From 0e03deca512098460d8fcba52bc5e0cb003e90e5 Mon Sep 17 00:00:00 2001 From: Nikola Matic Date: Thu, 25 Jan 2024 09:36:37 +0100 Subject: [PATCH 0001/1022] Set version to 0.8.25 --- CMakeLists.txt | 2 +- Changelog.md | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f6a905e39aa8..18af34d26bf0 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.24") +set(PROJECT_VERSION "0.8.25") # 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 d36470b01636..171dce2ef756 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,3 +1,14 @@ +### 0.8.25 (unreleased) + +Language Features: + + +Compiler Features: + + +Bugfixes: + + ### 0.8.24 (2024-01-25) Language Features: From a70cae9c9b6a7b6e2fe6556694adebe320d698f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Fri, 26 Jan 2024 17:01:56 +0100 Subject: [PATCH 0002/1022] Fix 0.8.23 changelog formatting --- Changelog.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Changelog.md b/Changelog.md index 171dce2ef756..7ab13de8fe4f 100644 --- a/Changelog.md +++ b/Changelog.md @@ -21,10 +21,10 @@ Language Features: Compiler Features: -* EVM: Support for the EVM Version "Cancun". -* SMTChecker: Support `bytes.concat` except when string literals are passed as arguments. -* Standard JSON Interface: Add experimental support to import EVM assembly in the format used by ``--asm-json``. -* TypeChecker: Comparison of internal function pointers now yields a warning, as it can produce unexpected results with the legacy pipeline enabled. + * EVM: Support for the EVM Version "Cancun". + * SMTChecker: Support `bytes.concat` except when string literals are passed as arguments. + * Standard JSON Interface: Add experimental support to import EVM assembly in the format used by ``--asm-json``. + * TypeChecker: Comparison of internal function pointers now yields a warning, as it can produce unexpected results with the legacy pipeline enabled. Bugfixes: From 6d5aa393b9261d98f2ef2b4526425a073be36423 Mon Sep 17 00:00:00 2001 From: Dimitris Apostolou Date: Fri, 26 Jan 2024 18:25:37 +0200 Subject: [PATCH 0003/1022] Fix typos --- libevmasm/ConstantOptimiser.h | 2 +- libsolidity/codegen/YulUtilFunctions.cpp | 2 +- libsolidity/interface/StandardCompiler.h | 2 +- libsolidity/lsp/Transport.h | 2 +- test/evmc/evmc.h | 2 +- test/tools/ossfuzz/README.md | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/libevmasm/ConstantOptimiser.h b/libevmasm/ConstantOptimiser.h index b491fb00422f..139e263ba369 100644 --- a/libevmasm/ConstantOptimiser.h +++ b/libevmasm/ConstantOptimiser.h @@ -70,7 +70,7 @@ class ConstantOptimisationMethod virtual ~ConstantOptimisationMethod() = default; virtual bigint gasNeeded() const = 0; /// Executes the method, potentially appending to the assembly and returns a vector of - /// assembly items the constant should be relpaced with in one sweep. + /// assembly items the constant should be replaced with in one sweep. /// If the vector is empty, the constants will not be deleted. virtual AssemblyItems execute(Assembly& _assembly) const = 0; diff --git a/libsolidity/codegen/YulUtilFunctions.cpp b/libsolidity/codegen/YulUtilFunctions.cpp index 5ff5ac4f3b98..35fea8ac4b76 100644 --- a/libsolidity/codegen/YulUtilFunctions.cpp +++ b/libsolidity/codegen/YulUtilFunctions.cpp @@ -3866,7 +3866,7 @@ std::string YulUtilFunctions::cleanupFunction(Type const& _type) } case Type::Category::Enum: { - // Out of range enums cannot be truncated unambigiously and therefore it should be an error. + // Out of range enums cannot be truncated unambiguously and therefore it should be an error. templ("body", "cleaned := value " + validatorFunction(_type, false) + "(value)"); break; } diff --git a/libsolidity/interface/StandardCompiler.h b/libsolidity/interface/StandardCompiler.h index 93cc73f3a7e2..03bdc7f12bd2 100644 --- a/libsolidity/interface/StandardCompiler.h +++ b/libsolidity/interface/StandardCompiler.h @@ -59,7 +59,7 @@ class StandardCompiler /// Sets all input parameters according to @a _input which conforms to the standardized input /// format, performs compilation and returns a standardized output. Json::Value compile(Json::Value const& _input) noexcept; - /// Parses input as JSON and peforms the above processing steps, returning a serialized JSON + /// Parses input as JSON and performs the above processing steps, returning a serialized JSON /// output. Parsing errors are returned as regular errors. std::string compile(std::string const& _input) noexcept; diff --git a/libsolidity/lsp/Transport.h b/libsolidity/lsp/Transport.h index 3e94e0398119..e3b03bcc7f2f 100644 --- a/libsolidity/lsp/Transport.h +++ b/libsolidity/lsp/Transport.h @@ -122,7 +122,7 @@ class Transport /// the message body from the transport line. virtual std::string readBytes(size_t _byteCount) = 0; - // Mimmicks std::getline() on this Transport API. + // Mimics std::getline() on this Transport API. virtual std::string getline() = 0; /// Writes the given payload @p _data to transport. diff --git a/test/evmc/evmc.h b/test/evmc/evmc.h index 48b03e554556..571c97f474e0 100644 --- a/test/evmc/evmc.h +++ b/test/evmc/evmc.h @@ -1181,7 +1181,7 @@ struct evmc_vm * * @par Binaries naming convention * For VMs distributed as shared libraries, the name of the library SHOULD match the VM name. - * The convetional library filename prefixes and extensions SHOULD be ignored by the Client. + * The conventional library filename prefixes and extensions SHOULD be ignored by the Client. * For example, the shared library with the "beta-interpreter" implementation may be named * `libbeta-interpreter.so`. * diff --git a/test/tools/ossfuzz/README.md b/test/tools/ossfuzz/README.md index 9343602d44d2..dae338648980 100644 --- a/test/tools/ossfuzz/README.md +++ b/test/tools/ossfuzz/README.md @@ -69,7 +69,7 @@ To help oss-fuzz do this, we (as project maintainers) need to provide the follow To be consistent and aid better evaluation of the utility of the fuzzing dictionary, we stick to the following rules-of-thumb: - Full tokens such as `block.number` are preceded and followed by a whitespace - - Incomplete tokens including function calls such as `msg.sender.send()` are abbreviated `.send(` to provide some leeway to the fuzzer to sythesize variants such as `address(this).send()` + - Incomplete tokens including function calls such as `msg.sender.send()` are abbreviated `.send(` to provide some leeway to the fuzzer to synthesize variants such as `address(this).send()` - Language keywords are suffixed by a whitespace with the exception of those that end a line of code such as `break;` and `continue;` [1]: https://github.com/google/oss-fuzz From fb99132474c177fc861305feeafd43b9cbb93b66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Wed, 13 Dec 2023 19:21:58 +0100 Subject: [PATCH 0004/1022] TypeInference: Remove unreachable errors on missing instantiation annotations guaranteed by previous passes --- .../experimental/analysis/TypeInference.cpp | 50 +++++++------------ scripts/error_codes.py | 5 -- ...instantiation_invalid_type_constructor.sol | 13 +++++ .../inference/instantiation_not_for_class.sol | 12 +++++ 4 files changed, 44 insertions(+), 36 deletions(-) create mode 100644 test/libsolidity/syntaxTests/experimental/inference/instantiation_invalid_type_constructor.sol create mode 100644 test/libsolidity/syntaxTests/experimental/inference/instantiation_not_for_class.sol diff --git a/libsolidity/experimental/analysis/TypeInference.cpp b/libsolidity/experimental/analysis/TypeInference.cpp index a13d6ebc9403..9ec7c9786724 100644 --- a/libsolidity/experimental/analysis/TypeInference.cpp +++ b/libsolidity/experimental/analysis/TypeInference.cpp @@ -621,45 +621,33 @@ bool TypeInference::visit(TypeClassInstantiation const& _typeClassInstantiation) if (instantiationAnnotation.type) return false; instantiationAnnotation.type = m_voidType; - std::optional typeClass = std::visit(util::GenericVisitor{ - [&](ASTPointer _typeClassName) -> std::optional { - if (auto const* typeClassDefinition = dynamic_cast(_typeClassName->annotation().referencedDeclaration)) - { - // visiting the type class will re-visit this instantiation - typeClassDefinition->accept(*this); - // TODO: more error handling? Should be covered by the visit above. - solAssert(m_analysis.annotation(*typeClassDefinition).typeClass.has_value()); - return m_analysis.annotation(*typeClassDefinition).typeClass.value(); - } - else - { - m_errorReporter.typeError(9817_error, _typeClassInstantiation.typeClass().location(), "Expected type class."); - return std::nullopt; - } + TypeClass typeClass = std::visit(util::GenericVisitor{ + [&](ASTPointer _typeClassName) -> TypeClass { + auto const* typeClassDefinition = dynamic_cast(_typeClassName->annotation().referencedDeclaration); + solAssert(typeClassDefinition); + + // visiting the type class will re-visit this instantiation + typeClassDefinition->accept(*this); + // TODO: more error handling? Should be covered by the visit above. + solAssert(m_analysis.annotation(*typeClassDefinition).typeClass.has_value()); + return m_analysis.annotation(*typeClassDefinition).typeClass.value(); }, - [&](Token _token) -> std::optional { - if (auto builtinClass = builtinClassFromToken(_token)) - if (auto typeClass = util::valueOrNullptr(annotation().builtinClasses, *builtinClass)) - return *typeClass; - m_errorReporter.typeError(2658_error, _typeClassInstantiation.location(), "Invalid type class name."); - return std::nullopt; + [&](Token _token) -> TypeClass { + std::optional builtinClass = builtinClassFromToken(_token); + solAssert(builtinClass.has_value()); + solAssert(annotation().builtinClasses.count(*builtinClass) != 0); + return annotation().builtinClasses.at(*builtinClass); } }, _typeClassInstantiation.typeClass().name()); - if (!typeClass) - return false; // TODO: _typeClassInstantiation.typeConstructor().accept(*this); ? auto typeConstructor = m_analysis.annotation(_typeClassInstantiation.typeConstructor()).typeConstructor; - if (!typeConstructor) - { - m_errorReporter.typeError(2138_error, _typeClassInstantiation.typeConstructor().location(), "Invalid type constructor."); - return false; - } + solAssert(typeConstructor); std::vector arguments; Arity arity{ {}, - *typeClass + typeClass }; { @@ -692,10 +680,10 @@ bool TypeInference::visit(TypeClassInstantiation const& _typeClassInstantiation) if (auto error = m_typeSystem.instantiateClass(instanceType, arity)) m_errorReporter.typeError(5094_error, _typeClassInstantiation.location(), *error); - auto const& classFunctions = annotation().typeClassFunctions.at(*typeClass); + auto const& classFunctions = annotation().typeClassFunctions.at(typeClass); TypeEnvironment newEnv = m_env->clone(); - if (!newEnv.unify(m_typeSystem.typeClassVariable(*typeClass), instanceType).empty()) + if (!newEnv.unify(m_typeSystem.typeClassVariable(typeClass), instanceType).empty()) { m_errorReporter.typeError(4686_error, _typeClassInstantiation.location(), "Unification of class and instance variable failed."); return false; diff --git a/scripts/error_codes.py b/scripts/error_codes.py index d4e9e5486665..8ffb7f2160f4 100755 --- a/scripts/error_codes.py +++ b/scripts/error_codes.py @@ -275,18 +275,15 @@ def examine_id_coverage(top_dir, source_id_to_file_names, new_ids_only=False): "1801", "1807", "2015", - "2138", "2345", "2399", "2599", "2655", - "2658", "2934", "3101", "3111", "3195", "3520", - "3570", "3573", "3654", "4316", @@ -329,8 +326,6 @@ def examine_id_coverage(top_dir, source_id_to_file_names, new_ids_only=False): "9282", "9603", "9658", - "9817", - "9831", "9988", } diff --git a/test/libsolidity/syntaxTests/experimental/inference/instantiation_invalid_type_constructor.sol b/test/libsolidity/syntaxTests/experimental/inference/instantiation_invalid_type_constructor.sol new file mode 100644 index 000000000000..0245deb1f401 --- /dev/null +++ b/test/libsolidity/syntaxTests/experimental/inference/instantiation_invalid_type_constructor.sol @@ -0,0 +1,13 @@ +pragma experimental solidity; + +class Self: C {} + +function f() {} + +instantiation f: C {} +// ==== +// EVMVersion: >=constantinople +// compileViaYul: true +// ---- +// Warning 2264: (0-29): Experimental features are turned on. Do not use experimental features on live deployments. +// TypeError 9831: (80-81): Expected type declaration. diff --git a/test/libsolidity/syntaxTests/experimental/inference/instantiation_not_for_class.sol b/test/libsolidity/syntaxTests/experimental/inference/instantiation_not_for_class.sol new file mode 100644 index 000000000000..c48fff74f94e --- /dev/null +++ b/test/libsolidity/syntaxTests/experimental/inference/instantiation_not_for_class.sol @@ -0,0 +1,12 @@ +pragma experimental solidity; + +type T; +type U; + +instantiation T: U {} +// ==== +// EVMVersion: >=constantinople +// compileViaYul: true +// ---- +// Warning 2264: (0-29): Experimental features are turned on. Do not use experimental features on live deployments. +// TypeError 3570: (65-66): Expected a type class. From 9d80e0e3ee42acfcef6926fefc64ccd21afbce2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Mon, 8 Jan 2024 19:02:04 +0100 Subject: [PATCH 0005/1022] Yul proto fuzzer: Add mcopy builtin to generator. --- test/tools/ossfuzz/protoToYul.cpp | 15 ++++++++++++++- test/tools/ossfuzz/protoToYul.h | 4 +++- test/tools/ossfuzz/yulProto.proto | 1 + 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/test/tools/ossfuzz/protoToYul.cpp b/test/tools/ossfuzz/protoToYul.cpp index 6c8f291d29a3..75074db3b064 100644 --- a/test/tools/ossfuzz/protoToYul.cpp +++ b/test/tools/ossfuzz/protoToYul.cpp @@ -796,6 +796,10 @@ void ProtoConverter::visit(CopyFunc const& _x) if (type == CopyFunc::RETURNDATA && !m_evmVersion.supportsReturndata()) return; + // Bail out if MCOPY is not supported for fuzzed EVM version + if (type == CopyFunc::MEMORY && !m_evmVersion.hasMcopy()) + return; + // Code copy may change state if e.g., some byte of code // is stored to storage via a sequence of mload and sstore. if (m_filterStatefulInstructions && type == CopyFunc::CODE) @@ -816,13 +820,22 @@ void ProtoConverter::visit(CopyFunc const& _x) case CopyFunc::DATA: m_output << "datacopy"; break; + case CopyFunc::MEMORY: + m_output << "mcopy"; } m_output << "("; m_output << "mod("; visit(_x.target()); m_output << ", " << to_string(s_maxMemory - s_maxSize) << ")"; m_output << ", "; - visit(_x.source()); + if (type == CopyFunc::MEMORY) + { + m_output << "mod("; + visit(_x.source()); + m_output << ", " << to_string(s_maxMemory - s_maxSize) << ")"; + } + else + visit(_x.source()); m_output << ", "; m_output << "mod("; visit(_x.size()); diff --git a/test/tools/ossfuzz/protoToYul.h b/test/tools/ossfuzz/protoToYul.h index b7f7c72e5a8e..c264dd51af13 100644 --- a/test/tools/ossfuzz/protoToYul.h +++ b/test/tools/ossfuzz/protoToYul.h @@ -346,7 +346,9 @@ class ProtoConverter static auto constexpr s_dataIdentifier = "datablock"; /// Upper bound on memory writes is 64KB in order to /// preserve semantic equivalence in the presence of - /// memory guard + /// memory guard. Note that s_maxMemory must be much larger + /// than s_maxSize to create tests without significant overlap + /// of I/O memory regions. static unsigned constexpr s_maxMemory = 65536; /// Upper bound on size for range copy functions static unsigned constexpr s_maxSize = 32768; diff --git a/test/tools/ossfuzz/yulProto.proto b/test/tools/ossfuzz/yulProto.proto index 7552fb23adde..afe70363ae2b 100644 --- a/test/tools/ossfuzz/yulProto.proto +++ b/test/tools/ossfuzz/yulProto.proto @@ -186,6 +186,7 @@ message CopyFunc { CODE = 1; RETURNDATA = 2; DATA = 3; + MEMORY = 4; } required CopyType ct = 1; required Expression target = 2; From fb7c2b4b9083a041e4ec3ab13265eed3015d6b7b Mon Sep 17 00:00:00 2001 From: Bhargava Shastry Date: Thu, 25 Jan 2024 06:54:08 +0100 Subject: [PATCH 0006/1022] Yul fuzzer: Support transient storage. --- test/tools/ossfuzz/protoToYul.cpp | 35 +++++++++++++++++++++++++------ test/tools/ossfuzz/yulProto.proto | 14 +++++++------ 2 files changed, 37 insertions(+), 12 deletions(-) diff --git a/test/tools/ossfuzz/protoToYul.cpp b/test/tools/ossfuzz/protoToYul.cpp index 6c8f291d29a3..7ad35d66d358 100644 --- a/test/tools/ossfuzz/protoToYul.cpp +++ b/test/tools/ossfuzz/protoToYul.cpp @@ -593,6 +593,12 @@ void ProtoConverter::visit(UnaryOp const& _x) return; } + if (op == UnaryOp::TLOAD && !m_evmVersion.supportsTransientStorage()) + { + m_output << dictionaryToken(); + return; + } + // The following instructions may lead to change of EVM state and are hence // excluded to avoid false positives. if ( @@ -620,6 +626,9 @@ void ProtoConverter::visit(UnaryOp const& _x) case UnaryOp::SLOAD: m_output << "sload"; break; + case UnaryOp::TLOAD: + m_output << "tload"; + break; case UnaryOp::ISZERO: m_output << "iszero"; break; @@ -1141,9 +1150,12 @@ void ProtoConverter::visit(StoreFunc const& _x) case StoreFunc::MSTORE8: m_output << "mstore8("; break; + case StoreFunc::TSTORE: + m_output << "tstore("; + break; } // Write to memory within bounds, storage is unbounded - if (storeType == StoreFunc::SSTORE) + if (storeType == StoreFunc::SSTORE || storeType == StoreFunc::TSTORE) visit(_x.loc()); else if (storeType == StoreFunc::MSTORE8) { @@ -1755,18 +1767,29 @@ void ProtoConverter::fillFunctionCallInput(unsigned _numInParams) void ProtoConverter::saveFunctionCallOutput(vector const& _varsVec) { - for (auto const& var: _varsVec) + constexpr auto numSlots = 10; + constexpr auto slotSize = 32; + + for (string const& var: _varsVec) { // Flip a dice to choose whether to save output values // in storage or memory. - bool coinFlip = counter() % 2 == 0; + unsigned diceThrow = counter() % (m_evmVersion.supportsTransientStorage() ? 3 : 2); // Pseudo-randomly choose one of the first ten 32-byte // aligned slots. - string slot = to_string((counter() % 10) * 32); - if (coinFlip) + string slot = std::to_string((counter() % numSlots) * slotSize); + if (diceThrow == 0) m_output << "sstore(" << slot << ", " << var << ")\n"; - else + else if (diceThrow == 1) m_output << "mstore(" << slot << ", " << var << ")\n"; + else + { + yulAssert( + m_evmVersion.supportsTransientStorage(), + "Proto fuzzer: Invalid evm version" + ); + m_output << "tstore(" << slot << ", " << var << ")\n"; + } } } diff --git a/test/tools/ossfuzz/yulProto.proto b/test/tools/ossfuzz/yulProto.proto index 7552fb23adde..f4eabab64aed 100644 --- a/test/tools/ossfuzz/yulProto.proto +++ b/test/tools/ossfuzz/yulProto.proto @@ -149,12 +149,13 @@ message UnaryOp { NOT = 0; MLOAD = 1; SLOAD = 2; - ISZERO = 3; - CALLDATALOAD = 4; - EXTCODESIZE = 5; - EXTCODEHASH = 6; - BALANCE = 7; - BLOCKHASH = 8; + TLOAD = 3; + ISZERO = 4; + CALLDATALOAD = 5; + EXTCODESIZE = 6; + EXTCODEHASH = 7; + BALANCE = 8; + BLOCKHASH = 9; } required UOp op = 1; required Expression operand = 2; @@ -230,6 +231,7 @@ message StoreFunc { MSTORE = 0; SSTORE = 1; MSTORE8 = 2; + TSTORE = 3; } required Expression loc = 1; required Expression val = 2; From e545e936d20375757ef25d473c113616bccaae0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Mon, 30 Oct 2023 10:41:11 +0100 Subject: [PATCH 0007/1022] TypeSystemHelper: substitute() --- .../experimental/ast/TypeSystemHelper.cpp | 27 ++++++++++++++++++- .../experimental/ast/TypeSystemHelper.h | 2 ++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/libsolidity/experimental/ast/TypeSystemHelper.cpp b/libsolidity/experimental/ast/TypeSystemHelper.cpp index bc7dd4fcc35a..36576d9cd8cc 100644 --- a/libsolidity/experimental/ast/TypeSystemHelper.cpp +++ b/libsolidity/experimental/ast/TypeSystemHelper.cpp @@ -287,9 +287,34 @@ std::vector TypeEnvironmentHelpers::typeVars(Type _type) con }; typeVarsImpl(_type, typeVarsImpl); return typeVars; - } +experimental::Type TypeEnvironmentHelpers::substitute( + Type const& _type, + Type const& _partToReplace, + Type const& _replacement +) const +{ + using ranges::views::transform; + using ranges::to; + + if (env.typeEquals(_type, _partToReplace)) + return _replacement; + + auto recurse = [&](Type const& _t) { return substitute(_t, _partToReplace, _replacement); }; + + return visit(util::GenericVisitor{ + [&](TypeConstant const& _typeConstant) -> Type { + return TypeConstant{ + _typeConstant.constructor, + _typeConstant.arguments | transform(recurse) | to>, + }; + }, + [&](auto const& _type) -> Type { + return _type; + }, + }, env.resolve(_type)); +} std::string TypeSystemHelpers::sortToString(Sort _sort) const { diff --git a/libsolidity/experimental/ast/TypeSystemHelper.h b/libsolidity/experimental/ast/TypeSystemHelper.h index fd55c1bf842e..d8a3092d23f2 100644 --- a/libsolidity/experimental/ast/TypeSystemHelper.h +++ b/libsolidity/experimental/ast/TypeSystemHelper.h @@ -55,6 +55,8 @@ struct TypeEnvironmentHelpers std::string typeToString(Type const& _type) const; std::string canonicalTypeName(Type _type) const; std::vector typeVars(Type _type) const; + + Type substitute(Type const& _type, Type const& _partToReplace, Type const& _replacement) const; }; } From 44ffdb1eaf9693ba0c776a7f3977dac0ff5e3a71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Mon, 30 Oct 2023 10:56:26 +0100 Subject: [PATCH 0008/1022] Introduce fixed type variables --- libsolidity/experimental/ast/TypeSystem.cpp | 40 ++++++++++++++----- libsolidity/experimental/ast/TypeSystem.h | 11 +++++ .../experimental/ast/TypeSystemHelper.cpp | 13 ++++++ .../experimental/ast/TypeSystemHelper.h | 2 + 4 files changed, 56 insertions(+), 10 deletions(-) diff --git a/libsolidity/experimental/ast/TypeSystem.cpp b/libsolidity/experimental/ast/TypeSystem.cpp index 680edce845f6..fac5073bb0ca 100644 --- a/libsolidity/experimental/ast/TypeSystem.cpp +++ b/libsolidity/experimental/ast/TypeSystem.cpp @@ -50,18 +50,21 @@ std::vector TypeEnvironment::unify(Type _a, [&](TypeVariable _left, TypeVariable _right) { if (_left.index() == _right.index()) solAssert(_left.sort() == _right.sort()); + else if (isFixedTypeVar(_left) && isFixedTypeVar(_right)) + unificationFailure(); + else if (isFixedTypeVar(_left)) + failures += instantiate(_right, _left); + else if (isFixedTypeVar(_right)) + failures += instantiate(_left, _right); + else if (_left.sort() <= _right.sort()) + failures += instantiate(_left, _right); + else if (_right.sort() <= _left.sort()) + failures += instantiate(_right, _left); else { - if (_left.sort() <= _right.sort()) - failures += instantiate(_left, _right); - else if (_right.sort() <= _left.sort()) - failures += instantiate(_right, _left); - else - { - Type newVar = m_typeSystem.freshVariable(_left.sort() + _right.sort()); - failures += instantiate(_left, newVar); - failures += instantiate(_right, newVar); - } + Type newVar = m_typeSystem.freshVariable(_left.sort() + _right.sort()); + failures += instantiate(_left, newVar); + failures += instantiate(_right, newVar); } }, [&](TypeVariable _var, auto) { @@ -112,6 +115,23 @@ bool TypeEnvironment::typeEquals(Type _lhs, Type _rhs) const }, resolve(_lhs), resolve(_rhs)); } + +bool TypeEnvironment::isFixedTypeVar(Type const& _typeVar) const +{ + return + std::holds_alternative(_typeVar) && + m_fixedTypeVariables.count(std::get(_typeVar).index()) != 0; +} + +void TypeEnvironment::fixTypeVars(std::vector const& _typeVars) +{ + for (Type const& typeVar: _typeVars) + { + solAssert(std::holds_alternative(typeVar)); + m_fixedTypeVariables.insert(std::get(typeVar).index()); + } +} + TypeEnvironment TypeEnvironment::clone() const { TypeEnvironment result{m_typeSystem}; diff --git a/libsolidity/experimental/ast/TypeSystem.h b/libsolidity/experimental/ast/TypeSystem.h index cac0feb81fe2..c3aa5001a16d 100644 --- a/libsolidity/experimental/ast/TypeSystem.h +++ b/libsolidity/experimental/ast/TypeSystem.h @@ -74,6 +74,9 @@ class TypeEnvironment TypeSystem& typeSystem() { return m_typeSystem; } TypeSystem const& typeSystem() const { return m_typeSystem; } + bool isFixedTypeVar(Type const& _typeVar) const; + void fixTypeVars(std::vector const& _typeVars); + private: TypeEnvironment(TypeEnvironment&& _env): m_typeSystem(_env.m_typeSystem), @@ -83,7 +86,15 @@ class TypeEnvironment [[nodiscard]] std::vector instantiate(TypeVariable _variable, Type _type); TypeSystem& m_typeSystem; + + /// For each @a TypeVariable (identified by its index) stores the type is has been successfully + /// unified with. Used for type resolution. Note that @a Type may itself be a type variable + /// or may contain type variables so resolution must be recursive. std::map m_typeVariables; + + /// Type variables marked as fixed free type variables (as opposed to generic type variables). + /// Identified by their indices. + std::set m_fixedTypeVariables; }; class TypeSystem diff --git a/libsolidity/experimental/ast/TypeSystemHelper.cpp b/libsolidity/experimental/ast/TypeSystemHelper.cpp index 36576d9cd8cc..0924754cd51b 100644 --- a/libsolidity/experimental/ast/TypeSystemHelper.cpp +++ b/libsolidity/experimental/ast/TypeSystemHelper.cpp @@ -25,6 +25,7 @@ #include +#include #include #include #include @@ -289,6 +290,18 @@ std::vector TypeEnvironmentHelpers::typeVars(Type _type) con return typeVars; } + +bool TypeEnvironmentHelpers::hasGenericTypeVars(Type const& _type) const +{ + return ranges::any_of( + TypeEnvironmentHelpers{*this}.typeVars(_type), + [&](Type const& _maybeTypeVar) { + solAssert(std::holds_alternative(_maybeTypeVar)); + return !env.isFixedTypeVar(_maybeTypeVar); + } + ); +} + experimental::Type TypeEnvironmentHelpers::substitute( Type const& _type, Type const& _partToReplace, diff --git a/libsolidity/experimental/ast/TypeSystemHelper.h b/libsolidity/experimental/ast/TypeSystemHelper.h index d8a3092d23f2..ba395ace3a62 100644 --- a/libsolidity/experimental/ast/TypeSystemHelper.h +++ b/libsolidity/experimental/ast/TypeSystemHelper.h @@ -56,6 +56,8 @@ struct TypeEnvironmentHelpers std::string canonicalTypeName(Type _type) const; std::vector typeVars(Type _type) const; + bool hasGenericTypeVars(Type const& _type) const; + Type substitute(Type const& _type, Type const& _partToReplace, Type const& _replacement) const; }; From fd3c393f9a753b491964f3301c7eb4d5357d8a5f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Mon, 30 Oct 2023 10:56:47 +0100 Subject: [PATCH 0009/1022] Use different prefixes when printing fixed and generic type variables --- .../experimental/ast/TypeSystemHelper.cpp | 2 +- .../builtin/builtin_type_definition.sol | 20 +-- .../inference/polymorphic_function_call.sol | 24 ++-- .../inference/polymorphic_type.sol | 42 +++--- .../polymorphic_type_abs_and_rep.sol | 42 +++--- ...rphic_type_instantiation_and_operators.sol | 124 +++++++++--------- 6 files changed, 127 insertions(+), 127 deletions(-) diff --git a/libsolidity/experimental/ast/TypeSystemHelper.cpp b/libsolidity/experimental/ast/TypeSystemHelper.cpp index 0924754cd51b..9ad18e1608bc 100644 --- a/libsolidity/experimental/ast/TypeSystemHelper.cpp +++ b/libsolidity/experimental/ast/TypeSystemHelper.cpp @@ -419,7 +419,7 @@ std::string TypeEnvironmentHelpers::typeToString(Type const& _type) const while (index /= 26) varName += static_cast('a' + (index%26)); reverse(varName.begin(), varName.end()); - stream << '\'' << varName; + stream << (env.isFixedTypeVar(_type) ? "'" : "?") << varName; switch (_type.sort().classes.size()) { case 0: diff --git a/test/libsolidity/syntaxTests/experimental/builtin/builtin_type_definition.sol b/test/libsolidity/syntaxTests/experimental/builtin/builtin_type_definition.sol index fc4783ceba19..fb76e1948b87 100644 --- a/test/libsolidity/syntaxTests/experimental/builtin/builtin_type_definition.sol +++ b/test/libsolidity/syntaxTests/experimental/builtin/builtin_type_definition.sol @@ -40,14 +40,14 @@ contract C { // Info 4164: (94-124): Inferred type: word // Info 4164: (125-161): Inferred type: integer // Info 4164: (162-192): Inferred type: () -// Info 4164: (194-228): Inferred type: tfun(('u:type, 'v:type), 'u:type -> 'v:type) -// Info 4164: (202-208): Inferred type: ('s:type, 't:type) -// Info 4164: (203-204): Inferred type: 's:type -// Info 4164: (206-207): Inferred type: 't:type -// Info 4164: (229-265): Inferred type: tfun(('y:type, 'z:type), ('y:type, 'z:type)) -// Info 4164: (238-244): Inferred type: ('w:type, 'x:type) -// Info 4164: (239-240): Inferred type: 'w:type -// Info 4164: (242-243): Inferred type: 'x:type +// Info 4164: (194-228): Inferred type: tfun((?u:type, ?v:type), ?u:type -> ?v:type) +// Info 4164: (202-208): Inferred type: (?s:type, ?t:type) +// Info 4164: (203-204): Inferred type: ?s:type +// Info 4164: (206-207): Inferred type: ?t:type +// Info 4164: (229-265): Inferred type: tfun((?y:type, ?z:type), (?y:type, ?z:type)) +// Info 4164: (238-244): Inferred type: (?w:type, ?x:type) +// Info 4164: (239-240): Inferred type: ?w:type +// Info 4164: (242-243): Inferred type: ?x:type // Info 4164: (284-584): Inferred type: () -> () // Info 4164: (292-294): Inferred type: () // Info 4164: (318-325): Inferred type: void @@ -84,9 +84,9 @@ contract C { // Info 4164: (525-529): Inferred type: word // Info 4164: (540-553): Inferred type: bool // Info 4164: (540-550): Inferred type: (bool, word) -> bool -// Info 4164: (540-544): Inferred type: ('bl:type, 'bm:type) +// Info 4164: (540-544): Inferred type: (?bl:type, ?bm:type) // Info 4164: (551-552): Inferred type: (bool, word) // Info 4164: (563-577): Inferred type: word // Info 4164: (563-574): Inferred type: (bool, word) -> word -// Info 4164: (563-567): Inferred type: ('bq:type, 'br:type) +// Info 4164: (563-567): Inferred type: (?bq:type, ?br:type) // Info 4164: (575-576): Inferred type: (bool, word) diff --git a/test/libsolidity/syntaxTests/experimental/inference/polymorphic_function_call.sol b/test/libsolidity/syntaxTests/experimental/inference/polymorphic_function_call.sol index eacc895202f3..487aea090581 100644 --- a/test/libsolidity/syntaxTests/experimental/inference/polymorphic_function_call.sol +++ b/test/libsolidity/syntaxTests/experimental/inference/polymorphic_function_call.sol @@ -15,18 +15,18 @@ function run(a: T, b: U(T), c: U(U(T))) { // ---- // Warning 2264: (0-29): Experimental features are turned on. Do not use experimental features on live deployments. // Info 4164: (31-38): Inferred type: T -// Info 4164: (39-49): Inferred type: tfun('u:type, U('u:type)) -// Info 4164: (45-48): Inferred type: 't:type -// Info 4164: (46-47): Inferred type: 't:type -// Info 4164: (51-82): Inferred type: ('x:type, 'y:type, U('ba:type)) -> () -// Info 4164: (61-79): Inferred type: ('x:type, 'y:type, U('ba:type)) -// Info 4164: (62-63): Inferred type: 'x:type -// Info 4164: (65-69): Inferred type: 'y:type -// Info 4164: (68-69): Inferred type: 'y:type -// Info 4164: (71-78): Inferred type: U('ba:type) -// Info 4164: (74-78): Inferred type: U('ba:type) -// Info 4164: (74-75): Inferred type: tfun('ba:type, U('ba:type)) -// Info 4164: (76-77): Inferred type: 'ba:type +// Info 4164: (39-49): Inferred type: tfun(?u:type, U(?u:type)) +// Info 4164: (45-48): Inferred type: ?t:type +// Info 4164: (46-47): Inferred type: ?t:type +// Info 4164: (51-82): Inferred type: (?x:type, ?y:type, U(?ba:type)) -> () +// Info 4164: (61-79): Inferred type: (?x:type, ?y:type, U(?ba:type)) +// Info 4164: (62-63): Inferred type: ?x:type +// Info 4164: (65-69): Inferred type: ?y:type +// Info 4164: (68-69): Inferred type: ?y:type +// Info 4164: (71-78): Inferred type: U(?ba:type) +// Info 4164: (74-78): Inferred type: U(?ba:type) +// Info 4164: (74-75): Inferred type: tfun(?ba:type, U(?ba:type)) +// Info 4164: (76-77): Inferred type: ?ba:type // Info 4164: (84-159): Inferred type: (T, U(T), U(U(T))) -> () // Info 4164: (96-123): Inferred type: (T, U(T), U(U(T))) // Info 4164: (97-101): Inferred type: T diff --git a/test/libsolidity/syntaxTests/experimental/inference/polymorphic_type.sol b/test/libsolidity/syntaxTests/experimental/inference/polymorphic_type.sol index b597a5b25295..fa68ad308a83 100644 --- a/test/libsolidity/syntaxTests/experimental/inference/polymorphic_type.sol +++ b/test/libsolidity/syntaxTests/experimental/inference/polymorphic_type.sol @@ -16,32 +16,32 @@ function run() { // compileViaYul: true // ---- // Warning 2264: (0-29): Experimental features are turned on. Do not use experimental features on live deployments. -// Info 4164: (31-47): Inferred type: tfun(('ba:type, 'bb:type, 'bc:type), T('ba:type, 'bb:type, 'bc:type)) -// Info 4164: (37-46): Inferred type: ('x:type, 'y:type, 'z:type) -// Info 4164: (38-39): Inferred type: 'x:type -// Info 4164: (41-42): Inferred type: 'y:type -// Info 4164: (44-45): Inferred type: 'z:type +// Info 4164: (31-47): Inferred type: tfun((?ba:type, ?bb:type, ?bc:type), T(?ba:type, ?bb:type, ?bc:type)) +// Info 4164: (37-46): Inferred type: (?x:type, ?y:type, ?z:type) +// Info 4164: (38-39): Inferred type: ?x:type +// Info 4164: (41-42): Inferred type: ?y:type +// Info 4164: (44-45): Inferred type: ?z:type // Info 4164: (48-55): Inferred type: U // Info 4164: (56-63): Inferred type: V // Info 4164: (65-81): Inferred type: C -// Info 4164: (71-75): Inferred type: 'be:(type, C) +// Info 4164: (71-75): Inferred type: ?be:(type, C) // Info 4164: (82-98): Inferred type: D -// Info 4164: (88-92): Inferred type: 'bg:(type, D) +// Info 4164: (88-92): Inferred type: ?bg:(type, D) // Info 4164: (100-170): Inferred type: () -> () // Info 4164: (112-114): Inferred type: () -// Info 4164: (125-141): Inferred type: T(U, 'bm:type, 'bo:(type, C)) -// Info 4164: (128-141): Inferred type: T(U, 'bm:type, 'bo:(type, C)) -// Info 4164: (128-129): Inferred type: tfun((U, 'bm:type, 'bo:(type, C)), T(U, 'bm:type, 'bo:(type, C))) +// Info 4164: (125-141): Inferred type: T(U, ?bm:type, ?bo:(type, C)) +// Info 4164: (128-141): Inferred type: T(U, ?bm:type, ?bo:(type, C)) +// Info 4164: (128-129): Inferred type: tfun((U, ?bm:type, ?bo:(type, C)), T(U, ?bm:type, ?bo:(type, C))) // Info 4164: (130-131): Inferred type: U -// Info 4164: (133-134): Inferred type: 'bm:type -// Info 4164: (136-140): Inferred type: 'bo:(type, C) -// Info 4164: (136-137): Inferred type: 'bo:(type, C) -// Info 4164: (139-140): Inferred type: 'bo:(type, C) -// Info 4164: (151-167): Inferred type: T(V, 'bt:type, 'bv:(type, D)) -// Info 4164: (154-167): Inferred type: T(V, 'bt:type, 'bv:(type, D)) -// Info 4164: (154-155): Inferred type: tfun((V, 'bt:type, 'bv:(type, D)), T(V, 'bt:type, 'bv:(type, D))) +// Info 4164: (133-134): Inferred type: ?bm:type +// Info 4164: (136-140): Inferred type: ?bo:(type, C) +// Info 4164: (136-137): Inferred type: ?bo:(type, C) +// Info 4164: (139-140): Inferred type: ?bo:(type, C) +// Info 4164: (151-167): Inferred type: T(V, ?bt:type, ?bv:(type, D)) +// Info 4164: (154-167): Inferred type: T(V, ?bt:type, ?bv:(type, D)) +// Info 4164: (154-155): Inferred type: tfun((V, ?bt:type, ?bv:(type, D)), T(V, ?bt:type, ?bv:(type, D))) // Info 4164: (156-157): Inferred type: V -// Info 4164: (159-160): Inferred type: 'bt:type -// Info 4164: (162-166): Inferred type: 'bv:(type, D) -// Info 4164: (162-163): Inferred type: 'bv:(type, D) -// Info 4164: (165-166): Inferred type: 'bv:(type, D) +// Info 4164: (159-160): Inferred type: ?bt:type +// Info 4164: (162-166): Inferred type: ?bv:(type, D) +// Info 4164: (162-163): Inferred type: ?bv:(type, D) +// Info 4164: (165-166): Inferred type: ?bv:(type, D) diff --git a/test/libsolidity/syntaxTests/experimental/inference/polymorphic_type_abs_and_rep.sol b/test/libsolidity/syntaxTests/experimental/inference/polymorphic_type_abs_and_rep.sol index 89f3f5f1a8b9..27631d064d18 100644 --- a/test/libsolidity/syntaxTests/experimental/inference/polymorphic_type_abs_and_rep.sol +++ b/test/libsolidity/syntaxTests/experimental/inference/polymorphic_type_abs_and_rep.sol @@ -24,15 +24,15 @@ function fun() { // Warning 2264: (0-29): Experimental features are turned on. Do not use experimental features on live deployments. // Info 4164: (31-41): Inferred type: uint // Info 4164: (42-54): Inferred type: string -// Info 4164: (56-66): Inferred type: tfun('v:type, T('v:type)) -// Info 4164: (62-65): Inferred type: 'u:type -// Info 4164: (63-64): Inferred type: 'u:type -// Info 4164: (67-84): Inferred type: tfun('x:type, U('x:type)) -// Info 4164: (73-76): Inferred type: 'w:type -// Info 4164: (74-75): Inferred type: 'w:type -// Info 4164: (79-83): Inferred type: T('w:type) -// Info 4164: (79-80): Inferred type: tfun('w:type, T('w:type)) -// Info 4164: (81-82): Inferred type: 'w:type +// Info 4164: (56-66): Inferred type: tfun(?v:type, T(?v:type)) +// Info 4164: (62-65): Inferred type: ?u:type +// Info 4164: (63-64): Inferred type: ?u:type +// Info 4164: (67-84): Inferred type: tfun(?x:type, U(?x:type)) +// Info 4164: (73-76): Inferred type: ?w:type +// Info 4164: (74-75): Inferred type: ?w:type +// Info 4164: (79-83): Inferred type: T(?w:type) +// Info 4164: (79-80): Inferred type: tfun(?w:type, T(?w:type)) +// Info 4164: (81-82): Inferred type: ?w:type // Info 4164: (86-245): Inferred type: () -> () // Info 4164: (98-100): Inferred type: () // Info 4164: (111-121): Inferred type: U(uint) @@ -43,13 +43,13 @@ function fun() { // Info 4164: (134-141): Inferred type: T(uint) // Info 4164: (134-135): Inferred type: tfun(uint, T(uint)) // Info 4164: (136-140): Inferred type: uint -// Info 4164: (147-155): Inferred type: T('bi:type) -// Info 4164: (147-152): Inferred type: U(uint) -> T('bi:type) -// Info 4164: (147-148): Inferred type: U('bg:type) +// Info 4164: (147-155): Inferred type: T(?bi:type) +// Info 4164: (147-152): Inferred type: U(uint) -> T(?bi:type) +// Info 4164: (147-148): Inferred type: U(?bg:type) // Info 4164: (153-154): Inferred type: U(uint) -// Info 4164: (161-169): Inferred type: U('bm:type) -// Info 4164: (161-166): Inferred type: T(uint) -> U('bm:type) -// Info 4164: (161-162): Inferred type: U('bk:type) +// Info 4164: (161-169): Inferred type: U(?bm:type) +// Info 4164: (161-166): Inferred type: T(uint) -> U(?bm:type) +// Info 4164: (161-162): Inferred type: U(?bk:type) // Info 4164: (167-168): Inferred type: T(uint) // Info 4164: (180-192): Inferred type: U(string) // Info 4164: (183-192): Inferred type: U(string) @@ -59,11 +59,11 @@ function fun() { // Info 4164: (205-214): Inferred type: T(string) // Info 4164: (205-206): Inferred type: tfun(string, T(string)) // Info 4164: (207-213): Inferred type: string -// Info 4164: (220-228): Inferred type: T('bu:type) -// Info 4164: (220-225): Inferred type: U(string) -> T('bu:type) -// Info 4164: (220-221): Inferred type: U('bs:type) +// Info 4164: (220-228): Inferred type: T(?bu:type) +// Info 4164: (220-225): Inferred type: U(string) -> T(?bu:type) +// Info 4164: (220-221): Inferred type: U(?bs:type) // Info 4164: (226-227): Inferred type: U(string) -// Info 4164: (234-242): Inferred type: U('by:type) -// Info 4164: (234-239): Inferred type: T(string) -> U('by:type) -// Info 4164: (234-235): Inferred type: U('bw:type) +// Info 4164: (234-242): Inferred type: U(?by:type) +// Info 4164: (234-239): Inferred type: T(string) -> U(?by:type) +// Info 4164: (234-235): Inferred type: U(?bw:type) // Info 4164: (240-241): Inferred type: T(string) diff --git a/test/libsolidity/syntaxTests/experimental/inference/polymorphic_type_instantiation_and_operators.sol b/test/libsolidity/syntaxTests/experimental/inference/polymorphic_type_instantiation_and_operators.sol index 25ab330f3b32..3bff1f4d0ad0 100644 --- a/test/libsolidity/syntaxTests/experimental/inference/polymorphic_type_instantiation_and_operators.sol +++ b/test/libsolidity/syntaxTests/experimental/inference/polymorphic_type_instantiation_and_operators.sol @@ -51,28 +51,28 @@ function fun(a: T(int: P3), b: T(str: P4)) { // ---- // Warning 2264: (0-29): Experimental features are turned on. Do not use experimental features on live deployments. // Info 4164: (31-61): Inferred type: bool -// Info 4164: (63-73): Inferred type: tfun('z:type, T('z:type)) -// Info 4164: (69-72): Inferred type: 'y:type -// Info 4164: (70-71): Inferred type: 'y:type +// Info 4164: (63-73): Inferred type: tfun(?z:type, T(?z:type)) +// Info 4164: (69-72): Inferred type: ?y:type +// Info 4164: (70-71): Inferred type: ?y:type // Info 4164: (74-83): Inferred type: int // Info 4164: (84-93): Inferred type: str // Info 4164: (95-156): Inferred type: C -// Info 4164: (101-105): Inferred type: 'bd:(type, C) -// Info 4164: (115-154): Inferred type: ('bd:(type, C), 'bd:(type, C)) -> 'bd:(type, C) -// Info 4164: (127-145): Inferred type: ('bd:(type, C), 'bd:(type, C)) -// Info 4164: (128-135): Inferred type: 'bd:(type, C) -// Info 4164: (131-135): Inferred type: 'bd:(type, C) -// Info 4164: (137-144): Inferred type: 'bd:(type, C) -// Info 4164: (140-144): Inferred type: 'bd:(type, C) -// Info 4164: (149-153): Inferred type: 'bd:(type, C) +// Info 4164: (101-105): Inferred type: ?bd:(type, C) +// Info 4164: (115-154): Inferred type: (?bd:(type, C), ?bd:(type, C)) -> ?bd:(type, C) +// Info 4164: (127-145): Inferred type: (?bd:(type, C), ?bd:(type, C)) +// Info 4164: (128-135): Inferred type: ?bd:(type, C) +// Info 4164: (131-135): Inferred type: ?bd:(type, C) +// Info 4164: (137-144): Inferred type: ?bd:(type, C) +// Info 4164: (140-144): Inferred type: ?bd:(type, C) +// Info 4164: (149-153): Inferred type: ?bd:(type, C) // Info 4164: (158-175): Inferred type: P1 -// Info 4164: (164-168): Inferred type: 'bg:(type, P1) +// Info 4164: (164-168): Inferred type: ?bg:(type, P1) // Info 4164: (176-193): Inferred type: P2 -// Info 4164: (182-186): Inferred type: 'bj:(type, P2) +// Info 4164: (182-186): Inferred type: ?bj:(type, P2) // Info 4164: (194-211): Inferred type: P3 -// Info 4164: (200-204): Inferred type: 'bw:(type, P3) +// Info 4164: (200-204): Inferred type: ?bw:(type, P3) // Info 4164: (212-229): Inferred type: P4 -// Info 4164: (218-222): Inferred type: 'by:(type, P4) +// Info 4164: (218-222): Inferred type: ?by:(type, P4) // Info 4164: (231-255): Inferred type: void // Info 4164: (256-280): Inferred type: void // Info 4164: (281-305): Inferred type: void @@ -80,56 +80,56 @@ function fun(a: T(int: P3), b: T(str: P4)) { // Info 4164: (332-356): Inferred type: void // Info 4164: (357-381): Inferred type: void // Info 4164: (383-458): Inferred type: void -// Info 4164: (398-405): Inferred type: 'ca:(type, P1) -// Info 4164: (399-404): Inferred type: 'ca:(type, P1) -// Info 4164: (402-404): Inferred type: 'ca:(type, P1) -// Info 4164: (415-456): Inferred type: (T('ca:(type, P1)), T('ca:(type, P1))) -> T('ca:(type, P1)) -// Info 4164: (427-445): Inferred type: (T('ca:(type, P1)), T('ca:(type, P1))) -// Info 4164: (428-435): Inferred type: T('ca:(type, P1)) -// Info 4164: (431-435): Inferred type: T('ca:(type, P1)) -// Info 4164: (431-432): Inferred type: tfun('ca:(type, P1), T('ca:(type, P1))) -// Info 4164: (433-434): Inferred type: 'ca:(type, P1) -// Info 4164: (437-444): Inferred type: T('ca:(type, P1)) -// Info 4164: (440-444): Inferred type: T('ca:(type, P1)) -// Info 4164: (440-441): Inferred type: tfun('ca:(type, P1), T('ca:(type, P1))) -// Info 4164: (442-443): Inferred type: 'ca:(type, P1) -// Info 4164: (449-453): Inferred type: T('ca:(type, P1)) -// Info 4164: (449-450): Inferred type: tfun('ca:(type, P1), T('ca:(type, P1))) -// Info 4164: (451-452): Inferred type: 'ca:(type, P1) +// Info 4164: (398-405): Inferred type: ?ca:(type, P1) +// Info 4164: (399-404): Inferred type: ?ca:(type, P1) +// Info 4164: (402-404): Inferred type: ?ca:(type, P1) +// Info 4164: (415-456): Inferred type: (T(?ca:(type, P1)), T(?ca:(type, P1))) -> T(?ca:(type, P1)) +// Info 4164: (427-445): Inferred type: (T(?ca:(type, P1)), T(?ca:(type, P1))) +// Info 4164: (428-435): Inferred type: T(?ca:(type, P1)) +// Info 4164: (431-435): Inferred type: T(?ca:(type, P1)) +// Info 4164: (431-432): Inferred type: tfun(?ca:(type, P1), T(?ca:(type, P1))) +// Info 4164: (433-434): Inferred type: ?ca:(type, P1) +// Info 4164: (437-444): Inferred type: T(?ca:(type, P1)) +// Info 4164: (440-444): Inferred type: T(?ca:(type, P1)) +// Info 4164: (440-441): Inferred type: tfun(?ca:(type, P1), T(?ca:(type, P1))) +// Info 4164: (442-443): Inferred type: ?ca:(type, P1) +// Info 4164: (449-453): Inferred type: T(?ca:(type, P1)) +// Info 4164: (449-450): Inferred type: tfun(?ca:(type, P1), T(?ca:(type, P1))) +// Info 4164: (451-452): Inferred type: ?ca:(type, P1) // Info 4164: (460-535): Inferred type: void -// Info 4164: (475-482): Inferred type: 'ck:(type, P2) -// Info 4164: (476-481): Inferred type: 'ck:(type, P2) -// Info 4164: (479-481): Inferred type: 'ck:(type, P2) -// Info 4164: (493-533): Inferred type: (T('ck:(type, P2)), T('ck:(type, P2))) -> bool -// Info 4164: (504-522): Inferred type: (T('ck:(type, P2)), T('ck:(type, P2))) -// Info 4164: (505-512): Inferred type: T('ck:(type, P2)) -// Info 4164: (508-512): Inferred type: T('ck:(type, P2)) -// Info 4164: (508-509): Inferred type: tfun('ck:(type, P2), T('ck:(type, P2))) -// Info 4164: (510-511): Inferred type: 'ck:(type, P2) -// Info 4164: (514-521): Inferred type: T('ck:(type, P2)) -// Info 4164: (517-521): Inferred type: T('ck:(type, P2)) -// Info 4164: (517-518): Inferred type: tfun('ck:(type, P2), T('ck:(type, P2))) -// Info 4164: (519-520): Inferred type: 'ck:(type, P2) +// Info 4164: (475-482): Inferred type: ?ck:(type, P2) +// Info 4164: (476-481): Inferred type: ?ck:(type, P2) +// Info 4164: (479-481): Inferred type: ?ck:(type, P2) +// Info 4164: (493-533): Inferred type: (T(?ck:(type, P2)), T(?ck:(type, P2))) -> bool +// Info 4164: (504-522): Inferred type: (T(?ck:(type, P2)), T(?ck:(type, P2))) +// Info 4164: (505-512): Inferred type: T(?ck:(type, P2)) +// Info 4164: (508-512): Inferred type: T(?ck:(type, P2)) +// Info 4164: (508-509): Inferred type: tfun(?ck:(type, P2), T(?ck:(type, P2))) +// Info 4164: (510-511): Inferred type: ?ck:(type, P2) +// Info 4164: (514-521): Inferred type: T(?ck:(type, P2)) +// Info 4164: (517-521): Inferred type: T(?ck:(type, P2)) +// Info 4164: (517-518): Inferred type: tfun(?ck:(type, P2), T(?ck:(type, P2))) +// Info 4164: (519-520): Inferred type: ?ck:(type, P2) // Info 4164: (526-530): Inferred type: bool // Info 4164: (537-618): Inferred type: void -// Info 4164: (552-565): Inferred type: 'bm:(type, P1, P2) -// Info 4164: (553-564): Inferred type: 'bm:(type, P1, P2) -// Info 4164: (556-564): Inferred type: 'bm:(type, P1, P2) -// Info 4164: (557-559): Inferred type: 'bm:(type, P1, P2) -// Info 4164: (561-563): Inferred type: 'bm:(type, P1, P2) -// Info 4164: (575-616): Inferred type: (T('bm:(type, P1, P2)), T('bm:(type, P1, P2))) -> T('bm:(type, P1, P2)) -// Info 4164: (587-605): Inferred type: (T('bm:(type, P1, P2)), T('bm:(type, P1, P2))) -// Info 4164: (588-595): Inferred type: T('bm:(type, P1, P2)) -// Info 4164: (591-595): Inferred type: T('bm:(type, P1, P2)) -// Info 4164: (591-592): Inferred type: tfun('bm:(type, P1, P2), T('bm:(type, P1, P2))) -// Info 4164: (593-594): Inferred type: 'bm:(type, P1, P2) -// Info 4164: (597-604): Inferred type: T('bm:(type, P1, P2)) -// Info 4164: (600-604): Inferred type: T('bm:(type, P1, P2)) -// Info 4164: (600-601): Inferred type: tfun('bm:(type, P1, P2), T('bm:(type, P1, P2))) -// Info 4164: (602-603): Inferred type: 'bm:(type, P1, P2) -// Info 4164: (609-613): Inferred type: T('bm:(type, P1, P2)) -// Info 4164: (609-610): Inferred type: tfun('bm:(type, P1, P2), T('bm:(type, P1, P2))) -// Info 4164: (611-612): Inferred type: 'bm:(type, P1, P2) +// Info 4164: (552-565): Inferred type: ?bm:(type, P1, P2) +// Info 4164: (553-564): Inferred type: ?bm:(type, P1, P2) +// Info 4164: (556-564): Inferred type: ?bm:(type, P1, P2) +// Info 4164: (557-559): Inferred type: ?bm:(type, P1, P2) +// Info 4164: (561-563): Inferred type: ?bm:(type, P1, P2) +// Info 4164: (575-616): Inferred type: (T(?bm:(type, P1, P2)), T(?bm:(type, P1, P2))) -> T(?bm:(type, P1, P2)) +// Info 4164: (587-605): Inferred type: (T(?bm:(type, P1, P2)), T(?bm:(type, P1, P2))) +// Info 4164: (588-595): Inferred type: T(?bm:(type, P1, P2)) +// Info 4164: (591-595): Inferred type: T(?bm:(type, P1, P2)) +// Info 4164: (591-592): Inferred type: tfun(?bm:(type, P1, P2), T(?bm:(type, P1, P2))) +// Info 4164: (593-594): Inferred type: ?bm:(type, P1, P2) +// Info 4164: (597-604): Inferred type: T(?bm:(type, P1, P2)) +// Info 4164: (600-604): Inferred type: T(?bm:(type, P1, P2)) +// Info 4164: (600-601): Inferred type: tfun(?bm:(type, P1, P2), T(?bm:(type, P1, P2))) +// Info 4164: (602-603): Inferred type: ?bm:(type, P1, P2) +// Info 4164: (609-613): Inferred type: T(?bm:(type, P1, P2)) +// Info 4164: (609-610): Inferred type: tfun(?bm:(type, P1, P2), T(?bm:(type, P1, P2))) +// Info 4164: (611-612): Inferred type: ?bm:(type, P1, P2) // Info 4164: (620-748): Inferred type: (T(int), T(str)) -> () // Info 4164: (632-662): Inferred type: (T(int), T(str)) // Info 4164: (633-646): Inferred type: T(int) From fce70ef0e34b7e6cc8d22b0fc08784758503e8d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Mon, 30 Oct 2023 11:09:04 +0100 Subject: [PATCH 0010/1022] Fixing type variables in defined type classes and functions --- .../experimental/analysis/TypeInference.cpp | 34 +++-- .../experimental/analysis/TypeInference.h | 1 + libsolidity/experimental/ast/TypeSystem.cpp | 2 + ...member_type_does_not_match_declaration.sol | 18 +++ .../inference/polymorphic_function_call.sol | 18 +-- .../inference/polymorphic_type.sol | 32 ++--- ...rphic_type_instantiation_and_operators.sol | 118 +++++++++--------- 7 files changed, 130 insertions(+), 93 deletions(-) create mode 100644 test/libsolidity/syntaxTests/experimental/inference/instantiation_member_type_does_not_match_declaration.sol diff --git a/libsolidity/experimental/analysis/TypeInference.cpp b/libsolidity/experimental/analysis/TypeInference.cpp index 9ec7c9786724..cb2de35d331c 100644 --- a/libsolidity/experimental/analysis/TypeInference.cpp +++ b/libsolidity/experimental/analysis/TypeInference.cpp @@ -166,6 +166,13 @@ bool TypeInference::visit(FunctionDefinition const& _functionDefinition) return false; } +void TypeInference::endVisit(FunctionDefinition const& _functionDefinition) +{ + solAssert(m_expressionContext == ExpressionContext::Term); + + m_env->fixTypeVars(TypeEnvironmentHelpers{*m_env}.typeVars(type(_functionDefinition))); +} + void TypeInference::endVisit(Return const& _return) { solAssert(m_currentFunctionType); @@ -204,6 +211,8 @@ bool TypeInference::visit(TypeClassDefinition const& _typeClassDefinition) solAssert(m_analysis.annotation(_typeClassDefinition).typeClass.has_value()); TypeClass typeClass = m_analysis.annotation(_typeClassDefinition).typeClass.value(); Type typeVar = m_typeSystem.typeClassVariable(typeClass); + unify(type(_typeClassDefinition.typeVariable()), typeVar, _typeClassDefinition.location()); + auto& typeMembersAnnotation = annotation().members[typeConstructor(&_typeClassDefinition)]; for (auto subNode: _typeClassDefinition.subNodes()) @@ -235,7 +244,6 @@ bool TypeInference::visit(TypeClassDefinition const& _typeClassDefinition) m_errorReporter.typeError(1807_error, _typeClassDefinition.location(), "Function " + functionName + " depends on invalid type variable."); } - unify(type(_typeClassDefinition.typeVariable()), m_typeSystem.freshTypeVariable({{typeClass}}), _typeClassDefinition.location()); for (auto instantiation: m_analysis.annotation(_typeClassDefinition).instantiations | ranges::views::values) // TODO: recursion-safety? Order of instantiation? instantiation->accept(*this); @@ -663,6 +671,7 @@ bool TypeInference::visit(TypeClassInstantiation const& _typeClassInstantiation) }) | ranges::to>; } } + m_env->fixTypeVars(arguments); Type instanceType{TypeConstant{*typeConstructor, arguments}}; @@ -682,12 +691,8 @@ bool TypeInference::visit(TypeClassInstantiation const& _typeClassInstantiation) auto const& classFunctions = annotation().typeClassFunctions.at(typeClass); - TypeEnvironment newEnv = m_env->clone(); - if (!newEnv.unify(m_typeSystem.typeClassVariable(typeClass), instanceType).empty()) - { - m_errorReporter.typeError(4686_error, _typeClassInstantiation.location(), "Unification of class and instance variable failed."); - return false; - } + solAssert(std::holds_alternative(m_typeSystem.typeClassVariable(typeClass))); + TypeVariable classVar = std::get(m_typeSystem.typeClassVariable(typeClass)); for (auto [name, classFunctionType]: classFunctions) { @@ -696,11 +701,22 @@ bool TypeInference::visit(TypeClassInstantiation const& _typeClassInstantiation) m_errorReporter.typeError(6948_error, _typeClassInstantiation.location(), "Missing function: " + name); continue; } + Type instantiatedClassFunctionType = TypeEnvironmentHelpers{*m_env}.substitute(classFunctionType, classVar, instanceType); + Type instanceFunctionType = functionTypes.at(name); functionTypes.erase(name); - if (!newEnv.typeEquals(instanceFunctionType, classFunctionType)) - m_errorReporter.typeError(7428_error, _typeClassInstantiation.location(), "Type mismatch for function " + name + " " + TypeEnvironmentHelpers{newEnv}.typeToString(instanceFunctionType) + " != " + TypeEnvironmentHelpers{newEnv}.typeToString(classFunctionType)); + if (!m_env->typeEquals(instanceFunctionType, instantiatedClassFunctionType)) + m_errorReporter.typeError( + 7428_error, + _typeClassInstantiation.location(), + fmt::format( + "Instantiation function '{}' does not match the declaration in the type class ({} != {}).", + name, + TypeEnvironmentHelpers{*m_env}.typeToString(instanceFunctionType), + TypeEnvironmentHelpers{*m_env}.typeToString(instantiatedClassFunctionType) + ) + ); } if (!functionTypes.empty()) diff --git a/libsolidity/experimental/analysis/TypeInference.h b/libsolidity/experimental/analysis/TypeInference.h index df9d0610a9a5..3eb2ad94cf71 100644 --- a/libsolidity/experimental/analysis/TypeInference.h +++ b/libsolidity/experimental/analysis/TypeInference.h @@ -57,6 +57,7 @@ class TypeInference: public ASTConstVisitor bool visit(VariableDeclaration const& _variableDeclaration) override; bool visit(FunctionDefinition const& _functionDefinition) override; + void endVisit(FunctionDefinition const& _functionDefinition) override; bool visit(ParameterList const&) override { return true; } void endVisit(ParameterList const& _parameterList) override; bool visit(SourceUnit const&) override { return true; } diff --git a/libsolidity/experimental/ast/TypeSystem.cpp b/libsolidity/experimental/ast/TypeSystem.cpp index fac5073bb0ca..4ddb2bf7c86c 100644 --- a/libsolidity/experimental/ast/TypeSystem.cpp +++ b/libsolidity/experimental/ast/TypeSystem.cpp @@ -301,6 +301,8 @@ std::variant TypeSystem::declareTypeClass(std::string _n Type typeVariable = (_primitive ? freshVariable({{typeClass}}) : freshTypeVariable({{typeClass}})); solAssert(std::holds_alternative(typeVariable)); + m_globalTypeEnvironment.fixTypeVars({typeVariable}); + m_typeClasses.emplace_back(TypeClassInfo{ typeVariable, _name, diff --git a/test/libsolidity/syntaxTests/experimental/inference/instantiation_member_type_does_not_match_declaration.sol b/test/libsolidity/syntaxTests/experimental/inference/instantiation_member_type_does_not_match_declaration.sol new file mode 100644 index 000000000000..1c845b8eeece --- /dev/null +++ b/test/libsolidity/syntaxTests/experimental/inference/instantiation_member_type_does_not_match_declaration.sol @@ -0,0 +1,18 @@ +pragma experimental solidity; + +type T; +type U; + +class Self: C { + function f(self: Self); +} + +instantiation T: C { + function f(self: U) {} +} +// ==== +// EVMVersion: >=constantinople +// compileViaYul: true +// ---- +// Warning 2264: (0-29): Experimental features are turned on. Do not use experimental features on live deployments. +// TypeError 7428: (95-144): Instantiation function 'f' does not match the declaration in the type class (U -> () != T -> ()). diff --git a/test/libsolidity/syntaxTests/experimental/inference/polymorphic_function_call.sol b/test/libsolidity/syntaxTests/experimental/inference/polymorphic_function_call.sol index 487aea090581..f85f7fd4121e 100644 --- a/test/libsolidity/syntaxTests/experimental/inference/polymorphic_function_call.sol +++ b/test/libsolidity/syntaxTests/experimental/inference/polymorphic_function_call.sol @@ -18,15 +18,15 @@ function run(a: T, b: U(T), c: U(U(T))) { // Info 4164: (39-49): Inferred type: tfun(?u:type, U(?u:type)) // Info 4164: (45-48): Inferred type: ?t:type // Info 4164: (46-47): Inferred type: ?t:type -// Info 4164: (51-82): Inferred type: (?x:type, ?y:type, U(?ba:type)) -> () -// Info 4164: (61-79): Inferred type: (?x:type, ?y:type, U(?ba:type)) -// Info 4164: (62-63): Inferred type: ?x:type -// Info 4164: (65-69): Inferred type: ?y:type -// Info 4164: (68-69): Inferred type: ?y:type -// Info 4164: (71-78): Inferred type: U(?ba:type) -// Info 4164: (74-78): Inferred type: U(?ba:type) -// Info 4164: (74-75): Inferred type: tfun(?ba:type, U(?ba:type)) -// Info 4164: (76-77): Inferred type: ?ba:type +// Info 4164: (51-82): Inferred type: ('x:type, 'y:type, U('ba:type)) -> () +// Info 4164: (61-79): Inferred type: ('x:type, 'y:type, U('ba:type)) +// Info 4164: (62-63): Inferred type: 'x:type +// Info 4164: (65-69): Inferred type: 'y:type +// Info 4164: (68-69): Inferred type: 'y:type +// Info 4164: (71-78): Inferred type: U('ba:type) +// Info 4164: (74-78): Inferred type: U('ba:type) +// Info 4164: (74-75): Inferred type: tfun('ba:type, U('ba:type)) +// Info 4164: (76-77): Inferred type: 'ba:type // Info 4164: (84-159): Inferred type: (T, U(T), U(U(T))) -> () // Info 4164: (96-123): Inferred type: (T, U(T), U(U(T))) // Info 4164: (97-101): Inferred type: T diff --git a/test/libsolidity/syntaxTests/experimental/inference/polymorphic_type.sol b/test/libsolidity/syntaxTests/experimental/inference/polymorphic_type.sol index fa68ad308a83..5aa190ecef5c 100644 --- a/test/libsolidity/syntaxTests/experimental/inference/polymorphic_type.sol +++ b/test/libsolidity/syntaxTests/experimental/inference/polymorphic_type.sol @@ -24,24 +24,24 @@ function run() { // Info 4164: (48-55): Inferred type: U // Info 4164: (56-63): Inferred type: V // Info 4164: (65-81): Inferred type: C -// Info 4164: (71-75): Inferred type: ?be:(type, C) +// Info 4164: (71-75): Inferred type: 'k:(type, C) // Info 4164: (82-98): Inferred type: D -// Info 4164: (88-92): Inferred type: ?bg:(type, D) +// Info 4164: (88-92): Inferred type: 'l:(type, D) // Info 4164: (100-170): Inferred type: () -> () // Info 4164: (112-114): Inferred type: () -// Info 4164: (125-141): Inferred type: T(U, ?bm:type, ?bo:(type, C)) -// Info 4164: (128-141): Inferred type: T(U, ?bm:type, ?bo:(type, C)) -// Info 4164: (128-129): Inferred type: tfun((U, ?bm:type, ?bo:(type, C)), T(U, ?bm:type, ?bo:(type, C))) +// Info 4164: (125-141): Inferred type: T(U, ?bk:type, ?bm:(type, C)) +// Info 4164: (128-141): Inferred type: T(U, ?bk:type, ?bm:(type, C)) +// Info 4164: (128-129): Inferred type: tfun((U, ?bk:type, ?bm:(type, C)), T(U, ?bk:type, ?bm:(type, C))) // Info 4164: (130-131): Inferred type: U -// Info 4164: (133-134): Inferred type: ?bm:type -// Info 4164: (136-140): Inferred type: ?bo:(type, C) -// Info 4164: (136-137): Inferred type: ?bo:(type, C) -// Info 4164: (139-140): Inferred type: ?bo:(type, C) -// Info 4164: (151-167): Inferred type: T(V, ?bt:type, ?bv:(type, D)) -// Info 4164: (154-167): Inferred type: T(V, ?bt:type, ?bv:(type, D)) -// Info 4164: (154-155): Inferred type: tfun((V, ?bt:type, ?bv:(type, D)), T(V, ?bt:type, ?bv:(type, D))) +// Info 4164: (133-134): Inferred type: ?bk:type +// Info 4164: (136-140): Inferred type: ?bm:(type, C) +// Info 4164: (136-137): Inferred type: ?bm:(type, C) +// Info 4164: (139-140): Inferred type: ?bm:(type, C) +// Info 4164: (151-167): Inferred type: T(V, ?br:type, ?bt:(type, D)) +// Info 4164: (154-167): Inferred type: T(V, ?br:type, ?bt:(type, D)) +// Info 4164: (154-155): Inferred type: tfun((V, ?br:type, ?bt:(type, D)), T(V, ?br:type, ?bt:(type, D))) // Info 4164: (156-157): Inferred type: V -// Info 4164: (159-160): Inferred type: ?bt:type -// Info 4164: (162-166): Inferred type: ?bv:(type, D) -// Info 4164: (162-163): Inferred type: ?bv:(type, D) -// Info 4164: (165-166): Inferred type: ?bv:(type, D) +// Info 4164: (159-160): Inferred type: ?br:type +// Info 4164: (162-166): Inferred type: ?bt:(type, D) +// Info 4164: (162-163): Inferred type: ?bt:(type, D) +// Info 4164: (165-166): Inferred type: ?bt:(type, D) diff --git a/test/libsolidity/syntaxTests/experimental/inference/polymorphic_type_instantiation_and_operators.sol b/test/libsolidity/syntaxTests/experimental/inference/polymorphic_type_instantiation_and_operators.sol index 3bff1f4d0ad0..22c4796e0fcd 100644 --- a/test/libsolidity/syntaxTests/experimental/inference/polymorphic_type_instantiation_and_operators.sol +++ b/test/libsolidity/syntaxTests/experimental/inference/polymorphic_type_instantiation_and_operators.sol @@ -57,22 +57,22 @@ function fun(a: T(int: P3), b: T(str: P4)) { // Info 4164: (74-83): Inferred type: int // Info 4164: (84-93): Inferred type: str // Info 4164: (95-156): Inferred type: C -// Info 4164: (101-105): Inferred type: ?bd:(type, C) -// Info 4164: (115-154): Inferred type: (?bd:(type, C), ?bd:(type, C)) -> ?bd:(type, C) -// Info 4164: (127-145): Inferred type: (?bd:(type, C), ?bd:(type, C)) -// Info 4164: (128-135): Inferred type: ?bd:(type, C) -// Info 4164: (131-135): Inferred type: ?bd:(type, C) -// Info 4164: (137-144): Inferred type: ?bd:(type, C) -// Info 4164: (140-144): Inferred type: ?bd:(type, C) -// Info 4164: (149-153): Inferred type: ?bd:(type, C) +// Info 4164: (101-105): Inferred type: 'k:(type, C) +// Info 4164: (115-154): Inferred type: ('k:(type, C), 'k:(type, C)) -> 'k:(type, C) +// Info 4164: (127-145): Inferred type: ('k:(type, C), 'k:(type, C)) +// Info 4164: (128-135): Inferred type: 'k:(type, C) +// Info 4164: (131-135): Inferred type: 'k:(type, C) +// Info 4164: (137-144): Inferred type: 'k:(type, C) +// Info 4164: (140-144): Inferred type: 'k:(type, C) +// Info 4164: (149-153): Inferred type: 'k:(type, C) // Info 4164: (158-175): Inferred type: P1 -// Info 4164: (164-168): Inferred type: ?bg:(type, P1) +// Info 4164: (164-168): Inferred type: 'l:(type, P1) // Info 4164: (176-193): Inferred type: P2 -// Info 4164: (182-186): Inferred type: ?bj:(type, P2) +// Info 4164: (182-186): Inferred type: 'm:(type, P2) // Info 4164: (194-211): Inferred type: P3 -// Info 4164: (200-204): Inferred type: ?bw:(type, P3) +// Info 4164: (200-204): Inferred type: 'n:(type, P3) // Info 4164: (212-229): Inferred type: P4 -// Info 4164: (218-222): Inferred type: ?by:(type, P4) +// Info 4164: (218-222): Inferred type: 'o:(type, P4) // Info 4164: (231-255): Inferred type: void // Info 4164: (256-280): Inferred type: void // Info 4164: (281-305): Inferred type: void @@ -80,56 +80,56 @@ function fun(a: T(int: P3), b: T(str: P4)) { // Info 4164: (332-356): Inferred type: void // Info 4164: (357-381): Inferred type: void // Info 4164: (383-458): Inferred type: void -// Info 4164: (398-405): Inferred type: ?ca:(type, P1) -// Info 4164: (399-404): Inferred type: ?ca:(type, P1) -// Info 4164: (402-404): Inferred type: ?ca:(type, P1) -// Info 4164: (415-456): Inferred type: (T(?ca:(type, P1)), T(?ca:(type, P1))) -> T(?ca:(type, P1)) -// Info 4164: (427-445): Inferred type: (T(?ca:(type, P1)), T(?ca:(type, P1))) -// Info 4164: (428-435): Inferred type: T(?ca:(type, P1)) -// Info 4164: (431-435): Inferred type: T(?ca:(type, P1)) -// Info 4164: (431-432): Inferred type: tfun(?ca:(type, P1), T(?ca:(type, P1))) -// Info 4164: (433-434): Inferred type: ?ca:(type, P1) -// Info 4164: (437-444): Inferred type: T(?ca:(type, P1)) -// Info 4164: (440-444): Inferred type: T(?ca:(type, P1)) -// Info 4164: (440-441): Inferred type: tfun(?ca:(type, P1), T(?ca:(type, P1))) -// Info 4164: (442-443): Inferred type: ?ca:(type, P1) -// Info 4164: (449-453): Inferred type: T(?ca:(type, P1)) -// Info 4164: (449-450): Inferred type: tfun(?ca:(type, P1), T(?ca:(type, P1))) -// Info 4164: (451-452): Inferred type: ?ca:(type, P1) +// Info 4164: (398-405): Inferred type: 'bv:(type, P1) +// Info 4164: (399-404): Inferred type: 'bv:(type, P1) +// Info 4164: (402-404): Inferred type: 'bv:(type, P1) +// Info 4164: (415-456): Inferred type: (T('bv:(type, P1)), T('bv:(type, P1))) -> T('bv:(type, P1)) +// Info 4164: (427-445): Inferred type: (T('bv:(type, P1)), T('bv:(type, P1))) +// Info 4164: (428-435): Inferred type: T('bv:(type, P1)) +// Info 4164: (431-435): Inferred type: T('bv:(type, P1)) +// Info 4164: (431-432): Inferred type: tfun('bv:(type, P1), T('bv:(type, P1))) +// Info 4164: (433-434): Inferred type: 'bv:(type, P1) +// Info 4164: (437-444): Inferred type: T('bv:(type, P1)) +// Info 4164: (440-444): Inferred type: T('bv:(type, P1)) +// Info 4164: (440-441): Inferred type: tfun('bv:(type, P1), T('bv:(type, P1))) +// Info 4164: (442-443): Inferred type: 'bv:(type, P1) +// Info 4164: (449-453): Inferred type: T('bv:(type, P1)) +// Info 4164: (449-450): Inferred type: tfun('bv:(type, P1), T('bv:(type, P1))) +// Info 4164: (451-452): Inferred type: 'bv:(type, P1) // Info 4164: (460-535): Inferred type: void -// Info 4164: (475-482): Inferred type: ?ck:(type, P2) -// Info 4164: (476-481): Inferred type: ?ck:(type, P2) -// Info 4164: (479-481): Inferred type: ?ck:(type, P2) -// Info 4164: (493-533): Inferred type: (T(?ck:(type, P2)), T(?ck:(type, P2))) -> bool -// Info 4164: (504-522): Inferred type: (T(?ck:(type, P2)), T(?ck:(type, P2))) -// Info 4164: (505-512): Inferred type: T(?ck:(type, P2)) -// Info 4164: (508-512): Inferred type: T(?ck:(type, P2)) -// Info 4164: (508-509): Inferred type: tfun(?ck:(type, P2), T(?ck:(type, P2))) -// Info 4164: (510-511): Inferred type: ?ck:(type, P2) -// Info 4164: (514-521): Inferred type: T(?ck:(type, P2)) -// Info 4164: (517-521): Inferred type: T(?ck:(type, P2)) -// Info 4164: (517-518): Inferred type: tfun(?ck:(type, P2), T(?ck:(type, P2))) -// Info 4164: (519-520): Inferred type: ?ck:(type, P2) +// Info 4164: (475-482): Inferred type: 'cf:(type, P2) +// Info 4164: (476-481): Inferred type: 'cf:(type, P2) +// Info 4164: (479-481): Inferred type: 'cf:(type, P2) +// Info 4164: (493-533): Inferred type: (T('cf:(type, P2)), T('cf:(type, P2))) -> bool +// Info 4164: (504-522): Inferred type: (T('cf:(type, P2)), T('cf:(type, P2))) +// Info 4164: (505-512): Inferred type: T('cf:(type, P2)) +// Info 4164: (508-512): Inferred type: T('cf:(type, P2)) +// Info 4164: (508-509): Inferred type: tfun('cf:(type, P2), T('cf:(type, P2))) +// Info 4164: (510-511): Inferred type: 'cf:(type, P2) +// Info 4164: (514-521): Inferred type: T('cf:(type, P2)) +// Info 4164: (517-521): Inferred type: T('cf:(type, P2)) +// Info 4164: (517-518): Inferred type: tfun('cf:(type, P2), T('cf:(type, P2))) +// Info 4164: (519-520): Inferred type: 'cf:(type, P2) // Info 4164: (526-530): Inferred type: bool // Info 4164: (537-618): Inferred type: void -// Info 4164: (552-565): Inferred type: ?bm:(type, P1, P2) -// Info 4164: (553-564): Inferred type: ?bm:(type, P1, P2) -// Info 4164: (556-564): Inferred type: ?bm:(type, P1, P2) -// Info 4164: (557-559): Inferred type: ?bm:(type, P1, P2) -// Info 4164: (561-563): Inferred type: ?bm:(type, P1, P2) -// Info 4164: (575-616): Inferred type: (T(?bm:(type, P1, P2)), T(?bm:(type, P1, P2))) -> T(?bm:(type, P1, P2)) -// Info 4164: (587-605): Inferred type: (T(?bm:(type, P1, P2)), T(?bm:(type, P1, P2))) -// Info 4164: (588-595): Inferred type: T(?bm:(type, P1, P2)) -// Info 4164: (591-595): Inferred type: T(?bm:(type, P1, P2)) -// Info 4164: (591-592): Inferred type: tfun(?bm:(type, P1, P2), T(?bm:(type, P1, P2))) -// Info 4164: (593-594): Inferred type: ?bm:(type, P1, P2) -// Info 4164: (597-604): Inferred type: T(?bm:(type, P1, P2)) -// Info 4164: (600-604): Inferred type: T(?bm:(type, P1, P2)) -// Info 4164: (600-601): Inferred type: tfun(?bm:(type, P1, P2), T(?bm:(type, P1, P2))) -// Info 4164: (602-603): Inferred type: ?bm:(type, P1, P2) -// Info 4164: (609-613): Inferred type: T(?bm:(type, P1, P2)) -// Info 4164: (609-610): Inferred type: tfun(?bm:(type, P1, P2), T(?bm:(type, P1, P2))) -// Info 4164: (611-612): Inferred type: ?bm:(type, P1, P2) +// Info 4164: (552-565): Inferred type: 'bj:(type, P1, P2) +// Info 4164: (553-564): Inferred type: 'bj:(type, P1, P2) +// Info 4164: (556-564): Inferred type: 'bj:(type, P1, P2) +// Info 4164: (557-559): Inferred type: 'bj:(type, P1, P2) +// Info 4164: (561-563): Inferred type: 'bj:(type, P1, P2) +// Info 4164: (575-616): Inferred type: (T('bj:(type, P1, P2)), T('bj:(type, P1, P2))) -> T('bj:(type, P1, P2)) +// Info 4164: (587-605): Inferred type: (T('bj:(type, P1, P2)), T('bj:(type, P1, P2))) +// Info 4164: (588-595): Inferred type: T('bj:(type, P1, P2)) +// Info 4164: (591-595): Inferred type: T('bj:(type, P1, P2)) +// Info 4164: (591-592): Inferred type: tfun('bj:(type, P1, P2), T('bj:(type, P1, P2))) +// Info 4164: (593-594): Inferred type: 'bj:(type, P1, P2) +// Info 4164: (597-604): Inferred type: T('bj:(type, P1, P2)) +// Info 4164: (600-604): Inferred type: T('bj:(type, P1, P2)) +// Info 4164: (600-601): Inferred type: tfun('bj:(type, P1, P2), T('bj:(type, P1, P2))) +// Info 4164: (602-603): Inferred type: 'bj:(type, P1, P2) +// Info 4164: (609-613): Inferred type: T('bj:(type, P1, P2)) +// Info 4164: (609-610): Inferred type: tfun('bj:(type, P1, P2), T('bj:(type, P1, P2))) +// Info 4164: (611-612): Inferred type: 'bj:(type, P1, P2) // Info 4164: (620-748): Inferred type: (T(int), T(str)) -> () // Info 4164: (632-662): Inferred type: (T(int), T(str)) // Info 4164: (633-646): Inferred type: T(int) From 8e210d2f8aa17a71b9306a232db7f4685b99bd13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Tue, 7 Nov 2023 17:27:06 +0100 Subject: [PATCH 0011/1022] Fixing type variables in type definitions --- .../experimental/analysis/TypeInference.cpp | 17 ++- libsolidity/experimental/ast/TypeSystem.cpp | 1 + .../builtin/builtin_type_definition.sol | 20 ++-- .../inference/polymorphic_function_call.sol | 24 ++--- .../inference/polymorphic_type.sol | 38 +++---- .../polymorphic_type_abs_and_rep.sol | 42 ++++---- ...rphic_type_instantiation_and_operators.sol | 100 +++++++++--------- 7 files changed, 128 insertions(+), 114 deletions(-) diff --git a/libsolidity/experimental/analysis/TypeInference.cpp b/libsolidity/experimental/analysis/TypeInference.cpp index cb2de35d331c..63a377f90d56 100644 --- a/libsolidity/experimental/analysis/TypeInference.cpp +++ b/libsolidity/experimental/analysis/TypeInference.cpp @@ -33,6 +33,7 @@ #include #include + #include using namespace solidity; @@ -776,12 +777,21 @@ bool TypeInference::visit(TypeDefinition const& _typeDefinition) return false; if (_typeDefinition.arguments()) + { + ScopedSaveAndRestore expressionContext{m_expressionContext, ExpressionContext::Type}; _typeDefinition.arguments()->accept(*this); + } std::vector arguments; if (_typeDefinition.arguments()) - for (size_t i = 0; i < _typeDefinition.arguments()->parameters().size(); ++i) - arguments.emplace_back(m_typeSystem.freshTypeVariable({})); + for (ASTPointer argumentDeclaration: _typeDefinition.arguments()->parameters()) + { + solAssert(argumentDeclaration); + Type typeVar = type(*argumentDeclaration); + solAssert(std::holds_alternative(typeVar)); + arguments.emplace_back(typeVar); + } + m_env->fixTypeVars(arguments); Type definedType = type(&_typeDefinition, arguments); if (arguments.empty()) @@ -807,6 +817,9 @@ bool TypeInference::visit(TypeDefinition const& _typeDefinition) solAssert(newlyInserted, fmt::format("Members of type '{}' are already defined.", m_typeSystem.constructorInfo(constructor).name)); if (underlyingType) { + // Undeclared type variables are not allowed in type definitions and we fixed all the declared ones. + solAssert(!TypeEnvironmentHelpers{*m_env}.hasGenericTypeVars(*underlyingType)); + members->second.emplace("abs", TypeMember{helper.functionType(*underlyingType, definedType)}); members->second.emplace("rep", TypeMember{helper.functionType(definedType, *underlyingType)}); } diff --git a/libsolidity/experimental/ast/TypeSystem.cpp b/libsolidity/experimental/ast/TypeSystem.cpp index 4ddb2bf7c86c..059054dcdbce 100644 --- a/libsolidity/experimental/ast/TypeSystem.cpp +++ b/libsolidity/experimental/ast/TypeSystem.cpp @@ -283,6 +283,7 @@ TypeConstructor TypeSystem::declareTypeConstructor(std::string _name, std::strin std::generate_n(std::back_inserter(argumentSorts), _arguments, [&](){ return Sort{{primitiveClass(PrimitiveClass::Type)}}; }); std::vector argumentTypes; std::generate_n(std::back_inserter(argumentTypes), _arguments, [&](){ return freshVariable({}); }); + m_globalTypeEnvironment.fixTypeVars(argumentTypes); auto error = instantiateClass(type(constructor, argumentTypes), Arity{argumentSorts, primitiveClass(PrimitiveClass::Type)}); solAssert(!error, *error); } diff --git a/test/libsolidity/syntaxTests/experimental/builtin/builtin_type_definition.sol b/test/libsolidity/syntaxTests/experimental/builtin/builtin_type_definition.sol index fb76e1948b87..373d76c339ff 100644 --- a/test/libsolidity/syntaxTests/experimental/builtin/builtin_type_definition.sol +++ b/test/libsolidity/syntaxTests/experimental/builtin/builtin_type_definition.sol @@ -40,14 +40,14 @@ contract C { // Info 4164: (94-124): Inferred type: word // Info 4164: (125-161): Inferred type: integer // Info 4164: (162-192): Inferred type: () -// Info 4164: (194-228): Inferred type: tfun((?u:type, ?v:type), ?u:type -> ?v:type) -// Info 4164: (202-208): Inferred type: (?s:type, ?t:type) -// Info 4164: (203-204): Inferred type: ?s:type -// Info 4164: (206-207): Inferred type: ?t:type -// Info 4164: (229-265): Inferred type: tfun((?y:type, ?z:type), (?y:type, ?z:type)) -// Info 4164: (238-244): Inferred type: (?w:type, ?x:type) -// Info 4164: (239-240): Inferred type: ?w:type -// Info 4164: (242-243): Inferred type: ?x:type +// Info 4164: (194-228): Inferred type: tfun(('s:type, 't:type), 's:type -> 't:type) +// Info 4164: (202-208): Inferred type: ('s:type, 't:type) +// Info 4164: (203-204): Inferred type: 's:type +// Info 4164: (206-207): Inferred type: 't:type +// Info 4164: (229-265): Inferred type: tfun(('u:type, 'v:type), ('u:type, 'v:type)) +// Info 4164: (238-244): Inferred type: ('u:type, 'v:type) +// Info 4164: (239-240): Inferred type: 'u:type +// Info 4164: (242-243): Inferred type: 'v:type // Info 4164: (284-584): Inferred type: () -> () // Info 4164: (292-294): Inferred type: () // Info 4164: (318-325): Inferred type: void @@ -84,9 +84,9 @@ contract C { // Info 4164: (525-529): Inferred type: word // Info 4164: (540-553): Inferred type: bool // Info 4164: (540-550): Inferred type: (bool, word) -> bool -// Info 4164: (540-544): Inferred type: (?bl:type, ?bm:type) +// Info 4164: (540-544): Inferred type: (?bh:type, ?bi:type) // Info 4164: (551-552): Inferred type: (bool, word) // Info 4164: (563-577): Inferred type: word // Info 4164: (563-574): Inferred type: (bool, word) -> word -// Info 4164: (563-567): Inferred type: (?bq:type, ?br:type) +// Info 4164: (563-567): Inferred type: (?bm:type, ?bn:type) // Info 4164: (575-576): Inferred type: (bool, word) diff --git a/test/libsolidity/syntaxTests/experimental/inference/polymorphic_function_call.sol b/test/libsolidity/syntaxTests/experimental/inference/polymorphic_function_call.sol index f85f7fd4121e..c73a857a2fcb 100644 --- a/test/libsolidity/syntaxTests/experimental/inference/polymorphic_function_call.sol +++ b/test/libsolidity/syntaxTests/experimental/inference/polymorphic_function_call.sol @@ -15,18 +15,18 @@ function run(a: T, b: U(T), c: U(U(T))) { // ---- // Warning 2264: (0-29): Experimental features are turned on. Do not use experimental features on live deployments. // Info 4164: (31-38): Inferred type: T -// Info 4164: (39-49): Inferred type: tfun(?u:type, U(?u:type)) -// Info 4164: (45-48): Inferred type: ?t:type -// Info 4164: (46-47): Inferred type: ?t:type -// Info 4164: (51-82): Inferred type: ('x:type, 'y:type, U('ba:type)) -> () -// Info 4164: (61-79): Inferred type: ('x:type, 'y:type, U('ba:type)) -// Info 4164: (62-63): Inferred type: 'x:type -// Info 4164: (65-69): Inferred type: 'y:type -// Info 4164: (68-69): Inferred type: 'y:type -// Info 4164: (71-78): Inferred type: U('ba:type) -// Info 4164: (74-78): Inferred type: U('ba:type) -// Info 4164: (74-75): Inferred type: tfun('ba:type, U('ba:type)) -// Info 4164: (76-77): Inferred type: 'ba:type +// Info 4164: (39-49): Inferred type: tfun('t:type, U('t:type)) +// Info 4164: (45-48): Inferred type: 't:type +// Info 4164: (46-47): Inferred type: 't:type +// Info 4164: (51-82): Inferred type: ('w:type, 'x:type, U('z:type)) -> () +// Info 4164: (61-79): Inferred type: ('w:type, 'x:type, U('z:type)) +// Info 4164: (62-63): Inferred type: 'w:type +// Info 4164: (65-69): Inferred type: 'x:type +// Info 4164: (68-69): Inferred type: 'x:type +// Info 4164: (71-78): Inferred type: U('z:type) +// Info 4164: (74-78): Inferred type: U('z:type) +// Info 4164: (74-75): Inferred type: tfun('z:type, U('z:type)) +// Info 4164: (76-77): Inferred type: 'z:type // Info 4164: (84-159): Inferred type: (T, U(T), U(U(T))) -> () // Info 4164: (96-123): Inferred type: (T, U(T), U(U(T))) // Info 4164: (97-101): Inferred type: T diff --git a/test/libsolidity/syntaxTests/experimental/inference/polymorphic_type.sol b/test/libsolidity/syntaxTests/experimental/inference/polymorphic_type.sol index 5aa190ecef5c..ca83ca2ec7fc 100644 --- a/test/libsolidity/syntaxTests/experimental/inference/polymorphic_type.sol +++ b/test/libsolidity/syntaxTests/experimental/inference/polymorphic_type.sol @@ -16,11 +16,11 @@ function run() { // compileViaYul: true // ---- // Warning 2264: (0-29): Experimental features are turned on. Do not use experimental features on live deployments. -// Info 4164: (31-47): Inferred type: tfun((?ba:type, ?bb:type, ?bc:type), T(?ba:type, ?bb:type, ?bc:type)) -// Info 4164: (37-46): Inferred type: (?x:type, ?y:type, ?z:type) -// Info 4164: (38-39): Inferred type: ?x:type -// Info 4164: (41-42): Inferred type: ?y:type -// Info 4164: (44-45): Inferred type: ?z:type +// Info 4164: (31-47): Inferred type: tfun(('x:type, 'y:type, 'z:type), T('x:type, 'y:type, 'z:type)) +// Info 4164: (37-46): Inferred type: ('x:type, 'y:type, 'z:type) +// Info 4164: (38-39): Inferred type: 'x:type +// Info 4164: (41-42): Inferred type: 'y:type +// Info 4164: (44-45): Inferred type: 'z:type // Info 4164: (48-55): Inferred type: U // Info 4164: (56-63): Inferred type: V // Info 4164: (65-81): Inferred type: C @@ -29,19 +29,19 @@ function run() { // Info 4164: (88-92): Inferred type: 'l:(type, D) // Info 4164: (100-170): Inferred type: () -> () // Info 4164: (112-114): Inferred type: () -// Info 4164: (125-141): Inferred type: T(U, ?bk:type, ?bm:(type, C)) -// Info 4164: (128-141): Inferred type: T(U, ?bk:type, ?bm:(type, C)) -// Info 4164: (128-129): Inferred type: tfun((U, ?bk:type, ?bm:(type, C)), T(U, ?bk:type, ?bm:(type, C))) +// Info 4164: (125-141): Inferred type: T(U, ?bh:type, ?bj:(type, C)) +// Info 4164: (128-141): Inferred type: T(U, ?bh:type, ?bj:(type, C)) +// Info 4164: (128-129): Inferred type: tfun((U, ?bh:type, ?bj:(type, C)), T(U, ?bh:type, ?bj:(type, C))) // Info 4164: (130-131): Inferred type: U -// Info 4164: (133-134): Inferred type: ?bk:type -// Info 4164: (136-140): Inferred type: ?bm:(type, C) -// Info 4164: (136-137): Inferred type: ?bm:(type, C) -// Info 4164: (139-140): Inferred type: ?bm:(type, C) -// Info 4164: (151-167): Inferred type: T(V, ?br:type, ?bt:(type, D)) -// Info 4164: (154-167): Inferred type: T(V, ?br:type, ?bt:(type, D)) -// Info 4164: (154-155): Inferred type: tfun((V, ?br:type, ?bt:(type, D)), T(V, ?br:type, ?bt:(type, D))) +// Info 4164: (133-134): Inferred type: ?bh:type +// Info 4164: (136-140): Inferred type: ?bj:(type, C) +// Info 4164: (136-137): Inferred type: ?bj:(type, C) +// Info 4164: (139-140): Inferred type: ?bj:(type, C) +// Info 4164: (151-167): Inferred type: T(V, ?bo:type, ?bq:(type, D)) +// Info 4164: (154-167): Inferred type: T(V, ?bo:type, ?bq:(type, D)) +// Info 4164: (154-155): Inferred type: tfun((V, ?bo:type, ?bq:(type, D)), T(V, ?bo:type, ?bq:(type, D))) // Info 4164: (156-157): Inferred type: V -// Info 4164: (159-160): Inferred type: ?br:type -// Info 4164: (162-166): Inferred type: ?bt:(type, D) -// Info 4164: (162-163): Inferred type: ?bt:(type, D) -// Info 4164: (165-166): Inferred type: ?bt:(type, D) +// Info 4164: (159-160): Inferred type: ?bo:type +// Info 4164: (162-166): Inferred type: ?bq:(type, D) +// Info 4164: (162-163): Inferred type: ?bq:(type, D) +// Info 4164: (165-166): Inferred type: ?bq:(type, D) diff --git a/test/libsolidity/syntaxTests/experimental/inference/polymorphic_type_abs_and_rep.sol b/test/libsolidity/syntaxTests/experimental/inference/polymorphic_type_abs_and_rep.sol index 27631d064d18..ebebf6dafc3c 100644 --- a/test/libsolidity/syntaxTests/experimental/inference/polymorphic_type_abs_and_rep.sol +++ b/test/libsolidity/syntaxTests/experimental/inference/polymorphic_type_abs_and_rep.sol @@ -24,15 +24,15 @@ function fun() { // Warning 2264: (0-29): Experimental features are turned on. Do not use experimental features on live deployments. // Info 4164: (31-41): Inferred type: uint // Info 4164: (42-54): Inferred type: string -// Info 4164: (56-66): Inferred type: tfun(?v:type, T(?v:type)) -// Info 4164: (62-65): Inferred type: ?u:type -// Info 4164: (63-64): Inferred type: ?u:type -// Info 4164: (67-84): Inferred type: tfun(?x:type, U(?x:type)) -// Info 4164: (73-76): Inferred type: ?w:type -// Info 4164: (74-75): Inferred type: ?w:type -// Info 4164: (79-83): Inferred type: T(?w:type) -// Info 4164: (79-80): Inferred type: tfun(?w:type, T(?w:type)) -// Info 4164: (81-82): Inferred type: ?w:type +// Info 4164: (56-66): Inferred type: tfun('u:type, T('u:type)) +// Info 4164: (62-65): Inferred type: 'u:type +// Info 4164: (63-64): Inferred type: 'u:type +// Info 4164: (67-84): Inferred type: tfun('v:type, U('v:type)) +// Info 4164: (73-76): Inferred type: 'v:type +// Info 4164: (74-75): Inferred type: 'v:type +// Info 4164: (79-83): Inferred type: T('v:type) +// Info 4164: (79-80): Inferred type: tfun('v:type, T('v:type)) +// Info 4164: (81-82): Inferred type: 'v:type // Info 4164: (86-245): Inferred type: () -> () // Info 4164: (98-100): Inferred type: () // Info 4164: (111-121): Inferred type: U(uint) @@ -43,13 +43,13 @@ function fun() { // Info 4164: (134-141): Inferred type: T(uint) // Info 4164: (134-135): Inferred type: tfun(uint, T(uint)) // Info 4164: (136-140): Inferred type: uint -// Info 4164: (147-155): Inferred type: T(?bi:type) -// Info 4164: (147-152): Inferred type: U(uint) -> T(?bi:type) -// Info 4164: (147-148): Inferred type: U(?bg:type) +// Info 4164: (147-155): Inferred type: T(uint) +// Info 4164: (147-152): Inferred type: U(uint) -> T(uint) +// Info 4164: (147-148): Inferred type: U(?be:type) // Info 4164: (153-154): Inferred type: U(uint) -// Info 4164: (161-169): Inferred type: U(?bm:type) -// Info 4164: (161-166): Inferred type: T(uint) -> U(?bm:type) -// Info 4164: (161-162): Inferred type: U(?bk:type) +// Info 4164: (161-169): Inferred type: U(uint) +// Info 4164: (161-166): Inferred type: T(uint) -> U(uint) +// Info 4164: (161-162): Inferred type: U(?bh:type) // Info 4164: (167-168): Inferred type: T(uint) // Info 4164: (180-192): Inferred type: U(string) // Info 4164: (183-192): Inferred type: U(string) @@ -59,11 +59,11 @@ function fun() { // Info 4164: (205-214): Inferred type: T(string) // Info 4164: (205-206): Inferred type: tfun(string, T(string)) // Info 4164: (207-213): Inferred type: string -// Info 4164: (220-228): Inferred type: T(?bu:type) -// Info 4164: (220-225): Inferred type: U(string) -> T(?bu:type) -// Info 4164: (220-221): Inferred type: U(?bs:type) +// Info 4164: (220-228): Inferred type: T(string) +// Info 4164: (220-225): Inferred type: U(string) -> T(string) +// Info 4164: (220-221): Inferred type: U(?bo:type) // Info 4164: (226-227): Inferred type: U(string) -// Info 4164: (234-242): Inferred type: U(?by:type) -// Info 4164: (234-239): Inferred type: T(string) -> U(?by:type) -// Info 4164: (234-235): Inferred type: U(?bw:type) +// Info 4164: (234-242): Inferred type: U(string) +// Info 4164: (234-239): Inferred type: T(string) -> U(string) +// Info 4164: (234-235): Inferred type: U(?br:type) // Info 4164: (240-241): Inferred type: T(string) diff --git a/test/libsolidity/syntaxTests/experimental/inference/polymorphic_type_instantiation_and_operators.sol b/test/libsolidity/syntaxTests/experimental/inference/polymorphic_type_instantiation_and_operators.sol index 22c4796e0fcd..c26436e06cca 100644 --- a/test/libsolidity/syntaxTests/experimental/inference/polymorphic_type_instantiation_and_operators.sol +++ b/test/libsolidity/syntaxTests/experimental/inference/polymorphic_type_instantiation_and_operators.sol @@ -51,9 +51,9 @@ function fun(a: T(int: P3), b: T(str: P4)) { // ---- // Warning 2264: (0-29): Experimental features are turned on. Do not use experimental features on live deployments. // Info 4164: (31-61): Inferred type: bool -// Info 4164: (63-73): Inferred type: tfun(?z:type, T(?z:type)) -// Info 4164: (69-72): Inferred type: ?y:type -// Info 4164: (70-71): Inferred type: ?y:type +// Info 4164: (63-73): Inferred type: tfun('y:type, T('y:type)) +// Info 4164: (69-72): Inferred type: 'y:type +// Info 4164: (70-71): Inferred type: 'y:type // Info 4164: (74-83): Inferred type: int // Info 4164: (84-93): Inferred type: str // Info 4164: (95-156): Inferred type: C @@ -80,56 +80,56 @@ function fun(a: T(int: P3), b: T(str: P4)) { // Info 4164: (332-356): Inferred type: void // Info 4164: (357-381): Inferred type: void // Info 4164: (383-458): Inferred type: void -// Info 4164: (398-405): Inferred type: 'bv:(type, P1) -// Info 4164: (399-404): Inferred type: 'bv:(type, P1) -// Info 4164: (402-404): Inferred type: 'bv:(type, P1) -// Info 4164: (415-456): Inferred type: (T('bv:(type, P1)), T('bv:(type, P1))) -> T('bv:(type, P1)) -// Info 4164: (427-445): Inferred type: (T('bv:(type, P1)), T('bv:(type, P1))) -// Info 4164: (428-435): Inferred type: T('bv:(type, P1)) -// Info 4164: (431-435): Inferred type: T('bv:(type, P1)) -// Info 4164: (431-432): Inferred type: tfun('bv:(type, P1), T('bv:(type, P1))) -// Info 4164: (433-434): Inferred type: 'bv:(type, P1) -// Info 4164: (437-444): Inferred type: T('bv:(type, P1)) -// Info 4164: (440-444): Inferred type: T('bv:(type, P1)) -// Info 4164: (440-441): Inferred type: tfun('bv:(type, P1), T('bv:(type, P1))) -// Info 4164: (442-443): Inferred type: 'bv:(type, P1) -// Info 4164: (449-453): Inferred type: T('bv:(type, P1)) -// Info 4164: (449-450): Inferred type: tfun('bv:(type, P1), T('bv:(type, P1))) -// Info 4164: (451-452): Inferred type: 'bv:(type, P1) +// Info 4164: (398-405): Inferred type: 'bu:(type, P1) +// Info 4164: (399-404): Inferred type: 'bu:(type, P1) +// Info 4164: (402-404): Inferred type: 'bu:(type, P1) +// Info 4164: (415-456): Inferred type: (T('bu:(type, P1)), T('bu:(type, P1))) -> T('bu:(type, P1)) +// Info 4164: (427-445): Inferred type: (T('bu:(type, P1)), T('bu:(type, P1))) +// Info 4164: (428-435): Inferred type: T('bu:(type, P1)) +// Info 4164: (431-435): Inferred type: T('bu:(type, P1)) +// Info 4164: (431-432): Inferred type: tfun('bu:(type, P1), T('bu:(type, P1))) +// Info 4164: (433-434): Inferred type: 'bu:(type, P1) +// Info 4164: (437-444): Inferred type: T('bu:(type, P1)) +// Info 4164: (440-444): Inferred type: T('bu:(type, P1)) +// Info 4164: (440-441): Inferred type: tfun('bu:(type, P1), T('bu:(type, P1))) +// Info 4164: (442-443): Inferred type: 'bu:(type, P1) +// Info 4164: (449-453): Inferred type: T('bu:(type, P1)) +// Info 4164: (449-450): Inferred type: tfun('bu:(type, P1), T('bu:(type, P1))) +// Info 4164: (451-452): Inferred type: 'bu:(type, P1) // Info 4164: (460-535): Inferred type: void -// Info 4164: (475-482): Inferred type: 'cf:(type, P2) -// Info 4164: (476-481): Inferred type: 'cf:(type, P2) -// Info 4164: (479-481): Inferred type: 'cf:(type, P2) -// Info 4164: (493-533): Inferred type: (T('cf:(type, P2)), T('cf:(type, P2))) -> bool -// Info 4164: (504-522): Inferred type: (T('cf:(type, P2)), T('cf:(type, P2))) -// Info 4164: (505-512): Inferred type: T('cf:(type, P2)) -// Info 4164: (508-512): Inferred type: T('cf:(type, P2)) -// Info 4164: (508-509): Inferred type: tfun('cf:(type, P2), T('cf:(type, P2))) -// Info 4164: (510-511): Inferred type: 'cf:(type, P2) -// Info 4164: (514-521): Inferred type: T('cf:(type, P2)) -// Info 4164: (517-521): Inferred type: T('cf:(type, P2)) -// Info 4164: (517-518): Inferred type: tfun('cf:(type, P2), T('cf:(type, P2))) -// Info 4164: (519-520): Inferred type: 'cf:(type, P2) +// Info 4164: (475-482): Inferred type: 'ce:(type, P2) +// Info 4164: (476-481): Inferred type: 'ce:(type, P2) +// Info 4164: (479-481): Inferred type: 'ce:(type, P2) +// Info 4164: (493-533): Inferred type: (T('ce:(type, P2)), T('ce:(type, P2))) -> bool +// Info 4164: (504-522): Inferred type: (T('ce:(type, P2)), T('ce:(type, P2))) +// Info 4164: (505-512): Inferred type: T('ce:(type, P2)) +// Info 4164: (508-512): Inferred type: T('ce:(type, P2)) +// Info 4164: (508-509): Inferred type: tfun('ce:(type, P2), T('ce:(type, P2))) +// Info 4164: (510-511): Inferred type: 'ce:(type, P2) +// Info 4164: (514-521): Inferred type: T('ce:(type, P2)) +// Info 4164: (517-521): Inferred type: T('ce:(type, P2)) +// Info 4164: (517-518): Inferred type: tfun('ce:(type, P2), T('ce:(type, P2))) +// Info 4164: (519-520): Inferred type: 'ce:(type, P2) // Info 4164: (526-530): Inferred type: bool // Info 4164: (537-618): Inferred type: void -// Info 4164: (552-565): Inferred type: 'bj:(type, P1, P2) -// Info 4164: (553-564): Inferred type: 'bj:(type, P1, P2) -// Info 4164: (556-564): Inferred type: 'bj:(type, P1, P2) -// Info 4164: (557-559): Inferred type: 'bj:(type, P1, P2) -// Info 4164: (561-563): Inferred type: 'bj:(type, P1, P2) -// Info 4164: (575-616): Inferred type: (T('bj:(type, P1, P2)), T('bj:(type, P1, P2))) -> T('bj:(type, P1, P2)) -// Info 4164: (587-605): Inferred type: (T('bj:(type, P1, P2)), T('bj:(type, P1, P2))) -// Info 4164: (588-595): Inferred type: T('bj:(type, P1, P2)) -// Info 4164: (591-595): Inferred type: T('bj:(type, P1, P2)) -// Info 4164: (591-592): Inferred type: tfun('bj:(type, P1, P2), T('bj:(type, P1, P2))) -// Info 4164: (593-594): Inferred type: 'bj:(type, P1, P2) -// Info 4164: (597-604): Inferred type: T('bj:(type, P1, P2)) -// Info 4164: (600-604): Inferred type: T('bj:(type, P1, P2)) -// Info 4164: (600-601): Inferred type: tfun('bj:(type, P1, P2), T('bj:(type, P1, P2))) -// Info 4164: (602-603): Inferred type: 'bj:(type, P1, P2) -// Info 4164: (609-613): Inferred type: T('bj:(type, P1, P2)) -// Info 4164: (609-610): Inferred type: tfun('bj:(type, P1, P2), T('bj:(type, P1, P2))) -// Info 4164: (611-612): Inferred type: 'bj:(type, P1, P2) +// Info 4164: (552-565): Inferred type: 'bi:(type, P1, P2) +// Info 4164: (553-564): Inferred type: 'bi:(type, P1, P2) +// Info 4164: (556-564): Inferred type: 'bi:(type, P1, P2) +// Info 4164: (557-559): Inferred type: 'bi:(type, P1, P2) +// Info 4164: (561-563): Inferred type: 'bi:(type, P1, P2) +// Info 4164: (575-616): Inferred type: (T('bi:(type, P1, P2)), T('bi:(type, P1, P2))) -> T('bi:(type, P1, P2)) +// Info 4164: (587-605): Inferred type: (T('bi:(type, P1, P2)), T('bi:(type, P1, P2))) +// Info 4164: (588-595): Inferred type: T('bi:(type, P1, P2)) +// Info 4164: (591-595): Inferred type: T('bi:(type, P1, P2)) +// Info 4164: (591-592): Inferred type: tfun('bi:(type, P1, P2), T('bi:(type, P1, P2))) +// Info 4164: (593-594): Inferred type: 'bi:(type, P1, P2) +// Info 4164: (597-604): Inferred type: T('bi:(type, P1, P2)) +// Info 4164: (600-604): Inferred type: T('bi:(type, P1, P2)) +// Info 4164: (600-601): Inferred type: tfun('bi:(type, P1, P2), T('bi:(type, P1, P2))) +// Info 4164: (602-603): Inferred type: 'bi:(type, P1, P2) +// Info 4164: (609-613): Inferred type: T('bi:(type, P1, P2)) +// Info 4164: (609-610): Inferred type: tfun('bi:(type, P1, P2), T('bi:(type, P1, P2))) +// Info 4164: (611-612): Inferred type: 'bi:(type, P1, P2) // Info 4164: (620-748): Inferred type: (T(int), T(str)) -> () // Info 4164: (632-662): Inferred type: (T(int), T(str)) // Info 4164: (633-646): Inferred type: T(int) From 7bf8ff29328de69a443d6e5e90459001f188cfce Mon Sep 17 00:00:00 2001 From: r0qs Date: Mon, 5 Feb 2024 13:51:40 +0100 Subject: [PATCH 0012/1022] Fix openzeppelin external test --- test/externalTests/zeppelin.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/externalTests/zeppelin.sh b/test/externalTests/zeppelin.sh index 54d753347573..64e6f5f0ec90 100755 --- a/test/externalTests/zeppelin.sh +++ b/test/externalTests/zeppelin.sh @@ -106,6 +106,10 @@ function zeppelin_test force_hardhat_compiler_settings "$config_file" "$(first_word "$SELECTED_PRESETS")" npm install + # TODO: We fix the version to 2.0.3 instead of 2.0.4 since the latter does not work with ethers.js 6.10.0 + # Maybe related to the use of dynamic imports here: https://github.com/NomicFoundation/hardhat/commit/16ae15642951ac324ef7093a3342f7cf3a2a49a4 + npm install @nomicfoundation/hardhat-chai-matchers@2.0.3 + replace_version_pragmas for preset in $SELECTED_PRESETS; do From a3e5f3f43154382118d25a0937dec67d3b062f5a Mon Sep 17 00:00:00 2001 From: Jeason Date: Fri, 19 Jan 2024 08:13:06 +0000 Subject: [PATCH 0013/1022] feat: add new rule name `usingAliases` for solidity `usingDirective` --- docs/grammar/SolidityParser.g4 | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/docs/grammar/SolidityParser.g4 b/docs/grammar/SolidityParser.g4 index 4a756029c2ef..c46cefd2fa34 100644 --- a/docs/grammar/SolidityParser.g4 +++ b/docs/grammar/SolidityParser.g4 @@ -337,7 +337,14 @@ userDefinableOperator: * Using directive to attach library functions and free functions to types. * Can occur within contracts and libraries and at the file level. */ -usingDirective: Using (identifierPath | (LBrace identifierPath (As userDefinableOperator)? (Comma identifierPath (As userDefinableOperator)?)* RBrace)) For (Mul | typeName) Global? Semicolon; +usingDirective: + Using ( + identifierPath + | (LBrace usingAliases (Comma usingAliases)* RBrace) + ) For (Mul | typeName) Global? Semicolon; + +usingAliases: identifierPath (As userDefinableOperator)?; + /** * A type name can be an elementary type, a function type, a mapping type, a user-defined type * (e.g. a contract or struct) or an array type. From ed96eb256f7519f350abc83b2eb7c712efe992ce Mon Sep 17 00:00:00 2001 From: Bhargava Shastry Date: Thu, 25 Jan 2024 06:36:50 +0100 Subject: [PATCH 0014/1022] Yul fuzzer: Support blobhash(uint) global function --- test/tools/ossfuzz/protoToYul.cpp | 9 +++++++++ test/tools/ossfuzz/yulProto.proto | 1 + 2 files changed, 10 insertions(+) diff --git a/test/tools/ossfuzz/protoToYul.cpp b/test/tools/ossfuzz/protoToYul.cpp index 1719dec46c98..1ba0d599d4b7 100644 --- a/test/tools/ossfuzz/protoToYul.cpp +++ b/test/tools/ossfuzz/protoToYul.cpp @@ -599,6 +599,12 @@ void ProtoConverter::visit(UnaryOp const& _x) return; } + if (op == UnaryOp::BLOBHASH && !m_evmVersion.hasBlobHash()) + { + m_output << dictionaryToken(); + return; + } + // The following instructions may lead to change of EVM state and are hence // excluded to avoid false positives. if ( @@ -647,6 +653,9 @@ void ProtoConverter::visit(UnaryOp const& _x) case UnaryOp::BLOCKHASH: m_output << "blockhash"; break; + case UnaryOp::BLOBHASH: + m_output << "blobhash"; + break; } m_output << "("; if (op == UnaryOp::MLOAD) diff --git a/test/tools/ossfuzz/yulProto.proto b/test/tools/ossfuzz/yulProto.proto index 2c10329de683..cf14b887c1b3 100644 --- a/test/tools/ossfuzz/yulProto.proto +++ b/test/tools/ossfuzz/yulProto.proto @@ -156,6 +156,7 @@ message UnaryOp { EXTCODEHASH = 7; BALANCE = 8; BLOCKHASH = 9; + BLOBHASH = 10; } required UOp op = 1; required Expression operand = 2; From c7db606144fd426d561196f6e38006073cfb18dc Mon Sep 17 00:00:00 2001 From: pgebal Date: Tue, 6 Feb 2024 11:43:42 +0100 Subject: [PATCH 0015/1022] Print a warning about function parameter names being used instead of values in SMTChecker (#14832) --- Changelog.md | 1 + libsolidity/formal/Predicate.cpp | 11 +++++++++-- test/libsolidity/smtCheckerTests/types/string_1.sol | 3 ++- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/Changelog.md b/Changelog.md index 7ab13de8fe4f..d20c266d8384 100644 --- a/Changelog.md +++ b/Changelog.md @@ -23,6 +23,7 @@ Language Features: Compiler Features: * EVM: Support for the EVM Version "Cancun". * SMTChecker: Support `bytes.concat` except when string literals are passed as arguments. + * SMTChecker: Print a message that function parameter name was used instead of a concrete value in a counterexample when the concrete value found by the solver is too long to print. * Standard JSON Interface: Add experimental support to import EVM assembly in the format used by ``--asm-json``. * TypeChecker: Comparison of internal function pointers now yields a warning, as it can produce unexpected results with the legacy pipeline enabled. diff --git a/libsolidity/formal/Predicate.cpp b/libsolidity/formal/Predicate.cpp index 58a5a5a3e721..01316d75ff43 100644 --- a/libsolidity/formal/Predicate.cpp +++ b/libsolidity/formal/Predicate.cpp @@ -316,11 +316,14 @@ std::string Predicate::formatSummaryCall( auto const& params = fun->parameters(); solAssert(params.size() == functionArgsCex.size(), ""); + bool paramNameInsteadOfValue = false; for (unsigned i = 0; i < params.size(); ++i) if (params.at(i) && functionArgsCex.at(i)) functionArgs.emplace_back(*functionArgsCex.at(i)); - else + else { + paramNameInsteadOfValue = true; functionArgs.emplace_back(params[i]->name()); + } std::string fName = fun->isConstructor() ? "constructor" : fun->isFallback() ? "fallback" : @@ -335,7 +338,11 @@ std::string Predicate::formatSummaryCall( solAssert(fun->annotation().contract, ""); prefix = fun->annotation().contract->name() + "."; } - return prefix + fName + "(" + boost::algorithm::join(functionArgs, ", ") + ")" + txModel; + + std::string summary = prefix + fName + "(" + boost::algorithm::join(functionArgs, ", ") + ")" + txModel; + if (paramNameInsteadOfValue) + summary += " -- counterexample incomplete; parameter name used instead of value"; + return summary; } std::vector> Predicate::summaryStateValues(std::vector const& _args) const diff --git a/test/libsolidity/smtCheckerTests/types/string_1.sol b/test/libsolidity/smtCheckerTests/types/string_1.sol index 8209f992805d..3a74a8e1ce31 100644 --- a/test/libsolidity/smtCheckerTests/types/string_1.sol +++ b/test/libsolidity/smtCheckerTests/types/string_1.sol @@ -6,5 +6,6 @@ contract C } // ==== // SMTEngine: all +// SMTIgnoreCex: no // ---- -// Warning 6328: (77-121): CHC: Assertion violation happens here.\nCounterexample:\n\n\nTransaction trace:\nC.constructor()\nC.f(s1, s2) +// Warning 6328: (77-121): CHC: Assertion violation happens here.\nCounterexample:\n\n\nTransaction trace:\nC.constructor()\nC.f(s1, s2) -- counterexample incomplete; parameter name used instead of value From 1c8072a2099e17a2467356fc862cae9b2074a3ff Mon Sep 17 00:00:00 2001 From: Nikola Matic Date: Wed, 7 Feb 2024 11:56:50 +0100 Subject: [PATCH 0016/1022] Remove dynamic byte arrays from value types section --- docs/types/value-types.rst | 8 -------- 1 file changed, 8 deletions(-) diff --git a/docs/types/value-types.rst b/docs/types/value-types.rst index d44d2fd70ad8..12fcb0b171d6 100644 --- a/docs/types/value-types.rst +++ b/docs/types/value-types.rst @@ -415,14 +415,6 @@ Members: .. note:: Prior to version 0.8.0, ``byte`` used to be an alias for ``bytes1``. -Dynamically-sized byte array ----------------------------- - -``bytes``: - Dynamically-sized byte array, see :ref:`arrays`. Not a value-type! -``string``: - Dynamically-sized UTF-8-encoded string, see :ref:`arrays`. Not a value-type! - .. index:: address, ! literal;address .. _address_literals: From 71a05dfe538c980c8987a5cdb04b273d6f0d755c Mon Sep 17 00:00:00 2001 From: Nikola Matic Date: Thu, 11 Jan 2024 13:04:52 +0100 Subject: [PATCH 0017/1022] Purge using namespace std from test/yulPhaser --- scripts/check_style.sh | 1 + test/yulPhaser/AlgorithmRunner.cpp | 125 ++++++++++++------------ test/yulPhaser/Chromosome.cpp | 19 ++-- test/yulPhaser/Common.cpp | 25 +++-- test/yulPhaser/FitnessMetrics.cpp | 35 ++++--- test/yulPhaser/GeneticAlgorithms.cpp | 83 ++++++++-------- test/yulPhaser/Mutations.cpp | 139 +++++++++++++-------------- test/yulPhaser/PairSelections.cpp | 52 +++++----- test/yulPhaser/Phaser.cpp | 85 ++++++++-------- test/yulPhaser/Population.cpp | 51 +++++----- test/yulPhaser/Program.cpp | 75 +++++++-------- test/yulPhaser/ProgramCache.cpp | 39 ++++---- test/yulPhaser/Selections.cpp | 93 +++++++++--------- test/yulPhaser/SimulationRNG.cpp | 44 ++++----- test/yulPhaser/TestHelpers.cpp | 27 +++--- test/yulPhaser/TestHelpersTest.cpp | 19 ++-- 16 files changed, 448 insertions(+), 464 deletions(-) diff --git a/scripts/check_style.sh b/scripts/check_style.sh index 7bcd8cca36c9..fe4d19734fc1 100755 --- a/scripts/check_style.sh +++ b/scripts/check_style.sh @@ -50,6 +50,7 @@ NAMESPACE_STD_FREE_FILES=( test/libyul/* test/solc/* test/tools/yulInterpreter/* + test/yulPhaser/* ) ( diff --git a/test/yulPhaser/AlgorithmRunner.cpp b/test/yulPhaser/AlgorithmRunner.cpp index 003403929eb2..56868f1ce76e 100644 --- a/test/yulPhaser/AlgorithmRunner.cpp +++ b/test/yulPhaser/AlgorithmRunner.cpp @@ -35,7 +35,6 @@ #include #include -using namespace std; using namespace boost::unit_test::framework; using namespace boost::test_tools; using namespace solidity::langutil; @@ -74,44 +73,44 @@ class AlgorithmRunnerFixture { protected: // NOTE: Regexes here should not contain spaces because we strip them before matching - regex RoundSummaryRegex{R"(-+ROUND\d+\[round:[0-9.]+s,total:[0-9.]+s\]-+)"}; - regex InitialPopulationHeaderRegex{"-+INITIALPOPULATION-+"}; + std::regex RoundSummaryRegex{R"(-+ROUND\d+\[round:[0-9.]+s,total:[0-9.]+s\]-+)"}; + std::regex InitialPopulationHeaderRegex{"-+INITIALPOPULATION-+"}; - string individualPattern(Individual const& individual) const + std::string individualPattern(Individual const& individual) const { - ostringstream output; + std::ostringstream output; output << individual.fitness << individual.chromosome; return output.str(); } - string topChromosomePattern(size_t roundNumber, Individual const& individual) const + std::string topChromosomePattern(size_t roundNumber, Individual const& individual) const { - ostringstream output; + std::ostringstream output; output << roundNumber << R"(\|[0-9.]+\|)" << individualPattern(individual); return output.str(); } - bool nextLineMatches(stringstream& stream, regex const& pattern) const + bool nextLineMatches(std::stringstream& stream, std::regex const& pattern) const { - string line; - if (getline(stream, line).fail()) + std::string line; + if (std::getline(stream, line).fail()) return false; - return regex_match(stripWhitespace(line), pattern); + return std::regex_match(stripWhitespace(line), pattern); } - shared_ptr m_fitnessMetric = make_shared(); + std::shared_ptr m_fitnessMetric = std::make_shared(); Population const m_population = Population::makeRandom(m_fitnessMetric, 5, 0, 20); - stringstream m_output; + std::stringstream m_output; AlgorithmRunner::Options m_options; }; class AlgorithmRunnerAutosaveFixture: public AlgorithmRunnerFixture { public: - static vector chromosomeStrings(Population const& _population) + static std::vector chromosomeStrings(Population const& _population) { - vector lines; + std::vector lines; for (auto const& individual: _population.individuals()) lines.push_back(toString(individual.chromosome)); @@ -120,7 +119,7 @@ class AlgorithmRunnerAutosaveFixture: public AlgorithmRunnerFixture protected: TemporaryDirectory m_tempDir; - string const m_autosavePath = (m_tempDir.path() / "population-autosave.txt").string(); + std::string const m_autosavePath = (m_tempDir.path() / "population-autosave.txt").string(); RandomisingAlgorithm m_algorithm; }; @@ -153,12 +152,12 @@ BOOST_FIXTURE_TEST_CASE(run_should_print_round_summary_after_each_round, Algorit runner.run(algorithm); BOOST_TEST(nextLineMatches(m_output, RoundSummaryRegex)); for (auto const& individual: runner.population().individuals()) - BOOST_TEST(nextLineMatches(m_output, regex(individualPattern(individual)))); + BOOST_TEST(nextLineMatches(m_output, std::regex(individualPattern(individual)))); runner.run(algorithm); BOOST_TEST(nextLineMatches(m_output, RoundSummaryRegex)); for (auto const& individual: runner.population().individuals()) - BOOST_TEST(nextLineMatches(m_output, regex(individualPattern(individual)))); + BOOST_TEST(nextLineMatches(m_output, std::regex(individualPattern(individual)))); BOOST_TEST(m_output.peek() == EOF); } @@ -172,9 +171,9 @@ BOOST_FIXTURE_TEST_CASE(run_should_not_print_round_summary_if_not_requested, Alg RandomisingAlgorithm algorithm; runner.run(algorithm); - BOOST_TEST(nextLineMatches(m_output, regex(""))); + BOOST_TEST(nextLineMatches(m_output, std::regex(""))); for (auto const& individual: runner.population().individuals()) - BOOST_TEST(nextLineMatches(m_output, regex(individualPattern(individual)))); + BOOST_TEST(nextLineMatches(m_output, std::regex(individualPattern(individual)))); BOOST_TEST(m_output.peek() == EOF); } @@ -202,7 +201,7 @@ BOOST_FIXTURE_TEST_CASE(run_should_print_only_top_chromosome_if_requested, Algor RandomisingAlgorithm algorithm; runner.run(algorithm); - BOOST_TEST(nextLineMatches(m_output, regex(topChromosomePattern(1, runner.population().individuals()[0])))); + BOOST_TEST(nextLineMatches(m_output, std::regex(topChromosomePattern(1, runner.population().individuals()[0])))); BOOST_TEST(m_output.peek() == EOF); } @@ -216,7 +215,7 @@ BOOST_FIXTURE_TEST_CASE(run_should_not_print_round_number_for_top_chromosome_if_ RandomisingAlgorithm algorithm; runner.run(algorithm); - BOOST_TEST(nextLineMatches(m_output, regex(individualPattern(runner.population().individuals()[0])))); + BOOST_TEST(nextLineMatches(m_output, std::regex(individualPattern(runner.population().individuals()[0])))); BOOST_TEST(m_output.peek() == EOF); } @@ -246,7 +245,7 @@ BOOST_FIXTURE_TEST_CASE(run_should_print_initial_population_if_requested, Algori BOOST_TEST(nextLineMatches(m_output, InitialPopulationHeaderRegex)); for (auto const& individual: m_population.individuals()) - BOOST_TEST(nextLineMatches(m_output, regex(individualPattern(individual)))); + BOOST_TEST(nextLineMatches(m_output, std::regex(individualPattern(individual)))); BOOST_TEST(m_output.peek() == EOF); } @@ -277,7 +276,7 @@ BOOST_FIXTURE_TEST_CASE(run_should_print_whole_initial_population_even_if_only_t BOOST_TEST(nextLineMatches(m_output, InitialPopulationHeaderRegex)); for (auto const& individual: m_population.individuals()) - BOOST_TEST(nextLineMatches(m_output, regex(individualPattern(individual)))); + BOOST_TEST(nextLineMatches(m_output, std::regex(individualPattern(individual)))); BOOST_TEST(m_output.peek() == EOF); } @@ -290,21 +289,21 @@ BOOST_FIXTURE_TEST_CASE(run_should_print_cache_stats_if_requested, AlgorithmRunn m_options.showCacheStats = true; RandomisingAlgorithm algorithm; - vector sourceStreams = { + std::vector sourceStreams = { CharStream("{mstore(10, 20)}", ""), CharStream("{mstore(10, 20)\nsstore(10, 20)}", ""), }; - vector programs = { + std::vector programs = { get(Program::load(sourceStreams[0])), get(Program::load(sourceStreams[1])), }; - vector> caches = { - make_shared(programs[0]), - make_shared(programs[1]), + std::vector> caches = { + std::make_shared(programs[0]), + std::make_shared(programs[1]), }; - shared_ptr fitnessMetric = make_shared(vector>{ - make_shared(nullopt, caches[0], CodeWeights{}), - make_shared(nullopt, caches[1], CodeWeights{}), + std::shared_ptr fitnessMetric = std::make_shared(std::vector>{ + std::make_shared(std::nullopt, caches[0], CodeWeights{}), + std::make_shared(std::nullopt, caches[1], CodeWeights{}), }); Population population = Population::makeRandom(fitnessMetric, 2, 0, 5); @@ -318,14 +317,14 @@ BOOST_FIXTURE_TEST_CASE(run_should_print_cache_stats_if_requested, AlgorithmRunn for (size_t i = 0; i < m_options.maxRounds.value() - 1; ++i) { - BOOST_TEST(nextLineMatches(m_output, regex(".*"))); - BOOST_TEST(nextLineMatches(m_output, regex("-+CACHESTATS-+"))); + BOOST_TEST(nextLineMatches(m_output, std::regex(".*"))); + BOOST_TEST(nextLineMatches(m_output, std::regex("-+CACHESTATS-+"))); if (i > 0) - BOOST_TEST(nextLineMatches(m_output, regex(R"(Round\d+:\d+entries)"))); - BOOST_TEST(nextLineMatches(m_output, regex(R"(Round\d+:\d+entries)"))); - BOOST_TEST(nextLineMatches(m_output, regex(R"(Totalhits:\d+)"))); - BOOST_TEST(nextLineMatches(m_output, regex(R"(Totalmisses:\d+)"))); - BOOST_TEST(nextLineMatches(m_output, regex(R"(Sizeofcachedcode:\d+)"))); + BOOST_TEST(nextLineMatches(m_output, std::regex(R"(Round\d+:\d+entries)"))); + BOOST_TEST(nextLineMatches(m_output, std::regex(R"(Round\d+:\d+entries)"))); + BOOST_TEST(nextLineMatches(m_output, std::regex(R"(Totalhits:\d+)"))); + BOOST_TEST(nextLineMatches(m_output, std::regex(R"(Totalmisses:\d+)"))); + BOOST_TEST(nextLineMatches(m_output, std::regex(R"(Sizeofcachedcode:\d+)"))); } BOOST_REQUIRE(stats.roundEntryCounts.size() == 2); @@ -333,13 +332,13 @@ BOOST_FIXTURE_TEST_CASE(run_should_print_cache_stats_if_requested, AlgorithmRunn BOOST_REQUIRE(stats.roundEntryCounts.count(m_options.maxRounds.value()) == 1); size_t round = m_options.maxRounds.value(); - BOOST_TEST(nextLineMatches(m_output, regex(".*"))); - BOOST_TEST(nextLineMatches(m_output, regex("-+CACHESTATS-+"))); - BOOST_TEST(nextLineMatches(m_output, regex("Round" + toString(round - 1) + ":" + toString(stats.roundEntryCounts[round - 1]) + "entries"))); - BOOST_TEST(nextLineMatches(m_output, regex("Round" + toString(round) + ":" + toString(stats.roundEntryCounts[round]) + "entries"))); - BOOST_TEST(nextLineMatches(m_output, regex("Totalhits:" + toString(stats.hits)))); - BOOST_TEST(nextLineMatches(m_output, regex("Totalmisses:" + toString(stats.misses)))); - BOOST_TEST(nextLineMatches(m_output, regex("Sizeofcachedcode:" + toString(stats.totalCodeSize)))); + BOOST_TEST(nextLineMatches(m_output, std::regex(".*"))); + BOOST_TEST(nextLineMatches(m_output, std::regex("-+CACHESTATS-+"))); + BOOST_TEST(nextLineMatches(m_output, std::regex("Round" + toString(round - 1) + ":" + toString(stats.roundEntryCounts[round - 1]) + "entries"))); + BOOST_TEST(nextLineMatches(m_output, std::regex("Round" + toString(round) + ":" + toString(stats.roundEntryCounts[round]) + "entries"))); + BOOST_TEST(nextLineMatches(m_output, std::regex("Totalhits:" + toString(stats.hits)))); + BOOST_TEST(nextLineMatches(m_output, std::regex("Totalmisses:" + toString(stats.misses)))); + BOOST_TEST(nextLineMatches(m_output, std::regex("Sizeofcachedcode:" + toString(stats.totalCodeSize)))); BOOST_TEST(m_output.peek() == EOF); } @@ -355,9 +354,9 @@ BOOST_FIXTURE_TEST_CASE(run_should_print_message_if_cache_stats_requested_but_ca AlgorithmRunner runner(m_population, {nullptr}, m_options, m_output); runner.run(algorithm); - BOOST_TEST(nextLineMatches(m_output, regex(".*"))); - BOOST_TEST(nextLineMatches(m_output, regex("-+CACHESTATS-+"))); - BOOST_TEST(nextLineMatches(m_output, regex(stripWhitespace("Program cache disabled")))); + BOOST_TEST(nextLineMatches(m_output, std::regex(".*"))); + BOOST_TEST(nextLineMatches(m_output, std::regex("-+CACHESTATS-+"))); + BOOST_TEST(nextLineMatches(m_output, std::regex(stripWhitespace("Program cache disabled")))); BOOST_TEST(m_output.peek() == EOF); } @@ -371,18 +370,18 @@ BOOST_FIXTURE_TEST_CASE(run_should_print_partial_stats_and_message_if_some_cache RandomisingAlgorithm algorithm; CharStream sourceStream = CharStream("{}", ""); - shared_ptr cache = make_shared(get(Program::load(sourceStream))); + std::shared_ptr cache = std::make_shared(std::get(Program::load(sourceStream))); AlgorithmRunner runner(m_population, {cache, nullptr}, m_options, m_output); BOOST_REQUIRE(cache->gatherStats().roundEntryCounts.size() == 0); runner.run(algorithm); - BOOST_TEST(nextLineMatches(m_output, regex(".*"))); - BOOST_TEST(nextLineMatches(m_output, regex("-+CACHESTATS-+"))); - BOOST_TEST(nextLineMatches(m_output, regex(R"(Totalhits:\d+)"))); - BOOST_TEST(nextLineMatches(m_output, regex(R"(Totalmisses:\d+)"))); - BOOST_TEST(nextLineMatches(m_output, regex(R"(Sizeofcachedcode:\d+)"))); - BOOST_TEST(nextLineMatches(m_output, regex(stripWhitespace("Program cache disabled for 1 out of 2 programs")))); + BOOST_TEST(nextLineMatches(m_output, std::regex(".*"))); + BOOST_TEST(nextLineMatches(m_output, std::regex("-+CACHESTATS-+"))); + BOOST_TEST(nextLineMatches(m_output, std::regex(R"(Totalhits:\d+)"))); + BOOST_TEST(nextLineMatches(m_output, std::regex(R"(Totalmisses:\d+)"))); + BOOST_TEST(nextLineMatches(m_output, std::regex(R"(Sizeofcachedcode:\d+)"))); + BOOST_TEST(nextLineMatches(m_output, std::regex(stripWhitespace("Program cache disabled for 1 out of 2 programs")))); BOOST_TEST(m_output.peek() == EOF); } @@ -421,10 +420,10 @@ BOOST_FIXTURE_TEST_CASE(run_should_overwrite_existing_file_if_autosave_file_spec AlgorithmRunner runner(m_population, {}, m_options, m_output); assert(!fs::exists(m_autosavePath)); - vector originalContent = {"Original content"}; + std::vector originalContent = {"Original content"}; { - ofstream tmpFile(m_autosavePath); - tmpFile << originalContent[0] << endl; + std::ofstream tmpFile(m_autosavePath); + tmpFile << originalContent[0] << std::endl; } assert(fs::exists(m_autosavePath)); assert(readLinesFromFile(m_autosavePath) == originalContent); @@ -438,7 +437,7 @@ BOOST_FIXTURE_TEST_CASE(run_should_overwrite_existing_file_if_autosave_file_spec BOOST_FIXTURE_TEST_CASE(run_should_not_save_population_to_file_if_autosave_file_not_specified, AlgorithmRunnerAutosaveFixture) { m_options.maxRounds = 5; - m_options.populationAutosaveFile = nullopt; + m_options.populationAutosaveFile = std::nullopt; AlgorithmRunner runner(m_population, {}, m_options, m_output); assert(!fs::exists(m_autosavePath)); @@ -499,9 +498,9 @@ BOOST_FIXTURE_TEST_CASE(run_should_not_randomise_duplicate_chromosomes_if_not_re BOOST_FIXTURE_TEST_CASE(run_should_clear_cache_at_the_beginning_and_update_it_before_each_round, AlgorithmRunnerFixture) { CharStream sourceStream = CharStream("{}", current_test_case().p_name); - vector> caches = { - make_shared(get(Program::load(sourceStream))), - make_shared(get(Program::load(sourceStream))), + std::vector> caches = { + std::make_shared(std::get(Program::load(sourceStream))), + std::make_shared(std::get(Program::load(sourceStream))), }; m_options.maxRounds = 10; diff --git a/test/yulPhaser/Chromosome.cpp b/test/yulPhaser/Chromosome.cpp index 1d12bf18c161..da109086a916 100644 --- a/test/yulPhaser/Chromosome.cpp +++ b/test/yulPhaser/Chromosome.cpp @@ -40,14 +40,13 @@ #include -using namespace std; using namespace solidity::yul; using namespace solidity::util; namespace solidity::phaser::test { -vector const ChrOmOsoMeSteps{ +std::vector const ChrOmOsoMeSteps{ ConditionalSimplifier::name, FunctionHoister::name, UnusedAssignEliminator::name, @@ -76,10 +75,10 @@ BOOST_AUTO_TEST_CASE(makeRandom_should_use_every_possible_step_with_the_same_pro constexpr int samplesPerStep = 500; constexpr double relativeTolerance = 0.02; - map stepIndices = enumerateOptmisationSteps(); + std::map stepIndices = enumerateOptmisationSteps(); auto chromosome = Chromosome::makeRandom(stepIndices.size() * samplesPerStep); - vector samples; + std::vector samples; for (auto& step: chromosome.optimisationSteps()) samples.push_back(stepIndices.at(step)); @@ -97,7 +96,7 @@ BOOST_AUTO_TEST_CASE(constructor_should_store_genes) BOOST_AUTO_TEST_CASE(constructor_should_store_optimisation_steps) { - vector steps = { + std::vector steps = { StructuralSimplifier::name, BlockFlattener::name, UnusedPruner::name, @@ -108,7 +107,7 @@ BOOST_AUTO_TEST_CASE(constructor_should_store_optimisation_steps) BOOST_AUTO_TEST_CASE(constructor_should_allow_duplicate_steps) { - vector steps = { + std::vector steps = { StructuralSimplifier::name, StructuralSimplifier::name, BlockFlattener::name, @@ -131,7 +130,7 @@ BOOST_AUTO_TEST_CASE(constructor_should_allow_genes_that_do_not_correspond_to_an BOOST_AUTO_TEST_CASE(output_operator_should_create_concise_and_unambiguous_string_representation) { - vector allSteps; + std::vector allSteps; for (auto const& step: OptimiserSuite::allSteps()) allSteps.push_back(step.first); Chromosome chromosome(allSteps); @@ -152,8 +151,8 @@ BOOST_AUTO_TEST_CASE(randomOptimisationStep_should_return_each_step_with_same_pr constexpr int samplesPerStep = 500; constexpr double relativeTolerance = 0.02; - map stepIndices = enumerateOptmisationSteps(); - vector samples; + std::map stepIndices = enumerateOptmisationSteps(); + std::vector samples; for (size_t i = 0; i <= stepIndices.size() * samplesPerStep; ++i) samples.push_back(stepIndices.at(Chromosome::randomOptimisationStep())); @@ -172,7 +171,7 @@ BOOST_AUTO_TEST_CASE(stepsToGenes_should_translate_optimisation_step_names_to_ab BOOST_AUTO_TEST_CASE(genesToSteps_should_translate_optimisation_step_abbreviations_to_names) { - BOOST_TEST(Chromosome::genesToSteps("") == vector{}); + BOOST_TEST(Chromosome::genesToSteps("") == std::vector{}); BOOST_TEST(Chromosome::genesToSteps("ChrOmOsoMe") == ChrOmOsoMeSteps); } diff --git a/test/yulPhaser/Common.cpp b/test/yulPhaser/Common.cpp index 734738483547..c4842045fa3f 100644 --- a/test/yulPhaser/Common.cpp +++ b/test/yulPhaser/Common.cpp @@ -30,7 +30,6 @@ #include #include -using namespace std; using namespace boost::test_tools; using namespace solidity::util; @@ -56,7 +55,7 @@ enum class TestEnum GH, }; -map const TestEnumToStringMap = +std::map const TestEnumToStringMap = { {TestEnum::A, "a"}, {TestEnum::B, "b"}, @@ -64,7 +63,7 @@ map const TestEnumToStringMap = {TestEnum::CD, "c-d"}, {TestEnum::EF, "e f"}, }; -map const StringToTestEnumMap = invertMap(TestEnumToStringMap); +std::map const StringToTestEnumMap = invertMap(TestEnumToStringMap); } @@ -74,29 +73,29 @@ BOOST_AUTO_TEST_SUITE(CommonTest) BOOST_FIXTURE_TEST_CASE(readLinesFromFile_should_return_all_lines_from_a_text_file_as_strings_without_newlines, ReadLinesFromFileFixture) { { - ofstream tmpFile((m_tempDir.path() / "test-file.txt").string()); - tmpFile << endl << "Line 1" << endl << endl << endl << "Line 2" << endl << "#" << endl << endl; + std::ofstream tmpFile((m_tempDir.path() / "test-file.txt").string()); + tmpFile << std::endl << "Line 1" << std::endl << std::endl << std::endl << "Line 2" << std::endl << "#" << std::endl << std::endl; } - vector lines = readLinesFromFile((m_tempDir.path() / "test-file.txt").string()); - BOOST_TEST((lines == vector{"", "Line 1", "", "", "Line 2", "#", ""})); + std::vector lines = readLinesFromFile((m_tempDir.path() / "test-file.txt").string()); + BOOST_TEST((lines == std::vector{"", "Line 1", "", "", "Line 2", "#", ""})); } BOOST_AUTO_TEST_CASE(deserializeChoice_should_convert_string_to_enum) { - istringstream aStream("a"); + std::istringstream aStream("a"); TestEnum aResult; deserializeChoice(aStream, aResult, StringToTestEnumMap); BOOST_CHECK(aResult == TestEnum::A); BOOST_TEST(!aStream.fail()); - istringstream bStream("b"); + std::istringstream bStream("b"); TestEnum bResult; deserializeChoice(bStream, bResult, StringToTestEnumMap); BOOST_CHECK(bResult == TestEnum::B); BOOST_TEST(!bStream.fail()); - istringstream cdStream("c-d"); + std::istringstream cdStream("c-d"); TestEnum cdResult; deserializeChoice(cdStream, cdResult, StringToTestEnumMap); BOOST_CHECK(cdResult == TestEnum::CD); @@ -105,7 +104,7 @@ BOOST_AUTO_TEST_CASE(deserializeChoice_should_convert_string_to_enum) BOOST_AUTO_TEST_CASE(deserializeChoice_should_set_failbit_if_there_is_no_enum_corresponding_to_string) { - istringstream xyzStream("xyz"); + std::istringstream xyzStream("xyz"); TestEnum xyzResult; deserializeChoice(xyzStream, xyzResult, StringToTestEnumMap); BOOST_TEST(xyzStream.fail()); @@ -113,13 +112,13 @@ BOOST_AUTO_TEST_CASE(deserializeChoice_should_set_failbit_if_there_is_no_enum_co BOOST_AUTO_TEST_CASE(deserializeChoice_does_not_have_to_support_strings_with_spaces) { - istringstream abStream("a b"); + std::istringstream abStream("a b"); TestEnum abResult; deserializeChoice(abStream, abResult, StringToTestEnumMap); BOOST_CHECK(abResult == TestEnum::A); BOOST_TEST(!abStream.fail()); - istringstream efStream("e f"); + std::istringstream efStream("e f"); TestEnum efResult; deserializeChoice(efStream, efResult, StringToTestEnumMap); BOOST_TEST(efStream.fail()); diff --git a/test/yulPhaser/FitnessMetrics.cpp b/test/yulPhaser/FitnessMetrics.cpp index bde15a537fd8..7fab2e18935e 100644 --- a/test/yulPhaser/FitnessMetrics.cpp +++ b/test/yulPhaser/FitnessMetrics.cpp @@ -29,7 +29,6 @@ #include -using namespace std; using namespace solidity::langutil; using namespace solidity::util; using namespace solidity::yul; @@ -74,22 +73,22 @@ class ProgramBasedMetricFixture } CharStream m_sourceStream = CharStream(SampleSourceCode, ""); - Chromosome m_chromosome{vector{UnusedPruner::name, EquivalentFunctionCombiner::name}}; - Program m_program = get(Program::load(m_sourceStream)); + Chromosome m_chromosome{std::vector{UnusedPruner::name, EquivalentFunctionCombiner::name}}; + Program m_program = std::get(Program::load(m_sourceStream)); Program m_optimisedProgram = optimisedProgram(m_program); - shared_ptr m_programCache = make_shared(m_program); + std::shared_ptr m_programCache = std::make_shared(m_program); static constexpr CodeWeights m_weights{}; }; class FitnessMetricCombinationFixture: public ProgramBasedMetricFixture { protected: - vector> m_simpleMetrics = { - make_shared(m_program, nullptr, m_weights, 1), - make_shared(m_program, nullptr, m_weights, 2), - make_shared(m_program, nullptr, m_weights, 3), + std::vector> m_simpleMetrics = { + std::make_shared(m_program, nullptr, m_weights, 1), + std::make_shared(m_program, nullptr, m_weights, 2), + std::make_shared(m_program, nullptr, m_weights, 3), }; - vector m_fitness = { + std::vector m_fitness = { m_simpleMetrics[0]->evaluate(m_chromosome), m_simpleMetrics[1]->evaluate(m_chromosome), m_simpleMetrics[2]->evaluate(m_chromosome), @@ -102,7 +101,7 @@ BOOST_AUTO_TEST_SUITE(ProgramBasedMetricTest) BOOST_FIXTURE_TEST_CASE(optimisedProgram_should_return_optimised_program_even_if_cache_not_available, ProgramBasedMetricFixture) { - string code = toString(DummyProgramBasedMetric(m_program, nullptr, m_weights).optimisedProgram(m_chromosome)); + std::string code = toString(DummyProgramBasedMetric(m_program, nullptr, m_weights).optimisedProgram(m_chromosome)); BOOST_TEST(code != toString(m_program)); BOOST_TEST(code == toString(m_optimisedProgram)); @@ -110,7 +109,7 @@ BOOST_FIXTURE_TEST_CASE(optimisedProgram_should_return_optimised_program_even_if BOOST_FIXTURE_TEST_CASE(optimisedProgram_should_use_cache_if_available, ProgramBasedMetricFixture) { - string code = toString(DummyProgramBasedMetric(nullopt, m_programCache, m_weights).optimisedProgram(m_chromosome)); + std::string code = toString(DummyProgramBasedMetric(std::nullopt, m_programCache, m_weights).optimisedProgram(m_chromosome)); BOOST_TEST(code != toString(m_program)); BOOST_TEST(code == toString(m_optimisedProgram)); @@ -119,7 +118,7 @@ BOOST_FIXTURE_TEST_CASE(optimisedProgram_should_use_cache_if_available, ProgramB BOOST_FIXTURE_TEST_CASE(optimisedProgramNoCache_should_return_optimised_program_even_if_cache_not_available, ProgramBasedMetricFixture) { - string code = toString(DummyProgramBasedMetric(m_program, nullptr, m_weights).optimisedProgramNoCache(m_chromosome)); + std::string code = toString(DummyProgramBasedMetric(m_program, nullptr, m_weights).optimisedProgramNoCache(m_chromosome)); BOOST_TEST(code != toString(m_program)); BOOST_TEST(code == toString(m_optimisedProgram)); @@ -127,7 +126,7 @@ BOOST_FIXTURE_TEST_CASE(optimisedProgramNoCache_should_return_optimised_program_ BOOST_FIXTURE_TEST_CASE(optimisedProgramNoCache_should_not_use_cache_even_if_available, ProgramBasedMetricFixture) { - string code = toString(DummyProgramBasedMetric(nullopt, m_programCache, m_weights).optimisedProgramNoCache(m_chromosome)); + std::string code = toString(DummyProgramBasedMetric(std::nullopt, m_programCache, m_weights).optimisedProgramNoCache(m_chromosome)); BOOST_TEST(code != toString(m_program)); BOOST_TEST(code == toString(m_optimisedProgram)); @@ -147,7 +146,7 @@ BOOST_FIXTURE_TEST_CASE(evaluate_should_compute_size_of_the_optimised_program, P BOOST_FIXTURE_TEST_CASE(evaluate_should_be_able_to_use_program_cache_if_available, ProgramBasedMetricFixture) { - size_t fitness = ProgramSize(nullopt, m_programCache, m_weights).evaluate(m_chromosome); + size_t fitness = ProgramSize(std::nullopt, m_programCache, m_weights).evaluate(m_chromosome); BOOST_TEST(fitness != m_program.codeSize(m_weights)); BOOST_TEST(fitness == m_optimisedProgram.codeSize(m_weights)); @@ -190,7 +189,7 @@ BOOST_FIXTURE_TEST_CASE(evaluate_should_compute_the_size_ratio_between_optimised BOOST_FIXTURE_TEST_CASE(evaluate_should_be_able_to_use_program_cache_if_available, ProgramBasedMetricFixture) { BOOST_TEST( - RelativeProgramSize(nullopt, m_programCache, 3, m_weights).evaluate(m_chromosome) == + RelativeProgramSize(std::nullopt, m_programCache, 3, m_weights).evaluate(m_chromosome) == round(1000.0 * double(m_optimisedProgram.codeSize(m_weights)) / double(m_program.codeSize(m_weights))) ); BOOST_TEST(m_programCache->size() == m_chromosome.length()); @@ -219,7 +218,7 @@ BOOST_FIXTURE_TEST_CASE(evaluate_should_return_one_if_number_of_repetitions_is_z BOOST_FIXTURE_TEST_CASE(evaluate_should_return_one_if_the_original_program_size_is_zero, ProgramBasedMetricFixture) { CharStream sourceStream = CharStream("{}", ""); - Program program = get(Program::load(sourceStream)); + Program program = std::get(Program::load(sourceStream)); RelativeProgramSize metric(program, nullptr, 3, m_weights); @@ -264,7 +263,7 @@ BOOST_FIXTURE_TEST_CASE(FitnessMetricMaximum_evaluate_should_compute_maximum_of_ FitnessMetricMaximum metric(m_simpleMetrics); assert(m_simpleMetrics.size() == 3); - BOOST_TEST(metric.evaluate(m_chromosome) == max(m_fitness[0], max(m_fitness[1], m_fitness[2]))); + BOOST_TEST(metric.evaluate(m_chromosome) == std::max(m_fitness[0], std::max(m_fitness[1], m_fitness[2]))); BOOST_TEST(metric.metrics() == m_simpleMetrics); } @@ -273,7 +272,7 @@ BOOST_FIXTURE_TEST_CASE(FitnessMetricMinimum_evaluate_should_compute_minimum_of_ FitnessMetricMinimum metric(m_simpleMetrics); assert(m_simpleMetrics.size() == 3); - BOOST_TEST(metric.evaluate(m_chromosome) == min(m_fitness[0], min(m_fitness[1], m_fitness[2]))); + BOOST_TEST(metric.evaluate(m_chromosome) == std::min(m_fitness[0], std::min(m_fitness[1], m_fitness[2]))); BOOST_TEST(metric.metrics() == m_simpleMetrics); } diff --git a/test/yulPhaser/GeneticAlgorithms.cpp b/test/yulPhaser/GeneticAlgorithms.cpp index 29c9cfa2ecaf..c3b661334499 100644 --- a/test/yulPhaser/GeneticAlgorithms.cpp +++ b/test/yulPhaser/GeneticAlgorithms.cpp @@ -29,7 +29,6 @@ #include #include -using namespace std; using namespace boost::unit_test::framework; using namespace boost::test_tools; using namespace solidity::util; @@ -40,7 +39,7 @@ namespace solidity::phaser::test class GeneticAlgorithmFixture { protected: - shared_ptr m_fitnessMetric = make_shared(); + std::shared_ptr m_fitnessMetric = std::make_shared(); }; class ClassicGeneticAlgorithmFixture: public GeneticAlgorithmFixture @@ -64,41 +63,41 @@ BOOST_AUTO_TEST_SUITE(RandomAlgorithmTest) BOOST_FIXTURE_TEST_CASE(runNextRound_should_preserve_elite_and_randomise_rest_of_population, GeneticAlgorithmFixture) { auto population = Population::makeRandom(m_fitnessMetric, 4, 3, 3) + Population::makeRandom(m_fitnessMetric, 4, 5, 5); - assert((chromosomeLengths(population) == vector{3, 3, 3, 3, 5, 5, 5, 5})); + assert((chromosomeLengths(population) == std::vector{3, 3, 3, 3, 5, 5, 5, 5})); RandomAlgorithm algorithm({0.5, 1, 1}); Population newPopulation = algorithm.runNextRound(population); - BOOST_TEST((chromosomeLengths(newPopulation) == vector{1, 1, 1, 1, 3, 3, 3, 3})); + BOOST_TEST((chromosomeLengths(newPopulation) == std::vector{1, 1, 1, 1, 3, 3, 3, 3})); } BOOST_FIXTURE_TEST_CASE(runNextRound_should_not_replace_elite_with_worse_individuals, GeneticAlgorithmFixture) { auto population = Population::makeRandom(m_fitnessMetric, 4, 3, 3) + Population::makeRandom(m_fitnessMetric, 4, 5, 5); - assert((chromosomeLengths(population) == vector{3, 3, 3, 3, 5, 5, 5, 5})); + assert((chromosomeLengths(population) == std::vector{3, 3, 3, 3, 5, 5, 5, 5})); RandomAlgorithm algorithm({0.5, 7, 7}); Population newPopulation = algorithm.runNextRound(population); - BOOST_TEST((chromosomeLengths(newPopulation) == vector{3, 3, 3, 3, 7, 7, 7, 7})); + BOOST_TEST((chromosomeLengths(newPopulation) == std::vector{3, 3, 3, 3, 7, 7, 7, 7})); } BOOST_FIXTURE_TEST_CASE(runNextRound_should_replace_all_chromosomes_if_zero_size_elite, GeneticAlgorithmFixture) { auto population = Population::makeRandom(m_fitnessMetric, 4, 3, 3) + Population::makeRandom(m_fitnessMetric, 4, 5, 5); - assert((chromosomeLengths(population) == vector{3, 3, 3, 3, 5, 5, 5, 5})); + assert((chromosomeLengths(population) == std::vector{3, 3, 3, 3, 5, 5, 5, 5})); RandomAlgorithm algorithm({0.0, 1, 1}); Population newPopulation = algorithm.runNextRound(population); - BOOST_TEST((chromosomeLengths(newPopulation) == vector{1, 1, 1, 1, 1, 1, 1, 1})); + BOOST_TEST((chromosomeLengths(newPopulation) == std::vector{1, 1, 1, 1, 1, 1, 1, 1})); } BOOST_FIXTURE_TEST_CASE(runNextRound_should_not_replace_any_chromosomes_if_whole_population_is_the_elite, GeneticAlgorithmFixture) { auto population = Population::makeRandom(m_fitnessMetric, 4, 3, 3) + Population::makeRandom(m_fitnessMetric, 4, 5, 5); - assert((chromosomeLengths(population) == vector{3, 3, 3, 3, 5, 5, 5, 5})); + assert((chromosomeLengths(population) == std::vector{3, 3, 3, 3, 5, 5, 5, 5})); RandomAlgorithm algorithm({1.0, 1, 1}); Population newPopulation = algorithm.runNextRound(population); - BOOST_TEST((chromosomeLengths(newPopulation) == vector{3, 3, 3, 3, 5, 5, 5, 5})); + BOOST_TEST((chromosomeLengths(newPopulation) == std::vector{3, 3, 3, 3, 5, 5, 5, 5})); } BOOST_AUTO_TEST_SUITE_END() @@ -107,7 +106,7 @@ BOOST_AUTO_TEST_SUITE(GenerationalElitistWithExclusivePoolsTest) BOOST_FIXTURE_TEST_CASE(runNextRound_should_preserve_elite_and_regenerate_rest_of_population, GeneticAlgorithmFixture) { auto population = Population::makeRandom(m_fitnessMetric, 6, 3, 3) + Population::makeRandom(m_fitnessMetric, 4, 5, 5); - assert((chromosomeLengths(population) == vector{3, 3, 3, 3, 3, 3, 5, 5, 5, 5})); + assert((chromosomeLengths(population) == std::vector{3, 3, 3, 3, 3, 3, 5, 5, 5, 5})); GenerationalElitistWithExclusivePools::Options options = { /* mutationPoolSize = */ 0.2, @@ -123,13 +122,13 @@ BOOST_FIXTURE_TEST_CASE(runNextRound_should_preserve_elite_and_regenerate_rest_o Population newPopulation = algorithm.runNextRound(population); - BOOST_TEST((chromosomeLengths(newPopulation) == vector{0, 0, 3, 3, 3, 3, 3, 3, 3, 3})); + BOOST_TEST((chromosomeLengths(newPopulation) == std::vector{0, 0, 3, 3, 3, 3, 3, 3, 3, 3})); } BOOST_FIXTURE_TEST_CASE(runNextRound_should_not_replace_elite_with_worse_individuals, GeneticAlgorithmFixture) { auto population = Population::makeRandom(m_fitnessMetric, 6, 3, 3) + Population::makeRandom(m_fitnessMetric, 4, 5, 5); - assert(chromosomeLengths(population) == (vector{3, 3, 3, 3, 3, 3, 5, 5, 5, 5})); + assert(chromosomeLengths(population) == (std::vector{3, 3, 3, 3, 3, 3, 5, 5, 5, 5})); GenerationalElitistWithExclusivePools::Options options = { /* mutationPoolSize = */ 0.2, @@ -145,7 +144,7 @@ BOOST_FIXTURE_TEST_CASE(runNextRound_should_not_replace_elite_with_worse_individ Population newPopulation = algorithm.runNextRound(population); - BOOST_TEST((chromosomeLengths(newPopulation) == vector{3, 3, 3, 3, 3, 3, 3, 3, 7, 7})); + BOOST_TEST((chromosomeLengths(newPopulation) == std::vector{3, 3, 3, 3, 3, 3, 3, 3, 7, 7})); } BOOST_FIXTURE_TEST_CASE(runNextRound_should_generate_individuals_in_the_crossover_pool_by_mutating_the_elite, GeneticAlgorithmFixture) @@ -169,7 +168,7 @@ BOOST_FIXTURE_TEST_CASE(runNextRound_should_generate_individuals_in_the_crossove BOOST_TEST(( chromosomeLengths(newPopulation) == - vector{0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 11, 11, 11} + std::vector{0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 11, 11, 11} )); } @@ -179,7 +178,7 @@ BOOST_FIXTURE_TEST_CASE(runNextRound_should_generate_individuals_in_the_crossove Population(m_fitnessMetric, {Chromosome("aa"), Chromosome("ff")}) + Population::makeRandom(m_fitnessMetric, 8, 6, 6) ); - assert((chromosomeLengths(population) == vector{2, 2, 6, 6, 6, 6, 6, 6, 6, 6})); + assert((chromosomeLengths(population) == std::vector{2, 2, 6, 6, 6, 6, 6, 6, 6, 6})); GenerationalElitistWithExclusivePools::Options options = { /* mutationPoolSize = */ 0.0, @@ -196,8 +195,8 @@ BOOST_FIXTURE_TEST_CASE(runNextRound_should_generate_individuals_in_the_crossove SimulationRNG::reset(1); Population newPopulation = algorithm.runNextRound(population); - vector const& newIndividuals = newPopulation.individuals(); - BOOST_TEST((chromosomeLengths(newPopulation) == vector{2, 2, 2, 2, 2, 2, 2, 2, 2, 2})); + std::vector const& newIndividuals = newPopulation.individuals(); + BOOST_TEST((chromosomeLengths(newPopulation) == std::vector{2, 2, 2, 2, 2, 2, 2, 2, 2, 2})); for (auto& individual: newIndividuals) BOOST_TEST(( individual.chromosome == Chromosome("aa") || @@ -228,7 +227,7 @@ BOOST_FIXTURE_TEST_CASE(runNextRound_should_select_individuals_with_probability_ Population::makeRandom(m_fitnessMetric, populationSize / 4, 2, 2) + Population::makeRandom(m_fitnessMetric, populationSize / 4, 3, 3); - map expectedProbabilities = { + std::map expectedProbabilities = { {0, 4.0 / (4 + 3 + 2 + 1)}, {1, 3.0 / (4 + 3 + 2 + 1)}, {2, 2.0 / (4 + 3 + 2 + 1)}, @@ -252,9 +251,9 @@ BOOST_FIXTURE_TEST_CASE(runNextRound_should_select_individuals_with_probability_ BOOST_TEST(newPopulation.individuals().size() == population.individuals().size()); - vector newFitness = chromosomeLengths(newPopulation); - BOOST_TEST(abs(mean(newFitness) - expectedValue) < expectedValue * relativeTolerance); - BOOST_TEST(abs(meanSquaredError(newFitness, expectedValue) - variance) < variance * relativeTolerance); + std::vector newFitness = chromosomeLengths(newPopulation); + BOOST_TEST(std::abs(mean(newFitness) - expectedValue) < expectedValue * relativeTolerance); + BOOST_TEST(std::abs(meanSquaredError(newFitness, expectedValue) - variance) < variance * relativeTolerance); } BOOST_FIXTURE_TEST_CASE(runNextRound_should_select_only_individuals_existing_in_the_original_population, ClassicGeneticAlgorithmFixture) @@ -262,7 +261,7 @@ BOOST_FIXTURE_TEST_CASE(runNextRound_should_select_only_individuals_existing_in_ constexpr size_t populationSize = 1000; auto population = Population::makeRandom(m_fitnessMetric, populationSize, 1, 10); - set originalSteps; + std::set originalSteps; for (auto const& individual: population.individuals()) originalSteps.insert(toString(individual.chromosome)); @@ -281,8 +280,8 @@ BOOST_FIXTURE_TEST_CASE(runNextRound_should_do_crossover, ClassicGeneticAlgorith Chromosome("gg"), Chromosome("gg"), Chromosome("gg"), }); - set originalSteps{"aa", "ff", "gg"}; - set crossedSteps{"af", "fa", "fg", "gf", "ga", "ag"}; + std::set originalSteps{"aa", "ff", "gg"}; + std::set crossedSteps{"af", "fa", "fg", "gf", "ga", "ag"}; m_options.crossoverChance = 0.8; ClassicGeneticAlgorithm algorithm(m_options); @@ -312,22 +311,22 @@ BOOST_FIXTURE_TEST_CASE(runNextRound_should_do_mutation, ClassicGeneticAlgorithm double const variance = m_options.mutationChance * (1 - m_options.mutationChance); Chromosome chromosome("aaaaaaaaaa"); - vector chromosomes(populationSize, chromosome); + std::vector chromosomes(populationSize, chromosome); Population population(m_fitnessMetric, chromosomes); SimulationRNG::reset(1); Population newPopulation = algorithm.runNextRound(population); - vector bernoulliTrials; + std::vector bernoulliTrials; for (auto const& individual: newPopulation.individuals()) { - string steps = toString(individual.chromosome); + std::string steps = toString(individual.chromosome); for (char step: steps) bernoulliTrials.push_back(static_cast(step != 'a')); } - BOOST_TEST(abs(mean(bernoulliTrials) - expectedValue) < expectedValue * relativeTolerance); - BOOST_TEST(abs(meanSquaredError(bernoulliTrials, expectedValue) - variance) < variance * relativeTolerance); + BOOST_TEST(std::abs(mean(bernoulliTrials) - expectedValue) < expectedValue * relativeTolerance); + BOOST_TEST(std::abs(meanSquaredError(bernoulliTrials, expectedValue) - variance) < variance * relativeTolerance); } BOOST_FIXTURE_TEST_CASE(runNextRound_should_do_deletion, ClassicGeneticAlgorithmFixture) @@ -341,22 +340,22 @@ BOOST_FIXTURE_TEST_CASE(runNextRound_should_do_deletion, ClassicGeneticAlgorithm double const variance = m_options.deletionChance * (1 - m_options.deletionChance); Chromosome chromosome("aaaaaaaaaa"); - vector chromosomes(populationSize, chromosome); + std::vector chromosomes(populationSize, chromosome); Population population(m_fitnessMetric, chromosomes); SimulationRNG::reset(1); Population newPopulation = algorithm.runNextRound(population); - vector bernoulliTrials; + std::vector bernoulliTrials; for (auto const& individual: newPopulation.individuals()) { - string steps = toString(individual.chromosome); + std::string steps = toString(individual.chromosome); for (size_t i = 0; i < chromosome.length(); ++i) bernoulliTrials.push_back(static_cast(i >= steps.size())); } - BOOST_TEST(abs(mean(bernoulliTrials) - expectedValue) < expectedValue * relativeTolerance); - BOOST_TEST(abs(meanSquaredError(bernoulliTrials, expectedValue) - variance) < variance * relativeTolerance); + BOOST_TEST(std::abs(mean(bernoulliTrials) - expectedValue) < expectedValue * relativeTolerance); + BOOST_TEST(std::abs(meanSquaredError(bernoulliTrials, expectedValue) - variance) < variance * relativeTolerance); } BOOST_FIXTURE_TEST_CASE(runNextRound_should_do_addition, ClassicGeneticAlgorithmFixture) @@ -370,16 +369,16 @@ BOOST_FIXTURE_TEST_CASE(runNextRound_should_do_addition, ClassicGeneticAlgorithm double const variance = m_options.additionChance * (1 - m_options.additionChance); Chromosome chromosome("aaaaaaaaaa"); - vector chromosomes(populationSize, chromosome); + std::vector chromosomes(populationSize, chromosome); Population population(m_fitnessMetric, chromosomes); SimulationRNG::reset(1); Population newPopulation = algorithm.runNextRound(population); - vector bernoulliTrials; + std::vector bernoulliTrials; for (auto const& individual: newPopulation.individuals()) { - string steps = toString(individual.chromosome); + std::string steps = toString(individual.chromosome); for (size_t i = 0; i < chromosome.length() + 1; ++i) { BOOST_REQUIRE(chromosome.length() <= steps.size() && steps.size() <= 2 * chromosome.length() + 1); @@ -387,21 +386,21 @@ BOOST_FIXTURE_TEST_CASE(runNextRound_should_do_addition, ClassicGeneticAlgorithm } } - BOOST_TEST(abs(mean(bernoulliTrials) - expectedValue) < expectedValue * relativeTolerance); - BOOST_TEST(abs(meanSquaredError(bernoulliTrials, expectedValue) - variance) < variance * relativeTolerance); + BOOST_TEST(std::abs(mean(bernoulliTrials) - expectedValue) < expectedValue * relativeTolerance); + BOOST_TEST(std::abs(meanSquaredError(bernoulliTrials, expectedValue) - variance) < variance * relativeTolerance); } BOOST_FIXTURE_TEST_CASE(runNextRound_should_preserve_elite, ClassicGeneticAlgorithmFixture) { auto population = Population::makeRandom(m_fitnessMetric, 4, 3, 3) + Population::makeRandom(m_fitnessMetric, 6, 5, 5); - assert((chromosomeLengths(population) == vector{3, 3, 3, 3, 5, 5, 5, 5, 5, 5})); + assert((chromosomeLengths(population) == std::vector{3, 3, 3, 3, 5, 5, 5, 5, 5, 5})); m_options.elitePoolSize = 0.5; m_options.deletionChance = 1.0; ClassicGeneticAlgorithm algorithm(m_options); Population newPopulation = algorithm.runNextRound(population); - BOOST_TEST((chromosomeLengths(newPopulation) == vector{0, 0, 0, 0, 0, 3, 3, 3, 3, 5})); + BOOST_TEST((chromosomeLengths(newPopulation) == std::vector{0, 0, 0, 0, 0, 3, 3, 3, 3, 5})); } BOOST_AUTO_TEST_SUITE_END() diff --git a/test/yulPhaser/Mutations.cpp b/test/yulPhaser/Mutations.cpp index 8e1d0238b3ef..a5a715e23a2a 100644 --- a/test/yulPhaser/Mutations.cpp +++ b/test/yulPhaser/Mutations.cpp @@ -30,7 +30,6 @@ #include #include -using namespace std; using namespace solidity::util; using namespace solidity::yul; @@ -48,7 +47,7 @@ BOOST_AUTO_TEST_CASE(geneRandomisation_should_iterate_over_genes_and_replace_the // Use genes that do not represent valid step abbreviations to be able to easily spot added steps. assert(OptimiserSuite::stepAbbreviationToNameMap().count('.') == 0); - Chromosome input = Chromosome(string(inputLength, '.')); + Chromosome input = Chromosome(std::string(inputLength, '.')); SimulationRNG::reset(1); for (size_t randomisationChancePercent = 20; randomisationChancePercent <= 100; randomisationChancePercent += 20) @@ -56,7 +55,7 @@ BOOST_AUTO_TEST_CASE(geneRandomisation_should_iterate_over_genes_and_replace_the double const randomisationChance = double(randomisationChancePercent) / 100.0; Chromosome output = geneRandomisation(randomisationChance)(input); - string outputGenes = output.genes(); + std::string outputGenes = output.genes(); BOOST_REQUIRE(output.length() == input.length()); double const expectedValue = randomisationChance; @@ -66,15 +65,15 @@ BOOST_AUTO_TEST_CASE(geneRandomisation_should_iterate_over_genes_and_replace_the (inputLength - randomisedGeneCount) * expectedValue * expectedValue + randomisedGeneCount * (1 - expectedValue) * (1 - expectedValue); - BOOST_TEST(abs(randomisedGeneCount / inputLength - expectedValue) < tolerance); - BOOST_TEST(abs(squaredError / inputLength - variance) < tolerance); + BOOST_TEST(std::abs(randomisedGeneCount / inputLength - expectedValue) < tolerance); + BOOST_TEST(std::abs(squaredError / inputLength - variance) < tolerance); } } BOOST_AUTO_TEST_CASE(geneRandomisation_should_return_identical_chromosome_if_probability_is_zero) { Chromosome chromosome("fcCUnDvejsrmV"); - function mutation = geneRandomisation(0.0); + std::function mutation = geneRandomisation(0.0); BOOST_TEST(mutation(chromosome) == chromosome); } @@ -86,7 +85,7 @@ BOOST_AUTO_TEST_CASE(geneDeletion_should_iterate_over_genes_and_delete_them_with // Use genes that do not represent valid step abbreviations to be able to easily spot added steps. assert(OptimiserSuite::stepAbbreviationToNameMap().count('.') == 0); - Chromosome input = Chromosome(string(inputLength, '.')); + Chromosome input = Chromosome(std::string(inputLength, '.')); SimulationRNG::reset(1); for (size_t deletionChancePercent = 20; deletionChancePercent < 100; deletionChancePercent += 20) @@ -94,7 +93,7 @@ BOOST_AUTO_TEST_CASE(geneDeletion_should_iterate_over_genes_and_delete_them_with double const deletionChance = double(deletionChancePercent) / 100.0; Chromosome output = geneDeletion(deletionChance)(input); - string outputGenes = output.genes(); + std::string outputGenes = output.genes(); BOOST_REQUIRE(output.length() <= input.length()); BOOST_REQUIRE(static_cast(count(outputGenes.begin(), outputGenes.end(), '.')) == output.length()); @@ -105,15 +104,15 @@ BOOST_AUTO_TEST_CASE(geneDeletion_should_iterate_over_genes_and_delete_them_with (double(inputLength) - deletedGeneCount) * expectedValue * expectedValue + deletedGeneCount * (1.0 - expectedValue) * (1.0 - expectedValue); - BOOST_TEST(abs(deletedGeneCount / double(inputLength) - expectedValue) < tolerance); - BOOST_TEST(abs(squaredError / double(inputLength) - variance) < tolerance); + BOOST_TEST(std::abs(deletedGeneCount / double(inputLength) - expectedValue) < tolerance); + BOOST_TEST(std::abs(squaredError / double(inputLength) - variance) < tolerance); } } BOOST_AUTO_TEST_CASE(geneDeletion_should_return_identical_chromosome_if_probability_is_zero) { Chromosome chromosome("fcCUnDvejsrmV"); - function mutation = geneDeletion(0.0); + std::function mutation = geneDeletion(0.0); BOOST_TEST(mutation(chromosome) == chromosome); } @@ -121,7 +120,7 @@ BOOST_AUTO_TEST_CASE(geneDeletion_should_return_identical_chromosome_if_probabil BOOST_AUTO_TEST_CASE(geneDeletion_should_delete_all_genes_if_probability_is_one) { Chromosome chromosome("fcCUnDvejsrmV"); - function mutation = geneDeletion(1.0); + std::function mutation = geneDeletion(1.0); BOOST_TEST(mutation(chromosome) == Chromosome("")); } @@ -134,7 +133,7 @@ BOOST_AUTO_TEST_CASE(geneAddition_should_iterate_over_gene_positions_and_insert_ // Use genes that do not represent valid step abbreviations to be able to easily spot added steps. assert(OptimiserSuite::stepAbbreviationToNameMap().count('.') == 0); - Chromosome input = Chromosome(string(inputLength, '.')); + Chromosome input = Chromosome(std::string(inputLength, '.')); SimulationRNG::reset(1); for (size_t additionChancePercent = 20; additionChancePercent < 100; additionChancePercent += 20) @@ -145,8 +144,8 @@ BOOST_AUTO_TEST_CASE(geneAddition_should_iterate_over_gene_positions_and_insert_ BOOST_REQUIRE(output.length() >= input.length()); BOOST_REQUIRE(output.length() <= inputLength + maxAdditions); - string_view outputGenes = output.genes(); - size_t preservedGeneCount = static_cast(count(outputGenes.begin(), outputGenes.end(), '.')); + std::string_view outputGenes = output.genes(); + size_t preservedGeneCount = static_cast(std::count(outputGenes.begin(), outputGenes.end(), '.')); BOOST_REQUIRE(preservedGeneCount == input.length()); double const expectedValue = additionChance; @@ -156,8 +155,8 @@ BOOST_AUTO_TEST_CASE(geneAddition_should_iterate_over_gene_positions_and_insert_ (double(maxAdditions) - addedGeneCount) * expectedValue * expectedValue + addedGeneCount * (1.0 - expectedValue) * (1.0 - expectedValue); - BOOST_TEST(abs(addedGeneCount / double(maxAdditions) - expectedValue) < tolerance); - BOOST_TEST(abs(squaredError / double(maxAdditions) - variance) < tolerance); + BOOST_TEST(std::abs(addedGeneCount / double(maxAdditions) - expectedValue) < tolerance); + BOOST_TEST(std::abs(squaredError / double(maxAdditions) - variance) < tolerance); } } @@ -165,7 +164,7 @@ BOOST_AUTO_TEST_CASE(geneAddition_should_be_able_to_insert_before_first_position { SimulationRNG::reset(7); Chromosome chromosome("fcCUnDvejs"); - function mutation = geneAddition(0.1); + std::function mutation = geneAddition(0.1); Chromosome mutatedChromosome = mutation(chromosome); BOOST_TEST(mutatedChromosome.length() > chromosome.length()); @@ -176,7 +175,7 @@ BOOST_AUTO_TEST_CASE(geneAddition_should_be_able_to_insert_after_last_position) { SimulationRNG::reset(81); Chromosome chromosome("fcCUnDvejs"); - function mutation = geneAddition(0.1); + std::function mutation = geneAddition(0.1); Chromosome mutatedChromosome = mutation(chromosome); BOOST_TEST(mutatedChromosome.length() > chromosome.length()); @@ -186,7 +185,7 @@ BOOST_AUTO_TEST_CASE(geneAddition_should_be_able_to_insert_after_last_position) BOOST_AUTO_TEST_CASE(geneAddition_should_return_identical_chromosome_if_probability_is_zero) { Chromosome chromosome("fcCUnDvejsrmV"); - function mutation = geneAddition(0.0); + std::function mutation = geneAddition(0.0); BOOST_TEST(mutation(chromosome) == chromosome); } @@ -194,12 +193,12 @@ BOOST_AUTO_TEST_CASE(geneAddition_should_return_identical_chromosome_if_probabil BOOST_AUTO_TEST_CASE(geneAddition_should_insert_genes_at_all_positions_if_probability_is_one) { Chromosome chromosome("fcCUnDvejsrmV"); - function mutation = geneAddition(1.0); + std::function mutation = geneAddition(1.0); Chromosome mutatedChromosome = mutation(chromosome); BOOST_TEST(mutatedChromosome.length() == chromosome.length() * 2 + 1); - vector originalGenes; + std::vector originalGenes; for (size_t i = 0; i < mutatedChromosome.length() - 1; ++i) if (i % 2 == 1) originalGenes.push_back(mutatedChromosome.optimisationSteps()[i]); @@ -211,7 +210,7 @@ BOOST_AUTO_TEST_CASE(alternativeMutations_should_choose_between_mutations_with_g { SimulationRNG::reset(1); Chromosome chromosome("a"); - function mutation = alternativeMutations( + std::function mutation = alternativeMutations( 0.8, wholeChromosomeReplacement(Chromosome("c")), wholeChromosomeReplacement(Chromosome("f")) @@ -234,7 +233,7 @@ BOOST_AUTO_TEST_CASE(alternativeMutations_should_choose_between_mutations_with_g BOOST_AUTO_TEST_CASE(alternativeMutations_should_always_choose_first_mutation_if_probability_is_one) { Chromosome chromosome("a"); - function mutation = alternativeMutations( + std::function mutation = alternativeMutations( 1.0, wholeChromosomeReplacement(Chromosome("c")), wholeChromosomeReplacement(Chromosome("f")) @@ -247,7 +246,7 @@ BOOST_AUTO_TEST_CASE(alternativeMutations_should_always_choose_first_mutation_if BOOST_AUTO_TEST_CASE(alternativeMutations_should_always_choose_second_mutation_if_probability_is_zero) { Chromosome chromosome("a"); - function mutation = alternativeMutations( + std::function mutation = alternativeMutations( 0.0, wholeChromosomeReplacement(Chromosome("c")), wholeChromosomeReplacement(Chromosome("f")) @@ -260,8 +259,8 @@ BOOST_AUTO_TEST_CASE(alternativeMutations_should_always_choose_second_mutation_i BOOST_AUTO_TEST_CASE(mutationSequence_should_apply_all_mutations) { Chromosome chromosome("aaaaa"); - vector steps = Chromosome::genesToSteps("gfc"); - function mutation = mutationSequence({ + std::vector steps = Chromosome::genesToSteps("gfc"); + std::function mutation = mutationSequence({ geneSubstitution(3, steps[0]), geneSubstitution(2, steps[1]), geneSubstitution(1, steps[2]), @@ -273,8 +272,8 @@ BOOST_AUTO_TEST_CASE(mutationSequence_should_apply_all_mutations) BOOST_AUTO_TEST_CASE(mutationSequence_apply_mutations_in_the_order_they_are_given) { Chromosome chromosome("aa"); - vector steps = Chromosome::genesToSteps("gcfo"); - function mutation = mutationSequence({ + std::vector steps = Chromosome::genesToSteps("gcfo"); + std::function mutation = mutationSequence({ geneSubstitution(0, steps[0]), geneSubstitution(1, steps[1]), geneSubstitution(0, steps[2]), @@ -287,14 +286,14 @@ BOOST_AUTO_TEST_CASE(mutationSequence_apply_mutations_in_the_order_they_are_give BOOST_AUTO_TEST_CASE(mutationSequence_should_return_unmodified_chromosome_if_given_no_mutations) { Chromosome chromosome("aa"); - function mutation = mutationSequence({}); + std::function mutation = mutationSequence({}); BOOST_TEST(mutation(chromosome) == chromosome); } BOOST_AUTO_TEST_CASE(randomPointCrossover_should_swap_chromosome_parts_at_random_point) { - function crossover = randomPointCrossover(); + std::function crossover = randomPointCrossover(); SimulationRNG::reset(1); Chromosome result1 = crossover(Chromosome("aaaaaaaaaa"), Chromosome("cccccc")); @@ -307,22 +306,22 @@ BOOST_AUTO_TEST_CASE(randomPointCrossover_should_swap_chromosome_parts_at_random BOOST_AUTO_TEST_CASE(symmetricRandomPointCrossover_should_swap_chromosome_parts_at_random_point) { - function crossover = symmetricRandomPointCrossover(); + std::function crossover = symmetricRandomPointCrossover(); SimulationRNG::reset(1); - tuple result1 = crossover(Chromosome("aaaaaaaaaa"), Chromosome("cccccc")); - tuple expectedPair1 = {Chromosome("aaaccc"), Chromosome("cccaaaaaaa")}; + std::tuple result1 = crossover(Chromosome("aaaaaaaaaa"), Chromosome("cccccc")); + std::tuple expectedPair1 = {Chromosome("aaaccc"), Chromosome("cccaaaaaaa")}; BOOST_TEST(result1 == expectedPair1); - tuple result2 = crossover(Chromosome("cccccc"), Chromosome("aaaaaaaaaa")); - tuple expectedPair2 = {Chromosome("ccccccaaaa"), Chromosome("aaaaaa")}; + std::tuple result2 = crossover(Chromosome("cccccc"), Chromosome("aaaaaaaaaa")); + std::tuple expectedPair2 = {Chromosome("ccccccaaaa"), Chromosome("aaaaaa")}; BOOST_TEST(result2 == expectedPair2); } BOOST_AUTO_TEST_CASE(randomPointCrossover_should_only_consider_points_available_on_both_chromosomes) { SimulationRNG::reset(1); - function crossover = randomPointCrossover(); + std::function crossover = randomPointCrossover(); for (size_t i = 0; i < 30; ++i) { @@ -346,7 +345,7 @@ BOOST_AUTO_TEST_CASE(randomPointCrossover_should_only_consider_points_available_ BOOST_AUTO_TEST_CASE(randomPointCrossover_should_never_split_at_position_zero_if_chromosomes_are_splittable) { SimulationRNG::reset(1); - function crossover = randomPointCrossover(); + std::function crossover = randomPointCrossover(); for (size_t i = 0; i < 30; ++i) { @@ -360,7 +359,7 @@ BOOST_AUTO_TEST_CASE(randomPointCrossover_should_never_split_at_position_zero_if BOOST_AUTO_TEST_CASE(randomPointCrossover_should_never_split_at_position_zero_if_chromosomes_are_not_empty) { SimulationRNG::reset(1); - function crossover = randomPointCrossover(); + std::function crossover = randomPointCrossover(); for (size_t i = 0; i < 30; ++i) { @@ -373,7 +372,7 @@ BOOST_AUTO_TEST_CASE(randomPointCrossover_should_never_split_at_position_zero_if BOOST_AUTO_TEST_CASE(randomPointCrossover_should_work_even_if_one_chromosome_is_unsplittable) { - function crossover = randomPointCrossover(); + std::function crossover = randomPointCrossover(); SimulationRNG::reset(1); BOOST_CHECK(crossover(Chromosome("ff"), Chromosome("a")) == Chromosome("f")); @@ -385,7 +384,7 @@ BOOST_AUTO_TEST_CASE(randomPointCrossover_should_split_at_position_zero_only_if_ Chromosome empty(""); Chromosome unsplittable("a"); Chromosome splittable("aaaa"); - function crossover = randomPointCrossover(); + std::function crossover = randomPointCrossover(); SimulationRNG::reset(1); BOOST_CHECK(crossover(empty, empty) == empty); @@ -447,13 +446,13 @@ BOOST_AUTO_TEST_CASE(fixedPointCrossover_should_split_at_end_of_shorter_chromoso BOOST_AUTO_TEST_CASE(fixedPointCrossover_should_select_correct_split_point_for_unsplittable_chromosomes) { - function crossover00 = fixedPointCrossover(0.0); + std::function crossover00 = fixedPointCrossover(0.0); BOOST_CHECK(crossover00(Chromosome("fff"), Chromosome("a")) == Chromosome("a")); BOOST_CHECK(crossover00(Chromosome("a"), Chromosome("fff")) == Chromosome("fff")); BOOST_CHECK(crossover00(Chromosome("f"), Chromosome("a")) == Chromosome("a")); - function crossover10 = fixedPointCrossover(1.0); + std::function crossover10 = fixedPointCrossover(1.0); BOOST_CHECK(crossover10(Chromosome("fff"), Chromosome("a")) == Chromosome("f")); BOOST_CHECK(crossover10(Chromosome("a"), Chromosome("fff")) == Chromosome("aff")); @@ -466,14 +465,14 @@ BOOST_AUTO_TEST_CASE(fixedPointCrossover_should_always_use_position_zero_as_spli Chromosome unsplittable("f"); Chromosome splittable("aaaa"); - function crossover00 = fixedPointCrossover(0.0); + std::function crossover00 = fixedPointCrossover(0.0); BOOST_CHECK(crossover00(empty, empty) == empty); BOOST_CHECK(crossover00(unsplittable, empty) == empty); BOOST_CHECK(crossover00(empty, unsplittable) == unsplittable); BOOST_CHECK(crossover00(splittable, empty) == empty); BOOST_CHECK(crossover00(empty, splittable) == splittable); - function crossover10 = fixedPointCrossover(1.0); + std::function crossover10 = fixedPointCrossover(1.0); BOOST_CHECK(crossover10(empty, empty) == empty); BOOST_CHECK(crossover10(unsplittable, empty) == empty); BOOST_CHECK(crossover10(empty, unsplittable) == unsplittable); @@ -483,7 +482,7 @@ BOOST_AUTO_TEST_CASE(fixedPointCrossover_should_always_use_position_zero_as_spli BOOST_AUTO_TEST_CASE(randomTwoPointCrossover_should_swap_chromosome_parts_between_two_random_points) { - function crossover = randomTwoPointCrossover(); + std::function crossover = randomTwoPointCrossover(); SimulationRNG::reset(1); Chromosome result1 = crossover(Chromosome("aaaaaaaaaa"), Chromosome("cccccc")); @@ -496,21 +495,21 @@ BOOST_AUTO_TEST_CASE(randomTwoPointCrossover_should_swap_chromosome_parts_betwee BOOST_AUTO_TEST_CASE(symmetricRandomTwoPointCrossover_should_swap_chromosome_parts_at_random_point) { - function crossover = symmetricRandomTwoPointCrossover(); + std::function crossover = symmetricRandomTwoPointCrossover(); SimulationRNG::reset(1); - tuple result1 = crossover(Chromosome("aaaaaaaaaa"), Chromosome("cccccc")); - tuple expectedPair1 = {Chromosome("aaacccaaaa"), Chromosome("cccaaa")}; + std::tuple result1 = crossover(Chromosome("aaaaaaaaaa"), Chromosome("cccccc")); + std::tuple expectedPair1 = {Chromosome("aaacccaaaa"), Chromosome("cccaaa")}; BOOST_TEST(result1 == expectedPair1); - tuple result2 = crossover(Chromosome("cccccc"), Chromosome("aaaaaaaaaa")); - tuple expectedPair2 = {Chromosome("ccccca"), Chromosome("aaaaacaaaa")}; + std::tuple result2 = crossover(Chromosome("cccccc"), Chromosome("aaaaaaaaaa")); + std::tuple expectedPair2 = {Chromosome("ccccca"), Chromosome("aaaaacaaaa")}; BOOST_TEST(result2 == expectedPair2); } BOOST_AUTO_TEST_CASE(randomTwoPointCrossover_should_only_consider_points_available_on_both_chromosomes) { - function crossover = randomTwoPointCrossover(); + std::function crossover = randomTwoPointCrossover(); for (size_t i = 0; i < 30; ++i) { @@ -539,7 +538,7 @@ BOOST_AUTO_TEST_CASE(randomTwoPointCrossover_should_only_consider_points_availab BOOST_AUTO_TEST_CASE(uniformCrossover_should_swap_randomly_selected_genes) { - function crossover = uniformCrossover(0.7); + std::function crossover = uniformCrossover(0.7); SimulationRNG::reset(1); Chromosome result1 = crossover(Chromosome("aaaaaaaaaa"), Chromosome("cccccc")); @@ -552,23 +551,23 @@ BOOST_AUTO_TEST_CASE(uniformCrossover_should_swap_randomly_selected_genes) BOOST_AUTO_TEST_CASE(symmetricUniformCrossover_should_swap_randomly_selected_genes) { - function crossover = symmetricUniformCrossover(0.7); + std::function crossover = symmetricUniformCrossover(0.7); SimulationRNG::reset(1); - tuple result1 = crossover(Chromosome("aaaaaaaaaa"), Chromosome("cccccc")); - tuple expectedPair1 = {Chromosome("caaacc"), Chromosome("acccaaaaaa")}; + std::tuple result1 = crossover(Chromosome("aaaaaaaaaa"), Chromosome("cccccc")); + std::tuple expectedPair1 = {Chromosome("caaacc"), Chromosome("acccaaaaaa")}; BOOST_TEST(result1 == expectedPair1); - tuple result2 = crossover(Chromosome("cccccc"), Chromosome("aaaaaaaaaa")); - tuple expectedPair2 = {Chromosome("caaaaaaaaa"), Chromosome("accccc")}; + std::tuple result2 = crossover(Chromosome("cccccc"), Chromosome("aaaaaaaaaa")); + std::tuple expectedPair2 = {Chromosome("caaaaaaaaa"), Chromosome("accccc")}; BOOST_TEST(result2 == expectedPair2); } BOOST_AUTO_TEST_CASE(uniformCrossover_should_only_consider_points_available_on_both_chromosomes) { - function crossover = uniformCrossover(0.7); + std::function crossover = uniformCrossover(0.7); - set expectedPatterns = { + std::set expectedPatterns = { "TTTTTTTTTTTTTTTTTTTT", "aTTTTTTTTTTTTTTTTTTT", "TaTTTTTTTTTTTTTTTTTT", @@ -616,20 +615,20 @@ BOOST_AUTO_TEST_CASE(uniformCrossover_should_swap_genes_with_uniform_probability double const expectedValue = swapChance; double const variance = swapChance * (1 - swapChance); - function crossover = uniformCrossover(swapChance); + std::function crossover = uniformCrossover(swapChance); Chromosome chromosome1("aaaaaaaaaa"); Chromosome chromosome2("cccccccccc"); - vector bernoulliTrials; + std::vector bernoulliTrials; for (size_t i = 0; i < operationCount; ++i) { - string genes = toString(crossover(chromosome1, chromosome2)); + std::string genes = toString(crossover(chromosome1, chromosome2)); for (size_t j = 0; j < chromosome1.length(); ++j) bernoulliTrials.push_back(static_cast(genes[j] == 'c')); } - BOOST_TEST(abs(mean(bernoulliTrials) - expectedValue) < expectedValue * relativeTolerance); - BOOST_TEST(abs(meanSquaredError(bernoulliTrials, expectedValue) - variance) < variance * relativeTolerance); + BOOST_TEST(std::abs(mean(bernoulliTrials) - expectedValue) < expectedValue * relativeTolerance); + BOOST_TEST(std::abs(meanSquaredError(bernoulliTrials, expectedValue) - variance) < variance * relativeTolerance); } BOOST_AUTO_TEST_CASE(uniformCrossover_should_swap_tail_with_uniform_probability) @@ -640,22 +639,22 @@ BOOST_AUTO_TEST_CASE(uniformCrossover_should_swap_tail_with_uniform_probability) double const expectedValue = swapChance; double const variance = swapChance * (1 - swapChance); - function crossover = uniformCrossover(swapChance); + std::function crossover = uniformCrossover(swapChance); Chromosome chromosome1("aaaaa"); Chromosome chromosome2("cccccccccc"); SimulationRNG::reset(1); - vector bernoulliTrials; + std::vector bernoulliTrials; for (size_t i = 0; i < operationCount; ++i) { - string genes = toString(crossover(chromosome1, chromosome2)); + std::string genes = toString(crossover(chromosome1, chromosome2)); BOOST_REQUIRE(genes.size() == 5 || genes.size() == 10); bernoulliTrials.push_back(static_cast(genes.size() == 10)); } - BOOST_TEST(abs(mean(bernoulliTrials) - expectedValue) < expectedValue * relativeTolerance); - BOOST_TEST(abs(meanSquaredError(bernoulliTrials, expectedValue) - variance) < variance * relativeTolerance); + BOOST_TEST(std::abs(mean(bernoulliTrials) - expectedValue) < expectedValue * relativeTolerance); + BOOST_TEST(std::abs(meanSquaredError(bernoulliTrials, expectedValue) - variance) < variance * relativeTolerance); } BOOST_AUTO_TEST_SUITE_END() diff --git a/test/yulPhaser/PairSelections.cpp b/test/yulPhaser/PairSelections.cpp index f3d13a5b3b27..82b9a900b68c 100644 --- a/test/yulPhaser/PairSelections.cpp +++ b/test/yulPhaser/PairSelections.cpp @@ -27,8 +27,6 @@ #include #include -using namespace std; - namespace solidity::phaser::test { @@ -45,35 +43,35 @@ BOOST_AUTO_TEST_CASE(materialise_should_return_random_values_with_equal_probabil constexpr double variance = (collectionSize * collectionSize - 1) / 12.0; SimulationRNG::reset(1); - vector> pairs = RandomPairSelection(selectionSize).materialise(collectionSize); - vector samples; + std::vector> pairs = RandomPairSelection(selectionSize).materialise(collectionSize); + std::vector samples; for (auto& [first, second]: pairs) { samples.push_back(first); samples.push_back(second); } - BOOST_TEST(abs(mean(samples) - expectedValue) < expectedValue * relativeTolerance); - BOOST_TEST(abs(meanSquaredError(samples, expectedValue) - variance) < variance * relativeTolerance); + BOOST_TEST(std::abs(mean(samples) - expectedValue) < expectedValue * relativeTolerance); + BOOST_TEST(std::abs(meanSquaredError(samples, expectedValue) - variance) < variance * relativeTolerance); } BOOST_AUTO_TEST_CASE(materialise_should_return_only_values_that_can_be_used_as_collection_indices) { const size_t collectionSize = 200; - vector> pairs = RandomPairSelection(0.5).materialise(collectionSize); + std::vector> pairs = RandomPairSelection(0.5).materialise(collectionSize); BOOST_TEST(pairs.size() == 100); - BOOST_TEST(all_of(pairs.begin(), pairs.end(), [&](auto const& pair){ return get<0>(pair) <= collectionSize; })); - BOOST_TEST(all_of(pairs.begin(), pairs.end(), [&](auto const& pair){ return get<1>(pair) <= collectionSize; })); + BOOST_TEST(all_of(pairs.begin(), pairs.end(), [&](auto const& pair){ return std::get<0>(pair) <= collectionSize; })); + BOOST_TEST(all_of(pairs.begin(), pairs.end(), [&](auto const& pair){ return std::get<1>(pair) <= collectionSize; })); } BOOST_AUTO_TEST_CASE(materialise_should_never_return_a_pair_of_identical_indices) { - vector> pairs = RandomPairSelection(0.5).materialise(100); + std::vector> pairs = RandomPairSelection(0.5).materialise(100); BOOST_TEST(pairs.size() == 50); - BOOST_TEST(all_of(pairs.begin(), pairs.end(), [](auto const& pair){ return get<0>(pair) != get<1>(pair); })); + BOOST_TEST(all_of(pairs.begin(), pairs.end(), [](auto const& pair){ return std::get<0>(pair) != std::get<1>(pair); })); } BOOST_AUTO_TEST_CASE(materialise_should_return_number_of_pairs_thats_a_fraction_of_collection_size) @@ -132,18 +130,18 @@ BOOST_AUTO_TEST_CASE(materialise_should_return_random_values_with_equal_probabil constexpr double variance = selectionChance * (1 - selectionChance); SimulationRNG::reset(1); - vector> pairs = PairsFromRandomSubset(selectionChance).materialise(collectionSize); - vector bernoulliTrials(collectionSize, 0); + std::vector> pairs = PairsFromRandomSubset(selectionChance).materialise(collectionSize); + std::vector bernoulliTrials(collectionSize, 0); for (auto& pair: pairs) { - BOOST_REQUIRE(get<1>(pair) < collectionSize); - BOOST_REQUIRE(get<1>(pair) < collectionSize); - bernoulliTrials[get<0>(pair)] = 1.0; - bernoulliTrials[get<1>(pair)] = 1.0; + BOOST_REQUIRE(std::get<1>(pair) < collectionSize); + BOOST_REQUIRE(std::get<1>(pair) < collectionSize); + bernoulliTrials[std::get<0>(pair)] = 1.0; + bernoulliTrials[std::get<1>(pair)] = 1.0; } - BOOST_TEST(abs(mean(bernoulliTrials) - expectedValue) < expectedValue * relativeTolerance); - BOOST_TEST(abs(meanSquaredError(bernoulliTrials, expectedValue) - variance) < variance * relativeTolerance); + BOOST_TEST(std::abs(mean(bernoulliTrials) - expectedValue) < expectedValue * relativeTolerance); + BOOST_TEST(std::abs(meanSquaredError(bernoulliTrials, expectedValue) - variance) < variance * relativeTolerance); } BOOST_AUTO_TEST_CASE(materialise_should_return_only_values_that_can_be_used_as_collection_indices) @@ -151,10 +149,10 @@ BOOST_AUTO_TEST_CASE(materialise_should_return_only_values_that_can_be_used_as_c const size_t collectionSize = 200; constexpr double selectionChance = 0.5; - vector> pairs = PairsFromRandomSubset(selectionChance).materialise(collectionSize); + std::vector> pairs = PairsFromRandomSubset(selectionChance).materialise(collectionSize); - BOOST_TEST(all_of(pairs.begin(), pairs.end(), [&](auto const& pair){ return get<0>(pair) <= collectionSize; })); - BOOST_TEST(all_of(pairs.begin(), pairs.end(), [&](auto const& pair){ return get<1>(pair) <= collectionSize; })); + BOOST_TEST(all_of(pairs.begin(), pairs.end(), [&](auto const& pair){ return std::get<0>(pair) <= collectionSize; })); + BOOST_TEST(all_of(pairs.begin(), pairs.end(), [&](auto const& pair){ return std::get<1>(pair) <= collectionSize; })); } BOOST_AUTO_TEST_CASE(materialise_should_use_unique_indices) @@ -162,12 +160,12 @@ BOOST_AUTO_TEST_CASE(materialise_should_use_unique_indices) constexpr size_t collectionSize = 200; constexpr double selectionChance = 0.5; - vector> pairs = PairsFromRandomSubset(selectionChance).materialise(collectionSize); - set indices; + std::vector> pairs = PairsFromRandomSubset(selectionChance).materialise(collectionSize); + std::set indices; for (auto& pair: pairs) { - indices.insert(get<0>(pair)); - indices.insert(get<1>(pair)); + indices.insert(std::get<0>(pair)); + indices.insert(std::get<1>(pair)); } BOOST_TEST(indices.size() == 2 * pairs.size()); @@ -195,7 +193,7 @@ BOOST_AUTO_TEST_CASE(materialise_should_return_all_pairs_if_selection_chance_is_ BOOST_AUTO_TEST_SUITE_END() BOOST_AUTO_TEST_SUITE(PairMosaicSelectionTest) -using IndexPairs = vector>; +using IndexPairs = std::vector>; BOOST_AUTO_TEST_CASE(materialise) { diff --git a/test/yulPhaser/Phaser.cpp b/test/yulPhaser/Phaser.cpp index feee2269e761..671f75546305 100644 --- a/test/yulPhaser/Phaser.cpp +++ b/test/yulPhaser/Phaser.cpp @@ -32,7 +32,6 @@ #include #include -using namespace std; using namespace solidity::util; using namespace solidity::langutil; using namespace solidity::yul; @@ -69,15 +68,15 @@ class GeneticAlgorithmFactoryFixture class FixtureWithPrograms { protected: - vector m_sourceStreams = { + std::vector m_sourceStreams = { CharStream("{}", ""), CharStream("{{}}", ""), CharStream("{{{}}}", ""), }; - vector m_programs = { - get(Program::load(m_sourceStreams[0])), - get(Program::load(m_sourceStreams[1])), - get(Program::load(m_sourceStreams[2])), + std::vector m_programs = { + std::get(Program::load(m_sourceStreams[0])), + std::get(Program::load(m_sourceStreams[1])), + std::get(Program::load(m_sourceStreams[2])), }; }; @@ -96,7 +95,7 @@ class FitnessMetricFactoryFixture: public FixtureWithPrograms class PoulationFactoryFixture { protected: - shared_ptr m_fitnessMetric = make_shared(); + std::shared_ptr m_fitnessMetric = std::make_shared(); PopulationFactory::Options m_options = { /* minChromosomeLength = */ 0, /* maxChromosomeLength = */ 0, @@ -113,7 +112,7 @@ BOOST_AUTO_TEST_SUITE(GeneticAlgorithmFactoryTest) BOOST_FIXTURE_TEST_CASE(build_should_select_the_right_algorithm_and_pass_the_options_to_it, GeneticAlgorithmFactoryFixture) { m_options.algorithm = Algorithm::Random; - unique_ptr algorithm1 = GeneticAlgorithmFactory::build(m_options, 100); + std::unique_ptr algorithm1 = GeneticAlgorithmFactory::build(m_options, 100); BOOST_REQUIRE(algorithm1 != nullptr); auto randomAlgorithm = dynamic_cast(algorithm1.get()); @@ -123,7 +122,7 @@ BOOST_FIXTURE_TEST_CASE(build_should_select_the_right_algorithm_and_pass_the_opt BOOST_TEST(randomAlgorithm->options().maxChromosomeLength == m_options.maxChromosomeLength); m_options.algorithm = Algorithm::GEWEP; - unique_ptr algorithm2 = GeneticAlgorithmFactory::build(m_options, 100); + std::unique_ptr algorithm2 = GeneticAlgorithmFactory::build(m_options, 100); BOOST_REQUIRE(algorithm2 != nullptr); auto gewepAlgorithm = dynamic_cast(algorithm2.get()); @@ -139,7 +138,7 @@ BOOST_FIXTURE_TEST_CASE(build_should_select_the_right_algorithm_and_pass_the_opt BOOST_TEST(gewepAlgorithm->options().percentGenesToAddOrDelete == m_options.gewepGenesToAddOrDelete.value()); m_options.algorithm = Algorithm::Classic; - unique_ptr algorithm3 = GeneticAlgorithmFactory::build(m_options, 100); + std::unique_ptr algorithm3 = GeneticAlgorithmFactory::build(m_options, 100); BOOST_REQUIRE(algorithm3 != nullptr); auto classicAlgorithm = dynamic_cast(algorithm3.get()); @@ -156,8 +155,8 @@ BOOST_FIXTURE_TEST_CASE(build_should_select_the_right_algorithm_and_pass_the_opt BOOST_FIXTURE_TEST_CASE(build_should_set_random_algorithm_elite_pool_size_based_on_population_size_if_not_specified, GeneticAlgorithmFactoryFixture) { m_options.algorithm = Algorithm::Random; - m_options.randomElitePoolSize = nullopt; - unique_ptr algorithm = GeneticAlgorithmFactory::build(m_options, 100); + m_options.randomElitePoolSize = std::nullopt; + std::unique_ptr algorithm = GeneticAlgorithmFactory::build(m_options, 100); BOOST_REQUIRE(algorithm != nullptr); auto randomAlgorithm = dynamic_cast(algorithm.get()); @@ -168,11 +167,11 @@ BOOST_FIXTURE_TEST_CASE(build_should_set_random_algorithm_elite_pool_size_based_ BOOST_FIXTURE_TEST_CASE(build_should_set_gewep_mutation_percentages_based_on_maximum_chromosome_length_if_not_specified, GeneticAlgorithmFactoryFixture) { m_options.algorithm = Algorithm::GEWEP; - m_options.gewepGenesToRandomise = nullopt; - m_options.gewepGenesToAddOrDelete = nullopt; + m_options.gewepGenesToRandomise = std::nullopt; + m_options.gewepGenesToAddOrDelete = std::nullopt; m_options.maxChromosomeLength = 125; - unique_ptr algorithm = GeneticAlgorithmFactory::build(m_options, 100); + std::unique_ptr algorithm = GeneticAlgorithmFactory::build(m_options, 100); BOOST_REQUIRE(algorithm != nullptr); auto gewepAlgorithm = dynamic_cast(algorithm.get()); @@ -188,7 +187,7 @@ BOOST_FIXTURE_TEST_CASE(build_should_create_metric_of_the_right_type, FitnessMet { m_options.metric = MetricChoice::RelativeCodeSize; m_options.metricAggregator = MetricAggregatorChoice::Sum; - unique_ptr metric = FitnessMetricFactory::build(m_options, {m_programs[0]}, {nullptr}, m_weights); + std::unique_ptr metric = FitnessMetricFactory::build(m_options, {m_programs[0]}, {nullptr}, m_weights); BOOST_REQUIRE(metric != nullptr); auto sumMetric = dynamic_cast(metric.get()); @@ -206,7 +205,7 @@ BOOST_FIXTURE_TEST_CASE(build_should_respect_chromosome_repetitions_option, Fitn m_options.metric = MetricChoice::CodeSize; m_options.metricAggregator = MetricAggregatorChoice::Average; m_options.chromosomeRepetitions = 5; - unique_ptr metric = FitnessMetricFactory::build(m_options, {m_programs[0]}, {nullptr}, m_weights); + std::unique_ptr metric = FitnessMetricFactory::build(m_options, {m_programs[0]}, {nullptr}, m_weights); BOOST_REQUIRE(metric != nullptr); auto averageMetric = dynamic_cast(metric.get()); @@ -224,7 +223,7 @@ BOOST_FIXTURE_TEST_CASE(build_should_set_relative_metric_scale, FitnessMetricFac m_options.metric = MetricChoice::RelativeCodeSize; m_options.metricAggregator = MetricAggregatorChoice::Average; m_options.relativeMetricScale = 10; - unique_ptr metric = FitnessMetricFactory::build(m_options, {m_programs[0]}, {nullptr}, m_weights); + std::unique_ptr metric = FitnessMetricFactory::build(m_options, {m_programs[0]}, {nullptr}, m_weights); BOOST_REQUIRE(metric != nullptr); auto averageMetric = dynamic_cast(metric.get()); @@ -239,10 +238,10 @@ BOOST_FIXTURE_TEST_CASE(build_should_set_relative_metric_scale, FitnessMetricFac BOOST_FIXTURE_TEST_CASE(build_should_create_metric_for_each_input_program, FitnessMetricFactoryFixture) { - unique_ptr metric = FitnessMetricFactory::build( + std::unique_ptr metric = FitnessMetricFactory::build( m_options, m_programs, - vector>(m_programs.size(), nullptr), + std::vector>(m_programs.size(), nullptr), m_weights ); BOOST_REQUIRE(metric != nullptr); @@ -255,14 +254,14 @@ BOOST_FIXTURE_TEST_CASE(build_should_create_metric_for_each_input_program, Fitne BOOST_FIXTURE_TEST_CASE(build_should_pass_program_caches_to_metrics, FitnessMetricFactoryFixture) { assert(m_programs.size() == 3); - vector> caches = { - make_shared(m_programs[0]), - make_shared(m_programs[1]), - make_shared(m_programs[2]), + std::vector> caches = { + std::make_shared(m_programs[0]), + std::make_shared(m_programs[1]), + std::make_shared(m_programs[2]), }; m_options.metric = MetricChoice::RelativeCodeSize; - unique_ptr metric = FitnessMetricFactory::build(m_options, m_programs, caches, m_weights); + std::unique_ptr metric = FitnessMetricFactory::build(m_options, m_programs, caches, m_weights); BOOST_REQUIRE(metric != nullptr); auto combinedMetric = dynamic_cast(metric.get()); @@ -287,7 +286,7 @@ BOOST_FIXTURE_TEST_CASE(build_should_create_an_empty_population_if_no_specific_o m_options.populationFromFile = {}; BOOST_TEST( PopulationFactory::build(m_options, m_fitnessMetric) == - Population(m_fitnessMetric, vector{}) + Population(m_fitnessMetric, std::vector{}) ); } @@ -318,7 +317,7 @@ BOOST_FIXTURE_TEST_CASE(build_should_respect_random_population_option, Poulation BOOST_FIXTURE_TEST_CASE(build_should_respect_population_from_file_option, PoulationFactoryFixture) { - map> fileContent = { + std::map> fileContent = { {"a.txt", {"a", "fff", "", "jxccLTa"}}, {"b.txt", {}}, {"c.txt", {""}}, @@ -328,9 +327,9 @@ BOOST_FIXTURE_TEST_CASE(build_should_respect_population_from_file_option, Poulat TemporaryDirectory tempDir; for (auto const& [fileName, chromosomes]: fileContent) { - ofstream tmpFile((tempDir.path() / fileName).string()); + std::ofstream tmpFile((tempDir.path() / fileName).string()); for (auto const& chromosome: chromosomes) - tmpFile << chromosome << endl; + tmpFile << chromosome << std::endl; m_options.populationFromFile.push_back((tempDir.path() / fileName).string()); } @@ -361,8 +360,8 @@ BOOST_FIXTURE_TEST_CASE(build_should_combine_populations_from_all_sources, Poula { TemporaryDirectory tempDir; { - ofstream tmpFile((tempDir.path() / "population.txt").string()); - tmpFile << "axc" << endl << "fcL" << endl; + std::ofstream tmpFile((tempDir.path() / "population.txt").string()); + tmpFile << "axc" << std::endl << "fcL" << std::endl; } m_options.population = {"axc", "fcL"}; @@ -388,7 +387,7 @@ BOOST_AUTO_TEST_SUITE(ProgramCacheFactoryTest) BOOST_FIXTURE_TEST_CASE(build_should_create_cache_for_each_input_program_if_cache_enabled, FixtureWithPrograms) { ProgramCacheFactory::Options options{/* programCacheEnabled = */ true}; - vector> caches = ProgramCacheFactory::build(options, m_programs); + std::vector> caches = ProgramCacheFactory::build(options, m_programs); assert(m_programs.size() >= 2 && "There must be at least 2 programs for this test to be meaningful"); BOOST_TEST(caches.size() == m_programs.size()); @@ -402,7 +401,7 @@ BOOST_FIXTURE_TEST_CASE(build_should_create_cache_for_each_input_program_if_cach BOOST_FIXTURE_TEST_CASE(build_should_return_nullptr_for_each_input_program_if_cache_disabled, FixtureWithPrograms) { ProgramCacheFactory::Options options{/* programCacheEnabled = */ false}; - vector> caches = ProgramCacheFactory::build(options, m_programs); + std::vector> caches = ProgramCacheFactory::build(options, m_programs); assert(m_programs.size() >= 2 && "There must be at least 2 programs for this test to be meaningful"); BOOST_TEST(caches.size() == m_programs.size()); @@ -416,7 +415,7 @@ BOOST_AUTO_TEST_SUITE(ProgramFactoryTest) BOOST_AUTO_TEST_CASE(build_should_load_programs_from_files) { TemporaryDirectory tempDir; - vector sources{"{}", "{{}}", "{{{}}}"}; + std::vector sources{"{}", "{{}}", "{{{}}}"}; ProgramFactory::Options options{ /* inputFiles = */ { (tempDir.path() / "program1.yul").string(), @@ -428,17 +427,17 @@ BOOST_AUTO_TEST_CASE(build_should_load_programs_from_files) for (size_t i = 0; i < sources.size(); ++i) { - ofstream tmpFile(options.inputFiles[i]); - tmpFile << sources[i] << endl; + std::ofstream tmpFile(options.inputFiles[i]); + tmpFile << sources[i] << std::endl; } - vector programs = ProgramFactory::build(options); + std::vector programs = ProgramFactory::build(options); BOOST_TEST(programs.size() == sources.size()); for (size_t i = 0; i < sources.size(); ++i) { CharStream sourceStream(sources[i], options.inputFiles[i]); - BOOST_TEST(toString(programs[i]) == toString(get(Program::load(sourceStream)))); + BOOST_TEST(toString(programs[i]) == toString(std::get(Program::load(sourceStream)))); } } @@ -451,17 +450,17 @@ BOOST_AUTO_TEST_CASE(build_should_apply_prefix) }; CharStream nestedSource("{{{let x:= 1}}}", ""); - Program nestedProgram = get(Program::load(nestedSource)); - Program flatProgram = get(Program::load(nestedSource)); + Program nestedProgram = std::get(Program::load(nestedSource)); + Program flatProgram = std::get(Program::load(nestedSource)); flatProgram.optimise(Chromosome::genesToSteps("f")); assert(toString(nestedProgram) != toString(flatProgram)); { - ofstream tmpFile(options.inputFiles[0]); - tmpFile << nestedSource.source() << endl; + std::ofstream tmpFile(options.inputFiles[0]); + tmpFile << nestedSource.source() << std::endl; } - vector programs = ProgramFactory::build(options); + std::vector programs = ProgramFactory::build(options); BOOST_TEST(programs.size() == 1); BOOST_TEST(toString(programs[0]) == toString(flatProgram)); diff --git a/test/yulPhaser/Population.cpp b/test/yulPhaser/Population.cpp index 13d06b521030..aed014592c1b 100644 --- a/test/yulPhaser/Population.cpp +++ b/test/yulPhaser/Population.cpp @@ -38,7 +38,6 @@ #include #include -using namespace std; using namespace solidity::langutil; using namespace solidity::yul; using namespace boost::unit_test::framework; @@ -52,12 +51,12 @@ class PopulationFixture static ChromosomePair twoStepSwap(Chromosome const& _chromosome1, Chromosome const& _chromosome2) { return ChromosomePair{ - Chromosome(vector{_chromosome1.optimisationSteps()[0], _chromosome2.optimisationSteps()[1]}), - Chromosome(vector{_chromosome2.optimisationSteps()[0], _chromosome1.optimisationSteps()[1]}), + Chromosome(std::vector{_chromosome1.optimisationSteps()[0], _chromosome2.optimisationSteps()[1]}), + Chromosome(std::vector{_chromosome2.optimisationSteps()[0], _chromosome1.optimisationSteps()[1]}), }; } - shared_ptr m_fitnessMetric = make_shared(); + std::shared_ptr m_fitnessMetric = std::make_shared(); }; BOOST_AUTO_TEST_SUITE(Phaser, *boost::unit_test::label("nooptions")) @@ -95,14 +94,14 @@ BOOST_AUTO_TEST_CASE(isFitter_should_return_false_for_identical_individuals) BOOST_FIXTURE_TEST_CASE(constructor_should_copy_chromosomes_compute_fitness_and_sort_chromosomes, PopulationFixture) { - vector chromosomes = { + std::vector chromosomes = { Chromosome::makeRandom(5), Chromosome::makeRandom(15), Chromosome::makeRandom(10), }; Population population(m_fitnessMetric, chromosomes); - vector const& individuals = population.individuals(); + std::vector const& individuals = population.individuals(); BOOST_TEST(individuals.size() == 3); BOOST_TEST(individuals[0].fitness == 5); @@ -115,7 +114,7 @@ BOOST_FIXTURE_TEST_CASE(constructor_should_copy_chromosomes_compute_fitness_and_ BOOST_FIXTURE_TEST_CASE(constructor_should_accept_individuals_without_recalculating_fitness, PopulationFixture) { - vector customIndividuals = { + std::vector customIndividuals = { Individual(Chromosome("aaaccc"), 20), Individual(Chromosome("aaa"), 10), Individual(Chromosome("aaaf"), 30), @@ -126,7 +125,7 @@ BOOST_FIXTURE_TEST_CASE(constructor_should_accept_individuals_without_recalculat Population population(m_fitnessMetric, customIndividuals); - vector expectedIndividuals{customIndividuals[1], customIndividuals[0], customIndividuals[2]}; + std::vector expectedIndividuals{customIndividuals[1], customIndividuals[0], customIndividuals[2]}; BOOST_TEST(population.individuals() == expectedIndividuals); } @@ -170,13 +169,13 @@ BOOST_FIXTURE_TEST_CASE(makeRandom_should_use_random_chromosome_length, Populati constexpr double relativeTolerance = 0.05; auto population = Population::makeRandom(m_fitnessMetric, populationSize, minLength, maxLength); - vector samples = chromosomeLengths(population); + std::vector samples = chromosomeLengths(population); const double expectedValue = (maxLength + minLength) / 2.0; const double variance = ((maxLength - minLength + 1) * (maxLength - minLength + 1) - 1) / 12.0; - BOOST_TEST(abs(mean(samples) - expectedValue) < expectedValue * relativeTolerance); - BOOST_TEST(abs(meanSquaredError(samples, expectedValue) - variance) < variance * relativeTolerance); + BOOST_TEST(std::abs(mean(samples) - expectedValue) < expectedValue * relativeTolerance); + BOOST_TEST(std::abs(meanSquaredError(samples, expectedValue) - variance) < variance * relativeTolerance); } BOOST_FIXTURE_TEST_CASE(makeRandom_should_return_population_with_random_chromosomes, PopulationFixture) @@ -186,10 +185,10 @@ BOOST_FIXTURE_TEST_CASE(makeRandom_should_return_population_with_random_chromoso constexpr int chromosomeLength = 30; constexpr double relativeTolerance = 0.01; - map stepIndices = enumerateOptmisationSteps(); + std::map stepIndices = enumerateOptmisationSteps(); auto population = Population::makeRandom(m_fitnessMetric, populationSize, chromosomeLength, chromosomeLength); - vector samples; + std::vector samples; for (auto& individual: population.individuals()) for (auto& step: individual.chromosome.optimisationSteps()) samples.push_back(stepIndices.at(step)); @@ -197,8 +196,8 @@ BOOST_FIXTURE_TEST_CASE(makeRandom_should_return_population_with_random_chromoso const double expectedValue = double(stepIndices.size() - 1) / 2.0; const double variance = double(stepIndices.size() * stepIndices.size() - 1) / 12.0; - BOOST_TEST(abs(mean(samples) - expectedValue) < expectedValue * relativeTolerance); - BOOST_TEST(abs(meanSquaredError(samples, expectedValue) - variance) < variance * relativeTolerance); + BOOST_TEST(std::abs(mean(samples) - expectedValue) < expectedValue * relativeTolerance); + BOOST_TEST(std::abs(meanSquaredError(samples, expectedValue) - variance) < variance * relativeTolerance); } BOOST_FIXTURE_TEST_CASE(makeRandom_should_compute_fitness, PopulationFixture) @@ -223,7 +222,7 @@ BOOST_FIXTURE_TEST_CASE(select_should_return_population_containing_individuals_i { Population population(m_fitnessMetric, {Chromosome("a"), Chromosome("c"), Chromosome("g"), Chromosome("h")}); RangeSelection selection(0.25, 0.75); - assert(selection.materialise(population.individuals().size()) == (vector{1, 2})); + assert(selection.materialise(population.individuals().size()) == (std::vector{1, 2})); BOOST_TEST( population.select(selection) == @@ -235,7 +234,7 @@ BOOST_FIXTURE_TEST_CASE(select_should_include_duplicates_if_selection_contains_d { Population population(m_fitnessMetric, {Chromosome("a"), Chromosome("c")}); MosaicSelection selection({0, 1}, 2.0); - assert(selection.materialise(population.individuals().size()) == (vector{0, 1, 0, 1})); + assert(selection.materialise(population.individuals().size()) == (std::vector{0, 1, 0, 1})); BOOST_TEST(population.select(selection) == Population(m_fitnessMetric, { population.individuals()[0].chromosome, @@ -258,7 +257,7 @@ BOOST_FIXTURE_TEST_CASE(mutate_should_return_population_containing_individuals_i { Population population(m_fitnessMetric, {Chromosome("aa"), Chromosome("cc"), Chromosome("gg"), Chromosome("hh")}); RangeSelection selection(0.25, 0.75); - assert(selection.materialise(population.individuals().size()) == (vector{1, 2})); + assert(selection.materialise(population.individuals().size()) == (std::vector{1, 2})); Population expectedPopulation(m_fitnessMetric, {Chromosome("fc"), Chromosome("fg")}); @@ -269,7 +268,7 @@ BOOST_FIXTURE_TEST_CASE(mutate_should_include_duplicates_if_selection_contains_d { Population population(m_fitnessMetric, {Chromosome("aa"), Chromosome("aa")}); RangeSelection selection(0.0, 1.0); - assert(selection.materialise(population.individuals().size()) == (vector{0, 1})); + assert(selection.materialise(population.individuals().size()) == (std::vector{0, 1})); BOOST_TEST( population.mutate(selection, geneSubstitution(0, BlockFlattener::name)) == @@ -290,7 +289,7 @@ BOOST_FIXTURE_TEST_CASE(crossover_should_return_population_containing_individual { Population population(m_fitnessMetric, {Chromosome("aa"), Chromosome("cc"), Chromosome("gg"), Chromosome("hh")}); PairMosaicSelection selection({{0, 1}, {2, 1}}, 1.0); - assert(selection.materialise(population.individuals().size()) == (vector>{{0, 1}, {2, 1}, {0, 1}, {2, 1}})); + assert(selection.materialise(population.individuals().size()) == (std::vector>{{0, 1}, {2, 1}, {0, 1}, {2, 1}})); Population expectedPopulation(m_fitnessMetric, {Chromosome("ac"), Chromosome("ac"), Chromosome("gc"), Chromosome("gc")}); @@ -301,7 +300,7 @@ BOOST_FIXTURE_TEST_CASE(crossover_should_include_duplicates_if_selection_contain { Population population(m_fitnessMetric, {Chromosome("aa"), Chromosome("aa")}); PairMosaicSelection selection({{0, 0}, {1, 1}}, 2.0); - assert(selection.materialise(population.individuals().size()) == (vector>{{0, 0}, {1, 1}, {0, 0}, {1, 1}})); + assert(selection.materialise(population.individuals().size()) == (std::vector>{{0, 0}, {1, 1}, {0, 0}, {1, 1}})); BOOST_TEST( population.crossover(selection, fixedPointCrossover(0.5)) == @@ -322,14 +321,14 @@ BOOST_FIXTURE_TEST_CASE(symmetricCrossoverWithRemainder_should_return_crossed_po { Population population(m_fitnessMetric, {Chromosome("aa"), Chromosome("cc"), Chromosome("gg"), Chromosome("hh")}); PairMosaicSelection selection({{2, 1}}, 0.25); - assert(selection.materialise(population.individuals().size()) == (vector>{{2, 1}})); + assert(selection.materialise(population.individuals().size()) == (std::vector>{{2, 1}})); Population expectedCrossedPopulation(m_fitnessMetric, {Chromosome("gc"), Chromosome("cg")}); Population expectedRemainder(m_fitnessMetric, {Chromosome("aa"), Chromosome("hh")}); BOOST_TEST( population.symmetricCrossoverWithRemainder(selection, twoStepSwap) == - (tuple{expectedCrossedPopulation, expectedRemainder}) + (std::tuple{expectedCrossedPopulation, expectedRemainder}) ); } @@ -337,7 +336,7 @@ BOOST_FIXTURE_TEST_CASE(symmetricCrossoverWithRemainder_should_allow_crossing_th { Population population(m_fitnessMetric, {Chromosome("aa"), Chromosome("cc"), Chromosome("gg"), Chromosome("hh")}); PairMosaicSelection selection({{0, 0}, {2, 1}}, 1.0); - assert(selection.materialise(population.individuals().size()) == (vector>{{0, 0}, {2, 1}, {0, 0}, {2, 1}})); + assert(selection.materialise(population.individuals().size()) == (std::vector>{{0, 0}, {2, 1}, {0, 0}, {2, 1}})); Population expectedCrossedPopulation(m_fitnessMetric, { Chromosome("aa"), Chromosome("aa"), @@ -349,7 +348,7 @@ BOOST_FIXTURE_TEST_CASE(symmetricCrossoverWithRemainder_should_allow_crossing_th BOOST_TEST( population.symmetricCrossoverWithRemainder(selection, twoStepSwap) == - (tuple{expectedCrossedPopulation, expectedRemainder}) + (std::tuple{expectedCrossedPopulation, expectedRemainder}) ); } @@ -361,7 +360,7 @@ BOOST_FIXTURE_TEST_CASE(symmetricCrossoverWithRemainder_should_return_empty_popu BOOST_TEST( population.symmetricCrossoverWithRemainder(selection, twoStepSwap) == - (tuple{Population(m_fitnessMetric), population}) + (std::tuple{Population(m_fitnessMetric), population}) ); } diff --git a/test/yulPhaser/Program.cpp b/test/yulPhaser/Program.cpp index 2e91926d059f..a54bf09af146 100644 --- a/test/yulPhaser/Program.cpp +++ b/test/yulPhaser/Program.cpp @@ -34,7 +34,6 @@ #include #include -using namespace std; using namespace solidity::langutil; using namespace solidity::util; using namespace solidity::yul; @@ -47,7 +46,7 @@ namespace /// If the block isn't redundant it just returns it immediately. Block const& skipRedundantBlocks(Block const& _block) { - if (_block.statements.size() == 1 && holds_alternative(_block.statements[0])) + if (_block.statements.size() == 1 && std::holds_alternative(_block.statements[0])) return skipRedundantBlocks(get(_block.statements[0])); else return _block; @@ -62,7 +61,7 @@ BOOST_AUTO_TEST_SUITE(ProgramTest) BOOST_AUTO_TEST_CASE(copy_constructor_should_make_deep_copy_of_ast) { - string sourceCode( + std::string sourceCode( "{\n" " let x := 1\n" "}\n" @@ -82,7 +81,7 @@ BOOST_AUTO_TEST_CASE(copy_constructor_should_make_deep_copy_of_ast) BOOST_AUTO_TEST_CASE(load_should_rewind_the_stream) { - string sourceCode( + std::string sourceCode( "{\n" " let x := 1\n" " let y := 2\n" @@ -98,7 +97,7 @@ BOOST_AUTO_TEST_CASE(load_should_rewind_the_stream) BOOST_AUTO_TEST_CASE(load_should_disambiguate) { - string sourceCode( + std::string sourceCode( "{\n" " {\n" " let x := 1\n" @@ -126,7 +125,7 @@ BOOST_AUTO_TEST_CASE(load_should_disambiguate) BOOST_AUTO_TEST_CASE(load_should_do_function_grouping_and_hoisting) { - string sourceCode( + std::string sourceCode( "{\n" " function foo() -> result\n" " {\n" @@ -144,14 +143,14 @@ BOOST_AUTO_TEST_CASE(load_should_do_function_grouping_and_hoisting) Program program = get(Program::load(sourceStream)); BOOST_TEST(program.ast().statements.size() == 3); - BOOST_TEST(holds_alternative(program.ast().statements[0])); - BOOST_TEST(holds_alternative(program.ast().statements[1])); - BOOST_TEST(holds_alternative(program.ast().statements[2])); + BOOST_TEST(std::holds_alternative(program.ast().statements[0])); + BOOST_TEST(std::holds_alternative(program.ast().statements[1])); + BOOST_TEST(std::holds_alternative(program.ast().statements[2])); } BOOST_AUTO_TEST_CASE(load_should_do_loop_init_rewriting) { - string sourceCode( + std::string sourceCode( "{\n" " for { let i := 0 } true {}\n" " {\n" @@ -163,35 +162,35 @@ BOOST_AUTO_TEST_CASE(load_should_do_loop_init_rewriting) // skipRedundantBlocks() makes the test independent of whether load() includes function grouping or not. Block const& parentBlock = skipRedundantBlocks(program.ast()); - BOOST_TEST(holds_alternative(parentBlock.statements[0])); - BOOST_TEST(holds_alternative(parentBlock.statements[1])); + BOOST_TEST(std::holds_alternative(parentBlock.statements[0])); + BOOST_TEST(std::holds_alternative(parentBlock.statements[1])); } BOOST_AUTO_TEST_CASE(load_should_throw_InvalidProgram_if_program_cant_be_parsed) { - string sourceCode("invalid program\n"); + std::string sourceCode("invalid program\n"); CharStream sourceStream(sourceCode, current_test_case().p_name); - BOOST_TEST(holds_alternative(Program::load(sourceStream))); + BOOST_TEST(std::holds_alternative(Program::load(sourceStream))); } BOOST_AUTO_TEST_CASE(load_should_throw_InvalidProgram_if_program_cant_be_analyzed) { // This should be parsed just fine but fail the analysis with: // Error: Variable not found or variable not lvalue. - string sourceCode( + std::string sourceCode( "{\n" " x := 1\n" "}\n" ); CharStream sourceStream(sourceCode, current_test_case().p_name); - BOOST_TEST(holds_alternative(Program::load(sourceStream))); + BOOST_TEST(std::holds_alternative(Program::load(sourceStream))); } BOOST_AUTO_TEST_CASE(load_should_accept_yul_objects_as_input) { - string sourceCode( + std::string sourceCode( "object \"C_178\" {\n" " code {\n" " mstore(64, 128)\n" @@ -203,12 +202,12 @@ BOOST_AUTO_TEST_CASE(load_should_accept_yul_objects_as_input) CharStream sourceStream(sourceCode, current_test_case().p_name); auto programOrErrors = Program::load(sourceStream); - BOOST_TEST(holds_alternative(programOrErrors)); + BOOST_TEST(std::holds_alternative(programOrErrors)); } BOOST_AUTO_TEST_CASE(load_should_return_errors_if_analysis_of_object_code_fails) { - string sourceCode( + std::string sourceCode( "object \"C_178\" {\n" " code {\n" " return(0, datasize(\"C_178_deployed\"))\n" @@ -218,12 +217,12 @@ BOOST_AUTO_TEST_CASE(load_should_return_errors_if_analysis_of_object_code_fails) CharStream sourceStream(sourceCode, current_test_case().p_name); auto programOrErrors = Program::load(sourceStream); - BOOST_TEST(holds_alternative(programOrErrors)); + BOOST_TEST(std::holds_alternative(programOrErrors)); } BOOST_AUTO_TEST_CASE(load_should_return_errors_if_parsing_of_nested_object_fails) { - string sourceCode( + std::string sourceCode( "object \"C_178\" {\n" " code {\n" " return(0, datasize(\"C_178_deployed\"))\n" @@ -243,12 +242,12 @@ BOOST_AUTO_TEST_CASE(load_should_return_errors_if_parsing_of_nested_object_fails CharStream sourceStream(sourceCode, current_test_case().p_name); auto programOrErrors = Program::load(sourceStream); - BOOST_TEST(holds_alternative(programOrErrors)); + BOOST_TEST(std::holds_alternative(programOrErrors)); } BOOST_AUTO_TEST_CASE(load_should_extract_nested_object_with_deployed_suffix_if_present) { - string sourceCode( + std::string sourceCode( "object \"C_178\" {\n" " code {\n" " return(0, datasize(\"C_178_deployed\"))\n" @@ -265,12 +264,12 @@ BOOST_AUTO_TEST_CASE(load_should_extract_nested_object_with_deployed_suffix_if_p CharStream sourceStream(sourceCode, current_test_case().p_name); auto programOrErrors = Program::load(sourceStream); - BOOST_TEST(holds_alternative(programOrErrors)); + BOOST_TEST(std::holds_alternative(programOrErrors)); } BOOST_AUTO_TEST_CASE(load_should_fall_back_to_parsing_the_whole_object_if_there_is_no_subobject_with_the_right_name) { - string sourceCode( + std::string sourceCode( "object \"C_178\" {\n" " code {\n" " mstore(64, 128)\n" @@ -292,16 +291,16 @@ BOOST_AUTO_TEST_CASE(load_should_fall_back_to_parsing_the_whole_object_if_there_ CharStream sourceStream(sourceCode, current_test_case().p_name); auto programOrErrors = Program::load(sourceStream); - BOOST_TEST(holds_alternative(programOrErrors)); + BOOST_TEST(std::holds_alternative(programOrErrors)); Block const& parentBlock = skipRedundantBlocks(get(programOrErrors).ast()); BOOST_TEST(parentBlock.statements.size() == 1); - BOOST_TEST(holds_alternative(parentBlock.statements[0])); + BOOST_TEST(std::holds_alternative(parentBlock.statements[0])); } BOOST_AUTO_TEST_CASE(load_should_ignore_data_in_objects) { - string sourceCode( + std::string sourceCode( "object \"C_178\" {\n" " code {\n" " mstore(64, 128)\n" @@ -312,12 +311,12 @@ BOOST_AUTO_TEST_CASE(load_should_ignore_data_in_objects) CharStream sourceStream(sourceCode, current_test_case().p_name); auto programOrErrors = Program::load(sourceStream); - BOOST_TEST(holds_alternative(programOrErrors)); + BOOST_TEST(std::holds_alternative(programOrErrors)); } BOOST_AUTO_TEST_CASE(optimise) { - string sourceCode( + std::string sourceCode( "{\n" " {\n" " if 1 { let x := 1 }\n" @@ -330,22 +329,22 @@ BOOST_AUTO_TEST_CASE(optimise) [[maybe_unused]] Block const& parentBlockBefore = skipRedundantBlocks(program.ast()); assert(parentBlockBefore.statements.size() == 2); - assert(holds_alternative(parentBlockBefore.statements[0])); - assert(holds_alternative(parentBlockBefore.statements[1])); + assert(std::holds_alternative(parentBlockBefore.statements[0])); + assert(std::holds_alternative(parentBlockBefore.statements[1])); program.optimise({StructuralSimplifier::name, BlockFlattener::name}); Block const& parentBlockAfter = program.ast(); BOOST_TEST(parentBlockAfter.statements.size() == 1); - BOOST_TEST(holds_alternative(parentBlockAfter.statements[0])); + BOOST_TEST(std::holds_alternative(parentBlockAfter.statements[0])); Block const& innerBlock = get(parentBlockAfter.statements[0]); BOOST_TEST(innerBlock.statements.size() == 1); - BOOST_TEST(holds_alternative(innerBlock.statements[0])); + BOOST_TEST(std::holds_alternative(innerBlock.statements[0])); } BOOST_AUTO_TEST_CASE(output_operator) { - string sourceCode( + std::string sourceCode( "{\n" " let factor := 13\n" " {\n" @@ -369,7 +368,7 @@ BOOST_AUTO_TEST_CASE(output_operator) BOOST_AUTO_TEST_CASE(toJson) { - string sourceCode( + std::string sourceCode( "{\n" " let a := 3\n" " if a\n" @@ -382,14 +381,14 @@ BOOST_AUTO_TEST_CASE(toJson) Program program = get(Program::load(sourceStream)); Json::Value parsingResult; - string errors; + std::string errors; BOOST_TEST(jsonParseStrict(program.toJson(), parsingResult, &errors)); BOOST_TEST(errors.empty()); } BOOST_AUTO_TEST_CASE(codeSize) { - string sourceCode( + std::string sourceCode( "{\n" " function foo() -> result\n" " {\n" diff --git a/test/yulPhaser/ProgramCache.cpp b/test/yulPhaser/ProgramCache.cpp index 2dab86fcda17..c4bf7f609e61 100644 --- a/test/yulPhaser/ProgramCache.cpp +++ b/test/yulPhaser/ProgramCache.cpp @@ -30,7 +30,6 @@ #include #include -using namespace std; using namespace solidity::util; using namespace solidity::langutil; using namespace solidity::yul; @@ -50,16 +49,16 @@ class ProgramCacheFixture " }\n" "}\n"; - Program optimisedProgram(Program _program, string _abbreviatedOptimisationSteps) const + Program optimisedProgram(Program _program, std::string _abbreviatedOptimisationSteps) const { Program result = std::move(_program); result.optimise(Chromosome::genesToSteps(_abbreviatedOptimisationSteps)); return result; } - static set cachedKeys(ProgramCache const& _programCache) + static std::set cachedKeys(ProgramCache const& _programCache) { - set keys; + std::set keys; for (auto pair = _programCache.entries().begin(); pair != _programCache.entries().end(); ++pair) keys.insert(pair->first); @@ -67,7 +66,7 @@ class ProgramCacheFixture } CharStream m_sourceStream = CharStream(SampleSourceCode, "program-cache-test"); - Program m_program = get(Program::load(m_sourceStream)); + Program m_program = std::get(Program::load(m_sourceStream)); ProgramCache m_programCache{m_program}; }; @@ -111,7 +110,7 @@ BOOST_FIXTURE_TEST_CASE(optimiseProgram_should_store_programs_for_all_prefixes, BOOST_TEST(toString(cachedProgram) == toString(programIuO)); - BOOST_REQUIRE((cachedKeys(m_programCache) == set{"I", "Iu", "IuO"})); + BOOST_REQUIRE((cachedKeys(m_programCache) == std::set{"I", "Iu", "IuO"})); BOOST_TEST(toString(*m_programCache.find("I")) == toString(programI)); BOOST_TEST(toString(*m_programCache.find("Iu")) == toString(programIu)); BOOST_TEST(toString(*m_programCache.find("IuO")) == toString(programIuO)); @@ -119,7 +118,7 @@ BOOST_FIXTURE_TEST_CASE(optimiseProgram_should_store_programs_for_all_prefixes, BOOST_FIXTURE_TEST_CASE(optimiseProgram_should_repeat_the_chromosome_requested_number_of_times, ProgramCacheFixture) { - string steps = "IuOIuO"; + std::string steps = "IuOIuO"; Program cachedProgram = m_programCache.optimiseProgram("IuO", 2); @@ -148,14 +147,14 @@ BOOST_FIXTURE_TEST_CASE(optimiseProgram_should_reuse_the_longest_prefix_and_move m_programCache.startRound(1); BOOST_TEST(m_programCache.currentRound() == 1); - BOOST_REQUIRE((cachedKeys(m_programCache) == set{"I", "Iu", "Ia"})); + BOOST_REQUIRE((cachedKeys(m_programCache) == std::set{"I", "Iu", "Ia"})); BOOST_TEST(m_programCache.entries().find("I")->second.roundNumber == 0); BOOST_TEST(m_programCache.entries().find("Iu")->second.roundNumber == 0); BOOST_TEST(m_programCache.entries().find("Ia")->second.roundNumber == 0); m_programCache.optimiseProgram("IuOI"); - BOOST_REQUIRE((cachedKeys(m_programCache) == set{"I", "Iu", "Ia", "IuO", "IuOI"})); + BOOST_REQUIRE((cachedKeys(m_programCache) == std::set{"I", "Iu", "Ia", "IuO", "IuOI"})); BOOST_TEST(m_programCache.entries().find("I")->second.roundNumber == 1); BOOST_TEST(m_programCache.entries().find("Iu")->second.roundNumber == 1); BOOST_TEST(m_programCache.entries().find("Ia")->second.roundNumber == 0); @@ -171,14 +170,14 @@ BOOST_FIXTURE_TEST_CASE(startRound_should_remove_entries_older_than_two_rounds, m_programCache.optimiseProgram("Iu"); BOOST_TEST(m_programCache.currentRound() == 0); - BOOST_REQUIRE((cachedKeys(m_programCache) == set{"I", "Iu"})); + BOOST_REQUIRE((cachedKeys(m_programCache) == std::set{"I", "Iu"})); BOOST_TEST(m_programCache.entries().find("I")->second.roundNumber == 0); BOOST_TEST(m_programCache.entries().find("Iu")->second.roundNumber == 0); m_programCache.optimiseProgram("a"); BOOST_TEST(m_programCache.currentRound() == 0); - BOOST_REQUIRE((cachedKeys(m_programCache) == set{"I", "Iu", "a"})); + BOOST_REQUIRE((cachedKeys(m_programCache) == std::set{"I", "Iu", "a"})); BOOST_TEST(m_programCache.entries().find("I")->second.roundNumber == 0); BOOST_TEST(m_programCache.entries().find("Iu")->second.roundNumber == 0); BOOST_TEST(m_programCache.entries().find("a")->second.roundNumber == 0); @@ -186,7 +185,7 @@ BOOST_FIXTURE_TEST_CASE(startRound_should_remove_entries_older_than_two_rounds, m_programCache.startRound(1); BOOST_TEST(m_programCache.currentRound() == 1); - BOOST_REQUIRE((cachedKeys(m_programCache) == set{"I", "Iu", "a"})); + BOOST_REQUIRE((cachedKeys(m_programCache) == std::set{"I", "Iu", "a"})); BOOST_TEST(m_programCache.entries().find("I")->second.roundNumber == 0); BOOST_TEST(m_programCache.entries().find("Iu")->second.roundNumber == 0); BOOST_TEST(m_programCache.entries().find("a")->second.roundNumber == 0); @@ -194,7 +193,7 @@ BOOST_FIXTURE_TEST_CASE(startRound_should_remove_entries_older_than_two_rounds, m_programCache.optimiseProgram("af"); BOOST_TEST(m_programCache.currentRound() == 1); - BOOST_REQUIRE((cachedKeys(m_programCache) == set{"I", "Iu", "a", "af"})); + BOOST_REQUIRE((cachedKeys(m_programCache) == std::set{"I", "Iu", "a", "af"})); BOOST_TEST(m_programCache.entries().find("I")->second.roundNumber == 0); BOOST_TEST(m_programCache.entries().find("Iu")->second.roundNumber == 0); BOOST_TEST(m_programCache.entries().find("a")->second.roundNumber == 1); @@ -203,7 +202,7 @@ BOOST_FIXTURE_TEST_CASE(startRound_should_remove_entries_older_than_two_rounds, m_programCache.startRound(2); BOOST_TEST(m_programCache.currentRound() == 2); - BOOST_REQUIRE((cachedKeys(m_programCache) == set{"a", "af"})); + BOOST_REQUIRE((cachedKeys(m_programCache) == std::set{"a", "af"})); BOOST_TEST(m_programCache.entries().find("a")->second.roundNumber == 1); BOOST_TEST(m_programCache.entries().find("af")->second.roundNumber == 1); @@ -223,31 +222,31 @@ BOOST_FIXTURE_TEST_CASE(gatherStats_should_return_cache_statistics, ProgramCache m_programCache.optimiseProgram("L"); m_programCache.optimiseProgram("Iu"); - BOOST_REQUIRE((cachedKeys(m_programCache) == set{"L", "I", "Iu"})); + BOOST_REQUIRE((cachedKeys(m_programCache) == std::set{"L", "I", "Iu"})); CacheStats expectedStats1{0, 3, sizeL + sizeI + sizeIu, {{0, 3}}}; BOOST_CHECK(m_programCache.gatherStats() == expectedStats1); m_programCache.optimiseProgram("IuO"); - BOOST_REQUIRE((cachedKeys(m_programCache) == set{"L", "I", "Iu", "IuO"})); + BOOST_REQUIRE((cachedKeys(m_programCache) == std::set{"L", "I", "Iu", "IuO"})); CacheStats expectedStats2{2, 4, sizeL + sizeI + sizeIu + sizeIuO, {{0, 4}}}; BOOST_CHECK(m_programCache.gatherStats() == expectedStats2); m_programCache.startRound(1); - BOOST_REQUIRE((cachedKeys(m_programCache) == set{"L", "I", "Iu", "IuO"})); + BOOST_REQUIRE((cachedKeys(m_programCache) == std::set{"L", "I", "Iu", "IuO"})); BOOST_CHECK(m_programCache.gatherStats() == expectedStats2); m_programCache.optimiseProgram("IuO"); - BOOST_REQUIRE((cachedKeys(m_programCache) == set{"L", "I", "Iu", "IuO"})); + BOOST_REQUIRE((cachedKeys(m_programCache) == std::set{"L", "I", "Iu", "IuO"})); CacheStats expectedStats3{5, 4, sizeL + sizeI + sizeIu + sizeIuO, {{0, 1}, {1, 3}}}; BOOST_CHECK(m_programCache.gatherStats() == expectedStats3); m_programCache.startRound(2); - BOOST_REQUIRE((cachedKeys(m_programCache) == set{"I", "Iu", "IuO"})); + BOOST_REQUIRE((cachedKeys(m_programCache) == std::set{"I", "Iu", "IuO"})); CacheStats expectedStats4{5, 4, sizeI + sizeIu + sizeIuO, {{1, 3}}}; BOOST_CHECK(m_programCache.gatherStats() == expectedStats4); m_programCache.optimiseProgram("LT"); - BOOST_REQUIRE((cachedKeys(m_programCache) == set{"L", "LT", "I", "Iu", "IuO"})); + BOOST_REQUIRE((cachedKeys(m_programCache) == std::set{"L", "LT", "I", "Iu", "IuO"})); CacheStats expectedStats5{5, 6, sizeL + sizeLT + sizeI + sizeIu + sizeIuO, {{1, 3}, {2, 2}}}; BOOST_CHECK(m_programCache.gatherStats() == expectedStats5); } diff --git a/test/yulPhaser/Selections.cpp b/test/yulPhaser/Selections.cpp index 28c8b8a879dc..866234978590 100644 --- a/test/yulPhaser/Selections.cpp +++ b/test/yulPhaser/Selections.cpp @@ -29,7 +29,6 @@ #include #include -using namespace std; using namespace solidity::util; namespace solidity::phaser::test @@ -41,28 +40,28 @@ BOOST_AUTO_TEST_SUITE(RangeSelectionTest) BOOST_AUTO_TEST_CASE(materialise) { - BOOST_TEST(RangeSelection(0.0, 1.0).materialise(10) == vector({0, 1, 2, 3, 4, 5, 6, 7, 8, 9})); - BOOST_TEST(RangeSelection(0.0, 0.1).materialise(10) == vector({0})); - BOOST_TEST(RangeSelection(0.0, 0.2).materialise(10) == vector({0, 1})); - BOOST_TEST(RangeSelection(0.0, 0.7).materialise(10) == vector({0, 1, 2, 3, 4, 5, 6})); + BOOST_TEST(RangeSelection(0.0, 1.0).materialise(10) == std::vector({0, 1, 2, 3, 4, 5, 6, 7, 8, 9})); + BOOST_TEST(RangeSelection(0.0, 0.1).materialise(10) == std::vector({0})); + BOOST_TEST(RangeSelection(0.0, 0.2).materialise(10) == std::vector({0, 1})); + BOOST_TEST(RangeSelection(0.0, 0.7).materialise(10) == std::vector({0, 1, 2, 3, 4, 5, 6})); - BOOST_TEST(RangeSelection(0.9, 1.0).materialise(10) == vector({ 9})); - BOOST_TEST(RangeSelection(0.8, 1.0).materialise(10) == vector({ 8, 9})); - BOOST_TEST(RangeSelection(0.5, 1.0).materialise(10) == vector({ 5, 6, 7, 8, 9})); + BOOST_TEST(RangeSelection(0.9, 1.0).materialise(10) == std::vector({ 9})); + BOOST_TEST(RangeSelection(0.8, 1.0).materialise(10) == std::vector({ 8, 9})); + BOOST_TEST(RangeSelection(0.5, 1.0).materialise(10) == std::vector({ 5, 6, 7, 8, 9})); - BOOST_TEST(RangeSelection(0.3, 0.6).materialise(10) == vector({ 3, 4, 5 })); - BOOST_TEST(RangeSelection(0.2, 0.7).materialise(10) == vector({ 2, 3, 4, 5, 6 })); - BOOST_TEST(RangeSelection(0.4, 0.7).materialise(10) == vector({ 4, 5, 6 })); + BOOST_TEST(RangeSelection(0.3, 0.6).materialise(10) == std::vector({ 3, 4, 5 })); + BOOST_TEST(RangeSelection(0.2, 0.7).materialise(10) == std::vector({ 2, 3, 4, 5, 6 })); + BOOST_TEST(RangeSelection(0.4, 0.7).materialise(10) == std::vector({ 4, 5, 6 })); - BOOST_TEST(RangeSelection(0.4, 0.7).materialise(5) == vector({2, 3})); + BOOST_TEST(RangeSelection(0.4, 0.7).materialise(5) == std::vector({2, 3})); } BOOST_AUTO_TEST_CASE(materialise_should_round_indices) { - BOOST_TEST(RangeSelection(0.01, 0.99).materialise(10) == vector({0, 1, 2, 3, 4, 5, 6, 7, 8, 9})); - BOOST_TEST(RangeSelection(0.04, 0.96).materialise(10) == vector({0, 1, 2, 3, 4, 5, 6, 7, 8, 9})); - BOOST_TEST(RangeSelection(0.05, 0.95).materialise(10) == vector({ 1, 2, 3, 4, 5, 6, 7, 8, 9})); - BOOST_TEST(RangeSelection(0.06, 0.94).materialise(10) == vector({ 1, 2, 3, 4, 5, 6, 7, 8 })); + BOOST_TEST(RangeSelection(0.01, 0.99).materialise(10) == std::vector({0, 1, 2, 3, 4, 5, 6, 7, 8, 9})); + BOOST_TEST(RangeSelection(0.04, 0.96).materialise(10) == std::vector({0, 1, 2, 3, 4, 5, 6, 7, 8, 9})); + BOOST_TEST(RangeSelection(0.05, 0.95).materialise(10) == std::vector({ 1, 2, 3, 4, 5, 6, 7, 8, 9})); + BOOST_TEST(RangeSelection(0.06, 0.94).materialise(10) == std::vector({ 1, 2, 3, 4, 5, 6, 7, 8 })); } BOOST_AUTO_TEST_CASE(materialise_should_handle_empty_collections) @@ -93,27 +92,27 @@ BOOST_AUTO_TEST_SUITE(MosaicSelectionTest) BOOST_AUTO_TEST_CASE(materialise) { - BOOST_TEST(MosaicSelection({1}, 0.5).materialise(4) == vector({1, 1})); - BOOST_TEST(MosaicSelection({1}, 1.0).materialise(4) == vector({1, 1, 1, 1})); - BOOST_TEST(MosaicSelection({1}, 2.0).materialise(4) == vector({1, 1, 1, 1, 1, 1, 1, 1})); - BOOST_TEST(MosaicSelection({1}, 1.0).materialise(2) == vector({1, 1})); - - BOOST_TEST(MosaicSelection({0, 1}, 0.5).materialise(4) == vector({0, 1})); - BOOST_TEST(MosaicSelection({0, 1}, 1.0).materialise(4) == vector({0, 1, 0, 1})); - BOOST_TEST(MosaicSelection({0, 1}, 2.0).materialise(4) == vector({0, 1, 0, 1, 0, 1, 0, 1})); - BOOST_TEST(MosaicSelection({0, 1}, 1.0).materialise(2) == vector({0, 1})); - - BOOST_TEST(MosaicSelection({3, 2, 1, 0}, 0.5).materialise(4) == vector({3, 2})); - BOOST_TEST(MosaicSelection({3, 2, 1, 0}, 1.0).materialise(4) == vector({3, 2, 1, 0})); - BOOST_TEST(MosaicSelection({3, 2, 1, 0}, 2.0).materialise(4) == vector({3, 2, 1, 0, 3, 2, 1, 0})); - BOOST_TEST(MosaicSelection({1, 0, 1, 0}, 1.0).materialise(2) == vector({1, 0})); + BOOST_TEST(MosaicSelection({1}, 0.5).materialise(4) == std::vector({1, 1})); + BOOST_TEST(MosaicSelection({1}, 1.0).materialise(4) == std::vector({1, 1, 1, 1})); + BOOST_TEST(MosaicSelection({1}, 2.0).materialise(4) == std::vector({1, 1, 1, 1, 1, 1, 1, 1})); + BOOST_TEST(MosaicSelection({1}, 1.0).materialise(2) == std::vector({1, 1})); + + BOOST_TEST(MosaicSelection({0, 1}, 0.5).materialise(4) == std::vector({0, 1})); + BOOST_TEST(MosaicSelection({0, 1}, 1.0).materialise(4) == std::vector({0, 1, 0, 1})); + BOOST_TEST(MosaicSelection({0, 1}, 2.0).materialise(4) == std::vector({0, 1, 0, 1, 0, 1, 0, 1})); + BOOST_TEST(MosaicSelection({0, 1}, 1.0).materialise(2) == std::vector({0, 1})); + + BOOST_TEST(MosaicSelection({3, 2, 1, 0}, 0.5).materialise(4) == std::vector({3, 2})); + BOOST_TEST(MosaicSelection({3, 2, 1, 0}, 1.0).materialise(4) == std::vector({3, 2, 1, 0})); + BOOST_TEST(MosaicSelection({3, 2, 1, 0}, 2.0).materialise(4) == std::vector({3, 2, 1, 0, 3, 2, 1, 0})); + BOOST_TEST(MosaicSelection({1, 0, 1, 0}, 1.0).materialise(2) == std::vector({1, 0})); } BOOST_AUTO_TEST_CASE(materialise_should_round_indices) { - BOOST_TEST(MosaicSelection({4, 3, 2, 1, 0}, 0.49).materialise(5) == vector({4, 3})); - BOOST_TEST(MosaicSelection({4, 3, 2, 1, 0}, 0.50).materialise(5) == vector({4, 3, 2})); - BOOST_TEST(MosaicSelection({4, 3, 2, 1, 0}, 0.51).materialise(5) == vector({4, 3, 2})); + BOOST_TEST(MosaicSelection({4, 3, 2, 1, 0}, 0.49).materialise(5) == std::vector({4, 3})); + BOOST_TEST(MosaicSelection({4, 3, 2, 1, 0}, 0.50).materialise(5) == std::vector({4, 3, 2})); + BOOST_TEST(MosaicSelection({4, 3, 2, 1, 0}, 0.51).materialise(5) == std::vector({4, 3, 2})); } BOOST_AUTO_TEST_CASE(materialise_should_handle_empty_collections) @@ -132,10 +131,10 @@ BOOST_AUTO_TEST_CASE(materialise_should_handle_empty_selections) BOOST_AUTO_TEST_CASE(materialise_should_clamp_indices_at_collection_size) { - BOOST_TEST(MosaicSelection({4, 3, 2, 1, 0}, 1.0).materialise(4) == vector({3, 3, 2, 1})); - BOOST_TEST(MosaicSelection({4, 3, 2, 1, 0}, 2.0).materialise(3) == vector({2, 2, 2, 1, 0, 2})); - BOOST_TEST(MosaicSelection({4, 3, 2, 1, 0}, 1.0).materialise(1) == vector({0})); - BOOST_TEST(MosaicSelection({4, 3, 2, 1, 0}, 7.0).materialise(1) == vector({0, 0, 0, 0, 0, 0, 0})); + BOOST_TEST(MosaicSelection({4, 3, 2, 1, 0}, 1.0).materialise(4) == std::vector({3, 3, 2, 1})); + BOOST_TEST(MosaicSelection({4, 3, 2, 1, 0}, 2.0).materialise(3) == std::vector({2, 2, 2, 1, 0, 2})); + BOOST_TEST(MosaicSelection({4, 3, 2, 1, 0}, 1.0).materialise(1) == std::vector({0})); + BOOST_TEST(MosaicSelection({4, 3, 2, 1, 0}, 7.0).materialise(1) == std::vector({0, 0, 0, 0, 0, 0, 0})); } BOOST_AUTO_TEST_SUITE_END() @@ -150,17 +149,17 @@ BOOST_AUTO_TEST_CASE(materialise_should_return_random_values_with_equal_probabil constexpr double variance = (collectionSize * collectionSize - 1) / 12.0; SimulationRNG::reset(1); - vector samples = RandomSelection(selectionSize).materialise(collectionSize); + std::vector samples = RandomSelection(selectionSize).materialise(collectionSize); - BOOST_TEST(abs(mean(samples) - expectedValue) < expectedValue * relativeTolerance); - BOOST_TEST(abs(meanSquaredError(samples, expectedValue) - variance) < variance * relativeTolerance); + BOOST_TEST(std::abs(mean(samples) - expectedValue) < expectedValue * relativeTolerance); + BOOST_TEST(std::abs(meanSquaredError(samples, expectedValue) - variance) < variance * relativeTolerance); } BOOST_AUTO_TEST_CASE(materialise_should_return_only_values_that_can_be_used_as_collection_indices) { const size_t collectionSize = 200; - vector indices = RandomSelection(0.5).materialise(collectionSize); + std::vector indices = RandomSelection(0.5).materialise(collectionSize); BOOST_TEST(indices.size() == 100); BOOST_TEST(all_of(indices.begin(), indices.end(), [&](auto const& index){ return index <= collectionSize; })); @@ -214,20 +213,20 @@ BOOST_AUTO_TEST_CASE(materialise_should_return_random_values_with_equal_probabil constexpr double variance = selectionChance * (1 - selectionChance); SimulationRNG::reset(1); - auto indices = convertContainer>(RandomSubset(selectionChance).materialise(collectionSize)); + auto indices = convertContainer>(RandomSubset(selectionChance).materialise(collectionSize)); - vector bernoulliTrials(collectionSize); + std::vector bernoulliTrials(collectionSize); for (size_t i = 0; i < collectionSize; ++i) bernoulliTrials[i] = double(indices.count(i)); - BOOST_TEST(abs(mean(bernoulliTrials) - expectedValue) < expectedValue * relativeTolerance); - BOOST_TEST(abs(meanSquaredError(bernoulliTrials, expectedValue) - variance) < variance * relativeTolerance); + BOOST_TEST(std::abs(mean(bernoulliTrials) - expectedValue) < expectedValue * relativeTolerance); + BOOST_TEST(std::abs(meanSquaredError(bernoulliTrials, expectedValue) - variance) < variance * relativeTolerance); } BOOST_AUTO_TEST_CASE(materialise_should_return_only_values_that_can_be_used_as_collection_indices) { const size_t collectionSize = 200; - vector indices = RandomSubset(0.5).materialise(collectionSize); + std::vector indices = RandomSubset(0.5).materialise(collectionSize); BOOST_TEST(all_of(indices.begin(), indices.end(), [&](auto const& index){ return index <= collectionSize; })); } @@ -235,7 +234,7 @@ BOOST_AUTO_TEST_CASE(materialise_should_return_only_values_that_can_be_used_as_c BOOST_AUTO_TEST_CASE(materialise_should_return_indices_in_the_same_order_they_are_in_the_container) { const size_t collectionSize = 200; - vector indices = RandomSubset(0.5).materialise(collectionSize); + std::vector indices = RandomSubset(0.5).materialise(collectionSize); for (size_t i = 1; i < indices.size(); ++i) BOOST_TEST(indices[i - 1] < indices[i]); diff --git a/test/yulPhaser/SimulationRNG.cpp b/test/yulPhaser/SimulationRNG.cpp index d6e8c3a81150..ff91846e30d8 100644 --- a/test/yulPhaser/SimulationRNG.cpp +++ b/test/yulPhaser/SimulationRNG.cpp @@ -24,8 +24,6 @@ #include -using namespace std; - namespace solidity::phaser::test { @@ -43,12 +41,12 @@ BOOST_AUTO_TEST_CASE(bernoulliTrial_should_produce_samples_with_right_expected_v constexpr double expectedValue = successProbability; constexpr double variance = successProbability * (1 - successProbability); - vector samples; + std::vector samples; for (uint32_t i = 0; i < numSamples; ++i) samples.push_back(static_cast(SimulationRNG::bernoulliTrial(successProbability))); - BOOST_TEST(abs(mean(samples) - expectedValue) < expectedValue * relativeTolerance); - BOOST_TEST(abs(meanSquaredError(samples, expectedValue) - variance) < variance * relativeTolerance); + BOOST_TEST(std::abs(mean(samples) - expectedValue) < expectedValue * relativeTolerance); + BOOST_TEST(std::abs(meanSquaredError(samples, expectedValue) - variance) < variance * relativeTolerance); } BOOST_AUTO_TEST_CASE(bernoulliTrial_can_be_reset) @@ -57,21 +55,21 @@ BOOST_AUTO_TEST_CASE(bernoulliTrial_can_be_reset) constexpr double successProbability = 0.4; SimulationRNG::reset(1); - vector samples1; + std::vector samples1; for (uint32_t i = 0; i < numSamples; ++i) samples1.push_back(static_cast(SimulationRNG::bernoulliTrial(successProbability))); - vector samples2; + std::vector samples2; for (uint32_t i = 0; i < numSamples; ++i) samples2.push_back(static_cast(SimulationRNG::bernoulliTrial(successProbability))); SimulationRNG::reset(1); - vector samples3; + std::vector samples3; for (uint32_t i = 0; i < numSamples; ++i) samples3.push_back(static_cast(SimulationRNG::bernoulliTrial(successProbability))); SimulationRNG::reset(2); - vector samples4; + std::vector samples4; for (uint32_t i = 0; i < numSamples; ++i) samples4.push_back(static_cast(SimulationRNG::bernoulliTrial(successProbability))); @@ -95,12 +93,12 @@ BOOST_AUTO_TEST_CASE(uniformInt_returns_different_values_when_called_multiple_ti constexpr double expectedValue = (minValue + maxValue) / 2.0; constexpr double variance = ((maxValue - minValue + 1) * (maxValue - minValue + 1) - 1) / 12.0; - vector samples; + std::vector samples; for (uint32_t i = 0; i < numSamples; ++i) samples.push_back(SimulationRNG::uniformInt(minValue, maxValue)); - BOOST_TEST(abs(mean(samples) - expectedValue) < expectedValue * relativeTolerance); - BOOST_TEST(abs(meanSquaredError(samples, expectedValue) - variance) < variance * relativeTolerance); + BOOST_TEST(std::abs(mean(samples) - expectedValue) < expectedValue * relativeTolerance); + BOOST_TEST(std::abs(meanSquaredError(samples, expectedValue) - variance) < variance * relativeTolerance); } BOOST_AUTO_TEST_CASE(uniformInt_can_be_reset) @@ -110,21 +108,21 @@ BOOST_AUTO_TEST_CASE(uniformInt_can_be_reset) constexpr uint32_t maxValue = 80; SimulationRNG::reset(1); - vector samples1; + std::vector samples1; for (uint32_t i = 0; i < numSamples; ++i) samples1.push_back(SimulationRNG::uniformInt(minValue, maxValue)); - vector samples2; + std::vector samples2; for (uint32_t i = 0; i < numSamples; ++i) samples2.push_back(SimulationRNG::uniformInt(minValue, maxValue)); SimulationRNG::reset(1); - vector samples3; + std::vector samples3; for (uint32_t i = 0; i < numSamples; ++i) samples3.push_back(SimulationRNG::uniformInt(minValue, maxValue)); SimulationRNG::reset(2); - vector samples4; + std::vector samples4; for (uint32_t i = 0; i < numSamples; ++i) samples4.push_back(SimulationRNG::uniformInt(minValue, maxValue)); @@ -148,12 +146,12 @@ BOOST_AUTO_TEST_CASE(binomialInt_should_produce_samples_with_right_expected_valu constexpr double expectedValue = numTrials * successProbability; constexpr double variance = numTrials * successProbability * (1 - successProbability); - vector samples; + std::vector samples; for (uint32_t i = 0; i < numSamples; ++i) samples.push_back(SimulationRNG::binomialInt(numTrials, successProbability)); - BOOST_TEST(abs(mean(samples) - expectedValue) < expectedValue * relativeTolerance); - BOOST_TEST(abs(meanSquaredError(samples, expectedValue) - variance) < variance * relativeTolerance); + BOOST_TEST(std::abs(mean(samples) - expectedValue) < expectedValue * relativeTolerance); + BOOST_TEST(std::abs(meanSquaredError(samples, expectedValue) - variance) < variance * relativeTolerance); } BOOST_AUTO_TEST_CASE(binomialInt_can_be_reset) @@ -163,21 +161,21 @@ BOOST_AUTO_TEST_CASE(binomialInt_can_be_reset) constexpr double successProbability = 0.6; SimulationRNG::reset(1); - vector samples1; + std::vector samples1; for (uint32_t i = 0; i < numSamples; ++i) samples1.push_back(SimulationRNG::binomialInt(numTrials, successProbability)); - vector samples2; + std::vector samples2; for (uint32_t i = 0; i < numSamples; ++i) samples2.push_back(SimulationRNG::binomialInt(numTrials, successProbability)); SimulationRNG::reset(1); - vector samples3; + std::vector samples3; for (uint32_t i = 0; i < numSamples; ++i) samples3.push_back(SimulationRNG::binomialInt(numTrials, successProbability)); SimulationRNG::reset(2); - vector samples4; + std::vector samples4; for (uint32_t i = 0; i < numSamples; ++i) samples4.push_back(SimulationRNG::binomialInt(numTrials, successProbability)); diff --git a/test/yulPhaser/TestHelpers.cpp b/test/yulPhaser/TestHelpers.cpp index 50afd70a3eb3..d75b63b4ac8b 100644 --- a/test/yulPhaser/TestHelpers.cpp +++ b/test/yulPhaser/TestHelpers.cpp @@ -22,22 +22,21 @@ #include -using namespace std; using namespace solidity; using namespace solidity::yul; using namespace solidity::phaser; using namespace solidity::phaser::test; -function phaser::test::wholeChromosomeReplacement(Chromosome _newChromosome) +std::function phaser::test::wholeChromosomeReplacement(Chromosome _newChromosome) { return [_newChromosome = std::move(_newChromosome)](Chromosome const&) { return _newChromosome; }; } -function phaser::test::geneSubstitution(size_t _geneIndex, string _geneValue) +std::function phaser::test::geneSubstitution(size_t _geneIndex, std::string _geneValue) { return [=](Chromosome const& _chromosome) { - vector newGenes = _chromosome.optimisationSteps(); + std::vector newGenes = _chromosome.optimisationSteps(); assert(_geneIndex < newGenes.size()); newGenes[_geneIndex] = _geneValue; @@ -45,18 +44,18 @@ function phaser::test::geneSubstitution(size_t _geneIndex, string _gen }; } -vector phaser::test::chromosomeLengths(Population const& _population) +std::vector phaser::test::chromosomeLengths(Population const& _population) { - vector lengths; + std::vector lengths; for (auto const& individual: _population.individuals()) lengths.push_back(individual.chromosome.length()); return lengths; } -map phaser::test::enumerateOptmisationSteps() +std::map phaser::test::enumerateOptmisationSteps() { - map stepIndices; + std::map stepIndices; size_t i = 0; for (auto const& nameAndAbbreviation: OptimiserSuite::stepNameToAbbreviationMap()) stepIndices.insert({nameAndAbbreviation.first, i++}); @@ -67,29 +66,29 @@ map phaser::test::enumerateOptmisationSteps() size_t phaser::test::countDifferences(Chromosome const& _chromosome1, Chromosome const& _chromosome2) { size_t count = 0; - for (size_t i = 0; i < min(_chromosome1.length(), _chromosome2.length()); ++i) + for (size_t i = 0; i < std::min(_chromosome1.length(), _chromosome2.length()); ++i) if (_chromosome1.optimisationSteps()[i] != _chromosome2.optimisationSteps()[i]) ++count; - return count + static_cast(abs( + return count + static_cast(std::abs( static_cast(_chromosome1.length()) - static_cast(_chromosome2.length()) )); } -string phaser::test::stripWhitespace(string const& input) +std::string phaser::test::stripWhitespace(std::string const& input) { - regex whitespaceRegex("\\s+"); + std::regex whitespaceRegex("\\s+"); return regex_replace(input, whitespaceRegex, ""); } -size_t phaser::test::countSubstringOccurrences(string const& _inputString, string const& _substring) +size_t phaser::test::countSubstringOccurrences(std::string const& _inputString, std::string const& _substring) { assert(_substring.size() > 0); size_t count = 0; size_t lastOccurrence = 0; - while ((lastOccurrence = _inputString.find(_substring, lastOccurrence)) != string::npos) + while ((lastOccurrence = _inputString.find(_substring, lastOccurrence)) != std::string::npos) { ++count; lastOccurrence += _substring.size(); diff --git a/test/yulPhaser/TestHelpersTest.cpp b/test/yulPhaser/TestHelpersTest.cpp index 89b98ecad7aa..23be74230cca 100644 --- a/test/yulPhaser/TestHelpersTest.cpp +++ b/test/yulPhaser/TestHelpersTest.cpp @@ -24,7 +24,6 @@ #include -using namespace std; using namespace solidity::yul; using namespace boost::test_tools; @@ -43,7 +42,7 @@ BOOST_AUTO_TEST_CASE(ChromosomeLengthMetric_evaluate_should_return_chromosome_le BOOST_AUTO_TEST_CASE(wholeChromosomeReplacement_should_replace_whole_chromosome_with_another) { - function mutation = wholeChromosomeReplacement(Chromosome("aaa")); + std::function mutation = wholeChromosomeReplacement(Chromosome("aaa")); BOOST_TEST(mutation(Chromosome("ccc")) == Chromosome("aaa")); } @@ -51,22 +50,22 @@ BOOST_AUTO_TEST_CASE(geneSubstitution_should_change_a_single_gene_at_a_given_ind { Chromosome chromosome("aaccff"); - function mutation1 = geneSubstitution(0, chromosome.optimisationSteps()[5]); + std::function mutation1 = geneSubstitution(0, chromosome.optimisationSteps()[5]); BOOST_TEST(mutation1(chromosome) == Chromosome("faccff")); - function mutation2 = geneSubstitution(5, chromosome.optimisationSteps()[0]); + std::function mutation2 = geneSubstitution(5, chromosome.optimisationSteps()[0]); BOOST_TEST(mutation2(chromosome) == Chromosome("aaccfa")); } BOOST_AUTO_TEST_CASE(chromosomeLengths_should_return_lengths_of_all_chromosomes_in_a_population) { - shared_ptr fitnessMetric = make_shared(); + std::shared_ptr fitnessMetric = std::make_shared(); Population population1(fitnessMetric, {Chromosome(), Chromosome("a"), Chromosome("aa"), Chromosome("aaa")}); - BOOST_TEST((chromosomeLengths(population1) == vector{0, 1, 2, 3})); + BOOST_TEST((chromosomeLengths(population1) == std::vector{0, 1, 2, 3})); Population population2(fitnessMetric); - BOOST_TEST((chromosomeLengths(population2) == vector{})); + BOOST_TEST((chromosomeLengths(population2) == std::vector{})); } BOOST_AUTO_TEST_CASE(countDifferences_should_return_zero_for_identical_chromosomes) @@ -99,11 +98,11 @@ BOOST_AUTO_TEST_CASE(countDifferences_should_count_missing_characters_as_differe BOOST_AUTO_TEST_CASE(enumerateOptimisationSteps_should_assing_indices_to_all_available_optimisation_steps) { - map stepsAndAbbreviations = OptimiserSuite::stepNameToAbbreviationMap(); - map stepsAndIndices = enumerateOptmisationSteps(); + std::map stepsAndAbbreviations = OptimiserSuite::stepNameToAbbreviationMap(); + std::map stepsAndIndices = enumerateOptmisationSteps(); BOOST_TEST(stepsAndIndices.size() == stepsAndAbbreviations.size()); - set stepsSoFar; + std::set stepsSoFar; for (auto& [name, index]: stepsAndIndices) { BOOST_TEST(index >= 0); From 838658ff36ba542a63f7e9582fdae51d7ac73024 Mon Sep 17 00:00:00 2001 From: Nikola Matic Date: Fri, 9 Feb 2024 14:50:23 +0100 Subject: [PATCH 0018/1022] Install dependencies and add symbolic link for python3 --- .circleci/config.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 02c15e691b4f..c06e06e12b81 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -977,6 +977,9 @@ jobs: steps: - run: git config --global core.autocrlf false - checkout + - run: + name: Install dependencies + command: python -m pip install --user requests - run: name: Python unit tests command: python.exe test/pyscriptTests.py @@ -1688,7 +1691,7 @@ jobs: - run: git config --global core.autocrlf false - checkout # Ensure windows has python3 alias required by prepare_bytecode_report - - run: ln -s /c/tools/miniconda3/python /c/tools/miniconda3/python3 + - run: ln -s /c/Python312/python /c/Python312/python3 - attach_workspace: at: build - prepare_bytecode_report: From 7c1bdbaa584ced642891894ab98b3bfa9055ea19 Mon Sep 17 00:00:00 2001 From: r0qs Date: Mon, 12 Feb 2024 11:50:30 +0100 Subject: [PATCH 0019/1022] Remove sha from foundry release tag --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index c06e06e12b81..b29c46bf8b9e 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -155,7 +155,7 @@ commands: ) echo "export FOUNDRY_REPO=$FOUNDRY_REPO" >> "$BASH_ENV" echo "export FOUNDRY_VERSION=$FOUNDRY_VERSION" >> "$BASH_ENV" - echo "export FOUNDRY_RELEASE_TAG='nightly-${FOUNDRY_RELEASE_SHA}'" >> "$BASH_ENV" + echo "export FOUNDRY_RELEASE_TAG='${FOUNDRY_VERSION}'" >> "$BASH_ENV" # Save commit sha for caching echo "$FOUNDRY_RELEASE_SHA" > /tmp/workspace/foundry-release-sha - restore_cache: From c7549de45bbc280055cc433990d13cac608f1d22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Sun, 11 Feb 2024 17:07:13 +0100 Subject: [PATCH 0020/1022] Only warn instead of failing when enforcing gas expectations with non-standard settings --- test/Common.cpp | 20 +++++++++----------- test/soltest.cpp | 3 --- test/tools/isoltest.cpp | 3 --- 3 files changed, 9 insertions(+), 17 deletions(-) diff --git a/test/Common.cpp b/test/Common.cpp index 6a3c5a2a00ad..14d90d837e8d 100644 --- a/test/Common.cpp +++ b/test/Common.cpp @@ -143,18 +143,16 @@ void CommonOptions::validate() const "Selected batch has to be less than number of batches." ); - if (enforceGasTest) + if (!enforceGasTest) + cout << endl << "WARNING :: Gas cost expectations are not being enforced" << endl << endl; + else if (evmVersion() != langutil::EVMVersion{} || useABIEncoderV1) { - assertThrow( - evmVersion() == langutil::EVMVersion{}, - ConfigException, - "Gas costs can only be enforced on latest evm version." - ); - assertThrow( - useABIEncoderV1 == false, - ConfigException, - "Gas costs can only be enforced on abi encoder v2." - ); + cout << endl << "WARNING :: Enforcing gas cost expectations with non-standard settings:" << endl; + if (evmVersion() != langutil::EVMVersion{}) + cout << "- EVM version: " << evmVersion().name() << " (default: " << langutil::EVMVersion{}.name() << ")" << endl; + if (useABIEncoderV1) + cout << "- ABI coder: v1 (default: v2)" << endl; + cout << endl << "DO NOT COMMIT THE UPDATED EXPECTATIONS." << endl << endl; } } diff --git a/test/soltest.cpp b/test/soltest.cpp index 6aa100248875..443c4c5de3e3 100644 --- a/test/soltest.cpp +++ b/test/soltest.cpp @@ -238,9 +238,6 @@ test_suite* init_unit_test_suite(int /*argc*/, char* /*argv*/[]) if (solidity::test::CommonOptions::get().disableSemanticTests) cout << endl << "--- SKIPPING ALL SEMANTICS TESTS ---" << endl << endl; - if (!solidity::test::CommonOptions::get().enforceGasTest) - cout << endl << "WARNING :: Gas Cost Expectations are not being enforced" << endl << endl; - Batcher batcher(CommonOptions::get().selectedBatch, CommonOptions::get().batches); if (CommonOptions::get().batches > 1) cout << "Batch " << CommonOptions::get().selectedBatch << " out of " << CommonOptions::get().batches << endl; diff --git a/test/tools/isoltest.cpp b/test/tools/isoltest.cpp index 2d93bdbc2b9a..9d20f1059fb3 100644 --- a/test/tools/isoltest.cpp +++ b/test/tools/isoltest.cpp @@ -448,9 +448,6 @@ int main(int argc, char const *argv[]) if (options.disableSemanticTests) cout << endl << "--- SKIPPING ALL SEMANTICS TESTS ---" << endl << endl; - if (!options.enforceGasTest) - cout << "WARNING :: Gas Cost Expectations are not being enforced" << endl << endl; - TestStats global_stats{0, 0}; cout << "Running tests..." << endl << endl; From 44da00d3ff7be33c5dc87ad1a62b5aba320bec09 Mon Sep 17 00:00:00 2001 From: Nikola Matic Date: Tue, 6 Feb 2024 12:25:25 +0100 Subject: [PATCH 0021/1022] Use MCOPY when copying byte arrays --- Changelog.md | 1 + libsolidity/codegen/YulUtilFunctions.cpp | 32 ++++++------ .../debug_info_in_yul_snippet_escaping/output | 2 + .../args | 1 + .../input.sol | 10 ++++ .../output | 51 +++++++++++++++++++ .../args | 1 + .../input.sol | 9 ++++ .../output | 51 +++++++++++++++++++ .../yul_string_format_ascii/output.json | 2 + .../yul_string_format_ascii_long/output.json | 2 + .../semanticTests/various/address_code.sol | 2 +- .../sizeLimits/bytecode_too_large.sol | 4 +- 13 files changed, 150 insertions(+), 18 deletions(-) create mode 100644 test/cmdlineTests/mcopy_bytes_array_returned_from_function/args create mode 100644 test/cmdlineTests/mcopy_bytes_array_returned_from_function/input.sol create mode 100644 test/cmdlineTests/mcopy_bytes_array_returned_from_function/output create mode 100644 test/cmdlineTests/mcopy_string_literal_returned_from_function/args create mode 100644 test/cmdlineTests/mcopy_string_literal_returned_from_function/input.sol create mode 100644 test/cmdlineTests/mcopy_string_literal_returned_from_function/output diff --git a/Changelog.md b/Changelog.md index d20c266d8384..3d64b1b80e6f 100644 --- a/Changelog.md +++ b/Changelog.md @@ -4,6 +4,7 @@ Language Features: Compiler Features: + * Code Generator: Use ``MCOPY`` instead of ``MLOAD``/``MSTORE`` loop when copying byte arrays. Bugfixes: diff --git a/libsolidity/codegen/YulUtilFunctions.cpp b/libsolidity/codegen/YulUtilFunctions.cpp index 35fea8ac4b76..0dabc8a36928 100644 --- a/libsolidity/codegen/YulUtilFunctions.cpp +++ b/libsolidity/codegen/YulUtilFunctions.cpp @@ -88,34 +88,36 @@ std::string YulUtilFunctions::copyToMemoryFunction(bool _fromCalldata, bool _cle "_to_memory"s + (_cleanup ? "_with_cleanup"s : ""s); - return m_functionCollector.createFunction(functionName, [&]() { + return m_functionCollector.createFunction(functionName, [&](std::vector& _args, std::vector&) { + _args = {"src", "dst", "length"}; + if (_fromCalldata) - { return Whiskers(R"( - function (src, dst, length) { - calldatacopy(dst, src, length) - mstore(add(dst, length), 0) - } + calldatacopy(dst, src, length) + mstore(add(dst, length), 0) )") - ("functionName", functionName) ("cleanup", _cleanup) .render(); - } else { - return Whiskers(R"( - function (src, dst, length) { + if (m_evmVersion.hasMcopy()) + return Whiskers(R"( + mcopy(dst, src, length) + mstore(add(dst, length), 0) + )") + ("cleanup", _cleanup) + .render(); + else + return Whiskers(R"( let i := 0 for { } lt(i, length) { i := add(i, 32) } { mstore(add(dst, i), mload(add(src, i))) } mstore(add(dst, length), 0) - } - )") - ("functionName", functionName) - ("cleanup", _cleanup) - .render(); + )") + ("cleanup", _cleanup) + .render(); } }); } diff --git a/test/cmdlineTests/debug_info_in_yul_snippet_escaping/output b/test/cmdlineTests/debug_info_in_yul_snippet_escaping/output index 94dfb864262a..4c90d9054d2a 100644 --- a/test/cmdlineTests/debug_info_in_yul_snippet_escaping/output +++ b/test/cmdlineTests/debug_info_in_yul_snippet_escaping/output @@ -180,12 +180,14 @@ object "D_27" { } function copy_memory_to_memory_with_cleanup(src, dst, length) { + let i := 0 for { } lt(i, length) { i := add(i, 32) } { mstore(add(dst, i), mload(add(src, i))) } mstore(add(dst, length), 0) + } function round_up_to_mul_of_32(value) -> result { diff --git a/test/cmdlineTests/mcopy_bytes_array_returned_from_function/args b/test/cmdlineTests/mcopy_bytes_array_returned_from_function/args new file mode 100644 index 000000000000..c74711ba8aec --- /dev/null +++ b/test/cmdlineTests/mcopy_bytes_array_returned_from_function/args @@ -0,0 +1 @@ +--evm-version cancun --no-cbor-metadata --via-ir --optimize --ir-optimized --debug-info none diff --git a/test/cmdlineTests/mcopy_bytes_array_returned_from_function/input.sol b/test/cmdlineTests/mcopy_bytes_array_returned_from_function/input.sol new file mode 100644 index 000000000000..05f24d64e792 --- /dev/null +++ b/test/cmdlineTests/mcopy_bytes_array_returned_from_function/input.sol @@ -0,0 +1,10 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity >=0.0.0; + +contract C { + function foo() external pure returns (bytes memory) + { + bytes memory ret = "aaaaa"; + return ret; + } +} diff --git a/test/cmdlineTests/mcopy_bytes_array_returned_from_function/output b/test/cmdlineTests/mcopy_bytes_array_returned_from_function/output new file mode 100644 index 000000000000..2441357d97fb --- /dev/null +++ b/test/cmdlineTests/mcopy_bytes_array_returned_from_function/output @@ -0,0 +1,51 @@ +Optimized IR: +/// @use-src 0:"mcopy_bytes_array_returned_from_function/input.sol" +object "C_14" { + code { + { + let _1 := memoryguard(0x80) + mstore(64, _1) + if callvalue() { revert(0, 0) } + let _2 := datasize("C_14_deployed") + codecopy(_1, dataoffset("C_14_deployed"), _2) + return(_1, _2) + } + } + /// @use-src 0:"mcopy_bytes_array_returned_from_function/input.sol" + object "C_14_deployed" { + code { + { + let _1 := memoryguard(0x80) + if iszero(lt(calldatasize(), 4)) + { + if eq(0xc2985578, shr(224, calldataload(0))) + { + if callvalue() { revert(0, 0) } + if slt(add(calldatasize(), not(3)), 0) { revert(0, 0) } + let _2 := 64 + let newFreePtr := add(_1, _2) + if or(gt(newFreePtr, 0xffffffffffffffff), lt(newFreePtr, _1)) + { + mstore(0, shl(224, 0x4e487b71)) + mstore(4, 0x41) + revert(0, 36) + } + mstore(_2, newFreePtr) + mstore(_1, 5) + let _3 := add(_1, 0x20) + mstore(_3, "aaaaa") + let memPos := mload(_2) + mstore(memPos, 0x20) + let length := mload(_1) + mstore(add(memPos, 0x20), length) + mcopy(add(memPos, _2), _3, length) + mstore(add(add(memPos, length), _2), 0) + return(memPos, add(sub(add(memPos, and(add(length, 31), not(31))), memPos), _2)) + } + } + revert(0, 0) + } + } + data ".metadata" hex"" + } +} diff --git a/test/cmdlineTests/mcopy_string_literal_returned_from_function/args b/test/cmdlineTests/mcopy_string_literal_returned_from_function/args new file mode 100644 index 000000000000..c74711ba8aec --- /dev/null +++ b/test/cmdlineTests/mcopy_string_literal_returned_from_function/args @@ -0,0 +1 @@ +--evm-version cancun --no-cbor-metadata --via-ir --optimize --ir-optimized --debug-info none diff --git a/test/cmdlineTests/mcopy_string_literal_returned_from_function/input.sol b/test/cmdlineTests/mcopy_string_literal_returned_from_function/input.sol new file mode 100644 index 000000000000..0251c7cec976 --- /dev/null +++ b/test/cmdlineTests/mcopy_string_literal_returned_from_function/input.sol @@ -0,0 +1,9 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity >=0.0.0; + +contract C { + function foo() external pure returns (string memory) + { + return "MCOPY on Cancun vacation."; + } +} diff --git a/test/cmdlineTests/mcopy_string_literal_returned_from_function/output b/test/cmdlineTests/mcopy_string_literal_returned_from_function/output new file mode 100644 index 000000000000..02740ec0d6cb --- /dev/null +++ b/test/cmdlineTests/mcopy_string_literal_returned_from_function/output @@ -0,0 +1,51 @@ +Optimized IR: +/// @use-src 0:"mcopy_string_literal_returned_from_function/input.sol" +object "C_10" { + code { + { + let _1 := memoryguard(0x80) + mstore(64, _1) + if callvalue() { revert(0, 0) } + let _2 := datasize("C_10_deployed") + codecopy(_1, dataoffset("C_10_deployed"), _2) + return(_1, _2) + } + } + /// @use-src 0:"mcopy_string_literal_returned_from_function/input.sol" + object "C_10_deployed" { + code { + { + let _1 := memoryguard(0x80) + if iszero(lt(calldatasize(), 4)) + { + if eq(0xc2985578, shr(224, calldataload(0))) + { + if callvalue() { revert(0, 0) } + if slt(add(calldatasize(), not(3)), 0) { revert(0, 0) } + let _2 := 64 + let newFreePtr := add(_1, _2) + if or(gt(newFreePtr, 0xffffffffffffffff), lt(newFreePtr, _1)) + { + mstore(0, shl(224, 0x4e487b71)) + mstore(4, 0x41) + revert(0, 0x24) + } + mstore(_2, newFreePtr) + mstore(_1, 25) + let _3 := add(_1, 0x20) + mstore(_3, "MCOPY on Cancun vacation.") + let memPos := mload(_2) + mstore(memPos, 0x20) + let length := mload(_1) + mstore(add(memPos, 0x20), length) + mcopy(add(memPos, _2), _3, length) + mstore(add(add(memPos, length), _2), 0) + return(memPos, add(sub(add(memPos, and(add(length, 31), not(31))), memPos), _2)) + } + } + revert(0, 0) + } + } + data ".metadata" hex"" + } +} diff --git a/test/cmdlineTests/yul_string_format_ascii/output.json b/test/cmdlineTests/yul_string_format_ascii/output.json index aa830d1abe9d..1a9612c777b8 100644 --- a/test/cmdlineTests/yul_string_format_ascii/output.json +++ b/test/cmdlineTests/yul_string_format_ascii/output.json @@ -96,12 +96,14 @@ object \"C_11\" { } function copy_memory_to_memory_with_cleanup(src, dst, length) { + let i := 0 for { } lt(i, length) { i := add(i, 32) } { mstore(add(dst, i), mload(add(src, i))) } mstore(add(dst, length), 0) + } function round_up_to_mul_of_32(value) -> result { diff --git a/test/cmdlineTests/yul_string_format_ascii_long/output.json b/test/cmdlineTests/yul_string_format_ascii_long/output.json index 348e5a0b578c..5adeabfdffcf 100644 --- a/test/cmdlineTests/yul_string_format_ascii_long/output.json +++ b/test/cmdlineTests/yul_string_format_ascii_long/output.json @@ -96,12 +96,14 @@ object \"C_11\" { } function copy_memory_to_memory_with_cleanup(src, dst, length) { + let i := 0 for { } lt(i, length) { i := add(i, 32) } { mstore(add(dst, i), mload(add(src, i))) } mstore(add(dst, length), 0) + } function round_up_to_mul_of_32(value) -> result { diff --git a/test/libsolidity/semanticTests/various/address_code.sol b/test/libsolidity/semanticTests/various/address_code.sol index 80daf116cdbd..7e48b00ca840 100644 --- a/test/libsolidity/semanticTests/various/address_code.sol +++ b/test/libsolidity/semanticTests/various/address_code.sol @@ -8,7 +8,7 @@ contract C { } // To avoid dependency on exact length. - function f() public view returns (bool) { return address(this).code.length > 400; } + function f() public view returns (bool) { return address(this).code.length > 380; } function g() public view returns (uint) { return address(0).code.length; } function h() public view returns (uint) { return address(1).code.length; } } diff --git a/test/libsolidity/syntaxTests/sizeLimits/bytecode_too_large.sol b/test/libsolidity/syntaxTests/sizeLimits/bytecode_too_large.sol index 21c48cc43323..f22b9755d652 100644 --- a/test/libsolidity/syntaxTests/sizeLimits/bytecode_too_large.sol +++ b/test/libsolidity/syntaxTests/sizeLimits/bytecode_too_large.sol @@ -7,6 +7,6 @@ contract test { } } // ==== -// EVMVersion: >=shanghai +// EVMVersion: >=cancun // ---- -// Warning 5574: (21-27154): Contract code size is 27187 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. +// Warning 5574: (21-27154): Contract code size is 27164 bytes and exceeds 24576 bytes (a limit introduced in Spurious Dragon). This contract may not be deployable on Mainnet. Consider enabling the optimizer (with a low "runs" value!), turning off revert strings, or using libraries. From 3122d35a4e8b0d49e20cb71833798d15d6e9ea73 Mon Sep 17 00:00:00 2001 From: Nikola Matic Date: Wed, 14 Feb 2024 14:41:26 +0100 Subject: [PATCH 0022/1022] ABI decode test case --- .../mcopy_bytes_array_abi_decode/args | 1 + .../mcopy_bytes_array_abi_decode/err | 5 + .../mcopy_bytes_array_abi_decode/input.sol | 9 + .../mcopy_bytes_array_abi_decode/output | 230 ++++++++++++++++++ 4 files changed, 245 insertions(+) create mode 100644 test/cmdlineTests/mcopy_bytes_array_abi_decode/args create mode 100644 test/cmdlineTests/mcopy_bytes_array_abi_decode/err create mode 100644 test/cmdlineTests/mcopy_bytes_array_abi_decode/input.sol create mode 100644 test/cmdlineTests/mcopy_bytes_array_abi_decode/output diff --git a/test/cmdlineTests/mcopy_bytes_array_abi_decode/args b/test/cmdlineTests/mcopy_bytes_array_abi_decode/args new file mode 100644 index 000000000000..4a03d8d932b9 --- /dev/null +++ b/test/cmdlineTests/mcopy_bytes_array_abi_decode/args @@ -0,0 +1 @@ +--evm-version cancun --no-cbor-metadata --via-ir --ir --debug-info none diff --git a/test/cmdlineTests/mcopy_bytes_array_abi_decode/err b/test/cmdlineTests/mcopy_bytes_array_abi_decode/err new file mode 100644 index 000000000000..de32e66295be --- /dev/null +++ b/test/cmdlineTests/mcopy_bytes_array_abi_decode/err @@ -0,0 +1,5 @@ +Warning: Statement has no effect. + --> mcopy_bytes_array_abi_decode/input.sol:7:9: + | +7 | abi.decode("abcd", (bytes)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/test/cmdlineTests/mcopy_bytes_array_abi_decode/input.sol b/test/cmdlineTests/mcopy_bytes_array_abi_decode/input.sol new file mode 100644 index 000000000000..07d66f800ec9 --- /dev/null +++ b/test/cmdlineTests/mcopy_bytes_array_abi_decode/input.sol @@ -0,0 +1,9 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity >=0.0.0; + +contract C { + function foo() external pure + { + abi.decode("abcd", (bytes)); + } +} diff --git a/test/cmdlineTests/mcopy_bytes_array_abi_decode/output b/test/cmdlineTests/mcopy_bytes_array_abi_decode/output new file mode 100644 index 000000000000..2a24ec834fa1 --- /dev/null +++ b/test/cmdlineTests/mcopy_bytes_array_abi_decode/output @@ -0,0 +1,230 @@ +IR: + +/// @use-src 0:"mcopy_bytes_array_abi_decode/input.sol" +object "C_15" { + code { + + mstore(64, memoryguard(128)) + if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } + + constructor_C_15() + + let _1 := allocate_unbounded() + codecopy(_1, dataoffset("C_15_deployed"), datasize("C_15_deployed")) + + return(_1, datasize("C_15_deployed")) + + function allocate_unbounded() -> memPtr { + memPtr := mload(64) + } + + function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() { + revert(0, 0) + } + + function constructor_C_15() { + + } + + } + /// @use-src 0:"mcopy_bytes_array_abi_decode/input.sol" + object "C_15_deployed" { + code { + + mstore(64, memoryguard(128)) + + if iszero(lt(calldatasize(), 4)) + { + let selector := shift_right_224_unsigned(calldataload(0)) + switch selector + + case 0xc2985578 + { + // foo() + + external_fun_foo_14() + } + + default {} + } + + revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() + + function shift_right_224_unsigned(value) -> newValue { + newValue := + + shr(224, value) + + } + + function allocate_unbounded() -> memPtr { + memPtr := mload(64) + } + + function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() { + revert(0, 0) + } + + function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() { + revert(0, 0) + } + + function abi_decode_tuple_(headStart, dataEnd) { + if slt(sub(dataEnd, headStart), 0) { revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() } + + } + + function abi_encode_tuple__to__fromStack(headStart ) -> tail { + tail := add(headStart, 0) + + } + + function external_fun_foo_14() { + + if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } + abi_decode_tuple_(4, calldatasize()) + fun_foo_14() + let memPos := allocate_unbounded() + let memEnd := abi_encode_tuple__to__fromStack(memPos ) + return(memPos, sub(memEnd, memPos)) + + } + + function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() { + revert(0, 0) + } + + function round_up_to_mul_of_32(value) -> result { + result := and(add(value, 31), not(31)) + } + + function panic_error_0x41() { + mstore(0, 35408467139433450592217433187231851964531694900788300625387963629091585785856) + mstore(4, 0x41) + revert(0, 0x24) + } + + function finalize_allocation(memPtr, size) { + let newFreePtr := add(memPtr, round_up_to_mul_of_32(size)) + // protect against overflow + if or(gt(newFreePtr, 0xffffffffffffffff), lt(newFreePtr, memPtr)) { panic_error_0x41() } + mstore(64, newFreePtr) + } + + function allocate_memory(size) -> memPtr { + memPtr := allocate_unbounded() + finalize_allocation(memPtr, size) + } + + function array_allocation_size_t_string_memory_ptr(length) -> size { + // Make sure we can allocate memory without overflow + if gt(length, 0xffffffffffffffff) { panic_error_0x41() } + + size := round_up_to_mul_of_32(length) + + // add length slot + size := add(size, 0x20) + + } + + function allocate_memory_array_t_string_memory_ptr(length) -> memPtr { + let allocSize := array_allocation_size_t_string_memory_ptr(length) + memPtr := allocate_memory(allocSize) + + mstore(memPtr, length) + + } + + function store_literal_in_memory_48bed44d1bcd124a28c27f343a817e5f5243190d3c52bf347daf876de1dbbf77(memPtr) { + + mstore(add(memPtr, 0), "abcd") + + } + + function copy_literal_to_memory_48bed44d1bcd124a28c27f343a817e5f5243190d3c52bf347daf876de1dbbf77() -> memPtr { + memPtr := allocate_memory_array_t_string_memory_ptr(4) + store_literal_in_memory_48bed44d1bcd124a28c27f343a817e5f5243190d3c52bf347daf876de1dbbf77(add(memPtr, 32)) + } + + function convert_t_stringliteral_48bed44d1bcd124a28c27f343a817e5f5243190d3c52bf347daf876de1dbbf77_to_t_bytes_memory_ptr() -> converted { + converted := copy_literal_to_memory_48bed44d1bcd124a28c27f343a817e5f5243190d3c52bf347daf876de1dbbf77() + } + + function revert_error_c1322bf8034eace5e0b5c7295db60986aa89aae5e0ea0873e4689e076861a5db() { + revert(0, 0) + } + + function revert_error_1b9f4a0a5773e33b91aa01db23bf8c55fce1411167c872835e7fa00a4f17d46d() { + revert(0, 0) + } + + function revert_error_987264b3b1d58a9c7f8255e93e81c77d86d6299019c33110a076957a3e06e2ae() { + revert(0, 0) + } + + function array_allocation_size_t_bytes_memory_ptr(length) -> size { + // Make sure we can allocate memory without overflow + if gt(length, 0xffffffffffffffff) { panic_error_0x41() } + + size := round_up_to_mul_of_32(length) + + // add length slot + size := add(size, 0x20) + + } + + function copy_memory_to_memory_with_cleanup(src, dst, length) { + + mcopy(dst, src, length) + mstore(add(dst, length), 0) + + } + + function abi_decode_available_length_t_bytes_memory_ptr_fromMemory(src, length, end) -> array { + array := allocate_memory(array_allocation_size_t_bytes_memory_ptr(length)) + mstore(array, length) + let dst := add(array, 0x20) + if gt(add(src, length), end) { revert_error_987264b3b1d58a9c7f8255e93e81c77d86d6299019c33110a076957a3e06e2ae() } + copy_memory_to_memory_with_cleanup(src, dst, length) + } + + // bytes + function abi_decode_t_bytes_memory_ptr_fromMemory(offset, end) -> array { + if iszero(slt(add(offset, 0x1f), end)) { revert_error_1b9f4a0a5773e33b91aa01db23bf8c55fce1411167c872835e7fa00a4f17d46d() } + let length := mload(offset) + array := abi_decode_available_length_t_bytes_memory_ptr_fromMemory(add(offset, 0x20), length, end) + } + + function abi_decode_tuple_t_bytes_memory_ptr_fromMemory(headStart, dataEnd) -> value0 { + if slt(sub(dataEnd, headStart), 32) { revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() } + + { + + let offset := mload(add(headStart, 0)) + if gt(offset, 0xffffffffffffffff) { revert_error_c1322bf8034eace5e0b5c7295db60986aa89aae5e0ea0873e4689e076861a5db() } + + value0 := abi_decode_t_bytes_memory_ptr_fromMemory(add(headStart, offset), dataEnd) + } + + } + + function array_length_t_bytes_memory_ptr(value) -> length { + + length := mload(value) + + } + + function fun_foo_14() { + + let _1_mpos := convert_t_stringliteral_48bed44d1bcd124a28c27f343a817e5f5243190d3c52bf347daf876de1dbbf77_to_t_bytes_memory_ptr() + + let expr_11_mpos := abi_decode_tuple_t_bytes_memory_ptr_fromMemory(add(_1_mpos, 32), add(add(_1_mpos, 32), array_length_t_bytes_memory_ptr(_1_mpos))) + + } + + } + + data ".metadata" hex"" + } + +} From 4032b5946cc0ae48baf4a65dd35e9401a3d612eb Mon Sep 17 00:00:00 2001 From: Alexander Arlt Date: Sat, 10 Feb 2024 01:47:07 +0100 Subject: [PATCH 0023/1022] Add DebugData to AssemblyItem. --- libevmasm/Assembly.cpp | 2 +- libevmasm/AssemblyItem.h | 45 ++++++++--- libevmasm/CommonSubexpressionEliminator.cpp | 76 ++++++++++--------- libevmasm/CommonSubexpressionEliminator.h | 4 +- libevmasm/ControlFlowGraph.cpp | 2 +- libevmasm/ExpressionClasses.cpp | 7 +- libevmasm/ExpressionClasses.h | 2 +- libevmasm/KnownState.cpp | 62 +++++++-------- libevmasm/KnownState.h | 16 ++-- libevmasm/PeepholeOptimiser.cpp | 14 ++-- libevmasm/SimplificationRules.cpp | 12 +-- libevmasm/SimplificationRules.h | 4 +- liblangutil/CMakeLists.txt | 1 + liblangutil/DebugData.h | 70 +++++++++++++++++ libyul/AST.h | 72 +++++------------- libyul/ASTForward.h | 1 - libyul/AsmParser.cpp | 26 +++---- libyul/AsmParser.h | 8 +- libyul/AsmPrinter.cpp | 2 +- libyul/AsmPrinter.h | 4 +- libyul/backends/evm/ConstantOptimiser.h | 6 +- libyul/backends/evm/ControlFlowGraph.h | 22 +++--- .../backends/evm/ControlFlowGraphBuilder.cpp | 8 +- libyul/backends/evm/ControlFlowGraphBuilder.h | 4 +- .../evm/OptimizedEVMCodeTransform.cpp | 2 +- .../backends/evm/OptimizedEVMCodeTransform.h | 2 +- libyul/optimiser/ConditionalSimplifier.cpp | 2 +- libyul/optimiser/ControlFlowSimplifier.cpp | 4 +- libyul/optimiser/ExpressionSplitter.cpp | 2 +- libyul/optimiser/ForLoopConditionIntoBody.cpp | 2 +- .../optimiser/ForLoopConditionOutOfBody.cpp | 2 +- libyul/optimiser/SSATransform.cpp | 4 +- libyul/optimiser/SimplificationRules.cpp | 2 +- libyul/optimiser/SimplificationRules.h | 6 +- libyul/optimiser/StackToMemoryMover.cpp | 4 +- test/tools/yulInterpreter/Inspector.cpp | 4 +- test/tools/yulInterpreter/Inspector.h | 6 +- 37 files changed, 289 insertions(+), 223 deletions(-) create mode 100644 liblangutil/DebugData.h diff --git a/libevmasm/Assembly.cpp b/libevmasm/Assembly.cpp index b6e4d0006c57..424d3229cae0 100644 --- a/libevmasm/Assembly.cpp +++ b/libevmasm/Assembly.cpp @@ -180,7 +180,7 @@ AssemblyItem Assembly::createAssemblyItemFromJSON(Json::Value const& _json, std: if (c_instructions.count(name)) { - AssemblyItem item{c_instructions.at(name), location}; + AssemblyItem item{c_instructions.at(name), langutil::DebugData::create(location)}; if (!jumpType.empty()) { if (item.instruction() == Instruction::JUMP || item.instruction() == Instruction::JUMPI) diff --git a/libevmasm/AssemblyItem.h b/libevmasm/AssemblyItem.h index 93be394733ca..c2b3603c6352 100644 --- a/libevmasm/AssemblyItem.h +++ b/libevmasm/AssemblyItem.h @@ -24,7 +24,8 @@ #include #include -#include +#include +#include #include #include #include @@ -64,16 +65,16 @@ class AssemblyItem public: enum class JumpType { Ordinary, IntoFunction, OutOfFunction }; - AssemblyItem(u256 _push, langutil::SourceLocation _location = langutil::SourceLocation()): - AssemblyItem(Push, std::move(_push), std::move(_location)) { } - AssemblyItem(Instruction _i, langutil::SourceLocation _location = langutil::SourceLocation()): + AssemblyItem(u256 _push, langutil::DebugData::ConstPtr _debugData = langutil::DebugData::create()): + AssemblyItem(Push, std::move(_push), std::move(_debugData)) { } + AssemblyItem(Instruction _i, langutil::DebugData::ConstPtr _debugData = langutil::DebugData::create()): m_type(Operation), m_instruction(_i), - m_location(std::move(_location)) + m_debugData(std::move(_debugData)) {} - AssemblyItem(AssemblyItemType _type, u256 _data = 0, langutil::SourceLocation _location = langutil::SourceLocation()): + AssemblyItem(AssemblyItemType _type, u256 _data = 0, langutil::DebugData::ConstPtr _debugData = langutil::DebugData::create()): m_type(_type), - m_location(std::move(_location)) + m_debugData(std::move(_debugData)) { if (m_type == Operation) m_instruction = Instruction(uint8_t(_data)); @@ -83,7 +84,8 @@ class AssemblyItem explicit AssemblyItem(bytes _verbatimData, size_t _arguments, size_t _returnVariables): m_type(VerbatimBytecode), m_instruction{}, - m_verbatimBytecode{{_arguments, _returnVariables, std::move(_verbatimData)}} + m_verbatimBytecode{{_arguments, _returnVariables, std::move(_verbatimData)}}, + m_debugData{langutil::DebugData::create()} {} AssemblyItem(AssemblyItem const&) = default; @@ -170,8 +172,29 @@ class AssemblyItem /// @returns true if the assembly item can be used in a functional context. bool canBeFunctional() const; - void setLocation(langutil::SourceLocation const& _location) { m_location = _location; } - langutil::SourceLocation const& location() const { return m_location; } + void setLocation(langutil::SourceLocation const& _location) + { + solAssert(m_debugData); + m_debugData = langutil::DebugData::create( + _location, + m_debugData->originLocation, + m_debugData->astID + ); + } + + langutil::SourceLocation const& location() const + { + solAssert(m_debugData); + return m_debugData->nativeLocation; + } + + void setDebugData(langutil::DebugData::ConstPtr _debugData) + { + solAssert(_debugData); + m_debugData = std::move(_debugData); + } + + langutil::DebugData::ConstPtr debugData() const { return m_debugData; } void setJumpType(JumpType _jumpType) { m_jumpType = _jumpType; } static std::optional parseJumpType(std::string const& _jumpType); @@ -196,7 +219,7 @@ class AssemblyItem /// If m_type == VerbatimBytecode, this holds number of arguments, number of /// return variables and verbatim bytecode. std::optional> m_verbatimBytecode; - langutil::SourceLocation m_location; + langutil::DebugData::ConstPtr m_debugData; JumpType m_jumpType = JumpType::Ordinary; /// Pushed value for operations with data to be determined during assembly stage, /// e.g. PushSubSize, PushTag, PushSub, etc. diff --git a/libevmasm/CommonSubexpressionEliminator.cpp b/libevmasm/CommonSubexpressionEliminator.cpp index de1e5a364aca..cb4eaebff3ce 100644 --- a/libevmasm/CommonSubexpressionEliminator.cpp +++ b/libevmasm/CommonSubexpressionEliminator.cpp @@ -29,6 +29,7 @@ #include #include +#include using namespace solidity; using namespace solidity::evmasm; @@ -57,9 +58,9 @@ std::vector CommonSubexpressionEliminator::getOptimizedItems() if (!m_state.stackElements().empty()) minHeight = std::min(minHeight, m_state.stackElements().begin()->first); for (int height = minHeight; height <= m_initialState.stackHeight(); ++height) - initialStackContents[height] = m_initialState.stackElement(height, SourceLocation()); + initialStackContents[height] = m_initialState.stackElement(height, langutil::DebugData::create()); for (int height = minHeight; height <= m_state.stackHeight(); ++height) - targetStackContents[height] = m_state.stackElement(height, SourceLocation()); + targetStackContents[height] = m_state.stackElement(height, langutil::DebugData::create()); AssemblyItems items = CSECodeGenerator(m_state.expressionClasses(), m_storeOperations).generateCode( m_initialState.sequenceNumber(), @@ -87,23 +88,24 @@ void CommonSubexpressionEliminator::optimizeBreakingItem() ExpressionClasses& classes = m_state.expressionClasses(); SourceLocation const& itemLocation = m_breakingItem->location(); + langutil::DebugData::ConstPtr debugData{langutil::DebugData::create(itemLocation)}; if (*m_breakingItem == AssemblyItem(Instruction::JUMPI)) { AssemblyItem::JumpType jumpType = m_breakingItem->getJumpType(); - Id condition = m_state.stackElement(m_state.stackHeight() - 1, itemLocation); + Id condition = m_state.stackElement(m_state.stackHeight() - 1, debugData); if (classes.knownNonZero(condition)) { - feedItem(AssemblyItem(Instruction::SWAP1, itemLocation), true); - feedItem(AssemblyItem(Instruction::POP, itemLocation), true); + feedItem(AssemblyItem(Instruction::SWAP1, debugData), true); + feedItem(AssemblyItem(Instruction::POP, debugData), true); - AssemblyItem item(Instruction::JUMP, itemLocation); + AssemblyItem item(Instruction::JUMP, debugData); item.setJumpType(jumpType); m_breakingItem = classes.storeItem(item); } else if (classes.knownZero(condition)) { - AssemblyItem it(Instruction::POP, itemLocation); + AssemblyItem it(Instruction::POP, debugData); feedItem(it, true); feedItem(it, true); m_breakingItem = nullptr; @@ -111,12 +113,12 @@ void CommonSubexpressionEliminator::optimizeBreakingItem() } else if (*m_breakingItem == AssemblyItem(Instruction::RETURN)) { - Id size = m_state.stackElement(m_state.stackHeight() - 1, itemLocation); + Id size = m_state.stackElement(m_state.stackHeight() - 1, debugData); if (classes.knownZero(size)) { - feedItem(AssemblyItem(Instruction::POP, itemLocation), true); - feedItem(AssemblyItem(Instruction::POP, itemLocation), true); - AssemblyItem item(Instruction::STOP, itemLocation); + feedItem(AssemblyItem(Instruction::POP, debugData), true); + feedItem(AssemblyItem(Instruction::POP, debugData), true); + AssemblyItem item(Instruction::STOP, debugData); m_breakingItem = classes.storeItem(item); } } @@ -181,16 +183,16 @@ AssemblyItems CSECodeGenerator::generateCode( assertThrow(!m_classPositions[targetItem.second].empty(), OptimizerException, ""); if (m_classPositions[targetItem.second].count(targetItem.first)) continue; - SourceLocation sourceLocation; + langutil::DebugData::ConstPtr debugData; if (m_expressionClasses.representative(targetItem.second).item) - sourceLocation = m_expressionClasses.representative(targetItem.second).item->location(); + debugData = m_expressionClasses.representative(targetItem.second).item->debugData(); int position = classElementPosition(targetItem.second); if (position < targetItem.first) // it is already at its target, we need another copy - appendDup(position, sourceLocation); + appendDup(position, debugData); else - appendOrRemoveSwap(position, sourceLocation); - appendOrRemoveSwap(targetItem.first, sourceLocation); + appendOrRemoveSwap(position, debugData); + appendOrRemoveSwap(targetItem.first, debugData); } // remove surplus elements @@ -263,7 +265,7 @@ void CSECodeGenerator::addDependencies(Id _c) case Instruction::KECCAK256: { Id length = expr.arguments.at(1); - AssemblyItem offsetInstr(Instruction::SUB, expr.item->location()); + AssemblyItem offsetInstr(Instruction::SUB, expr.item->debugData()); Id offsetToStart = m_expressionClasses.find(offsetInstr, {slot, slotToLoadFrom}); u256 const* o = m_expressionClasses.knownConstant(offsetToStart); u256 const* l = m_expressionClasses.knownConstant(length); @@ -334,7 +336,7 @@ void CSECodeGenerator::generateClassElement(Id _c, bool _allowSequenced) for (Id arg: arguments | ranges::views::reverse) generateClassElement(arg); - SourceLocation const& itemLocation = expr.item->location(); + langutil::DebugData::ConstPtr itemDebugData = expr.item->debugData(); // The arguments are somewhere on the stack now, so it remains to move them at the correct place. // This is quite difficult as sometimes, the values also have to removed in this process // (if canBeRemoved() returns true) and the two arguments can be equal. For now, this is @@ -342,42 +344,42 @@ void CSECodeGenerator::generateClassElement(Id _c, bool _allowSequenced) if (arguments.size() == 1) { if (canBeRemoved(arguments[0], _c)) - appendOrRemoveSwap(classElementPosition(arguments[0]), itemLocation); + appendOrRemoveSwap(classElementPosition(arguments[0]), itemDebugData); else - appendDup(classElementPosition(arguments[0]), itemLocation); + appendDup(classElementPosition(arguments[0]), itemDebugData); } else if (arguments.size() == 2) { if (canBeRemoved(arguments[1], _c)) { - appendOrRemoveSwap(classElementPosition(arguments[1]), itemLocation); + appendOrRemoveSwap(classElementPosition(arguments[1]), itemDebugData); if (arguments[0] == arguments[1]) - appendDup(m_stackHeight, itemLocation); + appendDup(m_stackHeight, itemDebugData); else if (canBeRemoved(arguments[0], _c)) { - appendOrRemoveSwap(m_stackHeight - 1, itemLocation); - appendOrRemoveSwap(classElementPosition(arguments[0]), itemLocation); + appendOrRemoveSwap(m_stackHeight - 1, itemDebugData); + appendOrRemoveSwap(classElementPosition(arguments[0]), itemDebugData); } else - appendDup(classElementPosition(arguments[0]), itemLocation); + appendDup(classElementPosition(arguments[0]), itemDebugData); } else { if (arguments[0] == arguments[1]) { - appendDup(classElementPosition(arguments[0]), itemLocation); - appendDup(m_stackHeight, itemLocation); + appendDup(classElementPosition(arguments[0]), itemDebugData); + appendDup(m_stackHeight, itemDebugData); } else if (canBeRemoved(arguments[0], _c)) { - appendOrRemoveSwap(classElementPosition(arguments[0]), itemLocation); - appendDup(classElementPosition(arguments[1]), itemLocation); - appendOrRemoveSwap(m_stackHeight - 1, itemLocation); + appendOrRemoveSwap(classElementPosition(arguments[0]), itemDebugData); + appendDup(classElementPosition(arguments[1]), itemDebugData); + appendOrRemoveSwap(m_stackHeight - 1, itemDebugData); } else { - appendDup(classElementPosition(arguments[1]), itemLocation); - appendDup(classElementPosition(arguments[0]), itemLocation); + appendDup(classElementPosition(arguments[1]), itemDebugData); + appendDup(classElementPosition(arguments[0]), itemDebugData); } } } @@ -398,7 +400,7 @@ void CSECodeGenerator::generateClassElement(Id _c, bool _allowSequenced) !m_generatedItems.empty() && m_generatedItems.back() == AssemblyItem(Instruction::SWAP1)) // this will not append a swap but remove the one that is already there - appendOrRemoveSwap(m_stackHeight - 1, itemLocation); + appendOrRemoveSwap(m_stackHeight - 1, itemDebugData); for (size_t i = 0; i < arguments.size(); ++i) { m_classPositions[m_stack[m_stackHeight - static_cast(i)]].erase(m_stackHeight - static_cast(i)); @@ -467,18 +469,18 @@ bool CSECodeGenerator::removeStackTopIfPossible() return true; } -void CSECodeGenerator::appendDup(int _fromPosition, SourceLocation const& _location) +void CSECodeGenerator::appendDup(int _fromPosition, langutil::DebugData::ConstPtr _debugData) { assertThrow(_fromPosition != c_invalidPosition, OptimizerException, ""); int instructionNum = 1 + m_stackHeight - _fromPosition; assertThrow(instructionNum <= 16, StackTooDeepException, util::stackTooDeepString); assertThrow(1 <= instructionNum, OptimizerException, "Invalid stack access."); - appendItem(AssemblyItem(dupInstruction(static_cast(instructionNum)), _location)); + appendItem(AssemblyItem(dupInstruction(static_cast(instructionNum)), std::move(_debugData))); m_stack[m_stackHeight] = m_stack[_fromPosition]; m_classPositions[m_stack[m_stackHeight]].insert(m_stackHeight); } -void CSECodeGenerator::appendOrRemoveSwap(int _fromPosition, SourceLocation const& _location) +void CSECodeGenerator::appendOrRemoveSwap(int _fromPosition, langutil::DebugData::ConstPtr _debugData) { assertThrow(_fromPosition != c_invalidPosition, OptimizerException, ""); if (_fromPosition == m_stackHeight) @@ -486,7 +488,7 @@ void CSECodeGenerator::appendOrRemoveSwap(int _fromPosition, SourceLocation cons int instructionNum = m_stackHeight - _fromPosition; assertThrow(instructionNum <= 16, StackTooDeepException, util::stackTooDeepString); assertThrow(1 <= instructionNum, OptimizerException, "Invalid stack access."); - appendItem(AssemblyItem(swapInstruction(static_cast(instructionNum)), _location)); + appendItem(AssemblyItem(swapInstruction(static_cast(instructionNum)), std::move(_debugData))); if (m_stack[m_stackHeight] != m_stack[_fromPosition]) { diff --git a/libevmasm/CommonSubexpressionEliminator.h b/libevmasm/CommonSubexpressionEliminator.h index b0810a9a1dd0..3e963838a4cc 100644 --- a/libevmasm/CommonSubexpressionEliminator.h +++ b/libevmasm/CommonSubexpressionEliminator.h @@ -142,10 +142,10 @@ class CSECodeGenerator bool removeStackTopIfPossible(); /// Appends a dup instruction to m_generatedItems to retrieve the element at the given stack position. - void appendDup(int _fromPosition, langutil::SourceLocation const& _location); + void appendDup(int _fromPosition, langutil::DebugData::ConstPtr _debugData); /// Appends a swap instruction to m_generatedItems to retrieve the element at the given stack position. /// @note this might also remove the last item if it exactly the same swap instruction. - void appendOrRemoveSwap(int _fromPosition, langutil::SourceLocation const& _location); + void appendOrRemoveSwap(int _fromPosition, langutil::DebugData::ConstPtr _debugData); /// Appends the given assembly item. void appendItem(AssemblyItem const& _item); diff --git a/libevmasm/ControlFlowGraph.cpp b/libevmasm/ControlFlowGraph.cpp index 9d2927ed9ca4..5b73fb6d5b21 100644 --- a/libevmasm/ControlFlowGraph.cpp +++ b/libevmasm/ControlFlowGraph.cpp @@ -275,7 +275,7 @@ void ControlFlowGraph::gatherKnowledge() //@todo in the case of JUMPI, add knowledge about the condition to the state // (for both values of the condition) std::set tags = state->tagsInExpression( - state->stackElement(state->stackHeight(), langutil::SourceLocation{}) + state->stackElement(state->stackHeight(), langutil::DebugData::create()) ); state->feedItem(m_items.at(pc++)); diff --git a/libevmasm/ExpressionClasses.cpp b/libevmasm/ExpressionClasses.cpp index dd66eea32840..74de0ae3f402 100644 --- a/libevmasm/ExpressionClasses.cpp +++ b/libevmasm/ExpressionClasses.cpp @@ -33,6 +33,7 @@ #include #include #include +#include using namespace solidity; using namespace solidity::evmasm; @@ -134,11 +135,11 @@ void ExpressionClasses::forceEqual( m_expressions.insert(exp); } -ExpressionClasses::Id ExpressionClasses::newClass(SourceLocation const& _location) +ExpressionClasses::Id ExpressionClasses::newClass(langutil::DebugData::ConstPtr _debugData) { Expression exp; exp.id = static_cast(m_representatives.size()); - exp.item = storeItem(AssemblyItem(UndefinedItem, (u256(1) << 255) + exp.id, _location)); + exp.item = storeItem(AssemblyItem(UndefinedItem, (u256(1) << 255) + exp.id, std::move(_debugData))); m_representatives.push_back(exp); m_expressions.insert(exp); return exp.id; @@ -226,7 +227,7 @@ ExpressionClasses::Id ExpressionClasses::tryToSimplify(Expression const& _expr) std::cout << "to " << match->action().toString() << std::endl; } - return rebuildExpression(ExpressionTemplate(match->action(), _expr.item->location())); + return rebuildExpression(ExpressionTemplate(match->action(), _expr.item->debugData())); } return std::numeric_limits::max(); diff --git a/libevmasm/ExpressionClasses.h b/libevmasm/ExpressionClasses.h index 8d4159fc7be1..510302e4c70c 100644 --- a/libevmasm/ExpressionClasses.h +++ b/libevmasm/ExpressionClasses.h @@ -92,7 +92,7 @@ class ExpressionClasses void forceEqual(Id _id, AssemblyItem const& _item, Ids const& _arguments, bool _copyItem = true); /// @returns the id of a new class which is different to all other classes. - Id newClass(langutil::SourceLocation const& _location); + Id newClass(langutil::DebugData::ConstPtr _debugData); /// @returns true if the values of the given classes are known to be different (on every input). /// @note that this function might still return false for some different inputs. diff --git a/libevmasm/KnownState.cpp b/libevmasm/KnownState.cpp index 91f798bf3890..3878ae0fdd75 100644 --- a/libevmasm/KnownState.cpp +++ b/libevmasm/KnownState.cpp @@ -27,6 +27,7 @@ #include #include +#include using namespace solidity; using namespace solidity::evmasm; @@ -114,7 +115,7 @@ KnownState::StoreOperation KnownState::feedItem(AssemblyItem const& _item, bool for (size_t i = 0; i < _item.returnValues(); ++i) setStackElement( m_stackHeight - static_cast(i), - m_expressionClasses->newClass(_item.location()) + m_expressionClasses->newClass(_item.debugData()) ); } else if (_item.type() != Operation) @@ -137,44 +138,44 @@ KnownState::StoreOperation KnownState::feedItem(AssemblyItem const& _item, bool m_stackHeight + 1, stackElement( m_stackHeight - static_cast(instruction) + static_cast(Instruction::DUP1), - _item.location() + _item.debugData() ) ); else if (SemanticInformation::isSwapInstruction(_item)) swapStackElements( m_stackHeight, m_stackHeight - 1 - static_cast(instruction) + static_cast(Instruction::SWAP1), - _item.location() + _item.debugData() ); else if (instruction != Instruction::POP) { std::vector arguments(static_cast(info.args)); for (size_t i = 0; i < static_cast(info.args); ++i) - arguments[i] = stackElement(m_stackHeight - static_cast(i), _item.location()); + arguments[i] = stackElement(m_stackHeight - static_cast(i), _item.debugData()); switch (_item.instruction()) { case Instruction::SSTORE: - op = storeInStorage(arguments[0], arguments[1], _item.location()); + op = storeInStorage(arguments[0], arguments[1], _item.debugData()); break; case Instruction::SLOAD: setStackElement( m_stackHeight + static_cast(_item.deposit()), - loadFromStorage(arguments[0], _item.location()) + loadFromStorage(arguments[0], _item.debugData()) ); break; case Instruction::MSTORE: - op = storeInMemory(arguments[0], arguments[1], _item.location()); + op = storeInMemory(arguments[0], arguments[1], _item.debugData()); break; case Instruction::MLOAD: setStackElement( m_stackHeight + static_cast(_item.deposit()), - loadFromMemory(arguments[0], _item.location()) + loadFromMemory(arguments[0], _item.debugData()) ); break; case Instruction::KECCAK256: setStackElement( m_stackHeight + static_cast(_item.deposit()), - applyKeccak256(arguments.at(0), arguments.at(1), _item.location()) + applyKeccak256(arguments.at(0), arguments.at(1), _item.debugData()) ); break; default: @@ -276,18 +277,18 @@ bool KnownState::operator==(KnownState const& _other) const return (thisIt == m_stackElements.cend() && otherIt == _other.m_stackElements.cend()); } -ExpressionClasses::Id KnownState::stackElement(int _stackHeight, SourceLocation const& _location) +ExpressionClasses::Id KnownState::stackElement(int _stackHeight, langutil::DebugData::ConstPtr _debugData) { if (m_stackElements.count(_stackHeight)) return m_stackElements.at(_stackHeight); // Stack element not found (not assigned yet), create new unknown equivalence class. return m_stackElements[_stackHeight] = - m_expressionClasses->find(AssemblyItem(UndefinedItem, _stackHeight, _location)); + m_expressionClasses->find(AssemblyItem(UndefinedItem, _stackHeight, std::move(_debugData))); } -KnownState::Id KnownState::relativeStackElement(int _stackOffset, SourceLocation const& _location) +KnownState::Id KnownState::relativeStackElement(int _stackOffset, langutil::DebugData::ConstPtr _debugData) { - return stackElement(m_stackHeight + _stackOffset, _location); + return stackElement(m_stackHeight + _stackOffset, std::move(_debugData)); } void KnownState::clearTagUnions() @@ -307,13 +308,13 @@ void KnownState::setStackElement(int _stackHeight, Id _class) void KnownState::swapStackElements( int _stackHeightA, int _stackHeightB, - SourceLocation const& _location + langutil::DebugData::ConstPtr _debugData ) { assertThrow(_stackHeightA != _stackHeightB, OptimizerException, "Swap on same stack elements."); // ensure they are created - stackElement(_stackHeightA, _location); - stackElement(_stackHeightB, _location); + stackElement(_stackHeightA, _debugData); + stackElement(_stackHeightB, _debugData); std::swap(m_stackElements[_stackHeightA], m_stackElements[_stackHeightB]); } @@ -321,7 +322,8 @@ void KnownState::swapStackElements( KnownState::StoreOperation KnownState::storeInStorage( Id _slot, Id _value, - SourceLocation const& _location) + langutil::DebugData::ConstPtr _debugData +) { if (m_storageContent.count(_slot) && m_storageContent[_slot] == _value) // do not execute the storage if we know that the value is already there @@ -336,7 +338,7 @@ KnownState::StoreOperation KnownState::storeInStorage( storageContents.insert(storageItem); m_storageContent = std::move(storageContents); - AssemblyItem item(Instruction::SSTORE, _location); + AssemblyItem item(Instruction::SSTORE, std::move(_debugData)); Id id = m_expressionClasses->find(item, {_slot, _value}, true, m_sequenceNumber); StoreOperation operation{StoreOperation::Storage, _slot, m_sequenceNumber, id}; m_storageContent[_slot] = _value; @@ -346,16 +348,16 @@ KnownState::StoreOperation KnownState::storeInStorage( return operation; } -ExpressionClasses::Id KnownState::loadFromStorage(Id _slot, SourceLocation const& _location) +ExpressionClasses::Id KnownState::loadFromStorage(Id _slot, langutil::DebugData::ConstPtr _debugData) { if (m_storageContent.count(_slot)) return m_storageContent.at(_slot); - AssemblyItem item(Instruction::SLOAD, _location); + AssemblyItem item(Instruction::SLOAD, std::move(_debugData)); return m_storageContent[_slot] = m_expressionClasses->find(item, {_slot}, true, m_sequenceNumber); } -KnownState::StoreOperation KnownState::storeInMemory(Id _slot, Id _value, SourceLocation const& _location) +KnownState::StoreOperation KnownState::storeInMemory(Id _slot, Id _value, langutil::DebugData::ConstPtr _debugData) { if (m_memoryContent.count(_slot) && m_memoryContent[_slot] == _value) // do not execute the store if we know that the value is already there @@ -368,7 +370,7 @@ KnownState::StoreOperation KnownState::storeInMemory(Id _slot, Id _value, Source memoryContents.insert(memoryItem); m_memoryContent = std::move(memoryContents); - AssemblyItem item(Instruction::MSTORE, _location); + AssemblyItem item(Instruction::MSTORE, std::move(_debugData)); Id id = m_expressionClasses->find(item, {_slot, _value}, true, m_sequenceNumber); StoreOperation operation{StoreOperation::Memory, _slot, m_sequenceNumber, id}; m_memoryContent[_slot] = _value; @@ -377,22 +379,22 @@ KnownState::StoreOperation KnownState::storeInMemory(Id _slot, Id _value, Source return operation; } -ExpressionClasses::Id KnownState::loadFromMemory(Id _slot, SourceLocation const& _location) +ExpressionClasses::Id KnownState::loadFromMemory(Id _slot, langutil::DebugData::ConstPtr _debugData) { if (m_memoryContent.count(_slot)) return m_memoryContent.at(_slot); - AssemblyItem item(Instruction::MLOAD, _location); + AssemblyItem item(Instruction::MLOAD, std::move(_debugData)); return m_memoryContent[_slot] = m_expressionClasses->find(item, {_slot}, true, m_sequenceNumber); } KnownState::Id KnownState::applyKeccak256( Id _start, Id _length, - SourceLocation const& _location + langutil::DebugData::ConstPtr _debugData ) { - AssemblyItem keccak256Item(Instruction::KECCAK256, _location); + AssemblyItem keccak256Item(Instruction::KECCAK256, _debugData); // Special logic if length is a short constant, otherwise we cannot tell. u256 const* l = m_expressionClasses->knownConstant(_length); // unknown or too large length @@ -403,10 +405,10 @@ KnownState::Id KnownState::applyKeccak256( for (unsigned i = 0; i < length; i += 32) { Id slot = m_expressionClasses->find( - AssemblyItem(Instruction::ADD, _location), + AssemblyItem(Instruction::ADD, _debugData), {_start, m_expressionClasses->find(u256(i))} ); - arguments.push_back(loadFromMemory(slot, _location)); + arguments.push_back(loadFromMemory(slot, _debugData)); } if (m_knownKeccak256Hashes.count({arguments, length})) return m_knownKeccak256Hashes.at({arguments, length}); @@ -418,7 +420,7 @@ KnownState::Id KnownState::applyKeccak256( for (Id a: arguments) data += toBigEndian(*m_expressionClasses->knownConstant(a)); data.resize(length); - v = m_expressionClasses->find(AssemblyItem(u256(util::keccak256(data)), _location)); + v = m_expressionClasses->find(AssemblyItem(u256(util::keccak256(data)), _debugData)); } else v = m_expressionClasses->find(keccak256Item, {_start, _length}, true, m_sequenceNumber); @@ -443,7 +445,7 @@ KnownState::Id KnownState::tagUnion(std::set _tags) return m_tagUnions.right.at(_tags); else { - Id id = m_expressionClasses->newClass(SourceLocation()); + Id id = m_expressionClasses->newClass(langutil::DebugData::create()); m_tagUnions.right.insert(make_pair(_tags, id)); return id; } diff --git a/libevmasm/KnownState.h b/libevmasm/KnownState.h index 9cc22710fabe..79426c36f4dd 100644 --- a/libevmasm/KnownState.h +++ b/libevmasm/KnownState.h @@ -134,9 +134,9 @@ class KnownState /// Retrieves the current equivalence class for the given stack element (or generates a new /// one if it does not exist yet). - Id stackElement(int _stackHeight, langutil::SourceLocation const& _location); + Id stackElement(int _stackHeight, langutil::DebugData::ConstPtr _debugData); /// @returns the stackElement relative to the current stack height. - Id relativeStackElement(int _stackOffset, langutil::SourceLocation const& _location = {}); + Id relativeStackElement(int _stackOffset, langutil::DebugData::ConstPtr _debugData = {}); /// @returns its set of tags if the given expression class is a known tag union; returns a set /// containing the tag if it is a PushTag expression and the empty set otherwise. @@ -155,22 +155,22 @@ class KnownState /// Assigns a new equivalence class to the next sequence number of the given stack element. void setStackElement(int _stackHeight, Id _class); /// Swaps the given stack elements in their next sequence number. - void swapStackElements(int _stackHeightA, int _stackHeightB, langutil::SourceLocation const& _location); + void swapStackElements(int _stackHeightA, int _stackHeightB, langutil::DebugData::ConstPtr _debugData); /// Increments the sequence number, deletes all storage information that might be overwritten /// and stores the new value at the given slot. /// @returns the store operation, which might be invalid if storage was not modified - StoreOperation storeInStorage(Id _slot, Id _value, langutil::SourceLocation const& _location); + StoreOperation storeInStorage(Id _slot, Id _value,langutil::DebugData::ConstPtr _debugData); /// Retrieves the current value at the given slot in storage or creates a new special sload class. - Id loadFromStorage(Id _slot, langutil::SourceLocation const& _location); + Id loadFromStorage(Id _slot, langutil::DebugData::ConstPtr _debugData); /// Increments the sequence number, deletes all memory information that might be overwritten /// and stores the new value at the given slot. /// @returns the store operation, which might be invalid if memory was not modified - StoreOperation storeInMemory(Id _slot, Id _value, langutil::SourceLocation const& _location); + StoreOperation storeInMemory(Id _slot, Id _value, langutil::DebugData::ConstPtr _debugData); /// Retrieves the current value at the given slot in memory or creates a new special mload class. - Id loadFromMemory(Id _slot, langutil::SourceLocation const& _location); + Id loadFromMemory(Id _slot, langutil::DebugData::ConstPtr _debugData); /// Finds or creates a new expression that applies the Keccak-256 hash function to the contents in memory. - Id applyKeccak256(Id _start, Id _length, langutil::SourceLocation const& _location); + Id applyKeccak256(Id _start, Id _length, langutil::DebugData::ConstPtr _debugData); /// @returns a new or already used Id representing the given set of tags. Id tagUnion(std::set _tags); diff --git a/libevmasm/PeepholeOptimiser.cpp b/libevmasm/PeepholeOptimiser.cpp index e9231c0a56b0..257a3727c01d 100644 --- a/libevmasm/PeepholeOptimiser.cpp +++ b/libevmasm/PeepholeOptimiser.cpp @@ -119,7 +119,7 @@ struct OpPop: SimplePeepholeOptimizerMethod if (instructionInfo(instr, langutil::EVMVersion()).ret == 1 && !instructionInfo(instr, langutil::EVMVersion()).sideEffects) { for (int j = 0; j < instructionInfo(instr, langutil::EVMVersion()).args; j++) - *_out = {Instruction::POP, _op.location()}; + *_out = {Instruction::POP, _op.debugData()}; return true; } } @@ -142,13 +142,13 @@ struct OpStop: SimplePeepholeOptimizerMethod Instruction instr = _op.instruction(); if (!instructionInfo(instr, langutil::EVMVersion()).sideEffects) { - *_out = {Instruction::STOP, _op.location()}; + *_out = {Instruction::STOP, _op.debugData()}; return true; } } else if (_op.type() == Push) { - *_out = {Instruction::STOP, _op.location()}; + *_out = {Instruction::STOP, _op.debugData()}; return true; } } @@ -208,7 +208,7 @@ struct DoublePush: SimplePeepholeOptimizerMethod if (_push1.type() == Push && _push2.type() == Push && _push1.data() == _push2.data()) { *_out = _push1; - *_out = {Instruction::DUP1, _push2.location()}; + *_out = {Instruction::DUP1, _push2.debugData()}; return true; } else @@ -334,7 +334,7 @@ struct EqIsZeroJumpI: SimplePeepholeOptimizerMethod _jumpi == Instruction::JUMPI ) { - *_out = AssemblyItem(Instruction::SUB, _eq.location()); + *_out = AssemblyItem(Instruction::SUB, _eq.debugData()); *_out = _pushTag; *_out = _jumpi; return true; @@ -365,7 +365,7 @@ struct DoubleJump: SimplePeepholeOptimizerMethod _pushTag1.data() == _tag1.data() ) { - *_out = AssemblyItem(Instruction::ISZERO, _jumpi.location()); + *_out = AssemblyItem(Instruction::ISZERO, _jumpi.debugData()); *_out = _pushTag2; *_out = _jumpi; *_out = _tag1; @@ -393,7 +393,7 @@ struct JumpToNext: SimplePeepholeOptimizerMethod ) { if (_jump == Instruction::JUMPI) - *_out = AssemblyItem(Instruction::POP, _jump.location()); + *_out = AssemblyItem(Instruction::POP, _jump.debugData()); *_out = _tag; return true; } diff --git a/libevmasm/SimplificationRules.cpp b/libevmasm/SimplificationRules.cpp index ef2d68c7fdaa..5085b2c3c8f7 100644 --- a/libevmasm/SimplificationRules.cpp +++ b/libevmasm/SimplificationRules.cpp @@ -126,12 +126,12 @@ bool Pattern::matches(Expression const& _expr, ExpressionClasses const& _classes return true; } -AssemblyItem Pattern::toAssemblyItem(SourceLocation const& _location) const +AssemblyItem Pattern::toAssemblyItem(langutil::DebugData::ConstPtr _debugData) const { if (m_type == Operation) - return AssemblyItem(m_instruction, _location); + return AssemblyItem(m_instruction, std::move(_debugData)); else - return AssemblyItem(m_type, data(), _location); + return AssemblyItem(m_type, data(), std::move(_debugData)); } std::string Pattern::toString() const @@ -199,7 +199,7 @@ u256 const& Pattern::data() const return *m_data; } -ExpressionTemplate::ExpressionTemplate(Pattern const& _pattern, SourceLocation const& _location) +ExpressionTemplate::ExpressionTemplate(Pattern const& _pattern, langutil::DebugData::ConstPtr const& _debugData) { if (_pattern.matchGroup()) { @@ -209,10 +209,10 @@ ExpressionTemplate::ExpressionTemplate(Pattern const& _pattern, SourceLocation c else { hasId = false; - item = _pattern.toAssemblyItem(_location); + item = _pattern.toAssemblyItem(_debugData); } for (auto const& arg: _pattern.arguments()) - arguments.emplace_back(arg, _location); + arguments.emplace_back(arg, _debugData); } std::string ExpressionTemplate::toString() const diff --git a/libevmasm/SimplificationRules.h b/libevmasm/SimplificationRules.h index b3f8da3c7f7c..fadad3608492 100644 --- a/libevmasm/SimplificationRules.h +++ b/libevmasm/SimplificationRules.h @@ -111,7 +111,7 @@ class Pattern unsigned matchGroup() const { return m_matchGroup; } bool matches(Expression const& _expr, ExpressionClasses const& _classes) const; - AssemblyItem toAssemblyItem(langutil::SourceLocation const& _location) const; + AssemblyItem toAssemblyItem(langutil::DebugData::ConstPtr _debugData) const; std::vector arguments() const { return m_arguments; } /// @returns the id of the matched expression if this pattern is part of a match group. @@ -149,7 +149,7 @@ struct ExpressionTemplate { using Expression = ExpressionClasses::Expression; using Id = ExpressionClasses::Id; - explicit ExpressionTemplate(Pattern const& _pattern, langutil::SourceLocation const& _location); + explicit ExpressionTemplate(Pattern const& _pattern, langutil::DebugData::ConstPtr const& _debugData); std::string toString() const; bool hasId = false; /// Id of the matched expression, if available. diff --git a/liblangutil/CMakeLists.txt b/liblangutil/CMakeLists.txt index 53be57e79d58..054d01d91881 100644 --- a/liblangutil/CMakeLists.txt +++ b/liblangutil/CMakeLists.txt @@ -3,6 +3,7 @@ set(sources Common.h CharStream.cpp CharStream.h + DebugData.h DebugInfoSelection.cpp DebugInfoSelection.h ErrorReporter.cpp diff --git a/liblangutil/DebugData.h b/liblangutil/DebugData.h new file mode 100644 index 000000000000..70259bd039f3 --- /dev/null +++ b/liblangutil/DebugData.h @@ -0,0 +1,70 @@ +/* + This file is part of solidity. + + solidity is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + solidity is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with solidity. If not, see . +*/ +// SPDX-License-Identifier: GPL-3.0 + +#pragma once + +#include +#include +#include + +namespace solidity::langutil +{ + +struct DebugData +{ + typedef typename std::shared_ptr ConstPtr; + + explicit DebugData( + langutil::SourceLocation _nativeLocation = {}, + langutil::SourceLocation _originLocation = {}, + std::optional _astID = {} + ): + nativeLocation(std::move(_nativeLocation)), + originLocation(std::move(_originLocation)), + astID(_astID) + {} + + static DebugData::ConstPtr create( + langutil::SourceLocation _nativeLocation, + langutil::SourceLocation _originLocation = {}, + std::optional _astID = {} + ) + { + return std::make_shared( + std::move(_nativeLocation), + std::move(_originLocation), + _astID + ); + } + + static DebugData::ConstPtr create() + { + static DebugData::ConstPtr emptyDebugData = create({}); + return emptyDebugData; + } + + /// Location in the Yul code. + langutil::SourceLocation nativeLocation; + /// Location in the original source that the Yul code was produced from. + /// Optional. Only present if the Yul source contains location annotations. + langutil::SourceLocation originLocation; + /// ID in the (Solidity) source AST. + std::optional astID; +}; + +} // namespace solidity::langutil diff --git a/libyul/AST.h b/libyul/AST.h index 71419d807faa..4e3e92de3dad 100644 --- a/libyul/AST.h +++ b/libyul/AST.h @@ -26,7 +26,7 @@ #include #include -#include +#include #include #include @@ -36,77 +36,43 @@ namespace solidity::yul using Type = YulString; -struct DebugData -{ - explicit DebugData( - langutil::SourceLocation _nativeLocation, - langutil::SourceLocation _originLocation = {}, - std::optional _astID = {} - ): - nativeLocation(std::move(_nativeLocation)), - originLocation(std::move(_originLocation)), - astID(std::move(_astID)) - {} - - static std::shared_ptr create( - langutil::SourceLocation _nativeLocation = {}, - langutil::SourceLocation _originLocation = {}, - std::optional _astID = {} - ) - { - return std::make_shared( - std::move(_nativeLocation), - std::move(_originLocation), - std::move(_astID) - ); - } - - /// Location in the Yul code. - langutil::SourceLocation nativeLocation; - /// Location in the original source that the Yul code was produced from. - /// Optional. Only present if the Yul source contains location annotations. - langutil::SourceLocation originLocation; - /// ID in the (Solidity) source AST. - std::optional astID; -}; - -struct TypedName { std::shared_ptr debugData; YulString name; Type type; }; +struct TypedName { langutil::DebugData::ConstPtr debugData; YulString name; Type type; }; using TypedNameList = std::vector; /// Literal number or string (up to 32 bytes) enum class LiteralKind { Number, Boolean, String }; -struct Literal { std::shared_ptr debugData; LiteralKind kind; YulString value; Type type; }; +struct Literal { langutil::DebugData::ConstPtr debugData; LiteralKind kind; YulString value; Type type; }; /// External / internal identifier or label reference -struct Identifier { std::shared_ptr debugData; YulString name; }; +struct Identifier { langutil::DebugData::ConstPtr debugData; YulString name; }; /// Assignment ("x := mload(20:u256)", expects push-1-expression on the right hand /// side and requires x to occupy exactly one stack slot. /// /// Multiple assignment ("x, y := f()"), where the left hand side variables each occupy /// a single stack slot and expects a single expression on the right hand returning /// the same amount of items as the number of variables. -struct Assignment { std::shared_ptr debugData; std::vector variableNames; std::unique_ptr value; }; -struct FunctionCall { std::shared_ptr debugData; Identifier functionName; std::vector arguments; }; +struct Assignment { langutil::DebugData::ConstPtr debugData; std::vector variableNames; std::unique_ptr value; }; +struct FunctionCall { langutil::DebugData::ConstPtr debugData; Identifier functionName; std::vector arguments; }; /// Statement that contains only a single expression -struct ExpressionStatement { std::shared_ptr debugData; Expression expression; }; +struct ExpressionStatement { langutil::DebugData::ConstPtr debugData; Expression expression; }; /// Block-scope variable declaration ("let x:u256 := mload(20:u256)"), non-hoisted -struct VariableDeclaration { std::shared_ptr debugData; TypedNameList variables; std::unique_ptr value; }; +struct VariableDeclaration { langutil::DebugData::ConstPtr debugData; TypedNameList variables; std::unique_ptr value; }; /// Block that creates a scope (frees declared stack variables) -struct Block { std::shared_ptr debugData; std::vector statements; }; +struct Block { langutil::DebugData::ConstPtr debugData; std::vector statements; }; /// Function definition ("function f(a, b) -> (d, e) { ... }") -struct FunctionDefinition { std::shared_ptr debugData; YulString name; TypedNameList parameters; TypedNameList returnVariables; Block body; }; +struct FunctionDefinition { langutil::DebugData::ConstPtr debugData; YulString name; TypedNameList parameters; TypedNameList returnVariables; Block body; }; /// Conditional execution without "else" part. -struct If { std::shared_ptr debugData; std::unique_ptr condition; Block body; }; +struct If { langutil::DebugData::ConstPtr debugData; std::unique_ptr condition; Block body; }; /// Switch case or default case -struct Case { std::shared_ptr debugData; std::unique_ptr value; Block body; }; +struct Case { langutil::DebugData::ConstPtr debugData; std::unique_ptr value; Block body; }; /// Switch statement -struct Switch { std::shared_ptr debugData; std::unique_ptr expression; std::vector cases; }; -struct ForLoop { std::shared_ptr debugData; Block pre; std::unique_ptr condition; Block post; Block body; }; +struct Switch { langutil::DebugData::ConstPtr debugData; std::unique_ptr expression; std::vector cases; }; +struct ForLoop { langutil::DebugData::ConstPtr debugData; Block pre; std::unique_ptr condition; Block post; Block body; }; /// Break statement (valid within for loop) -struct Break { std::shared_ptr debugData; }; +struct Break { langutil::DebugData::ConstPtr debugData; }; /// Continue statement (valid within for loop) -struct Continue { std::shared_ptr debugData; }; +struct Continue { langutil::DebugData::ConstPtr debugData; }; /// Leave statement (valid within function) -struct Leave { std::shared_ptr debugData; }; +struct Leave { langutil::DebugData::ConstPtr debugData; }; /// Extracts the IR source location from a Yul node. template inline langutil::SourceLocation nativeLocationOf(T const& _node) @@ -133,13 +99,13 @@ template inline langutil::SourceLocation originLocationOf(std::v } /// Extracts the debug data from a Yul node. -template inline std::shared_ptr debugDataOf(T const& _node) +template inline langutil::DebugData::ConstPtr debugDataOf(T const& _node) { return _node.debugData; } /// Extracts the debug data from a Yul node. -template inline std::shared_ptr debugDataOf(std::variant const& _node) +template inline langutil::DebugData::ConstPtr debugDataOf(std::variant const& _node) { return std::visit([](auto const& _arg) { return debugDataOf(_arg); }, _node); } diff --git a/libyul/ASTForward.h b/libyul/ASTForward.h index 0e61c6ca1263..a4dc5be3f8eb 100644 --- a/libyul/ASTForward.h +++ b/libyul/ASTForward.h @@ -28,7 +28,6 @@ namespace solidity::yul { -struct DebugData; enum class LiteralKind; struct Literal; struct Label; diff --git a/libyul/AsmParser.cpp b/libyul/AsmParser.cpp index 5d3ec84a4b97..3635b096af99 100644 --- a/libyul/AsmParser.cpp +++ b/libyul/AsmParser.cpp @@ -59,7 +59,7 @@ std::optional toInt(std::string const& _value) } -std::shared_ptr Parser::createDebugData() const +langutil::DebugData::ConstPtr Parser::createDebugData() const { switch (m_useSourceLocationFrom) { @@ -74,7 +74,7 @@ std::shared_ptr Parser::createDebugData() const } void Parser::updateLocationEndFrom( - std::shared_ptr& _debugData, + langutil::DebugData::ConstPtr& _debugData, SourceLocation const& _location ) const { @@ -286,7 +286,7 @@ std::optional>> Parser::parseASTI Block Parser::parseBlock() { RecursionGuard recursionGuard(*this); - Block block = createWithLocation(); + Block block = createWithDebugData(); expectToken(Token::LBrace); while (currentToken() != Token::RBrace) block.statements.emplace_back(parseStatement()); @@ -308,7 +308,7 @@ Statement Parser::parseStatement() return parseBlock(); case Token::If: { - If _if = createWithLocation(); + If _if = createWithDebugData(); advance(); _if.condition = std::make_unique(parseExpression()); _if.body = parseBlock(); @@ -317,7 +317,7 @@ Statement Parser::parseStatement() } case Token::Switch: { - Switch _switch = createWithLocation(); + Switch _switch = createWithDebugData(); advance(); _switch.expression = std::make_unique(parseExpression()); while (currentToken() == Token::Case) @@ -337,21 +337,21 @@ Statement Parser::parseStatement() return parseForLoop(); case Token::Break: { - Statement stmt{createWithLocation()}; + Statement stmt{createWithDebugData()}; checkBreakContinuePosition("break"); advance(); return stmt; } case Token::Continue: { - Statement stmt{createWithLocation()}; + Statement stmt{createWithDebugData()}; checkBreakContinuePosition("continue"); advance(); return stmt; } case Token::Leave: { - Statement stmt{createWithLocation()}; + Statement stmt{createWithDebugData()}; if (!m_insideFunction) m_errorReporter.syntaxError(8149_error, currentLocation(), "Keyword \"leave\" can only be used inside a function."); advance(); @@ -428,7 +428,7 @@ Statement Parser::parseStatement() Case Parser::parseCase() { RecursionGuard recursionGuard(*this); - Case _case = createWithLocation(); + Case _case = createWithDebugData(); if (currentToken() == Token::Default) advance(); else if (currentToken() == Token::Case) @@ -452,7 +452,7 @@ ForLoop Parser::parseForLoop() ForLoopComponent outerForLoopComponent = m_currentForLoopComponent; - ForLoop forLoop = createWithLocation(); + ForLoop forLoop = createWithDebugData(); expectToken(Token::For); m_currentForLoopComponent = ForLoopComponent::ForLoopPre; forLoop.pre = parseBlock(); @@ -559,7 +559,7 @@ std::variant Parser::parseLiteralOrIdentifier() VariableDeclaration Parser::parseVariableDeclaration() { RecursionGuard recursionGuard(*this); - VariableDeclaration varDecl = createWithLocation(); + VariableDeclaration varDecl = createWithDebugData(); expectToken(Token::Let); while (true) { @@ -595,7 +595,7 @@ FunctionDefinition Parser::parseFunctionDefinition() ForLoopComponent outerForLoopComponent = m_currentForLoopComponent; m_currentForLoopComponent = ForLoopComponent::None; - FunctionDefinition funDef = createWithLocation(); + FunctionDefinition funDef = createWithDebugData(); expectToken(Token::Function); funDef.name = expectAsmIdentifier(); expectToken(Token::LParen); @@ -657,7 +657,7 @@ FunctionCall Parser::parseCall(std::variant&& _initialOp) TypedName Parser::parseTypedName() { RecursionGuard recursionGuard(*this); - TypedName typedName = createWithLocation(); + TypedName typedName = createWithDebugData(); typedName.name = expectAsmIdentifier(); if (currentToken() == Token::Colon) { diff --git a/libyul/AsmParser.h b/libyul/AsmParser.h index da4f09ed2212..3e0af66acc10 100644 --- a/libyul/AsmParser.h +++ b/libyul/AsmParser.h @@ -118,15 +118,15 @@ class Parser: public langutil::ParserBase ); /// Creates a DebugData object with the correct source location set. - std::shared_ptr createDebugData() const; + langutil::DebugData::ConstPtr createDebugData() const; void updateLocationEndFrom( - std::shared_ptr& _debugData, + langutil::DebugData::ConstPtr& _debugData, langutil::SourceLocation const& _location ) const; - /// Creates an inline assembly node with the current source location. - template T createWithLocation() const + /// Creates an inline assembly node with the current debug data. + template T createWithDebugData() const { T r; r.debugData = createDebugData(); diff --git a/libyul/AsmPrinter.cpp b/libyul/AsmPrinter.cpp index bee213f8cafb..b27af037131b 100644 --- a/libyul/AsmPrinter.cpp +++ b/libyul/AsmPrinter.cpp @@ -305,7 +305,7 @@ std::string AsmPrinter::formatSourceLocation( return sourceLocation + (solidityCodeSnippet.empty() ? "" : " ") + solidityCodeSnippet; } -std::string AsmPrinter::formatDebugData(std::shared_ptr const& _debugData, bool _statement) +std::string AsmPrinter::formatDebugData(langutil::DebugData::ConstPtr const& _debugData, bool _statement) { if (!_debugData || m_debugInfoSelection.none()) return ""; diff --git a/libyul/AsmPrinter.h b/libyul/AsmPrinter.h index 7c67c14acfdc..d3f80b9a09d5 100644 --- a/libyul/AsmPrinter.h +++ b/libyul/AsmPrinter.h @@ -30,7 +30,7 @@ #include #include -#include +#include #include @@ -93,7 +93,7 @@ class AsmPrinter private: std::string formatTypedName(TypedName _variable); std::string appendTypeName(YulString _type, bool _isBoolLiteral = false) const; - std::string formatDebugData(std::shared_ptr const& _debugData, bool _statement); + std::string formatDebugData(langutil::DebugData::ConstPtr const& _debugData, bool _statement); template std::string formatDebugData(T const& _node) { diff --git a/libyul/backends/evm/ConstantOptimiser.h b/libyul/backends/evm/ConstantOptimiser.h index a60d2b2f5601..280f50bf9b97 100644 --- a/libyul/backends/evm/ConstantOptimiser.h +++ b/libyul/backends/evm/ConstantOptimiser.h @@ -27,7 +27,7 @@ #include #include -#include +#include #include @@ -74,7 +74,7 @@ class RepresentationFinder RepresentationFinder( EVMDialect const& _dialect, GasMeter const& _meter, - std::shared_ptr _debugData, + langutil::DebugData::ConstPtr _debugData, std::map& _cache ): m_dialect(_dialect), @@ -100,7 +100,7 @@ class RepresentationFinder EVMDialect const& m_dialect; GasMeter const& m_meter; - std::shared_ptr m_debugData; + langutil::DebugData::ConstPtr m_debugData; /// Counter for the complexity of optimization, will stop when it reaches zero. size_t m_maxSteps = 10000; std::map& m_cache; diff --git a/libyul/backends/evm/ControlFlowGraph.h b/libyul/backends/evm/ControlFlowGraph.h index 853a9e705dc2..980787c52297 100644 --- a/libyul/backends/evm/ControlFlowGraph.h +++ b/libyul/backends/evm/ControlFlowGraph.h @@ -76,7 +76,7 @@ struct FunctionReturnLabelSlot struct VariableSlot { std::reference_wrapper variable; - std::shared_ptr debugData{}; + langutil::DebugData::ConstPtr debugData{}; bool operator==(VariableSlot const& _rhs) const { return &variable.get() == &_rhs.variable.get(); } bool operator<(VariableSlot const& _rhs) const { return &variable.get() < &_rhs.variable.get(); } static constexpr bool canBeFreelyGenerated = false; @@ -85,7 +85,7 @@ struct VariableSlot struct LiteralSlot { u256 value; - std::shared_ptr debugData{}; + langutil::DebugData::ConstPtr debugData{}; bool operator==(LiteralSlot const& _rhs) const { return value == _rhs.value; } bool operator<(LiteralSlot const& _rhs) const { return value < _rhs.value; } static constexpr bool canBeFreelyGenerated = true; @@ -132,7 +132,7 @@ struct CFG struct BuiltinCall { - std::shared_ptr debugData; + langutil::DebugData::ConstPtr debugData; std::reference_wrapper builtin; std::reference_wrapper functionCall; /// Number of proper arguments with a position on the stack, excluding literal arguments. @@ -142,7 +142,7 @@ struct CFG }; struct FunctionCall { - std::shared_ptr debugData; + langutil::DebugData::ConstPtr debugData; std::reference_wrapper function; std::reference_wrapper functionCall; /// True, if the call is recursive, i.e. entering the function involves a control flow path (potentially involving @@ -153,7 +153,7 @@ struct CFG }; struct Assignment { - std::shared_ptr debugData; + langutil::DebugData::ConstPtr debugData; /// The variables being assigned to also occur as ``output`` in the ``Operation`` containing /// the assignment, but are also stored here for convenience. std::vector variables; @@ -176,25 +176,25 @@ struct CFG struct MainExit {}; struct ConditionalJump { - std::shared_ptr debugData; + langutil::DebugData::ConstPtr debugData; StackSlot condition; BasicBlock* nonZero = nullptr; BasicBlock* zero = nullptr; }; struct Jump { - std::shared_ptr debugData; + langutil::DebugData::ConstPtr debugData; BasicBlock* target = nullptr; /// The only backwards jumps are jumps from loop post to loop condition. bool backwards = false; }; struct FunctionReturn { - std::shared_ptr debugData; + langutil::DebugData::ConstPtr debugData; CFG::FunctionInfo* info = nullptr; }; struct Terminated {}; - std::shared_ptr debugData; + langutil::DebugData::ConstPtr debugData; std::vector entries; std::vector operations; /// True, if the block is the beginning of a disconnected subgraph. That is, if no block that is reachable @@ -210,7 +210,7 @@ struct CFG struct FunctionInfo { - std::shared_ptr debugData; + langutil::DebugData::ConstPtr debugData; Scope::Function const& function; FunctionDefinition const& functionDefinition; BasicBlock* entry = nullptr; @@ -238,7 +238,7 @@ struct CFG /// the switch case literals when transforming the control flow of a switch to a sequence of conditional jumps. std::list ghostCalls; - BasicBlock& makeBlock(std::shared_ptr _debugData) + BasicBlock& makeBlock(langutil::DebugData::ConstPtr _debugData) { return blocks.emplace_back(BasicBlock{std::move(_debugData), {}, {}}); } diff --git a/libyul/backends/evm/ControlFlowGraphBuilder.cpp b/libyul/backends/evm/ControlFlowGraphBuilder.cpp index 9a0a73b35fbf..4b0da1e80d91 100644 --- a/libyul/backends/evm/ControlFlowGraphBuilder.cpp +++ b/libyul/backends/evm/ControlFlowGraphBuilder.cpp @@ -333,7 +333,7 @@ void ControlFlowGraphBuilder::operator()(If const& _if) void ControlFlowGraphBuilder::operator()(Switch const& _switch) { yulAssert(m_currentBlock, ""); - std::shared_ptr preSwitchDebugData = debugDataOf(_switch); + langutil::DebugData::ConstPtr preSwitchDebugData = debugDataOf(_switch); auto ghostVariableId = m_graph.ghostVariables.size(); YulString ghostVariableName("GHOST[" + std::to_string(ghostVariableId) + "]"); @@ -393,7 +393,7 @@ void ControlFlowGraphBuilder::operator()(Switch const& _switch) void ControlFlowGraphBuilder::operator()(ForLoop const& _loop) { - std::shared_ptr preLoopDebugData = debugDataOf(_loop); + langutil::DebugData::ConstPtr preLoopDebugData = debugDataOf(_loop); ScopedSaveAndRestore scopeRestore(m_scope, m_info.scopes.at(&_loop.pre).get()); (*this)(_loop.pre); @@ -608,7 +608,7 @@ Scope::Variable const& ControlFlowGraphBuilder::lookupVariable(YulString _name) } void ControlFlowGraphBuilder::makeConditionalJump( - std::shared_ptr _debugData, + langutil::DebugData::ConstPtr _debugData, StackSlot _condition, CFG::BasicBlock& _nonZero, CFG::BasicBlock& _zero @@ -627,7 +627,7 @@ void ControlFlowGraphBuilder::makeConditionalJump( } void ControlFlowGraphBuilder::jump( - std::shared_ptr _debugData, + langutil::DebugData::ConstPtr _debugData, CFG::BasicBlock& _target, bool backwards ) diff --git a/libyul/backends/evm/ControlFlowGraphBuilder.h b/libyul/backends/evm/ControlFlowGraphBuilder.h index ffe935b0dd72..5007d361089b 100644 --- a/libyul/backends/evm/ControlFlowGraphBuilder.h +++ b/libyul/backends/evm/ControlFlowGraphBuilder.h @@ -67,13 +67,13 @@ class ControlFlowGraphBuilder Scope::Variable const& lookupVariable(YulString _name) const; /// Resets m_currentBlock to enforce a subsequent explicit reassignment. void makeConditionalJump( - std::shared_ptr _debugData, + langutil::DebugData::ConstPtr _debugData, StackSlot _condition, CFG::BasicBlock& _nonZero, CFG::BasicBlock& _zero ); void jump( - std::shared_ptr _debugData, + langutil::DebugData::ConstPtr _debugData, CFG::BasicBlock& _target, bool _backwards = false ); diff --git a/libyul/backends/evm/OptimizedEVMCodeTransform.cpp b/libyul/backends/evm/OptimizedEVMCodeTransform.cpp index 3df75bb88f50..a3052a542f64 100644 --- a/libyul/backends/evm/OptimizedEVMCodeTransform.cpp +++ b/libyul/backends/evm/OptimizedEVMCodeTransform.cpp @@ -237,7 +237,7 @@ void OptimizedEVMCodeTransform::validateSlot(StackSlot const& _slot, Expression }, _expression); } -void OptimizedEVMCodeTransform::createStackLayout(std::shared_ptr _debugData, Stack _targetStack) +void OptimizedEVMCodeTransform::createStackLayout(langutil::DebugData::ConstPtr _debugData, Stack _targetStack) { static constexpr auto slotVariableName = [](StackSlot const& _slot) { return std::visit(util::GenericVisitor{ diff --git a/libyul/backends/evm/OptimizedEVMCodeTransform.h b/libyul/backends/evm/OptimizedEVMCodeTransform.h index ed03c1453015..7e648ca964bb 100644 --- a/libyul/backends/evm/OptimizedEVMCodeTransform.h +++ b/libyul/backends/evm/OptimizedEVMCodeTransform.h @@ -83,7 +83,7 @@ class OptimizedEVMCodeTransform /// Shuffles m_stack to the desired @a _targetStack while emitting the shuffling code to m_assembly. /// Sets the source locations to the one in @a _debugData. - void createStackLayout(std::shared_ptr _debugData, Stack _targetStack); + void createStackLayout(langutil::DebugData::ConstPtr _debugData, Stack _targetStack); /// Generate code for the given block @a _block. /// Expects the current stack layout m_stack to be a stack layout that is compatible with the diff --git a/libyul/optimiser/ConditionalSimplifier.cpp b/libyul/optimiser/ConditionalSimplifier.cpp index b08b113de0ca..7119091257d3 100644 --- a/libyul/optimiser/ConditionalSimplifier.cpp +++ b/libyul/optimiser/ConditionalSimplifier.cpp @@ -78,7 +78,7 @@ void ConditionalSimplifier::operator()(Block& _block) ) { YulString condition = std::get(*_if.condition).name; - std::shared_ptr debugData = _if.debugData; + langutil::DebugData::ConstPtr debugData = _if.debugData; return make_vector( std::move(_s), Assignment{ diff --git a/libyul/optimiser/ControlFlowSimplifier.cpp b/libyul/optimiser/ControlFlowSimplifier.cpp index 771b4e86bfc7..10f479a421b4 100644 --- a/libyul/optimiser/ControlFlowSimplifier.cpp +++ b/libyul/optimiser/ControlFlowSimplifier.cpp @@ -37,7 +37,7 @@ namespace { ExpressionStatement makeDiscardCall( - std::shared_ptr const& _debugData, + langutil::DebugData::ConstPtr const& _debugData, BuiltinFunction const& _discardFunction, Expression&& _expression ) @@ -196,7 +196,7 @@ OptionalStatements ControlFlowSimplifier::reduceSingleCaseSwitch(Switch& _switch yulAssert(_switchStmt.cases.size() == 1, "Expected only one case!"); auto& switchCase = _switchStmt.cases.front(); - std::shared_ptr debugData = debugDataOf(*_switchStmt.expression); + langutil::DebugData::ConstPtr debugData = debugDataOf(*_switchStmt.expression); YulString type = m_typeInfo.typeOf(*_switchStmt.expression); if (switchCase.value) { diff --git a/libyul/optimiser/ExpressionSplitter.cpp b/libyul/optimiser/ExpressionSplitter.cpp index 986bcb097f33..6f0834d7760e 100644 --- a/libyul/optimiser/ExpressionSplitter.cpp +++ b/libyul/optimiser/ExpressionSplitter.cpp @@ -98,7 +98,7 @@ void ExpressionSplitter::outlineExpression(Expression& _expr) visit(_expr); - std::shared_ptr debugData = debugDataOf(_expr); + langutil::DebugData::ConstPtr debugData = debugDataOf(_expr); YulString var = m_nameDispenser.newName({}); YulString type = m_typeInfo.typeOf(_expr); m_statementsToPrefix.emplace_back(VariableDeclaration{ diff --git a/libyul/optimiser/ForLoopConditionIntoBody.cpp b/libyul/optimiser/ForLoopConditionIntoBody.cpp index 2dd0832c4288..33d8496f08b5 100644 --- a/libyul/optimiser/ForLoopConditionIntoBody.cpp +++ b/libyul/optimiser/ForLoopConditionIntoBody.cpp @@ -38,7 +38,7 @@ void ForLoopConditionIntoBody::operator()(ForLoop& _forLoop) !std::holds_alternative(*_forLoop.condition) ) { - std::shared_ptr debugData = debugDataOf(*_forLoop.condition); + langutil::DebugData::ConstPtr debugData = debugDataOf(*_forLoop.condition); _forLoop.body.statements.emplace( begin(_forLoop.body.statements), diff --git a/libyul/optimiser/ForLoopConditionOutOfBody.cpp b/libyul/optimiser/ForLoopConditionOutOfBody.cpp index 363ecdf0c02d..e2451bc6c6e9 100644 --- a/libyul/optimiser/ForLoopConditionOutOfBody.cpp +++ b/libyul/optimiser/ForLoopConditionOutOfBody.cpp @@ -54,7 +54,7 @@ void ForLoopConditionOutOfBody::operator()(ForLoop& _forLoop) return; YulString iszero = m_dialect.booleanNegationFunction()->name; - std::shared_ptr debugData = debugDataOf(*firstStatement.condition); + langutil::DebugData::ConstPtr debugData = debugDataOf(*firstStatement.condition); if ( std::holds_alternative(*firstStatement.condition) && diff --git a/libyul/optimiser/SSATransform.cpp b/libyul/optimiser/SSATransform.cpp index 74a7701494d4..675d21acc343 100644 --- a/libyul/optimiser/SSATransform.cpp +++ b/libyul/optimiser/SSATransform.cpp @@ -84,7 +84,7 @@ void IntroduceSSA::operator()(Block& _block) // Replace "let a := v" by "let a_1 := v let a := a_1" // Replace "let a, b := v" by "let a_1, b_1 := v let a := a_1 let b := b_2" - std::shared_ptr debugData = varDecl.debugData; + langutil::DebugData::ConstPtr debugData = varDecl.debugData; std::vector statements; statements.emplace_back(VariableDeclaration{debugData, {}, std::move(varDecl.value)}); TypedNameList newVariables; @@ -111,7 +111,7 @@ void IntroduceSSA::operator()(Block& _block) // Replace "a := v" by "let a_1 := v a := v" // Replace "a, b := v" by "let a_1, b_1 := v a := a_1 b := b_2" - std::shared_ptr debugData = assignment.debugData; + langutil::DebugData::ConstPtr debugData = assignment.debugData; std::vector statements; statements.emplace_back(VariableDeclaration{debugData, {}, std::move(assignment.value)}); TypedNameList newVariables; diff --git a/libyul/optimiser/SimplificationRules.cpp b/libyul/optimiser/SimplificationRules.cpp index f8bbcf678a1c..7fe56026ac95 100644 --- a/libyul/optimiser/SimplificationRules.cpp +++ b/libyul/optimiser/SimplificationRules.cpp @@ -234,7 +234,7 @@ evmasm::Instruction Pattern::instruction() const return m_instruction; } -Expression Pattern::toExpression(std::shared_ptr const& _debugData, langutil::EVMVersion _evmVersion) const +Expression Pattern::toExpression(langutil::DebugData::ConstPtr const& _debugData, langutil::EVMVersion _evmVersion) const { if (matchGroup()) return ASTCopier().translate(matchGroupValue()); diff --git a/libyul/optimiser/SimplificationRules.h b/libyul/optimiser/SimplificationRules.h index e36730f05425..5e498bd5c9a4 100644 --- a/libyul/optimiser/SimplificationRules.h +++ b/libyul/optimiser/SimplificationRules.h @@ -30,7 +30,7 @@ #include #include -#include +#include #include #include @@ -42,6 +42,8 @@ struct Dialect; struct AssignedValue; class Pattern; +using DebugData = langutil::DebugData; + /** * Container for all simplification rules. */ @@ -131,7 +133,7 @@ class Pattern /// Turns this pattern into an actual expression. Should only be called /// for patterns resulting from an action, i.e. with match groups assigned. - Expression toExpression(std::shared_ptr const& _debugData, langutil::EVMVersion _evmVersion) const; + Expression toExpression(langutil::DebugData::ConstPtr const& _debugData, langutil::EVMVersion _evmVersion) const; private: Expression const& matchGroupValue() const; diff --git a/libyul/optimiser/StackToMemoryMover.cpp b/libyul/optimiser/StackToMemoryMover.cpp index ab39669b2d9a..dedb5cd382ce 100644 --- a/libyul/optimiser/StackToMemoryMover.cpp +++ b/libyul/optimiser/StackToMemoryMover.cpp @@ -36,7 +36,7 @@ namespace { std::vector generateMemoryStore( Dialect const& _dialect, - std::shared_ptr const& _debugData, + langutil::DebugData::ConstPtr const& _debugData, YulString _mpos, Expression _value ) @@ -55,7 +55,7 @@ std::vector generateMemoryStore( return result; } -FunctionCall generateMemoryLoad(Dialect const& _dialect, std::shared_ptr const& _debugData, YulString _mpos) +FunctionCall generateMemoryLoad(Dialect const& _dialect, langutil::DebugData::ConstPtr const& _debugData, YulString _mpos) { BuiltinFunction const* memoryLoadFunction = _dialect.memoryLoadFunction(_dialect.defaultType); yulAssert(memoryLoadFunction, ""); diff --git a/test/tools/yulInterpreter/Inspector.cpp b/test/tools/yulInterpreter/Inspector.cpp index 9c4701d00a12..7746483a367a 100644 --- a/test/tools/yulInterpreter/Inspector.cpp +++ b/test/tools/yulInterpreter/Inspector.cpp @@ -56,7 +56,7 @@ void InspectedInterpreter::run( InspectedInterpreter{_inspector, _state, _dialect, scope, _disableExternalCalls, _disableMemoryTrace}(_ast); } -Inspector::NodeAction Inspector::queryUser(DebugData const& _data, std::map const& _variables) +Inspector::NodeAction Inspector::queryUser(langutil::DebugData const& _data, std::map const& _variables) { if (m_stepMode == NodeAction::RunNode) { @@ -131,7 +131,7 @@ Inspector::NodeAction Inspector::queryUser(DebugData const& _data, std::map(_data.nativeLocation.start), diff --git a/test/tools/yulInterpreter/Inspector.h b/test/tools/yulInterpreter/Inspector.h index 611279c6fe1c..f4518c7087d3 100644 --- a/test/tools/yulInterpreter/Inspector.h +++ b/test/tools/yulInterpreter/Inspector.h @@ -53,13 +53,13 @@ class Inspector * @returns NodeAction::RunNode if the current AST node (and all children nodes!) should be * processed without stopping, else NodeAction::StepThroughNode. */ - NodeAction queryUser(DebugData const& _data, std::map const& _variables); + NodeAction queryUser(langutil::DebugData const& _data, std::map const& _variables); void stepMode(NodeAction _action) { m_stepMode = _action; } std::string const& source() const { return m_source; } - void interactiveVisit(DebugData const& _debugData, std::map const& _variables, std::function _visitNode) + void interactiveVisit(langutil::DebugData const& _debugData, std::map const& _variables, std::function _visitNode) { Inspector::NodeAction action = queryUser(_debugData, _variables); @@ -78,7 +78,7 @@ class Inspector } private: - std::string currentSource(DebugData const& _data) const; + std::string currentSource(langutil::DebugData const& _data) const; /// Source of the file std::string const& m_source; From c7b8dcc52f28d68862ef298a94c7ce44f8080346 Mon Sep 17 00:00:00 2001 From: Alexander Arlt Date: Fri, 16 Feb 2024 20:40:05 +0100 Subject: [PATCH 0024/1022] [test] Add /usr/local/lib to search paths for macOS. --- test/Common.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/test/Common.cpp b/test/Common.cpp index 14d90d837e8d..bb4d2db7ebce 100644 --- a/test/Common.cpp +++ b/test/Common.cpp @@ -78,7 +78,10 @@ std::optional findInDefaultPath(std::string const& lib_name) fs::current_path() / ".." / "deps" / "lib", fs::current_path() / ".." / ".." / "deps", fs::current_path() / ".." / ".." / "deps" / "lib", - fs::current_path() + fs::current_path(), +#ifdef __APPLE__ + fs::current_path().root_path() / fs::path("usr") / "local" / "lib", +#endif }; for (auto const& basePath: searchPath) { From 9b8ed03823569a48005f0826175a08d5e1281f80 Mon Sep 17 00:00:00 2001 From: Alexander Arlt Date: Sun, 18 Feb 2024 20:53:03 +0100 Subject: [PATCH 0025/1022] Fix typo in Assembly::fromJSON(..). --- libevmasm/Assembly.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libevmasm/Assembly.cpp b/libevmasm/Assembly.cpp index b6e4d0006c57..ab6ac2c63f24 100644 --- a/libevmasm/Assembly.cpp +++ b/libevmasm/Assembly.cpp @@ -555,7 +555,7 @@ std::pair, std::vector> Assembly::fromJSO result->importAssemblyItemsFromJSON(_json[".code"], _level == 0 ? parsedSourceList : _sourceList); - if (_json[".auxdata"]) + if (_json.isMember(".auxdata")) { solRequire(_json[".auxdata"].isString(), AssemblyImportException, "Optional member '.auxdata' is not a string."); result->m_auxiliaryData = fromHex(_json[".auxdata"].asString()); From 5aed7515efd427b8f13f0abf3313539166292a3c Mon Sep 17 00:00:00 2001 From: r0qs Date: Mon, 19 Feb 2024 10:22:12 +0100 Subject: [PATCH 0026/1022] Use ethers version 6.11.0 on openzeppelin external tests --- test/externalTests/zeppelin.sh | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/test/externalTests/zeppelin.sh b/test/externalTests/zeppelin.sh index 64e6f5f0ec90..9f72aa4ec958 100755 --- a/test/externalTests/zeppelin.sh +++ b/test/externalTests/zeppelin.sh @@ -110,6 +110,13 @@ function zeppelin_test # Maybe related to the use of dynamic imports here: https://github.com/NomicFoundation/hardhat/commit/16ae15642951ac324ef7093a3342f7cf3a2a49a4 npm install @nomicfoundation/hardhat-chai-matchers@2.0.3 + # TODO: Remove when OpenZeppelin update to ethers 6.11.1+ + # Prior versions of ethers accepts an object instead of a string as an argument to the toUtf8Bytes function. + # However, starting from Ethers version 6.11.1, string arguments are enforced, + # which causes the introduced assertion to fail in some OpenZeppelin tests. + # See: https://github.com/ethers-io/ethers.js/issues/4583 + npm install ethers@6.11.0 + replace_version_pragmas for preset in $SELECTED_PRESETS; do From c21490f3c2e5c66e224029fc7f9cb482168bd7fe Mon Sep 17 00:00:00 2001 From: Alexander Arlt Date: Mon, 19 Feb 2024 13:34:15 +0100 Subject: [PATCH 0027/1022] [ci] Remove usage of ETH_EVMONE environment variable. --- .circleci/config.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index b29c46bf8b9e..f3843a689846 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -498,7 +498,6 @@ defaults: TERM: xterm MAKEFLAGS: -j5 CPUs: 5 - ETH_EVMONE: /usr/local/lib/libevmone.dylib - base_python_small: &base_python_small docker: From 18cabee1e4f60aae045ee9a0a0f2aba6d0d2c279 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Tue, 9 Jan 2024 14:08:38 +0100 Subject: [PATCH 0028/1022] CompilerStack: Don't swallow details include in OptimizerException - By catching and asserting it we hide the line number and message. - OptimizerException inherits from util::Exception so just letting it through will have the same effect as asserting. --- libsolidity/interface/CompilerStack.cpp | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/libsolidity/interface/CompilerStack.cpp b/libsolidity/interface/CompilerStack.cpp index 9b5c87818bf2..69394417586e 100644 --- a/libsolidity/interface/CompilerStack.cpp +++ b/libsolidity/interface/CompilerStack.cpp @@ -1480,15 +1480,8 @@ void CompilerStack::compileContract( solAssert(!m_viaIR, ""); bytes cborEncodedMetadata = createCBORMetadata(compiledContract, /* _forIR */ false); - try - { - // Run optimiser and compile the contract. - compiler->compileContract(_contract, _otherCompilers, cborEncodedMetadata); - } - catch(evmasm::OptimizerException const&) - { - solAssert(false, "Optimizer exception during compilation"); - } + // Run optimiser and compile the contract. + compiler->compileContract(_contract, _otherCompilers, cborEncodedMetadata); _otherCompilers[compiledContract.contract] = compiler; From f5188158f7edbc672cfc2b5b9125730bbf1886b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Tue, 9 Jan 2024 16:44:27 +0100 Subject: [PATCH 0029/1022] Remove obsolete gas cost tiers - They're no longer used because the cost depends on the EVM version. --- libevmasm/Assembly.cpp | 1 - libevmasm/GasMeter.cpp | 24 +++++++++++++----------- libevmasm/Instruction.cpp | 12 ++++++------ libevmasm/Instruction.h | 2 -- solc/CommandLineInterface.cpp | 2 -- 5 files changed, 19 insertions(+), 22 deletions(-) diff --git a/libevmasm/Assembly.cpp b/libevmasm/Assembly.cpp index ab6ac2c63f24..3f067ff6bcac 100644 --- a/libevmasm/Assembly.cpp +++ b/libevmasm/Assembly.cpp @@ -29,7 +29,6 @@ #include #include #include -#include #include #include diff --git a/libevmasm/GasMeter.cpp b/libevmasm/GasMeter.cpp index 5982b8a08092..e237e32a26ba 100644 --- a/libevmasm/GasMeter.cpp +++ b/libevmasm/GasMeter.cpp @@ -274,18 +274,20 @@ unsigned GasMeter::runGas(Instruction _instruction, langutil::EVMVersion _evmVer switch (instructionInfo(_instruction, _evmVersion).gasPriceTier) { - case Tier::Zero: return GasCosts::tier0Gas; - case Tier::Base: return GasCosts::tier1Gas; - case Tier::VeryLow: return GasCosts::tier2Gas; - case Tier::Low: return GasCosts::tier3Gas; - case Tier::Mid: return GasCosts::tier4Gas; - case Tier::High: return GasCosts::tier5Gas; - case Tier::Ext: return GasCosts::tier6Gas; - case Tier::WarmAccess: return GasCosts::warmStorageReadCost; - default: break; + case Tier::Zero: return GasCosts::tier0Gas; + case Tier::Base: return GasCosts::tier1Gas; + case Tier::VeryLow: return GasCosts::tier2Gas; + case Tier::Low: return GasCosts::tier3Gas; + case Tier::Mid: return GasCosts::tier4Gas; + case Tier::High: return GasCosts::tier5Gas; + case Tier::Ext: return GasCosts::tier6Gas; + case Tier::WarmAccess: return GasCosts::warmStorageReadCost; + + case Tier::Special: + case Tier::Invalid: + assertThrow(false, OptimizerException, "Invalid gas tier for instruction " + instructionInfo(_instruction, _evmVersion).name); } - assertThrow(false, OptimizerException, "Invalid gas tier for instruction " + instructionInfo(_instruction, _evmVersion).name); - return 0; + util::unreachable(); } u256 GasMeter::dataGas(bytes const& _data, bool _inCreation, langutil::EVMVersion _evmVersion) diff --git a/libevmasm/Instruction.cpp b/libevmasm/Instruction.cpp index a21f33e1838f..4e0684b6b4eb 100644 --- a/libevmasm/Instruction.cpp +++ b/libevmasm/Instruction.cpp @@ -211,7 +211,7 @@ static std::map const c_instructionInfo = { Instruction::SIGNEXTEND, { "SIGNEXTEND", 0, 2, 1, false, Tier::Low } }, { Instruction::KECCAK256, { "KECCAK256", 0, 2, 1, true, Tier::Special } }, { Instruction::ADDRESS, { "ADDRESS", 0, 0, 1, false, Tier::Base } }, - { Instruction::BALANCE, { "BALANCE", 0, 1, 1, false, Tier::Balance } }, + { Instruction::BALANCE, { "BALANCE", 0, 1, 1, false, Tier::Special } }, { Instruction::ORIGIN, { "ORIGIN", 0, 0, 1, false, Tier::Base } }, { Instruction::CALLER, { "CALLER", 0, 0, 1, false, Tier::Base } }, { Instruction::CALLVALUE, { "CALLVALUE", 0, 0, 1, false, Tier::Base } }, @@ -221,12 +221,12 @@ static std::map const c_instructionInfo = { Instruction::CODESIZE, { "CODESIZE", 0, 0, 1, false, Tier::Base } }, { Instruction::CODECOPY, { "CODECOPY", 0, 3, 0, true, Tier::VeryLow } }, { Instruction::GASPRICE, { "GASPRICE", 0, 0, 1, false, Tier::Base } }, - { Instruction::EXTCODESIZE, { "EXTCODESIZE", 0, 1, 1, false, Tier::ExtCode } }, - { Instruction::EXTCODECOPY, { "EXTCODECOPY", 0, 4, 0, true, Tier::ExtCode } }, - { Instruction::RETURNDATASIZE, {"RETURNDATASIZE", 0, 0, 1, false, Tier::Base } }, - { Instruction::RETURNDATACOPY, {"RETURNDATACOPY", 0, 3, 0, true, Tier::VeryLow } }, + { Instruction::EXTCODESIZE, { "EXTCODESIZE", 0, 1, 1, false, Tier::Special } }, + { Instruction::EXTCODECOPY, { "EXTCODECOPY", 0, 4, 0, true, Tier::Special } }, + { Instruction::RETURNDATASIZE, {"RETURNDATASIZE", 0, 0, 1, false, Tier::Base } }, + { Instruction::RETURNDATACOPY, {"RETURNDATACOPY", 0, 3, 0, true, Tier::VeryLow } }, { Instruction::MCOPY, { "MCOPY", 0, 3, 0, true, Tier::VeryLow } }, - { Instruction::EXTCODEHASH, { "EXTCODEHASH", 0, 1, 1, false, Tier::Balance } }, + { Instruction::EXTCODEHASH, { "EXTCODEHASH", 0, 1, 1, false, Tier::Special } }, { Instruction::BLOCKHASH, { "BLOCKHASH", 0, 1, 1, false, Tier::Ext } }, { Instruction::BLOBHASH, { "BLOBHASH", 0, 1, 1, false, Tier::VeryLow } }, { Instruction::COINBASE, { "COINBASE", 0, 0, 1, false, Tier::Base } }, diff --git a/libevmasm/Instruction.h b/libevmasm/Instruction.h index 1733863aa5a2..d29a6feca73c 100644 --- a/libevmasm/Instruction.h +++ b/libevmasm/Instruction.h @@ -297,8 +297,6 @@ enum class Tier High, // 10, Slow Ext, // 20, Ext WarmAccess, // 100, Warm Access - ExtCode, // 700, Extcode - Balance, // 400, Balance Special, // multiparam or otherwise special Invalid // Invalid. }; diff --git a/solc/CommandLineInterface.cpp b/solc/CommandLineInterface.cpp index 7181bfd4cc7e..4c08efb51a00 100644 --- a/solc/CommandLineInterface.cpp +++ b/solc/CommandLineInterface.cpp @@ -43,9 +43,7 @@ #include -#include #include -#include #include #include From 686f5cd455c837d6a54f819c8cff66733e2ecc8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Tue, 9 Jan 2024 15:54:03 +0100 Subject: [PATCH 0030/1022] Document the Tier enum and constants that come from Execution Specs --- libevmasm/GasMeter.h | 56 +++++++++++++++++++++-------------------- libevmasm/Instruction.h | 25 ++++++++++-------- 2 files changed, 44 insertions(+), 37 deletions(-) diff --git a/libevmasm/GasMeter.h b/libevmasm/GasMeter.h index ec1946644787..e4bb19925796 100644 --- a/libevmasm/GasMeter.h +++ b/libevmasm/GasMeter.h @@ -43,32 +43,34 @@ class KnownState; namespace GasCosts { + /// NOTE: The GAS_... constants referenced by comments are defined for each EVM version in the Execution Specs: + /// https://ethereum.github.io/execution-specs/autoapi/ethereum//vm/gas/index.html + static unsigned const stackLimit = 1024; - static unsigned const tier0Gas = 0; - static unsigned const tier1Gas = 2; - static unsigned const tier2Gas = 3; - static unsigned const tier3Gas = 5; - static unsigned const tier4Gas = 8; - static unsigned const tier5Gas = 10; - static unsigned const tier6Gas = 20; - static unsigned const tier7Gas = 0; - static unsigned const expGas = 10; + static unsigned const tier0Gas = 0; // GAS_ZERO (in Execution Specs) + static unsigned const tier1Gas = 2; // GAS_BASE + static unsigned const tier2Gas = 3; // GAS_VERY_LOW + static unsigned const tier3Gas = 5; // GAS_LOW / GAS_FAST_STEP + static unsigned const tier4Gas = 8; // GAS_MID + static unsigned const tier5Gas = 10; // GAS_HIGH + static unsigned const tier6Gas = 20; // GAS_BLOCK_HASH + static unsigned const expGas = 10; // GAS_EXPONENTIATION inline unsigned expByteGas(langutil::EVMVersion _evmVersion) { - return _evmVersion >= langutil::EVMVersion::spuriousDragon() ? 50 : 10; + return _evmVersion >= langutil::EVMVersion::spuriousDragon() ? 50 : 10; // GAS_EXPONENTIATION_PER_BYTE } - static unsigned const keccak256Gas = 30; - static unsigned const keccak256WordGas = 6; + static unsigned const keccak256Gas = 30; // GAS_KECCAK256 + static unsigned const keccak256WordGas = 6; // GAS_KECCAK256_WORD /// Corresponds to ACCESS_LIST_ADDRESS_COST from EIP-2930 static unsigned const accessListAddressCost = 2400; /// Corresponds to ACCESS_LIST_STORAGE_COST from EIP-2930 static unsigned const accessListStorageKeyCost = 1900; /// Corresponds to COLD_SLOAD_COST from EIP-2929 - static unsigned const coldSloadCost = 2100; + static unsigned const coldSloadCost = 2100; // GAS_COLD_SLOAD /// Corresponds to COLD_ACCOUNT_ACCESS_COST from EIP-2929 - static unsigned const coldAccountAccessCost = 2600; + static unsigned const coldAccountAccessCost = 2600; // GAS_COLD_ACCOUNT_ACCESS /// Corresponds to WARM_STORAGE_READ_COST from EIP-2929 - static unsigned const warmStorageReadCost = 100; + static unsigned const warmStorageReadCost = 100; // GAS_WARM_ACCESS inline unsigned sloadGas(langutil::EVMVersion _evmVersion) { if (_evmVersion >= langutil::EVMVersion::berlin()) @@ -81,7 +83,7 @@ namespace GasCosts return 50; } /// Corresponds to SSTORE_SET_GAS - static unsigned const sstoreSetGas = 20000; + static unsigned const sstoreSetGas = 20000; // GAS_STORAGE_SET /// Corresponds to SSTORE_RESET_GAS from EIP-2929 static unsigned const sstoreResetGas = 5000 - coldSloadCost; /// Corresponds to SSTORE_CLEARS_SCHEDULE from EIP-2200 @@ -130,11 +132,11 @@ namespace GasCosts else return 20; } - static unsigned const jumpdestGas = 1; - static unsigned const logGas = 375; - static unsigned const logDataGas = 8; - static unsigned const logTopicGas = 375; - static unsigned const createGas = 32000; + static unsigned const jumpdestGas = 1; // GAS_JUMPDEST + static unsigned const logGas = 375; // GAS_LOG + static unsigned const logDataGas = 8; // GAS_LOG_DATA + static unsigned const logTopicGas = 375; // GAS_LOG_TOPIC + static unsigned const createGas = 32000; // GAS_CREATE inline unsigned callGas(langutil::EVMVersion _evmVersion) { if (_evmVersion >= langutil::EVMVersion::berlin()) @@ -144,10 +146,10 @@ namespace GasCosts else return 40; } - static unsigned const callStipend = 2300; - static unsigned const callValueTransferGas = 9000; - static unsigned const callNewAccountGas = 25000; - inline unsigned selfdestructGas(langutil::EVMVersion _evmVersion) + static unsigned const callStipend = 2300; // GAS_CALL_STIPEND + static unsigned const callValueTransferGas = 9000; // GAS_CALL_VALUE + static unsigned const callNewAccountGas = 25000; // GAS_NEW_ACCOUNT / GAS_SELF_DESTRUCT_NEW_ACCOUNT + inline unsigned selfdestructGas(langutil::EVMVersion _evmVersion) // GAS_SELF_DESTRUCT { if (_evmVersion >= langutil::EVMVersion::berlin()) return coldAccountAccessCost; @@ -164,9 +166,9 @@ namespace GasCosts else return 24000; } - static unsigned const memoryGas = 3; + static unsigned const memoryGas = 3; // GAS_MEMORY / GAS_COPY / GAS_RETURN_DATA_COPY static unsigned const quadCoeffDiv = 512; - static unsigned const createDataGas = 200; + static unsigned const createDataGas = 200; // GAS_CODE_DEPOSIT static unsigned const txGas = 21000; static unsigned const txCreateGas = 53000; static unsigned const txDataZeroGas = 4; diff --git a/libevmasm/Instruction.h b/libevmasm/Instruction.h index d29a6feca73c..7d551f71d72f 100644 --- a/libevmasm/Instruction.h +++ b/libevmasm/Instruction.h @@ -287,18 +287,23 @@ inline Instruction logInstruction(unsigned _number) return Instruction(unsigned(Instruction::LOG0) + _number); } +/// Gas price tiers representing static cost of an instruction. +/// Opcodes whose cost is dynamic or depends on EVM version should use the `Special` tier and need +/// dedicated logic in GasMeter (especially in estimateMax()). +/// The tiers loosely follow opcode groups originally defined in the Yellow Paper. enum class Tier { - Zero = 0, // 0, Zero - Base, // 2, Quick - VeryLow, // 3, Fastest - Low, // 5, Fast - Mid, // 8, Mid - High, // 10, Slow - Ext, // 20, Ext - WarmAccess, // 100, Warm Access - Special, // multiparam or otherwise special - Invalid // Invalid. + // NOTE: Tiers should be ordered by cost, since we sometimes perform comparisons between them. + Zero = 0, // 0, Zero + Base, // 2, Quick + VeryLow, // 3, Fastest + Low, // 5, Fast + Mid, // 8, Mid + High, // 10, Slow + Ext, // 20, Ext + WarmAccess, // 100, Warm Access + Special, // multiparam or otherwise special + Invalid, // Invalid. }; /// Information structure for a particular instruction. From a973b4c6bffbd25497fb6b06fa1935ce4b63cbcd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Tue, 9 Jan 2024 17:13:42 +0100 Subject: [PATCH 0031/1022] Rename Ext gas cost tier to BlockHash --- libevmasm/GasMeter.cpp | 2 +- libevmasm/Instruction.cpp | 2 +- libevmasm/Instruction.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/libevmasm/GasMeter.cpp b/libevmasm/GasMeter.cpp index e237e32a26ba..b3d160585e37 100644 --- a/libevmasm/GasMeter.cpp +++ b/libevmasm/GasMeter.cpp @@ -280,7 +280,7 @@ unsigned GasMeter::runGas(Instruction _instruction, langutil::EVMVersion _evmVer case Tier::Low: return GasCosts::tier3Gas; case Tier::Mid: return GasCosts::tier4Gas; case Tier::High: return GasCosts::tier5Gas; - case Tier::Ext: return GasCosts::tier6Gas; + case Tier::BlockHash: return GasCosts::tier6Gas; case Tier::WarmAccess: return GasCosts::warmStorageReadCost; case Tier::Special: diff --git a/libevmasm/Instruction.cpp b/libevmasm/Instruction.cpp index 4e0684b6b4eb..ca0dff185ad4 100644 --- a/libevmasm/Instruction.cpp +++ b/libevmasm/Instruction.cpp @@ -227,7 +227,7 @@ static std::map const c_instructionInfo = { Instruction::RETURNDATACOPY, {"RETURNDATACOPY", 0, 3, 0, true, Tier::VeryLow } }, { Instruction::MCOPY, { "MCOPY", 0, 3, 0, true, Tier::VeryLow } }, { Instruction::EXTCODEHASH, { "EXTCODEHASH", 0, 1, 1, false, Tier::Special } }, - { Instruction::BLOCKHASH, { "BLOCKHASH", 0, 1, 1, false, Tier::Ext } }, + { Instruction::BLOCKHASH, { "BLOCKHASH", 0, 1, 1, false, Tier::BlockHash } }, { Instruction::BLOBHASH, { "BLOBHASH", 0, 1, 1, false, Tier::VeryLow } }, { Instruction::COINBASE, { "COINBASE", 0, 0, 1, false, Tier::Base } }, { Instruction::TIMESTAMP, { "TIMESTAMP", 0, 0, 1, false, Tier::Base } }, diff --git a/libevmasm/Instruction.h b/libevmasm/Instruction.h index 7d551f71d72f..289469b5ef7b 100644 --- a/libevmasm/Instruction.h +++ b/libevmasm/Instruction.h @@ -300,7 +300,7 @@ enum class Tier Low, // 5, Fast Mid, // 8, Mid High, // 10, Slow - Ext, // 20, Ext + BlockHash, // 20 WarmAccess, // 100, Warm Access Special, // multiparam or otherwise special Invalid, // Invalid. From 88ee7d8bb57075c94df3d70fce115357f1290b0c Mon Sep 17 00:00:00 2001 From: Alexander Arlt Date: Mon, 19 Feb 2024 16:28:08 +0100 Subject: [PATCH 0032/1022] [ci] Remove code signature from universal binary. --- .circleci/config.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index b29c46bf8b9e..672b77c96d4b 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -242,6 +242,13 @@ commands: # -------------------------------------------------------------------------- # Artifact Commands + remove_signature_from_universal_binary: + description: Remove signature from universal binary + steps: + - run: + name: Remove signature from universal binary + command: codesign --remove-signature build/solc/solc + store_artifacts_solc: description: Store compiled solc executable as artifact steps: @@ -1156,6 +1163,7 @@ jobs: - checkout - install_dependencies_osx - run_build + - remove_signature_from_universal_binary - store_artifacts_solc - store_artifacts_yul_phaser - persist_executables_to_workspace_osx From ac54fe1972f25227f9932c8b224ef119360b0e2d Mon Sep 17 00:00:00 2001 From: Nikola Matic Date: Thu, 11 Jan 2024 13:58:23 +0100 Subject: [PATCH 0033/1022] Purge using namespace std from test --- scripts/check_style.sh | 1 + test/Common.cpp | 34 +++++++------- test/CommonSyntaxTest.cpp | 69 ++++++++++++++-------------- test/EVMHost.cpp | 55 +++++++++++------------ test/ExecutionFramework.cpp | 45 +++++++++---------- test/FilesystemUtils.cpp | 17 ++++--- test/Metadata.cpp | 24 +++++----- test/TestCase.cpp | 35 +++++++-------- test/TestCaseReader.cpp | 89 ++++++++++++++++++------------------- test/soltest.cpp | 21 +++++---- 10 files changed, 192 insertions(+), 198 deletions(-) diff --git a/scripts/check_style.sh b/scripts/check_style.sh index fe4d19734fc1..3c9acf86ca74 100755 --- a/scripts/check_style.sh +++ b/scripts/check_style.sh @@ -39,6 +39,7 @@ NAMESPACE_STD_FREE_FILES=( libyul/backends/evm/* libyul/optimiser/* solc/* + test/* test/contracts/* test/libevmasm/* test/liblangutil/* diff --git a/test/Common.cpp b/test/Common.cpp index bb4d2db7ebce..ae725774c48a 100644 --- a/test/Common.cpp +++ b/test/Common.cpp @@ -32,8 +32,6 @@ namespace fs = boost::filesystem; namespace po = boost::program_options; -using namespace std; - namespace solidity::test { @@ -147,15 +145,15 @@ void CommonOptions::validate() const ); if (!enforceGasTest) - cout << endl << "WARNING :: Gas cost expectations are not being enforced" << endl << endl; + std::cout << std::endl << "WARNING :: Gas cost expectations are not being enforced" << std::endl << std::endl; else if (evmVersion() != langutil::EVMVersion{} || useABIEncoderV1) { - cout << endl << "WARNING :: Enforcing gas cost expectations with non-standard settings:" << endl; + std::cout << std::endl << "WARNING :: Enforcing gas cost expectations with non-standard settings:" << std::endl; if (evmVersion() != langutil::EVMVersion{}) - cout << "- EVM version: " << evmVersion().name() << " (default: " << langutil::EVMVersion{}.name() << ")" << endl; + std::cout << "- EVM version: " << evmVersion().name() << " (default: " << langutil::EVMVersion{}.name() << ")" << std::endl; if (useABIEncoderV1) - cout << "- ABI coder: v1 (default: v2)" << endl; - cout << endl << "DO NOT COMMIT THE UPDATED EXPECTATIONS." << endl << endl; + std::cout << "- ABI coder: v1 (default: v2)" << std::endl; + std::cout << std::endl << "DO NOT COMMIT THE UPDATED EXPECTATIONS." << std::endl << std::endl; } } @@ -176,7 +174,7 @@ bool CommonOptions::parse(int argc, char const* const* argv) // Request as uint64_t, since uint8_t will be parsed as character by boost. uint64_t eofVersion = arguments["eof-version"].as(); if (eofVersion != 1) - BOOST_THROW_EXCEPTION(std::runtime_error("Invalid EOF version: " + to_string(eofVersion))); + BOOST_THROW_EXCEPTION(std::runtime_error("Invalid EOF version: " + std::to_string(eofVersion))); m_eofVersion = 1; } @@ -213,18 +211,18 @@ bool CommonOptions::parse(int argc, char const* const* argv) return true; } -string CommonOptions::toString(vector const& _selectedOptions) const +std::string CommonOptions::toString(std::vector const& _selectedOptions) const { if (_selectedOptions.empty()) return ""; - auto boolToString = [](bool _value) -> string { return _value ? "true" : "false"; }; + auto boolToString = [](bool _value) -> std::string { return _value ? "true" : "false"; }; // Using std::map to avoid if-else/switch-case block - map optionValueMap = { + std::map optionValueMap = { {"evmVersion", evmVersion().name()}, {"optimize", boolToString(optimize)}, {"useABIEncoderV1", boolToString(useABIEncoderV1)}, - {"batch", to_string(selectedBatch + 1) + "/" + to_string(batches)}, + {"batch", std::to_string(selectedBatch + 1) + "/" + std::to_string(batches)}, {"enforceGasTest", boolToString(enforceGasTest)}, {"enforceGasTestMinValue", enforceGasTestMinValue.str()}, {"disableSemanticTests", boolToString(disableSemanticTests)}, @@ -233,18 +231,18 @@ string CommonOptions::toString(vector const& _selectedOptions) const {"showMetadata", boolToString(showMetadata)} }; - soltestAssert(ranges::all_of(_selectedOptions, [&optionValueMap](string const& _option) { return optionValueMap.count(_option) > 0; })); + soltestAssert(ranges::all_of(_selectedOptions, [&optionValueMap](std::string const& _option) { return optionValueMap.count(_option) > 0; })); - vector optionsWithValues = _selectedOptions | - ranges::views::transform([&optionValueMap](string const& _option) { return _option + "=" + optionValueMap.at(_option); }) | - ranges::to(); + std::vector optionsWithValues = _selectedOptions | + ranges::views::transform([&optionValueMap](std::string const& _option) { return _option + "=" + optionValueMap.at(_option); }) | + ranges::to(); return solidity::util::joinHumanReadable(optionsWithValues); } -void CommonOptions::printSelectedOptions(ostream& _stream, string const& _linePrefix, vector const& _selectedOptions) const +void CommonOptions::printSelectedOptions(std::ostream& _stream, std::string const& _linePrefix, std::vector const& _selectedOptions) const { - _stream << _linePrefix << "Run Settings: " << toString(_selectedOptions) << endl; + _stream << _linePrefix << "Run Settings: " << toString(_selectedOptions) << std::endl; } langutil::EVMVersion CommonOptions::evmVersion() const diff --git a/test/CommonSyntaxTest.cpp b/test/CommonSyntaxTest.cpp index 0dedd1fb043b..3cb908118ea2 100644 --- a/test/CommonSyntaxTest.cpp +++ b/test/CommonSyntaxTest.cpp @@ -34,7 +34,6 @@ #include #include -using namespace std; using namespace solidity; using namespace solidity::util; using namespace solidity::util::formatting; @@ -48,10 +47,10 @@ namespace fs = boost::filesystem; namespace { -int parseUnsignedInteger(string::iterator& _it, string::iterator _end) +int parseUnsignedInteger(std::string::iterator& _it, std::string::iterator _end) { if (_it == _end || !util::isDigit(*_it)) - BOOST_THROW_EXCEPTION(runtime_error("Invalid test expectation. Source location expected.")); + BOOST_THROW_EXCEPTION(std::runtime_error("Invalid test expectation. Source location expected.")); int result = 0; while (_it != _end && util::isDigit(*_it)) { @@ -64,7 +63,7 @@ int parseUnsignedInteger(string::iterator& _it, string::iterator _end) } -CommonSyntaxTest::CommonSyntaxTest(string const& _filename, langutil::EVMVersion _evmVersion): +CommonSyntaxTest::CommonSyntaxTest(std::string const& _filename, langutil::EVMVersion _evmVersion): EVMVersionRestrictedTestCase(_filename), m_sources(m_reader.sources()), m_expectations(parseExpectations(m_reader.stream())), @@ -72,7 +71,7 @@ CommonSyntaxTest::CommonSyntaxTest(string const& _filename, langutil::EVMVersion { } -TestCase::TestResult CommonSyntaxTest::run(ostream& _stream, string const& _linePrefix, bool _formatted) +TestCase::TestResult CommonSyntaxTest::run(std::ostream& _stream, std::string const& _linePrefix, bool _formatted) { parseCustomExpectations(m_reader.stream()); parseAndAnalyze(); @@ -80,7 +79,7 @@ TestCase::TestResult CommonSyntaxTest::run(ostream& _stream, string const& _line return conclude(_stream, _linePrefix, _formatted); } -TestCase::TestResult CommonSyntaxTest::conclude(ostream& _stream, string const& _linePrefix, bool _formatted) +TestCase::TestResult CommonSyntaxTest::conclude(std::ostream& _stream, std::string const& _linePrefix, bool _formatted) { if (expectationsMatch()) return TestResult::Success; @@ -89,16 +88,16 @@ TestCase::TestResult CommonSyntaxTest::conclude(ostream& _stream, string const& return TestResult::Failure; } -void CommonSyntaxTest::printExpectationAndError(ostream& _stream, string const& _linePrefix, bool _formatted) +void CommonSyntaxTest::printExpectationAndError(std::ostream& _stream, std::string const& _linePrefix, bool _formatted) { - string nextIndentLevel = _linePrefix + " "; - util::AnsiColorized(_stream, _formatted, {BOLD, CYAN}) << _linePrefix << "Expected result:" << endl; + std::string nextIndentLevel = _linePrefix + " "; + util::AnsiColorized(_stream, _formatted, {BOLD, CYAN}) << _linePrefix << "Expected result:" << std::endl; printExpectedResult(_stream, nextIndentLevel, _formatted); - util::AnsiColorized(_stream, _formatted, {BOLD, CYAN}) << _linePrefix << "Obtained result:" << endl; + util::AnsiColorized(_stream, _formatted, {BOLD, CYAN}) << _linePrefix << "Obtained result:" << std::endl; printObtainedResult(_stream, nextIndentLevel, _formatted); } -void CommonSyntaxTest::printSource(ostream& _stream, string const& _linePrefix, bool _formatted) const +void CommonSyntaxTest::printSource(std::ostream& _stream, std::string const& _linePrefix, bool _formatted) const { if (m_sources.sources.empty()) return; @@ -113,8 +112,8 @@ void CommonSyntaxTest::printSource(ostream& _stream, string const& _linePrefix, continue; if (outputSourceNames) - _stream << _linePrefix << util::formatting::CYAN << "==== Source: " << name << " ====" << util::formatting::RESET << endl; - vector sourceFormatting(source.length(), util::formatting::RESET); + _stream << _linePrefix << util::formatting::CYAN << "==== Source: " << name << " ====" << util::formatting::RESET << std::endl; + std::vector sourceFormatting(source.length(), util::formatting::RESET); for (auto const& error: m_errorList) if (error.sourceName == name && error.locationStart >= 0 && error.locationEnd >= 0) { @@ -143,7 +142,7 @@ void CommonSyntaxTest::printSource(ostream& _stream, string const& _linePrefix, _stream << source[i]; else { - _stream << util::formatting::RESET << endl; + _stream << util::formatting::RESET << std::endl; if (i + 1 < source.length()) _stream << _linePrefix << sourceFormatting[i]; } @@ -158,9 +157,9 @@ void CommonSyntaxTest::printSource(ostream& _stream, string const& _linePrefix, } } -void CommonSyntaxTest::parseCustomExpectations(istream& _stream) +void CommonSyntaxTest::parseCustomExpectations(std::istream& _stream) { - string remainingExpectations = boost::trim_copy(readUntilEnd(_stream)); + std::string remainingExpectations = boost::trim_copy(readUntilEnd(_stream)); soltestAssert( remainingExpectations.empty(), "Found custom expectations not supported by the test case:\n" + remainingExpectations @@ -172,27 +171,27 @@ bool CommonSyntaxTest::expectationsMatch() return m_expectations == m_errorList; } -void CommonSyntaxTest::printExpectedResult(ostream& _stream, string const& _linePrefix, bool _formatted) const +void CommonSyntaxTest::printExpectedResult(std::ostream& _stream, std::string const& _linePrefix, bool _formatted) const { printErrorList(_stream, m_expectations, _linePrefix, _formatted); } -void CommonSyntaxTest::printObtainedResult(ostream& _stream, string const& _linePrefix, bool _formatted) const +void CommonSyntaxTest::printObtainedResult(std::ostream& _stream, std::string const& _linePrefix, bool _formatted) const { printErrorList(_stream, m_errorList, _linePrefix, _formatted); } void CommonSyntaxTest::printErrorList( - ostream& _stream, - vector const& _errorList, - string const& _linePrefix, + std::ostream& _stream, + std::vector const& _errorList, + std::string const& _linePrefix, bool _formatted ) { if (_errorList.empty()) { if (_formatted) - util::AnsiColorized(_stream, _formatted, {BOLD, GREEN}) << _linePrefix << "Success" << endl; + util::AnsiColorized(_stream, _formatted, {BOLD, GREEN}) << _linePrefix << "Success" << std::endl; } else for (auto const& error: _errorList) @@ -220,11 +219,11 @@ void CommonSyntaxTest::printErrorList( _stream << error.locationEnd; _stream << "): "; } - _stream << error.message << endl; + _stream << error.message << std::endl; } } -string CommonSyntaxTest::errorMessage(util::Exception const& _e) +std::string CommonSyntaxTest::errorMessage(util::Exception const& _e) { if (_e.comment() && !_e.comment()->empty()) return boost::replace_all_copy(*_e.comment(), "\n", "\\n"); @@ -232,13 +231,13 @@ string CommonSyntaxTest::errorMessage(util::Exception const& _e) return "NONE"; } -vector CommonSyntaxTest::parseExpectations(istream& _stream) +std::vector CommonSyntaxTest::parseExpectations(std::istream& _stream) { - static string const customExpectationsDelimiter("// ----"); + static std::string const customExpectationsDelimiter("// ----"); - vector expectations; - string line; - while (getline(_stream, line)) + std::vector expectations; + std::string line; + while (std::getline(_stream, line)) { auto it = line.begin(); @@ -254,17 +253,17 @@ vector CommonSyntaxTest::parseExpectations(istream& _stream) if (it == line.end()) continue; auto typeBegin = it; - while (it != line.end() && isalpha(*it, locale::classic())) + while (it != line.end() && isalpha(*it, std::locale::classic())) ++it; - string errorTypeStr(typeBegin, it); - optional errorType = Error::parseErrorType(errorTypeStr); + std::string errorTypeStr(typeBegin, it); + std::optional errorType = Error::parseErrorType(errorTypeStr); if (!errorType.has_value()) - BOOST_THROW_EXCEPTION(runtime_error("Invalid error type: " + errorTypeStr)); + BOOST_THROW_EXCEPTION(std::runtime_error("Invalid error type: " + errorTypeStr)); skipWhitespace(it, line.end()); - optional errorId; + std::optional errorId; if (it != line.end() && util::isDigit(*it)) errorId = ErrorId{static_cast(parseUnsignedInteger(it, line.end()))}; @@ -295,7 +294,7 @@ vector CommonSyntaxTest::parseExpectations(istream& _stream) skipWhitespace(it, line.end()); - string errorMessage(it, line.end()); + std::string errorMessage(it, line.end()); expectations.emplace_back(SyntaxTestError{ errorType.value(), std::move(errorId), diff --git a/test/EVMHost.cpp b/test/EVMHost.cpp index 7e05ceec3ecb..9af4d7099dd2 100644 --- a/test/EVMHost.cpp +++ b/test/EVMHost.cpp @@ -31,16 +31,15 @@ #include #include -using namespace std; using namespace solidity; using namespace solidity::util; using namespace solidity::test; using namespace evmc::literals; -evmc::VM& EVMHost::getVM(string const& _path) +evmc::VM& EVMHost::getVM(std::string const& _path) { static evmc::VM NullVM{nullptr}; - static map> vms; + static std::map> vms; if (vms.count(_path) == 0) { evmc_loader_error_code errorCode = {}; @@ -48,16 +47,16 @@ evmc::VM& EVMHost::getVM(string const& _path) if (vm && errorCode == EVMC_LOADER_SUCCESS) { if (vm.get_capabilities() & (EVMC_CAPABILITY_EVM1)) - vms[_path] = make_unique(evmc::VM(std::move(vm))); + vms[_path] = std::make_unique(evmc::VM(std::move(vm))); else - cerr << "VM loaded does not support EVM1" << endl; + std::cerr << "VM loaded does not support EVM1" << std::endl; } else { - cerr << "Error loading VM from " << _path; + std::cerr << "Error loading VM from " << _path; if (char const* errorMsg = evmc_last_error_msg()) - cerr << ":" << endl << errorMsg; - cerr << endl; + std::cerr << ":" << std::endl << errorMsg; + std::cerr << std::endl; } } @@ -67,7 +66,7 @@ evmc::VM& EVMHost::getVM(string const& _path) return NullVM; } -bool EVMHost::checkVmPaths(vector const& _vmPaths) +bool EVMHost::checkVmPaths(std::vector const& _vmPaths) { bool evmVmFound = false; for (auto const& path: _vmPaths) @@ -79,7 +78,7 @@ bool EVMHost::checkVmPaths(vector const& _vmPaths) if (vm.has_capability(EVMC_CAPABILITY_EVM1)) { if (evmVmFound) - BOOST_THROW_EXCEPTION(runtime_error("Multiple evm1 evmc vms defined. Please only define one evm1 evmc vm.")); + BOOST_THROW_EXCEPTION(std::runtime_error("Multiple evm1 evmc vms defined. Please only define one evm1 evmc vm.")); evmVmFound = true; } } @@ -92,7 +91,7 @@ EVMHost::EVMHost(langutil::EVMVersion _evmVersion, evmc::VM& _vm): { if (!m_vm) { - cerr << "Unable to find evmone library" << endl; + std::cerr << "Unable to find evmone library" << std::endl; assertThrow(false, Exception, ""); } @@ -319,7 +318,7 @@ evmc::Result EVMHost::call(evmc_message const& _message) noexcept h160 createAddress(keccak256( bytes{static_cast(0xc0 + 21 + encodedNonce.size())} + bytes{0x94} + - bytes(begin(message.sender.bytes), end(message.sender.bytes)) + + bytes(std::begin(message.sender.bytes), std::end(message.sender.bytes)) + encodedNonce ), h160::AlignRight); @@ -332,8 +331,8 @@ evmc::Result EVMHost::call(evmc_message const& _message) noexcept { h160 createAddress(keccak256( bytes{0xff} + - bytes(begin(message.sender.bytes), end(message.sender.bytes)) + - bytes(begin(message.create2_salt.bytes), end(message.create2_salt.bytes)) + + bytes(std::begin(message.sender.bytes), std::end(message.sender.bytes)) + + bytes(std::begin(message.create2_salt.bytes), std::end(message.create2_salt.bytes)) + keccak256(bytes(message.input_data, message.input_data + message.input_size)).asBytes() ), h160::AlignRight); @@ -421,7 +420,7 @@ evmc::bytes32 EVMHost::get_block_hash(int64_t _number) const noexcept h160 EVMHost::convertFromEVMC(evmc::address const& _addr) { - return h160(bytes(begin(_addr.bytes), end(_addr.bytes))); + return h160(bytes(std::begin(_addr.bytes), std::end(_addr.bytes))); } evmc::address EVMHost::convertToEVMC(h160 const& _addr) @@ -434,7 +433,7 @@ evmc::address EVMHost::convertToEVMC(h160 const& _addr) h256 EVMHost::convertFromEVMC(evmc::bytes32 const& _data) { - return h256(bytes(begin(_data.bytes), end(_data.bytes))); + return h256(bytes(std::begin(_data.bytes), std::end(_data.bytes))); } evmc::bytes32 EVMHost::convertToEVMC(h256 const& _data) @@ -452,7 +451,7 @@ evmc::Result EVMHost::precompileECRecover(evmc_message const& _message) noexcept // Fixed cost of 3000 gas. constexpr int64_t gas_cost = 3000; - static map const inputOutput{ + static std::map const inputOutput{ { fromHex( "18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c" @@ -509,7 +508,7 @@ evmc::Result EVMHost::precompileRipeMD160(evmc_message const& _message) noexcept return 600 + 120 * ((size + 31) / 32); }; - static map const inputOutput{ + static std::map const inputOutput{ { bytes{}, { @@ -628,7 +627,7 @@ evmc::Result EVMHost::precompileALTBN128G1Add(evmc_message const& _message) noex // Fixed 500 or 150 gas. int64_t gas_cost = (Revision < EVMC_ISTANBUL) ? 500 : 150; - static map const inputOutput{ + static std::map const inputOutput{ { fromHex( "0000000000000000000000000000000000000000000000000000000000000000" @@ -896,7 +895,7 @@ evmc::Result EVMHost::precompileALTBN128G1Mul(evmc_message const& _message) noex // Fixed 40000 or 6000 gas. int64_t gas_cost = (Revision < EVMC_ISTANBUL) ? 40000 : 6000; - static map const inputOutput{ + static std::map const inputOutput{ { fromHex("0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000"), { @@ -990,7 +989,7 @@ evmc::Result EVMHost::precompileALTBN128PairingProduct(evmc_message const& _mess }; // NOTE this is a partial implementation for some inputs. - static map const inputOutput{ + static std::map const inputOutput{ { fromHex( "17c139df0efee0f766bc0204762b774362e4ded88953a39ce849a8a7fa163fa9" @@ -1155,7 +1154,7 @@ evmc::Result EVMHost::precompileBlake2f(evmc_message const&) noexcept evmc::Result EVMHost::precompileGeneric( evmc_message const& _message, - map const& _inOut) noexcept + std::map const& _inOut) noexcept { bytes input(_message.input_data, _message.input_data + _message.input_size); if (_inOut.count(input)) @@ -1202,7 +1201,7 @@ StorageMap const& EVMHost::get_address_storage(evmc::address const& _addr) return accounts[_addr].storage; } -string EVMHostPrinter::state() +std::string EVMHostPrinter::state() { // Print state and execution trace. if (m_host.account_exists(m_account)) @@ -1225,14 +1224,14 @@ void EVMHostPrinter::storage() << m_host.convertFromEVMC(slot) << ": " << m_host.convertFromEVMC(value.current) - << endl; + << std::endl; } void EVMHostPrinter::balance() { m_stateStream << "BALANCE " << m_host.convertFromEVMC(m_host.get_balance(m_account)) - << endl; + << std::endl; } void EVMHostPrinter::selfdestructRecords() @@ -1242,12 +1241,12 @@ void EVMHostPrinter::selfdestructRecords() m_stateStream << "SELFDESTRUCT" << " BENEFICIARY " << m_host.convertFromEVMC(beneficiary) - << endl; + << std::endl; } void EVMHostPrinter::callRecords() { - static auto constexpr callKind = [](evmc_call_kind _kind) -> string + static auto constexpr callKind = [](evmc_call_kind _kind) -> std::string { switch (_kind) { @@ -1270,5 +1269,5 @@ void EVMHostPrinter::callRecords() m_stateStream << callKind(record.kind) << " VALUE " << m_host.convertFromEVMC(record.value) - << endl; + << std::endl; } diff --git a/test/ExecutionFramework.cpp b/test/ExecutionFramework.cpp index a18a73de06b8..9fc36440b336 100644 --- a/test/ExecutionFramework.cpp +++ b/test/ExecutionFramework.cpp @@ -41,7 +41,6 @@ #include #include -using namespace std; using namespace solidity; using namespace solidity::util; using namespace solidity::test; @@ -52,7 +51,7 @@ ExecutionFramework::ExecutionFramework(): { } -ExecutionFramework::ExecutionFramework(langutil::EVMVersion _evmVersion, vector const& _vmPaths): +ExecutionFramework::ExecutionFramework(langutil::EVMVersion _evmVersion, std::vector const& _vmPaths): m_evmVersion(_evmVersion), m_optimiserSettings(solidity::frontend::OptimiserSettings::minimal()), m_showMessages(solidity::test::CommonOptions::get().showMessages), @@ -71,7 +70,7 @@ void ExecutionFramework::selectVM(evmc_capabilities _cap) evmc::VM& vm = EVMHost::getVM(path.string()); if (vm.has_capability(_cap)) { - m_evmcHost = make_unique(m_evmVersion, vm); + m_evmcHost = std::make_unique(m_evmVersion, vm); break; } } @@ -87,7 +86,7 @@ void ExecutionFramework::reset() EVMHost::convertToEVMC(u256(1) << 100); } -std::pair ExecutionFramework::compareAndCreateMessage( +std::pair ExecutionFramework::compareAndCreateMessage( bytes const& _result, bytes const& _expectation ) @@ -101,8 +100,8 @@ std::pair ExecutionFramework::compareAndCreateMessage( auto expectedHex = boost::replace_all_copy(util::toHex(_expectation), "0", "."); for (size_t i = 0; i < std::max(resultHex.size(), expectedHex.size()); i += 0x40) { - std::string result{i >= resultHex.size() ? string{} : resultHex.substr(i, 0x40)}; - std::string expected{i > expectedHex.size() ? string{} : expectedHex.substr(i, 0x40)}; + std::string result{i >= resultHex.size() ? std::string{} : resultHex.substr(i, 0x40)}; + std::string expected{i > expectedHex.size() ? std::string{} : expectedHex.substr(i, 0x40)}; message += (result == expected ? " " : " X ") + result + @@ -137,7 +136,7 @@ u256 ExecutionFramework::gasPrice() const u256 ExecutionFramework::blockHash(u256 const& _number) const { return u256{EVMHost::convertFromEVMC( - m_evmcHost->get_block_hash(static_cast(_number & numeric_limits::max())) + m_evmcHost->get_block_hash(static_cast(_number & std::numeric_limits::max())) )}; } @@ -153,12 +152,12 @@ void ExecutionFramework::sendMessage(bytes const& _data, bool _isCreation, u256 if (m_showMessages) { if (_isCreation) - cout << "CREATE " << m_sender.hex() << ":" << endl; + std::cout << "CREATE " << m_sender.hex() << ":" << std::endl; else - cout << "CALL " << m_sender.hex() << " -> " << m_contractAddress.hex() << ":" << endl; + std::cout << "CALL " << m_sender.hex() << " -> " << m_contractAddress.hex() << ":" << std::endl; if (_value > 0) - cout << " value: " << _value << endl; - cout << " in: " << util::toHex(_data) << endl; + std::cout << " value: " << _value << std::endl; + std::cout << " in: " << util::toHex(_data) << std::endl; } evmc_message message{}; message.input_data = _data.data(); @@ -189,19 +188,19 @@ void ExecutionFramework::sendMessage(bytes const& _data, bool _isCreation, u256 unsigned const refundRatio = (m_evmVersion >= langutil::EVMVersion::london() ? 5 : 2); auto const totalGasUsed = InitialGas - result.gas_left; - auto const gasRefund = min(u256(result.gas_refund), totalGasUsed / refundRatio); + auto const gasRefund = std::min(u256(result.gas_refund), totalGasUsed / refundRatio); m_gasUsed = totalGasUsed - gasRefund; m_transactionSuccessful = (result.status_code == EVMC_SUCCESS); if (m_showMessages) { - cout << " out: " << util::toHex(m_output) << endl; - cout << " result: " << static_cast(result.status_code) << endl; - cout << " gas used: " << m_gasUsed.str() << endl; - cout << " gas used (without refund): " << totalGasUsed.str() << endl; - cout << " gas refund (total): " << result.gas_refund << endl; - cout << " gas refund (bound): " << gasRefund.str() << endl; + std::cout << " out: " << util::toHex(m_output) << std::endl; + std::cout << " result: " << static_cast(result.status_code) << std::endl; + std::cout << " gas used: " << m_gasUsed.str() << std::endl; + std::cout << " gas used (without refund): " << totalGasUsed.str() << std::endl; + std::cout << " gas refund (total): " << result.gas_refund << std::endl; + std::cout << " gas refund (bound): " << gasRefund.str() << std::endl; } } @@ -211,9 +210,9 @@ void ExecutionFramework::sendEther(h160 const& _addr, u256 const& _amount) if (m_showMessages) { - cout << "SEND_ETHER " << m_sender.hex() << " -> " << _addr.hex() << ":" << endl; + std::cout << "SEND_ETHER " << m_sender.hex() << " -> " << _addr.hex() << ":" << std::endl; if (_amount > 0) - cout << " value: " << _amount << endl; + std::cout << " value: " << _amount << std::endl; } evmc_message message{}; message.sender = EVMHost::convertToEVMC(m_sender); @@ -294,14 +293,14 @@ bool ExecutionFramework::storageEmpty(h160 const& _addr) const return true; } -vector ExecutionFramework::recordedLogs() const +std::vector ExecutionFramework::recordedLogs() const { - vector logs; + std::vector logs; for (evmc::MockedHost::log_record const& logRecord: m_evmcHost->recorded_logs) logs.emplace_back( EVMHost::convertFromEVMC(logRecord.creator), bytes{logRecord.data.begin(), logRecord.data.end()}, - logRecord.topics | ranges::views::transform([](evmc::bytes32 _bytes) { return EVMHost::convertFromEVMC(_bytes); }) | ranges::to + logRecord.topics | ranges::views::transform([](evmc::bytes32 _bytes) { return EVMHost::convertFromEVMC(_bytes); }) | ranges::to ); return logs; } diff --git a/test/FilesystemUtils.cpp b/test/FilesystemUtils.cpp index 7506d677ecfb..2d917485d631 100644 --- a/test/FilesystemUtils.cpp +++ b/test/FilesystemUtils.cpp @@ -22,11 +22,10 @@ #include -using namespace std; using namespace solidity; using namespace solidity::test; -void solidity::test::createFilesWithParentDirs(set const& _paths, string const& _content) +void solidity::test::createFilesWithParentDirs(std::set const& _paths, std::string const& _content) { for (boost::filesystem::path const& path: _paths) { @@ -34,23 +33,23 @@ void solidity::test::createFilesWithParentDirs(set cons boost::filesystem::create_directories(path.parent_path()); // Use binary mode to avoid line ending conversion on Windows. - ofstream newFile(path.string(), std::ofstream::binary); + std::ofstream newFile(path.string(), std::ofstream::binary); newFile << _content; if (newFile.fail() || !boost::filesystem::exists(path)) - BOOST_THROW_EXCEPTION(runtime_error("Failed to create an empty file: \"" + path.string() + "\".")); + BOOST_THROW_EXCEPTION(std::runtime_error("Failed to create an empty file: \"" + path.string() + "\".")); } } -void solidity::test::createFileWithContent(boost::filesystem::path const& _path, string const& _content) +void solidity::test::createFileWithContent(boost::filesystem::path const& _path, std::string const& _content) { if (boost::filesystem::is_regular_file(_path)) - BOOST_THROW_EXCEPTION(runtime_error("File already exists: \"" + _path.string() + "\".")); \ + BOOST_THROW_EXCEPTION(std::runtime_error("File already exists: \"" + _path.string() + "\".")); \ // Use binary mode to avoid line ending conversion on Windows. - ofstream newFile(_path.string(), std::ofstream::binary); + std::ofstream newFile(_path.string(), std::ofstream::binary); if (newFile.fail() || !boost::filesystem::is_regular_file(_path)) - BOOST_THROW_EXCEPTION(runtime_error("Failed to create a file: \"" + _path.string() + "\".")); \ + BOOST_THROW_EXCEPTION(std::runtime_error("Failed to create a file: \"" + _path.string() + "\".")); \ newFile << _content; } @@ -80,7 +79,7 @@ bool solidity::test::createSymlinkIfSupportedByFilesystem( ) return false; else - BOOST_THROW_EXCEPTION(runtime_error( + BOOST_THROW_EXCEPTION(std::runtime_error( "Failed to create a symbolic link: \"" + _linkName.string() + "\"" " -> " + _targetPath.string() + "\"." " " + symlinkCreationError.message() + "." diff --git a/test/Metadata.cpp b/test/Metadata.cpp index 88a1f7b42f08..2fea65c65be0 100644 --- a/test/Metadata.cpp +++ b/test/Metadata.cpp @@ -26,8 +26,6 @@ #include #include -using namespace std; - namespace solidity::test { @@ -54,7 +52,7 @@ bytes bytecodeSansMetadata(bytes const& _bytecode) return bytes(_bytecode.begin(), _bytecode.end() - static_cast(metadataSize) - 2); } -string bytecodeSansMetadata(string const& _bytecode) +std::string bytecodeSansMetadata(std::string const& _bytecode) { return util::toHex(bytecodeSansMetadata(fromHex(_bytecode, util::WhenError::Throw))); } @@ -73,11 +71,11 @@ class TinyCBORParser assertThrow(nextType() == MajorType::Map, CBORException, "Fixed-length map expected."); return readLength(); } - string readKey() + std::string readKey() { return readString(); } - string readValue() + std::string readValue() { switch(nextType()) { @@ -132,7 +130,7 @@ class TinyCBORParser if (length == 24) return m_metadata.at(m_pos++); // Unsupported length kind. (Only by this parser.) - assertThrow(false, CBORException, string("Unsupported length ") + to_string(length)); + assertThrow(false, CBORException, std::string("Unsupported length ") + std::to_string(length)); } bytes readBytes(unsigned length) { @@ -140,28 +138,28 @@ class TinyCBORParser m_pos += length; return ret; } - string readString() + std::string readString() { // Expect a text string. assertThrow(nextType() == MajorType::TextString, CBORException, "String expected."); bytes tmp{readBytes(readLength())}; - return string{tmp.begin(), tmp.end()}; + return std::string{tmp.begin(), tmp.end()}; } unsigned m_pos; bytes const& m_metadata; }; -std::optional> parseCBORMetadata(bytes const& _metadata) +std::optional> parseCBORMetadata(bytes const& _metadata) { try { TinyCBORParser parser(_metadata); - map ret; + std::map ret; unsigned count = parser.mapItemCount(); for (unsigned i = 0; i < count; i++) { - string key = parser.readKey(); - string value = parser.readValue(); + std::string key = parser.readKey(); + std::string value = parser.readValue(); ret[std::move(key)] = std::move(value); } return ret; @@ -172,7 +170,7 @@ std::optional> parseCBORMetadata(bytes const& _metadata) } } -bool isValidMetadata(string const& _serialisedMetadata) +bool isValidMetadata(std::string const& _serialisedMetadata) { Json::Value metadata; if (!util::jsonParseStrict(_serialisedMetadata, metadata)) diff --git a/test/TestCase.cpp b/test/TestCase.cpp index 51608bd4a374..ae89bb56f31a 100644 --- a/test/TestCase.cpp +++ b/test/TestCase.cpp @@ -27,21 +27,20 @@ #include #include -using namespace std; using namespace solidity; using namespace solidity::frontend; using namespace solidity::frontend::test; using namespace solidity::util; -void TestCase::printSettings(ostream& _stream, const string& _linePrefix, const bool) +void TestCase::printSettings(std::ostream& _stream, const std::string& _linePrefix, const bool) { auto& settings = m_reader.settings(); if (settings.empty()) return; - _stream << _linePrefix << "// ====" << endl; + _stream << _linePrefix << "// ====" << std::endl; for (auto const& setting: settings) - _stream << _linePrefix << "// " << setting.first << ": " << setting.second << endl; + _stream << _linePrefix << "// " << setting.first << ": " << setting.second << std::endl; } void TestCase::printUpdatedSettings(std::ostream& _stream, std::string const& _linePrefix) @@ -51,7 +50,7 @@ void TestCase::printUpdatedSettings(std::ostream& _stream, std::string const& _l bool TestCase::isTestFilename(boost::filesystem::path const& _filename) { - string extension = _filename.extension().string(); + std::string extension = _filename.extension().string(); return (extension == ".sol" || extension == ".yul" || extension == ".stack") && !boost::starts_with(_filename.string(), "~") && !boost::starts_with(_filename.string(), "."); @@ -63,19 +62,19 @@ bool TestCase::shouldRun() return m_shouldRun; } -void TestCase::expect(string::iterator& _it, string::iterator _end, string::value_type _c) +void TestCase::expect(std::string::iterator& _it, std::string::iterator _end, std::string::value_type _c) { if (_it == _end || *_it != _c) - BOOST_THROW_EXCEPTION(runtime_error(string("Invalid test expectation. Expected: \"") + _c + "\".")); + BOOST_THROW_EXCEPTION(std::runtime_error(std::string("Invalid test expectation. Expected: \"") + _c + "\".")); ++_it; } -void TestCase::printSource(ostream& _stream, string const& _linePrefix, bool const) const +void TestCase::printSource(std::ostream& _stream, std::string const& _linePrefix, bool const) const { printPrefixed(_stream, m_source, _linePrefix); } -void TestCase::printUpdatedExpectations(ostream& _stream, string const& _linePrefix) const +void TestCase::printUpdatedExpectations(std::ostream& _stream, std::string const& _linePrefix) const { printPrefixed(_stream, m_obtainedResult, _linePrefix); } @@ -84,30 +83,30 @@ TestCase::TestResult TestCase::checkResult(std::ostream& _stream, const std::str { if (m_expectation != m_obtainedResult) { - string nextIndentLevel = _linePrefix + " "; + std::string nextIndentLevel = _linePrefix + " "; util::AnsiColorized(_stream, _formatted, {util::formatting::BOLD, util::formatting::CYAN}) - << _linePrefix << "Expected result:" << endl; + << _linePrefix << "Expected result:" << std::endl; // TODO could compute a simple diff with highlighted lines printPrefixed(_stream, m_expectation, nextIndentLevel); util::AnsiColorized(_stream, _formatted, {util::formatting::BOLD, util::formatting::CYAN}) - << _linePrefix << "Obtained result:" << endl; + << _linePrefix << "Obtained result:" << std::endl; printPrefixed(_stream, m_obtainedResult, nextIndentLevel); return TestResult::Failure; } return TestResult::Success; } -EVMVersionRestrictedTestCase::EVMVersionRestrictedTestCase(string const& _filename): +EVMVersionRestrictedTestCase::EVMVersionRestrictedTestCase(std::string const& _filename): TestCase(_filename) { - string versionString = m_reader.stringSetting("EVMVersion", "any"); + std::string versionString = m_reader.stringSetting("EVMVersion", "any"); if (versionString == "any") return; - string comparator; + std::string comparator; size_t versionBegin = 0; for (auto character: versionString) - if (!isalpha(character, locale::classic())) + if (!isalpha(character, std::locale::classic())) { comparator += character; versionBegin++; @@ -118,7 +117,7 @@ EVMVersionRestrictedTestCase::EVMVersionRestrictedTestCase(string const& _filena versionString = versionString.substr(versionBegin); std::optional version = langutil::EVMVersion::fromString(versionString); if (!version) - BOOST_THROW_EXCEPTION(runtime_error{"Invalid EVM version: \"" + versionString + "\""}); + BOOST_THROW_EXCEPTION(std::runtime_error{"Invalid EVM version: \"" + versionString + "\""}); langutil::EVMVersion evmVersion = solidity::test::CommonOptions::get().evmVersion(); bool comparisonResult; @@ -135,7 +134,7 @@ EVMVersionRestrictedTestCase::EVMVersionRestrictedTestCase(string const& _filena else if (comparator == "!") comparisonResult = !(evmVersion == version); else - BOOST_THROW_EXCEPTION(runtime_error{"Invalid EVM comparator: \"" + comparator + "\""}); + BOOST_THROW_EXCEPTION(std::runtime_error{"Invalid EVM comparator: \"" + comparator + "\""}); if (!comparisonResult) m_shouldRun = false; diff --git a/test/TestCaseReader.cpp b/test/TestCaseReader.cpp index 7ad752ef816e..da6174cbe9bd 100644 --- a/test/TestCaseReader.cpp +++ b/test/TestCaseReader.cpp @@ -23,36 +23,35 @@ #include #include -using namespace std; using namespace solidity::frontend::test; namespace fs = boost::filesystem; -TestCaseReader::TestCaseReader(string const& _filename): m_fileStream(_filename), m_fileName(_filename) +TestCaseReader::TestCaseReader(std::string const& _filename): m_fileStream(_filename), m_fileName(_filename) { if (!m_fileStream) - BOOST_THROW_EXCEPTION(runtime_error("Cannot open file: \"" + _filename + "\".")); - m_fileStream.exceptions(ios::badbit); + BOOST_THROW_EXCEPTION(std::runtime_error("Cannot open file: \"" + _filename + "\".")); + m_fileStream.exceptions(std::ios::badbit); - tie(m_sources, m_lineNumber) = parseSourcesAndSettingsWithLineNumber(m_fileStream); + std::tie(m_sources, m_lineNumber) = parseSourcesAndSettingsWithLineNumber(m_fileStream); m_unreadSettings = m_settings; } -TestCaseReader::TestCaseReader(istringstream const& _str) +TestCaseReader::TestCaseReader(std::istringstream const& _str) { - tie(m_sources, m_lineNumber) = parseSourcesAndSettingsWithLineNumber( - static_cast(const_cast(_str)) + std::tie(m_sources, m_lineNumber) = parseSourcesAndSettingsWithLineNumber( + static_cast(const_cast(_str)) ); } -string const& TestCaseReader::source() const +std::string const& TestCaseReader::source() const { if (m_sources.sources.size() != 1) - BOOST_THROW_EXCEPTION(runtime_error("Expected single source definition, but got multiple sources.")); + BOOST_THROW_EXCEPTION(std::runtime_error("Expected single source definition, but got multiple sources.")); return m_sources.sources.at(m_sources.mainSourceFile); } -string TestCaseReader::simpleExpectations() +std::string TestCaseReader::simpleExpectations() { return parseSimpleExpectations(m_fileStream); } @@ -63,13 +62,13 @@ bool TestCaseReader::boolSetting(std::string const& _name, bool _defaultValue) return _defaultValue; m_unreadSettings.erase(_name); - string value = m_settings.at(_name); + std::string value = m_settings.at(_name); if (value == "false") return false; if (value == "true") return true; - BOOST_THROW_EXCEPTION(runtime_error("Invalid Boolean value: " + value + ".")); + BOOST_THROW_EXCEPTION(std::runtime_error("Invalid Boolean value: " + value + ".")); } size_t TestCaseReader::sizetSetting(std::string const& _name, size_t _defaultValue) @@ -83,7 +82,7 @@ size_t TestCaseReader::sizetSetting(std::string const& _name, size_t _defaultVal return stoul(m_settings.at(_name)); } -string TestCaseReader::stringSetting(string const& _name, string const& _defaultValue) +std::string TestCaseReader::stringSetting(std::string const& _name, std::string const& _defaultValue) { if (m_settings.count(_name) == 0) return _defaultValue; @@ -95,26 +94,26 @@ string TestCaseReader::stringSetting(string const& _name, string const& _default void TestCaseReader::ensureAllSettingsRead() const { if (!m_unreadSettings.empty()) - BOOST_THROW_EXCEPTION(runtime_error( + BOOST_THROW_EXCEPTION(std::runtime_error( "Unknown setting(s): " + util::joinHumanReadable(m_unreadSettings | ranges::views::keys) )); } -pair TestCaseReader::parseSourcesAndSettingsWithLineNumber(istream& _stream) +std::pair TestCaseReader::parseSourcesAndSettingsWithLineNumber(std::istream& _stream) { - map sources; - map externalSources; - string currentSourceName; - string currentSource; - string line; + std::map sources; + std::map externalSources; + std::string currentSourceName; + std::string currentSource; + std::string line; size_t lineNumber = 1; - static string const externalSourceDelimiterStart("==== ExternalSource:"); - static string const sourceDelimiterStart("==== Source:"); - static string const sourceDelimiterEnd("===="); - static string const comment("// "); - static string const settingsDelimiter("// ===="); - static string const expectationsDelimiter("// ----"); + static std::string const externalSourceDelimiterStart("==== ExternalSource:"); + static std::string const sourceDelimiterStart("==== Source:"); + static std::string const sourceDelimiterEnd("===="); + static std::string const comment("// "); + static std::string const settingsDelimiter("// ===="); + static std::string const expectationsDelimiter("// ----"); bool sourcePart = true; while (getline(_stream, line)) { @@ -138,19 +137,19 @@ pair TestCaseReader::parseSourcesAndSettingsWithLineNumber(is line.size() - sourceDelimiterEnd.size() - sourceDelimiterStart.size() )); if (sources.count(currentSourceName)) - BOOST_THROW_EXCEPTION(runtime_error("Multiple definitions of test source \"" + currentSourceName + "\".")); + BOOST_THROW_EXCEPTION(std::runtime_error("Multiple definitions of test source \"" + currentSourceName + "\".")); } else if (boost::algorithm::starts_with(line, externalSourceDelimiterStart) && boost::algorithm::ends_with(line, sourceDelimiterEnd)) { - string externalSourceString = boost::trim_copy(line.substr( + std::string externalSourceString = boost::trim_copy(line.substr( externalSourceDelimiterStart.size(), line.size() - sourceDelimiterEnd.size() - externalSourceDelimiterStart.size() )); - string externalSourceName; + std::string externalSourceName; size_t remappingPos = externalSourceString.find('='); // Does the external source define a remapping? - if (remappingPos != string::npos) + if (remappingPos != std::string::npos) { externalSourceName = boost::trim_copy(externalSourceString.substr(0, remappingPos)); externalSourceString = boost::trim_copy(externalSourceString.substr(remappingPos + 1)); @@ -164,16 +163,16 @@ pair TestCaseReader::parseSourcesAndSettingsWithLineNumber(is if (!externalSourceTarget.is_relative() || !externalSourceTarget.root_path().empty()) // NOTE: UNC paths (ones starting with // or \\) are considered relative by Boost // since they have an empty root directory (but non-empty root name). - BOOST_THROW_EXCEPTION(runtime_error("External Source paths need to be relative to the location of the test case.")); + BOOST_THROW_EXCEPTION(std::runtime_error("External Source paths need to be relative to the location of the test case.")); fs::path externalSourceFullPath = testCaseParentDir / externalSourceTarget; - string externalSourceContent; + std::string externalSourceContent; if (!fs::exists(externalSourceFullPath)) - BOOST_THROW_EXCEPTION(runtime_error("External Source '" + externalSourceTarget.string() + "' not found.")); + BOOST_THROW_EXCEPTION(std::runtime_error("External Source '" + externalSourceTarget.string() + "' not found.")); else externalSourceContent = util::readFileAsString(externalSourceFullPath); if (sources.count(externalSourceName)) - BOOST_THROW_EXCEPTION(runtime_error("Multiple definitions of test source \"" + externalSourceName + "\".")); + BOOST_THROW_EXCEPTION(std::runtime_error("Multiple definitions of test source \"" + externalSourceName + "\".")); sources[externalSourceName] = externalSourceContent; externalSources[externalSourceName] = externalSourceTarget; } @@ -183,32 +182,32 @@ pair TestCaseReader::parseSourcesAndSettingsWithLineNumber(is else if (boost::algorithm::starts_with(line, comment)) { size_t colon = line.find(':'); - if (colon == string::npos) - BOOST_THROW_EXCEPTION(runtime_error(string("Expected \":\" inside setting."))); - string key = line.substr(comment.size(), colon - comment.size()); - string value = line.substr(colon + 1); + if (colon == std::string::npos) + BOOST_THROW_EXCEPTION(std::runtime_error(std::string("Expected \":\" inside setting."))); + std::string key = line.substr(comment.size(), colon - comment.size()); + std::string value = line.substr(colon + 1); boost::algorithm::trim(key); boost::algorithm::trim(value); m_settings[key] = value; } else - BOOST_THROW_EXCEPTION(runtime_error(string("Expected \"//\" or \"// ---\" to terminate settings and source."))); + BOOST_THROW_EXCEPTION(std::runtime_error(std::string("Expected \"//\" or \"// ---\" to terminate settings and source."))); } // Register the last source as the main one sources[currentSourceName] = currentSource; return {{std::move(sources), std::move(externalSources), std::move(currentSourceName)}, lineNumber}; } -string TestCaseReader::parseSimpleExpectations(istream& _file) +std::string TestCaseReader::parseSimpleExpectations(std::istream& _file) { - string result; - string line; - while (getline(_file, line)) + std::string result; + std::string line; + while (std::getline(_file, line)) if (boost::algorithm::starts_with(line, "// ")) result += line.substr(3) + "\n"; else if (line == "//") result += "\n"; else - BOOST_THROW_EXCEPTION(runtime_error("Test expectations must start with \"// \".")); + BOOST_THROW_EXCEPTION(std::runtime_error("Test expectations must start with \"// \".")); return result; } diff --git a/test/soltest.cpp b/test/soltest.cpp index 443c4c5de3e3..5fde4bda5679 100644 --- a/test/soltest.cpp +++ b/test/soltest.cpp @@ -35,6 +35,7 @@ #pragma warning(pop) #endif +#pragma GCC diagnostic pop #pragma GCC diagnostic pop #include @@ -49,7 +50,6 @@ using namespace boost::unit_test; using namespace solidity::frontend::test; namespace fs = boost::filesystem; -using namespace std; namespace { @@ -100,7 +100,7 @@ void runTestCase(TestCase::Config const& _config, TestCase::TestCaseCreator cons { try { - stringstream errorStream; + std::stringstream errorStream; auto testCase = _testCaseCreator(_config); if (testCase->shouldRun()) switch (testCase->run(errorStream)) @@ -133,7 +133,7 @@ int registerTests( boost::unit_test::test_suite& _suite, boost::filesystem::path const& _basepath, boost::filesystem::path const& _path, - vector const& _labels, + std::vector const& _labels, TestCase::TestCaseCreator _testCaseCreator, solidity::test::Batcher& _batcher ) @@ -176,9 +176,9 @@ int registerTests( // This must be a vector of unique_ptrs because Boost.Test keeps the equivalent of a string_view to the filename // that is passed in. If the strings were stored directly in the vector, pointers/references to them would be // invalidated on reallocation. - static vector> filenames; + static std::vector> filenames; - filenames.emplace_back(make_unique(_path.string())); + filenames.emplace_back(std::make_unique(_path.string())); auto test_case = make_test_case( [config, _testCaseCreator] { @@ -236,11 +236,14 @@ test_suite* init_unit_test_suite(int /*argc*/, char* /*argv*/[]) exit(EXIT_FAILURE); if (solidity::test::CommonOptions::get().disableSemanticTests) - cout << endl << "--- SKIPPING ALL SEMANTICS TESTS ---" << endl << endl; + std::cout << std::endl << "--- SKIPPING ALL SEMANTICS TESTS ---" << std::endl << std::endl; + + if (!solidity::test::CommonOptions::get().enforceGasTest) + std::cout << std::endl << "WARNING :: Gas Cost Expectations are not being enforced" << std::endl << std::endl; Batcher batcher(CommonOptions::get().selectedBatch, CommonOptions::get().batches); if (CommonOptions::get().batches > 1) - cout << "Batch " << CommonOptions::get().selectedBatch << " out of " << CommonOptions::get().batches << endl; + std::cout << "Batch " << CommonOptions::get().selectedBatch << " out of " << CommonOptions::get().batches << std::endl; // Batch the boost tests BoostBatcher boostBatcher(batcher); @@ -287,12 +290,12 @@ test_suite* init_unit_test_suite(int /*argc*/, char* /*argv*/[]) } catch (solidity::test::ConfigException const& exception) { - cerr << exception.what() << endl; + std::cerr << exception.what() << std::endl; exit(EXIT_FAILURE); } catch (std::runtime_error const& exception) { - cerr << exception.what() << endl; + std::cerr << exception.what() << std::endl; exit(EXIT_FAILURE); } From ac398869ad8ab1191f5c52fc58703877e3766ebc Mon Sep 17 00:00:00 2001 From: Martin Blicha Date: Wed, 7 Feb 2024 12:38:41 +0100 Subject: [PATCH 0034/1022] SMTChecker: Respect signedness of integer type When creating zero-value expression, we need to respect the signedness of the passed type. --- libsolidity/formal/SymbolicTypes.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libsolidity/formal/SymbolicTypes.cpp b/libsolidity/formal/SymbolicTypes.cpp index 45b872b3d0d9..350e18bdcf77 100644 --- a/libsolidity/formal/SymbolicTypes.cpp +++ b/libsolidity/formal/SymbolicTypes.cpp @@ -476,7 +476,7 @@ smtutil::Expression zeroValue(frontend::Type const* _type) if (isSupportedType(*_type)) { if (isNumber(*_type)) - return 0; + return isSigned(_type) ? smtutil::Expression(s256(0)) : smtutil::Expression(static_cast(0)); if (isBool(*_type)) return smtutil::Expression(false); if (isArray(*_type) || isMapping(*_type)) From 8770952466d9c7c16cabe534c843e29ef27f7a78 Mon Sep 17 00:00:00 2001 From: Martin Blicha Date: Wed, 7 Feb 2024 12:39:04 +0100 Subject: [PATCH 0035/1022] SMTChecker: Unsigned number expressions should have unsigned type --- libsmtutil/SolverInterface.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libsmtutil/SolverInterface.h b/libsmtutil/SolverInterface.h index 4a21f18410b8..82f81113358a 100644 --- a/libsmtutil/SolverInterface.h +++ b/libsmtutil/SolverInterface.h @@ -124,7 +124,7 @@ class Expression explicit Expression(std::string _name, std::vector _arguments, SortPointer _sort): name(std::move(_name)), arguments(std::move(_arguments)), sort(std::move(_sort)) {} Expression(size_t _number): Expression(std::to_string(_number), {}, SortProvider::uintSort) {} - Expression(u256 const& _number): Expression(_number.str(), {}, SortProvider::sintSort) {} + Expression(u256 const& _number): Expression(_number.str(), {}, SortProvider::uintSort) {} Expression(s256 const& _number): Expression( _number >= 0 ? _number.str() : "-", _number >= 0 ? From a1ad970aa10cb9dcf55af859a0de57ed41893722 Mon Sep 17 00:00:00 2001 From: Martin Blicha Date: Fri, 9 Feb 2024 16:07:52 +0100 Subject: [PATCH 0036/1022] SMTChecker: Add test case --- test/libsolidity/smtCheckerTests/types/mapping_6.sol | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 test/libsolidity/smtCheckerTests/types/mapping_6.sol diff --git a/test/libsolidity/smtCheckerTests/types/mapping_6.sol b/test/libsolidity/smtCheckerTests/types/mapping_6.sol new file mode 100644 index 000000000000..f2b6d74d7a43 --- /dev/null +++ b/test/libsolidity/smtCheckerTests/types/mapping_6.sol @@ -0,0 +1,12 @@ +// SPDX-License-Identifier: GPL-3.0 + + +// Regression for handling signedness, see issues #14791 and #14792 +contract C { + mapping(bool => int240) internal v1; + mapping(bytes14 => bytes15) internal v; + + function f() public payable { + delete v["A"]; + } +} From 22da46c91ceaa4e1a8061b16b69123b5b4ca2457 Mon Sep 17 00:00:00 2001 From: Martin Blicha Date: Fri, 9 Feb 2024 16:25:56 +0100 Subject: [PATCH 0037/1022] Update changelog --- Changelog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/Changelog.md b/Changelog.md index 3d64b1b80e6f..a33421f1cc56 100644 --- a/Changelog.md +++ b/Changelog.md @@ -8,6 +8,7 @@ Compiler Features: Bugfixes: + * SMTChecker: Fix internal error caused by not respecting the sign of an integer type when constructing zero-value SMT expressions. ### 0.8.24 (2024-01-25) From 4d163ff4bb6b84afff0dfd5817ad52b03e5aa521 Mon Sep 17 00:00:00 2001 From: Simon Perriard Date: Sun, 18 Feb 2024 20:13:37 +0100 Subject: [PATCH 0038/1022] Convert tagPos to a size for address size computation --- libevmasm/Assembly.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libevmasm/Assembly.cpp b/libevmasm/Assembly.cpp index 203db8613d24..acf6067697df 100644 --- a/libevmasm/Assembly.cpp +++ b/libevmasm/Assembly.cpp @@ -861,8 +861,8 @@ LinkerObject const& Assembly::assemble() const immutableReferencesBySub = linkerObject.immutableReferences; } for (size_t tagPos: sub->m_tagPositionsInBytecode) - if (tagPos != std::numeric_limits::max() && tagPos > subTagSize) - subTagSize = tagPos; + if (tagPos != std::numeric_limits::max() && numberEncodingSize(tagPos) > subTagSize) + subTagSize = numberEncodingSize(tagPos); } bool setsImmutables = false; From 8e212553d6f96031d000914cd19550cfbc06eca6 Mon Sep 17 00:00:00 2001 From: Daniel Kirchner Date: Mon, 19 Feb 2024 21:10:34 +0100 Subject: [PATCH 0039/1022] Account for subassemblies in tag size calculation, test adjustments and changelog entry. --- Changelog.md | 1 + libevmasm/Assembly.cpp | 12 ++++++++++++ test/cmdlineTests/function_debug_info/output | 2 +- .../output.json | 4 ++-- test/libsolidity/GasCosts.cpp | 16 ++++++++-------- .../semanticTests/arithmetics/check_var_init.sol | 2 +- .../array/constant_var_as_array_length.sol | 2 +- ...leanup_during_multi_element_per_slot_copy.sol | 6 +++--- .../array/fixed_arrays_in_constructors.sol | 2 +- .../semanticTests/array/reusing_memory.sol | 2 +- .../byte_array_to_storage_cleanup.sol | 6 +++--- .../constructor/arrays_in_constructors.sol | 2 +- .../constructor/bytes_in_constructors_packer.sol | 2 +- .../bytes_in_constructors_unpacker.sol | 2 +- .../constructor_arguments_external.sol | 4 ++-- .../constructor_static_array_argument.sol | 2 +- .../constructor_inheritance_init_order.sol | 2 +- .../constructor_inheritance_init_order_2.sol | 6 +++--- .../semanticTests/constructor_with_params.sol | 4 ++-- ...nstructor_with_params_diamond_inheritance.sol | 4 ++-- .../constructor_with_params_inheritance.sol | 4 ++-- .../events/event_emit_from_other_contract.sol | 6 +++--- .../externalContracts/FixedFeeRegistrar.sol | 6 +++--- .../semanticTests/externalContracts/base64.sol | 6 +++--- .../externalContracts/deposit_contract.sol | 4 ++-- .../externalContracts/prbmath_signed.sol | 6 +++--- .../externalContracts/prbmath_unsigned.sol | 6 +++--- .../externalContracts/ramanujan_pi.sol | 6 +++--- .../semanticTests/externalContracts/strings.sol | 6 +++--- .../creation_function_call_with_args.sol | 6 +++--- .../creation_function_call_with_salt.sol | 6 +++--- .../functionCall/gas_and_value_basic.sol | 6 +++--- .../functionCall/gas_and_value_brace_syntax.sol | 6 +++--- .../functionCall/send_zero_ether.sol | 2 +- .../semanticTests/immutable/use_scratch.sol | 4 ++-- .../inheritance/member_notation_ctor.sol | 4 ++-- .../inheritance/value_for_constructor.sol | 4 ++-- .../isoltestTesting/balance_other_contract.sol | 6 +++--- .../salted_create/prediction_example.sol | 2 +- .../salted_create/salted_create_with_value.sol | 2 +- .../semanticTests/smoke/constructor.sol | 6 +++--- .../semanticTests/state/blockhash_basic.sol | 6 +++--- .../semanticTests/userDefinedValueType/erc20.sol | 4 ++-- .../semanticTests/various/code_length.sol | 2 +- test/libsolidity/semanticTests/various/erc20.sol | 4 ++-- .../various/negative_stack_height.sol | 4 ++-- ...estruct_pre_cancun_multiple_beneficiaries.sol | 2 +- .../various/selfdestruct_pre_cancun_redeploy.sol | 6 +++--- .../semanticTests/various/senders_balance.sol | 6 +++--- .../semanticTests/various/value_complex.sol | 6 +++--- .../semanticTests/various/value_insane.sol | 6 +++--- .../sizeLimits/combined_too_large_shanghai.sol | 2 +- .../sizeLimits/initcode_too_large_shanghai.sol | 2 +- 53 files changed, 125 insertions(+), 112 deletions(-) diff --git a/Changelog.md b/Changelog.md index a33421f1cc56..b2ac59c65af8 100644 --- a/Changelog.md +++ b/Changelog.md @@ -8,6 +8,7 @@ Compiler Features: Bugfixes: + * Assembler: Prevent incorrect calculation of tag sizes. * SMTChecker: Fix internal error caused by not respecting the sign of an integer type when constructing zero-value SMT expressions. diff --git a/libevmasm/Assembly.cpp b/libevmasm/Assembly.cpp index acf6067697df..569ecda26a84 100644 --- a/libevmasm/Assembly.cpp +++ b/libevmasm/Assembly.cpp @@ -890,6 +890,18 @@ LinkerObject const& Assembly::assemble() const std::multimap subRef; std::vector sizeRef; ///< Pointers to code locations where the size of the program is inserted unsigned bytesPerTag = numberEncodingSize(bytesRequiredForCode); + // Adjust bytesPerTag for references to sub assemblies. + for (AssemblyItem const& i: m_items) + if (i.type() == PushTag) + { + auto [subId, tagId] = i.splitForeignPushTag(); + if (subId == std::numeric_limits::max()) + continue; + assertThrow(subId < m_subs.size(), AssemblyException, "Invalid sub id"); + auto subTagPosition = m_subs[subId]->m_tagPositionsInBytecode.at(tagId); + assertThrow(subTagPosition != std::numeric_limits::max(), AssemblyException, "Reference to tag without position."); + bytesPerTag = std::max(bytesPerTag, numberEncodingSize(subTagPosition)); + } uint8_t tagPush = static_cast(pushInstruction(bytesPerTag)); unsigned bytesRequiredIncludingData = bytesRequiredForCode + 1 + static_cast(m_auxiliaryData.size()); diff --git a/test/cmdlineTests/function_debug_info/output b/test/cmdlineTests/function_debug_info/output index b9ca3f3c40ec..c359d4e1c155 100644 --- a/test/cmdlineTests/function_debug_info/output +++ b/test/cmdlineTests/function_debug_info/output @@ -13,7 +13,7 @@ }, "abi_decode_tuple_t_uint256_fromMemory": { - "entryPoint": 92, + "entryPoint": 88, "parameterSlots": 2, "returnSlots": 1 } diff --git a/test/cmdlineTests/linking_standard_solidity_unresolved_references/output.json b/test/cmdlineTests/linking_standard_solidity_unresolved_references/output.json index 169e99961e93..3a69e3e2d782 100644 --- a/test/cmdlineTests/linking_standard_solidity_unresolved_references/output.json +++ b/test/cmdlineTests/linking_standard_solidity_unresolved_references/output.json @@ -17,11 +17,11 @@ [ { "length": 20, - "start": 174 + "start": 173 }, { "length": 20, - "start": 350 + "start": 349 } ] } diff --git a/test/libsolidity/GasCosts.cpp b/test/libsolidity/GasCosts.cpp index 520732810195..d8dad9e02705 100644 --- a/test/libsolidity/GasCosts.cpp +++ b/test/libsolidity/GasCosts.cpp @@ -101,7 +101,7 @@ BOOST_AUTO_TEST_CASE(string_storage) if (CommonOptions::get().useABIEncoderV1) CHECK_DEPLOY_GAS(133045, 129731, evmVersion); else - CHECK_DEPLOY_GAS(144999, 121229, evmVersion); + CHECK_DEPLOY_GAS(144995, 121229, evmVersion); } // This is only correct on >=Constantinople. else if (!CommonOptions::get().useABIEncoderV1) @@ -110,22 +110,22 @@ BOOST_AUTO_TEST_CASE(string_storage) { // Costs with 0 are cases which cannot be triggered in tests. if (evmVersion < EVMVersion::istanbul()) - CHECK_DEPLOY_GAS(0, 109241, evmVersion); + CHECK_DEPLOY_GAS(0, 109237, evmVersion); else if (evmVersion < EVMVersion::shanghai()) - CHECK_DEPLOY_GAS(0, 97697, evmVersion); + CHECK_DEPLOY_GAS(0, 97693, evmVersion); // Shanghai is cheaper due to `push0` else - CHECK_DEPLOY_GAS(0, 97071, evmVersion); + CHECK_DEPLOY_GAS(0, 97067, evmVersion); } else { if (evmVersion < EVMVersion::istanbul()) - CHECK_DEPLOY_GAS(139013, 123969, evmVersion); + CHECK_DEPLOY_GAS(139009, 123969, evmVersion); else if (evmVersion < EVMVersion::shanghai()) - CHECK_DEPLOY_GAS(123361, 110969, evmVersion); + CHECK_DEPLOY_GAS(123357, 110969, evmVersion); // Shanghai is cheaper due to `push0` else - CHECK_DEPLOY_GAS(121493, 110969, evmVersion); + CHECK_DEPLOY_GAS(121489, 110969, evmVersion); } } else if (evmVersion < EVMVersion::istanbul()) @@ -133,7 +133,7 @@ BOOST_AUTO_TEST_CASE(string_storage) else if (evmVersion < EVMVersion::shanghai()) CHECK_DEPLOY_GAS(114077, 96461, evmVersion); else - CHECK_DEPLOY_GAS(114077, 95835, evmVersion); + CHECK_DEPLOY_GAS(114077, 95831, evmVersion); if (evmVersion >= EVMVersion::byzantium()) { diff --git a/test/libsolidity/semanticTests/arithmetics/check_var_init.sol b/test/libsolidity/semanticTests/arithmetics/check_var_init.sol index 6cc02bd97580..fc5418cb0ed7 100644 --- a/test/libsolidity/semanticTests/arithmetics/check_var_init.sol +++ b/test/libsolidity/semanticTests/arithmetics/check_var_init.sol @@ -16,4 +16,4 @@ contract D { // ---- // f() -> FAILURE, hex"4e487b71", 0x11 // g(), 100 wei -> 1 -// gas legacy: 100388 +// gas legacy: 100380 diff --git a/test/libsolidity/semanticTests/array/constant_var_as_array_length.sol b/test/libsolidity/semanticTests/array/constant_var_as_array_length.sol index ca65f070657c..45861babaaf3 100644 --- a/test/libsolidity/semanticTests/array/constant_var_as_array_length.sol +++ b/test/libsolidity/semanticTests/array/constant_var_as_array_length.sol @@ -8,7 +8,7 @@ contract C { } // ---- // constructor(): 1, 2, 3 -> -// gas irOptimized: 139656 +// gas irOptimized: 139616 // gas legacy: 180517 // gas legacyOptimized: 150462 // a(uint256): 0 -> 1 diff --git a/test/libsolidity/semanticTests/array/copying/cleanup_during_multi_element_per_slot_copy.sol b/test/libsolidity/semanticTests/array/copying/cleanup_during_multi_element_per_slot_copy.sol index d2361dac5462..8be83289266e 100644 --- a/test/libsolidity/semanticTests/array/copying/cleanup_during_multi_element_per_slot_copy.sol +++ b/test/libsolidity/semanticTests/array/copying/cleanup_during_multi_element_per_slot_copy.sol @@ -16,7 +16,7 @@ contract C { } // ---- // constructor() -// gas irOptimized: 226349 -// gas legacy: 215757 -// gas legacyOptimized: 181760 +// gas irOptimized: 226321 +// gas legacy: 215753 +// gas legacyOptimized: 181756 // f() -> 0 diff --git a/test/libsolidity/semanticTests/array/fixed_arrays_in_constructors.sol b/test/libsolidity/semanticTests/array/fixed_arrays_in_constructors.sol index ac11d779a563..c7b2dc77a34b 100644 --- a/test/libsolidity/semanticTests/array/fixed_arrays_in_constructors.sol +++ b/test/libsolidity/semanticTests/array/fixed_arrays_in_constructors.sol @@ -9,7 +9,7 @@ contract Creator { } // ---- // constructor(): 1, 2, 3, 4 -> -// gas irOptimized: 126363 +// gas irOptimized: 126327 // gas legacy: 174186 // gas legacyOptimized: 128709 // r() -> 4 diff --git a/test/libsolidity/semanticTests/array/reusing_memory.sol b/test/libsolidity/semanticTests/array/reusing_memory.sol index 92b0c06bfb26..8f6afe30ba2c 100644 --- a/test/libsolidity/semanticTests/array/reusing_memory.sol +++ b/test/libsolidity/semanticTests/array/reusing_memory.sol @@ -25,5 +25,5 @@ contract Main { // ---- // f(uint256): 0x34 -> 0x46bddb1178e94d7f2892ff5f366840eb658911794f2c3a44c450aa2c505186c1 // gas irOptimized: 111924 -// gas legacy: 125162 +// gas legacy: 125154 // gas legacyOptimized: 113012 diff --git a/test/libsolidity/semanticTests/byte_array_to_storage_cleanup.sol b/test/libsolidity/semanticTests/byte_array_to_storage_cleanup.sol index dc77f0dff83a..877e2a1bce03 100644 --- a/test/libsolidity/semanticTests/byte_array_to_storage_cleanup.sol +++ b/test/libsolidity/semanticTests/byte_array_to_storage_cleanup.sol @@ -28,9 +28,9 @@ contract C { // compileViaYul: also // ---- // constructor() -> -// gas irOptimized: 443406 -// gas legacy: 711299 -// gas legacyOptimized: 482382 +// gas irOptimized: 443402 +// gas legacy: 711295 +// gas legacyOptimized: 482378 // h() -> 0x20, 0x40, 0x00, 0 // ~ emit ev(uint256[],uint256): 0x40, 0x21, 0x02, 0x00, 0x00 // g() -> 0x20, 0x40, 0, 0x00 diff --git a/test/libsolidity/semanticTests/constructor/arrays_in_constructors.sol b/test/libsolidity/semanticTests/constructor/arrays_in_constructors.sol index 3d9c1ffecefe..19d79b6c4fcf 100644 --- a/test/libsolidity/semanticTests/constructor/arrays_in_constructors.sol +++ b/test/libsolidity/semanticTests/constructor/arrays_in_constructors.sol @@ -25,5 +25,5 @@ contract Creator { // ---- // f(uint256,address[]): 7, 0x40, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 -> 7, 8 // gas irOptimized: 424526 -// gas legacy: 581443 +// gas legacy: 581426 // gas legacyOptimized: 444599 diff --git a/test/libsolidity/semanticTests/constructor/bytes_in_constructors_packer.sol b/test/libsolidity/semanticTests/constructor/bytes_in_constructors_packer.sol index 067a64e0e5f6..cfa74f016f6d 100644 --- a/test/libsolidity/semanticTests/constructor/bytes_in_constructors_packer.sol +++ b/test/libsolidity/semanticTests/constructor/bytes_in_constructors_packer.sol @@ -25,5 +25,5 @@ contract Creator { // ---- // f(uint256,bytes): 7, 0x40, 78, "abcdefghijklmnopqrstuvwxyzabcdef", "ghijklmnopqrstuvwxyzabcdefghijkl", "mnopqrstuvwxyz" -> 7, "h" // gas irOptimized: 275102 -// gas legacy: 418462 +// gas legacy: 418433 // gas legacyOptimized: 291960 diff --git a/test/libsolidity/semanticTests/constructor/bytes_in_constructors_unpacker.sol b/test/libsolidity/semanticTests/constructor/bytes_in_constructors_unpacker.sol index 0665cb807a7d..39da45e8a57e 100644 --- a/test/libsolidity/semanticTests/constructor/bytes_in_constructors_unpacker.sol +++ b/test/libsolidity/semanticTests/constructor/bytes_in_constructors_unpacker.sol @@ -9,7 +9,7 @@ contract Test { // ---- // constructor(): 7, 0x40, 78, "abcdefghijklmnopqrstuvwxyzabcdef", "ghijklmnopqrstuvwxyzabcdefghijkl", "mnopqrstuvwxyz" -> // gas irOptimized: 269225 -// gas legacy: 311324 +// gas legacy: 310820 // gas legacyOptimized: 258604 // m_x() -> 7 // m_s() -> 0x20, 78, "abcdefghijklmnopqrstuvwxyzabcdef", "ghijklmnopqrstuvwxyzabcdefghijkl", "mnopqrstuvwxyz" diff --git a/test/libsolidity/semanticTests/constructor/constructor_arguments_external.sol b/test/libsolidity/semanticTests/constructor/constructor_arguments_external.sol index 3037aaa31753..714ae3e5548c 100644 --- a/test/libsolidity/semanticTests/constructor/constructor_arguments_external.sol +++ b/test/libsolidity/semanticTests/constructor/constructor_arguments_external.sol @@ -17,8 +17,8 @@ contract Main { } // ---- // constructor(): "abc", true -// gas irOptimized: 104394 +// gas irOptimized: 104374 // gas legacy: 143300 -// gas legacyOptimized: 102961 +// gas legacyOptimized: 102933 // getFlag() -> true // getName() -> "abc" diff --git a/test/libsolidity/semanticTests/constructor/constructor_static_array_argument.sol b/test/libsolidity/semanticTests/constructor/constructor_static_array_argument.sol index 22acd1cc3fab..a61192742d04 100644 --- a/test/libsolidity/semanticTests/constructor/constructor_static_array_argument.sol +++ b/test/libsolidity/semanticTests/constructor/constructor_static_array_argument.sol @@ -9,7 +9,7 @@ contract C { } // ---- // constructor(): 1, 2, 3, 4 -> -// gas irOptimized: 171015 +// gas irOptimized: 170975 // gas legacy: 218378 // gas legacyOptimized: 176211 // a() -> 1 diff --git a/test/libsolidity/semanticTests/constructor_inheritance_init_order.sol b/test/libsolidity/semanticTests/constructor_inheritance_init_order.sol index 20cd8760b9b9..ece0cc31a651 100644 --- a/test/libsolidity/semanticTests/constructor_inheritance_init_order.sol +++ b/test/libsolidity/semanticTests/constructor_inheritance_init_order.sol @@ -14,5 +14,5 @@ contract B is A { // compileViaYul: true // ---- // constructor() -> -// gas irOptimized: 119640 +// gas irOptimized: 119636 // y() -> 42 diff --git a/test/libsolidity/semanticTests/constructor_inheritance_init_order_2.sol b/test/libsolidity/semanticTests/constructor_inheritance_init_order_2.sol index 820c56a4eea2..654c9af56df1 100644 --- a/test/libsolidity/semanticTests/constructor_inheritance_init_order_2.sol +++ b/test/libsolidity/semanticTests/constructor_inheritance_init_order_2.sol @@ -9,7 +9,7 @@ contract B is A { } // ---- // constructor() -> -// gas irOptimized: 119640 -// gas legacy: 133594 -// gas legacyOptimized: 115341 +// gas irOptimized: 119636 +// gas legacy: 133574 +// gas legacyOptimized: 115337 // y() -> 42 diff --git a/test/libsolidity/semanticTests/constructor_with_params.sol b/test/libsolidity/semanticTests/constructor_with_params.sol index 1916f692fd1a..e427f6d9ab7b 100644 --- a/test/libsolidity/semanticTests/constructor_with_params.sol +++ b/test/libsolidity/semanticTests/constructor_with_params.sol @@ -9,7 +9,7 @@ contract C { } // ---- // constructor(): 2, 0 -> -// gas irOptimized: 101390 -// gas legacy: 115678 +// gas irOptimized: 101370 +// gas legacy: 115614 // i() -> 2 // k() -> 0 diff --git a/test/libsolidity/semanticTests/constructor_with_params_diamond_inheritance.sol b/test/libsolidity/semanticTests/constructor_with_params_diamond_inheritance.sol index b2f66e4500d8..65070814476d 100644 --- a/test/libsolidity/semanticTests/constructor_with_params_diamond_inheritance.sol +++ b/test/libsolidity/semanticTests/constructor_with_params_diamond_inheritance.sol @@ -21,9 +21,9 @@ contract D is B, C { } // ---- // constructor(): 2, 0 -> -// gas irOptimized: 151966 +// gas irOptimized: 151950 // gas legacy: 168623 -// gas legacyOptimized: 144577 +// gas legacyOptimized: 144521 // i() -> 2 // j() -> 2 // k() -> 1 diff --git a/test/libsolidity/semanticTests/constructor_with_params_inheritance.sol b/test/libsolidity/semanticTests/constructor_with_params_inheritance.sol index f5b20d9816a0..8cc7c69f689b 100644 --- a/test/libsolidity/semanticTests/constructor_with_params_inheritance.sol +++ b/test/libsolidity/semanticTests/constructor_with_params_inheritance.sol @@ -12,8 +12,8 @@ contract D is C { } // ---- // constructor(): 2, 0 -> -// gas irOptimized: 121805 +// gas irOptimized: 121781 // gas legacy: 137193 -// gas legacyOptimized: 118548 +// gas legacyOptimized: 118504 // i() -> 2 // k() -> 1 diff --git a/test/libsolidity/semanticTests/events/event_emit_from_other_contract.sol b/test/libsolidity/semanticTests/events/event_emit_from_other_contract.sol index f8b5141b97fc..0c56cbb671fc 100644 --- a/test/libsolidity/semanticTests/events/event_emit_from_other_contract.sol +++ b/test/libsolidity/semanticTests/events/event_emit_from_other_contract.sol @@ -15,8 +15,8 @@ contract C { } // ---- // constructor() -> -// gas irOptimized: 165386 -// gas legacy: 244800 -// gas legacyOptimized: 171615 +// gas irOptimized: 165370 +// gas legacy: 244776 +// gas legacyOptimized: 171587 // deposit(bytes32), 18 wei: 0x1234 -> // ~ emit Deposit(address,bytes32,uint256) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: #0xc06afe3a8444fc0004668591e8306bfb9968e79e, #0x1234, 0x00 diff --git a/test/libsolidity/semanticTests/externalContracts/FixedFeeRegistrar.sol b/test/libsolidity/semanticTests/externalContracts/FixedFeeRegistrar.sol index f9f53275bba9..011fecbd3422 100644 --- a/test/libsolidity/semanticTests/externalContracts/FixedFeeRegistrar.sol +++ b/test/libsolidity/semanticTests/externalContracts/FixedFeeRegistrar.sol @@ -74,9 +74,9 @@ contract FixedFeeRegistrar is Registrar { } // ---- // constructor() -// gas irOptimized: 384610 -// gas legacy: 913421 -// gas legacyOptimized: 476928 +// gas irOptimized: 384606 +// gas legacy: 913417 +// gas legacyOptimized: 476924 // reserve(string), 69 ether: 0x20, 3, "abc" -> // ~ emit Changed(string): #0x4e03657aea45a94fc7d47ba826c8d667c0d1e6e33a64a036ec44f58fa12d6c45 // gas irOptimized: 45967 diff --git a/test/libsolidity/semanticTests/externalContracts/base64.sol b/test/libsolidity/semanticTests/externalContracts/base64.sol index 646601e6fb8b..ee2745d1acb9 100644 --- a/test/libsolidity/semanticTests/externalContracts/base64.sol +++ b/test/libsolidity/semanticTests/externalContracts/base64.sol @@ -33,9 +33,9 @@ contract test { // EVMVersion: >=constantinople // ---- // constructor() -// gas irOptimized: 405832 -// gas legacy: 735054 -// gas legacyOptimized: 522722 +// gas irOptimized: 405828 +// gas legacy: 735050 +// gas legacyOptimized: 522718 // encode_inline_asm(bytes): 0x20, 0 -> 0x20, 0 // encode_inline_asm(bytes): 0x20, 1, "f" -> 0x20, 4, "Zg==" // encode_inline_asm(bytes): 0x20, 2, "fo" -> 0x20, 4, "Zm8=" diff --git a/test/libsolidity/semanticTests/externalContracts/deposit_contract.sol b/test/libsolidity/semanticTests/externalContracts/deposit_contract.sol index 4f3342dea72f..caa7fc39c867 100644 --- a/test/libsolidity/semanticTests/externalContracts/deposit_contract.sol +++ b/test/libsolidity/semanticTests/externalContracts/deposit_contract.sol @@ -177,8 +177,8 @@ contract DepositContract is IDepositContract, ERC165 { // ---- // constructor() // gas irOptimized: 1386886 -// gas legacy: 2369061 -// gas legacyOptimized: 1740144 +// gas legacy: 2368733 +// gas legacyOptimized: 1740004 // supportsInterface(bytes4): 0x0 -> 0 // supportsInterface(bytes4): 0xffffffff00000000000000000000000000000000000000000000000000000000 -> false # defined to be false by ERC-165 # // supportsInterface(bytes4): 0x01ffc9a700000000000000000000000000000000000000000000000000000000 -> true # ERC-165 id # diff --git a/test/libsolidity/semanticTests/externalContracts/prbmath_signed.sol b/test/libsolidity/semanticTests/externalContracts/prbmath_signed.sol index 3311a8dcf444..ba7a208fd71b 100644 --- a/test/libsolidity/semanticTests/externalContracts/prbmath_signed.sol +++ b/test/libsolidity/semanticTests/externalContracts/prbmath_signed.sol @@ -48,9 +48,9 @@ contract test { } // ---- // constructor() -// gas irOptimized: 1841740 -// gas legacy: 2414091 -// gas legacyOptimized: 1847616 +// gas irOptimized: 1841736 +// gas legacy: 2414087 +// gas legacyOptimized: 1847612 // div(int256,int256): 3141592653589793238, 88714123 -> 35412542528203691288251815328 // gas irOptimized: 22137 // gas legacy: 22767 diff --git a/test/libsolidity/semanticTests/externalContracts/prbmath_unsigned.sol b/test/libsolidity/semanticTests/externalContracts/prbmath_unsigned.sol index fb1d1a43524a..90b283db4613 100644 --- a/test/libsolidity/semanticTests/externalContracts/prbmath_unsigned.sol +++ b/test/libsolidity/semanticTests/externalContracts/prbmath_unsigned.sol @@ -48,9 +48,9 @@ contract test { } // ---- // constructor() -// gas irOptimized: 1716327 -// gas legacy: 2193550 -// gas legacyOptimized: 1725061 +// gas irOptimized: 1716323 +// gas legacy: 2193546 +// gas legacyOptimized: 1725057 // div(uint256,uint256): 3141592653589793238, 88714123 -> 35412542528203691288251815328 // gas irOptimized: 22004 // gas legacy: 22497 diff --git a/test/libsolidity/semanticTests/externalContracts/ramanujan_pi.sol b/test/libsolidity/semanticTests/externalContracts/ramanujan_pi.sol index 3f555405ddbb..4442b6d479d3 100644 --- a/test/libsolidity/semanticTests/externalContracts/ramanujan_pi.sol +++ b/test/libsolidity/semanticTests/externalContracts/ramanujan_pi.sol @@ -33,9 +33,9 @@ contract test { } // ---- // constructor() -// gas irOptimized: 407507 -// gas legacy: 615090 -// gas legacyOptimized: 451871 +// gas irOptimized: 407503 +// gas legacy: 615086 +// gas legacyOptimized: 451867 // prb_pi() -> 3141592656369545286 // gas irOptimized: 57478 // gas legacy: 100947 diff --git a/test/libsolidity/semanticTests/externalContracts/strings.sol b/test/libsolidity/semanticTests/externalContracts/strings.sol index 18d6db37df1e..3f88fc39c65e 100644 --- a/test/libsolidity/semanticTests/externalContracts/strings.sol +++ b/test/libsolidity/semanticTests/externalContracts/strings.sol @@ -49,9 +49,9 @@ contract test { } // ---- // constructor() -// gas irOptimized: 630224 -// gas legacy: 1061957 -// gas legacyOptimized: 718937 +// gas irOptimized: 630220 +// gas legacy: 1061953 +// gas legacyOptimized: 718933 // toSlice(string): 0x20, 11, "hello world" -> 11, 0xa0 // gas irOptimized: 22660 // gas legacy: 23190 diff --git a/test/libsolidity/semanticTests/functionCall/creation_function_call_with_args.sol b/test/libsolidity/semanticTests/functionCall/creation_function_call_with_args.sol index 39592f4a4882..34aac74efa04 100644 --- a/test/libsolidity/semanticTests/functionCall/creation_function_call_with_args.sol +++ b/test/libsolidity/semanticTests/functionCall/creation_function_call_with_args.sol @@ -15,7 +15,7 @@ contract D { } // ---- // constructor(): 2 -> -// gas irOptimized: 192703 -// gas legacy: 241234 -// gas legacyOptimized: 192961 +// gas irOptimized: 192663 +// gas legacy: 241170 +// gas legacyOptimized: 192897 // f() -> 2 diff --git a/test/libsolidity/semanticTests/functionCall/creation_function_call_with_salt.sol b/test/libsolidity/semanticTests/functionCall/creation_function_call_with_salt.sol index 3850a0be7fd6..cb26a6e26adf 100644 --- a/test/libsolidity/semanticTests/functionCall/creation_function_call_with_salt.sol +++ b/test/libsolidity/semanticTests/functionCall/creation_function_call_with_salt.sol @@ -17,7 +17,7 @@ contract D { // EVMVersion: >=constantinople // ---- // constructor(): 2 -> -// gas irOptimized: 192866 -// gas legacy: 241606 -// gas legacyOptimized: 193193 +// gas irOptimized: 192826 +// gas legacy: 241536 +// gas legacyOptimized: 193129 // f() -> 2 diff --git a/test/libsolidity/semanticTests/functionCall/gas_and_value_basic.sol b/test/libsolidity/semanticTests/functionCall/gas_and_value_basic.sol index 79a829aa77ba..8396cb12db8d 100644 --- a/test/libsolidity/semanticTests/functionCall/gas_and_value_basic.sol +++ b/test/libsolidity/semanticTests/functionCall/gas_and_value_basic.sol @@ -38,9 +38,9 @@ contract test { } // ---- // constructor(), 20 wei -> -// gas irOptimized: 252642 -// gas legacy: 391588 -// gas legacyOptimized: 268089 +// gas irOptimized: 252626 +// gas legacy: 391568 +// gas legacyOptimized: 268069 // sendAmount(uint256): 5 -> 5 // outOfGas() -> FAILURE # call to helper should not succeed but amount should be transferred anyway # // checkState() -> false, 15 diff --git a/test/libsolidity/semanticTests/functionCall/gas_and_value_brace_syntax.sol b/test/libsolidity/semanticTests/functionCall/gas_and_value_brace_syntax.sol index 71b6ebb2c7a3..9d9c3f603f78 100644 --- a/test/libsolidity/semanticTests/functionCall/gas_and_value_brace_syntax.sol +++ b/test/libsolidity/semanticTests/functionCall/gas_and_value_brace_syntax.sol @@ -37,9 +37,9 @@ contract test { } // ---- // constructor(), 20 wei -> -// gas irOptimized: 252642 -// gas legacy: 391588 -// gas legacyOptimized: 268089 +// gas irOptimized: 252626 +// gas legacy: 391568 +// gas legacyOptimized: 268069 // sendAmount(uint256): 5 -> 5 // outOfGas() -> FAILURE # call to helper should not succeed but amount should be transferred anyway # // checkState() -> false, 15 diff --git a/test/libsolidity/semanticTests/functionCall/send_zero_ether.sol b/test/libsolidity/semanticTests/functionCall/send_zero_ether.sol index 18a19979295b..a737de5cd4e7 100644 --- a/test/libsolidity/semanticTests/functionCall/send_zero_ether.sol +++ b/test/libsolidity/semanticTests/functionCall/send_zero_ether.sol @@ -16,6 +16,6 @@ contract Main { // ---- // constructor(), 20 wei -> // gas irOptimized: 100264 -// gas legacy: 113411 +// gas legacy: 110555 // gas legacyOptimized: 100361 // s() -> true diff --git a/test/libsolidity/semanticTests/immutable/use_scratch.sol b/test/libsolidity/semanticTests/immutable/use_scratch.sol index 0a5ccf729f59..a7c8ea6a502a 100644 --- a/test/libsolidity/semanticTests/immutable/use_scratch.sol +++ b/test/libsolidity/semanticTests/immutable/use_scratch.sol @@ -15,8 +15,8 @@ contract C { } // ---- // constructor(): 3 -> -// gas irOptimized: 123542 +// gas irOptimized: 123526 // gas legacy: 197645 -// gas legacyOptimized: 137678 +// gas legacyOptimized: 137658 // f() -> 84, 23 // m(uint256): 3 -> 7 diff --git a/test/libsolidity/semanticTests/inheritance/member_notation_ctor.sol b/test/libsolidity/semanticTests/inheritance/member_notation_ctor.sol index 33392e8d48c6..263588abab5c 100644 --- a/test/libsolidity/semanticTests/inheritance/member_notation_ctor.sol +++ b/test/libsolidity/semanticTests/inheritance/member_notation_ctor.sol @@ -19,6 +19,6 @@ contract A { } // ---- // g(int256): -1 -> -1 -// gas legacy: 102086 +// gas legacy: 102078 // g(int256): 10 -> 10 -// gas legacy: 101714 +// gas legacy: 101706 diff --git a/test/libsolidity/semanticTests/inheritance/value_for_constructor.sol b/test/libsolidity/semanticTests/inheritance/value_for_constructor.sol index d8fd8766fec6..9627ad025ddd 100644 --- a/test/libsolidity/semanticTests/inheritance/value_for_constructor.sol +++ b/test/libsolidity/semanticTests/inheritance/value_for_constructor.sol @@ -39,9 +39,9 @@ contract Main { } // ---- // constructor(), 22 wei -> -// gas irOptimized: 261888 +// gas irOptimized: 261864 // gas legacy: 392786 -// gas legacyOptimized: 261633 +// gas legacyOptimized: 261593 // getFlag() -> true // getName() -> "abc" // getBalances() -> 12, 10 diff --git a/test/libsolidity/semanticTests/isoltestTesting/balance_other_contract.sol b/test/libsolidity/semanticTests/isoltestTesting/balance_other_contract.sol index 306bc35670fe..1a5c9b19b416 100644 --- a/test/libsolidity/semanticTests/isoltestTesting/balance_other_contract.sol +++ b/test/libsolidity/semanticTests/isoltestTesting/balance_other_contract.sol @@ -16,9 +16,9 @@ contract ClientReceipt { } // ---- // constructor(), 2000 wei -> -// gas irOptimized: 169915 -// gas legacy: 230038 -// gas legacyOptimized: 173883 +// gas irOptimized: 169907 +// gas legacy: 230018 +// gas legacyOptimized: 173867 // balance -> 1500 // gas irOptimized: 191881 // gas legacy: 235167 diff --git a/test/libsolidity/semanticTests/salted_create/prediction_example.sol b/test/libsolidity/semanticTests/salted_create/prediction_example.sol index 1c5ce63ad456..e7171536d6bb 100644 --- a/test/libsolidity/semanticTests/salted_create/prediction_example.sol +++ b/test/libsolidity/semanticTests/salted_create/prediction_example.sol @@ -26,4 +26,4 @@ contract C { // compileViaYul: also // ---- // createDSalted(bytes32,uint256): 42, 64 -> -// gas legacy: 102943 +// gas legacy: 102841 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 c4db17474223..58b3f076034c 100644 --- a/test/libsolidity/semanticTests/salted_create/salted_create_with_value.sol +++ b/test/libsolidity/semanticTests/salted_create/salted_create_with_value.sol @@ -23,4 +23,4 @@ contract A { // f(), 10 ether -> 3007, 3008, 3009 // gas irOptimized: 253005 // gas legacy: 381063 -// gas legacyOptimized: 279694 +// gas legacyOptimized: 279658 diff --git a/test/libsolidity/semanticTests/smoke/constructor.sol b/test/libsolidity/semanticTests/smoke/constructor.sol index 79b92867bc0d..55789b2f4b65 100644 --- a/test/libsolidity/semanticTests/smoke/constructor.sol +++ b/test/libsolidity/semanticTests/smoke/constructor.sol @@ -12,9 +12,9 @@ contract C { } // ---- // constructor(), 2 wei: 3 -> -// gas irOptimized: 104412 -// gas legacy: 148308 -// gas legacyOptimized: 106727 +// gas irOptimized: 104396 +// gas legacy: 148256 +// gas legacyOptimized: 106699 // state() -> 3 // balance() -> 2 // balance -> 2 diff --git a/test/libsolidity/semanticTests/state/blockhash_basic.sol b/test/libsolidity/semanticTests/state/blockhash_basic.sol index 01069aa0c6dc..03d6f9fe76ea 100644 --- a/test/libsolidity/semanticTests/state/blockhash_basic.sol +++ b/test/libsolidity/semanticTests/state/blockhash_basic.sol @@ -12,9 +12,9 @@ contract C { } // ---- // constructor() -// gas irOptimized: 108150 -// gas legacy: 152179 -// gas legacyOptimized: 106750 +// gas irOptimized: 108138 +// gas legacy: 152171 +// gas legacyOptimized: 106738 // genesisHash() -> 0x3737373737373737373737373737373737373737373737373737373737373737 // currentHash() -> 0 // f(uint256): 0 -> 0x3737373737373737373737373737373737373737373737373737373737373737 diff --git a/test/libsolidity/semanticTests/userDefinedValueType/erc20.sol b/test/libsolidity/semanticTests/userDefinedValueType/erc20.sol index 27ab530cd76d..ac8609d71324 100644 --- a/test/libsolidity/semanticTests/userDefinedValueType/erc20.sol +++ b/test/libsolidity/semanticTests/userDefinedValueType/erc20.sol @@ -113,8 +113,8 @@ contract ERC20 { // ---- // constructor() // ~ emit Transfer(address,address,uint256): #0x00, #0x1212121212121212121212121212120000000012, 0x14 -// gas irOptimized: 352698 -// gas legacy: 834932 +// gas irOptimized: 352682 +// gas legacy: 834752 // gas legacyOptimized: 412648 // totalSupply() -> 20 // gas irOptimized: 23415 diff --git a/test/libsolidity/semanticTests/various/code_length.sol b/test/libsolidity/semanticTests/various/code_length.sol index 97a7637976eb..a8aac5306f50 100644 --- a/test/libsolidity/semanticTests/various/code_length.sol +++ b/test/libsolidity/semanticTests/various/code_length.sol @@ -59,5 +59,5 @@ contract C { } // ---- // constructor() -// gas legacy: 124168 +// gas legacy: 124136 // f(): true, true -> true, true diff --git a/test/libsolidity/semanticTests/various/erc20.sol b/test/libsolidity/semanticTests/various/erc20.sol index b752a5210152..00c12fb18a70 100644 --- a/test/libsolidity/semanticTests/various/erc20.sol +++ b/test/libsolidity/semanticTests/various/erc20.sol @@ -96,8 +96,8 @@ contract ERC20 { // ---- // constructor() // ~ emit Transfer(address,address,uint256): #0x00, #0x1212121212121212121212121212120000000012, 0x14 -// gas irOptimized: 353276 -// gas legacy: 807683 +// gas irOptimized: 353248 +// gas legacy: 807559 // gas legacyOptimized: 408718 // totalSupply() -> 20 // gas irOptimized: 23415 diff --git a/test/libsolidity/semanticTests/various/negative_stack_height.sol b/test/libsolidity/semanticTests/various/negative_stack_height.sol index 3c9130e9fdf0..7289d2bbd96f 100644 --- a/test/libsolidity/semanticTests/various/negative_stack_height.sol +++ b/test/libsolidity/semanticTests/various/negative_stack_height.sol @@ -65,5 +65,5 @@ contract C { // compileViaYul: false // ---- // constructor() -> -// gas legacy: 575272 -// gas legacyOptimized: 345026 +// gas legacy: 575268 +// gas legacyOptimized: 345022 diff --git a/test/libsolidity/semanticTests/various/selfdestruct_pre_cancun_multiple_beneficiaries.sol b/test/libsolidity/semanticTests/various/selfdestruct_pre_cancun_multiple_beneficiaries.sol index 57b2d5c66ac4..87e81a2902d1 100644 --- a/test/libsolidity/semanticTests/various/selfdestruct_pre_cancun_multiple_beneficiaries.sol +++ b/test/libsolidity/semanticTests/various/selfdestruct_pre_cancun_multiple_beneficiaries.sol @@ -36,7 +36,7 @@ contract D { // ---- // constructor(), 2 ether -> // gas irOptimized: 223918 -// gas legacy: 374228 +// gas legacy: 374024 // gas legacyOptimized: 239815 // balance: 0x1111111111111111111111111111111111111111 -> 0 // balance: 0x2222222222222222222222222222222222222222 -> 0 diff --git a/test/libsolidity/semanticTests/various/selfdestruct_pre_cancun_redeploy.sol b/test/libsolidity/semanticTests/various/selfdestruct_pre_cancun_redeploy.sol index 9c9949854a0a..e0885782c260 100644 --- a/test/libsolidity/semanticTests/various/selfdestruct_pre_cancun_redeploy.sol +++ b/test/libsolidity/semanticTests/various/selfdestruct_pre_cancun_redeploy.sol @@ -79,9 +79,9 @@ contract D { // EVMVersion: =shanghai // ---- // constructor(), 1 ether -> -// gas irOptimized: 430265 -// gas legacy: 690264 -// gas legacyOptimized: 412819 +// gas irOptimized: 430253 +// gas legacy: 690244 +// gas legacyOptimized: 412799 // exists() -> false // test_deploy_and_terminate() -> // ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000 diff --git a/test/libsolidity/semanticTests/various/senders_balance.sol b/test/libsolidity/semanticTests/various/senders_balance.sol index 6628454db9db..a1c7d4147fc6 100644 --- a/test/libsolidity/semanticTests/various/senders_balance.sol +++ b/test/libsolidity/semanticTests/various/senders_balance.sol @@ -16,7 +16,7 @@ contract D { } // ---- // constructor(), 27 wei -> -// gas irOptimized: 167865 -// gas legacy: 218459 -// gas legacyOptimized: 167292 +// gas irOptimized: 167857 +// gas legacy: 218435 +// gas legacyOptimized: 167276 // f() -> 27 diff --git a/test/libsolidity/semanticTests/various/value_complex.sol b/test/libsolidity/semanticTests/various/value_complex.sol index 9f262fbdeb51..2adac6bf4cd0 100644 --- a/test/libsolidity/semanticTests/various/value_complex.sol +++ b/test/libsolidity/semanticTests/various/value_complex.sol @@ -19,7 +19,7 @@ contract test { } // ---- // constructor(), 20 wei -> -// gas irOptimized: 172407 -// gas legacy: 252296 -// gas legacyOptimized: 180352 +// gas irOptimized: 172399 +// gas legacy: 252276 +// gas legacyOptimized: 180336 // sendAmount(uint256): 5 -> 8 diff --git a/test/libsolidity/semanticTests/various/value_insane.sol b/test/libsolidity/semanticTests/various/value_insane.sol index 1e591050c3b3..87fa01485d61 100644 --- a/test/libsolidity/semanticTests/various/value_insane.sol +++ b/test/libsolidity/semanticTests/various/value_insane.sol @@ -18,7 +18,7 @@ contract test { } // ---- // constructor(), 20 wei -> -// gas irOptimized: 173271 -// gas legacy: 253820 -// gas legacyOptimized: 180784 +// gas irOptimized: 173263 +// gas legacy: 253800 +// gas legacyOptimized: 180768 // sendAmount(uint256): 5 -> 8 diff --git a/test/libsolidity/syntaxTests/sizeLimits/combined_too_large_shanghai.sol b/test/libsolidity/syntaxTests/sizeLimits/combined_too_large_shanghai.sol index 3fc466db3927..32e8d9133be2 100644 --- a/test/libsolidity/syntaxTests/sizeLimits/combined_too_large_shanghai.sol +++ b/test/libsolidity/syntaxTests/sizeLimits/combined_too_large_shanghai.sol @@ -29,4 +29,4 @@ contract test { // Warning 5574: (0-27130): Contract code size is 27187 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. // Warning 5574: (27132-27224): Contract code size is 27213 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. // Warning 5574: (27226-27319): Contract code size is 27212 bytes and exceeds 24576 bytes (a limit introduced in Spurious Dragon). This contract may not be deployable on Mainnet. Consider enabling the optimizer (with a low "runs" value!), turning off revert strings, or using libraries. -// Warning 3860: (27321-27398): Contract initcode size is 54628 bytes and exceeds 49152 bytes (a limit introduced in Shanghai). This contract may not be deployable on Mainnet. Consider enabling the optimizer (with a low "runs" value!), turning off revert strings, or using libraries. +// Warning 3860: (27321-27398): Contract initcode size is 54618 bytes and exceeds 49152 bytes (a limit introduced in Shanghai). This contract may not be deployable on Mainnet. Consider enabling the optimizer (with a low "runs" value!), turning off revert strings, or using libraries. diff --git a/test/libsolidity/syntaxTests/sizeLimits/initcode_too_large_shanghai.sol b/test/libsolidity/syntaxTests/sizeLimits/initcode_too_large_shanghai.sol index f82434d5d663..d48693db05b1 100644 --- a/test/libsolidity/syntaxTests/sizeLimits/initcode_too_large_shanghai.sol +++ b/test/libsolidity/syntaxTests/sizeLimits/initcode_too_large_shanghai.sol @@ -27,4 +27,4 @@ contract test { // ==== // EVMVersion: =shanghai // ---- -// Warning 3860: (20321-20415): Contract initcode size is 60896 bytes and exceeds 49152 bytes (a limit introduced in Shanghai). This contract may not be deployable on Mainnet. Consider enabling the optimizer (with a low "runs" value!), turning off revert strings, or using libraries. +// Warning 3860: (20321-20415): Contract initcode size is 60882 bytes and exceeds 49152 bytes (a limit introduced in Shanghai). This contract may not be deployable on Mainnet. Consider enabling the optimizer (with a low "runs" value!), turning off revert strings, or using libraries. From c49d84784e62082756b671bd1ed85c076185fe31 Mon Sep 17 00:00:00 2001 From: Nikola Matic Date: Tue, 20 Feb 2024 07:27:58 +0100 Subject: [PATCH 0040/1022] Force install python3.12 for Window bytecode compare job --- .circleci/config.yml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 5ab0b056a287..72d96fe4f871 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1697,8 +1697,12 @@ jobs: # platforms so line ending conversions must absolutely be disabled. - run: git config --global core.autocrlf false - checkout - # Ensure windows has python3 alias required by prepare_bytecode_report - - run: ln -s /c/Python312/python /c/Python312/python3 + - run: + name: Force install python3.12.2 + command: choco install python3 --pre --force --version=3.12.2 + - run: + name: Create a symlink for python3 + command: ln -s /c/ProgramData/chocolatey/bin/python3.12 /c/ProgramData/chocolatey/bin/python3 - attach_workspace: at: build - prepare_bytecode_report: From 1185ad0400223a54777904d1521102eec599d666 Mon Sep 17 00:00:00 2001 From: r0qs Date: Tue, 20 Feb 2024 14:49:28 +0100 Subject: [PATCH 0041/1022] Build hardhat from latest release in t_ems_ext_hardhat --- .circleci/config.yml | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 5ab0b056a287..5b13a794562c 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1386,7 +1386,31 @@ jobs: - checkout - attach_workspace: at: /tmp/workspace - - run: git clone --depth 1 https://github.com/nomiclabs/hardhat.git + - run: + name: Ensure pnpm is installed if npm is present + command: | + if command -v npm &> /dev/null; then + sudo npm install -g pnpm + fi + - run: + name: Retrieve Hardhat latest release tag + command: | + # Make authenticated requests when the Github token is available + if [[ -n "$GITHUB_ACCESS_TOKEN" ]]; then + EXTRA_HEADERS=(--header 'Authorization: Bearer '"${GITHUB_ACCESS_TOKEN}") + fi + HARDHAT_RELEASE_TAG=$( + curl \ + --silent \ + --location \ + --fail \ + --show-error \ + "${EXTRA_HEADERS[@]}" \ + https://api.github.com/repos/nomiclabs/hardhat/releases/latest \ + | jq --raw-output .tag_name \ + ) + echo "export HARDHAT_RELEASE_TAG='${HARDHAT_RELEASE_TAG}'" >> "$BASH_ENV" + - run: git clone --depth 1 https://github.com/nomiclabs/hardhat.git --branch $HARDHAT_RELEASE_TAG - run: name: Install dependencies command: | From d703b829b2f13d6a6d7b7bdd6271ec3fecdae4dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Sun, 11 Feb 2024 16:04:27 +0100 Subject: [PATCH 0042/1022] gas_diff_stats.py: Add basic unit tests --- .circleci/config.yml | 6 +- test/scripts/test_gas_diff_stats.py | 87 +++++++++++++++++++++++++++++ 2 files changed, 92 insertions(+), 1 deletion(-) create mode 100644 test/scripts/test_gas_diff_stats.py diff --git a/.circleci/config.yml b/.circleci/config.yml index 72d96fe4f871..e14a4ec78c6f 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -973,6 +973,10 @@ jobs: <<: *base_ubuntu2204_small steps: - checkout + - run: + # TODO: Add these to the base image + name: Install gas_diff_stats.py dependencies + command: python3 -m pip install --user parsec tabulate - run: name: Python unit tests command: python3 test/pyscriptTests.py @@ -985,7 +989,7 @@ jobs: - checkout - run: name: Install dependencies - command: python -m pip install --user requests + command: python -m pip install --user requests parsec tabulate - run: name: Python unit tests command: python.exe test/pyscriptTests.py diff --git a/test/scripts/test_gas_diff_stats.py b/test/scripts/test_gas_diff_stats.py new file mode 100644 index 000000000000..4980293aea08 --- /dev/null +++ b/test/scripts/test_gas_diff_stats.py @@ -0,0 +1,87 @@ +#!/usr/bin/env python + +import unittest +from textwrap import dedent + +# NOTE: This test file file only works with scripts/ added to PYTHONPATH so pylint can't find the imports +# pragma pylint: disable=import-error +from gas_diff_stats import collect_statistics +# pragma pylint: enable=import-error + +class TestGasDiffStats(unittest.TestCase): + def test_collect_statistics_should_fail_on_empty_diff(self): + with self.assertRaises(RuntimeError): + self.assertEqual(collect_statistics(""), (0, 0, 0, 0, 0, 0)) + + def test_collect_statistics_should_accept_whitespace_only_diff(self): + # TODO: Should it really work this way? + # If we're rejecting empty diff, not sure why whitespace is accepted. + self.assertEqual(collect_statistics("\n"), (0, 0, 0, 0, 0, 0)) + self.assertEqual(collect_statistics("\n \n\t\n\n"), (0, 0, 0, 0, 0, 0)) + + def test_collect_statistics_should_report_sum_of_gas_costs(self): + diff_output = dedent(""" + 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 1306529d4..77a330f3c 100644 + --- a/test/libsolidity/semanticTests/various/staticcall_for_view_and_pure.sol + +++ b/test/libsolidity/semanticTests/various/staticcall_for_view_and_pure.sol + @@ -38 +38,2 @@ contract D { + -// gas legacy: 102095 + +// gas legacy: 76495 + @@ -40,3 +41,6 @@ contract D { + -// gas irOptimized: 98438588 + -// gas legacy: 98438774 + -// gas legacyOptimized: 98438580 + +// gas irOptimized: 25388 + +// gas legacy: 98413174 + +// gas legacyOptimized: 25380 + @@ -44,3 +48,6 @@ contract D { + -// gas irOptimized: 98438589 + -// gas legacy: 98438774 + -// gas legacyOptimized: 98438580 + +// gas irOptimized: 25389 + +// gas legacy: 98413174 + +// gas legacyOptimized: 25380 + """).splitlines() + + self.assertEqual(collect_statistics(diff_output), ( + 98438588 + 98438589, # -irOptimized + 98438580 + 98438580, # -legacyOptimized + 102095 + 98438774 + 98438774, # -legacy + 25388 + 25389, # +irOptimized + 25380 + 25380, # +legacyOptimized + 76495 + 98413174 + 98413174, # +legacy + )) + + def test_collect_statistics_should_ignore_ir_costs(self): + diff_output = dedent(""" + -// gas legacy: 1 + -// gas ir: 2 + +// gas legacy: 3 + +// gas ir: 4 + """).splitlines() + + self.assertEqual(collect_statistics(diff_output), ( + 0, # -irOptimized + 0, # -legacyOptimized + 1, # -legacy + 0, # +irOptimized + 0, # +legacyOptimized + 3, # +legacy + )) + + def test_collect_statistics_should_ignore_unchanged_costs(self): + diff_output = dedent(""" + -// gas legacy: 1 + // gas legacyOptimized: 2 + +// gas legacy: 3 + """).splitlines() + + self.assertEqual(collect_statistics(diff_output), ( + 0, # -irOptimized + 0, # -legacyOptimized + 1, # -legacy + 0, # +irOptimized + 0, # +legacyOptimized + 3, # +legacy + )) From c6e23311cca599f25d1df87dcae8d2ce1f758793 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Sun, 11 Feb 2024 13:29:28 +0100 Subject: [PATCH 0043/1022] gas_diff_stats.py: Add a Python shebang - The script is executable but executes as a Bash script and fails. --- scripts/gas_diff_stats.py | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/gas_diff_stats.py b/scripts/gas_diff_stats.py index 234d42df0c0e..90a153cd3179 100755 --- a/scripts/gas_diff_stats.py +++ b/scripts/gas_diff_stats.py @@ -1,3 +1,4 @@ +#!/usr/bin/env python3 """A script to collect gas statistics and print it. Useful to summarize gas differences to semantic tests for a PR / branch. From e28a1d436a15e698b933f2a6cc5b160f2bcb3616 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Sun, 11 Feb 2024 13:31:42 +0100 Subject: [PATCH 0044/1022] gas_diff_stats.py: Print errors to stderr, not stdout --- scripts/gas_diff_stats.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/scripts/gas_diff_stats.py b/scripts/gas_diff_stats.py index 90a153cd3179..b220485c003d 100755 --- a/scripts/gas_diff_stats.py +++ b/scripts/gas_diff_stats.py @@ -18,7 +18,9 @@ repository. The changes are compared against ``origin/develop``. """ + import subprocess +import sys from pathlib import Path from enum import Enum from parsec import generate, ParseError, regex, string @@ -110,8 +112,8 @@ def try_parse_git_diff(fname): if diff_output: return collect_statistics(diff_output) except subprocess.CalledProcessError as e: - print("Error in the git diff:") - print(e.output) + print("Error in the git diff:", file=sys.stderr) + print(e.output, file=sys.stderr) return None def stat(old, new): return ((new - old) / old) * 100 if old else 0 From 5518a3074f0804e7d075122d27733b71812549c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Sun, 11 Feb 2024 13:35:50 +0100 Subject: [PATCH 0045/1022] gas_diff_stats.py: Don't let shell evaluate file names and support names with spaces --- scripts/gas_diff_stats.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/scripts/gas_diff_stats.py b/scripts/gas_diff_stats.py index b220485c003d..6f8087d4813e 100755 --- a/scripts/gas_diff_stats.py +++ b/scripts/gas_diff_stats.py @@ -105,8 +105,7 @@ def semantictest_statistics(): def try_parse_git_diff(fname): try: diff_output = subprocess.check_output( - "git diff --unified=0 origin/develop HEAD " + fname, - shell=True, + ["git", "diff", "--unified=0", "origin/develop", "HEAD", fname], universal_newlines=True ).splitlines() if diff_output: From 39f3e7673f84f874a33515f383efca029b2abc49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Sun, 11 Feb 2024 13:36:26 +0100 Subject: [PATCH 0046/1022] gas_diff_stats.py: Fail when the semantic test dir does not exist --- scripts/gas_diff_stats.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/scripts/gas_diff_stats.py b/scripts/gas_diff_stats.py index 6f8087d4813e..922aa7de45ee 100755 --- a/scripts/gas_diff_stats.py +++ b/scripts/gas_diff_stats.py @@ -35,6 +35,8 @@ class Diff(Enum): Minus = 1 Plus = 2 +SEMANTIC_TEST_DIR = Path("test/libsolidity/semanticTests/") + minus = string("-").result(Diff.Minus) plus = string("+").result(Diff.Plus) @@ -119,7 +121,10 @@ def stat(old, new): table = [] - for path in Path("test/libsolidity/semanticTests").rglob("*.sol"): + if not SEMANTIC_TEST_DIR.is_dir(): + sys.exit(f"Semantic tests not found. '{SEMANTIC_TEST_DIR.absolute()}' is missing or not a directory.") + + for path in SEMANTIC_TEST_DIR.rglob("*.sol"): fname = path.as_posix() parsed = try_parse_git_diff(fname) if parsed is None: From 855096b84b71aa5f5dd949f83e2dc90831f1e3f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Sun, 11 Feb 2024 15:17:41 +0100 Subject: [PATCH 0047/1022] gas_diff_stats.py: Skip non-gas lines to avoid having to silence parsing errors --- scripts/gas_diff_stats.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/scripts/gas_diff_stats.py b/scripts/gas_diff_stats.py index 922aa7de45ee..5d95d5a1935f 100755 --- a/scripts/gas_diff_stats.py +++ b/scripts/gas_diff_stats.py @@ -89,7 +89,12 @@ def try_parse(line): pass return None - out = [parsed for line in lines if (parsed := try_parse(line)) is not None] + out = [ + parsed + for line in lines + if line.startswith('+// gas ') or line.startswith('-// gas ') + if (parsed := try_parse(line)) is not None + ] diff_kinds = [Diff.Minus, Diff.Plus] codegen_kinds = [Kind.IrOptimized, Kind.LegacyOptimized, Kind.Legacy] return tuple( From b9c7b69c76ed73c57aef3681d6f29dd155d1607e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Sun, 11 Feb 2024 15:57:36 +0100 Subject: [PATCH 0048/1022] gas_diff_stats.py: Explicitly ignore ir gas instead of failing to parse it --- scripts/gas_diff_stats.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/scripts/gas_diff_stats.py b/scripts/gas_diff_stats.py index 5d95d5a1935f..518d8c2c7580 100755 --- a/scripts/gas_diff_stats.py +++ b/scripts/gas_diff_stats.py @@ -27,9 +27,10 @@ from tabulate import tabulate class Kind(Enum): - IrOptimized = 1 - Legacy = 2 - LegacyOptimized = 3 + Ir = 1 + IrOptimized = 2 + Legacy = 3 + LegacyOptimized = 4 class Diff(Enum): Minus = 1 @@ -44,6 +45,7 @@ class Diff(Enum): comment = string("//") colon = string(":") +gas_ir = string("gas ir").result(Kind.Ir) gas_ir_optimized = string("gas irOptimized").result(Kind.IrOptimized) gas_legacy_optimized = string("gas legacyOptimized").result(Kind.LegacyOptimized) gas_legacy = string("gas legacy").result(Kind.Legacy) @@ -64,7 +66,7 @@ def diff_string() -> (Kind, Diff, int): diff_kind = yield minus | plus yield comment yield space - codegen_kind = yield gas_ir_optimized ^ gas_legacy_optimized ^ gas_legacy + codegen_kind = yield gas_ir_optimized ^ gas_ir ^ gas_legacy_optimized ^ gas_legacy yield colon yield space val = yield number() From 65031d3b3e128cd30283afcec254d2326030069d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Sun, 11 Feb 2024 15:22:17 +0100 Subject: [PATCH 0049/1022] gas_diff_stats.py: Handle errors instead of ignoring them - It's possible now that errors are something really exceptional and don't happen on every run. --- scripts/gas_diff_stats.py | 46 ++++++++++++++++++++------------------- 1 file changed, 24 insertions(+), 22 deletions(-) diff --git a/scripts/gas_diff_stats.py b/scripts/gas_diff_stats.py index 518d8c2c7580..352700252464 100755 --- a/scripts/gas_diff_stats.py +++ b/scripts/gas_diff_stats.py @@ -84,18 +84,11 @@ def collect_statistics(lines) -> (int, int, int, int, int, int): if not lines: raise RuntimeError("Empty list") - def try_parse(line): - try: - return diff_string.parse(line) - except ParseError: - pass - return None - out = [ parsed for line in lines if line.startswith('+// gas ') or line.startswith('-// gas ') - if (parsed := try_parse(line)) is not None + if (parsed := diff_string.parse(line)) is not None ] diff_kinds = [Diff.Minus, Diff.Plus] codegen_kinds = [Kind.IrOptimized, Kind.LegacyOptimized, Kind.Legacy] @@ -111,18 +104,15 @@ def try_parse(line): def semantictest_statistics(): """Prints the tabulated statistics that can be pasted in github.""" - def try_parse_git_diff(fname): - try: - diff_output = subprocess.check_output( - ["git", "diff", "--unified=0", "origin/develop", "HEAD", fname], - universal_newlines=True - ).splitlines() - if diff_output: - return collect_statistics(diff_output) - except subprocess.CalledProcessError as e: - print("Error in the git diff:", file=sys.stderr) - print(e.output, file=sys.stderr) - return None + def parse_git_diff(fname): + diff_output = subprocess.check_output( + ["git", "diff", "--unified=0", "origin/develop", "HEAD", fname], + universal_newlines=True + ).splitlines() + if len(diff_output) == 0: + return None + return collect_statistics(diff_output) + def stat(old, new): return ((new - old) / old) * 100 if old else 0 @@ -133,7 +123,7 @@ def stat(old, new): for path in SEMANTIC_TEST_DIR.rglob("*.sol"): fname = path.as_posix() - parsed = try_parse_git_diff(fname) + parsed = parse_git_diff(fname) if parsed is None: continue ir_optimized = stat(parsed[0], parsed[3]) @@ -150,5 +140,17 @@ def stat(old, new): else: print("No differences found.") +def main(): + try: + semantictest_statistics() + except subprocess.CalledProcessError as exception: + sys.exit(f"Error in the git diff:\n{exception.output}") + except ParseError as exception: + sys.exit( + f"ParseError: {exception}\n\n" + f"{exception.text}\n" + f"{' ' * exception.index}^\n" + ) + if __name__ == "__main__": - semantictest_statistics() + main() From 43274fddef0ecc55f4026d089fef3928b0617680 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Sun, 11 Feb 2024 14:14:17 +0100 Subject: [PATCH 0050/1022] gas_diff_stats.py: Improve table and number formatting - Use blanks if percentage is infinite instead of misleadingly showing zero. - Round percentages to nearest integer (but indicate when numbers are only close to zero rather than exactly zero). Differences below one percent are rarely relevant, if ever. - Include % after the numbers. - Put file names in backticks to get them displayed using fixed-width font on github. --- scripts/gas_diff_stats.py | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/scripts/gas_diff_stats.py b/scripts/gas_diff_stats.py index 352700252464..0707b9857bc8 100755 --- a/scripts/gas_diff_stats.py +++ b/scripts/gas_diff_stats.py @@ -114,7 +114,16 @@ def parse_git_diff(fname): return collect_statistics(diff_output) def stat(old, new): - return ((new - old) / old) * 100 if old else 0 + if old == 0: + return '' + percentage = (new - old) / old * 100 + prefix = ( + # Distinguish actual zero from very small differences + '+' if round(percentage) == 0 and percentage > 0 else + '-' if round(percentage) == 0 and percentage < 0 else + '' + ) + return f'{prefix}{round(percentage)}%' table = [] @@ -129,12 +138,12 @@ def stat(old, new): ir_optimized = stat(parsed[0], parsed[3]) legacy_optimized = stat(parsed[1], parsed[4]) legacy = stat(parsed[2], parsed[5]) - fname = fname.split('/', 3)[-1] - table += [map(str, [fname, ir_optimized, legacy_optimized, legacy])] + fname = f"`{fname.split('/', 3)[-1]}`" + table += [[fname, ir_optimized, legacy_optimized, legacy]] if table: print("
Click for a table of gas differences\n") - table_header = ["File name", "IR-optimized (%)", "Legacy-Optimized (%)", "Legacy (%)"] + table_header = ["File name", "IR optimized", "Legacy optimized", "Legacy"] print(tabulate(table, headers=table_header, tablefmt="github")) print("
") else: From b88d690c66b963282a77e214001b160873434ddd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Sun, 11 Feb 2024 14:16:33 +0100 Subject: [PATCH 0051/1022] gas_diff_stats.py: Order rows in a deterministic way (by file path) --- scripts/gas_diff_stats.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/gas_diff_stats.py b/scripts/gas_diff_stats.py index 0707b9857bc8..7403b391721c 100755 --- a/scripts/gas_diff_stats.py +++ b/scripts/gas_diff_stats.py @@ -144,7 +144,7 @@ def stat(old, new): if table: print("
Click for a table of gas differences\n") table_header = ["File name", "IR optimized", "Legacy optimized", "Legacy"] - print(tabulate(table, headers=table_header, tablefmt="github")) + print(tabulate(sorted(table), headers=table_header, tablefmt="github")) print("
") else: print("No differences found.") From 36f2d39282a9f951b0f4780193398f5084073874 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Sun, 11 Feb 2024 16:15:52 +0100 Subject: [PATCH 0052/1022] CI: Add a smoke test run for gas_diff_stats.py --- .circleci/config.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index e14a4ec78c6f..8a16effd0f6b 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -980,6 +980,9 @@ jobs: - run: name: Python unit tests command: python3 test/pyscriptTests.py + - run: + name: Smoke test for gas_diff_stats.py + command: scripts/gas_diff_stats.py - matrix_notify_failure_unless_pr t_win_pyscripts: From a851c59bb9c6f226cfb483767a73ebf8b79e8329 Mon Sep 17 00:00:00 2001 From: r0qs Date: Wed, 21 Feb 2024 20:52:11 +0100 Subject: [PATCH 0053/1022] Fix ENS external test ensuring it applies memory-safe-assembly filter on files and not directories --- test/externalTests/ens.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/externalTests/ens.sh b/test/externalTests/ens.sh index aee291a1a468..178f468549a5 100755 --- a/test/externalTests/ens.sh +++ b/test/externalTests/ens.sh @@ -81,7 +81,7 @@ function ens_test sed -i "s|it\(('Cannot be called if CANNOT_CREATE_SUBDOMAIN is burned and is a new subdomain',\)|it.skip\1|g" test/wrapper/NameWrapper.js sed -i "s|it\(('Cannot be called if PARENT_CANNOT_CONTROL is burned and is an existing subdomain',\)|it.skip\1|g" test/wrapper/NameWrapper.js - find . -name "*.sol" -exec sed -i -e 's/^\(\s*\)\(assembly\)/\1\/\/\/ @solidity memory-safe-assembly\n\1\2/' '{}' \; + find . -name "*.sol" -type f -exec sed -i -e 's/^\(\s*\)\(assembly\)/\1\/\/\/ @solidity memory-safe-assembly\n\1\2/' '{}' \; for preset in $SELECTED_PRESETS; do hardhat_run_test "$config_file" "$preset" "${compile_only_presets[*]}" compile_fn test_fn From d7aa37de2eaa20e5463d2a266d8804c5fa2c80e4 Mon Sep 17 00:00:00 2001 From: r0qs Date: Tue, 20 Feb 2024 18:35:07 +0100 Subject: [PATCH 0054/1022] Use latest release instead of main branch on external tests --- scripts/externalTests/common.sh | 39 +++++++++++++------------ scripts/externalTests/runners/base.py | 3 +- scripts/externalTests/test_helpers.py | 40 +++++++++++++++----------- test/externalTests/bleeps.sh | 3 +- test/externalTests/brink.sh | 12 ++------ test/externalTests/chainlink.sh | 3 +- test/externalTests/colony.sh | 3 +- test/externalTests/elementfi.sh | 5 ++-- test/externalTests/ens.sh | 3 +- test/externalTests/euler.sh | 3 +- test/externalTests/gnosis.sh | 6 ++-- test/externalTests/gp2.sh | 15 ++-------- test/externalTests/perpetual-pools.sh | 3 +- test/externalTests/pool-together.sh | 8 ++---- test/externalTests/prb-math.py | 3 +- test/externalTests/trident.sh | 3 +- test/externalTests/uniswap.sh | 3 +- test/externalTests/yield-liquidator.sh | 3 +- test/externalTests/zeppelin.sh | 18 ++---------- 19 files changed, 68 insertions(+), 108 deletions(-) diff --git a/scripts/externalTests/common.sh b/scripts/externalTests/common.sh index 3bca968a5aa5..e49be6c8a0a9 100644 --- a/scripts/externalTests/common.sh +++ b/scripts/externalTests/common.sh @@ -106,25 +106,28 @@ function setup_solc function download_project { - local repo="$1" - local ref_type="$2" - local solcjs_ref="$3" - local test_dir="$4" - - [[ $ref_type == commit || $ref_type == branch || $ref_type == tag ]] || assertFail - - printLog "Cloning ${ref_type} ${solcjs_ref} of ${repo}..." - if [[ $ref_type == commit ]]; then - mkdir ext - cd ext - git init - git remote add origin "$repo" - git fetch --depth 1 origin "$solcjs_ref" - git reset --hard FETCH_HEAD - else - git clone --depth 1 "$repo" -b "$solcjs_ref" "$test_dir/ext" - cd ext + local repo_url="$1" + local ref="$2" + local test_dir="$3" + + printLog "Cloning ${repo_url}..." + # Clone the repo ignoring all blobs until needed by git. + # This allows access to commit history but with a fast initial clone + git clone --filter=blob:none "$repo_url" "$test_dir/ext" + cd "$test_dir/ext" + + # If the ref is '' try to use the latest tag as ref + # NOTE: Sadly this will not work with monorepos and may not always + # return the latest tag. + if [[ "$ref" == "" ]]; then + ref=$(git tag --sort=-v:refname | head --lines=1) fi + + [[ $ref != "" ]] || assertFail + + printLog "Using ref: ${ref}" + git checkout "$ref" + echo "Current commit hash: $(git rev-parse HEAD)" } diff --git a/scripts/externalTests/runners/base.py b/scripts/externalTests/runners/base.py index a79ed53442e9..c3807c528c38 100644 --- a/scripts/externalTests/runners/base.py +++ b/scripts/externalTests/runners/base.py @@ -47,7 +47,6 @@ class TestConfig: name: str repo_url: str - ref_type: str ref: str compile_only_presets: List[SettingsPreset] = field(default_factory=list) settings_presets: List[SettingsPreset] = field(default_factory=lambda: list(SettingsPreset)) @@ -134,7 +133,7 @@ def run_test(runner: BaseRunner): print(f"Using compiler version {solc_version}") # Download project - download_project(runner.test_dir, runner.config.repo_url, runner.config.ref_type, runner.config.ref) + download_project(runner.test_dir, runner.config.repo_url, runner.config.ref) # Configure run environment runner.setup_environment() diff --git a/scripts/externalTests/test_helpers.py b/scripts/externalTests/test_helpers.py index 9a573d50adf0..576db4429b05 100644 --- a/scripts/externalTests/test_helpers.py +++ b/scripts/externalTests/test_helpers.py @@ -96,23 +96,29 @@ def parse_command_line(description: str, args: List[str]): return arg_parser.parse_args(args) -def download_project(test_dir: Path, repo_url: str, ref_type: str = "branch", ref: str = "master"): - assert ref_type in ("commit", "branch", "tag") - - print(f"Cloning {ref_type} {ref} of {repo_url}...") - if ref_type == "commit": - os.mkdir(test_dir) - os.chdir(test_dir) - subprocess.run(["git", "init"], check=True) - subprocess.run(["git", "remote", "add", "origin", repo_url], check=True) - subprocess.run(["git", "fetch", "--depth", "1", "origin", ref], check=True) - subprocess.run(["git", "reset", "--hard", "FETCH_HEAD"], check=True) - else: - os.chdir(test_dir.parent) - subprocess.run(["git", "clone", "--no-progress", "--depth", "1", repo_url, "-b", ref, test_dir.resolve()], check=True) - if not test_dir.exists(): - raise RuntimeError("Failed to clone the project.") - os.chdir(test_dir) +def download_project(test_dir: Path, repo_url: str, ref: str = ""): + print(f"Cloning {repo_url}...") + # Clone the repo ignoring all blobs until needed by git. + # This allows access to commit history but with a fast initial clone + subprocess.run(["git", "clone", "--filter", "blob:none", repo_url, test_dir.resolve()], check=True) + if not test_dir.exists(): + raise RuntimeError("Failed to clone the project.") + os.chdir(test_dir) + + # If the ref is '' try to use the latest tag as ref + # NOTE: Sadly this will not work with monorepos and may not always + # return the latest tag. + if ref == "": + tags = subprocess.check_output( + ["git", "tag", "--sort", "-v:refname"], + encoding="ascii" + ).strip().split('\n') + if len(tags) == 0: + raise RuntimeError("Failed to retrieve latest release tag.") + ref = tags[0] + + print(f"Using ref: {ref}") + subprocess.run(["git", "checkout", ref], check=True) if (test_dir / ".gitmodules").exists(): subprocess.run(["git", "submodule", "update", "--init"], check=True) diff --git a/test/externalTests/bleeps.sh b/test/externalTests/bleeps.sh index 30f0ec9240b9..5090e6c12e92 100755 --- a/test/externalTests/bleeps.sh +++ b/test/externalTests/bleeps.sh @@ -38,7 +38,6 @@ function test_fn { HARDHAT_DEPLOY_FIXTURE=true npx --no hardhat --no-compile tes function bleeps_test { local repo="https://github.com/wighawag/bleeps" - local ref_type=branch local ref=main local config_file="hardhat.config.ts" local config_var=config @@ -58,7 +57,7 @@ function bleeps_test print_presets_or_exit "$SELECTED_PRESETS" setup_solc "$DIR" "$BINARY_TYPE" "$BINARY_PATH" - download_project "$repo" "$ref_type" "$ref" "$DIR" + download_project "$repo" "$ref" "$DIR" pushd "common-lib/" neutralize_package_json_hooks diff --git a/test/externalTests/brink.sh b/test/externalTests/brink.sh index 1c3ad2e19a13..48cc4028f3d7 100755 --- a/test/externalTests/brink.sh +++ b/test/externalTests/brink.sh @@ -37,8 +37,7 @@ function test_fn { SNAPSHOT_UPDATE=1 npx --no hardhat test; } function brink_test { local repo="https://github.com/brinktrade/brink-core" - local ref_type=branch - local ref=master + local ref="" local config_file="hardhat.config.js" local config_var="" local extra_settings="metadata: {bytecodeHash: 'none'}" @@ -60,25 +59,18 @@ function brink_test print_presets_or_exit "$SELECTED_PRESETS" setup_solc "$DIR" "$BINARY_TYPE" "$BINARY_PATH" - download_project "$repo" "$ref_type" "$ref" "$DIR" + download_project "$repo" "$ref" "$DIR" # TODO: Remove this when Brink merges https://github.com/brinktrade/brink-core/pull/52 sed -i "s|\(function isValidSignature(bytes \)calldata\( _data, bytes \)calldata\( _signature)\)|\1memory\2memory\3|g" src/Test/MockEIP1271Validator.sol - neutralize_package_lock neutralize_package_json_hooks force_hardhat_compiler_binary "$config_file" "$BINARY_TYPE" "$BINARY_PATH" force_hardhat_compiler_settings "$config_file" "$(first_word "$SELECTED_PRESETS")" "$config_var" "$CURRENT_EVM_VERSION" "$extra_settings" "$extra_optimizer_settings" yarn install yarn add hardhat-gas-reporter - # TODO: Remove when https://github.com/brinktrade/brink-core/issues/48 is fixed. - # TODO: Chai is ESM-only since version 5.x (see: https://github.com/chaijs/chai/issues/1561#issuecomment-1871134261), - # thus, we should stick to version 4.x until Brink and other dependencies also migrate to ESM. - yarn add chai@4.4.0 - replace_version_pragmas - for preset in $SELECTED_PRESETS; do hardhat_run_test "$config_file" "$preset" "${compile_only_presets[*]}" compile_fn test_fn "$config_var" "$extra_settings" "$extra_optimizer_settings" store_benchmark_report hardhat brink "$repo" "$preset" diff --git a/test/externalTests/chainlink.sh b/test/externalTests/chainlink.sh index 4d5080730f80..f11156713c76 100755 --- a/test/externalTests/chainlink.sh +++ b/test/externalTests/chainlink.sh @@ -37,7 +37,6 @@ function test_fn { yarn test; } function chainlink_test { local repo="https://github.com/solidity-external-tests/chainlink" - local ref_type=branch local ref=develop_080 local config_file="hardhat.config.ts" local config_var=config @@ -58,7 +57,7 @@ function chainlink_test print_presets_or_exit "$SELECTED_PRESETS" setup_solc "$DIR" "$BINARY_TYPE" "$BINARY_PATH" - download_project "$repo" "$ref_type" "$ref" "$DIR" + download_project "$repo" "$ref" "$DIR" cd "contracts/" diff --git a/test/externalTests/colony.sh b/test/externalTests/colony.sh index 402865107a8d..1dcd7deaa399 100755 --- a/test/externalTests/colony.sh +++ b/test/externalTests/colony.sh @@ -37,7 +37,6 @@ function test_fn { yarn run test:contracts; } function colony_test { local repo="https://github.com/solidity-external-tests/colonyNetwork.git" - local ref_type=branch local ref="develop_080" local config_file="truffle.js" @@ -57,7 +56,7 @@ function colony_test print_presets_or_exit "$SELECTED_PRESETS" setup_solc "$DIR" "$BINARY_TYPE" "$BINARY_PATH" - download_project "$repo" "$ref_type" "$ref" "$DIR" + download_project "$repo" "$ref" "$DIR" [[ $BINARY_TYPE == native ]] && replace_global_solc "$BINARY_PATH" neutralize_package_json_hooks diff --git a/test/externalTests/elementfi.sh b/test/externalTests/elementfi.sh index 94e622d10c5a..f3ecbb14170f 100755 --- a/test/externalTests/elementfi.sh +++ b/test/externalTests/elementfi.sh @@ -37,8 +37,7 @@ function test_fn { npm run test; } function elementfi_test { local repo="https://github.com/element-fi/elf-contracts" - local ref_type=branch - local ref=main + local ref="" local config_file="hardhat.config.ts" local config_var=config @@ -60,7 +59,7 @@ function elementfi_test print_presets_or_exit "$SELECTED_PRESETS" setup_solc "$DIR" "$BINARY_TYPE" "$BINARY_PATH" - download_project "$repo" "$ref_type" "$ref" "$DIR" + download_project "$repo" "$ref" "$DIR" chmod +x scripts/load-balancer-contracts.sh scripts/load-balancer-contracts.sh diff --git a/test/externalTests/ens.sh b/test/externalTests/ens.sh index aee291a1a468..a79d26c4efb7 100755 --- a/test/externalTests/ens.sh +++ b/test/externalTests/ens.sh @@ -37,7 +37,6 @@ function test_fn { yarn test; } function ens_test { local repo="https://github.com/ensdomains/ens-contracts.git" - local ref_type=commit local ref="083d29a2c50cd0a8307386abf8fadc217b256256" local config_file="hardhat.config.js" @@ -57,7 +56,7 @@ function ens_test print_presets_or_exit "$SELECTED_PRESETS" setup_solc "$DIR" "$BINARY_TYPE" "$BINARY_PATH" - download_project "$repo" "$ref_type" "$ref" "$DIR" + download_project "$repo" "$ref" "$DIR" neutralize_package_lock neutralize_package_json_hooks diff --git a/test/externalTests/euler.sh b/test/externalTests/euler.sh index 80f18e702d92..9ede1a340673 100755 --- a/test/externalTests/euler.sh +++ b/test/externalTests/euler.sh @@ -40,7 +40,6 @@ function test_fn { function euler_test { local repo="https://github.com/euler-xyz/euler-contracts" - local ref_type=branch local ref="master" local config_file="hardhat.config.js" @@ -59,7 +58,7 @@ function euler_test print_presets_or_exit "$SELECTED_PRESETS" setup_solc "$DIR" "$BINARY_TYPE" "$BINARY_PATH" - download_project "$repo" "$ref_type" "$ref" "$DIR" + download_project "$repo" "$ref" "$DIR" # Disable tests that won't pass on the ir presets due to Hardhat heuristics. Note that this also disables # them for other presets but that's fine - we want same code run for benchmarks to be comparable. diff --git a/test/externalTests/gnosis.sh b/test/externalTests/gnosis.sh index 5f7ea4876527..218a5a7504b5 100755 --- a/test/externalTests/gnosis.sh +++ b/test/externalTests/gnosis.sh @@ -37,8 +37,7 @@ function test_fn { npm test; } function gnosis_safe_test { local repo="https://github.com/safe-global/safe-contracts.git" - local ref_type=branch - local ref=main + local ref="" local config_file="hardhat.config.ts" local config_var=userConfig @@ -58,7 +57,7 @@ function gnosis_safe_test print_presets_or_exit "$SELECTED_PRESETS" setup_solc "$DIR" "$BINARY_TYPE" "$BINARY_PATH" - download_project "$repo" "$ref_type" "$ref" "$DIR" + download_project "$repo" "$ref" "$DIR" [[ $BINARY_TYPE == native ]] && replace_global_solc "$BINARY_PATH" # NOTE: The patterns below intentionally have hard-coded versions. @@ -77,7 +76,6 @@ function gnosis_safe_test sed -i "s|\(it\)\((\"can be used only via DELEGATECALL opcode\"\)|\1.skip\2|g" test/libraries/SignMessageLib.spec.ts sed -i "s|it\((\"can only be called from Safe itself\"\)|it.skip\1|g" test/libraries/Migration.spec.ts - neutralize_package_lock neutralize_package_json_hooks force_hardhat_compiler_binary "$config_file" "$BINARY_TYPE" "$BINARY_PATH" force_hardhat_compiler_settings "$config_file" "$(first_word "$SELECTED_PRESETS")" "$config_var" diff --git a/test/externalTests/gp2.sh b/test/externalTests/gp2.sh index bbb442226f62..1e52134a43de 100755 --- a/test/externalTests/gp2.sh +++ b/test/externalTests/gp2.sh @@ -37,8 +37,7 @@ function test_fn { yarn test; } function gp2_test { local repo="https://github.com/cowprotocol/contracts.git" - local ref_type=branch - local ref=main + local ref="" local config_file="hardhat.config.ts" local config_var="config" @@ -58,10 +57,9 @@ function gp2_test print_presets_or_exit "$SELECTED_PRESETS" setup_solc "$DIR" "$BINARY_TYPE" "$BINARY_PATH" - download_project "$repo" "$ref_type" "$ref" "$DIR" + download_project "$repo" "$ref" "$DIR" [[ $BINARY_TYPE == native ]] && replace_global_solc "$BINARY_PATH" - neutralize_package_lock neutralize_package_json_hooks name_hardhat_default_export "$config_file" "$config_var" force_hardhat_compiler_binary "$config_file" "$BINARY_TYPE" "$BINARY_PATH" @@ -69,14 +67,6 @@ function gp2_test force_hardhat_unlimited_contract_size "$config_file" "$config_var" yarn - # Workaround for error caused by the last release of hardhat-waffle@2.0.6 that bumps ethereum-waffle - # to version 4.0.10 and breaks gp2 build with the following error: - # - # Cannot find module 'ethereum-waffle/dist/cjs/src/deployContract' - # - # See: https://github.com/NomicFoundation/hardhat-waffle/commit/83ee9cb36ee59d0bedacbbd00043f030af104ad0 - yarn add '@nomiclabs/hardhat-waffle@2.0.5' - # Some dependencies come with pre-built artifacts. We want to build from scratch. rm -r node_modules/@gnosis.pm/safe-contracts/build/ @@ -104,7 +94,6 @@ function gp2_test sed -i 's|it\(("should revert when encoding invalid flags"\)|it.skip\1|g' test/GPv2Trade.test.ts replace_version_pragmas - for preset in $SELECTED_PRESETS; do hardhat_run_test "$config_file" "$preset" "${compile_only_presets[*]}" compile_fn test_fn "$config_var" store_benchmark_report hardhat gp2 "$repo" "$preset" diff --git a/test/externalTests/perpetual-pools.sh b/test/externalTests/perpetual-pools.sh index 8d8dc34e212d..31748a40ca2a 100755 --- a/test/externalTests/perpetual-pools.sh +++ b/test/externalTests/perpetual-pools.sh @@ -37,7 +37,6 @@ function test_fn { yarn test; } function perpetual_pools_test { local repo="https://github.com/solidity-external-tests/perpetual-pools-contracts" - local ref_type=branch local ref=pools-v2 local config_file="hardhat.config.ts" local config_var="config" @@ -57,7 +56,7 @@ function perpetual_pools_test print_presets_or_exit "$SELECTED_PRESETS" setup_solc "$DIR" "$BINARY_TYPE" "$BINARY_PATH" - download_project "$repo" "$ref_type" "$ref" "$DIR" + download_project "$repo" "$ref" "$DIR" # Disable tests that won't pass on the ir presets due to Hardhat heuristics. Note that this also disables # them for other presets but that's fine - we want same code run for benchmarks to be comparable. diff --git a/test/externalTests/pool-together.sh b/test/externalTests/pool-together.sh index 3f7141d9bade..f841206ef2a9 100755 --- a/test/externalTests/pool-together.sh +++ b/test/externalTests/pool-together.sh @@ -36,9 +36,8 @@ function test_fn { yarn test; } function pool_together_test { - local repo="https://github.com/pooltogether/v4-core" - local ref_type=branch - local ref=master + local repo="https://github.com/pooltogether/v4-core.git" + local ref="" local config_file="hardhat.config.ts" local config_var="config" @@ -57,13 +56,12 @@ function pool_together_test print_presets_or_exit "$SELECTED_PRESETS" setup_solc "$DIR" "$BINARY_TYPE" "$BINARY_PATH" - download_project "$repo" "$ref_type" "$ref" "$DIR" + download_project "$repo" "$ref" "$DIR" # TODO: Remove this when https://github.com/NomicFoundation/hardhat/issues/3365 gets fixed. sed -i "s|it\(('should fail to return value if value passed does not fit in [0-9]\+ bits'\)|it.skip\1|g" test/libraries/ExtendedSafeCast.test.ts sed -i "s|it\(('should require an rng to be requested'\)|it.skip\1|g" test/DrawBeacon.test.ts - neutralize_package_lock neutralize_package_json_hooks force_hardhat_compiler_binary "$config_file" "$BINARY_TYPE" "$BINARY_PATH" force_hardhat_compiler_settings "$config_file" "$(first_word "$SELECTED_PRESETS")" "$config_var" diff --git a/test/externalTests/prb-math.py b/test/externalTests/prb-math.py index e57688ec2e38..2d1469fc9015 100755 --- a/test/externalTests/prb-math.py +++ b/test/externalTests/prb-math.py @@ -51,8 +51,7 @@ def configure(self): test_config = TestConfig( name="PRBMath", repo_url="https://github.com/PaulRBerg/prb-math.git", - ref_type="branch", - ref="main", + ref="", compile_only_presets=[ # pylint: disable=line-too-long # SettingsPreset.IR_NO_OPTIMIZE, # Error: Yul exception:Variable expr_15699_address is 2 slot(s) too deep inside the stack. Stack too deep. diff --git a/test/externalTests/trident.sh b/test/externalTests/trident.sh index d8d94eb3c101..e5fa914e9cb8 100755 --- a/test/externalTests/trident.sh +++ b/test/externalTests/trident.sh @@ -45,7 +45,6 @@ function test_fn { function trident_test { local repo="https://github.com/sushiswap/trident" - local ref_type=commit # FIXME: Switch back to master branch when https://github.com/sushiswap/trident/issues/303 gets fixed. local ref="0cab5ae884cc9a41223d52791be775c3a053cb26" # master as of 2021-12-16 local config_file="hardhat.config.ts" @@ -66,7 +65,7 @@ function trident_test print_presets_or_exit "$SELECTED_PRESETS" setup_solc "$DIR" "$BINARY_TYPE" "$BINARY_PATH" - download_project "$repo" "$ref_type" "$ref" "$DIR" + download_project "$repo" "$ref" "$DIR" # TODO: Currently tests work only with the exact versions from yarn.lock. # Re-enable this when https://github.com/sushiswap/trident/issues/284 is fixed. diff --git a/test/externalTests/uniswap.sh b/test/externalTests/uniswap.sh index 8d2551b61920..bf5f828987eb 100755 --- a/test/externalTests/uniswap.sh +++ b/test/externalTests/uniswap.sh @@ -37,7 +37,6 @@ function test_fn { UPDATE_SNAPSHOT=1 npx hardhat test; } function uniswap_test { local repo="https://github.com/solidity-external-tests/uniswap-v3-core.git" - local ref_type=branch local ref=main_080 local config_file="hardhat.config.ts" local config_var=config @@ -57,7 +56,7 @@ function uniswap_test print_presets_or_exit "$SELECTED_PRESETS" setup_solc "$DIR" "$BINARY_TYPE" "$BINARY_PATH" - download_project "$repo" "$ref_type" "$ref" "$DIR" + download_project "$repo" "$ref" "$DIR" # Disable tests that won't pass on the ir presets due to Hardhat heuristics. Note that this also disables # them for other presets but that's fine - we want same code run for benchmarks to be comparable. diff --git a/test/externalTests/yield-liquidator.sh b/test/externalTests/yield-liquidator.sh index 7a4353af578e..16a6287e53dd 100755 --- a/test/externalTests/yield-liquidator.sh +++ b/test/externalTests/yield-liquidator.sh @@ -37,7 +37,6 @@ function test_fn { npm run test; } function yield_liquidator_test { local repo="https://github.com/yieldprotocol/yield-liquidator-v2" - local ref_type=branch local ref="master" local config_file="hardhat.config.ts" local config_var="module.exports" @@ -57,7 +56,7 @@ function yield_liquidator_test print_presets_or_exit "$SELECTED_PRESETS" setup_solc "$DIR" "$BINARY_TYPE" "$BINARY_PATH" - download_project "$repo" "$ref_type" "$ref" "$DIR" + download_project "$repo" "$ref" "$DIR" neutralize_package_lock neutralize_package_json_hooks diff --git a/test/externalTests/zeppelin.sh b/test/externalTests/zeppelin.sh index 9f72aa4ec958..655e4814f783 100755 --- a/test/externalTests/zeppelin.sh +++ b/test/externalTests/zeppelin.sh @@ -42,8 +42,7 @@ function test_fn { npm test; } function zeppelin_test { local repo="https://github.com/OpenZeppelin/openzeppelin-contracts.git" - local ref_type=branch - local ref="master" + local ref="" local config_file="hardhat.config.js" local compile_only_presets=( @@ -62,7 +61,7 @@ function zeppelin_test print_presets_or_exit "$SELECTED_PRESETS" setup_solc "$DIR" "$BINARY_TYPE" "$BINARY_PATH" - download_project "$repo" "$ref_type" "$ref" "$DIR" + download_project "$repo" "$ref" "$DIR" # Disable tests that won't pass on the ir presets due to Hardhat heuristics. Note that this also disables # them for other presets but that's fine - we want same code run for benchmarks to be comparable. @@ -100,25 +99,12 @@ function zeppelin_test # Here only the testToInt(248) and testToInt(256) cases fail so change the loop range to skip them sed -i "s|range(8, 256, 8)\(.forEach(bits => testToInt(bits));\)|range(8, 240, 8)\1|" test/utils/math/SafeCast.test.js - neutralize_package_lock neutralize_package_json_hooks force_hardhat_compiler_binary "$config_file" "$BINARY_TYPE" "$BINARY_PATH" force_hardhat_compiler_settings "$config_file" "$(first_word "$SELECTED_PRESETS")" npm install - # TODO: We fix the version to 2.0.3 instead of 2.0.4 since the latter does not work with ethers.js 6.10.0 - # Maybe related to the use of dynamic imports here: https://github.com/NomicFoundation/hardhat/commit/16ae15642951ac324ef7093a3342f7cf3a2a49a4 - npm install @nomicfoundation/hardhat-chai-matchers@2.0.3 - - # TODO: Remove when OpenZeppelin update to ethers 6.11.1+ - # Prior versions of ethers accepts an object instead of a string as an argument to the toUtf8Bytes function. - # However, starting from Ethers version 6.11.1, string arguments are enforced, - # which causes the introduced assertion to fail in some OpenZeppelin tests. - # See: https://github.com/ethers-io/ethers.js/issues/4583 - npm install ethers@6.11.0 - replace_version_pragmas - for preset in $SELECTED_PRESETS; do hardhat_run_test "$config_file" "$preset" "${compile_only_presets[*]}" compile_fn test_fn store_benchmark_report hardhat zeppelin "$repo" "$preset" From a9a870d8fc87e43e89467cabfe9c6b84217c715b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Wed, 7 Feb 2024 14:53:31 +0100 Subject: [PATCH 0055/1022] Test coverage for existing parsing and formatting functionality of gas expectations --- test/libsolidity/util/TestFileParserTests.cpp | 70 +++++++++++++++---- .../util/TestFunctionCallTests.cpp | 28 ++++++++ 2 files changed, 86 insertions(+), 12 deletions(-) diff --git a/test/libsolidity/util/TestFileParserTests.cpp b/test/libsolidity/util/TestFileParserTests.cpp index 59934fdb25cc..46499c14751b 100644 --- a/test/libsolidity/util/TestFileParserTests.cpp +++ b/test/libsolidity/util/TestFileParserTests.cpp @@ -49,18 +49,18 @@ std::vector parse(std::string const& _source, std::map _rawArguments = std::vector{}, - bool _isConstructor = false, - bool _isLibrary = false + FunctionCall const& _call, + FunctionCall::DisplayMode _mode, + std::string _signature = "", + bool _failure = true, + bytes _arguments = bytes{}, + bytes _expectations = bytes{}, + FunctionValue _value = { 0 }, + std::string _argumentComment = "", + std::string _expectationComment = "", + std::vector _rawArguments = std::vector{}, + bool _isConstructor = false, + bool _isLibrary = false ) { BOOST_REQUIRE_EQUAL(_call.expectations.failure, _failure); @@ -1063,6 +1063,52 @@ BOOST_AUTO_TEST_CASE(call_effects) BOOST_CHECK_THROW(parse(source, builtins), std::exception); } +BOOST_AUTO_TEST_CASE(gas) +{ + char const* source = R"( + // f() -> + // gas ir: 3245 + // gas legacy: 5000 + // gas legacyOptimized: 0 + )"; + auto const calls = parse(source); + BOOST_REQUIRE_EQUAL(calls.size(), 1); + BOOST_REQUIRE_EQUAL(calls[0].expectations.failure, false); + BOOST_TEST(calls[0].expectations.gasUsed == (std::map{ + {"ir", 3245}, + {"legacy", 5000}, + {"legacyOptimized", 0}, + })); +} + +BOOST_AUTO_TEST_CASE(gas_before_call) +{ + char const* source = R"( + // gas ir: 3245 + // f() -> + )"; + BOOST_REQUIRE_THROW(parse(source), TestParserError); +} + +BOOST_AUTO_TEST_CASE(gas_invalid_run_type) +{ + char const* source = R"( + // f() -> + // gas ir: 3245 + // gas experimental: 5000 + )"; + BOOST_REQUIRE_THROW(parse(source), TestParserError); +} + +BOOST_AUTO_TEST_CASE(gas_duplicate_run_type) +{ + char const* source = R"( + // f() -> + // gas ir: 3245 + // gas ir: 3245 + )"; + BOOST_REQUIRE_THROW(parse(source), TestParserError); +} BOOST_AUTO_TEST_SUITE_END() } diff --git a/test/libsolidity/util/TestFunctionCallTests.cpp b/test/libsolidity/util/TestFunctionCallTests.cpp index fa3fe995cac5..74a45c32687e 100644 --- a/test/libsolidity/util/TestFunctionCallTests.cpp +++ b/test/libsolidity/util/TestFunctionCallTests.cpp @@ -250,6 +250,34 @@ BOOST_AUTO_TEST_CASE(format_failure_singleline) BOOST_REQUIRE_EQUAL(test.format(), "// f(uint8): 1 -> FAILURE"); } +BOOST_AUTO_TEST_CASE(format_gas) +{ + FunctionCall call{ + "f()", + FunctionValue{0}, + FunctionCallArgs{}, + FunctionCallExpectations{ + std::vector{}, + false, // failure + "some comment", + { + {"ir", 3245}, + {"legacy", 5000}, + {"legacy optimized", 0}, + }, + } + }; + call.omitsArrow = false; + + BOOST_REQUIRE_EQUAL( + TestFunctionCall(call).format(), + "// f() -> #some comment#\n" + "// gas ir: 3245\n" + "// gas legacy: 5000\n" + "// gas legacy optimized: 0" + ); +} + BOOST_AUTO_TEST_SUITE_END() } From e47e948ff6d1319660b98d1502eff44356c303aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Sun, 11 Feb 2024 13:07:13 +0100 Subject: [PATCH 0056/1022] SoltesTypes: Fix outdated comment about allowed keys in gasUsed --- test/libsolidity/util/SoltestTypes.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/libsolidity/util/SoltestTypes.h b/test/libsolidity/util/SoltestTypes.h index b5b746e325e5..672e705534ce 100644 --- a/test/libsolidity/util/SoltestTypes.h +++ b/test/libsolidity/util/SoltestTypes.h @@ -216,7 +216,9 @@ struct FunctionCallExpectations return raw; } /// Gas used by function call - /// Should have values for Yul, YulOptimized, Legacy and LegacyOptimized + /// Keys represent all distinct combinations of compilation settings that affect produced + /// bytecode (and therefore the cost), except for EVM version. E.g. IR codegen without + /// optimization legacy codegen with optimization. std::map gasUsed; }; From d98c9438b2779ad554a179ca2d537d3da2dda33b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Wed, 7 Feb 2024 18:39:44 +0100 Subject: [PATCH 0057/1022] TestFunctionCall::formatGasExpectations(): runType can't be empty in practice --- test/libsolidity/util/TestFunctionCall.cpp | 43 +++++++++++----------- 1 file changed, 22 insertions(+), 21 deletions(-) diff --git a/test/libsolidity/util/TestFunctionCall.cpp b/test/libsolidity/util/TestFunctionCall.cpp index 64dfbd98253e..716dbff13b44 100644 --- a/test/libsolidity/util/TestFunctionCall.cpp +++ b/test/libsolidity/util/TestFunctionCall.cpp @@ -339,27 +339,28 @@ std::string TestFunctionCall::formatGasExpectations( { std::stringstream os; for (auto const& [runType, gasUsed]: (_useActualCost ? m_gasCosts : m_call.expectations.gasUsed)) - if (!runType.empty()) - { - bool differentResults = - m_gasCosts.count(runType) > 0 && - m_call.expectations.gasUsed.count(runType) > 0 && - m_gasCosts.at(runType) != m_call.expectations.gasUsed.at(runType); - - s256 difference = 0; - if (differentResults) - difference = - static_cast(m_gasCosts.at(runType)) - - static_cast(m_call.expectations.gasUsed.at(runType)); - int percent = 0; - if (differentResults) - percent = static_cast( - 100.0 * (static_cast(difference) / static_cast(m_call.expectations.gasUsed.at(runType))) - ); - os << std::endl << _linePrefix << "// gas " << runType << ": " << (gasUsed.str()); - if (_showDifference && differentResults && _useActualCost) - os << " [" << std::showpos << difference << " (" << percent << "%)]"; - } + { + soltestAssert(runType != ""); + + bool differentResults = + m_gasCosts.count(runType) > 0 && + m_call.expectations.gasUsed.count(runType) > 0 && + m_gasCosts.at(runType) != m_call.expectations.gasUsed.at(runType); + + s256 difference = 0; + if (differentResults) + difference = + static_cast(m_gasCosts.at(runType)) - + static_cast(m_call.expectations.gasUsed.at(runType)); + int percent = 0; + if (differentResults) + percent = static_cast( + 100.0 * (static_cast(difference) / static_cast(m_call.expectations.gasUsed.at(runType))) + ); + os << std::endl << _linePrefix << "// gas " << runType << ": " << (gasUsed.str()); + if (_showDifference && differentResults && _useActualCost) + os << " [" << std::showpos << difference << " (" << percent << "%)]"; + } return os.str(); } From c55c8b5504fdb8789741883e5af6f890be2b5cb7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Wed, 7 Feb 2024 19:42:41 +0100 Subject: [PATCH 0058/1022] TestFunctionCall::formatGasExpectations(): Move diffing into a helper --- test/libsolidity/util/TestFunctionCall.cpp | 43 +++++++++++++--------- 1 file changed, 25 insertions(+), 18 deletions(-) diff --git a/test/libsolidity/util/TestFunctionCall.cpp b/test/libsolidity/util/TestFunctionCall.cpp index 716dbff13b44..1d8c72191979 100644 --- a/test/libsolidity/util/TestFunctionCall.cpp +++ b/test/libsolidity/util/TestFunctionCall.cpp @@ -21,6 +21,7 @@ #include +#include #include #include #include @@ -331,6 +332,23 @@ std::string TestFunctionCall::formatRawParameters( return os.str(); } +namespace +{ + +std::string formatGasDiff(std::optional const& _gasUsed, std::optional const& _reference) +{ + if (!_reference.has_value() || !_gasUsed.has_value() || _gasUsed == _reference) + return ""; + + s256 difference = static_cast(*_gasUsed) - static_cast(*_reference); + int percent = static_cast( + 100.0 * (static_cast(difference) / static_cast(*_reference)) + ); + return fmt::format("{} ({:+}%)", difference.str(), percent); +} + +} + std::string TestFunctionCall::formatGasExpectations( std::string const& _linePrefix, bool _useActualCost, @@ -342,24 +360,13 @@ std::string TestFunctionCall::formatGasExpectations( { soltestAssert(runType != ""); - bool differentResults = - m_gasCosts.count(runType) > 0 && - m_call.expectations.gasUsed.count(runType) > 0 && - m_gasCosts.at(runType) != m_call.expectations.gasUsed.at(runType); - - s256 difference = 0; - if (differentResults) - difference = - static_cast(m_gasCosts.at(runType)) - - static_cast(m_call.expectations.gasUsed.at(runType)); - int percent = 0; - if (differentResults) - percent = static_cast( - 100.0 * (static_cast(difference) / static_cast(m_call.expectations.gasUsed.at(runType))) - ); - os << std::endl << _linePrefix << "// gas " << runType << ": " << (gasUsed.str()); - if (_showDifference && differentResults && _useActualCost) - os << " [" << std::showpos << difference << " (" << percent << "%)]"; + os << std::endl << _linePrefix << "// gas " << runType << ": " << gasUsed.str(); + std::string gasDiff = formatGasDiff( + m_gasCosts.count(runType) > 0 ? std::make_optional(m_gasCosts.at(runType)) : std::nullopt, + m_call.expectations.gasUsed.count(runType) > 0 ? std::make_optional(m_call.expectations.gasUsed.at(runType)) : std::nullopt + ); + if (_showDifference && !gasDiff.empty() && _useActualCost) + os << " [" << gasDiff << "]"; } return os.str(); } From cd94139f3f666ea3087122a46ab8b461722bd4fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Wed, 7 Feb 2024 19:51:57 +0100 Subject: [PATCH 0059/1022] TestFunctionCall::formatGasExpectations(): Handle corner cases properly --- test/libsolidity/util/TestFunctionCall.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/test/libsolidity/util/TestFunctionCall.cpp b/test/libsolidity/util/TestFunctionCall.cpp index 1d8c72191979..7a77f7287928 100644 --- a/test/libsolidity/util/TestFunctionCall.cpp +++ b/test/libsolidity/util/TestFunctionCall.cpp @@ -340,7 +340,13 @@ std::string formatGasDiff(std::optional const& _gasUsed, std::optional(*_gasUsed) - static_cast(*_reference); + + if (*_reference == 0) + return fmt::format("{}", difference.str()); + int percent = static_cast( 100.0 * (static_cast(difference) / static_cast(*_reference)) ); From d5bae3f5973c54395e450762ce8df25ba1dd3285 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Wed, 7 Feb 2024 20:00:19 +0100 Subject: [PATCH 0060/1022] TestFunctionCall::formatGasExpectations(): Helper for getting optional values from a map --- test/libsolidity/util/TestFunctionCall.cpp | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/test/libsolidity/util/TestFunctionCall.cpp b/test/libsolidity/util/TestFunctionCall.cpp index 7a77f7287928..54dd769d6116 100644 --- a/test/libsolidity/util/TestFunctionCall.cpp +++ b/test/libsolidity/util/TestFunctionCall.cpp @@ -353,6 +353,16 @@ std::string formatGasDiff(std::optional const& _gasUsed, std::optional gasOrNullopt(std::map const& _map, std::string const& _key) +{ + auto it = _map.find(_key); + if (it == _map.end()) + return std::nullopt; + + return it->second; +} + } std::string TestFunctionCall::formatGasExpectations( @@ -368,8 +378,8 @@ std::string TestFunctionCall::formatGasExpectations( os << std::endl << _linePrefix << "// gas " << runType << ": " << gasUsed.str(); std::string gasDiff = formatGasDiff( - m_gasCosts.count(runType) > 0 ? std::make_optional(m_gasCosts.at(runType)) : std::nullopt, - m_call.expectations.gasUsed.count(runType) > 0 ? std::make_optional(m_call.expectations.gasUsed.at(runType)) : std::nullopt + gasOrNullopt(m_gasCosts, runType), + gasOrNullopt(m_call.expectations.gasUsed, runType) ); if (_showDifference && !gasDiff.empty() && _useActualCost) os << " [" << gasDiff << "]"; From 2ee4d6b1eeaee104007a64ce0b23faa57862800d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Fri, 9 Feb 2024 19:24:34 +0100 Subject: [PATCH 0061/1022] Keep track of code deposit gas when executing contract code --- test/EVMHost.cpp | 7 ++++++- test/EVMHost.h | 7 +++++++ test/ExecutionFramework.cpp | 2 ++ test/ExecutionFramework.h | 6 ++++++ 4 files changed, 21 insertions(+), 1 deletion(-) diff --git a/test/EVMHost.cpp b/test/EVMHost.cpp index 9af4d7099dd2..c43d53d6bc43 100644 --- a/test/EVMHost.cpp +++ b/test/EVMHost.cpp @@ -161,6 +161,7 @@ void EVMHost::reset() recorded_calls.clear(); // Clear EIP-2929 account access indicator recorded_account_accesses.clear(); + m_totalCodeDepositGas = 0; // Mark all precompiled contracts as existing. Existing here means to have a balance (as per EIP-161). // NOTE: keep this in sync with `EVMHost::call` below. @@ -203,6 +204,7 @@ void EVMHost::newTransactionFrame() // Otherwise, the previous behavior (pre-Cancun) is maintained. accounts.erase(address); newlyCreatedAccounts.clear(); + m_totalCodeDepositGas = 0; recorded_selfdestructs.clear(); } @@ -392,15 +394,18 @@ evmc::Result EVMHost::call(evmc_message const& _message) noexcept if (message.kind == EVMC_CREATE || message.kind == EVMC_CREATE2) { - result.gas_left -= static_cast(evmasm::GasCosts::createDataGas * result.output_size); + int64_t codeDepositGas = static_cast(evmasm::GasCosts::createDataGas * result.output_size); + result.gas_left -= codeDepositGas; if (result.gas_left < 0) { + m_totalCodeDepositGas += -result.gas_left; result.gas_left = 0; result.status_code = EVMC_OUT_OF_GAS; // TODO clear some fields? } else { + m_totalCodeDepositGas += codeDepositGas; result.create_address = message.recipient; destination.code = evmc::bytes(result.output_data, result.output_data + result.output_size); destination.codehash = convertToEVMC(keccak256({result.output_data, result.output_size})); diff --git a/test/EVMHost.h b/test/EVMHost.h index 144596e05e38..848314c87974 100644 --- a/test/EVMHost.h +++ b/test/EVMHost.h @@ -94,6 +94,8 @@ class EVMHost: public evmc::MockedHost /// @returns contents of storage at @param _addr. StorageMap const& get_address_storage(evmc::address const& _addr); + u256 totalCodeDepositGas() const { return m_totalCodeDepositGas; } + static Address convertFromEVMC(evmc::address const& _addr); static evmc::address convertToEVMC(Address const& _addr); static util::h256 convertFromEVMC(evmc::bytes32 const& _data); @@ -137,6 +139,11 @@ class EVMHost: public evmc::MockedHost langutil::EVMVersion m_evmVersion; /// EVM version requested from EVMC (matches the above) evmc_revision m_evmRevision; + + /// The part of the total cost of the current transaction that paid for the code deposits. + /// I.e. GAS_CODE_DEPOSIT times the total size of deployed code of all newly created contracts, + /// including the current contract itself if it was a creation transaction. + u256 m_totalCodeDepositGas; }; class EVMHostPrinter diff --git a/test/ExecutionFramework.cpp b/test/ExecutionFramework.cpp index 9fc36440b336..0081ba4a9d27 100644 --- a/test/ExecutionFramework.cpp +++ b/test/ExecutionFramework.cpp @@ -191,6 +191,7 @@ void ExecutionFramework::sendMessage(bytes const& _data, bool _isCreation, u256 auto const gasRefund = std::min(u256(result.gas_refund), totalGasUsed / refundRatio); m_gasUsed = totalGasUsed - gasRefund; + m_gasUsedForCodeDeposit = m_evmcHost->totalCodeDepositGas(); m_transactionSuccessful = (result.status_code == EVMC_SUCCESS); if (m_showMessages) @@ -199,6 +200,7 @@ void ExecutionFramework::sendMessage(bytes const& _data, bool _isCreation, u256 std::cout << " result: " << static_cast(result.status_code) << std::endl; std::cout << " gas used: " << m_gasUsed.str() << std::endl; std::cout << " gas used (without refund): " << totalGasUsed.str() << std::endl; + std::cout << " code deposits only: " << m_gasUsedForCodeDeposit.str() << std::endl; std::cout << " gas refund (total): " << result.gas_refund << std::endl; std::cout << " gas refund (bound): " << gasRefund.str() << std::endl; } diff --git a/test/ExecutionFramework.h b/test/ExecutionFramework.h index 27ceb4f28033..5d66ea10d042 100644 --- a/test/ExecutionFramework.h +++ b/test/ExecutionFramework.h @@ -303,7 +303,13 @@ class ExecutionFramework util::h160 m_sender = account(0); util::h160 m_contractAddress; bytes m_output; + + /// Total gas used by the transaction, after refund. u256 m_gasUsed; + + /// The portion of @a m_gasUsed spent on code deposits of newly created contracts. + /// May exceed @a m_gasUsed in rare corner cases due to refunds. + u256 m_gasUsedForCodeDeposit; }; #define ABI_CHECK(result, expectation) do { \ From 96233864437e304b6c02c867b29ffe428a72c630 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Fri, 9 Feb 2024 19:27:07 +0100 Subject: [PATCH 0062/1022] Separate 'code' gas settings in semantic tests --- test/libsolidity/SemanticTest.cpp | 10 +- test/libsolidity/util/SoltestTypes.h | 5 + test/libsolidity/util/TestFileParser.cpp | 42 ++++++-- test/libsolidity/util/TestFileParserTests.cpp | 102 ++++++++++++++++++ test/libsolidity/util/TestFunctionCall.cpp | 22 ++++ test/libsolidity/util/TestFunctionCall.h | 9 +- .../util/TestFunctionCallTests.cpp | 65 ++++++++--- 7 files changed, 231 insertions(+), 24 deletions(-) diff --git a/test/libsolidity/SemanticTest.cpp b/test/libsolidity/SemanticTest.cpp index 25113b689d17..676c39eaf979 100644 --- a/test/libsolidity/SemanticTest.cpp +++ b/test/libsolidity/SemanticTest.cpp @@ -569,6 +569,11 @@ bool SemanticTest::checkGasCostExpectation(TestFunctionCall& io_test, bool _comp (_compileViaYul ? "ir"s : "legacy"s) + (m_optimiserSettings == OptimiserSettings::full() ? "Optimized" : ""); + soltestAssert( + io_test.call().expectations.gasUsed.count(setting) == + io_test.call().expectations.gasUsedForCodeDeposit.count(setting) + ); + // We don't check gas if enforce gas cost is not active // or test is run with abi encoder v1 only // or gas used less than threshold for enforcing feature @@ -587,9 +592,12 @@ bool SemanticTest::checkGasCostExpectation(TestFunctionCall& io_test, bool _comp solAssert(!m_runWithABIEncoderV1Only, ""); io_test.setGasCost(setting, m_gasUsed); + io_test.setCodeDepositGasCost(setting, m_gasUsedForCodeDeposit); + return io_test.call().expectations.gasUsed.count(setting) > 0 && - m_gasUsed == io_test.call().expectations.gasUsed.at(setting); + m_gasUsed == io_test.call().expectations.gasUsed.at(setting) && + m_gasUsedForCodeDeposit == io_test.call().expectations.gasUsedForCodeDeposit.at(setting); } void SemanticTest::printSource(std::ostream& _stream, std::string const& _linePrefix, bool _formatted) const diff --git a/test/libsolidity/util/SoltestTypes.h b/test/libsolidity/util/SoltestTypes.h index 672e705534ce..a2d593fd3c65 100644 --- a/test/libsolidity/util/SoltestTypes.h +++ b/test/libsolidity/util/SoltestTypes.h @@ -220,6 +220,11 @@ struct FunctionCallExpectations /// bytecode (and therefore the cost), except for EVM version. E.g. IR codegen without /// optimization legacy codegen with optimization. std::map gasUsed; + + /// The portion of @a gasUsed spent on code deposits of newly created contracts. + /// May exceed @a gasUsed in rare corner cases due to refunds. + /// Keys must always match @a gasUsedExcludingCode. + std::map gasUsedForCodeDeposit; }; /** diff --git a/test/libsolidity/util/TestFileParser.cpp b/test/libsolidity/util/TestFileParser.cpp index 3fba998a07bf..e7e20f7c5cb5 100644 --- a/test/libsolidity/util/TestFileParser.cpp +++ b/test/libsolidity/util/TestFileParser.cpp @@ -84,18 +84,31 @@ std::vector TestFileParser::parseFunctio BOOST_THROW_EXCEPTION(TestParserError("Expected function call before gas usage filter.")); std::string runType = m_scanner.currentLiteral(); - if (std::set{"ir", "irOptimized", "legacy", "legacyOptimized"}.count(runType) > 0) - { - m_scanner.scanNextToken(); - expect(Token::Colon); - if (calls.back().expectations.gasUsed.count(runType) > 0) - throw TestParserError("Gas usage expectation set multiple times."); - calls.back().expectations.gasUsed[runType] = u256(parseDecimalNumber()); - } - else + if (std::set{"ir", "irOptimized", "legacy", "legacyOptimized"}.count(runType) == 0) BOOST_THROW_EXCEPTION(TestParserError( "Expected \"ir\", \"irOptimized\", \"legacy\", or \"legacyOptimized\"." )); + m_scanner.scanNextToken(); + + bool isCodeDepositCost = false; + if (accept(Token::Identifier)) + { + if (m_scanner.currentLiteral() != "code") + BOOST_THROW_EXCEPTION(TestParserError("Expected \"code\" or \":\".")); + isCodeDepositCost = true; + m_scanner.scanNextToken(); + } + + expect(Token::Colon); + + std::map& gasExpectationMap = (isCodeDepositCost ? + calls.back().expectations.gasUsedForCodeDeposit : + calls.back().expectations.gasUsed + ); + if (gasExpectationMap.count(runType) > 0) + throw TestParserError("Gas usage expectation set multiple times."); + + gasExpectationMap[runType] = u256(parseDecimalNumber()); } else { @@ -189,6 +202,17 @@ std::vector TestFileParser::parseFunctio } } } + + for (FunctionCall& call: calls) + { + // Ensure that each specified gas expectation has both components to simplify working with them. + for (auto const& [runType, gas]: call.expectations.gasUsedForCodeDeposit) + call.expectations.gasUsed.try_emplace({runType, 0}); + + for (auto const& [runType, gas]: call.expectations.gasUsed) + call.expectations.gasUsedForCodeDeposit.try_emplace({runType, 0}); + } + return calls; } diff --git a/test/libsolidity/util/TestFileParserTests.cpp b/test/libsolidity/util/TestFileParserTests.cpp index 46499c14751b..7a794f915265 100644 --- a/test/libsolidity/util/TestFileParserTests.cpp +++ b/test/libsolidity/util/TestFileParserTests.cpp @@ -1079,6 +1079,11 @@ BOOST_AUTO_TEST_CASE(gas) {"legacy", 5000}, {"legacyOptimized", 0}, })); + BOOST_TEST(calls[0].expectations.gasUsedForCodeDeposit == (std::map{ + {"ir", 0}, + {"legacy", 0}, + {"legacyOptimized", 0}, + })); } BOOST_AUTO_TEST_CASE(gas_before_call) @@ -1109,6 +1114,103 @@ BOOST_AUTO_TEST_CASE(gas_duplicate_run_type) )"; BOOST_REQUIRE_THROW(parse(source), TestParserError); } + +BOOST_AUTO_TEST_CASE(gas_with_code_deposit_cost) +{ + char const* source = R"( + // f() -> + // gas legacyOptimized code: 1 + // gas ir: 13000 + // gas irOptimized: 6666 + // gas irOptimized code: 666 + // gas legacy code: 0 + // gas legacyOptimized: 2 + )"; + auto const calls = parse(source); + BOOST_REQUIRE_EQUAL(calls.size(), 1); + BOOST_REQUIRE_EQUAL(calls[0].expectations.failure, false); + BOOST_TEST(calls[0].expectations.gasUsed == (std::map{ + {"ir", 13000}, + {"irOptimized", 6666}, + {"legacy", 0}, + {"legacyOptimized", 2}, + })); + BOOST_TEST(calls[0].expectations.gasUsedForCodeDeposit == (std::map{ + {"ir", 0}, + {"irOptimized", 666}, + {"legacy", 0}, + {"legacyOptimized", 1}, + })); +} + +BOOST_AUTO_TEST_CASE(gas_with_code_deposit_cost_invalid_suffix) +{ + char const* source = R"( + // f() -> + // gas ir data: 3245 + )"; + BOOST_REQUIRE_THROW(parse(source), TestParserError); +} + +BOOST_AUTO_TEST_CASE(gas_with_code_deposit_cost_tokens_after_suffix) +{ + char const* source = R"( + // f() -> + // gas ir code code: 3245 + )"; + BOOST_REQUIRE_THROW(parse(source), TestParserError); +} + +BOOST_AUTO_TEST_CASE(gas_with_code_deposit_cost_double_code_gas) +{ + char const* source = R"( + // f() -> + // gas ir: 3245 + // gas ir code: 1 + // gas ir code: 1 + )"; + BOOST_REQUIRE_THROW(parse(source), TestParserError); +} + +BOOST_AUTO_TEST_CASE(gas_with_code_deposit_cost_negative_non_code_cost) +{ + // NOTE: This arrangement is unlikely but may still be possible due to refunds. + char const* source = R"( + // f() -> + // gas ir: 10 + // gas ir code: 20 + )"; + auto const calls = parse(source); + BOOST_REQUIRE_EQUAL(calls.size(), 1); + BOOST_REQUIRE_EQUAL(calls[0].expectations.failure, false); + BOOST_TEST(calls[0].expectations.gasUsed == (std::map{ + {"ir", 10}, + })); + BOOST_TEST(calls[0].expectations.gasUsedForCodeDeposit == (std::map{ + {"ir", 20}, + })); +} + +BOOST_AUTO_TEST_CASE(gas_with_code_deposit_cost_negative_total_cost) +{ + char const* source = R"( + // f() -> + // gas ir: -10 + // gas ir code: 20 + )"; + BOOST_REQUIRE_THROW(parse(source), TestParserError); +} + +BOOST_AUTO_TEST_CASE(gas_with_code_deposit_cost_negative_code_cost) +{ + char const* source = R"( + // f() -> + // gas ir: 20 + // gas ir code: -10 + )"; + BOOST_REQUIRE_THROW(parse(source), TestParserError); +} + BOOST_AUTO_TEST_SUITE_END() } diff --git a/test/libsolidity/util/TestFunctionCall.cpp b/test/libsolidity/util/TestFunctionCall.cpp index 54dd769d6116..b22ac3716a13 100644 --- a/test/libsolidity/util/TestFunctionCall.cpp +++ b/test/libsolidity/util/TestFunctionCall.cpp @@ -22,6 +22,9 @@ #include #include +#include +#include + #include #include #include @@ -371,11 +374,19 @@ std::string TestFunctionCall::formatGasExpectations( bool _showDifference ) const { + using ranges::views::keys; + using ranges::views::set_symmetric_difference; + + soltestAssert(set_symmetric_difference(m_codeDepositGasCosts | keys, m_gasCosts | keys).empty()); + soltestAssert(set_symmetric_difference(m_call.expectations.gasUsedForCodeDeposit | keys, m_call.expectations.gasUsed | keys).empty()); + std::stringstream os; for (auto const& [runType, gasUsed]: (_useActualCost ? m_gasCosts : m_call.expectations.gasUsed)) { soltestAssert(runType != ""); + u256 gasUsedForCodeDeposit = (_useActualCost ? m_codeDepositGasCosts : m_call.expectations.gasUsedForCodeDeposit).at(runType); + os << std::endl << _linePrefix << "// gas " << runType << ": " << gasUsed.str(); std::string gasDiff = formatGasDiff( gasOrNullopt(m_gasCosts, runType), @@ -383,6 +394,17 @@ std::string TestFunctionCall::formatGasExpectations( ); if (_showDifference && !gasDiff.empty() && _useActualCost) os << " [" << gasDiff << "]"; + + if (gasUsedForCodeDeposit != 0) + { + os << std::endl << _linePrefix << "// gas " << runType << " code: " << gasUsedForCodeDeposit.str(); + std::string codeGasDiff = formatGasDiff( + gasOrNullopt(m_codeDepositGasCosts, runType), + gasOrNullopt(m_call.expectations.gasUsedForCodeDeposit, runType) + ); + if (_showDifference && !codeGasDiff.empty() && _useActualCost) + os << " [" << codeGasDiff << "]"; + } } return os.str(); } diff --git a/test/libsolidity/util/TestFunctionCall.h b/test/libsolidity/util/TestFunctionCall.h index 8b4ed5019d41..cf05b6a216d7 100644 --- a/test/libsolidity/util/TestFunctionCall.h +++ b/test/libsolidity/util/TestFunctionCall.h @@ -51,7 +51,11 @@ class TestFunctionCall ExpectedValuesActualGas }; - TestFunctionCall(FunctionCall _call): m_call(std::move(_call)), m_gasCosts(m_call.expectations.gasUsed) {} + TestFunctionCall(FunctionCall _call): + m_call(std::move(_call)), + m_gasCosts(m_call.expectations.gasUsed), + m_codeDepositGasCosts(m_call.expectations.gasUsedForCodeDeposit) + {} /// Formats this function call test and applies the format that was detected during parsing. /// _renderMode determines the source of values to be inserted into the updated test expectations. @@ -94,6 +98,7 @@ class TestFunctionCall void setFailure(const bool _failure) { m_failure = _failure; } void setRawBytes(const bytes _rawBytes) { m_rawBytes = _rawBytes; } void setGasCost(std::string const& _runType, u256 const& _gasCost) { m_gasCosts[_runType] = _gasCost; } + void setCodeDepositGasCost(std::string const& _runType, u256 const& _gasCost) { m_codeDepositGasCosts[_runType] = _gasCost; } void setContractABI(Json::Value _contractABI) { m_contractABI = std::move(_contractABI); } void setSideEffects(std::vector _sideEffects) { m_call.actualSideEffects = _sideEffects; } @@ -143,6 +148,8 @@ class TestFunctionCall bytes m_rawBytes = bytes{}; /// Actual gas costs std::map m_gasCosts; + /// Actual code deposit gas costs + std::map m_codeDepositGasCosts; /// Transaction status of the actual call. False in case of a REVERT or any other failure. bool m_failure = true; /// JSON object which holds the contract ABI and that is used to set the output formatting diff --git a/test/libsolidity/util/TestFunctionCallTests.cpp b/test/libsolidity/util/TestFunctionCallTests.cpp index 74a45c32687e..b78b7e5f290d 100644 --- a/test/libsolidity/util/TestFunctionCallTests.cpp +++ b/test/libsolidity/util/TestFunctionCallTests.cpp @@ -38,7 +38,7 @@ BOOST_AUTO_TEST_CASE(format_unsigned_singleline) bytes expectedBytes = toBigEndian(u256{1}); ABIType abiType{ABIType::UnsignedDec, ABIType::AlignRight, 32}; Parameter param{expectedBytes, "1", abiType, FormatInfo{}}; - FunctionCallExpectations expectations{std::vector{param}, false, std::string{}, {}}; + FunctionCallExpectations expectations{std::vector{param}, false, std::string{}, {}, {}}; FunctionCallArgs arguments{std::vector{param}, std::string{}}; FunctionCall call{"f(uint8)", {0}, arguments, expectations}; call.omitsArrow = false; @@ -58,7 +58,7 @@ BOOST_AUTO_TEST_CASE(format_unsigned_singleline_signed_encoding) bytes expectedBytes = toBigEndian(u256{1}); ABIType abiType{ABIType::UnsignedDec, ABIType::AlignRight, 32}; Parameter param{expectedBytes, "1", abiType, FormatInfo{}}; - FunctionCallExpectations expectations{std::vector{param}, false, std::string{}, {}}; + FunctionCallExpectations expectations{std::vector{param}, false, std::string{}, {}, {}}; FunctionCallArgs arguments{std::vector{param}, std::string{}}; FunctionCall call{"f(uint8)", {0}, arguments, expectations}; call.omitsArrow = false; @@ -78,7 +78,7 @@ BOOST_AUTO_TEST_CASE(format_unsigned_multiline) bytes expectedBytes = toBigEndian(u256{1}); ABIType abiType{ABIType::UnsignedDec, ABIType::AlignRight, 32}; Parameter result{expectedBytes, "1", abiType, FormatInfo{}}; - FunctionCallExpectations expectations{std::vector{result}, false, std::string{}, {}}; + FunctionCallExpectations expectations{std::vector{result}, false, std::string{}, {}, {}}; FunctionCallArgs arguments{std::vector{}, std::string{}}; FunctionCall call{"f(uint8)", {0}, arguments, expectations}; call.omitsArrow = false; @@ -93,7 +93,7 @@ BOOST_AUTO_TEST_CASE(format_multiple_unsigned_singleline) bytes expectedBytes = toBigEndian(u256{1}); ABIType abiType{ABIType::UnsignedDec, ABIType::AlignRight, 32}; Parameter param{expectedBytes, "1", abiType, FormatInfo{}}; - FunctionCallExpectations expectations{std::vector{param, param}, false, std::string{}, {}}; + FunctionCallExpectations expectations{std::vector{param, param}, false, std::string{}, {}, {}}; FunctionCallArgs arguments{std::vector{param, param}, std::string{}}; FunctionCall call{"f(uint8, uint8)", {0}, arguments, expectations}; call.omitsArrow = false; @@ -107,7 +107,7 @@ BOOST_AUTO_TEST_CASE(format_signed_singleline) bytes expectedBytes = toBigEndian(u256{-1}); ABIType abiType{ABIType::UnsignedDec, ABIType::AlignRight, 32}; Parameter param{expectedBytes, "-1", abiType, FormatInfo{}}; - FunctionCallExpectations expectations{std::vector{param}, false, std::string{}, {}}; + FunctionCallExpectations expectations{std::vector{param}, false, std::string{}, {}, {}}; FunctionCallArgs arguments{std::vector{param}, std::string{}}; FunctionCall call{"f(int8)", {0}, arguments, expectations}; call.omitsArrow = false; @@ -127,7 +127,7 @@ BOOST_AUTO_TEST_CASE(format_hex_singleline) bytes expectedBytes = result + bytes(32 - result.size(), 0); ABIType abiType{ABIType::Hex, ABIType::AlignRight, 32}; Parameter param{expectedBytes, "0x31", abiType, FormatInfo{}}; - FunctionCallExpectations expectations{std::vector{param}, false, std::string{}, {}}; + FunctionCallExpectations expectations{std::vector{param}, false, std::string{}, {}, {}}; FunctionCallArgs arguments{std::vector{param}, std::string{}}; FunctionCall call{"f(bytes32)", {0}, arguments, expectations}; call.omitsArrow = false; @@ -149,7 +149,7 @@ BOOST_AUTO_TEST_CASE(format_hex_string_singleline) bytes expectedBytes = fromHex("4200ef"); ABIType abiType{ABIType::HexString, ABIType::AlignLeft, 3}; Parameter param{expectedBytes, "hex\"4200ef\"", abiType, FormatInfo{}}; - FunctionCallExpectations expectations{std::vector{param}, false, std::string{}, {}}; + FunctionCallExpectations expectations{std::vector{param}, false, std::string{}, {}, {}}; FunctionCallArgs arguments{std::vector{param}, std::string{}}; FunctionCall call{"f(string)", {0}, arguments, expectations}; call.omitsArrow = false; @@ -163,7 +163,7 @@ BOOST_AUTO_TEST_CASE(format_bool_true_singleline) bytes expectedBytes = toBigEndian(u256{true}); ABIType abiType{ABIType::Boolean, ABIType::AlignRight, 32}; Parameter param{expectedBytes, "true", abiType, FormatInfo{}}; - FunctionCallExpectations expectations{std::vector{param}, false, std::string{}, {}}; + FunctionCallExpectations expectations{std::vector{param}, false, std::string{}, {}, {}}; FunctionCallArgs arguments{std::vector{param}, std::string{}}; FunctionCall call{"f(bool)", {0}, arguments, expectations}; call.omitsArrow = false; @@ -184,7 +184,7 @@ BOOST_AUTO_TEST_CASE(format_bool_false_singleline) bytes expectedBytes = toBigEndian(u256{false}); ABIType abiType{ABIType::Boolean, ABIType::AlignRight, 32}; Parameter param{expectedBytes, "false", abiType, FormatInfo{}}; - FunctionCallExpectations expectations{std::vector{param}, false, std::string{}, {}}; + FunctionCallExpectations expectations{std::vector{param}, false, std::string{}, {}, {}}; FunctionCallArgs arguments{std::vector{param}, std::string{}}; FunctionCall call{"f(bool)", {0}, arguments, expectations}; call.omitsArrow = false; @@ -198,7 +198,7 @@ BOOST_AUTO_TEST_CASE(format_bool_left_singleline) bytes expectedBytes = toBigEndian(u256{false}); ABIType abiType{ABIType::Boolean, ABIType::AlignLeft, 32}; Parameter param{expectedBytes, "left(false)", abiType, FormatInfo{}}; - FunctionCallExpectations expectations{std::vector{param}, false, std::string{}, {}}; + FunctionCallExpectations expectations{std::vector{param}, false, std::string{}, {}, {}}; FunctionCallArgs arguments{std::vector{param}, std::string{}}; FunctionCall call{"f(bool)", {0}, arguments, expectations}; call.omitsArrow = false; @@ -213,7 +213,7 @@ BOOST_AUTO_TEST_CASE(format_hex_number_right_singleline) bytes expectedBytes = result + bytes(32 - result.size(), 0); ABIType abiType{ABIType::Hex, ABIType::AlignRight, 32}; Parameter param{expectedBytes, "right(0x42)", abiType, FormatInfo{}}; - FunctionCallExpectations expectations{std::vector{param}, false, std::string{}, {}}; + FunctionCallExpectations expectations{std::vector{param}, false, std::string{}, {}, {}}; FunctionCallArgs arguments{std::vector{param}, std::string{}}; FunctionCall call{"f(bool)", {0}, arguments, expectations}; call.omitsArrow = false; @@ -227,7 +227,7 @@ BOOST_AUTO_TEST_CASE(format_empty_byte_range) bytes expectedBytes; ABIType abiType{ABIType::None, ABIType::AlignNone, 0}; Parameter param{expectedBytes, "1", abiType, FormatInfo{}}; - FunctionCallExpectations expectations{std::vector{param}, false, std::string{}, {}}; + FunctionCallExpectations expectations{std::vector{param}, false, std::string{}, {}, {}}; FunctionCallArgs arguments{std::vector{}, std::string{}}; FunctionCall call{"f()", {0}, arguments, expectations}; call.omitsArrow = false; @@ -241,7 +241,7 @@ BOOST_AUTO_TEST_CASE(format_failure_singleline) bytes expectedBytes = toBigEndian(u256{1}); ABIType abiType{ABIType::UnsignedDec, ABIType::AlignRight, 32}; Parameter param{expectedBytes, "1", abiType, FormatInfo{}}; - FunctionCallExpectations expectations{std::vector{}, true, std::string{}, {}}; + FunctionCallExpectations expectations{std::vector{}, true, std::string{}, {}, {}}; FunctionCallArgs arguments{std::vector{param}, std::string{}}; FunctionCall call{"f(uint8)", {0}, arguments, expectations}; call.omitsArrow = false; @@ -265,6 +265,11 @@ BOOST_AUTO_TEST_CASE(format_gas) {"legacy", 5000}, {"legacy optimized", 0}, }, + { + {"ir", 0}, + {"legacy", 0}, + {"legacy optimized", 0}, + }, } }; call.omitsArrow = false; @@ -278,6 +283,40 @@ BOOST_AUTO_TEST_CASE(format_gas) ); } +BOOST_AUTO_TEST_CASE(format_gas_with_code_deposit) +{ + FunctionCall call{ + "f()", + FunctionValue{0}, + FunctionCallArgs{}, + FunctionCallExpectations{ + std::vector{}, + false, // failure + "some comment", + { + {"ir", 0}, // Zero costs are shown + {"legacy", 5000}, + {"legacy optimized", 300}, + }, + { + {"ir", 0}, // Zero code deposit costs are omitted + {"legacy", 125}, + {"legacy optimized", 0}, + }, + } + }; + call.omitsArrow = false; + + BOOST_REQUIRE_EQUAL( + TestFunctionCall(call).format(), + "// f() -> #some comment#\n" + "// gas ir: 0\n" + "// gas legacy: 5000\n" + "// gas legacy code: 125\n" + "// gas legacy optimized: 300" + ); +} + BOOST_AUTO_TEST_SUITE_END() } From 96ce95aa3a21f285ee32d30d8b2eed8017a2bdd6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Fri, 9 Feb 2024 21:30:46 +0100 Subject: [PATCH 0063/1022] Do not include code deposit gas in the total visible in test expectations --- test/libsolidity/SemanticTest.cpp | 13 +++++---- ...2_in_function_inherited_in_v1_contract.sol | 9 ++++-- ...ode_v2_in_modifier_used_in_v1_contract.sol | 3 +- .../arithmetics/check_var_init.sol | 3 +- .../array/constant_var_as_array_length.sol | 9 ++++-- ...nup_during_multi_element_per_slot_copy.sol | 9 ++++-- .../array/fixed_arrays_as_return_type.sol | 9 ++++-- .../array/fixed_arrays_in_constructors.sol | 9 ++++-- .../array/function_array_cross_calls.sol | 9 ++++-- .../semanticTests/array/reusing_memory.sol | 9 ++++-- .../byte_array_to_storage_cleanup.sol | 9 ++++-- .../constructor/arrays_in_constructors.sol | 9 ++++-- .../bytes_in_constructors_packer.sol | 9 ++++-- .../bytes_in_constructors_unpacker.sol | 9 ++++-- .../constructor_arguments_external.sol | 9 ++++-- .../constructor_function_complex.sol | 3 +- .../constructor_static_array_argument.sol | 9 ++++-- .../constructor/no_callvalue_check.sol | 9 ++++-- .../constructor_inheritance_init_order.sol | 3 +- .../constructor_inheritance_init_order_2.sol | 9 ++++-- .../semanticTests/constructor_with_params.sol | 6 ++-- ...ructor_with_params_diamond_inheritance.sol | 9 ++++-- .../constructor_with_params_inheritance.sol | 9 ++++-- .../events/event_emit_from_other_contract.sol | 9 ++++-- .../externalContracts/FixedFeeRegistrar.sol | 9 ++++-- .../externalContracts/base64.sol | 9 ++++-- .../externalContracts/deposit_contract.sol | 9 ++++-- .../externalContracts/prbmath_signed.sol | 9 ++++-- .../externalContracts/prbmath_unsigned.sol | 9 ++++-- .../externalContracts/ramanujan_pi.sol | 9 ++++-- .../externalContracts/strings.sol | 9 ++++-- .../freeFunctions/new_operator.sol | 3 +- .../creation_function_call_no_args.sol | 3 +- .../creation_function_call_with_args.sol | 9 ++++-- .../creation_function_call_with_salt.sol | 9 ++++-- .../external_call_to_nonexisting.sol | 9 ++++-- ...ernal_call_to_nonexisting_debugstrings.sol | 9 ++++-- .../functionCall/failed_create.sol | 9 ++++-- .../functionCall/gas_and_value_basic.sol | 9 ++++-- .../gas_and_value_brace_syntax.sol | 9 ++++-- .../functionCall/send_zero_ether.sol | 3 +- .../functionTypes/store_function.sol | 6 ++-- .../immutable/multi_creation.sol | 9 ++++-- .../semanticTests/immutable/use_scratch.sol | 9 ++++-- .../address_overload_resolution.sol | 6 ++-- ...d_function_calldata_calldata_interface.sol | 3 +- ...ted_function_calldata_memory_interface.sol | 6 ++-- .../inheritance/member_notation_ctor.sol | 6 ++-- .../inheritance/value_for_constructor.sol | 9 ++++-- .../balance_other_contract.sol | 9 ++++-- .../operator_making_pure_external_call.sol | 12 +++++--- .../operator_making_view_external_call.sol | 12 +++++--- .../salted_create/prediction_example.sol | 3 +- .../salted_create/salted_create.sol | 9 ++++-- .../salted_create_with_value.sol | 9 ++++-- .../semanticTests/smoke/alignment.sol | 3 +- .../semanticTests/smoke/constructor.sol | 9 ++++-- .../semanticTests/state/blockhash_basic.sol | 9 ++++-- .../userDefinedValueType/erc20.sol | 9 ++++-- .../using/using_global_invisible.sol | 3 +- .../semanticTests/various/address_code.sol | 9 ++++-- .../various/code_access_content.sol | 6 ++-- .../various/code_access_create.sol | 3 +- .../various/code_access_runtime.sol | 3 +- .../semanticTests/various/code_length.sol | 3 +- .../semanticTests/various/create_calldata.sol | 9 ++++-- .../semanticTests/various/erc20.sol | 9 ++++-- .../various/external_types_in_calls.sol | 3 +- .../various/many_subassemblies.sol | 9 ++++-- .../various/negative_stack_height.sol | 6 ++-- .../various/selfdestruct_pre_cancun.sol | 9 ++++-- ...ruct_pre_cancun_multiple_beneficiaries.sol | 21 +++++++++----- .../selfdestruct_pre_cancun_redeploy.sol | 18 ++++++++---- .../semanticTests/various/senders_balance.sol | 9 ++++-- .../various/staticcall_for_view_and_pure.sol | 21 +++++++++----- .../semanticTests/various/value_complex.sol | 9 ++++-- .../semanticTests/various/value_insane.sol | 9 ++++-- test/libsolidity/util/SoltestTypes.h | 6 ++-- test/libsolidity/util/TestFileParser.cpp | 6 ++-- test/libsolidity/util/TestFileParserTests.cpp | 29 +++++++------------ test/libsolidity/util/TestFunctionCall.cpp | 12 ++++---- test/libsolidity/util/TestFunctionCall.h | 6 ++-- .../util/TestFunctionCallTests.cpp | 4 +-- 83 files changed, 444 insertions(+), 244 deletions(-) diff --git a/test/libsolidity/SemanticTest.cpp b/test/libsolidity/SemanticTest.cpp index 676c39eaf979..381ec5bda54e 100644 --- a/test/libsolidity/SemanticTest.cpp +++ b/test/libsolidity/SemanticTest.cpp @@ -570,7 +570,7 @@ bool SemanticTest::checkGasCostExpectation(TestFunctionCall& io_test, bool _comp (m_optimiserSettings == OptimiserSettings::full() ? "Optimized" : ""); soltestAssert( - io_test.call().expectations.gasUsed.count(setting) == + io_test.call().expectations.gasUsedExcludingCode.count(setting) == io_test.call().expectations.gasUsedForCodeDeposit.count(setting) ); @@ -584,19 +584,22 @@ bool SemanticTest::checkGasCostExpectation(TestFunctionCall& io_test, bool _comp !m_enforceGasCost || m_gasUsed < m_enforceGasCostMinValue || m_gasUsed >= InitialGas || - (setting == "ir" && io_test.call().expectations.gasUsed.count(setting) == 0) || + (setting == "ir" && io_test.call().expectations.gasUsedExcludingCode.count(setting) == 0) || io_test.call().kind == FunctionCall::Kind::Builtin ) return true; solAssert(!m_runWithABIEncoderV1Only, ""); - io_test.setGasCost(setting, m_gasUsed); + // NOTE: Cost excluding code is unlikely to be negative but it may still be possible due to refunds. + // We'll deal with it when we actually have a test case like that. + solUnimplementedAssert(m_gasUsed >= m_gasUsedForCodeDeposit); + io_test.setGasCostExcludingCode(setting, m_gasUsed - m_gasUsedForCodeDeposit); io_test.setCodeDepositGasCost(setting, m_gasUsedForCodeDeposit); return - io_test.call().expectations.gasUsed.count(setting) > 0 && - m_gasUsed == io_test.call().expectations.gasUsed.at(setting) && + io_test.call().expectations.gasUsedExcludingCode.count(setting) > 0 && + m_gasUsed - m_gasUsedForCodeDeposit == io_test.call().expectations.gasUsedExcludingCode.at(setting) && m_gasUsedForCodeDeposit == io_test.call().expectations.gasUsedForCodeDeposit.at(setting); } 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 55f7991def80..c41905e2a491 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 @@ -30,6 +30,9 @@ contract C is B { } // ---- // test() -> 77 -// gas irOptimized: 110348 -// gas legacy: 151866 -// gas legacyOptimized: 110373 +// gas irOptimized: 55148 +// gas irOptimized code: 55200 +// gas legacy: 57266 +// gas legacy code: 94600 +// gas legacyOptimized: 55173 +// gas legacyOptimized code: 55200 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 7de26301205c..7a2395549b5f 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 @@ -39,4 +39,5 @@ contract C is B { // ---- // test() -> 5, 10 // gas irOptimized: 87337 -// gas legacy: 102651 +// gas legacy: 66251 +// gas legacy code: 36400 diff --git a/test/libsolidity/semanticTests/arithmetics/check_var_init.sol b/test/libsolidity/semanticTests/arithmetics/check_var_init.sol index fc5418cb0ed7..9061cd284de9 100644 --- a/test/libsolidity/semanticTests/arithmetics/check_var_init.sol +++ b/test/libsolidity/semanticTests/arithmetics/check_var_init.sol @@ -16,4 +16,5 @@ contract D { // ---- // f() -> FAILURE, hex"4e487b71", 0x11 // g(), 100 wei -> 1 -// gas legacy: 100380 +// gas legacy: 76780 +// gas legacy code: 23600 diff --git a/test/libsolidity/semanticTests/array/constant_var_as_array_length.sol b/test/libsolidity/semanticTests/array/constant_var_as_array_length.sol index 45861babaaf3..19acb7cba14b 100644 --- a/test/libsolidity/semanticTests/array/constant_var_as_array_length.sol +++ b/test/libsolidity/semanticTests/array/constant_var_as_array_length.sol @@ -8,9 +8,12 @@ contract C { } // ---- // constructor(): 1, 2, 3 -> -// gas irOptimized: 139616 -// gas legacy: 180517 -// gas legacyOptimized: 150462 +// gas irOptimized: 124816 +// gas irOptimized code: 14800 +// gas legacy: 134317 +// gas legacy code: 46200 +// gas legacyOptimized: 127062 +// gas legacyOptimized code: 23400 // a(uint256): 0 -> 1 // a(uint256): 1 -> 2 // a(uint256): 2 -> 3 diff --git a/test/libsolidity/semanticTests/array/copying/cleanup_during_multi_element_per_slot_copy.sol b/test/libsolidity/semanticTests/array/copying/cleanup_during_multi_element_per_slot_copy.sol index 8be83289266e..36b94d7c3974 100644 --- a/test/libsolidity/semanticTests/array/copying/cleanup_during_multi_element_per_slot_copy.sol +++ b/test/libsolidity/semanticTests/array/copying/cleanup_during_multi_element_per_slot_copy.sol @@ -16,7 +16,10 @@ contract C { } // ---- // constructor() -// gas irOptimized: 226321 -// gas legacy: 215753 -// gas legacyOptimized: 181756 +// gas irOptimized: 89121 +// gas irOptimized code: 137200 +// gas legacy: 89553 +// gas legacy code: 126200 +// gas legacyOptimized: 83556 +// gas legacyOptimized code: 98200 // f() -> 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 dd90985735b3..0fb513543bea 100644 --- a/test/libsolidity/semanticTests/array/fixed_arrays_as_return_type.sol +++ b/test/libsolidity/semanticTests/array/fixed_arrays_as_return_type.sol @@ -18,6 +18,9 @@ contract B { } // ---- // f() -> 2, 3, 4, 5, 6, 1000, 1001, 1002, 1003, 1004 -// gas irOptimized: 114404 -// gas legacy: 230001 -// gas legacyOptimized: 130637 +// gas irOptimized: 59204 +// gas irOptimized code: 55200 +// gas legacy: 68001 +// gas legacy code: 162000 +// gas legacyOptimized: 60037 +// gas legacyOptimized code: 70600 diff --git a/test/libsolidity/semanticTests/array/fixed_arrays_in_constructors.sol b/test/libsolidity/semanticTests/array/fixed_arrays_in_constructors.sol index c7b2dc77a34b..0eb0f1e90e7d 100644 --- a/test/libsolidity/semanticTests/array/fixed_arrays_in_constructors.sol +++ b/test/libsolidity/semanticTests/array/fixed_arrays_in_constructors.sol @@ -9,8 +9,11 @@ contract Creator { } // ---- // constructor(): 1, 2, 3, 4 -> -// gas irOptimized: 126327 -// gas legacy: 174186 -// gas legacyOptimized: 128709 +// gas irOptimized: 103927 +// gas irOptimized code: 22400 +// gas legacy: 115186 +// gas legacy code: 59000 +// gas legacyOptimized: 104909 +// gas legacyOptimized code: 23800 // r() -> 4 // ch() -> 3 diff --git a/test/libsolidity/semanticTests/array/function_array_cross_calls.sol b/test/libsolidity/semanticTests/array/function_array_cross_calls.sol index 773e904cc095..e35e24bbf12a 100644 --- a/test/libsolidity/semanticTests/array/function_array_cross_calls.sol +++ b/test/libsolidity/semanticTests/array/function_array_cross_calls.sol @@ -42,6 +42,9 @@ contract C { } // ---- // test() -> 5, 6, 7 -// gas irOptimized: 255728 -// gas legacy: 440376 -// gas legacyOptimized: 278651 +// gas irOptimized: 86128 +// gas irOptimized code: 169600 +// gas legacy: 97576 +// gas legacy code: 342800 +// gas legacyOptimized: 87851 +// gas legacyOptimized code: 190800 diff --git a/test/libsolidity/semanticTests/array/reusing_memory.sol b/test/libsolidity/semanticTests/array/reusing_memory.sol index 8f6afe30ba2c..a7608f6e0c81 100644 --- a/test/libsolidity/semanticTests/array/reusing_memory.sol +++ b/test/libsolidity/semanticTests/array/reusing_memory.sol @@ -24,6 +24,9 @@ contract Main { } // ---- // f(uint256): 0x34 -> 0x46bddb1178e94d7f2892ff5f366840eb658911794f2c3a44c450aa2c505186c1 -// gas irOptimized: 111924 -// gas legacy: 125154 -// gas legacyOptimized: 113012 +// gas irOptimized: 99524 +// gas irOptimized code: 12400 +// gas legacy: 101554 +// gas legacy code: 23600 +// gas legacyOptimized: 99612 +// gas legacyOptimized code: 13400 diff --git a/test/libsolidity/semanticTests/byte_array_to_storage_cleanup.sol b/test/libsolidity/semanticTests/byte_array_to_storage_cleanup.sol index 877e2a1bce03..14130926e7fb 100644 --- a/test/libsolidity/semanticTests/byte_array_to_storage_cleanup.sol +++ b/test/libsolidity/semanticTests/byte_array_to_storage_cleanup.sol @@ -28,9 +28,12 @@ contract C { // compileViaYul: also // ---- // constructor() -> -// gas irOptimized: 443402 -// gas legacy: 711295 -// gas legacyOptimized: 482378 +// gas irOptimized: 82402 +// gas irOptimized code: 361000 +// gas legacy: 101895 +// gas legacy code: 609400 +// gas legacyOptimized: 85378 +// gas legacyOptimized code: 397000 // h() -> 0x20, 0x40, 0x00, 0 // ~ emit ev(uint256[],uint256): 0x40, 0x21, 0x02, 0x00, 0x00 // g() -> 0x20, 0x40, 0, 0x00 diff --git a/test/libsolidity/semanticTests/constructor/arrays_in_constructors.sol b/test/libsolidity/semanticTests/constructor/arrays_in_constructors.sol index 19d79b6c4fcf..3e60ba451c8c 100644 --- a/test/libsolidity/semanticTests/constructor/arrays_in_constructors.sol +++ b/test/libsolidity/semanticTests/constructor/arrays_in_constructors.sol @@ -24,6 +24,9 @@ contract Creator { } // ---- // f(uint256,address[]): 7, 0x40, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 -> 7, 8 -// gas irOptimized: 424526 -// gas legacy: 581426 -// gas legacyOptimized: 444599 +// gas irOptimized: 328126 +// gas irOptimized code: 96400 +// gas legacy: 336626 +// gas legacy code: 244800 +// gas legacyOptimized: 329599 +// gas legacyOptimized code: 115000 diff --git a/test/libsolidity/semanticTests/constructor/bytes_in_constructors_packer.sol b/test/libsolidity/semanticTests/constructor/bytes_in_constructors_packer.sol index cfa74f016f6d..7885d3ceecf0 100644 --- a/test/libsolidity/semanticTests/constructor/bytes_in_constructors_packer.sol +++ b/test/libsolidity/semanticTests/constructor/bytes_in_constructors_packer.sol @@ -24,6 +24,9 @@ contract Creator { } // ---- // f(uint256,bytes): 7, 0x40, 78, "abcdefghijklmnopqrstuvwxyzabcdef", "ghijklmnopqrstuvwxyzabcdefghijkl", "mnopqrstuvwxyz" -> 7, "h" -// gas irOptimized: 275102 -// gas legacy: 418433 -// gas legacyOptimized: 291960 +// gas irOptimized: 169902 +// gas irOptimized code: 105200 +// gas legacy: 173433 +// gas legacy code: 245000 +// gas legacyOptimized: 170360 +// gas legacyOptimized code: 121600 diff --git a/test/libsolidity/semanticTests/constructor/bytes_in_constructors_unpacker.sol b/test/libsolidity/semanticTests/constructor/bytes_in_constructors_unpacker.sol index 39da45e8a57e..1d6b01127c5a 100644 --- a/test/libsolidity/semanticTests/constructor/bytes_in_constructors_unpacker.sol +++ b/test/libsolidity/semanticTests/constructor/bytes_in_constructors_unpacker.sol @@ -8,8 +8,11 @@ contract Test { } // ---- // constructor(): 7, 0x40, 78, "abcdefghijklmnopqrstuvwxyzabcdef", "ghijklmnopqrstuvwxyzabcdefghijkl", "mnopqrstuvwxyz" -> -// gas irOptimized: 269225 -// gas legacy: 310820 -// gas legacyOptimized: 258604 +// gas irOptimized: 182025 +// gas irOptimized code: 87200 +// gas legacy: 196220 +// gas legacy code: 114600 +// gas legacyOptimized: 182604 +// gas legacyOptimized code: 76000 // m_x() -> 7 // m_s() -> 0x20, 78, "abcdefghijklmnopqrstuvwxyzabcdef", "ghijklmnopqrstuvwxyzabcdefghijkl", "mnopqrstuvwxyz" diff --git a/test/libsolidity/semanticTests/constructor/constructor_arguments_external.sol b/test/libsolidity/semanticTests/constructor/constructor_arguments_external.sol index 714ae3e5548c..8fa725dad569 100644 --- a/test/libsolidity/semanticTests/constructor/constructor_arguments_external.sol +++ b/test/libsolidity/semanticTests/constructor/constructor_arguments_external.sol @@ -17,8 +17,11 @@ contract Main { } // ---- // constructor(): "abc", true -// gas irOptimized: 104374 -// gas legacy: 143300 -// gas legacyOptimized: 102933 +// gas irOptimized: 80174 +// gas irOptimized code: 24200 +// gas legacy: 85100 +// gas legacy code: 58200 +// gas legacyOptimized: 80133 +// gas legacyOptimized code: 22800 // getFlag() -> true // getName() -> "abc" diff --git a/test/libsolidity/semanticTests/constructor/constructor_function_complex.sol b/test/libsolidity/semanticTests/constructor/constructor_function_complex.sol index 4117b84b64f9..33650aff6fb6 100644 --- a/test/libsolidity/semanticTests/constructor/constructor_function_complex.sol +++ b/test/libsolidity/semanticTests/constructor/constructor_function_complex.sol @@ -17,4 +17,5 @@ contract C { } // ---- // f() -> 16 -// gas legacy: 102082 +// gas legacy: 78482 +// gas legacy code: 23600 diff --git a/test/libsolidity/semanticTests/constructor/constructor_static_array_argument.sol b/test/libsolidity/semanticTests/constructor/constructor_static_array_argument.sol index a61192742d04..e6ce445ada39 100644 --- a/test/libsolidity/semanticTests/constructor/constructor_static_array_argument.sol +++ b/test/libsolidity/semanticTests/constructor/constructor_static_array_argument.sol @@ -9,9 +9,12 @@ contract C { } // ---- // constructor(): 1, 2, 3, 4 -> -// gas irOptimized: 170975 -// gas legacy: 218378 -// gas legacyOptimized: 176211 +// gas irOptimized: 147975 +// gas irOptimized code: 23000 +// gas legacy: 157978 +// gas legacy code: 60400 +// gas legacyOptimized: 150011 +// gas legacyOptimized code: 26200 // a() -> 1 // b(uint256): 0 -> 2 // b(uint256): 1 -> 3 diff --git a/test/libsolidity/semanticTests/constructor/no_callvalue_check.sol b/test/libsolidity/semanticTests/constructor/no_callvalue_check.sol index eec01005ebd2..b1dc80a408d8 100644 --- a/test/libsolidity/semanticTests/constructor/no_callvalue_check.sol +++ b/test/libsolidity/semanticTests/constructor/no_callvalue_check.sol @@ -17,6 +17,9 @@ contract C { } // ---- // f(), 2000 ether -> true -// gas irOptimized: 119441 -// gas legacy: 122621 -// gas legacyOptimized: 122490 +// gas irOptimized: 117641 +// gas irOptimized code: 1800 +// gas legacy: 117821 +// gas legacy code: 4800 +// gas legacyOptimized: 117690 +// gas legacyOptimized code: 4800 diff --git a/test/libsolidity/semanticTests/constructor_inheritance_init_order.sol b/test/libsolidity/semanticTests/constructor_inheritance_init_order.sol index ece0cc31a651..ef53142d458a 100644 --- a/test/libsolidity/semanticTests/constructor_inheritance_init_order.sol +++ b/test/libsolidity/semanticTests/constructor_inheritance_init_order.sol @@ -14,5 +14,6 @@ contract B is A { // compileViaYul: true // ---- // constructor() -> -// gas irOptimized: 119636 +// gas irOptimized: 99436 +// gas irOptimized code: 20200 // y() -> 42 diff --git a/test/libsolidity/semanticTests/constructor_inheritance_init_order_2.sol b/test/libsolidity/semanticTests/constructor_inheritance_init_order_2.sol index 654c9af56df1..e19ad39cfad7 100644 --- a/test/libsolidity/semanticTests/constructor_inheritance_init_order_2.sol +++ b/test/libsolidity/semanticTests/constructor_inheritance_init_order_2.sol @@ -9,7 +9,10 @@ contract B is A { } // ---- // constructor() -> -// gas irOptimized: 119636 -// gas legacy: 133574 -// gas legacyOptimized: 115337 +// gas irOptimized: 99436 +// gas irOptimized code: 20200 +// gas legacy: 100974 +// gas legacy code: 32600 +// gas legacyOptimized: 99137 +// gas legacyOptimized code: 16200 // y() -> 42 diff --git a/test/libsolidity/semanticTests/constructor_with_params.sol b/test/libsolidity/semanticTests/constructor_with_params.sol index e427f6d9ab7b..1c5a170202f3 100644 --- a/test/libsolidity/semanticTests/constructor_with_params.sol +++ b/test/libsolidity/semanticTests/constructor_with_params.sol @@ -9,7 +9,9 @@ contract C { } // ---- // constructor(): 2, 0 -> -// gas irOptimized: 101370 -// gas legacy: 115614 +// gas irOptimized: 81170 +// gas irOptimized code: 20200 +// gas legacy: 83614 +// gas legacy code: 32000 // i() -> 2 // k() -> 0 diff --git a/test/libsolidity/semanticTests/constructor_with_params_diamond_inheritance.sol b/test/libsolidity/semanticTests/constructor_with_params_diamond_inheritance.sol index 65070814476d..29f401a77322 100644 --- a/test/libsolidity/semanticTests/constructor_with_params_diamond_inheritance.sol +++ b/test/libsolidity/semanticTests/constructor_with_params_diamond_inheritance.sol @@ -21,9 +21,12 @@ contract D is B, C { } // ---- // constructor(): 2, 0 -> -// gas irOptimized: 151950 -// gas legacy: 168623 -// gas legacyOptimized: 144521 +// gas irOptimized: 124350 +// gas irOptimized code: 27600 +// gas legacy: 128223 +// gas legacy code: 40400 +// gas legacyOptimized: 123921 +// gas legacyOptimized code: 20600 // i() -> 2 // j() -> 2 // k() -> 1 diff --git a/test/libsolidity/semanticTests/constructor_with_params_inheritance.sol b/test/libsolidity/semanticTests/constructor_with_params_inheritance.sol index 8cc7c69f689b..b0373b74f193 100644 --- a/test/libsolidity/semanticTests/constructor_with_params_inheritance.sol +++ b/test/libsolidity/semanticTests/constructor_with_params_inheritance.sol @@ -12,8 +12,11 @@ contract D is C { } // ---- // constructor(): 2, 0 -> -// gas irOptimized: 121781 -// gas legacy: 137193 -// gas legacyOptimized: 118504 +// gas irOptimized: 101581 +// gas irOptimized code: 20200 +// gas legacy: 105193 +// gas legacy code: 32000 +// gas legacyOptimized: 101504 +// gas legacyOptimized code: 17000 // i() -> 2 // k() -> 1 diff --git a/test/libsolidity/semanticTests/events/event_emit_from_other_contract.sol b/test/libsolidity/semanticTests/events/event_emit_from_other_contract.sol index 0c56cbb671fc..6a01d0019295 100644 --- a/test/libsolidity/semanticTests/events/event_emit_from_other_contract.sol +++ b/test/libsolidity/semanticTests/events/event_emit_from_other_contract.sol @@ -15,8 +15,11 @@ contract C { } // ---- // constructor() -> -// gas irOptimized: 165370 -// gas legacy: 244776 -// gas legacyOptimized: 171587 +// gas irOptimized: 113970 +// gas irOptimized code: 51400 +// gas legacy: 119776 +// gas legacy code: 125000 +// gas legacyOptimized: 114187 +// gas legacyOptimized code: 57400 // deposit(bytes32), 18 wei: 0x1234 -> // ~ emit Deposit(address,bytes32,uint256) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: #0xc06afe3a8444fc0004668591e8306bfb9968e79e, #0x1234, 0x00 diff --git a/test/libsolidity/semanticTests/externalContracts/FixedFeeRegistrar.sol b/test/libsolidity/semanticTests/externalContracts/FixedFeeRegistrar.sol index 011fecbd3422..d308d4597e53 100644 --- a/test/libsolidity/semanticTests/externalContracts/FixedFeeRegistrar.sol +++ b/test/libsolidity/semanticTests/externalContracts/FixedFeeRegistrar.sol @@ -74,9 +74,12 @@ contract FixedFeeRegistrar is Registrar { } // ---- // constructor() -// gas irOptimized: 384606 -// gas legacy: 913417 -// gas legacyOptimized: 476924 +// gas irOptimized: 78006 +// gas irOptimized code: 306600 +// gas legacy: 115817 +// gas legacy code: 797600 +// gas legacyOptimized: 84924 +// gas legacyOptimized code: 392000 // reserve(string), 69 ether: 0x20, 3, "abc" -> // ~ emit Changed(string): #0x4e03657aea45a94fc7d47ba826c8d667c0d1e6e33a64a036ec44f58fa12d6c45 // gas irOptimized: 45967 diff --git a/test/libsolidity/semanticTests/externalContracts/base64.sol b/test/libsolidity/semanticTests/externalContracts/base64.sol index ee2745d1acb9..b712092ed022 100644 --- a/test/libsolidity/semanticTests/externalContracts/base64.sol +++ b/test/libsolidity/semanticTests/externalContracts/base64.sol @@ -33,9 +33,12 @@ contract test { // EVMVersion: >=constantinople // ---- // constructor() -// gas irOptimized: 405828 -// gas legacy: 735050 -// gas legacyOptimized: 522718 +// gas irOptimized: 79428 +// gas irOptimized code: 326400 +// gas legacy: 102450 +// gas legacy code: 632600 +// gas legacyOptimized: 88318 +// gas legacyOptimized code: 434400 // encode_inline_asm(bytes): 0x20, 0 -> 0x20, 0 // encode_inline_asm(bytes): 0x20, 1, "f" -> 0x20, 4, "Zg==" // encode_inline_asm(bytes): 0x20, 2, "fo" -> 0x20, 4, "Zm8=" diff --git a/test/libsolidity/semanticTests/externalContracts/deposit_contract.sol b/test/libsolidity/semanticTests/externalContracts/deposit_contract.sol index caa7fc39c867..0ef87edd4f08 100644 --- a/test/libsolidity/semanticTests/externalContracts/deposit_contract.sol +++ b/test/libsolidity/semanticTests/externalContracts/deposit_contract.sol @@ -176,9 +176,12 @@ contract DepositContract is IDepositContract, ERC165 { } // ---- // constructor() -// gas irOptimized: 1386886 -// gas legacy: 2368733 -// gas legacyOptimized: 1740004 +// gas irOptimized: 815686 +// gas irOptimized code: 571200 +// gas legacy: 925933 +// gas legacy code: 1442800 +// gas legacyOptimized: 854404 +// gas legacyOptimized code: 885600 // supportsInterface(bytes4): 0x0 -> 0 // supportsInterface(bytes4): 0xffffffff00000000000000000000000000000000000000000000000000000000 -> false # defined to be false by ERC-165 # // supportsInterface(bytes4): 0x01ffc9a700000000000000000000000000000000000000000000000000000000 -> true # ERC-165 id # diff --git a/test/libsolidity/semanticTests/externalContracts/prbmath_signed.sol b/test/libsolidity/semanticTests/externalContracts/prbmath_signed.sol index ba7a208fd71b..ddd63971836c 100644 --- a/test/libsolidity/semanticTests/externalContracts/prbmath_signed.sol +++ b/test/libsolidity/semanticTests/externalContracts/prbmath_signed.sol @@ -48,9 +48,12 @@ contract test { } // ---- // constructor() -// gas irOptimized: 1841736 -// gas legacy: 2414087 -// gas legacyOptimized: 1847612 +// gas irOptimized: 177336 +// gas irOptimized code: 1664400 +// gas legacy: 209687 +// gas legacy code: 2204400 +// gas legacyOptimized: 178012 +// gas legacyOptimized code: 1669600 // div(int256,int256): 3141592653589793238, 88714123 -> 35412542528203691288251815328 // gas irOptimized: 22137 // gas legacy: 22767 diff --git a/test/libsolidity/semanticTests/externalContracts/prbmath_unsigned.sol b/test/libsolidity/semanticTests/externalContracts/prbmath_unsigned.sol index 90b283db4613..deacfd05641b 100644 --- a/test/libsolidity/semanticTests/externalContracts/prbmath_unsigned.sol +++ b/test/libsolidity/semanticTests/externalContracts/prbmath_unsigned.sol @@ -48,9 +48,12 @@ contract test { } // ---- // constructor() -// gas irOptimized: 1716323 -// gas legacy: 2193546 -// gas legacyOptimized: 1725057 +// gas irOptimized: 168523 +// gas irOptimized code: 1547800 +// gas legacy: 195146 +// gas legacy code: 1998400 +// gas legacyOptimized: 168857 +// gas legacyOptimized code: 1556200 // div(uint256,uint256): 3141592653589793238, 88714123 -> 35412542528203691288251815328 // gas irOptimized: 22004 // gas legacy: 22497 diff --git a/test/libsolidity/semanticTests/externalContracts/ramanujan_pi.sol b/test/libsolidity/semanticTests/externalContracts/ramanujan_pi.sol index 4442b6d479d3..cdaec8797eb7 100644 --- a/test/libsolidity/semanticTests/externalContracts/ramanujan_pi.sol +++ b/test/libsolidity/semanticTests/externalContracts/ramanujan_pi.sol @@ -33,9 +33,12 @@ contract test { } // ---- // constructor() -// gas irOptimized: 407503 -// gas legacy: 615086 -// gas legacyOptimized: 451867 +// gas irOptimized: 79503 +// gas irOptimized code: 328000 +// gas legacy: 92086 +// gas legacy code: 523000 +// gas legacyOptimized: 82667 +// gas legacyOptimized code: 369200 // prb_pi() -> 3141592656369545286 // gas irOptimized: 57478 // gas legacy: 100947 diff --git a/test/libsolidity/semanticTests/externalContracts/strings.sol b/test/libsolidity/semanticTests/externalContracts/strings.sol index 3f88fc39c65e..a4b0f9fd353d 100644 --- a/test/libsolidity/semanticTests/externalContracts/strings.sol +++ b/test/libsolidity/semanticTests/externalContracts/strings.sol @@ -49,9 +49,12 @@ contract test { } // ---- // constructor() -// gas irOptimized: 630220 -// gas legacy: 1061953 -// gas legacyOptimized: 718933 +// gas irOptimized: 96420 +// gas irOptimized code: 533800 +// gas legacy: 126553 +// gas legacy code: 935400 +// gas legacyOptimized: 102933 +// gas legacyOptimized code: 616000 // toSlice(string): 0x20, 11, "hello world" -> 11, 0xa0 // gas irOptimized: 22660 // gas legacy: 23190 diff --git a/test/libsolidity/semanticTests/freeFunctions/new_operator.sol b/test/libsolidity/semanticTests/freeFunctions/new_operator.sol index dd44a1b5950c..d621629c3b49 100644 --- a/test/libsolidity/semanticTests/freeFunctions/new_operator.sol +++ b/test/libsolidity/semanticTests/freeFunctions/new_operator.sol @@ -13,4 +13,5 @@ contract D { } // ---- // f() -> 2 -// gas legacy: 100211 +// gas legacy: 76611 +// gas legacy code: 23600 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 b6a33fb7e835..6044065958a4 100644 --- a/test/libsolidity/semanticTests/functionCall/creation_function_call_no_args.sol +++ b/test/libsolidity/semanticTests/functionCall/creation_function_call_no_args.sol @@ -11,4 +11,5 @@ contract D { } // ---- // f() -> 2 -// gas legacy: 100185 +// gas legacy: 76585 +// gas legacy code: 23600 diff --git a/test/libsolidity/semanticTests/functionCall/creation_function_call_with_args.sol b/test/libsolidity/semanticTests/functionCall/creation_function_call_with_args.sol index 34aac74efa04..1133dc2be300 100644 --- a/test/libsolidity/semanticTests/functionCall/creation_function_call_with_args.sol +++ b/test/libsolidity/semanticTests/functionCall/creation_function_call_with_args.sol @@ -15,7 +15,10 @@ contract D { } // ---- // constructor(): 2 -> -// gas irOptimized: 192663 -// gas legacy: 241170 -// gas legacyOptimized: 192897 +// gas irOptimized: 138863 +// gas irOptimized code: 53800 +// gas legacy: 145570 +// gas legacy code: 95600 +// gas legacyOptimized: 138297 +// gas legacyOptimized code: 54600 // f() -> 2 diff --git a/test/libsolidity/semanticTests/functionCall/creation_function_call_with_salt.sol b/test/libsolidity/semanticTests/functionCall/creation_function_call_with_salt.sol index cb26a6e26adf..ba90a8ecd5a6 100644 --- a/test/libsolidity/semanticTests/functionCall/creation_function_call_with_salt.sol +++ b/test/libsolidity/semanticTests/functionCall/creation_function_call_with_salt.sol @@ -17,7 +17,10 @@ contract D { // EVMVersion: >=constantinople // ---- // constructor(): 2 -> -// gas irOptimized: 192826 -// gas legacy: 241536 -// gas legacyOptimized: 193129 +// gas irOptimized: 139026 +// gas irOptimized code: 53800 +// gas legacy: 145936 +// gas legacy code: 95600 +// gas legacyOptimized: 138529 +// gas legacyOptimized code: 54600 // f() -> 2 diff --git a/test/libsolidity/semanticTests/functionCall/external_call_to_nonexisting.sol b/test/libsolidity/semanticTests/functionCall/external_call_to_nonexisting.sol index a1c74cf89838..9d521f7777f9 100644 --- a/test/libsolidity/semanticTests/functionCall/external_call_to_nonexisting.sol +++ b/test/libsolidity/semanticTests/functionCall/external_call_to_nonexisting.sol @@ -22,9 +22,12 @@ contract C { } // ---- // constructor(), 1 ether -> -// gas irOptimized: 262355 -// gas legacy: 441442 -// gas legacyOptimized: 292862 +// gas irOptimized: 89555 +// gas irOptimized code: 172800 +// gas legacy: 103042 +// gas legacy code: 338400 +// gas legacyOptimized: 91862 +// gas legacyOptimized code: 201000 // f(uint256): 0 -> FAILURE // f(uint256): 1 -> FAILURE // f(uint256): 2 -> FAILURE 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 96f097ce7f4a..9baacd812773 100644 --- a/test/libsolidity/semanticTests/functionCall/external_call_to_nonexisting_debugstrings.sol +++ b/test/libsolidity/semanticTests/functionCall/external_call_to_nonexisting_debugstrings.sol @@ -25,9 +25,12 @@ contract C { // revertStrings: debug // ---- // constructor(), 1 ether -> -// gas irOptimized: 390464 -// gas legacy: 809985 -// gas legacyOptimized: 498331 +// gas irOptimized: 99264 +// gas irOptimized code: 291200 +// gas legacy: 123585 +// gas legacy code: 686400 +// gas legacyOptimized: 107331 +// gas legacyOptimized code: 391000 // 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" diff --git a/test/libsolidity/semanticTests/functionCall/failed_create.sol b/test/libsolidity/semanticTests/functionCall/failed_create.sol index 091e5a77a62a..b6c077753a51 100644 --- a/test/libsolidity/semanticTests/functionCall/failed_create.sol +++ b/test/libsolidity/semanticTests/functionCall/failed_create.sol @@ -17,9 +17,12 @@ contract C { // EVMVersion: >=byzantium // ---- // constructor(), 20 wei -// gas irOptimized: 166148 -// gas legacy: 285547 -// gas legacyOptimized: 168515 +// gas irOptimized: 61548 +// gas irOptimized code: 104600 +// gas legacy: 70147 +// gas legacy code: 215400 +// gas legacyOptimized: 61715 +// gas legacyOptimized code: 106800 // f(uint256): 20 -> 0x137aa4dfc0911524504fcd4d98501f179bc13b4a // x() -> 1 // f(uint256): 20 -> FAILURE diff --git a/test/libsolidity/semanticTests/functionCall/gas_and_value_basic.sol b/test/libsolidity/semanticTests/functionCall/gas_and_value_basic.sol index 8396cb12db8d..806c8eb41b9d 100644 --- a/test/libsolidity/semanticTests/functionCall/gas_and_value_basic.sol +++ b/test/libsolidity/semanticTests/functionCall/gas_and_value_basic.sol @@ -38,9 +38,12 @@ contract test { } // ---- // constructor(), 20 wei -> -// gas irOptimized: 252626 -// gas legacy: 391568 -// gas legacyOptimized: 268069 +// gas irOptimized: 120226 +// gas irOptimized code: 132400 +// gas legacy: 130568 +// gas legacy code: 261000 +// gas legacyOptimized: 121069 +// gas legacyOptimized code: 147000 // sendAmount(uint256): 5 -> 5 // outOfGas() -> FAILURE # call to helper should not succeed but amount should be transferred anyway # // checkState() -> false, 15 diff --git a/test/libsolidity/semanticTests/functionCall/gas_and_value_brace_syntax.sol b/test/libsolidity/semanticTests/functionCall/gas_and_value_brace_syntax.sol index 9d9c3f603f78..c186fc40b22c 100644 --- a/test/libsolidity/semanticTests/functionCall/gas_and_value_brace_syntax.sol +++ b/test/libsolidity/semanticTests/functionCall/gas_and_value_brace_syntax.sol @@ -37,9 +37,12 @@ contract test { } // ---- // constructor(), 20 wei -> -// gas irOptimized: 252626 -// gas legacy: 391568 -// gas legacyOptimized: 268069 +// gas irOptimized: 120226 +// gas irOptimized code: 132400 +// gas legacy: 130568 +// gas legacy code: 261000 +// gas legacyOptimized: 121069 +// gas legacyOptimized code: 147000 // sendAmount(uint256): 5 -> 5 // outOfGas() -> FAILURE # call to helper should not succeed but amount should be transferred anyway # // checkState() -> false, 15 diff --git a/test/libsolidity/semanticTests/functionCall/send_zero_ether.sol b/test/libsolidity/semanticTests/functionCall/send_zero_ether.sol index a737de5cd4e7..94a721323244 100644 --- a/test/libsolidity/semanticTests/functionCall/send_zero_ether.sol +++ b/test/libsolidity/semanticTests/functionCall/send_zero_ether.sol @@ -16,6 +16,7 @@ contract Main { // ---- // constructor(), 20 wei -> // gas irOptimized: 100264 -// gas legacy: 110555 +// gas legacy: 57555 +// gas legacy code: 53000 // gas legacyOptimized: 100361 // s() -> true diff --git a/test/libsolidity/semanticTests/functionTypes/store_function.sol b/test/libsolidity/semanticTests/functionTypes/store_function.sol index 132a6c95659a..5397d0b70187 100644 --- a/test/libsolidity/semanticTests/functionTypes/store_function.sol +++ b/test/libsolidity/semanticTests/functionTypes/store_function.sol @@ -26,5 +26,7 @@ contract C { // ---- // t() -> 9 // gas irOptimized: 99064 -// gas legacy: 149095 -// gas legacyOptimized: 106188 +// gas legacy: 79495 +// gas legacy code: 69600 +// gas legacyOptimized: 77588 +// gas legacyOptimized code: 28600 diff --git a/test/libsolidity/semanticTests/immutable/multi_creation.sol b/test/libsolidity/semanticTests/immutable/multi_creation.sol index 145c32add6e9..c8806c50d060 100644 --- a/test/libsolidity/semanticTests/immutable/multi_creation.sol +++ b/test/libsolidity/semanticTests/immutable/multi_creation.sol @@ -27,8 +27,11 @@ contract C { } // ---- // f() -> 3, 7, 5 -// gas irOptimized: 124021 -// gas legacy: 148528 -// gas legacyOptimized: 123971 +// gas irOptimized: 86821 +// gas irOptimized code: 37200 +// gas legacy: 87728 +// gas legacy code: 60800 +// gas legacyOptimized: 86771 +// gas legacyOptimized code: 37200 // x() -> 7 // y() -> 5 diff --git a/test/libsolidity/semanticTests/immutable/use_scratch.sol b/test/libsolidity/semanticTests/immutable/use_scratch.sol index a7c8ea6a502a..dc07086c29c3 100644 --- a/test/libsolidity/semanticTests/immutable/use_scratch.sol +++ b/test/libsolidity/semanticTests/immutable/use_scratch.sol @@ -15,8 +15,11 @@ contract C { } // ---- // constructor(): 3 -> -// gas irOptimized: 123526 -// gas legacy: 197645 -// gas legacyOptimized: 137658 +// gas irOptimized: 81126 +// gas irOptimized code: 42400 +// gas legacy: 88245 +// gas legacy code: 109400 +// gas legacyOptimized: 81858 +// gas legacyOptimized code: 55800 // f() -> 84, 23 // m(uint256): 3 -> 7 diff --git a/test/libsolidity/semanticTests/inheritance/address_overload_resolution.sol b/test/libsolidity/semanticTests/inheritance/address_overload_resolution.sol index c65d1abec558..0865ed2876ad 100644 --- a/test/libsolidity/semanticTests/inheritance/address_overload_resolution.sol +++ b/test/libsolidity/semanticTests/inheritance/address_overload_resolution.sol @@ -21,7 +21,9 @@ contract D { // ---- // f() -> 1 // gas irOptimized: 77051 -// gas legacy: 112280 +// gas legacy: 54480 +// gas legacy code: 57800 // g() -> 5 // gas irOptimized: 77106 -// gas legacy: 112816 +// gas legacy: 55016 +// gas legacy code: 57800 diff --git a/test/libsolidity/semanticTests/inheritance/inherited_function_calldata_calldata_interface.sol b/test/libsolidity/semanticTests/inheritance/inherited_function_calldata_calldata_interface.sol index 3114c80f1912..0567c2ab1412 100644 --- a/test/libsolidity/semanticTests/inheritance/inherited_function_calldata_calldata_interface.sol +++ b/test/libsolidity/semanticTests/inheritance/inherited_function_calldata_calldata_interface.sol @@ -23,4 +23,5 @@ contract B { // ---- // g() -> 42 // gas irOptimized: 80813 -// gas legacy: 122471 +// gas legacy: 55871 +// gas legacy code: 66600 diff --git a/test/libsolidity/semanticTests/inheritance/inherited_function_calldata_memory_interface.sol b/test/libsolidity/semanticTests/inheritance/inherited_function_calldata_memory_interface.sol index 74bf42ec7e61..d5ff54b68a16 100644 --- a/test/libsolidity/semanticTests/inheritance/inherited_function_calldata_memory_interface.sol +++ b/test/libsolidity/semanticTests/inheritance/inherited_function_calldata_memory_interface.sol @@ -23,5 +23,7 @@ contract B { // ---- // g() -> 42 // gas irOptimized: 100282 -// gas legacy: 180440 -// gas legacyOptimized: 112596 +// gas legacy: 56840 +// gas legacy code: 123600 +// gas legacyOptimized: 54996 +// gas legacyOptimized code: 57600 diff --git a/test/libsolidity/semanticTests/inheritance/member_notation_ctor.sol b/test/libsolidity/semanticTests/inheritance/member_notation_ctor.sol index 263588abab5c..e704a297bbac 100644 --- a/test/libsolidity/semanticTests/inheritance/member_notation_ctor.sol +++ b/test/libsolidity/semanticTests/inheritance/member_notation_ctor.sol @@ -19,6 +19,8 @@ contract A { } // ---- // g(int256): -1 -> -1 -// gas legacy: 102078 +// gas legacy: 77878 +// gas legacy code: 24200 // g(int256): 10 -> 10 -// gas legacy: 101706 +// gas legacy: 77506 +// gas legacy code: 24200 diff --git a/test/libsolidity/semanticTests/inheritance/value_for_constructor.sol b/test/libsolidity/semanticTests/inheritance/value_for_constructor.sol index 9627ad025ddd..fdd0bafaadfe 100644 --- a/test/libsolidity/semanticTests/inheritance/value_for_constructor.sol +++ b/test/libsolidity/semanticTests/inheritance/value_for_constructor.sol @@ -39,9 +39,12 @@ contract Main { } // ---- // constructor(), 22 wei -> -// gas irOptimized: 261864 -// gas legacy: 392786 -// gas legacyOptimized: 261593 +// gas irOptimized: 143864 +// gas irOptimized code: 118000 +// gas legacy: 156586 +// gas legacy code: 236200 +// gas legacyOptimized: 143593 +// gas legacyOptimized code: 118000 // getFlag() -> true // getName() -> "abc" // getBalances() -> 12, 10 diff --git a/test/libsolidity/semanticTests/isoltestTesting/balance_other_contract.sol b/test/libsolidity/semanticTests/isoltestTesting/balance_other_contract.sol index 1a5c9b19b416..0ad55b5ddff1 100644 --- a/test/libsolidity/semanticTests/isoltestTesting/balance_other_contract.sol +++ b/test/libsolidity/semanticTests/isoltestTesting/balance_other_contract.sol @@ -16,9 +16,12 @@ contract ClientReceipt { } // ---- // constructor(), 2000 wei -> -// gas irOptimized: 169907 -// gas legacy: 230018 -// gas legacyOptimized: 173867 +// gas irOptimized: 114107 +// gas irOptimized code: 55800 +// gas legacy: 118618 +// gas legacy code: 111400 +// gas legacyOptimized: 114067 +// gas legacyOptimized code: 59800 // balance -> 1500 // gas irOptimized: 191881 // gas legacy: 235167 diff --git a/test/libsolidity/semanticTests/operators/userDefined/operator_making_pure_external_call.sol b/test/libsolidity/semanticTests/operators/userDefined/operator_making_pure_external_call.sol index ce6a0f48db09..a621b4c12ad5 100644 --- a/test/libsolidity/semanticTests/operators/userDefined/operator_making_pure_external_call.sol +++ b/test/libsolidity/semanticTests/operators/userDefined/operator_making_pure_external_call.sol @@ -53,9 +53,13 @@ contract C { // ---- // testMul(int32,int32): 42, 10 -> 420 // gas irOptimized: 102563 -// gas legacy: 183981 -// gas legacyOptimized: 123563 +// gas legacy: 56981 +// gas legacy code: 127000 +// gas legacyOptimized: 55163 +// gas legacyOptimized code: 68400 // testInc(int32): 42 -> 43 // gas irOptimized: 102386 -// gas legacy: 183239 -// gas legacyOptimized: 123251 +// gas legacy: 56239 +// gas legacy code: 127000 +// gas legacyOptimized: 54851 +// gas legacyOptimized code: 68400 diff --git a/test/libsolidity/semanticTests/operators/userDefined/operator_making_view_external_call.sol b/test/libsolidity/semanticTests/operators/userDefined/operator_making_view_external_call.sol index f3f8ebdc63db..84f6bf08e7a6 100644 --- a/test/libsolidity/semanticTests/operators/userDefined/operator_making_view_external_call.sol +++ b/test/libsolidity/semanticTests/operators/userDefined/operator_making_view_external_call.sol @@ -59,9 +59,13 @@ contract C { // ---- // testMul(int32,int32): 42, 10 -> 420 // gas irOptimized: 102563 -// gas legacy: 183981 -// gas legacyOptimized: 123563 +// gas legacy: 56981 +// gas legacy code: 127000 +// gas legacyOptimized: 55163 +// gas legacyOptimized code: 68400 // testInc(int32): 42 -> 43 // gas irOptimized: 102386 -// gas legacy: 183239 -// gas legacyOptimized: 123251 +// gas legacy: 56239 +// gas legacy code: 127000 +// gas legacyOptimized: 54851 +// gas legacyOptimized code: 68400 diff --git a/test/libsolidity/semanticTests/salted_create/prediction_example.sol b/test/libsolidity/semanticTests/salted_create/prediction_example.sol index e7171536d6bb..6fa865440bd4 100644 --- a/test/libsolidity/semanticTests/salted_create/prediction_example.sol +++ b/test/libsolidity/semanticTests/salted_create/prediction_example.sol @@ -26,4 +26,5 @@ contract C { // compileViaYul: also // ---- // createDSalted(bytes32,uint256): 42, 64 -> -// gas legacy: 102841 +// gas legacy: 79241 +// gas legacy code: 23600 diff --git a/test/libsolidity/semanticTests/salted_create/salted_create.sol b/test/libsolidity/semanticTests/salted_create/salted_create.sol index 743ff5fd2a23..535a2813c17c 100644 --- a/test/libsolidity/semanticTests/salted_create/salted_create.sol +++ b/test/libsolidity/semanticTests/salted_create/salted_create.sol @@ -21,6 +21,9 @@ contract A { // ---- // different_salt() -> true // same_salt() -> true -// gas irOptimized: 98438895 -// gas legacy: 98439109 -// gas legacyOptimized: 98438967 +// gas irOptimized: 98438295 +// gas irOptimized code: 600 +// gas legacy: 98437509 +// gas legacy code: 1600 +// gas legacyOptimized: 98437367 +// gas legacyOptimized code: 1600 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 58b3f076034c..735731c8abf7 100644 --- a/test/libsolidity/semanticTests/salted_create/salted_create_with_value.sol +++ b/test/libsolidity/semanticTests/salted_create/salted_create_with_value.sol @@ -21,6 +21,9 @@ contract A { // EVMVersion: >=constantinople // ---- // f(), 10 ether -> 3007, 3008, 3009 -// gas irOptimized: 253005 -// gas legacy: 381063 -// gas legacyOptimized: 279658 +// gas irOptimized: 187005 +// gas irOptimized code: 66000 +// gas legacy: 190863 +// gas legacy code: 190200 +// gas legacyOptimized: 187258 +// gas legacyOptimized code: 92400 diff --git a/test/libsolidity/semanticTests/smoke/alignment.sol b/test/libsolidity/semanticTests/smoke/alignment.sol index 3e8016f988f8..296ae0161711 100644 --- a/test/libsolidity/semanticTests/smoke/alignment.sol +++ b/test/libsolidity/semanticTests/smoke/alignment.sol @@ -25,5 +25,6 @@ contract D { // stateDecimal() -> right(42) // stateBytes() -> left(0x4200ef) // internalStateDecimal() -> 0x20 -// gas legacy: 100265 +// gas legacy: 76665 +// gas legacy code: 23600 // update(bool,uint256,bytes32): false, -23, left(0x2300ef) -> false, -23, left(0x2300ef) diff --git a/test/libsolidity/semanticTests/smoke/constructor.sol b/test/libsolidity/semanticTests/smoke/constructor.sol index 55789b2f4b65..2783fe4a8c9c 100644 --- a/test/libsolidity/semanticTests/smoke/constructor.sol +++ b/test/libsolidity/semanticTests/smoke/constructor.sol @@ -12,9 +12,12 @@ contract C { } // ---- // constructor(), 2 wei: 3 -> -// gas irOptimized: 104396 -// gas legacy: 148256 -// gas legacyOptimized: 106699 +// gas irOptimized: 78996 +// gas irOptimized code: 25400 +// gas legacy: 83056 +// gas legacy code: 65200 +// gas legacyOptimized: 78899 +// gas legacyOptimized code: 27800 // state() -> 3 // balance() -> 2 // balance -> 2 diff --git a/test/libsolidity/semanticTests/state/blockhash_basic.sol b/test/libsolidity/semanticTests/state/blockhash_basic.sol index 03d6f9fe76ea..64b8d55a26b6 100644 --- a/test/libsolidity/semanticTests/state/blockhash_basic.sol +++ b/test/libsolidity/semanticTests/state/blockhash_basic.sol @@ -12,9 +12,12 @@ contract C { } // ---- // constructor() -// gas irOptimized: 108138 -// gas legacy: 152171 -// gas legacyOptimized: 106738 +// gas irOptimized: 80338 +// gas irOptimized code: 27800 +// gas legacy: 83571 +// gas legacy code: 68600 +// gas legacyOptimized: 80338 +// gas legacyOptimized code: 26400 // genesisHash() -> 0x3737373737373737373737373737373737373737373737373737373737373737 // currentHash() -> 0 // f(uint256): 0 -> 0x3737373737373737373737373737373737373737373737373737373737373737 diff --git a/test/libsolidity/semanticTests/userDefinedValueType/erc20.sol b/test/libsolidity/semanticTests/userDefinedValueType/erc20.sol index ac8609d71324..8976cf3c52cc 100644 --- a/test/libsolidity/semanticTests/userDefinedValueType/erc20.sol +++ b/test/libsolidity/semanticTests/userDefinedValueType/erc20.sol @@ -113,9 +113,12 @@ contract ERC20 { // ---- // constructor() // ~ emit Transfer(address,address,uint256): #0x00, #0x1212121212121212121212121212120000000012, 0x14 -// gas irOptimized: 352682 -// gas legacy: 834752 -// gas legacyOptimized: 412648 +// gas irOptimized: 121082 +// gas irOptimized code: 231600 +// gas legacy: 163352 +// gas legacy code: 671400 +// gas legacyOptimized: 127448 +// gas legacyOptimized code: 285200 // totalSupply() -> 20 // gas irOptimized: 23415 // gas legacy: 23653 diff --git a/test/libsolidity/semanticTests/using/using_global_invisible.sol b/test/libsolidity/semanticTests/using/using_global_invisible.sol index 3e767a185d90..818707f6fe35 100644 --- a/test/libsolidity/semanticTests/using/using_global_invisible.sol +++ b/test/libsolidity/semanticTests/using/using_global_invisible.sol @@ -40,4 +40,5 @@ contract D { // ---- // library: "A":L // test() -> 3 -// gas legacy: 120881 +// gas legacy: 59681 +// gas legacy code: 61200 diff --git a/test/libsolidity/semanticTests/various/address_code.sol b/test/libsolidity/semanticTests/various/address_code.sol index 7e48b00ca840..6a97c0bf7ee2 100644 --- a/test/libsolidity/semanticTests/various/address_code.sol +++ b/test/libsolidity/semanticTests/various/address_code.sol @@ -14,9 +14,12 @@ contract C { } // ---- // constructor() -> -// gas irOptimized: 173273 -// gas legacy: 241796 -// gas legacyOptimized: 153670 +// gas irOptimized: 70873 +// gas irOptimized code: 102400 +// gas legacy: 82796 +// gas legacy code: 159000 +// gas legacyOptimized: 69870 +// gas legacyOptimized code: 83800 // initCode() -> 0x20, 0 // f() -> true // g() -> 0 diff --git a/test/libsolidity/semanticTests/various/code_access_content.sol b/test/libsolidity/semanticTests/various/code_access_content.sol index 92d31d621433..dc4e49b2dae0 100644 --- a/test/libsolidity/semanticTests/various/code_access_content.sol +++ b/test/libsolidity/semanticTests/various/code_access_content.sol @@ -38,6 +38,8 @@ contract C { } // ---- // testRuntime() -> true -// gas legacy: 100177 +// gas legacy: 76577 +// gas legacy code: 23600 // testCreation() -> true -// gas legacy: 100600 +// gas legacy: 77000 +// gas legacy code: 23600 diff --git a/test/libsolidity/semanticTests/various/code_access_create.sol b/test/libsolidity/semanticTests/various/code_access_create.sol index 075682129cda..d2b7f92f4e66 100644 --- a/test/libsolidity/semanticTests/various/code_access_create.sol +++ b/test/libsolidity/semanticTests/various/code_access_create.sol @@ -23,4 +23,5 @@ contract C { } // ---- // test() -> 7 -// gas legacy: 100849 +// gas legacy: 76649 +// gas legacy code: 24200 diff --git a/test/libsolidity/semanticTests/various/code_access_runtime.sol b/test/libsolidity/semanticTests/various/code_access_runtime.sol index 9a9e7a80bf90..b62eb0b8535c 100644 --- a/test/libsolidity/semanticTests/various/code_access_runtime.sol +++ b/test/libsolidity/semanticTests/various/code_access_runtime.sol @@ -23,4 +23,5 @@ contract C { // EVMVersion: >=constantinople // ---- // test() -> 42 -// gas legacy: 100235 +// gas legacy: 76035 +// gas legacy code: 24200 diff --git a/test/libsolidity/semanticTests/various/code_length.sol b/test/libsolidity/semanticTests/various/code_length.sol index a8aac5306f50..c30ac838fe4c 100644 --- a/test/libsolidity/semanticTests/various/code_length.sol +++ b/test/libsolidity/semanticTests/various/code_length.sol @@ -59,5 +59,6 @@ contract C { } // ---- // constructor() -// gas legacy: 124136 +// gas legacy: 66936 +// gas legacy code: 57200 // f(): true, true -> true, true diff --git a/test/libsolidity/semanticTests/various/create_calldata.sol b/test/libsolidity/semanticTests/various/create_calldata.sol index c3d038136f6e..2db42adebb86 100644 --- a/test/libsolidity/semanticTests/various/create_calldata.sol +++ b/test/libsolidity/semanticTests/various/create_calldata.sol @@ -8,7 +8,10 @@ contract C { } // ---- // constructor(): 42 -> -// gas irOptimized: 145578 -// gas legacy: 173845 -// gas legacyOptimized: 137877 +// gas irOptimized: 68378 +// gas irOptimized code: 77200 +// gas legacy: 78445 +// gas legacy code: 95400 +// gas legacyOptimized: 68677 +// gas legacyOptimized code: 69200 // s() -> 0x20, 0 diff --git a/test/libsolidity/semanticTests/various/erc20.sol b/test/libsolidity/semanticTests/various/erc20.sol index 00c12fb18a70..f7956c4c50eb 100644 --- a/test/libsolidity/semanticTests/various/erc20.sol +++ b/test/libsolidity/semanticTests/various/erc20.sol @@ -96,9 +96,12 @@ contract ERC20 { // ---- // constructor() // ~ emit Transfer(address,address,uint256): #0x00, #0x1212121212121212121212121212120000000012, 0x14 -// gas irOptimized: 353248 -// gas legacy: 807559 -// gas legacyOptimized: 408718 +// gas irOptimized: 121248 +// gas irOptimized code: 232000 +// gas legacy: 159959 +// gas legacy code: 647600 +// gas legacyOptimized: 126918 +// gas legacyOptimized code: 281800 // totalSupply() -> 20 // gas irOptimized: 23415 // gas legacy: 23524 diff --git a/test/libsolidity/semanticTests/various/external_types_in_calls.sol b/test/libsolidity/semanticTests/various/external_types_in_calls.sol index e8742c2346b0..aff302d26e8f 100644 --- a/test/libsolidity/semanticTests/various/external_types_in_calls.sol +++ b/test/libsolidity/semanticTests/various/external_types_in_calls.sol @@ -24,5 +24,6 @@ contract C { } // ---- // test() -> 9, 7 -// gas legacy: 127514 +// gas legacy: 80314 +// gas legacy code: 47200 // t2() -> 9 diff --git a/test/libsolidity/semanticTests/various/many_subassemblies.sol b/test/libsolidity/semanticTests/various/many_subassemblies.sol index 26c3a1bbff7b..67a576da7889 100644 --- a/test/libsolidity/semanticTests/various/many_subassemblies.sol +++ b/test/libsolidity/semanticTests/various/many_subassemblies.sol @@ -30,6 +30,9 @@ contract D { } // ---- // run() -> -// gas irOptimized: 381615 -// gas legacy: 392719 -// gas legacyOptimized: 392719 +// gas irOptimized: 375015 +// gas irOptimized code: 6600 +// gas legacy: 375119 +// gas legacy code: 17600 +// gas legacyOptimized: 375119 +// gas legacyOptimized code: 17600 diff --git a/test/libsolidity/semanticTests/various/negative_stack_height.sol b/test/libsolidity/semanticTests/various/negative_stack_height.sol index 7289d2bbd96f..44fd0089cf70 100644 --- a/test/libsolidity/semanticTests/various/negative_stack_height.sol +++ b/test/libsolidity/semanticTests/various/negative_stack_height.sol @@ -65,5 +65,7 @@ contract C { // compileViaYul: false // ---- // constructor() -> -// gas legacy: 575268 -// gas legacyOptimized: 345022 +// gas legacy: 92268 +// gas legacy code: 483000 +// gas legacyOptimized: 75022 +// gas legacyOptimized code: 270000 diff --git a/test/libsolidity/semanticTests/various/selfdestruct_pre_cancun.sol b/test/libsolidity/semanticTests/various/selfdestruct_pre_cancun.sol index 4142eb25cf2d..a39b6c42355c 100644 --- a/test/libsolidity/semanticTests/various/selfdestruct_pre_cancun.sol +++ b/test/libsolidity/semanticTests/various/selfdestruct_pre_cancun.sol @@ -62,9 +62,12 @@ contract D { // EVMVersion: =shanghai // ---- // constructor(), 1 ether -> -// gas irOptimized: 242428 -// gas legacy: 373563 -// gas legacyOptimized: 234516 +// gas irOptimized: 67028 +// gas irOptimized code: 175400 +// gas legacy: 76163 +// gas legacy code: 297400 +// gas legacyOptimized: 66516 +// gas legacyOptimized code: 168000 // exists() -> false // test_create_and_terminate() -> // exists() -> false diff --git a/test/libsolidity/semanticTests/various/selfdestruct_pre_cancun_multiple_beneficiaries.sol b/test/libsolidity/semanticTests/various/selfdestruct_pre_cancun_multiple_beneficiaries.sol index 87e81a2902d1..a09a7cac68b1 100644 --- a/test/libsolidity/semanticTests/various/selfdestruct_pre_cancun_multiple_beneficiaries.sol +++ b/test/libsolidity/semanticTests/various/selfdestruct_pre_cancun_multiple_beneficiaries.sol @@ -35,23 +35,30 @@ contract D { // EVMVersion: <=shanghai // ---- // constructor(), 2 ether -> -// gas irOptimized: 223918 -// gas legacy: 374024 -// gas legacyOptimized: 239815 +// gas irOptimized: 107718 +// gas irOptimized code: 116200 +// gas legacy: 120424 +// gas legacy code: 253600 +// gas legacyOptimized: 109015 +// gas legacyOptimized code: 130800 // balance: 0x1111111111111111111111111111111111111111 -> 0 // balance: 0x2222222222222222222222222222222222222222 -> 0 // balance -> 2000000000000000000 // exists() -> false // test_deploy_and_terminate_twice() -> -// gas irOptimized: 135350 -// gas legacy: 165584 -// gas legacyOptimized: 144396 +// gas irOptimized: 121350 +// gas irOptimized code: 14000 +// gas legacy: 122384 +// gas legacy code: 43200 +// gas legacyOptimized: 121596 +// gas legacyOptimized code: 22800 // exists() -> false // balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000 // balance: 0x2222222222222222222222222222222222222222 -> 0 // balance -> 1000000000000000000 // deploy() -> -// gas legacy: 101691 +// gas legacy: 58491 +// gas legacy code: 43200 // exists() -> true // balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000 // balance: 0x2222222222222222222222222222222222222222 -> 0 diff --git a/test/libsolidity/semanticTests/various/selfdestruct_pre_cancun_redeploy.sol b/test/libsolidity/semanticTests/various/selfdestruct_pre_cancun_redeploy.sol index e0885782c260..fc650ebba741 100644 --- a/test/libsolidity/semanticTests/various/selfdestruct_pre_cancun_redeploy.sol +++ b/test/libsolidity/semanticTests/various/selfdestruct_pre_cancun_redeploy.sol @@ -79,15 +79,21 @@ contract D { // EVMVersion: =shanghai // ---- // constructor(), 1 ether -> -// gas irOptimized: 430253 -// gas legacy: 690244 -// gas legacyOptimized: 412799 +// gas irOptimized: 133253 +// gas irOptimized code: 297000 +// gas legacy: 151644 +// gas legacy code: 538600 +// gas legacyOptimized: 131799 +// gas legacyOptimized code: 281000 // exists() -> false // test_deploy_and_terminate() -> // ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000 -// gas irOptimized: 117489 -// gas legacy: 118895 -// gas legacyOptimized: 117137 +// gas irOptimized: 96689 +// gas irOptimized code: 20800 +// gas legacy: 98095 +// gas legacy code: 20800 +// gas legacyOptimized: 96337 +// gas legacyOptimized code: 20800 // exists() -> false // deploy_create2() -> // ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000 diff --git a/test/libsolidity/semanticTests/various/senders_balance.sol b/test/libsolidity/semanticTests/various/senders_balance.sol index a1c7d4147fc6..5b4371149f42 100644 --- a/test/libsolidity/semanticTests/various/senders_balance.sol +++ b/test/libsolidity/semanticTests/various/senders_balance.sol @@ -16,7 +16,10 @@ contract D { } // ---- // constructor(), 27 wei -> -// gas irOptimized: 167857 -// gas legacy: 218435 -// gas legacyOptimized: 167276 +// gas irOptimized: 114057 +// gas irOptimized code: 53800 +// gas legacy: 117835 +// gas legacy code: 100600 +// gas legacyOptimized: 113676 +// gas legacyOptimized code: 53600 // f() -> 27 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 1306529d4183..77a330f3cd54 100644 --- a/test/libsolidity/semanticTests/various/staticcall_for_view_and_pure.sol +++ b/test/libsolidity/semanticTests/various/staticcall_for_view_and_pure.sol @@ -35,12 +35,19 @@ contract D { // EVMVersion: >=byzantium // ---- // f() -> 0x1 # This should work, next should throw # -// gas legacy: 102095 +// gas legacy: 76495 +// gas legacy code: 25600 // fview() -> FAILURE -// gas irOptimized: 98438588 -// gas legacy: 98438774 -// gas legacyOptimized: 98438580 +// gas irOptimized: 98425388 +// gas irOptimized code: 13200 +// gas legacy: 98413174 +// gas legacy code: 25600 +// gas legacyOptimized: 98425380 +// gas legacyOptimized code: 13200 // fpure() -> FAILURE -// gas irOptimized: 98438589 -// gas legacy: 98438774 -// gas legacyOptimized: 98438580 +// gas irOptimized: 98425389 +// gas irOptimized code: 13200 +// gas legacy: 98413174 +// gas legacy code: 25600 +// gas legacyOptimized: 98425380 +// gas legacyOptimized code: 13200 diff --git a/test/libsolidity/semanticTests/various/value_complex.sol b/test/libsolidity/semanticTests/various/value_complex.sol index 2adac6bf4cd0..427a006dc102 100644 --- a/test/libsolidity/semanticTests/various/value_complex.sol +++ b/test/libsolidity/semanticTests/various/value_complex.sol @@ -19,7 +19,10 @@ contract test { } // ---- // constructor(), 20 wei -> -// gas irOptimized: 172399 -// gas legacy: 252276 -// gas legacyOptimized: 180336 +// gas irOptimized: 114399 +// gas irOptimized code: 58000 +// gas legacy: 120076 +// gas legacy code: 132200 +// gas legacyOptimized: 114536 +// gas legacyOptimized code: 65800 // sendAmount(uint256): 5 -> 8 diff --git a/test/libsolidity/semanticTests/various/value_insane.sol b/test/libsolidity/semanticTests/various/value_insane.sol index 87fa01485d61..97fbbab1e634 100644 --- a/test/libsolidity/semanticTests/various/value_insane.sol +++ b/test/libsolidity/semanticTests/various/value_insane.sol @@ -18,7 +18,10 @@ contract test { } // ---- // constructor(), 20 wei -> -// gas irOptimized: 173263 -// gas legacy: 253800 -// gas legacyOptimized: 180768 +// gas irOptimized: 114463 +// gas irOptimized code: 58800 +// gas legacy: 120200 +// gas legacy code: 133600 +// gas legacyOptimized: 114568 +// gas legacyOptimized code: 66200 // sendAmount(uint256): 5 -> 8 diff --git a/test/libsolidity/util/SoltestTypes.h b/test/libsolidity/util/SoltestTypes.h index a2d593fd3c65..791cea011610 100644 --- a/test/libsolidity/util/SoltestTypes.h +++ b/test/libsolidity/util/SoltestTypes.h @@ -215,11 +215,11 @@ struct FunctionCallExpectations raw += param.rawBytes; return raw; } - /// Gas used by function call - /// Keys represent all distinct combinations of compilation settings that affect produced + /// Gas used by function call minus the portion spent on code deposits (which is tracked + /// separately, in @a gasUsedForCodeDeposit). /// bytecode (and therefore the cost), except for EVM version. E.g. IR codegen without /// optimization legacy codegen with optimization. - std::map gasUsed; + std::map gasUsedExcludingCode; /// The portion of @a gasUsed spent on code deposits of newly created contracts. /// May exceed @a gasUsed in rare corner cases due to refunds. diff --git a/test/libsolidity/util/TestFileParser.cpp b/test/libsolidity/util/TestFileParser.cpp index e7e20f7c5cb5..5a32a1591a16 100644 --- a/test/libsolidity/util/TestFileParser.cpp +++ b/test/libsolidity/util/TestFileParser.cpp @@ -103,7 +103,7 @@ std::vector TestFileParser::parseFunctio std::map& gasExpectationMap = (isCodeDepositCost ? calls.back().expectations.gasUsedForCodeDeposit : - calls.back().expectations.gasUsed + calls.back().expectations.gasUsedExcludingCode ); if (gasExpectationMap.count(runType) > 0) throw TestParserError("Gas usage expectation set multiple times."); @@ -207,9 +207,9 @@ std::vector TestFileParser::parseFunctio { // Ensure that each specified gas expectation has both components to simplify working with them. for (auto const& [runType, gas]: call.expectations.gasUsedForCodeDeposit) - call.expectations.gasUsed.try_emplace({runType, 0}); + call.expectations.gasUsedExcludingCode.try_emplace({runType, 0}); - for (auto const& [runType, gas]: call.expectations.gasUsed) + for (auto const& [runType, gas]: call.expectations.gasUsedExcludingCode) call.expectations.gasUsedForCodeDeposit.try_emplace({runType, 0}); } diff --git a/test/libsolidity/util/TestFileParserTests.cpp b/test/libsolidity/util/TestFileParserTests.cpp index 7a794f915265..4bb4aed3aced 100644 --- a/test/libsolidity/util/TestFileParserTests.cpp +++ b/test/libsolidity/util/TestFileParserTests.cpp @@ -1074,7 +1074,7 @@ BOOST_AUTO_TEST_CASE(gas) auto const calls = parse(source); BOOST_REQUIRE_EQUAL(calls.size(), 1); BOOST_REQUIRE_EQUAL(calls[0].expectations.failure, false); - BOOST_TEST(calls[0].expectations.gasUsed == (std::map{ + BOOST_TEST(calls[0].expectations.gasUsedExcludingCode == (std::map{ {"ir", 3245}, {"legacy", 5000}, {"legacyOptimized", 0}, @@ -1121,19 +1121,19 @@ BOOST_AUTO_TEST_CASE(gas_with_code_deposit_cost) // f() -> // gas legacyOptimized code: 1 // gas ir: 13000 - // gas irOptimized: 6666 + // gas irOptimized: 6000 // gas irOptimized code: 666 // gas legacy code: 0 - // gas legacyOptimized: 2 + // gas legacyOptimized: 1 )"; auto const calls = parse(source); BOOST_REQUIRE_EQUAL(calls.size(), 1); BOOST_REQUIRE_EQUAL(calls[0].expectations.failure, false); - BOOST_TEST(calls[0].expectations.gasUsed == (std::map{ + BOOST_TEST(calls[0].expectations.gasUsedExcludingCode == (std::map{ {"ir", 13000}, - {"irOptimized", 6666}, + {"irOptimized", 6000}, {"legacy", 0}, - {"legacyOptimized", 2}, + {"legacyOptimized", 1}, })); BOOST_TEST(calls[0].expectations.gasUsedForCodeDeposit == (std::map{ {"ir", 0}, @@ -1175,27 +1175,20 @@ BOOST_AUTO_TEST_CASE(gas_with_code_deposit_cost_double_code_gas) BOOST_AUTO_TEST_CASE(gas_with_code_deposit_cost_negative_non_code_cost) { // NOTE: This arrangement is unlikely but may still be possible due to refunds. + // We'll deal with it when we actually have a test case like that. char const* source = R"( // f() -> - // gas ir: 10 + // gas ir: -10 // gas ir code: 20 )"; - auto const calls = parse(source); - BOOST_REQUIRE_EQUAL(calls.size(), 1); - BOOST_REQUIRE_EQUAL(calls[0].expectations.failure, false); - BOOST_TEST(calls[0].expectations.gasUsed == (std::map{ - {"ir", 10}, - })); - BOOST_TEST(calls[0].expectations.gasUsedForCodeDeposit == (std::map{ - {"ir", 20}, - })); + BOOST_REQUIRE_THROW(parse(source), TestParserError); } BOOST_AUTO_TEST_CASE(gas_with_code_deposit_cost_negative_total_cost) { char const* source = R"( // f() -> - // gas ir: -10 + // gas ir: -30 // gas ir code: 20 )"; BOOST_REQUIRE_THROW(parse(source), TestParserError); @@ -1205,7 +1198,7 @@ BOOST_AUTO_TEST_CASE(gas_with_code_deposit_cost_negative_code_cost) { char const* source = R"( // f() -> - // gas ir: 20 + // gas ir: 10 // gas ir code: -10 )"; BOOST_REQUIRE_THROW(parse(source), TestParserError); diff --git a/test/libsolidity/util/TestFunctionCall.cpp b/test/libsolidity/util/TestFunctionCall.cpp index b22ac3716a13..dd74d4035c68 100644 --- a/test/libsolidity/util/TestFunctionCall.cpp +++ b/test/libsolidity/util/TestFunctionCall.cpp @@ -377,20 +377,20 @@ std::string TestFunctionCall::formatGasExpectations( using ranges::views::keys; using ranges::views::set_symmetric_difference; - soltestAssert(set_symmetric_difference(m_codeDepositGasCosts | keys, m_gasCosts | keys).empty()); - soltestAssert(set_symmetric_difference(m_call.expectations.gasUsedForCodeDeposit | keys, m_call.expectations.gasUsed | keys).empty()); + soltestAssert(set_symmetric_difference(m_codeDepositGasCosts | keys, m_gasCostsExcludingCode | keys).empty()); + soltestAssert(set_symmetric_difference(m_call.expectations.gasUsedForCodeDeposit | keys, m_call.expectations.gasUsedExcludingCode | keys).empty()); std::stringstream os; - for (auto const& [runType, gasUsed]: (_useActualCost ? m_gasCosts : m_call.expectations.gasUsed)) + for (auto const& [runType, gasUsedExcludingCode]: (_useActualCost ? m_gasCostsExcludingCode : m_call.expectations.gasUsedExcludingCode)) { soltestAssert(runType != ""); u256 gasUsedForCodeDeposit = (_useActualCost ? m_codeDepositGasCosts : m_call.expectations.gasUsedForCodeDeposit).at(runType); - os << std::endl << _linePrefix << "// gas " << runType << ": " << gasUsed.str(); + os << std::endl << _linePrefix << "// gas " << runType << ": " << gasUsedExcludingCode.str(); std::string gasDiff = formatGasDiff( - gasOrNullopt(m_gasCosts, runType), - gasOrNullopt(m_call.expectations.gasUsed, runType) + gasOrNullopt(m_gasCostsExcludingCode, runType), + gasOrNullopt(m_call.expectations.gasUsedExcludingCode, runType) ); if (_showDifference && !gasDiff.empty() && _useActualCost) os << " [" << gasDiff << "]"; diff --git a/test/libsolidity/util/TestFunctionCall.h b/test/libsolidity/util/TestFunctionCall.h index cf05b6a216d7..724cb8286c19 100644 --- a/test/libsolidity/util/TestFunctionCall.h +++ b/test/libsolidity/util/TestFunctionCall.h @@ -53,7 +53,7 @@ class TestFunctionCall TestFunctionCall(FunctionCall _call): m_call(std::move(_call)), - m_gasCosts(m_call.expectations.gasUsed), + m_gasCostsExcludingCode(m_call.expectations.gasUsedExcludingCode), m_codeDepositGasCosts(m_call.expectations.gasUsedForCodeDeposit) {} @@ -97,7 +97,7 @@ class TestFunctionCall void calledNonExistingFunction() { m_calledNonExistingFunction = true; } void setFailure(const bool _failure) { m_failure = _failure; } void setRawBytes(const bytes _rawBytes) { m_rawBytes = _rawBytes; } - void setGasCost(std::string const& _runType, u256 const& _gasCost) { m_gasCosts[_runType] = _gasCost; } + void setGasCostExcludingCode(std::string const& _runType, u256 const& _gasCost) { m_gasCostsExcludingCode[_runType] = _gasCost; } void setCodeDepositGasCost(std::string const& _runType, u256 const& _gasCost) { m_codeDepositGasCosts[_runType] = _gasCost; } void setContractABI(Json::Value _contractABI) { m_contractABI = std::move(_contractABI); } void setSideEffects(std::vector _sideEffects) { m_call.actualSideEffects = _sideEffects; } @@ -147,7 +147,7 @@ class TestFunctionCall /// Result of the actual call been made. bytes m_rawBytes = bytes{}; /// Actual gas costs - std::map m_gasCosts; + std::map m_gasCostsExcludingCode; /// Actual code deposit gas costs std::map m_codeDepositGasCosts; /// Transaction status of the actual call. False in case of a REVERT or any other failure. diff --git a/test/libsolidity/util/TestFunctionCallTests.cpp b/test/libsolidity/util/TestFunctionCallTests.cpp index b78b7e5f290d..5741ccd0debe 100644 --- a/test/libsolidity/util/TestFunctionCallTests.cpp +++ b/test/libsolidity/util/TestFunctionCallTests.cpp @@ -295,7 +295,7 @@ BOOST_AUTO_TEST_CASE(format_gas_with_code_deposit) "some comment", { {"ir", 0}, // Zero costs are shown - {"legacy", 5000}, + {"legacy", 4875}, {"legacy optimized", 300}, }, { @@ -311,7 +311,7 @@ BOOST_AUTO_TEST_CASE(format_gas_with_code_deposit) TestFunctionCall(call).format(), "// f() -> #some comment#\n" "// gas ir: 0\n" - "// gas legacy: 5000\n" + "// gas legacy: 4875\n" "// gas legacy code: 125\n" "// gas legacy optimized: 300" ); From 381b149b8dd3fe87ae9d1af49514788adaa3e997 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Sun, 11 Feb 2024 16:03:50 +0100 Subject: [PATCH 0064/1022] gas_diff_stats.py: Include code deposit costs in total cost --- scripts/gas_diff_stats.py | 5 ++++- test/scripts/test_gas_diff_stats.py | 22 ++++++++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/scripts/gas_diff_stats.py b/scripts/gas_diff_stats.py index 7403b391721c..13d8a59e8d76 100755 --- a/scripts/gas_diff_stats.py +++ b/scripts/gas_diff_stats.py @@ -23,7 +23,7 @@ import sys from pathlib import Path from enum import Enum -from parsec import generate, ParseError, regex, string +from parsec import generate, ParseError, regex, string, optional from tabulate import tabulate class Kind(Enum): @@ -49,6 +49,7 @@ class Diff(Enum): gas_ir_optimized = string("gas irOptimized").result(Kind.IrOptimized) gas_legacy_optimized = string("gas legacyOptimized").result(Kind.LegacyOptimized) gas_legacy = string("gas legacy").result(Kind.Legacy) +code_suffix = string("code") def number() -> int: """Parse number.""" @@ -67,6 +68,8 @@ def diff_string() -> (Kind, Diff, int): yield comment yield space codegen_kind = yield gas_ir_optimized ^ gas_ir ^ gas_legacy_optimized ^ gas_legacy + yield optional(space) + yield optional(code_suffix) yield colon yield space val = yield number() diff --git a/test/scripts/test_gas_diff_stats.py b/test/scripts/test_gas_diff_stats.py index 4980293aea08..e67bd0be8930 100644 --- a/test/scripts/test_gas_diff_stats.py +++ b/test/scripts/test_gas_diff_stats.py @@ -85,3 +85,25 @@ def test_collect_statistics_should_ignore_unchanged_costs(self): 0, # +legacyOptimized 3, # +legacy )) + + def test_collect_statistics_should_include_code_deposit_in_total_cost(self): + diff_output = dedent(""" + -// gas irOptimized: 1 + -// gas legacy: 20 + -// gas legacyOptimized: 300 + +// gas irOptimized: 4000 + +// gas irOptimized code: 50000 + +// gas legacy: 600000 + +// gas legacyOptimized: 7000000 + +// gas legacyOptimized code: 80000000 + -// gas legacy code: 900000000 + """).splitlines() + + self.assertEqual(collect_statistics(diff_output), ( + 1, # -irOptimized + 300, # -legacyOptimized + 900000020, # -legacy + 54000, # +irOptimized + 87000000, # +legacyOptimized + 600000, # +legacy + )) From e7312a501086e1b0751bc3abbc7e7f08de8b8acd Mon Sep 17 00:00:00 2001 From: r0qs Date: Wed, 21 Feb 2024 21:09:09 +0100 Subject: [PATCH 0065/1022] Use CircleCI rust+node convenience image for t_ems_ext_hardhat job --- .circleci/config.yml | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 663c64520e4a..30c0229642a0 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1385,7 +1385,7 @@ jobs: t_ems_ext_hardhat: <<: *base_node_small docker: - - image: cimg/node:18.16 + - image: cimg/rust:1.74.0-node environment: <<: *base_node_small_env HARDHAT_TESTS_SOLC_PATH: /tmp/workspace/soljson.js @@ -1395,18 +1395,15 @@ jobs: at: /tmp/workspace - run: name: Ensure pnpm is installed if npm is present - command: | - if command -v npm &> /dev/null; then - sudo npm install -g pnpm - fi + command: sudo npm install -g pnpm - run: name: Retrieve Hardhat latest release tag command: | # Make authenticated requests when the Github token is available if [[ -n "$GITHUB_ACCESS_TOKEN" ]]; then - EXTRA_HEADERS=(--header 'Authorization: Bearer '"${GITHUB_ACCESS_TOKEN}") + EXTRA_HEADERS=(--header "Authorization: Bearer ${GITHUB_ACCESS_TOKEN}") fi - HARDHAT_RELEASE_TAG=$( + HARDHAT_LATEST_RELEASE_TAG=$( curl \ --silent \ --location \ @@ -1416,8 +1413,8 @@ jobs: https://api.github.com/repos/nomiclabs/hardhat/releases/latest \ | jq --raw-output .tag_name \ ) - echo "export HARDHAT_RELEASE_TAG='${HARDHAT_RELEASE_TAG}'" >> "$BASH_ENV" - - run: git clone --depth 1 https://github.com/nomiclabs/hardhat.git --branch $HARDHAT_RELEASE_TAG + echo "export HARDHAT_LATEST_RELEASE_TAG='${HARDHAT_LATEST_RELEASE_TAG}'" >> "$BASH_ENV" + - run: git clone --depth 1 https://github.com/nomiclabs/hardhat.git --branch "$HARDHAT_LATEST_RELEASE_TAG" - run: name: Install dependencies command: | From c8358f5677a786847fb4783866f995d0e140389c Mon Sep 17 00:00:00 2001 From: r0qs Date: Wed, 21 Feb 2024 21:01:28 +0100 Subject: [PATCH 0066/1022] Fix detect_hardhat_artifact_dir in externalTests scripts --- scripts/externalTests/common.sh | 41 ++++++++++++++++----------------- 1 file changed, 20 insertions(+), 21 deletions(-) diff --git a/scripts/externalTests/common.sh b/scripts/externalTests/common.sh index 3bca968a5aa5..082a25c4c58c 100644 --- a/scripts/externalTests/common.sh +++ b/scripts/externalTests/common.sh @@ -570,17 +570,15 @@ function gas_report_to_json cat - | "${REPO_ROOT}/scripts/externalTests/parse_eth_gas_report.py" | jq '{gas: .}' } -function detect_hardhat_artifact_dir -{ - if [[ -e build/ && -e artifacts/ ]]; then - fail "Cannot determine Hardhat artifact location. Both build/ and artifacts/ exist" - elif [[ -e build/ ]]; then - echo -n build/artifacts - elif [[ -e artifacts/ ]]; then - echo -n artifacts - else - fail "Hardhat build artifacts not found." - fi +function detect_hardhat_artifact_dirs +{ + # NOTE: The artifacts path is a configured parameter in Hardhat, so the below may fail for new external tests + # See: https://hardhat.org/hardhat-runner/docs/config#path-configuration + local artifact_dir=() + [[ -e build/artifacts ]] && artifact_dir+=("build/artifacts") + [[ -e artifacts/ ]] && artifact_dir+=("artifacts") + (( ${#artifact_dir[@]} != 0 )) || assertFail + echo -n "${artifact_dir[@]}" } function bytecode_size_json_from_truffle_artifacts @@ -605,16 +603,17 @@ function bytecode_size_json_from_truffle_artifacts function bytecode_size_json_from_hardhat_artifacts { # NOTE: The output of this function is a series of concatenated JSON dicts rather than a list. - - for artifact in "$(detect_hardhat_artifact_dir)"/build-info/*.json; do - # Each artifact contains Standard JSON output under the `output` key. - # Process it into a dict of the form `{"": {"": }}`, - # Note that one Hardhat artifact often represents multiple input files. - jq '.output.contracts | to_entries[] | { - "\(.key)": .value | to_entries[] | { - "\(.key)": (.value.evm.bytecode.object | length / 2) - } - }' "$artifact" + for artifact_dir in $(detect_hardhat_artifact_dirs); do + for artifact in "$artifact_dir"/build-info/*.json; do + # Each artifact contains Standard JSON output under the `output` key. + # Process it into a dict of the form `{"": {"": }}`, + # Note that one Hardhat artifact often represents multiple input files. + jq '.output.contracts | to_entries[] | { + "\(.key)": .value | to_entries[] | { + "\(.key)": (.value.evm.bytecode.object | length / 2) + } + }' "$artifact" + done done } From 4af244f4aa0dd97e3e2178a3a1fd4dd53760b529 Mon Sep 17 00:00:00 2001 From: r0qs Date: Fri, 2 Feb 2024 14:55:12 +0100 Subject: [PATCH 0067/1022] Separate nightly-ossfuzz workflow from nightly workflow --- .circleci/config.yml | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 30c0229642a0..9d3105a27701 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1978,10 +1978,6 @@ workflows: <<: *on_develop jobs: - # OSSFUZZ builds and (regression) tests - - b_ubu_ossfuzz: *requires_nothing - - t_ubu_ossfuzz: *requires_b_ubu_ossfuzz - # Code Coverage enabled build and tests - b_ubu_codecov: *requires_nothing - t_ubu_codecov: *requires_b_ubu_codecov @@ -1997,3 +1993,15 @@ workflows: - b_ubu_san_clang: *job_b_ubu_ubsan_clang - t_ubu_ubsan_clang_soltest: *requires_b_ubu_ubsan_clang - t_ubu_ubsan_clang_cli: *requires_b_ubu_ubsan_clang + + nightly-ossfuzz: + + triggers: + - schedule: + cron: "0 0 * * *" + <<: *on_develop + + jobs: + # OSSFUZZ builds and (regression) tests + - b_ubu_ossfuzz: *requires_nothing + - t_ubu_ossfuzz: *requires_b_ubu_ossfuzz From e095590330dfbd3022db12eb5f106606f818dd21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Thu, 2 Nov 2023 18:59:14 +0100 Subject: [PATCH 0068/1022] Parser::parseFunctionDefinition(): Return FunctionDefinition, not ASTNode --- libsolidity/parsing/Parser.cpp | 2 +- libsolidity/parsing/Parser.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libsolidity/parsing/Parser.cpp b/libsolidity/parsing/Parser.cpp index 42be1ab9eecf..c7f0c313fd18 100644 --- a/libsolidity/parsing/Parser.cpp +++ b/libsolidity/parsing/Parser.cpp @@ -627,7 +627,7 @@ Parser::FunctionHeaderParserResult Parser::parseFunctionHeader(bool _isStateVari return result; } -ASTPointer Parser::parseFunctionDefinition(bool _freeFunction, bool _allowBody) +ASTPointer Parser::parseFunctionDefinition(bool _freeFunction, bool _allowBody) { RecursionGuard recursionGuard(*this); ASTNodeFactory nodeFactory(*this); diff --git a/libsolidity/parsing/Parser.h b/libsolidity/parsing/Parser.h index d4c48c7a638a..86dd2843fdbc 100644 --- a/libsolidity/parsing/Parser.h +++ b/libsolidity/parsing/Parser.h @@ -102,7 +102,7 @@ class Parser: public langutil::ParserBase ASTPointer parseOverrideSpecifier(); StateMutability parseStateMutability(); FunctionHeaderParserResult parseFunctionHeader(bool _isStateVariable); - ASTPointer parseFunctionDefinition(bool _freeFunction = false, bool _allowBody = true); + ASTPointer parseFunctionDefinition(bool _freeFunction = false, bool _allowBody = true); ASTPointer parseStructDefinition(); ASTPointer parseEnumDefinition(); ASTPointer parseUserDefinedValueTypeDefinition(); From fa35ed5b98baa56e6e03abe61f3e6b9b42643e5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Thu, 2 Nov 2023 18:37:14 +0100 Subject: [PATCH 0069/1022] Add ForAllQuantifier AST node --- libsolidity/ast/AST.h | 32 ++++++++++++++++++++++++++++++++ libsolidity/ast/ASTAnnotations.h | 4 ++++ libsolidity/ast/ASTForward.h | 1 + libsolidity/ast/ASTVisitor.h | 4 ++++ libsolidity/ast/AST_accept.h | 20 ++++++++++++++++++++ 5 files changed, 61 insertions(+) diff --git a/libsolidity/ast/AST.h b/libsolidity/ast/AST.h index b9cc2118ef54..27926721aa6f 100644 --- a/libsolidity/ast/AST.h +++ b/libsolidity/ast/AST.h @@ -2625,6 +2625,38 @@ class Builtin: public Expression SourceLocation m_nameParameterLocation; }; +// TODO: NatSpec used on the quantifier should be recognized as applying to the function. +class ForAllQuantifier: public ASTNode, public Scopable, public ScopeOpener +{ +public: + ForAllQuantifier( + int64_t _id, + SourceLocation _location, + ASTPointer _typeVariableDeclarations, + ASTPointer _quantifiedDeclaration + ): + ASTNode(_id, std::move(_location)), + m_typeVariableDeclarations(std::move(_typeVariableDeclarations)), + m_quantifiedDeclaration(std::move(_quantifiedDeclaration)) + { + solAssert(m_typeVariableDeclarations); + solAssert(m_quantifiedDeclaration); + } + + void accept(ASTVisitor& _visitor) override; + void accept(ASTConstVisitor& _visitor) const override; + ForAllQuantifierAnnotation& annotation() const override { return initAnnotation(); } + + bool experimentalSolidityOnly() const override { return true; } + + ParameterList const& typeVariableDeclarations() const { return *m_typeVariableDeclarations; } + FunctionDefinition const& quantifiedDeclaration() const { return *m_quantifiedDeclaration; } + +private: + ASTPointer m_typeVariableDeclarations; + ASTPointer m_quantifiedDeclaration; +}; + /// @} } diff --git a/libsolidity/ast/ASTAnnotations.h b/libsolidity/ast/ASTAnnotations.h index e68614f464c0..f7519250a3a8 100644 --- a/libsolidity/ast/ASTAnnotations.h +++ b/libsolidity/ast/ASTAnnotations.h @@ -350,6 +350,10 @@ struct FunctionCallAnnotation: ExpressionAnnotation struct TypeClassDefinitionAnnotation: TypeDeclarationAnnotation, StructurallyDocumentedAnnotation { }; + +struct ForAllQuantifierAnnotation: StatementAnnotation, ScopableAnnotation +{ +}; /// @} } diff --git a/libsolidity/ast/ASTForward.h b/libsolidity/ast/ASTForward.h index f7c3d60237d7..b8a3a4ae0057 100644 --- a/libsolidity/ast/ASTForward.h +++ b/libsolidity/ast/ASTForward.h @@ -106,6 +106,7 @@ class TypeClassInstantiation; class TypeClassName; class TypeDefinition; class Builtin; +class ForAllQuantifier; /// @} class VariableScope; diff --git a/libsolidity/ast/ASTVisitor.h b/libsolidity/ast/ASTVisitor.h index f9196d6b95c8..f985a449019a 100644 --- a/libsolidity/ast/ASTVisitor.h +++ b/libsolidity/ast/ASTVisitor.h @@ -116,6 +116,7 @@ class ASTVisitor virtual bool visit(TypeDefinition& _node) { return visitNode(_node); } virtual bool visit(TypeClassName& _node) { return visitNode(_node); } virtual bool visit(Builtin& _node) { return visitNode(_node); } + virtual bool visit(ForAllQuantifier& _node) { return visitNode(_node); } /// @} virtual void endVisit(SourceUnit& _node) { endVisitNode(_node); } @@ -180,6 +181,7 @@ class ASTVisitor virtual void endVisit(TypeDefinition& _node) { endVisitNode(_node); } virtual void endVisit(TypeClassName& _node) { endVisitNode(_node); } virtual void endVisit(Builtin& _node) { endVisitNode(_node); } + virtual void endVisit(ForAllQuantifier& _node) { endVisitNode(_node); } /// @} protected: @@ -266,6 +268,7 @@ class ASTConstVisitor virtual bool visit(TypeDefinition const& _node) { return visitNode(_node); } virtual bool visit(TypeClassName const& _node) { return visitNode(_node); } virtual bool visit(Builtin const& _node) { return visitNode(_node); } + virtual bool visit(ForAllQuantifier const& _node) { return visitNode(_node); } /// @} virtual void endVisit(SourceUnit const& _node) { endVisitNode(_node); } @@ -330,6 +333,7 @@ class ASTConstVisitor virtual void endVisit(TypeDefinition const& _node) { endVisitNode(_node); } virtual void endVisit(TypeClassName const& _node) { endVisitNode(_node); } virtual void endVisit(Builtin const& _node) { endVisitNode(_node); } + virtual void endVisit(ForAllQuantifier const& _node) { endVisitNode(_node); } /// @} protected: diff --git a/libsolidity/ast/AST_accept.h b/libsolidity/ast/AST_accept.h index be9de64db7a2..55ebe2a78c61 100644 --- a/libsolidity/ast/AST_accept.h +++ b/libsolidity/ast/AST_accept.h @@ -1140,6 +1140,26 @@ void Builtin::accept(ASTConstVisitor& _visitor) const _visitor.visit(*this); _visitor.endVisit(*this); } + +void ForAllQuantifier::accept(ASTVisitor& _visitor) +{ + if (_visitor.visit(*this)) + { + m_typeVariableDeclarations->accept(_visitor); + m_quantifiedDeclaration->accept(_visitor); + } + _visitor.endVisit(*this); +} + +void ForAllQuantifier::accept(ASTConstVisitor& _visitor) const +{ + if (_visitor.visit(*this)) + { + m_typeVariableDeclarations->accept(_visitor); + m_quantifiedDeclaration->accept(_visitor); + } + _visitor.endVisit(*this); +} /// @} } From 4d051c1fcefa9c8766f7083139e294703503d88a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Thu, 2 Nov 2023 19:07:44 +0100 Subject: [PATCH 0070/1022] Add parser support for quantified function definitions --- liblangutil/Token.h | 1 + .../experimental/analysis/TypeInference.cpp | 13 ++++++ .../experimental/analysis/TypeInference.h | 1 + libsolidity/parsing/Parser.cpp | 24 +++++++++++ libsolidity/parsing/Parser.h | 1 + .../parsing/forall_free_function.sol | 27 ++++++++++++ .../forall_free_function_no_type_var.sol | 14 ++++++ .../forall_free_function_with_sorts.sol | 43 +++++++++++++++++++ .../parsing/forall_type_class.sol | 8 ++++ .../forall_type_class_instantiation.sol | 12 ++++++ 10 files changed, 144 insertions(+) create mode 100644 test/libsolidity/syntaxTests/experimental/parsing/forall_free_function.sol create mode 100644 test/libsolidity/syntaxTests/experimental/parsing/forall_free_function_no_type_var.sol create mode 100644 test/libsolidity/syntaxTests/experimental/parsing/forall_free_function_with_sorts.sol create mode 100644 test/libsolidity/syntaxTests/experimental/parsing/forall_type_class.sol create mode 100644 test/libsolidity/syntaxTests/experimental/parsing/forall_type_class_instantiation.sol diff --git a/liblangutil/Token.h b/liblangutil/Token.h index 98de0b228d04..0f7c2df08034 100644 --- a/liblangutil/Token.h +++ b/liblangutil/Token.h @@ -276,6 +276,7 @@ namespace solidity::langutil K(Itself, "itself", 0) \ K(StaticAssert, "static_assert", 0) \ K(Builtin, "__builtin", 0) \ + K(ForAll, "forall", 0) \ T(ExperimentalEnd, nullptr, 0) /* used as experimental enum end marker */ \ \ /* Illegal token - not able to scan. */ \ diff --git a/libsolidity/experimental/analysis/TypeInference.cpp b/libsolidity/experimental/analysis/TypeInference.cpp index 63a377f90d56..8625937a35d0 100644 --- a/libsolidity/experimental/analysis/TypeInference.cpp +++ b/libsolidity/experimental/analysis/TypeInference.cpp @@ -129,6 +129,19 @@ bool TypeInference::analyze(SourceUnit const& _sourceUnit) return !m_errorReporter.hasErrors(); } +bool TypeInference::visit(ForAllQuantifier const& _quantifier) +{ + solAssert(m_expressionContext == ExpressionContext::Term); + + { + ScopedSaveAndRestore expressionContext{m_expressionContext, ExpressionContext::Type}; + _quantifier.typeVariableDeclarations().accept(*this); + } + + _quantifier.quantifiedDeclaration().accept(*this); + return false; +} + bool TypeInference::visit(FunctionDefinition const& _functionDefinition) { solAssert(m_expressionContext == ExpressionContext::Term); diff --git a/libsolidity/experimental/analysis/TypeInference.h b/libsolidity/experimental/analysis/TypeInference.h index 3eb2ad94cf71..093236799555 100644 --- a/libsolidity/experimental/analysis/TypeInference.h +++ b/libsolidity/experimental/analysis/TypeInference.h @@ -56,6 +56,7 @@ class TypeInference: public ASTConstVisitor void endVisit(VariableDeclarationStatement const& _variableDeclarationStatement) override; bool visit(VariableDeclaration const& _variableDeclaration) override; + bool visit(ForAllQuantifier const& _forAllQuantifier) override; bool visit(FunctionDefinition const& _functionDefinition) override; void endVisit(FunctionDefinition const& _functionDefinition) override; bool visit(ParameterList const&) override { return true; } diff --git a/libsolidity/parsing/Parser.cpp b/libsolidity/parsing/Parser.cpp index c7f0c313fd18..f650e0dbf1dc 100644 --- a/libsolidity/parsing/Parser.cpp +++ b/libsolidity/parsing/Parser.cpp @@ -137,6 +137,9 @@ ASTPointer Parser::parse(CharStream& _charStream) case Token::Function: nodes.push_back(parseFunctionDefinition(true)); break; + case Token::ForAll: + nodes.push_back(parseQuantifiedFunctionDefinition()); + break; case Token::Event: nodes.push_back(parseEventDefinition()); break; @@ -627,6 +630,27 @@ Parser::FunctionHeaderParserResult Parser::parseFunctionHeader(bool _isStateVari return result; } +ASTPointer Parser::parseQuantifiedFunctionDefinition() +{ + solAssert(m_experimentalSolidityEnabledInCurrentSourceUnit); + RecursionGuard recursionGuard(*this); + ASTNodeFactory nodeFactory(*this); + + expectToken(Token::ForAll); + ASTPointer typeVariableDeclarations = parseParameterList(); + nodeFactory.markEndPosition(); + + if (m_scanner->currentToken() != Token::Function) + fatalParserError(5709_error, "Expected a function definition."); + + ASTPointer quantifiedFunction = parseFunctionDefinition(true /* _freeFunction */, true /* _allowBody */); + + return nodeFactory.createNode( + std::move(typeVariableDeclarations), + std::move(quantifiedFunction) + ); +} + ASTPointer Parser::parseFunctionDefinition(bool _freeFunction, bool _allowBody) { RecursionGuard recursionGuard(*this); diff --git a/libsolidity/parsing/Parser.h b/libsolidity/parsing/Parser.h index 86dd2843fdbc..aedfdb7ddd37 100644 --- a/libsolidity/parsing/Parser.h +++ b/libsolidity/parsing/Parser.h @@ -102,6 +102,7 @@ class Parser: public langutil::ParserBase ASTPointer parseOverrideSpecifier(); StateMutability parseStateMutability(); FunctionHeaderParserResult parseFunctionHeader(bool _isStateVariable); + ASTPointer parseQuantifiedFunctionDefinition(); ASTPointer parseFunctionDefinition(bool _freeFunction = false, bool _allowBody = true); ASTPointer parseStructDefinition(); ASTPointer parseEnumDefinition(); diff --git a/test/libsolidity/syntaxTests/experimental/parsing/forall_free_function.sol b/test/libsolidity/syntaxTests/experimental/parsing/forall_free_function.sol new file mode 100644 index 000000000000..ba22a9fae4b4 --- /dev/null +++ b/test/libsolidity/syntaxTests/experimental/parsing/forall_free_function.sol @@ -0,0 +1,27 @@ +pragma experimental solidity; + +forall (A) +function f(a: A) {} + +forall (A, B) +function g(a: A, b: B) {} +// ==== +// EVMVersion: >=constantinople +// compileViaYul: true +// ---- +// Warning 2264: (0-29): Experimental features are turned on. Do not use experimental features on live deployments. +// Info 4164: (38-41): Inferred type: 's:type +// Info 4164: (39-40): Inferred type: 's:type +// Info 4164: (42-61): Inferred type: 's:type -> () +// Info 4164: (52-58): Inferred type: 's:type +// Info 4164: (53-57): Inferred type: 's:type +// Info 4164: (56-57): Inferred type: 's:type +// Info 4164: (70-76): Inferred type: ('v:type, 'w:type) +// Info 4164: (71-72): Inferred type: 'v:type +// Info 4164: (74-75): Inferred type: 'w:type +// Info 4164: (77-102): Inferred type: ('v:type, 'w:type) -> () +// Info 4164: (87-99): Inferred type: ('v:type, 'w:type) +// Info 4164: (88-92): Inferred type: 'v:type +// Info 4164: (91-92): Inferred type: 'v:type +// Info 4164: (94-98): Inferred type: 'w:type +// Info 4164: (97-98): Inferred type: 'w:type diff --git a/test/libsolidity/syntaxTests/experimental/parsing/forall_free_function_no_type_var.sol b/test/libsolidity/syntaxTests/experimental/parsing/forall_free_function_no_type_var.sol new file mode 100644 index 000000000000..66753fdd0f68 --- /dev/null +++ b/test/libsolidity/syntaxTests/experimental/parsing/forall_free_function_no_type_var.sol @@ -0,0 +1,14 @@ +pragma experimental solidity; + +forall () +function f(x: ()) {} +// ==== +// EVMVersion: >=constantinople +// compileViaYul: true +// ---- +// Warning 2264: (0-29): Experimental features are turned on. Do not use experimental features on live deployments. +// Info 4164: (38-40): Inferred type: () +// Info 4164: (41-61): Inferred type: () -> () +// Info 4164: (51-58): Inferred type: () +// Info 4164: (52-57): Inferred type: () +// Info 4164: (55-57): Inferred type: () diff --git a/test/libsolidity/syntaxTests/experimental/parsing/forall_free_function_with_sorts.sol b/test/libsolidity/syntaxTests/experimental/parsing/forall_free_function_with_sorts.sol new file mode 100644 index 000000000000..1ab09fd2bd24 --- /dev/null +++ b/test/libsolidity/syntaxTests/experimental/parsing/forall_free_function_with_sorts.sol @@ -0,0 +1,43 @@ +pragma experimental solidity; + +class Self: Class1 {} +class Self: Class2 {} + +forall (A: (Class1, Class2), B: Class1) +function f(a: A: Class1, b: B: Class1) {} + +forall A: Class1 +function g(a: A) {} +// ==== +// EVMVersion: >=constantinople +// compileViaYul: true +// ---- +// Warning 2264: (0-29): Experimental features are turned on. Do not use experimental features on live deployments. +// Info 4164: (31-52): Inferred type: Class1 +// Info 4164: (37-41): Inferred type: 'k:(type, Class1) +// Info 4164: (53-74): Inferred type: Class2 +// Info 4164: (59-63): Inferred type: 'l:(type, Class2) +// Info 4164: (83-115): Inferred type: ('ba:(type, Class1, Class2), 'bg:(type, Class1)) +// Info 4164: (84-103): Inferred type: 'ba:(type, Class1, Class2) +// Info 4164: (87-103): Inferred type: 'ba:(type, Class1, Class2) +// Info 4164: (88-94): Inferred type: 'ba:(type, Class1, Class2) +// Info 4164: (96-102): Inferred type: 'ba:(type, Class1, Class2) +// Info 4164: (105-114): Inferred type: 'bg:(type, Class1) +// Info 4164: (108-114): Inferred type: 'bg:(type, Class1) +// Info 4164: (116-157): Inferred type: ('ba:(type, Class1, Class2), 'bg:(type, Class1)) -> () +// Info 4164: (126-154): Inferred type: ('ba:(type, Class1, Class2), 'bg:(type, Class1)) +// Info 4164: (127-139): Inferred type: 'ba:(type, Class1, Class2) +// Info 4164: (130-139): Inferred type: 'ba:(type, Class1, Class2) +// Info 4164: (130-131): Inferred type: 'ba:(type, Class1, Class2) +// Info 4164: (133-139): Inferred type: 'ba:(type, Class1, Class2) +// Info 4164: (141-153): Inferred type: 'bg:(type, Class1) +// Info 4164: (144-153): Inferred type: 'bg:(type, Class1) +// Info 4164: (144-145): Inferred type: 'bg:(type, Class1) +// Info 4164: (147-153): Inferred type: 'bg:(type, Class1) +// Info 4164: (166-175): Inferred type: 'bi:(type, Class1) +// Info 4164: (166-175): Inferred type: 'bi:(type, Class1) +// Info 4164: (169-175): Inferred type: 'bi:(type, Class1) +// Info 4164: (176-195): Inferred type: 'bi:(type, Class1) -> () +// Info 4164: (186-192): Inferred type: 'bi:(type, Class1) +// Info 4164: (187-191): Inferred type: 'bi:(type, Class1) +// Info 4164: (190-191): Inferred type: 'bi:(type, Class1) diff --git a/test/libsolidity/syntaxTests/experimental/parsing/forall_type_class.sol b/test/libsolidity/syntaxTests/experimental/parsing/forall_type_class.sol new file mode 100644 index 000000000000..aa0012eac16f --- /dev/null +++ b/test/libsolidity/syntaxTests/experimental/parsing/forall_type_class.sol @@ -0,0 +1,8 @@ +pragma experimental solidity; + +forall (A, B) +class Self: C {} +// ==== +// EVMVersion: >=constantinople +// ---- +// ParserError 5709: (45-50): Expected a function definition. diff --git a/test/libsolidity/syntaxTests/experimental/parsing/forall_type_class_instantiation.sol b/test/libsolidity/syntaxTests/experimental/parsing/forall_type_class_instantiation.sol new file mode 100644 index 000000000000..31573447a369 --- /dev/null +++ b/test/libsolidity/syntaxTests/experimental/parsing/forall_type_class_instantiation.sol @@ -0,0 +1,12 @@ +pragma experimental solidity; + +type T; + +class Self: C {} + +forall (A, B) +instantiation T: C {} +// ==== +// EVMVersion: >=constantinople +// ---- +// ParserError 5709: (72-85): Expected a function definition. From cd52e5aa9c282e75654709cd2890638e52561521 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Mon, 6 Nov 2023 12:01:25 +0100 Subject: [PATCH 0071/1022] TypeInference: Require declarations for type variables --- libsolidity/analysis/NameAndTypeResolver.cpp | 31 ++++++-- .../experimental/analysis/TypeInference.cpp | 6 +- .../undeclared_type_variable_in_function.sol | 17 +++++ ...d_type_variable_in_quantified_function.sol | 12 ++++ ...undeclared_type_variable_in_type_class.sol | 17 +++++ .../inference/polymorphic_function_call.sol | 70 ++++++++++--------- .../inference/polymorphic_type.sol | 41 ++++++----- ...ulti_use_function_parameter_and_return.sol | 16 +++++ ...variable_multi_use_function_parameters.sol | 16 +++++ 9 files changed, 169 insertions(+), 57 deletions(-) create mode 100644 test/libsolidity/syntaxTests/experimental/forall/undeclared_type_variable_in_function.sol create mode 100644 test/libsolidity/syntaxTests/experimental/forall/undeclared_type_variable_in_quantified_function.sol create mode 100644 test/libsolidity/syntaxTests/experimental/forall/undeclared_type_variable_in_type_class.sol create mode 100644 test/libsolidity/syntaxTests/experimental/inference/type_variable_multi_use_function_parameter_and_return.sol create mode 100644 test/libsolidity/syntaxTests/experimental/inference/type_variable_multi_use_function_parameters.sol diff --git a/libsolidity/analysis/NameAndTypeResolver.cpp b/libsolidity/analysis/NameAndTypeResolver.cpp index 94d0568118b9..642e87a53b3e 100644 --- a/libsolidity/analysis/NameAndTypeResolver.cpp +++ b/libsolidity/analysis/NameAndTypeResolver.cpp @@ -703,11 +703,34 @@ void DeclarationRegistrationHelper::registerDeclaration(Declaration& _declaratio solAssert(m_currentScope && m_scopes.count(m_currentScope), "No current scope."); solAssert(m_currentScope == _declaration.scope(), "Unexpected current scope."); - // Register declaration as inactive if we are in block scope. - bool inactive = - (dynamic_cast(m_currentScope) || dynamic_cast(m_currentScope)); + // Functions defined inside quantifiers should be visible in the scope containing the quantifier + // TODO: Turn it into a more generic mechanism in the same vein as Scopable and ScopeOpener if + // it turns out we need more special-casing here. + auto const* quantifier = dynamic_cast(m_currentScope); + auto const* functionDefinition = dynamic_cast(&_declaration); + if (quantifier && functionDefinition) + { + solAssert(quantifier->scope()); + solAssert( + // forall quantifiers cannot be used in block scope so the declaration is always active. + !dynamic_cast(quantifier->scope()) && + !dynamic_cast(quantifier->scope()) + ); - registerDeclaration(*m_scopes[m_currentScope], _declaration, nullptr, nullptr, inactive, m_errorReporter); + // NOTE: We're registering the function outside of its scope(). This will only affect + // name lookups. An more general alternative would be to modify Scoper to simply assign it + // that scope in the first place, but this would complicate the AST traversal here, which + // currently assumes that scopes follow ScopeOpener nesting. + registerDeclaration(*m_scopes.at(quantifier->scope()), _declaration, nullptr, nullptr, false /* inactive */, m_errorReporter); + } + else + { + // Register declaration as inactive if we are in block scope. + bool inactive = + (dynamic_cast(m_currentScope) || dynamic_cast(m_currentScope)); + + registerDeclaration(*m_scopes[m_currentScope], _declaration, nullptr, nullptr, inactive, m_errorReporter); + } solAssert(_declaration.annotation().scope == m_currentScope, ""); solAssert(_declaration.annotation().contract == m_currentContract, ""); diff --git a/libsolidity/experimental/analysis/TypeInference.cpp b/libsolidity/experimental/analysis/TypeInference.cpp index 8625937a35d0..6913dc0bf7cd 100644 --- a/libsolidity/experimental/analysis/TypeInference.cpp +++ b/libsolidity/experimental/analysis/TypeInference.cpp @@ -580,9 +580,11 @@ bool TypeInference::visit(Identifier const& _identifier) solAssert(false); break; case ExpressionContext::Type: - // TODO: register free type variable name! + m_errorReporter.typeError(5934_error, _identifier.location(), "Undeclared type variable."); + + // Assign it a fresh variable anyway just so that we can continue analysis. identifierAnnotation.type = m_typeSystem.freshTypeVariable({}); - return false; + break; case ExpressionContext::Sort: // TODO: error handling solAssert(false); diff --git a/test/libsolidity/syntaxTests/experimental/forall/undeclared_type_variable_in_function.sol b/test/libsolidity/syntaxTests/experimental/forall/undeclared_type_variable_in_function.sol new file mode 100644 index 000000000000..da1169969143 --- /dev/null +++ b/test/libsolidity/syntaxTests/experimental/forall/undeclared_type_variable_in_function.sol @@ -0,0 +1,17 @@ +pragma experimental solidity; + +type T(X); + +function f(p: P, q: T(Q)) { + let r: (R, S); + let s: S; +} +// ==== +// EVMVersion: >=constantinople +// ---- +// Warning 2264: (0-29): Experimental features are turned on. Do not use experimental features on live deployments. +// TypeError 5934: (57-58): Undeclared type variable. +// TypeError 5934: (65-66): Undeclared type variable. +// TypeError 5934: (83-84): Undeclared type variable. +// TypeError 5934: (86-87): Undeclared type variable. +// TypeError 5934: (101-102): Undeclared type variable. diff --git a/test/libsolidity/syntaxTests/experimental/forall/undeclared_type_variable_in_quantified_function.sol b/test/libsolidity/syntaxTests/experimental/forall/undeclared_type_variable_in_quantified_function.sol new file mode 100644 index 000000000000..91b734569372 --- /dev/null +++ b/test/libsolidity/syntaxTests/experimental/forall/undeclared_type_variable_in_quantified_function.sol @@ -0,0 +1,12 @@ +pragma experimental solidity; + +forall A +function f(b: B) { + let c: C; +} +// ==== +// EVMVersion: >=constantinople +// ---- +// Warning 2264: (0-29): Experimental features are turned on. Do not use experimental features on live deployments. +// TypeError 5934: (54-55): Undeclared type variable. +// TypeError 5934: (70-71): Undeclared type variable. diff --git a/test/libsolidity/syntaxTests/experimental/forall/undeclared_type_variable_in_type_class.sol b/test/libsolidity/syntaxTests/experimental/forall/undeclared_type_variable_in_type_class.sol new file mode 100644 index 000000000000..8af0cce82699 --- /dev/null +++ b/test/libsolidity/syntaxTests/experimental/forall/undeclared_type_variable_in_type_class.sol @@ -0,0 +1,17 @@ +pragma experimental solidity; + +type T(X); + +class Self: C { + function f(self: Self); +} + +instantiation T(Y): C { + function f(self: T(Z)) {} +} +// ==== +// EVMVersion: >=constantinople +// ---- +// Warning 2264: (0-29): Experimental features are turned on. Do not use experimental features on live deployments. +// TypeError 5934: (137-138): Undeclared type variable. +// TypeError 7428: (90-145): Instantiation function 'f' does not match the declaration in the type class (T('bc:type) -> () != T('y:type) -> ()). diff --git a/test/libsolidity/syntaxTests/experimental/inference/polymorphic_function_call.sol b/test/libsolidity/syntaxTests/experimental/inference/polymorphic_function_call.sol index c73a857a2fcb..c9c7e01109e7 100644 --- a/test/libsolidity/syntaxTests/experimental/inference/polymorphic_function_call.sol +++ b/test/libsolidity/syntaxTests/experimental/inference/polymorphic_function_call.sol @@ -3,6 +3,7 @@ pragma experimental solidity; type T; type U(A); +forall (X, Y) function f(x, y: X, z: U(Y)) {} function run(a: T, b: U(T), c: U(U(T))) { @@ -18,36 +19,39 @@ function run(a: T, b: U(T), c: U(U(T))) { // Info 4164: (39-49): Inferred type: tfun('t:type, U('t:type)) // Info 4164: (45-48): Inferred type: 't:type // Info 4164: (46-47): Inferred type: 't:type -// Info 4164: (51-82): Inferred type: ('w:type, 'x:type, U('z:type)) -> () -// Info 4164: (61-79): Inferred type: ('w:type, 'x:type, U('z:type)) -// Info 4164: (62-63): Inferred type: 'w:type -// Info 4164: (65-69): Inferred type: 'x:type -// Info 4164: (68-69): Inferred type: 'x:type -// Info 4164: (71-78): Inferred type: U('z:type) -// Info 4164: (74-78): Inferred type: U('z:type) -// Info 4164: (74-75): Inferred type: tfun('z:type, U('z:type)) -// Info 4164: (76-77): Inferred type: 'z:type -// Info 4164: (84-159): Inferred type: (T, U(T), U(U(T))) -> () -// Info 4164: (96-123): Inferred type: (T, U(T), U(U(T))) -// Info 4164: (97-101): Inferred type: T -// Info 4164: (100-101): Inferred type: T -// Info 4164: (103-110): Inferred type: U(T) -// Info 4164: (106-110): Inferred type: U(T) -// Info 4164: (106-107): Inferred type: tfun(T, U(T)) -// Info 4164: (108-109): Inferred type: T -// Info 4164: (112-122): Inferred type: U(U(T)) -// Info 4164: (115-122): Inferred type: U(U(T)) -// Info 4164: (115-116): Inferred type: tfun(U(T), U(U(T))) -// Info 4164: (117-121): Inferred type: U(T) -// Info 4164: (117-118): Inferred type: tfun(T, U(T)) -// Info 4164: (119-120): Inferred type: T -// Info 4164: (130-140): Inferred type: () -// Info 4164: (130-131): Inferred type: (T, T, U(T)) -> () -// Info 4164: (132-133): Inferred type: T -// Info 4164: (135-136): Inferred type: T -// Info 4164: (138-139): Inferred type: U(T) -// Info 4164: (146-156): Inferred type: () -// Info 4164: (146-147): Inferred type: (U(T), U(T), U(U(T))) -> () -// Info 4164: (148-149): Inferred type: U(T) -// Info 4164: (151-152): Inferred type: U(T) -// Info 4164: (154-155): Inferred type: U(U(T)) +// Info 4164: (58-64): Inferred type: ('u:type, 'v:type) +// Info 4164: (59-60): Inferred type: 'u:type +// Info 4164: (62-63): Inferred type: 'v:type +// Info 4164: (65-96): Inferred type: ('y:type, 'u:type, U('v:type)) -> () +// Info 4164: (75-93): Inferred type: ('y:type, 'u:type, U('v:type)) +// Info 4164: (76-77): Inferred type: 'y:type +// Info 4164: (79-83): Inferred type: 'u:type +// Info 4164: (82-83): Inferred type: 'u:type +// Info 4164: (85-92): Inferred type: U('v:type) +// Info 4164: (88-92): Inferred type: U('v:type) +// Info 4164: (88-89): Inferred type: tfun('v:type, U('v:type)) +// Info 4164: (90-91): Inferred type: 'v:type +// Info 4164: (98-173): Inferred type: (T, U(T), U(U(T))) -> () +// Info 4164: (110-137): Inferred type: (T, U(T), U(U(T))) +// Info 4164: (111-115): Inferred type: T +// Info 4164: (114-115): Inferred type: T +// Info 4164: (117-124): Inferred type: U(T) +// Info 4164: (120-124): Inferred type: U(T) +// Info 4164: (120-121): Inferred type: tfun(T, U(T)) +// Info 4164: (122-123): Inferred type: T +// Info 4164: (126-136): Inferred type: U(U(T)) +// Info 4164: (129-136): Inferred type: U(U(T)) +// Info 4164: (129-130): Inferred type: tfun(U(T), U(U(T))) +// Info 4164: (131-135): Inferred type: U(T) +// Info 4164: (131-132): Inferred type: tfun(T, U(T)) +// Info 4164: (133-134): Inferred type: T +// Info 4164: (144-154): Inferred type: () +// Info 4164: (144-145): Inferred type: (T, T, U(T)) -> () +// Info 4164: (146-147): Inferred type: T +// Info 4164: (149-150): Inferred type: T +// Info 4164: (152-153): Inferred type: U(T) +// Info 4164: (160-170): Inferred type: () +// Info 4164: (160-161): Inferred type: (U(T), U(T), U(U(T))) -> () +// Info 4164: (162-163): Inferred type: U(T) +// Info 4164: (165-166): Inferred type: U(T) +// Info 4164: (168-169): Inferred type: U(U(T)) diff --git a/test/libsolidity/syntaxTests/experimental/inference/polymorphic_type.sol b/test/libsolidity/syntaxTests/experimental/inference/polymorphic_type.sol index ca83ca2ec7fc..85f810a9dc0d 100644 --- a/test/libsolidity/syntaxTests/experimental/inference/polymorphic_type.sol +++ b/test/libsolidity/syntaxTests/experimental/inference/polymorphic_type.sol @@ -7,6 +7,7 @@ type V; class Self: C {} class Self: D {} +forall (X, Y, Z) function run() { let x: T(U, X, Z: C); let y: T(V, Y, Z: D); @@ -27,21 +28,25 @@ function run() { // Info 4164: (71-75): Inferred type: 'k:(type, C) // Info 4164: (82-98): Inferred type: D // Info 4164: (88-92): Inferred type: 'l:(type, D) -// Info 4164: (100-170): Inferred type: () -> () -// Info 4164: (112-114): Inferred type: () -// Info 4164: (125-141): Inferred type: T(U, ?bh:type, ?bj:(type, C)) -// Info 4164: (128-141): Inferred type: T(U, ?bh:type, ?bj:(type, C)) -// Info 4164: (128-129): Inferred type: tfun((U, ?bh:type, ?bj:(type, C)), T(U, ?bh:type, ?bj:(type, C))) -// Info 4164: (130-131): Inferred type: U -// Info 4164: (133-134): Inferred type: ?bh:type -// Info 4164: (136-140): Inferred type: ?bj:(type, C) -// Info 4164: (136-137): Inferred type: ?bj:(type, C) -// Info 4164: (139-140): Inferred type: ?bj:(type, C) -// Info 4164: (151-167): Inferred type: T(V, ?bo:type, ?bq:(type, D)) -// Info 4164: (154-167): Inferred type: T(V, ?bo:type, ?bq:(type, D)) -// Info 4164: (154-155): Inferred type: tfun((V, ?bo:type, ?bq:(type, D)), T(V, ?bo:type, ?bq:(type, D))) -// Info 4164: (156-157): Inferred type: V -// Info 4164: (159-160): Inferred type: ?bo:type -// Info 4164: (162-166): Inferred type: ?bq:(type, D) -// Info 4164: (162-163): Inferred type: ?bq:(type, D) -// Info 4164: (165-166): Inferred type: ?bq:(type, D) +// Info 4164: (107-116): Inferred type: (?bc:type, ?bd:type, ?bq:(type, C, D)) +// Info 4164: (108-109): Inferred type: ?bc:type +// Info 4164: (111-112): Inferred type: ?bd:type +// Info 4164: (114-115): Inferred type: ?bq:(type, C, D) +// Info 4164: (117-187): Inferred type: () -> () +// Info 4164: (129-131): Inferred type: () +// Info 4164: (142-158): Inferred type: T(U, ?bc:type, ?bq:(type, C, D)) +// Info 4164: (145-158): Inferred type: T(U, ?bc:type, ?bq:(type, C, D)) +// Info 4164: (145-146): Inferred type: tfun((U, ?bc:type, ?bq:(type, C, D)), T(U, ?bc:type, ?bq:(type, C, D))) +// Info 4164: (147-148): Inferred type: U +// Info 4164: (150-151): Inferred type: ?bc:type +// Info 4164: (153-157): Inferred type: ?bq:(type, C, D) +// Info 4164: (153-154): Inferred type: ?bq:(type, C, D) +// Info 4164: (156-157): Inferred type: ?bq:(type, C, D) +// Info 4164: (168-184): Inferred type: T(V, ?bd:type, ?bq:(type, C, D)) +// Info 4164: (171-184): Inferred type: T(V, ?bd:type, ?bq:(type, C, D)) +// Info 4164: (171-172): Inferred type: tfun((V, ?bd:type, ?bq:(type, C, D)), T(V, ?bd:type, ?bq:(type, C, D))) +// Info 4164: (173-174): Inferred type: V +// Info 4164: (176-177): Inferred type: ?bd:type +// Info 4164: (179-183): Inferred type: ?bq:(type, C, D) +// Info 4164: (179-180): Inferred type: ?bq:(type, C, D) +// Info 4164: (182-183): Inferred type: ?bq:(type, C, D) diff --git a/test/libsolidity/syntaxTests/experimental/inference/type_variable_multi_use_function_parameter_and_return.sol b/test/libsolidity/syntaxTests/experimental/inference/type_variable_multi_use_function_parameter_and_return.sol new file mode 100644 index 000000000000..00cd7b1207df --- /dev/null +++ b/test/libsolidity/syntaxTests/experimental/inference/type_variable_multi_use_function_parameter_and_return.sol @@ -0,0 +1,16 @@ +pragma experimental solidity; + +type T; +type U; + +forall X +function f(x: X) -> X {} + +function test(t: T, u: U) { + t = f(u); +} +// ==== +// EVMVersion: >=constantinople +// ---- +// Warning 2264: (0-29): Experimental features are turned on. Do not use experimental features on live deployments. +// TypeError 8456: (115-123): Cannot unify T and U. diff --git a/test/libsolidity/syntaxTests/experimental/inference/type_variable_multi_use_function_parameters.sol b/test/libsolidity/syntaxTests/experimental/inference/type_variable_multi_use_function_parameters.sol new file mode 100644 index 000000000000..7122cdd9efce --- /dev/null +++ b/test/libsolidity/syntaxTests/experimental/inference/type_variable_multi_use_function_parameters.sol @@ -0,0 +1,16 @@ +pragma experimental solidity; + +type T; +type U; + +forall X +function f(x: X, y: X) {} + +function test(t: T, u: U) { + f(t, u); +} +// ==== +// EVMVersion: >=constantinople +// ---- +// Warning 2264: (0-29): Experimental features are turned on. Do not use experimental features on live deployments. +// TypeError 8456: (116-123): Cannot unify T and U. From 180f744c434dc6a5fbeb09715e194ab05a30bd88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Mon, 26 Feb 2024 19:44:15 +0100 Subject: [PATCH 0072/1022] gas_diff_stats.py: Sort the table by average change --- scripts/gas_diff_stats.py | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/scripts/gas_diff_stats.py b/scripts/gas_diff_stats.py index 13d8a59e8d76..e593bb9a9746 100755 --- a/scripts/gas_diff_stats.py +++ b/scripts/gas_diff_stats.py @@ -116,10 +116,16 @@ def parse_git_diff(fname): return None return collect_statistics(diff_output) - def stat(old, new): - if old == 0: + def percent(old, new): + return (int(new) - int(old)) / int(old) * 100 if int(old) != 0 else None + + def percent_or_zero(old, new): + result = percent(old, new) + return result if result is not None else 0 + + def format_percent(percentage): + if percentage is None: return '' - percentage = (new - old) / old * 100 prefix = ( # Distinguish actual zero from very small differences '+' if round(percentage) == 0 and percentage > 0 else @@ -128,6 +134,9 @@ def stat(old, new): ) return f'{prefix}{round(percentage)}%' + def stat(old, new): + return format_percent(percent(old, new)) + table = [] if not SEMANTIC_TEST_DIR.is_dir(): @@ -138,16 +147,24 @@ def stat(old, new): parsed = parse_git_diff(fname) if parsed is None: continue + assert len(parsed) == 6 ir_optimized = stat(parsed[0], parsed[3]) legacy_optimized = stat(parsed[1], parsed[4]) legacy = stat(parsed[2], parsed[5]) fname = f"`{fname.split('/', 3)[-1]}`" - table += [[fname, ir_optimized, legacy_optimized, legacy]] + average = (( + percent_or_zero(parsed[0], parsed[3]) + + percent_or_zero(parsed[1], parsed[4]) + + percent_or_zero(parsed[2], parsed[5]) + ) / 3) + table += [[average, fname, ir_optimized, legacy_optimized, legacy]] + + sorted_table = [row[1:] for row in sorted(table, reverse=True)] if table: print("
Click for a table of gas differences\n") table_header = ["File name", "IR optimized", "Legacy optimized", "Legacy"] - print(tabulate(sorted(table), headers=table_header, tablefmt="github")) + print(tabulate(sorted_table, headers=table_header, tablefmt="github")) print("
") else: print("No differences found.") From 125767ed17b9a6ab517aaf6ef910b7eaabe82fe0 Mon Sep 17 00:00:00 2001 From: Martin Blicha Date: Tue, 27 Feb 2024 17:21:34 +0100 Subject: [PATCH 0073/1022] SMTCommand: Remember to flush query before calling solver On MacOS I often experienced a problem that the solver reported SMT-LIB file as malformed. It appears that the whole query was not written to the file and using std::flush fixed the problem. --- Changelog.md | 1 + libsolidity/interface/SMTSolverCommand.cpp | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/Changelog.md b/Changelog.md index b2ac59c65af8..33e2793d5c37 100644 --- a/Changelog.md +++ b/Changelog.md @@ -10,6 +10,7 @@ Compiler Features: Bugfixes: * Assembler: Prevent incorrect calculation of tag sizes. * SMTChecker: Fix internal error caused by not respecting the sign of an integer type when constructing zero-value SMT expressions. + * SMTChecker: Ensure query is properly flushed to a file before calling solver when using SMT-LIB interface. ### 0.8.24 (2024-01-25) diff --git a/libsolidity/interface/SMTSolverCommand.cpp b/libsolidity/interface/SMTSolverCommand.cpp index 92e0485b84a7..d1c58c0c0a69 100644 --- a/libsolidity/interface/SMTSolverCommand.cpp +++ b/libsolidity/interface/SMTSolverCommand.cpp @@ -51,7 +51,7 @@ ReadCallback::Result SMTSolverCommand::solve(std::string const& _kind, std::stri auto queryFileName = tempDir.path() / ("query_" + queryHash.hex() + ".smt2"); auto queryFile = boost::filesystem::ofstream(queryFileName); - queryFile << _query; + queryFile << _query << std::flush; auto eldBin = boost::process::search_path(m_solverCmd); From 51eff63222ae7866ebbda2cc280c3291e74ac719 Mon Sep 17 00:00:00 2001 From: ByeongSu Go <107296751+eclipse1228@users.noreply.github.com> Date: Thu, 29 Feb 2024 18:45:48 +0900 Subject: [PATCH 0074/1022] Update introduction-to-smart-contracts.rst (#14884) --- docs/introduction-to-smart-contracts.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/introduction-to-smart-contracts.rst b/docs/introduction-to-smart-contracts.rst index c4cc1201b02a..614cb275d4cd 100644 --- a/docs/introduction-to-smart-contracts.rst +++ b/docs/introduction-to-smart-contracts.rst @@ -156,7 +156,7 @@ creates a public state variable, but it is a more complex datatype. The :ref:`mapping ` type maps addresses to :ref:`unsigned integers `. Mappings can be seen as `hash tables `_ which are -virtually initialised such that every possible key exists from the start and is mapped to a +virtually initialized such that every possible key exists from the start and is mapped to a value whose byte-representation is all zeros. However, it is neither possible to obtain a list of all keys of a mapping, nor a list of all values. Record what you added to the mapping, or use it in a context where this is not needed. Or From e7aaf03d57e560d29a6c3e7ae631aba7c3fbccf7 Mon Sep 17 00:00:00 2001 From: Vojtch Date: Thu, 29 Feb 2024 10:58:53 +0100 Subject: [PATCH 0075/1022] docs: Replace references to "mining" with "attestation" (#14147) * docs: fix old wording Updated mining to attestation, but maybe it doesn't even make sense to put it like this. This is for the maintainers to decide but maybe it'd make sense to remove "(which is called "attestation")" altogether and just add a link to more information about LMD-GHOST. * Update docs/introduction-to-smart-contracts.rst --------- Co-authored-by: Vishwa Mehta --- docs/introduction-to-smart-contracts.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/introduction-to-smart-contracts.rst b/docs/introduction-to-smart-contracts.rst index 614cb275d4cd..3c43e5f193b2 100644 --- a/docs/introduction-to-smart-contracts.rst +++ b/docs/introduction-to-smart-contracts.rst @@ -304,7 +304,7 @@ These blocks form a linear sequence in time, and that is where the word "blockch Blocks are added to the chain at regular intervals, although these intervals may be subject to change in the future. For the most up-to-date information, it is recommended to monitor the network, for example, on `Etherscan `_. -As part of the "order selection mechanism" (which is called "mining") it may happen that +As part of the "order selection mechanism", which is called `attestation `_, it may happen that blocks are reverted from time to time, but only at the "tip" of the chain. The more blocks are added on top of a particular block, the less likely this block will be reverted. So it might be that your transactions are reverted and even removed from the blockchain, but the longer you wait, the less From 9bd2424cffbd7b21ee37b736c7c339f606bd6667 Mon Sep 17 00:00:00 2001 From: Chomtana Date: Thu, 29 Feb 2024 17:02:31 +0700 Subject: [PATCH 0076/1022] Fix typos in variable names and comment (#14876) * Fix word determinsm -> determinism * Fix word Optimzation -> Optimization * Fix word affilate -> affiliate * fix: import_base assertion --- libyul/optimiser/StackCompressor.cpp | 6 ++--- test/compilationTests/corion/ico.sol | 22 +++++++++---------- .../smtCheckerTests/imports/import_base.sol | 4 ++-- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/libyul/optimiser/StackCompressor.cpp b/libyul/optimiser/StackCompressor.cpp index 87a5e411c5e2..58552147a608 100644 --- a/libyul/optimiser/StackCompressor.cpp +++ b/libyul/optimiser/StackCompressor.cpp @@ -253,7 +253,7 @@ bool StackCompressor::run( _optimizeStackAllocation && evmDialect->evmVersion().canOverchargeGasForCall() && evmDialect->providesObjectAccess(); - bool allowMSizeOptimzation = !MSizeFinder::containsMSize(_dialect, *_object.code); + bool allowMSizeOptimization = !MSizeFinder::containsMSize(_dialect, *_object.code); if (usesOptimizedCodeGenerator) { yul::AsmAnalysisInfo analysisInfo = yul::AsmAnalyzer::analyzeStrictAssertCorrect(_dialect, _object); @@ -262,7 +262,7 @@ bool StackCompressor::run( _dialect, *_object.code, StackLayoutGenerator::reportStackTooDeep(*cfg), - allowMSizeOptimzation + allowMSizeOptimization ); } else @@ -275,7 +275,7 @@ bool StackCompressor::run( _dialect, *_object.code, stackSurplus, - allowMSizeOptimzation + allowMSizeOptimization ); } return false; diff --git a/test/compilationTests/corion/ico.sol b/test/compilationTests/corion/ico.sol index 36510ea65843..35960fe43a44 100644 --- a/test/compilationTests/corion/ico.sol +++ b/test/compilationTests/corion/ico.sol @@ -284,7 +284,7 @@ contract ico is safeMath { require( buy(payable(msg.sender), address(0x00)) ); } - function buy(address payable beneficiaryAddress, address affilateAddress) public payable returns (bool success) { + function buy(address payable beneficiaryAddress, address affiliateAddress) public payable returns (bool success) { /* Buying a token @@ -297,12 +297,12 @@ contract ico is safeMath { More than 1e10 token: 3% More than 1e9 token: 2% below 1% @beneficiaryAddress The address of the accredited where the token will be sent. - @affilateAddress The address of the person who offered who will get the referral reward. It can not be equal with the beneficiaryAddress. + @affiliateAddress The address of the person who offered who will get the referral reward. It can not be equal with the beneficiaryAddress. */ require( isICO() ); if ( beneficiaryAddress == address(0x00)) { beneficiaryAddress = payable(msg.sender); } - if ( beneficiaryAddress == affilateAddress ) { - affilateAddress = address(0x00); + if ( beneficiaryAddress == affiliateAddress ) { + affiliateAddress = address(0x00); } uint256 _value = msg.value; if ( beneficiaryAddress.balance < 0.2 ether ) { @@ -317,9 +317,9 @@ contract ico is safeMath { totalMint = safeAdd(totalMint, _reward); require( foundationAddress.send(_value * 10 / 100) ); uint256 extra; - if ( affilateAddress != address(0x00) && ( brought[affilateAddress].eth > 0 || interestDB[affilateAddress][0].amount > 0 ) ) { - affiliate[affilateAddress].weight = safeAdd(affiliate[affilateAddress].weight, _reward); - extra = affiliate[affilateAddress].weight; + if ( affiliateAddress != address(0x00) && ( brought[affiliateAddress].eth > 0 || interestDB[affiliateAddress][0].amount > 0 ) ) { + affiliate[affiliateAddress].weight = safeAdd(affiliate[affiliateAddress].weight, _reward); + extra = affiliate[affiliateAddress].weight; uint256 rate; if (extra >= 1e12) { rate = 5; @@ -332,12 +332,12 @@ contract ico is safeMath { } else { rate = 1; } - extra = safeSub(extra * rate / 100, affiliate[affilateAddress].paid); - affiliate[affilateAddress].paid = safeAdd(affiliate[affilateAddress].paid, extra); - token(tokenAddr).mint(affilateAddress, extra); + extra = safeSub(extra * rate / 100, affiliate[affiliateAddress].paid); + affiliate[affiliateAddress].paid = safeAdd(affiliate[affiliateAddress].paid, extra); + token(tokenAddr).mint(affiliateAddress, extra); } checkPremium(beneficiaryAddress); - emit EICO(beneficiaryAddress, _reward, affilateAddress, extra); + emit EICO(beneficiaryAddress, _reward, affiliateAddress, extra); return true; } diff --git a/test/libsolidity/smtCheckerTests/imports/import_base.sol b/test/libsolidity/smtCheckerTests/imports/import_base.sol index 3e8aeefe4845..fb6ed2ee4800 100644 --- a/test/libsolidity/smtCheckerTests/imports/import_base.sol +++ b/test/libsolidity/smtCheckerTests/imports/import_base.sol @@ -12,7 +12,7 @@ contract Base { import "base"; contract Der is Base { function g(uint y) public { - require(x < 10); // added to restrict the search space and avoid non-determinsm in Spacer + require(x < 10); // added to restrict the search space and avoid non-determinism in Spacer x += f(); assert(y > x); } @@ -20,5 +20,5 @@ contract Der is Base { // ==== // SMTEngine: all // ---- -// Warning 6328: (der:173-186): CHC: Assertion violation happens here. +// Warning 6328: (der:174-187): CHC: Assertion violation happens here. // Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. From 7676ab1014b9fe6bd4314cb648ef790933992e7f Mon Sep 17 00:00:00 2001 From: Aditya Kode <105551807+adityakode@users.noreply.github.com> Date: Thu, 29 Feb 2024 15:38:54 +0530 Subject: [PATCH 0077/1022] Update natspec-format.rst : Added structs and enums to Tags (#14267) * Update natspec-format.rst * Update docs/natspec-format.rst --------- Co-authored-by: Vishwa Mehta --- docs/natspec-format.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/natspec-format.rst b/docs/natspec-format.rst index 0265fef3e689..f92958b90c02 100644 --- a/docs/natspec-format.rst +++ b/docs/natspec-format.rst @@ -115,10 +115,10 @@ in the same way as if it were tagged with ``@notice``. =============== ====================================================================================== ============================= Tag Context =============== ====================================================================================== ============================= -``@title`` A title that should describe the contract/interface contract, library, interface -``@author`` The name of the author contract, library, interface -``@notice`` Explain to an end user what this does contract, library, interface, function, public state variable, event -``@dev`` Explain to a developer any extra details contract, library, interface, function, state variable, event +``@title`` A title that should describe the contract/interface contract, library, interface, struct, enum +``@author`` The name of the author contract, library, interface, struct, enum +``@notice`` Explain to an end user what this does contract, library, interface, function, public state variable, event, struct, enum +``@dev`` Explain to a developer any extra details contract, library, interface, function, state variable, event, struct, enum ``@param`` Documents a parameter just like in Doxygen (must be followed by parameter name) function, event ``@return`` Documents the return variables of a contract's function function, public state variable ``@inheritdoc`` Copies all missing tags from the base function (must be followed by the contract name) function, public state variable From 6b417ddf521dd8620fc00b7bebb14ede24b3d747 Mon Sep 17 00:00:00 2001 From: Alexander Arlt Date: Fri, 1 Mar 2024 19:40:14 +0100 Subject: [PATCH 0078/1022] [evmasm] Fix handling of missing source locations during import. --- Changelog.md | 1 + libevmasm/Assembly.cpp | 6 ++++-- .../asm_json_import_all_valid_flags/output | 20 +++++++++---------- .../output | 1 - .../output | 1 - .../output | 1 - 6 files changed, 15 insertions(+), 15 deletions(-) diff --git a/Changelog.md b/Changelog.md index 33e2793d5c37..c279531cfe8c 100644 --- a/Changelog.md +++ b/Changelog.md @@ -9,6 +9,7 @@ Compiler Features: Bugfixes: * Assembler: Prevent incorrect calculation of tag sizes. + * EVM Assembly Import: Fix handling of missing source locations during import. * SMTChecker: Fix internal error caused by not respecting the sign of an integer type when constructing zero-value SMT expressions. * SMTChecker: Ensure query is properly flushed to a file before calling solver when using SMT-LIB interface. diff --git a/libevmasm/Assembly.cpp b/libevmasm/Assembly.cpp index 569ecda26a84..067e230343d0 100644 --- a/libevmasm/Assembly.cpp +++ b/libevmasm/Assembly.cpp @@ -124,8 +124,10 @@ AssemblyItem Assembly::createAssemblyItemFromJSON(Json::Value const& _json, std: solRequire(!name.empty(), AssemblyImportException, "Member 'name' is empty."); SourceLocation location; - location.start = get(_json["begin"]); - location.end = get(_json["end"]); + if (_json.isMember("begin")) + location.start = get(_json["begin"]); + if (_json.isMember("end")) + location.end = get(_json["end"]); int srcIndex = getOrDefault(_json["source"], -1); size_t modifierDepth = static_cast(getOrDefault(_json["modifierDepth"], 0)); std::string value = getOrDefault(_json["value"], ""); diff --git a/test/cmdlineTests/asm_json_import_all_valid_flags/output b/test/cmdlineTests/asm_json_import_all_valid_flags/output index 7b8aa0297982..837187d195ae 100644 --- a/test/cmdlineTests/asm_json_import_all_valid_flags/output +++ b/test/cmdlineTests/asm_json_import_all_valid_flags/output @@ -8,8 +8,8 @@ ".code": [ { - "begin": 0, - "end": 0, + "begin": -1, + "end": -1, "name": "PUSH", "source": -1, "value": "0" @@ -22,8 +22,8 @@ ".code": [ { - "begin": 0, - "end": 0, + "begin": -1, + "end": -1, "name": "PUSH", "source": -1, "value": "1" @@ -40,8 +40,8 @@ "bin": "5ffe", "bin-runtime": "6001", "opcodes": "PUSH0 INVALID ", - "srcmap": "0:0::-:0", - "srcmap-runtime": "0:0::-:0" + "srcmap": ":::-:0", + "srcmap-runtime": ":::-:0" } }, "sourceList": @@ -60,8 +60,8 @@ EVM assembly: ".code": [ { - "begin": 0, - "end": 0, + "begin": -1, + "end": -1, "name": "PUSH", "source": -1, "value": "0" @@ -74,8 +74,8 @@ EVM assembly: ".code": [ { - "begin": 0, - "end": 0, + "begin": -1, + "end": -1, "name": "PUSH", "source": -1, "value": "1" diff --git a/test/cmdlineTests/asm_json_import_difficulty_prevrandao/output b/test/cmdlineTests/asm_json_import_difficulty_prevrandao/output index 3d19f83d668f..1713fb49b6cc 100644 --- a/test/cmdlineTests/asm_json_import_difficulty_prevrandao/output +++ b/test/cmdlineTests/asm_json_import_difficulty_prevrandao/output @@ -1,6 +1,5 @@ Opcodes: PREVRANDAO PREVRANDAO EVM assembly: - /* */ prevrandao prevrandao diff --git a/test/cmdlineTests/asm_json_import_hex_subassembly_indices/output b/test/cmdlineTests/asm_json_import_hex_subassembly_indices/output index 873465aa1f3f..60f114ba68e0 100644 --- a/test/cmdlineTests/asm_json_import_hex_subassembly_indices/output +++ b/test/cmdlineTests/asm_json_import_hex_subassembly_indices/output @@ -1,7 +1,6 @@ Opcodes: PUSH0 INVALID EVM assembly: - /* */ 0x00 stop diff --git a/test/cmdlineTests/asm_json_import_random_order_data_index/output b/test/cmdlineTests/asm_json_import_random_order_data_index/output index b23848e5ddcb..ab2f02dc7c84 100644 --- a/test/cmdlineTests/asm_json_import_random_order_data_index/output +++ b/test/cmdlineTests/asm_json_import_random_order_data_index/output @@ -1,7 +1,6 @@ Opcodes: PUSH0 INVALID EVM assembly: - /* */ 0x00 stop From b630c0a415fd49e6fdc398bc9fef38ea3cef2a0e Mon Sep 17 00:00:00 2001 From: minaminao Date: Thu, 27 Jul 2023 13:38:27 +0900 Subject: [PATCH 0079/1022] fix: rename RedundantAssignEliminator to UnusedAssignEliminator --- docs/internals/optimizer.rst | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/docs/internals/optimizer.rst b/docs/internals/optimizer.rst index 70896333c2bc..0a160d61199e 100644 --- a/docs/internals/optimizer.rst +++ b/docs/internals/optimizer.rst @@ -298,7 +298,7 @@ The following transformation steps are the main components: - SSA Transform - Common Subexpression Eliminator - Expression Simplifier -- Redundant Assign Eliminator +- Unused Assign Eliminator - Full Inliner .. _optimizer-steps: @@ -335,11 +335,11 @@ Abbreviation Full name ``T`` :ref:`literal-rematerialiser` ``L`` :ref:`load-resolver` ``M`` :ref:`loop-invariant-code-motion` -``r`` :ref:`redundant-assign-eliminator` ``m`` :ref:`rematerialiser` ``V`` :ref:`SSA-reverser` ``a`` :ref:`SSA-transform` ``t`` :ref:`structural-simplifier` +``r`` :ref:`unused-assign-eliminator` ``p`` :ref:`unused-function-parameter-pruner` ``S`` :ref:`unused-store-eliminator` ``u`` :ref:`unused-pruner` @@ -652,7 +652,7 @@ the block, a new SSA variable will be created at the location where control flow this includes the beginning of loop post/body block and the location right after If/Switch/ForLoop/Block statement. -After this stage, the Redundant Assign Eliminator is recommended to remove the unnecessary +After this stage, the Unused Assign Eliminator is recommended to remove the unnecessary intermediate assignments. This stage provides best results if the Expression Splitter and the Common Subexpression Eliminator @@ -660,10 +660,10 @@ are run right before it, because then it does not generate excessive amounts of On the other hand, the Common Subexpression Eliminator could be more efficient if run after the SSA transform. -.. _redundant-assign-eliminator: +.. _unused-assign-eliminator: -RedundantAssignEliminator -^^^^^^^^^^^^^^^^^^^^^^^^^ +UnusedAssignEliminator +^^^^^^^^^^^^^^^^^^^^^^ The SSA transform always generates an assignment of the form ``a := a_i``, even though these might be unnecessary in many cases, like the following example: @@ -691,7 +691,7 @@ The SSA transform converts this snippet to the following: sstore(a_3, 1) } -The Redundant Assign Eliminator removes all the three assignments to ``a``, because +The Unused Assign Eliminator removes all the three assignments to ``a``, because the value of ``a`` is not used and thus turn this snippet into strict SSA form: @@ -704,7 +704,7 @@ snippet into strict SSA form: sstore(a_3, 1) } -Of course the intricate parts of determining whether an assignment is redundant or not +Of course the intricate parts of determining whether an assignment is unused or not are connected to joining control flow. The component works as follows in detail: @@ -829,7 +829,7 @@ current value if the value is an identifier. The combination of the two rules above allow to compute a local value numbering, which means that if two variables have the same value, one of them will always be unused. The Unused Pruner or the -Redundant Assign Eliminator will then be able to fully eliminate such +Unused Assign Eliminator will then be able to fully eliminate such variables. This step is especially efficient if the expression splitter is run From 8709ae9304a58f22053d74c9f08100360696a5c5 Mon Sep 17 00:00:00 2001 From: minaminao Date: Thu, 17 Aug 2023 12:29:00 +0900 Subject: [PATCH 0080/1022] fix: typos --- docs/bugs.rst | 2 +- docs/cheatsheet.rst | 2 +- docs/contracts/inheritance.rst | 2 +- docs/contributing.rst | 4 ++-- docs/installing-solidity.rst | 16 ++++++++-------- docs/internals/optimizer.rst | 4 ++-- 6 files changed, 15 insertions(+), 15 deletions(-) diff --git a/docs/bugs.rst b/docs/bugs.rst index 350b1e7a48e8..f7f18e9a7f86 100644 --- a/docs/bugs.rst +++ b/docs/bugs.rst @@ -7,7 +7,7 @@ List of Known Bugs ################## Below, you can find a JSON-formatted list of some of the known security-relevant bugs in the -Solidity compiler. The file itself is hosted in the `Github repository +Solidity compiler. The file itself is hosted in the `GitHub repository `_. The list stretches back as far as version 0.3.0, bugs known to be present only in versions preceding that are not listed. diff --git a/docs/cheatsheet.rst b/docs/cheatsheet.rst index 2b68d7311982..e4f7beabd5f5 100644 --- a/docs/cheatsheet.rst +++ b/docs/cheatsheet.rst @@ -159,7 +159,7 @@ Modifiers - ``pure`` for functions: Disallows modification or access of state. - ``view`` for functions: Disallows modification of state. - ``payable`` for functions: Allows them to receive Ether together with a call. -- ``constant`` for state variables: Disallows assignment (except initialisation), does not occupy storage slot. +- ``constant`` for state variables: Disallows assignment (except initialization), does not occupy storage slot. - ``immutable`` for state variables: Allows assignment at construction time and is constant when deployed. Is stored in code. - ``anonymous`` for events: Does not store event signature as topic. - ``indexed`` for event parameters: Stores the parameter as topic. diff --git a/docs/contracts/inheritance.rst b/docs/contracts/inheritance.rst index c787c5af6a90..02ab19163ffb 100644 --- a/docs/contracts/inheritance.rst +++ b/docs/contracts/inheritance.rst @@ -398,7 +398,7 @@ Constructors A constructor is an optional function declared with the ``constructor`` keyword which is executed upon contract creation, and where you can run contract -initialisation code. +initialization code. Before the constructor code is executed, state variables are initialised to their specified value if you initialise them inline, or their :ref:`default value` if you do not. diff --git a/docs/contributing.rst b/docs/contributing.rst index ac4e2375ebdc..8ce402680bb1 100644 --- a/docs/contributing.rst +++ b/docs/contributing.rst @@ -128,7 +128,7 @@ for the ``evmone`` shared object can be specified via the ``ETH_EVMONE`` environ If you do not have it installed, you can skip these tests by passing the ``--no-semantic-tests`` flag to ``scripts/soltest.sh``. -The ``evmone`` library should both end with the file name +The ``evmone`` library should end with the file name extension ``.so`` on Linux, ``.dll`` on Windows systems and ``.dylib`` on macOS. For running SMT tests, the ``libz3`` library must be installed and locatable @@ -552,7 +552,7 @@ topics, issues or feature implementations are debated in detail. The invitation We are also sharing feedback surveys and other content that is relevant to language design in the forum. -If you want to know where the team is standing in terms or implementing new features, you can follow the implementation status in the `Solidity Github project `_. +If you want to know where the team is standing in terms or implementing new features, you can follow the implementation status in the `Solidity GitHub project `_. Issues in the design backlog need further specification and will either be discussed in a language design call or in a regular team call. You can see the upcoming changes for the next breaking release by changing from the default branch (`develop`) to the `breaking branch `_. diff --git a/docs/installing-solidity.rst b/docs/installing-solidity.rst index 2f048fe3c104..ab688a8f448c 100644 --- a/docs/installing-solidity.rst +++ b/docs/installing-solidity.rst @@ -83,14 +83,14 @@ and runs it in a new container, passing the ``--help`` argument. docker run ethereum/solc:stable --help -For example, You can specify release build versions in the tag for the 0.5.4 release. +You can specify release build versions in the tag. For example: .. code-block:: bash docker run ethereum/solc:0.5.4 --help To use the Docker image to compile Solidity files on the host machine, mount a -local folder for input and output, and specify the contract to compile. For example. +local folder for input and output, and specify the contract to compile. For example: .. code-block:: bash @@ -183,7 +183,7 @@ If you need a specific version of Solidity you can install a Homebrew formula directly from Github. View -`solidity.rb commits on Github `_. +`solidity.rb commits on GitHub `_. Copy the commit hash of the version you want and check it out on your machine. @@ -224,8 +224,8 @@ out-of-the-box but it is also meant to be friendly to third-party tools: (via git, HTTPS, IPFS or just have it cached locally) and verify hashes of the binaries after downloading them, you do not have to use HTTPS for the binaries themselves. -The same binaries are in most cases available on the `Solidity release page on Github`_. The -difference is that we do not generally update old releases on the Github release page. This means +The same binaries are in most cases available on the `Solidity release page on GitHub`_. The +difference is that we do not generally update old releases on the GitHub release page. This means that we do not rename them if the naming convention changes and we do not add builds for platforms that were not supported at the time of release. This only happens in ``solc-bin``. @@ -301,7 +301,7 @@ This means that: .. _IPFS: https://ipfs.io .. _Swarm: https://swarm-gateways.net/bzz:/swarm.eth .. _solc-bin: https://github.com/ethereum/solc-bin/ -.. _Solidity release page on github: https://github.com/ethereum/solidity/releases +.. _Solidity release page on GitHub: https://github.com/ethereum/solidity/releases .. _sha3sum: https://github.com/maandree/sha3sum .. _keccak256() function from ethereumjs-util: https://github.com/ethereumjs/ethereumjs-util/blob/master/docs/modules/_hash_.md#const-keccak256 .. _WebAssembly builds: https://emscripten.org/docs/compiling/WebAssembly.html @@ -461,11 +461,11 @@ you should fork Solidity and add your personal fork as a second remote: This method will result in a pre-release build leading to e.g. a flag being set in each bytecode produced by such a compiler. If you want to re-build a released Solidity compiler, then - please use the source tarball on the github release page: + please use the source tarball on the GitHub release page: https://github.com/ethereum/solidity/releases/download/v0.X.Y/solidity_0.X.Y.tar.gz - (not the "Source code" provided by github). + (not the "Source code" provided by GitHub). Command-Line Build ------------------ diff --git a/docs/internals/optimizer.rst b/docs/internals/optimizer.rst index 0a160d61199e..4588cb48358c 100644 --- a/docs/internals/optimizer.rst +++ b/docs/internals/optimizer.rst @@ -482,7 +482,7 @@ is transformed to } This eases the rest of the optimization process because we can ignore -the complicated scoping rules of the for loop initialisation block. +the complicated scoping rules of the for loop initialization block. .. _var-decl-initializer: @@ -1217,7 +1217,7 @@ The FullInliner replaces certain calls of certain functions by the function's body. This is not very helpful in most cases, because it just increases the code size but does not have a benefit. Furthermore, code is usually very expensive and we would often rather have shorter -code than more efficient code. In same cases, though, inlining a function +code than more efficient code. In some cases, though, inlining a function can have positive effects on subsequent optimizer steps. This is the case if one of the function arguments is a constant, for example. From f96a8514ad8a4119b793a54227ef7e83e2fbdb85 Mon Sep 17 00:00:00 2001 From: minaminao Date: Thu, 17 Aug 2023 12:31:32 +0900 Subject: [PATCH 0081/1022] chore: update example version of solidity in docker command --- docs/installing-solidity.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/installing-solidity.rst b/docs/installing-solidity.rst index ab688a8f448c..123f17422d7e 100644 --- a/docs/installing-solidity.rst +++ b/docs/installing-solidity.rst @@ -87,7 +87,7 @@ You can specify release build versions in the tag. For example: .. code-block:: bash - docker run ethereum/solc:0.5.4 --help + docker run ethereum/solc:0.8.21 --help To use the Docker image to compile Solidity files on the host machine, mount a local folder for input and output, and specify the contract to compile. For example: From 0225d9d336578e33480432b651ed02d2266f024c Mon Sep 17 00:00:00 2001 From: Vishwa Mehta Date: Fri, 1 Mar 2024 22:46:20 +0530 Subject: [PATCH 0082/1022] Update installing-solidity.rst --- docs/installing-solidity.rst | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/docs/installing-solidity.rst b/docs/installing-solidity.rst index 123f17422d7e..4e0948189d01 100644 --- a/docs/installing-solidity.rst +++ b/docs/installing-solidity.rst @@ -87,7 +87,12 @@ You can specify release build versions in the tag. For example: .. code-block:: bash - docker run ethereum/solc:0.8.21 --help + docker run ethereum/solc:stable --help + +Note: Specific version tags are supported for the Docker tag such as `docker run ethereum/solc:0.8.23 --help`. + +We will be passing the `stable` tag here instead of specific version tag to ensure that users get the latest version +by default and avoid the issue of an out-of-date version. To use the Docker image to compile Solidity files on the host machine, mount a local folder for input and output, and specify the contract to compile. For example: From 51b697676c47b775370c727094106939092fea92 Mon Sep 17 00:00:00 2001 From: Vishwa Mehta Date: Fri, 1 Mar 2024 22:53:45 +0530 Subject: [PATCH 0083/1022] Update installing-solidity.rst --- docs/installing-solidity.rst | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/docs/installing-solidity.rst b/docs/installing-solidity.rst index 4e0948189d01..bc20ae346168 100644 --- a/docs/installing-solidity.rst +++ b/docs/installing-solidity.rst @@ -89,10 +89,11 @@ You can specify release build versions in the tag. For example: docker run ethereum/solc:stable --help -Note: Specific version tags are supported for the Docker tag such as `docker run ethereum/solc:0.8.23 --help`. +Note -We will be passing the `stable` tag here instead of specific version tag to ensure that users get the latest version -by default and avoid the issue of an out-of-date version. +Specific version tags are supported for the Docker tag such as `docker run ethereum/solc:0.8.23 --help`. We will be passing the +`stable` tag here instead of specific version tag to ensure that users get the latest version by default and avoid the issue of +an out-of-date version. To use the Docker image to compile Solidity files on the host machine, mount a local folder for input and output, and specify the contract to compile. For example: From 8f0cb8a7afb59b653b1dcf334b16243023934309 Mon Sep 17 00:00:00 2001 From: Vishwa Mehta Date: Mon, 4 Mar 2024 12:41:49 +0530 Subject: [PATCH 0084/1022] Update docs/installing-solidity.rst Co-authored-by: r0qs --- docs/installing-solidity.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/installing-solidity.rst b/docs/installing-solidity.rst index bc20ae346168..8d5b421d3a19 100644 --- a/docs/installing-solidity.rst +++ b/docs/installing-solidity.rst @@ -91,7 +91,7 @@ You can specify release build versions in the tag. For example: Note -Specific version tags are supported for the Docker tag such as `docker run ethereum/solc:0.8.23 --help`. We will be passing the +Specific compiler versions are supported as the Docker image tag such as `ethereum/solc:0.8.23`. We will be passing the `stable` tag here instead of specific version tag to ensure that users get the latest version by default and avoid the issue of an out-of-date version. From cbd84372da1d6e02a5a023b46a1921eefccb2abd Mon Sep 17 00:00:00 2001 From: Alexander Arlt Date: Mon, 4 Mar 2024 14:53:53 +0100 Subject: [PATCH 0085/1022] Fix python snippet causing "SyntaxWarning" in Scanner. --- test/cmdlineTests.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/cmdlineTests.sh b/test/cmdlineTests.sh index 3166cd6b5dd0..4f7b88fe974f 100755 --- a/test/cmdlineTests.sh +++ b/test/cmdlineTests.sh @@ -216,7 +216,7 @@ import re, sys json = open("$stdout_path", "r").read() json = re.sub(r"{[^{}]*Warning: This is a pre-release compiler version[^{}]*},?", "", json) json = re.sub(r"\"errors\":\s*\[\s*\],?","\n" if json[1] == " " else "",json) # Remove "errors" array if it's not empty -json = re.sub("\n\\s*\n", "\n", json) # Remove trailing whitespace +json = re.sub(r"\n\s*\n", "\n", json) # Remove trailing whitespace json = re.sub(r"},(\n{0,1})\n*(\s*(]|}))", r"}\1\2", json) # Remove trailing comma open("$stdout_path", "w").write(json) EOF From a6830fd939e7be9f0406761da4a5c51f398bd5ef Mon Sep 17 00:00:00 2001 From: Matheus Aguiar Date: Wed, 28 Feb 2024 22:52:25 -0300 Subject: [PATCH 0086/1022] Emit transient storage warning only once --- Changelog.md | 1 + liblangutil/ErrorReporter.cpp | 11 +++++++++ liblangutil/ErrorReporter.h | 3 +++ libyul/AsmAnalysis.cpp | 3 ++- ...e_warning_only_once_multiple_contracts.sol | 23 +++++++++++++++++++ .../tstore_warning_only_once.yul | 10 ++++++++ 6 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 test/libsolidity/syntaxTests/inlineAssembly/tstore_warning_only_once_multiple_contracts.sol create mode 100644 test/libyul/yulSyntaxTests/tstore_warning_only_once.yul diff --git a/Changelog.md b/Changelog.md index c279531cfe8c..6defb4d72b53 100644 --- a/Changelog.md +++ b/Changelog.md @@ -5,6 +5,7 @@ Language Features: Compiler Features: * Code Generator: Use ``MCOPY`` instead of ``MLOAD``/``MSTORE`` loop when copying byte arrays. + * Yul Analyzer: Emit transient storage warning only for the first occurrence of ``tstore``. Bugfixes: diff --git a/liblangutil/ErrorReporter.cpp b/liblangutil/ErrorReporter.cpp index 298e4f630f10..bf10483aa5a2 100644 --- a/liblangutil/ErrorReporter.cpp +++ b/liblangutil/ErrorReporter.cpp @@ -23,6 +23,7 @@ #include #include +#include #include using namespace solidity; @@ -81,6 +82,16 @@ bool ErrorReporter::hasExcessiveErrors() const return m_errorCount > c_maxErrorsAllowed; } +bool ErrorReporter::hasError(ErrorId _errorId) const +{ + auto errorMatch = [&](std::shared_ptr const& error) -> bool { + solAssert(error.get()); + return error->errorId() == _errorId; + }; + + return ranges::find_if(m_errorList, errorMatch) != ranges::end(m_errorList); +} + bool ErrorReporter::checkForExcessiveErrors(Error::Type _type) { if (_type == Error::Type::Warning) diff --git a/liblangutil/ErrorReporter.h b/liblangutil/ErrorReporter.h index 6901e87b94f8..c78b6f498d2e 100644 --- a/liblangutil/ErrorReporter.h +++ b/liblangutil/ErrorReporter.h @@ -137,6 +137,9 @@ class ErrorReporter // @returns true if the maximum error count has been reached. bool hasExcessiveErrors() const; + /// @returns true if there is at least one occurrence of error + bool hasError(ErrorId _errorId) const; + class ErrorWatcher { public: diff --git a/libyul/AsmAnalysis.cpp b/libyul/AsmAnalysis.cpp index cc811f75d182..0efaa12c2c8a 100644 --- a/libyul/AsmAnalysis.cpp +++ b/libyul/AsmAnalysis.cpp @@ -324,7 +324,8 @@ std::vector AsmAnalyzer::operator()(FunctionCall const& _funCall) ); else if ( m_evmVersion.supportsTransientStorage() && - _funCall.functionName.name == "tstore"_yulstring + _funCall.functionName.name == "tstore"_yulstring && + !m_errorReporter.hasError({2394}) ) m_errorReporter.warning( 2394_error, diff --git a/test/libsolidity/syntaxTests/inlineAssembly/tstore_warning_only_once_multiple_contracts.sol b/test/libsolidity/syntaxTests/inlineAssembly/tstore_warning_only_once_multiple_contracts.sol new file mode 100644 index 000000000000..5b05831f659b --- /dev/null +++ b/test/libsolidity/syntaxTests/inlineAssembly/tstore_warning_only_once_multiple_contracts.sol @@ -0,0 +1,23 @@ +contract C { + function f() external { + assembly { + tstore(0, 0) + let a := tload(0) + tstore(0, 1) + tstore(1, a) + } + } +} + +contract D { + function g() external { + assembly { + tstore(0, 0) + tstore(0, 1) + } + } +} +// ==== +// EVMVersion: >=cancun +// ---- +// Warning 2394: (72-78): Transient storage as defined by EIP-1153 can break the composability of smart contracts: Since transient storage is cleared only at the end of the transaction and not at the end of the outermost call frame to the contract within a transaction, your contract may unintentionally misbehave when invoked multiple times in a complex transaction. To avoid this, be sure to clear all transient storage at the end of any call to your contract. The use of transient storage for reentrancy guards that are cleared at the end of the call is safe. diff --git a/test/libyul/yulSyntaxTests/tstore_warning_only_once.yul b/test/libyul/yulSyntaxTests/tstore_warning_only_once.yul new file mode 100644 index 000000000000..44a6b59b49ab --- /dev/null +++ b/test/libyul/yulSyntaxTests/tstore_warning_only_once.yul @@ -0,0 +1,10 @@ +{ + tstore(0, 0) + tstore(0, 1) + let x := tload(0) + tstore(1, 0) +} +// ==== +// EVMVersion: >=cancun +// ---- +// Warning 2394: (6-12): Transient storage as defined by EIP-1153 can break the composability of smart contracts: Since transient storage is cleared only at the end of the transaction and not at the end of the outermost call frame to the contract within a transaction, your contract may unintentionally misbehave when invoked multiple times in a complex transaction. To avoid this, be sure to clear all transient storage at the end of any call to your contract. The use of transient storage for reentrancy guards that are cleared at the end of the call is safe. From ad77fd7c67fcff25e5963b6398a909a67220725a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Tue, 6 Feb 2024 14:39:21 +0100 Subject: [PATCH 0087/1022] EVMHost: Rename newlyCreatedAccounts to m_newlyCreatedAccounts --- test/EVMHost.cpp | 6 +++--- test/EVMHost.h | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/test/EVMHost.cpp b/test/EVMHost.cpp index c43d53d6bc43..b4005e16eabb 100644 --- a/test/EVMHost.cpp +++ b/test/EVMHost.cpp @@ -198,12 +198,12 @@ void EVMHost::newTransactionFrame() } // Process selfdestruct list for (auto& [address, _]: recorded_selfdestructs) - if (m_evmVersion < langutil::EVMVersion::cancun() || newlyCreatedAccounts.count(address)) + if (m_evmVersion < langutil::EVMVersion::cancun() || m_newlyCreatedAccounts.count(address)) // EIP-6780: If SELFDESTRUCT is executed in a transaction different from the one // in which it was created, we do NOT record it or clear any data. // Otherwise, the previous behavior (pre-Cancun) is maintained. accounts.erase(address); - newlyCreatedAccounts.clear(); + m_newlyCreatedAccounts.clear(); m_totalCodeDepositGas = 0; recorded_selfdestructs.clear(); } @@ -358,7 +358,7 @@ evmc::Result EVMHost::call(evmc_message const& _message) noexcept auto& destination = accounts[message.recipient]; if (message.kind == EVMC_CREATE || message.kind == EVMC_CREATE2) // Mark account as created if it is a CREATE or CREATE2 call - newlyCreatedAccounts.emplace(message.recipient); + m_newlyCreatedAccounts.emplace(message.recipient); if (value != 0 && message.kind != EVMC_DELEGATECALL && message.kind != EVMC_CALLCODE) { diff --git a/test/EVMHost.h b/test/EVMHost.h index 848314c87974..121adbc15945 100644 --- a/test/EVMHost.h +++ b/test/EVMHost.h @@ -131,15 +131,15 @@ class EVMHost: public evmc::MockedHost static evmc::Result resultWithGas(int64_t gas_limit, int64_t gas_required, bytes const& _data) noexcept; static evmc::Result resultWithFailure() noexcept; - /// Store the accounts that have been created in the current transaction. - std::unordered_set newlyCreatedAccounts; - evmc::VM& m_vm; /// EVM version requested by the testing tool langutil::EVMVersion m_evmVersion; /// EVM version requested from EVMC (matches the above) evmc_revision m_evmRevision; + /// Store the accounts that have been created in the current transaction. + std::unordered_set m_newlyCreatedAccounts; + /// The part of the total cost of the current transaction that paid for the code deposits. /// I.e. GAS_CODE_DEPOSIT times the total size of deployed code of all newly created contracts, /// including the current contract itself if it was a creation transaction. From 41363d723cc530fe7e0d586454d96ccdd41ac7e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Tue, 6 Feb 2024 14:39:41 +0100 Subject: [PATCH 0088/1022] EVMHost: Reset m_newlyCreatedAccounts() in reset() --- test/EVMHost.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/test/EVMHost.cpp b/test/EVMHost.cpp index b4005e16eabb..e74491862a2b 100644 --- a/test/EVMHost.cpp +++ b/test/EVMHost.cpp @@ -161,6 +161,7 @@ void EVMHost::reset() recorded_calls.clear(); // Clear EIP-2929 account access indicator recorded_account_accesses.clear(); + m_newlyCreatedAccounts.clear(); m_totalCodeDepositGas = 0; // Mark all precompiled contracts as existing. Existing here means to have a balance (as per EIP-161). From c09d2c091bd98048c7ba86f22c0364ab991e21b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Sun, 11 Feb 2024 18:59:16 +0100 Subject: [PATCH 0089/1022] EVMHost: Note about newly created accounts not being rolled back --- test/EVMHost.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/test/EVMHost.cpp b/test/EVMHost.cpp index e74491862a2b..2243758356db 100644 --- a/test/EVMHost.cpp +++ b/test/EVMHost.cpp @@ -359,6 +359,7 @@ evmc::Result EVMHost::call(evmc_message const& _message) noexcept auto& destination = accounts[message.recipient]; if (message.kind == EVMC_CREATE || message.kind == EVMC_CREATE2) // Mark account as created if it is a CREATE or CREATE2 call + // TODO: Should we roll changes back on failure like we do for `accounts`? m_newlyCreatedAccounts.emplace(message.recipient); if (value != 0 && message.kind != EVMC_DELEGATECALL && message.kind != EVMC_CALLCODE) From 2b2c76c214c9c5770856f91601426ab6b79a2d0b Mon Sep 17 00:00:00 2001 From: racerole Date: Wed, 6 Mar 2024 10:52:46 +0800 Subject: [PATCH 0090/1022] remove repetitive word Signed-off-by: racerole --- test/libyul/yulInterpreterTests/mcopy.yul | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/libyul/yulInterpreterTests/mcopy.yul b/test/libyul/yulInterpreterTests/mcopy.yul index 6483239cb151..3ec6af00213f 100644 --- a/test/libyul/yulInterpreterTests/mcopy.yul +++ b/test/libyul/yulInterpreterTests/mcopy.yul @@ -7,7 +7,7 @@ mcopy(0x60, 0, 32) // Append a duplicate of the first word past msize mcopy(0x90, 0x30, 1) // Copy the 0x44 byte from the middle of second word past msize mcopy(0, 0, 0) // No-op - mcopy(0x2f, 0x90, 2) // Copy the 0x4400 straddling msize back into the the middle of second word + mcopy(0x2f, 0x90, 2) // Copy the 0x4400 straddling msize back into the middle of second word mcopy(0xa0, 0, 160) // Duplicate the whole thing } // ==== From 1affe8e0d7445803402bc643599a5f475cf9a112 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Wed, 6 Mar 2024 17:13:21 +0100 Subject: [PATCH 0091/1022] gp2: Remove config section that requires an Etherscan key --- test/externalTests/gp2.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/test/externalTests/gp2.sh b/test/externalTests/gp2.sh index 1e52134a43de..af77f99aa8b8 100755 --- a/test/externalTests/gp2.sh +++ b/test/externalTests/gp2.sh @@ -67,6 +67,9 @@ function gp2_test force_hardhat_unlimited_contract_size "$config_file" "$config_var" yarn + # Remove the config section that requires an Etherscan key. We don't need it just to run tests. + sed -i '/^ etherscan: {$/,/^ },$/d' hardhat.config.ts + # Some dependencies come with pre-built artifacts. We want to build from scratch. rm -r node_modules/@gnosis.pm/safe-contracts/build/ From 21566ccf82cff1cb72a71e428139db7c7ee7cf0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Wed, 6 Mar 2024 17:17:14 +0100 Subject: [PATCH 0092/1022] bleeps: Disable the ir-optimize-evm+yul preset, which now results in StackTooDeep --- test/externalTests/bleeps.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/externalTests/bleeps.sh b/test/externalTests/bleeps.sh index 5090e6c12e92..5a987e45933e 100755 --- a/test/externalTests/bleeps.sh +++ b/test/externalTests/bleeps.sh @@ -47,7 +47,7 @@ function bleeps_test "${compile_only_presets[@]}" #ir-no-optimize # Compilation fails with: "YulException: Variable expr_15509_mpos is 4 too deep in the stack". No memoryguard was present. #ir-optimize-evm-only # Compilation fails with: "YulException: Variable expr_15260_mpos is 4 too deep in the stack". No memoryguard was present. - ir-optimize-evm+yul + #ir-optimize-evm+yul # Compilation fails with: "YulException: Variable expr_15208_mpos is 1 too deep in the stack". No memoryguard was present. #legacy-no-optimize # Compilation fails with: "CompilerError: Stack too deep, try removing local variables." #legacy-optimize-evm-only # Compilation fails with: "CompilerError: Stack too deep, try removing local variables." legacy-optimize-evm+yul From ce63512f9526b5cf0e5994591114ecb81bde7379 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Wed, 6 Mar 2024 15:59:35 +0100 Subject: [PATCH 0093/1022] chainlink: Switch base image back to node 16 --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 30c0229642a0..c2394cdce04c 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -819,7 +819,7 @@ defaults: name: t_native_test_ext_chainlink project: chainlink binary_type: native - image: cimg/node:18.16 + image: cimg/node:16.20 resource_class: large # Tests run out of memory on a smaller machine - job_native_test_ext_gp2: &job_native_test_ext_gp2 From 95bcc632cefe3f2c8cdec449290fb0b4dee82c90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Wed, 6 Mar 2024 19:00:39 +0100 Subject: [PATCH 0094/1022] Convert all the disabled external tests into compile-only tests This way we can still get bytecode size benchmarks for them --- .circleci/config.yml | 86 ++++++++++++++++++++++++-------------------- 1 file changed, 48 insertions(+), 38 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index c2394cdce04c..f30429fe6112 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -720,11 +720,14 @@ defaults: image: cimg/node:14.20 python2: true - - job_native_test_ext_gnosis: &job_native_test_ext_gnosis + - job_native_compile_ext_gnosis: &job_native_compile_ext_gnosis <<: *requires_b_ubu_static - name: t_native_test_ext_gnosis + name: t_native_compile_ext_gnosis project: gnosis binary_type: native + # NOTE: We are disabling the gnosis test suite due to version discrepancies that are difficult to fix. + # Check again after (and if) https://github.com/safe-global/safe-contracts/pull/644 is merged. + compile_only: 1 image: cimg/node:18.16 - job_native_test_ext_zeppelin: &job_native_test_ext_zeppelin @@ -742,18 +745,24 @@ defaults: binary_type: native image: cimg/node:18.16 - - job_native_test_ext_trident: &job_native_test_ext_trident + - job_native_compile_ext_trident: &job_native_compile_ext_trident <<: *requires_b_ubu_static - name: t_native_test_ext_trident + name: t_native_compile_ext_trident project: trident binary_type: native + # NOTE: test suite disabled due to dependence on a specific version of Hardhat + # which does not support shanghai EVM. + compile_only: 1 image: cimg/node:18.16 - - job_native_test_ext_euler: &job_native_test_ext_euler + - job_native_compile_ext_euler: &job_native_compile_ext_euler <<: *requires_b_ubu_static - name: t_native_test_ext_euler + name: t_native_compile_ext_euler project: euler binary_type: native + # NOTE: test suite disabled due to dependence on a specific version of Hardhat + # which does not support shanghai EVM. + compile_only: 1 resource_class: medium - job_native_test_ext_yield_liquidator: &job_native_test_ext_yield_liquidator @@ -763,18 +772,24 @@ defaults: binary_type: native image: cimg/node:18.16 - - job_native_test_ext_bleeps: &job_native_test_ext_bleeps + - job_native_compile_ext_bleeps: &job_native_compile_ext_bleeps <<: *requires_b_ubu_static - name: t_native_test_ext_bleeps + name: t_native_compile_ext_bleeps project: bleeps binary_type: native + # NOTE: test suite disabled due to dependence on a specific version of Hardhat + # which does not support shanghai EVM. + compile_only: 1 resource_class: medium - - job_native_test_ext_pool_together: &job_native_test_ext_pool_together + - job_native_compile_ext_pool_together: &job_native_compile_ext_pool_together <<: *requires_b_ubu_static - name: t_native_test_ext_pool_together + name: t_native_compile_ext_pool_together project: pool-together binary_type: native + # NOTE: test suite disabled due to dependence on a specific version of Hardhat + # which does not support shanghai EVM. + compile_only: 1 image: cimg/node:18.16 - job_native_test_ext_perpetual_pools: &job_native_test_ext_perpetual_pools @@ -814,19 +829,24 @@ defaults: binary_type: native image: cimg/node:18.16 - - job_native_test_ext_chainlink: &job_native_test_ext_chainlink + - job_native_compile_ext_chainlink: &job_native_compile_ext_chainlink <<: *requires_b_ubu_static - name: t_native_test_ext_chainlink + name: t_native_compile_ext_chainlink project: chainlink binary_type: native + # NOTE: test suite disabled due to dependence on a specific version of Hardhat + # which does not support shanghai EVM. + compile_only: 1 image: cimg/node:16.20 resource_class: large # Tests run out of memory on a smaller machine - - job_native_test_ext_gp2: &job_native_test_ext_gp2 + - job_native_compile_ext_gp2: &job_native_compile_ext_gp2 <<: *requires_b_ubu_static - name: t_native_test_ext_gp2 + name: t_native_compile_ext_gp2 project: gp2 binary_type: native + # NOTE: test suite disabled due to constant failures. + compile_only: 1 image: cimg/node:18.16 - job_b_ubu_asan_clang: &job_b_ubu_asan_clang @@ -1868,9 +1888,7 @@ workflows: - t_ext: *job_ems_compile_ext_colony - # NOTE: We are disabling the gnosis test suite due to version discrepancies that are difficult to fix. - # Check again after (and if) https://github.com/safe-global/safe-contracts/pull/644 is merged. - #- t_ext: *job_native_test_ext_gnosis + - t_ext: *job_native_compile_ext_gnosis - t_ext: *job_native_test_ext_zeppelin - t_ext: *job_native_test_ext_ens - t_ext: *job_native_test_ext_yield_liquidator @@ -1879,23 +1897,18 @@ workflows: - t_ext: *job_native_test_ext_prb_math - t_ext: *job_native_test_ext_elementfi - t_ext: *job_native_test_ext_brink - # NOTE: We are disabling gp2 tests due to constant failures. - # - t_ext: *job_native_test_ext_gp2 - # NOTE: The external tests below were commented because they - # depend on a specific version of hardhat which does not support shanghai EVM. - #- t_ext: *job_native_test_ext_trident - #- t_ext: *job_native_test_ext_euler - #- t_ext: *job_native_test_ext_bleeps - #- t_ext: *job_native_test_ext_pool_together - #- t_ext: *job_native_test_ext_chainlink + - t_ext: *job_native_compile_ext_gp2 + - t_ext: *job_native_compile_ext_trident + - t_ext: *job_native_compile_ext_euler + - t_ext: *job_native_compile_ext_bleeps + - t_ext: *job_native_compile_ext_pool_together + - t_ext: *job_native_compile_ext_chainlink - c_ext_benchmarks: <<: *requires_nothing requires: - t_ems_compile_ext_colony - # NOTE: We are disabling the gnosis test suite due to version discrepancies that are difficult to fix. - # Check again after (and if) https://github.com/safe-global/safe-contracts/pull/644 is merged. - #- t_native_test_ext_gnosis + - t_native_compile_ext_gnosis - t_native_test_ext_zeppelin - t_native_test_ext_ens - t_native_test_ext_yield_liquidator @@ -1903,18 +1916,15 @@ workflows: - t_native_test_ext_uniswap - t_native_test_ext_elementfi - t_native_test_ext_brink - # NOTE: We are disabling gp2 tests due to constant failures. - #- t_native_test_ext_gp2 + - t_native_compile_ext_gp2 # TODO: Dropping prb-math from the benchmarks since it is not implemented yet # in the new Foundry external testing infrastructure. # - t_native_test_ext_prb_math - # NOTE: The external tests below were commented because they - # depend on a specific version of hardhat which does not support shanghai EVM. - #- t_native_test_ext_trident - #- t_native_test_ext_euler - #- t_native_test_ext_bleeps - #- t_native_test_ext_pool_together - #- t_native_test_ext_chainlink + - t_native_compile_ext_trident + - t_native_compile_ext_euler + - t_native_compile_ext_bleeps + - t_native_compile_ext_pool_together + - t_native_compile_ext_chainlink # Windows build and tests - b_win: *requires_nothing From 5aed3c4bbb04f0d43c6467d64e9a5a8cfb963dd8 Mon Sep 17 00:00:00 2001 From: r0qs Date: Wed, 6 Mar 2024 15:11:25 +0100 Subject: [PATCH 0095/1022] Fix hardhat version to 2.20.0 on uniswap and perpetual_pools external tests --- test/externalTests/perpetual-pools.sh | 5 +++++ test/externalTests/uniswap.sh | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/test/externalTests/perpetual-pools.sh b/test/externalTests/perpetual-pools.sh index 31748a40ca2a..1d7bb8f33b3e 100755 --- a/test/externalTests/perpetual-pools.sh +++ b/test/externalTests/perpetual-pools.sh @@ -69,7 +69,12 @@ function perpetual_pools_test force_hardhat_compiler_binary "$config_file" "$BINARY_TYPE" "$BINARY_PATH" force_hardhat_compiler_settings "$config_file" "$(first_word "$SELECTED_PRESETS")" "$config_var" force_hardhat_unlimited_contract_size "$config_file" "$config_var" + yarn install + # We set hardhat version to 2.20.0 since version 2.21.0 has issues with solidity-coverage plugin + # that often causes out-of-memory errors. + # See hardhat note about the issue here: https://github.com/NomicFoundation/hardhat/releases/tag/hardhat@2.21.0 + yarn add hardhat@2.20.0 replace_version_pragmas diff --git a/test/externalTests/uniswap.sh b/test/externalTests/uniswap.sh index bf5f828987eb..04f27ab3f77f 100755 --- a/test/externalTests/uniswap.sh +++ b/test/externalTests/uniswap.sh @@ -90,6 +90,11 @@ function uniswap_test # TODO: Remove when https://github.com/ethers-io/ethers.js/discussions/2849 is resolved. yarn add ethers@5.6.1 + # We set hardhat version to 2.20.0 since version 2.21.0 has issues with solidity-coverage plugin + # that often causes out-of-memory errors. + # See hardhat note about the issue here: https://github.com/NomicFoundation/hardhat/releases/tag/hardhat@2.21.0 + yarn add hardhat@2.20.0 + replace_version_pragmas for preset in $SELECTED_PRESETS; do From d29eded2da25e91fc7bb126e67030ea09da44d9c Mon Sep 17 00:00:00 2001 From: Saw-mon & Natalie <3140080+Saw-mon-and-Natalie@users.noreply.github.com> Date: Thu, 7 Mar 2024 16:33:17 +0100 Subject: [PATCH 0096/1022] reorders assertThrow statements and adds one to the MCOPY case. --- libevmasm/SemanticInformation.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libevmasm/SemanticInformation.cpp b/libevmasm/SemanticInformation.cpp index c5e14d5f4b85..978fb7ce2aef 100644 --- a/libevmasm/SemanticInformation.cpp +++ b/libevmasm/SemanticInformation.cpp @@ -87,8 +87,8 @@ std::vector SemanticInformation::readWriteOperat case Instruction::LOG4: { assertThrow(storage(_instruction) == Effect::None, OptimizerException, ""); - assertThrow(transientStorage(_instruction) == Effect::None, OptimizerException, ""); assertThrow(memory(_instruction) == Effect::Read, OptimizerException, ""); + assertThrow(transientStorage(_instruction) == Effect::None, OptimizerException, ""); Operation op; op.effect = memory(_instruction); op.location = Location::Memory; @@ -126,6 +126,7 @@ std::vector SemanticInformation::readWriteOperat { assertThrow(memory(_instruction) != Effect::None, OptimizerException, ""); assertThrow(storage(_instruction) == Effect::None, OptimizerException, ""); + assertThrow(transientStorage(_instruction) == Effect::None, OptimizerException, ""); Operation readOperation; readOperation.effect = Read; From 6ee38afed8792dd1dd669612a226bf8080a49ae2 Mon Sep 17 00:00:00 2001 From: Alexander Arlt Date: Thu, 7 Mar 2024 21:19:08 +0100 Subject: [PATCH 0097/1022] [solutil] Add missing include guard. --- libsolutil/cxx20.h | 1 + 1 file changed, 1 insertion(+) diff --git a/libsolutil/cxx20.h b/libsolutil/cxx20.h index c65b0454b89c..a21a73e681af 100644 --- a/libsolutil/cxx20.h +++ b/libsolutil/cxx20.h @@ -15,6 +15,7 @@ along with solidity. If not, see . */ // SPDX-License-Identifier: GPL-3.0 +#pragma once #include From e084f71f7b28294e38576458d72d32855aa4e0e5 Mon Sep 17 00:00:00 2001 From: Cyrus Date: Fri, 8 Mar 2024 12:11:48 +0800 Subject: [PATCH 0098/1022] fix typos --- libevmasm/GasMeter.h | 2 +- libevmasm/Inliner.cpp | 2 +- libsolidity/parsing/Parser.h | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/libevmasm/GasMeter.h b/libevmasm/GasMeter.h index e4bb19925796..c91e0f0971c9 100644 --- a/libevmasm/GasMeter.h +++ b/libevmasm/GasMeter.h @@ -216,7 +216,7 @@ class GasMeter /// @returns an upper bound on the gas consumed by the given instruction and updates /// the state. - /// @param _inculdeExternalCosts if true, include costs caused by other contracts in calls. + /// @param _includeExternalCosts if true, include costs caused by other contracts in calls. GasConsumption estimateMax(AssemblyItem const& _item, bool _includeExternalCosts = true); u256 const& largestMemoryAccess() const { return m_largestMemoryAccess; } diff --git a/libevmasm/Inliner.cpp b/libevmasm/Inliner.cpp index ded5172ddc3a..67918e558bc3 100644 --- a/libevmasm/Inliner.cpp +++ b/libevmasm/Inliner.cpp @@ -44,7 +44,7 @@ using namespace solidity::evmasm; namespace { -/// @returns an estimation of the runtime gas cost of the AsssemblyItems in @a _itemRange. +/// @returns an estimation of the runtime gas cost of the AssemblyItems in @a _itemRange. template u256 executionCost(RangeType const& _itemRange, langutil::EVMVersion _evmVersion) { diff --git a/libsolidity/parsing/Parser.h b/libsolidity/parsing/Parser.h index aedfdb7ddd37..8f0868ac1172 100644 --- a/libsolidity/parsing/Parser.h +++ b/libsolidity/parsing/Parser.h @@ -223,10 +223,10 @@ class Parser: public langutil::ParserBase /// or an expression; IndexAccessedPath parseIndexAccessedPath(); /// @returns a typename parsed in look-ahead fashion from something like "a.b[8][2**70]", - /// or an empty pointer if an empty @a _pathAndIncides has been supplied. + /// or an empty pointer if an empty @a _pathAndIndices has been supplied. ASTPointer typeNameFromIndexAccessStructure(IndexAccessedPath const& _pathAndIndices); /// @returns an expression parsed in look-ahead fashion from something like "a.b[8][2**70]", - /// or an empty pointer if an empty @a _pathAndIncides has been supplied. + /// or an empty pointer if an empty @a _pathAndIndices has been supplied. ASTPointer expressionFromIndexAccessStructure(IndexAccessedPath const& _pathAndIndices); ASTPointer expectIdentifierToken(); From 86444080a45f475a1065522ffd0ee32e28120c72 Mon Sep 17 00:00:00 2001 From: r0qs Date: Wed, 29 Nov 2023 15:46:30 -0300 Subject: [PATCH 0099/1022] Move deprecated evm versions to nightly CI workflow --- .circleci/config.yml | 27 ++++++++++++++++++++++++++- .circleci/soltest_all.sh | 7 +++++-- 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 59d00ff4155e..af5ddef21be1 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -220,11 +220,18 @@ commands: command: .circleci/soltest.sh run_soltest_all: + parameters: + # NOTE: If not specified, soltest_all.sh will use the default values as specified in the script. + # In other words, it will execute for all EVM versions that are not marked as deprecated. + evm_versions: + description: "List of EVM versions (separated by space)." + type: string + default: "" steps: - run: name: soltest_all no_output_timeout: 30m - command: .circleci/soltest_all.sh + command: .circleci/soltest_all.sh "<< parameters.evm_versions >>" run_cmdline_tests: steps: @@ -1267,6 +1274,20 @@ jobs: steps: - soltest_all + t_ubu_soltest_deprecated_evm_versions: &t_ubu_soltest_deprecated_evm_versions + <<: *base_ubuntu2204_large + parallelism: 50 + steps: + - checkout + - attach_workspace: + at: build + - run_soltest_all: + evm_versions: homestead byzantium + - store_test_results: + path: test_results/ + - store_artifacts_test_results + - matrix_notify_failure_unless_pr + t_ubu_lsp: &t_ubu_lsp <<: *base_ubuntu2204_small steps: @@ -2004,6 +2025,10 @@ workflows: - t_ubu_ubsan_clang_soltest: *requires_b_ubu_ubsan_clang - t_ubu_ubsan_clang_cli: *requires_b_ubu_ubsan_clang + # Deprecated EVM versions tests + - b_ubu: *requires_nothing + - t_ubu_soltest_deprecated_evm_versions: *requires_b_ubu + nightly-ossfuzz: triggers: diff --git a/.circleci/soltest_all.sh b/.circleci/soltest_all.sh index 1e941731dac3..40ee75b270cd 100755 --- a/.circleci/soltest_all.sh +++ b/.circleci/soltest_all.sh @@ -31,9 +31,12 @@ REPODIR="$(realpath "$(dirname "$0")"/..)" # shellcheck source=scripts/common.sh source "${REPODIR}/scripts/common.sh" -EVM_VALUES=(homestead byzantium constantinople petersburg istanbul berlin london paris shanghai cancun) +DEFAULT_EVM_VALUES=(constantinople petersburg istanbul berlin london paris shanghai cancun) +# Deserialize the EVM_VALUES array if it was provided as argument or +# set EVM_VALUES to the default values. +IFS=" " read -ra EVM_VALUES <<< "${1:-${DEFAULT_EVM_VALUES[@]}}" + DEFAULT_EVM=shanghai -[[ " ${EVM_VALUES[*]} " =~ $DEFAULT_EVM ]] OPTIMIZE_VALUES=(0 1) # Run for ABI encoder v1, without SMTChecker tests. From 9762ebb24cdb79e22d94215e0ebccc27937c63e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Fri, 8 Mar 2024 18:55:33 +0100 Subject: [PATCH 0100/1022] Fix unnecessary compilation when --via-ir is used on its own --- Changelog.md | 1 + libsolidity/interface/CompilerStack.cpp | 2 +- test/cmdlineTests/abi_via_ir/args | 1 + test/cmdlineTests/abi_via_ir/input.sol | 28 ++++ test/cmdlineTests/abi_via_ir/output | 167 ++++++++++++++++++++++++ 5 files changed, 198 insertions(+), 1 deletion(-) create mode 100644 test/cmdlineTests/abi_via_ir/args create mode 100644 test/cmdlineTests/abi_via_ir/input.sol create mode 100644 test/cmdlineTests/abi_via_ir/output diff --git a/Changelog.md b/Changelog.md index 6defb4d72b53..ab62f25eb894 100644 --- a/Changelog.md +++ b/Changelog.md @@ -10,6 +10,7 @@ Compiler Features: Bugfixes: * Assembler: Prevent incorrect calculation of tag sizes. + * Commandline Interface: Do not run IR pipeline when ``--via-ir`` is used but no output that depends on the IR is requested. * EVM Assembly Import: Fix handling of missing source locations during import. * SMTChecker: Fix internal error caused by not respecting the sign of an integer type when constructing zero-value SMT expressions. * SMTChecker: Ensure query is properly flushed to a file before calling solver when using SMT-LIB interface. diff --git a/libsolidity/interface/CompilerStack.cpp b/libsolidity/interface/CompilerStack.cpp index 69394417586e..eca1b50be4f0 100644 --- a/libsolidity/interface/CompilerStack.cpp +++ b/libsolidity/interface/CompilerStack.cpp @@ -736,7 +736,7 @@ bool CompilerStack::compile(State _stopAfter) { try { - if (m_viaIR || m_generateIR) + if ((m_generateEvmBytecode && m_viaIR) || m_generateIR) generateIR(*contract); if (m_generateEvmBytecode) { diff --git a/test/cmdlineTests/abi_via_ir/args b/test/cmdlineTests/abi_via_ir/args new file mode 100644 index 000000000000..5dc346ecb4bb --- /dev/null +++ b/test/cmdlineTests/abi_via_ir/args @@ -0,0 +1 @@ +--abi --via-ir --pretty-json --json-indent 4 diff --git a/test/cmdlineTests/abi_via_ir/input.sol b/test/cmdlineTests/abi_via_ir/input.sol new file mode 100644 index 000000000000..1f5c758f719d --- /dev/null +++ b/test/cmdlineTests/abi_via_ir/input.sol @@ -0,0 +1,28 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity >=0.0; + +error fileLevelError(uint z); + +library L { + event libraryEvent(uint r); + error libraryError(uint r); + error libraryErrorUnused(uint u); + event libraryEventUnused(uint u); +} + +contract C { + struct S { uint x; } + + event ev(uint y); + event anon_ev(uint y) anonymous; + + error err(uint z, uint w); + + function f(S memory s) public { + emit L.libraryEvent(3); + if (s.x > 1) + revert fileLevelError(3); + else + revert L.libraryError(4); + } +} diff --git a/test/cmdlineTests/abi_via_ir/output b/test/cmdlineTests/abi_via_ir/output new file mode 100644 index 000000000000..daf18f3497a7 --- /dev/null +++ b/test/cmdlineTests/abi_via_ir/output @@ -0,0 +1,167 @@ + +======= abi_via_ir/input.sol:C ======= +Contract JSON ABI +[ + { + "inputs": + [ + { + "internalType": "uint256", + "name": "z", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "w", + "type": "uint256" + } + ], + "name": "err", + "type": "error" + }, + { + "inputs": + [ + { + "internalType": "uint256", + "name": "z", + "type": "uint256" + } + ], + "name": "fileLevelError", + "type": "error" + }, + { + "inputs": + [ + { + "internalType": "uint256", + "name": "r", + "type": "uint256" + } + ], + "name": "libraryError", + "type": "error" + }, + { + "anonymous": true, + "inputs": + [ + { + "indexed": false, + "internalType": "uint256", + "name": "y", + "type": "uint256" + } + ], + "name": "anon_ev", + "type": "event" + }, + { + "anonymous": false, + "inputs": + [ + { + "indexed": false, + "internalType": "uint256", + "name": "y", + "type": "uint256" + } + ], + "name": "ev", + "type": "event" + }, + { + "anonymous": false, + "inputs": + [ + { + "indexed": false, + "internalType": "uint256", + "name": "r", + "type": "uint256" + } + ], + "name": "libraryEvent", + "type": "event" + }, + { + "inputs": + [ + { + "components": + [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + } + ], + "internalType": "struct C.S", + "name": "s", + "type": "tuple" + } + ], + "name": "f", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] + +======= abi_via_ir/input.sol:L ======= +Contract JSON ABI +[ + { + "inputs": + [ + { + "internalType": "uint256", + "name": "r", + "type": "uint256" + } + ], + "name": "libraryError", + "type": "error" + }, + { + "inputs": + [ + { + "internalType": "uint256", + "name": "u", + "type": "uint256" + } + ], + "name": "libraryErrorUnused", + "type": "error" + }, + { + "anonymous": false, + "inputs": + [ + { + "indexed": false, + "internalType": "uint256", + "name": "r", + "type": "uint256" + } + ], + "name": "libraryEvent", + "type": "event" + }, + { + "anonymous": false, + "inputs": + [ + { + "indexed": false, + "internalType": "uint256", + "name": "u", + "type": "uint256" + } + ], + "name": "libraryEventUnused", + "type": "event" + } +] From 0c4bca56a176116940740d0de4f371a0b5357484 Mon Sep 17 00:00:00 2001 From: omahs <73983677+omahs@users.noreply.github.com> Date: Fri, 8 Mar 2024 20:46:24 +0100 Subject: [PATCH 0101/1022] fix typo --- test/compilationTests/corion/ico.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/compilationTests/corion/ico.sol b/test/compilationTests/corion/ico.sol index 35960fe43a44..801b6d402f3a 100644 --- a/test/compilationTests/corion/ico.sol +++ b/test/compilationTests/corion/ico.sol @@ -372,5 +372,5 @@ contract ico is safeMath { return startBlock <= block.number && block.number <= icoDelay && ( ! aborted ) && ( ! closed ); } - event EICO(address indexed Address, uint256 indexed value, address Affiliate, uint256 AffilateValue); + event EICO(address indexed Address, uint256 indexed value, address Affiliate, uint256 AffiliateValue); } From 193a4579aec550f71af7b5355d82ad57a8588d9d Mon Sep 17 00:00:00 2001 From: omahs <73983677+omahs@users.noreply.github.com> Date: Fri, 8 Mar 2024 20:50:22 +0100 Subject: [PATCH 0102/1022] fix typo --- docs/smtchecker.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/smtchecker.rst b/docs/smtchecker.rst index f8085b63de6f..dfdcf465198b 100644 --- a/docs/smtchecker.rst +++ b/docs/smtchecker.rst @@ -944,7 +944,7 @@ the arguments. |complex) | | +-----------------------------------+--------------------------------------+ |external functions without |BMC: Erase state knowledge and assume | -|implementation |result is nondeterminisc. | +|implementation |result is nondeterministic. | | |CHC: Nondeterministic summary. | | |Try to infer invariants that hold | | |after the call returns. | From 0219d1e0f2df22cac5ba8e944f26f20860f7a56e Mon Sep 17 00:00:00 2001 From: Martin Blicha Date: Tue, 5 Mar 2024 13:14:32 +0100 Subject: [PATCH 0103/1022] SMTChecker: Fix usage of Eldarica with SMT callback Previously, CHC engine with SMT interface would always call Eldarica if it was present in the system, regardless whether user specified model-checker-solver as smtlib2 or eld. Here we make sure Eldarica is called only when it is specified as the solver of choice. The proposed solution is to make SMTSolverCommand modifiable and set it up properly based on the user settings. This requires changes also in UniversalCallback, because in the compiler we must be able to check if the given callback is UniversalCallback provided by CommandLineInterface. This mechanism can be used to migrate also other solvers to the SMTLIB interface by further extending/adapting SMTSolverCommand. Its advantage is that meaning of the callback stays the same, thus there is not need to change anything on the side of solc-js. --- Changelog.md | 3 ++- libsolidity/formal/ModelCheckerSettings.h | 2 +- libsolidity/interface/CompilerStack.cpp | 6 ++++++ libsolidity/interface/SMTSolverCommand.cpp | 23 +++++++++++++++++--- libsolidity/interface/SMTSolverCommand.h | 7 +++--- libsolidity/interface/UniversalCallback.h | 25 +++++++++++++--------- solc/CommandLineInterface.h | 2 +- 7 files changed, 49 insertions(+), 19 deletions(-) diff --git a/Changelog.md b/Changelog.md index 6defb4d72b53..6564cb9a3e22 100644 --- a/Changelog.md +++ b/Changelog.md @@ -11,8 +11,9 @@ Compiler Features: Bugfixes: * Assembler: Prevent incorrect calculation of tag sizes. * EVM Assembly Import: Fix handling of missing source locations during import. - * SMTChecker: Fix internal error caused by not respecting the sign of an integer type when constructing zero-value SMT expressions. * SMTChecker: Ensure query is properly flushed to a file before calling solver when using SMT-LIB interface. + * SMTChecker: Fix internal error caused by not respecting the sign of an integer type when constructing zero-value SMT expressions. + * SMTChecker: Run Eldarica only when explicitly requested with `--model-checker-solvers eld`, even when it is present on the system. ### 0.8.24 (2024-01-25) diff --git a/libsolidity/formal/ModelCheckerSettings.h b/libsolidity/formal/ModelCheckerSettings.h index b645f7c3b6e7..0cfa370c40c8 100644 --- a/libsolidity/formal/ModelCheckerSettings.h +++ b/libsolidity/formal/ModelCheckerSettings.h @@ -175,7 +175,7 @@ struct ModelCheckerSettings bool showUnsupported = false; smtutil::SMTSolverChoice solvers = smtutil::SMTSolverChoice::Z3(); ModelCheckerTargets targets = ModelCheckerTargets::Default(); - std::optional timeout; + std::optional timeout; // in milliseconds bool operator!=(ModelCheckerSettings const& _other) const noexcept { return !(*this == _other); } bool operator==(ModelCheckerSettings const& _other) const noexcept diff --git a/libsolidity/interface/CompilerStack.cpp b/libsolidity/interface/CompilerStack.cpp index 69394417586e..e9df599630fb 100644 --- a/libsolidity/interface/CompilerStack.cpp +++ b/libsolidity/interface/CompilerStack.cpp @@ -53,6 +53,7 @@ #include #include #include +#include #include #include @@ -654,7 +655,12 @@ bool CompilerStack::analyzeLegacy(bool _noErrorsSoFar) // m_modelCheckerSettings is spread to engines and solver interfaces, // so we need to check whether the enabled ones are available before building the classes. if (m_modelCheckerSettings.engine.any()) + { m_modelCheckerSettings.solvers = ModelChecker::checkRequestedSolvers(m_modelCheckerSettings.solvers, m_errorReporter); + if (auto* universalCallback = m_readFile.target()) + if (m_modelCheckerSettings.solvers.eld) + universalCallback->smtCommand().setEldarica(m_modelCheckerSettings.timeout); + } ModelChecker modelChecker(m_errorReporter, *this, m_smtlib2Responses, m_modelCheckerSettings, m_readFile); modelChecker.checkRequestedSourcesAndContracts(allSources); diff --git a/libsolidity/interface/SMTSolverCommand.cpp b/libsolidity/interface/SMTSolverCommand.cpp index d1c58c0c0a69..8ef36cb75189 100644 --- a/libsolidity/interface/SMTSolverCommand.cpp +++ b/libsolidity/interface/SMTSolverCommand.cpp @@ -37,7 +37,17 @@ using solidity::util::errinfo_comment; namespace solidity::frontend { -SMTSolverCommand::SMTSolverCommand(std::string _solverCmd) : m_solverCmd(_solverCmd) {} +void SMTSolverCommand::setEldarica(std::optional timeoutInMilliseconds) +{ + m_arguments.clear(); + m_solverCmd = "eld"; + if (timeoutInMilliseconds) + { + unsigned int timeoutInSeconds = timeoutInMilliseconds.value() / 1000u; + timeoutInSeconds = timeoutInSeconds == 0 ? 1 : timeoutInSeconds; + m_arguments.push_back("-t:" + std::to_string(timeoutInSeconds)); + } +} ReadCallback::Result SMTSolverCommand::solve(std::string const& _kind, std::string const& _query) { @@ -46,6 +56,9 @@ ReadCallback::Result SMTSolverCommand::solve(std::string const& _kind, std::stri if (_kind != ReadCallback::kindString(ReadCallback::Kind::SMTQuery)) solAssert(false, "SMTQuery callback used as callback kind " + _kind); + if (m_solverCmd.empty()) + return ReadCallback::Result{false, "No solver set."}; + auto tempDir = solidity::util::TemporaryDirectory("smt"); util::h256 queryHash = util::keccak256(_query); auto queryFileName = tempDir.path() / ("query_" + queryHash.hex() + ".smt2"); @@ -58,11 +71,15 @@ ReadCallback::Result SMTSolverCommand::solve(std::string const& _kind, std::stri if (eldBin.empty()) return ReadCallback::Result{false, m_solverCmd + " binary not found."}; + auto args = m_arguments; + args.push_back(queryFileName.string()); + boost::process::ipstream pipe; boost::process::child eld( eldBin, - queryFileName, - boost::process::std_out > pipe + args, + boost::process::std_out > pipe, + boost::process::std_err >boost::process::null ); std::vector data; diff --git a/libsolidity/interface/SMTSolverCommand.h b/libsolidity/interface/SMTSolverCommand.h index 56a6ba171055..1d1201e49062 100644 --- a/libsolidity/interface/SMTSolverCommand.h +++ b/libsolidity/interface/SMTSolverCommand.h @@ -28,8 +28,6 @@ namespace solidity::frontend class SMTSolverCommand { public: - SMTSolverCommand(std::string _solverCmd); - /// Calls an SMT solver with the given query. frontend::ReadCallback::Result solve(std::string const& _kind, std::string const& _query); @@ -38,9 +36,12 @@ class SMTSolverCommand return [this](std::string const& _kind, std::string const& _query) { return solve(_kind, _query); }; } + void setEldarica(std::optional timeoutInMilliseconds); + private: /// The name of the solver's binary. - std::string const m_solverCmd; + std::string m_solverCmd; + std::vector m_arguments; }; } diff --git a/libsolidity/interface/UniversalCallback.h b/libsolidity/interface/UniversalCallback.h index 3fe74c65e48f..ef5450a1c5e4 100644 --- a/libsolidity/interface/UniversalCallback.h +++ b/libsolidity/interface/UniversalCallback.h @@ -34,22 +34,27 @@ class UniversalCallback m_solver{_solver} {} + ReadCallback::Result operator()(std::string const& _kind, std::string const& _data) + { + if (_kind == ReadCallback::kindString(ReadCallback::Kind::ReadFile)) + if (!m_fileReader) + return ReadCallback::Result{false, "No import callback."}; + else + return m_fileReader->readFile(_kind, _data); + else if (_kind == ReadCallback::kindString(ReadCallback::Kind::SMTQuery)) + return m_solver.solve(_kind, _data); + solAssert(false, "Unknown callback kind."); + } + frontend::ReadCallback::Callback callback() { - return [this](std::string const& _kind, std::string const& _data) -> ReadCallback::Result { - if (_kind == ReadCallback::kindString(ReadCallback::Kind::ReadFile)) - if (!m_fileReader) - return ReadCallback::Result{false, "No import callback."}; - else - return m_fileReader->readFile(_kind, _data); - else if (_kind == ReadCallback::kindString(ReadCallback::Kind::SMTQuery)) - return m_solver.solve(_kind, _data); - solAssert(false, "Unknown callback kind."); - }; + return *this; } void resetImportCallback() { m_fileReader = nullptr; } + SMTSolverCommand& smtCommand() { return m_solver; } + private: FileReader* m_fileReader; SMTSolverCommand& m_solver; diff --git a/solc/CommandLineInterface.h b/solc/CommandLineInterface.h index 906b34d62b53..1fb4ac00bcb1 100644 --- a/solc/CommandLineInterface.h +++ b/solc/CommandLineInterface.h @@ -147,7 +147,7 @@ class CommandLineInterface std::ostream& m_serr; bool m_hasOutput = false; FileReader m_fileReader; - SMTSolverCommand m_solverCommand{"eld"}; + SMTSolverCommand m_solverCommand; UniversalCallback m_universalCallback{&m_fileReader, m_solverCommand}; std::optional m_standardJsonInput; std::unique_ptr m_compiler; From b18b23daf6c4d812211ff9ef329ae8c44999fb17 Mon Sep 17 00:00:00 2001 From: r0qs Date: Tue, 12 Mar 2024 15:18:39 +0100 Subject: [PATCH 0104/1022] Add missing hardhat networks settings to external tests --- scripts/externalTests/common.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/scripts/externalTests/common.sh b/scripts/externalTests/common.sh index bab5890aa400..de9b8da96d8c 100644 --- a/scripts/externalTests/common.sh +++ b/scripts/externalTests/common.sh @@ -332,12 +332,16 @@ function force_hardhat_compiler_settings echo "require('hardhat-gas-reporter');" echo "module.exports.gasReporter = ${gas_reporter_settings};" echo "module.exports.solidity = ${compiler_settings};" + echo "module.exports.networks.hardhat = module.exports.networks.hardhat || { hardfork: '${evm_version}' }" + echo "module.exports.networks.hardhat.hardfork = '${evm_version}'" else [[ $config_file == *\.ts ]] || assertFail [[ $config_var_name != "" ]] || assertFail echo 'import "hardhat-gas-reporter";' echo "${config_var_name}.gasReporter = ${gas_reporter_settings};" echo "${config_var_name}.solidity = {compilers: [${compiler_settings}]};" + echo "${config_var_name}.networks!.hardhat = ${config_var_name}.networks!.hardhat ?? { hardfork: '${evm_version}' };" + echo "${config_var_name}.networks!.hardhat!.hardfork = '${evm_version}'" fi >> "$config_file" } From c82707cae6a085585421f6952eedffccffb7cb56 Mon Sep 17 00:00:00 2001 From: r0qs Date: Tue, 12 Mar 2024 16:50:51 +0100 Subject: [PATCH 0105/1022] Fix hardhat version to version that supports cancun hardfork --- test/externalTests/brink.sh | 1 + test/externalTests/elementfi.sh | 4 +--- test/externalTests/gnosis.sh | 1 + test/externalTests/pool-together.sh | 3 +++ 4 files changed, 6 insertions(+), 3 deletions(-) diff --git a/test/externalTests/brink.sh b/test/externalTests/brink.sh index 48cc4028f3d7..d8ad001ac014 100755 --- a/test/externalTests/brink.sh +++ b/test/externalTests/brink.sh @@ -64,6 +64,7 @@ function brink_test # TODO: Remove this when Brink merges https://github.com/brinktrade/brink-core/pull/52 sed -i "s|\(function isValidSignature(bytes \)calldata\( _data, bytes \)calldata\( _signature)\)|\1memory\2memory\3|g" src/Test/MockEIP1271Validator.sol + neutralize_package_lock neutralize_package_json_hooks force_hardhat_compiler_binary "$config_file" "$BINARY_TYPE" "$BINARY_PATH" force_hardhat_compiler_settings "$config_file" "$(first_word "$SELECTED_PRESETS")" "$config_var" "$CURRENT_EVM_VERSION" "$extra_settings" "$extra_optimizer_settings" diff --git a/test/externalTests/elementfi.sh b/test/externalTests/elementfi.sh index f3ecbb14170f..f34a169e9512 100755 --- a/test/externalTests/elementfi.sh +++ b/test/externalTests/elementfi.sh @@ -99,9 +99,7 @@ function elementfi_test # "ProviderError: Too Many Requests error received from eth-mainnet.alchemyapi.io" rm test/mockERC20YearnVaultTest.ts - # Several tests fail unless we use the exact versions hard-coded in package-lock.json - #neutralize_package_lock - + neutralize_package_lock neutralize_package_json_hooks force_hardhat_compiler_binary "$config_file" "$BINARY_TYPE" "$BINARY_PATH" force_hardhat_compiler_settings "$config_file" "$(first_word "$SELECTED_PRESETS")" "$config_var" diff --git a/test/externalTests/gnosis.sh b/test/externalTests/gnosis.sh index 218a5a7504b5..416d36153623 100755 --- a/test/externalTests/gnosis.sh +++ b/test/externalTests/gnosis.sh @@ -76,6 +76,7 @@ function gnosis_safe_test sed -i "s|\(it\)\((\"can be used only via DELEGATECALL opcode\"\)|\1.skip\2|g" test/libraries/SignMessageLib.spec.ts sed -i "s|it\((\"can only be called from Safe itself\"\)|it.skip\1|g" test/libraries/Migration.spec.ts + neutralize_package_lock neutralize_package_json_hooks force_hardhat_compiler_binary "$config_file" "$BINARY_TYPE" "$BINARY_PATH" force_hardhat_compiler_settings "$config_file" "$(first_word "$SELECTED_PRESETS")" "$config_var" diff --git a/test/externalTests/pool-together.sh b/test/externalTests/pool-together.sh index f841206ef2a9..0fc8aafbd69d 100755 --- a/test/externalTests/pool-together.sh +++ b/test/externalTests/pool-together.sh @@ -66,6 +66,9 @@ function pool_together_test force_hardhat_compiler_binary "$config_file" "$BINARY_TYPE" "$BINARY_PATH" force_hardhat_compiler_settings "$config_file" "$(first_word "$SELECTED_PRESETS")" "$config_var" yarn install + # Hardhat 2.20.0 is the last version that works. Newer versions throw this error: + # Unexpected config HardhatConfig.networks.hardhat.initialBaseFeePerGas found - This field is only valid for networks with EIP-1559. Try a newer hardfork or remove it. + yarn add hardhat@2.20.0 # These come with already compiled artifacts. We want them recompiled with latest compiler. rm -r node_modules/@pooltogether/yield-source-interface/artifacts/ From 6b3ca241105fd9298a3ff7f9dcb62bf1d58f952b Mon Sep 17 00:00:00 2001 From: r0qs Date: Tue, 12 Mar 2024 18:51:24 +0100 Subject: [PATCH 0106/1022] Disable trident, chainlink and bleeps external tests --- .circleci/config.yml | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index af5ddef21be1..e437e1d38759 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1919,11 +1919,13 @@ workflows: - t_ext: *job_native_test_ext_elementfi - t_ext: *job_native_test_ext_brink - t_ext: *job_native_compile_ext_gp2 - - t_ext: *job_native_compile_ext_trident - t_ext: *job_native_compile_ext_euler - - t_ext: *job_native_compile_ext_bleeps - t_ext: *job_native_compile_ext_pool_together - - t_ext: *job_native_compile_ext_chainlink + # TODO: Dropping the external tests below since they are based on old forks and + # fail after update the default evm version to cancun. + #- t_ext: *job_native_compile_ext_trident + #- t_ext: *job_native_compile_ext_chainlink + #- t_ext: *job_native_compile_ext_bleeps - c_ext_benchmarks: <<: *requires_nothing @@ -1941,11 +1943,13 @@ workflows: # TODO: Dropping prb-math from the benchmarks since it is not implemented yet # in the new Foundry external testing infrastructure. # - t_native_test_ext_prb_math - - t_native_compile_ext_trident - t_native_compile_ext_euler - - t_native_compile_ext_bleeps - t_native_compile_ext_pool_together - - t_native_compile_ext_chainlink + # TODO: Dropping the external tests below since they are based on old forks and + # fail after update the default evm version to cancun. + #- t_native_compile_ext_trident + #- t_native_compile_ext_chainlink + #- t_native_compile_ext_bleeps # Windows build and tests - b_win: *requires_nothing From 7c6f9f1154b757b040b1cbd9e4383caf04ceeaa9 Mon Sep 17 00:00:00 2001 From: Twice Date: Thu, 14 Mar 2024 00:49:02 +0900 Subject: [PATCH 0107/1022] Use move ctor instead of copy ctor in stringOrDefault --- libsolutil/Assertions.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libsolutil/Assertions.h b/libsolutil/Assertions.h index 6735cda166be..4879299bf011 100644 --- a/libsolutil/Assertions.h +++ b/libsolutil/Assertions.h @@ -28,6 +28,7 @@ #include #include +#include namespace solidity::util { @@ -69,7 +70,7 @@ inline std::string stringOrDefault(std::string _string, std::string _defaultStri { // NOTE: Putting this in a function rather than directly in a macro prevents the string from // being evaluated multiple times if it's not just a literal. - return (!_string.empty() ? _string : _defaultString); + return (!_string.empty() ? std::move(_string) : std::move(_defaultString)); } } From ab55b0a49840491cd6e47e87e519360e21e9c518 Mon Sep 17 00:00:00 2001 From: matheusaaguiar <95899911+matheusaaguiar@users.noreply.github.com> Date: Wed, 13 Mar 2024 14:55:48 -0300 Subject: [PATCH 0108/1022] Add multiple source test to ensure transient storage is emitted only once during compilation (#14935) --- ...ore_warning_only_once_multiple_sources.sol | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 test/libsolidity/syntaxTests/inlineAssembly/tstore_warning_only_once_multiple_sources.sol diff --git a/test/libsolidity/syntaxTests/inlineAssembly/tstore_warning_only_once_multiple_sources.sol b/test/libsolidity/syntaxTests/inlineAssembly/tstore_warning_only_once_multiple_sources.sol new file mode 100644 index 000000000000..51e3a19bccc0 --- /dev/null +++ b/test/libsolidity/syntaxTests/inlineAssembly/tstore_warning_only_once_multiple_sources.sol @@ -0,0 +1,34 @@ +==== Source: A ==== +contract C { + function f() external { + assembly { + tstore(0, 0) + let a := tload(0) + tstore(0, 1) + tstore(1, a) + } + } +} +==== Source: B ==== +import {C as C} from "A"; +contract D { + function g() external { + assembly { + tstore(0, 0) + tstore(0, 1) + } + } +} +==== Source: C ==== +contract X { + function h() external { + assembly { + tstore(0, 0) + tstore(0, 0) + } + } +} +// ==== +// EVMVersion: >=cancun +// ---- +// Warning 2394: (A:72-78): Transient storage as defined by EIP-1153 can break the composability of smart contracts: Since transient storage is cleared only at the end of the transaction and not at the end of the outermost call frame to the contract within a transaction, your contract may unintentionally misbehave when invoked multiple times in a complex transaction. To avoid this, be sure to clear all transient storage at the end of any call to your contract. The use of transient storage for reentrancy guards that are cleared at the end of the call is safe. From 7115a63f2d4e159d41a5c517472af92e219d85f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nikola=20Mati=C4=87?= Date: Wed, 13 Mar 2024 20:09:52 +0100 Subject: [PATCH 0109/1022] Update release checklist (#14812) --- ReleaseChecklist.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ReleaseChecklist.md b/ReleaseChecklist.md index 167417a95d1a..5db731cfc591 100644 --- a/ReleaseChecklist.md +++ b/ReleaseChecklist.md @@ -50,7 +50,7 @@ At least a day before the release: ### Create the Release - [ ] Create a [release on GitHub](https://github.com/ethereum/solidity/releases/new). Set the target to the ``develop`` branch and the tag to the new version, e.g. ``v0.8.5``. - Include the following warning: ``**The release is still in progress and the binaries may not yet be available from all sources.**``. + Include the following warning: ``**The release is still in progress. You may see broken links and binaries may not yet be available from all sources.**``. Do not publish it yet - click the ``Save draft`` button instead. - [ ] Thank voluntary contributors in the GitHub release notes. Use ``scripts/list_contributors.sh v`` to get initial list of names. @@ -68,6 +68,7 @@ At least a day before the release: - [ ] Take the ``github-binaries.tar`` tarball from ``c_release_binaries`` run of the tagged commit in circle-ci and add all binaries from it to the release page. Make sure it contains four binaries: ``solc-windows.exe``, ``solc-macos``, ``solc-static-linux`` and ``soljson.js``. - [ ] Take the ``solc-bin-binaries.tar`` tarball from ``c_release_binaries`` run of the tagged commit in circle-ci and add all binaries from it to solc-bin. + - [ ] Run ``npm install`` if you've got a clean checkout of the solc-bin repo. - [ ] Run ``npm run update -- --reuse-hashes`` in ``solc-bin`` and verify that the script has updated ``list.js``, ``list.txt`` and ``list.json`` files correctly and that symlinks to the new release have been added in ``solc-bin/wasm/`` and ``solc-bin/emscripten-wasm32/``. - [ ] Create a pull request in solc-bin and merge. From a15da0a70f3a06822f9a07f0d991bf8250acfa53 Mon Sep 17 00:00:00 2001 From: Vishwa Mehta Date: Wed, 24 Jan 2024 18:49:14 +0530 Subject: [PATCH 0110/1022] Clean up docs to reflect changes in the behaviour of SELFDESTRUCT as per EIP-6780 --- docs/cheatsheet.rst | 2 +- docs/contracts/function-modifiers.rst | 16 +-- docs/contracts/inheritance.rst | 133 +++++++++++++++-------- docs/examples/micropayment.rst | 101 ++++++++++++----- docs/introduction-to-smart-contracts.rst | 20 +++- docs/metadata.rst | 4 +- docs/style-guide.rst | 9 +- docs/units-and-global-variables.rst | 20 +++- docs/using-the-compiler.rst | 4 +- 9 files changed, 207 insertions(+), 102 deletions(-) diff --git a/docs/cheatsheet.rst b/docs/cheatsheet.rst index e4f7beabd5f5..bc678c647d54 100644 --- a/docs/cheatsheet.rst +++ b/docs/cheatsheet.rst @@ -118,7 +118,7 @@ Contract-related - ``this`` (current contract's type): the current contract, explicitly convertible to ``address`` or ``address payable`` - ``super``: a contract one level higher in the inheritance hierarchy -- ``selfdestruct(address payable recipient)``: destroy the current contract, sending its funds to the given address +- ``selfdestruct(address payable recipient)``: send all funds to the given address and (only on EVMs before Cancun or when invoked within the transaction creating the contract) destroy the contract. .. index:: type;name, type;creationCode, type;runtimeCode, type;interfaceId, type;min, type;max diff --git a/docs/contracts/function-modifiers.rst b/docs/contracts/function-modifiers.rst index 454e12ab65cf..2fd0357db054 100644 --- a/docs/contracts/function-modifiers.rst +++ b/docs/contracts/function-modifiers.rst @@ -19,7 +19,6 @@ if they are marked ``virtual``. For details, please see // SPDX-License-Identifier: GPL-3.0 pragma solidity >=0.7.1 <0.9.0; - // This will report a warning due to deprecated selfdestruct contract owned { constructor() { owner = payable(msg.sender); } @@ -41,16 +40,6 @@ if they are marked ``virtual``. For details, please see } } - contract destructible is owned { - // This contract inherits the `onlyOwner` modifier from - // `owned` and applies it to the `destroy` function, which - // causes that calls to `destroy` only have an effect if - // they are made by the stored owner. - function destroy() public onlyOwner { - selfdestruct(owner); - } - } - contract priced { // Modifiers can receive arguments: modifier costs(uint price) { @@ -60,7 +49,7 @@ if they are marked ``virtual``. For details, please see } } - contract Register is priced, destructible { + contract Register is priced, owned { mapping(address => bool) registeredAddresses; uint price; @@ -73,6 +62,9 @@ if they are marked ``virtual``. For details, please see registeredAddresses[msg.sender] = true; } + // This contract inherits the `onlyOwner` modifier from + // the `owned` contract. As a result, calls to `changePrice` will + // only take effect if they are made by the stored owner. function changePrice(uint price_) public onlyOwner { price = price_; } diff --git a/docs/contracts/inheritance.rst b/docs/contracts/inheritance.rst index 02ab19163ffb..fccfee609587 100644 --- a/docs/contracts/inheritance.rst +++ b/docs/contracts/inheritance.rst @@ -40,27 +40,27 @@ Details are given in the following example. // SPDX-License-Identifier: GPL-3.0 pragma solidity >=0.7.0 <0.9.0; - // This will report a warning due to deprecated selfdestruct contract Owned { - constructor() { owner = payable(msg.sender); } address payable owner; + constructor() { owner = payable(msg.sender); } } - // Use `is` to derive from another contract. Derived // contracts can access all non-private members including // internal functions and state variables. These cannot be // accessed externally via `this`, though. - contract Destructible is Owned { + contract Emittable is Owned { + event Emitted(); + // The keyword `virtual` means that the function can change // its behavior in derived classes ("overriding"). - function destroy() virtual public { - if (msg.sender == owner) selfdestruct(owner); + function emitEvent() virtual public { + if (msg.sender == owner) + emit Emitted(); } } - // These abstract contracts are only provided to make the // interface known to the compiler. Note the function // without body. If a contract does not implement all @@ -69,37 +69,35 @@ Details are given in the following example. function lookup(uint id) public virtual returns (address adr); } - abstract contract NameReg { function register(bytes32 name) public virtual; function unregister() public virtual; } - // Multiple inheritance is possible. Note that `Owned` is - // also a base class of `Destructible`, yet there is only a single + // also a base class of `Emittable`, yet there is only a single // instance of `Owned` (as for virtual inheritance in C++). - contract Named is Owned, Destructible { + contract Named is Owned, Emittable { constructor(bytes32 name) { Config config = Config(0xD5f9D8D94886E70b06E474c3fB14Fd43E2f23970); NameReg(config.lookup(1)).register(name); } // Functions can be overridden by another function with the same name and - // the same number/types of inputs. If the overriding function has different + // the same number/types of inputs. If the overriding function has different // types of output parameters, that causes an error. // Both local and message-based function calls take these overrides // into account. // If you want the function to override, you need to use the // `override` keyword. You need to specify the `virtual` keyword again // if you want this function to be overridden again. - function destroy() public virtual override { + function emitEvent() public virtual override { if (msg.sender == owner) { Config config = Config(0xD5f9D8D94886E70b06E474c3fB14Fd43E2f23970); NameReg(config.lookup(1)).unregister(); // It is still possible to call a specific // overridden function. - Destructible.destroy(); + Emittable.emitEvent(); } } } @@ -108,93 +106,132 @@ Details are given in the following example. // If a constructor takes an argument, it needs to be // provided in the header or modifier-invocation-style at // the constructor of the derived contract (see below). - contract PriceFeed is Owned, Destructible, Named("GoldFeed") { + contract PriceFeed is Owned, Emittable, Named("GoldFeed") { + uint info; + function updateInfo(uint newInfo) public { if (msg.sender == owner) info = newInfo; } // Here, we only specify `override` and not `virtual`. // This means that contracts deriving from `PriceFeed` - // cannot change the behavior of `destroy` anymore. - function destroy() public override(Destructible, Named) { Named.destroy(); } + // cannot change the behavior of `emitEvent` anymore. + function emitEvent() public override(Emittable, Named) { Named.emitEvent(); } function get() public view returns(uint r) { return info; } - - uint info; } -Note that above, we call ``Destructible.destroy()`` to "forward" the -destruction request. The way this is done is problematic, as +Note that above, we call ``Emittable.emitEvent()`` to "forward" the +emit event request. The way this is done is problematic, as seen in the following example: .. code-block:: solidity // SPDX-License-Identifier: GPL-3.0 pragma solidity >=0.7.0 <0.9.0; - // This will report a warning due to deprecated selfdestruct - contract owned { - constructor() { owner = payable(msg.sender); } + contract Owned { address payable owner; + constructor() { owner = payable(msg.sender); } } - contract Destructible is owned { - function destroy() public virtual { - if (msg.sender == owner) selfdestruct(owner); + contract Emittable is Owned { + event Emitted(); + + function emitEvent() virtual public { + if (msg.sender == owner) { + emit Emitted(); + } } } - contract Base1 is Destructible { - function destroy() public virtual override { /* do cleanup 1 */ Destructible.destroy(); } + contract Base1 is Emittable { + event Base1Emitted(); + function emitEvent() public virtual override { + /* Here, we emit an event to simulate some Base1 logic */ + emit Base1Emitted(); + Emittable.emitEvent(); + } } - contract Base2 is Destructible { - function destroy() public virtual override { /* do cleanup 2 */ Destructible.destroy(); } + contract Base2 is Emittable { + event Base2Emitted(); + function emitEvent() public virtual override { + /* Here, we emit an event to simulate some Base2 logic */ + emit Base2Emitted(); + Emittable.emitEvent(); + } } contract Final is Base1, Base2 { - function destroy() public override(Base1, Base2) { Base2.destroy(); } + event FinalEmitted(); + function emitEvent() public override(Base1, Base2) { + /* Here, we emit an event to simulate some Final logic */ + emit FinalEmitted(); + Base2.emitEvent(); + } } -A call to ``Final.destroy()`` will call ``Base2.destroy`` because we specify it +A call to ``Final.emitEvent()`` will call ``Base2.emitEvent`` because we specify it explicitly in the final override, but this function will bypass -``Base1.destroy``. The way around this is to use ``super``: +``Base1.emitEvent``, resulting in the following sequence of events: +``FinalEmitted -> Base2Emitted -> Emitted``, instead of the expected sequence: +``FinalEmitted -> Base2Emitted -> Base1Emitted -> Emitted``. +The way around this is to use ``super``: .. code-block:: solidity // SPDX-License-Identifier: GPL-3.0 pragma solidity >=0.7.0 <0.9.0; - // This will report a warning due to deprecated selfdestruct - contract owned { - constructor() { owner = payable(msg.sender); } + contract Owned { address payable owner; + constructor() { owner = payable(msg.sender); } } - contract Destructible is owned { - function destroy() virtual public { - if (msg.sender == owner) selfdestruct(owner); + contract Emittable is Owned { + event Emitted(); + + function emitEvent() virtual public { + if (msg.sender == owner) { + emit Emitted(); + } } } - contract Base1 is Destructible { - function destroy() public virtual override { /* do cleanup 1 */ super.destroy(); } + contract Base1 is Emittable { + event Base1Emitted(); + function emitEvent() public virtual override { + /* Here, we emit an event to simulate some Base1 logic */ + emit Base1Emitted(); + super.emitEvent(); + } } - contract Base2 is Destructible { - function destroy() public virtual override { /* do cleanup 2 */ super.destroy(); } + contract Base2 is Emittable { + event Base2Emitted(); + function emitEvent() public virtual override { + /* Here, we emit an event to simulate some Base2 logic */ + emit Base2Emitted(); + super.emitEvent(); + } } contract Final is Base1, Base2 { - function destroy() public override(Base1, Base2) { super.destroy(); } + event FinalEmitted(); + function emitEvent() public override(Base1, Base2) { + /* Here, we emit an event to simulate some Final logic */ + emit FinalEmitted(); + super.emitEvent(); + } } -If ``Base2`` calls a function of ``super``, it does not simply +If ``Final`` calls a function of ``super``, it does not simply call this function on one of its base contracts. Rather, it calls this function on the next base contract in the final -inheritance graph, so it will call ``Base1.destroy()`` (note that +inheritance graph, so it will call ``Base1.emitEvent()`` (note that the final inheritance sequence is -- starting with the most -derived contract: Final, Base2, Base1, Destructible, owned). +derived contract: Final, Base2, Base1, Emittable, Owned). The actual function that is called when using super is not known in the context of the class where it is used, although its type is known. This is similar for ordinary diff --git a/docs/examples/micropayment.rst b/docs/examples/micropayment.rst index 50f28005bfd6..c3aef0d653da 100644 --- a/docs/examples/micropayment.rst +++ b/docs/examples/micropayment.rst @@ -55,7 +55,7 @@ as it provides a number of other security benefits. What to Sign ------------ -For a contract that fulfils payments, the signed message must include: +For a contract that fulfills payments, the signed message must include: 1. The recipient's address. 2. The amount to be transferred. @@ -80,6 +80,10 @@ the contract's address itself will be accepted. You can find an example of this in the first two lines of the ``claimPayment()`` function of the full contract at the end of this section. +Furthermore, instead of destroying the contract by calling ``selfdestruct``, +which is currently deprecated, we will disable the contract's functionalities by freezing it, +resulting in the reversion of any call after it being frozen. + Packing arguments ----------------- @@ -144,30 +148,54 @@ The full contract // SPDX-License-Identifier: GPL-3.0 pragma solidity >=0.7.0 <0.9.0; - // This will report a warning due to deprecated selfdestruct - contract ReceiverPays { - address owner = msg.sender; + contract Owned { + address payable owner; + constructor() { + owner = payable(msg.sender); + } + } + + contract Freezable is Owned { + bool private _frozen = false; + + modifier notFrozen() { + require(!_frozen, "Inactive Contract."); + _; + } + + function freeze() internal { + if (msg.sender == owner) + _frozen = true; + } + } + + contract ReceiverPays is Freezable { mapping(uint256 => bool) usedNonces; constructor() payable {} - function claimPayment(uint256 amount, uint256 nonce, bytes memory signature) external { + function claimPayment(uint256 amount, uint256 nonce, bytes memory signature) + external + notFrozen + { require(!usedNonces[nonce]); usedNonces[nonce] = true; // this recreates the message that was signed on the client bytes32 message = prefixed(keccak256(abi.encodePacked(msg.sender, amount, nonce, this))); - require(recoverSigner(message, signature) == owner); - payable(msg.sender).transfer(amount); } - /// destroy the contract and reclaim the leftover funds. - function shutdown() external { + /// freeze the contract and reclaim the leftover funds. + function shutdown() + external + notFrozen + { require(msg.sender == owner); - selfdestruct(payable(msg.sender)); + freeze(); + payable(msg.sender).transfer(address(this).balance); } /// signature methods. @@ -196,7 +224,6 @@ The full contract returns (address) { (uint8 v, bytes32 r, bytes32 s) = splitSignature(sig); - return ecrecover(message, v, r, s); } @@ -305,7 +332,7 @@ Closing the Payment Channel When Bob is ready to receive his funds, it is time to close the payment channel by calling a ``close`` function on the smart contract. Closing the channel pays the recipient the Ether they are owed and -destroys the contract, sending any remaining Ether back to Alice. To +deactivates the contract by freezing it, sending any remaining Ether back to Alice. To close the channel, Bob needs to provide a message signed by Alice. The smart contract must verify that the message contains a valid signature from the sender. @@ -320,7 +347,7 @@ they could provide a message with a lower amount and cheat the recipient out of The function verifies the signed message matches the given parameters. If everything checks out, the recipient is sent their portion of the Ether, -and the sender is sent the rest via a ``selfdestruct``. +and the sender is sent the remaining funds via a ``transfer``. You can see the ``close`` function in the full contract. Channel Expiration @@ -342,11 +369,24 @@ The full contract // SPDX-License-Identifier: GPL-3.0 pragma solidity >=0.7.0 <0.9.0; - // This will report a warning due to deprecated selfdestruct - contract SimplePaymentChannel { - address payable public sender; // The account sending payments. - address payable public recipient; // The account receiving the payments. - uint256 public expiration; // Timeout in case the recipient never closes. + + contract Frozeable { + bool private _frozen = false; + + modifier notFrozen() { + require(!_frozen, "Inactive Contract."); + _; + } + + function freeze() internal { + _frozen = true; + } + } + + contract SimplePaymentChannel is Frozeable { + address payable public sender; // The account sending payments. + address payable public recipient; // The account receiving the payments. + uint256 public expiration; // Timeout in case the recipient never closes. constructor (address payable recipientAddress, uint256 duration) payable @@ -359,16 +399,23 @@ The full contract /// the recipient can close the channel at any time by presenting a /// signed amount from the sender. the recipient will be sent that amount, /// and the remainder will go back to the sender - function close(uint256 amount, bytes memory signature) external { + function close(uint256 amount, bytes memory signature) + external + notFrozen + { require(msg.sender == recipient); require(isValidSignature(amount, signature)); recipient.transfer(amount); - selfdestruct(sender); + freeze(); + sender.transfer(address(this).balance); } /// the sender can extend the expiration at any time - function extend(uint256 newExpiration) external { + function extend(uint256 newExpiration) + external + notFrozen + { require(msg.sender == sender); require(newExpiration > expiration); @@ -377,9 +424,13 @@ The full contract /// if the timeout is reached without the recipient closing the channel, /// then the Ether is released back to the sender. - function claimTimeout() external { + function claimTimeout() + external + notFrozen + { require(block.timestamp >= expiration); - selfdestruct(sender); + freeze(); + sender.transfer(address(this).balance); } function isValidSignature(uint256 amount, bytes memory signature) @@ -388,14 +439,12 @@ The full contract returns (bool) { bytes32 message = prefixed(keccak256(abi.encodePacked(this, amount))); - // check that the signature is from the payment sender return recoverSigner(message, signature) == sender; } /// All functions below this are just taken from the chapter /// 'creating and verifying signatures' chapter. - function splitSignature(bytes memory sig) internal pure @@ -411,7 +460,6 @@ The full contract // final byte (first byte of the next 32 bytes) v := byte(0, mload(add(sig, 96))) } - return (v, r, s); } @@ -421,7 +469,6 @@ The full contract returns (address) { (uint8 v, bytes32 r, bytes32 s) = splitSignature(sig); - return ecrecover(message, v, r, s); } diff --git a/docs/introduction-to-smart-contracts.rst b/docs/introduction-to-smart-contracts.rst index 3c43e5f193b2..a31b06616aee 100644 --- a/docs/introduction-to-smart-contracts.rst +++ b/docs/introduction-to-smart-contracts.rst @@ -563,9 +563,23 @@ idea, but it is potentially dangerous, as if someone sends Ether to removed contracts, the Ether is forever lost. .. warning:: - From version 0.8.18 and up, the use of ``selfdestruct`` in both Solidity and Yul will trigger a - deprecation warning, since the ``SELFDESTRUCT`` opcode will eventually undergo breaking changes in behavior - as stated in `EIP-6049 `_. + From ``EVM >= Cancun`` onwards, ``selfdestruct`` will **only** send all Ether in the account to the given recipient and not destroy the contract. + However, when ``selfdestruct`` is called in the same transaction that creates the contract calling it, + the behaviour of ``selfdestruct`` before Cancun hardfork (i.e., ``EVM <= Shanghai``) is preserved and will destroy the current contract, + deleting any data, including storage keys, code and the account itself. + See `EIP-6780 `_ for more details. + + The new behaviour is the result of a network-wide change that affects all contracts present on + the Ethereum mainnet and testnets. + It is important to note that this change is dependent on the EVM version of the chain on which + the contract is deployed. + The ``--evm-version`` setting used when compiling the contract has no bearing on it. + + Also, note that the ``selfdestruct`` opcode has been deprecated in Solidity version 0.8.18, + as recommended by `EIP-6049 `_. + The deprecation is still in effect and the compiler will still emit warnings on its use. + Any use in newly deployed contracts is strongly discouraged even if the new behavior is taken into account. + Future changes to the EVM might further reduce the functionality of the opcode. .. warning:: Even if a contract is removed by ``selfdestruct``, it is still part of the diff --git a/docs/metadata.rst b/docs/metadata.rst index ede16a73fd8e..a44d9875388a 100644 --- a/docs/metadata.rst +++ b/docs/metadata.rst @@ -175,9 +175,9 @@ explanatory purposes. }, // Required: Compilation source files/source units, keys are file paths "sources": { - "destructible": { + "settable": { // Required (unless "url" is used): literal contents of the source file - "content": "contract destructible is owned { function destroy() { if (msg.sender == owner) selfdestruct(owner); } }", + "content": "contract settable is owned { uint256 private x = 0; function set(uint256 _x) public { if (msg.sender == owner) x = _x; } }", // Required: keccak256 hash of the source file "keccak256": "0x234..." }, diff --git a/docs/style-guide.rst b/docs/style-guide.rst index 427ede5ee3da..0ac890cb3478 100644 --- a/docs/style-guide.rst +++ b/docs/style-guide.rst @@ -662,10 +662,11 @@ Yes: return balanceOf[from]; } - function shutdown() public onlyOwner { - selfdestruct(owner); + function increment(uint x) public onlyOwner pure returns (uint) { + return x + 1; } + No: .. code-block:: solidity @@ -674,8 +675,8 @@ No: return balanceOf[from]; } - function shutdown() onlyOwner public { - selfdestruct(owner); + function increment(uint x) onlyOwner public pure returns (uint) { + return x + 1; } For long function declarations, it is recommended to drop each argument onto diff --git a/docs/units-and-global-variables.rst b/docs/units-and-global-variables.rst index a0422c32dfa9..a743441d564d 100644 --- a/docs/units-and-global-variables.rst +++ b/docs/units-and-global-variables.rst @@ -339,9 +339,23 @@ Contract-related Furthermore, all functions of the current contract are callable directly including the current function. .. warning:: - From version 0.8.18 and up, the use of ``selfdestruct`` in both Solidity and Yul will trigger a - deprecation warning, since the ``SELFDESTRUCT`` opcode will eventually undergo breaking changes in behavior - as stated in `EIP-6049 `_. + From ``EVM >= Cancun`` onwards, ``selfdestruct`` will **only** send all Ether in the account to the given recipient and not destroy the contract. + However, when ``selfdestruct`` is called in the same transaction that creates the contract calling it, + the behaviour of ``selfdestruct`` before Cancun hardfork (i.e., ``EVM <= Shanghai``) is preserved and will destroy the current contract, + deleting any data, including storage keys, code and the account itself. + See `EIP-6780 `_ for more details. + + The new behaviour is the result of a network-wide change that affects all contracts present on + the Ethereum mainnet and testnets. + It is important to note that this change is dependent on the EVM version of the chain on which + the contract is deployed. + The ``--evm-version`` setting used when compiling the contract has no bearing on it. + + Also, note that the ``selfdestruct`` opcode has been deprecated in Solidity version 0.8.18, + as recommended by `EIP-6049 `_. + The deprecation is still in effect and the compiler will still emit warnings on its use. + Any use in newly deployed contracts is strongly discouraged even if the new behavior is taken into account. + Future changes to the EVM might further reduce the functionality of the opcode. .. note:: Prior to version 0.5.0, there was a function called ``suicide`` with the same diff --git a/docs/using-the-compiler.rst b/docs/using-the-compiler.rst index 97abbdba9df6..219c2f42ed0b 100644 --- a/docs/using-the-compiler.rst +++ b/docs/using-the-compiler.rst @@ -236,12 +236,12 @@ Input Description // `--allow-paths `. ] }, - "destructible": + "settable": { // Optional: keccak256 hash of the source file "keccak256": "0x234...", // Required (unless "urls" is used): literal contents of the source file - "content": "contract destructible is owned { function shutdown() { if (msg.sender == owner) selfdestruct(owner); } }" + "content": "contract settable is owned { uint256 private x = 0; function set(uint256 _x) public { if (msg.sender == owner) x = _x; } }" }, "myFile.sol_json.ast": { From a547f615c271dc357e753abb5c95c24b9d3d0e0b Mon Sep 17 00:00:00 2001 From: Nikola Matic Date: Wed, 13 Mar 2024 22:31:14 +0100 Subject: [PATCH 0111/1022] Disable gp2 and zeppelin ext tests --- .circleci/config.yml | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index e437e1d38759..7fe8967b4435 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1910,7 +1910,8 @@ workflows: - t_ext: *job_ems_compile_ext_colony - t_ext: *job_native_compile_ext_gnosis - - t_ext: *job_native_test_ext_zeppelin + # TODO: Re-enable once bumped to use Cancun supported hardhat version + # - t_ext: *job_native_test_ext_zeppelin - t_ext: *job_native_test_ext_ens - t_ext: *job_native_test_ext_yield_liquidator - t_ext: *job_native_test_ext_perpetual_pools @@ -1918,7 +1919,8 @@ workflows: - t_ext: *job_native_test_ext_prb_math - t_ext: *job_native_test_ext_elementfi - t_ext: *job_native_test_ext_brink - - t_ext: *job_native_compile_ext_gp2 + # TODO: Re-enable once bumped to use Cancun supported hardhat version + # - t_ext: *job_native_compile_ext_gp2 - t_ext: *job_native_compile_ext_euler - t_ext: *job_native_compile_ext_pool_together # TODO: Dropping the external tests below since they are based on old forks and @@ -1932,14 +1934,16 @@ workflows: requires: - t_ems_compile_ext_colony - t_native_compile_ext_gnosis - - t_native_test_ext_zeppelin + # TODO: Re-enable once bumped to use Cancun supported hardhat version + # - t_native_test_ext_zeppelin - t_native_test_ext_ens - t_native_test_ext_yield_liquidator - t_native_test_ext_perpetual_pools - t_native_test_ext_uniswap - t_native_test_ext_elementfi - t_native_test_ext_brink - - t_native_compile_ext_gp2 + # TODO: Re-enable once bumped to use Cancun supported hardhat version + # - t_native_compile_ext_gp2 # TODO: Dropping prb-math from the benchmarks since it is not implemented yet # in the new Foundry external testing infrastructure. # - t_native_test_ext_prb_math From fbeef890ea61c1d07b716a90c5e7548cf791fba7 Mon Sep 17 00:00:00 2001 From: r0qs Date: Wed, 13 Mar 2024 02:01:35 +0100 Subject: [PATCH 0112/1022] Set cancun hardfork in hardhat stack traces tests --- .circleci/config.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index 7fe8967b4435..dc4cec201981 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1469,6 +1469,9 @@ jobs: # NOTE: This is expected to work without running `pnpm build` first. cd hardhat/packages/hardhat-core + # TODO: temporarily set hardhat stack traces tests to use cancun hardfork + # Remove this when hardhat switch to cancun by default: https://github.com/NomicFoundation/hardhat/issues/4851 + sed -i 's/hardfork: "shanghai",/hardfork: "cancun",/' test/internal/hardhat-network/stack-traces/execution.ts pnpm test - matrix_notify_failure_unless_pr From a388ccb2c464493ecb62797462df6e9d9e6cf047 Mon Sep 17 00:00:00 2001 From: Matheus Aguiar Date: Mon, 4 Mar 2024 15:25:05 -0300 Subject: [PATCH 0113/1022] Make cancun the default EVM version --- .circleci/soltest_all.sh | 2 +- Changelog.md | 1 + docs/using-the-compiler.rst | 8 +- liblangutil/EVMVersion.h | 2 +- libyul/AsmAnalysis.cpp | 9 +- scripts/error_codes.py | 1 - scripts/externalTests/common.sh | 2 +- scripts/externalTests/runners/base.py | 2 +- scripts/tests.sh | 2 +- .../debug_info_in_yul_snippet_escaping/output | 22 ++--- test/cmdlineTests/metadata/output | 2 +- test/cmdlineTests/name_simplifier/output | 10 +-- .../standard_metadata/output.json | 2 +- .../output.json | 2 +- .../viair_subobject_optimization/output | 82 +++++++------------ .../output | 2 +- .../yul_string_format_ascii/output.json | 6 +- .../yul_string_format_ascii_long/output.json | 6 +- test/libsolidity/StandardCompiler.cpp | 4 +- test/libsolidity/gasTests/abiv2.sol | 6 +- test/libsolidity/gasTests/abiv2_optimised.sol | 4 +- .../abi_encode_calldata_slice.sol | 12 +-- .../abi_encode_calldata_slice.sol | 12 +-- .../abiEncoderV2/abi_encode_v2.sol | 6 +- .../abiEncoderV2/calldata_array.sol | 2 +- .../calldata_overlapped_dynamic_arrays.sol | 6 +- .../abiEncoderV2/storage_array_encoding.sol | 12 +-- .../abi_decode_simple_storage.sol | 6 +- .../copying/bytes_storage_to_storage.sol | 30 +++---- .../copy_byte_array_in_struct_to_storage.sol | 12 +-- .../function_type_array_to_storage.sol | 12 +-- .../copying/storage_memory_nested_bytes.sol | 6 +- .../array/pop/byte_array_pop_masking_long.sol | 6 +- .../byte_array_to_storage_cleanup.sol | 12 +-- .../bytes_in_constructors_packer.sol | 12 +-- .../bytes_in_constructors_unpacker.sol | 12 +-- .../externalContracts/FixedFeeRegistrar.sol | 12 +-- .../externalContracts/base64.sol | 12 +-- .../externalContracts/deposit_contract.sol | 36 ++++---- .../externalContracts/strings.sol | 12 +-- .../external_call_to_nonexisting.sol | 12 +-- ...ernal_call_to_nonexisting_debugstrings.sol | 12 +-- .../inlineAssembly/blobhash_pre_cancun.sol | 2 +- .../transient_storage_low_level_calls.sol | 6 ++ .../transient_storage_selfdestruct.sol | 10 +++ .../tstore_hidden_staticcall.sol | 3 + .../salted_create/prediction_example.sol | 2 +- .../structs/copy_from_mapping.sol | 6 +- .../copy_substructures_from_mapping.sol | 6 +- .../structs/copy_substructures_to_mapping.sol | 18 ++-- .../semanticTests/structs/copy_to_mapping.sol | 24 +++--- .../semanticTests/various/address_code.sol | 12 +-- .../semanticTests/various/create_calldata.sol | 12 +-- .../various/selfdestruct_post_cancun.sol | 9 +- ...uct_post_cancun_multiple_beneficiaries.sol | 14 ++++ .../selfdestruct_post_cancun_redeploy.sol | 20 +++-- .../skip_dynamic_types_for_structs.sol | 6 +- .../blobhash_pre_cancun_not_declared.sol | 4 +- .../inlineAssembly/mcopy_pre_cancun.sol | 4 +- .../transient_storage_invalid_pre_cancun.sol | 6 +- .../types/magic_block_blobbasefee_error.sol | 2 +- 61 files changed, 298 insertions(+), 299 deletions(-) diff --git a/.circleci/soltest_all.sh b/.circleci/soltest_all.sh index 40ee75b270cd..009852710e51 100755 --- a/.circleci/soltest_all.sh +++ b/.circleci/soltest_all.sh @@ -36,7 +36,7 @@ DEFAULT_EVM_VALUES=(constantinople petersburg istanbul berlin london paris shang # set EVM_VALUES to the default values. IFS=" " read -ra EVM_VALUES <<< "${1:-${DEFAULT_EVM_VALUES[@]}}" -DEFAULT_EVM=shanghai +DEFAULT_EVM=cancun OPTIMIZE_VALUES=(0 1) # Run for ABI encoder v1, without SMTChecker tests. diff --git a/Changelog.md b/Changelog.md index 8c6df568e9ce..ba5dff678755 100644 --- a/Changelog.md +++ b/Changelog.md @@ -6,6 +6,7 @@ Language Features: Compiler Features: * Code Generator: Use ``MCOPY`` instead of ``MLOAD``/``MSTORE`` loop when copying byte arrays. * Yul Analyzer: Emit transient storage warning only for the first occurrence of ``tstore``. + * EVM: Set default EVM version to ``cancun``. Bugfixes: diff --git a/docs/using-the-compiler.rst b/docs/using-the-compiler.rst index 219c2f42ed0b..875c15b09d6d 100644 --- a/docs/using-the-compiler.rst +++ b/docs/using-the-compiler.rst @@ -174,9 +174,9 @@ at each version. Backward compatibility is not guaranteed between each version. - The block's base fee (`EIP-3198 `_ and `EIP-1559 `_) can be accessed via the global ``block.basefee`` or ``basefee()`` in inline assembly. - ``paris`` - Introduces ``prevrandao()`` and ``block.prevrandao``, and changes the semantics of the now deprecated ``block.difficulty``, disallowing ``difficulty()`` in inline assembly (see `EIP-4399 `_). -- ``shanghai`` (**default**) +- ``shanghai`` - Smaller code size and gas savings due to the introduction of ``push0`` (see `EIP-3855 `_). -- ``cancun`` +- ``cancun`` (**default**) - The block's blob base fee (`EIP-7516 `_ and `EIP-4844 `_) can be accessed via the global ``block.blobbasefee`` or ``blobbasefee()`` in inline assembly. - Introduces ``blobhash()`` in inline assembly and a corresponding global function to retrieve versioned hashes of blobs associated with the transaction (see `EIP-4844 `_). - Opcode ``mcopy`` is available in assembly (see `EIP-5656 `_). @@ -344,8 +344,8 @@ Input Description // Version of the EVM to compile for. // Affects type checking and code generation. Can be homestead, // tangerineWhistle, spuriousDragon, byzantium, constantinople, - // petersburg, istanbul, berlin, london, paris or shanghai (default) - "evmVersion": "shanghai", + // petersburg, istanbul, berlin, london, paris, shanghai or cancun (default) + "evmVersion": "cancun", // Optional: Change compilation pipeline to go through the Yul intermediate representation. // This is false by default. "viaIR": true, diff --git a/liblangutil/EVMVersion.h b/liblangutil/EVMVersion.h index 992933a898bf..58b54f3dcaa7 100644 --- a/liblangutil/EVMVersion.h +++ b/liblangutil/EVMVersion.h @@ -119,7 +119,7 @@ class EVMVersion: EVMVersion(Version _version): m_version(_version) {} - Version m_version = Version::Shanghai; + Version m_version = Version::Cancun; }; } diff --git a/libyul/AsmAnalysis.cpp b/libyul/AsmAnalysis.cpp index 0efaa12c2c8a..1972d2674516 100644 --- a/libyul/AsmAnalysis.cpp +++ b/libyul/AsmAnalysis.cpp @@ -752,14 +752,11 @@ bool AsmAnalyzer::validateInstructions(evmasm::Instruction _instr, SourceLocatio else if (_instr == evmasm::Instruction::BLOBBASEFEE && !m_evmVersion.hasBlobBaseFee()) errorForVM(6679_error, "only available for Cancun-compatible"); else if (_instr == evmasm::Instruction::BLOBHASH && !m_evmVersion.hasBlobHash()) - // TODO: Change this assertion to an error, similar to the ones above, when Cancun becomes the default EVM version. - yulAssert(false); + errorForVM(8314_error, "only available for Cancun-compatible"); else if (_instr == evmasm::Instruction::MCOPY && !m_evmVersion.hasMcopy()) - // TODO: Change this assertion to an error, similar to the ones above, when Cancun becomes the default EVM version. - yulAssert(false); + errorForVM(7755_error, "only available for Cancun-compatible"); else if ((_instr == evmasm::Instruction::TSTORE || _instr == evmasm::Instruction::TLOAD) && !m_evmVersion.supportsTransientStorage()) - // TODO: Change this assertion to an error, similar to the ones above, when Cancun becomes the default EVM version. - yulAssert(false); + errorForVM(6243_error, "only available for Cancun-compatible"); else if (_instr == evmasm::Instruction::PC) m_errorReporter.error( 2450_error, diff --git a/scripts/error_codes.py b/scripts/error_codes.py index 8ffb7f2160f4..27e7b1102bbe 100755 --- a/scripts/error_codes.py +++ b/scripts/error_codes.py @@ -202,7 +202,6 @@ def examine_id_coverage(top_dir, source_id_to_file_names, new_ids_only=False): "4591", # "There are more than 256 warnings. Ignoring the rest." # Due to 3805, the warning lists look different for different compiler builds. "1834", # Unimplemented feature error, as we do not test it anymore via cmdLineTests - "6679", # blobbasefee being used in inline assembly for EVMVersion < cancun "1180", # SMTChecker, covered by CL tests "2339", # SMTChecker, covered by CL tests "2961", # SMTChecker, covered by CL tests diff --git a/scripts/externalTests/common.sh b/scripts/externalTests/common.sh index de9b8da96d8c..8bc9bdf7bd40 100644 --- a/scripts/externalTests/common.sh +++ b/scripts/externalTests/common.sh @@ -22,7 +22,7 @@ set -e # Requires $REPO_ROOT to be defined and "${REPO_ROOT}/scripts/common.sh" to be included before. -CURRENT_EVM_VERSION=shanghai +CURRENT_EVM_VERSION=cancun AVAILABLE_PRESETS=( legacy-no-optimize diff --git a/scripts/externalTests/runners/base.py b/scripts/externalTests/runners/base.py index c3807c528c38..cd94fab6b80b 100644 --- a/scripts/externalTests/runners/base.py +++ b/scripts/externalTests/runners/base.py @@ -41,7 +41,7 @@ from test_helpers import settings_from_preset from test_helpers import SettingsPreset -CURRENT_EVM_VERSION: str = "shanghai" +CURRENT_EVM_VERSION: str = "cancun" @dataclass class TestConfig: diff --git a/scripts/tests.sh b/scripts/tests.sh index 9df40e385c1a..26eaf4b4b15b 100755 --- a/scripts/tests.sh +++ b/scripts/tests.sh @@ -115,7 +115,7 @@ do for vm in $EVM_VERSIONS do FORCE_ABIV1_RUNS="no" - if [[ "$vm" == "shanghai" ]] + if [[ "$vm" == "cancun" ]] then FORCE_ABIV1_RUNS="no yes" # run both in paris fi diff --git a/test/cmdlineTests/debug_info_in_yul_snippet_escaping/output b/test/cmdlineTests/debug_info_in_yul_snippet_escaping/output index 4c90d9054d2a..0bd6285b785e 100644 --- a/test/cmdlineTests/debug_info_in_yul_snippet_escaping/output +++ b/test/cmdlineTests/debug_info_in_yul_snippet_escaping/output @@ -181,11 +181,7 @@ object "D_27" { function copy_memory_to_memory_with_cleanup(src, dst, length) { - let i := 0 - for { } lt(i, length) { i := add(i, 32) } - { - mstore(add(dst, i), mload(add(src, i))) - } + mcopy(dst, src, length) mstore(add(dst, length), 0) } @@ -470,8 +466,7 @@ object "D_27" { } mstore(_2, newFreePtr) mstore(memPtr, 2) - let _6 := 32 - mstore(add(memPtr, _6), "/*") + mstore(add(memPtr, 32), "/*") let memPtr_1 := mload(_2) let newFreePtr_1 := add(memPtr_1, 96) if or(gt(newFreePtr_1, /** @src 0:446:491 "new /// @src 0:149:156 \"new C()\"..." */ _5), /** @src 0:279:599 "contract D /** @src 0:96:165 \"contract D {...\" *\/ {..." */ lt(newFreePtr_1, memPtr_1)) @@ -482,17 +477,14 @@ object "D_27" { } mstore(_2, newFreePtr_1) mstore(memPtr_1, 39) - mstore(add(memPtr_1, _6), 0x2f2a2a204073726320303a39363a313635202022636f6e74726163742044207b) + let _6 := add(memPtr_1, 32) + mstore(_6, 0x2f2a2a204073726320303a39363a313635202022636f6e74726163742044207b) mstore(add(memPtr_1, _2), shl(200, 0x2e2e2e22202a2f)) let memPos := mload(_2) - mstore(memPos, _6) + mstore(memPos, 32) let length := mload(memPtr_1) - mstore(add(memPos, _6), length) - let i := 0 - for { } lt(i, length) { i := add(i, _6) } - { - mstore(add(add(memPos, i), _2), mload(add(add(memPtr_1, i), _6))) - } + mstore(add(memPos, 32), length) + mcopy(add(memPos, _2), _6, length) mstore(add(add(memPos, length), _2), 0) return(memPos, add(sub(add(memPos, and(add(length, 31), not(31))), memPos), _2)) } diff --git a/test/cmdlineTests/metadata/output b/test/cmdlineTests/metadata/output index bf1e750c95f0..b6a684b844f3 100644 --- a/test/cmdlineTests/metadata/output +++ b/test/cmdlineTests/metadata/output @@ -1,4 +1,4 @@ ======= metadata/input.sol:C ======= Metadata: -{"compiler":{"version": ""},"language":"Solidity","output":{"abi":[],"devdoc":{"kind":"dev","methods":{},"version":1},"userdoc":{"kind":"user","methods":{},"version":1}},"settings":{"compilationTarget":{"metadata/input.sol":"C"},"evmVersion":"shanghai","libraries":{},"metadata":{"bytecodeHash":"ipfs"},"optimizer":{"enabled":false,"runs":200},"remappings":[]},"sources":{"metadata/input.sol":{"keccak256":"0x5cf617b1707a484e3c4bd59643013dec76ab7d75900b46855214729ae3e0ceb0","license":"GPL-3.0","urls":["bzz-raw://ac418a02dfadf87234150d3568f33269e3f49460345cb39300e017a6d755eff2","dweb:/ipfs/QmQq3owBu25x2WV46HB1WyKzJpxiAPecU7eMKqtXCF7eeS"]}},"version":1} +{"compiler":{"version": ""},"language":"Solidity","output":{"abi":[],"devdoc":{"kind":"dev","methods":{},"version":1},"userdoc":{"kind":"user","methods":{},"version":1}},"settings":{"compilationTarget":{"metadata/input.sol":"C"},"evmVersion":"cancun","libraries":{},"metadata":{"bytecodeHash":"ipfs"},"optimizer":{"enabled":false,"runs":200},"remappings":[]},"sources":{"metadata/input.sol":{"keccak256":"0x5cf617b1707a484e3c4bd59643013dec76ab7d75900b46855214729ae3e0ceb0","license":"GPL-3.0","urls":["bzz-raw://ac418a02dfadf87234150d3568f33269e3f49460345cb39300e017a6d755eff2","dweb:/ipfs/QmQq3owBu25x2WV46HB1WyKzJpxiAPecU7eMKqtXCF7eeS"]}},"version":1} diff --git a/test/cmdlineTests/name_simplifier/output b/test/cmdlineTests/name_simplifier/output index ed4c6e5c02e9..0a461e3e4af4 100644 --- a/test/cmdlineTests/name_simplifier/output +++ b/test/cmdlineTests/name_simplifier/output @@ -98,9 +98,9 @@ object "C_59" { } mstore(_9, newFreePtr_2) mstore(memPtr_1, 100) - mstore(add(memPtr_1, _3), "longstringlongstringlongstringlo") + let _11 := add(memPtr_1, _3) + mstore(_11, "longstringlongstringlongstringlo") mstore(add(memPtr_1, _9), "ngstringlongstringlongstringlong") - let _11 := 96 mstore(add(memPtr_1, 96), "stringlongstringlongstringlongst") mstore(add(memPtr_1, 128), "ring") let memPos := mload(_9) @@ -108,11 +108,7 @@ object "C_59" { mstore(add(memPos, _3), _9) let length := mload(memPtr_1) mstore(add(memPos, _9), length) - let i := 0 - for { } lt(i, length) { i := add(i, _3) } - { - mstore(add(add(memPos, i), _11), mload(add(add(memPtr_1, i), _3))) - } + mcopy(add(memPos, 96), _11, length) mstore(add(add(memPos, length), 96), 0) return(memPos, add(sub(add(memPos, and(add(length, 31), _8)), memPos), 96)) } diff --git a/test/cmdlineTests/standard_metadata/output.json b/test/cmdlineTests/standard_metadata/output.json index 4429466676d1..955d30c34475 100644 --- a/test/cmdlineTests/standard_metadata/output.json +++ b/test/cmdlineTests/standard_metadata/output.json @@ -5,7 +5,7 @@ { "C": { - "metadata": "{\"compiler\":{\"version\":\"\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"C\":\"C\"},\"evmVersion\":\"shanghai\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"C\":{\"keccak256\":\"0x5cf617b1707a484e3c4bd59643013dec76ab7d75900b46855214729ae3e0ceb0\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://ac418a02dfadf87234150d3568f33269e3f49460345cb39300e017a6d755eff2\",\"dweb:/ipfs/QmQq3owBu25x2WV46HB1WyKzJpxiAPecU7eMKqtXCF7eeS\"]}},\"version\":1}" + "metadata": "{\"compiler\":{\"version\":\"\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"C\":\"C\"},\"evmVersion\":\"cancun\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"C\":{\"keccak256\":\"0x5cf617b1707a484e3c4bd59643013dec76ab7d75900b46855214729ae3e0ceb0\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://ac418a02dfadf87234150d3568f33269e3f49460345cb39300e017a6d755eff2\",\"dweb:/ipfs/QmQq3owBu25x2WV46HB1WyKzJpxiAPecU7eMKqtXCF7eeS\"]}},\"version\":1}" } } }, diff --git a/test/cmdlineTests/standard_outputs_on_compilation_error/output.json b/test/cmdlineTests/standard_outputs_on_compilation_error/output.json index ac01fb1eba9c..aae6d02f6b41 100644 --- a/test/cmdlineTests/standard_outputs_on_compilation_error/output.json +++ b/test/cmdlineTests/standard_outputs_on_compilation_error/output.json @@ -40,7 +40,7 @@ "x()": "0c55699c" } }, - "metadata": "{\"compiler\":{\"version\":\"\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"x\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"C\":\"C\"},\"evmVersion\":\"shanghai\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"C\":{\"keccak256\":\"0x67a13ebd685e4c6f792e71eb747dac57edb99e94d04d841ee6c979ae517934ce\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://665b000da768823654f680d02686c1e59d682a0b3882e43a77fed9f80ce64ae8\",\"dweb:/ipfs/QmVnKvuidH6KiCdNQpoAQUtDbB8hXkafVLXWMNitUcxnqC\"]}},\"version\":1}", + "metadata": "{\"compiler\":{\"version\":\"\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"x\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"C\":\"C\"},\"evmVersion\":\"cancun\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"C\":{\"keccak256\":\"0x67a13ebd685e4c6f792e71eb747dac57edb99e94d04d841ee6c979ae517934ce\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://665b000da768823654f680d02686c1e59d682a0b3882e43a77fed9f80ce64ae8\",\"dweb:/ipfs/QmVnKvuidH6KiCdNQpoAQUtDbB8hXkafVLXWMNitUcxnqC\"]}},\"version\":1}", "storageLayout": { "storage": [], diff --git a/test/cmdlineTests/viair_subobject_optimization/output b/test/cmdlineTests/viair_subobject_optimization/output index 4804d138434c..5090c282bb24 100644 --- a/test/cmdlineTests/viair_subobject_optimization/output +++ b/test/cmdlineTests/viair_subobject_optimization/output @@ -117,77 +117,70 @@ sub_0: assembly { tag_3: jumpi(tag_7, callvalue) jumpi(tag_7, slt(add(not(0x03), calldatasize), 0x00)) - not(0x1f) /* "viair_subobject_optimization/input.sol":745:765 type(C).creationCode */ dataSize(sub_0) /* "viair_subobject_optimization/input.sol":669:772 contract D {... */ - 0x3f + swap1 + not(0x1f) + swap1 dup2 + 0x3f + dup5 add - dup3 and - dup4 + dup2 add - swap1 + swap2 + dup2 dup4 - dup3 lt 0xffffffffffffffff - dup4 + dup5 gt or tag_9 jumpi - swap3 - swap1 - 0x40 - swap1 0x40 + swap3 + dup4 mstore /* "viair_subobject_optimization/input.sol":745:765 type(C).creationCode */ dup4 dup3 mstore 0x20 + dup3 + add swap4 dataOffset(sub_0) - 0x20 - dup5 - add + dup6 codecopy /* "viair_subobject_optimization/input.sol":669:772 contract D {... */ - mload(0x40) + 0x1f + dup4 + mload + swap5 + dup6 swap4 - dup5 - swap3 /* "viair_subobject_optimization/input.sol":745:765 type(C).creationCode */ 0x20 /* "viair_subobject_optimization/input.sol":669:772 contract D {... */ - dup5 + dup6 mstore - dup1 mload - swap3 - dup4 + dup1 + swap2 + dup2 /* "viair_subobject_optimization/input.sol":745:765 type(C).creationCode */ 0x20 /* "viair_subobject_optimization/input.sol":669:772 contract D {... */ - dup7 + dup8 add mstore - 0x00 - tag_11: - dup5 - dup2 - lt - tag_12 - jumpi - dup6 - 0x40 - dup2 - dup10 - 0x1f - dup10 + dup7 + dup7 + add + mcopy 0x00 dup6 dup3 @@ -203,25 +196,6 @@ sub_0: assembly { add swap1 return - tag_12: - dup3 - dup2 - add - dup5 - add - mload - dup9 - dup3 - add - dup4 - add - mstore - dup8 - swap6 - pop - dup4 - add - jump(tag_11) tag_9: mstore(0x00, shl(0xe0, 0x4e487b71)) mstore(0x04, 0x41) diff --git a/test/cmdlineTests/yul_optimizer_steps_without_optimize_empty_sequence/output b/test/cmdlineTests/yul_optimizer_steps_without_optimize_empty_sequence/output index 9ee68107929a..6873abe60e47 100644 --- a/test/cmdlineTests/yul_optimizer_steps_without_optimize_empty_sequence/output +++ b/test/cmdlineTests/yul_optimizer_steps_without_optimize_empty_sequence/output @@ -130,4 +130,4 @@ object "C_28" { } Metadata: -{"compiler":{"version": ""},"language":"Solidity","output":{"abi":[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"foo","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"}],"devdoc":{"kind":"dev","methods":{},"version":1},"userdoc":{"kind":"user","methods":{},"version":1}},"settings":{"compilationTarget":{"yul_optimizer_steps_without_optimize_empty_sequence/input.sol":"C"},"evmVersion":"shanghai","libraries":{},"metadata":{"bytecodeHash":"ipfs"},"optimizer":{"details":{"constantOptimizer":false,"cse":false,"deduplicate":false,"inliner":false,"jumpdestRemover":true,"orderLiterals":false,"peephole":true,"simpleCounterForLoopUncheckedIncrement":true,"yul":false,"yulDetails":{"optimizerSteps":":"}},"runs":200},"remappings":[]},"sources":{"yul_optimizer_steps_without_optimize_empty_sequence/input.sol":{"keccak256":"0x3fc910e345ce1ee62bfa6b0f66931ee632c08265b25b6139cfbbfe4d2f8d5dd8","license":"GPL-3.0","urls":["bzz-raw://e557e9ad2c2e420a669c06ae456b0b790d77d2d6d492cd8540e6b244388a5140","dweb:/ipfs/QmaNiZmC2Mo3YxGiehs1n3dVTjZwD7FguX7EUtpeshMVuR"]}},"version":1} +{"compiler":{"version": ""},"language":"Solidity","output":{"abi":[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"foo","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"}],"devdoc":{"kind":"dev","methods":{},"version":1},"userdoc":{"kind":"user","methods":{},"version":1}},"settings":{"compilationTarget":{"yul_optimizer_steps_without_optimize_empty_sequence/input.sol":"C"},"evmVersion":"cancun","libraries":{},"metadata":{"bytecodeHash":"ipfs"},"optimizer":{"details":{"constantOptimizer":false,"cse":false,"deduplicate":false,"inliner":false,"jumpdestRemover":true,"orderLiterals":false,"peephole":true,"simpleCounterForLoopUncheckedIncrement":true,"yul":false,"yulDetails":{"optimizerSteps":":"}},"runs":200},"remappings":[]},"sources":{"yul_optimizer_steps_without_optimize_empty_sequence/input.sol":{"keccak256":"0x3fc910e345ce1ee62bfa6b0f66931ee632c08265b25b6139cfbbfe4d2f8d5dd8","license":"GPL-3.0","urls":["bzz-raw://e557e9ad2c2e420a669c06ae456b0b790d77d2d6d492cd8540e6b244388a5140","dweb:/ipfs/QmaNiZmC2Mo3YxGiehs1n3dVTjZwD7FguX7EUtpeshMVuR"]}},"version":1} diff --git a/test/cmdlineTests/yul_string_format_ascii/output.json b/test/cmdlineTests/yul_string_format_ascii/output.json index 1a9612c777b8..edb76c0cd405 100644 --- a/test/cmdlineTests/yul_string_format_ascii/output.json +++ b/test/cmdlineTests/yul_string_format_ascii/output.json @@ -97,11 +97,7 @@ object \"C_11\" { function copy_memory_to_memory_with_cleanup(src, dst, length) { - let i := 0 - for { } lt(i, length) { i := add(i, 32) } - { - mstore(add(dst, i), mload(add(src, i))) - } + mcopy(dst, src, length) mstore(add(dst, length), 0) } diff --git a/test/cmdlineTests/yul_string_format_ascii_long/output.json b/test/cmdlineTests/yul_string_format_ascii_long/output.json index 5adeabfdffcf..36d6cfd954e9 100644 --- a/test/cmdlineTests/yul_string_format_ascii_long/output.json +++ b/test/cmdlineTests/yul_string_format_ascii_long/output.json @@ -97,11 +97,7 @@ object \"C_11\" { function copy_memory_to_memory_with_cleanup(src, dst, length) { - let i := 0 - for { } lt(i, length) { i := add(i, 32) } - { - mstore(add(dst, i), mload(add(src, i))) - } + mcopy(dst, src, length) mstore(add(dst, length), 0) } diff --git a/test/libsolidity/StandardCompiler.cpp b/test/libsolidity/StandardCompiler.cpp index ab013692d5ea..7fafa2a62e08 100644 --- a/test/libsolidity/StandardCompiler.cpp +++ b/test/libsolidity/StandardCompiler.cpp @@ -1050,9 +1050,11 @@ BOOST_AUTO_TEST_CASE(evm_version) BOOST_CHECK(result["contracts"]["fileA"]["A"]["metadata"].asString().find("\"evmVersion\":\"paris\"") != std::string::npos); result = compile(inputForVersion("\"evmVersion\": \"shanghai\",")); BOOST_CHECK(result["contracts"]["fileA"]["A"]["metadata"].asString().find("\"evmVersion\":\"shanghai\"") != std::string::npos); + result = compile(inputForVersion("\"evmVersion\": \"cancun\",")); + BOOST_CHECK(result["contracts"]["fileA"]["A"]["metadata"].asString().find("\"evmVersion\":\"cancun\"") != std::string::npos); // test default result = compile(inputForVersion("")); - BOOST_CHECK(result["contracts"]["fileA"]["A"]["metadata"].asString().find("\"evmVersion\":\"shanghai\"") != std::string::npos); + BOOST_CHECK(result["contracts"]["fileA"]["A"]["metadata"].asString().find("\"evmVersion\":\"cancun\"") != std::string::npos); // test invalid result = compile(inputForVersion("\"evmVersion\": \"invalid\",")); BOOST_CHECK(result["errors"][0]["message"].asString() == "Invalid EVM version requested."); diff --git a/test/libsolidity/gasTests/abiv2.sol b/test/libsolidity/gasTests/abiv2.sol index aacb333bfeca..6fa822fade47 100644 --- a/test/libsolidity/gasTests/abiv2.sol +++ b/test/libsolidity/gasTests/abiv2.sol @@ -14,9 +14,9 @@ contract C { } // ---- // creation: -// codeDepositCost: 1213200 -// executionCost: 1259 -// totalCost: 1214459 +// codeDepositCost: 1208000 +// executionCost: 1252 +// totalCost: 1209252 // external: // a(): 2425 // b(uint256): infinite diff --git a/test/libsolidity/gasTests/abiv2_optimised.sol b/test/libsolidity/gasTests/abiv2_optimised.sol index 1ab8803d28b2..8f407e6ede24 100644 --- a/test/libsolidity/gasTests/abiv2_optimised.sol +++ b/test/libsolidity/gasTests/abiv2_optimised.sol @@ -17,9 +17,9 @@ contract C { // optimize-yul: true // ---- // creation: -// codeDepositCost: 639000 +// codeDepositCost: 634600 // executionCost: 668 -// totalCost: 639668 +// totalCost: 635268 // external: // a(): 2283 // b(uint256): 4649 diff --git a/test/libsolidity/semanticTests/abiEncoderV1/abi_encode_calldata_slice.sol b/test/libsolidity/semanticTests/abiEncoderV1/abi_encode_calldata_slice.sol index f548c50bcf52..3dd5dd269340 100644 --- a/test/libsolidity/semanticTests/abiEncoderV1/abi_encode_calldata_slice.sol +++ b/test/libsolidity/semanticTests/abiEncoderV1/abi_encode_calldata_slice.sol @@ -59,10 +59,10 @@ contract C { // EVMVersion: >homestead // ---- // test_bytes() -> -// gas irOptimized: 321332 -// gas legacy: 319111 -// gas legacyOptimized: 269317 +// gas irOptimized: 306908 +// gas legacy: 305827 +// gas legacyOptimized: 255013 // test_uint256() -> -// gas irOptimized: 447646 -// gas legacy: 433627 -// gas legacyOptimized: 365410 +// gas irOptimized: 435054 +// gas legacy: 421315 +// gas legacyOptimized: 352838 diff --git a/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_calldata_slice.sol b/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_calldata_slice.sol index 686164de856a..5457e7f6743e 100644 --- a/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_calldata_slice.sol +++ b/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_calldata_slice.sol @@ -60,10 +60,10 @@ contract C { // EVMVersion: >homestead // ---- // test_bytes() -> -// gas irOptimized: 321332 -// gas legacy: 319111 -// gas legacyOptimized: 269317 +// gas irOptimized: 306908 +// gas legacy: 305827 +// gas legacyOptimized: 255013 // test_uint256() -> -// gas irOptimized: 447646 -// gas legacy: 433627 -// gas legacyOptimized: 365410 +// gas irOptimized: 435054 +// gas legacy: 421315 +// gas legacyOptimized: 352838 diff --git a/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_v2.sol b/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_v2.sol index 5e50d5e9a807..c0d5f5d3fb9c 100644 --- a/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_v2.sol +++ b/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_v2.sol @@ -50,6 +50,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: 112630 -// gas legacy: 114794 -// gas legacyOptimized: 112572 +// gas irOptimized: 111708 +// gas legacy: 113892 +// gas legacyOptimized: 111646 diff --git a/test/libsolidity/semanticTests/abiEncoderV2/calldata_array.sol b/test/libsolidity/semanticTests/abiEncoderV2/calldata_array.sol index 22aad67492e8..f749e403b567 100644 --- a/test/libsolidity/semanticTests/abiEncoderV2/calldata_array.sol +++ b/test/libsolidity/semanticTests/abiEncoderV2/calldata_array.sol @@ -20,6 +20,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: 120043 +// gas irOptimized: 117157 // gas legacy: 101568 // gas legacyOptimized: 119092 diff --git a/test/libsolidity/semanticTests/abiEncoderV2/calldata_overlapped_dynamic_arrays.sol b/test/libsolidity/semanticTests/abiEncoderV2/calldata_overlapped_dynamic_arrays.sol index a92336097172..46df313331e4 100644 --- a/test/libsolidity/semanticTests/abiEncoderV2/calldata_overlapped_dynamic_arrays.sol +++ b/test/libsolidity/semanticTests/abiEncoderV2/calldata_overlapped_dynamic_arrays.sol @@ -33,8 +33,8 @@ contract C { // f_which(uint256[],uint256[2],uint256): 0x40, 1, 2, 1, 5, 6 -> 0x20, 0x40, 5, 2 // f_which(uint256[],uint256[2],uint256): 0x40, 1, 2, 1 -> FAILURE // f_storage(uint256[],uint256[2]): 0x20, 1, 2 -> 0x20, 0x60, 0x20, 1, 2 -// gas irOptimized: 111642 -// gas legacy: 112944 -// gas legacyOptimized: 112092 +// gas irOptimized: 111395 +// gas legacy: 112709 +// gas legacyOptimized: 111852 // f_storage(uint256[],uint256[2]): 0x40, 1, 2, 5, 6 -> 0x20, 0x80, 0x20, 2, 5, 6 // f_storage(uint256[],uint256[2]): 0x40, 1, 2, 5 -> FAILURE diff --git a/test/libsolidity/semanticTests/abiEncoderV2/storage_array_encoding.sol b/test/libsolidity/semanticTests/abiEncoderV2/storage_array_encoding.sol index 33075675358e..14699df57219 100644 --- a/test/libsolidity/semanticTests/abiEncoderV2/storage_array_encoding.sol +++ b/test/libsolidity/semanticTests/abiEncoderV2/storage_array_encoding.sol @@ -18,10 +18,10 @@ contract C { // EVMVersion: >homestead // ---- // h(uint256[2][]): 0x20, 3, 123, 124, 223, 224, 323, 324 -> 32, 256, 0x20, 3, 123, 124, 223, 224, 323, 324 -// gas irOptimized: 180720 -// gas legacy: 184830 -// gas legacyOptimized: 181493 +// gas irOptimized: 180103 +// gas legacy: 184235 +// gas legacyOptimized: 180873 // i(uint256[2][2]): 123, 124, 223, 224 -> 32, 128, 123, 124, 223, 224 -// gas irOptimized: 112425 -// gas legacy: 115398 -// gas legacyOptimized: 112982 +// gas irOptimized: 112104 +// gas legacy: 115091 +// gas legacyOptimized: 112666 diff --git a/test/libsolidity/semanticTests/abiencodedecode/abi_decode_simple_storage.sol b/test/libsolidity/semanticTests/abiencodedecode/abi_decode_simple_storage.sol index c06d2b24c457..9f59c43155ee 100644 --- a/test/libsolidity/semanticTests/abiencodedecode/abi_decode_simple_storage.sol +++ b/test/libsolidity/semanticTests/abiencodedecode/abi_decode_simple_storage.sol @@ -8,6 +8,6 @@ contract C { } // ---- // f(bytes): 0x20, 0x80, 0x21, 0x40, 0x7, "abcdefg" -> 0x21, 0x40, 0x7, "abcdefg" -// gas irOptimized: 135661 -// gas legacy: 137278 -// gas legacyOptimized: 136048 +// gas irOptimized: 135452 +// gas legacy: 137096 +// gas legacyOptimized: 135834 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 38dbe52bccde..24565b4c62a6 100644 --- a/test/libsolidity/semanticTests/array/copying/bytes_storage_to_storage.sol +++ b/test/libsolidity/semanticTests/array/copying/bytes_storage_to_storage.sol @@ -17,25 +17,25 @@ contract c { // ---- // f(uint256): 0 -> 0x20, 0x00 // f(uint256): 31 -> 0x20, 0x1f, 0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e00 -// gas irOptimized: 104476 -// gas legacy: 112974 -// gas legacyOptimized: 112717 +// gas irOptimized: 103283 +// gas legacy: 112883 +// gas legacyOptimized: 112629 // f(uint256): 32 -> 0x20, 0x20, 1780731860627700044960722568376592200742329637303199754547598369979440671 -// gas irOptimized: 118962 -// gas legacy: 129034 -// gas legacyOptimized: 128952 +// gas irOptimized: 117740 +// gas legacy: 128943 +// gas legacyOptimized: 128864 // f(uint256): 33 -> 0x20, 33, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x2000000000000000000000000000000000000000000000000000000000000000 -// gas irOptimized: 125419 -// gas legacy: 136234 -// gas legacyOptimized: 135643 +// gas irOptimized: 124080 +// gas legacy: 136071 +// gas legacyOptimized: 135479 // f(uint256): 63 -> 0x20, 0x3f, 1780731860627700044960722568376592200742329637303199754547598369979440671, 14532552714582660066924456880521368950258152170031413196862950297402215316992 -// gas irOptimized: 129529 -// gas legacy: 148834 -// gas legacyOptimized: 148873 +// gas irOptimized: 127140 +// gas legacy: 148671 +// gas legacyOptimized: 148709 // f(uint256): 12 -> 0x20, 0x0c, 0x0102030405060708090a0b0000000000000000000000000000000000000000 // gas legacy: 59345 // gas legacyOptimized: 57279 // f(uint256): 129 -> 0x20, 0x81, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f, 29063324697304692433803953038474361308315562010425523193971352996434451193439, 0x606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f, -57896044618658097711785492504343953926634992332820282019728792003956564819968 -// gas irOptimized: 421911 -// gas legacy: 459355 -// gas legacyOptimized: 461066 +// gas irOptimized: 416966 +// gas legacy: 458976 +// gas legacyOptimized: 460674 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 5482f615f241..33a4c7045af5 100644 --- a/test/libsolidity/semanticTests/array/copying/copy_byte_array_in_struct_to_storage.sol +++ b/test/libsolidity/semanticTests/array/copying/copy_byte_array_in_struct_to_storage.sol @@ -35,12 +35,12 @@ contract C { } // ---- // f() -> 0x40, 0x80, 6, 0x6162636465660000000000000000000000000000000000000000000000000000, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000 -// gas irOptimized: 179750 -// gas legacy: 181001 -// gas legacyOptimized: 180018 +// gas irOptimized: 179420 +// gas legacy: 180675 +// gas legacyOptimized: 179700 // g() -> 0x40, 0xc0, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000, 0x11, 0x3132333435363738393233343536373839000000000000000000000000000000 -// gas irOptimized: 106679 -// gas legacy: 109720 -// gas legacyOptimized: 106932 +// gas irOptimized: 106349 +// gas legacy: 109394 +// gas legacyOptimized: 106614 // h() -> 0x40, 0x60, 0x00, 0x00 // storageEmpty -> 1 diff --git a/test/libsolidity/semanticTests/array/copying/function_type_array_to_storage.sol b/test/libsolidity/semanticTests/array/copying/function_type_array_to_storage.sol index 275a0fca1b75..56a415079084 100644 --- a/test/libsolidity/semanticTests/array/copying/function_type_array_to_storage.sol +++ b/test/libsolidity/semanticTests/array/copying/function_type_array_to_storage.sol @@ -46,11 +46,11 @@ contract C { } // ---- // test() -> 0x20, 0x14, "[a called][b called]" -// gas irOptimized: 116645 -// gas legacy: 118936 -// gas legacyOptimized: 116975 +// gas irOptimized: 116546 +// gas legacy: 118845 +// gas legacyOptimized: 116887 // test2() -> 0x20, 0x14, "[b called][a called]" // test3() -> 0x20, 0x14, "[b called][a called]" -// gas irOptimized: 103246 -// gas legacy: 102745 -// gas legacyOptimized: 101669 +// gas irOptimized: 103147 +// gas legacy: 102654 +// gas legacyOptimized: 101581 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 211477c553c2..0e8cff97fd57 100644 --- a/test/libsolidity/semanticTests/array/copying/storage_memory_nested_bytes.sol +++ b/test/libsolidity/semanticTests/array/copying/storage_memory_nested_bytes.sol @@ -11,6 +11,6 @@ contract C { } // ---- // f() -> 0x20, 0x02, 0x40, 0x80, 3, 0x6162630000000000000000000000000000000000000000000000000000000000, 0x99, 44048183304486788312148433451363384677562265908331949128489393215789685032262, 32241931068525137014058842823026578386641954854143559838526554899205067598957, 49951309422467613961193228765530489307475214998374779756599339590522149884499, 0x54555658595a6162636465666768696a6b6c6d6e6f707172737475767778797a, 0x4142434445464748494a4b4c4d4e4f5051525354555658595a00000000000000 -// gas irOptimized: 202731 -// gas legacy: 204798 -// gas legacyOptimized: 203357 +// gas irOptimized: 202162 +// gas legacy: 204328 +// gas legacyOptimized: 202887 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 5b1a61839183..674b0841e6b4 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 @@ -9,6 +9,6 @@ contract c { } // ---- // test() -> 0x20, 33, 0x303030303030303030303030303030303030303030303030303030303030303, 0x0300000000000000000000000000000000000000000000000000000000000000 -// gas irOptimized: 107343 -// gas legacy: 121408 -// gas legacyOptimized: 120534 +// gas irOptimized: 107183 +// gas legacy: 121245 +// gas legacyOptimized: 120370 diff --git a/test/libsolidity/semanticTests/byte_array_to_storage_cleanup.sol b/test/libsolidity/semanticTests/byte_array_to_storage_cleanup.sol index 14130926e7fb..8d0cb0a01294 100644 --- a/test/libsolidity/semanticTests/byte_array_to_storage_cleanup.sol +++ b/test/libsolidity/semanticTests/byte_array_to_storage_cleanup.sol @@ -28,12 +28,12 @@ contract C { // compileViaYul: also // ---- // constructor() -> -// gas irOptimized: 82402 -// gas irOptimized code: 361000 -// gas legacy: 101895 -// gas legacy code: 609400 -// gas legacyOptimized: 85378 -// gas legacyOptimized code: 397000 +// gas irOptimized: 81932 +// gas irOptimized code: 355200 +// gas legacy: 101472 +// gas legacy code: 604200 +// gas legacyOptimized: 85004 +// gas legacyOptimized code: 392400 // h() -> 0x20, 0x40, 0x00, 0 // ~ emit ev(uint256[],uint256): 0x40, 0x21, 0x02, 0x00, 0x00 // g() -> 0x20, 0x40, 0, 0x00 diff --git a/test/libsolidity/semanticTests/constructor/bytes_in_constructors_packer.sol b/test/libsolidity/semanticTests/constructor/bytes_in_constructors_packer.sol index 7885d3ceecf0..c0b9df16c34d 100644 --- a/test/libsolidity/semanticTests/constructor/bytes_in_constructors_packer.sol +++ b/test/libsolidity/semanticTests/constructor/bytes_in_constructors_packer.sol @@ -24,9 +24,9 @@ contract Creator { } // ---- // f(uint256,bytes): 7, 0x40, 78, "abcdefghijklmnopqrstuvwxyzabcdef", "ghijklmnopqrstuvwxyzabcdefghijkl", "mnopqrstuvwxyz" -> 7, "h" -// gas irOptimized: 169902 -// gas irOptimized code: 105200 -// gas legacy: 173433 -// gas legacy code: 245000 -// gas legacyOptimized: 170360 -// gas legacyOptimized code: 121600 +// gas irOptimized: 169361 +// gas irOptimized code: 99200 +// gas legacy: 172944 +// gas legacy code: 239800 +// gas legacyOptimized: 169858 +// gas legacyOptimized code: 117000 diff --git a/test/libsolidity/semanticTests/constructor/bytes_in_constructors_unpacker.sol b/test/libsolidity/semanticTests/constructor/bytes_in_constructors_unpacker.sol index 1d6b01127c5a..0918a970e272 100644 --- a/test/libsolidity/semanticTests/constructor/bytes_in_constructors_unpacker.sol +++ b/test/libsolidity/semanticTests/constructor/bytes_in_constructors_unpacker.sol @@ -8,11 +8,11 @@ contract Test { } // ---- // constructor(): 7, 0x40, 78, "abcdefghijklmnopqrstuvwxyzabcdef", "ghijklmnopqrstuvwxyzabcdefghijkl", "mnopqrstuvwxyz" -> -// gas irOptimized: 182025 -// gas irOptimized code: 87200 -// gas legacy: 196220 -// gas legacy code: 114600 -// gas legacyOptimized: 182604 -// gas legacyOptimized code: 76000 +// gas irOptimized: 180756 +// gas irOptimized code: 79200 +// gas legacy: 195165 +// gas legacy code: 109400 +// gas legacyOptimized: 181600 +// gas legacyOptimized code: 71400 // m_x() -> 7 // m_s() -> 0x20, 78, "abcdefghijklmnopqrstuvwxyzabcdef", "ghijklmnopqrstuvwxyzabcdefghijkl", "mnopqrstuvwxyz" diff --git a/test/libsolidity/semanticTests/externalContracts/FixedFeeRegistrar.sol b/test/libsolidity/semanticTests/externalContracts/FixedFeeRegistrar.sol index d308d4597e53..925ed54e6dc3 100644 --- a/test/libsolidity/semanticTests/externalContracts/FixedFeeRegistrar.sol +++ b/test/libsolidity/semanticTests/externalContracts/FixedFeeRegistrar.sol @@ -74,12 +74,12 @@ contract FixedFeeRegistrar is Registrar { } // ---- // constructor() -// gas irOptimized: 78006 -// gas irOptimized code: 306600 -// gas legacy: 115817 -// gas legacy code: 797600 -// gas legacyOptimized: 84924 -// gas legacyOptimized code: 392000 +// gas irOptimized: 77654 +// gas irOptimized code: 302200 +// gas legacy: 115395 +// gas legacy code: 792400 +// gas legacyOptimized: 84566 +// gas legacyOptimized code: 387600 // reserve(string), 69 ether: 0x20, 3, "abc" -> // ~ emit Changed(string): #0x4e03657aea45a94fc7d47ba826c8d667c0d1e6e33a64a036ec44f58fa12d6c45 // gas irOptimized: 45967 diff --git a/test/libsolidity/semanticTests/externalContracts/base64.sol b/test/libsolidity/semanticTests/externalContracts/base64.sol index b712092ed022..aed2a11df22c 100644 --- a/test/libsolidity/semanticTests/externalContracts/base64.sol +++ b/test/libsolidity/semanticTests/externalContracts/base64.sol @@ -33,12 +33,12 @@ contract test { // EVMVersion: >=constantinople // ---- // constructor() -// gas irOptimized: 79428 -// gas irOptimized code: 326400 -// gas legacy: 102450 -// gas legacy code: 632600 -// gas legacyOptimized: 88318 -// gas legacyOptimized code: 434400 +// gas irOptimized: 78952 +// gas irOptimized code: 320600 +// gas legacy: 102034 +// gas legacy code: 627400 +// gas legacyOptimized: 87950 +// gas legacyOptimized code: 429800 // encode_inline_asm(bytes): 0x20, 0 -> 0x20, 0 // encode_inline_asm(bytes): 0x20, 1, "f" -> 0x20, 4, "Zg==" // encode_inline_asm(bytes): 0x20, 2, "fo" -> 0x20, 4, "Zm8=" diff --git a/test/libsolidity/semanticTests/externalContracts/deposit_contract.sol b/test/libsolidity/semanticTests/externalContracts/deposit_contract.sol index 0ef87edd4f08..ce77683aab73 100644 --- a/test/libsolidity/semanticTests/externalContracts/deposit_contract.sol +++ b/test/libsolidity/semanticTests/externalContracts/deposit_contract.sol @@ -176,38 +176,38 @@ contract DepositContract is IDepositContract, ERC165 { } // ---- // constructor() -// gas irOptimized: 815686 -// gas irOptimized code: 571200 -// gas legacy: 925933 -// gas legacy code: 1442800 -// gas legacyOptimized: 854404 -// gas legacyOptimized code: 885600 +// gas irOptimized: 809248 +// gas irOptimized code: 558000 +// gas legacy: 919945 +// gas legacy code: 1437600 +// gas legacyOptimized: 848464 +// gas legacyOptimized code: 875200 // supportsInterface(bytes4): 0x0 -> 0 // supportsInterface(bytes4): 0xffffffff00000000000000000000000000000000000000000000000000000000 -> false # defined to be false by ERC-165 # // supportsInterface(bytes4): 0x01ffc9a700000000000000000000000000000000000000000000000000000000 -> true # ERC-165 id # // supportsInterface(bytes4): 0x8564090700000000000000000000000000000000000000000000000000000000 -> true # the deposit interface id # // get_deposit_root() -> 0xd70a234731285c6804c2a4f56711ddb8c82c99740f207854891028af34e27e5e -// gas irOptimized: 115231 -// gas legacy: 148205 -// gas legacyOptimized: 122303 +// gas irOptimized: 109009 +// gas legacy: 142735 +// gas legacyOptimized: 117558 // 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: 115231 -// gas legacy: 148205 -// gas legacyOptimized: 122303 +// gas irOptimized: 109009 +// gas legacy: 142735 +// gas legacyOptimized: 117558 // 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: 115216 -// gas legacy: 148214 -// gas legacyOptimized: 122315 +// gas irOptimized: 108994 +// gas legacy: 142744 +// gas legacyOptimized: 117570 // 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: 115216 -// gas legacy: 148214 -// gas legacyOptimized: 122315 +// gas irOptimized: 108994 +// gas legacy: 142744 +// gas legacyOptimized: 117570 // get_deposit_count() -> 0x20, 8, 0x0200000000000000000000000000000000000000000000000000000000000000 diff --git a/test/libsolidity/semanticTests/externalContracts/strings.sol b/test/libsolidity/semanticTests/externalContracts/strings.sol index a4b0f9fd353d..102c85ae0fa8 100644 --- a/test/libsolidity/semanticTests/externalContracts/strings.sol +++ b/test/libsolidity/semanticTests/externalContracts/strings.sol @@ -49,12 +49,12 @@ contract test { } // ---- // constructor() -// gas irOptimized: 96420 -// gas irOptimized code: 533800 -// gas legacy: 126553 -// gas legacy code: 935400 -// gas legacyOptimized: 102933 -// gas legacyOptimized code: 616000 +// gas irOptimized: 95949 +// gas irOptimized code: 528000 +// gas legacy: 126106 +// gas legacy code: 930200 +// gas legacyOptimized: 102559 +// gas legacyOptimized code: 611400 // toSlice(string): 0x20, 11, "hello world" -> 11, 0xa0 // gas irOptimized: 22660 // gas legacy: 23190 diff --git a/test/libsolidity/semanticTests/functionCall/external_call_to_nonexisting.sol b/test/libsolidity/semanticTests/functionCall/external_call_to_nonexisting.sol index 9d521f7777f9..5b254a9f6c2d 100644 --- a/test/libsolidity/semanticTests/functionCall/external_call_to_nonexisting.sol +++ b/test/libsolidity/semanticTests/functionCall/external_call_to_nonexisting.sol @@ -22,12 +22,12 @@ contract C { } // ---- // constructor(), 1 ether -> -// gas irOptimized: 89555 -// gas irOptimized code: 172800 -// gas legacy: 103042 -// gas legacy code: 338400 -// gas legacyOptimized: 91862 -// gas legacyOptimized code: 201000 +// gas irOptimized: 89155 +// gas irOptimized code: 167800 +// gas legacy: 102626 +// gas legacy code: 333200 +// gas legacyOptimized: 91471 +// gas legacyOptimized code: 196200 // f(uint256): 0 -> FAILURE // f(uint256): 1 -> FAILURE // f(uint256): 2 -> FAILURE 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 9baacd812773..8bf182a89ee8 100644 --- a/test/libsolidity/semanticTests/functionCall/external_call_to_nonexisting_debugstrings.sol +++ b/test/libsolidity/semanticTests/functionCall/external_call_to_nonexisting_debugstrings.sol @@ -25,12 +25,12 @@ contract C { // revertStrings: debug // ---- // constructor(), 1 ether -> -// gas irOptimized: 99264 -// gas irOptimized code: 291200 -// gas legacy: 123585 -// gas legacy code: 686400 -// gas legacyOptimized: 107331 -// gas legacyOptimized code: 391000 +// gas irOptimized: 98842 +// gas irOptimized code: 286000 +// gas legacy: 123163 +// gas legacy code: 681200 +// gas legacyOptimized: 106957 +// gas legacyOptimized code: 386400 // 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" diff --git a/test/libsolidity/semanticTests/inlineAssembly/blobhash_pre_cancun.sol b/test/libsolidity/semanticTests/inlineAssembly/blobhash_pre_cancun.sol index 8972958e1f80..d3a41fc07bf3 100644 --- a/test/libsolidity/semanticTests/inlineAssembly/blobhash_pre_cancun.sol +++ b/test/libsolidity/semanticTests/inlineAssembly/blobhash_pre_cancun.sol @@ -15,7 +15,7 @@ contract C { } } // ==== -// EVMVersion: <=shanghai +// EVMVersion: 1 // g() -> 1000 diff --git a/test/libsolidity/semanticTests/inlineAssembly/transient_storage_low_level_calls.sol b/test/libsolidity/semanticTests/inlineAssembly/transient_storage_low_level_calls.sol index f3fe0384472d..e43fc475740a 100644 --- a/test/libsolidity/semanticTests/inlineAssembly/transient_storage_low_level_calls.sol +++ b/test/libsolidity/semanticTests/inlineAssembly/transient_storage_low_level_calls.sol @@ -68,3 +68,9 @@ contract C { // testCall() -> true // tloadAllowedStaticCall() -> true // tstoreNotAllowedStaticCall() -> true +// gas irOptimized: 98419720 +// gas irOptimized code: 19000 +// gas legacy: 98409086 +// gas legacy code: 30000 +// gas legacyOptimized: 98420962 +// gas legacyOptimized code: 17800 diff --git a/test/libsolidity/semanticTests/inlineAssembly/transient_storage_selfdestruct.sol b/test/libsolidity/semanticTests/inlineAssembly/transient_storage_selfdestruct.sol index 935435420e44..f4975cd4c790 100644 --- a/test/libsolidity/semanticTests/inlineAssembly/transient_storage_selfdestruct.sol +++ b/test/libsolidity/semanticTests/inlineAssembly/transient_storage_selfdestruct.sol @@ -40,5 +40,15 @@ contract D { // EVMVersion: >=cancun // ---- // constructor() -> +// gas irOptimized: 127944 +// gas irOptimized code: 225200 +// gas legacy: 149357 +// gas legacy code: 499800 +// gas legacyOptimized: 125830 +// gas legacyOptimized code: 203200 // destroy() -> // createAndDestroy() -> +// gas legacy: 67044 +// gas legacy code: 92600 +// gas legacyOptimized: 65675 +// gas legacyOptimized code: 39400 diff --git a/test/libsolidity/semanticTests/inlineAssembly/tstore_hidden_staticcall.sol b/test/libsolidity/semanticTests/inlineAssembly/tstore_hidden_staticcall.sol index bdd9401ee5a6..d64c7dfb5fce 100644 --- a/test/libsolidity/semanticTests/inlineAssembly/tstore_hidden_staticcall.sol +++ b/test/libsolidity/semanticTests/inlineAssembly/tstore_hidden_staticcall.sol @@ -18,3 +18,6 @@ contract C { // EVMVersion: >=cancun // ---- // test() -> FAILURE +// gas irOptimized: 98437877 +// gas legacy: 98437872 +// gas legacyOptimized: 98437873 diff --git a/test/libsolidity/semanticTests/salted_create/prediction_example.sol b/test/libsolidity/semanticTests/salted_create/prediction_example.sol index 6fa865440bd4..75174729326f 100644 --- a/test/libsolidity/semanticTests/salted_create/prediction_example.sol +++ b/test/libsolidity/semanticTests/salted_create/prediction_example.sol @@ -26,5 +26,5 @@ contract C { // compileViaYul: also // ---- // createDSalted(bytes32,uint256): 42, 64 -> -// gas legacy: 79241 +// gas legacy: 78574 // gas legacy code: 23600 diff --git a/test/libsolidity/semanticTests/structs/copy_from_mapping.sol b/test/libsolidity/semanticTests/structs/copy_from_mapping.sol index 1d1783a16291..8ee19a278a23 100644 --- a/test/libsolidity/semanticTests/structs/copy_from_mapping.sol +++ b/test/libsolidity/semanticTests/structs/copy_from_mapping.sol @@ -36,8 +36,8 @@ contract C { } // ---- // to_state() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 -// gas irOptimized: 121481 -// gas legacy: 123069 -// gas legacyOptimized: 121756 +// gas irOptimized: 121394 +// gas legacy: 122978 +// gas legacyOptimized: 121648 // to_storage() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 // to_memory() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 diff --git a/test/libsolidity/semanticTests/structs/copy_substructures_from_mapping.sol b/test/libsolidity/semanticTests/structs/copy_substructures_from_mapping.sol index a1b0999ff5b1..9b0fa9207a8c 100644 --- a/test/libsolidity/semanticTests/structs/copy_substructures_from_mapping.sol +++ b/test/libsolidity/semanticTests/structs/copy_substructures_from_mapping.sol @@ -44,8 +44,8 @@ contract C { } // ---- // to_state() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 -// gas irOptimized: 121598 -// gas legacy: 123208 -// gas legacyOptimized: 121763 +// gas irOptimized: 121511 +// gas legacy: 123117 +// gas legacyOptimized: 121655 // to_storage() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 // to_memory() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 diff --git a/test/libsolidity/semanticTests/structs/copy_substructures_to_mapping.sol b/test/libsolidity/semanticTests/structs/copy_substructures_to_mapping.sol index b88466113408..a0834ca5bf5b 100644 --- a/test/libsolidity/semanticTests/structs/copy_substructures_to_mapping.sol +++ b/test/libsolidity/semanticTests/structs/copy_substructures_to_mapping.sol @@ -52,14 +52,14 @@ contract C { } // ---- // from_memory() -> 0x20, 0x60, 0xa0, 0x15, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 -// gas irOptimized: 123039 -// gas legacy: 130227 -// gas legacyOptimized: 128758 +// gas irOptimized: 122952 +// gas legacy: 130136 +// gas legacyOptimized: 128650 // from_state() -> 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 -// gas irOptimized: 121709 -// gas legacy: 123282 -// gas legacyOptimized: 121868 +// gas irOptimized: 121622 +// gas legacy: 123191 +// gas legacyOptimized: 121760 // from_calldata((bytes,uint16[],uint16)): 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 -> 0x20, 0x60, 0xa0, 0x15, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 -// gas irOptimized: 115130 -// gas legacy: 122516 -// gas legacyOptimized: 120804 +// gas irOptimized: 115043 +// gas legacy: 122425 +// gas legacyOptimized: 120696 diff --git a/test/libsolidity/semanticTests/structs/copy_to_mapping.sol b/test/libsolidity/semanticTests/structs/copy_to_mapping.sol index e6b569922c5f..033f0f518c12 100644 --- a/test/libsolidity/semanticTests/structs/copy_to_mapping.sol +++ b/test/libsolidity/semanticTests/structs/copy_to_mapping.sol @@ -45,18 +45,18 @@ contract C { } // ---- // from_state() -> 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 -// gas irOptimized: 121686 -// gas legacy: 123144 -// gas legacyOptimized: 121808 +// gas irOptimized: 121599 +// gas legacy: 123053 +// gas legacyOptimized: 121700 // from_storage() -> 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 -// gas irOptimized: 121731 -// gas legacy: 123193 -// gas legacyOptimized: 121860 +// gas irOptimized: 121644 +// gas legacy: 123102 +// gas legacyOptimized: 121752 // from_memory() -> 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 -// gas irOptimized: 122947 -// gas legacy: 130088 -// gas legacyOptimized: 128754 +// gas irOptimized: 122860 +// gas legacy: 129997 +// gas legacyOptimized: 128646 // from_calldata((bytes,uint16[],uint16)): 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 -> 0x20, 0x60, 0xa0, 21, 3, 0x666f6f0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 -// gas irOptimized: 115045 -// gas legacy: 118301 -// gas legacyOptimized: 115432 +// gas irOptimized: 114958 +// gas legacy: 118210 +// gas legacyOptimized: 115324 diff --git a/test/libsolidity/semanticTests/various/address_code.sol b/test/libsolidity/semanticTests/various/address_code.sol index 6a97c0bf7ee2..f283aaeaa3de 100644 --- a/test/libsolidity/semanticTests/various/address_code.sol +++ b/test/libsolidity/semanticTests/various/address_code.sol @@ -14,12 +14,12 @@ contract C { } // ---- // constructor() -> -// gas irOptimized: 70873 -// gas irOptimized code: 102400 -// gas legacy: 82796 -// gas legacy code: 159000 -// gas legacyOptimized: 69870 -// gas legacyOptimized code: 83800 +// gas irOptimized: 70351 +// gas irOptimized code: 95800 +// gas legacy: 82380 +// gas legacy code: 153800 +// gas legacyOptimized: 69496 +// gas legacyOptimized code: 79200 // initCode() -> 0x20, 0 // f() -> true // g() -> 0 diff --git a/test/libsolidity/semanticTests/various/create_calldata.sol b/test/libsolidity/semanticTests/various/create_calldata.sol index 2db42adebb86..b8ec252095c8 100644 --- a/test/libsolidity/semanticTests/various/create_calldata.sol +++ b/test/libsolidity/semanticTests/various/create_calldata.sol @@ -8,10 +8,10 @@ contract C { } // ---- // constructor(): 42 -> -// gas irOptimized: 68378 -// gas irOptimized code: 77200 -// gas legacy: 78445 -// gas legacy code: 95400 -// gas legacyOptimized: 68677 -// gas legacyOptimized code: 69200 +// gas irOptimized: 67834 +// gas irOptimized code: 70400 +// gas legacy: 78029 +// gas legacy code: 90200 +// gas legacyOptimized: 68321 +// gas legacyOptimized code: 64600 // s() -> 0x20, 0 diff --git a/test/libsolidity/semanticTests/various/selfdestruct_post_cancun.sol b/test/libsolidity/semanticTests/various/selfdestruct_post_cancun.sol index 85c95be44795..263da7133fa9 100644 --- a/test/libsolidity/semanticTests/various/selfdestruct_post_cancun.sol +++ b/test/libsolidity/semanticTests/various/selfdestruct_post_cancun.sol @@ -64,9 +64,12 @@ contract D { // EVMVersion: >=cancun // ---- // constructor(), 1 ether -> -// gas irOptimized: 455954 -// gas legacy: 375495 -// gas legacyOptimized: 507630 +// gas irOptimized: 67028 +// gas irOptimized code: 175400 +// gas legacy: 76163 +// gas legacy code: 297400 +// gas legacyOptimized: 66516 +// gas legacyOptimized code: 168000 // exists() -> false // test_create_and_terminate() -> // exists() -> false diff --git a/test/libsolidity/semanticTests/various/selfdestruct_post_cancun_multiple_beneficiaries.sol b/test/libsolidity/semanticTests/various/selfdestruct_post_cancun_multiple_beneficiaries.sol index 4bc65b760811..16797ee4c0fd 100644 --- a/test/libsolidity/semanticTests/various/selfdestruct_post_cancun_multiple_beneficiaries.sol +++ b/test/libsolidity/semanticTests/various/selfdestruct_post_cancun_multiple_beneficiaries.sol @@ -35,16 +35,30 @@ contract D { // EVMVersion: >=cancun // ---- // constructor(), 2 ether -> +// gas irOptimized: 107718 +// gas irOptimized code: 116200 +// gas legacy: 120424 +// gas legacy code: 253600 +// gas legacyOptimized: 109015 +// gas legacyOptimized code: 130800 // balance: 0x1111111111111111111111111111111111111111 -> 0 // balance: 0x2222222222222222222222222222222222222222 -> 0 // balance -> 2000000000000000000 // exists() -> false // test_deploy_and_terminate_twice() -> +// gas irOptimized: 121350 +// gas irOptimized code: 14000 +// gas legacy: 122384 +// gas legacy code: 43200 +// gas legacyOptimized: 121596 +// gas legacyOptimized code: 22800 // exists() -> false // balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000 // balance: 0x2222222222222222222222222222222222222222 -> 0 // balance -> 1000000000000000000 // deploy() -> +// gas legacy: 58491 +// gas legacy code: 43200 // exists() -> true // balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000 // balance: 0x2222222222222222222222222222222222222222 -> 0 diff --git a/test/libsolidity/semanticTests/various/selfdestruct_post_cancun_redeploy.sol b/test/libsolidity/semanticTests/various/selfdestruct_post_cancun_redeploy.sol index 473571bf1391..1b3022efedf0 100644 --- a/test/libsolidity/semanticTests/various/selfdestruct_post_cancun_redeploy.sol +++ b/test/libsolidity/semanticTests/various/selfdestruct_post_cancun_redeploy.sol @@ -82,14 +82,21 @@ contract D { // EVMVersion: >=cancun // ---- // constructor(), 1 ether -> -// gas irOptimized: 562058 -// gas legacy: 633310 -// gas legacyOptimized: 590051 +// gas irOptimized: 132874 +// gas irOptimized code: 292400 +// gas legacy: 151217 +// gas legacy code: 533400 +// gas legacyOptimized: 131436 +// gas legacyOptimized code: 276600 // exists() -> false // test_deploy_and_terminate() -> // ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000 -// gas irOptimized: 118541 -// gas legacyOptimized: 118305 +// gas irOptimized: 96394 +// gas irOptimized code: 20800 +// gas legacy: 97788 +// gas legacy code: 20800 +// gas legacyOptimized: 96044 +// gas legacyOptimized code: 20800 // exists() -> false // deploy_create2() -> // ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000 @@ -99,3 +106,6 @@ contract D { // test_balance_after_selfdestruct() -> // exists() -> true // deploy_create2() -> FAILURE +// gas irOptimized: 96903654 +// gas legacy: 96903660 +// gas legacyOptimized: 96903641 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 ce8946c55c4e..ef53a4e47848 100644 --- a/test/libsolidity/semanticTests/various/skip_dynamic_types_for_structs.sol +++ b/test/libsolidity/semanticTests/various/skip_dynamic_types_for_structs.sol @@ -19,6 +19,6 @@ contract C { } // ---- // g() -> 2, 6 -// gas irOptimized: 178475 -// gas legacy: 180839 -// gas legacyOptimized: 179374 +// gas irOptimized: 178263 +// gas legacy: 180657 +// gas legacyOptimized: 179156 diff --git a/test/libsolidity/syntaxTests/inlineAssembly/blobhash_pre_cancun_not_declared.sol b/test/libsolidity/syntaxTests/inlineAssembly/blobhash_pre_cancun_not_declared.sol index c0284b330e25..8f58c77ce6f3 100644 --- a/test/libsolidity/syntaxTests/inlineAssembly/blobhash_pre_cancun_not_declared.sol +++ b/test/libsolidity/syntaxTests/inlineAssembly/blobhash_pre_cancun_not_declared.sol @@ -6,7 +6,7 @@ contract C { } } // ==== -// EVMVersion: <=shanghai +// EVMVersion: =shanghai // ---- -// DeclarationError 4619: (106-114): Function "blobhash" not found. +// TypeError 8314: (106-114): The "blobhash" instruction is only available for Cancun-compatible VMs (you are currently compiling for "shanghai"). // DeclarationError 8678: (99-116): Variable count for assignment to "ret" does not match number of values (1 vs. 0) diff --git a/test/libsolidity/syntaxTests/inlineAssembly/mcopy_pre_cancun.sol b/test/libsolidity/syntaxTests/inlineAssembly/mcopy_pre_cancun.sol index 090e2f62862c..96be578948c9 100644 --- a/test/libsolidity/syntaxTests/inlineAssembly/mcopy_pre_cancun.sol +++ b/test/libsolidity/syntaxTests/inlineAssembly/mcopy_pre_cancun.sol @@ -6,6 +6,6 @@ contract C { } } // ==== -// EVMVersion: Date: Thu, 14 Mar 2024 07:40:36 +0100 Subject: [PATCH 0114/1022] Use specific hardhat version on openzeppelin and gp2 external tests (#14938) --- .circleci/config.yml | 12 ++++-------- test/externalTests/gp2.sh | 9 +++++++++ test/externalTests/zeppelin.sh | 6 ++++++ 3 files changed, 19 insertions(+), 8 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index dc4cec201981..13f0c499f549 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1913,8 +1913,7 @@ workflows: - t_ext: *job_ems_compile_ext_colony - t_ext: *job_native_compile_ext_gnosis - # TODO: Re-enable once bumped to use Cancun supported hardhat version - # - t_ext: *job_native_test_ext_zeppelin + - t_ext: *job_native_test_ext_zeppelin - t_ext: *job_native_test_ext_ens - t_ext: *job_native_test_ext_yield_liquidator - t_ext: *job_native_test_ext_perpetual_pools @@ -1922,8 +1921,7 @@ workflows: - t_ext: *job_native_test_ext_prb_math - t_ext: *job_native_test_ext_elementfi - t_ext: *job_native_test_ext_brink - # TODO: Re-enable once bumped to use Cancun supported hardhat version - # - t_ext: *job_native_compile_ext_gp2 + - t_ext: *job_native_compile_ext_gp2 - t_ext: *job_native_compile_ext_euler - t_ext: *job_native_compile_ext_pool_together # TODO: Dropping the external tests below since they are based on old forks and @@ -1937,16 +1935,14 @@ workflows: requires: - t_ems_compile_ext_colony - t_native_compile_ext_gnosis - # TODO: Re-enable once bumped to use Cancun supported hardhat version - # - t_native_test_ext_zeppelin + - t_native_test_ext_zeppelin - t_native_test_ext_ens - t_native_test_ext_yield_liquidator - t_native_test_ext_perpetual_pools - t_native_test_ext_uniswap - t_native_test_ext_elementfi - t_native_test_ext_brink - # TODO: Re-enable once bumped to use Cancun supported hardhat version - # - t_native_compile_ext_gp2 + - t_native_compile_ext_gp2 # TODO: Dropping prb-math from the benchmarks since it is not implemented yet # in the new Foundry external testing infrastructure. # - t_native_test_ext_prb_math diff --git a/test/externalTests/gp2.sh b/test/externalTests/gp2.sh index af77f99aa8b8..20ea586f5f09 100755 --- a/test/externalTests/gp2.sh +++ b/test/externalTests/gp2.sh @@ -66,6 +66,15 @@ function gp2_test force_hardhat_compiler_settings "$config_file" "$(first_word "$SELECTED_PRESETS")" "$config_var" force_hardhat_unlimited_contract_size "$config_file" "$config_var" yarn + # We require to install hardhat 2.20.0 due to support for evm version cancun, otherwise we get the following error: + # Invalid value {"blockGasLimit":12500000,"hardfork":"cancun","allowUnlimitedContractSize":true} for HardhatConfig.networks.hardhat - Expected a value of type HardhatNetworkConfig. + # See: https://github.com/NomicFoundation/hardhat/issues/4176 + yarn add hardhat@2.20.0 + + # Ignore bench directory which fails to compile with current hardhat and ethers versions. + # bench/trace/gas.ts:123:19 - error TS2339: Property 'equals' does not exist on type 'Uint8Array'. + jq '. + {"exclude": ["bench"]}' tsconfig.json > temp.json + mv temp.json tsconfig.json # Remove the config section that requires an Etherscan key. We don't need it just to run tests. sed -i '/^ etherscan: {$/,/^ },$/d' hardhat.config.ts diff --git a/test/externalTests/zeppelin.sh b/test/externalTests/zeppelin.sh index 655e4814f783..64c901f61428 100755 --- a/test/externalTests/zeppelin.sh +++ b/test/externalTests/zeppelin.sh @@ -95,6 +95,8 @@ function zeppelin_test sed -i "s|it(\('calling upgradeToAndCall on the implementation reverts'\)|it.skip(\1|g" test/proxy/utils/UUPSUpgradeable.test.js sed -i "s|it(\('calling upgradeTo from a contract that is not an ERC1967 proxy\)|it.skip(\1|g" test/proxy/utils/UUPSUpgradeable.test.js sed -i "s|it(\('calling upgradeToAndCall from a contract that is not an ERC1967 proxy\)|it.skip(\1|g" test/proxy/utils/UUPSUpgradeable.test.js + sed -i "s|it(\('rejects overflow'\)|it.skip(\1|g" test/token/ERC20/ERC20.test.js + sed -i "s|it(\('decimals overflow'\)|it.skip(\1|g" test/token/ERC20/extensions/ERC4626.test.js # Here only the testToInt(248) and testToInt(256) cases fail so change the loop range to skip them sed -i "s|range(8, 256, 8)\(.forEach(bits => testToInt(bits));\)|range(8, 240, 8)\1|" test/utils/math/SafeCast.test.js @@ -103,6 +105,10 @@ function zeppelin_test force_hardhat_compiler_binary "$config_file" "$BINARY_TYPE" "$BINARY_PATH" force_hardhat_compiler_settings "$config_file" "$(first_word "$SELECTED_PRESETS")" npm install + # We require to install hardhat 2.20.0 due to support for evm version cancun, otherwise we get the following error: + # Invalid value {"blockGasLimit":10000000,"allowUnlimitedContractSize":true,"hardfork":"cancun"} for HardhatConfig.networks.hardhat - Expected a value of type HardhatNetworkConfig. + # See: https://github.com/NomicFoundation/hardhat/issues/4176 + npm install hardhat@2.20.0 replace_version_pragmas for preset in $SELECTED_PRESETS; do From b61c2a91b3a478bd53fb831b0e8811668bc0dd05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nikola=20Mati=C4=87?= Date: Thu, 14 Mar 2024 11:29:02 +0100 Subject: [PATCH 0115/1022] Sort changelog and add release date for 0.8.25 (#14939) --- Changelog.md | 7 ++----- docs/bugs_by_version.json | 4 ++++ 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/Changelog.md b/Changelog.md index ba5dff678755..6a2e25fa2d1d 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,12 +1,9 @@ -### 0.8.25 (unreleased) - -Language Features: - +### 0.8.25 (2023-03-14) Compiler Features: * Code Generator: Use ``MCOPY`` instead of ``MLOAD``/``MSTORE`` loop when copying byte arrays. - * Yul Analyzer: Emit transient storage warning only for the first occurrence of ``tstore``. * EVM: Set default EVM version to ``cancun``. + * Yul Analyzer: Emit transient storage warning only for the first occurrence of ``tstore``. Bugfixes: diff --git a/docs/bugs_by_version.json b/docs/bugs_by_version.json index 156b846d012d..7022635fde1a 100644 --- a/docs/bugs_by_version.json +++ b/docs/bugs_by_version.json @@ -1890,6 +1890,10 @@ "bugs": [], "released": "2024-01-25" }, + "0.8.25": { + "bugs": [], + "released": "2023-03-14" + }, "0.8.3": { "bugs": [ "FullInlinerNonExpressionSplitArgumentEvaluationOrder", From 4b748854d76b095ebec51c518ffca63b2494b123 Mon Sep 17 00:00:00 2001 From: Nikola Matic Date: Thu, 14 Mar 2024 11:35:19 +0100 Subject: [PATCH 0116/1022] Set version to 0.8.26 --- CMakeLists.txt | 2 +- Changelog.md | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 18af34d26bf0..5e2a2b4a32f1 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.25") +set(PROJECT_VERSION "0.8.26") # 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 6a2e25fa2d1d..21a58478a6c8 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,3 +1,14 @@ +### 0.8.26 (unreleased) + +Language Features: + + +Compiler Features: + + +Bugfixes: + + ### 0.8.25 (2023-03-14) Compiler Features: From 655a9d806ee7259658f47f3ff29f690cf175c13c Mon Sep 17 00:00:00 2001 From: Zuri Obozuwa Date: Fri, 15 Mar 2024 01:59:46 +0000 Subject: [PATCH 0117/1022] Fix passing of string input parameter to Enable method of DebugInfoSelection struct Use const ref to input string instead of incurring the cost of copying the input string --- liblangutil/DebugInfoSelection.cpp | 2 +- liblangutil/DebugInfoSelection.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/liblangutil/DebugInfoSelection.cpp b/liblangutil/DebugInfoSelection.cpp index 88e09cdb7aa0..ad0b615c1c1e 100644 --- a/liblangutil/DebugInfoSelection.cpp +++ b/liblangutil/DebugInfoSelection.cpp @@ -83,7 +83,7 @@ std::optional DebugInfoSelection::fromComponents( return selection; } -bool DebugInfoSelection::enable(std::string _component) +bool DebugInfoSelection::enable(std::string const& _component) { auto memberIt = componentMap().find(boost::trim_copy(_component)); if (memberIt == componentMap().end()) diff --git a/liblangutil/DebugInfoSelection.h b/liblangutil/DebugInfoSelection.h index 40ba3d6b2573..3a9432de6d02 100644 --- a/liblangutil/DebugInfoSelection.h +++ b/liblangutil/DebugInfoSelection.h @@ -49,7 +49,7 @@ struct DebugInfoSelection std::vector const& _componentNames, bool _acceptWildcards = false ); - bool enable(std::string _component); + bool enable(std::string const& _component); bool all() const noexcept; bool any() const noexcept; From 905c8ae15217a2853dd9378f1445e875b822505a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Fri, 15 Mar 2024 17:32:25 +0100 Subject: [PATCH 0118/1022] PPA scripts: Don't use tabs for alignment --- scripts/deps-ppa/static_z3.sh | 8 ++++---- scripts/release_ppa.sh | 24 ++++++++++++------------ 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/scripts/deps-ppa/static_z3.sh b/scripts/deps-ppa/static_z3.sh index 67cb15ce8a2c..106119917722 100755 --- a/scripts/deps-ppa/static_z3.sh +++ b/scripts/deps-ppa/static_z3.sh @@ -9,10 +9,10 @@ ## This requires the following entries in /etc/dput.cf: ## ## [cpp-build-deps] -## fqdn = ppa.launchpad.net -## method = ftp -## incoming = ~ethereum/cpp-build-deps -## login = anonymous +## fqdn = ppa.launchpad.net +## method = ftp +## incoming = ~ethereum/cpp-build-deps +## login = anonymous ## ## To interact with launchpad, you need to set the variables $LAUNCHPAD_EMAIL ## and $LAUNCHPAD_KEYID in the file .release_ppa_auth in the root directory of diff --git a/scripts/release_ppa.sh b/scripts/release_ppa.sh index 252fd4c49c64..e134ed16142a 100755 --- a/scripts/release_ppa.sh +++ b/scripts/release_ppa.sh @@ -23,22 +23,22 @@ ## Additionally the following entries in /etc/dput.cf are required: ## ## [ethereum-dev] -## fqdn = ppa.launchpad.net -## method = ftp -## incoming = ~ethereum/ethereum-dev -## login = anonymous +## fqdn = ppa.launchpad.net +## method = ftp +## incoming = ~ethereum/ethereum-dev +## login = anonymous ## ## [ethereum] -## fqdn = ppa.launchpad.net -## method = ftp -## incoming = ~ethereum/ethereum -## login = anonymous +## fqdn = ppa.launchpad.net +## method = ftp +## incoming = ~ethereum/ethereum +## login = anonymous ## ## [ethereum-static] -## fqdn = ppa.launchpad.net -## method = ftp -## incoming = ~ethereum/ethereum-static -## login = anonymous +## fqdn = ppa.launchpad.net +## method = ftp +## incoming = ~ethereum/ethereum-static +## login = anonymous ## ############################################################################## From b74203030ff8a09fa546c1d0c7ccb19fbbbf1a10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Fri, 15 Mar 2024 17:33:15 +0100 Subject: [PATCH 0119/1022] PPA scripts: Drop lunar from the distribution list --- scripts/deps-ppa/static_z3.sh | 2 +- scripts/release_ppa.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/deps-ppa/static_z3.sh b/scripts/deps-ppa/static_z3.sh index 106119917722..be45f44526f8 100755 --- a/scripts/deps-ppa/static_z3.sh +++ b/scripts/deps-ppa/static_z3.sh @@ -41,7 +41,7 @@ sourcePPAConfig # Sanity check checkDputEntries "\[cpp-build-deps\]" -DISTRIBUTIONS="focal jammy lunar mantic" +DISTRIBUTIONS="focal jammy mantic" for distribution in $DISTRIBUTIONS do diff --git a/scripts/release_ppa.sh b/scripts/release_ppa.sh index e134ed16142a..6a6fa8f0e55f 100755 --- a/scripts/release_ppa.sh +++ b/scripts/release_ppa.sh @@ -68,7 +68,7 @@ packagename=solc # This needs to be a still active release static_build_distribution=focal -DISTRIBUTIONS="focal jammy lunar mantic" +DISTRIBUTIONS="focal jammy mantic" if is_release then From d19991c34910e2c18788d3df78b633af71be80c9 Mon Sep 17 00:00:00 2001 From: Snoppy Date: Tue, 26 Mar 2024 16:32:36 +0800 Subject: [PATCH 0120/1022] fix typos (#14940) --- test/compilationTests/corion/premium.sol | 2 +- test/compilationTests/corion/schelling.sol | 2 +- test/compilationTests/corion/token.sol | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/test/compilationTests/corion/premium.sol b/test/compilationTests/corion/premium.sol index 8dbe76212bd5..646ab00e1594 100644 --- a/test/compilationTests/corion/premium.sol +++ b/test/compilationTests/corion/premium.sol @@ -310,7 +310,7 @@ contract premium is module, safeMath { @addr The address which is needed to be checked. - @success Is the address crontact or not + @success Is the address contract or not */ uint256 _codeLength; assembly { diff --git a/test/compilationTests/corion/schelling.sol b/test/compilationTests/corion/schelling.sol index 2503748b8b5c..96b530d26e83 100644 --- a/test/compilationTests/corion/schelling.sol +++ b/test/compilationTests/corion/schelling.sol @@ -521,7 +521,7 @@ contract schelling is module, announcementTypes, schellingVars { @aboveW Weight of votes: ABOVE @belowW Weight of votes: BELOW - @uint256 Calculatet weight + @uint256 Calculate weight */ if ( aboveW == belowW ) { return aboveW + belowW; diff --git a/test/compilationTests/corion/token.sol b/test/compilationTests/corion/token.sol index 51c93f120be4..377e8b68f2d1 100644 --- a/test/compilationTests/corion/token.sol +++ b/test/compilationTests/corion/token.sol @@ -464,7 +464,7 @@ contract token is safeMath, module, announcementTypes { @addr Address to be checked - @success Is the address crontact or not + @success Is the address contract or not */ uint256 _codeLength; assembly { From 06fc835c8383c8ec0a69d9131bc2a552334cccb9 Mon Sep 17 00:00:00 2001 From: InventiveCoder <163831412+InventiveCoder@users.noreply.github.com> Date: Tue, 26 Mar 2024 16:35:10 +0800 Subject: [PATCH 0121/1022] Remove redundant word (#14952) Signed-off-by: InventiveCoder --- libsolidity/codegen/ir/Common.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libsolidity/codegen/ir/Common.h b/libsolidity/codegen/ir/Common.h index 2484ad80914f..cf5bc69c7bea 100644 --- a/libsolidity/codegen/ir/Common.h +++ b/libsolidity/codegen/ir/Common.h @@ -81,7 +81,7 @@ std::string dispenseLocationComment(ASTNode const& _node, IRGenerationContext& _ } // Overloading std::less() makes it possible to use YulArity as a map key. We could define operator< -// instead but such an operator would be a bit ambiguous (e.g. YulArity{2, 2} would be be greater than +// instead but such an operator would be a bit ambiguous (e.g. YulArity{2, 2} would be greater than // YulArity{1, 10} in lexicographical order but the latter has greater total number of inputs and outputs). template<> struct std::less From f82f0a1abc29996643c2e2b932fab933d5fa8bf3 Mon Sep 17 00:00:00 2001 From: r0qs Date: Mon, 25 Mar 2024 12:19:05 +0100 Subject: [PATCH 0122/1022] Install latest eldarica release on base ubuntu image --- .../buildpack-deps/Dockerfile.ubuntu2004 | 25 +++++++++++++++---- .../buildpack-deps/Dockerfile.ubuntu2204 | 25 +++++++++++++++---- 2 files changed, 40 insertions(+), 10 deletions(-) diff --git a/scripts/docker/buildpack-deps/Dockerfile.ubuntu2004 b/scripts/docker/buildpack-deps/Dockerfile.ubuntu2004 index 6ff8d1bd43ec..45490291a9c6 100644 --- a/scripts/docker/buildpack-deps/Dockerfile.ubuntu2004 +++ b/scripts/docker/buildpack-deps/Dockerfile.ubuntu2004 @@ -22,14 +22,14 @@ # (c) 2016-2019 solidity contributors. #------------------------------------------------------------------------------ FROM buildpack-deps:focal AS base -LABEL version="21" +LABEL version="22" ARG DEBIAN_FRONTEND=noninteractive RUN set -ex; \ - dist=$(grep DISTRIB_CODENAME /etc/lsb-release | cut -d= -f2); \ - echo "deb http://ppa.launchpad.net/ethereum/cpp-build-deps/ubuntu $dist main" >> /etc/apt/sources.list ; \ - apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 1c52189c923f6ca9 ; \ + dist=$(grep DISTRIB_CODENAME /etc/lsb-release | cut -d= -f2); \ + echo "deb http://ppa.launchpad.net/ethereum/cpp-build-deps/ubuntu $dist main" >> /etc/apt/sources.list ; \ + apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 1c52189c923f6ca9 ; \ apt-get update; \ apt-get install -qqy --no-install-recommends \ build-essential sudo \ @@ -40,7 +40,20 @@ RUN set -ex; \ libcvc4-dev libz3-static-dev z3-static jq \ ; \ apt-get install -qy python3-pip python3-sphinx; \ - pip3 install codecov; \ + pip3 install codecov; + +# Eldarica +RUN set -ex; \ + apt-get update; \ + apt-get install -qy unzip openjdk-11-jre; \ + eldarica_version="2.1"; \ + wget "https://github.com/uuverifiers/eldarica/releases/download/v${eldarica_version}/eldarica-bin-${eldarica_version}.zip" -O /opt/eld_binaries.zip; \ + test "$(sha256sum /opt/eld_binaries.zip)" = "0ac43f45c0925383c9d2077f62bbb515fd792375f3b2b101b30c9e81dcd7785c /opt/eld_binaries.zip"; \ + unzip /opt/eld_binaries.zip -d /opt; \ + rm -f /opt/eld_binaries.zip; + +# Cleanup +RUN set -ex; \ rm -rf /var/lib/apt/lists/* FROM base AS libraries @@ -57,3 +70,5 @@ FROM base COPY --from=libraries /usr/lib /usr/lib COPY --from=libraries /usr/bin /usr/bin COPY --from=libraries /usr/include /usr/include +COPY --from=libraries /opt/eldarica /opt/eldarica +ENV PATH="$PATH:/opt/eldarica" diff --git a/scripts/docker/buildpack-deps/Dockerfile.ubuntu2204 b/scripts/docker/buildpack-deps/Dockerfile.ubuntu2204 index 6908811f925f..d7b92544863c 100644 --- a/scripts/docker/buildpack-deps/Dockerfile.ubuntu2204 +++ b/scripts/docker/buildpack-deps/Dockerfile.ubuntu2204 @@ -22,14 +22,14 @@ # (c) 2016-2019 solidity contributors. #------------------------------------------------------------------------------ FROM buildpack-deps:jammy AS base -LABEL version="6" +LABEL version="7" ARG DEBIAN_FRONTEND=noninteractive RUN set -ex; \ - dist=$(grep DISTRIB_CODENAME /etc/lsb-release | cut -d= -f2); \ - echo "deb http://ppa.launchpad.net/ethereum/cpp-build-deps/ubuntu $dist main" >> /etc/apt/sources.list ; \ - apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 1c52189c923f6ca9 ; \ + dist=$(grep DISTRIB_CODENAME /etc/lsb-release | cut -d= -f2); \ + echo "deb http://ppa.launchpad.net/ethereum/cpp-build-deps/ubuntu $dist main" >> /etc/apt/sources.list ; \ + apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 1c52189c923f6ca9 ; \ apt-get update; \ apt-get install -qqy --no-install-recommends \ build-essential sudo \ @@ -40,7 +40,20 @@ RUN set -ex; \ libcvc4-dev libz3-static-dev z3-static jq \ libcln-dev zip locales-all; \ apt-get install -qy python3-pip python3-sphinx; \ - pip3 install codecov; \ + pip3 install codecov; + +# Eldarica +RUN set -ex; \ + apt-get update; \ + apt-get install -qy unzip openjdk-11-jre; \ + eldarica_version="2.1"; \ + wget "https://github.com/uuverifiers/eldarica/releases/download/v${eldarica_version}/eldarica-bin-${eldarica_version}.zip" -O /opt/eld_binaries.zip; \ + test "$(sha256sum /opt/eld_binaries.zip)" = "0ac43f45c0925383c9d2077f62bbb515fd792375f3b2b101b30c9e81dcd7785c /opt/eld_binaries.zip"; \ + unzip /opt/eld_binaries.zip -d /opt; \ + rm -f /opt/eld_binaries.zip; + +# Cleanup +RUN set -ex; \ rm -rf /var/lib/apt/lists/* FROM base AS libraries @@ -61,3 +74,5 @@ FROM base COPY --from=libraries /usr/lib /usr/lib COPY --from=libraries /usr/bin /usr/bin COPY --from=libraries /usr/include /usr/include +COPY --from=libraries /opt/eldarica /opt/eldarica +ENV PATH="$PATH:/opt/eldarica" From 9b0134b9539c4e731d701e29740880792a3cd400 Mon Sep 17 00:00:00 2001 From: r0qs Date: Mon, 25 Mar 2024 17:17:33 +0100 Subject: [PATCH 0123/1022] Install eldarica on OSX machines --- .circleci/osx_install_dependencies.sh | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/.circleci/osx_install_dependencies.sh b/.circleci/osx_install_dependencies.sh index 4ca4a31d503b..87383ba8f58b 100755 --- a/.circleci/osx_install_dependencies.sh +++ b/.circleci/osx_install_dependencies.sh @@ -55,6 +55,9 @@ then brew install coreutils brew install diffutils brew install grep + # JRE is required to run eldarica solver + brew install openjdk@11 + brew install unzip # writing to /usr/local/lib need administrative privileges. sudo ./scripts/install_obsolete_jsoncpp_1_7_4.sh @@ -73,6 +76,14 @@ then cd .. sudo rm -rf "$boost_dir" + # eldarica + eldarica_version="2.1" + wget "https://github.com/uuverifiers/eldarica/releases/download/v${eldarica_version}/eldarica-bin-${eldarica_version}.zip" -O /tmp/eld_binaries.zip + validate_checksum /tmp/eld_binaries.zip 0ac43f45c0925383c9d2077f62bbb515fd792375f3b2b101b30c9e81dcd7785c + unzip /tmp/eld_binaries.zip -d /tmp + sudo mv /tmp/eldarica/{eld,eld-client,target,eldEnv} /usr/local/bin + rm -rf /tmp/{eldarica,eld_binaries.zip} + # z3 z3_version="4.12.1" z3_dir="z3-z3-$z3_version" From 77b8ca51d649201be80e17fbc539cf2378f69c1a Mon Sep 17 00:00:00 2001 From: r0qs Date: Mon, 25 Mar 2024 17:22:27 +0100 Subject: [PATCH 0124/1022] Update `actions/checkout` version to v4 --- .github/workflows/buildpack-deps.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/buildpack-deps.yml b/.github/workflows/buildpack-deps.yml index 6a261bd2eb9c..2cd6e5048c07 100644 --- a/.github/workflows/buildpack-deps.yml +++ b/.github/workflows/buildpack-deps.yml @@ -26,7 +26,7 @@ jobs: image_variant: [emscripten, ubuntu.clang.ossfuzz, ubuntu2004, ubuntu2204.clang, ubuntu2204] steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 with: fetch-depth: 0 From 1fec659620b1e260679bc365a7580cb12c2dc955 Mon Sep 17 00:00:00 2001 From: r0qs Date: Mon, 25 Mar 2024 14:19:38 +0100 Subject: [PATCH 0125/1022] Bump CI docker images --- .circleci/config.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 13f0c499f549..5b6f023cc577 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -9,12 +9,12 @@ version: 2.1 parameters: ubuntu-2004-docker-image: type: string - # solbuildpackpusher/solidity-buildpack-deps:ubuntu2004-21 - default: "solbuildpackpusher/solidity-buildpack-deps@sha256:6f64c7b35aabddb416d28f621a3c4bbae768c257d6866f6a7f05f8225acc94f0" + # solbuildpackpusher/solidity-buildpack-deps:ubuntu2004-22 + default: "solbuildpackpusher/solidity-buildpack-deps@sha256:212b4d79a89c6e2d9b58ddea2d6296c5618f4ae0b016694a3b159d2b11cbbacc" ubuntu-2204-docker-image: type: string - # solbuildpackpusher/solidity-buildpack-deps:ubuntu2204-6 - default: "solbuildpackpusher/solidity-buildpack-deps@sha256:6eee10420382588b274374c6a18cb2e5d4f8a9fef5cf440b3a1acfc32bf52837" + # solbuildpackpusher/solidity-buildpack-deps:ubuntu2204-7 + default: "solbuildpackpusher/solidity-buildpack-deps@sha256:ecbeec36b12fd953bfb6fb3e7ced474bb73945d7ed615e6538960c32bae8126c" ubuntu-2204-clang-docker-image: type: string # solbuildpackpusher/solidity-buildpack-deps:ubuntu2204.clang-5 From 9ea88304f2658cbe771dc7ce29dfc15e98d3d604 Mon Sep 17 00:00:00 2001 From: Martin Blicha Date: Tue, 5 Mar 2024 20:13:32 +0100 Subject: [PATCH 0126/1022] SMTChecker: Add command-line test for Eldarica --- test/cmdlineTests/model_checker_solvers_eld/args | 1 + test/cmdlineTests/model_checker_solvers_eld/err | 5 +++++ test/cmdlineTests/model_checker_solvers_eld/input.sol | 7 +++++++ 3 files changed, 13 insertions(+) create mode 100644 test/cmdlineTests/model_checker_solvers_eld/args create mode 100644 test/cmdlineTests/model_checker_solvers_eld/err create mode 100644 test/cmdlineTests/model_checker_solvers_eld/input.sol diff --git a/test/cmdlineTests/model_checker_solvers_eld/args b/test/cmdlineTests/model_checker_solvers_eld/args new file mode 100644 index 000000000000..e4acd0b46b71 --- /dev/null +++ b/test/cmdlineTests/model_checker_solvers_eld/args @@ -0,0 +1 @@ +--model-checker-engine chc --model-checker-solvers eld diff --git a/test/cmdlineTests/model_checker_solvers_eld/err b/test/cmdlineTests/model_checker_solvers_eld/err new file mode 100644 index 000000000000..ff7ad37b313e --- /dev/null +++ b/test/cmdlineTests/model_checker_solvers_eld/err @@ -0,0 +1,5 @@ +Warning: CHC: Assertion violation happens here. + --> model_checker_solvers_eld/input.sol:5:3: + | +5 | assert(x > 0); + | ^^^^^^^^^^^^^ diff --git a/test/cmdlineTests/model_checker_solvers_eld/input.sol b/test/cmdlineTests/model_checker_solvers_eld/input.sol new file mode 100644 index 000000000000..7d05ef6e5f3e --- /dev/null +++ b/test/cmdlineTests/model_checker_solvers_eld/input.sol @@ -0,0 +1,7 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity >=0.0; +contract test { + function f(uint x) public pure { + assert(x > 0); + } +} \ No newline at end of file From 1d9ae8703405310b7b2c1c7b4ed551f6deadda54 Mon Sep 17 00:00:00 2001 From: r0qs Date: Wed, 3 Apr 2024 10:53:10 +0200 Subject: [PATCH 0127/1022] Install Eldarica on Ubuntu Clang images --- .../Dockerfile.ubuntu.clang.ossfuzz | 18 +++++++++++++++++- .../Dockerfile.ubuntu2204.clang | 19 +++++++++++++++++-- 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/scripts/docker/buildpack-deps/Dockerfile.ubuntu.clang.ossfuzz b/scripts/docker/buildpack-deps/Dockerfile.ubuntu.clang.ossfuzz index fd98de73e07f..0b2a99b1a299 100644 --- a/scripts/docker/buildpack-deps/Dockerfile.ubuntu.clang.ossfuzz +++ b/scripts/docker/buildpack-deps/Dockerfile.ubuntu.clang.ossfuzz @@ -22,7 +22,7 @@ # (c) 2016-2021 solidity contributors. #------------------------------------------------------------------------------ FROM gcr.io/oss-fuzz-base/base-clang:latest as base -LABEL version="4" +LABEL version="5" ARG DEBIAN_FRONTEND=noninteractive @@ -73,6 +73,16 @@ RUN set -ex; \ make install; \ rm -rf /usr/src/z3 +# Eldarica +RUN set -ex; \ + apt-get update; \ + apt-get install -qy unzip openjdk-11-jre; \ + eldarica_version="2.1"; \ + wget "https://github.com/uuverifiers/eldarica/releases/download/v${eldarica_version}/eldarica-bin-${eldarica_version}.zip" -O /opt/eld_binaries.zip; \ + test "$(sha256sum /opt/eld_binaries.zip)" = "0ac43f45c0925383c9d2077f62bbb515fd792375f3b2b101b30c9e81dcd7785c /opt/eld_binaries.zip"; \ + unzip /opt/eld_binaries.zip -d /opt; \ + rm -f /opt/eld_binaries.zip; + # OSSFUZZ: libprotobuf-mutator RUN set -ex; \ git clone https://github.com/google/libprotobuf-mutator.git \ @@ -137,7 +147,13 @@ RUN set -ex; \ cp abicoder.hpp /usr/include; \ rm -rf /usr/src/Yul-Isabelle +# Cleanup +RUN set -ex; \ + rm -rf /var/lib/apt/lists/* + FROM base COPY --from=libraries /usr/lib /usr/lib COPY --from=libraries /usr/bin /usr/bin COPY --from=libraries /usr/include /usr/include +COPY --from=libraries /opt/eldarica /opt/eldarica +ENV PATH="$PATH:/opt/eldarica" diff --git a/scripts/docker/buildpack-deps/Dockerfile.ubuntu2204.clang b/scripts/docker/buildpack-deps/Dockerfile.ubuntu2204.clang index a14bdc113817..60d5a599c32e 100644 --- a/scripts/docker/buildpack-deps/Dockerfile.ubuntu2204.clang +++ b/scripts/docker/buildpack-deps/Dockerfile.ubuntu2204.clang @@ -22,7 +22,7 @@ # (c) 2016-2019 solidity contributors. #------------------------------------------------------------------------------ FROM buildpack-deps:jammy AS base -LABEL version="5" +LABEL version="6" ARG DEBIAN_FRONTEND=noninteractive @@ -39,7 +39,20 @@ RUN set -ex; \ libboost-program-options-dev \ clang \ libz3-static-dev z3-static jq \ - libcln-dev; \ + libcln-dev; + +# Eldarica +RUN set -ex; \ + apt-get update; \ + apt-get install -qy unzip openjdk-11-jre; \ + eldarica_version="2.1"; \ + wget "https://github.com/uuverifiers/eldarica/releases/download/v${eldarica_version}/eldarica-bin-${eldarica_version}.zip" -O /opt/eld_binaries.zip; \ + test "$(sha256sum /opt/eld_binaries.zip)" = "0ac43f45c0925383c9d2077f62bbb515fd792375f3b2b101b30c9e81dcd7785c /opt/eld_binaries.zip"; \ + unzip /opt/eld_binaries.zip -d /opt; \ + rm -f /opt/eld_binaries.zip; + +# Cleanup +RUN set -ex; \ rm -rf /var/lib/apt/lists/* FROM base AS libraries @@ -63,3 +76,5 @@ FROM base COPY --from=libraries /usr/lib /usr/lib COPY --from=libraries /usr/bin /usr/bin COPY --from=libraries /usr/include /usr/include +COPY --from=libraries /opt/eldarica /opt/eldarica +ENV PATH="$PATH:/opt/eldarica" From f6dd9b0005b00e7a30772b767df223eee82059b8 Mon Sep 17 00:00:00 2001 From: zo9999 <99550525+zo9999@users.noreply.github.com> Date: Wed, 3 Apr 2024 10:05:05 +0100 Subject: [PATCH 0128/1022] Make KnowledgeBase object constructors explicit in order to avoid (#14958) unexpected implicit conversions --- libyul/optimiser/KnowledgeBase.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libyul/optimiser/KnowledgeBase.h b/libyul/optimiser/KnowledgeBase.h index 258f85f5cddf..f83c5ac66105 100644 --- a/libyul/optimiser/KnowledgeBase.h +++ b/libyul/optimiser/KnowledgeBase.h @@ -62,11 +62,11 @@ class KnowledgeBase public: /// Constructor for arbitrary value callback that allows for variable values /// to change in between calls to functions of this class. - KnowledgeBase(std::function _variableValues): + explicit KnowledgeBase(std::function _variableValues): m_variableValues(std::move(_variableValues)) {} /// Constructor to use if source code is in SSA form and values are constant. - KnowledgeBase(std::map const& _ssaValues); + explicit KnowledgeBase(std::map const& _ssaValues); bool knownToBeDifferent(YulString _a, YulString _b); std::optional differenceIfKnownConstant(YulString _a, YulString _b); From c75e63aba9b63f31b608e92263ed8ba6ed40e492 Mon Sep 17 00:00:00 2001 From: Tamas Molnar Date: Wed, 3 Apr 2024 12:01:21 +0200 Subject: [PATCH 0129/1022] docs: Replace outdated Scaffold-ETH link to Scaffold-ETH-2 (#14973) --- docs/resources.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/resources.rst b/docs/resources.rst index 85b3cf9a3912..1773859d4eaf 100644 --- a/docs/resources.rst +++ b/docs/resources.rst @@ -110,7 +110,7 @@ Solidity Tools * `leafleth `_ A documentation generator for Solidity smart-contracts. -* `Scaffold-ETH `_ +* `Scaffold-ETH 2 `_ Forkable Ethereum development stack focused on fast product iterations. * `sol2uml `_ From ad5eab88e3d66a98d47853bc0af0da1dfc2d2f70 Mon Sep 17 00:00:00 2001 From: Juliano Penna Date: Wed, 3 Apr 2024 07:04:12 -0300 Subject: [PATCH 0130/1022] Update reference-types.rst (#14949) It isn't "the only possibility for public contract function arguments" since version 0.6.9, as mentioned in the second "Note" of https://docs.soliditylang.org/en/v0.8.24/types.html#data-location --- docs/types/reference-types.rst | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/types/reference-types.rst b/docs/types/reference-types.rst index d2e9300e64a4..a6c48d2416d9 100644 --- a/docs/types/reference-types.rst +++ b/docs/types/reference-types.rst @@ -392,8 +392,7 @@ Array Members // Data location for all state variables is storage. bool[2][] pairsOfFlags; - // newPairs is stored in memory - the only possibility - // for public contract function arguments + // newPairs is stored in memory function setAllFlagPairs(bool[2][] memory newPairs) public { // assignment to a storage array performs a copy of ``newPairs`` and // replaces the complete array ``pairsOfFlags``. From 10b1b3c8fc360efdcec7579398409b614c3caae9 Mon Sep 17 00:00:00 2001 From: Vc Date: Wed, 3 Apr 2024 18:17:52 +0800 Subject: [PATCH 0131/1022] Optimize the magicVariableToID function. (#14901) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Nikola Matić --- libsolidity/analysis/GlobalContext.cpp | 56 ++++++++++++++------------ 1 file changed, 31 insertions(+), 25 deletions(-) diff --git a/libsolidity/analysis/GlobalContext.cpp b/libsolidity/analysis/GlobalContext.cpp index 628b903617de..c4833689fe04 100644 --- a/libsolidity/analysis/GlobalContext.cpp +++ b/libsolidity/analysis/GlobalContext.cpp @@ -28,40 +28,46 @@ #include #include #include +#include namespace solidity::frontend { namespace { + /// Magic variables get negative ids for easy differentiation int magicVariableToID(std::string const& _name) { - if (_name == "abi") return -1; - else if (_name == "addmod") return -2; - else if (_name == "assert") return -3; - else if (_name == "block") return -4; - else if (_name == "blockhash") return -5; - else if (_name == "ecrecover") return -6; - else if (_name == "gasleft") return -7; - else if (_name == "keccak256") return -8; - else if (_name == "msg") return -15; - else if (_name == "mulmod") return -16; - else if (_name == "now") return -17; - else if (_name == "require") return -18; - else if (_name == "revert") return -19; - else if (_name == "ripemd160") return -20; - else if (_name == "selfdestruct") return -21; - else if (_name == "sha256") return -22; - else if (_name == "sha3") return -23; - else if (_name == "suicide") return -24; - else if (_name == "super") return -25; - else if (_name == "tx") return -26; - else if (_name == "type") return -27; - else if (_name == "this") return -28; - else if (_name == "blobhash") return -29; - else - solAssert(false, "Unknown magic variable: \"" + _name + "\"."); + static std::unordered_map const magicVariables = { + {"abi", -1}, + {"addmod", -2}, + {"assert", -3}, + {"block", -4}, + {"blockhash", -5}, + {"ecrecover", -6}, + {"gasleft", -7}, + {"keccak256", -8}, + {"msg", -15}, + {"mulmod", -16}, + {"now", -17}, + {"require", -18}, + {"revert", -19}, + {"ripemd160", -20}, + {"selfdestruct", -21}, + {"sha256", -22}, + {"sha3", -23}, + {"suicide", -24}, + {"super", -25}, + {"tx", -26}, + {"type", -27}, + {"this", -28}, + {"blobhash", -29} + }; + + if (auto id = magicVariables.find(_name); id != magicVariables.end()) + return id->second; + solAssert(false, "Unknown magic variable: \"" + _name + "\"."); } inline std::vector> constructMagicVariables(langutil::EVMVersion _evmVersion) From d2cbe963cf50ef9b18f7239ebd27409ec00b7a50 Mon Sep 17 00:00:00 2001 From: wilsoncusack Date: Wed, 3 Apr 2024 06:21:05 -0400 Subject: [PATCH 0132/1022] NatSpec: add error to context for notice, dev, and param tags. (#14970) --- docs/natspec-format.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/natspec-format.rst b/docs/natspec-format.rst index f92958b90c02..b187ea84c74f 100644 --- a/docs/natspec-format.rst +++ b/docs/natspec-format.rst @@ -117,9 +117,9 @@ Tag =============== ====================================================================================== ============================= ``@title`` A title that should describe the contract/interface contract, library, interface, struct, enum ``@author`` The name of the author contract, library, interface, struct, enum -``@notice`` Explain to an end user what this does contract, library, interface, function, public state variable, event, struct, enum -``@dev`` Explain to a developer any extra details contract, library, interface, function, state variable, event, struct, enum -``@param`` Documents a parameter just like in Doxygen (must be followed by parameter name) function, event +``@notice`` Explain to an end user what this does contract, library, interface, function, public state variable, event, struct, enum, error +``@dev`` Explain to a developer any extra details contract, library, interface, function, state variable, event, struct, enum, error +``@param`` Documents a parameter just like in Doxygen (must be followed by parameter name) function, event, error ``@return`` Documents the return variables of a contract's function function, public state variable ``@inheritdoc`` Copies all missing tags from the base function (must be followed by the contract name) function, public state variable ``@custom:...`` Custom tag, semantics is application-defined everywhere From ab1f2b83e94515ac09feddeaec85334632801399 Mon Sep 17 00:00:00 2001 From: Ardis Lu Date: Wed, 3 Apr 2024 03:35:02 -0700 Subject: [PATCH 0133/1022] Update precompiled contract address range (#14950) --- docs/introduction-to-smart-contracts.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/introduction-to-smart-contracts.rst b/docs/introduction-to-smart-contracts.rst index a31b06616aee..de06d684ec43 100644 --- a/docs/introduction-to-smart-contracts.rst +++ b/docs/introduction-to-smart-contracts.rst @@ -603,7 +603,7 @@ Precompiled Contracts ===================== There is a small set of contract addresses that are special: -The address range between ``1`` and (including) ``8`` contains +The address range between ``1`` and (including) ``0x0a`` contains "precompiled contracts" that can be called as any other contract but their behavior (and their gas consumption) is not defined by EVM code stored at that address (they do not contain code) From 87bdfd6a70fd20b9fdcb269ab870c1ca09552873 Mon Sep 17 00:00:00 2001 From: Alexander Arlt Date: Thu, 15 Feb 2024 22:59:11 +0100 Subject: [PATCH 0134/1022] [buildsystem] Fix libstdlib to use CMAKE_CURRENT_SOURCE_DIR. --- libstdlib/CMakeLists.txt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libstdlib/CMakeLists.txt b/libstdlib/CMakeLists.txt index 65a3a1cda16b..b6b22832d6e6 100644 --- a/libstdlib/CMakeLists.txt +++ b/libstdlib/CMakeLists.txt @@ -1,18 +1,18 @@ # This will re-generate the headers if any file within src was modified. -set_directory_properties(PROPERTY CMAKE_CONFIGURE_DEPENDS ${PROJECT_SOURCE_DIR}/stdlib/src/) +set_directory_properties(PROPERTY CMAKE_CONFIGURE_DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/src/) set(STDLIB stub) set(GENERATED_STDLIB_HEADERS) foreach(src IN LISTS STDLIB) - set(STDLIB_FILE ${PROJECT_SOURCE_DIR}/libstdlib/src/${src}.sol) + set(STDLIB_FILE ${CMAKE_CURRENT_SOURCE_DIR}/src/${src}.sol) file(READ ${STDLIB_FILE} STDLIB_FILE_CONTENT HEX) string(REGEX MATCHALL ".." STDLIB_FILE_CONTENT "${STDLIB_FILE_CONTENT}") list(REMOVE_ITEM STDLIB_FILE_CONTENT "0d") string(REGEX REPLACE ";" ",\n\t0x" STDLIB_FILE_CONTENT "${STDLIB_FILE_CONTENT}") set(STDLIB_FILE_CONTENT "0x${STDLIB_FILE_CONTENT}") set(STDLIB_FILE_NAME ${src}) - configure_file("${PROJECT_SOURCE_DIR}/libstdlib/stdlib.src.h.in" ${PROJECT_BINARY_DIR}/include/libstdlib/${src}.h NEWLINE_STYLE LF @ONLY) + configure_file("${CMAKE_CURRENT_SOURCE_DIR}/stdlib.src.h.in" ${PROJECT_BINARY_DIR}/include/libstdlib/${src}.h NEWLINE_STYLE LF @ONLY) list(APPEND GENERATED_STDLIB_HEADERS ${PROJECT_BINARY_DIR}/include/libstdlib/${src}.h) endforeach() -configure_file("${PROJECT_SOURCE_DIR}/libstdlib/stdlib.h.in" ${PROJECT_BINARY_DIR}/include/libstdlib/stdlib.h NEWLINE_STYLE LF @ONLY) +configure_file("${CMAKE_CURRENT_SOURCE_DIR}/stdlib.h.in" ${PROJECT_BINARY_DIR}/include/libstdlib/stdlib.h NEWLINE_STYLE LF @ONLY) From b60ed2b96a6b00b2d23a2dd9caf98173527fc38f Mon Sep 17 00:00:00 2001 From: Alexander Arlt Date: Fri, 16 Feb 2024 18:00:41 +0100 Subject: [PATCH 0135/1022] [buildsystem] Add USE_SYSTEM_LIBRARIES option. --- CMakeLists.txt | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5e2a2b4a32f1..6609585a7ba4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -37,16 +37,19 @@ option(SOLC_STATIC_STDLIBS "Link solc against static versions of libgcc and libs option(STRICT_Z3_VERSION "Use the latest version of Z3" ON) option(PEDANTIC "Enable extra warnings and pedantic build flags. Treat all warnings as errors." ON) option(PROFILE_OPTIMIZER_STEPS "Output performance metrics for the optimiser steps." OFF) +option(USE_SYSTEM_LIBRARIES "Use system libraries" OFF) # Setup cccache. include(EthCcache) # Let's find our dependencies include(EthDependencies) -include(fmtlib) -include(jsoncpp) -include(range-v3) -include_directories(SYSTEM ${JSONCPP_INCLUDE_DIR}) +if (NOT USE_SYSTEM_LIBRARIES) + include(fmtlib) + include(jsoncpp) + include(range-v3) + include_directories(SYSTEM ${JSONCPP_INCLUDE_DIR}) +endif() find_package(Threads) From d178c40102f024f17e64c777b37729aec544409e Mon Sep 17 00:00:00 2001 From: Alexander Arlt Date: Fri, 16 Feb 2024 19:33:38 +0100 Subject: [PATCH 0136/1022] [buildsystem] Add ONLY_BUILD_SOLIDITY_LIBRARIES option. --- CMakeLists.txt | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6609585a7ba4..142e884edd02 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -38,6 +38,7 @@ option(STRICT_Z3_VERSION "Use the latest version of Z3" ON) option(PEDANTIC "Enable extra warnings and pedantic build flags. Treat all warnings as errors." ON) option(PROFILE_OPTIMIZER_STEPS "Output performance metrics for the optimiser steps." OFF) option(USE_SYSTEM_LIBRARIES "Use system libraries" OFF) +option(ONLY_BUILD_SOLIDITY_LIBRARIES "Only build solidity libraries" OFF) # Setup cccache. include(EthCcache) @@ -144,12 +145,16 @@ add_subdirectory(libyul) add_subdirectory(libsolidity) add_subdirectory(libsolc) add_subdirectory(libstdlib) -add_subdirectory(tools) -if (NOT EMSCRIPTEN) - add_subdirectory(solc) -endif() +if (NOT ONLY_BUILD_SOLIDITY_LIBRARIES) + add_subdirectory(tools) + + if (NOT EMSCRIPTEN) + add_subdirectory(solc) + endif() -if (TESTS AND NOT EMSCRIPTEN) - add_subdirectory(test) + if (TESTS AND NOT EMSCRIPTEN) + add_subdirectory(test) + endif() endif() + From 780018ad21656f04a6737b87965706e9dc4e8058 Mon Sep 17 00:00:00 2001 From: Alexander Arlt Date: Fri, 16 Feb 2024 19:40:56 +0100 Subject: [PATCH 0137/1022] [buildsystem] Add STRICT_JSONCPP_VERSION option. --- CMakeLists.txt | 5 +++++ libsolutil/JSON.cpp | 2 ++ 2 files changed, 7 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 142e884edd02..b9f2ddc36cad 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -39,6 +39,7 @@ option(PEDANTIC "Enable extra warnings and pedantic build flags. Treat all warni option(PROFILE_OPTIMIZER_STEPS "Output performance metrics for the optimiser steps." OFF) option(USE_SYSTEM_LIBRARIES "Use system libraries" OFF) option(ONLY_BUILD_SOLIDITY_LIBRARIES "Only build solidity libraries" OFF) +option(STRICT_JSONCPP_VERSION "Strictly check installed jsoncpp version" ON) # Setup cccache. include(EthCcache) @@ -62,6 +63,10 @@ if (PROFILE_OPTIMIZER_STEPS) add_definitions(-DPROFILE_OPTIMIZER_STEPS) endif() +if (STRICT_JSONCPP_VERSION) + add_definitions(-DSTRICT_JSONCPP_VERSION_CHECK) +endif() + # Figure out what compiler and system are we using include(EthCompilerSettings) diff --git a/libsolutil/JSON.cpp b/libsolutil/JSON.cpp index ea75ada0f79f..3a2570d47ec1 100644 --- a/libsolutil/JSON.cpp +++ b/libsolutil/JSON.cpp @@ -30,10 +30,12 @@ #include #include +#ifdef STRICT_JSONCPP_VERSION_CHECK static_assert( (JSONCPP_VERSION_MAJOR == 1) && (JSONCPP_VERSION_MINOR == 9) && (JSONCPP_VERSION_PATCH == 3), "Unexpected jsoncpp version: " JSONCPP_VERSION_STRING ". Expecting 1.9.3." ); +#endif namespace solidity::util { From 8b1b65f93f2b48a3d35316caeb9508f56e787f19 Mon Sep 17 00:00:00 2001 From: r0qs Date: Wed, 3 Apr 2024 12:40:44 +0200 Subject: [PATCH 0138/1022] Bump ubuntu-clang docker images --- .circleci/config.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 5b6f023cc577..21b596830b7c 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -17,12 +17,12 @@ parameters: default: "solbuildpackpusher/solidity-buildpack-deps@sha256:ecbeec36b12fd953bfb6fb3e7ced474bb73945d7ed615e6538960c32bae8126c" ubuntu-2204-clang-docker-image: type: string - # solbuildpackpusher/solidity-buildpack-deps:ubuntu2204.clang-5 - default: "solbuildpackpusher/solidity-buildpack-deps@sha256:e991421ce9f44d6476b29588fc355da1c3b3fedcc424fd12d844bbe310ad7851" + # solbuildpackpusher/solidity-buildpack-deps:ubuntu2204.clang-6 + default: "solbuildpackpusher/solidity-buildpack-deps@sha256:1818a56061f39ece4a92138948404214bf939c9deb68f4dc2c68cd82b39e8410" ubuntu-clang-ossfuzz-docker-image: type: string - # solbuildpackpusher/solidity-buildpack-deps:ubuntu.clang.ossfuzz-4 - default: "solbuildpackpusher/solidity-buildpack-deps@sha256:b122ef9dca71a8f90b74f3ba13cda4453681506e4a4ff047e7bc2130c76b0d1e" + # solbuildpackpusher/solidity-buildpack-deps:ubuntu.clang.ossfuzz-5 + default: "solbuildpackpusher/solidity-buildpack-deps@sha256:c21c4c2a591d0702c388d1944539f6498ed8e51c54c1a1cb34693079efd9ab77" emscripten-docker-image: type: string # NOTE: Please remember to update the `build_emscripten.sh` whenever the hash of this image changes. From 95046121317ee9bfc65dbe88aa64ed296cc3e08e Mon Sep 17 00:00:00 2001 From: Pawel Gebal Date: Thu, 4 Apr 2024 17:14:07 +0200 Subject: [PATCH 0139/1022] SMTChecker: Fix internal error when using bitwise operators with an array element as an argument --- Changelog.md | 1 + libsmtutil/Z3Interface.cpp | 2 ++ .../operators/bitwise_and_array.sol | 17 +++++++++++++++++ 3 files changed, 20 insertions(+) create mode 100644 test/libsolidity/smtCheckerTests/operators/bitwise_and_array.sol diff --git a/Changelog.md b/Changelog.md index 21a58478a6c8..c915a1ecfe95 100644 --- a/Changelog.md +++ b/Changelog.md @@ -7,6 +7,7 @@ Compiler Features: Bugfixes: + * SMTChecker: Fix internal error when using bitwise operators with an array element as argument. ### 0.8.25 (2023-03-14) diff --git a/libsmtutil/Z3Interface.cpp b/libsmtutil/Z3Interface.cpp index a16e75668e40..1cfbc815f78e 100644 --- a/libsmtutil/Z3Interface.cpp +++ b/libsmtutil/Z3Interface.cpp @@ -386,6 +386,8 @@ Expression Z3Interface::fromZ3Expr(z3::expr const& _expr) kind == Z3_OP_RECURSIVE ) return Expression(_expr.decl().name().str(), arguments, fromZ3Sort(_expr.get_sort())); + else if (kind == Z3_OP_CONCAT) + return Expression("concat", arguments, sort); smtAssert(false); diff --git a/test/libsolidity/smtCheckerTests/operators/bitwise_and_array.sol b/test/libsolidity/smtCheckerTests/operators/bitwise_and_array.sol new file mode 100644 index 000000000000..96e143490926 --- /dev/null +++ b/test/libsolidity/smtCheckerTests/operators/bitwise_and_array.sol @@ -0,0 +1,17 @@ +contract C { + function bitwiseXor(int[10] memory p) public pure { + 1 ^ p[0]; + } + + function bitwiseAnd(int[10] memory p) public pure { + 1 & p[0]; + } + + function bitwiseOr(int[10] memory p) public pure { + 1 | p[0]; + } +} +// ==== +// SMTEngine: all +// ---- +// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. From bcb10f8111ae987ba711f62cdcc308896e7b3332 Mon Sep 17 00:00:00 2001 From: Alexander Arlt Date: Wed, 3 Apr 2024 13:47:18 +0200 Subject: [PATCH 0140/1022] Remove signature removal from macos universal binaries. --- .circleci/config.yml | 8 -------- 1 file changed, 8 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 21b596830b7c..0dd960e93d19 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -249,13 +249,6 @@ commands: # -------------------------------------------------------------------------- # Artifact Commands - remove_signature_from_universal_binary: - description: Remove signature from universal binary - steps: - - run: - name: Remove signature from universal binary - command: codesign --remove-signature build/solc/solc - store_artifacts_solc: description: Store compiled solc executable as artifact steps: @@ -1196,7 +1189,6 @@ jobs: - checkout - install_dependencies_osx - run_build - - remove_signature_from_universal_binary - store_artifacts_solc - store_artifacts_yul_phaser - persist_executables_to_workspace_osx From f6d5a4373e85067b5ba7f54fb6c45e7802c4c067 Mon Sep 17 00:00:00 2001 From: hanghuge Date: Sat, 6 Apr 2024 21:01:34 +0800 Subject: [PATCH 0141/1022] chore: remove repetitive words Signed-off-by: hanghuge --- libsolidity/interface/FileReader.cpp | 2 +- .../yulOptimizerTests/unusedAssignEliminator/for_continue.yul | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libsolidity/interface/FileReader.cpp b/libsolidity/interface/FileReader.cpp index 4197780e65b2..158d4dd2c95c 100644 --- a/libsolidity/interface/FileReader.cpp +++ b/libsolidity/interface/FileReader.cpp @@ -271,7 +271,7 @@ boost::filesystem::path FileReader::normalizeCLIPathForVFS( // If the path is on the same drive as the working dir, for portability we prefer not to // include the root name. Do this only for non-UNC paths - my experiments show that on Windows - // when the working dir is an UNC path, / does not not actually refer to the root of the UNC path. + // when the working dir is an UNC path, / does not actually refer to the root of the UNC path. boost::filesystem::path normalizedRootPath = normalizeCLIRootPathForVFS(normalizedPath, canonicalWorkDir); diff --git a/test/libyul/yulOptimizerTests/unusedAssignEliminator/for_continue.yul b/test/libyul/yulOptimizerTests/unusedAssignEliminator/for_continue.yul index d3cfb0d84b0b..213ebcaea45b 100644 --- a/test/libyul/yulOptimizerTests/unusedAssignEliminator/for_continue.yul +++ b/test/libyul/yulOptimizerTests/unusedAssignEliminator/for_continue.yul @@ -7,7 +7,7 @@ x := 2 // Will not be removed as if-condition can be false. if callvalue() { // This can be removed because x is overwritten both after the - // loop at at the start of the next iteration. + // loop at the start of the next iteration. x := 3 continue } From 37f46544bd2e9eefe85624cd18ce5a2c7b963c77 Mon Sep 17 00:00:00 2001 From: Alexander Arlt Date: Sun, 18 Feb 2024 23:11:48 +0100 Subject: [PATCH 0142/1022] Rename some tests. --- .../args | 0 .../output | 0 .../stdin | 0 .../args | 0 .../output | 0 .../stdin | 0 .../args | 0 .../output | 0 .../stdin | 0 .../args | 0 .../err | 0 .../exit | 0 .../stdin | 0 .../args | 0 .../err | 0 .../exit | 0 .../stdin | 0 .../args | 0 .../err | 0 .../exit | 0 .../stdin | 0 .../args | 0 .../err | 0 .../exit | 0 .../stdin | 0 .../args | 0 .../err | 0 .../exit | 0 .../stdin | 0 .../{asm_json_import_no_value => import_asm_json_no_value}/args | 0 .../{asm_json_import_no_value => import_asm_json_no_value}/err | 0 .../{asm_json_import_no_value => import_asm_json_no_value}/exit | 0 .../{asm_json_import_no_value => import_asm_json_no_value}/stdin | 0 .../args | 0 .../err | 0 .../exit | 0 .../stdin | 0 .../args | 0 .../err | 0 .../exit | 0 .../stdin | 0 .../args | 0 .../err | 0 .../exit | 0 .../stdin | 0 .../args | 0 .../output | 0 .../stdin | 0 .../args | 0 .../err | 0 .../exit | 0 .../stdin | 0 .../args | 0 .../err | 0 .../exit | 0 .../stdin | 0 .../{asm_json_import_verbatim => import_asm_json_verbatim}/args | 0 .../{asm_json_import_verbatim => import_asm_json_verbatim}/output | 0 .../{asm_json_import_verbatim => import_asm_json_verbatim}/stdin | 0 .../args | 0 .../output | 0 .../stdin | 0 .../args | 0 .../output | 0 .../stdin | 0 65 files changed, 0 insertions(+), 0 deletions(-) rename test/cmdlineTests/{asm_json_import_all_valid_flags => import_asm_json_all_valid_flags}/args (100%) rename test/cmdlineTests/{asm_json_import_all_valid_flags => import_asm_json_all_valid_flags}/output (100%) rename test/cmdlineTests/{asm_json_import_all_valid_flags => import_asm_json_all_valid_flags}/stdin (100%) rename test/cmdlineTests/{asm_json_import_difficulty_prevrandao => import_asm_json_difficulty_prevrandao}/args (100%) rename test/cmdlineTests/{asm_json_import_difficulty_prevrandao => import_asm_json_difficulty_prevrandao}/output (100%) rename test/cmdlineTests/{asm_json_import_difficulty_prevrandao => import_asm_json_difficulty_prevrandao}/stdin (100%) rename test/cmdlineTests/{asm_json_import_hex_subassembly_indices => import_asm_json_hex_subassembly_indices}/args (100%) rename test/cmdlineTests/{asm_json_import_hex_subassembly_indices => import_asm_json_hex_subassembly_indices}/output (100%) rename test/cmdlineTests/{asm_json_import_hex_subassembly_indices => import_asm_json_hex_subassembly_indices}/stdin (100%) rename test/cmdlineTests/{asm_json_import_invalid_data_not_hex => import_asm_json_invalid_data_not_hex}/args (100%) rename test/cmdlineTests/{asm_json_import_invalid_data_not_hex => import_asm_json_invalid_data_not_hex}/err (100%) rename test/cmdlineTests/{asm_json_import_invalid_data_not_hex => import_asm_json_invalid_data_not_hex}/exit (100%) rename test/cmdlineTests/{asm_json_import_invalid_data_not_hex => import_asm_json_invalid_data_not_hex}/stdin (100%) rename test/cmdlineTests/{asm_json_import_invalid_data_not_object => import_asm_json_invalid_data_not_object}/args (100%) rename test/cmdlineTests/{asm_json_import_invalid_data_not_object => import_asm_json_invalid_data_not_object}/err (100%) rename test/cmdlineTests/{asm_json_import_invalid_data_not_object => import_asm_json_invalid_data_not_object}/exit (100%) rename test/cmdlineTests/{asm_json_import_invalid_data_not_object => import_asm_json_invalid_data_not_object}/stdin (100%) rename test/cmdlineTests/{asm_json_import_invalid_jumptype_instruction => import_asm_json_invalid_jumptype_instruction}/args (100%) rename test/cmdlineTests/{asm_json_import_invalid_jumptype_instruction => import_asm_json_invalid_jumptype_instruction}/err (100%) rename test/cmdlineTests/{asm_json_import_invalid_jumptype_instruction => import_asm_json_invalid_jumptype_instruction}/exit (100%) rename test/cmdlineTests/{asm_json_import_invalid_jumptype_instruction => import_asm_json_invalid_jumptype_instruction}/stdin (100%) rename test/cmdlineTests/{asm_json_import_invalid_value => import_asm_json_invalid_value}/args (100%) rename test/cmdlineTests/{asm_json_import_invalid_value => import_asm_json_invalid_value}/err (100%) rename test/cmdlineTests/{asm_json_import_invalid_value => import_asm_json_invalid_value}/exit (100%) rename test/cmdlineTests/{asm_json_import_invalid_value => import_asm_json_invalid_value}/stdin (100%) rename test/cmdlineTests/{asm_json_import_missing_subobject_indices => import_asm_json_missing_subobject_indices}/args (100%) rename test/cmdlineTests/{asm_json_import_missing_subobject_indices => import_asm_json_missing_subobject_indices}/err (100%) rename test/cmdlineTests/{asm_json_import_missing_subobject_indices => import_asm_json_missing_subobject_indices}/exit (100%) rename test/cmdlineTests/{asm_json_import_missing_subobject_indices => import_asm_json_missing_subobject_indices}/stdin (100%) rename test/cmdlineTests/{asm_json_import_no_value => import_asm_json_no_value}/args (100%) rename test/cmdlineTests/{asm_json_import_no_value => import_asm_json_no_value}/err (100%) rename test/cmdlineTests/{asm_json_import_no_value => import_asm_json_no_value}/exit (100%) rename test/cmdlineTests/{asm_json_import_no_value => import_asm_json_no_value}/stdin (100%) rename test/cmdlineTests/{asm_json_import_non_unique_sources => import_asm_json_non_unique_sources}/args (100%) rename test/cmdlineTests/{asm_json_import_non_unique_sources => import_asm_json_non_unique_sources}/err (100%) rename test/cmdlineTests/{asm_json_import_non_unique_sources => import_asm_json_non_unique_sources}/exit (100%) rename test/cmdlineTests/{asm_json_import_non_unique_sources => import_asm_json_non_unique_sources}/stdin (100%) rename test/cmdlineTests/{asm_json_import_optimize_not_supported => import_asm_json_optimize_not_supported}/args (100%) rename test/cmdlineTests/{asm_json_import_optimize_not_supported => import_asm_json_optimize_not_supported}/err (100%) rename test/cmdlineTests/{asm_json_import_optimize_not_supported => import_asm_json_optimize_not_supported}/exit (100%) rename test/cmdlineTests/{asm_json_import_optimize_not_supported => import_asm_json_optimize_not_supported}/stdin (100%) rename test/cmdlineTests/{asm_json_import_out_of_range_data_index => import_asm_json_out_of_range_data_index}/args (100%) rename test/cmdlineTests/{asm_json_import_out_of_range_data_index => import_asm_json_out_of_range_data_index}/err (100%) rename test/cmdlineTests/{asm_json_import_out_of_range_data_index => import_asm_json_out_of_range_data_index}/exit (100%) rename test/cmdlineTests/{asm_json_import_out_of_range_data_index => import_asm_json_out_of_range_data_index}/stdin (100%) rename test/cmdlineTests/{asm_json_import_random_order_data_index => import_asm_json_random_order_data_index}/args (100%) rename test/cmdlineTests/{asm_json_import_random_order_data_index => import_asm_json_random_order_data_index}/output (100%) rename test/cmdlineTests/{asm_json_import_random_order_data_index => import_asm_json_random_order_data_index}/stdin (100%) rename test/cmdlineTests/{asm_json_import_unrecognized_field => import_asm_json_unrecognized_field}/args (100%) rename test/cmdlineTests/{asm_json_import_unrecognized_field => import_asm_json_unrecognized_field}/err (100%) rename test/cmdlineTests/{asm_json_import_unrecognized_field => import_asm_json_unrecognized_field}/exit (100%) rename test/cmdlineTests/{asm_json_import_unrecognized_field => import_asm_json_unrecognized_field}/stdin (100%) rename test/cmdlineTests/{asm_json_import_untagged_jumpdest => import_asm_json_untagged_jumpdest}/args (100%) rename test/cmdlineTests/{asm_json_import_untagged_jumpdest => import_asm_json_untagged_jumpdest}/err (100%) rename test/cmdlineTests/{asm_json_import_untagged_jumpdest => import_asm_json_untagged_jumpdest}/exit (100%) rename test/cmdlineTests/{asm_json_import_untagged_jumpdest => import_asm_json_untagged_jumpdest}/stdin (100%) rename test/cmdlineTests/{asm_json_import_verbatim => import_asm_json_verbatim}/args (100%) rename test/cmdlineTests/{asm_json_import_verbatim => import_asm_json_verbatim}/output (100%) rename test/cmdlineTests/{asm_json_import_verbatim => import_asm_json_verbatim}/stdin (100%) rename test/cmdlineTests/{asm_json_import_yul_more_subobjects => import_asm_json_yul_more_subobjects}/args (100%) rename test/cmdlineTests/{asm_json_import_yul_more_subobjects => import_asm_json_yul_more_subobjects}/output (100%) rename test/cmdlineTests/{asm_json_import_yul_more_subobjects => import_asm_json_yul_more_subobjects}/stdin (100%) rename test/cmdlineTests/{asm_json_import_yul_subobjects => import_asm_json_yul_subobjects}/args (100%) rename test/cmdlineTests/{asm_json_import_yul_subobjects => import_asm_json_yul_subobjects}/output (100%) rename test/cmdlineTests/{asm_json_import_yul_subobjects => import_asm_json_yul_subobjects}/stdin (100%) diff --git a/test/cmdlineTests/asm_json_import_all_valid_flags/args b/test/cmdlineTests/import_asm_json_all_valid_flags/args similarity index 100% rename from test/cmdlineTests/asm_json_import_all_valid_flags/args rename to test/cmdlineTests/import_asm_json_all_valid_flags/args diff --git a/test/cmdlineTests/asm_json_import_all_valid_flags/output b/test/cmdlineTests/import_asm_json_all_valid_flags/output similarity index 100% rename from test/cmdlineTests/asm_json_import_all_valid_flags/output rename to test/cmdlineTests/import_asm_json_all_valid_flags/output diff --git a/test/cmdlineTests/asm_json_import_all_valid_flags/stdin b/test/cmdlineTests/import_asm_json_all_valid_flags/stdin similarity index 100% rename from test/cmdlineTests/asm_json_import_all_valid_flags/stdin rename to test/cmdlineTests/import_asm_json_all_valid_flags/stdin diff --git a/test/cmdlineTests/asm_json_import_difficulty_prevrandao/args b/test/cmdlineTests/import_asm_json_difficulty_prevrandao/args similarity index 100% rename from test/cmdlineTests/asm_json_import_difficulty_prevrandao/args rename to test/cmdlineTests/import_asm_json_difficulty_prevrandao/args diff --git a/test/cmdlineTests/asm_json_import_difficulty_prevrandao/output b/test/cmdlineTests/import_asm_json_difficulty_prevrandao/output similarity index 100% rename from test/cmdlineTests/asm_json_import_difficulty_prevrandao/output rename to test/cmdlineTests/import_asm_json_difficulty_prevrandao/output diff --git a/test/cmdlineTests/asm_json_import_difficulty_prevrandao/stdin b/test/cmdlineTests/import_asm_json_difficulty_prevrandao/stdin similarity index 100% rename from test/cmdlineTests/asm_json_import_difficulty_prevrandao/stdin rename to test/cmdlineTests/import_asm_json_difficulty_prevrandao/stdin diff --git a/test/cmdlineTests/asm_json_import_hex_subassembly_indices/args b/test/cmdlineTests/import_asm_json_hex_subassembly_indices/args similarity index 100% rename from test/cmdlineTests/asm_json_import_hex_subassembly_indices/args rename to test/cmdlineTests/import_asm_json_hex_subassembly_indices/args diff --git a/test/cmdlineTests/asm_json_import_hex_subassembly_indices/output b/test/cmdlineTests/import_asm_json_hex_subassembly_indices/output similarity index 100% rename from test/cmdlineTests/asm_json_import_hex_subassembly_indices/output rename to test/cmdlineTests/import_asm_json_hex_subassembly_indices/output diff --git a/test/cmdlineTests/asm_json_import_hex_subassembly_indices/stdin b/test/cmdlineTests/import_asm_json_hex_subassembly_indices/stdin similarity index 100% rename from test/cmdlineTests/asm_json_import_hex_subassembly_indices/stdin rename to test/cmdlineTests/import_asm_json_hex_subassembly_indices/stdin diff --git a/test/cmdlineTests/asm_json_import_invalid_data_not_hex/args b/test/cmdlineTests/import_asm_json_invalid_data_not_hex/args similarity index 100% rename from test/cmdlineTests/asm_json_import_invalid_data_not_hex/args rename to test/cmdlineTests/import_asm_json_invalid_data_not_hex/args diff --git a/test/cmdlineTests/asm_json_import_invalid_data_not_hex/err b/test/cmdlineTests/import_asm_json_invalid_data_not_hex/err similarity index 100% rename from test/cmdlineTests/asm_json_import_invalid_data_not_hex/err rename to test/cmdlineTests/import_asm_json_invalid_data_not_hex/err diff --git a/test/cmdlineTests/asm_json_import_invalid_data_not_hex/exit b/test/cmdlineTests/import_asm_json_invalid_data_not_hex/exit similarity index 100% rename from test/cmdlineTests/asm_json_import_invalid_data_not_hex/exit rename to test/cmdlineTests/import_asm_json_invalid_data_not_hex/exit diff --git a/test/cmdlineTests/asm_json_import_invalid_data_not_hex/stdin b/test/cmdlineTests/import_asm_json_invalid_data_not_hex/stdin similarity index 100% rename from test/cmdlineTests/asm_json_import_invalid_data_not_hex/stdin rename to test/cmdlineTests/import_asm_json_invalid_data_not_hex/stdin diff --git a/test/cmdlineTests/asm_json_import_invalid_data_not_object/args b/test/cmdlineTests/import_asm_json_invalid_data_not_object/args similarity index 100% rename from test/cmdlineTests/asm_json_import_invalid_data_not_object/args rename to test/cmdlineTests/import_asm_json_invalid_data_not_object/args diff --git a/test/cmdlineTests/asm_json_import_invalid_data_not_object/err b/test/cmdlineTests/import_asm_json_invalid_data_not_object/err similarity index 100% rename from test/cmdlineTests/asm_json_import_invalid_data_not_object/err rename to test/cmdlineTests/import_asm_json_invalid_data_not_object/err diff --git a/test/cmdlineTests/asm_json_import_invalid_data_not_object/exit b/test/cmdlineTests/import_asm_json_invalid_data_not_object/exit similarity index 100% rename from test/cmdlineTests/asm_json_import_invalid_data_not_object/exit rename to test/cmdlineTests/import_asm_json_invalid_data_not_object/exit diff --git a/test/cmdlineTests/asm_json_import_invalid_data_not_object/stdin b/test/cmdlineTests/import_asm_json_invalid_data_not_object/stdin similarity index 100% rename from test/cmdlineTests/asm_json_import_invalid_data_not_object/stdin rename to test/cmdlineTests/import_asm_json_invalid_data_not_object/stdin diff --git a/test/cmdlineTests/asm_json_import_invalid_jumptype_instruction/args b/test/cmdlineTests/import_asm_json_invalid_jumptype_instruction/args similarity index 100% rename from test/cmdlineTests/asm_json_import_invalid_jumptype_instruction/args rename to test/cmdlineTests/import_asm_json_invalid_jumptype_instruction/args diff --git a/test/cmdlineTests/asm_json_import_invalid_jumptype_instruction/err b/test/cmdlineTests/import_asm_json_invalid_jumptype_instruction/err similarity index 100% rename from test/cmdlineTests/asm_json_import_invalid_jumptype_instruction/err rename to test/cmdlineTests/import_asm_json_invalid_jumptype_instruction/err diff --git a/test/cmdlineTests/asm_json_import_invalid_jumptype_instruction/exit b/test/cmdlineTests/import_asm_json_invalid_jumptype_instruction/exit similarity index 100% rename from test/cmdlineTests/asm_json_import_invalid_jumptype_instruction/exit rename to test/cmdlineTests/import_asm_json_invalid_jumptype_instruction/exit diff --git a/test/cmdlineTests/asm_json_import_invalid_jumptype_instruction/stdin b/test/cmdlineTests/import_asm_json_invalid_jumptype_instruction/stdin similarity index 100% rename from test/cmdlineTests/asm_json_import_invalid_jumptype_instruction/stdin rename to test/cmdlineTests/import_asm_json_invalid_jumptype_instruction/stdin diff --git a/test/cmdlineTests/asm_json_import_invalid_value/args b/test/cmdlineTests/import_asm_json_invalid_value/args similarity index 100% rename from test/cmdlineTests/asm_json_import_invalid_value/args rename to test/cmdlineTests/import_asm_json_invalid_value/args diff --git a/test/cmdlineTests/asm_json_import_invalid_value/err b/test/cmdlineTests/import_asm_json_invalid_value/err similarity index 100% rename from test/cmdlineTests/asm_json_import_invalid_value/err rename to test/cmdlineTests/import_asm_json_invalid_value/err diff --git a/test/cmdlineTests/asm_json_import_invalid_value/exit b/test/cmdlineTests/import_asm_json_invalid_value/exit similarity index 100% rename from test/cmdlineTests/asm_json_import_invalid_value/exit rename to test/cmdlineTests/import_asm_json_invalid_value/exit diff --git a/test/cmdlineTests/asm_json_import_invalid_value/stdin b/test/cmdlineTests/import_asm_json_invalid_value/stdin similarity index 100% rename from test/cmdlineTests/asm_json_import_invalid_value/stdin rename to test/cmdlineTests/import_asm_json_invalid_value/stdin diff --git a/test/cmdlineTests/asm_json_import_missing_subobject_indices/args b/test/cmdlineTests/import_asm_json_missing_subobject_indices/args similarity index 100% rename from test/cmdlineTests/asm_json_import_missing_subobject_indices/args rename to test/cmdlineTests/import_asm_json_missing_subobject_indices/args diff --git a/test/cmdlineTests/asm_json_import_missing_subobject_indices/err b/test/cmdlineTests/import_asm_json_missing_subobject_indices/err similarity index 100% rename from test/cmdlineTests/asm_json_import_missing_subobject_indices/err rename to test/cmdlineTests/import_asm_json_missing_subobject_indices/err diff --git a/test/cmdlineTests/asm_json_import_missing_subobject_indices/exit b/test/cmdlineTests/import_asm_json_missing_subobject_indices/exit similarity index 100% rename from test/cmdlineTests/asm_json_import_missing_subobject_indices/exit rename to test/cmdlineTests/import_asm_json_missing_subobject_indices/exit diff --git a/test/cmdlineTests/asm_json_import_missing_subobject_indices/stdin b/test/cmdlineTests/import_asm_json_missing_subobject_indices/stdin similarity index 100% rename from test/cmdlineTests/asm_json_import_missing_subobject_indices/stdin rename to test/cmdlineTests/import_asm_json_missing_subobject_indices/stdin diff --git a/test/cmdlineTests/asm_json_import_no_value/args b/test/cmdlineTests/import_asm_json_no_value/args similarity index 100% rename from test/cmdlineTests/asm_json_import_no_value/args rename to test/cmdlineTests/import_asm_json_no_value/args diff --git a/test/cmdlineTests/asm_json_import_no_value/err b/test/cmdlineTests/import_asm_json_no_value/err similarity index 100% rename from test/cmdlineTests/asm_json_import_no_value/err rename to test/cmdlineTests/import_asm_json_no_value/err diff --git a/test/cmdlineTests/asm_json_import_no_value/exit b/test/cmdlineTests/import_asm_json_no_value/exit similarity index 100% rename from test/cmdlineTests/asm_json_import_no_value/exit rename to test/cmdlineTests/import_asm_json_no_value/exit diff --git a/test/cmdlineTests/asm_json_import_no_value/stdin b/test/cmdlineTests/import_asm_json_no_value/stdin similarity index 100% rename from test/cmdlineTests/asm_json_import_no_value/stdin rename to test/cmdlineTests/import_asm_json_no_value/stdin diff --git a/test/cmdlineTests/asm_json_import_non_unique_sources/args b/test/cmdlineTests/import_asm_json_non_unique_sources/args similarity index 100% rename from test/cmdlineTests/asm_json_import_non_unique_sources/args rename to test/cmdlineTests/import_asm_json_non_unique_sources/args diff --git a/test/cmdlineTests/asm_json_import_non_unique_sources/err b/test/cmdlineTests/import_asm_json_non_unique_sources/err similarity index 100% rename from test/cmdlineTests/asm_json_import_non_unique_sources/err rename to test/cmdlineTests/import_asm_json_non_unique_sources/err diff --git a/test/cmdlineTests/asm_json_import_non_unique_sources/exit b/test/cmdlineTests/import_asm_json_non_unique_sources/exit similarity index 100% rename from test/cmdlineTests/asm_json_import_non_unique_sources/exit rename to test/cmdlineTests/import_asm_json_non_unique_sources/exit diff --git a/test/cmdlineTests/asm_json_import_non_unique_sources/stdin b/test/cmdlineTests/import_asm_json_non_unique_sources/stdin similarity index 100% rename from test/cmdlineTests/asm_json_import_non_unique_sources/stdin rename to test/cmdlineTests/import_asm_json_non_unique_sources/stdin diff --git a/test/cmdlineTests/asm_json_import_optimize_not_supported/args b/test/cmdlineTests/import_asm_json_optimize_not_supported/args similarity index 100% rename from test/cmdlineTests/asm_json_import_optimize_not_supported/args rename to test/cmdlineTests/import_asm_json_optimize_not_supported/args diff --git a/test/cmdlineTests/asm_json_import_optimize_not_supported/err b/test/cmdlineTests/import_asm_json_optimize_not_supported/err similarity index 100% rename from test/cmdlineTests/asm_json_import_optimize_not_supported/err rename to test/cmdlineTests/import_asm_json_optimize_not_supported/err diff --git a/test/cmdlineTests/asm_json_import_optimize_not_supported/exit b/test/cmdlineTests/import_asm_json_optimize_not_supported/exit similarity index 100% rename from test/cmdlineTests/asm_json_import_optimize_not_supported/exit rename to test/cmdlineTests/import_asm_json_optimize_not_supported/exit diff --git a/test/cmdlineTests/asm_json_import_optimize_not_supported/stdin b/test/cmdlineTests/import_asm_json_optimize_not_supported/stdin similarity index 100% rename from test/cmdlineTests/asm_json_import_optimize_not_supported/stdin rename to test/cmdlineTests/import_asm_json_optimize_not_supported/stdin diff --git a/test/cmdlineTests/asm_json_import_out_of_range_data_index/args b/test/cmdlineTests/import_asm_json_out_of_range_data_index/args similarity index 100% rename from test/cmdlineTests/asm_json_import_out_of_range_data_index/args rename to test/cmdlineTests/import_asm_json_out_of_range_data_index/args diff --git a/test/cmdlineTests/asm_json_import_out_of_range_data_index/err b/test/cmdlineTests/import_asm_json_out_of_range_data_index/err similarity index 100% rename from test/cmdlineTests/asm_json_import_out_of_range_data_index/err rename to test/cmdlineTests/import_asm_json_out_of_range_data_index/err diff --git a/test/cmdlineTests/asm_json_import_out_of_range_data_index/exit b/test/cmdlineTests/import_asm_json_out_of_range_data_index/exit similarity index 100% rename from test/cmdlineTests/asm_json_import_out_of_range_data_index/exit rename to test/cmdlineTests/import_asm_json_out_of_range_data_index/exit diff --git a/test/cmdlineTests/asm_json_import_out_of_range_data_index/stdin b/test/cmdlineTests/import_asm_json_out_of_range_data_index/stdin similarity index 100% rename from test/cmdlineTests/asm_json_import_out_of_range_data_index/stdin rename to test/cmdlineTests/import_asm_json_out_of_range_data_index/stdin diff --git a/test/cmdlineTests/asm_json_import_random_order_data_index/args b/test/cmdlineTests/import_asm_json_random_order_data_index/args similarity index 100% rename from test/cmdlineTests/asm_json_import_random_order_data_index/args rename to test/cmdlineTests/import_asm_json_random_order_data_index/args diff --git a/test/cmdlineTests/asm_json_import_random_order_data_index/output b/test/cmdlineTests/import_asm_json_random_order_data_index/output similarity index 100% rename from test/cmdlineTests/asm_json_import_random_order_data_index/output rename to test/cmdlineTests/import_asm_json_random_order_data_index/output diff --git a/test/cmdlineTests/asm_json_import_random_order_data_index/stdin b/test/cmdlineTests/import_asm_json_random_order_data_index/stdin similarity index 100% rename from test/cmdlineTests/asm_json_import_random_order_data_index/stdin rename to test/cmdlineTests/import_asm_json_random_order_data_index/stdin diff --git a/test/cmdlineTests/asm_json_import_unrecognized_field/args b/test/cmdlineTests/import_asm_json_unrecognized_field/args similarity index 100% rename from test/cmdlineTests/asm_json_import_unrecognized_field/args rename to test/cmdlineTests/import_asm_json_unrecognized_field/args diff --git a/test/cmdlineTests/asm_json_import_unrecognized_field/err b/test/cmdlineTests/import_asm_json_unrecognized_field/err similarity index 100% rename from test/cmdlineTests/asm_json_import_unrecognized_field/err rename to test/cmdlineTests/import_asm_json_unrecognized_field/err diff --git a/test/cmdlineTests/asm_json_import_unrecognized_field/exit b/test/cmdlineTests/import_asm_json_unrecognized_field/exit similarity index 100% rename from test/cmdlineTests/asm_json_import_unrecognized_field/exit rename to test/cmdlineTests/import_asm_json_unrecognized_field/exit diff --git a/test/cmdlineTests/asm_json_import_unrecognized_field/stdin b/test/cmdlineTests/import_asm_json_unrecognized_field/stdin similarity index 100% rename from test/cmdlineTests/asm_json_import_unrecognized_field/stdin rename to test/cmdlineTests/import_asm_json_unrecognized_field/stdin diff --git a/test/cmdlineTests/asm_json_import_untagged_jumpdest/args b/test/cmdlineTests/import_asm_json_untagged_jumpdest/args similarity index 100% rename from test/cmdlineTests/asm_json_import_untagged_jumpdest/args rename to test/cmdlineTests/import_asm_json_untagged_jumpdest/args diff --git a/test/cmdlineTests/asm_json_import_untagged_jumpdest/err b/test/cmdlineTests/import_asm_json_untagged_jumpdest/err similarity index 100% rename from test/cmdlineTests/asm_json_import_untagged_jumpdest/err rename to test/cmdlineTests/import_asm_json_untagged_jumpdest/err diff --git a/test/cmdlineTests/asm_json_import_untagged_jumpdest/exit b/test/cmdlineTests/import_asm_json_untagged_jumpdest/exit similarity index 100% rename from test/cmdlineTests/asm_json_import_untagged_jumpdest/exit rename to test/cmdlineTests/import_asm_json_untagged_jumpdest/exit diff --git a/test/cmdlineTests/asm_json_import_untagged_jumpdest/stdin b/test/cmdlineTests/import_asm_json_untagged_jumpdest/stdin similarity index 100% rename from test/cmdlineTests/asm_json_import_untagged_jumpdest/stdin rename to test/cmdlineTests/import_asm_json_untagged_jumpdest/stdin diff --git a/test/cmdlineTests/asm_json_import_verbatim/args b/test/cmdlineTests/import_asm_json_verbatim/args similarity index 100% rename from test/cmdlineTests/asm_json_import_verbatim/args rename to test/cmdlineTests/import_asm_json_verbatim/args diff --git a/test/cmdlineTests/asm_json_import_verbatim/output b/test/cmdlineTests/import_asm_json_verbatim/output similarity index 100% rename from test/cmdlineTests/asm_json_import_verbatim/output rename to test/cmdlineTests/import_asm_json_verbatim/output diff --git a/test/cmdlineTests/asm_json_import_verbatim/stdin b/test/cmdlineTests/import_asm_json_verbatim/stdin similarity index 100% rename from test/cmdlineTests/asm_json_import_verbatim/stdin rename to test/cmdlineTests/import_asm_json_verbatim/stdin diff --git a/test/cmdlineTests/asm_json_import_yul_more_subobjects/args b/test/cmdlineTests/import_asm_json_yul_more_subobjects/args similarity index 100% rename from test/cmdlineTests/asm_json_import_yul_more_subobjects/args rename to test/cmdlineTests/import_asm_json_yul_more_subobjects/args diff --git a/test/cmdlineTests/asm_json_import_yul_more_subobjects/output b/test/cmdlineTests/import_asm_json_yul_more_subobjects/output similarity index 100% rename from test/cmdlineTests/asm_json_import_yul_more_subobjects/output rename to test/cmdlineTests/import_asm_json_yul_more_subobjects/output diff --git a/test/cmdlineTests/asm_json_import_yul_more_subobjects/stdin b/test/cmdlineTests/import_asm_json_yul_more_subobjects/stdin similarity index 100% rename from test/cmdlineTests/asm_json_import_yul_more_subobjects/stdin rename to test/cmdlineTests/import_asm_json_yul_more_subobjects/stdin diff --git a/test/cmdlineTests/asm_json_import_yul_subobjects/args b/test/cmdlineTests/import_asm_json_yul_subobjects/args similarity index 100% rename from test/cmdlineTests/asm_json_import_yul_subobjects/args rename to test/cmdlineTests/import_asm_json_yul_subobjects/args diff --git a/test/cmdlineTests/asm_json_import_yul_subobjects/output b/test/cmdlineTests/import_asm_json_yul_subobjects/output similarity index 100% rename from test/cmdlineTests/asm_json_import_yul_subobjects/output rename to test/cmdlineTests/import_asm_json_yul_subobjects/output diff --git a/test/cmdlineTests/asm_json_import_yul_subobjects/stdin b/test/cmdlineTests/import_asm_json_yul_subobjects/stdin similarity index 100% rename from test/cmdlineTests/asm_json_import_yul_subobjects/stdin rename to test/cmdlineTests/import_asm_json_yul_subobjects/stdin From c5c0bc534ede889a836c6282f85a2d59d209b3d2 Mon Sep 17 00:00:00 2001 From: Alexander Arlt Date: Mon, 8 Apr 2024 11:21:44 +0200 Subject: [PATCH 0143/1022] Rename additional tests. --- .../input.json | 0 .../output.json | 0 .../input.json | 0 .../output.json | 0 .../input.json | 0 .../output.json | 0 .../input.json | 0 .../output.json | 0 .../input.json | 0 .../output.json | 0 .../input.json | 0 .../output.json | 0 .../input.json | 0 .../output.json | 0 .../input.json | 0 .../output.json | 0 .../input.json | 0 .../output.json | 0 .../input.json | 0 .../output.json | 0 .../input.json | 0 .../output.json | 0 22 files changed, 0 insertions(+), 0 deletions(-) rename test/cmdlineTests/{standard_import_evmasm => standard_import_asm_json}/input.json (100%) rename test/cmdlineTests/{standard_import_evmasm => standard_import_asm_json}/output.json (100%) rename test/cmdlineTests/{standard_import_evmasm_immutable_references => standard_import_asm_json_immutable_references}/input.json (100%) rename test/cmdlineTests/{standard_import_evmasm_immutable_references => standard_import_asm_json_immutable_references}/output.json (100%) rename test/cmdlineTests/{standard_import_evmasm_invalid_input_array => standard_import_asm_json_invalid_input_array}/input.json (100%) rename test/cmdlineTests/{standard_import_evmasm_invalid_input_array => standard_import_asm_json_invalid_input_array}/output.json (100%) rename test/cmdlineTests/{standard_import_evmasm_invalid_key_inside_source => standard_import_asm_json_invalid_key_inside_source}/input.json (100%) rename test/cmdlineTests/{standard_import_evmasm_invalid_key_inside_source => standard_import_asm_json_invalid_key_inside_source}/output.json (100%) rename test/cmdlineTests/{standard_import_evmasm_invalid_key_other_source => standard_import_asm_json_invalid_key_other_source}/input.json (100%) rename test/cmdlineTests/{standard_import_evmasm_invalid_key_other_source => standard_import_asm_json_invalid_key_other_source}/output.json (100%) rename test/cmdlineTests/{standard_import_evmasm_invalid_no_source => standard_import_asm_json_invalid_no_source}/input.json (100%) rename test/cmdlineTests/{standard_import_evmasm_invalid_no_source => standard_import_asm_json_invalid_no_source}/output.json (100%) rename test/cmdlineTests/{standard_import_evmasm_invalid_opcode => standard_import_asm_json_invalid_opcode}/input.json (100%) rename test/cmdlineTests/{standard_import_evmasm_invalid_opcode => standard_import_asm_json_invalid_opcode}/output.json (100%) rename test/cmdlineTests/{standard_import_evmasm_invalid_two_sources => standard_import_asm_json_invalid_two_sources}/input.json (100%) rename test/cmdlineTests/{standard_import_evmasm_invalid_two_sources => standard_import_asm_json_invalid_two_sources}/output.json (100%) rename test/cmdlineTests/{standard_import_evmasm_link_references => standard_import_asm_json_link_references}/input.json (100%) rename test/cmdlineTests/{standard_import_evmasm_link_references => standard_import_asm_json_link_references}/output.json (100%) rename test/cmdlineTests/{standard_import_evmasm_multiple_keys_inside_source => standard_import_asm_json_multiple_keys_inside_source}/input.json (100%) rename test/cmdlineTests/{standard_import_evmasm_multiple_keys_inside_source => standard_import_asm_json_multiple_keys_inside_source}/output.json (100%) rename test/cmdlineTests/{standard_import_evmasm_no_output_selection => standard_import_asm_json_no_output_selection}/input.json (100%) rename test/cmdlineTests/{standard_import_evmasm_no_output_selection => standard_import_asm_json_no_output_selection}/output.json (100%) diff --git a/test/cmdlineTests/standard_import_evmasm/input.json b/test/cmdlineTests/standard_import_asm_json/input.json similarity index 100% rename from test/cmdlineTests/standard_import_evmasm/input.json rename to test/cmdlineTests/standard_import_asm_json/input.json diff --git a/test/cmdlineTests/standard_import_evmasm/output.json b/test/cmdlineTests/standard_import_asm_json/output.json similarity index 100% rename from test/cmdlineTests/standard_import_evmasm/output.json rename to test/cmdlineTests/standard_import_asm_json/output.json diff --git a/test/cmdlineTests/standard_import_evmasm_immutable_references/input.json b/test/cmdlineTests/standard_import_asm_json_immutable_references/input.json similarity index 100% rename from test/cmdlineTests/standard_import_evmasm_immutable_references/input.json rename to test/cmdlineTests/standard_import_asm_json_immutable_references/input.json diff --git a/test/cmdlineTests/standard_import_evmasm_immutable_references/output.json b/test/cmdlineTests/standard_import_asm_json_immutable_references/output.json similarity index 100% rename from test/cmdlineTests/standard_import_evmasm_immutable_references/output.json rename to test/cmdlineTests/standard_import_asm_json_immutable_references/output.json diff --git a/test/cmdlineTests/standard_import_evmasm_invalid_input_array/input.json b/test/cmdlineTests/standard_import_asm_json_invalid_input_array/input.json similarity index 100% rename from test/cmdlineTests/standard_import_evmasm_invalid_input_array/input.json rename to test/cmdlineTests/standard_import_asm_json_invalid_input_array/input.json diff --git a/test/cmdlineTests/standard_import_evmasm_invalid_input_array/output.json b/test/cmdlineTests/standard_import_asm_json_invalid_input_array/output.json similarity index 100% rename from test/cmdlineTests/standard_import_evmasm_invalid_input_array/output.json rename to test/cmdlineTests/standard_import_asm_json_invalid_input_array/output.json diff --git a/test/cmdlineTests/standard_import_evmasm_invalid_key_inside_source/input.json b/test/cmdlineTests/standard_import_asm_json_invalid_key_inside_source/input.json similarity index 100% rename from test/cmdlineTests/standard_import_evmasm_invalid_key_inside_source/input.json rename to test/cmdlineTests/standard_import_asm_json_invalid_key_inside_source/input.json diff --git a/test/cmdlineTests/standard_import_evmasm_invalid_key_inside_source/output.json b/test/cmdlineTests/standard_import_asm_json_invalid_key_inside_source/output.json similarity index 100% rename from test/cmdlineTests/standard_import_evmasm_invalid_key_inside_source/output.json rename to test/cmdlineTests/standard_import_asm_json_invalid_key_inside_source/output.json diff --git a/test/cmdlineTests/standard_import_evmasm_invalid_key_other_source/input.json b/test/cmdlineTests/standard_import_asm_json_invalid_key_other_source/input.json similarity index 100% rename from test/cmdlineTests/standard_import_evmasm_invalid_key_other_source/input.json rename to test/cmdlineTests/standard_import_asm_json_invalid_key_other_source/input.json diff --git a/test/cmdlineTests/standard_import_evmasm_invalid_key_other_source/output.json b/test/cmdlineTests/standard_import_asm_json_invalid_key_other_source/output.json similarity index 100% rename from test/cmdlineTests/standard_import_evmasm_invalid_key_other_source/output.json rename to test/cmdlineTests/standard_import_asm_json_invalid_key_other_source/output.json diff --git a/test/cmdlineTests/standard_import_evmasm_invalid_no_source/input.json b/test/cmdlineTests/standard_import_asm_json_invalid_no_source/input.json similarity index 100% rename from test/cmdlineTests/standard_import_evmasm_invalid_no_source/input.json rename to test/cmdlineTests/standard_import_asm_json_invalid_no_source/input.json diff --git a/test/cmdlineTests/standard_import_evmasm_invalid_no_source/output.json b/test/cmdlineTests/standard_import_asm_json_invalid_no_source/output.json similarity index 100% rename from test/cmdlineTests/standard_import_evmasm_invalid_no_source/output.json rename to test/cmdlineTests/standard_import_asm_json_invalid_no_source/output.json diff --git a/test/cmdlineTests/standard_import_evmasm_invalid_opcode/input.json b/test/cmdlineTests/standard_import_asm_json_invalid_opcode/input.json similarity index 100% rename from test/cmdlineTests/standard_import_evmasm_invalid_opcode/input.json rename to test/cmdlineTests/standard_import_asm_json_invalid_opcode/input.json diff --git a/test/cmdlineTests/standard_import_evmasm_invalid_opcode/output.json b/test/cmdlineTests/standard_import_asm_json_invalid_opcode/output.json similarity index 100% rename from test/cmdlineTests/standard_import_evmasm_invalid_opcode/output.json rename to test/cmdlineTests/standard_import_asm_json_invalid_opcode/output.json diff --git a/test/cmdlineTests/standard_import_evmasm_invalid_two_sources/input.json b/test/cmdlineTests/standard_import_asm_json_invalid_two_sources/input.json similarity index 100% rename from test/cmdlineTests/standard_import_evmasm_invalid_two_sources/input.json rename to test/cmdlineTests/standard_import_asm_json_invalid_two_sources/input.json diff --git a/test/cmdlineTests/standard_import_evmasm_invalid_two_sources/output.json b/test/cmdlineTests/standard_import_asm_json_invalid_two_sources/output.json similarity index 100% rename from test/cmdlineTests/standard_import_evmasm_invalid_two_sources/output.json rename to test/cmdlineTests/standard_import_asm_json_invalid_two_sources/output.json diff --git a/test/cmdlineTests/standard_import_evmasm_link_references/input.json b/test/cmdlineTests/standard_import_asm_json_link_references/input.json similarity index 100% rename from test/cmdlineTests/standard_import_evmasm_link_references/input.json rename to test/cmdlineTests/standard_import_asm_json_link_references/input.json diff --git a/test/cmdlineTests/standard_import_evmasm_link_references/output.json b/test/cmdlineTests/standard_import_asm_json_link_references/output.json similarity index 100% rename from test/cmdlineTests/standard_import_evmasm_link_references/output.json rename to test/cmdlineTests/standard_import_asm_json_link_references/output.json diff --git a/test/cmdlineTests/standard_import_evmasm_multiple_keys_inside_source/input.json b/test/cmdlineTests/standard_import_asm_json_multiple_keys_inside_source/input.json similarity index 100% rename from test/cmdlineTests/standard_import_evmasm_multiple_keys_inside_source/input.json rename to test/cmdlineTests/standard_import_asm_json_multiple_keys_inside_source/input.json diff --git a/test/cmdlineTests/standard_import_evmasm_multiple_keys_inside_source/output.json b/test/cmdlineTests/standard_import_asm_json_multiple_keys_inside_source/output.json similarity index 100% rename from test/cmdlineTests/standard_import_evmasm_multiple_keys_inside_source/output.json rename to test/cmdlineTests/standard_import_asm_json_multiple_keys_inside_source/output.json diff --git a/test/cmdlineTests/standard_import_evmasm_no_output_selection/input.json b/test/cmdlineTests/standard_import_asm_json_no_output_selection/input.json similarity index 100% rename from test/cmdlineTests/standard_import_evmasm_no_output_selection/input.json rename to test/cmdlineTests/standard_import_asm_json_no_output_selection/input.json diff --git a/test/cmdlineTests/standard_import_evmasm_no_output_selection/output.json b/test/cmdlineTests/standard_import_asm_json_no_output_selection/output.json similarity index 100% rename from test/cmdlineTests/standard_import_evmasm_no_output_selection/output.json rename to test/cmdlineTests/standard_import_asm_json_no_output_selection/output.json From 0c32ddb0d6130b38b70180c4076fbc8123fb401f Mon Sep 17 00:00:00 2001 From: pcw109550 Date: Mon, 8 Apr 2024 11:48:53 -0600 Subject: [PATCH 0144/1022] Fix error msg for hex number combined with unit denomination --- libsolidity/analysis/TypeChecker.cpp | 2 +- .../denominations/combining_hex_and_denomination.sol | 2 +- .../syntaxTests/denominations/invalid_denomination_address.sol | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp index 5bef2803acb6..0bcab65d932f 100644 --- a/libsolidity/analysis/TypeChecker.cpp +++ b/libsolidity/analysis/TypeChecker.cpp @@ -3874,7 +3874,7 @@ void TypeChecker::endVisit(Literal const& _literal) 5145_error, _literal.location(), "Hexadecimal numbers cannot be used with unit denominations. " - "You can use an expression of the form \"0x1234 * 1 day\" instead." + "You can use an expression of the form \"0x1234 * 1 days\" instead." ); if (_literal.subDenomination() == Literal::SubDenomination::Year) diff --git a/test/libsolidity/syntaxTests/denominations/combining_hex_and_denomination.sol b/test/libsolidity/syntaxTests/denominations/combining_hex_and_denomination.sol index 994c0568a141..f200b135600e 100644 --- a/test/libsolidity/syntaxTests/denominations/combining_hex_and_denomination.sol +++ b/test/libsolidity/syntaxTests/denominations/combining_hex_and_denomination.sol @@ -2,4 +2,4 @@ contract C { uint constant x = 0x01 wei; } // ---- -// TypeError 5145: (32-40): Hexadecimal numbers cannot be used with unit denominations. You can use an expression of the form "0x1234 * 1 day" instead. +// TypeError 5145: (32-40): Hexadecimal numbers cannot be used with unit denominations. You can use an expression of the form "0x1234 * 1 days" instead. diff --git a/test/libsolidity/syntaxTests/denominations/invalid_denomination_address.sol b/test/libsolidity/syntaxTests/denominations/invalid_denomination_address.sol index 8eec22dee3f0..7c1f1e270f08 100644 --- a/test/libsolidity/syntaxTests/denominations/invalid_denomination_address.sol +++ b/test/libsolidity/syntaxTests/denominations/invalid_denomination_address.sol @@ -2,4 +2,4 @@ contract C { address a = 0x11111122222333334444455555666667777788888 wei; } // ---- -// TypeError 5145: (26-73): Hexadecimal numbers cannot be used with unit denominations. You can use an expression of the form "0x1234 * 1 day" instead. +// TypeError 5145: (26-73): Hexadecimal numbers cannot be used with unit denominations. You can use an expression of the form "0x1234 * 1 days" instead. From 8c320419775e8f207a305c85ee40e6d8717c051b Mon Sep 17 00:00:00 2001 From: looklose Date: Wed, 10 Apr 2024 20:42:50 +0800 Subject: [PATCH 0145/1022] chore: fix typo in comment Signed-off-by: looklose --- libsolc/libsolc.h | 2 +- libsolutil/Keccak256.cpp | 2 +- test/libsolidity/AnalysisFramework.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/libsolc/libsolc.h b/libsolc/libsolc.h index c5b3b3db732b..b259ed06a20c 100644 --- a/libsolc/libsolc.h +++ b/libsolc/libsolc.h @@ -45,7 +45,7 @@ extern "C" { /// @param o_error A pointer to an error message, if there is one. /// /// The file (as well as error) contents that is to be allocated by the callback -/// implementor must use the solidity_alloc() API to allocate its underlying +/// implementer must use the solidity_alloc() API to allocate its underlying /// storage. Ownership is then transferred to the compiler which will take care /// of the deallocation. /// diff --git a/libsolutil/Keccak256.cpp b/libsolutil/Keccak256.cpp index c54dedabeb8f..9cf716354a9b 100644 --- a/libsolutil/Keccak256.cpp +++ b/libsolutil/Keccak256.cpp @@ -35,7 +35,7 @@ namespace * * A single-file implementation of SHA-3 and SHAKE. * - * Implementor: David Leon Gil + * implementer: David Leon Gil * License: CC0, attribution kindly requested. Blame taken too, * but not liability. */ diff --git a/test/libsolidity/AnalysisFramework.h b/test/libsolidity/AnalysisFramework.h index e7b2c03ec284..93581a58274e 100644 --- a/test/libsolidity/AnalysisFramework.h +++ b/test/libsolidity/AnalysisFramework.h @@ -200,7 +200,7 @@ CHECK_ERROR_OR_WARNING(text, type, substrings, false, true) #define CHECK_WARNING(text, substring) \ CHECK_ERROR_OR_WARNING(text, Warning, std::vector{(substring)}, true, false) -// [checkWarningAllowMulti(text, substring)] aserts that the compilation down to typechecking +// [checkWarningAllowMulti(text, substring)] asserts that the compilation down to typechecking // emits a warning and with a message containing [substring]. // Because of the limitations of the preprocessor, you cannot use {"abc", "def"} as arguments, // but have to replace them by (std::vector{"abc", "def"}) (note the parentheses) From c2d2143dad57319ecb737aa7033a555bafc618e3 Mon Sep 17 00:00:00 2001 From: Martin Blicha Date: Wed, 3 Apr 2024 21:37:15 +0200 Subject: [PATCH 0146/1022] SMTChecker: Add helper method to check for compatibility of sorts The helper method makes clear the intent clear and should be more readable than if-then-else branches with smtAssertions. Moreover, some of the if-conditions were not checking the right thing. --- libsmtutil/SolverInterface.h | 26 ++++++++++---------------- 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/libsmtutil/SolverInterface.h b/libsmtutil/SolverInterface.h index 82f81113358a..f9a61e2ec81f 100644 --- a/libsmtutil/SolverInterface.h +++ b/libsmtutil/SolverInterface.h @@ -189,10 +189,7 @@ class Expression static Expression ite(Expression _condition, Expression _trueValue, Expression _falseValue) { - if (_trueValue.sort->kind == Kind::Int) - smtAssert(_trueValue.sort->kind == _falseValue.sort->kind, ""); - else - smtAssert(*_trueValue.sort == *_falseValue.sort, ""); + smtAssert(areCompatible(*_trueValue.sort, *_falseValue.sort)); SortPointer sort = _trueValue.sort; return Expression("ite", std::vector{ std::move(_condition), std::move(_trueValue), std::move(_falseValue) @@ -216,10 +213,7 @@ class Expression std::shared_ptr arraySort = std::dynamic_pointer_cast(_array.sort); smtAssert(arraySort, ""); smtAssert(_index.sort, ""); - if (arraySort->domain->kind == Kind::Int) - smtAssert(arraySort->domain->kind == _index.sort->kind, ""); - else - smtAssert(*arraySort->domain == *_index.sort, ""); + smtAssert(areCompatible(*arraySort->domain, *_index.sort)); return Expression( "select", std::vector{std::move(_array), std::move(_index)}, @@ -236,10 +230,7 @@ class Expression smtAssert(_index.sort, ""); smtAssert(_element.sort, ""); smtAssert(*arraySort->domain == *_index.sort, ""); - if (arraySort->domain->kind == Kind::Int) - smtAssert(arraySort->range->kind == _element.sort->kind, ""); - else - smtAssert(*arraySort->range == *_element.sort, ""); + smtAssert(areCompatible(*arraySort->range, *_element.sort)); return Expression( "store", std::vector{std::move(_array), std::move(_index), std::move(_element)}, @@ -254,10 +245,7 @@ class Expression auto arraySort = std::dynamic_pointer_cast(sortSort->inner); smtAssert(sortSort && arraySort, ""); smtAssert(_value.sort, ""); - if (arraySort->domain->kind == Kind::Int) - smtAssert(arraySort->range->kind == _value.sort->kind, ""); - else - smtAssert(*arraySort->range == *_value.sort, ""); + smtAssert(areCompatible(*arraySort->range, *_value.sort)); return Expression( "const_array", std::vector{std::move(_sort), std::move(_value)}, @@ -501,6 +489,12 @@ class Expression SortPointer sort; private: + /// Helper method for checking sort compatibility when creating expressions + /// Signed and unsigned Int sorts are compatible even though they are not same + static bool areCompatible(Sort const& s1, Sort const& s2) + { + return s1.kind == Kind::Int ? s1.kind == s2.kind : s1 == s2; + } /// Manual constructors, should only be used by SolverInterface and this class itself. Expression(std::string _name, std::vector _arguments, Kind _kind): Expression(std::move(_name), std::move(_arguments), std::make_shared(_kind)) {} From 60240b489447824c16b54f893a9b76d0ee5678f3 Mon Sep 17 00:00:00 2001 From: Martin Blicha Date: Wed, 3 Apr 2024 21:41:58 +0200 Subject: [PATCH 0147/1022] SMTChecker: Relax assertion for creating array store expression --- libsmtutil/SolverInterface.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libsmtutil/SolverInterface.h b/libsmtutil/SolverInterface.h index f9a61e2ec81f..13803de6e91a 100644 --- a/libsmtutil/SolverInterface.h +++ b/libsmtutil/SolverInterface.h @@ -229,7 +229,7 @@ class Expression smtAssert(arraySort, ""); smtAssert(_index.sort, ""); smtAssert(_element.sort, ""); - smtAssert(*arraySort->domain == *_index.sort, ""); + smtAssert(areCompatible(*arraySort->domain, *_index.sort)); smtAssert(areCompatible(*arraySort->range, *_element.sort)); return Expression( "store", From e74472c77d1b8a714c23df14175b0e95aabdfe43 Mon Sep 17 00:00:00 2001 From: Martin Blicha Date: Wed, 3 Apr 2024 21:50:46 +0200 Subject: [PATCH 0148/1022] SMTChecker: Add regression test --- ...pping_integer_signedness_compatibility.sol | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 test/libsolidity/smtCheckerTests/types/mapping_integer_signedness_compatibility.sol diff --git a/test/libsolidity/smtCheckerTests/types/mapping_integer_signedness_compatibility.sol b/test/libsolidity/smtCheckerTests/types/mapping_integer_signedness_compatibility.sol new file mode 100644 index 000000000000..a05c8d3e1b3a --- /dev/null +++ b/test/libsolidity/smtCheckerTests/types/mapping_integer_signedness_compatibility.sol @@ -0,0 +1,25 @@ +// SPDX-License-Identifier: GPL-3.0 + + +// Regression for handling signedness, see issue #14792 +contract C { + mapping(int => int) v1; + mapping(int => uint) v2; + mapping(uint => int) v3; + mapping(uint => uint) v4; + mapping(bytes12 => int) v5; + uint[5] a1; + int[5] a2; + + function f() public { + delete v1[0]; + delete v2[0]; + delete v3[0]; + delete v4[0]; + delete v5[0]; + delete a1[0]; + delete a2[0]; + } +} +// ---- +// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. From 0c831e0995fde6aed98c77b8ea6f72c80c941867 Mon Sep 17 00:00:00 2001 From: Martin Blicha Date: Fri, 12 Apr 2024 09:56:32 +0200 Subject: [PATCH 0149/1022] Add a changelog entry about a fixed ICE in SMTChecker --- Changelog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/Changelog.md b/Changelog.md index c915a1ecfe95..ccc2de41a6ce 100644 --- a/Changelog.md +++ b/Changelog.md @@ -7,6 +7,7 @@ Compiler Features: Bugfixes: + * SMTChecker: Fix internal error on mapping access caused by too strong requirements on sort compatibility of the index and mapping domain. * SMTChecker: Fix internal error when using bitwise operators with an array element as argument. From b958d80eaaebb697c962462e42f7769155211e36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Fri, 12 Apr 2024 14:27:53 +0200 Subject: [PATCH 0150/1022] gas_diff_stats: Use argparse and adjust description to work better with it --- scripts/gas_diff_stats.py | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/scripts/gas_diff_stats.py b/scripts/gas_diff_stats.py index e593bb9a9746..8736e21d781c 100755 --- a/scripts/gas_diff_stats.py +++ b/scripts/gas_diff_stats.py @@ -1,26 +1,21 @@ #!/usr/bin/env python3 -"""A script to collect gas statistics and print it. +"""Summarizes gas differences from semantic test diff. -Useful to summarize gas differences to semantic tests for a PR / branch. +The script collects all gas differences present in git diff of semantic tests +and summarizes them in the form of a table that's ready to post in a GitHub comment. +The diff is calculated against the `origin/develop` branch. +Only changes that are already committed are taken into account. +Changes that are only staged or not staged or committed at all are ignored. -Dependencies: Parsec (https://pypi.org/project/parsec/) and Tabulate -(https://pypi.org/project/tabulate/) - - pip install parsec tabulate - -Run from root project dir. - - python3 scripts/gas_diff_stats.py - -Note that the changes to semantic tests have to be committed. - -Assumes that there is a remote named ``origin`` pointing to the Solidity github -repository. The changes are compared against ``origin/develop``. +Useful for reviewing the gas impact of a specific PR / branch. +Instead of tediously going through each individual change, it's recommended to review the table. +Dependencies: parsec, tabulate """ import subprocess import sys +from argparse import ArgumentParser, RawDescriptionHelpFormatter from pathlib import Path from enum import Enum from parsec import generate, ParseError, regex, string, optional @@ -170,6 +165,9 @@ def stat(old, new): print("No differences found.") def main(): + parser = ArgumentParser(description=__doc__, formatter_class=RawDescriptionHelpFormatter) + options = parser.parse_args() + try: semantictest_statistics() except subprocess.CalledProcessError as exception: From 42aa58aa36c3f2ef1dcde1e3e2d4d185b076e6a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Fri, 12 Apr 2024 15:29:11 +0200 Subject: [PATCH 0151/1022] gas_diff_stats: Base branch option --- scripts/gas_diff_stats.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/scripts/gas_diff_stats.py b/scripts/gas_diff_stats.py index 8736e21d781c..ecb4cc912a4e 100755 --- a/scripts/gas_diff_stats.py +++ b/scripts/gas_diff_stats.py @@ -3,7 +3,6 @@ The script collects all gas differences present in git diff of semantic tests and summarizes them in the form of a table that's ready to post in a GitHub comment. -The diff is calculated against the `origin/develop` branch. Only changes that are already committed are taken into account. Changes that are only staged or not staged or committed at all are ignored. @@ -100,11 +99,11 @@ def collect_statistics(lines) -> (int, int, int, int, int, int): for _codegen_kind in codegen_kinds ) -def semantictest_statistics(): +def semantictest_statistics(base_branch: str): """Prints the tabulated statistics that can be pasted in github.""" def parse_git_diff(fname): diff_output = subprocess.check_output( - ["git", "diff", "--unified=0", "origin/develop", "HEAD", fname], + ["git", "diff", "--unified=0", base_branch, "HEAD", fname], universal_newlines=True ).splitlines() if len(diff_output) == 0: @@ -166,10 +165,16 @@ def stat(old, new): def main(): parser = ArgumentParser(description=__doc__, formatter_class=RawDescriptionHelpFormatter) + parser.add_argument( + '--base', + dest='base_branch', + default='origin/develop', + help='The base branch to diff against. default: origin/develop', + ) options = parser.parse_args() try: - semantictest_statistics() + semantictest_statistics(options.base_branch) except subprocess.CalledProcessError as exception: sys.exit(f"Error in the git diff:\n{exception.output}") except ParseError as exception: From 54e425236d47a0bbab658bb55d3bf5d3b4565a65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Fri, 12 Apr 2024 23:10:36 +0200 Subject: [PATCH 0152/1022] Clean up tab/space mix and tabs used for alignment --- CODING_STYLE.md | 2 +- cmake/EthCompilerSettings.cmake | 34 +- cmake/EthDependencies.cmake | 6 +- docs/grammar/SolidityParser.g4 | 4 +- libevmasm/AssemblyItem.cpp | 2 +- libevmasm/Instruction.cpp | 300 ++++++++-------- libevmasm/Instruction.h | 334 +++++++++--------- liblangutil/Token.h | 16 +- libsmtutil/CHCSmtLib2Interface.cpp | 2 +- libsolidity/analysis/TypeChecker.cpp | 2 +- libsolidity/ast/ASTAnnotations.h | 4 +- libsolidity/ast/Types.cpp | 2 +- libsolidity/codegen/ExpressionCompiler.cpp | 2 +- .../experimental/codegen/IRGenerator.cpp | 15 +- .../experimental/codegen/IRGenerator.h | 4 +- libsolidity/formal/BMC.cpp | 4 +- libsolidity/formal/SMTEncoder.h | 2 +- libsolutil/FixedHash.h | 2 +- libsolutil/Result.h | 6 +- libyul/YulString.h | 2 +- .../backends/evm/ControlFlowGraphBuilder.cpp | 2 +- libyul/backends/evm/EVMDialect.cpp | 36 +- libyul/backends/evm/StackLayoutGenerator.cpp | 2 +- libyul/optimiser/ExpressionJoiner.h | 6 +- libyul/optimiser/SSAReverser.h | 34 +- scripts/release_ppa.sh | 4 +- test/EVMHost.cpp | 2 +- test/InteractiveTests.h | 42 +-- .../model_checker_contracts_all/input.sol | 6 +- .../input.json | 4 +- .../input.json | 4 +- .../input.json | 28 +- .../standard_wrong_key_metadata/input.json | 14 +- .../standard_wrong_key_optimizer/input.json | 14 +- .../standard_wrong_key_settings/input.json | 40 +-- test/libevmasm/Optimiser.cpp | 4 +- test/libsolidity/SemanticTest.cpp | 2 +- test/libsolidity/SolidityEndToEndTest.cpp | 36 +- test/libsolidity/SolidityOptimizer.cpp | 4 +- test/libsolidity/StandardCompiler.cpp | 2 +- .../dev_multiple_params_mixed_whitespace.sol | 6 +- .../functions/functions_library_internal.sol | 2 +- .../loops/do_while_bmc_iterations_break_6.sol | 2 +- .../loops/do_while_bmc_iterations_break_7.sol | 4 +- ..._while_bmc_iterations_break_continue_1.sol | 4 +- ..._while_bmc_iterations_break_continue_2.sol | 4 +- .../loops/for_loop_bmc_iterations_break_2.sol | 2 +- .../loops/for_loop_bmc_iterations_break_8.sol | 2 +- .../loops/for_loop_bmc_iterations_break_9.sol | 2 +- ...r_loop_bmc_iterations_break_continue_1.sol | 4 +- ...r_loop_bmc_iterations_break_continue_2.sol | 2 +- ...r_loop_bmc_iterations_break_continue_3.sol | 2 +- .../for_loop_bmc_iterations_continue_3.sol | 2 +- .../loops/while_bmc_iterations_8.sol | 2 +- .../loops/while_bmc_iterations_break_4.sol | 2 +- .../loops/while_bmc_iterations_break_6.sol | 2 +- .../loops/while_bmc_iterations_break_7.sol | 4 +- .../while_bmc_iterations_break_continue_1.sol | 4 +- .../while_bmc_iterations_break_continue_2.sol | 4 +- .../while_bmc_iterations_semantics_2.sol | 2 +- .../operators/delete_multid_array.sol | 8 +- .../util/TestFunctionCallTests.cpp | 2 +- test/libyul/Parser.cpp | 8 +- test/libyul/StackShufflingTest.cpp | 24 +- test/libyul/YulOptimizerTestCommon.cpp | 2 +- .../nested_different_names.yul | 8 +- .../nested_same_name.yul | 8 +- .../expressionSimplifier/return_vars_zero.yul | 2 +- .../static_array_slot_computation.yul | 8 +- test/tools/ossfuzz/protoToAbiV2.cpp | 6 +- test/tools/ossfuzz/protoToAbiV2.h | 200 +++++------ test/tools/ossfuzz/protoToYul.h | 8 +- 72 files changed, 686 insertions(+), 687 deletions(-) diff --git a/CODING_STYLE.md b/CODING_STYLE.md index 5b9129fbd07b..2305ae1ec752 100644 --- a/CODING_STYLE.md +++ b/CODING_STYLE.md @@ -20,7 +20,7 @@ Yes: ```cpp if (a == b[i]) - printf("Hello\n"); // NOTE spaces used instead of tab here for clarity - first byte should be '\t'. + printf("Hello\n"); // NOTE spaces used instead of tab here for clarity - first byte should be '\t'. foo->bar( someLongVariableName, anotherLongVariableName, diff --git a/cmake/EthCompilerSettings.cmake b/cmake/EthCompilerSettings.cmake index 6cfa864c1d1a..5c2802d1fe20 100644 --- a/cmake/EthCompilerSettings.cmake +++ b/cmake/EthCompilerSettings.cmake @@ -171,25 +171,25 @@ elseif (DEFINED MSVC) # CMAKE_CXX_FLAGS_RELWITHDEBINFO for GCC/Clang does not include NDEBUG string(REPLACE "/DNDEBUG" " " CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO}") - add_compile_options(/MP) # enable parallel compilation - add_compile_options(/EHsc) # specify Exception Handling Model in msvc + add_compile_options(/MP) # enable parallel compilation + add_compile_options(/EHsc) # specify Exception Handling Model in msvc if(PEDANTIC) - add_compile_options(/WX) # enable warnings-as-errors + add_compile_options(/WX) # enable warnings-as-errors endif() - add_compile_options(/wd4068) # disable unknown pragma warning (4068) - add_compile_options(/wd4996) # disable unsafe function warning (4996) - add_compile_options(/wd4503) # disable decorated name length exceeded, name was truncated (4503) - add_compile_options(/wd4267) # disable conversion from 'size_t' to 'type', possible loss of data (4267) - add_compile_options(/wd4180) # disable qualifier applied to function type has no meaning; ignored (4180) - add_compile_options(/wd4290) # disable C++ exception specification ignored except to indicate a function is not __declspec(nothrow) (4290) - add_compile_options(/wd4244) # disable conversion from 'type1' to 'type2', possible loss of data (4244) - add_compile_options(/wd4800) # disable forcing value to bool 'true' or 'false' (performance warning) (4800) - add_compile_options(-D_WIN32_WINNT=0x0600) # declare Windows Vista API requirement - add_compile_options(-DNOMINMAX) # undefine windows.h MAX && MIN macros cause it cause conflicts with std::min && std::max functions - add_compile_options(/utf-8) # enable utf-8 encoding (solves warning 4819) - add_compile_options(-DBOOST_REGEX_NO_LIB) # disable automatic boost::regex library selection - add_compile_options(-D_REGEX_MAX_STACK_COUNT=200000L) # increase std::regex recursion depth limit - add_compile_options(/permissive-) # specify standards conformance mode to the compiler + add_compile_options(/wd4068) # disable unknown pragma warning (4068) + add_compile_options(/wd4996) # disable unsafe function warning (4996) + add_compile_options(/wd4503) # disable decorated name length exceeded, name was truncated (4503) + add_compile_options(/wd4267) # disable conversion from 'size_t' to 'type', possible loss of data (4267) + add_compile_options(/wd4180) # disable qualifier applied to function type has no meaning; ignored (4180) + add_compile_options(/wd4290) # disable C++ exception specification ignored except to indicate a function is not __declspec(nothrow) (4290) + add_compile_options(/wd4244) # disable conversion from 'type1' to 'type2', possible loss of data (4244) + add_compile_options(/wd4800) # disable forcing value to bool 'true' or 'false' (performance warning) (4800) + add_compile_options(-D_WIN32_WINNT=0x0600) # declare Windows Vista API requirement + add_compile_options(-DNOMINMAX) # undefine windows.h MAX && MIN macros cause it cause conflicts with std::min && std::max functions + add_compile_options(/utf-8) # enable utf-8 encoding (solves warning 4819) + add_compile_options(-DBOOST_REGEX_NO_LIB) # disable automatic boost::regex library selection + add_compile_options(-D_REGEX_MAX_STACK_COUNT=200000L) # increase std::regex recursion depth limit + add_compile_options(/permissive-) # specify standards conformance mode to the compiler # disable empty object file warning set(CMAKE_STATIC_LINKER_FLAGS "${CMAKE_STATIC_LINKER_FLAGS} /ignore:4221") diff --git a/cmake/EthDependencies.cmake b/cmake/EthDependencies.cmake index 7a84a01d9868..16f30a640d27 100644 --- a/cmake/EthDependencies.cmake +++ b/cmake/EthDependencies.cmake @@ -10,9 +10,9 @@ if (DEFINED MSVC) else() get_filename_component(DEPS_DIR "${CMAKE_CURRENT_LIST_DIR}/../deps/install" ABSOLUTE) set(ETH_DEPENDENCY_INSTALL_DIR - "${DEPS_DIR}/x64" # Old location for deps. - "${DEPS_DIR}/win64" # New location for deps. - "${DEPS_DIR}/win64/Release/share" # LLVM shared cmake files. + "${DEPS_DIR}/x64" # Old location for deps. + "${DEPS_DIR}/win64" # New location for deps. + "${DEPS_DIR}/win64/Release/share" # LLVM shared cmake files. ) endif() set (CMAKE_PREFIX_PATH ${ETH_DEPENDENCY_INSTALL_DIR} ${CMAKE_PREFIX_PATH}) diff --git a/docs/grammar/SolidityParser.g4 b/docs/grammar/SolidityParser.g4 index c46cefd2fa34..e6d3ed7ccaea 100644 --- a/docs/grammar/SolidityParser.g4 +++ b/docs/grammar/SolidityParser.g4 @@ -251,7 +251,7 @@ structMember: type=typeName name=identifier Semicolon; /** * Definition of an enum. Can occur at top-level within a source unit or within a contract, library or interface. */ -enumDefinition: Enum name=identifier LBrace enumValues+=identifier (Comma enumValues+=identifier)* RBrace; +enumDefinition: Enum name=identifier LBrace enumValues+=identifier (Comma enumValues+=identifier)* RBrace; /** * Definition of a user defined value type. Can occur at top-level within a source unit or within a contract, library or interface. */ @@ -400,7 +400,7 @@ expression: | New typeName # NewExpr | tupleExpression # Tuple | inlineArrayExpression # InlineArray - | ( + | ( identifier | literal | literalWithSubDenomination diff --git a/libevmasm/AssemblyItem.cpp b/libevmasm/AssemblyItem.cpp index 2adaa023a13e..c88a9663f3b7 100644 --- a/libevmasm/AssemblyItem.cpp +++ b/libevmasm/AssemblyItem.cpp @@ -127,7 +127,7 @@ size_t AssemblyItem::bytesRequired(size_t _addressLength, Precision _precision) return 1 + std::max(1, numberEncodingSize(data())); case PushSubSize: case PushProgramSize: - return 1 + 4; // worst case: a 16MB program + return 1 + 4; // worst case: a 16MB program case PushTag: case PushData: case PushSub: diff --git a/libevmasm/Instruction.cpp b/libevmasm/Instruction.cpp index ca0dff185ad4..943f34ee4c1f 100644 --- a/libevmasm/Instruction.cpp +++ b/libevmasm/Instruction.cpp @@ -182,156 +182,156 @@ std::map const solidity::evmasm::c_instructions = /// @note InstructionInfo is assumed to be the same across all EVM versions except for the instruction name. static std::map const c_instructionInfo = -{ // Add, Args, Ret, SideEffects, GasPriceTier - { Instruction::STOP, { "STOP", 0, 0, 0, true, Tier::Zero } }, - { Instruction::ADD, { "ADD", 0, 2, 1, false, Tier::VeryLow } }, - { Instruction::SUB, { "SUB", 0, 2, 1, false, Tier::VeryLow } }, - { Instruction::MUL, { "MUL", 0, 2, 1, false, Tier::Low } }, - { Instruction::DIV, { "DIV", 0, 2, 1, false, Tier::Low } }, - { Instruction::SDIV, { "SDIV", 0, 2, 1, false, Tier::Low } }, - { Instruction::MOD, { "MOD", 0, 2, 1, false, Tier::Low } }, - { Instruction::SMOD, { "SMOD", 0, 2, 1, false, Tier::Low } }, - { Instruction::EXP, { "EXP", 0, 2, 1, false, Tier::Special } }, - { Instruction::NOT, { "NOT", 0, 1, 1, false, Tier::VeryLow } }, - { Instruction::LT, { "LT", 0, 2, 1, false, Tier::VeryLow } }, - { Instruction::GT, { "GT", 0, 2, 1, false, Tier::VeryLow } }, - { Instruction::SLT, { "SLT", 0, 2, 1, false, Tier::VeryLow } }, - { Instruction::SGT, { "SGT", 0, 2, 1, false, Tier::VeryLow } }, - { Instruction::EQ, { "EQ", 0, 2, 1, false, Tier::VeryLow } }, - { Instruction::ISZERO, { "ISZERO", 0, 1, 1, false, Tier::VeryLow } }, - { Instruction::AND, { "AND", 0, 2, 1, false, Tier::VeryLow } }, - { Instruction::OR, { "OR", 0, 2, 1, false, Tier::VeryLow } }, - { Instruction::XOR, { "XOR", 0, 2, 1, false, Tier::VeryLow } }, - { Instruction::BYTE, { "BYTE", 0, 2, 1, false, Tier::VeryLow } }, - { Instruction::SHL, { "SHL", 0, 2, 1, false, Tier::VeryLow } }, - { Instruction::SHR, { "SHR", 0, 2, 1, false, Tier::VeryLow } }, - { Instruction::SAR, { "SAR", 0, 2, 1, false, Tier::VeryLow } }, - { Instruction::ADDMOD, { "ADDMOD", 0, 3, 1, false, Tier::Mid } }, - { Instruction::MULMOD, { "MULMOD", 0, 3, 1, false, Tier::Mid } }, - { Instruction::SIGNEXTEND, { "SIGNEXTEND", 0, 2, 1, false, Tier::Low } }, - { Instruction::KECCAK256, { "KECCAK256", 0, 2, 1, true, Tier::Special } }, - { Instruction::ADDRESS, { "ADDRESS", 0, 0, 1, false, Tier::Base } }, - { Instruction::BALANCE, { "BALANCE", 0, 1, 1, false, Tier::Special } }, - { Instruction::ORIGIN, { "ORIGIN", 0, 0, 1, false, Tier::Base } }, - { Instruction::CALLER, { "CALLER", 0, 0, 1, false, Tier::Base } }, - { Instruction::CALLVALUE, { "CALLVALUE", 0, 0, 1, false, Tier::Base } }, - { Instruction::CALLDATALOAD,{ "CALLDATALOAD", 0, 1, 1, false, Tier::VeryLow } }, - { Instruction::CALLDATASIZE,{ "CALLDATASIZE", 0, 0, 1, false, Tier::Base } }, - { Instruction::CALLDATACOPY,{ "CALLDATACOPY", 0, 3, 0, true, Tier::VeryLow } }, - { Instruction::CODESIZE, { "CODESIZE", 0, 0, 1, false, Tier::Base } }, - { Instruction::CODECOPY, { "CODECOPY", 0, 3, 0, true, Tier::VeryLow } }, - { Instruction::GASPRICE, { "GASPRICE", 0, 0, 1, false, Tier::Base } }, - { Instruction::EXTCODESIZE, { "EXTCODESIZE", 0, 1, 1, false, Tier::Special } }, - { Instruction::EXTCODECOPY, { "EXTCODECOPY", 0, 4, 0, true, Tier::Special } }, - { Instruction::RETURNDATASIZE, {"RETURNDATASIZE", 0, 0, 1, false, Tier::Base } }, - { Instruction::RETURNDATACOPY, {"RETURNDATACOPY", 0, 3, 0, true, Tier::VeryLow } }, - { Instruction::MCOPY, { "MCOPY", 0, 3, 0, true, Tier::VeryLow } }, - { Instruction::EXTCODEHASH, { "EXTCODEHASH", 0, 1, 1, false, Tier::Special } }, - { Instruction::BLOCKHASH, { "BLOCKHASH", 0, 1, 1, false, Tier::BlockHash } }, - { Instruction::BLOBHASH, { "BLOBHASH", 0, 1, 1, false, Tier::VeryLow } }, - { Instruction::COINBASE, { "COINBASE", 0, 0, 1, false, Tier::Base } }, - { Instruction::TIMESTAMP, { "TIMESTAMP", 0, 0, 1, false, Tier::Base } }, - { Instruction::NUMBER, { "NUMBER", 0, 0, 1, false, Tier::Base } }, - { Instruction::PREVRANDAO, { "PREVRANDAO", 0, 0, 1, false, Tier::Base } }, - { Instruction::GASLIMIT, { "GASLIMIT", 0, 0, 1, false, Tier::Base } }, - { Instruction::CHAINID, { "CHAINID", 0, 0, 1, false, Tier::Base } }, - { Instruction::SELFBALANCE, { "SELFBALANCE", 0, 0, 1, false, Tier::Low } }, - { Instruction::BASEFEE, { "BASEFEE", 0, 0, 1, false, Tier::Base } }, - { Instruction::BLOBBASEFEE, { "BLOBBASEFEE", 0, 0, 1, false, Tier::Base } }, - { Instruction::POP, { "POP", 0, 1, 0, false, Tier::Base } }, - { Instruction::MLOAD, { "MLOAD", 0, 1, 1, true, Tier::VeryLow } }, - { Instruction::MSTORE, { "MSTORE", 0, 2, 0, true, Tier::VeryLow } }, - { Instruction::MSTORE8, { "MSTORE8", 0, 2, 0, true, Tier::VeryLow } }, - { Instruction::SLOAD, { "SLOAD", 0, 1, 1, false, Tier::Special } }, - { Instruction::SSTORE, { "SSTORE", 0, 2, 0, true, Tier::Special } }, - { Instruction::TLOAD, { "TLOAD", 0, 1, 1, false, Tier::WarmAccess} }, - { Instruction::TSTORE, { "TSTORE", 0, 2, 0, true, Tier::WarmAccess} }, - { Instruction::JUMP, { "JUMP", 0, 1, 0, true, Tier::Mid } }, - { Instruction::JUMPI, { "JUMPI", 0, 2, 0, true, Tier::High } }, - { Instruction::PC, { "PC", 0, 0, 1, false, Tier::Base } }, - { Instruction::MSIZE, { "MSIZE", 0, 0, 1, false, Tier::Base } }, - { Instruction::GAS, { "GAS", 0, 0, 1, false, Tier::Base } }, - { Instruction::JUMPDEST, { "JUMPDEST", 0, 0, 0, true, Tier::Special } }, - { Instruction::PUSH0, { "PUSH0", 0, 0, 1, false, Tier::Base } }, - { Instruction::PUSH1, { "PUSH1", 1, 0, 1, false, Tier::VeryLow } }, - { Instruction::PUSH2, { "PUSH2", 2, 0, 1, false, Tier::VeryLow } }, - { Instruction::PUSH3, { "PUSH3", 3, 0, 1, false, Tier::VeryLow } }, - { Instruction::PUSH4, { "PUSH4", 4, 0, 1, false, Tier::VeryLow } }, - { Instruction::PUSH5, { "PUSH5", 5, 0, 1, false, Tier::VeryLow } }, - { Instruction::PUSH6, { "PUSH6", 6, 0, 1, false, Tier::VeryLow } }, - { Instruction::PUSH7, { "PUSH7", 7, 0, 1, false, Tier::VeryLow } }, - { Instruction::PUSH8, { "PUSH8", 8, 0, 1, false, Tier::VeryLow } }, - { Instruction::PUSH9, { "PUSH9", 9, 0, 1, false, Tier::VeryLow } }, - { Instruction::PUSH10, { "PUSH10", 10, 0, 1, false, Tier::VeryLow } }, - { Instruction::PUSH11, { "PUSH11", 11, 0, 1, false, Tier::VeryLow } }, - { Instruction::PUSH12, { "PUSH12", 12, 0, 1, false, Tier::VeryLow } }, - { Instruction::PUSH13, { "PUSH13", 13, 0, 1, false, Tier::VeryLow } }, - { Instruction::PUSH14, { "PUSH14", 14, 0, 1, false, Tier::VeryLow } }, - { Instruction::PUSH15, { "PUSH15", 15, 0, 1, false, Tier::VeryLow } }, - { Instruction::PUSH16, { "PUSH16", 16, 0, 1, false, Tier::VeryLow } }, - { Instruction::PUSH17, { "PUSH17", 17, 0, 1, false, Tier::VeryLow } }, - { Instruction::PUSH18, { "PUSH18", 18, 0, 1, false, Tier::VeryLow } }, - { Instruction::PUSH19, { "PUSH19", 19, 0, 1, false, Tier::VeryLow } }, - { Instruction::PUSH20, { "PUSH20", 20, 0, 1, false, Tier::VeryLow } }, - { Instruction::PUSH21, { "PUSH21", 21, 0, 1, false, Tier::VeryLow } }, - { Instruction::PUSH22, { "PUSH22", 22, 0, 1, false, Tier::VeryLow } }, - { Instruction::PUSH23, { "PUSH23", 23, 0, 1, false, Tier::VeryLow } }, - { Instruction::PUSH24, { "PUSH24", 24, 0, 1, false, Tier::VeryLow } }, - { Instruction::PUSH25, { "PUSH25", 25, 0, 1, false, Tier::VeryLow } }, - { Instruction::PUSH26, { "PUSH26", 26, 0, 1, false, Tier::VeryLow } }, - { Instruction::PUSH27, { "PUSH27", 27, 0, 1, false, Tier::VeryLow } }, - { Instruction::PUSH28, { "PUSH28", 28, 0, 1, false, Tier::VeryLow } }, - { Instruction::PUSH29, { "PUSH29", 29, 0, 1, false, Tier::VeryLow } }, - { Instruction::PUSH30, { "PUSH30", 30, 0, 1, false, Tier::VeryLow } }, - { Instruction::PUSH31, { "PUSH31", 31, 0, 1, false, Tier::VeryLow } }, - { Instruction::PUSH32, { "PUSH32", 32, 0, 1, false, Tier::VeryLow } }, - { Instruction::DUP1, { "DUP1", 0, 1, 2, false, Tier::VeryLow } }, - { Instruction::DUP2, { "DUP2", 0, 2, 3, false, Tier::VeryLow } }, - { Instruction::DUP3, { "DUP3", 0, 3, 4, false, Tier::VeryLow } }, - { Instruction::DUP4, { "DUP4", 0, 4, 5, false, Tier::VeryLow } }, - { Instruction::DUP5, { "DUP5", 0, 5, 6, false, Tier::VeryLow } }, - { Instruction::DUP6, { "DUP6", 0, 6, 7, false, Tier::VeryLow } }, - { Instruction::DUP7, { "DUP7", 0, 7, 8, false, Tier::VeryLow } }, - { Instruction::DUP8, { "DUP8", 0, 8, 9, false, Tier::VeryLow } }, - { Instruction::DUP9, { "DUP9", 0, 9, 10, false, Tier::VeryLow } }, - { Instruction::DUP10, { "DUP10", 0, 10, 11, false, Tier::VeryLow } }, - { Instruction::DUP11, { "DUP11", 0, 11, 12, false, Tier::VeryLow } }, - { Instruction::DUP12, { "DUP12", 0, 12, 13, false, Tier::VeryLow } }, - { Instruction::DUP13, { "DUP13", 0, 13, 14, false, Tier::VeryLow } }, - { Instruction::DUP14, { "DUP14", 0, 14, 15, false, Tier::VeryLow } }, - { Instruction::DUP15, { "DUP15", 0, 15, 16, false, Tier::VeryLow } }, - { Instruction::DUP16, { "DUP16", 0, 16, 17, false, Tier::VeryLow } }, - { Instruction::SWAP1, { "SWAP1", 0, 2, 2, false, Tier::VeryLow } }, - { Instruction::SWAP2, { "SWAP2", 0, 3, 3, false, Tier::VeryLow } }, - { Instruction::SWAP3, { "SWAP3", 0, 4, 4, false, Tier::VeryLow } }, - { Instruction::SWAP4, { "SWAP4", 0, 5, 5, false, Tier::VeryLow } }, - { Instruction::SWAP5, { "SWAP5", 0, 6, 6, false, Tier::VeryLow } }, - { Instruction::SWAP6, { "SWAP6", 0, 7, 7, false, Tier::VeryLow } }, - { Instruction::SWAP7, { "SWAP7", 0, 8, 8, false, Tier::VeryLow } }, - { Instruction::SWAP8, { "SWAP8", 0, 9, 9, false, Tier::VeryLow } }, - { Instruction::SWAP9, { "SWAP9", 0, 10, 10, false, Tier::VeryLow } }, - { Instruction::SWAP10, { "SWAP10", 0, 11, 11, false, Tier::VeryLow } }, - { Instruction::SWAP11, { "SWAP11", 0, 12, 12, false, Tier::VeryLow } }, - { Instruction::SWAP12, { "SWAP12", 0, 13, 13, false, Tier::VeryLow } }, - { Instruction::SWAP13, { "SWAP13", 0, 14, 14, false, Tier::VeryLow } }, - { Instruction::SWAP14, { "SWAP14", 0, 15, 15, false, Tier::VeryLow } }, - { Instruction::SWAP15, { "SWAP15", 0, 16, 16, false, Tier::VeryLow } }, - { Instruction::SWAP16, { "SWAP16", 0, 17, 17, false, Tier::VeryLow } }, - { Instruction::LOG0, { "LOG0", 0, 2, 0, true, Tier::Special } }, - { Instruction::LOG1, { "LOG1", 0, 3, 0, true, Tier::Special } }, - { Instruction::LOG2, { "LOG2", 0, 4, 0, true, Tier::Special } }, - { Instruction::LOG3, { "LOG3", 0, 5, 0, true, Tier::Special } }, - { Instruction::LOG4, { "LOG4", 0, 6, 0, true, Tier::Special } }, - { Instruction::CREATE, { "CREATE", 0, 3, 1, true, Tier::Special } }, - { Instruction::CALL, { "CALL", 0, 7, 1, true, Tier::Special } }, - { Instruction::CALLCODE, { "CALLCODE", 0, 7, 1, true, Tier::Special } }, - { Instruction::RETURN, { "RETURN", 0, 2, 0, true, Tier::Zero } }, - { Instruction::DELEGATECALL, { "DELEGATECALL", 0, 6, 1, true, Tier::Special } }, - { Instruction::STATICCALL, { "STATICCALL", 0, 6, 1, true, Tier::Special } }, - { Instruction::CREATE2, { "CREATE2", 0, 4, 1, true, Tier::Special } }, - { Instruction::REVERT, { "REVERT", 0, 2, 0, true, Tier::Zero } }, - { Instruction::INVALID, { "INVALID", 0, 0, 0, true, Tier::Zero } }, - { Instruction::SELFDESTRUCT, { "SELFDESTRUCT", 0, 1, 0, true, Tier::Special } } +{ // Add Args Ret SideEffects GasPriceTier + {Instruction::STOP, {"STOP", 0, 0, 0, true, Tier::Zero}}, + {Instruction::ADD, {"ADD", 0, 2, 1, false, Tier::VeryLow}}, + {Instruction::SUB, {"SUB", 0, 2, 1, false, Tier::VeryLow}}, + {Instruction::MUL, {"MUL", 0, 2, 1, false, Tier::Low}}, + {Instruction::DIV, {"DIV", 0, 2, 1, false, Tier::Low}}, + {Instruction::SDIV, {"SDIV", 0, 2, 1, false, Tier::Low}}, + {Instruction::MOD, {"MOD", 0, 2, 1, false, Tier::Low}}, + {Instruction::SMOD, {"SMOD", 0, 2, 1, false, Tier::Low}}, + {Instruction::EXP, {"EXP", 0, 2, 1, false, Tier::Special}}, + {Instruction::NOT, {"NOT", 0, 1, 1, false, Tier::VeryLow}}, + {Instruction::LT, {"LT", 0, 2, 1, false, Tier::VeryLow}}, + {Instruction::GT, {"GT", 0, 2, 1, false, Tier::VeryLow}}, + {Instruction::SLT, {"SLT", 0, 2, 1, false, Tier::VeryLow}}, + {Instruction::SGT, {"SGT", 0, 2, 1, false, Tier::VeryLow}}, + {Instruction::EQ, {"EQ", 0, 2, 1, false, Tier::VeryLow}}, + {Instruction::ISZERO, {"ISZERO", 0, 1, 1, false, Tier::VeryLow}}, + {Instruction::AND, {"AND", 0, 2, 1, false, Tier::VeryLow}}, + {Instruction::OR, {"OR", 0, 2, 1, false, Tier::VeryLow}}, + {Instruction::XOR, {"XOR", 0, 2, 1, false, Tier::VeryLow}}, + {Instruction::BYTE, {"BYTE", 0, 2, 1, false, Tier::VeryLow}}, + {Instruction::SHL, {"SHL", 0, 2, 1, false, Tier::VeryLow}}, + {Instruction::SHR, {"SHR", 0, 2, 1, false, Tier::VeryLow}}, + {Instruction::SAR, {"SAR", 0, 2, 1, false, Tier::VeryLow}}, + {Instruction::ADDMOD, {"ADDMOD", 0, 3, 1, false, Tier::Mid}}, + {Instruction::MULMOD, {"MULMOD", 0, 3, 1, false, Tier::Mid}}, + {Instruction::SIGNEXTEND, {"SIGNEXTEND", 0, 2, 1, false, Tier::Low}}, + {Instruction::KECCAK256, {"KECCAK256", 0, 2, 1, true, Tier::Special}}, + {Instruction::ADDRESS, {"ADDRESS", 0, 0, 1, false, Tier::Base}}, + {Instruction::BALANCE, {"BALANCE", 0, 1, 1, false, Tier::Special}}, + {Instruction::ORIGIN, {"ORIGIN", 0, 0, 1, false, Tier::Base}}, + {Instruction::CALLER, {"CALLER", 0, 0, 1, false, Tier::Base}}, + {Instruction::CALLVALUE, {"CALLVALUE", 0, 0, 1, false, Tier::Base}}, + {Instruction::CALLDATALOAD, {"CALLDATALOAD", 0, 1, 1, false, Tier::VeryLow}}, + {Instruction::CALLDATASIZE, {"CALLDATASIZE", 0, 0, 1, false, Tier::Base}}, + {Instruction::CALLDATACOPY, {"CALLDATACOPY", 0, 3, 0, true, Tier::VeryLow}}, + {Instruction::CODESIZE, {"CODESIZE", 0, 0, 1, false, Tier::Base}}, + {Instruction::CODECOPY, {"CODECOPY", 0, 3, 0, true, Tier::VeryLow}}, + {Instruction::GASPRICE, {"GASPRICE", 0, 0, 1, false, Tier::Base}}, + {Instruction::EXTCODESIZE, {"EXTCODESIZE", 0, 1, 1, false, Tier::Special}}, + {Instruction::EXTCODECOPY, {"EXTCODECOPY", 0, 4, 0, true, Tier::Special}}, + {Instruction::RETURNDATASIZE, {"RETURNDATASIZE", 0, 0, 1, false, Tier::Base}}, + {Instruction::RETURNDATACOPY, {"RETURNDATACOPY", 0, 3, 0, true, Tier::VeryLow}}, + {Instruction::MCOPY, {"MCOPY", 0, 3, 0, true, Tier::VeryLow}}, + {Instruction::EXTCODEHASH, {"EXTCODEHASH", 0, 1, 1, false, Tier::Special}}, + {Instruction::BLOCKHASH, {"BLOCKHASH", 0, 1, 1, false, Tier::BlockHash}}, + {Instruction::BLOBHASH, {"BLOBHASH", 0, 1, 1, false, Tier::VeryLow}}, + {Instruction::COINBASE, {"COINBASE", 0, 0, 1, false, Tier::Base}}, + {Instruction::TIMESTAMP, {"TIMESTAMP", 0, 0, 1, false, Tier::Base}}, + {Instruction::NUMBER, {"NUMBER", 0, 0, 1, false, Tier::Base}}, + {Instruction::PREVRANDAO, {"PREVRANDAO", 0, 0, 1, false, Tier::Base}}, + {Instruction::GASLIMIT, {"GASLIMIT", 0, 0, 1, false, Tier::Base}}, + {Instruction::CHAINID, {"CHAINID", 0, 0, 1, false, Tier::Base}}, + {Instruction::SELFBALANCE, {"SELFBALANCE", 0, 0, 1, false, Tier::Low}}, + {Instruction::BASEFEE, {"BASEFEE", 0, 0, 1, false, Tier::Base}}, + {Instruction::BLOBBASEFEE, {"BLOBBASEFEE", 0, 0, 1, false, Tier::Base}}, + {Instruction::POP, {"POP", 0, 1, 0, false, Tier::Base}}, + {Instruction::MLOAD, {"MLOAD", 0, 1, 1, true, Tier::VeryLow}}, + {Instruction::MSTORE, {"MSTORE", 0, 2, 0, true, Tier::VeryLow}}, + {Instruction::MSTORE8, {"MSTORE8", 0, 2, 0, true, Tier::VeryLow}}, + {Instruction::SLOAD, {"SLOAD", 0, 1, 1, false, Tier::Special}}, + {Instruction::SSTORE, {"SSTORE", 0, 2, 0, true, Tier::Special}}, + {Instruction::TLOAD, {"TLOAD", 0, 1, 1, false, Tier::WarmAccess}}, + {Instruction::TSTORE, {"TSTORE", 0, 2, 0, true, Tier::WarmAccess}}, + {Instruction::JUMP, {"JUMP", 0, 1, 0, true, Tier::Mid}}, + {Instruction::JUMPI, {"JUMPI", 0, 2, 0, true, Tier::High}}, + {Instruction::PC, {"PC", 0, 0, 1, false, Tier::Base}}, + {Instruction::MSIZE, {"MSIZE", 0, 0, 1, false, Tier::Base}}, + {Instruction::GAS, {"GAS", 0, 0, 1, false, Tier::Base}}, + {Instruction::JUMPDEST, {"JUMPDEST", 0, 0, 0, true, Tier::Special}}, + {Instruction::PUSH0, {"PUSH0", 0, 0, 1, false, Tier::Base}}, + {Instruction::PUSH1, {"PUSH1", 1, 0, 1, false, Tier::VeryLow}}, + {Instruction::PUSH2, {"PUSH2", 2, 0, 1, false, Tier::VeryLow}}, + {Instruction::PUSH3, {"PUSH3", 3, 0, 1, false, Tier::VeryLow}}, + {Instruction::PUSH4, {"PUSH4", 4, 0, 1, false, Tier::VeryLow}}, + {Instruction::PUSH5, {"PUSH5", 5, 0, 1, false, Tier::VeryLow}}, + {Instruction::PUSH6, {"PUSH6", 6, 0, 1, false, Tier::VeryLow}}, + {Instruction::PUSH7, {"PUSH7", 7, 0, 1, false, Tier::VeryLow}}, + {Instruction::PUSH8, {"PUSH8", 8, 0, 1, false, Tier::VeryLow}}, + {Instruction::PUSH9, {"PUSH9", 9, 0, 1, false, Tier::VeryLow}}, + {Instruction::PUSH10, {"PUSH10", 10, 0, 1, false, Tier::VeryLow}}, + {Instruction::PUSH11, {"PUSH11", 11, 0, 1, false, Tier::VeryLow}}, + {Instruction::PUSH12, {"PUSH12", 12, 0, 1, false, Tier::VeryLow}}, + {Instruction::PUSH13, {"PUSH13", 13, 0, 1, false, Tier::VeryLow}}, + {Instruction::PUSH14, {"PUSH14", 14, 0, 1, false, Tier::VeryLow}}, + {Instruction::PUSH15, {"PUSH15", 15, 0, 1, false, Tier::VeryLow}}, + {Instruction::PUSH16, {"PUSH16", 16, 0, 1, false, Tier::VeryLow}}, + {Instruction::PUSH17, {"PUSH17", 17, 0, 1, false, Tier::VeryLow}}, + {Instruction::PUSH18, {"PUSH18", 18, 0, 1, false, Tier::VeryLow}}, + {Instruction::PUSH19, {"PUSH19", 19, 0, 1, false, Tier::VeryLow}}, + {Instruction::PUSH20, {"PUSH20", 20, 0, 1, false, Tier::VeryLow}}, + {Instruction::PUSH21, {"PUSH21", 21, 0, 1, false, Tier::VeryLow}}, + {Instruction::PUSH22, {"PUSH22", 22, 0, 1, false, Tier::VeryLow}}, + {Instruction::PUSH23, {"PUSH23", 23, 0, 1, false, Tier::VeryLow}}, + {Instruction::PUSH24, {"PUSH24", 24, 0, 1, false, Tier::VeryLow}}, + {Instruction::PUSH25, {"PUSH25", 25, 0, 1, false, Tier::VeryLow}}, + {Instruction::PUSH26, {"PUSH26", 26, 0, 1, false, Tier::VeryLow}}, + {Instruction::PUSH27, {"PUSH27", 27, 0, 1, false, Tier::VeryLow}}, + {Instruction::PUSH28, {"PUSH28", 28, 0, 1, false, Tier::VeryLow}}, + {Instruction::PUSH29, {"PUSH29", 29, 0, 1, false, Tier::VeryLow}}, + {Instruction::PUSH30, {"PUSH30", 30, 0, 1, false, Tier::VeryLow}}, + {Instruction::PUSH31, {"PUSH31", 31, 0, 1, false, Tier::VeryLow}}, + {Instruction::PUSH32, {"PUSH32", 32, 0, 1, false, Tier::VeryLow}}, + {Instruction::DUP1, {"DUP1", 0, 1, 2, false, Tier::VeryLow}}, + {Instruction::DUP2, {"DUP2", 0, 2, 3, false, Tier::VeryLow}}, + {Instruction::DUP3, {"DUP3", 0, 3, 4, false, Tier::VeryLow}}, + {Instruction::DUP4, {"DUP4", 0, 4, 5, false, Tier::VeryLow}}, + {Instruction::DUP5, {"DUP5", 0, 5, 6, false, Tier::VeryLow}}, + {Instruction::DUP6, {"DUP6", 0, 6, 7, false, Tier::VeryLow}}, + {Instruction::DUP7, {"DUP7", 0, 7, 8, false, Tier::VeryLow}}, + {Instruction::DUP8, {"DUP8", 0, 8, 9, false, Tier::VeryLow}}, + {Instruction::DUP9, {"DUP9", 0, 9, 10, false, Tier::VeryLow}}, + {Instruction::DUP10, {"DUP10", 0, 10, 11, false, Tier::VeryLow}}, + {Instruction::DUP11, {"DUP11", 0, 11, 12, false, Tier::VeryLow}}, + {Instruction::DUP12, {"DUP12", 0, 12, 13, false, Tier::VeryLow}}, + {Instruction::DUP13, {"DUP13", 0, 13, 14, false, Tier::VeryLow}}, + {Instruction::DUP14, {"DUP14", 0, 14, 15, false, Tier::VeryLow}}, + {Instruction::DUP15, {"DUP15", 0, 15, 16, false, Tier::VeryLow}}, + {Instruction::DUP16, {"DUP16", 0, 16, 17, false, Tier::VeryLow}}, + {Instruction::SWAP1, {"SWAP1", 0, 2, 2, false, Tier::VeryLow}}, + {Instruction::SWAP2, {"SWAP2", 0, 3, 3, false, Tier::VeryLow}}, + {Instruction::SWAP3, {"SWAP3", 0, 4, 4, false, Tier::VeryLow}}, + {Instruction::SWAP4, {"SWAP4", 0, 5, 5, false, Tier::VeryLow}}, + {Instruction::SWAP5, {"SWAP5", 0, 6, 6, false, Tier::VeryLow}}, + {Instruction::SWAP6, {"SWAP6", 0, 7, 7, false, Tier::VeryLow}}, + {Instruction::SWAP7, {"SWAP7", 0, 8, 8, false, Tier::VeryLow}}, + {Instruction::SWAP8, {"SWAP8", 0, 9, 9, false, Tier::VeryLow}}, + {Instruction::SWAP9, {"SWAP9", 0, 10, 10, false, Tier::VeryLow}}, + {Instruction::SWAP10, {"SWAP10", 0, 11, 11, false, Tier::VeryLow}}, + {Instruction::SWAP11, {"SWAP11", 0, 12, 12, false, Tier::VeryLow}}, + {Instruction::SWAP12, {"SWAP12", 0, 13, 13, false, Tier::VeryLow}}, + {Instruction::SWAP13, {"SWAP13", 0, 14, 14, false, Tier::VeryLow}}, + {Instruction::SWAP14, {"SWAP14", 0, 15, 15, false, Tier::VeryLow}}, + {Instruction::SWAP15, {"SWAP15", 0, 16, 16, false, Tier::VeryLow}}, + {Instruction::SWAP16, {"SWAP16", 0, 17, 17, false, Tier::VeryLow}}, + {Instruction::LOG0, {"LOG0", 0, 2, 0, true, Tier::Special}}, + {Instruction::LOG1, {"LOG1", 0, 3, 0, true, Tier::Special}}, + {Instruction::LOG2, {"LOG2", 0, 4, 0, true, Tier::Special}}, + {Instruction::LOG3, {"LOG3", 0, 5, 0, true, Tier::Special}}, + {Instruction::LOG4, {"LOG4", 0, 6, 0, true, Tier::Special}}, + {Instruction::CREATE, {"CREATE", 0, 3, 1, true, Tier::Special}}, + {Instruction::CALL, {"CALL", 0, 7, 1, true, Tier::Special}}, + {Instruction::CALLCODE, {"CALLCODE", 0, 7, 1, true, Tier::Special}}, + {Instruction::RETURN, {"RETURN", 0, 2, 0, true, Tier::Zero}}, + {Instruction::DELEGATECALL, {"DELEGATECALL", 0, 6, 1, true, Tier::Special}}, + {Instruction::STATICCALL, {"STATICCALL", 0, 6, 1, true, Tier::Special}}, + {Instruction::CREATE2, {"CREATE2", 0, 4, 1, true, Tier::Special}}, + {Instruction::REVERT, {"REVERT", 0, 2, 0, true, Tier::Zero}}, + {Instruction::INVALID, {"INVALID", 0, 0, 0, true, Tier::Zero}}, + {Instruction::SELFDESTRUCT, {"SELFDESTRUCT", 0, 1, 0, true, Tier::Special}} }; InstructionInfo solidity::evmasm::instructionInfo(Instruction _inst, langutil::EVMVersion _evmVersion) diff --git a/libevmasm/Instruction.h b/libevmasm/Instruction.h index 289469b5ef7b..f89c72c8941e 100644 --- a/libevmasm/Instruction.h +++ b/libevmasm/Instruction.h @@ -33,167 +33,167 @@ namespace solidity::evmasm /// Virtual machine bytecode instruction. enum class Instruction: uint8_t { - STOP = 0x00, ///< halts execution - ADD, ///< addition operation - MUL, ///< multiplication operation - SUB, ///< subtraction operation - DIV, ///< integer division operation - SDIV, ///< signed integer division operation - MOD, ///< modulo remainder operation - SMOD, ///< signed modulo remainder operation - ADDMOD, ///< unsigned modular addition - MULMOD, ///< unsigned modular multiplication - EXP, ///< exponential operation - SIGNEXTEND, ///< extend length of signed integer - - LT = 0x10, ///< less-than comparison - GT, ///< greater-than comparison - SLT, ///< signed less-than comparison - SGT, ///< signed greater-than comparison - EQ, ///< equality comparison - ISZERO, ///< simple not operator - AND, ///< bitwise AND operation - OR, ///< bitwise OR operation - XOR, ///< bitwise XOR operation - NOT, ///< bitwise NOT operation - BYTE, ///< retrieve single byte from word - SHL, ///< bitwise SHL operation - SHR, ///< bitwise SHR operation - SAR, ///< bitwise SAR operation - - KECCAK256 = 0x20, ///< compute KECCAK-256 hash - - ADDRESS = 0x30, ///< get address of currently executing account - BALANCE, ///< get balance of the given account - ORIGIN, ///< get execution origination address - CALLER, ///< get caller address - CALLVALUE, ///< get deposited value by the instruction/transaction responsible for this execution - CALLDATALOAD, ///< get input data of current environment - CALLDATASIZE, ///< get size of input data in current environment - CALLDATACOPY, ///< copy input data in current environment to memory - CODESIZE, ///< get size of code running in current environment - CODECOPY, ///< copy code running in current environment to memory - GASPRICE, ///< get price of gas in current environment - EXTCODESIZE, ///< get external code size (from another contract) - EXTCODECOPY, ///< copy external code (from another contract) - RETURNDATASIZE = 0x3d, ///< get size of return data buffer - RETURNDATACOPY = 0x3e, ///< copy return data in current environment to memory - EXTCODEHASH = 0x3f, ///< get external code hash (from another contract) - - BLOCKHASH = 0x40, ///< get hash of most recent complete block - COINBASE, ///< get the block's coinbase address - TIMESTAMP, ///< get the block's timestamp - NUMBER, ///< get the block's number - PREVRANDAO, ///< get randomness provided by the beacon chain - GASLIMIT, ///< get the block's gas limit - CHAINID, ///< get the config's chainid param - SELFBALANCE, ///< get balance of the current account - BASEFEE, ///< get the block's basefee - BLOBHASH = 0x49, ///< get a versioned hash of one of the blobs associated with the transaction - BLOBBASEFEE = 0x4a, ///< get the block's blob basefee - - POP = 0x50, ///< remove item from stack - MLOAD, ///< load word from memory - MSTORE, ///< save word to memory - MSTORE8, ///< save byte to memory - SLOAD, ///< load word from storage - SSTORE, ///< save word to storage - JUMP, ///< alter the program counter - JUMPI, ///< conditionally alter the program counter - PC, ///< get the program counter - MSIZE, ///< get the size of active memory - GAS, ///< get the amount of available gas - JUMPDEST, ///< set a potential jump destination - MCOPY = 0x5e, ///< copy between memory areas - - TLOAD = 0x5c, ///< load word from transient storage - TSTORE = 0x5d, ///< save word to transient storage - - PUSH0 = 0x5f, ///< place the value 0 on stack - PUSH1 = 0x60, ///< place 1 byte item on stack - PUSH2, ///< place 2 byte item on stack - PUSH3, ///< place 3 byte item on stack - PUSH4, ///< place 4 byte item on stack - PUSH5, ///< place 5 byte item on stack - PUSH6, ///< place 6 byte item on stack - PUSH7, ///< place 7 byte item on stack - PUSH8, ///< place 8 byte item on stack - PUSH9, ///< place 9 byte item on stack - PUSH10, ///< place 10 byte item on stack - PUSH11, ///< place 11 byte item on stack - PUSH12, ///< place 12 byte item on stack - PUSH13, ///< place 13 byte item on stack - PUSH14, ///< place 14 byte item on stack - PUSH15, ///< place 15 byte item on stack - PUSH16, ///< place 16 byte item on stack - PUSH17, ///< place 17 byte item on stack - PUSH18, ///< place 18 byte item on stack - PUSH19, ///< place 19 byte item on stack - PUSH20, ///< place 20 byte item on stack - PUSH21, ///< place 21 byte item on stack - PUSH22, ///< place 22 byte item on stack - PUSH23, ///< place 23 byte item on stack - PUSH24, ///< place 24 byte item on stack - PUSH25, ///< place 25 byte item on stack - PUSH26, ///< place 26 byte item on stack - PUSH27, ///< place 27 byte item on stack - PUSH28, ///< place 28 byte item on stack - PUSH29, ///< place 29 byte item on stack - PUSH30, ///< place 30 byte item on stack - PUSH31, ///< place 31 byte item on stack - PUSH32, ///< place 32 byte item on stack - - DUP1 = 0x80, ///< copies the highest item in the stack to the top of the stack - DUP2, ///< copies the second highest item in the stack to the top of the stack - DUP3, ///< copies the third highest item in the stack to the top of the stack - DUP4, ///< copies the 4th highest item in the stack to the top of the stack - DUP5, ///< copies the 5th highest item in the stack to the top of the stack - DUP6, ///< copies the 6th highest item in the stack to the top of the stack - DUP7, ///< copies the 7th highest item in the stack to the top of the stack - DUP8, ///< copies the 8th highest item in the stack to the top of the stack - DUP9, ///< copies the 9th highest item in the stack to the top of the stack - DUP10, ///< copies the 10th highest item in the stack to the top of the stack - DUP11, ///< copies the 11th highest item in the stack to the top of the stack - DUP12, ///< copies the 12th highest item in the stack to the top of the stack - DUP13, ///< copies the 13th highest item in the stack to the top of the stack - DUP14, ///< copies the 14th highest item in the stack to the top of the stack - DUP15, ///< copies the 15th highest item in the stack to the top of the stack - DUP16, ///< copies the 16th highest item in the stack to the top of the stack - - SWAP1 = 0x90, ///< swaps the highest and second highest value on the stack - SWAP2, ///< swaps the highest and third highest value on the stack - SWAP3, ///< swaps the highest and 4th highest value on the stack - SWAP4, ///< swaps the highest and 5th highest value on the stack - SWAP5, ///< swaps the highest and 6th highest value on the stack - SWAP6, ///< swaps the highest and 7th highest value on the stack - SWAP7, ///< swaps the highest and 8th highest value on the stack - SWAP8, ///< swaps the highest and 9th highest value on the stack - SWAP9, ///< swaps the highest and 10th highest value on the stack - SWAP10, ///< swaps the highest and 11th highest value on the stack - SWAP11, ///< swaps the highest and 12th highest value on the stack - SWAP12, ///< swaps the highest and 13th highest value on the stack - SWAP13, ///< swaps the highest and 14th highest value on the stack - SWAP14, ///< swaps the highest and 15th highest value on the stack - SWAP15, ///< swaps the highest and 16th highest value on the stack - SWAP16, ///< swaps the highest and 17th highest value on the stack - - LOG0 = 0xa0, ///< Makes a log entry; no topics. - LOG1, ///< Makes a log entry; 1 topic. - LOG2, ///< Makes a log entry; 2 topics. - LOG3, ///< Makes a log entry; 3 topics. - LOG4, ///< Makes a log entry; 4 topics. - - CREATE = 0xf0, ///< create a new account with associated code - CALL, ///< message-call into an account - CALLCODE, ///< message-call with another account's code only - RETURN, ///< halt execution returning output data - DELEGATECALL, ///< like CALLCODE but keeps caller's value and sender - CREATE2 = 0xf5, ///< create new account with associated code at address `sha3(0xff + sender + salt + init code) % 2**160` - STATICCALL = 0xfa, ///< like CALL but disallow state modifications - - REVERT = 0xfd, ///< halt execution, revert state and return output data - INVALID = 0xfe, ///< invalid instruction for expressing runtime errors (e.g., division-by-zero) - SELFDESTRUCT = 0xff ///< halt execution and register account for later deletion + STOP = 0x00, ///< halts execution + ADD, ///< addition operation + MUL, ///< multiplication operation + SUB, ///< subtraction operation + DIV, ///< integer division operation + SDIV, ///< signed integer division operation + MOD, ///< modulo remainder operation + SMOD, ///< signed modulo remainder operation + ADDMOD, ///< unsigned modular addition + MULMOD, ///< unsigned modular multiplication + EXP, ///< exponential operation + SIGNEXTEND, ///< extend length of signed integer + + LT = 0x10, ///< less-than comparison + GT, ///< greater-than comparison + SLT, ///< signed less-than comparison + SGT, ///< signed greater-than comparison + EQ, ///< equality comparison + ISZERO, ///< simple not operator + AND, ///< bitwise AND operation + OR, ///< bitwise OR operation + XOR, ///< bitwise XOR operation + NOT, ///< bitwise NOT operation + BYTE, ///< retrieve single byte from word + SHL, ///< bitwise SHL operation + SHR, ///< bitwise SHR operation + SAR, ///< bitwise SAR operation + + KECCAK256 = 0x20, ///< compute KECCAK-256 hash + + ADDRESS = 0x30, ///< get address of currently executing account + BALANCE, ///< get balance of the given account + ORIGIN, ///< get execution origination address + CALLER, ///< get caller address + CALLVALUE, ///< get deposited value by the instruction/transaction responsible for this execution + CALLDATALOAD, ///< get input data of current environment + CALLDATASIZE, ///< get size of input data in current environment + CALLDATACOPY, ///< copy input data in current environment to memory + CODESIZE, ///< get size of code running in current environment + CODECOPY, ///< copy code running in current environment to memory + GASPRICE, ///< get price of gas in current environment + EXTCODESIZE, ///< get external code size (from another contract) + EXTCODECOPY, ///< copy external code (from another contract) + RETURNDATASIZE = 0x3d, ///< get size of return data buffer + RETURNDATACOPY = 0x3e, ///< copy return data in current environment to memory + EXTCODEHASH = 0x3f, ///< get external code hash (from another contract) + + BLOCKHASH = 0x40, ///< get hash of most recent complete block + COINBASE, ///< get the block's coinbase address + TIMESTAMP, ///< get the block's timestamp + NUMBER, ///< get the block's number + PREVRANDAO, ///< get randomness provided by the beacon chain + GASLIMIT, ///< get the block's gas limit + CHAINID, ///< get the config's chainid param + SELFBALANCE, ///< get balance of the current account + BASEFEE, ///< get the block's basefee + BLOBHASH = 0x49, ///< get a versioned hash of one of the blobs associated with the transaction + BLOBBASEFEE = 0x4a, ///< get the block's blob basefee + + POP = 0x50, ///< remove item from stack + MLOAD, ///< load word from memory + MSTORE, ///< save word to memory + MSTORE8, ///< save byte to memory + SLOAD, ///< load word from storage + SSTORE, ///< save word to storage + JUMP, ///< alter the program counter + JUMPI, ///< conditionally alter the program counter + PC, ///< get the program counter + MSIZE, ///< get the size of active memory + GAS, ///< get the amount of available gas + JUMPDEST, ///< set a potential jump destination + MCOPY = 0x5e, ///< copy between memory areas + + TLOAD = 0x5c, ///< load word from transient storage + TSTORE = 0x5d, ///< save word to transient storage + + PUSH0 = 0x5f, ///< place the value 0 on stack + PUSH1 = 0x60, ///< place 1 byte item on stack + PUSH2, ///< place 2 byte item on stack + PUSH3, ///< place 3 byte item on stack + PUSH4, ///< place 4 byte item on stack + PUSH5, ///< place 5 byte item on stack + PUSH6, ///< place 6 byte item on stack + PUSH7, ///< place 7 byte item on stack + PUSH8, ///< place 8 byte item on stack + PUSH9, ///< place 9 byte item on stack + PUSH10, ///< place 10 byte item on stack + PUSH11, ///< place 11 byte item on stack + PUSH12, ///< place 12 byte item on stack + PUSH13, ///< place 13 byte item on stack + PUSH14, ///< place 14 byte item on stack + PUSH15, ///< place 15 byte item on stack + PUSH16, ///< place 16 byte item on stack + PUSH17, ///< place 17 byte item on stack + PUSH18, ///< place 18 byte item on stack + PUSH19, ///< place 19 byte item on stack + PUSH20, ///< place 20 byte item on stack + PUSH21, ///< place 21 byte item on stack + PUSH22, ///< place 22 byte item on stack + PUSH23, ///< place 23 byte item on stack + PUSH24, ///< place 24 byte item on stack + PUSH25, ///< place 25 byte item on stack + PUSH26, ///< place 26 byte item on stack + PUSH27, ///< place 27 byte item on stack + PUSH28, ///< place 28 byte item on stack + PUSH29, ///< place 29 byte item on stack + PUSH30, ///< place 30 byte item on stack + PUSH31, ///< place 31 byte item on stack + PUSH32, ///< place 32 byte item on stack + + DUP1 = 0x80, ///< copies the highest item in the stack to the top of the stack + DUP2, ///< copies the second highest item in the stack to the top of the stack + DUP3, ///< copies the third highest item in the stack to the top of the stack + DUP4, ///< copies the 4th highest item in the stack to the top of the stack + DUP5, ///< copies the 5th highest item in the stack to the top of the stack + DUP6, ///< copies the 6th highest item in the stack to the top of the stack + DUP7, ///< copies the 7th highest item in the stack to the top of the stack + DUP8, ///< copies the 8th highest item in the stack to the top of the stack + DUP9, ///< copies the 9th highest item in the stack to the top of the stack + DUP10, ///< copies the 10th highest item in the stack to the top of the stack + DUP11, ///< copies the 11th highest item in the stack to the top of the stack + DUP12, ///< copies the 12th highest item in the stack to the top of the stack + DUP13, ///< copies the 13th highest item in the stack to the top of the stack + DUP14, ///< copies the 14th highest item in the stack to the top of the stack + DUP15, ///< copies the 15th highest item in the stack to the top of the stack + DUP16, ///< copies the 16th highest item in the stack to the top of the stack + + SWAP1 = 0x90, ///< swaps the highest and second highest value on the stack + SWAP2, ///< swaps the highest and third highest value on the stack + SWAP3, ///< swaps the highest and 4th highest value on the stack + SWAP4, ///< swaps the highest and 5th highest value on the stack + SWAP5, ///< swaps the highest and 6th highest value on the stack + SWAP6, ///< swaps the highest and 7th highest value on the stack + SWAP7, ///< swaps the highest and 8th highest value on the stack + SWAP8, ///< swaps the highest and 9th highest value on the stack + SWAP9, ///< swaps the highest and 10th highest value on the stack + SWAP10, ///< swaps the highest and 11th highest value on the stack + SWAP11, ///< swaps the highest and 12th highest value on the stack + SWAP12, ///< swaps the highest and 13th highest value on the stack + SWAP13, ///< swaps the highest and 14th highest value on the stack + SWAP14, ///< swaps the highest and 15th highest value on the stack + SWAP15, ///< swaps the highest and 16th highest value on the stack + SWAP16, ///< swaps the highest and 17th highest value on the stack + + LOG0 = 0xa0, ///< Makes a log entry; no topics. + LOG1, ///< Makes a log entry; 1 topic. + LOG2, ///< Makes a log entry; 2 topics. + LOG3, ///< Makes a log entry; 3 topics. + LOG4, ///< Makes a log entry; 4 topics. + + CREATE = 0xf0, ///< create a new account with associated code + CALL, ///< message-call into an account + CALLCODE, ///< message-call with another account's code only + RETURN, ///< halt execution returning output data + DELEGATECALL, ///< like CALLCODE but keeps caller's value and sender + CREATE2 = 0xf5, ///< create new account with associated code at address `sha3(0xff + sender + salt + init code) % 2**160` + STATICCALL = 0xfa, ///< like CALL but disallow state modifications + + REVERT = 0xfd, ///< halt execution, revert state and return output data + INVALID = 0xfe, ///< invalid instruction for expressing runtime errors (e.g., division-by-zero) + SELFDESTRUCT = 0xff ///< halt execution and register account for later deletion }; /// @returns true if the instruction is of the CALL opcode family @@ -309,12 +309,12 @@ enum class Tier /// Information structure for a particular instruction. struct InstructionInfo { - std::string name; ///< The name of the instruction. - int additional; ///< Additional items required in memory for this instructions (only for PUSH). - int args; ///< Number of items required on the stack for this instruction (and, for the purposes of ret, the number taken from the stack). - int ret; ///< Number of items placed (back) on the stack by this instruction, assuming args items were removed. - bool sideEffects; ///< false if the only effect on the execution environment (apart from gas usage) is a change to a topmost segment of the stack - Tier gasPriceTier; ///< Tier for gas pricing. + std::string name; ///< The name of the instruction. + int additional; ///< Additional items required in memory for this instructions (only for PUSH). + int args; ///< Number of items required on the stack for this instruction (and, for the purposes of ret, the number taken from the stack). + int ret; ///< Number of items placed (back) on the stack by this instruction, assuming args items were removed. + bool sideEffects; ///< false if the only effect on the execution environment (apart from gas usage) is a change to a topmost segment of the stack + Tier gasPriceTier; ///< Tier for gas pricing. }; /// Information on all the instructions. diff --git a/liblangutil/Token.h b/liblangutil/Token.h index 0f7c2df08034..d1073a872b69 100644 --- a/liblangutil/Token.h +++ b/liblangutil/Token.h @@ -64,11 +64,11 @@ namespace solidity::langutil #define IGNORE_TOKEN(name, string, precedence) -#define TOKEN_LIST(T, K) \ - /* End of source indicator. */ \ - T(EOS, "EOS", 0) \ - \ - /* Punctuators (ECMA-262, section 7.7, page 15). */ \ +#define TOKEN_LIST(T, K) \ + /* End of source indicator. */ \ + T(EOS, "EOS", 0) \ + \ + /* Punctuators (ECMA-262, section 7.7, page 15). */ \ T(LParen, "(", 0) \ T(RParen, ")", 0) \ T(LBrack, "[", 0) \ @@ -82,9 +82,9 @@ namespace solidity::langutil T(DoubleArrow, "=>", 0) \ T(RightArrow, "->", 0) \ \ - /* Assignment operators. */ \ - /* IsAssignmentOp() relies on this block of enum values being */ \ - /* contiguous and sorted in the same order!*/ \ + /* Assignment operators. */ \ + /* IsAssignmentOp() relies on this block of enum values being */ \ + /* contiguous and sorted in the same order!*/ \ T(Assign, "=", 2) \ /* The following have to be in exactly the same order as the simple binary operators*/ \ T(AssignBitOr, "|=", 2) \ diff --git a/libsmtutil/CHCSmtLib2Interface.cpp b/libsmtutil/CHCSmtLib2Interface.cpp index ef7c56ac0c06..ac906e301a96 100644 --- a/libsmtutil/CHCSmtLib2Interface.cpp +++ b/libsmtutil/CHCSmtLib2Interface.cpp @@ -221,5 +221,5 @@ std::string CHCSmtLib2Interface::createHeaderAndDeclarations() { } std::string CHCSmtLib2Interface::createQueryAssertion(std::string name) { - return "(assert\n(forall " + forall() + "\n" + "(=> " + name + " false)))"; + return "(assert\n(forall " + forall() + "\n" + "(=> " + name + " false)))"; } diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp index 0bcab65d932f..a7402ba40f60 100644 --- a/libsolidity/analysis/TypeChecker.cpp +++ b/libsolidity/analysis/TypeChecker.cpp @@ -3413,7 +3413,7 @@ bool TypeChecker::visit(MemberAccess const& _memberAccess) annotation.isPure = true; else if ( magicType->kind() == MagicType::Kind::MetaType && - (memberName == "min" || memberName == "max") + (memberName == "min" || memberName == "max") ) annotation.isPure = true; else if (magicType->kind() == MagicType::Kind::Block) diff --git a/libsolidity/ast/ASTAnnotations.h b/libsolidity/ast/ASTAnnotations.h index f7519250a3a8..81b3b8374697 100644 --- a/libsolidity/ast/ASTAnnotations.h +++ b/libsolidity/ast/ASTAnnotations.h @@ -65,8 +65,8 @@ struct ASTAnnotation struct DocTag { - std::string content; ///< The text content of the tag. - std::string paramName; ///< Only used for @param, stores the parameter name. + std::string content; ///< The text content of the tag. + std::string paramName; ///< Only used for @param, stores the parameter name. }; struct StructurallyDocumentedAnnotation diff --git a/libsolidity/ast/Types.cpp b/libsolidity/ast/Types.cpp index 0af9f105fb1b..d09d03fbec17 100644 --- a/libsolidity/ast/Types.cpp +++ b/libsolidity/ast/Types.cpp @@ -1042,7 +1042,7 @@ BoolResult RationalNumberType::isExplicitlyConvertibleTo(Type const& _convertTo) if (category == Category::FixedBytes) return false; else if (auto addressType = dynamic_cast(&_convertTo)) - return (m_value == 0) || + return (m_value == 0) || ((addressType->stateMutability() != StateMutability::Payable) && !isNegative() && !isFractional() && diff --git a/libsolidity/codegen/ExpressionCompiler.cpp b/libsolidity/codegen/ExpressionCompiler.cpp index 494d106c833f..3824d5432139 100644 --- a/libsolidity/codegen/ExpressionCompiler.cpp +++ b/libsolidity/codegen/ExpressionCompiler.cpp @@ -942,7 +942,7 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall) else { solAssert(paramTypes[arg - 1]->isValueType(), ""); - if (auto functionType = dynamic_cast(paramTypes[arg - 1])) + if (auto functionType = dynamic_cast(paramTypes[arg - 1])) { auto argumentType = dynamic_cast(arguments[arg-1]->annotation().type); diff --git a/libsolidity/experimental/codegen/IRGenerator.cpp b/libsolidity/experimental/codegen/IRGenerator.cpp index 257bd2be16ba..40deb38c397e 100644 --- a/libsolidity/experimental/codegen/IRGenerator.cpp +++ b/libsolidity/experimental/codegen/IRGenerator.cpp @@ -52,14 +52,13 @@ IRGenerator::IRGenerator( DebugInfoSelection const&, CharStreamProvider const*, Analysis const& _analysis -) -: -m_evmVersion(_evmVersion), -m_eofVersion(_eofVersion), -// m_debugInfoSelection(_debugInfoSelection), -// m_soliditySourceProvider(_soliditySourceProvider), -m_env(_analysis.typeSystem().env().clone()), -m_context{_analysis, &m_env, {}, {}} +): + m_evmVersion(_evmVersion), + m_eofVersion(_eofVersion), + //m_debugInfoSelection(_debugInfoSelection), + //m_soliditySourceProvider(_soliditySourceProvider), + m_env(_analysis.typeSystem().env().clone()), + m_context{_analysis, &m_env, {}, {}} { } diff --git a/libsolidity/experimental/codegen/IRGenerator.h b/libsolidity/experimental/codegen/IRGenerator.h index cce8c730572b..7d3baf8f954e 100644 --- a/libsolidity/experimental/codegen/IRGenerator.h +++ b/libsolidity/experimental/codegen/IRGenerator.h @@ -63,8 +63,8 @@ class IRGenerator langutil::EVMVersion const m_evmVersion; std::optional const m_eofVersion; OptimiserSettings const m_optimiserSettings; -// langutil::DebugInfoSelection m_debugInfoSelection = {}; -// langutil::CharStreamProvider const* m_soliditySourceProvider = nullptr; + //langutil::DebugInfoSelection m_debugInfoSelection = {}; + //langutil::CharStreamProvider const* m_soliditySourceProvider = nullptr; TypeEnvironment m_env; IRGenerationContext m_context; }; diff --git a/libsolidity/formal/BMC.cpp b/libsolidity/formal/BMC.cpp index b16182af8c88..932a315a703a 100644 --- a/libsolidity/formal/BMC.cpp +++ b/libsolidity/formal/BMC.cpp @@ -349,7 +349,7 @@ bool BMC::visit(WhileStatement const& _node) _node.body().accept(*this); popPathCondition(); - auto brokeInCurrentIteration = mergeVariablesFromLoopCheckpoints(); + auto brokeInCurrentIteration = mergeVariablesFromLoopCheckpoints(); // merges indices modified when accepting loop condition that no longer holds mergeVariables( @@ -414,7 +414,7 @@ bool BMC::visit(ForStatement const& _node) pushPathCondition(forCondition); _node.body().accept(*this); - auto brokeInCurrentIteration = mergeVariablesFromLoopCheckpoints(); + auto brokeInCurrentIteration = mergeVariablesFromLoopCheckpoints(); // accept loop expression if there was no break if (_node.loopExpression()) diff --git a/libsolidity/formal/SMTEncoder.h b/libsolidity/formal/SMTEncoder.h index be676930cab1..bea3a85ef9c8 100644 --- a/libsolidity/formal/SMTEncoder.h +++ b/libsolidity/formal/SMTEncoder.h @@ -277,7 +277,7 @@ class SMTEncoder: public ASTConstVisitor /// @returns a pair of expressions representing _left / _right and _left mod _right, respectively. /// Uses slack variables and additional constraints to express the results using only operations /// more friendly to the SMT solver (multiplication, addition, subtraction and comparison). - std::pair divModWithSlacks( + std::pair divModWithSlacks( smtutil::Expression _left, smtutil::Expression _right, IntegerType const& _type diff --git a/libsolutil/FixedHash.h b/libsolutil/FixedHash.h index c4c72e9eb78a..3aa248480839 100644 --- a/libsolutil/FixedHash.h +++ b/libsolutil/FixedHash.h @@ -159,7 +159,7 @@ class FixedHash bytes asBytes() const { return bytes(data(), data() + N); } private: - std::array m_data; ///< The binary data. + std::array m_data; ///< The binary data. }; /// Stream I/O for the FixedHash class. diff --git a/libsolutil/Result.h b/libsolutil/Result.h index ca9563947729..bf6bde84b6ea 100644 --- a/libsolutil/Result.h +++ b/libsolutil/Result.h @@ -30,9 +30,9 @@ namespace solidity::util /// /// Result check() /// { -/// if (false) -/// return Result::err("Error message.") -/// return true; +/// if (false) +/// return Result::err("Error message.") +/// return true; /// } /// diff --git a/libyul/YulString.h b/libyul/YulString.h index 5522e34849a4..7dbaf1b84a03 100644 --- a/libyul/YulString.h +++ b/libyul/YulString.h @@ -66,7 +66,7 @@ class YulStringRepository return Handle{id, h}; } - std::string const& idToString(size_t _id) const { return *m_strings.at(_id); } + std::string const& idToString(size_t _id) const { return *m_strings.at(_id); } static std::uint64_t hash(std::string const& v) { diff --git a/libyul/backends/evm/ControlFlowGraphBuilder.cpp b/libyul/backends/evm/ControlFlowGraphBuilder.cpp index 4b0da1e80d91..f048e5717e10 100644 --- a/libyul/backends/evm/ControlFlowGraphBuilder.cpp +++ b/libyul/backends/evm/ControlFlowGraphBuilder.cpp @@ -103,7 +103,7 @@ void markRecursiveCalls(CFG& _cfg) _addChild(_conditionalJump.nonZero); }, [&](CFG::BasicBlock::FunctionReturn const&) {}, - [&](CFG::BasicBlock::Terminated const&) {}, + [&](CFG::BasicBlock::Terminated const&) {}, }, _block->exit); }); return calls; diff --git a/libyul/backends/evm/EVMDialect.cpp b/libyul/backends/evm/EVMDialect.cpp index f3c529bb1ab5..6a3b34f97707 100644 --- a/libyul/backends/evm/EVMDialect.cpp +++ b/libyul/backends/evm/EVMDialect.cpp @@ -287,15 +287,15 @@ std::map createBuiltins(langutil::EVMVersion _ 3, 0, SideEffects{ - false, // movable - true, // movableApartFromEffects - false, // canBeRemoved - false, // canBeRemovedIfNotMSize - true, // cannotLoop - SideEffects::None, // otherState - SideEffects::None, // storage - SideEffects::Write, // memory - SideEffects::None // transientStorage + false, // movable + true, // movableApartFromEffects + false, // canBeRemoved + false, // canBeRemovedIfNotMSize + true, // cannotLoop + SideEffects::None, // otherState + SideEffects::None, // storage + SideEffects::Write, // memory + SideEffects::None // transientStorage }, {}, []( @@ -311,15 +311,15 @@ std::map createBuiltins(langutil::EVMVersion _ 3, 0, SideEffects{ - false, // movable - false, // movableApartFromEffects - false, // canBeRemoved - false, // canBeRemovedIfNotMSize - true, // cannotLoop - SideEffects::None, // otherState - SideEffects::None, // storage - SideEffects::Write, // memory - SideEffects::None // transientStorage + false, // movable + false, // movableApartFromEffects + false, // canBeRemoved + false, // canBeRemovedIfNotMSize + true, // cannotLoop + SideEffects::None, // otherState + SideEffects::None, // storage + SideEffects::Write, // memory + SideEffects::None // transientStorage }, {std::nullopt, LiteralKind::String, std::nullopt}, []( diff --git a/libyul/backends/evm/StackLayoutGenerator.cpp b/libyul/backends/evm/StackLayoutGenerator.cpp index 88190b45b3fc..51db3a14d5b3 100644 --- a/libyul/backends/evm/StackLayoutGenerator.cpp +++ b/libyul/backends/evm/StackLayoutGenerator.cpp @@ -539,7 +539,7 @@ void StackLayoutGenerator::stitchConditionalJumps(CFG::BasicBlock const& _block) _addChild(_conditionalJump.zero); _addChild(_conditionalJump.nonZero); }, - [&](CFG::BasicBlock::FunctionReturn const&) {}, + [&](CFG::BasicBlock::FunctionReturn const&) {}, [&](CFG::BasicBlock::Terminated const&) { }, }, _block->exit); }); diff --git a/libyul/optimiser/ExpressionJoiner.h b/libyul/optimiser/ExpressionJoiner.h index eb22ad79fbdb..3a1fdf743579 100644 --- a/libyul/optimiser/ExpressionJoiner.h +++ b/libyul/optimiser/ExpressionJoiner.h @@ -91,9 +91,9 @@ class ExpressionJoiner: public ASTModifier bool isLatestStatementVarDeclJoinable(Identifier const& _identifier); private: - Block* m_currentBlock = nullptr; ///< Pointer to current block holding the statement being visited. - size_t m_latestStatementInBlock = 0; ///< Offset to m_currentBlock's statements of the last visited statement. - std::map m_references; ///< Holds reference counts to all variable declarations in current block. + Block* m_currentBlock = nullptr; ///< Pointer to current block holding the statement being visited. + size_t m_latestStatementInBlock = 0; ///< Offset to m_currentBlock's statements of the last visited statement. + std::map m_references; ///< Holds reference counts to all variable declarations in current block. }; } diff --git a/libyul/optimiser/SSAReverser.h b/libyul/optimiser/SSAReverser.h index bb6e98bc8ded..675c5c4afff0 100644 --- a/libyul/optimiser/SSAReverser.h +++ b/libyul/optimiser/SSAReverser.h @@ -30,42 +30,42 @@ class AssignmentCounter; * * In particular, the SSA transform will rewrite * - * a := E + * a := E * * to * - * let a_1 := E - * a := a_1 + * let a_1 := E + * a := a_1 * * To undo this kind of transformation, the SSAReverser changes this back to * - * a := E - * let a_1 := a + * a := E + * let a_1 := a * - * In the special case - * let a := E - * a := a + * In the special case + * let a := E + * a := a * - * the redundant assignment "a := a" is removed. + * the redundant assignment "a := a" is removed. * * * Secondly, the SSA transform will rewrite * - * let a := E + * let a := E * to * - * let a_1 := E - * let a := a_1 + * let a_1 := E + * let a := a_1 * * To undo this kind of transformation, the SSAReverser changes this back to * - * let a := E - * let a_1 := a + * let a := E + * let a_1 := a * - * After that the CSE can replace references of a_1 by references to a, - * after which the unused pruner can remove the declaration of a_1. + * After that the CSE can replace references of a_1 by references to a, + * after which the unused pruner can remove the declaration of a_1. * - * Prerequisites: Disambiguator + * Prerequisites: Disambiguator * */ class SSAReverser: public ASTModifier diff --git a/scripts/release_ppa.sh b/scripts/release_ppa.sh index 6a6fa8f0e55f..9a94fbcf2c56 100755 --- a/scripts/release_ppa.sh +++ b/scripts/release_ppa.sh @@ -210,8 +210,8 @@ export DH_OPTIONS override_dh_auto_test: #override_dh_installdocs: -# make -C docs html -# dh_installdocs docs/_build/html +# make -C docs html +# dh_installdocs docs/_build/html override_dh_shlibdeps: dh_shlibdeps --dpkg-shlibdeps-params=--ignore-missing-info diff --git a/test/EVMHost.cpp b/test/EVMHost.cpp index 2243758356db..4ab9b2b08d7e 100644 --- a/test/EVMHost.cpp +++ b/test/EVMHost.cpp @@ -191,7 +191,7 @@ void EVMHost::newTransactionFrame() for (auto& [slot, value]: account.storage) { value.access_status = EVMC_ACCESS_COLD; // Clear EIP-2929 storage access indicator - value.original = value.current; // Clear EIP-2200 dirty slot + value.original = value.current; // Clear EIP-2200 dirty slot } // Clear transient storage according to EIP 1153 diff --git a/test/InteractiveTests.h b/test/InteractiveTests.h index 2519fa86f488..42e20d7e3919 100644 --- a/test/InteractiveTests.h +++ b/test/InteractiveTests.h @@ -61,27 +61,27 @@ struct Testsuite /// Array of testsuits that can be run interactively as well as automatically Testsuite const g_interactiveTestsuites[] = { /* - Title Path Subpath SMT NeedsVM Creator function */ - {"Yul Optimizer", "libyul", "yulOptimizerTests", false, false, &yul::test::YulOptimizerTest::create}, - {"Yul Interpreter", "libyul", "yulInterpreterTests", false, false, &yul::test::YulInterpreterTest::create}, - {"Yul Object Compiler", "libyul", "objectCompiler", false, false, &yul::test::ObjectCompilerTest::create}, - {"Yul Control Flow Graph", "libyul", "yulControlFlowGraph", false, false, &yul::test::ControlFlowGraphTest::create}, - {"Yul Stack Layout", "libyul", "yulStackLayout", false, false, &yul::test::StackLayoutGeneratorTest::create}, - {"Yul Stack Shuffling", "libyul", "yulStackShuffling", false, false, &yul::test::StackShufflingTest::create}, - {"Control Flow Side Effects", "libyul", "controlFlowSideEffects", false, false, &yul::test::ControlFlowSideEffectsTest::create}, - {"Function Side Effects", "libyul", "functionSideEffects", false, false, &yul::test::FunctionSideEffects::create}, - {"Yul Syntax", "libyul", "yulSyntaxTests", false, false, &yul::test::SyntaxTest::create}, - {"EVM Code Transform", "libyul", "evmCodeTransform", false, false, &yul::test::EVMCodeTransformTest::create, {"nooptions"}}, - {"Syntax", "libsolidity", "syntaxTests", false, false, &SyntaxTest::create}, - {"Semantic", "libsolidity", "semanticTests", false, true, &SemanticTest::create}, - {"JSON AST", "libsolidity", "ASTJSON", false, false, &ASTJSONTest::create}, - {"JSON ABI", "libsolidity", "ABIJson", false, false, &ABIJsonTest::create}, - {"JSON Natspec", "libsolidity", "natspecJSON", false, false, &NatspecJSONTest::create}, - {"SMT Checker", "libsolidity", "smtCheckerTests", true, false, &SMTCheckerTest::create}, - {"Gas Estimates", "libsolidity", "gasTests", false, false, &GasTest::create}, - {"Memory Guard", "libsolidity", "memoryGuardTests", false, false, &MemoryGuardTest::create}, - {"AST Properties", "libsolidity", "astPropertyTests", false, false, &ASTPropertyTest::create}, - {"Function Dependency Graph", "libsolidity", "functionDependencyGraphTests", false, false, &FunctionDependencyGraphTest::create}, + Title Path Subpath SMT NeedsVM Creator function */ + {"Yul Optimizer", "libyul", "yulOptimizerTests", false, false, &yul::test::YulOptimizerTest::create}, + {"Yul Interpreter", "libyul", "yulInterpreterTests", false, false, &yul::test::YulInterpreterTest::create}, + {"Yul Object Compiler", "libyul", "objectCompiler", false, false, &yul::test::ObjectCompilerTest::create}, + {"Yul Control Flow Graph", "libyul", "yulControlFlowGraph", false, false, &yul::test::ControlFlowGraphTest::create}, + {"Yul Stack Layout", "libyul", "yulStackLayout", false, false, &yul::test::StackLayoutGeneratorTest::create}, + {"Yul Stack Shuffling", "libyul", "yulStackShuffling", false, false, &yul::test::StackShufflingTest::create}, + {"Control Flow Side Effects", "libyul", "controlFlowSideEffects", false, false, &yul::test::ControlFlowSideEffectsTest::create}, + {"Function Side Effects", "libyul", "functionSideEffects", false, false, &yul::test::FunctionSideEffects::create}, + {"Yul Syntax", "libyul", "yulSyntaxTests", false, false, &yul::test::SyntaxTest::create}, + {"EVM Code Transform", "libyul", "evmCodeTransform", false, false, &yul::test::EVMCodeTransformTest::create, {"nooptions"}}, + {"Syntax", "libsolidity", "syntaxTests", false, false, &SyntaxTest::create}, + {"Semantic", "libsolidity", "semanticTests", false, true, &SemanticTest::create}, + {"JSON AST", "libsolidity", "ASTJSON", false, false, &ASTJSONTest::create}, + {"JSON ABI", "libsolidity", "ABIJson", false, false, &ABIJsonTest::create}, + {"JSON Natspec", "libsolidity", "natspecJSON", false, false, &NatspecJSONTest::create}, + {"SMT Checker", "libsolidity", "smtCheckerTests", true, false, &SMTCheckerTest::create}, + {"Gas Estimates", "libsolidity", "gasTests", false, false, &GasTest::create}, + {"Memory Guard", "libsolidity", "memoryGuardTests", false, false, &MemoryGuardTest::create}, + {"AST Properties", "libsolidity", "astPropertyTests", false, false, &ASTPropertyTest::create}, + {"Function Dependency Graph", "libsolidity", "functionDependencyGraphTests", false, false, &FunctionDependencyGraphTest::create}, }; } diff --git a/test/cmdlineTests/model_checker_contracts_all/input.sol b/test/cmdlineTests/model_checker_contracts_all/input.sol index 52b71f2e5d68..f47f2f31d63c 100644 --- a/test/cmdlineTests/model_checker_contracts_all/input.sol +++ b/test/cmdlineTests/model_checker_contracts_all/input.sol @@ -2,11 +2,11 @@ pragma solidity >=0.0; contract B { function f(uint x) public pure { - assert(x > 0); + assert(x > 0); } } contract A is B { function g(uint y) public pure { - assert(y > 0); + assert(y > 0); } -} \ No newline at end of file +} diff --git a/test/cmdlineTests/standard_debug_info_in_evm_asm_via_ir_location/input.json b/test/cmdlineTests/standard_debug_info_in_evm_asm_via_ir_location/input.json index c1a7209b3e3e..6ff7662901e4 100644 --- a/test/cmdlineTests/standard_debug_info_in_evm_asm_via_ir_location/input.json +++ b/test/cmdlineTests/standard_debug_info_in_evm_asm_via_ir_location/input.json @@ -4,11 +4,11 @@ { "C": { - "content": "//SPDX-License-Identifier: GPL-2.0\npragma solidity >=0.0;\npragma abicoder v2;\n\ncontract C\n{\n int constant constVar = 41;\n int immutable immutVar = 42;\n int public stateVar;\n\n constructor(int _init)\n {\n stateVar = _init;\n }\n\n function f() external pure returns (int)\n {\n return constVar + immutVar;\n }\n modifier m()\n {\n stateVar++;\n _;\n }\n function f2() m public returns (int)\n {\n return stateVar + this.f() + immutVar;\n }\n}\n" + "content": "//SPDX-License-Identifier: GPL-2.0\npragma solidity >=0.0;\npragma abicoder v2;\n\ncontract C\n{\n int constant constVar = 41;\n int immutable immutVar = 42;\n int public stateVar;\n\n constructor(int _init)\n {\n stateVar = _init;\n }\n\n function f() external pure returns (int)\n {\n return constVar + immutVar;\n }\n modifier m()\n {\n stateVar++;\n _;\n }\n function f2() m public returns (int)\n {\n return stateVar + this.f() + immutVar;\n }\n}\n" }, "D": { - "content": "//SPDX-License-Identifier: GPL-2.0\npragma solidity >=0.0;\npragma abicoder v2;\nimport \"C\";\n\ncontract D is C(3)\n{\n constructor(int _init2)\n {\n stateVar += _init2;\n }\n}\n" + "content": "//SPDX-License-Identifier: GPL-2.0\npragma solidity >=0.0;\npragma abicoder v2;\nimport \"C\";\n\ncontract D is C(3)\n{\n constructor(int _init2)\n {\n stateVar += _init2;\n }\n}\n" } }, "settings": diff --git a/test/cmdlineTests/standard_debug_info_in_yul_location/input.json b/test/cmdlineTests/standard_debug_info_in_yul_location/input.json index 8ba84239afd9..47dd4d234ccc 100644 --- a/test/cmdlineTests/standard_debug_info_in_yul_location/input.json +++ b/test/cmdlineTests/standard_debug_info_in_yul_location/input.json @@ -4,11 +4,11 @@ { "C": { - "content": "//SPDX-License-Identifier: GPL-2.0\npragma solidity >=0.0;\npragma abicoder v2;\n\ncontract C\n{\n int public constant constVar = 41;\n int immutable immutVar = 42;\n int public stateVar;\n\n constructor(int _init)\n {\n stateVar = _init;\n }\n\n function f() external pure returns (int)\n {\n return constVar + immutVar;\n }\n modifier m()\n {\n stateVar++;\n _;\n }\n function f2() m public returns (int)\n {\n return stateVar + this.f() + immutVar;\n }\n}\n" + "content": "//SPDX-License-Identifier: GPL-2.0\npragma solidity >=0.0;\npragma abicoder v2;\n\ncontract C\n{\n int public constant constVar = 41;\n int immutable immutVar = 42;\n int public stateVar;\n\n constructor(int _init)\n {\n stateVar = _init;\n }\n\n function f() external pure returns (int)\n {\n return constVar + immutVar;\n }\n modifier m()\n {\n stateVar++;\n _;\n }\n function f2() m public returns (int)\n {\n return stateVar + this.f() + immutVar;\n }\n}\n" }, "D": { - "content": "//SPDX-License-Identifier: GPL-2.0\npragma solidity >=0.0;\npragma abicoder v2;\nimport \"C\";\n\ncontract D is C(3)\n{\n constructor(int _init2)\n {\n stateVar += _init2;\n }\n}\n" + "content": "//SPDX-License-Identifier: GPL-2.0\npragma solidity >=0.0;\npragma abicoder v2;\nimport \"C\";\n\ncontract D is C(3)\n{\n constructor(int _init2)\n {\n stateVar += _init2;\n }\n}\n" } }, "settings": diff --git a/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_with_empty_sequence_no_yul/input.json b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_with_empty_sequence_no_yul/input.json index 9de7beea915a..8e6add377cac 100644 --- a/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_with_empty_sequence_no_yul/input.json +++ b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_with_empty_sequence_no_yul/input.json @@ -1,16 +1,16 @@ { - "language": "Solidity", - "sources": { - "A": {"urls": ["standard_optimizer_yulDetails_optimiserSteps_with_empty_sequence_no_yul/in.sol"]} - }, - "settings": { - "optimizer": { - "details": { - "yul": false, - "yulDetails": { - "optimizerSteps": ":" - } - } - } - } + "language": "Solidity", + "sources": { + "A": {"urls": ["standard_optimizer_yulDetails_optimiserSteps_with_empty_sequence_no_yul/in.sol"]} + }, + "settings": { + "optimizer": { + "details": { + "yul": false, + "yulDetails": { + "optimizerSteps": ":" + } + } + } + } } diff --git a/test/cmdlineTests/standard_wrong_key_metadata/input.json b/test/cmdlineTests/standard_wrong_key_metadata/input.json index a52d45004b57..e0906d312e40 100644 --- a/test/cmdlineTests/standard_wrong_key_metadata/input.json +++ b/test/cmdlineTests/standard_wrong_key_metadata/input.json @@ -10,13 +10,13 @@ "settings": { "optimizer": { - "enabled": true, - "runs": 200 - }, - "evmVersion": "byzantium", - "metadata": { + "enabled": true, + "runs": 200 + }, + "evmVersion": "byzantium", + "metadata": { "key1": "test", - "useLiteralContent": true - } + "useLiteralContent": true + } } } diff --git a/test/cmdlineTests/standard_wrong_key_optimizer/input.json b/test/cmdlineTests/standard_wrong_key_optimizer/input.json index 945c1e3460ee..2d54f09ebfff 100644 --- a/test/cmdlineTests/standard_wrong_key_optimizer/input.json +++ b/test/cmdlineTests/standard_wrong_key_optimizer/input.json @@ -11,12 +11,12 @@ { "optimizer": { "key1": "test", - "enabled": true, - "runs": 200 - }, - "evmVersion": "byzantium", - "metadata": { - "useLiteralContent": true - } + "enabled": true, + "runs": 200 + }, + "evmVersion": "byzantium", + "metadata": { + "useLiteralContent": true + } } } diff --git a/test/cmdlineTests/standard_wrong_key_settings/input.json b/test/cmdlineTests/standard_wrong_key_settings/input.json index 8f0e1d06b96e..2ce8871f9e1b 100644 --- a/test/cmdlineTests/standard_wrong_key_settings/input.json +++ b/test/cmdlineTests/standard_wrong_key_settings/input.json @@ -1,22 +1,22 @@ { - "language": "Solidity", - "sources": - { - "A": - { - "content": "//SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0; contract C { function f() public pure {} }" - } - }, - "settings": - { - "optimizer": { - "enabled": true, - "runs": 200 - }, - "evmVersion": "byzantium", - "metadata": { - "useLiteralContent": true - }, - "key1": "test" - } + "language": "Solidity", + "sources": + { + "A": + { + "content": "//SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0; contract C { function f() public pure {} }" + } + }, + "settings": + { + "optimizer": { + "enabled": true, + "runs": 200 + }, + "evmVersion": "byzantium", + "metadata": { + "useLiteralContent": true + }, + "key1": "test" + } } diff --git a/test/libevmasm/Optimiser.cpp b/test/libevmasm/Optimiser.cpp index e1795d391ce2..04d41fffeb18 100644 --- a/test/libevmasm/Optimiser.cpp +++ b/test/libevmasm/Optimiser.cpp @@ -1358,11 +1358,11 @@ BOOST_AUTO_TEST_CASE(cse_verbatim_mload) auto verbatim = AssemblyItem{bytes{1, 2, 3, 4, 5}, 0, 0}; AssemblyItems input{ u256(1000), - Instruction::MLOAD, // Should not be removed + Instruction::MLOAD, // Should not be removed Instruction::POP, verbatim, u256(1000), - Instruction::MLOAD, // Should not be removed + Instruction::MLOAD, // Should not be removed Instruction::POP, }; diff --git a/test/libsolidity/SemanticTest.cpp b/test/libsolidity/SemanticTest.cpp index 381ec5bda54e..63e8a924abca 100644 --- a/test/libsolidity/SemanticTest.cpp +++ b/test/libsolidity/SemanticTest.cpp @@ -157,7 +157,7 @@ std::map SemanticTest::makeBuiltins() { soltestAssert(_call.arguments.parameters.empty(), "No arguments expected."); return toBigEndian(u256(storageEmpty(m_contractAddress) ? 1 : 0)); - } + } }, { "account", diff --git a/test/libsolidity/SolidityEndToEndTest.cpp b/test/libsolidity/SolidityEndToEndTest.cpp index e34df0307c79..e321a5298603 100644 --- a/test/libsolidity/SolidityEndToEndTest.cpp +++ b/test/libsolidity/SolidityEndToEndTest.cpp @@ -1680,29 +1680,29 @@ BOOST_AUTO_TEST_CASE(array_copy_storage_abi) //BOOST_AUTO_TEST_CASE(assignment_to_const_array_vars) //{ -// char const* sourceCode = R"( -// contract C { -// uint[3] constant x = [uint(1), 2, 3]; -// uint constant y = x[0] + x[1] + x[2]; -// function f() public returns (uint) { return y; } -// } -// )"; -// compileAndRun(sourceCode); -// ABI_CHECK(callContractFunction("f()"), encodeArgs(1 + 2 + 3)); +// char const* sourceCode = R"( +// contract C { +// uint[3] constant x = [uint(1), 2, 3]; +// uint constant y = x[0] + x[1] + x[2]; +// function f() public returns (uint) { return y; } +// } +// )"; +// compileAndRun(sourceCode); +// ABI_CHECK(callContractFunction("f()"), encodeArgs(1 + 2 + 3)); //} // Disabled until https://github.com/ethereum/solidity/issues/715 is implemented //BOOST_AUTO_TEST_CASE(constant_struct) //{ -// char const* sourceCode = R"( -// contract C { -// struct S { uint x; uint[] y; } -// S constant x = S(5, new uint[](4)); -// function f() public returns (uint) { return x.x; } -// } -// )"; -// compileAndRun(sourceCode); -// ABI_CHECK(callContractFunction("f()"), encodeArgs(5)); +// char const* sourceCode = R"( +// contract C { +// struct S { uint x; uint[] y; } +// S constant x = S(5, new uint[](4)); +// function f() public returns (uint) { return x.x; } +// } +// )"; +// compileAndRun(sourceCode); +// ABI_CHECK(callContractFunction("f()"), encodeArgs(5)); //} BOOST_AUTO_TEST_CASE(evm_exceptions_in_constructor_out_of_baund) diff --git a/test/libsolidity/SolidityOptimizer.cpp b/test/libsolidity/SolidityOptimizer.cpp index 27f1a7e847bb..d52ad6b9c48a 100644 --- a/test/libsolidity/SolidityOptimizer.cpp +++ b/test/libsolidity/SolidityOptimizer.cpp @@ -291,7 +291,7 @@ BOOST_AUTO_TEST_CASE(retain_information_in_branches) numSHA3s++; }); // TEST DISABLED - OPTIMIZER IS NOT EFFECTIVE ON THIS ONE ANYMORE -// BOOST_CHECK_EQUAL(1, numSHA3s); +// BOOST_CHECK_EQUAL(1, numSHA3s); } BOOST_AUTO_TEST_CASE(store_tags_as_unions) @@ -334,7 +334,7 @@ BOOST_AUTO_TEST_CASE(store_tags_as_unions) numSHA3s++; }); // TEST DISABLED UNTIL 93693404 IS IMPLEMENTED -// BOOST_CHECK_EQUAL(2, numSHA3s); +// BOOST_CHECK_EQUAL(2, numSHA3s); } BOOST_AUTO_TEST_CASE(incorrect_storage_access_bug) diff --git a/test/libsolidity/StandardCompiler.cpp b/test/libsolidity/StandardCompiler.cpp index 7fafa2a62e08..22db222ea5af 100644 --- a/test/libsolidity/StandardCompiler.cpp +++ b/test/libsolidity/StandardCompiler.cpp @@ -1220,7 +1220,7 @@ BOOST_AUTO_TEST_CASE(optimizer_settings_details_different) BOOST_CHECK( optimizer["details"]["yulDetails"]["optimizerSteps"].asString() == OptimiserSettings::DefaultYulOptimiserSteps + ":"s + OptimiserSettings::DefaultYulOptimiserCleanupSteps - ); + ); BOOST_CHECK_EQUAL(optimizer["details"].getMemberNames().size(), 10); BOOST_CHECK(optimizer["runs"].asUInt() == 600); } diff --git a/test/libsolidity/natspecJSON/dev_multiple_params_mixed_whitespace.sol b/test/libsolidity/natspecJSON/dev_multiple_params_mixed_whitespace.sol index 61f45aa6204d..fc3fd4d71f90 100644 --- a/test/libsolidity/natspecJSON/dev_multiple_params_mixed_whitespace.sol +++ b/test/libsolidity/natspecJSON/dev_multiple_params_mixed_whitespace.sol @@ -1,7 +1,7 @@ contract test { - /// @dev Multiplies a number by 7 and adds second parameter - /// @param a Documentation for the first parameter - /// @param second Documentation for the second parameter + /// @dev Multiplies a number by 7 and adds second parameter + /// @param a Documentation for the first parameter + /// @param second Documentation for the second parameter function mul(uint a, uint second) public returns (uint d) { return a * 7 + second; } } diff --git a/test/libsolidity/smtCheckerTests/functions/functions_library_internal.sol b/test/libsolidity/smtCheckerTests/functions/functions_library_internal.sol index 405c3f71507e..d2f2d6923de1 100644 --- a/test/libsolidity/smtCheckerTests/functions/functions_library_internal.sol +++ b/test/libsolidity/smtCheckerTests/functions/functions_library_internal.sol @@ -7,7 +7,7 @@ contract C { function f() public { function()internal x; x.value(42); - } + } } // ==== // SMTEngine: all diff --git a/test/libsolidity/smtCheckerTests/loops/do_while_bmc_iterations_break_6.sol b/test/libsolidity/smtCheckerTests/loops/do_while_bmc_iterations_break_6.sol index d0a917fa915c..4880b3a0d5c3 100644 --- a/test/libsolidity/smtCheckerTests/loops/do_while_bmc_iterations_break_6.sol +++ b/test/libsolidity/smtCheckerTests/loops/do_while_bmc_iterations_break_6.sol @@ -4,7 +4,7 @@ contract C { do { ++x; if (x > 0) { - x = 2; + x = 2; break; } if (x > 1) { diff --git a/test/libsolidity/smtCheckerTests/loops/do_while_bmc_iterations_break_7.sol b/test/libsolidity/smtCheckerTests/loops/do_while_bmc_iterations_break_7.sol index 52c3270ba7ea..5b4d6579bff7 100644 --- a/test/libsolidity/smtCheckerTests/loops/do_while_bmc_iterations_break_7.sol +++ b/test/libsolidity/smtCheckerTests/loops/do_while_bmc_iterations_break_7.sol @@ -6,11 +6,11 @@ contract C { if (x > 1) { x = 3; break; - } + } if (x > 0) { x = 2; break; - } + } } while (x < 3); assert(x == 2); } diff --git a/test/libsolidity/smtCheckerTests/loops/do_while_bmc_iterations_break_continue_1.sol b/test/libsolidity/smtCheckerTests/loops/do_while_bmc_iterations_break_continue_1.sol index 53ce958fab1a..43a5f91f5ab5 100644 --- a/test/libsolidity/smtCheckerTests/loops/do_while_bmc_iterations_break_continue_1.sol +++ b/test/libsolidity/smtCheckerTests/loops/do_while_bmc_iterations_break_continue_1.sol @@ -4,11 +4,11 @@ contract C { do { if (x > 1) { break; - } + } if (x >= 0) { x = 10; continue; - } + } } while (x < 3); assert(x == 10); } diff --git a/test/libsolidity/smtCheckerTests/loops/do_while_bmc_iterations_break_continue_2.sol b/test/libsolidity/smtCheckerTests/loops/do_while_bmc_iterations_break_continue_2.sol index 12d6fff6f5a8..eed910118470 100644 --- a/test/libsolidity/smtCheckerTests/loops/do_while_bmc_iterations_break_continue_2.sol +++ b/test/libsolidity/smtCheckerTests/loops/do_while_bmc_iterations_break_continue_2.sol @@ -5,11 +5,11 @@ contract C { if (x > 1) { x = 3; break; - } + } if (x >= 0) { x = 2; continue; - } + } } while (x < 4); assert(x == 3); } diff --git a/test/libsolidity/smtCheckerTests/loops/for_loop_bmc_iterations_break_2.sol b/test/libsolidity/smtCheckerTests/loops/for_loop_bmc_iterations_break_2.sol index cada2d85195e..e7ff49daed1d 100644 --- a/test/libsolidity/smtCheckerTests/loops/for_loop_bmc_iterations_break_2.sol +++ b/test/libsolidity/smtCheckerTests/loops/for_loop_bmc_iterations_break_2.sol @@ -4,7 +4,7 @@ contract C uint x; for (uint i = 0; i < 3; ++i) { ++x; - break; + break; } assert(x == 1); } diff --git a/test/libsolidity/smtCheckerTests/loops/for_loop_bmc_iterations_break_8.sol b/test/libsolidity/smtCheckerTests/loops/for_loop_bmc_iterations_break_8.sol index a88a031e75e1..de3237838929 100644 --- a/test/libsolidity/smtCheckerTests/loops/for_loop_bmc_iterations_break_8.sol +++ b/test/libsolidity/smtCheckerTests/loops/for_loop_bmc_iterations_break_8.sol @@ -3,7 +3,7 @@ contract C function f() public pure { uint x; for (;;) { - break; + break; ++x; } assert(x == 0); diff --git a/test/libsolidity/smtCheckerTests/loops/for_loop_bmc_iterations_break_9.sol b/test/libsolidity/smtCheckerTests/loops/for_loop_bmc_iterations_break_9.sol index 4ce3d9268e89..8106ba30f9f8 100644 --- a/test/libsolidity/smtCheckerTests/loops/for_loop_bmc_iterations_break_9.sol +++ b/test/libsolidity/smtCheckerTests/loops/for_loop_bmc_iterations_break_9.sol @@ -4,7 +4,7 @@ contract C uint x; for (;x < 2;) { ++x; - break; + break; } assert(x == 1); } diff --git a/test/libsolidity/smtCheckerTests/loops/for_loop_bmc_iterations_break_continue_1.sol b/test/libsolidity/smtCheckerTests/loops/for_loop_bmc_iterations_break_continue_1.sol index b999f9cf6176..1dbe81a96929 100644 --- a/test/libsolidity/smtCheckerTests/loops/for_loop_bmc_iterations_break_continue_1.sol +++ b/test/libsolidity/smtCheckerTests/loops/for_loop_bmc_iterations_break_continue_1.sol @@ -5,11 +5,11 @@ contract C for (uint i = 0; i < 3; ++i) { if (i > 1) { break; - } + } if (i >= 0) { x = 10; continue; - } + } } assert(x == 10); } diff --git a/test/libsolidity/smtCheckerTests/loops/for_loop_bmc_iterations_break_continue_2.sol b/test/libsolidity/smtCheckerTests/loops/for_loop_bmc_iterations_break_continue_2.sol index 0da0f5d9940f..1781f77ce7f4 100644 --- a/test/libsolidity/smtCheckerTests/loops/for_loop_bmc_iterations_break_continue_2.sol +++ b/test/libsolidity/smtCheckerTests/loops/for_loop_bmc_iterations_break_continue_2.sol @@ -6,7 +6,7 @@ contract C if (i > 0) { x = 1; break; - } + } if (i >= 0) { x = 2; continue; diff --git a/test/libsolidity/smtCheckerTests/loops/for_loop_bmc_iterations_break_continue_3.sol b/test/libsolidity/smtCheckerTests/loops/for_loop_bmc_iterations_break_continue_3.sol index 9f762bb43674..9336127581b5 100644 --- a/test/libsolidity/smtCheckerTests/loops/for_loop_bmc_iterations_break_continue_3.sol +++ b/test/libsolidity/smtCheckerTests/loops/for_loop_bmc_iterations_break_continue_3.sol @@ -6,7 +6,7 @@ contract C if (i > 0) { x = 1; break; - } else { + } else { x = 2; continue; } diff --git a/test/libsolidity/smtCheckerTests/loops/for_loop_bmc_iterations_continue_3.sol b/test/libsolidity/smtCheckerTests/loops/for_loop_bmc_iterations_continue_3.sol index b74709e484fd..6f999a14cf7f 100644 --- a/test/libsolidity/smtCheckerTests/loops/for_loop_bmc_iterations_continue_3.sol +++ b/test/libsolidity/smtCheckerTests/loops/for_loop_bmc_iterations_continue_3.sol @@ -7,7 +7,7 @@ contract C x = 10; continue; } - if (x > 0) { + if (x > 0) { x = 11; continue; } diff --git a/test/libsolidity/smtCheckerTests/loops/while_bmc_iterations_8.sol b/test/libsolidity/smtCheckerTests/loops/while_bmc_iterations_8.sol index b7ad4e2ecb0b..69c49d8f8982 100644 --- a/test/libsolidity/smtCheckerTests/loops/while_bmc_iterations_8.sol +++ b/test/libsolidity/smtCheckerTests/loops/while_bmc_iterations_8.sol @@ -3,7 +3,7 @@ contract C uint256[] y; function f() public view { - uint256 x = 0; + uint256 x = 0; while (x < y.length) { x = 1; } diff --git a/test/libsolidity/smtCheckerTests/loops/while_bmc_iterations_break_4.sol b/test/libsolidity/smtCheckerTests/loops/while_bmc_iterations_break_4.sol index d1939871bf39..989130a138ae 100644 --- a/test/libsolidity/smtCheckerTests/loops/while_bmc_iterations_break_4.sol +++ b/test/libsolidity/smtCheckerTests/loops/while_bmc_iterations_break_4.sol @@ -4,7 +4,7 @@ contract C { while (x < 3) { ++x; if (x > 0) { - ++x; + ++x; break; } } diff --git a/test/libsolidity/smtCheckerTests/loops/while_bmc_iterations_break_6.sol b/test/libsolidity/smtCheckerTests/loops/while_bmc_iterations_break_6.sol index 0546e48c0ddb..9f2bdd1aa224 100644 --- a/test/libsolidity/smtCheckerTests/loops/while_bmc_iterations_break_6.sol +++ b/test/libsolidity/smtCheckerTests/loops/while_bmc_iterations_break_6.sol @@ -4,7 +4,7 @@ contract C { while (x < 3) { ++x; if (x > 0) { - x = 2; + x = 2; break; } if (x > 1) { diff --git a/test/libsolidity/smtCheckerTests/loops/while_bmc_iterations_break_7.sol b/test/libsolidity/smtCheckerTests/loops/while_bmc_iterations_break_7.sol index 8e4d3b6261d0..c1aca1bcc328 100644 --- a/test/libsolidity/smtCheckerTests/loops/while_bmc_iterations_break_7.sol +++ b/test/libsolidity/smtCheckerTests/loops/while_bmc_iterations_break_7.sol @@ -6,11 +6,11 @@ contract C { if (x > 1) { x = 3; break; - } + } if (x > 0) { x = 2; break; - } + } } assert(x == 2); } diff --git a/test/libsolidity/smtCheckerTests/loops/while_bmc_iterations_break_continue_1.sol b/test/libsolidity/smtCheckerTests/loops/while_bmc_iterations_break_continue_1.sol index bb9554523453..6332d20e3e29 100644 --- a/test/libsolidity/smtCheckerTests/loops/while_bmc_iterations_break_continue_1.sol +++ b/test/libsolidity/smtCheckerTests/loops/while_bmc_iterations_break_continue_1.sol @@ -4,11 +4,11 @@ contract C { while (x < 3) { if (x > 1) { break; - } + } if (x >= 0) { x = 10; continue; - } + } } assert(x == 10); } diff --git a/test/libsolidity/smtCheckerTests/loops/while_bmc_iterations_break_continue_2.sol b/test/libsolidity/smtCheckerTests/loops/while_bmc_iterations_break_continue_2.sol index b65404e22f76..c4e47d528961 100644 --- a/test/libsolidity/smtCheckerTests/loops/while_bmc_iterations_break_continue_2.sol +++ b/test/libsolidity/smtCheckerTests/loops/while_bmc_iterations_break_continue_2.sol @@ -5,11 +5,11 @@ contract C { if (x > 1) { x = 3; break; - } + } if (x >= 0) { x = 2; continue; - } + } } assert(x == 3); } diff --git a/test/libsolidity/smtCheckerTests/loops/while_bmc_iterations_semantics_2.sol b/test/libsolidity/smtCheckerTests/loops/while_bmc_iterations_semantics_2.sol index a50acf4d2b4e..5b22ca942628 100644 --- a/test/libsolidity/smtCheckerTests/loops/while_bmc_iterations_semantics_2.sol +++ b/test/libsolidity/smtCheckerTests/loops/while_bmc_iterations_semantics_2.sol @@ -7,7 +7,7 @@ contract C { y = 1; ++x; } - // BMC loop iteration setting is just enough to leave the loop + // BMC loop iteration setting is just enough to leave the loop assert(x == 3); assert(y == 1); // should fail assert(y == 0); diff --git a/test/libsolidity/smtCheckerTests/operators/delete_multid_array.sol b/test/libsolidity/smtCheckerTests/operators/delete_multid_array.sol index 53a1a253e00e..ea6eb3a9aa0a 100644 --- a/test/libsolidity/smtCheckerTests/operators/delete_multid_array.sol +++ b/test/libsolidity/smtCheckerTests/operators/delete_multid_array.sol @@ -9,21 +9,21 @@ contract C { delete a; assert(a.length == 0); } - function g(uint x, uint y, uint v) public { + function g(uint x, uint y, uint v) public { require(x < b.length); require(y < b[x].length); b[x][y] = v; delete b; assert(b.length == 0); } - function h(uint x, uint y, uint v) public { + function h(uint x, uint y, uint v) public { require(x < b.length); require(y < b[x].length); b[x][y] = v; delete b[x]; assert(b[x].length == 0); } - function i(uint x, uint y, uint v) public { + function i(uint x, uint y, uint v) public { require(x < b.length); require(y < b[x].length); b[x][y] = v; @@ -31,7 +31,7 @@ contract C { delete b[y]; assert(b[y].length == 0); } - function j(uint x, uint y, uint z, uint v) public { + function j(uint x, uint y, uint z, uint v) public { require(x < b.length); require(y < b[x].length); b[x][y] = v; diff --git a/test/libsolidity/util/TestFunctionCallTests.cpp b/test/libsolidity/util/TestFunctionCallTests.cpp index 5741ccd0debe..72e5c7393f2a 100644 --- a/test/libsolidity/util/TestFunctionCallTests.cpp +++ b/test/libsolidity/util/TestFunctionCallTests.cpp @@ -85,7 +85,7 @@ BOOST_AUTO_TEST_CASE(format_unsigned_multiline) call.displayMode = FunctionCall::DisplayMode::MultiLine; TestFunctionCall test{call}; - BOOST_REQUIRE_EQUAL(test.format(), "// f(uint8)\n// -> 1"); + BOOST_REQUIRE_EQUAL(test.format(), "// f(uint8)\n// -> 1"); } BOOST_AUTO_TEST_CASE(format_multiple_unsigned_singleline) diff --git a/test/libyul/Parser.cpp b/test/libyul/Parser.cpp index c9b9ec0727f7..69314abee136 100644 --- a/test/libyul/Parser.cpp +++ b/test/libyul/Parser.cpp @@ -450,12 +450,12 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_mixed_locations_3) ErrorReporter reporter(errorList); auto const sourceText = R"( /// @src 1:23:45 - { // Block - { // Block - sstore(0, 1) // FunctionCall + { // Block + { // Block + sstore(0, 1) // FunctionCall /// @src 0:420:680 } - mstore(1, 2) // FunctionCall + mstore(1, 2) // FunctionCall } )"; EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); diff --git a/test/libyul/StackShufflingTest.cpp b/test/libyul/StackShufflingTest.cpp index 7c85a931e2c8..e53eeafbb03c 100644 --- a/test/libyul/StackShufflingTest.cpp +++ b/test/libyul/StackShufflingTest.cpp @@ -56,12 +56,12 @@ bool StackShufflingTest::parse(std::string const& _source) scanner.next(); std::string functionName = scanner.currentLiteral(); auto call = yul::FunctionCall{ - {}, yul::Identifier{{}, YulString(functionName)}, {} + {}, yul::Identifier{{}, YulString(functionName)}, {} }; stack.emplace_back(FunctionCallReturnLabelSlot{ - m_functions.insert( - make_pair(functionName, call) - ).first->second + m_functions.insert( + make_pair(functionName, call) + ).first->second }); expectToken(Token::RBrack); } @@ -78,14 +78,14 @@ bool StackShufflingTest::parse(std::string const& _source) scanner.next(); std::string functionName = scanner.currentLiteral(); auto call = yul::FunctionCall{ - {}, yul::Identifier{{}, YulString(functionName)}, {} - }; + {}, yul::Identifier{{}, YulString(functionName)}, {} + }; expectToken(Token::Comma); scanner.next(); size_t index = size_t(atoi(scanner.currentLiteral().c_str())); stack.emplace_back(TemporarySlot{ - m_functions.insert(make_pair(functionName, call)).first->second, - index + m_functions.insert(make_pair(functionName, call)).first->second, + index }); expectToken(Token::RBrack); } @@ -104,7 +104,7 @@ bool StackShufflingTest::parse(std::string const& _source) std::string ghostVariableId = scanner.currentLiteral(); Scope::Variable ghostVar = Scope::Variable{""_yulstring, YulString(literal + "[" + ghostVariableId + "]")}; stack.emplace_back(VariableSlot{ - m_variables.insert(std::make_pair(ghostVar.name, ghostVar)).first->second + m_variables.insert(std::make_pair(ghostVar.name, ghostVar)).first->second }); expectToken(Token::RBrack); } @@ -112,9 +112,9 @@ bool StackShufflingTest::parse(std::string const& _source) { Scope::Variable var = Scope::Variable{""_yulstring, YulString(literal)}; stack.emplace_back(VariableSlot{ - m_variables.insert( - make_pair(literal, var) - ).first->second + m_variables.insert( + make_pair(literal, var) + ).first->second }); } scanner.next(); diff --git a/test/libyul/YulOptimizerTestCommon.cpp b/test/libyul/YulOptimizerTestCommon.cpp index e529f1d95d32..ea68f8dcd420 100644 --- a/test/libyul/YulOptimizerTestCommon.cpp +++ b/test/libyul/YulOptimizerTestCommon.cpp @@ -422,7 +422,7 @@ std::string YulOptimizerTestCommon::randomOptimiserStep(unsigned _seed) // Do not fuzz reasoning based simplifier because // it can sometimes drain memory. if ( - optimiserStep == "mainFunction" || + optimiserStep == "mainFunction" || optimiserStep == "wordSizeTransform" ) // "Fullsuite" is fuzzed roughly four times more frequently than diff --git a/test/libyul/yulOptimizerTests/circularReferencesPruner/nested_different_names.yul b/test/libyul/yulOptimizerTests/circularReferencesPruner/nested_different_names.yul index f78b9fb99234..2cde783c1a59 100644 --- a/test/libyul/yulOptimizerTests/circularReferencesPruner/nested_different_names.yul +++ b/test/libyul/yulOptimizerTests/circularReferencesPruner/nested_different_names.yul @@ -1,11 +1,11 @@ { { - function a() -> x { x := b() } - function b() -> y { y := a() } + function a() -> x { x := b() } + function b() -> y { y := a() } } { - function c() -> z { z := d() } - function d() -> w { w := c() } + function c() -> z { z := d() } + function d() -> w { w := c() } } } // ---- diff --git a/test/libyul/yulOptimizerTests/circularReferencesPruner/nested_same_name.yul b/test/libyul/yulOptimizerTests/circularReferencesPruner/nested_same_name.yul index 858a48d85baa..112f9fdccdde 100644 --- a/test/libyul/yulOptimizerTests/circularReferencesPruner/nested_same_name.yul +++ b/test/libyul/yulOptimizerTests/circularReferencesPruner/nested_same_name.yul @@ -1,11 +1,11 @@ { { - function z() -> x { x := y() } - function y() -> x { x := z() } + function z() -> x { x := y() } + function y() -> x { x := z() } } { - function z() -> x { x := y() } - function y() -> x { x := z() } + function z() -> x { x := y() } + function y() -> x { x := z() } } } // ---- diff --git a/test/libyul/yulOptimizerTests/expressionSimplifier/return_vars_zero.yul b/test/libyul/yulOptimizerTests/expressionSimplifier/return_vars_zero.yul index 73a79410dfeb..f9191afb6bbc 100644 --- a/test/libyul/yulOptimizerTests/expressionSimplifier/return_vars_zero.yul +++ b/test/libyul/yulOptimizerTests/expressionSimplifier/return_vars_zero.yul @@ -1,7 +1,7 @@ // return variables are assumed to be zero initially. { function f() -> c, d { - let y := add(d, add(c, 7)) + let y := add(d, add(c, 7)) sstore(0, y) } let t, v := f() diff --git a/test/libyul/yulOptimizerTests/fullSuite/static_array_slot_computation.yul b/test/libyul/yulOptimizerTests/fullSuite/static_array_slot_computation.yul index bf74af6f4713..6dc1d8c94b7c 100644 --- a/test/libyul/yulOptimizerTests/fullSuite/static_array_slot_computation.yul +++ b/test/libyul/yulOptimizerTests/fullSuite/static_array_slot_computation.yul @@ -1,8 +1,8 @@ // The yul code for the following contract -// contract C { -// uint256[] x; -// function f() public { x[10] = 5; } -// } +// contract C { +// uint256[] x; +// function f() public { x[10] = 5; } +// } { let _1 := 0 diff --git a/test/tools/ossfuzz/protoToAbiV2.cpp b/test/tools/ossfuzz/protoToAbiV2.cpp index 98de7dd359ba..af2e5ede1b78 100644 --- a/test/tools/ossfuzz/protoToAbiV2.cpp +++ b/test/tools/ossfuzz/protoToAbiV2.cpp @@ -53,8 +53,8 @@ BOOST_PP_REPEAT(32, USINGDECL, 0) ostringstream stream; \ switch (_intWidth) \ { \ - BOOST_PP_REPEAT(32, CASEIMPL, sign) \ - } \ + BOOST_PP_REPEAT(32, CASEIMPL, sign) \ + } \ return stream.str(); using namespace std; @@ -103,7 +103,7 @@ string ProtoConverter::getVarDecl( // One level of indentation for state variable declarations // Two levels of indentation for local variable declarations return Whiskers(R"( - ;)" + ;)" ) ("isLocalVar", !m_isStateVar) ("type", _type) diff --git a/test/tools/ossfuzz/protoToAbiV2.h b/test/tools/ossfuzz/protoToAbiV2.h index be583d49711c..803c0e7b3461 100644 --- a/test/tools/ossfuzz/protoToAbiV2.h +++ b/test/tools/ossfuzz/protoToAbiV2.h @@ -19,116 +19,116 @@ /** * Template of the solidity test program generated by this converter is as follows: * - * pragma solidity >=0.0; - * pragma experimental ABIEncoderV2; + * pragma solidity >=0.0; + * pragma experimental ABIEncoderV2; * - * contract C { - * // State variable - * string sv_0; - * // Test function that is called by the VM. - * // There are 2 variations of this function: one returns - * // the output of test_calldata_coding() and the other - * // returns the output of test_returndata_coding(). The - * // proto field called Test decides which one of the two - * // are chosen for creating a test case. - * function test() public returns (uint) { - * // The protobuf field "Contract.test" decides which of - * // the two internal functions "test_calldata_coding()" - * // and "test_returndata_coding()" are called. Here, - * // we assume that the protobuf field equals "CALLDATA_CODER" - * return this.test_calldata_coding() - * } + * contract C { + * // State variable + * string sv_0; + * // Test function that is called by the VM. + * // There are 2 variations of this function: one returns + * // the output of test_calldata_coding() and the other + * // returns the output of test_returndata_coding(). The + * // proto field called Test decides which one of the two + * // are chosen for creating a test case. + * function test() public returns (uint) { + * // The protobuf field "Contract.test" decides which of + * // the two internal functions "test_calldata_coding()" + * // and "test_returndata_coding()" are called. Here, + * // we assume that the protobuf field equals "CALLDATA_CODER" + * return this.test_calldata_coding() + * } * - * // The following function is generated if the protobuf field - * // "Contract.test" is equal to "RETURNDATA_CODER". - * function test_returndata_coding() internal returns (uint) { - * string memory lv_0, bytes memory lv_1 = test_returndata_external(); - * if (lv_0 != 044852b2a670ade5407e78fb2863c51de9fcb96542a07186fe3aeda6bb8a116d) - * return 1; - * if (lv_1 != "1") - * return 2; - * return 0; - * } + * // The following function is generated if the protobuf field + * // "Contract.test" is equal to "RETURNDATA_CODER". + * function test_returndata_coding() internal returns (uint) { + * string memory lv_0, bytes memory lv_1 = test_returndata_external(); + * if (lv_0 != 044852b2a670ade5407e78fb2863c51de9fcb96542a07186fe3aeda6bb8a116d) + * return 1; + * if (lv_1 != "1") + * return 2; + * return 0; + * } * - * // The following function is generated if the protobuf field - * // "Contract.test" is equal to "RETURNDATA_CODER". - * function test_returndata_external() external returns (string memory, bytes memory) - * { - * sv_0 = "044852b2a670ade5407e78fb2863c51de9fcb96542a07186fe3aeda6bb8a116d"; - * bytes memory lv_0 = "1"; - * return (sv_0, lv_0); - * } + * // The following function is generated if the protobuf field + * // "Contract.test" is equal to "RETURNDATA_CODER". + * function test_returndata_external() external returns (string memory, bytes memory) + * { + * sv_0 = "044852b2a670ade5407e78fb2863c51de9fcb96542a07186fe3aeda6bb8a116d"; + * bytes memory lv_0 = "1"; + * return (sv_0, lv_0); + * } * - * // The following function is generated if the protobuf field - * // "Contract.test" is equal to "CALLDATA_CODER". - * function test_calldata_coding() internal returns (uint) { - * // Local variable - * bytes lv_1 = "1"; - * sv_0 = "044852b2a670ade5407e78fb2863c51de9fcb96542a07186fe3aeda6bb8a116d"; - * uint returnVal = this.coder_public(sv_0, lv_1); - * if (returnVal != 0) - * return returnVal; - * // Since the return codes in the public and external coder functions are identical - * // we offset error code by a fixed amount (200000) for differentiation. - * returnVal = this.coder_external(sv_0, lv_1); - * if (returnVal != 0) - * return 200000 + returnVal; - * // Encode parameters - * bytes memory argumentEncoding = abi.encode(); - * returnVal = checkEncodedCall(this.coder_public.selector, argumentEncoding, ); - * // Check if calls to coder_public meet expectations for correctly/incorrectly encoded data. - * if (returnVal != 0) - * return returnVal; + * // The following function is generated if the protobuf field + * // "Contract.test" is equal to "CALLDATA_CODER". + * function test_calldata_coding() internal returns (uint) { + * // Local variable + * bytes lv_1 = "1"; + * sv_0 = "044852b2a670ade5407e78fb2863c51de9fcb96542a07186fe3aeda6bb8a116d"; + * uint returnVal = this.coder_public(sv_0, lv_1); + * if (returnVal != 0) + * return returnVal; + * // Since the return codes in the public and external coder functions are identical + * // we offset error code by a fixed amount (200000) for differentiation. + * returnVal = this.coder_external(sv_0, lv_1); + * if (returnVal != 0) + * return 200000 + returnVal; + * // Encode parameters + * bytes memory argumentEncoding = abi.encode(); + * returnVal = checkEncodedCall(this.coder_public.selector, argumentEncoding, ); + * // Check if calls to coder_public meet expectations for correctly/incorrectly encoded data. + * if (returnVal != 0) + * return returnVal; * - * returnVal = checkEncodedCall(this.coder_external.selector, argumentEncoding, ); - * // Check if calls to coder_external meet expectations for correctly/incorrectly encoded data. - * // Offset return value to distinguish between failures originating from coder_public and coder_external. - * if (returnVal != 0) - * return uint(200000) + returnVal; - * // Return zero if all checks pass. - * return 0; - * } + * returnVal = checkEncodedCall(this.coder_external.selector, argumentEncoding, ); + * // Check if calls to coder_external meet expectations for correctly/incorrectly encoded data. + * // Offset return value to distinguish between failures originating from coder_public and coder_external. + * if (returnVal != 0) + * return uint(200000) + returnVal; + * // Return zero if all checks pass. + * return 0; + * } * - * /// Accepts function selector, correct argument encoding, and an invalid encoding length as input. - * /// Returns a non-zero value if either call with correct encoding fails or call with incorrect encoding - * /// succeeds. Returns zero if both calls meet expectation. - * function checkEncodedCall(bytes4 funcSelector, bytes memory argumentEncoding, uint invalidLengthFuzz) - * public returns (uint) { - * ... - * } + * /// Accepts function selector, correct argument encoding, and an invalid encoding length as input. + * /// Returns a non-zero value if either call with correct encoding fails or call with incorrect encoding + * /// succeeds. Returns zero if both calls meet expectation. + * function checkEncodedCall(bytes4 funcSelector, bytes memory argumentEncoding, uint invalidLengthFuzz) + * public returns (uint) { + * ... + * } * - * /// Accepts function selector, correct argument encoding, and length of invalid encoding and returns - * /// the correct and incorrect abi encoding for calling the function specified by the function selector. - * function createEncoding(bytes4 funcSelector, bytes memory argumentEncoding, uint invalidLengthFuzz) - * internal pure returns (bytes memory, bytes memory) { - * ... - * } + * /// Accepts function selector, correct argument encoding, and length of invalid encoding and returns + * /// the correct and incorrect abi encoding for calling the function specified by the function selector. + * function createEncoding(bytes4 funcSelector, bytes memory argumentEncoding, uint invalidLengthFuzz) + * internal pure returns (bytes memory, bytes memory) { + * ... + * } * - * /// Compares two dynamically sized bytes arrays for equality. - * function bytesCompare(bytes memory a, bytes memory b) internal pure returns (bool) { - * ... - * } + * /// Compares two dynamically sized bytes arrays for equality. + * function bytesCompare(bytes memory a, bytes memory b) internal pure returns (bool) { + * ... + * } * - * // Public function that is called by test() function. Accepts one or more arguments and returns - * // a uint value (zero if abi en/decoding was successful, non-zero otherwise) - * function coder_public(string memory c_0, bytes memory c_1) public pure returns (uint) { - * if (!bytesCompare(bytes(c_0), "044852b2a670ade5407e78fb2863c51de9fcb96542a07186fe3aeda6bb8a116d")) - * return 1; - * if (!bytesCompare(c_1, "1")) - * return 2; - * return 0; - * } + * // Public function that is called by test() function. Accepts one or more arguments and returns + * // a uint value (zero if abi en/decoding was successful, non-zero otherwise) + * function coder_public(string memory c_0, bytes memory c_1) public pure returns (uint) { + * if (!bytesCompare(bytes(c_0), "044852b2a670ade5407e78fb2863c51de9fcb96542a07186fe3aeda6bb8a116d")) + * return 1; + * if (!bytesCompare(c_1, "1")) + * return 2; + * return 0; + * } * - * // External function that is called by test() function. Accepts one or more arguments and returns - * // a uint value (zero if abi en/decoding was successful, non-zero otherwise) - * function coder_external(string calldata c_0, bytes calldata c_1) external pure returns (uint) { - * if (!bytesCompare(bytes(c_0), "044852b2a670ade5407e78fb2863c51de9fcb96542a07186fe3aeda6bb8a116d")) - * return 1; - * if (!bytesCompare(c_1, "1")) - * return 2; - * return 0; - * } - * } + * // External function that is called by test() function. Accepts one or more arguments and returns + * // a uint value (zero if abi en/decoding was successful, non-zero otherwise) + * function coder_external(string calldata c_0, bytes calldata c_1) external pure returns (uint) { + * if (!bytesCompare(bytes(c_0), "044852b2a670ade5407e78fb2863c51de9fcb96542a07186fe3aeda6bb8a116d")) + * return 1; + * if (!bytesCompare(c_1, "1")) + * return 2; + * return 0; + * } + * } */ namespace solidity::test::abiv2fuzzer diff --git a/test/tools/ossfuzz/protoToYul.h b/test/tools/ossfuzz/protoToYul.h index c264dd51af13..2ae54f68a0b1 100644 --- a/test/tools/ossfuzz/protoToYul.h +++ b/test/tools/ossfuzz/protoToYul.h @@ -199,9 +199,9 @@ class ProtoConverter /// Prints a Yul formatted variable declaration statement to the output /// stream. /// Example 1: createVarDecls(0, 1, true) returns {"x_0"} and prints - /// let x_0 := + /// let x_0 := /// Example 2: createVarDecls(0, 2, false) returns {"x_0", "x_1"} and prints - /// let x_0, x_1 + /// let x_0, x_1 /// @param _start Start index of variable (inclusive) /// @param _end End index of variable (exclusive) /// @param _isAssignment Flag indicating if variable declaration is also @@ -215,7 +215,7 @@ class ProtoConverter /// Prints comma separated variable names to output stream and /// returns a vector containing the printed variable names. /// Example: createVars(0, 2) returns {"x_0", "x_1"} and prints - /// x_0, x_1 + /// x_0, x_1 /// @param _startIdx Start index of variable (inclusive) /// @param _endIdx End index of variable (exclusive) /// @return A vector of strings containing the printed variable names. @@ -264,7 +264,7 @@ class ProtoConverter /// @param _p Enum that decides if the returned token is hex prefixed ("0x") or not /// @return Dictionary token at the index computed using a /// monotonically increasing counter as follows: - /// index = (m_inputSize * m_inputSize + counter) % dictionarySize + /// index = (m_inputSize * m_inputSize + counter) % dictionarySize /// where m_inputSize is the size of the protobuf input and /// dictionarySize is the total number of entries in the dictionary. std::string dictionaryToken(util::HexPrefix _p = util::HexPrefix::Add); From 5cd92b57080bf6aa328c1527ea0fb1213afb0068 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Fri, 12 Apr 2024 23:33:16 +0200 Subject: [PATCH 0153/1022] Update text expectations --- .../model_checker_contracts_all/err | 12 +- .../output.json | 194 +++++------ .../output.json | 312 +++++++++--------- .../loops/for_loop_bmc_iterations_break_8.sol | 2 +- .../while_bmc_iterations_semantics_2.sol | 2 +- 5 files changed, 261 insertions(+), 261 deletions(-) diff --git a/test/cmdlineTests/model_checker_contracts_all/err b/test/cmdlineTests/model_checker_contracts_all/err index 57b620b49b68..9135483d5f79 100644 --- a/test/cmdlineTests/model_checker_contracts_all/err +++ b/test/cmdlineTests/model_checker_contracts_all/err @@ -6,10 +6,10 @@ x = 0 Transaction trace: B.constructor() B.f(0) - --> model_checker_contracts_all/input.sol:5:3: + --> model_checker_contracts_all/input.sol:5:9: | -5 | assert(x > 0); - | ^^^^^^^^^^^^^ +5 | assert(x > 0); + | ^^^^^^^^^^^^^ Warning: CHC: Assertion violation happens here. Counterexample: @@ -19,7 +19,7 @@ y = 0 Transaction trace: A.constructor() A.g(0) - --> model_checker_contracts_all/input.sol:10:3: + --> model_checker_contracts_all/input.sol:10:9: | -10 | assert(y > 0); - | ^^^^^^^^^^^^^ +10 | assert(y > 0); + | ^^^^^^^^^^^^^ 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 143ad92c304a..97041b2380b5 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 @@ -7,7 +7,7 @@ { "evm": { - "assembly": " /* \"C\":79:428 contract C... */ + "assembly": " /* \"C\":79:503 contract C... */ 0xa0 jumpi(tag_5, callvalue) 0x1f @@ -49,10 +49,10 @@ tag_5 jumpi mload - /* \"C\":147:149 42 */ + /* \"C\":153:155 42 */ mstore(0x80, 0x2a) 0x00 - /* \"C\":79:428 contract C... */ + /* \"C\":79:503 contract C... */ sstore mload(0x40) dataSize(sub_0) @@ -61,9 +61,9 @@ dataOffset(sub_0) dup3 codecopy - /* \"C\":147:149 42 */ + /* \"C\":153:155 42 */ 0x80 - /* \"C\":79:428 contract C... */ + /* \"C\":79:503 contract C... */ mload dup2 assignImmutable(\"0xe4b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c10\") @@ -79,7 +79,7 @@ tag_3: stop sub_0: assembly { - /* \"C\":79:428 contract C... */ + /* \"C\":79:503 contract C... */ 0x80 0x40 swap1 @@ -129,21 +129,21 @@ sub_0: assembly { dup2 mload shl(0xe4, 0x026121ff) - /* \"C\":403:411 this.f() */ + /* \"C\":475:483 this.f() */ dup2 mstore - /* \"C\":79:428 contract C... */ + /* \"C\":79:503 contract C... */ swap2 swap1 - /* \"C\":403:411 this.f() */ + /* \"C\":475:483 this.f() */ 0x20 - /* \"C\":79:428 contract C... */ + /* \"C\":79:503 contract C... */ dup4 0x04 dup2 - /* \"C\":403:407 this */ + /* \"C\":475:479 this */ address - /* \"C\":403:411 this.f() */ + /* \"C\":475:483 this.f() */ gas staticcall swap3 @@ -151,50 +151,50 @@ sub_0: assembly { iszero tag_16 jumpi - /* \"C\":79:428 contract C... */ + /* \"C\":79:503 contract C... */ 0x00 - /* \"C\":403:411 this.f() */ + /* \"C\":475:483 this.f() */ swap4 tag_18 jumpi - /* \"C\":79:428 contract C... */ + /* \"C\":79:503 contract C... */ tag_19: - /* \"C\":392:411 stateVar + this.f() */ + /* \"C\":464:483 stateVar + this.f() */ pop tag_20 - /* \"C\":403:411 this.f() */ + /* \"C\":475:483 this.f() */ 0x20 - /* \"C\":392:411 stateVar + this.f() */ + /* \"C\":464:483 stateVar + this.f() */ swap4 - /* \"C\":392:422 stateVar + this.f() + immutVar */ + /* \"C\":464:494 stateVar + this.f() + immutVar */ tag_21 - /* \"C\":392:411 stateVar + this.f() */ + /* \"C\":464:483 stateVar + this.f() */ swap3 tag_1 jump\t// in tag_20: - /* \"C\":414:422 immutVar */ + /* \"C\":486:494 immutVar */ immutable(\"0xe4b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c10\") - /* \"C\":392:422 stateVar + this.f() + immutVar */ + /* \"C\":464:494 stateVar + this.f() + immutVar */ swap1 tag_1 jump\t// in tag_21: - /* \"C\":79:428 contract C... */ + /* \"C\":79:503 contract C... */ swap1 mload swap1 dup2 mstore return - /* \"C\":403:411 this.f() */ + /* \"C\":475:483 this.f() */ tag_18: swap3 pop 0x20 jumpi(tag_22, gt(0x20, returndatasize)) tag_23: - /* \"C\":79:428 contract C... */ + /* \"C\":79:503 contract C... */ 0x1f dup2 add @@ -211,18 +211,18 @@ sub_0: assembly { or tag_24 jumpi - /* \"C\":403:411 this.f() */ + /* \"C\":475:483 this.f() */ 0x20 - /* \"C\":79:428 contract C... */ + /* \"C\":79:503 contract C... */ swap2 dup6 swap2 dup6 mstore - /* \"C\":403:411 this.f() */ + /* \"C\":475:483 this.f() */ dup2 add - /* \"C\":79:428 contract C... */ + /* \"C\":79:503 contract C... */ sub slt tag_26 @@ -230,30 +230,30 @@ sub_0: assembly { swap2 mload swap2 - /* \"C\":392:411 stateVar + this.f() */ + /* \"C\":464:483 stateVar + this.f() */ tag_20 - /* \"C\":403:411 this.f() */ + /* \"C\":475:483 this.f() */ jump(tag_19) - /* \"C\":79:428 contract C... */ + /* \"C\":79:503 contract C... */ tag_26: 0x00 dup1 revert tag_24: - /* \"C\":117:119 41 */ + /* \"C\":120:122 41 */ shl(0xe0, 0x4e487b71) - /* \"C\":79:428 contract C... */ + /* \"C\":79:503 contract C... */ 0x00 mstore mstore(0x04, 0x41) revert(0x00, 0x24) - /* \"C\":403:411 this.f() */ + /* \"C\":475:483 this.f() */ tag_22: pop returndatasize jump(tag_23) tag_16: - /* \"C\":79:428 contract C... */ + /* \"C\":79:503 contract C... */ dup3 mload returndatasize @@ -264,23 +264,23 @@ sub_0: assembly { swap1 revert tag_14: - /* \"C\":117:119 41 */ + /* \"C\":120:122 41 */ shl(0xe0, 0x4e487b71) - /* \"C\":79:428 contract C... */ + /* \"C\":79:503 contract C... */ 0x00 - /* \"C\":117:119 41 */ + /* \"C\":120:122 41 */ mstore 0x11 - /* \"C\":79:428 contract C... */ + /* \"C\":79:503 contract C... */ 0x04 - /* \"C\":117:119 41 */ + /* \"C\":120:122 41 */ mstore 0x24 - /* \"C\":79:428 contract C... */ + /* \"C\":79:503 contract C... */ 0x00 - /* \"C\":117:119 41 */ + /* \"C\":120:122 41 */ revert - /* \"C\":79:428 contract C... */ + /* \"C\":79:503 contract C... */ tag_6: pop jumpi(tag_26, callvalue) @@ -297,9 +297,9 @@ sub_0: assembly { tag_4: jumpi(tag_26, callvalue) jumpi(tag_26, slt(add(not(0x03), calldatasize), 0x00)) - /* \"C\":290:298 immutVar */ + /* \"C\":326:334 immutVar */ immutable(\"0xe4b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c10\") - /* \"C\":117:119 41 */ + /* \"C\":120:122 41 */ swap1 dup2 0x29 @@ -311,13 +311,13 @@ sub_0: assembly { and tag_14 jumpi - /* \"C\":79:428 contract C... */ + /* \"C\":79:503 contract C... */ 0x20 swap2 dup2 mstore return - /* \"C\":117:119 41 */ + /* \"C\":120:122 41 */ tag_1: swap2 swap1 @@ -356,7 +356,7 @@ sub_0: assembly { { "evm": { - "assembly": " /* \"D\":91:166 contract D is C(3)... */ + "assembly": " /* \"D\":91:181 contract D is C(3)... */ 0xa0 jumpi(tag_5, callvalue) 0x1f @@ -398,13 +398,13 @@ sub_0: assembly { tag_5 jumpi mload - /* \"C\":147:149 42 */ + /* \"C\":153:155 42 */ mstore(0x80, 0x2a) - /* \"D\":91:166 contract D is C(3)... */ + /* \"D\":91:181 contract D is C(3)... */ dup1 /* \"D\":107:108 3 */ 0x03 - /* \"D\":91:166 contract D is C(3)... */ + /* \"D\":91:181 contract D is C(3)... */ add swap1 dup2 @@ -422,9 +422,9 @@ sub_0: assembly { dataOffset(sub_0) dup3 codecopy - /* \"C\":147:149 42 */ + /* \"C\":153:155 42 */ 0x80 - /* \"D\":91:166 contract D is C(3)... */ + /* \"D\":91:181 contract D is C(3)... */ mload dup2 assignImmutable(\"0xe4b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c10\") @@ -444,7 +444,7 @@ tag_3: stop sub_0: assembly { - /* \"D\":91:166 contract D is C(3)... */ + /* \"D\":91:181 contract D is C(3)... */ 0x80 0x40 swap1 @@ -494,21 +494,21 @@ sub_0: assembly { dup2 mload shl(0xe4, 0x026121ff) - /* \"C\":403:411 this.f() */ + /* \"C\":475:483 this.f() */ dup2 mstore - /* \"D\":91:166 contract D is C(3)... */ + /* \"D\":91:181 contract D is C(3)... */ swap2 swap1 - /* \"C\":403:411 this.f() */ + /* \"C\":475:483 this.f() */ 0x20 - /* \"D\":91:166 contract D is C(3)... */ + /* \"D\":91:181 contract D is C(3)... */ dup4 0x04 dup2 - /* \"C\":403:407 this */ + /* \"C\":475:479 this */ address - /* \"C\":403:411 this.f() */ + /* \"C\":475:483 this.f() */ gas staticcall swap3 @@ -516,50 +516,50 @@ sub_0: assembly { iszero tag_16 jumpi - /* \"D\":91:166 contract D is C(3)... */ + /* \"D\":91:181 contract D is C(3)... */ 0x00 - /* \"C\":403:411 this.f() */ + /* \"C\":475:483 this.f() */ swap4 tag_18 jumpi - /* \"D\":91:166 contract D is C(3)... */ + /* \"D\":91:181 contract D is C(3)... */ tag_19: - /* \"C\":392:411 stateVar + this.f() */ + /* \"C\":464:483 stateVar + this.f() */ pop tag_20 - /* \"C\":403:411 this.f() */ + /* \"C\":475:483 this.f() */ 0x20 - /* \"C\":392:411 stateVar + this.f() */ + /* \"C\":464:483 stateVar + this.f() */ swap4 - /* \"C\":392:422 stateVar + this.f() + immutVar */ + /* \"C\":464:494 stateVar + this.f() + immutVar */ tag_21 - /* \"C\":392:411 stateVar + this.f() */ + /* \"C\":464:483 stateVar + this.f() */ swap3 tag_1 jump\t// in tag_20: - /* \"C\":414:422 immutVar */ + /* \"C\":486:494 immutVar */ immutable(\"0xe4b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c10\") - /* \"C\":392:422 stateVar + this.f() + immutVar */ + /* \"C\":464:494 stateVar + this.f() + immutVar */ swap1 tag_1 jump\t// in tag_21: - /* \"D\":91:166 contract D is C(3)... */ + /* \"D\":91:181 contract D is C(3)... */ swap1 mload swap1 dup2 mstore return - /* \"C\":403:411 this.f() */ + /* \"C\":475:483 this.f() */ tag_18: swap3 pop 0x20 jumpi(tag_22, gt(0x20, returndatasize)) tag_23: - /* \"D\":91:166 contract D is C(3)... */ + /* \"D\":91:181 contract D is C(3)... */ 0x1f dup2 add @@ -576,18 +576,18 @@ sub_0: assembly { or tag_24 jumpi - /* \"C\":403:411 this.f() */ + /* \"C\":475:483 this.f() */ 0x20 - /* \"D\":91:166 contract D is C(3)... */ + /* \"D\":91:181 contract D is C(3)... */ swap2 dup6 swap2 dup6 mstore - /* \"C\":403:411 this.f() */ + /* \"C\":475:483 this.f() */ dup2 add - /* \"D\":91:166 contract D is C(3)... */ + /* \"D\":91:181 contract D is C(3)... */ sub slt tag_26 @@ -595,30 +595,30 @@ sub_0: assembly { swap2 mload swap2 - /* \"C\":392:411 stateVar + this.f() */ + /* \"C\":464:483 stateVar + this.f() */ tag_20 - /* \"C\":403:411 this.f() */ + /* \"C\":475:483 this.f() */ jump(tag_19) - /* \"D\":91:166 contract D is C(3)... */ + /* \"D\":91:181 contract D is C(3)... */ tag_26: 0x00 dup1 revert tag_24: - /* \"C\":117:119 41 */ + /* \"C\":120:122 41 */ shl(0xe0, 0x4e487b71) - /* \"D\":91:166 contract D is C(3)... */ + /* \"D\":91:181 contract D is C(3)... */ 0x00 mstore mstore(0x04, 0x41) revert(0x00, 0x24) - /* \"C\":403:411 this.f() */ + /* \"C\":475:483 this.f() */ tag_22: pop returndatasize jump(tag_23) tag_16: - /* \"D\":91:166 contract D is C(3)... */ + /* \"D\":91:181 contract D is C(3)... */ dup3 mload returndatasize @@ -629,23 +629,23 @@ sub_0: assembly { swap1 revert tag_14: - /* \"C\":117:119 41 */ + /* \"C\":120:122 41 */ shl(0xe0, 0x4e487b71) - /* \"D\":91:166 contract D is C(3)... */ + /* \"D\":91:181 contract D is C(3)... */ 0x00 - /* \"C\":117:119 41 */ + /* \"C\":120:122 41 */ mstore 0x11 - /* \"D\":91:166 contract D is C(3)... */ + /* \"D\":91:181 contract D is C(3)... */ 0x04 - /* \"C\":117:119 41 */ + /* \"C\":120:122 41 */ mstore 0x24 - /* \"D\":91:166 contract D is C(3)... */ + /* \"D\":91:181 contract D is C(3)... */ 0x00 - /* \"C\":117:119 41 */ + /* \"C\":120:122 41 */ revert - /* \"D\":91:166 contract D is C(3)... */ + /* \"D\":91:181 contract D is C(3)... */ tag_6: pop jumpi(tag_26, callvalue) @@ -662,9 +662,9 @@ sub_0: assembly { tag_4: jumpi(tag_26, callvalue) jumpi(tag_26, slt(add(not(0x03), calldatasize), 0x00)) - /* \"C\":290:298 immutVar */ + /* \"C\":326:334 immutVar */ immutable(\"0xe4b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c10\") - /* \"C\":117:119 41 */ + /* \"C\":120:122 41 */ swap1 dup2 0x29 @@ -676,13 +676,13 @@ sub_0: assembly { and tag_14 jumpi - /* \"D\":91:166 contract D is C(3)... */ + /* \"D\":91:181 contract D is C(3)... */ 0x20 swap2 dup2 mstore return - /* \"C\":117:119 41 */ + /* \"C\":120:122 41 */ tag_1: swap2 swap1 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 2671162722e0..54748658fd6a 100644 --- a/test/cmdlineTests/standard_debug_info_in_yul_location/output.json +++ b/test/cmdlineTests/standard_debug_info_in_yul_location/output.json @@ -9,7 +9,7 @@ /// @use-src 0:\"C\" object \"C_54\" { code { - /// @src 0:79:435 \"contract C...\" + /// @src 0:79:510 \"contract C...\" mstore(64, memoryguard(160)) if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } @@ -136,31 +136,31 @@ object \"C_54\" { } /// @ast-id 20 - /// @src 0:182:230 \"constructor(int _init)...\" + /// @src 0:194:254 \"constructor(int _init)...\" function constructor_C_54(var__init_12) { - /// @src 0:182:230 \"constructor(int _init)...\" + /// @src 0:194:254 \"constructor(int _init)...\" - /// @src 0:154:156 \"42\" + /// @src 0:160:162 \"42\" let expr_7 := 0x2a let _3 := convert_t_rational_42_by_1_to_t_int256(expr_7) mstore(128, _3) - /// @src 0:221:226 \"_init\" + /// @src 0:242:247 \"_init\" let _4 := var__init_12 let expr_16 := _4 - /// @src 0:210:226 \"stateVar = _init\" + /// @src 0:231:247 \"stateVar = _init\" update_storage_value_offset_0t_int256_to_t_int256(0x00, expr_16) let expr_17 := expr_16 } - /// @src 0:79:435 \"contract C...\" + /// @src 0:79:510 \"contract C...\" } /// @use-src 0:\"C\" object \"C_54_deployed\" { code { - /// @src 0:79:435 \"contract C...\" + /// @src 0:79:510 \"contract C...\" mstore(64, memoryguard(128)) if iszero(lt(calldatasize(), 4)) @@ -272,7 +272,7 @@ object \"C_54\" { } /// @ast-id 10 - /// @src 0:159:178 \"int public stateVar\" + /// @src 0:168:187 \"int public stateVar\" function getter_fun_stateVar_10() -> ret { let slot := 0 @@ -281,7 +281,7 @@ object \"C_54\" { ret := read_from_storage_split_dynamic_t_int256(slot, offset) } - /// @src 0:79:435 \"contract C...\" + /// @src 0:79:510 \"contract C...\" function external_fun_stateVar_10() { @@ -317,9 +317,9 @@ object \"C_54\" { converted := cleanup_t_int256(identity(cleanup_t_rational_41_by_1(value))) } - /// @src 0:93:126 \"int public constant constVar = 41\" + /// @src 0:96:129 \"int public constant constVar = 41\" function constant_constVar_5() -> ret { - /// @src 0:124:126 \"41\" + /// @src 0:127:129 \"41\" let expr_4 := 0x29 let _1 := convert_t_rational_41_by_1_to_t_int256(expr_4) @@ -327,11 +327,11 @@ object \"C_54\" { } /// @ast-id 5 - /// @src 0:93:126 \"int public constant constVar = 41\" + /// @src 0:96:129 \"int public constant constVar = 41\" function getter_fun_constVar_5() -> ret_0 { ret_0 := constant_constVar_5() } - /// @src 0:79:435 \"contract C...\" + /// @src 0:79:510 \"contract C...\" function external_fun_constVar_5() { @@ -373,26 +373,26 @@ object \"C_54\" { } /// @ast-id 30 - /// @src 0:233:309 \"function f() external pure returns (int)...\" + /// @src 0:260:348 \"function f() external pure returns (int)...\" function fun_f_30() -> var__23 { - /// @src 0:269:272 \"int\" + /// @src 0:296:299 \"int\" let zero_t_int256_2 := zero_value_for_split_t_int256() var__23 := zero_t_int256_2 - /// @src 0:286:294 \"constVar\" + /// @src 0:322:330 \"constVar\" let expr_25 := constant_constVar_5() - /// @src 0:297:305 \"immutVar\" + /// @src 0:333:341 \"immutVar\" let _3 := loadimmutable(\"8\") let expr_26 := _3 - /// @src 0:286:305 \"constVar + immutVar\" + /// @src 0:322:341 \"constVar + immutVar\" let expr_27 := checked_add_t_int256(expr_25, expr_26) - /// @src 0:279:305 \"return constVar + immutVar\" + /// @src 0:315:341 \"return constVar + immutVar\" var__23 := expr_27 leave } - /// @src 0:79:435 \"contract C...\" + /// @src 0:79:510 \"contract C...\" function shift_right_0_unsigned(value) -> newValue { newValue := @@ -444,20 +444,20 @@ object \"C_54\" { } /// @ast-id 37 - /// @src 0:311:348 \"modifier m()...\" + /// @src 0:353:408 \"modifier m()...\" function modifier_m_40(var__42) -> _5 { _5 := var__42 - /// @src 0:329:339 \"stateVar++\" + /// @src 0:380:390 \"stateVar++\" let _7 := read_from_storage_split_offset_0_t_int256(0x00) let _6 := increment_t_int256(_7) update_storage_value_offset_0t_int256_to_t_int256(0x00, _6) let expr_33 := _7 - /// @src 0:343:344 \"_\" + /// @src 0:400:401 \"_\" _5 := fun_f2_53_inner(var__42) } - /// @src 0:79:435 \"contract C...\" + /// @src 0:79:510 \"contract C...\" function cleanup_t_uint160(value) -> cleaned { cleaned := and(value, 0xffffffffffffffffffffffffffffffffffffffff) @@ -539,19 +539,19 @@ object \"C_54\" { revert(pos, returndatasize()) } - /// @src 0:350:433 \"function f2() m public returns (int)...\" + /// @src 0:413:508 \"function f2() m public returns (int)...\" function fun_f2_53_inner(_8) -> var__42 { var__42 := _8 - /// @src 0:399:407 \"stateVar\" + /// @src 0:471:479 \"stateVar\" let _9 := read_from_storage_split_offset_0_t_int256(0x00) let expr_44 := _9 - /// @src 0:410:414 \"this\" + /// @src 0:482:486 \"this\" let expr_45_address := address() - /// @src 0:410:416 \"this.f\" + /// @src 0:482:488 \"this.f\" 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()\" + /// @src 0:482:490 \"this.f()\" // storage for arguments and returned data let _10 := allocate_unbounded() @@ -577,32 +577,32 @@ object \"C_54\" { // decode return parameters from external try-call into retVars expr_47 := abi_decode_tuple_t_int256_fromMemory(_10, add(_10, _13)) } - /// @src 0:399:418 \"stateVar + this.f()\" + /// @src 0:471:490 \"stateVar + this.f()\" let expr_48 := checked_add_t_int256(expr_44, expr_47) - /// @src 0:421:429 \"immutVar\" + /// @src 0:493:501 \"immutVar\" let _14 := loadimmutable(\"8\") let expr_49 := _14 - /// @src 0:399:429 \"stateVar + this.f() + immutVar\" + /// @src 0:471:501 \"stateVar + this.f() + immutVar\" let expr_50 := checked_add_t_int256(expr_48, expr_49) - /// @src 0:392:429 \"return stateVar + this.f() + immutVar\" + /// @src 0:464:501 \"return stateVar + this.f() + immutVar\" var__42 := expr_50 leave } - /// @src 0:79:435 \"contract C...\" + /// @src 0:79:510 \"contract C...\" /// @ast-id 53 - /// @src 0:350:433 \"function f2() m public returns (int)...\" + /// @src 0:413:508 \"function f2() m public returns (int)...\" function fun_f2_53() -> var__42 { - /// @src 0:382:385 \"int\" + /// @src 0:445:448 \"int\" let zero_t_int256_4 := zero_value_for_split_t_int256() var__42 := zero_t_int256_4 var__42 := modifier_m_40(var__42) } - /// @src 0:79:435 \"contract C...\" + /// @src 0:79:510 \"contract C...\" } @@ -616,7 +616,7 @@ object \"C_54\" { object \"C_54\" { code { { - /// @src 0:79:435 \"contract C...\" + /// @src 0:79:510 \"contract C...\" let _1 := memoryguard(0xa0) if callvalue() { revert(0, 0) } let programSize := datasize(\"C_54\") @@ -624,9 +624,9 @@ object \"C_54\" { 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(/** @src -1:-1:-1 */ 0, /** @src 0:79:510 \"contract C...\" */ shl(224, 0x4e487b71)) mstore(4, 0x41) - revert(/** @src -1:-1:-1 */ 0, /** @src 0:79:435 \"contract C...\" */ 0x24) + revert(/** @src -1:-1:-1 */ 0, /** @src 0:79:510 \"contract C...\" */ 0x24) } mstore(64, newFreePtr) codecopy(_1, programSize, argSize) @@ -634,17 +634,17 @@ object \"C_54\" { { revert(/** @src -1:-1:-1 */ 0, 0) } - /// @src 0:79:435 \"contract C...\" + /// @src 0:79:510 \"contract C...\" let value := mload(_1) - /// @src 0:154:156 \"42\" + /// @src 0:160:162 \"42\" mstore(128, 0x2a) - /// @src 0:79:435 \"contract C...\" - sstore(/** @src -1:-1:-1 */ 0, /** @src 0:79:435 \"contract C...\" */ value) + /// @src 0:79:510 \"contract C...\" + sstore(/** @src -1:-1:-1 */ 0, /** @src 0:79:510 \"contract C...\" */ value) let _2 := mload(64) let _3 := datasize(\"C_54_deployed\") codecopy(_2, dataoffset(\"C_54_deployed\"), _3) - setimmutable(_2, \"8\", mload(/** @src 0:154:156 \"42\" */ 128)) - /// @src 0:79:435 \"contract C...\" + setimmutable(_2, \"8\", mload(/** @src 0:160:162 \"42\" */ 128)) + /// @src 0:79:510 \"contract C...\" return(_2, _3) } } @@ -652,7 +652,7 @@ object \"C_54\" { object \"C_54_deployed\" { code { { - /// @src 0:79:435 \"contract C...\" + /// @src 0:79:510 \"contract C...\" let _1 := memoryguard(0x80) let _2 := 64 mstore(_2, _1) @@ -662,10 +662,10 @@ object \"C_54\" { case 0x26121ff0 { if callvalue() { revert(0, 0) } if slt(add(calldatasize(), not(3)), 0) { revert(0, 0) } - /// @src 0:297:305 \"immutVar\" + /// @src 0:333:341 \"immutVar\" let _3 := loadimmutable(\"8\") - /// @src 0:79:435 \"contract C...\" - let sum := add(/** @src 0:124:126 \"41\" */ 0x29, /** @src 0:79:435 \"contract C...\" */ _3) + /// @src 0:79:510 \"contract C...\" + let sum := add(/** @src 0:127:129 \"41\" */ 0x29, /** @src 0:79:510 \"contract C...\" */ _3) if and(1, slt(sum, _3)) { mstore(0, shl(224, 0x4e487b71)) @@ -695,27 +695,27 @@ object \"C_54\" { } let ret := add(_5, 1) sstore(0, ret) - /// @src 0:410:418 \"this.f()\" - let _6 := /** @src 0:79:435 \"contract C...\" */ mload(_2) - /// @src 0:410:418 \"this.f()\" - mstore(_6, /** @src 0:79:435 \"contract C...\" */ shl(228, 0x026121ff)) - /// @src 0:410:418 \"this.f()\" - let _7 := staticcall(gas(), /** @src 0:410:414 \"this\" */ address(), /** @src 0:410:418 \"this.f()\" */ _6, /** @src 0:79:435 \"contract C...\" */ 4, /** @src 0:410:418 \"this.f()\" */ _6, 32) + /// @src 0:482:490 \"this.f()\" + let _6 := /** @src 0:79:510 \"contract C...\" */ mload(_2) + /// @src 0:482:490 \"this.f()\" + mstore(_6, /** @src 0:79:510 \"contract C...\" */ shl(228, 0x026121ff)) + /// @src 0:482:490 \"this.f()\" + let _7 := staticcall(gas(), /** @src 0:482:486 \"this\" */ address(), /** @src 0:482:490 \"this.f()\" */ _6, /** @src 0:79:510 \"contract C...\" */ 4, /** @src 0:482:490 \"this.f()\" */ _6, 32) if iszero(_7) { - /// @src 0:79:435 \"contract C...\" + /// @src 0:79:510 \"contract C...\" let pos := mload(_2) returndatacopy(pos, 0, returndatasize()) revert(pos, returndatasize()) } - /// @src 0:410:418 \"this.f()\" - let expr := /** @src 0:79:435 \"contract C...\" */ 0 - /// @src 0:410:418 \"this.f()\" + /// @src 0:482:490 \"this.f()\" + let expr := /** @src 0:79:510 \"contract C...\" */ 0 + /// @src 0:482:490 \"this.f()\" if _7 { let _8 := 32 if gt(32, returndatasize()) { _8 := returndatasize() } - /// @src 0:79:435 \"contract C...\" + /// @src 0:79:510 \"contract C...\" let newFreePtr := add(_6, and(add(_8, 31), not(31))) if or(gt(newFreePtr, 0xffffffffffffffff), lt(newFreePtr, _6)) { @@ -724,27 +724,27 @@ object \"C_54\" { revert(0, 0x24) } mstore(_2, newFreePtr) - if slt(sub(/** @src 0:410:418 \"this.f()\" */ add(_6, _8), /** @src 0:79:435 \"contract C...\" */ _6), /** @src 0:410:418 \"this.f()\" */ 32) - /// @src 0:79:435 \"contract C...\" + if slt(sub(/** @src 0:482:490 \"this.f()\" */ add(_6, _8), /** @src 0:79:510 \"contract C...\" */ _6), /** @src 0:482:490 \"this.f()\" */ 32) + /// @src 0:79:510 \"contract C...\" { revert(0, 0) } - /// @src 0:410:418 \"this.f()\" - expr := /** @src 0:79:435 \"contract C...\" */ mload(_6) + /// @src 0:482:490 \"this.f()\" + expr := /** @src 0:79:510 \"contract C...\" */ mload(_6) } - /// @src 0:399:418 \"stateVar + this.f()\" + /// @src 0:471:490 \"stateVar + this.f()\" let expr_1 := checked_add_int256(ret, expr) - /// @src 0:392:429 \"return stateVar + this.f() + immutVar\" - let var := /** @src 0:399:429 \"stateVar + this.f() + immutVar\" */ checked_add_int256(expr_1, /** @src 0:421:429 \"immutVar\" */ loadimmutable(\"8\")) - /// @src 0:79:435 \"contract C...\" + /// @src 0:464:501 \"return stateVar + this.f() + immutVar\" + let var := /** @src 0:471:501 \"stateVar + this.f() + immutVar\" */ checked_add_int256(expr_1, /** @src 0:493:501 \"immutVar\" */ loadimmutable(\"8\")) + /// @src 0:79:510 \"contract C...\" let memPos_1 := mload(_2) mstore(memPos_1, var) - return(memPos_1, /** @src 0:410:418 \"this.f()\" */ 32) + return(memPos_1, /** @src 0:482:490 \"this.f()\" */ 32) } - case /** @src 0:79:435 \"contract C...\" */ 0xa00b982b { + case /** @src 0:79:510 \"contract C...\" */ 0xa00b982b { if callvalue() { revert(0, 0) } if slt(add(calldatasize(), not(3)), 0) { revert(0, 0) } let memPos_2 := mload(_2) - mstore(memPos_2, /** @src 0:124:126 \"41\" */ 0x29) - /// @src 0:79:435 \"contract C...\" + mstore(memPos_2, /** @src 0:127:129 \"41\" */ 0x29) + /// @src 0:79:510 \"contract C...\" return(memPos_2, 32) } } @@ -777,7 +777,7 @@ object \"C_54\" { /// @use-src 0:\"C\", 1:\"D\" object \"D_72\" { code { - /// @src 1:91:166 \"contract D is C(3)...\" + /// @src 1:91:181 \"contract D is C(3)...\" mstore(64, memoryguard(160)) if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } @@ -944,26 +944,26 @@ object \"D_72\" { } /// @ast-id 71 - /// @src 1:113:164 \"constructor(int _init2)...\" + /// @src 1:116:179 \"constructor(int _init2)...\" function constructor_D_72(var__init2_63) { /// @src 1:107:108 \"3\" let expr_60 := 0x03 let _3 := convert_t_rational_3_by_1_to_t_int256(expr_60) - /// @src 1:113:164 \"constructor(int _init2)...\" + /// @src 1:116:179 \"constructor(int _init2)...\" constructor_C_54(_3) - /// @src 1:154:160 \"_init2\" + /// @src 1:166:172 \"_init2\" let _4 := var__init2_63 let expr_67 := _4 - /// @src 1:142:160 \"stateVar += _init2\" + /// @src 1:154:172 \"stateVar += _init2\" let _5 := read_from_storage_split_offset_0_t_int256(0x00) let expr_68 := checked_add_t_int256(_5, expr_67) update_storage_value_offset_0t_int256_to_t_int256(0x00, expr_68) } - /// @src 1:91:166 \"contract D is C(3)...\" + /// @src 1:91:181 \"contract D is C(3)...\" function cleanup_t_rational_42_by_1(value) -> cleaned { cleaned := value @@ -974,31 +974,31 @@ object \"D_72\" { } /// @ast-id 20 - /// @src 0:182:230 \"constructor(int _init)...\" + /// @src 0:194:254 \"constructor(int _init)...\" function constructor_C_54(var__init_12) { - /// @src 0:182:230 \"constructor(int _init)...\" + /// @src 0:194:254 \"constructor(int _init)...\" - /// @src 0:154:156 \"42\" + /// @src 0:160:162 \"42\" let expr_7 := 0x2a let _6 := convert_t_rational_42_by_1_to_t_int256(expr_7) mstore(128, _6) - /// @src 0:221:226 \"_init\" + /// @src 0:242:247 \"_init\" let _7 := var__init_12 let expr_16 := _7 - /// @src 0:210:226 \"stateVar = _init\" + /// @src 0:231:247 \"stateVar = _init\" update_storage_value_offset_0t_int256_to_t_int256(0x00, expr_16) let expr_17 := expr_16 } - /// @src 1:91:166 \"contract D is C(3)...\" + /// @src 1:91:181 \"contract D is C(3)...\" } /// @use-src 0:\"C\", 1:\"D\" object \"D_72_deployed\" { code { - /// @src 1:91:166 \"contract D is C(3)...\" + /// @src 1:91:181 \"contract D is C(3)...\" mstore(64, memoryguard(128)) if iszero(lt(calldatasize(), 4)) @@ -1110,7 +1110,7 @@ object \"D_72\" { } /// @ast-id 10 - /// @src 0:159:178 \"int public stateVar\" + /// @src 0:168:187 \"int public stateVar\" function getter_fun_stateVar_10() -> ret { let slot := 0 @@ -1119,7 +1119,7 @@ object \"D_72\" { ret := read_from_storage_split_dynamic_t_int256(slot, offset) } - /// @src 1:91:166 \"contract D is C(3)...\" + /// @src 1:91:181 \"contract D is C(3)...\" function external_fun_stateVar_10() { @@ -1155,9 +1155,9 @@ object \"D_72\" { converted := cleanup_t_int256(identity(cleanup_t_rational_41_by_1(value))) } - /// @src 0:93:126 \"int public constant constVar = 41\" + /// @src 0:96:129 \"int public constant constVar = 41\" function constant_constVar_5() -> ret { - /// @src 0:124:126 \"41\" + /// @src 0:127:129 \"41\" let expr_4 := 0x29 let _1 := convert_t_rational_41_by_1_to_t_int256(expr_4) @@ -1165,11 +1165,11 @@ object \"D_72\" { } /// @ast-id 5 - /// @src 0:93:126 \"int public constant constVar = 41\" + /// @src 0:96:129 \"int public constant constVar = 41\" function getter_fun_constVar_5() -> ret_0 { ret_0 := constant_constVar_5() } - /// @src 1:91:166 \"contract D is C(3)...\" + /// @src 1:91:181 \"contract D is C(3)...\" function external_fun_constVar_5() { @@ -1211,26 +1211,26 @@ object \"D_72\" { } /// @ast-id 30 - /// @src 0:233:309 \"function f() external pure returns (int)...\" + /// @src 0:260:348 \"function f() external pure returns (int)...\" function fun_f_30() -> var__23 { - /// @src 0:269:272 \"int\" + /// @src 0:296:299 \"int\" let zero_t_int256_2 := zero_value_for_split_t_int256() var__23 := zero_t_int256_2 - /// @src 0:286:294 \"constVar\" + /// @src 0:322:330 \"constVar\" let expr_25 := constant_constVar_5() - /// @src 0:297:305 \"immutVar\" + /// @src 0:333:341 \"immutVar\" let _3 := loadimmutable(\"8\") let expr_26 := _3 - /// @src 0:286:305 \"constVar + immutVar\" + /// @src 0:322:341 \"constVar + immutVar\" let expr_27 := checked_add_t_int256(expr_25, expr_26) - /// @src 0:279:305 \"return constVar + immutVar\" + /// @src 0:315:341 \"return constVar + immutVar\" var__23 := expr_27 leave } - /// @src 1:91:166 \"contract D is C(3)...\" + /// @src 1:91:181 \"contract D is C(3)...\" function shift_right_0_unsigned(value) -> newValue { newValue := @@ -1282,20 +1282,20 @@ object \"D_72\" { } /// @ast-id 37 - /// @src 0:311:348 \"modifier m()...\" + /// @src 0:353:408 \"modifier m()...\" function modifier_m_40(var__42) -> _5 { _5 := var__42 - /// @src 0:329:339 \"stateVar++\" + /// @src 0:380:390 \"stateVar++\" let _7 := read_from_storage_split_offset_0_t_int256(0x00) let _6 := increment_t_int256(_7) update_storage_value_offset_0t_int256_to_t_int256(0x00, _6) let expr_33 := _7 - /// @src 0:343:344 \"_\" + /// @src 0:400:401 \"_\" _5 := fun_f2_53_inner(var__42) } - /// @src 1:91:166 \"contract D is C(3)...\" + /// @src 1:91:181 \"contract D is C(3)...\" function cleanup_t_uint160(value) -> cleaned { cleaned := and(value, 0xffffffffffffffffffffffffffffffffffffffff) @@ -1377,19 +1377,19 @@ object \"D_72\" { revert(pos, returndatasize()) } - /// @src 0:350:433 \"function f2() m public returns (int)...\" + /// @src 0:413:508 \"function f2() m public returns (int)...\" function fun_f2_53_inner(_8) -> var__42 { var__42 := _8 - /// @src 0:399:407 \"stateVar\" + /// @src 0:471:479 \"stateVar\" let _9 := read_from_storage_split_offset_0_t_int256(0x00) let expr_44 := _9 - /// @src 0:410:414 \"this\" + /// @src 0:482:486 \"this\" let expr_45_address := address() - /// @src 0:410:416 \"this.f\" + /// @src 0:482:488 \"this.f\" 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()\" + /// @src 0:482:490 \"this.f()\" // storage for arguments and returned data let _10 := allocate_unbounded() @@ -1415,32 +1415,32 @@ object \"D_72\" { // decode return parameters from external try-call into retVars expr_47 := abi_decode_tuple_t_int256_fromMemory(_10, add(_10, _13)) } - /// @src 0:399:418 \"stateVar + this.f()\" + /// @src 0:471:490 \"stateVar + this.f()\" let expr_48 := checked_add_t_int256(expr_44, expr_47) - /// @src 0:421:429 \"immutVar\" + /// @src 0:493:501 \"immutVar\" let _14 := loadimmutable(\"8\") let expr_49 := _14 - /// @src 0:399:429 \"stateVar + this.f() + immutVar\" + /// @src 0:471:501 \"stateVar + this.f() + immutVar\" let expr_50 := checked_add_t_int256(expr_48, expr_49) - /// @src 0:392:429 \"return stateVar + this.f() + immutVar\" + /// @src 0:464:501 \"return stateVar + this.f() + immutVar\" var__42 := expr_50 leave } - /// @src 1:91:166 \"contract D is C(3)...\" + /// @src 1:91:181 \"contract D is C(3)...\" /// @ast-id 53 - /// @src 0:350:433 \"function f2() m public returns (int)...\" + /// @src 0:413:508 \"function f2() m public returns (int)...\" function fun_f2_53() -> var__42 { - /// @src 0:382:385 \"int\" + /// @src 0:445:448 \"int\" let zero_t_int256_4 := zero_value_for_split_t_int256() var__42 := zero_t_int256_4 var__42 := modifier_m_40(var__42) } - /// @src 1:91:166 \"contract D is C(3)...\" + /// @src 1:91:181 \"contract D is C(3)...\" } @@ -1454,7 +1454,7 @@ object \"D_72\" { object \"D_72\" { code { { - /// @src 1:91:166 \"contract D is C(3)...\" + /// @src 1:91:181 \"contract D is C(3)...\" let _1 := memoryguard(0xa0) if callvalue() { revert(0, 0) } let programSize := datasize(\"D_72\") @@ -1462,9 +1462,9 @@ object \"D_72\" { 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(/** @src -1:-1:-1 */ 0, /** @src 1:91:181 \"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) + revert(/** @src -1:-1:-1 */ 0, /** @src 1:91:181 \"contract D is C(3)...\" */ 0x24) } mstore(64, newFreePtr) codecopy(_1, programSize, argSize) @@ -1472,24 +1472,24 @@ object \"D_72\" { { revert(/** @src -1:-1:-1 */ 0, 0) } - /// @src 1:91:166 \"contract D is C(3)...\" + /// @src 1:91:181 \"contract D is C(3)...\" let value := mload(_1) - /// @src 0:154:156 \"42\" + /// @src 0:160:162 \"42\" mstore(128, 0x2a) - /// @src 1:91:166 \"contract D is C(3)...\" - let sum := add(/** @src 1:107:108 \"3\" */ 0x03, /** @src 1:91:166 \"contract D is C(3)...\" */ value) + /// @src 1:91:181 \"contract D is C(3)...\" + let sum := add(/** @src 1:107:108 \"3\" */ 0x03, /** @src 1:91:181 \"contract D is C(3)...\" */ value) if and(1, slt(sum, value)) { - mstore(/** @src -1:-1:-1 */ 0, /** @src 1:91:166 \"contract D is C(3)...\" */ shl(224, 0x4e487b71)) + mstore(/** @src -1:-1:-1 */ 0, /** @src 1:91:181 \"contract D is C(3)...\" */ shl(224, 0x4e487b71)) mstore(4, 0x11) - revert(/** @src -1:-1:-1 */ 0, /** @src 1:91:166 \"contract D is C(3)...\" */ 0x24) + revert(/** @src -1:-1:-1 */ 0, /** @src 1:91:181 \"contract D is C(3)...\" */ 0x24) } - sstore(/** @src -1:-1:-1 */ 0, /** @src 1:91:166 \"contract D is C(3)...\" */ sum) + sstore(/** @src -1:-1:-1 */ 0, /** @src 1:91:181 \"contract D is C(3)...\" */ sum) let _2 := mload(64) let _3 := datasize(\"D_72_deployed\") codecopy(_2, dataoffset(\"D_72_deployed\"), _3) - setimmutable(_2, \"8\", mload(/** @src 0:154:156 \"42\" */ 128)) - /// @src 1:91:166 \"contract D is C(3)...\" + setimmutable(_2, \"8\", mload(/** @src 0:160:162 \"42\" */ 128)) + /// @src 1:91:181 \"contract D is C(3)...\" return(_2, _3) } } @@ -1497,7 +1497,7 @@ object \"D_72\" { object \"D_72_deployed\" { code { { - /// @src 1:91:166 \"contract D is C(3)...\" + /// @src 1:91:181 \"contract D is C(3)...\" let _1 := memoryguard(0x80) let _2 := 64 mstore(_2, _1) @@ -1507,10 +1507,10 @@ object \"D_72\" { case 0x26121ff0 { if callvalue() { revert(0, 0) } if slt(add(calldatasize(), not(3)), 0) { revert(0, 0) } - /// @src 0:297:305 \"immutVar\" + /// @src 0:333:341 \"immutVar\" let _3 := loadimmutable(\"8\") - /// @src 1:91:166 \"contract D is C(3)...\" - let sum := add(/** @src 0:124:126 \"41\" */ 0x29, /** @src 1:91:166 \"contract D is C(3)...\" */ _3) + /// @src 1:91:181 \"contract D is C(3)...\" + let sum := add(/** @src 0:127:129 \"41\" */ 0x29, /** @src 1:91:181 \"contract D is C(3)...\" */ _3) if and(1, slt(sum, _3)) { mstore(0, shl(224, 0x4e487b71)) @@ -1540,27 +1540,27 @@ object \"D_72\" { } let ret := add(_5, 1) sstore(0, ret) - /// @src 0:410:418 \"this.f()\" - let _6 := /** @src 1:91:166 \"contract D is C(3)...\" */ mload(_2) - /// @src 0:410:418 \"this.f()\" - mstore(_6, /** @src 1:91:166 \"contract D is C(3)...\" */ shl(228, 0x026121ff)) - /// @src 0:410:418 \"this.f()\" - let _7 := staticcall(gas(), /** @src 0:410:414 \"this\" */ address(), /** @src 0:410:418 \"this.f()\" */ _6, /** @src 1:91:166 \"contract D is C(3)...\" */ 4, /** @src 0:410:418 \"this.f()\" */ _6, 32) + /// @src 0:482:490 \"this.f()\" + let _6 := /** @src 1:91:181 \"contract D is C(3)...\" */ mload(_2) + /// @src 0:482:490 \"this.f()\" + mstore(_6, /** @src 1:91:181 \"contract D is C(3)...\" */ shl(228, 0x026121ff)) + /// @src 0:482:490 \"this.f()\" + let _7 := staticcall(gas(), /** @src 0:482:486 \"this\" */ address(), /** @src 0:482:490 \"this.f()\" */ _6, /** @src 1:91:181 \"contract D is C(3)...\" */ 4, /** @src 0:482:490 \"this.f()\" */ _6, 32) if iszero(_7) { - /// @src 1:91:166 \"contract D is C(3)...\" + /// @src 1:91:181 \"contract D is C(3)...\" let pos := mload(_2) returndatacopy(pos, 0, returndatasize()) revert(pos, returndatasize()) } - /// @src 0:410:418 \"this.f()\" - let expr := /** @src 1:91:166 \"contract D is C(3)...\" */ 0 - /// @src 0:410:418 \"this.f()\" + /// @src 0:482:490 \"this.f()\" + let expr := /** @src 1:91:181 \"contract D is C(3)...\" */ 0 + /// @src 0:482:490 \"this.f()\" if _7 { let _8 := 32 if gt(32, returndatasize()) { _8 := returndatasize() } - /// @src 1:91:166 \"contract D is C(3)...\" + /// @src 1:91:181 \"contract D is C(3)...\" let newFreePtr := add(_6, and(add(_8, 31), not(31))) if or(gt(newFreePtr, 0xffffffffffffffff), lt(newFreePtr, _6)) { @@ -1569,27 +1569,27 @@ object \"D_72\" { revert(0, 0x24) } mstore(_2, newFreePtr) - if slt(sub(/** @src 0:410:418 \"this.f()\" */ add(_6, _8), /** @src 1:91:166 \"contract D is C(3)...\" */ _6), /** @src 0:410:418 \"this.f()\" */ 32) - /// @src 1:91:166 \"contract D is C(3)...\" + if slt(sub(/** @src 0:482:490 \"this.f()\" */ add(_6, _8), /** @src 1:91:181 \"contract D is C(3)...\" */ _6), /** @src 0:482:490 \"this.f()\" */ 32) + /// @src 1:91:181 \"contract D is C(3)...\" { revert(0, 0) } - /// @src 0:410:418 \"this.f()\" - expr := /** @src 1:91:166 \"contract D is C(3)...\" */ mload(_6) + /// @src 0:482:490 \"this.f()\" + expr := /** @src 1:91:181 \"contract D is C(3)...\" */ mload(_6) } - /// @src 0:399:418 \"stateVar + this.f()\" + /// @src 0:471:490 \"stateVar + this.f()\" let expr_1 := checked_add_int256(ret, expr) - /// @src 0:392:429 \"return stateVar + this.f() + immutVar\" - let var := /** @src 0:399:429 \"stateVar + this.f() + immutVar\" */ checked_add_int256(expr_1, /** @src 0:421:429 \"immutVar\" */ loadimmutable(\"8\")) - /// @src 1:91:166 \"contract D is C(3)...\" + /// @src 0:464:501 \"return stateVar + this.f() + immutVar\" + let var := /** @src 0:471:501 \"stateVar + this.f() + immutVar\" */ checked_add_int256(expr_1, /** @src 0:493:501 \"immutVar\" */ loadimmutable(\"8\")) + /// @src 1:91:181 \"contract D is C(3)...\" let memPos_1 := mload(_2) mstore(memPos_1, var) - return(memPos_1, /** @src 0:410:418 \"this.f()\" */ 32) + return(memPos_1, /** @src 0:482:490 \"this.f()\" */ 32) } - case /** @src 1:91:166 \"contract D is C(3)...\" */ 0xa00b982b { + case /** @src 1:91:181 \"contract D is C(3)...\" */ 0xa00b982b { if callvalue() { revert(0, 0) } if slt(add(calldatasize(), not(3)), 0) { revert(0, 0) } let memPos_2 := mload(_2) - mstore(memPos_2, /** @src 0:124:126 \"41\" */ 0x29) - /// @src 1:91:166 \"contract D is C(3)...\" + mstore(memPos_2, /** @src 0:127:129 \"41\" */ 0x29) + /// @src 1:91:181 \"contract D is C(3)...\" return(memPos_2, 32) } } diff --git a/test/libsolidity/smtCheckerTests/loops/for_loop_bmc_iterations_break_8.sol b/test/libsolidity/smtCheckerTests/loops/for_loop_bmc_iterations_break_8.sol index de3237838929..1778e22d5aff 100644 --- a/test/libsolidity/smtCheckerTests/loops/for_loop_bmc_iterations_break_8.sol +++ b/test/libsolidity/smtCheckerTests/loops/for_loop_bmc_iterations_break_8.sol @@ -14,5 +14,5 @@ contract C // SMTSolvers: z3 // BMCLoopIterations: 4 // ---- -// Warning 5740: (78-81): Unreachable code. +// Warning 5740: (77-80): Unreachable code. // Info 6002: BMC: 2 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/loops/while_bmc_iterations_semantics_2.sol b/test/libsolidity/smtCheckerTests/loops/while_bmc_iterations_semantics_2.sol index 5b22ca942628..157cc61b6569 100644 --- a/test/libsolidity/smtCheckerTests/loops/while_bmc_iterations_semantics_2.sol +++ b/test/libsolidity/smtCheckerTests/loops/while_bmc_iterations_semantics_2.sol @@ -18,5 +18,5 @@ contract C { // SMTSolvers: z3 // BMCLoopIterations: 3 // ---- -// Warning 4661: (220-234): BMC: Assertion violation happens here. +// Warning 4661: (219-233): BMC: Assertion violation happens here. // Info 6002: BMC: 3 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. From 019d45e039b613dddd8edf7771809bcb88c3f838 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Fri, 12 Apr 2024 16:40:54 +0200 Subject: [PATCH 0154/1022] External tests: Include timing information in the JSON report --- scripts/common.sh | 22 ++++++++++++++++++++++ scripts/externalTests/common.sh | 14 +++++++++++--- 2 files changed, 33 insertions(+), 3 deletions(-) diff --git a/scripts/common.sh b/scripts/common.sh index d149253bf71f..81dd2ec491a8 100644 --- a/scripts/common.sh +++ b/scripts/common.sh @@ -324,3 +324,25 @@ function gnu_grep grep "$@" fi } + +function time_to_json_file +{ + local output_file="$1" + local cmd=("${@:2}") + (( $# >= 2 )) || assertFail + + # $TIMEFORMAT is the format used by built-in `time`. Description is in `man bash`. + local original_timeformat="$TIMEFORMAT" + TIMEFORMAT='{"real": %R, "user": %U, "sys": %S}' + + # We temporarily use descriptors 3 and 4 to preserve stdout and stderr of the original command. + # This allows us to store `time`'s own stderr in a file. Then we restore initial descriptors. + { + { + time { "${cmd[@]}" 1>&3 2>&4; } + } 2> "$output_file" + } 3>&1 4>&2 + + # Restore original format so that it does not spill outside of the function. + TIMEFORMAT="$original_timeformat" +} diff --git a/scripts/externalTests/common.sh b/scripts/externalTests/common.sh index 8bc9bdf7bd40..2983b30c296a 100644 --- a/scripts/externalTests/common.sh +++ b/scripts/externalTests/common.sh @@ -505,14 +505,14 @@ function compile_and_run_test [[ $preset != *" "* ]] || assertFail "Preset names must not contain spaces." printLog "Running compile function..." - time $compile_fn - $verify_fn "$SOLCVERSION_SHORT" "$SOLCVERSION" + time_to_json_file "$(compilation_time_report_path "$preset")" "$compile_fn" + "$verify_fn" "$SOLCVERSION_SHORT" "$SOLCVERSION" if [[ "$COMPILE_ONLY" == 1 || " $compile_only_presets " == *" $preset "* ]]; then printLog "Skipping test function..." else printLog "Running test function..." - $test_fn + "$test_fn" fi } @@ -572,6 +572,13 @@ function gas_report_path echo "${DIR}/gas-report-${preset}.rst" } +function compilation_time_report_path +{ + local preset="$1" + + echo "${DIR}/compilation-time-report-${preset}.json" +} + function gas_report_to_json { cat - | "${REPO_ROOT}/scripts/externalTests/parse_eth_gas_report.py" | jq '{gas: .}' @@ -679,5 +686,6 @@ function store_benchmark_report "bytecode_size_json_from_${framework}_artifacts" | combine_artifact_json project_info_json "$project_url" + echo "{\"compilation_time\": $(cat "$(compilation_time_report_path "$preset")")}" } | jq --slurp "{\"${project_name}\": {\"${preset}\": add}}" --indent 4 --sort-keys > "$output_file" } From d96043f2d33ac4c30cbe0230b5737465ff1668d5 Mon Sep 17 00:00:00 2001 From: Vijay Raj Panchal <42858378+vijayrajpanchall@users.noreply.github.com> Date: Mon, 15 Apr 2024 10:32:57 +0530 Subject: [PATCH 0155/1022] Update Changelog.md Refactor: Update date to reflect current year in version 0.8.25 (2024-03-14) entry --- Changelog.md | 2 +- docs/bugs_by_version.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Changelog.md b/Changelog.md index ccc2de41a6ce..029f1944dd17 100644 --- a/Changelog.md +++ b/Changelog.md @@ -11,7 +11,7 @@ Bugfixes: * SMTChecker: Fix internal error when using bitwise operators with an array element as argument. -### 0.8.25 (2023-03-14) +### 0.8.25 (2024-03-14) Compiler Features: * Code Generator: Use ``MCOPY`` instead of ``MLOAD``/``MSTORE`` loop when copying byte arrays. diff --git a/docs/bugs_by_version.json b/docs/bugs_by_version.json index 7022635fde1a..52b6c9f48b3e 100644 --- a/docs/bugs_by_version.json +++ b/docs/bugs_by_version.json @@ -1892,7 +1892,7 @@ }, "0.8.25": { "bugs": [], - "released": "2023-03-14" + "released": "2024-03-14" }, "0.8.3": { "bugs": [ From 581d81434fa548f0425862d7a3fc68cb3fac9bac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Fri, 12 Apr 2024 13:04:05 +0200 Subject: [PATCH 0156/1022] time benchmarks: Actually ignore errors from legacy compilation --- test/benchmarks/run.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/benchmarks/run.sh b/test/benchmarks/run.sh index ef1c146f00c8..251e5dc3f407 100755 --- a/test/benchmarks/run.sh +++ b/test/benchmarks/run.sh @@ -51,7 +51,7 @@ do solc_command_via_ir=("${solc}" --via-ir --optimize --bin --color "${input_path}") # Legacy can fail. - "${time_bin_path}" --output "${result_legacy_file}" --format "%e" "${solc_command_legacy[@]}" >/dev/null 2>>"${warnings_and_errors_file}" + "${time_bin_path}" --output "${result_legacy_file}" --format "%e" "${solc_command_legacy[@]}" >/dev/null 2>>"${warnings_and_errors_file}" || true "${time_bin_path}" --output "${result_via_ir_file}" --format "%e" "${solc_command_via_ir[@]}" >/dev/null 2>>"${warnings_and_errors_file}" time_legacy=$(<"${result_legacy_file}") From d6198ee819f82e8956de55d0c0aa3eb7bb117578 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Fri, 12 Apr 2024 13:06:49 +0200 Subject: [PATCH 0157/1022] time benchmarks: Add bytecode size measurement --- test/benchmarks/run.sh | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/test/benchmarks/run.sh b/test/benchmarks/run.sh index 251e5dc3f407..d97c532524d5 100755 --- a/test/benchmarks/run.sh +++ b/test/benchmarks/run.sh @@ -26,6 +26,9 @@ set -euo pipefail REPO_ROOT=$(cd "$(dirname "$0")/../../" && pwd) SOLIDITY_BUILD_DIR=${SOLIDITY_BUILD_DIR:-${REPO_ROOT}/build} +# shellcheck source=scripts/common_cmdline.sh +source "${REPO_ROOT}/scripts/common_cmdline.sh" + output_dir=$(mktemp -d -t solc-benchmark-XXXXXX) result_legacy_file="${output_dir}/benchmark-legacy.txt" result_via_ir_file="${output_dir}/benchmark-via-ir.txt" @@ -38,6 +41,12 @@ function cleanup() { trap cleanup SIGINT SIGTERM +function bytecode_size { + local bytecode_chars + bytecode_chars=$(stripCLIDecorations | stripEmptyLines | wc --chars) + echo $(( bytecode_chars / 2 )) +} + solc="${SOLIDITY_BUILD_DIR}/solc/solc" benchmarks_dir="${REPO_ROOT}/test/benchmarks" benchmarks=("chains.sol" "OptimizorClub.sol" "verifier.sol") @@ -51,17 +60,20 @@ do solc_command_via_ir=("${solc}" --via-ir --optimize --bin --color "${input_path}") # Legacy can fail. - "${time_bin_path}" --output "${result_legacy_file}" --format "%e" "${solc_command_legacy[@]}" >/dev/null 2>>"${warnings_and_errors_file}" || true - "${time_bin_path}" --output "${result_via_ir_file}" --format "%e" "${solc_command_via_ir[@]}" >/dev/null 2>>"${warnings_and_errors_file}" + "${time_bin_path}" --output "${result_legacy_file}" --format "%e" "${solc_command_legacy[@]}" >"${output_dir}/bytecode-legacy.bin" 2>>"${warnings_and_errors_file}" || true + "${time_bin_path}" --output "${result_via_ir_file}" --format "%e" "${solc_command_via_ir[@]}" >"${output_dir}/bytecode-via-ir.bin" 2>>"${warnings_and_errors_file}" time_legacy=$(<"${result_legacy_file}") time_via_ir=$(<"${result_via_ir_file}") + bytecode_size_legacy=$(bytecode_size <"${output_dir}/bytecode-legacy.bin") + bytecode_size_via_ir=$(bytecode_size <"${output_dir}/bytecode-via-ir.bin") + echo "=======================================================" echo " ${input_file}" echo "-------------------------------------------------------" - echo "legacy pipeline took ${time_legacy} seconds to execute." - echo "via-ir pipeline took ${time_via_ir} seconds to execute." + echo "legacy pipeline took ${time_legacy} seconds to execute. Bytecode size is ${bytecode_size_legacy} bytes." + echo "via-ir pipeline took ${time_via_ir} seconds to execute. Bytecode size is ${bytecode_size_viar_ir} bytes." echo "=======================================================" done From 1317bcc9baa707fd6edd942b2d9f62322ea89eaf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Fri, 12 Apr 2024 13:13:23 +0200 Subject: [PATCH 0158/1022] time benchmarks: Accept solc binary as argument and add minimal validations --- test/benchmarks/run.sh | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/test/benchmarks/run.sh b/test/benchmarks/run.sh index d97c532524d5..8c4a660f8ec1 100755 --- a/test/benchmarks/run.sh +++ b/test/benchmarks/run.sh @@ -26,9 +26,16 @@ set -euo pipefail REPO_ROOT=$(cd "$(dirname "$0")/../../" && pwd) SOLIDITY_BUILD_DIR=${SOLIDITY_BUILD_DIR:-${REPO_ROOT}/build} +# shellcheck source=scripts/common.sh +source "${REPO_ROOT}/scripts/common.sh" # shellcheck source=scripts/common_cmdline.sh source "${REPO_ROOT}/scripts/common_cmdline.sh" +(( $# <= 1 )) || fail "Too many arguments. Usage: run.sh []" + +solc="${1:-${SOLIDITY_BUILD_DIR}/solc/solc}" +command_available "$solc" --version + output_dir=$(mktemp -d -t solc-benchmark-XXXXXX) result_legacy_file="${output_dir}/benchmark-legacy.txt" result_via_ir_file="${output_dir}/benchmark-via-ir.txt" @@ -47,7 +54,6 @@ function bytecode_size { echo $(( bytecode_chars / 2 )) } -solc="${SOLIDITY_BUILD_DIR}/solc/solc" benchmarks_dir="${REPO_ROOT}/test/benchmarks" benchmarks=("chains.sol" "OptimizorClub.sol" "verifier.sol") time_bin_path=$(type -P time) From 50433df2f1f32cf6577718fc45f4ffae2cddf167 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Fri, 12 Apr 2024 13:40:22 +0200 Subject: [PATCH 0159/1022] time benchmarks: Format results as a markdown table --- test/benchmarks/run.sh | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/test/benchmarks/run.sh b/test/benchmarks/run.sh index 8c4a660f8ec1..8bfd32d435a3 100755 --- a/test/benchmarks/run.sh +++ b/test/benchmarks/run.sh @@ -58,6 +58,9 @@ benchmarks_dir="${REPO_ROOT}/test/benchmarks" benchmarks=("chains.sol" "OptimizorClub.sol" "verifier.sol") time_bin_path=$(type -P time) +echo "| File | Pipeline | Bytecode size | Time | Exit code |" +echo "|----------------------|----------|--------------:|---------:|----------:|" + for input_file in "${benchmarks[@]}" do input_path="${benchmarks_dir}/${input_file}" @@ -66,21 +69,16 @@ do solc_command_via_ir=("${solc}" --via-ir --optimize --bin --color "${input_path}") # Legacy can fail. - "${time_bin_path}" --output "${result_legacy_file}" --format "%e" "${solc_command_legacy[@]}" >"${output_dir}/bytecode-legacy.bin" 2>>"${warnings_and_errors_file}" || true - "${time_bin_path}" --output "${result_via_ir_file}" --format "%e" "${solc_command_via_ir[@]}" >"${output_dir}/bytecode-via-ir.bin" 2>>"${warnings_and_errors_file}" + "${time_bin_path}" --output "${result_legacy_file}" --quiet --format "%e s | %x" "${solc_command_legacy[@]}" >"${output_dir}/bytecode-legacy.bin" 2>>"${warnings_and_errors_file}" || true + "${time_bin_path}" --output "${result_via_ir_file}" --quiet --format "%e s | %x" "${solc_command_via_ir[@]}" >"${output_dir}/bytecode-via-ir.bin" 2>>"${warnings_and_errors_file}" - time_legacy=$(<"${result_legacy_file}") - time_via_ir=$(<"${result_via_ir_file}") + time_and_status_legacy=$(<"${result_legacy_file}") + time_and_status_via_ir=$(<"${result_via_ir_file}") bytecode_size_legacy=$(bytecode_size <"${output_dir}/bytecode-legacy.bin") bytecode_size_via_ir=$(bytecode_size <"${output_dir}/bytecode-via-ir.bin") - - echo "=======================================================" - echo " ${input_file}" - echo "-------------------------------------------------------" - echo "legacy pipeline took ${time_legacy} seconds to execute. Bytecode size is ${bytecode_size_legacy} bytes." - echo "via-ir pipeline took ${time_via_ir} seconds to execute. Bytecode size is ${bytecode_size_viar_ir} bytes." - echo "=======================================================" + printf '| %-20s | legacy | %7d bytes | %20s |\n' '`'"$input_file"'`' "$bytecode_size_legacy" "$time_and_status_legacy" + printf '| %-20s | via-ir | %7d bytes | %20s |\n' '`'"$input_file"'`' "$bytecode_size_via_ir" "$time_and_status_via_ir" done echo From e6bd63be525380a18c63890986c3c7c3def35c57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Fri, 12 Apr 2024 14:11:20 +0200 Subject: [PATCH 0160/1022] time benchmarks: Reorder input files from fastest to slowest - --- test/benchmarks/run.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/benchmarks/run.sh b/test/benchmarks/run.sh index 8bfd32d435a3..8f873fde4b3f 100755 --- a/test/benchmarks/run.sh +++ b/test/benchmarks/run.sh @@ -55,7 +55,7 @@ function bytecode_size { } benchmarks_dir="${REPO_ROOT}/test/benchmarks" -benchmarks=("chains.sol" "OptimizorClub.sol" "verifier.sol") +benchmarks=("verifier.sol" "OptimizorClub.sol" "chains.sol") time_bin_path=$(type -P time) echo "| File | Pipeline | Bytecode size | Time | Exit code |" From 6b83a43ea0b6c0d631f17544b4b889e07b4b18b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Fri, 12 Apr 2024 14:14:04 +0200 Subject: [PATCH 0161/1022] time benchmarks: Refactor to reduce repetitiion --- test/benchmarks/run.sh | 47 ++++++++++++++++++++++-------------------- 1 file changed, 25 insertions(+), 22 deletions(-) diff --git a/test/benchmarks/run.sh b/test/benchmarks/run.sh index 8f873fde4b3f..1784b3700bde 100755 --- a/test/benchmarks/run.sh +++ b/test/benchmarks/run.sh @@ -37,9 +37,6 @@ solc="${1:-${SOLIDITY_BUILD_DIR}/solc/solc}" command_available "$solc" --version output_dir=$(mktemp -d -t solc-benchmark-XXXXXX) -result_legacy_file="${output_dir}/benchmark-legacy.txt" -result_via_ir_file="${output_dir}/benchmark-via-ir.txt" -warnings_and_errors_file="${output_dir}/benchmark-warn-err.txt" function cleanup() { rm -r "${output_dir}" @@ -54,7 +51,28 @@ function bytecode_size { echo $(( bytecode_chars / 2 )) } -benchmarks_dir="${REPO_ROOT}/test/benchmarks" +function benchmark_contract { + local pipeline="$1" + local input_path="$2" + + local solc_command=("${solc}" --optimize --bin --color "${input_path}") + [[ $pipeline == via-ir ]] && solc_command+=(--via-ir) + local time_args=(--output "${output_dir}/time-and-status-${pipeline}.txt" --quiet --format '%e s | %x') + + # NOTE: Legacy pipeline may fail with "Stack too deep" in some cases. That's fine. + "$time_bin_path" \ + "${time_args[@]}" \ + "${solc_command[@]}" \ + > "${output_dir}/bytecode-${pipeline}.bin" \ + 2>> "${output_dir}/benchmark-warn-err.txt" || [[ $pipeline == legacy ]] + + printf '| %-20s | %s | %7d bytes | %20s |\n' \ + '`'"$input_file"'`' \ + "$pipeline" \ + "$(bytecode_size < "${output_dir}/bytecode-${pipeline}.bin")" \ + "$(< "${output_dir}/time-and-status-${pipeline}.txt")" +} + benchmarks=("verifier.sol" "OptimizorClub.sol" "chains.sol") time_bin_path=$(type -P time) @@ -63,29 +81,14 @@ echo "|----------------------|----------|--------------:|---------:|----------:| for input_file in "${benchmarks[@]}" do - input_path="${benchmarks_dir}/${input_file}" - - solc_command_legacy=("${solc}" --optimize --bin --color "${input_path}") - solc_command_via_ir=("${solc}" --via-ir --optimize --bin --color "${input_path}") - - # Legacy can fail. - "${time_bin_path}" --output "${result_legacy_file}" --quiet --format "%e s | %x" "${solc_command_legacy[@]}" >"${output_dir}/bytecode-legacy.bin" 2>>"${warnings_and_errors_file}" || true - "${time_bin_path}" --output "${result_via_ir_file}" --quiet --format "%e s | %x" "${solc_command_via_ir[@]}" >"${output_dir}/bytecode-via-ir.bin" 2>>"${warnings_and_errors_file}" - - time_and_status_legacy=$(<"${result_legacy_file}") - time_and_status_via_ir=$(<"${result_via_ir_file}") - bytecode_size_legacy=$(bytecode_size <"${output_dir}/bytecode-legacy.bin") - bytecode_size_via_ir=$(bytecode_size <"${output_dir}/bytecode-via-ir.bin") - - printf '| %-20s | legacy | %7d bytes | %20s |\n' '`'"$input_file"'`' "$bytecode_size_legacy" "$time_and_status_legacy" - printf '| %-20s | via-ir | %7d bytes | %20s |\n' '`'"$input_file"'`' "$bytecode_size_via_ir" "$time_and_status_via_ir" + benchmark_contract legacy "${REPO_ROOT}/test/benchmarks/${input_file}" + benchmark_contract via-ir "${REPO_ROOT}/test/benchmarks/${input_file}" done echo echo "=======================================================" echo "Warnings and errors generated during run:" echo "=======================================================" -echo "$(<"${warnings_and_errors_file}")" +echo "$(< "${output_dir}/benchmark-warn-err.txt")" cleanup - From ac76c40ebc4a7ddea4cb545d5ed7e02a014095d1 Mon Sep 17 00:00:00 2001 From: r0qs Date: Tue, 16 Apr 2024 19:05:39 +0200 Subject: [PATCH 0162/1022] Prevent pnpm frozen lockfile --- .circleci/config.yml | 2 +- test/externalTests/prb-math.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 0dd960e93d19..8b588740fec4 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1452,7 +1452,7 @@ jobs: name: Install dependencies command: | cd hardhat - pnpm install + pnpm install --no-frozen-lockfile - run: name: Run hardhat-core test suite command: | diff --git a/test/externalTests/prb-math.py b/test/externalTests/prb-math.py index 2d1469fc9015..0cfefb843fa2 100755 --- a/test/externalTests/prb-math.py +++ b/test/externalTests/prb-math.py @@ -43,7 +43,7 @@ def configure(self): # Starting from version v4.0.2, the default installation method for PRBMath dependencies # has transitioned from Foundry to Node.js. subprocess.run( - ["pnpm", "install"], + ["pnpm", "install", "--no-frozen-lockfile"], env=self.env, check=True ) From 7f882ef57fc47c5b8d821a7eba8900149362b96b Mon Sep 17 00:00:00 2001 From: Nikola Matic Date: Mon, 4 Mar 2024 10:13:53 +0100 Subject: [PATCH 0163/1022] Bytecode difference caused by SSA transform Changelog Review comments Unique vector Repro test --- Changelog.md | 1 + libsolutil/CommonData.h | 43 ++++++++++++ libyul/optimiser/SSATransform.cpp | 37 ++++++----- scripts/common/cmdline_helpers.py | 46 +++++++++---- .../inputs.sol | 13 ++++ .../test.py | 65 +++++++++++++++++++ .../ssaTransform/function.yul | 8 +-- 7 files changed, 177 insertions(+), 36 deletions(-) create mode 100644 test/cmdlineTests/~bytecode_equivalence_with_unused_contracts/inputs.sol create mode 100755 test/cmdlineTests/~bytecode_equivalence_with_unused_contracts/test.py diff --git a/Changelog.md b/Changelog.md index 029f1944dd17..a54afa62cf9c 100644 --- a/Changelog.md +++ b/Changelog.md @@ -9,6 +9,7 @@ Compiler Features: Bugfixes: * SMTChecker: Fix internal error on mapping access caused by too strong requirements on sort compatibility of the index and mapping domain. * SMTChecker: Fix internal error when using bitwise operators with an array element as argument. + * Yul Optimizer: Fix the order of assignments generated by ``SSATransform`` being dependent on AST IDs, sometimes resulting in different (but equivalent) bytecode when unrelated files were added to the compilation pipeline. ### 0.8.25 (2024-03-14) diff --git a/libsolutil/CommonData.h b/libsolutil/CommonData.h index f3c168e6510b..de6873845dea 100644 --- a/libsolutil/CommonData.h +++ b/libsolutil/CommonData.h @@ -343,6 +343,49 @@ void joinMap(std::map& _a, std::map&& _b, F _conflictSolver) } } +template +class UniqueVector +{ +public: + std::vector const& contents() const { return m_contents; } + size_t size() const { return m_contents.size(); } + bool empty() const { return m_contents.empty(); } + auto begin() const { return m_contents.begin(); } + auto end() const { return m_contents.end(); } + void clear() { m_contents.clear(); } + bool contains(T const& _value) const + { + return std::find(m_contents.begin(), m_contents.end(), _value) != m_contents.end(); + } + + void pushBack(T _value) + { + if (!contains(_value)) + m_contents.emplace_back(std::move(_value)); + } + + void pushBack(UniqueVector const& _values) + { + for (auto&& value: _values) + pushBack(value); + } + + void removeAll(std::vector const& _values) + { + for (auto const& value: _values) + m_contents.erase(std::find(m_contents.begin(), m_contents.end(), value)); + } + +private: + std::vector m_contents; +}; + +template +void swap(UniqueVector& _lhs, UniqueVector& _rhs) +{ + std::swap(_lhs.contents(), _rhs.contents()); +} + namespace detail { diff --git a/libyul/optimiser/SSATransform.cpp b/libyul/optimiser/SSATransform.cpp index 675d21acc343..dba2f6f04610 100644 --- a/libyul/optimiser/SSATransform.cpp +++ b/libyul/optimiser/SSATransform.cpp @@ -166,8 +166,8 @@ class IntroduceControlFlowSSA: public ASTModifier std::set const& m_variablesToReplace; /// Variables (that are to be replaced) currently in scope. std::set m_variablesInScope; - /// Set of variables that do not have a specific value. - std::set m_variablesToReassign; + /// Variables that do not have a specific value. + util::UniqueVector m_variablesToReassign; TypeInfo const& m_typeInfo; }; @@ -175,14 +175,14 @@ void IntroduceControlFlowSSA::operator()(FunctionDefinition& _function) { std::set varsInScope; std::swap(varsInScope, m_variablesInScope); - std::set toReassign; + util::UniqueVector toReassign; std::swap(toReassign, m_variablesToReassign); for (auto const& param: _function.parameters) if (m_variablesToReplace.count(param.name)) { m_variablesInScope.insert(param.name); - m_variablesToReassign.insert(param.name); + m_variablesToReassign.pushBack(param.name); } ASTModifier::operator()(_function); @@ -196,8 +196,8 @@ void IntroduceControlFlowSSA::operator()(ForLoop& _for) yulAssert(_for.pre.statements.empty(), "For loop init rewriter not run."); for (auto const& var: assignedVariableNames(_for.body) + assignedVariableNames(_for.post)) - if (m_variablesInScope.count(var)) - m_variablesToReassign.insert(var); + if (util::contains(m_variablesInScope,var)) + m_variablesToReassign.pushBack(var); (*this)(_for.body); (*this)(_for.post); @@ -207,26 +207,26 @@ void IntroduceControlFlowSSA::operator()(Switch& _switch) { yulAssert(m_variablesToReassign.empty(), ""); - std::set toReassign; + util::UniqueVector toReassign; for (auto& c: _switch.cases) { (*this)(c.body); - toReassign += m_variablesToReassign; + toReassign.pushBack(m_variablesToReassign); } - m_variablesToReassign += toReassign; + m_variablesToReassign.pushBack(toReassign); } void IntroduceControlFlowSSA::operator()(Block& _block) { - std::set variablesDeclaredHere; - std::set assignedVariables; + util::UniqueVector variablesDeclaredHere; + util::UniqueVector assignedVariables; util::iterateReplacing( _block.statements, [&](Statement& _s) -> std::optional> { - std::vector toPrepend; + std::vector toPrepend; for (YulString toReassign: m_variablesToReassign) { YulString newName = m_nameDispenser.newName(toReassign); @@ -235,7 +235,7 @@ void IntroduceControlFlowSSA::operator()(Block& _block) {TypedName{debugDataOf(_s), newName, m_typeInfo.typeOfVariable(toReassign)}}, std::make_unique(Identifier{debugDataOf(_s), toReassign}) }); - assignedVariables.insert(toReassign); + assignedVariables.pushBack(toReassign); } m_variablesToReassign.clear(); @@ -245,7 +245,7 @@ void IntroduceControlFlowSSA::operator()(Block& _block) for (auto const& var: varDecl.variables) if (m_variablesToReplace.count(var.name)) { - variablesDeclaredHere.insert(var.name); + variablesDeclaredHere.pushBack(var.name); m_variablesInScope.insert(var.name); } } @@ -254,7 +254,7 @@ void IntroduceControlFlowSSA::operator()(Block& _block) Assignment& assignment = std::get(_s); for (auto const& var: assignment.variableNames) if (m_variablesToReplace.count(var.name)) - assignedVariables.insert(var.name); + assignedVariables.pushBack(var.name); } else visit(_s); @@ -268,9 +268,10 @@ void IntroduceControlFlowSSA::operator()(Block& _block) } } ); - m_variablesToReassign += assignedVariables; - m_variablesInScope -= variablesDeclaredHere; - m_variablesToReassign -= variablesDeclaredHere; + + m_variablesToReassign.pushBack(assignedVariables); + m_variablesInScope -= variablesDeclaredHere.contents(); + m_variablesToReassign.removeAll(variablesDeclaredHere.contents()); } /** diff --git a/scripts/common/cmdline_helpers.py b/scripts/common/cmdline_helpers.py index ede9f9385549..822cf7f85806 100644 --- a/scripts/common/cmdline_helpers.py +++ b/scripts/common/cmdline_helpers.py @@ -11,10 +11,12 @@ from bytecodecompare.prepare_report import parse_cli_output -DEFAULT_PREAMBLE = dedent(""" +DEFAULT_PREAMBLE = dedent( + """ // SPDX-License-Identifier: UNLICENSED pragma solidity >=0.0; -""") +""" +) def inside_temporary_dir(prefix): @@ -22,8 +24,10 @@ def inside_temporary_dir(prefix): Creates a temporary directory, enters the directory and executes the function inside it. Restores the previous working directory after executing the function. """ + def tmp_dir_decorator(fn): previous_dir = os.getcwd() + def f(*args, **kwargs): try: tmp_dir = mkdtemp(prefix=prefix) @@ -33,35 +37,49 @@ def f(*args, **kwargs): return result finally: os.chdir(previous_dir) + return f + return tmp_dir_decorator -def solc_bin_report(solc_binary: str, input_files: List[Path], via_ir: bool) -> FileReport: +def solc_bin_report( + solc_binary: str, + input_files: List[Path], + via_ir: bool, + optimize: bool = False, + yul_optimizations: Optional[str] = None, +) -> FileReport: """ Runs the solidity compiler binary """ output = subprocess.check_output( - [solc_binary, '--bin'] + - input_files + - (['--via-ir'] if via_ir else []), - encoding='utf8', + [solc_binary, "--bin"] + + input_files + + (["--via-ir"] if via_ir else []) + + (["--optimize"] if optimize else []) + + (["--yul-optimizations", yul_optimizations] if yul_optimizations else []), + encoding="utf8", ) - return parse_cli_output('', output, 0) + return parse_cli_output("", output, 0) -def save_bytecode(bytecode_path: Path, reports: FileReport, contract: Optional[str] = None): - with open(bytecode_path, 'w', encoding='utf8') as f: +def save_bytecode( + bytecode_path: Path, reports: FileReport, contract: Optional[str] = None +): + with open(bytecode_path, "w", encoding="utf8") as f: for report in reports.contract_reports: if contract is None or report.contract_name == contract: - bytecode = report.bytecode if report.bytecode is not None else '' - f.write(f'{report.contract_name}: {bytecode}\n') + bytecode = ( + report.bytecode if report.bytecode is not None else "" + ) + f.write(f"{report.contract_name}: {bytecode}\n") def add_preamble(source_path: Path, preamble: str = DEFAULT_PREAMBLE): - for source in source_path.glob('**/*.sol'): - with open(source, 'r+', encoding='utf8') as f: + for source in source_path.glob("**/*.sol"): + with open(source, "r+", encoding="utf8") as f: content = f.read() f.seek(0, 0) f.write(preamble + content) diff --git a/test/cmdlineTests/~bytecode_equivalence_with_unused_contracts/inputs.sol b/test/cmdlineTests/~bytecode_equivalence_with_unused_contracts/inputs.sol new file mode 100644 index 000000000000..ff982c56d495 --- /dev/null +++ b/test/cmdlineTests/~bytecode_equivalence_with_unused_contracts/inputs.sol @@ -0,0 +1,13 @@ +==== Source: A.sol ==== +contract DummyContract1 {} +contract DummyContract2 {} +contract DummyContract3 {} + +==== Source: B.sol ==== +contract B { + function f(uint8 a_0, uint8 a_1, uint8 a_2) public pure { + a_1 = 1; + a_2 = 2; + a_0; + } +} diff --git a/test/cmdlineTests/~bytecode_equivalence_with_unused_contracts/test.py b/test/cmdlineTests/~bytecode_equivalence_with_unused_contracts/test.py new file mode 100755 index 000000000000..e15293b8ea61 --- /dev/null +++ b/test/cmdlineTests/~bytecode_equivalence_with_unused_contracts/test.py @@ -0,0 +1,65 @@ +#!/usr/bin/env python3 + +import os +import sys +from pathlib import Path +from textwrap import dedent + +# pylint: disable=wrong-import-position +PROJECT_ROOT = Path(__file__).parents[3] +sys.path.insert(0, str(PROJECT_ROOT / "scripts")) + +from common.cmdline_helpers import add_preamble +from common.cmdline_helpers import inside_temporary_dir +from common.cmdline_helpers import save_bytecode +from common.cmdline_helpers import solc_bin_report +from common.git_helpers import git_diff +from splitSources import split_sources + + +@inside_temporary_dir(Path(__file__).parent.name) +def test_bytecode_equivalence(): + source_file_path = Path(__file__).parent / "inputs.sol" + split_sources(source_file_path, suppress_output=True) + add_preamble(Path.cwd()) + + solc_binary = os.environ.get("SOLC") + if solc_binary is None: + raise RuntimeError( + dedent( + """\ + `solc` compiler not found. + Please ensure you set the SOLC environment variable + with the correct path to the compiler's binary. + """ + ) + ) + + # Repro for https://github.com/ethereum/solidity/issues/14829 + save_bytecode( + Path("B.bin"), + solc_bin_report( + solc_binary, + [Path("B.sol")], + via_ir=True, + optimize=True, + yul_optimizations="a:", + ), + contract="B", + ) + save_bytecode( + Path("AB.bin"), + solc_bin_report( + solc_binary, + [Path("A.sol"), Path("B.sol")], + via_ir=True, + optimize=True, + yul_optimizations="a:", + ), + contract="B", + ) + return git_diff(Path("B.bin"), Path("AB.bin")) + + +if __name__ == "__main__": + sys.exit(test_bytecode_equivalence()) diff --git a/test/libyul/yulOptimizerTests/ssaTransform/function.yul b/test/libyul/yulOptimizerTests/ssaTransform/function.yul index d41c18b04c60..341d18cc12ce 100644 --- a/test/libyul/yulOptimizerTests/ssaTransform/function.yul +++ b/test/libyul/yulOptimizerTests/ssaTransform/function.yul @@ -12,15 +12,15 @@ // { // function f(a, b) -> c, d // { -// let b_5 := b -// let a_6 := a -// let b_1 := add(b_5, a_6) +// let a_5 := a +// let b_6 := b +// let b_1 := add(b_6, a_5) // b := b_1 // let c_2 := add(c, b_1) // c := c_2 // let d_3 := add(d, c_2) // d := d_3 -// let a_4 := add(a_6, d_3) +// let a_4 := add(a_5, d_3) // a := a_4 // } // } From 04b220da0dc5b82a8db213adc60128b5f696906c Mon Sep 17 00:00:00 2001 From: pcw109550 Date: Wed, 17 Apr 2024 09:17:38 -0600 Subject: [PATCH 0164/1022] Fix string/hex string literal implicit conversion to bytesNN --- docs/types/conversion.rst | 9 ++++----- ...ing_to_bytesNN_different_size_implicit.sol | 20 +++++++++++++++++++ 2 files changed, 24 insertions(+), 5 deletions(-) create mode 100644 test/libsolidity/syntaxTests/types/hex_string_to_bytesNN_different_size_implicit.sol diff --git a/docs/types/conversion.rst b/docs/types/conversion.rst index dafb336bd01e..92f0e19dc359 100644 --- a/docs/types/conversion.rst +++ b/docs/types/conversion.rst @@ -174,15 +174,14 @@ converted to any fixed-size bytes type: bytes4 g = 0x0; // fine String literals and hex string literals can be implicitly converted to fixed-size byte arrays, -if their number of characters matches the size of the bytes type: +if their number of characters is less than or equal to the size of the bytes type: .. code-block:: solidity bytes2 a = hex"1234"; // fine bytes2 b = "xy"; // fine - bytes2 c = hex"12"; // not allowed - bytes2 d = hex"123"; // not allowed - bytes2 e = "x"; // not allowed + bytes2 c = hex"12"; // fine + bytes2 e = "x"; // fine bytes2 f = "xyz"; // not allowed .. index:: literal;address @@ -199,4 +198,4 @@ An ``address a`` can be converted explicitly to ``address payable`` via ``payabl .. note:: Prior to version 0.8.0, it was possible to explicitly convert from any integer type (of any size, signed or unsigned) to ``address`` or ``address payable``. - Starting with in 0.8.0 only conversion from ``uint160`` is allowed. \ No newline at end of file + Starting with 0.8.0 only conversion from ``uint160`` is allowed. diff --git a/test/libsolidity/syntaxTests/types/hex_string_to_bytesNN_different_size_implicit.sol b/test/libsolidity/syntaxTests/types/hex_string_to_bytesNN_different_size_implicit.sol new file mode 100644 index 000000000000..177694af1ae1 --- /dev/null +++ b/test/libsolidity/syntaxTests/types/hex_string_to_bytesNN_different_size_implicit.sol @@ -0,0 +1,20 @@ +contract C { + function f() public pure { + bytes1 b1 = hex""; + bytes1 b2 = hex"1234"; + bytes2 b3 = hex"12"; + bytes2 b4 = hex"1234"; + bytes2 b5 = hex"123456"; + bytes3 b6 = hex"1234"; + bytes3 b7 = hex"123456"; + bytes3 b8 = hex"12345678"; + bytes4 b9 = hex"123456"; + bytes4 b10 = hex"12345678"; + bytes4 b11 = hex"1234567890"; + } +} +// ---- +// TypeError 9574: (72-93): Type literal_string hex"1234" is not implicitly convertible to expected type bytes1. Literal is larger than the type. +// TypeError 9574: (154-177): Type literal_string hex"123456" is not implicitly convertible to expected type bytes2. Literal is larger than the type. +// TypeError 9574: (242-267): Type literal_string hex"12345678" is not implicitly convertible to expected type bytes3. Literal is larger than the type. +// TypeError 9574: (337-365): Type literal_string hex"1234567890" is not implicitly convertible to expected type bytes4. Literal is larger than the type. From a0e1a3e2eacb925a291aa416bae9f130b5d3f893 Mon Sep 17 00:00:00 2001 From: Matheus Aguiar Date: Tue, 26 Mar 2024 16:26:57 -0300 Subject: [PATCH 0165/1022] fix uncaught ICE when --yul-optimizations is empty/blank --- Changelog.md | 2 ++ docs/internals/optimizer.rst | 2 +- libsolidity/interface/CompilerStack.cpp | 5 +--- libsolidity/interface/StandardCompiler.cpp | 7 ++++- libyul/optimiser/Suite.cpp | 20 ++++--------- solc/CommandLineParser.cpp | 11 +++++-- .../input.json | 25 ++++++++++++++++ .../output.json | 19 ++++++++++++ .../input.json | 25 ++++++++++++++++ .../output.json | 19 ++++++++++++ .../output.json | 4 +-- .../input.json | 19 ++++++++++++ .../output.json | 12 ++++++++ .../input.json | 19 ++++++++++++ .../output.json | 12 ++++++++ .../args | 1 + .../input.sol | 3 ++ .../output | 4 +++ .../yul_optimizer_steps_disabled/err | 2 +- test/solc/CommandLineInterface.cpp | 23 +++++++++++++++ test/solc/CommandLineParser.cpp | 29 ++++++++++++++++--- 21 files changed, 233 insertions(+), 30 deletions(-) create mode 100644 test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_empty_sequence_metadata/input.json create mode 100644 test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_empty_sequence_metadata/output.json create mode 100644 test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_empty_sequence_whitespaces_metadata/input.json create mode 100644 test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_empty_sequence_whitespaces_metadata/output.json create mode 100644 test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_no_yul_empty_string/input.json create mode 100644 test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_no_yul_empty_string/output.json create mode 100644 test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_no_yul_whitespaces/input.json create mode 100644 test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_no_yul_whitespaces/output.json create mode 100644 test/cmdlineTests/yul_optimizer_disabled_sequence_empty/args create mode 100644 test/cmdlineTests/yul_optimizer_disabled_sequence_empty/input.sol create mode 100644 test/cmdlineTests/yul_optimizer_disabled_sequence_empty/output diff --git a/Changelog.md b/Changelog.md index a54afa62cf9c..3a7f3ec9a20d 100644 --- a/Changelog.md +++ b/Changelog.md @@ -7,8 +7,10 @@ Compiler Features: Bugfixes: + * Commandline Interface: Fix ICE when the optimizer is disabled and an empty/blank string is used for ``--yul-optimizations`` sequence. * SMTChecker: Fix internal error on mapping access caused by too strong requirements on sort compatibility of the index and mapping domain. * SMTChecker: Fix internal error when using bitwise operators with an array element as argument. + * Standard JSON Interface: Fix ICE when the optimizer is disabled and an empty/blank string is used for ``optimizerSteps`` sequence. * Yul Optimizer: Fix the order of assignments generated by ``SSATransform`` being dependent on AST IDs, sometimes resulting in different (but equivalent) bytecode when unrelated files were added to the compilation pipeline. diff --git a/docs/internals/optimizer.rst b/docs/internals/optimizer.rst index 4588cb48358c..c1b959a8ab4d 100644 --- a/docs/internals/optimizer.rst +++ b/docs/internals/optimizer.rst @@ -46,7 +46,7 @@ for a stand-alone Yul mode. enabled by default and can only be turned off via the :ref:`Standard JSON `. .. note:: - An empty optimizer sequence is accepted even without ``--optimize`` in order to fully disable + An empty optimizer sequence, i.e ``:``, is accepted even without ``--optimize`` in order to fully disable the user-supplied portion of the Yul :ref:`optimizer sequence `, as by default, even when the optimizer is not turned on, the :ref:`unused pruner ` step will be run. diff --git a/libsolidity/interface/CompilerStack.cpp b/libsolidity/interface/CompilerStack.cpp index baba57d1d5ce..514f3a554755 100644 --- a/libsolidity/interface/CompilerStack.cpp +++ b/libsolidity/interface/CompilerStack.cpp @@ -1722,10 +1722,7 @@ std::string CompilerStack::createMetadata(Contract const& _contract, bool _forIR details["yulDetails"]["stackAllocation"] = m_optimiserSettings.optimizeStackAllocation; details["yulDetails"]["optimizerSteps"] = m_optimiserSettings.yulOptimiserSteps + ":" + m_optimiserSettings.yulOptimiserCleanupSteps; } - else if ( - OptimiserSuite::isEmptyOptimizerSequence(m_optimiserSettings.yulOptimiserSteps) && - OptimiserSuite::isEmptyOptimizerSequence(m_optimiserSettings.yulOptimiserCleanupSteps) - ) + else if (OptimiserSuite::isEmptyOptimizerSequence(m_optimiserSettings.yulOptimiserSteps + ":" + m_optimiserSettings.yulOptimiserCleanupSteps)) { solAssert(m_optimiserSettings.optimizeStackAllocation == false); details["yulDetails"] = Json::objectValue; diff --git a/libsolidity/interface/StandardCompiler.cpp b/libsolidity/interface/StandardCompiler.cpp index 85a5a5d232e5..1f7b3fa758b8 100644 --- a/libsolidity/interface/StandardCompiler.cpp +++ b/libsolidity/interface/StandardCompiler.cpp @@ -465,7 +465,12 @@ std::optional checkOptimizerDetailSteps(Json::Value const& _details { std::string const fullSequence = _details[_name].asString(); if (!_runYulOptimizer && !OptimiserSuite::isEmptyOptimizerSequence(fullSequence)) - return formatFatalError(Error::Type::JSONError, "If Yul optimizer is disabled, only an empty optimizerSteps sequence is accepted."); + { + std::string errorMessage = + "If Yul optimizer is disabled, only an empty optimizerSteps sequence is accepted." + " Note that the empty optimizer sequence is properly denoted by \":\"."; + return formatFatalError(Error::Type::JSONError, errorMessage); + } try { diff --git a/libyul/optimiser/Suite.cpp b/libyul/optimiser/Suite.cpp index 545ae4de06d7..d35cdc256c30 100644 --- a/libyul/optimiser/Suite.cpp +++ b/libyul/optimiser/Suite.cpp @@ -77,6 +77,8 @@ #include #include +#include +#include #include #include @@ -385,21 +387,9 @@ void OptimiserSuite::validateSequence(std::string_view _stepAbbreviations) bool OptimiserSuite::isEmptyOptimizerSequence(std::string const& _sequence) { - size_t delimiterCount{0}; - for (char const step: _sequence) - switch (step) - { - case ':': - if (++delimiterCount > 1) - return false; - break; - case ' ': - case '\n': - break; - default: - return false; - } - return true; + return + ranges::count(_sequence, ':') == 1 && + ranges::none_of(_sequence, [](auto _step) { return _step != ':' && _step != ' ' && _step != '\n'; }); } void OptimiserSuite::runSequence(std::string_view _stepAbbreviations, Block& _ast, bool _repeatUntilStable) diff --git a/solc/CommandLineParser.cpp b/solc/CommandLineParser.cpp index 6216af4a0180..824c899110a2 100644 --- a/solc/CommandLineParser.cpp +++ b/solc/CommandLineParser.cpp @@ -1229,8 +1229,15 @@ void CommandLineParser::processArgs() if (m_args.count(g_strYulOptimizations)) { OptimiserSettings optimiserSettings = m_options.optimiserSettings(); - if (!optimiserSettings.runYulOptimiser && !OptimiserSuite::isEmptyOptimizerSequence(m_args[g_strYulOptimizations].as())) - solThrow(CommandLineValidationError, "--" + g_strYulOptimizations + " is invalid with a non-empty sequence if Yul optimizer is disabled."); + if ( + !optimiserSettings.runYulOptimiser && + !OptimiserSuite::isEmptyOptimizerSequence(m_args[g_strYulOptimizations].as()) + ) + solThrow( + CommandLineValidationError, + "--" + g_strYulOptimizations + " is invalid with a non-empty sequence if Yul optimizer is disabled." + " Note that the empty optimizer sequence is properly denoted by \":\"." + ); try { diff --git a/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_empty_sequence_metadata/input.json b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_empty_sequence_metadata/input.json new file mode 100644 index 000000000000..e229656ea2ea --- /dev/null +++ b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_empty_sequence_metadata/input.json @@ -0,0 +1,25 @@ +{ + "language": "Solidity", + "sources": { + "A": {"content": " + // SPDX-License-Identifier: GPL-3.0 + pragma solidity >=0.0; + contract C { } + "} + }, + "settings": { + "optimizer": { + "details": { + "yul": false, + "yulDetails": { + "optimizerSteps": ":" + } + } + }, + "outputSelection": { + "*": { + "*": ["metadata"] + } + } + } +} diff --git a/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_empty_sequence_metadata/output.json b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_empty_sequence_metadata/output.json new file mode 100644 index 000000000000..725822763aff --- /dev/null +++ b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_empty_sequence_metadata/output.json @@ -0,0 +1,19 @@ +{ + "contracts": + { + "A": + { + "C": + { + "metadata": "{\"compiler\":{\"version\":\"\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"A\":\"C\"},\"evmVersion\":\"cancun\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"details\":{\"constantOptimizer\":false,\"cse\":false,\"deduplicate\":false,\"inliner\":false,\"jumpdestRemover\":true,\"orderLiterals\":false,\"peephole\":true,\"simpleCounterForLoopUncheckedIncrement\":true,\"yul\":false,\"yulDetails\":{\"optimizerSteps\":\":\"}},\"runs\":200},\"remappings\":[]},\"sources\":{\"A\":{\"keccak256\":\"0xb284c39999cb85b80be315a6e9e322adf67a783c66e91ba4439168694580a66d\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://098cee915fad095b8a996813768bd7d5e8c9e40c405e8c43d0572bb7bbc17334\",\"dweb:/ipfs/QmZmUzvSryrrD7pJ9S32iQnEWn4QBL4J1NdbQqL2Xc3yTr\"]}},\"version\":1}" + } + } + }, + "sources": + { + "A": + { + "id": 0 + } + } +} diff --git a/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_empty_sequence_whitespaces_metadata/input.json b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_empty_sequence_whitespaces_metadata/input.json new file mode 100644 index 000000000000..ddf2d963ff94 --- /dev/null +++ b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_empty_sequence_whitespaces_metadata/input.json @@ -0,0 +1,25 @@ +{ + "language": "Solidity", + "sources": { + "A": {"content": " + // SPDX-License-Identifier: GPL-3.0 + pragma solidity >=0.0; + contract C { } + "} + }, + "settings": { + "optimizer": { + "details": { + "yul": false, + "yulDetails": { + "optimizerSteps": " : " + } + } + }, + "outputSelection": { + "*": { + "*": ["metadata"] + } + } + } +} diff --git a/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_empty_sequence_whitespaces_metadata/output.json b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_empty_sequence_whitespaces_metadata/output.json new file mode 100644 index 000000000000..725822763aff --- /dev/null +++ b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_empty_sequence_whitespaces_metadata/output.json @@ -0,0 +1,19 @@ +{ + "contracts": + { + "A": + { + "C": + { + "metadata": "{\"compiler\":{\"version\":\"\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"A\":\"C\"},\"evmVersion\":\"cancun\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"details\":{\"constantOptimizer\":false,\"cse\":false,\"deduplicate\":false,\"inliner\":false,\"jumpdestRemover\":true,\"orderLiterals\":false,\"peephole\":true,\"simpleCounterForLoopUncheckedIncrement\":true,\"yul\":false,\"yulDetails\":{\"optimizerSteps\":\":\"}},\"runs\":200},\"remappings\":[]},\"sources\":{\"A\":{\"keccak256\":\"0xb284c39999cb85b80be315a6e9e322adf67a783c66e91ba4439168694580a66d\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://098cee915fad095b8a996813768bd7d5e8c9e40c405e8c43d0572bb7bbc17334\",\"dweb:/ipfs/QmZmUzvSryrrD7pJ9S32iQnEWn4QBL4J1NdbQqL2Xc3yTr\"]}},\"version\":1}" + } + } + }, + "sources": + { + "A": + { + "id": 0 + } + } +} diff --git a/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_no_yul/output.json b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_no_yul/output.json index fa3c9d93edc5..e0b6a26c1bfb 100644 --- a/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_no_yul/output.json +++ b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_no_yul/output.json @@ -3,8 +3,8 @@ [ { "component": "general", - "formattedMessage": "If Yul optimizer is disabled, only an empty optimizerSteps sequence is accepted.", - "message": "If Yul optimizer is disabled, only an empty optimizerSteps sequence is accepted.", + "formattedMessage": "If Yul optimizer is disabled, only an empty optimizerSteps sequence is accepted. Note that the empty optimizer sequence is properly denoted by \":\".", + "message": "If Yul optimizer is disabled, only an empty optimizerSteps sequence is accepted. Note that the empty optimizer sequence is properly denoted by \":\".", "severity": "error", "type": "JSONError" } diff --git a/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_no_yul_empty_string/input.json b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_no_yul_empty_string/input.json new file mode 100644 index 000000000000..ad7d7ff14b51 --- /dev/null +++ b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_no_yul_empty_string/input.json @@ -0,0 +1,19 @@ +{ + "language": "Solidity", + "sources": { + "A": {"content": " + // SPDX-License-Identifier: GPL-3.0 + pragma solidity >=0.0; + "} + }, + "settings": { + "optimizer": { + "details": { + "yul": false, + "yulDetails": { + "optimizerSteps": "" + } + } + } + } +} diff --git a/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_no_yul_empty_string/output.json b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_no_yul_empty_string/output.json new file mode 100644 index 000000000000..e0b6a26c1bfb --- /dev/null +++ b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_no_yul_empty_string/output.json @@ -0,0 +1,12 @@ +{ + "errors": + [ + { + "component": "general", + "formattedMessage": "If Yul optimizer is disabled, only an empty optimizerSteps sequence is accepted. Note that the empty optimizer sequence is properly denoted by \":\".", + "message": "If Yul optimizer is disabled, only an empty optimizerSteps sequence is accepted. Note that the empty optimizer sequence is properly denoted by \":\".", + "severity": "error", + "type": "JSONError" + } + ] +} diff --git a/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_no_yul_whitespaces/input.json b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_no_yul_whitespaces/input.json new file mode 100644 index 000000000000..85a53fce7713 --- /dev/null +++ b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_no_yul_whitespaces/input.json @@ -0,0 +1,19 @@ +{ + "language": "Solidity", + "sources": { + "A": {"content": " + // SPDX-License-Identifier: GPL-3.0 + pragma solidity >=0.0; + "} + }, + "settings": { + "optimizer": { + "details": { + "yul": false, + "yulDetails": { + "optimizerSteps": " " + } + } + } + } +} diff --git a/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_no_yul_whitespaces/output.json b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_no_yul_whitespaces/output.json new file mode 100644 index 000000000000..e0b6a26c1bfb --- /dev/null +++ b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_no_yul_whitespaces/output.json @@ -0,0 +1,12 @@ +{ + "errors": + [ + { + "component": "general", + "formattedMessage": "If Yul optimizer is disabled, only an empty optimizerSteps sequence is accepted. Note that the empty optimizer sequence is properly denoted by \":\".", + "message": "If Yul optimizer is disabled, only an empty optimizerSteps sequence is accepted. Note that the empty optimizer sequence is properly denoted by \":\".", + "severity": "error", + "type": "JSONError" + } + ] +} diff --git a/test/cmdlineTests/yul_optimizer_disabled_sequence_empty/args b/test/cmdlineTests/yul_optimizer_disabled_sequence_empty/args new file mode 100644 index 000000000000..da9301b32f2c --- /dev/null +++ b/test/cmdlineTests/yul_optimizer_disabled_sequence_empty/args @@ -0,0 +1 @@ +--metadata --yul-optimizations : \ No newline at end of file diff --git a/test/cmdlineTests/yul_optimizer_disabled_sequence_empty/input.sol b/test/cmdlineTests/yul_optimizer_disabled_sequence_empty/input.sol new file mode 100644 index 000000000000..37cd85bffa5d --- /dev/null +++ b/test/cmdlineTests/yul_optimizer_disabled_sequence_empty/input.sol @@ -0,0 +1,3 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity >=0.0; +contract C { } \ No newline at end of file diff --git a/test/cmdlineTests/yul_optimizer_disabled_sequence_empty/output b/test/cmdlineTests/yul_optimizer_disabled_sequence_empty/output new file mode 100644 index 000000000000..7b948303ee43 --- /dev/null +++ b/test/cmdlineTests/yul_optimizer_disabled_sequence_empty/output @@ -0,0 +1,4 @@ + +======= yul_optimizer_disabled_sequence_empty/input.sol:C ======= +Metadata: +{"compiler":{"version": ""},"language":"Solidity","output":{"abi":[],"devdoc":{"kind":"dev","methods":{},"version":1},"userdoc":{"kind":"user","methods":{},"version":1}},"settings":{"compilationTarget":{"yul_optimizer_disabled_sequence_empty/input.sol":"C"},"evmVersion":"cancun","libraries":{},"metadata":{"bytecodeHash":"ipfs"},"optimizer":{"details":{"constantOptimizer":false,"cse":false,"deduplicate":false,"inliner":false,"jumpdestRemover":true,"orderLiterals":false,"peephole":true,"simpleCounterForLoopUncheckedIncrement":true,"yul":false,"yulDetails":{"optimizerSteps":":"}},"runs":200},"remappings":[]},"sources":{"yul_optimizer_disabled_sequence_empty/input.sol":{"keccak256":"0xc2db3500808896ce1e69de2fe20cecab7ae2ffbb47cdf6ba8321296d95f49fc5","license":"GPL-3.0","urls":["bzz-raw://fde21393c068cd9f2d2b10ba4782db54f6f1c9a725074b17fa742531076be8a4","dweb:/ipfs/QmeTD6mR7YrWNyRowKRS7xs6cJNeMF3T49GAHzGM1bquyM"]}},"version":1} diff --git a/test/cmdlineTests/yul_optimizer_steps_disabled/err b/test/cmdlineTests/yul_optimizer_steps_disabled/err index 1abbab8bde55..c5a2e506d74b 100644 --- a/test/cmdlineTests/yul_optimizer_steps_disabled/err +++ b/test/cmdlineTests/yul_optimizer_steps_disabled/err @@ -1 +1 @@ -Error: --yul-optimizations is invalid with a non-empty sequence if Yul optimizer is disabled. +Error: --yul-optimizations is invalid with a non-empty sequence if Yul optimizer is disabled. Note that the empty optimizer sequence is properly denoted by ":". diff --git a/test/solc/CommandLineInterface.cpp b/test/solc/CommandLineInterface.cpp index 7a4f625c1570..73ebb2c54089 100644 --- a/test/solc/CommandLineInterface.cpp +++ b/test/solc/CommandLineInterface.cpp @@ -241,6 +241,29 @@ BOOST_AUTO_TEST_CASE(cli_input) BOOST_CHECK_EQUAL(result.reader.allowedDirectories(), expectedAllowedPaths); } +BOOST_AUTO_TEST_CASE(cli_optimizer_disabled_yul_optimization_input_whitespaces_or_empty) +{ + TemporaryDirectory tempDir(TEST_CASE_NAME); + createFilesWithParentDirs({tempDir.path() / "input.sol"}); + createFilesWithParentDirs({tempDir.path() / "input.yul"}); + + std::string const expectedMessage = + "--yul-optimizations is invalid with a non-empty sequence if Yul optimizer is disabled." + " Note that the empty optimizer sequence is properly denoted by \":\"."; + std::vector> const commandVariations = { + {"solc", "--strict-assembly", "--yul-optimizations", "", (tempDir.path() / "input.yul").string()}, + {"solc", "--strict-assembly", "--yul-optimizations", " ", (tempDir.path() / "input.yul").string()}, + {"solc", "--yul-optimizations", "", (tempDir.path() / "input.sol").string()}, + {"solc", "--yul-optimizations", " ", (tempDir.path() / "input.sol").string()}, + }; + for (auto const& command: commandVariations) + BOOST_CHECK_EXCEPTION( + parseCommandLineAndReadInputFiles(command), + CommandLineValidationError, + [&](auto const& _exception) { BOOST_TEST(_exception.what() == expectedMessage); return true; } + ); +} + BOOST_AUTO_TEST_CASE(cli_ignore_missing_some_files_exist) { TemporaryDirectory tempDir1(TEST_CASE_NAME); diff --git a/test/solc/CommandLineParser.cpp b/test/solc/CommandLineParser.cpp index e0592da5d174..9fe24bcc662f 100644 --- a/test/solc/CommandLineParser.cpp +++ b/test/solc/CommandLineParser.cpp @@ -498,6 +498,9 @@ BOOST_AUTO_TEST_CASE(valid_optimiser_sequences) { std::vector validSequenceInputs { ":", // Empty optimization sequence and empty cleanup sequence + " : ", // whitespaces only optimization sequence and whitespaces only cleanup sequence + ": ", // Empty optimization sequence and whitespaces only cleanup sequence + " :", // whitespaces only optimization sequence and empty cleanup sequence ":fDn", // Empty optimization sequence and specified cleanup sequence "dhfoDgvulfnTUtnIf:", // Specified optimization sequence and empty cleanup sequence "dhfoDgvulfnTUtnIf:fDn", // Specified optimization sequence and cleanup sequence @@ -509,6 +512,9 @@ BOOST_AUTO_TEST_CASE(valid_optimiser_sequences) std::vector> const expectedParsedSequences { {"", ""}, + {" ", " "}, + {"", " "}, + {" ", ""}, {"", "fDn"}, {"dhfoDgvulfnTUtnIf", ""}, {"dhfoDgvulfnTUtnIf", "fDn"}, @@ -600,11 +606,26 @@ BOOST_AUTO_TEST_CASE(valid_empty_optimizer_sequences_without_optimize) BOOST_AUTO_TEST_CASE(invalid_optimizer_sequence_without_optimize) { - std::string const invalidSequence{"u: "}; - std::string const expectedErrorMessage{"--yul-optimizations is invalid with a non-empty sequence if Yul optimizer is disabled."}; - std::vector commandLineOptions{"solc", "contract.sol", "--yul-optimizations=" + invalidSequence}; + std::vector const invalidSequenceInputs { + {" "}, + {"u: "}, + {"u:"}, + {":f"}, + {" :f"} + }; + + std::string const expectedErrorMessage{ + "--yul-optimizations is invalid with a non-empty sequence if Yul optimizer is disabled." + " Note that the empty optimizer sequence is properly denoted by \":\"." + }; + auto hasCorrectMessage = [&](CommandLineValidationError const& _exception) { return _exception.what() == expectedErrorMessage; }; - BOOST_CHECK_EXCEPTION(parseCommandLine(commandLineOptions), CommandLineValidationError, hasCorrectMessage); + + for (auto const& invalidSequence: invalidSequenceInputs) + { + std::vector commandLineOptions{"solc", "contract.sol", "--yul-optimizations=" + invalidSequence}; + BOOST_CHECK_EXCEPTION(parseCommandLine(commandLineOptions), CommandLineValidationError, hasCorrectMessage); + } } BOOST_AUTO_TEST_SUITE_END() From 00b2e54e1e0d54795adf904186e23dd08329a70f Mon Sep 17 00:00:00 2001 From: pgebal Date: Thu, 18 Apr 2024 18:24:28 +0200 Subject: [PATCH 0166/1022] Fix internal error when using an empty tuple with a ternary operator (#15025) --- Changelog.md | 1 + libsmtutil/Z3Interface.cpp | 6 ++++++ .../ternary_operator_with_functions.sol | 11 +++++++++++ .../operators/ternary_operator_with_tuple.sol | 18 ++++++++++++++++++ 4 files changed, 36 insertions(+) create mode 100644 test/libsolidity/smtCheckerTests/operators/ternary_operator_with_functions.sol create mode 100644 test/libsolidity/smtCheckerTests/operators/ternary_operator_with_tuple.sol diff --git a/Changelog.md b/Changelog.md index a54afa62cf9c..3fdd337aa5c3 100644 --- a/Changelog.md +++ b/Changelog.md @@ -8,6 +8,7 @@ Compiler Features: Bugfixes: * SMTChecker: Fix internal error on mapping access caused by too strong requirements on sort compatibility of the index and mapping domain. + * SMTChecker: Fix internal error when using an empty tuple in a conditional operator. * SMTChecker: Fix internal error when using bitwise operators with an array element as argument. * Yul Optimizer: Fix the order of assignments generated by ``SSATransform`` being dependent on AST IDs, sometimes resulting in different (but equivalent) bytecode when unrelated files were added to the compilation pipeline. diff --git a/libsmtutil/Z3Interface.cpp b/libsmtutil/Z3Interface.cpp index 1cfbc815f78e..4e1d1cec1236 100644 --- a/libsmtutil/Z3Interface.cpp +++ b/libsmtutil/Z3Interface.cpp @@ -169,6 +169,12 @@ z3::expr Z3Interface::toZ3Expr(Expression const& _expr) smtAssert(sortSort, ""); return m_context.constant(n.c_str(), z3Sort(*sortSort->inner)); } + else if (n == "tuple_constructor") + { + auto constructor = z3::func_decl(m_context, Z3_get_tuple_sort_mk_decl(m_context, z3Sort(*_expr.sort))); + smtAssert(constructor.arity() == arguments.size()); + return constructor(); + } else try { diff --git a/test/libsolidity/smtCheckerTests/operators/ternary_operator_with_functions.sol b/test/libsolidity/smtCheckerTests/operators/ternary_operator_with_functions.sol new file mode 100644 index 000000000000..8214862e7c82 --- /dev/null +++ b/test/libsolidity/smtCheckerTests/operators/ternary_operator_with_functions.sol @@ -0,0 +1,11 @@ +contract C { + function f() public {} + function g() public {} + + function test() public { + true ? f() : g(); + } +} +// ==== +// SMTEngine: all +// ---- diff --git a/test/libsolidity/smtCheckerTests/operators/ternary_operator_with_tuple.sol b/test/libsolidity/smtCheckerTests/operators/ternary_operator_with_tuple.sol new file mode 100644 index 000000000000..d05d699c3373 --- /dev/null +++ b/test/libsolidity/smtCheckerTests/operators/ternary_operator_with_tuple.sol @@ -0,0 +1,18 @@ +contract C { + function empty_tuple() public pure { + true ? () : (); // bug fix test, proper handling of empty tuples + } + + function non_empty_tuple() public pure { + true ? (1, 2) : (3, 4); + } + + function return_empty_tuple() public pure { + return true ? () : (); + } +} +// ==== +// SMTEngine: all +// ---- +// Warning 6133: (53-67): Statement has no effect. +// Warning 6133: (166-188): Statement has no effect. From cc27468bd6eca8fdb1d2a11af15307a57598c271 Mon Sep 17 00:00:00 2001 From: Alexander Arlt Date: Mon, 22 Apr 2024 12:27:36 +0200 Subject: [PATCH 0167/1022] Remove wordSizeTransform. --- test/libyul/YulOptimizerTest.cpp | 3 +-- test/libyul/YulOptimizerTestCommon.cpp | 7 +++---- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/test/libyul/YulOptimizerTest.cpp b/test/libyul/YulOptimizerTest.cpp index 9fc6712db330..82e2549809e2 100644 --- a/test/libyul/YulOptimizerTest.cpp +++ b/test/libyul/YulOptimizerTest.cpp @@ -81,8 +81,7 @@ TestCase::TestResult YulOptimizerTest::run(std::ostream& _stream, std::string co auto const printed = (m_object->subObjects.empty() ? AsmPrinter{ *m_dialect }(*m_object->code) : m_object->toString(m_dialect)); // Re-parse new code for compilability - // TODO: support for wordSizeTransform which needs different input and output dialects - if (m_optimizerStep != "wordSizeTransform" && !std::get<0>(parse(_stream, _linePrefix, _formatted, printed))) + if (!std::get<0>(parse(_stream, _linePrefix, _formatted, printed))) { util::AnsiColorized(_stream, _formatted, {util::formatting::BOLD, util::formatting::CYAN}) << _linePrefix << "Result after the optimiser:" << std::endl; diff --git a/test/libyul/YulOptimizerTestCommon.cpp b/test/libyul/YulOptimizerTestCommon.cpp index ea68f8dcd420..091a9a0b6cff 100644 --- a/test/libyul/YulOptimizerTestCommon.cpp +++ b/test/libyul/YulOptimizerTestCommon.cpp @@ -417,13 +417,12 @@ std::string YulOptimizerTestCommon::randomOptimiserStep(unsigned _seed) if (count == idx) { std::string optimiserStep = step.first; - // Do not fuzz mainFunction and wordSizeTransform - // because they do not preserve yul code semantics. + // Do not fuzz mainFunction + // because it does not preserve yul code semantics. // Do not fuzz reasoning based simplifier because // it can sometimes drain memory. if ( - optimiserStep == "mainFunction" || - optimiserStep == "wordSizeTransform" + optimiserStep == "mainFunction" ) // "Fullsuite" is fuzzed roughly four times more frequently than // other steps because of the filtering in place above. From df01dcc7b759f53ba45811979d3286562eab7846 Mon Sep 17 00:00:00 2001 From: pcw109550 Date: Tue, 23 Apr 2024 00:20:34 -0600 Subject: [PATCH 0168/1022] Better error message when consecutive underscores --- libsolidity/analysis/SyntaxChecker.cpp | 2 +- .../parsing/lexer_numbers_with_underscores_decimal_fail.sol | 2 +- .../parsing/lexer_numbers_with_underscores_fixed_fail.sol | 2 +- .../parsing/lexer_numbers_with_underscores_hex_fail.sol | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/libsolidity/analysis/SyntaxChecker.cpp b/libsolidity/analysis/SyntaxChecker.cpp index ac23ca36a8f4..b083690cced6 100644 --- a/libsolidity/analysis/SyntaxChecker.cpp +++ b/libsolidity/analysis/SyntaxChecker.cpp @@ -300,7 +300,7 @@ bool SyntaxChecker::visit(Literal const& _literal) if (value.find("__") != ASTString::npos) { - m_errorReporter.syntaxError(2990_error, _literal.location(), "Invalid use of underscores in number literal. Only one consecutive underscores between digits allowed."); + m_errorReporter.syntaxError(2990_error, _literal.location(), "Invalid use of underscores in number literal. Only one consecutive underscore between digits is allowed."); return true; } diff --git a/test/libsolidity/syntaxTests/parsing/lexer_numbers_with_underscores_decimal_fail.sol b/test/libsolidity/syntaxTests/parsing/lexer_numbers_with_underscores_decimal_fail.sol index 6cbeb217c771..279a67ade038 100644 --- a/test/libsolidity/syntaxTests/parsing/lexer_numbers_with_underscores_decimal_fail.sol +++ b/test/libsolidity/syntaxTests/parsing/lexer_numbers_with_underscores_decimal_fail.sol @@ -8,6 +8,6 @@ contract C { } // ---- // SyntaxError 2090: (56-61): Invalid use of underscores in number literal. No trailing underscores allowed. -// SyntaxError 2990: (77-83): Invalid use of underscores in number literal. Only one consecutive underscores between digits allowed. +// SyntaxError 2990: (77-83): Invalid use of underscores in number literal. Only one consecutive underscore between digits is allowed. // SyntaxError 6415: (99-105): Invalid use of underscores in number literal. No underscore at the end of the mantissa allowed. // SyntaxError 6165: (121-127): Invalid use of underscores in number literal. No underscore in front of exponent allowed. diff --git a/test/libsolidity/syntaxTests/parsing/lexer_numbers_with_underscores_fixed_fail.sol b/test/libsolidity/syntaxTests/parsing/lexer_numbers_with_underscores_fixed_fail.sol index 49bf042cdabe..43f0aa948285 100644 --- a/test/libsolidity/syntaxTests/parsing/lexer_numbers_with_underscores_fixed_fail.sol +++ b/test/libsolidity/syntaxTests/parsing/lexer_numbers_with_underscores_fixed_fail.sol @@ -10,7 +10,7 @@ contract C { } // ---- // SyntaxError 2090: (57-64): Invalid use of underscores in number literal. No trailing underscores allowed. -// SyntaxError 2990: (81-91): Invalid use of underscores in number literal. Only one consecutive underscores between digits allowed. +// SyntaxError 2990: (81-91): Invalid use of underscores in number literal. Only one consecutive underscore between digits is allowed. // SyntaxError 1023: (108-112): Invalid use of underscores in number literal. No underscores in front of the fraction part allowed. // SyntaxError 3891: (129-133): Invalid use of underscores in number literal. No underscores in front of the fraction part allowed. // SyntaxError 6165: (150-157): Invalid use of underscores in number literal. No underscore in front of exponent allowed. diff --git a/test/libsolidity/syntaxTests/parsing/lexer_numbers_with_underscores_hex_fail.sol b/test/libsolidity/syntaxTests/parsing/lexer_numbers_with_underscores_hex_fail.sol index 5a2e2f5c1f7e..50cfda8e29e0 100644 --- a/test/libsolidity/syntaxTests/parsing/lexer_numbers_with_underscores_hex_fail.sol +++ b/test/libsolidity/syntaxTests/parsing/lexer_numbers_with_underscores_hex_fail.sol @@ -4,4 +4,4 @@ contract C { } } // ---- -// SyntaxError 2990: (56-79): Invalid use of underscores in number literal. Only one consecutive underscores between digits allowed. +// SyntaxError 2990: (56-79): Invalid use of underscores in number literal. Only one consecutive underscore between digits is allowed. From f4534b19bd84d4526557e5cb44cfe242f8794040 Mon Sep 17 00:00:00 2001 From: edurivara Date: Fri, 15 Mar 2024 01:11:20 +0100 Subject: [PATCH 0169/1022] Reduce default font weight for readability --- docs/_static/css/toggle.css | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/_static/css/toggle.css b/docs/_static/css/toggle.css index 6f03e6fb6aba..c0265bfcb624 100644 --- a/docs/_static/css/toggle.css +++ b/docs/_static/css/toggle.css @@ -85,4 +85,8 @@ html.transition *:after { .wy-menu-vertical a:hover { background-color: #0002; +} + +body { + font-weight: 200; } \ No newline at end of file From fb11553a650f6e07299354a867fc80e1c1ba3c0b Mon Sep 17 00:00:00 2001 From: edurivara Date: Tue, 2 Apr 2024 17:13:45 +0200 Subject: [PATCH 0170/1022] Font weight to 200px and letter spacing 0.5px for readability --- docs/_static/css/toggle.css | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/_static/css/toggle.css b/docs/_static/css/toggle.css index c0265bfcb624..d525ab62a78f 100644 --- a/docs/_static/css/toggle.css +++ b/docs/_static/css/toggle.css @@ -88,5 +88,6 @@ html.transition *:after { } body { - font-weight: 200; + font-weight: 300; + letter-spacing: 0.5px; } \ No newline at end of file From 0711fa3f17f827319c7081312d60cce3c4902199 Mon Sep 17 00:00:00 2001 From: Nikola Matic Date: Wed, 6 Mar 2024 14:17:54 +0100 Subject: [PATCH 0171/1022] Require with custom error Disallow require with error in legacy More tests Docs Use AST ID in generated Yul helper function names Changelog Review comments --- Changelog.md | 1 + docs/contracts/errors.rst | 37 ++- docs/control-structures.rst | 29 +- docs/introduction-to-smart-contracts.rst | 14 +- libsolidity/analysis/GlobalContext.cpp | 1 + libsolidity/analysis/PostTypeChecker.cpp | 27 +- libsolidity/analysis/PostTypeChecker.h | 1 + libsolidity/ast/TypeProvider.cpp | 5 +- libsolidity/ast/TypeProvider.h | 2 +- libsolidity/ast/Types.cpp | 12 +- libsolidity/ast/Types.h | 3 + libsolidity/codegen/ExpressionCompiler.cpp | 6 + libsolidity/codegen/YulUtilFunctions.cpp | 62 ++++ libsolidity/codegen/YulUtilFunctions.h | 4 + .../codegen/ir/IRGeneratorForStatements.cpp | 52 ++-- .../codegen/ir/IRGeneratorForStatements.h | 1 + test/cmdlineTests/require_overload/err | 1 + test/cmdlineTests/require_with_error_ir/args | 1 + .../require_with_error_ir/input.sol | 17 ++ .../cmdlineTests/require_with_error_ir/output | 265 ++++++++++++++++++ .../~documentation_examples/test.sh | 4 + test/libsolidity/ASTJSON/used_errors.json | 8 +- ...quire_different_errors_same_parameters.sol | 21 ++ ...quire_error_function_pointer_parameter.sol | 20 ++ .../require_error_multiple_arguments.sol | 20 ++ .../errors/require_error_string_literal.sol | 20 ++ .../errors/require_error_string_memory.sol | 22 ++ .../errors/require_error_uint256.sol | 20 ++ .../errors/require_evaluation_order.sol | 28 ++ .../errors/require_inherited_error.sol | 17 ++ .../abi_encodeCall_tuple_from_error_event.sol | 2 +- ...encodeCall_tuple_from_invalid_operator.sol | 2 +- .../errors/abi_decode_error_constructor.sol | 9 + .../errors/abi_encode_error_constructor.sol | 8 + .../syntaxTests/errors/assert_with_error.sol | 2 +- .../syntaxTests/errors/require_custom.sol | 3 +- .../errors/require_custom_legacy.sol | 8 + .../syntaxTests/errors/require_nested.sol | 15 + .../errors/selector_on_instance.sol | 2 +- .../revertStatement/error_used_elsewhere.sol | 2 +- .../revertStatement/require_nested.sol | 13 + 41 files changed, 718 insertions(+), 69 deletions(-) create mode 100644 test/cmdlineTests/require_with_error_ir/args create mode 100644 test/cmdlineTests/require_with_error_ir/input.sol create mode 100644 test/cmdlineTests/require_with_error_ir/output create mode 100644 test/libsolidity/semanticTests/errors/require_different_errors_same_parameters.sol create mode 100644 test/libsolidity/semanticTests/errors/require_error_function_pointer_parameter.sol create mode 100644 test/libsolidity/semanticTests/errors/require_error_multiple_arguments.sol create mode 100644 test/libsolidity/semanticTests/errors/require_error_string_literal.sol create mode 100644 test/libsolidity/semanticTests/errors/require_error_string_memory.sol create mode 100644 test/libsolidity/semanticTests/errors/require_error_uint256.sol create mode 100644 test/libsolidity/semanticTests/errors/require_evaluation_order.sol create mode 100644 test/libsolidity/semanticTests/errors/require_inherited_error.sol create mode 100644 test/libsolidity/syntaxTests/errors/abi_decode_error_constructor.sol create mode 100644 test/libsolidity/syntaxTests/errors/abi_encode_error_constructor.sol create mode 100644 test/libsolidity/syntaxTests/errors/require_custom_legacy.sol create mode 100644 test/libsolidity/syntaxTests/errors/require_nested.sol create mode 100644 test/libsolidity/syntaxTests/revertStatement/require_nested.sol diff --git a/Changelog.md b/Changelog.md index c8b448c93cbb..c118e9f248a4 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,6 +1,7 @@ ### 0.8.26 (unreleased) Language Features: + * Introduce a new overload ``require(bool, Error)`` that allows usage of ``require`` functions with custom errors. This feature is available in the ``via-ir`` pipeline only. Compiler Features: diff --git a/docs/contracts/errors.rst b/docs/contracts/errors.rst index 19577a3872ba..e4955ddae1fd 100644 --- a/docs/contracts/errors.rst +++ b/docs/contracts/errors.rst @@ -1,22 +1,25 @@ -.. index:: ! error, revert, ! selector; of an error +.. index:: ! error, revert, require, ! selector; of an error .. _errors: -******************************* -Errors and the Revert Statement -******************************* +************* +Custom Errors +************* Errors in Solidity provide a convenient and gas-efficient way to explain to the user why an operation failed. They can be defined inside and outside of contracts (including interfaces and libraries). They have to be used together with the :ref:`revert statement ` -which causes -all changes in the current call to be reverted and passes the error data back to the -caller. +or the :ref:`require function `. +In the case of ``revert`` statements, or ``require`` calls where the condition is evaluated to be false, +all changes in the current call are reverted, and the error data passed back to the caller. + +The example below shows custom error usage with the ``revert`` statement in function ``transferWithRevertError``, +as well as the newer approach with ``require`` in function ``transferWithRequireError``. .. code-block:: solidity // SPDX-License-Identifier: GPL-3.0 - pragma solidity ^0.8.4; + pragma solidity ^0.8.26; /// Insufficient balance for transfer. Needed `required` but only /// `available` available. @@ -24,9 +27,10 @@ caller. /// @param required requested amount to transfer. error InsufficientBalance(uint256 available, uint256 required); + // This will only compile via IR contract TestToken { mapping(address => uint) balance; - function transfer(address to, uint256 amount) public { + function transferWithRevertError(address to, uint256 amount) public { if (amount > balance[msg.sender]) revert InsufficientBalance({ available: balance[msg.sender], @@ -35,12 +39,22 @@ caller. balance[msg.sender] -= amount; balance[to] += amount; } + function transferWithRequireError(address to, uint256 amount) public { + require(amount > balance[msg.sender], InsufficientBalance(balance[msg.sender], amount)); + balance[msg.sender] -= amount; + balance[to] += amount; + } // ... } +Another important detail to mention when it comes to using ``require`` with custom errors, is that memory +allocation for the error-based revert reason will only happen in the reverting case, which, along with +optimization of constants and string literals makes this about as gas-efficient as the +``if (!condition) revert CustomError(args)`` pattern. + Errors cannot be overloaded or overridden but are inherited. The same error can be defined in multiple places as long as the scopes are distinct. -Instances of errors can only be created using ``revert`` statements. +Instances of errors can only be created using ``revert`` statements, or as the second argument to ``require`` functions. The error creates data that is then passed to the caller with the revert operation to either return to the off-chain component or catch it in a :ref:`try/catch statement `. @@ -65,8 +79,7 @@ The selector consists of the first four bytes of the keccak256-hash of the signa only the name of the error is relevant, not the contract or file where it is defined. The statement ``require(condition, "description");`` would be equivalent to -``if (!condition) revert Error("description")`` if you could define -``error Error(string)``. +``if (!condition) revert Error("description")`` if you could define ``error Error(string)``. Note, however, that ``Error`` is a built-in type and cannot be defined in user-supplied code. Similarly, a failing ``assert`` or similar conditions will revert with an error diff --git a/docs/control-structures.rst b/docs/control-structures.rst index ea8a9c569de1..81e62ec57bea 100644 --- a/docs/control-structures.rst +++ b/docs/control-structures.rst @@ -594,6 +594,8 @@ The built-in errors ``Error(string)`` and ``Panic(uint256)`` are used by special functions, as explained below. ``Error`` is used for "regular" error conditions while ``Panic`` is used for errors that should not be present in bug-free code. +.. _assert-and-require-statements: + Panic via ``assert`` and Error via ``require`` ---------------------------------------------- @@ -625,21 +627,24 @@ The error code supplied with the error data indicates the kind of panic. #. 0x41: If you allocate too much memory or create an array that is too large. #. 0x51: If you call a zero-initialized variable of internal function type. -The ``require`` function either creates an error without any data or -an error of type ``Error(string)``. It -should be used to ensure valid conditions -that cannot be detected until execution time. -This includes conditions on inputs -or return values from calls to external contracts. +The ``require`` function provides three overloads: + +1. ``require(bool)`` which will revert without any data (not even an error selector). +2. ``require(bool, string)`` which will revert with an ``Error(string)``. +3. ``require(bool, error)`` which will revert with the custom, user supplied error provided as the second argument. .. note:: + ``require`` arguments are evaluated unconditionally, so take special care to make sure that + they are not expressions with unexpected side-effects. + For example, in ``require(condition, CustomError(f()));`` and ``require(condition, f());``, + function ``f()`` will be called regardless of whether the supplied condition is ``true`` or ``false``. - It is currently not possible to use custom errors in combination - with ``require``. Please use ``if (!condition) revert CustomError();`` instead. +.. note:: + Using custom errors with ``require`` is only supported by the via IR pipeline, i.e. compilation via Yul. + For the legacy pipeline, please use ``if (!condition) revert CustomError();`` instead. An ``Error(string)`` exception (or an exception without data) is generated -by the compiler -in the following situations: +by the compiler in the following situations: #. Calling ``require(x)`` where ``x`` evaluates to ``false``. #. If you use ``revert()`` or ``revert("description")``. @@ -662,10 +667,10 @@ an ``Error`` or a ``Panic`` (or whatever else was given): #. If you create a contract using the ``new`` keyword but the contract creation :ref:`does not finish properly`. -You can optionally provide a message string for ``require``, but not for ``assert``. +You can optionally provide a message string or a custom error to ``require``, but not to ``assert``. .. note:: - If you do not provide a string argument to ``require``, it will revert + If you do not provide a string or custom error argument to ``require``, it will revert with empty error data, not even including the error selector. diff --git a/docs/introduction-to-smart-contracts.rst b/docs/introduction-to-smart-contracts.rst index de06d684ec43..1c5b8737326e 100644 --- a/docs/introduction-to-smart-contracts.rst +++ b/docs/introduction-to-smart-contracts.rst @@ -85,8 +85,9 @@ registering with a username and password, all you need is an Ethereum keypair. .. code-block:: solidity // SPDX-License-Identifier: GPL-3.0 - pragma solidity ^0.8.4; + pragma solidity ^0.8.26; + // This will only compile via IR contract Coin { // The keyword "public" makes variables // accessible from other contracts @@ -118,12 +119,7 @@ registering with a username and password, all you need is an Ethereum keypair. // Sends an amount of existing coins // from any caller to an address function send(address receiver, uint amount) public { - if (amount > balances[msg.sender]) - revert InsufficientBalance({ - requested: amount, - available: balances[msg.sender] - }); - + require(amount > balances[msg.sender], InsufficientBalance(amount, balances[msg.sender])); balances[msg.sender] -= amount; balances[receiver] += amount; emit Sent(msg.sender, receiver, amount); @@ -225,8 +221,8 @@ than the maximum value of ``uint`` (``2**256 - 1``). This is also true for the s :ref:`Errors ` allow you to provide more information to the caller about why a condition or operation failed. Errors are used together with the :ref:`revert statement `. The ``revert`` statement unconditionally -aborts and reverts all changes similar to the ``require`` function, but it also -allows you to provide the name of an error and additional data which will be supplied to the caller +aborts and reverts all changes, much like the :ref:`require function `. +Both approaches allow you to provide the name of an error and additional data which will be supplied to the caller (and eventually to the front-end application or block explorer) so that a failure can more easily be debugged or reacted upon. diff --git a/libsolidity/analysis/GlobalContext.cpp b/libsolidity/analysis/GlobalContext.cpp index c4833689fe04..0c265d24515b 100644 --- a/libsolidity/analysis/GlobalContext.cpp +++ b/libsolidity/analysis/GlobalContext.cpp @@ -90,6 +90,7 @@ inline std::vector> constructMag magicVarDecl("now", TypeProvider::uint256()), magicVarDecl("require", TypeProvider::function(strings{"bool"}, strings{}, FunctionType::Kind::Require, StateMutability::Pure)), magicVarDecl("require", TypeProvider::function(strings{"bool", "string memory"}, strings{}, FunctionType::Kind::Require, StateMutability::Pure)), + magicVarDecl("require", TypeProvider::function(TypePointers{TypeProvider::boolean(), TypeProvider::magic(MagicType::Kind::Error)}, TypePointers{}, strings{2, ""}, strings{}, FunctionType::Kind::Require, StateMutability::Pure)), magicVarDecl("revert", TypeProvider::function(strings(), strings(), FunctionType::Kind::Revert, StateMutability::Pure)), magicVarDecl("revert", TypeProvider::function(strings{"string memory"}, strings(), FunctionType::Kind::Revert, StateMutability::Pure)), magicVarDecl("ripemd160", TypeProvider::function(strings{"bytes memory"}, strings{"bytes20"}, FunctionType::Kind::RIPEMD160, StateMutability::Pure)), diff --git a/libsolidity/analysis/PostTypeChecker.cpp b/libsolidity/analysis/PostTypeChecker.cpp index fe3a59d0cc97..9731ef3cc624 100644 --- a/libsolidity/analysis/PostTypeChecker.cpp +++ b/libsolidity/analysis/PostTypeChecker.cpp @@ -103,6 +103,11 @@ bool PostTypeChecker::visit(FunctionCall const& _functionCall) return callVisit(_functionCall); } +void PostTypeChecker::endVisit(FunctionCall const& _functionCall) +{ + callEndVisit(_functionCall); +} + bool PostTypeChecker::visit(Identifier const& _identifier) { return callVisit(_identifier); @@ -304,6 +309,7 @@ struct ModifierContextChecker: public PostTypeChecker::Checker bool m_insideModifierInvocation = false; }; +// TODO: this should either be split into separate emit and error checkers, or at least renamed to include require struct EventOutsideEmitErrorOutsideRevertChecker: public PostTypeChecker::Checker { EventOutsideEmitErrorOutsideRevertChecker(ErrorReporter& _errorReporter): @@ -336,6 +342,11 @@ struct EventOutsideEmitErrorOutsideRevertChecker: public PostTypeChecker::Checke if (*_functionCall.annotation().kind == FunctionCallKind::FunctionCall) if (auto const* functionType = dynamic_cast(_functionCall.expression().annotation().type)) { + if (functionType->kind() == FunctionType::Kind::Require) + { + solAssert(!m_inRequire); + m_inRequire = true; + } // Check for event outside of emit statement if (!dynamic_cast(m_currentStatement) && functionType->kind() == FunctionType::Kind::Event) m_errorReporter.typeError( @@ -343,11 +354,11 @@ struct EventOutsideEmitErrorOutsideRevertChecker: public PostTypeChecker::Checke _functionCall.location(), "Event invocations have to be prefixed by \"emit\"." ); - else if (!dynamic_cast(m_currentStatement) && functionType->kind() == FunctionType::Kind::Error) + else if (!dynamic_cast(m_currentStatement) && !m_inRequire && functionType->kind() == FunctionType::Kind::Error) m_errorReporter.typeError( 7757_error, _functionCall.location(), - "Errors can only be used with revert statements: \"revert MyError();\"." + "Errors can only be used with revert statements: \"revert MyError(args);\", or require functions: \"require(condition, MyError(args))\"." ); } m_currentStatement = nullptr; @@ -355,8 +366,20 @@ struct EventOutsideEmitErrorOutsideRevertChecker: public PostTypeChecker::Checke return true; } + void endVisit(FunctionCall const& _functionCall) override + { + if (*_functionCall.annotation().kind == FunctionCallKind::FunctionCall) + if (auto const* functionType = dynamic_cast(_functionCall.expression().annotation().type)) + if (functionType->kind() == FunctionType::Kind::Require) + { + solAssert(m_inRequire); + m_inRequire = false; + } + } + private: Statement const* m_currentStatement = nullptr; + bool m_inRequire = false; }; struct NoVariablesInInterfaceChecker: public PostTypeChecker::Checker diff --git a/libsolidity/analysis/PostTypeChecker.h b/libsolidity/analysis/PostTypeChecker.h index 178130a35663..347f464eda04 100644 --- a/libsolidity/analysis/PostTypeChecker.h +++ b/libsolidity/analysis/PostTypeChecker.h @@ -87,6 +87,7 @@ class PostTypeChecker: private ASTConstVisitor void endVisit(RevertStatement const& _revert) override; bool visit(FunctionCall const& _functionCall) override; + void endVisit(FunctionCall const& _functionCall) override; bool visit(Identifier const& _identifier) override; bool visit(MemberAccess const& _identifier) override; diff --git a/libsolidity/ast/TypeProvider.cpp b/libsolidity/ast/TypeProvider.cpp index da508755687b..41e103edf94f 100644 --- a/libsolidity/ast/TypeProvider.cpp +++ b/libsolidity/ast/TypeProvider.cpp @@ -145,11 +145,12 @@ std::array, 32> const TypeProvider::m_bytesM{{ {std::make_unique(32)} }}; -std::array, 4> const TypeProvider::m_magics{{ +std::array, 5> const TypeProvider::m_magics{{ {std::make_unique(MagicType::Kind::Block)}, {std::make_unique(MagicType::Kind::Message)}, {std::make_unique(MagicType::Kind::Transaction)}, - {std::make_unique(MagicType::Kind::ABI)} + {std::make_unique(MagicType::Kind::ABI)}, + {std::make_unique(MagicType::Kind::Error)} // MetaType is stored separately }}; diff --git a/libsolidity/ast/TypeProvider.h b/libsolidity/ast/TypeProvider.h index 02b9eb35d2b2..67b1fc0f29ae 100644 --- a/libsolidity/ast/TypeProvider.h +++ b/libsolidity/ast/TypeProvider.h @@ -226,7 +226,7 @@ class TypeProvider static std::array, 32> const m_intM; static std::array, 32> const m_uintM; static std::array, 32> const m_bytesM; - static std::array, 4> const m_magics; ///< MagicType's except MetaType + static std::array, 5> const m_magics; ///< MagicType's except MetaType std::map, std::unique_ptr> m_ufixedMxN{}; std::map, std::unique_ptr> m_fixedMxN{}; diff --git a/libsolidity/ast/Types.cpp b/libsolidity/ast/Types.cpp index d09d03fbec17..028b7667326f 100644 --- a/libsolidity/ast/Types.cpp +++ b/libsolidity/ast/Types.cpp @@ -2919,13 +2919,15 @@ FunctionType::FunctionType(ErrorDefinition const& _error): m_parameterTypes.push_back(var->annotation().type); } + m_returnParameterNames.push_back(""); + m_returnParameterTypes.push_back(TypeProvider::magic(MagicType::Kind::Error)); + solAssert( m_parameterNames.size() == m_parameterTypes.size(), "Parameter names list must match parameter types list!" ); solAssert( - m_returnParameterNames.size() == 0 && - m_returnParameterTypes.size() == 0, + m_returnParameterNames.size() == m_returnParameterTypes.size(), "" ); } @@ -4091,6 +4093,8 @@ std::string MagicType::richIdentifier() const case Kind::MetaType: solAssert(m_typeArgument, ""); return "t_magic_meta_type_" + m_typeArgument->richIdentifier(); + case Kind::Error: + return "t_error"; } return ""; } @@ -4196,6 +4200,8 @@ MemberList::MemberMap MagicType::nativeMembers(ASTNode const*) const FunctionType::Options::withArbitraryParameters() )} }); + case Kind::Error: + return {}; case Kind::MetaType: { solAssert( @@ -4259,6 +4265,8 @@ std::string MagicType::toString(bool _withoutDataLocation) const case Kind::MetaType: solAssert(m_typeArgument, ""); return "type(" + m_typeArgument->toString(_withoutDataLocation) + ")"; + case Kind::Error: + return "error"; } solAssert(false, "Unknown kind of magic."); return {}; diff --git a/libsolidity/ast/Types.h b/libsolidity/ast/Types.h index 7bbd2f075875..3ab4a1d97ebc 100644 --- a/libsolidity/ast/Types.h +++ b/libsolidity/ast/Types.h @@ -1661,6 +1661,8 @@ class ModuleType: public Type /** * Special type for magic variables (block, msg, tx, type(...)), similar to a struct but without any reference. + * + * It is also the type shared by all instances of all custom error types. */ class MagicType: public Type { @@ -1670,6 +1672,7 @@ class MagicType: public Type Message, ///< "msg" Transaction, ///< "tx" ABI, ///< "abi" + Error, ///< custom error instance MetaType ///< "type(...)" }; diff --git a/libsolidity/codegen/ExpressionCompiler.cpp b/libsolidity/codegen/ExpressionCompiler.cpp index 3824d5432139..54090f960437 100644 --- a/libsolidity/codegen/ExpressionCompiler.cpp +++ b/libsolidity/codegen/ExpressionCompiler.cpp @@ -1259,6 +1259,12 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall) // function call. solAssert(arguments.size() == 2, ""); solAssert(function.kind() == FunctionType::Kind::Require, ""); + // Check if the function call matches ``require(bool, error)``, and throw an unimplemented error, + // as require with custom errors is not supported in legacy codegen. + auto const* magicType = dynamic_cast(arguments[1]->annotation().type); + if (magicType && magicType->kind() == MagicType::Kind::Error) + solUnimplemented("Require with a custom error is only available using the via-ir pipeline."); + if (m_context.revertStrings() == RevertStrings::Strip) { if (!*arguments.at(1)->annotation().isPure) diff --git a/libsolidity/codegen/YulUtilFunctions.cpp b/libsolidity/codegen/YulUtilFunctions.cpp index 0dabc8a36928..5a135acb7b4e 100644 --- a/libsolidity/codegen/YulUtilFunctions.cpp +++ b/libsolidity/codegen/YulUtilFunctions.cpp @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -266,6 +267,67 @@ std::string YulUtilFunctions::requireOrAssertFunction(bool _assert, Type const* }); } +std::string YulUtilFunctions::requireWithErrorFunction(FunctionCall const& errorConstructorCall) +{ + ErrorDefinition const* errorDefinition = dynamic_cast(ASTNode::referencedDeclaration(errorConstructorCall.expression())); + solAssert(errorDefinition); + + std::string const errorSignature = errorDefinition->functionType(true)->externalSignature(); + std::string const signatureHash = formatNumber(util::selectorFromSignatureU256(errorSignature)); + std::string const functionName = [&]() { + // Note that in most cases we'll always generate one function per error definition, + // because types in the constructor call will match the ones in the definition. The only + // exception are calls with types, where each instance has its own type (e.g. literals). + std::string name = "require_helper_t_error_" + std::to_string(errorDefinition->id()) + "_" + errorDefinition->name(); + for (ASTPointer const& argument: errorConstructorCall.sortedArguments()) + { + solAssert(argument->annotation().type); + name += ("_" + argument->annotation().type->identifier()); + } + return name; + }(); + + auto errorArgumentVarsAndTypes = [&]() -> std::tuple, std::vector> { + std::vector errorArgumentVars; + std::vector errorArgumentTypes; + for (ASTPointer const& arg: errorConstructorCall.sortedArguments()) + { + solAssert(arg->annotation().type); + if (arg->annotation().type->sizeOnStack() > 0) + errorArgumentVars += IRVariable(*arg).stackSlots(); + errorArgumentTypes.push_back(arg->annotation().type); + } + return std::make_tuple(std::move(errorArgumentVars), std::move(errorArgumentTypes)); + }(); + + return m_functionCollector.createFunction(functionName, [&]() { + auto [errorArgumentVars, errorArgumentTypes] = errorArgumentVarsAndTypes; + std::string const encodeFunc = ABIFunctions(m_evmVersion, m_revertStrings, m_functionCollector) + .tupleEncoder( + errorArgumentTypes, + errorDefinition->functionType(true)->parameterTypes() + ); + + return Whiskers(R"( + function (condition ) { + if iszero(condition) { + let memPtr := () + mstore(memPtr, ) + let end := (add(memPtr, ) ) + revert(memPtr, sub(end, memPtr)) + } + } + )") + ("functionName", functionName) + ("allocateUnbounded", allocateUnboundedFunction()) + ("errorHash", signatureHash) + ("abiEncodeFunc", encodeFunc) + ("hashHeaderSize", std::to_string(4)) + ("errorArguments", joinHumanReadablePrefixed(errorArgumentVars)) + .render(); + }); +} + std::string YulUtilFunctions::leftAlignFunction(Type const& _type) { std::string functionName = std::string("leftAlign_") + _type.identifier(); diff --git a/libsolidity/codegen/YulUtilFunctions.h b/libsolidity/codegen/YulUtilFunctions.h index 7d736df5b3bc..db4c26725ddd 100644 --- a/libsolidity/codegen/YulUtilFunctions.h +++ b/libsolidity/codegen/YulUtilFunctions.h @@ -94,6 +94,10 @@ class YulUtilFunctions // `assert` or `require` call. std::string requireOrAssertFunction(bool _assert, Type const* _messageType = nullptr); + // @returns function that has equivalent logic of a require function, but with a custom + // error constructor parameter. + std::string requireWithErrorFunction(FunctionCall const& errorConstructorCall); + /// @returns the name of a function that takes a (cleaned) value of the given value type and /// left-aligns it, usually for use in non-padded encoding. std::string leftAlignFunction(Type const& _type); diff --git a/libsolidity/codegen/ir/IRGeneratorForStatements.cpp b/libsolidity/codegen/ir/IRGeneratorForStatements.cpp index 57414da93ba1..bf028fce510f 100644 --- a/libsolidity/codegen/ir/IRGeneratorForStatements.cpp +++ b/libsolidity/codegen/ir/IRGeneratorForStatements.cpp @@ -796,6 +796,17 @@ bool IRGeneratorForStatements::visit(UnaryOperation const& _unaryOperation) return false; } +void IRGeneratorForStatements::endVisit(RevertStatement const& _revertStatement) +{ + ErrorDefinition const* error = dynamic_cast(ASTNode::referencedDeclaration(_revertStatement.errorCall().expression())); + solAssert(error); + revertWithError( + error->functionType(true)->externalSignature(), + error->functionType(true)->parameterTypes(), + _revertStatement.errorCall().sortedArguments() + ); +} + bool IRGeneratorForStatements::visit(BinaryOperation const& _binOp) { setLocation(_binOp); @@ -1114,17 +1125,6 @@ void IRGeneratorForStatements::endVisit(FunctionCall const& _functionCall) appendCode() << templ.render(); break; } - case FunctionType::Kind::Error: - { - ErrorDefinition const* error = dynamic_cast(ASTNode::referencedDeclaration(_functionCall.expression())); - solAssert(error); - revertWithError( - error->functionType(true)->externalSignature(), - error->functionType(true)->parameterTypes(), - _functionCall.sortedArguments() - ); - break; - } case FunctionType::Kind::Wrap: case FunctionType::Kind::Unwrap: { @@ -1153,15 +1153,28 @@ void IRGeneratorForStatements::endVisit(FunctionCall const& _functionCall) arguments.size() > 1 && m_context.revertStrings() != RevertStrings::Strip ? arguments[1]->annotation().type : nullptr; - std::string requireOrAssertFunction = m_utils.requireOrAssertFunction( - functionType->kind() == FunctionType::Kind::Assert, - messageArgumentType - ); - appendCode() << std::move(requireOrAssertFunction) << "(" << IRVariable(*arguments[0]).name(); - if (messageArgumentType && messageArgumentType->sizeOnStack() > 0) - appendCode() << ", " << IRVariable(*arguments[1]).commaSeparatedList(); - appendCode() << ")\n"; + auto const* magicType = dynamic_cast(messageArgumentType); + if (magicType && magicType->kind() == MagicType::Kind::Error) + { + auto const& errorConstructorCall = dynamic_cast(*arguments[1]); + appendCode() << m_utils.requireWithErrorFunction(errorConstructorCall) << "(" <annotation().type->sizeOnStack() > 0) + appendCode() << ", " << IRVariable(*argument).commaSeparatedList(); + appendCode() << ")\n"; + } + else + { + std::string requireOrAssertFunction = m_utils.requireOrAssertFunction( + functionType->kind() == FunctionType::Kind::Assert, + messageArgumentType + ); + appendCode() << std::move(requireOrAssertFunction) << "(" << IRVariable(*arguments[0]).name(); + if (messageArgumentType && messageArgumentType->sizeOnStack() > 0) + appendCode() << ", " << IRVariable(*arguments[1]).commaSeparatedList(); + appendCode() << ")\n"; + } break; } @@ -1467,6 +1480,7 @@ void IRGeneratorForStatements::endVisit(FunctionCall const& _functionCall) ")\n"; break; } + case FunctionType::Kind::Error: case FunctionType::Kind::MetaType: { break; diff --git a/libsolidity/codegen/ir/IRGeneratorForStatements.h b/libsolidity/codegen/ir/IRGeneratorForStatements.h index f4ce2a7d00a1..15ef71f13844 100644 --- a/libsolidity/codegen/ir/IRGeneratorForStatements.h +++ b/libsolidity/codegen/ir/IRGeneratorForStatements.h @@ -132,6 +132,7 @@ class IRGeneratorForStatements: public IRGeneratorForStatementsBase void endVisit(IndexRangeAccess const& _indexRangeAccess) override; void endVisit(Identifier const& _identifier) override; bool visit(Literal const& _literal) override; + void endVisit(RevertStatement const& _revertStatement) override; bool visit(TryStatement const& _tryStatement) override; bool visit(TryCatchClause const& _tryCatchClause) override; diff --git a/test/cmdlineTests/require_overload/err b/test/cmdlineTests/require_overload/err index 4c33672d4a27..184c8c22bdd0 100644 --- a/test/cmdlineTests/require_overload/err +++ b/test/cmdlineTests/require_overload/err @@ -5,3 +5,4 @@ Error: No matching declaration found after argument-dependent lookup. | ^^^^^^^ Note: Candidate: function require(bool) Note: Candidate: function require(bool, string memory) +Note: Candidate: function require(bool, error) diff --git a/test/cmdlineTests/require_with_error_ir/args b/test/cmdlineTests/require_with_error_ir/args new file mode 100644 index 000000000000..be08aefb416b --- /dev/null +++ b/test/cmdlineTests/require_with_error_ir/args @@ -0,0 +1 @@ +--ir --debug-info none diff --git a/test/cmdlineTests/require_with_error_ir/input.sol b/test/cmdlineTests/require_with_error_ir/input.sol new file mode 100644 index 000000000000..f041b27b7ddf --- /dev/null +++ b/test/cmdlineTests/require_with_error_ir/input.sol @@ -0,0 +1,17 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity >=0.0; + +error CustomError(uint256, string); + +contract C +{ + function f(bool condition) external pure + { + require(condition, CustomError(1, "two")); + } + + function g(bool condition) external pure + { + require(condition, CustomError(2, "three")); + } +} diff --git a/test/cmdlineTests/require_with_error_ir/output b/test/cmdlineTests/require_with_error_ir/output new file mode 100644 index 000000000000..dacc9fc91032 --- /dev/null +++ b/test/cmdlineTests/require_with_error_ir/output @@ -0,0 +1,265 @@ +IR: + +/// @use-src 0:"require_with_error_ir/input.sol" +object "C_36" { + code { + + mstore(64, memoryguard(128)) + if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } + + constructor_C_36() + + let _1 := allocate_unbounded() + codecopy(_1, dataoffset("C_36_deployed"), datasize("C_36_deployed")) + + return(_1, datasize("C_36_deployed")) + + function allocate_unbounded() -> memPtr { + memPtr := mload(64) + } + + function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() { + revert(0, 0) + } + + function constructor_C_36() { + + } + + } + /// @use-src 0:"require_with_error_ir/input.sol" + object "C_36_deployed" { + code { + + mstore(64, memoryguard(128)) + + if iszero(lt(calldatasize(), 4)) + { + let selector := shift_right_224_unsigned(calldataload(0)) + switch selector + + case 0x98c3a6c1 + { + // f(bool) + + external_fun_f_21() + } + + case 0xd48092f7 + { + // g(bool) + + external_fun_g_35() + } + + default {} + } + + revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() + + function shift_right_224_unsigned(value) -> newValue { + newValue := + + shr(224, value) + + } + + function allocate_unbounded() -> memPtr { + memPtr := mload(64) + } + + function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() { + revert(0, 0) + } + + function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() { + revert(0, 0) + } + + function revert_error_c1322bf8034eace5e0b5c7295db60986aa89aae5e0ea0873e4689e076861a5db() { + revert(0, 0) + } + + function cleanup_t_bool(value) -> cleaned { + cleaned := iszero(iszero(value)) + } + + function validator_revert_t_bool(value) { + if iszero(eq(value, cleanup_t_bool(value))) { revert(0, 0) } + } + + function abi_decode_t_bool(offset, end) -> value { + value := calldataload(offset) + validator_revert_t_bool(value) + } + + function abi_decode_tuple_t_bool(headStart, dataEnd) -> value0 { + if slt(sub(dataEnd, headStart), 32) { revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() } + + { + + let offset := 0 + + value0 := abi_decode_t_bool(add(headStart, offset), dataEnd) + } + + } + + function abi_encode_tuple__to__fromStack(headStart ) -> tail { + tail := add(headStart, 0) + + } + + function external_fun_f_21() { + + if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } + let param_0 := abi_decode_tuple_t_bool(4, calldatasize()) + fun_f_21(param_0) + let memPos := allocate_unbounded() + let memEnd := abi_encode_tuple__to__fromStack(memPos ) + return(memPos, sub(memEnd, memPos)) + + } + + function external_fun_g_35() { + + if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } + let param_0 := abi_decode_tuple_t_bool(4, calldatasize()) + fun_g_35(param_0) + let memPos := allocate_unbounded() + let memEnd := abi_encode_tuple__to__fromStack(memPos ) + return(memPos, sub(memEnd, memPos)) + + } + + function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() { + revert(0, 0) + } + + function cleanup_t_rational_1_by_1(value) -> cleaned { + cleaned := value + } + + function cleanup_t_uint256(value) -> cleaned { + cleaned := value + } + + function identity(value) -> ret { + ret := value + } + + function convert_t_rational_1_by_1_to_t_uint256(value) -> converted { + converted := cleanup_t_uint256(identity(cleanup_t_rational_1_by_1(value))) + } + + function abi_encode_t_rational_1_by_1_to_t_uint256_fromStack(value, pos) { + mstore(pos, convert_t_rational_1_by_1_to_t_uint256(value)) + } + + function array_storeLengthForEncoding_t_string_memory_ptr_fromStack(pos, length) -> updated_pos { + mstore(pos, length) + updated_pos := add(pos, 0x20) + } + + function store_literal_in_memory_332c39dcd398ea34a48b871898d589f55fc4c7bce00562fb670c972e7e1b0720(memPtr) { + + mstore(add(memPtr, 0), "two") + + } + + function abi_encode_t_stringliteral_332c39dcd398ea34a48b871898d589f55fc4c7bce00562fb670c972e7e1b0720_to_t_string_memory_ptr_fromStack(pos) -> end { + pos := array_storeLengthForEncoding_t_string_memory_ptr_fromStack(pos, 3) + store_literal_in_memory_332c39dcd398ea34a48b871898d589f55fc4c7bce00562fb670c972e7e1b0720(pos) + end := add(pos, 32) + } + + function abi_encode_tuple_t_rational_1_by_1_t_stringliteral_332c39dcd398ea34a48b871898d589f55fc4c7bce00562fb670c972e7e1b0720__to_t_uint256_t_string_memory_ptr__fromStack(headStart , value0) -> tail { + tail := add(headStart, 64) + + abi_encode_t_rational_1_by_1_to_t_uint256_fromStack(value0, add(headStart, 0)) + + mstore(add(headStart, 32), sub(tail, headStart)) + tail := abi_encode_t_stringliteral_332c39dcd398ea34a48b871898d589f55fc4c7bce00562fb670c972e7e1b0720_to_t_string_memory_ptr_fromStack( tail) + + } + + function require_helper_t_error_7_CustomError_t_rational_1_by_1_t_stringliteral_332c39dcd398ea34a48b871898d589f55fc4c7bce00562fb670c972e7e1b0720(condition , expr_15) { + if iszero(condition) { + let memPtr := allocate_unbounded() + mstore(memPtr, 0x97ea5a2f00000000000000000000000000000000000000000000000000000000) + let end := abi_encode_tuple_t_rational_1_by_1_t_stringliteral_332c39dcd398ea34a48b871898d589f55fc4c7bce00562fb670c972e7e1b0720__to_t_uint256_t_string_memory_ptr__fromStack(add(memPtr, 4) , expr_15) + revert(memPtr, sub(end, memPtr)) + } + } + + function fun_f_21(var_condition_9) { + + let _1 := var_condition_9 + let expr_13 := _1 + + let expr_15 := 0x01 + + require_helper_t_error_7_CustomError_t_rational_1_by_1_t_stringliteral_332c39dcd398ea34a48b871898d589f55fc4c7bce00562fb670c972e7e1b0720(expr_13, expr_15) + + } + + function cleanup_t_rational_2_by_1(value) -> cleaned { + cleaned := value + } + + function convert_t_rational_2_by_1_to_t_uint256(value) -> converted { + converted := cleanup_t_uint256(identity(cleanup_t_rational_2_by_1(value))) + } + + function abi_encode_t_rational_2_by_1_to_t_uint256_fromStack(value, pos) { + mstore(pos, convert_t_rational_2_by_1_to_t_uint256(value)) + } + + function store_literal_in_memory_89027a4db8d1d3a0787296eb1553fba0dc506f981f9697f1a66994c458d392b5(memPtr) { + + mstore(add(memPtr, 0), "three") + + } + + function abi_encode_t_stringliteral_89027a4db8d1d3a0787296eb1553fba0dc506f981f9697f1a66994c458d392b5_to_t_string_memory_ptr_fromStack(pos) -> end { + pos := array_storeLengthForEncoding_t_string_memory_ptr_fromStack(pos, 5) + store_literal_in_memory_89027a4db8d1d3a0787296eb1553fba0dc506f981f9697f1a66994c458d392b5(pos) + end := add(pos, 32) + } + + function abi_encode_tuple_t_rational_2_by_1_t_stringliteral_89027a4db8d1d3a0787296eb1553fba0dc506f981f9697f1a66994c458d392b5__to_t_uint256_t_string_memory_ptr__fromStack(headStart , value0) -> tail { + tail := add(headStart, 64) + + abi_encode_t_rational_2_by_1_to_t_uint256_fromStack(value0, add(headStart, 0)) + + mstore(add(headStart, 32), sub(tail, headStart)) + tail := abi_encode_t_stringliteral_89027a4db8d1d3a0787296eb1553fba0dc506f981f9697f1a66994c458d392b5_to_t_string_memory_ptr_fromStack( tail) + + } + + function require_helper_t_error_7_CustomError_t_rational_2_by_1_t_stringliteral_89027a4db8d1d3a0787296eb1553fba0dc506f981f9697f1a66994c458d392b5(condition , expr_29) { + if iszero(condition) { + let memPtr := allocate_unbounded() + mstore(memPtr, 0x97ea5a2f00000000000000000000000000000000000000000000000000000000) + let end := abi_encode_tuple_t_rational_2_by_1_t_stringliteral_89027a4db8d1d3a0787296eb1553fba0dc506f981f9697f1a66994c458d392b5__to_t_uint256_t_string_memory_ptr__fromStack(add(memPtr, 4) , expr_29) + revert(memPtr, sub(end, memPtr)) + } + } + + function fun_g_35(var_condition_23) { + + let _2 := var_condition_23 + let expr_27 := _2 + + let expr_29 := 0x02 + + require_helper_t_error_7_CustomError_t_rational_2_by_1_t_stringliteral_89027a4db8d1d3a0787296eb1553fba0dc506f981f9697f1a66994c458d392b5(expr_27, expr_29) + + } + + } + + data ".metadata" hex"" + } + +} diff --git a/test/cmdlineTests/~documentation_examples/test.sh b/test/cmdlineTests/~documentation_examples/test.sh index 1acf5e8a7a4f..636f9600d2a8 100755 --- a/test/cmdlineTests/~documentation_examples/test.sh +++ b/test/cmdlineTests/~documentation_examples/test.sh @@ -39,6 +39,10 @@ do then opts+=(--ignore-warnings) fi + if grep "// This will only compile via IR" "$f" >/dev/null + then + opts+=(--via-ir) + fi # Disable the version pragma in code snippets that only work with the current development version. # It's necessary because x.y.z won't match `^x.y.z` or `>=x.y.z` pragmas until it's officially released. diff --git a/test/libsolidity/ASTJSON/used_errors.json b/test/libsolidity/ASTJSON/used_errors.json index 12a59f9cbf10..cff59a5efc5b 100644 --- a/test/libsolidity/ASTJSON/used_errors.json +++ b/test/libsolidity/ASTJSON/used_errors.json @@ -57,8 +57,8 @@ "src": "38:1:1", "typeDescriptions": { - "typeIdentifier": "t_function_error_pure$__$returns$__$", - "typeString": "function () pure" + "typeIdentifier": "t_function_error_pure$__$returns$_t_error_$", + "typeString": "function () pure returns (error)" } }, "id": 6, @@ -74,8 +74,8 @@ "tryCall": false, "typeDescriptions": { - "typeIdentifier": "t_tuple$__$", - "typeString": "tuple()" + "typeIdentifier": "t_error", + "typeString": "error" } }, "id": 7, diff --git a/test/libsolidity/semanticTests/errors/require_different_errors_same_parameters.sol b/test/libsolidity/semanticTests/errors/require_different_errors_same_parameters.sol new file mode 100644 index 000000000000..37cbb207da59 --- /dev/null +++ b/test/libsolidity/semanticTests/errors/require_different_errors_same_parameters.sol @@ -0,0 +1,21 @@ +error AnError(uint256, string, uint256); +error AnotherError(uint256, string, uint256); + +contract C +{ + function f() external pure + { + require(false, AnError(1, "two", 3)); + } + + function g() external pure + { + require(false, AnotherError(4, "five", 6)); + } +} + +// ==== +// compileViaYul: true +// ---- +// f() -> FAILURE, hex"f55fefe3", hex"0000000000000000000000000000000000000000000000000000000000000001", hex"0000000000000000000000000000000000000000000000000000000000000060", hex"0000000000000000000000000000000000000000000000000000000000000003", hex"0000000000000000000000000000000000000000000000000000000000000003", hex"74776f0000000000000000000000000000000000000000000000000000000000" +// g() -> FAILURE, hex"44a06798", hex"0000000000000000000000000000000000000000000000000000000000000004", hex"0000000000000000000000000000000000000000000000000000000000000060", hex"0000000000000000000000000000000000000000000000000000000000000006", hex"0000000000000000000000000000000000000000000000000000000000000004", hex"6669766500000000000000000000000000000000000000000000000000000000" diff --git a/test/libsolidity/semanticTests/errors/require_error_function_pointer_parameter.sol b/test/libsolidity/semanticTests/errors/require_error_function_pointer_parameter.sol new file mode 100644 index 000000000000..2e1dcdd5888a --- /dev/null +++ b/test/libsolidity/semanticTests/errors/require_error_function_pointer_parameter.sol @@ -0,0 +1,20 @@ +error CustomError(function(uint256) external pure returns (uint256)); + +contract C +{ + function e(uint256 x) external pure returns (uint256) + { + return x; + } + + function f() external view + { + // more than one stack slot + require(false, CustomError(this.e)); + } +} + +// ==== +// compileViaYul: true +// ---- +// f() -> FAILURE, hex"271b1dfa", hex"c06afe3a8444fc0004668591e8306bfb9968e79ef37cdc8e0000000000000000" diff --git a/test/libsolidity/semanticTests/errors/require_error_multiple_arguments.sol b/test/libsolidity/semanticTests/errors/require_error_multiple_arguments.sol new file mode 100644 index 000000000000..6c8521f9d2de --- /dev/null +++ b/test/libsolidity/semanticTests/errors/require_error_multiple_arguments.sol @@ -0,0 +1,20 @@ +error CustomError(uint256, string, uint256); + +contract C +{ + function f() external pure + { + require(false, CustomError(1, "two", 3)); + } + + function g() external pure + { + require(false, CustomError(4, "five", 6)); + } +} + +// ==== +// compileViaYul: true +// ---- +// f() -> FAILURE, hex"11a1077e", hex"0000000000000000000000000000000000000000000000000000000000000001", hex"0000000000000000000000000000000000000000000000000000000000000060", hex"0000000000000000000000000000000000000000000000000000000000000003", hex"0000000000000000000000000000000000000000000000000000000000000003", hex"74776f0000000000000000000000000000000000000000000000000000000000" +// g() -> FAILURE, hex"11a1077e", hex"0000000000000000000000000000000000000000000000000000000000000004", hex"0000000000000000000000000000000000000000000000000000000000000060", hex"0000000000000000000000000000000000000000000000000000000000000006", hex"0000000000000000000000000000000000000000000000000000000000000004", hex"6669766500000000000000000000000000000000000000000000000000000000" diff --git a/test/libsolidity/semanticTests/errors/require_error_string_literal.sol b/test/libsolidity/semanticTests/errors/require_error_string_literal.sol new file mode 100644 index 000000000000..5a3a140d0b23 --- /dev/null +++ b/test/libsolidity/semanticTests/errors/require_error_string_literal.sol @@ -0,0 +1,20 @@ +error CustomError(string); + +contract C +{ + function f() external pure + { + require(false, CustomError("errorReason")); + } + + function g() external pure + { + require(false, CustomError("anotherReason")); + } +} + +// ==== +// compileViaYul: true +// ---- +// f() -> FAILURE, hex"8d6ea8be", hex"0000000000000000000000000000000000000000000000000000000000000020", hex"000000000000000000000000000000000000000000000000000000000000000b", hex"6572726f72526561736f6e000000000000000000000000000000000000000000" +// g() -> FAILURE, hex"8d6ea8be", hex"0000000000000000000000000000000000000000000000000000000000000020", hex"000000000000000000000000000000000000000000000000000000000000000d", hex"616e6f74686572526561736f6e00000000000000000000000000000000000000" diff --git a/test/libsolidity/semanticTests/errors/require_error_string_memory.sol b/test/libsolidity/semanticTests/errors/require_error_string_memory.sol new file mode 100644 index 000000000000..13947d399036 --- /dev/null +++ b/test/libsolidity/semanticTests/errors/require_error_string_memory.sol @@ -0,0 +1,22 @@ +error CustomError(string); + +contract C +{ + function f() external pure + { + string memory reason = "errorReason"; + require(false, CustomError(reason)); + } + + function g() external pure + { + string memory reason = "anotherReason"; + require(false, CustomError(reason)); + } +} + +// ==== +// compileViaYul: true +// ---- +// f() -> FAILURE, hex"8d6ea8be", hex"0000000000000000000000000000000000000000000000000000000000000020", hex"000000000000000000000000000000000000000000000000000000000000000b", hex"6572726f72526561736f6e000000000000000000000000000000000000000000" +// g() -> FAILURE, hex"8d6ea8be", hex"0000000000000000000000000000000000000000000000000000000000000020", hex"000000000000000000000000000000000000000000000000000000000000000d", hex"616e6f74686572526561736f6e00000000000000000000000000000000000000" diff --git a/test/libsolidity/semanticTests/errors/require_error_uint256.sol b/test/libsolidity/semanticTests/errors/require_error_uint256.sol new file mode 100644 index 000000000000..d400e5fa7c23 --- /dev/null +++ b/test/libsolidity/semanticTests/errors/require_error_uint256.sol @@ -0,0 +1,20 @@ +error CustomError(uint256); + +contract C +{ + function f() external pure + { + require(false, CustomError(1)); + } + + function g() external pure + { + require(false, CustomError(2)); + } +} + +// ==== +// compileViaYul: true +// ---- +// f() -> FAILURE, hex"110b3655", hex"0000000000000000000000000000000000000000000000000000000000000001" +// g() -> FAILURE, hex"110b3655", hex"0000000000000000000000000000000000000000000000000000000000000002" diff --git a/test/libsolidity/semanticTests/errors/require_evaluation_order.sol b/test/libsolidity/semanticTests/errors/require_evaluation_order.sol new file mode 100644 index 000000000000..4733b3aee73b --- /dev/null +++ b/test/libsolidity/semanticTests/errors/require_evaluation_order.sol @@ -0,0 +1,28 @@ +contract C +{ + error E(uint); + + function r() internal returns (uint) + { + assembly { mstore(0, 7) return (0, 32) } + return 42; + } + + function f() public returns (uint) + { + require(false, E(r())); + return 42; + } + + function g() public returns (uint) + { + require(true, E(r())); + return 42; + } +} + +// ==== +// compileViaYul: true +// ---- +// f() -> 7 +// g() -> 7 diff --git a/test/libsolidity/semanticTests/errors/require_inherited_error.sol b/test/libsolidity/semanticTests/errors/require_inherited_error.sol new file mode 100644 index 000000000000..24b544b73cf9 --- /dev/null +++ b/test/libsolidity/semanticTests/errors/require_inherited_error.sol @@ -0,0 +1,17 @@ +contract Base +{ + error CustomError(uint256, string, uint256); +} + +contract C is Base +{ + function f() external pure + { + require(false, CustomError(1, "two", 3)); + } +} + +// ==== +// compileViaYul: true +// ---- +// f() -> FAILURE, hex"11a1077e", hex"0000000000000000000000000000000000000000000000000000000000000001", hex"0000000000000000000000000000000000000000000000000000000000000060", hex"0000000000000000000000000000000000000000000000000000000000000003", hex"0000000000000000000000000000000000000000000000000000000000000003", hex"74776f0000000000000000000000000000000000000000000000000000000000" diff --git a/test/libsolidity/syntaxTests/abiEncoder/abi_encodeCall_tuple_from_error_event.sol b/test/libsolidity/syntaxTests/abiEncoder/abi_encodeCall_tuple_from_error_event.sol index c96b82909921..c309d4c22724 100644 --- a/test/libsolidity/syntaxTests/abiEncoder/abi_encodeCall_tuple_from_error_event.sol +++ b/test/libsolidity/syntaxTests/abiEncoder/abi_encodeCall_tuple_from_error_event.sol @@ -12,5 +12,5 @@ contract C { } // ---- // TypeError 9062: (138-142): Expected an inline tuple, not an expression of a tuple type. -// TypeError 9062: (177-181): Expected an inline tuple, not an expression of a tuple type. +// TypeError 7515: (153-182): Expected a tuple with 0 components instead of a single non-tuple parameter. // TypeError 9062: (216-224): Expected an inline tuple, not an expression of a tuple type. diff --git a/test/libsolidity/syntaxTests/abiEncoder/abi_encodeCall_tuple_from_invalid_operator.sol b/test/libsolidity/syntaxTests/abiEncoder/abi_encodeCall_tuple_from_invalid_operator.sol index f6035dd0af33..9646acf483f2 100644 --- a/test/libsolidity/syntaxTests/abiEncoder/abi_encodeCall_tuple_from_invalid_operator.sol +++ b/test/libsolidity/syntaxTests/abiEncoder/abi_encodeCall_tuple_from_invalid_operator.sol @@ -17,7 +17,7 @@ contract C { // ---- // TypeError 2271: (284-299): Built-in binary operator + cannot be applied to types tuple(int_const 1,int_const 1) and tuple(int_const 2,int_const 2). // TypeError 9062: (284-299): Expected an inline tuple, not an expression of a tuple type. -// TypeError 2271: (334-345): Built-in binary operator / cannot be applied to types tuple() and tuple(). +// TypeError 2271: (334-345): Built-in binary operator / cannot be applied to types tuple() and error. // TypeError 9062: (334-345): Expected an inline tuple, not an expression of a tuple type. // TypeError 4907: (380-383): Built-in unary operator ! cannot be applied to type tuple(). // TypeError 9062: (380-383): Expected an inline tuple, not an expression of a tuple type. diff --git a/test/libsolidity/syntaxTests/errors/abi_decode_error_constructor.sol b/test/libsolidity/syntaxTests/errors/abi_decode_error_constructor.sol new file mode 100644 index 000000000000..d3d26e6ccbab --- /dev/null +++ b/test/libsolidity/syntaxTests/errors/abi_decode_error_constructor.sol @@ -0,0 +1,9 @@ +error E(uint); +contract C { + function f() public pure returns (bytes memory) { + return abi.decode(msg.data, (E(1))); + } +} +// ---- +// TypeError 1039: (119-123): Argument has to be a type name. +// TypeError 5132: (90-125): Different number of arguments in return statement than in returns declaration. diff --git a/test/libsolidity/syntaxTests/errors/abi_encode_error_constructor.sol b/test/libsolidity/syntaxTests/errors/abi_encode_error_constructor.sol new file mode 100644 index 000000000000..e8a22b08e2e5 --- /dev/null +++ b/test/libsolidity/syntaxTests/errors/abi_encode_error_constructor.sol @@ -0,0 +1,8 @@ +error E(uint); +contract C { + function f() public pure returns (bytes memory) { + return abi.encode(E(1)); + } +} +// ---- +// TypeError 2056: (108-112): This type cannot be encoded. diff --git a/test/libsolidity/syntaxTests/errors/assert_with_error.sol b/test/libsolidity/syntaxTests/errors/assert_with_error.sol index 90f79b40eeb7..16972baaffb9 100644 --- a/test/libsolidity/syntaxTests/errors/assert_with_error.sol +++ b/test/libsolidity/syntaxTests/errors/assert_with_error.sol @@ -3,4 +3,4 @@ function f() pure { assert(E()); } // ---- -// TypeError 9553: (42-45): Invalid type for argument in function call. Invalid implicit conversion from tuple() to bool requested. +// TypeError 9553: (42-45): Invalid type for argument in function call. Invalid implicit conversion from error to bool requested. diff --git a/test/libsolidity/syntaxTests/errors/require_custom.sol b/test/libsolidity/syntaxTests/errors/require_custom.sol index f139a4fe5a7c..f428390277fb 100644 --- a/test/libsolidity/syntaxTests/errors/require_custom.sol +++ b/test/libsolidity/syntaxTests/errors/require_custom.sol @@ -4,5 +4,6 @@ contract C { require(c, E(2, 7)); } } +// ==== +// compileViaYul: true // ---- -// TypeError 9322: (83-90): No matching declaration found after argument-dependent lookup. diff --git a/test/libsolidity/syntaxTests/errors/require_custom_legacy.sol b/test/libsolidity/syntaxTests/errors/require_custom_legacy.sol new file mode 100644 index 000000000000..334b847393cb --- /dev/null +++ b/test/libsolidity/syntaxTests/errors/require_custom_legacy.sol @@ -0,0 +1,8 @@ +error E(uint a, uint b); +contract C { + function f(bool c) public pure { + require(c, E(2, 7)); + } +} +// ---- +// UnimplementedFeatureError: Require with a custom error is only available using the via-ir pipeline. diff --git a/test/libsolidity/syntaxTests/errors/require_nested.sol b/test/libsolidity/syntaxTests/errors/require_nested.sol new file mode 100644 index 000000000000..c5dc018242df --- /dev/null +++ b/test/libsolidity/syntaxTests/errors/require_nested.sol @@ -0,0 +1,15 @@ +error CustomError(uint256); + +contract C +{ + function f() public pure returns (uint256) + { + require(false, require(CustomError(1))); + return 2; + } +} + +// ==== +// compileViaYul: true +// ---- +// TypeError 9322: (118-125): No matching declaration found after argument-dependent lookup. diff --git a/test/libsolidity/syntaxTests/errors/selector_on_instance.sol b/test/libsolidity/syntaxTests/errors/selector_on_instance.sol index 3eac5984f311..008a94c02789 100644 --- a/test/libsolidity/syntaxTests/errors/selector_on_instance.sol +++ b/test/libsolidity/syntaxTests/errors/selector_on_instance.sol @@ -4,4 +4,4 @@ contract C { bytes4 t = E().selector; } // ---- -// TypeError 9582: (40-52): Member "selector" not found or not visible after argument-dependent lookup in tuple(). +// TypeError 9582: (40-52): Member "selector" not found or not visible after argument-dependent lookup in error. diff --git a/test/libsolidity/syntaxTests/revertStatement/error_used_elsewhere.sol b/test/libsolidity/syntaxTests/revertStatement/error_used_elsewhere.sol index 208a7326be14..bad026154d31 100644 --- a/test/libsolidity/syntaxTests/revertStatement/error_used_elsewhere.sol +++ b/test/libsolidity/syntaxTests/revertStatement/error_used_elsewhere.sol @@ -3,4 +3,4 @@ function f() pure { E(); } // ---- -// TypeError 7757: (35-38): Errors can only be used with revert statements: "revert MyError();". +// TypeError 7757: (35-38): Errors can only be used with revert statements: "revert MyError(args);", or require functions: "require(condition, MyError(args))". diff --git a/test/libsolidity/syntaxTests/revertStatement/require_nested.sol b/test/libsolidity/syntaxTests/revertStatement/require_nested.sol new file mode 100644 index 000000000000..721c37c254e2 --- /dev/null +++ b/test/libsolidity/syntaxTests/revertStatement/require_nested.sol @@ -0,0 +1,13 @@ +error Error(uint256); + +contract C +{ + error OtherError(uint256); + + function f() external pure + { + revert Error(require(false, OtherError(1))); + } +} +// ---- +// TypeError 9553: (126-155): Invalid type for argument in function call. Invalid implicit conversion from tuple() to uint256 requested. From 1bf0f386a0fca48cc509f5ea51ad0356d28dd86d Mon Sep 17 00:00:00 2001 From: Nikola Matic Date: Fri, 19 Apr 2024 12:57:09 +0200 Subject: [PATCH 0172/1022] Refactor revertWithError usage --- libsolidity/codegen/YulUtilFunctions.cpp | 104 ++++++++++-------- libsolidity/codegen/YulUtilFunctions.h | 12 ++ .../codegen/ir/IRGeneratorForStatements.cpp | 31 ++---- .../cmdlineTests/require_with_error_ir/output | 6 +- 4 files changed, 83 insertions(+), 70 deletions(-) diff --git a/libsolidity/codegen/YulUtilFunctions.cpp b/libsolidity/codegen/YulUtilFunctions.cpp index 5a135acb7b4e..94c2cf8c6a15 100644 --- a/libsolidity/codegen/YulUtilFunctions.cpp +++ b/libsolidity/codegen/YulUtilFunctions.cpp @@ -216,6 +216,42 @@ std::string YulUtilFunctions::copyLiteralToStorageFunction(std::string const& _l }); } +std::string YulUtilFunctions::revertWithError( + std::string const& _signature, + std::vector const& _parameterTypes, + std::vector> const& _errorArguments, + std::string const& _posVar, + std::string const& _endVar +) +{ + solAssert((!_posVar.empty() && !_endVar.empty()) || (_posVar.empty() && _endVar.empty())); + bool const needsNewVariable = !_posVar.empty() && !_endVar.empty(); + + Whiskers templ(R"({ + let := () + mstore(, ) + let := (add(, 4) ) + revert(, sub(, )) + })"); + templ("pos", needsNewVariable ? _posVar : "memPtr"); + templ("end", needsNewVariable ? _endVar : "end"); + templ("hash", formatNumber(util::selectorFromSignatureU256(_signature))); + templ("allocateUnbounded", allocateUnboundedFunction()); + + std::vector errorArgumentVars; + std::vector errorArgumentTypes; + for (ASTPointer const& arg: _errorArguments) + { + errorArgumentVars += IRVariable(*arg).stackSlots(); + solAssert(arg->annotation().type); + errorArgumentTypes.push_back(arg->annotation().type); + } + templ("argumentVars", joinHumanReadablePrefixed(errorArgumentVars)); + templ("encode", ABIFunctions(m_evmVersion, m_revertStrings, m_functionCollector).tupleEncoder(errorArgumentTypes, _parameterTypes)); + + return templ.render(); +} + std::string YulUtilFunctions::requireOrAssertFunction(bool _assert, Type const* _messageType) { std::string functionName = @@ -273,57 +309,37 @@ std::string YulUtilFunctions::requireWithErrorFunction(FunctionCall const& error solAssert(errorDefinition); std::string const errorSignature = errorDefinition->functionType(true)->externalSignature(); - std::string const signatureHash = formatNumber(util::selectorFromSignatureU256(errorSignature)); - std::string const functionName = [&]() { - // Note that in most cases we'll always generate one function per error definition, - // because types in the constructor call will match the ones in the definition. The only - // exception are calls with types, where each instance has its own type (e.g. literals). - std::string name = "require_helper_t_error_" + std::to_string(errorDefinition->id()) + "_" + errorDefinition->name(); - for (ASTPointer const& argument: errorConstructorCall.sortedArguments()) - { - solAssert(argument->annotation().type); - name += ("_" + argument->annotation().type->identifier()); - } - return name; - }(); + // Note that in most cases we'll always generate one function per error definition, + // because types in the constructor call will match the ones in the definition. The only + // exception are calls with types, where each instance has its own type (e.g. literals). + std::string functionName = "require_helper_t_error_" + std::to_string(errorDefinition->id()) + "_" + errorDefinition->name(); + for (ASTPointer const& argument: errorConstructorCall.sortedArguments()) + { + solAssert(argument->annotation().type); + functionName += ("_" + argument->annotation().type->identifier()); + } - auto errorArgumentVarsAndTypes = [&]() -> std::tuple, std::vector> { - std::vector errorArgumentVars; - std::vector errorArgumentTypes; - for (ASTPointer const& arg: errorConstructorCall.sortedArguments()) - { - solAssert(arg->annotation().type); - if (arg->annotation().type->sizeOnStack() > 0) - errorArgumentVars += IRVariable(*arg).stackSlots(); - errorArgumentTypes.push_back(arg->annotation().type); - } - return std::make_tuple(std::move(errorArgumentVars), std::move(errorArgumentTypes)); - }(); + std::vector functionParameterNames; + for (ASTPointer const& arg: errorConstructorCall.sortedArguments()) + { + solAssert(arg->annotation().type); + if (arg->annotation().type->sizeOnStack() > 0) + functionParameterNames += IRVariable(*arg).stackSlots(); + } return m_functionCollector.createFunction(functionName, [&]() { - auto [errorArgumentVars, errorArgumentTypes] = errorArgumentVarsAndTypes; - std::string const encodeFunc = ABIFunctions(m_evmVersion, m_revertStrings, m_functionCollector) - .tupleEncoder( - errorArgumentTypes, - errorDefinition->functionType(true)->parameterTypes() - ); - return Whiskers(R"( - function (condition ) { - if iszero(condition) { - let memPtr := () - mstore(memPtr, ) - let end := (add(memPtr, ) ) - revert(memPtr, sub(end, memPtr)) - } + function (condition ) { + if iszero(condition) + } )") ("functionName", functionName) - ("allocateUnbounded", allocateUnboundedFunction()) - ("errorHash", signatureHash) - ("abiEncodeFunc", encodeFunc) - ("hashHeaderSize", std::to_string(4)) - ("errorArguments", joinHumanReadablePrefixed(errorArgumentVars)) + ("functionParameterNames", joinHumanReadablePrefixed(functionParameterNames)) + // We're creating parameter names from the expressions passed into the constructor call, + // which will result in odd names like `expr_29` that would normally be used for locals. + // Note that this is the naming expected by `revertWithError()`. + ("revertWithError", revertWithError(errorSignature, errorDefinition->functionType(true)->parameterTypes(), errorConstructorCall.sortedArguments())) .render(); }); } diff --git a/libsolidity/codegen/YulUtilFunctions.h b/libsolidity/codegen/YulUtilFunctions.h index db4c26725ddd..58d20dcbf4a2 100644 --- a/libsolidity/codegen/YulUtilFunctions.h +++ b/libsolidity/codegen/YulUtilFunctions.h @@ -90,6 +90,18 @@ class YulUtilFunctions /// signature: (slot) -> std::string copyLiteralToStorageFunction(std::string const& _literal); + /// @returns statements to revert with an error. + /// Generates code to revert with an error. The error arguments are assumed to + /// be already evaluated and available in local IRVariables, but not yet + /// converted. + std::string revertWithError( + std::string const& _signature, + std::vector const& _parameterTypes, + std::vector> const& _errorArguments, + std::string const& _posVar = {}, + std::string const& _endVar = {} + ); + // @returns the name of a function that has the equivalent logic of an // `assert` or `require` call. std::string requireOrAssertFunction(bool _assert, Type const* _messageType = nullptr); diff --git a/libsolidity/codegen/ir/IRGeneratorForStatements.cpp b/libsolidity/codegen/ir/IRGeneratorForStatements.cpp index bf028fce510f..bffd4de68253 100644 --- a/libsolidity/codegen/ir/IRGeneratorForStatements.cpp +++ b/libsolidity/codegen/ir/IRGeneratorForStatements.cpp @@ -3389,32 +3389,15 @@ void IRGeneratorForStatements::revertWithError( std::vector> const& _errorArguments ) { - Whiskers templ(R"({ - let := () - mstore(, ) - let := (add(, 4) ) - revert(, sub(, )) - })"); - templ("pos", m_context.newYulVariable()); - templ("end", m_context.newYulVariable()); - templ("hash", util::selectorFromSignatureU256(_signature).str()); - templ("allocateUnbounded", m_utils.allocateUnboundedFunction()); - - std::vector errorArgumentVars; - std::vector errorArgumentTypes; - for (ASTPointer const& arg: _errorArguments) - { - errorArgumentVars += IRVariable(*arg).stackSlots(); - solAssert(arg->annotation().type); - errorArgumentTypes.push_back(arg->annotation().type); - } - templ("argumentVars", joinHumanReadablePrefixed(errorArgumentVars)); - templ("encode", m_context.abiFunctions().tupleEncoder(errorArgumentTypes, _parameterTypes)); - - appendCode() << templ.render(); + appendCode() << m_utils.revertWithError( + _signature, + _parameterTypes, + _errorArguments, + m_context.newYulVariable(), + m_context.newYulVariable() + ); } - bool IRGeneratorForStatements::visit(TryCatchClause const& _clause) { _clause.block().accept(*this); diff --git a/test/cmdlineTests/require_with_error_ir/output b/test/cmdlineTests/require_with_error_ir/output index dacc9fc91032..232f0d76fce9 100644 --- a/test/cmdlineTests/require_with_error_ir/output +++ b/test/cmdlineTests/require_with_error_ir/output @@ -184,7 +184,8 @@ object "C_36" { } function require_helper_t_error_7_CustomError_t_rational_1_by_1_t_stringliteral_332c39dcd398ea34a48b871898d589f55fc4c7bce00562fb670c972e7e1b0720(condition , expr_15) { - if iszero(condition) { + if iszero(condition) + { let memPtr := allocate_unbounded() mstore(memPtr, 0x97ea5a2f00000000000000000000000000000000000000000000000000000000) let end := abi_encode_tuple_t_rational_1_by_1_t_stringliteral_332c39dcd398ea34a48b871898d589f55fc4c7bce00562fb670c972e7e1b0720__to_t_uint256_t_string_memory_ptr__fromStack(add(memPtr, 4) , expr_15) @@ -238,7 +239,8 @@ object "C_36" { } function require_helper_t_error_7_CustomError_t_rational_2_by_1_t_stringliteral_89027a4db8d1d3a0787296eb1553fba0dc506f981f9697f1a66994c458d392b5(condition , expr_29) { - if iszero(condition) { + if iszero(condition) + { let memPtr := allocate_unbounded() mstore(memPtr, 0x97ea5a2f00000000000000000000000000000000000000000000000000000000) let end := abi_encode_tuple_t_rational_2_by_1_t_stringliteral_89027a4db8d1d3a0787296eb1553fba0dc506f981f9697f1a66994c458d392b5__to_t_uint256_t_string_memory_ptr__fromStack(add(memPtr, 4) , expr_29) From ceabc540b65cfff875407d04c179122fd7e02096 Mon Sep 17 00:00:00 2001 From: Nikola Matic Date: Fri, 26 Apr 2024 07:01:18 +0200 Subject: [PATCH 0173/1022] Fix mistake in require condition in docs --- docs/contracts/errors.rst | 2 +- docs/introduction-to-smart-contracts.rst | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/contracts/errors.rst b/docs/contracts/errors.rst index e4955ddae1fd..8c57586e96f8 100644 --- a/docs/contracts/errors.rst +++ b/docs/contracts/errors.rst @@ -40,7 +40,7 @@ as well as the newer approach with ``require`` in function ``transferWithRequire balance[to] += amount; } function transferWithRequireError(address to, uint256 amount) public { - require(amount > balance[msg.sender], InsufficientBalance(balance[msg.sender], amount)); + require(amount <= balance[msg.sender], InsufficientBalance(balance[msg.sender], amount)); balance[msg.sender] -= amount; balance[to] += amount; } diff --git a/docs/introduction-to-smart-contracts.rst b/docs/introduction-to-smart-contracts.rst index 1c5b8737326e..c8600579457f 100644 --- a/docs/introduction-to-smart-contracts.rst +++ b/docs/introduction-to-smart-contracts.rst @@ -119,7 +119,7 @@ registering with a username and password, all you need is an Ethereum keypair. // Sends an amount of existing coins // from any caller to an address function send(address receiver, uint amount) public { - require(amount > balances[msg.sender], InsufficientBalance(amount, balances[msg.sender])); + require(amount <= balances[msg.sender], InsufficientBalance(amount, balances[msg.sender])); balances[msg.sender] -= amount; balances[receiver] += amount; emit Sent(msg.sender, receiver, amount); From 351a910b6d8d5642b16428ecde78461c800d5072 Mon Sep 17 00:00:00 2001 From: r0qs Date: Fri, 26 Apr 2024 14:17:41 +0200 Subject: [PATCH 0174/1022] Install python dependencies on buildpack-deps images --- scripts/docker/buildpack-deps/Dockerfile.emscripten | 5 +++-- .../buildpack-deps/Dockerfile.ubuntu.clang.ossfuzz | 11 ++++++----- scripts/docker/buildpack-deps/Dockerfile.ubuntu2004 | 7 ++++--- scripts/docker/buildpack-deps/Dockerfile.ubuntu2204 | 7 ++++--- .../docker/buildpack-deps/Dockerfile.ubuntu2204.clang | 8 +++++--- 5 files changed, 22 insertions(+), 16 deletions(-) diff --git a/scripts/docker/buildpack-deps/Dockerfile.emscripten b/scripts/docker/buildpack-deps/Dockerfile.emscripten index c29fc699ac01..f72909a2461b 100644 --- a/scripts/docker/buildpack-deps/Dockerfile.emscripten +++ b/scripts/docker/buildpack-deps/Dockerfile.emscripten @@ -33,13 +33,14 @@ # Using $(em-config CACHE)/sysroot/usr seems to work, though, and still has cmake find the # dependencies automatically. FROM emscripten/emsdk:3.1.19 AS base -LABEL version="16" +LABEL version="17" ADD emscripten.jam /usr/src RUN set -ex && \ \ apt-get update && \ - apt-get install lz4 sudo --no-install-recommends && \ + apt-get install lz4 sudo lsof python3 python3-pip --no-install-recommends && \ + pip3 install requests && \ \ cd /usr/src && \ git clone https://github.com/Z3Prover/z3.git -b z3-4.12.1 --depth 1 && \ diff --git a/scripts/docker/buildpack-deps/Dockerfile.ubuntu.clang.ossfuzz b/scripts/docker/buildpack-deps/Dockerfile.ubuntu.clang.ossfuzz index 0b2a99b1a299..2775c5c4d118 100644 --- a/scripts/docker/buildpack-deps/Dockerfile.ubuntu.clang.ossfuzz +++ b/scripts/docker/buildpack-deps/Dockerfile.ubuntu.clang.ossfuzz @@ -22,19 +22,20 @@ # (c) 2016-2021 solidity contributors. #------------------------------------------------------------------------------ FROM gcr.io/oss-fuzz-base/base-clang:latest as base -LABEL version="5" +LABEL version="6" ARG DEBIAN_FRONTEND=noninteractive RUN apt-get update; \ apt-get -qqy install --no-install-recommends \ automake libtool bison texinfo \ - build-essential sudo \ + build-essential sudo lsof \ software-properties-common \ - ninja-build git wget \ - libbz2-dev zlib1g-dev git curl uuid-dev \ + ninja-build git wget python3-pip \ + libbz2-dev zlib1g-dev curl uuid-dev \ pkg-config openjdk-8-jdk liblzma-dev unzip mlton m4 jq; \ - apt-get install -qy python3-pip; + pip3 install codecov parsec tabulate pylint z3-solver \ + pygments-lexer-solidity deepdiff colorama requests; # Install cmake 3.21.2 (minimum requirement is cmake 3.10) RUN wget https://github.com/Kitware/CMake/releases/download/v3.21.2/cmake-3.21.2-Linux-x86_64.sh; \ diff --git a/scripts/docker/buildpack-deps/Dockerfile.ubuntu2004 b/scripts/docker/buildpack-deps/Dockerfile.ubuntu2004 index 45490291a9c6..c2d038ee0adb 100644 --- a/scripts/docker/buildpack-deps/Dockerfile.ubuntu2004 +++ b/scripts/docker/buildpack-deps/Dockerfile.ubuntu2004 @@ -22,7 +22,7 @@ # (c) 2016-2019 solidity contributors. #------------------------------------------------------------------------------ FROM buildpack-deps:focal AS base -LABEL version="22" +LABEL version="23" ARG DEBIAN_FRONTEND=noninteractive @@ -34,13 +34,14 @@ RUN set -ex; \ apt-get install -qqy --no-install-recommends \ build-essential sudo \ software-properties-common \ - cmake ninja-build \ + cmake ninja-build lsof \ libboost-filesystem-dev libboost-test-dev libboost-system-dev \ libboost-program-options-dev \ libcvc4-dev libz3-static-dev z3-static jq \ ; \ apt-get install -qy python3-pip python3-sphinx; \ - pip3 install codecov; + pip3 install codecov parsec tabulate pylint z3-solver \ + pygments-lexer-solidity deepdiff colorama requests; # Eldarica RUN set -ex; \ diff --git a/scripts/docker/buildpack-deps/Dockerfile.ubuntu2204 b/scripts/docker/buildpack-deps/Dockerfile.ubuntu2204 index d7b92544863c..957940914a2e 100644 --- a/scripts/docker/buildpack-deps/Dockerfile.ubuntu2204 +++ b/scripts/docker/buildpack-deps/Dockerfile.ubuntu2204 @@ -22,7 +22,7 @@ # (c) 2016-2019 solidity contributors. #------------------------------------------------------------------------------ FROM buildpack-deps:jammy AS base -LABEL version="7" +LABEL version="8" ARG DEBIAN_FRONTEND=noninteractive @@ -34,13 +34,14 @@ RUN set -ex; \ apt-get install -qqy --no-install-recommends \ build-essential sudo \ software-properties-common \ - cmake ninja-build \ + cmake ninja-build lsof \ libboost-filesystem-dev libboost-test-dev libboost-system-dev \ libboost-program-options-dev \ libcvc4-dev libz3-static-dev z3-static jq \ libcln-dev zip locales-all; \ apt-get install -qy python3-pip python3-sphinx; \ - pip3 install codecov; + pip3 install codecov parsec tabulate pylint z3-solver \ + pygments-lexer-solidity deepdiff colorama requests; # Eldarica RUN set -ex; \ diff --git a/scripts/docker/buildpack-deps/Dockerfile.ubuntu2204.clang b/scripts/docker/buildpack-deps/Dockerfile.ubuntu2204.clang index 60d5a599c32e..b26ce3ff5f6c 100644 --- a/scripts/docker/buildpack-deps/Dockerfile.ubuntu2204.clang +++ b/scripts/docker/buildpack-deps/Dockerfile.ubuntu2204.clang @@ -22,7 +22,7 @@ # (c) 2016-2019 solidity contributors. #------------------------------------------------------------------------------ FROM buildpack-deps:jammy AS base -LABEL version="6" +LABEL version="7" ARG DEBIAN_FRONTEND=noninteractive @@ -34,12 +34,14 @@ RUN set -ex; \ apt-get install -qqy --no-install-recommends \ build-essential sudo \ software-properties-common \ - cmake ninja-build \ + cmake ninja-build lsof \ libboost-filesystem-dev libboost-test-dev libboost-system-dev \ libboost-program-options-dev \ clang \ libz3-static-dev z3-static jq \ - libcln-dev; + libcln-dev python3-pip; \ + pip3 install codecov parsec tabulate pylint z3-solver \ + pygments-lexer-solidity deepdiff colorama requests; # Eldarica RUN set -ex; \ From c5bfea2268fa70168f39be634c11b5b5b25876c9 Mon Sep 17 00:00:00 2001 From: Nikola Matic Date: Fri, 26 Apr 2024 10:49:30 +0200 Subject: [PATCH 0175/1022] Refactor requireOrAssert to use revertWithError --- libsolidity/codegen/YulUtilFunctions.cpp | 33 +- libsolidity/codegen/YulUtilFunctions.h | 6 +- .../codegen/ir/IRGeneratorForStatements.cpp | 4 +- .../require_with_error_ir/input.sol | 9 +- test/cmdlineTests/require_with_string_ir/args | 1 + .../require_with_string_ir/input.sol | 13 + .../require_with_string_ir/output | 290 ++++++++++++++++++ 7 files changed, 324 insertions(+), 32 deletions(-) create mode 100644 test/cmdlineTests/require_with_string_ir/args create mode 100644 test/cmdlineTests/require_with_string_ir/input.sol create mode 100644 test/cmdlineTests/require_with_string_ir/output diff --git a/libsolidity/codegen/YulUtilFunctions.cpp b/libsolidity/codegen/YulUtilFunctions.cpp index 94c2cf8c6a15..b71dfd566a75 100644 --- a/libsolidity/codegen/YulUtilFunctions.cpp +++ b/libsolidity/codegen/YulUtilFunctions.cpp @@ -252,7 +252,7 @@ std::string YulUtilFunctions::revertWithError( return templ.render(); } -std::string YulUtilFunctions::requireOrAssertFunction(bool _assert, Type const* _messageType) +std::string YulUtilFunctions::requireOrAssertFunction(bool _assert, Type const* _messageType, ASTPointer _stringArgumentExpression) { std::string functionName = std::string(_assert ? "assert_helper" : "require_helper") + @@ -271,34 +271,19 @@ std::string YulUtilFunctions::requireOrAssertFunction(bool _assert, Type const* ("functionName", functionName) .render(); - int const hashHeaderSize = 4; - u256 const errorHash = util::selectorFromSignatureU256("Error(string)"); - - std::string const encodeFunc = ABIFunctions(m_evmVersion, m_revertStrings, m_functionCollector) - .tupleEncoder( - {_messageType}, - {TypeProvider::stringMemory()} - ); + solAssert(_stringArgumentExpression, "Require with string must have a string argument"); + solAssert(_stringArgumentExpression->annotation().type); + std::vector functionParameterNames = IRVariable(*_stringArgumentExpression).stackSlots(); return Whiskers(R"( - function (condition ) { - if iszero(condition) { - let memPtr := () - mstore(memPtr, ) - let end := (add(memPtr, ) ) - revert(memPtr, sub(end, memPtr)) - } + function (condition ) { + if iszero(condition) + } )") ("functionName", functionName) - ("allocateUnbounded", allocateUnboundedFunction()) - ("errorHash", formatNumber(errorHash)) - ("abiEncodeFunc", encodeFunc) - ("hashHeaderSize", std::to_string(hashHeaderSize)) - ("messageVars", - (_messageType->sizeOnStack() > 0 ? ", " : "") + - suffixedVariableNameList("message_", 1, 1 + _messageType->sizeOnStack()) - ) + ("revertWithError", revertWithError("Error(string)", {_messageType}, {_stringArgumentExpression})) + ("functionParameterNames", joinHumanReadablePrefixed(functionParameterNames)) .render(); }); } diff --git a/libsolidity/codegen/YulUtilFunctions.h b/libsolidity/codegen/YulUtilFunctions.h index 58d20dcbf4a2..a1b45b656f13 100644 --- a/libsolidity/codegen/YulUtilFunctions.h +++ b/libsolidity/codegen/YulUtilFunctions.h @@ -104,7 +104,11 @@ class YulUtilFunctions // @returns the name of a function that has the equivalent logic of an // `assert` or `require` call. - std::string requireOrAssertFunction(bool _assert, Type const* _messageType = nullptr); + std::string requireOrAssertFunction( + bool _assert, + Type const* _messageType = nullptr, + ASTPointer _stringArgumentExpression = nullptr + ); // @returns function that has equivalent logic of a require function, but with a custom // error constructor parameter. diff --git a/libsolidity/codegen/ir/IRGeneratorForStatements.cpp b/libsolidity/codegen/ir/IRGeneratorForStatements.cpp index bffd4de68253..2464fefc434b 100644 --- a/libsolidity/codegen/ir/IRGeneratorForStatements.cpp +++ b/libsolidity/codegen/ir/IRGeneratorForStatements.cpp @@ -1166,9 +1166,11 @@ void IRGeneratorForStatements::endVisit(FunctionCall const& _functionCall) } else { + ASTPointer stringArgumentExpression = messageArgumentType ? arguments[1] : nullptr; std::string requireOrAssertFunction = m_utils.requireOrAssertFunction( functionType->kind() == FunctionType::Kind::Assert, - messageArgumentType + messageArgumentType, + stringArgumentExpression ); appendCode() << std::move(requireOrAssertFunction) << "(" << IRVariable(*arguments[0]).name(); if (messageArgumentType && messageArgumentType->sizeOnStack() > 0) diff --git a/test/cmdlineTests/require_with_error_ir/input.sol b/test/cmdlineTests/require_with_error_ir/input.sol index f041b27b7ddf..eb0787fcc16d 100644 --- a/test/cmdlineTests/require_with_error_ir/input.sol +++ b/test/cmdlineTests/require_with_error_ir/input.sol @@ -3,15 +3,12 @@ pragma solidity >=0.0; error CustomError(uint256, string); -contract C -{ - function f(bool condition) external pure - { +contract C { + function f(bool condition) external pure { require(condition, CustomError(1, "two")); } - function g(bool condition) external pure - { + function g(bool condition) external pure { require(condition, CustomError(2, "three")); } } diff --git a/test/cmdlineTests/require_with_string_ir/args b/test/cmdlineTests/require_with_string_ir/args new file mode 100644 index 000000000000..be08aefb416b --- /dev/null +++ b/test/cmdlineTests/require_with_string_ir/args @@ -0,0 +1 @@ +--ir --debug-info none diff --git a/test/cmdlineTests/require_with_string_ir/input.sol b/test/cmdlineTests/require_with_string_ir/input.sol new file mode 100644 index 000000000000..c47045171405 --- /dev/null +++ b/test/cmdlineTests/require_with_string_ir/input.sol @@ -0,0 +1,13 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity >=0.0; + +contract C { + function f(bool condition) external pure { + string memory message = "Condition must be satisfied"; + require(condition, message); + } + + function g(bool condition) external pure { + require(condition, "Condition must be satisfied"); + } +} diff --git a/test/cmdlineTests/require_with_string_ir/output b/test/cmdlineTests/require_with_string_ir/output new file mode 100644 index 000000000000..21828ac2a5ec --- /dev/null +++ b/test/cmdlineTests/require_with_string_ir/output @@ -0,0 +1,290 @@ +IR: + +/// @use-src 0:"require_with_string_ir/input.sol" +object "C_28" { + code { + + mstore(64, memoryguard(128)) + if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } + + constructor_C_28() + + let _1 := allocate_unbounded() + codecopy(_1, dataoffset("C_28_deployed"), datasize("C_28_deployed")) + + return(_1, datasize("C_28_deployed")) + + function allocate_unbounded() -> memPtr { + memPtr := mload(64) + } + + function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() { + revert(0, 0) + } + + function constructor_C_28() { + + } + + } + /// @use-src 0:"require_with_string_ir/input.sol" + object "C_28_deployed" { + code { + + mstore(64, memoryguard(128)) + + if iszero(lt(calldatasize(), 4)) + { + let selector := shift_right_224_unsigned(calldataload(0)) + switch selector + + case 0x98c3a6c1 + { + // f(bool) + + external_fun_f_16() + } + + case 0xd48092f7 + { + // g(bool) + + external_fun_g_27() + } + + default {} + } + + revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() + + function shift_right_224_unsigned(value) -> newValue { + newValue := + + shr(224, value) + + } + + function allocate_unbounded() -> memPtr { + memPtr := mload(64) + } + + function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() { + revert(0, 0) + } + + function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() { + revert(0, 0) + } + + function revert_error_c1322bf8034eace5e0b5c7295db60986aa89aae5e0ea0873e4689e076861a5db() { + revert(0, 0) + } + + function cleanup_t_bool(value) -> cleaned { + cleaned := iszero(iszero(value)) + } + + function validator_revert_t_bool(value) { + if iszero(eq(value, cleanup_t_bool(value))) { revert(0, 0) } + } + + function abi_decode_t_bool(offset, end) -> value { + value := calldataload(offset) + validator_revert_t_bool(value) + } + + function abi_decode_tuple_t_bool(headStart, dataEnd) -> value0 { + if slt(sub(dataEnd, headStart), 32) { revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() } + + { + + let offset := 0 + + value0 := abi_decode_t_bool(add(headStart, offset), dataEnd) + } + + } + + function abi_encode_tuple__to__fromStack(headStart ) -> tail { + tail := add(headStart, 0) + + } + + function external_fun_f_16() { + + if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } + let param_0 := abi_decode_tuple_t_bool(4, calldatasize()) + fun_f_16(param_0) + let memPos := allocate_unbounded() + let memEnd := abi_encode_tuple__to__fromStack(memPos ) + return(memPos, sub(memEnd, memPos)) + + } + + function external_fun_g_27() { + + if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } + let param_0 := abi_decode_tuple_t_bool(4, calldatasize()) + fun_g_27(param_0) + let memPos := allocate_unbounded() + let memEnd := abi_encode_tuple__to__fromStack(memPos ) + return(memPos, sub(memEnd, memPos)) + + } + + function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() { + revert(0, 0) + } + + function round_up_to_mul_of_32(value) -> result { + result := and(add(value, 31), not(31)) + } + + function panic_error_0x41() { + mstore(0, 35408467139433450592217433187231851964531694900788300625387963629091585785856) + mstore(4, 0x41) + revert(0, 0x24) + } + + function finalize_allocation(memPtr, size) { + let newFreePtr := add(memPtr, round_up_to_mul_of_32(size)) + // protect against overflow + if or(gt(newFreePtr, 0xffffffffffffffff), lt(newFreePtr, memPtr)) { panic_error_0x41() } + mstore(64, newFreePtr) + } + + function allocate_memory(size) -> memPtr { + memPtr := allocate_unbounded() + finalize_allocation(memPtr, size) + } + + function array_allocation_size_t_string_memory_ptr(length) -> size { + // Make sure we can allocate memory without overflow + if gt(length, 0xffffffffffffffff) { panic_error_0x41() } + + size := round_up_to_mul_of_32(length) + + // add length slot + size := add(size, 0x20) + + } + + function allocate_memory_array_t_string_memory_ptr(length) -> memPtr { + let allocSize := array_allocation_size_t_string_memory_ptr(length) + memPtr := allocate_memory(allocSize) + + mstore(memPtr, length) + + } + + function store_literal_in_memory_b25d43cff48de8365ad132c5f45b74f4593f9e69e5b749d86685f77282c88e46(memPtr) { + + mstore(add(memPtr, 0), "Condition must be satisfied") + + } + + function copy_literal_to_memory_b25d43cff48de8365ad132c5f45b74f4593f9e69e5b749d86685f77282c88e46() -> memPtr { + memPtr := allocate_memory_array_t_string_memory_ptr(27) + store_literal_in_memory_b25d43cff48de8365ad132c5f45b74f4593f9e69e5b749d86685f77282c88e46(add(memPtr, 32)) + } + + function convert_t_stringliteral_b25d43cff48de8365ad132c5f45b74f4593f9e69e5b749d86685f77282c88e46_to_t_string_memory_ptr() -> converted { + converted := copy_literal_to_memory_b25d43cff48de8365ad132c5f45b74f4593f9e69e5b749d86685f77282c88e46() + } + + function array_length_t_string_memory_ptr(value) -> length { + + length := mload(value) + + } + + function array_storeLengthForEncoding_t_string_memory_ptr_fromStack(pos, length) -> updated_pos { + mstore(pos, length) + updated_pos := add(pos, 0x20) + } + + function copy_memory_to_memory_with_cleanup(src, dst, length) { + + mcopy(dst, src, length) + mstore(add(dst, length), 0) + + } + + function abi_encode_t_string_memory_ptr_to_t_string_memory_ptr_fromStack(value, pos) -> end { + let length := array_length_t_string_memory_ptr(value) + pos := array_storeLengthForEncoding_t_string_memory_ptr_fromStack(pos, length) + copy_memory_to_memory_with_cleanup(add(value, 0x20), pos, length) + end := add(pos, round_up_to_mul_of_32(length)) + } + + function abi_encode_tuple_t_string_memory_ptr__to_t_string_memory_ptr__fromStack(headStart , value0) -> tail { + tail := add(headStart, 32) + + mstore(add(headStart, 0), sub(tail, headStart)) + tail := abi_encode_t_string_memory_ptr_to_t_string_memory_ptr_fromStack(value0, tail) + + } + + function require_helper_t_string_memory_ptr(condition , expr_12_mpos) { + if iszero(condition) + { + let memPtr := allocate_unbounded() + mstore(memPtr, 0x08c379a000000000000000000000000000000000000000000000000000000000) + let end := abi_encode_tuple_t_string_memory_ptr__to_t_string_memory_ptr__fromStack(add(memPtr, 4) , expr_12_mpos) + revert(memPtr, sub(end, memPtr)) + } + } + + function fun_f_16(var_condition_3) { + + let var_message_7_mpos := convert_t_stringliteral_b25d43cff48de8365ad132c5f45b74f4593f9e69e5b749d86685f77282c88e46_to_t_string_memory_ptr() + + let _1 := var_condition_3 + let expr_11 := _1 + + let _2_mpos := var_message_7_mpos + let expr_12_mpos := _2_mpos + + require_helper_t_string_memory_ptr(expr_11, expr_12_mpos) + + } + + function abi_encode_t_stringliteral_b25d43cff48de8365ad132c5f45b74f4593f9e69e5b749d86685f77282c88e46_to_t_string_memory_ptr_fromStack(pos) -> end { + pos := array_storeLengthForEncoding_t_string_memory_ptr_fromStack(pos, 27) + store_literal_in_memory_b25d43cff48de8365ad132c5f45b74f4593f9e69e5b749d86685f77282c88e46(pos) + end := add(pos, 32) + } + + function abi_encode_tuple_t_stringliteral_b25d43cff48de8365ad132c5f45b74f4593f9e69e5b749d86685f77282c88e46__to_t_string_memory_ptr__fromStack(headStart ) -> tail { + tail := add(headStart, 32) + + mstore(add(headStart, 0), sub(tail, headStart)) + tail := abi_encode_t_stringliteral_b25d43cff48de8365ad132c5f45b74f4593f9e69e5b749d86685f77282c88e46_to_t_string_memory_ptr_fromStack( tail) + + } + + function require_helper_t_stringliteral_b25d43cff48de8365ad132c5f45b74f4593f9e69e5b749d86685f77282c88e46(condition ) { + if iszero(condition) + { + let memPtr := allocate_unbounded() + mstore(memPtr, 0x08c379a000000000000000000000000000000000000000000000000000000000) + let end := abi_encode_tuple_t_stringliteral_b25d43cff48de8365ad132c5f45b74f4593f9e69e5b749d86685f77282c88e46__to_t_string_memory_ptr__fromStack(add(memPtr, 4) ) + revert(memPtr, sub(end, memPtr)) + } + } + + function fun_g_27(var_condition_18) { + + let _3 := var_condition_18 + let expr_22 := _3 + + require_helper_t_stringliteral_b25d43cff48de8365ad132c5f45b74f4593f9e69e5b749d86685f77282c88e46(expr_22) + + } + + } + + data ".metadata" hex"" + } + +} From 700ba0b9b36d65280192a1b5d012c4ae34131276 Mon Sep 17 00:00:00 2001 From: r0qs Date: Fri, 26 Apr 2024 17:04:29 +0200 Subject: [PATCH 0176/1022] Sort packages in alphabetical order and split commands by line --- .../buildpack-deps/Dockerfile.emscripten | 8 +++- .../Dockerfile.ubuntu.clang.ossfuzz | 39 ++++++++++++++---- .../buildpack-deps/Dockerfile.ubuntu2004 | 38 ++++++++++++----- .../buildpack-deps/Dockerfile.ubuntu2204 | 41 ++++++++++++++----- .../Dockerfile.ubuntu2204.clang | 38 ++++++++++++----- 5 files changed, 125 insertions(+), 39 deletions(-) diff --git a/scripts/docker/buildpack-deps/Dockerfile.emscripten b/scripts/docker/buildpack-deps/Dockerfile.emscripten index f72909a2461b..961901f00b70 100644 --- a/scripts/docker/buildpack-deps/Dockerfile.emscripten +++ b/scripts/docker/buildpack-deps/Dockerfile.emscripten @@ -37,9 +37,13 @@ LABEL version="17" ADD emscripten.jam /usr/src RUN set -ex && \ - \ apt-get update && \ - apt-get install lz4 sudo lsof python3 python3-pip --no-install-recommends && \ + apt-get install -qqy --no-install-recommends \ + lsof \ + lz4 \ + python3 \ + python3-pip \ + sudo && \ pip3 install requests && \ \ cd /usr/src && \ diff --git a/scripts/docker/buildpack-deps/Dockerfile.ubuntu.clang.ossfuzz b/scripts/docker/buildpack-deps/Dockerfile.ubuntu.clang.ossfuzz index 2775c5c4d118..94b6c247c62e 100644 --- a/scripts/docker/buildpack-deps/Dockerfile.ubuntu.clang.ossfuzz +++ b/scripts/docker/buildpack-deps/Dockerfile.ubuntu.clang.ossfuzz @@ -28,14 +28,39 @@ ARG DEBIAN_FRONTEND=noninteractive RUN apt-get update; \ apt-get -qqy install --no-install-recommends \ - automake libtool bison texinfo \ - build-essential sudo lsof \ + automake \ + bison \ + build-essential \ + curl \ + git \ + jq \ + libbz2-dev \ + liblzma-dev \ + libtool \ + lsof \ + m4 \ + mlton \ + ninja-build \ + openjdk-8-jdk \ + pkg-config \ + python3-pip \ software-properties-common \ - ninja-build git wget python3-pip \ - libbz2-dev zlib1g-dev curl uuid-dev \ - pkg-config openjdk-8-jdk liblzma-dev unzip mlton m4 jq; \ - pip3 install codecov parsec tabulate pylint z3-solver \ - pygments-lexer-solidity deepdiff colorama requests; + sudo \ + texinfo \ + unzip \ + uuid-dev \ + wget \ + zlib1g-dev; \ + pip3 install \ + codecov \ + colorama \ + deepdiff \ + parsec \ + pygments-lexer-solidity \ + pylint \ + requests \ + tabulate \ + z3-solver; # Install cmake 3.21.2 (minimum requirement is cmake 3.10) RUN wget https://github.com/Kitware/CMake/releases/download/v3.21.2/cmake-3.21.2-Linux-x86_64.sh; \ diff --git a/scripts/docker/buildpack-deps/Dockerfile.ubuntu2004 b/scripts/docker/buildpack-deps/Dockerfile.ubuntu2004 index c2d038ee0adb..4b5dbafac591 100644 --- a/scripts/docker/buildpack-deps/Dockerfile.ubuntu2004 +++ b/scripts/docker/buildpack-deps/Dockerfile.ubuntu2004 @@ -32,21 +32,39 @@ RUN set -ex; \ apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 1c52189c923f6ca9 ; \ apt-get update; \ apt-get install -qqy --no-install-recommends \ - build-essential sudo \ - software-properties-common \ - cmake ninja-build lsof \ - libboost-filesystem-dev libboost-test-dev libboost-system-dev \ + build-essential \ + cmake \ + jq \ + libboost-filesystem-dev \ libboost-program-options-dev \ - libcvc4-dev libz3-static-dev z3-static jq \ - ; \ - apt-get install -qy python3-pip python3-sphinx; \ - pip3 install codecov parsec tabulate pylint z3-solver \ - pygments-lexer-solidity deepdiff colorama requests; + libboost-system-dev \ + libboost-test-dev \ + libcvc4-dev \ + libz3-static-dev \ + lsof \ + ninja-build \ + python3-pip \ + python3-sphinx \ + software-properties-common \ + sudo \ + z3-static; \ + pip3 install \ + codecov \ + colorama \ + deepdiff \ + parsec \ + pygments-lexer-solidity \ + pylint \ + requests \ + tabulate \ + z3-solver; # Eldarica RUN set -ex; \ apt-get update; \ - apt-get install -qy unzip openjdk-11-jre; \ + apt-get install -qqy \ + openjdk-11-jre \ + unzip; \ eldarica_version="2.1"; \ wget "https://github.com/uuverifiers/eldarica/releases/download/v${eldarica_version}/eldarica-bin-${eldarica_version}.zip" -O /opt/eld_binaries.zip; \ test "$(sha256sum /opt/eld_binaries.zip)" = "0ac43f45c0925383c9d2077f62bbb515fd792375f3b2b101b30c9e81dcd7785c /opt/eld_binaries.zip"; \ diff --git a/scripts/docker/buildpack-deps/Dockerfile.ubuntu2204 b/scripts/docker/buildpack-deps/Dockerfile.ubuntu2204 index 957940914a2e..92cc20d43ae8 100644 --- a/scripts/docker/buildpack-deps/Dockerfile.ubuntu2204 +++ b/scripts/docker/buildpack-deps/Dockerfile.ubuntu2204 @@ -32,21 +32,42 @@ RUN set -ex; \ apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 1c52189c923f6ca9 ; \ apt-get update; \ apt-get install -qqy --no-install-recommends \ - build-essential sudo \ - software-properties-common \ - cmake ninja-build lsof \ - libboost-filesystem-dev libboost-test-dev libboost-system-dev \ + build-essential \ + cmake \ + jq \ + libboost-filesystem-dev \ libboost-program-options-dev \ - libcvc4-dev libz3-static-dev z3-static jq \ - libcln-dev zip locales-all; \ - apt-get install -qy python3-pip python3-sphinx; \ - pip3 install codecov parsec tabulate pylint z3-solver \ - pygments-lexer-solidity deepdiff colorama requests; + libboost-system-dev \ + libboost-test-dev \ + libcln-dev \ + libcvc4-dev \ + libz3-static-dev \ + locales-all \ + lsof \ + ninja-build \ + python3-pip \ + python3-sphinx \ + software-properties-common \ + sudo \ + z3-static \ + zip; \ + pip3 install \ + codecov \ + colorama \ + deepdiff \ + parsec \ + pygments-lexer-solidity \ + pylint \ + requests \ + tabulate \ + z3-solver; # Eldarica RUN set -ex; \ apt-get update; \ - apt-get install -qy unzip openjdk-11-jre; \ + apt-get install -qqy \ + openjdk-11-jre \ + unzip; \ eldarica_version="2.1"; \ wget "https://github.com/uuverifiers/eldarica/releases/download/v${eldarica_version}/eldarica-bin-${eldarica_version}.zip" -O /opt/eld_binaries.zip; \ test "$(sha256sum /opt/eld_binaries.zip)" = "0ac43f45c0925383c9d2077f62bbb515fd792375f3b2b101b30c9e81dcd7785c /opt/eld_binaries.zip"; \ diff --git a/scripts/docker/buildpack-deps/Dockerfile.ubuntu2204.clang b/scripts/docker/buildpack-deps/Dockerfile.ubuntu2204.clang index b26ce3ff5f6c..b11f798e81ac 100644 --- a/scripts/docker/buildpack-deps/Dockerfile.ubuntu2204.clang +++ b/scripts/docker/buildpack-deps/Dockerfile.ubuntu2204.clang @@ -32,21 +32,39 @@ RUN set -ex; \ apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 1c52189c923f6ca9 ; \ apt-get update; \ apt-get install -qqy --no-install-recommends \ - build-essential sudo \ - software-properties-common \ - cmake ninja-build lsof \ - libboost-filesystem-dev libboost-test-dev libboost-system-dev \ - libboost-program-options-dev \ + build-essential \ clang \ - libz3-static-dev z3-static jq \ - libcln-dev python3-pip; \ - pip3 install codecov parsec tabulate pylint z3-solver \ - pygments-lexer-solidity deepdiff colorama requests; + cmake \ + jq \ + lsof \ + libboost-filesystem-dev \ + libboost-program-options-dev \ + libboost-system-dev \ + libboost-test-dev \ + libcln-dev \ + libz3-static-dev \ + ninja-build \ + python3-pip \ + software-properties-common \ + sudo \ + z3-static; \ + pip3 install \ + codecov \ + colorama \ + deepdiff \ + parsec \ + pygments-lexer-solidity \ + pylint \ + requests \ + tabulate \ + z3-solver; # Eldarica RUN set -ex; \ apt-get update; \ - apt-get install -qy unzip openjdk-11-jre; \ + apt-get install -qy \ + openjdk-11-jre \ + unzip; \ eldarica_version="2.1"; \ wget "https://github.com/uuverifiers/eldarica/releases/download/v${eldarica_version}/eldarica-bin-${eldarica_version}.zip" -O /opt/eld_binaries.zip; \ test "$(sha256sum /opt/eld_binaries.zip)" = "0ac43f45c0925383c9d2077f62bbb515fd792375f3b2b101b30c9e81dcd7785c /opt/eld_binaries.zip"; \ From 9cbd0a1046f4665a830dd402dee69585bba4a214 Mon Sep 17 00:00:00 2001 From: r0qs Date: Fri, 26 Apr 2024 17:06:32 +0200 Subject: [PATCH 0177/1022] Remove superfluous cleanup step --- scripts/docker/buildpack-deps/Dockerfile.ubuntu.clang.ossfuzz | 4 ---- scripts/docker/buildpack-deps/Dockerfile.ubuntu2004 | 4 ---- scripts/docker/buildpack-deps/Dockerfile.ubuntu2204 | 4 ---- scripts/docker/buildpack-deps/Dockerfile.ubuntu2204.clang | 4 ---- 4 files changed, 16 deletions(-) diff --git a/scripts/docker/buildpack-deps/Dockerfile.ubuntu.clang.ossfuzz b/scripts/docker/buildpack-deps/Dockerfile.ubuntu.clang.ossfuzz index 94b6c247c62e..f8a4c73ce9b1 100644 --- a/scripts/docker/buildpack-deps/Dockerfile.ubuntu.clang.ossfuzz +++ b/scripts/docker/buildpack-deps/Dockerfile.ubuntu.clang.ossfuzz @@ -173,10 +173,6 @@ RUN set -ex; \ cp abicoder.hpp /usr/include; \ rm -rf /usr/src/Yul-Isabelle -# Cleanup -RUN set -ex; \ - rm -rf /var/lib/apt/lists/* - FROM base COPY --from=libraries /usr/lib /usr/lib COPY --from=libraries /usr/bin /usr/bin diff --git a/scripts/docker/buildpack-deps/Dockerfile.ubuntu2004 b/scripts/docker/buildpack-deps/Dockerfile.ubuntu2004 index 4b5dbafac591..815c93ee84b5 100644 --- a/scripts/docker/buildpack-deps/Dockerfile.ubuntu2004 +++ b/scripts/docker/buildpack-deps/Dockerfile.ubuntu2004 @@ -71,10 +71,6 @@ RUN set -ex; \ unzip /opt/eld_binaries.zip -d /opt; \ rm -f /opt/eld_binaries.zip; -# Cleanup -RUN set -ex; \ - rm -rf /var/lib/apt/lists/* - FROM base AS libraries # EVMONE diff --git a/scripts/docker/buildpack-deps/Dockerfile.ubuntu2204 b/scripts/docker/buildpack-deps/Dockerfile.ubuntu2204 index 92cc20d43ae8..254e83b4cfc7 100644 --- a/scripts/docker/buildpack-deps/Dockerfile.ubuntu2204 +++ b/scripts/docker/buildpack-deps/Dockerfile.ubuntu2204 @@ -74,10 +74,6 @@ RUN set -ex; \ unzip /opt/eld_binaries.zip -d /opt; \ rm -f /opt/eld_binaries.zip; -# Cleanup -RUN set -ex; \ - rm -rf /var/lib/apt/lists/* - FROM base AS libraries # EVMONE diff --git a/scripts/docker/buildpack-deps/Dockerfile.ubuntu2204.clang b/scripts/docker/buildpack-deps/Dockerfile.ubuntu2204.clang index b11f798e81ac..af6155b6e0a0 100644 --- a/scripts/docker/buildpack-deps/Dockerfile.ubuntu2204.clang +++ b/scripts/docker/buildpack-deps/Dockerfile.ubuntu2204.clang @@ -71,10 +71,6 @@ RUN set -ex; \ unzip /opt/eld_binaries.zip -d /opt; \ rm -f /opt/eld_binaries.zip; -# Cleanup -RUN set -ex; \ - rm -rf /var/lib/apt/lists/* - FROM base AS libraries ENV CC clang From 9b89c30c06fa20854737a5fee86cc7d3847d7095 Mon Sep 17 00:00:00 2001 From: r0qs Date: Fri, 26 Apr 2024 14:38:21 +0200 Subject: [PATCH 0178/1022] Move python dependencies to docker images Co-authored-by: Tim-Tscheppe --- .circleci/config.yml | 31 ++----------------------------- 1 file changed, 2 insertions(+), 29 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 8b588740fec4..9ca938b9b8bc 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -331,9 +331,6 @@ commands: - checkout - attach_workspace: at: build - - run: - name: Install dependencies - command: pip install --user deepdiff colorama - run: name: Executing solc LSP test suite command: test/lsp.py build/solc/solc --non-interactive @@ -925,19 +922,9 @@ jobs: - matrix_notify_failure_unless_pr chk_pylint: - <<: *base_cimg_small + <<: *base_ubuntu2204_small steps: - checkout - - install_python3: - packages: > - pylint - z3-solver - pygments-lexer-solidity - parsec - tabulate - deepdiff - colorama - requests - run: pylint --version - run: name: Linting Python Scripts @@ -974,11 +961,9 @@ jobs: - matrix_notify_failure_unless_pr chk_proofs: - <<: *base_cimg_small + <<: *base_ubuntu2204_small steps: - checkout - - install_python3: - packages: z3-solver - run_proofs - matrix_notify_failure_unless_pr @@ -993,10 +978,6 @@ jobs: <<: *base_ubuntu2204_small steps: - checkout - - run: - # TODO: Add these to the base image - name: Install gas_diff_stats.py dependencies - command: python3 -m pip install --user parsec tabulate - run: name: Python unit tests command: python3 test/pyscriptTests.py @@ -1508,14 +1489,6 @@ jobs: if command -v npm &> /dev/null; then sudo npm install -g pnpm fi - - install_python3: - packages: requests - - run: - name: Install lsof - command: | - # lsof is used by Colony in its stop-blockchain-client.sh script - sudo apt update - sudo apt-get --quiet --assume-yes --no-install-recommends install lsof - when: condition: << parameters.python2 >> steps: From 21dbf834117aec2a8751a7b5abffb640a1cf9336 Mon Sep 17 00:00:00 2001 From: r0qs Date: Fri, 26 Apr 2024 17:59:01 +0200 Subject: [PATCH 0179/1022] Bump CI docker images --- .circleci/config.yml | 22 +++++++++++----------- scripts/build_emscripten.sh | 4 ++-- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 9ca938b9b8bc..b5b151c58a84 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -9,25 +9,25 @@ version: 2.1 parameters: ubuntu-2004-docker-image: type: string - # solbuildpackpusher/solidity-buildpack-deps:ubuntu2004-22 - default: "solbuildpackpusher/solidity-buildpack-deps@sha256:212b4d79a89c6e2d9b58ddea2d6296c5618f4ae0b016694a3b159d2b11cbbacc" + # solbuildpackpusher/solidity-buildpack-deps:ubuntu2004-23 + default: "solbuildpackpusher/solidity-buildpack-deps@sha256:84a1fb8771236e8d9aa5c615a425b8929e56a6e4f150a60078c8d74a1ceaa6c2" ubuntu-2204-docker-image: type: string - # solbuildpackpusher/solidity-buildpack-deps:ubuntu2204-7 - default: "solbuildpackpusher/solidity-buildpack-deps@sha256:ecbeec36b12fd953bfb6fb3e7ced474bb73945d7ed615e6538960c32bae8126c" + # solbuildpackpusher/solidity-buildpack-deps:ubuntu2204-8 + default: "solbuildpackpusher/solidity-buildpack-deps@sha256:1c3a4118218640b2bf632242979a63d48f3d9c70d48be9574332f2dbbd04b192" ubuntu-2204-clang-docker-image: type: string - # solbuildpackpusher/solidity-buildpack-deps:ubuntu2204.clang-6 - default: "solbuildpackpusher/solidity-buildpack-deps@sha256:1818a56061f39ece4a92138948404214bf939c9deb68f4dc2c68cd82b39e8410" + # solbuildpackpusher/solidity-buildpack-deps:ubuntu2204.clang-7 + default: "solbuildpackpusher/solidity-buildpack-deps@sha256:0f47e733e100080c4174381c262cfcf974bc8e7c3c41b8dff611b9641c82f714" ubuntu-clang-ossfuzz-docker-image: type: string - # solbuildpackpusher/solidity-buildpack-deps:ubuntu.clang.ossfuzz-5 - default: "solbuildpackpusher/solidity-buildpack-deps@sha256:c21c4c2a591d0702c388d1944539f6498ed8e51c54c1a1cb34693079efd9ab77" + # solbuildpackpusher/solidity-buildpack-deps:ubuntu.clang.ossfuzz-6 + default: "solbuildpackpusher/solidity-buildpack-deps@sha256:8883fa2845bbc1e0922af60439313666e4ba325f67a117e17d78cca3ea6589b3" emscripten-docker-image: type: string - # NOTE: Please remember to update the `build_emscripten.sh` whenever the hash of this image changes. - # solbuildpackpusher/solidity-buildpack-deps:emscripten-16 - default: "solbuildpackpusher/solidity-buildpack-deps@sha256:19fcb5ac029bbc27ec36e10f7d14ea224d8010145f9690562ef084fd16146b0c" + # NOTE: Please remember to update the `scripts/build_emscripten.sh` whenever the hash of this image changes. + # solbuildpackpusher/solidity-buildpack-deps:emscripten-17 + default: "solbuildpackpusher/solidity-buildpack-deps@sha256:c57f2bfb8c15d70fe290629358dd1c73dc126e3760f443b54764797556b887d4" evm-version: type: string default: london diff --git a/scripts/build_emscripten.sh b/scripts/build_emscripten.sh index 1b780a4276b6..dc862b1f7efc 100755 --- a/scripts/build_emscripten.sh +++ b/scripts/build_emscripten.sh @@ -33,9 +33,9 @@ if (( $# != 0 )); then params="$(printf "%q " "${@}")" fi -# solbuildpackpusher/solidity-buildpack-deps:emscripten-16 +# solbuildpackpusher/solidity-buildpack-deps:emscripten-17 # NOTE: Without `safe.directory` git would assume it's not safe to operate on /root/project since it's owned by a different user. # See https://github.blog/2022-04-12-git-security-vulnerability-announced/ docker run -v "$(pwd):/root/project" -w /root/project \ - solbuildpackpusher/solidity-buildpack-deps@sha256:19fcb5ac029bbc27ec36e10f7d14ea224d8010145f9690562ef084fd16146b0c \ + solbuildpackpusher/solidity-buildpack-deps@sha256:c57f2bfb8c15d70fe290629358dd1c73dc126e3760f443b54764797556b887d4 \ /bin/bash -c "git config --global --add safe.directory /root/project && ./scripts/ci/build_emscripten.sh ${params}" From 61ced0d9745233dbdb50a3603ceb3be1ddc4cac2 Mon Sep 17 00:00:00 2001 From: Patrick Collins <54278053+PatrickAlphaC@users.noreply.github.com> Date: Sat, 27 Apr 2024 13:39:23 -0400 Subject: [PATCH 0180/1022] Update cheatsheet.rst The documentation currently says: ```` ``abi.encodeCall(function functionPointer, (...)) returns (bytes memory)``: ABI-encodes a call to ``functionPointer`` with the arguments found in the tuple. Performs a full type-check, ensuring the types match the function signature. Result equals ``abi.encodeWithSelector(functionPointer.selector, (...))`` ```` However, this is not correct. `abi.encodeWithSelector` does not take a tuple as a second argument, instead, it takes an unended list of arguments. Saying these two are identical, is then not correct: - `abi.encodeCall(function functionPointer, (...)) ` - `abi.encodeWithSelector(functionPointer.selector, (...))` It should be that these two are identical: - `abi.encodeCall(function functionPointer, (...)) ` - `abi.encodeWithSelector(functionPointer.selector, ...)` subtle, but maybe there is a clearly way to say that `encodeWithSelector` is the same as the unpacked tuple from `encodeCall`. --- docs/cheatsheet.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/cheatsheet.rst b/docs/cheatsheet.rst index bc678c647d54..6b69b81be34a 100644 --- a/docs/cheatsheet.rst +++ b/docs/cheatsheet.rst @@ -23,7 +23,7 @@ ABI Encoding and Decoding Functions - ``abi.encodeWithSelector(bytes4 selector, ...) returns (bytes memory)``: :ref:`ABI `-encodes the given arguments starting from the second and prepends the given four-byte selector - ``abi.encodeCall(function functionPointer, (...)) returns (bytes memory)``: ABI-encodes a call to ``functionPointer`` with the arguments found in the - tuple. Performs a full type-check, ensuring the types match the function signature. Result equals ``abi.encodeWithSelector(functionPointer.selector, (...))`` + tuple. Performs a full type-check, ensuring the types match the function signature. Result equals ``abi.encodeWithSelector(functionPointer.selector, ...)`` - ``abi.encodeWithSignature(string memory signature, ...) returns (bytes memory)``: Equivalent to ``abi.encodeWithSelector(bytes4(keccak256(bytes(signature))), ...)`` From 2f5f6b9fb8e888a52c2f6042609df628824a1c96 Mon Sep 17 00:00:00 2001 From: r0qs Date: Mon, 29 Apr 2024 17:50:07 +0200 Subject: [PATCH 0181/1022] Replace yarn with pnpm in the external tests since yarn seems to be unable to resolve Hardhat dependencies --- test/externalTests/brink.sh | 4 ++-- test/externalTests/ens.sh | 2 +- test/externalTests/uniswap.sh | 8 ++++---- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/test/externalTests/brink.sh b/test/externalTests/brink.sh index d8ad001ac014..02e5fe971c65 100755 --- a/test/externalTests/brink.sh +++ b/test/externalTests/brink.sh @@ -68,8 +68,8 @@ function brink_test neutralize_package_json_hooks force_hardhat_compiler_binary "$config_file" "$BINARY_TYPE" "$BINARY_PATH" force_hardhat_compiler_settings "$config_file" "$(first_word "$SELECTED_PRESETS")" "$config_var" "$CURRENT_EVM_VERSION" "$extra_settings" "$extra_optimizer_settings" - yarn install - yarn add hardhat-gas-reporter + pnpm install + pnpm install hardhat-gas-reporter replace_version_pragmas for preset in $SELECTED_PRESETS; do diff --git a/test/externalTests/ens.sh b/test/externalTests/ens.sh index a011dd2a720c..b7a053f6f7bf 100755 --- a/test/externalTests/ens.sh +++ b/test/externalTests/ens.sh @@ -62,7 +62,7 @@ function ens_test neutralize_package_json_hooks force_hardhat_compiler_binary "$config_file" "$BINARY_TYPE" "$BINARY_PATH" force_hardhat_compiler_settings "$config_file" "$(first_word "$SELECTED_PRESETS")" - yarn install + pnpm install replace_version_pragmas neutralize_packaged_contracts diff --git a/test/externalTests/uniswap.sh b/test/externalTests/uniswap.sh index 04f27ab3f77f..f3d78e6e3397 100755 --- a/test/externalTests/uniswap.sh +++ b/test/externalTests/uniswap.sh @@ -83,17 +83,17 @@ function uniswap_test # - Newer versions of ethereumjs/tx have an issue with 'gteHardfork()' method. neutralize_package_lock - yarn install - yarn add hardhat-gas-reporter + pnpm install + pnpm install hardhat-gas-reporter # With ethers.js 5.6.2 many tests for revert messages fail. # TODO: Remove when https://github.com/ethers-io/ethers.js/discussions/2849 is resolved. - yarn add ethers@5.6.1 + pnpm install ethers@5.6.1 # We set hardhat version to 2.20.0 since version 2.21.0 has issues with solidity-coverage plugin # that often causes out-of-memory errors. # See hardhat note about the issue here: https://github.com/NomicFoundation/hardhat/releases/tag/hardhat@2.21.0 - yarn add hardhat@2.20.0 + pnpm install hardhat@2.20.0 replace_version_pragmas From 3794bc1825d51f5927b3d99305f3ea97232ec55b Mon Sep 17 00:00:00 2001 From: r0qs Date: Mon, 29 Apr 2024 17:47:21 +0200 Subject: [PATCH 0182/1022] Remove perpetual-pools external test --- .circleci/config.yml | 9 --- test/externalTests/perpetual-pools.sh | 87 --------------------------- 2 files changed, 96 deletions(-) delete mode 100755 test/externalTests/perpetual-pools.sh diff --git a/.circleci/config.yml b/.circleci/config.yml index b5b151c58a84..34e2e339333d 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -789,13 +789,6 @@ defaults: compile_only: 1 image: cimg/node:18.16 - - job_native_test_ext_perpetual_pools: &job_native_test_ext_perpetual_pools - <<: *requires_b_ubu_static - name: t_native_test_ext_perpetual_pools - project: perpetual-pools - binary_type: native - image: cimg/node:18.16 - - job_native_test_ext_uniswap: &job_native_test_ext_uniswap <<: *requires_b_ubu_static name: t_native_test_ext_uniswap @@ -1881,7 +1874,6 @@ workflows: - t_ext: *job_native_test_ext_zeppelin - t_ext: *job_native_test_ext_ens - t_ext: *job_native_test_ext_yield_liquidator - - t_ext: *job_native_test_ext_perpetual_pools - t_ext: *job_native_test_ext_uniswap - t_ext: *job_native_test_ext_prb_math - t_ext: *job_native_test_ext_elementfi @@ -1903,7 +1895,6 @@ workflows: - t_native_test_ext_zeppelin - t_native_test_ext_ens - t_native_test_ext_yield_liquidator - - t_native_test_ext_perpetual_pools - t_native_test_ext_uniswap - t_native_test_ext_elementfi - t_native_test_ext_brink diff --git a/test/externalTests/perpetual-pools.sh b/test/externalTests/perpetual-pools.sh deleted file mode 100755 index 1d7bb8f33b3e..000000000000 --- a/test/externalTests/perpetual-pools.sh +++ /dev/null @@ -1,87 +0,0 @@ -#!/usr/bin/env bash - -# ------------------------------------------------------------------------------ -# 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) 2022 solidity contributors. -#------------------------------------------------------------------------------ - -set -e - -source scripts/common.sh -source scripts/externalTests/common.sh - -REPO_ROOT=$(realpath "$(dirname "$0")/../..") - -verify_input "$@" -BINARY_TYPE="$1" -BINARY_PATH="$(realpath "$2")" -SELECTED_PRESETS="$3" - -function compile_fn { yarn build; } -function test_fn { yarn test; } - -function perpetual_pools_test -{ - local repo="https://github.com/solidity-external-tests/perpetual-pools-contracts" - local ref=pools-v2 - local config_file="hardhat.config.ts" - local config_var="config" - - local compile_only_presets=() - local settings_presets=( - "${compile_only_presets[@]}" - ir-no-optimize - ir-optimize-evm-only - ir-optimize-evm+yul - legacy-no-optimize - legacy-optimize-evm-only - legacy-optimize-evm+yul - ) - - [[ $SELECTED_PRESETS != "" ]] || SELECTED_PRESETS=$(circleci_select_steps_multiarg "${settings_presets[@]}") - print_presets_or_exit "$SELECTED_PRESETS" - - setup_solc "$DIR" "$BINARY_TYPE" "$BINARY_PATH" - download_project "$repo" "$ref" "$DIR" - - # Disable tests that won't pass on the ir presets due to Hardhat heuristics. Note that this also disables - # them for other presets but that's fine - we want same code run for benchmarks to be comparable. - # TODO: Remove this when Hardhat adjusts heuristics for IR (https://github.com/nomiclabs/hardhat/issues/3365). - sed -i 's|\(it\)\(("Should not allow commits that are too large"\)|\1.skip\2|g' test/PoolCommitter/commit.spec.ts - sed -i 's|\(it\)\(("Should not allow for too many commitments (that bring amount over a user'\''s balance)"\)|\1.skip\2|g' test/PoolCommitter/commit.spec.ts - - neutralize_package_lock - neutralize_package_json_hooks - force_hardhat_compiler_binary "$config_file" "$BINARY_TYPE" "$BINARY_PATH" - force_hardhat_compiler_settings "$config_file" "$(first_word "$SELECTED_PRESETS")" "$config_var" - force_hardhat_unlimited_contract_size "$config_file" "$config_var" - - yarn install - # We set hardhat version to 2.20.0 since version 2.21.0 has issues with solidity-coverage plugin - # that often causes out-of-memory errors. - # See hardhat note about the issue here: https://github.com/NomicFoundation/hardhat/releases/tag/hardhat@2.21.0 - yarn add hardhat@2.20.0 - - replace_version_pragmas - - for preset in $SELECTED_PRESETS; do - hardhat_run_test "$config_file" "$preset" "${compile_only_presets[*]}" compile_fn test_fn "$config_var" - store_benchmark_report hardhat perpetual-pools "$repo" "$preset" - done -} - -external_test Tracer-Perpetual-Pools perpetual_pools_test From 007205a27493e11e3a49943f51f0bc3b30e43a2a Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Tue, 30 Apr 2024 10:14:30 +0200 Subject: [PATCH 0183/1022] Order `Instructions.h` by opcodes TLOAD/TSTORE was out of order --- libevmasm/Instruction.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/libevmasm/Instruction.h b/libevmasm/Instruction.h index f89c72c8941e..a3629eec2db8 100644 --- a/libevmasm/Instruction.h +++ b/libevmasm/Instruction.h @@ -104,10 +104,9 @@ enum class Instruction: uint8_t MSIZE, ///< get the size of active memory GAS, ///< get the amount of available gas JUMPDEST, ///< set a potential jump destination - MCOPY = 0x5e, ///< copy between memory areas - TLOAD = 0x5c, ///< load word from transient storage TSTORE = 0x5d, ///< save word to transient storage + MCOPY = 0x5e, ///< copy between memory areas PUSH0 = 0x5f, ///< place the value 0 on stack PUSH1 = 0x60, ///< place 1 byte item on stack From 7fb62227cf53bd44199efe80165f369cb22a7498 Mon Sep 17 00:00:00 2001 From: Martin Blicha Date: Wed, 13 Mar 2024 14:12:25 +0100 Subject: [PATCH 0184/1022] SMTChecker: First version of SMTLIB2 parser Parser code was originally written by @chriseth for solsmt, an SMT solver developed internally for Solidity --- libsmtutil/CMakeLists.txt | 2 + libsmtutil/SMTLib2Parser.cpp | 97 ++++++++++++++++++++++++++++++++++++ libsmtutil/SMTLib2Parser.h | 96 +++++++++++++++++++++++++++++++++++ 3 files changed, 195 insertions(+) create mode 100644 libsmtutil/SMTLib2Parser.cpp create mode 100644 libsmtutil/SMTLib2Parser.h diff --git a/libsmtutil/CMakeLists.txt b/libsmtutil/CMakeLists.txt index af7f47b60c04..cb222e22c4a1 100644 --- a/libsmtutil/CMakeLists.txt +++ b/libsmtutil/CMakeLists.txt @@ -4,6 +4,8 @@ set(sources Exceptions.h SMTLib2Interface.cpp SMTLib2Interface.h + SMTLib2Parser.cpp + SMTLib2Parser.h SMTPortfolio.cpp SMTPortfolio.h SolverInterface.h diff --git a/libsmtutil/SMTLib2Parser.cpp b/libsmtutil/SMTLib2Parser.cpp new file mode 100644 index 000000000000..f3a3bd96a94c --- /dev/null +++ b/libsmtutil/SMTLib2Parser.cpp @@ -0,0 +1,97 @@ +/* + 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 solidity::langutil; +using namespace solidity::smtutil; + +std::string SMTLib2Expression::toString() const { + return std::visit(solidity::util::GenericVisitor{ + [](std::string const& _sv) { return _sv; }, + [](std::vector const& _subExpr) { + std::vector formatted; + for (auto const& item: _subExpr) + formatted.emplace_back(item.toString()); + return "(" + solidity::util::joinHumanReadable(formatted, " ") + ")"; + } + }, data); +} + +SMTLib2Expression SMTLib2Parser::parseExpression() { + skipWhitespace(); + if (token() == '(') + { + advance(); + skipWhitespace(); + std::vector subExpressions; + while (token() != 0 && token() != ')') + { + subExpressions.emplace_back(parseExpression()); + skipWhitespace(); + } + if (token() != ')') + throw ParsingException{}; + // Simulate whitespace because we do not want to read the next token since it might block. + m_token = ' '; + return {std::move(subExpressions)}; + } else + return {parseToken()}; +} + +std::string SMTLib2Parser::parseToken() { + std::string result; + + skipWhitespace(); + bool isPipe = token() == '|'; + if (isPipe) + advance(); + while (token() != 0) + { + char c = token(); + if (isPipe && c == '|') + { + advance(); + break; + } else if (!isPipe && (isWhiteSpace(c) || c == '(' || c == ')')) + break; + result.push_back(c); + advance(); + } + return result; +} + +void SMTLib2Parser::advance() { + if (!m_input.good()) + throw ParsingException{}; + m_token = static_cast(m_input.get()); + if (token() == ';') + while (token() != '\n' && token() != 0) + m_token = static_cast(m_input.get()); +} + +void SMTLib2Parser::skipWhitespace() { + while (isWhiteSpace(token())) + advance(); +} diff --git a/libsmtutil/SMTLib2Parser.h b/libsmtutil/SMTLib2Parser.h new file mode 100644 index 000000000000..48eb76a1374e --- /dev/null +++ b/libsmtutil/SMTLib2Parser.h @@ -0,0 +1,96 @@ +/* + This file is part of solidity. + + solidity is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + solidity is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with solidity. If not, see . +*/ +// SPDX-License-Identifier: GPL-3.0 + +#pragma once + +#include + +#include +#include +#include +#include + +/** + * The following is a parser for SMT-LIB2 expressions developed originally by @chriseth as part of solsmt. + */ + +namespace solidity::smtutil +{ + +struct SMTLib2Expression { + using args_t = std::vector; + std::variant data; + + [[nodiscard]] std::string toString() const; +}; + +inline bool isAtom(SMTLib2Expression const& expr) +{ + return std::holds_alternative(expr.data); +} + +inline std::string const& asAtom(SMTLib2Expression const& expr) +{ + smtAssert(isAtom(expr)); + return std::get(expr.data); +} + +inline auto const& asSubExpressions(SMTLib2Expression const& expr) +{ + smtAssert(!isAtom(expr)); + return std::get(expr.data); +} + +inline auto& asSubExpressions(SMTLib2Expression& expr) +{ + smtAssert(!isAtom(expr)); + return std::get(expr.data); +} + +class SMTLib2Parser { +public: + class ParsingException {}; + + explicit SMTLib2Parser(std::istream& _input) : + m_input(_input), + m_token(static_cast(m_input.get())) {} + + SMTLib2Expression parseExpression(); + + bool isEOF() + { + skipWhitespace(); + return m_input.eof(); + } + +private: + std::string parseToken(); + + void skipWhitespace(); + + [[nodiscard]] char token() const + { + return m_token; + } + + void advance(); + + std::istream& m_input; + char m_token = 0; +}; +} From eb118198169796ea3c5b40999a72d7513942da3e Mon Sep 17 00:00:00 2001 From: Martin Blicha Date: Wed, 13 Mar 2024 19:37:46 +0100 Subject: [PATCH 0185/1022] SMTChecker: Instruct Eldarica to produce invariants if requested --- libsolidity/interface/CompilerStack.cpp | 2 +- libsolidity/interface/SMTSolverCommand.cpp | 4 +++- libsolidity/interface/SMTSolverCommand.h | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/libsolidity/interface/CompilerStack.cpp b/libsolidity/interface/CompilerStack.cpp index 514f3a554755..2d1fd10743a3 100644 --- a/libsolidity/interface/CompilerStack.cpp +++ b/libsolidity/interface/CompilerStack.cpp @@ -659,7 +659,7 @@ bool CompilerStack::analyzeLegacy(bool _noErrorsSoFar) m_modelCheckerSettings.solvers = ModelChecker::checkRequestedSolvers(m_modelCheckerSettings.solvers, m_errorReporter); if (auto* universalCallback = m_readFile.target()) if (m_modelCheckerSettings.solvers.eld) - universalCallback->smtCommand().setEldarica(m_modelCheckerSettings.timeout); + universalCallback->smtCommand().setEldarica(m_modelCheckerSettings.timeout, m_modelCheckerSettings.invariants != ModelCheckerInvariants::None()); } ModelChecker modelChecker(m_errorReporter, *this, m_smtlib2Responses, m_modelCheckerSettings, m_readFile); diff --git a/libsolidity/interface/SMTSolverCommand.cpp b/libsolidity/interface/SMTSolverCommand.cpp index 8ef36cb75189..7d814cd9c3c4 100644 --- a/libsolidity/interface/SMTSolverCommand.cpp +++ b/libsolidity/interface/SMTSolverCommand.cpp @@ -37,7 +37,7 @@ using solidity::util::errinfo_comment; namespace solidity::frontend { -void SMTSolverCommand::setEldarica(std::optional timeoutInMilliseconds) +void SMTSolverCommand::setEldarica(std::optional timeoutInMilliseconds, bool computeInvariants) { m_arguments.clear(); m_solverCmd = "eld"; @@ -47,6 +47,8 @@ void SMTSolverCommand::setEldarica(std::optional timeoutInMillisec timeoutInSeconds = timeoutInSeconds == 0 ? 1 : timeoutInSeconds; m_arguments.push_back("-t:" + std::to_string(timeoutInSeconds)); } + if (computeInvariants) + m_arguments.emplace_back("-ssol"); } ReadCallback::Result SMTSolverCommand::solve(std::string const& _kind, std::string const& _query) diff --git a/libsolidity/interface/SMTSolverCommand.h b/libsolidity/interface/SMTSolverCommand.h index 1d1201e49062..665c19c1b767 100644 --- a/libsolidity/interface/SMTSolverCommand.h +++ b/libsolidity/interface/SMTSolverCommand.h @@ -36,7 +36,7 @@ class SMTSolverCommand return [this](std::string const& _kind, std::string const& _query) { return solve(_kind, _query); }; } - void setEldarica(std::optional timeoutInMilliseconds); + void setEldarica(std::optional timeoutInMilliseconds, bool computeInvariants); private: /// The name of the solver's binary. From 1fcaec5ddce3dc45fd62867a21cd9d97b7ff4db9 Mon Sep 17 00:00:00 2001 From: Martin Blicha Date: Tue, 16 Apr 2024 13:24:19 +0200 Subject: [PATCH 0186/1022] SMTChecker: Remember sorts already in SMTLibInterface --- libsmtutil/CHCSmtLib2Interface.cpp | 20 +++++++------------- libsmtutil/CHCSmtLib2Interface.h | 6 +++--- libsmtutil/SMTLib2Interface.cpp | 30 +++++++++++++++++++----------- libsmtutil/SMTLib2Interface.h | 9 ++++++++- 4 files changed, 37 insertions(+), 28 deletions(-) diff --git a/libsmtutil/CHCSmtLib2Interface.cpp b/libsmtutil/CHCSmtLib2Interface.cpp index ac906e301a96..7e643abac809 100644 --- a/libsmtutil/CHCSmtLib2Interface.cpp +++ b/libsmtutil/CHCSmtLib2Interface.cpp @@ -56,7 +56,7 @@ void CHCSmtLib2Interface::reset() m_accumulatedOutput.clear(); m_variables.clear(); m_unhandledQueries.clear(); - m_sortNames.clear(); + m_smtlib2->reset(); } void CHCSmtLib2Interface::registerRelation(Expression const& _expr) @@ -115,24 +115,18 @@ void CHCSmtLib2Interface::declareVariable(std::string const& _name, SortPointer else if (!m_variables.count(_name)) { m_variables.insert(_name); - write("(declare-var |" + _name + "| " + toSmtLibSort(*_sort) + ')'); + write("(declare-var |" + _name + "| " + toSmtLibSort(_sort) + ')'); } } -std::string CHCSmtLib2Interface::toSmtLibSort(Sort const& _sort) +std::string CHCSmtLib2Interface::toSmtLibSort(SortPointer _sort) { - if (!m_sortNames.count(&_sort)) - m_sortNames[&_sort] = m_smtlib2->toSmtLibSort(_sort); - return m_sortNames.at(&_sort); + return m_smtlib2->toSmtLibSort(_sort); } std::string CHCSmtLib2Interface::toSmtLibSort(std::vector const& _sorts) { - std::string ssort("("); - for (auto const& sort: _sorts) - ssort += toSmtLibSort(*sort) + " "; - ssort += ")"; - return ssort; + return m_smtlib2->toSmtLibSort(_sorts); } std::string CHCSmtLib2Interface::forall() @@ -142,7 +136,7 @@ std::string CHCSmtLib2Interface::forall() { solAssert(sort, ""); if (sort->kind != Kind::Function) - vars += " (" + name + " " + toSmtLibSort(*sort) + ")"; + vars += " (" + name + " " + toSmtLibSort(sort) + ")"; } vars += ")"; return vars; @@ -158,7 +152,7 @@ void CHCSmtLib2Interface::declareFunction(std::string const& _name, SortPointer auto fSort = std::dynamic_pointer_cast(_sort); smtAssert(fSort->codomain); std::string domain = toSmtLibSort(fSort->domain); - std::string codomain = toSmtLibSort(*fSort->codomain); + std::string codomain = toSmtLibSort(fSort->codomain); m_variables.insert(_name); write( "(declare-fun |" + diff --git a/libsmtutil/CHCSmtLib2Interface.h b/libsmtutil/CHCSmtLib2Interface.h index 0f3a68ee405d..b133c485e095 100644 --- a/libsmtutil/CHCSmtLib2Interface.h +++ b/libsmtutil/CHCSmtLib2Interface.h @@ -57,8 +57,10 @@ class CHCSmtLib2Interface: public CHCSolverInterface SMTLib2Interface* smtlib2Interface() const { return m_smtlib2.get(); } + auto const& sortNames() const { return m_smtlib2->sortNames(); } + private: - std::string toSmtLibSort(Sort const& _sort); + std::string toSmtLibSort(SortPointer _sort); std::string toSmtLibSort(std::vector const& _sort); void writeHeader(); @@ -85,8 +87,6 @@ class CHCSmtLib2Interface: public CHCSolverInterface frontend::ReadCallback::Callback m_smtCallback; SMTSolverChoice m_enabledSolvers; - - std::map m_sortNames; }; } diff --git a/libsmtutil/SMTLib2Interface.cpp b/libsmtutil/SMTLib2Interface.cpp index ac5645bf121b..12469a4ae05f 100644 --- a/libsmtutil/SMTLib2Interface.cpp +++ b/libsmtutil/SMTLib2Interface.cpp @@ -56,6 +56,7 @@ void SMTLib2Interface::reset() m_accumulatedOutput.emplace_back(); m_variables.clear(); m_userSorts.clear(); + m_sortNames.clear(); write("(set-option :produce-models true)"); if (m_queryTimeout) write("(set-option :timeout " + std::to_string(*m_queryTimeout) + ")"); @@ -81,7 +82,7 @@ void SMTLib2Interface::declareVariable(std::string const& _name, SortPointer con else if (!m_variables.count(_name)) { m_variables.emplace(_name, _sort); - write("(declare-fun |" + _name + "| () " + toSmtLibSort(*_sort) + ')'); + write("(declare-fun |" + _name + "| () " + toSmtLibSort(_sort) + ')'); } } @@ -94,7 +95,7 @@ void SMTLib2Interface::declareFunction(std::string const& _name, SortPointer con { auto const& fSort = std::dynamic_pointer_cast(_sort); std::string domain = toSmtLibSort(fSort->domain); - std::string codomain = toSmtLibSort(*fSort->codomain); + std::string codomain = toSmtLibSort(fSort->codomain); m_variables.emplace(_name, _sort); write( "(declare-fun |" + @@ -183,7 +184,7 @@ std::string SMTLib2Interface::toSExpr(Expression const& _expr) smtAssert(sortSort, ""); auto arraySort = std::dynamic_pointer_cast(sortSort->inner); smtAssert(arraySort, ""); - sexpr += "(as const " + toSmtLibSort(*arraySort) + ") "; + sexpr += "(as const " + toSmtLibSort(arraySort) + ") "; sexpr += toSExpr(_expr.arguments.at(1)); } else if (_expr.name == "tuple_get") @@ -212,25 +213,32 @@ std::string SMTLib2Interface::toSExpr(Expression const& _expr) return sexpr; } -std::string SMTLib2Interface::toSmtLibSort(Sort const& _sort) +std::string SMTLib2Interface::toSmtLibSort(solidity::smtutil::SortPointer _sort) { - switch (_sort.kind) + if (!m_sortNames.count(_sort)) + m_sortNames[_sort] = toSmtLibSortInternal(_sort); + return m_sortNames.at(_sort); +} + +std::string SMTLib2Interface::toSmtLibSortInternal(SortPointer _sort) +{ + switch (_sort->kind) { case Kind::Int: return "Int"; case Kind::Bool: return "Bool"; case Kind::BitVector: - return "(_ BitVec " + std::to_string(dynamic_cast(_sort).size) + ")"; + return "(_ BitVec " + std::to_string(dynamic_cast(*_sort).size) + ")"; case Kind::Array: { - auto const& arraySort = dynamic_cast(_sort); + auto const& arraySort = dynamic_cast(*_sort); smtAssert(arraySort.domain && arraySort.range, ""); - return "(Array " + toSmtLibSort(*arraySort.domain) + ' ' + toSmtLibSort(*arraySort.range) + ')'; + return "(Array " + toSmtLibSort(arraySort.domain) + ' ' + toSmtLibSort(arraySort.range) + ')'; } case Kind::Tuple: { - auto const& tupleSort = dynamic_cast(_sort); + auto const& tupleSort = dynamic_cast(*_sort); std::string tupleName = "|" + tupleSort.name + "|"; auto isName = [&](auto entry) { return entry.first == tupleName; }; if (ranges::find_if(m_userSorts, isName) == m_userSorts.end()) @@ -238,7 +246,7 @@ std::string SMTLib2Interface::toSmtLibSort(Sort const& _sort) std::string decl("(declare-datatypes ((" + tupleName + " 0)) (((" + tupleName); smtAssert(tupleSort.members.size() == tupleSort.components.size(), ""); for (unsigned i = 0; i < tupleSort.members.size(); ++i) - decl += " (|" + tupleSort.members.at(i) + "| " + toSmtLibSort(*tupleSort.components.at(i)) + ")"; + decl += " (|" + tupleSort.members.at(i) + "| " + toSmtLibSort(tupleSort.components.at(i)) + ")"; decl += "))))"; m_userSorts.emplace_back(tupleName, decl); write(decl); @@ -255,7 +263,7 @@ std::string SMTLib2Interface::toSmtLibSort(std::vector const& _sort { std::string ssort("("); for (auto const& sort: _sorts) - ssort += toSmtLibSort(*sort) + " "; + ssort += toSmtLibSort(sort) + " "; ssort += ")"; return ssort; } diff --git a/libsmtutil/SMTLib2Interface.h b/libsmtutil/SMTLib2Interface.h index 9ef8e94a8c0a..fbfde664d579 100644 --- a/libsmtutil/SMTLib2Interface.h +++ b/libsmtutil/SMTLib2Interface.h @@ -61,12 +61,13 @@ class SMTLib2Interface: public SolverInterface // Used by CHCSmtLib2Interface std::string toSExpr(Expression const& _expr); - std::string toSmtLibSort(Sort const& _sort); + std::string toSmtLibSort(SortPointer _sort); std::string toSmtLibSort(std::vector const& _sort); std::map variables() { return m_variables; } std::vector> const& userSorts() const { return m_userSorts; } + std::map const& sortNames() const { return m_sortNames; } std::string dumpQuery(std::vector const& _expressionsToEvaluate); @@ -81,6 +82,8 @@ class SMTLib2Interface: public SolverInterface /// Communicates with the solver via the callback. Throws SMTSolverError on error. std::string querySolver(std::string const& _input); + std::string toSmtLibSortInternal(SortPointer _sort); + std::vector m_accumulatedOutput; std::map m_variables; @@ -90,6 +93,10 @@ class SMTLib2Interface: public SolverInterface /// otherwise solvers cannot parse the queries. std::vector> m_userSorts; + /// Maps a user sort to SMT-LIB2 sort. + /// Remembers all declared sorts and is used as a cache as well. + std::map m_sortNames; + std::map m_queryResponses; std::vector m_unhandledQueries; From 384f005071afe0da2e209246ee74bc20ed2cdc89 Mon Sep 17 00:00:00 2001 From: Martin Blicha Date: Tue, 16 Apr 2024 13:52:22 +0200 Subject: [PATCH 0187/1022] SMTChecker: Support retrieving invariants from Eldarica We add support for parsing CHC solver response containing a model, i.e., invariants. We utilise our SMT parser to build S-expression representation which we then interpret using the context we remembered while building the query. We have to rememeber all predicates declared to the solver, and, consequently, all sorts we have declared to the solver. --- libsmtutil/CHCSmtLib2Interface.cpp | 284 ++++++++++++++++++++++++++++- libsmtutil/CHCSmtLib2Interface.h | 3 + 2 files changed, 286 insertions(+), 1 deletion(-) diff --git a/libsmtutil/CHCSmtLib2Interface.cpp b/libsmtutil/CHCSmtLib2Interface.cpp index 7e643abac809..671ec9b51d6c 100644 --- a/libsmtutil/CHCSmtLib2Interface.cpp +++ b/libsmtutil/CHCSmtLib2Interface.cpp @@ -18,11 +18,17 @@ #include +#include + #include +#include +#include #include #include +#include +#include #include #include @@ -96,7 +102,10 @@ std::tuple CHCSmtLib2Inte CheckResult result; // TODO proper parsing if (boost::starts_with(response, "sat")) - result = CheckResult::UNSATISFIABLE; + { + auto maybeInvariants = invariantsFromSolverResponse(response); + return {CheckResult::UNSATISFIABLE, maybeInvariants.value_or(Expression(true)), {}}; + } else if (boost::starts_with(response, "unsat")) result = CheckResult::SATISFIABLE; else if (boost::starts_with(response, "unknown")) @@ -217,3 +226,276 @@ std::string CHCSmtLib2Interface::createHeaderAndDeclarations() { std::string CHCSmtLib2Interface::createQueryAssertion(std::string name) { return "(assert\n(forall " + forall() + "\n" + "(=> " + name + " false)))"; } + +class SMTLibTranslationContext +{ + CHCSmtLib2Interface const& m_chcInterface; + std::map m_knownVariables; + + static bool isNumber(std::string const& _expr) + { + return ranges::all_of(_expr, [](char c) { return isDigit(c) || c == '.'; }); + } + + +public: + explicit SMTLibTranslationContext(CHCSmtLib2Interface const& _chcInterface) : m_chcInterface(_chcInterface) + { + // fill user defined sorts and constructors + auto const& userSorts = m_chcInterface.smtlib2Interface()->userSorts(); + for (auto const& declaration: userSorts | ranges::views::values) + { + std::stringstream ss(declaration); + SMTLib2Parser parser(ss); + auto expr = parser.parseExpression(); + smtAssert(parser.isEOF()); + smtAssert(!isAtom(expr)); + auto const& args = asSubExpressions(expr); + smtAssert(args.size() == 3); + smtAssert(isAtom(args[0]) && asAtom(args[0]) == "declare-datatypes"); + // args[1] is the name of the type + // args[2] is the constructor with the members + smtAssert(!isAtom(args[2]) && asSubExpressions(args[2]).size() == 1 && !isAtom(asSubExpressions(args[2])[0])); + auto const& constructors = asSubExpressions(asSubExpressions(args[2])[0]); + smtAssert(constructors.size() == 1); + auto const& constructor = constructors[0]; + // constructor is a list: name + members + smtAssert(!isAtom(constructor)); + auto const& constructorArgs = asSubExpressions(constructor); + for (unsigned i = 1u; i < constructorArgs.size(); ++i) + { + auto const& carg = constructorArgs[i]; + smtAssert(!isAtom(carg) && asSubExpressions(carg).size() == 2); + auto const& nameSortPair = asSubExpressions(carg); + m_knownVariables.emplace(asAtom(nameSortPair[0]), toSort(nameSortPair[1])); + } + } + } + + void addVariableDeclaration(std::string name, SortPointer sort) + { + smtAssert(m_knownVariables.find(name) == m_knownVariables.end()); + m_knownVariables.emplace(std::move(name), std::move(sort)); + } + + std::optional lookupKnownTupleSort(std::string const& name) { + auto const& userSorts = m_chcInterface.sortNames(); + std::string quotedName = "|" + name + "|"; + auto it = ranges::find_if(userSorts, [&](auto const& entry) { return entry.second == quotedName; }); + if (it != userSorts.end() && it->first->kind == Kind::Tuple) + { + auto tupleSort = std::dynamic_pointer_cast(it->first); + smtAssert(tupleSort); + return tupleSort; + } + return {}; + } + + SortPointer toSort(SMTLib2Expression const& expr) + { + if (isAtom(expr)) + { + auto const& name = asAtom(expr); + if (name == "Int") + return SortProvider::sintSort; + if (name == "Bool") + return SortProvider::boolSort; + auto tupleSort = lookupKnownTupleSort(name); + if (tupleSort) + return tupleSort.value(); + } else { + auto const& args = asSubExpressions(expr); + if (asAtom(args[0]) == "Array") + { + smtAssert(args.size() == 3); + auto domainSort = toSort(args[1]); + auto codomainSort = toSort(args[2]); + return std::make_shared(std::move(domainSort), std::move(codomainSort)); + } + if (args.size() == 3 && isAtom(args[0]) && asAtom(args[0]) == "_" && isAtom(args[1]) && asAtom(args[1]) == "int2bv") + return std::make_shared(std::stoul(asAtom(args[2]))); + } + smtAssert(false, "Unknown sort encountered"); + } + + smtutil::Expression parseQuantifier( + std::string const& quantifierName, + std::vector const& varList, + SMTLib2Expression const& coreExpression + ) + { + std::vector> boundVariables; + for (auto const& sortedVar: varList) + { + smtAssert(!isAtom(sortedVar)); + auto varSortPair = asSubExpressions(sortedVar); + smtAssert(varSortPair.size() == 2); + boundVariables.emplace_back(asAtom(varSortPair[0]), toSort(varSortPair[1])); + } + for (auto const& [var, sort] : boundVariables) + { + smtAssert(m_knownVariables.find(var) == m_knownVariables.end()); // TODO: deal with shadowing? + m_knownVariables.emplace(var, sort); + } + auto core = toSMTUtilExpression(coreExpression); + for (auto const& [var, sort] : boundVariables) + { + smtAssert(m_knownVariables.find(var) != m_knownVariables.end()); + m_knownVariables.erase(var); + } + return Expression(quantifierName, {core}, SortProvider::boolSort); // TODO: what about the bound variables? + + } + + smtutil::Expression toSMTUtilExpression(SMTLib2Expression const& _expr) + { + return std::visit( + GenericVisitor{ + [&](std::string const& _atom) + { + if (_atom == "true" || _atom == "false") + return smtutil::Expression(_atom == "true"); + else if (isNumber(_atom)) + return smtutil::Expression(_atom, {}, SortProvider::sintSort); + else if (auto it = m_knownVariables.find(_atom); it != m_knownVariables.end()) + return smtutil::Expression(_atom, {}, it->second); + else // assume this is a predicate with sort bool; TODO: Context should be aware of predicates! + return smtutil::Expression(_atom, {}, SortProvider::boolSort); + }, + [&](std::vector const& _subExpr) + { + SortPointer sort; + std::vector arguments; + if (isAtom(_subExpr.front())) + { + std::string const& op = asAtom(_subExpr.front()); + if (op == "!") + { + // named term, we ignore the name + smtAssert(_subExpr.size() > 2); + return toSMTUtilExpression(_subExpr[1]); + } + if (op == "exists" || op == "forall") + { + smtAssert(_subExpr.size() == 3); + smtAssert(!isAtom(_subExpr[1])); + return parseQuantifier(op, asSubExpressions(_subExpr[1]), _subExpr[2]); + } + for (size_t i = 1; i < _subExpr.size(); i++) + arguments.emplace_back(toSMTUtilExpression(_subExpr[i])); + if (auto tupleSort = lookupKnownTupleSort(op); tupleSort) + { + auto sortSort = std::make_shared(tupleSort.value()); + return Expression::tuple_constructor(Expression(sortSort), arguments); + } + if (auto it = m_knownVariables.find(op); it != m_knownVariables.end()) + return smtutil::Expression(op, std::move(arguments), it->second); + else + { + std::set + boolOperators{"and", "or", "not", "=", "<", ">", "<=", ">=", "=>"}; + sort = contains(boolOperators, op) ? SortProvider::boolSort : arguments.back().sort; + return smtutil::Expression(op, std::move(arguments), std::move(sort)); + } + smtAssert(false, "Unhandled case in expression conversion"); + } + else + { + // check for const array + if (_subExpr.size() == 2 and !isAtom(_subExpr[0])) + { + auto const& typeArgs = asSubExpressions(_subExpr.front()); + if (typeArgs.size() == 3 && typeArgs[0].toString() == "as" + && typeArgs[1].toString() == "const") + { + auto arraySort = toSort(typeArgs[2]); + auto sortSort = std::make_shared(arraySort); + return smtutil::Expression:: + const_array(Expression(sortSort), toSMTUtilExpression(_subExpr[1])); + } + if (typeArgs.size() == 3 && typeArgs[0].toString() == "_" + && typeArgs[1].toString() == "int2bv") + { + auto bvSort = std::dynamic_pointer_cast(toSort(_subExpr[0])); + smtAssert(bvSort); + return smtutil::Expression::int2bv(toSMTUtilExpression(_subExpr[1]), bvSort->size); + } + if (typeArgs.size() == 4 && typeArgs[0].toString() == "_" + && typeArgs[1].toString() == "extract") + return smtutil::Expression( + "extract", + {toSMTUtilExpression(typeArgs[2]), toSMTUtilExpression(typeArgs[3])}, + SortProvider::bitVectorSort // TODO: Compute bit size properly? + ); + } + smtAssert(false, "Unhandled case in expression conversion"); + } + } + }, + _expr.data + ); + } +}; + + +#define precondition(CONDITION) if (!(CONDITION)) return {} +std::optional CHCSmtLib2Interface::invariantsFromSolverResponse(std::string const& _response) const +{ + std::stringstream ss(_response); + std::string answer; + ss >> answer; + precondition(answer == "sat"); + SMTLib2Parser parser(ss); + precondition(!parser.isEOF()); // There has to be a model + std::vector parsedOutput; + try + { + while (!parser.isEOF()) + parsedOutput.push_back(parser.parseExpression()); + } + catch(SMTLib2Parser::ParsingException&) + { + return {}; + } + smtAssert(parser.isEOF()); + precondition(!parsedOutput.empty()); + auto& commands = parsedOutput.size() == 1 ? asSubExpressions(parsedOutput[0]) : parsedOutput; + std::vector definitions; + for (auto& command: commands) + { + auto& args = asSubExpressions(command); + precondition(args.size() == 5); + // args[0] = "define-fun" + // args[1] = predicate name + // args[2] = formal arguments of the predicate + // args[3] = return sort + // args[4] = body of the predicate's interpretation + precondition(isAtom(args[0]) && asAtom(args[0]) == "define-fun"); + precondition(isAtom(args[1])); + precondition(!isAtom(args[2])); + precondition(isAtom(args[3]) && asAtom(args[3]) == "Bool"); + auto& interpretation = args[4]; +// inlineLetExpressions(interpretation); + SMTLibTranslationContext context(*this); + auto const& formalArguments = asSubExpressions(args[2]); + std::vector predicateArgs; + for (auto const& formalArgument: formalArguments) + { + precondition(!isAtom(formalArgument)); + auto const& nameSortPair = asSubExpressions(formalArgument); + precondition(nameSortPair.size() == 2); + precondition(isAtom(nameSortPair[0])); + SortPointer varSort = context.toSort(nameSortPair[1]); + context.addVariableDeclaration(asAtom(nameSortPair[0]), varSort); + Expression arg = context.toSMTUtilExpression(nameSortPair[0]); + predicateArgs.push_back(arg); + } + + auto parsedInterpretation = context.toSMTUtilExpression(interpretation); + + Expression predicate(asAtom(args[1]), predicateArgs, SortProvider::boolSort); + definitions.push_back(predicate == parsedInterpretation); + } + return Expression::mkAnd(std::move(definitions)); +} +#undef precondition diff --git a/libsmtutil/CHCSmtLib2Interface.h b/libsmtutil/CHCSmtLib2Interface.h index b133c485e095..f7f656fd0b49 100644 --- a/libsmtutil/CHCSmtLib2Interface.h +++ b/libsmtutil/CHCSmtLib2Interface.h @@ -76,6 +76,9 @@ class CHCSmtLib2Interface: public CHCSolverInterface /// Communicates with the solver via the callback. Throws SMTSolverError on error. std::string querySolver(std::string const& _input); + /// Translates CHC solver response with a model to our representation of invariants. Returns None on error. + std::optional invariantsFromSolverResponse(std::string const& response) const; + /// Used to access toSmtLibSort, SExpr, and handle variables. std::unique_ptr m_smtlib2; From 048ce0b19dc488ad10ac3eb1419f29edfb5e153b Mon Sep 17 00:00:00 2001 From: Martin Blicha Date: Tue, 16 Apr 2024 15:03:25 +0200 Subject: [PATCH 0188/1022] SMTChecker: Add command-line test for invariants from Eldarica --- .../model_checker_invariants_contract_eld/args | 1 + .../model_checker_invariants_contract_eld/err | 4 ++++ .../model_checker_invariants_contract_eld/input.sol | 8 ++++++++ 3 files changed, 13 insertions(+) create mode 100644 test/cmdlineTests/model_checker_invariants_contract_eld/args create mode 100644 test/cmdlineTests/model_checker_invariants_contract_eld/err create mode 100644 test/cmdlineTests/model_checker_invariants_contract_eld/input.sol diff --git a/test/cmdlineTests/model_checker_invariants_contract_eld/args b/test/cmdlineTests/model_checker_invariants_contract_eld/args new file mode 100644 index 000000000000..7f2a13bfd8c1 --- /dev/null +++ b/test/cmdlineTests/model_checker_invariants_contract_eld/args @@ -0,0 +1 @@ +--model-checker-engine chc --model-checker-invariants contract --model-checker-solvers eld diff --git a/test/cmdlineTests/model_checker_invariants_contract_eld/err b/test/cmdlineTests/model_checker_invariants_contract_eld/err new file mode 100644 index 000000000000..29c5a5bc8eae --- /dev/null +++ b/test/cmdlineTests/model_checker_invariants_contract_eld/err @@ -0,0 +1,4 @@ +Info: CHC: 1 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. + +Info: Contract invariant(s) for model_checker_invariants_contract_eld/input.sol:test: +(x = 0) diff --git a/test/cmdlineTests/model_checker_invariants_contract_eld/input.sol b/test/cmdlineTests/model_checker_invariants_contract_eld/input.sol new file mode 100644 index 000000000000..4bee228bd65f --- /dev/null +++ b/test/cmdlineTests/model_checker_invariants_contract_eld/input.sol @@ -0,0 +1,8 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity >=0.0; +contract test { + uint x; + function f() public view { + assert(x < 10); + } +} From 87d86bfba64d8b88537a4a85c1d71f521986b614 Mon Sep 17 00:00:00 2001 From: Alexander Arlt Date: Tue, 20 Feb 2024 14:23:58 +0100 Subject: [PATCH 0189/1022] Replace internal JSON library jsoncpp with nlohmann::json. --- CMakeLists.txt | 10 +- Changelog.md | 2 + cmake/jsoncpp.cmake | 72 --- cmake/nlohmann-json.cmake | 21 + libevmasm/AbstractAssemblyStack.h | 2 +- libevmasm/Assembly.cpp | 117 ++-- libevmasm/Assembly.h | 11 +- libevmasm/EVMAssemblyStack.cpp | 6 +- libevmasm/EVMAssemblyStack.h | 4 +- libsolidity/ast/AST.h | 3 +- libsolidity/ast/ASTJsonExporter.cpp | 223 ++++--- libsolidity/ast/ASTJsonExporter.h | 46 +- libsolidity/ast/ASTJsonImporter.cpp | 402 ++++++------ libsolidity/ast/ASTJsonImporter.h | 154 ++--- libsolidity/codegen/ir/IRGenerationContext.h | 1 + libsolidity/codegen/ir/IRGenerator.cpp | 3 +- libsolidity/codegen/ir/IRGenerator.h | 4 +- .../experimental/codegen/IRGenerator.h | 2 +- libsolidity/formal/BMC.h | 1 + libsolidity/interface/ABI.cpp | 54 +- libsolidity/interface/ABI.h | 8 +- libsolidity/interface/CompilerStack.cpp | 86 ++- libsolidity/interface/CompilerStack.h | 49 +- libsolidity/interface/Natspec.cpp | 64 +- libsolidity/interface/Natspec.h | 14 +- libsolidity/interface/StandardCompiler.cpp | 611 +++++++++--------- libsolidity/interface/StandardCompiler.h | 20 +- libsolidity/interface/StorageLayout.cpp | 22 +- libsolidity/interface/StorageLayout.h | 9 +- libsolidity/lsp/DocumentHoverHandler.cpp | 6 +- libsolidity/lsp/DocumentHoverHandler.h | 2 +- libsolidity/lsp/GotoDefinition.cpp | 6 +- libsolidity/lsp/GotoDefinition.h | 2 +- libsolidity/lsp/HandlerBase.cpp | 11 +- libsolidity/lsp/HandlerBase.h | 6 +- libsolidity/lsp/LanguageServer.cpp | 273 ++++---- libsolidity/lsp/LanguageServer.h | 32 +- libsolidity/lsp/RenameSymbol.cpp | 18 +- libsolidity/lsp/RenameSymbol.h | 2 +- libsolidity/lsp/SemanticTokensBuilder.cpp | 16 +- libsolidity/lsp/SemanticTokensBuilder.h | 6 +- libsolidity/lsp/Transport.cpp | 29 +- libsolidity/lsp/Transport.h | 15 +- libsolidity/lsp/Utils.cpp | 20 +- libsolidity/lsp/Utils.h | 10 +- libsolutil/CMakeLists.txt | 2 +- libsolutil/Exceptions.h | 1 + libsolutil/JSON.cpp | 248 ++++--- libsolutil/JSON.h | 98 ++- libyul/AsmJsonConverter.cpp | 84 ++- libyul/AsmJsonConverter.h | 42 +- libyul/AsmJsonImporter.cpp | 98 +-- libyul/AsmJsonImporter.h | 48 +- libyul/Object.cpp | 14 +- libyul/Object.h | 8 +- libyul/YulStack.cpp | 2 +- libyul/YulStack.h | 5 +- libyul/backends/evm/StackLayoutGenerator.cpp | 2 +- solc/CommandLineInterface.cpp | 78 +-- solc/CommandLineInterface.h | 2 +- test/Metadata.cpp | 28 +- test/Metadata.h | 2 +- .../standard_import_with_comments/input.json | 95 +++ .../standard_import_with_comments/output.json | 97 +++ .../input.json | 85 +++ .../output.json | 97 +++ .../input.json | 29 + .../output.json | 12 + .../standard_non_utf8_filename/input.json | 17 + .../standard_non_utf8_filename/output.json | 12 + .../standard_non_utf8_filename2/input.json | 17 + .../standard_non_utf8_filename2/output.json | 12 + .../standard_raw_utf16_filename/input.json | Bin 0 -> 297 bytes .../standard_raw_utf16_filename/output.json | 12 + test/libevmasm/Assembler.cpp | 2 +- test/libsolidity/ASTPropertyTest.cpp | 36 +- test/libsolidity/ASTPropertyTest.h | 2 +- test/libsolidity/GasTest.cpp | 18 +- test/libsolidity/LibSolc.cpp | 32 +- test/libsolidity/Metadata.cpp | 56 +- test/libsolidity/NatspecJSONTest.cpp | 4 +- test/libsolidity/NatspecJSONTest.h | 2 +- test/libsolidity/SemanticTest.cpp | 2 +- test/libsolidity/StandardCompiler.cpp | 610 ++++++++--------- test/libsolidity/util/ContractABIUtils.cpp | 16 +- test/libsolidity/util/ContractABIUtils.h | 7 +- test/libsolidity/util/TestFunctionCall.cpp | 2 +- test/libsolidity/util/TestFunctionCall.h | 6 +- test/libsolutil/JSON.cpp | 278 ++++---- test/solc/CommandLineInterface.cpp | 11 +- test/tools/fuzzer_common.cpp | 18 +- .../tools/ossfuzz/SolidityEvmoneInterface.cpp | 6 +- test/tools/ossfuzz/SolidityEvmoneInterface.h | 4 +- test/yulPhaser/Program.cpp | 2 +- tools/yulPhaser/Program.cpp | 2 +- 95 files changed, 2734 insertions(+), 2104 deletions(-) delete mode 100644 cmake/jsoncpp.cmake create mode 100644 cmake/nlohmann-json.cmake create mode 100644 test/cmdlineTests/standard_import_with_comments/input.json create mode 100644 test/cmdlineTests/standard_import_with_comments/output.json create mode 100644 test/cmdlineTests/standard_import_with_comments_simple/input.json create mode 100644 test/cmdlineTests/standard_import_with_comments_simple/output.json create mode 100644 test/cmdlineTests/standard_import_with_invalid_utf8/input.json create mode 100644 test/cmdlineTests/standard_import_with_invalid_utf8/output.json create mode 100644 test/cmdlineTests/standard_non_utf8_filename/input.json create mode 100644 test/cmdlineTests/standard_non_utf8_filename/output.json create mode 100644 test/cmdlineTests/standard_non_utf8_filename2/input.json create mode 100644 test/cmdlineTests/standard_non_utf8_filename2/output.json create mode 100644 test/cmdlineTests/standard_raw_utf16_filename/input.json create mode 100644 test/cmdlineTests/standard_raw_utf16_filename/output.json diff --git a/CMakeLists.txt b/CMakeLists.txt index b9f2ddc36cad..3e2332b9220b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -39,7 +39,7 @@ option(PEDANTIC "Enable extra warnings and pedantic build flags. Treat all warni option(PROFILE_OPTIMIZER_STEPS "Output performance metrics for the optimiser steps." OFF) option(USE_SYSTEM_LIBRARIES "Use system libraries" OFF) option(ONLY_BUILD_SOLIDITY_LIBRARIES "Only build solidity libraries" OFF) -option(STRICT_JSONCPP_VERSION "Strictly check installed jsoncpp version" ON) +option(STRICT_NLOHMANN_JSON_VERSION "Strictly check installed nlohmann json version" ON) # Setup cccache. include(EthCcache) @@ -48,9 +48,8 @@ include(EthCcache) include(EthDependencies) if (NOT USE_SYSTEM_LIBRARIES) include(fmtlib) - include(jsoncpp) + include(nlohmann-json) include(range-v3) - include_directories(SYSTEM ${JSONCPP_INCLUDE_DIR}) endif() find_package(Threads) @@ -63,8 +62,8 @@ if (PROFILE_OPTIMIZER_STEPS) add_definitions(-DPROFILE_OPTIMIZER_STEPS) endif() -if (STRICT_JSONCPP_VERSION) - add_definitions(-DSTRICT_JSONCPP_VERSION_CHECK) +if (STRICT_NLOHMANN_JSON_VERSION) + add_definitions(-DSTRICT_NLOHMANN_JSON_VERSION_CHECK) endif() # Figure out what compiler and system are we using @@ -162,4 +161,3 @@ if (NOT ONLY_BUILD_SOLIDITY_LIBRARIES) add_subdirectory(test) endif() endif() - diff --git a/Changelog.md b/Changelog.md index c118e9f248a4..0f26cacfc90a 100644 --- a/Changelog.md +++ b/Changelog.md @@ -32,6 +32,8 @@ Bugfixes: * SMTChecker: Fix internal error caused by not respecting the sign of an integer type when constructing zero-value SMT expressions. * SMTChecker: Run Eldarica only when explicitly requested with `--model-checker-solvers eld`, even when it is present on the system. +Build System: + * Replace internal JSON library jsoncpp with nlohmann::json. ### 0.8.24 (2024-01-25) diff --git a/cmake/jsoncpp.cmake b/cmake/jsoncpp.cmake deleted file mode 100644 index c47c2697a3dc..000000000000 --- a/cmake/jsoncpp.cmake +++ /dev/null @@ -1,72 +0,0 @@ -include(ExternalProject) - -if (${CMAKE_SYSTEM_NAME} STREQUAL "Emscripten") - set(JSONCPP_CMAKE_COMMAND emcmake cmake) -else() - set(JSONCPP_CMAKE_COMMAND ${CMAKE_COMMAND}) -endif() - -set(prefix "${PROJECT_BINARY_DIR}/deps") -set(JSONCPP_LIBRARY "${prefix}/lib/${CMAKE_STATIC_LIBRARY_PREFIX}jsoncpp${CMAKE_STATIC_LIBRARY_SUFFIX}") -set(JSONCPP_INCLUDE_DIR "${prefix}/include") - -# TODO: Investigate why this breaks some emscripten builds and -# check whether this can be removed after updating the emscripten -# versions used in the CI runs. -if(EMSCRIPTEN) - # Do not include all flags in CMAKE_CXX_FLAGS for emscripten, - # but only use -std=c++17. Using all flags causes build failures - # at the moment. - set(JSONCPP_CXX_FLAGS -std=c++17) -else() - # jsoncpp uses implicit casts for comparing integer and - # floating point numbers. This causes clang-10 (used by ossfuzz builder) - # to error on the implicit conversions. Here, we request jsoncpp - # to unconditionally use static casts for these conversions by defining the - # JSON_USE_INT64_DOUBLE_CONVERSION preprocessor macro. Doing so, - # not only gets rid of the implicit conversion error that clang-10 produces - # but also forces safer behavior in general. - set(JSONCPP_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DJSON_USE_INT64_DOUBLE_CONVERSION") -endif() - -set(byproducts "") -if(CMAKE_VERSION VERSION_GREATER 3.1) - set(byproducts BUILD_BYPRODUCTS "${JSONCPP_LIBRARY}") -endif() - -# Propagate CMAKE_MSVC_RUNTIME_LIBRARY on Windows builds, if set. -if (WIN32 AND POLICY CMP0091 AND CMAKE_MSVC_RUNTIME_LIBRARY) - list(APPEND JSONCPP_CMAKE_ARGS "-DCMAKE_POLICY_DEFAULT_CMP0091:STRING=NEW") - list(APPEND JSONCPP_CMAKE_ARGS "-DCMAKE_MSVC_RUNTIME_LIBRARY=${CMAKE_MSVC_RUNTIME_LIBRARY}") -endif() - -string(REPLACE ";" "$" CMAKE_OSX_ARCHITECTURES_ "${CMAKE_OSX_ARCHITECTURES}") -ExternalProject_Add(jsoncpp-project - PREFIX "${prefix}" - DOWNLOAD_DIR "${PROJECT_SOURCE_DIR}/deps/downloads" - DOWNLOAD_NAME jsoncpp-1.9.3.tar.gz - URL https://github.com/open-source-parsers/jsoncpp/archive/1.9.3.tar.gz - URL_HASH SHA256=8593c1d69e703563d94d8c12244e2e18893eeb9a8a9f8aa3d09a327aa45c8f7d - CMAKE_COMMAND ${JSONCPP_CMAKE_COMMAND} - CMAKE_ARGS -DCMAKE_INSTALL_PREFIX= - -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} - -DCMAKE_INSTALL_LIBDIR=lib - # Build static lib but suitable to be included in a shared lib. - -DCMAKE_POSITION_INDEPENDENT_CODE=${BUILD_SHARED_LIBS} - -DJSONCPP_WITH_EXAMPLE=OFF - -DJSONCPP_WITH_TESTS=OFF - -DJSONCPP_WITH_PKGCONFIG_SUPPORT=OFF - -DCMAKE_CXX_FLAGS=${JSONCPP_CXX_FLAGS} - -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} - -DCMAKE_OSX_ARCHITECTURES=${CMAKE_OSX_ARCHITECTURES_} - ${JSONCPP_CMAKE_ARGS} - ${byproducts} -) - -# Create jsoncpp imported library -add_library(jsoncpp STATIC IMPORTED) -file(MAKE_DIRECTORY ${JSONCPP_INCLUDE_DIR}) # Must exist. -set_property(TARGET jsoncpp PROPERTY IMPORTED_LOCATION ${JSONCPP_LIBRARY}) -set_property(TARGET jsoncpp PROPERTY INTERFACE_SYSTEM_INCLUDE_DIRECTORIES ${JSONCPP_INCLUDE_DIR}) -set_property(TARGET jsoncpp PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${JSONCPP_INCLUDE_DIR}) -add_dependencies(jsoncpp jsoncpp-project) diff --git a/cmake/nlohmann-json.cmake b/cmake/nlohmann-json.cmake new file mode 100644 index 000000000000..02891e6a7ba6 --- /dev/null +++ b/cmake/nlohmann-json.cmake @@ -0,0 +1,21 @@ +include(ExternalProject) + +ExternalProject_Add(nlohmann-json-project + DOWNLOAD_DIR "${CMAKE_SOURCE_DIR}/deps/nlohmann/nlohmann" + DOWNLOAD_NAME json.hpp + DOWNLOAD_NO_EXTRACT 1 + URL https://github.com/nlohmann/json/releases/download/v3.11.3/json.hpp + URL_HASH SHA256=9bea4c8066ef4a1c206b2be5a36302f8926f7fdc6087af5d20b417d0cf103ea6 + CMAKE_COMMAND true + BUILD_COMMAND true + INSTALL_COMMAND true +) + +# Create nlohmann-json imported library +add_library(nlohmann-json INTERFACE IMPORTED) +file(MAKE_DIRECTORY ${CMAKE_SOURCE_DIR}/deps/nlohmann) # Must exist. +set_target_properties(nlohmann-json PROPERTIES + INTERFACE_COMPILE_OPTIONS "\$<\$:/permissive->" + INTERFACE_SYSTEM_INCLUDE_DIRECTORIES ${CMAKE_SOURCE_DIR}/deps/nlohmann + INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_SOURCE_DIR}/deps/nlohmann) +add_dependencies(nlohmann-json nlohmann-json-project) \ No newline at end of file diff --git a/libevmasm/AbstractAssemblyStack.h b/libevmasm/AbstractAssemblyStack.h index 6be78cbc7cac..278edf5c273b 100644 --- a/libevmasm/AbstractAssemblyStack.h +++ b/libevmasm/AbstractAssemblyStack.h @@ -40,7 +40,7 @@ class AbstractAssemblyStack virtual std::string const* sourceMapping(std::string const& _contractName) const = 0; virtual std::string const* runtimeSourceMapping(std::string const& _contractName) const = 0; - virtual Json::Value assemblyJSON(std::string const& _contractName) const = 0; + virtual Json assemblyJSON(std::string const& _contractName) const = 0; virtual std::string assemblyString(std::string const& _contractName, StringMap const& _sourceCodes) const = 0; virtual std::string const filesystemFriendlyName(std::string const& _contractName) const = 0; diff --git a/libevmasm/Assembly.cpp b/libevmasm/Assembly.cpp index 067e230343d0..356a2818a4cd 100644 --- a/libevmasm/Assembly.cpp +++ b/libevmasm/Assembly.cpp @@ -80,10 +80,10 @@ unsigned Assembly::codeSize(unsigned subTagSize) const } } -void Assembly::importAssemblyItemsFromJSON(Json::Value const& _code, std::vector const& _sourceList) +void Assembly::importAssemblyItemsFromJSON(Json const& _code, std::vector const& _sourceList) { solAssert(m_items.empty()); - solRequire(_code.isArray(), AssemblyImportException, "Supplied JSON is not an array."); + solRequire(_code.is_array(), AssemblyImportException, "Supplied JSON is not an array."); for (auto jsonItemIter = std::begin(_code); jsonItemIter != std::end(_code); ++jsonItemIter) { AssemblyItem const& newItem = m_items.emplace_back(createAssemblyItemFromJSON(*jsonItemIter, _sourceList)); @@ -98,11 +98,11 @@ void Assembly::importAssemblyItemsFromJSON(Json::Value const& _code, std::vector } } -AssemblyItem Assembly::createAssemblyItemFromJSON(Json::Value const& _json, std::vector const& _sourceList) +AssemblyItem Assembly::createAssemblyItemFromJSON(Json const& _json, std::vector const& _sourceList) { - solRequire(_json.isObject(), AssemblyImportException, "Supplied JSON is not an object."); + solRequire(_json.is_object(), AssemblyImportException, "Supplied JSON is not an object."); static std::set const validMembers{"name", "begin", "end", "source", "value", "modifierDepth", "jumpType"}; - for (std::string const& member: _json.getMemberNames()) + for (auto const& [member, _]: _json.items()) solRequire( validMembers.count(member), AssemblyImportException, @@ -124,14 +124,14 @@ AssemblyItem Assembly::createAssemblyItemFromJSON(Json::Value const& _json, std: solRequire(!name.empty(), AssemblyImportException, "Member 'name' is empty."); SourceLocation location; - if (_json.isMember("begin")) + if (_json.contains("begin")) location.start = get(_json["begin"]); - if (_json.isMember("end")) + if (_json.contains("end")) location.end = get(_json["end"]); - int srcIndex = getOrDefault(_json["source"], -1); - size_t modifierDepth = static_cast(getOrDefault(_json["modifierDepth"], 0)); - std::string value = getOrDefault(_json["value"], ""); - std::string jumpType = getOrDefault(_json["jumpType"], ""); + int srcIndex = getOrDefault(_json, "source", -1); + size_t modifierDepth = static_cast(getOrDefault(_json, "modifierDepth", 0)); + std::string value = getOrDefault(_json, "value", ""); + std::string jumpType = getOrDefault(_json, "jumpType", ""); auto updateUsedTags = [&](u256 const& data) { @@ -429,11 +429,11 @@ std::string Assembly::assemblyString( return tmp.str(); } -Json::Value Assembly::assemblyJSON(std::map const& _sourceIndices, bool _includeSourceList) const +Json Assembly::assemblyJSON(std::map const& _sourceIndices, bool _includeSourceList) const { - Json::Value root; - root[".code"] = Json::arrayValue; - Json::Value& code = root[".code"]; + Json root; + root[".code"] = Json::array(); + Json& code = root[".code"]; for (AssemblyItem const& item: m_items) { int sourceIndex = -1; @@ -445,7 +445,7 @@ Json::Value Assembly::assemblyJSON(std::map const& _sourc } auto [name, data] = item.nameAndData(m_evmVersion); - Json::Value jsonItem; + Json jsonItem; jsonItem["name"] = name; jsonItem["begin"] = item.location().start; jsonItem["end"] = item.location().end; @@ -461,32 +461,32 @@ Json::Value Assembly::assemblyJSON(std::map const& _sourc if (!data.empty()) jsonItem["value"] = data; jsonItem["source"] = sourceIndex; - code.append(std::move(jsonItem)); + code.emplace_back(std::move(jsonItem)); if (item.type() == AssemblyItemType::Tag) { - Json::Value jumpdest; + Json jumpdest; jumpdest["name"] = "JUMPDEST"; jumpdest["begin"] = item.location().start; jumpdest["end"] = item.location().end; jumpdest["source"] = sourceIndex; if (item.m_modifierDepth != 0) jumpdest["modifierDepth"] = static_cast(item.m_modifierDepth); - code.append(std::move(jumpdest)); + code.emplace_back(std::move(jumpdest)); } } if (_includeSourceList) { - root["sourceList"] = Json::arrayValue; - Json::Value& jsonSourceList = root["sourceList"]; + root["sourceList"] = Json::array(); + Json& jsonSourceList = root["sourceList"]; for (auto const& [name, index]: _sourceIndices) jsonSourceList[index] = name; } if (!m_data.empty() || !m_subs.empty()) { - root[".data"] = Json::objectValue; - Json::Value& data = root[".data"]; + root[".data"] = Json::object(); + Json& data = root[".data"]; for (auto const& i: m_data) if (u256(i.first) >= m_subs.size()) data[util::toHex(toBigEndian((u256)i.first), util::HexPrefix::DontAdd, util::HexCase::Upper)] = util::toHex(i.second); @@ -506,110 +506,107 @@ Json::Value Assembly::assemblyJSON(std::map const& _sourc } std::pair, std::vector> Assembly::fromJSON( - Json::Value const& _json, + Json const& _json, std::vector const& _sourceList, size_t _level ) { - solRequire(_json.isObject(), AssemblyImportException, "Supplied JSON is not an object."); + solRequire(_json.is_object(), AssemblyImportException, "Supplied JSON is not an object."); static std::set const validMembers{".code", ".data", ".auxdata", "sourceList"}; - for (std::string const& attribute: _json.getMemberNames()) + for (auto const& [attribute, _]: _json.items()) solRequire(validMembers.count(attribute), AssemblyImportException, "Unknown attribute '" + attribute + "'."); if (_level == 0) { - if (_json.isMember("sourceList")) + if (_json.contains("sourceList")) { - solRequire(_json["sourceList"].isArray(), AssemblyImportException, "Optional member 'sourceList' is not an array."); - for (Json::Value const& sourceName: _json["sourceList"]) - solRequire(sourceName.isString(), AssemblyImportException, "The 'sourceList' array contains an item that is not a string."); + solRequire(_json["sourceList"].is_array(), AssemblyImportException, "Optional member 'sourceList' is not an array."); + for (Json const& sourceName: _json["sourceList"]) + solRequire(sourceName.is_string(), AssemblyImportException, "The 'sourceList' array contains an item that is not a string."); } } else solRequire( - !_json.isMember("sourceList"), + !_json.contains("sourceList"), AssemblyImportException, "Member 'sourceList' may only be present in the root JSON object." ); auto result = std::make_shared(EVMVersion{}, _level == 0 /* _creation */, "" /* _name */); std::vector parsedSourceList; - if (_json.isMember("sourceList")) + if (_json.contains("sourceList")) { solAssert(_level == 0); solAssert(_sourceList.empty()); - for (Json::Value const& sourceName: _json["sourceList"]) + for (Json const& sourceName: _json["sourceList"]) { solRequire( - std::find(parsedSourceList.begin(), parsedSourceList.end(), sourceName.asString()) == parsedSourceList.end(), + std::find(parsedSourceList.begin(), parsedSourceList.end(), sourceName.get()) == parsedSourceList.end(), AssemblyImportException, "Items in 'sourceList' array are not unique." ); - parsedSourceList.emplace_back(sourceName.asString()); + parsedSourceList.emplace_back(sourceName.get()); } } - solRequire(_json.isMember(".code"), AssemblyImportException, "Member '.code' is missing."); - solRequire(_json[".code"].isArray(), AssemblyImportException, "Member '.code' is not an array."); - for (Json::Value const& codeItem: _json[".code"]) - solRequire(codeItem.isObject(), AssemblyImportException, "The '.code' array contains an item that is not an object."); + solRequire(_json.contains(".code"), AssemblyImportException, "Member '.code' is missing."); + solRequire(_json[".code"].is_array(), AssemblyImportException, "Member '.code' is not an array."); + for (Json const& codeItem: _json[".code"]) + solRequire(codeItem.is_object(), AssemblyImportException, "The '.code' array contains an item that is not an object."); result->importAssemblyItemsFromJSON(_json[".code"], _level == 0 ? parsedSourceList : _sourceList); - if (_json.isMember(".auxdata")) + if (_json.contains(".auxdata")) { - solRequire(_json[".auxdata"].isString(), AssemblyImportException, "Optional member '.auxdata' is not a string."); - result->m_auxiliaryData = fromHex(_json[".auxdata"].asString()); + solRequire(_json[".auxdata"].is_string(), AssemblyImportException, "Optional member '.auxdata' is not a string."); + result->m_auxiliaryData = fromHex(_json[".auxdata"].get()); solRequire(!result->m_auxiliaryData.empty(), AssemblyImportException, "Optional member '.auxdata' is not a valid hexadecimal string."); } - if (_json.isMember(".data")) + if (_json.contains(".data")) { - solRequire(_json[".data"].isObject(), AssemblyImportException, "Optional member '.data' is not an object."); - Json::Value const& data = _json[".data"]; + solRequire(_json[".data"].is_object(), AssemblyImportException, "Optional member '.data' is not an object."); + Json const& data = _json[".data"]; std::map> subAssemblies; - for (Json::ValueConstIterator dataIter = data.begin(); dataIter != data.end(); dataIter++) + for (auto const& [key, value] : data.items()) { - solAssert(dataIter.key().isString()); - std::string dataItemID = dataIter.key().asString(); - Json::Value const& dataItem = data[dataItemID]; - if (dataItem.isString()) + if (value.is_string()) { solRequire( - dataItem.asString().empty() || !fromHex(dataItem.asString()).empty(), + value.get().empty() || !fromHex(value.get()).empty(), AssemblyImportException, - "The value for key '" + dataItemID + "' inside '.data' is not a valid hexadecimal string." + "The value for key '" + key + "' inside '.data' is not a valid hexadecimal string." ); - result->m_data[h256(fromHex(dataItemID))] = fromHex(dataItem.asString()); + result->m_data[h256(fromHex(key))] = fromHex(value.get()); } - else if (dataItem.isObject()) + else if (value.is_object()) { size_t index{}; try { // Using signed variant because stoul() still accepts negative numbers and // just lets them wrap around. - int parsedDataItemID = std::stoi(dataItemID, nullptr, 16); - solRequire(parsedDataItemID >= 0, AssemblyImportException, "The key '" + dataItemID + "' inside '.data' is out of the supported integer range."); + int parsedDataItemID = std::stoi(key, nullptr, 16); + solRequire(parsedDataItemID >= 0, AssemblyImportException, "The key '" + key + "' inside '.data' is out of the supported integer range."); index = static_cast(parsedDataItemID); } catch (std::invalid_argument const&) { - solThrow(AssemblyImportException, "The key '" + dataItemID + "' inside '.data' is not an integer."); + solThrow(AssemblyImportException, "The key '" + key + "' inside '.data' is not an integer."); } catch (std::out_of_range const&) { - solThrow(AssemblyImportException, "The key '" + dataItemID + "' inside '.data' is out of the supported integer range."); + solThrow(AssemblyImportException, "The key '" + key + "' inside '.data' is out of the supported integer range."); } - auto [subAssembly, emptySourceList] = Assembly::fromJSON(dataItem, _level == 0 ? parsedSourceList : _sourceList, _level + 1); + auto [subAssembly, emptySourceList] = Assembly::fromJSON(value, _level == 0 ? parsedSourceList : _sourceList, _level + 1); solAssert(subAssembly); solAssert(emptySourceList.empty()); solAssert(subAssemblies.count(index) == 0); subAssemblies[index] = subAssembly; } else - solThrow(AssemblyImportException, "The value of key '" + dataItemID + "' inside '.data' is neither a hex string nor an object."); + solThrow(AssemblyImportException, "The value of key '" + key + "' inside '.data' is neither a hex string nor an object."); } if (!subAssemblies.empty()) diff --git a/libevmasm/Assembly.h b/libevmasm/Assembly.h index 6e900282569b..123d7f3ddd8c 100644 --- a/libevmasm/Assembly.h +++ b/libevmasm/Assembly.h @@ -30,11 +30,10 @@ #include #include #include +#include #include -#include - #include #include #include @@ -150,7 +149,7 @@ class Assembly ) const; /// Create a JSON representation of the assembly. - Json::Value assemblyJSON(std::map const& _sourceIndices, bool _includeSourceList = true) const; + Json assemblyJSON(std::map const& _sourceIndices, bool _includeSourceList = true) const; /// Constructs an @a Assembly from the serialized JSON representation. /// @param _json JSON object containing assembly in the format produced by assemblyJSON(). @@ -163,7 +162,7 @@ class Assembly /// @returns Created @a Assembly and the source list read from the 'sourceList' field of the root /// assembly or an empty list (in recursive calls). static std::pair, std::vector> fromJSON( - Json::Value const& _json, + Json const& _json, std::vector const& _sourceList = {}, size_t _level = 0 ); @@ -188,13 +187,13 @@ class Assembly /// the code array. This method only works on clean Assembly objects that don't have any items defined yet. /// @param _json JSON array that contains assembly items (e.g. json['.code']) /// @param _sourceList List of source names. - void importAssemblyItemsFromJSON(Json::Value const& _code, std::vector const& _sourceList); + void importAssemblyItemsFromJSON(Json const& _code, std::vector const& _sourceList); /// Creates an AssemblyItem from a given JSON representation. /// @param _json JSON object that consists a single assembly item /// @param _sourceList List of source names. /// @returns AssemblyItem of _json argument. - AssemblyItem createAssemblyItemFromJSON(Json::Value const& _json, std::vector const& _sourceList); + AssemblyItem createAssemblyItemFromJSON(Json const& _json, std::vector const& _sourceList); private: bool m_invalid = false; diff --git a/libevmasm/EVMAssemblyStack.cpp b/libevmasm/EVMAssemblyStack.cpp index a06044256faf..20605ee354a0 100644 --- a/libevmasm/EVMAssemblyStack.cpp +++ b/libevmasm/EVMAssemblyStack.cpp @@ -36,12 +36,12 @@ namespace solidity::evmasm void EVMAssemblyStack::parseAndAnalyze(std::string const& _sourceName, std::string const& _source) { - Json::Value assemblyJson; + Json assemblyJson; solRequire(jsonParseStrict(_source, assemblyJson), AssemblyImportException, "Could not parse JSON file."); analyze(_sourceName, assemblyJson); } -void EVMAssemblyStack::analyze(std::string const& _sourceName, Json::Value const& _assemblyJson) +void EVMAssemblyStack::analyze(std::string const& _sourceName, Json const& _assemblyJson) { solAssert(!m_evmAssembly); m_name = _sourceName; @@ -99,7 +99,7 @@ std::string const* EVMAssemblyStack::runtimeSourceMapping(std::string const& _co return &m_runtimeSourceMapping; } -Json::Value EVMAssemblyStack::assemblyJSON(std::string const& _contractName) const +Json EVMAssemblyStack::assemblyJSON(std::string const& _contractName) const { solAssert(_contractName == m_name); solAssert(m_evmAssembly); diff --git a/libevmasm/EVMAssemblyStack.h b/libevmasm/EVMAssemblyStack.h index 7fe77e7d208b..f2516c0b8a0a 100644 --- a/libevmasm/EVMAssemblyStack.h +++ b/libevmasm/EVMAssemblyStack.h @@ -43,7 +43,7 @@ class EVMAssemblyStack: public AbstractAssemblyStack /// Runs analysis steps. /// Multiple calls overwrite the previous state. /// @throws AssemblyImportException, if JSON could not be validated. - void analyze(std::string const& _sourceName, Json::Value const& _assemblyJson); + void analyze(std::string const& _sourceName, Json const& _assemblyJson); void assemble(); @@ -58,7 +58,7 @@ class EVMAssemblyStack: public AbstractAssemblyStack virtual std::string const* sourceMapping(std::string const& _contractName) const override; virtual std::string const* runtimeSourceMapping(std::string const& _contractName) const override; - virtual Json::Value assemblyJSON(std::string const& _contractName) const override; + virtual Json assemblyJSON(std::string const& _contractName) const override; virtual std::string assemblyString(std::string const& _contractName, StringMap const& _sourceCodes) const override; virtual std::string const filesystemFriendlyName(std::string const& _contractName) const override; diff --git a/libsolidity/ast/AST.h b/libsolidity/ast/AST.h index 27926721aa6f..d8b178377bd8 100644 --- a/libsolidity/ast/AST.h +++ b/libsolidity/ast/AST.h @@ -34,8 +34,7 @@ #include #include #include - -#include +#include #include #include diff --git a/libsolidity/ast/ASTJsonExporter.cpp b/libsolidity/ast/ASTJsonExporter.cpp index c54a2d013ad0..f94b91674bcb 100644 --- a/libsolidity/ast/ASTJsonExporter.cpp +++ b/libsolidity/ast/ASTJsonExporter.cpp @@ -46,12 +46,13 @@ using namespace std::string_literals; using namespace solidity::langutil; +using namespace solidity; namespace { template typename C> -void addIfSet(std::vector>& _attributes, std::string const& _name, C const& _value) +void addIfSet(std::vector>& _attributes, std::string const& _name, C const& _value) { if constexpr (std::is_same_v, solidity::util::SetOnce>) { @@ -82,23 +83,23 @@ ASTJsonExporter::ASTJsonExporter(CompilerStack::State _stackState, std::map>&& _attributes + std::initializer_list>&& _attributes ) { ASTJsonExporter::setJsonNode( _node, _nodeName, - std::vector>(std::move(_attributes)) + std::vector>(std::move(_attributes)) ); } void ASTJsonExporter::setJsonNode( ASTNode const& _node, std::string const& _nodeType, - std::vector>&& _attributes + std::vector>&& _attributes ) { - m_currentValue = Json::objectValue; + m_currentValue = Json::object(); m_currentValue["id"] = nodeId(_node); m_currentValue["src"] = sourceLocationToString(_node.location()); if (auto const* documented = dynamic_cast(&_node)) @@ -126,12 +127,12 @@ std::string ASTJsonExporter::sourceLocationToString(SourceLocation const& _locat return std::to_string(_location.start) + ":" + std::to_string(length) + ":" + (sourceIndexOpt.has_value() ? std::to_string(sourceIndexOpt.value()) : "-1"); } -Json::Value ASTJsonExporter::sourceLocationsToJson(std::vector const& _sourceLocations) const +Json ASTJsonExporter::sourceLocationsToJson(std::vector const& _sourceLocations) const { - Json::Value locations = Json::arrayValue; + Json locations = Json::array(); for (SourceLocation const& location: _sourceLocations) - locations.append(sourceLocationToString(location)); + locations.emplace_back(sourceLocationToString(location)); return locations; } @@ -141,33 +142,33 @@ std::string ASTJsonExporter::namePathToString(std::vector const& _nam return boost::algorithm::join(_namePath, "."s); } -Json::Value ASTJsonExporter::typePointerToJson(Type const* _tp, bool _withoutDataLocation) +Json ASTJsonExporter::typePointerToJson(Type const* _tp, bool _withoutDataLocation) { - Json::Value typeDescriptions(Json::objectValue); - typeDescriptions["typeString"] = _tp ? Json::Value(_tp->toString(_withoutDataLocation)) : Json::nullValue; - typeDescriptions["typeIdentifier"] = _tp ? Json::Value(_tp->identifier()) : Json::nullValue; + Json typeDescriptions; + typeDescriptions["typeString"] = _tp ? Json(_tp->toString(_withoutDataLocation)) : Json(); + typeDescriptions["typeIdentifier"] = _tp ? Json(_tp->identifier()) : Json(); return typeDescriptions; } -Json::Value ASTJsonExporter::typePointerToJson(std::optional const& _tps) +Json ASTJsonExporter::typePointerToJson(std::optional const& _tps) { if (_tps) { - Json::Value arguments(Json::arrayValue); + Json arguments = Json::array(); for (auto const& tp: _tps->types) appendMove(arguments, typePointerToJson(tp)); return arguments; } else - return Json::nullValue; + return Json(); } void ASTJsonExporter::appendExpressionAttributes( - std::vector>& _attributes, + std::vector>& _attributes, ExpressionAnnotation const& _annotation ) { - std::vector> exprAttributes = { + std::vector> exprAttributes = { std::make_pair("typeDescriptions", typePointerToJson(_annotation.type)), std::make_pair("argumentTypes", typePointerToJson(_annotation.arguments)) }; @@ -182,18 +183,18 @@ void ASTJsonExporter::appendExpressionAttributes( _attributes += exprAttributes; } -Json::Value ASTJsonExporter::inlineAssemblyIdentifierToJson(std::pair _info) const +Json ASTJsonExporter::inlineAssemblyIdentifierToJson(std::pair _info) const { - Json::Value tuple(Json::objectValue); + Json tuple; tuple["src"] = sourceLocationToString(nativeLocationOf(*_info.first)); tuple["declaration"] = idOrNull(_info.second.declaration); - tuple["isSlot"] = Json::Value(_info.second.suffix == "slot"); - tuple["isOffset"] = Json::Value(_info.second.suffix == "offset"); + tuple["isSlot"] = Json(_info.second.suffix == "slot"); + tuple["isOffset"] = Json(_info.second.suffix == "offset"); if (!_info.second.suffix.empty()) - tuple["suffix"] = Json::Value(_info.second.suffix); + tuple["suffix"] = Json(_info.second.suffix); - tuple["valueSize"] = Json::Value(Json::LargestUInt(_info.second.valueSize)); + tuple["valueSize"] = Json(static_cast(_info.second.valueSize)); return tuple; } @@ -203,7 +204,7 @@ void ASTJsonExporter::print(std::ostream& _stream, ASTNode const& _node, util::J _stream << util::jsonPrint(toJson(_node), _format); } -Json::Value ASTJsonExporter::toJson(ASTNode const& _node) +Json ASTJsonExporter::toJson(ASTNode const& _node) { _node.accept(*this); return util::removeNullMembers(std::move(m_currentValue)); @@ -211,22 +212,22 @@ Json::Value ASTJsonExporter::toJson(ASTNode const& _node) bool ASTJsonExporter::visit(SourceUnit const& _node) { - std::vector> attributes = { - std::make_pair("license", _node.licenseString() ? Json::Value(*_node.licenseString()) : Json::nullValue), + std::vector> attributes = { + std::make_pair("license", _node.licenseString() ? Json(*_node.licenseString()) : Json()), std::make_pair("nodes", toJson(_node.nodes())), }; if (_node.experimentalSolidity()) - attributes.emplace_back("experimentalSolidity", Json::Value(_node.experimentalSolidity())); + attributes.emplace_back("experimentalSolidity", Json(_node.experimentalSolidity())); if (_node.annotation().exportedSymbols.set()) { - Json::Value exportedSymbols = Json::objectValue; + Json exportedSymbols = Json::object(); for (auto const& sym: *_node.annotation().exportedSymbols) { - exportedSymbols[sym.first] = Json::arrayValue; + exportedSymbols[sym.first] = Json::array(); for (Declaration const* overload: sym.second) - exportedSymbols[sym.first].append(nodeId(*overload)); + exportedSymbols[sym.first].emplace_back(nodeId(*overload)); } attributes.emplace_back("exportedSymbols", exportedSymbols); @@ -241,9 +242,9 @@ bool ASTJsonExporter::visit(SourceUnit const& _node) bool ASTJsonExporter::visit(PragmaDirective const& _node) { - Json::Value literals(Json::arrayValue); + Json literals = Json::array(); for (auto const& literal: _node.literals()) - literals.append(literal); + literals.emplace_back(literal); setJsonNode(_node, "PragmaDirective", { std::make_pair("literals", std::move(literals)) }); @@ -252,7 +253,7 @@ bool ASTJsonExporter::visit(PragmaDirective const& _node) bool ASTJsonExporter::visit(ImportDirective const& _node) { - std::vector> attributes = { + std::vector> attributes = { std::make_pair("file", _node.path()), std::make_pair("sourceUnit", idOrNull(_node.annotation().sourceUnit)), std::make_pair("scope", idOrNull(_node.scope())) @@ -261,17 +262,17 @@ bool ASTJsonExporter::visit(ImportDirective const& _node) addIfSet(attributes, "absolutePath", _node.annotation().absolutePath); attributes.emplace_back("unitAlias", _node.name()); - attributes.emplace_back("nameLocation", Json::Value(sourceLocationToString(_node.nameLocation()))); + attributes.emplace_back("nameLocation", Json(sourceLocationToString(_node.nameLocation()))); - Json::Value symbolAliases(Json::arrayValue); + Json symbolAliases = Json::array(); for (auto const& symbolAlias: _node.symbolAliases()) { - Json::Value tuple(Json::objectValue); + Json tuple; solAssert(symbolAlias.symbol, ""); tuple["foreign"] = toJson(*symbolAlias.symbol); - tuple["local"] = symbolAlias.alias ? Json::Value(*symbolAlias.alias) : Json::nullValue; + tuple["local"] = symbolAlias.alias ? Json(*symbolAlias.alias) : Json(); tuple["nameLocation"] = sourceLocationToString(_node.nameLocation()); - symbolAliases.append(tuple); + symbolAliases.emplace_back(tuple); } attributes.emplace_back("symbolAliases", std::move(symbolAliases)); setJsonNode(_node, "ImportDirective", std::move(attributes)); @@ -280,10 +281,10 @@ bool ASTJsonExporter::visit(ImportDirective const& _node) bool ASTJsonExporter::visit(ContractDefinition const& _node) { - std::vector> attributes = { + std::vector> attributes = { std::make_pair("name", _node.name()), std::make_pair("nameLocation", sourceLocationToString(_node.nameLocation())), - std::make_pair("documentation", _node.documentation() ? toJson(*_node.documentation()) : Json::nullValue), + std::make_pair("documentation", _node.documentation() ? toJson(*_node.documentation()) : Json()), std::make_pair("contractKind", contractKind(_node.contractKind())), std::make_pair("abstract", _node.abstract()), std::make_pair("baseContracts", toJson(_node.baseContracts())), @@ -303,7 +304,7 @@ bool ASTJsonExporter::visit(ContractDefinition const& _node) if (!_node.annotation().internalFunctionIDs.empty()) { - Json::Value internalFunctionIDs(Json::objectValue); + Json internalFunctionIDs; for (auto const& [functionDefinition, internalFunctionID]: _node.annotation().internalFunctionIDs) internalFunctionIDs[std::to_string(functionDefinition->id())] = internalFunctionID; attributes.emplace_back("internalFunctionIDs", std::move(internalFunctionIDs)); @@ -315,10 +316,10 @@ bool ASTJsonExporter::visit(ContractDefinition const& _node) bool ASTJsonExporter::visit(IdentifierPath const& _node) { - Json::Value nameLocations = Json::arrayValue; + Json nameLocations = Json::array(); for (SourceLocation location: _node.pathLocations()) - nameLocations.append(sourceLocationToString(location)); + nameLocations.emplace_back(sourceLocationToString(location)); setJsonNode(_node, "IdentifierPath", { std::make_pair("name", namePathToString(_node.path())), @@ -332,23 +333,23 @@ bool ASTJsonExporter::visit(InheritanceSpecifier const& _node) { setJsonNode(_node, "InheritanceSpecifier", { std::make_pair("baseName", toJson(_node.name())), - std::make_pair("arguments", _node.arguments() ? toJson(*_node.arguments()) : Json::nullValue) + std::make_pair("arguments", _node.arguments() ? toJson(*_node.arguments()) : Json()) }); return false; } bool ASTJsonExporter::visit(UsingForDirective const& _node) { - std::vector> attributes = { - std::make_pair("typeName", _node.typeName() ? toJson(*_node.typeName()) : Json::nullValue) + std::vector> attributes = { + std::make_pair("typeName", _node.typeName() ? toJson(*_node.typeName()) : Json()) }; if (_node.usesBraces()) { - Json::Value functionList; + Json functionList = Json::array(); for (auto&& [function, op]: _node.functionsAndOperators()) { - Json::Value functionNode; + Json functionNode; if (!op.has_value()) functionNode["function"] = toJson(*function); else @@ -356,7 +357,7 @@ bool ASTJsonExporter::visit(UsingForDirective const& _node) functionNode["definition"] = toJson(*function); functionNode["operator"] = std::string(TokenTraits::toString(*op)); } - functionList.append(std::move(functionNode)); + functionList.emplace_back(std::move(functionNode)); } attributes.emplace_back("functionList", std::move(functionList)); } @@ -376,10 +377,10 @@ bool ASTJsonExporter::visit(UsingForDirective const& _node) bool ASTJsonExporter::visit(StructDefinition const& _node) { - std::vector> attributes = { + std::vector> attributes = { std::make_pair("name", _node.name()), std::make_pair("nameLocation", sourceLocationToString(_node.nameLocation())), - std::make_pair("documentation", _node.documentation() ? toJson(*_node.documentation()) : Json::nullValue), + std::make_pair("documentation", _node.documentation() ? toJson(*_node.documentation()) : Json()), std::make_pair("visibility", Declaration::visibilityToString(_node.visibility())), std::make_pair("members", toJson(_node.members())), std::make_pair("scope", idOrNull(_node.scope())) @@ -394,10 +395,10 @@ bool ASTJsonExporter::visit(StructDefinition const& _node) bool ASTJsonExporter::visit(EnumDefinition const& _node) { - std::vector> attributes = { + std::vector> attributes = { std::make_pair("name", _node.name()), std::make_pair("nameLocation", sourceLocationToString(_node.nameLocation())), - std::make_pair("documentation", _node.documentation() ? toJson(*_node.documentation()) : Json::nullValue), + std::make_pair("documentation", _node.documentation() ? toJson(*_node.documentation()) : Json()), std::make_pair("members", toJson(_node.members())) }; @@ -420,7 +421,7 @@ bool ASTJsonExporter::visit(EnumValue const& _node) bool ASTJsonExporter::visit(UserDefinedValueTypeDefinition const& _node) { solAssert(_node.underlyingType(), ""); - std::vector> attributes = { + std::vector> attributes = { std::make_pair("name", _node.name()), std::make_pair("nameLocation", sourceLocationToString(_node.nameLocation())), std::make_pair("underlyingType", toJson(*_node.underlyingType())) @@ -450,18 +451,18 @@ bool ASTJsonExporter::visit(OverrideSpecifier const& _node) bool ASTJsonExporter::visit(FunctionDefinition const& _node) { - std::vector> attributes = { + std::vector> attributes = { std::make_pair("name", _node.name()), std::make_pair("nameLocation", sourceLocationToString(_node.nameLocation())), - std::make_pair("documentation", _node.documentation() ? toJson(*_node.documentation()) : Json::nullValue), + std::make_pair("documentation", _node.documentation() ? toJson(*_node.documentation()) : Json()), std::make_pair("kind", _node.isFree() ? "freeFunction" : TokenTraits::toString(_node.kind())), std::make_pair("stateMutability", stateMutabilityToString(_node.stateMutability())), std::make_pair("virtual", _node.markedVirtual()), - std::make_pair("overrides", _node.overrides() ? toJson(*_node.overrides()) : Json::nullValue), + std::make_pair("overrides", _node.overrides() ? toJson(*_node.overrides()) : Json()), std::make_pair("parameters", toJson(_node.parameterList())), std::make_pair("returnParameters", toJson(*_node.returnParameterList())), std::make_pair("modifiers", toJson(_node.modifiers())), - std::make_pair("body", _node.isImplemented() ? toJson(_node.body()) : Json::nullValue), + std::make_pair("body", _node.isImplemented() ? toJson(_node.body()) : Json()), std::make_pair("implemented", _node.isImplemented()), std::make_pair("scope", idOrNull(_node.scope())) }; @@ -489,7 +490,7 @@ bool ASTJsonExporter::visit(FunctionDefinition const& _node) bool ASTJsonExporter::visit(VariableDeclaration const& _node) { - std::vector> attributes = { + std::vector> attributes = { std::make_pair("name", _node.name()), std::make_pair("nameLocation", sourceLocationToString(_node.nameLocation())), std::make_pair("typeName", toJson(_node.typeName())), @@ -497,9 +498,9 @@ bool ASTJsonExporter::visit(VariableDeclaration const& _node) std::make_pair("mutability", VariableDeclaration::mutabilityToString(_node.mutability())), std::make_pair("stateVariable", _node.isStateVariable()), std::make_pair("storageLocation", location(_node.referenceLocation())), - std::make_pair("overrides", _node.overrides() ? toJson(*_node.overrides()) : Json::nullValue), + std::make_pair("overrides", _node.overrides() ? toJson(*_node.overrides()) : Json()), std::make_pair("visibility", Declaration::visibilityToString(_node.visibility())), - std::make_pair("value", _node.value() ? toJson(*_node.value()) : Json::nullValue), + std::make_pair("value", _node.value() ? toJson(*_node.value()) : Json()), std::make_pair("scope", idOrNull(_node.scope())), std::make_pair("typeDescriptions", typePointerToJson(_node.annotation().type, true)) }; @@ -517,15 +518,15 @@ bool ASTJsonExporter::visit(VariableDeclaration const& _node) bool ASTJsonExporter::visit(ModifierDefinition const& _node) { - std::vector> attributes = { + std::vector> attributes = { std::make_pair("name", _node.name()), std::make_pair("nameLocation", sourceLocationToString(_node.nameLocation())), - std::make_pair("documentation", _node.documentation() ? toJson(*_node.documentation()) : Json::nullValue), + std::make_pair("documentation", _node.documentation() ? toJson(*_node.documentation()) : Json()), std::make_pair("visibility", Declaration::visibilityToString(_node.visibility())), std::make_pair("parameters", toJson(_node.parameterList())), std::make_pair("virtual", _node.markedVirtual()), - std::make_pair("overrides", _node.overrides() ? toJson(*_node.overrides()) : Json::nullValue), - std::make_pair("body", _node.isImplemented() ? toJson(_node.body()) : Json::nullValue) + std::make_pair("overrides", _node.overrides() ? toJson(*_node.overrides()) : Json()), + std::make_pair("body", _node.isImplemented() ? toJson(_node.body()) : Json()) }; if (!_node.annotation().baseFunctions.empty()) attributes.emplace_back(std::make_pair("baseModifiers", getContainerIds(_node.annotation().baseFunctions, true))); @@ -535,9 +536,9 @@ bool ASTJsonExporter::visit(ModifierDefinition const& _node) bool ASTJsonExporter::visit(ModifierInvocation const& _node) { - std::vector> attributes{ + std::vector> attributes{ std::make_pair("modifierName", toJson(_node.name())), - std::make_pair("arguments", _node.arguments() ? toJson(*_node.arguments()) : Json::nullValue) + std::make_pair("arguments", _node.arguments() ? toJson(*_node.arguments()) : Json()) }; if (Declaration const* declaration = _node.name().annotation().referencedDeclaration) { @@ -553,10 +554,10 @@ bool ASTJsonExporter::visit(ModifierInvocation const& _node) bool ASTJsonExporter::visit(EventDefinition const& _node) { m_inEvent = true; - std::vector> _attributes = { + std::vector> _attributes = { std::make_pair("name", _node.name()), std::make_pair("nameLocation", sourceLocationToString(_node.nameLocation())), - std::make_pair("documentation", _node.documentation() ? toJson(*_node.documentation()) : Json::nullValue), + std::make_pair("documentation", _node.documentation() ? toJson(*_node.documentation()) : Json()), std::make_pair("parameters", toJson(_node.parameterList())), std::make_pair("anonymous", _node.isAnonymous()) }; @@ -573,10 +574,10 @@ bool ASTJsonExporter::visit(EventDefinition const& _node) bool ASTJsonExporter::visit(ErrorDefinition const& _node) { - std::vector> _attributes = { + std::vector> _attributes = { std::make_pair("name", _node.name()), std::make_pair("nameLocation", sourceLocationToString(_node.nameLocation())), - std::make_pair("documentation", _node.documentation() ? toJson(*_node.documentation()) : Json::nullValue), + std::make_pair("documentation", _node.documentation() ? toJson(*_node.documentation()) : Json()), std::make_pair("parameters", toJson(_node.parameterList())) }; if (m_stackState >= CompilerStack::State::AnalysisSuccessful) @@ -588,7 +589,7 @@ bool ASTJsonExporter::visit(ErrorDefinition const& _node) bool ASTJsonExporter::visit(ElementaryTypeName const& _node) { - std::vector> attributes = { + std::vector> attributes = { std::make_pair("name", _node.typeName().toString()), std::make_pair("typeDescriptions", typePointerToJson(_node.annotation().type, true)) }; @@ -648,7 +649,7 @@ bool ASTJsonExporter::visit(ArrayTypeName const& _node) bool ASTJsonExporter::visit(InlineAssembly const& _node) { - std::vector> externalReferences; + std::vector> externalReferences; for (auto const& it: _node.annotation().externalReferences) if (it.first) @@ -657,26 +658,26 @@ bool ASTJsonExporter::visit(InlineAssembly const& _node) inlineAssemblyIdentifierToJson(it) )); - Json::Value externalReferencesJson = Json::arrayValue; + Json externalReferencesJson = Json::array(); std::sort(externalReferences.begin(), externalReferences.end()); - for (Json::Value& it: externalReferences | ranges::views::values) - externalReferencesJson.append(std::move(it)); + for (Json& it: externalReferences | ranges::views::values) + externalReferencesJson.emplace_back(std::move(it)); - std::vector> attributes = { - std::make_pair("AST", Json::Value(yul::AsmJsonConverter(sourceIndexFromLocation(_node.location()))(_node.operations()))), + std::vector> attributes = { + std::make_pair("AST", Json(yul::AsmJsonConverter(sourceIndexFromLocation(_node.location()))(_node.operations()))), std::make_pair("externalReferences", std::move(externalReferencesJson)), std::make_pair("evmVersion", dynamic_cast(_node.dialect()).evmVersion().name()) }; if (_node.flags()) { - Json::Value flags(Json::arrayValue); + Json flags = Json::array(); for (auto const& flag: *_node.flags()) if (flag) - flags.append(*flag); + flags.emplace_back(*flag); else - flags.append(Json::nullValue); + flags.emplace_back(Json()); attributes.emplace_back(std::make_pair("flags", std::move(flags))); } setJsonNode(_node, "InlineAssembly", std::move(attributes)); @@ -743,7 +744,7 @@ bool ASTJsonExporter::visit(WhileStatement const& _node) bool ASTJsonExporter::visit(ForStatement const& _node) { - std::vector> attributes = { + std::vector> attributes = { std::make_pair("initializationExpression", toJsonOrNull(_node.initializationExpression())), std::make_pair("condition", toJsonOrNull(_node.condition())), std::make_pair("loopExpression", toJsonOrNull(_node.loopExpression())), @@ -802,7 +803,7 @@ bool ASTJsonExporter::visit(RevertStatement const& _node) bool ASTJsonExporter::visit(VariableDeclarationStatement const& _node) { - Json::Value varDecs(Json::arrayValue); + Json varDecs = Json::array(); for (auto const& v: _node.declarations()) appendMove(varDecs, idOrNull(v.get())); setJsonNode(_node, "VariableDeclarationStatement", { @@ -823,7 +824,7 @@ bool ASTJsonExporter::visit(ExpressionStatement const& _node) bool ASTJsonExporter::visit(Conditional const& _node) { - std::vector> attributes = { + std::vector> attributes = { std::make_pair("condition", toJson(_node.condition())), std::make_pair("trueExpression", toJson(_node.trueExpression())), std::make_pair("falseExpression", toJson(_node.falseExpression())) @@ -835,7 +836,7 @@ bool ASTJsonExporter::visit(Conditional const& _node) bool ASTJsonExporter::visit(Assignment const& _node) { - std::vector> attributes = { + std::vector> attributes = { std::make_pair("operator", TokenTraits::toString(_node.assignmentOperator())), std::make_pair("leftHandSide", toJson(_node.leftHandSide())), std::make_pair("rightHandSide", toJson(_node.rightHandSide())) @@ -847,8 +848,8 @@ bool ASTJsonExporter::visit(Assignment const& _node) bool ASTJsonExporter::visit(TupleExpression const& _node) { - std::vector> attributes = { - std::make_pair("isInlineArray", Json::Value(_node.isInlineArray())), + std::vector> attributes = { + std::make_pair("isInlineArray", Json(_node.isInlineArray())), std::make_pair("components", toJson(_node.components())), }; appendExpressionAttributes(attributes, _node.annotation()); @@ -858,7 +859,7 @@ bool ASTJsonExporter::visit(TupleExpression const& _node) bool ASTJsonExporter::visit(UnaryOperation const& _node) { - std::vector> attributes = { + std::vector> attributes = { std::make_pair("prefix", _node.isPrefixOperation()), std::make_pair("operator", TokenTraits::toString(_node.getOperator())), std::make_pair("subExpression", toJson(_node.subExpression())) @@ -873,7 +874,7 @@ bool ASTJsonExporter::visit(UnaryOperation const& _node) bool ASTJsonExporter::visit(BinaryOperation const& _node) { - std::vector> attributes = { + std::vector> attributes = { std::make_pair("operator", TokenTraits::toString(_node.getOperator())), std::make_pair("leftExpression", toJson(_node.leftExpression())), std::make_pair("rightExpression", toJson(_node.rightExpression())), @@ -889,10 +890,10 @@ bool ASTJsonExporter::visit(BinaryOperation const& _node) bool ASTJsonExporter::visit(FunctionCall const& _node) { - Json::Value names(Json::arrayValue); + Json names = Json::array(); for (auto const& name: _node.names()) - names.append(Json::Value(*name)); - std::vector> attributes = { + names.push_back(Json(*name)); + std::vector> attributes = { std::make_pair("expression", toJson(_node.expression())), std::make_pair("names", std::move(names)), std::make_pair("nameLocations", sourceLocationsToJson(_node.nameLocations())), @@ -913,11 +914,11 @@ bool ASTJsonExporter::visit(FunctionCall const& _node) bool ASTJsonExporter::visit(FunctionCallOptions const& _node) { - Json::Value names(Json::arrayValue); + Json names = Json::array(); for (auto const& name: _node.names()) - names.append(Json::Value(*name)); + names.emplace_back(Json(*name)); - std::vector> attributes = { + std::vector> attributes = { std::make_pair("expression", toJson(_node.expression())), std::make_pair("names", std::move(names)), std::make_pair("options", toJson(_node.options())), @@ -930,7 +931,7 @@ bool ASTJsonExporter::visit(FunctionCallOptions const& _node) bool ASTJsonExporter::visit(NewExpression const& _node) { - std::vector> attributes = { + std::vector> attributes = { std::make_pair("typeName", toJson(_node.typeName())) }; appendExpressionAttributes(attributes, _node.annotation()); @@ -940,9 +941,9 @@ bool ASTJsonExporter::visit(NewExpression const& _node) bool ASTJsonExporter::visit(MemberAccess const& _node) { - std::vector> attributes = { + std::vector> attributes = { std::make_pair("memberName", _node.memberName()), - std::make_pair("memberLocation", Json::Value(sourceLocationToString(_node.memberLocation()))), + std::make_pair("memberLocation", Json(sourceLocationToString(_node.memberLocation()))), std::make_pair("expression", toJson(_node.expression())), std::make_pair("referencedDeclaration", idOrNull(_node.annotation().referencedDeclaration)), }; @@ -953,7 +954,7 @@ bool ASTJsonExporter::visit(MemberAccess const& _node) bool ASTJsonExporter::visit(IndexAccess const& _node) { - std::vector> attributes = { + std::vector> attributes = { std::make_pair("baseExpression", toJson(_node.baseExpression())), std::make_pair("indexExpression", toJsonOrNull(_node.indexExpression())), }; @@ -964,7 +965,7 @@ bool ASTJsonExporter::visit(IndexAccess const& _node) bool ASTJsonExporter::visit(IndexRangeAccess const& _node) { - std::vector> attributes = { + std::vector> attributes = { std::make_pair("baseExpression", toJson(_node.baseExpression())), std::make_pair("startExpression", toJsonOrNull(_node.startExpression())), std::make_pair("endExpression", toJsonOrNull(_node.endExpression())), @@ -976,9 +977,9 @@ bool ASTJsonExporter::visit(IndexRangeAccess const& _node) bool ASTJsonExporter::visit(Identifier const& _node) { - Json::Value overloads(Json::arrayValue); + Json overloads = Json::array(); for (auto const& dec: _node.annotation().overloadedDeclarations) - overloads.append(nodeId(*dec)); + overloads.emplace_back(nodeId(*dec)); setJsonNode(_node, "Identifier", { std::make_pair("name", _node.name()), std::make_pair("referencedDeclaration", idOrNull(_node.annotation().referencedDeclaration)), @@ -991,7 +992,7 @@ bool ASTJsonExporter::visit(Identifier const& _node) bool ASTJsonExporter::visit(ElementaryTypeNameExpression const& _node) { - std::vector> attributes = { + std::vector> attributes = { std::make_pair("typeName", toJson(_node.type())) }; appendExpressionAttributes(attributes, _node.annotation()); @@ -1001,19 +1002,19 @@ bool ASTJsonExporter::visit(ElementaryTypeNameExpression const& _node) bool ASTJsonExporter::visit(Literal const& _node) { - Json::Value value{_node.value()}; + Json value = _node.value(); if (!util::validateUTF8(_node.value())) - value = Json::nullValue; + value = Json(); Token subdenomination = Token(_node.subDenomination()); - std::vector> attributes = { + std::vector> attributes = { std::make_pair("kind", literalTokenKind(_node.token())), std::make_pair("value", value), std::make_pair("hexValue", util::toHex(util::asBytes(_node.value()))), std::make_pair( "subdenomination", subdenomination == Token::Illegal ? - Json::nullValue : - Json::Value{TokenTraits::toString(subdenomination)} + Json() : + Json(TokenTraits::toString(subdenomination)) ) }; appendExpressionAttributes(attributes, _node.annotation()); @@ -1023,16 +1024,14 @@ bool ASTJsonExporter::visit(Literal const& _node) bool ASTJsonExporter::visit(StructuredDocumentation const& _node) { - Json::Value text{*_node.text()}; - std::vector> attributes = { + Json text = *_node.text(); + std::vector> attributes = { std::make_pair("text", text) }; setJsonNode(_node, "StructuredDocumentation", std::move(attributes)); return false; } - - void ASTJsonExporter::endVisit(EventDefinition const&) { m_inEvent = false; diff --git a/libsolidity/ast/ASTJsonExporter.h b/libsolidity/ast/ASTJsonExporter.h index ff3b94fa28de..c7933120a974 100644 --- a/libsolidity/ast/ASTJsonExporter.h +++ b/libsolidity/ast/ASTJsonExporter.h @@ -28,7 +28,6 @@ #include #include -#include #include #include @@ -60,16 +59,16 @@ class ASTJsonExporter: public ASTConstVisitor ); /// Output the json representation of the AST to _stream. void print(std::ostream& _stream, ASTNode const& _node, util::JsonFormat const& _format); - Json::Value toJson(ASTNode const& _node); + Json toJson(ASTNode const& _node); template - Json::Value toJson(std::vector> const& _nodes) + Json toJson(std::vector> const& _nodes) { - Json::Value ret(Json::arrayValue); + Json ret = Json::array(); for (auto const& n: _nodes) if (n) appendMove(ret, toJson(*n)); else - ret.append(Json::nullValue); + ret.emplace_back(Json()); return ret; } bool visit(SourceUnit const& _node) override; @@ -135,27 +134,27 @@ class ASTJsonExporter: public ASTConstVisitor void setJsonNode( ASTNode const& _node, std::string const& _nodeName, - std::initializer_list>&& _attributes + std::initializer_list>&& _attributes ); void setJsonNode( ASTNode const& _node, std::string const& _nodeName, - std::vector>&& _attributes + std::vector>&& _attributes ); /// Maps source location to an index, if source is valid and a mapping does exist, otherwise returns std::nullopt. std::optional sourceIndexFromLocation(langutil::SourceLocation const& _location) const; std::string sourceLocationToString(langutil::SourceLocation const& _location) const; - Json::Value sourceLocationsToJson(std::vector const& _sourceLocations) const; + Json sourceLocationsToJson(std::vector const& _sourceLocations) const; static std::string namePathToString(std::vector const& _namePath); - static Json::Value idOrNull(ASTNode const* _pt) + static Json idOrNull(ASTNode const* _pt) { - return _pt ? Json::Value(nodeId(*_pt)) : Json::nullValue; + return _pt ? Json(nodeId(*_pt)) : Json(); } - Json::Value toJsonOrNull(ASTNode const* _node) + Json toJsonOrNull(ASTNode const* _node) { - return _node ? toJson(*_node) : Json::nullValue; + return _node ? toJson(*_node) : Json(); } - Json::Value inlineAssemblyIdentifierToJson(std::pair _info) const; + Json inlineAssemblyIdentifierToJson(std::pair _info) const; static std::string location(VariableDeclaration::Location _location); static std::string contractKind(ContractKind _kind); static std::string functionCallKind(FunctionCallKind _kind); @@ -167,7 +166,7 @@ class ASTJsonExporter: public ASTConstVisitor return _node.id(); } template - static Json::Value getContainerIds(Container const& _container, bool _order = false) + static Json getContainerIds(Container const& _container, bool _order = false) { std::vector tmp; @@ -178,28 +177,27 @@ class ASTJsonExporter: public ASTConstVisitor } if (_order) std::sort(tmp.begin(), tmp.end()); - Json::Value json(Json::arrayValue); + Json json = Json::array(); for (int64_t val: tmp) - json.append(val); - + json.emplace_back(val); return json; } - static Json::Value typePointerToJson(Type const* _tp, bool _withoutDataLocation = false); - static Json::Value typePointerToJson(std::optional const& _tps); + static Json typePointerToJson(Type const* _tp, bool _withoutDataLocation = false); + static Json typePointerToJson(std::optional const& _tps); void appendExpressionAttributes( - std::vector> &_attributes, + std::vector> &_attributes, ExpressionAnnotation const& _annotation ); - static void appendMove(Json::Value& _array, Json::Value&& _value) + static void appendMove(Json& _array, Json&& _value) { - solAssert(_array.isArray(), ""); - _array.append(std::move(_value)); + solAssert(_array.is_array(), ""); + _array.emplace_back(std::move(_value)); } CompilerStack::State m_stackState = CompilerStack::State::Empty; ///< Used to only access information that already exists bool m_inEvent = false; ///< whether we are currently inside an event or not - Json::Value m_currentValue; + Json m_currentValue; std::map m_sourceIndices; }; diff --git a/libsolidity/ast/ASTJsonImporter.cpp b/libsolidity/ast/ASTJsonImporter.cpp index 6e6dd9eb5eeb..5c1d4bdc0c30 100644 --- a/libsolidity/ast/ASTJsonImporter.cpp +++ b/libsolidity/ast/ASTJsonImporter.cpp @@ -43,9 +43,9 @@ namespace solidity::frontend using SourceLocation = langutil::SourceLocation; template -ASTPointer ASTJsonImporter::nullOrCast(Json::Value const& _json) +ASTPointer ASTJsonImporter::nullOrCast(Json const& _json) { - if (_json.isNull()) + if (_json.is_null()) return nullptr; else return std::dynamic_pointer_cast(convertJsonToASTNode(_json)); @@ -54,13 +54,13 @@ ASTPointer ASTJsonImporter::nullOrCast(Json::Value const& _json) // ============ public =========================== -std::map> ASTJsonImporter::jsonToSourceUnit(std::map const& _sourceList) +std::map> ASTJsonImporter::jsonToSourceUnit(std::map const& _sourceList) { for (auto const& src: _sourceList) m_sourceNames.emplace_back(std::make_shared(src.first)); for (auto const& srcPair: _sourceList) { - astAssert(!srcPair.second.isNull()); + astAssert(!srcPair.second.is_null()); astAssert(member(srcPair.second,"nodeType") == "SourceUnit", "The 'nodeType' of the highest node must be 'SourceUnit'."); m_sourceUnits[srcPair.first] = createSourceUnit(srcPair.second, srcPair.first); } @@ -71,11 +71,12 @@ std::map> ASTJsonImporter::jsonToSourceUnit( // =========== general creation functions ============== template -ASTPointer ASTJsonImporter::createASTNode(Json::Value const& _node, Args&&... _args) +ASTPointer ASTJsonImporter::createASTNode(Json const& _node, Args&&... _args) { - astAssert(member(_node, "id").isInt64(), "'id'-field must be 64bit integer."); + static_assert(std::is_same_v); + astAssert(member(_node, "id").is_number_integer(), "'id'-field must be 64bit integer."); - int64_t id = _node["id"].asInt64(); + int64_t id = static_cast(_node["id"]); astAssert(m_usedIDs.insert(id).second, "Found duplicate node ID!"); @@ -87,50 +88,50 @@ ASTPointer ASTJsonImporter::createASTNode(Json::Value const& _node, Args&&... return n; } -SourceLocation const ASTJsonImporter::createSourceLocation(Json::Value const& _node) +SourceLocation const ASTJsonImporter::createSourceLocation(Json const& _node) { - astAssert(member(_node, "src").isString(), "'src' must be a string"); + astAssert(member(_node, "src").is_string(), "'src' must be a string"); - return solidity::langutil::parseSourceLocation(_node["src"].asString(), m_sourceNames); + return solidity::langutil::parseSourceLocation(_node["src"].get(), m_sourceNames); } -std::optional> ASTJsonImporter::createSourceLocations(Json::Value const& _node) const +std::optional> ASTJsonImporter::createSourceLocations(Json const& _node) const { std::vector locations; - if (_node.isMember("nameLocations") && _node["nameLocations"].isArray()) + if (_node.contains("nameLocations") && _node["nameLocations"].is_array()) { for (auto const& val: _node["nameLocations"]) - locations.emplace_back(langutil::parseSourceLocation(val.asString(), m_sourceNames)); + locations.emplace_back(langutil::parseSourceLocation(val.get(), m_sourceNames)); return locations; } return std::nullopt; } -SourceLocation ASTJsonImporter::createNameSourceLocation(Json::Value const& _node) +SourceLocation ASTJsonImporter::createNameSourceLocation(Json const& _node) { - astAssert(member(_node, "nameLocation").isString(), "'nameLocation' must be a string"); + astAssert(member(_node, "nameLocation").is_string(), "'nameLocation' must be a string"); - return solidity::langutil::parseSourceLocation(_node["nameLocation"].asString(), m_sourceNames); + return solidity::langutil::parseSourceLocation(_node["nameLocation"].get(), m_sourceNames); } -SourceLocation ASTJsonImporter::createKeyNameSourceLocation(Json::Value const& _node) +SourceLocation ASTJsonImporter::createKeyNameSourceLocation(Json const& _node) { - astAssert(member(_node, "keyNameLocation").isString(), "'keyNameLocation' must be a string"); + astAssert(member(_node, "keyNameLocation").is_string(), "'keyNameLocation' must be a string"); - return solidity::langutil::parseSourceLocation(_node["keyNameLocation"].asString(), m_sourceNames); + return solidity::langutil::parseSourceLocation(_node["keyNameLocation"].get(), m_sourceNames); } -SourceLocation ASTJsonImporter::createValueNameSourceLocation(Json::Value const& _node) +SourceLocation ASTJsonImporter::createValueNameSourceLocation(Json const& _node) { - astAssert(member(_node, "valueNameLocation").isString(), "'valueNameLocation' must be a string"); + astAssert(member(_node, "valueNameLocation").is_string(), "'valueNameLocation' must be a string"); - return solidity::langutil::parseSourceLocation(_node["valueNameLocation"].asString(), m_sourceNames); + return solidity::langutil::parseSourceLocation(_node["valueNameLocation"].get(), m_sourceNames); } template -ASTPointer ASTJsonImporter::convertJsonToASTNode(Json::Value const& _node) +ASTPointer ASTJsonImporter::convertJsonToASTNode(Json const& _node) { ASTPointer ret = std::dynamic_pointer_cast(convertJsonToASTNode(_node)); astAssert(ret, "cast of converted json-node must not be nullptr"); @@ -138,10 +139,10 @@ ASTPointer ASTJsonImporter::convertJsonToASTNode(Json::Value const& _node) } -ASTPointer ASTJsonImporter::convertJsonToASTNode(Json::Value const& _json) +ASTPointer ASTJsonImporter::convertJsonToASTNode(Json const& _json) { - astAssert(_json["nodeType"].isString() && _json.isMember("id"), "JSON-Node needs to have 'nodeType' and 'id' fields."); - std::string nodeType = _json["nodeType"].asString(); + astAssert(_json["nodeType"].is_string() && _json.contains("id"), "JSON-Node needs to have 'nodeType' and 'id' fields."); + std::string nodeType = _json["nodeType"].get(); if (nodeType == "PragmaDirective") return createPragmaDirective(_json); if (nodeType == "ImportDirective") @@ -263,15 +264,15 @@ ASTPointer ASTJsonImporter::convertJsonToASTNode(Json::Value const& _js // ============ functions to instantiate the AST-Nodes from Json-Nodes ============== -ASTPointer ASTJsonImporter::createSourceUnit(Json::Value const& _node, std::string const& _srcName) +ASTPointer ASTJsonImporter::createSourceUnit(Json const& _node, std::string const& _srcName) { std::optional license; - if (_node.isMember("license") && !_node["license"].isNull()) - license = _node["license"].asString(); + if (_node.contains("license") && !_node["license"].is_null()) + license = _node["license"].get(); bool experimentalSolidity = false; - if (_node.isMember("experimentalSolidity") && !_node["experimentalSolidity"].isNull()) - experimentalSolidity = _node["experimentalSolidity"].asBool(); + if (_node.contains("experimentalSolidity") && !_node["experimentalSolidity"].is_null()) + experimentalSolidity = _node["experimentalSolidity"].get(); std::vector> nodes; for (auto& child: member(_node, "nodes")) @@ -282,20 +283,20 @@ ASTPointer ASTJsonImporter::createSourceUnit(Json::Value const& _nod return tmp; } -ASTPointer ASTJsonImporter::createPragmaDirective(Json::Value const& _node) +ASTPointer ASTJsonImporter::createPragmaDirective(Json const& _node) { std::vector tokens; std::vector literals; for (auto const& lit: member(_node, "literals")) { - std::string l = lit.asString(); + std::string l = lit.get(); literals.push_back(l); tokens.push_back(scanSingleToken(l)); } return createASTNode(_node, tokens, literals); } -ASTPointer ASTJsonImporter::createImportDirective(Json::Value const& _node) +ASTPointer ASTJsonImporter::createImportDirective(Json const& _node) { ASTPointer unitAlias = memberAsASTString(_node, "unitAlias"); ASTPointer path = memberAsASTString(_node, "file"); @@ -303,11 +304,11 @@ ASTPointer ASTJsonImporter::createImportDirective(Json::Value c for (auto& tuple: member(_node, "symbolAliases")) { - astAssert(tuple["local"].isNull() || tuple["local"].isString(), "expected 'local' to be a string or null!"); + astAssert(tuple["local"].is_null() || tuple["local"].is_string(), "expected 'local' to be a string or null!"); symbolAliases.push_back({ createIdentifier(tuple["foreign"]), - tuple["local"].isNull() ? nullptr : std::make_shared(tuple["local"].asString()), + tuple["local"].is_null() ? nullptr : std::make_shared(tuple["local"].get()), createSourceLocation(tuple["foreign"])} ); } @@ -319,15 +320,15 @@ ASTPointer ASTJsonImporter::createImportDirective(Json::Value c std::move(symbolAliases) ); - astAssert(_node["absolutePath"].isString(), "Expected 'absolutePath' to be a string!"); + astAssert(_node["absolutePath"].is_string(), "Expected 'absolutePath' to be a string!"); - tmp->annotation().absolutePath = _node["absolutePath"].asString(); + tmp->annotation().absolutePath = _node["absolutePath"].get(); return tmp; } -ASTPointer ASTJsonImporter::createContractDefinition(Json::Value const& _node) +ASTPointer ASTJsonImporter::createContractDefinition(Json const& _node) { - astAssert(_node["name"].isString(), "Expected 'name' to be a string!"); + astAssert(_node["name"].is_string(), "Expected 'name' to be a string!"); std::vector> baseContracts; @@ -341,9 +342,9 @@ ASTPointer ASTJsonImporter::createContractDefinition(Json::V return createASTNode( _node, - std::make_shared(_node["name"].asString()), + std::make_shared(_node["name"].get()), createNameSourceLocation(_node), - _node["documentation"].isNull() ? nullptr : createDocumentation(member(_node, "documentation")), + (_node.contains("documentation") && !_node["documentation"].is_null()) ? createDocumentation(member(_node, "documentation")) : nullptr, baseContracts, subNodes, contractKind(_node), @@ -351,14 +352,14 @@ ASTPointer ASTJsonImporter::createContractDefinition(Json::V ); } -ASTPointer ASTJsonImporter::createIdentifierPath(Json::Value const& _node) +ASTPointer ASTJsonImporter::createIdentifierPath(Json const& _node) { - astAssert(_node["name"].isString(), "Expected 'name' to be a string!"); + astAssert(_node["name"].is_string(), "Expected 'name' to be a string!"); std::vector namePath; std::vector namePathLocations; std::vector strs; - std::string nameString = member(_node, "name").asString(); + std::string nameString = member(_node, "name").get(); boost::algorithm::split(strs, nameString, boost::is_any_of(".")); astAssert(!strs.empty(), "Expected at least one element in IdentifierPath."); for (std::string s: strs) @@ -367,9 +368,9 @@ ASTPointer ASTJsonImporter::createIdentifierPath(Json::Value con namePath.emplace_back(s); } - if (_node.isMember("nameLocations") && _node["nameLocations"].isArray()) + if (_node.contains("nameLocations") && _node["nameLocations"].is_array()) for (auto const& val: _node["nameLocations"]) - namePathLocations.emplace_back(langutil::parseSourceLocation(val.asString(), m_sourceNames)); + namePathLocations.emplace_back(langutil::parseSourceLocation(val.get(), m_sourceNames)); else namePathLocations.resize(namePath.size()); @@ -385,7 +386,7 @@ ASTPointer ASTJsonImporter::createIdentifierPath(Json::Value con ); } -ASTPointer ASTJsonImporter::createInheritanceSpecifier(Json::Value const& _node) +ASTPointer ASTJsonImporter::createInheritanceSpecifier(Json const& _node) { std::vector> arguments; for (auto& arg: member(_node, "arguments")) @@ -393,36 +394,36 @@ ASTPointer ASTJsonImporter::createInheritanceSpecifier(Jso return createASTNode( _node, createIdentifierPath(member(_node, "baseName")), - member(_node, "arguments").isNull() ? nullptr : std::make_unique>>(arguments) + member(_node, "arguments").is_null() ? nullptr : std::make_unique>>(arguments) ); } -ASTPointer ASTJsonImporter::createUsingForDirective(Json::Value const& _node) +ASTPointer ASTJsonImporter::createUsingForDirective(Json const& _node) { std::vector> functions; std::vector> operators; - if (_node.isMember("libraryName")) + if (_node.contains("libraryName")) { - astAssert(!_node["libraryName"].isArray()); - astAssert(!_node["libraryName"]["operator"]); + astAssert(!_node["libraryName"].is_array()); + astAssert(!_node["libraryName"].contains("operator")); functions.emplace_back(createIdentifierPath(_node["libraryName"])); operators.emplace_back(std::nullopt); } - else if (_node.isMember("functionList")) - for (Json::Value const& function: _node["functionList"]) + else if (_node.contains("functionList")) + for (Json const& function: _node["functionList"]) { - if (function.isMember("function")) + if (function.contains("function")) { - astAssert(!function.isMember("operator")); - astAssert(!function.isMember("definition")); + astAssert(!function.contains("operator")); + astAssert(!function.contains("definition")); functions.emplace_back(createIdentifierPath(function["function"])); operators.emplace_back(std::nullopt); } else { - astAssert(function.isMember("operator")); - astAssert(function.isMember("definition")); + astAssert(function.contains("operator")); + astAssert(function.contains("definition")); Token const operatorName = scanSingleToken(function["operator"]); astAssert(util::contains(frontend::userDefinableOperators, operatorName)); @@ -436,13 +437,13 @@ ASTPointer ASTJsonImporter::createUsingForDirective(Json::Val _node, std::move(functions), std::move(operators), - !_node.isMember("libraryName"), - _node["typeName"].isNull() ? nullptr : convertJsonToASTNode(_node["typeName"]), + !_node.contains("libraryName"), + (_node.contains("typeName") && !_node["typeName"].is_null()) ? convertJsonToASTNode(_node["typeName"]) : nullptr, memberAsBool(_node, "global") ); } -ASTPointer ASTJsonImporter::createStructDefinition(Json::Value const& _node) +ASTPointer ASTJsonImporter::createStructDefinition(Json const& _node) { std::vector> members; for (auto& member: _node["members"]) @@ -452,11 +453,11 @@ ASTPointer ASTJsonImporter::createStructDefinition(Json::Value const& _ memberAsASTString(_node, "name"), createNameSourceLocation(_node), members, - _node["documentation"].isNull() ? nullptr : createDocumentation(member(_node, "documentation")) + (_node.contains("documentation") && !_node["documentation"].is_null()) ? createDocumentation(member(_node, "documentation")) : nullptr ); } -ASTPointer ASTJsonImporter::createEnumDefinition(Json::Value const& _node) +ASTPointer ASTJsonImporter::createEnumDefinition(Json const& _node) { std::vector> members; for (auto& member: _node["members"]) @@ -466,11 +467,11 @@ ASTPointer ASTJsonImporter::createEnumDefinition(Json::Value con memberAsASTString(_node, "name"), createNameSourceLocation(_node), members, - _node["documentation"].isNull() ? nullptr : createDocumentation(member(_node, "documentation")) + (_node.contains("documentation") && !_node["documentation"].is_null()) ? createDocumentation(member(_node, "documentation")) : nullptr ); } -ASTPointer ASTJsonImporter::createEnumValue(Json::Value const& _node) +ASTPointer ASTJsonImporter::createEnumValue(Json const& _node) { return createASTNode( _node, @@ -478,7 +479,7 @@ ASTPointer ASTJsonImporter::createEnumValue(Json::Value const& _node) ); } -ASTPointer ASTJsonImporter::createUserDefinedValueTypeDefinition(Json::Value const& _node) +ASTPointer ASTJsonImporter::createUserDefinedValueTypeDefinition(Json const& _node) { return createASTNode( _node, @@ -488,7 +489,7 @@ ASTPointer ASTJsonImporter::createUserDefinedVal ); } -ASTPointer ASTJsonImporter::createParameterList(Json::Value const& _node) +ASTPointer ASTJsonImporter::createParameterList(Json const& _node) { std::vector> parameters; for (auto& param: _node["parameters"]) @@ -499,12 +500,13 @@ ASTPointer ASTJsonImporter::createParameterList(Json::Value const ); } -ASTPointer ASTJsonImporter::createOverrideSpecifier(Json::Value const& _node) +ASTPointer ASTJsonImporter::createOverrideSpecifier(Json const& _node) { std::vector> overrides; - for (auto& param: _node["overrides"]) - overrides.push_back(createIdentifierPath(param)); + if ( _node.contains("overrides")) + for (auto& param: _node["overrides"]) + overrides.push_back(createIdentifierPath(param)); return createASTNode( _node, @@ -512,13 +514,13 @@ ASTPointer ASTJsonImporter::createOverrideSpecifier(Json::Val ); } -ASTPointer ASTJsonImporter::createFunctionDefinition(Json::Value const& _node) +ASTPointer ASTJsonImporter::createFunctionDefinition(Json const& _node) { - astAssert(_node["kind"].isString(), "Expected 'kind' to be a string!"); + astAssert(_node["kind"].is_string(), "Expected 'kind' to be a string!"); Token kind; bool freeFunction = false; - std::string kindStr = member(_node, "kind").asString(); + std::string kindStr = member(_node, "kind").get(); if (kindStr == "constructor") kind = Token::Constructor; @@ -555,8 +557,8 @@ ASTPointer ASTJsonImporter::createFunctionDefinition(Json::V freeFunction, kind, memberAsBool(_node, "virtual"), - _node["overrides"].isNull() ? nullptr : createOverrideSpecifier(member(_node, "overrides")), - _node["documentation"].isNull() ? nullptr : createDocumentation(member(_node, "documentation")), + (_node.contains("overrides") && !_node["overrides"].is_null()) ? createOverrideSpecifier(member(_node, "overrides")) : nullptr, + (_node.contains("documentation") && !_node["documentation"].is_null()) ? createDocumentation(member(_node, "documentation")) : nullptr, createParameterList(member(_node, "parameters")), modifiers, createParameterList(member(_node, "returnParameters")), @@ -564,13 +566,13 @@ ASTPointer ASTJsonImporter::createFunctionDefinition(Json::V ); } -ASTPointer ASTJsonImporter::createVariableDeclaration(Json::Value const& _node) +ASTPointer ASTJsonImporter::createVariableDeclaration(Json const& _node) { - astAssert(_node["name"].isString(), "Expected 'name' to be a string!"); + astAssert(_node["name"].is_string(), "Expected 'name' to be a string!"); VariableDeclaration::Mutability mutability{}; - astAssert(member(_node, "mutability").isString(), "'mutability' expected to be string."); - std::string const mutabilityStr = member(_node, "mutability").asString(); + astAssert(member(_node, "mutability").is_string(), "'mutability' expected to be string."); + std::string const mutabilityStr = member(_node, "mutability").get(); if (mutabilityStr == "constant") { mutability = VariableDeclaration::Mutability::Constant; @@ -590,33 +592,33 @@ ASTPointer ASTJsonImporter::createVariableDeclaration(Json: return createASTNode( _node, nullOrCast(member(_node, "typeName")), - std::make_shared(member(_node, "name").asString()), + std::make_shared(member(_node, "name").get()), createNameSourceLocation(_node), nullOrCast(member(_node, "value")), visibility(_node), - _node["documentation"].isNull() ? nullptr : createDocumentation(member(_node, "documentation")), - _node.isMember("indexed") ? memberAsBool(_node, "indexed") : false, + (_node.contains("documentation") && !_node["documentation"].is_null()) ? createDocumentation(member(_node, "documentation")) : nullptr, + (_node.contains("indexed") && !_node["indexed"].is_null()) ? memberAsBool(_node, "indexed") : false, mutability, - _node["overrides"].isNull() ? nullptr : createOverrideSpecifier(member(_node, "overrides")), + (_node.contains("overrides") && !_node["overrides"].is_null()) ? createOverrideSpecifier(member(_node, "overrides")) : nullptr, location(_node) ); } -ASTPointer ASTJsonImporter::createModifierDefinition(Json::Value const& _node) +ASTPointer ASTJsonImporter::createModifierDefinition(Json const& _node) { return createASTNode( _node, memberAsASTString(_node, "name"), createNameSourceLocation(_node), - _node["documentation"].isNull() ? nullptr : createDocumentation(member(_node, "documentation")), + (_node.contains("documentation") && !_node["documentation"].is_null()) ? createDocumentation(member(_node, "documentation")) : nullptr, createParameterList(member(_node, "parameters")), memberAsBool(_node, "virtual"), - _node["overrides"].isNull() ? nullptr : createOverrideSpecifier(member(_node, "overrides")), - _node["body"].isNull() ? nullptr: createBlock(member(_node, "body"), false) + (_node.contains("overrides") && !_node["overrides"].is_null()) ? createOverrideSpecifier(member(_node, "overrides")) : nullptr, + (_node.contains("body") && !_node["body"].is_null()) ? createBlock(member(_node, "body"), false) : nullptr ); } -ASTPointer ASTJsonImporter::createModifierInvocation(Json::Value const& _node) +ASTPointer ASTJsonImporter::createModifierInvocation(Json const& _node) { std::vector> arguments; for (auto& arg: member(_node, "arguments")) @@ -624,53 +626,53 @@ ASTPointer ASTJsonImporter::createModifierInvocation(Json::V return createASTNode( _node, createIdentifierPath(member(_node, "modifierName")), - member(_node, "arguments").isNull() ? nullptr : std::make_unique>>(arguments) + member(_node, "arguments").is_null() ? nullptr : std::make_unique>>(arguments) ); } -ASTPointer ASTJsonImporter::createEventDefinition(Json::Value const& _node) +ASTPointer ASTJsonImporter::createEventDefinition(Json const& _node) { return createASTNode( _node, memberAsASTString(_node, "name"), createNameSourceLocation(_node), - _node["documentation"].isNull() ? nullptr : createDocumentation(member(_node, "documentation")), + (_node.contains("documentation") && !_node["documentation"].is_null()) ? createDocumentation(member(_node, "documentation")) : nullptr, createParameterList(member(_node, "parameters")), memberAsBool(_node, "anonymous") ); } -ASTPointer ASTJsonImporter::createErrorDefinition(Json::Value const& _node) +ASTPointer ASTJsonImporter::createErrorDefinition(Json const& _node) { return createASTNode( _node, memberAsASTString(_node, "name"), createNameSourceLocation(_node), - _node["documentation"].isNull() ? nullptr : createDocumentation(member(_node, "documentation")), + (_node.contains("documentation") && !_node["documentation"].is_null()) ? createDocumentation(member(_node, "documentation")) : nullptr, createParameterList(member(_node, "parameters")) ); } -ASTPointer ASTJsonImporter::createElementaryTypeName(Json::Value const& _node) +ASTPointer ASTJsonImporter::createElementaryTypeName(Json const& _node) { unsigned short firstNum; unsigned short secondNum; - astAssert(_node["name"].isString(), "Expected 'name' to be a string!"); + astAssert(_node["name"].is_string(), "Expected 'name' to be a string!"); - std::string name = member(_node, "name").asString(); + std::string name = member(_node, "name").get(); Token token; std::tie(token, firstNum, secondNum) = TokenTraits::fromIdentifierOrKeyword(name); ElementaryTypeNameToken elem(token, firstNum, secondNum); std::optional mutability = {}; - if (_node.isMember("stateMutability")) + if (_node.contains("stateMutability")) mutability = stateMutability(_node); return createASTNode(_node, elem, mutability); } -ASTPointer ASTJsonImporter::createUserDefinedTypeName(Json::Value const& _node) +ASTPointer ASTJsonImporter::createUserDefinedTypeName(Json const& _node) { return createASTNode( _node, @@ -678,7 +680,7 @@ ASTPointer ASTJsonImporter::createUserDefinedTypeName(Json: ); } -ASTPointer ASTJsonImporter::createFunctionTypeName(Json::Value const& _node) +ASTPointer ASTJsonImporter::createFunctionTypeName(Json const& _node) { return createASTNode( _node, @@ -689,7 +691,7 @@ ASTPointer ASTJsonImporter::createFunctionTypeName(Json::Value ); } -ASTPointer ASTJsonImporter::createMapping(Json::Value const& _node) +ASTPointer ASTJsonImporter::createMapping(Json const& _node) { return createASTNode( _node, @@ -702,7 +704,7 @@ ASTPointer ASTJsonImporter::createMapping(Json::Value const& _node) ); } -ASTPointer ASTJsonImporter::createArrayTypeName(Json::Value const& _node) +ASTPointer ASTJsonImporter::createArrayTypeName(Json const& _node) { return createASTNode( _node, @@ -711,24 +713,24 @@ ASTPointer ASTJsonImporter::createArrayTypeName(Json::Value const ); } -ASTPointer ASTJsonImporter::createInlineAssembly(Json::Value const& _node) +ASTPointer ASTJsonImporter::createInlineAssembly(Json const& _node) { - astAssert(_node["evmVersion"].isString(), "Expected evmVersion to be a string!"); - auto evmVersion = langutil::EVMVersion::fromString(_node["evmVersion"].asString()); + astAssert(_node["evmVersion"].is_string(), "Expected evmVersion to be a string!"); + auto evmVersion = langutil::EVMVersion::fromString(_node["evmVersion"].get()); astAssert(evmVersion.has_value(), "Invalid EVM version!"); astAssert(m_evmVersion == evmVersion, "Imported tree evm version differs from configured evm version!"); yul::Dialect const& dialect = yul::EVMDialect::strictAssemblyForEVM(evmVersion.value()); ASTPointer>> flags; - if (_node.isMember("flags")) + if (_node.contains("flags")) { flags = std::make_shared>>(); - Json::Value const& flagsNode = _node["flags"]; - astAssert(flagsNode.isArray(), "Assembly flags must be an array."); - for (Json::ArrayIndex i = 0; i < flagsNode.size(); ++i) + Json const& flagsNode = _node["flags"]; + astAssert(flagsNode.is_array(), "Assembly flags must be an array."); + for (auto const& flag: flagsNode) { - astAssert(flagsNode[i].isString(), "Assembly flag must be a string."); - flags->emplace_back(std::make_shared(flagsNode[i].asString())); + astAssert(flag.is_string(), "Assembly flag must be a string."); + flags->emplace_back(std::make_shared(flag.get())); } } std::shared_ptr operations = std::make_shared(yul::AsmJsonImporter(m_sourceNames).createBlock(member(_node, "AST"))); @@ -741,7 +743,7 @@ ASTPointer ASTJsonImporter::createInlineAssembly(Json::Value con ); } -ASTPointer ASTJsonImporter::createBlock(Json::Value const& _node, bool _unchecked) +ASTPointer ASTJsonImporter::createBlock(Json const& _node, bool _unchecked) { std::vector> statements; for (auto& stat: member(_node, "statements")) @@ -754,7 +756,7 @@ ASTPointer ASTJsonImporter::createBlock(Json::Value const& _node, bool _u ); } -ASTPointer ASTJsonImporter::createPlaceholderStatement(Json::Value const& _node) +ASTPointer ASTJsonImporter::createPlaceholderStatement(Json const& _node) { return createASTNode( _node, @@ -762,7 +764,7 @@ ASTPointer ASTJsonImporter::createPlaceholderStatement(Jso ); } -ASTPointer ASTJsonImporter::createIfStatement(Json::Value const& _node) +ASTPointer ASTJsonImporter::createIfStatement(Json const& _node) { return createASTNode( _node, @@ -773,7 +775,7 @@ ASTPointer ASTJsonImporter::createIfStatement(Json::Value const& _ ); } -ASTPointer ASTJsonImporter::createTryCatchClause(Json::Value const& _node) +ASTPointer ASTJsonImporter::createTryCatchClause(Json const& _node) { return createASTNode( _node, @@ -783,7 +785,7 @@ ASTPointer ASTJsonImporter::createTryCatchClause(Json::Value con ); } -ASTPointer ASTJsonImporter::createTryStatement(Json::Value const& _node) +ASTPointer ASTJsonImporter::createTryStatement(Json const& _node) { std::vector> clauses; @@ -798,7 +800,7 @@ ASTPointer ASTJsonImporter::createTryStatement(Json::Value const& ); } -ASTPointer ASTJsonImporter::createWhileStatement(Json::Value const& _node, bool _isDoWhile=false) +ASTPointer ASTJsonImporter::createWhileStatement(Json const& _node, bool _isDoWhile=false) { return createASTNode( _node, @@ -809,7 +811,7 @@ ASTPointer ASTJsonImporter::createWhileStatement(Json::Value con ); } -ASTPointer ASTJsonImporter::createForStatement(Json::Value const& _node) +ASTPointer ASTJsonImporter::createForStatement(Json const& _node) { return createASTNode( _node, @@ -821,7 +823,7 @@ ASTPointer ASTJsonImporter::createForStatement(Json::Value const& ); } -ASTPointer ASTJsonImporter::createContinue(Json::Value const& _node) +ASTPointer ASTJsonImporter::createContinue(Json const& _node) { return createASTNode( _node, @@ -829,7 +831,7 @@ ASTPointer ASTJsonImporter::createContinue(Json::Value const& _node) ); } -ASTPointer ASTJsonImporter::createBreak(Json::Value const& _node) +ASTPointer ASTJsonImporter::createBreak(Json const& _node) { return createASTNode( _node, @@ -837,7 +839,7 @@ ASTPointer ASTJsonImporter::createBreak(Json::Value const& _node) ); } -ASTPointer ASTJsonImporter::createReturn(Json::Value const& _node) +ASTPointer ASTJsonImporter::createReturn(Json const& _node) { return createASTNode( _node, @@ -846,7 +848,7 @@ ASTPointer ASTJsonImporter::createReturn(Json::Value const& _node) ); } -ASTPointer ASTJsonImporter::createThrow(Json::Value const& _node) +ASTPointer ASTJsonImporter::createThrow(Json const& _node) { return createASTNode( _node, @@ -854,7 +856,7 @@ ASTPointer ASTJsonImporter::createThrow(Json::Value const& _node) ); } -ASTPointer ASTJsonImporter::createEmitStatement(Json::Value const& _node) +ASTPointer ASTJsonImporter::createEmitStatement(Json const& _node) { return createASTNode( _node, @@ -863,7 +865,7 @@ ASTPointer ASTJsonImporter::createEmitStatement(Json::Value const ); } -ASTPointer ASTJsonImporter::createRevertStatement(Json::Value const& _node) +ASTPointer ASTJsonImporter::createRevertStatement(Json const& _node) { return createASTNode( _node, @@ -872,11 +874,11 @@ ASTPointer ASTJsonImporter::createRevertStatement(Json::Value c ); } -ASTPointer ASTJsonImporter::createVariableDeclarationStatement(Json::Value const& _node) +ASTPointer ASTJsonImporter::createVariableDeclarationStatement(Json const& _node) { std::vector> variables; for (auto& var: member(_node, "declarations")) - variables.push_back(var.isNull() ? nullptr : createVariableDeclaration(var)); //unnamed components are empty pointers + variables.push_back(var.is_null() ? nullptr : createVariableDeclaration(var)); //unnamed components are empty pointers return createASTNode( _node, nullOrASTString(_node, "documentation"), @@ -885,7 +887,7 @@ ASTPointer ASTJsonImporter::createVariableDeclarat ); } -ASTPointer ASTJsonImporter::createExpressionStatement(Json::Value const& _node) +ASTPointer ASTJsonImporter::createExpressionStatement(Json const& _node) { return createASTNode( _node, @@ -894,7 +896,7 @@ ASTPointer ASTJsonImporter::createExpressionStatement(Json: ); } -ASTPointer ASTJsonImporter::createConditional(Json::Value const& _node) +ASTPointer ASTJsonImporter::createConditional(Json const& _node) { return createASTNode( _node, @@ -904,7 +906,7 @@ ASTPointer ASTJsonImporter::createConditional(Json::Value const& _ ); } -ASTPointer ASTJsonImporter::createAssignment(Json::Value const& _node) +ASTPointer ASTJsonImporter::createAssignment(Json const& _node) { return createASTNode( _node, @@ -914,7 +916,7 @@ ASTPointer ASTJsonImporter::createAssignment(Json::Value const& _no ); } -ASTPointer ASTJsonImporter::createTupleExpression(Json::Value const& _node) +ASTPointer ASTJsonImporter::createTupleExpression(Json const& _node) { std::vector> components; for (auto& comp: member(_node, "components")) @@ -926,7 +928,7 @@ ASTPointer ASTJsonImporter::createTupleExpression(Json::Value c ); } -ASTPointer ASTJsonImporter::createUnaryOperation(Json::Value const& _node) +ASTPointer ASTJsonImporter::createUnaryOperation(Json const& _node) { return createASTNode( _node, @@ -936,7 +938,7 @@ ASTPointer ASTJsonImporter::createUnaryOperation(Json::Value con ); } -ASTPointer ASTJsonImporter::createBinaryOperation(Json::Value const& _node) +ASTPointer ASTJsonImporter::createBinaryOperation(Json const& _node) { return createASTNode( _node, @@ -946,7 +948,7 @@ ASTPointer ASTJsonImporter::createBinaryOperation(Json::Value c ); } -ASTPointer ASTJsonImporter::createFunctionCall(Json::Value const& _node) +ASTPointer ASTJsonImporter::createFunctionCall(Json const& _node) { std::vector> arguments; for (auto& arg: member(_node, "arguments")) @@ -954,8 +956,8 @@ ASTPointer ASTJsonImporter::createFunctionCall(Json::Value const& std::vector> names; for (auto& name: member(_node, "names")) { - astAssert(name.isString(), "Expected 'names' members to be strings!"); - names.push_back(std::make_shared(name.asString())); + astAssert(name.is_string(), "Expected 'names' members to be strings!"); + names.push_back(std::make_shared(name.get())); } std::optional> sourceLocations = createSourceLocations(_node); @@ -971,7 +973,7 @@ ASTPointer ASTJsonImporter::createFunctionCall(Json::Value const& ); } -ASTPointer ASTJsonImporter::createFunctionCallOptions(Json::Value const& _node) +ASTPointer ASTJsonImporter::createFunctionCallOptions(Json const& _node) { std::vector> options; for (auto& option: member(_node, "options")) @@ -979,8 +981,8 @@ ASTPointer ASTJsonImporter::createFunctionCallOptions(Json: std::vector> names; for (auto& name: member(_node, "names")) { - astAssert(name.isString(), "Expected 'names' members to be strings!"); - names.push_back(std::make_shared(name.asString())); + astAssert(name.is_string(), "Expected 'names' members to be strings!"); + names.push_back(std::make_shared(name.get())); } return createASTNode( @@ -991,7 +993,7 @@ ASTPointer ASTJsonImporter::createFunctionCallOptions(Json: ); } -ASTPointer ASTJsonImporter::createNewExpression(Json::Value const& _node) +ASTPointer ASTJsonImporter::createNewExpression(Json const& _node) { return createASTNode( _node, @@ -999,11 +1001,11 @@ ASTPointer ASTJsonImporter::createNewExpression(Json::Value const ); } -ASTPointer ASTJsonImporter::createMemberAccess(Json::Value const& _node) +ASTPointer ASTJsonImporter::createMemberAccess(Json const& _node) { SourceLocation memberLocation; - if (member(_node, "memberLocation").isString()) - memberLocation = solidity::langutil::parseSourceLocation(_node["memberLocation"].asString(), m_sourceNames); + if (member(_node, "memberLocation").is_string()) + memberLocation = solidity::langutil::parseSourceLocation(_node["memberLocation"].get(), m_sourceNames); return createASTNode( _node, @@ -1013,7 +1015,7 @@ ASTPointer ASTJsonImporter::createMemberAccess(Json::Value const& ); } -ASTPointer ASTJsonImporter::createIndexAccess(Json::Value const& _node) +ASTPointer ASTJsonImporter::createIndexAccess(Json const& _node) { return createASTNode( _node, @@ -1022,7 +1024,7 @@ ASTPointer ASTJsonImporter::createIndexAccess(Json::Value const& _n ); } -ASTPointer ASTJsonImporter::createIndexRangeAccess(Json::Value const& _node) +ASTPointer ASTJsonImporter::createIndexRangeAccess(Json const& _node) { return createASTNode( _node, @@ -1032,12 +1034,12 @@ ASTPointer ASTJsonImporter::createIndexRangeAccess(Json::Value ); } -ASTPointer ASTJsonImporter::createIdentifier(Json::Value const& _node) +ASTPointer ASTJsonImporter::createIdentifier(Json const& _node) { return createASTNode(_node, memberAsASTString(_node, "name")); } -ASTPointer ASTJsonImporter::createElementaryTypeNameExpression(Json::Value const& _node) +ASTPointer ASTJsonImporter::createElementaryTypeNameExpression(Json const& _node) { return createASTNode( _node, @@ -1045,116 +1047,116 @@ ASTPointer ASTJsonImporter::createElementaryTypeNa ); } -ASTPointer ASTJsonImporter::createLiteral(Json::Value const& _node) +ASTPointer ASTJsonImporter::createLiteral(Json const& _node) { static std::string const valStr = "value"; static std::string const hexValStr = "hexValue"; - astAssert(member(_node, valStr).isString() || member(_node, hexValStr).isString(), "Literal-value is unset."); + astAssert(member(_node, valStr).is_string() || member(_node, hexValStr).is_string(), "Literal-value is unset."); - ASTPointer value = _node.isMember(hexValStr) ? - std::make_shared(util::asString(util::fromHex(_node[hexValStr].asString()))) : - std::make_shared(_node[valStr].asString()); + ASTPointer value = _node.contains(hexValStr) ? + std::make_shared(util::asString(util::fromHex(_node[hexValStr].get()))) : + std::make_shared(_node[valStr].get()); return createASTNode( _node, literalTokenKind(_node), value, - member(_node, "subdenomination").isNull() ? Literal::SubDenomination::None : subdenomination(_node) + member(_node, "subdenomination").is_null() ? Literal::SubDenomination::None : subdenomination(_node) ); } -ASTPointer ASTJsonImporter::createDocumentation(Json::Value const& _node) +ASTPointer ASTJsonImporter::createDocumentation(Json const& _node) { static std::string const textString = "text"; - astAssert(member(_node, textString).isString(), "'text' must be a string"); + astAssert(member(_node, textString).is_string(), "'text' must be a string"); return createASTNode( _node, - std::make_shared(_node[textString].asString()) + std::make_shared(_node[textString].get()) ); } // ===== helper functions ========== -Json::Value ASTJsonImporter::member(Json::Value const& _node, std::string const& _name) +Json ASTJsonImporter::member(Json const& _node, std::string const& _name) { - if (!_node.isMember(_name)) - return Json::nullValue; + if (!_node.contains(_name)) + return Json(); return _node[_name]; } -Token ASTJsonImporter::scanSingleToken(Json::Value const& _node) +Token ASTJsonImporter::scanSingleToken(Json const& _node) { - langutil::CharStream charStream(_node.asString(), ""); + langutil::CharStream charStream(_node.get(), ""); langutil::Scanner scanner{charStream}; astAssert(scanner.peekNextToken() == Token::EOS, "Token string is too long."); return scanner.currentToken(); } -ASTPointer ASTJsonImporter::nullOrASTString(Json::Value const& _json, std::string const& _name) +ASTPointer ASTJsonImporter::nullOrASTString(Json const& _json, std::string const& _name) { - return _json[_name].isString() ? memberAsASTString(_json, _name) : nullptr; + return (_json.contains(_name) && (_json[_name].is_string())) ? memberAsASTString(_json, _name) : nullptr; } -ASTPointer ASTJsonImporter::memberAsASTString(Json::Value const& _node, std::string const& _name) +ASTPointer ASTJsonImporter::memberAsASTString(Json const& _node, std::string const& _name) { - Json::Value value = member(_node, _name); - astAssert(value.isString(), "field " + _name + " must be of type string."); - return std::make_shared(_node[_name].asString()); + Json value = member(_node, _name); + astAssert(value.is_string(), "field " + _name + " must be of type string."); + return std::make_shared(_node[_name].get()); } -bool ASTJsonImporter::memberAsBool(Json::Value const& _node, std::string const& _name) +bool ASTJsonImporter::memberAsBool(Json const& _node, std::string const& _name) { - Json::Value value = member(_node, _name); - astAssert(value.isBool(), "field " + _name + " must be of type boolean."); - return _node[_name].asBool(); + Json value = member(_node, _name); + astAssert(value.is_boolean(), "field " + _name + " must be of type boolean."); + return _node[_name].get(); } // =========== JSON to definition helpers ======================= -ContractKind ASTJsonImporter::contractKind(Json::Value const& _node) +ContractKind ASTJsonImporter::contractKind(Json const& _node) { ContractKind kind; - astAssert(!member(_node, "contractKind").isNull(), "'Contract-kind' can not be null."); - if (_node["contractKind"].asString() == "interface") + astAssert(!member(_node, "contractKind").is_null(), "'Contract-kind' can not be null."); + if (_node["contractKind"].get() == "interface") kind = ContractKind::Interface; - else if (_node["contractKind"].asString() == "contract") + else if (_node["contractKind"].get() == "contract") kind = ContractKind::Contract; - else if (_node["contractKind"].asString() == "library") + else if (_node["contractKind"].get() == "library") kind = ContractKind::Library; else astAssert(false, "Unknown ContractKind"); return kind; } -Token ASTJsonImporter::literalTokenKind(Json::Value const& _node) +Token ASTJsonImporter::literalTokenKind(Json const& _node) { - astAssert(member(_node, "kind").isString(), "Token-'kind' expected to be a string."); + astAssert(member(_node, "kind").is_string(), "Token-'kind' expected to be a string."); Token tok; - if (_node["kind"].asString() == "number") + if (_node["kind"].get() == "number") tok = Token::Number; - else if (_node["kind"].asString() == "string") + else if (_node["kind"].get() == "string") tok = Token::StringLiteral; - else if (_node["kind"].asString() == "unicodeString") + else if (_node["kind"].get() == "unicodeString") tok = Token::UnicodeStringLiteral; - else if (_node["kind"].asString() == "hexString") + else if (_node["kind"].get() == "hexString") tok = Token::HexStringLiteral; - else if (_node["kind"].asString() == "bool") - tok = (member(_node, "value").asString() == "true") ? Token::TrueLiteral : Token::FalseLiteral; + else if (_node["kind"].get() == "bool") + tok = (member(_node, "value").get() == "true") ? Token::TrueLiteral : Token::FalseLiteral; else astAssert(false, "Unknown kind of literalString"); return tok; } -Visibility ASTJsonImporter::visibility(Json::Value const& _node) +Visibility ASTJsonImporter::visibility(Json const& _node) { - Json::Value visibility = member(_node, "visibility"); - astAssert(visibility.isString(), "'visibility' expected to be a string."); + Json visibility = member(_node, "visibility"); + astAssert(visibility.is_string(), "'visibility' expected to be a string."); - std::string const visibilityStr = visibility.asString(); + std::string const visibilityStr = visibility.get(); if (visibilityStr == "default") return Visibility::Default; @@ -1173,12 +1175,12 @@ Visibility ASTJsonImporter::visibility(Json::Value const& _node) util::unreachable(); } -VariableDeclaration::Location ASTJsonImporter::location(Json::Value const& _node) +VariableDeclaration::Location ASTJsonImporter::location(Json const& _node) { - Json::Value storageLoc = member(_node, "storageLocation"); - astAssert(storageLoc.isString(), "'storageLocation' expected to be a string."); + Json storageLoc = member(_node, "storageLocation"); + astAssert(storageLoc.is_string(), "'storageLocation' expected to be a string."); - std::string const storageLocStr = storageLoc.asString(); + std::string const storageLocStr = storageLoc.get(); if (storageLocStr == "default") return VariableDeclaration::Location::Unspecified; @@ -1195,16 +1197,16 @@ VariableDeclaration::Location ASTJsonImporter::location(Json::Value const& _node util::unreachable(); } -Literal::SubDenomination ASTJsonImporter::subdenomination(Json::Value const& _node) +Literal::SubDenomination ASTJsonImporter::subdenomination(Json const& _node) { - Json::Value subDen = member(_node, "subdenomination"); + Json subDen = member(_node, "subdenomination"); - if (subDen.isNull()) + if (subDen.is_null()) return Literal::SubDenomination::None; - astAssert(subDen.isString(), "'subDenomination' expected to be string."); + astAssert(subDen.is_string(), "'subDenomination' expected to be string."); - std::string const subDenStr = subDen.asString(); + std::string const subDenStr = subDen.get(); if (subDenStr == "wei") return Literal::SubDenomination::Wei; @@ -1231,10 +1233,10 @@ Literal::SubDenomination ASTJsonImporter::subdenomination(Json::Value const& _no util::unreachable(); } -StateMutability ASTJsonImporter::stateMutability(Json::Value const& _node) +StateMutability ASTJsonImporter::stateMutability(Json const& _node) { - astAssert(member(_node, "stateMutability").isString(), "StateMutability' expected to be string."); - std::string const mutabilityStr = member(_node, "stateMutability").asString(); + astAssert(member(_node, "stateMutability").is_string(), "StateMutability' expected to be string."); + std::string const mutabilityStr = member(_node, "stateMutability").get(); if (mutabilityStr == "pure") return StateMutability::Pure; diff --git a/libsolidity/ast/ASTJsonImporter.h b/libsolidity/ast/ASTJsonImporter.h index b9a4d4950569..943415df93ca 100644 --- a/libsolidity/ast/ASTJsonImporter.h +++ b/libsolidity/ast/ASTJsonImporter.h @@ -24,8 +24,8 @@ #pragma once #include +#include #include -#include #include #include #include @@ -47,7 +47,7 @@ class ASTJsonImporter /// Converts the AST from JSON-format to ASTPointer /// @a _sourceList used to provide source names for the ASTs /// @returns map of sourcenames to their respective ASTs - std::map> jsonToSourceUnit(std::map const& _sourceList); + std::map> jsonToSourceUnit(std::map const& _sourceList); private: @@ -56,105 +56,105 @@ class ASTJsonImporter /// Sets the source location and nodeID /// @returns the ASTNode Object class of the respective JSON node, template - ASTPointer createASTNode(Json::Value const& _node, Args&&... _args); + ASTPointer createASTNode(Json const& _node, Args&&... _args); /// @returns the sourceLocation-object created from the string in the JSON node - langutil::SourceLocation const createSourceLocation(Json::Value const& _node); - std::optional> createSourceLocations(Json::Value const& _node) const; + langutil::SourceLocation const createSourceLocation(Json const& _node); + std::optional> createSourceLocations(Json const& _node) const; /// Creates an ASTNode for a given JSON-ast of unknown type /// @returns Pointer to a new created ASTNode - ASTPointer convertJsonToASTNode(Json::Value const& _ast); + ASTPointer convertJsonToASTNode(Json const& _ast); /// @returns a pointer to the more specific subclass of ASTNode /// as indicated by the nodeType field of the json template - ASTPointer convertJsonToASTNode(Json::Value const& _node); + ASTPointer convertJsonToASTNode(Json const& _node); - langutil::SourceLocation createNameSourceLocation(Json::Value const& _node); + langutil::SourceLocation createNameSourceLocation(Json const& _node); /// @returns source location of a mapping key name - langutil::SourceLocation createKeyNameSourceLocation(Json::Value const& _node); + langutil::SourceLocation createKeyNameSourceLocation(Json const& _node); /// @returns source location of a mapping value name - langutil::SourceLocation createValueNameSourceLocation(Json::Value const& _node); + langutil::SourceLocation createValueNameSourceLocation(Json const& _node); /// \defgroup nodeCreators JSON to AST-Nodes ///@{ - ASTPointer createSourceUnit(Json::Value const& _node, std::string const& _srcName); - ASTPointer createPragmaDirective(Json::Value const& _node); - ASTPointer createImportDirective(Json::Value const& _node); - ASTPointer createContractDefinition(Json::Value const& _node); - ASTPointer createIdentifierPath(Json::Value const& _node); - ASTPointer createInheritanceSpecifier(Json::Value const& _node); - ASTPointer createUsingForDirective(Json::Value const& _node); - ASTPointer createStructDefinition(Json::Value const& _node); - ASTPointer createEnumDefinition(Json::Value const& _node); - ASTPointer createEnumValue(Json::Value const& _node); - ASTPointer createUserDefinedValueTypeDefinition(Json::Value const& _node); - ASTPointer createParameterList(Json::Value const& _node); - ASTPointer createOverrideSpecifier(Json::Value const& _node); - ASTPointer createFunctionDefinition(Json::Value const& _node); - ASTPointer createVariableDeclaration(Json::Value const& _node); - ASTPointer createModifierDefinition(Json::Value const& _node); - ASTPointer createModifierInvocation(Json::Value const& _node); - ASTPointer createEventDefinition(Json::Value const& _node); - ASTPointer createErrorDefinition(Json::Value const& _node); - ASTPointer createElementaryTypeName(Json::Value const& _node); - ASTPointer createUserDefinedTypeName(Json::Value const& _node); - ASTPointer createFunctionTypeName(Json::Value const& _node); - ASTPointer createMapping(Json::Value const& _node); - ASTPointer createArrayTypeName(Json::Value const& _node); - ASTPointer createInlineAssembly(Json::Value const& _node); - ASTPointer createBlock(Json::Value const& _node, bool _unchecked); - ASTPointer createPlaceholderStatement(Json::Value const& _node); - ASTPointer createIfStatement(Json::Value const& _node); - ASTPointer createTryCatchClause(Json::Value const& _node); - ASTPointer createTryStatement(Json::Value const& _node); - ASTPointer createWhileStatement(Json::Value const& _node, bool _isDoWhile); - ASTPointer createForStatement(Json::Value const& _node); - ASTPointer createContinue(Json::Value const& _node); - ASTPointer createBreak(Json::Value const& _node); - ASTPointer createReturn(Json::Value const& _node); - ASTPointer createThrow(Json::Value const& _node); - ASTPointer createEmitStatement(Json::Value const& _node); - ASTPointer createRevertStatement(Json::Value const& _node); - ASTPointer createVariableDeclarationStatement(Json::Value const& _node); - ASTPointer createExpressionStatement(Json::Value const& _node); - ASTPointer createConditional(Json::Value const& _node); - ASTPointer createAssignment(Json::Value const& _node); - ASTPointer createTupleExpression(Json::Value const& _node); - ASTPointer createUnaryOperation(Json::Value const& _node); - ASTPointer createBinaryOperation(Json::Value const& _node); - ASTPointer createFunctionCall(Json::Value const& _node); - ASTPointer createFunctionCallOptions(Json::Value const& _node); - ASTPointer createNewExpression(Json::Value const& _node); - ASTPointer createMemberAccess(Json::Value const& _node); - ASTPointer createIndexAccess(Json::Value const& _node); - ASTPointer createIndexRangeAccess(Json::Value const& _node); - ASTPointer createIdentifier(Json::Value const& _node); - ASTPointer createElementaryTypeNameExpression(Json::Value const& _node); - ASTPointer createLiteral(Json::Value const& _node); - ASTPointer createDocumentation(Json::Value const& _node); + ASTPointer createSourceUnit(Json const& _node, std::string const& _srcName); + ASTPointer createPragmaDirective(Json const& _node); + ASTPointer createImportDirective(Json const& _node); + ASTPointer createContractDefinition(Json const& _node); + ASTPointer createIdentifierPath(Json const& _node); + ASTPointer createInheritanceSpecifier(Json const& _node); + ASTPointer createUsingForDirective(Json const& _node); + ASTPointer createStructDefinition(Json const& _node); + ASTPointer createEnumDefinition(Json const& _node); + ASTPointer createEnumValue(Json const& _node); + ASTPointer createUserDefinedValueTypeDefinition(Json const& _node); + ASTPointer createParameterList(Json const& _node); + ASTPointer createOverrideSpecifier(Json const& _node); + ASTPointer createFunctionDefinition(Json const& _node); + ASTPointer createVariableDeclaration(Json const& _node); + ASTPointer createModifierDefinition(Json const& _node); + ASTPointer createModifierInvocation(Json const& _node); + ASTPointer createEventDefinition(Json const& _node); + ASTPointer createErrorDefinition(Json const& _node); + ASTPointer createElementaryTypeName(Json const& _node); + ASTPointer createUserDefinedTypeName(Json const& _node); + ASTPointer createFunctionTypeName(Json const& _node); + ASTPointer createMapping(Json const& _node); + ASTPointer createArrayTypeName(Json const& _node); + ASTPointer createInlineAssembly(Json const& _node); + ASTPointer createBlock(Json const& _node, bool _unchecked); + ASTPointer createPlaceholderStatement(Json const& _node); + ASTPointer createIfStatement(Json const& _node); + ASTPointer createTryCatchClause(Json const& _node); + ASTPointer createTryStatement(Json const& _node); + ASTPointer createWhileStatement(Json const& _node, bool _isDoWhile); + ASTPointer createForStatement(Json const& _node); + ASTPointer createContinue(Json const& _node); + ASTPointer createBreak(Json const& _node); + ASTPointer createReturn(Json const& _node); + ASTPointer createThrow(Json const& _node); + ASTPointer createEmitStatement(Json const& _node); + ASTPointer createRevertStatement(Json const& _node); + ASTPointer createVariableDeclarationStatement(Json const& _node); + ASTPointer createExpressionStatement(Json const& _node); + ASTPointer createConditional(Json const& _node); + ASTPointer createAssignment(Json const& _node); + ASTPointer createTupleExpression(Json const& _node); + ASTPointer createUnaryOperation(Json const& _node); + ASTPointer createBinaryOperation(Json const& _node); + ASTPointer createFunctionCall(Json const& _node); + ASTPointer createFunctionCallOptions(Json const& _node); + ASTPointer createNewExpression(Json const& _node); + ASTPointer createMemberAccess(Json const& _node); + ASTPointer createIndexAccess(Json const& _node); + ASTPointer createIndexRangeAccess(Json const& _node); + ASTPointer createIdentifier(Json const& _node); + ASTPointer createElementaryTypeNameExpression(Json const& _node); + ASTPointer createLiteral(Json const& _node); + ASTPointer createDocumentation(Json const& _node); ///@} // =============== general helper functions =================== /// @returns the member of a given JSON object, throws if member does not exist - Json::Value member(Json::Value const& _node, std::string const& _name); + Json member(Json const& _node, std::string const& _name); /// @returns the appropriate TokenObject used in parsed Strings (pragma directive or operator) - Token scanSingleToken(Json::Value const& _node); + Token scanSingleToken(Json const& _node); template ///@returns nullptr or an ASTPointer cast to a specific Class - ASTPointer nullOrCast(Json::Value const& _json); + ASTPointer nullOrCast(Json const& _json); /// @returns nullptr or ASTString, given an JSON string or an empty field - ASTPointer nullOrASTString(Json::Value const& _json, std::string const& _name); + ASTPointer nullOrASTString(Json const& _json, std::string const& _name); // ============== JSON to definition helpers =============== /// \defgroup typeHelpers Json to ast-datatype helpers /// {@ - ASTPointer memberAsASTString(Json::Value const& _node, std::string const& _name); - bool memberAsBool(Json::Value const& _node, std::string const& _name); - Visibility visibility(Json::Value const& _node); - StateMutability stateMutability(Json::Value const& _node); - VariableDeclaration::Location location(Json::Value const& _node); - ContractKind contractKind(Json::Value const& _node); - Token literalTokenKind(Json::Value const& _node); - Literal::SubDenomination subdenomination(Json::Value const& _node); + ASTPointer memberAsASTString(Json const& _node, std::string const& _name); + bool memberAsBool(Json const& _node, std::string const& _name); + Visibility visibility(Json const& _node); + StateMutability stateMutability(Json const& _node); + VariableDeclaration::Location location(Json const& _node); + ContractKind contractKind(Json const& _node); + Token literalTokenKind(Json const& _node); + Literal::SubDenomination subdenomination(Json const& _node); ///@} // =========== member variables =============== diff --git a/libsolidity/codegen/ir/IRGenerationContext.h b/libsolidity/codegen/ir/IRGenerationContext.h index a80a18a62a10..8e03a378b302 100644 --- a/libsolidity/codegen/ir/IRGenerationContext.h +++ b/libsolidity/codegen/ir/IRGenerationContext.h @@ -37,6 +37,7 @@ #include #include #include +#include namespace solidity::frontend { diff --git a/libsolidity/codegen/ir/IRGenerator.cpp b/libsolidity/codegen/ir/IRGenerator.cpp index b84fbc357345..59585c762eec 100644 --- a/libsolidity/codegen/ir/IRGenerator.cpp +++ b/libsolidity/codegen/ir/IRGenerator.cpp @@ -37,8 +37,7 @@ #include #include #include - -#include +#include #include #include diff --git a/libsolidity/codegen/ir/IRGenerator.h b/libsolidity/codegen/ir/IRGenerator.h index 9026954d6100..9f01b74fc246 100644 --- a/libsolidity/codegen/ir/IRGenerator.h +++ b/libsolidity/codegen/ir/IRGenerator.h @@ -23,6 +23,8 @@ #pragma once +#include + #include #include #include @@ -32,8 +34,6 @@ #include #include -#include - #include namespace solidity::frontend diff --git a/libsolidity/experimental/codegen/IRGenerator.h b/libsolidity/experimental/codegen/IRGenerator.h index 7d3baf8f954e..5da6f9f6fd6a 100644 --- a/libsolidity/experimental/codegen/IRGenerator.h +++ b/libsolidity/experimental/codegen/IRGenerator.h @@ -29,7 +29,7 @@ #include #include -#include +#include #include diff --git a/libsolidity/formal/BMC.h b/libsolidity/formal/BMC.h index 9daa1683721c..1f97cbeef480 100644 --- a/libsolidity/formal/BMC.h +++ b/libsolidity/formal/BMC.h @@ -41,6 +41,7 @@ #include #include #include +#include using solidity::util::h256; diff --git a/libsolidity/interface/ABI.cpp b/libsolidity/interface/ABI.cpp index cf6e863bbbf2..e06f4b5828cc 100644 --- a/libsolidity/interface/ABI.cpp +++ b/libsolidity/interface/ABI.cpp @@ -38,12 +38,14 @@ bool anyDataStoredInStorage(TypePointers const& _pointers) } } -Json::Value ABI::generate(ContractDefinition const& _contractDef) +Json ABI::generate(ContractDefinition const& _contractDef) { - auto compare = [](Json::Value const& _a, Json::Value const& _b) -> bool { - return std::make_tuple(_a["type"], _a["name"]) < std::make_tuple(_b["type"], _b["name"]); + auto compare = [](Json const& _a, Json const& _b) -> bool + { + return std::make_tuple(_a.value("type", Json()), _a.value("name", Json())) < + std::make_tuple(_b.value("type", Json()), _b.value("name", Json())); }; - std::multiset abi(compare); + std::multiset abi(compare); for (auto it: _contractDef.interfaceFunctions()) { @@ -55,7 +57,7 @@ Json::Value ABI::generate(ContractDefinition const& _contractDef) FunctionType const* externalFunctionType = it.second->interfaceFunctionType(); solAssert(!!externalFunctionType, ""); - Json::Value method{Json::objectValue}; + Json method; method["type"] = "function"; method["name"] = it.second->declaration().name(); method["stateMutability"] = stateMutabilityToString(externalFunctionType->stateMutability()); @@ -79,7 +81,7 @@ Json::Value ABI::generate(ContractDefinition const& _contractDef) FunctionType constrType(*constructor); FunctionType const* externalFunctionType = constrType.interfaceFunctionType(); solAssert(!!externalFunctionType, ""); - Json::Value method{Json::objectValue}; + Json method; method["type"] = "constructor"; method["stateMutability"] = stateMutabilityToString(externalFunctionType->stateMutability()); method["inputs"] = formatTypeList( @@ -95,25 +97,25 @@ Json::Value ABI::generate(ContractDefinition const& _contractDef) { auto const* externalFunctionType = FunctionType(*fallbackOrReceive).interfaceFunctionType(); solAssert(!!externalFunctionType, ""); - Json::Value method{Json::objectValue}; + Json method; method["type"] = TokenTraits::toString(fallbackOrReceive->kind()); method["stateMutability"] = stateMutabilityToString(externalFunctionType->stateMutability()); abi.emplace(std::move(method)); } for (auto const& it: _contractDef.interfaceEvents()) { - Json::Value event{Json::objectValue}; + Json event; event["type"] = "event"; event["name"] = it->name(); event["anonymous"] = it->isAnonymous(); - Json::Value params{Json::arrayValue}; + Json params = Json::array(); for (auto const& p: it->parameters()) { Type const* type = p->annotation().type->interfaceType(false); solAssert(type, ""); auto param = formatType(p->name(), *type, *p->annotation().type, false); param["indexed"] = p->isIndexed(); - params.append(std::move(param)); + params.emplace_back(param); } event["inputs"] = std::move(params); abi.emplace(std::move(event)); @@ -121,53 +123,53 @@ Json::Value ABI::generate(ContractDefinition const& _contractDef) for (ErrorDefinition const* error: _contractDef.interfaceErrors()) { - Json::Value errorJson{Json::objectValue}; + Json errorJson; errorJson["type"] = "error"; errorJson["name"] = error->name(); - errorJson["inputs"] = Json::arrayValue; + errorJson["inputs"] = Json::array(); for (auto const& p: error->parameters()) { Type const* type = p->annotation().type->interfaceType(false); solAssert(type, ""); - errorJson["inputs"].append( + errorJson["inputs"].emplace_back( formatType(p->name(), *type, *p->annotation().type, false) ); } abi.emplace(std::move(errorJson)); } - Json::Value abiJson{Json::arrayValue}; + Json abiJson = Json::array(); for (auto& f: abi) - abiJson.append(std::move(f)); + abiJson.emplace_back(std::move(f)); return abiJson; } -Json::Value ABI::formatTypeList( +Json ABI::formatTypeList( std::vector const& _names, std::vector const& _encodingTypes, std::vector const& _solidityTypes, bool _forLibrary ) { - Json::Value params{Json::arrayValue}; + Json params = Json::array(); solAssert(_names.size() == _encodingTypes.size(), "Names and types vector size does not match"); solAssert(_names.size() == _solidityTypes.size(), ""); for (unsigned i = 0; i < _names.size(); ++i) { solAssert(_encodingTypes[i], ""); - params.append(formatType(_names[i], *_encodingTypes[i], *_solidityTypes[i], _forLibrary)); + params.emplace_back(formatType(_names[i], *_encodingTypes[i], *_solidityTypes[i], _forLibrary)); } return params; } -Json::Value ABI::formatType( +Json ABI::formatType( std::string const& _name, Type const& _encodingType, Type const& _solidityType, bool _forLibrary ) { - Json::Value ret{Json::objectValue}; + Json ret; ret["name"] = _name; ret["internalType"] = _solidityType.toString(true); std::string suffix = (_forLibrary && _encodingType.dataStoredIn(DataLocation::Storage)) ? " storage" : ""; @@ -185,31 +187,31 @@ Json::Value ABI::formatType( else suffix = std::string("[") + arrayType->length().str() + "]"; solAssert(arrayType->baseType(), ""); - Json::Value subtype = formatType( + Json subtype = formatType( "", *arrayType->baseType(), *dynamic_cast(_solidityType).baseType(), _forLibrary ); - if (subtype.isMember("components")) + if (subtype.contains("components")) { - ret["type"] = subtype["type"].asString() + suffix; + ret["type"] = subtype["type"].get() + suffix; ret["components"] = subtype["components"]; } else - ret["type"] = subtype["type"].asString() + suffix; + ret["type"] = subtype["type"].get() + suffix; } } else if (StructType const* structType = dynamic_cast(&_encodingType)) { ret["type"] = "tuple"; - ret["components"] = Json::arrayValue; + ret["components"] = Json::array(); for (auto const& member: structType->members(nullptr)) { solAssert(member.type, ""); Type const* t = member.type->interfaceType(_forLibrary); solAssert(t, ""); - ret["components"].append(formatType(member.name, *t, *member.type, _forLibrary)); + ret["components"].emplace_back(formatType(member.name, *t, *member.type, _forLibrary)); } } else diff --git a/libsolidity/interface/ABI.h b/libsolidity/interface/ABI.h index e956614497db..22e306c4322b 100644 --- a/libsolidity/interface/ABI.h +++ b/libsolidity/interface/ABI.h @@ -21,7 +21,7 @@ #pragma once -#include +#include #include #include @@ -38,14 +38,14 @@ class ABI /// Get the ABI Interface of the contract /// @param _contractDef The contract definition /// @return A JSONrepresentation of the contract's ABI Interface - static Json::Value generate(ContractDefinition const& _contractDef); + static Json generate(ContractDefinition const& _contractDef); private: /// @returns a json value suitable for a list of types in function input or output /// parameters or other places. If @a _forLibrary is true, complex types are referenced /// by name, otherwise they are anonymously expanded. /// @a _solidityTypes is the list of original Solidity types where @a _encodingTypes is the list of /// ABI types used for the actual encoding. - static Json::Value formatTypeList( + static Json formatTypeList( std::vector const& _names, std::vector const& _encodingTypes, std::vector const& _solidityTypes, @@ -56,7 +56,7 @@ class ABI /// If it is possible to express the type as a single string, it is allowed to return a single string. /// @a _solidityType is the original Solidity type and @a _encodingTypes is the /// ABI type used for the actual encoding. - static Json::Value formatType( + static Json formatType( std::string const& _name, Type const& _encodingType, Type const& _solidityType, diff --git a/libsolidity/interface/CompilerStack.cpp b/libsolidity/interface/CompilerStack.cpp index 2d1fd10743a3..2a9005680678 100644 --- a/libsolidity/interface/CompilerStack.cpp +++ b/libsolidity/interface/CompilerStack.cpp @@ -85,8 +85,6 @@ #include #include -#include - #include #include @@ -426,7 +424,7 @@ bool CompilerStack::parse() return true; } -void CompilerStack::importASTs(std::map const& _sources) +void CompilerStack::importASTs(std::map const& _sources) { if (m_stackState != Empty) solThrow(CompilerError, "Must call importASTs only before the SourcesSet state."); @@ -843,18 +841,18 @@ evmasm::AssemblyItems const* CompilerStack::runtimeAssemblyItems(std::string con return currentContract.evmRuntimeAssembly ? ¤tContract.evmRuntimeAssembly->items() : nullptr; } -Json::Value CompilerStack::generatedSources(std::string const& _contractName, bool _runtime) const +Json CompilerStack::generatedSources(std::string const& _contractName, bool _runtime) const { if (m_stackState != CompilationSuccessful) solThrow(CompilerError, "Compilation was not successful."); Contract const& c = contract(_contractName); - util::LazyInit const& sources = + util::LazyInit const& sources = _runtime ? c.runtimeGeneratedSources : c.generatedSources; return sources.init([&]{ - Json::Value sources{Json::arrayValue}; + Json sources = Json::array(); // If there is no compiler, then no bytecode was generated and thus no // sources were generated (or we compiled "via IR"). if (c.compiler) @@ -947,7 +945,7 @@ std::string const& CompilerStack::yulIR(std::string const& _contractName) const return contract(_contractName).yulIR; } -Json::Value const& CompilerStack::yulIRAst(std::string const& _contractName) const +Json const& CompilerStack::yulIRAst(std::string const& _contractName) const { if (m_stackState != CompilationSuccessful) solThrow(CompilerError, "Compilation was not successful."); @@ -965,7 +963,7 @@ std::string const& CompilerStack::yulIROptimized(std::string const& _contractNam return contract(_contractName).yulIROptimized; } -Json::Value const& CompilerStack::yulIROptimizedAst(std::string const& _contractName) const +Json const& CompilerStack::yulIROptimizedAst(std::string const& _contractName) const { if (m_stackState != CompilationSuccessful) solThrow(CompilerError, "Compilation was not successful."); @@ -1005,7 +1003,7 @@ std::string CompilerStack::assemblyString(std::string const& _contractName, Stri } /// TODO: cache the JSON -Json::Value CompilerStack::assemblyJSON(std::string const& _contractName) const +Json CompilerStack::assemblyJSON(std::string const& _contractName) const { if (m_stackState != CompilationSuccessful) solThrow(CompilerError, "Compilation was not successful."); @@ -1016,7 +1014,7 @@ Json::Value CompilerStack::assemblyJSON(std::string const& _contractName) const if (currentContract.evmAssembly) return currentContract.evmAssembly->assemblyJSON(sourceIndices()); else - return Json::Value(); + return Json(); } std::vector CompilerStack::sourceNames() const @@ -1035,7 +1033,7 @@ std::map CompilerStack::sourceIndices() const return indices; } -Json::Value const& CompilerStack::contractABI(std::string const& _contractName) const +Json const& CompilerStack::contractABI(std::string const& _contractName) const { if (m_stackState < AnalysisSuccessful) solThrow(CompilerError, "Analysis was not successful."); @@ -1043,7 +1041,7 @@ Json::Value const& CompilerStack::contractABI(std::string const& _contractName) return contractABI(contract(_contractName)); } -Json::Value const& CompilerStack::contractABI(Contract const& _contract) const +Json const& CompilerStack::contractABI(Contract const& _contract) const { if (m_stackState < AnalysisSuccessful) solThrow(CompilerError, "Analysis was not successful."); @@ -1054,7 +1052,7 @@ Json::Value const& CompilerStack::contractABI(Contract const& _contract) const return _contract.abi.init([&]{ return ABI::generate(*_contract.contract); }); } -Json::Value const& CompilerStack::storageLayout(std::string const& _contractName) const +Json const& CompilerStack::storageLayout(std::string const& _contractName) const { if (m_stackState < AnalysisSuccessful) solThrow(CompilerError, "Analysis was not successful."); @@ -1062,7 +1060,7 @@ Json::Value const& CompilerStack::storageLayout(std::string const& _contractName return storageLayout(contract(_contractName)); } -Json::Value const& CompilerStack::storageLayout(Contract const& _contract) const +Json const& CompilerStack::storageLayout(Contract const& _contract) const { if (m_stackState < AnalysisSuccessful) solThrow(CompilerError, "Analysis was not successful."); @@ -1073,7 +1071,7 @@ Json::Value const& CompilerStack::storageLayout(Contract const& _contract) const return _contract.storageLayout.init([&]{ return StorageLayout().generate(*_contract.contract); }); } -Json::Value const& CompilerStack::natspecUser(std::string const& _contractName) const +Json const& CompilerStack::natspecUser(std::string const& _contractName) const { if (m_stackState < AnalysisSuccessful) solThrow(CompilerError, "Analysis was not successful."); @@ -1081,7 +1079,7 @@ Json::Value const& CompilerStack::natspecUser(std::string const& _contractName) return natspecUser(contract(_contractName)); } -Json::Value const& CompilerStack::natspecUser(Contract const& _contract) const +Json const& CompilerStack::natspecUser(Contract const& _contract) const { if (m_stackState < AnalysisSuccessful) solThrow(CompilerError, "Analysis was not successful."); @@ -1092,7 +1090,7 @@ Json::Value const& CompilerStack::natspecUser(Contract const& _contract) const return _contract.userDocumentation.init([&]{ return Natspec::userDocumentation(*_contract.contract); }); } -Json::Value const& CompilerStack::natspecDev(std::string const& _contractName) const +Json const& CompilerStack::natspecDev(std::string const& _contractName) const { if (m_stackState < AnalysisSuccessful) solThrow(CompilerError, "Analysis was not successful."); @@ -1100,7 +1098,7 @@ Json::Value const& CompilerStack::natspecDev(std::string const& _contractName) c return natspecDev(contract(_contractName)); } -Json::Value const& CompilerStack::natspecDev(Contract const& _contract) const +Json const& CompilerStack::natspecDev(Contract const& _contract) const { if (m_stackState < AnalysisSuccessful) solThrow(CompilerError, "Analysis was not successful."); @@ -1112,16 +1110,16 @@ Json::Value const& CompilerStack::natspecDev(Contract const& _contract) const return _contract.devDocumentation.init([&]{ return Natspec::devDocumentation(*_contract.contract); }); } -Json::Value CompilerStack::interfaceSymbols(std::string const& _contractName) const +Json CompilerStack::interfaceSymbols(std::string const& _contractName) const { if (m_stackState < AnalysisSuccessful) solThrow(CompilerError, "Analysis was not successful."); solUnimplementedAssert(!isExperimentalSolidity()); - Json::Value interfaceSymbols(Json::objectValue); + Json interfaceSymbols; // Always have a methods object - interfaceSymbols["methods"] = Json::objectValue; + interfaceSymbols["methods"] = Json::object(); for (auto const& it: contractDefinition(_contractName).interfaceFunctions()) interfaceSymbols["methods"][it.second->externalSignature()] = it.first.hex(); @@ -1650,7 +1648,7 @@ CompilerStack::Source const& CompilerStack::source(std::string const& _sourceNam std::string CompilerStack::createMetadata(Contract const& _contract, bool _forIR) const { - Json::Value meta{Json::objectValue}; + Json meta; meta["version"] = 1; std::string sourceType; switch (m_compilationSourceType) @@ -1671,7 +1669,7 @@ std::string CompilerStack::createMetadata(Contract const& _contract, bool _forIR for (auto const sourceUnit: _contract.contract->sourceUnit().referencedSourceUnits(true)) referencedSources.insert(*sourceUnit->annotation().path); - meta["sources"] = Json::objectValue; + meta["sources"] = Json::object(); for (auto const& s: m_sources) { if (!referencedSources.count(s.first)) @@ -1685,15 +1683,15 @@ std::string CompilerStack::createMetadata(Contract const& _contract, bool _forIR meta["sources"][s.first]["content"] = s.second.charStream->source(); else { - meta["sources"][s.first]["urls"] = Json::arrayValue; - meta["sources"][s.first]["urls"].append("bzz-raw://" + util::toHex(s.second.swarmHash().asBytes())); - meta["sources"][s.first]["urls"].append(s.second.ipfsUrl()); + meta["sources"][s.first]["urls"] = Json::array(); + meta["sources"][s.first]["urls"].emplace_back("bzz-raw://" + util::toHex(s.second.swarmHash().asBytes())); + meta["sources"][s.first]["urls"].emplace_back(s.second.ipfsUrl()); } } - static_assert(sizeof(m_optimiserSettings.expectedExecutionsPerDeployment) <= sizeof(Json::LargestUInt), "Invalid word size."); - solAssert(static_cast(m_optimiserSettings.expectedExecutionsPerDeployment) < std::numeric_limits::max(), ""); - meta["settings"]["optimizer"]["runs"] = Json::Value(Json::LargestUInt(m_optimiserSettings.expectedExecutionsPerDeployment)); + static_assert(sizeof(m_optimiserSettings.expectedExecutionsPerDeployment) <= sizeof(Json::number_integer_t), "Invalid word size."); + solAssert(static_cast(m_optimiserSettings.expectedExecutionsPerDeployment) < std::numeric_limits::max(), ""); + meta["settings"]["optimizer"]["runs"] = Json::number_integer_t(m_optimiserSettings.expectedExecutionsPerDeployment); /// Backwards compatibility: If set to one of the default settings, do not provide details. OptimiserSettings settingsWithoutRuns = m_optimiserSettings; @@ -1705,7 +1703,7 @@ std::string CompilerStack::createMetadata(Contract const& _contract, bool _forIR meta["settings"]["optimizer"]["enabled"] = true; else { - Json::Value details{Json::objectValue}; + Json details = Json::object(); details["orderLiterals"] = m_optimiserSettings.runOrderLiterals; details["inliner"] = m_optimiserSettings.runInliner; @@ -1718,14 +1716,14 @@ std::string CompilerStack::createMetadata(Contract const& _contract, bool _forIR details["yul"] = m_optimiserSettings.runYulOptimiser; if (m_optimiserSettings.runYulOptimiser) { - details["yulDetails"] = Json::objectValue; + details["yulDetails"] = Json::object(); details["yulDetails"]["stackAllocation"] = m_optimiserSettings.optimizeStackAllocation; details["yulDetails"]["optimizerSteps"] = m_optimiserSettings.yulOptimiserSteps + ":" + m_optimiserSettings.yulOptimiserCleanupSteps; } else if (OptimiserSuite::isEmptyOptimizerSequence(m_optimiserSettings.yulOptimiserSteps + ":" + m_optimiserSettings.yulOptimiserCleanupSteps)) { solAssert(m_optimiserSettings.optimizeStackAllocation == false); - details["yulDetails"] = Json::objectValue; + details["yulDetails"] = Json::object(); details["yulDetails"]["optimizerSteps"] = ":"; } else @@ -1758,14 +1756,14 @@ std::string CompilerStack::createMetadata(Contract const& _contract, bool _forIR meta["settings"]["compilationTarget"][_contract.contract->sourceUnitName()] = *_contract.contract->annotation().canonicalName; - meta["settings"]["remappings"] = Json::arrayValue; + meta["settings"]["remappings"] = Json::array(); std::set remappings; for (auto const& r: m_importRemapper.remappings()) remappings.insert(r.context + ":" + r.prefix + "=" + r.target); for (auto const& r: remappings) - meta["settings"]["remappings"].append(r); + meta["settings"]["remappings"].emplace_back(r); - meta["settings"]["libraries"] = Json::objectValue; + meta["settings"]["libraries"] = Json::object(); for (auto const& library: m_libraries) meta["settings"]["libraries"][library.first] = "0x" + util::toHex(library.second.asBytes()); @@ -1897,17 +1895,17 @@ bytes CompilerStack::createCBORMetadata(Contract const& _contract, bool _forIR) namespace { -Json::Value gasToJson(GasEstimator::GasConsumption const& _gas) +Json gasToJson(GasEstimator::GasConsumption const& _gas) { if (_gas.isInfinite) - return Json::Value("infinite"); + return Json("infinite"); else - return Json::Value(util::toString(_gas.value)); + return Json(util::toString(_gas.value)); } } -Json::Value CompilerStack::gasEstimates(std::string const& _contractName) const +Json CompilerStack::gasEstimates(std::string const& _contractName) const { if (m_stackState != CompilationSuccessful) solThrow(CompilerError, "Compilation was not successful."); @@ -1915,18 +1913,18 @@ Json::Value CompilerStack::gasEstimates(std::string const& _contractName) const solUnimplementedAssert(!isExperimentalSolidity()); if (!assemblyItems(_contractName) && !runtimeAssemblyItems(_contractName)) - return Json::Value(); + return Json(); using Gas = GasEstimator::GasConsumption; GasEstimator gasEstimator(m_evmVersion); - Json::Value output(Json::objectValue); + Json output = Json::object(); if (evmasm::AssemblyItems const* items = assemblyItems(_contractName)) { Gas executionGas = gasEstimator.functionalEstimation(*items); Gas codeDepositGas{evmasm::GasMeter::dataGas(runtimeObject(_contractName).bytecode, false, m_evmVersion)}; - Json::Value creation(Json::objectValue); + Json creation = Json::object(); creation["codeDepositCost"] = gasToJson(codeDepositGas); creation["executionCost"] = gasToJson(executionGas); /// TODO: implement + overload to avoid the need of += @@ -1939,7 +1937,7 @@ Json::Value CompilerStack::gasEstimates(std::string const& _contractName) const { /// External functions ContractDefinition const& contract = contractDefinition(_contractName); - Json::Value externalFunctions(Json::objectValue); + Json externalFunctions = Json::object(); for (auto it: contract.interfaceFunctions()) { std::string sig = it.second->externalSignature(); @@ -1956,7 +1954,7 @@ Json::Value CompilerStack::gasEstimates(std::string const& _contractName) const output["external"] = externalFunctions; /// Internal functions - Json::Value internalFunctions(Json::objectValue); + Json internalFunctions = Json::object(); for (auto const& it: contract.definedFunctions()) { /// Exclude externally visible functions, constructor, fallback and receive ether function diff --git a/libsolidity/interface/CompilerStack.h b/libsolidity/interface/CompilerStack.h index 57d30e602d1d..ef76764faf70 100644 --- a/libsolidity/interface/CompilerStack.h +++ b/libsolidity/interface/CompilerStack.h @@ -47,8 +47,7 @@ #include #include #include - -#include +#include #include #include @@ -221,7 +220,7 @@ class CompilerStack: public langutil::CharStreamProvider, public evmasm::Abstrac /// Imports given SourceUnits so they can be analyzed. Leads to the same internal state as parse(). /// Will throw errors if the import fails - void importASTs(std::map const& _sources); + void importASTs(std::map const& _sources); /// Performs the analysis steps (imports, scopesetting, syntaxCheck, referenceResolving, /// typechecking, staticAnalysis) on previously parsed sources. @@ -277,13 +276,13 @@ class CompilerStack: public langutil::CharStreamProvider, public evmasm::Abstrac std::string const& yulIR(std::string const& _contractName) const; /// @returns the IR representation of a contract AST in format. - Json::Value const& yulIRAst(std::string const& _contractName) const; + Json const& yulIRAst(std::string const& _contractName) const; /// @returns the optimized IR representation of a contract. std::string const& yulIROptimized(std::string const& _contractName) const; /// @returns the optimized IR representation of a contract AST in JSON format. - Json::Value const& yulIROptimizedAst(std::string const& _contractName) const; + Json const& yulIROptimizedAst(std::string const& _contractName) const; /// @returns the assembled object for a contract. virtual evmasm::LinkerObject const& object(std::string const& _contractName) const override; @@ -299,7 +298,7 @@ class CompilerStack: public langutil::CharStreamProvider, public evmasm::Abstrac /// @returns an array containing all utility sources generated during compilation. /// Format: [ { name: string, id: number, language: "Yul", contents: string }, ... ] - Json::Value generatedSources(std::string const& _contractName, bool _runtime = false) const; + Json generatedSources(std::string const& _contractName, bool _runtime = false) const; /// @returns the string that provides a mapping between bytecode and sourcecode or a nullptr /// if the contract does not (yet) have bytecode. @@ -317,26 +316,26 @@ class CompilerStack: public langutil::CharStreamProvider, public evmasm::Abstrac /// @returns a JSON representation of the assembly. /// @arg _sourceCodes is the map of input files to source code strings /// Prerequisite: Successful compilation. - virtual Json::Value assemblyJSON(std::string const& _contractName) const override; + virtual Json assemblyJSON(std::string const& _contractName) const override; /// @returns a JSON representing the contract ABI. /// Prerequisite: Successful call to parse or compile. - Json::Value const& contractABI(std::string const& _contractName) const; + Json const& contractABI(std::string const& _contractName) const; /// @returns a JSON representing the storage layout of the contract. /// Prerequisite: Successful call to parse or compile. - Json::Value const& storageLayout(std::string const& _contractName) const; + Json const& storageLayout(std::string const& _contractName) const; /// @returns a JSON representing the contract's user documentation. /// Prerequisite: Successful call to parse or compile. - Json::Value const& natspecUser(std::string const& _contractName) const; + Json const& natspecUser(std::string const& _contractName) const; /// @returns a JSON representing the contract's developer documentation. /// Prerequisite: Successful call to parse or compile. - Json::Value const& natspecDev(std::string const& _contractName) const; + Json const& natspecDev(std::string const& _contractName) const; /// @returns a JSON object with the three members ``methods``, ``events``, ``errors``. Each is a map, mapping identifiers (hashes) to function names. - Json::Value interfaceSymbols(std::string const& _contractName) const; + Json interfaceSymbols(std::string const& _contractName) const; /// @returns the Contract Metadata matching the pipeline selected using the viaIR setting. std::string const& metadata(std::string const& _contractName) const { return metadata(contract(_contractName)); } @@ -350,7 +349,7 @@ class CompilerStack: public langutil::CharStreamProvider, public evmasm::Abstrac bytes cborMetadata(std::string const& _contractName, bool _forIR) const; /// @returns a JSON representing the estimated gas usage for contract creation, internal and external functions - Json::Value gasEstimates(std::string const& _contractName) const; + Json gasEstimates(std::string const& _contractName) const; /// Changes the format of the metadata appended at the end of the bytecode. void setMetadataFormat(MetadataFormat _metadataFormat) { m_metadataFormat = _metadataFormat; } @@ -390,15 +389,15 @@ class CompilerStack: public langutil::CharStreamProvider, public evmasm::Abstrac evmasm::LinkerObject runtimeObject; ///< Runtime object. std::string yulIR; ///< Yul IR code. std::string yulIROptimized; ///< Optimized Yul IR code. - Json::Value yulIRAst; ///< JSON AST of Yul IR code. - Json::Value yulIROptimizedAst; ///< JSON AST of optimized Yul IR code. + Json yulIRAst; ///< JSON AST of Yul IR code. + Json yulIROptimizedAst; ///< JSON AST of optimized Yul IR code. util::LazyInit metadata; ///< The metadata json that will be hashed into the chain. - util::LazyInit abi; - util::LazyInit storageLayout; - util::LazyInit userDocumentation; - util::LazyInit devDocumentation; - util::LazyInit generatedSources; - util::LazyInit runtimeGeneratedSources; + util::LazyInit abi; + util::LazyInit storageLayout; + util::LazyInit userDocumentation; + util::LazyInit devDocumentation; + util::LazyInit generatedSources; + util::LazyInit runtimeGeneratedSources; mutable std::optional sourceMapping; mutable std::optional runtimeSourceMapping; }; @@ -479,19 +478,19 @@ class CompilerStack: public langutil::CharStreamProvider, public evmasm::Abstrac /// @returns the contract ABI as a JSON object. /// This will generate the JSON object and store it in the Contract object if it is not present yet. - Json::Value const& contractABI(Contract const&) const; + Json const& contractABI(Contract const&) const; /// @returns the storage layout of the contract as a JSON object. /// This will generate the JSON object and store it in the Contract object if it is not present yet. - Json::Value const& storageLayout(Contract const&) const; + Json const& storageLayout(Contract const&) const; /// @returns the Natspec User documentation as a JSON object. /// This will generate the JSON object and store it in the Contract object if it is not present yet. - Json::Value const& natspecUser(Contract const&) const; + Json const& natspecUser(Contract const&) const; /// @returns the Natspec Developer documentation as a JSON object. /// This will generate the JSON object and store it in the Contract object if it is not present yet. - Json::Value const& natspecDev(Contract const&) const; + Json const& natspecDev(Contract const&) const; /// @returns the Contract Metadata matching the pipeline selected using the viaIR setting. /// This will generate the metadata and store it in the Contract object if it is not present yet. diff --git a/libsolidity/interface/Natspec.cpp b/libsolidity/interface/Natspec.cpp index 539a3573f50b..a0da7b54bb5e 100644 --- a/libsolidity/interface/Natspec.cpp +++ b/libsolidity/interface/Natspec.cpp @@ -33,13 +33,13 @@ using namespace solidity; using namespace solidity::frontend; -Json::Value Natspec::userDocumentation(ContractDefinition const& _contractDef) +Json Natspec::userDocumentation(ContractDefinition const& _contractDef) { - Json::Value doc{Json::objectValue}; + Json doc; - doc["version"] = Json::Value(c_natspecVersion); - doc["kind"] = Json::Value("user"); - doc["methods"] = Json::objectValue; + doc["version"] = Json(c_natspecVersion); + doc["kind"] = Json("user"); + doc["methods"] = Json::object(); auto constructorDefinition(_contractDef.constructor()); if (constructorDefinition) @@ -48,15 +48,15 @@ Json::Value Natspec::userDocumentation(ContractDefinition const& _contractDef) if (!value.empty()) { // add the constructor, only if we have any documentation to add - Json::Value user{Json::objectValue}; - user["notice"] = Json::Value(value); + Json user; + user["notice"] = Json(value); doc["methods"]["constructor"] = user; } } std::string notice = extractDoc(_contractDef.annotation().docTags, "notice"); if (!notice.empty()) - doc["notice"] = Json::Value(notice); + doc["notice"] = Json(notice); for (auto const& it: _contractDef.interfaceFunctions()) if (it.second->hasDeclaration()) @@ -88,21 +88,21 @@ Json::Value Natspec::userDocumentation(ContractDefinition const& _contractDef) std::string value = extractDoc(error->annotation().docTags, "notice"); if (!value.empty()) { - Json::Value errorDoc{Json::objectValue}; + Json errorDoc; errorDoc["notice"] = value; - doc["errors"][error->functionType(true)->externalSignature()].append(std::move(errorDoc)); + doc["errors"][error->functionType(true)->externalSignature()].emplace_back(std::move(errorDoc)); } } return doc; } -Json::Value Natspec::devDocumentation(ContractDefinition const& _contractDef) +Json Natspec::devDocumentation(ContractDefinition const& _contractDef) { - Json::Value doc = extractCustomDoc(_contractDef.annotation().docTags); + Json doc = extractCustomDoc(_contractDef.annotation().docTags); - doc["version"] = Json::Value(c_natspecVersion); - doc["kind"] = Json::Value("dev"); + doc["version"] = Json(c_natspecVersion); + doc["kind"] = Json("dev"); auto author = extractDoc(_contractDef.annotation().docTags, "author"); if (!author.empty()) @@ -112,13 +112,13 @@ Json::Value Natspec::devDocumentation(ContractDefinition const& _contractDef) doc["title"] = title; auto dev = extractDoc(_contractDef.annotation().docTags, "dev"); if (!dev.empty()) - doc["details"] = Json::Value(dev); + doc["details"] = Json(dev); - doc["methods"] = Json::objectValue; + doc["methods"] = Json::object(); auto constructorDefinition(_contractDef.constructor()); if (constructorDefinition) { - Json::Value constructor(devDocumentation(constructorDefinition->annotation().docTags)); + Json constructor(devDocumentation(constructorDefinition->annotation().docTags)); if (!constructor.empty()) // add the constructor, only if we have any documentation to add doc["methods"]["constructor"] = constructor; @@ -130,9 +130,9 @@ Json::Value Natspec::devDocumentation(ContractDefinition const& _contractDef) continue; if (auto fun = dynamic_cast(&it.second->declaration())) { - Json::Value method(devDocumentation(fun->annotation().docTags)); + Json method(devDocumentation(fun->annotation().docTags)); // add the function, only if we have any documentation to add - Json::Value jsonReturn = extractReturnParameterDocs( + Json jsonReturn = extractReturnParameterDocs( fun->annotation().docTags, fun->functionType(false)->returnParameterNames() ); @@ -150,7 +150,7 @@ Json::Value Natspec::devDocumentation(ContractDefinition const& _contractDef) if (auto devDoc = devDocumentation(varDecl->annotation().docTags); !devDoc.empty()) doc["stateVariables"][varDecl->name()] = devDoc; - auto const assignIfNotEmpty = [&](std::string const& _name, Json::Value const& _content) + auto const assignIfNotEmpty = [&](std::string const& _name, Json const& _content) { if (!_content.empty()) doc["stateVariables"][varDecl->name()][_name] = _content; @@ -171,14 +171,14 @@ Json::Value Natspec::devDocumentation(ContractDefinition const& _contractDef) doc["events"][event->functionType(true)->externalSignature()] = devDoc; for (auto const& error: _contractDef.interfaceErrors()) if (auto devDoc = devDocumentation(error->annotation().docTags); !devDoc.empty()) - doc["errors"][error->functionType(true)->externalSignature()].append(devDoc); + doc["errors"][error->functionType(true)->externalSignature()].emplace_back(devDoc); return doc; } -Json::Value Natspec::extractReturnParameterDocs(std::multimap const& _tags, std::vector const& _returnParameterNames) +Json Natspec::extractReturnParameterDocs(std::multimap const& _tags, std::vector const& _returnParameterNames) { - Json::Value jsonReturn{Json::objectValue}; + Json jsonReturn; auto returnDocs = _tags.equal_range("return"); if (!_returnParameterNames.empty()) @@ -199,7 +199,7 @@ Json::Value Natspec::extractReturnParameterDocs(std::multimap const& _tags, return value; } -Json::Value Natspec::extractCustomDoc(std::multimap const& _tags) +Json Natspec::extractCustomDoc(std::multimap const& _tags) { std::map concatenated; for (auto const& [tag, value]: _tags) @@ -224,28 +224,28 @@ Json::Value Natspec::extractCustomDoc(std::multimap const& concatenated[tag] += value.content; // We do not want to create an object if there are no custom tags found. if (concatenated.empty()) - return Json::nullValue; - Json::Value result{Json::objectValue}; + return Json(); + Json result; for (auto& [tag, value]: concatenated) result[tag] = std::move(value); return result; } -Json::Value Natspec::devDocumentation(std::multimap const& _tags) +Json Natspec::devDocumentation(std::multimap const& _tags) { - Json::Value json = extractCustomDoc(_tags); + Json json = extractCustomDoc(_tags); auto dev = extractDoc(_tags, "dev"); if (!dev.empty()) - json["details"] = Json::Value(dev); + json["details"] = Json(dev); auto author = extractDoc(_tags, "author"); if (!author.empty()) json["author"] = author; - Json::Value params(Json::objectValue); + Json params; auto paramRange = _tags.equal_range("param"); for (auto i = paramRange.first; i != paramRange.second; ++i) - params[i->second.paramName] = Json::Value(i->second.content); + params[i->second.paramName] = Json(i->second.content); if (!params.empty()) json["params"] = params; diff --git a/libsolidity/interface/Natspec.h b/libsolidity/interface/Natspec.h index e75485097def..994f1350cb87 100644 --- a/libsolidity/interface/Natspec.h +++ b/libsolidity/interface/Natspec.h @@ -26,10 +26,10 @@ #pragma once -#include +#include +#include #include #include -#include namespace solidity::frontend { @@ -46,32 +46,32 @@ class Natspec /// Get the User documentation of the contract /// @param _contractDef The contract definition /// @return A JSON representation of the contract's user documentation - static Json::Value userDocumentation(ContractDefinition const& _contractDef); + static Json userDocumentation(ContractDefinition const& _contractDef); /// Generates the Developer's documentation of the contract /// @param _contractDef The contract definition /// @return A JSON representation /// of the contract's developer documentation - static Json::Value devDocumentation(ContractDefinition const& _contractDef); + static Json devDocumentation(ContractDefinition const& _contractDef); private: /// @returns concatenation of all content under the given tag name. static std::string extractDoc(std::multimap const& _tags, std::string const& _name); /// Extract all custom tags from @a _tags. - static Json::Value extractCustomDoc(std::multimap const& _tags); + static Json extractCustomDoc(std::multimap const& _tags); /// Helper-function that will create a json object with dev specific annotations, if present. /// @param _tags docTags that are used. /// @return A JSON representation /// of the contract's developer documentation - static Json::Value devDocumentation(std::multimap const& _tags); + static Json devDocumentation(std::multimap const& _tags); /// Helper-function that will create a json object for the "returns" field for a given function definition. /// @param _tags docTags that are used. /// @param _returnParameterNames names of the return parameters /// @return A JSON representation /// of a method's return notice documentation - static Json::Value extractReturnParameterDocs(std::multimap const& _tags, std::vector const& _returnParameterNames); + static Json extractReturnParameterDocs(std::multimap const& _tags, std::vector const& _returnParameterNames); /// Temporary function until https://github.com/ethereum/solidity/issues/11114 is implemented. /// @return all events defined in the contract and its base contracts and all events diff --git a/libsolidity/interface/StandardCompiler.cpp b/libsolidity/interface/StandardCompiler.cpp index 1f7b3fa758b8..a54a9aa10720 100644 --- a/libsolidity/interface/StandardCompiler.cpp +++ b/libsolidity/interface/StandardCompiler.cpp @@ -54,64 +54,64 @@ using namespace std::string_literals; namespace { -Json::Value formatError( +Json formatError( Error::Type _type, std::string const& _component, std::string const& _message, std::string const& _formattedMessage = "", - Json::Value const& _sourceLocation = Json::Value(), - Json::Value const& _secondarySourceLocation = Json::Value() + Json const& _sourceLocation = Json(), + Json const& _secondarySourceLocation = Json() ) { - Json::Value error{Json::objectValue}; + Json error; error["type"] = Error::formatErrorType(_type); error["component"] = _component; error["severity"] = Error::formatErrorSeverityLowercase(Error::errorSeverity(_type)); error["message"] = _message; error["formattedMessage"] = (_formattedMessage.length() > 0) ? _formattedMessage : _message; - if (_sourceLocation.isObject()) + if (_sourceLocation.is_object()) error["sourceLocation"] = _sourceLocation; - if (_secondarySourceLocation.isArray()) + if (_secondarySourceLocation.is_array()) error["secondarySourceLocations"] = _secondarySourceLocation; return error; } -Json::Value formatFatalError(Error::Type _type, std::string const& _message) +Json formatFatalError(Error::Type _type, std::string const& _message) { - Json::Value output{Json::objectValue}; - output["errors"] = Json::arrayValue; - output["errors"].append(formatError(_type, "general", _message)); + Json output; + output["errors"] = Json::array(); + output["errors"].emplace_back(formatError(_type, "general", _message)); return output; } -Json::Value formatSourceLocation(SourceLocation const* location) +Json formatSourceLocation(SourceLocation const* location) { if (!location || !location->sourceName) - return Json::nullValue; + return Json(); - Json::Value sourceLocation{Json::objectValue}; + Json sourceLocation; sourceLocation["file"] = *location->sourceName; sourceLocation["start"] = location->start; sourceLocation["end"] = location->end; return sourceLocation; } -Json::Value formatSecondarySourceLocation(SecondarySourceLocation const* _secondaryLocation) +Json formatSecondarySourceLocation(SecondarySourceLocation const* _secondaryLocation) { if (!_secondaryLocation) - return Json::nullValue; + return Json(); - Json::Value secondarySourceLocation{Json::arrayValue}; + Json secondarySourceLocation = Json::array(); for (auto const& location: _secondaryLocation->infos) { - Json::Value msg = formatSourceLocation(&location.second); + Json msg = formatSourceLocation(&location.second); msg["message"] = location.first; - secondarySourceLocation.append(msg); + secondarySourceLocation.emplace_back(msg); } return secondarySourceLocation; } -Json::Value formatErrorWithException( +Json formatErrorWithException( CharStreamProvider const& _charStreamProvider, util::Exception const& _exception, Error::Type _type, @@ -134,7 +134,7 @@ Json::Value formatErrorWithException( else message = _message; - Json::Value error = formatError( + Json error = formatError( _type, _component, message, @@ -149,13 +149,13 @@ Json::Value formatErrorWithException( return error; } -std::map> requestedContractNames(Json::Value const& _outputSelection) +std::map> requestedContractNames(Json const& _outputSelection) { std::map> contracts; - for (auto const& sourceName: _outputSelection.getMemberNames()) + for (auto const& [sourceName, _]: _outputSelection.items()) { std::string key = (sourceName == "*") ? "" : sourceName; - for (auto const& contractName: _outputSelection[sourceName].getMemberNames()) + for (auto const& [contractName, _]: _outputSelection[sourceName].items()) { std::string value = (contractName == "*") ? "" : contractName; contracts[key].insert(value); @@ -177,12 +177,12 @@ bool hashMatchesContent(std::string const& _hash, std::string const& _content) } } -bool isArtifactRequested(Json::Value const& _outputSelection, std::string const& _artifact, bool _wildcardMatchesExperimental) +bool isArtifactRequested(Json const& _outputSelection, std::string const& _artifact, bool _wildcardMatchesExperimental) { static std::set experimental{"ir", "irAst", "irOptimized", "irOptimizedAst"}; for (auto const& selectedArtifactJson: _outputSelection) { - std::string const& selectedArtifact = selectedArtifactJson.asString(); + std::string const& selectedArtifact = selectedArtifactJson.get(); if ( _artifact == selectedArtifact || boost::algorithm::starts_with(_artifact, selectedArtifact + ".") @@ -211,13 +211,13 @@ bool isArtifactRequested(Json::Value const& _outputSelection, std::string const& /// /// @TODO optimise this. Perhaps flatten the structure upfront. /// -bool isArtifactRequested(Json::Value const& _outputSelection, std::string const& _file, std::string const& _contract, std::string const& _artifact, bool _wildcardMatchesExperimental) +bool isArtifactRequested(Json const& _outputSelection, std::string const& _file, std::string const& _contract, std::string const& _artifact, bool _wildcardMatchesExperimental) { - if (!_outputSelection.isObject()) + if (!_outputSelection.is_object()) return false; for (auto const& file: { _file, std::string("*") }) - if (_outputSelection.isMember(file) && _outputSelection[file].isObject()) + if (_outputSelection.contains(file) && _outputSelection[file].is_object()) { /// For SourceUnit-level targets (such as AST) only allow empty name, otherwise /// for Contract-level targets try both contract name and wildcard @@ -226,8 +226,8 @@ bool isArtifactRequested(Json::Value const& _outputSelection, std::string const& contracts.emplace_back("*"); for (auto const& contract: contracts) if ( - _outputSelection[file].isMember(contract) && - _outputSelection[file][contract].isArray() && + _outputSelection[file].contains(contract) && + _outputSelection[file][contract].is_array() && isArtifactRequested(_outputSelection[file][contract], _artifact, _wildcardMatchesExperimental) ) return true; @@ -236,7 +236,7 @@ bool isArtifactRequested(Json::Value const& _outputSelection, std::string const& return false; } -bool isArtifactRequested(Json::Value const& _outputSelection, std::string const& _file, std::string const& _contract, std::vector const& _artifacts, bool _wildcardMatchesExperimental) +bool isArtifactRequested(Json const& _outputSelection, std::string const& _file, std::string const& _contract, std::vector const& _artifacts, bool _wildcardMatchesExperimental) { for (auto const& artifact: _artifacts) if (isArtifactRequested(_outputSelection, _file, _contract, artifact, _wildcardMatchesExperimental)) @@ -255,9 +255,9 @@ std::vector evmObjectComponents(std::string const& _objectKind) } /// @returns true if any binary was requested, i.e. we actually have to perform compilation. -bool isBinaryRequested(Json::Value const& _outputSelection) +bool isBinaryRequested(Json const& _outputSelection) { - if (!_outputSelection.isObject()) + if (!_outputSelection.is_object()) return false; // This does not include "evm.methodIdentifiers" on purpose! @@ -276,9 +276,9 @@ bool isBinaryRequested(Json::Value const& _outputSelection) } /// @returns true if EVM bytecode was requested, i.e. we have to run the old code generator. -bool isEvmBytecodeRequested(Json::Value const& _outputSelection) +bool isEvmBytecodeRequested(Json const& _outputSelection) { - if (!_outputSelection.isObject()) + if (!_outputSelection.is_object()) return false; static std::vector const outputsThatRequireEvmBinaries = std::vector{ @@ -296,9 +296,9 @@ bool isEvmBytecodeRequested(Json::Value const& _outputSelection) /// @returns true if any Yul IR was requested. Note that as an exception, '*' does not /// yet match "ir", "irAst", "irOptimized" or "irOptimizedAst" -bool isIRRequested(Json::Value const& _outputSelection) +bool isIRRequested(Json const& _outputSelection) { - if (!_outputSelection.isObject()) + if (!_outputSelection.is_object()) return false; for (auto const& fileRequests: _outputSelection) @@ -315,9 +315,9 @@ bool isIRRequested(Json::Value const& _outputSelection) return false; } -Json::Value formatLinkReferences(std::map const& linkReferences) +Json formatLinkReferences(std::map const& linkReferences) { - Json::Value ret{Json::objectValue}; + Json ret = Json::object(); for (auto const& ref: linkReferences) { @@ -329,14 +329,14 @@ Json::Value formatLinkReferences(std::map const& linkRefere std::string file = (colon != std::string::npos ? fullname.substr(0, colon) : ""); std::string name = (colon != std::string::npos ? fullname.substr(colon + 1) : fullname); - Json::Value fileObject = ret.get(file, Json::objectValue); - Json::Value libraryArray = fileObject.get(name, Json::arrayValue); + Json fileObject = ret.value(file, Json::object()); + Json libraryArray = fileObject.value(name, Json::array()); - Json::Value entry{Json::objectValue}; - entry["start"] = Json::UInt(ref.first); + Json entry; + entry["start"] = Json(ref.first); entry["length"] = 20; - libraryArray.append(entry); + libraryArray.emplace_back(entry); fileObject[name] = libraryArray; ret[file] = fileObject; } @@ -344,20 +344,20 @@ Json::Value formatLinkReferences(std::map const& linkRefere return ret; } -Json::Value formatImmutableReferences(std::map>> const& _immutableReferences) +Json formatImmutableReferences(std::map>> const& _immutableReferences) { - Json::Value ret{Json::objectValue}; + Json ret = Json::object(); for (auto const& immutableReference: _immutableReferences) { auto const& [identifier, byteOffsets] = immutableReference.second; - Json::Value array(Json::arrayValue); + Json array = Json::array(); for (size_t byteOffset: byteOffsets) { - Json::Value byteRange{Json::objectValue}; - byteRange["start"] = Json::UInt(byteOffset); - byteRange["length"] = Json::UInt(32); // immutable references are currently always 32 bytes wide - array.append(byteRange); + Json byteRange; + byteRange["start"] = Json::number_unsigned_t(byteOffset); + byteRange["length"] = Json::number_unsigned_t(32); // immutable references are currently always 32 bytes wide + array.emplace_back(byteRange); } ret[identifier] = array; } @@ -365,16 +365,16 @@ Json::Value formatImmutableReferences(std::map const& _artifactRequested ) { - Json::Value output{Json::objectValue}; + Json output; if (_artifactRequested("object")) output["object"] = _object.toHex(); if (_artifactRequested("opcodes")) @@ -392,78 +392,78 @@ Json::Value collectEVMObject( return output; } -std::optional checkKeys(Json::Value const& _input, std::set const& _keys, std::string const& _name) +std::optional checkKeys(Json const& _input, std::set const& _keys, std::string const& _name) { - if (!!_input && !_input.isObject()) + if (!_input.empty() && !_input.is_object()) return formatFatalError(Error::Type::JSONError, "\"" + _name + "\" must be an object"); - for (auto const& member: _input.getMemberNames()) + for (auto const& [member, _]: _input.items()) if (!_keys.count(member)) return formatFatalError(Error::Type::JSONError, "Unknown key \"" + member + "\""); return std::nullopt; } -std::optional checkRootKeys(Json::Value const& _input) +std::optional checkRootKeys(Json const& _input) { static std::set keys{"auxiliaryInput", "language", "settings", "sources"}; return checkKeys(_input, keys, "root"); } -std::optional checkSourceKeys(Json::Value const& _input, std::string const& _name) +std::optional checkSourceKeys(Json const& _input, std::string const& _name) { static std::set keys{"content", "keccak256", "urls"}; return checkKeys(_input, keys, "sources." + _name); } -std::optional checkAuxiliaryInputKeys(Json::Value const& _input) +std::optional checkAuxiliaryInputKeys(Json const& _input) { static std::set keys{"smtlib2responses"}; return checkKeys(_input, keys, "auxiliaryInput"); } -std::optional checkSettingsKeys(Json::Value const& _input) +std::optional checkSettingsKeys(Json const& _input) { static std::set keys{"debug", "evmVersion", "libraries", "metadata", "modelChecker", "optimizer", "outputSelection", "remappings", "stopAfter", "viaIR"}; return checkKeys(_input, keys, "settings"); } -std::optional checkModelCheckerSettingsKeys(Json::Value const& _input) +std::optional checkModelCheckerSettingsKeys(Json const& _input) { static std::set keys{"bmcLoopIterations", "contracts", "divModNoSlacks", "engine", "extCalls", "invariants", "printQuery", "showProvedSafe", "showUnproved", "showUnsupported", "solvers", "targets", "timeout"}; return checkKeys(_input, keys, "modelChecker"); } -std::optional checkOptimizerKeys(Json::Value const& _input) +std::optional checkOptimizerKeys(Json const& _input) { static std::set keys{"details", "enabled", "runs"}; return checkKeys(_input, keys, "settings.optimizer"); } -std::optional checkOptimizerDetailsKeys(Json::Value const& _input) +std::optional checkOptimizerDetailsKeys(Json const& _input) { static std::set keys{"peephole", "inliner", "jumpdestRemover", "orderLiterals", "deduplicate", "cse", "constantOptimizer", "yul", "yulDetails", "simpleCounterForLoopUncheckedIncrement"}; return checkKeys(_input, keys, "settings.optimizer.details"); } -std::optional checkOptimizerDetail(Json::Value const& _details, std::string const& _name, bool& _setting) +std::optional checkOptimizerDetail(Json const& _details, std::string const& _name, bool& _setting) { - if (_details.isMember(_name)) + if (_details.contains(_name)) { - if (!_details[_name].isBool()) + if (!_details[_name].is_boolean()) return formatFatalError(Error::Type::JSONError, "\"settings.optimizer.details." + _name + "\" must be Boolean"); - _setting = _details[_name].asBool(); + _setting = _details[_name].get(); } return {}; } -std::optional checkOptimizerDetailSteps(Json::Value const& _details, std::string const& _name, std::string& _optimiserSetting, std::string& _cleanupSetting, bool _runYulOptimizer) +std::optional checkOptimizerDetailSteps(Json const& _details, std::string const& _name, std::string& _optimiserSetting, std::string& _cleanupSetting, bool _runYulOptimizer) { - if (_details.isMember(_name)) + if (_details.contains(_name)) { - if (_details[_name].isString()) + if (_details[_name].is_string()) { - std::string const fullSequence = _details[_name].asString(); + std::string const fullSequence = _details[_name].get(); if (!_runYulOptimizer && !OptimiserSuite::isEmptyOptimizerSequence(fullSequence)) { std::string errorMessage = @@ -474,7 +474,7 @@ std::optional checkOptimizerDetailSteps(Json::Value const& _details try { - yul::OptimiserSuite::validateSequence(_details[_name].asString()); + yul::OptimiserSuite::validateSequence(_details[_name].get()); } catch (yul::OptimizerException const& _exception) { @@ -499,43 +499,39 @@ std::optional checkOptimizerDetailSteps(Json::Value const& _details return {}; } -std::optional checkMetadataKeys(Json::Value const& _input) +std::optional checkMetadataKeys(Json const& _input) { - if (_input.isObject()) + if (_input.is_object()) { - if (_input.isMember("appendCBOR") && !_input["appendCBOR"].isBool()) + if (_input.contains("appendCBOR") && !_input["appendCBOR"].is_boolean()) return formatFatalError(Error::Type::JSONError, "\"settings.metadata.appendCBOR\" must be Boolean"); - if (_input.isMember("useLiteralContent") && !_input["useLiteralContent"].isBool()) + if (_input.contains("useLiteralContent") && !_input["useLiteralContent"].is_boolean()) return formatFatalError(Error::Type::JSONError, "\"settings.metadata.useLiteralContent\" must be Boolean"); static std::set hashes{"ipfs", "bzzr1", "none"}; - if (_input.isMember("bytecodeHash") && !hashes.count(_input["bytecodeHash"].asString())) + if (_input.contains("bytecodeHash") && !hashes.count(_input["bytecodeHash"].get())) return formatFatalError(Error::Type::JSONError, "\"settings.metadata.bytecodeHash\" must be \"ipfs\", \"bzzr1\" or \"none\""); } static std::set keys{"appendCBOR", "useLiteralContent", "bytecodeHash"}; return checkKeys(_input, keys, "settings.metadata"); } -std::optional checkOutputSelection(Json::Value const& _outputSelection) +std::optional checkOutputSelection(Json const& _outputSelection) { - if (!!_outputSelection && !_outputSelection.isObject()) + if (!_outputSelection.empty() && !_outputSelection.is_object()) return formatFatalError(Error::Type::JSONError, "\"settings.outputSelection\" must be an object"); - for (auto const& sourceName: _outputSelection.getMemberNames()) + for (auto const& [sourceName, sourceVal]: _outputSelection.items()) { - auto const& sourceVal = _outputSelection[sourceName]; - - if (!sourceVal.isObject()) + if (!sourceVal.is_object()) return formatFatalError( Error::Type::JSONError, "\"settings.outputSelection." + sourceName + "\" must be an object" ); - for (auto const& contractName: sourceVal.getMemberNames()) + for (auto const& [contractName, contractVal]: sourceVal.items()) { - auto const& contractVal = sourceVal[contractName]; - - if (!contractVal.isArray()) + if (!contractVal.is_array()) return formatFatalError( Error::Type::JSONError, "\"settings.outputSelection." + @@ -546,7 +542,7 @@ std::optional checkOutputSelection(Json::Value const& _outputSelect ); for (auto const& output: contractVal) - if (!output.isString()) + if (!output.is_string()) return formatFatalError( Error::Type::JSONError, "\"settings.outputSelection." + @@ -563,32 +559,32 @@ std::optional checkOutputSelection(Json::Value const& _outputSelect /// Validates the optimizer settings and returns them in a parsed object. /// On error returns the json-formatted error message. -std::variant parseOptimizerSettings(Json::Value const& _jsonInput) +std::variant parseOptimizerSettings(Json const& _jsonInput) { if (auto result = checkOptimizerKeys(_jsonInput)) return *result; OptimiserSettings settings = OptimiserSettings::minimal(); - if (_jsonInput.isMember("enabled")) + if (_jsonInput.contains("enabled")) { - if (!_jsonInput["enabled"].isBool()) + if (!_jsonInput["enabled"].is_boolean()) return formatFatalError(Error::Type::JSONError, "The \"enabled\" setting must be a Boolean."); - if (_jsonInput["enabled"].asBool()) + if (_jsonInput["enabled"].get()) settings = OptimiserSettings::standard(); } - if (_jsonInput.isMember("runs")) + if (_jsonInput.contains("runs")) { - if (!_jsonInput["runs"].isUInt()) + if (!_jsonInput["runs"].is_number_unsigned()) return formatFatalError(Error::Type::JSONError, "The \"runs\" setting must be an unsigned number."); - settings.expectedExecutionsPerDeployment = _jsonInput["runs"].asUInt(); + settings.expectedExecutionsPerDeployment = _jsonInput["runs"].get(); } - if (_jsonInput.isMember("details")) + if (_jsonInput.contains("details")) { - Json::Value const& details = _jsonInput["details"]; + Json const& details = _jsonInput["details"]; if (auto result = checkOptimizerDetailsKeys(details)) return *result; @@ -611,7 +607,7 @@ std::variant parseOptimizerSettings(Json::Value if (auto error = checkOptimizerDetail(details, "simpleCounterForLoopUncheckedIncrement", settings.simpleCounterForLoopUncheckedIncrement)) return *error; settings.optimizeStackAllocation = settings.runYulOptimiser; - if (details.isMember("yulDetails")) + if (details.contains("yulDetails")) { if (!settings.runYulOptimiser) { @@ -635,45 +631,46 @@ std::variant parseOptimizerSettings(Json::Value } -std::variant StandardCompiler::parseInput(Json::Value const& _input) +std::variant StandardCompiler::parseInput(Json const& _input) { InputsAndSettings ret; - if (!_input.isObject()) + if (!_input.is_object()) return formatFatalError(Error::Type::JSONError, "Input is not a JSON object."); if (auto result = checkRootKeys(_input)) return *result; - ret.language = _input["language"].asString(); + ret.language = _input.value("language", ""); - Json::Value const& sources = _input["sources"]; + Json const& sources = _input.value("sources", Json()); - if (!sources.isObject() && !sources.isNull()) + if (!sources.is_object() && !sources.is_null()) return formatFatalError(Error::Type::JSONError, "\"sources\" is not a JSON object."); if (sources.empty()) return formatFatalError(Error::Type::JSONError, "No input sources specified."); - ret.errors = Json::arrayValue; + ret.errors = Json::array(); + ret.sources = Json::object(); if (ret.language == "Solidity" || ret.language == "Yul") { - for (auto const& sourceName: sources.getMemberNames()) + for (auto const& [sourceName, sourceValue]: sources.items()) { std::string hash; - if (auto result = checkSourceKeys(sources[sourceName], sourceName)) + if (auto result = checkSourceKeys(sourceValue, sourceName)) return *result; - if (sources[sourceName]["keccak256"].isString()) - hash = sources[sourceName]["keccak256"].asString(); + if (sourceValue.contains("keccak256") && sourceValue["keccak256"].is_string()) + hash = sourceValue["keccak256"].get(); - if (sources[sourceName]["content"].isString()) + if (sourceValue.contains("content") && sourceValue["content"].is_string()) { - std::string content = sources[sourceName]["content"].asString(); + std::string content = sourceValue["content"].get(); if (!hash.empty() && !hashMatchesContent(hash, content)) - ret.errors.append(formatError( + ret.errors.emplace_back(formatError( Error::Type::IOError, "general", "Mismatch between content and supplied hash for \"" + sourceName + "\"" @@ -681,7 +678,7 @@ std::variant StandardCompiler: else ret.sources[sourceName] = content; } - else if (sources[sourceName]["urls"].isArray()) + else if (sourceValue["urls"].is_array()) { if (!m_readFile) return formatFatalError( @@ -691,18 +688,18 @@ std::variant StandardCompiler: std::vector failures; bool found = false; - for (auto const& url: sources[sourceName]["urls"]) + for (auto const& url: sourceValue["urls"]) { - if (!url.isString()) + if (!url.is_string()) return formatFatalError(Error::Type::JSONError, "URL must be a string."); - ReadCallback::Result result = m_readFile(ReadCallback::kindString(ReadCallback::Kind::ReadFile), url.asString()); + ReadCallback::Result result = m_readFile(ReadCallback::kindString(ReadCallback::Kind::ReadFile), url.get()); if (result.success) { if (!hash.empty() && !hashMatchesContent(hash, result.responseOrErrorMessage)) - ret.errors.append(formatError( + ret.errors.emplace_back(formatError( Error::Type::IOError, "general", - "Mismatch between content and supplied hash for \"" + sourceName + "\" at \"" + url.asString() + "\"" + "Mismatch between content and supplied hash for \"" + sourceName + "\" at \"" + url.get() + "\"" )); else { @@ -713,14 +710,14 @@ std::variant StandardCompiler: } else failures.push_back( - "Cannot import url (\"" + url.asString() + "\"): " + result.responseOrErrorMessage + "Cannot import url (\"" + url.get() + "\"): " + result.responseOrErrorMessage ); } for (auto const& failure: failures) { /// If the import succeeded, let mark all the others as warnings, otherwise all of them are errors. - ret.errors.append(formatError( + ret.errors.emplace_back(formatError( found ? Error::Type::Warning : Error::Type::IOError, "general", failure @@ -733,25 +730,25 @@ std::variant StandardCompiler: } else if (ret.language == "SolidityAST") { - for (auto const& sourceName: sources.getMemberNames()) - ret.sources[sourceName] = util::jsonCompactPrint(sources[sourceName]); + for (auto const& [sourceName, sourceValue]: sources.items()) + ret.sources[sourceName] = util::jsonCompactPrint(sourceValue); } else if (ret.language == "EVMAssembly") { - for (std::string const& sourceName: sources.getMemberNames()) + for (auto const& [sourceName, sourceValue]: sources.items()) { - solAssert(sources.isMember(sourceName)); + solAssert(sources.contains(sourceName)); if ( - !sources[sourceName].isMember("assemblyJson") || - !sources[sourceName]["assemblyJson"].isObject() || - sources[sourceName].size() != 1 + !sourceValue.contains("assemblyJson") || + !sourceValue["assemblyJson"].is_object() || + sourceValue.size() != 1 ) return formatFatalError( Error::Type::JSONError, "Invalid input source specified. Expected exactly one object, named 'assemblyJson', inside $.sources." + sourceName ); - ret.jsonSources[sourceName] = sources[sourceName]["assemblyJson"]; + ret.jsonSources[sourceName] = sourceValue["assemblyJson"]; } if (ret.jsonSources.size() != 1) return formatFatalError( @@ -759,20 +756,20 @@ std::variant StandardCompiler: "EVMAssembly import only supports exactly one input file." ); } - Json::Value const& auxInputs = _input["auxiliaryInput"]; + Json const& auxInputs = _input.value("auxiliaryInput", Json::object()); if (auto result = checkAuxiliaryInputKeys(auxInputs)) return *result; - if (!!auxInputs) + if (!auxInputs.empty()) { - Json::Value const& smtlib2Responses = auxInputs["smtlib2responses"]; - if (!!smtlib2Responses) + Json const& smtlib2Responses = auxInputs.value("smtlib2responses", Json::object()); + if (!smtlib2Responses.empty()) { - if (!smtlib2Responses.isObject()) + if (!smtlib2Responses.is_object()) return formatFatalError(Error::Type::JSONError, "\"auxiliaryInput.smtlib2responses\" must be an object."); - for (auto const& hashString: smtlib2Responses.getMemberNames()) + for (auto const& [hashString, response]: smtlib2Responses.items()) { util::h256 hash; try @@ -784,49 +781,49 @@ std::variant StandardCompiler: return formatFatalError(Error::Type::JSONError, "Invalid hex encoding of SMTLib2 auxiliary input."); } - if (!smtlib2Responses[hashString].isString()) + if (!response.is_string()) return formatFatalError( Error::Type::JSONError, "\"smtlib2Responses." + hashString + "\" must be a string." ); - ret.smtLib2Responses[hash] = smtlib2Responses[hashString].asString(); + ret.smtLib2Responses[hash] = response.get(); } } } - Json::Value const& settings = _input.get("settings", Json::Value()); + Json const& settings = _input.value("settings", Json::object()); if (auto result = checkSettingsKeys(settings)) return *result; - if (settings.isMember("stopAfter")) + if (settings.contains("stopAfter")) { - if (!settings["stopAfter"].isString()) + if (!settings["stopAfter"].is_string()) return formatFatalError(Error::Type::JSONError, "\"settings.stopAfter\" must be a string."); - if (settings["stopAfter"].asString() != "parsing") + if (settings["stopAfter"].get() != "parsing") return formatFatalError(Error::Type::JSONError, "Invalid value for \"settings.stopAfter\". Only valid value is \"parsing\"."); ret.stopAfter = CompilerStack::State::Parsed; } - if (settings.isMember("viaIR")) + if (settings.contains("viaIR")) { - if (!settings["viaIR"].isBool()) + if (!settings["viaIR"].is_boolean()) return formatFatalError(Error::Type::JSONError, "\"settings.viaIR\" must be a Boolean."); - ret.viaIR = settings["viaIR"].asBool(); + ret.viaIR = settings["viaIR"].get(); } - if (settings.isMember("evmVersion")) + if (settings.contains("evmVersion")) { - if (!settings["evmVersion"].isString()) + if (!settings["evmVersion"].is_string()) return formatFatalError(Error::Type::JSONError, "evmVersion must be a string."); - std::optional version = langutil::EVMVersion::fromString(settings["evmVersion"].asString()); + std::optional version = langutil::EVMVersion::fromString(settings["evmVersion"].get()); if (!version) return formatFatalError(Error::Type::JSONError, "Invalid EVM version requested."); if (version < EVMVersion::constantinople()) - ret.errors.append(formatError( + ret.errors.emplace_back(formatError( Error::Type::Warning, "general", "Support for EVM versions older than constantinople is deprecated and will be removed in the future." @@ -834,26 +831,26 @@ std::variant StandardCompiler: ret.evmVersion = *version; } - if (settings.isMember("eofVersion")) + if (settings.contains("eofVersion")) { - if (!settings["eofVersion"].isUInt()) + if (!settings["eofVersion"].is_number_unsigned()) return formatFatalError(Error::Type::JSONError, "eofVersion must be an unsigned integer."); - auto eofVersion = settings["evmVersion"].asUInt(); + auto eofVersion = settings["evmVersion"].get(); if (eofVersion != 1) return formatFatalError(Error::Type::JSONError, "Invalid EOF version requested."); ret.eofVersion = 1; } - if (settings.isMember("debug")) + if (settings.contains("debug")) { if (auto result = checkKeys(settings["debug"], {"revertStrings", "debugInfo"}, "settings.debug")) return *result; - if (settings["debug"].isMember("revertStrings")) + if (settings["debug"].contains("revertStrings")) { - if (!settings["debug"]["revertStrings"].isString()) + if (!settings["debug"]["revertStrings"].is_string()) return formatFatalError(Error::Type::JSONError, "settings.debug.revertStrings must be a string."); - std::optional revertStrings = revertStringsFromString(settings["debug"]["revertStrings"].asString()); + std::optional revertStrings = revertStringsFromString(settings["debug"]["revertStrings"].get()); if (!revertStrings) return formatFatalError(Error::Type::JSONError, "Invalid value for settings.debug.revertStrings."); if (*revertStrings == RevertStrings::VerboseDebug) @@ -864,14 +861,14 @@ std::variant StandardCompiler: ret.revertStrings = *revertStrings; } - if (settings["debug"].isMember("debugInfo")) + if (settings["debug"].contains("debugInfo")) { - if (!settings["debug"]["debugInfo"].isArray()) + if (!settings["debug"]["debugInfo"].is_array()) return formatFatalError(Error::Type::JSONError, "settings.debug.debugInfo must be an array."); std::vector components; - for (Json::Value const& arrayValue: settings["debug"]["debugInfo"]) - components.push_back(arrayValue.asString()); + for (Json const& arrayValue: settings["debug"]["debugInfo"]) + components.push_back(arrayValue.get()); std::optional debugInfoSelection = DebugInfoSelection::fromComponents( components, @@ -890,41 +887,40 @@ std::variant StandardCompiler: } } - if (settings.isMember("remappings") && !settings["remappings"].isArray()) + if (settings.contains("remappings") && !settings["remappings"].is_array()) return formatFatalError(Error::Type::JSONError, "\"settings.remappings\" must be an array of strings."); - for (auto const& remapping: settings.get("remappings", Json::Value())) + for (auto const& remapping: settings.value("remappings", Json::object())) { - if (!remapping.isString()) + if (!remapping.is_string()) return formatFatalError(Error::Type::JSONError, "\"settings.remappings\" must be an array of strings"); - if (auto r = ImportRemapper::parseRemapping(remapping.asString())) + if (auto r = ImportRemapper::parseRemapping(remapping.get())) ret.remappings.emplace_back(std::move(*r)); else - return formatFatalError(Error::Type::JSONError, "Invalid remapping: \"" + remapping.asString() + "\""); + return formatFatalError(Error::Type::JSONError, "Invalid remapping: \"" + remapping.get() + "\""); } - if (settings.isMember("optimizer")) + if (settings.contains("optimizer")) { auto optimiserSettings = parseOptimizerSettings(settings["optimizer"]); - if (std::holds_alternative(optimiserSettings)) - return std::get(std::move(optimiserSettings)); // was an error + if (std::holds_alternative(optimiserSettings)) + return std::get(std::move(optimiserSettings)); // was an error else ret.optimiserSettings = std::get(std::move(optimiserSettings)); } - Json::Value jsonLibraries = settings.get("libraries", Json::Value(Json::objectValue)); - if (!jsonLibraries.isObject()) + Json const& jsonLibraries = settings.value("libraries", Json::object()); + if (!jsonLibraries.is_object()) return formatFatalError(Error::Type::JSONError, "\"libraries\" is not a JSON object."); - for (auto const& sourceName: jsonLibraries.getMemberNames()) + for (auto const& [sourceName, jsonSourceName]: jsonLibraries.items()) { - auto const& jsonSourceName = jsonLibraries[sourceName]; - if (!jsonSourceName.isObject()) + if (!jsonSourceName.is_object()) return formatFatalError(Error::Type::JSONError, "Library entry is not a JSON object."); - for (auto const& library: jsonSourceName.getMemberNames()) + for (auto const& [library, libraryValue]: jsonSourceName.items()) { - if (!jsonSourceName[library].isString()) + if (!libraryValue.is_string()) return formatFatalError(Error::Type::JSONError, "Library address must be a string."); - std::string address = jsonSourceName[library].asString(); + std::string address = libraryValue.get(); if (!boost::starts_with(address, "0x")) return formatFatalError( @@ -952,21 +948,24 @@ std::variant StandardCompiler: } } - Json::Value metadataSettings = settings.get("metadata", Json::Value()); + Json const& metadataSettings = settings.value("metadata", Json::object()); if (auto result = checkMetadataKeys(metadataSettings)) return *result; solAssert(CompilerStack::defaultMetadataFormat() != CompilerStack::MetadataFormat::NoMetadata, ""); ret.metadataFormat = - metadataSettings.get("appendCBOR", Json::Value(true)).asBool() ? + metadataSettings.value("appendCBOR", Json(true)) ? CompilerStack::defaultMetadataFormat() : CompilerStack::MetadataFormat::NoMetadata; - ret.metadataLiteralSources = metadataSettings.get("useLiteralContent", Json::Value(false)).asBool(); - if (metadataSettings.isMember("bytecodeHash")) + ret.metadataLiteralSources = + metadataSettings.contains("useLiteralContent") && + metadataSettings["useLiteralContent"].is_boolean() && + metadataSettings["useLiteralContent"].get(); + if (metadataSettings.contains("bytecodeHash")) { - auto metadataHash = metadataSettings["bytecodeHash"].asString(); + auto metadataHash = metadataSettings["bytecodeHash"].get(); ret.metadataHash = metadataHash == "ipfs" ? CompilerStack::MetadataHash::IPFS : @@ -982,12 +981,12 @@ std::variant StandardCompiler: ); } - Json::Value outputSelection = settings.get("outputSelection", Json::Value()); + Json const& outputSelection = settings.value("outputSelection", Json::object()); if (auto jsonError = checkOutputSelection(outputSelection)) return *jsonError; - ret.outputSelection = std::move(outputSelection); + ret.outputSelection = outputSelection; if (ret.stopAfter != CompilerStack::State::CompilationSuccessful && isBinaryRequested(ret.outputSelection)) return formatFatalError( @@ -995,34 +994,33 @@ std::variant StandardCompiler: "Requested output selection conflicts with \"settings.stopAfter\"." ); - Json::Value const& modelCheckerSettings = settings.get("modelChecker", Json::Value()); + Json const& modelCheckerSettings = settings.value("modelChecker", Json::object()); if (auto result = checkModelCheckerSettingsKeys(modelCheckerSettings)) return *result; - if (modelCheckerSettings.isMember("contracts")) + if (modelCheckerSettings.contains("contracts")) { auto const& sources = modelCheckerSettings["contracts"]; - if (!sources.isObject() && !sources.isNull()) + if (!sources.is_object() && !sources.is_null()) return formatFatalError(Error::Type::JSONError, "settings.modelChecker.contracts is not a JSON object."); std::map> sourceContracts; - for (auto const& source: sources.getMemberNames()) + for (auto const& [source, contracts]: sources.items()) { if (source.empty()) return formatFatalError(Error::Type::JSONError, "Source name cannot be empty."); - auto const& contracts = sources[source]; - if (!contracts.isArray()) + if (!contracts.is_array()) return formatFatalError(Error::Type::JSONError, "Source contracts must be an array."); for (auto const& contract: contracts) { - if (!contract.isString()) + if (!contract.is_string()) return formatFatalError(Error::Type::JSONError, "Every contract in settings.modelChecker.contracts must be a string."); - if (contract.asString().empty()) + if (contract.get().empty()) return formatFatalError(Error::Type::JSONError, "Contract name cannot be empty."); - sourceContracts[source].insert(contract.asString()); + sourceContracts[source].insert(contract.get()); } if (sourceContracts[source].empty()) @@ -1031,56 +1029,56 @@ std::variant StandardCompiler: ret.modelCheckerSettings.contracts = {std::move(sourceContracts)}; } - if (modelCheckerSettings.isMember("divModNoSlacks")) + if (modelCheckerSettings.contains("divModNoSlacks")) { auto const& divModNoSlacks = modelCheckerSettings["divModNoSlacks"]; - if (!divModNoSlacks.isBool()) + if (!divModNoSlacks.is_boolean()) return formatFatalError(Error::Type::JSONError, "settings.modelChecker.divModNoSlacks must be a Boolean."); - ret.modelCheckerSettings.divModNoSlacks = divModNoSlacks.asBool(); + ret.modelCheckerSettings.divModNoSlacks = divModNoSlacks.get(); } - if (modelCheckerSettings.isMember("engine")) + if (modelCheckerSettings.contains("engine")) { - if (!modelCheckerSettings["engine"].isString()) + if (!modelCheckerSettings["engine"].is_string()) return formatFatalError(Error::Type::JSONError, "settings.modelChecker.engine must be a string."); - std::optional engine = ModelCheckerEngine::fromString(modelCheckerSettings["engine"].asString()); + std::optional engine = ModelCheckerEngine::fromString(modelCheckerSettings["engine"].get()); if (!engine) return formatFatalError(Error::Type::JSONError, "Invalid model checker engine requested."); ret.modelCheckerSettings.engine = *engine; } - if (modelCheckerSettings.isMember("bmcLoopIterations")) + if (modelCheckerSettings.contains("bmcLoopIterations")) { if (!ret.modelCheckerSettings.engine.bmc) return formatFatalError(Error::Type::JSONError, "settings.modelChecker.bmcLoopIterations requires the BMC engine to be enabled."); - if (modelCheckerSettings["bmcLoopIterations"].isUInt()) - ret.modelCheckerSettings.bmcLoopIterations = modelCheckerSettings["bmcLoopIterations"].asUInt(); + if (modelCheckerSettings["bmcLoopIterations"].is_number_unsigned()) + ret.modelCheckerSettings.bmcLoopIterations = modelCheckerSettings["bmcLoopIterations"].get(); else return formatFatalError(Error::Type::JSONError, "settings.modelChecker.bmcLoopIterations must be an unsigned integer."); } - if (modelCheckerSettings.isMember("extCalls")) + if (modelCheckerSettings.contains("extCalls")) { - if (!modelCheckerSettings["extCalls"].isString()) + if (!modelCheckerSettings["extCalls"].is_string()) return formatFatalError(Error::Type::JSONError, "settings.modelChecker.extCalls must be a string."); - std::optional extCalls = ModelCheckerExtCalls::fromString(modelCheckerSettings["extCalls"].asString()); + std::optional extCalls = ModelCheckerExtCalls::fromString(modelCheckerSettings["extCalls"].get()); if (!extCalls) return formatFatalError(Error::Type::JSONError, "Invalid model checker extCalls requested."); ret.modelCheckerSettings.externalCalls = *extCalls; } - if (modelCheckerSettings.isMember("invariants")) + if (modelCheckerSettings.contains("invariants")) { auto const& invariantsArray = modelCheckerSettings["invariants"]; - if (!invariantsArray.isArray()) + if (!invariantsArray.is_array()) return formatFatalError(Error::Type::JSONError, "settings.modelChecker.invariants must be an array."); ModelCheckerInvariants invariants; for (auto const& i: invariantsArray) { - if (!i.isString()) + if (!i.is_string()) return formatFatalError(Error::Type::JSONError, "Every invariant type in settings.modelChecker.invariants must be a string."); - if (!invariants.setFromString(i.asString())) + if (!invariants.setFromString(i.get())) return formatFatalError(Error::Type::JSONError, "Invalid model checker invariants requested."); } @@ -1090,72 +1088,72 @@ std::variant StandardCompiler: ret.modelCheckerSettings.invariants = invariants; } - if (modelCheckerSettings.isMember("showProvedSafe")) + if (modelCheckerSettings.contains("showProvedSafe")) { auto const& showProvedSafe = modelCheckerSettings["showProvedSafe"]; - if (!showProvedSafe.isBool()) + if (!showProvedSafe.is_boolean()) return formatFatalError(Error::Type::JSONError, "settings.modelChecker.showProvedSafe must be a Boolean value."); - ret.modelCheckerSettings.showProvedSafe = showProvedSafe.asBool(); + ret.modelCheckerSettings.showProvedSafe = showProvedSafe.get(); } - if (modelCheckerSettings.isMember("showUnproved")) + if (modelCheckerSettings.contains("showUnproved")) { auto const& showUnproved = modelCheckerSettings["showUnproved"]; - if (!showUnproved.isBool()) + if (!showUnproved.is_boolean()) return formatFatalError(Error::Type::JSONError, "settings.modelChecker.showUnproved must be a Boolean value."); - ret.modelCheckerSettings.showUnproved = showUnproved.asBool(); + ret.modelCheckerSettings.showUnproved = showUnproved.get(); } - if (modelCheckerSettings.isMember("showUnsupported")) + if (modelCheckerSettings.contains("showUnsupported")) { auto const& showUnsupported = modelCheckerSettings["showUnsupported"]; - if (!showUnsupported.isBool()) + if (!showUnsupported.is_boolean()) return formatFatalError(Error::Type::JSONError, "settings.modelChecker.showUnsupported must be a Boolean value."); - ret.modelCheckerSettings.showUnsupported = showUnsupported.asBool(); + ret.modelCheckerSettings.showUnsupported = showUnsupported.get(); } - if (modelCheckerSettings.isMember("solvers")) + if (modelCheckerSettings.contains("solvers")) { auto const& solversArray = modelCheckerSettings["solvers"]; - if (!solversArray.isArray()) + if (!solversArray.is_array()) return formatFatalError(Error::Type::JSONError, "settings.modelChecker.solvers must be an array."); smtutil::SMTSolverChoice solvers; for (auto const& s: solversArray) { - if (!s.isString()) + if (!s.is_string()) return formatFatalError(Error::Type::JSONError, "Every target in settings.modelChecker.solvers must be a string."); - if (!solvers.setSolver(s.asString())) + if (!solvers.setSolver(s.get())) return formatFatalError(Error::Type::JSONError, "Invalid model checker solvers requested."); } ret.modelCheckerSettings.solvers = solvers; } - if (modelCheckerSettings.isMember("printQuery")) + if (modelCheckerSettings.contains("printQuery")) { auto const& printQuery = modelCheckerSettings["printQuery"]; - if (!printQuery.isBool()) + if (!printQuery.is_boolean()) return formatFatalError(Error::Type::JSONError, "settings.modelChecker.printQuery must be a Boolean value."); if (!(ret.modelCheckerSettings.solvers == smtutil::SMTSolverChoice::SMTLIB2())) return formatFatalError(Error::Type::JSONError, "Only SMTLib2 solver can be enabled to print queries"); - ret.modelCheckerSettings.printQuery = printQuery.asBool(); + ret.modelCheckerSettings.printQuery = printQuery.get(); } - if (modelCheckerSettings.isMember("targets")) + if (modelCheckerSettings.contains("targets")) { auto const& targetsArray = modelCheckerSettings["targets"]; - if (!targetsArray.isArray()) + if (!targetsArray.is_array()) return formatFatalError(Error::Type::JSONError, "settings.modelChecker.targets must be an array."); ModelCheckerTargets targets; for (auto const& t: targetsArray) { - if (!t.isString()) + if (!t.is_string()) return formatFatalError(Error::Type::JSONError, "Every target in settings.modelChecker.targets must be a string."); - if (!targets.setFromString(t.asString())) + if (!targets.setFromString(t.get())) return formatFatalError(Error::Type::JSONError, "Invalid model checker targets requested."); } @@ -1165,45 +1163,45 @@ std::variant StandardCompiler: ret.modelCheckerSettings.targets = targets; } - if (modelCheckerSettings.isMember("timeout")) + if (modelCheckerSettings.contains("timeout")) { - if (!modelCheckerSettings["timeout"].isUInt()) + if (!modelCheckerSettings["timeout"].is_number_unsigned()) return formatFatalError(Error::Type::JSONError, "settings.modelChecker.timeout must be an unsigned integer."); - ret.modelCheckerSettings.timeout = modelCheckerSettings["timeout"].asUInt(); + ret.modelCheckerSettings.timeout = modelCheckerSettings["timeout"].get(); } return {std::move(ret)}; } -std::map StandardCompiler::parseAstFromInput(StringMap const& _sources) +std::map StandardCompiler::parseAstFromInput(StringMap const& _sources) { - std::map sourceJsons; + std::map sourceJsons; for (auto const& [sourceName, sourceCode]: _sources) { - Json::Value ast; + Json ast; astAssert(util::jsonParseStrict(sourceCode, ast), "Input file could not be parsed to JSON"); - std::string astKey = ast.isMember("ast") ? "ast" : "AST"; + std::string astKey = ast.contains("ast") ? "ast" : "AST"; - astAssert(ast.isMember(astKey), "astkey is not member"); - astAssert(ast[astKey]["nodeType"].asString() == "SourceUnit", "Top-level node should be a 'SourceUnit'"); + astAssert(ast.contains(astKey), "astkey is not member"); + astAssert(ast[astKey]["nodeType"].get() == "SourceUnit", "Top-level node should be a 'SourceUnit'"); astAssert(sourceJsons.count(sourceName) == 0, "All sources must have unique names"); sourceJsons.emplace(sourceName, std::move(ast[astKey])); } return sourceJsons; } -Json::Value StandardCompiler::importEVMAssembly(StandardCompiler::InputsAndSettings _inputsAndSettings) +Json StandardCompiler::importEVMAssembly(StandardCompiler::InputsAndSettings _inputsAndSettings) { solAssert(_inputsAndSettings.language == "EVMAssembly"); solAssert(_inputsAndSettings.sources.empty()); solAssert(_inputsAndSettings.jsonSources.size() == 1); if (!isBinaryRequested(_inputsAndSettings.outputSelection)) - return Json::objectValue; + return Json::object(); evmasm::EVMAssemblyStack stack(_inputsAndSettings.evmVersion); std::string const& sourceName = _inputsAndSettings.jsonSources.begin()->first; // result of structured binding can only be used within lambda from C++20 on. - Json::Value const& sourceJson = _inputsAndSettings.jsonSources.begin()->second; + Json const& sourceJson = _inputsAndSettings.jsonSources.begin()->second; try { stack.analyze(sourceName, sourceJson); @@ -1226,11 +1224,11 @@ Json::Value StandardCompiler::importEVMAssembly(StandardCompiler::InputsAndSetti ); } if (!stack.compilationSuccessful()) - return Json::objectValue; + return Json::object(); // EVM bool const wildcardMatchesExperimental = false; - Json::Value evmData = Json::objectValue; + Json evmData; if (isArtifactRequested(_inputsAndSettings.outputSelection, sourceName, "", "evm.assembly", wildcardMatchesExperimental)) evmData["assembly"] = stack.assemblyString(sourceName, {}); if (isArtifactRequested(_inputsAndSettings.outputSelection, sourceName, "", "evm.legacyAssembly", wildcardMatchesExperimental)) @@ -1284,18 +1282,18 @@ Json::Value StandardCompiler::importEVMAssembly(StandardCompiler::InputsAndSetti } ); - Json::Value contractData = Json::objectValue; + Json contractData; if (!evmData.empty()) contractData["evm"] = evmData; - Json::Value contractsOutput = Json::objectValue; + Json contractsOutput; contractsOutput[sourceName][""] = contractData; - Json::Value output = Json::objectValue; + Json output; output["contracts"] = contractsOutput; return util::removeNullMembers(output); } -Json::Value StandardCompiler::compileSolidity(StandardCompiler::InputsAndSettings _inputsAndSettings) +Json StandardCompiler::compileSolidity(StandardCompiler::InputsAndSettings _inputsAndSettings) { solAssert(_inputsAndSettings.jsonSources.empty()); @@ -1323,7 +1321,7 @@ Json::Value StandardCompiler::compileSolidity(StandardCompiler::InputsAndSetting compilerStack.enableEvmBytecodeGeneration(isEvmBytecodeRequested(_inputsAndSettings.outputSelection)); compilerStack.enableIRGeneration(isIRRequested(_inputsAndSettings.outputSelection)); - Json::Value errors = std::move(_inputsAndSettings.errors); + Json errors = std::move(_inputsAndSettings.errors); bool const binariesRequested = isBinaryRequested(_inputsAndSettings.outputSelection); @@ -1335,7 +1333,7 @@ Json::Value StandardCompiler::compileSolidity(StandardCompiler::InputsAndSetting { compilerStack.importASTs(parseAstFromInput(sourceList)); if (!compilerStack.analyze()) - errors.append(formatError(Error::Type::FatalError, "general", "Analysis of the AST failed.")); + errors.emplace_back(formatError(Error::Type::FatalError, "general", "Analysis of the AST failed.")); if (binariesRequested) compilerStack.compile(); } @@ -1352,7 +1350,7 @@ Json::Value StandardCompiler::compileSolidity(StandardCompiler::InputsAndSetting compilerStack.parseAndAnalyze(_inputsAndSettings.stopAfter); for (auto const& error: compilerStack.errors()) - errors.append(formatErrorWithException( + errors.emplace_back(formatErrorWithException( compilerStack, *error, error->type(), @@ -1365,7 +1363,7 @@ Json::Value StandardCompiler::compileSolidity(StandardCompiler::InputsAndSetting /// This is only thrown in a very few locations. catch (Error const& _error) { - errors.append(formatErrorWithException( + errors.emplace_back(formatErrorWithException( compilerStack, _error, _error.type(), @@ -1376,7 +1374,7 @@ Json::Value StandardCompiler::compileSolidity(StandardCompiler::InputsAndSetting /// This should not be leaked from compile(). catch (FatalError const& _exception) { - errors.append(formatError( + errors.emplace_back(formatError( Error::Type::FatalError, "general", "Uncaught fatal error: " + boost::diagnostic_information(_exception) @@ -1384,7 +1382,7 @@ Json::Value StandardCompiler::compileSolidity(StandardCompiler::InputsAndSetting } catch (CompilerError const& _exception) { - errors.append(formatErrorWithException( + errors.emplace_back(formatErrorWithException( compilerStack, _exception, Error::Type::CompilerError, @@ -1394,7 +1392,7 @@ Json::Value StandardCompiler::compileSolidity(StandardCompiler::InputsAndSetting } catch (InternalCompilerError const& _exception) { - errors.append(formatErrorWithException( + errors.emplace_back(formatErrorWithException( compilerStack, _exception, Error::Type::InternalCompilerError, @@ -1404,7 +1402,7 @@ Json::Value StandardCompiler::compileSolidity(StandardCompiler::InputsAndSetting } catch (UnimplementedFeatureError const& _exception) { - errors.append(formatErrorWithException( + errors.emplace_back(formatErrorWithException( compilerStack, _exception, Error::Type::UnimplementedFeatureError, @@ -1414,7 +1412,7 @@ Json::Value StandardCompiler::compileSolidity(StandardCompiler::InputsAndSetting } catch (yul::YulException const& _exception) { - errors.append(formatErrorWithException( + errors.emplace_back(formatErrorWithException( compilerStack, _exception, Error::Type::YulException, @@ -1424,7 +1422,7 @@ Json::Value StandardCompiler::compileSolidity(StandardCompiler::InputsAndSetting } catch (smtutil::SMTLogicError const& _exception) { - errors.append(formatErrorWithException( + errors.emplace_back(formatErrorWithException( compilerStack, _exception, Error::Type::SMTLogicException, @@ -1434,7 +1432,7 @@ Json::Value StandardCompiler::compileSolidity(StandardCompiler::InputsAndSetting } catch (util::Exception const& _exception) { - errors.append(formatError( + errors.emplace_back(formatError( Error::Type::Exception, "general", "Exception during compilation: " + boost::diagnostic_information(_exception) @@ -1442,7 +1440,7 @@ Json::Value StandardCompiler::compileSolidity(StandardCompiler::InputsAndSetting } catch (std::exception const& _exception) { - errors.append(formatError( + errors.emplace_back(formatError( Error::Type::Exception, "general", "Unknown exception during compilation: " + boost::diagnostic_information(_exception) @@ -1450,7 +1448,7 @@ Json::Value StandardCompiler::compileSolidity(StandardCompiler::InputsAndSetting } catch (...) { - errors.append(formatError( + errors.emplace_back(formatError( Error::Type::Exception, "general", "Unknown exception during compilation: " + boost::current_exception_diagnostic_information() @@ -1473,7 +1471,7 @@ Json::Value StandardCompiler::compileSolidity(StandardCompiler::InputsAndSetting ) return formatFatalError(Error::Type::InternalCompilerError, "No error reported, but compilation failed."); - Json::Value output = Json::objectValue; + Json output; if (errors.size() > 0) output["errors"] = std::move(errors); @@ -1484,21 +1482,21 @@ Json::Value StandardCompiler::compileSolidity(StandardCompiler::InputsAndSetting bool const wildcardMatchesExperimental = false; - output["sources"] = Json::objectValue; + output["sources"] = Json::object(); unsigned sourceIndex = 0; // NOTE: A case that will pass `parsingSuccess && !analysisFailed` but not `analysisSuccess` is // stopAfter: parsing with no parsing errors. if (parsingSuccess && !analysisFailed) for (std::string const& sourceName: compilerStack.sourceNames()) { - Json::Value sourceResult = Json::objectValue; + Json sourceResult; sourceResult["id"] = sourceIndex++; if (isArtifactRequested(_inputsAndSettings.outputSelection, sourceName, "", "ast", wildcardMatchesExperimental)) sourceResult["ast"] = ASTJsonExporter(compilerStack.state(), compilerStack.sourceIndices()).toJson(compilerStack.ast(sourceName)); output["sources"][sourceName] = sourceResult; } - Json::Value contractsOutput = Json::objectValue; + Json contractsOutput; for (std::string const& contractName: analysisSuccess ? compilerStack.contractNames() : std::vector()) { size_t colon = contractName.rfind(':'); @@ -1507,7 +1505,7 @@ Json::Value StandardCompiler::compileSolidity(StandardCompiler::InputsAndSetting std::string name = contractName.substr(colon + 1); // ABI, storage layout, documentation and metadata - Json::Value contractData(Json::objectValue); + Json contractData; if (isArtifactRequested(_inputsAndSettings.outputSelection, file, name, "abi", wildcardMatchesExperimental)) contractData["abi"] = compilerStack.contractABI(contractName); if (isArtifactRequested(_inputsAndSettings.outputSelection, file, name, "storageLayout", false)) @@ -1530,7 +1528,7 @@ Json::Value StandardCompiler::compileSolidity(StandardCompiler::InputsAndSetting contractData["irOptimizedAst"] = compilerStack.yulIROptimizedAst(contractName); // EVM - Json::Value evmData(Json::objectValue); + Json evmData; if (compilationSuccess && isArtifactRequested(_inputsAndSettings.outputSelection, file, name, "evm.assembly", wildcardMatchesExperimental)) evmData["assembly"] = compilerStack.assemblyString(contractName, sourceList); if (compilationSuccess && isArtifactRequested(_inputsAndSettings.outputSelection, file, name, "evm.legacyAssembly", wildcardMatchesExperimental)) @@ -1589,8 +1587,8 @@ Json::Value StandardCompiler::compileSolidity(StandardCompiler::InputsAndSetting if (!contractData.empty()) { - if (!contractsOutput.isMember(file)) - contractsOutput[file] = Json::objectValue; + if (!contractsOutput.contains(file)) + contractsOutput[file] = Json::object(); contractsOutput[file][name] = contractData; } } @@ -1601,16 +1599,16 @@ Json::Value StandardCompiler::compileSolidity(StandardCompiler::InputsAndSetting } -Json::Value StandardCompiler::compileYul(InputsAndSettings _inputsAndSettings) +Json StandardCompiler::compileYul(InputsAndSettings _inputsAndSettings) { solAssert(_inputsAndSettings.jsonSources.empty()); - Json::Value output = Json::objectValue; + Json output; output["errors"] = std::move(_inputsAndSettings.errors); if (_inputsAndSettings.sources.size() != 1) { - output["errors"].append(formatError( + output["errors"].emplace_back(formatError( Error::Type::JSONError, "general", "Yul mode only supports exactly one input file." @@ -1619,7 +1617,7 @@ Json::Value StandardCompiler::compileYul(InputsAndSettings _inputsAndSettings) } if (!_inputsAndSettings.smtLib2Responses.empty()) { - output["errors"].append(formatError( + output["errors"].emplace_back(formatError( Error::Type::JSONError, "general", "Yul mode does not support smtlib2responses." @@ -1628,7 +1626,7 @@ Json::Value StandardCompiler::compileYul(InputsAndSettings _inputsAndSettings) } if (!_inputsAndSettings.remappings.empty()) { - output["errors"].append(formatError( + output["errors"].emplace_back(formatError( Error::Type::JSONError, "general", "Field \"settings.remappings\" cannot be used for Yul." @@ -1637,7 +1635,7 @@ Json::Value StandardCompiler::compileYul(InputsAndSettings _inputsAndSettings) } if (_inputsAndSettings.revertStrings != RevertStrings::Default) { - output["errors"].append(formatError( + output["errors"].emplace_back(formatError( Error::Type::JSONError, "general", "Field \"settings.debug.revertStrings\" cannot be used for Yul." @@ -1660,7 +1658,7 @@ Json::Value StandardCompiler::compileYul(InputsAndSettings _inputsAndSettings) // Inconsistent state - stop here to receive error reports from users if (!stack.parseAndAnalyze(sourceName, sourceContents) && stack.errors().empty()) { - output["errors"].append(formatError( + output["errors"].emplace_back(formatError( Error::Type::InternalCompilerError, "general", "No error reported, but compilation failed." @@ -1674,7 +1672,7 @@ Json::Value StandardCompiler::compileYul(InputsAndSettings _inputsAndSettings) { auto err = std::dynamic_pointer_cast(error); - output["errors"].append(formatErrorWithException( + output["errors"].emplace_back(formatErrorWithException( stack, *error, err->type(), @@ -1693,7 +1691,7 @@ Json::Value StandardCompiler::compileYul(InputsAndSettings _inputsAndSettings) if (isArtifactRequested(_inputsAndSettings.outputSelection, sourceName, contractName, "ast", wildcardMatchesExperimental)) { - Json::Value sourceResult = Json::objectValue; + Json sourceResult; sourceResult["id"] = 0; sourceResult["ast"] = stack.astJson(); output["sources"][sourceName] = sourceResult; @@ -1725,7 +1723,7 @@ Json::Value StandardCompiler::compileYul(InputsAndSettings _inputsAndSettings) _inputsAndSettings.evmVersion, *o.bytecode, o.sourceMappings.get(), - Json::arrayValue, + Json::array(), isDeployed, [&, kind = kind](std::string const& _element) { return isArtifactRequested( _inputsAndSettings.outputSelection, @@ -1745,16 +1743,15 @@ Json::Value StandardCompiler::compileYul(InputsAndSettings _inputsAndSettings) return output; } - -Json::Value StandardCompiler::compile(Json::Value const& _input) noexcept +Json StandardCompiler::compile(Json const& _input) noexcept { YulStringRepository::reset(); try { auto parsed = parseInput(_input); - if (std::holds_alternative(parsed)) - return std::get(std::move(parsed)); + if (std::holds_alternative(parsed)) + return std::get(std::move(parsed)); InputsAndSettings settings = std::get(std::move(parsed)); if (settings.language == "Solidity") return compileSolidity(std::move(settings)); @@ -1767,13 +1764,29 @@ Json::Value StandardCompiler::compile(Json::Value const& _input) noexcept else return formatFatalError(Error::Type::JSONError, "Only \"Solidity\", \"Yul\", \"SolidityAST\" or \"EVMAssembly\" is supported as a language."); } - catch (Json::LogicError const& _exception) + catch (Json::parse_error const& _exception) + { + return formatFatalError(Error::Type::InternalCompilerError, std::string("JSON parse_error exception: ") + util::removeNlohmannInternalErrorIdentifier(_exception.what())); + } + catch (Json::invalid_iterator const& _exception) + { + return formatFatalError(Error::Type::InternalCompilerError, std::string("JSON invalid_iterator exception: ") + util::removeNlohmannInternalErrorIdentifier(_exception.what())); + } + catch (Json::type_error const& _exception) + { + return formatFatalError(Error::Type::InternalCompilerError, std::string("JSON type_error exception: ") + util::removeNlohmannInternalErrorIdentifier(_exception.what())); + } + catch (Json::out_of_range const& _exception) { - return formatFatalError(Error::Type::InternalCompilerError, std::string("JSON logic exception: ") + _exception.what()); + return formatFatalError(Error::Type::InternalCompilerError, std::string("JSON out_of_range exception: ") + util::removeNlohmannInternalErrorIdentifier(_exception.what())); } - catch (Json::RuntimeError const& _exception) + catch (Json::other_error const& _exception) { - return formatFatalError(Error::Type::InternalCompilerError, std::string("JSON runtime exception: ") + _exception.what()); + return formatFatalError(Error::Type::InternalCompilerError, std::string("JSON other_error exception: ") + util::removeNlohmannInternalErrorIdentifier(_exception.what())); + } + catch (Json::exception const& _exception) + { + return formatFatalError(Error::Type::InternalCompilerError, std::string("JSON runtime exception: ") + util::removeNlohmannInternalErrorIdentifier(_exception.what())); } catch (util::Exception const& _exception) { @@ -1787,7 +1800,7 @@ Json::Value StandardCompiler::compile(Json::Value const& _input) noexcept std::string StandardCompiler::compile(std::string const& _input) noexcept { - Json::Value input; + Json input; std::string errors; try { @@ -1796,12 +1809,15 @@ std::string StandardCompiler::compile(std::string const& _input) noexcept } catch (...) { - return "{\"errors\":[{\"type\":\"JSONError\",\"component\":\"general\",\"severity\":\"error\",\"message\":\"Error parsing input JSON.\"}]}"; + if (errors.empty()) + return "{\"errors\":[{\"type\":\"JSONError\",\"component\":\"general\",\"severity\":\"error\",\"message\":\"Error parsing input JSON.\"}]}"; + else + return "{\"errors\":[{\"type\":\"JSONError\",\"component\":\"general\",\"severity\":\"error\",\"message\":\"Error parsing input JSON: " + errors + "\"}]}"; } - // cout << "Input: " << input.toStyledString() << endl; - Json::Value output = compile(input); - // cout << "Output: " << output.toStyledString() << endl; +// std::cout << "Input: " << solidity::util::jsonPrettyPrint(input) << std::endl; + Json output = compile(input); +// std::cout << "Output: " << solidity::util::jsonPrettyPrint(output) << std::endl; try { @@ -1813,24 +1829,25 @@ std::string StandardCompiler::compile(std::string const& _input) noexcept } } -Json::Value StandardCompiler::formatFunctionDebugData( +Json StandardCompiler::formatFunctionDebugData( std::map const& _debugInfo ) { - Json::Value ret(Json::objectValue); + static_assert(std::is_same_v); + Json ret = Json::object(); for (auto const& [name, info]: _debugInfo) { - Json::Value fun; + Json fun = Json::object(); if (info.sourceID) - fun["id"] = Json::UInt64(*info.sourceID); + fun["id"] = Json::number_unsigned_t(*info.sourceID); else - fun["id"] = Json::nullValue; + fun["id"] = Json(); if (info.bytecodeOffset) - fun["entryPoint"] = Json::UInt64(*info.bytecodeOffset); + fun["entryPoint"] = Json::number_unsigned_t(*info.bytecodeOffset); else - fun["entryPoint"] = Json::nullValue; - fun["parameterSlots"] = Json::UInt64(info.params); - fun["returnSlots"] = Json::UInt64(info.returns); + fun["entryPoint"] = Json(); + fun["parameterSlots"] = Json::number_unsigned_t(info.params); + fun["returnSlots"] = Json::number_unsigned_t(info.returns); ret[name] = std::move(fun); } diff --git a/libsolidity/interface/StandardCompiler.h b/libsolidity/interface/StandardCompiler.h index 03bdc7f12bd2..590d96b9c191 100644 --- a/libsolidity/interface/StandardCompiler.h +++ b/libsolidity/interface/StandardCompiler.h @@ -58,12 +58,12 @@ class StandardCompiler /// Sets all input parameters according to @a _input which conforms to the standardized input /// format, performs compilation and returns a standardized output. - Json::Value compile(Json::Value const& _input) noexcept; + Json compile(Json const& _input) noexcept; /// Parses input as JSON and performs the above processing steps, returning a serialized JSON /// output. Parsing errors are returned as regular errors. std::string compile(std::string const& _input) noexcept; - static Json::Value formatFunctionDebugData( + static Json formatFunctionDebugData( std::map const& _debugInfo ); @@ -71,10 +71,10 @@ class StandardCompiler struct InputsAndSettings { std::string language; - Json::Value errors; + Json errors; CompilerStack::State stopAfter = CompilerStack::State::CompilationSuccessful; std::map sources; - std::map jsonSources; + std::map jsonSources; std::map smtLib2Responses; langutil::EVMVersion evmVersion; std::optional eofVersion; @@ -86,19 +86,19 @@ class StandardCompiler bool metadataLiteralSources = false; CompilerStack::MetadataFormat metadataFormat = CompilerStack::defaultMetadataFormat(); CompilerStack::MetadataHash metadataHash = CompilerStack::MetadataHash::IPFS; - Json::Value outputSelection; + Json outputSelection; ModelCheckerSettings modelCheckerSettings = ModelCheckerSettings{}; bool viaIR = false; }; /// Parses the input json (and potentially invokes the read callback) and either returns /// it in condensed form or an error as a json object. - std::variant parseInput(Json::Value const& _input); + std::variant parseInput(Json const& _input); - std::map parseAstFromInput(StringMap const& _sources); - Json::Value importEVMAssembly(InputsAndSettings _inputsAndSettings); - Json::Value compileSolidity(InputsAndSettings _inputsAndSettings); - Json::Value compileYul(InputsAndSettings _inputsAndSettings); + std::map parseAstFromInput(StringMap const& _sources); + Json importEVMAssembly(InputsAndSettings _inputsAndSettings); + Json compileSolidity(InputsAndSettings _inputsAndSettings); + Json compileYul(InputsAndSettings _inputsAndSettings); ReadCallback::Callback m_readFile; diff --git a/libsolidity/interface/StorageLayout.cpp b/libsolidity/interface/StorageLayout.cpp index 8e1d0eed101d..7f344f6edf65 100644 --- a/libsolidity/interface/StorageLayout.cpp +++ b/libsolidity/interface/StorageLayout.cpp @@ -23,7 +23,7 @@ using namespace solidity; using namespace solidity::frontend; -Json::Value StorageLayout::generate(ContractDefinition const& _contractDef) +Json StorageLayout::generate(ContractDefinition const& _contractDef) { solAssert(!m_contract, ""); m_contract = &_contractDef; @@ -34,19 +34,19 @@ Json::Value StorageLayout::generate(ContractDefinition const& _contractDef) auto contractType = dynamic_cast(typeType->actualType()); solAssert(contractType, ""); - Json::Value variables(Json::arrayValue); + Json variables = Json::array(); for (auto [var, slot, offset]: contractType->stateVariables()) - variables.append(generate(*var, slot, offset)); + variables.emplace_back(generate(*var, slot, offset)); - Json::Value layout; + Json layout; layout["storage"] = std::move(variables); layout["types"] = std::move(m_types); return layout; } -Json::Value StorageLayout::generate(VariableDeclaration const& _var, u256 const& _slot, unsigned _offset) +Json StorageLayout::generate(VariableDeclaration const& _var, u256 const& _slot, unsigned _offset) { - Json::Value varEntry; + Json varEntry; Type const* varType = _var.type(); varEntry["label"] = _var.name(); @@ -63,22 +63,22 @@ Json::Value StorageLayout::generate(VariableDeclaration const& _var, u256 const& void StorageLayout::generate(Type const* _type) { - if (m_types.isMember(typeKeyName(_type))) + if (m_types.contains(typeKeyName(_type))) return; // Register it now to cut recursive visits. - Json::Value& typeInfo = m_types[typeKeyName(_type)]; + Json& typeInfo = m_types[typeKeyName(_type)]; typeInfo["label"] = _type->toString(true); typeInfo["numberOfBytes"] = u256(_type->storageBytes() * _type->storageSize()).str(); if (auto structType = dynamic_cast(_type)) { - Json::Value members(Json::arrayValue); + Json members = Json::array(); auto const& structDef = structType->structDefinition(); for (auto const& member: structDef.members()) { auto const& offsets = structType->storageOffsetsOfMember(member->name()); - members.append(generate(*member, offsets.first, offsets.second)); + members.emplace_back(generate(*member, offsets.first, offsets.second)); } typeInfo["members"] = std::move(members); typeInfo["encoding"] = "inplace"; @@ -108,7 +108,7 @@ void StorageLayout::generate(Type const* _type) typeInfo["encoding"] = "inplace"; } - solAssert(typeInfo.isMember("encoding"), ""); + solAssert(typeInfo.contains("encoding"), ""); } std::string StorageLayout::typeKeyName(Type const* _type) diff --git a/libsolidity/interface/StorageLayout.h b/libsolidity/interface/StorageLayout.h index ffe8e6b5a0c6..b0b2d70b6df5 100644 --- a/libsolidity/interface/StorageLayout.h +++ b/libsolidity/interface/StorageLayout.h @@ -21,11 +21,10 @@ #pragma once +#include #include #include -#include - namespace solidity::frontend { @@ -35,11 +34,11 @@ class StorageLayout /// Generates the storage layout of the contract /// @param _contractDef The contract definition /// @return A JSON representation of the contract's storage layout. - Json::Value generate(ContractDefinition const& _contractDef); + Json generate(ContractDefinition const& _contractDef); private: /// Generates the JSON information for a variable and its storage location. - Json::Value generate(VariableDeclaration const& _var, u256 const& _slot, unsigned _offset); + Json generate(VariableDeclaration const& _var, u256 const& _slot, unsigned _offset); /// Generates the JSON information for @param _type void generate(Type const* _type); @@ -47,7 +46,7 @@ class StorageLayout /// The key for the JSON object describing a type. std::string typeKeyName(Type const* _type); - Json::Value m_types; + Json m_types; /// Current analyzed contract ContractDefinition const* m_contract = nullptr; diff --git a/libsolidity/lsp/DocumentHoverHandler.cpp b/libsolidity/lsp/DocumentHoverHandler.cpp index 39d1d72c331c..e5991b765a66 100644 --- a/libsolidity/lsp/DocumentHoverHandler.cpp +++ b/libsolidity/lsp/DocumentHoverHandler.cpp @@ -55,7 +55,7 @@ struct MarkdownBuilder } -void DocumentHoverHandler::operator()(MessageID _id, Json::Value const& _args) +void DocumentHoverHandler::operator()(MessageID _id, Json const& _args) { auto const [sourceUnitName, lineColumn] = HandlerBase(*this).extractSourceUnitNameAndLineColumn(_args); auto const [sourceNode, sourceOffset] = m_server.astNodeAndOffsetAtSourceLocation(sourceUnitName, lineColumn); @@ -108,11 +108,11 @@ void DocumentHoverHandler::operator()(MessageID _id, Json::Value const& _args) if (tooltipText.empty()) { - client().reply(_id, Json::nullValue); + client().reply(_id, Json()); return; } - Json::Value reply = Json::objectValue; + Json reply; reply["range"] = rangeToHighlight; reply["contents"]["kind"] = "markdown"; reply["contents"]["value"] = std::move(tooltipText); diff --git a/libsolidity/lsp/DocumentHoverHandler.h b/libsolidity/lsp/DocumentHoverHandler.h index 9bb4084c261e..e35e856098f0 100644 --- a/libsolidity/lsp/DocumentHoverHandler.h +++ b/libsolidity/lsp/DocumentHoverHandler.h @@ -26,7 +26,7 @@ class DocumentHoverHandler: public HandlerBase public: using HandlerBase::HandlerBase; - void operator()(MessageID, Json::Value const&); + void operator()(MessageID, Json const&); }; } diff --git a/libsolidity/lsp/GotoDefinition.cpp b/libsolidity/lsp/GotoDefinition.cpp index 136e4d7c391b..07b0c6f0be3c 100644 --- a/libsolidity/lsp/GotoDefinition.cpp +++ b/libsolidity/lsp/GotoDefinition.cpp @@ -31,7 +31,7 @@ using namespace solidity::frontend; using namespace solidity::langutil; using namespace solidity::lsp; -void GotoDefinition::operator()(MessageID _id, Json::Value const& _args) +void GotoDefinition::operator()(MessageID _id, Json const& _args) { auto const [sourceUnitName, lineColumn] = extractSourceUnitNameAndLineColumn(_args); @@ -58,8 +58,8 @@ void GotoDefinition::operator()(MessageID _id, Json::Value const& _args) locations.emplace_back(SourceLocation{0, 0, std::make_shared(path)}); } - Json::Value reply = Json::arrayValue; + Json reply = Json::array(); for (SourceLocation const& location: locations) - reply.append(toJson(location)); + reply.emplace_back(toJson(location)); client().reply(_id, reply); } diff --git a/libsolidity/lsp/GotoDefinition.h b/libsolidity/lsp/GotoDefinition.h index 453da3f1561c..4ffd64e7ff22 100644 --- a/libsolidity/lsp/GotoDefinition.h +++ b/libsolidity/lsp/GotoDefinition.h @@ -25,7 +25,7 @@ class GotoDefinition: public HandlerBase public: explicit GotoDefinition(LanguageServer& _server): HandlerBase(_server) {} - void operator()(MessageID, Json::Value const&); + void operator()(MessageID, Json const&); }; } diff --git a/libsolidity/lsp/HandlerBase.cpp b/libsolidity/lsp/HandlerBase.cpp index a23e43a83ce1..c49bce1dd697 100644 --- a/libsolidity/lsp/HandlerBase.cpp +++ b/libsolidity/lsp/HandlerBase.cpp @@ -29,8 +29,9 @@ using namespace solidity::langutil; using namespace solidity::lsp; using namespace solidity::util; +using namespace solidity; -Json::Value HandlerBase::toRange(SourceLocation const& _location) const +Json HandlerBase::toRange(SourceLocation const& _location) const { if (!_location.hasText()) return toJsonRange({}, {}); @@ -42,18 +43,18 @@ Json::Value HandlerBase::toRange(SourceLocation const& _location) const return toJsonRange(start, end); } -Json::Value HandlerBase::toJson(SourceLocation const& _location) const +Json HandlerBase::toJson(SourceLocation const& _location) const { solAssert(_location.sourceName); - Json::Value item = Json::objectValue; + Json item; item["uri"] = fileRepository().sourceUnitNameToUri(*_location.sourceName); item["range"] = toRange(_location); return item; } -std::pair HandlerBase::extractSourceUnitNameAndLineColumn(Json::Value const& _args) const +std::pair HandlerBase::extractSourceUnitNameAndLineColumn(Json const& _args) const { - std::string const uri = _args["textDocument"]["uri"].asString(); + std::string const uri = _args["textDocument"]["uri"].get(); std::string const sourceUnitName = fileRepository().uriToSourceUnitName(uri); if (!fileRepository().sourceUnits().count(sourceUnitName)) BOOST_THROW_EXCEPTION( diff --git a/libsolidity/lsp/HandlerBase.h b/libsolidity/lsp/HandlerBase.h index e2ccb88d82ec..718d15c5f631 100644 --- a/libsolidity/lsp/HandlerBase.h +++ b/libsolidity/lsp/HandlerBase.h @@ -38,12 +38,12 @@ class HandlerBase public: explicit HandlerBase(LanguageServer& _server): m_server{_server} {} - Json::Value toRange(langutil::SourceLocation const& _location) const; - Json::Value toJson(langutil::SourceLocation const& _location) const; + Json toRange(langutil::SourceLocation const& _location) const; + Json toJson(langutil::SourceLocation const& _location) const; /// @returns source unit name and the line column position as extracted /// from the JSON-RPC parameters. - std::pair extractSourceUnitNameAndLineColumn(Json::Value const& _params) const; + std::pair extractSourceUnitNameAndLineColumn(Json const& _params) const; langutil::CharStreamProvider const& charStreamProvider() const noexcept { return m_server.compilerStack(); } FileRepository& fileRepository() const noexcept { return m_server.fileRepository(); } diff --git a/libsolidity/lsp/LanguageServer.cpp b/libsolidity/lsp/LanguageServer.cpp index 2b8b62706d50..d726139e3a73 100644 --- a/libsolidity/lsp/LanguageServer.cpp +++ b/libsolidity/lsp/LanguageServer.cpp @@ -52,6 +52,7 @@ using namespace std::placeholders; using namespace solidity::lsp; using namespace solidity::langutil; using namespace solidity::frontend; +using namespace solidity; namespace fs = boost::filesystem; @@ -85,44 +86,44 @@ int toDiagnosticSeverity(Error::Type _errorType) return -1; } -Json::Value semanticTokensLegend() +Json semanticTokensLegend() { - Json::Value legend = Json::objectValue; + Json legend; // NOTE! The (alphabetical) order and items must match exactly the items of // their respective enum class members. - Json::Value tokenTypes = Json::arrayValue; - tokenTypes.append("class"); - tokenTypes.append("comment"); - tokenTypes.append("enum"); - tokenTypes.append("enumMember"); - tokenTypes.append("event"); - tokenTypes.append("function"); - tokenTypes.append("interface"); - tokenTypes.append("keyword"); - tokenTypes.append("macro"); - tokenTypes.append("method"); - tokenTypes.append("modifier"); - tokenTypes.append("number"); - tokenTypes.append("operator"); - tokenTypes.append("parameter"); - tokenTypes.append("property"); - tokenTypes.append("std::string"); - tokenTypes.append("struct"); - tokenTypes.append("type"); - tokenTypes.append("typeParameter"); - tokenTypes.append("variable"); + Json tokenTypes = Json::array(); + tokenTypes.emplace_back("class"); + tokenTypes.emplace_back("comment"); + tokenTypes.emplace_back("enum"); + tokenTypes.emplace_back("enumMember"); + tokenTypes.emplace_back("event"); + tokenTypes.emplace_back("function"); + tokenTypes.emplace_back("interface"); + tokenTypes.emplace_back("keyword"); + tokenTypes.emplace_back("macro"); + tokenTypes.emplace_back("method"); + tokenTypes.emplace_back("modifier"); + tokenTypes.emplace_back("number"); + tokenTypes.emplace_back("operator"); + tokenTypes.emplace_back("parameter"); + tokenTypes.emplace_back("property"); + tokenTypes.emplace_back("std::string"); + tokenTypes.emplace_back("struct"); + tokenTypes.emplace_back("type"); + tokenTypes.emplace_back("typeParameter"); + tokenTypes.emplace_back("variable"); legend["tokenTypes"] = tokenTypes; - Json::Value tokenModifiers = Json::arrayValue; - tokenModifiers.append("abstract"); - tokenModifiers.append("declaration"); - tokenModifiers.append("definition"); - tokenModifiers.append("deprecated"); - tokenModifiers.append("documentation"); - tokenModifiers.append("modification"); - tokenModifiers.append("readonly"); + Json tokenModifiers = Json::array(); + tokenModifiers.emplace_back("abstract"); + tokenModifiers.emplace_back("declaration"); + tokenModifiers.emplace_back("definition"); + tokenModifiers.emplace_back("deprecated"); + tokenModifiers.emplace_back("documentation"); + tokenModifiers.emplace_back("modification"); + tokenModifiers.emplace_back("readonly"); legend["tokenModifiers"] = tokenModifiers; return legend; @@ -138,7 +139,7 @@ LanguageServer::LanguageServer(Transport& _transport): {"exit", [this](auto, auto) { m_state = (m_state == State::ShutdownRequested ? State::ExitRequested : State::ExitWithoutShutdown); }}, {"initialize", std::bind(&LanguageServer::handleInitialize, this, _1, _2)}, {"initialized", std::bind(&LanguageServer::handleInitialized, this, _1, _2)}, - {"$/setTrace", [this](auto, Json::Value const& args) { setTrace(args["value"]); }}, + {"$/setTrace", [this](auto, Json const& args) { setTrace(args["value"]); }}, {"shutdown", [this](auto, auto) { m_state = State::ShutdownRequested; }}, {"textDocument/definition", GotoDefinition(*this) }, {"textDocument/didOpen", std::bind(&LanguageServer::handleTextDocumentDidOpen, this, _2)}, @@ -155,17 +156,17 @@ LanguageServer::LanguageServer(Transport& _transport): { } -Json::Value LanguageServer::toRange(SourceLocation const& _location) +Json LanguageServer::toRange(SourceLocation const& _location) { return HandlerBase(*this).toRange(_location); } -Json::Value LanguageServer::toJson(SourceLocation const& _location) +Json LanguageServer::toJson(SourceLocation const& _location) { return HandlerBase(*this).toJson(_location); } -void LanguageServer::changeConfiguration(Json::Value const& _settings) +void LanguageServer::changeConfiguration(Json const& _settings) { // The settings item: "file-load-strategy" (enum) defaults to "project-directory" if not (or not correctly) set. // It can be overridden during client's handshake or at runtime, as usual. @@ -176,9 +177,9 @@ void LanguageServer::changeConfiguration(Json::Value const& _settings) // // If this value is set to "directly-opened-and-on-import", then only currently directly opened files and // those files being imported directly or indirectly will be included in operations. - if (_settings["file-load-strategy"]) + if (_settings.contains("file-load-strategy")) { - auto const text = _settings["file-load-strategy"].asString(); + auto const text = _settings["file-load-strategy"].get(); if (text == "project-directory") m_fileLoadStrategy = FileLoadStrategy::ProjectDirectory; else if (text == "directly-opened-and-on-import") @@ -188,18 +189,18 @@ void LanguageServer::changeConfiguration(Json::Value const& _settings) } m_settingsObject = _settings; - Json::Value jsonIncludePaths = _settings["include-paths"]; + Json jsonIncludePaths = _settings.contains("include-paths") ? _settings["include-paths"] : Json::object(); - if (jsonIncludePaths) + if (!jsonIncludePaths.empty()) { int typeFailureCount = 0; - if (jsonIncludePaths.isArray()) + if (jsonIncludePaths.is_array()) { std::vector includePaths; - for (Json::Value const& jsonPath: jsonIncludePaths) + for (Json const& jsonPath: jsonIncludePaths) { - if (jsonPath.isString()) - includePaths.emplace_back(boost::filesystem::path(jsonPath.asString())); + if (jsonPath.is_string()) + includePaths.emplace_back(jsonPath.get()); else typeFailureCount++; } @@ -274,11 +275,11 @@ void LanguageServer::compileAndUpdateDiagnostics() // These are the source units we will sent diagnostics to the client for sure, // even if it is just to clear previous diagnostics. - std::map diagnosticsBySourceUnit; + std::map diagnosticsBySourceUnit; for (std::string const& sourceUnitName: m_fileRepository.sourceUnits() | ranges::views::keys) - diagnosticsBySourceUnit[sourceUnitName] = Json::arrayValue; + diagnosticsBySourceUnit[sourceUnitName] = Json::array(); for (std::string const& sourceUnitName: m_nonemptyDiagnostics) - diagnosticsBySourceUnit[sourceUnitName] = Json::arrayValue; + diagnosticsBySourceUnit[sourceUnitName] = Json::array(); for (std::shared_ptr const& error: m_compilerStack.errors()) { @@ -287,10 +288,10 @@ void LanguageServer::compileAndUpdateDiagnostics() // LSP only has diagnostics applied to individual files. continue; - Json::Value jsonDiag; + Json jsonDiag; jsonDiag["source"] = "solc"; jsonDiag["severity"] = toDiagnosticSeverity(error->type()); - jsonDiag["code"] = Json::UInt64{error->errorId().error}; + jsonDiag["code"] = Json(error->errorId().error); std::string message = Error::formatErrorType(error->type()) + ":"; if (std::string const* comment = error->comment()) message += " " + *comment; @@ -300,26 +301,26 @@ void LanguageServer::compileAndUpdateDiagnostics() if (auto const* secondary = error->secondarySourceLocation()) for (auto&& [secondaryMessage, secondaryLocation]: secondary->infos) { - Json::Value jsonRelated; + Json jsonRelated; jsonRelated["message"] = secondaryMessage; jsonRelated["location"] = toJson(secondaryLocation); - jsonDiag["relatedInformation"].append(jsonRelated); + jsonDiag["relatedInformation"].emplace_back(jsonRelated); } - diagnosticsBySourceUnit[*location->sourceName].append(jsonDiag); + diagnosticsBySourceUnit[*location->sourceName].emplace_back(jsonDiag); } if (m_client.traceValue() != TraceValue::Off) { - Json::Value extra; - extra["openFileCount"] = Json::UInt64(diagnosticsBySourceUnit.size()); + Json extra; + extra["openFileCount"] = Json(diagnosticsBySourceUnit.size()); m_client.trace("Number of currently open files: " + std::to_string(diagnosticsBySourceUnit.size()), extra); } m_nonemptyDiagnostics.clear(); for (auto&& [sourceUnitName, diagnostics]: diagnosticsBySourceUnit) { - Json::Value params; + Json params; params["uri"] = m_fileRepository.sourceUnitNameToUri(sourceUnitName); if (!diagnostics.empty()) m_nonemptyDiagnostics.insert(sourceUnitName); @@ -335,14 +336,15 @@ bool LanguageServer::run() MessageID id; try { - std::optional const jsonMessage = m_client.receive(); + std::optional const jsonMessage = m_client.receive(); if (!jsonMessage) continue; - if ((*jsonMessage)["method"].isString()) + if ((*jsonMessage).contains("method") && (*jsonMessage)["method"].is_string()) { - std::string const methodName = (*jsonMessage)["method"].asString(); - id = (*jsonMessage)["id"]; + std::string const methodName = (*jsonMessage)["method"].get(); + if ((*jsonMessage).contains("id")) + id = (*jsonMessage)["id"]; lspDebug(fmt::format("received method call: {}", methodName)); if (auto handler = util::valueOrDefault(m_handlers, methodName)) @@ -353,7 +355,7 @@ bool LanguageServer::run() else m_client.error({}, ErrorCode::ParseError, "\"method\" has to be a string."); } - catch (Json::Exception const&) + catch (Json::exception const&) { m_client.error(id, ErrorCode::InvalidParams, "JSON object access error. Most likely due to a badly formatted JSON request message."s); } @@ -378,7 +380,7 @@ void LanguageServer::requireServerInitialized() ); } -void LanguageServer::handleInitialize(MessageID _id, Json::Value const& _args) +void LanguageServer::handleInitialize(MessageID _id, Json const& _args) { lspRequire( m_state == State::Started, @@ -391,9 +393,9 @@ void LanguageServer::handleInitialize(MessageID _id, Json::Value const& _args) // The default of FileReader is to use `.`, but the path from where the LSP was started // should not matter. std::string rootPath("/"); - if (Json::Value uri = _args["rootUri"]) + if (_args.contains("rootUri") && _args["rootUri"].is_string()) { - rootPath = uri.asString(); + rootPath = _args["rootUri"].get(); lspRequire( boost::starts_with(rootPath, "file://"), ErrorCode::InvalidParams, @@ -401,17 +403,17 @@ void LanguageServer::handleInitialize(MessageID _id, Json::Value const& _args) ); rootPath = stripFileUriSchemePrefix(rootPath); } - else if (Json::Value rootPath = _args["rootPath"]) - rootPath = rootPath.asString(); + else if (_args.contains("rootPath")) + rootPath = _args["rootPath"].get(); - if (_args["trace"]) + if (_args.contains("trace")) setTrace(_args["trace"]); m_fileRepository = FileRepository(rootPath, {}); - if (_args["initializationOptions"].isObject()) + if (_args.contains("initializationOptions") && _args["initializationOptions"].is_object()) changeConfiguration(_args["initializationOptions"]); - Json::Value replyArgs; + Json replyArgs; replyArgs["serverInfo"]["name"] = "solc"; replyArgs["serverInfo"]["version"] = std::string(VersionNumber); replyArgs["capabilities"]["definitionProvider"] = true; @@ -427,44 +429,49 @@ void LanguageServer::handleInitialize(MessageID _id, Json::Value const& _args) m_client.reply(_id, std::move(replyArgs)); } -void LanguageServer::handleInitialized(MessageID, Json::Value const&) +void LanguageServer::handleInitialized(MessageID, Json const&) { if (m_fileLoadStrategy == FileLoadStrategy::ProjectDirectory) compileAndUpdateDiagnostics(); } -void LanguageServer::semanticTokensFull(MessageID _id, Json::Value const& _args) +void LanguageServer::semanticTokensFull(MessageID _id, Json const& _args) { - auto uri = _args["textDocument"]["uri"]; + if (_args.contains("textDocument") && _args["textDocument"].contains("uri")) + { + auto uri = _args["textDocument"]["uri"]; - compile(); + compile(); - auto const sourceName = m_fileRepository.uriToSourceUnitName(uri.as()); - SourceUnit const& ast = m_compilerStack.ast(sourceName); - m_compilerStack.charStream(sourceName); - Json::Value data = SemanticTokensBuilder().build(ast, m_compilerStack.charStream(sourceName)); + auto const sourceName = m_fileRepository.uriToSourceUnitName(uri.get()); + SourceUnit const& ast = m_compilerStack.ast(sourceName); + m_compilerStack.charStream(sourceName); + Json data = SemanticTokensBuilder().build(ast, m_compilerStack.charStream(sourceName)); - Json::Value reply = Json::objectValue; - reply["data"] = data; + Json reply; + reply["data"] = data; - m_client.reply(_id, std::move(reply)); + m_client.reply(_id, std::move(reply)); + } + else + m_client.error(_id, ErrorCode::InvalidParams, "Invalid parameter: textDocument.uri expected."); } -void LanguageServer::handleWorkspaceDidChangeConfiguration(Json::Value const& _args) +void LanguageServer::handleWorkspaceDidChangeConfiguration(Json const& _args) { requireServerInitialized(); - if (_args["settings"].isObject()) + if (_args.contains("settings") && _args["settings"].is_object()) changeConfiguration(_args["settings"]); } -void LanguageServer::setTrace(Json::Value const& _args) +void LanguageServer::setTrace(Json const& _args) { - if (!_args.isString()) + if (!_args.is_string()) // Simply ignore invalid parameter. return; - std::string const stringValue = _args.asString(); + std::string const stringValue = _args.get(); if (stringValue == "off") m_client.setTrace(TraceValue::Off); else if (stringValue == "messages") @@ -473,78 +480,90 @@ void LanguageServer::setTrace(Json::Value const& _args) m_client.setTrace(TraceValue::Verbose); } -void LanguageServer::handleTextDocumentDidOpen(Json::Value const& _args) +void LanguageServer::handleTextDocumentDidOpen(Json const& _args) { requireServerInitialized(); lspRequire( - _args["textDocument"], + _args.contains("textDocument"), ErrorCode::RequestFailed, "Text document parameter missing." ); - std::string text = _args["textDocument"]["text"].asString(); - std::string uri = _args["textDocument"]["uri"].asString(); - m_openFiles.insert(uri); - m_fileRepository.setSourceByUri(uri, std::move(text)); - compileAndUpdateDiagnostics(); + if (_args["textDocument"].contains("text") && _args["textDocument"].contains("uri")) + { + std::string text = _args["textDocument"]["text"].get(); + std::string uri = _args["textDocument"]["uri"].get(); + m_openFiles.insert(uri); + m_fileRepository.setSourceByUri(uri, std::move(text)); + compileAndUpdateDiagnostics(); + } } -void LanguageServer::handleTextDocumentDidChange(Json::Value const& _args) +void LanguageServer::handleTextDocumentDidChange(Json const& _args) { requireServerInitialized(); - std::string const uri = _args["textDocument"]["uri"].asString(); - - for (Json::Value jsonContentChange: _args["contentChanges"]) + if (_args.contains("textDocument") && _args["textDocument"].contains("uri")) { - lspRequire( - jsonContentChange.isObject(), - ErrorCode::RequestFailed, - "Invalid content reference." - ); - - std::string const sourceUnitName = m_fileRepository.uriToSourceUnitName(uri); - lspRequire( - m_fileRepository.sourceUnits().count(sourceUnitName), - ErrorCode::RequestFailed, - "Unknown file: " + uri - ); + std::string const uri = _args["textDocument"]["uri"].get(); - std::string text = jsonContentChange["text"].asString(); - if (jsonContentChange["range"].isObject()) // otherwise full content update - { - std::optional change = parseRange(m_fileRepository, sourceUnitName, jsonContentChange["range"]); - lspRequire( - change && change->hasText(), - ErrorCode::RequestFailed, - "Invalid source range: " + util::jsonCompactPrint(jsonContentChange["range"]) - ); + if (_args.contains("contentChanges")) + for (auto const& [_, jsonContentChange]: _args["contentChanges"].items()) + { + lspRequire(jsonContentChange.is_object(), ErrorCode::RequestFailed, "Invalid content reference."); + + std::string const sourceUnitName = m_fileRepository.uriToSourceUnitName(uri); + lspRequire( + m_fileRepository.sourceUnits().count(sourceUnitName), + ErrorCode::RequestFailed, + "Unknown file: " + uri); + + if (jsonContentChange.contains("text")) + { + std::string text = jsonContentChange["text"].get(); + if (jsonContentChange.contains("range") + && jsonContentChange["range"].is_object()) // otherwise full content update + { + std::optional change + = parseRange(m_fileRepository, sourceUnitName, jsonContentChange["range"]); + lspRequire( + change && change->hasText(), + ErrorCode::RequestFailed, + "Invalid source range: " + util::jsonCompactPrint(jsonContentChange["range"])); + + std::string buffer = m_fileRepository.sourceUnits().at(sourceUnitName); + buffer.replace( + static_cast(change->start), + static_cast(change->end - change->start), + std::move(text)); + text = std::move(buffer); + } + m_fileRepository.setSourceByUri(uri, std::move(text)); + } + } - std::string buffer = m_fileRepository.sourceUnits().at(sourceUnitName); - buffer.replace(static_cast(change->start), static_cast(change->end - change->start), std::move(text)); - text = std::move(buffer); - } - m_fileRepository.setSourceByUri(uri, std::move(text)); + compileAndUpdateDiagnostics(); } - - compileAndUpdateDiagnostics(); } -void LanguageServer::handleTextDocumentDidClose(Json::Value const& _args) +void LanguageServer::handleTextDocumentDidClose(Json const& _args) { requireServerInitialized(); lspRequire( - _args["textDocument"], + _args.contains("textDocument"), ErrorCode::RequestFailed, "Text document parameter missing." ); - std::string uri = _args["textDocument"]["uri"].asString(); - m_openFiles.erase(uri); + if (_args["textDocument"].contains("uri")) + { + std::string uri = _args["textDocument"]["uri"].get(); + m_openFiles.erase(uri); - compileAndUpdateDiagnostics(); + compileAndUpdateDiagnostics(); + } } ASTNode const* LanguageServer::astNodeAtSourceLocation(std::string const& _sourceUnitName, LineColumn const& _filePos) diff --git a/libsolidity/lsp/LanguageServer.h b/libsolidity/lsp/LanguageServer.h index d80f8e879c7a..4bea5809fa45 100644 --- a/libsolidity/lsp/LanguageServer.h +++ b/libsolidity/lsp/LanguageServer.h @@ -22,7 +22,7 @@ #include #include -#include +#include #include #include @@ -85,29 +85,29 @@ class LanguageServer /// Checks if the server is initialized (to be used by messages that need it to be initialized). /// Reports an error and returns false if not. void requireServerInitialized(); - void handleInitialize(MessageID _id, Json::Value const& _args); - void handleInitialized(MessageID _id, Json::Value const& _args); - void handleWorkspaceDidChangeConfiguration(Json::Value const& _args); - void setTrace(Json::Value const& _args); - void handleTextDocumentDidOpen(Json::Value const& _args); - void handleTextDocumentDidChange(Json::Value const& _args); - void handleTextDocumentDidClose(Json::Value const& _args); - void handleRename(Json::Value const& _args); - void handleGotoDefinition(MessageID _id, Json::Value const& _args); - void semanticTokensFull(MessageID _id, Json::Value const& _args); + void handleInitialize(MessageID _id, Json const& _args); + void handleInitialized(MessageID _id, Json const& _args); + void handleWorkspaceDidChangeConfiguration(Json const& _args); + void setTrace(Json const& _args); + void handleTextDocumentDidOpen(Json const& _args); + void handleTextDocumentDidChange(Json const& _args); + void handleTextDocumentDidClose(Json const& _args); + void handleRename(Json const& _args); + void handleGotoDefinition(MessageID _id, Json const& _args); + void semanticTokensFull(MessageID _id, Json const& _args); /// Invoked when the server user-supplied configuration changes (initiated by the client). - void changeConfiguration(Json::Value const&); + void changeConfiguration(Json const&); /// Compile everything until after analysis phase. void compile(); std::vector allSolidityFilesFromProject() const; - using MessageHandler = std::function; + using MessageHandler = std::function; - Json::Value toRange(langutil::SourceLocation const& _location); - Json::Value toJson(langutil::SourceLocation const& _location); + Json toRange(langutil::SourceLocation const& _location); + Json toJson(langutil::SourceLocation const& _location); // LSP related member fields @@ -127,7 +127,7 @@ class LanguageServer frontend::CompilerStack m_compilerStack; /// User-supplied custom configuration settings (such as EVM version). - Json::Value m_settingsObject; + Json m_settingsObject; }; } diff --git a/libsolidity/lsp/RenameSymbol.cpp b/libsolidity/lsp/RenameSymbol.cpp index 75f032fcca47..497ee50fb451 100644 --- a/libsolidity/lsp/RenameSymbol.cpp +++ b/libsolidity/lsp/RenameSymbol.cpp @@ -47,11 +47,11 @@ CallableDeclaration const* extractCallableDeclaration(FunctionCall const& _funct } -void RenameSymbol::operator()(MessageID _id, Json::Value const& _args) +void RenameSymbol::operator()(MessageID _id, Json const& _args) { auto const&& [sourceUnitName, lineColumn] = extractSourceUnitNameAndLineColumn(_args); - std::string const newName = _args["newName"].asString(); - std::string const uri = _args["textDocument"]["uri"].asString(); + std::string const newName = _args["newName"].get(); + std::string const uri = _args["textDocument"]["uri"].get(); ASTNode const* sourceNode = m_server.astNodeAtSourceLocation(sourceUnitName, lineColumn); @@ -90,10 +90,10 @@ void RenameSymbol::operator()(MessageID _id, Json::Value const& _args) // Apply changes in reverse order (will iterate in reverse) sort(m_locations.begin(), m_locations.end()); - Json::Value reply = Json::objectValue; - reply["changes"] = Json::objectValue; + Json reply; + reply["changes"] = Json::object(); - Json::Value edits = Json::arrayValue; + Json edits = Json::array(); for (auto i = m_locations.rbegin(); i != m_locations.rend(); i++) { @@ -105,16 +105,16 @@ void RenameSymbol::operator()(MessageID _id, Json::Value const& _args) buffer.replace((size_t)i->start, (size_t)(i->end - i->start), newName); fileRepository().setSourceByUri(uri, std::move(buffer)); - Json::Value edit = Json::objectValue; + Json edit; edit["range"] = toRange(*i); edit["newText"] = newName; // Record changes for the client - edits.append(edit); + edits.emplace_back(edit); if (i + 1 == m_locations.rend() || (i + 1)->sourceName != i->sourceName) { reply["changes"][uri] = edits; - edits = Json::arrayValue; + edits = Json::array(); // Reset. } } diff --git a/libsolidity/lsp/RenameSymbol.h b/libsolidity/lsp/RenameSymbol.h index cafa8c067a25..c4a2ac98f359 100644 --- a/libsolidity/lsp/RenameSymbol.h +++ b/libsolidity/lsp/RenameSymbol.h @@ -27,7 +27,7 @@ class RenameSymbol: public HandlerBase public: explicit RenameSymbol(LanguageServer& _server): HandlerBase(_server) {} - void operator()(MessageID, Json::Value const&); + void operator()(MessageID, Json const&); protected: // Nested class because otherwise `RenameSymbol` couldn't be easily used // with LanguageServer::m_handlers as `ASTConstVisitor` deletes required diff --git a/libsolidity/lsp/SemanticTokensBuilder.cpp b/libsolidity/lsp/SemanticTokensBuilder.cpp index 2f44354184ef..be0796860cb9 100644 --- a/libsolidity/lsp/SemanticTokensBuilder.cpp +++ b/libsolidity/lsp/SemanticTokensBuilder.cpp @@ -70,7 +70,7 @@ SemanticTokenType semanticTokenTypeForExpression(frontend::Type const* _type) } // end namespace -Json::Value SemanticTokensBuilder::build(SourceUnit const& _sourceUnit, CharStream const& _charStream) +Json SemanticTokensBuilder::build(SourceUnit const& _sourceUnit, CharStream const& _charStream) { reset(&_charStream); _sourceUnit.accept(*this); @@ -79,7 +79,7 @@ Json::Value SemanticTokensBuilder::build(SourceUnit const& _sourceUnit, CharStre void SemanticTokensBuilder::reset(CharStream const* _charStream) { - m_encodedTokens = Json::arrayValue; + m_encodedTokens = Json::array(); m_charStream = _charStream; m_lastLine = 0; m_lastStartChar = 0; @@ -120,14 +120,14 @@ void SemanticTokensBuilder::encode( lspDebug(fmt::format("encode [{}:{}..{}] {}", line, startChar, length, static_cast(_tokenType))); - m_encodedTokens.append(line - m_lastLine); + m_encodedTokens.emplace_back(line - m_lastLine); if (line == m_lastLine) - m_encodedTokens.append(startChar - m_lastStartChar); + m_encodedTokens.emplace_back(startChar - m_lastStartChar); else - m_encodedTokens.append(startChar); - m_encodedTokens.append(length); - m_encodedTokens.append(static_cast(_tokenType)); - m_encodedTokens.append(static_cast(_modifiers)); + m_encodedTokens.emplace_back(startChar); + m_encodedTokens.emplace_back(length); + m_encodedTokens.emplace_back(static_cast(_tokenType)); + m_encodedTokens.emplace_back(static_cast(_modifiers)); m_lastLine = line; m_lastStartChar = startChar; diff --git a/libsolidity/lsp/SemanticTokensBuilder.h b/libsolidity/lsp/SemanticTokensBuilder.h index ca3c48d1c68d..3facb99e2bae 100644 --- a/libsolidity/lsp/SemanticTokensBuilder.h +++ b/libsolidity/lsp/SemanticTokensBuilder.h @@ -17,7 +17,7 @@ // SPDX-License-Identifier: GPL-3.0 #include #include -#include +#include #include @@ -87,7 +87,7 @@ constexpr SemanticTokenModifiers operator|(SemanticTokenModifiers a, SemanticTok class SemanticTokensBuilder: public frontend::ASTConstVisitor { public: - Json::Value build(frontend::SourceUnit const& _sourceUnit, langutil::CharStream const& _charStream); + Json build(frontend::SourceUnit const& _sourceUnit, langutil::CharStream const& _charStream); void reset(langutil::CharStream const* _charStream); void encode( @@ -114,7 +114,7 @@ class SemanticTokensBuilder: public frontend::ASTConstVisitor bool visit(frontend::VariableDeclaration const&) override; private: - Json::Value m_encodedTokens; + Json m_encodedTokens; langutil::CharStream const* m_charStream; int m_lastLine; int m_lastStartChar; diff --git a/libsolidity/lsp/Transport.cpp b/libsolidity/lsp/Transport.cpp index 7f8eb2283488..743ad6d66955 100644 --- a/libsolidity/lsp/Transport.cpp +++ b/libsolidity/lsp/Transport.cpp @@ -38,9 +38,10 @@ #endif using namespace solidity::lsp; +using namespace solidity; // {{{ Transport -std::optional Transport::receive() +std::optional Transport::receive() { auto const headers = parseHeaders(); if (!headers) @@ -57,10 +58,10 @@ std::optional Transport::receive() std::string const data = readBytes(stoul(headers->at("content-length"))); - Json::Value jsonMessage; + Json jsonMessage; std::string jsonParsingErrors; solidity::util::jsonParseStrict(data, jsonMessage, &jsonParsingErrors); - if (!jsonParsingErrors.empty() || !jsonMessage || !jsonMessage.isObject()) + if (!jsonParsingErrors.empty() || jsonMessage.empty() || !jsonMessage.is_object()) { error({}, ErrorCode::ParseError, "Could not parse RPC JSON payload. " + jsonParsingErrors); return std::nullopt; @@ -69,12 +70,12 @@ std::optional Transport::receive() return {std::move(jsonMessage)}; } -void Transport::trace(std::string _message, Json::Value _extra) +void Transport::trace(std::string _message, Json _extra) { if (m_logTrace != TraceValue::Off) { - Json::Value params; - if (_extra.isObject()) + Json params; + if (_extra.is_object()) params = std::move(_extra); params["message"] = std::move(_message); notify("$/logTrace", std::move(params)); @@ -103,34 +104,34 @@ std::optional> Transport::parseHeaders() return {std::move(headers)}; } -void Transport::notify(std::string _method, Json::Value _message) +void Transport::notify(std::string _method, Json _message) { - Json::Value json; + Json json; json["method"] = std::move(_method); json["params"] = std::move(_message); send(std::move(json)); } -void Transport::reply(MessageID _id, Json::Value _message) +void Transport::reply(MessageID _id, Json _message) { - Json::Value json; + Json json; json["result"] = std::move(_message); send(std::move(json), _id); } void Transport::error(MessageID _id, ErrorCode _code, std::string _message) { - Json::Value json; + Json json; json["error"]["code"] = static_cast(_code); json["error"]["message"] = std::move(_message); send(std::move(json), _id); } -void Transport::send(Json::Value _json, MessageID _id) +void Transport::send(Json _json, MessageID _id) { - solAssert(_json.isObject()); + solAssert(_json.is_object()); _json["jsonrpc"] = "2.0"; - if (_id != Json::nullValue) + if (_id != Json()) _json["id"] = _id; // Trailing CRLF only for easier readability. diff --git a/libsolidity/lsp/Transport.h b/libsolidity/lsp/Transport.h index e3b03bcc7f2f..e76cb5f7da5d 100644 --- a/libsolidity/lsp/Transport.h +++ b/libsolidity/lsp/Transport.h @@ -18,8 +18,7 @@ #pragma once #include - -#include +#include #include #include @@ -32,7 +31,7 @@ namespace solidity::lsp { -using MessageID = Json::Value; +using MessageID = Json; enum class TraceValue { @@ -98,14 +97,14 @@ class Transport public: virtual ~Transport() = default; - std::optional receive(); - void notify(std::string _method, Json::Value _params); - void reply(MessageID _id, Json::Value _result); + std::optional receive(); + void notify(std::string _method, Json _params); + void reply(MessageID _id, Json _result); void error(MessageID _id, ErrorCode _code, std::string _message); virtual bool closed() const noexcept = 0; - void trace(std::string _message, Json::Value _extra = Json::nullValue); + void trace(std::string _message, Json _extra = Json{}); TraceValue traceValue() const noexcept { return m_logTrace; } void setTrace(TraceValue _value) noexcept { m_logTrace = _value; } @@ -135,7 +134,7 @@ class Transport /// Sends an arbitrary raw message to the client. /// /// Used by the notify/reply/error function family. - virtual void send(Json::Value _message, MessageID _id = Json::nullValue); + virtual void send(Json _message, MessageID _id = Json{}); }; /** diff --git a/libsolidity/lsp/Utils.cpp b/libsolidity/lsp/Utils.cpp index 85e27a4fda5f..7667ce688ecd 100644 --- a/libsolidity/lsp/Utils.cpp +++ b/libsolidity/lsp/Utils.cpp @@ -31,26 +31,26 @@ namespace solidity::lsp using namespace frontend; using namespace langutil; -std::optional parseLineColumn(Json::Value const& _lineColumn) +std::optional parseLineColumn(Json const& _lineColumn) { - if (_lineColumn.isObject() && _lineColumn["line"].isInt() && _lineColumn["character"].isInt()) - return LineColumn{_lineColumn["line"].asInt(), _lineColumn["character"].asInt()}; + if (_lineColumn.is_object() && _lineColumn["line"].is_number_integer() && _lineColumn["character"].is_number_integer()) + return LineColumn{_lineColumn["line"].get(), _lineColumn["character"].get()}; else return std::nullopt; } -Json::Value toJson(LineColumn const& _pos) +Json toJson(LineColumn const& _pos) { - Json::Value json = Json::objectValue; + Json json; json["line"] = std::max(_pos.line, 0); json["character"] = std::max(_pos.column, 0); return json; } -Json::Value toJsonRange(LineColumn const& _start, LineColumn const& _end) +Json toJsonRange(LineColumn const& _start, LineColumn const& _end) { - Json::Value json; + Json json; json["start"] = toJson(_start); json["end"] = toJson(_end); return json; @@ -86,7 +86,7 @@ std::optional declarationLocation(Declaration const* _declaratio std::optional parsePosition( FileRepository const& _fileRepository, std::string const& _sourceUnitName, - Json::Value const& _position + Json const& _position ) { if (!_fileRepository.sourceUnits().count(_sourceUnitName)) @@ -101,9 +101,9 @@ std::optional parsePosition( return std::nullopt; } -std::optional parseRange(FileRepository const& _fileRepository, std::string const& _sourceUnitName, Json::Value const& _range) +std::optional parseRange(FileRepository const& _fileRepository, std::string const& _sourceUnitName, Json const& _range) { - if (!_range.isObject()) + if (!_range.is_object()) return std::nullopt; std::optional start = parsePosition(_fileRepository, _sourceUnitName, _range["start"]); std::optional end = parsePosition(_fileRepository, _sourceUnitName, _range["end"]); diff --git a/libsolidity/lsp/Utils.h b/libsolidity/lsp/Utils.h index c6d40213e6d3..318cdc87d6fc 100644 --- a/libsolidity/lsp/Utils.h +++ b/libsolidity/lsp/Utils.h @@ -44,16 +44,16 @@ namespace solidity::lsp class FileRepository; -std::optional parseLineColumn(Json::Value const& _lineColumn); -Json::Value toJson(langutil::LineColumn const& _pos); -Json::Value toJsonRange(langutil::LineColumn const& _start, langutil::LineColumn const& _end); +std::optional parseLineColumn(Json const& _lineColumn); +Json toJson(langutil::LineColumn const& _pos); +Json toJsonRange(langutil::LineColumn const& _start, langutil::LineColumn const& _end); /// @returns the source location given a source unit name and an LSP Range object, /// or nullopt on failure. std::optional parsePosition( FileRepository const& _fileRepository, std::string const& _sourceUnitName, - Json::Value const& _position + Json const& _position ); /// @returns the source location given a source unit name and an LSP Range object, @@ -61,7 +61,7 @@ std::optional parsePosition( std::optional parseRange( FileRepository const& _fileRepository, std::string const& _sourceUnitName, - Json::Value const& _range + Json const& _range ); /// Strips the file:// URI prefix off the given path, if present, diff --git a/libsolutil/CMakeLists.txt b/libsolutil/CMakeLists.txt index f97d61b671c1..0fdb23b0445f 100644 --- a/libsolutil/CMakeLists.txt +++ b/libsolutil/CMakeLists.txt @@ -43,7 +43,7 @@ set(sources ) add_library(solutil ${sources}) -target_link_libraries(solutil PUBLIC jsoncpp Boost::boost Boost::filesystem Boost::system range-v3 fmt::fmt-header-only) +target_link_libraries(solutil PUBLIC Boost::boost Boost::filesystem Boost::system range-v3 fmt::fmt-header-only nlohmann-json) target_include_directories(solutil PUBLIC "${PROJECT_SOURCE_DIR}") add_dependencies(solutil solidity_BuildInfo.h) diff --git a/libsolutil/Exceptions.h b/libsolutil/Exceptions.h index 9d73a0012eb4..7dd9b6769ad4 100644 --- a/libsolutil/Exceptions.h +++ b/libsolutil/Exceptions.h @@ -76,6 +76,7 @@ DEV_SIMPLE_EXCEPTION(FileNotFound); DEV_SIMPLE_EXCEPTION(NotAFile); DEV_SIMPLE_EXCEPTION(DataTooLong); DEV_SIMPLE_EXCEPTION(StringTooLong); +DEV_SIMPLE_EXCEPTION(InvalidType); // error information to be added to exceptions using errinfo_comment = boost::error_info; diff --git a/libsolutil/JSON.cpp b/libsolutil/JSON.cpp index 3a2570d47ec1..63746c86531a 100644 --- a/libsolutil/JSON.cpp +++ b/libsolutil/JSON.cpp @@ -22,19 +22,18 @@ #include -#include +#include -#include +#include +#include -#include #include -#include +#include -#ifdef STRICT_JSONCPP_VERSION_CHECK +#ifdef STRICT_NLOHMANN_JSON_VERSION_CHECK static_assert( - (JSONCPP_VERSION_MAJOR == 1) && (JSONCPP_VERSION_MINOR == 9) && (JSONCPP_VERSION_PATCH == 3), - "Unexpected jsoncpp version: " JSONCPP_VERSION_STRING ". Expecting 1.9.3." -); + (NLOHMANN_JSON_VERSION_MAJOR == 3) && (NLOHMANN_JSON_VERSION_MINOR == 11) && (NLOHMANN_JSON_VERSION_PATCH == 3), + "Unexpected nlohmann-json version. Expecting 3.11.3."); #endif namespace solidity::util @@ -43,116 +42,209 @@ namespace solidity::util namespace { -/// StreamWriterBuilder that can be constructed with specific settings -class StreamWriterBuilder: public Json::StreamWriterBuilder +/// Takes a JSON value (@ _json) and removes all its members with value 'null' recursively. +void removeNullMembersHelper(Json& _json) { -public: - explicit StreamWriterBuilder(std::map const& _settings) + if (_json.is_array()) { - for (auto const& iter: _settings) - this->settings_[iter.first] = iter.second; + for (auto& child: _json) + removeNullMembersHelper(child); } -}; - -/// CharReaderBuilder with strict-mode settings -class StrictModeCharReaderBuilder: public Json::CharReaderBuilder -{ -public: - StrictModeCharReaderBuilder() + else if (_json.is_object()) { - Json::CharReaderBuilder::strictMode(&this->settings_); + for (auto it = _json.begin(); it != _json.end();) + { + if (it->is_null()) + it = _json.erase(it); + else + { + removeNullMembersHelper(*it); + ++it; + } + } } -}; +} -/// Serialise the JSON object (@a _input) with specific builder (@a _builder) -/// \param _input JSON input string -/// \param _builder StreamWriterBuilder that is used to create new Json::StreamWriter -/// \return serialized json object -std::string print(Json::Value const& _input, Json::StreamWriterBuilder const& _builder) +std::string trimRightAllLines(std::string const& input) { - std::stringstream stream; - std::unique_ptr writer(_builder.newStreamWriter()); - writer->write(_input, &stream); - return stream.str(); + std::vector lines; + std::string output; + boost::split(lines, input, boost::is_any_of("\n")); + for (auto& line: lines) + { + boost::trim_right(line); + if (!line.empty()) + output += line + "\n"; + } + return boost::trim_right_copy(output); } -/// Parse a JSON string (@a _input) with specified builder (@ _builder) and writes resulting JSON object to (@a _json) -/// \param _builder CharReaderBuilder that is used to create new Json::CharReaders -/// \param _input JSON input string -/// \param _json [out] resulting JSON object -/// \param _errs [out] Formatted error messages -/// \return \c true if the document was successfully parsed, \c false if an error occurred. -bool parse(Json::CharReaderBuilder& _builder, std::string const& _input, Json::Value& _json, std::string* _errs) +std::string formatLikeJsoncpp(std::string const& _dumped, JsonFormat const& _format) { - std::unique_ptr reader(_builder.newCharReader()); - return reader->parse(_input.c_str(), _input.c_str() + _input.length(), &_json, _errs); + uint32_t indentLevel = 0; + std::stringstream reformatted; + bool inQuotes = false; + for (size_t i = 0; i < _dumped.size(); ++i) + { + char c = _dumped[i]; + bool emptyThing = false; + + if (c == '"' && (i == 0 || _dumped[i - 1] != '\\')) + inQuotes = !inQuotes; + + if (!inQuotes) + { + if (i < _dumped.size() - 1) + { + char nc = _dumped[i + 1]; + if ((c == '[' && nc == ']') || (c == '{' && nc == '}')) + emptyThing = true; + } + if (c == '[' || c == '{') + { + if (i > 0 && _dumped[i - 1] != '\n') + if (!emptyThing) + reformatted << '\n' << std::string(indentLevel * _format.indent, ' '); + indentLevel++; + } + else if (c == ']' || c == '}') + { + indentLevel--; + if (i + 1 < _dumped.size() && _dumped[i + 1] != '\n' + && (_dumped[i + 1] == ']' || _dumped[i + 1] == '}')) + reformatted << '\n' << std::string(indentLevel * _format.indent, ' '); + } + } + reformatted << c; + if (!emptyThing && !inQuotes && (c == '[' || c == '{') && indentLevel > 0 && i + 1 < _dumped.size() + && _dumped[i + 1] != '\n') + reformatted << '\n' << std::string(indentLevel * _format.indent, ' '); + } + return trimRightAllLines(reformatted.str()); } -/// Takes a JSON value (@ _json) and removes all its members with value 'null' recursively. -void removeNullMembersHelper(Json::Value& _json) +std::string escapeNewlinesAndTabsWithinStringLiterals(std::string const& _json) { - if (_json.type() == Json::ValueType::arrayValue) - for (auto& child: _json) - removeNullMembersHelper(child); - else if (_json.type() == Json::ValueType::objectValue) - for (auto const& key: _json.getMemberNames()) + std::stringstream fixed; + bool inQuotes = false; + for (size_t i = 0; i < _json.size(); ++i) + { + char c = _json[i]; + + // Originally we had just this here: + // if (c == '"' && (i == 0 || _json[i - 1] != '\\')) + // inQuotes = !inQuotes; + // However, this is not working if the escape character itself was escaped. e.g. "\n\r'\"\\". + + if (c == '"') + { + size_t backslashCount = 0; + size_t j = i; + while (j > 0 && _json[j - 1] == '\\') + { + backslashCount++; + j--; + } + if (backslashCount % 2 == 0) + { + inQuotes = !inQuotes; + fixed << c; + continue; + } + } + + if (inQuotes) { - Json::Value& value = _json[key]; - if (value.isNull()) - _json.removeMember(key); + if (c == '\n') + fixed << "\\n"; + else if (c == '\t') + fixed << "\\t"; else - removeNullMembersHelper(value); + fixed << c; } + else + fixed << c; + } + return fixed.str(); } } // end anonymous namespace -Json::Value removeNullMembers(Json::Value _json) +Json removeNullMembers(Json _json) { removeNullMembersHelper(_json); return _json; } -std::string jsonPrettyPrint(Json::Value const& _input) +std::string removeNlohmannInternalErrorIdentifier(std::string const& _input) { - return jsonPrint(_input, JsonFormat{ JsonFormat::Pretty }); -} + std::string result = _input; + std::size_t startPos = result.find('['); + std::size_t endPos = result.find(']', startPos); -std::string jsonCompactPrint(Json::Value const& _input) -{ - return jsonPrint(_input, JsonFormat{ JsonFormat::Compact }); + if (startPos != std::string::npos && endPos != std::string::npos) + result.erase(startPos, endPos - startPos + 1); + + return boost::trim_copy(result); } -std::string jsonPrint(Json::Value const& _input, JsonFormat const& _format) +std::string jsonPrettyPrint(Json const& _input) { return jsonPrint(_input, JsonFormat{JsonFormat::Pretty}); } + +std::string jsonCompactPrint(Json const& _input) { return jsonPrint(_input, JsonFormat{JsonFormat::Compact}); } + +std::string jsonPrint(Json const& _input, JsonFormat const& _format) { - std::map settings; - if (_format.format == JsonFormat::Pretty) - { - settings["indentation"] = std::string(_format.indent, ' '); - settings["enableYAMLCompatibility"] = true; - } - else - settings["indentation"] = ""; - StreamWriterBuilder writerBuilder(settings); - std::string result = print(_input, writerBuilder); + // NOTE: -1 here means no new lines (it is also the default setting) + std::string dumped = _input.dump( + /* indent */ (_format.format == JsonFormat::Pretty) ? static_cast(_format.indent) : -1, + /* indent_char */ ' ', + /* ensure_ascii */ true + ); + + // let's remove this once all test-cases having the correct output. if (_format.format == JsonFormat::Pretty) - boost::replace_all(result, " \n", "\n"); - return result; + dumped = formatLikeJsoncpp(dumped, _format); + + return dumped; } -bool jsonParseStrict(std::string const& _input, Json::Value& _json, std::string* _errs /* = nullptr */) +bool jsonParseStrict(std::string const& _input, Json& _json, std::string* _errs /* = nullptr */) { - static StrictModeCharReaderBuilder readerBuilder; - return parse(readerBuilder, _input, _json, _errs); + try + { + _json = Json::parse( + // TODO: remove this in the next breaking release? + escapeNewlinesAndTabsWithinStringLiterals(_input), + /* callback */ nullptr, + /* allow exceptions */ true, + /* ignore_comments */true + ); + _errs = {}; + return true; + } + catch (Json::parse_error const& e) + { + if (_errs) + { + std::stringstream escaped; + for (char c: removeNlohmannInternalErrorIdentifier(e.what())) + if (std::isprint(c)) + escaped << c; + else + escaped << "\\x" + toHex(static_cast(c)); + *_errs = escaped.str(); + } + return false; + } } -std::optional jsonValueByPath(Json::Value const& _node, std::string_view _jsonPath) +std::optional jsonValueByPath(Json const& _node, std::string_view _jsonPath) { - if (!_node.isObject() || _jsonPath.empty()) + if (!_node.is_object() || _jsonPath.empty()) return {}; std::string memberName = std::string(_jsonPath.substr(0, _jsonPath.find_first_of('.'))); - if (!_node.isMember(memberName)) + if (!_node.contains(memberName)) return {}; if (memberName == _jsonPath) diff --git a/libsolutil/JSON.h b/libsolutil/JSON.h index f368739e1a99..2cdac70c7857 100644 --- a/libsolutil/JSON.h +++ b/libsolutil/JSON.h @@ -23,17 +23,26 @@ #pragma once -#include +#include +#include #include #include #include +#include + +namespace solidity +{ + +using Json = nlohmann::json; + +} // namespace solidity namespace solidity::util { /// Removes members with null value recursively from (@a _json). -Json::Value removeNullMembers(Json::Value _json); +Json removeNullMembers(Json _json); /// JSON printing format. struct JsonFormat @@ -54,27 +63,29 @@ struct JsonFormat }; /// Serialise the JSON object (@a _input) with indentation -std::string jsonPrettyPrint(Json::Value const& _input); +std::string jsonPrettyPrint(Json const& _input); /// Serialise the JSON object (@a _input) without indentation -std::string jsonCompactPrint(Json::Value const& _input); +std::string jsonCompactPrint(Json const& _input); /// Serialise the JSON object (@a _input) using specified format (@a _format) -std::string jsonPrint(Json::Value const& _input, JsonFormat const& _format); +std::string jsonPrint(Json const& _input, JsonFormat const& _format); /// Parse a JSON string (@a _input) with enabled strict-mode and writes resulting JSON object to (@a _json) /// \param _input JSON input string /// \param _json [out] resulting JSON object /// \param _errs [out] Formatted error messages /// \return \c true if the document was successfully parsed, \c false if an error occurred. -bool jsonParseStrict(std::string const& _input, Json::Value& _json, std::string* _errs = nullptr); +bool jsonParseStrict(std::string const& _input, Json& _json, std::string* _errs = nullptr); /// Retrieves the value specified by @p _jsonPath by from a series of nested JSON dictionaries. /// @param _jsonPath A dot-separated series of dictionary keys. /// @param _node The node representing the start of the path. /// @returns The value of the last key on the path. @a nullptr if any node on the path descends /// into something that is not a dictionary or the key is not present. -std::optional jsonValueByPath(Json::Value const& _node, std::string_view _jsonPath); +std::optional jsonValueByPath(Json const& _node, std::string_view _jsonPath); + +std::string removeNlohmannInternalErrorIdentifier(std::string const& _input); namespace detail { @@ -82,60 +93,95 @@ namespace detail template struct helper; -template +template struct helper_impl { - static bool isOfType(Json::Value const& _input) + static bool isOfType(Json const& _input) { return (_input.*checkMember)(); } - static T get(Json::Value const& _input) + static T get(Json const& _input) { + assertThrow(isOfType(_input), InvalidType, ""); return (_input.*convertMember)(); } - static T getOrDefault(Json::Value const& _input, T _default = {}) + static T getOrDefault(Json const& _input, std::string const& _name, T _default = {}) { T result = _default; - if (isOfType(_input)) - result = (_input.*convertMember)(); + if (_input.contains(_name) && isOfType(_input[_name])) + result = (_input[_name].*convertMember)(); return result; } }; -template<> struct helper: helper_impl {}; -template<> struct helper: helper_impl {}; -template<> struct helper: helper_impl {}; -template<> struct helper: helper_impl {}; -template<> struct helper: helper_impl {}; -template<> struct helper: helper_impl {}; -template<> struct helper: helper_impl {}; +template +struct helper_impl_with_range_check +{ + static bool isOfType(Json const& _input) + { + if ( (_input.*checkMember)()) + { + T value = (_input.*convertMember)(); + return (value >= std::numeric_limits::min() && value <= std::numeric_limits::max()); + } + return false; + } + + static RT get(Json const& _input) + { + assertThrow(isOfType(_input), InvalidType, ""); + return static_cast((_input.*convertMember)()); + } + + static RT getOrDefault(Json const& _input, std::string const& _name, RT _default = {}) + { + RT value = _default; + if (_input.contains(_name) && isOfType(_input[_name])) + value = static_cast((_input[_name].*convertMember)()); + return value; + } +}; + +template<> struct helper: helper_impl> {}; +template<> struct helper: helper_impl> {}; +template<> struct helper: helper_impl> {}; +template<> struct helper: helper_impl> {}; +template<> struct helper: helper_impl> {}; + +template<> struct helper: helper_impl_with_range_check> {}; +template<> struct helper: helper_impl_with_range_check> {}; +template<> struct helper: helper_impl_with_range_check> {}; +template<> struct helper: helper_impl_with_range_check> {}; +template<> struct helper: helper_impl_with_range_check> {}; +template<> struct helper: helper_impl_with_range_check> {}; +template<> struct helper: helper_impl_with_range_check> {}; } // namespace detail template -bool isOfType(Json::Value const& _input) +bool isOfType(Json const& _input) { return detail::helper::isOfType(_input); } template -bool isOfTypeIfExists(Json::Value const& _input, std::string const& _name) +bool isOfTypeIfExists(Json const& _input, std::string const& _name) { - if (_input.isMember(_name)) + if (_input.contains(_name)) return isOfType(_input[_name]); return true; } template -T get(Json::Value const& _input) +T get(Json const& _input) { return detail::helper::get(_input); } template -T getOrDefault(Json::Value const& _input, T _default = {}) +T getOrDefault(Json const& _input, std::string const& _name, T _default = {}) { - return detail::helper::getOrDefault(_input, _default); + return detail::helper::getOrDefault(_input, _name, _default); } } // namespace solidity::util diff --git a/libyul/AsmJsonConverter.cpp b/libyul/AsmJsonConverter.cpp index bf2468b4e4bb..a89e4967aa4e 100644 --- a/libyul/AsmJsonConverter.cpp +++ b/libyul/AsmJsonConverter.cpp @@ -29,25 +29,25 @@ namespace solidity::yul { -Json::Value AsmJsonConverter::operator()(Block const& _node) const +Json AsmJsonConverter::operator()(Block const& _node) const { - Json::Value ret = createAstNode(originLocationOf(_node), nativeLocationOf(_node), "YulBlock"); + Json ret = createAstNode(originLocationOf(_node), nativeLocationOf(_node), "YulBlock"); ret["statements"] = vectorOfVariantsToJson(_node.statements); return ret; } -Json::Value AsmJsonConverter::operator()(TypedName const& _node) const +Json AsmJsonConverter::operator()(TypedName const& _node) const { yulAssert(!_node.name.empty(), "Invalid variable name."); - Json::Value ret = createAstNode(originLocationOf(_node), nativeLocationOf(_node), "YulTypedName"); + Json ret = createAstNode(originLocationOf(_node), nativeLocationOf(_node), "YulTypedName"); ret["name"] = _node.name.str(); ret["type"] = _node.type.str(); return ret; } -Json::Value AsmJsonConverter::operator()(Literal const& _node) const +Json AsmJsonConverter::operator()(Literal const& _node) const { - Json::Value ret = createAstNode(originLocationOf(_node), nativeLocationOf(_node), "YulLiteral"); + Json ret = createAstNode(originLocationOf(_node), nativeLocationOf(_node), "YulLiteral"); switch (_node.kind) { case LiteralKind::Number: @@ -71,94 +71,92 @@ Json::Value AsmJsonConverter::operator()(Literal const& _node) const return ret; } -Json::Value AsmJsonConverter::operator()(Identifier const& _node) const +Json AsmJsonConverter::operator()(Identifier const& _node) const { yulAssert(!_node.name.empty(), "Invalid identifier"); - Json::Value ret = createAstNode(originLocationOf(_node), nativeLocationOf(_node), "YulIdentifier"); + Json ret = createAstNode(originLocationOf(_node), nativeLocationOf(_node), "YulIdentifier"); ret["name"] = _node.name.str(); return ret; } -Json::Value AsmJsonConverter::operator()(Assignment const& _node) const +Json AsmJsonConverter::operator()(Assignment const& _node) const { yulAssert(_node.variableNames.size() >= 1, "Invalid assignment syntax"); - Json::Value ret = createAstNode(originLocationOf(_node), nativeLocationOf(_node), "YulAssignment"); + Json ret = createAstNode(originLocationOf(_node), nativeLocationOf(_node), "YulAssignment"); for (auto const& var: _node.variableNames) - ret["variableNames"].append((*this)(var)); - ret["value"] = _node.value ? std::visit(*this, *_node.value) : Json::nullValue; + ret["variableNames"].emplace_back((*this)(var)); + ret["value"] = _node.value ? std::visit(*this, *_node.value) : Json(); return ret; } -Json::Value AsmJsonConverter::operator()(FunctionCall const& _node) const +Json AsmJsonConverter::operator()(FunctionCall const& _node) const { - Json::Value ret = createAstNode(originLocationOf(_node), nativeLocationOf(_node), "YulFunctionCall"); + Json ret = createAstNode(originLocationOf(_node), nativeLocationOf(_node), "YulFunctionCall"); ret["functionName"] = (*this)(_node.functionName); ret["arguments"] = vectorOfVariantsToJson(_node.arguments); return ret; } -Json::Value AsmJsonConverter::operator()(ExpressionStatement const& _node) const +Json AsmJsonConverter::operator()(ExpressionStatement const& _node) const { - Json::Value ret = createAstNode(originLocationOf(_node), nativeLocationOf(_node), "YulExpressionStatement"); + Json ret = createAstNode(originLocationOf(_node), nativeLocationOf(_node), "YulExpressionStatement"); ret["expression"] = std::visit(*this, _node.expression); return ret; } -Json::Value AsmJsonConverter::operator()(VariableDeclaration const& _node) const +Json AsmJsonConverter::operator()(VariableDeclaration const& _node) const { - Json::Value ret = createAstNode(originLocationOf(_node), nativeLocationOf(_node), "YulVariableDeclaration"); + Json ret = createAstNode(originLocationOf(_node), nativeLocationOf(_node), "YulVariableDeclaration"); for (auto const& var: _node.variables) - ret["variables"].append((*this)(var)); - - ret["value"] = _node.value ? std::visit(*this, *_node.value) : Json::nullValue; - + ret["variables"].emplace_back((*this)(var)); + ret["value"] = _node.value ? std::visit(*this, *_node.value) : Json(); return ret; } -Json::Value AsmJsonConverter::operator()(FunctionDefinition const& _node) const +Json AsmJsonConverter::operator()(FunctionDefinition const& _node) const { yulAssert(!_node.name.empty(), "Invalid function name."); - Json::Value ret = createAstNode(originLocationOf(_node), nativeLocationOf(_node), "YulFunctionDefinition"); + Json ret = createAstNode(originLocationOf(_node), nativeLocationOf(_node), "YulFunctionDefinition"); ret["name"] = _node.name.str(); for (auto const& var: _node.parameters) - ret["parameters"].append((*this)(var)); + ret["parameters"].emplace_back((*this)(var)); for (auto const& var: _node.returnVariables) - ret["returnVariables"].append((*this)(var)); + ret["returnVariables"].emplace_back((*this)(var)); ret["body"] = (*this)(_node.body); return ret; } -Json::Value AsmJsonConverter::operator()(If const& _node) const +Json AsmJsonConverter::operator()(If const& _node) const { yulAssert(_node.condition, "Invalid if condition."); - Json::Value ret = createAstNode(originLocationOf(_node), nativeLocationOf(_node), "YulIf"); + Json ret = createAstNode(originLocationOf(_node), nativeLocationOf(_node), "YulIf"); ret["condition"] = std::visit(*this, *_node.condition); ret["body"] = (*this)(_node.body); return ret; } -Json::Value AsmJsonConverter::operator()(Switch const& _node) const +Json AsmJsonConverter::operator()(Switch const& _node) const { yulAssert(_node.expression, "Invalid expression pointer."); - Json::Value ret = createAstNode(originLocationOf(_node), nativeLocationOf(_node), "YulSwitch"); + Json ret = createAstNode(originLocationOf(_node), nativeLocationOf(_node), "YulSwitch"); ret["expression"] = std::visit(*this, *_node.expression); for (auto const& var: _node.cases) - ret["cases"].append((*this)(var)); + ret["cases"].emplace_back((*this)(var)); return ret; } -Json::Value AsmJsonConverter::operator()(Case const& _node) const +Json AsmJsonConverter::operator()(Case const& _node) const { - Json::Value ret = createAstNode(originLocationOf(_node), nativeLocationOf(_node), "YulCase"); + Json ret = createAstNode(originLocationOf(_node), nativeLocationOf(_node), "YulCase"); ret["value"] = _node.value ? (*this)(*_node.value) : "default"; ret["body"] = (*this)(_node.body); return ret; } -Json::Value AsmJsonConverter::operator()(ForLoop const& _node) const +Json AsmJsonConverter::operator()(ForLoop const& _node) const { yulAssert(_node.condition, "Invalid for loop condition."); - Json::Value ret = createAstNode(originLocationOf(_node), nativeLocationOf(_node), "YulForLoop"); + Json ret = createAstNode(originLocationOf(_node), nativeLocationOf(_node), "YulForLoop"); ret["pre"] = (*this)(_node.pre); ret["condition"] = std::visit(*this, *_node.condition); ret["post"] = (*this)(_node.post); @@ -166,24 +164,24 @@ Json::Value AsmJsonConverter::operator()(ForLoop const& _node) const return ret; } -Json::Value AsmJsonConverter::operator()(Break const& _node) const +Json AsmJsonConverter::operator()(Break const& _node) const { return createAstNode(originLocationOf(_node), nativeLocationOf(_node), "YulBreak"); } -Json::Value AsmJsonConverter::operator()(Continue const& _node) const +Json AsmJsonConverter::operator()(Continue const& _node) const { return createAstNode(originLocationOf(_node), nativeLocationOf(_node), "YulContinue"); } -Json::Value AsmJsonConverter::operator()(Leave const& _node) const +Json AsmJsonConverter::operator()(Leave const& _node) const { return createAstNode(originLocationOf(_node), nativeLocationOf(_node), "YulLeave"); } -Json::Value AsmJsonConverter::createAstNode(langutil::SourceLocation const& _originLocation, langutil::SourceLocation const& _nativeLocation, std::string _nodeType) const +Json AsmJsonConverter::createAstNode(langutil::SourceLocation const& _originLocation, langutil::SourceLocation const& _nativeLocation, std::string _nodeType) const { - Json::Value ret{Json::objectValue}; + Json ret; ret["nodeType"] = std::move(_nodeType); auto srcLocation = [&](int start, int end) -> std::string { @@ -196,11 +194,11 @@ Json::Value AsmJsonConverter::createAstNode(langutil::SourceLocation const& _ori } template -Json::Value AsmJsonConverter::vectorOfVariantsToJson(std::vector const& _vec) const +Json AsmJsonConverter::vectorOfVariantsToJson(std::vector const& _vec) const { - Json::Value ret{Json::arrayValue}; + Json ret = Json::array(); for (auto const& var: _vec) - ret.append(std::visit(*this, var)); + ret.emplace_back(std::visit(*this, var)); return ret; } diff --git a/libyul/AsmJsonConverter.h b/libyul/AsmJsonConverter.h index 236ecbba579c..9c4b5d5e8ebc 100644 --- a/libyul/AsmJsonConverter.h +++ b/libyul/AsmJsonConverter.h @@ -25,7 +25,7 @@ #include #include -#include +#include #include #include #include @@ -36,35 +36,35 @@ namespace solidity::yul /** * Converter of the yul AST into JSON format */ -class AsmJsonConverter: public boost::static_visitor +class AsmJsonConverter: public boost::static_visitor { public: /// Create a converter to JSON for any block of inline assembly /// @a _sourceIndex to be used to abbreviate source name in the source locations explicit AsmJsonConverter(std::optional _sourceIndex): m_sourceIndex(_sourceIndex) {} - Json::Value operator()(Block const& _node) const; - Json::Value operator()(TypedName const& _node) const; - Json::Value operator()(Literal const& _node) const; - Json::Value operator()(Identifier const& _node) const; - Json::Value operator()(Assignment const& _node) const; - Json::Value operator()(VariableDeclaration const& _node) const; - Json::Value operator()(FunctionDefinition const& _node) const; - Json::Value operator()(FunctionCall const& _node) const; - Json::Value operator()(If const& _node) const; - Json::Value operator()(Switch const& _node) const; - Json::Value operator()(Case const& _node) const; - Json::Value operator()(ForLoop const& _node) const; - Json::Value operator()(Break const& _node) const; - Json::Value operator()(Continue const& _node) const; - Json::Value operator()(Leave const& _node) const; - Json::Value operator()(ExpressionStatement const& _node) const; - Json::Value operator()(Label const& _node) const; + Json operator()(Block const& _node) const; + Json operator()(TypedName const& _node) const; + Json operator()(Literal const& _node) const; + Json operator()(Identifier const& _node) const; + Json operator()(Assignment const& _node) const; + Json operator()(VariableDeclaration const& _node) const; + Json operator()(FunctionDefinition const& _node) const; + Json operator()(FunctionCall const& _node) const; + Json operator()(If const& _node) const; + Json operator()(Switch const& _node) const; + Json operator()(Case const& _node) const; + Json operator()(ForLoop const& _node) const; + Json operator()(Break const& _node) const; + Json operator()(Continue const& _node) const; + Json operator()(Leave const& _node) const; + Json operator()(ExpressionStatement const& _node) const; + Json operator()(Label const& _node) const; private: - Json::Value createAstNode(langutil::SourceLocation const& _originLocation, langutil::SourceLocation const& _nativeLocation, std::string _nodeType) const; + Json createAstNode(langutil::SourceLocation const& _originLocation, langutil::SourceLocation const& _nativeLocation, std::string _nodeType) const; template - Json::Value vectorOfVariantsToJson(std::vector const& vec) const; + Json vectorOfVariantsToJson(std::vector const& vec) const; std::optional const m_sourceIndex; }; diff --git a/libyul/AsmJsonImporter.cpp b/libyul/AsmJsonImporter.cpp index 190dcda21d05..41e065853517 100644 --- a/libyul/AsmJsonImporter.cpp +++ b/libyul/AsmJsonImporter.cpp @@ -41,15 +41,15 @@ namespace solidity::yul using SourceLocation = langutil::SourceLocation; -SourceLocation const AsmJsonImporter::createSourceLocation(Json::Value const& _node) +SourceLocation const AsmJsonImporter::createSourceLocation(Json const& _node) { - yulAssert(member(_node, "src").isString(), "'src' must be a string"); + yulAssert(member(_node, "src").is_string(), "'src' must be a string"); - return solidity::langutil::parseSourceLocation(_node["src"].asString(), m_sourceNames); + return solidity::langutil::parseSourceLocation(_node["src"].get(), m_sourceNames); } template -T AsmJsonImporter::createAsmNode(Json::Value const& _node) +T AsmJsonImporter::createAsmNode(Json const& _node) { T r; SourceLocation nativeLocation = createSourceLocation(_node); @@ -61,26 +61,26 @@ T AsmJsonImporter::createAsmNode(Json::Value const& _node) return r; } -Json::Value AsmJsonImporter::member(Json::Value const& _node, std::string const& _name) +Json AsmJsonImporter::member(Json const& _node, std::string const& _name) { - if (!_node.isMember(_name)) - return Json::nullValue; + if (!_node.contains(_name)) + return Json(); return _node[_name]; } -TypedName AsmJsonImporter::createTypedName(Json::Value const& _node) +TypedName AsmJsonImporter::createTypedName(Json const& _node) { auto typedName = createAsmNode(_node); - typedName.type = YulString{member(_node, "type").asString()}; - typedName.name = YulString{member(_node, "name").asString()}; + typedName.type = YulString{member(_node, "type").get()}; + typedName.name = YulString{member(_node, "name").get()}; return typedName; } -Statement AsmJsonImporter::createStatement(Json::Value const& _node) +Statement AsmJsonImporter::createStatement(Json const& _node) { - Json::Value jsonNodeType = member(_node, "nodeType"); - yulAssert(jsonNodeType.isString(), "Expected \"nodeType\" to be of type string!"); - std::string nodeType = jsonNodeType.asString(); + Json jsonNodeType = member(_node, "nodeType"); + yulAssert(jsonNodeType.is_string(), "Expected \"nodeType\" to be of type string!"); + std::string nodeType = jsonNodeType.get(); yulAssert(nodeType.substr(0, 3) == "Yul", "Invalid nodeType prefix"); nodeType = nodeType.substr(3); @@ -114,11 +114,11 @@ Statement AsmJsonImporter::createStatement(Json::Value const& _node) util::unreachable(); } -Expression AsmJsonImporter::createExpression(Json::Value const& _node) +Expression AsmJsonImporter::createExpression(Json const& _node) { - Json::Value jsonNodeType = member(_node, "nodeType"); - yulAssert(jsonNodeType.isString(), "Expected \"nodeType\" to be of type string!"); - std::string nodeType = jsonNodeType.asString(); + Json jsonNodeType = member(_node, "nodeType"); + yulAssert(jsonNodeType.is_string(), "Expected \"nodeType\" to be of type string!"); + std::string nodeType = jsonNodeType.get(); yulAssert(nodeType.substr(0, 3) == "Yul", "Invalid nodeType prefix"); nodeType = nodeType.substr(3); @@ -136,7 +136,7 @@ Expression AsmJsonImporter::createExpression(Json::Value const& _node) util::unreachable(); } -std::vector AsmJsonImporter::createExpressionVector(Json::Value const& _array) +std::vector AsmJsonImporter::createExpressionVector(Json const& _array) { std::vector ret; for (auto& var: _array) @@ -144,7 +144,7 @@ std::vector AsmJsonImporter::createExpressionVector(Json::Value cons return ret; } -std::vector AsmJsonImporter::createStatementVector(Json::Value const& _array) +std::vector AsmJsonImporter::createStatementVector(Json const& _array) { std::vector ret; for (auto& var: _array) @@ -152,25 +152,25 @@ std::vector AsmJsonImporter::createStatementVector(Json::Value const& return ret; } -Block AsmJsonImporter::createBlock(Json::Value const& _node) +Block AsmJsonImporter::createBlock(Json const& _node) { auto block = createAsmNode(_node); block.statements = createStatementVector(_node["statements"]); return block; } -Literal AsmJsonImporter::createLiteral(Json::Value const& _node) +Literal AsmJsonImporter::createLiteral(Json const& _node) { auto lit = createAsmNode(_node); - std::string kind = member(_node, "kind").asString(); + std::string kind = member(_node, "kind").get(); - solAssert(member(_node, "hexValue").isString() || member(_node, "value").isString(), ""); - if (_node.isMember("hexValue")) - lit.value = YulString{util::asString(util::fromHex(member(_node, "hexValue").asString()))}; + solAssert(member(_node, "hexValue").is_string() || member(_node, "value").is_string(), ""); + if (_node.contains("hexValue")) + lit.value = YulString{util::asString(util::fromHex(member(_node, "hexValue").get()))}; else - lit.value = YulString{member(_node, "value").asString()}; + lit.value = YulString{member(_node, "value").get()}; - lit.type= YulString{member(_node, "type").asString()}; + lit.type= YulString{member(_node, "type").get()}; if (kind == "number") { @@ -207,23 +207,23 @@ Literal AsmJsonImporter::createLiteral(Json::Value const& _node) return lit; } -Leave AsmJsonImporter::createLeave(Json::Value const& _node) +Leave AsmJsonImporter::createLeave(Json const& _node) { return createAsmNode(_node); } -Identifier AsmJsonImporter::createIdentifier(Json::Value const& _node) +Identifier AsmJsonImporter::createIdentifier(Json const& _node) { auto identifier = createAsmNode(_node); - identifier.name = YulString(member(_node, "name").asString()); + identifier.name = YulString(member(_node, "name").get()); return identifier; } -Assignment AsmJsonImporter::createAssignment(Json::Value const& _node) +Assignment AsmJsonImporter::createAssignment(Json const& _node) { auto assignment = createAsmNode(_node); - if (_node.isMember("variableNames")) + if (_node.contains("variableNames")) for (auto const& var: member(_node, "variableNames")) assignment.variableNames.emplace_back(createIdentifier(var)); @@ -231,7 +231,7 @@ Assignment AsmJsonImporter::createAssignment(Json::Value const& _node) return assignment; } -FunctionCall AsmJsonImporter::createFunctionCall(Json::Value const& _node) +FunctionCall AsmJsonImporter::createFunctionCall(Json const& _node) { auto functionCall = createAsmNode(_node); @@ -243,35 +243,35 @@ FunctionCall AsmJsonImporter::createFunctionCall(Json::Value const& _node) return functionCall; } -ExpressionStatement AsmJsonImporter::createExpressionStatement(Json::Value const& _node) +ExpressionStatement AsmJsonImporter::createExpressionStatement(Json const& _node) { auto statement = createAsmNode(_node); statement.expression = createExpression(member(_node, "expression")); return statement; } -VariableDeclaration AsmJsonImporter::createVariableDeclaration(Json::Value const& _node) +VariableDeclaration AsmJsonImporter::createVariableDeclaration(Json const& _node) { auto varDec = createAsmNode(_node); for (auto const& var: member(_node, "variables")) varDec.variables.emplace_back(createTypedName(var)); - if (_node.isMember("value")) + if (_node.contains("value")) varDec.value = std::make_unique(createExpression(member(_node, "value"))); return varDec; } -FunctionDefinition AsmJsonImporter::createFunctionDefinition(Json::Value const& _node) +FunctionDefinition AsmJsonImporter::createFunctionDefinition(Json const& _node) { auto funcDef = createAsmNode(_node); - funcDef.name = YulString{member(_node, "name").asString()}; + funcDef.name = YulString{member(_node, "name").get()}; - if (_node.isMember("parameters")) + if (_node.contains("parameters")) for (auto const& var: member(_node, "parameters")) funcDef.parameters.emplace_back(createTypedName(var)); - if (_node.isMember("returnVariables")) + if (_node.contains("returnVariables")) for (auto const& var: member(_node, "returnVariables")) funcDef.returnVariables.emplace_back(createTypedName(var)); @@ -279,7 +279,7 @@ FunctionDefinition AsmJsonImporter::createFunctionDefinition(Json::Value const& return funcDef; } -If AsmJsonImporter::createIf(Json::Value const& _node) +If AsmJsonImporter::createIf(Json const& _node) { auto ifStatement = createAsmNode(_node); ifStatement.condition = std::make_unique(createExpression(member(_node, "condition"))); @@ -287,19 +287,19 @@ If AsmJsonImporter::createIf(Json::Value const& _node) return ifStatement; } -Case AsmJsonImporter::createCase(Json::Value const& _node) +Case AsmJsonImporter::createCase(Json const& _node) { auto caseStatement = createAsmNode(_node); auto const& value = member(_node, "value"); - if (value.isString()) - yulAssert(value.asString() == "default", "Expected default case"); + if (value.is_string()) + yulAssert(value.get() == "default", "Expected default case"); else caseStatement.value = std::make_unique(createLiteral(value)); caseStatement.body = createBlock(member(_node, "body")); return caseStatement; } -Switch AsmJsonImporter::createSwitch(Json::Value const& _node) +Switch AsmJsonImporter::createSwitch(Json const& _node) { auto switchStatement = createAsmNode(_node); switchStatement.expression = std::make_unique(createExpression(member(_node, "expression"))); @@ -308,7 +308,7 @@ Switch AsmJsonImporter::createSwitch(Json::Value const& _node) return switchStatement; } -ForLoop AsmJsonImporter::createForLoop(Json::Value const& _node) +ForLoop AsmJsonImporter::createForLoop(Json const& _node) { auto forLoop = createAsmNode(_node); forLoop.pre = createBlock(member(_node, "pre")); @@ -318,12 +318,12 @@ ForLoop AsmJsonImporter::createForLoop(Json::Value const& _node) return forLoop; } -Break AsmJsonImporter::createBreak(Json::Value const& _node) +Break AsmJsonImporter::createBreak(Json const& _node) { return createAsmNode(_node); } -Continue AsmJsonImporter::createContinue(Json::Value const& _node) +Continue AsmJsonImporter::createContinue(Json const& _node) { return createAsmNode(_node); } diff --git a/libyul/AsmJsonImporter.h b/libyul/AsmJsonImporter.h index 506352fa4811..87933761a654 100644 --- a/libyul/AsmJsonImporter.h +++ b/libyul/AsmJsonImporter.h @@ -23,7 +23,7 @@ #pragma once -#include +#include #include #include @@ -41,36 +41,36 @@ class AsmJsonImporter explicit AsmJsonImporter(std::vector> const& _sourceNames): m_sourceNames(_sourceNames) {} - yul::Block createBlock(Json::Value const& _node); + yul::Block createBlock(Json const& _node); private: - langutil::SourceLocation const createSourceLocation(Json::Value const& _node); + langutil::SourceLocation const createSourceLocation(Json const& _node); template - T createAsmNode(Json::Value const& _node); + T createAsmNode(Json const& _node); /// helper function to access member functions of the JSON /// and throw an error if it does not exist - Json::Value member(Json::Value const& _node, std::string const& _name); + Json member(Json const& _node, std::string const& _name); - yul::Statement createStatement(Json::Value const& _node); - yul::Expression createExpression(Json::Value const& _node); - std::vector createStatementVector(Json::Value const& _array); - std::vector createExpressionVector(Json::Value const& _array); + yul::Statement createStatement(Json const& _node); + yul::Expression createExpression(Json const& _node); + std::vector createStatementVector(Json const& _array); + std::vector createExpressionVector(Json const& _array); - yul::TypedName createTypedName(Json::Value const& _node); - yul::Literal createLiteral(Json::Value const& _node); - yul::Leave createLeave(Json::Value const& _node); - yul::Identifier createIdentifier(Json::Value const& _node); - yul::Assignment createAssignment(Json::Value const& _node); - yul::FunctionCall createFunctionCall(Json::Value const& _node); - yul::ExpressionStatement createExpressionStatement(Json::Value const& _node); - yul::VariableDeclaration createVariableDeclaration(Json::Value const& _node); - yul::FunctionDefinition createFunctionDefinition(Json::Value const& _node); - yul::If createIf(Json::Value const& _node); - yul::Case createCase(Json::Value const& _node); - yul::Switch createSwitch(Json::Value const& _node); - yul::ForLoop createForLoop(Json::Value const& _node); - yul::Break createBreak(Json::Value const& _node); - yul::Continue createContinue(Json::Value const& _node); + yul::TypedName createTypedName(Json const& _node); + yul::Literal createLiteral(Json const& _node); + yul::Leave createLeave(Json const& _node); + yul::Identifier createIdentifier(Json const& _node); + yul::Assignment createAssignment(Json const& _node); + yul::FunctionCall createFunctionCall(Json const& _node); + yul::ExpressionStatement createExpressionStatement(Json const& _node); + yul::VariableDeclaration createVariableDeclaration(Json const& _node); + yul::FunctionDefinition createFunctionDefinition(Json const& _node); + yul::If createIf(Json const& _node); + yul::Case createCase(Json const& _node); + yul::Switch createSwitch(Json const& _node); + yul::ForLoop createForLoop(Json const& _node); + yul::Break createBreak(Json const& _node); + yul::Continue createContinue(Json const& _node); std::vector> const& m_sourceNames; }; diff --git a/libyul/Object.cpp b/libyul/Object.cpp index 0d3d66c8e5f2..260cb733011f 100644 --- a/libyul/Object.cpp +++ b/libyul/Object.cpp @@ -75,27 +75,27 @@ std::string Object::toString( return useSrcComment + "object \"" + name.str() + "\" {\n" + indent(inner) + "\n}"; } -Json::Value Data::toJson() const +Json Data::toJson() const { - Json::Value ret{Json::objectValue}; + Json ret; ret["nodeType"] = "YulData"; ret["value"] = util::toHex(data); return ret; } -Json::Value Object::toJson() const +Json Object::toJson() const { yulAssert(code, "No code"); - Json::Value codeJson{Json::objectValue}; + Json codeJson; codeJson["nodeType"] = "YulCode"; codeJson["block"] = AsmJsonConverter(0 /* sourceIndex */)(*code); - Json::Value subObjectsJson{Json::arrayValue}; + Json subObjectsJson = Json::array(); for (std::shared_ptr const& subObject: subObjects) - subObjectsJson.append(subObject->toJson()); + subObjectsJson.emplace_back(subObject->toJson()); - Json::Value ret{Json::objectValue}; + Json ret; ret["nodeType"] = "YulObject"; ret["name"] = name.str(); ret["code"] = codeJson; diff --git a/libyul/Object.h b/libyul/Object.h index 5f88d3bc7ff6..54a8080d08c0 100644 --- a/libyul/Object.h +++ b/libyul/Object.h @@ -28,11 +28,11 @@ #include #include +#include #include #include #include -#include namespace solidity::yul { @@ -58,7 +58,7 @@ struct ObjectNode langutil::DebugInfoSelection const& _debugInfoSelection, langutil::CharStreamProvider const* _soliditySourceProvider ) const = 0; - virtual Json::Value toJson() const = 0; + virtual Json toJson() const = 0; }; /** @@ -75,7 +75,7 @@ struct Data: public ObjectNode langutil::DebugInfoSelection const& _debugInfoSelection, langutil::CharStreamProvider const* _soliditySourceProvider ) const override; - Json::Value toJson() const override; + Json toJson() const override; }; @@ -98,7 +98,7 @@ struct Object: public ObjectNode langutil::CharStreamProvider const* _soliditySourceProvider = nullptr ) const; /// @returns a compact JSON representation of the AST. - Json::Value toJson() const; + Json toJson() const; /// @returns the set of names of data objects accessible from within the code of /// this object, including the name of object itself /// Handles all names containing dots as reserved identifiers, not accessible as data. diff --git a/libyul/YulStack.cpp b/libyul/YulStack.cpp index 6c89cadbdfd9..a4341cba308c 100644 --- a/libyul/YulStack.cpp +++ b/libyul/YulStack.cpp @@ -312,7 +312,7 @@ std::string YulStack::print( return m_parserResult->toString(&languageToDialect(m_language, m_evmVersion), m_debugInfoSelection, _soliditySourceProvider) + "\n"; } -Json::Value YulStack::astJson() const +Json YulStack::astJson() const { yulAssert(m_parserResult, ""); yulAssert(m_parserResult->code, ""); diff --git a/libyul/YulStack.h b/libyul/YulStack.h index 700fd2b3baa3..27f530b44c4a 100644 --- a/libyul/YulStack.h +++ b/libyul/YulStack.h @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -33,8 +34,6 @@ #include -#include - #include #include @@ -132,7 +131,7 @@ class YulStack: public langutil::CharStreamProvider std::string print( langutil::CharStreamProvider const* _soliditySourceProvider = nullptr ) const; - Json::Value astJson() const; + Json astJson() const; /// Return the parsed and analyzed object. std::shared_ptr parserResult() const; diff --git a/libyul/backends/evm/StackLayoutGenerator.cpp b/libyul/backends/evm/StackLayoutGenerator.cpp index 51db3a14d5b3..954c9f2af7af 100644 --- a/libyul/backends/evm/StackLayoutGenerator.cpp +++ b/libyul/backends/evm/StackLayoutGenerator.cpp @@ -771,7 +771,7 @@ void StackLayoutGenerator::fillInJunk(CFG::BasicBlock const& _block, CFG::Functi yulAssert(util::contains(m_currentFunctionInfo->returnVariables, std::get(_slot))); // Strictly speaking the cost of the PUSH0 depends on the targeted EVM version, but the difference // will not matter here. - opGas += evmasm::GasMeter::runGas(evmasm::pushInstruction(0), langutil::EVMVersion());; + opGas += evmasm::GasMeter::runGas(evmasm::pushInstruction(0), langutil::EVMVersion()); } } }; diff --git a/solc/CommandLineInterface.cpp b/solc/CommandLineInterface.cpp index 4c08efb51a00..514f84c209df 100644 --- a/solc/CommandLineInterface.cpp +++ b/solc/CommandLineInterface.cpp @@ -353,23 +353,23 @@ void CommandLineInterface::handleSignatureHashes(std::string const& _contract) if (!m_options.compiler.outputs.signatureHashes) return; - Json::Value interfaceSymbols = m_compiler->interfaceSymbols(_contract); + Json interfaceSymbols = m_compiler->interfaceSymbols(_contract); std::string out = "Function signatures:\n"; - for (auto const& name: interfaceSymbols["methods"].getMemberNames()) - out += interfaceSymbols["methods"][name].asString() + ": " + name + "\n"; + for (auto const& [name, value]: interfaceSymbols["methods"].items()) + out += value.get() + ": " + name + "\n"; - if (interfaceSymbols.isMember("errors")) + if (interfaceSymbols.contains("errors")) { out += "\nError signatures:\n"; - for (auto const& name: interfaceSymbols["errors"].getMemberNames()) - out += interfaceSymbols["errors"][name].asString() + ": " + name + "\n"; + for (auto const& [name, value]: interfaceSymbols["errors"].items()) + out += value.get() + ": " + name + "\n"; } - if (interfaceSymbols.isMember("events")) + if (interfaceSymbols.contains("events")) { out += "\nEvent signatures:\n"; - for (auto const& name: interfaceSymbols["events"].getMemberNames()) - out += interfaceSymbols["events"][name].asString() + ": " + name + "\n"; + for (auto const& [name, value]: interfaceSymbols["events"].items()) + out += value.get() + ": " + name + "\n"; } if (!m_options.output.dir.empty()) @@ -467,40 +467,40 @@ void CommandLineInterface::handleGasEstimation(std::string const& _contract) { solAssert(CompilerInputModes.count(m_options.input.mode) == 1); - Json::Value estimates = m_compiler->gasEstimates(_contract); + Json estimates = m_compiler->gasEstimates(_contract); sout() << "Gas estimation:" << std::endl; - if (estimates["creation"].isObject()) + if (estimates["creation"].is_object()) { - Json::Value creation = estimates["creation"]; + Json creation = estimates["creation"]; sout() << "construction:" << std::endl; - sout() << " " << creation["executionCost"].asString(); - sout() << " + " << creation["codeDepositCost"].asString(); - sout() << " = " << creation["totalCost"].asString() << std::endl; + sout() << " " << creation["executionCost"].get(); + sout() << " + " << creation["codeDepositCost"].get(); + sout() << " = " << creation["totalCost"].get() << std::endl; } - if (estimates["external"].isObject()) + if (estimates["external"].is_object()) { - Json::Value externalFunctions = estimates["external"]; + Json externalFunctions = estimates["external"]; sout() << "external:" << std::endl; - for (auto const& name: externalFunctions.getMemberNames()) + for (auto const& [name, value]: externalFunctions.items()) { if (name.empty()) sout() << " fallback:\t"; else sout() << " " << name << ":\t"; - sout() << externalFunctions[name].asString() << std::endl; + sout() << value.get() << std::endl; } } - if (estimates["internal"].isObject()) + if (estimates["internal"].is_object()) { - Json::Value internalFunctions = estimates["internal"]; + Json internalFunctions = estimates["internal"]; sout() << "internal:" << std::endl; - for (auto const& name: internalFunctions.getMemberNames()) + for (auto const& [name, value]: internalFunctions.items()) { sout() << " " << name << ":\t"; - sout() << internalFunctions[name].asString() << std::endl; + sout() << value.get() << std::endl; } } } @@ -613,27 +613,27 @@ void CommandLineInterface::readInputFiles() solThrow(CommandLineValidationError, "All specified input files either do not exist or are not regular files."); } -std::map CommandLineInterface::parseAstFromInput() +std::map CommandLineInterface::parseAstFromInput() { solAssert(m_options.input.mode == InputMode::CompilerWithASTImport); - std::map sourceJsons; + std::map sourceJsons; std::map tmpSources; for (SourceCode const& sourceCode: m_fileReader.sourceUnits() | ranges::views::values) { - Json::Value ast; + Json ast; astAssert(jsonParseStrict(sourceCode, ast), "Input file could not be parsed to JSON"); - astAssert(ast.isMember("sources"), "Invalid Format for import-JSON: Must have 'sources'-object"); + astAssert(ast.contains("sources"), "Invalid Format for import-JSON: Must have 'sources'-object"); - for (auto& src: ast["sources"].getMemberNames()) + for (auto const& [src, value]: ast["sources"].items()) { - std::string astKey = ast["sources"][src].isMember("ast") ? "ast" : "AST"; + std::string astKey = value.contains("ast") ? "ast" : "AST"; - astAssert(ast["sources"][src].isMember(astKey), "astkey is not member"); - astAssert(ast["sources"][src][astKey]["nodeType"].asString() == "SourceUnit", "Top-level node should be a 'SourceUnit'"); + astAssert(ast["sources"][src].contains(astKey), "astkey is not member"); + astAssert(ast["sources"][src][astKey]["nodeType"].get() == "SourceUnit", "Top-level node should be a 'SourceUnit'"); astAssert(sourceJsons.count(src) == 0, "All sources must have unique names"); - sourceJsons.emplace(src, std::move(ast["sources"][src][astKey])); + sourceJsons.emplace(src, std::move(value[astKey])); tmpSources[src] = util::jsonCompactPrint(ast); } } @@ -942,16 +942,16 @@ void CommandLineInterface::handleCombinedJSON() if (!m_options.compiler.combinedJsonRequests.has_value()) return; - Json::Value output(Json::objectValue); + Json output; output[g_strVersion] = frontend::VersionString; std::vector contracts = m_assemblyStack->contractNames(); if (!contracts.empty()) - output[g_strContracts] = Json::Value(Json::objectValue); + output[g_strContracts] = Json::object(); for (std::string const& contractName: contracts) { - Json::Value& contractData = output[g_strContracts][contractName] = Json::objectValue; + Json& contractData = output[g_strContracts][contractName] = Json::object(); // NOTE: The state checks here are more strict that in Standard JSON. There we allow // requesting certain outputs even if compilation fails as long as analysis went ok. @@ -1013,19 +1013,19 @@ void CommandLineInterface::handleCombinedJSON() if (needsSourceList) { // Indices into this array are used to abbreviate source names in source locations. - output[g_strSourceList] = Json::Value(Json::arrayValue); + output[g_strSourceList] = Json::array(); for (auto const& source: m_assemblyStack->sourceNames()) - output[g_strSourceList].append(source); + output[g_strSourceList].emplace_back(source); } if (m_options.compiler.combinedJsonRequests->ast) { solAssert(m_compiler); - output[g_strSources] = Json::Value(Json::objectValue); + output[g_strSources] = Json::object(); for (auto const& sourceCode: m_fileReader.sourceUnits()) { - output[g_strSources][sourceCode.first] = Json::Value(Json::objectValue); + output[g_strSources][sourceCode.first] = Json::object(); output[g_strSources][sourceCode.first]["AST"] = ASTJsonExporter( m_compiler->state(), m_compiler->sourceIndices() diff --git a/solc/CommandLineInterface.h b/solc/CommandLineInterface.h index 1fb4ac00bcb1..bcebcbcfd3be 100644 --- a/solc/CommandLineInterface.h +++ b/solc/CommandLineInterface.h @@ -120,7 +120,7 @@ class CommandLineInterface /// such that they can be imported into the compiler (importASTs()) /// (produced by --combined-json ast /// or standard-json output - std::map parseAstFromInput(); + std::map parseAstFromInput(); /// Create a file in the given directory /// @arg _fileName the name of the file diff --git a/test/Metadata.cpp b/test/Metadata.cpp index 2fea65c65be0..cdfcdfb19c48 100644 --- a/test/Metadata.cpp +++ b/test/Metadata.cpp @@ -172,33 +172,33 @@ std::optional> parseCBORMetadata(bytes const& bool isValidMetadata(std::string const& _serialisedMetadata) { - Json::Value metadata; + Json metadata; if (!util::jsonParseStrict(_serialisedMetadata, metadata)) return false; return isValidMetadata(metadata); } -bool isValidMetadata(Json::Value const& _metadata) +bool isValidMetadata(Json const& _metadata) { if ( - !_metadata.isObject() || - !_metadata.isMember("version") || - !_metadata.isMember("language") || - !_metadata.isMember("compiler") || - !_metadata.isMember("settings") || - !_metadata.isMember("sources") || - !_metadata.isMember("output") || - !_metadata["settings"].isMember("evmVersion") || - !_metadata["settings"].isMember("metadata") || - !_metadata["settings"]["metadata"].isMember("bytecodeHash") + !_metadata.is_object() || + !_metadata.contains("version") || + !_metadata.contains("language") || + !_metadata.contains("compiler") || + !_metadata.contains("settings") || + !_metadata.contains("sources") || + !_metadata.contains("output") || + !_metadata["settings"].contains("evmVersion") || + !_metadata["settings"].contains("metadata") || + !_metadata["settings"]["metadata"].contains("bytecodeHash") ) return false; - if (!_metadata["version"].isNumeric() || _metadata["version"] != 1) + if (!_metadata["version"].is_number() || _metadata["version"] != 1) return false; - if (!_metadata["language"].isString() || _metadata["language"].asString() != "Solidity") + if (!_metadata["language"].is_string() || _metadata["language"].get() != "Solidity") return false; /// @TODO add more strict checks diff --git a/test/Metadata.h b/test/Metadata.h index 86b43e245f18..f3dae0cbdea0 100644 --- a/test/Metadata.h +++ b/test/Metadata.h @@ -53,6 +53,6 @@ std::optional> parseCBORMetadata(bytes const& bool isValidMetadata(std::string const& _serialisedMetadata); /// Expects a deserialised metadata JSON and returns true if the content is valid metadata. -bool isValidMetadata(Json::Value const& _metadata); +bool isValidMetadata(Json const& _metadata); } // end namespaces diff --git a/test/cmdlineTests/standard_import_with_comments/input.json b/test/cmdlineTests/standard_import_with_comments/input.json new file mode 100644 index 000000000000..4ed88177cf1f --- /dev/null +++ b/test/cmdlineTests/standard_import_with_comments/input.json @@ -0,0 +1,95 @@ +{ + "language": "SolidityAST", + "sources": { // this is a comment + "A": { + "ast": { + "absolutePath": "A", + "exportedSymbols": { + "C": [ + 6 /* and this another comment */ + ] + }, + "id": 7, + "license": "GPL-3.0", + "nodeType": "SourceUnit", + "nodes": /* and this is a comment too */[ + // this is a comment + { + /*this is a comment*/"id"/* and this is another comment too*/: 1, + "literals": [ + "solidity", + ">=", + "0.0" + ], + "nodeType": "PragmaDirective", + "src": "36:22:0" + }, + { + "abstract": false, + "baseContracts": [], + "canonicalName": "C", + "contractDependencies": [], + "contractKind": "contract", + "fullyImplemented": true, + "id": 6, + "linearizedBaseContracts": [ + 6 + ], + "name": "C", + "nameLocation": "68:1:0", + "nodeType": "ContractDefinition", + "nodes": [ + { + "body": { + "id": 4, + "nodeType": "Block", + "src": "97:2:0", + "statements": [] + }, + "functionSelector": "26121ff0", + "id": 5, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "f", + "nameLocation": "81:1:0", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 2, + "nodeType": "ParameterList", + "parameters": [], + "src": "82:2:0" + }, + "returnParameters": { + "id": 3, + "nodeType": "ParameterList", + "parameters": [], + "src": "97:0:0" + }, + "scope": 6, + "src": "72:27:0", + "stateMutability": "pure", + "virtual": false, + "visibility": "public" + } + ], + "scope": 7, + "src": "59:42:0", + "usedErrors": [] + } + ], + "src": "36:65:0" + }, + "id": 0 + } + }, + "settings": { + "outputSelection": { + "*": { + "": [ + "ast" + ] + } + } + } +} diff --git a/test/cmdlineTests/standard_import_with_comments/output.json b/test/cmdlineTests/standard_import_with_comments/output.json new file mode 100644 index 000000000000..6ecac5ca364d --- /dev/null +++ b/test/cmdlineTests/standard_import_with_comments/output.json @@ -0,0 +1,97 @@ +{ + "sources": + { + "A": + { + "ast": + { + "absolutePath": "A", + "exportedSymbols": + { + "C": + [ + 6 + ] + }, + "id": 7, + "license": "GPL-3.0", + "nodeType": "SourceUnit", + "nodes": + [ + { + "id": 1, + "literals": + [ + "solidity", + ">=", + "0.0" + ], + "nodeType": "PragmaDirective", + "src": "36:22:0" + }, + { + "abstract": false, + "baseContracts": [], + "canonicalName": "C", + "contractDependencies": [], + "contractKind": "contract", + "fullyImplemented": true, + "id": 6, + "linearizedBaseContracts": + [ + 6 + ], + "name": "C", + "nameLocation": "68:1:0", + "nodeType": "ContractDefinition", + "nodes": + [ + { + "body": + { + "id": 4, + "nodeType": "Block", + "src": "97:2:0", + "statements": [] + }, + "functionSelector": "26121ff0", + "id": 5, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "f", + "nameLocation": "81:1:0", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 2, + "nodeType": "ParameterList", + "parameters": [], + "src": "82:2:0" + }, + "returnParameters": + { + "id": 3, + "nodeType": "ParameterList", + "parameters": [], + "src": "97:0:0" + }, + "scope": 6, + "src": "72:27:0", + "stateMutability": "pure", + "virtual": false, + "visibility": "public" + } + ], + "scope": 7, + "src": "59:42:0", + "usedErrors": [], + "usedEvents": [] + } + ], + "src": "36:65:0" + }, + "id": 0 + } + } +} diff --git a/test/cmdlineTests/standard_import_with_comments_simple/input.json b/test/cmdlineTests/standard_import_with_comments_simple/input.json new file mode 100644 index 000000000000..21faca8c624e --- /dev/null +++ b/test/cmdlineTests/standard_import_with_comments_simple/input.json @@ -0,0 +1,85 @@ +{ + "language": "SolidityAST", + "sources": { + // this is a comment + "A": { + "ast": { + "absolutePath": "A", + "exportedSymbols": { + "C": [6 /* and this another comment */] + }, + "id": 7, + "license": "GPL-3.0", + "nodeType": "SourceUnit", + "nodes": [ + { + "id": 1, + "literals": ["solidity", ">=", "0.0"], + "nodeType": "PragmaDirective", + "src": "36:22:0" + }, + { + "abstract": false, + "baseContracts": [], + "canonicalName": "C", + "contractDependencies": [], + "contractKind": "contract", + "fullyImplemented": true, + "id": 6, + "linearizedBaseContracts": [6], + "name": "C", + "nameLocation": "68:1:0", + "nodeType": "ContractDefinition", + "nodes": [ + { + "body": { + "id": 4, + "nodeType": "Block", + "src": "97:2:0", + "statements": [] + }, + "functionSelector": "26121ff0", + "id": 5, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "f", + "nameLocation": "81:1:0", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 2, + "nodeType": "ParameterList", + "parameters": [], + "src": "82:2:0" + }, + "returnParameters": { + "id": 3, + "nodeType": "ParameterList", + "parameters": [], + "src": "97:0:0" + }, + "scope": 6, + "src": "72:27:0", + "stateMutability": "pure", + "virtual": false, + "visibility": "public" + } + ], + "scope": 7, + "src": "59:42:0", + "usedErrors": [] + } + ], + "src": "36:65:0" + }, + "id": 0 + } + }, + "settings": { + "outputSelection": { + "*": { + "": ["ast"] + } + } + } +} diff --git a/test/cmdlineTests/standard_import_with_comments_simple/output.json b/test/cmdlineTests/standard_import_with_comments_simple/output.json new file mode 100644 index 000000000000..6ecac5ca364d --- /dev/null +++ b/test/cmdlineTests/standard_import_with_comments_simple/output.json @@ -0,0 +1,97 @@ +{ + "sources": + { + "A": + { + "ast": + { + "absolutePath": "A", + "exportedSymbols": + { + "C": + [ + 6 + ] + }, + "id": 7, + "license": "GPL-3.0", + "nodeType": "SourceUnit", + "nodes": + [ + { + "id": 1, + "literals": + [ + "solidity", + ">=", + "0.0" + ], + "nodeType": "PragmaDirective", + "src": "36:22:0" + }, + { + "abstract": false, + "baseContracts": [], + "canonicalName": "C", + "contractDependencies": [], + "contractKind": "contract", + "fullyImplemented": true, + "id": 6, + "linearizedBaseContracts": + [ + 6 + ], + "name": "C", + "nameLocation": "68:1:0", + "nodeType": "ContractDefinition", + "nodes": + [ + { + "body": + { + "id": 4, + "nodeType": "Block", + "src": "97:2:0", + "statements": [] + }, + "functionSelector": "26121ff0", + "id": 5, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "f", + "nameLocation": "81:1:0", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 2, + "nodeType": "ParameterList", + "parameters": [], + "src": "82:2:0" + }, + "returnParameters": + { + "id": 3, + "nodeType": "ParameterList", + "parameters": [], + "src": "97:0:0" + }, + "scope": 6, + "src": "72:27:0", + "stateMutability": "pure", + "virtual": false, + "visibility": "public" + } + ], + "scope": 7, + "src": "59:42:0", + "usedErrors": [], + "usedEvents": [] + } + ], + "src": "36:65:0" + }, + "id": 0 + } + } +} diff --git a/test/cmdlineTests/standard_import_with_invalid_utf8/input.json b/test/cmdlineTests/standard_import_with_invalid_utf8/input.json new file mode 100644 index 000000000000..7b54aebfbb66 --- /dev/null +++ b/test/cmdlineTests/standard_import_with_invalid_utf8/input.json @@ -0,0 +1,29 @@ +{ + "language": "EVMAssembly", + "sources": { + "A": { + "assemblyJson": { + ".code": [ + { + "begin": 36, + "end": 51, + "name": "PUSH", + "source": 0, + "value": "\ud800" + } + ], + "sourceList": [ + "" + ] + } + } + }, + "settings": { + "outputSelection": { + "*": { + "": [ + ] + } + } + } +} diff --git a/test/cmdlineTests/standard_import_with_invalid_utf8/output.json b/test/cmdlineTests/standard_import_with_invalid_utf8/output.json new file mode 100644 index 000000000000..057e4fe169c6 --- /dev/null +++ b/test/cmdlineTests/standard_import_with_invalid_utf8/output.json @@ -0,0 +1,12 @@ +{ + "errors": + [ + { + "component": "general", + "formattedMessage": "parse error at line 12, column 23: syntax error while parsing value - invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF; last read: '\"\\ud800\"'", + "message": "parse error at line 12, column 23: syntax error while parsing value - invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF; last read: '\"\\ud800\"'", + "severity": "error", + "type": "JSONError" + } + ] +} diff --git a/test/cmdlineTests/standard_non_utf8_filename/input.json b/test/cmdlineTests/standard_non_utf8_filename/input.json new file mode 100644 index 000000000000..b0f7d595768a --- /dev/null +++ b/test/cmdlineTests/standard_non_utf8_filename/input.json @@ -0,0 +1,17 @@ +{ + "language": "Solidity", + "sources": + { + "": + { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0; pragma abicoder v2; contract C { function f() public pure {} }" + } + }, + "settings": + { + "outputSelection": + { + "*": { "*": ["ir"] } + } + } +} diff --git a/test/cmdlineTests/standard_non_utf8_filename/output.json b/test/cmdlineTests/standard_non_utf8_filename/output.json new file mode 100644 index 000000000000..a74a83a98975 --- /dev/null +++ b/test/cmdlineTests/standard_non_utf8_filename/output.json @@ -0,0 +1,12 @@ +{ + "errors": + [ + { + "component": "general", + "formattedMessage": "parse error at line 5, column 4: syntax error while parsing object key - invalid string: ill-formed UTF-8 byte; last read: '\"\\xff'; expected string literal", + "message": "parse error at line 5, column 4: syntax error while parsing object key - invalid string: ill-formed UTF-8 byte; last read: '\"\\xff'; expected string literal", + "severity": "error", + "type": "JSONError" + } + ] +} diff --git a/test/cmdlineTests/standard_non_utf8_filename2/input.json b/test/cmdlineTests/standard_non_utf8_filename2/input.json new file mode 100644 index 000000000000..7310c1472397 --- /dev/null +++ b/test/cmdlineTests/standard_non_utf8_filename2/input.json @@ -0,0 +1,17 @@ +{ + "language": "Solidity", + "sources": + { + "": + { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0; pragma abicoder v2; contract C { function f() public pure {} }" + } + }, + "settings": + { + "outputSelection": + { + "*": { "*": ["ir"] } + } + } +} diff --git a/test/cmdlineTests/standard_non_utf8_filename2/output.json b/test/cmdlineTests/standard_non_utf8_filename2/output.json new file mode 100644 index 000000000000..a74a83a98975 --- /dev/null +++ b/test/cmdlineTests/standard_non_utf8_filename2/output.json @@ -0,0 +1,12 @@ +{ + "errors": + [ + { + "component": "general", + "formattedMessage": "parse error at line 5, column 4: syntax error while parsing object key - invalid string: ill-formed UTF-8 byte; last read: '\"\\xff'; expected string literal", + "message": "parse error at line 5, column 4: syntax error while parsing object key - invalid string: ill-formed UTF-8 byte; last read: '\"\\xff'; expected string literal", + "severity": "error", + "type": "JSONError" + } + ] +} diff --git a/test/cmdlineTests/standard_raw_utf16_filename/input.json b/test/cmdlineTests/standard_raw_utf16_filename/input.json new file mode 100644 index 0000000000000000000000000000000000000000..1c4a1b3232cf6ae00d16546bd94afcc8ee2d4fd6 GIT binary patch literal 297 zcmYk1O-sZu5QckAe#I~+mF;fPTNk~opu!#&dQeag*>qY4Vp7sXkkG%qXVX$phGCcw zo_XIS1sY}hsCvR0uyKZ44nMfbi_t}|X~bHJB!$4@xwsT2$EA2()90?850(po+Sx!h z%&6TCn$zQ3d1Os?r1GWB3+|YF4Ns?IdAF@T?BG@ZrC?m&!oz*Ft@f~v)tR+x$;0>U z9%i&xI=}%EbkXX-&O&!}4MRK|*133sG{J;f&LqXOc%Ts2_J1Z^3_}bJ8Cn4UwBKaa R32-j&$R0l-Ll%&n'; expected string literal", + "message": "parse error at line 5, column 4: syntax error while parsing object key - invalid string: control character U+0000 (NUL) must be escaped to \\u0000; last read: '\"'; expected string literal", + "severity": "error", + "type": "JSONError" + } + ] +} diff --git a/test/libevmasm/Assembler.cpp b/test/libevmasm/Assembler.cpp index 2b01ae03c7ec..afad9d13ddc5 100644 --- a/test/libevmasm/Assembler.cpp +++ b/test/libevmasm/Assembler.cpp @@ -210,7 +210,7 @@ BOOST_AUTO_TEST_CASE(all_assembly_items) "{\"begin\":8,\"end\":18,\"name\":\"MSTORE\",\"source\":2}" "]},\"A6885B3731702DA62E8E4A8F584AC46A7F6822F4E2BA50FBA902F67B1588D23B\":\"01020304\"},\"sourceList\":[\"root.asm\",\"sub.asm\",\"verbatim.asm\"]}" }; - Json::Value jsonValue; + Json jsonValue; BOOST_CHECK(util::jsonParseStrict(json, jsonValue)); BOOST_CHECK_EQUAL(util::jsonCompactPrint(_assembly.assemblyJSON(indices)), util::jsonCompactPrint(jsonValue)); } diff --git a/test/libsolidity/ASTPropertyTest.cpp b/test/libsolidity/ASTPropertyTest.cpp index 8dc2c2930bfc..05c9b8786db8 100644 --- a/test/libsolidity/ASTPropertyTest.cpp +++ b/test/libsolidity/ASTPropertyTest.cpp @@ -108,20 +108,20 @@ void ASTPropertyTest::readExpectations() m_expectation = formatExpectations(false /* _obtainedResult */); } -void ASTPropertyTest::extractTestsFromAST(Json::Value const& _astJson) +void ASTPropertyTest::extractTestsFromAST(Json const& _astJson) { - std::queue nodesToVisit; + std::queue nodesToVisit; nodesToVisit.push(_astJson); while (!nodesToVisit.empty()) { - Json::Value& node = nodesToVisit.front(); + Json& node = nodesToVisit.front(); - if (node.isArray()) + if (node.is_array()) for (auto&& member: node) nodesToVisit.push(member); - else if (node.isObject()) - for (std::string const& memberName: node.getMemberNames()) + else if (node.is_object()) + for (auto const& [memberName, value]: node.items()) { if (memberName != "documentation") { @@ -129,9 +129,8 @@ void ASTPropertyTest::extractTestsFromAST(Json::Value const& _astJson) continue; } - std::string nodeDocstring = node["documentation"].isObject() ? - node["documentation"]["text"].asString() : - node["documentation"].asString(); + std::string nodeDocstring = value.is_object() ? + value["text"].get() : value.get(); soltestAssert(!nodeDocstring.empty()); std::vector pairs = readKeyValuePairs(nodeDocstring); @@ -150,17 +149,22 @@ void ASTPropertyTest::extractTestsFromAST(Json::Value const& _astJson) ); m_tests[testId].property = testedProperty; - soltestAssert(node.isMember("nodeType")); - std::optional propertyNode = jsonValueByPath(node, testedProperty); + soltestAssert(node.contains("nodeType")); + std::optional propertyNode = jsonValueByPath(node, testedProperty); soltestAssert( propertyNode.has_value(), - node["nodeType"].asString() + " node does not have a property named \""s + testedProperty + "\"" + node["nodeType"].get() + " node does not have a property named \""s + testedProperty + "\"" ); soltestAssert( - !propertyNode->isObject() && !propertyNode->isArray(), + !propertyNode->is_object() && !propertyNode->is_array(), "Property \"" + testedProperty + "\" is an object or an array." ); - m_tests[testId].obtainedValue = propertyNode->asString(); + if (propertyNode->is_string()) + m_tests[testId].obtainedValue = propertyNode->get(); + else if (propertyNode->is_boolean()) + m_tests[testId].obtainedValue = fmt::format("{}", propertyNode->get()); + else + soltestAssert(false); } } @@ -195,8 +199,8 @@ TestCase::TestResult ASTPropertyTest::run(std::ostream& _stream, std::string con SourceReferenceFormatter::formatErrorInformation(compiler.errors(), compiler, _formatted) )); - Json::Value astJson = ASTJsonExporter(compiler.state()).toJson(compiler.ast("A")); - soltestAssert(astJson); + Json astJson = ASTJsonExporter(compiler.state()).toJson(compiler.ast("A")); + soltestAssert(!astJson.empty()); extractTestsFromAST(astJson); diff --git a/test/libsolidity/ASTPropertyTest.h b/test/libsolidity/ASTPropertyTest.h index e4cec05280b5..6130cedb299e 100644 --- a/test/libsolidity/ASTPropertyTest.h +++ b/test/libsolidity/ASTPropertyTest.h @@ -56,7 +56,7 @@ class ASTPropertyTest: public TestCase void readExpectations(); std::vector readKeyValuePairs(std::string const& _input); - void extractTestsFromAST(Json::Value const& _astJson); + void extractTestsFromAST(Json const& _astJson); std::string formatExpectations(bool _obtainedResult = true); std::vector m_testOrder; diff --git a/test/libsolidity/GasTest.cpp b/test/libsolidity/GasTest.cpp index 4786a2a86327..14722535e446 100644 --- a/test/libsolidity/GasTest.cpp +++ b/test/libsolidity/GasTest.cpp @@ -82,18 +82,18 @@ void GasTest::parseExpectations(std::istream& _stream) void GasTest::printUpdatedExpectations(std::ostream& _stream, std::string const& _linePrefix) const { - Json::Value estimates = compiler().gasEstimates(compiler().lastContractName()); - for (auto groupIt = estimates.begin(); groupIt != estimates.end(); ++groupIt) + Json estimates = compiler().gasEstimates(compiler().lastContractName()); + for (auto& [key, group] : estimates.items()) { - _stream << _linePrefix << groupIt.key().asString() << ":" << std::endl; - for (auto it = groupIt->begin(); it != groupIt->end(); ++it) + _stream << _linePrefix << key << ":" << std::endl; + for (auto& [elementKey, value] : group.items()) { _stream << _linePrefix << " "; - if (it.key().asString().empty()) + if (elementKey.empty()) _stream << "fallback"; else - _stream << it.key().asString(); - _stream << ": " << it->asString() << std::endl; + _stream << elementKey; + _stream << ": " << value.get() << std::endl; } } } @@ -128,14 +128,14 @@ TestCase::TestResult GasTest::run(std::ostream& _stream, std::string const& _lin return TestResult::FatalError; } - Json::Value estimateGroups = compiler().gasEstimates(compiler().lastContractName()); + Json estimateGroups = compiler().gasEstimates(compiler().lastContractName()); if ( m_expectations.size() == estimateGroups.size() && boost::all(m_expectations, [&](auto const& expectations) { auto const& estimates = estimateGroups[expectations.first]; return estimates.size() == expectations.second.size() && boost::all(expectations.second, [&](auto const& entry) { - return entry.second == estimates[entry.first].asString(); + return entry.second == estimates[entry.first].template get(); }); }) ) diff --git a/test/libsolidity/LibSolc.cpp b/test/libsolidity/LibSolc.cpp index 1a7a6ba69633..f7a434dcfd25 100644 --- a/test/libsolidity/LibSolc.cpp +++ b/test/libsolidity/LibSolc.cpp @@ -36,30 +36,30 @@ namespace /// TODO: share this between StandardCompiler.cpp /// Helper to match a specific error type and message -bool containsError(Json::Value const& _compilerResult, std::string const& _type, std::string const& _message) +bool containsError(Json const& _compilerResult, std::string const& _type, std::string const& _message) { - if (!_compilerResult.isMember("errors")) + if (!_compilerResult.contains("errors")) return false; for (auto const& error: _compilerResult["errors"]) { - BOOST_REQUIRE(error.isObject()); - BOOST_REQUIRE(error["type"].isString()); - BOOST_REQUIRE(error["message"].isString()); - if ((error["type"].asString() == _type) && (error["message"].asString() == _message)) + BOOST_REQUIRE(error.is_object()); + BOOST_REQUIRE(error["type"].is_string()); + BOOST_REQUIRE(error["message"].is_string()); + if ((error["type"].get() == _type) && (error["message"].get() == _message)) return true; } return false; } -Json::Value compile(std::string const& _input, CStyleReadFileCallback _callback = nullptr) +Json compile(std::string const& _input, CStyleReadFileCallback _callback = nullptr) { char* output_ptr = solidity_compile(_input.c_str(), _callback, nullptr); std::string output(output_ptr); solidity_free(output_ptr); solidity_reset(); - Json::Value ret; + Json ret; BOOST_REQUIRE(util::jsonParseStrict(output, ret)); return ret; } @@ -100,14 +100,14 @@ BOOST_AUTO_TEST_CASE(standard_compilation) } } )"; - Json::Value result = compile(input); - BOOST_REQUIRE(result.isObject()); + Json result = compile(input); + BOOST_REQUIRE(result.is_object()); // Only tests some assumptions. The StandardCompiler is tested properly in another suite. - BOOST_CHECK(result.isMember("sources")); + BOOST_CHECK(result.contains("sources")); // This used to test that it is a member, but we did not actually request any output, // so there should not be a contract member. - BOOST_CHECK(!result.isMember("contracts")); + BOOST_CHECK(!result.contains("contracts")); } BOOST_AUTO_TEST_CASE(missing_callback) @@ -122,8 +122,8 @@ BOOST_AUTO_TEST_CASE(missing_callback) } } )"; - Json::Value result = compile(input); - BOOST_REQUIRE(result.isObject()); + Json result = compile(input); + BOOST_REQUIRE(result.is_object()); BOOST_CHECK(containsError(result, "ParserError", "Source \"missing.sol\" not found: File not supplied initially.")); } @@ -168,8 +168,8 @@ BOOST_AUTO_TEST_CASE(with_callback) } }; - Json::Value result = compile(input, callback); - BOOST_REQUIRE(result.isObject()); + Json result = compile(input, callback); + BOOST_REQUIRE(result.is_object()); // This ensures that "found.sol" was properly loaded which triggered the second import statement. BOOST_CHECK(containsError(result, "ParserError", "Source \"missing.sol\" not found: Missing file.")); diff --git a/test/libsolidity/Metadata.cpp b/test/libsolidity/Metadata.cpp index 029419af11c5..94687f99006d 100644 --- a/test/libsolidity/Metadata.cpp +++ b/test/libsolidity/Metadata.cpp @@ -57,17 +57,17 @@ std::optional compileAndCheckLicenseMetadata(std::string const& _co BOOST_REQUIRE_MESSAGE(compilerStack.compile(), "Compiling contract failed"); std::string const& serialisedMetadata = compilerStack.metadata(_contractName); - Json::Value metadata; + Json metadata; BOOST_REQUIRE(util::jsonParseStrict(serialisedMetadata, metadata)); BOOST_CHECK(solidity::test::isValidMetadata(metadata)); BOOST_CHECK_EQUAL(metadata["sources"].size(), 1); - BOOST_REQUIRE(metadata["sources"].isMember("A.sol")); + BOOST_REQUIRE(metadata["sources"].contains("A.sol")); - if (metadata["sources"]["A.sol"].isMember("license")) + if (metadata["sources"]["A.sol"].contains("license")) { - BOOST_REQUIRE(metadata["sources"]["A.sol"]["license"].isString()); - return metadata["sources"]["A.sol"]["license"].asString(); + BOOST_REQUIRE(metadata["sources"]["A.sol"]["license"].is_string()); + return metadata["sources"]["A.sol"]["license"].get(); } else return std::nullopt; @@ -288,12 +288,12 @@ BOOST_AUTO_TEST_CASE(metadata_relevant_sources) BOOST_REQUIRE_MESSAGE(compilerStack.compile(), "Compiling contract failed"); std::string const& serialisedMetadata = compilerStack.metadata("A"); - Json::Value metadata; + Json metadata; BOOST_REQUIRE(util::jsonParseStrict(serialisedMetadata, metadata)); BOOST_CHECK(solidity::test::isValidMetadata(metadata)); BOOST_CHECK_EQUAL(metadata["sources"].size(), 1); - BOOST_CHECK(metadata["sources"].isMember("A")); + BOOST_CHECK(metadata["sources"].contains("A")); } BOOST_AUTO_TEST_CASE(metadata_relevant_sources_imports) @@ -329,14 +329,14 @@ BOOST_AUTO_TEST_CASE(metadata_relevant_sources_imports) BOOST_REQUIRE_MESSAGE(compilerStack.compile(), "Compiling contract failed"); std::string const& serialisedMetadata = compilerStack.metadata("C"); - Json::Value metadata; + Json metadata; BOOST_REQUIRE(util::jsonParseStrict(serialisedMetadata, metadata)); BOOST_CHECK(solidity::test::isValidMetadata(metadata)); BOOST_CHECK_EQUAL(metadata["sources"].size(), 3); - BOOST_CHECK(metadata["sources"].isMember("A")); - BOOST_CHECK(metadata["sources"].isMember("B")); - BOOST_CHECK(metadata["sources"].isMember("C")); + BOOST_CHECK(metadata["sources"].contains("A")); + BOOST_CHECK(metadata["sources"].contains("B")); + BOOST_CHECK(metadata["sources"].contains("C")); } BOOST_AUTO_TEST_CASE(metadata_useLiteralContent) @@ -357,16 +357,16 @@ BOOST_AUTO_TEST_CASE(metadata_useLiteralContent) compilerStack.useMetadataLiteralSources(_literal); BOOST_REQUIRE_MESSAGE(compilerStack.compile(), "Compiling contract failed"); std::string metadata_str = compilerStack.metadata("test"); - Json::Value metadata; + Json metadata; BOOST_REQUIRE(util::jsonParseStrict(metadata_str, metadata)); BOOST_CHECK(solidity::test::isValidMetadata(metadata)); - BOOST_CHECK(metadata.isMember("settings")); - BOOST_CHECK(metadata["settings"].isMember("metadata")); - BOOST_CHECK(metadata["settings"]["metadata"].isMember("bytecodeHash")); + BOOST_CHECK(metadata.contains("settings")); + BOOST_CHECK(metadata["settings"].contains("metadata")); + BOOST_CHECK(metadata["settings"]["metadata"].contains("bytecodeHash")); if (_literal) { - BOOST_CHECK(metadata["settings"]["metadata"].isMember("useLiteralContent")); - BOOST_CHECK(metadata["settings"]["metadata"]["useLiteralContent"].asBool()); + BOOST_CHECK(metadata["settings"]["metadata"].contains("useLiteralContent")); + BOOST_CHECK(metadata["settings"]["metadata"]["useLiteralContent"].get()); } }; @@ -391,17 +391,17 @@ BOOST_AUTO_TEST_CASE(metadata_viair) compilerStack.setViaIR(_viaIR); BOOST_REQUIRE_MESSAGE(compilerStack.compile(), "Compiling contract failed"); - Json::Value metadata; + Json metadata; BOOST_REQUIRE(util::jsonParseStrict(compilerStack.metadata("test"), metadata)); BOOST_CHECK(solidity::test::isValidMetadata(metadata)); - BOOST_CHECK(metadata.isMember("settings")); + BOOST_CHECK(metadata.contains("settings")); if (_viaIR) { - BOOST_CHECK(metadata["settings"].isMember("viaIR")); - BOOST_CHECK(metadata["settings"]["viaIR"].asBool()); + BOOST_CHECK(metadata["settings"].contains("viaIR")); + BOOST_CHECK(metadata["settings"]["viaIR"].get()); } else - BOOST_CHECK(!metadata["settings"].isMember("viaIR")); + BOOST_CHECK(!metadata["settings"].contains("viaIR")); BOOST_CHECK(compilerStack.cborMetadata("test") == compilerStack.cborMetadata("test", _viaIR)); BOOST_CHECK(compilerStack.cborMetadata("test") != compilerStack.cborMetadata("test", !_viaIR)); @@ -431,7 +431,7 @@ BOOST_AUTO_TEST_CASE(metadata_revert_strings) BOOST_REQUIRE_MESSAGE(compilerStack.compile(), "Compiling contract failed"); std::string const& serialisedMetadata = compilerStack.metadata("A"); - Json::Value metadata; + Json metadata; BOOST_REQUIRE(util::jsonParseStrict(serialisedMetadata, metadata)); BOOST_CHECK(solidity::test::isValidMetadata(metadata)); @@ -469,14 +469,14 @@ BOOST_AUTO_TEST_CASE(metadata_optimiser_sequence) BOOST_REQUIRE_MESSAGE(compilerStack.compile(), "Compiling contract failed"); std::string const& serialisedMetadata = compilerStack.metadata("C"); - Json::Value metadata; + Json metadata; BOOST_REQUIRE(util::jsonParseStrict(serialisedMetadata, metadata)); BOOST_CHECK(solidity::test::isValidMetadata(metadata)); - BOOST_CHECK(metadata["settings"]["optimizer"].isMember("details")); - BOOST_CHECK(metadata["settings"]["optimizer"]["details"].isMember("yulDetails")); - BOOST_CHECK(metadata["settings"]["optimizer"]["details"]["yulDetails"].isMember("optimizerSteps")); + BOOST_CHECK(metadata["settings"]["optimizer"].contains("details")); + BOOST_CHECK(metadata["settings"]["optimizer"]["details"].contains("yulDetails")); + BOOST_CHECK(metadata["settings"]["optimizer"]["details"]["yulDetails"].contains("optimizerSteps")); - std::string const metadataOptimizerSteps = metadata["settings"]["optimizer"]["details"]["yulDetails"]["optimizerSteps"].asString(); + std::string const metadataOptimizerSteps = metadata["settings"]["optimizer"]["details"]["yulDetails"]["optimizerSteps"].get(); std::string const expectedMetadataOptimiserSteps = _optimizerSequence + ":" + _optimizerCleanupSequence; BOOST_CHECK_EQUAL(metadataOptimizerSteps, expectedMetadataOptimiserSteps); }; diff --git a/test/libsolidity/NatspecJSONTest.cpp b/test/libsolidity/NatspecJSONTest.cpp index 9f1ba1d7de00..7dff638f0de5 100644 --- a/test/libsolidity/NatspecJSONTest.cpp +++ b/test/libsolidity/NatspecJSONTest.cpp @@ -67,7 +67,7 @@ void NatspecJSONTest::parseCustomExpectations(std::istream& _stream) std::string rawJSON = extractExpectationJSON(_stream); std::string jsonErrors; - Json::Value parsedJSON; + Json parsedJSON; bool jsonParsingSuccessful = jsonParseStrict(rawJSON, parsedJSON, &jsonErrors); if (!jsonParsingSuccessful) BOOST_THROW_EXCEPTION(std::runtime_error(fmt::format( @@ -86,7 +86,7 @@ void NatspecJSONTest::parseCustomExpectations(std::istream& _stream) bool NatspecJSONTest::expectationsMatch() { - // NOTE: Comparing pretty printed Json::Values to avoid using its operator==, which fails to + // NOTE: Comparing pretty printed Jsons to avoid using its operator==, which fails to // compare equal numbers as equal. For example, for 'version' field the value is sometimes int, // sometimes uint and they compare as different even when both are 1. return diff --git a/test/libsolidity/NatspecJSONTest.h b/test/libsolidity/NatspecJSONTest.h index 762b88d10659..619ece83b165 100644 --- a/test/libsolidity/NatspecJSONTest.h +++ b/test/libsolidity/NatspecJSONTest.h @@ -44,7 +44,7 @@ enum class NatspecJSONKind std::ostream& operator<<(std::ostream& _output, NatspecJSONKind _kind); -using NatspecMap = std::map>; +using NatspecMap = std::map>; using SerializedNatspecMap = std::map>; class NatspecJSONTest: public SyntaxTest diff --git a/test/libsolidity/SemanticTest.cpp b/test/libsolidity/SemanticTest.cpp index 63e8a924abca..b0bdb95cb9c4 100644 --- a/test/libsolidity/SemanticTest.cpp +++ b/test/libsolidity/SemanticTest.cpp @@ -429,7 +429,7 @@ TestCase::TestResult SemanticTest::runTest( { soltestAssert( m_allowNonExistingFunctions || - m_compiler.interfaceSymbols(m_compiler.lastContractName(m_sources.mainSourceFile))["methods"].isMember(test.call().signature), + m_compiler.interfaceSymbols(m_compiler.lastContractName(m_sources.mainSourceFile))["methods"].contains(test.call().signature), "The function " + test.call().signature + " is not known to the compiler" ); diff --git a/test/libsolidity/StandardCompiler.cpp b/test/libsolidity/StandardCompiler.cpp index 22db222ea5af..cdb6c5bd2d9d 100644 --- a/test/libsolidity/StandardCompiler.cpp +++ b/test/libsolidity/StandardCompiler.cpp @@ -22,6 +22,7 @@ #include #include +#include #include #include #include @@ -55,97 +56,97 @@ langutil::Error::Severity str2Severity(std::string const& _cat) } /// Helper to match a specific error type and message -bool containsError(Json::Value const& _compilerResult, std::string const& _type, std::string const& _message) +bool containsError(Json const& _compilerResult, std::string const& _type, std::string const& _message) { - if (!_compilerResult.isMember("errors")) + if (!_compilerResult.contains("errors")) return false; for (auto const& error: _compilerResult["errors"]) { - BOOST_REQUIRE(error.isObject()); - BOOST_REQUIRE(error["type"].isString()); - BOOST_REQUIRE(error["message"].isString()); - if ((error["type"].asString() == _type) && (error["message"].asString() == _message)) + BOOST_REQUIRE(error.is_object()); + BOOST_REQUIRE(error["type"].is_string()); + BOOST_REQUIRE(error["message"].is_string()); + if ((error["type"].get() == _type) && (error["message"].get() == _message)) return true; } return false; } -bool containsAtMostWarnings(Json::Value const& _compilerResult) +bool containsAtMostWarnings(Json const& _compilerResult) { - if (!_compilerResult.isMember("errors")) + if (!_compilerResult.contains("errors")) return true; for (auto const& error: _compilerResult["errors"]) { - BOOST_REQUIRE(error.isObject()); - BOOST_REQUIRE(error["severity"].isString()); - if (langutil::Error::isError(str2Severity(error["severity"].asString()))) + BOOST_REQUIRE(error.is_object()); + BOOST_REQUIRE(error["severity"].is_string()); + if (langutil::Error::isError(str2Severity(error["severity"].get()))) return false; } return true; } -Json::Value getContractResult(Json::Value const& _compilerResult, std::string const& _file, std::string const& _name) +Json getContractResult(Json const& _compilerResult, std::string const& _file, std::string const& _name) { - if ( - !_compilerResult["contracts"].isObject() || - !_compilerResult["contracts"][_file].isObject() || - !_compilerResult["contracts"][_file][_name].isObject() + if (!_compilerResult.contains("contracts") || + !_compilerResult["contracts"].is_object() || + !_compilerResult["contracts"][_file].is_object() || + !_compilerResult["contracts"][_file][_name].is_object() ) - return Json::Value(); + return Json(); return _compilerResult["contracts"][_file][_name]; } -void checkLinkReferencesSchema(Json::Value const& _contractResult) +void checkLinkReferencesSchema(Json const& _contractResult) { - BOOST_TEST_REQUIRE(_contractResult.isObject()); - BOOST_TEST_REQUIRE(_contractResult["evm"]["bytecode"].isObject()); + BOOST_TEST_REQUIRE(_contractResult.is_object()); + BOOST_TEST_REQUIRE(_contractResult["evm"]["bytecode"].is_object()); - Json::Value const& linkReferenceResult = _contractResult["evm"]["bytecode"]["linkReferences"]; - BOOST_TEST_REQUIRE(linkReferenceResult.isObject()); + Json const& linkReferenceResult = _contractResult["evm"]["bytecode"]["linkReferences"]; + BOOST_TEST_REQUIRE(linkReferenceResult.is_object()); - for (std::string const& fileName: linkReferenceResult.getMemberNames()) + for (auto const& [fileName, references]: linkReferenceResult.items()) { - BOOST_TEST_REQUIRE(linkReferenceResult[fileName].isObject()); - for (std::string const& libraryName: linkReferenceResult[fileName].getMemberNames()) + BOOST_TEST_REQUIRE(references.is_object()); + for (auto const& [libraryName, libraryValue]: references.items()) { - BOOST_TEST_REQUIRE(linkReferenceResult[fileName][libraryName].isArray()); - BOOST_TEST_REQUIRE(!linkReferenceResult[fileName][libraryName].empty()); - for (int i = 0; i < static_cast(linkReferenceResult.size()); ++i) + BOOST_TEST_REQUIRE(libraryValue.is_array()); + BOOST_TEST_REQUIRE(!libraryValue.empty()); + for (size_t i = 0; i < static_cast(linkReferenceResult.size()); ++i) { - BOOST_TEST_REQUIRE(linkReferenceResult[fileName][libraryName][i].isObject()); - BOOST_TEST_REQUIRE(linkReferenceResult[fileName][libraryName][i].size() == 2); - BOOST_TEST_REQUIRE(linkReferenceResult[fileName][libraryName][i]["length"].isUInt()); - BOOST_TEST_REQUIRE(linkReferenceResult[fileName][libraryName][i]["start"].isUInt()); + BOOST_TEST_REQUIRE(libraryValue[i].is_object()); + BOOST_TEST_REQUIRE(libraryValue[i].size() == 2); + BOOST_TEST_REQUIRE(libraryValue[i]["length"].is_number_unsigned()); + BOOST_TEST_REQUIRE(libraryValue[i]["start"].is_number_unsigned()); } } } } -void expectLinkReferences(Json::Value const& _contractResult, std::map> const& _expectedLinkReferences) +void expectLinkReferences(Json const& _contractResult, std::map> const& _expectedLinkReferences) { checkLinkReferencesSchema(_contractResult); - Json::Value const& linkReferenceResult = _contractResult["evm"]["bytecode"]["linkReferences"]; + Json const& linkReferenceResult = _contractResult["evm"]["bytecode"]["linkReferences"]; BOOST_TEST(linkReferenceResult.size() == _expectedLinkReferences.size()); for (auto const& [fileName, libraries]: _expectedLinkReferences) { - BOOST_TEST(linkReferenceResult.isMember(fileName)); + BOOST_TEST(linkReferenceResult.contains(fileName)); BOOST_TEST(linkReferenceResult[fileName].size() == libraries.size()); for (std::string const& libraryName: libraries) - BOOST_TEST(linkReferenceResult[fileName].isMember(libraryName)); + BOOST_TEST(linkReferenceResult[fileName].contains(libraryName)); } } -Json::Value compile(std::string _input) +Json compile(std::string _input) { StandardCompiler compiler; std::string output = compiler.compile(std::move(_input)); - Json::Value ret; + Json ret; BOOST_REQUIRE(util::jsonParseStrict(output, ret)); return ret; } @@ -156,25 +157,24 @@ BOOST_AUTO_TEST_SUITE(StandardCompiler) BOOST_AUTO_TEST_CASE(assume_object_input) { - Json::Value result; + Json result; /// Use the native JSON interface of StandardCompiler to trigger these frontend::StandardCompiler compiler; - result = compiler.compile(Json::Value()); + result = compiler.compile(Json()); BOOST_CHECK(containsError(result, "JSONError", "Input is not a JSON object.")); - result = compiler.compile(Json::Value("INVALID")); + result = compiler.compile(Json("INVALID")); BOOST_CHECK(containsError(result, "JSONError", "Input is not a JSON object.")); /// Use the string interface of StandardCompiler to trigger these result = compile(""); - BOOST_CHECK(containsError(result, "JSONError", "* Line 1, Column 1\n Syntax error: value, object or array expected.\n* Line 1, Column 1\n A valid JSON document must be either an array or an object value.\n")); + BOOST_CHECK(containsError(result, "JSONError", "parse error at line 1, column 1: attempting to parse an empty input; check that your input string or stream contains the expected JSON")); result = compile("invalid"); - BOOST_CHECK(containsError(result, "JSONError", "* Line 1, Column 1\n Syntax error: value, object or array expected.\n* Line 1, Column 2\n Extra non-whitespace after JSON value.\n")); + BOOST_CHECK(containsError(result, "JSONError", "parse error at line 1, column 1: syntax error while parsing value - invalid literal; last read: 'i'")); result = compile("\"invalid\""); - BOOST_CHECK(containsError(result, "JSONError", "* Line 1, Column 1\n A valid JSON document must be either an array or an object value.\n")); - BOOST_CHECK(!containsError(result, "JSONError", "* Line 1, Column 1\n Syntax error: value, object or array expected.\n")); + BOOST_CHECK(containsError(result, "JSONError", "Input is not a JSON object.")); result = compile("{}"); - BOOST_CHECK(!containsError(result, "JSONError", "* Line 1, Column 1\n Syntax error: value, object or array expected.\n")); + BOOST_CHECK(containsError(result, "JSONError", "No input sources specified.")); BOOST_CHECK(!containsAtMostWarnings(result)); } @@ -186,7 +186,7 @@ BOOST_AUTO_TEST_CASE(invalid_language) "sources": { "name": { "content": "abc" } } } )"; - Json::Value result = compile(input); + Json result = compile(input); BOOST_CHECK(containsError(result, "JSONError", "Only \"Solidity\", \"Yul\", \"SolidityAST\" or \"EVMAssembly\" is supported as a language.")); } @@ -197,7 +197,7 @@ BOOST_AUTO_TEST_CASE(valid_language) "language": "Solidity" } )"; - Json::Value result = compile(input); + Json result = compile(input); BOOST_CHECK(!containsError(result, "JSONError", "Only \"Solidity\" or \"Yul\" is supported as a language.")); } @@ -208,7 +208,7 @@ BOOST_AUTO_TEST_CASE(no_sources) "language": "Solidity" } )"; - Json::Value result = compile(input); + Json result = compile(input); BOOST_CHECK(containsError(result, "JSONError", "No input sources specified.")); } @@ -220,7 +220,7 @@ BOOST_AUTO_TEST_CASE(no_sources_empty_object) "sources": {} } )"; - Json::Value result = compile(input); + Json result = compile(input); BOOST_CHECK(containsError(result, "JSONError", "No input sources specified.")); } @@ -232,7 +232,7 @@ BOOST_AUTO_TEST_CASE(no_sources_empty_array) "sources": [] } )"; - Json::Value result = compile(input); + Json result = compile(input); BOOST_CHECK(containsError(result, "JSONError", "\"sources\" is not a JSON object.")); } @@ -244,7 +244,7 @@ BOOST_AUTO_TEST_CASE(sources_is_array) "sources": ["aa", "bb"] } )"; - Json::Value result = compile(input); + Json result = compile(input); BOOST_CHECK(containsError(result, "JSONError", "\"sources\" is not a JSON object.")); } @@ -262,8 +262,8 @@ BOOST_AUTO_TEST_CASE(unexpected_trailing_test) } } )"; - Json::Value result = compile(input); - BOOST_CHECK(containsError(result, "JSONError", "* Line 10, Column 2\n Extra non-whitespace after JSON value.\n")); + Json result = compile(input); + BOOST_CHECK(containsError(result, "JSONError", "parse error at line 10, column 2: syntax error while parsing value - unexpected '}'; expected end of input")); } BOOST_AUTO_TEST_CASE(smoke_test) @@ -278,7 +278,7 @@ BOOST_AUTO_TEST_CASE(smoke_test) } } )"; - Json::Value result = compile(input); + Json result = compile(input); BOOST_CHECK(containsAtMostWarnings(result)); } @@ -299,7 +299,7 @@ BOOST_AUTO_TEST_CASE(optimizer_enabled_not_boolean) } } )"; - Json::Value result = compile(input); + Json result = compile(input); BOOST_CHECK(containsError(result, "JSONError", "The \"enabled\" setting must be a Boolean.")); } @@ -321,7 +321,7 @@ BOOST_AUTO_TEST_CASE(optimizer_runs_not_a_number) } } )"; - Json::Value result = compile(input); + Json result = compile(input); BOOST_CHECK(containsError(result, "JSONError", "The \"runs\" setting must be an unsigned number.")); } @@ -343,7 +343,7 @@ BOOST_AUTO_TEST_CASE(optimizer_runs_not_an_unsigned_number) } } )"; - Json::Value result = compile(input); + Json result = compile(input); BOOST_CHECK(containsError(result, "JSONError", "The \"runs\" setting must be an unsigned number.")); } @@ -367,28 +367,28 @@ BOOST_AUTO_TEST_CASE(basic_compilation) } } )"; - Json::Value result = compile(input); + Json result = compile(input); BOOST_CHECK(containsAtMostWarnings(result)); - Json::Value contract = getContractResult(result, "fileA", "A"); - BOOST_CHECK(contract.isObject()); - BOOST_CHECK(contract["abi"].isArray()); + Json contract = getContractResult(result, "fileA", "A"); + BOOST_CHECK(contract.is_object()); + BOOST_CHECK(contract["abi"].is_array()); BOOST_CHECK_EQUAL(util::jsonCompactPrint(contract["abi"]), "[]"); - BOOST_CHECK(contract["devdoc"].isObject()); + BOOST_CHECK(contract["devdoc"].is_object()); BOOST_CHECK_EQUAL(util::jsonCompactPrint(contract["devdoc"]), R"({"kind":"dev","methods":{},"version":1})"); - BOOST_CHECK(contract["userdoc"].isObject()); + BOOST_CHECK(contract["userdoc"].is_object()); BOOST_CHECK_EQUAL(util::jsonCompactPrint(contract["userdoc"]), R"({"kind":"user","methods":{},"version":1})"); - BOOST_CHECK(contract["evm"].isObject()); + BOOST_CHECK(contract["evm"].is_object()); /// @TODO check evm.methodIdentifiers, legacyAssembly, bytecode, deployedBytecode - BOOST_CHECK(contract["evm"]["bytecode"].isObject()); - BOOST_CHECK(contract["evm"]["bytecode"]["object"].isString()); + BOOST_CHECK(contract["evm"]["bytecode"].is_object()); + BOOST_CHECK(contract["evm"]["bytecode"]["object"].is_string()); BOOST_CHECK_EQUAL( - solidity::test::bytecodeSansMetadata(contract["evm"]["bytecode"]["object"].asString()), + solidity::test::bytecodeSansMetadata(contract["evm"]["bytecode"]["object"].get()), std::string("6080604052348015600e575f80fd5b5060") + (VersionIsRelease ? "3e" : util::toHex(bytes{uint8_t(60 + VersionStringStrict.size())})) + "80601a5f395ff3fe60806040525f80fdfe" ); - BOOST_CHECK(contract["evm"]["assembly"].isString()); - BOOST_CHECK(contract["evm"]["assembly"].asString().find( + BOOST_CHECK(contract["evm"]["assembly"].is_string()); + BOOST_CHECK(contract["evm"]["assembly"].get().find( " /* \"fileA\":0:14 contract A { } */\n mstore(0x40, 0x80)\n " "callvalue\n dup1\n " "iszero\n tag_1\n jumpi\n " @@ -400,22 +400,22 @@ BOOST_AUTO_TEST_CASE(basic_compilation) "0x00\n " "dup1\n revert\n\n auxdata: 0xa26469706673582212" ) == 0); - BOOST_CHECK(contract["evm"]["gasEstimates"].isObject()); + BOOST_CHECK(contract["evm"]["gasEstimates"].is_object()); BOOST_CHECK_EQUAL(contract["evm"]["gasEstimates"].size(), 1); - BOOST_CHECK(contract["evm"]["gasEstimates"]["creation"].isObject()); + BOOST_CHECK(contract["evm"]["gasEstimates"]["creation"].is_object()); BOOST_CHECK_EQUAL(contract["evm"]["gasEstimates"]["creation"].size(), 3); - BOOST_CHECK(contract["evm"]["gasEstimates"]["creation"]["codeDepositCost"].isString()); - BOOST_CHECK(contract["evm"]["gasEstimates"]["creation"]["executionCost"].isString()); - BOOST_CHECK(contract["evm"]["gasEstimates"]["creation"]["totalCost"].isString()); + BOOST_CHECK(contract["evm"]["gasEstimates"]["creation"]["codeDepositCost"].is_string()); + BOOST_CHECK(contract["evm"]["gasEstimates"]["creation"]["executionCost"].is_string()); + BOOST_CHECK(contract["evm"]["gasEstimates"]["creation"]["totalCost"].is_string()); BOOST_CHECK_EQUAL( - u256(contract["evm"]["gasEstimates"]["creation"]["codeDepositCost"].asString()) + - u256(contract["evm"]["gasEstimates"]["creation"]["executionCost"].asString()), - u256(contract["evm"]["gasEstimates"]["creation"]["totalCost"].asString()) + u256(contract["evm"]["gasEstimates"]["creation"]["codeDepositCost"].get()) + + u256(contract["evm"]["gasEstimates"]["creation"]["executionCost"].get()), + u256(contract["evm"]["gasEstimates"]["creation"]["totalCost"].get()) ); // Lets take the top level `.code` section (the "deployer code"), that should expose most of the features of // the assembly JSON. What we want to check here is Operation, Push, PushTag, PushSub, PushSubSize and Tag. - BOOST_CHECK(contract["evm"]["legacyAssembly"].isObject()); - BOOST_CHECK(contract["evm"]["legacyAssembly"][".code"].isArray()); + BOOST_CHECK(contract["evm"]["legacyAssembly"].is_object()); + BOOST_CHECK(contract["evm"]["legacyAssembly"][".code"].is_array()); BOOST_CHECK_EQUAL( util::jsonCompactPrint(contract["evm"]["legacyAssembly"][".code"]), "[{\"begin\":0,\"end\":14,\"name\":\"PUSH\",\"source\":0,\"value\":\"80\"}," @@ -440,11 +440,11 @@ BOOST_AUTO_TEST_CASE(basic_compilation) "{\"begin\":0,\"end\":14,\"name\":\"PUSH\",\"source\":0,\"value\":\"0\"}," "{\"begin\":0,\"end\":14,\"name\":\"RETURN\",\"source\":0}]" ); - BOOST_CHECK(contract["metadata"].isString()); - BOOST_CHECK(solidity::test::isValidMetadata(contract["metadata"].asString())); - BOOST_CHECK(result["sources"].isObject()); - BOOST_CHECK(result["sources"]["fileA"].isObject()); - BOOST_CHECK(result["sources"]["fileA"]["ast"].isObject()); + BOOST_CHECK(contract["metadata"].is_string()); + BOOST_CHECK(solidity::test::isValidMetadata(contract["metadata"].get())); + BOOST_CHECK(result["sources"].is_object()); + BOOST_CHECK(result["sources"]["fileA"].is_object()); + BOOST_CHECK(result["sources"]["fileA"]["ast"].is_object()); BOOST_CHECK_EQUAL( util::jsonCompactPrint(result["sources"]["fileA"]["ast"]), "{\"absolutePath\":\"fileA\",\"exportedSymbols\":{\"A\":[1]},\"id\":2,\"nodeType\":\"SourceUnit\",\"nodes\":[{\"abstract\":false," @@ -476,14 +476,14 @@ BOOST_AUTO_TEST_CASE(compilation_error) } } )"; - Json::Value result = compile(input); - BOOST_CHECK(result.isMember("errors")); + Json result = compile(input); + BOOST_CHECK(result.contains("errors")); BOOST_CHECK(result["errors"].size() >= 1); for (auto const& error: result["errors"]) { - BOOST_REQUIRE(error.isObject()); - BOOST_REQUIRE(error["message"].isString()); - if (error["message"].asString().find("pre-release compiler") == std::string::npos) + BOOST_REQUIRE(error.is_object()); + BOOST_REQUIRE(error["message"].is_string()); + if (error["message"].get().find("pre-release compiler") == std::string::npos) { BOOST_CHECK_EQUAL( util::jsonCompactPrint(error), @@ -516,11 +516,11 @@ BOOST_AUTO_TEST_CASE(output_selection_explicit) } } )"; - Json::Value result = compile(input); + Json result = compile(input); BOOST_CHECK(containsAtMostWarnings(result)); - Json::Value contract = getContractResult(result, "fileA", "A"); - BOOST_CHECK(contract.isObject()); - BOOST_CHECK(contract["abi"].isArray()); + Json contract = getContractResult(result, "fileA", "A"); + BOOST_CHECK(contract.is_object()); + BOOST_CHECK(contract["abi"].is_array()); BOOST_CHECK_EQUAL(util::jsonCompactPrint(contract["abi"]), "[]"); } @@ -545,11 +545,11 @@ BOOST_AUTO_TEST_CASE(output_selection_all_contracts) } } )"; - Json::Value result = compile(input); + Json result = compile(input); BOOST_CHECK(containsAtMostWarnings(result)); - Json::Value contract = getContractResult(result, "fileA", "A"); - BOOST_CHECK(contract.isObject()); - BOOST_CHECK(contract["abi"].isArray()); + Json contract = getContractResult(result, "fileA", "A"); + BOOST_CHECK(contract.is_object()); + BOOST_CHECK(contract["abi"].is_array()); BOOST_CHECK_EQUAL(util::jsonCompactPrint(contract["abi"]), "[]"); } @@ -574,11 +574,11 @@ BOOST_AUTO_TEST_CASE(output_selection_all_files_single_contract) } } )"; - Json::Value result = compile(input); + Json result = compile(input); BOOST_CHECK(containsAtMostWarnings(result)); - Json::Value contract = getContractResult(result, "fileA", "A"); - BOOST_CHECK(contract.isObject()); - BOOST_CHECK(contract["abi"].isArray()); + Json contract = getContractResult(result, "fileA", "A"); + BOOST_CHECK(contract.is_object()); + BOOST_CHECK(contract["abi"].is_array()); BOOST_CHECK_EQUAL(util::jsonCompactPrint(contract["abi"]), "[]"); } @@ -603,11 +603,11 @@ BOOST_AUTO_TEST_CASE(output_selection_all_files_all_contracts) } } )"; - Json::Value result = compile(input); + Json result = compile(input); BOOST_CHECK(containsAtMostWarnings(result)); - Json::Value contract = getContractResult(result, "fileA", "A"); - BOOST_CHECK(contract.isObject()); - BOOST_CHECK(contract["abi"].isArray()); + Json contract = getContractResult(result, "fileA", "A"); + BOOST_CHECK(contract.is_object()); + BOOST_CHECK(contract["abi"].is_array()); BOOST_CHECK_EQUAL(util::jsonCompactPrint(contract["abi"]), "[]"); } @@ -632,11 +632,11 @@ BOOST_AUTO_TEST_CASE(output_selection_dependent_contract) } } )"; - Json::Value result = compile(input); + Json result = compile(input); BOOST_CHECK(containsAtMostWarnings(result)); - Json::Value contract = getContractResult(result, "fileA", "A"); - BOOST_CHECK(contract.isObject()); - BOOST_CHECK(contract["abi"].isArray()); + Json contract = getContractResult(result, "fileA", "A"); + BOOST_CHECK(contract.is_object()); + BOOST_CHECK(contract["abi"].is_array()); BOOST_CHECK_EQUAL(util::jsonCompactPrint(contract["abi"]), "[{\"inputs\":[],\"name\":\"f\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]"); } @@ -664,11 +664,11 @@ BOOST_AUTO_TEST_CASE(output_selection_dependent_contract_with_import) } } )"; - Json::Value result = compile(input); + Json result = compile(input); BOOST_CHECK(containsAtMostWarnings(result)); - Json::Value contract = getContractResult(result, "fileA", "A"); - BOOST_CHECK(contract.isObject()); - BOOST_CHECK(contract["abi"].isArray()); + Json contract = getContractResult(result, "fileA", "A"); + BOOST_CHECK(contract.is_object()); + BOOST_CHECK(contract["abi"].is_array()); BOOST_CHECK_EQUAL(util::jsonCompactPrint(contract["abi"]), "[{\"inputs\":[],\"name\":\"f\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]"); } @@ -693,11 +693,11 @@ BOOST_AUTO_TEST_CASE(filename_with_colon) } } )"; - Json::Value result = compile(input); + Json result = compile(input); BOOST_CHECK(containsAtMostWarnings(result)); - Json::Value contract = getContractResult(result, "http://github.com/ethereum/solidity/std/StandardToken.sol", "A"); - BOOST_CHECK(contract.isObject()); - BOOST_CHECK(contract["abi"].isArray()); + Json contract = getContractResult(result, "http://github.com/ethereum/solidity/std/StandardToken.sol", "A"); + BOOST_CHECK(contract.is_object()); + BOOST_CHECK(contract["abi"].is_array()); BOOST_CHECK_EQUAL(util::jsonCompactPrint(contract["abi"]), "[]"); } @@ -725,10 +725,10 @@ BOOST_AUTO_TEST_CASE(library_filename_with_colon) } } )"; - Json::Value result = compile(input); + Json result = compile(input); BOOST_CHECK(containsAtMostWarnings(result)); - Json::Value contract = getContractResult(result, "fileA", "A"); - BOOST_CHECK(contract.isObject()); + Json contract = getContractResult(result, "fileA", "A"); + BOOST_CHECK(contract.is_object()); expectLinkReferences(contract, {{"git:library.sol", {"L"}}}); } @@ -747,7 +747,7 @@ BOOST_AUTO_TEST_CASE(libraries_invalid_top_level) } } )"; - Json::Value result = compile(input); + Json result = compile(input); BOOST_CHECK(containsError(result, "JSONError", "\"libraries\" is not a JSON object.")); } @@ -768,7 +768,7 @@ BOOST_AUTO_TEST_CASE(libraries_invalid_entry) } } )"; - Json::Value result = compile(input); + Json result = compile(input); BOOST_CHECK(containsError(result, "JSONError", "Library entry is not a JSON object.")); } @@ -791,7 +791,7 @@ BOOST_AUTO_TEST_CASE(libraries_invalid_hex) } } )"; - Json::Value result = compile(input); + Json result = compile(input); BOOST_CHECK(containsError(result, "JSONError", "Invalid library address (\"0x4200000000000000000000000000000000000xx1\") supplied.")); } @@ -815,7 +815,7 @@ BOOST_AUTO_TEST_CASE(libraries_invalid_length) } } )"; - Json::Value result = compile(input); + Json result = compile(input); BOOST_CHECK(containsError(result, "JSONError", "Library address is of invalid length.")); } @@ -838,7 +838,7 @@ BOOST_AUTO_TEST_CASE(libraries_missing_hex_prefix) } } )"; - Json::Value result = compile(input); + Json result = compile(input); BOOST_CHECK(containsError(result, "JSONError", "Library address is not prefixed with \"0x\".")); } @@ -874,9 +874,9 @@ BOOST_AUTO_TEST_CASE(library_linking) } } )"; - Json::Value result = compile(input); + Json result = compile(input); BOOST_TEST(containsAtMostWarnings(result)); - Json::Value contractResult = getContractResult(result, "fileA", "A"); + Json contractResult = getContractResult(result, "fileA", "A"); expectLinkReferences(contractResult, {{"library2.sol", {"L2"}}}); } @@ -906,9 +906,9 @@ BOOST_AUTO_TEST_CASE(linking_yul) } } )"; - Json::Value result = compile(input); + Json result = compile(input); BOOST_TEST(containsAtMostWarnings(result)); - Json::Value contractResult = getContractResult(result, "fileA", "a"); + Json contractResult = getContractResult(result, "fileA", "a"); expectLinkReferences(contractResult, {}); } @@ -938,9 +938,9 @@ BOOST_AUTO_TEST_CASE(linking_yul_empty_link_reference) } } )"; - Json::Value result = compile(input); + Json result = compile(input); BOOST_TEST(containsAtMostWarnings(result)); - Json::Value contractResult = getContractResult(result, "fileA", "a"); + Json contractResult = getContractResult(result, "fileA", "a"); expectLinkReferences(contractResult, {{"", {""}}}); } @@ -970,9 +970,9 @@ BOOST_AUTO_TEST_CASE(linking_yul_no_filename_in_link_reference) } } )"; - Json::Value result = compile(input); + Json result = compile(input); BOOST_TEST(containsAtMostWarnings(result)); - Json::Value contractResult = getContractResult(result, "fileA", "a"); + Json contractResult = getContractResult(result, "fileA", "a"); expectLinkReferences(contractResult, {{"", {"L"}}}); } @@ -1002,9 +1002,9 @@ BOOST_AUTO_TEST_CASE(linking_yul_same_library_name_different_files) } } )"; - Json::Value result = compile(input); + Json result = compile(input); BOOST_TEST(containsAtMostWarnings(result)); - Json::Value contractResult = getContractResult(result, "fileA", "a"); + Json contractResult = getContractResult(result, "fileA", "a"); expectLinkReferences(contractResult, {{"fileC", {"L"}}}); } @@ -1027,37 +1027,37 @@ BOOST_AUTO_TEST_CASE(evm_version) } )"; }; - Json::Value result; + Json result; result = compile(inputForVersion("\"evmVersion\": \"homestead\",")); - BOOST_CHECK(result["contracts"]["fileA"]["A"]["metadata"].asString().find("\"evmVersion\":\"homestead\"") != std::string::npos); + BOOST_CHECK(result["contracts"]["fileA"]["A"]["metadata"].get().find("\"evmVersion\":\"homestead\"") != std::string::npos); result = compile(inputForVersion("\"evmVersion\": \"tangerineWhistle\",")); - BOOST_CHECK(result["contracts"]["fileA"]["A"]["metadata"].asString().find("\"evmVersion\":\"tangerineWhistle\"") != std::string::npos); + BOOST_CHECK(result["contracts"]["fileA"]["A"]["metadata"].get().find("\"evmVersion\":\"tangerineWhistle\"") != std::string::npos); result = compile(inputForVersion("\"evmVersion\": \"spuriousDragon\",")); - BOOST_CHECK(result["contracts"]["fileA"]["A"]["metadata"].asString().find("\"evmVersion\":\"spuriousDragon\"") != std::string::npos); + BOOST_CHECK(result["contracts"]["fileA"]["A"]["metadata"].get().find("\"evmVersion\":\"spuriousDragon\"") != std::string::npos); result = compile(inputForVersion("\"evmVersion\": \"byzantium\",")); - BOOST_CHECK(result["contracts"]["fileA"]["A"]["metadata"].asString().find("\"evmVersion\":\"byzantium\"") != std::string::npos); + BOOST_CHECK(result["contracts"]["fileA"]["A"]["metadata"].get().find("\"evmVersion\":\"byzantium\"") != std::string::npos); result = compile(inputForVersion("\"evmVersion\": \"constantinople\",")); - BOOST_CHECK(result["contracts"]["fileA"]["A"]["metadata"].asString().find("\"evmVersion\":\"constantinople\"") != std::string::npos); + BOOST_CHECK(result["contracts"]["fileA"]["A"]["metadata"].get().find("\"evmVersion\":\"constantinople\"") != std::string::npos); result = compile(inputForVersion("\"evmVersion\": \"petersburg\",")); - BOOST_CHECK(result["contracts"]["fileA"]["A"]["metadata"].asString().find("\"evmVersion\":\"petersburg\"") != std::string::npos); + BOOST_CHECK(result["contracts"]["fileA"]["A"]["metadata"].get().find("\"evmVersion\":\"petersburg\"") != std::string::npos); result = compile(inputForVersion("\"evmVersion\": \"istanbul\",")); - BOOST_CHECK(result["contracts"]["fileA"]["A"]["metadata"].asString().find("\"evmVersion\":\"istanbul\"") != std::string::npos); + BOOST_CHECK(result["contracts"]["fileA"]["A"]["metadata"].get().find("\"evmVersion\":\"istanbul\"") != std::string::npos); result = compile(inputForVersion("\"evmVersion\": \"berlin\",")); - BOOST_CHECK(result["contracts"]["fileA"]["A"]["metadata"].asString().find("\"evmVersion\":\"berlin\"") != std::string::npos); + BOOST_CHECK(result["contracts"]["fileA"]["A"]["metadata"].get().find("\"evmVersion\":\"berlin\"") != std::string::npos); result = compile(inputForVersion("\"evmVersion\": \"london\",")); - BOOST_CHECK(result["contracts"]["fileA"]["A"]["metadata"].asString().find("\"evmVersion\":\"london\"") != std::string::npos); + BOOST_CHECK(result["contracts"]["fileA"]["A"]["metadata"].get().find("\"evmVersion\":\"london\"") != std::string::npos); result = compile(inputForVersion("\"evmVersion\": \"paris\",")); - BOOST_CHECK(result["contracts"]["fileA"]["A"]["metadata"].asString().find("\"evmVersion\":\"paris\"") != std::string::npos); + BOOST_CHECK(result["contracts"]["fileA"]["A"]["metadata"].get().find("\"evmVersion\":\"paris\"") != std::string::npos); result = compile(inputForVersion("\"evmVersion\": \"shanghai\",")); - BOOST_CHECK(result["contracts"]["fileA"]["A"]["metadata"].asString().find("\"evmVersion\":\"shanghai\"") != std::string::npos); + BOOST_CHECK(result["contracts"]["fileA"]["A"]["metadata"].get().find("\"evmVersion\":\"shanghai\"") != std::string::npos); result = compile(inputForVersion("\"evmVersion\": \"cancun\",")); - BOOST_CHECK(result["contracts"]["fileA"]["A"]["metadata"].asString().find("\"evmVersion\":\"cancun\"") != std::string::npos); + BOOST_CHECK(result["contracts"]["fileA"]["A"]["metadata"].get().find("\"evmVersion\":\"cancun\"") != std::string::npos); // test default result = compile(inputForVersion("")); - BOOST_CHECK(result["contracts"]["fileA"]["A"]["metadata"].asString().find("\"evmVersion\":\"cancun\"") != std::string::npos); + BOOST_CHECK(result["contracts"]["fileA"]["A"]["metadata"].get().find("\"evmVersion\":\"cancun\"") != std::string::npos); // test invalid result = compile(inputForVersion("\"evmVersion\": \"invalid\",")); - BOOST_CHECK(result["errors"][0]["message"].asString() == "Invalid EVM version requested."); + BOOST_CHECK(result["errors"][0]["message"].get() == "Invalid EVM version requested."); } BOOST_AUTO_TEST_CASE(optimizer_settings_default_disabled) @@ -1077,19 +1077,19 @@ BOOST_AUTO_TEST_CASE(optimizer_settings_default_disabled) } } )"; - Json::Value result = compile(input); + Json result = compile(input); BOOST_CHECK(containsAtMostWarnings(result)); - Json::Value contract = getContractResult(result, "fileA", "A"); - BOOST_CHECK(contract.isObject()); - BOOST_CHECK(contract["metadata"].isString()); - Json::Value metadata; - BOOST_CHECK(util::jsonParseStrict(contract["metadata"].asString(), metadata)); - - Json::Value const& optimizer = metadata["settings"]["optimizer"]; - BOOST_CHECK(optimizer.isMember("enabled")); - BOOST_CHECK(optimizer["enabled"].asBool() == false); - BOOST_CHECK(!optimizer.isMember("details")); - BOOST_CHECK(optimizer["runs"].asUInt() == 200); + Json contract = getContractResult(result, "fileA", "A"); + BOOST_CHECK(contract.is_object()); + BOOST_CHECK(contract["metadata"].is_string()); + Json metadata; + BOOST_CHECK(util::jsonParseStrict(contract["metadata"].get(), metadata)); + + Json const& optimizer = metadata["settings"]["optimizer"]; + BOOST_CHECK(optimizer.contains("enabled")); + BOOST_CHECK(optimizer["enabled"].get() == false); + BOOST_CHECK(!optimizer.contains("details")); + BOOST_CHECK(optimizer["runs"].get() == 200); } BOOST_AUTO_TEST_CASE(optimizer_settings_default_enabled) @@ -1110,19 +1110,19 @@ BOOST_AUTO_TEST_CASE(optimizer_settings_default_enabled) } } )"; - Json::Value result = compile(input); + Json result = compile(input); BOOST_CHECK(containsAtMostWarnings(result)); - Json::Value contract = getContractResult(result, "fileA", "A"); - BOOST_CHECK(contract.isObject()); - BOOST_CHECK(contract["metadata"].isString()); - Json::Value metadata; - BOOST_CHECK(util::jsonParseStrict(contract["metadata"].asString(), metadata)); - - Json::Value const& optimizer = metadata["settings"]["optimizer"]; - BOOST_CHECK(optimizer.isMember("enabled")); - BOOST_CHECK(optimizer["enabled"].asBool() == true); - BOOST_CHECK(!optimizer.isMember("details")); - BOOST_CHECK(optimizer["runs"].asUInt() == 200); + Json contract = getContractResult(result, "fileA", "A"); + BOOST_CHECK(contract.is_object()); + BOOST_CHECK(contract["metadata"].is_string()); + Json metadata; + BOOST_CHECK(util::jsonParseStrict(contract["metadata"].get(), metadata)); + + Json const& optimizer = metadata["settings"]["optimizer"]; + BOOST_CHECK(optimizer.contains("enabled")); + BOOST_CHECK(optimizer["enabled"].get() == true); + BOOST_CHECK(!optimizer.contains("details")); + BOOST_CHECK(optimizer["runs"].get() == 200); } BOOST_AUTO_TEST_CASE(optimizer_settings_details_exactly_as_default_disabled) @@ -1150,20 +1150,20 @@ BOOST_AUTO_TEST_CASE(optimizer_settings_details_exactly_as_default_disabled) } } )"; - Json::Value result = compile(input); + Json result = compile(input); BOOST_CHECK(containsAtMostWarnings(result)); - Json::Value contract = getContractResult(result, "fileA", "A"); - BOOST_CHECK(contract.isObject()); - BOOST_CHECK(contract["metadata"].isString()); - Json::Value metadata; - BOOST_CHECK(util::jsonParseStrict(contract["metadata"].asString(), metadata)); - - Json::Value const& optimizer = metadata["settings"]["optimizer"]; - BOOST_CHECK(optimizer.isMember("enabled")); + Json contract = getContractResult(result, "fileA", "A"); + BOOST_CHECK(contract.is_object()); + BOOST_CHECK(contract["metadata"].is_string()); + Json metadata; + BOOST_CHECK(util::jsonParseStrict(contract["metadata"].get(), metadata)); + + Json const& optimizer = metadata["settings"]["optimizer"]; + BOOST_CHECK(optimizer.contains("enabled")); // enabled is switched to false instead! - BOOST_CHECK(optimizer["enabled"].asBool() == false); - BOOST_CHECK(!optimizer.isMember("details")); - BOOST_CHECK(optimizer["runs"].asUInt() == 200); + BOOST_CHECK(optimizer["enabled"].get() == false); + BOOST_CHECK(!optimizer.contains("details")); + BOOST_CHECK(optimizer["runs"].get() == 200); } BOOST_AUTO_TEST_CASE(optimizer_settings_details_different) @@ -1193,36 +1193,36 @@ BOOST_AUTO_TEST_CASE(optimizer_settings_details_different) } } )"; - Json::Value result = compile(input); + Json result = compile(input); BOOST_CHECK(containsAtMostWarnings(result)); - Json::Value contract = getContractResult(result, "fileA", "A"); - BOOST_CHECK(contract.isObject()); - BOOST_CHECK(contract["metadata"].isString()); - Json::Value metadata; - BOOST_CHECK(util::jsonParseStrict(contract["metadata"].asString(), metadata)); - - Json::Value const& optimizer = metadata["settings"]["optimizer"]; - BOOST_CHECK(!optimizer.isMember("enabled")); - BOOST_CHECK(optimizer.isMember("details")); - BOOST_CHECK(optimizer["details"]["constantOptimizer"].asBool() == true); - BOOST_CHECK(optimizer["details"]["cse"].asBool() == false); - BOOST_CHECK(optimizer["details"]["deduplicate"].asBool() == true); - BOOST_CHECK(optimizer["details"]["jumpdestRemover"].asBool() == true); - BOOST_CHECK(optimizer["details"]["orderLiterals"].asBool() == false); - BOOST_CHECK(optimizer["details"]["peephole"].asBool() == true); - BOOST_CHECK(optimizer["details"]["yul"].asBool() == true); - BOOST_CHECK(optimizer["details"]["yulDetails"].isObject()); + Json contract = getContractResult(result, "fileA", "A"); + BOOST_CHECK(contract.is_object()); + BOOST_CHECK(contract["metadata"].is_string()); + Json metadata; + BOOST_CHECK(util::jsonParseStrict(contract["metadata"].get(), metadata)); + + Json const& optimizer = metadata["settings"]["optimizer"]; + BOOST_CHECK(!optimizer.contains("enabled")); + BOOST_CHECK(optimizer.contains("details")); + BOOST_CHECK(optimizer["details"]["constantOptimizer"].get() == true); + BOOST_CHECK(optimizer["details"]["cse"].get() == false); + BOOST_CHECK(optimizer["details"]["deduplicate"].get() == true); + BOOST_CHECK(optimizer["details"]["jumpdestRemover"].get() == true); + BOOST_CHECK(optimizer["details"]["orderLiterals"].get() == false); + BOOST_CHECK(optimizer["details"]["peephole"].get() == true); + BOOST_CHECK(optimizer["details"]["yul"].get() == true); + BOOST_CHECK(optimizer["details"]["yulDetails"].is_object()); +// BOOST_CHECK( +// util::convertContainer>(optimizer["details"]["yulDetails"].getMemberNames()) == +// (std::set{"stackAllocation", "optimizerSteps"}) +// ); + BOOST_CHECK(optimizer["details"]["yulDetails"]["stackAllocation"].get() == true); BOOST_CHECK( - util::convertContainer>(optimizer["details"]["yulDetails"].getMemberNames()) == - (std::set{"stackAllocation", "optimizerSteps"}) - ); - BOOST_CHECK(optimizer["details"]["yulDetails"]["stackAllocation"].asBool() == true); - BOOST_CHECK( - optimizer["details"]["yulDetails"]["optimizerSteps"].asString() == + optimizer["details"]["yulDetails"]["optimizerSteps"].get() == OptimiserSettings::DefaultYulOptimiserSteps + ":"s + OptimiserSettings::DefaultYulOptimiserCleanupSteps - ); - BOOST_CHECK_EQUAL(optimizer["details"].getMemberNames().size(), 10); - BOOST_CHECK(optimizer["runs"].asUInt() == 600); + ); + BOOST_CHECK_EQUAL(optimizer["details"].size(), 10); + BOOST_CHECK(optimizer["runs"].get() == 600); } BOOST_AUTO_TEST_CASE(metadata_without_compilation) @@ -1250,12 +1250,12 @@ BOOST_AUTO_TEST_CASE(metadata_without_compilation) } } )"; - Json::Value result = compile(input); + Json result = compile(input); BOOST_CHECK(containsAtMostWarnings(result)); - Json::Value contract = getContractResult(result, "fileA", "A"); - BOOST_CHECK(contract.isObject()); - BOOST_CHECK(contract["metadata"].isString()); - BOOST_CHECK(solidity::test::isValidMetadata(contract["metadata"].asString())); + Json contract = getContractResult(result, "fileA", "A"); + BOOST_CHECK(contract.is_object()); + BOOST_CHECK(contract["metadata"].is_string()); + BOOST_CHECK(solidity::test::isValidMetadata(contract["metadata"].get())); } @@ -1281,13 +1281,13 @@ BOOST_AUTO_TEST_CASE(license_in_metadata) } } )"; - Json::Value result = compile(input); + Json result = compile(input); BOOST_CHECK(containsAtMostWarnings(result)); - Json::Value contract = getContractResult(result, "fileA", "A"); - BOOST_CHECK(contract.isObject()); - BOOST_CHECK(contract["metadata"].isString()); - Json::Value metadata; - BOOST_REQUIRE(util::jsonParseStrict(contract["metadata"].asString(), metadata)); + Json contract = getContractResult(result, "fileA", "A"); + BOOST_CHECK(contract.is_object()); + BOOST_CHECK(contract["metadata"].is_string()); + Json metadata; + BOOST_REQUIRE(util::jsonParseStrict(contract["metadata"].get(), metadata)); BOOST_CHECK_EQUAL(metadata["sources"]["fileA"]["license"], "GPL-3.0"); BOOST_CHECK_EQUAL(metadata["sources"]["fileB"]["license"], "MIT"); BOOST_CHECK_EQUAL(metadata["sources"]["fileC"]["license"], "MIT AND GPL-3.0"); @@ -1317,14 +1317,14 @@ BOOST_AUTO_TEST_CASE(common_pattern) } } )"; - Json::Value result = compile(input); + Json result = compile(input); BOOST_CHECK(containsAtMostWarnings(result)); - Json::Value contract = getContractResult(result, "fileA", "A"); - BOOST_CHECK(contract.isObject()); - BOOST_CHECK(contract["metadata"].isString()); - BOOST_CHECK(solidity::test::isValidMetadata(contract["metadata"].asString())); - BOOST_CHECK(contract["evm"]["bytecode"].isObject()); - BOOST_CHECK(contract["evm"]["bytecode"]["object"].isString()); + Json contract = getContractResult(result, "fileA", "A"); + BOOST_CHECK(contract.is_object()); + BOOST_CHECK(contract["metadata"].is_string()); + BOOST_CHECK(solidity::test::isValidMetadata(contract["metadata"].get())); + BOOST_CHECK(contract["evm"]["bytecode"].is_object()); + BOOST_CHECK(contract["evm"]["bytecode"]["object"].is_string()); } BOOST_AUTO_TEST_CASE(use_stack_optimization) @@ -1375,17 +1375,17 @@ BOOST_AUTO_TEST_CASE(use_stack_optimization) } )"; - Json::Value parsedInput; + Json parsedInput; BOOST_REQUIRE(util::jsonParseStrict(input, parsedInput)); solidity::frontend::StandardCompiler compiler; - Json::Value result = compiler.compile(parsedInput); + Json result = compiler.compile(parsedInput); BOOST_CHECK(containsAtMostWarnings(result)); - Json::Value contract = getContractResult(result, "fileA", "A"); - BOOST_REQUIRE(contract.isObject()); - BOOST_REQUIRE(contract["evm"]["bytecode"]["object"].isString()); - BOOST_CHECK(contract["evm"]["bytecode"]["object"].asString().length() > 20); + Json contract = getContractResult(result, "fileA", "A"); + BOOST_REQUIRE(contract.is_object()); + BOOST_REQUIRE(contract["evm"]["bytecode"]["object"].is_string()); + BOOST_CHECK(contract["evm"]["bytecode"]["object"].get().length() > 20); // Now disable stack optimizations and UnusedFunctionParameterPruner (p) // results in "stack too deep" @@ -1398,10 +1398,10 @@ BOOST_AUTO_TEST_CASE(use_stack_optimization) parsedInput["settings"]["optimizer"]["details"]["yulDetails"]["optimizerSteps"] = optimiserSteps; result = compiler.compile(parsedInput); - BOOST_REQUIRE(result["errors"].isArray()); + BOOST_REQUIRE(result["errors"].is_array()); BOOST_CHECK(result["errors"][0]["severity"] == "error"); - BOOST_REQUIRE(result["errors"][0]["message"].isString()); - BOOST_CHECK(result["errors"][0]["message"].asString().find("When compiling inline assembly") != std::string::npos); + BOOST_REQUIRE(result["errors"][0]["message"].is_string()); + BOOST_CHECK(result["errors"][0]["message"].get().find("When compiling inline assembly") != std::string::npos); BOOST_CHECK(result["errors"][0]["type"] == "CompilerError"); } @@ -1427,22 +1427,22 @@ BOOST_AUTO_TEST_CASE(standard_output_selection_wildcard) } )"; - Json::Value parsedInput; + Json parsedInput; BOOST_REQUIRE(util::jsonParseStrict(input, parsedInput)); solidity::frontend::StandardCompiler compiler; - Json::Value result = compiler.compile(parsedInput); + Json result = compiler.compile(parsedInput); - BOOST_REQUIRE(result["contracts"].isObject()); + BOOST_REQUIRE(result["contracts"].is_object()); BOOST_REQUIRE(result["contracts"].size() == 1); - BOOST_REQUIRE(result["contracts"]["A"].isObject()); + BOOST_REQUIRE(result["contracts"]["A"].is_object()); BOOST_REQUIRE(result["contracts"]["A"].size() == 1); - BOOST_REQUIRE(result["contracts"]["A"]["C"].isObject()); - BOOST_REQUIRE(result["contracts"]["A"]["C"]["evm"].isObject()); - BOOST_REQUIRE(result["contracts"]["A"]["C"]["evm"]["bytecode"].isObject()); - BOOST_REQUIRE(result["sources"].isObject()); + BOOST_REQUIRE(result["contracts"]["A"]["C"].is_object()); + BOOST_REQUIRE(result["contracts"]["A"]["C"]["evm"].is_object()); + BOOST_REQUIRE(result["contracts"]["A"]["C"]["evm"]["bytecode"].is_object()); + BOOST_REQUIRE(result["sources"].is_object()); BOOST_REQUIRE(result["sources"].size() == 1); - BOOST_REQUIRE(result["sources"]["A"].isObject()); + BOOST_REQUIRE(result["sources"]["A"].is_object()); } @@ -1468,22 +1468,22 @@ BOOST_AUTO_TEST_CASE(standard_output_selection_wildcard_colon_source) } )"; - Json::Value parsedInput; + Json parsedInput; BOOST_REQUIRE(util::jsonParseStrict(input, parsedInput)); solidity::frontend::StandardCompiler compiler; - Json::Value result = compiler.compile(parsedInput); + Json result = compiler.compile(parsedInput); - BOOST_REQUIRE(result["contracts"].isObject()); + BOOST_REQUIRE(result["contracts"].is_object()); BOOST_REQUIRE(result["contracts"].size() == 1); - BOOST_REQUIRE(result["contracts"][":A"].isObject()); + BOOST_REQUIRE(result["contracts"][":A"].is_object()); BOOST_REQUIRE(result["contracts"][":A"].size() == 1); - BOOST_REQUIRE(result["contracts"][":A"]["C"].isObject()); - BOOST_REQUIRE(result["contracts"][":A"]["C"]["evm"].isObject()); - BOOST_REQUIRE(result["contracts"][":A"]["C"]["evm"]["bytecode"].isObject()); - BOOST_REQUIRE(result["sources"].isObject()); + BOOST_REQUIRE(result["contracts"][":A"]["C"].is_object()); + BOOST_REQUIRE(result["contracts"][":A"]["C"]["evm"].is_object()); + BOOST_REQUIRE(result["contracts"][":A"]["C"]["evm"]["bytecode"].is_object()); + BOOST_REQUIRE(result["sources"].is_object()); BOOST_REQUIRE(result["sources"].size() == 1); - BOOST_REQUIRE(result["sources"][":A"].isObject()); + BOOST_REQUIRE(result["sources"][":A"].is_object()); } BOOST_AUTO_TEST_CASE(standard_output_selection_wildcard_empty_source) @@ -1508,22 +1508,22 @@ BOOST_AUTO_TEST_CASE(standard_output_selection_wildcard_empty_source) } )"; - Json::Value parsedInput; + Json parsedInput; BOOST_REQUIRE(util::jsonParseStrict(input, parsedInput)); solidity::frontend::StandardCompiler compiler; - Json::Value result = compiler.compile(parsedInput); + Json result = compiler.compile(parsedInput); - BOOST_REQUIRE(result["contracts"].isObject()); + BOOST_REQUIRE(result["contracts"].is_object()); BOOST_REQUIRE(result["contracts"].size() == 1); - BOOST_REQUIRE(result["contracts"][""].isObject()); + BOOST_REQUIRE(result["contracts"][""].is_object()); BOOST_REQUIRE(result["contracts"][""].size() == 1); - BOOST_REQUIRE(result["contracts"][""]["C"].isObject()); - BOOST_REQUIRE(result["contracts"][""]["C"]["evm"].isObject()); - BOOST_REQUIRE(result["contracts"][""]["C"]["evm"]["bytecode"].isObject()); - BOOST_REQUIRE(result["sources"].isObject()); + BOOST_REQUIRE(result["contracts"][""]["C"].is_object()); + BOOST_REQUIRE(result["contracts"][""]["C"]["evm"].is_object()); + BOOST_REQUIRE(result["contracts"][""]["C"]["evm"]["bytecode"].is_object()); + BOOST_REQUIRE(result["sources"].is_object()); BOOST_REQUIRE(result["sources"].size() == 1); - BOOST_REQUIRE(result["sources"][""].isObject()); + BOOST_REQUIRE(result["sources"][""].is_object()); } BOOST_AUTO_TEST_CASE(standard_output_selection_wildcard_multiple_sources) @@ -1552,23 +1552,23 @@ BOOST_AUTO_TEST_CASE(standard_output_selection_wildcard_multiple_sources) } )"; - Json::Value parsedInput; + Json parsedInput; BOOST_REQUIRE(util::jsonParseStrict(input, parsedInput)); solidity::frontend::StandardCompiler compiler; - Json::Value result = compiler.compile(parsedInput); + Json result = compiler.compile(parsedInput); - BOOST_REQUIRE(result["contracts"].isObject()); + BOOST_REQUIRE(result["contracts"].is_object()); BOOST_REQUIRE(result["contracts"].size() == 1); - BOOST_REQUIRE(result["contracts"]["B"].isObject()); + BOOST_REQUIRE(result["contracts"]["B"].is_object()); BOOST_REQUIRE(result["contracts"]["B"].size() == 1); - BOOST_REQUIRE(result["contracts"]["B"]["D"].isObject()); - BOOST_REQUIRE(result["contracts"]["B"]["D"]["evm"].isObject()); - BOOST_REQUIRE(result["contracts"]["B"]["D"]["evm"]["bytecode"].isObject()); - BOOST_REQUIRE(result["sources"].isObject()); + BOOST_REQUIRE(result["contracts"]["B"]["D"].is_object()); + BOOST_REQUIRE(result["contracts"]["B"]["D"]["evm"].is_object()); + BOOST_REQUIRE(result["contracts"]["B"]["D"]["evm"]["bytecode"].is_object()); + BOOST_REQUIRE(result["sources"].is_object()); BOOST_REQUIRE(result["sources"].size() == 2); - BOOST_REQUIRE(result["sources"]["A"].isObject()); - BOOST_REQUIRE(result["sources"]["B"].isObject()); + BOOST_REQUIRE(result["sources"]["A"].is_object()); + BOOST_REQUIRE(result["sources"]["B"].is_object()); } BOOST_AUTO_TEST_CASE(stopAfter_invalid_value) @@ -1588,7 +1588,7 @@ BOOST_AUTO_TEST_CASE(stopAfter_invalid_value) } } )"; - Json::Value result = compile(input); + Json result = compile(input); BOOST_CHECK(containsError(result, "JSONError", "Invalid value for \"settings.stopAfter\". Only valid value is \"parsing\".")); } @@ -1609,7 +1609,7 @@ BOOST_AUTO_TEST_CASE(stopAfter_invalid_type) } } )"; - Json::Value result = compile(input); + Json result = compile(input); BOOST_CHECK(containsError(result, "JSONError", "\"settings.stopAfter\" must be a string.")); } @@ -1630,7 +1630,7 @@ BOOST_AUTO_TEST_CASE(stopAfter_bin_conflict) } } )"; - Json::Value result = compile(input); + Json result = compile(input); BOOST_CHECK(containsError(result, "JSONError", "Requested output selection conflicts with \"settings.stopAfter\".")); } @@ -1650,10 +1650,10 @@ BOOST_AUTO_TEST_CASE(stopAfter_ast_output) } } )"; - Json::Value result = compile(input); - BOOST_CHECK(result["sources"].isObject()); - BOOST_CHECK(result["sources"]["a.sol"].isObject()); - BOOST_CHECK(result["sources"]["a.sol"]["ast"].isObject()); + Json result = compile(input); + BOOST_CHECK(result["sources"].is_object()); + BOOST_CHECK(result["sources"]["a.sol"].is_object()); + BOOST_CHECK(result["sources"]["a.sol"]["ast"].is_object()); } BOOST_AUTO_TEST_CASE(dependency_tracking_of_abstract_contract) @@ -1679,21 +1679,21 @@ BOOST_AUTO_TEST_CASE(dependency_tracking_of_abstract_contract) } )"; - Json::Value parsedInput; + Json parsedInput; BOOST_REQUIRE(util::jsonParseStrict(input, parsedInput)); solidity::frontend::StandardCompiler compiler; - Json::Value result = compiler.compile(parsedInput); + Json result = compiler.compile(parsedInput); - BOOST_REQUIRE(result["contracts"].isObject()); + BOOST_REQUIRE(result["contracts"].is_object()); BOOST_REQUIRE(result["contracts"].size() == 1); - BOOST_REQUIRE(result["contracts"]["BlockRewardAuRaCoins.sol"].isObject()); + BOOST_REQUIRE(result["contracts"]["BlockRewardAuRaCoins.sol"].is_object()); BOOST_REQUIRE(result["contracts"]["BlockRewardAuRaCoins.sol"].size() == 1); - BOOST_REQUIRE(result["contracts"]["BlockRewardAuRaCoins.sol"]["BlockRewardAuRaCoins"].isObject()); - BOOST_REQUIRE(result["contracts"]["BlockRewardAuRaCoins.sol"]["BlockRewardAuRaCoins"]["evm"].isObject()); - BOOST_REQUIRE(result["contracts"]["BlockRewardAuRaCoins.sol"]["BlockRewardAuRaCoins"]["ir"].isString()); - BOOST_REQUIRE(result["contracts"]["BlockRewardAuRaCoins.sol"]["BlockRewardAuRaCoins"]["evm"]["bytecode"].isObject()); - BOOST_REQUIRE(result["sources"].isObject()); + BOOST_REQUIRE(result["contracts"]["BlockRewardAuRaCoins.sol"]["BlockRewardAuRaCoins"].is_object()); + BOOST_REQUIRE(result["contracts"]["BlockRewardAuRaCoins.sol"]["BlockRewardAuRaCoins"]["evm"].is_object()); + BOOST_REQUIRE(result["contracts"]["BlockRewardAuRaCoins.sol"]["BlockRewardAuRaCoins"]["ir"].is_string()); + BOOST_REQUIRE(result["contracts"]["BlockRewardAuRaCoins.sol"]["BlockRewardAuRaCoins"]["evm"]["bytecode"].is_object()); + BOOST_REQUIRE(result["sources"].is_object()); BOOST_REQUIRE(result["sources"].size() == 2); } @@ -1717,20 +1717,20 @@ BOOST_AUTO_TEST_CASE(dependency_tracking_of_abstract_contract_yul) } )"; - Json::Value parsedInput; + Json parsedInput; BOOST_REQUIRE(util::jsonParseStrict(input, parsedInput)); solidity::frontend::StandardCompiler compiler; - Json::Value result = compiler.compile(parsedInput); + Json result = compiler.compile(parsedInput); - BOOST_REQUIRE(result["contracts"].isObject()); + BOOST_REQUIRE(result["contracts"].is_object()); BOOST_REQUIRE(result["contracts"].size() == 1); - BOOST_REQUIRE(result["contracts"]["A.sol"].isObject()); + BOOST_REQUIRE(result["contracts"]["A.sol"].is_object()); BOOST_REQUIRE(result["contracts"]["A.sol"].size() == 1); - BOOST_REQUIRE(result["contracts"]["A.sol"]["C"].isObject()); - BOOST_REQUIRE(result["contracts"]["A.sol"]["C"]["ir"].isString()); + BOOST_REQUIRE(result["contracts"]["A.sol"]["C"].is_object()); + BOOST_REQUIRE(result["contracts"]["A.sol"]["C"]["ir"].is_string()); - const std::string& irCode = result["contracts"]["A.sol"]["C"]["ir"].asString(); + const std::string& irCode = result["contracts"]["A.sol"]["C"]["ir"].get(); // Make sure C and B contracts are deployed BOOST_REQUIRE(irCode.find("object \"C") != std::string::npos); @@ -1742,7 +1742,7 @@ BOOST_AUTO_TEST_CASE(dependency_tracking_of_abstract_contract_yul) BOOST_REQUIRE(irCode.find("object \"D") == std::string::npos); - BOOST_REQUIRE(result["sources"].isObject()); + BOOST_REQUIRE(result["sources"].is_object()); BOOST_REQUIRE(result["sources"].size() == 1); } @@ -1766,13 +1766,13 @@ BOOST_AUTO_TEST_CASE(source_location_of_bare_block) } )"; - Json::Value parsedInput; + Json parsedInput; BOOST_REQUIRE(util::jsonParseStrict(input, parsedInput)); solidity::frontend::StandardCompiler compiler; - Json::Value result = compiler.compile(parsedInput); + Json result = compiler.compile(parsedInput); - std::string sourceMap = result["contracts"]["A.sol"]["A"]["evm"]["bytecode"]["sourceMap"].asString(); + std::string sourceMap = result["contracts"]["A.sol"]["A"]["evm"]["bytecode"]["sourceMap"].get(); // Check that the bare block's source location is referenced. std::string sourceRef = diff --git a/test/libsolidity/util/ContractABIUtils.cpp b/test/libsolidity/util/ContractABIUtils.cpp index 641c9107d69b..fb2f4eb62679 100644 --- a/test/libsolidity/util/ContractABIUtils.cpp +++ b/test/libsolidity/util/ContractABIUtils.cpp @@ -140,16 +140,16 @@ std::optional isFixedPoint(std::string const& type) return fixedPointType; } -std::string functionSignatureFromABI(Json::Value const& _functionABI) +std::string functionSignatureFromABI(Json const& _functionABI) { auto inputs = _functionABI["inputs"]; - std::string signature = {_functionABI["name"].asString() + "("}; + std::string signature = {_functionABI["name"].get() + "("}; size_t parameterCount = 0; for (auto const& input: inputs) { parameterCount++; - signature += input["type"].asString(); + signature += input["type"].get(); if (parameterCount < inputs.size()) signature += ","; } @@ -161,11 +161,11 @@ std::string functionSignatureFromABI(Json::Value const& _functionABI) std::optional ContractABIUtils::parametersFromJsonOutputs( ErrorReporter& _errorReporter, - Json::Value const& _contractABI, + Json const& _contractABI, std::string const& _functionSignature ) { - if (!_contractABI) + if (_contractABI.empty()) return std::nullopt; for (auto const& function: _contractABI) @@ -177,7 +177,7 @@ std::optional ContractABIUtils::paramet for (auto const& output: function["outputs"]) { - std::string type = output["type"].asString(); + std::string type = output["type"].get(); ABITypes inplaceTypes; ABITypes dynamicTypes; @@ -209,13 +209,13 @@ std::optional ContractABIUtils::paramet } bool ContractABIUtils::appendTypesFromName( - Json::Value const& _functionOutput, + Json const& _functionOutput, ABITypes& _inplaceTypes, ABITypes& _dynamicTypes, bool _isCompoundType ) { - std::string type = _functionOutput["type"].asString(); + std::string type = _functionOutput["type"].get(); if (isBool(type)) _inplaceTypes.push_back(ABIType{ABIType::Boolean}); else if (isUint(type)) diff --git a/test/libsolidity/util/ContractABIUtils.h b/test/libsolidity/util/ContractABIUtils.h index 209eca4232ba..3f0b1b04e283 100644 --- a/test/libsolidity/util/ContractABIUtils.h +++ b/test/libsolidity/util/ContractABIUtils.h @@ -19,8 +19,7 @@ #include #include - -#include +#include namespace solidity::frontend::test { @@ -40,7 +39,7 @@ class ContractABIUtils /// auto-correction during interactive update routine. static std::optional parametersFromJsonOutputs( ErrorReporter& _errorReporter, - Json::Value const& _contractABI, + Json const& _contractABI, std::string const& _functionSignature ); @@ -86,7 +85,7 @@ class ContractABIUtils /// `bytes` -> [`Unsigned`, `Unsigned`, `HexString`] /// ... static bool appendTypesFromName( - Json::Value const& _functionOutput, + Json const& _functionOutput, ABITypes& _inplaceTypes, ABITypes& _dynamicTypes, bool _isCompoundType = false diff --git a/test/libsolidity/util/TestFunctionCall.cpp b/test/libsolidity/util/TestFunctionCall.cpp index dd74d4035c68..3e0d3e873708 100644 --- a/test/libsolidity/util/TestFunctionCall.cpp +++ b/test/libsolidity/util/TestFunctionCall.cpp @@ -413,7 +413,7 @@ void TestFunctionCall::reset() { m_rawBytes = bytes{}; m_failure = true; - m_contractABI = Json::Value{}; + m_contractABI = Json(); m_calledNonExistingFunction = false; } diff --git a/test/libsolidity/util/TestFunctionCall.h b/test/libsolidity/util/TestFunctionCall.h index 724cb8286c19..9a63262cc2eb 100644 --- a/test/libsolidity/util/TestFunctionCall.h +++ b/test/libsolidity/util/TestFunctionCall.h @@ -23,8 +23,6 @@ #include #include -#include - #include #include #include @@ -99,7 +97,7 @@ class TestFunctionCall void setRawBytes(const bytes _rawBytes) { m_rawBytes = _rawBytes; } void setGasCostExcludingCode(std::string const& _runType, u256 const& _gasCost) { m_gasCostsExcludingCode[_runType] = _gasCost; } void setCodeDepositGasCost(std::string const& _runType, u256 const& _gasCost) { m_codeDepositGasCosts[_runType] = _gasCost; } - void setContractABI(Json::Value _contractABI) { m_contractABI = std::move(_contractABI); } + void setContractABI(Json _contractABI) { m_contractABI = std::move(_contractABI); } void setSideEffects(std::vector _sideEffects) { m_call.actualSideEffects = _sideEffects; } private: @@ -154,7 +152,7 @@ class TestFunctionCall bool m_failure = true; /// JSON object which holds the contract ABI and that is used to set the output formatting /// in the interactive update routine. - Json::Value m_contractABI = Json::Value{}; + Json m_contractABI = Json{}; /// Flags that the test failed because the called function is not known to exist on the contract. bool m_calledNonExistingFunction = false; }; diff --git a/test/libsolutil/JSON.cpp b/test/libsolutil/JSON.cpp index da10c0b3c6a9..91e6771acc90 100644 --- a/test/libsolutil/JSON.cpp +++ b/test/libsolutil/JSON.cpp @@ -34,50 +34,50 @@ BOOST_AUTO_TEST_SUITE(JsonTest, *boost::unit_test::label("nooptions")) BOOST_AUTO_TEST_CASE(json_types) { - auto check = [](Json::Value value, std::string const& expectation) { + auto check = [](Json value, std::string const& expectation) { BOOST_CHECK(jsonCompactPrint(value) == expectation); }; - Json::Value value; + Json value; BOOST_CHECK(value.empty()); value = {}; BOOST_CHECK(value.empty()); - value = Json::Value(); + value = Json(); BOOST_CHECK(value.empty()); - value = Json::nullValue; + value = Json(); BOOST_CHECK(value.empty()); check(value, "null"); check({}, "null"); - check(Json::Value(), "null"); - check(Json::nullValue, "null"); - check(Json::objectValue, "{}"); - check(Json::arrayValue, "[]"); - check(Json::UInt(1), "1"); - check(Json::UInt(-1), "4294967295"); - check(Json::UInt64(1), "1"); - check(Json::UInt64(-1), "18446744073709551615"); - check(Json::LargestUInt(1), "1"); - check(Json::LargestUInt(-1), "18446744073709551615"); - check(Json::LargestUInt(0xffffffff), "4294967295"); - check(Json::Value("test"), "\"test\""); + check(Json(), "null"); + check(Json(), "null"); + check(Json::object(), "{}"); + check(Json::array(), "[]"); + check(1, "1"); + check(static_cast(-1), "4294967295"); + check(1, "1"); + check(static_cast(-1), "18446744073709551615"); + check(1, "1"); + check(static_cast(-1), "18446744073709551615"); + check(0xffffffff, "4294967295"); + check(Json("test"), "\"test\""); check("test", "\"test\""); check(true, "true"); - value = Json::objectValue; + value = Json::object(); value["key"] = "value"; check(value, "{\"key\":\"value\"}"); - value = Json::arrayValue; - value.append(1); - value.append(2); + value = Json::array(); + value.push_back(1); + value.push_back(2); check(value, "[1,2]"); } BOOST_AUTO_TEST_CASE(json_pretty_print) { - Json::Value json; - Json::Value jsonChild; + Json json; + Json jsonChild; jsonChild["3.1"] = "3.1"; jsonChild["3.2"] = 2; @@ -85,7 +85,7 @@ BOOST_AUTO_TEST_CASE(json_pretty_print) json["2"] = "2"; json["3"] = jsonChild; json["4"] = "ऑ ऒ ओ औ क ख"; - json["5"] = "\xff"; + json["5"] = "\\xff\\xfe"; BOOST_CHECK( "{\n" @@ -97,14 +97,14 @@ BOOST_AUTO_TEST_CASE(json_pretty_print) " \"3.2\": 2\n" " },\n" " \"4\": \"\\u0911 \\u0912 \\u0913 \\u0914 \\u0915 \\u0916\",\n" - " \"5\": \"\\ufffd\"\n" + " \"5\": \"\\\\xff\\\\xfe\"\n" "}" == jsonPrettyPrint(json)); } BOOST_AUTO_TEST_CASE(json_compact_print) { - Json::Value json; - Json::Value jsonChild; + Json json; + Json jsonChild; jsonChild["3.1"] = "3.1"; jsonChild["3.2"] = 2; @@ -112,9 +112,10 @@ BOOST_AUTO_TEST_CASE(json_compact_print) json["2"] = "2"; json["3"] = jsonChild; json["4"] = "ऑ ऒ ओ औ क ख"; - json["5"] = "\xff"; + json["5"] = "\x10"; + json["6"] = "\u4e2d"; - BOOST_CHECK("{\"1\":1,\"2\":\"2\",\"3\":{\"3.1\":\"3.1\",\"3.2\":2},\"4\":\"\\u0911 \\u0912 \\u0913 \\u0914 \\u0915 \\u0916\",\"5\":\"\\ufffd\"}" == jsonCompactPrint(json)); + BOOST_CHECK(R"({"1":1,"2":"2","3":{"3.1":"3.1","3.2":2},"4":"\u0911 \u0912 \u0913 \u0914 \u0915 \u0916","5":"\u0010","6":"\u4e2d"})" == jsonCompactPrint(json)); } BOOST_AUTO_TEST_CASE(parse_json_strict) @@ -122,7 +123,7 @@ BOOST_AUTO_TEST_CASE(parse_json_strict) // In this test we check conformance against JSON.parse (https://tc39.es/ecma262/multipage/structured-data.html#sec-json.parse) // and ECMA-404 (https://www.ecma-international.org/publications-and-standards/standards/ecma-404/) - Json::Value json; + Json json; std::string errors; // Just parse a valid json input @@ -135,179 +136,202 @@ BOOST_AUTO_TEST_CASE(parse_json_strict) // Trailing garbage is not allowed in ECMA-262 BOOST_CHECK(!jsonParseStrict("{\"1\":2,\"2\":\"2\",\"3\":{\"3.1\":\"3.1\",\"3.2\":3}}}}}}}}}}", json, &errors)); - // Comments are not allowed in ECMA-262 - // ... but JSONCPP allows them - BOOST_CHECK(jsonParseStrict( - "{\"1\":3, // awesome comment\n\"2\":\"2\",\"3\":{\"3.1\":\"3.1\",\"3.2\":5}}", json, &errors - )); - BOOST_CHECK(json["1"] == 3); - BOOST_CHECK(json["2"] == "2"); - BOOST_CHECK(json["3"]["3.1"] == "3.1"); - BOOST_CHECK(json["3"]["3.2"] == 5); - // According to ECMA-404 object, array, number, string, true, false, null are allowed // ... but JSONCPP disallows value types BOOST_CHECK(jsonParseStrict("[]", json, &errors)); - BOOST_CHECK(json.isArray()); + BOOST_CHECK(json.is_array()); BOOST_CHECK(jsonParseStrict("{}", json, &errors)); - BOOST_CHECK(json.isObject()); - BOOST_CHECK(!jsonParseStrict("1", json, &errors)); - // BOOST_CHECK(json.isNumeric()); - BOOST_CHECK(!jsonParseStrict("\"hello\"", json, &errors)); - // BOOST_CHECK(json.isString()); - BOOST_CHECK(!jsonParseStrict("true", json, &errors)); - // BOOST_CHECK(json.isBool()); - BOOST_CHECK(!jsonParseStrict("null", json, &errors)); - // BOOST_CHECK(json.isNull()); + BOOST_CHECK(json.is_object()); + BOOST_CHECK(jsonParseStrict("1", json, &errors)); + BOOST_CHECK(json.is_number()); + BOOST_CHECK(jsonParseStrict("\"hello\"", json, &errors)); + BOOST_CHECK(json.is_string()); + BOOST_CHECK(jsonParseStrict("true", json, &errors)); + BOOST_CHECK(json.is_boolean()); + BOOST_CHECK(jsonParseStrict("null", json, &errors)); + BOOST_CHECK(json.is_null()); // Single quotes are also disallowed by ECMA-404 BOOST_CHECK(!jsonParseStrict("'hello'", json, &errors)); - // BOOST_CHECK(json.isString()); + // BOOST_CHECK(json.is_string()); // Only string keys in objects are allowed in ECMA-404 BOOST_CHECK(!jsonParseStrict("{ 42: \"hello\" }", json, &errors)); // According to ECMA-404 hex escape sequences are not allowed, only unicode (\uNNNN) and // a few control characters (\b, \f, \n, \r, \t) - // - // More lenient parsers allow hex escapes as long as they translate to a valid UTF-8 encoding. - // - // ... but JSONCPP allows any hex escapes - BOOST_CHECK(jsonParseStrict("[ \"\x80\xec\x80\" ]", json, &errors)); - BOOST_CHECK(json.isArray()); - BOOST_CHECK(json[0] == "\x80\xec\x80"); - - // This would be valid more lenient parsers. + BOOST_CHECK(jsonParseStrict("[ \"\xF0\x9F\x98\x8A\" ]", json, &errors)); - BOOST_CHECK(json.isArray()); + BOOST_CHECK(json.is_array()); BOOST_CHECK(json[0] == "😊"); + BOOST_CHECK(json[0] == "\xF0\x9F\x98\x8A"); } BOOST_AUTO_TEST_CASE(json_isOfType) { - Json::Value json; + Json json; json["float"] = 3.1f; json["double"] = 3.1; json["int"] = 2; - json["int64"] = Json::Int64{0x4000000000000000}; + json["int64"] = 0x4000000000000000; json["string"] = "Hello World!"; BOOST_CHECK(isOfType(json["float"])); BOOST_CHECK(isOfType(json["double"])); BOOST_CHECK(isOfType(json["int"])); - BOOST_CHECK(isOfType(json["int"])); - BOOST_CHECK(isOfType(json["int"])); - BOOST_CHECK(isOfType(json["int"])); - BOOST_CHECK(isOfType(json["int64"])); - BOOST_CHECK(isOfType(json["int64"])); + BOOST_CHECK(isOfType(json["int"])); + BOOST_CHECK(isOfType(json["int"])); + BOOST_CHECK(isOfType(json["int"])); + BOOST_CHECK(isOfType(json["int"])); + BOOST_CHECK(isOfType(json["int64"])); + BOOST_CHECK(isOfType(json["int64"])); + BOOST_CHECK(isOfType(json["int64"])); BOOST_CHECK(isOfType(json["string"])); - BOOST_CHECK(!isOfType(json["int64"])); + BOOST_CHECK(!isOfType(json["int64"])); BOOST_CHECK(!isOfType(json["double"])); BOOST_CHECK(!isOfType(json["string"])); BOOST_CHECK(!isOfType(json["string"])); - BOOST_CHECK(!isOfType(json["string"])); - BOOST_CHECK(!isOfType(json["string"])); - BOOST_CHECK(!isOfType(json["string"])); - BOOST_CHECK(!isOfType(json["string"])); + BOOST_CHECK(!isOfType(json["string"])); + BOOST_CHECK(!isOfType(json["string"])); + BOOST_CHECK(!isOfType(json["string"])); + BOOST_CHECK(!isOfType(json["string"])); } BOOST_AUTO_TEST_CASE(json_isisOfTypeIfExists) { - Json::Value json; + Json json; json["float"] = 3.1f; json["double"] = 3.1; json["int"] = 2; - json["int64"] = Json::Int64{0x4000000000000000}; + json["uint"] = 2u; + json["int64"] = 0x4000000000000000; + json["uint64"] = 0x4000000000000000u; json["string"] = "Hello World!"; BOOST_CHECK(isOfTypeIfExists(json, "float")); BOOST_CHECK(isOfTypeIfExists(json, "double")); BOOST_CHECK(isOfTypeIfExists(json, "int")); - BOOST_CHECK(isOfTypeIfExists(json, "int")); - BOOST_CHECK(isOfTypeIfExists(json, "int")); - BOOST_CHECK(isOfTypeIfExists(json, "int")); - BOOST_CHECK(isOfTypeIfExists(json, "int64")); - BOOST_CHECK(isOfTypeIfExists(json, "int64")); + BOOST_CHECK(isOfTypeIfExists(json, "int")); + BOOST_CHECK(isOfTypeIfExists(json, "uint")); + BOOST_CHECK(isOfTypeIfExists(json, "int")); + BOOST_CHECK(isOfTypeIfExists(json, "int64")); + BOOST_CHECK(isOfTypeIfExists(json, "uint64")); BOOST_CHECK(isOfTypeIfExists(json, "string")); - BOOST_CHECK(!isOfTypeIfExists(json, "int64")); + BOOST_CHECK(!isOfTypeIfExists(json, "int64")); BOOST_CHECK(!isOfTypeIfExists(json, "double")); BOOST_CHECK(!isOfTypeIfExists(json, "string")); BOOST_CHECK(!isOfTypeIfExists(json, "string")); - BOOST_CHECK(!isOfTypeIfExists(json, "string")); - BOOST_CHECK(!isOfTypeIfExists(json, "string")); - BOOST_CHECK(!isOfTypeIfExists(json, "string")); - BOOST_CHECK(!isOfTypeIfExists(json, "string")); - BOOST_CHECK(isOfTypeIfExists(json, "NOT_EXISTING")); + BOOST_CHECK(!isOfTypeIfExists(json, "string")); + BOOST_CHECK(!isOfTypeIfExists(json, "string")); + BOOST_CHECK(!isOfTypeIfExists(json, "string")); + BOOST_CHECK(!isOfTypeIfExists(json, "string")); + BOOST_CHECK(isOfTypeIfExists(json, "NOT_EXISTING")); } BOOST_AUTO_TEST_CASE(json_getOrDefault) { - Json::Value json; + Json json; json["float"] = 3.1f; json["double"] = 3.1; json["int"] = 2; - json["int64"] = Json::Int64{0x4000000000000000}; - json["uint64"] = Json::UInt64{0x5000000000000000}; + json["int64"] = 0x4000000000000000; + json["uint64"] = 0x5000000000000000; json["string"] = "Hello World!"; - BOOST_CHECK(getOrDefault(json["float"]) == 3.1f); - BOOST_CHECK(getOrDefault(json["float"], -1.1f) == 3.1f); - BOOST_CHECK(getOrDefault(json["no_float"], -1.1f) == -1.1f); - BOOST_CHECK(getOrDefault(json["double"]) == 3.1); - BOOST_CHECK(getOrDefault(json["double"], -1) == 3.1); - BOOST_CHECK(getOrDefault(json["no_double"], -1.1) == -1.1); - BOOST_CHECK(getOrDefault(json["int"]) == 2); - BOOST_CHECK(getOrDefault(json["int"], -1) == 2); - BOOST_CHECK(getOrDefault(json["no_int"], -1) == -1); - BOOST_CHECK(getOrDefault(json["int"]) == 2); - BOOST_CHECK(getOrDefault(json["int"], -1) == 2); - BOOST_CHECK(getOrDefault(json["no_int"], -1) == -1); - BOOST_CHECK(getOrDefault(json["int"]) == 2); - BOOST_CHECK(getOrDefault(json["int"], 1) == 2); - BOOST_CHECK(getOrDefault(json["no_int"], 1) == 1); - BOOST_CHECK(getOrDefault(json["int"]) == 2); - BOOST_CHECK(getOrDefault(json["int"], -1) == 2); - BOOST_CHECK(getOrDefault(json["no_int"], -1) == -1); - BOOST_CHECK(getOrDefault(json["int64"]) == 0x4000000000000000); - BOOST_CHECK(getOrDefault(json["int64"], -1) == 0x4000000000000000); - BOOST_CHECK(getOrDefault(json["no_int64"], -1) == -1); - BOOST_CHECK(getOrDefault(json["int64"]) == 0x4000000000000000); - BOOST_CHECK(getOrDefault(json["int64"], 1) == 0x4000000000000000); - BOOST_CHECK(getOrDefault(json["no_int64"], 1) == 1); - BOOST_CHECK(getOrDefault(json["uint64"]) == 0x5000000000000000); - BOOST_CHECK(getOrDefault(json["uint64"], 1) == 0x5000000000000000); - BOOST_CHECK(getOrDefault(json["no_uint64"], 1) == 1); - BOOST_CHECK(getOrDefault(json["string"], "ERROR") == "Hello World!"); - BOOST_CHECK(getOrDefault(json["no_string"]).empty()); - BOOST_CHECK(getOrDefault(json["no_string"], "ERROR") == "ERROR"); + BOOST_CHECK(getOrDefault(json, "float") == 3.1f); + BOOST_CHECK(getOrDefault(json, "float", -1.1f) == 3.1f); + BOOST_CHECK(getOrDefault(json, "no_float", -1.1f) == -1.1f); + BOOST_CHECK(getOrDefault(json, "double") == 3.1); + BOOST_CHECK(getOrDefault(json, "double", -1) == 3.1); + BOOST_CHECK(getOrDefault(json, "no_double", -1.1) == -1.1); + BOOST_CHECK(getOrDefault(json, "int") == 2); + BOOST_CHECK(getOrDefault(json, "int", -1) == 2); + BOOST_CHECK(getOrDefault(json, "no_int", -1) == -1); + BOOST_CHECK(getOrDefault(json, "int") == 2); + BOOST_CHECK(getOrDefault(json, "int", -1) == 2); + BOOST_CHECK(getOrDefault(json, "no_int", -1) == -1); + BOOST_CHECK(getOrDefault(json, "int") == 2); + BOOST_CHECK(getOrDefault(json, "int", 1) == 2); + BOOST_CHECK(getOrDefault(json, "no_int", 1) == 1); + BOOST_CHECK(getOrDefault(json, "int") == 2); + BOOST_CHECK(getOrDefault(json, "int", -1) == 2); + BOOST_CHECK(getOrDefault(json, "no_int", -1) == -1); + BOOST_CHECK(getOrDefault(json, "int64") == 0x4000000000000000); + BOOST_CHECK(getOrDefault(json, "int64", -1) == 0x4000000000000000); + BOOST_CHECK(getOrDefault(json, "no_int64", -1) == -1); + BOOST_CHECK(getOrDefault(json, "int64") == 0x4000000000000000); + BOOST_CHECK(getOrDefault(json, "int64", 1) == 0x4000000000000000); + BOOST_CHECK(getOrDefault(json, "no_int64", 1) == 1); + BOOST_CHECK(getOrDefault(json, "uint64") == 0x5000000000000000); + BOOST_CHECK(getOrDefault(json, "uint64", 1) == 0x5000000000000000); + BOOST_CHECK(getOrDefault(json, "no_uint64", 1) == 1); + BOOST_CHECK(getOrDefault(json, "string", "ERROR") == "Hello World!"); + BOOST_CHECK(getOrDefault(json, "no_string").empty()); + BOOST_CHECK(getOrDefault(json, "no_string", "ERROR") == "ERROR"); } BOOST_AUTO_TEST_CASE(json_get) { - Json::Value json; + Json json; json["float"] = 3.1f; json["double"] = 3.1; json["int"] = 2; - json["int64"] = Json::Int64{0x4000000000000000}; - json["uint64"] = Json::UInt64{0x5000000000000000}; + json["int64"] = 0x4000000000000000; + json["uint64"] = 0x5000000000000000; json["string"] = "Hello World!"; BOOST_CHECK(get(json["float"]) == 3.1f); BOOST_CHECK(get(json["double"]) == 3.1); BOOST_CHECK(get(json["int"]) == 2); - BOOST_CHECK(get(json["int"]) == 2); - BOOST_CHECK(get(json["int"]) == 2); - BOOST_CHECK(get(json["int"]) == 2); - BOOST_CHECK(get(json["int64"]) == 0x4000000000000000); - BOOST_CHECK(get(json["int64"]) == 0x4000000000000000); - BOOST_CHECK(get(json["uint64"]) == 0x5000000000000000); + BOOST_CHECK(get(json["int"]) == 2); + BOOST_CHECK(get(json["int"]) == 2); + BOOST_CHECK(get(json["int"]) == 2); + BOOST_CHECK(get(json["int64"]) == 0x4000000000000000); + BOOST_CHECK(get(json["int64"]) == 0x4000000000000000); + BOOST_CHECK(get(json["uint64"]) == 0x5000000000000000); BOOST_CHECK(get(json["string"]) == "Hello World!"); } +template +void json_test_int_range() +{ + Json max = {{"v", std::numeric_limits::max()}}; + Json min = {{"v", std::numeric_limits::min()}}; + Json overflow = {{"v", static_cast(std::numeric_limits::max()) + 1}}; + Json underflow = {{"v", static_cast(std::numeric_limits::min()) - 1}}; + BOOST_CHECK(getOrDefault(max, "v", 0) == std::numeric_limits::max()); + BOOST_CHECK(getOrDefault(min, "v", 0) == std::numeric_limits::min()); + BOOST_CHECK(getOrDefault(overflow, "v", 0) == 0); + BOOST_CHECK(getOrDefault(underflow, "v", 0) == 0); + BOOST_CHECK(get(max["v"]) == std::numeric_limits::max()); + BOOST_CHECK(get(min["v"]) == std::numeric_limits::min()); + BOOST_CHECK_THROW(get(overflow["v"]), InvalidType); + BOOST_CHECK_THROW(get(underflow["v"]), InvalidType); +} + +BOOST_AUTO_TEST_CASE(json_range_checks) +{ + json_test_int_range(); + json_test_int_range(); + json_test_int_range(); + json_test_int_range(); + json_test_int_range(); + json_test_int_range(); + + Json overflow = {{"v", static_cast(std::numeric_limits::max()) * 2}}; + Json underflow = {{"v", static_cast(std::numeric_limits::min()) / 2}}; + BOOST_CHECK(getOrDefault({{"v", std::numeric_limits::max()}}, "v", 0) == std::numeric_limits::max()); + BOOST_CHECK(getOrDefault({{"v", std::numeric_limits::min()}}, "v", 0) == std::numeric_limits::min()); + BOOST_CHECK(getOrDefault(overflow, "v", 0) == 0); + BOOST_CHECK(getOrDefault(underflow, "v", 0) == 0); + BOOST_CHECK_THROW(get(overflow["v"]), InvalidType); + BOOST_CHECK_THROW(get(underflow["v"]), InvalidType); +} + BOOST_AUTO_TEST_SUITE_END() } diff --git a/test/solc/CommandLineInterface.cpp b/test/solc/CommandLineInterface.cpp index 73ebb2c54089..b3b93cb3aa11 100644 --- a/test/solc/CommandLineInterface.cpp +++ b/test/solc/CommandLineInterface.cpp @@ -1180,15 +1180,20 @@ BOOST_AUTO_TEST_CASE(standard_json_include_paths) OptionsReaderAndMessages result = runCLI(commandLine, standardJsonInput); - Json::Value parsedStdout; + Json parsedStdout; std::string jsonParsingErrors; BOOST_TEST(util::jsonParseStrict(result.stdoutContent, parsedStdout, &jsonParsingErrors)); BOOST_TEST(jsonParsingErrors == ""); - for (Json::Value const& errorDict: parsedStdout["errors"]) + for (Json const& errorDict: parsedStdout["errors"]) // The error list might contain pre-release compiler warning BOOST_TEST(errorDict["severity"] != "error"); + // we might be able to use ranges again, but the nlohmann::json support is not yet fully there. + // (parsedStdout["sources"].items() | ranges::views::keys | ranges::to) + std::set sources; + for (auto const& [key, _]: parsedStdout["sources"].items()) + sources.insert(key); BOOST_TEST( - (parsedStdout["sources"].getMemberNames() | ranges::to) == + sources == (expectedSources | ranges::views::keys | ranges::to) + std::set{"main.sol"} ); diff --git a/test/tools/fuzzer_common.cpp b/test/tools/fuzzer_common.cpp index 1bb04bf66aad..c7e94f40b779 100644 --- a/test/tools/fuzzer_common.cpp +++ b/test/tools/fuzzer_common.cpp @@ -58,13 +58,13 @@ void FuzzerUtil::testCompilerJsonInterface(string const& _input, bool _optimize, if (!_quiet) cout << "Testing compiler " << (_optimize ? "with" : "without") << " optimizer." << endl; - Json::Value config = Json::objectValue; + Json config; config["language"] = "Solidity"; - config["sources"] = Json::objectValue; - config["sources"][""] = Json::objectValue; + config["sources"] = Json::object(); + config["sources"][""] = Json::object(); config["sources"][""]["content"] = _input; - config["settings"] = Json::objectValue; - config["settings"]["optimizer"] = Json::objectValue; + config["settings"] = Json::object(); + config["settings"]["optimizer"] = Json::object(); config["settings"]["optimizer"]["enabled"] = _optimize; config["settings"]["optimizer"]["runs"] = static_cast(OptimiserSettings{}.expectedExecutionsPerDeployment); config["settings"]["evmVersion"] = "berlin"; @@ -155,23 +155,23 @@ void FuzzerUtil::runCompiler(string const& _input, bool _quiet) // This should be safe given the above copies the output. solidity_reset(); - Json::Value output; + Json output; if (!jsonParseStrict(outputString, output)) { string msg{"Compiler produced invalid JSON output."}; cout << msg << endl; BOOST_THROW_EXCEPTION(std::runtime_error(std::move(msg))); } - if (output.isMember("errors")) + if (output.contains("errors")) for (auto const& error: output["errors"]) { - string invalid = findAnyOf(error["type"].asString(), vector{ + string invalid = findAnyOf(error["type"].get(), vector{ "Exception", "InternalCompilerError" }); if (!invalid.empty()) { - string msg = "Invalid error: \"" + error["type"].asString() + "\""; + string msg = "Invalid error: \"" + error["type"].get() + "\""; cout << msg << endl; BOOST_THROW_EXCEPTION(std::runtime_error(std::move(msg))); } diff --git a/test/tools/ossfuzz/SolidityEvmoneInterface.cpp b/test/tools/ossfuzz/SolidityEvmoneInterface.cpp index 34147090882c..9d98190ddacf 100644 --- a/test/tools/ossfuzz/SolidityEvmoneInterface.cpp +++ b/test/tools/ossfuzz/SolidityEvmoneInterface.cpp @@ -57,7 +57,7 @@ optional SolidityCompilationFramework::compileContract() else contractName = m_compilerInput.contractName; evmasm::LinkerObject obj = m_compiler.object(contractName); - Json::Value methodIdentifiers = m_compiler.interfaceSymbols(contractName)["methods"]; + Json methodIdentifiers = m_compiler.interfaceSymbols(contractName)["methods"]; return CompilerOutput{obj.bytecode, methodIdentifiers}; } } @@ -164,10 +164,10 @@ evmc::Result EvmoneUtility::compileDeployAndExecute(string _fuzzIsabelle) // isabelle test entry point. At the moment, we are sure that the // entry point is the second method in the contract (hence the ++) // but not its name. - methodName = (++cOutput->methodIdentifiersInContract.begin())->asString() + + methodName = (++cOutput->methodIdentifiersInContract.begin())->get() + _fuzzIsabelle.substr(2, _fuzzIsabelle.size()); else - methodName = cOutput->methodIdentifiersInContract[m_methodName].asString(); + methodName = cOutput->methodIdentifiersInContract[m_methodName].get(); return deployAndExecute( cOutput->byteCode, diff --git a/test/tools/ossfuzz/SolidityEvmoneInterface.h b/test/tools/ossfuzz/SolidityEvmoneInterface.h index ea684ea72332..00582c681e62 100644 --- a/test/tools/ossfuzz/SolidityEvmoneInterface.h +++ b/test/tools/ossfuzz/SolidityEvmoneInterface.h @@ -35,7 +35,7 @@ struct CompilerOutput /// EVM bytecode returned by compiler solidity::bytes byteCode; /// Method identifiers in a contract - Json::Value methodIdentifiersInContract; + Json methodIdentifiersInContract; }; struct CompilerInput @@ -89,7 +89,7 @@ class SolidityCompilationFramework m_compilerInput.libraryAddresses = std::move(_libraryAddresses); } /// @returns method identifiers in contract called @param _contractName. - Json::Value methodIdentifiers(std::string const& _contractName) + Json methodIdentifiers(std::string const& _contractName) { return m_compiler.interfaceSymbols(_contractName)["methods"]; } diff --git a/test/yulPhaser/Program.cpp b/test/yulPhaser/Program.cpp index a54bf09af146..018de32ee2e7 100644 --- a/test/yulPhaser/Program.cpp +++ b/test/yulPhaser/Program.cpp @@ -380,7 +380,7 @@ BOOST_AUTO_TEST_CASE(toJson) CharStream sourceStream(sourceCode, current_test_case().p_name); Program program = get(Program::load(sourceStream)); - Json::Value parsingResult; + Json parsingResult; std::string errors; BOOST_TEST(jsonParseStrict(program.toJson(), parsingResult, &errors)); BOOST_TEST(errors.empty()); diff --git a/tools/yulPhaser/Program.cpp b/tools/yulPhaser/Program.cpp index 3089591ed8ba..f24f5e03f4bb 100644 --- a/tools/yulPhaser/Program.cpp +++ b/tools/yulPhaser/Program.cpp @@ -111,7 +111,7 @@ ostream& phaser::operator<<(ostream& _stream, Program const& _program) string Program::toJson() const { - Json::Value serializedAst = AsmJsonConverter(0)(*m_ast); + Json serializedAst = AsmJsonConverter(0)(*m_ast); return jsonPrettyPrint(removeNullMembers(std::move(serializedAst))); } From dd07096a98e48430143596ed0d6acab9f7282157 Mon Sep 17 00:00:00 2001 From: clonker Date: Thu, 2 May 2024 16:12:46 +0200 Subject: [PATCH 0190/1022] StaticAnalyzer: Only raise a compile time error for division and modulo by zero when it's between literals. --- Changelog.md | 1 + libsolidity/analysis/StaticAnalyzer.cpp | 3 ++- .../literalOperations/division_by_zero_complex_compound.sol | 5 +++++ .../literalOperations/division_by_zero_compound.sol | 5 +++++ .../literalOperations/division_by_zero_nonliteral.sol | 4 ++++ .../literalOperations/mod_zero_complex_compound.sol | 5 +++++ .../syntaxTests/literalOperations/mod_zero_compound.sol | 5 +++++ .../syntaxTests/literalOperations/mod_zero_nonliteral.sol | 4 ++++ 8 files changed, 31 insertions(+), 1 deletion(-) create mode 100644 test/libsolidity/syntaxTests/literalOperations/division_by_zero_complex_compound.sol create mode 100644 test/libsolidity/syntaxTests/literalOperations/division_by_zero_compound.sol create mode 100644 test/libsolidity/syntaxTests/literalOperations/division_by_zero_nonliteral.sol create mode 100644 test/libsolidity/syntaxTests/literalOperations/mod_zero_complex_compound.sol create mode 100644 test/libsolidity/syntaxTests/literalOperations/mod_zero_compound.sol create mode 100644 test/libsolidity/syntaxTests/literalOperations/mod_zero_nonliteral.sol diff --git a/Changelog.md b/Changelog.md index c118e9f248a4..16e42aff26d9 100644 --- a/Changelog.md +++ b/Changelog.md @@ -13,6 +13,7 @@ Bugfixes: * SMTChecker: Fix internal error when using an empty tuple in a conditional operator. * SMTChecker: Fix internal error when using bitwise operators with an array element as argument. * Standard JSON Interface: Fix ICE when the optimizer is disabled and an empty/blank string is used for ``optimizerSteps`` sequence. + * StaticAnalyzer: Only raise a compile time error for division and modulo by zero when it's between literals. * Yul Optimizer: Fix the order of assignments generated by ``SSATransform`` being dependent on AST IDs, sometimes resulting in different (but equivalent) bytecode when unrelated files were added to the compilation pipeline. diff --git a/libsolidity/analysis/StaticAnalyzer.cpp b/libsolidity/analysis/StaticAnalyzer.cpp index 10c2c922ca47..563295e23c00 100644 --- a/libsolidity/analysis/StaticAnalyzer.cpp +++ b/libsolidity/analysis/StaticAnalyzer.cpp @@ -298,7 +298,8 @@ bool StaticAnalyzer::visit(BinaryOperation const& _operation) { if ( *_operation.rightExpression().annotation().isPure && - (_operation.getOperator() == Token::Div || _operation.getOperator() == Token::Mod) + (_operation.getOperator() == Token::Div || _operation.getOperator() == Token::Mod) && + ConstantEvaluator::evaluate(m_errorReporter, _operation.leftExpression()) ) if (auto rhs = ConstantEvaluator::evaluate(m_errorReporter, _operation.rightExpression())) if (rhs->value == 0) diff --git a/test/libsolidity/syntaxTests/literalOperations/division_by_zero_complex_compound.sol b/test/libsolidity/syntaxTests/literalOperations/division_by_zero_complex_compound.sol new file mode 100644 index 000000000000..c3a51cc29760 --- /dev/null +++ b/test/libsolidity/syntaxTests/literalOperations/division_by_zero_complex_compound.sol @@ -0,0 +1,5 @@ +contract A { + uint a; + constructor() { a /= (((2)*2)%4); } +} +// ---- diff --git a/test/libsolidity/syntaxTests/literalOperations/division_by_zero_compound.sol b/test/libsolidity/syntaxTests/literalOperations/division_by_zero_compound.sol new file mode 100644 index 000000000000..9404f0ce9711 --- /dev/null +++ b/test/libsolidity/syntaxTests/literalOperations/division_by_zero_compound.sol @@ -0,0 +1,5 @@ +contract A { + uint a = 5; + constructor() { a /= uint(0); } +} +// ---- diff --git a/test/libsolidity/syntaxTests/literalOperations/division_by_zero_nonliteral.sol b/test/libsolidity/syntaxTests/literalOperations/division_by_zero_nonliteral.sol new file mode 100644 index 000000000000..66540568f357 --- /dev/null +++ b/test/libsolidity/syntaxTests/literalOperations/division_by_zero_nonliteral.sol @@ -0,0 +1,4 @@ +contract A { + constructor() { uint a; a / 0; } +} +// ---- diff --git a/test/libsolidity/syntaxTests/literalOperations/mod_zero_complex_compound.sol b/test/libsolidity/syntaxTests/literalOperations/mod_zero_complex_compound.sol new file mode 100644 index 000000000000..1e9f1e1fa731 --- /dev/null +++ b/test/libsolidity/syntaxTests/literalOperations/mod_zero_complex_compound.sol @@ -0,0 +1,5 @@ +contract A { + uint a = 5; + constructor() { a %= uint(((2)*2)%4); } +} +// ---- diff --git a/test/libsolidity/syntaxTests/literalOperations/mod_zero_compound.sol b/test/libsolidity/syntaxTests/literalOperations/mod_zero_compound.sol new file mode 100644 index 000000000000..2fb6e1df09af --- /dev/null +++ b/test/libsolidity/syntaxTests/literalOperations/mod_zero_compound.sol @@ -0,0 +1,5 @@ +contract A { + uint a; + constructor() { a = 5; a %= 0; } +} +// ---- diff --git a/test/libsolidity/syntaxTests/literalOperations/mod_zero_nonliteral.sol b/test/libsolidity/syntaxTests/literalOperations/mod_zero_nonliteral.sol new file mode 100644 index 000000000000..0722a096fc85 --- /dev/null +++ b/test/libsolidity/syntaxTests/literalOperations/mod_zero_nonliteral.sol @@ -0,0 +1,4 @@ +contract A { + constructor() { uint a; a % 0; } +} +// ---- From cb783989c78f67dca4208fa269544ab720846143 Mon Sep 17 00:00:00 2001 From: Alexander Arlt Date: Tue, 7 May 2024 16:37:00 +0200 Subject: [PATCH 0191/1022] Correct changelog. --- Changelog.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Changelog.md b/Changelog.md index 193f5bb46289..59284486b39c 100644 --- a/Changelog.md +++ b/Changelog.md @@ -17,6 +17,10 @@ Bugfixes: * Yul Optimizer: Fix the order of assignments generated by ``SSATransform`` being dependent on AST IDs, sometimes resulting in different (but equivalent) bytecode when unrelated files were added to the compilation pipeline. +Build System: +* Replace internal JSON library jsoncpp with nlohmann::json. + + ### 0.8.25 (2024-03-14) Compiler Features: @@ -33,9 +37,6 @@ Bugfixes: * SMTChecker: Fix internal error caused by not respecting the sign of an integer type when constructing zero-value SMT expressions. * SMTChecker: Run Eldarica only when explicitly requested with `--model-checker-solvers eld`, even when it is present on the system. -Build System: - * Replace internal JSON library jsoncpp with nlohmann::json. - ### 0.8.24 (2024-01-25) Language Features: From 6cc75270d996e1af22c9318a29cff64bed5b6191 Mon Sep 17 00:00:00 2001 From: Alexander Arlt Date: Tue, 7 May 2024 17:08:24 +0200 Subject: [PATCH 0192/1022] Mark embedding options as advanced. --- CMakeLists.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3e2332b9220b..91c1056ec3a4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -40,6 +40,9 @@ option(PROFILE_OPTIMIZER_STEPS "Output performance metrics for the optimiser ste option(USE_SYSTEM_LIBRARIES "Use system libraries" OFF) option(ONLY_BUILD_SOLIDITY_LIBRARIES "Only build solidity libraries" OFF) option(STRICT_NLOHMANN_JSON_VERSION "Strictly check installed nlohmann json version" ON) +mark_as_advanced(USE_SYSTEM_LIBRARIES) +mark_as_advanced(ONLY_BUILD_SOLIDITY_LIBRARIES) +mark_as_advanced(STRICT_NLOHMANN_JSON_VERSION) # Setup cccache. include(EthCcache) From 3485bc94cf1c8bd4152fee33b3161c0b5649a69b Mon Sep 17 00:00:00 2001 From: Alexander Arlt Date: Tue, 7 May 2024 14:58:41 +0200 Subject: [PATCH 0193/1022] Reformat tests in nlohmann::json style. --- libsolutil/JSON.cpp | 64 -- test/cmdlineTests/abi_via_ir/output | 36 +- test/cmdlineTests/asm_json/output | 15 +- .../ast_compact_json_with_base_path/output | 27 +- test/cmdlineTests/ast_ir/output | 345 +++---- test/cmdlineTests/combined_json_abi/output | 6 +- .../combined_json_generated_sources/output | 333 +++---- .../combined_json_stop_after_parsing/output | 21 +- .../combined_json_with_base_path/output | 48 +- .../combined_json_with_devdoc/output | 15 +- .../combined_json_with_userdoc/output | 15 +- test/cmdlineTests/events_in_abi/output | 9 +- test/cmdlineTests/function_debug_info/output | 36 +- .../function_debug_info_via_yul/output | 6 +- .../import_asm_json_all_valid_flags/output | 42 +- .../output | 105 +-- .../linking_standard_solidity/output.json | 21 +- .../output.json | 21 +- .../output.json | 30 +- .../linking_standard_yul/output.json | 15 +- .../output.json | 15 +- .../output.json | 24 +- .../no_contract_combined_json/output | 18 +- .../output_selection_all_A1/output.json | 36 +- .../output_selection_all_A2/output.json | 24 +- .../output_selection_all_blank/output.json | 9 +- .../output_selection_all_star/output.json | 54 +- .../output_selection_single_A1/output.json | 24 +- .../output_selection_single_B1/output.json | 24 +- .../output_selection_single_all/output.json | 33 +- .../pretty_json_indent_only/output.json | 6 +- .../pretty_json_standard/output.json | 6 +- .../pretty_json_standard_indent/output.json | 6 +- .../output.json | 30 +- .../output.json | 18 +- .../output.json | 18 +- .../output.json | 18 +- .../output.json | 3 +- .../output.json | 24 +- .../standard_default_success/output.json | 6 +- .../standard_empty_file_name/output.json | 6 +- .../output.json | 9 +- .../output.json | 6 +- .../standard_function_debug_info/output.json | 93 +- .../standard_generatedSources/output.json | 852 ++++++------------ .../standard_immutable_references/output.json | 27 +- .../standard_import_asm_json/output.json | 27 +- .../output.json | 24 +- .../output.json | 3 +- .../output.json | 3 +- .../output.json | 3 +- .../output.json | 3 +- .../output.json | 3 +- .../output.json | 3 +- .../output.json | 27 +- .../output.json | 3 +- .../standard_import_ast/output.json | 36 +- .../output.json | 21 +- .../standard_import_with_comments/output.json | 36 +- .../output.json | 36 +- .../output.json | 3 +- .../output.json | 198 ++-- .../output.json | 15 +- .../standard_ir_ast_requested/output.json | 246 ++--- .../standard_ir_requested/output.json | 15 +- .../standard_metadata/output.json | 15 +- .../output.json | 21 +- .../output.json | 18 +- .../output.json | 9 +- .../output.json | 9 +- .../output.json | 3 +- .../output.json | 15 +- .../output.json | 15 +- .../output.json | 3 +- .../output.json | 3 +- .../output.json | 3 +- .../output.json | 15 +- .../output.json | 21 +- .../output.json | 15 +- .../output.json | 9 +- .../output.json | 3 +- .../output.json | 3 +- .../output.json | 3 +- .../output.json | 9 +- .../output.json | 9 +- .../output.json | 9 +- .../output.json | 15 +- .../output.json | 9 +- .../output.json | 15 +- .../output.json | 3 +- .../output.json | 12 +- .../output.json | 15 +- .../output.json | 12 +- .../output.json | 6 +- .../output.json | 3 +- .../output.json | 12 +- .../output.json | 12 +- .../output.json | 3 +- .../output.json | 3 +- .../output.json | 9 +- .../output.json | 15 +- .../output.json | 12 +- .../output.json | 3 +- .../output.json | 3 +- .../output.json | 3 +- .../output.json | 15 +- .../output.json | 15 +- .../output.json | 15 +- .../output.json | 3 +- .../output.json | 3 +- .../output.json | 3 +- .../output.json | 12 +- .../output.json | 12 +- .../output.json | 12 +- .../output.json | 12 +- .../output.json | 12 +- .../output.json | 12 +- .../output.json | 18 +- .../output.json | 18 +- .../output.json | 18 +- .../output.json | 3 +- .../output.json | 9 +- .../output.json | 9 +- .../output.json | 9 +- .../output.json | 9 +- .../output.json | 18 +- .../output.json | 15 +- .../output.json | 12 +- .../output.json | 3 +- .../output.json | 9 +- .../output.json | 9 +- .../output.json | 9 +- .../output.json | 9 +- .../output.json | 9 +- .../output.json | 9 +- .../output.json | 12 +- .../output.json | 12 +- .../output.json | 12 +- .../output.json | 3 +- .../output.json | 9 +- .../output.json | 15 +- .../output.json | 12 +- .../output.json | 12 +- .../output.json | 15 +- .../output.json | 12 +- .../output.json | 15 +- .../output.json | 6 +- .../output.json | 15 +- .../output.json | 6 +- .../output.json | 33 +- .../output.json | 33 +- .../output.json | 21 +- .../output.json | 15 +- .../output.json | 12 +- .../output.json | 3 +- .../output.json | 6 +- .../output.json | 12 +- .../output.json | 15 +- .../output.json | 12 +- .../output.json | 6 +- .../output.json | 12 +- .../output.json | 15 +- .../output.json | 12 +- .../output.json | 27 +- .../output.json | 18 +- .../output.json | 21 +- .../output.json | 15 +- .../output.json | 3 +- .../output.json | 3 +- .../output.json | 3 +- .../output.json | 9 +- .../output.json | 9 +- .../output.json | 9 +- .../output.json | 3 +- .../output.json | 3 +- .../standard_no_append_cbor/output.json | 21 +- .../output.json | 3 +- .../standard_no_import_callback/output.json | 6 +- .../standard_non_utf8_filename/output.json | 3 +- .../standard_non_utf8_filename2/output.json | 3 +- .../standard_only_ast_requested/output.json | 36 +- .../output.json | 522 ++++------- .../output.json | 3 +- .../output.json | 3 +- .../standard_optimizer_no_yul/output.json | 6 +- .../standard_optimizer_yul/output.json | 6 +- .../standard_optimizer_yulDetails/output.json | 6 +- .../output.json | 3 +- .../output.json | 6 +- .../output.json | 15 +- .../output.json | 15 +- .../output.json | 3 +- .../output.json | 3 +- .../output.json | 3 +- .../output.json | 6 +- .../output.json | 3 +- .../output.json | 3 +- .../output.json | 3 +- .../output.json | 3 +- .../output.json | 3 +- .../output.json | 3 +- .../output.json | 3 +- .../output.json | 6 +- .../output.json | 6 +- .../output.json | 6 +- .../output.json | 6 +- .../output.json | 6 +- .../output.json | 6 +- .../output.json | 3 +- .../output.json | 6 +- .../output.json | 6 +- .../output.json | 6 +- .../output.json | 108 +-- .../output.json | 6 +- .../output.json | 27 +- .../standard_raw_utf16_filename/output.json | 3 +- .../output.json | 9 +- .../output.json | 15 +- .../output.json | 3 +- .../output.json | 6 +- .../output.json | 9 +- .../standard_urls_missing/output.json | 3 +- .../standard_viair_requested/output.json | 42 +- .../output.json | 3 +- .../standard_wrong_key_metadata/output.json | 3 +- .../standard_wrong_key_optimizer/output.json | 3 +- .../standard_wrong_key_root/output.json | 3 +- .../standard_wrong_key_settings/output.json | 3 +- .../standard_wrong_key_source/output.json | 3 +- .../output.json | 3 +- .../output.json | 3 +- .../output.json | 3 +- .../standard_wrong_type_metadata/output.json | 3 +- .../standard_wrong_type_optimizer/output.json | 3 +- .../output.json | 3 +- .../output.json | 3 +- .../output.json | 3 +- .../output.json | 3 +- .../output.json | 3 +- .../output.json | 3 +- .../standard_wrong_type_root/output.json | 3 +- .../standard_wrong_type_settings/output.json | 3 +- .../standard_wrong_type_source/output.json | 3 +- .../standard_wrong_type_sources/output.json | 3 +- .../output.json | 3 +- test/cmdlineTests/standard_yul/output.json | 60 +- .../output.json | 12 +- .../output.json | 12 +- .../output.json | 12 +- .../output.json | 3 +- .../output.json | 3 +- .../output.json | 24 +- .../standard_yul_multiple_files/output.json | 3 +- .../output.json | 3 +- .../standard_yul_object/output.json | 63 +- .../output.json | 6 +- .../standard_yul_object_name/output.json | 84 +- .../standard_yul_optimiserSteps/output.json | 60 +- .../standard_yul_optimized/output.json | 60 +- .../output.json | 3 +- .../standard_yul_stack_opt/output.json | 12 +- .../output.json | 12 +- .../stop_after_parsing_ast/output | 6 +- .../storage_layout_bytes/output.json | 27 +- .../storage_layout_dyn_array/output.json | 36 +- .../storage_layout_many/output.json | 60 +- .../storage_layout_mapping/output.json | 39 +- .../storage_layout_smoke/output.json | 18 +- .../output.json | 21 +- .../storage_layout_string/output.json | 27 +- .../storage_layout_struct/output.json | 42 +- .../storage_layout_struct_packed/output.json | 45 +- .../storage_layout_user_defined/output | 12 +- .../storage_layout_value_types/output.json | 33 +- .../output.json | 39 +- .../strict_asm_ast_compact_json/output | 21 +- .../yul_string_format_ascii/output.json | 15 +- .../output.json | 15 +- .../output.json | 15 +- .../yul_string_format_ascii_long/output.json | 15 +- .../yul_string_format_hex/output.json | 15 +- test/libsolidity/ABIJson/basic_test.sol | 6 +- test/libsolidity/ABIJson/constructor_abi.sol | 3 +- ...ty_name_input_parameter_with_named_one.sol | 6 +- .../ABIJson/empty_name_return_parameters.sol | 6 +- test/libsolidity/ABIJson/errors.sol | 15 +- .../libsolidity/ABIJson/errors_referenced.sol | 9 +- .../ABIJson/event_emited_in_base_contract.sol | 9 +- .../event_emitted_from_foreign_contract.sol | 18 +- test/libsolidity/ABIJson/event_file_level.sol | 9 +- test/libsolidity/ABIJson/event_structs.sol | 12 +- test/libsolidity/ABIJson/events.sol | 12 +- test/libsolidity/ABIJson/events_indirect.sol | 9 +- test/libsolidity/ABIJson/function_type.sol | 3 +- .../ABIJson/function_type_extended.sol | 3 +- test/libsolidity/ABIJson/global_struct.sol | 12 +- test/libsolidity/ABIJson/inherited.sol | 27 +- test/libsolidity/ABIJson/library_function.sol | 6 +- test/libsolidity/ABIJson/mapping.sol | 18 +- test/libsolidity/ABIJson/multiple_methods.sol | 12 +- .../ABIJson/multiple_methods_order.sol | 12 +- test/libsolidity/ABIJson/multiple_params.sol | 6 +- .../ABIJson/payable_constructor_abi.sol | 3 +- test/libsolidity/ABIJson/pure_function.sol | 12 +- .../ABIJson/return_param_in_abi.sol | 6 +- test/libsolidity/ABIJson/return_structs.sol | 9 +- .../ABIJson/return_structs_with_contracts.sol | 6 +- .../ABIJson/structs_and_arrays.sol | 3 +- .../ABIJson/structs_in_libraries.sol | 9 +- .../ABIJson/user_defined_value_type.sol | 30 +- test/libsolidity/ABIJson/view_function.sol | 12 +- .../ASTJSON/abstract_contract.json | 24 +- .../libsolidity/ASTJSON/abstract_contract.sol | 1 + .../ASTJSON/abstract_contract_parseOnly.json | 15 +- test/libsolidity/ASTJSON/address_payable.json | 210 ++--- test/libsolidity/ASTJSON/address_payable.sol | 1 + .../ASTJSON/address_payable_parseOnly.json | 111 +-- test/libsolidity/ASTJSON/array_type_name.json | 30 +- .../ASTJSON/array_type_name_parseOnly.json | 12 +- test/libsolidity/ASTJSON/assembly/call.json | 48 +- test/libsolidity/ASTJSON/assembly/call.sol | 1 + .../ASTJSON/assembly/call_parseOnly.json | 39 +- .../ASTJSON/assembly/empty_block.json | 33 +- .../ASTJSON/assembly/empty_block.sol | 1 + .../assembly/empty_block_parseOnly.json | 24 +- .../empty_let_variable_declaration.json | 36 +- .../empty_let_variable_declaration.sol | 1 + ...ty_let_variable_declaration_parseOnly.json | 27 +- .../ASTJSON/assembly/function.json | 60 +- .../libsolidity/ASTJSON/assembly/function.sol | 1 + .../ASTJSON/assembly/function_parseOnly.json | 51 +- test/libsolidity/ASTJSON/assembly/leave.json | 39 +- test/libsolidity/ASTJSON/assembly/leave.sol | 1 + .../ASTJSON/assembly/leave_parseOnly.json | 30 +- test/libsolidity/ASTJSON/assembly/loop.json | 66 +- test/libsolidity/ASTJSON/assembly/loop.sol | 1 + .../ASTJSON/assembly/loop_parseOnly.json | 57 +- .../ASTJSON/assembly/nested_functions.json | 63 +- .../ASTJSON/assembly/nested_functions.sol | 1 + .../assembly/nested_functions_parseOnly.json | 45 +- .../ASTJSON/assembly/slot_offset.json | 81 +- .../ASTJSON/assembly/slot_offset.sol | 1 + .../assembly/slot_offset_parseOnly.json | 57 +- .../ASTJSON/assembly/stringlit.json | 39 +- .../ASTJSON/assembly/stringlit.sol | 1 + .../ASTJSON/assembly/stringlit_parseOnly.json | 30 +- test/libsolidity/ASTJSON/assembly/switch.json | 75 +- test/libsolidity/ASTJSON/assembly/switch.sol | 1 + .../ASTJSON/assembly/switch_default.json | 48 +- .../ASTJSON/assembly/switch_default.sol | 1 + .../assembly/switch_default_parseOnly.json | 39 +- .../ASTJSON/assembly/switch_parseOnly.json | 66 +- .../ASTJSON/assembly/var_access.json | 57 +- .../ASTJSON/assembly/var_access.sol | 1 + .../assembly/var_access_parseOnly.json | 39 +- ...nternal_function_different_ids_export.json | 333 +++---- ...internal_function_different_ids_export.sol | 3 - .../ast_internal_function_id_export.json | 477 ++++------ .../ASTJSON/base_constructor_call.json | 78 +- .../base_constructor_call_parseOnly.json | 54 +- test/libsolidity/ASTJSON/constructor.json | 24 +- test/libsolidity/ASTJSON/constructor.sol | 1 + .../ASTJSON/constructor_parseOnly.json | 15 +- .../ASTJSON/contract_dep_order.json | 72 +- .../ASTJSON/contract_dep_order_parseOnly.json | 39 +- test/libsolidity/ASTJSON/documentation.json | 90 +- test/libsolidity/ASTJSON/documentation.sol | 4 +- .../ASTJSON/documentation_local_variable.json | 174 ++-- ...ocumentation_local_variable_parseOnly.json | 102 +-- .../ASTJSON/documentation_on_statements.json | 138 +-- ...documentation_on_statements_parseOnly.json | 78 +- .../ASTJSON/documentation_parseOnly.json | 51 +- .../ASTJSON/documentation_triple.json | 141 +-- .../documentation_triple_parseOnly.json | 78 +- test/libsolidity/ASTJSON/enum_natspec.json | 15 +- .../ASTJSON/enum_natspec_parseOnly.json | 9 +- test/libsolidity/ASTJSON/enum_value.json | 18 +- .../ASTJSON/enum_value_declaration.json | 57 +- .../enum_value_declaration_parseOnly.json | 36 +- .../ASTJSON/enum_value_parseOnly.json | 9 +- .../ASTJSON/event_aggregated_contract.json | 138 +-- .../libsolidity/ASTJSON/event_definition.json | 21 +- .../ASTJSON/event_definition_parseOnly.json | 9 +- .../event_emited_in_base_contract.json | 102 +-- .../event_emitted_from_foreign_contract.json | 102 +-- ...itted_from_foreign_contract_parseOnly.json | 51 +- .../ASTJSON/event_inheritance.json | 69 +- ...event_with_variables_of_internal_types.sol | 1 + ...variables_of_internal_types_parseOnly.json | 21 +- .../ASTJSON/fail_after_parsing.sol | 5 +- .../ASTJSON/fail_after_parsing_parseOnly.json | 87 +- test/libsolidity/ASTJSON/fallback.json | 24 +- test/libsolidity/ASTJSON/fallback.sol | 1 + .../ASTJSON/fallback_and_receive_ether.json | 33 +- .../ASTJSON/fallback_and_receive_ether.sol | 1 + .../fallback_and_receive_ether_parseOnly.json | 24 +- .../ASTJSON/fallback_parseOnly.json | 15 +- .../libsolidity/ASTJSON/fallback_payable.json | 24 +- test/libsolidity/ASTJSON/fallback_payable.sol | 1 + .../ASTJSON/fallback_payable_parseOnly.json | 15 +- test/libsolidity/ASTJSON/function_type.json | 84 +- .../ASTJSON/function_type_parseOnly.json | 51 +- test/libsolidity/ASTJSON/global_enum.json | 12 +- .../ASTJSON/global_enum_parseOnly.json | 6 +- test/libsolidity/ASTJSON/global_struct.json | 21 +- .../ASTJSON/global_struct_parseOnly.json | 9 +- test/libsolidity/ASTJSON/indirect_event.json | 102 +-- .../ASTJSON/indirect_event_parseOnly.json | 60 +- .../ASTJSON/inheritance_specifier.json | 27 +- .../inheritance_specifier_parseOnly.json | 12 +- test/libsolidity/ASTJSON/license.json | 12 +- .../ASTJSON/license_parseOnly.json | 3 +- .../long_type_name_binary_operation.json | 63 +- ..._type_name_binary_operation_parseOnly.json | 36 +- .../ASTJSON/long_type_name_identifier.json | 69 +- .../long_type_name_identifier_parseOnly.json | 39 +- test/libsolidity/ASTJSON/mappings.json | 114 +-- test/libsolidity/ASTJSON/mappings.sol | 1 + .../ASTJSON/mappings_parseOnly.json | 57 +- .../ASTJSON/modifier_definition.json | 60 +- .../modifier_definition_parseOnly.json | 42 +- .../ASTJSON/modifier_invocation.json | 60 +- .../modifier_invocation_parseOnly.json | 42 +- test/libsolidity/ASTJSON/mutability.json | 60 +- test/libsolidity/ASTJSON/mutability.sol | 1 + .../ASTJSON/mutability_parseOnly.json | 24 +- test/libsolidity/ASTJSON/non_utf8.json | 84 +- .../ASTJSON/non_utf8_parseOnly.json | 48 +- .../ASTJSON/not_existing_import.sol | 2 +- .../not_existing_import_parseOnly.json | 33 +- test/libsolidity/ASTJSON/override.json | 111 +-- test/libsolidity/ASTJSON/override.sol | 1 + .../ASTJSON/override_parseOnly.json | 81 +- .../ASTJSON/placeholder_statement.json | 24 +- .../placeholder_statement_parseOnly.json | 15 +- ...ragma_experimental_solidity_parseOnly.json | 6 +- test/libsolidity/ASTJSON/receive_ether.json | 24 +- test/libsolidity/ASTJSON/receive_ether.sol | 1 + .../ASTJSON/receive_ether_parseOnly.json | 15 +- test/libsolidity/ASTJSON/short_type_name.json | 48 +- .../ASTJSON/short_type_name_parseOnly.json | 30 +- .../ASTJSON/short_type_name_ref.json | 54 +- .../short_type_name_ref_parseOnly.json | 33 +- test/libsolidity/ASTJSON/smoke.json | 12 +- test/libsolidity/ASTJSON/smoke_parseOnly.json | 3 +- test/libsolidity/ASTJSON/source_location.json | 60 +- .../ASTJSON/source_location_parseOnly.json | 36 +- test/libsolidity/ASTJSON/string.json | 48 +- .../libsolidity/ASTJSON/string_parseOnly.json | 30 +- test/libsolidity/ASTJSON/struct_natspec.json | 42 +- .../ASTJSON/struct_natspec_parseOnly.json | 18 +- .../ASTJSON/two_base_functions.json | 90 +- .../ASTJSON/two_base_functions.sol | 1 + .../ASTJSON/two_base_functions_parseOnly.json | 66 +- test/libsolidity/ASTJSON/unicode.json | 48 +- .../ASTJSON/unicode_parseOnly.json | 30 +- test/libsolidity/ASTJSON/used_errors.json | 78 +- test/libsolidity/ASTJSON/used_errors.sol | 1 + .../ASTJSON/used_errors_parseOnly.json | 48 +- .../ASTJSON/userDefinedValueType.json | 135 +-- .../ASTJSON/userDefinedValueType.sol | 1 + .../userDefinedValueType_parseOnly.json | 81 +- .../ASTJSON/user_defined_operator.json | 252 ++---- .../ASTJSON/user_defined_operator.sol | 1 + .../ASTJSON/using_for_directive.json | 66 +- .../using_for_directive_parseOnly.json | 39 +- test/libsolidity/ASTJSON/yul_hex_literal.json | 51 +- test/libsolidity/ASTJSON/yul_hex_literal.sol | 1 + .../ASTJSON/yul_hex_literal_parseOnly.json | 42 +- test/libsolutil/JSON.cpp | 3 +- 470 files changed, 4707 insertions(+), 9427 deletions(-) diff --git a/libsolutil/JSON.cpp b/libsolutil/JSON.cpp index 63746c86531a..055024edb3d0 100644 --- a/libsolutil/JSON.cpp +++ b/libsolutil/JSON.cpp @@ -25,9 +25,7 @@ #include #include -#include -#include #include #ifdef STRICT_NLOHMANN_JSON_VERSION_CHECK @@ -65,64 +63,6 @@ void removeNullMembersHelper(Json& _json) } } -std::string trimRightAllLines(std::string const& input) -{ - std::vector lines; - std::string output; - boost::split(lines, input, boost::is_any_of("\n")); - for (auto& line: lines) - { - boost::trim_right(line); - if (!line.empty()) - output += line + "\n"; - } - return boost::trim_right_copy(output); -} - -std::string formatLikeJsoncpp(std::string const& _dumped, JsonFormat const& _format) -{ - uint32_t indentLevel = 0; - std::stringstream reformatted; - bool inQuotes = false; - for (size_t i = 0; i < _dumped.size(); ++i) - { - char c = _dumped[i]; - bool emptyThing = false; - - if (c == '"' && (i == 0 || _dumped[i - 1] != '\\')) - inQuotes = !inQuotes; - - if (!inQuotes) - { - if (i < _dumped.size() - 1) - { - char nc = _dumped[i + 1]; - if ((c == '[' && nc == ']') || (c == '{' && nc == '}')) - emptyThing = true; - } - if (c == '[' || c == '{') - { - if (i > 0 && _dumped[i - 1] != '\n') - if (!emptyThing) - reformatted << '\n' << std::string(indentLevel * _format.indent, ' '); - indentLevel++; - } - else if (c == ']' || c == '}') - { - indentLevel--; - if (i + 1 < _dumped.size() && _dumped[i + 1] != '\n' - && (_dumped[i + 1] == ']' || _dumped[i + 1] == '}')) - reformatted << '\n' << std::string(indentLevel * _format.indent, ' '); - } - } - reformatted << c; - if (!emptyThing && !inQuotes && (c == '[' || c == '{') && indentLevel > 0 && i + 1 < _dumped.size() - && _dumped[i + 1] != '\n') - reformatted << '\n' << std::string(indentLevel * _format.indent, ' '); - } - return trimRightAllLines(reformatted.str()); -} - std::string escapeNewlinesAndTabsWithinStringLiterals(std::string const& _json) { std::stringstream fixed; @@ -201,10 +141,6 @@ std::string jsonPrint(Json const& _input, JsonFormat const& _format) /* ensure_ascii */ true ); - // let's remove this once all test-cases having the correct output. - if (_format.format == JsonFormat::Pretty) - dumped = formatLikeJsoncpp(dumped, _format); - return dumped; } diff --git a/test/cmdlineTests/abi_via_ir/output b/test/cmdlineTests/abi_via_ir/output index daf18f3497a7..56ba01a4a248 100644 --- a/test/cmdlineTests/abi_via_ir/output +++ b/test/cmdlineTests/abi_via_ir/output @@ -3,8 +3,7 @@ Contract JSON ABI [ { - "inputs": - [ + "inputs": [ { "internalType": "uint256", "name": "z", @@ -20,8 +19,7 @@ Contract JSON ABI "type": "error" }, { - "inputs": - [ + "inputs": [ { "internalType": "uint256", "name": "z", @@ -32,8 +30,7 @@ Contract JSON ABI "type": "error" }, { - "inputs": - [ + "inputs": [ { "internalType": "uint256", "name": "r", @@ -45,8 +42,7 @@ Contract JSON ABI }, { "anonymous": true, - "inputs": - [ + "inputs": [ { "indexed": false, "internalType": "uint256", @@ -59,8 +55,7 @@ Contract JSON ABI }, { "anonymous": false, - "inputs": - [ + "inputs": [ { "indexed": false, "internalType": "uint256", @@ -73,8 +68,7 @@ Contract JSON ABI }, { "anonymous": false, - "inputs": - [ + "inputs": [ { "indexed": false, "internalType": "uint256", @@ -86,11 +80,9 @@ Contract JSON ABI "type": "event" }, { - "inputs": - [ + "inputs": [ { - "components": - [ + "components": [ { "internalType": "uint256", "name": "x", @@ -113,8 +105,7 @@ Contract JSON ABI Contract JSON ABI [ { - "inputs": - [ + "inputs": [ { "internalType": "uint256", "name": "r", @@ -125,8 +116,7 @@ Contract JSON ABI "type": "error" }, { - "inputs": - [ + "inputs": [ { "internalType": "uint256", "name": "u", @@ -138,8 +128,7 @@ Contract JSON ABI }, { "anonymous": false, - "inputs": - [ + "inputs": [ { "indexed": false, "internalType": "uint256", @@ -152,8 +141,7 @@ Contract JSON ABI }, { "anonymous": false, - "inputs": - [ + "inputs": [ { "indexed": false, "internalType": "uint256", diff --git a/test/cmdlineTests/asm_json/output b/test/cmdlineTests/asm_json/output index f6a0a4b19053..38d9c9fdf5fe 100644 --- a/test/cmdlineTests/asm_json/output +++ b/test/cmdlineTests/asm_json/output @@ -2,8 +2,7 @@ ======= asm_json/input.sol:C ======= EVM assembly: { - ".code": - [ + ".code": [ { "begin": 60, "end": 160, @@ -140,13 +139,10 @@ EVM assembly: "source": 0 } ], - ".data": - { - "0": - { + ".data": { + "0": { ".auxdata": "", - ".code": - [ + ".code": [ { "begin": 60, "end": 160, @@ -1570,8 +1566,7 @@ EVM assembly: ] } }, - "sourceList": - [ + "sourceList": [ "asm_json/input.sol", "#utility.yul" ] diff --git a/test/cmdlineTests/ast_compact_json_with_base_path/output b/test/cmdlineTests/ast_compact_json_with_base_path/output index 5c5c6ffd5123..c61502020765 100644 --- a/test/cmdlineTests/ast_compact_json_with_base_path/output +++ b/test/cmdlineTests/ast_compact_json_with_base_path/output @@ -4,22 +4,18 @@ JSON AST (compact format): ======= ast_compact_json_with_base_path/c.sol ======= { "absolutePath": "ast_compact_json_with_base_path/c.sol", - "exportedSymbols": - { - "C": - [ + "exportedSymbols": { + "C": [ 5 ] }, "id": 6, "license": "GPL-3.0", "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "id": 4, - "literals": - [ + "literals": [ "solidity", ">=", "0.0" @@ -35,8 +31,7 @@ JSON AST (compact format): "contractKind": "contract", "fullyImplemented": true, "id": 5, - "linearizedBaseContracts": - [ + "linearizedBaseContracts": [ 5 ], "name": "C", @@ -54,22 +49,18 @@ JSON AST (compact format): ======= ast_compact_json_with_base_path/input.sol ======= { "absolutePath": "ast_compact_json_with_base_path/input.sol", - "exportedSymbols": - { - "C": - [ + "exportedSymbols": { + "C": [ 5 ] }, "id": 3, "license": "GPL-3.0", "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "id": 1, - "literals": - [ + "literals": [ "solidity", ">=", "0.0" diff --git a/test/cmdlineTests/ast_ir/output b/test/cmdlineTests/ast_ir/output index cca31349e868..c68c77872969 100644 --- a/test/cmdlineTests/ast_ir/output +++ b/test/cmdlineTests/ast_ir/output @@ -1,19 +1,14 @@ IR AST: { - "code": - { - "block": - { + "code": { + "block": { "nativeSrc": "59:790:0", "nodeType": "YulBlock", "src": "-1:-1:0", - "statements": - [ + "statements": [ { - "expression": - { - "arguments": - [ + "expression": { + "arguments": [ { "kind": "number", "nativeSrc": "118:2:0", @@ -23,8 +18,7 @@ IR AST: "value": "64" }, { - "arguments": - [ + "arguments": [ { "kind": "number", "nativeSrc": "134:3:0", @@ -34,8 +28,7 @@ IR AST: "value": "128" } ], - "functionName": - { + "functionName": { "name": "memoryguard", "nativeSrc": "122:11:0", "nodeType": "YulIdentifier", @@ -46,8 +39,7 @@ IR AST: "src": "60:13:0" } ], - "functionName": - { + "functionName": { "name": "mstore", "nativeSrc": "111:6:0", "nodeType": "YulIdentifier", @@ -62,19 +54,15 @@ IR AST: "src": "60:13:0" }, { - "body": - { + "body": { "nativeSrc": "163:83:0", "nodeType": "YulBlock", "src": "60:13:0", - "statements": - [ + "statements": [ { - "expression": - { + "expression": { "arguments": [], - "functionName": - { + "functionName": { "name": "revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb", "nativeSrc": "165:77:0", "nodeType": "YulIdentifier", @@ -90,11 +78,9 @@ IR AST: } ] }, - "condition": - { + "condition": { "arguments": [], - "functionName": - { + "functionName": { "name": "callvalue", "nativeSrc": "151:9:0", "nodeType": "YulIdentifier", @@ -109,11 +95,9 @@ IR AST: "src": "60:13:0" }, { - "expression": - { + "expression": { "arguments": [], - "functionName": - { + "functionName": { "name": "constructor_C_2", "nativeSrc": "256:15:0", "nodeType": "YulIdentifier", @@ -131,11 +115,9 @@ IR AST: "nativeSrc": "283:30:0", "nodeType": "YulVariableDeclaration", "src": "60:13:0", - "value": - { + "value": { "arguments": [], - "functionName": - { + "functionName": { "name": "allocate_unbounded", "nativeSrc": "293:18:0", "nodeType": "YulIdentifier", @@ -145,8 +127,7 @@ IR AST: "nodeType": "YulFunctionCall", "src": "60:13:0" }, - "variables": - [ + "variables": [ { "name": "_1", "nativeSrc": "287:2:0", @@ -157,10 +138,8 @@ IR AST: ] }, { - "expression": - { - "arguments": - [ + "expression": { + "arguments": [ { "name": "_1", "nativeSrc": "331:2:0", @@ -168,8 +147,7 @@ IR AST: "src": "60:13:0" }, { - "arguments": - [ + "arguments": [ { "hexValue": "435f325f6465706c6f796564", "kind": "string", @@ -180,8 +158,7 @@ IR AST: "value": "C_2_deployed" } ], - "functionName": - { + "functionName": { "name": "dataoffset", "nativeSrc": "335:10:0", "nodeType": "YulIdentifier", @@ -192,8 +169,7 @@ IR AST: "src": "60:13:0" }, { - "arguments": - [ + "arguments": [ { "hexValue": "435f325f6465706c6f796564", "kind": "string", @@ -204,8 +180,7 @@ IR AST: "value": "C_2_deployed" } ], - "functionName": - { + "functionName": { "name": "datasize", "nativeSrc": "363:8:0", "nodeType": "YulIdentifier", @@ -216,8 +191,7 @@ IR AST: "src": "60:13:0" } ], - "functionName": - { + "functionName": { "name": "codecopy", "nativeSrc": "322:8:0", "nodeType": "YulIdentifier", @@ -232,10 +206,8 @@ IR AST: "src": "60:13:0" }, { - "expression": - { - "arguments": - [ + "expression": { + "arguments": [ { "name": "_1", "nativeSrc": "405:2:0", @@ -243,8 +215,7 @@ IR AST: "src": "60:13:0" }, { - "arguments": - [ + "arguments": [ { "hexValue": "435f325f6465706c6f796564", "kind": "string", @@ -255,8 +226,7 @@ IR AST: "value": "C_2_deployed" } ], - "functionName": - { + "functionName": { "name": "datasize", "nativeSrc": "409:8:0", "nodeType": "YulIdentifier", @@ -267,8 +237,7 @@ IR AST: "src": "60:13:0" } ], - "functionName": - { + "functionName": { "name": "return", "nativeSrc": "398:6:0", "nodeType": "YulIdentifier", @@ -283,21 +252,17 @@ IR AST: "src": "60:13:0" }, { - "body": - { + "body": { "nativeSrc": "484:43:0", "nodeType": "YulBlock", "src": "60:13:0", - "statements": - [ + "statements": [ { "nativeSrc": "498:19:0", "nodeType": "YulAssignment", "src": "60:13:0", - "value": - { - "arguments": - [ + "value": { + "arguments": [ { "kind": "number", "nativeSrc": "514:2:0", @@ -307,8 +272,7 @@ IR AST: "value": "64" } ], - "functionName": - { + "functionName": { "name": "mload", "nativeSrc": "508:5:0", "nodeType": "YulIdentifier", @@ -318,8 +282,7 @@ IR AST: "nodeType": "YulFunctionCall", "src": "60:13:0" }, - "variableNames": - [ + "variableNames": [ { "name": "memPtr", "nativeSrc": "498:6:0", @@ -333,8 +296,7 @@ IR AST: "name": "allocate_unbounded", "nativeSrc": "444:83:0", "nodeType": "YulFunctionDefinition", - "returnVariables": - [ + "returnVariables": [ { "name": "memPtr", "nativeSrc": "477:6:0", @@ -346,18 +308,14 @@ IR AST: "src": "60:13:0" }, { - "body": - { + "body": { "nativeSrc": "626:36:0", "nodeType": "YulBlock", "src": "60:13:0", - "statements": - [ + "statements": [ { - "expression": - { - "arguments": - [ + "expression": { + "arguments": [ { "kind": "number", "nativeSrc": "647:1:0", @@ -375,8 +333,7 @@ IR AST: "value": "0" } ], - "functionName": - { + "functionName": { "name": "revert", "nativeSrc": "640:6:0", "nodeType": "YulIdentifier", @@ -398,8 +355,7 @@ IR AST: "src": "60:13:0" }, { - "body": - { + "body": { "nativeSrc": "741:59:0", "nodeType": "YulBlock", "src": "60:13:0", @@ -416,23 +372,17 @@ IR AST: }, "name": "C_2", "nodeType": "YulObject", - "subObjects": - [ + "subObjects": [ { - "code": - { - "block": - { + "code": { + "block": { "nativeSrc": "929:588:0", "nodeType": "YulBlock", "src": "-1:-1:0", - "statements": - [ + "statements": [ { - "expression": - { - "arguments": - [ + "expression": { + "arguments": [ { "kind": "number", "nativeSrc": "996:2:0", @@ -442,8 +392,7 @@ IR AST: "value": "64" }, { - "arguments": - [ + "arguments": [ { "kind": "number", "nativeSrc": "1012:3:0", @@ -453,8 +402,7 @@ IR AST: "value": "128" } ], - "functionName": - { + "functionName": { "name": "memoryguard", "nativeSrc": "1000:11:0", "nodeType": "YulIdentifier", @@ -465,8 +413,7 @@ IR AST: "src": "60:13:0" } ], - "functionName": - { + "functionName": { "name": "mstore", "nativeSrc": "989:6:0", "nodeType": "YulIdentifier", @@ -481,11 +428,9 @@ IR AST: "src": "60:13:0" }, { - "expression": - { + "expression": { "arguments": [], - "functionName": - { + "functionName": { "name": "revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74", "nativeSrc": "1031:77:0", "nodeType": "YulIdentifier", @@ -500,21 +445,17 @@ IR AST: "src": "60:13:0" }, { - "body": - { + "body": { "nativeSrc": "1177:77:0", "nodeType": "YulBlock", "src": "60:13:0", - "statements": - [ + "statements": [ { "nativeSrc": "1195:44:0", "nodeType": "YulAssignment", "src": "60:13:0", - "value": - { - "arguments": - [ + "value": { + "arguments": [ { "kind": "number", "nativeSrc": "1228:3:0", @@ -530,8 +471,7 @@ IR AST: "src": "60:13:0" } ], - "functionName": - { + "functionName": { "name": "shr", "nativeSrc": "1224:3:0", "nodeType": "YulIdentifier", @@ -541,8 +481,7 @@ IR AST: "nodeType": "YulFunctionCall", "src": "60:13:0" }, - "variableNames": - [ + "variableNames": [ { "name": "newValue", "nativeSrc": "1195:8:0", @@ -556,8 +495,7 @@ IR AST: "name": "shift_right_224_unsigned", "nativeSrc": "1124:130:0", "nodeType": "YulFunctionDefinition", - "parameters": - [ + "parameters": [ { "name": "value", "nativeSrc": "1158:5:0", @@ -566,8 +504,7 @@ IR AST: "type": "" } ], - "returnVariables": - [ + "returnVariables": [ { "name": "newValue", "nativeSrc": "1168:8:0", @@ -579,21 +516,17 @@ IR AST: "src": "60:13:0" }, { - "body": - { + "body": { "nativeSrc": "1308:51:0", "nodeType": "YulBlock", "src": "60:13:0", - "statements": - [ + "statements": [ { "nativeSrc": "1326:19:0", "nodeType": "YulAssignment", "src": "60:13:0", - "value": - { - "arguments": - [ + "value": { + "arguments": [ { "kind": "number", "nativeSrc": "1342:2:0", @@ -603,8 +536,7 @@ IR AST: "value": "64" } ], - "functionName": - { + "functionName": { "name": "mload", "nativeSrc": "1336:5:0", "nodeType": "YulIdentifier", @@ -614,8 +546,7 @@ IR AST: "nodeType": "YulFunctionCall", "src": "60:13:0" }, - "variableNames": - [ + "variableNames": [ { "name": "memPtr", "nativeSrc": "1326:6:0", @@ -629,8 +560,7 @@ IR AST: "name": "allocate_unbounded", "nativeSrc": "1268:91:0", "nodeType": "YulFunctionDefinition", - "returnVariables": - [ + "returnVariables": [ { "name": "memPtr", "nativeSrc": "1301:6:0", @@ -642,18 +572,14 @@ IR AST: "src": "60:13:0" }, { - "body": - { + "body": { "nativeSrc": "1462:44:0", "nodeType": "YulBlock", "src": "60:13:0", - "statements": - [ + "statements": [ { - "expression": - { - "arguments": - [ + "expression": { + "arguments": [ { "kind": "number", "nativeSrc": "1487:1:0", @@ -671,8 +597,7 @@ IR AST: "value": "0" } ], - "functionName": - { + "functionName": { "name": "revert", "nativeSrc": "1480:6:0", "nodeType": "YulIdentifier", @@ -699,8 +624,7 @@ IR AST: }, "name": "C_2_deployed", "nodeType": "YulObject", - "subObjects": - [ + "subObjects": [ { "nodeType": "YulData", "value": "" @@ -711,29 +635,23 @@ IR AST: } Optimized IR AST: { - "code": - { - "block": - { + "code": { + "block": { "nativeSrc": "59:790:0", "nodeType": "YulBlock", "src": "-1:-1:0", - "statements": - [ + "statements": [ { "nativeSrc": "59:790:0", "nodeType": "YulBlock", "src": "-1:-1:0", - "statements": - [ + "statements": [ { "nativeSrc": "122:16:0", "nodeType": "YulVariableDeclaration", "src": "60:13:0", - "value": - { - "arguments": - [ + "value": { + "arguments": [ { "kind": "number", "nativeSrc": "134:3:0", @@ -743,8 +661,7 @@ Optimized IR AST: "value": "0x80" } ], - "functionName": - { + "functionName": { "name": "memoryguard", "nativeSrc": "122:11:0", "nodeType": "YulIdentifier", @@ -754,8 +671,7 @@ Optimized IR AST: "nodeType": "YulFunctionCall", "src": "60:13:0" }, - "variables": - [ + "variables": [ { "name": "_1", "nativeSrc": "122:16:0", @@ -766,10 +682,8 @@ Optimized IR AST: ] }, { - "expression": - { - "arguments": - [ + "expression": { + "arguments": [ { "kind": "number", "nativeSrc": "118:2:0", @@ -785,8 +699,7 @@ Optimized IR AST: "src": "60:13:0" } ], - "functionName": - { + "functionName": { "name": "mstore", "nativeSrc": "111:6:0", "nodeType": "YulIdentifier", @@ -801,18 +714,14 @@ Optimized IR AST: "src": "60:13:0" }, { - "body": - { + "body": { "nativeSrc": "163:83:0", "nodeType": "YulBlock", "src": "60:13:0", - "statements": - [ + "statements": [ { - "expression": - { - "arguments": - [ + "expression": { + "arguments": [ { "kind": "number", "nativeSrc": "650:1:0", @@ -830,8 +739,7 @@ Optimized IR AST: "value": "0" } ], - "functionName": - { + "functionName": { "name": "revert", "nativeSrc": "640:6:0", "nodeType": "YulIdentifier", @@ -847,11 +755,9 @@ Optimized IR AST: } ] }, - "condition": - { + "condition": { "arguments": [], - "functionName": - { + "functionName": { "name": "callvalue", "nativeSrc": "151:9:0", "nodeType": "YulIdentifier", @@ -869,10 +775,8 @@ Optimized IR AST: "nativeSrc": "363:24:0", "nodeType": "YulVariableDeclaration", "src": "60:13:0", - "value": - { - "arguments": - [ + "value": { + "arguments": [ { "hexValue": "435f325f6465706c6f796564", "kind": "string", @@ -883,8 +787,7 @@ Optimized IR AST: "value": "C_2_deployed" } ], - "functionName": - { + "functionName": { "name": "datasize", "nativeSrc": "363:8:0", "nodeType": "YulIdentifier", @@ -894,8 +797,7 @@ Optimized IR AST: "nodeType": "YulFunctionCall", "src": "60:13:0" }, - "variables": - [ + "variables": [ { "name": "_2", "nativeSrc": "363:24:0", @@ -906,10 +808,8 @@ Optimized IR AST: ] }, { - "expression": - { - "arguments": - [ + "expression": { + "arguments": [ { "name": "_1", "nativeSrc": "331:2:0", @@ -917,8 +817,7 @@ Optimized IR AST: "src": "60:13:0" }, { - "arguments": - [ + "arguments": [ { "hexValue": "435f325f6465706c6f796564", "kind": "string", @@ -929,8 +828,7 @@ Optimized IR AST: "value": "C_2_deployed" } ], - "functionName": - { + "functionName": { "name": "dataoffset", "nativeSrc": "335:10:0", "nodeType": "YulIdentifier", @@ -947,8 +845,7 @@ Optimized IR AST: "src": "60:13:0" } ], - "functionName": - { + "functionName": { "name": "codecopy", "nativeSrc": "322:8:0", "nodeType": "YulIdentifier", @@ -963,10 +860,8 @@ Optimized IR AST: "src": "60:13:0" }, { - "expression": - { - "arguments": - [ + "expression": { + "arguments": [ { "name": "_1", "nativeSrc": "405:2:0", @@ -980,8 +875,7 @@ Optimized IR AST: "src": "60:13:0" } ], - "functionName": - { + "functionName": { "name": "return", "nativeSrc": "398:6:0", "nodeType": "YulIdentifier", @@ -1003,29 +897,22 @@ Optimized IR AST: }, "name": "C_2", "nodeType": "YulObject", - "subObjects": - [ + "subObjects": [ { - "code": - { - "block": - { + "code": { + "block": { "nativeSrc": "929:588:0", "nodeType": "YulBlock", "src": "-1:-1:0", - "statements": - [ + "statements": [ { "nativeSrc": "929:588:0", "nodeType": "YulBlock", "src": "-1:-1:0", - "statements": - [ + "statements": [ { - "expression": - { - "arguments": - [ + "expression": { + "arguments": [ { "kind": "number", "nativeSrc": "1490:1:0", @@ -1043,8 +930,7 @@ Optimized IR AST: "value": "0" } ], - "functionName": - { + "functionName": { "name": "revert", "nativeSrc": "1480:6:0", "nodeType": "YulIdentifier", @@ -1066,8 +952,7 @@ Optimized IR AST: }, "name": "C_2_deployed", "nodeType": "YulObject", - "subObjects": - [ + "subObjects": [ { "nodeType": "YulData", "value": "" diff --git a/test/cmdlineTests/combined_json_abi/output b/test/cmdlineTests/combined_json_abi/output index c775c6d72ca1..79b539db78d0 100644 --- a/test/cmdlineTests/combined_json_abi/output +++ b/test/cmdlineTests/combined_json_abi/output @@ -1,8 +1,6 @@ { - "contracts": - { - "combined_json_abi/input.sol:C": - { + "contracts": { + "combined_json_abi/input.sol:C": { "abi": [] } }, diff --git a/test/cmdlineTests/combined_json_generated_sources/output b/test/cmdlineTests/combined_json_generated_sources/output index 5ef9078d6e80..db7c86ce13d7 100644 --- a/test/cmdlineTests/combined_json_generated_sources/output +++ b/test/cmdlineTests/combined_json_generated_sources/output @@ -1,35 +1,26 @@ { - "contracts": - { - "combined_json_generated_sources/input.sol:C": - { + "contracts": { + "combined_json_generated_sources/input.sol:C": { "generated-sources": [], - "generated-sources-runtime": - [ + "generated-sources-runtime": [ { - "ast": - { + "ast": { "nativeSrc": "0:1856:1", "nodeType": "YulBlock", "src": "0:1856:1", - "statements": - [ + "statements": [ { - "body": - { + "body": { "nativeSrc": "47:35:1", "nodeType": "YulBlock", "src": "47:35:1", - "statements": - [ + "statements": [ { "nativeSrc": "57:19:1", "nodeType": "YulAssignment", "src": "57:19:1", - "value": - { - "arguments": - [ + "value": { + "arguments": [ { "kind": "number", "nativeSrc": "73:2:1", @@ -39,8 +30,7 @@ "value": "64" } ], - "functionName": - { + "functionName": { "name": "mload", "nativeSrc": "67:5:1", "nodeType": "YulIdentifier", @@ -50,8 +40,7 @@ "nodeType": "YulFunctionCall", "src": "67:9:1" }, - "variableNames": - [ + "variableNames": [ { "name": "memPtr", "nativeSrc": "57:6:1", @@ -65,8 +54,7 @@ "name": "allocate_unbounded", "nativeSrc": "7:75:1", "nodeType": "YulFunctionDefinition", - "returnVariables": - [ + "returnVariables": [ { "name": "memPtr", "nativeSrc": "40:6:1", @@ -78,18 +66,14 @@ "src": "7:75:1" }, { - "body": - { + "body": { "nativeSrc": "177:28:1", "nodeType": "YulBlock", "src": "177:28:1", - "statements": - [ + "statements": [ { - "expression": - { - "arguments": - [ + "expression": { + "arguments": [ { "kind": "number", "nativeSrc": "194:1:1", @@ -107,8 +91,7 @@ "value": "0" } ], - "functionName": - { + "functionName": { "name": "revert", "nativeSrc": "187:6:1", "nodeType": "YulIdentifier", @@ -130,18 +113,14 @@ "src": "88:117:1" }, { - "body": - { + "body": { "nativeSrc": "300:28:1", "nodeType": "YulBlock", "src": "300:28:1", - "statements": - [ + "statements": [ { - "expression": - { - "arguments": - [ + "expression": { + "arguments": [ { "kind": "number", "nativeSrc": "317:1:1", @@ -159,8 +138,7 @@ "value": "0" } ], - "functionName": - { + "functionName": { "name": "revert", "nativeSrc": "310:6:1", "nodeType": "YulIdentifier", @@ -182,18 +160,14 @@ "src": "211:117:1" }, { - "body": - { + "body": { "nativeSrc": "423:28:1", "nodeType": "YulBlock", "src": "423:28:1", - "statements": - [ + "statements": [ { - "expression": - { - "arguments": - [ + "expression": { + "arguments": [ { "kind": "number", "nativeSrc": "440:1:1", @@ -211,8 +185,7 @@ "value": "0" } ], - "functionName": - { + "functionName": { "name": "revert", "nativeSrc": "433:6:1", "nodeType": "YulIdentifier", @@ -234,18 +207,14 @@ "src": "334:117:1" }, { - "body": - { + "body": { "nativeSrc": "546:28:1", "nodeType": "YulBlock", "src": "546:28:1", - "statements": - [ + "statements": [ { - "expression": - { - "arguments": - [ + "expression": { + "arguments": [ { "kind": "number", "nativeSrc": "563:1:1", @@ -263,8 +232,7 @@ "value": "0" } ], - "functionName": - { + "functionName": { "name": "revert", "nativeSrc": "556:6:1", "nodeType": "YulIdentifier", @@ -286,18 +254,14 @@ "src": "457:117:1" }, { - "body": - { + "body": { "nativeSrc": "669:28:1", "nodeType": "YulBlock", "src": "669:28:1", - "statements": - [ + "statements": [ { - "expression": - { - "arguments": - [ + "expression": { + "arguments": [ { "kind": "number", "nativeSrc": "686:1:1", @@ -315,8 +279,7 @@ "value": "0" } ], - "functionName": - { + "functionName": { "name": "revert", "nativeSrc": "679:6:1", "nodeType": "YulIdentifier", @@ -338,27 +301,21 @@ "src": "580:117:1" }, { - "body": - { + "body": { "nativeSrc": "810:478:1", "nodeType": "YulBlock", "src": "810:478:1", - "statements": - [ + "statements": [ { - "body": - { + "body": { "nativeSrc": "859:83:1", "nodeType": "YulBlock", "src": "859:83:1", - "statements": - [ + "statements": [ { - "expression": - { + "expression": { "arguments": [], - "functionName": - { + "functionName": { "name": "revert_error_1b9f4a0a5773e33b91aa01db23bf8c55fce1411167c872835e7fa00a4f17d46d", "nativeSrc": "861:77:1", "nodeType": "YulIdentifier", @@ -374,16 +331,12 @@ } ] }, - "condition": - { - "arguments": - [ + "condition": { + "arguments": [ { - "arguments": - [ + "arguments": [ { - "arguments": - [ + "arguments": [ { "name": "offset", "nativeSrc": "838:6:1", @@ -399,8 +352,7 @@ "value": "0x1f" } ], - "functionName": - { + "functionName": { "name": "add", "nativeSrc": "834:3:1", "nodeType": "YulIdentifier", @@ -417,8 +369,7 @@ "src": "853:3:1" } ], - "functionName": - { + "functionName": { "name": "slt", "nativeSrc": "830:3:1", "nodeType": "YulIdentifier", @@ -429,8 +380,7 @@ "src": "830:27:1" } ], - "functionName": - { + "functionName": { "name": "iszero", "nativeSrc": "823:6:1", "nodeType": "YulIdentifier", @@ -448,10 +398,8 @@ "nativeSrc": "951:30:1", "nodeType": "YulAssignment", "src": "951:30:1", - "value": - { - "arguments": - [ + "value": { + "arguments": [ { "name": "offset", "nativeSrc": "974:6:1", @@ -459,8 +407,7 @@ "src": "974:6:1" } ], - "functionName": - { + "functionName": { "name": "calldataload", "nativeSrc": "961:12:1", "nodeType": "YulIdentifier", @@ -470,8 +417,7 @@ "nodeType": "YulFunctionCall", "src": "961:20:1" }, - "variableNames": - [ + "variableNames": [ { "name": "length", "nativeSrc": "951:6:1", @@ -481,19 +427,15 @@ ] }, { - "body": - { + "body": { "nativeSrc": "1024:83:1", "nodeType": "YulBlock", "src": "1024:83:1", - "statements": - [ + "statements": [ { - "expression": - { + "expression": { "arguments": [], - "functionName": - { + "functionName": { "name": "revert_error_15abf5612cd996bc235ba1e55a4a30ac60e6bb601ff7ba4ad3f179b6be8d0490", "nativeSrc": "1026:77:1", "nodeType": "YulIdentifier", @@ -509,10 +451,8 @@ } ] }, - "condition": - { - "arguments": - [ + "condition": { + "arguments": [ { "name": "length", "nativeSrc": "996:6:1", @@ -528,8 +468,7 @@ "value": "0xffffffffffffffff" } ], - "functionName": - { + "functionName": { "name": "gt", "nativeSrc": "993:2:1", "nodeType": "YulIdentifier", @@ -547,10 +486,8 @@ "nativeSrc": "1116:29:1", "nodeType": "YulAssignment", "src": "1116:29:1", - "value": - { - "arguments": - [ + "value": { + "arguments": [ { "name": "offset", "nativeSrc": "1132:6:1", @@ -566,8 +503,7 @@ "value": "0x20" } ], - "functionName": - { + "functionName": { "name": "add", "nativeSrc": "1128:3:1", "nodeType": "YulIdentifier", @@ -577,8 +513,7 @@ "nodeType": "YulFunctionCall", "src": "1128:17:1" }, - "variableNames": - [ + "variableNames": [ { "name": "arrayPos", "nativeSrc": "1116:8:1", @@ -588,19 +523,15 @@ ] }, { - "body": - { + "body": { "nativeSrc": "1199:83:1", "nodeType": "YulBlock", "src": "1199:83:1", - "statements": - [ + "statements": [ { - "expression": - { + "expression": { "arguments": [], - "functionName": - { + "functionName": { "name": "revert_error_81385d8c0b31fffe14be1da910c8bd3a80be4cfa248e04f42ec0faea3132a8ef", "nativeSrc": "1201:77:1", "nodeType": "YulIdentifier", @@ -616,13 +547,10 @@ } ] }, - "condition": - { - "arguments": - [ + "condition": { + "arguments": [ { - "arguments": - [ + "arguments": [ { "name": "arrayPos", "nativeSrc": "1164:8:1", @@ -630,8 +558,7 @@ "src": "1164:8:1" }, { - "arguments": - [ + "arguments": [ { "name": "length", "nativeSrc": "1178:6:1", @@ -647,8 +574,7 @@ "value": "0x20" } ], - "functionName": - { + "functionName": { "name": "mul", "nativeSrc": "1174:3:1", "nodeType": "YulIdentifier", @@ -659,8 +585,7 @@ "src": "1174:17:1" } ], - "functionName": - { + "functionName": { "name": "add", "nativeSrc": "1160:3:1", "nodeType": "YulIdentifier", @@ -677,8 +602,7 @@ "src": "1194:3:1" } ], - "functionName": - { + "functionName": { "name": "gt", "nativeSrc": "1157:2:1", "nodeType": "YulIdentifier", @@ -697,8 +621,7 @@ "name": "abi_decode_t_array$_t_uint256_$dyn_calldata_ptr", "nativeSrc": "720:568:1", "nodeType": "YulFunctionDefinition", - "parameters": - [ + "parameters": [ { "name": "offset", "nativeSrc": "777:6:1", @@ -714,8 +637,7 @@ "type": "" } ], - "returnVariables": - [ + "returnVariables": [ { "name": "arrayPos", "nativeSrc": "793:8:1", @@ -734,27 +656,21 @@ "src": "720:568:1" }, { - "body": - { + "body": { "nativeSrc": "1395:458:1", "nodeType": "YulBlock", "src": "1395:458:1", - "statements": - [ + "statements": [ { - "body": - { + "body": { "nativeSrc": "1441:83:1", "nodeType": "YulBlock", "src": "1441:83:1", - "statements": - [ + "statements": [ { - "expression": - { + "expression": { "arguments": [], - "functionName": - { + "functionName": { "name": "revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b", "nativeSrc": "1443:77:1", "nodeType": "YulIdentifier", @@ -770,13 +686,10 @@ } ] }, - "condition": - { - "arguments": - [ + "condition": { + "arguments": [ { - "arguments": - [ + "arguments": [ { "name": "dataEnd", "nativeSrc": "1416:7:1", @@ -790,8 +703,7 @@ "src": "1425:9:1" } ], - "functionName": - { + "functionName": { "name": "sub", "nativeSrc": "1412:3:1", "nodeType": "YulIdentifier", @@ -810,8 +722,7 @@ "value": "32" } ], - "functionName": - { + "functionName": { "name": "slt", "nativeSrc": "1408:3:1", "nodeType": "YulIdentifier", @@ -829,19 +740,15 @@ "nativeSrc": "1534:312:1", "nodeType": "YulBlock", "src": "1534:312:1", - "statements": - [ + "statements": [ { "nativeSrc": "1549:45:1", "nodeType": "YulVariableDeclaration", "src": "1549:45:1", - "value": - { - "arguments": - [ + "value": { + "arguments": [ { - "arguments": - [ + "arguments": [ { "name": "headStart", "nativeSrc": "1580:9:1", @@ -857,8 +764,7 @@ "value": "0" } ], - "functionName": - { + "functionName": { "name": "add", "nativeSrc": "1576:3:1", "nodeType": "YulIdentifier", @@ -869,8 +775,7 @@ "src": "1576:17:1" } ], - "functionName": - { + "functionName": { "name": "calldataload", "nativeSrc": "1563:12:1", "nodeType": "YulIdentifier", @@ -880,8 +785,7 @@ "nodeType": "YulFunctionCall", "src": "1563:31:1" }, - "variables": - [ + "variables": [ { "name": "offset", "nativeSrc": "1553:6:1", @@ -892,19 +796,15 @@ ] }, { - "body": - { + "body": { "nativeSrc": "1641:83:1", "nodeType": "YulBlock", "src": "1641:83:1", - "statements": - [ + "statements": [ { - "expression": - { + "expression": { "arguments": [], - "functionName": - { + "functionName": { "name": "revert_error_c1322bf8034eace5e0b5c7295db60986aa89aae5e0ea0873e4689e076861a5db", "nativeSrc": "1643:77:1", "nodeType": "YulIdentifier", @@ -920,10 +820,8 @@ } ] }, - "condition": - { - "arguments": - [ + "condition": { + "arguments": [ { "name": "offset", "nativeSrc": "1613:6:1", @@ -939,8 +837,7 @@ "value": "0xffffffffffffffff" } ], - "functionName": - { + "functionName": { "name": "gt", "nativeSrc": "1610:2:1", "nodeType": "YulIdentifier", @@ -958,13 +855,10 @@ "nativeSrc": "1738:98:1", "nodeType": "YulAssignment", "src": "1738:98:1", - "value": - { - "arguments": - [ + "value": { + "arguments": [ { - "arguments": - [ + "arguments": [ { "name": "headStart", "nativeSrc": "1808:9:1", @@ -978,8 +872,7 @@ "src": "1819:6:1" } ], - "functionName": - { + "functionName": { "name": "add", "nativeSrc": "1804:3:1", "nodeType": "YulIdentifier", @@ -996,8 +889,7 @@ "src": "1828:7:1" } ], - "functionName": - { + "functionName": { "name": "abi_decode_t_array$_t_uint256_$dyn_calldata_ptr", "nativeSrc": "1756:47:1", "nodeType": "YulIdentifier", @@ -1007,8 +899,7 @@ "nodeType": "YulFunctionCall", "src": "1756:80:1" }, - "variableNames": - [ + "variableNames": [ { "name": "value0", "nativeSrc": "1738:6:1", @@ -1030,8 +921,7 @@ "name": "abi_decode_tuple_t_array$_t_uint256_$dyn_calldata_ptr", "nativeSrc": "1294:559:1", "nodeType": "YulFunctionDefinition", - "parameters": - [ + "parameters": [ { "name": "headStart", "nativeSrc": "1357:9:1", @@ -1047,8 +937,7 @@ "type": "" } ], - "returnVariables": - [ + "returnVariables": [ { "name": "value0", "nativeSrc": "1380:6:1", diff --git a/test/cmdlineTests/combined_json_stop_after_parsing/output b/test/cmdlineTests/combined_json_stop_after_parsing/output index 32cdd019b859..64e66e3f1227 100644 --- a/test/cmdlineTests/combined_json_stop_after_parsing/output +++ b/test/cmdlineTests/combined_json_stop_after_parsing/output @@ -1,28 +1,21 @@ { - "contracts": - { + "contracts": { "combined_json_stop_after_parsing/input.sol:C": {} }, - "sourceList": - [ + "sourceList": [ "combined_json_stop_after_parsing/input.sol" ], - "sources": - { - "combined_json_stop_after_parsing/input.sol": - { - "AST": - { + "sources": { + "combined_json_stop_after_parsing/input.sol": { + "AST": { "absolutePath": "combined_json_stop_after_parsing/input.sol", "id": 3, "license": "GPL-3.0", "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "id": 1, - "literals": - [ + "literals": [ "solidity", "*" ], diff --git a/test/cmdlineTests/combined_json_with_base_path/output b/test/cmdlineTests/combined_json_with_base_path/output index ec9bbcbcb22e..0a3add37e3b4 100644 --- a/test/cmdlineTests/combined_json_with_base_path/output +++ b/test/cmdlineTests/combined_json_with_base_path/output @@ -1,36 +1,27 @@ { - "contracts": - { + "contracts": { "combined_json_with_base_path/c.sol:C": {} }, - "sourceList": - [ + "sourceList": [ "combined_json_with_base_path/c.sol", "combined_json_with_base_path/input.sol" ], - "sources": - { - "combined_json_with_base_path/c.sol": - { - "AST": - { + "sources": { + "combined_json_with_base_path/c.sol": { + "AST": { "absolutePath": "combined_json_with_base_path/c.sol", - "exportedSymbols": - { - "C": - [ + "exportedSymbols": { + "C": [ 5 ] }, "id": 6, "license": "GPL-3.0", "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "id": 4, - "literals": - [ + "literals": [ "solidity", ">=", "0.0" @@ -46,8 +37,7 @@ "contractKind": "contract", "fullyImplemented": true, "id": 5, - "linearizedBaseContracts": - [ + "linearizedBaseContracts": [ 5 ], "name": "C", @@ -64,27 +54,21 @@ }, "id": 0 }, - "combined_json_with_base_path/input.sol": - { - "AST": - { + "combined_json_with_base_path/input.sol": { + "AST": { "absolutePath": "combined_json_with_base_path/input.sol", - "exportedSymbols": - { - "C": - [ + "exportedSymbols": { + "C": [ 5 ] }, "id": 3, "license": "GPL-3.0", "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "id": 1, - "literals": - [ + "literals": [ "solidity", ">=", "0.0" diff --git a/test/cmdlineTests/combined_json_with_devdoc/output b/test/cmdlineTests/combined_json_with_devdoc/output index d3df44a90d17..817018ea6c58 100644 --- a/test/cmdlineTests/combined_json_with_devdoc/output +++ b/test/cmdlineTests/combined_json_with_devdoc/output @@ -1,20 +1,15 @@ { - "contracts": - { - "combined_json_with_devdoc/input.sol:C": - { - "devdoc": - { + "contracts": { + "combined_json_with_devdoc/input.sol:C": { + "devdoc": { "details": "This is devdoc.", "kind": "dev", "methods": {}, "version": 1 } }, - "combined_json_with_devdoc/input.sol:D": - { - "devdoc": - { + "combined_json_with_devdoc/input.sol:D": { + "devdoc": { "kind": "dev", "methods": {}, "version": 1 diff --git a/test/cmdlineTests/combined_json_with_userdoc/output b/test/cmdlineTests/combined_json_with_userdoc/output index 650981d67c4f..4eb56fe24dd2 100644 --- a/test/cmdlineTests/combined_json_with_userdoc/output +++ b/test/cmdlineTests/combined_json_with_userdoc/output @@ -1,20 +1,15 @@ { - "contracts": - { - "combined_json_with_userdoc/input.sol:C": - { - "userdoc": - { + "contracts": { + "combined_json_with_userdoc/input.sol:C": { + "userdoc": { "kind": "user", "methods": {}, "notice": "Description for users.", "version": 1 } }, - "combined_json_with_userdoc/input.sol:D": - { - "userdoc": - { + "combined_json_with_userdoc/input.sol:D": { + "userdoc": { "kind": "user", "methods": {}, "version": 1 diff --git a/test/cmdlineTests/events_in_abi/output b/test/cmdlineTests/events_in_abi/output index 6c18a17521f0..ab246ef24a15 100644 --- a/test/cmdlineTests/events_in_abi/output +++ b/test/cmdlineTests/events_in_abi/output @@ -4,8 +4,7 @@ Contract JSON ABI [ { "anonymous": false, - "inputs": - [ + "inputs": [ { "indexed": false, "internalType": "uint256", @@ -18,8 +17,7 @@ Contract JSON ABI }, { "anonymous": false, - "inputs": - [ + "inputs": [ { "indexed": true, "internalType": "uint256", @@ -44,8 +42,7 @@ Contract JSON ABI [ { "anonymous": false, - "inputs": - [ + "inputs": [ { "indexed": false, "internalType": "uint256", diff --git a/test/cmdlineTests/function_debug_info/output b/test/cmdlineTests/function_debug_info/output index c359d4e1c155..bd7ba1197b96 100644 --- a/test/cmdlineTests/function_debug_info/output +++ b/test/cmdlineTests/function_debug_info/output @@ -1,57 +1,45 @@ { - "contracts": - { - "function_debug_info/input.sol:C": - { - "function-debug": - { - "@_34": - { + "contracts": { + "function_debug_info/input.sol:C": { + "function-debug": { + "@_34": { "id": 34, "parameterSlots": 1, "returnSlots": 0 }, - "abi_decode_tuple_t_uint256_fromMemory": - { + "abi_decode_tuple_t_uint256_fromMemory": { "entryPoint": 88, "parameterSlots": 2, "returnSlots": 1 } }, - "function-debug-runtime": - { - "@f_14": - { + "function-debug-runtime": { + "@f_14": { "entryPoint": 124, "id": 14, "parameterSlots": 2, "returnSlots": 1 }, - "@t_22": - { + "@t_22": { "id": 22, "parameterSlots": 0, "returnSlots": 0 }, - "abi_decode_tuple_t_array$_t_uint256_$dyn_calldata_ptr": - { + "abi_decode_tuple_t_array$_t_uint256_$dyn_calldata_ptr": { "entryPoint": 158, "parameterSlots": 2, "returnSlots": 2 }, - "abi_decode_tuple_t_uint256": - { + "abi_decode_tuple_t_uint256": { "entryPoint": 269, "parameterSlots": 2, "returnSlots": 1 }, - "abi_encode_tuple_t_uint256__to_t_uint256__fromStack_reversed": - { + "abi_encode_tuple_t_uint256__to_t_uint256__fromStack_reversed": { "parameterSlots": 2, "returnSlots": 1 }, - "panic_error_0x32": - { + "panic_error_0x32": { "entryPoint": 292, "parameterSlots": 0, "returnSlots": 0 diff --git a/test/cmdlineTests/function_debug_info_via_yul/output b/test/cmdlineTests/function_debug_info_via_yul/output index 5af245ce4afa..05c2da48c607 100644 --- a/test/cmdlineTests/function_debug_info_via_yul/output +++ b/test/cmdlineTests/function_debug_info_via_yul/output @@ -1,8 +1,6 @@ { - "contracts": - { - "function_debug_info_via_yul/input.sol:C": - { + "contracts": { + "function_debug_info_via_yul/input.sol:C": { "function-debug": {}, "function-debug-runtime": {} } diff --git a/test/cmdlineTests/import_asm_json_all_valid_flags/output b/test/cmdlineTests/import_asm_json_all_valid_flags/output index 837187d195ae..c96001047a3c 100644 --- a/test/cmdlineTests/import_asm_json_all_valid_flags/output +++ b/test/cmdlineTests/import_asm_json_all_valid_flags/output @@ -1,12 +1,8 @@ { - "contracts": - { - "": - { - "asm": - { - ".code": - [ + "contracts": { + "": { + "asm": { + ".code": [ { "begin": -1, "end": -1, @@ -15,12 +11,9 @@ "value": "0" } ], - ".data": - { - "0": - { - ".code": - [ + ".data": { + "0": { + ".code": [ { "begin": -1, "end": -1, @@ -31,8 +24,7 @@ ] } }, - "sourceList": - [ + "sourceList": [ "contract.sol", "#utility.yul" ] @@ -44,8 +36,7 @@ "srcmap-runtime": ":::-:0" } }, - "sourceList": - [ + "sourceList": [ "contract.sol", "#utility.yul" ], @@ -57,8 +48,7 @@ Binary of the runtime part: 6001 EVM assembly: { - ".code": - [ + ".code": [ { "begin": -1, "end": -1, @@ -67,12 +57,9 @@ EVM assembly: "value": "0" } ], - ".data": - { - "0": - { - ".code": - [ + ".data": { + "0": { + ".code": [ { "begin": -1, "end": -1, @@ -83,8 +70,7 @@ EVM assembly: ] } }, - "sourceList": - [ + "sourceList": [ "contract.sol", "#utility.yul" ] diff --git a/test/cmdlineTests/inline_assembly_function_name_clash/output b/test/cmdlineTests/inline_assembly_function_name_clash/output index 8becb87ae06f..d7c7bf9e09d9 100644 --- a/test/cmdlineTests/inline_assembly_function_name_clash/output +++ b/test/cmdlineTests/inline_assembly_function_name_clash/output @@ -1,204 +1,169 @@ { - "contracts": - { - "inline_assembly_function_name_clash/input.sol:C": - { - "function-debug-runtime": - { - "abi_decode": - { + "contracts": { + "inline_assembly_function_name_clash/input.sol:C": { + "function-debug-runtime": { + "abi_decode": { "entryPoint": 80, "parameterSlots": 2, "returnSlots": 0 }, - "abi_encode_uint256": - { + "abi_encode_uint256": { "entryPoint": 111, "parameterSlots": 2, "returnSlots": 1 }, - "abi_encode_uint256_to_uint256": - { + "abi_encode_uint256_to_uint256": { "entryPoint": 98, "parameterSlots": 2, "returnSlots": 0 }, - "allocate_unbounded": - { + "allocate_unbounded": { "entryPoint": 66, "parameterSlots": 0, "returnSlots": 1 }, - "cleanup_uint256": - { + "cleanup_uint256": { "entryPoint": 95, "parameterSlots": 1, "returnSlots": 1 }, - "convert_uint256_to_uint256": - { + "convert_uint256_to_uint256": { "entryPoint": 276, "parameterSlots": 1, "returnSlots": 1 }, - "external_fun_f": - { + "external_fun_f": { "entryPoint": 132, "parameterSlots": 0, "returnSlots": 0 }, - "external_fun_g": - { + "external_fun_g": { "entryPoint": 185, "parameterSlots": 0, "returnSlots": 0 }, - "fun_f": - { + "fun_f": { "entryPoint": 442, "id": 25, "parameterSlots": 0, "returnSlots": 1 }, - "fun_f_inner": - { + "fun_f_inner": { "entryPoint": 430, "parameterSlots": 1, "returnSlots": 1 }, - "fun_g": - { + "fun_g": { "entryPoint": 564, "id": 36, "parameterSlots": 0, "returnSlots": 1 }, - "fun_g_inner": - { + "fun_g_inner": { "entryPoint": 552, "parameterSlots": 1, "returnSlots": 1 }, - "identity": - { + "identity": { "entryPoint": 273, "parameterSlots": 1, "returnSlots": 1 }, - "modifier_m": - { + "modifier_m": { "entryPoint": 509, "id": 14, "parameterSlots": 1, "returnSlots": 1 }, - "modifier_m_17": - { + "modifier_m_17": { "entryPoint": 344, "id": 14, "parameterSlots": 1, "returnSlots": 1 }, - "modifier_m_19": - { + "modifier_m_19": { "entryPoint": 387, "id": 14, "parameterSlots": 1, "returnSlots": 1 }, - "modifier_m_28": - { + "modifier_m_28": { "entryPoint": 466, "id": 14, "parameterSlots": 1, "returnSlots": 1 }, - "prepare_store_uint256": - { + "prepare_store_uint256": { "entryPoint": 304, "parameterSlots": 1, "returnSlots": 1 }, - "revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74": - { + "revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74": { "entryPoint": 238, "parameterSlots": 0, "returnSlots": 0 }, - "revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb": - { + "revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb": { "entryPoint": 72, "parameterSlots": 0, "returnSlots": 0 }, - "revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b": - { + "revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b": { "entryPoint": 76, "parameterSlots": 0, "returnSlots": 0 }, - "shift_left": - { + "shift_left": { "entryPoint": 246, "parameterSlots": 1, "returnSlots": 1 }, - "shift_right_unsigned": - { + "shift_right_unsigned": { "entryPoint": 60, "parameterSlots": 1, "returnSlots": 1 }, - "update_byte_slice_shift": - { + "update_byte_slice_shift": { "entryPoint": 251, "parameterSlots": 2, "returnSlots": 1 }, - "update_storage_value_offsett_uint256_to_uint256": - { + "update_storage_value_offsett_uint256_to_uint256": { "entryPoint": 307, "parameterSlots": 2, "returnSlots": 0 }, - "usr$f": - { + "usr$f": { "entryPoint": 339, "parameterSlots": 0, "returnSlots": 1 }, - "usr$f_17": - { + "usr$f_17": { "entryPoint": 382, "parameterSlots": 0, "returnSlots": 1 }, - "usr$f_22": - { + "usr$f_22": { "entryPoint": 425, "parameterSlots": 0, "returnSlots": 1 }, - "usr$f_26": - { + "usr$f_26": { "entryPoint": 461, "parameterSlots": 0, "returnSlots": 1 }, - "usr$f_32": - { + "usr$f_32": { "entryPoint": 504, "parameterSlots": 0, "returnSlots": 1 }, - "usr$f_37": - { + "usr$f_37": { "entryPoint": 547, "parameterSlots": 0, "returnSlots": 1 }, - "zero_value_for_split_uint256": - { + "zero_value_for_split_uint256": { "entryPoint": 242, "parameterSlots": 0, "returnSlots": 1 diff --git a/test/cmdlineTests/linking_standard_solidity/output.json b/test/cmdlineTests/linking_standard_solidity/output.json index 83813d806b01..1e49af2ca0fa 100644 --- a/test/cmdlineTests/linking_standard_solidity/output.json +++ b/test/cmdlineTests/linking_standard_solidity/output.json @@ -1,14 +1,9 @@ { - "contracts": - { - "A": - { - "C": - { - "evm": - { - "bytecode": - { + "contracts": { + "A": { + "C": { + "evm": { + "bytecode": { "linkReferences": {}, "object": "" } @@ -16,10 +11,8 @@ } } }, - "sources": - { - "A": - { + "sources": { + "A": { "id": 0 } } diff --git a/test/cmdlineTests/linking_standard_solidity_quote_in_file_name/output.json b/test/cmdlineTests/linking_standard_solidity_quote_in_file_name/output.json index 38e0a1b5aa18..87e80b8d19a8 100644 --- a/test/cmdlineTests/linking_standard_solidity_quote_in_file_name/output.json +++ b/test/cmdlineTests/linking_standard_solidity_quote_in_file_name/output.json @@ -1,14 +1,9 @@ { - "contracts": - { - "A\"B": - { - "C": - { - "evm": - { - "bytecode": - { + "contracts": { + "A\"B": { + "C": { + "evm": { + "bytecode": { "linkReferences": {}, "object": "" } @@ -16,10 +11,8 @@ } } }, - "sources": - { - "A\"B": - { + "sources": { + "A\"B": { "id": 0 } } diff --git a/test/cmdlineTests/linking_standard_solidity_unresolved_references/output.json b/test/cmdlineTests/linking_standard_solidity_unresolved_references/output.json index 3a69e3e2d782..71c17347a754 100644 --- a/test/cmdlineTests/linking_standard_solidity_unresolved_references/output.json +++ b/test/cmdlineTests/linking_standard_solidity_unresolved_references/output.json @@ -1,20 +1,12 @@ { - "contracts": - { - "A": - { - "C": - { - "evm": - { - "bytecode": - { - "linkReferences": - { - "A": - { - "L2": - [ + "contracts": { + "A": { + "C": { + "evm": { + "bytecode": { + "linkReferences": { + "A": { + "L2": [ { "length": 20, "start": 173 @@ -32,10 +24,8 @@ } } }, - "sources": - { - "A": - { + "sources": { + "A": { "id": 0 } } diff --git a/test/cmdlineTests/linking_standard_yul/output.json b/test/cmdlineTests/linking_standard_yul/output.json index b9059bdfd622..90445cfe0831 100644 --- a/test/cmdlineTests/linking_standard_yul/output.json +++ b/test/cmdlineTests/linking_standard_yul/output.json @@ -1,14 +1,9 @@ { - "contracts": - { - "A": - { - "a": - { - "evm": - { - "bytecode": - { + "contracts": { + "A": { + "a": { + "evm": { + "bytecode": { "linkReferences": {}, "object": "" } diff --git a/test/cmdlineTests/linking_standard_yul_quote_in_file_name/output.json b/test/cmdlineTests/linking_standard_yul_quote_in_file_name/output.json index b9059bdfd622..90445cfe0831 100644 --- a/test/cmdlineTests/linking_standard_yul_quote_in_file_name/output.json +++ b/test/cmdlineTests/linking_standard_yul_quote_in_file_name/output.json @@ -1,14 +1,9 @@ { - "contracts": - { - "A": - { - "a": - { - "evm": - { - "bytecode": - { + "contracts": { + "A": { + "a": { + "evm": { + "bytecode": { "linkReferences": {}, "object": "" } diff --git a/test/cmdlineTests/linking_standard_yul_unresolved_references/output.json b/test/cmdlineTests/linking_standard_yul_unresolved_references/output.json index ac1250cd4c74..041e8206b830 100644 --- a/test/cmdlineTests/linking_standard_yul_unresolved_references/output.json +++ b/test/cmdlineTests/linking_standard_yul_unresolved_references/output.json @@ -1,20 +1,12 @@ { - "contracts": - { - "A": - { - "a": - { - "evm": - { - "bytecode": - { - "linkReferences": - { - "contract/test.sol": - { - "L2": - [ + "contracts": { + "A": { + "a": { + "evm": { + "bytecode": { + "linkReferences": { + "contract/test.sol": { + "L2": [ { "length": 20, "start": 22 diff --git a/test/cmdlineTests/no_contract_combined_json/output b/test/cmdlineTests/no_contract_combined_json/output index e0caa6fa1acc..8c454e341442 100644 --- a/test/cmdlineTests/no_contract_combined_json/output +++ b/test/cmdlineTests/no_contract_combined_json/output @@ -1,25 +1,19 @@ { - "sourceList": - [ + "sourceList": [ "no_contract_combined_json/input.sol" ], - "sources": - { - "no_contract_combined_json/input.sol": - { - "AST": - { + "sources": { + "no_contract_combined_json/input.sol": { + "AST": { "absolutePath": "no_contract_combined_json/input.sol", "exportedSymbols": {}, "id": 2, "license": "GPL-3.0", "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "id": 1, - "literals": - [ + "literals": [ "solidity", ">=", "0.0" diff --git a/test/cmdlineTests/output_selection_all_A1/output.json b/test/cmdlineTests/output_selection_all_A1/output.json index b21b632bdc88..e28a8af254e5 100644 --- a/test/cmdlineTests/output_selection_all_A1/output.json +++ b/test/cmdlineTests/output_selection_all_A1/output.json @@ -1,41 +1,29 @@ { - "contracts": - { - "a.sol": - { - "A1": - { - "evm": - { - "bytecode": - { + "contracts": { + "a.sol": { + "A1": { + "evm": { + "bytecode": { "object": "" } } } }, - "b.sol": - { - "A1": - { - "evm": - { - "bytecode": - { + "b.sol": { + "A1": { + "evm": { + "bytecode": { "object": "" } } } } }, - "sources": - { - "a.sol": - { + "sources": { + "a.sol": { "id": 0 }, - "b.sol": - { + "b.sol": { "id": 1 } } diff --git a/test/cmdlineTests/output_selection_all_A2/output.json b/test/cmdlineTests/output_selection_all_A2/output.json index c33941c2f9e5..9e6ea3b0e715 100644 --- a/test/cmdlineTests/output_selection_all_A2/output.json +++ b/test/cmdlineTests/output_selection_all_A2/output.json @@ -1,28 +1,20 @@ { - "contracts": - { - "a.sol": - { - "A2": - { - "evm": - { - "bytecode": - { + "contracts": { + "a.sol": { + "A2": { + "evm": { + "bytecode": { "object": "" } } } } }, - "sources": - { - "a.sol": - { + "sources": { + "a.sol": { "id": 0 }, - "b.sol": - { + "b.sol": { "id": 1 } } diff --git a/test/cmdlineTests/output_selection_all_blank/output.json b/test/cmdlineTests/output_selection_all_blank/output.json index b4c60911cb64..d05ed608c34c 100644 --- a/test/cmdlineTests/output_selection_all_blank/output.json +++ b/test/cmdlineTests/output_selection_all_blank/output.json @@ -1,12 +1,9 @@ { - "sources": - { - "a.sol": - { + "sources": { + "a.sol": { "id": 0 }, - "b.sol": - { + "b.sol": { "id": 1 } } diff --git a/test/cmdlineTests/output_selection_all_star/output.json b/test/cmdlineTests/output_selection_all_star/output.json index f709636212b6..668c4b4235c9 100644 --- a/test/cmdlineTests/output_selection_all_star/output.json +++ b/test/cmdlineTests/output_selection_all_star/output.json @@ -1,61 +1,43 @@ { - "contracts": - { - "a.sol": - { - "A1": - { - "evm": - { - "bytecode": - { + "contracts": { + "a.sol": { + "A1": { + "evm": { + "bytecode": { "object": "" } } }, - "A2": - { - "evm": - { - "bytecode": - { + "A2": { + "evm": { + "bytecode": { "object": "" } } } }, - "b.sol": - { - "A1": - { - "evm": - { - "bytecode": - { + "b.sol": { + "A1": { + "evm": { + "bytecode": { "object": "" } } }, - "B2": - { - "evm": - { - "bytecode": - { + "B2": { + "evm": { + "bytecode": { "object": "" } } } } }, - "sources": - { - "a.sol": - { + "sources": { + "a.sol": { "id": 0 }, - "b.sol": - { + "b.sol": { "id": 1 } } diff --git a/test/cmdlineTests/output_selection_single_A1/output.json b/test/cmdlineTests/output_selection_single_A1/output.json index ab44a2d540a4..137b19cc0dd8 100644 --- a/test/cmdlineTests/output_selection_single_A1/output.json +++ b/test/cmdlineTests/output_selection_single_A1/output.json @@ -1,28 +1,20 @@ { - "contracts": - { - "a.sol": - { - "A1": - { - "evm": - { - "bytecode": - { + "contracts": { + "a.sol": { + "A1": { + "evm": { + "bytecode": { "object": "" } } } } }, - "sources": - { - "a.sol": - { + "sources": { + "a.sol": { "id": 0 }, - "b.sol": - { + "b.sol": { "id": 1 } } diff --git a/test/cmdlineTests/output_selection_single_B1/output.json b/test/cmdlineTests/output_selection_single_B1/output.json index ffaf266b4d06..87dd70b3aa28 100644 --- a/test/cmdlineTests/output_selection_single_B1/output.json +++ b/test/cmdlineTests/output_selection_single_B1/output.json @@ -1,28 +1,20 @@ { - "contracts": - { - "b.sol": - { - "B2": - { - "evm": - { - "bytecode": - { + "contracts": { + "b.sol": { + "B2": { + "evm": { + "bytecode": { "object": "" } } } } }, - "sources": - { - "a.sol": - { + "sources": { + "a.sol": { "id": 0 }, - "b.sol": - { + "b.sol": { "id": 1 } } diff --git a/test/cmdlineTests/output_selection_single_all/output.json b/test/cmdlineTests/output_selection_single_all/output.json index 52d04cb18ddf..123f437137f3 100644 --- a/test/cmdlineTests/output_selection_single_all/output.json +++ b/test/cmdlineTests/output_selection_single_all/output.json @@ -1,38 +1,27 @@ { - "contracts": - { - "a.sol": - { - "A1": - { - "evm": - { - "bytecode": - { + "contracts": { + "a.sol": { + "A1": { + "evm": { + "bytecode": { "object": "" } } }, - "A2": - { - "evm": - { - "bytecode": - { + "A2": { + "evm": { + "bytecode": { "object": "" } } } } }, - "sources": - { - "a.sol": - { + "sources": { + "a.sol": { "id": 0 }, - "b.sol": - { + "b.sol": { "id": 1 } } diff --git a/test/cmdlineTests/pretty_json_indent_only/output.json b/test/cmdlineTests/pretty_json_indent_only/output.json index 80d51c4f1f2f..eeefefbd74da 100644 --- a/test/cmdlineTests/pretty_json_indent_only/output.json +++ b/test/cmdlineTests/pretty_json_indent_only/output.json @@ -1,8 +1,6 @@ { - "sources": - { - "A": - { + "sources": { + "A": { "id": 0 } } diff --git a/test/cmdlineTests/pretty_json_standard/output.json b/test/cmdlineTests/pretty_json_standard/output.json index 29185e758349..96281af4e0a9 100644 --- a/test/cmdlineTests/pretty_json_standard/output.json +++ b/test/cmdlineTests/pretty_json_standard/output.json @@ -1,8 +1,6 @@ { - "sources": - { - "A": - { + "sources": { + "A": { "id": 0 } } diff --git a/test/cmdlineTests/pretty_json_standard_indent/output.json b/test/cmdlineTests/pretty_json_standard_indent/output.json index 80d51c4f1f2f..eeefefbd74da 100644 --- a/test/cmdlineTests/pretty_json_standard_indent/output.json +++ b/test/cmdlineTests/pretty_json_standard_indent/output.json @@ -1,8 +1,6 @@ { - "sources": - { - "A": - { + "sources": { + "A": { "id": 0 } } 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 97041b2380b5..642d07f49af2 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,12 +1,8 @@ { - "contracts": - { - "C": - { - "C": - { - "evm": - { + "contracts": { + "C": { + "C": { + "evm": { "assembly": " /* \"C\":79:503 contract C... */ 0xa0 jumpi(tag_5, callvalue) @@ -350,12 +346,9 @@ sub_0: assembly { } } }, - "D": - { - "D": - { - "evm": - { + "D": { + "D": { + "evm": { "assembly": " /* \"D\":91:181 contract D is C(3)... */ 0xa0 jumpi(tag_5, callvalue) @@ -716,14 +709,11 @@ sub_0: assembly { } } }, - "sources": - { - "C": - { + "sources": { + "C": { "id": 0 }, - "D": - { + "D": { "id": 1 } } 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 ee958b55b029..9489a75bf3df 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 @@ -1,12 +1,8 @@ { - "contracts": - { - "C": - { - "C": - { - "evm": - { + "contracts": { + "C": { + "C": { + "evm": { "assembly": " /* \"C\":60:101 contract C {... */ mstore(0x40, 0x80) callvalue @@ -211,10 +207,8 @@ object \"C_6\" { } } }, - "sources": - { - "C": - { + "sources": { + "C": { "id": 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 007b7fc62bad..f8f2958b0384 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 @@ -1,12 +1,8 @@ { - "contracts": - { - "C": - { - "C": - { - "evm": - { + "contracts": { + "C": { + "C": { + "evm": { "assembly": " /* \"C\":60:101 */ mstore(0x40, 0x80) callvalue @@ -210,10 +206,8 @@ object \"C_6\" { } } }, - "sources": - { - "C": - { + "sources": { + "C": { "id": 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 884da9eb9715..2a5a2bc2ae15 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 @@ -1,12 +1,8 @@ { - "contracts": - { - "C": - { - "C": - { - "evm": - { + "contracts": { + "C": { + "C": { + "evm": { "assembly": " mstore(0x40, 0x80) callvalue dup1 @@ -199,10 +195,8 @@ object \"C_6\" { } } }, - "sources": - { - "C": - { + "sources": { + "C": { "id": 0 } } diff --git a/test/cmdlineTests/standard_debug_info_in_yul_and_evm_asm_print_snippet_only/output.json b/test/cmdlineTests/standard_debug_info_in_yul_and_evm_asm_print_snippet_only/output.json index fb7f199a75cf..7f48fd4e93bc 100644 --- a/test/cmdlineTests/standard_debug_info_in_yul_and_evm_asm_print_snippet_only/output.json +++ b/test/cmdlineTests/standard_debug_info_in_yul_and_evm_asm_print_snippet_only/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "formattedMessage": "To use 'snippet' with settings.debug.debugInfo you must select also 'location'.", 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 54748658fd6a..3e687cc1a0fc 100644 --- a/test/cmdlineTests/standard_debug_info_in_yul_location/output.json +++ b/test/cmdlineTests/standard_debug_info_in_yul_location/output.json @@ -1,10 +1,7 @@ { - "contracts": - { - "C": - { - "C": - { + "contracts": { + "C": { + "C": { "ir": " /// @use-src 0:\"C\" object \"C_54\" { @@ -769,10 +766,8 @@ object \"C_54\" { " } }, - "D": - { - "D": - { + "D": { + "D": { "ir": " /// @use-src 0:\"C\", 1:\"D\" object \"D_72\" { @@ -1615,14 +1610,11 @@ object \"D_72\" { } } }, - "sources": - { - "C": - { + "sources": { + "C": { "id": 0 }, - "D": - { + "D": { "id": 1 } } diff --git a/test/cmdlineTests/standard_default_success/output.json b/test/cmdlineTests/standard_default_success/output.json index acf3b74ef1de..f047ff70a9eb 100644 --- a/test/cmdlineTests/standard_default_success/output.json +++ b/test/cmdlineTests/standard_default_success/output.json @@ -1,8 +1,6 @@ { - "sources": - { - "A": - { + "sources": { + "A": { "id": 0 } } diff --git a/test/cmdlineTests/standard_empty_file_name/output.json b/test/cmdlineTests/standard_empty_file_name/output.json index 4e4d84c41c75..1fd016e54e81 100644 --- a/test/cmdlineTests/standard_empty_file_name/output.json +++ b/test/cmdlineTests/standard_empty_file_name/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "errorCode": "2904", @@ -9,8 +8,7 @@ ", "message": "Declaration \"A\" not found in \"\" (referenced as \".\").", "severity": "error", - "sourceLocation": - { + "sourceLocation": { "end": 79, "file": "", "start": 59 diff --git a/test/cmdlineTests/standard_evm_version_byzantium/output.json b/test/cmdlineTests/standard_evm_version_byzantium/output.json index b2428b105060..36570f9c2a9a 100644 --- a/test/cmdlineTests/standard_evm_version_byzantium/output.json +++ b/test/cmdlineTests/standard_evm_version_byzantium/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "formattedMessage": "Support for EVM versions older than constantinople is deprecated and will be removed in the future.", @@ -9,10 +8,8 @@ "type": "Warning" } ], - "sources": - { - "input.sol": - { + "sources": { + "input.sol": { "id": 0 } } diff --git a/test/cmdlineTests/standard_evm_version_constantinople/output.json b/test/cmdlineTests/standard_evm_version_constantinople/output.json index 1ce414a4cc79..81fa23ff623f 100644 --- a/test/cmdlineTests/standard_evm_version_constantinople/output.json +++ b/test/cmdlineTests/standard_evm_version_constantinople/output.json @@ -1,8 +1,6 @@ { - "sources": - { - "input.sol": - { + "sources": { + "input.sol": { "id": 0 } } diff --git a/test/cmdlineTests/standard_function_debug_info/output.json b/test/cmdlineTests/standard_function_debug_info/output.json index bbbb6b96faf3..645e1646a698 100644 --- a/test/cmdlineTests/standard_function_debug_info/output.json +++ b/test/cmdlineTests/standard_function_debug_info/output.json @@ -1,169 +1,140 @@ { - "contracts": - { - "a.sol": - { - "A": - { - "evm": - { - "bytecode": - { + "contracts": { + "a.sol": { + "A": { + "evm": { + "bytecode": { "functionDebugData": {} }, - "deployedBytecode": - { - "functionDebugData": - { - "@f_19": - { + "deployedBytecode": { + "functionDebugData": { + "@f_19": { "entryPoint": 93, "id": 19, "parameterSlots": 1, "returnSlots": 1 }, - "abi_decode_available_length_t_array$_t_uint256_$dyn_memory_ptr": - { + "abi_decode_available_length_t_array$_t_uint256_$dyn_memory_ptr": { "entryPoint": 421, "id": null, "parameterSlots": 3, "returnSlots": 1 }, - "abi_decode_t_array$_t_uint256_$dyn_memory_ptr": - { + "abi_decode_t_array$_t_uint256_$dyn_memory_ptr": { "entryPoint": 525, "id": null, "parameterSlots": 2, "returnSlots": 1 }, - "abi_decode_t_uint256": - { + "abi_decode_t_uint256": { "entryPoint": 401, "id": null, "parameterSlots": 2, "returnSlots": 1 }, - "abi_decode_tuple_t_array$_t_uint256_$dyn_memory_ptr": - { + "abi_decode_tuple_t_array$_t_uint256_$dyn_memory_ptr": { "entryPoint": 570, "id": null, "parameterSlots": 2, "returnSlots": 1 }, - "abi_encode_t_uint256_to_t_uint256_fromStack": - { + "abi_encode_t_uint256_to_t_uint256_fromStack": { "entryPoint": 641, "id": null, "parameterSlots": 2, "returnSlots": 0 }, - "abi_encode_tuple_t_uint256__to_t_uint256__fromStack_reversed": - { + "abi_encode_tuple_t_uint256__to_t_uint256__fromStack_reversed": { "entryPoint": 656, "id": null, "parameterSlots": 2, "returnSlots": 1 }, - "allocate_memory": - { + "allocate_memory": { "entryPoint": 297, "id": null, "parameterSlots": 1, "returnSlots": 1 }, - "allocate_unbounded": - { + "allocate_unbounded": { "entryPoint": 166, "id": null, "parameterSlots": 0, "returnSlots": 1 }, - "array_allocation_size_t_array$_t_uint256_$dyn_memory_ptr": - { + "array_allocation_size_t_array$_t_uint256_$dyn_memory_ptr": { "entryPoint": 323, "id": null, "parameterSlots": 1, "returnSlots": 1 }, - "checked_add_t_uint256": - { + "checked_add_t_uint256": { "entryPoint": 771, "id": null, "parameterSlots": 2, "returnSlots": 1 }, - "cleanup_t_uint256": - { + "cleanup_t_uint256": { "entryPoint": 370, "id": null, "parameterSlots": 1, "returnSlots": 1 }, - "finalize_allocation": - { + "finalize_allocation": { "entryPoint": 248, "id": null, "parameterSlots": 2, "returnSlots": 0 }, - "panic_error_0x11": - { + "panic_error_0x11": { "entryPoint": 726, "id": null, "parameterSlots": 0, "returnSlots": 0 }, - "panic_error_0x32": - { + "panic_error_0x32": { "entryPoint": 681, "id": null, "parameterSlots": 0, "returnSlots": 0 }, - "panic_error_0x41": - { + "panic_error_0x41": { "entryPoint": 203, "id": null, "parameterSlots": 0, "returnSlots": 0 }, - "revert_error_1b9f4a0a5773e33b91aa01db23bf8c55fce1411167c872835e7fa00a4f17d46d": - { + "revert_error_1b9f4a0a5773e33b91aa01db23bf8c55fce1411167c872835e7fa00a4f17d46d": { "entryPoint": 183, "id": null, "parameterSlots": 0, "returnSlots": 0 }, - "revert_error_81385d8c0b31fffe14be1da910c8bd3a80be4cfa248e04f42ec0faea3132a8ef": - { + "revert_error_81385d8c0b31fffe14be1da910c8bd3a80be4cfa248e04f42ec0faea3132a8ef": { "entryPoint": 366, "id": null, "parameterSlots": 0, "returnSlots": 0 }, - "revert_error_c1322bf8034eace5e0b5c7295db60986aa89aae5e0ea0873e4689e076861a5db": - { + "revert_error_c1322bf8034eace5e0b5c7295db60986aa89aae5e0ea0873e4689e076861a5db": { "entryPoint": 179, "id": null, "parameterSlots": 0, "returnSlots": 0 }, - "revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b": - { + "revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b": { "entryPoint": 175, "id": null, "parameterSlots": 0, "returnSlots": 0 }, - "round_up_to_mul_of_32": - { + "round_up_to_mul_of_32": { "entryPoint": 187, "id": null, "parameterSlots": 1, "returnSlots": 1 }, - "validator_revert_t_uint256": - { + "validator_revert_t_uint256": { "entryPoint": 379, "id": null, "parameterSlots": 1, @@ -175,10 +146,8 @@ } } }, - "sources": - { - "a.sol": - { + "sources": { + "a.sol": { "id": 0 } } diff --git a/test/cmdlineTests/standard_generatedSources/output.json b/test/cmdlineTests/standard_generatedSources/output.json index 350d108991bd..4fb0b3dcc336 100644 --- a/test/cmdlineTests/standard_generatedSources/output.json +++ b/test/cmdlineTests/standard_generatedSources/output.json @@ -1,45 +1,32 @@ { - "contracts": - { - "a.sol": - { - "A": - { - "evm": - { - "bytecode": - { + "contracts": { + "a.sol": { + "A": { + "evm": { + "bytecode": { "generatedSources": [], "object": "" }, - "deployedBytecode": - { - "generatedSources": - [ + "deployedBytecode": { + "generatedSources": [ { - "ast": - { + "ast": { "nativeSrc": "0:3989:1", "nodeType": "YulBlock", "src": "0:3989:1", - "statements": - [ + "statements": [ { - "body": - { + "body": { "nativeSrc": "47:35:1", "nodeType": "YulBlock", "src": "47:35:1", - "statements": - [ + "statements": [ { "nativeSrc": "57:19:1", "nodeType": "YulAssignment", "src": "57:19:1", - "value": - { - "arguments": - [ + "value": { + "arguments": [ { "kind": "number", "nativeSrc": "73:2:1", @@ -49,8 +36,7 @@ "value": "64" } ], - "functionName": - { + "functionName": { "name": "mload", "nativeSrc": "67:5:1", "nodeType": "YulIdentifier", @@ -60,8 +46,7 @@ "nodeType": "YulFunctionCall", "src": "67:9:1" }, - "variableNames": - [ + "variableNames": [ { "name": "memPtr", "nativeSrc": "57:6:1", @@ -75,8 +60,7 @@ "name": "allocate_unbounded", "nativeSrc": "7:75:1", "nodeType": "YulFunctionDefinition", - "returnVariables": - [ + "returnVariables": [ { "name": "memPtr", "nativeSrc": "40:6:1", @@ -88,18 +72,14 @@ "src": "7:75:1" }, { - "body": - { + "body": { "nativeSrc": "177:28:1", "nodeType": "YulBlock", "src": "177:28:1", - "statements": - [ + "statements": [ { - "expression": - { - "arguments": - [ + "expression": { + "arguments": [ { "kind": "number", "nativeSrc": "194:1:1", @@ -117,8 +97,7 @@ "value": "0" } ], - "functionName": - { + "functionName": { "name": "revert", "nativeSrc": "187:6:1", "nodeType": "YulIdentifier", @@ -140,18 +119,14 @@ "src": "88:117:1" }, { - "body": - { + "body": { "nativeSrc": "300:28:1", "nodeType": "YulBlock", "src": "300:28:1", - "statements": - [ + "statements": [ { - "expression": - { - "arguments": - [ + "expression": { + "arguments": [ { "kind": "number", "nativeSrc": "317:1:1", @@ -169,8 +144,7 @@ "value": "0" } ], - "functionName": - { + "functionName": { "name": "revert", "nativeSrc": "310:6:1", "nodeType": "YulIdentifier", @@ -192,18 +166,14 @@ "src": "211:117:1" }, { - "body": - { + "body": { "nativeSrc": "423:28:1", "nodeType": "YulBlock", "src": "423:28:1", - "statements": - [ + "statements": [ { - "expression": - { - "arguments": - [ + "expression": { + "arguments": [ { "kind": "number", "nativeSrc": "440:1:1", @@ -221,8 +191,7 @@ "value": "0" } ], - "functionName": - { + "functionName": { "name": "revert", "nativeSrc": "433:6:1", "nodeType": "YulIdentifier", @@ -244,24 +213,19 @@ "src": "334:117:1" }, { - "body": - { + "body": { "nativeSrc": "505:54:1", "nodeType": "YulBlock", "src": "505:54:1", - "statements": - [ + "statements": [ { "nativeSrc": "515:38:1", "nodeType": "YulAssignment", "src": "515:38:1", - "value": - { - "arguments": - [ + "value": { + "arguments": [ { - "arguments": - [ + "arguments": [ { "name": "value", "nativeSrc": "533:5:1", @@ -277,8 +241,7 @@ "value": "31" } ], - "functionName": - { + "functionName": { "name": "add", "nativeSrc": "529:3:1", "nodeType": "YulIdentifier", @@ -289,8 +252,7 @@ "src": "529:14:1" }, { - "arguments": - [ + "arguments": [ { "kind": "number", "nativeSrc": "549:2:1", @@ -300,8 +262,7 @@ "value": "31" } ], - "functionName": - { + "functionName": { "name": "not", "nativeSrc": "545:3:1", "nodeType": "YulIdentifier", @@ -312,8 +273,7 @@ "src": "545:7:1" } ], - "functionName": - { + "functionName": { "name": "and", "nativeSrc": "525:3:1", "nodeType": "YulIdentifier", @@ -323,8 +283,7 @@ "nodeType": "YulFunctionCall", "src": "525:28:1" }, - "variableNames": - [ + "variableNames": [ { "name": "result", "nativeSrc": "515:6:1", @@ -338,8 +297,7 @@ "name": "round_up_to_mul_of_32", "nativeSrc": "457:102:1", "nodeType": "YulFunctionDefinition", - "parameters": - [ + "parameters": [ { "name": "value", "nativeSrc": "488:5:1", @@ -348,8 +306,7 @@ "type": "" } ], - "returnVariables": - [ + "returnVariables": [ { "name": "result", "nativeSrc": "498:6:1", @@ -361,18 +318,14 @@ "src": "457:102:1" }, { - "body": - { + "body": { "nativeSrc": "593:152:1", "nodeType": "YulBlock", "src": "593:152:1", - "statements": - [ + "statements": [ { - "expression": - { - "arguments": - [ + "expression": { + "arguments": [ { "kind": "number", "nativeSrc": "610:1:1", @@ -390,8 +343,7 @@ "value": "35408467139433450592217433187231851964531694900788300625387963629091585785856" } ], - "functionName": - { + "functionName": { "name": "mstore", "nativeSrc": "603:6:1", "nodeType": "YulIdentifier", @@ -406,10 +358,8 @@ "src": "603:88:1" }, { - "expression": - { - "arguments": - [ + "expression": { + "arguments": [ { "kind": "number", "nativeSrc": "707:1:1", @@ -427,8 +377,7 @@ "value": "0x41" } ], - "functionName": - { + "functionName": { "name": "mstore", "nativeSrc": "700:6:1", "nodeType": "YulIdentifier", @@ -443,10 +392,8 @@ "src": "700:15:1" }, { - "expression": - { - "arguments": - [ + "expression": { + "arguments": [ { "kind": "number", "nativeSrc": "731:1:1", @@ -464,8 +411,7 @@ "value": "0x24" } ], - "functionName": - { + "functionName": { "name": "revert", "nativeSrc": "724:6:1", "nodeType": "YulIdentifier", @@ -487,21 +433,17 @@ "src": "565:180:1" }, { - "body": - { + "body": { "nativeSrc": "794:238:1", "nodeType": "YulBlock", "src": "794:238:1", - "statements": - [ + "statements": [ { "nativeSrc": "804:58:1", "nodeType": "YulVariableDeclaration", "src": "804:58:1", - "value": - { - "arguments": - [ + "value": { + "arguments": [ { "name": "memPtr", "nativeSrc": "826:6:1", @@ -509,8 +451,7 @@ "src": "826:6:1" }, { - "arguments": - [ + "arguments": [ { "name": "size", "nativeSrc": "856:4:1", @@ -518,8 +459,7 @@ "src": "856:4:1" } ], - "functionName": - { + "functionName": { "name": "round_up_to_mul_of_32", "nativeSrc": "834:21:1", "nodeType": "YulIdentifier", @@ -530,8 +470,7 @@ "src": "834:27:1" } ], - "functionName": - { + "functionName": { "name": "add", "nativeSrc": "822:3:1", "nodeType": "YulIdentifier", @@ -541,8 +480,7 @@ "nodeType": "YulFunctionCall", "src": "822:40:1" }, - "variables": - [ + "variables": [ { "name": "newFreePtr", "nativeSrc": "808:10:1", @@ -553,19 +491,15 @@ ] }, { - "body": - { + "body": { "nativeSrc": "973:22:1", "nodeType": "YulBlock", "src": "973:22:1", - "statements": - [ + "statements": [ { - "expression": - { + "expression": { "arguments": [], - "functionName": - { + "functionName": { "name": "panic_error_0x41", "nativeSrc": "975:16:1", "nodeType": "YulIdentifier", @@ -581,13 +515,10 @@ } ] }, - "condition": - { - "arguments": - [ + "condition": { + "arguments": [ { - "arguments": - [ + "arguments": [ { "name": "newFreePtr", "nativeSrc": "916:10:1", @@ -603,8 +534,7 @@ "value": "0xffffffffffffffff" } ], - "functionName": - { + "functionName": { "name": "gt", "nativeSrc": "913:2:1", "nodeType": "YulIdentifier", @@ -615,8 +545,7 @@ "src": "913:34:1" }, { - "arguments": - [ + "arguments": [ { "name": "newFreePtr", "nativeSrc": "952:10:1", @@ -630,8 +559,7 @@ "src": "964:6:1" } ], - "functionName": - { + "functionName": { "name": "lt", "nativeSrc": "949:2:1", "nodeType": "YulIdentifier", @@ -642,8 +570,7 @@ "src": "949:22:1" } ], - "functionName": - { + "functionName": { "name": "or", "nativeSrc": "910:2:1", "nodeType": "YulIdentifier", @@ -658,10 +585,8 @@ "src": "907:88:1" }, { - "expression": - { - "arguments": - [ + "expression": { + "arguments": [ { "kind": "number", "nativeSrc": "1011:2:1", @@ -677,8 +602,7 @@ "src": "1015:10:1" } ], - "functionName": - { + "functionName": { "name": "mstore", "nativeSrc": "1004:6:1", "nodeType": "YulIdentifier", @@ -697,8 +621,7 @@ "name": "finalize_allocation", "nativeSrc": "751:281:1", "nodeType": "YulFunctionDefinition", - "parameters": - [ + "parameters": [ { "name": "memPtr", "nativeSrc": "780:6:1", @@ -717,22 +640,18 @@ "src": "751:281:1" }, { - "body": - { + "body": { "nativeSrc": "1079:88:1", "nodeType": "YulBlock", "src": "1079:88:1", - "statements": - [ + "statements": [ { "nativeSrc": "1089:30:1", "nodeType": "YulAssignment", "src": "1089:30:1", - "value": - { + "value": { "arguments": [], - "functionName": - { + "functionName": { "name": "allocate_unbounded", "nativeSrc": "1099:18:1", "nodeType": "YulIdentifier", @@ -742,8 +661,7 @@ "nodeType": "YulFunctionCall", "src": "1099:20:1" }, - "variableNames": - [ + "variableNames": [ { "name": "memPtr", "nativeSrc": "1089:6:1", @@ -753,10 +671,8 @@ ] }, { - "expression": - { - "arguments": - [ + "expression": { + "arguments": [ { "name": "memPtr", "nativeSrc": "1148:6:1", @@ -770,8 +686,7 @@ "src": "1156:4:1" } ], - "functionName": - { + "functionName": { "name": "finalize_allocation", "nativeSrc": "1128:19:1", "nodeType": "YulIdentifier", @@ -790,8 +705,7 @@ "name": "allocate_memory", "nativeSrc": "1038:129:1", "nodeType": "YulFunctionDefinition", - "parameters": - [ + "parameters": [ { "name": "size", "nativeSrc": "1063:4:1", @@ -800,8 +714,7 @@ "type": "" } ], - "returnVariables": - [ + "returnVariables": [ { "name": "memPtr", "nativeSrc": "1072:6:1", @@ -813,27 +726,21 @@ "src": "1038:129:1" }, { - "body": - { + "body": { "nativeSrc": "1255:229:1", "nodeType": "YulBlock", "src": "1255:229:1", - "statements": - [ + "statements": [ { - "body": - { + "body": { "nativeSrc": "1360:22:1", "nodeType": "YulBlock", "src": "1360:22:1", - "statements": - [ + "statements": [ { - "expression": - { + "expression": { "arguments": [], - "functionName": - { + "functionName": { "name": "panic_error_0x41", "nativeSrc": "1362:16:1", "nodeType": "YulIdentifier", @@ -849,10 +756,8 @@ } ] }, - "condition": - { - "arguments": - [ + "condition": { + "arguments": [ { "name": "length", "nativeSrc": "1332:6:1", @@ -868,8 +773,7 @@ "value": "0xffffffffffffffff" } ], - "functionName": - { + "functionName": { "name": "gt", "nativeSrc": "1329:2:1", "nodeType": "YulIdentifier", @@ -887,10 +791,8 @@ "nativeSrc": "1392:25:1", "nodeType": "YulAssignment", "src": "1392:25:1", - "value": - { - "arguments": - [ + "value": { + "arguments": [ { "name": "length", "nativeSrc": "1404:6:1", @@ -906,8 +808,7 @@ "value": "0x20" } ], - "functionName": - { + "functionName": { "name": "mul", "nativeSrc": "1400:3:1", "nodeType": "YulIdentifier", @@ -917,8 +818,7 @@ "nodeType": "YulFunctionCall", "src": "1400:17:1" }, - "variableNames": - [ + "variableNames": [ { "name": "size", "nativeSrc": "1392:4:1", @@ -931,10 +831,8 @@ "nativeSrc": "1454:23:1", "nodeType": "YulAssignment", "src": "1454:23:1", - "value": - { - "arguments": - [ + "value": { + "arguments": [ { "name": "size", "nativeSrc": "1466:4:1", @@ -950,8 +848,7 @@ "value": "0x20" } ], - "functionName": - { + "functionName": { "name": "add", "nativeSrc": "1462:3:1", "nodeType": "YulIdentifier", @@ -961,8 +858,7 @@ "nodeType": "YulFunctionCall", "src": "1462:15:1" }, - "variableNames": - [ + "variableNames": [ { "name": "size", "nativeSrc": "1454:4:1", @@ -976,8 +872,7 @@ "name": "array_allocation_size_t_array$_t_uint256_$dyn_memory_ptr", "nativeSrc": "1173:311:1", "nodeType": "YulFunctionDefinition", - "parameters": - [ + "parameters": [ { "name": "length", "nativeSrc": "1239:6:1", @@ -986,8 +881,7 @@ "type": "" } ], - "returnVariables": - [ + "returnVariables": [ { "name": "size", "nativeSrc": "1250:4:1", @@ -999,18 +893,14 @@ "src": "1173:311:1" }, { - "body": - { + "body": { "nativeSrc": "1579:28:1", "nodeType": "YulBlock", "src": "1579:28:1", - "statements": - [ + "statements": [ { - "expression": - { - "arguments": - [ + "expression": { + "arguments": [ { "kind": "number", "nativeSrc": "1596:1:1", @@ -1028,8 +918,7 @@ "value": "0" } ], - "functionName": - { + "functionName": { "name": "revert", "nativeSrc": "1589:6:1", "nodeType": "YulIdentifier", @@ -1051,26 +940,22 @@ "src": "1490:117:1" }, { - "body": - { + "body": { "nativeSrc": "1658:32:1", "nodeType": "YulBlock", "src": "1658:32:1", - "statements": - [ + "statements": [ { "nativeSrc": "1668:16:1", "nodeType": "YulAssignment", "src": "1668:16:1", - "value": - { + "value": { "name": "value", "nativeSrc": "1679:5:1", "nodeType": "YulIdentifier", "src": "1679:5:1" }, - "variableNames": - [ + "variableNames": [ { "name": "cleaned", "nativeSrc": "1668:7:1", @@ -1084,8 +969,7 @@ "name": "cleanup_t_uint256", "nativeSrc": "1613:77:1", "nodeType": "YulFunctionDefinition", - "parameters": - [ + "parameters": [ { "name": "value", "nativeSrc": "1640:5:1", @@ -1094,8 +978,7 @@ "type": "" } ], - "returnVariables": - [ + "returnVariables": [ { "name": "cleaned", "nativeSrc": "1650:7:1", @@ -1107,26 +990,20 @@ "src": "1613:77:1" }, { - "body": - { + "body": { "nativeSrc": "1739:79:1", "nodeType": "YulBlock", "src": "1739:79:1", - "statements": - [ + "statements": [ { - "body": - { + "body": { "nativeSrc": "1796:16:1", "nodeType": "YulBlock", "src": "1796:16:1", - "statements": - [ + "statements": [ { - "expression": - { - "arguments": - [ + "expression": { + "arguments": [ { "kind": "number", "nativeSrc": "1805:1:1", @@ -1144,8 +1021,7 @@ "value": "0" } ], - "functionName": - { + "functionName": { "name": "revert", "nativeSrc": "1798:6:1", "nodeType": "YulIdentifier", @@ -1161,13 +1037,10 @@ } ] }, - "condition": - { - "arguments": - [ + "condition": { + "arguments": [ { - "arguments": - [ + "arguments": [ { "name": "value", "nativeSrc": "1762:5:1", @@ -1175,8 +1048,7 @@ "src": "1762:5:1" }, { - "arguments": - [ + "arguments": [ { "name": "value", "nativeSrc": "1787:5:1", @@ -1184,8 +1056,7 @@ "src": "1787:5:1" } ], - "functionName": - { + "functionName": { "name": "cleanup_t_uint256", "nativeSrc": "1769:17:1", "nodeType": "YulIdentifier", @@ -1196,8 +1067,7 @@ "src": "1769:24:1" } ], - "functionName": - { + "functionName": { "name": "eq", "nativeSrc": "1759:2:1", "nodeType": "YulIdentifier", @@ -1208,8 +1078,7 @@ "src": "1759:35:1" } ], - "functionName": - { + "functionName": { "name": "iszero", "nativeSrc": "1752:6:1", "nodeType": "YulIdentifier", @@ -1228,8 +1097,7 @@ "name": "validator_revert_t_uint256", "nativeSrc": "1696:122:1", "nodeType": "YulFunctionDefinition", - "parameters": - [ + "parameters": [ { "name": "value", "nativeSrc": "1732:5:1", @@ -1241,21 +1109,17 @@ "src": "1696:122:1" }, { - "body": - { + "body": { "nativeSrc": "1876:87:1", "nodeType": "YulBlock", "src": "1876:87:1", - "statements": - [ + "statements": [ { "nativeSrc": "1886:29:1", "nodeType": "YulAssignment", "src": "1886:29:1", - "value": - { - "arguments": - [ + "value": { + "arguments": [ { "name": "offset", "nativeSrc": "1908:6:1", @@ -1263,8 +1127,7 @@ "src": "1908:6:1" } ], - "functionName": - { + "functionName": { "name": "calldataload", "nativeSrc": "1895:12:1", "nodeType": "YulIdentifier", @@ -1274,8 +1137,7 @@ "nodeType": "YulFunctionCall", "src": "1895:20:1" }, - "variableNames": - [ + "variableNames": [ { "name": "value", "nativeSrc": "1886:5:1", @@ -1285,10 +1147,8 @@ ] }, { - "expression": - { - "arguments": - [ + "expression": { + "arguments": [ { "name": "value", "nativeSrc": "1951:5:1", @@ -1296,8 +1156,7 @@ "src": "1951:5:1" } ], - "functionName": - { + "functionName": { "name": "validator_revert_t_uint256", "nativeSrc": "1924:26:1", "nodeType": "YulIdentifier", @@ -1316,8 +1175,7 @@ "name": "abi_decode_t_uint256", "nativeSrc": "1824:139:1", "nodeType": "YulFunctionDefinition", - "parameters": - [ + "parameters": [ { "name": "offset", "nativeSrc": "1854:6:1", @@ -1333,8 +1191,7 @@ "type": "" } ], - "returnVariables": - [ + "returnVariables": [ { "name": "value", "nativeSrc": "1870:5:1", @@ -1346,24 +1203,19 @@ "src": "1824:139:1" }, { - "body": - { + "body": { "nativeSrc": "2088:608:1", "nodeType": "YulBlock", "src": "2088:608:1", - "statements": - [ + "statements": [ { "nativeSrc": "2098:90:1", "nodeType": "YulAssignment", "src": "2098:90:1", - "value": - { - "arguments": - [ + "value": { + "arguments": [ { - "arguments": - [ + "arguments": [ { "name": "length", "nativeSrc": "2180:6:1", @@ -1371,8 +1223,7 @@ "src": "2180:6:1" } ], - "functionName": - { + "functionName": { "name": "array_allocation_size_t_array$_t_uint256_$dyn_memory_ptr", "nativeSrc": "2123:56:1", "nodeType": "YulIdentifier", @@ -1383,8 +1234,7 @@ "src": "2123:64:1" } ], - "functionName": - { + "functionName": { "name": "allocate_memory", "nativeSrc": "2107:15:1", "nodeType": "YulIdentifier", @@ -1394,8 +1244,7 @@ "nodeType": "YulFunctionCall", "src": "2107:81:1" }, - "variableNames": - [ + "variableNames": [ { "name": "array", "nativeSrc": "2098:5:1", @@ -1408,15 +1257,13 @@ "nativeSrc": "2197:16:1", "nodeType": "YulVariableDeclaration", "src": "2197:16:1", - "value": - { + "value": { "name": "array", "nativeSrc": "2208:5:1", "nodeType": "YulIdentifier", "src": "2208:5:1" }, - "variables": - [ + "variables": [ { "name": "dst", "nativeSrc": "2201:3:1", @@ -1427,10 +1274,8 @@ ] }, { - "expression": - { - "arguments": - [ + "expression": { + "arguments": [ { "name": "array", "nativeSrc": "2230:5:1", @@ -1444,8 +1289,7 @@ "src": "2237:6:1" } ], - "functionName": - { + "functionName": { "name": "mstore", "nativeSrc": "2223:6:1", "nodeType": "YulIdentifier", @@ -1463,10 +1307,8 @@ "nativeSrc": "2253:23:1", "nodeType": "YulAssignment", "src": "2253:23:1", - "value": - { - "arguments": - [ + "value": { + "arguments": [ { "name": "array", "nativeSrc": "2264:5:1", @@ -1482,8 +1324,7 @@ "value": "0x20" } ], - "functionName": - { + "functionName": { "name": "add", "nativeSrc": "2260:3:1", "nodeType": "YulIdentifier", @@ -1493,8 +1334,7 @@ "nodeType": "YulFunctionCall", "src": "2260:16:1" }, - "variableNames": - [ + "variableNames": [ { "name": "dst", "nativeSrc": "2253:3:1", @@ -1507,10 +1347,8 @@ "nativeSrc": "2286:44:1", "nodeType": "YulVariableDeclaration", "src": "2286:44:1", - "value": - { - "arguments": - [ + "value": { + "arguments": [ { "name": "offset", "nativeSrc": "2304:6:1", @@ -1518,8 +1356,7 @@ "src": "2304:6:1" }, { - "arguments": - [ + "arguments": [ { "name": "length", "nativeSrc": "2316:6:1", @@ -1535,8 +1372,7 @@ "value": "0x20" } ], - "functionName": - { + "functionName": { "name": "mul", "nativeSrc": "2312:3:1", "nodeType": "YulIdentifier", @@ -1547,8 +1383,7 @@ "src": "2312:17:1" } ], - "functionName": - { + "functionName": { "name": "add", "nativeSrc": "2300:3:1", "nodeType": "YulIdentifier", @@ -1558,8 +1393,7 @@ "nodeType": "YulFunctionCall", "src": "2300:30:1" }, - "variables": - [ + "variables": [ { "name": "srcEnd", "nativeSrc": "2290:6:1", @@ -1570,19 +1404,15 @@ ] }, { - "body": - { + "body": { "nativeSrc": "2358:103:1", "nodeType": "YulBlock", "src": "2358:103:1", - "statements": - [ + "statements": [ { - "expression": - { + "expression": { "arguments": [], - "functionName": - { + "functionName": { "name": "revert_error_81385d8c0b31fffe14be1da910c8bd3a80be4cfa248e04f42ec0faea3132a8ef", "nativeSrc": "2372:77:1", "nodeType": "YulIdentifier", @@ -1598,10 +1428,8 @@ } ] }, - "condition": - { - "arguments": - [ + "condition": { + "arguments": [ { "name": "srcEnd", "nativeSrc": "2345:6:1", @@ -1615,8 +1443,7 @@ "src": "2353:3:1" } ], - "functionName": - { + "functionName": { "name": "gt", "nativeSrc": "2342:2:1", "nodeType": "YulIdentifier", @@ -1631,26 +1458,22 @@ "src": "2339:122:1" }, { - "body": - { + "body": { "nativeSrc": "2546:144:1", "nodeType": "YulBlock", "src": "2546:144:1", - "statements": - [ + "statements": [ { "nativeSrc": "2561:21:1", "nodeType": "YulVariableDeclaration", "src": "2561:21:1", - "value": - { + "value": { "name": "src", "nativeSrc": "2579:3:1", "nodeType": "YulIdentifier", "src": "2579:3:1" }, - "variables": - [ + "variables": [ { "name": "elementPos", "nativeSrc": "2565:10:1", @@ -1661,10 +1484,8 @@ ] }, { - "expression": - { - "arguments": - [ + "expression": { + "arguments": [ { "name": "dst", "nativeSrc": "2603:3:1", @@ -1672,8 +1493,7 @@ "src": "2603:3:1" }, { - "arguments": - [ + "arguments": [ { "name": "elementPos", "nativeSrc": "2629:10:1", @@ -1687,8 +1507,7 @@ "src": "2641:3:1" } ], - "functionName": - { + "functionName": { "name": "abi_decode_t_uint256", "nativeSrc": "2608:20:1", "nodeType": "YulIdentifier", @@ -1699,8 +1518,7 @@ "src": "2608:37:1" } ], - "functionName": - { + "functionName": { "name": "mstore", "nativeSrc": "2596:6:1", "nodeType": "YulIdentifier", @@ -1718,10 +1536,8 @@ "nativeSrc": "2659:21:1", "nodeType": "YulAssignment", "src": "2659:21:1", - "value": - { - "arguments": - [ + "value": { + "arguments": [ { "name": "dst", "nativeSrc": "2670:3:1", @@ -1737,8 +1553,7 @@ "value": "0x20" } ], - "functionName": - { + "functionName": { "name": "add", "nativeSrc": "2666:3:1", "nodeType": "YulIdentifier", @@ -1748,8 +1563,7 @@ "nodeType": "YulFunctionCall", "src": "2666:14:1" }, - "variableNames": - [ + "variableNames": [ { "name": "dst", "nativeSrc": "2659:3:1", @@ -1760,10 +1574,8 @@ } ] }, - "condition": - { - "arguments": - [ + "condition": { + "arguments": [ { "name": "src", "nativeSrc": "2499:3:1", @@ -1777,8 +1589,7 @@ "src": "2504:6:1" } ], - "functionName": - { + "functionName": { "name": "lt", "nativeSrc": "2496:2:1", "nodeType": "YulIdentifier", @@ -1790,21 +1601,17 @@ }, "nativeSrc": "2470:220:1", "nodeType": "YulForLoop", - "post": - { + "post": { "nativeSrc": "2512:25:1", "nodeType": "YulBlock", "src": "2512:25:1", - "statements": - [ + "statements": [ { "nativeSrc": "2514:21:1", "nodeType": "YulAssignment", "src": "2514:21:1", - "value": - { - "arguments": - [ + "value": { + "arguments": [ { "name": "src", "nativeSrc": "2525:3:1", @@ -1820,8 +1627,7 @@ "value": "0x20" } ], - "functionName": - { + "functionName": { "name": "add", "nativeSrc": "2521:3:1", "nodeType": "YulIdentifier", @@ -1831,8 +1637,7 @@ "nodeType": "YulFunctionCall", "src": "2521:14:1" }, - "variableNames": - [ + "variableNames": [ { "name": "src", "nativeSrc": "2514:3:1", @@ -1843,26 +1648,22 @@ } ] }, - "pre": - { + "pre": { "nativeSrc": "2474:21:1", "nodeType": "YulBlock", "src": "2474:21:1", - "statements": - [ + "statements": [ { "nativeSrc": "2476:17:1", "nodeType": "YulVariableDeclaration", "src": "2476:17:1", - "value": - { + "value": { "name": "offset", "nativeSrc": "2487:6:1", "nodeType": "YulIdentifier", "src": "2487:6:1" }, - "variables": - [ + "variables": [ { "name": "src", "nativeSrc": "2480:3:1", @@ -1881,8 +1682,7 @@ "name": "abi_decode_available_length_t_array$_t_uint256_$dyn_memory_ptr", "nativeSrc": "1986:710:1", "nodeType": "YulFunctionDefinition", - "parameters": - [ + "parameters": [ { "name": "offset", "nativeSrc": "2058:6:1", @@ -1905,8 +1705,7 @@ "type": "" } ], - "returnVariables": - [ + "returnVariables": [ { "name": "array", "nativeSrc": "2082:5:1", @@ -1918,27 +1717,21 @@ "src": "1986:710:1" }, { - "body": - { + "body": { "nativeSrc": "2796:293:1", "nodeType": "YulBlock", "src": "2796:293:1", - "statements": - [ + "statements": [ { - "body": - { + "body": { "nativeSrc": "2845:83:1", "nodeType": "YulBlock", "src": "2845:83:1", - "statements": - [ + "statements": [ { - "expression": - { + "expression": { "arguments": [], - "functionName": - { + "functionName": { "name": "revert_error_1b9f4a0a5773e33b91aa01db23bf8c55fce1411167c872835e7fa00a4f17d46d", "nativeSrc": "2847:77:1", "nodeType": "YulIdentifier", @@ -1954,16 +1747,12 @@ } ] }, - "condition": - { - "arguments": - [ + "condition": { + "arguments": [ { - "arguments": - [ + "arguments": [ { - "arguments": - [ + "arguments": [ { "name": "offset", "nativeSrc": "2824:6:1", @@ -1979,8 +1768,7 @@ "value": "0x1f" } ], - "functionName": - { + "functionName": { "name": "add", "nativeSrc": "2820:3:1", "nodeType": "YulIdentifier", @@ -1997,8 +1785,7 @@ "src": "2839:3:1" } ], - "functionName": - { + "functionName": { "name": "slt", "nativeSrc": "2816:3:1", "nodeType": "YulIdentifier", @@ -2009,8 +1796,7 @@ "src": "2816:27:1" } ], - "functionName": - { + "functionName": { "name": "iszero", "nativeSrc": "2809:6:1", "nodeType": "YulIdentifier", @@ -2028,10 +1814,8 @@ "nativeSrc": "2937:34:1", "nodeType": "YulVariableDeclaration", "src": "2937:34:1", - "value": - { - "arguments": - [ + "value": { + "arguments": [ { "name": "offset", "nativeSrc": "2964:6:1", @@ -2039,8 +1823,7 @@ "src": "2964:6:1" } ], - "functionName": - { + "functionName": { "name": "calldataload", "nativeSrc": "2951:12:1", "nodeType": "YulIdentifier", @@ -2050,8 +1833,7 @@ "nodeType": "YulFunctionCall", "src": "2951:20:1" }, - "variables": - [ + "variables": [ { "name": "length", "nativeSrc": "2941:6:1", @@ -2065,13 +1847,10 @@ "nativeSrc": "2980:103:1", "nodeType": "YulAssignment", "src": "2980:103:1", - "value": - { - "arguments": - [ + "value": { + "arguments": [ { - "arguments": - [ + "arguments": [ { "name": "offset", "nativeSrc": "3056:6:1", @@ -2087,8 +1866,7 @@ "value": "0x20" } ], - "functionName": - { + "functionName": { "name": "add", "nativeSrc": "3052:3:1", "nodeType": "YulIdentifier", @@ -2111,8 +1889,7 @@ "src": "3079:3:1" } ], - "functionName": - { + "functionName": { "name": "abi_decode_available_length_t_array$_t_uint256_$dyn_memory_ptr", "nativeSrc": "2989:62:1", "nodeType": "YulIdentifier", @@ -2122,8 +1899,7 @@ "nodeType": "YulFunctionCall", "src": "2989:94:1" }, - "variableNames": - [ + "variableNames": [ { "name": "array", "nativeSrc": "2980:5:1", @@ -2137,8 +1913,7 @@ "name": "abi_decode_t_array$_t_uint256_$dyn_memory_ptr", "nativeSrc": "2719:370:1", "nodeType": "YulFunctionDefinition", - "parameters": - [ + "parameters": [ { "name": "offset", "nativeSrc": "2774:6:1", @@ -2154,8 +1929,7 @@ "type": "" } ], - "returnVariables": - [ + "returnVariables": [ { "name": "array", "nativeSrc": "2790:5:1", @@ -2167,27 +1941,21 @@ "src": "2719:370:1" }, { - "body": - { + "body": { "nativeSrc": "3186:448:1", "nodeType": "YulBlock", "src": "3186:448:1", - "statements": - [ + "statements": [ { - "body": - { + "body": { "nativeSrc": "3232:83:1", "nodeType": "YulBlock", "src": "3232:83:1", - "statements": - [ + "statements": [ { - "expression": - { + "expression": { "arguments": [], - "functionName": - { + "functionName": { "name": "revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b", "nativeSrc": "3234:77:1", "nodeType": "YulIdentifier", @@ -2203,13 +1971,10 @@ } ] }, - "condition": - { - "arguments": - [ + "condition": { + "arguments": [ { - "arguments": - [ + "arguments": [ { "name": "dataEnd", "nativeSrc": "3207:7:1", @@ -2223,8 +1988,7 @@ "src": "3216:9:1" } ], - "functionName": - { + "functionName": { "name": "sub", "nativeSrc": "3203:3:1", "nodeType": "YulIdentifier", @@ -2243,8 +2007,7 @@ "value": "32" } ], - "functionName": - { + "functionName": { "name": "slt", "nativeSrc": "3199:3:1", "nodeType": "YulIdentifier", @@ -2262,19 +2025,15 @@ "nativeSrc": "3325:302:1", "nodeType": "YulBlock", "src": "3325:302:1", - "statements": - [ + "statements": [ { "nativeSrc": "3340:45:1", "nodeType": "YulVariableDeclaration", "src": "3340:45:1", - "value": - { - "arguments": - [ + "value": { + "arguments": [ { - "arguments": - [ + "arguments": [ { "name": "headStart", "nativeSrc": "3371:9:1", @@ -2290,8 +2049,7 @@ "value": "0" } ], - "functionName": - { + "functionName": { "name": "add", "nativeSrc": "3367:3:1", "nodeType": "YulIdentifier", @@ -2302,8 +2060,7 @@ "src": "3367:17:1" } ], - "functionName": - { + "functionName": { "name": "calldataload", "nativeSrc": "3354:12:1", "nodeType": "YulIdentifier", @@ -2313,8 +2070,7 @@ "nodeType": "YulFunctionCall", "src": "3354:31:1" }, - "variables": - [ + "variables": [ { "name": "offset", "nativeSrc": "3344:6:1", @@ -2325,19 +2081,15 @@ ] }, { - "body": - { + "body": { "nativeSrc": "3432:83:1", "nodeType": "YulBlock", "src": "3432:83:1", - "statements": - [ + "statements": [ { - "expression": - { + "expression": { "arguments": [], - "functionName": - { + "functionName": { "name": "revert_error_c1322bf8034eace5e0b5c7295db60986aa89aae5e0ea0873e4689e076861a5db", "nativeSrc": "3434:77:1", "nodeType": "YulIdentifier", @@ -2353,10 +2105,8 @@ } ] }, - "condition": - { - "arguments": - [ + "condition": { + "arguments": [ { "name": "offset", "nativeSrc": "3404:6:1", @@ -2372,8 +2122,7 @@ "value": "0xffffffffffffffff" } ], - "functionName": - { + "functionName": { "name": "gt", "nativeSrc": "3401:2:1", "nodeType": "YulIdentifier", @@ -2391,13 +2140,10 @@ "nativeSrc": "3529:88:1", "nodeType": "YulAssignment", "src": "3529:88:1", - "value": - { - "arguments": - [ + "value": { + "arguments": [ { - "arguments": - [ + "arguments": [ { "name": "headStart", "nativeSrc": "3589:9:1", @@ -2411,8 +2157,7 @@ "src": "3600:6:1" } ], - "functionName": - { + "functionName": { "name": "add", "nativeSrc": "3585:3:1", "nodeType": "YulIdentifier", @@ -2429,8 +2174,7 @@ "src": "3609:7:1" } ], - "functionName": - { + "functionName": { "name": "abi_decode_t_array$_t_uint256_$dyn_memory_ptr", "nativeSrc": "3539:45:1", "nodeType": "YulIdentifier", @@ -2440,8 +2184,7 @@ "nodeType": "YulFunctionCall", "src": "3539:78:1" }, - "variableNames": - [ + "variableNames": [ { "name": "value0", "nativeSrc": "3529:6:1", @@ -2457,8 +2200,7 @@ "name": "abi_decode_tuple_t_array$_t_uint256_$dyn_memory_ptr", "nativeSrc": "3095:539:1", "nodeType": "YulFunctionDefinition", - "parameters": - [ + "parameters": [ { "name": "headStart", "nativeSrc": "3156:9:1", @@ -2474,8 +2216,7 @@ "type": "" } ], - "returnVariables": - [ + "returnVariables": [ { "name": "value0", "nativeSrc": "3179:6:1", @@ -2487,18 +2228,14 @@ "src": "3095:539:1" }, { - "body": - { + "body": { "nativeSrc": "3705:53:1", "nodeType": "YulBlock", "src": "3705:53:1", - "statements": - [ + "statements": [ { - "expression": - { - "arguments": - [ + "expression": { + "arguments": [ { "name": "pos", "nativeSrc": "3722:3:1", @@ -2506,8 +2243,7 @@ "src": "3722:3:1" }, { - "arguments": - [ + "arguments": [ { "name": "value", "nativeSrc": "3745:5:1", @@ -2515,8 +2251,7 @@ "src": "3745:5:1" } ], - "functionName": - { + "functionName": { "name": "cleanup_t_uint256", "nativeSrc": "3727:17:1", "nodeType": "YulIdentifier", @@ -2527,8 +2262,7 @@ "src": "3727:24:1" } ], - "functionName": - { + "functionName": { "name": "mstore", "nativeSrc": "3715:6:1", "nodeType": "YulIdentifier", @@ -2547,8 +2281,7 @@ "name": "abi_encode_t_uint256_to_t_uint256_fromStack", "nativeSrc": "3640:118:1", "nodeType": "YulFunctionDefinition", - "parameters": - [ + "parameters": [ { "name": "value", "nativeSrc": "3693:5:1", @@ -2567,21 +2300,17 @@ "src": "3640:118:1" }, { - "body": - { + "body": { "nativeSrc": "3862:124:1", "nodeType": "YulBlock", "src": "3862:124:1", - "statements": - [ + "statements": [ { "nativeSrc": "3872:26:1", "nodeType": "YulAssignment", "src": "3872:26:1", - "value": - { - "arguments": - [ + "value": { + "arguments": [ { "name": "headStart", "nativeSrc": "3884:9:1", @@ -2597,8 +2326,7 @@ "value": "32" } ], - "functionName": - { + "functionName": { "name": "add", "nativeSrc": "3880:3:1", "nodeType": "YulIdentifier", @@ -2608,8 +2336,7 @@ "nodeType": "YulFunctionCall", "src": "3880:18:1" }, - "variableNames": - [ + "variableNames": [ { "name": "tail", "nativeSrc": "3872:4:1", @@ -2619,10 +2346,8 @@ ] }, { - "expression": - { - "arguments": - [ + "expression": { + "arguments": [ { "name": "value0", "nativeSrc": "3952:6:1", @@ -2630,8 +2355,7 @@ "src": "3952:6:1" }, { - "arguments": - [ + "arguments": [ { "name": "headStart", "nativeSrc": "3965:9:1", @@ -2647,8 +2371,7 @@ "value": "0" } ], - "functionName": - { + "functionName": { "name": "add", "nativeSrc": "3961:3:1", "nodeType": "YulIdentifier", @@ -2659,8 +2382,7 @@ "src": "3961:17:1" } ], - "functionName": - { + "functionName": { "name": "abi_encode_t_uint256_to_t_uint256_fromStack", "nativeSrc": "3908:43:1", "nodeType": "YulIdentifier", @@ -2679,8 +2401,7 @@ "name": "abi_encode_tuple_t_uint256__to_t_uint256__fromStack_reversed", "nativeSrc": "3764:222:1", "nodeType": "YulFunctionDefinition", - "parameters": - [ + "parameters": [ { "name": "headStart", "nativeSrc": "3834:9:1", @@ -2696,8 +2417,7 @@ "type": "" } ], - "returnVariables": - [ + "returnVariables": [ { "name": "tail", "nativeSrc": "3857:4:1", @@ -2843,8 +2563,7 @@ } } }, - "errors": - [ + "errors": [ { "component": "general", "errorCode": "3420", @@ -2854,8 +2573,7 @@ ", "message": "Source file does not specify required compiler version!", "severity": "warning", - "sourceLocation": - { + "sourceLocation": { "end": -1, "file": "a.sol", "start": -1 @@ -2863,10 +2581,8 @@ "type": "Warning" } ], - "sources": - { - "a.sol": - { + "sources": { + "a.sol": { "id": 0 } } diff --git a/test/cmdlineTests/standard_immutable_references/output.json b/test/cmdlineTests/standard_immutable_references/output.json index e25a911fff6e..cfa087bce500 100644 --- a/test/cmdlineTests/standard_immutable_references/output.json +++ b/test/cmdlineTests/standard_immutable_references/output.json @@ -1,18 +1,11 @@ { - "contracts": - { - "a.sol": - { - "A": - { - "evm": - { - "deployedBytecode": - { - "immutableReferences": - { - "6": - [ + "contracts": { + "a.sol": { + "A": { + "evm": { + "deployedBytecode": { + "immutableReferences": { + "6": [ { "length": 32, "start": 75 @@ -24,10 +17,8 @@ } } }, - "sources": - { - "a.sol": - { + "sources": { + "a.sol": { "id": 0 } } diff --git a/test/cmdlineTests/standard_import_asm_json/output.json b/test/cmdlineTests/standard_import_asm_json/output.json index 5b7cdf3bb9d4..1db28796071a 100644 --- a/test/cmdlineTests/standard_import_asm_json/output.json +++ b/test/cmdlineTests/standard_import_asm_json/output.json @@ -1,25 +1,19 @@ { - "contracts": - { - "A": - { - "": - { - "evm": - { + "contracts": { + "A": { + "": { + "evm": { "assembly": " /* \"\":36:51 */ 0x00 ", - "bytecode": - { + "bytecode": { "functionDebugData": {}, "linkReferences": {}, "object": "", "opcodes":"", "sourceMap":"" }, - "deployedBytecode": - { + "deployedBytecode": { "functionDebugData": {}, "immutableReferences": {}, "linkReferences": {}, @@ -27,10 +21,8 @@ "opcodes": "", "sourceMap": "" }, - "legacyAssembly": - { - ".code": - [ + "legacyAssembly": { + ".code": [ { "begin": 36, "end": 51, @@ -39,8 +31,7 @@ "value": "0" } ], - "sourceList": - [ + "sourceList": [ "" ] } diff --git a/test/cmdlineTests/standard_import_asm_json_immutable_references/output.json b/test/cmdlineTests/standard_import_asm_json_immutable_references/output.json index 05a6ff7d5eca..f0554d8c602b 100644 --- a/test/cmdlineTests/standard_import_asm_json_immutable_references/output.json +++ b/test/cmdlineTests/standard_import_asm_json_immutable_references/output.json @@ -1,27 +1,19 @@ { - "contracts": - { - "A": - { - "": - { - "evm": - { - "bytecode": - { + "contracts": { + "A": { + "": { + "evm": { + "bytecode": { "functionDebugData": {}, "linkReferences": {}, "object": "", "opcodes":"", "sourceMap":"" }, - "deployedBytecode": - { + "deployedBytecode": { "functionDebugData": {}, - "immutableReferences": - { - "6": - [ + "immutableReferences": { + "6": [ { "length": 32, "start": 1 diff --git a/test/cmdlineTests/standard_import_asm_json_invalid_input_array/output.json b/test/cmdlineTests/standard_import_asm_json_invalid_input_array/output.json index 2a075efd02ae..489a41933198 100644 --- a/test/cmdlineTests/standard_import_asm_json_invalid_input_array/output.json +++ b/test/cmdlineTests/standard_import_asm_json_invalid_input_array/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "formattedMessage": "Invalid input source specified. Expected exactly one object, named 'assemblyJson', inside $.sources.A", diff --git a/test/cmdlineTests/standard_import_asm_json_invalid_key_inside_source/output.json b/test/cmdlineTests/standard_import_asm_json_invalid_key_inside_source/output.json index 2a075efd02ae..489a41933198 100644 --- a/test/cmdlineTests/standard_import_asm_json_invalid_key_inside_source/output.json +++ b/test/cmdlineTests/standard_import_asm_json_invalid_key_inside_source/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "formattedMessage": "Invalid input source specified. Expected exactly one object, named 'assemblyJson', inside $.sources.A", diff --git a/test/cmdlineTests/standard_import_asm_json_invalid_key_other_source/output.json b/test/cmdlineTests/standard_import_asm_json_invalid_key_other_source/output.json index 2a075efd02ae..489a41933198 100644 --- a/test/cmdlineTests/standard_import_asm_json_invalid_key_other_source/output.json +++ b/test/cmdlineTests/standard_import_asm_json_invalid_key_other_source/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "formattedMessage": "Invalid input source specified. Expected exactly one object, named 'assemblyJson', inside $.sources.A", diff --git a/test/cmdlineTests/standard_import_asm_json_invalid_no_source/output.json b/test/cmdlineTests/standard_import_asm_json_invalid_no_source/output.json index 3495a7411d9e..135ec60dea2d 100644 --- a/test/cmdlineTests/standard_import_asm_json_invalid_no_source/output.json +++ b/test/cmdlineTests/standard_import_asm_json_invalid_no_source/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "formattedMessage": "No input sources specified.", diff --git a/test/cmdlineTests/standard_import_asm_json_invalid_opcode/output.json b/test/cmdlineTests/standard_import_asm_json_invalid_opcode/output.json index 6314f8b05693..cccd241d9416 100644 --- a/test/cmdlineTests/standard_import_asm_json_invalid_opcode/output.json +++ b/test/cmdlineTests/standard_import_asm_json_invalid_opcode/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "formattedMessage": "Assembly import error: InvalidOpcode", diff --git a/test/cmdlineTests/standard_import_asm_json_invalid_two_sources/output.json b/test/cmdlineTests/standard_import_asm_json_invalid_two_sources/output.json index affe4c34e651..9e85128bbdc4 100644 --- a/test/cmdlineTests/standard_import_asm_json_invalid_two_sources/output.json +++ b/test/cmdlineTests/standard_import_asm_json_invalid_two_sources/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "formattedMessage": "EVMAssembly import only supports exactly one input file.", diff --git a/test/cmdlineTests/standard_import_asm_json_link_references/output.json b/test/cmdlineTests/standard_import_asm_json_link_references/output.json index 864f65a53f70..fed476e620c5 100644 --- a/test/cmdlineTests/standard_import_asm_json_link_references/output.json +++ b/test/cmdlineTests/standard_import_asm_json_link_references/output.json @@ -1,30 +1,21 @@ { - "contracts": - { - "A": - { - "": - { - "evm": - { - "bytecode": - { + "contracts": { + "A": { + "": { + "evm": { + "bytecode": { "functionDebugData": {}, "linkReferences": {}, "object": "", "opcodes":"", "sourceMap": "" }, - "deployedBytecode": - { + "deployedBytecode": { "functionDebugData": {}, "immutableReferences": {}, - "linkReferences": - { - "test.sol": - { - "L": - [ + "linkReferences": { + "test.sol": { + "L": [ { "length": 20, "start": 1 diff --git a/test/cmdlineTests/standard_import_asm_json_multiple_keys_inside_source/output.json b/test/cmdlineTests/standard_import_asm_json_multiple_keys_inside_source/output.json index 2a075efd02ae..489a41933198 100644 --- a/test/cmdlineTests/standard_import_asm_json_multiple_keys_inside_source/output.json +++ b/test/cmdlineTests/standard_import_asm_json_multiple_keys_inside_source/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "formattedMessage": "Invalid input source specified. Expected exactly one object, named 'assemblyJson', inside $.sources.A", diff --git a/test/cmdlineTests/standard_import_ast/output.json b/test/cmdlineTests/standard_import_ast/output.json index 6ecac5ca364d..d54da1750bc8 100644 --- a/test/cmdlineTests/standard_import_ast/output.json +++ b/test/cmdlineTests/standard_import_ast/output.json @@ -1,27 +1,20 @@ { - "sources": - { - "A": - { - "ast": - { + "sources": { + "A": { + "ast": { "absolutePath": "A", - "exportedSymbols": - { - "C": - [ + "exportedSymbols": { + "C": [ 6 ] }, "id": 7, "license": "GPL-3.0", "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "id": 1, - "literals": - [ + "literals": [ "solidity", ">=", "0.0" @@ -37,18 +30,15 @@ "contractKind": "contract", "fullyImplemented": true, "id": 6, - "linearizedBaseContracts": - [ + "linearizedBaseContracts": [ 6 ], "name": "C", "nameLocation": "68:1:0", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { - "body": - { + "body": { "id": 4, "nodeType": "Block", "src": "97:2:0", @@ -62,15 +52,13 @@ "name": "f", "nameLocation": "81:1:0", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 2, "nodeType": "ParameterList", "parameters": [], "src": "82:2:0" }, - "returnParameters": - { + "returnParameters": { "id": 3, "nodeType": "ParameterList", "parameters": [], diff --git a/test/cmdlineTests/standard_import_ast_select_bytecode/output.json b/test/cmdlineTests/standard_import_ast_select_bytecode/output.json index 0fca3f2715a3..c060efd971a7 100644 --- a/test/cmdlineTests/standard_import_ast_select_bytecode/output.json +++ b/test/cmdlineTests/standard_import_ast_select_bytecode/output.json @@ -1,14 +1,9 @@ { - "contracts": - { - "A": - { - "test": - { - "evm": - { - "bytecode": - { + "contracts": { + "A": { + "test": { + "evm": { + "bytecode": { "functionDebugData": {}, "generatedSources": [], "linkReferences": {}, @@ -20,10 +15,8 @@ } } }, - "sources": - { - "A": - { + "sources": { + "A": { "id": 0 } } diff --git a/test/cmdlineTests/standard_import_with_comments/output.json b/test/cmdlineTests/standard_import_with_comments/output.json index 6ecac5ca364d..d54da1750bc8 100644 --- a/test/cmdlineTests/standard_import_with_comments/output.json +++ b/test/cmdlineTests/standard_import_with_comments/output.json @@ -1,27 +1,20 @@ { - "sources": - { - "A": - { - "ast": - { + "sources": { + "A": { + "ast": { "absolutePath": "A", - "exportedSymbols": - { - "C": - [ + "exportedSymbols": { + "C": [ 6 ] }, "id": 7, "license": "GPL-3.0", "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "id": 1, - "literals": - [ + "literals": [ "solidity", ">=", "0.0" @@ -37,18 +30,15 @@ "contractKind": "contract", "fullyImplemented": true, "id": 6, - "linearizedBaseContracts": - [ + "linearizedBaseContracts": [ 6 ], "name": "C", "nameLocation": "68:1:0", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { - "body": - { + "body": { "id": 4, "nodeType": "Block", "src": "97:2:0", @@ -62,15 +52,13 @@ "name": "f", "nameLocation": "81:1:0", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 2, "nodeType": "ParameterList", "parameters": [], "src": "82:2:0" }, - "returnParameters": - { + "returnParameters": { "id": 3, "nodeType": "ParameterList", "parameters": [], diff --git a/test/cmdlineTests/standard_import_with_comments_simple/output.json b/test/cmdlineTests/standard_import_with_comments_simple/output.json index 6ecac5ca364d..d54da1750bc8 100644 --- a/test/cmdlineTests/standard_import_with_comments_simple/output.json +++ b/test/cmdlineTests/standard_import_with_comments_simple/output.json @@ -1,27 +1,20 @@ { - "sources": - { - "A": - { - "ast": - { + "sources": { + "A": { + "ast": { "absolutePath": "A", - "exportedSymbols": - { - "C": - [ + "exportedSymbols": { + "C": [ 6 ] }, "id": 7, "license": "GPL-3.0", "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "id": 1, - "literals": - [ + "literals": [ "solidity", ">=", "0.0" @@ -37,18 +30,15 @@ "contractKind": "contract", "fullyImplemented": true, "id": 6, - "linearizedBaseContracts": - [ + "linearizedBaseContracts": [ 6 ], "name": "C", "nameLocation": "68:1:0", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { - "body": - { + "body": { "id": 4, "nodeType": "Block", "src": "97:2:0", @@ -62,15 +52,13 @@ "name": "f", "nameLocation": "81:1:0", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 2, "nodeType": "ParameterList", "parameters": [], "src": "82:2:0" }, - "returnParameters": - { + "returnParameters": { "id": 3, "nodeType": "ParameterList", "parameters": [], diff --git a/test/cmdlineTests/standard_import_with_invalid_utf8/output.json b/test/cmdlineTests/standard_import_with_invalid_utf8/output.json index 057e4fe169c6..e168f8797b06 100644 --- a/test/cmdlineTests/standard_import_with_invalid_utf8/output.json +++ b/test/cmdlineTests/standard_import_with_invalid_utf8/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "formattedMessage": "parse error at line 12, column 23: syntax error while parsing value - invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF; last read: '\"\\ud800\"'", diff --git a/test/cmdlineTests/standard_irOptimized_ast_requested/output.json b/test/cmdlineTests/standard_irOptimized_ast_requested/output.json index 200b653ff443..91d0e87f3619 100644 --- a/test/cmdlineTests/standard_irOptimized_ast_requested/output.json +++ b/test/cmdlineTests/standard_irOptimized_ast_requested/output.json @@ -1,32 +1,22 @@ { - "contracts": - { - "C": - { - "C": - { - "irOptimizedAst": - { - "code": - { - "block": - { + "contracts": { + "C": { + "C": { + "irOptimizedAst": { + "code": { + "block": { "nativeSrc": "44:790:0", "nodeType": "YulBlock", "src": "-1:-1:0", - "statements": - [ + "statements": [ { "nativeSrc": "44:790:0", "nodeType": "YulBlock", "src": "-1:-1:0", - "statements": - [ + "statements": [ { - "expression": - { - "arguments": - [ + "expression": { + "arguments": [ { "kind": "number", "nativeSrc": "103:2:0", @@ -36,8 +26,7 @@ "value": "64" }, { - "arguments": - [ + "arguments": [ { "kind": "number", "nativeSrc": "119:3:0", @@ -47,8 +36,7 @@ "value": "0x80" } ], - "functionName": - { + "functionName": { "name": "memoryguard", "nativeSrc": "107:11:0", "nodeType": "YulIdentifier", @@ -59,8 +47,7 @@ "src": "56:13:0" } ], - "functionName": - { + "functionName": { "name": "mstore", "nativeSrc": "96:6:0", "nodeType": "YulIdentifier", @@ -75,19 +62,15 @@ "src": "56:13:0" }, { - "body": - { + "body": { "nativeSrc": "148:83:0", "nodeType": "YulBlock", "src": "56:13:0", - "statements": - [ + "statements": [ { - "expression": - { + "expression": { "arguments": [], - "functionName": - { + "functionName": { "name": "revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb", "nativeSrc": "150:77:0", "nodeType": "YulIdentifier", @@ -103,11 +86,9 @@ } ] }, - "condition": - { + "condition": { "arguments": [], - "functionName": - { + "functionName": { "name": "callvalue", "nativeSrc": "136:9:0", "nodeType": "YulIdentifier", @@ -125,11 +106,9 @@ "nativeSrc": "268:30:0", "nodeType": "YulVariableDeclaration", "src": "56:13:0", - "value": - { + "value": { "arguments": [], - "functionName": - { + "functionName": { "name": "allocate_unbounded", "nativeSrc": "278:18:0", "nodeType": "YulIdentifier", @@ -139,8 +118,7 @@ "nodeType": "YulFunctionCall", "src": "56:13:0" }, - "variables": - [ + "variables": [ { "name": "_1", "nativeSrc": "272:2:0", @@ -151,10 +129,8 @@ ] }, { - "expression": - { - "arguments": - [ + "expression": { + "arguments": [ { "name": "_1", "nativeSrc": "316:2:0", @@ -162,8 +138,7 @@ "src": "56:13:0" }, { - "arguments": - [ + "arguments": [ { "hexValue": "435f325f6465706c6f796564", "kind": "string", @@ -174,8 +149,7 @@ "value": "C_2_deployed" } ], - "functionName": - { + "functionName": { "name": "dataoffset", "nativeSrc": "320:10:0", "nodeType": "YulIdentifier", @@ -186,8 +160,7 @@ "src": "56:13:0" }, { - "arguments": - [ + "arguments": [ { "hexValue": "435f325f6465706c6f796564", "kind": "string", @@ -198,8 +171,7 @@ "value": "C_2_deployed" } ], - "functionName": - { + "functionName": { "name": "datasize", "nativeSrc": "348:8:0", "nodeType": "YulIdentifier", @@ -210,8 +182,7 @@ "src": "56:13:0" } ], - "functionName": - { + "functionName": { "name": "codecopy", "nativeSrc": "307:8:0", "nodeType": "YulIdentifier", @@ -226,10 +197,8 @@ "src": "56:13:0" }, { - "expression": - { - "arguments": - [ + "expression": { + "arguments": [ { "name": "_1", "nativeSrc": "390:2:0", @@ -237,8 +206,7 @@ "src": "56:13:0" }, { - "arguments": - [ + "arguments": [ { "hexValue": "435f325f6465706c6f796564", "kind": "string", @@ -249,8 +217,7 @@ "value": "C_2_deployed" } ], - "functionName": - { + "functionName": { "name": "datasize", "nativeSrc": "394:8:0", "nodeType": "YulIdentifier", @@ -261,8 +228,7 @@ "src": "56:13:0" } ], - "functionName": - { + "functionName": { "name": "return", "nativeSrc": "383:6:0", "nodeType": "YulIdentifier", @@ -279,21 +245,17 @@ ] }, { - "body": - { + "body": { "nativeSrc": "469:43:0", "nodeType": "YulBlock", "src": "56:13:0", - "statements": - [ + "statements": [ { "nativeSrc": "483:19:0", "nodeType": "YulAssignment", "src": "56:13:0", - "value": - { - "arguments": - [ + "value": { + "arguments": [ { "kind": "number", "nativeSrc": "499:2:0", @@ -303,8 +265,7 @@ "value": "64" } ], - "functionName": - { + "functionName": { "name": "mload", "nativeSrc": "493:5:0", "nodeType": "YulIdentifier", @@ -314,8 +275,7 @@ "nodeType": "YulFunctionCall", "src": "56:13:0" }, - "variableNames": - [ + "variableNames": [ { "name": "memPtr", "nativeSrc": "483:6:0", @@ -329,8 +289,7 @@ "name": "allocate_unbounded", "nativeSrc": "429:83:0", "nodeType": "YulFunctionDefinition", - "returnVariables": - [ + "returnVariables": [ { "name": "memPtr", "nativeSrc": "462:6:0", @@ -342,18 +301,14 @@ "src": "56:13:0" }, { - "body": - { + "body": { "nativeSrc": "611:36:0", "nodeType": "YulBlock", "src": "56:13:0", - "statements": - [ + "statements": [ { - "expression": - { - "arguments": - [ + "expression": { + "arguments": [ { "kind": "number", "nativeSrc": "632:1:0", @@ -371,8 +326,7 @@ "value": "0" } ], - "functionName": - { + "functionName": { "name": "revert", "nativeSrc": "625:6:0", "nodeType": "YulIdentifier", @@ -399,29 +353,22 @@ }, "name": "C_2", "nodeType": "YulObject", - "subObjects": - [ + "subObjects": [ { - "code": - { - "block": - { + "code": { + "block": { "nativeSrc": "899:588:0", "nodeType": "YulBlock", "src": "-1:-1:0", - "statements": - [ + "statements": [ { "nativeSrc": "899:588:0", "nodeType": "YulBlock", "src": "-1:-1:0", - "statements": - [ + "statements": [ { - "expression": - { - "arguments": - [ + "expression": { + "arguments": [ { "kind": "number", "nativeSrc": "966:2:0", @@ -431,8 +378,7 @@ "value": "64" }, { - "arguments": - [ + "arguments": [ { "kind": "number", "nativeSrc": "982:3:0", @@ -442,8 +388,7 @@ "value": "0x80" } ], - "functionName": - { + "functionName": { "name": "memoryguard", "nativeSrc": "970:11:0", "nodeType": "YulIdentifier", @@ -454,8 +399,7 @@ "src": "56:13:0" } ], - "functionName": - { + "functionName": { "name": "mstore", "nativeSrc": "959:6:0", "nodeType": "YulIdentifier", @@ -470,11 +414,9 @@ "src": "56:13:0" }, { - "expression": - { + "expression": { "arguments": [], - "functionName": - { + "functionName": { "name": "revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74", "nativeSrc": "1001:77:0", "nodeType": "YulIdentifier", @@ -491,18 +433,14 @@ ] }, { - "body": - { + "body": { "nativeSrc": "1432:44:0", "nodeType": "YulBlock", "src": "56:13:0", - "statements": - [ + "statements": [ { - "expression": - { - "arguments": - [ + "expression": { + "arguments": [ { "kind": "number", "nativeSrc": "1457:1:0", @@ -520,8 +458,7 @@ "value": "0" } ], - "functionName": - { + "functionName": { "name": "revert", "nativeSrc": "1450:6:0", "nodeType": "YulIdentifier", @@ -548,8 +485,7 @@ }, "name": "C_2_deployed", "nodeType": "YulObject", - "subObjects": - [ + "subObjects": [ { "nodeType": "YulData", "value": "" @@ -561,10 +497,8 @@ } } }, - "sources": - { - "C": - { + "sources": { + "C": { "id": 0 } } diff --git a/test/cmdlineTests/standard_irOptimized_requested/output.json b/test/cmdlineTests/standard_irOptimized_requested/output.json index 88ce6489578e..849b436b24a5 100644 --- a/test/cmdlineTests/standard_irOptimized_requested/output.json +++ b/test/cmdlineTests/standard_irOptimized_requested/output.json @@ -1,10 +1,7 @@ { - "contracts": - { - "A": - { - "C": - { + "contracts": { + "A": { + "C": { "irOptimized": "/// @use-src 0:\"A\" object \"C_7\" { code { @@ -77,10 +74,8 @@ object \"C_7\" { } } }, - "sources": - { - "A": - { + "sources": { + "A": { "id": 0 } } diff --git a/test/cmdlineTests/standard_ir_ast_requested/output.json b/test/cmdlineTests/standard_ir_ast_requested/output.json index f949d7b30cb2..b2e1c0c7dd39 100644 --- a/test/cmdlineTests/standard_ir_ast_requested/output.json +++ b/test/cmdlineTests/standard_ir_ast_requested/output.json @@ -1,26 +1,17 @@ { - "contracts": - { - "C": - { - "C": - { - "irAst": - { - "code": - { - "block": - { + "contracts": { + "C": { + "C": { + "irAst": { + "code": { + "block": { "nativeSrc": "44:790:0", "nodeType": "YulBlock", "src": "-1:-1:0", - "statements": - [ + "statements": [ { - "expression": - { - "arguments": - [ + "expression": { + "arguments": [ { "kind": "number", "nativeSrc": "103:2:0", @@ -30,8 +21,7 @@ "value": "64" }, { - "arguments": - [ + "arguments": [ { "kind": "number", "nativeSrc": "119:3:0", @@ -41,8 +31,7 @@ "value": "128" } ], - "functionName": - { + "functionName": { "name": "memoryguard", "nativeSrc": "107:11:0", "nodeType": "YulIdentifier", @@ -53,8 +42,7 @@ "src": "56:13:0" } ], - "functionName": - { + "functionName": { "name": "mstore", "nativeSrc": "96:6:0", "nodeType": "YulIdentifier", @@ -69,19 +57,15 @@ "src": "56:13:0" }, { - "body": - { + "body": { "nativeSrc": "148:83:0", "nodeType": "YulBlock", "src": "56:13:0", - "statements": - [ + "statements": [ { - "expression": - { + "expression": { "arguments": [], - "functionName": - { + "functionName": { "name": "revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb", "nativeSrc": "150:77:0", "nodeType": "YulIdentifier", @@ -97,11 +81,9 @@ } ] }, - "condition": - { + "condition": { "arguments": [], - "functionName": - { + "functionName": { "name": "callvalue", "nativeSrc": "136:9:0", "nodeType": "YulIdentifier", @@ -116,11 +98,9 @@ "src": "56:13:0" }, { - "expression": - { + "expression": { "arguments": [], - "functionName": - { + "functionName": { "name": "constructor_C_2", "nativeSrc": "241:15:0", "nodeType": "YulIdentifier", @@ -138,11 +118,9 @@ "nativeSrc": "268:30:0", "nodeType": "YulVariableDeclaration", "src": "56:13:0", - "value": - { + "value": { "arguments": [], - "functionName": - { + "functionName": { "name": "allocate_unbounded", "nativeSrc": "278:18:0", "nodeType": "YulIdentifier", @@ -152,8 +130,7 @@ "nodeType": "YulFunctionCall", "src": "56:13:0" }, - "variables": - [ + "variables": [ { "name": "_1", "nativeSrc": "272:2:0", @@ -164,10 +141,8 @@ ] }, { - "expression": - { - "arguments": - [ + "expression": { + "arguments": [ { "name": "_1", "nativeSrc": "316:2:0", @@ -175,8 +150,7 @@ "src": "56:13:0" }, { - "arguments": - [ + "arguments": [ { "hexValue": "435f325f6465706c6f796564", "kind": "string", @@ -187,8 +161,7 @@ "value": "C_2_deployed" } ], - "functionName": - { + "functionName": { "name": "dataoffset", "nativeSrc": "320:10:0", "nodeType": "YulIdentifier", @@ -199,8 +172,7 @@ "src": "56:13:0" }, { - "arguments": - [ + "arguments": [ { "hexValue": "435f325f6465706c6f796564", "kind": "string", @@ -211,8 +183,7 @@ "value": "C_2_deployed" } ], - "functionName": - { + "functionName": { "name": "datasize", "nativeSrc": "348:8:0", "nodeType": "YulIdentifier", @@ -223,8 +194,7 @@ "src": "56:13:0" } ], - "functionName": - { + "functionName": { "name": "codecopy", "nativeSrc": "307:8:0", "nodeType": "YulIdentifier", @@ -239,10 +209,8 @@ "src": "56:13:0" }, { - "expression": - { - "arguments": - [ + "expression": { + "arguments": [ { "name": "_1", "nativeSrc": "390:2:0", @@ -250,8 +218,7 @@ "src": "56:13:0" }, { - "arguments": - [ + "arguments": [ { "hexValue": "435f325f6465706c6f796564", "kind": "string", @@ -262,8 +229,7 @@ "value": "C_2_deployed" } ], - "functionName": - { + "functionName": { "name": "datasize", "nativeSrc": "394:8:0", "nodeType": "YulIdentifier", @@ -274,8 +240,7 @@ "src": "56:13:0" } ], - "functionName": - { + "functionName": { "name": "return", "nativeSrc": "383:6:0", "nodeType": "YulIdentifier", @@ -290,21 +255,17 @@ "src": "56:13:0" }, { - "body": - { + "body": { "nativeSrc": "469:43:0", "nodeType": "YulBlock", "src": "56:13:0", - "statements": - [ + "statements": [ { "nativeSrc": "483:19:0", "nodeType": "YulAssignment", "src": "56:13:0", - "value": - { - "arguments": - [ + "value": { + "arguments": [ { "kind": "number", "nativeSrc": "499:2:0", @@ -314,8 +275,7 @@ "value": "64" } ], - "functionName": - { + "functionName": { "name": "mload", "nativeSrc": "493:5:0", "nodeType": "YulIdentifier", @@ -325,8 +285,7 @@ "nodeType": "YulFunctionCall", "src": "56:13:0" }, - "variableNames": - [ + "variableNames": [ { "name": "memPtr", "nativeSrc": "483:6:0", @@ -340,8 +299,7 @@ "name": "allocate_unbounded", "nativeSrc": "429:83:0", "nodeType": "YulFunctionDefinition", - "returnVariables": - [ + "returnVariables": [ { "name": "memPtr", "nativeSrc": "462:6:0", @@ -353,18 +311,14 @@ "src": "56:13:0" }, { - "body": - { + "body": { "nativeSrc": "611:36:0", "nodeType": "YulBlock", "src": "56:13:0", - "statements": - [ + "statements": [ { - "expression": - { - "arguments": - [ + "expression": { + "arguments": [ { "kind": "number", "nativeSrc": "632:1:0", @@ -382,8 +336,7 @@ "value": "0" } ], - "functionName": - { + "functionName": { "name": "revert", "nativeSrc": "625:6:0", "nodeType": "YulIdentifier", @@ -405,8 +358,7 @@ "src": "56:13:0" }, { - "body": - { + "body": { "nativeSrc": "726:59:0", "nodeType": "YulBlock", "src": "56:13:0", @@ -423,23 +375,17 @@ }, "name": "C_2", "nodeType": "YulObject", - "subObjects": - [ + "subObjects": [ { - "code": - { - "block": - { + "code": { + "block": { "nativeSrc": "899:588:0", "nodeType": "YulBlock", "src": "-1:-1:0", - "statements": - [ + "statements": [ { - "expression": - { - "arguments": - [ + "expression": { + "arguments": [ { "kind": "number", "nativeSrc": "966:2:0", @@ -449,8 +395,7 @@ "value": "64" }, { - "arguments": - [ + "arguments": [ { "kind": "number", "nativeSrc": "982:3:0", @@ -460,8 +405,7 @@ "value": "128" } ], - "functionName": - { + "functionName": { "name": "memoryguard", "nativeSrc": "970:11:0", "nodeType": "YulIdentifier", @@ -472,8 +416,7 @@ "src": "56:13:0" } ], - "functionName": - { + "functionName": { "name": "mstore", "nativeSrc": "959:6:0", "nodeType": "YulIdentifier", @@ -488,11 +431,9 @@ "src": "56:13:0" }, { - "expression": - { + "expression": { "arguments": [], - "functionName": - { + "functionName": { "name": "revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74", "nativeSrc": "1001:77:0", "nodeType": "YulIdentifier", @@ -507,21 +448,17 @@ "src": "56:13:0" }, { - "body": - { + "body": { "nativeSrc": "1147:77:0", "nodeType": "YulBlock", "src": "56:13:0", - "statements": - [ + "statements": [ { "nativeSrc": "1165:44:0", "nodeType": "YulAssignment", "src": "56:13:0", - "value": - { - "arguments": - [ + "value": { + "arguments": [ { "kind": "number", "nativeSrc": "1198:3:0", @@ -537,8 +474,7 @@ "src": "56:13:0" } ], - "functionName": - { + "functionName": { "name": "shr", "nativeSrc": "1194:3:0", "nodeType": "YulIdentifier", @@ -548,8 +484,7 @@ "nodeType": "YulFunctionCall", "src": "56:13:0" }, - "variableNames": - [ + "variableNames": [ { "name": "newValue", "nativeSrc": "1165:8:0", @@ -563,8 +498,7 @@ "name": "shift_right_224_unsigned", "nativeSrc": "1094:130:0", "nodeType": "YulFunctionDefinition", - "parameters": - [ + "parameters": [ { "name": "value", "nativeSrc": "1128:5:0", @@ -573,8 +507,7 @@ "type": "" } ], - "returnVariables": - [ + "returnVariables": [ { "name": "newValue", "nativeSrc": "1138:8:0", @@ -586,21 +519,17 @@ "src": "56:13:0" }, { - "body": - { + "body": { "nativeSrc": "1278:51:0", "nodeType": "YulBlock", "src": "56:13:0", - "statements": - [ + "statements": [ { "nativeSrc": "1296:19:0", "nodeType": "YulAssignment", "src": "56:13:0", - "value": - { - "arguments": - [ + "value": { + "arguments": [ { "kind": "number", "nativeSrc": "1312:2:0", @@ -610,8 +539,7 @@ "value": "64" } ], - "functionName": - { + "functionName": { "name": "mload", "nativeSrc": "1306:5:0", "nodeType": "YulIdentifier", @@ -621,8 +549,7 @@ "nodeType": "YulFunctionCall", "src": "56:13:0" }, - "variableNames": - [ + "variableNames": [ { "name": "memPtr", "nativeSrc": "1296:6:0", @@ -636,8 +563,7 @@ "name": "allocate_unbounded", "nativeSrc": "1238:91:0", "nodeType": "YulFunctionDefinition", - "returnVariables": - [ + "returnVariables": [ { "name": "memPtr", "nativeSrc": "1271:6:0", @@ -649,18 +575,14 @@ "src": "56:13:0" }, { - "body": - { + "body": { "nativeSrc": "1432:44:0", "nodeType": "YulBlock", "src": "56:13:0", - "statements": - [ + "statements": [ { - "expression": - { - "arguments": - [ + "expression": { + "arguments": [ { "kind": "number", "nativeSrc": "1457:1:0", @@ -678,8 +600,7 @@ "value": "0" } ], - "functionName": - { + "functionName": { "name": "revert", "nativeSrc": "1450:6:0", "nodeType": "YulIdentifier", @@ -706,8 +627,7 @@ }, "name": "C_2_deployed", "nodeType": "YulObject", - "subObjects": - [ + "subObjects": [ { "nodeType": "YulData", "value": "" @@ -719,10 +639,8 @@ } } }, - "sources": - { - "C": - { + "sources": { + "C": { "id": 0 } } diff --git a/test/cmdlineTests/standard_ir_requested/output.json b/test/cmdlineTests/standard_ir_requested/output.json index ab38f0a58921..e359d5ca550f 100644 --- a/test/cmdlineTests/standard_ir_requested/output.json +++ b/test/cmdlineTests/standard_ir_requested/output.json @@ -1,10 +1,7 @@ { - "contracts": - { - "A": - { - "C": - { + "contracts": { + "A": { + "C": { "ir": " /// @use-src 0:\"A\" object \"C_7\" { @@ -122,10 +119,8 @@ object \"C_7\" { } } }, - "sources": - { - "A": - { + "sources": { + "A": { "id": 0 } } diff --git a/test/cmdlineTests/standard_metadata/output.json b/test/cmdlineTests/standard_metadata/output.json index 955d30c34475..5b9c8504f386 100644 --- a/test/cmdlineTests/standard_metadata/output.json +++ b/test/cmdlineTests/standard_metadata/output.json @@ -1,18 +1,13 @@ { - "contracts": - { - "C": - { - "C": - { + "contracts": { + "C": { + "C": { "metadata": "{\"compiler\":{\"version\":\"\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"C\":\"C\"},\"evmVersion\":\"cancun\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"C\":{\"keccak256\":\"0x5cf617b1707a484e3c4bd59643013dec76ab7d75900b46855214729ae3e0ceb0\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://ac418a02dfadf87234150d3568f33269e3f49460345cb39300e017a6d755eff2\",\"dweb:/ipfs/QmQq3owBu25x2WV46HB1WyKzJpxiAPecU7eMKqtXCF7eeS\"]}},\"version\":1}" } } }, - "sources": - { - "C": - { + "sources": { + "C": { "id": 0 } } diff --git a/test/cmdlineTests/standard_method_identifiers_requested/output.json b/test/cmdlineTests/standard_method_identifiers_requested/output.json index 35d4f5002508..df1e81f732cf 100644 --- a/test/cmdlineTests/standard_method_identifiers_requested/output.json +++ b/test/cmdlineTests/standard_method_identifiers_requested/output.json @@ -1,24 +1,17 @@ { - "contracts": - { - "A": - { - "C": - { - "evm": - { - "methodIdentifiers": - { + "contracts": { + "A": { + "C": { + "evm": { + "methodIdentifiers": { "f()": "26121ff0" } } } } }, - "sources": - { - "A": - { + "sources": { + "A": { "id": 0 } } diff --git a/test/cmdlineTests/standard_method_identifiers_requested_empty/output.json b/test/cmdlineTests/standard_method_identifiers_requested_empty/output.json index f90a33351b35..1d3245c20487 100644 --- a/test/cmdlineTests/standard_method_identifiers_requested_empty/output.json +++ b/test/cmdlineTests/standard_method_identifiers_requested_empty/output.json @@ -1,21 +1,15 @@ { - "contracts": - { - "A": - { - "C": - { - "evm": - { + "contracts": { + "A": { + "C": { + "evm": { "methodIdentifiers": {} } } } }, - "sources": - { - "A": - { + "sources": { + "A": { "id": 0 } } diff --git a/test/cmdlineTests/standard_missing_key_useLiteralContent/output.json b/test/cmdlineTests/standard_missing_key_useLiteralContent/output.json index f3a09c9e7bfb..d18ad81fa715 100644 --- a/test/cmdlineTests/standard_missing_key_useLiteralContent/output.json +++ b/test/cmdlineTests/standard_missing_key_useLiteralContent/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "formattedMessage": "Support for EVM versions older than constantinople is deprecated and will be removed in the future.", @@ -9,10 +8,8 @@ "type": "Warning" } ], - "sources": - { - "A": - { + "sources": { + "A": { "id": 0 } } diff --git a/test/cmdlineTests/standard_model_checker_bmc_loop_iterations/output.json b/test/cmdlineTests/standard_model_checker_bmc_loop_iterations/output.json index 139b0825bc47..ffaa2823bfe4 100644 --- a/test/cmdlineTests/standard_model_checker_bmc_loop_iterations/output.json +++ b/test/cmdlineTests/standard_model_checker_bmc_loop_iterations/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "errorCode": "6002", @@ -12,10 +11,8 @@ "type": "Info" } ], - "sources": - { - "Source": - { + "sources": { + "Source": { "id": 0 } } diff --git a/test/cmdlineTests/standard_model_checker_bmc_loop_iterations_invalid_arg/output.json b/test/cmdlineTests/standard_model_checker_bmc_loop_iterations_invalid_arg/output.json index 971973d85c0c..05b835e56922 100644 --- a/test/cmdlineTests/standard_model_checker_bmc_loop_iterations_invalid_arg/output.json +++ b/test/cmdlineTests/standard_model_checker_bmc_loop_iterations_invalid_arg/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "formattedMessage": "settings.modelChecker.bmcLoopIterations must be an unsigned integer.", diff --git a/test/cmdlineTests/standard_model_checker_contracts_all/output.json b/test/cmdlineTests/standard_model_checker_contracts_all/output.json index b4bfd66b8489..e9fc1b4cf6b5 100644 --- a/test/cmdlineTests/standard_model_checker_contracts_all/output.json +++ b/test/cmdlineTests/standard_model_checker_contracts_all/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "errorCode": "6328", @@ -27,8 +26,7 @@ Transaction trace: B.constructor() B.g(0)", "severity": "warning", - "sourceLocation": - { + "sourceLocation": { "end": 137, "file": "Source", "start": 124 @@ -61,8 +59,7 @@ Transaction trace: A.constructor() A.f(0)", "severity": "warning", - "sourceLocation": - { + "sourceLocation": { "end": 231, "file": "Source", "start": 218 @@ -70,10 +67,8 @@ A.f(0)", "type": "Warning" } ], - "sources": - { - "Source": - { + "sources": { + "Source": { "id": 0 } } diff --git a/test/cmdlineTests/standard_model_checker_contracts_all_explicit/output.json b/test/cmdlineTests/standard_model_checker_contracts_all_explicit/output.json index b4bfd66b8489..e9fc1b4cf6b5 100644 --- a/test/cmdlineTests/standard_model_checker_contracts_all_explicit/output.json +++ b/test/cmdlineTests/standard_model_checker_contracts_all_explicit/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "errorCode": "6328", @@ -27,8 +26,7 @@ Transaction trace: B.constructor() B.g(0)", "severity": "warning", - "sourceLocation": - { + "sourceLocation": { "end": 137, "file": "Source", "start": 124 @@ -61,8 +59,7 @@ Transaction trace: A.constructor() A.f(0)", "severity": "warning", - "sourceLocation": - { + "sourceLocation": { "end": 231, "file": "Source", "start": 218 @@ -70,10 +67,8 @@ A.f(0)", "type": "Warning" } ], - "sources": - { - "Source": - { + "sources": { + "Source": { "id": 0 } } diff --git a/test/cmdlineTests/standard_model_checker_contracts_empty_array/output.json b/test/cmdlineTests/standard_model_checker_contracts_empty_array/output.json index ada440ad3880..fe1bdb97dda3 100644 --- a/test/cmdlineTests/standard_model_checker_contracts_empty_array/output.json +++ b/test/cmdlineTests/standard_model_checker_contracts_empty_array/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "formattedMessage": "Source contracts must be a non-empty array.", diff --git a/test/cmdlineTests/standard_model_checker_contracts_empty_contract/output.json b/test/cmdlineTests/standard_model_checker_contracts_empty_contract/output.json index c3b171e99e4f..e31326ff861e 100644 --- a/test/cmdlineTests/standard_model_checker_contracts_empty_contract/output.json +++ b/test/cmdlineTests/standard_model_checker_contracts_empty_contract/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "formattedMessage": "Contract name cannot be empty.", diff --git a/test/cmdlineTests/standard_model_checker_contracts_empty_source/output.json b/test/cmdlineTests/standard_model_checker_contracts_empty_source/output.json index 98dcc1afadfb..b4495bb2223c 100644 --- a/test/cmdlineTests/standard_model_checker_contracts_empty_source/output.json +++ b/test/cmdlineTests/standard_model_checker_contracts_empty_source/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "formattedMessage": "Source name cannot be empty.", diff --git a/test/cmdlineTests/standard_model_checker_contracts_inexistent_contract/output.json b/test/cmdlineTests/standard_model_checker_contracts_inexistent_contract/output.json index 7ff30950c1ba..22d5f32de32b 100644 --- a/test/cmdlineTests/standard_model_checker_contracts_inexistent_contract/output.json +++ b/test/cmdlineTests/standard_model_checker_contracts_inexistent_contract/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "errorCode": "7400", @@ -37,8 +36,7 @@ Transaction trace: B.constructor() B.g(0)", "severity": "warning", - "sourceLocation": - { + "sourceLocation": { "end": 137, "file": "Source", "start": 124 @@ -71,8 +69,7 @@ Transaction trace: A.constructor() A.f(0)", "severity": "warning", - "sourceLocation": - { + "sourceLocation": { "end": 231, "file": "Source", "start": 218 @@ -80,10 +77,8 @@ A.f(0)", "type": "Warning" } ], - "sources": - { - "Source": - { + "sources": { + "Source": { "id": 0 } } diff --git a/test/cmdlineTests/standard_model_checker_contracts_multi_source/output.json b/test/cmdlineTests/standard_model_checker_contracts_multi_source/output.json index cb18875e1bf4..fe287f833637 100644 --- a/test/cmdlineTests/standard_model_checker_contracts_multi_source/output.json +++ b/test/cmdlineTests/standard_model_checker_contracts_multi_source/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "errorCode": "6328", @@ -27,8 +26,7 @@ Transaction trace: B.constructor() B.g(0)", "severity": "warning", - "sourceLocation": - { + "sourceLocation": { "end": 137, "file": "Source", "start": 124 @@ -61,8 +59,7 @@ Transaction trace: A.constructor() A.f(0)", "severity": "warning", - "sourceLocation": - { + "sourceLocation": { "end": 231, "file": "Source", "start": 218 @@ -95,8 +92,7 @@ Transaction trace: C.constructor() C.h(0)", "severity": "warning", - "sourceLocation": - { + "sourceLocation": { "end": 165, "file": "Source2", "start": 150 @@ -104,14 +100,11 @@ C.h(0)", "type": "Warning" } ], - "sources": - { - "Source": - { + "sources": { + "Source": { "id": 0 }, - "Source2": - { + "Source2": { "id": 1 } } diff --git a/test/cmdlineTests/standard_model_checker_contracts_only_one/output.json b/test/cmdlineTests/standard_model_checker_contracts_only_one/output.json index b4bfd66b8489..e9fc1b4cf6b5 100644 --- a/test/cmdlineTests/standard_model_checker_contracts_only_one/output.json +++ b/test/cmdlineTests/standard_model_checker_contracts_only_one/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "errorCode": "6328", @@ -27,8 +26,7 @@ Transaction trace: B.constructor() B.g(0)", "severity": "warning", - "sourceLocation": - { + "sourceLocation": { "end": 137, "file": "Source", "start": 124 @@ -61,8 +59,7 @@ Transaction trace: A.constructor() A.f(0)", "severity": "warning", - "sourceLocation": - { + "sourceLocation": { "end": 231, "file": "Source", "start": 218 @@ -70,10 +67,8 @@ A.f(0)", "type": "Warning" } ], - "sources": - { - "Source": - { + "sources": { + "Source": { "id": 0 } } diff --git a/test/cmdlineTests/standard_model_checker_contracts_wrong_key_sources/output.json b/test/cmdlineTests/standard_model_checker_contracts_wrong_key_sources/output.json index d38ad1b599ef..b792b6d93bea 100644 --- a/test/cmdlineTests/standard_model_checker_contracts_wrong_key_sources/output.json +++ b/test/cmdlineTests/standard_model_checker_contracts_wrong_key_sources/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "errorCode": "9134", @@ -12,10 +11,8 @@ "type": "Warning" } ], - "sources": - { - "Source": - { + "sources": { + "Source": { "id": 0 } } diff --git a/test/cmdlineTests/standard_model_checker_contracts_wrong_key_sources_2/output.json b/test/cmdlineTests/standard_model_checker_contracts_wrong_key_sources_2/output.json index 98365d1bf8a6..05bab373313b 100644 --- a/test/cmdlineTests/standard_model_checker_contracts_wrong_key_sources_2/output.json +++ b/test/cmdlineTests/standard_model_checker_contracts_wrong_key_sources_2/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "formattedMessage": "settings.modelChecker.contracts is not a JSON object.", diff --git a/test/cmdlineTests/standard_model_checker_contracts_wrong_key_sources_3/output.json b/test/cmdlineTests/standard_model_checker_contracts_wrong_key_sources_3/output.json index 567db80afe4e..d07d645f4ae2 100644 --- a/test/cmdlineTests/standard_model_checker_contracts_wrong_key_sources_3/output.json +++ b/test/cmdlineTests/standard_model_checker_contracts_wrong_key_sources_3/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "formattedMessage": "Source contracts must be an array.", diff --git a/test/cmdlineTests/standard_model_checker_contracts_wrong_key_sources_4/output.json b/test/cmdlineTests/standard_model_checker_contracts_wrong_key_sources_4/output.json index 30d4c2dcf098..90790a859e8d 100644 --- a/test/cmdlineTests/standard_model_checker_contracts_wrong_key_sources_4/output.json +++ b/test/cmdlineTests/standard_model_checker_contracts_wrong_key_sources_4/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "formattedMessage": "Every contract in settings.modelChecker.contracts must be a string.", diff --git a/test/cmdlineTests/standard_model_checker_divModSlacks_default_all/output.json b/test/cmdlineTests/standard_model_checker_divModSlacks_default_all/output.json index b8637143b07c..82ee5a107717 100644 --- a/test/cmdlineTests/standard_model_checker_divModSlacks_default_all/output.json +++ b/test/cmdlineTests/standard_model_checker_divModSlacks_default_all/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "errorCode": "1391", @@ -12,10 +11,8 @@ "type": "Info" } ], - "sources": - { - "A": - { + "sources": { + "A": { "id": 0 } } diff --git a/test/cmdlineTests/standard_model_checker_divModSlacks_default_bmc/output.json b/test/cmdlineTests/standard_model_checker_divModSlacks_default_bmc/output.json index a6ce9b3c96f9..dfba5336499a 100644 --- a/test/cmdlineTests/standard_model_checker_divModSlacks_default_bmc/output.json +++ b/test/cmdlineTests/standard_model_checker_divModSlacks_default_bmc/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "errorCode": "6002", @@ -12,10 +11,8 @@ "type": "Info" } ], - "sources": - { - "A": - { + "sources": { + "A": { "id": 0 } } diff --git a/test/cmdlineTests/standard_model_checker_divModSlacks_default_chc/output.json b/test/cmdlineTests/standard_model_checker_divModSlacks_default_chc/output.json index b8637143b07c..82ee5a107717 100644 --- a/test/cmdlineTests/standard_model_checker_divModSlacks_default_chc/output.json +++ b/test/cmdlineTests/standard_model_checker_divModSlacks_default_chc/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "errorCode": "1391", @@ -12,10 +11,8 @@ "type": "Info" } ], - "sources": - { - "A": - { + "sources": { + "A": { "id": 0 } } diff --git a/test/cmdlineTests/standard_model_checker_divModSlacks_false_all/output.json b/test/cmdlineTests/standard_model_checker_divModSlacks_false_all/output.json index f7ecf690d82a..eefa60785bb2 100644 --- a/test/cmdlineTests/standard_model_checker_divModSlacks_false_all/output.json +++ b/test/cmdlineTests/standard_model_checker_divModSlacks_false_all/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "errorCode": "1218", @@ -13,8 +12,7 @@ ", "message": "CHC: Error trying to invoke SMT solver.", "severity": "warning", - "sourceLocation": - { + "sourceLocation": { "end": 182, "file": "A", "start": 177 @@ -33,8 +31,7 @@ ", "message": "CHC: Error trying to invoke SMT solver.", "severity": "warning", - "sourceLocation": - { + "sourceLocation": { "end": 189, "file": "A", "start": 184 @@ -62,10 +59,8 @@ "type": "Info" } ], - "sources": - { - "A": - { + "sources": { + "A": { "id": 0 } } diff --git a/test/cmdlineTests/standard_model_checker_divModSlacks_false_bmc/output.json b/test/cmdlineTests/standard_model_checker_divModSlacks_false_bmc/output.json index a6ce9b3c96f9..dfba5336499a 100644 --- a/test/cmdlineTests/standard_model_checker_divModSlacks_false_bmc/output.json +++ b/test/cmdlineTests/standard_model_checker_divModSlacks_false_bmc/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "errorCode": "6002", @@ -12,10 +11,8 @@ "type": "Info" } ], - "sources": - { - "A": - { + "sources": { + "A": { "id": 0 } } diff --git a/test/cmdlineTests/standard_model_checker_divModSlacks_false_chc/output.json b/test/cmdlineTests/standard_model_checker_divModSlacks_false_chc/output.json index fccd15838fc8..16fb77513081 100644 --- a/test/cmdlineTests/standard_model_checker_divModSlacks_false_chc/output.json +++ b/test/cmdlineTests/standard_model_checker_divModSlacks_false_chc/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "errorCode": "1218", @@ -13,8 +12,7 @@ ", "message": "CHC: Error trying to invoke SMT solver.", "severity": "warning", - "sourceLocation": - { + "sourceLocation": { "end": 182, "file": "A", "start": 177 @@ -33,8 +31,7 @@ ", "message": "CHC: Error trying to invoke SMT solver.", "severity": "warning", - "sourceLocation": - { + "sourceLocation": { "end": 189, "file": "A", "start": 184 @@ -52,10 +49,8 @@ "type": "Warning" } ], - "sources": - { - "A": - { + "sources": { + "A": { "id": 0 } } diff --git a/test/cmdlineTests/standard_model_checker_divModSlacks_wrong/output.json b/test/cmdlineTests/standard_model_checker_divModSlacks_wrong/output.json index 457fb1ba0cc8..dae639c6410a 100644 --- a/test/cmdlineTests/standard_model_checker_divModSlacks_wrong/output.json +++ b/test/cmdlineTests/standard_model_checker_divModSlacks_wrong/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "formattedMessage": "settings.modelChecker.divModNoSlacks must be a Boolean.", diff --git a/test/cmdlineTests/standard_model_checker_engine_all/output.json b/test/cmdlineTests/standard_model_checker_engine_all/output.json index 2a2c394fdd72..be51d6b2e518 100644 --- a/test/cmdlineTests/standard_model_checker_engine_all/output.json +++ b/test/cmdlineTests/standard_model_checker_engine_all/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "errorCode": "6328", @@ -27,8 +26,7 @@ Transaction trace: C.constructor() C.f(0)", "severity": "warning", - "sourceLocation": - { + "sourceLocation": { "end": 119, "file": "A", "start": 106 @@ -36,10 +34,8 @@ C.f(0)", "type": "Warning" } ], - "sources": - { - "A": - { + "sources": { + "A": { "id": 0 } } diff --git a/test/cmdlineTests/standard_model_checker_engine_bmc/output.json b/test/cmdlineTests/standard_model_checker_engine_bmc/output.json index 75e679ef473d..4727ea083585 100644 --- a/test/cmdlineTests/standard_model_checker_engine_bmc/output.json +++ b/test/cmdlineTests/standard_model_checker_engine_bmc/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "errorCode": "4661", @@ -17,8 +16,7 @@ Note: ", "message": "BMC: Assertion violation happens here.", - "secondarySourceLocations": - [ + "secondarySourceLocations": [ { "message": "Counterexample: x = 0 @@ -32,8 +30,7 @@ Note: } ], "severity": "warning", - "sourceLocation": - { + "sourceLocation": { "end": 119, "file": "A", "start": 106 @@ -41,10 +38,8 @@ Note: "type": "Warning" } ], - "sources": - { - "A": - { + "sources": { + "A": { "id": 0 } } diff --git a/test/cmdlineTests/standard_model_checker_engine_chc/output.json b/test/cmdlineTests/standard_model_checker_engine_chc/output.json index 2a2c394fdd72..be51d6b2e518 100644 --- a/test/cmdlineTests/standard_model_checker_engine_chc/output.json +++ b/test/cmdlineTests/standard_model_checker_engine_chc/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "errorCode": "6328", @@ -27,8 +26,7 @@ Transaction trace: C.constructor() C.f(0)", "severity": "warning", - "sourceLocation": - { + "sourceLocation": { "end": 119, "file": "A", "start": 106 @@ -36,10 +34,8 @@ C.f(0)", "type": "Warning" } ], - "sources": - { - "A": - { + "sources": { + "A": { "id": 0 } } diff --git a/test/cmdlineTests/standard_model_checker_engine_none/output.json b/test/cmdlineTests/standard_model_checker_engine_none/output.json index acf3b74ef1de..f047ff70a9eb 100644 --- a/test/cmdlineTests/standard_model_checker_engine_none/output.json +++ b/test/cmdlineTests/standard_model_checker_engine_none/output.json @@ -1,8 +1,6 @@ { - "sources": - { - "A": - { + "sources": { + "A": { "id": 0 } } diff --git a/test/cmdlineTests/standard_model_checker_ext_calls_empty_arg/output.json b/test/cmdlineTests/standard_model_checker_ext_calls_empty_arg/output.json index 4e214a37b2db..34d69504d5bd 100644 --- a/test/cmdlineTests/standard_model_checker_ext_calls_empty_arg/output.json +++ b/test/cmdlineTests/standard_model_checker_ext_calls_empty_arg/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "formattedMessage": "Invalid model checker extCalls requested.", diff --git a/test/cmdlineTests/standard_model_checker_ext_calls_trusted_chc/output.json b/test/cmdlineTests/standard_model_checker_ext_calls_trusted_chc/output.json index 7f3993410144..16bfff9b7736 100644 --- a/test/cmdlineTests/standard_model_checker_ext_calls_trusted_chc/output.json +++ b/test/cmdlineTests/standard_model_checker_ext_calls_trusted_chc/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "errorCode": "2018", @@ -13,8 +12,7 @@ ", "message": "Function state mutability can be restricted to pure", "severity": "warning", - "sourceLocation": - { + "sourceLocation": { "end": 152, "file": "A", "start": 85 @@ -32,10 +30,8 @@ "type": "Info" } ], - "sources": - { - "A": - { + "sources": { + "A": { "id": 0 } } diff --git a/test/cmdlineTests/standard_model_checker_ext_calls_untrusted_chc/output.json b/test/cmdlineTests/standard_model_checker_ext_calls_untrusted_chc/output.json index c6b072a85863..858d225e67f9 100644 --- a/test/cmdlineTests/standard_model_checker_ext_calls_untrusted_chc/output.json +++ b/test/cmdlineTests/standard_model_checker_ext_calls_untrusted_chc/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "errorCode": "6328", @@ -31,8 +30,7 @@ test.constructor() test.g(0) e.f() -- untrusted external call", "severity": "warning", - "sourceLocation": - { + "sourceLocation": { "end": 254, "file": "A", "start": 240 @@ -40,10 +38,8 @@ test.g(0) "type": "Warning" } ], - "sources": - { - "A": - { + "sources": { + "A": { "id": 0 } } diff --git a/test/cmdlineTests/standard_model_checker_ext_calls_wrong_arg_1/output.json b/test/cmdlineTests/standard_model_checker_ext_calls_wrong_arg_1/output.json index 4e214a37b2db..34d69504d5bd 100644 --- a/test/cmdlineTests/standard_model_checker_ext_calls_wrong_arg_1/output.json +++ b/test/cmdlineTests/standard_model_checker_ext_calls_wrong_arg_1/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "formattedMessage": "Invalid model checker extCalls requested.", diff --git a/test/cmdlineTests/standard_model_checker_ext_calls_wrong_arg_2/output.json b/test/cmdlineTests/standard_model_checker_ext_calls_wrong_arg_2/output.json index e869637ed125..5daa6a447ad7 100644 --- a/test/cmdlineTests/standard_model_checker_ext_calls_wrong_arg_2/output.json +++ b/test/cmdlineTests/standard_model_checker_ext_calls_wrong_arg_2/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "formattedMessage": "settings.modelChecker.extCalls must be a string.", diff --git a/test/cmdlineTests/standard_model_checker_invariants_contract/output.json b/test/cmdlineTests/standard_model_checker_invariants_contract/output.json index 314b66aae4ae..f3cd0758c0ea 100644 --- a/test/cmdlineTests/standard_model_checker_invariants_contract/output.json +++ b/test/cmdlineTests/standard_model_checker_invariants_contract/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "errorCode": "1391", @@ -26,10 +25,8 @@ "type": "Info" } ], - "sources": - { - "A": - { + "sources": { + "A": { "id": 0 } } 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 5a83ba7ac752..d46fdda8a917 100644 --- a/test/cmdlineTests/standard_model_checker_invariants_contract_reentrancy/output.json +++ b/test/cmdlineTests/standard_model_checker_invariants_contract_reentrancy/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "errorCode": "9302", @@ -13,8 +12,7 @@ ", "message": "Return value of low-level calls not used.", "severity": "warning", - "sourceLocation": - { + "sourceLocation": { "end": 143, "file": "A", "start": 132 @@ -51,8 +49,7 @@ State: x = 0 test.f(0x0) _a.call(\"\") -- untrusted external call", "severity": "warning", - "sourceLocation": - { + "sourceLocation": { "end": 166, "file": "A", "start": 151 @@ -60,10 +57,8 @@ test.f(0x0) "type": "Warning" } ], - "sources": - { - "A": - { + "sources": { + "A": { "id": 0 } } diff --git a/test/cmdlineTests/standard_model_checker_invariants_reentrancy/output.json b/test/cmdlineTests/standard_model_checker_invariants_reentrancy/output.json index feb586a3e32b..bf6b296cdfa3 100644 --- a/test/cmdlineTests/standard_model_checker_invariants_reentrancy/output.json +++ b/test/cmdlineTests/standard_model_checker_invariants_reentrancy/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "errorCode": "9302", @@ -13,8 +12,7 @@ ", "message": "Return value of low-level calls not used.", "severity": "warning", - "sourceLocation": - { + "sourceLocation": { "end": 143, "file": "A", "start": 132 @@ -50,10 +48,8 @@ "type": "Info" } ], - "sources": - { - "A": - { + "sources": { + "A": { "id": 0 } } diff --git a/test/cmdlineTests/standard_model_checker_invariants_wrong_key/output.json b/test/cmdlineTests/standard_model_checker_invariants_wrong_key/output.json index 45fcfbe984ce..06b42cb6f418 100644 --- a/test/cmdlineTests/standard_model_checker_invariants_wrong_key/output.json +++ b/test/cmdlineTests/standard_model_checker_invariants_wrong_key/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "formattedMessage": "Invalid model checker invariants requested.", diff --git a/test/cmdlineTests/standard_model_checker_invariants_wrong_type/output.json b/test/cmdlineTests/standard_model_checker_invariants_wrong_type/output.json index d1992e464d6e..c59605d2cd3a 100644 --- a/test/cmdlineTests/standard_model_checker_invariants_wrong_type/output.json +++ b/test/cmdlineTests/standard_model_checker_invariants_wrong_type/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "formattedMessage": "Every invariant type in settings.modelChecker.invariants must be a string.", diff --git a/test/cmdlineTests/standard_model_checker_invariants_wrong_type_2/output.json b/test/cmdlineTests/standard_model_checker_invariants_wrong_type_2/output.json index 078edfc1d8e3..eaa736025cab 100644 --- a/test/cmdlineTests/standard_model_checker_invariants_wrong_type_2/output.json +++ b/test/cmdlineTests/standard_model_checker_invariants_wrong_type_2/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "formattedMessage": "settings.modelChecker.invariants must be an array.", diff --git a/test/cmdlineTests/standard_model_checker_print_query_all/output.json b/test/cmdlineTests/standard_model_checker_print_query_all/output.json index b8e11ced7301..16ff42e0c306 100644 --- a/test/cmdlineTests/standard_model_checker_print_query_all/output.json +++ b/test/cmdlineTests/standard_model_checker_print_query_all/output.json @@ -1,8 +1,6 @@ { - "auxiliaryInputRequested": - { - "smtlib2queries": - { + "auxiliaryInputRequested": { + "smtlib2queries": { "0x1880095c52d8681601c6821e4a5c29740649509af99947bce54102546dd3376a": "(set-option :timeout 1000) (set-logic HORN) (declare-datatypes ((|bytes_tuple| 0)) (((|bytes_tuple| (|bytes_tuple_accessor_array| (Array Int Int)) (|bytes_tuple_accessor_length| Int))))) @@ -159,8 +157,7 @@ " } }, - "errors": - [ + "errors": [ { "component": "general", "errorCode": "2339", @@ -530,10 +527,8 @@ "type": "Warning" } ], - "sources": - { - "A": - { + "sources": { + "A": { "id": 0 } } diff --git a/test/cmdlineTests/standard_model_checker_print_query_bmc/output.json b/test/cmdlineTests/standard_model_checker_print_query_bmc/output.json index f7b4dc7e2871..1c9826ad22e0 100644 --- a/test/cmdlineTests/standard_model_checker_print_query_bmc/output.json +++ b/test/cmdlineTests/standard_model_checker_print_query_bmc/output.json @@ -1,8 +1,6 @@ { - "auxiliaryInputRequested": - { - "smtlib2queries": - { + "auxiliaryInputRequested": { + "smtlib2queries": { "0x8704a7b848b706ef33cbfc06e4f185636f568a29621126b7244355dd0de956bb": "(set-option :produce-models true) (set-logic ALL) (declare-fun |error_0| () Int) @@ -32,8 +30,7 @@ " } }, - "errors": - [ + "errors": [ { "component": "general", "errorCode": "6240", @@ -119,10 +116,8 @@ "type": "Warning" } ], - "sources": - { - "A": - { + "sources": { + "A": { "id": 0 } } diff --git a/test/cmdlineTests/standard_model_checker_print_query_chc/output.json b/test/cmdlineTests/standard_model_checker_print_query_chc/output.json index 9ef925b205a2..a9b0df0fb687 100644 --- a/test/cmdlineTests/standard_model_checker_print_query_chc/output.json +++ b/test/cmdlineTests/standard_model_checker_print_query_chc/output.json @@ -1,8 +1,6 @@ { - "auxiliaryInputRequested": - { - "smtlib2queries": - { + "auxiliaryInputRequested": { + "smtlib2queries": { "0x1880095c52d8681601c6821e4a5c29740649509af99947bce54102546dd3376a": "(set-option :timeout 1000) (set-logic HORN) (declare-datatypes ((|bytes_tuple| 0)) (((|bytes_tuple| (|bytes_tuple_accessor_array| (Array Int Int)) (|bytes_tuple_accessor_length| Int))))) @@ -129,8 +127,7 @@ " } }, - "errors": - [ + "errors": [ { "component": "general", "errorCode": "2339", @@ -410,10 +407,8 @@ "type": "Warning" } ], - "sources": - { - "A": - { + "sources": { + "A": { "id": 0 } } diff --git a/test/cmdlineTests/standard_model_checker_print_query_invalid_arg/output.json b/test/cmdlineTests/standard_model_checker_print_query_invalid_arg/output.json index 00c389f7a433..a9f44c912fa5 100644 --- a/test/cmdlineTests/standard_model_checker_print_query_invalid_arg/output.json +++ b/test/cmdlineTests/standard_model_checker_print_query_invalid_arg/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "formattedMessage": "settings.modelChecker.printQuery must be a Boolean value.", diff --git a/test/cmdlineTests/standard_model_checker_print_query_no_smtlib2_solver/output.json b/test/cmdlineTests/standard_model_checker_print_query_no_smtlib2_solver/output.json index 42d4b5b2db8a..d675499f91db 100644 --- a/test/cmdlineTests/standard_model_checker_print_query_no_smtlib2_solver/output.json +++ b/test/cmdlineTests/standard_model_checker_print_query_no_smtlib2_solver/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "formattedMessage": "Only SMTLib2 solver can be enabled to print queries", diff --git a/test/cmdlineTests/standard_model_checker_print_query_superflous_solver/output.json b/test/cmdlineTests/standard_model_checker_print_query_superflous_solver/output.json index 42d4b5b2db8a..d675499f91db 100644 --- a/test/cmdlineTests/standard_model_checker_print_query_superflous_solver/output.json +++ b/test/cmdlineTests/standard_model_checker_print_query_superflous_solver/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "formattedMessage": "Only SMTLib2 solver can be enabled to print queries", diff --git a/test/cmdlineTests/standard_model_checker_show_proved_safe_default_all_engines/output.json b/test/cmdlineTests/standard_model_checker_show_proved_safe_default_all_engines/output.json index b8118ba16a5d..4c57da4607c0 100644 --- a/test/cmdlineTests/standard_model_checker_show_proved_safe_default_all_engines/output.json +++ b/test/cmdlineTests/standard_model_checker_show_proved_safe_default_all_engines/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "errorCode": "2018", @@ -13,8 +12,7 @@ ", "message": "Function state mutability can be restricted to pure", "severity": "warning", - "sourceLocation": - { + "sourceLocation": { "end": 162, "file": "A", "start": 81 @@ -32,10 +30,8 @@ "type": "Info" } ], - "sources": - { - "A": - { + "sources": { + "A": { "id": 0 } } diff --git a/test/cmdlineTests/standard_model_checker_show_proved_safe_default_bmc/output.json b/test/cmdlineTests/standard_model_checker_show_proved_safe_default_bmc/output.json index eb6ed6e27705..6d9dbb4092b2 100644 --- a/test/cmdlineTests/standard_model_checker_show_proved_safe_default_bmc/output.json +++ b/test/cmdlineTests/standard_model_checker_show_proved_safe_default_bmc/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "errorCode": "2018", @@ -13,8 +12,7 @@ ", "message": "Function state mutability can be restricted to pure", "severity": "warning", - "sourceLocation": - { + "sourceLocation": { "end": 162, "file": "A", "start": 81 @@ -32,10 +30,8 @@ "type": "Info" } ], - "sources": - { - "A": - { + "sources": { + "A": { "id": 0 } } diff --git a/test/cmdlineTests/standard_model_checker_show_proved_safe_default_chc/output.json b/test/cmdlineTests/standard_model_checker_show_proved_safe_default_chc/output.json index b8118ba16a5d..4c57da4607c0 100644 --- a/test/cmdlineTests/standard_model_checker_show_proved_safe_default_chc/output.json +++ b/test/cmdlineTests/standard_model_checker_show_proved_safe_default_chc/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "errorCode": "2018", @@ -13,8 +12,7 @@ ", "message": "Function state mutability can be restricted to pure", "severity": "warning", - "sourceLocation": - { + "sourceLocation": { "end": 162, "file": "A", "start": 81 @@ -32,10 +30,8 @@ "type": "Info" } ], - "sources": - { - "A": - { + "sources": { + "A": { "id": 0 } } diff --git a/test/cmdlineTests/standard_model_checker_show_proved_safe_false_all_engines/output.json b/test/cmdlineTests/standard_model_checker_show_proved_safe_false_all_engines/output.json index b8118ba16a5d..4c57da4607c0 100644 --- a/test/cmdlineTests/standard_model_checker_show_proved_safe_false_all_engines/output.json +++ b/test/cmdlineTests/standard_model_checker_show_proved_safe_false_all_engines/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "errorCode": "2018", @@ -13,8 +12,7 @@ ", "message": "Function state mutability can be restricted to pure", "severity": "warning", - "sourceLocation": - { + "sourceLocation": { "end": 162, "file": "A", "start": 81 @@ -32,10 +30,8 @@ "type": "Info" } ], - "sources": - { - "A": - { + "sources": { + "A": { "id": 0 } } diff --git a/test/cmdlineTests/standard_model_checker_show_proved_safe_false_bmc/output.json b/test/cmdlineTests/standard_model_checker_show_proved_safe_false_bmc/output.json index eb6ed6e27705..6d9dbb4092b2 100644 --- a/test/cmdlineTests/standard_model_checker_show_proved_safe_false_bmc/output.json +++ b/test/cmdlineTests/standard_model_checker_show_proved_safe_false_bmc/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "errorCode": "2018", @@ -13,8 +12,7 @@ ", "message": "Function state mutability can be restricted to pure", "severity": "warning", - "sourceLocation": - { + "sourceLocation": { "end": 162, "file": "A", "start": 81 @@ -32,10 +30,8 @@ "type": "Info" } ], - "sources": - { - "A": - { + "sources": { + "A": { "id": 0 } } diff --git a/test/cmdlineTests/standard_model_checker_show_proved_safe_false_chc/output.json b/test/cmdlineTests/standard_model_checker_show_proved_safe_false_chc/output.json index b8118ba16a5d..4c57da4607c0 100644 --- a/test/cmdlineTests/standard_model_checker_show_proved_safe_false_chc/output.json +++ b/test/cmdlineTests/standard_model_checker_show_proved_safe_false_chc/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "errorCode": "2018", @@ -13,8 +12,7 @@ ", "message": "Function state mutability can be restricted to pure", "severity": "warning", - "sourceLocation": - { + "sourceLocation": { "end": 162, "file": "A", "start": 81 @@ -32,10 +30,8 @@ "type": "Info" } ], - "sources": - { - "A": - { + "sources": { + "A": { "id": 0 } } diff --git a/test/cmdlineTests/standard_model_checker_show_proved_safe_true_all_engines/output.json b/test/cmdlineTests/standard_model_checker_show_proved_safe_true_all_engines/output.json index 8482298559ec..22f863b12c64 100644 --- a/test/cmdlineTests/standard_model_checker_show_proved_safe_true_all_engines/output.json +++ b/test/cmdlineTests/standard_model_checker_show_proved_safe_true_all_engines/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "errorCode": "2018", @@ -13,8 +12,7 @@ ", "message": "Function state mutability can be restricted to pure", "severity": "warning", - "sourceLocation": - { + "sourceLocation": { "end": 162, "file": "A", "start": 81 @@ -33,8 +31,7 @@ ", "message": "CHC: Assertion violation check is safe!", "severity": "info", - "sourceLocation": - { + "sourceLocation": { "end": 130, "file": "A", "start": 116 @@ -53,8 +50,7 @@ ", "message": "CHC: Assertion violation check is safe!", "severity": "info", - "sourceLocation": - { + "sourceLocation": { "end": 154, "file": "A", "start": 138 @@ -62,10 +58,8 @@ "type": "Info" } ], - "sources": - { - "A": - { + "sources": { + "A": { "id": 0 } } diff --git a/test/cmdlineTests/standard_model_checker_show_proved_safe_true_bmc/output.json b/test/cmdlineTests/standard_model_checker_show_proved_safe_true_bmc/output.json index 20ddce1fd542..2788a64a8ac9 100644 --- a/test/cmdlineTests/standard_model_checker_show_proved_safe_true_bmc/output.json +++ b/test/cmdlineTests/standard_model_checker_show_proved_safe_true_bmc/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "errorCode": "2018", @@ -13,8 +12,7 @@ ", "message": "Function state mutability can be restricted to pure", "severity": "warning", - "sourceLocation": - { + "sourceLocation": { "end": 162, "file": "A", "start": 81 @@ -33,8 +31,7 @@ ", "message": "BMC: Assertion violation check is safe!", "severity": "info", - "sourceLocation": - { + "sourceLocation": { "end": 130, "file": "A", "start": 116 @@ -53,8 +50,7 @@ ", "message": "BMC: Assertion violation check is safe!", "severity": "info", - "sourceLocation": - { + "sourceLocation": { "end": 154, "file": "A", "start": 138 @@ -62,10 +58,8 @@ "type": "Info" } ], - "sources": - { - "A": - { + "sources": { + "A": { "id": 0 } } diff --git a/test/cmdlineTests/standard_model_checker_show_proved_safe_true_chc/output.json b/test/cmdlineTests/standard_model_checker_show_proved_safe_true_chc/output.json index 8482298559ec..22f863b12c64 100644 --- a/test/cmdlineTests/standard_model_checker_show_proved_safe_true_chc/output.json +++ b/test/cmdlineTests/standard_model_checker_show_proved_safe_true_chc/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "errorCode": "2018", @@ -13,8 +12,7 @@ ", "message": "Function state mutability can be restricted to pure", "severity": "warning", - "sourceLocation": - { + "sourceLocation": { "end": 162, "file": "A", "start": 81 @@ -33,8 +31,7 @@ ", "message": "CHC: Assertion violation check is safe!", "severity": "info", - "sourceLocation": - { + "sourceLocation": { "end": 130, "file": "A", "start": 116 @@ -53,8 +50,7 @@ ", "message": "CHC: Assertion violation check is safe!", "severity": "info", - "sourceLocation": - { + "sourceLocation": { "end": 154, "file": "A", "start": 138 @@ -62,10 +58,8 @@ "type": "Info" } ], - "sources": - { - "A": - { + "sources": { + "A": { "id": 0 } } diff --git a/test/cmdlineTests/standard_model_checker_show_proved_safe_wrong/output.json b/test/cmdlineTests/standard_model_checker_show_proved_safe_wrong/output.json index 7c8ccff6e2e5..b5811ff03505 100644 --- a/test/cmdlineTests/standard_model_checker_show_proved_safe_wrong/output.json +++ b/test/cmdlineTests/standard_model_checker_show_proved_safe_wrong/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "formattedMessage": "settings.modelChecker.showProvedSafe must be a Boolean value.", diff --git a/test/cmdlineTests/standard_model_checker_show_unproved_default_all_engines/output.json b/test/cmdlineTests/standard_model_checker_show_unproved_default_all_engines/output.json index fb599d21d2e4..da3b3dcad888 100644 --- a/test/cmdlineTests/standard_model_checker_show_unproved_default_all_engines/output.json +++ b/test/cmdlineTests/standard_model_checker_show_unproved_default_all_engines/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "errorCode": "5840", @@ -22,10 +21,8 @@ "type": "Warning" } ], - "sources": - { - "A": - { + "sources": { + "A": { "id": 0 } } diff --git a/test/cmdlineTests/standard_model_checker_show_unproved_false_all_engines/output.json b/test/cmdlineTests/standard_model_checker_show_unproved_false_all_engines/output.json index fb599d21d2e4..da3b3dcad888 100644 --- a/test/cmdlineTests/standard_model_checker_show_unproved_false_all_engines/output.json +++ b/test/cmdlineTests/standard_model_checker_show_unproved_false_all_engines/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "errorCode": "5840", @@ -22,10 +21,8 @@ "type": "Warning" } ], - "sources": - { - "A": - { + "sources": { + "A": { "id": 0 } } diff --git a/test/cmdlineTests/standard_model_checker_show_unproved_false_bmc/output.json b/test/cmdlineTests/standard_model_checker_show_unproved_false_bmc/output.json index 4554ec69e93a..67f8df731994 100644 --- a/test/cmdlineTests/standard_model_checker_show_unproved_false_bmc/output.json +++ b/test/cmdlineTests/standard_model_checker_show_unproved_false_bmc/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "errorCode": "2788", @@ -12,10 +11,8 @@ "type": "Warning" } ], - "sources": - { - "A": - { + "sources": { + "A": { "id": 0 } } diff --git a/test/cmdlineTests/standard_model_checker_show_unproved_false_chc/output.json b/test/cmdlineTests/standard_model_checker_show_unproved_false_chc/output.json index 7f0e676cb818..66cdf505c609 100644 --- a/test/cmdlineTests/standard_model_checker_show_unproved_false_chc/output.json +++ b/test/cmdlineTests/standard_model_checker_show_unproved_false_chc/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "errorCode": "5840", @@ -12,10 +11,8 @@ "type": "Warning" } ], - "sources": - { - "A": - { + "sources": { + "A": { "id": 0 } } diff --git a/test/cmdlineTests/standard_model_checker_show_unproved_true_all_engines/output.json b/test/cmdlineTests/standard_model_checker_show_unproved_true_all_engines/output.json index ecb157f88fbc..b6153de5ebe5 100644 --- a/test/cmdlineTests/standard_model_checker_show_unproved_true_all_engines/output.json +++ b/test/cmdlineTests/standard_model_checker_show_unproved_true_all_engines/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "errorCode": "6328", @@ -13,8 +12,7 @@ ", "message": "CHC: Assertion violation might happen here.", "severity": "warning", - "sourceLocation": - { + "sourceLocation": { "end": 201, "file": "A", "start": 186 @@ -33,15 +31,13 @@ Note: ", "message": "BMC: Assertion violation might happen here.", - "secondarySourceLocations": - [ + "secondarySourceLocations": [ { "message": "" } ], "severity": "warning", - "sourceLocation": - { + "sourceLocation": { "end": 201, "file": "A", "start": 186 @@ -49,10 +45,8 @@ Note: "type": "Warning" } ], - "sources": - { - "A": - { + "sources": { + "A": { "id": 0 } } diff --git a/test/cmdlineTests/standard_model_checker_show_unproved_true_bmc/output.json b/test/cmdlineTests/standard_model_checker_show_unproved_true_bmc/output.json index 116af8dce28c..6c3b57c79553 100644 --- a/test/cmdlineTests/standard_model_checker_show_unproved_true_bmc/output.json +++ b/test/cmdlineTests/standard_model_checker_show_unproved_true_bmc/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "errorCode": "7812", @@ -13,15 +12,13 @@ Note: ", "message": "BMC: Assertion violation might happen here.", - "secondarySourceLocations": - [ + "secondarySourceLocations": [ { "message": "" } ], "severity": "warning", - "sourceLocation": - { + "sourceLocation": { "end": 201, "file": "A", "start": 186 @@ -29,10 +26,8 @@ Note: "type": "Warning" } ], - "sources": - { - "A": - { + "sources": { + "A": { "id": 0 } } diff --git a/test/cmdlineTests/standard_model_checker_show_unproved_true_chc/output.json b/test/cmdlineTests/standard_model_checker_show_unproved_true_chc/output.json index 58956287fd52..78efcad94963 100644 --- a/test/cmdlineTests/standard_model_checker_show_unproved_true_chc/output.json +++ b/test/cmdlineTests/standard_model_checker_show_unproved_true_chc/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "errorCode": "6328", @@ -13,8 +12,7 @@ ", "message": "CHC: Assertion violation might happen here.", "severity": "warning", - "sourceLocation": - { + "sourceLocation": { "end": 201, "file": "A", "start": 186 @@ -22,10 +20,8 @@ "type": "Warning" } ], - "sources": - { - "A": - { + "sources": { + "A": { "id": 0 } } diff --git a/test/cmdlineTests/standard_model_checker_show_unproved_wrong/output.json b/test/cmdlineTests/standard_model_checker_show_unproved_wrong/output.json index a9342cddfbb7..49b97bab572c 100644 --- a/test/cmdlineTests/standard_model_checker_show_unproved_wrong/output.json +++ b/test/cmdlineTests/standard_model_checker_show_unproved_wrong/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "formattedMessage": "settings.modelChecker.showUnproved must be a Boolean value.", diff --git a/test/cmdlineTests/standard_model_checker_show_unsupported_default_all_engines/output.json b/test/cmdlineTests/standard_model_checker_show_unsupported_default_all_engines/output.json index 23cf80defb86..b8f8515b8b4a 100644 --- a/test/cmdlineTests/standard_model_checker_show_unsupported_default_all_engines/output.json +++ b/test/cmdlineTests/standard_model_checker_show_unsupported_default_all_engines/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "errorCode": "5724", @@ -12,10 +11,8 @@ "type": "Warning" } ], - "sources": - { - "A": - { + "sources": { + "A": { "id": 0 } } diff --git a/test/cmdlineTests/standard_model_checker_show_unsupported_default_bmc/output.json b/test/cmdlineTests/standard_model_checker_show_unsupported_default_bmc/output.json index 23cf80defb86..b8f8515b8b4a 100644 --- a/test/cmdlineTests/standard_model_checker_show_unsupported_default_bmc/output.json +++ b/test/cmdlineTests/standard_model_checker_show_unsupported_default_bmc/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "errorCode": "5724", @@ -12,10 +11,8 @@ "type": "Warning" } ], - "sources": - { - "A": - { + "sources": { + "A": { "id": 0 } } diff --git a/test/cmdlineTests/standard_model_checker_show_unsupported_default_chc/output.json b/test/cmdlineTests/standard_model_checker_show_unsupported_default_chc/output.json index 23cf80defb86..b8f8515b8b4a 100644 --- a/test/cmdlineTests/standard_model_checker_show_unsupported_default_chc/output.json +++ b/test/cmdlineTests/standard_model_checker_show_unsupported_default_chc/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "errorCode": "5724", @@ -12,10 +11,8 @@ "type": "Warning" } ], - "sources": - { - "A": - { + "sources": { + "A": { "id": 0 } } diff --git a/test/cmdlineTests/standard_model_checker_show_unsupported_false_all_engines/output.json b/test/cmdlineTests/standard_model_checker_show_unsupported_false_all_engines/output.json index 23cf80defb86..b8f8515b8b4a 100644 --- a/test/cmdlineTests/standard_model_checker_show_unsupported_false_all_engines/output.json +++ b/test/cmdlineTests/standard_model_checker_show_unsupported_false_all_engines/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "errorCode": "5724", @@ -12,10 +11,8 @@ "type": "Warning" } ], - "sources": - { - "A": - { + "sources": { + "A": { "id": 0 } } diff --git a/test/cmdlineTests/standard_model_checker_show_unsupported_false_bmc/output.json b/test/cmdlineTests/standard_model_checker_show_unsupported_false_bmc/output.json index 23cf80defb86..b8f8515b8b4a 100644 --- a/test/cmdlineTests/standard_model_checker_show_unsupported_false_bmc/output.json +++ b/test/cmdlineTests/standard_model_checker_show_unsupported_false_bmc/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "errorCode": "5724", @@ -12,10 +11,8 @@ "type": "Warning" } ], - "sources": - { - "A": - { + "sources": { + "A": { "id": 0 } } diff --git a/test/cmdlineTests/standard_model_checker_show_unsupported_false_chc/output.json b/test/cmdlineTests/standard_model_checker_show_unsupported_false_chc/output.json index 23cf80defb86..b8f8515b8b4a 100644 --- a/test/cmdlineTests/standard_model_checker_show_unsupported_false_chc/output.json +++ b/test/cmdlineTests/standard_model_checker_show_unsupported_false_chc/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "errorCode": "5724", @@ -12,10 +11,8 @@ "type": "Warning" } ], - "sources": - { - "A": - { + "sources": { + "A": { "id": 0 } } diff --git a/test/cmdlineTests/standard_model_checker_show_unsupported_true_all_engines/output.json b/test/cmdlineTests/standard_model_checker_show_unsupported_true_all_engines/output.json index 13d327d40547..e9eb877ea055 100644 --- a/test/cmdlineTests/standard_model_checker_show_unsupported_true_all_engines/output.json +++ b/test/cmdlineTests/standard_model_checker_show_unsupported_true_all_engines/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "errorCode": "7737", @@ -13,8 +12,7 @@ ", "message": "Inline assembly may cause SMTChecker to produce spurious warnings (false positives).", "severity": "warning", - "sourceLocation": - { + "sourceLocation": { "end": 127, "file": "A", "start": 116 @@ -22,10 +20,8 @@ "type": "Warning" } ], - "sources": - { - "A": - { + "sources": { + "A": { "id": 0 } } diff --git a/test/cmdlineTests/standard_model_checker_show_unsupported_true_bmc/output.json b/test/cmdlineTests/standard_model_checker_show_unsupported_true_bmc/output.json index 13d327d40547..e9eb877ea055 100644 --- a/test/cmdlineTests/standard_model_checker_show_unsupported_true_bmc/output.json +++ b/test/cmdlineTests/standard_model_checker_show_unsupported_true_bmc/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "errorCode": "7737", @@ -13,8 +12,7 @@ ", "message": "Inline assembly may cause SMTChecker to produce spurious warnings (false positives).", "severity": "warning", - "sourceLocation": - { + "sourceLocation": { "end": 127, "file": "A", "start": 116 @@ -22,10 +20,8 @@ "type": "Warning" } ], - "sources": - { - "A": - { + "sources": { + "A": { "id": 0 } } diff --git a/test/cmdlineTests/standard_model_checker_show_unsupported_true_chc/output.json b/test/cmdlineTests/standard_model_checker_show_unsupported_true_chc/output.json index 13d327d40547..e9eb877ea055 100644 --- a/test/cmdlineTests/standard_model_checker_show_unsupported_true_chc/output.json +++ b/test/cmdlineTests/standard_model_checker_show_unsupported_true_chc/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "errorCode": "7737", @@ -13,8 +12,7 @@ ", "message": "Inline assembly may cause SMTChecker to produce spurious warnings (false positives).", "severity": "warning", - "sourceLocation": - { + "sourceLocation": { "end": 127, "file": "A", "start": 116 @@ -22,10 +20,8 @@ "type": "Warning" } ], - "sources": - { - "A": - { + "sources": { + "A": { "id": 0 } } diff --git a/test/cmdlineTests/standard_model_checker_show_unsupported_wrong/output.json b/test/cmdlineTests/standard_model_checker_show_unsupported_wrong/output.json index 997b005ef7ee..068c3a872b7e 100644 --- a/test/cmdlineTests/standard_model_checker_show_unsupported_wrong/output.json +++ b/test/cmdlineTests/standard_model_checker_show_unsupported_wrong/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "formattedMessage": "settings.modelChecker.showUnsupported must be a Boolean value.", diff --git a/test/cmdlineTests/standard_model_checker_solvers_none/output.json b/test/cmdlineTests/standard_model_checker_solvers_none/output.json index e5d356ce5a9d..e8de49d1ede3 100644 --- a/test/cmdlineTests/standard_model_checker_solvers_none/output.json +++ b/test/cmdlineTests/standard_model_checker_solvers_none/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "errorCode": "7649", @@ -22,10 +21,8 @@ "type": "Warning" } ], - "sources": - { - "A": - { + "sources": { + "A": { "id": 0 } } diff --git a/test/cmdlineTests/standard_model_checker_solvers_smtlib2/output.json b/test/cmdlineTests/standard_model_checker_solvers_smtlib2/output.json index ebeca53f5ba3..d3bdc6b7eb28 100644 --- a/test/cmdlineTests/standard_model_checker_solvers_smtlib2/output.json +++ b/test/cmdlineTests/standard_model_checker_solvers_smtlib2/output.json @@ -1,8 +1,6 @@ { - "auxiliaryInputRequested": - { - "smtlib2queries": - { + "auxiliaryInputRequested": { + "smtlib2queries": { "0x75b95497d56c30e254a59358d72ddd4e78f9e90db621cfe677e85d05b2252411": "(set-option :produce-models true) (set-logic ALL) (declare-fun |x_3_3| () Int) @@ -155,8 +153,7 @@ " } }, - "errors": - [ + "errors": [ { "component": "general", "errorCode": "5840", @@ -198,10 +195,8 @@ "type": "Warning" } ], - "sources": - { - "A": - { + "sources": { + "A": { "id": 0 } } diff --git a/test/cmdlineTests/standard_model_checker_solvers_z3/output.json b/test/cmdlineTests/standard_model_checker_solvers_z3/output.json index 2a2c394fdd72..be51d6b2e518 100644 --- a/test/cmdlineTests/standard_model_checker_solvers_z3/output.json +++ b/test/cmdlineTests/standard_model_checker_solvers_z3/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "errorCode": "6328", @@ -27,8 +26,7 @@ Transaction trace: C.constructor() C.f(0)", "severity": "warning", - "sourceLocation": - { + "sourceLocation": { "end": 119, "file": "A", "start": 106 @@ -36,10 +34,8 @@ C.f(0)", "type": "Warning" } ], - "sources": - { - "A": - { + "sources": { + "A": { "id": 0 } } diff --git a/test/cmdlineTests/standard_model_checker_solvers_z3_smtlib2/output.json b/test/cmdlineTests/standard_model_checker_solvers_z3_smtlib2/output.json index 2a2c394fdd72..be51d6b2e518 100644 --- a/test/cmdlineTests/standard_model_checker_solvers_z3_smtlib2/output.json +++ b/test/cmdlineTests/standard_model_checker_solvers_z3_smtlib2/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "errorCode": "6328", @@ -27,8 +26,7 @@ Transaction trace: C.constructor() C.f(0)", "severity": "warning", - "sourceLocation": - { + "sourceLocation": { "end": 119, "file": "A", "start": 106 @@ -36,10 +34,8 @@ C.f(0)", "type": "Warning" } ], - "sources": - { - "A": - { + "sources": { + "A": { "id": 0 } } diff --git a/test/cmdlineTests/standard_model_checker_targets_assert_bmc/output.json b/test/cmdlineTests/standard_model_checker_targets_assert_bmc/output.json index 18452ccbc985..9e90ec538d35 100644 --- a/test/cmdlineTests/standard_model_checker_targets_assert_bmc/output.json +++ b/test/cmdlineTests/standard_model_checker_targets_assert_bmc/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "errorCode": "4661", @@ -18,8 +17,7 @@ Note: ", "message": "BMC: Assertion violation happens here.", - "secondarySourceLocations": - [ + "secondarySourceLocations": [ { "message": "Counterexample: a = 0 @@ -34,8 +32,7 @@ Note: } ], "severity": "warning", - "sourceLocation": - { + "sourceLocation": { "end": 258, "file": "A", "start": 245 @@ -43,10 +40,8 @@ Note: "type": "Warning" } ], - "sources": - { - "A": - { + "sources": { + "A": { "id": 0 } } diff --git a/test/cmdlineTests/standard_model_checker_targets_assert_chc/output.json b/test/cmdlineTests/standard_model_checker_targets_assert_chc/output.json index 5c43fe6b54d8..bf4fa6626933 100644 --- a/test/cmdlineTests/standard_model_checker_targets_assert_chc/output.json +++ b/test/cmdlineTests/standard_model_checker_targets_assert_chc/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "errorCode": "6328", @@ -31,8 +30,7 @@ test.constructor() State: arr = [] test.f(0x0, 1)", "severity": "warning", - "sourceLocation": - { + "sourceLocation": { "end": 258, "file": "A", "start": 245 @@ -40,10 +38,8 @@ test.f(0x0, 1)", "type": "Warning" } ], - "sources": - { - "A": - { + "sources": { + "A": { "id": 0 } } diff --git a/test/cmdlineTests/standard_model_checker_targets_balance_bmc/output.json b/test/cmdlineTests/standard_model_checker_targets_balance_bmc/output.json index 9ee51daba1fb..6c2c90c9888b 100644 --- a/test/cmdlineTests/standard_model_checker_targets_balance_bmc/output.json +++ b/test/cmdlineTests/standard_model_checker_targets_balance_bmc/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "errorCode": "1236", @@ -18,8 +17,7 @@ Note: ", "message": "BMC: Insufficient funds happens here.", - "secondarySourceLocations": - [ + "secondarySourceLocations": [ { "message": "Counterexample: a = 0 @@ -34,8 +32,7 @@ Note: } ], "severity": "warning", - "sourceLocation": - { + "sourceLocation": { "end": 237, "file": "A", "start": 224 @@ -43,10 +40,8 @@ Note: "type": "Warning" } ], - "sources": - { - "A": - { + "sources": { + "A": { "id": 0 } } diff --git a/test/cmdlineTests/standard_model_checker_targets_balance_chc/output.json b/test/cmdlineTests/standard_model_checker_targets_balance_chc/output.json index acf3b74ef1de..f047ff70a9eb 100644 --- a/test/cmdlineTests/standard_model_checker_targets_balance_chc/output.json +++ b/test/cmdlineTests/standard_model_checker_targets_balance_chc/output.json @@ -1,8 +1,6 @@ { - "sources": - { - "A": - { + "sources": { + "A": { "id": 0 } } diff --git a/test/cmdlineTests/standard_model_checker_targets_constantCondition_bmc/output.json b/test/cmdlineTests/standard_model_checker_targets_constantCondition_bmc/output.json index 94ba81c2bea4..9bfdf0b02111 100644 --- a/test/cmdlineTests/standard_model_checker_targets_constantCondition_bmc/output.json +++ b/test/cmdlineTests/standard_model_checker_targets_constantCondition_bmc/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "errorCode": "6838", @@ -13,15 +12,13 @@ Note: Callstack: ", "message": "BMC: Condition is always true.", - "secondarySourceLocations": - [ + "secondarySourceLocations": [ { "message": "Callstack:" } ], "severity": "warning", - "sourceLocation": - { + "sourceLocation": { "end": 165, "file": "A", "start": 159 @@ -29,10 +26,8 @@ Note: Callstack: "type": "Warning" } ], - "sources": - { - "A": - { + "sources": { + "A": { "id": 0 } } diff --git a/test/cmdlineTests/standard_model_checker_targets_constantCondition_chc/output.json b/test/cmdlineTests/standard_model_checker_targets_constantCondition_chc/output.json index acf3b74ef1de..f047ff70a9eb 100644 --- a/test/cmdlineTests/standard_model_checker_targets_constantCondition_chc/output.json +++ b/test/cmdlineTests/standard_model_checker_targets_constantCondition_chc/output.json @@ -1,8 +1,6 @@ { - "sources": - { - "A": - { + "sources": { + "A": { "id": 0 } } diff --git a/test/cmdlineTests/standard_model_checker_targets_default_all_engines/output.json b/test/cmdlineTests/standard_model_checker_targets_default_all_engines/output.json index 4c967fa5d0ae..2318e5adfaba 100644 --- a/test/cmdlineTests/standard_model_checker_targets_default_all_engines/output.json +++ b/test/cmdlineTests/standard_model_checker_targets_default_all_engines/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "errorCode": "4281", @@ -31,8 +30,7 @@ test.constructor() State: arr = [] test.f(0x0, 1)", "severity": "warning", - "sourceLocation": - { + "sourceLocation": { "end": 216, "file": "A", "start": 211 @@ -69,8 +67,7 @@ test.constructor() State: arr = [] test.f(0x0, 1)", "severity": "warning", - "sourceLocation": - { + "sourceLocation": { "end": 258, "file": "A", "start": 245 @@ -107,8 +104,7 @@ test.constructor() State: arr = [] test.f(0x0, 1)", "severity": "warning", - "sourceLocation": - { + "sourceLocation": { "end": 275, "file": "A", "start": 266 @@ -145,8 +141,7 @@ test.constructor() State: arr = [] test.f(0x0, 1)", "severity": "warning", - "sourceLocation": - { + "sourceLocation": { "end": 289, "file": "A", "start": 283 @@ -165,15 +160,13 @@ Note: Callstack: ", "message": "BMC: Condition is always true.", - "secondarySourceLocations": - [ + "secondarySourceLocations": [ { "message": "Callstack:" } ], "severity": "warning", - "sourceLocation": - { + "sourceLocation": { "end": 165, "file": "A", "start": 159 @@ -197,8 +190,7 @@ Note: ", "message": "BMC: Insufficient funds happens here.", - "secondarySourceLocations": - [ + "secondarySourceLocations": [ { "message": "Counterexample: a = 0 @@ -213,8 +205,7 @@ Note: } ], "severity": "warning", - "sourceLocation": - { + "sourceLocation": { "end": 237, "file": "A", "start": 224 @@ -222,10 +213,8 @@ Note: "type": "Warning" } ], - "sources": - { - "A": - { + "sources": { + "A": { "id": 0 } } diff --git a/test/cmdlineTests/standard_model_checker_targets_default_bmc/output.json b/test/cmdlineTests/standard_model_checker_targets_default_bmc/output.json index 1be99ca4556c..e055d38d2e53 100644 --- a/test/cmdlineTests/standard_model_checker_targets_default_bmc/output.json +++ b/test/cmdlineTests/standard_model_checker_targets_default_bmc/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "errorCode": "6838", @@ -13,15 +12,13 @@ Note: Callstack: ", "message": "BMC: Condition is always true.", - "secondarySourceLocations": - [ + "secondarySourceLocations": [ { "message": "Callstack:" } ], "severity": "warning", - "sourceLocation": - { + "sourceLocation": { "end": 165, "file": "A", "start": 159 @@ -46,8 +43,7 @@ Note: ", "message": "BMC: Division by zero happens here.", - "secondarySourceLocations": - [ + "secondarySourceLocations": [ { "message": "Counterexample: = 0 @@ -63,8 +59,7 @@ Note: } ], "severity": "warning", - "sourceLocation": - { + "sourceLocation": { "end": 216, "file": "A", "start": 211 @@ -88,8 +83,7 @@ Note: ", "message": "BMC: Insufficient funds happens here.", - "secondarySourceLocations": - [ + "secondarySourceLocations": [ { "message": "Counterexample: a = 0 @@ -104,8 +98,7 @@ Note: } ], "severity": "warning", - "sourceLocation": - { + "sourceLocation": { "end": 237, "file": "A", "start": 224 @@ -129,8 +122,7 @@ Note: ", "message": "BMC: Assertion violation happens here.", - "secondarySourceLocations": - [ + "secondarySourceLocations": [ { "message": "Counterexample: a = 0 @@ -145,8 +137,7 @@ Note: } ], "severity": "warning", - "sourceLocation": - { + "sourceLocation": { "end": 258, "file": "A", "start": 245 @@ -154,10 +145,8 @@ Note: "type": "Warning" } ], - "sources": - { - "A": - { + "sources": { + "A": { "id": 0 } } diff --git a/test/cmdlineTests/standard_model_checker_targets_default_chc/output.json b/test/cmdlineTests/standard_model_checker_targets_default_chc/output.json index c3df366c990d..eb39e0271233 100644 --- a/test/cmdlineTests/standard_model_checker_targets_default_chc/output.json +++ b/test/cmdlineTests/standard_model_checker_targets_default_chc/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "errorCode": "4281", @@ -31,8 +30,7 @@ test.constructor() State: arr = [] test.f(0x0, 1)", "severity": "warning", - "sourceLocation": - { + "sourceLocation": { "end": 216, "file": "A", "start": 211 @@ -69,8 +67,7 @@ test.constructor() State: arr = [] test.f(0x0, 1)", "severity": "warning", - "sourceLocation": - { + "sourceLocation": { "end": 258, "file": "A", "start": 245 @@ -107,8 +104,7 @@ test.constructor() State: arr = [] test.f(0x0, 1)", "severity": "warning", - "sourceLocation": - { + "sourceLocation": { "end": 275, "file": "A", "start": 266 @@ -145,8 +141,7 @@ test.constructor() State: arr = [] test.f(0x0, 1)", "severity": "warning", - "sourceLocation": - { + "sourceLocation": { "end": 289, "file": "A", "start": 283 @@ -154,10 +149,8 @@ test.f(0x0, 1)", "type": "Warning" } ], - "sources": - { - "A": - { + "sources": { + "A": { "id": 0 } } diff --git a/test/cmdlineTests/standard_model_checker_targets_div_by_zero_bmc/output.json b/test/cmdlineTests/standard_model_checker_targets_div_by_zero_bmc/output.json index 05ce12ca2c2b..6ba0e6f82057 100644 --- a/test/cmdlineTests/standard_model_checker_targets_div_by_zero_bmc/output.json +++ b/test/cmdlineTests/standard_model_checker_targets_div_by_zero_bmc/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "errorCode": "3046", @@ -19,8 +18,7 @@ Note: ", "message": "BMC: Division by zero happens here.", - "secondarySourceLocations": - [ + "secondarySourceLocations": [ { "message": "Counterexample: = 0 @@ -36,8 +34,7 @@ Note: } ], "severity": "warning", - "sourceLocation": - { + "sourceLocation": { "end": 216, "file": "A", "start": 211 @@ -45,10 +42,8 @@ Note: "type": "Warning" } ], - "sources": - { - "A": - { + "sources": { + "A": { "id": 0 } } diff --git a/test/cmdlineTests/standard_model_checker_targets_div_by_zero_chc/output.json b/test/cmdlineTests/standard_model_checker_targets_div_by_zero_chc/output.json index 5c09175e7297..0789c79996fe 100644 --- a/test/cmdlineTests/standard_model_checker_targets_div_by_zero_chc/output.json +++ b/test/cmdlineTests/standard_model_checker_targets_div_by_zero_chc/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "errorCode": "4281", @@ -31,8 +30,7 @@ test.constructor() State: arr = [] test.f(0x0, 1)", "severity": "warning", - "sourceLocation": - { + "sourceLocation": { "end": 216, "file": "A", "start": 211 @@ -40,10 +38,8 @@ test.f(0x0, 1)", "type": "Warning" } ], - "sources": - { - "A": - { + "sources": { + "A": { "id": 0 } } diff --git a/test/cmdlineTests/standard_model_checker_targets_empty_array/output.json b/test/cmdlineTests/standard_model_checker_targets_empty_array/output.json index 312af9741c32..6b5c6e0689da 100644 --- a/test/cmdlineTests/standard_model_checker_targets_empty_array/output.json +++ b/test/cmdlineTests/standard_model_checker_targets_empty_array/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "formattedMessage": "settings.modelChecker.targets must be a non-empty array.", diff --git a/test/cmdlineTests/standard_model_checker_targets_out_of_bounds_bmc/output.json b/test/cmdlineTests/standard_model_checker_targets_out_of_bounds_bmc/output.json index acf3b74ef1de..f047ff70a9eb 100644 --- a/test/cmdlineTests/standard_model_checker_targets_out_of_bounds_bmc/output.json +++ b/test/cmdlineTests/standard_model_checker_targets_out_of_bounds_bmc/output.json @@ -1,8 +1,6 @@ { - "sources": - { - "A": - { + "sources": { + "A": { "id": 0 } } diff --git a/test/cmdlineTests/standard_model_checker_targets_out_of_bounds_chc/output.json b/test/cmdlineTests/standard_model_checker_targets_out_of_bounds_chc/output.json index b87480e74b4c..f5f49fb508e7 100644 --- a/test/cmdlineTests/standard_model_checker_targets_out_of_bounds_chc/output.json +++ b/test/cmdlineTests/standard_model_checker_targets_out_of_bounds_chc/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "errorCode": "6368", @@ -31,8 +30,7 @@ test.constructor() State: arr = [] test.f(0x0, 1)", "severity": "warning", - "sourceLocation": - { + "sourceLocation": { "end": 289, "file": "A", "start": 283 @@ -40,10 +38,8 @@ test.f(0x0, 1)", "type": "Warning" } ], - "sources": - { - "A": - { + "sources": { + "A": { "id": 0 } } diff --git a/test/cmdlineTests/standard_model_checker_targets_overflow_bmc/output.json b/test/cmdlineTests/standard_model_checker_targets_overflow_bmc/output.json index 09c1cdb5f10a..8d34765cdb14 100644 --- a/test/cmdlineTests/standard_model_checker_targets_overflow_bmc/output.json +++ b/test/cmdlineTests/standard_model_checker_targets_overflow_bmc/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "errorCode": "2661", @@ -19,8 +18,7 @@ Note: ", "message": "BMC: Overflow (resulting value larger than 2**256 - 1) happens here.", - "secondarySourceLocations": - [ + "secondarySourceLocations": [ { "message": "Counterexample: = 2**256 @@ -36,8 +34,7 @@ Note: } ], "severity": "warning", - "sourceLocation": - { + "sourceLocation": { "end": 203, "file": "A", "start": 185 @@ -45,10 +42,8 @@ Note: "type": "Warning" } ], - "sources": - { - "A": - { + "sources": { + "A": { "id": 0 } } diff --git a/test/cmdlineTests/standard_model_checker_targets_overflow_chc/output.json b/test/cmdlineTests/standard_model_checker_targets_overflow_chc/output.json index b700a938ed14..9beb30a35b7c 100644 --- a/test/cmdlineTests/standard_model_checker_targets_overflow_chc/output.json +++ b/test/cmdlineTests/standard_model_checker_targets_overflow_chc/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "errorCode": "4984", @@ -31,8 +30,7 @@ test.constructor() State: arr = [] test.f(0x0, 2)", "severity": "warning", - "sourceLocation": - { + "sourceLocation": { "end": 203, "file": "A", "start": 185 @@ -40,10 +38,8 @@ test.f(0x0, 2)", "type": "Warning" } ], - "sources": - { - "A": - { + "sources": { + "A": { "id": 0 } } diff --git a/test/cmdlineTests/standard_model_checker_targets_pop_empty_bmc/output.json b/test/cmdlineTests/standard_model_checker_targets_pop_empty_bmc/output.json index acf3b74ef1de..f047ff70a9eb 100644 --- a/test/cmdlineTests/standard_model_checker_targets_pop_empty_bmc/output.json +++ b/test/cmdlineTests/standard_model_checker_targets_pop_empty_bmc/output.json @@ -1,8 +1,6 @@ { - "sources": - { - "A": - { + "sources": { + "A": { "id": 0 } } diff --git a/test/cmdlineTests/standard_model_checker_targets_pop_empty_chc/output.json b/test/cmdlineTests/standard_model_checker_targets_pop_empty_chc/output.json index c670bb4f6088..4cccf8456df4 100644 --- a/test/cmdlineTests/standard_model_checker_targets_pop_empty_chc/output.json +++ b/test/cmdlineTests/standard_model_checker_targets_pop_empty_chc/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "errorCode": "2529", @@ -31,8 +30,7 @@ test.constructor() State: arr = [] test.f(0x0, 1)", "severity": "warning", - "sourceLocation": - { + "sourceLocation": { "end": 275, "file": "A", "start": 266 @@ -40,10 +38,8 @@ test.f(0x0, 1)", "type": "Warning" } ], - "sources": - { - "A": - { + "sources": { + "A": { "id": 0 } } diff --git a/test/cmdlineTests/standard_model_checker_targets_underflow_bmc/output.json b/test/cmdlineTests/standard_model_checker_targets_underflow_bmc/output.json index c656eda21a9c..df17886b2fea 100644 --- a/test/cmdlineTests/standard_model_checker_targets_underflow_bmc/output.json +++ b/test/cmdlineTests/standard_model_checker_targets_underflow_bmc/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "errorCode": "4144", @@ -19,8 +18,7 @@ Note: ", "message": "BMC: Underflow (resulting value less than 0) happens here.", - "secondarySourceLocations": - [ + "secondarySourceLocations": [ { "message": "Counterexample: = (- 1) @@ -36,8 +34,7 @@ Note: } ], "severity": "warning", - "sourceLocation": - { + "sourceLocation": { "end": 177, "file": "A", "start": 174 @@ -45,10 +42,8 @@ Note: "type": "Warning" } ], - "sources": - { - "A": - { + "sources": { + "A": { "id": 0 } } diff --git a/test/cmdlineTests/standard_model_checker_targets_underflow_chc/output.json b/test/cmdlineTests/standard_model_checker_targets_underflow_chc/output.json index 600d7fe6b842..442f2f47a981 100644 --- a/test/cmdlineTests/standard_model_checker_targets_underflow_chc/output.json +++ b/test/cmdlineTests/standard_model_checker_targets_underflow_chc/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "errorCode": "3944", @@ -31,8 +30,7 @@ test.constructor() State: arr = [] test.f(0x0, 0)", "severity": "warning", - "sourceLocation": - { + "sourceLocation": { "end": 177, "file": "A", "start": 174 @@ -40,10 +38,8 @@ test.f(0x0, 0)", "type": "Warning" } ], - "sources": - { - "A": - { + "sources": { + "A": { "id": 0 } } diff --git a/test/cmdlineTests/standard_model_checker_targets_underflow_overflow_assert_bmc/output.json b/test/cmdlineTests/standard_model_checker_targets_underflow_overflow_assert_bmc/output.json index 004b98128e2c..c80d3e22a8e2 100644 --- a/test/cmdlineTests/standard_model_checker_targets_underflow_overflow_assert_bmc/output.json +++ b/test/cmdlineTests/standard_model_checker_targets_underflow_overflow_assert_bmc/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "errorCode": "4144", @@ -19,8 +18,7 @@ Note: ", "message": "BMC: Underflow (resulting value less than 0) happens here.", - "secondarySourceLocations": - [ + "secondarySourceLocations": [ { "message": "Counterexample: = (- 1) @@ -36,8 +34,7 @@ Note: } ], "severity": "warning", - "sourceLocation": - { + "sourceLocation": { "end": 177, "file": "A", "start": 174 @@ -62,8 +59,7 @@ Note: ", "message": "BMC: Overflow (resulting value larger than 2**256 - 1) happens here.", - "secondarySourceLocations": - [ + "secondarySourceLocations": [ { "message": "Counterexample: = 2**256 @@ -79,8 +75,7 @@ Note: } ], "severity": "warning", - "sourceLocation": - { + "sourceLocation": { "end": 203, "file": "A", "start": 185 @@ -104,8 +99,7 @@ Note: ", "message": "BMC: Assertion violation happens here.", - "secondarySourceLocations": - [ + "secondarySourceLocations": [ { "message": "Counterexample: a = 0 @@ -120,8 +114,7 @@ Note: } ], "severity": "warning", - "sourceLocation": - { + "sourceLocation": { "end": 258, "file": "A", "start": 245 @@ -129,10 +122,8 @@ Note: "type": "Warning" } ], - "sources": - { - "A": - { + "sources": { + "A": { "id": 0 } } diff --git a/test/cmdlineTests/standard_model_checker_targets_underflow_overflow_assert_chc/output.json b/test/cmdlineTests/standard_model_checker_targets_underflow_overflow_assert_chc/output.json index 5afeeaa9407e..e5719640aad3 100644 --- a/test/cmdlineTests/standard_model_checker_targets_underflow_overflow_assert_chc/output.json +++ b/test/cmdlineTests/standard_model_checker_targets_underflow_overflow_assert_chc/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "errorCode": "3944", @@ -31,8 +30,7 @@ test.constructor() State: arr = [] test.f(0x0, 0)", "severity": "warning", - "sourceLocation": - { + "sourceLocation": { "end": 177, "file": "A", "start": 174 @@ -69,8 +67,7 @@ test.constructor() State: arr = [] test.f(0x0, 2)", "severity": "warning", - "sourceLocation": - { + "sourceLocation": { "end": 203, "file": "A", "start": 185 @@ -107,8 +104,7 @@ test.constructor() State: arr = [] test.f(0x0, 1)", "severity": "warning", - "sourceLocation": - { + "sourceLocation": { "end": 258, "file": "A", "start": 245 @@ -116,10 +112,8 @@ test.f(0x0, 1)", "type": "Warning" } ], - "sources": - { - "A": - { + "sources": { + "A": { "id": 0 } } diff --git a/test/cmdlineTests/standard_model_checker_targets_underflow_overflow_bmc/output.json b/test/cmdlineTests/standard_model_checker_targets_underflow_overflow_bmc/output.json index 8a9452a7b83d..de02d57c90ab 100644 --- a/test/cmdlineTests/standard_model_checker_targets_underflow_overflow_bmc/output.json +++ b/test/cmdlineTests/standard_model_checker_targets_underflow_overflow_bmc/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "errorCode": "4144", @@ -19,8 +18,7 @@ Note: ", "message": "BMC: Underflow (resulting value less than 0) happens here.", - "secondarySourceLocations": - [ + "secondarySourceLocations": [ { "message": "Counterexample: = (- 1) @@ -36,8 +34,7 @@ Note: } ], "severity": "warning", - "sourceLocation": - { + "sourceLocation": { "end": 177, "file": "A", "start": 174 @@ -62,8 +59,7 @@ Note: ", "message": "BMC: Overflow (resulting value larger than 2**256 - 1) happens here.", - "secondarySourceLocations": - [ + "secondarySourceLocations": [ { "message": "Counterexample: = 2**256 @@ -79,8 +75,7 @@ Note: } ], "severity": "warning", - "sourceLocation": - { + "sourceLocation": { "end": 203, "file": "A", "start": 185 @@ -88,10 +83,8 @@ Note: "type": "Warning" } ], - "sources": - { - "A": - { + "sources": { + "A": { "id": 0 } } diff --git a/test/cmdlineTests/standard_model_checker_targets_underflow_overflow_chc/output.json b/test/cmdlineTests/standard_model_checker_targets_underflow_overflow_chc/output.json index 9a07b669ad3b..6fb8762e4312 100644 --- a/test/cmdlineTests/standard_model_checker_targets_underflow_overflow_chc/output.json +++ b/test/cmdlineTests/standard_model_checker_targets_underflow_overflow_chc/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "errorCode": "3944", @@ -31,8 +30,7 @@ test.constructor() State: arr = [] test.f(0x0, 0)", "severity": "warning", - "sourceLocation": - { + "sourceLocation": { "end": 177, "file": "A", "start": 174 @@ -69,8 +67,7 @@ test.constructor() State: arr = [] test.f(0x0, 2)", "severity": "warning", - "sourceLocation": - { + "sourceLocation": { "end": 203, "file": "A", "start": 185 @@ -78,10 +75,8 @@ test.f(0x0, 2)", "type": "Warning" } ], - "sources": - { - "A": - { + "sources": { + "A": { "id": 0 } } diff --git a/test/cmdlineTests/standard_model_checker_targets_wrong_target_types/output.json b/test/cmdlineTests/standard_model_checker_targets_wrong_target_types/output.json index 6e2af863ec69..fee6f21958a1 100644 --- a/test/cmdlineTests/standard_model_checker_targets_wrong_target_types/output.json +++ b/test/cmdlineTests/standard_model_checker_targets_wrong_target_types/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "formattedMessage": "Every target in settings.modelChecker.targets must be a string.", diff --git a/test/cmdlineTests/standard_model_checker_targets_wrong_target_types_2/output.json b/test/cmdlineTests/standard_model_checker_targets_wrong_target_types_2/output.json index c1e7759b5c10..996d75e70916 100644 --- a/test/cmdlineTests/standard_model_checker_targets_wrong_target_types_2/output.json +++ b/test/cmdlineTests/standard_model_checker_targets_wrong_target_types_2/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "formattedMessage": "settings.modelChecker.targets must be an array.", diff --git a/test/cmdlineTests/standard_model_checker_targets_wrong_targets/output.json b/test/cmdlineTests/standard_model_checker_targets_wrong_targets/output.json index d0bf7f56daba..e51a85258117 100644 --- a/test/cmdlineTests/standard_model_checker_targets_wrong_targets/output.json +++ b/test/cmdlineTests/standard_model_checker_targets_wrong_targets/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "formattedMessage": "Invalid model checker targets requested.", diff --git a/test/cmdlineTests/standard_model_checker_timeout_all/output.json b/test/cmdlineTests/standard_model_checker_timeout_all/output.json index 73b117145445..2da324f33ae6 100644 --- a/test/cmdlineTests/standard_model_checker_timeout_all/output.json +++ b/test/cmdlineTests/standard_model_checker_timeout_all/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "errorCode": "5840", @@ -32,10 +31,8 @@ "type": "Warning" } ], - "sources": - { - "A": - { + "sources": { + "A": { "id": 0 } } diff --git a/test/cmdlineTests/standard_model_checker_timeout_bmc/output.json b/test/cmdlineTests/standard_model_checker_timeout_bmc/output.json index a709ec062c79..f813782d74d1 100644 --- a/test/cmdlineTests/standard_model_checker_timeout_bmc/output.json +++ b/test/cmdlineTests/standard_model_checker_timeout_bmc/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "errorCode": "2788", @@ -22,10 +21,8 @@ "type": "Info" } ], - "sources": - { - "A": - { + "sources": { + "A": { "id": 0 } } diff --git a/test/cmdlineTests/standard_model_checker_timeout_chc/output.json b/test/cmdlineTests/standard_model_checker_timeout_chc/output.json index 553a1b93b62b..1ff515e25ee4 100644 --- a/test/cmdlineTests/standard_model_checker_timeout_chc/output.json +++ b/test/cmdlineTests/standard_model_checker_timeout_chc/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "errorCode": "5840", @@ -22,10 +21,8 @@ "type": "Info" } ], - "sources": - { - "A": - { + "sources": { + "A": { "id": 0 } } diff --git a/test/cmdlineTests/standard_model_checker_timeout_wrong_key/output.json b/test/cmdlineTests/standard_model_checker_timeout_wrong_key/output.json index 137562f4196b..afa05c3a8d58 100644 --- a/test/cmdlineTests/standard_model_checker_timeout_wrong_key/output.json +++ b/test/cmdlineTests/standard_model_checker_timeout_wrong_key/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "formattedMessage": "Unknown key \"atimeout\"", diff --git a/test/cmdlineTests/standard_model_checker_timeout_wrong_value/output.json b/test/cmdlineTests/standard_model_checker_timeout_wrong_value/output.json index ce630905c6c8..7fbdfbbe82a3 100644 --- a/test/cmdlineTests/standard_model_checker_timeout_wrong_value/output.json +++ b/test/cmdlineTests/standard_model_checker_timeout_wrong_value/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "formattedMessage": "settings.modelChecker.timeout must be an unsigned integer.", diff --git a/test/cmdlineTests/standard_no_append_cbor/output.json b/test/cmdlineTests/standard_no_append_cbor/output.json index 0fca3f2715a3..c060efd971a7 100644 --- a/test/cmdlineTests/standard_no_append_cbor/output.json +++ b/test/cmdlineTests/standard_no_append_cbor/output.json @@ -1,14 +1,9 @@ { - "contracts": - { - "A": - { - "test": - { - "evm": - { - "bytecode": - { + "contracts": { + "A": { + "test": { + "evm": { + "bytecode": { "functionDebugData": {}, "generatedSources": [], "linkReferences": {}, @@ -20,10 +15,8 @@ } } }, - "sources": - { - "A": - { + "sources": { + "A": { "id": 0 } } diff --git a/test/cmdlineTests/standard_no_append_cbor_with_metadata_hash/output.json b/test/cmdlineTests/standard_no_append_cbor_with_metadata_hash/output.json index 0c264f898a87..a31841944eda 100644 --- a/test/cmdlineTests/standard_no_append_cbor_with_metadata_hash/output.json +++ b/test/cmdlineTests/standard_no_append_cbor_with_metadata_hash/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "formattedMessage": "When the parameter \"appendCBOR\" is set to false, the parameter \"bytecodeHash\" cannot be set to \"ipfs\". The parameter \"bytecodeHash\" should either be skipped, or set to \"none\".", diff --git a/test/cmdlineTests/standard_no_import_callback/output.json b/test/cmdlineTests/standard_no_import_callback/output.json index a4e2d8d3a2bf..3c16f1caa7cf 100644 --- a/test/cmdlineTests/standard_no_import_callback/output.json +++ b/test/cmdlineTests/standard_no_import_callback/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "errorCode": "6275", @@ -13,8 +12,7 @@ ", "message": "Source \"standard_no_import_callback/B.sol\" not found: No import callback.", "severity": "error", - "sourceLocation": - { + "sourceLocation": { "end": 102, "file": "A", "start": 59 diff --git a/test/cmdlineTests/standard_non_utf8_filename/output.json b/test/cmdlineTests/standard_non_utf8_filename/output.json index a74a83a98975..5dc1b6f1b678 100644 --- a/test/cmdlineTests/standard_non_utf8_filename/output.json +++ b/test/cmdlineTests/standard_non_utf8_filename/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "formattedMessage": "parse error at line 5, column 4: syntax error while parsing object key - invalid string: ill-formed UTF-8 byte; last read: '\"\\xff'; expected string literal", diff --git a/test/cmdlineTests/standard_non_utf8_filename2/output.json b/test/cmdlineTests/standard_non_utf8_filename2/output.json index a74a83a98975..5dc1b6f1b678 100644 --- a/test/cmdlineTests/standard_non_utf8_filename2/output.json +++ b/test/cmdlineTests/standard_non_utf8_filename2/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "formattedMessage": "parse error at line 5, column 4: syntax error while parsing object key - invalid string: ill-formed UTF-8 byte; last read: '\"\\xff'; expected string literal", diff --git a/test/cmdlineTests/standard_only_ast_requested/output.json b/test/cmdlineTests/standard_only_ast_requested/output.json index 6ecac5ca364d..d54da1750bc8 100644 --- a/test/cmdlineTests/standard_only_ast_requested/output.json +++ b/test/cmdlineTests/standard_only_ast_requested/output.json @@ -1,27 +1,20 @@ { - "sources": - { - "A": - { - "ast": - { + "sources": { + "A": { + "ast": { "absolutePath": "A", - "exportedSymbols": - { - "C": - [ + "exportedSymbols": { + "C": [ 6 ] }, "id": 7, "license": "GPL-3.0", "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "id": 1, - "literals": - [ + "literals": [ "solidity", ">=", "0.0" @@ -37,18 +30,15 @@ "contractKind": "contract", "fullyImplemented": true, "id": 6, - "linearizedBaseContracts": - [ + "linearizedBaseContracts": [ 6 ], "name": "C", "nameLocation": "68:1:0", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { - "body": - { + "body": { "id": 4, "nodeType": "Block", "src": "97:2:0", @@ -62,15 +52,13 @@ "name": "f", "nameLocation": "81:1:0", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 2, "nodeType": "ParameterList", "parameters": [], "src": "82:2:0" }, - "returnParameters": - { + "returnParameters": { "id": 3, "nodeType": "ParameterList", "parameters": [], diff --git a/test/cmdlineTests/standard_optimizer_generatedSources/output.json b/test/cmdlineTests/standard_optimizer_generatedSources/output.json index da2c31cbee25..0f8c3d4eae55 100644 --- a/test/cmdlineTests/standard_optimizer_generatedSources/output.json +++ b/test/cmdlineTests/standard_optimizer_generatedSources/output.json @@ -1,29 +1,20 @@ { - "contracts": - { - "a.sol": - { - "A": - { - "evm": - { - "bytecode": - { + "contracts": { + "a.sol": { + "A": { + "evm": { + "bytecode": { "generatedSources": [], "object": "" }, - "deployedBytecode": - { - "generatedSources": - [ + "deployedBytecode": { + "generatedSources": [ { - "ast": - { + "ast": { "nativeSrc": "0:1445:1", "nodeType": "YulBlock", "src": "0:1445:1", - "statements": - [ + "statements": [ { "nativeSrc": "6:3:1", "nodeType": "YulBlock", @@ -31,18 +22,14 @@ "statements": [] }, { - "body": - { + "body": { "nativeSrc": "46:95:1", "nodeType": "YulBlock", "src": "46:95:1", - "statements": - [ + "statements": [ { - "expression": - { - "arguments": - [ + "expression": { + "arguments": [ { "kind": "number", "nativeSrc": "63:1:1", @@ -52,8 +39,7 @@ "value": "0" }, { - "arguments": - [ + "arguments": [ { "kind": "number", "nativeSrc": "70:3:1", @@ -71,8 +57,7 @@ "value": "0x4e487b71" } ], - "functionName": - { + "functionName": { "name": "shl", "nativeSrc": "66:3:1", "nodeType": "YulIdentifier", @@ -83,8 +68,7 @@ "src": "66:20:1" } ], - "functionName": - { + "functionName": { "name": "mstore", "nativeSrc": "56:6:1", "nodeType": "YulIdentifier", @@ -99,10 +83,8 @@ "src": "56:31:1" }, { - "expression": - { - "arguments": - [ + "expression": { + "arguments": [ { "kind": "number", "nativeSrc": "103:1:1", @@ -120,8 +102,7 @@ "value": "0x41" } ], - "functionName": - { + "functionName": { "name": "mstore", "nativeSrc": "96:6:1", "nodeType": "YulIdentifier", @@ -136,10 +117,8 @@ "src": "96:15:1" }, { - "expression": - { - "arguments": - [ + "expression": { + "arguments": [ { "kind": "number", "nativeSrc": "127:1:1", @@ -157,8 +136,7 @@ "value": "0x24" } ], - "functionName": - { + "functionName": { "name": "revert", "nativeSrc": "120:6:1", "nodeType": "YulIdentifier", @@ -180,19 +158,16 @@ "src": "14:127:1" }, { - "body": - { + "body": { "nativeSrc": "241:1020:1", "nodeType": "YulBlock", "src": "241:1020:1", - "statements": - [ + "statements": [ { "nativeSrc": "251:12:1", "nodeType": "YulVariableDeclaration", "src": "251:12:1", - "value": - { + "value": { "kind": "number", "nativeSrc": "261:2:1", "nodeType": "YulLiteral", @@ -200,8 +175,7 @@ "type": "", "value": "32" }, - "variables": - [ + "variables": [ { "name": "_1", "nativeSrc": "255:2:1", @@ -212,18 +186,14 @@ ] }, { - "body": - { + "body": { "nativeSrc": "308:16:1", "nodeType": "YulBlock", "src": "308:16:1", - "statements": - [ + "statements": [ { - "expression": - { - "arguments": - [ + "expression": { + "arguments": [ { "kind": "number", "nativeSrc": "317:1:1", @@ -241,8 +211,7 @@ "value": "0" } ], - "functionName": - { + "functionName": { "name": "revert", "nativeSrc": "310:6:1", "nodeType": "YulIdentifier", @@ -258,13 +227,10 @@ } ] }, - "condition": - { - "arguments": - [ + "condition": { + "arguments": [ { - "arguments": - [ + "arguments": [ { "name": "dataEnd", "nativeSrc": "283:7:1", @@ -278,8 +244,7 @@ "src": "292:9:1" } ], - "functionName": - { + "functionName": { "name": "sub", "nativeSrc": "279:3:1", "nodeType": "YulIdentifier", @@ -296,8 +261,7 @@ "src": "304:2:1" } ], - "functionName": - { + "functionName": { "name": "slt", "nativeSrc": "275:3:1", "nodeType": "YulIdentifier", @@ -315,10 +279,8 @@ "nativeSrc": "333:37:1", "nodeType": "YulVariableDeclaration", "src": "333:37:1", - "value": - { - "arguments": - [ + "value": { + "arguments": [ { "name": "headStart", "nativeSrc": "360:9:1", @@ -326,8 +288,7 @@ "src": "360:9:1" } ], - "functionName": - { + "functionName": { "name": "calldataload", "nativeSrc": "347:12:1", "nodeType": "YulIdentifier", @@ -337,8 +298,7 @@ "nodeType": "YulFunctionCall", "src": "347:23:1" }, - "variables": - [ + "variables": [ { "name": "offset", "nativeSrc": "337:6:1", @@ -352,8 +312,7 @@ "nativeSrc": "379:28:1", "nodeType": "YulVariableDeclaration", "src": "379:28:1", - "value": - { + "value": { "kind": "number", "nativeSrc": "389:18:1", "nodeType": "YulLiteral", @@ -361,8 +320,7 @@ "type": "", "value": "0xffffffffffffffff" }, - "variables": - [ + "variables": [ { "name": "_2", "nativeSrc": "383:2:1", @@ -373,18 +331,14 @@ ] }, { - "body": - { + "body": { "nativeSrc": "434:16:1", "nodeType": "YulBlock", "src": "434:16:1", - "statements": - [ + "statements": [ { - "expression": - { - "arguments": - [ + "expression": { + "arguments": [ { "kind": "number", "nativeSrc": "443:1:1", @@ -402,8 +356,7 @@ "value": "0" } ], - "functionName": - { + "functionName": { "name": "revert", "nativeSrc": "436:6:1", "nodeType": "YulIdentifier", @@ -419,10 +372,8 @@ } ] }, - "condition": - { - "arguments": - [ + "condition": { + "arguments": [ { "name": "offset", "nativeSrc": "422:6:1", @@ -436,8 +387,7 @@ "src": "430:2:1" } ], - "functionName": - { + "functionName": { "name": "gt", "nativeSrc": "419:2:1", "nodeType": "YulIdentifier", @@ -455,10 +405,8 @@ "nativeSrc": "459:32:1", "nodeType": "YulVariableDeclaration", "src": "459:32:1", - "value": - { - "arguments": - [ + "value": { + "arguments": [ { "name": "headStart", "nativeSrc": "473:9:1", @@ -472,8 +420,7 @@ "src": "484:6:1" } ], - "functionName": - { + "functionName": { "name": "add", "nativeSrc": "469:3:1", "nodeType": "YulIdentifier", @@ -483,8 +430,7 @@ "nodeType": "YulFunctionCall", "src": "469:22:1" }, - "variables": - [ + "variables": [ { "name": "_3", "nativeSrc": "463:2:1", @@ -495,18 +441,14 @@ ] }, { - "body": - { + "body": { "nativeSrc": "539:16:1", "nodeType": "YulBlock", "src": "539:16:1", - "statements": - [ + "statements": [ { - "expression": - { - "arguments": - [ + "expression": { + "arguments": [ { "kind": "number", "nativeSrc": "548:1:1", @@ -524,8 +466,7 @@ "value": "0" } ], - "functionName": - { + "functionName": { "name": "revert", "nativeSrc": "541:6:1", "nodeType": "YulIdentifier", @@ -541,16 +482,12 @@ } ] }, - "condition": - { - "arguments": - [ + "condition": { + "arguments": [ { - "arguments": - [ + "arguments": [ { - "arguments": - [ + "arguments": [ { "name": "_3", "nativeSrc": "518:2:1", @@ -566,8 +503,7 @@ "value": "0x1f" } ], - "functionName": - { + "functionName": { "name": "add", "nativeSrc": "514:3:1", "nodeType": "YulIdentifier", @@ -584,8 +520,7 @@ "src": "529:7:1" } ], - "functionName": - { + "functionName": { "name": "slt", "nativeSrc": "510:3:1", "nodeType": "YulIdentifier", @@ -596,8 +531,7 @@ "src": "510:27:1" } ], - "functionName": - { + "functionName": { "name": "iszero", "nativeSrc": "503:6:1", "nodeType": "YulIdentifier", @@ -615,10 +549,8 @@ "nativeSrc": "564:26:1", "nodeType": "YulVariableDeclaration", "src": "564:26:1", - "value": - { - "arguments": - [ + "value": { + "arguments": [ { "name": "_3", "nativeSrc": "587:2:1", @@ -626,8 +558,7 @@ "src": "587:2:1" } ], - "functionName": - { + "functionName": { "name": "calldataload", "nativeSrc": "574:12:1", "nodeType": "YulIdentifier", @@ -637,8 +568,7 @@ "nodeType": "YulFunctionCall", "src": "574:16:1" }, - "variables": - [ + "variables": [ { "name": "_4", "nativeSrc": "568:2:1", @@ -649,19 +579,15 @@ ] }, { - "body": - { + "body": { "nativeSrc": "613:22:1", "nodeType": "YulBlock", "src": "613:22:1", - "statements": - [ + "statements": [ { - "expression": - { + "expression": { "arguments": [], - "functionName": - { + "functionName": { "name": "panic_error_0x41", "nativeSrc": "615:16:1", "nodeType": "YulIdentifier", @@ -677,10 +603,8 @@ } ] }, - "condition": - { - "arguments": - [ + "condition": { + "arguments": [ { "name": "_4", "nativeSrc": "605:2:1", @@ -694,8 +618,7 @@ "src": "609:2:1" } ], - "functionName": - { + "functionName": { "name": "gt", "nativeSrc": "602:2:1", "nodeType": "YulIdentifier", @@ -713,10 +636,8 @@ "nativeSrc": "644:20:1", "nodeType": "YulVariableDeclaration", "src": "644:20:1", - "value": - { - "arguments": - [ + "value": { + "arguments": [ { "kind": "number", "nativeSrc": "658:1:1", @@ -732,8 +653,7 @@ "src": "661:2:1" } ], - "functionName": - { + "functionName": { "name": "shl", "nativeSrc": "654:3:1", "nodeType": "YulIdentifier", @@ -743,8 +663,7 @@ "nodeType": "YulFunctionCall", "src": "654:10:1" }, - "variables": - [ + "variables": [ { "name": "_5", "nativeSrc": "648:2:1", @@ -758,10 +677,8 @@ "nativeSrc": "673:23:1", "nodeType": "YulVariableDeclaration", "src": "673:23:1", - "value": - { - "arguments": - [ + "value": { + "arguments": [ { "kind": "number", "nativeSrc": "693:2:1", @@ -771,8 +688,7 @@ "value": "64" } ], - "functionName": - { + "functionName": { "name": "mload", "nativeSrc": "687:5:1", "nodeType": "YulIdentifier", @@ -782,8 +698,7 @@ "nodeType": "YulFunctionCall", "src": "687:9:1" }, - "variables": - [ + "variables": [ { "name": "memPtr", "nativeSrc": "677:6:1", @@ -797,10 +712,8 @@ "nativeSrc": "705:56:1", "nodeType": "YulVariableDeclaration", "src": "705:56:1", - "value": - { - "arguments": - [ + "value": { + "arguments": [ { "name": "memPtr", "nativeSrc": "727:6:1", @@ -808,11 +721,9 @@ "src": "727:6:1" }, { - "arguments": - [ + "arguments": [ { - "arguments": - [ + "arguments": [ { "name": "_5", "nativeSrc": "743:2:1", @@ -828,8 +739,7 @@ "value": "63" } ], - "functionName": - { + "functionName": { "name": "add", "nativeSrc": "739:3:1", "nodeType": "YulIdentifier", @@ -840,8 +750,7 @@ "src": "739:11:1" }, { - "arguments": - [ + "arguments": [ { "kind": "number", "nativeSrc": "756:2:1", @@ -851,8 +760,7 @@ "value": "31" } ], - "functionName": - { + "functionName": { "name": "not", "nativeSrc": "752:3:1", "nodeType": "YulIdentifier", @@ -863,8 +771,7 @@ "src": "752:7:1" } ], - "functionName": - { + "functionName": { "name": "and", "nativeSrc": "735:3:1", "nodeType": "YulIdentifier", @@ -875,8 +782,7 @@ "src": "735:25:1" } ], - "functionName": - { + "functionName": { "name": "add", "nativeSrc": "723:3:1", "nodeType": "YulIdentifier", @@ -886,8 +792,7 @@ "nodeType": "YulFunctionCall", "src": "723:38:1" }, - "variables": - [ + "variables": [ { "name": "newFreePtr", "nativeSrc": "709:10:1", @@ -898,19 +803,15 @@ ] }, { - "body": - { + "body": { "nativeSrc": "820:22:1", "nodeType": "YulBlock", "src": "820:22:1", - "statements": - [ + "statements": [ { - "expression": - { + "expression": { "arguments": [], - "functionName": - { + "functionName": { "name": "panic_error_0x41", "nativeSrc": "822:16:1", "nodeType": "YulIdentifier", @@ -926,13 +827,10 @@ } ] }, - "condition": - { - "arguments": - [ + "condition": { + "arguments": [ { - "arguments": - [ + "arguments": [ { "name": "newFreePtr", "nativeSrc": "779:10:1", @@ -946,8 +844,7 @@ "src": "791:2:1" } ], - "functionName": - { + "functionName": { "name": "gt", "nativeSrc": "776:2:1", "nodeType": "YulIdentifier", @@ -958,8 +855,7 @@ "src": "776:18:1" }, { - "arguments": - [ + "arguments": [ { "name": "newFreePtr", "nativeSrc": "799:10:1", @@ -973,8 +869,7 @@ "src": "811:6:1" } ], - "functionName": - { + "functionName": { "name": "lt", "nativeSrc": "796:2:1", "nodeType": "YulIdentifier", @@ -985,8 +880,7 @@ "src": "796:22:1" } ], - "functionName": - { + "functionName": { "name": "or", "nativeSrc": "773:2:1", "nodeType": "YulIdentifier", @@ -1001,10 +895,8 @@ "src": "770:72:1" }, { - "expression": - { - "arguments": - [ + "expression": { + "arguments": [ { "kind": "number", "nativeSrc": "858:2:1", @@ -1020,8 +912,7 @@ "src": "862:10:1" } ], - "functionName": - { + "functionName": { "name": "mstore", "nativeSrc": "851:6:1", "nodeType": "YulIdentifier", @@ -1039,15 +930,13 @@ "nativeSrc": "882:17:1", "nodeType": "YulVariableDeclaration", "src": "882:17:1", - "value": - { + "value": { "name": "memPtr", "nativeSrc": "893:6:1", "nodeType": "YulIdentifier", "src": "893:6:1" }, - "variables": - [ + "variables": [ { "name": "dst", "nativeSrc": "886:3:1", @@ -1058,10 +947,8 @@ ] }, { - "expression": - { - "arguments": - [ + "expression": { + "arguments": [ { "name": "memPtr", "nativeSrc": "915:6:1", @@ -1075,8 +962,7 @@ "src": "923:2:1" } ], - "functionName": - { + "functionName": { "name": "mstore", "nativeSrc": "908:6:1", "nodeType": "YulIdentifier", @@ -1094,10 +980,8 @@ "nativeSrc": "935:22:1", "nodeType": "YulAssignment", "src": "935:22:1", - "value": - { - "arguments": - [ + "value": { + "arguments": [ { "name": "memPtr", "nativeSrc": "946:6:1", @@ -1111,8 +995,7 @@ "src": "954:2:1" } ], - "functionName": - { + "functionName": { "name": "add", "nativeSrc": "942:3:1", "nodeType": "YulIdentifier", @@ -1122,8 +1005,7 @@ "nodeType": "YulFunctionCall", "src": "942:15:1" }, - "variableNames": - [ + "variableNames": [ { "name": "dst", "nativeSrc": "935:3:1", @@ -1136,13 +1018,10 @@ "nativeSrc": "966:34:1", "nodeType": "YulVariableDeclaration", "src": "966:34:1", - "value": - { - "arguments": - [ + "value": { + "arguments": [ { - "arguments": - [ + "arguments": [ { "name": "_3", "nativeSrc": "988:2:1", @@ -1156,8 +1035,7 @@ "src": "992:2:1" } ], - "functionName": - { + "functionName": { "name": "add", "nativeSrc": "984:3:1", "nodeType": "YulIdentifier", @@ -1174,8 +1052,7 @@ "src": "997:2:1" } ], - "functionName": - { + "functionName": { "name": "add", "nativeSrc": "980:3:1", "nodeType": "YulIdentifier", @@ -1185,8 +1062,7 @@ "nodeType": "YulFunctionCall", "src": "980:20:1" }, - "variables": - [ + "variables": [ { "name": "srcEnd", "nativeSrc": "970:6:1", @@ -1197,18 +1073,14 @@ ] }, { - "body": - { + "body": { "nativeSrc": "1032:16:1", "nodeType": "YulBlock", "src": "1032:16:1", - "statements": - [ + "statements": [ { - "expression": - { - "arguments": - [ + "expression": { + "arguments": [ { "kind": "number", "nativeSrc": "1041:1:1", @@ -1226,8 +1098,7 @@ "value": "0" } ], - "functionName": - { + "functionName": { "name": "revert", "nativeSrc": "1034:6:1", "nodeType": "YulIdentifier", @@ -1243,10 +1114,8 @@ } ] }, - "condition": - { - "arguments": - [ + "condition": { + "arguments": [ { "name": "srcEnd", "nativeSrc": "1015:6:1", @@ -1260,8 +1129,7 @@ "src": "1023:7:1" } ], - "functionName": - { + "functionName": { "name": "gt", "nativeSrc": "1012:2:1", "nodeType": "YulIdentifier", @@ -1279,10 +1147,8 @@ "nativeSrc": "1057:22:1", "nodeType": "YulVariableDeclaration", "src": "1057:22:1", - "value": - { - "arguments": - [ + "value": { + "arguments": [ { "name": "_3", "nativeSrc": "1072:2:1", @@ -1296,8 +1162,7 @@ "src": "1076:2:1" } ], - "functionName": - { + "functionName": { "name": "add", "nativeSrc": "1068:3:1", "nodeType": "YulIdentifier", @@ -1307,8 +1172,7 @@ "nodeType": "YulFunctionCall", "src": "1068:11:1" }, - "variables": - [ + "variables": [ { "name": "src", "nativeSrc": "1061:3:1", @@ -1319,18 +1183,14 @@ ] }, { - "body": - { + "body": { "nativeSrc": "1144:86:1", "nodeType": "YulBlock", "src": "1144:86:1", - "statements": - [ + "statements": [ { - "expression": - { - "arguments": - [ + "expression": { + "arguments": [ { "name": "dst", "nativeSrc": "1165:3:1", @@ -1338,8 +1198,7 @@ "src": "1165:3:1" }, { - "arguments": - [ + "arguments": [ { "name": "src", "nativeSrc": "1183:3:1", @@ -1347,8 +1206,7 @@ "src": "1183:3:1" } ], - "functionName": - { + "functionName": { "name": "calldataload", "nativeSrc": "1170:12:1", "nodeType": "YulIdentifier", @@ -1359,8 +1217,7 @@ "src": "1170:17:1" } ], - "functionName": - { + "functionName": { "name": "mstore", "nativeSrc": "1158:6:1", "nodeType": "YulIdentifier", @@ -1378,10 +1235,8 @@ "nativeSrc": "1201:19:1", "nodeType": "YulAssignment", "src": "1201:19:1", - "value": - { - "arguments": - [ + "value": { + "arguments": [ { "name": "dst", "nativeSrc": "1212:3:1", @@ -1395,8 +1250,7 @@ "src": "1217:2:1" } ], - "functionName": - { + "functionName": { "name": "add", "nativeSrc": "1208:3:1", "nodeType": "YulIdentifier", @@ -1406,8 +1260,7 @@ "nodeType": "YulFunctionCall", "src": "1208:12:1" }, - "variableNames": - [ + "variableNames": [ { "name": "dst", "nativeSrc": "1201:3:1", @@ -1418,10 +1271,8 @@ } ] }, - "condition": - { - "arguments": - [ + "condition": { + "arguments": [ { "name": "src", "nativeSrc": "1099:3:1", @@ -1435,8 +1286,7 @@ "src": "1104:6:1" } ], - "functionName": - { + "functionName": { "name": "lt", "nativeSrc": "1096:2:1", "nodeType": "YulIdentifier", @@ -1448,21 +1298,17 @@ }, "nativeSrc": "1088:142:1", "nodeType": "YulForLoop", - "post": - { + "post": { "nativeSrc": "1112:23:1", "nodeType": "YulBlock", "src": "1112:23:1", - "statements": - [ + "statements": [ { "nativeSrc": "1114:19:1", "nodeType": "YulAssignment", "src": "1114:19:1", - "value": - { - "arguments": - [ + "value": { + "arguments": [ { "name": "src", "nativeSrc": "1125:3:1", @@ -1476,8 +1322,7 @@ "src": "1130:2:1" } ], - "functionName": - { + "functionName": { "name": "add", "nativeSrc": "1121:3:1", "nodeType": "YulIdentifier", @@ -1487,8 +1332,7 @@ "nodeType": "YulFunctionCall", "src": "1121:12:1" }, - "variableNames": - [ + "variableNames": [ { "name": "src", "nativeSrc": "1114:3:1", @@ -1499,8 +1343,7 @@ } ] }, - "pre": - { + "pre": { "nativeSrc": "1092:3:1", "nodeType": "YulBlock", "src": "1092:3:1", @@ -1512,15 +1355,13 @@ "nativeSrc": "1239:16:1", "nodeType": "YulAssignment", "src": "1239:16:1", - "value": - { + "value": { "name": "memPtr", "nativeSrc": "1249:6:1", "nodeType": "YulIdentifier", "src": "1249:6:1" }, - "variableNames": - [ + "variableNames": [ { "name": "value0", "nativeSrc": "1239:6:1", @@ -1534,8 +1375,7 @@ "name": "abi_decode_tuple_t_array$_t_uint256_$dyn_memory_ptr", "nativeSrc": "146:1115:1", "nodeType": "YulFunctionDefinition", - "parameters": - [ + "parameters": [ { "name": "headStart", "nativeSrc": "207:9:1", @@ -1551,8 +1391,7 @@ "type": "" } ], - "returnVariables": - [ + "returnVariables": [ { "name": "value0", "nativeSrc": "230:6:1", @@ -1564,21 +1403,17 @@ "src": "146:1115:1" }, { - "body": - { + "body": { "nativeSrc": "1367:76:1", "nodeType": "YulBlock", "src": "1367:76:1", - "statements": - [ + "statements": [ { "nativeSrc": "1377:26:1", "nodeType": "YulAssignment", "src": "1377:26:1", - "value": - { - "arguments": - [ + "value": { + "arguments": [ { "name": "headStart", "nativeSrc": "1389:9:1", @@ -1594,8 +1429,7 @@ "value": "32" } ], - "functionName": - { + "functionName": { "name": "add", "nativeSrc": "1385:3:1", "nodeType": "YulIdentifier", @@ -1605,8 +1439,7 @@ "nodeType": "YulFunctionCall", "src": "1385:18:1" }, - "variableNames": - [ + "variableNames": [ { "name": "tail", "nativeSrc": "1377:4:1", @@ -1616,10 +1449,8 @@ ] }, { - "expression": - { - "arguments": - [ + "expression": { + "arguments": [ { "name": "headStart", "nativeSrc": "1419:9:1", @@ -1633,8 +1464,7 @@ "src": "1430:6:1" } ], - "functionName": - { + "functionName": { "name": "mstore", "nativeSrc": "1412:6:1", "nodeType": "YulIdentifier", @@ -1653,8 +1483,7 @@ "name": "abi_encode_tuple_t_uint256__to_t_uint256__fromStack_reversed", "nativeSrc": "1266:177:1", "nodeType": "YulFunctionDefinition", - "parameters": - [ + "parameters": [ { "name": "headStart", "nativeSrc": "1336:9:1", @@ -1670,8 +1499,7 @@ "type": "" } ], - "returnVariables": - [ + "returnVariables": [ { "name": "tail", "nativeSrc": "1358:4:1", @@ -1737,10 +1565,8 @@ } } }, - "sources": - { - "a.sol": - { + "sources": { + "a.sol": { "id": 0 } } diff --git a/test/cmdlineTests/standard_optimizer_invalid_detail_type/output.json b/test/cmdlineTests/standard_optimizer_invalid_detail_type/output.json index 2601dea6c3d1..10ba5e396196 100644 --- a/test/cmdlineTests/standard_optimizer_invalid_detail_type/output.json +++ b/test/cmdlineTests/standard_optimizer_invalid_detail_type/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "formattedMessage": "\"settings.optimizer.details.peephole\" must be Boolean", diff --git a/test/cmdlineTests/standard_optimizer_invalid_details/output.json b/test/cmdlineTests/standard_optimizer_invalid_details/output.json index c7dfaf3142f9..79b0de4e8004 100644 --- a/test/cmdlineTests/standard_optimizer_invalid_details/output.json +++ b/test/cmdlineTests/standard_optimizer_invalid_details/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "formattedMessage": "Unknown key \"notThere\"", diff --git a/test/cmdlineTests/standard_optimizer_no_yul/output.json b/test/cmdlineTests/standard_optimizer_no_yul/output.json index acf3b74ef1de..f047ff70a9eb 100644 --- a/test/cmdlineTests/standard_optimizer_no_yul/output.json +++ b/test/cmdlineTests/standard_optimizer_no_yul/output.json @@ -1,8 +1,6 @@ { - "sources": - { - "A": - { + "sources": { + "A": { "id": 0 } } diff --git a/test/cmdlineTests/standard_optimizer_yul/output.json b/test/cmdlineTests/standard_optimizer_yul/output.json index acf3b74ef1de..f047ff70a9eb 100644 --- a/test/cmdlineTests/standard_optimizer_yul/output.json +++ b/test/cmdlineTests/standard_optimizer_yul/output.json @@ -1,8 +1,6 @@ { - "sources": - { - "A": - { + "sources": { + "A": { "id": 0 } } diff --git a/test/cmdlineTests/standard_optimizer_yulDetails/output.json b/test/cmdlineTests/standard_optimizer_yulDetails/output.json index acf3b74ef1de..f047ff70a9eb 100644 --- a/test/cmdlineTests/standard_optimizer_yulDetails/output.json +++ b/test/cmdlineTests/standard_optimizer_yulDetails/output.json @@ -1,8 +1,6 @@ { - "sources": - { - "A": - { + "sources": { + "A": { "id": 0 } } diff --git a/test/cmdlineTests/standard_optimizer_yulDetails_no_object/output.json b/test/cmdlineTests/standard_optimizer_yulDetails_no_object/output.json index 86a0c86986fc..c658301e9aff 100644 --- a/test/cmdlineTests/standard_optimizer_yulDetails_no_object/output.json +++ b/test/cmdlineTests/standard_optimizer_yulDetails_no_object/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "formattedMessage": "\"settings.optimizer.details.yulDetails\" must be an object", diff --git a/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps/output.json b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps/output.json index acf3b74ef1de..f047ff70a9eb 100644 --- a/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps/output.json +++ b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps/output.json @@ -1,8 +1,6 @@ { - "sources": - { - "A": - { + "sources": { + "A": { "id": 0 } } diff --git a/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_empty_sequence_metadata/output.json b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_empty_sequence_metadata/output.json index 725822763aff..c461a1485bda 100644 --- a/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_empty_sequence_metadata/output.json +++ b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_empty_sequence_metadata/output.json @@ -1,18 +1,13 @@ { - "contracts": - { - "A": - { - "C": - { + "contracts": { + "A": { + "C": { "metadata": "{\"compiler\":{\"version\":\"\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"A\":\"C\"},\"evmVersion\":\"cancun\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"details\":{\"constantOptimizer\":false,\"cse\":false,\"deduplicate\":false,\"inliner\":false,\"jumpdestRemover\":true,\"orderLiterals\":false,\"peephole\":true,\"simpleCounterForLoopUncheckedIncrement\":true,\"yul\":false,\"yulDetails\":{\"optimizerSteps\":\":\"}},\"runs\":200},\"remappings\":[]},\"sources\":{\"A\":{\"keccak256\":\"0xb284c39999cb85b80be315a6e9e322adf67a783c66e91ba4439168694580a66d\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://098cee915fad095b8a996813768bd7d5e8c9e40c405e8c43d0572bb7bbc17334\",\"dweb:/ipfs/QmZmUzvSryrrD7pJ9S32iQnEWn4QBL4J1NdbQqL2Xc3yTr\"]}},\"version\":1}" } } }, - "sources": - { - "A": - { + "sources": { + "A": { "id": 0 } } diff --git a/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_empty_sequence_whitespaces_metadata/output.json b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_empty_sequence_whitespaces_metadata/output.json index 725822763aff..c461a1485bda 100644 --- a/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_empty_sequence_whitespaces_metadata/output.json +++ b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_empty_sequence_whitespaces_metadata/output.json @@ -1,18 +1,13 @@ { - "contracts": - { - "A": - { - "C": - { + "contracts": { + "A": { + "C": { "metadata": "{\"compiler\":{\"version\":\"\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"A\":\"C\"},\"evmVersion\":\"cancun\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"details\":{\"constantOptimizer\":false,\"cse\":false,\"deduplicate\":false,\"inliner\":false,\"jumpdestRemover\":true,\"orderLiterals\":false,\"peephole\":true,\"simpleCounterForLoopUncheckedIncrement\":true,\"yul\":false,\"yulDetails\":{\"optimizerSteps\":\":\"}},\"runs\":200},\"remappings\":[]},\"sources\":{\"A\":{\"keccak256\":\"0xb284c39999cb85b80be315a6e9e322adf67a783c66e91ba4439168694580a66d\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://098cee915fad095b8a996813768bd7d5e8c9e40c405e8c43d0572bb7bbc17334\",\"dweb:/ipfs/QmZmUzvSryrrD7pJ9S32iQnEWn4QBL4J1NdbQqL2Xc3yTr\"]}},\"version\":1}" } } }, - "sources": - { - "A": - { + "sources": { + "A": { "id": 0 } } diff --git a/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_invalid_abbreviation/output.json b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_invalid_abbreviation/output.json index d4f6ef3a7e55..267a8c3609ae 100644 --- a/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_invalid_abbreviation/output.json +++ b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_invalid_abbreviation/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "formattedMessage": "Invalid optimizer step sequence in \"settings.optimizer.details.optimizerSteps\": 'b' is not a valid step abbreviation", diff --git a/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_invalid_nested_delimiter/output.json b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_invalid_nested_delimiter/output.json index f44ca7e2e589..ea101d2e18e4 100644 --- a/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_invalid_nested_delimiter/output.json +++ b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_invalid_nested_delimiter/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "formattedMessage": "Invalid optimizer step sequence in \"settings.optimizer.details.optimizerSteps\": Cleanup sequence delimiter cannot be placed inside the brackets", diff --git a/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_mutliple_delimiters/output.json b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_mutliple_delimiters/output.json index 16cba14d70c6..595049f41c52 100644 --- a/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_mutliple_delimiters/output.json +++ b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_mutliple_delimiters/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "formattedMessage": "Invalid optimizer step sequence in \"settings.optimizer.details.optimizerSteps\": Too many cleanup sequence delimiters", diff --git a/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_nested_brackets/output.json b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_nested_brackets/output.json index acf3b74ef1de..f047ff70a9eb 100644 --- a/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_nested_brackets/output.json +++ b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_nested_brackets/output.json @@ -1,8 +1,6 @@ { - "sources": - { - "A": - { + "sources": { + "A": { "id": 0 } } diff --git a/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_nesting_too_deep/output.json b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_nesting_too_deep/output.json index e06e14205db0..25fc97e47ee1 100644 --- a/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_nesting_too_deep/output.json +++ b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_nesting_too_deep/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "formattedMessage": "Invalid optimizer step sequence in \"settings.optimizer.details.optimizerSteps\": Brackets nested too deep", diff --git a/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_no_yul/output.json b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_no_yul/output.json index e0b6a26c1bfb..322a7e25b9bc 100644 --- a/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_no_yul/output.json +++ b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_no_yul/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "formattedMessage": "If Yul optimizer is disabled, only an empty optimizerSteps sequence is accepted. Note that the empty optimizer sequence is properly denoted by \":\".", diff --git a/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_no_yul_empty_string/output.json b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_no_yul_empty_string/output.json index e0b6a26c1bfb..322a7e25b9bc 100644 --- a/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_no_yul_empty_string/output.json +++ b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_no_yul_empty_string/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "formattedMessage": "If Yul optimizer is disabled, only an empty optimizerSteps sequence is accepted. Note that the empty optimizer sequence is properly denoted by \":\".", diff --git a/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_no_yul_whitespaces/output.json b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_no_yul_whitespaces/output.json index e0b6a26c1bfb..322a7e25b9bc 100644 --- a/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_no_yul_whitespaces/output.json +++ b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_no_yul_whitespaces/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "formattedMessage": "If Yul optimizer is disabled, only an empty optimizerSteps sequence is accepted. Note that the empty optimizer sequence is properly denoted by \":\".", diff --git a/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_type/output.json b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_type/output.json index d6f9a9df8560..a1e5151c1d3f 100644 --- a/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_type/output.json +++ b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_type/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "formattedMessage": "\"settings.optimizer.details.optimizerSteps\" must be a string", diff --git a/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_unbalanced_closing_bracket/output.json b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_unbalanced_closing_bracket/output.json index 316529b0d9c8..3f93509f2726 100644 --- a/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_unbalanced_closing_bracket/output.json +++ b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_unbalanced_closing_bracket/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "formattedMessage": "Invalid optimizer step sequence in \"settings.optimizer.details.optimizerSteps\": Unbalanced brackets", diff --git a/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_unbalanced_opening_bracket/output.json b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_unbalanced_opening_bracket/output.json index 316529b0d9c8..3f93509f2726 100644 --- a/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_unbalanced_opening_bracket/output.json +++ b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_unbalanced_opening_bracket/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "formattedMessage": "Invalid optimizer step sequence in \"settings.optimizer.details.optimizerSteps\": Unbalanced brackets", diff --git a/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_with_cleanup_sequence/output.json b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_with_cleanup_sequence/output.json index acf3b74ef1de..f047ff70a9eb 100644 --- a/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_with_cleanup_sequence/output.json +++ b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_with_cleanup_sequence/output.json @@ -1,8 +1,6 @@ { - "sources": - { - "A": - { + "sources": { + "A": { "id": 0 } } diff --git a/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_with_empty_cleanup_sequence/output.json b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_with_empty_cleanup_sequence/output.json index acf3b74ef1de..f047ff70a9eb 100644 --- a/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_with_empty_cleanup_sequence/output.json +++ b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_with_empty_cleanup_sequence/output.json @@ -1,8 +1,6 @@ { - "sources": - { - "A": - { + "sources": { + "A": { "id": 0 } } diff --git a/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_with_empty_optimisation_sequence/output.json b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_with_empty_optimisation_sequence/output.json index acf3b74ef1de..f047ff70a9eb 100644 --- a/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_with_empty_optimisation_sequence/output.json +++ b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_with_empty_optimisation_sequence/output.json @@ -1,8 +1,6 @@ { - "sources": - { - "A": - { + "sources": { + "A": { "id": 0 } } diff --git a/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_with_empty_sequence/output.json b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_with_empty_sequence/output.json index acf3b74ef1de..f047ff70a9eb 100644 --- a/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_with_empty_sequence/output.json +++ b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_with_empty_sequence/output.json @@ -1,8 +1,6 @@ { - "sources": - { - "A": - { + "sources": { + "A": { "id": 0 } } diff --git a/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_with_empty_sequence_no_yul/output.json b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_with_empty_sequence_no_yul/output.json index acf3b74ef1de..f047ff70a9eb 100644 --- a/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_with_empty_sequence_no_yul/output.json +++ b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_with_empty_sequence_no_yul/output.json @@ -1,8 +1,6 @@ { - "sources": - { - "A": - { + "sources": { + "A": { "id": 0 } } diff --git a/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_with_whitespace_newline_sequence_no_yul/output.json b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_with_whitespace_newline_sequence_no_yul/output.json index acf3b74ef1de..f047ff70a9eb 100644 --- a/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_with_whitespace_newline_sequence_no_yul/output.json +++ b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_with_whitespace_newline_sequence_no_yul/output.json @@ -1,8 +1,6 @@ { - "sources": - { - "A": - { + "sources": { + "A": { "id": 0 } } diff --git a/test/cmdlineTests/standard_optimizer_yulDetails_without_yul/output.json b/test/cmdlineTests/standard_optimizer_yulDetails_without_yul/output.json index 2470015e1fb0..1da39084e74b 100644 --- a/test/cmdlineTests/standard_optimizer_yulDetails_without_yul/output.json +++ b/test/cmdlineTests/standard_optimizer_yulDetails_without_yul/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "formattedMessage": "Only optimizerSteps can be set in yulDetails when Yul optimizer is disabled.", diff --git a/test/cmdlineTests/standard_outputs_on_analysis_error_fatal/output.json b/test/cmdlineTests/standard_outputs_on_analysis_error_fatal/output.json index 51d12668fb13..e0c83975351b 100644 --- a/test/cmdlineTests/standard_outputs_on_analysis_error_fatal/output.json +++ b/test/cmdlineTests/standard_outputs_on_analysis_error_fatal/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "errorCode": "3644", @@ -13,8 +12,7 @@ ", "message": "This parameter has a type that can only be used internally. You can make the contract abstract to avoid this problem.", "severity": "error", - "sourceLocation": - { + "sourceLocation": { "end": 258, "file": "C", "start": 244 diff --git a/test/cmdlineTests/standard_outputs_on_analysis_error_fatal_after_current_step/output.json b/test/cmdlineTests/standard_outputs_on_analysis_error_fatal_after_current_step/output.json index d47ded5d4018..d6357a5b16d7 100644 --- a/test/cmdlineTests/standard_outputs_on_analysis_error_fatal_after_current_step/output.json +++ b/test/cmdlineTests/standard_outputs_on_analysis_error_fatal_after_current_step/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "errorCode": "8297", @@ -13,8 +12,7 @@ ", "message": "The \"immutable\" keyword can only be used for state variables.", "severity": "error", - "sourceLocation": - { + "sourceLocation": { "end": 259, "file": "C", "start": 243 diff --git a/test/cmdlineTests/standard_outputs_on_analysis_error_non_fatal/output.json b/test/cmdlineTests/standard_outputs_on_analysis_error_non_fatal/output.json index 2f3aaae4420c..2dcecead01ff 100644 --- a/test/cmdlineTests/standard_outputs_on_analysis_error_non_fatal/output.json +++ b/test/cmdlineTests/standard_outputs_on_analysis_error_non_fatal/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "errorCode": "7407", @@ -13,8 +12,7 @@ ", "message": "Type uint256 is not implicitly convertible to expected type string storage ref.", "severity": "error", - "sourceLocation": - { + "sourceLocation": { "end": 235, "file": "C", "start": 234 diff --git a/test/cmdlineTests/standard_outputs_on_compilation_error/output.json b/test/cmdlineTests/standard_outputs_on_compilation_error/output.json index aae6d02f6b41..09f4afc4ef2d 100644 --- a/test/cmdlineTests/standard_outputs_on_compilation_error/output.json +++ b/test/cmdlineTests/standard_outputs_on_compilation_error/output.json @@ -1,12 +1,8 @@ { - "contracts": - { - "C": - { - "C": - { - "abi": - [ + "contracts": { + "C": { + "C": { + "abi": [ { "inputs": [], "stateMutability": "nonpayable", @@ -15,8 +11,7 @@ { "inputs": [], "name": "x", - "outputs": - [ + "outputs": [ { "internalType": "uint256", "name": "", @@ -27,27 +22,22 @@ "type": "function" } ], - "devdoc": - { + "devdoc": { "kind": "dev", "methods": {}, "version": 1 }, - "evm": - { - "methodIdentifiers": - { + "evm": { + "methodIdentifiers": { "x()": "0c55699c" } }, "metadata": "{\"compiler\":{\"version\":\"\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"x\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"C\":\"C\"},\"evmVersion\":\"cancun\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"C\":{\"keccak256\":\"0x67a13ebd685e4c6f792e71eb747dac57edb99e94d04d841ee6c979ae517934ce\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://665b000da768823654f680d02686c1e59d682a0b3882e43a77fed9f80ce64ae8\",\"dweb:/ipfs/QmVnKvuidH6KiCdNQpoAQUtDbB8hXkafVLXWMNitUcxnqC\"]}},\"version\":1}", - "storageLayout": - { + "storageLayout": { "storage": [], "types": null }, - "userdoc": - { + "userdoc": { "kind": "user", "methods": {}, "version": 1 @@ -55,8 +45,7 @@ } } }, - "errors": - [ + "errors": [ { "component": "general", "errorCode": "1284", @@ -68,29 +57,22 @@ "type": "CodeGenerationError" } ], - "sources": - { - "C": - { - "ast": - { + "sources": { + "C": { + "ast": { "absolutePath": "C", - "exportedSymbols": - { - "C": - [ + "exportedSymbols": { + "C": [ 15 ] }, "id": 16, "license": "GPL-3.0", "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "id": 1, - "literals": - [ + "literals": [ "solidity", "*" ], @@ -105,15 +87,13 @@ "contractKind": "contract", "fullyImplemented": true, "id": 15, - "linearizedBaseContracts": - [ + "linearizedBaseContracts": [ 15 ], "name": "C", "nameLocation": "65:1:0", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { "constant": false, "functionSelector": "0c55699c", @@ -126,19 +106,16 @@ "src": "228:23:0", "stateVariable": true, "storageLocation": "default", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_uint256", "typeString": "uint256" }, - "typeName": - { + "typeName": { "id": 2, "name": "uint", "nodeType": "ElementaryTypeName", "src": "228:4:0", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_uint256", "typeString": "uint256" } @@ -146,39 +123,33 @@ "visibility": "public" }, { - "body": - { + "body": { "id": 13, "nodeType": "Block", "src": "272:46:0", - "statements": - [ + "statements": [ { - "expression": - { + "expression": { "id": 8, "isConstant": false, "isLValue": false, "isPure": false, "lValueRequested": false, - "leftHandSide": - { + "leftHandSide": { "id": 6, "name": "x", "nodeType": "Identifier", "overloadedDeclarations": [], "referencedDeclaration": 3, "src": "282:1:0", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_uint256", "typeString": "uint256" } }, "nodeType": "Assignment", "operator": "=", - "rightHandSide": - { + "rightHandSide": { "hexValue": "30", "id": 7, "isConstant": false, @@ -188,16 +159,14 @@ "lValueRequested": false, "nodeType": "Literal", "src": "286:1:0", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_rational_0_by_1", "typeString": "int_const 0" }, "value": "0" }, "src": "282:5:0", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_uint256", "typeString": "uint256" } @@ -207,15 +176,13 @@ "src": "282:5:0" }, { - "body": - { + "body": { "id": 11, "nodeType": "Block", "src": "310:2:0", "statements": [] }, - "condition": - { + "condition": { "hexValue": "74727565", "id": 10, "isConstant": false, @@ -225,8 +192,7 @@ "lValueRequested": false, "nodeType": "Literal", "src": "304:4:0", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_bool", "typeString": "bool" }, @@ -245,15 +211,13 @@ "name": "", "nameLocation": "-1:-1:-1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 4, "nodeType": "ParameterList", "parameters": [], "src": "269:2:0" }, - "returnParameters": - { + "returnParameters": { "id": 5, "nodeType": "ParameterList", "parameters": [], diff --git a/test/cmdlineTests/standard_outputs_on_parsing_error/output.json b/test/cmdlineTests/standard_outputs_on_parsing_error/output.json index 8c1f6c0dbe28..6730d772ee02 100644 --- a/test/cmdlineTests/standard_outputs_on_parsing_error/output.json +++ b/test/cmdlineTests/standard_outputs_on_parsing_error/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "errorCode": "7858", @@ -13,8 +12,7 @@ ", "message": "Expected pragma, import directive or contract/interface/library/struct/enum/constant/function/error definition.", "severity": "error", - "sourceLocation": - { + "sourceLocation": { "end": 121, "file": "C", "start": 120 diff --git a/test/cmdlineTests/standard_parsing_import_absolute_paths/output.json b/test/cmdlineTests/standard_parsing_import_absolute_paths/output.json index 1982561ef2a2..1be9f4b0d095 100644 --- a/test/cmdlineTests/standard_parsing_import_absolute_paths/output.json +++ b/test/cmdlineTests/standard_parsing_import_absolute_paths/output.json @@ -1,20 +1,15 @@ { - "sources": - { - "/lib/L.sol": - { - "ast": - { + "sources": { + "/lib/L.sol": { + "ast": { "absolutePath": "/lib/L.sol", "id": 2, "license": "GPL-2.0", "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "id": 1, - "literals": - [ + "literals": [ "solidity", ">=", "0.0" @@ -27,20 +22,16 @@ }, "id": 0 }, - "/project/../C.sol": - { - "ast": - { + "/project/../C.sol": { + "ast": { "absolutePath": "/project/../C.sol", "id": 5, "license": "GPL-2.0", "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "id": 3, - "literals": - [ + "literals": [ "solidity", ">=", "0.0" diff --git a/test/cmdlineTests/standard_raw_utf16_filename/output.json b/test/cmdlineTests/standard_raw_utf16_filename/output.json index a370472f25f1..cebd87943a63 100644 --- a/test/cmdlineTests/standard_raw_utf16_filename/output.json +++ b/test/cmdlineTests/standard_raw_utf16_filename/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "formattedMessage": "parse error at line 5, column 4: syntax error while parsing object key - invalid string: control character U+0000 (NUL) must be escaped to \\u0000; last read: '\"'; expected string literal", diff --git a/test/cmdlineTests/standard_secondary_source_location/output.json b/test/cmdlineTests/standard_secondary_source_location/output.json index 6423769aab15..ea47eeaade30 100644 --- a/test/cmdlineTests/standard_secondary_source_location/output.json +++ b/test/cmdlineTests/standard_secondary_source_location/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "errorCode": "3364", @@ -22,8 +21,7 @@ Note: Second constructor call is here: ", "message": "Base constructor arguments given twice.", - "secondarySourceLocations": - [ + "secondarySourceLocations": [ { "end": 112, "file": "A", @@ -38,8 +36,7 @@ Note: Second constructor call is here: } ], "severity": "error", - "sourceLocation": - { + "sourceLocation": { "end": 160, "file": "A", "start": 139 diff --git a/test/cmdlineTests/standard_stop_after_parsing_ast_requested/output.json b/test/cmdlineTests/standard_stop_after_parsing_ast_requested/output.json index 6907d4780f58..3bddad829272 100644 --- a/test/cmdlineTests/standard_stop_after_parsing_ast_requested/output.json +++ b/test/cmdlineTests/standard_stop_after_parsing_ast_requested/output.json @@ -1,20 +1,15 @@ { - "sources": - { - "C": - { - "ast": - { + "sources": { + "C": { + "ast": { "absolutePath": "C", "id": 4, "license": "GPL-3.0", "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "id": 1, - "literals": - [ + "literals": [ "solidity", "*" ], diff --git a/test/cmdlineTests/standard_stop_after_parsing_bytecode_requested/output.json b/test/cmdlineTests/standard_stop_after_parsing_bytecode_requested/output.json index 37195309631d..1699ed88086c 100644 --- a/test/cmdlineTests/standard_stop_after_parsing_bytecode_requested/output.json +++ b/test/cmdlineTests/standard_stop_after_parsing_bytecode_requested/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "formattedMessage": "Requested output selection conflicts with \"settings.stopAfter\".", diff --git a/test/cmdlineTests/standard_stop_after_parsing_non_binary_output_requested/output.json b/test/cmdlineTests/standard_stop_after_parsing_non_binary_output_requested/output.json index 5b64763be82f..264cd37be95e 100644 --- a/test/cmdlineTests/standard_stop_after_parsing_non_binary_output_requested/output.json +++ b/test/cmdlineTests/standard_stop_after_parsing_non_binary_output_requested/output.json @@ -1,8 +1,6 @@ { - "sources": - { - "C": - { + "sources": { + "C": { "id": 0 } } diff --git a/test/cmdlineTests/standard_urls_existing_and_missing/output.json b/test/cmdlineTests/standard_urls_existing_and_missing/output.json index 87db5f4db78e..e9db1135d764 100644 --- a/test/cmdlineTests/standard_urls_existing_and_missing/output.json +++ b/test/cmdlineTests/standard_urls_existing_and_missing/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "formattedMessage": "Cannot import url (\"standard_urls_existing_and_missing/non-existent-contract-1.sol\"): File not found. Searched the following locations: \"\".", @@ -9,10 +8,8 @@ "type": "Warning" } ], - "sources": - { - "url_not_found.sol": - { + "sources": { + "url_not_found.sol": { "id": 0 } } diff --git a/test/cmdlineTests/standard_urls_missing/output.json b/test/cmdlineTests/standard_urls_missing/output.json index 267618ee9330..7e2bb3dd59c2 100644 --- a/test/cmdlineTests/standard_urls_missing/output.json +++ b/test/cmdlineTests/standard_urls_missing/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "formattedMessage": "Cannot import url (\"standard_urls_missing/non-existent-contract-1.sol\"): File not found. Searched the following locations: \"\".", diff --git a/test/cmdlineTests/standard_viair_requested/output.json b/test/cmdlineTests/standard_viair_requested/output.json index 3e459c56f959..0105ea97298a 100644 --- a/test/cmdlineTests/standard_viair_requested/output.json +++ b/test/cmdlineTests/standard_viair_requested/output.json @@ -1,19 +1,13 @@ { - "contracts": - { - "A": - { - "C": - { - "evm": - { - "bytecode": - { + "contracts": { + "A": { + "C": { + "evm": { + "bytecode": { "generatedSources": [], "object": "" }, - "deployedBytecode": - { + "deployedBytecode": { "object": "" } }, @@ -81,17 +75,13 @@ object \"C_3\" { " }, - "D": - { - "evm": - { - "bytecode": - { + "D": { + "evm": { + "bytecode": { "generatedSources": [], "object": "" }, - "deployedBytecode": - { + "deployedBytecode": { "object": "" } }, @@ -299,8 +289,7 @@ object \"D_16\" { } } }, - "errors": - [ + "errors": [ { "component": "general", "errorCode": "2072", @@ -313,8 +302,7 @@ object \"D_16\" { ", "message": "Unused local variable.", "severity": "warning", - "sourceLocation": - { + "sourceLocation": { "end": 131, "file": "A", "start": 128 @@ -322,10 +310,8 @@ object \"D_16\" { "type": "Warning" } ], - "sources": - { - "A": - { + "sources": { + "A": { "id": 0 } } diff --git a/test/cmdlineTests/standard_wrong_key_auxiliary_input/output.json b/test/cmdlineTests/standard_wrong_key_auxiliary_input/output.json index 1e846d19c708..e1ac73e8fd5a 100644 --- a/test/cmdlineTests/standard_wrong_key_auxiliary_input/output.json +++ b/test/cmdlineTests/standard_wrong_key_auxiliary_input/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "formattedMessage": "Unknown key \"key1\"", diff --git a/test/cmdlineTests/standard_wrong_key_metadata/output.json b/test/cmdlineTests/standard_wrong_key_metadata/output.json index 1e846d19c708..e1ac73e8fd5a 100644 --- a/test/cmdlineTests/standard_wrong_key_metadata/output.json +++ b/test/cmdlineTests/standard_wrong_key_metadata/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "formattedMessage": "Unknown key \"key1\"", diff --git a/test/cmdlineTests/standard_wrong_key_optimizer/output.json b/test/cmdlineTests/standard_wrong_key_optimizer/output.json index 1e846d19c708..e1ac73e8fd5a 100644 --- a/test/cmdlineTests/standard_wrong_key_optimizer/output.json +++ b/test/cmdlineTests/standard_wrong_key_optimizer/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "formattedMessage": "Unknown key \"key1\"", diff --git a/test/cmdlineTests/standard_wrong_key_root/output.json b/test/cmdlineTests/standard_wrong_key_root/output.json index 1e846d19c708..e1ac73e8fd5a 100644 --- a/test/cmdlineTests/standard_wrong_key_root/output.json +++ b/test/cmdlineTests/standard_wrong_key_root/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "formattedMessage": "Unknown key \"key1\"", diff --git a/test/cmdlineTests/standard_wrong_key_settings/output.json b/test/cmdlineTests/standard_wrong_key_settings/output.json index 1e846d19c708..e1ac73e8fd5a 100644 --- a/test/cmdlineTests/standard_wrong_key_settings/output.json +++ b/test/cmdlineTests/standard_wrong_key_settings/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "formattedMessage": "Unknown key \"key1\"", diff --git a/test/cmdlineTests/standard_wrong_key_source/output.json b/test/cmdlineTests/standard_wrong_key_source/output.json index 1e846d19c708..e1ac73e8fd5a 100644 --- a/test/cmdlineTests/standard_wrong_key_source/output.json +++ b/test/cmdlineTests/standard_wrong_key_source/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "formattedMessage": "Unknown key \"key1\"", diff --git a/test/cmdlineTests/standard_wrong_type_auxiliary_input/output.json b/test/cmdlineTests/standard_wrong_type_auxiliary_input/output.json index 877ecad4dce6..efe3d722e629 100644 --- a/test/cmdlineTests/standard_wrong_type_auxiliary_input/output.json +++ b/test/cmdlineTests/standard_wrong_type_auxiliary_input/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "formattedMessage": "\"auxiliaryInput\" must be an object", diff --git a/test/cmdlineTests/standard_wrong_type_auxiliary_input_smtlib2responses/output.json b/test/cmdlineTests/standard_wrong_type_auxiliary_input_smtlib2responses/output.json index c28238145e4c..ec3c7a804477 100644 --- a/test/cmdlineTests/standard_wrong_type_auxiliary_input_smtlib2responses/output.json +++ b/test/cmdlineTests/standard_wrong_type_auxiliary_input_smtlib2responses/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "formattedMessage": "\"auxiliaryInput.smtlib2responses\" must be an object.", diff --git a/test/cmdlineTests/standard_wrong_type_auxiliary_input_smtlib2responses_member/output.json b/test/cmdlineTests/standard_wrong_type_auxiliary_input_smtlib2responses_member/output.json index 6676998c6cca..0cbceafdad98 100644 --- a/test/cmdlineTests/standard_wrong_type_auxiliary_input_smtlib2responses_member/output.json +++ b/test/cmdlineTests/standard_wrong_type_auxiliary_input_smtlib2responses_member/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "formattedMessage": "\"smtlib2Responses.abc\" must be a string.", diff --git a/test/cmdlineTests/standard_wrong_type_metadata/output.json b/test/cmdlineTests/standard_wrong_type_metadata/output.json index df9f8cae37ad..38b2ffca6a96 100644 --- a/test/cmdlineTests/standard_wrong_type_metadata/output.json +++ b/test/cmdlineTests/standard_wrong_type_metadata/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "formattedMessage": "\"settings.metadata\" must be an object", diff --git a/test/cmdlineTests/standard_wrong_type_optimizer/output.json b/test/cmdlineTests/standard_wrong_type_optimizer/output.json index d7ce30326b92..c6bc5cc3fafa 100644 --- a/test/cmdlineTests/standard_wrong_type_optimizer/output.json +++ b/test/cmdlineTests/standard_wrong_type_optimizer/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "formattedMessage": "\"settings.optimizer\" must be an object", diff --git a/test/cmdlineTests/standard_wrong_type_output_selection/output.json b/test/cmdlineTests/standard_wrong_type_output_selection/output.json index d7d8f563fde5..346590a7cd89 100644 --- a/test/cmdlineTests/standard_wrong_type_output_selection/output.json +++ b/test/cmdlineTests/standard_wrong_type_output_selection/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "formattedMessage": "\"settings.outputSelection\" must be an object", diff --git a/test/cmdlineTests/standard_wrong_type_output_selection_contract/output.json b/test/cmdlineTests/standard_wrong_type_output_selection_contract/output.json index 5a35419ef94d..dbb4af997110 100644 --- a/test/cmdlineTests/standard_wrong_type_output_selection_contract/output.json +++ b/test/cmdlineTests/standard_wrong_type_output_selection_contract/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "formattedMessage": "\"settings.outputSelection.fileA.A\" must be a string array", diff --git a/test/cmdlineTests/standard_wrong_type_output_selection_file/output.json b/test/cmdlineTests/standard_wrong_type_output_selection_file/output.json index 888efc75b01c..4a7385834231 100644 --- a/test/cmdlineTests/standard_wrong_type_output_selection_file/output.json +++ b/test/cmdlineTests/standard_wrong_type_output_selection_file/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "formattedMessage": "\"settings.outputSelection.fileA\" must be an object", diff --git a/test/cmdlineTests/standard_wrong_type_output_selection_output/output.json b/test/cmdlineTests/standard_wrong_type_output_selection_output/output.json index 5a35419ef94d..dbb4af997110 100644 --- a/test/cmdlineTests/standard_wrong_type_output_selection_output/output.json +++ b/test/cmdlineTests/standard_wrong_type_output_selection_output/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "formattedMessage": "\"settings.outputSelection.fileA.A\" must be a string array", diff --git a/test/cmdlineTests/standard_wrong_type_remappings/output.json b/test/cmdlineTests/standard_wrong_type_remappings/output.json index b94919077e18..a4c327048658 100644 --- a/test/cmdlineTests/standard_wrong_type_remappings/output.json +++ b/test/cmdlineTests/standard_wrong_type_remappings/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "formattedMessage": "\"settings.remappings\" must be an array of strings.", diff --git a/test/cmdlineTests/standard_wrong_type_remappings_entry/output.json b/test/cmdlineTests/standard_wrong_type_remappings_entry/output.json index d083c85be340..75162fd057c1 100644 --- a/test/cmdlineTests/standard_wrong_type_remappings_entry/output.json +++ b/test/cmdlineTests/standard_wrong_type_remappings_entry/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "formattedMessage": "\"settings.remappings\" must be an array of strings", diff --git a/test/cmdlineTests/standard_wrong_type_root/output.json b/test/cmdlineTests/standard_wrong_type_root/output.json index da8fefdf5944..59f7778b13c6 100644 --- a/test/cmdlineTests/standard_wrong_type_root/output.json +++ b/test/cmdlineTests/standard_wrong_type_root/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "formattedMessage": "Input is not a JSON object.", diff --git a/test/cmdlineTests/standard_wrong_type_settings/output.json b/test/cmdlineTests/standard_wrong_type_settings/output.json index a25071c85884..d75283112a30 100644 --- a/test/cmdlineTests/standard_wrong_type_settings/output.json +++ b/test/cmdlineTests/standard_wrong_type_settings/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "formattedMessage": "\"settings\" must be an object", diff --git a/test/cmdlineTests/standard_wrong_type_source/output.json b/test/cmdlineTests/standard_wrong_type_source/output.json index 98496c64333d..0da063fb1c2a 100644 --- a/test/cmdlineTests/standard_wrong_type_source/output.json +++ b/test/cmdlineTests/standard_wrong_type_source/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "formattedMessage": "\"sources.A\" must be an object", diff --git a/test/cmdlineTests/standard_wrong_type_sources/output.json b/test/cmdlineTests/standard_wrong_type_sources/output.json index 3f5f51fcebc3..abf248c00e3f 100644 --- a/test/cmdlineTests/standard_wrong_type_sources/output.json +++ b/test/cmdlineTests/standard_wrong_type_sources/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "formattedMessage": "\"sources\" is not a JSON object.", diff --git a/test/cmdlineTests/standard_wrong_type_useLiteralContent/output.json b/test/cmdlineTests/standard_wrong_type_useLiteralContent/output.json index 7135c9856258..def6ad69e095 100644 --- a/test/cmdlineTests/standard_wrong_type_useLiteralContent/output.json +++ b/test/cmdlineTests/standard_wrong_type_useLiteralContent/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "formattedMessage": "\"settings.metadata.useLiteralContent\" must be Boolean", diff --git a/test/cmdlineTests/standard_yul/output.json b/test/cmdlineTests/standard_yul/output.json index c1b22726fb84..8d2ab0074790 100644 --- a/test/cmdlineTests/standard_yul/output.json +++ b/test/cmdlineTests/standard_yul/output.json @@ -1,12 +1,8 @@ { - "contracts": - { - "A": - { - "object": - { - "evm": - { + "contracts": { + "A": { + "object": { + "evm": { "assembly": " /* \"A\":38:39 */ 0x00 /* \"A\":11:19 */ @@ -20,8 +16,7 @@ /* \"A\":0:42 */ stop ", - "bytecode": - { + "bytecode": { "functionDebugData": {}, "generatedSources": [], "linkReferences": {}, @@ -49,29 +44,21 @@ } } }, - "sources": - { - "A": - { - "ast": - { - "code": - { - "block": - { + "sources": { + "A": { + "ast": { + "code": { + "block": { "nativeSrc": "0:42:0", "nodeType": "YulBlock", "src": "0:42:0", - "statements": - [ + "statements": [ { "nativeSrc": "2:17:0", "nodeType": "YulVariableDeclaration", "src": "2:17:0", - "value": - { - "arguments": - [ + "value": { + "arguments": [ { "kind": "number", "nativeSrc": "17:1:0", @@ -81,8 +68,7 @@ "value": "0" } ], - "functionName": - { + "functionName": { "name": "mload", "nativeSrc": "11:5:0", "nodeType": "YulIdentifier", @@ -92,8 +78,7 @@ "nodeType": "YulFunctionCall", "src": "11:8:0" }, - "variables": - [ + "variables": [ { "name": "x", "nativeSrc": "6:1:0", @@ -104,13 +89,10 @@ ] }, { - "expression": - { - "arguments": - [ + "expression": { + "arguments": [ { - "arguments": - [ + "arguments": [ { "name": "x", "nativeSrc": "31:1:0", @@ -126,8 +108,7 @@ "value": "0" } ], - "functionName": - { + "functionName": { "name": "add", "nativeSrc": "27:3:0", "nodeType": "YulIdentifier", @@ -146,8 +127,7 @@ "value": "0" } ], - "functionName": - { + "functionName": { "name": "sstore", "nativeSrc": "20:6:0", "nodeType": "YulIdentifier", diff --git a/test/cmdlineTests/standard_yul_debug_info_print_all/output.json b/test/cmdlineTests/standard_yul_debug_info_print_all/output.json index 9d675a06918d..c994baf4fcc2 100644 --- a/test/cmdlineTests/standard_yul_debug_info_print_all/output.json +++ b/test/cmdlineTests/standard_yul_debug_info_print_all/output.json @@ -1,12 +1,8 @@ { - "contracts": - { - "C": - { - "C_6_deployed": - { - "evm": - { + "contracts": { + "C": { + "C_6_deployed": { + "evm": { "assembly": " /* \"input.sol\":60:101 */ mstore(0x40, 0x80) tag_2 diff --git a/test/cmdlineTests/standard_yul_debug_info_print_location_only/output.json b/test/cmdlineTests/standard_yul_debug_info_print_location_only/output.json index 8cbbd326c71e..54b37f8ef858 100644 --- a/test/cmdlineTests/standard_yul_debug_info_print_location_only/output.json +++ b/test/cmdlineTests/standard_yul_debug_info_print_location_only/output.json @@ -1,12 +1,8 @@ { - "contracts": - { - "C": - { - "C_6_deployed": - { - "evm": - { + "contracts": { + "C": { + "C_6_deployed": { + "evm": { "assembly": " /* \"input.sol\":60:101 */ mstore(0x40, 0x80) tag_2 diff --git a/test/cmdlineTests/standard_yul_debug_info_print_none/output.json b/test/cmdlineTests/standard_yul_debug_info_print_none/output.json index d1e4cff4cb3d..5b8cc709fb10 100644 --- a/test/cmdlineTests/standard_yul_debug_info_print_none/output.json +++ b/test/cmdlineTests/standard_yul_debug_info_print_none/output.json @@ -1,12 +1,8 @@ { - "contracts": - { - "C": - { - "C_6_deployed": - { - "evm": - { + "contracts": { + "C": { + "C_6_deployed": { + "evm": { "assembly": " mstore(0x40, 0x80) tag_2 tag_1 diff --git a/test/cmdlineTests/standard_yul_debug_info_print_snippet_only/output.json b/test/cmdlineTests/standard_yul_debug_info_print_snippet_only/output.json index fb7f199a75cf..7f48fd4e93bc 100644 --- a/test/cmdlineTests/standard_yul_debug_info_print_snippet_only/output.json +++ b/test/cmdlineTests/standard_yul_debug_info_print_snippet_only/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "formattedMessage": "To use 'snippet' with settings.debug.debugInfo you must select also 'location'.", diff --git a/test/cmdlineTests/standard_yul_evm_version_byzantium/output.json b/test/cmdlineTests/standard_yul_evm_version_byzantium/output.json index 9fff562796b2..bbe178353f5f 100644 --- a/test/cmdlineTests/standard_yul_evm_version_byzantium/output.json +++ b/test/cmdlineTests/standard_yul_evm_version_byzantium/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "formattedMessage": "Support for EVM versions older than constantinople is deprecated and will be removed in the future.", diff --git a/test/cmdlineTests/standard_yul_immutable_references/output.json b/test/cmdlineTests/standard_yul_immutable_references/output.json index 1f75e8ad20b1..7bfbb076a389 100644 --- a/test/cmdlineTests/standard_yul_immutable_references/output.json +++ b/test/cmdlineTests/standard_yul_immutable_references/output.json @@ -1,14 +1,9 @@ { - "contracts": - { - "A": - { - "YulTest": - { - "evm": - { - "bytecode": - { + "contracts": { + "A": { + "YulTest": { + "evm": { + "bytecode": { "functionDebugData": {}, "generatedSources": [], "linkReferences": {}, @@ -16,14 +11,11 @@ "opcodes":"", "sourceMap":"" }, - "deployedBytecode": - { + "deployedBytecode": { "functionDebugData": {}, "generatedSources": [], - "immutableReferences": - { - "test": - [ + "immutableReferences": { + "test": [ { "length": 32, "start": 1 diff --git a/test/cmdlineTests/standard_yul_multiple_files/output.json b/test/cmdlineTests/standard_yul_multiple_files/output.json index cdef28c267cf..88f390204eb3 100644 --- a/test/cmdlineTests/standard_yul_multiple_files/output.json +++ b/test/cmdlineTests/standard_yul_multiple_files/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "formattedMessage": "Yul mode only supports exactly one input file.", diff --git a/test/cmdlineTests/standard_yul_multiple_files_selected/output.json b/test/cmdlineTests/standard_yul_multiple_files_selected/output.json index cdef28c267cf..88f390204eb3 100644 --- a/test/cmdlineTests/standard_yul_multiple_files_selected/output.json +++ b/test/cmdlineTests/standard_yul_multiple_files_selected/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "formattedMessage": "Yul mode only supports exactly one input file.", diff --git a/test/cmdlineTests/standard_yul_object/output.json b/test/cmdlineTests/standard_yul_object/output.json index 1404cd3aa7df..87d0cab8f4ff 100644 --- a/test/cmdlineTests/standard_yul_object/output.json +++ b/test/cmdlineTests/standard_yul_object/output.json @@ -1,12 +1,8 @@ { - "contracts": - { - "A": - { - "NamedObject": - { - "evm": - { + "contracts": { + "A": { + "NamedObject": { + "evm": { "assembly": " /* \"A\":80:81 */ 0x00 /* \"A\":39:61 */ @@ -21,8 +17,7 @@ stop data_4e03657aea45a94fc7d47ba826c8d667c0d1e6e33a64a036ec44f58fa12d6c45 616263 ", - "bytecode": - { + "bytecode": { "functionDebugData": {}, "generatedSources": [], "linkReferences": {}, @@ -52,29 +47,21 @@ data_4e03657aea45a94fc7d47ba826c8d667c0d1e6e33a64a036ec44f58fa12d6c45 616263 } } }, - "sources": - { - "A": - { - "ast": - { - "code": - { - "block": - { + "sources": { + "A": { + "ast": { + "code": { + "block": { "nativeSrc": "28:56:0", "nodeType": "YulBlock", "src": "28:56:0", - "statements": - [ + "statements": [ { "nativeSrc": "30:31:0", "nodeType": "YulVariableDeclaration", "src": "30:31:0", - "value": - { - "arguments": - [ + "value": { + "arguments": [ { "hexValue": "446174614e616d65", "kind": "string", @@ -85,8 +72,7 @@ data_4e03657aea45a94fc7d47ba826c8d667c0d1e6e33a64a036ec44f58fa12d6c45 616263 "value": "DataName" } ], - "functionName": - { + "functionName": { "name": "dataoffset", "nativeSrc": "39:10:0", "nodeType": "YulIdentifier", @@ -96,8 +82,7 @@ data_4e03657aea45a94fc7d47ba826c8d667c0d1e6e33a64a036ec44f58fa12d6c45 616263 "nodeType": "YulFunctionCall", "src": "39:22:0" }, - "variables": - [ + "variables": [ { "name": "x", "nativeSrc": "34:1:0", @@ -108,13 +93,10 @@ data_4e03657aea45a94fc7d47ba826c8d667c0d1e6e33a64a036ec44f58fa12d6c45 616263 ] }, { - "expression": - { - "arguments": - [ + "expression": { + "arguments": [ { - "arguments": - [ + "arguments": [ { "name": "x", "nativeSrc": "73:1:0", @@ -130,8 +112,7 @@ data_4e03657aea45a94fc7d47ba826c8d667c0d1e6e33a64a036ec44f58fa12d6c45 616263 "value": "0" } ], - "functionName": - { + "functionName": { "name": "add", "nativeSrc": "69:3:0", "nodeType": "YulIdentifier", @@ -150,8 +131,7 @@ data_4e03657aea45a94fc7d47ba826c8d667c0d1e6e33a64a036ec44f58fa12d6c45 616263 "value": "0" } ], - "functionName": - { + "functionName": { "name": "sstore", "nativeSrc": "62:6:0", "nodeType": "YulIdentifier", @@ -171,8 +151,7 @@ data_4e03657aea45a94fc7d47ba826c8d667c0d1e6e33a64a036ec44f58fa12d6c45 616263 }, "name": "NamedObject", "nodeType": "YulObject", - "subObjects": - [ + "subObjects": [ { "nodeType": "YulData", "value": "616263" diff --git a/test/cmdlineTests/standard_yul_object_invalid_sub/output.json b/test/cmdlineTests/standard_yul_object_invalid_sub/output.json index 98522145a6e0..fea1aa169a17 100644 --- a/test/cmdlineTests/standard_yul_object_invalid_sub/output.json +++ b/test/cmdlineTests/standard_yul_object_invalid_sub/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "formattedMessage": "TypeError: Unknown data object \"NamedObject.\". @@ -12,8 +11,7 @@ ", "message": "Unknown data object \"NamedObject.\".", "severity": "error", - "sourceLocation": - { + "sourceLocation": { "end": 64, "file": "A", "start": 50 diff --git a/test/cmdlineTests/standard_yul_object_name/output.json b/test/cmdlineTests/standard_yul_object_name/output.json index 6803c322d194..c6e98130d210 100644 --- a/test/cmdlineTests/standard_yul_object_name/output.json +++ b/test/cmdlineTests/standard_yul_object_name/output.json @@ -1,12 +1,8 @@ { - "contracts": - { - "A": - { - "NamedObject": - { - "evm": - { + "contracts": { + "A": { + "NamedObject": { + "evm": { "assembly": " /* \"A\":80:81 */ 0x00 /* \"A\":39:61 */ @@ -29,8 +25,7 @@ sub_0: assembly { revert } ", - "bytecode": - { + "bytecode": { "functionDebugData": {}, "generatedSources": [], "linkReferences": {}, @@ -38,8 +33,7 @@ sub_0: assembly { "opcodes":"", "sourceMap":"" }, - "deployedBytecode": - { + "deployedBytecode": { "functionDebugData": {}, "generatedSources": [], "immutableReferences": {}, @@ -76,29 +70,21 @@ sub_0: assembly { } } }, - "sources": - { - "A": - { - "ast": - { - "code": - { - "block": - { + "sources": { + "A": { + "ast": { + "code": { + "block": { "nativeSrc": "28:56:0", "nodeType": "YulBlock", "src": "28:56:0", - "statements": - [ + "statements": [ { "nativeSrc": "30:31:0", "nodeType": "YulVariableDeclaration", "src": "30:31:0", - "value": - { - "arguments": - [ + "value": { + "arguments": [ { "hexValue": "446174614e616d65", "kind": "string", @@ -109,8 +95,7 @@ sub_0: assembly { "value": "DataName" } ], - "functionName": - { + "functionName": { "name": "dataoffset", "nativeSrc": "39:10:0", "nodeType": "YulIdentifier", @@ -120,8 +105,7 @@ sub_0: assembly { "nodeType": "YulFunctionCall", "src": "39:22:0" }, - "variables": - [ + "variables": [ { "name": "x", "nativeSrc": "34:1:0", @@ -132,13 +116,10 @@ sub_0: assembly { ] }, { - "expression": - { - "arguments": - [ + "expression": { + "arguments": [ { - "arguments": - [ + "arguments": [ { "name": "x", "nativeSrc": "73:1:0", @@ -154,8 +135,7 @@ sub_0: assembly { "value": "0" } ], - "functionName": - { + "functionName": { "name": "add", "nativeSrc": "69:3:0", "nodeType": "YulIdentifier", @@ -174,8 +154,7 @@ sub_0: assembly { "value": "0" } ], - "functionName": - { + "functionName": { "name": "sstore", "nativeSrc": "62:6:0", "nodeType": "YulIdentifier", @@ -195,27 +174,21 @@ sub_0: assembly { }, "name": "NamedObject", "nodeType": "YulObject", - "subObjects": - [ + "subObjects": [ { "nodeType": "YulData", "value": "616263" }, { - "code": - { - "block": - { + "code": { + "block": { "nativeSrc": "135:16:0", "nodeType": "YulBlock", "src": "135:16:0", - "statements": - [ + "statements": [ { - "expression": - { - "arguments": - [ + "expression": { + "arguments": [ { "kind": "number", "nativeSrc": "144:1:0", @@ -233,8 +206,7 @@ sub_0: assembly { "value": "0" } ], - "functionName": - { + "functionName": { "name": "revert", "nativeSrc": "137:6:0", "nodeType": "YulIdentifier", diff --git a/test/cmdlineTests/standard_yul_optimiserSteps/output.json b/test/cmdlineTests/standard_yul_optimiserSteps/output.json index 85a34261f02b..1c72379c610b 100644 --- a/test/cmdlineTests/standard_yul_optimiserSteps/output.json +++ b/test/cmdlineTests/standard_yul_optimiserSteps/output.json @@ -1,12 +1,8 @@ { - "contracts": - { - "A": - { - "object": - { - "evm": - { + "contracts": { + "A": { + "object": { + "evm": { "assembly": " /* \"A\":38:39 */ 0x00 /* \"A\":11:19 */ @@ -17,8 +13,7 @@ /* \"A\":0:42 */ stop ", - "bytecode": - { + "bytecode": { "functionDebugData": {}, "generatedSources": [], "linkReferences": {}, @@ -46,29 +41,21 @@ } } }, - "sources": - { - "A": - { - "ast": - { - "code": - { - "block": - { + "sources": { + "A": { + "ast": { + "code": { + "block": { "nativeSrc": "0:42:0", "nodeType": "YulBlock", "src": "0:42:0", - "statements": - [ + "statements": [ { "nativeSrc": "2:17:0", "nodeType": "YulVariableDeclaration", "src": "2:17:0", - "value": - { - "arguments": - [ + "value": { + "arguments": [ { "kind": "number", "nativeSrc": "17:1:0", @@ -78,8 +65,7 @@ "value": "0" } ], - "functionName": - { + "functionName": { "name": "mload", "nativeSrc": "11:5:0", "nodeType": "YulIdentifier", @@ -89,8 +75,7 @@ "nodeType": "YulFunctionCall", "src": "11:8:0" }, - "variables": - [ + "variables": [ { "name": "x", "nativeSrc": "6:1:0", @@ -101,13 +86,10 @@ ] }, { - "expression": - { - "arguments": - [ + "expression": { + "arguments": [ { - "arguments": - [ + "arguments": [ { "name": "x", "nativeSrc": "31:1:0", @@ -123,8 +105,7 @@ "value": "0" } ], - "functionName": - { + "functionName": { "name": "add", "nativeSrc": "27:3:0", "nodeType": "YulIdentifier", @@ -143,8 +124,7 @@ "value": "0" } ], - "functionName": - { + "functionName": { "name": "sstore", "nativeSrc": "20:6:0", "nodeType": "YulIdentifier", diff --git a/test/cmdlineTests/standard_yul_optimized/output.json b/test/cmdlineTests/standard_yul_optimized/output.json index d580ef6ae01f..c443b2863f15 100644 --- a/test/cmdlineTests/standard_yul_optimized/output.json +++ b/test/cmdlineTests/standard_yul_optimized/output.json @@ -1,12 +1,8 @@ { - "contracts": - { - "A": - { - "object": - { - "evm": - { + "contracts": { + "A": { + "object": { + "evm": { "assembly": " /* \"A\":17:18 */ 0x00 /* \"A\":11:19 */ @@ -17,8 +13,7 @@ /* \"A\":0:42 */ stop ", - "bytecode": - { + "bytecode": { "functionDebugData": {}, "generatedSources": [], "linkReferences": {}, @@ -41,29 +36,21 @@ } } }, - "sources": - { - "A": - { - "ast": - { - "code": - { - "block": - { + "sources": { + "A": { + "ast": { + "code": { + "block": { "nativeSrc": "0:42:0", "nodeType": "YulBlock", "src": "0:42:0", - "statements": - [ + "statements": [ { "nativeSrc": "2:17:0", "nodeType": "YulVariableDeclaration", "src": "2:17:0", - "value": - { - "arguments": - [ + "value": { + "arguments": [ { "kind": "number", "nativeSrc": "17:1:0", @@ -73,8 +60,7 @@ "value": "0" } ], - "functionName": - { + "functionName": { "name": "mload", "nativeSrc": "11:5:0", "nodeType": "YulIdentifier", @@ -84,8 +70,7 @@ "nodeType": "YulFunctionCall", "src": "11:8:0" }, - "variables": - [ + "variables": [ { "name": "x", "nativeSrc": "6:1:0", @@ -96,13 +81,10 @@ ] }, { - "expression": - { - "arguments": - [ + "expression": { + "arguments": [ { - "arguments": - [ + "arguments": [ { "name": "x", "nativeSrc": "31:1:0", @@ -118,8 +100,7 @@ "value": "0" } ], - "functionName": - { + "functionName": { "name": "add", "nativeSrc": "27:3:0", "nodeType": "YulIdentifier", @@ -138,8 +119,7 @@ "value": "0" } ], - "functionName": - { + "functionName": { "name": "sstore", "nativeSrc": "20:6:0", "nodeType": "YulIdentifier", diff --git a/test/cmdlineTests/standard_yul_single_file_via_urls/output.json b/test/cmdlineTests/standard_yul_single_file_via_urls/output.json index a97057c88994..e76d039f5eff 100644 --- a/test/cmdlineTests/standard_yul_single_file_via_urls/output.json +++ b/test/cmdlineTests/standard_yul_single_file_via_urls/output.json @@ -1,6 +1,5 @@ { - "errors": - [ + "errors": [ { "component": "general", "formattedMessage": "Cannot import url (\"in.yul\"): File not found. Searched the following locations: \"\".", diff --git a/test/cmdlineTests/standard_yul_stack_opt/output.json b/test/cmdlineTests/standard_yul_stack_opt/output.json index e10ef0c1724f..9d89edfb4ae9 100644 --- a/test/cmdlineTests/standard_yul_stack_opt/output.json +++ b/test/cmdlineTests/standard_yul_stack_opt/output.json @@ -1,12 +1,8 @@ { - "contracts": - { - "A": - { - "object": - { - "evm": - { + "contracts": { + "A": { + "object": { + "evm": { "assembly": " /* \"A\":16:17 */ 0x01 /* \"A\":27:28 */ diff --git a/test/cmdlineTests/standard_yul_stack_opt_disabled/output.json b/test/cmdlineTests/standard_yul_stack_opt_disabled/output.json index 8d58cf320415..f0752b812b44 100644 --- a/test/cmdlineTests/standard_yul_stack_opt_disabled/output.json +++ b/test/cmdlineTests/standard_yul_stack_opt_disabled/output.json @@ -1,12 +1,8 @@ { - "contracts": - { - "A": - { - "object": - { - "evm": - { + "contracts": { + "A": { + "object": { + "evm": { "assembly": " /* \"A\":16:17 */ 0x01 /* \"A\":27:28 */ diff --git a/test/cmdlineTests/stop_after_parsing_ast/output b/test/cmdlineTests/stop_after_parsing_ast/output index 163941860401..6cca9557da1b 100644 --- a/test/cmdlineTests/stop_after_parsing_ast/output +++ b/test/cmdlineTests/stop_after_parsing_ast/output @@ -7,12 +7,10 @@ JSON AST (compact format): "id": 4, "license": "GPL-3.0", "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "id": 1, - "literals": - [ + "literals": [ "solidity", "*" ], diff --git a/test/cmdlineTests/storage_layout_bytes/output.json b/test/cmdlineTests/storage_layout_bytes/output.json index c2ca7813c672..67091e974e2b 100644 --- a/test/cmdlineTests/storage_layout_bytes/output.json +++ b/test/cmdlineTests/storage_layout_bytes/output.json @@ -1,14 +1,9 @@ { - "contracts": - { - "fileA": - { - "A": - { - "storageLayout": - { - "storage": - [ + "contracts": { + "fileA": { + "A": { + "storageLayout": { + "storage": [ { "astId": 4, "contract": "fileA:A", @@ -26,10 +21,8 @@ "type": "t_bytes_storage" } ], - "types": - { - "t_bytes_storage": - { + "types": { + "t_bytes_storage": { "encoding": "bytes", "label": "bytes", "numberOfBytes": "32" @@ -39,10 +32,8 @@ } } }, - "sources": - { - "fileA": - { + "sources": { + "fileA": { "id": 0 } } diff --git a/test/cmdlineTests/storage_layout_dyn_array/output.json b/test/cmdlineTests/storage_layout_dyn_array/output.json index fa7ed04bad1b..f4468c411d3b 100644 --- a/test/cmdlineTests/storage_layout_dyn_array/output.json +++ b/test/cmdlineTests/storage_layout_dyn_array/output.json @@ -1,14 +1,9 @@ { - "contracts": - { - "fileA": - { - "A": - { - "storageLayout": - { - "storage": - [ + "contracts": { + "fileA": { + "A": { + "storageLayout": { + "storage": [ { "astId": 4, "contract": "fileA:A", @@ -26,30 +21,25 @@ "type": "t_array(t_bool)dyn_storage" } ], - "types": - { - "t_array(t_bool)dyn_storage": - { + "types": { + "t_array(t_bool)dyn_storage": { "base": "t_bool", "encoding": "dynamic_array", "label": "bool[]", "numberOfBytes": "32" }, - "t_array(t_uint256)dyn_storage": - { + "t_array(t_uint256)dyn_storage": { "base": "t_uint256", "encoding": "dynamic_array", "label": "uint256[]", "numberOfBytes": "32" }, - "t_bool": - { + "t_bool": { "encoding": "inplace", "label": "bool", "numberOfBytes": "1" }, - "t_uint256": - { + "t_uint256": { "encoding": "inplace", "label": "uint256", "numberOfBytes": "32" @@ -59,10 +49,8 @@ } } }, - "sources": - { - "fileA": - { + "sources": { + "fileA": { "id": 0 } } diff --git a/test/cmdlineTests/storage_layout_many/output.json b/test/cmdlineTests/storage_layout_many/output.json index 68cb00682477..fa1b6f13e2a7 100644 --- a/test/cmdlineTests/storage_layout_many/output.json +++ b/test/cmdlineTests/storage_layout_many/output.json @@ -1,14 +1,9 @@ { - "contracts": - { - "fileA": - { - "A": - { - "storageLayout": - { - "storage": - [ + "contracts": { + "fileA": { + "A": { + "storageLayout": { + "storage": [ { "astId": 15, "contract": "fileA:A", @@ -74,68 +69,57 @@ "type": "t_bytes_storage" } ], - "types": - { - "t_address": - { + "types": { + "t_address": { "encoding": "inplace", "label": "address", "numberOfBytes": "20" }, - "t_array(t_uint256)2_storage": - { + "t_array(t_uint256)2_storage": { "base": "t_uint256", "encoding": "inplace", "label": "uint256[2]", "numberOfBytes": "64" }, - "t_array(t_uint256)dyn_storage": - { + "t_array(t_uint256)dyn_storage": { "base": "t_uint256", "encoding": "dynamic_array", "label": "uint256[]", "numberOfBytes": "32" }, - "t_bool": - { + "t_bool": { "encoding": "inplace", "label": "bool", "numberOfBytes": "1" }, - "t_bytes_storage": - { + "t_bytes_storage": { "encoding": "bytes", "label": "bytes", "numberOfBytes": "32" }, - "t_mapping(t_address,t_bool)": - { + "t_mapping(t_address,t_bool)": { "encoding": "mapping", "key": "t_address", "label": "mapping(address => bool)", "numberOfBytes": "32", "value": "t_bool" }, - "t_mapping(t_uint256,t_mapping(t_address,t_bool))": - { + "t_mapping(t_uint256,t_mapping(t_address,t_bool))": { "encoding": "mapping", "key": "t_uint256", "label": "mapping(uint256 => mapping(address => bool))", "numberOfBytes": "32", "value": "t_mapping(t_address,t_bool)" }, - "t_string_storage": - { + "t_string_storage": { "encoding": "bytes", "label": "string", "numberOfBytes": "32" }, - "t_struct(S)13_storage": - { + "t_struct(S)13_storage": { "encoding": "inplace", "label": "struct A.S", - "members": - [ + "members": [ { "astId": 3, "contract": "fileA:A", @@ -171,14 +155,12 @@ ], "numberOfBytes": "128" }, - "t_uint128": - { + "t_uint128": { "encoding": "inplace", "label": "uint128", "numberOfBytes": "16" }, - "t_uint256": - { + "t_uint256": { "encoding": "inplace", "label": "uint256", "numberOfBytes": "32" @@ -188,10 +170,8 @@ } } }, - "sources": - { - "fileA": - { + "sources": { + "fileA": { "id": 0 } } diff --git a/test/cmdlineTests/storage_layout_mapping/output.json b/test/cmdlineTests/storage_layout_mapping/output.json index 8d13fb34b45d..9fb9f847c575 100644 --- a/test/cmdlineTests/storage_layout_mapping/output.json +++ b/test/cmdlineTests/storage_layout_mapping/output.json @@ -1,14 +1,9 @@ { - "contracts": - { - "fileA": - { - "A": - { - "storageLayout": - { - "storage": - [ + "contracts": { + "fileA": { + "A": { + "storageLayout": { + "storage": [ { "astId": 3, "contract": "fileA:A", @@ -34,38 +29,32 @@ "type": "t_mapping(t_uint256,t_mapping(t_address,t_bool))" } ], - "types": - { - "t_address": - { + "types": { + "t_address": { "encoding": "inplace", "label": "address", "numberOfBytes": "20" }, - "t_bool": - { + "t_bool": { "encoding": "inplace", "label": "bool", "numberOfBytes": "1" }, - "t_mapping(t_address,t_bool)": - { + "t_mapping(t_address,t_bool)": { "encoding": "mapping", "key": "t_address", "label": "mapping(address => bool)", "numberOfBytes": "32", "value": "t_bool" }, - "t_mapping(t_uint256,t_mapping(t_address,t_bool))": - { + "t_mapping(t_uint256,t_mapping(t_address,t_bool))": { "encoding": "mapping", "key": "t_uint256", "label": "mapping(uint256 => mapping(address => bool))", "numberOfBytes": "32", "value": "t_mapping(t_address,t_bool)" }, - "t_uint256": - { + "t_uint256": { "encoding": "inplace", "label": "uint256", "numberOfBytes": "32" @@ -75,10 +64,8 @@ } } }, - "sources": - { - "fileA": - { + "sources": { + "fileA": { "id": 0 } } diff --git a/test/cmdlineTests/storage_layout_smoke/output.json b/test/cmdlineTests/storage_layout_smoke/output.json index 9fe46bb673c5..e2eaee5004e1 100644 --- a/test/cmdlineTests/storage_layout_smoke/output.json +++ b/test/cmdlineTests/storage_layout_smoke/output.json @@ -1,22 +1,16 @@ { - "contracts": - { - "fileA": - { - "A": - { - "storageLayout": - { + "contracts": { + "fileA": { + "A": { + "storageLayout": { "storage": [], "types": null } } } }, - "sources": - { - "fileA": - { + "sources": { + "fileA": { "id": 0 } } diff --git a/test/cmdlineTests/storage_layout_smoke_two_contracts/output.json b/test/cmdlineTests/storage_layout_smoke_two_contracts/output.json index fc4e422a5e72..2b94484591e3 100644 --- a/test/cmdlineTests/storage_layout_smoke_two_contracts/output.json +++ b/test/cmdlineTests/storage_layout_smoke_two_contracts/output.json @@ -1,26 +1,19 @@ { - "contracts": - { - "fileA": - { - "A": - { - "storageLayout": - { + "contracts": { + "fileA": { + "A": { + "storageLayout": { "storage": [], "types": null } } } }, - "sources": - { - "fileA": - { + "sources": { + "fileA": { "id": 0 }, - "fileB": - { + "fileB": { "id": 1 } } diff --git a/test/cmdlineTests/storage_layout_string/output.json b/test/cmdlineTests/storage_layout_string/output.json index 20c6f64ccd3a..2fcb974dbd30 100644 --- a/test/cmdlineTests/storage_layout_string/output.json +++ b/test/cmdlineTests/storage_layout_string/output.json @@ -1,14 +1,9 @@ { - "contracts": - { - "fileA": - { - "A": - { - "storageLayout": - { - "storage": - [ + "contracts": { + "fileA": { + "A": { + "storageLayout": { + "storage": [ { "astId": 4, "contract": "fileA:A", @@ -26,10 +21,8 @@ "type": "t_string_storage" } ], - "types": - { - "t_string_storage": - { + "types": { + "t_string_storage": { "encoding": "bytes", "label": "string", "numberOfBytes": "32" @@ -39,10 +32,8 @@ } } }, - "sources": - { - "fileA": - { + "sources": { + "fileA": { "id": 0 } } diff --git a/test/cmdlineTests/storage_layout_struct/output.json b/test/cmdlineTests/storage_layout_struct/output.json index f682d9634a3d..1fadb220e876 100644 --- a/test/cmdlineTests/storage_layout_struct/output.json +++ b/test/cmdlineTests/storage_layout_struct/output.json @@ -1,14 +1,9 @@ { - "contracts": - { - "fileA": - { - "A": - { - "storageLayout": - { - "storage": - [ + "contracts": { + "fileA": { + "A": { + "storageLayout": { + "storage": [ { "astId": 15, "contract": "fileA:A", @@ -42,34 +37,28 @@ "type": "t_address" } ], - "types": - { - "t_address": - { + "types": { + "t_address": { "encoding": "inplace", "label": "address", "numberOfBytes": "20" }, - "t_array(t_uint256)2_storage": - { + "t_array(t_uint256)2_storage": { "base": "t_uint256", "encoding": "inplace", "label": "uint256[2]", "numberOfBytes": "64" }, - "t_array(t_uint256)dyn_storage": - { + "t_array(t_uint256)dyn_storage": { "base": "t_uint256", "encoding": "dynamic_array", "label": "uint256[]", "numberOfBytes": "32" }, - "t_struct(S)13_storage": - { + "t_struct(S)13_storage": { "encoding": "inplace", "label": "struct A.S", - "members": - [ + "members": [ { "astId": 3, "contract": "fileA:A", @@ -105,8 +94,7 @@ ], "numberOfBytes": "160" }, - "t_uint256": - { + "t_uint256": { "encoding": "inplace", "label": "uint256", "numberOfBytes": "32" @@ -116,10 +104,8 @@ } } }, - "sources": - { - "fileA": - { + "sources": { + "fileA": { "id": 0 } } diff --git a/test/cmdlineTests/storage_layout_struct_packed/output.json b/test/cmdlineTests/storage_layout_struct_packed/output.json index 7731bd2230d3..f91a9a0cd3d6 100644 --- a/test/cmdlineTests/storage_layout_struct_packed/output.json +++ b/test/cmdlineTests/storage_layout_struct_packed/output.json @@ -1,14 +1,9 @@ { - "contracts": - { - "fileA": - { - "A": - { - "storageLayout": - { - "storage": - [ + "contracts": { + "fileA": { + "A": { + "storageLayout": { + "storage": [ { "astId": 15, "contract": "fileA:A", @@ -42,34 +37,28 @@ "type": "t_address" } ], - "types": - { - "t_address": - { + "types": { + "t_address": { "encoding": "inplace", "label": "address", "numberOfBytes": "20" }, - "t_array(t_uint256)2_storage": - { + "t_array(t_uint256)2_storage": { "base": "t_uint256", "encoding": "inplace", "label": "uint256[2]", "numberOfBytes": "64" }, - "t_array(t_uint256)dyn_storage": - { + "t_array(t_uint256)dyn_storage": { "base": "t_uint256", "encoding": "dynamic_array", "label": "uint256[]", "numberOfBytes": "32" }, - "t_struct(S)13_storage": - { + "t_struct(S)13_storage": { "encoding": "inplace", "label": "struct A.S", - "members": - [ + "members": [ { "astId": 3, "contract": "fileA:A", @@ -105,14 +94,12 @@ ], "numberOfBytes": "128" }, - "t_uint128": - { + "t_uint128": { "encoding": "inplace", "label": "uint128", "numberOfBytes": "16" }, - "t_uint256": - { + "t_uint256": { "encoding": "inplace", "label": "uint256", "numberOfBytes": "32" @@ -122,10 +109,8 @@ } } }, - "sources": - { - "fileA": - { + "sources": { + "fileA": { "id": 0 } } diff --git a/test/cmdlineTests/storage_layout_user_defined/output b/test/cmdlineTests/storage_layout_user_defined/output index f79b8413e664..bb7819c66f12 100644 --- a/test/cmdlineTests/storage_layout_user_defined/output +++ b/test/cmdlineTests/storage_layout_user_defined/output @@ -2,8 +2,7 @@ ======= storage_layout_user_defined/input.sol:C ======= Contract Storage Layout: { - "storage": - [ + "storage": [ { "astId": 7, "contract": "storage_layout_user_defined/input.sol:C", @@ -69,16 +68,13 @@ Contract Storage Layout: "type": "t_userDefinedValueType(MyInt8)4" } ], - "types": - { - "t_userDefinedValueType(MyInt128)2": - { + "types": { + "t_userDefinedValueType(MyInt128)2": { "encoding": "inplace", "label": "MyInt128", "numberOfBytes": "16" }, - "t_userDefinedValueType(MyInt8)4": - { + "t_userDefinedValueType(MyInt8)4": { "encoding": "inplace", "label": "MyInt8", "numberOfBytes": "1" diff --git a/test/cmdlineTests/storage_layout_value_types/output.json b/test/cmdlineTests/storage_layout_value_types/output.json index 10fbd762b5d2..b737adc973c3 100644 --- a/test/cmdlineTests/storage_layout_value_types/output.json +++ b/test/cmdlineTests/storage_layout_value_types/output.json @@ -1,14 +1,9 @@ { - "contracts": - { - "fileA": - { - "A": - { - "storageLayout": - { - "storage": - [ + "contracts": { + "fileA": { + "A": { + "storageLayout": { + "storage": [ { "astId": 3, "contract": "fileA:A", @@ -42,23 +37,19 @@ "type": "t_array(t_uint256)2_storage" } ], - "types": - { - "t_address": - { + "types": { + "t_address": { "encoding": "inplace", "label": "address", "numberOfBytes": "20" }, - "t_array(t_uint256)2_storage": - { + "t_array(t_uint256)2_storage": { "base": "t_uint256", "encoding": "inplace", "label": "uint256[2]", "numberOfBytes": "64" }, - "t_uint256": - { + "t_uint256": { "encoding": "inplace", "label": "uint256", "numberOfBytes": "32" @@ -68,10 +59,8 @@ } } }, - "sources": - { - "fileA": - { + "sources": { + "fileA": { "id": 0 } } diff --git a/test/cmdlineTests/storage_layout_value_types_packed/output.json b/test/cmdlineTests/storage_layout_value_types_packed/output.json index eefb69e667e4..cea9bc81c633 100644 --- a/test/cmdlineTests/storage_layout_value_types_packed/output.json +++ b/test/cmdlineTests/storage_layout_value_types_packed/output.json @@ -1,14 +1,9 @@ { - "contracts": - { - "fileA": - { - "A": - { - "storageLayout": - { - "storage": - [ + "contracts": { + "fileA": { + "A": { + "storageLayout": { + "storage": [ { "astId": 3, "contract": "fileA:A", @@ -50,35 +45,29 @@ "type": "t_array(t_uint256)2_storage" } ], - "types": - { - "t_address": - { + "types": { + "t_address": { "encoding": "inplace", "label": "address", "numberOfBytes": "20" }, - "t_array(t_uint256)2_storage": - { + "t_array(t_uint256)2_storage": { "base": "t_uint256", "encoding": "inplace", "label": "uint256[2]", "numberOfBytes": "64" }, - "t_uint128": - { + "t_uint128": { "encoding": "inplace", "label": "uint128", "numberOfBytes": "16" }, - "t_uint256": - { + "t_uint256": { "encoding": "inplace", "label": "uint256", "numberOfBytes": "32" }, - "t_uint64": - { + "t_uint64": { "encoding": "inplace", "label": "uint64", "numberOfBytes": "8" @@ -88,10 +77,8 @@ } } }, - "sources": - { - "fileA": - { + "sources": { + "fileA": { "id": 0 } } diff --git a/test/cmdlineTests/strict_asm_ast_compact_json/output b/test/cmdlineTests/strict_asm_ast_compact_json/output index 98afddcfa9d7..b4c6dc142467 100644 --- a/test/cmdlineTests/strict_asm_ast_compact_json/output +++ b/test/cmdlineTests/strict_asm_ast_compact_json/output @@ -3,26 +3,20 @@ AST: { - "code": - { - "block": - { + "code": { + "block": { "nativeSrc": "60:246:0", "nodeType": "YulBlock", "src": "-1:-1:0", - "statements": - [ + "statements": [ { "nativeSrc": "60:246:0", "nodeType": "YulBlock", "src": "-1:-1:0", - "statements": - [ + "statements": [ { - "expression": - { - "arguments": - [ + "expression": { + "arguments": [ { "kind": "number", "nativeSrc": "122:2:0", @@ -40,8 +34,7 @@ AST: "value": "128" } ], - "functionName": - { + "functionName": { "name": "mstore", "nativeSrc": "115:6:0", "nodeType": "YulIdentifier", diff --git a/test/cmdlineTests/yul_string_format_ascii/output.json b/test/cmdlineTests/yul_string_format_ascii/output.json index edb76c0cd405..6847228b53a5 100644 --- a/test/cmdlineTests/yul_string_format_ascii/output.json +++ b/test/cmdlineTests/yul_string_format_ascii/output.json @@ -1,10 +1,7 @@ { - "contracts": - { - "A": - { - "C": - { + "contracts": { + "A": { + "C": { "ir": " /// @use-src 0:\"A\" object \"C_11\" { @@ -217,10 +214,8 @@ object \"C_11\" { } } }, - "sources": - { - "A": - { + "sources": { + "A": { "id": 0 } } diff --git a/test/cmdlineTests/yul_string_format_ascii_bytes32/output.json b/test/cmdlineTests/yul_string_format_ascii_bytes32/output.json index bfe775ca40c5..2e077e8594a4 100644 --- a/test/cmdlineTests/yul_string_format_ascii_bytes32/output.json +++ b/test/cmdlineTests/yul_string_format_ascii_bytes32/output.json @@ -1,10 +1,7 @@ { - "contracts": - { - "A": - { - "C": - { + "contracts": { + "A": { + "C": { "ir": " /// @use-src 0:\"A\" object \"C_11\" { @@ -147,10 +144,8 @@ object \"C_11\" { } } }, - "sources": - { - "A": - { + "sources": { + "A": { "id": 0 } } 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 f4b14aadcfc5..d2044189a848 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 @@ -1,10 +1,7 @@ { - "contracts": - { - "A": - { - "C": - { + "contracts": { + "A": { + "C": { "ir": " /// @use-src 0:\"A\" object \"C_11\" { @@ -160,10 +157,8 @@ object \"C_11\" { } } }, - "sources": - { - "A": - { + "sources": { + "A": { "id": 0 } } diff --git a/test/cmdlineTests/yul_string_format_ascii_long/output.json b/test/cmdlineTests/yul_string_format_ascii_long/output.json index 36d6cfd954e9..20644f3a3b73 100644 --- a/test/cmdlineTests/yul_string_format_ascii_long/output.json +++ b/test/cmdlineTests/yul_string_format_ascii_long/output.json @@ -1,10 +1,7 @@ { - "contracts": - { - "A": - { - "C": - { + "contracts": { + "A": { + "C": { "ir": " /// @use-src 0:\"A\" object \"C_11\" { @@ -221,10 +218,8 @@ object \"C_11\" { } } }, - "sources": - { - "A": - { + "sources": { + "A": { "id": 0 } } diff --git a/test/cmdlineTests/yul_string_format_hex/output.json b/test/cmdlineTests/yul_string_format_hex/output.json index 5568fc7a0d1e..a120fa4c9b7c 100644 --- a/test/cmdlineTests/yul_string_format_hex/output.json +++ b/test/cmdlineTests/yul_string_format_hex/output.json @@ -1,10 +1,7 @@ { - "contracts": - { - "A": - { - "C": - { + "contracts": { + "A": { + "C": { "ir": " /// @use-src 0:\"A\" object \"C_11\" { @@ -160,10 +157,8 @@ object \"C_11\" { } } }, - "sources": - { - "A": - { + "sources": { + "A": { "id": 0 } } diff --git a/test/libsolidity/ABIJson/basic_test.sol b/test/libsolidity/ABIJson/basic_test.sol index 37c833bcfa29..8f60eb728208 100644 --- a/test/libsolidity/ABIJson/basic_test.sol +++ b/test/libsolidity/ABIJson/basic_test.sol @@ -5,8 +5,7 @@ contract test { // :test // [ // { -// "inputs": -// [ +// "inputs": [ // { // "internalType": "uint256", // "name": "a", @@ -14,8 +13,7 @@ contract test { // } // ], // "name": "f", -// "outputs": -// [ +// "outputs": [ // { // "internalType": "uint256", // "name": "d", diff --git a/test/libsolidity/ABIJson/constructor_abi.sol b/test/libsolidity/ABIJson/constructor_abi.sol index ae07c9401138..406927f0ae8c 100644 --- a/test/libsolidity/ABIJson/constructor_abi.sol +++ b/test/libsolidity/ABIJson/constructor_abi.sol @@ -5,8 +5,7 @@ contract test { // :test // [ // { -// "inputs": -// [ +// "inputs": [ // { // "internalType": "uint256", // "name": "param1", diff --git a/test/libsolidity/ABIJson/empty_name_input_parameter_with_named_one.sol b/test/libsolidity/ABIJson/empty_name_input_parameter_with_named_one.sol index d412e755acff..c3ba37b0e7f7 100644 --- a/test/libsolidity/ABIJson/empty_name_input_parameter_with_named_one.sol +++ b/test/libsolidity/ABIJson/empty_name_input_parameter_with_named_one.sol @@ -9,8 +9,7 @@ contract test { // :test // [ // { -// "inputs": -// [ +// "inputs": [ // { // "internalType": "uint256", // "name": "", @@ -23,8 +22,7 @@ contract test { // } // ], // "name": "f", -// "outputs": -// [ +// "outputs": [ // { // "internalType": "uint256", // "name": "ret_k", diff --git a/test/libsolidity/ABIJson/empty_name_return_parameters.sol b/test/libsolidity/ABIJson/empty_name_return_parameters.sol index 1415276fdce9..56c4de8a2442 100644 --- a/test/libsolidity/ABIJson/empty_name_return_parameters.sol +++ b/test/libsolidity/ABIJson/empty_name_return_parameters.sol @@ -7,8 +7,7 @@ contract test { // :test // [ // { -// "inputs": -// [ +// "inputs": [ // { // "internalType": "uint256", // "name": "k", @@ -16,8 +15,7 @@ contract test { // } // ], // "name": "f", -// "outputs": -// [ +// "outputs": [ // { // "internalType": "uint256", // "name": "", diff --git a/test/libsolidity/ABIJson/errors.sol b/test/libsolidity/ABIJson/errors.sol index 91c76ce6f44b..86b16dd85133 100644 --- a/test/libsolidity/ABIJson/errors.sol +++ b/test/libsolidity/ABIJson/errors.sol @@ -13,8 +13,7 @@ contract X { // :X // [ // { -// "inputs": -// [ +// "inputs": [ // { // "internalType": "uint256", // "name": "", @@ -25,8 +24,7 @@ contract X { // "type": "error" // }, // { -// "inputs": -// [ +// "inputs": [ // { // "internalType": "uint256", // "name": "a", @@ -42,8 +40,7 @@ contract X { // "type": "error" // }, // { -// "inputs": -// [ +// "inputs": [ // { // "internalType": "uint256", // "name": "a", @@ -59,11 +56,9 @@ contract X { // "type": "error" // }, // { -// "inputs": -// [ +// "inputs": [ // { -// "components": -// [ +// "components": [ // { // "internalType": "uint256", // "name": "x", diff --git a/test/libsolidity/ABIJson/errors_referenced.sol b/test/libsolidity/ABIJson/errors_referenced.sol index ecb5b1003e2a..a624bda105c3 100644 --- a/test/libsolidity/ABIJson/errors_referenced.sol +++ b/test/libsolidity/ABIJson/errors_referenced.sol @@ -34,8 +34,7 @@ contract X is C { // :D // [ // { -// "inputs": -// [ +// "inputs": [ // { // "internalType": "uint256", // "name": "", @@ -61,8 +60,7 @@ contract X is C { // "type": "error" // }, // { -// "inputs": -// [ +// "inputs": [ // { // "internalType": "uint256", // "name": "", @@ -78,8 +76,7 @@ contract X is C { // "type": "error" // }, // { -// "inputs": -// [ +// "inputs": [ // { // "internalType": "uint256", // "name": "x", diff --git a/test/libsolidity/ABIJson/event_emited_in_base_contract.sol b/test/libsolidity/ABIJson/event_emited_in_base_contract.sol index f9c3d2019cbe..043b92d5552e 100644 --- a/test/libsolidity/ABIJson/event_emited_in_base_contract.sol +++ b/test/libsolidity/ABIJson/event_emited_in_base_contract.sol @@ -18,8 +18,7 @@ contract C is B {} // }, // { // "anonymous": false, -// "inputs": -// [ +// "inputs": [ // { // "indexed": false, // "internalType": "uint8", @@ -37,8 +36,7 @@ contract C is B {} // [ // { // "anonymous": false, -// "inputs": -// [ +// "inputs": [ // { // "indexed": false, // "internalType": "uint8", @@ -56,8 +54,7 @@ contract C is B {} // [ // { // "anonymous": false, -// "inputs": -// [ +// "inputs": [ // { // "indexed": false, // "internalType": "uint8", diff --git a/test/libsolidity/ABIJson/event_emitted_from_foreign_contract.sol b/test/libsolidity/ABIJson/event_emitted_from_foreign_contract.sol index 30c115669752..1603519c0cd7 100644 --- a/test/libsolidity/ABIJson/event_emitted_from_foreign_contract.sol +++ b/test/libsolidity/ABIJson/event_emitted_from_foreign_contract.sol @@ -17,8 +17,7 @@ contract D { // [ // { // "anonymous": false, -// "inputs": -// [ +// "inputs": [ // { // "indexed": true, // "internalType": "address", @@ -36,8 +35,7 @@ contract D { // [ // { // "anonymous": false, -// "inputs": -// [ +// "inputs": [ // { // "indexed": false, // "internalType": "uint256", @@ -50,8 +48,7 @@ contract D { // }, // { // "anonymous": false, -// "inputs": -// [ +// "inputs": [ // { // "indexed": true, // "internalType": "address", @@ -64,8 +61,7 @@ contract D { // }, // { // "anonymous": false, -// "inputs": -// [ +// "inputs": [ // { // "indexed": true, // "internalType": "address", @@ -77,8 +73,7 @@ contract D { // "type": "event" // }, // { -// "inputs": -// [ +// "inputs": [ // { // "internalType": "address", // "name": "sender", @@ -97,8 +92,7 @@ contract D { // [ // { // "anonymous": false, -// "inputs": -// [ +// "inputs": [ // { // "indexed": false, // "internalType": "uint256", diff --git a/test/libsolidity/ABIJson/event_file_level.sol b/test/libsolidity/ABIJson/event_file_level.sol index 5b5c39a82c68..65e260d6666b 100644 --- a/test/libsolidity/ABIJson/event_file_level.sol +++ b/test/libsolidity/ABIJson/event_file_level.sol @@ -32,8 +32,7 @@ contract D is C { // }, // { // "anonymous": false, -// "inputs": -// [ +// "inputs": [ // { // "indexed": false, // "internalType": "uint256", @@ -64,8 +63,7 @@ contract D is C { // }, // { // "anonymous": false, -// "inputs": -// [ +// "inputs": [ // { // "indexed": false, // "internalType": "uint256", @@ -78,8 +76,7 @@ contract D is C { // }, // { // "anonymous": false, -// "inputs": -// [ +// "inputs": [ // { // "indexed": false, // "internalType": "string", diff --git a/test/libsolidity/ABIJson/event_structs.sol b/test/libsolidity/ABIJson/event_structs.sol index 83431907a7dd..6c1ec3b17499 100644 --- a/test/libsolidity/ABIJson/event_structs.sol +++ b/test/libsolidity/ABIJson/event_structs.sol @@ -9,11 +9,9 @@ contract C { // [ // { // "anonymous": false, -// "inputs": -// [ +// "inputs": [ // { -// "components": -// [ +// "components": [ // { // "internalType": "uint256[2]", // "name": "x", @@ -26,16 +24,14 @@ contract C { // "type": "tuple" // }, // { -// "components": -// [ +// "components": [ // { // "internalType": "uint256", // "name": "a", // "type": "uint256" // }, // { -// "components": -// [ +// "components": [ // { // "internalType": "uint256[2]", // "name": "x", diff --git a/test/libsolidity/ABIJson/events.sol b/test/libsolidity/ABIJson/events.sol index bab6a743652e..8c8cfc4a239d 100644 --- a/test/libsolidity/ABIJson/events.sol +++ b/test/libsolidity/ABIJson/events.sol @@ -10,8 +10,7 @@ contract test { // [ // { // "anonymous": false, -// "inputs": -// [ +// "inputs": [ // { // "indexed": false, // "internalType": "uint256", @@ -36,8 +35,7 @@ contract test { // }, // { // "anonymous": false, -// "inputs": -// [ +// "inputs": [ // { // "indexed": false, // "internalType": "uint256", @@ -55,8 +53,7 @@ contract test { // "type": "event" // }, // { -// "inputs": -// [ +// "inputs": [ // { // "internalType": "uint256", // "name": "a", @@ -64,8 +61,7 @@ contract test { // } // ], // "name": "f", -// "outputs": -// [ +// "outputs": [ // { // "internalType": "uint256", // "name": "d", diff --git a/test/libsolidity/ABIJson/events_indirect.sol b/test/libsolidity/ABIJson/events_indirect.sol index 86368028ccc2..0d11f79ecf72 100644 --- a/test/libsolidity/ABIJson/events_indirect.sol +++ b/test/libsolidity/ABIJson/events_indirect.sol @@ -15,8 +15,7 @@ contract test { // [ // { // "anonymous": false, -// "inputs": -// [ +// "inputs": [ // { // "indexed": false, // "internalType": "uint256", @@ -35,8 +34,7 @@ contract test { // }, // { // "anonymous": false, -// "inputs": -// [ +// "inputs": [ // { // "indexed": false, // "internalType": "uint256", @@ -60,8 +58,7 @@ contract test { // [ // { // "anonymous": false, -// "inputs": -// [ +// "inputs": [ // { // "indexed": false, // "internalType": "uint256", diff --git a/test/libsolidity/ABIJson/function_type.sol b/test/libsolidity/ABIJson/function_type.sol index 51e36b92b5da..ab20bbb14e56 100644 --- a/test/libsolidity/ABIJson/function_type.sol +++ b/test/libsolidity/ABIJson/function_type.sol @@ -5,8 +5,7 @@ contract test { // :test // [ // { -// "inputs": -// [ +// "inputs": [ // { // "internalType": "function (uint256) external returns (uint256)", // "name": "x", diff --git a/test/libsolidity/ABIJson/function_type_extended.sol b/test/libsolidity/ABIJson/function_type_extended.sol index 6257bb4c47ed..cac235d6cfcf 100644 --- a/test/libsolidity/ABIJson/function_type_extended.sol +++ b/test/libsolidity/ABIJson/function_type_extended.sol @@ -5,8 +5,7 @@ contract test { // :test // [ // { -// "inputs": -// [ +// "inputs": [ // { // "internalType": "function (contract test) external returns (contract test[])", // "name": "x", diff --git a/test/libsolidity/ABIJson/global_struct.sol b/test/libsolidity/ABIJson/global_struct.sol index 11ce8246feab..960cda232313 100644 --- a/test/libsolidity/ABIJson/global_struct.sol +++ b/test/libsolidity/ABIJson/global_struct.sol @@ -8,11 +8,9 @@ contract C { // :C // [ // { -// "inputs": -// [ +// "inputs": [ // { -// "components": -// [ +// "components": [ // { // "internalType": "uint256", // "name": "a", @@ -30,11 +28,9 @@ contract C { // "type": "function" // }, // { -// "inputs": -// [ +// "inputs": [ // { -// "components": -// [ +// "components": [ // { // "internalType": "uint256", // "name": "a", diff --git a/test/libsolidity/ABIJson/inherited.sol b/test/libsolidity/ABIJson/inherited.sol index cdd8296d8efc..681cc892b84f 100644 --- a/test/libsolidity/ABIJson/inherited.sol +++ b/test/libsolidity/ABIJson/inherited.sol @@ -11,8 +11,7 @@ contract Derived is Base { // [ // { // "anonymous": false, -// "inputs": -// [ +// "inputs": [ // { // "indexed": true, // "internalType": "bytes32", @@ -24,8 +23,7 @@ contract Derived is Base { // "type": "event" // }, // { -// "inputs": -// [ +// "inputs": [ // { // "internalType": "uint256", // "name": "p", @@ -33,8 +31,7 @@ contract Derived is Base { // } // ], // "name": "baseFunction", -// "outputs": -// [ +// "outputs": [ // { // "internalType": "uint256", // "name": "i", @@ -51,8 +48,7 @@ contract Derived is Base { // [ // { // "anonymous": false, -// "inputs": -// [ +// "inputs": [ // { // "indexed": true, // "internalType": "bytes32", @@ -65,8 +61,7 @@ contract Derived is Base { // }, // { // "anonymous": false, -// "inputs": -// [ +// "inputs": [ // { // "indexed": true, // "internalType": "uint256", @@ -78,8 +73,7 @@ contract Derived is Base { // "type": "event" // }, // { -// "inputs": -// [ +// "inputs": [ // { // "internalType": "uint256", // "name": "p", @@ -87,8 +81,7 @@ contract Derived is Base { // } // ], // "name": "baseFunction", -// "outputs": -// [ +// "outputs": [ // { // "internalType": "uint256", // "name": "i", @@ -99,8 +92,7 @@ contract Derived is Base { // "type": "function" // }, // { -// "inputs": -// [ +// "inputs": [ // { // "internalType": "bytes32", // "name": "p", @@ -108,8 +100,7 @@ contract Derived is Base { // } // ], // "name": "derivedFunction", -// "outputs": -// [ +// "outputs": [ // { // "internalType": "bytes32", // "name": "i", diff --git a/test/libsolidity/ABIJson/library_function.sol b/test/libsolidity/ABIJson/library_function.sol index 5fe404e95b39..2a27729fc914 100644 --- a/test/libsolidity/ABIJson/library_function.sol +++ b/test/libsolidity/ABIJson/library_function.sol @@ -12,8 +12,7 @@ library test { // :test // [ // { -// "inputs": -// [ +// "inputs": [ // { // "internalType": "uint256[]", // "name": "c", @@ -26,8 +25,7 @@ library test { // } // ], // "name": "f1", -// "outputs": -// [ +// "outputs": [ // { // "internalType": "uint256[]", // "name": "e", diff --git a/test/libsolidity/ABIJson/mapping.sol b/test/libsolidity/ABIJson/mapping.sol index e84b716f2a43..1c5e29fd870b 100644 --- a/test/libsolidity/ABIJson/mapping.sol +++ b/test/libsolidity/ABIJson/mapping.sol @@ -7,8 +7,7 @@ contract test { // :test // [ // { -// "inputs": -// [ +// "inputs": [ // { // "internalType": "address", // "name": "owner", @@ -21,8 +20,7 @@ contract test { // } // ], // "name": "allowance", -// "outputs": -// [ +// "outputs": [ // { // "internalType": "uint256", // "name": "value", @@ -33,8 +31,7 @@ contract test { // "type": "function" // }, // { -// "inputs": -// [ +// "inputs": [ // { // "internalType": "bytes32", // "name": "", @@ -42,8 +39,7 @@ contract test { // } // ], // "name": "commits", -// "outputs": -// [ +// "outputs": [ // { // "internalType": "address", // "name": "sender", @@ -54,8 +50,7 @@ contract test { // "type": "function" // }, // { -// "inputs": -// [ +// "inputs": [ // { // "internalType": "bytes32", // "name": "", @@ -63,8 +58,7 @@ contract test { // } // ], // "name": "something", -// "outputs": -// [ +// "outputs": [ // { // "internalType": "bytes32", // "name": "", diff --git a/test/libsolidity/ABIJson/multiple_methods.sol b/test/libsolidity/ABIJson/multiple_methods.sol index f4738e6ea16e..6ff81c4a6bb2 100644 --- a/test/libsolidity/ABIJson/multiple_methods.sol +++ b/test/libsolidity/ABIJson/multiple_methods.sol @@ -6,8 +6,7 @@ contract test { // :test // [ // { -// "inputs": -// [ +// "inputs": [ // { // "internalType": "uint256", // "name": "a", @@ -15,8 +14,7 @@ contract test { // } // ], // "name": "f", -// "outputs": -// [ +// "outputs": [ // { // "internalType": "uint256", // "name": "d", @@ -27,8 +25,7 @@ contract test { // "type": "function" // }, // { -// "inputs": -// [ +// "inputs": [ // { // "internalType": "uint256", // "name": "b", @@ -36,8 +33,7 @@ contract test { // } // ], // "name": "g", -// "outputs": -// [ +// "outputs": [ // { // "internalType": "uint256", // "name": "e", diff --git a/test/libsolidity/ABIJson/multiple_methods_order.sol b/test/libsolidity/ABIJson/multiple_methods_order.sol index 606c80db3ce6..fdc9b6d64362 100644 --- a/test/libsolidity/ABIJson/multiple_methods_order.sol +++ b/test/libsolidity/ABIJson/multiple_methods_order.sol @@ -7,8 +7,7 @@ contract test { // :test // [ // { -// "inputs": -// [ +// "inputs": [ // { // "internalType": "uint256", // "name": "b", @@ -16,8 +15,7 @@ contract test { // } // ], // "name": "c", -// "outputs": -// [ +// "outputs": [ // { // "internalType": "uint256", // "name": "e", @@ -28,8 +26,7 @@ contract test { // "type": "function" // }, // { -// "inputs": -// [ +// "inputs": [ // { // "internalType": "uint256", // "name": "a", @@ -37,8 +34,7 @@ contract test { // } // ], // "name": "f", -// "outputs": -// [ +// "outputs": [ // { // "internalType": "uint256", // "name": "d", diff --git a/test/libsolidity/ABIJson/multiple_params.sol b/test/libsolidity/ABIJson/multiple_params.sol index e223fc3eb590..9657905c9848 100644 --- a/test/libsolidity/ABIJson/multiple_params.sol +++ b/test/libsolidity/ABIJson/multiple_params.sol @@ -5,8 +5,7 @@ contract test { // :test // [ // { -// "inputs": -// [ +// "inputs": [ // { // "internalType": "uint256", // "name": "a", @@ -19,8 +18,7 @@ contract test { // } // ], // "name": "f", -// "outputs": -// [ +// "outputs": [ // { // "internalType": "uint256", // "name": "d", diff --git a/test/libsolidity/ABIJson/payable_constructor_abi.sol b/test/libsolidity/ABIJson/payable_constructor_abi.sol index 579e83efb10f..aa74e2a3f3ed 100644 --- a/test/libsolidity/ABIJson/payable_constructor_abi.sol +++ b/test/libsolidity/ABIJson/payable_constructor_abi.sol @@ -5,8 +5,7 @@ contract test { // :test // [ // { -// "inputs": -// [ +// "inputs": [ // { // "internalType": "uint256", // "name": "param1", diff --git a/test/libsolidity/ABIJson/pure_function.sol b/test/libsolidity/ABIJson/pure_function.sol index c98431eb2a4e..38c51ebf5277 100644 --- a/test/libsolidity/ABIJson/pure_function.sol +++ b/test/libsolidity/ABIJson/pure_function.sol @@ -6,8 +6,7 @@ contract test { // :test // [ // { -// "inputs": -// [ +// "inputs": [ // { // "internalType": "uint32", // "name": "a", @@ -15,8 +14,7 @@ contract test { // } // ], // "name": "boo", -// "outputs": -// [ +// "outputs": [ // { // "internalType": "uint256", // "name": "b", @@ -27,8 +25,7 @@ contract test { // "type": "function" // }, // { -// "inputs": -// [ +// "inputs": [ // { // "internalType": "uint256", // "name": "a", @@ -41,8 +38,7 @@ contract test { // } // ], // "name": "foo", -// "outputs": -// [ +// "outputs": [ // { // "internalType": "uint256", // "name": "d", diff --git a/test/libsolidity/ABIJson/return_param_in_abi.sol b/test/libsolidity/ABIJson/return_param_in_abi.sol index 23995d62a323..754c474a0a47 100644 --- a/test/libsolidity/ABIJson/return_param_in_abi.sol +++ b/test/libsolidity/ABIJson/return_param_in_abi.sol @@ -11,8 +11,7 @@ contract test { // :test // [ // { -// "inputs": -// [ +// "inputs": [ // { // "internalType": "enum test.ActionChoices", // "name": "param", @@ -25,8 +24,7 @@ contract test { // { // "inputs": [], // "name": "ret", -// "outputs": -// [ +// "outputs": [ // { // "internalType": "enum test.ActionChoices", // "name": "", diff --git a/test/libsolidity/ABIJson/return_structs.sol b/test/libsolidity/ABIJson/return_structs.sol index 9a1e493d5087..a0bcb84b4c31 100644 --- a/test/libsolidity/ABIJson/return_structs.sol +++ b/test/libsolidity/ABIJson/return_structs.sol @@ -11,24 +11,21 @@ contract C { // { // "inputs": [], // "name": "f", -// "outputs": -// [ +// "outputs": [ // { // "internalType": "uint256", // "name": "x", // "type": "uint256" // }, // { -// "components": -// [ +// "components": [ // { // "internalType": "uint256", // "name": "a", // "type": "uint256" // }, // { -// "components": -// [ +// "components": [ // { // "internalType": "uint256[2]", // "name": "x", diff --git a/test/libsolidity/ABIJson/return_structs_with_contracts.sol b/test/libsolidity/ABIJson/return_structs_with_contracts.sol index 135c3295f766..9c8e81d148f7 100644 --- a/test/libsolidity/ABIJson/return_structs_with_contracts.sol +++ b/test/libsolidity/ABIJson/return_structs_with_contracts.sol @@ -10,11 +10,9 @@ contract C { // { // "inputs": [], // "name": "f", -// "outputs": -// [ +// "outputs": [ // { -// "components": -// [ +// "components": [ // { // "internalType": "contract C[]", // "name": "x", diff --git a/test/libsolidity/ABIJson/structs_and_arrays.sol b/test/libsolidity/ABIJson/structs_and_arrays.sol index b2c6bc0ad971..a4f1bc4d6b19 100644 --- a/test/libsolidity/ABIJson/structs_and_arrays.sol +++ b/test/libsolidity/ABIJson/structs_and_arrays.sol @@ -6,8 +6,7 @@ contract test { // :test // [ // { -// "inputs": -// [ +// "inputs": [ // { // "internalType": "string", // "name": "a", diff --git a/test/libsolidity/ABIJson/structs_in_libraries.sol b/test/libsolidity/ABIJson/structs_in_libraries.sol index 3f278337f0bc..edc76327a7af 100644 --- a/test/libsolidity/ABIJson/structs_in_libraries.sol +++ b/test/libsolidity/ABIJson/structs_in_libraries.sol @@ -9,19 +9,16 @@ library L { // :L // [ // { -// "inputs": -// [ +// "inputs": [ // { -// "components": -// [ +// "components": [ // { // "internalType": "uint256", // "name": "a", // "type": "uint256" // }, // { -// "components": -// [ +// "components": [ // { // "internalType": "uint256[2]", // "name": "x", diff --git a/test/libsolidity/ABIJson/user_defined_value_type.sol b/test/libsolidity/ABIJson/user_defined_value_type.sol index 3bd034e6a9b0..d20ff9903c30 100644 --- a/test/libsolidity/ABIJson/user_defined_value_type.sol +++ b/test/libsolidity/ABIJson/user_defined_value_type.sol @@ -33,8 +33,7 @@ contract C { // { // "inputs": [], // "name": "myAddress", -// "outputs": -// [ +// "outputs": [ // { // "internalType": "C.MyAddress", // "name": "", @@ -47,8 +46,7 @@ contract C { // { // "inputs": [], // "name": "myByte1", -// "outputs": -// [ +// "outputs": [ // { // "internalType": "MyByte1", // "name": "", @@ -61,8 +59,7 @@ contract C { // { // "inputs": [], // "name": "myBytes32", -// "outputs": -// [ +// "outputs": [ // { // "internalType": "C.MyBytes32", // "name": "", @@ -75,8 +72,7 @@ contract C { // { // "inputs": [], // "name": "myInt", -// "outputs": -// [ +// "outputs": [ // { // "internalType": "MyInt", // "name": "", @@ -89,8 +85,7 @@ contract C { // { // "inputs": [], // "name": "myUInt8", -// "outputs": -// [ +// "outputs": [ // { // "internalType": "C.MyUInt8", // "name": "", @@ -101,8 +96,7 @@ contract C { // "type": "function" // }, // { -// "inputs": -// [ +// "inputs": [ // { // "internalType": "C.MyAddress", // "name": "a", @@ -115,8 +109,7 @@ contract C { // "type": "function" // }, // { -// "inputs": -// [ +// "inputs": [ // { // "internalType": "MyByte1", // "name": "a", @@ -129,8 +122,7 @@ contract C { // "type": "function" // }, // { -// "inputs": -// [ +// "inputs": [ // { // "internalType": "C.MyBytes32", // "name": "a", @@ -143,8 +135,7 @@ contract C { // "type": "function" // }, // { -// "inputs": -// [ +// "inputs": [ // { // "internalType": "MyInt", // "name": "a", @@ -157,8 +148,7 @@ contract C { // "type": "function" // }, // { -// "inputs": -// [ +// "inputs": [ // { // "internalType": "C.MyUInt8", // "name": "a", diff --git a/test/libsolidity/ABIJson/view_function.sol b/test/libsolidity/ABIJson/view_function.sol index d5f54ecdeefe..88f03d6365aa 100644 --- a/test/libsolidity/ABIJson/view_function.sol +++ b/test/libsolidity/ABIJson/view_function.sol @@ -6,8 +6,7 @@ contract test { // :test // [ // { -// "inputs": -// [ +// "inputs": [ // { // "internalType": "uint32", // "name": "a", @@ -15,8 +14,7 @@ contract test { // } // ], // "name": "boo", -// "outputs": -// [ +// "outputs": [ // { // "internalType": "uint256", // "name": "b", @@ -27,8 +25,7 @@ contract test { // "type": "function" // }, // { -// "inputs": -// [ +// "inputs": [ // { // "internalType": "uint256", // "name": "a", @@ -41,8 +38,7 @@ contract test { // } // ], // "name": "foo", -// "outputs": -// [ +// "outputs": [ // { // "internalType": "uint256", // "name": "d", diff --git a/test/libsolidity/ASTJSON/abstract_contract.json b/test/libsolidity/ASTJSON/abstract_contract.json index 48c20b43584d..fb82b35b29a5 100644 --- a/test/libsolidity/ASTJSON/abstract_contract.json +++ b/test/libsolidity/ASTJSON/abstract_contract.json @@ -1,16 +1,13 @@ { "absolutePath": "a", - "exportedSymbols": - { - "C": - [ + "exportedSymbols": { + "C": [ 5 ] }, "id": 6, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "abstract": true, "baseContracts": [], @@ -19,18 +16,15 @@ "contractKind": "contract", "fullyImplemented": true, "id": 5, - "linearizedBaseContracts": - [ + "linearizedBaseContracts": [ 5 ], "name": "C", "nameLocation": "18:1:1", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { - "body": - { + "body": { "id": 3, "nodeType": "Block", "src": "37:4:1", @@ -43,15 +37,13 @@ "name": "", "nameLocation": "-1:-1:-1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 1, "nodeType": "ParameterList", "parameters": [], "src": "34:2:1" }, - "returnParameters": - { + "returnParameters": { "id": 2, "nodeType": "ParameterList", "parameters": [], diff --git a/test/libsolidity/ASTJSON/abstract_contract.sol b/test/libsolidity/ASTJSON/abstract_contract.sol index 3ef96612f5fb..bddbc177931a 100644 --- a/test/libsolidity/ASTJSON/abstract_contract.sol +++ b/test/libsolidity/ASTJSON/abstract_contract.sol @@ -2,4 +2,5 @@ abstract contract C { constructor() { } } + // ---- diff --git a/test/libsolidity/ASTJSON/abstract_contract_parseOnly.json b/test/libsolidity/ASTJSON/abstract_contract_parseOnly.json index d9ba04e6cfd0..fedcbd99e8da 100644 --- a/test/libsolidity/ASTJSON/abstract_contract_parseOnly.json +++ b/test/libsolidity/ASTJSON/abstract_contract_parseOnly.json @@ -2,8 +2,7 @@ "absolutePath": "a", "id": 6, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "abstract": true, "baseContracts": [], @@ -13,11 +12,9 @@ "name": "C", "nameLocation": "18:1:1", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { - "body": - { + "body": { "id": 3, "nodeType": "Block", "src": "37:4:1", @@ -30,15 +27,13 @@ "name": "", "nameLocation": "-1:-1:-1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 1, "nodeType": "ParameterList", "parameters": [], "src": "34:2:1" }, - "returnParameters": - { + "returnParameters": { "id": 2, "nodeType": "ParameterList", "parameters": [], diff --git a/test/libsolidity/ASTJSON/address_payable.json b/test/libsolidity/ASTJSON/address_payable.json index adf79823ec30..3e8c7955a281 100644 --- a/test/libsolidity/ASTJSON/address_payable.json +++ b/test/libsolidity/ASTJSON/address_payable.json @@ -1,16 +1,13 @@ { "absolutePath": "a", - "exportedSymbols": - { - "C": - [ + "exportedSymbols": { + "C": [ 39 ] }, "id": 40, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "abstract": false, "baseContracts": [], @@ -19,15 +16,13 @@ "contractKind": "contract", "fullyImplemented": true, "id": 39, - "linearizedBaseContracts": - [ + "linearizedBaseContracts": [ 39 ], "name": "C", "nameLocation": "9:1:1", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { "constant": false, "functionSelector": "97682884", @@ -40,46 +35,39 @@ "src": "17:44:1", "stateVariable": true, "storageLocation": "default", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_mapping$_t_address_$_t_address_payable_$", "typeString": "mapping(address => address payable)" }, - "typeName": - { + "typeName": { "id": 3, "keyName": "", "keyNameLocation": "-1:-1:-1", - "keyType": - { + "keyType": { "id": 1, "name": "address", "nodeType": "ElementaryTypeName", "src": "25:7:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_address", "typeString": "address" } }, "nodeType": "Mapping", "src": "17:35:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_mapping$_t_address_$_t_address_payable_$", "typeString": "mapping(address => address payable)" }, "valueName": "", "valueNameLocation": "-1:-1:-1", - "valueType": - { + "valueType": { "id": 2, "name": "address", "nodeType": "ElementaryTypeName", "src": "36:15:1", "stateMutability": "payable", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_address_payable", "typeString": "address payable" } @@ -88,20 +76,16 @@ "visibility": "public" }, { - "body": - { + "body": { "id": 37, "nodeType": "Block", "src": "134:122:1", - "statements": - [ + "statements": [ { - "assignments": - [ + "assignments": [ 12 ], - "declarations": - [ + "declarations": [ { "constant": false, "id": 12, @@ -113,20 +97,17 @@ "src": "144:17:1", "stateVariable": false, "storageLocation": "default", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_address_payable", "typeString": "address payable" }, - "typeName": - { + "typeName": { "id": 11, "name": "address", "nodeType": "ElementaryTypeName", "src": "144:15:1", "stateMutability": "payable", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_address_payable", "typeString": "address payable" } @@ -135,33 +116,28 @@ } ], "id": 16, - "initialValue": - { - "baseExpression": - { + "initialValue": { + "baseExpression": { "id": 13, "name": "m", "nodeType": "Identifier", "overloadedDeclarations": [], "referencedDeclaration": 4, "src": "164:1:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_mapping$_t_address_$_t_address_payable_$", "typeString": "mapping(address => address payable)" } }, "id": 15, - "indexExpression": - { + "indexExpression": { "id": 14, "name": "arg", "nodeType": "Identifier", "overloadedDeclarations": [], "referencedDeclaration": 6, "src": "166:3:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_address_payable", "typeString": "address payable" } @@ -172,8 +148,7 @@ "lValueRequested": false, "nodeType": "IndexAccess", "src": "164:6:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_address_payable", "typeString": "address payable" } @@ -182,46 +157,40 @@ "src": "144:26:1" }, { - "expression": - { + "expression": { "id": 19, "isConstant": false, "isLValue": false, "isPure": false, "lValueRequested": false, - "leftHandSide": - { + "leftHandSide": { "id": 17, "name": "r", "nodeType": "Identifier", "overloadedDeclarations": [], "referencedDeclaration": 9, "src": "180:1:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_address_payable", "typeString": "address payable" } }, "nodeType": "Assignment", "operator": "=", - "rightHandSide": - { + "rightHandSide": { "id": 18, "name": "arg", "nodeType": "Identifier", "overloadedDeclarations": [], "referencedDeclaration": 6, "src": "184:3:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_address_payable", "typeString": "address payable" } }, "src": "180:7:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_address_payable", "typeString": "address payable" } @@ -231,12 +200,10 @@ "src": "180:7:1" }, { - "assignments": - [ + "assignments": [ 22 ], - "declarations": - [ + "declarations": [ { "constant": false, "id": 22, @@ -248,20 +215,17 @@ "src": "197:9:1", "stateVariable": false, "storageLocation": "default", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_address", "typeString": "address" }, - "typeName": - { + "typeName": { "id": 21, "name": "address", "nodeType": "ElementaryTypeName", "src": "197:7:1", "stateMutability": "nonpayable", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_address", "typeString": "address" } @@ -270,10 +234,8 @@ } ], "id": 27, - "initialValue": - { - "arguments": - [ + "initialValue": { + "arguments": [ { "id": 25, "name": "this", @@ -281,17 +243,14 @@ "overloadedDeclarations": [], "referencedDeclaration": -28, "src": "217:4:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_contract$_C_$39", "typeString": "contract C" } } ], - "expression": - { - "argumentTypes": - [ + "expression": { + "argumentTypes": [ { "typeIdentifier": "t_contract$_C_$39", "typeString": "contract C" @@ -304,13 +263,11 @@ "lValueRequested": false, "nodeType": "ElementaryTypeNameExpression", "src": "209:7:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_type$_t_address_$", "typeString": "type(address)" }, - "typeName": - { + "typeName": { "id": 23, "name": "address", "nodeType": "ElementaryTypeName", @@ -329,8 +286,7 @@ "nodeType": "FunctionCall", "src": "209:13:1", "tryCall": false, - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_address", "typeString": "address" } @@ -339,40 +295,34 @@ "src": "197:25:1" }, { - "expression": - { + "expression": { "id": 35, "isConstant": false, "isLValue": false, "isPure": false, "lValueRequested": false, - "leftHandSide": - { - "baseExpression": - { + "leftHandSide": { + "baseExpression": { "id": 28, "name": "m", "nodeType": "Identifier", "overloadedDeclarations": [], "referencedDeclaration": 4, "src": "232:1:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_mapping$_t_address_$_t_address_payable_$", "typeString": "mapping(address => address payable)" } }, "id": 30, - "indexExpression": - { + "indexExpression": { "id": 29, "name": "c", "nodeType": "Identifier", "overloadedDeclarations": [], "referencedDeclaration": 22, "src": "234:1:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_address", "typeString": "address" } @@ -383,18 +333,15 @@ "lValueRequested": true, "nodeType": "IndexAccess", "src": "232:4:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_address_payable", "typeString": "address payable" } }, "nodeType": "Assignment", "operator": "=", - "rightHandSide": - { - "arguments": - [ + "rightHandSide": { + "arguments": [ { "hexValue": "30", "id": 33, @@ -405,18 +352,15 @@ "lValueRequested": false, "nodeType": "Literal", "src": "247:1:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_rational_0_by_1", "typeString": "int_const 0" }, "value": "0" } ], - "expression": - { - "argumentTypes": - [ + "expression": { + "argumentTypes": [ { "typeIdentifier": "t_rational_0_by_1", "typeString": "int_const 0" @@ -429,13 +373,11 @@ "lValueRequested": false, "nodeType": "ElementaryTypeNameExpression", "src": "239:8:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_type$_t_address_payable_$", "typeString": "type(address payable)" }, - "typeName": - { + "typeName": { "id": 31, "name": "address", "nodeType": "ElementaryTypeName", @@ -455,15 +397,13 @@ "nodeType": "FunctionCall", "src": "239:10:1", "tryCall": false, - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_address_payable", "typeString": "address payable" } }, "src": "232:17:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_address_payable", "typeString": "address payable" } @@ -482,12 +422,10 @@ "name": "f", "nameLocation": "76:1:1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 7, "nodeType": "ParameterList", - "parameters": - [ + "parameters": [ { "constant": false, "id": 6, @@ -499,20 +437,17 @@ "src": "78:19:1", "stateVariable": false, "storageLocation": "default", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_address_payable", "typeString": "address payable" }, - "typeName": - { + "typeName": { "id": 5, "name": "address", "nodeType": "ElementaryTypeName", "src": "78:15:1", "stateMutability": "payable", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_address_payable", "typeString": "address payable" } @@ -522,12 +457,10 @@ ], "src": "77:21:1" }, - "returnParameters": - { + "returnParameters": { "id": 10, "nodeType": "ParameterList", - "parameters": - [ + "parameters": [ { "constant": false, "id": 9, @@ -539,20 +472,17 @@ "src": "115:17:1", "stateVariable": false, "storageLocation": "default", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_address_payable", "typeString": "address payable" }, - "typeName": - { + "typeName": { "id": 8, "name": "address", "nodeType": "ElementaryTypeName", "src": "115:15:1", "stateMutability": "payable", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_address_payable", "typeString": "address payable" } diff --git a/test/libsolidity/ASTJSON/address_payable.sol b/test/libsolidity/ASTJSON/address_payable.sol index f9ebb124ebaf..28c9c8a20da4 100644 --- a/test/libsolidity/ASTJSON/address_payable.sol +++ b/test/libsolidity/ASTJSON/address_payable.sol @@ -7,4 +7,5 @@ contract C { m[c] = payable(0); } } + // ---- diff --git a/test/libsolidity/ASTJSON/address_payable_parseOnly.json b/test/libsolidity/ASTJSON/address_payable_parseOnly.json index 02b809cc96da..84e60f1cdd80 100644 --- a/test/libsolidity/ASTJSON/address_payable_parseOnly.json +++ b/test/libsolidity/ASTJSON/address_payable_parseOnly.json @@ -2,8 +2,7 @@ "absolutePath": "a", "id": 40, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "abstract": false, "baseContracts": [], @@ -13,8 +12,7 @@ "name": "C", "nameLocation": "9:1:1", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { "constant": false, "id": 4, @@ -26,13 +24,11 @@ "stateVariable": false, "storageLocation": "default", "typeDescriptions": {}, - "typeName": - { + "typeName": { "id": 3, "keyName": "", "keyNameLocation": "-1:-1:-1", - "keyType": - { + "keyType": { "id": 1, "name": "address", "nodeType": "ElementaryTypeName", @@ -44,8 +40,7 @@ "typeDescriptions": {}, "valueName": "", "valueNameLocation": "-1:-1:-1", - "valueType": - { + "valueType": { "id": 2, "name": "address", "nodeType": "ElementaryTypeName", @@ -57,20 +52,16 @@ "visibility": "public" }, { - "body": - { + "body": { "id": 37, "nodeType": "Block", "src": "134:122:1", - "statements": - [ + "statements": [ { - "assignments": - [ + "assignments": [ 12 ], - "declarations": - [ + "declarations": [ { "constant": false, "id": 12, @@ -82,8 +73,7 @@ "stateVariable": false, "storageLocation": "default", "typeDescriptions": {}, - "typeName": - { + "typeName": { "id": 11, "name": "address", "nodeType": "ElementaryTypeName", @@ -95,10 +85,8 @@ } ], "id": 16, - "initialValue": - { - "baseExpression": - { + "initialValue": { + "baseExpression": { "id": 13, "name": "m", "nodeType": "Identifier", @@ -107,8 +95,7 @@ "typeDescriptions": {} }, "id": 15, - "indexExpression": - { + "indexExpression": { "id": 14, "name": "arg", "nodeType": "Identifier", @@ -124,11 +111,9 @@ "src": "144:26:1" }, { - "expression": - { + "expression": { "id": 19, - "leftHandSide": - { + "leftHandSide": { "id": 17, "name": "r", "nodeType": "Identifier", @@ -138,8 +123,7 @@ }, "nodeType": "Assignment", "operator": "=", - "rightHandSide": - { + "rightHandSide": { "id": 18, "name": "arg", "nodeType": "Identifier", @@ -155,12 +139,10 @@ "src": "180:7:1" }, { - "assignments": - [ + "assignments": [ 22 ], - "declarations": - [ + "declarations": [ { "constant": false, "id": 22, @@ -172,8 +154,7 @@ "stateVariable": false, "storageLocation": "default", "typeDescriptions": {}, - "typeName": - { + "typeName": { "id": 21, "name": "address", "nodeType": "ElementaryTypeName", @@ -185,10 +166,8 @@ } ], "id": 27, - "initialValue": - { - "arguments": - [ + "initialValue": { + "arguments": [ { "id": 25, "name": "this", @@ -198,14 +177,12 @@ "typeDescriptions": {} } ], - "expression": - { + "expression": { "id": 24, "nodeType": "ElementaryTypeNameExpression", "src": "209:7:1", "typeDescriptions": {}, - "typeName": - { + "typeName": { "id": 23, "name": "address", "nodeType": "ElementaryTypeName", @@ -225,13 +202,10 @@ "src": "197:25:1" }, { - "expression": - { + "expression": { "id": 35, - "leftHandSide": - { - "baseExpression": - { + "leftHandSide": { + "baseExpression": { "id": 28, "name": "m", "nodeType": "Identifier", @@ -240,8 +214,7 @@ "typeDescriptions": {} }, "id": 30, - "indexExpression": - { + "indexExpression": { "id": 29, "name": "c", "nodeType": "Identifier", @@ -255,10 +228,8 @@ }, "nodeType": "Assignment", "operator": "=", - "rightHandSide": - { - "arguments": - [ + "rightHandSide": { + "arguments": [ { "hexValue": "30", "id": 33, @@ -269,14 +240,12 @@ "value": "0" } ], - "expression": - { + "expression": { "id": 32, "nodeType": "ElementaryTypeNameExpression", "src": "239:8:1", "typeDescriptions": {}, - "typeName": - { + "typeName": { "id": 31, "name": "address", "nodeType": "ElementaryTypeName", @@ -309,12 +278,10 @@ "name": "f", "nameLocation": "76:1:1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 7, "nodeType": "ParameterList", - "parameters": - [ + "parameters": [ { "constant": false, "id": 6, @@ -326,8 +293,7 @@ "stateVariable": false, "storageLocation": "default", "typeDescriptions": {}, - "typeName": - { + "typeName": { "id": 5, "name": "address", "nodeType": "ElementaryTypeName", @@ -340,12 +306,10 @@ ], "src": "77:21:1" }, - "returnParameters": - { + "returnParameters": { "id": 10, "nodeType": "ParameterList", - "parameters": - [ + "parameters": [ { "constant": false, "id": 9, @@ -357,8 +321,7 @@ "stateVariable": false, "storageLocation": "default", "typeDescriptions": {}, - "typeName": - { + "typeName": { "id": 8, "name": "address", "nodeType": "ElementaryTypeName", diff --git a/test/libsolidity/ASTJSON/array_type_name.json b/test/libsolidity/ASTJSON/array_type_name.json index 1cd97e1765a3..e87f505f01e8 100644 --- a/test/libsolidity/ASTJSON/array_type_name.json +++ b/test/libsolidity/ASTJSON/array_type_name.json @@ -1,16 +1,13 @@ { "absolutePath": "a", - "exportedSymbols": - { - "C": - [ + "exportedSymbols": { + "C": [ 4 ] }, "id": 5, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "abstract": false, "baseContracts": [], @@ -19,15 +16,13 @@ "contractKind": "contract", "fullyImplemented": true, "id": 4, - "linearizedBaseContracts": - [ + "linearizedBaseContracts": [ 4 ], "name": "C", "nameLocation": "9:1:1", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { "constant": false, "id": 3, @@ -39,21 +34,17 @@ "src": "13:8:1", "stateVariable": true, "storageLocation": "default", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_array$_t_uint256_$dyn_storage", "typeString": "uint256[]" }, - "typeName": - { - "baseType": - { + "typeName": { + "baseType": { "id": 1, "name": "uint", "nodeType": "ElementaryTypeName", "src": "13:4:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_uint256", "typeString": "uint256" } @@ -61,8 +52,7 @@ "id": 2, "nodeType": "ArrayTypeName", "src": "13:6:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_array$_t_uint256_$dyn_storage_ptr", "typeString": "uint256[]" } diff --git a/test/libsolidity/ASTJSON/array_type_name_parseOnly.json b/test/libsolidity/ASTJSON/array_type_name_parseOnly.json index 1e0b72ca07f2..6c61e8d7d0bd 100644 --- a/test/libsolidity/ASTJSON/array_type_name_parseOnly.json +++ b/test/libsolidity/ASTJSON/array_type_name_parseOnly.json @@ -2,8 +2,7 @@ "absolutePath": "a", "id": 5, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "abstract": false, "baseContracts": [], @@ -13,8 +12,7 @@ "name": "C", "nameLocation": "9:1:1", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { "constant": false, "id": 3, @@ -26,10 +24,8 @@ "stateVariable": false, "storageLocation": "default", "typeDescriptions": {}, - "typeName": - { - "baseType": - { + "typeName": { + "baseType": { "id": 1, "name": "uint", "nodeType": "ElementaryTypeName", diff --git a/test/libsolidity/ASTJSON/assembly/call.json b/test/libsolidity/ASTJSON/assembly/call.json index d92cf05fe8e4..6d5ffe9b6ff7 100644 --- a/test/libsolidity/ASTJSON/assembly/call.json +++ b/test/libsolidity/ASTJSON/assembly/call.json @@ -1,16 +1,13 @@ { "absolutePath": "a", - "exportedSymbols": - { - "C": - [ + "exportedSymbols": { + "C": [ 6 ] }, "id": 7, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "abstract": false, "baseContracts": [], @@ -19,39 +16,30 @@ "contractKind": "contract", "fullyImplemented": true, "id": 6, - "linearizedBaseContracts": - [ + "linearizedBaseContracts": [ 6 ], "name": "C", "nameLocation": "9:1:1", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { - "body": - { + "body": { "id": 4, "nodeType": "Block", "src": "37:59:1", - "statements": - [ + "statements": [ { - "AST": - { + "AST": { "nativeSrc": "56:34:1", "nodeType": "YulBlock", "src": "56:34:1", - "statements": - [ + "statements": [ { - "expression": - { - "arguments": - [ + "expression": { + "arguments": [ { - "arguments": - [ + "arguments": [ { "kind": "number", "nativeSrc": "67:1:1", @@ -109,8 +97,7 @@ "value": "6" } ], - "functionName": - { + "functionName": { "name": "call", "nativeSrc": "62:4:1", "nodeType": "YulIdentifier", @@ -121,8 +108,7 @@ "src": "62:25:1" } ], - "functionName": - { + "functionName": { "name": "pop", "nativeSrc": "58:3:1", "nodeType": "YulIdentifier", @@ -154,15 +140,13 @@ "name": "j", "nameLocation": "26:1:1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 1, "nodeType": "ParameterList", "parameters": [], "src": "27:2:1" }, - "returnParameters": - { + "returnParameters": { "id": 2, "nodeType": "ParameterList", "parameters": [], diff --git a/test/libsolidity/ASTJSON/assembly/call.sol b/test/libsolidity/ASTJSON/assembly/call.sol index 1735fd7f7e22..09d1ce184378 100644 --- a/test/libsolidity/ASTJSON/assembly/call.sol +++ b/test/libsolidity/ASTJSON/assembly/call.sol @@ -3,4 +3,5 @@ contract C { assembly { pop(call(0, 1, 2, 3, 4, 5, 6)) } } } + // ---- diff --git a/test/libsolidity/ASTJSON/assembly/call_parseOnly.json b/test/libsolidity/ASTJSON/assembly/call_parseOnly.json index 803a1e4f5f1e..1e7c5b1f8ea3 100644 --- a/test/libsolidity/ASTJSON/assembly/call_parseOnly.json +++ b/test/libsolidity/ASTJSON/assembly/call_parseOnly.json @@ -2,8 +2,7 @@ "absolutePath": "a", "id": 7, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "abstract": false, "baseContracts": [], @@ -13,32 +12,24 @@ "name": "C", "nameLocation": "9:1:1", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { - "body": - { + "body": { "id": 4, "nodeType": "Block", "src": "37:59:1", - "statements": - [ + "statements": [ { - "AST": - { + "AST": { "nativeSrc": "56:34:1", "nodeType": "YulBlock", "src": "56:34:1", - "statements": - [ + "statements": [ { - "expression": - { - "arguments": - [ + "expression": { + "arguments": [ { - "arguments": - [ + "arguments": [ { "kind": "number", "nativeSrc": "67:1:1", @@ -96,8 +87,7 @@ "value": "6" } ], - "functionName": - { + "functionName": { "name": "call", "nativeSrc": "62:4:1", "nodeType": "YulIdentifier", @@ -108,8 +98,7 @@ "src": "62:25:1" } ], - "functionName": - { + "functionName": { "name": "pop", "nativeSrc": "58:3:1", "nodeType": "YulIdentifier", @@ -140,15 +129,13 @@ "name": "j", "nameLocation": "26:1:1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 1, "nodeType": "ParameterList", "parameters": [], "src": "27:2:1" }, - "returnParameters": - { + "returnParameters": { "id": 2, "nodeType": "ParameterList", "parameters": [], diff --git a/test/libsolidity/ASTJSON/assembly/empty_block.json b/test/libsolidity/ASTJSON/assembly/empty_block.json index 3ec3c2eec018..1829d057d900 100644 --- a/test/libsolidity/ASTJSON/assembly/empty_block.json +++ b/test/libsolidity/ASTJSON/assembly/empty_block.json @@ -1,16 +1,13 @@ { "absolutePath": "a", - "exportedSymbols": - { - "C": - [ + "exportedSymbols": { + "C": [ 6 ] }, "id": 7, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "abstract": false, "baseContracts": [], @@ -19,31 +16,25 @@ "contractKind": "contract", "fullyImplemented": true, "id": 6, - "linearizedBaseContracts": - [ + "linearizedBaseContracts": [ 6 ], "name": "C", "nameLocation": "9:1:1", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { - "body": - { + "body": { "id": 4, "nodeType": "Block", "src": "42:31:1", - "statements": - [ + "statements": [ { - "AST": - { + "AST": { "nativeSrc": "61:6:1", "nodeType": "YulBlock", "src": "61:6:1", - "statements": - [ + "statements": [ { "nativeSrc": "63:2:1", "nodeType": "YulBlock", @@ -68,15 +59,13 @@ "name": "g", "nameLocation": "26:1:1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 1, "nodeType": "ParameterList", "parameters": [], "src": "27:2:1" }, - "returnParameters": - { + "returnParameters": { "id": 2, "nodeType": "ParameterList", "parameters": [], diff --git a/test/libsolidity/ASTJSON/assembly/empty_block.sol b/test/libsolidity/ASTJSON/assembly/empty_block.sol index 33bb796ea615..23c2babbe36d 100644 --- a/test/libsolidity/ASTJSON/assembly/empty_block.sol +++ b/test/libsolidity/ASTJSON/assembly/empty_block.sol @@ -3,4 +3,5 @@ contract C { assembly { {} } } } + // ---- diff --git a/test/libsolidity/ASTJSON/assembly/empty_block_parseOnly.json b/test/libsolidity/ASTJSON/assembly/empty_block_parseOnly.json index ee8e7b7330fb..92404c15f00d 100644 --- a/test/libsolidity/ASTJSON/assembly/empty_block_parseOnly.json +++ b/test/libsolidity/ASTJSON/assembly/empty_block_parseOnly.json @@ -2,8 +2,7 @@ "absolutePath": "a", "id": 7, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "abstract": false, "baseContracts": [], @@ -13,24 +12,19 @@ "name": "C", "nameLocation": "9:1:1", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { - "body": - { + "body": { "id": 4, "nodeType": "Block", "src": "42:31:1", - "statements": - [ + "statements": [ { - "AST": - { + "AST": { "nativeSrc": "61:6:1", "nodeType": "YulBlock", "src": "61:6:1", - "statements": - [ + "statements": [ { "nativeSrc": "63:2:1", "nodeType": "YulBlock", @@ -54,15 +48,13 @@ "name": "g", "nameLocation": "26:1:1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 1, "nodeType": "ParameterList", "parameters": [], "src": "27:2:1" }, - "returnParameters": - { + "returnParameters": { "id": 2, "nodeType": "ParameterList", "parameters": [], diff --git a/test/libsolidity/ASTJSON/assembly/empty_let_variable_declaration.json b/test/libsolidity/ASTJSON/assembly/empty_let_variable_declaration.json index 9d64279da848..b9435a41cecc 100644 --- a/test/libsolidity/ASTJSON/assembly/empty_let_variable_declaration.json +++ b/test/libsolidity/ASTJSON/assembly/empty_let_variable_declaration.json @@ -1,16 +1,13 @@ { "absolutePath": "a", - "exportedSymbols": - { - "C": - [ + "exportedSymbols": { + "C": [ 6 ] }, "id": 7, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "abstract": false, "baseContracts": [], @@ -19,37 +16,30 @@ "contractKind": "contract", "fullyImplemented": true, "id": 6, - "linearizedBaseContracts": - [ + "linearizedBaseContracts": [ 6 ], "name": "C", "nameLocation": "9:1:1", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { - "body": - { + "body": { "id": 4, "nodeType": "Block", "src": "39:30:1", - "statements": - [ + "statements": [ { - "AST": - { + "AST": { "nativeSrc": "52:14:1", "nodeType": "YulBlock", "src": "52:14:1", - "statements": - [ + "statements": [ { "nativeSrc": "57:5:1", "nodeType": "YulVariableDeclaration", "src": "57:5:1", - "variables": - [ + "variables": [ { "name": "x", "nativeSrc": "61:1:1", @@ -77,15 +67,13 @@ "name": "f", "nameLocation": "23:1:1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 1, "nodeType": "ParameterList", "parameters": [], "src": "24:2:1" }, - "returnParameters": - { + "returnParameters": { "id": 2, "nodeType": "ParameterList", "parameters": [], diff --git a/test/libsolidity/ASTJSON/assembly/empty_let_variable_declaration.sol b/test/libsolidity/ASTJSON/assembly/empty_let_variable_declaration.sol index 5b396dd44156..bfc5ff95fd42 100644 --- a/test/libsolidity/ASTJSON/assembly/empty_let_variable_declaration.sol +++ b/test/libsolidity/ASTJSON/assembly/empty_let_variable_declaration.sol @@ -5,4 +5,5 @@ contract C { } } } + // ---- diff --git a/test/libsolidity/ASTJSON/assembly/empty_let_variable_declaration_parseOnly.json b/test/libsolidity/ASTJSON/assembly/empty_let_variable_declaration_parseOnly.json index 5f12f280ba9b..bba11cc633f7 100644 --- a/test/libsolidity/ASTJSON/assembly/empty_let_variable_declaration_parseOnly.json +++ b/test/libsolidity/ASTJSON/assembly/empty_let_variable_declaration_parseOnly.json @@ -2,8 +2,7 @@ "absolutePath": "a", "id": 7, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "abstract": false, "baseContracts": [], @@ -13,30 +12,24 @@ "name": "C", "nameLocation": "9:1:1", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { - "body": - { + "body": { "id": 4, "nodeType": "Block", "src": "39:30:1", - "statements": - [ + "statements": [ { - "AST": - { + "AST": { "nativeSrc": "52:14:1", "nodeType": "YulBlock", "src": "52:14:1", - "statements": - [ + "statements": [ { "nativeSrc": "57:5:1", "nodeType": "YulVariableDeclaration", "src": "57:5:1", - "variables": - [ + "variables": [ { "name": "x", "nativeSrc": "61:1:1", @@ -63,15 +56,13 @@ "name": "f", "nameLocation": "23:1:1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 1, "nodeType": "ParameterList", "parameters": [], "src": "24:2:1" }, - "returnParameters": - { + "returnParameters": { "id": 2, "nodeType": "ParameterList", "parameters": [], diff --git a/test/libsolidity/ASTJSON/assembly/function.json b/test/libsolidity/ASTJSON/assembly/function.json index a3b908ac18b9..c409d615e926 100644 --- a/test/libsolidity/ASTJSON/assembly/function.json +++ b/test/libsolidity/ASTJSON/assembly/function.json @@ -1,16 +1,13 @@ { "absolutePath": "a", - "exportedSymbols": - { - "C": - [ + "exportedSymbols": { + "C": [ 6 ] }, "id": 7, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "abstract": false, "baseContracts": [], @@ -19,47 +16,36 @@ "contractKind": "contract", "fullyImplemented": true, "id": 6, - "linearizedBaseContracts": - [ + "linearizedBaseContracts": [ 6 ], "name": "C", "nameLocation": "9:1:1", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { - "body": - { + "body": { "id": 4, "nodeType": "Block", "src": "42:68:1", - "statements": - [ + "statements": [ { - "AST": - { + "AST": { "nativeSrc": "61:43:1", "nodeType": "YulBlock", "src": "61:43:1", - "statements": - [ + "statements": [ { - "body": - { + "body": { "nativeSrc": "76:22:1", "nodeType": "YulBlock", "src": "76:22:1", - "statements": - [ + "statements": [ { - "expression": - { - "arguments": - [ + "expression": { + "arguments": [ { - "arguments": - [ + "arguments": [ { "kind": "number", "nativeSrc": "92:2:1", @@ -69,8 +55,7 @@ "value": "20" } ], - "functionName": - { + "functionName": { "name": "blockhash", "nativeSrc": "82:9:1", "nodeType": "YulIdentifier", @@ -81,8 +66,7 @@ "src": "82:13:1" } ], - "functionName": - { + "functionName": { "name": "pop", "nativeSrc": "78:3:1", "nodeType": "YulIdentifier", @@ -104,11 +88,9 @@ "src": "63:35:1" }, { - "expression": - { + "expression": { "arguments": [], - "functionName": - { + "functionName": { "name": "g", "nativeSrc": "99:1:1", "nodeType": "YulIdentifier", @@ -140,15 +122,13 @@ "name": "h", "nameLocation": "26:1:1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 1, "nodeType": "ParameterList", "parameters": [], "src": "27:2:1" }, - "returnParameters": - { + "returnParameters": { "id": 2, "nodeType": "ParameterList", "parameters": [], diff --git a/test/libsolidity/ASTJSON/assembly/function.sol b/test/libsolidity/ASTJSON/assembly/function.sol index 1edf2f2de24d..6020f1f51318 100644 --- a/test/libsolidity/ASTJSON/assembly/function.sol +++ b/test/libsolidity/ASTJSON/assembly/function.sol @@ -3,4 +3,5 @@ contract C { assembly { function g() { pop(blockhash(20)) } g() } } } + // ---- diff --git a/test/libsolidity/ASTJSON/assembly/function_parseOnly.json b/test/libsolidity/ASTJSON/assembly/function_parseOnly.json index 04f5c2721b70..2e681ed63f9d 100644 --- a/test/libsolidity/ASTJSON/assembly/function_parseOnly.json +++ b/test/libsolidity/ASTJSON/assembly/function_parseOnly.json @@ -2,8 +2,7 @@ "absolutePath": "a", "id": 7, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "abstract": false, "baseContracts": [], @@ -13,40 +12,30 @@ "name": "C", "nameLocation": "9:1:1", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { - "body": - { + "body": { "id": 4, "nodeType": "Block", "src": "42:68:1", - "statements": - [ + "statements": [ { - "AST": - { + "AST": { "nativeSrc": "61:43:1", "nodeType": "YulBlock", "src": "61:43:1", - "statements": - [ + "statements": [ { - "body": - { + "body": { "nativeSrc": "76:22:1", "nodeType": "YulBlock", "src": "76:22:1", - "statements": - [ + "statements": [ { - "expression": - { - "arguments": - [ + "expression": { + "arguments": [ { - "arguments": - [ + "arguments": [ { "kind": "number", "nativeSrc": "92:2:1", @@ -56,8 +45,7 @@ "value": "20" } ], - "functionName": - { + "functionName": { "name": "blockhash", "nativeSrc": "82:9:1", "nodeType": "YulIdentifier", @@ -68,8 +56,7 @@ "src": "82:13:1" } ], - "functionName": - { + "functionName": { "name": "pop", "nativeSrc": "78:3:1", "nodeType": "YulIdentifier", @@ -91,11 +78,9 @@ "src": "63:35:1" }, { - "expression": - { + "expression": { "arguments": [], - "functionName": - { + "functionName": { "name": "g", "nativeSrc": "99:1:1", "nodeType": "YulIdentifier", @@ -126,15 +111,13 @@ "name": "h", "nameLocation": "26:1:1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 1, "nodeType": "ParameterList", "parameters": [], "src": "27:2:1" }, - "returnParameters": - { + "returnParameters": { "id": 2, "nodeType": "ParameterList", "parameters": [], diff --git a/test/libsolidity/ASTJSON/assembly/leave.json b/test/libsolidity/ASTJSON/assembly/leave.json index 51c94f542c76..e7fbf9f6f6e1 100644 --- a/test/libsolidity/ASTJSON/assembly/leave.json +++ b/test/libsolidity/ASTJSON/assembly/leave.json @@ -1,16 +1,13 @@ { "absolutePath": "a", - "exportedSymbols": - { - "C": - [ + "exportedSymbols": { + "C": [ 6 ] }, "id": 7, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "abstract": false, "baseContracts": [], @@ -19,39 +16,31 @@ "contractKind": "contract", "fullyImplemented": true, "id": 6, - "linearizedBaseContracts": - [ + "linearizedBaseContracts": [ 6 ], "name": "C", "nameLocation": "9:1:1", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { - "body": - { + "body": { "id": 4, "nodeType": "Block", "src": "37:51:1", - "statements": - [ + "statements": [ { - "AST": - { + "AST": { "nativeSrc": "56:26:1", "nodeType": "YulBlock", "src": "56:26:1", - "statements": - [ + "statements": [ { - "body": - { + "body": { "nativeSrc": "71:9:1", "nodeType": "YulBlock", "src": "71:9:1", - "statements": - [ + "statements": [ { "nativeSrc": "73:5:1", "nodeType": "YulLeave", @@ -82,15 +71,13 @@ "name": "l", "nameLocation": "26:1:1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 1, "nodeType": "ParameterList", "parameters": [], "src": "27:2:1" }, - "returnParameters": - { + "returnParameters": { "id": 2, "nodeType": "ParameterList", "parameters": [], diff --git a/test/libsolidity/ASTJSON/assembly/leave.sol b/test/libsolidity/ASTJSON/assembly/leave.sol index 39f1cafedb22..5ae4a9e0dd09 100644 --- a/test/libsolidity/ASTJSON/assembly/leave.sol +++ b/test/libsolidity/ASTJSON/assembly/leave.sol @@ -3,4 +3,5 @@ contract C { assembly { function f() { leave } } } } + // ---- diff --git a/test/libsolidity/ASTJSON/assembly/leave_parseOnly.json b/test/libsolidity/ASTJSON/assembly/leave_parseOnly.json index ee34743eac32..c71ffd3fed1f 100644 --- a/test/libsolidity/ASTJSON/assembly/leave_parseOnly.json +++ b/test/libsolidity/ASTJSON/assembly/leave_parseOnly.json @@ -2,8 +2,7 @@ "absolutePath": "a", "id": 7, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "abstract": false, "baseContracts": [], @@ -13,32 +12,25 @@ "name": "C", "nameLocation": "9:1:1", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { - "body": - { + "body": { "id": 4, "nodeType": "Block", "src": "37:51:1", - "statements": - [ + "statements": [ { - "AST": - { + "AST": { "nativeSrc": "56:26:1", "nodeType": "YulBlock", "src": "56:26:1", - "statements": - [ + "statements": [ { - "body": - { + "body": { "nativeSrc": "71:9:1", "nodeType": "YulBlock", "src": "71:9:1", - "statements": - [ + "statements": [ { "nativeSrc": "73:5:1", "nodeType": "YulLeave", @@ -68,15 +60,13 @@ "name": "l", "nameLocation": "26:1:1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 1, "nodeType": "ParameterList", "parameters": [], "src": "27:2:1" }, - "returnParameters": - { + "returnParameters": { "id": 2, "nodeType": "ParameterList", "parameters": [], diff --git a/test/libsolidity/ASTJSON/assembly/loop.json b/test/libsolidity/ASTJSON/assembly/loop.json index d3d20992d772..01efb79e6b2d 100644 --- a/test/libsolidity/ASTJSON/assembly/loop.json +++ b/test/libsolidity/ASTJSON/assembly/loop.json @@ -1,16 +1,13 @@ { "absolutePath": "a", - "exportedSymbols": - { - "C": - [ + "exportedSymbols": { + "C": [ 6 ] }, "id": 7, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "abstract": false, "baseContracts": [], @@ -19,39 +16,31 @@ "contractKind": "contract", "fullyImplemented": true, "id": 6, - "linearizedBaseContracts": - [ + "linearizedBaseContracts": [ 6 ], "name": "C", "nameLocation": "9:1:1", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { - "body": - { + "body": { "id": 4, "nodeType": "Block", "src": "42:74:1", - "statements": - [ + "statements": [ { - "AST": - { + "AST": { "nativeSrc": "61:49:1", "nodeType": "YulBlock", "src": "61:49:1", - "statements": - [ + "statements": [ { - "body": - { + "body": { "nativeSrc": "90:18:1", "nodeType": "YulBlock", "src": "90:18:1", - "statements": - [ + "statements": [ { "nativeSrc": "92:5:1", "nodeType": "YulBreak", @@ -64,8 +53,7 @@ } ] }, - "condition": - { + "condition": { "kind": "number", "nativeSrc": "70:1:1", "nodeType": "YulLiteral", @@ -75,21 +63,16 @@ }, "nativeSrc": "63:45:1", "nodeType": "YulForLoop", - "post": - { + "post": { "nativeSrc": "72:17:1", "nodeType": "YulBlock", "src": "72:17:1", - "statements": - [ + "statements": [ { - "expression": - { - "arguments": - [ + "expression": { + "arguments": [ { - "arguments": - [ + "arguments": [ { "kind": "number", "nativeSrc": "84:1:1", @@ -99,8 +82,7 @@ "value": "0" } ], - "functionName": - { + "functionName": { "name": "sload", "nativeSrc": "78:5:1", "nodeType": "YulIdentifier", @@ -111,8 +93,7 @@ "src": "78:8:1" } ], - "functionName": - { + "functionName": { "name": "pop", "nativeSrc": "74:3:1", "nodeType": "YulIdentifier", @@ -128,8 +109,7 @@ } ] }, - "pre": - { + "pre": { "nativeSrc": "67:2:1", "nodeType": "YulBlock", "src": "67:2:1", @@ -155,15 +135,13 @@ "name": "g", "nameLocation": "26:1:1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 1, "nodeType": "ParameterList", "parameters": [], "src": "27:2:1" }, - "returnParameters": - { + "returnParameters": { "id": 2, "nodeType": "ParameterList", "parameters": [], diff --git a/test/libsolidity/ASTJSON/assembly/loop.sol b/test/libsolidity/ASTJSON/assembly/loop.sol index baa45e62c489..bba8d282f63d 100644 --- a/test/libsolidity/ASTJSON/assembly/loop.sol +++ b/test/libsolidity/ASTJSON/assembly/loop.sol @@ -3,4 +3,5 @@ contract C { assembly { for {} 1 { pop(sload(0)) } { break continue } } } } + // ---- diff --git a/test/libsolidity/ASTJSON/assembly/loop_parseOnly.json b/test/libsolidity/ASTJSON/assembly/loop_parseOnly.json index 24dbbdc4eaf8..8fecb9dfd3e9 100644 --- a/test/libsolidity/ASTJSON/assembly/loop_parseOnly.json +++ b/test/libsolidity/ASTJSON/assembly/loop_parseOnly.json @@ -2,8 +2,7 @@ "absolutePath": "a", "id": 7, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "abstract": false, "baseContracts": [], @@ -13,32 +12,25 @@ "name": "C", "nameLocation": "9:1:1", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { - "body": - { + "body": { "id": 4, "nodeType": "Block", "src": "42:74:1", - "statements": - [ + "statements": [ { - "AST": - { + "AST": { "nativeSrc": "61:49:1", "nodeType": "YulBlock", "src": "61:49:1", - "statements": - [ + "statements": [ { - "body": - { + "body": { "nativeSrc": "90:18:1", "nodeType": "YulBlock", "src": "90:18:1", - "statements": - [ + "statements": [ { "nativeSrc": "92:5:1", "nodeType": "YulBreak", @@ -51,8 +43,7 @@ } ] }, - "condition": - { + "condition": { "kind": "number", "nativeSrc": "70:1:1", "nodeType": "YulLiteral", @@ -62,21 +53,16 @@ }, "nativeSrc": "63:45:1", "nodeType": "YulForLoop", - "post": - { + "post": { "nativeSrc": "72:17:1", "nodeType": "YulBlock", "src": "72:17:1", - "statements": - [ + "statements": [ { - "expression": - { - "arguments": - [ + "expression": { + "arguments": [ { - "arguments": - [ + "arguments": [ { "kind": "number", "nativeSrc": "84:1:1", @@ -86,8 +72,7 @@ "value": "0" } ], - "functionName": - { + "functionName": { "name": "sload", "nativeSrc": "78:5:1", "nodeType": "YulIdentifier", @@ -98,8 +83,7 @@ "src": "78:8:1" } ], - "functionName": - { + "functionName": { "name": "pop", "nativeSrc": "74:3:1", "nodeType": "YulIdentifier", @@ -115,8 +99,7 @@ } ] }, - "pre": - { + "pre": { "nativeSrc": "67:2:1", "nodeType": "YulBlock", "src": "67:2:1", @@ -141,15 +124,13 @@ "name": "g", "nameLocation": "26:1:1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 1, "nodeType": "ParameterList", "parameters": [], "src": "27:2:1" }, - "returnParameters": - { + "returnParameters": { "id": 2, "nodeType": "ParameterList", "parameters": [], diff --git a/test/libsolidity/ASTJSON/assembly/nested_functions.json b/test/libsolidity/ASTJSON/assembly/nested_functions.json index 3c9fd53ec03c..c4c2b0ae44ef 100644 --- a/test/libsolidity/ASTJSON/assembly/nested_functions.json +++ b/test/libsolidity/ASTJSON/assembly/nested_functions.json @@ -1,16 +1,13 @@ { "absolutePath": "a", - "exportedSymbols": - { - "C": - [ + "exportedSymbols": { + "C": [ 8 ] }, "id": 9, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "abstract": false, "baseContracts": [], @@ -19,42 +16,33 @@ "contractKind": "contract", "fullyImplemented": true, "id": 8, - "linearizedBaseContracts": - [ + "linearizedBaseContracts": [ 8 ], "name": "C", "nameLocation": "9:1:1", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { - "body": - { + "body": { "id": 6, "nodeType": "Block", "src": "57:95:1", - "statements": - [ + "statements": [ { - "AST": - { + "AST": { "nativeSrc": "72:76:1", "nodeType": "YulBlock", "src": "72:76:1", - "statements": - [ + "statements": [ { - "body": - { + "body": { "nativeSrc": "94:35:1", "nodeType": "YulBlock", "src": "94:35:1", - "statements": - [ + "statements": [ { - "body": - { + "body": { "nativeSrc": "118:3:1", "nodeType": "YulBlock", "src": "118:3:1", @@ -76,8 +64,7 @@ "nativeSrc": "136:6:1", "nodeType": "YulAssignment", "src": "136:6:1", - "value": - { + "value": { "kind": "number", "nativeSrc": "141:1:1", "nodeType": "YulLiteral", @@ -85,8 +72,7 @@ "type": "", "value": "2" }, - "variableNames": - [ + "variableNames": [ { "name": "x", "nativeSrc": "136:1:1", @@ -98,8 +84,7 @@ ] }, "evmVersion": %EVMVERSION%, - "externalReferences": - [ + "externalReferences": [ { "declaration": 3, "isOffset": false, @@ -122,19 +107,16 @@ "name": "f", "nameLocation": "24:1:1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 1, "nodeType": "ParameterList", "parameters": [], "src": "25:2:1" }, - "returnParameters": - { + "returnParameters": { "id": 4, "nodeType": "ParameterList", - "parameters": - [ + "parameters": [ { "constant": false, "id": 3, @@ -146,19 +128,16 @@ "src": "49:6:1", "stateVariable": false, "storageLocation": "default", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_uint256", "typeString": "uint256" }, - "typeName": - { + "typeName": { "id": 2, "name": "uint", "nodeType": "ElementaryTypeName", "src": "49:4:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_uint256", "typeString": "uint256" } diff --git a/test/libsolidity/ASTJSON/assembly/nested_functions.sol b/test/libsolidity/ASTJSON/assembly/nested_functions.sol index 42479fa94ad3..396efa0bf8a2 100644 --- a/test/libsolidity/ASTJSON/assembly/nested_functions.sol +++ b/test/libsolidity/ASTJSON/assembly/nested_functions.sol @@ -8,4 +8,5 @@ contract C { } } } + // ---- diff --git a/test/libsolidity/ASTJSON/assembly/nested_functions_parseOnly.json b/test/libsolidity/ASTJSON/assembly/nested_functions_parseOnly.json index b924b42cfd0e..acb05ca8695f 100644 --- a/test/libsolidity/ASTJSON/assembly/nested_functions_parseOnly.json +++ b/test/libsolidity/ASTJSON/assembly/nested_functions_parseOnly.json @@ -2,8 +2,7 @@ "absolutePath": "a", "id": 9, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "abstract": false, "baseContracts": [], @@ -13,35 +12,27 @@ "name": "C", "nameLocation": "9:1:1", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { - "body": - { + "body": { "id": 6, "nodeType": "Block", "src": "57:95:1", - "statements": - [ + "statements": [ { - "AST": - { + "AST": { "nativeSrc": "72:76:1", "nodeType": "YulBlock", "src": "72:76:1", - "statements": - [ + "statements": [ { - "body": - { + "body": { "nativeSrc": "94:35:1", "nodeType": "YulBlock", "src": "94:35:1", - "statements": - [ + "statements": [ { - "body": - { + "body": { "nativeSrc": "118:3:1", "nodeType": "YulBlock", "src": "118:3:1", @@ -63,8 +54,7 @@ "nativeSrc": "136:6:1", "nodeType": "YulAssignment", "src": "136:6:1", - "value": - { + "value": { "kind": "number", "nativeSrc": "141:1:1", "nodeType": "YulLiteral", @@ -72,8 +62,7 @@ "type": "", "value": "2" }, - "variableNames": - [ + "variableNames": [ { "name": "x", "nativeSrc": "136:1:1", @@ -99,19 +88,16 @@ "name": "f", "nameLocation": "24:1:1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 1, "nodeType": "ParameterList", "parameters": [], "src": "25:2:1" }, - "returnParameters": - { + "returnParameters": { "id": 4, "nodeType": "ParameterList", - "parameters": - [ + "parameters": [ { "constant": false, "id": 3, @@ -123,8 +109,7 @@ "stateVariable": false, "storageLocation": "default", "typeDescriptions": {}, - "typeName": - { + "typeName": { "id": 2, "name": "uint", "nodeType": "ElementaryTypeName", diff --git a/test/libsolidity/ASTJSON/assembly/slot_offset.json b/test/libsolidity/ASTJSON/assembly/slot_offset.json index 799239b3afc6..8599bf3a8978 100644 --- a/test/libsolidity/ASTJSON/assembly/slot_offset.json +++ b/test/libsolidity/ASTJSON/assembly/slot_offset.json @@ -1,16 +1,13 @@ { "absolutePath": "a", - "exportedSymbols": - { - "C": - [ + "exportedSymbols": { + "C": [ 12 ] }, "id": 13, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "abstract": false, "baseContracts": [], @@ -19,20 +16,17 @@ "contractKind": "contract", "fullyImplemented": true, "id": 12, - "linearizedBaseContracts": - [ + "linearizedBaseContracts": [ 12 ], "name": "C", "nameLocation": "9:1:1", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { "canonicalName": "C.S", "id": 3, - "members": - [ + "members": [ { "constant": false, "id": 2, @@ -44,19 +38,16 @@ "src": "28:6:1", "stateVariable": false, "storageLocation": "default", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_uint256", "typeString": "uint256" }, - "typeName": - { + "typeName": { "id": 1, "name": "uint", "nodeType": "ElementaryTypeName", "src": "28:4:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_uint256", "typeString": "uint256" } @@ -82,21 +73,17 @@ "src": "42:3:1", "stateVariable": true, "storageLocation": "default", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_struct$_S_$3_storage", "typeString": "struct C.S" }, - "typeName": - { + "typeName": { "id": 5, "nodeType": "UserDefinedTypeName", - "pathNode": - { + "pathNode": { "id": 4, "name": "S", - "nameLocations": - [ + "nameLocations": [ "42:1:1" ], "nodeType": "IdentifierPath", @@ -105,8 +92,7 @@ }, "referencedDeclaration": 3, "src": "42:1:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_struct$_S_$3_storage_ptr", "typeString": "struct C.S" } @@ -114,34 +100,28 @@ "visibility": "internal" }, { - "body": - { + "body": { "id": 10, "nodeType": "Block", "src": "76:70:1", - "statements": - [ + "statements": [ { - "AST": - { + "AST": { "nativeSrc": "95:45:1", "nodeType": "YulBlock", "src": "95:45:1", - "statements": - [ + "statements": [ { "nativeSrc": "97:17:1", "nodeType": "YulVariableDeclaration", "src": "97:17:1", - "value": - { + "value": { "name": "s.offset", "nativeSrc": "106:8:1", "nodeType": "YulIdentifier", "src": "106:8:1" }, - "variables": - [ + "variables": [ { "name": "x", "nativeSrc": "101:1:1", @@ -155,10 +135,8 @@ "nativeSrc": "115:23:1", "nodeType": "YulVariableDeclaration", "src": "115:23:1", - "value": - { - "arguments": - [ + "value": { + "arguments": [ { "name": "s.slot", "nativeSrc": "128:6:1", @@ -174,8 +152,7 @@ "value": "2" } ], - "functionName": - { + "functionName": { "name": "mul", "nativeSrc": "124:3:1", "nodeType": "YulIdentifier", @@ -185,8 +162,7 @@ "nodeType": "YulFunctionCall", "src": "124:14:1" }, - "variables": - [ + "variables": [ { "name": "y", "nativeSrc": "119:1:1", @@ -199,8 +175,7 @@ ] }, "evmVersion": %EVMVERSION%, - "externalReferences": - [ + "externalReferences": [ { "declaration": 6, "isOffset": true, @@ -232,15 +207,13 @@ "name": "e", "nameLocation": "60:1:1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 7, "nodeType": "ParameterList", "parameters": [], "src": "61:2:1" }, - "returnParameters": - { + "returnParameters": { "id": 8, "nodeType": "ParameterList", "parameters": [], diff --git a/test/libsolidity/ASTJSON/assembly/slot_offset.sol b/test/libsolidity/ASTJSON/assembly/slot_offset.sol index 0cc2b07c116b..d3c8f75542e2 100644 --- a/test/libsolidity/ASTJSON/assembly/slot_offset.sol +++ b/test/libsolidity/ASTJSON/assembly/slot_offset.sol @@ -5,4 +5,5 @@ contract C { assembly { let x := s.offset let y := mul(s.slot, 2) } } } + // ---- diff --git a/test/libsolidity/ASTJSON/assembly/slot_offset_parseOnly.json b/test/libsolidity/ASTJSON/assembly/slot_offset_parseOnly.json index ef8dc8b0adb8..5363931c4ae4 100644 --- a/test/libsolidity/ASTJSON/assembly/slot_offset_parseOnly.json +++ b/test/libsolidity/ASTJSON/assembly/slot_offset_parseOnly.json @@ -2,8 +2,7 @@ "absolutePath": "a", "id": 13, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "abstract": false, "baseContracts": [], @@ -13,12 +12,10 @@ "name": "C", "nameLocation": "9:1:1", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { "id": 3, - "members": - [ + "members": [ { "constant": false, "id": 2, @@ -30,8 +27,7 @@ "stateVariable": false, "storageLocation": "default", "typeDescriptions": {}, - "typeName": - { + "typeName": { "id": 1, "name": "uint", "nodeType": "ElementaryTypeName", @@ -58,16 +54,13 @@ "stateVariable": false, "storageLocation": "default", "typeDescriptions": {}, - "typeName": - { + "typeName": { "id": 5, "nodeType": "UserDefinedTypeName", - "pathNode": - { + "pathNode": { "id": 4, "name": "S", - "nameLocations": - [ + "nameLocations": [ "42:1:1" ], "nodeType": "IdentifierPath", @@ -79,34 +72,28 @@ "visibility": "internal" }, { - "body": - { + "body": { "id": 10, "nodeType": "Block", "src": "76:70:1", - "statements": - [ + "statements": [ { - "AST": - { + "AST": { "nativeSrc": "95:45:1", "nodeType": "YulBlock", "src": "95:45:1", - "statements": - [ + "statements": [ { "nativeSrc": "97:17:1", "nodeType": "YulVariableDeclaration", "src": "97:17:1", - "value": - { + "value": { "name": "s.offset", "nativeSrc": "106:8:1", "nodeType": "YulIdentifier", "src": "106:8:1" }, - "variables": - [ + "variables": [ { "name": "x", "nativeSrc": "101:1:1", @@ -120,10 +107,8 @@ "nativeSrc": "115:23:1", "nodeType": "YulVariableDeclaration", "src": "115:23:1", - "value": - { - "arguments": - [ + "value": { + "arguments": [ { "name": "s.slot", "nativeSrc": "128:6:1", @@ -139,8 +124,7 @@ "value": "2" } ], - "functionName": - { + "functionName": { "name": "mul", "nativeSrc": "124:3:1", "nodeType": "YulIdentifier", @@ -150,8 +134,7 @@ "nodeType": "YulFunctionCall", "src": "124:14:1" }, - "variables": - [ + "variables": [ { "name": "y", "nativeSrc": "119:1:1", @@ -178,15 +161,13 @@ "name": "e", "nameLocation": "60:1:1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 7, "nodeType": "ParameterList", "parameters": [], "src": "61:2:1" }, - "returnParameters": - { + "returnParameters": { "id": 8, "nodeType": "ParameterList", "parameters": [], diff --git a/test/libsolidity/ASTJSON/assembly/stringlit.json b/test/libsolidity/ASTJSON/assembly/stringlit.json index ab27a3d16ff6..2a27e55b2ccd 100644 --- a/test/libsolidity/ASTJSON/assembly/stringlit.json +++ b/test/libsolidity/ASTJSON/assembly/stringlit.json @@ -1,16 +1,13 @@ { "absolutePath": "a", - "exportedSymbols": - { - "C": - [ + "exportedSymbols": { + "C": [ 6 ] }, "id": 7, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "abstract": false, "baseContracts": [], @@ -19,37 +16,30 @@ "contractKind": "contract", "fullyImplemented": true, "id": 6, - "linearizedBaseContracts": - [ + "linearizedBaseContracts": [ 6 ], "name": "C", "nameLocation": "9:1:1", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { - "body": - { + "body": { "id": 4, "nodeType": "Block", "src": "37:43:1", - "statements": - [ + "statements": [ { - "AST": - { + "AST": { "nativeSrc": "56:18:1", "nodeType": "YulBlock", "src": "56:18:1", - "statements": - [ + "statements": [ { "nativeSrc": "58:14:1", "nodeType": "YulVariableDeclaration", "src": "58:14:1", - "value": - { + "value": { "hexValue": "616263", "kind": "string", "nativeSrc": "67:5:1", @@ -58,8 +48,7 @@ "type": "", "value": "abc" }, - "variables": - [ + "variables": [ { "name": "x", "nativeSrc": "62:1:1", @@ -87,15 +76,13 @@ "name": "m", "nameLocation": "26:1:1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 1, "nodeType": "ParameterList", "parameters": [], "src": "27:2:1" }, - "returnParameters": - { + "returnParameters": { "id": 2, "nodeType": "ParameterList", "parameters": [], diff --git a/test/libsolidity/ASTJSON/assembly/stringlit.sol b/test/libsolidity/ASTJSON/assembly/stringlit.sol index 6f5278ac17f1..e382095ad0be 100644 --- a/test/libsolidity/ASTJSON/assembly/stringlit.sol +++ b/test/libsolidity/ASTJSON/assembly/stringlit.sol @@ -3,4 +3,5 @@ contract C { assembly { let x := "abc" } } } + // ---- diff --git a/test/libsolidity/ASTJSON/assembly/stringlit_parseOnly.json b/test/libsolidity/ASTJSON/assembly/stringlit_parseOnly.json index 3cb2a907287d..3d021620e1cf 100644 --- a/test/libsolidity/ASTJSON/assembly/stringlit_parseOnly.json +++ b/test/libsolidity/ASTJSON/assembly/stringlit_parseOnly.json @@ -2,8 +2,7 @@ "absolutePath": "a", "id": 7, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "abstract": false, "baseContracts": [], @@ -13,30 +12,24 @@ "name": "C", "nameLocation": "9:1:1", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { - "body": - { + "body": { "id": 4, "nodeType": "Block", "src": "37:43:1", - "statements": - [ + "statements": [ { - "AST": - { + "AST": { "nativeSrc": "56:18:1", "nodeType": "YulBlock", "src": "56:18:1", - "statements": - [ + "statements": [ { "nativeSrc": "58:14:1", "nodeType": "YulVariableDeclaration", "src": "58:14:1", - "value": - { + "value": { "hexValue": "616263", "kind": "string", "nativeSrc": "67:5:1", @@ -45,8 +38,7 @@ "type": "", "value": "abc" }, - "variables": - [ + "variables": [ { "name": "x", "nativeSrc": "62:1:1", @@ -73,15 +65,13 @@ "name": "m", "nameLocation": "26:1:1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 1, "nodeType": "ParameterList", "parameters": [], "src": "27:2:1" }, - "returnParameters": - { + "returnParameters": { "id": 2, "nodeType": "ParameterList", "parameters": [], diff --git a/test/libsolidity/ASTJSON/assembly/switch.json b/test/libsolidity/ASTJSON/assembly/switch.json index 99c69e048bfb..1a418931bc88 100644 --- a/test/libsolidity/ASTJSON/assembly/switch.json +++ b/test/libsolidity/ASTJSON/assembly/switch.json @@ -1,16 +1,13 @@ { "absolutePath": "a", - "exportedSymbols": - { - "C": - [ + "exportedSymbols": { + "C": [ 6 ] }, "id": 7, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "abstract": false, "baseContracts": [], @@ -19,37 +16,30 @@ "contractKind": "contract", "fullyImplemented": true, "id": 6, - "linearizedBaseContracts": - [ + "linearizedBaseContracts": [ 6 ], "name": "C", "nameLocation": "9:1:1", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { - "body": - { + "body": { "id": 4, "nodeType": "Block", "src": "42:154:1", - "statements": - [ + "statements": [ { - "AST": - { + "AST": { "nativeSrc": "61:129:1", "nodeType": "YulBlock", "src": "61:129:1", - "statements": - [ + "statements": [ { "nativeSrc": "75:10:1", "nodeType": "YulVariableDeclaration", "src": "75:10:1", - "value": - { + "value": { "kind": "number", "nativeSrc": "84:1:1", "nodeType": "YulLiteral", @@ -57,8 +47,7 @@ "type": "", "value": "0" }, - "variables": - [ + "variables": [ { "name": "v", "nativeSrc": "79:1:1", @@ -69,22 +58,18 @@ ] }, { - "cases": - [ + "cases": [ { - "body": - { + "body": { "nativeSrc": "139:10:1", "nodeType": "YulBlock", "src": "139:10:1", - "statements": - [ + "statements": [ { "nativeSrc": "141:6:1", "nodeType": "YulAssignment", "src": "141:6:1", - "value": - { + "value": { "kind": "number", "nativeSrc": "146:1:1", "nodeType": "YulLiteral", @@ -92,8 +77,7 @@ "type": "", "value": "1" }, - "variableNames": - [ + "variableNames": [ { "name": "v", "nativeSrc": "141:1:1", @@ -107,8 +91,7 @@ "nativeSrc": "132:17:1", "nodeType": "YulCase", "src": "132:17:1", - "value": - { + "value": { "kind": "number", "nativeSrc": "137:1:1", "nodeType": "YulLiteral", @@ -118,19 +101,16 @@ } }, { - "body": - { + "body": { "nativeSrc": "170:10:1", "nodeType": "YulBlock", "src": "170:10:1", - "statements": - [ + "statements": [ { "nativeSrc": "172:6:1", "nodeType": "YulAssignment", "src": "172:6:1", - "value": - { + "value": { "kind": "number", "nativeSrc": "177:1:1", "nodeType": "YulLiteral", @@ -138,8 +118,7 @@ "type": "", "value": "2" }, - "variableNames": - [ + "variableNames": [ { "name": "v", "nativeSrc": "172:1:1", @@ -156,11 +135,9 @@ "value": "default" } ], - "expression": - { + "expression": { "arguments": [], - "functionName": - { + "functionName": { "name": "calldatasize", "nativeSrc": "105:12:1", "nodeType": "YulIdentifier", @@ -192,15 +169,13 @@ "name": "f", "nameLocation": "26:1:1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 1, "nodeType": "ParameterList", "parameters": [], "src": "27:2:1" }, - "returnParameters": - { + "returnParameters": { "id": 2, "nodeType": "ParameterList", "parameters": [], diff --git a/test/libsolidity/ASTJSON/assembly/switch.sol b/test/libsolidity/ASTJSON/assembly/switch.sol index a7a23d26aac3..c04d311b09e4 100644 --- a/test/libsolidity/ASTJSON/assembly/switch.sol +++ b/test/libsolidity/ASTJSON/assembly/switch.sol @@ -8,4 +8,5 @@ contract C { } } } + // ---- diff --git a/test/libsolidity/ASTJSON/assembly/switch_default.json b/test/libsolidity/ASTJSON/assembly/switch_default.json index 07f804f3cb74..9d016e261099 100644 --- a/test/libsolidity/ASTJSON/assembly/switch_default.json +++ b/test/libsolidity/ASTJSON/assembly/switch_default.json @@ -1,16 +1,13 @@ { "absolutePath": "a", - "exportedSymbols": - { - "C": - [ + "exportedSymbols": { + "C": [ 6 ] }, "id": 7, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "abstract": false, "baseContracts": [], @@ -19,37 +16,29 @@ "contractKind": "contract", "fullyImplemented": true, "id": 6, - "linearizedBaseContracts": - [ + "linearizedBaseContracts": [ 6 ], "name": "C", "nameLocation": "9:1:1", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { - "body": - { + "body": { "id": 4, "nodeType": "Block", "src": "42:58:1", - "statements": - [ + "statements": [ { - "AST": - { + "AST": { "nativeSrc": "61:33:1", "nodeType": "YulBlock", "src": "61:33:1", - "statements": - [ + "statements": [ { - "cases": - [ + "cases": [ { - "body": - { + "body": { "nativeSrc": "79:2:1", "nodeType": "YulBlock", "src": "79:2:1", @@ -58,8 +47,7 @@ "nativeSrc": "72:9:1", "nodeType": "YulCase", "src": "72:9:1", - "value": - { + "value": { "kind": "number", "nativeSrc": "77:1:1", "nodeType": "YulLiteral", @@ -69,8 +57,7 @@ } }, { - "body": - { + "body": { "nativeSrc": "90:2:1", "nodeType": "YulBlock", "src": "90:2:1", @@ -82,8 +69,7 @@ "value": "default" } ], - "expression": - { + "expression": { "kind": "number", "nativeSrc": "70:1:1", "nodeType": "YulLiteral", @@ -113,15 +99,13 @@ "name": "g", "nameLocation": "26:1:1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 1, "nodeType": "ParameterList", "parameters": [], "src": "27:2:1" }, - "returnParameters": - { + "returnParameters": { "id": 2, "nodeType": "ParameterList", "parameters": [], diff --git a/test/libsolidity/ASTJSON/assembly/switch_default.sol b/test/libsolidity/ASTJSON/assembly/switch_default.sol index 0760bb7dfdb7..1f61896fe275 100644 --- a/test/libsolidity/ASTJSON/assembly/switch_default.sol +++ b/test/libsolidity/ASTJSON/assembly/switch_default.sol @@ -3,4 +3,5 @@ contract C { assembly { switch 0 case 0 {} default {} } } } + // ---- diff --git a/test/libsolidity/ASTJSON/assembly/switch_default_parseOnly.json b/test/libsolidity/ASTJSON/assembly/switch_default_parseOnly.json index 2ec302770814..22523b478e5f 100644 --- a/test/libsolidity/ASTJSON/assembly/switch_default_parseOnly.json +++ b/test/libsolidity/ASTJSON/assembly/switch_default_parseOnly.json @@ -2,8 +2,7 @@ "absolutePath": "a", "id": 7, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "abstract": false, "baseContracts": [], @@ -13,30 +12,23 @@ "name": "C", "nameLocation": "9:1:1", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { - "body": - { + "body": { "id": 4, "nodeType": "Block", "src": "42:58:1", - "statements": - [ + "statements": [ { - "AST": - { + "AST": { "nativeSrc": "61:33:1", "nodeType": "YulBlock", "src": "61:33:1", - "statements": - [ + "statements": [ { - "cases": - [ + "cases": [ { - "body": - { + "body": { "nativeSrc": "79:2:1", "nodeType": "YulBlock", "src": "79:2:1", @@ -45,8 +37,7 @@ "nativeSrc": "72:9:1", "nodeType": "YulCase", "src": "72:9:1", - "value": - { + "value": { "kind": "number", "nativeSrc": "77:1:1", "nodeType": "YulLiteral", @@ -56,8 +47,7 @@ } }, { - "body": - { + "body": { "nativeSrc": "90:2:1", "nodeType": "YulBlock", "src": "90:2:1", @@ -69,8 +59,7 @@ "value": "default" } ], - "expression": - { + "expression": { "kind": "number", "nativeSrc": "70:1:1", "nodeType": "YulLiteral", @@ -99,15 +88,13 @@ "name": "g", "nameLocation": "26:1:1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 1, "nodeType": "ParameterList", "parameters": [], "src": "27:2:1" }, - "returnParameters": - { + "returnParameters": { "id": 2, "nodeType": "ParameterList", "parameters": [], diff --git a/test/libsolidity/ASTJSON/assembly/switch_parseOnly.json b/test/libsolidity/ASTJSON/assembly/switch_parseOnly.json index 2412ea48dd0c..dc16d43f916a 100644 --- a/test/libsolidity/ASTJSON/assembly/switch_parseOnly.json +++ b/test/libsolidity/ASTJSON/assembly/switch_parseOnly.json @@ -2,8 +2,7 @@ "absolutePath": "a", "id": 7, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "abstract": false, "baseContracts": [], @@ -13,30 +12,24 @@ "name": "C", "nameLocation": "9:1:1", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { - "body": - { + "body": { "id": 4, "nodeType": "Block", "src": "42:154:1", - "statements": - [ + "statements": [ { - "AST": - { + "AST": { "nativeSrc": "61:129:1", "nodeType": "YulBlock", "src": "61:129:1", - "statements": - [ + "statements": [ { "nativeSrc": "75:10:1", "nodeType": "YulVariableDeclaration", "src": "75:10:1", - "value": - { + "value": { "kind": "number", "nativeSrc": "84:1:1", "nodeType": "YulLiteral", @@ -44,8 +37,7 @@ "type": "", "value": "0" }, - "variables": - [ + "variables": [ { "name": "v", "nativeSrc": "79:1:1", @@ -56,22 +48,18 @@ ] }, { - "cases": - [ + "cases": [ { - "body": - { + "body": { "nativeSrc": "139:10:1", "nodeType": "YulBlock", "src": "139:10:1", - "statements": - [ + "statements": [ { "nativeSrc": "141:6:1", "nodeType": "YulAssignment", "src": "141:6:1", - "value": - { + "value": { "kind": "number", "nativeSrc": "146:1:1", "nodeType": "YulLiteral", @@ -79,8 +67,7 @@ "type": "", "value": "1" }, - "variableNames": - [ + "variableNames": [ { "name": "v", "nativeSrc": "141:1:1", @@ -94,8 +81,7 @@ "nativeSrc": "132:17:1", "nodeType": "YulCase", "src": "132:17:1", - "value": - { + "value": { "kind": "number", "nativeSrc": "137:1:1", "nodeType": "YulLiteral", @@ -105,19 +91,16 @@ } }, { - "body": - { + "body": { "nativeSrc": "170:10:1", "nodeType": "YulBlock", "src": "170:10:1", - "statements": - [ + "statements": [ { "nativeSrc": "172:6:1", "nodeType": "YulAssignment", "src": "172:6:1", - "value": - { + "value": { "kind": "number", "nativeSrc": "177:1:1", "nodeType": "YulLiteral", @@ -125,8 +108,7 @@ "type": "", "value": "2" }, - "variableNames": - [ + "variableNames": [ { "name": "v", "nativeSrc": "172:1:1", @@ -143,11 +125,9 @@ "value": "default" } ], - "expression": - { + "expression": { "arguments": [], - "functionName": - { + "functionName": { "name": "calldatasize", "nativeSrc": "105:12:1", "nodeType": "YulIdentifier", @@ -178,15 +158,13 @@ "name": "f", "nameLocation": "26:1:1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 1, "nodeType": "ParameterList", "parameters": [], "src": "27:2:1" }, - "returnParameters": - { + "returnParameters": { "id": 2, "nodeType": "ParameterList", "parameters": [], diff --git a/test/libsolidity/ASTJSON/assembly/var_access.json b/test/libsolidity/ASTJSON/assembly/var_access.json index ae7845815fa2..86bc76fa78e5 100644 --- a/test/libsolidity/ASTJSON/assembly/var_access.json +++ b/test/libsolidity/ASTJSON/assembly/var_access.json @@ -1,16 +1,13 @@ { "absolutePath": "a", - "exportedSymbols": - { - "C": - [ + "exportedSymbols": { + "C": [ 9 ] }, "id": 10, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "abstract": false, "baseContracts": [], @@ -19,30 +16,24 @@ "contractKind": "contract", "fullyImplemented": true, "id": 9, - "linearizedBaseContracts": - [ + "linearizedBaseContracts": [ 9 ], "name": "C", "nameLocation": "9:1:1", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { - "body": - { + "body": { "id": 7, "nodeType": "Block", "src": "42:51:1", - "statements": - [ + "statements": [ { - "assignments": - [ + "assignments": [ 4 ], - "declarations": - [ + "declarations": [ { "constant": false, "id": 4, @@ -54,19 +45,16 @@ "src": "52:6:1", "stateVariable": false, "storageLocation": "default", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_uint256", "typeString": "uint256" }, - "typeName": - { + "typeName": { "id": 3, "name": "uint", "nodeType": "ElementaryTypeName", "src": "52:4:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_uint256", "typeString": "uint256" } @@ -79,19 +67,16 @@ "src": "52:6:1" }, { - "AST": - { + "AST": { "nativeSrc": "77:10:1", "nodeType": "YulBlock", "src": "77:10:1", - "statements": - [ + "statements": [ { "nativeSrc": "79:6:1", "nodeType": "YulAssignment", "src": "79:6:1", - "value": - { + "value": { "kind": "number", "nativeSrc": "84:1:1", "nodeType": "YulLiteral", @@ -99,8 +84,7 @@ "type": "", "value": "7" }, - "variableNames": - [ + "variableNames": [ { "name": "x", "nativeSrc": "79:1:1", @@ -112,8 +96,7 @@ ] }, "evmVersion": %EVMVERSION%, - "externalReferences": - [ + "externalReferences": [ { "declaration": 4, "isOffset": false, @@ -136,15 +119,13 @@ "name": "f", "nameLocation": "26:1:1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 1, "nodeType": "ParameterList", "parameters": [], "src": "27:2:1" }, - "returnParameters": - { + "returnParameters": { "id": 2, "nodeType": "ParameterList", "parameters": [], diff --git a/test/libsolidity/ASTJSON/assembly/var_access.sol b/test/libsolidity/ASTJSON/assembly/var_access.sol index e4b7423fde04..768f38c3342c 100644 --- a/test/libsolidity/ASTJSON/assembly/var_access.sol +++ b/test/libsolidity/ASTJSON/assembly/var_access.sol @@ -4,4 +4,5 @@ contract C { assembly { x := 7 } } } + // ---- diff --git a/test/libsolidity/ASTJSON/assembly/var_access_parseOnly.json b/test/libsolidity/ASTJSON/assembly/var_access_parseOnly.json index ca3fcf92c91e..129104bbcda4 100644 --- a/test/libsolidity/ASTJSON/assembly/var_access_parseOnly.json +++ b/test/libsolidity/ASTJSON/assembly/var_access_parseOnly.json @@ -2,8 +2,7 @@ "absolutePath": "a", "id": 10, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "abstract": false, "baseContracts": [], @@ -13,23 +12,18 @@ "name": "C", "nameLocation": "9:1:1", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { - "body": - { + "body": { "id": 7, "nodeType": "Block", "src": "42:51:1", - "statements": - [ + "statements": [ { - "assignments": - [ + "assignments": [ 4 ], - "declarations": - [ + "declarations": [ { "constant": false, "id": 4, @@ -41,8 +35,7 @@ "stateVariable": false, "storageLocation": "default", "typeDescriptions": {}, - "typeName": - { + "typeName": { "id": 3, "name": "uint", "nodeType": "ElementaryTypeName", @@ -57,19 +50,16 @@ "src": "52:6:1" }, { - "AST": - { + "AST": { "nativeSrc": "77:10:1", "nodeType": "YulBlock", "src": "77:10:1", - "statements": - [ + "statements": [ { "nativeSrc": "79:6:1", "nodeType": "YulAssignment", "src": "79:6:1", - "value": - { + "value": { "kind": "number", "nativeSrc": "84:1:1", "nodeType": "YulLiteral", @@ -77,8 +67,7 @@ "type": "", "value": "7" }, - "variableNames": - [ + "variableNames": [ { "name": "x", "nativeSrc": "79:1:1", @@ -104,15 +93,13 @@ "name": "f", "nameLocation": "26:1:1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 1, "nodeType": "ParameterList", "parameters": [], "src": "27:2:1" }, - "returnParameters": - { + "returnParameters": { "id": 2, "nodeType": "ParameterList", "parameters": [], diff --git a/test/libsolidity/ASTJSON/ast_internal_function_different_ids_export.json b/test/libsolidity/ASTJSON/ast_internal_function_different_ids_export.json index 07886a166338..f94345ffcd92 100644 --- a/test/libsolidity/ASTJSON/ast_internal_function_different_ids_export.json +++ b/test/libsolidity/ASTJSON/ast_internal_function_different_ids_export.json @@ -1,28 +1,22 @@ [ { "absolutePath": "L", - "exportedSymbols": - { - "L": - [ + "exportedSymbols": { + "L": [ 78 ], - "free1": - [ + "free1": [ 65 ], - "free2": - [ + "free2": [ 69 ] }, "id": 79, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { - "body": - { + "body": { "id": 64, "nodeType": "Block", "src": "17:2:1", @@ -35,15 +29,13 @@ "name": "free1", "nameLocation": "9:5:1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 62, "nodeType": "ParameterList", "parameters": [], "src": "14:2:1" }, - "returnParameters": - { + "returnParameters": { "id": 63, "nodeType": "ParameterList", "parameters": [], @@ -56,8 +48,7 @@ "visibility": "internal" }, { - "body": - { + "body": { "id": 68, "nodeType": "Block", "src": "37:2:1", @@ -70,15 +61,13 @@ "name": "free2", "nameLocation": "29:5:1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 66, "nodeType": "ParameterList", "parameters": [], "src": "34:2:1" }, - "returnParameters": - { + "returnParameters": { "id": 67, "nodeType": "ParameterList", "parameters": [], @@ -98,18 +87,15 @@ "contractKind": "library", "fullyImplemented": true, "id": 78, - "linearizedBaseContracts": - [ + "linearizedBaseContracts": [ 78 ], "name": "L", "nameLocation": "48:1:1", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { - "body": - { + "body": { "id": 72, "nodeType": "Block", "src": "78:2:1", @@ -122,15 +108,13 @@ "name": "g", "nameLocation": "65:1:1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 70, "nodeType": "ParameterList", "parameters": [], "src": "66:2:1" }, - "returnParameters": - { + "returnParameters": { "id": 71, "nodeType": "ParameterList", "parameters": [], @@ -143,8 +127,7 @@ "visibility": "internal" }, { - "body": - { + "body": { "id": 76, "nodeType": "Block", "src": "107:2:1", @@ -157,15 +140,13 @@ "name": "h", "nameLocation": "94:1:1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 74, "nodeType": "ParameterList", "parameters": [], "src": "95:2:1" }, - "returnParameters": - { + "returnParameters": { "id": 75, "nodeType": "ParameterList", "parameters": [], @@ -188,33 +169,26 @@ }, { "absolutePath": "A", - "exportedSymbols": - { - "A": - [ + "exportedSymbols": { + "A": [ 22 ], - "B": - [ + "B": [ 37 ], - "L": - [ + "L": [ 78 ], - "free1": - [ + "free1": [ 65 ], - "free2": - [ + "free2": [ 69 ] }, "id": 38, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "absolutePath": "L", "file": "L", @@ -235,49 +209,39 @@ "contractKind": "contract", "fullyImplemented": true, "id": 22, - "internalFunctionIDs": - { + "internalFunctionIDs": { "69": 1, "73": 2, "77": 3 }, - "linearizedBaseContracts": - [ + "linearizedBaseContracts": [ 22 ], "name": "A", "nameLocation": "21:1:2", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { - "body": - { + "body": { "id": 20, "nodeType": "Block", "src": "49:60:2", - "statements": - [ + "statements": [ { - "expression": - { + "expression": { "arguments": [], - "expression": - { + "expression": { "argumentTypes": [], - "components": - [ + "components": [ { - "expression": - { + "expression": { "id": 4, "name": "L", "nodeType": "Identifier", "overloadedDeclarations": [], "referencedDeclaration": 78, "src": "60:1:2", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_type$_t_contract$_L_$78_$", "typeString": "type(library L)" } @@ -292,8 +256,7 @@ "nodeType": "MemberAccess", "referencedDeclaration": 73, "src": "60:3:2", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_function_internal_nonpayable$__$returns$__$", "typeString": "function ()" } @@ -307,8 +270,7 @@ "lValueRequested": false, "nodeType": "TupleExpression", "src": "59:5:2", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_function_internal_nonpayable$__$returns$__$", "typeString": "function ()" } @@ -324,8 +286,7 @@ "nodeType": "FunctionCall", "src": "59:7:2", "tryCall": false, - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_tuple$__$", "typeString": "tuple()" } @@ -335,14 +296,11 @@ "src": "59:7:2" }, { - "expression": - { + "expression": { "arguments": [], - "expression": - { + "expression": { "argumentTypes": [], - "components": - [ + "components": [ { "id": 10, "name": "free2", @@ -350,8 +308,7 @@ "overloadedDeclarations": [], "referencedDeclaration": 69, "src": "77:5:2", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_function_internal_nonpayable$__$returns$__$", "typeString": "function ()" } @@ -365,8 +322,7 @@ "lValueRequested": false, "nodeType": "TupleExpression", "src": "76:7:2", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_function_internal_nonpayable$__$returns$__$", "typeString": "function ()" } @@ -382,8 +338,7 @@ "nodeType": "FunctionCall", "src": "76:9:2", "tryCall": false, - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_tuple$__$", "typeString": "tuple()" } @@ -393,25 +348,20 @@ "src": "76:9:2" }, { - "expression": - { + "expression": { "arguments": [], - "expression": - { + "expression": { "argumentTypes": [], - "components": - [ + "components": [ { - "expression": - { + "expression": { "id": 14, "name": "L", "nodeType": "Identifier", "overloadedDeclarations": [], "referencedDeclaration": 78, "src": "96:1:2", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_type$_t_contract$_L_$78_$", "typeString": "type(library L)" } @@ -426,8 +376,7 @@ "nodeType": "MemberAccess", "referencedDeclaration": 77, "src": "96:3:2", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_function_internal_nonpayable$__$returns$__$", "typeString": "function ()" } @@ -441,8 +390,7 @@ "lValueRequested": false, "nodeType": "TupleExpression", "src": "95:5:2", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_function_internal_nonpayable$__$returns$__$", "typeString": "function ()" } @@ -458,8 +406,7 @@ "nodeType": "FunctionCall", "src": "95:7:2", "tryCall": false, - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_tuple$__$", "typeString": "tuple()" } @@ -478,15 +425,13 @@ "name": "f", "nameLocation": "38:1:2", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 2, "nodeType": "ParameterList", "parameters": [], "src": "39:2:2" }, - "returnParameters": - { + "returnParameters": { "id": 3, "nodeType": "ParameterList", "parameters": [], @@ -512,48 +457,38 @@ "contractKind": "contract", "fullyImplemented": true, "id": 37, - "internalFunctionIDs": - { + "internalFunctionIDs": { "69": 1, "77": 2 }, - "linearizedBaseContracts": - [ + "linearizedBaseContracts": [ 37 ], "name": "B", "nameLocation": "121:1:2", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { - "body": - { + "body": { "id": 35, "nodeType": "Block", "src": "149:43:2", - "statements": - [ + "statements": [ { - "expression": - { + "expression": { "arguments": [], - "expression": - { + "expression": { "argumentTypes": [], - "components": - [ + "components": [ { - "expression": - { + "expression": { "id": 25, "name": "L", "nodeType": "Identifier", "overloadedDeclarations": [], "referencedDeclaration": 78, "src": "160:1:2", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_type$_t_contract$_L_$78_$", "typeString": "type(library L)" } @@ -568,8 +503,7 @@ "nodeType": "MemberAccess", "referencedDeclaration": 77, "src": "160:3:2", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_function_internal_nonpayable$__$returns$__$", "typeString": "function ()" } @@ -583,8 +517,7 @@ "lValueRequested": false, "nodeType": "TupleExpression", "src": "159:5:2", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_function_internal_nonpayable$__$returns$__$", "typeString": "function ()" } @@ -600,8 +533,7 @@ "nodeType": "FunctionCall", "src": "159:7:2", "tryCall": false, - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_tuple$__$", "typeString": "tuple()" } @@ -611,14 +543,11 @@ "src": "159:7:2" }, { - "expression": - { + "expression": { "arguments": [], - "expression": - { + "expression": { "argumentTypes": [], - "components": - [ + "components": [ { "id": 31, "name": "free2", @@ -626,8 +555,7 @@ "overloadedDeclarations": [], "referencedDeclaration": 69, "src": "177:5:2", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_function_internal_nonpayable$__$returns$__$", "typeString": "function ()" } @@ -641,8 +569,7 @@ "lValueRequested": false, "nodeType": "TupleExpression", "src": "176:7:2", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_function_internal_nonpayable$__$returns$__$", "typeString": "function ()" } @@ -658,8 +585,7 @@ "nodeType": "FunctionCall", "src": "176:9:2", "tryCall": false, - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_tuple$__$", "typeString": "tuple()" } @@ -678,15 +604,13 @@ "name": "f", "nameLocation": "138:1:2", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 23, "nodeType": "ParameterList", "parameters": [], "src": "139:2:2" }, - "returnParameters": - { + "returnParameters": { "id": 24, "nodeType": "ParameterList", "parameters": [], @@ -709,29 +633,23 @@ }, { "absolutePath": "C", - "exportedSymbols": - { - "C": - [ + "exportedSymbols": { + "C": [ 60 ], - "L": - [ + "L": [ 78 ], - "free1": - [ + "free1": [ 65 ], - "free2": - [ + "free2": [ 69 ] }, "id": 61, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "absolutePath": "L", "file": "L", @@ -752,49 +670,39 @@ "contractKind": "contract", "fullyImplemented": true, "id": 60, - "internalFunctionIDs": - { + "internalFunctionIDs": { "69": 1, "73": 2, "77": 3 }, - "linearizedBaseContracts": - [ + "linearizedBaseContracts": [ 60 ], "name": "C", "nameLocation": "21:1:3", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { - "body": - { + "body": { "id": 58, "nodeType": "Block", "src": "49:60:3", - "statements": - [ + "statements": [ { - "expression": - { + "expression": { "arguments": [], - "expression": - { + "expression": { "argumentTypes": [], - "components": - [ + "components": [ { - "expression": - { + "expression": { "id": 42, "name": "L", "nodeType": "Identifier", "overloadedDeclarations": [], "referencedDeclaration": 78, "src": "60:1:3", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_type$_t_contract$_L_$78_$", "typeString": "type(library L)" } @@ -809,8 +717,7 @@ "nodeType": "MemberAccess", "referencedDeclaration": 73, "src": "60:3:3", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_function_internal_nonpayable$__$returns$__$", "typeString": "function ()" } @@ -824,8 +731,7 @@ "lValueRequested": false, "nodeType": "TupleExpression", "src": "59:5:3", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_function_internal_nonpayable$__$returns$__$", "typeString": "function ()" } @@ -841,8 +747,7 @@ "nodeType": "FunctionCall", "src": "59:7:3", "tryCall": false, - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_tuple$__$", "typeString": "tuple()" } @@ -852,14 +757,11 @@ "src": "59:7:3" }, { - "expression": - { + "expression": { "arguments": [], - "expression": - { + "expression": { "argumentTypes": [], - "components": - [ + "components": [ { "id": 48, "name": "free2", @@ -867,8 +769,7 @@ "overloadedDeclarations": [], "referencedDeclaration": 69, "src": "77:5:3", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_function_internal_nonpayable$__$returns$__$", "typeString": "function ()" } @@ -882,8 +783,7 @@ "lValueRequested": false, "nodeType": "TupleExpression", "src": "76:7:3", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_function_internal_nonpayable$__$returns$__$", "typeString": "function ()" } @@ -899,8 +799,7 @@ "nodeType": "FunctionCall", "src": "76:9:3", "tryCall": false, - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_tuple$__$", "typeString": "tuple()" } @@ -910,25 +809,20 @@ "src": "76:9:3" }, { - "expression": - { + "expression": { "arguments": [], - "expression": - { + "expression": { "argumentTypes": [], - "components": - [ + "components": [ { - "expression": - { + "expression": { "id": 52, "name": "L", "nodeType": "Identifier", "overloadedDeclarations": [], "referencedDeclaration": 78, "src": "96:1:3", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_type$_t_contract$_L_$78_$", "typeString": "type(library L)" } @@ -943,8 +837,7 @@ "nodeType": "MemberAccess", "referencedDeclaration": 77, "src": "96:3:3", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_function_internal_nonpayable$__$returns$__$", "typeString": "function ()" } @@ -958,8 +851,7 @@ "lValueRequested": false, "nodeType": "TupleExpression", "src": "95:5:3", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_function_internal_nonpayable$__$returns$__$", "typeString": "function ()" } @@ -975,8 +867,7 @@ "nodeType": "FunctionCall", "src": "95:7:3", "tryCall": false, - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_tuple$__$", "typeString": "tuple()" } @@ -995,15 +886,13 @@ "name": "f", "nameLocation": "38:1:3", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 40, "nodeType": "ParameterList", "parameters": [], "src": "39:2:3" }, - "returnParameters": - { + "returnParameters": { "id": 41, "nodeType": "ParameterList", "parameters": [], diff --git a/test/libsolidity/ASTJSON/ast_internal_function_different_ids_export.sol b/test/libsolidity/ASTJSON/ast_internal_function_different_ids_export.sol index 6e0b28c82ac3..bf3222902131 100644 --- a/test/libsolidity/ASTJSON/ast_internal_function_different_ids_export.sol +++ b/test/libsolidity/ASTJSON/ast_internal_function_different_ids_export.sol @@ -1,5 +1,4 @@ ==== Source: L ==== - function free1() {} function free2() {} library L { @@ -8,7 +7,6 @@ library L { } ==== Source: A ==== - import "L"; contract A { function f() public { @@ -25,7 +23,6 @@ contract B { } ==== Source: C ==== - import "L"; contract C { function f() public { diff --git a/test/libsolidity/ASTJSON/ast_internal_function_id_export.json b/test/libsolidity/ASTJSON/ast_internal_function_id_export.json index d452f2d99fec..cbbc962c027a 100644 --- a/test/libsolidity/ASTJSON/ast_internal_function_id_export.json +++ b/test/libsolidity/ASTJSON/ast_internal_function_id_export.json @@ -1,39 +1,30 @@ { "absolutePath": "a", - "exportedSymbols": - { - "C": - [ + "exportedSymbols": { + "C": [ 128 ], - "D": - [ + "D": [ 141 ], - "L": - [ + "L": [ 53 ], - "free1": - [ + "free1": [ 4 ], - "free2": - [ + "free2": [ 8 ], - "free3": - [ + "free3": [ 12 ] }, "id": 142, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { - "body": - { + "body": { "id": 3, "nodeType": "Block", "src": "17:2:1", @@ -46,15 +37,13 @@ "name": "free1", "nameLocation": "9:5:1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 1, "nodeType": "ParameterList", "parameters": [], "src": "14:2:1" }, - "returnParameters": - { + "returnParameters": { "id": 2, "nodeType": "ParameterList", "parameters": [], @@ -67,8 +56,7 @@ "visibility": "internal" }, { - "body": - { + "body": { "id": 7, "nodeType": "Block", "src": "37:2:1", @@ -81,15 +69,13 @@ "name": "free2", "nameLocation": "29:5:1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 5, "nodeType": "ParameterList", "parameters": [], "src": "34:2:1" }, - "returnParameters": - { + "returnParameters": { "id": 6, "nodeType": "ParameterList", "parameters": [], @@ -102,8 +88,7 @@ "visibility": "internal" }, { - "body": - { + "body": { "id": 11, "nodeType": "Block", "src": "57:2:1", @@ -116,15 +101,13 @@ "name": "free3", "nameLocation": "49:5:1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 9, "nodeType": "ParameterList", "parameters": [], "src": "54:2:1" }, - "returnParameters": - { + "returnParameters": { "id": 10, "nodeType": "ParameterList", "parameters": [], @@ -144,25 +127,21 @@ "contractKind": "library", "fullyImplemented": true, "id": 53, - "internalFunctionIDs": - { + "internalFunctionIDs": { "20": 3, "24": 4, "4": 1, "8": 2 }, - "linearizedBaseContracts": - [ + "linearizedBaseContracts": [ 53 ], "name": "L", "nameLocation": "68:1:1", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { - "body": - { + "body": { "id": 15, "nodeType": "Block", "src": "100:2:1", @@ -176,15 +155,13 @@ "name": "ext", "nameLocation": "85:3:1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 13, "nodeType": "ParameterList", "parameters": [], "src": "88:2:1" }, - "returnParameters": - { + "returnParameters": { "id": 14, "nodeType": "ParameterList", "parameters": [], @@ -197,8 +174,7 @@ "visibility": "external" }, { - "body": - { + "body": { "id": 19, "nodeType": "Block", "src": "132:2:1", @@ -211,15 +187,13 @@ "name": "inr1", "nameLocation": "116:4:1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 17, "nodeType": "ParameterList", "parameters": [], "src": "120:2:1" }, - "returnParameters": - { + "returnParameters": { "id": 18, "nodeType": "ParameterList", "parameters": [], @@ -232,8 +206,7 @@ "visibility": "internal" }, { - "body": - { + "body": { "id": 23, "nodeType": "Block", "src": "164:2:1", @@ -246,15 +219,13 @@ "name": "inr2", "nameLocation": "148:4:1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 21, "nodeType": "ParameterList", "parameters": [], "src": "152:2:1" }, - "returnParameters": - { + "returnParameters": { "id": 22, "nodeType": "ParameterList", "parameters": [], @@ -267,8 +238,7 @@ "visibility": "internal" }, { - "body": - { + "body": { "id": 27, "nodeType": "Block", "src": "196:2:1", @@ -281,15 +251,13 @@ "name": "inr3", "nameLocation": "180:4:1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 25, "nodeType": "ParameterList", "parameters": [], "src": "184:2:1" }, - "returnParameters": - { + "returnParameters": { "id": 26, "nodeType": "ParameterList", "parameters": [], @@ -302,24 +270,20 @@ "visibility": "internal" }, { - "body": - { + "body": { "id": 39, "nodeType": "Block", "src": "228:51:1", - "statements": - [ + "statements": [ { - "expression": - { + "expression": { "id": 31, "name": "free1", "nodeType": "Identifier", "overloadedDeclarations": [], "referencedDeclaration": 4, "src": "238:5:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_function_internal_nonpayable$__$returns$__$", "typeString": "function ()" } @@ -329,16 +293,14 @@ "src": "238:5:1" }, { - "expression": - { + "expression": { "id": 33, "name": "inr1", "nodeType": "Identifier", "overloadedDeclarations": [], "referencedDeclaration": 20, "src": "253:4:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_function_internal_nonpayable$__$returns$__$", "typeString": "function ()" } @@ -348,18 +310,15 @@ "src": "253:4:1" }, { - "expression": - { - "expression": - { + "expression": { + "expression": { "id": 35, "name": "L", "nodeType": "Identifier", "overloadedDeclarations": [], "referencedDeclaration": 53, "src": "267:1:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_type$_t_contract$_L_$53_$", "typeString": "type(library L)" } @@ -374,8 +333,7 @@ "nodeType": "MemberAccess", "referencedDeclaration": 16, "src": "267:5:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_function_delegatecall_nonpayable$__$returns$__$", "typeString": "function ()" } @@ -394,15 +352,13 @@ "name": "access", "nameLocation": "212:6:1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 29, "nodeType": "ParameterList", "parameters": [], "src": "218:2:1" }, - "returnParameters": - { + "returnParameters": { "id": 30, "nodeType": "ParameterList", "parameters": [], @@ -415,22 +371,17 @@ "visibility": "public" }, { - "body": - { + "body": { "id": 51, "nodeType": "Block", "src": "313:44:1", - "statements": - [ + "statements": [ { - "expression": - { + "expression": { "arguments": [], - "expression": - { + "expression": { "argumentTypes": [], - "components": - [ + "components": [ { "id": 43, "name": "free2", @@ -438,8 +389,7 @@ "overloadedDeclarations": [], "referencedDeclaration": 8, "src": "324:5:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_function_internal_nonpayable$__$returns$__$", "typeString": "function ()" } @@ -453,8 +403,7 @@ "lValueRequested": false, "nodeType": "TupleExpression", "src": "323:7:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_function_internal_nonpayable$__$returns$__$", "typeString": "function ()" } @@ -470,8 +419,7 @@ "nodeType": "FunctionCall", "src": "323:9:1", "tryCall": false, - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_tuple$__$", "typeString": "tuple()" } @@ -481,14 +429,11 @@ "src": "323:9:1" }, { - "expression": - { + "expression": { "arguments": [], - "expression": - { + "expression": { "argumentTypes": [], - "components": - [ + "components": [ { "id": 47, "name": "inr2", @@ -496,8 +441,7 @@ "overloadedDeclarations": [], "referencedDeclaration": 24, "src": "343:4:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_function_internal_nonpayable$__$returns$__$", "typeString": "function ()" } @@ -511,8 +455,7 @@ "lValueRequested": false, "nodeType": "TupleExpression", "src": "342:6:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_function_internal_nonpayable$__$returns$__$", "typeString": "function ()" } @@ -528,8 +471,7 @@ "nodeType": "FunctionCall", "src": "342:8:1", "tryCall": false, - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_tuple$__$", "typeString": "tuple()" } @@ -548,15 +490,13 @@ "name": "expression", "nameLocation": "293:10:1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 41, "nodeType": "ParameterList", "parameters": [], "src": "303:2:1" }, - "returnParameters": - { + "returnParameters": { "id": 42, "nodeType": "ParameterList", "parameters": [], @@ -582,8 +522,7 @@ "contractKind": "contract", "fullyImplemented": true, "id": 128, - "internalFunctionIDs": - { + "internalFunctionIDs": { "20": 3, "24": 4, "4": 1, @@ -591,18 +530,15 @@ "73": 6, "8": 2 }, - "linearizedBaseContracts": - [ + "linearizedBaseContracts": [ 128 ], "name": "C", "nameLocation": "369:1:1", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { - "body": - { + "body": { "id": 56, "nodeType": "Block", "src": "402:2:1", @@ -616,15 +552,13 @@ "name": "ext1", "nameLocation": "386:4:1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 54, "nodeType": "ParameterList", "parameters": [], "src": "390:2:1" }, - "returnParameters": - { + "returnParameters": { "id": 55, "nodeType": "ParameterList", "parameters": [], @@ -637,8 +571,7 @@ "visibility": "external" }, { - "body": - { + "body": { "id": 60, "nodeType": "Block", "src": "434:2:1", @@ -652,15 +585,13 @@ "name": "ext2", "nameLocation": "418:4:1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 58, "nodeType": "ParameterList", "parameters": [], "src": "422:2:1" }, - "returnParameters": - { + "returnParameters": { "id": 59, "nodeType": "ParameterList", "parameters": [], @@ -673,8 +604,7 @@ "visibility": "external" }, { - "body": - { + "body": { "id": 64, "nodeType": "Block", "src": "466:2:1", @@ -688,15 +618,13 @@ "name": "ext3", "nameLocation": "450:4:1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 62, "nodeType": "ParameterList", "parameters": [], "src": "454:2:1" }, - "returnParameters": - { + "returnParameters": { "id": 63, "nodeType": "ParameterList", "parameters": [], @@ -709,8 +637,7 @@ "visibility": "external" }, { - "body": - { + "body": { "id": 68, "nodeType": "Block", "src": "498:2:1", @@ -723,15 +650,13 @@ "name": "inr1", "nameLocation": "482:4:1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 66, "nodeType": "ParameterList", "parameters": [], "src": "486:2:1" }, - "returnParameters": - { + "returnParameters": { "id": 67, "nodeType": "ParameterList", "parameters": [], @@ -744,8 +669,7 @@ "visibility": "internal" }, { - "body": - { + "body": { "id": 72, "nodeType": "Block", "src": "530:2:1", @@ -758,15 +682,13 @@ "name": "inr2", "nameLocation": "514:4:1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 70, "nodeType": "ParameterList", "parameters": [], "src": "518:2:1" }, - "returnParameters": - { + "returnParameters": { "id": 71, "nodeType": "ParameterList", "parameters": [], @@ -779,8 +701,7 @@ "visibility": "internal" }, { - "body": - { + "body": { "id": 76, "nodeType": "Block", "src": "562:2:1", @@ -793,15 +714,13 @@ "name": "inr3", "nameLocation": "546:4:1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 74, "nodeType": "ParameterList", "parameters": [], "src": "550:2:1" }, - "returnParameters": - { + "returnParameters": { "id": 75, "nodeType": "ParameterList", "parameters": [], @@ -814,26 +733,21 @@ "visibility": "internal" }, { - "body": - { + "body": { "id": 96, "nodeType": "Block", "src": "594:86:1", - "statements": - [ + "statements": [ { - "expression": - { - "expression": - { + "expression": { + "expression": { "id": 80, "name": "this", "nodeType": "Identifier", "overloadedDeclarations": [], "referencedDeclaration": -28, "src": "604:4:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_contract$_C_$128", "typeString": "contract C" } @@ -848,8 +762,7 @@ "nodeType": "MemberAccess", "referencedDeclaration": 57, "src": "604:9:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_function_external_nonpayable$__$returns$__$", "typeString": "function () external" } @@ -859,16 +772,14 @@ "src": "604:9:1" }, { - "expression": - { + "expression": { "id": 84, "name": "inr1", "nodeType": "Identifier", "overloadedDeclarations": [], "referencedDeclaration": 69, "src": "623:4:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_function_internal_nonpayable$__$returns$__$", "typeString": "function ()" } @@ -878,16 +789,14 @@ "src": "623:4:1" }, { - "expression": - { + "expression": { "id": 86, "name": "free1", "nodeType": "Identifier", "overloadedDeclarations": [], "referencedDeclaration": 4, "src": "637:5:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_function_internal_nonpayable$__$returns$__$", "typeString": "function ()" } @@ -897,18 +806,15 @@ "src": "637:5:1" }, { - "expression": - { - "expression": - { + "expression": { + "expression": { "id": 88, "name": "L", "nodeType": "Identifier", "overloadedDeclarations": [], "referencedDeclaration": 53, "src": "652:1:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_type$_t_contract$_L_$53_$", "typeString": "type(library L)" } @@ -923,8 +829,7 @@ "nodeType": "MemberAccess", "referencedDeclaration": 20, "src": "652:6:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_function_internal_nonpayable$__$returns$__$", "typeString": "function ()" } @@ -934,18 +839,15 @@ "src": "652:6:1" }, { - "expression": - { - "expression": - { + "expression": { + "expression": { "id": 92, "name": "L", "nodeType": "Identifier", "overloadedDeclarations": [], "referencedDeclaration": 53, "src": "668:1:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_type$_t_contract$_L_$53_$", "typeString": "type(library L)" } @@ -960,8 +862,7 @@ "nodeType": "MemberAccess", "referencedDeclaration": 16, "src": "668:5:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_function_delegatecall_nonpayable$__$returns$__$", "typeString": "function ()" } @@ -980,15 +881,13 @@ "name": "access", "nameLocation": "578:6:1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 78, "nodeType": "ParameterList", "parameters": [], "src": "584:2:1" }, - "returnParameters": - { + "returnParameters": { "id": 79, "nodeType": "ParameterList", "parameters": [], @@ -1001,33 +900,26 @@ "visibility": "public" }, { - "body": - { + "body": { "id": 126, "nodeType": "Block", "src": "714:106:1", - "statements": - [ + "statements": [ { - "expression": - { + "expression": { "arguments": [], - "expression": - { + "expression": { "argumentTypes": [], - "components": - [ + "components": [ { - "expression": - { + "expression": { "id": 100, "name": "this", "nodeType": "Identifier", "overloadedDeclarations": [], "referencedDeclaration": -28, "src": "725:4:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_contract$_C_$128", "typeString": "contract C" } @@ -1042,8 +934,7 @@ "nodeType": "MemberAccess", "referencedDeclaration": 61, "src": "725:9:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_function_external_nonpayable$__$returns$__$", "typeString": "function () external" } @@ -1057,8 +948,7 @@ "lValueRequested": false, "nodeType": "TupleExpression", "src": "724:11:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_function_external_nonpayable$__$returns$__$", "typeString": "function () external" } @@ -1074,8 +964,7 @@ "nodeType": "FunctionCall", "src": "724:13:1", "tryCall": false, - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_tuple$__$", "typeString": "tuple()" } @@ -1085,14 +974,11 @@ "src": "724:13:1" }, { - "expression": - { + "expression": { "arguments": [], - "expression": - { + "expression": { "argumentTypes": [], - "components": - [ + "components": [ { "id": 106, "name": "inr2", @@ -1100,8 +986,7 @@ "overloadedDeclarations": [], "referencedDeclaration": 73, "src": "748:4:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_function_internal_nonpayable$__$returns$__$", "typeString": "function ()" } @@ -1115,8 +1000,7 @@ "lValueRequested": false, "nodeType": "TupleExpression", "src": "747:6:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_function_internal_nonpayable$__$returns$__$", "typeString": "function ()" } @@ -1132,8 +1016,7 @@ "nodeType": "FunctionCall", "src": "747:8:1", "tryCall": false, - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_tuple$__$", "typeString": "tuple()" } @@ -1143,14 +1026,11 @@ "src": "747:8:1" }, { - "expression": - { + "expression": { "arguments": [], - "expression": - { + "expression": { "argumentTypes": [], - "components": - [ + "components": [ { "id": 110, "name": "free2", @@ -1158,8 +1038,7 @@ "overloadedDeclarations": [], "referencedDeclaration": 8, "src": "766:5:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_function_internal_nonpayable$__$returns$__$", "typeString": "function ()" } @@ -1173,8 +1052,7 @@ "lValueRequested": false, "nodeType": "TupleExpression", "src": "765:7:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_function_internal_nonpayable$__$returns$__$", "typeString": "function ()" } @@ -1190,8 +1068,7 @@ "nodeType": "FunctionCall", "src": "765:9:1", "tryCall": false, - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_tuple$__$", "typeString": "tuple()" } @@ -1201,25 +1078,20 @@ "src": "765:9:1" }, { - "expression": - { + "expression": { "arguments": [], - "expression": - { + "expression": { "argumentTypes": [], - "components": - [ + "components": [ { - "expression": - { + "expression": { "id": 114, "name": "L", "nodeType": "Identifier", "overloadedDeclarations": [], "referencedDeclaration": 53, "src": "785:1:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_type$_t_contract$_L_$53_$", "typeString": "type(library L)" } @@ -1234,8 +1106,7 @@ "nodeType": "MemberAccess", "referencedDeclaration": 24, "src": "785:6:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_function_internal_nonpayable$__$returns$__$", "typeString": "function ()" } @@ -1249,8 +1120,7 @@ "lValueRequested": false, "nodeType": "TupleExpression", "src": "784:8:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_function_internal_nonpayable$__$returns$__$", "typeString": "function ()" } @@ -1266,8 +1136,7 @@ "nodeType": "FunctionCall", "src": "784:10:1", "tryCall": false, - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_tuple$__$", "typeString": "tuple()" } @@ -1277,25 +1146,20 @@ "src": "784:10:1" }, { - "expression": - { + "expression": { "arguments": [], - "expression": - { + "expression": { "argumentTypes": [], - "components": - [ + "components": [ { - "expression": - { + "expression": { "id": 120, "name": "L", "nodeType": "Identifier", "overloadedDeclarations": [], "referencedDeclaration": 53, "src": "805:1:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_type$_t_contract$_L_$53_$", "typeString": "type(library L)" } @@ -1310,8 +1174,7 @@ "nodeType": "MemberAccess", "referencedDeclaration": 16, "src": "805:5:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_function_delegatecall_nonpayable$__$returns$__$", "typeString": "function ()" } @@ -1325,8 +1188,7 @@ "lValueRequested": false, "nodeType": "TupleExpression", "src": "804:7:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_function_delegatecall_nonpayable$__$returns$__$", "typeString": "function ()" } @@ -1342,8 +1204,7 @@ "nodeType": "FunctionCall", "src": "804:9:1", "tryCall": false, - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_tuple$__$", "typeString": "tuple()" } @@ -1362,15 +1223,13 @@ "name": "expression", "nameLocation": "694:10:1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 98, "nodeType": "ParameterList", "parameters": [], "src": "704:2:1" }, - "returnParameters": - { + "returnParameters": { "id": 99, "nodeType": "ParameterList", "parameters": [], @@ -1390,15 +1249,12 @@ }, { "abstract": false, - "baseContracts": - [ + "baseContracts": [ { - "baseName": - { + "baseName": { "id": 129, "name": "C", - "nameLocations": - [ + "nameLocations": [ "837:1:1" ], "nodeType": "IdentifierPath", @@ -1415,8 +1271,7 @@ "contractKind": "contract", "fullyImplemented": true, "id": 141, - "internalFunctionIDs": - { + "internalFunctionIDs": { "20": 3, "24": 4, "4": 1, @@ -1424,30 +1279,24 @@ "73": 6, "8": 2 }, - "linearizedBaseContracts": - [ + "linearizedBaseContracts": [ 141, 128 ], "name": "D", "nameLocation": "832:1:1", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { - "body": - { + "body": { "id": 139, "nodeType": "Block", "src": "859:47:1", - "statements": - [ + "statements": [ { - "expression": - { + "expression": { "arguments": [], - "expression": - { + "expression": { "argumentTypes": [], "id": 133, "name": "access", @@ -1455,8 +1304,7 @@ "overloadedDeclarations": [], "referencedDeclaration": 97, "src": "869:6:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_function_internal_nonpayable$__$returns$__$", "typeString": "function ()" } @@ -1472,8 +1320,7 @@ "nodeType": "FunctionCall", "src": "869:8:1", "tryCall": false, - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_tuple$__$", "typeString": "tuple()" } @@ -1483,11 +1330,9 @@ "src": "869:8:1" }, { - "expression": - { + "expression": { "arguments": [], - "expression": - { + "expression": { "argumentTypes": [], "id": 136, "name": "expression", @@ -1495,8 +1340,7 @@ "overloadedDeclarations": [], "referencedDeclaration": 127, "src": "887:10:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_function_internal_nonpayable$__$returns$__$", "typeString": "function ()" } @@ -1512,8 +1356,7 @@ "nodeType": "FunctionCall", "src": "887:12:1", "tryCall": false, - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_tuple$__$", "typeString": "tuple()" } @@ -1531,15 +1374,13 @@ "name": "", "nameLocation": "-1:-1:-1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 131, "nodeType": "ParameterList", "parameters": [], "src": "856:2:1" }, - "returnParameters": - { + "returnParameters": { "id": 132, "nodeType": "ParameterList", "parameters": [], diff --git a/test/libsolidity/ASTJSON/base_constructor_call.json b/test/libsolidity/ASTJSON/base_constructor_call.json index 2c3c68c40d3a..408cb947704a 100644 --- a/test/libsolidity/ASTJSON/base_constructor_call.json +++ b/test/libsolidity/ASTJSON/base_constructor_call.json @@ -1,20 +1,16 @@ { "absolutePath": "a", - "exportedSymbols": - { - "A": - [ + "exportedSymbols": { + "A": [ 7 ], - "C": - [ + "C": [ 17 ] }, "id": 18, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "abstract": false, "baseContracts": [], @@ -23,18 +19,15 @@ "contractKind": "contract", "fullyImplemented": true, "id": 7, - "linearizedBaseContracts": - [ + "linearizedBaseContracts": [ 7 ], "name": "A", "nameLocation": "9:1:1", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { - "body": - { + "body": { "id": 5, "nodeType": "Block", "src": "31:2:1", @@ -47,12 +40,10 @@ "name": "", "nameLocation": "-1:-1:-1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 3, "nodeType": "ParameterList", - "parameters": - [ + "parameters": [ { "constant": false, "id": 2, @@ -64,19 +55,16 @@ "src": "25:4:1", "stateVariable": false, "storageLocation": "default", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_uint256", "typeString": "uint256" }, - "typeName": - { + "typeName": { "id": 1, "name": "uint", "nodeType": "ElementaryTypeName", "src": "25:4:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_uint256", "typeString": "uint256" } @@ -86,8 +74,7 @@ ], "src": "24:6:1" }, - "returnParameters": - { + "returnParameters": { "id": 4, "nodeType": "ParameterList", "parameters": [], @@ -107,15 +94,12 @@ }, { "abstract": false, - "baseContracts": - [ + "baseContracts": [ { - "baseName": - { + "baseName": { "id": 8, "name": "A", - "nameLocations": - [ + "nameLocations": [ "50:1:1" ], "nodeType": "IdentifierPath", @@ -132,19 +116,16 @@ "contractKind": "contract", "fullyImplemented": true, "id": 17, - "linearizedBaseContracts": - [ + "linearizedBaseContracts": [ 17, 7 ], "name": "C", "nameLocation": "45:1:1", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { - "body": - { + "body": { "id": 15, "nodeType": "Block", "src": "73:2:1", @@ -153,11 +134,9 @@ "id": 16, "implemented": true, "kind": "constructor", - "modifiers": - [ + "modifiers": [ { - "arguments": - [ + "arguments": [ { "hexValue": "32", "id": 12, @@ -168,8 +147,7 @@ "lValueRequested": false, "nodeType": "Literal", "src": "70:1:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_rational_2_by_1", "typeString": "int_const 2" }, @@ -178,12 +156,10 @@ ], "id": 13, "kind": "baseConstructorSpecifier", - "modifierName": - { + "modifierName": { "id": 11, "name": "A", - "nameLocations": - [ + "nameLocations": [ "68:1:1" ], "nodeType": "IdentifierPath", @@ -197,15 +173,13 @@ "name": "", "nameLocation": "-1:-1:-1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 10, "nodeType": "ParameterList", "parameters": [], "src": "65:2:1" }, - "returnParameters": - { + "returnParameters": { "id": 14, "nodeType": "ParameterList", "parameters": [], diff --git a/test/libsolidity/ASTJSON/base_constructor_call_parseOnly.json b/test/libsolidity/ASTJSON/base_constructor_call_parseOnly.json index 730a05178c62..07a57a9db788 100644 --- a/test/libsolidity/ASTJSON/base_constructor_call_parseOnly.json +++ b/test/libsolidity/ASTJSON/base_constructor_call_parseOnly.json @@ -2,8 +2,7 @@ "absolutePath": "a", "id": 18, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "abstract": false, "baseContracts": [], @@ -13,11 +12,9 @@ "name": "A", "nameLocation": "9:1:1", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { - "body": - { + "body": { "id": 5, "nodeType": "Block", "src": "31:2:1", @@ -30,12 +27,10 @@ "name": "", "nameLocation": "-1:-1:-1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 3, "nodeType": "ParameterList", - "parameters": - [ + "parameters": [ { "constant": false, "id": 2, @@ -47,8 +42,7 @@ "stateVariable": false, "storageLocation": "default", "typeDescriptions": {}, - "typeName": - { + "typeName": { "id": 1, "name": "uint", "nodeType": "ElementaryTypeName", @@ -60,8 +54,7 @@ ], "src": "24:6:1" }, - "returnParameters": - { + "returnParameters": { "id": 4, "nodeType": "ParameterList", "parameters": [], @@ -78,15 +71,12 @@ }, { "abstract": false, - "baseContracts": - [ + "baseContracts": [ { - "baseName": - { + "baseName": { "id": 8, "name": "A", - "nameLocations": - [ + "nameLocations": [ "50:1:1" ], "nodeType": "IdentifierPath", @@ -103,11 +93,9 @@ "name": "C", "nameLocation": "45:1:1", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { - "body": - { + "body": { "id": 15, "nodeType": "Block", "src": "73:2:1", @@ -116,11 +104,9 @@ "id": 16, "implemented": true, "kind": "constructor", - "modifiers": - [ + "modifiers": [ { - "arguments": - [ + "arguments": [ { "hexValue": "32", "id": 12, @@ -132,12 +118,10 @@ } ], "id": 13, - "modifierName": - { + "modifierName": { "id": 11, "name": "A", - "nameLocations": - [ + "nameLocations": [ "68:1:1" ], "nodeType": "IdentifierPath", @@ -150,15 +134,13 @@ "name": "", "nameLocation": "-1:-1:-1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 10, "nodeType": "ParameterList", "parameters": [], "src": "65:2:1" }, - "returnParameters": - { + "returnParameters": { "id": 14, "nodeType": "ParameterList", "parameters": [], diff --git a/test/libsolidity/ASTJSON/constructor.json b/test/libsolidity/ASTJSON/constructor.json index 53e622b5ddab..2c18d73f240a 100644 --- a/test/libsolidity/ASTJSON/constructor.json +++ b/test/libsolidity/ASTJSON/constructor.json @@ -1,16 +1,13 @@ { "absolutePath": "a", - "exportedSymbols": - { - "C": - [ + "exportedSymbols": { + "C": [ 5 ] }, "id": 6, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "abstract": false, "baseContracts": [], @@ -19,18 +16,15 @@ "contractKind": "contract", "fullyImplemented": true, "id": 5, - "linearizedBaseContracts": - [ + "linearizedBaseContracts": [ 5 ], "name": "C", "nameLocation": "9:1:1", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { - "body": - { + "body": { "id": 3, "nodeType": "Block", "src": "28:4:1", @@ -43,15 +37,13 @@ "name": "", "nameLocation": "-1:-1:-1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 1, "nodeType": "ParameterList", "parameters": [], "src": "25:2:1" }, - "returnParameters": - { + "returnParameters": { "id": 2, "nodeType": "ParameterList", "parameters": [], diff --git a/test/libsolidity/ASTJSON/constructor.sol b/test/libsolidity/ASTJSON/constructor.sol index b48aa1be342a..b2b1c646048b 100644 --- a/test/libsolidity/ASTJSON/constructor.sol +++ b/test/libsolidity/ASTJSON/constructor.sol @@ -2,4 +2,5 @@ contract C { constructor() { } } + // ---- diff --git a/test/libsolidity/ASTJSON/constructor_parseOnly.json b/test/libsolidity/ASTJSON/constructor_parseOnly.json index 9b1d4cfc4460..4645d6d3be0e 100644 --- a/test/libsolidity/ASTJSON/constructor_parseOnly.json +++ b/test/libsolidity/ASTJSON/constructor_parseOnly.json @@ -2,8 +2,7 @@ "absolutePath": "a", "id": 6, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "abstract": false, "baseContracts": [], @@ -13,11 +12,9 @@ "name": "C", "nameLocation": "9:1:1", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { - "body": - { + "body": { "id": 3, "nodeType": "Block", "src": "28:4:1", @@ -30,15 +27,13 @@ "name": "", "nameLocation": "-1:-1:-1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 1, "nodeType": "ParameterList", "parameters": [], "src": "25:2:1" }, - "returnParameters": - { + "returnParameters": { "id": 2, "nodeType": "ParameterList", "parameters": [], diff --git a/test/libsolidity/ASTJSON/contract_dep_order.json b/test/libsolidity/ASTJSON/contract_dep_order.json index 67eff600b68f..396957617446 100644 --- a/test/libsolidity/ASTJSON/contract_dep_order.json +++ b/test/libsolidity/ASTJSON/contract_dep_order.json @@ -1,32 +1,25 @@ { "absolutePath": "a", - "exportedSymbols": - { - "A": - [ + "exportedSymbols": { + "A": [ 1 ], - "B": - [ + "B": [ 4 ], - "C": - [ + "C": [ 7 ], - "D": - [ + "D": [ 10 ], - "E": - [ + "E": [ 13 ] }, "id": 14, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "abstract": false, "baseContracts": [], @@ -35,8 +28,7 @@ "contractKind": "contract", "fullyImplemented": true, "id": 1, - "linearizedBaseContracts": - [ + "linearizedBaseContracts": [ 1 ], "name": "A", @@ -50,15 +42,12 @@ }, { "abstract": false, - "baseContracts": - [ + "baseContracts": [ { - "baseName": - { + "baseName": { "id": 2, "name": "A", - "nameLocations": - [ + "nameLocations": [ "29:1:1" ], "nodeType": "IdentifierPath", @@ -75,8 +64,7 @@ "contractKind": "contract", "fullyImplemented": true, "id": 4, - "linearizedBaseContracts": - [ + "linearizedBaseContracts": [ 4, 1 ], @@ -91,15 +79,12 @@ }, { "abstract": false, - "baseContracts": - [ + "baseContracts": [ { - "baseName": - { + "baseName": { "id": 5, "name": "B", - "nameLocations": - [ + "nameLocations": [ "49:1:1" ], "nodeType": "IdentifierPath", @@ -116,8 +101,7 @@ "contractKind": "contract", "fullyImplemented": true, "id": 7, - "linearizedBaseContracts": - [ + "linearizedBaseContracts": [ 7, 4, 1 @@ -133,15 +117,12 @@ }, { "abstract": false, - "baseContracts": - [ + "baseContracts": [ { - "baseName": - { + "baseName": { "id": 8, "name": "C", - "nameLocations": - [ + "nameLocations": [ "69:1:1" ], "nodeType": "IdentifierPath", @@ -158,8 +139,7 @@ "contractKind": "contract", "fullyImplemented": true, "id": 10, - "linearizedBaseContracts": - [ + "linearizedBaseContracts": [ 10, 7, 4, @@ -176,15 +156,12 @@ }, { "abstract": false, - "baseContracts": - [ + "baseContracts": [ { - "baseName": - { + "baseName": { "id": 11, "name": "D", - "nameLocations": - [ + "nameLocations": [ "89:1:1" ], "nodeType": "IdentifierPath", @@ -201,8 +178,7 @@ "contractKind": "contract", "fullyImplemented": true, "id": 13, - "linearizedBaseContracts": - [ + "linearizedBaseContracts": [ 13, 10, 7, diff --git a/test/libsolidity/ASTJSON/contract_dep_order_parseOnly.json b/test/libsolidity/ASTJSON/contract_dep_order_parseOnly.json index ba8c377cf7cd..022d93b9e865 100644 --- a/test/libsolidity/ASTJSON/contract_dep_order_parseOnly.json +++ b/test/libsolidity/ASTJSON/contract_dep_order_parseOnly.json @@ -2,8 +2,7 @@ "absolutePath": "a", "id": 14, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "abstract": false, "baseContracts": [], @@ -20,15 +19,12 @@ }, { "abstract": false, - "baseContracts": - [ + "baseContracts": [ { - "baseName": - { + "baseName": { "id": 2, "name": "A", - "nameLocations": - [ + "nameLocations": [ "29:1:1" ], "nodeType": "IdentifierPath", @@ -52,15 +48,12 @@ }, { "abstract": false, - "baseContracts": - [ + "baseContracts": [ { - "baseName": - { + "baseName": { "id": 5, "name": "B", - "nameLocations": - [ + "nameLocations": [ "49:1:1" ], "nodeType": "IdentifierPath", @@ -84,15 +77,12 @@ }, { "abstract": false, - "baseContracts": - [ + "baseContracts": [ { - "baseName": - { + "baseName": { "id": 8, "name": "C", - "nameLocations": - [ + "nameLocations": [ "69:1:1" ], "nodeType": "IdentifierPath", @@ -116,15 +106,12 @@ }, { "abstract": false, - "baseContracts": - [ + "baseContracts": [ { - "baseName": - { + "baseName": { "id": 11, "name": "D", - "nameLocations": - [ + "nameLocations": [ "89:1:1" ], "nodeType": "IdentifierPath", diff --git a/test/libsolidity/ASTJSON/documentation.json b/test/libsolidity/ASTJSON/documentation.json index 43224bc64d1d..9558eb3fc4ff 100644 --- a/test/libsolidity/ASTJSON/documentation.json +++ b/test/libsolidity/ASTJSON/documentation.json @@ -1,25 +1,21 @@ [ { "absolutePath": "a", - "exportedSymbols": - { - "C": - [ + "exportedSymbols": { + "C": [ 2 ] }, "id": 3, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "abstract": false, "baseContracts": [], "canonicalName": "C", "contractDependencies": [], "contractKind": "contract", - "documentation": - { + "documentation": { "id": 1, "nodeType": "StructuredDocumentation", "src": "0:27:1", @@ -27,8 +23,7 @@ }, "fullyImplemented": true, "id": 2, - "linearizedBaseContracts": - [ + "linearizedBaseContracts": [ 2 ], "name": "C", @@ -45,25 +40,21 @@ }, { "absolutePath": "b", - "exportedSymbols": - { - "C": - [ + "exportedSymbols": { + "C": [ 5 ] }, "id": 6, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "abstract": false, "baseContracts": [], "canonicalName": "C", "contractDependencies": [], "contractKind": "contract", - "documentation": - { + "documentation": { "id": 4, "nodeType": "StructuredDocumentation", "src": "0:61:2", @@ -71,8 +62,7 @@ }, "fullyImplemented": true, "id": 5, - "linearizedBaseContracts": - [ + "linearizedBaseContracts": [ 5 ], "name": "C", @@ -89,17 +79,14 @@ }, { "absolutePath": "c", - "exportedSymbols": - { - "C": - [ + "exportedSymbols": { + "C": [ 23 ] }, "id": 24, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "abstract": false, "baseContracts": [], @@ -108,19 +95,16 @@ "contractKind": "contract", "fullyImplemented": true, "id": 23, - "linearizedBaseContracts": - [ + "linearizedBaseContracts": [ 23 ], "name": "C", "nameLocation": "9:1:3", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { "constant": false, - "documentation": - { + "documentation": { "id": 7, "nodeType": "StructuredDocumentation", "src": "15:32:3", @@ -136,19 +120,16 @@ "src": "48:17:3", "stateVariable": true, "storageLocation": "default", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_uint256", "typeString": "uint256" }, - "typeName": - { + "typeName": { "id": 8, "name": "uint", "nodeType": "ElementaryTypeName", "src": "48:4:3", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_uint256", "typeString": "uint256" } @@ -157,8 +138,7 @@ }, { "anonymous": false, - "documentation": - { + "documentation": { "id": 10, "nodeType": "StructuredDocumentation", "src": "69:26:3", @@ -169,8 +149,7 @@ "name": "Evt", "nameLocation": "102:3:3", "nodeType": "EventDefinition", - "parameters": - { + "parameters": { "id": 11, "nodeType": "ParameterList", "parameters": [], @@ -179,13 +158,11 @@ "src": "96:12:3" }, { - "body": - { + "body": { "id": 16, "nodeType": "Block", "src": "153:6:3", - "statements": - [ + "statements": [ { "id": 15, "nodeType": "PlaceholderStatement", @@ -193,8 +170,7 @@ } ] }, - "documentation": - { + "documentation": { "id": 13, "nodeType": "StructuredDocumentation", "src": "111:26:3", @@ -204,8 +180,7 @@ "name": "mod", "nameLocation": "147:3:3", "nodeType": "ModifierDefinition", - "parameters": - { + "parameters": { "id": 14, "nodeType": "ParameterList", "parameters": [], @@ -216,15 +191,13 @@ "visibility": "internal" }, { - "body": - { + "body": { "id": 21, "nodeType": "Block", "src": "209:2:3", "statements": [] }, - "documentation": - { + "documentation": { "id": 18, "nodeType": "StructuredDocumentation", "src": "162:25:3", @@ -238,15 +211,13 @@ "name": "fn", "nameLocation": "197:2:3", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 19, "nodeType": "ParameterList", "parameters": [], "src": "199:2:3" }, - "returnParameters": - { + "returnParameters": { "id": 20, "nodeType": "ParameterList", "parameters": [], @@ -262,8 +233,7 @@ "scope": 24, "src": "0:213:3", "usedErrors": [], - "usedEvents": - [ + "usedEvents": [ 12 ] } diff --git a/test/libsolidity/ASTJSON/documentation.sol b/test/libsolidity/ASTJSON/documentation.sol index 6bbf4042af60..471b7a4761c7 100644 --- a/test/libsolidity/ASTJSON/documentation.sol +++ b/test/libsolidity/ASTJSON/documentation.sol @@ -1,19 +1,17 @@ ==== Source: a ==== - /**This contract is empty*/ contract C {} ==== Source: b ==== - /**This contract is empty and has a line-breaking comment.*/ contract C {} ==== Source: c ==== - contract C { /** Some comment on state var.*/ uint public state; /** Some comment on Evt.*/ event Evt(); /** Some comment on mod.*/ modifier mod() { _; } /** Some comment on fn.*/ function fn() public {} } + // ---- diff --git a/test/libsolidity/ASTJSON/documentation_local_variable.json b/test/libsolidity/ASTJSON/documentation_local_variable.json index 62d76e782c2b..1e22c91616b2 100644 --- a/test/libsolidity/ASTJSON/documentation_local_variable.json +++ b/test/libsolidity/ASTJSON/documentation_local_variable.json @@ -1,16 +1,13 @@ { "absolutePath": "a", - "exportedSymbols": - { - "C": - [ + "exportedSymbols": { + "C": [ 41 ] }, "id": 42, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "abstract": false, "baseContracts": [], @@ -19,30 +16,24 @@ "contractKind": "contract", "fullyImplemented": true, "id": 41, - "linearizedBaseContracts": - [ + "linearizedBaseContracts": [ 41 ], "name": "C", "nameLocation": "9:1:1", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { - "body": - { + "body": { "id": 26, "nodeType": "Block", "src": "42:330:1", - "statements": - [ + "statements": [ { - "assignments": - [ + "assignments": [ 5 ], - "declarations": - [ + "declarations": [ { "constant": false, "id": 5, @@ -54,19 +45,16 @@ "src": "109:6:1", "stateVariable": false, "storageLocation": "default", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_uint256", "typeString": "uint256" }, - "typeName": - { + "typeName": { "id": 4, "name": "uint", "nodeType": "ElementaryTypeName", "src": "109:4:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_uint256", "typeString": "uint256" } @@ -76,8 +64,7 @@ ], "documentation": "Documentation for x; will appear in ast json", "id": 7, - "initialValue": - { + "initialValue": { "hexValue": "31", "id": 6, "isConstant": false, @@ -87,8 +74,7 @@ "lValueRequested": false, "nodeType": "Literal", "src": "118:1:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_rational_1_by_1", "typeString": "int_const 1" }, @@ -98,20 +84,16 @@ "src": "109:10:1" }, { - "body": - { + "body": { "id": 24, "nodeType": "Block", "src": "270:96:1", - "statements": - [ + "statements": [ { - "assignments": - [ + "assignments": [ 21 ], - "declarations": - [ + "declarations": [ { "constant": false, "id": 21, @@ -123,19 +105,16 @@ "src": "345:6:1", "stateVariable": false, "storageLocation": "default", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_uint256", "typeString": "uint256" }, - "typeName": - { + "typeName": { "id": 20, "name": "uint", "nodeType": "ElementaryTypeName", "src": "345:4:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_uint256", "typeString": "uint256" } @@ -145,8 +124,7 @@ ], "documentation": "documentation for j; will appear in ast json", "id": 23, - "initialValue": - { + "initialValue": { "hexValue": "30", "id": 22, "isConstant": false, @@ -156,8 +134,7 @@ "lValueRequested": false, "nodeType": "Literal", "src": "354:1:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_rational_0_by_1", "typeString": "int_const 0" }, @@ -168,10 +145,8 @@ } ] }, - "condition": - { - "commonType": - { + "condition": { + "commonType": { "typeIdentifier": "t_uint256", "typeString": "uint256" }, @@ -180,24 +155,21 @@ "isLValue": false, "isPure": false, "lValueRequested": false, - "leftExpression": - { + "leftExpression": { "id": 13, "name": "i", "nodeType": "Identifier", "overloadedDeclarations": [], "referencedDeclaration": 10, "src": "236:1:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_uint256", "typeString": "uint256" } }, "nodeType": "BinaryOperation", "operator": "<", - "rightExpression": - { + "rightExpression": { "hexValue": "3130", "id": 14, "isConstant": false, @@ -207,29 +179,24 @@ "lValueRequested": false, "nodeType": "Literal", "src": "240:2:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_rational_10_by_1", "typeString": "int_const 10" }, "value": "10" }, "src": "236:6:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_bool", "typeString": "bool" } }, "id": 25, - "initializationExpression": - { - "assignments": - [ + "initializationExpression": { + "assignments": [ 10 ], - "declarations": - [ + "declarations": [ { "constant": false, "id": 10, @@ -241,19 +208,16 @@ "src": "212:6:1", "stateVariable": false, "storageLocation": "default", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_uint256", "typeString": "uint256" }, - "typeName": - { + "typeName": { "id": 9, "name": "uint", "nodeType": "ElementaryTypeName", "src": "212:4:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_uint256", "typeString": "uint256" } @@ -262,8 +226,7 @@ } ], "id": 12, - "initialValue": - { + "initialValue": { "hexValue": "30", "id": 11, "isConstant": false, @@ -273,8 +236,7 @@ "lValueRequested": false, "nodeType": "Literal", "src": "221:1:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_rational_0_by_1", "typeString": "int_const 0" }, @@ -284,10 +246,8 @@ "src": "212:10:1" }, "isSimpleCounterLoop": true, - "loopExpression": - { - "expression": - { + "loopExpression": { + "expression": { "id": 17, "isConstant": false, "isLValue": false, @@ -297,22 +257,19 @@ "operator": "++", "prefix": true, "src": "256:3:1", - "subExpression": - { + "subExpression": { "id": 16, "name": "i", "nodeType": "Identifier", "overloadedDeclarations": [], "referencedDeclaration": 10, "src": "258:1:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_uint256", "typeString": "uint256" } }, - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_uint256", "typeString": "uint256" } @@ -334,15 +291,13 @@ "name": "f", "nameLocation": "26:1:1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 1, "nodeType": "ParameterList", "parameters": [], "src": "27:2:1" }, - "returnParameters": - { + "returnParameters": { "id": 2, "nodeType": "ParameterList", "parameters": [], @@ -355,8 +310,7 @@ "visibility": "public" }, { - "body": - { + "body": { "id": 39, "nodeType": "Block", "src": "662:2:1", @@ -370,12 +324,10 @@ "name": "g", "nameLocation": "386:1:1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 37, "nodeType": "ParameterList", - "parameters": - [ + "parameters": [ { "constant": false, "id": 30, @@ -387,19 +339,16 @@ "src": "463:11:1", "stateVariable": false, "storageLocation": "default", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_uint256", "typeString": "uint256" }, - "typeName": - { + "typeName": { "id": 29, "name": "uint", "nodeType": "ElementaryTypeName", "src": "463:4:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_uint256", "typeString": "uint256" } @@ -417,19 +366,16 @@ "src": "550:11:1", "stateVariable": false, "storageLocation": "default", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_uint256", "typeString": "uint256" }, - "typeName": - { + "typeName": { "id": 32, "name": "uint", "nodeType": "ElementaryTypeName", "src": "550:4:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_uint256", "typeString": "uint256" } @@ -447,19 +393,16 @@ "src": "637:11:1", "stateVariable": false, "storageLocation": "default", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_uint256", "typeString": "uint256" }, - "typeName": - { + "typeName": { "id": 35, "name": "uint", "nodeType": "ElementaryTypeName", "src": "637:4:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_uint256", "typeString": "uint256" } @@ -469,8 +412,7 @@ ], "src": "387:267:1" }, - "returnParameters": - { + "returnParameters": { "id": 38, "nodeType": "ParameterList", "parameters": [], diff --git a/test/libsolidity/ASTJSON/documentation_local_variable_parseOnly.json b/test/libsolidity/ASTJSON/documentation_local_variable_parseOnly.json index 8725838394e8..97939eaa15c9 100644 --- a/test/libsolidity/ASTJSON/documentation_local_variable_parseOnly.json +++ b/test/libsolidity/ASTJSON/documentation_local_variable_parseOnly.json @@ -2,8 +2,7 @@ "absolutePath": "a", "id": 42, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "abstract": false, "baseContracts": [], @@ -13,23 +12,18 @@ "name": "C", "nameLocation": "9:1:1", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { - "body": - { + "body": { "id": 26, "nodeType": "Block", "src": "42:330:1", - "statements": - [ + "statements": [ { - "assignments": - [ + "assignments": [ 5 ], - "declarations": - [ + "declarations": [ { "constant": false, "id": 5, @@ -41,8 +35,7 @@ "stateVariable": false, "storageLocation": "default", "typeDescriptions": {}, - "typeName": - { + "typeName": { "id": 4, "name": "uint", "nodeType": "ElementaryTypeName", @@ -54,8 +47,7 @@ ], "documentation": "Documentation for x; will appear in ast json", "id": 7, - "initialValue": - { + "initialValue": { "hexValue": "31", "id": 6, "kind": "number", @@ -68,20 +60,16 @@ "src": "109:10:1" }, { - "body": - { + "body": { "id": 24, "nodeType": "Block", "src": "270:96:1", - "statements": - [ + "statements": [ { - "assignments": - [ + "assignments": [ 21 ], - "declarations": - [ + "declarations": [ { "constant": false, "id": 21, @@ -93,8 +81,7 @@ "stateVariable": false, "storageLocation": "default", "typeDescriptions": {}, - "typeName": - { + "typeName": { "id": 20, "name": "uint", "nodeType": "ElementaryTypeName", @@ -106,8 +93,7 @@ ], "documentation": "documentation for j; will appear in ast json", "id": 23, - "initialValue": - { + "initialValue": { "hexValue": "30", "id": 22, "kind": "number", @@ -121,12 +107,10 @@ } ] }, - "condition": - { + "condition": { "commonType": {}, "id": 15, - "leftExpression": - { + "leftExpression": { "id": 13, "name": "i", "nodeType": "Identifier", @@ -136,8 +120,7 @@ }, "nodeType": "BinaryOperation", "operator": "<", - "rightExpression": - { + "rightExpression": { "hexValue": "3130", "id": 14, "kind": "number", @@ -150,14 +133,11 @@ "typeDescriptions": {} }, "id": 25, - "initializationExpression": - { - "assignments": - [ + "initializationExpression": { + "assignments": [ 10 ], - "declarations": - [ + "declarations": [ { "constant": false, "id": 10, @@ -169,8 +149,7 @@ "stateVariable": false, "storageLocation": "default", "typeDescriptions": {}, - "typeName": - { + "typeName": { "id": 9, "name": "uint", "nodeType": "ElementaryTypeName", @@ -181,8 +160,7 @@ } ], "id": 12, - "initialValue": - { + "initialValue": { "hexValue": "30", "id": 11, "kind": "number", @@ -194,17 +172,14 @@ "nodeType": "VariableDeclarationStatement", "src": "212:10:1" }, - "loopExpression": - { - "expression": - { + "loopExpression": { + "expression": { "id": 17, "nodeType": "UnaryOperation", "operator": "++", "prefix": true, "src": "256:3:1", - "subExpression": - { + "subExpression": { "id": 16, "name": "i", "nodeType": "Identifier", @@ -230,15 +205,13 @@ "name": "f", "nameLocation": "26:1:1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 1, "nodeType": "ParameterList", "parameters": [], "src": "27:2:1" }, - "returnParameters": - { + "returnParameters": { "id": 2, "nodeType": "ParameterList", "parameters": [], @@ -250,8 +223,7 @@ "visibility": "public" }, { - "body": - { + "body": { "id": 39, "nodeType": "Block", "src": "662:2:1", @@ -264,12 +236,10 @@ "name": "g", "nameLocation": "386:1:1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 37, "nodeType": "ParameterList", - "parameters": - [ + "parameters": [ { "constant": false, "id": 30, @@ -281,8 +251,7 @@ "stateVariable": false, "storageLocation": "default", "typeDescriptions": {}, - "typeName": - { + "typeName": { "id": 29, "name": "uint", "nodeType": "ElementaryTypeName", @@ -302,8 +271,7 @@ "stateVariable": false, "storageLocation": "default", "typeDescriptions": {}, - "typeName": - { + "typeName": { "id": 32, "name": "uint", "nodeType": "ElementaryTypeName", @@ -323,8 +291,7 @@ "stateVariable": false, "storageLocation": "default", "typeDescriptions": {}, - "typeName": - { + "typeName": { "id": 35, "name": "uint", "nodeType": "ElementaryTypeName", @@ -336,8 +303,7 @@ ], "src": "387:267:1" }, - "returnParameters": - { + "returnParameters": { "id": 38, "nodeType": "ParameterList", "parameters": [], diff --git a/test/libsolidity/ASTJSON/documentation_on_statements.json b/test/libsolidity/ASTJSON/documentation_on_statements.json index cc4a1ef3c166..350d7868672f 100644 --- a/test/libsolidity/ASTJSON/documentation_on_statements.json +++ b/test/libsolidity/ASTJSON/documentation_on_statements.json @@ -1,16 +1,13 @@ { "absolutePath": "a", - "exportedSymbols": - { - "C": - [ + "exportedSymbols": { + "C": [ 27 ] }, "id": 28, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "abstract": false, "baseContracts": [], @@ -19,15 +16,13 @@ "contractKind": "contract", "fullyImplemented": true, "id": 27, - "linearizedBaseContracts": - [ + "linearizedBaseContracts": [ 27 ], "name": "C", "nameLocation": "9:1:1", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { "constant": false, "id": 2, @@ -39,19 +34,16 @@ "src": "45:6:1", "stateVariable": true, "storageLocation": "default", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_uint256", "typeString": "uint256" }, - "typeName": - { + "typeName": { "id": 1, "name": "uint", "nodeType": "ElementaryTypeName", "src": "45:4:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_uint256", "typeString": "uint256" } @@ -59,47 +51,39 @@ "visibility": "internal" }, { - "body": - { + "body": { "id": 25, "nodeType": "Block", "src": "99:229:1", - "statements": - [ + "statements": [ { - "body": - { + "body": { "id": 21, "nodeType": "Block", "src": "156:66:1", - "statements": - [ + "statements": [ { - "expression": - { + "expression": { "id": 19, "isConstant": false, "isLValue": false, "isPure": false, "lValueRequested": false, - "leftHandSide": - { + "leftHandSide": { "id": 17, "name": "x", "nodeType": "Identifier", "overloadedDeclarations": [], "referencedDeclaration": 5, "src": "205:1:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_uint256", "typeString": "uint256" } }, "nodeType": "Assignment", "operator": "*=", - "rightHandSide": - { + "rightHandSide": { "hexValue": "32", "id": 18, "isConstant": false, @@ -109,16 +93,14 @@ "lValueRequested": false, "nodeType": "Literal", "src": "210:1:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_rational_2_by_1", "typeString": "int_const 2" }, "value": "2" }, "src": "205:6:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_uint256", "typeString": "uint256" } @@ -129,10 +111,8 @@ } ] }, - "condition": - { - "commonType": - { + "condition": { + "commonType": { "typeIdentifier": "t_uint256", "typeString": "uint256" }, @@ -141,24 +121,21 @@ "isLValue": false, "isPure": false, "lValueRequested": false, - "leftExpression": - { + "leftExpression": { "id": 11, "name": "i", "nodeType": "Identifier", "overloadedDeclarations": [], "referencedDeclaration": 8, "src": "143:1:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_uint256", "typeString": "uint256" } }, "nodeType": "BinaryOperation", "operator": "<", - "rightExpression": - { + "rightExpression": { "hexValue": "3230", "id": 12, "isConstant": false, @@ -168,29 +145,24 @@ "lValueRequested": false, "nodeType": "Literal", "src": "147:2:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_rational_20_by_1", "typeString": "int_const 20" }, "value": "20" }, "src": "143:6:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_bool", "typeString": "bool" } }, "id": 22, - "initializationExpression": - { - "assignments": - [ + "initializationExpression": { + "assignments": [ 8 ], - "declarations": - [ + "declarations": [ { "constant": false, "id": 8, @@ -202,19 +174,16 @@ "src": "131:6:1", "stateVariable": false, "storageLocation": "default", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_uint256", "typeString": "uint256" }, - "typeName": - { + "typeName": { "id": 7, "name": "uint", "nodeType": "ElementaryTypeName", "src": "131:4:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_uint256", "typeString": "uint256" } @@ -223,8 +192,7 @@ } ], "id": 10, - "initialValue": - { + "initialValue": { "hexValue": "30", "id": 9, "isConstant": false, @@ -234,8 +202,7 @@ "lValueRequested": false, "nodeType": "Literal", "src": "140:1:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_rational_0_by_1", "typeString": "int_const 0" }, @@ -245,10 +212,8 @@ "src": "131:10:1" }, "isSimpleCounterLoop": true, - "loopExpression": - { - "expression": - { + "loopExpression": { + "expression": { "id": 15, "isConstant": false, "isLValue": false, @@ -258,22 +223,19 @@ "operator": "++", "prefix": false, "src": "151:3:1", - "subExpression": - { + "subExpression": { "id": 14, "name": "i", "nodeType": "Identifier", "overloadedDeclarations": [], "referencedDeclaration": 8, "src": "151:1:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_uint256", "typeString": "uint256" } }, - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_uint256", "typeString": "uint256" } @@ -286,16 +248,14 @@ "src": "126:96:1" }, { - "expression": - { + "expression": { "id": 23, "name": "x", "nodeType": "Identifier", "overloadedDeclarations": [], "referencedDeclaration": 5, "src": "320:1:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_uint256", "typeString": "uint256" } @@ -315,19 +275,16 @@ "name": "f", "nameLocation": "66:1:1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 3, "nodeType": "ParameterList", "parameters": [], "src": "67:2:1" }, - "returnParameters": - { + "returnParameters": { "id": 6, "nodeType": "ParameterList", - "parameters": - [ + "parameters": [ { "constant": false, "id": 5, @@ -339,19 +296,16 @@ "src": "91:6:1", "stateVariable": false, "storageLocation": "default", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_uint256", "typeString": "uint256" }, - "typeName": - { + "typeName": { "id": 4, "name": "uint", "nodeType": "ElementaryTypeName", "src": "91:4:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_uint256", "typeString": "uint256" } diff --git a/test/libsolidity/ASTJSON/documentation_on_statements_parseOnly.json b/test/libsolidity/ASTJSON/documentation_on_statements_parseOnly.json index 3872027cbb54..e266c2e5b330 100644 --- a/test/libsolidity/ASTJSON/documentation_on_statements_parseOnly.json +++ b/test/libsolidity/ASTJSON/documentation_on_statements_parseOnly.json @@ -2,8 +2,7 @@ "absolutePath": "a", "id": 28, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "abstract": false, "baseContracts": [], @@ -13,8 +12,7 @@ "name": "C", "nameLocation": "9:1:1", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { "constant": false, "id": 2, @@ -26,8 +24,7 @@ "stateVariable": false, "storageLocation": "default", "typeDescriptions": {}, - "typeName": - { + "typeName": { "id": 1, "name": "uint", "nodeType": "ElementaryTypeName", @@ -37,27 +34,21 @@ "visibility": "internal" }, { - "body": - { + "body": { "id": 25, "nodeType": "Block", "src": "99:229:1", - "statements": - [ + "statements": [ { - "body": - { + "body": { "id": 21, "nodeType": "Block", "src": "156:66:1", - "statements": - [ + "statements": [ { - "expression": - { + "expression": { "id": 19, - "leftHandSide": - { + "leftHandSide": { "id": 17, "name": "x", "nodeType": "Identifier", @@ -67,8 +58,7 @@ }, "nodeType": "Assignment", "operator": "*=", - "rightHandSide": - { + "rightHandSide": { "hexValue": "32", "id": 18, "kind": "number", @@ -86,12 +76,10 @@ } ] }, - "condition": - { + "condition": { "commonType": {}, "id": 13, - "leftExpression": - { + "leftExpression": { "id": 11, "name": "i", "nodeType": "Identifier", @@ -101,8 +89,7 @@ }, "nodeType": "BinaryOperation", "operator": "<", - "rightExpression": - { + "rightExpression": { "hexValue": "3230", "id": 12, "kind": "number", @@ -115,14 +102,11 @@ "typeDescriptions": {} }, "id": 22, - "initializationExpression": - { - "assignments": - [ + "initializationExpression": { + "assignments": [ 8 ], - "declarations": - [ + "declarations": [ { "constant": false, "id": 8, @@ -134,8 +118,7 @@ "stateVariable": false, "storageLocation": "default", "typeDescriptions": {}, - "typeName": - { + "typeName": { "id": 7, "name": "uint", "nodeType": "ElementaryTypeName", @@ -146,8 +129,7 @@ } ], "id": 10, - "initialValue": - { + "initialValue": { "hexValue": "30", "id": 9, "kind": "number", @@ -159,17 +141,14 @@ "nodeType": "VariableDeclarationStatement", "src": "131:10:1" }, - "loopExpression": - { - "expression": - { + "loopExpression": { + "expression": { "id": 15, "nodeType": "UnaryOperation", "operator": "++", "prefix": false, "src": "151:3:1", - "subExpression": - { + "subExpression": { "id": 14, "name": "i", "nodeType": "Identifier", @@ -187,8 +166,7 @@ "src": "126:96:1" }, { - "expression": - { + "expression": { "id": 23, "name": "x", "nodeType": "Identifier", @@ -209,19 +187,16 @@ "name": "f", "nameLocation": "66:1:1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 3, "nodeType": "ParameterList", "parameters": [], "src": "67:2:1" }, - "returnParameters": - { + "returnParameters": { "id": 6, "nodeType": "ParameterList", - "parameters": - [ + "parameters": [ { "constant": false, "id": 5, @@ -233,8 +208,7 @@ "stateVariable": false, "storageLocation": "default", "typeDescriptions": {}, - "typeName": - { + "typeName": { "id": 4, "name": "uint", "nodeType": "ElementaryTypeName", diff --git a/test/libsolidity/ASTJSON/documentation_parseOnly.json b/test/libsolidity/ASTJSON/documentation_parseOnly.json index 7f446279b613..c6215818d624 100644 --- a/test/libsolidity/ASTJSON/documentation_parseOnly.json +++ b/test/libsolidity/ASTJSON/documentation_parseOnly.json @@ -3,15 +3,13 @@ "absolutePath": "a", "id": 3, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "abstract": false, "baseContracts": [], "contractDependencies": [], "contractKind": "contract", - "documentation": - { + "documentation": { "id": 1, "nodeType": "StructuredDocumentation", "src": "0:27:1", @@ -33,15 +31,13 @@ "absolutePath": "b", "id": 6, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "abstract": false, "baseContracts": [], "contractDependencies": [], "contractKind": "contract", - "documentation": - { + "documentation": { "id": 4, "nodeType": "StructuredDocumentation", "src": "0:61:2", @@ -63,8 +59,7 @@ "absolutePath": "c", "id": 24, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "abstract": false, "baseContracts": [], @@ -74,8 +69,7 @@ "name": "C", "nameLocation": "9:1:3", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { "constant": false, "id": 9, @@ -87,8 +81,7 @@ "stateVariable": false, "storageLocation": "default", "typeDescriptions": {}, - "typeName": - { + "typeName": { "id": 8, "name": "uint", "nodeType": "ElementaryTypeName", @@ -99,8 +92,7 @@ }, { "anonymous": false, - "documentation": - { + "documentation": { "id": 10, "nodeType": "StructuredDocumentation", "src": "69:26:3", @@ -110,8 +102,7 @@ "name": "Evt", "nameLocation": "102:3:3", "nodeType": "EventDefinition", - "parameters": - { + "parameters": { "id": 11, "nodeType": "ParameterList", "parameters": [], @@ -120,13 +111,11 @@ "src": "96:12:3" }, { - "body": - { + "body": { "id": 16, "nodeType": "Block", "src": "153:6:3", - "statements": - [ + "statements": [ { "id": 15, "nodeType": "PlaceholderStatement", @@ -134,8 +123,7 @@ } ] }, - "documentation": - { + "documentation": { "id": 13, "nodeType": "StructuredDocumentation", "src": "111:26:3", @@ -145,8 +133,7 @@ "name": "mod", "nameLocation": "147:3:3", "nodeType": "ModifierDefinition", - "parameters": - { + "parameters": { "id": 14, "nodeType": "ParameterList", "parameters": [], @@ -157,15 +144,13 @@ "visibility": "internal" }, { - "body": - { + "body": { "id": 21, "nodeType": "Block", "src": "209:2:3", "statements": [] }, - "documentation": - { + "documentation": { "id": 18, "nodeType": "StructuredDocumentation", "src": "162:25:3", @@ -178,15 +163,13 @@ "name": "fn", "nameLocation": "197:2:3", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 19, "nodeType": "ParameterList", "parameters": [], "src": "199:2:3" }, - "returnParameters": - { + "returnParameters": { "id": 20, "nodeType": "ParameterList", "parameters": [], diff --git a/test/libsolidity/ASTJSON/documentation_triple.json b/test/libsolidity/ASTJSON/documentation_triple.json index cd44bd4eb60d..bc3c3d8878cd 100644 --- a/test/libsolidity/ASTJSON/documentation_triple.json +++ b/test/libsolidity/ASTJSON/documentation_triple.json @@ -1,16 +1,13 @@ { "absolutePath": "a", - "exportedSymbols": - { - "C": - [ + "exportedSymbols": { + "C": [ 28 ] }, "id": 29, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "abstract": false, "baseContracts": [], @@ -19,19 +16,16 @@ "contractKind": "contract", "fullyImplemented": true, "id": 28, - "linearizedBaseContracts": - [ + "linearizedBaseContracts": [ 28 ], "name": "C", "nameLocation": "9:1:1", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { "constant": false, - "documentation": - { + "documentation": { "id": 1, "nodeType": "StructuredDocumentation", "src": "17:8:1", @@ -46,19 +40,16 @@ "src": "30:6:1", "stateVariable": true, "storageLocation": "default", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_uint256", "typeString": "uint256" }, - "typeName": - { + "typeName": { "id": 2, "name": "uint", "nodeType": "ElementaryTypeName", "src": "30:4:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_uint256", "typeString": "uint256" } @@ -66,48 +57,40 @@ "visibility": "internal" }, { - "body": - { + "body": { "id": 26, "nodeType": "Block", "src": "84:181:1", - "statements": - [ + "statements": [ { - "body": - { + "body": { "id": 22, "nodeType": "Block", "src": "142:75:1", - "statements": - [ + "statements": [ { "documentation": "tee\n s \"t\" 3", - "expression": - { + "expression": { "id": 20, "isConstant": false, "isLValue": false, "isPure": false, "lValueRequested": false, - "leftHandSide": - { + "leftHandSide": { "id": 18, "name": "x", "nodeType": "Identifier", "overloadedDeclarations": [], "referencedDeclaration": 6, "src": "200:1:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_uint256", "typeString": "uint256" } }, "nodeType": "Assignment", "operator": "*=", - "rightHandSide": - { + "rightHandSide": { "hexValue": "32", "id": 19, "isConstant": false, @@ -117,16 +100,14 @@ "lValueRequested": false, "nodeType": "Literal", "src": "205:1:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_rational_2_by_1", "typeString": "int_const 2" }, "value": "2" }, "src": "200:6:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_uint256", "typeString": "uint256" } @@ -137,10 +118,8 @@ } ] }, - "condition": - { - "commonType": - { + "condition": { + "commonType": { "typeIdentifier": "t_uint256", "typeString": "uint256" }, @@ -149,24 +128,21 @@ "isLValue": false, "isPure": false, "lValueRequested": false, - "leftExpression": - { + "leftExpression": { "id": 12, "name": "i", "nodeType": "Identifier", "overloadedDeclarations": [], "referencedDeclaration": 9, "src": "129:1:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_uint256", "typeString": "uint256" } }, "nodeType": "BinaryOperation", "operator": "<", - "rightExpression": - { + "rightExpression": { "hexValue": "3230", "id": 13, "isConstant": false, @@ -176,30 +152,25 @@ "lValueRequested": false, "nodeType": "Literal", "src": "133:2:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_rational_20_by_1", "typeString": "int_const 20" }, "value": "20" }, "src": "129:6:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_bool", "typeString": "bool" } }, "documentation": "test2", "id": 23, - "initializationExpression": - { - "assignments": - [ + "initializationExpression": { + "assignments": [ 9 ], - "declarations": - [ + "declarations": [ { "constant": false, "id": 9, @@ -211,19 +182,16 @@ "src": "117:6:1", "stateVariable": false, "storageLocation": "default", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_uint256", "typeString": "uint256" }, - "typeName": - { + "typeName": { "id": 8, "name": "uint", "nodeType": "ElementaryTypeName", "src": "117:4:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_uint256", "typeString": "uint256" } @@ -232,8 +200,7 @@ } ], "id": 11, - "initialValue": - { + "initialValue": { "hexValue": "30", "id": 10, "isConstant": false, @@ -243,8 +210,7 @@ "lValueRequested": false, "nodeType": "Literal", "src": "126:1:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_rational_0_by_1", "typeString": "int_const 0" }, @@ -254,10 +220,8 @@ "src": "117:10:1" }, "isSimpleCounterLoop": true, - "loopExpression": - { - "expression": - { + "loopExpression": { + "expression": { "id": 16, "isConstant": false, "isLValue": false, @@ -267,22 +231,19 @@ "operator": "++", "prefix": false, "src": "137:3:1", - "subExpression": - { + "subExpression": { "id": 15, "name": "i", "nodeType": "Identifier", "overloadedDeclarations": [], "referencedDeclaration": 9, "src": "137:1:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_uint256", "typeString": "uint256" } }, - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_uint256", "typeString": "uint256" } @@ -296,16 +257,14 @@ }, { "documentation": "tes \"t4\" ", - "expression": - { + "expression": { "id": 24, "name": "x", "nodeType": "Identifier", "overloadedDeclarations": [], "referencedDeclaration": 6, "src": "257:1:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_uint256", "typeString": "uint256" } @@ -325,19 +284,16 @@ "name": "f", "nameLocation": "51:1:1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 4, "nodeType": "ParameterList", "parameters": [], "src": "52:2:1" }, - "returnParameters": - { + "returnParameters": { "id": 7, "nodeType": "ParameterList", - "parameters": - [ + "parameters": [ { "constant": false, "id": 6, @@ -349,19 +305,16 @@ "src": "76:6:1", "stateVariable": false, "storageLocation": "default", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_uint256", "typeString": "uint256" }, - "typeName": - { + "typeName": { "id": 5, "name": "uint", "nodeType": "ElementaryTypeName", "src": "76:4:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_uint256", "typeString": "uint256" } diff --git a/test/libsolidity/ASTJSON/documentation_triple_parseOnly.json b/test/libsolidity/ASTJSON/documentation_triple_parseOnly.json index 5ccc2631ca99..7f24ded91141 100644 --- a/test/libsolidity/ASTJSON/documentation_triple_parseOnly.json +++ b/test/libsolidity/ASTJSON/documentation_triple_parseOnly.json @@ -2,8 +2,7 @@ "absolutePath": "a", "id": 29, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "abstract": false, "baseContracts": [], @@ -13,8 +12,7 @@ "name": "C", "nameLocation": "9:1:1", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { "constant": false, "id": 3, @@ -26,8 +24,7 @@ "stateVariable": false, "storageLocation": "default", "typeDescriptions": {}, - "typeName": - { + "typeName": { "id": 2, "name": "uint", "nodeType": "ElementaryTypeName", @@ -37,28 +34,22 @@ "visibility": "internal" }, { - "body": - { + "body": { "id": 26, "nodeType": "Block", "src": "84:181:1", - "statements": - [ + "statements": [ { - "body": - { + "body": { "id": 22, "nodeType": "Block", "src": "142:75:1", - "statements": - [ + "statements": [ { "documentation": "tee\n s \"t\" 3", - "expression": - { + "expression": { "id": 20, - "leftHandSide": - { + "leftHandSide": { "id": 18, "name": "x", "nodeType": "Identifier", @@ -68,8 +59,7 @@ }, "nodeType": "Assignment", "operator": "*=", - "rightHandSide": - { + "rightHandSide": { "hexValue": "32", "id": 19, "kind": "number", @@ -87,12 +77,10 @@ } ] }, - "condition": - { + "condition": { "commonType": {}, "id": 14, - "leftExpression": - { + "leftExpression": { "id": 12, "name": "i", "nodeType": "Identifier", @@ -102,8 +90,7 @@ }, "nodeType": "BinaryOperation", "operator": "<", - "rightExpression": - { + "rightExpression": { "hexValue": "3230", "id": 13, "kind": "number", @@ -117,14 +104,11 @@ }, "documentation": "test2", "id": 23, - "initializationExpression": - { - "assignments": - [ + "initializationExpression": { + "assignments": [ 9 ], - "declarations": - [ + "declarations": [ { "constant": false, "id": 9, @@ -136,8 +120,7 @@ "stateVariable": false, "storageLocation": "default", "typeDescriptions": {}, - "typeName": - { + "typeName": { "id": 8, "name": "uint", "nodeType": "ElementaryTypeName", @@ -148,8 +131,7 @@ } ], "id": 11, - "initialValue": - { + "initialValue": { "hexValue": "30", "id": 10, "kind": "number", @@ -161,17 +143,14 @@ "nodeType": "VariableDeclarationStatement", "src": "117:10:1" }, - "loopExpression": - { - "expression": - { + "loopExpression": { + "expression": { "id": 16, "nodeType": "UnaryOperation", "operator": "++", "prefix": false, "src": "137:3:1", - "subExpression": - { + "subExpression": { "id": 15, "name": "i", "nodeType": "Identifier", @@ -190,8 +169,7 @@ }, { "documentation": "tes \"t4\" ", - "expression": - { + "expression": { "id": 24, "name": "x", "nodeType": "Identifier", @@ -212,19 +190,16 @@ "name": "f", "nameLocation": "51:1:1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 4, "nodeType": "ParameterList", "parameters": [], "src": "52:2:1" }, - "returnParameters": - { + "returnParameters": { "id": 7, "nodeType": "ParameterList", - "parameters": - [ + "parameters": [ { "constant": false, "id": 6, @@ -236,8 +211,7 @@ "stateVariable": false, "storageLocation": "default", "typeDescriptions": {}, - "typeName": - { + "typeName": { "id": 5, "name": "uint", "nodeType": "ElementaryTypeName", diff --git a/test/libsolidity/ASTJSON/enum_natspec.json b/test/libsolidity/ASTJSON/enum_natspec.json index f3cc7b8df8aa..e55e3705d22d 100644 --- a/test/libsolidity/ASTJSON/enum_natspec.json +++ b/test/libsolidity/ASTJSON/enum_natspec.json @@ -1,28 +1,23 @@ { "absolutePath": "a", - "exportedSymbols": - { - "Color": - [ + "exportedSymbols": { + "Color": [ 4 ] }, "id": 5, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "canonicalName": "Color", - "documentation": - { + "documentation": { "id": 1, "nodeType": "StructuredDocumentation", "src": "0:112:1", "text": "@title example of title\n @author example of author\n @notice example of notice\n @dev example of dev" }, "id": 4, - "members": - [ + "members": [ { "id": 2, "name": "Red", diff --git a/test/libsolidity/ASTJSON/enum_natspec_parseOnly.json b/test/libsolidity/ASTJSON/enum_natspec_parseOnly.json index b5a38af6c449..723df77c1ff5 100644 --- a/test/libsolidity/ASTJSON/enum_natspec_parseOnly.json +++ b/test/libsolidity/ASTJSON/enum_natspec_parseOnly.json @@ -2,19 +2,16 @@ "absolutePath": "a", "id": 5, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { - "documentation": - { + "documentation": { "id": 1, "nodeType": "StructuredDocumentation", "src": "0:112:1", "text": "@title example of title\n @author example of author\n @notice example of notice\n @dev example of dev" }, "id": 4, - "members": - [ + "members": [ { "id": 2, "name": "Red", diff --git a/test/libsolidity/ASTJSON/enum_value.json b/test/libsolidity/ASTJSON/enum_value.json index 31615f657b6a..de507a79ef48 100644 --- a/test/libsolidity/ASTJSON/enum_value.json +++ b/test/libsolidity/ASTJSON/enum_value.json @@ -1,16 +1,13 @@ { "absolutePath": "a", - "exportedSymbols": - { - "C": - [ + "exportedSymbols": { + "C": [ 4 ] }, "id": 5, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "abstract": false, "baseContracts": [], @@ -19,20 +16,17 @@ "contractKind": "contract", "fullyImplemented": true, "id": 4, - "linearizedBaseContracts": - [ + "linearizedBaseContracts": [ 4 ], "name": "C", "nameLocation": "9:1:1", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { "canonicalName": "C.E", "id": 3, - "members": - [ + "members": [ { "id": 1, "name": "A", diff --git a/test/libsolidity/ASTJSON/enum_value_declaration.json b/test/libsolidity/ASTJSON/enum_value_declaration.json index acdcc736e25e..324911fa90f8 100644 --- a/test/libsolidity/ASTJSON/enum_value_declaration.json +++ b/test/libsolidity/ASTJSON/enum_value_declaration.json @@ -1,25 +1,20 @@ { "absolutePath": "a", - "exportedSymbols": - { - "A": - [ + "exportedSymbols": { + "A": [ 3 ], - "f": - [ + "f": [ 13 ] }, "id": 14, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "canonicalName": "A", "id": 3, - "members": - [ + "members": [ { "id": 1, "name": "X", @@ -41,26 +36,21 @@ "src": "0:15:1" }, { - "body": - { + "body": { "id": 12, "nodeType": "Block", "src": "46:15:1", - "statements": - [ + "statements": [ { - "expression": - { - "expression": - { + "expression": { + "expression": { "id": 9, "name": "A", "nodeType": "Identifier", "overloadedDeclarations": [], "referencedDeclaration": 3, "src": "55:1:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_type$_t_enum$_A_$3_$", "typeString": "type(enum A)" } @@ -75,8 +65,7 @@ "nodeType": "MemberAccess", "referencedDeclaration": 1, "src": "55:3:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_enum$_A_$3", "typeString": "enum A" } @@ -95,19 +84,16 @@ "name": "f", "nameLocation": "25:1:1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 4, "nodeType": "ParameterList", "parameters": [], "src": "26:2:1" }, - "returnParameters": - { + "returnParameters": { "id": 8, "nodeType": "ParameterList", - "parameters": - [ + "parameters": [ { "constant": false, "id": 7, @@ -119,21 +105,17 @@ "src": "43:1:1", "stateVariable": false, "storageLocation": "default", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_enum$_A_$3", "typeString": "enum A" }, - "typeName": - { + "typeName": { "id": 6, "nodeType": "UserDefinedTypeName", - "pathNode": - { + "pathNode": { "id": 5, "name": "A", - "nameLocations": - [ + "nameLocations": [ "43:1:1" ], "nodeType": "IdentifierPath", @@ -142,8 +124,7 @@ }, "referencedDeclaration": 3, "src": "43:1:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_enum$_A_$3", "typeString": "enum A" } diff --git a/test/libsolidity/ASTJSON/enum_value_declaration_parseOnly.json b/test/libsolidity/ASTJSON/enum_value_declaration_parseOnly.json index 8fa574fa74d6..93499e815628 100644 --- a/test/libsolidity/ASTJSON/enum_value_declaration_parseOnly.json +++ b/test/libsolidity/ASTJSON/enum_value_declaration_parseOnly.json @@ -2,12 +2,10 @@ "absolutePath": "a", "id": 14, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "id": 3, - "members": - [ + "members": [ { "id": 1, "name": "X", @@ -29,18 +27,14 @@ "src": "0:15:1" }, { - "body": - { + "body": { "id": 12, "nodeType": "Block", "src": "46:15:1", - "statements": - [ + "statements": [ { - "expression": - { - "expression": - { + "expression": { + "expression": { "id": 9, "name": "A", "nodeType": "Identifier", @@ -68,19 +62,16 @@ "name": "f", "nameLocation": "25:1:1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 4, "nodeType": "ParameterList", "parameters": [], "src": "26:2:1" }, - "returnParameters": - { + "returnParameters": { "id": 8, "nodeType": "ParameterList", - "parameters": - [ + "parameters": [ { "constant": false, "id": 7, @@ -92,16 +83,13 @@ "stateVariable": false, "storageLocation": "default", "typeDescriptions": {}, - "typeName": - { + "typeName": { "id": 6, "nodeType": "UserDefinedTypeName", - "pathNode": - { + "pathNode": { "id": 5, "name": "A", - "nameLocations": - [ + "nameLocations": [ "43:1:1" ], "nodeType": "IdentifierPath", diff --git a/test/libsolidity/ASTJSON/enum_value_parseOnly.json b/test/libsolidity/ASTJSON/enum_value_parseOnly.json index 006e2db36077..564c71273eff 100644 --- a/test/libsolidity/ASTJSON/enum_value_parseOnly.json +++ b/test/libsolidity/ASTJSON/enum_value_parseOnly.json @@ -2,8 +2,7 @@ "absolutePath": "a", "id": 5, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "abstract": false, "baseContracts": [], @@ -13,12 +12,10 @@ "name": "C", "nameLocation": "9:1:1", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { "id": 3, - "members": - [ + "members": [ { "id": 1, "name": "A", diff --git a/test/libsolidity/ASTJSON/event_aggregated_contract.json b/test/libsolidity/ASTJSON/event_aggregated_contract.json index e312320c126a..d1bf17c75b29 100644 --- a/test/libsolidity/ASTJSON/event_aggregated_contract.json +++ b/test/libsolidity/ASTJSON/event_aggregated_contract.json @@ -1,20 +1,16 @@ { "absolutePath": "a", - "exportedSymbols": - { - "C": - [ + "exportedSymbols": { + "C": [ 10 ], - "D": - [ + "D": [ 30 ] }, "id": 31, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "abstract": false, "baseContracts": [], @@ -23,15 +19,13 @@ "contractKind": "contract", "fullyImplemented": true, "id": 10, - "linearizedBaseContracts": - [ + "linearizedBaseContracts": [ 10 ], "name": "C", "nameLocation": "9:1:1", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { "anonymous": false, "eventSelector": "ffae15ba29768297c9b951e2e14bc33dc84599d1572acc234266fc70392babc8", @@ -39,8 +33,7 @@ "name": "e", "nameLocation": "23:1:1", "nodeType": "EventDefinition", - "parameters": - { + "parameters": { "id": 1, "nodeType": "ParameterList", "parameters": [], @@ -49,19 +42,15 @@ "src": "17:10:1" }, { - "body": - { + "body": { "id": 8, "nodeType": "Block", "src": "52:25:1", - "statements": - [ + "statements": [ { - "eventCall": - { + "eventCall": { "arguments": [], - "expression": - { + "expression": { "argumentTypes": [], "id": 5, "name": "e", @@ -69,8 +58,7 @@ "overloadedDeclarations": [], "referencedDeclaration": 2, "src": "67:1:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_function_event_nonpayable$__$returns$__$", "typeString": "function ()" } @@ -86,8 +74,7 @@ "nodeType": "FunctionCall", "src": "67:3:1", "tryCall": false, - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_tuple$__$", "typeString": "tuple()" } @@ -106,15 +93,13 @@ "name": "f", "nameLocation": "41:1:1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 3, "nodeType": "ParameterList", "parameters": [], "src": "42:2:1" }, - "returnParameters": - { + "returnParameters": { "id": 4, "nodeType": "ParameterList", "parameters": [], @@ -130,8 +115,7 @@ "scope": 31, "src": "0:79:1", "usedErrors": [], - "usedEvents": - [ + "usedEvents": [ 2 ] }, @@ -139,22 +123,19 @@ "abstract": false, "baseContracts": [], "canonicalName": "D", - "contractDependencies": - [ + "contractDependencies": [ 10 ], "contractKind": "contract", "fullyImplemented": true, "id": 30, - "linearizedBaseContracts": - [ + "linearizedBaseContracts": [ 30 ], "name": "D", "nameLocation": "89:1:1", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { "constant": false, "id": 13, @@ -166,21 +147,17 @@ "src": "97:3:1", "stateVariable": true, "storageLocation": "default", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_contract$_C_$10", "typeString": "contract C" }, - "typeName": - { + "typeName": { "id": 12, "nodeType": "UserDefinedTypeName", - "pathNode": - { + "pathNode": { "id": 11, "name": "C", - "nameLocations": - [ + "nameLocations": [ "97:1:1" ], "nodeType": "IdentifierPath", @@ -189,8 +166,7 @@ }, "referencedDeclaration": 10, "src": "97:1:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_contract$_C_$10", "typeString": "contract C" } @@ -198,42 +174,35 @@ "visibility": "internal" }, { - "body": - { + "body": { "id": 28, "nodeType": "Block", "src": "120:43:1", - "statements": - [ + "statements": [ { - "expression": - { + "expression": { "id": 21, "isConstant": false, "isLValue": false, "isPure": false, "lValueRequested": false, - "leftHandSide": - { + "leftHandSide": { "id": 16, "name": "c", "nodeType": "Identifier", "overloadedDeclarations": [], "referencedDeclaration": 13, "src": "130:1:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_contract$_C_$10", "typeString": "contract C" } }, "nodeType": "Assignment", "operator": "=", - "rightHandSide": - { + "rightHandSide": { "arguments": [], - "expression": - { + "expression": { "argumentTypes": [], "id": 19, "isConstant": false, @@ -242,21 +211,17 @@ "lValueRequested": false, "nodeType": "NewExpression", "src": "134:5:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_function_creation_nonpayable$__$returns$_t_contract$_C_$10_$", "typeString": "function () returns (contract C)" }, - "typeName": - { + "typeName": { "id": 18, "nodeType": "UserDefinedTypeName", - "pathNode": - { + "pathNode": { "id": 17, "name": "C", - "nameLocations": - [ + "nameLocations": [ "138:1:1" ], "nodeType": "IdentifierPath", @@ -265,8 +230,7 @@ }, "referencedDeclaration": 10, "src": "138:1:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_contract$_C_$10", "typeString": "contract C" } @@ -283,15 +247,13 @@ "nodeType": "FunctionCall", "src": "134:7:1", "tryCall": false, - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_contract$_C_$10", "typeString": "contract C" } }, "src": "130:11:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_contract$_C_$10", "typeString": "contract C" } @@ -301,22 +263,18 @@ "src": "130:11:1" }, { - "expression": - { + "expression": { "arguments": [], - "expression": - { + "expression": { "argumentTypes": [], - "expression": - { + "expression": { "id": 23, "name": "c", "nodeType": "Identifier", "overloadedDeclarations": [], "referencedDeclaration": 13, "src": "151:1:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_contract$_C_$10", "typeString": "contract C" } @@ -331,8 +289,7 @@ "nodeType": "MemberAccess", "referencedDeclaration": 9, "src": "151:3:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_function_external_nonpayable$__$returns$__$", "typeString": "function () external" } @@ -348,8 +305,7 @@ "nodeType": "FunctionCall", "src": "151:5:1", "tryCall": false, - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_tuple$__$", "typeString": "tuple()" } @@ -367,15 +323,13 @@ "name": "", "nameLocation": "-1:-1:-1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 14, "nodeType": "ParameterList", "parameters": [], "src": "117:2:1" }, - "returnParameters": - { + "returnParameters": { "id": 15, "nodeType": "ParameterList", "parameters": [], diff --git a/test/libsolidity/ASTJSON/event_definition.json b/test/libsolidity/ASTJSON/event_definition.json index b59164fcb049..cdbe3041eb35 100644 --- a/test/libsolidity/ASTJSON/event_definition.json +++ b/test/libsolidity/ASTJSON/event_definition.json @@ -1,16 +1,13 @@ { "absolutePath": "a", - "exportedSymbols": - { - "C": - [ + "exportedSymbols": { + "C": [ 3 ] }, "id": 4, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "abstract": false, "baseContracts": [], @@ -19,15 +16,13 @@ "contractKind": "contract", "fullyImplemented": true, "id": 3, - "linearizedBaseContracts": - [ + "linearizedBaseContracts": [ 3 ], "name": "C", "nameLocation": "9:1:1", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { "anonymous": false, "eventSelector": "92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028", @@ -35,8 +30,7 @@ "name": "E", "nameLocation": "19:1:1", "nodeType": "EventDefinition", - "parameters": - { + "parameters": { "id": 1, "nodeType": "ParameterList", "parameters": [], @@ -48,8 +42,7 @@ "scope": 4, "src": "0:25:1", "usedErrors": [], - "usedEvents": - [ + "usedEvents": [ 2 ] } diff --git a/test/libsolidity/ASTJSON/event_definition_parseOnly.json b/test/libsolidity/ASTJSON/event_definition_parseOnly.json index 9116b3d2da28..25745fdc6e12 100644 --- a/test/libsolidity/ASTJSON/event_definition_parseOnly.json +++ b/test/libsolidity/ASTJSON/event_definition_parseOnly.json @@ -2,8 +2,7 @@ "absolutePath": "a", "id": 4, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "abstract": false, "baseContracts": [], @@ -13,16 +12,14 @@ "name": "C", "nameLocation": "9:1:1", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { "anonymous": false, "id": 2, "name": "E", "nameLocation": "19:1:1", "nodeType": "EventDefinition", - "parameters": - { + "parameters": { "id": 1, "nodeType": "ParameterList", "parameters": [], diff --git a/test/libsolidity/ASTJSON/event_emited_in_base_contract.json b/test/libsolidity/ASTJSON/event_emited_in_base_contract.json index 6b183b493111..40bb3bae44aa 100644 --- a/test/libsolidity/ASTJSON/event_emited_in_base_contract.json +++ b/test/libsolidity/ASTJSON/event_emited_in_base_contract.json @@ -1,24 +1,19 @@ { "absolutePath": "a", - "exportedSymbols": - { - "B": - [ + "exportedSymbols": { + "B": [ 16 ], - "C": - [ + "C": [ 19 ], - "L": - [ + "L": [ 5 ] }, "id": 20, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "abstract": false, "baseContracts": [], @@ -27,15 +22,13 @@ "contractKind": "library", "fullyImplemented": true, "id": 5, - "linearizedBaseContracts": - [ + "linearizedBaseContracts": [ 5 ], "name": "L", "nameLocation": "10:1:1", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { "anonymous": false, "eventSelector": "870e3024466c178150e2490c7cfb455e33c0db877113af040f89189d07946664", @@ -43,12 +36,10 @@ "name": "E", "nameLocation": "20:1:1", "nodeType": "EventDefinition", - "parameters": - { + "parameters": { "id": 3, "nodeType": "ParameterList", - "parameters": - [ + "parameters": [ { "constant": false, "id": 2, @@ -61,19 +52,16 @@ "src": "22:5:1", "stateVariable": false, "storageLocation": "default", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_uint8", "typeString": "uint8" }, - "typeName": - { + "typeName": { "id": 1, "name": "uint8", "nodeType": "ElementaryTypeName", "src": "22:5:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_uint8", "typeString": "uint8" } @@ -89,8 +77,7 @@ "scope": 20, "src": "0:31:1", "usedErrors": [], - "usedEvents": - [ + "usedEvents": [ 4 ] }, @@ -102,28 +89,22 @@ "contractKind": "contract", "fullyImplemented": true, "id": 16, - "linearizedBaseContracts": - [ + "linearizedBaseContracts": [ 16 ], "name": "B", "nameLocation": "41:1:1", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { - "body": - { + "body": { "id": 14, "nodeType": "Block", "src": "63:28:1", - "statements": - [ + "statements": [ { - "eventCall": - { - "arguments": - [ + "eventCall": { + "arguments": [ { "hexValue": "30", "id": 11, @@ -134,33 +115,28 @@ "lValueRequested": false, "nodeType": "Literal", "src": "82:1:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_rational_0_by_1", "typeString": "int_const 0" }, "value": "0" } ], - "expression": - { - "argumentTypes": - [ + "expression": { + "argumentTypes": [ { "typeIdentifier": "t_rational_0_by_1", "typeString": "int_const 0" } ], - "expression": - { + "expression": { "id": 8, "name": "L", "nodeType": "Identifier", "overloadedDeclarations": [], "referencedDeclaration": 5, "src": "78:1:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_type$_t_contract$_L_$5_$", "typeString": "type(library L)" } @@ -175,8 +151,7 @@ "nodeType": "MemberAccess", "referencedDeclaration": 4, "src": "78:3:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_function_event_nonpayable$_t_uint8_$returns$__$", "typeString": "function (uint8)" } @@ -192,8 +167,7 @@ "nodeType": "FunctionCall", "src": "78:6:1", "tryCall": false, - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_tuple$__$", "typeString": "tuple()" } @@ -211,15 +185,13 @@ "name": "", "nameLocation": "-1:-1:-1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 6, "nodeType": "ParameterList", "parameters": [], "src": "60:2:1" }, - "returnParameters": - { + "returnParameters": { "id": 7, "nodeType": "ParameterList", "parameters": [], @@ -235,22 +207,18 @@ "scope": 20, "src": "32:61:1", "usedErrors": [], - "usedEvents": - [ + "usedEvents": [ 4 ] }, { "abstract": false, - "baseContracts": - [ + "baseContracts": [ { - "baseName": - { + "baseName": { "id": 17, "name": "B", - "nameLocations": - [ + "nameLocations": [ "108:1:1" ], "nodeType": "IdentifierPath", @@ -267,8 +235,7 @@ "contractKind": "contract", "fullyImplemented": true, "id": 19, - "linearizedBaseContracts": - [ + "linearizedBaseContracts": [ 19, 16 ], @@ -279,8 +246,7 @@ "scope": 20, "src": "94:18:1", "usedErrors": [], - "usedEvents": - [ + "usedEvents": [ 4 ] } diff --git a/test/libsolidity/ASTJSON/event_emitted_from_foreign_contract.json b/test/libsolidity/ASTJSON/event_emitted_from_foreign_contract.json index 2d70e2f9feb8..92de58cf8b2a 100644 --- a/test/libsolidity/ASTJSON/event_emitted_from_foreign_contract.json +++ b/test/libsolidity/ASTJSON/event_emitted_from_foreign_contract.json @@ -1,20 +1,16 @@ { "absolutePath": "a", - "exportedSymbols": - { - "C": - [ + "exportedSymbols": { + "C": [ 5 ], - "D": - [ + "D": [ 19 ] }, "id": 20, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "abstract": false, "baseContracts": [], @@ -23,15 +19,13 @@ "contractKind": "contract", "fullyImplemented": true, "id": 5, - "linearizedBaseContracts": - [ + "linearizedBaseContracts": [ 5 ], "name": "C", "nameLocation": "9:1:1", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { "anonymous": false, "eventSelector": "bd1155618a34fd53d1a2de9f705f42f3582842cba0b985b25c59888d86e0c929", @@ -39,12 +33,10 @@ "name": "E", "nameLocation": "23:1:1", "nodeType": "EventDefinition", - "parameters": - { + "parameters": { "id": 3, "nodeType": "ParameterList", - "parameters": - [ + "parameters": [ { "constant": false, "id": 2, @@ -57,20 +49,17 @@ "src": "25:22:1", "stateVariable": false, "storageLocation": "default", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_address", "typeString": "address" }, - "typeName": - { + "typeName": { "id": 1, "name": "address", "nodeType": "ElementaryTypeName", "src": "25:7:1", "stateMutability": "nonpayable", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_address", "typeString": "address" } @@ -86,8 +75,7 @@ "scope": 20, "src": "0:51:1", "usedErrors": [], - "usedEvents": - [ + "usedEvents": [ 4 ] }, @@ -99,39 +87,31 @@ "contractKind": "contract", "fullyImplemented": true, "id": 19, - "linearizedBaseContracts": - [ + "linearizedBaseContracts": [ 19 ], "name": "D", "nameLocation": "61:1:1", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { - "body": - { + "body": { "id": 17, "nodeType": "Block", "src": "106:37:1", - "statements": - [ + "statements": [ { - "eventCall": - { - "arguments": - [ + "eventCall": { + "arguments": [ { - "expression": - { + "expression": { "id": 13, "name": "msg", "nodeType": "Identifier", "overloadedDeclarations": [], "referencedDeclaration": -15, "src": "125:3:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_magic_message", "typeString": "msg" } @@ -145,32 +125,27 @@ "memberName": "sender", "nodeType": "MemberAccess", "src": "125:10:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_address", "typeString": "address" } } ], - "expression": - { - "argumentTypes": - [ + "expression": { + "argumentTypes": [ { "typeIdentifier": "t_address", "typeString": "address" } ], - "expression": - { + "expression": { "id": 10, "name": "C", "nodeType": "Identifier", "overloadedDeclarations": [], "referencedDeclaration": 5, "src": "121:1:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_type$_t_contract$_C_$5_$", "typeString": "type(contract C)" } @@ -185,8 +160,7 @@ "nodeType": "MemberAccess", "referencedDeclaration": 4, "src": "121:3:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_function_event_nonpayable$_t_address_$returns$__$", "typeString": "function (address)" } @@ -202,8 +176,7 @@ "nodeType": "FunctionCall", "src": "121:15:1", "tryCall": false, - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_tuple$__$", "typeString": "tuple()" } @@ -222,12 +195,10 @@ "name": "test", "nameLocation": "78:4:1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 8, "nodeType": "ParameterList", - "parameters": - [ + "parameters": [ { "constant": false, "id": 7, @@ -239,20 +210,17 @@ "src": "83:14:1", "stateVariable": false, "storageLocation": "default", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_address", "typeString": "address" }, - "typeName": - { + "typeName": { "id": 6, "name": "address", "nodeType": "ElementaryTypeName", "src": "83:7:1", "stateMutability": "nonpayable", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_address", "typeString": "address" } @@ -262,8 +230,7 @@ ], "src": "82:16:1" }, - "returnParameters": - { + "returnParameters": { "id": 9, "nodeType": "ParameterList", "parameters": [], @@ -279,8 +246,7 @@ "scope": 20, "src": "52:93:1", "usedErrors": [], - "usedEvents": - [ + "usedEvents": [ 4 ] } diff --git a/test/libsolidity/ASTJSON/event_emitted_from_foreign_contract_parseOnly.json b/test/libsolidity/ASTJSON/event_emitted_from_foreign_contract_parseOnly.json index b6c0ca5e0315..60ccdff44c14 100644 --- a/test/libsolidity/ASTJSON/event_emitted_from_foreign_contract_parseOnly.json +++ b/test/libsolidity/ASTJSON/event_emitted_from_foreign_contract_parseOnly.json @@ -2,8 +2,7 @@ "absolutePath": "a", "id": 20, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "abstract": false, "baseContracts": [], @@ -13,20 +12,17 @@ "name": "C", "nameLocation": "9:1:1", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { "anonymous": false, "id": 4, "name": "E", "nameLocation": "23:1:1", "nodeType": "EventDefinition", - "parameters": - { + "parameters": { "id": 3, "nodeType": "ParameterList", - "parameters": - [ + "parameters": [ { "constant": false, "id": 2, @@ -39,8 +35,7 @@ "stateVariable": false, "storageLocation": "default", "typeDescriptions": {}, - "typeName": - { + "typeName": { "id": 1, "name": "address", "nodeType": "ElementaryTypeName", @@ -69,24 +64,18 @@ "name": "D", "nameLocation": "61:1:1", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { - "body": - { + "body": { "id": 17, "nodeType": "Block", "src": "106:37:1", - "statements": - [ + "statements": [ { - "eventCall": - { - "arguments": - [ + "eventCall": { + "arguments": [ { - "expression": - { + "expression": { "id": 13, "name": "msg", "nodeType": "Identifier", @@ -102,10 +91,8 @@ "typeDescriptions": {} } ], - "expression": - { - "expression": - { + "expression": { + "expression": { "id": 10, "name": "C", "nodeType": "Identifier", @@ -141,12 +128,10 @@ "name": "test", "nameLocation": "78:4:1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 8, "nodeType": "ParameterList", - "parameters": - [ + "parameters": [ { "constant": false, "id": 7, @@ -158,8 +143,7 @@ "stateVariable": false, "storageLocation": "default", "typeDescriptions": {}, - "typeName": - { + "typeName": { "id": 6, "name": "address", "nodeType": "ElementaryTypeName", @@ -172,8 +156,7 @@ ], "src": "82:16:1" }, - "returnParameters": - { + "returnParameters": { "id": 9, "nodeType": "ParameterList", "parameters": [], diff --git a/test/libsolidity/ASTJSON/event_inheritance.json b/test/libsolidity/ASTJSON/event_inheritance.json index afa79e916c3c..d9a78da03a67 100644 --- a/test/libsolidity/ASTJSON/event_inheritance.json +++ b/test/libsolidity/ASTJSON/event_inheritance.json @@ -1,24 +1,19 @@ { "absolutePath": "a", - "exportedSymbols": - { - "B": - [ + "exportedSymbols": { + "B": [ 3 ], - "C": - [ + "C": [ 8 ], - "D": - [ + "D": [ 13 ] }, "id": 14, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "abstract": false, "baseContracts": [], @@ -27,15 +22,13 @@ "contractKind": "interface", "fullyImplemented": true, "id": 3, - "linearizedBaseContracts": - [ + "linearizedBaseContracts": [ 3 ], "name": "B", "nameLocation": "10:1:1", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { "anonymous": false, "eventSelector": "dbec0351ad6bb0c1f07ea56e236e3e692fde2259f0165fd422f241da339b7e4f", @@ -43,8 +36,7 @@ "name": "EB", "nameLocation": "24:2:1", "nodeType": "EventDefinition", - "parameters": - { + "parameters": { "id": 1, "nodeType": "ParameterList", "parameters": [], @@ -56,22 +48,18 @@ "scope": 14, "src": "0:31:1", "usedErrors": [], - "usedEvents": - [ + "usedEvents": [ 2 ] }, { "abstract": false, - "baseContracts": - [ + "baseContracts": [ { - "baseName": - { + "baseName": { "id": 4, "name": "B", - "nameLocations": - [ + "nameLocations": [ "46:1:1" ], "nodeType": "IdentifierPath", @@ -88,16 +76,14 @@ "contractKind": "contract", "fullyImplemented": true, "id": 8, - "linearizedBaseContracts": - [ + "linearizedBaseContracts": [ 8, 3 ], "name": "C", "nameLocation": "41:1:1", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { "anonymous": false, "eventSelector": "a08b3367d3fa83ea27f8951ffb5d9d160cbfadbd80816b47f677e7699d76f5a0", @@ -105,8 +91,7 @@ "name": "EC", "nameLocation": "60:2:1", "nodeType": "EventDefinition", - "parameters": - { + "parameters": { "id": 6, "nodeType": "ParameterList", "parameters": [], @@ -118,23 +103,19 @@ "scope": 14, "src": "32:35:1", "usedErrors": [], - "usedEvents": - [ + "usedEvents": [ 2, 7 ] }, { "abstract": false, - "baseContracts": - [ + "baseContracts": [ { - "baseName": - { + "baseName": { "id": 9, "name": "C", - "nameLocations": - [ + "nameLocations": [ "82:1:1" ], "nodeType": "IdentifierPath", @@ -151,8 +132,7 @@ "contractKind": "contract", "fullyImplemented": true, "id": 13, - "linearizedBaseContracts": - [ + "linearizedBaseContracts": [ 13, 8, 3 @@ -160,8 +140,7 @@ "name": "D", "nameLocation": "77:1:1", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { "anonymous": false, "eventSelector": "caa54b91a2314ab89b39714b1cd283762e53a2f59cfb997d6770e2824c39db0d", @@ -169,8 +148,7 @@ "name": "ED", "nameLocation": "96:2:1", "nodeType": "EventDefinition", - "parameters": - { + "parameters": { "id": 11, "nodeType": "ParameterList", "parameters": [], @@ -182,8 +160,7 @@ "scope": 14, "src": "68:35:1", "usedErrors": [], - "usedEvents": - [ + "usedEvents": [ 2, 7, 12 diff --git a/test/libsolidity/ASTJSON/event_with_variables_of_internal_types.sol b/test/libsolidity/ASTJSON/event_with_variables_of_internal_types.sol index 6fe58c39c168..a2291057003d 100644 --- a/test/libsolidity/ASTJSON/event_with_variables_of_internal_types.sol +++ b/test/libsolidity/ASTJSON/event_with_variables_of_internal_types.sol @@ -1,4 +1,5 @@ contract C { event E(function() internal); } + // ---- diff --git a/test/libsolidity/ASTJSON/event_with_variables_of_internal_types_parseOnly.json b/test/libsolidity/ASTJSON/event_with_variables_of_internal_types_parseOnly.json index 3ff426cb2230..44c1fb536895 100644 --- a/test/libsolidity/ASTJSON/event_with_variables_of_internal_types_parseOnly.json +++ b/test/libsolidity/ASTJSON/event_with_variables_of_internal_types_parseOnly.json @@ -2,8 +2,7 @@ "absolutePath": "a", "id": 8, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "abstract": false, "baseContracts": [], @@ -13,20 +12,17 @@ "name": "C", "nameLocation": "9:1:1", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { "anonymous": false, "id": 6, "name": "E", "nameLocation": "23:1:1", "nodeType": "EventDefinition", - "parameters": - { + "parameters": { "id": 5, "nodeType": "ParameterList", - "parameters": - [ + "parameters": [ { "constant": false, "id": 4, @@ -39,19 +35,16 @@ "stateVariable": false, "storageLocation": "default", "typeDescriptions": {}, - "typeName": - { + "typeName": { "id": 3, "nodeType": "FunctionTypeName", - "parameterTypes": - { + "parameterTypes": { "id": 1, "nodeType": "ParameterList", "parameters": [], "src": "33:2:1" }, - "returnParameterTypes": - { + "returnParameterTypes": { "id": 2, "nodeType": "ParameterList", "parameters": [], diff --git a/test/libsolidity/ASTJSON/fail_after_parsing.sol b/test/libsolidity/ASTJSON/fail_after_parsing.sol index 882b4c950267..052900e93ce1 100644 --- a/test/libsolidity/ASTJSON/fail_after_parsing.sol +++ b/test/libsolidity/ASTJSON/fail_after_parsing.sol @@ -1,15 +1,12 @@ function g() public; - interface I { struct S { S s; } - function f(E storage e) { error E; emit E(); - ++c; uint calldata c = 123.4; } } + // ---- -// failAfter: Parsed diff --git a/test/libsolidity/ASTJSON/fail_after_parsing_parseOnly.json b/test/libsolidity/ASTJSON/fail_after_parsing_parseOnly.json index f1d958617427..6f841649c897 100644 --- a/test/libsolidity/ASTJSON/fail_after_parsing_parseOnly.json +++ b/test/libsolidity/ASTJSON/fail_after_parsing_parseOnly.json @@ -2,8 +2,7 @@ "absolutePath": "a", "id": 30, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "id": 3, "implemented": false, @@ -12,15 +11,13 @@ "name": "g", "nameLocation": "9:1:1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 1, "nodeType": "ParameterList", "parameters": [], "src": "10:2:1" }, - "returnParameters": - { + "returnParameters": { "id": 2, "nodeType": "ParameterList", "parameters": [], @@ -40,12 +37,10 @@ "name": "I", "nameLocation": "31:1:1", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { "id": 7, - "members": - [ + "members": [ { "constant": false, "id": 6, @@ -57,16 +52,13 @@ "stateVariable": false, "storageLocation": "default", "typeDescriptions": {}, - "typeName": - { + "typeName": { "id": 5, "nodeType": "UserDefinedTypeName", - "pathNode": - { + "pathNode": { "id": 4, "name": "S", - "nameLocations": - [ + "nameLocations": [ "50:1:1" ], "nodeType": "IdentifierPath", @@ -85,20 +77,16 @@ "visibility": "public" }, { - "body": - { + "body": { "id": 27, "nodeType": "Block", "src": "85:88:1", - "statements": - [ + "statements": [ { - "assignments": - [ + "assignments": [ 15 ], - "declarations": - [ + "declarations": [ { "constant": false, "id": 15, @@ -110,16 +98,13 @@ "stateVariable": false, "storageLocation": "default", "typeDescriptions": {}, - "typeName": - { + "typeName": { "id": 14, "nodeType": "UserDefinedTypeName", - "pathNode": - { + "pathNode": { "id": 13, "name": "error", - "nameLocations": - [ + "nameLocations": [ "95:5:1" ], "nodeType": "IdentifierPath", @@ -136,11 +121,9 @@ "src": "95:7:1" }, { - "eventCall": - { + "eventCall": { "arguments": [], - "expression": - { + "expression": { "id": 17, "name": "E", "nodeType": "Identifier", @@ -161,15 +144,13 @@ "src": "112:8:1" }, { - "expression": - { + "expression": { "id": 21, "nodeType": "UnaryOperation", "operator": "++", "prefix": true, "src": "130:3:1", - "subExpression": - { + "subExpression": { "id": 20, "name": "c", "nodeType": "Identifier", @@ -184,12 +165,10 @@ "src": "130:3:1" }, { - "assignments": - [ + "assignments": [ 24 ], - "declarations": - [ + "declarations": [ { "constant": false, "id": 24, @@ -201,8 +180,7 @@ "stateVariable": false, "storageLocation": "calldata", "typeDescriptions": {}, - "typeName": - { + "typeName": { "id": 23, "name": "uint", "nodeType": "ElementaryTypeName", @@ -213,8 +191,7 @@ } ], "id": 26, - "initialValue": - { + "initialValue": { "hexValue": "3132332e34", "id": 25, "kind": "number", @@ -235,12 +212,10 @@ "name": "f", "nameLocation": "70:1:1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 11, "nodeType": "ParameterList", - "parameters": - [ + "parameters": [ { "constant": false, "id": 10, @@ -252,16 +227,13 @@ "stateVariable": false, "storageLocation": "storage", "typeDescriptions": {}, - "typeName": - { + "typeName": { "id": 9, "nodeType": "UserDefinedTypeName", - "pathNode": - { + "pathNode": { "id": 8, "name": "E", - "nameLocations": - [ + "nameLocations": [ "72:1:1" ], "nodeType": "IdentifierPath", @@ -275,8 +247,7 @@ ], "src": "71:13:1" }, - "returnParameters": - { + "returnParameters": { "id": 12, "nodeType": "ParameterList", "parameters": [], diff --git a/test/libsolidity/ASTJSON/fallback.json b/test/libsolidity/ASTJSON/fallback.json index f68c72ce6600..93646f2afa5c 100644 --- a/test/libsolidity/ASTJSON/fallback.json +++ b/test/libsolidity/ASTJSON/fallback.json @@ -1,16 +1,13 @@ { "absolutePath": "a", - "exportedSymbols": - { - "C": - [ + "exportedSymbols": { + "C": [ 5 ] }, "id": 6, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "abstract": false, "baseContracts": [], @@ -19,18 +16,15 @@ "contractKind": "contract", "fullyImplemented": true, "id": 5, - "linearizedBaseContracts": - [ + "linearizedBaseContracts": [ 5 ], "name": "C", "nameLocation": "9:1:1", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { - "body": - { + "body": { "id": 3, "nodeType": "Block", "src": "43:5:1", @@ -43,15 +37,13 @@ "name": "", "nameLocation": "-1:-1:-1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 1, "nodeType": "ParameterList", "parameters": [], "src": "23:2:1" }, - "returnParameters": - { + "returnParameters": { "id": 2, "nodeType": "ParameterList", "parameters": [], diff --git a/test/libsolidity/ASTJSON/fallback.sol b/test/libsolidity/ASTJSON/fallback.sol index 170e77958c97..219d85db593a 100644 --- a/test/libsolidity/ASTJSON/fallback.sol +++ b/test/libsolidity/ASTJSON/fallback.sol @@ -2,4 +2,5 @@ contract C { fallback() external payable { } } + // ---- diff --git a/test/libsolidity/ASTJSON/fallback_and_receive_ether.json b/test/libsolidity/ASTJSON/fallback_and_receive_ether.json index f41559d2a640..5504719ecb2f 100644 --- a/test/libsolidity/ASTJSON/fallback_and_receive_ether.json +++ b/test/libsolidity/ASTJSON/fallback_and_receive_ether.json @@ -1,16 +1,13 @@ { "absolutePath": "a", - "exportedSymbols": - { - "C": - [ + "exportedSymbols": { + "C": [ 9 ] }, "id": 10, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "abstract": false, "baseContracts": [], @@ -19,18 +16,15 @@ "contractKind": "contract", "fullyImplemented": true, "id": 9, - "linearizedBaseContracts": - [ + "linearizedBaseContracts": [ 9 ], "name": "C", "nameLocation": "9:1:1", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { - "body": - { + "body": { "id": 3, "nodeType": "Block", "src": "42:5:1", @@ -43,15 +37,13 @@ "name": "", "nameLocation": "-1:-1:-1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 1, "nodeType": "ParameterList", "parameters": [], "src": "22:2:1" }, - "returnParameters": - { + "returnParameters": { "id": 2, "nodeType": "ParameterList", "parameters": [], @@ -64,8 +56,7 @@ "visibility": "external" }, { - "body": - { + "body": { "id": 7, "nodeType": "Block", "src": "78:5:1", @@ -78,15 +69,13 @@ "name": "", "nameLocation": "-1:-1:-1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 5, "nodeType": "ParameterList", "parameters": [], "src": "58:2:1" }, - "returnParameters": - { + "returnParameters": { "id": 6, "nodeType": "ParameterList", "parameters": [], diff --git a/test/libsolidity/ASTJSON/fallback_and_receive_ether.sol b/test/libsolidity/ASTJSON/fallback_and_receive_ether.sol index 7eb712582db6..89acccf5a603 100644 --- a/test/libsolidity/ASTJSON/fallback_and_receive_ether.sol +++ b/test/libsolidity/ASTJSON/fallback_and_receive_ether.sol @@ -4,4 +4,5 @@ contract C { fallback() external payable { } } + // ---- diff --git a/test/libsolidity/ASTJSON/fallback_and_receive_ether_parseOnly.json b/test/libsolidity/ASTJSON/fallback_and_receive_ether_parseOnly.json index 215bf3a83bd9..34260824fe6e 100644 --- a/test/libsolidity/ASTJSON/fallback_and_receive_ether_parseOnly.json +++ b/test/libsolidity/ASTJSON/fallback_and_receive_ether_parseOnly.json @@ -2,8 +2,7 @@ "absolutePath": "a", "id": 10, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "abstract": false, "baseContracts": [], @@ -13,11 +12,9 @@ "name": "C", "nameLocation": "9:1:1", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { - "body": - { + "body": { "id": 3, "nodeType": "Block", "src": "42:5:1", @@ -30,15 +27,13 @@ "name": "", "nameLocation": "-1:-1:-1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 1, "nodeType": "ParameterList", "parameters": [], "src": "22:2:1" }, - "returnParameters": - { + "returnParameters": { "id": 2, "nodeType": "ParameterList", "parameters": [], @@ -50,8 +45,7 @@ "visibility": "external" }, { - "body": - { + "body": { "id": 7, "nodeType": "Block", "src": "78:5:1", @@ -64,15 +58,13 @@ "name": "", "nameLocation": "-1:-1:-1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 5, "nodeType": "ParameterList", "parameters": [], "src": "58:2:1" }, - "returnParameters": - { + "returnParameters": { "id": 6, "nodeType": "ParameterList", "parameters": [], diff --git a/test/libsolidity/ASTJSON/fallback_parseOnly.json b/test/libsolidity/ASTJSON/fallback_parseOnly.json index eb81fafbe930..6991b32b4114 100644 --- a/test/libsolidity/ASTJSON/fallback_parseOnly.json +++ b/test/libsolidity/ASTJSON/fallback_parseOnly.json @@ -2,8 +2,7 @@ "absolutePath": "a", "id": 6, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "abstract": false, "baseContracts": [], @@ -13,11 +12,9 @@ "name": "C", "nameLocation": "9:1:1", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { - "body": - { + "body": { "id": 3, "nodeType": "Block", "src": "43:5:1", @@ -30,15 +27,13 @@ "name": "", "nameLocation": "-1:-1:-1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 1, "nodeType": "ParameterList", "parameters": [], "src": "23:2:1" }, - "returnParameters": - { + "returnParameters": { "id": 2, "nodeType": "ParameterList", "parameters": [], diff --git a/test/libsolidity/ASTJSON/fallback_payable.json b/test/libsolidity/ASTJSON/fallback_payable.json index 790351764550..e3eacc1ecc95 100644 --- a/test/libsolidity/ASTJSON/fallback_payable.json +++ b/test/libsolidity/ASTJSON/fallback_payable.json @@ -1,16 +1,13 @@ { "absolutePath": "a", - "exportedSymbols": - { - "C": - [ + "exportedSymbols": { + "C": [ 5 ] }, "id": 6, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "abstract": false, "baseContracts": [], @@ -19,18 +16,15 @@ "contractKind": "contract", "fullyImplemented": true, "id": 5, - "linearizedBaseContracts": - [ + "linearizedBaseContracts": [ 5 ], "name": "C", "nameLocation": "9:1:1", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { - "body": - { + "body": { "id": 3, "nodeType": "Block", "src": "34:2:1", @@ -43,15 +37,13 @@ "name": "", "nameLocation": "-1:-1:-1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 1, "nodeType": "ParameterList", "parameters": [], "src": "22:2:1" }, - "returnParameters": - { + "returnParameters": { "id": 2, "nodeType": "ParameterList", "parameters": [], diff --git a/test/libsolidity/ASTJSON/fallback_payable.sol b/test/libsolidity/ASTJSON/fallback_payable.sol index 7eff747af373..d66d378aff8d 100644 --- a/test/libsolidity/ASTJSON/fallback_payable.sol +++ b/test/libsolidity/ASTJSON/fallback_payable.sol @@ -1,4 +1,5 @@ contract C { fallback() external {} } + // ---- diff --git a/test/libsolidity/ASTJSON/fallback_payable_parseOnly.json b/test/libsolidity/ASTJSON/fallback_payable_parseOnly.json index e1810828a39d..f14d2f1ed645 100644 --- a/test/libsolidity/ASTJSON/fallback_payable_parseOnly.json +++ b/test/libsolidity/ASTJSON/fallback_payable_parseOnly.json @@ -2,8 +2,7 @@ "absolutePath": "a", "id": 6, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "abstract": false, "baseContracts": [], @@ -13,11 +12,9 @@ "name": "C", "nameLocation": "9:1:1", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { - "body": - { + "body": { "id": 3, "nodeType": "Block", "src": "34:2:1", @@ -30,15 +27,13 @@ "name": "", "nameLocation": "-1:-1:-1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 1, "nodeType": "ParameterList", "parameters": [], "src": "22:2:1" }, - "returnParameters": - { + "returnParameters": { "id": 2, "nodeType": "ParameterList", "parameters": [], diff --git a/test/libsolidity/ASTJSON/function_type.json b/test/libsolidity/ASTJSON/function_type.json index e1a5156cf77d..563b65438cd1 100644 --- a/test/libsolidity/ASTJSON/function_type.json +++ b/test/libsolidity/ASTJSON/function_type.json @@ -1,16 +1,13 @@ { "absolutePath": "a", - "exportedSymbols": - { - "C": - [ + "exportedSymbols": { + "C": [ 17 ] }, "id": 18, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "abstract": false, "baseContracts": [], @@ -19,18 +16,15 @@ "contractKind": "contract", "fullyImplemented": true, "id": 17, - "linearizedBaseContracts": - [ + "linearizedBaseContracts": [ 17 ], "name": "C", "nameLocation": "9:1:1", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { - "body": - { + "body": { "id": 15, "nodeType": "Block", "src": "127:2:1", @@ -44,12 +38,10 @@ "name": "f", "nameLocation": "22:1:1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 7, "nodeType": "ParameterList", - "parameters": - [ + "parameters": [ { "constant": false, "id": 6, @@ -61,28 +53,23 @@ "src": "24:44:1", "stateVariable": false, "storageLocation": "default", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_function_external_payable$__$returns$_t_uint256_$", "typeString": "function () payable external returns (uint256)" }, - "typeName": - { + "typeName": { "id": 5, "nodeType": "FunctionTypeName", - "parameterTypes": - { + "parameterTypes": { "id": 1, "nodeType": "ParameterList", "parameters": [], "src": "32:2:1" }, - "returnParameterTypes": - { + "returnParameterTypes": { "id": 4, "nodeType": "ParameterList", - "parameters": - [ + "parameters": [ { "constant": false, "id": 3, @@ -94,19 +81,16 @@ "src": "61:4:1", "stateVariable": false, "storageLocation": "default", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_uint256", "typeString": "uint256" }, - "typeName": - { + "typeName": { "id": 2, "name": "uint", "nodeType": "ElementaryTypeName", "src": "61:4:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_uint256", "typeString": "uint256" } @@ -118,8 +102,7 @@ }, "src": "24:44:1", "stateMutability": "payable", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_function_external_payable$__$returns$_t_uint256_$", "typeString": "function () payable external returns (uint256)" }, @@ -130,12 +113,10 @@ ], "src": "23:46:1" }, - "returnParameters": - { + "returnParameters": { "id": 14, "nodeType": "ParameterList", - "parameters": - [ + "parameters": [ { "constant": false, "id": 13, @@ -147,28 +128,23 @@ "src": "86:40:1", "stateVariable": false, "storageLocation": "default", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_function_external_view$__$returns$_t_uint256_$", "typeString": "function () view external returns (uint256)" }, - "typeName": - { + "typeName": { "id": 12, "nodeType": "FunctionTypeName", - "parameterTypes": - { + "parameterTypes": { "id": 8, "nodeType": "ParameterList", "parameters": [], "src": "94:2:1" }, - "returnParameterTypes": - { + "returnParameterTypes": { "id": 11, "nodeType": "ParameterList", - "parameters": - [ + "parameters": [ { "constant": false, "id": 10, @@ -180,19 +156,16 @@ "src": "120:4:1", "stateVariable": false, "storageLocation": "default", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_uint256", "typeString": "uint256" }, - "typeName": - { + "typeName": { "id": 9, "name": "uint", "nodeType": "ElementaryTypeName", "src": "120:4:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_uint256", "typeString": "uint256" } @@ -204,8 +177,7 @@ }, "src": "86:40:1", "stateMutability": "view", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_function_external_view$__$returns$_t_uint256_$", "typeString": "function () view external returns (uint256)" }, diff --git a/test/libsolidity/ASTJSON/function_type_parseOnly.json b/test/libsolidity/ASTJSON/function_type_parseOnly.json index 64b09d5d9d9b..765c51780e00 100644 --- a/test/libsolidity/ASTJSON/function_type_parseOnly.json +++ b/test/libsolidity/ASTJSON/function_type_parseOnly.json @@ -2,8 +2,7 @@ "absolutePath": "a", "id": 18, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "abstract": false, "baseContracts": [], @@ -13,11 +12,9 @@ "name": "C", "nameLocation": "9:1:1", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { - "body": - { + "body": { "id": 15, "nodeType": "Block", "src": "127:2:1", @@ -30,12 +27,10 @@ "name": "f", "nameLocation": "22:1:1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 7, "nodeType": "ParameterList", - "parameters": - [ + "parameters": [ { "constant": false, "id": 6, @@ -47,23 +42,19 @@ "stateVariable": false, "storageLocation": "default", "typeDescriptions": {}, - "typeName": - { + "typeName": { "id": 5, "nodeType": "FunctionTypeName", - "parameterTypes": - { + "parameterTypes": { "id": 1, "nodeType": "ParameterList", "parameters": [], "src": "32:2:1" }, - "returnParameterTypes": - { + "returnParameterTypes": { "id": 4, "nodeType": "ParameterList", - "parameters": - [ + "parameters": [ { "constant": false, "id": 3, @@ -75,8 +66,7 @@ "stateVariable": false, "storageLocation": "default", "typeDescriptions": {}, - "typeName": - { + "typeName": { "id": 2, "name": "uint", "nodeType": "ElementaryTypeName", @@ -98,12 +88,10 @@ ], "src": "23:46:1" }, - "returnParameters": - { + "returnParameters": { "id": 14, "nodeType": "ParameterList", - "parameters": - [ + "parameters": [ { "constant": false, "id": 13, @@ -115,23 +103,19 @@ "stateVariable": false, "storageLocation": "default", "typeDescriptions": {}, - "typeName": - { + "typeName": { "id": 12, "nodeType": "FunctionTypeName", - "parameterTypes": - { + "parameterTypes": { "id": 8, "nodeType": "ParameterList", "parameters": [], "src": "94:2:1" }, - "returnParameterTypes": - { + "returnParameterTypes": { "id": 11, "nodeType": "ParameterList", - "parameters": - [ + "parameters": [ { "constant": false, "id": 10, @@ -143,8 +127,7 @@ "stateVariable": false, "storageLocation": "default", "typeDescriptions": {}, - "typeName": - { + "typeName": { "id": 9, "name": "uint", "nodeType": "ElementaryTypeName", diff --git a/test/libsolidity/ASTJSON/global_enum.json b/test/libsolidity/ASTJSON/global_enum.json index 0b673cffbf9d..17a92954f5c6 100644 --- a/test/libsolidity/ASTJSON/global_enum.json +++ b/test/libsolidity/ASTJSON/global_enum.json @@ -1,21 +1,17 @@ { "absolutePath": "a", - "exportedSymbols": - { - "E": - [ + "exportedSymbols": { + "E": [ 2 ] }, "id": 3, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "canonicalName": "E", "id": 2, - "members": - [ + "members": [ { "id": 1, "name": "A", diff --git a/test/libsolidity/ASTJSON/global_enum_parseOnly.json b/test/libsolidity/ASTJSON/global_enum_parseOnly.json index 887d5997cd05..c390db5b3792 100644 --- a/test/libsolidity/ASTJSON/global_enum_parseOnly.json +++ b/test/libsolidity/ASTJSON/global_enum_parseOnly.json @@ -2,12 +2,10 @@ "absolutePath": "a", "id": 3, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "id": 2, - "members": - [ + "members": [ { "id": 1, "name": "A", diff --git a/test/libsolidity/ASTJSON/global_struct.json b/test/libsolidity/ASTJSON/global_struct.json index 2c14a5e41446..f7f937d04bd8 100644 --- a/test/libsolidity/ASTJSON/global_struct.json +++ b/test/libsolidity/ASTJSON/global_struct.json @@ -1,21 +1,17 @@ { "absolutePath": "a", - "exportedSymbols": - { - "S": - [ + "exportedSymbols": { + "S": [ 3 ] }, "id": 4, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "canonicalName": "S", "id": 3, - "members": - [ + "members": [ { "constant": false, "id": 2, @@ -27,19 +23,16 @@ "src": "11:9:1", "stateVariable": false, "storageLocation": "default", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_uint256", "typeString": "uint256" }, - "typeName": - { + "typeName": { "id": 1, "name": "uint256", "nodeType": "ElementaryTypeName", "src": "11:7:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_uint256", "typeString": "uint256" } diff --git a/test/libsolidity/ASTJSON/global_struct_parseOnly.json b/test/libsolidity/ASTJSON/global_struct_parseOnly.json index 418cb79faf12..5f90ab8a1028 100644 --- a/test/libsolidity/ASTJSON/global_struct_parseOnly.json +++ b/test/libsolidity/ASTJSON/global_struct_parseOnly.json @@ -2,12 +2,10 @@ "absolutePath": "a", "id": 4, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "id": 3, - "members": - [ + "members": [ { "constant": false, "id": 2, @@ -19,8 +17,7 @@ "stateVariable": false, "storageLocation": "default", "typeDescriptions": {}, - "typeName": - { + "typeName": { "id": 1, "name": "uint256", "nodeType": "ElementaryTypeName", diff --git a/test/libsolidity/ASTJSON/indirect_event.json b/test/libsolidity/ASTJSON/indirect_event.json index fcbe81756275..691e814e51ef 100644 --- a/test/libsolidity/ASTJSON/indirect_event.json +++ b/test/libsolidity/ASTJSON/indirect_event.json @@ -1,21 +1,17 @@ { "absolutePath": "a", - "exportedSymbols": - { - "C": - [ + "exportedSymbols": { + "C": [ 25 ], - "L": - [ + "L": [ 10 ] }, "id": 26, "license": "GPL-3.0", "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "abstract": false, "baseContracts": [], @@ -24,15 +20,13 @@ "contractKind": "library", "fullyImplemented": true, "id": 10, - "linearizedBaseContracts": - [ + "linearizedBaseContracts": [ 10 ], "name": "L", "nameLocation": "44:1:1", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { "anonymous": false, "eventSelector": "92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028", @@ -40,8 +34,7 @@ "name": "E", "nameLocation": "58:1:1", "nodeType": "EventDefinition", - "parameters": - { + "parameters": { "id": 1, "nodeType": "ParameterList", "parameters": [], @@ -50,19 +43,15 @@ "src": "52:10:1" }, { - "body": - { + "body": { "id": 8, "nodeType": "Block", "src": "89:13:1", - "statements": - [ + "statements": [ { - "eventCall": - { + "eventCall": { "arguments": [], - "expression": - { + "expression": { "argumentTypes": [], "id": 5, "name": "E", @@ -70,8 +59,7 @@ "overloadedDeclarations": [], "referencedDeclaration": 2, "src": "96:1:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_function_event_nonpayable$__$returns$__$", "typeString": "function ()" } @@ -87,8 +75,7 @@ "nodeType": "FunctionCall", "src": "96:3:1", "tryCall": false, - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_tuple$__$", "typeString": "tuple()" } @@ -106,15 +93,13 @@ "name": "f", "nameLocation": "76:1:1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 3, "nodeType": "ParameterList", "parameters": [], "src": "77:2:1" }, - "returnParameters": - { + "returnParameters": { "id": 4, "nodeType": "ParameterList", "parameters": [], @@ -130,8 +115,7 @@ "scope": 26, "src": "36:68:1", "usedErrors": [], - "usedEvents": - [ + "usedEvents": [ 2 ] }, @@ -143,15 +127,13 @@ "contractKind": "contract", "fullyImplemented": true, "id": 25, - "linearizedBaseContracts": - [ + "linearizedBaseContracts": [ 25 ], "name": "C", "nameLocation": "114:1:1", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { "anonymous": false, "eventSelector": "70a5d861ef9816388422765f41d618eb3abdf490acb37354b539729e37b09f0e", @@ -159,8 +141,7 @@ "name": "H", "nameLocation": "128:1:1", "nodeType": "EventDefinition", - "parameters": - { + "parameters": { "id": 11, "nodeType": "ParameterList", "parameters": [], @@ -169,30 +150,24 @@ "src": "122:10:1" }, { - "body": - { + "body": { "id": 23, "nodeType": "Block", "src": "157:20:1", - "statements": - [ + "statements": [ { - "expression": - { + "expression": { "arguments": [], - "expression": - { + "expression": { "argumentTypes": [], - "expression": - { + "expression": { "id": 15, "name": "L", "nodeType": "Identifier", "overloadedDeclarations": [], "referencedDeclaration": 10, "src": "159:1:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_type$_t_contract$_L_$10_$", "typeString": "type(library L)" } @@ -207,8 +182,7 @@ "nodeType": "MemberAccess", "referencedDeclaration": 9, "src": "159:3:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_function_internal_nonpayable$__$returns$__$", "typeString": "function ()" } @@ -224,8 +198,7 @@ "nodeType": "FunctionCall", "src": "159:5:1", "tryCall": false, - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_tuple$__$", "typeString": "tuple()" } @@ -235,11 +208,9 @@ "src": "159:5:1" }, { - "eventCall": - { + "eventCall": { "arguments": [], - "expression": - { + "expression": { "argumentTypes": [], "id": 20, "name": "H", @@ -247,8 +218,7 @@ "overloadedDeclarations": [], "referencedDeclaration": 12, "src": "171:1:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_function_event_nonpayable$__$returns$__$", "typeString": "function ()" } @@ -264,8 +234,7 @@ "nodeType": "FunctionCall", "src": "171:3:1", "tryCall": false, - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_tuple$__$", "typeString": "tuple()" } @@ -284,15 +253,13 @@ "name": "g", "nameLocation": "146:1:1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 13, "nodeType": "ParameterList", "parameters": [], "src": "147:2:1" }, - "returnParameters": - { + "returnParameters": { "id": 14, "nodeType": "ParameterList", "parameters": [], @@ -308,8 +275,7 @@ "scope": 26, "src": "105:74:1", "usedErrors": [], - "usedEvents": - [ + "usedEvents": [ 2, 12 ] diff --git a/test/libsolidity/ASTJSON/indirect_event_parseOnly.json b/test/libsolidity/ASTJSON/indirect_event_parseOnly.json index 17ca036d3259..82ce0cd15f68 100644 --- a/test/libsolidity/ASTJSON/indirect_event_parseOnly.json +++ b/test/libsolidity/ASTJSON/indirect_event_parseOnly.json @@ -3,8 +3,7 @@ "id": 26, "license": "GPL-3.0", "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "abstract": false, "baseContracts": [], @@ -14,16 +13,14 @@ "name": "L", "nameLocation": "44:1:1", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { "anonymous": false, "id": 2, "name": "E", "nameLocation": "58:1:1", "nodeType": "EventDefinition", - "parameters": - { + "parameters": { "id": 1, "nodeType": "ParameterList", "parameters": [], @@ -32,19 +29,15 @@ "src": "52:10:1" }, { - "body": - { + "body": { "id": 8, "nodeType": "Block", "src": "89:13:1", - "statements": - [ + "statements": [ { - "eventCall": - { + "eventCall": { "arguments": [], - "expression": - { + "expression": { "id": 5, "name": "E", "nodeType": "Identifier", @@ -73,15 +66,13 @@ "name": "f", "nameLocation": "76:1:1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 3, "nodeType": "ParameterList", "parameters": [], "src": "77:2:1" }, - "returnParameters": - { + "returnParameters": { "id": 4, "nodeType": "ParameterList", "parameters": [], @@ -106,16 +97,14 @@ "name": "C", "nameLocation": "114:1:1", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { "anonymous": false, "id": 12, "name": "H", "nameLocation": "128:1:1", "nodeType": "EventDefinition", - "parameters": - { + "parameters": { "id": 11, "nodeType": "ParameterList", "parameters": [], @@ -124,21 +113,16 @@ "src": "122:10:1" }, { - "body": - { + "body": { "id": 23, "nodeType": "Block", "src": "157:20:1", - "statements": - [ + "statements": [ { - "expression": - { + "expression": { "arguments": [], - "expression": - { - "expression": - { + "expression": { + "expression": { "id": 15, "name": "L", "nodeType": "Identifier", @@ -166,11 +150,9 @@ "src": "159:5:1" }, { - "eventCall": - { + "eventCall": { "arguments": [], - "expression": - { + "expression": { "id": 20, "name": "H", "nodeType": "Identifier", @@ -199,15 +181,13 @@ "name": "g", "nameLocation": "146:1:1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 13, "nodeType": "ParameterList", "parameters": [], "src": "147:2:1" }, - "returnParameters": - { + "returnParameters": { "id": 14, "nodeType": "ParameterList", "parameters": [], diff --git a/test/libsolidity/ASTJSON/inheritance_specifier.json b/test/libsolidity/ASTJSON/inheritance_specifier.json index ae210c949620..4365a9e435c7 100644 --- a/test/libsolidity/ASTJSON/inheritance_specifier.json +++ b/test/libsolidity/ASTJSON/inheritance_specifier.json @@ -1,20 +1,16 @@ { "absolutePath": "a", - "exportedSymbols": - { - "C1": - [ + "exportedSymbols": { + "C1": [ 1 ], - "C2": - [ + "C2": [ 4 ] }, "id": 5, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "abstract": false, "baseContracts": [], @@ -23,8 +19,7 @@ "contractKind": "contract", "fullyImplemented": true, "id": 1, - "linearizedBaseContracts": - [ + "linearizedBaseContracts": [ 1 ], "name": "C1", @@ -38,15 +33,12 @@ }, { "abstract": false, - "baseContracts": - [ + "baseContracts": [ { - "baseName": - { + "baseName": { "id": 2, "name": "C1", - "nameLocations": - [ + "nameLocations": [ "30:2:1" ], "nodeType": "IdentifierPath", @@ -63,8 +55,7 @@ "contractKind": "contract", "fullyImplemented": true, "id": 4, - "linearizedBaseContracts": - [ + "linearizedBaseContracts": [ 4, 1 ], diff --git a/test/libsolidity/ASTJSON/inheritance_specifier_parseOnly.json b/test/libsolidity/ASTJSON/inheritance_specifier_parseOnly.json index 171391b36d5e..a334485a9881 100644 --- a/test/libsolidity/ASTJSON/inheritance_specifier_parseOnly.json +++ b/test/libsolidity/ASTJSON/inheritance_specifier_parseOnly.json @@ -2,8 +2,7 @@ "absolutePath": "a", "id": 5, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "abstract": false, "baseContracts": [], @@ -20,15 +19,12 @@ }, { "abstract": false, - "baseContracts": - [ + "baseContracts": [ { - "baseName": - { + "baseName": { "id": 2, "name": "C1", - "nameLocations": - [ + "nameLocations": [ "30:2:1" ], "nodeType": "IdentifierPath", diff --git a/test/libsolidity/ASTJSON/license.json b/test/libsolidity/ASTJSON/license.json index 4c0882637f2d..f12ed7e3e056 100644 --- a/test/libsolidity/ASTJSON/license.json +++ b/test/libsolidity/ASTJSON/license.json @@ -1,17 +1,14 @@ { "absolutePath": "a", - "exportedSymbols": - { - "C": - [ + "exportedSymbols": { + "C": [ 1 ] }, "id": 2, "license": "GPL-3.0", "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "abstract": false, "baseContracts": [], @@ -20,8 +17,7 @@ "contractKind": "contract", "fullyImplemented": true, "id": 1, - "linearizedBaseContracts": - [ + "linearizedBaseContracts": [ 1 ], "name": "C", diff --git a/test/libsolidity/ASTJSON/license_parseOnly.json b/test/libsolidity/ASTJSON/license_parseOnly.json index f2958f15ffad..def7f2c62337 100644 --- a/test/libsolidity/ASTJSON/license_parseOnly.json +++ b/test/libsolidity/ASTJSON/license_parseOnly.json @@ -3,8 +3,7 @@ "id": 2, "license": "GPL-3.0", "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "abstract": false, "baseContracts": [], diff --git a/test/libsolidity/ASTJSON/long_type_name_binary_operation.json b/test/libsolidity/ASTJSON/long_type_name_binary_operation.json index 9bcd5e8fd9f2..f5a6aad08139 100644 --- a/test/libsolidity/ASTJSON/long_type_name_binary_operation.json +++ b/test/libsolidity/ASTJSON/long_type_name_binary_operation.json @@ -1,16 +1,13 @@ { "absolutePath": "a", - "exportedSymbols": - { - "c": - [ + "exportedSymbols": { + "c": [ 11 ] }, "id": 12, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "abstract": false, "baseContracts": [], @@ -19,30 +16,24 @@ "contractKind": "contract", "fullyImplemented": true, "id": 11, - "linearizedBaseContracts": - [ + "linearizedBaseContracts": [ 11 ], "name": "c", "nameLocation": "9:1:1", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { - "body": - { + "body": { "id": 9, "nodeType": "Block", "src": "33:19:1", - "statements": - [ + "statements": [ { - "assignments": - [ + "assignments": [ 4 ], - "declarations": - [ + "declarations": [ { "constant": false, "id": 4, @@ -54,19 +45,16 @@ "src": "35:6:1", "stateVariable": false, "storageLocation": "default", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_uint256", "typeString": "uint256" }, - "typeName": - { + "typeName": { "id": 3, "name": "uint", "nodeType": "ElementaryTypeName", "src": "35:4:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_uint256", "typeString": "uint256" } @@ -75,10 +63,8 @@ } ], "id": 8, - "initialValue": - { - "commonType": - { + "initialValue": { + "commonType": { "typeIdentifier": "t_rational_5_by_1", "typeString": "int_const 5" }, @@ -87,8 +73,7 @@ "isLValue": false, "isPure": true, "lValueRequested": false, - "leftExpression": - { + "leftExpression": { "hexValue": "32", "id": 5, "isConstant": false, @@ -98,8 +83,7 @@ "lValueRequested": false, "nodeType": "Literal", "src": "44:1:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_rational_2_by_1", "typeString": "int_const 2" }, @@ -107,8 +91,7 @@ }, "nodeType": "BinaryOperation", "operator": "+", - "rightExpression": - { + "rightExpression": { "hexValue": "33", "id": 6, "isConstant": false, @@ -118,16 +101,14 @@ "lValueRequested": false, "nodeType": "Literal", "src": "48:1:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_rational_3_by_1", "typeString": "int_const 3" }, "value": "3" }, "src": "44:5:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_rational_5_by_1", "typeString": "int_const 5" } @@ -145,15 +126,13 @@ "name": "f", "nameLocation": "22:1:1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 1, "nodeType": "ParameterList", "parameters": [], "src": "23:2:1" }, - "returnParameters": - { + "returnParameters": { "id": 2, "nodeType": "ParameterList", "parameters": [], diff --git a/test/libsolidity/ASTJSON/long_type_name_binary_operation_parseOnly.json b/test/libsolidity/ASTJSON/long_type_name_binary_operation_parseOnly.json index 2cb372dd26ac..56587809e8fb 100644 --- a/test/libsolidity/ASTJSON/long_type_name_binary_operation_parseOnly.json +++ b/test/libsolidity/ASTJSON/long_type_name_binary_operation_parseOnly.json @@ -2,8 +2,7 @@ "absolutePath": "a", "id": 12, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "abstract": false, "baseContracts": [], @@ -13,23 +12,18 @@ "name": "c", "nameLocation": "9:1:1", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { - "body": - { + "body": { "id": 9, "nodeType": "Block", "src": "33:19:1", - "statements": - [ + "statements": [ { - "assignments": - [ + "assignments": [ 4 ], - "declarations": - [ + "declarations": [ { "constant": false, "id": 4, @@ -41,8 +35,7 @@ "stateVariable": false, "storageLocation": "default", "typeDescriptions": {}, - "typeName": - { + "typeName": { "id": 3, "name": "uint", "nodeType": "ElementaryTypeName", @@ -53,12 +46,10 @@ } ], "id": 8, - "initialValue": - { + "initialValue": { "commonType": {}, "id": 7, - "leftExpression": - { + "leftExpression": { "hexValue": "32", "id": 5, "kind": "number", @@ -69,8 +60,7 @@ }, "nodeType": "BinaryOperation", "operator": "+", - "rightExpression": - { + "rightExpression": { "hexValue": "33", "id": 6, "kind": "number", @@ -94,15 +84,13 @@ "name": "f", "nameLocation": "22:1:1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 1, "nodeType": "ParameterList", "parameters": [], "src": "23:2:1" }, - "returnParameters": - { + "returnParameters": { "id": 2, "nodeType": "ParameterList", "parameters": [], diff --git a/test/libsolidity/ASTJSON/long_type_name_identifier.json b/test/libsolidity/ASTJSON/long_type_name_identifier.json index c22aeb40c28b..d3e76eaac4c0 100644 --- a/test/libsolidity/ASTJSON/long_type_name_identifier.json +++ b/test/libsolidity/ASTJSON/long_type_name_identifier.json @@ -1,16 +1,13 @@ { "absolutePath": "a", - "exportedSymbols": - { - "c": - [ + "exportedSymbols": { + "c": [ 15 ] }, "id": 16, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "abstract": false, "baseContracts": [], @@ -19,15 +16,13 @@ "contractKind": "contract", "fullyImplemented": true, "id": 15, - "linearizedBaseContracts": - [ + "linearizedBaseContracts": [ 15 ], "name": "c", "nameLocation": "9:1:1", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { "constant": false, "id": 3, @@ -39,21 +34,17 @@ "src": "13:8:1", "stateVariable": true, "storageLocation": "default", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_array$_t_uint256_$dyn_storage", "typeString": "uint256[]" }, - "typeName": - { - "baseType": - { + "typeName": { + "baseType": { "id": 1, "name": "uint", "nodeType": "ElementaryTypeName", "src": "13:4:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_uint256", "typeString": "uint256" } @@ -61,8 +52,7 @@ "id": 2, "nodeType": "ArrayTypeName", "src": "13:6:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_array$_t_uint256_$dyn_storage_ptr", "typeString": "uint256[]" } @@ -70,20 +60,16 @@ "visibility": "internal" }, { - "body": - { + "body": { "id": 13, "nodeType": "Block", "src": "43:25:1", - "statements": - [ + "statements": [ { - "assignments": - [ + "assignments": [ 10 ], - "declarations": - [ + "declarations": [ { "constant": false, "id": 10, @@ -95,21 +81,17 @@ "src": "45:16:1", "stateVariable": false, "storageLocation": "storage", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_array$_t_uint256_$dyn_storage_ptr", "typeString": "uint256[]" }, - "typeName": - { - "baseType": - { + "typeName": { + "baseType": { "id": 8, "name": "uint", "nodeType": "ElementaryTypeName", "src": "45:4:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_uint256", "typeString": "uint256" } @@ -117,8 +99,7 @@ "id": 9, "nodeType": "ArrayTypeName", "src": "45:6:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_array$_t_uint256_$dyn_storage_ptr", "typeString": "uint256[]" } @@ -127,16 +108,14 @@ } ], "id": 12, - "initialValue": - { + "initialValue": { "id": 11, "name": "a", "nodeType": "Identifier", "overloadedDeclarations": [], "referencedDeclaration": 3, "src": "64:1:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_array$_t_uint256_$dyn_storage", "typeString": "uint256[] storage ref" } @@ -154,15 +133,13 @@ "name": "f", "nameLocation": "32:1:1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 4, "nodeType": "ParameterList", "parameters": [], "src": "33:2:1" }, - "returnParameters": - { + "returnParameters": { "id": 5, "nodeType": "ParameterList", "parameters": [], diff --git a/test/libsolidity/ASTJSON/long_type_name_identifier_parseOnly.json b/test/libsolidity/ASTJSON/long_type_name_identifier_parseOnly.json index 1bf50bed601c..597bd383bbd3 100644 --- a/test/libsolidity/ASTJSON/long_type_name_identifier_parseOnly.json +++ b/test/libsolidity/ASTJSON/long_type_name_identifier_parseOnly.json @@ -2,8 +2,7 @@ "absolutePath": "a", "id": 16, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "abstract": false, "baseContracts": [], @@ -13,8 +12,7 @@ "name": "c", "nameLocation": "9:1:1", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { "constant": false, "id": 3, @@ -26,10 +24,8 @@ "stateVariable": false, "storageLocation": "default", "typeDescriptions": {}, - "typeName": - { - "baseType": - { + "typeName": { + "baseType": { "id": 1, "name": "uint", "nodeType": "ElementaryTypeName", @@ -44,20 +40,16 @@ "visibility": "internal" }, { - "body": - { + "body": { "id": 13, "nodeType": "Block", "src": "43:25:1", - "statements": - [ + "statements": [ { - "assignments": - [ + "assignments": [ 10 ], - "declarations": - [ + "declarations": [ { "constant": false, "id": 10, @@ -69,10 +61,8 @@ "stateVariable": false, "storageLocation": "storage", "typeDescriptions": {}, - "typeName": - { - "baseType": - { + "typeName": { + "baseType": { "id": 8, "name": "uint", "nodeType": "ElementaryTypeName", @@ -88,8 +78,7 @@ } ], "id": 12, - "initialValue": - { + "initialValue": { "id": 11, "name": "a", "nodeType": "Identifier", @@ -109,15 +98,13 @@ "name": "f", "nameLocation": "32:1:1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 4, "nodeType": "ParameterList", "parameters": [], "src": "33:2:1" }, - "returnParameters": - { + "returnParameters": { "id": 5, "nodeType": "ParameterList", "parameters": [], diff --git a/test/libsolidity/ASTJSON/mappings.json b/test/libsolidity/ASTJSON/mappings.json index 81bf19db1a85..c1b9cfc4807a 100644 --- a/test/libsolidity/ASTJSON/mappings.json +++ b/test/libsolidity/ASTJSON/mappings.json @@ -1,16 +1,13 @@ { "absolutePath": "a", - "exportedSymbols": - { - "C": - [ + "exportedSymbols": { + "C": [ 23 ] }, "id": 24, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "abstract": false, "baseContracts": [], @@ -19,20 +16,17 @@ "contractKind": "contract", "fullyImplemented": true, "id": 23, - "linearizedBaseContracts": - [ + "linearizedBaseContracts": [ 23 ], "name": "C", "nameLocation": "9:1:1", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { "canonicalName": "C.E", "id": 4, - "members": - [ + "members": [ { "id": 1, "name": "A", @@ -71,26 +65,21 @@ "src": "40:20:1", "stateVariable": true, "storageLocation": "default", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_mapping$_t_contract$_C_$23_$_t_bool_$", "typeString": "mapping(contract C => bool)" }, - "typeName": - { + "typeName": { "id": 8, "keyName": "", "keyNameLocation": "-1:-1:-1", - "keyType": - { + "keyType": { "id": 6, "nodeType": "UserDefinedTypeName", - "pathNode": - { + "pathNode": { "id": 5, "name": "C", - "nameLocations": - [ + "nameLocations": [ "48:1:1" ], "nodeType": "IdentifierPath", @@ -99,29 +88,25 @@ }, "referencedDeclaration": 23, "src": "48:1:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_contract$_C_$23", "typeString": "contract C" } }, "nodeType": "Mapping", "src": "40:18:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_mapping$_t_contract$_C_$23_$_t_bool_$", "typeString": "mapping(contract C => bool)" }, "valueName": "", "valueNameLocation": "-1:-1:-1", - "valueType": - { + "valueType": { "id": 7, "name": "bool", "nodeType": "ElementaryTypeName", "src": "53:4:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_bool", "typeString": "bool" } @@ -140,45 +125,38 @@ "src": "66:26:1", "stateVariable": true, "storageLocation": "default", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_mapping$_t_address_$_t_bool_$", "typeString": "mapping(address => bool)" }, - "typeName": - { + "typeName": { "id": 12, "keyName": "", "keyNameLocation": "-1:-1:-1", - "keyType": - { + "keyType": { "id": 10, "name": "address", "nodeType": "ElementaryTypeName", "src": "74:7:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_address", "typeString": "address" } }, "nodeType": "Mapping", "src": "66:24:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_mapping$_t_address_$_t_bool_$", "typeString": "mapping(address => bool)" }, "valueName": "", "valueNameLocation": "-1:-1:-1", - "valueType": - { + "valueType": { "id": 11, "name": "bool", "nodeType": "ElementaryTypeName", "src": "85:4:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_bool", "typeString": "bool" } @@ -197,26 +175,21 @@ "src": "98:20:1", "stateVariable": true, "storageLocation": "default", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_mapping$_t_enum$_E_$4_$_t_bool_$", "typeString": "mapping(enum C.E => bool)" }, - "typeName": - { + "typeName": { "id": 17, "keyName": "", "keyNameLocation": "-1:-1:-1", - "keyType": - { + "keyType": { "id": 15, "nodeType": "UserDefinedTypeName", - "pathNode": - { + "pathNode": { "id": 14, "name": "E", - "nameLocations": - [ + "nameLocations": [ "106:1:1" ], "nodeType": "IdentifierPath", @@ -225,29 +198,25 @@ }, "referencedDeclaration": 4, "src": "106:1:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_enum$_E_$4", "typeString": "enum C.E" } }, "nodeType": "Mapping", "src": "98:18:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_mapping$_t_enum$_E_$4_$_t_bool_$", "typeString": "mapping(enum C.E => bool)" }, "valueName": "", "valueNameLocation": "-1:-1:-1", - "valueType": - { + "valueType": { "id": 16, "name": "bool", "nodeType": "ElementaryTypeName", "src": "111:4:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_bool", "typeString": "bool" } @@ -266,45 +235,38 @@ "src": "124:46:1", "stateVariable": true, "storageLocation": "default", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_mapping$_t_address_$_t_uint256_$", "typeString": "mapping(address => uint256)" }, - "typeName": - { + "typeName": { "id": 21, "keyName": "keyAddress", "keyNameLocation": "140:10:1", - "keyType": - { + "keyType": { "id": 19, "name": "address", "nodeType": "ElementaryTypeName", "src": "132:7:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_address", "typeString": "address" } }, "nodeType": "Mapping", "src": "124:44:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_mapping$_t_address_$_t_uint256_$", "typeString": "mapping(address => uint256)" }, "valueName": "value", "valueNameLocation": "162:5:1", - "valueType": - { + "valueType": { "id": 20, "name": "uint256", "nodeType": "ElementaryTypeName", "src": "154:7:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_uint256", "typeString": "uint256" } diff --git a/test/libsolidity/ASTJSON/mappings.sol b/test/libsolidity/ASTJSON/mappings.sol index 5412ca601eb9..05912d21f703 100644 --- a/test/libsolidity/ASTJSON/mappings.sol +++ b/test/libsolidity/ASTJSON/mappings.sol @@ -5,4 +5,5 @@ contract C { mapping(E => bool) c; mapping(address keyAddress => uint256 value) d; } + // ---- diff --git a/test/libsolidity/ASTJSON/mappings_parseOnly.json b/test/libsolidity/ASTJSON/mappings_parseOnly.json index 84cfb4004a4d..4edc75ffde9b 100644 --- a/test/libsolidity/ASTJSON/mappings_parseOnly.json +++ b/test/libsolidity/ASTJSON/mappings_parseOnly.json @@ -2,8 +2,7 @@ "absolutePath": "a", "id": 24, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "abstract": false, "baseContracts": [], @@ -13,12 +12,10 @@ "name": "C", "nameLocation": "9:1:1", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { "id": 4, - "members": - [ + "members": [ { "id": 1, "name": "A", @@ -57,21 +54,17 @@ "stateVariable": false, "storageLocation": "default", "typeDescriptions": {}, - "typeName": - { + "typeName": { "id": 8, "keyName": "", "keyNameLocation": "-1:-1:-1", - "keyType": - { + "keyType": { "id": 6, "nodeType": "UserDefinedTypeName", - "pathNode": - { + "pathNode": { "id": 5, "name": "C", - "nameLocations": - [ + "nameLocations": [ "48:1:1" ], "nodeType": "IdentifierPath", @@ -85,8 +78,7 @@ "typeDescriptions": {}, "valueName": "", "valueNameLocation": "-1:-1:-1", - "valueType": - { + "valueType": { "id": 7, "name": "bool", "nodeType": "ElementaryTypeName", @@ -107,13 +99,11 @@ "stateVariable": false, "storageLocation": "default", "typeDescriptions": {}, - "typeName": - { + "typeName": { "id": 12, "keyName": "", "keyNameLocation": "-1:-1:-1", - "keyType": - { + "keyType": { "id": 10, "name": "address", "nodeType": "ElementaryTypeName", @@ -125,8 +115,7 @@ "typeDescriptions": {}, "valueName": "", "valueNameLocation": "-1:-1:-1", - "valueType": - { + "valueType": { "id": 11, "name": "bool", "nodeType": "ElementaryTypeName", @@ -147,21 +136,17 @@ "stateVariable": false, "storageLocation": "default", "typeDescriptions": {}, - "typeName": - { + "typeName": { "id": 17, "keyName": "", "keyNameLocation": "-1:-1:-1", - "keyType": - { + "keyType": { "id": 15, "nodeType": "UserDefinedTypeName", - "pathNode": - { + "pathNode": { "id": 14, "name": "E", - "nameLocations": - [ + "nameLocations": [ "106:1:1" ], "nodeType": "IdentifierPath", @@ -175,8 +160,7 @@ "typeDescriptions": {}, "valueName": "", "valueNameLocation": "-1:-1:-1", - "valueType": - { + "valueType": { "id": 16, "name": "bool", "nodeType": "ElementaryTypeName", @@ -197,13 +181,11 @@ "stateVariable": false, "storageLocation": "default", "typeDescriptions": {}, - "typeName": - { + "typeName": { "id": 21, "keyName": "keyAddress", "keyNameLocation": "140:10:1", - "keyType": - { + "keyType": { "id": 19, "name": "address", "nodeType": "ElementaryTypeName", @@ -215,8 +197,7 @@ "typeDescriptions": {}, "valueName": "value", "valueNameLocation": "162:5:1", - "valueType": - { + "valueType": { "id": 20, "name": "uint256", "nodeType": "ElementaryTypeName", diff --git a/test/libsolidity/ASTJSON/modifier_definition.json b/test/libsolidity/ASTJSON/modifier_definition.json index 30ebcb7c20b2..485e0f0c1b2a 100644 --- a/test/libsolidity/ASTJSON/modifier_definition.json +++ b/test/libsolidity/ASTJSON/modifier_definition.json @@ -1,16 +1,13 @@ { "absolutePath": "a", - "exportedSymbols": - { - "C": - [ + "exportedSymbols": { + "C": [ 14 ] }, "id": 15, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "abstract": false, "baseContracts": [], @@ -19,23 +16,19 @@ "contractKind": "contract", "fullyImplemented": true, "id": 14, - "linearizedBaseContracts": - [ + "linearizedBaseContracts": [ 14 ], "name": "C", "nameLocation": "9:1:1", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { - "body": - { + "body": { "id": 5, "nodeType": "Block", "src": "32:6:1", - "statements": - [ + "statements": [ { "id": 4, "nodeType": "PlaceholderStatement", @@ -47,12 +40,10 @@ "name": "M", "nameLocation": "22:1:1", "nodeType": "ModifierDefinition", - "parameters": - { + "parameters": { "id": 3, "nodeType": "ParameterList", - "parameters": - [ + "parameters": [ { "constant": false, "id": 2, @@ -64,19 +55,16 @@ "src": "24:6:1", "stateVariable": false, "storageLocation": "default", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_uint256", "typeString": "uint256" }, - "typeName": - { + "typeName": { "id": 1, "name": "uint", "nodeType": "ElementaryTypeName", "src": "24:4:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_uint256", "typeString": "uint256" } @@ -91,8 +79,7 @@ "visibility": "internal" }, { - "body": - { + "body": { "id": 12, "nodeType": "Block", "src": "64:2:1", @@ -102,11 +89,9 @@ "id": 13, "implemented": true, "kind": "function", - "modifiers": - [ + "modifiers": [ { - "arguments": - [ + "arguments": [ { "hexValue": "31", "id": 9, @@ -117,8 +102,7 @@ "lValueRequested": false, "nodeType": "Literal", "src": "54:1:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_rational_1_by_1", "typeString": "int_const 1" }, @@ -127,12 +111,10 @@ ], "id": 10, "kind": "modifierInvocation", - "modifierName": - { + "modifierName": { "id": 8, "name": "M", - "nameLocations": - [ + "nameLocations": [ "52:1:1" ], "nodeType": "IdentifierPath", @@ -146,15 +128,13 @@ "name": "F", "nameLocation": "48:1:1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 7, "nodeType": "ParameterList", "parameters": [], "src": "49:2:1" }, - "returnParameters": - { + "returnParameters": { "id": 11, "nodeType": "ParameterList", "parameters": [], diff --git a/test/libsolidity/ASTJSON/modifier_definition_parseOnly.json b/test/libsolidity/ASTJSON/modifier_definition_parseOnly.json index f8067952a28c..22ed7bdc6677 100644 --- a/test/libsolidity/ASTJSON/modifier_definition_parseOnly.json +++ b/test/libsolidity/ASTJSON/modifier_definition_parseOnly.json @@ -2,8 +2,7 @@ "absolutePath": "a", "id": 15, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "abstract": false, "baseContracts": [], @@ -13,16 +12,13 @@ "name": "C", "nameLocation": "9:1:1", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { - "body": - { + "body": { "id": 5, "nodeType": "Block", "src": "32:6:1", - "statements": - [ + "statements": [ { "id": 4, "nodeType": "PlaceholderStatement", @@ -34,12 +30,10 @@ "name": "M", "nameLocation": "22:1:1", "nodeType": "ModifierDefinition", - "parameters": - { + "parameters": { "id": 3, "nodeType": "ParameterList", - "parameters": - [ + "parameters": [ { "constant": false, "id": 2, @@ -51,8 +45,7 @@ "stateVariable": false, "storageLocation": "default", "typeDescriptions": {}, - "typeName": - { + "typeName": { "id": 1, "name": "uint", "nodeType": "ElementaryTypeName", @@ -69,8 +62,7 @@ "visibility": "internal" }, { - "body": - { + "body": { "id": 12, "nodeType": "Block", "src": "64:2:1", @@ -79,11 +71,9 @@ "id": 13, "implemented": true, "kind": "function", - "modifiers": - [ + "modifiers": [ { - "arguments": - [ + "arguments": [ { "hexValue": "31", "id": 9, @@ -95,12 +85,10 @@ } ], "id": 10, - "modifierName": - { + "modifierName": { "id": 8, "name": "M", - "nameLocations": - [ + "nameLocations": [ "52:1:1" ], "nodeType": "IdentifierPath", @@ -113,15 +101,13 @@ "name": "F", "nameLocation": "48:1:1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 7, "nodeType": "ParameterList", "parameters": [], "src": "49:2:1" }, - "returnParameters": - { + "returnParameters": { "id": 11, "nodeType": "ParameterList", "parameters": [], diff --git a/test/libsolidity/ASTJSON/modifier_invocation.json b/test/libsolidity/ASTJSON/modifier_invocation.json index 30ebcb7c20b2..485e0f0c1b2a 100644 --- a/test/libsolidity/ASTJSON/modifier_invocation.json +++ b/test/libsolidity/ASTJSON/modifier_invocation.json @@ -1,16 +1,13 @@ { "absolutePath": "a", - "exportedSymbols": - { - "C": - [ + "exportedSymbols": { + "C": [ 14 ] }, "id": 15, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "abstract": false, "baseContracts": [], @@ -19,23 +16,19 @@ "contractKind": "contract", "fullyImplemented": true, "id": 14, - "linearizedBaseContracts": - [ + "linearizedBaseContracts": [ 14 ], "name": "C", "nameLocation": "9:1:1", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { - "body": - { + "body": { "id": 5, "nodeType": "Block", "src": "32:6:1", - "statements": - [ + "statements": [ { "id": 4, "nodeType": "PlaceholderStatement", @@ -47,12 +40,10 @@ "name": "M", "nameLocation": "22:1:1", "nodeType": "ModifierDefinition", - "parameters": - { + "parameters": { "id": 3, "nodeType": "ParameterList", - "parameters": - [ + "parameters": [ { "constant": false, "id": 2, @@ -64,19 +55,16 @@ "src": "24:6:1", "stateVariable": false, "storageLocation": "default", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_uint256", "typeString": "uint256" }, - "typeName": - { + "typeName": { "id": 1, "name": "uint", "nodeType": "ElementaryTypeName", "src": "24:4:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_uint256", "typeString": "uint256" } @@ -91,8 +79,7 @@ "visibility": "internal" }, { - "body": - { + "body": { "id": 12, "nodeType": "Block", "src": "64:2:1", @@ -102,11 +89,9 @@ "id": 13, "implemented": true, "kind": "function", - "modifiers": - [ + "modifiers": [ { - "arguments": - [ + "arguments": [ { "hexValue": "31", "id": 9, @@ -117,8 +102,7 @@ "lValueRequested": false, "nodeType": "Literal", "src": "54:1:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_rational_1_by_1", "typeString": "int_const 1" }, @@ -127,12 +111,10 @@ ], "id": 10, "kind": "modifierInvocation", - "modifierName": - { + "modifierName": { "id": 8, "name": "M", - "nameLocations": - [ + "nameLocations": [ "52:1:1" ], "nodeType": "IdentifierPath", @@ -146,15 +128,13 @@ "name": "F", "nameLocation": "48:1:1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 7, "nodeType": "ParameterList", "parameters": [], "src": "49:2:1" }, - "returnParameters": - { + "returnParameters": { "id": 11, "nodeType": "ParameterList", "parameters": [], diff --git a/test/libsolidity/ASTJSON/modifier_invocation_parseOnly.json b/test/libsolidity/ASTJSON/modifier_invocation_parseOnly.json index f8067952a28c..22ed7bdc6677 100644 --- a/test/libsolidity/ASTJSON/modifier_invocation_parseOnly.json +++ b/test/libsolidity/ASTJSON/modifier_invocation_parseOnly.json @@ -2,8 +2,7 @@ "absolutePath": "a", "id": 15, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "abstract": false, "baseContracts": [], @@ -13,16 +12,13 @@ "name": "C", "nameLocation": "9:1:1", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { - "body": - { + "body": { "id": 5, "nodeType": "Block", "src": "32:6:1", - "statements": - [ + "statements": [ { "id": 4, "nodeType": "PlaceholderStatement", @@ -34,12 +30,10 @@ "name": "M", "nameLocation": "22:1:1", "nodeType": "ModifierDefinition", - "parameters": - { + "parameters": { "id": 3, "nodeType": "ParameterList", - "parameters": - [ + "parameters": [ { "constant": false, "id": 2, @@ -51,8 +45,7 @@ "stateVariable": false, "storageLocation": "default", "typeDescriptions": {}, - "typeName": - { + "typeName": { "id": 1, "name": "uint", "nodeType": "ElementaryTypeName", @@ -69,8 +62,7 @@ "visibility": "internal" }, { - "body": - { + "body": { "id": 12, "nodeType": "Block", "src": "64:2:1", @@ -79,11 +71,9 @@ "id": 13, "implemented": true, "kind": "function", - "modifiers": - [ + "modifiers": [ { - "arguments": - [ + "arguments": [ { "hexValue": "31", "id": 9, @@ -95,12 +85,10 @@ } ], "id": 10, - "modifierName": - { + "modifierName": { "id": 8, "name": "M", - "nameLocations": - [ + "nameLocations": [ "52:1:1" ], "nodeType": "IdentifierPath", @@ -113,15 +101,13 @@ "name": "F", "nameLocation": "48:1:1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 7, "nodeType": "ParameterList", "parameters": [], "src": "49:2:1" }, - "returnParameters": - { + "returnParameters": { "id": 11, "nodeType": "ParameterList", "parameters": [], diff --git a/test/libsolidity/ASTJSON/mutability.json b/test/libsolidity/ASTJSON/mutability.json index b6318d84e5e9..cb7ace3b32e6 100644 --- a/test/libsolidity/ASTJSON/mutability.json +++ b/test/libsolidity/ASTJSON/mutability.json @@ -1,16 +1,13 @@ { "absolutePath": "a", - "exportedSymbols": - { - "C": - [ + "exportedSymbols": { + "C": [ 10 ] }, "id": 11, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "abstract": false, "baseContracts": [], @@ -19,15 +16,13 @@ "contractKind": "contract", "fullyImplemented": true, "id": 10, - "linearizedBaseContracts": - [ + "linearizedBaseContracts": [ 10 ], "name": "C", "nameLocation": "9:1:1", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { "constant": false, "functionSelector": "0dbe671f", @@ -40,25 +35,21 @@ "src": "17:27:1", "stateVariable": true, "storageLocation": "default", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_uint256", "typeString": "uint256" }, - "typeName": - { + "typeName": { "id": 1, "name": "uint", "nodeType": "ElementaryTypeName", "src": "17:4:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_uint256", "typeString": "uint256" } }, - "value": - { + "value": { "hexValue": "34", "id": 2, "isConstant": false, @@ -68,8 +59,7 @@ "lValueRequested": false, "nodeType": "Literal", "src": "43:1:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_rational_4_by_1", "typeString": "int_const 4" }, @@ -89,25 +79,21 @@ "src": "50:26:1", "stateVariable": true, "storageLocation": "default", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_uint256", "typeString": "uint256" }, - "typeName": - { + "typeName": { "id": 4, "name": "uint", "nodeType": "ElementaryTypeName", "src": "50:4:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_uint256", "typeString": "uint256" } }, - "value": - { + "value": { "hexValue": "32", "id": 5, "isConstant": false, @@ -117,8 +103,7 @@ "lValueRequested": false, "nodeType": "Literal", "src": "75:1:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_rational_2_by_1", "typeString": "int_const 2" }, @@ -138,25 +123,21 @@ "src": "82:17:1", "stateVariable": true, "storageLocation": "default", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_uint256", "typeString": "uint256" }, - "typeName": - { + "typeName": { "id": 7, "name": "uint", "nodeType": "ElementaryTypeName", "src": "82:4:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_uint256", "typeString": "uint256" } }, - "value": - { + "value": { "hexValue": "33", "id": 8, "isConstant": false, @@ -166,8 +147,7 @@ "lValueRequested": false, "nodeType": "Literal", "src": "98:1:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_rational_3_by_1", "typeString": "int_const 3" }, diff --git a/test/libsolidity/ASTJSON/mutability.sol b/test/libsolidity/ASTJSON/mutability.sol index 3f67c29e0981..7688186e773f 100644 --- a/test/libsolidity/ASTJSON/mutability.sol +++ b/test/libsolidity/ASTJSON/mutability.sol @@ -4,4 +4,5 @@ contract C uint public constant b = 2; uint public c = 3; } + // ---- diff --git a/test/libsolidity/ASTJSON/mutability_parseOnly.json b/test/libsolidity/ASTJSON/mutability_parseOnly.json index 637f8e11416c..74ae78f84c07 100644 --- a/test/libsolidity/ASTJSON/mutability_parseOnly.json +++ b/test/libsolidity/ASTJSON/mutability_parseOnly.json @@ -2,8 +2,7 @@ "absolutePath": "a", "id": 11, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "abstract": false, "baseContracts": [], @@ -13,8 +12,7 @@ "name": "C", "nameLocation": "9:1:1", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { "constant": false, "id": 3, @@ -26,16 +24,14 @@ "stateVariable": false, "storageLocation": "default", "typeDescriptions": {}, - "typeName": - { + "typeName": { "id": 1, "name": "uint", "nodeType": "ElementaryTypeName", "src": "17:4:1", "typeDescriptions": {} }, - "value": - { + "value": { "hexValue": "34", "id": 2, "kind": "number", @@ -57,16 +53,14 @@ "stateVariable": false, "storageLocation": "default", "typeDescriptions": {}, - "typeName": - { + "typeName": { "id": 4, "name": "uint", "nodeType": "ElementaryTypeName", "src": "50:4:1", "typeDescriptions": {} }, - "value": - { + "value": { "hexValue": "32", "id": 5, "kind": "number", @@ -88,16 +82,14 @@ "stateVariable": false, "storageLocation": "default", "typeDescriptions": {}, - "typeName": - { + "typeName": { "id": 7, "name": "uint", "nodeType": "ElementaryTypeName", "src": "82:4:1", "typeDescriptions": {} }, - "value": - { + "value": { "hexValue": "33", "id": 8, "kind": "number", diff --git a/test/libsolidity/ASTJSON/non_utf8.json b/test/libsolidity/ASTJSON/non_utf8.json index 0058e56eb322..b13ab7f8a132 100644 --- a/test/libsolidity/ASTJSON/non_utf8.json +++ b/test/libsolidity/ASTJSON/non_utf8.json @@ -1,16 +1,13 @@ { "absolutePath": "a", - "exportedSymbols": - { - "C": - [ + "exportedSymbols": { + "C": [ 15 ] }, "id": 16, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "abstract": false, "baseContracts": [], @@ -19,30 +16,24 @@ "contractKind": "contract", "fullyImplemented": true, "id": 15, - "linearizedBaseContracts": - [ + "linearizedBaseContracts": [ 15 ], "name": "C", "nameLocation": "9:1:1", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { - "body": - { + "body": { "id": 13, "nodeType": "Block", "src": "33:45:1", - "statements": - [ + "statements": [ { - "assignments": - [ + "assignments": [ 4 ], - "declarations": - [ + "declarations": [ { "constant": false, "id": 4, @@ -54,19 +45,16 @@ "src": "35:15:1", "stateVariable": false, "storageLocation": "memory", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_string_memory_ptr", "typeString": "string" }, - "typeName": - { + "typeName": { "id": 3, "name": "string", "nodeType": "ElementaryTypeName", "src": "35:6:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_string_storage_ptr", "typeString": "string" } @@ -75,13 +63,10 @@ } ], "id": 12, - "initialValue": - { - "arguments": - [ + "initialValue": { + "arguments": [ { - "arguments": - [ + "arguments": [ { "hexValue": "ff", "id": 9, @@ -92,17 +77,14 @@ "lValueRequested": false, "nodeType": "Literal", "src": "66:7:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_stringliteral_8b1a944cf13a9a1c08facb2c9e98623ef3254d2ddb48113885c3e8e97fec8db9", "typeString": "literal_string hex\"ff\"" } } ], - "expression": - { - "argumentTypes": - [ + "expression": { + "argumentTypes": [ { "typeIdentifier": "t_stringliteral_8b1a944cf13a9a1c08facb2c9e98623ef3254d2ddb48113885c3e8e97fec8db9", "typeString": "literal_string hex\"ff\"" @@ -115,13 +97,11 @@ "lValueRequested": false, "nodeType": "ElementaryTypeNameExpression", "src": "60:5:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_type$_t_bytes_storage_ptr_$", "typeString": "type(bytes storage pointer)" }, - "typeName": - { + "typeName": { "id": 7, "name": "bytes", "nodeType": "ElementaryTypeName", @@ -140,17 +120,14 @@ "nodeType": "FunctionCall", "src": "60:14:1", "tryCall": false, - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_bytes_memory_ptr", "typeString": "bytes memory" } } ], - "expression": - { - "argumentTypes": - [ + "expression": { + "argumentTypes": [ { "typeIdentifier": "t_bytes_memory_ptr", "typeString": "bytes memory" @@ -163,13 +140,11 @@ "lValueRequested": false, "nodeType": "ElementaryTypeNameExpression", "src": "53:6:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_type$_t_string_storage_ptr_$", "typeString": "type(string storage pointer)" }, - "typeName": - { + "typeName": { "id": 5, "name": "string", "nodeType": "ElementaryTypeName", @@ -188,8 +163,7 @@ "nodeType": "FunctionCall", "src": "53:22:1", "tryCall": false, - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_string_memory_ptr", "typeString": "string memory" } @@ -207,15 +181,13 @@ "name": "f", "nameLocation": "22:1:1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 1, "nodeType": "ParameterList", "parameters": [], "src": "23:2:1" }, - "returnParameters": - { + "returnParameters": { "id": 2, "nodeType": "ParameterList", "parameters": [], diff --git a/test/libsolidity/ASTJSON/non_utf8_parseOnly.json b/test/libsolidity/ASTJSON/non_utf8_parseOnly.json index bbc350f96dfe..34a99dba3461 100644 --- a/test/libsolidity/ASTJSON/non_utf8_parseOnly.json +++ b/test/libsolidity/ASTJSON/non_utf8_parseOnly.json @@ -2,8 +2,7 @@ "absolutePath": "a", "id": 16, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "abstract": false, "baseContracts": [], @@ -13,23 +12,18 @@ "name": "C", "nameLocation": "9:1:1", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { - "body": - { + "body": { "id": 13, "nodeType": "Block", "src": "33:45:1", - "statements": - [ + "statements": [ { - "assignments": - [ + "assignments": [ 4 ], - "declarations": - [ + "declarations": [ { "constant": false, "id": 4, @@ -41,8 +35,7 @@ "stateVariable": false, "storageLocation": "memory", "typeDescriptions": {}, - "typeName": - { + "typeName": { "id": 3, "name": "string", "nodeType": "ElementaryTypeName", @@ -53,13 +46,10 @@ } ], "id": 12, - "initialValue": - { - "arguments": - [ + "initialValue": { + "arguments": [ { - "arguments": - [ + "arguments": [ { "hexValue": "ff", "id": 9, @@ -69,14 +59,12 @@ "typeDescriptions": {} } ], - "expression": - { + "expression": { "id": 8, "nodeType": "ElementaryTypeNameExpression", "src": "60:5:1", "typeDescriptions": {}, - "typeName": - { + "typeName": { "id": 7, "name": "bytes", "nodeType": "ElementaryTypeName", @@ -93,14 +81,12 @@ "typeDescriptions": {} } ], - "expression": - { + "expression": { "id": 6, "nodeType": "ElementaryTypeNameExpression", "src": "53:6:1", "typeDescriptions": {}, - "typeName": - { + "typeName": { "id": 5, "name": "string", "nodeType": "ElementaryTypeName", @@ -128,15 +114,13 @@ "name": "f", "nameLocation": "22:1:1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 1, "nodeType": "ParameterList", "parameters": [], "src": "23:2:1" }, - "returnParameters": - { + "returnParameters": { "id": 2, "nodeType": "ParameterList", "parameters": [], diff --git a/test/libsolidity/ASTJSON/not_existing_import.sol b/test/libsolidity/ASTJSON/not_existing_import.sol index ad3c100c499b..6353c7527bde 100644 --- a/test/libsolidity/ASTJSON/not_existing_import.sol +++ b/test/libsolidity/ASTJSON/not_existing_import.sol @@ -4,5 +4,5 @@ contract C is NotExisting.X NotExisting.SomeStruct public myStruct; constructor() {} } + // ---- -// failAfter: Parsed diff --git a/test/libsolidity/ASTJSON/not_existing_import_parseOnly.json b/test/libsolidity/ASTJSON/not_existing_import_parseOnly.json index ea08150fd372..04c5c69ab1c8 100644 --- a/test/libsolidity/ASTJSON/not_existing_import_parseOnly.json +++ b/test/libsolidity/ASTJSON/not_existing_import_parseOnly.json @@ -2,8 +2,7 @@ "absolutePath": "a", "id": 12, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "absolutePath": "notexisting.sol", "file": "notexisting.sol", @@ -16,15 +15,12 @@ }, { "abstract": false, - "baseContracts": - [ + "baseContracts": [ { - "baseName": - { + "baseName": { "id": 2, "name": "NotExisting.X", - "nameLocations": - [ + "nameLocations": [ "55:11:1", "67:1:1" ], @@ -42,8 +38,7 @@ "name": "C", "nameLocation": "50:1:1", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { "constant": false, "id": 6, @@ -55,16 +50,13 @@ "stateVariable": false, "storageLocation": "default", "typeDescriptions": {}, - "typeName": - { + "typeName": { "id": 5, "nodeType": "UserDefinedTypeName", - "pathNode": - { + "pathNode": { "id": 4, "name": "NotExisting.SomeStruct", - "nameLocations": - [ + "nameLocations": [ "72:11:1", "84:10:1" ], @@ -77,8 +69,7 @@ "visibility": "public" }, { - "body": - { + "body": { "id": 9, "nodeType": "Block", "src": "127:2:1", @@ -91,15 +82,13 @@ "name": "", "nameLocation": "-1:-1:-1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 7, "nodeType": "ParameterList", "parameters": [], "src": "124:2:1" }, - "returnParameters": - { + "returnParameters": { "id": 8, "nodeType": "ParameterList", "parameters": [], diff --git a/test/libsolidity/ASTJSON/override.json b/test/libsolidity/ASTJSON/override.json index 35d36eac4e9f..927d0d498150 100644 --- a/test/libsolidity/ASTJSON/override.json +++ b/test/libsolidity/ASTJSON/override.json @@ -1,24 +1,19 @@ { "absolutePath": "a", - "exportedSymbols": - { - "A": - [ + "exportedSymbols": { + "A": [ 5 ], - "B": - [ + "B": [ 16 ], - "C": - [ + "C": [ 29 ] }, "id": 30, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "abstract": false, "baseContracts": [], @@ -27,18 +22,15 @@ "contractKind": "contract", "fullyImplemented": true, "id": 5, - "linearizedBaseContracts": - [ + "linearizedBaseContracts": [ 5 ], "name": "A", "nameLocation": "9:1:1", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { - "body": - { + "body": { "id": 3, "nodeType": "Block", "src": "44:2:1", @@ -52,15 +44,13 @@ "name": "faa", "nameLocation": "23:3:1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 1, "nodeType": "ParameterList", "parameters": [], "src": "26:2:1" }, - "returnParameters": - { + "returnParameters": { "id": 2, "nodeType": "ParameterList", "parameters": [], @@ -80,15 +70,12 @@ }, { "abstract": true, - "baseContracts": - [ + "baseContracts": [ { - "baseName": - { + "baseName": { "id": 6, "name": "A", - "nameLocations": - [ + "nameLocations": [ "72:1:1" ], "nodeType": "IdentifierPath", @@ -105,16 +92,14 @@ "contractKind": "contract", "fullyImplemented": false, "id": 16, - "linearizedBaseContracts": - [ + "linearizedBaseContracts": [ 16, 5 ], "name": "B", "nameLocation": "67:1:1", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { "functionSelector": "c2985578", "id": 10, @@ -124,15 +109,13 @@ "name": "foo", "nameLocation": "86:3:1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 8, "nodeType": "ParameterList", "parameters": [], "src": "89:2:1" }, - "returnParameters": - { + "returnParameters": { "id": 9, "nodeType": "ParameterList", "parameters": [], @@ -145,12 +128,10 @@ "visibility": "public" }, { - "baseFunctions": - [ + "baseFunctions": [ 4 ], - "body": - { + "body": { "id": 14, "nodeType": "Block", "src": "148:2:1", @@ -164,22 +145,19 @@ "name": "faa", "nameLocation": "118:3:1", "nodeType": "FunctionDefinition", - "overrides": - { + "overrides": { "id": 12, "nodeType": "OverrideSpecifier", "overrides": [], "src": "139:8:1" }, - "parameters": - { + "parameters": { "id": 11, "nodeType": "ParameterList", "parameters": [], "src": "121:2:1" }, - "returnParameters": - { + "returnParameters": { "id": 13, "nodeType": "ParameterList", "parameters": [], @@ -199,15 +177,12 @@ }, { "abstract": false, - "baseContracts": - [ + "baseContracts": [ { - "baseName": - { + "baseName": { "id": 17, "name": "B", - "nameLocations": - [ + "nameLocations": [ "167:1:1" ], "nodeType": "IdentifierPath", @@ -224,8 +199,7 @@ "contractKind": "contract", "fullyImplemented": true, "id": 29, - "linearizedBaseContracts": - [ + "linearizedBaseContracts": [ 29, 16, 5 @@ -233,15 +207,12 @@ "name": "C", "nameLocation": "162:1:1", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { - "baseFunctions": - [ + "baseFunctions": [ 10 ], - "body": - { + "body": { "id": 22, "nodeType": "Block", "src": "203:3:1", @@ -255,22 +226,19 @@ "name": "foo", "nameLocation": "181:3:1", "nodeType": "FunctionDefinition", - "overrides": - { + "overrides": { "id": 20, "nodeType": "OverrideSpecifier", "overrides": [], "src": "194:8:1" }, - "parameters": - { + "parameters": { "id": 19, "nodeType": "ParameterList", "parameters": [], "src": "184:2:1" }, - "returnParameters": - { + "returnParameters": { "id": 21, "nodeType": "ParameterList", "parameters": [], @@ -283,12 +251,10 @@ "visibility": "public" }, { - "baseFunctions": - [ + "baseFunctions": [ 15 ], - "body": - { + "body": { "id": 27, "nodeType": "Block", "src": "239:3:1", @@ -302,22 +268,19 @@ "name": "faa", "nameLocation": "217:3:1", "nodeType": "FunctionDefinition", - "overrides": - { + "overrides": { "id": 25, "nodeType": "OverrideSpecifier", "overrides": [], "src": "230:8:1" }, - "parameters": - { + "parameters": { "id": 24, "nodeType": "ParameterList", "parameters": [], "src": "220:2:1" }, - "returnParameters": - { + "returnParameters": { "id": 26, "nodeType": "ParameterList", "parameters": [], diff --git a/test/libsolidity/ASTJSON/override.sol b/test/libsolidity/ASTJSON/override.sol index a03244985744..1aaa58c600ab 100644 --- a/test/libsolidity/ASTJSON/override.sol +++ b/test/libsolidity/ASTJSON/override.sol @@ -9,4 +9,5 @@ contract C is B { function foo() public override { } function faa() public override { } } + // ---- diff --git a/test/libsolidity/ASTJSON/override_parseOnly.json b/test/libsolidity/ASTJSON/override_parseOnly.json index 3a927f5f2f12..7b9bcd268a38 100644 --- a/test/libsolidity/ASTJSON/override_parseOnly.json +++ b/test/libsolidity/ASTJSON/override_parseOnly.json @@ -2,8 +2,7 @@ "absolutePath": "a", "id": 30, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "abstract": false, "baseContracts": [], @@ -13,11 +12,9 @@ "name": "A", "nameLocation": "9:1:1", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { - "body": - { + "body": { "id": 3, "nodeType": "Block", "src": "44:2:1", @@ -30,15 +27,13 @@ "name": "faa", "nameLocation": "23:3:1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 1, "nodeType": "ParameterList", "parameters": [], "src": "26:2:1" }, - "returnParameters": - { + "returnParameters": { "id": 2, "nodeType": "ParameterList", "parameters": [], @@ -56,15 +51,12 @@ }, { "abstract": true, - "baseContracts": - [ + "baseContracts": [ { - "baseName": - { + "baseName": { "id": 6, "name": "A", - "nameLocations": - [ + "nameLocations": [ "72:1:1" ], "nodeType": "IdentifierPath", @@ -81,8 +73,7 @@ "name": "B", "nameLocation": "67:1:1", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { "id": 10, "implemented": false, @@ -91,15 +82,13 @@ "name": "foo", "nameLocation": "86:3:1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 8, "nodeType": "ParameterList", "parameters": [], "src": "89:2:1" }, - "returnParameters": - { + "returnParameters": { "id": 9, "nodeType": "ParameterList", "parameters": [], @@ -111,8 +100,7 @@ "visibility": "public" }, { - "body": - { + "body": { "id": 14, "nodeType": "Block", "src": "148:2:1", @@ -125,22 +113,19 @@ "name": "faa", "nameLocation": "118:3:1", "nodeType": "FunctionDefinition", - "overrides": - { + "overrides": { "id": 12, "nodeType": "OverrideSpecifier", "overrides": [], "src": "139:8:1" }, - "parameters": - { + "parameters": { "id": 11, "nodeType": "ParameterList", "parameters": [], "src": "121:2:1" }, - "returnParameters": - { + "returnParameters": { "id": 13, "nodeType": "ParameterList", "parameters": [], @@ -158,15 +143,12 @@ }, { "abstract": false, - "baseContracts": - [ + "baseContracts": [ { - "baseName": - { + "baseName": { "id": 17, "name": "B", - "nameLocations": - [ + "nameLocations": [ "167:1:1" ], "nodeType": "IdentifierPath", @@ -183,11 +165,9 @@ "name": "C", "nameLocation": "162:1:1", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { - "body": - { + "body": { "id": 22, "nodeType": "Block", "src": "203:3:1", @@ -200,22 +180,19 @@ "name": "foo", "nameLocation": "181:3:1", "nodeType": "FunctionDefinition", - "overrides": - { + "overrides": { "id": 20, "nodeType": "OverrideSpecifier", "overrides": [], "src": "194:8:1" }, - "parameters": - { + "parameters": { "id": 19, "nodeType": "ParameterList", "parameters": [], "src": "184:2:1" }, - "returnParameters": - { + "returnParameters": { "id": 21, "nodeType": "ParameterList", "parameters": [], @@ -227,8 +204,7 @@ "visibility": "public" }, { - "body": - { + "body": { "id": 27, "nodeType": "Block", "src": "239:3:1", @@ -241,22 +217,19 @@ "name": "faa", "nameLocation": "217:3:1", "nodeType": "FunctionDefinition", - "overrides": - { + "overrides": { "id": 25, "nodeType": "OverrideSpecifier", "overrides": [], "src": "230:8:1" }, - "parameters": - { + "parameters": { "id": 24, "nodeType": "ParameterList", "parameters": [], "src": "220:2:1" }, - "returnParameters": - { + "returnParameters": { "id": 26, "nodeType": "ParameterList", "parameters": [], diff --git a/test/libsolidity/ASTJSON/placeholder_statement.json b/test/libsolidity/ASTJSON/placeholder_statement.json index 96a46c1484c3..dbc9bdd1db2a 100644 --- a/test/libsolidity/ASTJSON/placeholder_statement.json +++ b/test/libsolidity/ASTJSON/placeholder_statement.json @@ -1,16 +1,13 @@ { "absolutePath": "a", - "exportedSymbols": - { - "C": - [ + "exportedSymbols": { + "C": [ 5 ] }, "id": 6, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "abstract": false, "baseContracts": [], @@ -19,23 +16,19 @@ "contractKind": "contract", "fullyImplemented": true, "id": 5, - "linearizedBaseContracts": - [ + "linearizedBaseContracts": [ 5 ], "name": "C", "nameLocation": "9:1:1", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { - "body": - { + "body": { "id": 3, "nodeType": "Block", "src": "24:6:1", - "statements": - [ + "statements": [ { "id": 2, "nodeType": "PlaceholderStatement", @@ -47,8 +40,7 @@ "name": "M", "nameLocation": "22:1:1", "nodeType": "ModifierDefinition", - "parameters": - { + "parameters": { "id": 1, "nodeType": "ParameterList", "parameters": [], diff --git a/test/libsolidity/ASTJSON/placeholder_statement_parseOnly.json b/test/libsolidity/ASTJSON/placeholder_statement_parseOnly.json index 8af17040246f..58610047d29c 100644 --- a/test/libsolidity/ASTJSON/placeholder_statement_parseOnly.json +++ b/test/libsolidity/ASTJSON/placeholder_statement_parseOnly.json @@ -2,8 +2,7 @@ "absolutePath": "a", "id": 6, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "abstract": false, "baseContracts": [], @@ -13,16 +12,13 @@ "name": "C", "nameLocation": "9:1:1", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { - "body": - { + "body": { "id": 3, "nodeType": "Block", "src": "24:6:1", - "statements": - [ + "statements": [ { "id": 2, "nodeType": "PlaceholderStatement", @@ -34,8 +30,7 @@ "name": "M", "nameLocation": "22:1:1", "nodeType": "ModifierDefinition", - "parameters": - { + "parameters": { "id": 1, "nodeType": "ParameterList", "parameters": [], diff --git a/test/libsolidity/ASTJSON/pragma_experimental_solidity_parseOnly.json b/test/libsolidity/ASTJSON/pragma_experimental_solidity_parseOnly.json index b1ac937a2427..a962a1cc1f88 100644 --- a/test/libsolidity/ASTJSON/pragma_experimental_solidity_parseOnly.json +++ b/test/libsolidity/ASTJSON/pragma_experimental_solidity_parseOnly.json @@ -3,12 +3,10 @@ "experimentalSolidity": true, "id": 2, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "id": 1, - "literals": - [ + "literals": [ "experimental", "solidity" ], diff --git a/test/libsolidity/ASTJSON/receive_ether.json b/test/libsolidity/ASTJSON/receive_ether.json index 2790493993ee..d02c84a498f6 100644 --- a/test/libsolidity/ASTJSON/receive_ether.json +++ b/test/libsolidity/ASTJSON/receive_ether.json @@ -1,16 +1,13 @@ { "absolutePath": "a", - "exportedSymbols": - { - "C": - [ + "exportedSymbols": { + "C": [ 5 ] }, "id": 6, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "abstract": false, "baseContracts": [], @@ -19,18 +16,15 @@ "contractKind": "contract", "fullyImplemented": true, "id": 5, - "linearizedBaseContracts": - [ + "linearizedBaseContracts": [ 5 ], "name": "C", "nameLocation": "9:1:1", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { - "body": - { + "body": { "id": 3, "nodeType": "Block", "src": "42:5:1", @@ -43,15 +37,13 @@ "name": "", "nameLocation": "-1:-1:-1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 1, "nodeType": "ParameterList", "parameters": [], "src": "22:2:1" }, - "returnParameters": - { + "returnParameters": { "id": 2, "nodeType": "ParameterList", "parameters": [], diff --git a/test/libsolidity/ASTJSON/receive_ether.sol b/test/libsolidity/ASTJSON/receive_ether.sol index 1e59dc1317bc..f75a43b2dfd1 100644 --- a/test/libsolidity/ASTJSON/receive_ether.sol +++ b/test/libsolidity/ASTJSON/receive_ether.sol @@ -2,4 +2,5 @@ contract C { receive() external payable { } } + // ---- diff --git a/test/libsolidity/ASTJSON/receive_ether_parseOnly.json b/test/libsolidity/ASTJSON/receive_ether_parseOnly.json index f9aede155ec7..9f0c4f60a8ea 100644 --- a/test/libsolidity/ASTJSON/receive_ether_parseOnly.json +++ b/test/libsolidity/ASTJSON/receive_ether_parseOnly.json @@ -2,8 +2,7 @@ "absolutePath": "a", "id": 6, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "abstract": false, "baseContracts": [], @@ -13,11 +12,9 @@ "name": "C", "nameLocation": "9:1:1", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { - "body": - { + "body": { "id": 3, "nodeType": "Block", "src": "42:5:1", @@ -30,15 +27,13 @@ "name": "", "nameLocation": "-1:-1:-1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 1, "nodeType": "ParameterList", "parameters": [], "src": "22:2:1" }, - "returnParameters": - { + "returnParameters": { "id": 2, "nodeType": "ParameterList", "parameters": [], diff --git a/test/libsolidity/ASTJSON/short_type_name.json b/test/libsolidity/ASTJSON/short_type_name.json index 1c1138cbafb3..f5b8bcf06c57 100644 --- a/test/libsolidity/ASTJSON/short_type_name.json +++ b/test/libsolidity/ASTJSON/short_type_name.json @@ -1,16 +1,13 @@ { "absolutePath": "a", - "exportedSymbols": - { - "c": - [ + "exportedSymbols": { + "c": [ 11 ] }, "id": 12, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "abstract": false, "baseContracts": [], @@ -19,30 +16,24 @@ "contractKind": "contract", "fullyImplemented": true, "id": 11, - "linearizedBaseContracts": - [ + "linearizedBaseContracts": [ 11 ], "name": "c", "nameLocation": "9:1:1", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { - "body": - { + "body": { "id": 9, "nodeType": "Block", "src": "33:20:1", - "statements": - [ + "statements": [ { - "assignments": - [ + "assignments": [ 7 ], - "declarations": - [ + "declarations": [ { "constant": false, "id": 7, @@ -54,21 +45,17 @@ "src": "35:15:1", "stateVariable": false, "storageLocation": "memory", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_array$_t_uint256_$dyn_memory_ptr", "typeString": "uint256[]" }, - "typeName": - { - "baseType": - { + "typeName": { + "baseType": { "id": 5, "name": "uint", "nodeType": "ElementaryTypeName", "src": "35:4:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_uint256", "typeString": "uint256" } @@ -76,8 +63,7 @@ "id": 6, "nodeType": "ArrayTypeName", "src": "35:6:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_array$_t_uint256_$dyn_storage_ptr", "typeString": "uint256[]" } @@ -99,15 +85,13 @@ "name": "f", "nameLocation": "22:1:1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 1, "nodeType": "ParameterList", "parameters": [], "src": "23:2:1" }, - "returnParameters": - { + "returnParameters": { "id": 2, "nodeType": "ParameterList", "parameters": [], diff --git a/test/libsolidity/ASTJSON/short_type_name_parseOnly.json b/test/libsolidity/ASTJSON/short_type_name_parseOnly.json index 3c4acfa775ed..27e1919c2fc2 100644 --- a/test/libsolidity/ASTJSON/short_type_name_parseOnly.json +++ b/test/libsolidity/ASTJSON/short_type_name_parseOnly.json @@ -2,8 +2,7 @@ "absolutePath": "a", "id": 12, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "abstract": false, "baseContracts": [], @@ -13,23 +12,18 @@ "name": "c", "nameLocation": "9:1:1", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { - "body": - { + "body": { "id": 9, "nodeType": "Block", "src": "33:20:1", - "statements": - [ + "statements": [ { - "assignments": - [ + "assignments": [ 7 ], - "declarations": - [ + "declarations": [ { "constant": false, "id": 7, @@ -41,10 +35,8 @@ "stateVariable": false, "storageLocation": "memory", "typeDescriptions": {}, - "typeName": - { - "baseType": - { + "typeName": { + "baseType": { "id": 5, "name": "uint", "nodeType": "ElementaryTypeName", @@ -72,15 +64,13 @@ "name": "f", "nameLocation": "22:1:1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 1, "nodeType": "ParameterList", "parameters": [], "src": "23:2:1" }, - "returnParameters": - { + "returnParameters": { "id": 2, "nodeType": "ParameterList", "parameters": [], diff --git a/test/libsolidity/ASTJSON/short_type_name_ref.json b/test/libsolidity/ASTJSON/short_type_name_ref.json index 447b1e5b7705..59ce1f39dae7 100644 --- a/test/libsolidity/ASTJSON/short_type_name_ref.json +++ b/test/libsolidity/ASTJSON/short_type_name_ref.json @@ -1,16 +1,13 @@ { "absolutePath": "a", - "exportedSymbols": - { - "c": - [ + "exportedSymbols": { + "c": [ 12 ] }, "id": 13, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "abstract": false, "baseContracts": [], @@ -19,30 +16,24 @@ "contractKind": "contract", "fullyImplemented": true, "id": 12, - "linearizedBaseContracts": - [ + "linearizedBaseContracts": [ 12 ], "name": "c", "nameLocation": "9:1:1", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { - "body": - { + "body": { "id": 10, "nodeType": "Block", "src": "33:25:1", - "statements": - [ + "statements": [ { - "assignments": - [ + "assignments": [ 8 ], - "declarations": - [ + "declarations": [ { "constant": false, "id": 8, @@ -54,23 +45,18 @@ "src": "35:20:1", "stateVariable": false, "storageLocation": "memory", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_array$_t_array$_t_uint256_$dyn_memory_ptr_$dyn_memory_ptr", "typeString": "uint256[][]" }, - "typeName": - { - "baseType": - { - "baseType": - { + "typeName": { + "baseType": { + "baseType": { "id": 5, "name": "uint", "nodeType": "ElementaryTypeName", "src": "35:4:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_uint256", "typeString": "uint256" } @@ -78,8 +64,7 @@ "id": 6, "nodeType": "ArrayTypeName", "src": "35:6:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_array$_t_uint256_$dyn_storage_ptr", "typeString": "uint256[]" } @@ -87,8 +72,7 @@ "id": 7, "nodeType": "ArrayTypeName", "src": "35:8:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_array$_t_array$_t_uint256_$dyn_storage_$dyn_storage_ptr", "typeString": "uint256[][]" } @@ -110,15 +94,13 @@ "name": "f", "nameLocation": "22:1:1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 1, "nodeType": "ParameterList", "parameters": [], "src": "23:2:1" }, - "returnParameters": - { + "returnParameters": { "id": 2, "nodeType": "ParameterList", "parameters": [], diff --git a/test/libsolidity/ASTJSON/short_type_name_ref_parseOnly.json b/test/libsolidity/ASTJSON/short_type_name_ref_parseOnly.json index 07c782d47bb4..9a7e6fccf7a8 100644 --- a/test/libsolidity/ASTJSON/short_type_name_ref_parseOnly.json +++ b/test/libsolidity/ASTJSON/short_type_name_ref_parseOnly.json @@ -2,8 +2,7 @@ "absolutePath": "a", "id": 13, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "abstract": false, "baseContracts": [], @@ -13,23 +12,18 @@ "name": "c", "nameLocation": "9:1:1", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { - "body": - { + "body": { "id": 10, "nodeType": "Block", "src": "33:25:1", - "statements": - [ + "statements": [ { - "assignments": - [ + "assignments": [ 8 ], - "declarations": - [ + "declarations": [ { "constant": false, "id": 8, @@ -41,12 +35,9 @@ "stateVariable": false, "storageLocation": "memory", "typeDescriptions": {}, - "typeName": - { - "baseType": - { - "baseType": - { + "typeName": { + "baseType": { + "baseType": { "id": 5, "name": "uint", "nodeType": "ElementaryTypeName", @@ -79,15 +70,13 @@ "name": "f", "nameLocation": "22:1:1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 1, "nodeType": "ParameterList", "parameters": [], "src": "23:2:1" }, - "returnParameters": - { + "returnParameters": { "id": 2, "nodeType": "ParameterList", "parameters": [], diff --git a/test/libsolidity/ASTJSON/smoke.json b/test/libsolidity/ASTJSON/smoke.json index d3b114bbcba4..d1fc5b13b3a8 100644 --- a/test/libsolidity/ASTJSON/smoke.json +++ b/test/libsolidity/ASTJSON/smoke.json @@ -1,16 +1,13 @@ { "absolutePath": "a", - "exportedSymbols": - { - "C": - [ + "exportedSymbols": { + "C": [ 1 ] }, "id": 2, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "abstract": false, "baseContracts": [], @@ -19,8 +16,7 @@ "contractKind": "contract", "fullyImplemented": true, "id": 1, - "linearizedBaseContracts": - [ + "linearizedBaseContracts": [ 1 ], "name": "C", diff --git a/test/libsolidity/ASTJSON/smoke_parseOnly.json b/test/libsolidity/ASTJSON/smoke_parseOnly.json index 1160fea91e75..22b597ce9d87 100644 --- a/test/libsolidity/ASTJSON/smoke_parseOnly.json +++ b/test/libsolidity/ASTJSON/smoke_parseOnly.json @@ -2,8 +2,7 @@ "absolutePath": "a", "id": 2, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "abstract": false, "baseContracts": [], diff --git a/test/libsolidity/ASTJSON/source_location.json b/test/libsolidity/ASTJSON/source_location.json index caeaf027ab3f..526069063b3f 100644 --- a/test/libsolidity/ASTJSON/source_location.json +++ b/test/libsolidity/ASTJSON/source_location.json @@ -1,16 +1,13 @@ { "absolutePath": "a", - "exportedSymbols": - { - "C": - [ + "exportedSymbols": { + "C": [ 12 ] }, "id": 13, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "abstract": false, "baseContracts": [], @@ -19,30 +16,24 @@ "contractKind": "contract", "fullyImplemented": true, "id": 12, - "linearizedBaseContracts": - [ + "linearizedBaseContracts": [ 12 ], "name": "C", "nameLocation": "9:1:1", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { - "body": - { + "body": { "id": 10, "nodeType": "Block", "src": "33:20:1", - "statements": - [ + "statements": [ { - "assignments": - [ + "assignments": [ 4 ], - "declarations": - [ + "declarations": [ { "constant": false, "id": 4, @@ -54,19 +45,16 @@ "src": "35:6:1", "stateVariable": false, "storageLocation": "default", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_uint256", "typeString": "uint256" }, - "typeName": - { + "typeName": { "id": 3, "name": "uint", "nodeType": "ElementaryTypeName", "src": "35:4:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_uint256", "typeString": "uint256" } @@ -75,8 +63,7 @@ } ], "id": 6, - "initialValue": - { + "initialValue": { "hexValue": "32", "id": 5, "isConstant": false, @@ -86,8 +73,7 @@ "lValueRequested": false, "nodeType": "Literal", "src": "44:1:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_rational_2_by_1", "typeString": "int_const 2" }, @@ -97,8 +83,7 @@ "src": "35:10:1" }, { - "expression": - { + "expression": { "id": 8, "isConstant": false, "isLValue": false, @@ -108,22 +93,19 @@ "operator": "++", "prefix": false, "src": "47:3:1", - "subExpression": - { + "subExpression": { "id": 7, "name": "x", "nodeType": "Identifier", "overloadedDeclarations": [], "referencedDeclaration": 4, "src": "47:1:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_uint256", "typeString": "uint256" } }, - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_uint256", "typeString": "uint256" } @@ -142,15 +124,13 @@ "name": "f", "nameLocation": "22:1:1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 1, "nodeType": "ParameterList", "parameters": [], "src": "23:2:1" }, - "returnParameters": - { + "returnParameters": { "id": 2, "nodeType": "ParameterList", "parameters": [], diff --git a/test/libsolidity/ASTJSON/source_location_parseOnly.json b/test/libsolidity/ASTJSON/source_location_parseOnly.json index ec25111bd349..877092a04579 100644 --- a/test/libsolidity/ASTJSON/source_location_parseOnly.json +++ b/test/libsolidity/ASTJSON/source_location_parseOnly.json @@ -2,8 +2,7 @@ "absolutePath": "a", "id": 13, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "abstract": false, "baseContracts": [], @@ -13,23 +12,18 @@ "name": "C", "nameLocation": "9:1:1", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { - "body": - { + "body": { "id": 10, "nodeType": "Block", "src": "33:20:1", - "statements": - [ + "statements": [ { - "assignments": - [ + "assignments": [ 4 ], - "declarations": - [ + "declarations": [ { "constant": false, "id": 4, @@ -41,8 +35,7 @@ "stateVariable": false, "storageLocation": "default", "typeDescriptions": {}, - "typeName": - { + "typeName": { "id": 3, "name": "uint", "nodeType": "ElementaryTypeName", @@ -53,8 +46,7 @@ } ], "id": 6, - "initialValue": - { + "initialValue": { "hexValue": "32", "id": 5, "kind": "number", @@ -67,15 +59,13 @@ "src": "35:10:1" }, { - "expression": - { + "expression": { "id": 8, "nodeType": "UnaryOperation", "operator": "++", "prefix": false, "src": "47:3:1", - "subExpression": - { + "subExpression": { "id": 7, "name": "x", "nodeType": "Identifier", @@ -98,15 +88,13 @@ "name": "f", "nameLocation": "22:1:1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 1, "nodeType": "ParameterList", "parameters": [], "src": "23:2:1" }, - "returnParameters": - { + "returnParameters": { "id": 2, "nodeType": "ParameterList", "parameters": [], diff --git a/test/libsolidity/ASTJSON/string.json b/test/libsolidity/ASTJSON/string.json index c7706e3bfc01..d4b37e2e16d2 100644 --- a/test/libsolidity/ASTJSON/string.json +++ b/test/libsolidity/ASTJSON/string.json @@ -1,16 +1,13 @@ { "absolutePath": "a", - "exportedSymbols": - { - "C": - [ + "exportedSymbols": { + "C": [ 9 ] }, "id": 10, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "abstract": false, "baseContracts": [], @@ -19,30 +16,24 @@ "contractKind": "contract", "fullyImplemented": true, "id": 9, - "linearizedBaseContracts": - [ + "linearizedBaseContracts": [ 9 ], "name": "C", "nameLocation": "9:1:1", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { - "body": - { + "body": { "id": 7, "nodeType": "Block", "src": "33:36:1", - "statements": - [ + "statements": [ { - "assignments": - [ + "assignments": [ 4 ], - "declarations": - [ + "declarations": [ { "constant": false, "id": 4, @@ -54,19 +45,16 @@ "src": "35:15:1", "stateVariable": false, "storageLocation": "memory", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_string_memory_ptr", "typeString": "string" }, - "typeName": - { + "typeName": { "id": 3, "name": "string", "nodeType": "ElementaryTypeName", "src": "35:6:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_string_storage_ptr", "typeString": "string" } @@ -75,8 +63,7 @@ } ], "id": 6, - "initialValue": - { + "initialValue": { "hexValue": "48656c6c6f20576f726c64", "id": 5, "isConstant": false, @@ -86,8 +73,7 @@ "lValueRequested": false, "nodeType": "Literal", "src": "53:13:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_stringliteral_592fa743889fc7f92ac2a37bb1f5ba1daf2a5c84741ca0e0061d243a2e6707ba", "typeString": "literal_string \"Hello World\"" }, @@ -106,15 +92,13 @@ "name": "f", "nameLocation": "22:1:1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 1, "nodeType": "ParameterList", "parameters": [], "src": "23:2:1" }, - "returnParameters": - { + "returnParameters": { "id": 2, "nodeType": "ParameterList", "parameters": [], diff --git a/test/libsolidity/ASTJSON/string_parseOnly.json b/test/libsolidity/ASTJSON/string_parseOnly.json index 5f97eb1f917e..4f8006e57206 100644 --- a/test/libsolidity/ASTJSON/string_parseOnly.json +++ b/test/libsolidity/ASTJSON/string_parseOnly.json @@ -2,8 +2,7 @@ "absolutePath": "a", "id": 10, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "abstract": false, "baseContracts": [], @@ -13,23 +12,18 @@ "name": "C", "nameLocation": "9:1:1", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { - "body": - { + "body": { "id": 7, "nodeType": "Block", "src": "33:36:1", - "statements": - [ + "statements": [ { - "assignments": - [ + "assignments": [ 4 ], - "declarations": - [ + "declarations": [ { "constant": false, "id": 4, @@ -41,8 +35,7 @@ "stateVariable": false, "storageLocation": "memory", "typeDescriptions": {}, - "typeName": - { + "typeName": { "id": 3, "name": "string", "nodeType": "ElementaryTypeName", @@ -53,8 +46,7 @@ } ], "id": 6, - "initialValue": - { + "initialValue": { "hexValue": "48656c6c6f20576f726c64", "id": 5, "kind": "string", @@ -75,15 +67,13 @@ "name": "f", "nameLocation": "22:1:1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 1, "nodeType": "ParameterList", "parameters": [], "src": "23:2:1" }, - "returnParameters": - { + "returnParameters": { "id": 2, "nodeType": "ParameterList", "parameters": [], diff --git a/test/libsolidity/ASTJSON/struct_natspec.json b/test/libsolidity/ASTJSON/struct_natspec.json index d8b38a8033d3..0a17909df628 100644 --- a/test/libsolidity/ASTJSON/struct_natspec.json +++ b/test/libsolidity/ASTJSON/struct_natspec.json @@ -1,28 +1,23 @@ { "absolutePath": "a", - "exportedSymbols": - { - "Example": - [ + "exportedSymbols": { + "Example": [ 8 ] }, "id": 9, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "canonicalName": "Example", - "documentation": - { + "documentation": { "id": 1, "nodeType": "StructuredDocumentation", "src": "0:112:1", "text": "@title example of title\n @author example of author\n @notice example of notice\n @dev example of dev" }, "id": 8, - "members": - [ + "members": [ { "constant": false, "id": 3, @@ -34,19 +29,16 @@ "src": "133:11:1", "stateVariable": false, "storageLocation": "default", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_string_storage_ptr", "typeString": "string" }, - "typeName": - { + "typeName": { "id": 2, "name": "string", "nodeType": "ElementaryTypeName", "src": "133:6:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_string_storage_ptr", "typeString": "string" } @@ -64,19 +56,16 @@ "src": "150:10:1", "stateVariable": false, "storageLocation": "default", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_bool", "typeString": "bool" }, - "typeName": - { + "typeName": { "id": 4, "name": "bool", "nodeType": "ElementaryTypeName", "src": "150:4:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_bool", "typeString": "bool" } @@ -94,19 +83,16 @@ "src": "166:13:1", "stateVariable": false, "storageLocation": "default", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_uint256", "typeString": "uint256" }, - "typeName": - { + "typeName": { "id": 6, "name": "uint256", "nodeType": "ElementaryTypeName", "src": "166:7:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_uint256", "typeString": "uint256" } diff --git a/test/libsolidity/ASTJSON/struct_natspec_parseOnly.json b/test/libsolidity/ASTJSON/struct_natspec_parseOnly.json index b80aaf377cb8..6ba465580b09 100644 --- a/test/libsolidity/ASTJSON/struct_natspec_parseOnly.json +++ b/test/libsolidity/ASTJSON/struct_natspec_parseOnly.json @@ -2,19 +2,16 @@ "absolutePath": "a", "id": 9, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { - "documentation": - { + "documentation": { "id": 1, "nodeType": "StructuredDocumentation", "src": "0:112:1", "text": "@title example of title\n @author example of author\n @notice example of notice\n @dev example of dev" }, "id": 8, - "members": - [ + "members": [ { "constant": false, "id": 3, @@ -26,8 +23,7 @@ "stateVariable": false, "storageLocation": "default", "typeDescriptions": {}, - "typeName": - { + "typeName": { "id": 2, "name": "string", "nodeType": "ElementaryTypeName", @@ -47,8 +43,7 @@ "stateVariable": false, "storageLocation": "default", "typeDescriptions": {}, - "typeName": - { + "typeName": { "id": 4, "name": "bool", "nodeType": "ElementaryTypeName", @@ -68,8 +63,7 @@ "stateVariable": false, "storageLocation": "default", "typeDescriptions": {}, - "typeName": - { + "typeName": { "id": 6, "name": "uint256", "nodeType": "ElementaryTypeName", diff --git a/test/libsolidity/ASTJSON/two_base_functions.json b/test/libsolidity/ASTJSON/two_base_functions.json index 0ed997a32fa3..132a7a9071bc 100644 --- a/test/libsolidity/ASTJSON/two_base_functions.json +++ b/test/libsolidity/ASTJSON/two_base_functions.json @@ -1,24 +1,19 @@ { "absolutePath": "a", - "exportedSymbols": - { - "A": - [ + "exportedSymbols": { + "A": [ 5 ], - "B": - [ + "B": [ 10 ], - "C": - [ + "C": [ 22 ] }, "id": 23, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "abstract": false, "baseContracts": [], @@ -27,18 +22,15 @@ "contractKind": "contract", "fullyImplemented": true, "id": 5, - "linearizedBaseContracts": - [ + "linearizedBaseContracts": [ 5 ], "name": "A", "nameLocation": "9:1:1", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { - "body": - { + "body": { "id": 3, "nodeType": "Block", "src": "45:2:1", @@ -52,15 +44,13 @@ "name": "f", "nameLocation": "26:1:1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 1, "nodeType": "ParameterList", "parameters": [], "src": "27:2:1" }, - "returnParameters": - { + "returnParameters": { "id": 2, "nodeType": "ParameterList", "parameters": [], @@ -86,18 +76,15 @@ "contractKind": "contract", "fullyImplemented": true, "id": 10, - "linearizedBaseContracts": - [ + "linearizedBaseContracts": [ 10 ], "name": "B", "nameLocation": "59:1:1", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { - "body": - { + "body": { "id": 8, "nodeType": "Block", "src": "95:2:1", @@ -111,15 +98,13 @@ "name": "f", "nameLocation": "76:1:1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 6, "nodeType": "ParameterList", "parameters": [], "src": "77:2:1" }, - "returnParameters": - { + "returnParameters": { "id": 7, "nodeType": "ParameterList", "parameters": [], @@ -139,15 +124,12 @@ }, { "abstract": false, - "baseContracts": - [ + "baseContracts": [ { - "baseName": - { + "baseName": { "id": 11, "name": "A", - "nameLocations": - [ + "nameLocations": [ "114:1:1" ], "nodeType": "IdentifierPath", @@ -159,12 +141,10 @@ "src": "114:1:1" }, { - "baseName": - { + "baseName": { "id": 13, "name": "B", - "nameLocations": - [ + "nameLocations": [ "117:1:1" ], "nodeType": "IdentifierPath", @@ -181,8 +161,7 @@ "contractKind": "contract", "fullyImplemented": true, "id": 22, - "linearizedBaseContracts": - [ + "linearizedBaseContracts": [ 22, 10, 5 @@ -190,16 +169,13 @@ "name": "C", "nameLocation": "109:1:1", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { - "baseFunctions": - [ + "baseFunctions": [ 4, 9 ], - "body": - { + "body": { "id": 20, "nodeType": "Block", "src": "160:2:1", @@ -213,17 +189,14 @@ "name": "f", "nameLocation": "134:1:1", "nodeType": "FunctionDefinition", - "overrides": - { + "overrides": { "id": 18, "nodeType": "OverrideSpecifier", - "overrides": - [ + "overrides": [ { "id": 16, "name": "A", - "nameLocations": - [ + "nameLocations": [ "154:1:1" ], "nodeType": "IdentifierPath", @@ -233,8 +206,7 @@ { "id": 17, "name": "B", - "nameLocations": - [ + "nameLocations": [ "157:1:1" ], "nodeType": "IdentifierPath", @@ -244,15 +216,13 @@ ], "src": "145:14:1" }, - "parameters": - { + "parameters": { "id": 15, "nodeType": "ParameterList", "parameters": [], "src": "135:2:1" }, - "returnParameters": - { + "returnParameters": { "id": 19, "nodeType": "ParameterList", "parameters": [], diff --git a/test/libsolidity/ASTJSON/two_base_functions.sol b/test/libsolidity/ASTJSON/two_base_functions.sol index 0a00bcc14505..89c8e207a531 100644 --- a/test/libsolidity/ASTJSON/two_base_functions.sol +++ b/test/libsolidity/ASTJSON/two_base_functions.sol @@ -7,4 +7,5 @@ contract B { contract C is A, B { function f() public override(A, B) {} } + // ---- diff --git a/test/libsolidity/ASTJSON/two_base_functions_parseOnly.json b/test/libsolidity/ASTJSON/two_base_functions_parseOnly.json index e448be836bf8..2e9691ac9870 100644 --- a/test/libsolidity/ASTJSON/two_base_functions_parseOnly.json +++ b/test/libsolidity/ASTJSON/two_base_functions_parseOnly.json @@ -2,8 +2,7 @@ "absolutePath": "a", "id": 23, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "abstract": false, "baseContracts": [], @@ -13,11 +12,9 @@ "name": "A", "nameLocation": "9:1:1", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { - "body": - { + "body": { "id": 3, "nodeType": "Block", "src": "45:2:1", @@ -30,15 +27,13 @@ "name": "f", "nameLocation": "26:1:1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 1, "nodeType": "ParameterList", "parameters": [], "src": "27:2:1" }, - "returnParameters": - { + "returnParameters": { "id": 2, "nodeType": "ParameterList", "parameters": [], @@ -63,11 +58,9 @@ "name": "B", "nameLocation": "59:1:1", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { - "body": - { + "body": { "id": 8, "nodeType": "Block", "src": "95:2:1", @@ -80,15 +73,13 @@ "name": "f", "nameLocation": "76:1:1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 6, "nodeType": "ParameterList", "parameters": [], "src": "77:2:1" }, - "returnParameters": - { + "returnParameters": { "id": 7, "nodeType": "ParameterList", "parameters": [], @@ -106,15 +97,12 @@ }, { "abstract": false, - "baseContracts": - [ + "baseContracts": [ { - "baseName": - { + "baseName": { "id": 11, "name": "A", - "nameLocations": - [ + "nameLocations": [ "114:1:1" ], "nodeType": "IdentifierPath", @@ -125,12 +113,10 @@ "src": "114:1:1" }, { - "baseName": - { + "baseName": { "id": 13, "name": "B", - "nameLocations": - [ + "nameLocations": [ "117:1:1" ], "nodeType": "IdentifierPath", @@ -147,11 +133,9 @@ "name": "C", "nameLocation": "109:1:1", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { - "body": - { + "body": { "id": 20, "nodeType": "Block", "src": "160:2:1", @@ -164,17 +148,14 @@ "name": "f", "nameLocation": "134:1:1", "nodeType": "FunctionDefinition", - "overrides": - { + "overrides": { "id": 18, "nodeType": "OverrideSpecifier", - "overrides": - [ + "overrides": [ { "id": 16, "name": "A", - "nameLocations": - [ + "nameLocations": [ "154:1:1" ], "nodeType": "IdentifierPath", @@ -183,8 +164,7 @@ { "id": 17, "name": "B", - "nameLocations": - [ + "nameLocations": [ "157:1:1" ], "nodeType": "IdentifierPath", @@ -193,15 +173,13 @@ ], "src": "145:14:1" }, - "parameters": - { + "parameters": { "id": 15, "nodeType": "ParameterList", "parameters": [], "src": "135:2:1" }, - "returnParameters": - { + "returnParameters": { "id": 19, "nodeType": "ParameterList", "parameters": [], diff --git a/test/libsolidity/ASTJSON/unicode.json b/test/libsolidity/ASTJSON/unicode.json index 0ff1426f17e2..2521e690e747 100644 --- a/test/libsolidity/ASTJSON/unicode.json +++ b/test/libsolidity/ASTJSON/unicode.json @@ -1,16 +1,13 @@ { "absolutePath": "a", - "exportedSymbols": - { - "C": - [ + "exportedSymbols": { + "C": [ 9 ] }, "id": 10, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "abstract": false, "baseContracts": [], @@ -19,30 +16,24 @@ "contractKind": "contract", "fullyImplemented": true, "id": 9, - "linearizedBaseContracts": - [ + "linearizedBaseContracts": [ 9 ], "name": "C", "nameLocation": "9:1:1", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { - "body": - { + "body": { "id": 7, "nodeType": "Block", "src": "33:42:1", - "statements": - [ + "statements": [ { - "assignments": - [ + "assignments": [ 4 ], - "declarations": - [ + "declarations": [ { "constant": false, "id": 4, @@ -54,19 +45,16 @@ "src": "35:15:1", "stateVariable": false, "storageLocation": "memory", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_string_memory_ptr", "typeString": "string" }, - "typeName": - { + "typeName": { "id": 3, "name": "string", "nodeType": "ElementaryTypeName", "src": "35:6:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_string_storage_ptr", "typeString": "string" } @@ -75,8 +63,7 @@ } ], "id": 6, - "initialValue": - { + "initialValue": { "hexValue": "48656c6c6f20f09f9883", "id": 5, "isConstant": false, @@ -86,8 +73,7 @@ "lValueRequested": false, "nodeType": "Literal", "src": "53:19:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_stringliteral_cd7a99177cebb3d14b8cc54e313dbf76867c71cd6fbb9a33ce3870dc80e9992b", "typeString": "literal_string hex\"48656c6c6f20f09f9883\"" }, @@ -106,15 +92,13 @@ "name": "f", "nameLocation": "22:1:1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 1, "nodeType": "ParameterList", "parameters": [], "src": "23:2:1" }, - "returnParameters": - { + "returnParameters": { "id": 2, "nodeType": "ParameterList", "parameters": [], diff --git a/test/libsolidity/ASTJSON/unicode_parseOnly.json b/test/libsolidity/ASTJSON/unicode_parseOnly.json index c8fb780c40cc..0567c08a088d 100644 --- a/test/libsolidity/ASTJSON/unicode_parseOnly.json +++ b/test/libsolidity/ASTJSON/unicode_parseOnly.json @@ -2,8 +2,7 @@ "absolutePath": "a", "id": 10, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "abstract": false, "baseContracts": [], @@ -13,23 +12,18 @@ "name": "C", "nameLocation": "9:1:1", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { - "body": - { + "body": { "id": 7, "nodeType": "Block", "src": "33:42:1", - "statements": - [ + "statements": [ { - "assignments": - [ + "assignments": [ 4 ], - "declarations": - [ + "declarations": [ { "constant": false, "id": 4, @@ -41,8 +35,7 @@ "stateVariable": false, "storageLocation": "memory", "typeDescriptions": {}, - "typeName": - { + "typeName": { "id": 3, "name": "string", "nodeType": "ElementaryTypeName", @@ -53,8 +46,7 @@ } ], "id": 6, - "initialValue": - { + "initialValue": { "hexValue": "48656c6c6f20f09f9883", "id": 5, "kind": "unicodeString", @@ -75,15 +67,13 @@ "name": "f", "nameLocation": "22:1:1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 1, "nodeType": "ParameterList", "parameters": [], "src": "23:2:1" }, - "returnParameters": - { + "returnParameters": { "id": 2, "nodeType": "ParameterList", "parameters": [], diff --git a/test/libsolidity/ASTJSON/used_errors.json b/test/libsolidity/ASTJSON/used_errors.json index cff59a5efc5b..9db7b6a98357 100644 --- a/test/libsolidity/ASTJSON/used_errors.json +++ b/test/libsolidity/ASTJSON/used_errors.json @@ -1,32 +1,26 @@ { "absolutePath": "a", - "exportedSymbols": - { - "C": - [ + "exportedSymbols": { + "C": [ 19 ], - "X": - [ + "X": [ 2 ], - "f": - [ + "f": [ 9 ] }, "id": 20, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "errorSelector": "c1599bd9", "id": 2, "name": "X", "nameLocation": "6:1:1", "nodeType": "ErrorDefinition", - "parameters": - { + "parameters": { "id": 1, "nodeType": "ParameterList", "parameters": [], @@ -35,19 +29,15 @@ "src": "0:10:1" }, { - "body": - { + "body": { "id": 8, "nodeType": "Block", "src": "29:15:1", - "statements": - [ + "statements": [ { - "errorCall": - { + "errorCall": { "arguments": [], - "expression": - { + "expression": { "argumentTypes": [], "id": 5, "name": "X", @@ -55,8 +45,7 @@ "overloadedDeclarations": [], "referencedDeclaration": 2, "src": "38:1:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_function_error_pure$__$returns$_t_error_$", "typeString": "function () pure returns (error)" } @@ -72,8 +61,7 @@ "nodeType": "FunctionCall", "src": "38:3:1", "tryCall": false, - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_error", "typeString": "error" } @@ -91,15 +79,13 @@ "name": "f", "nameLocation": "20:1:1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 3, "nodeType": "ParameterList", "parameters": [], "src": "21:2:1" }, - "returnParameters": - { + "returnParameters": { "id": 4, "nodeType": "ParameterList", "parameters": [], @@ -119,23 +105,20 @@ "contractKind": "contract", "fullyImplemented": true, "id": 19, - "linearizedBaseContracts": - [ + "linearizedBaseContracts": [ 19 ], "name": "C", "nameLocation": "54:1:1", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { "errorSelector": "2bc80f3a", "id": 11, "name": "T", "nameLocation": "68:1:1", "nodeType": "ErrorDefinition", - "parameters": - { + "parameters": { "id": 10, "nodeType": "ParameterList", "parameters": [], @@ -144,19 +127,15 @@ "src": "62:10:1" }, { - "body": - { + "body": { "id": 17, "nodeType": "Block", "src": "97:8:1", - "statements": - [ + "statements": [ { - "expression": - { + "expression": { "arguments": [], - "expression": - { + "expression": { "argumentTypes": [], "id": 14, "name": "f", @@ -164,8 +143,7 @@ "overloadedDeclarations": [], "referencedDeclaration": 9, "src": "99:1:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_function_internal_pure$__$returns$__$", "typeString": "function () pure" } @@ -181,8 +159,7 @@ "nodeType": "FunctionCall", "src": "99:3:1", "tryCall": false, - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_tuple$__$", "typeString": "tuple()" } @@ -201,15 +178,13 @@ "name": "h", "nameLocation": "86:1:1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 12, "nodeType": "ParameterList", "parameters": [], "src": "87:2:1" }, - "returnParameters": - { + "returnParameters": { "id": 13, "nodeType": "ParameterList", "parameters": [], @@ -224,8 +199,7 @@ ], "scope": 20, "src": "45:62:1", - "usedErrors": - [ + "usedErrors": [ 2, 11 ], diff --git a/test/libsolidity/ASTJSON/used_errors.sol b/test/libsolidity/ASTJSON/used_errors.sol index 97f7a27f48e2..24c03982fed6 100644 --- a/test/libsolidity/ASTJSON/used_errors.sol +++ b/test/libsolidity/ASTJSON/used_errors.sol @@ -4,4 +4,5 @@ contract C { error T(); function h() public { f(); } } + // ---- diff --git a/test/libsolidity/ASTJSON/used_errors_parseOnly.json b/test/libsolidity/ASTJSON/used_errors_parseOnly.json index 115ea2aee567..402291f29dfd 100644 --- a/test/libsolidity/ASTJSON/used_errors_parseOnly.json +++ b/test/libsolidity/ASTJSON/used_errors_parseOnly.json @@ -2,15 +2,13 @@ "absolutePath": "a", "id": 20, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "id": 2, "name": "X", "nameLocation": "6:1:1", "nodeType": "ErrorDefinition", - "parameters": - { + "parameters": { "id": 1, "nodeType": "ParameterList", "parameters": [], @@ -19,19 +17,15 @@ "src": "0:10:1" }, { - "body": - { + "body": { "id": 8, "nodeType": "Block", "src": "29:15:1", - "statements": - [ + "statements": [ { - "errorCall": - { + "errorCall": { "arguments": [], - "expression": - { + "expression": { "id": 5, "name": "X", "nodeType": "Identifier", @@ -60,15 +54,13 @@ "name": "f", "nameLocation": "20:1:1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 3, "nodeType": "ParameterList", "parameters": [], "src": "21:2:1" }, - "returnParameters": - { + "returnParameters": { "id": 4, "nodeType": "ParameterList", "parameters": [], @@ -88,15 +80,13 @@ "name": "C", "nameLocation": "54:1:1", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { "id": 11, "name": "T", "nameLocation": "68:1:1", "nodeType": "ErrorDefinition", - "parameters": - { + "parameters": { "id": 10, "nodeType": "ParameterList", "parameters": [], @@ -105,19 +95,15 @@ "src": "62:10:1" }, { - "body": - { + "body": { "id": 17, "nodeType": "Block", "src": "97:8:1", - "statements": - [ + "statements": [ { - "expression": - { + "expression": { "arguments": [], - "expression": - { + "expression": { "id": 14, "name": "f", "nodeType": "Identifier", @@ -146,15 +132,13 @@ "name": "h", "nameLocation": "86:1:1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 12, "nodeType": "ParameterList", "parameters": [], "src": "87:2:1" }, - "returnParameters": - { + "returnParameters": { "id": 13, "nodeType": "ParameterList", "parameters": [], diff --git a/test/libsolidity/ASTJSON/userDefinedValueType.json b/test/libsolidity/ASTJSON/userDefinedValueType.json index adf1172f05a9..51f8ee553bd5 100644 --- a/test/libsolidity/ASTJSON/userDefinedValueType.json +++ b/test/libsolidity/ASTJSON/userDefinedValueType.json @@ -1,28 +1,22 @@ { "absolutePath": "a", - "exportedSymbols": - { - "C": - [ + "exportedSymbols": { + "C": [ 27 ], - "MyAddress": - [ + "MyAddress": [ 2 ], - "MyUInt": - [ + "MyUInt": [ 4 ], - "f": - [ + "f": [ 16 ] }, "id": 28, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "canonicalName": "MyAddress", "id": 2, @@ -30,15 +24,13 @@ "nameLocation": "5:9:1", "nodeType": "UserDefinedValueTypeDefinition", "src": "0:26:1", - "underlyingType": - { + "underlyingType": { "id": 1, "name": "address", "nodeType": "ElementaryTypeName", "src": "18:7:1", "stateMutability": "nonpayable", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_address", "typeString": "address" } @@ -51,34 +43,28 @@ "nameLocation": "32:6:1", "nodeType": "UserDefinedValueTypeDefinition", "src": "27:20:1", - "underlyingType": - { + "underlyingType": { "id": 3, "name": "uint", "nodeType": "ElementaryTypeName", "src": "42:4:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_uint256", "typeString": "uint256" } } }, { - "body": - { + "body": { "id": 15, "nodeType": "Block", "src": "61:34:1", - "statements": - [ + "statements": [ { - "assignments": - [ + "assignments": [ 9 ], - "declarations": - [ + "declarations": [ { "constant": false, "id": 9, @@ -90,21 +76,17 @@ "src": "67:11:1", "stateVariable": false, "storageLocation": "default", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_userDefinedValueType$_MyAddress_$2", "typeString": "MyAddress" }, - "typeName": - { + "typeName": { "id": 8, "nodeType": "UserDefinedTypeName", - "pathNode": - { + "pathNode": { "id": 7, "name": "MyAddress", - "nameLocations": - [ + "nameLocations": [ "67:9:1" ], "nodeType": "IdentifierPath", @@ -113,8 +95,7 @@ }, "referencedDeclaration": 2, "src": "67:9:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_userDefinedValueType$_MyAddress_$2", "typeString": "MyAddress" } @@ -127,12 +108,10 @@ "src": "67:11:1" }, { - "assignments": - [ + "assignments": [ 13 ], - "declarations": - [ + "declarations": [ { "constant": false, "id": 13, @@ -144,21 +123,17 @@ "src": "84:8:1", "stateVariable": false, "storageLocation": "default", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_userDefinedValueType$_MyUInt_$4", "typeString": "MyUInt" }, - "typeName": - { + "typeName": { "id": 12, "nodeType": "UserDefinedTypeName", - "pathNode": - { + "pathNode": { "id": 11, "name": "MyUInt", - "nameLocations": - [ + "nameLocations": [ "84:6:1" ], "nodeType": "IdentifierPath", @@ -167,8 +142,7 @@ }, "referencedDeclaration": 4, "src": "84:6:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_userDefinedValueType$_MyUInt_$4", "typeString": "MyUInt" } @@ -189,15 +163,13 @@ "name": "f", "nameLocation": "57:1:1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 5, "nodeType": "ParameterList", "parameters": [], "src": "58:2:1" }, - "returnParameters": - { + "returnParameters": { "id": 6, "nodeType": "ParameterList", "parameters": [], @@ -217,15 +189,13 @@ "contractKind": "contract", "fullyImplemented": true, "id": 27, - "linearizedBaseContracts": - [ + "linearizedBaseContracts": [ 27 ], "name": "C", "nameLocation": "105:1:1", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { "canonicalName": "C.MyAddress", "id": 18, @@ -233,15 +203,13 @@ "nameLocation": "118:9:1", "nodeType": "UserDefinedValueTypeDefinition", "src": "113:26:1", - "underlyingType": - { + "underlyingType": { "id": 17, "name": "address", "nodeType": "ElementaryTypeName", "src": "131:7:1", "stateMutability": "nonpayable", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_address", "typeString": "address" } @@ -254,14 +222,12 @@ "nameLocation": "149:6:1", "nodeType": "UserDefinedValueTypeDefinition", "src": "144:20:1", - "underlyingType": - { + "underlyingType": { "id": 19, "name": "uint", "nodeType": "ElementaryTypeName", "src": "159:4:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_uint256", "typeString": "uint256" } @@ -279,26 +245,21 @@ "src": "169:37:1", "stateVariable": true, "storageLocation": "default", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_mapping$_t_userDefinedValueType$_MyAddress_$18_$_t_userDefinedValueType$_MyUInt_$20_$", "typeString": "mapping(C.MyAddress => C.MyUInt)" }, - "typeName": - { + "typeName": { "id": 25, "keyName": "", "keyNameLocation": "-1:-1:-1", - "keyType": - { + "keyType": { "id": 22, "nodeType": "UserDefinedTypeName", - "pathNode": - { + "pathNode": { "id": 21, "name": "MyAddress", - "nameLocations": - [ + "nameLocations": [ "177:9:1" ], "nodeType": "IdentifierPath", @@ -307,31 +268,26 @@ }, "referencedDeclaration": 18, "src": "177:9:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_userDefinedValueType$_MyAddress_$18", "typeString": "C.MyAddress" } }, "nodeType": "Mapping", "src": "169:28:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_mapping$_t_userDefinedValueType$_MyAddress_$18_$_t_userDefinedValueType$_MyUInt_$20_$", "typeString": "mapping(C.MyAddress => C.MyUInt)" }, "valueName": "", "valueNameLocation": "-1:-1:-1", - "valueType": - { + "valueType": { "id": 24, "nodeType": "UserDefinedTypeName", - "pathNode": - { + "pathNode": { "id": 23, "name": "MyUInt", - "nameLocations": - [ + "nameLocations": [ "190:6:1" ], "nodeType": "IdentifierPath", @@ -340,8 +296,7 @@ }, "referencedDeclaration": 20, "src": "190:6:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_userDefinedValueType$_MyUInt_$20", "typeString": "C.MyUInt" } diff --git a/test/libsolidity/ASTJSON/userDefinedValueType.sol b/test/libsolidity/ASTJSON/userDefinedValueType.sol index d5ef2e00b9f8..f1124f8cd6fd 100644 --- a/test/libsolidity/ASTJSON/userDefinedValueType.sol +++ b/test/libsolidity/ASTJSON/userDefinedValueType.sol @@ -9,4 +9,5 @@ contract C { type MyUInt is uint; mapping(MyAddress => MyUInt) public m; } + // ---- diff --git a/test/libsolidity/ASTJSON/userDefinedValueType_parseOnly.json b/test/libsolidity/ASTJSON/userDefinedValueType_parseOnly.json index 90e48a98276b..c3bb96ddd4df 100644 --- a/test/libsolidity/ASTJSON/userDefinedValueType_parseOnly.json +++ b/test/libsolidity/ASTJSON/userDefinedValueType_parseOnly.json @@ -2,16 +2,14 @@ "absolutePath": "a", "id": 28, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "id": 2, "name": "MyAddress", "nameLocation": "5:9:1", "nodeType": "UserDefinedValueTypeDefinition", "src": "0:26:1", - "underlyingType": - { + "underlyingType": { "id": 1, "name": "address", "nodeType": "ElementaryTypeName", @@ -26,8 +24,7 @@ "nameLocation": "32:6:1", "nodeType": "UserDefinedValueTypeDefinition", "src": "27:20:1", - "underlyingType": - { + "underlyingType": { "id": 3, "name": "uint", "nodeType": "ElementaryTypeName", @@ -36,20 +33,16 @@ } }, { - "body": - { + "body": { "id": 15, "nodeType": "Block", "src": "61:34:1", - "statements": - [ + "statements": [ { - "assignments": - [ + "assignments": [ 9 ], - "declarations": - [ + "declarations": [ { "constant": false, "id": 9, @@ -61,16 +54,13 @@ "stateVariable": false, "storageLocation": "default", "typeDescriptions": {}, - "typeName": - { + "typeName": { "id": 8, "nodeType": "UserDefinedTypeName", - "pathNode": - { + "pathNode": { "id": 7, "name": "MyAddress", - "nameLocations": - [ + "nameLocations": [ "67:9:1" ], "nodeType": "IdentifierPath", @@ -87,12 +77,10 @@ "src": "67:11:1" }, { - "assignments": - [ + "assignments": [ 13 ], - "declarations": - [ + "declarations": [ { "constant": false, "id": 13, @@ -104,16 +92,13 @@ "stateVariable": false, "storageLocation": "default", "typeDescriptions": {}, - "typeName": - { + "typeName": { "id": 12, "nodeType": "UserDefinedTypeName", - "pathNode": - { + "pathNode": { "id": 11, "name": "MyUInt", - "nameLocations": - [ + "nameLocations": [ "84:6:1" ], "nodeType": "IdentifierPath", @@ -138,15 +123,13 @@ "name": "f", "nameLocation": "57:1:1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 5, "nodeType": "ParameterList", "parameters": [], "src": "58:2:1" }, - "returnParameters": - { + "returnParameters": { "id": 6, "nodeType": "ParameterList", "parameters": [], @@ -166,16 +149,14 @@ "name": "C", "nameLocation": "105:1:1", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { "id": 18, "name": "MyAddress", "nameLocation": "118:9:1", "nodeType": "UserDefinedValueTypeDefinition", "src": "113:26:1", - "underlyingType": - { + "underlyingType": { "id": 17, "name": "address", "nodeType": "ElementaryTypeName", @@ -190,8 +171,7 @@ "nameLocation": "149:6:1", "nodeType": "UserDefinedValueTypeDefinition", "src": "144:20:1", - "underlyingType": - { + "underlyingType": { "id": 19, "name": "uint", "nodeType": "ElementaryTypeName", @@ -210,21 +190,17 @@ "stateVariable": false, "storageLocation": "default", "typeDescriptions": {}, - "typeName": - { + "typeName": { "id": 25, "keyName": "", "keyNameLocation": "-1:-1:-1", - "keyType": - { + "keyType": { "id": 22, "nodeType": "UserDefinedTypeName", - "pathNode": - { + "pathNode": { "id": 21, "name": "MyAddress", - "nameLocations": - [ + "nameLocations": [ "177:9:1" ], "nodeType": "IdentifierPath", @@ -238,16 +214,13 @@ "typeDescriptions": {}, "valueName": "", "valueNameLocation": "-1:-1:-1", - "valueType": - { + "valueType": { "id": 24, "nodeType": "UserDefinedTypeName", - "pathNode": - { + "pathNode": { "id": 23, "name": "MyUInt", - "nameLocations": - [ + "nameLocations": [ "190:6:1" ], "nodeType": "IdentifierPath", diff --git a/test/libsolidity/ASTJSON/user_defined_operator.json b/test/libsolidity/ASTJSON/user_defined_operator.json index ed72de49dd28..b39d2e07ea10 100644 --- a/test/libsolidity/ASTJSON/user_defined_operator.json +++ b/test/libsolidity/ASTJSON/user_defined_operator.json @@ -1,28 +1,22 @@ { "absolutePath": "a", - "exportedSymbols": - { - "C": - [ + "exportedSymbols": { + "C": [ 49 ], - "I8": - [ + "I8": [ 2 ], - "sub": - [ + "sub": [ 20 ], - "unsub": - [ + "unsub": [ 30 ] }, "id": 50, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "canonicalName": "I8", "id": 2, @@ -30,29 +24,24 @@ "nameLocation": "5:2:1", "nodeType": "UserDefinedValueTypeDefinition", "src": "0:16:1", - "underlyingType": - { + "underlyingType": { "id": 1, "name": "int8", "nodeType": "ElementaryTypeName", "src": "11:4:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_int8", "typeString": "int8" } } }, { - "functionList": - [ + "functionList": [ { - "definition": - { + "definition": { "id": 3, "name": "sub", - "nameLocations": - [ + "nameLocations": [ "24:3:1" ], "nodeType": "IdentifierPath", @@ -62,12 +51,10 @@ "operator": "-" }, { - "definition": - { + "definition": { "id": 4, "name": "unsub", - "nameLocations": - [ + "nameLocations": [ "34:5:1" ], "nodeType": "IdentifierPath", @@ -81,16 +68,13 @@ "id": 7, "nodeType": "UsingForDirective", "src": "17:43:1", - "typeName": - { + "typeName": { "id": 6, "nodeType": "UserDefinedTypeName", - "pathNode": - { + "pathNode": { "id": 5, "name": "I8", - "nameLocations": - [ + "nameLocations": [ "50:2:1" ], "nodeType": "IdentifierPath", @@ -99,16 +83,14 @@ }, "referencedDeclaration": 2, "src": "50:2:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_userDefinedValueType$_I8_$2", "typeString": "I8" } } }, { - "body": - { + "body": { "id": 19, "nodeType": "Block", "src": "100:2:1", @@ -121,12 +103,10 @@ "name": "sub", "nameLocation": "70:3:1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 14, "nodeType": "ParameterList", - "parameters": - [ + "parameters": [ { "constant": false, "id": 10, @@ -138,21 +118,17 @@ "src": "74:2:1", "stateVariable": false, "storageLocation": "default", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_userDefinedValueType$_I8_$2", "typeString": "I8" }, - "typeName": - { + "typeName": { "id": 9, "nodeType": "UserDefinedTypeName", - "pathNode": - { + "pathNode": { "id": 8, "name": "I8", - "nameLocations": - [ + "nameLocations": [ "74:2:1" ], "nodeType": "IdentifierPath", @@ -161,8 +137,7 @@ }, "referencedDeclaration": 2, "src": "74:2:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_userDefinedValueType$_I8_$2", "typeString": "I8" } @@ -180,21 +155,17 @@ "src": "78:2:1", "stateVariable": false, "storageLocation": "default", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_userDefinedValueType$_I8_$2", "typeString": "I8" }, - "typeName": - { + "typeName": { "id": 12, "nodeType": "UserDefinedTypeName", - "pathNode": - { + "pathNode": { "id": 11, "name": "I8", - "nameLocations": - [ + "nameLocations": [ "78:2:1" ], "nodeType": "IdentifierPath", @@ -203,8 +174,7 @@ }, "referencedDeclaration": 2, "src": "78:2:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_userDefinedValueType$_I8_$2", "typeString": "I8" } @@ -214,12 +184,10 @@ ], "src": "73:8:1" }, - "returnParameters": - { + "returnParameters": { "id": 18, "nodeType": "ParameterList", - "parameters": - [ + "parameters": [ { "constant": false, "id": 17, @@ -231,21 +199,17 @@ "src": "96:2:1", "stateVariable": false, "storageLocation": "default", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_userDefinedValueType$_I8_$2", "typeString": "I8" }, - "typeName": - { + "typeName": { "id": 16, "nodeType": "UserDefinedTypeName", - "pathNode": - { + "pathNode": { "id": 15, "name": "I8", - "nameLocations": - [ + "nameLocations": [ "96:2:1" ], "nodeType": "IdentifierPath", @@ -254,8 +218,7 @@ }, "referencedDeclaration": 2, "src": "96:2:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_userDefinedValueType$_I8_$2", "typeString": "I8" } @@ -272,8 +235,7 @@ "visibility": "internal" }, { - "body": - { + "body": { "id": 29, "nodeType": "Block", "src": "140:2:1", @@ -286,12 +248,10 @@ "name": "unsub", "nameLocation": "112:5:1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 24, "nodeType": "ParameterList", - "parameters": - [ + "parameters": [ { "constant": false, "id": 23, @@ -303,21 +263,17 @@ "src": "118:2:1", "stateVariable": false, "storageLocation": "default", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_userDefinedValueType$_I8_$2", "typeString": "I8" }, - "typeName": - { + "typeName": { "id": 22, "nodeType": "UserDefinedTypeName", - "pathNode": - { + "pathNode": { "id": 21, "name": "I8", - "nameLocations": - [ + "nameLocations": [ "118:2:1" ], "nodeType": "IdentifierPath", @@ -326,8 +282,7 @@ }, "referencedDeclaration": 2, "src": "118:2:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_userDefinedValueType$_I8_$2", "typeString": "I8" } @@ -337,12 +292,10 @@ ], "src": "117:4:1" }, - "returnParameters": - { + "returnParameters": { "id": 28, "nodeType": "ParameterList", - "parameters": - [ + "parameters": [ { "constant": false, "id": 27, @@ -354,21 +307,17 @@ "src": "136:2:1", "stateVariable": false, "storageLocation": "default", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_userDefinedValueType$_I8_$2", "typeString": "I8" }, - "typeName": - { + "typeName": { "id": 26, "nodeType": "UserDefinedTypeName", - "pathNode": - { + "pathNode": { "id": 25, "name": "I8", - "nameLocations": - [ + "nameLocations": [ "136:2:1" ], "nodeType": "IdentifierPath", @@ -377,8 +326,7 @@ }, "referencedDeclaration": 2, "src": "136:2:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_userDefinedValueType$_I8_$2", "typeString": "I8" } @@ -402,28 +350,22 @@ "contractKind": "contract", "fullyImplemented": true, "id": 49, - "linearizedBaseContracts": - [ + "linearizedBaseContracts": [ 49 ], "name": "C", "nameLocation": "152:1:1", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { - "body": - { + "body": { "id": 47, "nodeType": "Block", "src": "208:30:1", - "statements": - [ + "statements": [ { - "expression": - { - "commonType": - { + "expression": { + "commonType": { "typeIdentifier": "t_userDefinedValueType$_I8_$2", "typeString": "I8" }, @@ -433,8 +375,7 @@ "isLValue": false, "isPure": false, "lValueRequested": false, - "leftExpression": - { + "leftExpression": { "function": 30, "id": 43, "isConstant": false, @@ -445,45 +386,39 @@ "operator": "-", "prefix": true, "src": "225:2:1", - "subExpression": - { + "subExpression": { "id": 42, "name": "a", "nodeType": "Identifier", "overloadedDeclarations": [], "referencedDeclaration": 33, "src": "226:1:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_userDefinedValueType$_I8_$2", "typeString": "I8" } }, - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_userDefinedValueType$_I8_$2", "typeString": "I8" } }, "nodeType": "BinaryOperation", "operator": "-", - "rightExpression": - { + "rightExpression": { "id": 44, "name": "b", "nodeType": "Identifier", "overloadedDeclarations": [], "referencedDeclaration": 36, "src": "230:1:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_userDefinedValueType$_I8_$2", "typeString": "I8" } }, "src": "225:6:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_userDefinedValueType$_I8_$2", "typeString": "I8" } @@ -503,12 +438,10 @@ "name": "f", "nameLocation": "169:1:1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 37, "nodeType": "ParameterList", - "parameters": - [ + "parameters": [ { "constant": false, "id": 33, @@ -520,21 +453,17 @@ "src": "171:4:1", "stateVariable": false, "storageLocation": "default", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_userDefinedValueType$_I8_$2", "typeString": "I8" }, - "typeName": - { + "typeName": { "id": 32, "nodeType": "UserDefinedTypeName", - "pathNode": - { + "pathNode": { "id": 31, "name": "I8", - "nameLocations": - [ + "nameLocations": [ "171:2:1" ], "nodeType": "IdentifierPath", @@ -543,8 +472,7 @@ }, "referencedDeclaration": 2, "src": "171:2:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_userDefinedValueType$_I8_$2", "typeString": "I8" } @@ -562,21 +490,17 @@ "src": "177:4:1", "stateVariable": false, "storageLocation": "default", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_userDefinedValueType$_I8_$2", "typeString": "I8" }, - "typeName": - { + "typeName": { "id": 35, "nodeType": "UserDefinedTypeName", - "pathNode": - { + "pathNode": { "id": 34, "name": "I8", - "nameLocations": - [ + "nameLocations": [ "177:2:1" ], "nodeType": "IdentifierPath", @@ -585,8 +509,7 @@ }, "referencedDeclaration": 2, "src": "177:2:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_userDefinedValueType$_I8_$2", "typeString": "I8" } @@ -596,12 +519,10 @@ ], "src": "170:12:1" }, - "returnParameters": - { + "returnParameters": { "id": 41, "nodeType": "ParameterList", - "parameters": - [ + "parameters": [ { "constant": false, "id": 40, @@ -613,21 +534,17 @@ "src": "204:2:1", "stateVariable": false, "storageLocation": "default", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_userDefinedValueType$_I8_$2", "typeString": "I8" }, - "typeName": - { + "typeName": { "id": 39, "nodeType": "UserDefinedTypeName", - "pathNode": - { + "pathNode": { "id": 38, "name": "I8", - "nameLocations": - [ + "nameLocations": [ "204:2:1" ], "nodeType": "IdentifierPath", @@ -636,8 +553,7 @@ }, "referencedDeclaration": 2, "src": "204:2:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_userDefinedValueType$_I8_$2", "typeString": "I8" } diff --git a/test/libsolidity/ASTJSON/user_defined_operator.sol b/test/libsolidity/ASTJSON/user_defined_operator.sol index bfbdf7b9bf83..df5d0ed32609 100644 --- a/test/libsolidity/ASTJSON/user_defined_operator.sol +++ b/test/libsolidity/ASTJSON/user_defined_operator.sol @@ -7,4 +7,5 @@ contract C { return -a - b; } } + // ---- diff --git a/test/libsolidity/ASTJSON/using_for_directive.json b/test/libsolidity/ASTJSON/using_for_directive.json index f3094980ff12..b62ec8e865cc 100644 --- a/test/libsolidity/ASTJSON/using_for_directive.json +++ b/test/libsolidity/ASTJSON/using_for_directive.json @@ -1,34 +1,26 @@ { "absolutePath": "a", - "exportedSymbols": - { - "C": - [ + "exportedSymbols": { + "C": [ 13 ], - "L": - [ + "L": [ 4 ], - "f": - [ + "f": [ 10 ] }, "id": 14, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { - "functionList": - [ + "functionList": [ { - "function": - { + "function": { "id": 1, "name": "f", - "nameLocations": - [ + "nameLocations": [ "7:1:1" ], "nodeType": "IdentifierPath", @@ -41,14 +33,12 @@ "id": 3, "nodeType": "UsingForDirective", "src": "0:19:1", - "typeName": - { + "typeName": { "id": 2, "name": "uint", "nodeType": "ElementaryTypeName", "src": "14:4:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_uint256", "typeString": "uint256" } @@ -62,8 +52,7 @@ "contractKind": "library", "fullyImplemented": true, "id": 4, - "linearizedBaseContracts": - [ + "linearizedBaseContracts": [ 4 ], "name": "L", @@ -76,8 +65,7 @@ "usedEvents": [] }, { - "body": - { + "body": { "id": 9, "nodeType": "Block", "src": "50:2:1", @@ -90,12 +78,10 @@ "name": "f", "nameLocation": "42:1:1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 7, "nodeType": "ParameterList", - "parameters": - [ + "parameters": [ { "constant": false, "id": 6, @@ -107,19 +93,16 @@ "src": "44:4:1", "stateVariable": false, "storageLocation": "default", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_uint256", "typeString": "uint256" }, - "typeName": - { + "typeName": { "id": 5, "name": "uint", "nodeType": "ElementaryTypeName", "src": "44:4:1", - "typeDescriptions": - { + "typeDescriptions": { "typeIdentifier": "t_uint256", "typeString": "uint256" } @@ -129,8 +112,7 @@ ], "src": "43:6:1" }, - "returnParameters": - { + "returnParameters": { "id": 8, "nodeType": "ParameterList", "parameters": [], @@ -150,24 +132,20 @@ "contractKind": "contract", "fullyImplemented": true, "id": 13, - "linearizedBaseContracts": - [ + "linearizedBaseContracts": [ 13 ], "name": "C", "nameLocation": "62:1:1", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { "global": false, "id": 12, - "libraryName": - { + "libraryName": { "id": 11, "name": "L", - "nameLocations": - [ + "nameLocations": [ "72:1:1" ], "nodeType": "IdentifierPath", diff --git a/test/libsolidity/ASTJSON/using_for_directive_parseOnly.json b/test/libsolidity/ASTJSON/using_for_directive_parseOnly.json index 9360227d435e..4858081c23fb 100644 --- a/test/libsolidity/ASTJSON/using_for_directive_parseOnly.json +++ b/test/libsolidity/ASTJSON/using_for_directive_parseOnly.json @@ -2,18 +2,14 @@ "absolutePath": "a", "id": 14, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { - "functionList": - [ + "functionList": [ { - "function": - { + "function": { "id": 1, "name": "f", - "nameLocations": - [ + "nameLocations": [ "7:1:1" ], "nodeType": "IdentifierPath", @@ -25,8 +21,7 @@ "id": 3, "nodeType": "UsingForDirective", "src": "0:19:1", - "typeName": - { + "typeName": { "id": 2, "name": "uint", "nodeType": "ElementaryTypeName", @@ -49,8 +44,7 @@ "usedEvents": [] }, { - "body": - { + "body": { "id": 9, "nodeType": "Block", "src": "50:2:1", @@ -63,12 +57,10 @@ "name": "f", "nameLocation": "42:1:1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 7, "nodeType": "ParameterList", - "parameters": - [ + "parameters": [ { "constant": false, "id": 6, @@ -80,8 +72,7 @@ "stateVariable": false, "storageLocation": "default", "typeDescriptions": {}, - "typeName": - { + "typeName": { "id": 5, "name": "uint", "nodeType": "ElementaryTypeName", @@ -93,8 +84,7 @@ ], "src": "43:6:1" }, - "returnParameters": - { + "returnParameters": { "id": 8, "nodeType": "ParameterList", "parameters": [], @@ -114,17 +104,14 @@ "name": "C", "nameLocation": "62:1:1", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { "global": false, "id": 12, - "libraryName": - { + "libraryName": { "id": 11, "name": "L", - "nameLocations": - [ + "nameLocations": [ "72:1:1" ], "nodeType": "IdentifierPath", diff --git a/test/libsolidity/ASTJSON/yul_hex_literal.json b/test/libsolidity/ASTJSON/yul_hex_literal.json index 0498289c6729..22d8c6d8e91f 100644 --- a/test/libsolidity/ASTJSON/yul_hex_literal.json +++ b/test/libsolidity/ASTJSON/yul_hex_literal.json @@ -1,16 +1,13 @@ { "absolutePath": "a", - "exportedSymbols": - { - "Sample": - [ + "exportedSymbols": { + "Sample": [ 6 ] }, "id": 7, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "abstract": false, "baseContracts": [], @@ -19,37 +16,30 @@ "contractKind": "contract", "fullyImplemented": true, "id": 6, - "linearizedBaseContracts": - [ + "linearizedBaseContracts": [ 6 ], "name": "Sample", "nameLocation": "9:6:1", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { - "body": - { + "body": { "id": 4, "nodeType": "Block", "src": "47:167:1", - "statements": - [ + "statements": [ { - "AST": - { + "AST": { "nativeSrc": "66:142:1", "nodeType": "YulBlock", "src": "66:142:1", - "statements": - [ + "statements": [ { "nativeSrc": "80:15:1", "nodeType": "YulVariableDeclaration", "src": "80:15:1", - "value": - { + "value": { "hexValue": "74657374", "kind": "string", "nativeSrc": "89:6:1", @@ -58,8 +48,7 @@ "type": "", "value": "test" }, - "variables": - [ + "variables": [ { "name": "a", "nativeSrc": "84:1:1", @@ -73,8 +62,7 @@ "nativeSrc": "108:54:1", "nodeType": "YulVariableDeclaration", "src": "108:54:1", - "value": - { + "value": { "hexValue": "112233445566778899aabbccddeeff6677889900", "kind": "string", "nativeSrc": "117:45:1", @@ -82,8 +70,7 @@ "src": "117:45:1", "type": "" }, - "variables": - [ + "variables": [ { "name": "b", "nativeSrc": "112:1:1", @@ -97,8 +84,7 @@ "nativeSrc": "175:23:1", "nodeType": "YulVariableDeclaration", "src": "175:23:1", - "value": - { + "value": { "hexValue": "1234abcd", "kind": "string", "nativeSrc": "184:14:1", @@ -106,8 +92,7 @@ "src": "184:14:1", "type": "" }, - "variables": - [ + "variables": [ { "name": "c", "nativeSrc": "179:1:1", @@ -135,15 +120,13 @@ "name": "f", "nameLocation": "31:1:1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 1, "nodeType": "ParameterList", "parameters": [], "src": "32:2:1" }, - "returnParameters": - { + "returnParameters": { "id": 2, "nodeType": "ParameterList", "parameters": [], diff --git a/test/libsolidity/ASTJSON/yul_hex_literal.sol b/test/libsolidity/ASTJSON/yul_hex_literal.sol index c3b57a8fe8d2..f441866c1d1b 100644 --- a/test/libsolidity/ASTJSON/yul_hex_literal.sol +++ b/test/libsolidity/ASTJSON/yul_hex_literal.sol @@ -7,4 +7,5 @@ contract Sample { } } } + // ---- diff --git a/test/libsolidity/ASTJSON/yul_hex_literal_parseOnly.json b/test/libsolidity/ASTJSON/yul_hex_literal_parseOnly.json index 023c13cc7423..d26e2e29695f 100644 --- a/test/libsolidity/ASTJSON/yul_hex_literal_parseOnly.json +++ b/test/libsolidity/ASTJSON/yul_hex_literal_parseOnly.json @@ -2,8 +2,7 @@ "absolutePath": "a", "id": 7, "nodeType": "SourceUnit", - "nodes": - [ + "nodes": [ { "abstract": false, "baseContracts": [], @@ -13,30 +12,24 @@ "name": "Sample", "nameLocation": "9:6:1", "nodeType": "ContractDefinition", - "nodes": - [ + "nodes": [ { - "body": - { + "body": { "id": 4, "nodeType": "Block", "src": "47:167:1", - "statements": - [ + "statements": [ { - "AST": - { + "AST": { "nativeSrc": "66:142:1", "nodeType": "YulBlock", "src": "66:142:1", - "statements": - [ + "statements": [ { "nativeSrc": "80:15:1", "nodeType": "YulVariableDeclaration", "src": "80:15:1", - "value": - { + "value": { "hexValue": "74657374", "kind": "string", "nativeSrc": "89:6:1", @@ -45,8 +38,7 @@ "type": "", "value": "test" }, - "variables": - [ + "variables": [ { "name": "a", "nativeSrc": "84:1:1", @@ -60,8 +52,7 @@ "nativeSrc": "108:54:1", "nodeType": "YulVariableDeclaration", "src": "108:54:1", - "value": - { + "value": { "hexValue": "112233445566778899aabbccddeeff6677889900", "kind": "string", "nativeSrc": "117:45:1", @@ -69,8 +60,7 @@ "src": "117:45:1", "type": "" }, - "variables": - [ + "variables": [ { "name": "b", "nativeSrc": "112:1:1", @@ -84,8 +74,7 @@ "nativeSrc": "175:23:1", "nodeType": "YulVariableDeclaration", "src": "175:23:1", - "value": - { + "value": { "hexValue": "1234abcd", "kind": "string", "nativeSrc": "184:14:1", @@ -93,8 +82,7 @@ "src": "184:14:1", "type": "" }, - "variables": - [ + "variables": [ { "name": "c", "nativeSrc": "179:1:1", @@ -121,15 +109,13 @@ "name": "f", "nameLocation": "31:1:1", "nodeType": "FunctionDefinition", - "parameters": - { + "parameters": { "id": 1, "nodeType": "ParameterList", "parameters": [], "src": "32:2:1" }, - "returnParameters": - { + "returnParameters": { "id": 2, "nodeType": "ParameterList", "parameters": [], diff --git a/test/libsolutil/JSON.cpp b/test/libsolutil/JSON.cpp index 91e6771acc90..7b5528fffefb 100644 --- a/test/libsolutil/JSON.cpp +++ b/test/libsolutil/JSON.cpp @@ -91,8 +91,7 @@ BOOST_AUTO_TEST_CASE(json_pretty_print) "{\n" " \"1\": 1,\n" " \"2\": \"2\",\n" - " \"3\":\n" - " {\n" + " \"3\": {\n" " \"3.1\": \"3.1\",\n" " \"3.2\": 2\n" " },\n" From 2572e1345ed4cc94e96b15945717c4cfed87c19f Mon Sep 17 00:00:00 2001 From: Martin Blicha Date: Tue, 23 Apr 2024 13:20:38 +0200 Subject: [PATCH 0194/1022] SMTChecker: Fix equality of array literals There are two kinds of array literals in Solidity: string literals (arrays of characters/bytes) and proper array literals (e.g., [1,2,3]). While array literals cannot be directly tested for equality in Solidity, it is possible to compute hash of these values and compare hashes. The expectation is that hashes of the same array literals would be the same, but previously SMTChecker returned false positive in this case, saying that they don't have to be equal. The reason for the false positive was the following. We represent Solidity array literal as a tuple `(elements, length)` where `length` is an integer representing the actualy length of the array literal, and `elements` are an SMT-LIB array, where the first `length` elements represent the actual content of the array literal. However, SMT-LIB arrays are infinite objects (more like functions from indices to elements). Previously, we left the part after `length`-th element unspecified. For the solver this meant that two array literals equal at the Solidity level were represented with two different SMT-LIB arrays. The proposed solution is to always start from a constant-zero array, and use store operations to build an SMT-LIB array that matches the Solidity array literal. --- Changelog.md | 1 + libsolidity/formal/SMTEncoder.cpp | 21 ++++++++++++++++- .../model_checker_invariants_all/err | 2 +- .../err | 2 +- .../abi/abi_encode_packed_string_literal.sol | 20 +++++++--------- ...code_packed_string_literal_no_unproved.sol | 20 +++++++--------- .../abi/abi_encode_string_literal.sol | 17 ++++++-------- ...bi_encode_with_selector_string_literal.sol | 21 ++++++++--------- .../abi/abi_encode_with_sig_array_slice.sol | 7 ++---- .../abi/abi_encode_with_sig_array_slice_2.sol | 7 ++---- .../abi_encode_with_sig_string_literal.sol | 20 +++++++--------- .../crypto/crypto_functions_same_array.sol | 23 +++++++++++++++++++ .../crypto_functions_same_string_literal.sol | 23 +++++++++++++++++++ .../external_calls/call_mutex_unsafe.sol | 4 ++-- .../smtCheckerTests/types/array_literal_3.sol | 2 +- 15 files changed, 116 insertions(+), 74 deletions(-) create mode 100644 test/libsolidity/smtCheckerTests/crypto/crypto_functions_same_array.sol create mode 100644 test/libsolidity/smtCheckerTests/crypto/crypto_functions_same_string_literal.sol diff --git a/Changelog.md b/Changelog.md index 59284486b39c..b924b1ccde30 100644 --- a/Changelog.md +++ b/Changelog.md @@ -9,6 +9,7 @@ Compiler Features: Bugfixes: * Commandline Interface: Fix ICE when the optimizer is disabled and an empty/blank string is used for ``--yul-optimizations`` sequence. + * SMTChecker: Fix false positive when comparing hashes of same array or string literals. * SMTChecker: Fix internal error on mapping access caused by too strong requirements on sort compatibility of the index and mapping domain. * SMTChecker: Fix internal error when using an empty tuple in a conditional operator. * SMTChecker: Fix internal error when using bitwise operators with an array element as argument. diff --git a/libsolidity/formal/SMTEncoder.cpp b/libsolidity/formal/SMTEncoder.cpp index 61aad0e8f526..c92c5399a685 100644 --- a/libsolidity/formal/SMTEncoder.cpp +++ b/libsolidity/formal/SMTEncoder.cpp @@ -1296,8 +1296,27 @@ void SMTEncoder::addArrayLiteralAssertions( ) { m_context.addAssertion(_symArray.length() == _elementValues.size()); + + // Assert to the solver that _elementValues are exactly the elements at the beginning of the array. + // Since we create new symbolic representation for every array literal in the source file, we want to ensure that + // representations of two equal literals are also equal. For this reason we always start from constant-zero array. + // This ensures SMT-LIB arrays (which are infinite) are also equal beyond the length of the Solidity array literal. + auto type = _symArray.type(); + smtAssert(type); + auto valueType = [&]() { + if (auto const* arrayType = dynamic_cast(type)) + return arrayType->baseType(); + if (smt::isStringLiteral(*type)) + return TypeProvider::stringMemory()->baseType(); + smtAssert(false); + }(); + auto tupleSort = std::dynamic_pointer_cast(smt::smtSort(*type)); + auto sortSort = std::make_shared(tupleSort->components.front()); + smtutil::Expression arrayExpr = smtutil::Expression::const_array(smtutil::Expression(sortSort), smt::zeroValue(valueType)); + smtAssert(arrayExpr.sort->kind == smtutil::Kind::Array); for (size_t i = 0; i < _elementValues.size(); i++) - m_context.addAssertion(smtutil::Expression::select(_symArray.elements(), i) == _elementValues[i]); + arrayExpr = smtutil::Expression::store(arrayExpr, smtutil::Expression(i), _elementValues[i]); + m_context.addAssertion(_symArray.elements() == arrayExpr); } void SMTEncoder::bytesToFixedBytesAssertions( diff --git a/test/cmdlineTests/model_checker_invariants_all/err b/test/cmdlineTests/model_checker_invariants_all/err index 347f40325d14..7ec97678e990 100644 --- a/test/cmdlineTests/model_checker_invariants_all/err +++ b/test/cmdlineTests/model_checker_invariants_all/err @@ -9,6 +9,6 @@ Info: CHC: 1 verification condition(s) proved safe! Enable the model checker opt Info: Contract invariant(s) for model_checker_invariants_all/input.sol:test: (!(x >= 1) || true) Reentrancy property(ies) for model_checker_invariants_all/input.sol:test: -(((!(x <= 0) || !(x' >= 1)) && (!(x <= 0) || !( >= 1))) || true) +(((!(x <= 0) || !( >= 1)) && (!(x <= 0) || !(x' >= 1))) || true) = 0 -> no errors = 1 -> Assertion failed at assert(x == 0) diff --git a/test/cmdlineTests/model_checker_invariants_contract_reentrancy/err b/test/cmdlineTests/model_checker_invariants_contract_reentrancy/err index c6d149f15a40..11ee3a702f8c 100644 --- a/test/cmdlineTests/model_checker_invariants_contract_reentrancy/err +++ b/test/cmdlineTests/model_checker_invariants_contract_reentrancy/err @@ -9,6 +9,6 @@ Info: CHC: 1 verification condition(s) proved safe! Enable the model checker opt Info: Contract invariant(s) for model_checker_invariants_contract_reentrancy/input.sol:test: (!(x >= 1) || true) Reentrancy property(ies) for model_checker_invariants_contract_reentrancy/input.sol:test: -(((!(x <= 0) || !(x' >= 1)) && (!(x <= 0) || !( >= 1))) || true) +(((!(x <= 0) || !( >= 1)) && (!(x <= 0) || !(x' >= 1))) || true) = 0 -> no errors = 1 -> Assertion failed at assert(x == 0) diff --git a/test/libsolidity/smtCheckerTests/abi/abi_encode_packed_string_literal.sol b/test/libsolidity/smtCheckerTests/abi/abi_encode_packed_string_literal.sol index 08c48cbd99de..47b15369c04c 100644 --- a/test/libsolidity/smtCheckerTests/abi/abi_encode_packed_string_literal.sol +++ b/test/libsolidity/smtCheckerTests/abi/abi_encode_packed_string_literal.sol @@ -2,18 +2,16 @@ contract C { function abiencodePackedStringLiteral() public pure { bytes memory b1 = abi.encodePacked(""); bytes memory b2 = abi.encodePacked(""); - // should hold, but currently fails due to string literal abstraction - assert(b1.length == b2.length); + assert(b1.length == b2.length); // should hold bytes memory b3 = abi.encodePacked(bytes("")); - assert(b1.length == b3.length); // should fail + assert(b1.length == b3.length); // should hold bytes memory b4 = abi.encodePacked(bytes24("")); - // should hold, but currently fails due to string literal abstraction - assert(b1.length == b4.length); + assert(b1.length == b4.length); // should fail bytes memory b5 = abi.encodePacked(string("")); - assert(b1.length == b5.length); // should fail + assert(b1.length == b5.length); // should hold, but currently fails due to abstraction bytes memory b6 = abi.encode(""); assert(b1.length == b6.length); // should fail @@ -21,10 +19,8 @@ contract C { } // ==== // SMTEngine: all -// SMTIgnoreOS: macos // ---- -// Warning 6328: (226-256): CHC: Assertion violation happens here.\nCounterexample:\n\nb1 = [0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42]\nb3 = []\nb4 = []\nb5 = []\nb6 = []\n\nTransaction trace:\nC.constructor()\nC.abiencodePackedStringLiteral() -// Warning 6328: (310-340): CHC: Assertion violation happens here.\nCounterexample:\n\nb2 = [0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72]\nb4 = []\nb5 = []\nb6 = []\n\nTransaction trace:\nC.constructor()\nC.abiencodePackedStringLiteral() -// Warning 6328: (483-513): CHC: Assertion violation happens here.\nCounterexample:\n\nb5 = []\nb6 = []\n\nTransaction trace:\nC.constructor()\nC.abiencodePackedStringLiteral() -// Warning 6328: (568-598): CHC: Assertion violation happens here.\nCounterexample:\n\nb2 = [0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc]\nb6 = []\n\nTransaction trace:\nC.constructor()\nC.abiencodePackedStringLiteral() -// Warning 6328: (654-684): CHC: Assertion violation happens here.\nCounterexample:\n\nb3 = [0x011a, 0x011a, 0x011a, 0x011a, 0x011a, 0x011a, 0x011a, 0x011a, 0x011a, 0x011a, 0x011a, 0x011a, 0x011a, 0x011a, 0x011a, 0x011a, 0x011a, 0x011a, 0x011a, 0x011a, 0x011a, 0x011a, 0x011a, 0x011a, 0x011a, 0x011a, 0x011a, 0x011a, 0x011a, 0x011a, 0x011a, 0x011a, 0x011a, 0x011a, 0x011a, 0x011a, 0x011a, 0x011a, 0x011a, 0x011a, 0x011a, 0x011a, 0x011a, 0x011a, 0x011a, 0x011a, 0x011a, 0x011a, 0x011a, 0x011a, 0x011a, 0x011a, 0x011a, 0x011a, 0x011a, 0x011a, 0x011a, 0x011a, 0x011a, 0x011a, 0x011a, 0x011a, 0x011a, 0x011a, 0x011a, 0x011a]\nb6 = [0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117]\n\nTransaction trace:\nC.constructor()\nC.abiencodePackedStringLiteral() +// Warning 6328: (354-384): CHC: Assertion violation happens here.\nCounterexample:\n\nb5 = []\nb6 = []\n\nTransaction trace:\nC.constructor()\nC.abiencodePackedStringLiteral() +// Warning 6328: (454-484): CHC: Assertion violation happens here.\nCounterexample:\n\nb6 = []\n\nTransaction trace:\nC.constructor()\nC.abiencodePackedStringLiteral() +// Warning 6328: (580-610): CHC: Assertion violation happens here.\nCounterexample:\n\n\nTransaction trace:\nC.constructor()\nC.abiencodePackedStringLiteral() +// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/abi/abi_encode_packed_string_literal_no_unproved.sol b/test/libsolidity/smtCheckerTests/abi/abi_encode_packed_string_literal_no_unproved.sol index f80027626102..581e649fcbbe 100644 --- a/test/libsolidity/smtCheckerTests/abi/abi_encode_packed_string_literal_no_unproved.sol +++ b/test/libsolidity/smtCheckerTests/abi/abi_encode_packed_string_literal_no_unproved.sol @@ -2,18 +2,16 @@ contract C { function abiencodePackedStringLiteral() public pure { bytes memory b1 = abi.encodePacked(""); bytes memory b2 = abi.encodePacked(""); - // should hold, but currently fails due to string literal abstraction - assert(b1.length == b2.length); + assert(b1.length == b2.length); // should hold bytes memory b3 = abi.encodePacked(bytes("")); - assert(b1.length == b3.length); // should fail + assert(b1.length == b3.length); // should hold bytes memory b4 = abi.encodePacked(bytes24("")); - // should hold, but currently fails due to string literal abstraction - assert(b1.length == b4.length); + assert(b1.length == b4.length); // should fail bytes memory b5 = abi.encodePacked(string("")); - assert(b1.length == b5.length); // should fail + assert(b1.length == b5.length); // should hold, but fails due to abstraction bytes memory b6 = abi.encode(""); assert(b1.length == b6.length); // should fail @@ -22,10 +20,8 @@ contract C { // ==== // SMTEngine: all // SMTShowUnproved: no -// SMTIgnoreOS: macos // ---- -// Warning 6328: (226-256): CHC: Assertion violation happens here.\nCounterexample:\n\nb1 = [0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42]\nb3 = []\nb4 = []\nb5 = []\nb6 = []\n\nTransaction trace:\nC.constructor()\nC.abiencodePackedStringLiteral() -// Warning 6328: (310-340): CHC: Assertion violation happens here.\nCounterexample:\n\nb2 = [0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72]\nb4 = []\nb5 = []\nb6 = []\n\nTransaction trace:\nC.constructor()\nC.abiencodePackedStringLiteral() -// Warning 6328: (483-513): CHC: Assertion violation happens here.\nCounterexample:\n\nb5 = []\nb6 = []\n\nTransaction trace:\nC.constructor()\nC.abiencodePackedStringLiteral() -// Warning 6328: (568-598): CHC: Assertion violation happens here.\nCounterexample:\n\nb2 = [0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc]\nb6 = []\n\nTransaction trace:\nC.constructor()\nC.abiencodePackedStringLiteral() -// Warning 6328: (654-684): CHC: Assertion violation happens here.\nCounterexample:\n\nb3 = [0x011a, 0x011a, 0x011a, 0x011a, 0x011a, 0x011a, 0x011a, 0x011a, 0x011a, 0x011a, 0x011a, 0x011a, 0x011a, 0x011a, 0x011a, 0x011a, 0x011a, 0x011a, 0x011a, 0x011a, 0x011a, 0x011a, 0x011a, 0x011a, 0x011a, 0x011a, 0x011a, 0x011a, 0x011a, 0x011a, 0x011a, 0x011a, 0x011a, 0x011a, 0x011a, 0x011a, 0x011a, 0x011a, 0x011a, 0x011a, 0x011a, 0x011a, 0x011a, 0x011a, 0x011a, 0x011a, 0x011a, 0x011a, 0x011a, 0x011a, 0x011a, 0x011a, 0x011a, 0x011a, 0x011a, 0x011a, 0x011a, 0x011a, 0x011a, 0x011a, 0x011a, 0x011a, 0x011a, 0x011a, 0x011a, 0x011a]\nb6 = [0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117]\n\nTransaction trace:\nC.constructor()\nC.abiencodePackedStringLiteral() +// Warning 6328: (354-384): CHC: Assertion violation happens here.\nCounterexample:\n\nb5 = []\nb6 = []\n\nTransaction trace:\nC.constructor()\nC.abiencodePackedStringLiteral() +// Warning 6328: (454-484): CHC: Assertion violation happens here.\nCounterexample:\n\nb6 = []\n\nTransaction trace:\nC.constructor()\nC.abiencodePackedStringLiteral() +// Warning 6328: (570-600): CHC: Assertion violation happens here.\nCounterexample:\n\n\nTransaction trace:\nC.constructor()\nC.abiencodePackedStringLiteral() +// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/abi/abi_encode_string_literal.sol b/test/libsolidity/smtCheckerTests/abi/abi_encode_string_literal.sol index b55952ee74f6..77d3cfb83be4 100644 --- a/test/libsolidity/smtCheckerTests/abi/abi_encode_string_literal.sol +++ b/test/libsolidity/smtCheckerTests/abi/abi_encode_string_literal.sol @@ -2,25 +2,22 @@ contract C { function abiEncodeStringLiteral() public pure { bytes memory b1 = abi.encode(""); bytes memory b2 = abi.encode(""); - // should hold, but currently fails due to string literal abstraction + // should hold assert(b1.length == b2.length); bytes memory b3 = abi.encode(bytes("")); - assert(b1.length == b3.length); // should fail + assert(b1.length == b3.length); // should hold bytes memory b4 = abi.encode(bytes24("")); - // should hold, but currently fails due to string literal abstraction - assert(b1.length == b4.length); + assert(b1.length == b4.length); // should fail bytes memory b5 = abi.encode(string("")); - assert(b1.length == b5.length); // should fail + assert(b1.length == b5.length); // should hold, but currently fails due to abstraction } } // ==== // SMTEngine: all -// SMTIgnoreOS: macos // ---- -// Warning 6328: (208-238): CHC: Assertion violation happens here.\nCounterexample:\n\nb3 = []\nb4 = []\nb5 = []\n\nTransaction trace:\nC.constructor()\nC.abiEncodeStringLiteral() -// Warning 6328: (286-316): CHC: Assertion violation happens here.\nCounterexample:\n\nb2 = [0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d]\nb3 = [0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d]\nb4 = []\nb5 = []\n\nTransaction trace:\nC.constructor()\nC.abiEncodeStringLiteral() -// Warning 6328: (453-483): CHC: Assertion violation happens here.\nCounterexample:\n\nb5 = []\n\nTransaction trace:\nC.constructor()\nC.abiEncodeStringLiteral() -// Warning 6328: (532-562): CHC: Assertion violation happens here.\nCounterexample:\n\nb3 = [0xca, 0xca, 0xca, 0xca, 0xca, 0xca, 0xca, 0xca, 0xca, 0xca, 0xca, 0xca, 0xca, 0xca, 0xca, 0xca, 0xca, 0xca, 0xca, 0xca, 0xca, 0xca, 0xca, 0xca, 0xca, 0xca, 0xca, 0xca, 0xca, 0xca, 0xca, 0xca, 0xca, 0xca, 0xca, 0xca, 0xca, 0xca, 0xca, 0xca, 0xca, 0xca, 0xca, 0xca, 0xca, 0xca, 0xca, 0xca, 0xca, 0xca, 0xca, 0xca, 0xca, 0xca, 0xca, 0xca, 0xca, 0xca, 0xca, 0xca, 0xca, 0xca, 0xca, 0xca, 0xca, 0xca]\n\nTransaction trace:\nC.constructor()\nC.abiEncodeStringLiteral() +// Warning 6328: (326-356): CHC: Assertion violation happens here.\nCounterexample:\n\nb5 = []\n\nTransaction trace:\nC.constructor()\nC.abiEncodeStringLiteral() +// Warning 6328: (420-450): CHC: Assertion violation happens here.\nCounterexample:\n\n\nTransaction trace:\nC.constructor()\nC.abiEncodeStringLiteral() +// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/abi/abi_encode_with_selector_string_literal.sol b/test/libsolidity/smtCheckerTests/abi/abi_encode_with_selector_string_literal.sol index 6d1ab3066c84..dd183263a42f 100644 --- a/test/libsolidity/smtCheckerTests/abi/abi_encode_with_selector_string_literal.sol +++ b/test/libsolidity/smtCheckerTests/abi/abi_encode_with_selector_string_literal.sol @@ -2,18 +2,17 @@ contract C { function abiEncodeStringLiteral(bytes4 sel) public pure { bytes memory b1 = abi.encodeWithSelector(sel, ""); bytes memory b2 = abi.encodeWithSelector(sel, ""); - // should hold, but currently fails due to string literal abstraction - assert(b1.length == b2.length); + + assert(b1.length == b2.length); // should hold bytes memory b3 = abi.encodeWithSelector(sel, bytes("")); - assert(b1.length == b3.length); // should fail + assert(b1.length == b3.length); // should hold bytes memory b4 = abi.encodeWithSelector(sel, bytes24("")); - // should hold, but currently fails due to string literal abstraction - assert(b1.length == b4.length); + assert(b1.length == b4.length); // should fail bytes memory b5 = abi.encodeWithSelector(sel, string("")); - assert(b1.length == b5.length); // should fail + assert(b1.length == b5.length); // should hold, but currently fails due to abstraction bytes memory b6 = abi.encodeWithSelector(0xcafecafe, bytes24("")); assert(b4.length == b6.length); // should fail @@ -21,10 +20,8 @@ contract C { } // ==== // SMTEngine: all -// SMTIgnoreOS: macos // ---- -// Warning 6328: (252-282): CHC: Assertion violation happens here.\nCounterexample:\n\nsel = 0x0\nb1 = [0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46]\nb3 = []\nb4 = []\nb5 = []\nb6 = []\n\nTransaction trace:\nC.constructor()\nC.abiEncodeStringLiteral(0x0) -// Warning 6328: (347-377): CHC: Assertion violation happens here.\nCounterexample:\n\nsel = 0x0\nb3 = [0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d]\nb4 = []\nb5 = []\nb6 = []\n\nTransaction trace:\nC.constructor()\nC.abiEncodeStringLiteral(0x0) -// Warning 6328: (531-561): CHC: Assertion violation happens here.\nCounterexample:\n\nsel = 0x0\nb1 = [0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90]\nb5 = []\nb6 = []\n\nTransaction trace:\nC.constructor()\nC.abiEncodeStringLiteral(0x0) -// Warning 6328: (627-657): CHC: Assertion violation happens here.\nCounterexample:\n\nsel = 0x0\nb5 = [0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1]\nb6 = []\n\nTransaction trace:\nC.constructor()\nC.abiEncodeStringLiteral(0x0) -// Warning 6328: (746-776): CHC: Assertion violation happens here.\nCounterexample:\n\nsel = 0x0\nb2 = []\nb5 = [0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2]\n\nTransaction trace:\nC.constructor()\nC.abiEncodeStringLiteral(0x0) +// Warning 6328: (403-433): CHC: Assertion violation happens here.\nCounterexample:\n\nsel = 0x0\nb5 = []\nb6 = []\n\nTransaction trace:\nC.constructor()\nC.abiEncodeStringLiteral(0x0) +// Warning 6328: (514-544): CHC: Assertion violation happens here.\nCounterexample:\n\nsel = 0x0\nb6 = []\n\nTransaction trace:\nC.constructor()\nC.abiEncodeStringLiteral(0x0) +// Warning 6328: (673-703): CHC: Assertion violation happens here.\nCounterexample:\n\nsel = 0x0\nb6 = []\n\nTransaction trace:\nC.constructor()\nC.abiEncodeStringLiteral(0x0) +// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/abi/abi_encode_with_sig_array_slice.sol b/test/libsolidity/smtCheckerTests/abi/abi_encode_with_sig_array_slice.sol index fad7437448f3..b2d1b4acc6d0 100644 --- a/test/libsolidity/smtCheckerTests/abi/abi_encode_with_sig_array_slice.sol +++ b/test/libsolidity/smtCheckerTests/abi/abi_encode_with_sig_array_slice.sol @@ -24,10 +24,7 @@ contract C { } // ==== // SMTEngine: all -// SMTIgnoreOS: macos // ---- -// Warning 6328: (334-364): CHC: Assertion violation happens here. +// Warning 6328: (334-364): CHC: Assertion violation happens here.\nCounterexample:\n\ndata = [0x4f]\nb2 = [0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c]\nb3 = []\nb4 = []\nx = 0\ny = 0\nb5 = []\nb6 = []\n\nTransaction trace:\nC.constructor()\nC.abiEncodeSlice(sig, [0x4f]) -- counterexample incomplete; parameter name used instead of value // Warning 6328: (588-618): CHC: Assertion violation happens here. -// Warning 6328: (1086-1116): CHC: Assertion violation might happen here. -// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. -// Warning 4661: (1086-1116): BMC: Assertion violation happens here. +// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/abi/abi_encode_with_sig_array_slice_2.sol b/test/libsolidity/smtCheckerTests/abi/abi_encode_with_sig_array_slice_2.sol index 41e71ee5bf0e..4c21a02a6bbb 100644 --- a/test/libsolidity/smtCheckerTests/abi/abi_encode_with_sig_array_slice_2.sol +++ b/test/libsolidity/smtCheckerTests/abi/abi_encode_with_sig_array_slice_2.sol @@ -24,10 +24,7 @@ contract C { } // ==== // SMTEngine: all -// SMTIgnoreOS: macos // ---- -// Warning 6328: (335-365): CHC: Assertion violation happens here. +// Warning 6328: (335-365): CHC: Assertion violation happens here.\nCounterexample:\n\ndata = [36]\nb3 = []\nb4 = []\nx = 0\ny = 0\nb5 = []\nb6 = []\n\nTransaction trace:\nC.constructor()\nC.abiEncodeSlice(sig, [36]) -- counterexample incomplete; parameter name used instead of value // Warning 6328: (589-619): CHC: Assertion violation happens here. -// Warning 6328: (1087-1117): CHC: Assertion violation might happen here. -// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. -// Warning 4661: (1087-1117): BMC: Assertion violation happens here. +// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/abi/abi_encode_with_sig_string_literal.sol b/test/libsolidity/smtCheckerTests/abi/abi_encode_with_sig_string_literal.sol index de218cfaa6d6..ca782442b6f1 100644 --- a/test/libsolidity/smtCheckerTests/abi/abi_encode_with_sig_string_literal.sol +++ b/test/libsolidity/smtCheckerTests/abi/abi_encode_with_sig_string_literal.sol @@ -2,18 +2,16 @@ contract C { function abiEncodeStringLiteral(string memory sig) public pure { bytes memory b1 = abi.encodeWithSignature(sig, ""); bytes memory b2 = abi.encodeWithSignature(sig, ""); - // should hold, but currently fails due to string literal abstraction - assert(b1.length == b2.length); + assert(b1.length == b2.length); // should hold bytes memory b3 = abi.encodeWithSignature(sig, bytes("")); - assert(b1.length == b3.length); // should fail + assert(b1.length == b3.length); // should hold bytes memory b4 = abi.encodeWithSignature(sig, bytes24("")); - // should hold, but currently fails due to string literal abstraction - assert(b1.length == b4.length); + assert(b1.length == b4.length); // should fail bytes memory b5 = abi.encodeWithSignature(sig, string("")); - assert(b1.length == b5.length); // should fail + assert(b1.length == b5.length); // should hold, but currently fails due to abstraction bytes memory b6 = abi.encodeWithSelector("f()", bytes24("")); assert(b4.length == b6.length); // should fail @@ -21,10 +19,8 @@ contract C { } // ==== // SMTEngine: all -// SMTIgnoreOS: macos // ---- -// Warning 6328: (261-291): CHC: Assertion violation happens here.\nCounterexample:\n\nb2 = [0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a]\nb3 = []\nb4 = []\nb5 = []\nb6 = []\n\nTransaction trace:\nC.constructor()\nC.abiEncodeStringLiteral(sig) -// Warning 6328: (357-387): CHC: Assertion violation happens here.\nCounterexample:\n\nb3 = [0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90]\nb4 = []\nb5 = []\nb6 = []\n\nTransaction trace:\nC.constructor()\nC.abiEncodeStringLiteral(sig) -// Warning 6328: (542-572): CHC: Assertion violation happens here.\nCounterexample:\n\nb3 = [0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa]\nb5 = []\nb6 = []\n\nTransaction trace:\nC.constructor()\nC.abiEncodeStringLiteral(sig) -// Warning 6328: (639-669): CHC: Assertion violation happens here.\nCounterexample:\n\nb4 = [0x22, 0x22, 0x22, 0x22, 0x22, 0x0d, 0x22, 0x22, 0x22, 0x22, 0x09, 0x22, 0x0b, 0x22, 0x22, 0x0e, 0x22, 0x10, 0x22, 0x12, 0x22, 0x14, 0x22, 0x16, 0x22, 0x18, 0x22, 0x1a, 0x22, 0x1c, 0x22, 0x1e, 0x22, 0x20, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22]\nb6 = []\n\nTransaction trace:\nC.constructor()\nC.abiEncodeStringLiteral(sig) -// Warning 6328: (753-783): CHC: Assertion violation happens here.\nCounterexample:\n\nb2 = [0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117]\nb4 = []\nb5 = [0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118]\n\nTransaction trace:\nC.constructor()\nC.abiEncodeStringLiteral(sig) +// Warning 6328: (413-443): CHC: Assertion violation happens here.\nCounterexample:\n\nb5 = []\nb6 = []\n\nTransaction trace:\nC.constructor()\nC.abiEncodeStringLiteral(sig) -- counterexample incomplete; parameter name used instead of value +// Warning 6328: (525-555): CHC: Assertion violation happens here.\nCounterexample:\n\nb6 = []\n\nTransaction trace:\nC.constructor()\nC.abiEncodeStringLiteral(sig) -- counterexample incomplete; parameter name used instead of value +// Warning 6328: (679-709): CHC: Assertion violation happens here.\nCounterexample:\n\n\nTransaction trace:\nC.constructor()\nC.abiEncodeStringLiteral(sig) -- counterexample incomplete; parameter name used instead of value +// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/crypto/crypto_functions_same_array.sol b/test/libsolidity/smtCheckerTests/crypto/crypto_functions_same_array.sol new file mode 100644 index 000000000000..b0e3b9565aab --- /dev/null +++ b/test/libsolidity/smtCheckerTests/crypto/crypto_functions_same_array.sol @@ -0,0 +1,23 @@ +contract C { + function c1() public pure { + bytes32 k1 = keccak256(abi.encode([1])); + bytes32 k2 = keccak256(abi.encode([1])); + assert(k1 == k2); + } + + function c2() public pure { + bytes32 s1 = sha256(abi.encode([1,2])); + bytes32 s2 = sha256(abi.encode([1,2])); + assert(s1 == s2); + } + + function c3() public pure { + bytes32 r1 = ripemd160(abi.encode([1,2,3])); + bytes32 r2 = ripemd160(abi.encode([1,2,3])); + assert(r1 == r2); + } +} +// ==== +// SMTEngine: chc +// ---- +// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/crypto/crypto_functions_same_string_literal.sol b/test/libsolidity/smtCheckerTests/crypto/crypto_functions_same_string_literal.sol new file mode 100644 index 000000000000..9e5123ab5bd5 --- /dev/null +++ b/test/libsolidity/smtCheckerTests/crypto/crypto_functions_same_string_literal.sol @@ -0,0 +1,23 @@ +contract C { + function c1() public pure { + bytes32 k1 = keccak256("1"); + bytes32 k2 = keccak256("1"); + assert(k1 == k2); + } + + function c2() public pure { + bytes32 s1 = sha256("10"); + bytes32 s2 = sha256("10"); + assert(s1 == s2); + } + + function c3() public pure { + bytes32 r1 = ripemd160("100"); + bytes32 r2 = ripemd160("100"); + assert(r1 == r2); + } +} +// ==== +// SMTEngine: chc +// ---- +// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/external_calls/call_mutex_unsafe.sol b/test/libsolidity/smtCheckerTests/external_calls/call_mutex_unsafe.sol index e8c17d3eb05f..d2fefcd5f743 100644 --- a/test/libsolidity/smtCheckerTests/external_calls/call_mutex_unsafe.sol +++ b/test/libsolidity/smtCheckerTests/external_calls/call_mutex_unsafe.sol @@ -21,7 +21,7 @@ contract C { } // ==== // SMTEngine: all -// SMTIgnoreCex: no +// SMTIgnoreCex: yes // ---- // Warning 9302: (212-228): Return value of low-level calls not used. -// Warning 6328: (232-246): CHC: Assertion violation happens here.\nCounterexample:\nx = 0, lock = false\n_a = 0x0\ny = 1\n\nTransaction trace:\nC.constructor()\nState: x = 0, lock = false\nC.set(1)\nState: x = 1, lock = false\nC.f(0x0)\n _a.call("aaaaa") -- untrusted external call, synthesized as:\n C.set(0) -- reentrant call +// Warning 6328: (232-246): CHC: Assertion violation happens here.\nCounterexample:\nx = 1, lock = false\n_a = 0x0\ny = 0\n\nTransaction trace:\nC.constructor()\nState: x = 0, lock = false\nC.f(0x0)\n _a.call("aaaaa") -- untrusted external call, synthesized as:\n C.set(1) -- reentrant call diff --git a/test/libsolidity/smtCheckerTests/types/array_literal_3.sol b/test/libsolidity/smtCheckerTests/types/array_literal_3.sol index cdaff2bf44a4..b4655f394f83 100644 --- a/test/libsolidity/smtCheckerTests/types/array_literal_3.sol +++ b/test/libsolidity/smtCheckerTests/types/array_literal_3.sol @@ -11,5 +11,5 @@ contract C // SMTEngine: all // SMTIgnoreCex: no // ---- -// Warning 6328: (168-188): CHC: Assertion violation happens here. +// Warning 6328: (168-188): CHC: Assertion violation happens here.\nCounterexample:\n\na = [1, 2, 3]\nb = [1, 2, 4]\n\nTransaction trace:\nC.constructor()\nC.f() // Info 1391: CHC: 8 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. From 9599d85eb042318fbd8d31565f5e5be7b09fc9fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Mon, 12 Feb 2024 13:24:01 +0100 Subject: [PATCH 0195/1022] Optimizer docs: Style corrections - Add missing backticks. - Use consistent style for step naming (capitalized, without spaces, without backticks). - Correct minor text errors like missing plurals. --- docs/internals/optimizer.rst | 183 ++++++++++++++++++----------------- 1 file changed, 92 insertions(+), 91 deletions(-) diff --git a/docs/internals/optimizer.rst b/docs/internals/optimizer.rst index c1b959a8ab4d..604560554ad5 100644 --- a/docs/internals/optimizer.rst +++ b/docs/internals/optimizer.rst @@ -295,11 +295,11 @@ backtracking. All components of the Yul-based optimizer module are explained below. The following transformation steps are the main components: -- SSA Transform -- Common Subexpression Eliminator -- Expression Simplifier -- Unused Assign Eliminator -- Full Inliner +- SSATransform +- CommonSubexpressionEliminator +- ExpressionSimplifier +- UnusedAssignEliminator +- FullInliner .. _optimizer-steps: @@ -313,7 +313,7 @@ on the individual steps and their sequence below. Abbreviation Full name ============ =============================== ``f`` :ref:`block-flattener` -``l`` :ref:`circular-reference-pruner` +``l`` :ref:`circular-references-pruner` ``c`` :ref:`common-subexpression-eliminator` ``C`` :ref:`conditional-simplifier` ``U`` :ref:`conditional-unsimplifier` @@ -336,8 +336,8 @@ Abbreviation Full name ``L`` :ref:`load-resolver` ``M`` :ref:`loop-invariant-code-motion` ``m`` :ref:`rematerialiser` -``V`` :ref:`SSA-reverser` -``a`` :ref:`SSA-transform` +``V`` :ref:`ssa-reverser` +``a`` :ref:`ssa-transform` ``t`` :ref:`structural-simplifier` ``r`` :ref:`unused-assign-eliminator` ``p`` :ref:`unused-function-parameter-pruner` @@ -416,7 +416,7 @@ and functions can be optimized in isolation without having to traverse the AST c FunctionGrouper ^^^^^^^^^^^^^^^ -The function grouper has to be applied after the disambiguator and the function hoister. +The function grouper has to be applied after the Disambiguator and the FunctionHoister. Its effect is that all topmost elements that are not function definitions are moved into a single block which is the first statement of the root block. @@ -429,14 +429,14 @@ After this step, a program has the following normal form: Where ``I`` is a (potentially empty) block that does not contain any function definitions (not even recursively) and ``F`` is a list of function definitions such that no function contains a function definition. -The benefit of this stage is that we always know where the list of function begins. +The benefit of this stage is that we always know where the list of functions begins. .. _for-loop-condition-into-body: ForLoopConditionIntoBody ^^^^^^^^^^^^^^^^^^^^^^^^ -This transformation moves the loop-iteration condition of a for-loop into loop body. +This transformation moves the loop-iteration condition of a ``for`` loop into loop body. We need this transformation because :ref:`expression-splitter` will not apply to iteration condition expressions (the ``C`` in the following example). @@ -455,7 +455,7 @@ is transformed to Body... } -This transformation can also be useful when paired with ``LoopInvariantCodeMotion``, since +This transformation can also be useful when paired with LoopInvariantCodeMotion, since invariants in the loop-invariant conditions can then be taken outside the loop. .. _for-loop-init-rewriter: @@ -463,7 +463,7 @@ invariants in the loop-invariant conditions can then be taken outside the loop. ForLoopInitRewriter ^^^^^^^^^^^^^^^^^^^ -This transformation moves the initialization part of a for-loop to before +This transformation moves the initialization part of a ``for`` loop to before the loop: .. code-block:: text @@ -482,7 +482,7 @@ is transformed to } This eases the rest of the optimization process because we can ignore -the complicated scoping rules of the for loop initialization block. +the complicated scoping rules of the ``for`` loop initialization block. .. _var-decl-initializer: @@ -600,7 +600,7 @@ and it is also easier to perform function call inlining. Furthermore, it is simp to replace individual parts of expressions or re-organize the "expression tree". The drawback is that such code is much harder to read for humans. -.. _SSA-transform: +.. _ssa-transform: SSATransform ^^^^^^^^^^^^ @@ -645,19 +645,19 @@ are not modified) perform the following transforms: Furthermore, always record the current value of ``i`` used for ``a`` and replace each reference to ``a`` by ``a_i``. The current value mapping is cleared for a variable ``a`` at the end of each block -in which it was assigned to and at the end of the for loop init block if it is assigned -inside the for loop body or post block. +in which it was assigned to and at the end of the ``for`` loop init block if it is assigned +inside the ``for`` loop body or post block. If a variable's value is cleared according to the rule above and the variable is declared outside the block, a new SSA variable will be created at the location where control flow joins, this includes the beginning of loop post/body block and the location right after -If/Switch/ForLoop/Block statement. +``if``/``switch``/``for``/block statement. -After this stage, the Unused Assign Eliminator is recommended to remove the unnecessary +After this stage, the UnusedAssignEliminator is recommended to remove the unnecessary intermediate assignments. -This stage provides best results if the Expression Splitter and the Common Subexpression Eliminator +This stage provides best results if the ExpressionSplitter and the CommonSubexpressionEliminator are run right before it, because then it does not generate excessive amounts of variables. -On the other hand, the Common Subexpression Eliminator could be more efficient if run after the +On the other hand, the CommonSubexpressionEliminator could be more efficient if run after the SSA transform. .. _unused-assign-eliminator: @@ -691,7 +691,7 @@ The SSA transform converts this snippet to the following: sstore(a_3, 1) } -The Unused Assign Eliminator removes all the three assignments to ``a``, because +The UnusedAssignEliminator removes all the three assignments to ``a``, because the value of ``a`` is not used and thus turn this snippet into strict SSA form: @@ -716,7 +716,7 @@ mapping from assignment statements to the three states value will be used later by a reference to the variable. When an assignment is visited, it is added to the mapping in the "undecided" state -(see remark about for loops below) and every other assignment to the same variable +(see remark about ``for`` loops below) and every other assignment to the same variable that is still in the "undecided" state is changed to "unused". When a variable is referenced, the state of any assignment to that variable still in the "undecided" state is changed to "used". @@ -731,7 +731,7 @@ Conflicting values are resolved in the following way: - "unused", "used" -> "used" - "undecided", "used" -> "used" -For for-loops, the condition, body and post-part are visited twice, taking +For ``for`` loops, the condition, body and post-part are visited twice, taking the joining control-flow at the condition into account. In other words, we create three control flow paths: Zero runs of the loop, one run and two runs and then combine them at the end. @@ -757,13 +757,13 @@ and thus .. code-block:: none - max(s, f(s), f(f(s))) = max(s, f(s), f(f(s)), f(f(f(s))), ...). + max(s, f(s), f(f(s))) = max(s, f(s), f(f(s)), f(f(f(s))), ...) In summary, running the loop at most twice is enough because there are only three different states. -For switch statements that have a "default"-case, there is no control-flow -part that skips the switch. +For ``switch`` statements that have a default case, there is no control-flow +part that skips the ``switch``. When a variable goes out of scope, all statements still in the "undecided" state are changed to "unused", unless the variable is the return @@ -793,7 +793,7 @@ The following parts make an expression non-movable: DataflowAnalyzer ^^^^^^^^^^^^^^^^ -The Dataflow Analyzer is not an optimizer step itself but is used as a tool +The DataflowAnalyzer is not an optimizer step itself but is used as a tool by other components. While traversing the AST, it tracks the current value of each variable, as long as that value is a movable expression. It records the variables that are part of the expression @@ -804,7 +804,7 @@ of the currently stored expression for ``b``. At control-flow joins, knowledge about variables is cleared if they have or would be assigned in any of the control-flow paths. For instance, upon entering a -for loop, all variables are cleared that will be assigned during the +``for`` loop, all variables are cleared that will be assigned during the body or the post block. Expression-Scale Simplifications @@ -818,7 +818,7 @@ and hopefully simpler expressions. CommonSubexpressionEliminator ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -This step uses the Dataflow Analyzer and replaces subexpressions that +This step uses the DataflowAnalyzer and replaces subexpressions that syntactically match the current value of a variable by a reference to that variable. This is an equivalence transform because such subexpressions have to be movable. @@ -828,24 +828,24 @@ current value if the value is an identifier. The combination of the two rules above allow to compute a local value numbering, which means that if two variables have the same -value, one of them will always be unused. The Unused Pruner or the -Unused Assign Eliminator will then be able to fully eliminate such +value, one of them will always be unused. The UnusedPruner or the +UnusedAssignEliminator will then be able to fully eliminate such variables. -This step is especially efficient if the expression splitter is run +This step is especially efficient if the ExpressionSplitter is run before. If the code is in pseudo-SSA form, the values of variables are available for a longer time and thus we have a higher chance of expressions to be replaceable. -The expression simplifier will be able to perform better replacements -if the common subexpression eliminator was run right before it. +The ExpressionSimplifier will be able to perform better replacements +if the CommonSubexpressionEliminator was run right before it. .. _expression-simplifier: ExpressionSimplifier ^^^^^^^^^^^^^^^^^^^^ -The ExpressionSimplifier uses the Dataflow Analyzer and makes use +The ExpressionSimplifier uses the DataflowAnalyzer and makes use of a list of equivalence transforms on expressions like ``X + 0 -> X`` to simplify the code. @@ -857,7 +857,7 @@ even when the code is in pseudo-SSA form. Some of the patterns like ``X - X -> 0`` can only be applied as long as the expression ``X`` is movable, because otherwise it would remove its potential side-effects. Since variable references are always movable, even if their current -value might not be, the Expression Simplifier is again more powerful +value might not be, the ExpressionSimplifier is again more powerful in split or pseudo-SSA form. .. _literal-rematerialiser: @@ -877,12 +877,12 @@ currently stored in storage resp. memory, if known. Works best if the code is in SSA form. -Prerequisite: Disambiguator, ForLoopInitRewriter. +Prerequisites: Disambiguator, ForLoopInitRewriter. Statement-Scale Simplifications ------------------------------- -.. _circular-reference-pruner: +.. _circular-references-pruner: CircularReferencesPruner ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -895,7 +895,7 @@ neither externally referenced nor referenced from the outermost context. ConditionalSimplifier ^^^^^^^^^^^^^^^^^^^^^ -The Conditional Simplifier inserts assignments to condition variables if the value can be determined +The ConditionalSimplifier inserts assignments to condition variables if the value can be determined from the control-flow. Destroys SSA form. @@ -906,12 +906,12 @@ we cannot assign a specific value. Current features: -- switch cases: insert " := " -- after if statement with terminating control-flow, insert " := 0" +- ``switch`` cases: insert `` := `` +- after ``if`` statement with terminating control-flow, insert `` := 0`` Future features: -- allow replacements by "1" +- 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. @@ -923,7 +923,7 @@ Prerequisite: Disambiguator. ConditionalUnsimplifier ^^^^^^^^^^^^^^^^^^^^^^^ -Reverse of Conditional Simplifier. +Reverse of ConditionalSimplifier. .. _control-flow-simplifier: @@ -932,14 +932,14 @@ ControlFlowSimplifier Simplifies several control-flow structures: -- replace if with empty body with pop(condition) -- remove empty default switch case -- remove empty switch case if no default case exists -- replace switch with no cases with pop(expression) -- turn switch with single case into if -- replace switch with only default case with pop(expression) and body -- replace switch with const expr with matching case body -- replace ``for`` with terminating control flow and without other break/continue by ``if`` +- replace ``if`` with empty body with ``pop(condition)`` +- remove empty default ``switch`` case +- remove empty ``switch`` case if no default case exists +- replace ``switch`` with no cases with ``pop(expression)`` +- turn ``switch`` with single case into ``if`` +- replace ``switch`` with only default case with ``pop(expression)`` and body +- replace ``switch`` with const expr with matching case body +- replace ``for`` with terminating control flow and without other ``break``/``continue`` by ``if`` - remove ``leave`` at the end of a function. None of these operations depend on the data flow. The StructuralSimplifier @@ -949,6 +949,7 @@ The ControlFlowSimplifier does record the presence or absence of ``break`` and ``continue`` statements during its traversal. Prerequisite: Disambiguator, FunctionHoister, ForLoopInitRewriter. + Important: Introduces EVM opcodes and thus can only be used on EVM code for now. .. _dead-code-eliminator: @@ -959,15 +960,16 @@ DeadCodeEliminator This optimization stage removes unreachable code. Unreachable code is any code within a block which is preceded by a -leave, return, invalid, break, continue, selfdestruct, revert or by a call to a user-defined function that recurses infinitely. +``leave``, ``return``, ``invalid``, ``break``, ``continue``, ``selfdestruct``, ``revert`` or by +a call to a user-defined function that recurses infinitely. Function definitions are retained as they might be called by earlier code and thus are considered reachable. -Because variables declared in a for loop's init block have their scope extended to the loop body, +Because variables declared in a ``for`` loop's init block have their scope extended to the loop body, we require ForLoopInitRewriter to run before this step. -Prerequisite: ForLoopInitRewriter, Function Hoister, Function Grouper +Prerequisites: ForLoopInitRewriter, FunctionHoister, FunctionGrouper. .. _equal-store-eliminator: @@ -978,12 +980,12 @@ This steps removes ``mstore(k, v)`` and ``sstore(k, v)`` calls if there was a previous call to ``mstore(k, v)`` / ``sstore(k, v)``, no other store in between and the values of ``k`` and ``v`` did not change. -This simple step is effective if run after the SSA transform and the -Common Subexpression Eliminator, because SSA will make sure that the variables -will not change and the Common Subexpression Eliminator re-uses exactly the same +This simple step is effective if run after the SSATransform and the +CommonSubexpressionEliminator, because SSA will make sure that the variables +will not change and the CommonSubexpressionEliminator re-uses exactly the same variable if the value is known to be the same. -Prerequisites: Disambiguator, ForLoopInitRewriter +Prerequisites: Disambiguator, ForLoopInitRewriter. .. _unused-pruner: @@ -992,8 +994,8 @@ UnusedPruner This step removes the definitions of all functions that are never referenced. -It also removes the declaration of variables that are never referenced. -If the declaration assigns a value that is not movable, the expression is retained, +It also removes declarations of variables that are never referenced. +If a declaration assigns a value that is not movable, the expression is retained, but its value is discarded. All movable expression statements (expressions that are not assigned) are removed. @@ -1006,22 +1008,22 @@ StructuralSimplifier This is a general step that performs various kinds of simplifications on a structural level: -- replace if statement with empty body by ``pop(condition)`` -- replace if statement with true condition by its body -- remove if statement with false condition -- turn switch with single case into if -- replace switch with only default case by ``pop(expression)`` and body -- replace switch with literal expression by matching case body -- replace for loop with false condition by its initialization part +- replace ``if`` statement with empty body by ``pop(condition)`` +- replace ``if`` statement with true condition by its body +- remove ``if`` statement with false condition +- turn ``switch`` with single case into ``if`` +- replace ``switch`` with only default case by ``pop(expression)`` and body +- replace ``switch`` with literal expression by matching case body +- replace ``for`` loop with false condition by its initialization part -This component uses the Dataflow Analyzer. +This component uses the DataflowAnalyzer. .. _block-flattener: BlockFlattener ^^^^^^^^^^^^^^ -This stage eliminates nested blocks by inserting the statement in the +This stage eliminates nested blocks by inserting the statements in the inner block at the appropriate place in the outer block. It depends on the FunctionGrouper and does not flatten the outermost block to keep the form produced by the FunctionGrouper. @@ -1062,10 +1064,9 @@ This optimization moves movable SSA variable declarations outside the loop. Only statements at the top level in a loop's body or post block are considered, i.e variable declarations inside conditional branches will not be moved out of the loop. -Requirements: +ExpressionSplitter and SSATransform should be run upfront to obtain better results. -- The Disambiguator, ForLoopInitRewriter and FunctionHoister must be run upfront. -- Expression splitter and SSA transform should be run upfront to obtain better result. +Prerequisites: Disambiguator, ForLoopInitRewriter, FunctionHoister. Function-Level Optimizations @@ -1092,7 +1093,7 @@ function ``f_1`` that takes only one argument, i.e., Other optimization steps will be able to make more simplifications to the function. The optimization step is mainly useful for functions that would not be inlined. -Prerequisites: Disambiguator, FunctionHoister +Prerequisites: Disambiguator, FunctionHoister. LiteralRematerialiser is recommended as a prerequisite, even though it's not required for correctness. @@ -1122,7 +1123,7 @@ The step LiteralRematerialiser is not required for correctness. It helps deal wi ``function f(x) -> y { revert(y, y} }`` where the literal ``y`` will be replaced by its value ``0``, allowing us to rewrite the function. -.. index:: ! unused store eliminator +.. index:: ! UnusedStoreEliminator .. _unused-store-eliminator: UnusedStoreEliminator @@ -1149,7 +1150,7 @@ For example, the following code sstore(c, 3) } -will be transformed into the code below after the Unused Store Eliminator step is run +will be transformed into the code below after the UnusedStoreEliminator step is run .. code-block:: yul @@ -1159,7 +1160,7 @@ will be transformed into the code below after the Unused Store Eliminator step i sstore(c, 3) } -For memory store operations, things are generally simpler, at least in the outermost yul block as all such +For memory store operations, things are generally simpler, at least in the outermost Yul block as all such statements will be removed if they are never read from in any code path. At function analysis level, however, the approach is similar to ``sstore``, as we do not know whether the memory location will be read once we leave the function's scope, so the statement will be removed only if all code paths lead to a memory overwrite. @@ -1177,8 +1178,8 @@ If two functions are syntactically equivalent, while allowing variable renaming but not any re-ordering, then any reference to one of the functions is replaced by the other. -The actual removal of the function is performed by the Unused Pruner. +The actual removal of the function is performed by the UnusedPruner. Function Inlining ----------------- @@ -1199,7 +1200,7 @@ Furthermore, for all parameters, all of the following need to be true: - The argument is movable. - The parameter is either referenced less than twice in the function body, or the argument is rather cheap - ("cost" of at most 1, like a constant up to 0xff). + ("cost" of at most 1, like a constant up to ``0xff``). Example: The function to be inlined has the form of ``function f(...) -> r { r := E }`` where ``E`` is an expression that does not reference ``r`` and all arguments in the function call are movable expressions. @@ -1255,7 +1256,7 @@ variables as much as possible. ExpressionJoiner ^^^^^^^^^^^^^^^^ -This is the opposite operation of the expression splitter. It turns a sequence of +This is the opposite operation of the ExpressionSplitter. It turns a sequence of variable declarations that have exactly one reference into a complex expression. This stage fully preserves the order of function calls and opcode executions. It does not make use of any information concerning the commutativity of the opcodes; @@ -1275,21 +1276,21 @@ Because of that, the snippet ``let x := add(0, 2) let y := mul(x, 3)`` is transformed to ``let y := mul(add(0, 2), 3)``, even though the ``add`` opcode would be executed after the evaluation of the literal ``3``. -.. _SSA-reverser: +.. _ssa-reverser: SSAReverser ^^^^^^^^^^^ -This is a tiny step that helps in reversing the effects of the SSA transform -if it is combined with the Common Subexpression Eliminator and the -Unused Pruner. +This is a tiny step that helps in reversing the effects of the SSATransform +if it is combined with the CommonSubexpressionEliminator and the +UnusedPruner. The SSA form we generate is detrimental to code generation because it produces many local variables. It would be better to just re-use existing variables with assignments instead of fresh variable declarations. -The SSA transform rewrites +The SSATransform rewrites .. code-block:: yul @@ -1307,7 +1308,7 @@ to a := a_2 The problem is that instead of ``a``, the variable ``a_1`` is used -whenever ``a`` was referenced. The SSA transform changes statements +whenever ``a`` was referenced. The SSATransform changes statements of this form by just swapping out the declaration and the assignment. The above snippet is turned into @@ -1320,10 +1321,10 @@ snippet is turned into let a_2 := a This is a very simple equivalence transform, but when we now run the -Common Subexpression Eliminator, it will replace all occurrences of ``a_1`` -by ``a`` (until ``a`` is re-assigned). The Unused Pruner will then +CommonSubexpressionEliminator, it will replace all occurrences of ``a_1`` +by ``a`` (until ``a`` is re-assigned). The UnusedPruner will then eliminate the variable ``a_1`` altogether and thus fully reverse the -SSA transform. +SSATransform. .. _stack-compressor: @@ -1354,9 +1355,9 @@ is comparatively cheap to evaluate. Furthermore, it is only semantically equival the value of the expression did not change between the point of assignment and the point of use. The main benefit of this stage is that it can save stack slots if it leads to a variable being eliminated completely (see below), but it can also -save a DUP opcode on the EVM if the expression is very cheap. +save a ``DUP`` opcode on the EVM if the expression is very cheap. -The Rematerialiser uses the Dataflow Analyzer to track the current values of variables, +The Rematerialiser uses the DataflowAnalyzer to track the current values of variables, which are always movable. If the value is very cheap or the variable was explicitly requested to be eliminated, the variable reference is replaced by its current value. From e6f48c2d5f8da82e595b691747d2f97a6822acaf Mon Sep 17 00:00:00 2001 From: Nikola Matic Date: Thu, 9 May 2024 20:46:38 +0200 Subject: [PATCH 0196/1022] Fix python version for Windows builds --- .circleci/config.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 34e2e339333d..38bcaea7b311 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1728,8 +1728,8 @@ jobs: - run: git config --global core.autocrlf false - checkout - run: - name: Force install python3.12.2 - command: choco install python3 --pre --force --version=3.12.2 + name: Force install python3.12 + command: choco install python312 --pre --force - run: name: Create a symlink for python3 command: ln -s /c/ProgramData/chocolatey/bin/python3.12 /c/ProgramData/chocolatey/bin/python3 From e446713b917d50ea37dc05a280d7c582402d2d3c Mon Sep 17 00:00:00 2001 From: Nikola Matic Date: Thu, 9 May 2024 20:18:03 +0200 Subject: [PATCH 0197/1022] Fix archlinux build by disabling test --- test/yulPhaser/AlgorithmRunner.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/test/yulPhaser/AlgorithmRunner.cpp b/test/yulPhaser/AlgorithmRunner.cpp index 56868f1ce76e..f89a0d70f57e 100644 --- a/test/yulPhaser/AlgorithmRunner.cpp +++ b/test/yulPhaser/AlgorithmRunner.cpp @@ -434,6 +434,10 @@ BOOST_FIXTURE_TEST_CASE(run_should_overwrite_existing_file_if_autosave_file_spec BOOST_TEST(readLinesFromFile(m_autosavePath) != originalContent); } +// Disabled due to a fairly obscure bug in GCC 13+ +// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109561 +// The issue is on line 444, and more specifically the Options struct std::optional +/* BOOST_FIXTURE_TEST_CASE(run_should_not_save_population_to_file_if_autosave_file_not_specified, AlgorithmRunnerAutosaveFixture) { m_options.maxRounds = 5; @@ -445,6 +449,7 @@ BOOST_FIXTURE_TEST_CASE(run_should_not_save_population_to_file_if_autosave_file_ BOOST_TEST(!fs::exists(m_autosavePath)); } +*/ BOOST_FIXTURE_TEST_CASE(run_should_randomise_duplicate_chromosomes_if_requested, AlgorithmRunnerFixture) { From c9e2c20932f5635faf5e7715b8a6999f2a8895dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Wed, 14 Feb 2024 19:02:36 +0100 Subject: [PATCH 0198/1022] Fix a bug preventing repeated parts of optimizer sequence from ever stopping after the first cycle --- Changelog.md | 1 + libyul/optimiser/Suite.cpp | 4 +- test/cmdlineTests/optimizer_user_yul/output | 13 ++++++- .../copying/array_elements_to_mapping.sol | 2 +- .../array/copying/array_to_mapping.sol | 2 +- .../copying/calldata_array_to_mapping.sol | 2 +- ...d_array_of_structs_calldata_to_storage.sol | 6 +-- ...ted_array_of_structs_memory_to_storage.sol | 6 +-- ...d_array_of_structs_calldata_to_storage.sol | 6 +-- ...ted_array_of_structs_memory_to_storage.sol | 6 +-- .../copying/storage_memory_packed_dyn.sol | 2 +- .../externalContracts/deposit_contract.sol | 12 +++--- .../semanticTests/externalContracts/snark.sol | 4 +- .../functionCall/gas_and_value_basic.sol | 4 +- .../gas_and_value_brace_syntax.sol | 4 +- .../libraries/internal_types_in_library.sol | 2 +- .../copy_substructures_from_mapping.sol | 2 +- .../structs/copy_substructures_to_mapping.sol | 6 +-- .../semanticTests/structs/copy_to_mapping.sol | 8 ++-- .../mapping/copy_from_mapping_to_mapping.sol | 2 +- .../userDefinedValueType/calldata.sol | 4 +- .../skip_dynamic_types_for_structs.sol | 2 +- .../unusedFunctionParameterPruner_loop.yul | 38 ++++++++++++++++--- 23 files changed, 89 insertions(+), 49 deletions(-) diff --git a/Changelog.md b/Changelog.md index b924b1ccde30..f34f803e68be 100644 --- a/Changelog.md +++ b/Changelog.md @@ -9,6 +9,7 @@ Compiler Features: Bugfixes: * Commandline Interface: Fix ICE when the optimizer is disabled and an empty/blank string is used for ``--yul-optimizations`` sequence. + * Optimizer: Fix optimizer executing each repeating part of the step sequence at least twice, even if the code size already became stable after the first iteration. * SMTChecker: Fix false positive when comparing hashes of same array or string literals. * SMTChecker: Fix internal error on mapping access caused by too strong requirements on sort compatibility of the index and mapping domain. * SMTChecker: Fix internal error when using an empty tuple in a conditional operator. diff --git a/libyul/optimiser/Suite.cpp b/libyul/optimiser/Suite.cpp index d35cdc256c30..83bc0370092b 100644 --- a/libyul/optimiser/Suite.cpp +++ b/libyul/optimiser/Suite.cpp @@ -462,7 +462,9 @@ void OptimiserSuite::runSequence(std::string_view _stepAbbreviations, Block& _as subsequences.push_back({subsequence, true}); } - size_t codeSize = 0; + // NOTE: If _repeatUntilStable is false, the value will not be used so do not calculate it. + size_t codeSize = (_repeatUntilStable ? CodeSize::codeSizeIncludingFunctions(_ast) : 0); + for (size_t round = 0; round < MaxRounds; ++round) { for (auto const& [subsequence, repeat]: subsequences) diff --git a/test/cmdlineTests/optimizer_user_yul/output b/test/cmdlineTests/optimizer_user_yul/output index 689e82ddb4e4..602a7de95b96 100644 --- a/test/cmdlineTests/optimizer_user_yul/output +++ b/test/cmdlineTests/optimizer_user_yul/output @@ -42,6 +42,7 @@ tag_5: /* "optimizer_user_yul/input.sol":263:269 a := 2 */ swap1 pop + 0x00 /* "optimizer_user_yul/input.sol":369:370 3 */ 0x03 /* "optimizer_user_yul/input.sol":366:367 2 */ @@ -58,10 +59,18 @@ tag_6: /* "optimizer_user_yul/input.sol":384:392 sload(5) */ dup1 /* "optimizer_user_yul/input.sol":376:509 for { } sload(5) { } {... */ - iszero - tag_6 + tag_8 jumpi + /* "optimizer_user_yul/input.sol":495:504 exp(x, y) */ + 0x01 + /* "optimizer_user_yul/input.sol":490:504 z := exp(x, y) */ + swap2 + pop + /* "optimizer_user_yul/input.sol":376:509 for { } sload(5) { } {... */ + jump(tag_6) +tag_8: /* "optimizer_user_yul/input.sol":380:383 { } */ + pop pop /* "optimizer_user_yul/input.sol":340:513 {... */ pop diff --git a/test/libsolidity/semanticTests/array/copying/array_elements_to_mapping.sol b/test/libsolidity/semanticTests/array/copying/array_elements_to_mapping.sol index b1e8659be8df..b138e7265f90 100644 --- a/test/libsolidity/semanticTests/array/copying/array_elements_to_mapping.sol +++ b/test/libsolidity/semanticTests/array/copying/array_elements_to_mapping.sol @@ -52,7 +52,7 @@ contract C { } // ---- // from_storage() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 -// gas irOptimized: 150004 +// gas irOptimized: 150022 // gas legacy: 150745 // gas legacyOptimized: 148678 // from_storage_ptr() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 diff --git a/test/libsolidity/semanticTests/array/copying/array_to_mapping.sol b/test/libsolidity/semanticTests/array/copying/array_to_mapping.sol index 50ea19a1eab4..893610eb1377 100644 --- a/test/libsolidity/semanticTests/array/copying/array_to_mapping.sol +++ b/test/libsolidity/semanticTests/array/copying/array_to_mapping.sol @@ -37,7 +37,7 @@ contract C { } // ---- // from_storage() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 -// gas irOptimized: 147871 +// gas irOptimized: 147889 // gas legacy: 148896 // gas legacyOptimized: 146901 // from_storage_ptr() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 diff --git a/test/libsolidity/semanticTests/array/copying/calldata_array_to_mapping.sol b/test/libsolidity/semanticTests/array/copying/calldata_array_to_mapping.sol index e6bf7671a1b0..b8bd588d5672 100644 --- a/test/libsolidity/semanticTests/array/copying/calldata_array_to_mapping.sol +++ b/test/libsolidity/semanticTests/array/copying/calldata_array_to_mapping.sol @@ -14,4 +14,4 @@ contract C { // compileViaYul: true // ---- // from_calldata(uint8[][]): 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 -// gas irOptimized: 139683 +// gas irOptimized: 139637 diff --git a/test/libsolidity/semanticTests/array/copying/elements_of_nested_array_of_structs_calldata_to_storage.sol b/test/libsolidity/semanticTests/array/copying/elements_of_nested_array_of_structs_calldata_to_storage.sol index ea5625f21d39..6c5c0e8faa6f 100644 --- a/test/libsolidity/semanticTests/array/copying/elements_of_nested_array_of_structs_calldata_to_storage.sol +++ b/test/libsolidity/semanticTests/array/copying/elements_of_nested_array_of_structs_calldata_to_storage.sol @@ -31,8 +31,8 @@ contract C { // compileViaYul: true // ---- // test1((uint8[],uint8[2])[][][]): 0x20, 1, 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -// gas irOptimized: 327874 +// gas irOptimized: 327883 // test2((uint8[],uint8[2])[][1][]): 0x20, 2, 0x40, 0x0160, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13, 0x20, 1, 0x20, 0x60, 31, 37, 2, 23, 29 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13 -// gas irOptimized: 140879 +// gas irOptimized: 140882 // test3((uint8[],uint8[2])[1][][2]): 0x20, 0x40, 0x60, 0, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -// gas irOptimized: 188535 +// gas irOptimized: 188541 diff --git a/test/libsolidity/semanticTests/array/copying/elements_of_nested_array_of_structs_memory_to_storage.sol b/test/libsolidity/semanticTests/array/copying/elements_of_nested_array_of_structs_memory_to_storage.sol index 96f24f77da19..a593b1d1dd0b 100644 --- a/test/libsolidity/semanticTests/array/copying/elements_of_nested_array_of_structs_memory_to_storage.sol +++ b/test/libsolidity/semanticTests/array/copying/elements_of_nested_array_of_structs_memory_to_storage.sol @@ -31,8 +31,8 @@ contract C { // compileViaYul: true // ---- // test1((uint8[],uint8[2])[][][]): 0x20, 1, 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -// gas irOptimized: 332660 +// gas irOptimized: 332687 // test2((uint8[],uint8[2])[][1][]): 0x20, 2, 0x40, 0x0160, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13, 0x20, 1, 0x20, 0x60, 31, 37, 2, 23, 29 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13 -// gas irOptimized: 145150 +// gas irOptimized: 145159 // test3((uint8[],uint8[2])[1][][2]): 0x20, 0x40, 0x60, 0, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -// gas irOptimized: 192598 +// gas irOptimized: 192616 diff --git a/test/libsolidity/semanticTests/array/copying/nested_array_of_structs_calldata_to_storage.sol b/test/libsolidity/semanticTests/array/copying/nested_array_of_structs_calldata_to_storage.sol index 844a86304ee7..3666443bbc18 100644 --- a/test/libsolidity/semanticTests/array/copying/nested_array_of_structs_calldata_to_storage.sol +++ b/test/libsolidity/semanticTests/array/copying/nested_array_of_structs_calldata_to_storage.sol @@ -29,8 +29,8 @@ contract C { // compileViaYul: true // ---- // test1((uint8[],uint8[2])[][]): 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -// gas irOptimized: 304747 +// gas irOptimized: 304756 // test2((uint8[],uint8[2])[][1]): 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13 -// gas irOptimized: 116464 +// gas irOptimized: 116467 // test3((uint8[],uint8[2])[1][]): 0x20, 2, 0x40, 0x0120, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 0x0120, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -// gas irOptimized: 188024 +// gas irOptimized: 188030 diff --git a/test/libsolidity/semanticTests/array/copying/nested_array_of_structs_memory_to_storage.sol b/test/libsolidity/semanticTests/array/copying/nested_array_of_structs_memory_to_storage.sol index 209a6ee696e9..821d33d4dd04 100644 --- a/test/libsolidity/semanticTests/array/copying/nested_array_of_structs_memory_to_storage.sol +++ b/test/libsolidity/semanticTests/array/copying/nested_array_of_structs_memory_to_storage.sol @@ -29,8 +29,8 @@ contract C { // compileViaYul: true // ---- // test1((uint8[],uint8[2])[][]): 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -// gas irOptimized: 309074 +// gas irOptimized: 309101 // test2((uint8[],uint8[2])[][1]): 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13 -// gas irOptimized: 118256 +// gas irOptimized: 118265 // test3((uint8[],uint8[2])[1][]): 0x20, 2, 0x40, 0x0120, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 0x0120, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -// gas irOptimized: 190993 +// gas irOptimized: 191011 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 3ba5604a79f5..48d06ab4ea37 100644 --- a/test/libsolidity/semanticTests/array/copying/storage_memory_packed_dyn.sol +++ b/test/libsolidity/semanticTests/array/copying/storage_memory_packed_dyn.sol @@ -13,6 +13,6 @@ contract C { } // ---- // f() -> 2, 3, 4 -// gas irOptimized: 109108 +// gas irOptimized: 109104 // gas legacy: 122235 // gas legacyOptimized: 118411 diff --git a/test/libsolidity/semanticTests/externalContracts/deposit_contract.sol b/test/libsolidity/semanticTests/externalContracts/deposit_contract.sol index ce77683aab73..5288d859b76f 100644 --- a/test/libsolidity/semanticTests/externalContracts/deposit_contract.sol +++ b/test/libsolidity/semanticTests/externalContracts/deposit_contract.sol @@ -176,8 +176,8 @@ contract DepositContract is IDepositContract, ERC165 { } // ---- // constructor() -// gas irOptimized: 809248 -// gas irOptimized code: 558000 +// gas irOptimized: 809628 +// gas irOptimized code: 563200 // gas legacy: 919945 // gas legacy code: 1437600 // gas legacyOptimized: 848464 @@ -187,27 +187,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: 109009 +// gas irOptimized: 108921 // gas legacy: 142735 // gas legacyOptimized: 117558 // 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: 109009 +// gas irOptimized: 108921 // gas legacy: 142735 // gas legacyOptimized: 117558 // 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: 108994 +// gas irOptimized: 108914 // gas legacy: 142744 // gas legacyOptimized: 117570 // 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: 108994 +// gas irOptimized: 108914 // gas legacy: 142744 // gas legacyOptimized: 117570 // get_deposit_count() -> 0x20, 8, 0x0200000000000000000000000000000000000000000000000000000000000000 diff --git a/test/libsolidity/semanticTests/externalContracts/snark.sol b/test/libsolidity/semanticTests/externalContracts/snark.sol index d3492a5c6b06..58f5e58048c9 100644 --- a/test/libsolidity/semanticTests/externalContracts/snark.sol +++ b/test/libsolidity/semanticTests/externalContracts/snark.sol @@ -294,11 +294,11 @@ contract Test { // f() -> true // g() -> true // pair() -> true -// gas irOptimized: 269697 +// gas irOptimized: 269701 // gas legacy: 275206 // gas legacyOptimized: 266925 // verifyTx() -> true // ~ emit Verified(string): 0x20, 0x16, "Successfully verified." -// gas irOptimized: 782210 +// gas irOptimized: 782238 // gas legacy: 801868 // gas legacyOptimized: 770942 diff --git a/test/libsolidity/semanticTests/functionCall/gas_and_value_basic.sol b/test/libsolidity/semanticTests/functionCall/gas_and_value_basic.sol index 806c8eb41b9d..2f8f62586bd5 100644 --- a/test/libsolidity/semanticTests/functionCall/gas_and_value_basic.sol +++ b/test/libsolidity/semanticTests/functionCall/gas_and_value_basic.sol @@ -38,8 +38,8 @@ contract test { } // ---- // constructor(), 20 wei -> -// gas irOptimized: 120226 -// gas irOptimized code: 132400 +// gas irOptimized: 120912 +// gas irOptimized code: 140000 // gas legacy: 130568 // gas legacy code: 261000 // gas legacyOptimized: 121069 diff --git a/test/libsolidity/semanticTests/functionCall/gas_and_value_brace_syntax.sol b/test/libsolidity/semanticTests/functionCall/gas_and_value_brace_syntax.sol index c186fc40b22c..4821146e7eca 100644 --- a/test/libsolidity/semanticTests/functionCall/gas_and_value_brace_syntax.sol +++ b/test/libsolidity/semanticTests/functionCall/gas_and_value_brace_syntax.sol @@ -37,8 +37,8 @@ contract test { } // ---- // constructor(), 20 wei -> -// gas irOptimized: 120226 -// gas irOptimized code: 132400 +// gas irOptimized: 120912 +// gas irOptimized code: 140000 // gas legacy: 130568 // gas legacy code: 261000 // gas legacyOptimized: 121069 diff --git a/test/libsolidity/semanticTests/libraries/internal_types_in_library.sol b/test/libsolidity/semanticTests/libraries/internal_types_in_library.sol index 79d53273ba7e..bdf4e4c30a6a 100644 --- a/test/libsolidity/semanticTests/libraries/internal_types_in_library.sol +++ b/test/libsolidity/semanticTests/libraries/internal_types_in_library.sol @@ -22,6 +22,6 @@ contract Test { // ---- // library: Lib // f() -> 4, 0x11 -// gas irOptimized: 111560 +// gas irOptimized: 111629 // gas legacy: 132935 // gas legacyOptimized: 118023 diff --git a/test/libsolidity/semanticTests/structs/copy_substructures_from_mapping.sol b/test/libsolidity/semanticTests/structs/copy_substructures_from_mapping.sol index 9b0fa9207a8c..8091f5a241c0 100644 --- a/test/libsolidity/semanticTests/structs/copy_substructures_from_mapping.sol +++ b/test/libsolidity/semanticTests/structs/copy_substructures_from_mapping.sol @@ -44,7 +44,7 @@ contract C { } // ---- // to_state() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 -// gas irOptimized: 121511 +// gas irOptimized: 121499 // gas legacy: 123117 // gas legacyOptimized: 121655 // to_storage() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 diff --git a/test/libsolidity/semanticTests/structs/copy_substructures_to_mapping.sol b/test/libsolidity/semanticTests/structs/copy_substructures_to_mapping.sol index a0834ca5bf5b..2083032ff356 100644 --- a/test/libsolidity/semanticTests/structs/copy_substructures_to_mapping.sol +++ b/test/libsolidity/semanticTests/structs/copy_substructures_to_mapping.sol @@ -52,14 +52,14 @@ contract C { } // ---- // from_memory() -> 0x20, 0x60, 0xa0, 0x15, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 -// gas irOptimized: 122952 +// gas irOptimized: 122923 // gas legacy: 130136 // gas legacyOptimized: 128650 // from_state() -> 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 -// gas irOptimized: 121622 +// gas irOptimized: 121616 // gas legacy: 123191 // gas legacyOptimized: 121760 // from_calldata((bytes,uint16[],uint16)): 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 -> 0x20, 0x60, 0xa0, 0x15, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 -// gas irOptimized: 115043 +// gas irOptimized: 115037 // gas legacy: 122425 // gas legacyOptimized: 120696 diff --git a/test/libsolidity/semanticTests/structs/copy_to_mapping.sol b/test/libsolidity/semanticTests/structs/copy_to_mapping.sol index 033f0f518c12..c44277e4f198 100644 --- a/test/libsolidity/semanticTests/structs/copy_to_mapping.sol +++ b/test/libsolidity/semanticTests/structs/copy_to_mapping.sol @@ -45,18 +45,18 @@ contract C { } // ---- // from_state() -> 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 -// gas irOptimized: 121599 +// gas irOptimized: 121593 // gas legacy: 123053 // gas legacyOptimized: 121700 // from_storage() -> 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 -// gas irOptimized: 121644 +// gas irOptimized: 121638 // gas legacy: 123102 // gas legacyOptimized: 121752 // from_memory() -> 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 -// gas irOptimized: 122860 +// gas irOptimized: 122831 // gas legacy: 129997 // gas legacyOptimized: 128646 // from_calldata((bytes,uint16[],uint16)): 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 -> 0x20, 0x60, 0xa0, 21, 3, 0x666f6f0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 -// gas irOptimized: 114958 +// gas irOptimized: 114952 // gas legacy: 118210 // gas legacyOptimized: 115324 diff --git a/test/libsolidity/semanticTests/types/mapping/copy_from_mapping_to_mapping.sol b/test/libsolidity/semanticTests/types/mapping/copy_from_mapping_to_mapping.sol index b17ba6d9160b..e1e1e3b2654d 100644 --- a/test/libsolidity/semanticTests/types/mapping/copy_from_mapping_to_mapping.sol +++ b/test/libsolidity/semanticTests/types/mapping/copy_from_mapping_to_mapping.sol @@ -29,6 +29,6 @@ contract C { } // ---- // f() -> 0x20, 7, 8, 9, 0xa0, 13, 2, 0x40, 0xa0, 2, 3, 4, 2, 3, 4 -// gas irOptimized: 197082 +// gas irOptimized: 197116 // gas legacy: 199891 // gas legacyOptimized: 196817 diff --git a/test/libsolidity/semanticTests/userDefinedValueType/calldata.sol b/test/libsolidity/semanticTests/userDefinedValueType/calldata.sol index 9ed64be08bcf..ea1fc99b4207 100644 --- a/test/libsolidity/semanticTests/userDefinedValueType/calldata.sol +++ b/test/libsolidity/semanticTests/userDefinedValueType/calldata.sol @@ -49,11 +49,11 @@ contract C { } // ---- // test_f() -> true -// gas irOptimized: 122078 +// gas irOptimized: 122094 // gas legacy: 125322 // gas legacyOptimized: 122709 // test_g() -> true -// gas irOptimized: 106215 +// gas irOptimized: 106271 // gas legacy: 111120 // gas legacyOptimized: 106964 // addresses(uint256): 0 -> 0x18 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 ef53a4e47848..52287a8f322e 100644 --- a/test/libsolidity/semanticTests/various/skip_dynamic_types_for_structs.sol +++ b/test/libsolidity/semanticTests/various/skip_dynamic_types_for_structs.sol @@ -19,6 +19,6 @@ contract C { } // ---- // g() -> 2, 6 -// gas irOptimized: 178263 +// gas irOptimized: 178277 // gas legacy: 180657 // gas legacyOptimized: 179156 diff --git a/test/libyul/yulOptimizerTests/fullSuite/unusedFunctionParameterPruner_loop.yul b/test/libyul/yulOptimizerTests/fullSuite/unusedFunctionParameterPruner_loop.yul index f0b7546d0592..148f4a1e7ea0 100644 --- a/test/libyul/yulOptimizerTests/fullSuite/unusedFunctionParameterPruner_loop.yul +++ b/test/libyul/yulOptimizerTests/fullSuite/unusedFunctionParameterPruner_loop.yul @@ -20,18 +20,46 @@ // { // { // f() -// f() -// f() +// f_72() +// f_73() // sstore(0, 1) // } // function f() // { +// let a := 1 +// let b := 10 +// let a_1 := calldataload(0) +// let _1 := iszero(a_1) +// for { } iszero(b) { b := add(b, not(0)) } +// { +// a := a_1 +// mstore(a_1, 0) +// if _1 { leave } +// } +// } +// function f_72() +// { +// let a := 2 +// let b := 10 +// let a_1 := calldataload(0) +// let _1 := iszero(a_1) +// for { } iszero(b) { b := add(b, not(0)) } +// { +// a := a_1 +// mstore(a_1, 0) +// if _1 { leave } +// } +// } +// function f_73() +// { +// let a := 3 // let b := 10 -// let a := calldataload(0) -// let _1 := iszero(a) +// let a_1 := calldataload(0) +// let _1 := iszero(a_1) // for { } iszero(b) { b := add(b, not(0)) } // { -// mstore(a, 0) +// a := a_1 +// mstore(a_1, 0) // if _1 { leave } // } // } From 10afe0dd544836239dcb1e870a4d2628eb9f0d31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Sat, 11 May 2024 19:43:45 +0200 Subject: [PATCH 0199/1022] Make fullSuite medium test case less artificial - The structural simplification here is pretty artificial while the main point of the test is resolution of memory loads. - In exchange add a simpler case covering structural simplification for the whole sequence. --- test/libyul/yulOptimizerTests/fullSuite/medium.yul | 4 +--- .../fullSuite/structural_simplification.yul | 11 +++++++++++ 2 files changed, 12 insertions(+), 3 deletions(-) create mode 100644 test/libyul/yulOptimizerTests/fullSuite/structural_simplification.yul diff --git a/test/libyul/yulOptimizerTests/fullSuite/medium.yul b/test/libyul/yulOptimizerTests/fullSuite/medium.yul index 9a6381d79913..911504071661 100644 --- a/test/libyul/yulOptimizerTests/fullSuite/medium.yul +++ b/test/libyul/yulOptimizerTests/fullSuite/medium.yul @@ -12,9 +12,7 @@ if 0 { mstore(0x40, 0x20) } - if sub(2,1) { - for { switch mul(1,2) case 2 { mstore(0x40, 0x20) } } sub(1,1) {} { mstore(0x80, 0x40) } - } + mstore(0x40, 0x20) sstore(0, array_index_access(x, 3)) sstore(1, mload(0x40)) } diff --git a/test/libyul/yulOptimizerTests/fullSuite/structural_simplification.yul b/test/libyul/yulOptimizerTests/fullSuite/structural_simplification.yul new file mode 100644 index 000000000000..85a975fde188 --- /dev/null +++ b/test/libyul/yulOptimizerTests/fullSuite/structural_simplification.yul @@ -0,0 +1,11 @@ +{ + if sub(2, 1) { + mstore(0x40, 0x20) + for {} sub(1, 1) {} {} + } + sstore(1, mload(0x40)) +} +// ---- +// step: fullSuite +// +// { { sstore(1, 0x20) } } From 54ab398a44143fce6f63502f533c651f4d080bae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Wed, 6 Mar 2024 12:00:27 +0100 Subject: [PATCH 0200/1022] Change the default optimizer sequence to the `the-good-parts-mk3` candidate - `the-good-parts` variant found using seqbench. - Third refinement: - adjusted to improve results for the erc20.sol contract. - adjustments to address regressions visible in test output of the previous version. --- libsolidity/interface/OptimiserSettings.h | 32 ++++++++++++----------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/libsolidity/interface/OptimiserSettings.h b/libsolidity/interface/OptimiserSettings.h index 46683088a042..1ca46ccbc260 100644 --- a/libsolidity/interface/OptimiserSettings.h +++ b/libsolidity/interface/OptimiserSettings.h @@ -43,23 +43,25 @@ struct OptimiserSettings { static char constexpr DefaultYulOptimiserSteps[] = "dhfoDgvulfnTUtnIf" // None of these can make stack problems worse - "[" - "xa[r]EscLM" // Turn into SSA and simplify - "cCTUtTOntnfDIul" // Perform structural simplification - "Lcul" // Simplify again - "Vcul [j]" // Reverse SSA - - // should have good "compilability" property here. - - "Tpeul" // Run functional expression inliner - "xa[rul]" // Prune a bit more in SSA - "xa[r]cL" // Turn into SSA again and simplify - "gvif" // Run full inliner - "CTUca[r]LSsTFOtfDnca[r]Iulc" // SSA plus simplify - "]" + + "xa[r]EscLM" // Turn into SSA and simplify + "Vcul [j]" // Reverse SSA + + // should have good "compilability" property here. + + "Trpeul" // Run functional expression inliner + "xa[r]cL" // Turn into SSA again and simplify + "gvifM" // Run full inliner + "CTUca[r]LSsTFOtfDnca[r]Iulc" // SSA plus simplify + + "scCTUt" + "gvifM" // Run full inliner + "x[scCTUt] TOntnfDIul" // Perform structural simplification + "gvifM" // Run full inliner + "jmul[jul] VcTOcul jmul"; // Make source short and pretty - static char constexpr DefaultYulOptimiserCleanupSteps[] = "fDnTOcmu"; + static char constexpr DefaultYulOptimiserCleanupSteps[] = "fDnTOcmuO"; /// No optimisations at all - not recommended. static OptimiserSettings none() From c12fe8a1d00485f10a0d51d05be3ff209795421d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Fri, 8 Mar 2024 20:27:38 +0100 Subject: [PATCH 0201/1022] Update gas expectations --- test/libsolidity/gasTests/abiv2_optimised.sol | 6 +++--- .../abiEncoderV1/abi_decode_v2_storage.sol | 4 ++-- .../abi_encode_calldata_slice.sol | 8 ++++---- .../struct/struct_storage_ptr.sol | 2 +- .../abi_encode_calldata_slice.sol | 8 ++++---- .../abiEncoderV2/abi_encode_v2.sol | 4 ++-- ...2_in_function_inherited_in_v1_contract.sol | 8 ++++---- .../abiEncoderV2/calldata_array.sol | 2 +- .../calldata_overlapped_dynamic_arrays.sol | 4 ++-- .../abiEncoderV2/storage_array_encoding.sol | 8 ++++---- .../abi_decode_simple_storage.sol | 4 ++-- .../array/array_memory_index_access.sol | 2 +- .../array/array_storage_index_access.sol | 18 ++++++++--------- .../array_storage_index_boundary_test.sol | 4 ++-- .../array/array_storage_index_zeroed_test.sol | 8 ++++---- .../array/array_storage_length_access.sol | 2 +- .../array/array_storage_push_empty.sol | 4 ++-- ...rray_storage_push_empty_length_address.sol | 4 ++-- .../array/array_storage_push_pop.sol | 4 ++-- .../arrays_complex_from_and_to_storage.sol | 4 ++-- .../array/byte_array_transitional_2.sol | 2 +- .../array/bytes_length_member.sol | 2 +- .../array/constant_var_as_array_length.sol | 4 ++-- .../copying/array_copy_calldata_storage.sol | 4 ++-- .../copying/array_copy_cleanup_uint40.sol | 2 +- .../copying/array_copy_clear_storage.sol | 2 +- .../copying/array_copy_different_packing.sol | 2 +- .../copying/array_copy_including_array.sol | 4 ++-- .../array/copying/array_copy_nested_array.sol | 4 ++-- ...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 | 4 ++-- .../copying/array_copy_target_leftover.sol | 4 ++-- .../copying/array_copy_target_simple.sol | 2 +- .../copying/array_copy_target_simple_2.sol | 2 +- .../copying/array_elements_to_mapping.sol | 4 ++-- .../array_nested_calldata_to_storage.sol | 8 ++++---- .../array_nested_memory_to_storage.sol | 4 ++-- ...on_external_storage_to_storage_dynamic.sol | 4 ++-- ...o_storage_dynamic_different_mutability.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 +- .../array/copying/array_to_mapping.sol | 4 ++-- .../copying/arrays_from_and_to_storage.sol | 2 +- .../array/copying/bytes_inside_mappings.sol | 4 ++-- .../copying/bytes_storage_to_storage.sol | 20 +++++++++---------- .../calldata_array_dynamic_to_storage.sol | 4 ++-- .../copying/calldata_array_to_mapping.sol | 2 +- ...nup_during_multi_element_per_slot_copy.sol | 4 ++-- .../copy_byte_array_in_struct_to_storage.sol | 8 ++++---- .../copying/copy_byte_array_to_storage.sol | 4 ++-- .../copy_function_internal_storage_array.sol | 2 +- .../array/copying/copy_removes_bytes_data.sol | 2 +- ...d_array_of_structs_calldata_to_storage.sol | 6 +++--- ...ted_array_of_structs_memory_to_storage.sol | 6 +++--- .../function_type_array_to_storage.sol | 8 ++++---- .../memory_dyn_2d_bytes_to_storage.sol | 4 ++-- ...ested_array_element_storage_to_storage.sol | 6 +++--- ...d_array_of_structs_calldata_to_storage.sol | 6 +++--- ...ted_array_of_structs_memory_to_storage.sol | 6 +++--- ...ed_array_of_structs_storage_to_storage.sol | 4 ++-- ...amic_array_element_calldata_to_storage.sol | 4 ++-- .../array/copying/storage_memory_nested.sol | 2 +- .../copying/storage_memory_nested_bytes.sol | 4 ++-- .../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 | 4 ++-- .../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 | 6 +++--- .../array/fixed_arrays_in_constructors.sol | 2 +- .../array/function_array_cross_calls.sol | 8 ++++---- ...nvalid_encoding_for_storage_byte_array.sol | 4 ++-- .../array/pop/array_pop_array_transition.sol | 2 +- .../array/pop/array_pop_uint16_transition.sol | 2 +- .../array/pop/array_pop_uint24_transition.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 | 4 ++-- .../array/push/array_push_struct.sol | 2 +- .../push/array_push_struct_from_calldata.sol | 4 ++-- .../array/push/byte_array_push_transition.sol | 2 +- .../array/push/nested_bytes_push.sol | 4 ++-- .../array/push/push_no_args_2d.sol | 4 ++-- .../array/push/push_no_args_bytes.sol | 2 +- .../semanticTests/array/reusing_memory.sol | 2 +- .../byte_array_to_storage_cleanup.sol | 8 ++++---- .../copy_from_calldata_removes_bytes_data.sol | 2 +- .../constructor/arrays_in_constructors.sol | 8 ++++---- .../bytes_in_constructors_packer.sol | 8 ++++---- .../bytes_in_constructors_unpacker.sol | 6 +++--- .../constructor_static_array_argument.sol | 4 ++-- .../constructor/no_callvalue_check.sol | 2 +- .../events/event_dynamic_array_storage.sol | 4 ++-- .../events/event_dynamic_array_storage_v2.sol | 4 ++-- .../event_dynamic_nested_array_storage_v2.sol | 4 ++-- .../events/event_indexed_string.sol | 4 ++-- .../externalContracts/FixedFeeRegistrar.sol | 8 ++++---- .../externalContracts/base64.sol | 12 +++++------ .../externalContracts/deposit_contract.sol | 16 +++++++-------- .../externalContracts/prbmath_signed.sol | 4 ++-- .../externalContracts/prbmath_unsigned.sol | 4 ++-- .../externalContracts/ramanujan_pi.sol | 4 ++-- .../semanticTests/externalContracts/snark.sol | 4 ++-- .../externalContracts/strings.sol | 12 +++++------ .../creation_function_call_with_args.sol | 2 +- .../creation_function_call_with_salt.sol | 2 +- .../external_call_to_nonexisting.sol | 8 ++++---- ...ernal_call_to_nonexisting_debugstrings.sol | 8 ++++---- .../functionCall/gas_and_value_basic.sol | 4 ++-- .../gas_and_value_brace_syntax.sol | 4 ++-- .../mapping_array_internal_argument.sol | 2 +- .../immutable/multi_creation.sol | 2 +- .../semanticTests/immutable/use_scratch.sol | 2 +- ...ted_function_calldata_memory_interface.sol | 4 ++-- .../transient_storage_selfdestruct.sol | 4 ++-- .../balance_other_contract.sol | 4 ++-- .../libraries/internal_types_in_library.sol | 2 +- .../using_library_mappings_public.sol | 2 +- .../using_library_mappings_return.sol | 2 +- .../salted_create_with_value.sol | 4 ++-- .../storage/empty_nonempty_empty.sol | 4 ++-- .../storage/packed_storage_structs_bytes.sol | 2 +- ...ta_struct_with_nested_array_to_storage.sol | 4 ++-- .../conversion/recursive_storage_memory.sol | 2 +- .../structs/copy_from_mapping.sol | 4 ++-- .../copy_struct_array_from_storage.sol | 2 +- .../copy_substructures_from_mapping.sol | 4 ++-- .../structs/copy_substructures_to_mapping.sol | 12 +++++------ .../semanticTests/structs/copy_to_mapping.sol | 16 +++++++-------- .../structs/memory_structs_nested_load.sol | 2 +- ...truct_containing_bytes_copy_and_delete.sol | 8 ++++---- .../semanticTests/structs/struct_copy.sol | 4 ++-- .../structs/struct_copy_via_local.sol | 2 +- .../struct_delete_storage_with_array.sol | 4 ++-- .../struct_memory_to_storage_function_ptr.sol | 2 +- .../semanticTests/structs/structs.sol | 2 +- .../mapping/copy_from_mapping_to_mapping.sol | 4 ++-- .../userDefinedValueType/calldata.sol | 8 ++++---- .../userDefinedValueType/erc20.sol | 8 ++++---- .../semanticTests/various/address_code.sol | 6 +++--- .../semanticTests/various/create_calldata.sol | 4 ++-- .../various/destructuring_assignment.sol | 4 ++-- .../semanticTests/various/erc20.sol | 8 ++++---- .../various/many_subassemblies.sol | 2 +- ...uct_post_cancun_multiple_beneficiaries.sol | 6 +++--- .../selfdestruct_post_cancun_redeploy.sol | 6 +++--- ...ruct_pre_cancun_multiple_beneficiaries.sol | 6 +++--- .../selfdestruct_pre_cancun_redeploy.sol | 6 +++--- .../skip_dynamic_types_for_structs.sol | 4 ++-- .../various/staticcall_for_view_and_pure.sol | 2 +- .../semanticTests/various/value_complex.sol | 4 ++-- .../semanticTests/various/value_insane.sol | 4 ++-- .../viaYul/copy_struct_invalid_ir_bug.sol | 2 +- 168 files changed, 358 insertions(+), 358 deletions(-) diff --git a/test/libsolidity/gasTests/abiv2_optimised.sol b/test/libsolidity/gasTests/abiv2_optimised.sol index 8f407e6ede24..2989c1acd8f9 100644 --- a/test/libsolidity/gasTests/abiv2_optimised.sol +++ b/test/libsolidity/gasTests/abiv2_optimised.sol @@ -17,9 +17,9 @@ contract C { // optimize-yul: true // ---- // creation: -// codeDepositCost: 634600 -// executionCost: 668 -// totalCost: 635268 +// codeDepositCost: 618200 +// executionCost: 649 +// totalCost: 618849 // external: // a(): 2283 // b(uint256): 4649 diff --git a/test/libsolidity/semanticTests/abiEncoderV1/abi_decode_v2_storage.sol b/test/libsolidity/semanticTests/abiEncoderV1/abi_decode_v2_storage.sol index b4ef43c44172..8d74a34f48bb 100644 --- a/test/libsolidity/semanticTests/abiEncoderV1/abi_decode_v2_storage.sol +++ b/test/libsolidity/semanticTests/abiEncoderV1/abi_decode_v2_storage.sol @@ -21,6 +21,6 @@ contract C { } // ---- // f() -> 0x20, 0x8, 0x40, 0x3, 0x9, 0xa, 0xb -// gas irOptimized: 203149 +// gas irOptimized: 203173 // gas legacy: 206263 -// gas legacyOptimized: 203156 +// gas legacyOptimized: 203172 diff --git a/test/libsolidity/semanticTests/abiEncoderV1/abi_encode_calldata_slice.sol b/test/libsolidity/semanticTests/abiEncoderV1/abi_encode_calldata_slice.sol index 3dd5dd269340..a518a3750ede 100644 --- a/test/libsolidity/semanticTests/abiEncoderV1/abi_encode_calldata_slice.sol +++ b/test/libsolidity/semanticTests/abiEncoderV1/abi_encode_calldata_slice.sol @@ -59,10 +59,10 @@ contract C { // EVMVersion: >homestead // ---- // test_bytes() -> -// gas irOptimized: 306908 +// gas irOptimized: 314884 // gas legacy: 305827 -// gas legacyOptimized: 255013 +// gas legacyOptimized: 253681 // test_uint256() -> -// gas irOptimized: 435054 +// gas irOptimized: 448346 // gas legacy: 421315 -// gas legacyOptimized: 352838 +// gas legacyOptimized: 351650 diff --git a/test/libsolidity/semanticTests/abiEncoderV1/struct/struct_storage_ptr.sol b/test/libsolidity/semanticTests/abiEncoderV1/struct/struct_storage_ptr.sol index efffab86c1cf..c8eb95418906 100644 --- a/test/libsolidity/semanticTests/abiEncoderV1/struct/struct_storage_ptr.sol +++ b/test/libsolidity/semanticTests/abiEncoderV1/struct/struct_storage_ptr.sol @@ -24,6 +24,6 @@ contract C { // ---- // library: L // f() -> 8, 7, 1, 2, 7, 12 -// gas irOptimized: 166475 +// gas irOptimized: 166759 // gas legacy: 169283 // gas legacyOptimized: 167248 diff --git a/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_calldata_slice.sol b/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_calldata_slice.sol index 5457e7f6743e..b80d14d6b02b 100644 --- a/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_calldata_slice.sol +++ b/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_calldata_slice.sol @@ -60,10 +60,10 @@ contract C { // EVMVersion: >homestead // ---- // test_bytes() -> -// gas irOptimized: 306908 +// gas irOptimized: 314884 // gas legacy: 305827 -// gas legacyOptimized: 255013 +// gas legacyOptimized: 253681 // test_uint256() -> -// gas irOptimized: 435054 +// gas irOptimized: 448346 // gas legacy: 421315 -// gas legacyOptimized: 352838 +// gas legacyOptimized: 351650 diff --git a/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_v2.sol b/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_v2.sol index c0d5f5d3fb9c..f07d4039d5d7 100644 --- a/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_v2.sol +++ b/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_v2.sol @@ -50,6 +50,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: 111708 +// gas irOptimized: 111816 // gas legacy: 113892 -// gas legacyOptimized: 111646 +// gas legacyOptimized: 111658 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 c41905e2a491..bb3ad1aad1a9 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 @@ -30,9 +30,9 @@ contract C is B { } // ---- // test() -> 77 -// gas irOptimized: 55148 -// gas irOptimized code: 55200 +// gas irOptimized: 55117 +// gas irOptimized code: 56800 // gas legacy: 57266 // gas legacy code: 94600 -// gas legacyOptimized: 55173 -// gas legacyOptimized code: 55200 +// gas legacyOptimized: 55195 +// gas legacyOptimized code: 55000 diff --git a/test/libsolidity/semanticTests/abiEncoderV2/calldata_array.sol b/test/libsolidity/semanticTests/abiEncoderV2/calldata_array.sol index f749e403b567..cdce1b95a529 100644 --- a/test/libsolidity/semanticTests/abiEncoderV2/calldata_array.sol +++ b/test/libsolidity/semanticTests/abiEncoderV2/calldata_array.sol @@ -20,6 +20,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: 117157 +// gas irOptimized: 120978 // gas legacy: 101568 // gas legacyOptimized: 119092 diff --git a/test/libsolidity/semanticTests/abiEncoderV2/calldata_overlapped_dynamic_arrays.sol b/test/libsolidity/semanticTests/abiEncoderV2/calldata_overlapped_dynamic_arrays.sol index 46df313331e4..81c9c46c6efa 100644 --- a/test/libsolidity/semanticTests/abiEncoderV2/calldata_overlapped_dynamic_arrays.sol +++ b/test/libsolidity/semanticTests/abiEncoderV2/calldata_overlapped_dynamic_arrays.sol @@ -33,8 +33,8 @@ contract C { // f_which(uint256[],uint256[2],uint256): 0x40, 1, 2, 1, 5, 6 -> 0x20, 0x40, 5, 2 // f_which(uint256[],uint256[2],uint256): 0x40, 1, 2, 1 -> FAILURE // f_storage(uint256[],uint256[2]): 0x20, 1, 2 -> 0x20, 0x60, 0x20, 1, 2 -// gas irOptimized: 111395 +// gas irOptimized: 111415 // gas legacy: 112709 -// gas legacyOptimized: 111852 +// gas legacyOptimized: 111847 // f_storage(uint256[],uint256[2]): 0x40, 1, 2, 5, 6 -> 0x20, 0x80, 0x20, 2, 5, 6 // f_storage(uint256[],uint256[2]): 0x40, 1, 2, 5 -> FAILURE diff --git a/test/libsolidity/semanticTests/abiEncoderV2/storage_array_encoding.sol b/test/libsolidity/semanticTests/abiEncoderV2/storage_array_encoding.sol index 14699df57219..7eb93d401989 100644 --- a/test/libsolidity/semanticTests/abiEncoderV2/storage_array_encoding.sol +++ b/test/libsolidity/semanticTests/abiEncoderV2/storage_array_encoding.sol @@ -18,10 +18,10 @@ contract C { // EVMVersion: >homestead // ---- // h(uint256[2][]): 0x20, 3, 123, 124, 223, 224, 323, 324 -> 32, 256, 0x20, 3, 123, 124, 223, 224, 323, 324 -// gas irOptimized: 180103 +// gas irOptimized: 180086 // gas legacy: 184235 -// gas legacyOptimized: 180873 +// gas legacyOptimized: 180857 // i(uint256[2][2]): 123, 124, 223, 224 -> 32, 128, 123, 124, 223, 224 -// gas irOptimized: 112104 +// gas irOptimized: 112031 // gas legacy: 115091 -// gas legacyOptimized: 112666 +// gas legacyOptimized: 112657 diff --git a/test/libsolidity/semanticTests/abiencodedecode/abi_decode_simple_storage.sol b/test/libsolidity/semanticTests/abiencodedecode/abi_decode_simple_storage.sol index 9f59c43155ee..93e20b475e9c 100644 --- a/test/libsolidity/semanticTests/abiencodedecode/abi_decode_simple_storage.sol +++ b/test/libsolidity/semanticTests/abiencodedecode/abi_decode_simple_storage.sol @@ -8,6 +8,6 @@ contract C { } // ---- // f(bytes): 0x20, 0x80, 0x21, 0x40, 0x7, "abcdefg" -> 0x21, 0x40, 0x7, "abcdefg" -// gas irOptimized: 135452 +// gas irOptimized: 135505 // gas legacy: 137096 -// gas legacyOptimized: 135834 +// gas legacyOptimized: 135824 diff --git a/test/libsolidity/semanticTests/array/array_memory_index_access.sol b/test/libsolidity/semanticTests/array/array_memory_index_access.sol index d313e7acb234..49fc58c45de4 100644 --- a/test/libsolidity/semanticTests/array/array_memory_index_access.sol +++ b/test/libsolidity/semanticTests/array/array_memory_index_access.sol @@ -26,7 +26,7 @@ contract C { // index(uint256): 10 -> true // index(uint256): 20 -> true // index(uint256): 0xFF -> true -// gas irOptimized: 108291 +// gas irOptimized: 108272 // gas legacy: 181523 // gas legacyOptimized: 117443 // accessIndex(uint256,int256): 10, 1 -> 2 diff --git a/test/libsolidity/semanticTests/array/array_storage_index_access.sol b/test/libsolidity/semanticTests/array/array_storage_index_access.sol index 2589e4709dae..2957e6d98d61 100644 --- a/test/libsolidity/semanticTests/array/array_storage_index_access.sol +++ b/test/libsolidity/semanticTests/array/array_storage_index_access.sol @@ -16,38 +16,38 @@ contract C { // ---- // test_indices(uint256): 1 -> // test_indices(uint256): 129 -> -// gas irOptimized: 3003025 +// gas irOptimized: 3017687 // gas legacy: 3038654 // gas legacyOptimized: 2995964 // test_indices(uint256): 5 -> -// gas irOptimized: 576296 +// gas irOptimized: 579670 // gas legacy: 573810 // gas legacyOptimized: 571847 // test_indices(uint256): 10 -> -// gas irOptimized: 157009 +// gas irOptimized: 157953 // gas legacy: 160108 // gas legacyOptimized: 156996 // test_indices(uint256): 15 -> -// gas irOptimized: 171409 +// gas irOptimized: 172733 // gas legacy: 175973 // gas legacyOptimized: 171596 // test_indices(uint256): 0xFF -> -// gas irOptimized: 5645329 +// gas irOptimized: 5673823 // gas legacy: 5715748 // gas legacyOptimized: 5632556 // test_indices(uint256): 1000 -> -// gas irOptimized: 18068701 +// gas irOptimized: 18173005 // gas legacy: 18347810 // gas legacyOptimized: 18037248 // test_indices(uint256): 129 -> -// gas irOptimized: 4136840 +// gas irOptimized: 4166279 // gas legacy: 4140113 // gas legacyOptimized: 4108272 // test_indices(uint256): 128 -> -// gas irOptimized: 395769 +// gas irOptimized: 405522 // gas legacy: 433498 // gas legacyOptimized: 400909 // test_indices(uint256): 1 -> -// gas irOptimized: 580232 +// gas irOptimized: 583437 // gas legacy: 576715 // gas legacyOptimized: 575542 diff --git a/test/libsolidity/semanticTests/array/array_storage_index_boundary_test.sol b/test/libsolidity/semanticTests/array/array_storage_index_boundary_test.sol index c77aad0a4515..494c99782f22 100644 --- a/test/libsolidity/semanticTests/array/array_storage_index_boundary_test.sol +++ b/test/libsolidity/semanticTests/array/array_storage_index_boundary_test.sol @@ -16,11 +16,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: 137913 +// gas irOptimized: 147246 // gas legacy: 133633 // gas legacyOptimized: 114354 // test_boundary_check(uint256,uint256): 256, 255 -> 0 -// gas irOptimized: 140048 +// gas irOptimized: 149422 // gas legacy: 135949 // gas legacyOptimized: 116533 // test_boundary_check(uint256,uint256): 256, 0xFFFF -> FAILURE, hex"4e487b71", 0x32 diff --git a/test/libsolidity/semanticTests/array/array_storage_index_zeroed_test.sol b/test/libsolidity/semanticTests/array/array_storage_index_zeroed_test.sol index 593358659341..de260b373574 100644 --- a/test/libsolidity/semanticTests/array/array_storage_index_zeroed_test.sol +++ b/test/libsolidity/semanticTests/array/array_storage_index_zeroed_test.sol @@ -52,18 +52,18 @@ contract C { // ---- // test_zeroed_indicies(uint256): 1 -> // test_zeroed_indicies(uint256): 5 -> -// gas irOptimized: 131315 +// gas irOptimized: 133763 // gas legacy: 131671 // gas legacyOptimized: 129994 // test_zeroed_indicies(uint256): 10 -> -// gas irOptimized: 224578 +// gas irOptimized: 228556 // gas legacy: 225237 // gas legacyOptimized: 222359 // test_zeroed_indicies(uint256): 15 -> -// gas irOptimized: 321962 +// gas irOptimized: 327360 // gas legacy: 322937 // gas legacyOptimized: 318919 // test_zeroed_indicies(uint256): 0xFF -> -// gas irOptimized: 5080806 +// gas irOptimized: 5180120 // gas legacy: 5093941 // gas legacyOptimized: 5020727 diff --git a/test/libsolidity/semanticTests/array/array_storage_length_access.sol b/test/libsolidity/semanticTests/array/array_storage_length_access.sol index 0669a320971d..47fddc5547bc 100644 --- a/test/libsolidity/semanticTests/array/array_storage_length_access.sol +++ b/test/libsolidity/semanticTests/array/array_storage_length_access.sol @@ -16,7 +16,7 @@ contract C { // gas legacy: 128571 // gas legacyOptimized: 110143 // set_get_length(uint256): 0xFFF -> 0xFFF -// gas irOptimized: 1209119 +// gas irOptimized: 1209116 // gas legacy: 1689548 // gas legacyOptimized: 1393535 // set_get_length(uint256): 0xFFFFF -> FAILURE # Out-of-gas # diff --git a/test/libsolidity/semanticTests/array/array_storage_push_empty.sol b/test/libsolidity/semanticTests/array/array_storage_push_empty.sol index 80376b423f62..b84cdd90a374 100644 --- a/test/libsolidity/semanticTests/array/array_storage_push_empty.sol +++ b/test/libsolidity/semanticTests/array/array_storage_push_empty.sol @@ -12,11 +12,11 @@ contract C { // EVMVersion: >=petersburg // ---- // pushEmpty(uint256): 128 -// gas irOptimized: 401024 +// gas irOptimized: 410745 // gas legacy: 400640 // gas legacyOptimized: 388804 // pushEmpty(uint256): 256 -// gas irOptimized: 683700 +// gas irOptimized: 698285 // gas legacy: 685108 // gas legacyOptimized: 671480 // pushEmpty(uint256): 38869 -> FAILURE # out-of-gas # diff --git a/test/libsolidity/semanticTests/array/array_storage_push_empty_length_address.sol b/test/libsolidity/semanticTests/array/array_storage_push_empty_length_address.sol index 4b5b407eaff5..607e1ecd3547 100644 --- a/test/libsolidity/semanticTests/array/array_storage_push_empty_length_address.sol +++ b/test/libsolidity/semanticTests/array/array_storage_push_empty_length_address.sol @@ -21,11 +21,11 @@ contract C { // gas legacy: 77730 // gas legacyOptimized: 77162 // set_get_length(uint256): 0xFF -> 0xFF -// gas irOptimized: 158881 +// gas irOptimized: 168565 // gas legacy: 696850 // gas legacyOptimized: 134488 // set_get_length(uint256): 0xFFF -> 0xFFF -// gas irOptimized: 1762213 +// gas irOptimized: 1908127 // gas legacy: 9857362 // gas legacyOptimized: 1393660 // set_get_length(uint256): 0xFFFFF -> FAILURE # Out-of-gas # diff --git a/test/libsolidity/semanticTests/array/array_storage_push_pop.sol b/test/libsolidity/semanticTests/array/array_storage_push_pop.sol index 5befbe2282b2..78a74ab5d4ff 100644 --- a/test/libsolidity/semanticTests/array/array_storage_push_pop.sol +++ b/test/libsolidity/semanticTests/array/array_storage_push_pop.sol @@ -17,11 +17,11 @@ contract C { // gas legacy: 105722 // gas legacyOptimized: 103508 // set_get_length(uint256): 0xFF -> 0 -// gas irOptimized: 815997 +// gas irOptimized: 833586 // gas legacy: 808020 // gas legacyOptimized: 784467 // set_get_length(uint256): 0xFFF -> 0 -// gas irOptimized: 12746889 +// gas irOptimized: 13029438 // gas legacy: 12612192 // gas legacyOptimized: 12239199 // set_get_length(uint256): 0xFFFF -> FAILURE # Out-of-gas # 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 95280054aae7..918185e9afa2 100644 --- a/test/libsolidity/semanticTests/array/arrays_complex_from_and_to_storage.sol +++ b/test/libsolidity/semanticTests/array/arrays_complex_from_and_to_storage.sol @@ -12,9 +12,9 @@ contract Test { } // ---- // set(uint24[3][]): 0x20, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12 -> 0x06 -// gas irOptimized: 186557 +// gas irOptimized: 185219 // gas legacy: 211054 -// gas legacyOptimized: 206042 +// gas legacyOptimized: 206077 // data(uint256,uint256): 0x02, 0x02 -> 0x09 // data(uint256,uint256): 0x05, 0x01 -> 0x11 // data(uint256,uint256): 0x06, 0x00 -> FAILURE diff --git a/test/libsolidity/semanticTests/array/byte_array_transitional_2.sol b/test/libsolidity/semanticTests/array/byte_array_transitional_2.sol index 3e0f02225bce..401f97a1c97a 100644 --- a/test/libsolidity/semanticTests/array/byte_array_transitional_2.sol +++ b/test/libsolidity/semanticTests/array/byte_array_transitional_2.sol @@ -17,6 +17,6 @@ contract c { } // ---- // test() -> 0 -// gas irOptimized: 123560 +// gas irOptimized: 122719 // gas legacy: 147098 // gas legacyOptimized: 144200 diff --git a/test/libsolidity/semanticTests/array/bytes_length_member.sol b/test/libsolidity/semanticTests/array/bytes_length_member.sol index 0a3c58b3ac92..105bbfba8d53 100644 --- a/test/libsolidity/semanticTests/array/bytes_length_member.sol +++ b/test/libsolidity/semanticTests/array/bytes_length_member.sol @@ -13,7 +13,7 @@ contract c { // ---- // getLength() -> 0 // set(): 1, 2 -> true -// gas irOptimized: 110393 +// gas irOptimized: 110425 // gas legacy: 110952 // gas legacyOptimized: 110576 // getLength() -> 68 diff --git a/test/libsolidity/semanticTests/array/constant_var_as_array_length.sol b/test/libsolidity/semanticTests/array/constant_var_as_array_length.sol index 19acb7cba14b..342f3218fcb4 100644 --- a/test/libsolidity/semanticTests/array/constant_var_as_array_length.sol +++ b/test/libsolidity/semanticTests/array/constant_var_as_array_length.sol @@ -8,11 +8,11 @@ contract C { } // ---- // constructor(): 1, 2, 3 -> -// gas irOptimized: 124816 +// gas irOptimized: 124991 // gas irOptimized code: 14800 // gas legacy: 134317 // gas legacy code: 46200 -// gas legacyOptimized: 127062 +// gas legacyOptimized: 127166 // gas legacyOptimized code: 23400 // a(uint256): 0 -> 1 // a(uint256): 1 -> 2 diff --git a/test/libsolidity/semanticTests/array/copying/array_copy_calldata_storage.sol b/test/libsolidity/semanticTests/array/copying/array_copy_calldata_storage.sol index 80ecd3e1cef4..96580c47db8c 100644 --- a/test/libsolidity/semanticTests/array/copying/array_copy_calldata_storage.sol +++ b/test/libsolidity/semanticTests/array/copying/array_copy_calldata_storage.sol @@ -20,7 +20,7 @@ contract c { } // ---- // store(uint256[9],uint8[3][]): 21, 22, 23, 24, 25, 26, 27, 28, 29, 0x140, 4, 1, 2, 3, 11, 12, 13, 21, 22, 23, 31, 32, 33 -> 32 -// gas irOptimized: 648315 +// gas irOptimized: 647725 // gas legacy: 694356 -// gas legacyOptimized: 693864 +// gas legacyOptimized: 693850 // retrieve() -> 9, 28, 9, 28, 4, 3, 32 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 600f00a98110..9609215a7dca 100644 --- a/test/libsolidity/semanticTests/array/copying/array_copy_cleanup_uint40.sol +++ b/test/libsolidity/semanticTests/array/copying/array_copy_cleanup_uint40.sol @@ -46,6 +46,6 @@ contract C { } // ---- // f() -> true -// gas irOptimized: 117264 +// gas irOptimized: 122592 // gas legacy: 124660 // gas legacyOptimized: 122801 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 0bdcda1d9e7f..6c0ba7af6928 100644 --- a/test/libsolidity/semanticTests/array/copying/array_copy_clear_storage.sol +++ b/test/libsolidity/semanticTests/array/copying/array_copy_clear_storage.sol @@ -13,6 +13,6 @@ contract C { } // ---- // f() -> 0 -// gas irOptimized: 107453 +// gas irOptimized: 108246 // gas legacy: 108218 // gas legacyOptimized: 107625 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 6e81269d8a50..2176655fe389 100644 --- a/test/libsolidity/semanticTests/array/copying/array_copy_different_packing.sol +++ b/test/libsolidity/semanticTests/array/copying/array_copy_different_packing.sol @@ -18,6 +18,6 @@ contract c { } // ---- // test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x05000000000000000000000000000000000000000000000000 -// gas irOptimized: 207889 +// gas irOptimized: 208459 // gas legacy: 220707 // gas legacyOptimized: 220098 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 385f2ecfbf1e..20aee3a293f4 100644 --- a/test/libsolidity/semanticTests/array/copying/array_copy_including_array.sol +++ b/test/libsolidity/semanticTests/array/copying/array_copy_including_array.sol @@ -35,12 +35,12 @@ contract c { } // ---- // test() -> 0x02000202 -// gas irOptimized: 4547793 +// gas irOptimized: 4549703 // gas legacy: 4475396 // gas legacyOptimized: 4447665 // storageEmpty -> 1 // clear() -> 0, 0 -// gas irOptimized: 4474777 +// gas irOptimized: 4478226 // gas legacy: 4407188 // gas legacyOptimized: 4381336 // 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 737e4b32bc1d..0420f953bb56 100644 --- a/test/libsolidity/semanticTests/array/copying/array_copy_nested_array.sol +++ b/test/libsolidity/semanticTests/array/copying/array_copy_nested_array.sol @@ -12,6 +12,6 @@ contract c { } // ---- // test(uint256[2][]): 32, 3, 7, 8, 9, 10, 11, 12 -> 10 -// gas irOptimized: 689656 +// gas irOptimized: 689558 // gas legacy: 686178 -// gas legacyOptimized: 685628 +// gas legacyOptimized: 685612 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 d477dc6cf978..e292809b800a 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 @@ -17,6 +17,6 @@ contract c { } // ---- // test() -> 5, 4 -// gas irOptimized: 205044 +// gas irOptimized: 205667 // gas legacy: 213863 // gas legacyOptimized: 212902 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 0571195861b7..44fede749cc4 100644 --- a/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_different_base_nested.sol +++ b/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_different_base_nested.sol @@ -21,6 +21,6 @@ contract c { } // ---- // test() -> 3, 4 -// gas irOptimized: 169565 +// gas irOptimized: 169669 // gas legacy: 175424 // gas legacyOptimized: 172535 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 99dd1ca934ff..1f102ea14a7c 100644 --- a/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_dyn_dyn.sol +++ b/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_dyn_dyn.sol @@ -15,7 +15,7 @@ contract c { // ---- // setData1(uint256,uint256,uint256): 10, 5, 4 -> // copyStorageStorage() -> -// gas irOptimized: 111348 +// gas irOptimized: 111353 // gas legacy: 109272 // gas legacyOptimized: 109262 // 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 30173409eb77..03c1f4e8753c 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 @@ -17,6 +17,6 @@ contract c { } // ---- // test() -> 5, 4 -// gas irOptimized: 252929 +// gas irOptimized: 253591 // gas legacy: 250892 // gas legacyOptimized: 250046 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 971469dec64f..f4bf1b2d2131 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 @@ -11,6 +11,6 @@ contract c { } // ---- // test() -> 9, 4 -// gas irOptimized: 123135 +// gas irOptimized: 123180 // gas legacy: 123567 // gas legacyOptimized: 123202 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 0d613e5e946b..145a8060edb1 100644 --- a/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_static_static.sol +++ b/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_static_static.sol @@ -14,6 +14,6 @@ contract c { } // ---- // test() -> 8, 0 -// gas irOptimized: 196259 +// gas irOptimized: 196251 // gas legacy: 194843 // gas legacyOptimized: 194281 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 cfb623393c87..7fa5ee515f87 100644 --- a/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_struct.sol +++ b/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_struct.sol @@ -17,7 +17,7 @@ contract c { } // ---- // test() -> 4, 5 -// gas irOptimized: 190694 +// gas irOptimized: 190628 // gas legacy: 190852 // gas legacyOptimized: 189658 // 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 6bd31ca5af46..d88ac0674672 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 @@ -15,6 +15,6 @@ contract C { } // ---- // f() -> 0x20, 2, 0x40, 0xa0, 2, 0, 1, 2, 2, 3 -// gas irOptimized: 161624 +// gas irOptimized: 161793 // gas legacy: 162203 -// gas legacyOptimized: 159934 +// gas legacyOptimized: 159953 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 10a48a18c574..ebfbdeab9720 100644 --- a/test/libsolidity/semanticTests/array/copying/array_copy_target_leftover.sol +++ b/test/libsolidity/semanticTests/array/copying/array_copy_target_leftover.sol @@ -17,6 +17,6 @@ contract c { } // ---- // test() -> 0xffffffff, 0x0000000000000000000000000a00090008000700060005000400030002000100, 0x0000000000000000000000000000000000000000000000000000000000000000 -// gas irOptimized: 100980 +// gas irOptimized: 100495 // gas legacy: 158142 -// gas legacyOptimized: 141096 +// gas legacyOptimized: 141020 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 a839e3bb44b2..309753066510 100644 --- a/test/libsolidity/semanticTests/array/copying/array_copy_target_simple.sol +++ b/test/libsolidity/semanticTests/array/copying/array_copy_target_simple.sol @@ -18,6 +18,6 @@ contract c { } // ---- // test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x0 -// gas irOptimized: 273372 +// gas irOptimized: 273545 // gas legacy: 282604 // gas legacyOptimized: 281510 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 f9e1cbd27ef1..b08487417547 100644 --- a/test/libsolidity/semanticTests/array/copying/array_copy_target_simple_2.sol +++ b/test/libsolidity/semanticTests/array/copying/array_copy_target_simple_2.sol @@ -18,6 +18,6 @@ contract c { } // ---- // test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x00 -// gas irOptimized: 233118 +// gas irOptimized: 232997 // gas legacy: 235697 // gas legacyOptimized: 235193 diff --git a/test/libsolidity/semanticTests/array/copying/array_elements_to_mapping.sol b/test/libsolidity/semanticTests/array/copying/array_elements_to_mapping.sol index b138e7265f90..085f72ed96c1 100644 --- a/test/libsolidity/semanticTests/array/copying/array_elements_to_mapping.sol +++ b/test/libsolidity/semanticTests/array/copying/array_elements_to_mapping.sol @@ -52,9 +52,9 @@ contract C { } // ---- // from_storage() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 -// gas irOptimized: 150022 +// gas irOptimized: 149880 // gas legacy: 150745 -// gas legacyOptimized: 148678 +// gas legacyOptimized: 148700 // from_storage_ptr() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 // from_memory() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 // from_calldata(uint8[][]): 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 diff --git a/test/libsolidity/semanticTests/array/copying/array_nested_calldata_to_storage.sol b/test/libsolidity/semanticTests/array/copying/array_nested_calldata_to_storage.sol index 919e83298675..ac37f794e147 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: 180716 +// gas irOptimized: 181041 // test2(uint256[][2]): 0x20, 0x40, 0x40, 2, 23, 42 -> 2, 65 -// gas irOptimized: 157544 +// gas irOptimized: 157604 // test3(uint256[2][]): 0x20, 2, 23, 42, 23, 42 -> 2, 65 -// gas irOptimized: 134634 +// gas irOptimized: 134813 // test4(uint256[2][2]): 23, 42, 23, 42 -> 65 -// gas irOptimized: 111252 +// gas irOptimized: 111177 diff --git a/test/libsolidity/semanticTests/array/copying/array_nested_memory_to_storage.sol b/test/libsolidity/semanticTests/array/copying/array_nested_memory_to_storage.sol index eb4b1bbb9aab..e2228f993f07 100644 --- a/test/libsolidity/semanticTests/array/copying/array_nested_memory_to_storage.sol +++ b/test/libsolidity/semanticTests/array/copying/array_nested_memory_to_storage.sol @@ -38,12 +38,12 @@ contract Test { } // ---- // test() -> 24 -// gas irOptimized: 226666 +// gas irOptimized: 226743 // gas legacy: 227084 // gas legacyOptimized: 226529 // test1() -> 3 // test2() -> 6 // test3() -> 24 -// gas irOptimized: 141225 +// gas irOptimized: 141325 // gas legacy: 142238 // gas legacyOptimized: 141365 diff --git a/test/libsolidity/semanticTests/array/copying/array_of_function_external_storage_to_storage_dynamic.sol b/test/libsolidity/semanticTests/array/copying/array_of_function_external_storage_to_storage_dynamic.sol index 01329504d2a9..ab3c172d3399 100644 --- a/test/libsolidity/semanticTests/array/copying/array_of_function_external_storage_to_storage_dynamic.sol +++ b/test/libsolidity/semanticTests/array/copying/array_of_function_external_storage_to_storage_dynamic.sol @@ -45,7 +45,7 @@ contract C { } // ---- // copyExternalStorageArrayOfFunctionType() -> true -// gas irOptimized: 104592 +// gas irOptimized: 104566 // gas legacy: 108554 -// gas legacyOptimized: 102413 +// gas legacyOptimized: 102405 // copyInternalArrayOfFunctionType() -> true diff --git a/test/libsolidity/semanticTests/array/copying/array_of_function_external_storage_to_storage_dynamic_different_mutability.sol b/test/libsolidity/semanticTests/array/copying/array_of_function_external_storage_to_storage_dynamic_different_mutability.sol index 50756d0b0c3d..2bb3bcf333e3 100644 --- a/test/libsolidity/semanticTests/array/copying/array_of_function_external_storage_to_storage_dynamic_different_mutability.sol +++ b/test/libsolidity/semanticTests/array/copying/array_of_function_external_storage_to_storage_dynamic_different_mutability.sol @@ -48,8 +48,8 @@ contract C { } // ---- // copyExternalStorageArraysOfFunctionType() -> true -// gas irOptimized: 104265 +// gas irOptimized: 104238 // gas legacy: 108295 -// gas legacyOptimized: 102146 +// gas legacyOptimized: 102162 // copyInternalArrayOfFunctionType() -> true // gas legacy: 104178 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 546a6e49e48d..3147401cfa1d 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: 119704 +// gas irOptimized: 120747 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 38e26e480add..5b3fe1f7016f 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: 118362 +// gas irOptimized: 118796 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 c6e6c58765ac..09037719a6f0 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: 326771 +// gas irOptimized: 327456 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 510e7c9a4a62..8b6ad78ea777 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: 181890 +// gas irOptimized: 181932 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 5c44ef16a54d..82e65edf1d49 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 @@ -12,6 +12,6 @@ contract C { } // ---- // f() -> 1, 2, 3 -// gas irOptimized: 131915 +// gas irOptimized: 131939 // gas legacy: 134606 // gas legacyOptimized: 131938 diff --git a/test/libsolidity/semanticTests/array/copying/array_to_mapping.sol b/test/libsolidity/semanticTests/array/copying/array_to_mapping.sol index 893610eb1377..75a68759b6e0 100644 --- a/test/libsolidity/semanticTests/array/copying/array_to_mapping.sol +++ b/test/libsolidity/semanticTests/array/copying/array_to_mapping.sol @@ -37,8 +37,8 @@ contract C { } // ---- // from_storage() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 -// gas irOptimized: 147889 +// gas irOptimized: 147761 // gas legacy: 148896 -// gas legacyOptimized: 146901 +// gas legacyOptimized: 146923 // from_storage_ptr() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 // from_memory() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 diff --git a/test/libsolidity/semanticTests/array/copying/arrays_from_and_to_storage.sol b/test/libsolidity/semanticTests/array/copying/arrays_from_and_to_storage.sol index 0deb396d3d66..af2983b066bd 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 { // set(uint24[]): 0x20, 18, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18 -> 18 // gas irOptimized: 99616 // gas legacy: 103509 -// gas legacyOptimized: 101390 +// gas legacyOptimized: 101266 // data(uint256): 7 -> 8 // data(uint256): 15 -> 16 // data(uint256): 18 -> FAILURE diff --git a/test/libsolidity/semanticTests/array/copying/bytes_inside_mappings.sol b/test/libsolidity/semanticTests/array/copying/bytes_inside_mappings.sol index 19e5ddebd443..e61b7dff7a5f 100644 --- a/test/libsolidity/semanticTests/array/copying/bytes_inside_mappings.sol +++ b/test/libsolidity/semanticTests/array/copying/bytes_inside_mappings.sol @@ -5,11 +5,11 @@ contract c { } // ---- // set(uint256): 1, 2 -> true -// gas irOptimized: 110558 +// gas irOptimized: 110550 // gas legacy: 111312 // gas legacyOptimized: 110741 // set(uint256): 2, 2, 3, 4, 5 -> true -// gas irOptimized: 177509 +// gas irOptimized: 177501 // gas legacy: 178314 // gas legacyOptimized: 177716 // 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 24565b4c62a6..ea364d4378ec 100644 --- a/test/libsolidity/semanticTests/array/copying/bytes_storage_to_storage.sol +++ b/test/libsolidity/semanticTests/array/copying/bytes_storage_to_storage.sol @@ -17,25 +17,25 @@ contract c { // ---- // f(uint256): 0 -> 0x20, 0x00 // f(uint256): 31 -> 0x20, 0x1f, 0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e00 -// gas irOptimized: 103283 +// gas irOptimized: 103269 // gas legacy: 112883 -// gas legacyOptimized: 112629 +// gas legacyOptimized: 112647 // f(uint256): 32 -> 0x20, 0x20, 1780731860627700044960722568376592200742329637303199754547598369979440671 -// gas irOptimized: 117740 +// gas irOptimized: 117928 // gas legacy: 128943 -// gas legacyOptimized: 128864 +// gas legacyOptimized: 128854 // f(uint256): 33 -> 0x20, 33, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x2000000000000000000000000000000000000000000000000000000000000000 -// gas irOptimized: 124080 +// gas irOptimized: 124200 // gas legacy: 136071 -// gas legacyOptimized: 135479 +// gas legacyOptimized: 135469 // f(uint256): 63 -> 0x20, 0x3f, 1780731860627700044960722568376592200742329637303199754547598369979440671, 14532552714582660066924456880521368950258152170031413196862950297402215316992 -// gas irOptimized: 127140 +// gas irOptimized: 127350 // gas legacy: 148671 -// gas legacyOptimized: 148709 +// gas legacyOptimized: 148699 // f(uint256): 12 -> 0x20, 0x0c, 0x0102030405060708090a0b0000000000000000000000000000000000000000 // gas legacy: 59345 // gas legacyOptimized: 57279 // f(uint256): 129 -> 0x20, 0x81, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f, 29063324697304692433803953038474361308315562010425523193971352996434451193439, 0x606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f, -57896044618658097711785492504343953926634992332820282019728792003956564819968 -// gas irOptimized: 416966 +// gas irOptimized: 417312 // gas legacy: 458976 -// gas legacyOptimized: 460674 +// gas legacyOptimized: 460664 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 706232d589f7..1da1d0a40c78 100644 --- a/test/libsolidity/semanticTests/array/copying/calldata_array_dynamic_to_storage.sol +++ b/test/libsolidity/semanticTests/array/copying/calldata_array_dynamic_to_storage.sol @@ -9,6 +9,6 @@ contract C { } // ---- // f(uint256[]): 0x20, 0x03, 0x1, 0x2, 0x3 -> 0x1 -// gas irOptimized: 110968 +// gas irOptimized: 111096 // gas legacy: 111551 -// gas legacyOptimized: 111339 +// gas legacyOptimized: 111323 diff --git a/test/libsolidity/semanticTests/array/copying/calldata_array_to_mapping.sol b/test/libsolidity/semanticTests/array/copying/calldata_array_to_mapping.sol index b8bd588d5672..48460586d280 100644 --- a/test/libsolidity/semanticTests/array/copying/calldata_array_to_mapping.sol +++ b/test/libsolidity/semanticTests/array/copying/calldata_array_to_mapping.sol @@ -14,4 +14,4 @@ contract C { // compileViaYul: true // ---- // from_calldata(uint8[][]): 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 -// gas irOptimized: 139637 +// gas irOptimized: 139587 diff --git a/test/libsolidity/semanticTests/array/copying/cleanup_during_multi_element_per_slot_copy.sol b/test/libsolidity/semanticTests/array/copying/cleanup_during_multi_element_per_slot_copy.sol index 36b94d7c3974..e6284072d1f9 100644 --- a/test/libsolidity/semanticTests/array/copying/cleanup_during_multi_element_per_slot_copy.sol +++ b/test/libsolidity/semanticTests/array/copying/cleanup_during_multi_element_per_slot_copy.sol @@ -16,8 +16,8 @@ contract C { } // ---- // constructor() -// gas irOptimized: 89121 -// gas irOptimized code: 137200 +// gas irOptimized: 90065 +// gas irOptimized code: 149000 // gas legacy: 89553 // gas legacy code: 126200 // gas legacyOptimized: 83556 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 33a4c7045af5..7c0459ef139e 100644 --- a/test/libsolidity/semanticTests/array/copying/copy_byte_array_in_struct_to_storage.sol +++ b/test/libsolidity/semanticTests/array/copying/copy_byte_array_in_struct_to_storage.sol @@ -35,12 +35,12 @@ contract C { } // ---- // f() -> 0x40, 0x80, 6, 0x6162636465660000000000000000000000000000000000000000000000000000, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000 -// gas irOptimized: 179420 +// gas irOptimized: 179408 // gas legacy: 180675 -// gas legacyOptimized: 179700 +// gas legacyOptimized: 179686 // g() -> 0x40, 0xc0, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000, 0x11, 0x3132333435363738393233343536373839000000000000000000000000000000 -// gas irOptimized: 106349 +// gas irOptimized: 106344 // gas legacy: 109394 -// gas legacyOptimized: 106614 +// gas legacyOptimized: 106600 // h() -> 0x40, 0x60, 0x00, 0x00 // storageEmpty -> 1 diff --git a/test/libsolidity/semanticTests/array/copying/copy_byte_array_to_storage.sol b/test/libsolidity/semanticTests/array/copying/copy_byte_array_to_storage.sol index d4599cdb7e58..1fd42ab34621 100644 --- a/test/libsolidity/semanticTests/array/copying/copy_byte_array_to_storage.sol +++ b/test/libsolidity/semanticTests/array/copying/copy_byte_array_to_storage.sol @@ -46,6 +46,6 @@ contract C { } // ---- // f() -> 0xff -// gas irOptimized: 143412 +// gas irOptimized: 143867 // gas legacy: 153395 -// gas legacyOptimized: 146720 +// gas legacyOptimized: 146689 diff --git a/test/libsolidity/semanticTests/array/copying/copy_function_internal_storage_array.sol b/test/libsolidity/semanticTests/array/copying/copy_function_internal_storage_array.sol index fb2177901239..a6a64942d2ad 100644 --- a/test/libsolidity/semanticTests/array/copying/copy_function_internal_storage_array.sol +++ b/test/libsolidity/semanticTests/array/copying/copy_function_internal_storage_array.sol @@ -15,6 +15,6 @@ contract C { } // ---- // test() -> 7 -// gas irOptimized: 122455 +// gas irOptimized: 122461 // gas legacy: 205176 // gas legacyOptimized: 204971 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 85c396fb4e12..48d02bdc7737 100644 --- a/test/libsolidity/semanticTests/array/copying/copy_removes_bytes_data.sol +++ b/test/libsolidity/semanticTests/array/copying/copy_removes_bytes_data.sol @@ -7,7 +7,7 @@ contract c { } // ---- // set(): 1, 2, 3, 4, 5 -> true -// gas irOptimized: 177376 +// gas irOptimized: 177344 // gas legacy: 177954 // gas legacyOptimized: 177550 // storageEmpty -> 0 diff --git a/test/libsolidity/semanticTests/array/copying/elements_of_nested_array_of_structs_calldata_to_storage.sol b/test/libsolidity/semanticTests/array/copying/elements_of_nested_array_of_structs_calldata_to_storage.sol index 6c5c0e8faa6f..672e7435f1a9 100644 --- a/test/libsolidity/semanticTests/array/copying/elements_of_nested_array_of_structs_calldata_to_storage.sol +++ b/test/libsolidity/semanticTests/array/copying/elements_of_nested_array_of_structs_calldata_to_storage.sol @@ -31,8 +31,8 @@ contract C { // compileViaYul: true // ---- // test1((uint8[],uint8[2])[][][]): 0x20, 1, 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -// gas irOptimized: 327883 +// gas irOptimized: 327921 // test2((uint8[],uint8[2])[][1][]): 0x20, 2, 0x40, 0x0160, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13, 0x20, 1, 0x20, 0x60, 31, 37, 2, 23, 29 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13 -// gas irOptimized: 140882 +// gas irOptimized: 141162 // test3((uint8[],uint8[2])[1][][2]): 0x20, 0x40, 0x60, 0, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -// gas irOptimized: 188541 +// gas irOptimized: 188442 diff --git a/test/libsolidity/semanticTests/array/copying/elements_of_nested_array_of_structs_memory_to_storage.sol b/test/libsolidity/semanticTests/array/copying/elements_of_nested_array_of_structs_memory_to_storage.sol index a593b1d1dd0b..f232d8aba9d4 100644 --- a/test/libsolidity/semanticTests/array/copying/elements_of_nested_array_of_structs_memory_to_storage.sol +++ b/test/libsolidity/semanticTests/array/copying/elements_of_nested_array_of_structs_memory_to_storage.sol @@ -31,8 +31,8 @@ contract C { // compileViaYul: true // ---- // test1((uint8[],uint8[2])[][][]): 0x20, 1, 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -// gas irOptimized: 332687 +// gas irOptimized: 332567 // test2((uint8[],uint8[2])[][1][]): 0x20, 2, 0x40, 0x0160, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13, 0x20, 1, 0x20, 0x60, 31, 37, 2, 23, 29 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13 -// gas irOptimized: 145159 +// gas irOptimized: 145409 // test3((uint8[],uint8[2])[1][][2]): 0x20, 0x40, 0x60, 0, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -// gas irOptimized: 192616 +// gas irOptimized: 192248 diff --git a/test/libsolidity/semanticTests/array/copying/function_type_array_to_storage.sol b/test/libsolidity/semanticTests/array/copying/function_type_array_to_storage.sol index 56a415079084..097c7b4d10d2 100644 --- a/test/libsolidity/semanticTests/array/copying/function_type_array_to_storage.sol +++ b/test/libsolidity/semanticTests/array/copying/function_type_array_to_storage.sol @@ -46,11 +46,11 @@ contract C { } // ---- // test() -> 0x20, 0x14, "[a called][b called]" -// gas irOptimized: 116546 +// gas irOptimized: 116530 // gas legacy: 118845 -// gas legacyOptimized: 116887 +// gas legacyOptimized: 116844 // test2() -> 0x20, 0x14, "[b called][a called]" // test3() -> 0x20, 0x14, "[b called][a called]" -// gas irOptimized: 103147 +// gas irOptimized: 103150 // gas legacy: 102654 -// gas legacyOptimized: 101581 +// gas legacyOptimized: 101556 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 79882a74b267..c5497547900f 100644 --- a/test/libsolidity/semanticTests/array/copying/memory_dyn_2d_bytes_to_storage.sol +++ b/test/libsolidity/semanticTests/array/copying/memory_dyn_2d_bytes_to_storage.sol @@ -18,6 +18,6 @@ contract C { } // ---- // f() -> 3 -// gas irOptimized: 127422 +// gas irOptimized: 128296 // gas legacy: 129050 -// gas legacyOptimized: 128222 +// gas legacyOptimized: 128210 diff --git a/test/libsolidity/semanticTests/array/copying/nested_array_element_storage_to_storage.sol b/test/libsolidity/semanticTests/array/copying/nested_array_element_storage_to_storage.sol index f85b8eb9f31b..ad00ee8c513b 100644 --- a/test/libsolidity/semanticTests/array/copying/nested_array_element_storage_to_storage.sol +++ b/test/libsolidity/semanticTests/array/copying/nested_array_element_storage_to_storage.sol @@ -70,15 +70,15 @@ contract C { } // ---- // test1() -> -// gas irOptimized: 150468 +// gas irOptimized: 150488 // gas legacy: 150949 // gas legacyOptimized: 150906 // test2() -> FAILURE -// gas irOptimized: 150378 +// gas irOptimized: 150389 // gas legacy: 150673 // gas legacyOptimized: 150576 // test3() -> -// gas irOptimized: 123762 +// gas irOptimized: 124300 // gas legacy: 125333 // gas legacyOptimized: 125127 // test4() -> FAILURE diff --git a/test/libsolidity/semanticTests/array/copying/nested_array_of_structs_calldata_to_storage.sol b/test/libsolidity/semanticTests/array/copying/nested_array_of_structs_calldata_to_storage.sol index 3666443bbc18..3b774f56e4eb 100644 --- a/test/libsolidity/semanticTests/array/copying/nested_array_of_structs_calldata_to_storage.sol +++ b/test/libsolidity/semanticTests/array/copying/nested_array_of_structs_calldata_to_storage.sol @@ -29,8 +29,8 @@ contract C { // compileViaYul: true // ---- // test1((uint8[],uint8[2])[][]): 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -// gas irOptimized: 304756 +// gas irOptimized: 304794 // test2((uint8[],uint8[2])[][1]): 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13 -// gas irOptimized: 116467 +// gas irOptimized: 116653 // test3((uint8[],uint8[2])[1][]): 0x20, 2, 0x40, 0x0120, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 0x0120, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -// gas irOptimized: 188030 +// gas irOptimized: 188000 diff --git a/test/libsolidity/semanticTests/array/copying/nested_array_of_structs_memory_to_storage.sol b/test/libsolidity/semanticTests/array/copying/nested_array_of_structs_memory_to_storage.sol index 821d33d4dd04..35e7943b8b62 100644 --- a/test/libsolidity/semanticTests/array/copying/nested_array_of_structs_memory_to_storage.sol +++ b/test/libsolidity/semanticTests/array/copying/nested_array_of_structs_memory_to_storage.sol @@ -29,8 +29,8 @@ contract C { // compileViaYul: true // ---- // test1((uint8[],uint8[2])[][]): 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -// gas irOptimized: 309101 +// gas irOptimized: 309078 // test2((uint8[],uint8[2])[][1]): 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13 -// gas irOptimized: 118265 +// gas irOptimized: 118314 // test3((uint8[],uint8[2])[1][]): 0x20, 2, 0x40, 0x0120, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 0x0120, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -// gas irOptimized: 191011 +// gas irOptimized: 191051 diff --git a/test/libsolidity/semanticTests/array/copying/nested_array_of_structs_storage_to_storage.sol b/test/libsolidity/semanticTests/array/copying/nested_array_of_structs_storage_to_storage.sol index c356e029f6b6..d0d1691597ee 100644 --- a/test/libsolidity/semanticTests/array/copying/nested_array_of_structs_storage_to_storage.sol +++ b/test/libsolidity/semanticTests/array/copying/nested_array_of_structs_storage_to_storage.sol @@ -63,7 +63,7 @@ contract C { // compileViaYul: true // ---- // test1() -// gas irOptimized: 123202 +// gas irOptimized: 123195 // test2() -// gas irOptimized: 123027 +// gas irOptimized: 123018 // test3() diff --git a/test/libsolidity/semanticTests/array/copying/nested_dynamic_array_element_calldata_to_storage.sol b/test/libsolidity/semanticTests/array/copying/nested_dynamic_array_element_calldata_to_storage.sol index dfb7c27aca40..a4222be0b4f1 100644 --- a/test/libsolidity/semanticTests/array/copying/nested_dynamic_array_element_calldata_to_storage.sol +++ b/test/libsolidity/semanticTests/array/copying/nested_dynamic_array_element_calldata_to_storage.sol @@ -30,7 +30,7 @@ contract C { // compileViaYul: true // ---- // test(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -// gas irOptimized: 138040 +// gas irOptimized: 137897 // test2(uint8[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -// gas irOptimized: 164246 +// gas irOptimized: 164506 // gas legacyOptimized: 120228 diff --git a/test/libsolidity/semanticTests/array/copying/storage_memory_nested.sol b/test/libsolidity/semanticTests/array/copying/storage_memory_nested.sol index 9a2fbb4d9d58..ac92189e48de 100644 --- a/test/libsolidity/semanticTests/array/copying/storage_memory_nested.sol +++ b/test/libsolidity/semanticTests/array/copying/storage_memory_nested.sol @@ -17,6 +17,6 @@ contract C { } // ---- // f() -> 1, 2, 3, 4, 5, 6, 7 -// gas irOptimized: 205783 +// gas irOptimized: 206440 // gas legacy: 211765 // gas legacyOptimized: 211181 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 0e8cff97fd57..b743a5825a75 100644 --- a/test/libsolidity/semanticTests/array/copying/storage_memory_nested_bytes.sol +++ b/test/libsolidity/semanticTests/array/copying/storage_memory_nested_bytes.sol @@ -11,6 +11,6 @@ contract C { } // ---- // f() -> 0x20, 0x02, 0x40, 0x80, 3, 0x6162630000000000000000000000000000000000000000000000000000000000, 0x99, 44048183304486788312148433451363384677562265908331949128489393215789685032262, 32241931068525137014058842823026578386641954854143559838526554899205067598957, 49951309422467613961193228765530489307475214998374779756599339590522149884499, 0x54555658595a6162636465666768696a6b6c6d6e6f707172737475767778797a, 0x4142434445464748494a4b4c4d4e4f5051525354555658595a00000000000000 -// gas irOptimized: 202162 +// gas irOptimized: 202083 // gas legacy: 204328 -// gas legacyOptimized: 202887 +// gas legacyOptimized: 202900 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 3606d7d60188..da7187a27e65 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 @@ -18,6 +18,6 @@ contract C { } // ---- // f() -> 1, 2, 3, 4, 5, 6, 7 -// gas irOptimized: 205783 +// gas irOptimized: 206440 // gas legacy: 211770 // gas legacyOptimized: 211186 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 cfbf5c874575..d4a348ea4095 100644 --- a/test/libsolidity/semanticTests/array/copying/storage_memory_nested_struct.sol +++ b/test/libsolidity/semanticTests/array/copying/storage_memory_nested_struct.sol @@ -24,6 +24,6 @@ contract C { } // ---- // f() -> 11, 0x0c, 1, 0x15, 22, 4 -// gas irOptimized: 291047 +// gas irOptimized: 291212 // gas legacy: 293407 // gas legacyOptimized: 290218 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 48d06ab4ea37..c5bd7d0b0c28 100644 --- a/test/libsolidity/semanticTests/array/copying/storage_memory_packed_dyn.sol +++ b/test/libsolidity/semanticTests/array/copying/storage_memory_packed_dyn.sol @@ -13,6 +13,6 @@ contract C { } // ---- // f() -> 2, 3, 4 -// gas irOptimized: 109104 +// gas irOptimized: 114338 // gas legacy: 122235 // gas legacyOptimized: 118411 diff --git a/test/libsolidity/semanticTests/array/create_memory_array.sol b/test/libsolidity/semanticTests/array/create_memory_array.sol index d507f080f36f..a95499fd8aa5 100644 --- a/test/libsolidity/semanticTests/array/create_memory_array.sol +++ b/test/libsolidity/semanticTests/array/create_memory_array.sol @@ -18,6 +18,6 @@ contract C { } // ---- // f() -> "A", 8, 4, "B" -// gas irOptimized: 125822 +// gas irOptimized: 136664 // gas legacy: 121382 // gas legacyOptimized: 115488 diff --git a/test/libsolidity/semanticTests/array/delete/bytes_delete_element.sol b/test/libsolidity/semanticTests/array/delete/bytes_delete_element.sol index fffea685a8cb..5deaa7d4e80c 100644 --- a/test/libsolidity/semanticTests/array/delete/bytes_delete_element.sol +++ b/test/libsolidity/semanticTests/array/delete/bytes_delete_element.sol @@ -16,6 +16,6 @@ contract c { } // ---- // test1() -> true -// gas irOptimized: 204782 +// gas irOptimized: 218452 // gas legacy: 242256 -// gas legacyOptimized: 241192 +// gas legacyOptimized: 241182 diff --git a/test/libsolidity/semanticTests/array/dynamic_array_cleanup.sol b/test/libsolidity/semanticTests/array/dynamic_array_cleanup.sol index eb950d1834c2..380e30242536 100644 --- a/test/libsolidity/semanticTests/array/dynamic_array_cleanup.sol +++ b/test/libsolidity/semanticTests/array/dynamic_array_cleanup.sol @@ -14,7 +14,7 @@ contract c { // ---- // storageEmpty -> 1 // fill() -> -// gas irOptimized: 519017 +// gas irOptimized: 519494 // gas legacy: 518936 // gas legacyOptimized: 515555 // 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 2f6769a24189..62b611a878e5 100644 --- a/test/libsolidity/semanticTests/array/dynamic_arrays_in_storage.sol +++ b/test/libsolidity/semanticTests/array/dynamic_arrays_in_storage.sol @@ -41,7 +41,7 @@ contract c { // ---- // getLengths() -> 0, 0 // setLengths(uint256,uint256): 48, 49 -> -// gas irOptimized: 110797 +// gas irOptimized: 112674 // gas legacy: 108273 // gas legacyOptimized: 100269 // 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 7621d05bdcfd..2db14a939e5a 100644 --- a/test/libsolidity/semanticTests/array/dynamic_multi_array_cleanup.sol +++ b/test/libsolidity/semanticTests/array/dynamic_multi_array_cleanup.sol @@ -16,7 +16,7 @@ contract c { // ---- // storageEmpty -> 1 // fill() -> 8 -// gas irOptimized: 122742 +// gas irOptimized: 122985 // gas legacy: 121602 // gas legacyOptimized: 120589 // storageEmpty -> 0 diff --git a/test/libsolidity/semanticTests/array/fixed_array_cleanup.sol b/test/libsolidity/semanticTests/array/fixed_array_cleanup.sol index b4d9a30ec068..cc009b7e9e6b 100644 --- a/test/libsolidity/semanticTests/array/fixed_array_cleanup.sol +++ b/test/libsolidity/semanticTests/array/fixed_array_cleanup.sol @@ -10,7 +10,7 @@ contract c { // ---- // storageEmpty -> 1 // fill() -> -// gas irOptimized: 464834 +// gas irOptimized: 465013 // gas legacy: 468818 // gas legacyOptimized: 466238 // 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 0fb513543bea..e4bf3a7197e7 100644 --- a/test/libsolidity/semanticTests/array/fixed_arrays_as_return_type.sol +++ b/test/libsolidity/semanticTests/array/fixed_arrays_as_return_type.sol @@ -18,9 +18,9 @@ contract B { } // ---- // f() -> 2, 3, 4, 5, 6, 1000, 1001, 1002, 1003, 1004 -// gas irOptimized: 59204 -// gas irOptimized code: 55200 +// gas irOptimized: 59212 +// gas irOptimized code: 56600 // gas legacy: 68001 // gas legacy code: 162000 -// gas legacyOptimized: 60037 +// gas legacyOptimized: 59997 // gas legacyOptimized code: 70600 diff --git a/test/libsolidity/semanticTests/array/fixed_arrays_in_constructors.sol b/test/libsolidity/semanticTests/array/fixed_arrays_in_constructors.sol index 0eb0f1e90e7d..817d06c0f5a6 100644 --- a/test/libsolidity/semanticTests/array/fixed_arrays_in_constructors.sol +++ b/test/libsolidity/semanticTests/array/fixed_arrays_in_constructors.sol @@ -9,7 +9,7 @@ contract Creator { } // ---- // constructor(): 1, 2, 3, 4 -> -// gas irOptimized: 103927 +// gas irOptimized: 104102 // gas irOptimized code: 22400 // gas legacy: 115186 // gas legacy code: 59000 diff --git a/test/libsolidity/semanticTests/array/function_array_cross_calls.sol b/test/libsolidity/semanticTests/array/function_array_cross_calls.sol index e35e24bbf12a..e9517c0e38a1 100644 --- a/test/libsolidity/semanticTests/array/function_array_cross_calls.sol +++ b/test/libsolidity/semanticTests/array/function_array_cross_calls.sol @@ -42,9 +42,9 @@ contract C { } // ---- // test() -> 5, 6, 7 -// gas irOptimized: 86128 -// gas irOptimized code: 169600 +// gas irOptimized: 86484 +// gas irOptimized code: 161200 // gas legacy: 97576 // gas legacy code: 342800 -// gas legacyOptimized: 87851 -// gas legacyOptimized code: 190800 +// gas legacyOptimized: 87811 +// gas legacyOptimized code: 193000 diff --git a/test/libsolidity/semanticTests/array/invalid_encoding_for_storage_byte_array.sol b/test/libsolidity/semanticTests/array/invalid_encoding_for_storage_byte_array.sol index ddf67aa90fbf..5fd53c6d1299 100644 --- a/test/libsolidity/semanticTests/array/invalid_encoding_for_storage_byte_array.sol +++ b/test/libsolidity/semanticTests/array/invalid_encoding_for_storage_byte_array.sol @@ -40,9 +40,9 @@ contract C { // copyFromStorageShort() // x() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000 // copyFromStorageLong() -// gas irOptimized: 121106 +// gas irOptimized: 121104 // gas legacy: 121904 -// gas legacyOptimized: 121398 +// gas legacyOptimized: 121388 // x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000 // copyToStorage() // x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000 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 a08d27ac0b38..be1916ef131f 100644 --- a/test/libsolidity/semanticTests/array/pop/array_pop_array_transition.sol +++ b/test/libsolidity/semanticTests/array/pop/array_pop_array_transition.sol @@ -23,7 +23,7 @@ contract c { } // ---- // test() -> 1, 2, 3 -// gas irOptimized: 1827730 +// gas irOptimized: 1828226 // gas legacy: 1822466 // gas legacyOptimized: 1813404 // 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 1b69ab336bc7..73870d4285a0 100644 --- a/test/libsolidity/semanticTests/array/pop/array_pop_uint16_transition.sol +++ b/test/libsolidity/semanticTests/array/pop/array_pop_uint16_transition.sol @@ -18,7 +18,7 @@ contract c { } // ---- // test() -> 38, 28, 18 -// gas irOptimized: 148538 +// gas irOptimized: 148380 // gas legacy: 151184 // gas legacyOptimized: 142418 // 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 d2e5995c0070..e0fc1658154f 100644 --- a/test/libsolidity/semanticTests/array/pop/array_pop_uint24_transition.sol +++ b/test/libsolidity/semanticTests/array/pop/array_pop_uint24_transition.sol @@ -18,7 +18,7 @@ contract c { } // ---- // test() -> 20, 10 -// gas irOptimized: 126068 +// gas irOptimized: 125889 // gas legacy: 127216 // gas legacyOptimized: 122224 // storageEmpty -> 1 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 a3ba9d4d2111..c567c4509eaf 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 @@ -16,7 +16,7 @@ contract c { } // ---- // test() -> true -// gas irOptimized: 140154 +// gas irOptimized: 138848 // gas legacy: 178397 // gas legacyOptimized: 163832 // 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 a014e761ea24..d9d2d9d2d94e 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 @@ -15,7 +15,7 @@ contract c { } // ---- // test() -> -// gas irOptimized: 113782 +// gas irOptimized: 113679 // gas legacy: 131245 // gas legacyOptimized: 126668 // 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 674b0841e6b4..490de759b550 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 @@ -9,6 +9,6 @@ contract c { } // ---- // test() -> 0x20, 33, 0x303030303030303030303030303030303030303030303030303030303030303, 0x0300000000000000000000000000000000000000000000000000000000000000 -// gas irOptimized: 107183 +// gas irOptimized: 106778 // gas legacy: 121245 // gas legacyOptimized: 120370 diff --git a/test/libsolidity/semanticTests/array/push/array_push.sol b/test/libsolidity/semanticTests/array/push/array_push.sol index 3e7ceb5a8b7d..6198ba163595 100644 --- a/test/libsolidity/semanticTests/array/push/array_push.sol +++ b/test/libsolidity/semanticTests/array/push/array_push.sol @@ -16,6 +16,6 @@ contract c { } // ---- // test() -> 5, 4, 3, 3 -// gas irOptimized: 111363 +// gas irOptimized: 111834 // gas legacy: 111807 // gas legacyOptimized: 111122 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 a010a9938ac7..4bcac0f13829 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 @@ -12,6 +12,6 @@ contract C { } // ---- // f(uint120[]): 0x20, 3, 1, 2, 3 -> 1 -// gas irOptimized: 112812 +// gas irOptimized: 112853 // gas legacy: 113659 -// gas legacyOptimized: 113482 +// gas legacyOptimized: 113466 diff --git a/test/libsolidity/semanticTests/array/push/array_push_struct.sol b/test/libsolidity/semanticTests/array/push/array_push_struct.sol index 06c5db88b73c..b6db507ea385 100644 --- a/test/libsolidity/semanticTests/array/push/array_push_struct.sol +++ b/test/libsolidity/semanticTests/array/push/array_push_struct.sol @@ -20,6 +20,6 @@ contract c { } // ---- // test() -> 2, 3, 4, 5 -// gas irOptimized: 135103 +// gas irOptimized: 135329 // gas legacy: 147443 // gas legacyOptimized: 146434 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 4a33f816d773..37de90cb695a 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 @@ -16,6 +16,6 @@ contract c { } // ---- // 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: 137061 +// gas irOptimized: 137153 // gas legacy: 142423 -// gas legacyOptimized: 137991 +// gas legacyOptimized: 137981 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 5f1fe0fac770..763cb9a040e1 100644 --- a/test/libsolidity/semanticTests/array/push/byte_array_push_transition.sol +++ b/test/libsolidity/semanticTests/array/push/byte_array_push_transition.sol @@ -15,6 +15,6 @@ contract c { } // ---- // test() -> 0 -// gas irOptimized: 167700 +// gas irOptimized: 167569 // gas legacy: 206219 // gas legacyOptimized: 197297 diff --git a/test/libsolidity/semanticTests/array/push/nested_bytes_push.sol b/test/libsolidity/semanticTests/array/push/nested_bytes_push.sol index 30ed47920d9c..aeaeb9ee72a2 100644 --- a/test/libsolidity/semanticTests/array/push/nested_bytes_push.sol +++ b/test/libsolidity/semanticTests/array/push/nested_bytes_push.sol @@ -13,6 +13,6 @@ contract C { } // ---- // f() -> -// gas irOptimized: 179112 +// gas irOptimized: 179534 // gas legacy: 181014 -// gas legacyOptimized: 180422 +// gas legacyOptimized: 180398 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 6901e32b8b54..00e454516330 100644 --- a/test/libsolidity/semanticTests/array/push/push_no_args_2d.sol +++ b/test/libsolidity/semanticTests/array/push/push_no_args_2d.sol @@ -27,14 +27,14 @@ contract C { // ---- // l() -> 0 // f(uint256,uint256): 42, 64 -> -// gas irOptimized: 112266 +// gas irOptimized: 112288 // gas legacy: 107920 // gas legacyOptimized: 101897 // l() -> 1 // ll(uint256): 0 -> 43 // a(uint256,uint256): 0, 42 -> 64 // f(uint256,uint256): 84, 128 -> -// gas irOptimized: 118686 +// gas irOptimized: 118708 // gas legacy: 109972 // 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 b19ebcc7367f..b013a7ebbcf1 100644 --- a/test/libsolidity/semanticTests/array/push/push_no_args_bytes.sol +++ b/test/libsolidity/semanticTests/array/push/push_no_args_bytes.sol @@ -21,7 +21,7 @@ contract C { // ---- // l() -> 0 // g(uint256): 70 -> -// gas irOptimized: 180849 +// gas irOptimized: 181778 // gas legacy: 175185 // gas legacyOptimized: 175005 // l() -> 70 diff --git a/test/libsolidity/semanticTests/array/reusing_memory.sol b/test/libsolidity/semanticTests/array/reusing_memory.sol index a7608f6e0c81..621860c075c8 100644 --- a/test/libsolidity/semanticTests/array/reusing_memory.sol +++ b/test/libsolidity/semanticTests/array/reusing_memory.sol @@ -24,7 +24,7 @@ contract Main { } // ---- // f(uint256): 0x34 -> 0x46bddb1178e94d7f2892ff5f366840eb658911794f2c3a44c450aa2c505186c1 -// gas irOptimized: 99524 +// gas irOptimized: 99552 // gas irOptimized code: 12400 // gas legacy: 101554 // gas legacy code: 23600 diff --git a/test/libsolidity/semanticTests/byte_array_to_storage_cleanup.sol b/test/libsolidity/semanticTests/byte_array_to_storage_cleanup.sol index 8d0cb0a01294..dab01b5983c6 100644 --- a/test/libsolidity/semanticTests/byte_array_to_storage_cleanup.sol +++ b/test/libsolidity/semanticTests/byte_array_to_storage_cleanup.sol @@ -28,12 +28,12 @@ contract C { // compileViaYul: also // ---- // constructor() -> -// gas irOptimized: 81932 -// gas irOptimized code: 355200 +// gas irOptimized: 82100 +// gas irOptimized code: 357600 // gas legacy: 101472 // gas legacy code: 604200 -// gas legacyOptimized: 85004 -// gas legacyOptimized code: 392400 +// gas legacyOptimized: 84956 +// gas legacyOptimized code: 391800 // h() -> 0x20, 0x40, 0x00, 0 // ~ emit ev(uint256[],uint256): 0x40, 0x21, 0x02, 0x00, 0x00 // g() -> 0x20, 0x40, 0, 0x00 diff --git a/test/libsolidity/semanticTests/calldata/copy_from_calldata_removes_bytes_data.sol b/test/libsolidity/semanticTests/calldata/copy_from_calldata_removes_bytes_data.sol index aedf5ada4f57..09dcd034796d 100644 --- a/test/libsolidity/semanticTests/calldata/copy_from_calldata_removes_bytes_data.sol +++ b/test/libsolidity/semanticTests/calldata/copy_from_calldata_removes_bytes_data.sol @@ -9,7 +9,7 @@ contract c { // EVMVersion: >=byzantium // ---- // (): 1, 2, 3, 4, 5 -> -// gas irOptimized: 155130 +// gas irOptimized: 155125 // gas legacy: 155473 // gas legacyOptimized: 155295 // checkIfDataIsEmpty() -> false diff --git a/test/libsolidity/semanticTests/constructor/arrays_in_constructors.sol b/test/libsolidity/semanticTests/constructor/arrays_in_constructors.sol index 3e60ba451c8c..685b1a93890c 100644 --- a/test/libsolidity/semanticTests/constructor/arrays_in_constructors.sol +++ b/test/libsolidity/semanticTests/constructor/arrays_in_constructors.sol @@ -24,9 +24,9 @@ contract Creator { } // ---- // f(uint256,address[]): 7, 0x40, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 -> 7, 8 -// gas irOptimized: 328126 -// gas irOptimized code: 96400 +// gas irOptimized: 327784 +// gas irOptimized code: 94000 // gas legacy: 336626 // gas legacy code: 244800 -// gas legacyOptimized: 329599 -// gas legacyOptimized code: 115000 +// gas legacyOptimized: 329518 +// gas legacyOptimized code: 117000 diff --git a/test/libsolidity/semanticTests/constructor/bytes_in_constructors_packer.sol b/test/libsolidity/semanticTests/constructor/bytes_in_constructors_packer.sol index c0b9df16c34d..0310d58d7a93 100644 --- a/test/libsolidity/semanticTests/constructor/bytes_in_constructors_packer.sol +++ b/test/libsolidity/semanticTests/constructor/bytes_in_constructors_packer.sol @@ -24,9 +24,9 @@ contract Creator { } // ---- // f(uint256,bytes): 7, 0x40, 78, "abcdefghijklmnopqrstuvwxyzabcdef", "ghijklmnopqrstuvwxyzabcdefghijkl", "mnopqrstuvwxyz" -> 7, "h" -// gas irOptimized: 169361 -// gas irOptimized code: 99200 +// gas irOptimized: 169292 +// gas irOptimized code: 99600 // gas legacy: 172944 // gas legacy code: 239800 -// gas legacyOptimized: 169858 -// gas legacyOptimized code: 117000 +// gas legacyOptimized: 169818 +// gas legacyOptimized code: 118600 diff --git a/test/libsolidity/semanticTests/constructor/bytes_in_constructors_unpacker.sol b/test/libsolidity/semanticTests/constructor/bytes_in_constructors_unpacker.sol index 0918a970e272..4194e14a69c0 100644 --- a/test/libsolidity/semanticTests/constructor/bytes_in_constructors_unpacker.sol +++ b/test/libsolidity/semanticTests/constructor/bytes_in_constructors_unpacker.sol @@ -8,11 +8,11 @@ contract Test { } // ---- // constructor(): 7, 0x40, 78, "abcdefghijklmnopqrstuvwxyzabcdef", "ghijklmnopqrstuvwxyzabcdefghijkl", "mnopqrstuvwxyz" -> -// gas irOptimized: 180756 -// gas irOptimized code: 79200 +// gas irOptimized: 181465 +// gas irOptimized code: 78400 // gas legacy: 195165 // gas legacy code: 109400 -// gas legacyOptimized: 181600 +// gas legacyOptimized: 181609 // gas legacyOptimized code: 71400 // m_x() -> 7 // m_s() -> 0x20, 78, "abcdefghijklmnopqrstuvwxyzabcdef", "ghijklmnopqrstuvwxyzabcdefghijkl", "mnopqrstuvwxyz" diff --git a/test/libsolidity/semanticTests/constructor/constructor_static_array_argument.sol b/test/libsolidity/semanticTests/constructor/constructor_static_array_argument.sol index e6ce445ada39..327c41d9be81 100644 --- a/test/libsolidity/semanticTests/constructor/constructor_static_array_argument.sol +++ b/test/libsolidity/semanticTests/constructor/constructor_static_array_argument.sol @@ -9,11 +9,11 @@ contract C { } // ---- // constructor(): 1, 2, 3, 4 -> -// gas irOptimized: 147975 +// gas irOptimized: 148129 // gas irOptimized code: 23000 // gas legacy: 157978 // gas legacy code: 60400 -// gas legacyOptimized: 150011 +// gas legacyOptimized: 149974 // gas legacyOptimized code: 26200 // a() -> 1 // b(uint256): 0 -> 2 diff --git a/test/libsolidity/semanticTests/constructor/no_callvalue_check.sol b/test/libsolidity/semanticTests/constructor/no_callvalue_check.sol index b1dc80a408d8..583f1ca37b3f 100644 --- a/test/libsolidity/semanticTests/constructor/no_callvalue_check.sol +++ b/test/libsolidity/semanticTests/constructor/no_callvalue_check.sol @@ -17,7 +17,7 @@ contract C { } // ---- // f(), 2000 ether -> true -// gas irOptimized: 117641 +// gas irOptimized: 117623 // gas irOptimized code: 1800 // gas legacy: 117821 // gas legacy code: 4800 diff --git a/test/libsolidity/semanticTests/events/event_dynamic_array_storage.sol b/test/libsolidity/semanticTests/events/event_dynamic_array_storage.sol index fec281c59a01..76acd4a0b23f 100644 --- a/test/libsolidity/semanticTests/events/event_dynamic_array_storage.sol +++ b/test/libsolidity/semanticTests/events/event_dynamic_array_storage.sol @@ -13,6 +13,6 @@ contract C { // ---- // createEvent(uint256): 42 -> // ~ emit E(uint256[]): 0x20, 0x03, 0x2a, 0x2b, 0x2c -// gas irOptimized: 113485 +// gas irOptimized: 114231 // gas legacy: 116314 -// gas legacyOptimized: 114407 +// gas legacyOptimized: 114408 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 2b5a7114d99b..bdcda3a09370 100644 --- a/test/libsolidity/semanticTests/events/event_dynamic_array_storage_v2.sol +++ b/test/libsolidity/semanticTests/events/event_dynamic_array_storage_v2.sol @@ -14,6 +14,6 @@ contract C { // ---- // createEvent(uint256): 42 -> // ~ emit E(uint256[]): 0x20, 0x03, 0x2a, 0x2b, 0x2c -// gas irOptimized: 113485 +// gas irOptimized: 114231 // gas legacy: 116314 -// gas legacyOptimized: 114407 +// gas legacyOptimized: 114408 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 d6cfb68beff9..324f456f6794 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 @@ -15,6 +15,6 @@ contract C { // ---- // createEvent(uint256): 42 -> // ~ emit E(uint256[][]): 0x20, 0x02, 0x40, 0xa0, 0x02, 0x2a, 0x2b, 0x02, 0x2c, 0x2d -// gas irOptimized: 185033 +// gas irOptimized: 185148 // gas legacy: 187495 -// gas legacyOptimized: 184525 +// gas legacyOptimized: 184550 diff --git a/test/libsolidity/semanticTests/events/event_indexed_string.sol b/test/libsolidity/semanticTests/events/event_indexed_string.sol index 739619066a43..0ad2affe377a 100644 --- a/test/libsolidity/semanticTests/events/event_indexed_string.sol +++ b/test/libsolidity/semanticTests/events/event_indexed_string.sol @@ -17,6 +17,6 @@ contract C { // ---- // deposit() -> // ~ emit E(string,uint256[4]): #0xa7fb06bb999a5eb9aff9e0779953f4e1e4ce58044936c2f51c7fb879b85c08bd, #0xe755d8cc1a8cde16a2a31160dcd8017ac32d7e2f13215b29a23cdae40a78aa81 -// gas irOptimized: 328856 +// gas irOptimized: 332789 // gas legacy: 365828 -// gas legacyOptimized: 362251 +// gas legacyOptimized: 362250 diff --git a/test/libsolidity/semanticTests/externalContracts/FixedFeeRegistrar.sol b/test/libsolidity/semanticTests/externalContracts/FixedFeeRegistrar.sol index 925ed54e6dc3..47feaf5258bb 100644 --- a/test/libsolidity/semanticTests/externalContracts/FixedFeeRegistrar.sol +++ b/test/libsolidity/semanticTests/externalContracts/FixedFeeRegistrar.sol @@ -74,12 +74,12 @@ contract FixedFeeRegistrar is Registrar { } // ---- // constructor() -// gas irOptimized: 77654 -// gas irOptimized code: 302200 +// gas irOptimized: 78076 +// gas irOptimized code: 307400 // gas legacy: 115395 // gas legacy code: 792400 -// gas legacyOptimized: 84566 -// gas legacyOptimized code: 387600 +// gas legacyOptimized: 84598 +// gas legacyOptimized code: 388000 // reserve(string), 69 ether: 0x20, 3, "abc" -> // ~ emit Changed(string): #0x4e03657aea45a94fc7d47ba826c8d667c0d1e6e33a64a036ec44f58fa12d6c45 // gas irOptimized: 45967 diff --git a/test/libsolidity/semanticTests/externalContracts/base64.sol b/test/libsolidity/semanticTests/externalContracts/base64.sol index aed2a11df22c..a986be149b50 100644 --- a/test/libsolidity/semanticTests/externalContracts/base64.sol +++ b/test/libsolidity/semanticTests/externalContracts/base64.sol @@ -33,11 +33,11 @@ contract test { // EVMVersion: >=constantinople // ---- // constructor() -// gas irOptimized: 78952 -// gas irOptimized code: 320600 +// gas irOptimized: 79076 +// gas irOptimized code: 322000 // gas legacy: 102034 // gas legacy code: 627400 -// gas legacyOptimized: 87950 +// gas legacyOptimized: 87926 // gas legacyOptimized code: 429800 // encode_inline_asm(bytes): 0x20, 0 -> 0x20, 0 // encode_inline_asm(bytes): 0x20, 1, "f" -> 0x20, 4, "Zg==" @@ -54,10 +54,10 @@ contract test { // encode_no_asm(bytes): 0x20, 5, "fooba" -> 0x20, 8, "Zm9vYmE=" // encode_no_asm(bytes): 0x20, 6, "foobar" -> 0x20, 8, "Zm9vYmFy" // encode_inline_asm_large() -// gas irOptimized: 1322025 +// gas irOptimized: 1406025 // gas legacy: 1554031 // gas legacyOptimized: 1132031 // encode_no_asm_large() -// gas irOptimized: 3206081 +// gas irOptimized: 3512081 // gas legacy: 4587075 -// gas legacyOptimized: 2823075 +// gas legacyOptimized: 2813075 diff --git a/test/libsolidity/semanticTests/externalContracts/deposit_contract.sol b/test/libsolidity/semanticTests/externalContracts/deposit_contract.sol index 5288d859b76f..9bfa3a340e5f 100644 --- a/test/libsolidity/semanticTests/externalContracts/deposit_contract.sol +++ b/test/libsolidity/semanticTests/externalContracts/deposit_contract.sol @@ -176,38 +176,38 @@ contract DepositContract is IDepositContract, ERC165 { } // ---- // constructor() -// gas irOptimized: 809628 -// gas irOptimized code: 563200 +// gas irOptimized: 809602 +// gas irOptimized code: 558000 // gas legacy: 919945 // gas legacy code: 1437600 -// gas legacyOptimized: 848464 -// gas legacyOptimized code: 875200 +// gas legacyOptimized: 848699 +// gas legacyOptimized code: 878200 // supportsInterface(bytes4): 0x0 -> 0 // supportsInterface(bytes4): 0xffffffff00000000000000000000000000000000000000000000000000000000 -> false # defined to be false by ERC-165 # // supportsInterface(bytes4): 0x01ffc9a700000000000000000000000000000000000000000000000000000000 -> true # ERC-165 id # // supportsInterface(bytes4): 0x8564090700000000000000000000000000000000000000000000000000000000 -> true # the deposit interface id # // get_deposit_root() -> 0xd70a234731285c6804c2a4f56711ddb8c82c99740f207854891028af34e27e5e -// gas irOptimized: 108921 +// gas irOptimized: 109178 // gas legacy: 142735 // gas legacyOptimized: 117558 // 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: 108921 +// gas irOptimized: 109178 // gas legacy: 142735 // gas legacyOptimized: 117558 // 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: 108914 +// gas irOptimized: 109174 // gas legacy: 142744 // gas legacyOptimized: 117570 // 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: 108914 +// gas irOptimized: 109174 // gas legacy: 142744 // gas legacyOptimized: 117570 // 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 ddd63971836c..4990d24e9a7e 100644 --- a/test/libsolidity/semanticTests/externalContracts/prbmath_signed.sol +++ b/test/libsolidity/semanticTests/externalContracts/prbmath_signed.sol @@ -48,8 +48,8 @@ contract test { } // ---- // constructor() -// gas irOptimized: 177336 -// gas irOptimized code: 1664400 +// gas irOptimized: 177903 +// gas irOptimized code: 1674400 // gas legacy: 209687 // gas legacy code: 2204400 // gas legacyOptimized: 178012 diff --git a/test/libsolidity/semanticTests/externalContracts/prbmath_unsigned.sol b/test/libsolidity/semanticTests/externalContracts/prbmath_unsigned.sol index deacfd05641b..5d95c7a75c84 100644 --- a/test/libsolidity/semanticTests/externalContracts/prbmath_unsigned.sol +++ b/test/libsolidity/semanticTests/externalContracts/prbmath_unsigned.sol @@ -48,8 +48,8 @@ contract test { } // ---- // constructor() -// gas irOptimized: 168523 -// gas irOptimized code: 1547800 +// gas irOptimized: 170626 +// gas irOptimized code: 1577400 // gas legacy: 195146 // gas legacy code: 1998400 // gas legacyOptimized: 168857 diff --git a/test/libsolidity/semanticTests/externalContracts/ramanujan_pi.sol b/test/libsolidity/semanticTests/externalContracts/ramanujan_pi.sol index cdaec8797eb7..1aa72b897b97 100644 --- a/test/libsolidity/semanticTests/externalContracts/ramanujan_pi.sol +++ b/test/libsolidity/semanticTests/externalContracts/ramanujan_pi.sol @@ -33,8 +33,8 @@ contract test { } // ---- // constructor() -// gas irOptimized: 79503 -// gas irOptimized code: 328000 +// gas irOptimized: 77816 +// gas irOptimized code: 307600 // gas legacy: 92086 // gas legacy code: 523000 // gas legacyOptimized: 82667 diff --git a/test/libsolidity/semanticTests/externalContracts/snark.sol b/test/libsolidity/semanticTests/externalContracts/snark.sol index 58f5e58048c9..97d15183a19b 100644 --- a/test/libsolidity/semanticTests/externalContracts/snark.sol +++ b/test/libsolidity/semanticTests/externalContracts/snark.sol @@ -294,11 +294,11 @@ contract Test { // f() -> true // g() -> true // pair() -> true -// gas irOptimized: 269701 +// gas irOptimized: 270424 // gas legacy: 275206 // gas legacyOptimized: 266925 // verifyTx() -> true // ~ emit Verified(string): 0x20, 0x16, "Successfully verified." -// gas irOptimized: 782238 +// gas irOptimized: 785783 // gas legacy: 801868 // gas legacyOptimized: 770942 diff --git a/test/libsolidity/semanticTests/externalContracts/strings.sol b/test/libsolidity/semanticTests/externalContracts/strings.sol index 102c85ae0fa8..773d7156afa3 100644 --- a/test/libsolidity/semanticTests/externalContracts/strings.sol +++ b/test/libsolidity/semanticTests/externalContracts/strings.sol @@ -49,12 +49,12 @@ contract test { } // ---- // constructor() -// gas irOptimized: 95949 -// gas irOptimized code: 528000 +// gas irOptimized: 95303 +// gas irOptimized code: 520000 // gas legacy: 126106 // gas legacy code: 930200 -// gas legacyOptimized: 102559 -// gas legacyOptimized code: 611400 +// gas legacyOptimized: 102639 +// gas legacyOptimized code: 612400 // toSlice(string): 0x20, 11, "hello world" -> 11, 0xa0 // gas irOptimized: 22660 // gas legacy: 23190 @@ -72,6 +72,6 @@ contract test { // gas legacy: 31621 // gas legacyOptimized: 27914 // benchmark(string,bytes32): 0x40, 0x0842021, 8, "solidity" -> 0x2020 -// gas irOptimized: 1980944 +// gas irOptimized: 1976778 // gas legacy: 4233999 -// gas legacyOptimized: 2318684 +// gas legacyOptimized: 2318670 diff --git a/test/libsolidity/semanticTests/functionCall/creation_function_call_with_args.sol b/test/libsolidity/semanticTests/functionCall/creation_function_call_with_args.sol index 1133dc2be300..f7c05c10c4d6 100644 --- a/test/libsolidity/semanticTests/functionCall/creation_function_call_with_args.sol +++ b/test/libsolidity/semanticTests/functionCall/creation_function_call_with_args.sol @@ -15,7 +15,7 @@ contract D { } // ---- // constructor(): 2 -> -// gas irOptimized: 138863 +// gas irOptimized: 138930 // gas irOptimized code: 53800 // gas legacy: 145570 // gas legacy code: 95600 diff --git a/test/libsolidity/semanticTests/functionCall/creation_function_call_with_salt.sol b/test/libsolidity/semanticTests/functionCall/creation_function_call_with_salt.sol index ba90a8ecd5a6..9742a1d2f373 100644 --- a/test/libsolidity/semanticTests/functionCall/creation_function_call_with_salt.sol +++ b/test/libsolidity/semanticTests/functionCall/creation_function_call_with_salt.sol @@ -17,7 +17,7 @@ contract D { // EVMVersion: >=constantinople // ---- // constructor(): 2 -> -// gas irOptimized: 139026 +// gas irOptimized: 139112 // gas irOptimized code: 53800 // gas legacy: 145936 // gas legacy code: 95600 diff --git a/test/libsolidity/semanticTests/functionCall/external_call_to_nonexisting.sol b/test/libsolidity/semanticTests/functionCall/external_call_to_nonexisting.sol index 5b254a9f6c2d..87f7cbebb0d5 100644 --- a/test/libsolidity/semanticTests/functionCall/external_call_to_nonexisting.sol +++ b/test/libsolidity/semanticTests/functionCall/external_call_to_nonexisting.sol @@ -22,12 +22,12 @@ contract C { } // ---- // constructor(), 1 ether -> -// gas irOptimized: 89155 -// gas irOptimized code: 167800 +// gas irOptimized: 88853 +// gas irOptimized code: 164400 // gas legacy: 102626 // gas legacy code: 333200 -// gas legacyOptimized: 91471 -// gas legacyOptimized code: 196200 +// gas legacyOptimized: 91599 +// gas legacyOptimized code: 197800 // f(uint256): 0 -> FAILURE // f(uint256): 1 -> FAILURE // f(uint256): 2 -> FAILURE 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 8bf182a89ee8..9da010e9bc21 100644 --- a/test/libsolidity/semanticTests/functionCall/external_call_to_nonexisting_debugstrings.sol +++ b/test/libsolidity/semanticTests/functionCall/external_call_to_nonexisting_debugstrings.sol @@ -25,12 +25,12 @@ contract C { // revertStrings: debug // ---- // constructor(), 1 ether -> -// gas irOptimized: 98842 -// gas irOptimized code: 286000 +// gas irOptimized: 98698 +// gas irOptimized code: 284200 // gas legacy: 123163 // gas legacy code: 681200 -// gas legacyOptimized: 106957 -// gas legacyOptimized code: 386400 +// gas legacyOptimized: 107069 +// gas legacyOptimized code: 387800 // 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" diff --git a/test/libsolidity/semanticTests/functionCall/gas_and_value_basic.sol b/test/libsolidity/semanticTests/functionCall/gas_and_value_basic.sol index 2f8f62586bd5..bf6f2c4baf4d 100644 --- a/test/libsolidity/semanticTests/functionCall/gas_and_value_basic.sol +++ b/test/libsolidity/semanticTests/functionCall/gas_and_value_basic.sol @@ -38,8 +38,8 @@ contract test { } // ---- // constructor(), 20 wei -> -// gas irOptimized: 120912 -// gas irOptimized code: 140000 +// gas irOptimized: 120218 +// gas irOptimized code: 132000 // gas legacy: 130568 // gas legacy code: 261000 // gas legacyOptimized: 121069 diff --git a/test/libsolidity/semanticTests/functionCall/gas_and_value_brace_syntax.sol b/test/libsolidity/semanticTests/functionCall/gas_and_value_brace_syntax.sol index 4821146e7eca..ebc78a437f69 100644 --- a/test/libsolidity/semanticTests/functionCall/gas_and_value_brace_syntax.sol +++ b/test/libsolidity/semanticTests/functionCall/gas_and_value_brace_syntax.sol @@ -37,8 +37,8 @@ contract test { } // ---- // constructor(), 20 wei -> -// gas irOptimized: 120912 -// gas irOptimized code: 140000 +// gas irOptimized: 120218 +// gas irOptimized code: 132000 // gas legacy: 130568 // gas legacy code: 261000 // gas legacyOptimized: 121069 diff --git a/test/libsolidity/semanticTests/functionCall/mapping_array_internal_argument.sol b/test/libsolidity/semanticTests/functionCall/mapping_array_internal_argument.sol index 28c1822d77b7..7a9bf6014bad 100644 --- a/test/libsolidity/semanticTests/functionCall/mapping_array_internal_argument.sol +++ b/test/libsolidity/semanticTests/functionCall/mapping_array_internal_argument.sol @@ -18,7 +18,7 @@ contract test { } // ---- // set(uint8,uint8,uint8,uint8,uint8): 1, 21, 22, 42, 43 -> 0, 0, 0, 0 -// gas irOptimized: 111628 +// gas irOptimized: 111237 // gas legacy: 113748 // gas legacyOptimized: 111772 // get(uint8): 1 -> 21, 22, 42, 43 diff --git a/test/libsolidity/semanticTests/immutable/multi_creation.sol b/test/libsolidity/semanticTests/immutable/multi_creation.sol index c8806c50d060..e1eb0621a611 100644 --- a/test/libsolidity/semanticTests/immutable/multi_creation.sol +++ b/test/libsolidity/semanticTests/immutable/multi_creation.sol @@ -27,7 +27,7 @@ contract C { } // ---- // f() -> 3, 7, 5 -// gas irOptimized: 86821 +// gas irOptimized: 86796 // gas irOptimized code: 37200 // gas legacy: 87728 // gas legacy code: 60800 diff --git a/test/libsolidity/semanticTests/immutable/use_scratch.sol b/test/libsolidity/semanticTests/immutable/use_scratch.sol index dc07086c29c3..2ee05af918c7 100644 --- a/test/libsolidity/semanticTests/immutable/use_scratch.sol +++ b/test/libsolidity/semanticTests/immutable/use_scratch.sol @@ -15,7 +15,7 @@ contract C { } // ---- // constructor(): 3 -> -// gas irOptimized: 81126 +// gas irOptimized: 81194 // gas irOptimized code: 42400 // gas legacy: 88245 // gas legacy code: 109400 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 d5ff54b68a16..5234c27adf12 100644 --- a/test/libsolidity/semanticTests/inheritance/inherited_function_calldata_memory_interface.sol +++ b/test/libsolidity/semanticTests/inheritance/inherited_function_calldata_memory_interface.sol @@ -25,5 +25,5 @@ contract B { // gas irOptimized: 100282 // gas legacy: 56840 // gas legacy code: 123600 -// gas legacyOptimized: 54996 -// gas legacyOptimized code: 57600 +// gas legacyOptimized: 55002 +// gas legacyOptimized code: 60600 diff --git a/test/libsolidity/semanticTests/inlineAssembly/transient_storage_selfdestruct.sol b/test/libsolidity/semanticTests/inlineAssembly/transient_storage_selfdestruct.sol index f4975cd4c790..a375207252dc 100644 --- a/test/libsolidity/semanticTests/inlineAssembly/transient_storage_selfdestruct.sol +++ b/test/libsolidity/semanticTests/inlineAssembly/transient_storage_selfdestruct.sol @@ -40,8 +40,8 @@ contract D { // EVMVersion: >=cancun // ---- // constructor() -> -// gas irOptimized: 127944 -// gas irOptimized code: 225200 +// gas irOptimized: 127596 +// gas irOptimized code: 221000 // gas legacy: 149357 // gas legacy code: 499800 // gas legacyOptimized: 125830 diff --git a/test/libsolidity/semanticTests/isoltestTesting/balance_other_contract.sol b/test/libsolidity/semanticTests/isoltestTesting/balance_other_contract.sol index 0ad55b5ddff1..8ec19fffa573 100644 --- a/test/libsolidity/semanticTests/isoltestTesting/balance_other_contract.sol +++ b/test/libsolidity/semanticTests/isoltestTesting/balance_other_contract.sol @@ -16,8 +16,8 @@ contract ClientReceipt { } // ---- // constructor(), 2000 wei -> -// gas irOptimized: 114107 -// gas irOptimized code: 55800 +// gas irOptimized: 114353 +// gas irOptimized code: 58800 // gas legacy: 118618 // gas legacy code: 111400 // gas legacyOptimized: 114067 diff --git a/test/libsolidity/semanticTests/libraries/internal_types_in_library.sol b/test/libsolidity/semanticTests/libraries/internal_types_in_library.sol index bdf4e4c30a6a..817118473107 100644 --- a/test/libsolidity/semanticTests/libraries/internal_types_in_library.sol +++ b/test/libsolidity/semanticTests/libraries/internal_types_in_library.sol @@ -22,6 +22,6 @@ contract Test { // ---- // library: Lib // f() -> 4, 0x11 -// gas irOptimized: 111629 +// gas irOptimized: 111419 // gas legacy: 132935 // gas legacyOptimized: 118023 diff --git a/test/libsolidity/semanticTests/libraries/using_library_mappings_public.sol b/test/libsolidity/semanticTests/libraries/using_library_mappings_public.sol index b3e06c5bcfb8..bbdc920471bc 100644 --- a/test/libsolidity/semanticTests/libraries/using_library_mappings_public.sol +++ b/test/libsolidity/semanticTests/libraries/using_library_mappings_public.sol @@ -19,6 +19,6 @@ contract Test { // ---- // library: Lib // f() -> 1, 0, 0x2a, 0x17, 0, 0x63 -// gas irOptimized: 119635 +// gas irOptimized: 119837 // gas legacy: 124674 // gas legacyOptimized: 119669 diff --git a/test/libsolidity/semanticTests/libraries/using_library_mappings_return.sol b/test/libsolidity/semanticTests/libraries/using_library_mappings_return.sol index e9d855969afd..98cdf4fd18cd 100644 --- a/test/libsolidity/semanticTests/libraries/using_library_mappings_return.sol +++ b/test/libsolidity/semanticTests/libraries/using_library_mappings_return.sol @@ -17,6 +17,6 @@ contract Test { // ---- // library: Lib // f() -> 1, 0, 0x2a, 0x17, 0, 0x63 -// gas irOptimized: 120194 +// gas irOptimized: 119568 // gas legacy: 125109 // gas legacyOptimized: 120128 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 735731c8abf7..083c9a5e4838 100644 --- a/test/libsolidity/semanticTests/salted_create/salted_create_with_value.sol +++ b/test/libsolidity/semanticTests/salted_create/salted_create_with_value.sol @@ -21,8 +21,8 @@ contract A { // EVMVersion: >=constantinople // ---- // f(), 10 ether -> 3007, 3008, 3009 -// gas irOptimized: 187005 -// gas irOptimized code: 66000 +// gas irOptimized: 187022 +// gas irOptimized code: 67200 // gas legacy: 190863 // gas legacy code: 190200 // gas legacyOptimized: 187258 diff --git a/test/libsolidity/semanticTests/storage/empty_nonempty_empty.sol b/test/libsolidity/semanticTests/storage/empty_nonempty_empty.sol index 5f32421657cd..0c2f54b9e759 100644 --- a/test/libsolidity/semanticTests/storage/empty_nonempty_empty.sol +++ b/test/libsolidity/semanticTests/storage/empty_nonempty_empty.sol @@ -22,9 +22,9 @@ contract Test { // set(bytes): 0x20, 0 // storageEmpty -> 1 // set(bytes): 0x20, 66, "12345678901234567890123456789012", "12345678901234567890123456789012", "12" -// gas irOptimized: 111886 +// gas irOptimized: 111852 // gas legacy: 112734 -// gas legacyOptimized: 112115 +// gas legacyOptimized: 112084 // storageEmpty -> 0 // set(bytes): 0x20, 3, "abc" // storageEmpty -> 0 diff --git a/test/libsolidity/semanticTests/storage/packed_storage_structs_bytes.sol b/test/libsolidity/semanticTests/storage/packed_storage_structs_bytes.sol index 2c29abc79bb0..75edb1c9e0fe 100644 --- a/test/libsolidity/semanticTests/storage/packed_storage_structs_bytes.sol +++ b/test/libsolidity/semanticTests/storage/packed_storage_structs_bytes.sol @@ -42,6 +42,6 @@ contract C { } // ---- // test() -> true -// gas irOptimized: 132493 +// gas irOptimized: 132633 // gas legacy: 136009 // gas legacyOptimized: 133478 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 add42a8f3b18..ebf546fe2803 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 @@ -16,6 +16,6 @@ contract C { } // ---- // f(uint32,(uint128,uint256[][2],uint32)): 55, 0x40, 77, 0x60, 88, 0x40, 0x40, 2, 1, 2 -> 55, 77, 1, 2, 88 -// gas irOptimized: 202843 +// gas irOptimized: 202902 // gas legacy: 207384 -// gas legacyOptimized: 203584 +// gas legacyOptimized: 203588 diff --git a/test/libsolidity/semanticTests/structs/conversion/recursive_storage_memory.sol b/test/libsolidity/semanticTests/structs/conversion/recursive_storage_memory.sol index 699836179be2..4465b1a3eece 100644 --- a/test/libsolidity/semanticTests/structs/conversion/recursive_storage_memory.sol +++ b/test/libsolidity/semanticTests/structs/conversion/recursive_storage_memory.sol @@ -23,6 +23,6 @@ contract CopyTest { } // ---- // run() -> 2, 23, 42 -// gas irOptimized: 193677 +// gas irOptimized: 192828 // gas legacy: 185731 // gas legacyOptimized: 184458 diff --git a/test/libsolidity/semanticTests/structs/copy_from_mapping.sol b/test/libsolidity/semanticTests/structs/copy_from_mapping.sol index 8ee19a278a23..a072fb0576b7 100644 --- a/test/libsolidity/semanticTests/structs/copy_from_mapping.sol +++ b/test/libsolidity/semanticTests/structs/copy_from_mapping.sol @@ -36,8 +36,8 @@ contract C { } // ---- // to_state() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 -// gas irOptimized: 121394 +// gas irOptimized: 121282 // gas legacy: 122978 -// gas legacyOptimized: 121648 +// gas legacyOptimized: 121652 // to_storage() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 // to_memory() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 diff --git a/test/libsolidity/semanticTests/structs/copy_struct_array_from_storage.sol b/test/libsolidity/semanticTests/structs/copy_struct_array_from_storage.sol index 937eeeaf437e..29e7afca361a 100644 --- a/test/libsolidity/semanticTests/structs/copy_struct_array_from_storage.sol +++ b/test/libsolidity/semanticTests/structs/copy_struct_array_from_storage.sol @@ -87,7 +87,7 @@ contract Test { // EVMVersion: >homestead // ---- // test1() -> true -// gas irOptimized: 152882 +// gas irOptimized: 152965 // gas legacy: 153012 // gas legacyOptimized: 152637 // test2() -> true diff --git a/test/libsolidity/semanticTests/structs/copy_substructures_from_mapping.sol b/test/libsolidity/semanticTests/structs/copy_substructures_from_mapping.sol index 8091f5a241c0..61d2d68aada7 100644 --- a/test/libsolidity/semanticTests/structs/copy_substructures_from_mapping.sol +++ b/test/libsolidity/semanticTests/structs/copy_substructures_from_mapping.sol @@ -44,8 +44,8 @@ contract C { } // ---- // to_state() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 -// gas irOptimized: 121499 +// gas irOptimized: 121454 // gas legacy: 123117 -// gas legacyOptimized: 121655 +// gas legacyOptimized: 121659 // to_storage() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 // to_memory() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 diff --git a/test/libsolidity/semanticTests/structs/copy_substructures_to_mapping.sol b/test/libsolidity/semanticTests/structs/copy_substructures_to_mapping.sol index 2083032ff356..7d458ca29397 100644 --- a/test/libsolidity/semanticTests/structs/copy_substructures_to_mapping.sol +++ b/test/libsolidity/semanticTests/structs/copy_substructures_to_mapping.sol @@ -52,14 +52,14 @@ contract C { } // ---- // from_memory() -> 0x20, 0x60, 0xa0, 0x15, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 -// gas irOptimized: 122923 +// gas irOptimized: 122720 // gas legacy: 130136 -// gas legacyOptimized: 128650 +// gas legacyOptimized: 128649 // from_state() -> 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 -// gas irOptimized: 121616 +// gas irOptimized: 121424 // gas legacy: 123191 -// gas legacyOptimized: 121760 +// gas legacyOptimized: 121764 // from_calldata((bytes,uint16[],uint16)): 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 -> 0x20, 0x60, 0xa0, 0x15, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 -// gas irOptimized: 115037 +// gas irOptimized: 114852 // gas legacy: 122425 -// gas legacyOptimized: 120696 +// gas legacyOptimized: 120700 diff --git a/test/libsolidity/semanticTests/structs/copy_to_mapping.sol b/test/libsolidity/semanticTests/structs/copy_to_mapping.sol index c44277e4f198..068dc3d8c682 100644 --- a/test/libsolidity/semanticTests/structs/copy_to_mapping.sol +++ b/test/libsolidity/semanticTests/structs/copy_to_mapping.sol @@ -45,18 +45,18 @@ contract C { } // ---- // from_state() -> 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 -// gas irOptimized: 121593 +// gas irOptimized: 121515 // gas legacy: 123053 -// gas legacyOptimized: 121700 +// gas legacyOptimized: 121704 // from_storage() -> 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 -// gas irOptimized: 121638 +// gas irOptimized: 121559 // gas legacy: 123102 -// gas legacyOptimized: 121752 +// gas legacyOptimized: 121756 // from_memory() -> 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 -// gas irOptimized: 122831 +// gas irOptimized: 122740 // gas legacy: 129997 -// gas legacyOptimized: 128646 +// gas legacyOptimized: 128645 // from_calldata((bytes,uint16[],uint16)): 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 -> 0x20, 0x60, 0xa0, 21, 3, 0x666f6f0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 -// gas irOptimized: 114952 +// gas irOptimized: 114824 // gas legacy: 118210 -// gas legacyOptimized: 115324 +// gas legacyOptimized: 115329 diff --git a/test/libsolidity/semanticTests/structs/memory_structs_nested_load.sol b/test/libsolidity/semanticTests/structs/memory_structs_nested_load.sol index e5b139d5c3c7..5ba9765415d9 100644 --- a/test/libsolidity/semanticTests/structs/memory_structs_nested_load.sol +++ b/test/libsolidity/semanticTests/structs/memory_structs_nested_load.sol @@ -66,7 +66,7 @@ contract Test { } // ---- // load() -> 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 -// gas irOptimized: 110317 +// gas irOptimized: 110772 // gas legacy: 112964 // gas legacyOptimized: 110876 // 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 856edc27be48..955e082b72ae 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 @@ -23,17 +23,17 @@ contract c { // ---- // storageEmpty -> 1 // set(uint256,bytes,uint256): 12, 0x60, 13, 33, "12345678901234567890123456789012", "3" -> true -// gas irOptimized: 133592 +// gas irOptimized: 133560 // gas legacy: 134628 -// gas legacyOptimized: 133871 +// gas legacyOptimized: 133858 // test(uint256): 32 -> "3" // storageEmpty -> 0 // copy() -> true // storageEmpty -> 1 // set(uint256,bytes,uint256): 12, 0x60, 13, 33, "12345678901234567890123456789012", "3" -> true -// gas irOptimized: 133592 +// gas irOptimized: 133560 // gas legacy: 134628 -// gas legacyOptimized: 133871 +// gas legacyOptimized: 133858 // storageEmpty -> 0 // del() -> true // storageEmpty -> 1 diff --git a/test/libsolidity/semanticTests/structs/struct_copy.sol b/test/libsolidity/semanticTests/structs/struct_copy.sol index a321f0686897..1fb9ef2168f6 100644 --- a/test/libsolidity/semanticTests/structs/struct_copy.sol +++ b/test/libsolidity/semanticTests/structs/struct_copy.sol @@ -35,12 +35,12 @@ contract c { } // ---- // set(uint256): 7 -> true -// gas irOptimized: 109893 +// gas irOptimized: 109932 // gas legacy: 110597 // gas legacyOptimized: 110003 // retrieve(uint256): 7 -> 1, 3, 4, 2 // copy(uint256,uint256): 7, 8 -> true -// gas irOptimized: 118582 +// gas irOptimized: 118581 // gas legacy: 119147 // gas legacyOptimized: 118619 // 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 71b40acc80f6..6b8788d2c09d 100644 --- a/test/libsolidity/semanticTests/structs/struct_copy_via_local.sol +++ b/test/libsolidity/semanticTests/structs/struct_copy_via_local.sol @@ -17,6 +17,6 @@ contract c { } // ---- // test() -> true -// gas irOptimized: 109706 +// gas irOptimized: 109921 // gas legacy: 110615 // gas legacyOptimized: 109705 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 d76618bbc9fc..28998df448dd 100644 --- a/test/libsolidity/semanticTests/structs/struct_delete_storage_with_array.sol +++ b/test/libsolidity/semanticTests/structs/struct_delete_storage_with_array.sol @@ -42,10 +42,10 @@ contract C { } // ---- // f() -> -// gas irOptimized: 113210 +// gas irOptimized: 113477 // gas legacy: 113591 // gas legacyOptimized: 113103 // g() -> -// gas irOptimized: 118580 +// gas irOptimized: 118843 // gas legacy: 118764 // gas legacyOptimized: 118172 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 9af3774692a9..bd9fcf3e2303 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 @@ -28,6 +28,6 @@ contract C { } // ---- // f() -> 42, 23, 34, 42, 42 -// gas irOptimized: 110382 +// gas irOptimized: 110682 // gas legacy: 111993 // gas legacyOptimized: 110546 diff --git a/test/libsolidity/semanticTests/structs/structs.sol b/test/libsolidity/semanticTests/structs/structs.sol index b5e9d10bb844..190387051349 100644 --- a/test/libsolidity/semanticTests/structs/structs.sol +++ b/test/libsolidity/semanticTests/structs/structs.sol @@ -30,7 +30,7 @@ contract test { // ---- // check() -> false // set() -> -// gas irOptimized: 134417 +// gas irOptimized: 134073 // gas legacy: 135246 // gas legacyOptimized: 134062 // check() -> true diff --git a/test/libsolidity/semanticTests/types/mapping/copy_from_mapping_to_mapping.sol b/test/libsolidity/semanticTests/types/mapping/copy_from_mapping_to_mapping.sol index e1e1e3b2654d..19c31f288011 100644 --- a/test/libsolidity/semanticTests/types/mapping/copy_from_mapping_to_mapping.sol +++ b/test/libsolidity/semanticTests/types/mapping/copy_from_mapping_to_mapping.sol @@ -29,6 +29,6 @@ contract C { } // ---- // f() -> 0x20, 7, 8, 9, 0xa0, 13, 2, 0x40, 0xa0, 2, 3, 4, 2, 3, 4 -// gas irOptimized: 197116 +// gas irOptimized: 197102 // gas legacy: 199891 -// gas legacyOptimized: 196817 +// gas legacyOptimized: 196845 diff --git a/test/libsolidity/semanticTests/userDefinedValueType/calldata.sol b/test/libsolidity/semanticTests/userDefinedValueType/calldata.sol index ea1fc99b4207..1433386e5a24 100644 --- a/test/libsolidity/semanticTests/userDefinedValueType/calldata.sol +++ b/test/libsolidity/semanticTests/userDefinedValueType/calldata.sol @@ -49,13 +49,13 @@ contract C { } // ---- // test_f() -> true -// gas irOptimized: 122094 +// gas irOptimized: 122212 // gas legacy: 125322 -// gas legacyOptimized: 122709 +// gas legacyOptimized: 122694 // test_g() -> true -// gas irOptimized: 106271 +// gas irOptimized: 106428 // gas legacy: 111120 -// gas legacyOptimized: 106964 +// gas legacyOptimized: 106925 // addresses(uint256): 0 -> 0x18 // addresses(uint256): 1 -> 0x19 // addresses(uint256): 3 -> 0x1b diff --git a/test/libsolidity/semanticTests/userDefinedValueType/erc20.sol b/test/libsolidity/semanticTests/userDefinedValueType/erc20.sol index 8976cf3c52cc..30aa590d6fa3 100644 --- a/test/libsolidity/semanticTests/userDefinedValueType/erc20.sol +++ b/test/libsolidity/semanticTests/userDefinedValueType/erc20.sol @@ -113,12 +113,12 @@ contract ERC20 { // ---- // constructor() // ~ emit Transfer(address,address,uint256): #0x00, #0x1212121212121212121212121212120000000012, 0x14 -// gas irOptimized: 121082 -// gas irOptimized code: 231600 +// gas irOptimized: 121322 +// gas irOptimized code: 234600 // gas legacy: 163352 // gas legacy code: 671400 -// gas legacyOptimized: 127448 -// gas legacyOptimized code: 285200 +// gas legacyOptimized: 127464 +// gas legacyOptimized code: 285400 // totalSupply() -> 20 // gas irOptimized: 23415 // gas legacy: 23653 diff --git a/test/libsolidity/semanticTests/various/address_code.sol b/test/libsolidity/semanticTests/various/address_code.sol index f283aaeaa3de..8b601ca8c14c 100644 --- a/test/libsolidity/semanticTests/various/address_code.sol +++ b/test/libsolidity/semanticTests/various/address_code.sol @@ -14,11 +14,11 @@ contract C { } // ---- // constructor() -> -// gas irOptimized: 70351 -// gas irOptimized code: 95800 +// gas irOptimized: 70760 +// gas irOptimized code: 94600 // gas legacy: 82380 // gas legacy code: 153800 -// gas legacyOptimized: 69496 +// gas legacyOptimized: 69400 // gas legacyOptimized code: 79200 // initCode() -> 0x20, 0 // f() -> true diff --git a/test/libsolidity/semanticTests/various/create_calldata.sol b/test/libsolidity/semanticTests/various/create_calldata.sol index b8ec252095c8..3ca50db13661 100644 --- a/test/libsolidity/semanticTests/various/create_calldata.sol +++ b/test/libsolidity/semanticTests/various/create_calldata.sol @@ -8,8 +8,8 @@ contract C { } // ---- // constructor(): 42 -> -// gas irOptimized: 67834 -// gas irOptimized code: 70400 +// gas irOptimized: 68239 +// gas irOptimized code: 69000 // gas legacy: 78029 // gas legacy code: 90200 // gas legacyOptimized: 68321 diff --git a/test/libsolidity/semanticTests/various/destructuring_assignment.sol b/test/libsolidity/semanticTests/various/destructuring_assignment.sol index b8236e2cd5ff..82183a112139 100644 --- a/test/libsolidity/semanticTests/various/destructuring_assignment.sol +++ b/test/libsolidity/semanticTests/various/destructuring_assignment.sol @@ -33,6 +33,6 @@ contract C { } // ---- // f(bytes): 0x20, 0x5, "abcde" -> 0 -// gas irOptimized: 241837 +// gas irOptimized: 242027 // gas legacy: 243284 -// gas legacyOptimized: 242420 +// gas legacyOptimized: 242395 diff --git a/test/libsolidity/semanticTests/various/erc20.sol b/test/libsolidity/semanticTests/various/erc20.sol index f7956c4c50eb..1a7718f6834f 100644 --- a/test/libsolidity/semanticTests/various/erc20.sol +++ b/test/libsolidity/semanticTests/various/erc20.sol @@ -96,12 +96,12 @@ contract ERC20 { // ---- // constructor() // ~ emit Transfer(address,address,uint256): #0x00, #0x1212121212121212121212121212120000000012, 0x14 -// gas irOptimized: 121248 -// gas irOptimized code: 232000 +// gas irOptimized: 121632 +// gas irOptimized code: 236800 // gas legacy: 159959 // gas legacy code: 647600 -// gas legacyOptimized: 126918 -// gas legacyOptimized code: 281800 +// gas legacyOptimized: 126934 +// gas legacyOptimized code: 282000 // totalSupply() -> 20 // gas irOptimized: 23415 // gas legacy: 23524 diff --git a/test/libsolidity/semanticTests/various/many_subassemblies.sol b/test/libsolidity/semanticTests/various/many_subassemblies.sol index 67a576da7889..b270c7006694 100644 --- a/test/libsolidity/semanticTests/various/many_subassemblies.sol +++ b/test/libsolidity/semanticTests/various/many_subassemblies.sol @@ -30,7 +30,7 @@ contract D { } // ---- // run() -> -// gas irOptimized: 375015 +// gas irOptimized: 374934 // gas irOptimized code: 6600 // gas legacy: 375119 // gas legacy code: 17600 diff --git a/test/libsolidity/semanticTests/various/selfdestruct_post_cancun_multiple_beneficiaries.sol b/test/libsolidity/semanticTests/various/selfdestruct_post_cancun_multiple_beneficiaries.sol index 16797ee4c0fd..690bff8d5588 100644 --- a/test/libsolidity/semanticTests/various/selfdestruct_post_cancun_multiple_beneficiaries.sol +++ b/test/libsolidity/semanticTests/various/selfdestruct_post_cancun_multiple_beneficiaries.sol @@ -35,8 +35,8 @@ contract D { // EVMVersion: >=cancun // ---- // constructor(), 2 ether -> -// gas irOptimized: 107718 -// gas irOptimized code: 116200 +// gas irOptimized: 108104 +// gas irOptimized code: 119200 // gas legacy: 120424 // gas legacy code: 253600 // gas legacyOptimized: 109015 @@ -46,7 +46,7 @@ contract D { // balance -> 2000000000000000000 // exists() -> false // test_deploy_and_terminate_twice() -> -// gas irOptimized: 121350 +// gas irOptimized: 121395 // gas irOptimized code: 14000 // gas legacy: 122384 // gas legacy code: 43200 diff --git a/test/libsolidity/semanticTests/various/selfdestruct_post_cancun_redeploy.sol b/test/libsolidity/semanticTests/various/selfdestruct_post_cancun_redeploy.sol index 1b3022efedf0..1ae89a558e70 100644 --- a/test/libsolidity/semanticTests/various/selfdestruct_post_cancun_redeploy.sol +++ b/test/libsolidity/semanticTests/various/selfdestruct_post_cancun_redeploy.sol @@ -82,8 +82,8 @@ contract D { // EVMVersion: >=cancun // ---- // constructor(), 1 ether -> -// gas irOptimized: 132874 -// gas irOptimized code: 292400 +// gas irOptimized: 132974 +// gas irOptimized code: 293800 // gas legacy: 151217 // gas legacy code: 533400 // gas legacyOptimized: 131436 @@ -91,7 +91,7 @@ contract D { // exists() -> false // test_deploy_and_terminate() -> // ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000 -// gas irOptimized: 96394 +// gas irOptimized: 96528 // gas irOptimized code: 20800 // gas legacy: 97788 // gas legacy code: 20800 diff --git a/test/libsolidity/semanticTests/various/selfdestruct_pre_cancun_multiple_beneficiaries.sol b/test/libsolidity/semanticTests/various/selfdestruct_pre_cancun_multiple_beneficiaries.sol index a09a7cac68b1..dbe7109cbd9e 100644 --- a/test/libsolidity/semanticTests/various/selfdestruct_pre_cancun_multiple_beneficiaries.sol +++ b/test/libsolidity/semanticTests/various/selfdestruct_pre_cancun_multiple_beneficiaries.sol @@ -35,8 +35,8 @@ contract D { // EVMVersion: <=shanghai // ---- // constructor(), 2 ether -> -// gas irOptimized: 107718 -// gas irOptimized code: 116200 +// gas irOptimized: 108104 +// gas irOptimized code: 119200 // gas legacy: 120424 // gas legacy code: 253600 // gas legacyOptimized: 109015 @@ -46,7 +46,7 @@ contract D { // balance -> 2000000000000000000 // exists() -> false // test_deploy_and_terminate_twice() -> -// gas irOptimized: 121350 +// gas irOptimized: 121395 // gas irOptimized code: 14000 // gas legacy: 122384 // gas legacy code: 43200 diff --git a/test/libsolidity/semanticTests/various/selfdestruct_pre_cancun_redeploy.sol b/test/libsolidity/semanticTests/various/selfdestruct_pre_cancun_redeploy.sol index fc650ebba741..0d7f2334ebc0 100644 --- a/test/libsolidity/semanticTests/various/selfdestruct_pre_cancun_redeploy.sol +++ b/test/libsolidity/semanticTests/various/selfdestruct_pre_cancun_redeploy.sol @@ -79,8 +79,8 @@ contract D { // EVMVersion: =shanghai // ---- // constructor(), 1 ether -> -// gas irOptimized: 133253 -// gas irOptimized code: 297000 +// gas irOptimized: 133342 +// gas irOptimized code: 298400 // gas legacy: 151644 // gas legacy code: 538600 // gas legacyOptimized: 131799 @@ -88,7 +88,7 @@ contract D { // exists() -> false // test_deploy_and_terminate() -> // ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000 -// gas irOptimized: 96689 +// gas irOptimized: 96823 // gas irOptimized code: 20800 // gas legacy: 98095 // gas legacy code: 20800 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 52287a8f322e..9d078cfd698c 100644 --- a/test/libsolidity/semanticTests/various/skip_dynamic_types_for_structs.sol +++ b/test/libsolidity/semanticTests/various/skip_dynamic_types_for_structs.sol @@ -19,6 +19,6 @@ contract C { } // ---- // g() -> 2, 6 -// gas irOptimized: 178277 +// gas irOptimized: 178195 // gas legacy: 180657 -// gas legacyOptimized: 179156 +// gas legacyOptimized: 179146 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 77a330f3cd54..2063fff7a571 100644 --- a/test/libsolidity/semanticTests/various/staticcall_for_view_and_pure.sol +++ b/test/libsolidity/semanticTests/various/staticcall_for_view_and_pure.sol @@ -45,7 +45,7 @@ contract D { // gas legacyOptimized: 98425380 // gas legacyOptimized code: 13200 // fpure() -> FAILURE -// gas irOptimized: 98425389 +// gas irOptimized: 98425388 // gas irOptimized code: 13200 // gas legacy: 98413174 // gas legacy code: 25600 diff --git a/test/libsolidity/semanticTests/various/value_complex.sol b/test/libsolidity/semanticTests/various/value_complex.sol index 427a006dc102..dc92e38df59b 100644 --- a/test/libsolidity/semanticTests/various/value_complex.sol +++ b/test/libsolidity/semanticTests/various/value_complex.sol @@ -19,8 +19,8 @@ contract test { } // ---- // constructor(), 20 wei -> -// gas irOptimized: 114399 -// gas irOptimized code: 58000 +// gas irOptimized: 114463 +// gas irOptimized code: 58800 // gas legacy: 120076 // gas legacy code: 132200 // gas legacyOptimized: 114536 diff --git a/test/libsolidity/semanticTests/various/value_insane.sol b/test/libsolidity/semanticTests/various/value_insane.sol index 97fbbab1e634..ad0e95701d07 100644 --- a/test/libsolidity/semanticTests/various/value_insane.sol +++ b/test/libsolidity/semanticTests/various/value_insane.sol @@ -18,8 +18,8 @@ contract test { } // ---- // constructor(), 20 wei -> -// gas irOptimized: 114463 -// gas irOptimized code: 58800 +// gas irOptimized: 114527 +// gas irOptimized code: 59600 // gas legacy: 120200 // gas legacy code: 133600 // gas legacyOptimized: 114568 diff --git a/test/libsolidity/semanticTests/viaYul/copy_struct_invalid_ir_bug.sol b/test/libsolidity/semanticTests/viaYul/copy_struct_invalid_ir_bug.sol index 5a85ba07591a..fbaa7789ea0e 100644 --- a/test/libsolidity/semanticTests/viaYul/copy_struct_invalid_ir_bug.sol +++ b/test/libsolidity/semanticTests/viaYul/copy_struct_invalid_ir_bug.sol @@ -21,6 +21,6 @@ contract C { } // ---- // f() -> -// gas irOptimized: 112969 +// gas irOptimized: 113118 // gas legacy: 112890 // gas legacyOptimized: 112580 From e19abe4b622da3ae7ab386e160f631bc8108f6d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Fri, 8 Mar 2024 20:33:07 +0100 Subject: [PATCH 0202/1022] Update other test expectations --- .../debug_info_in_yul_snippet_escaping/output | 62 +- test/cmdlineTests/function_debug_info/output | 4 +- .../output | 21 +- .../output | 21 +- test/cmdlineTests/name_simplifier/output | 136 +-- .../cmdlineTests/optimizer_array_sload/output | 15 +- test/cmdlineTests/optimizer_user_yul/output | 13 +- .../output.json | 152 +-- .../output.json | 140 +-- .../output.json | 1021 +++++++++-------- .../viair_subobject_optimization/output | 51 +- .../sizeLimits/combined_too_large_paris.sol | 6 +- .../combined_too_large_shanghai.sol | 8 +- .../initcode_too_large_shanghai.sol | 2 +- .../yulOptimizerTests/fullSuite/abi2.yul | 31 +- .../fullSuite/abi_example1.yul | 58 +- .../fullSuite/ackermann_function.yul | 3 +- .../fullSuite/ackermann_function_if.yul | 3 +- .../yulOptimizerTests/fullSuite/aztec.yul | 79 +- .../call_arguments_without_side_effects.yul | 29 +- .../fullSuite/create2_and_mask.yul | 5 +- .../fullSuite/create_and_mask.yul | 5 +- .../fullSuite/devcon_example.yul | 5 +- .../fullSuite/extcodelength.yul | 8 +- .../fullSuite/loopInvariantCodeMotion.yul | 5 +- ..._dependent_cse_bug_part_1_pre_shanghai.yul | 11 +- ..._dependent_cse_bug_part_2_pre_shanghai.yul | 11 +- .../fullSuite/stack_compressor_msize.yul | 28 +- .../fullSuite/structural_simplification.yul | 9 +- .../unusedFunctionParameterPruner_loop.yul | 38 +- 30 files changed, 965 insertions(+), 1015 deletions(-) diff --git a/test/cmdlineTests/debug_info_in_yul_snippet_escaping/output b/test/cmdlineTests/debug_info_in_yul_snippet_escaping/output index 0bd6285b785e..d5c02fc82151 100644 --- a/test/cmdlineTests/debug_info_in_yul_snippet_escaping/output +++ b/test/cmdlineTests/debug_info_in_yul_snippet_escaping/output @@ -428,8 +428,7 @@ object "D_27" { { /// @src 0:279:599 "contract D /** @src 0:96:165 \"contract D {...\" *\/ {..." let _1 := memoryguard(0x80) - let _2 := 64 - mstore(_2, _1) + mstore(64, _1) if iszero(lt(calldatasize(), 4)) { if eq(0x26121ff0, shr(224, calldataload(0))) @@ -437,10 +436,9 @@ object "D_27" { if callvalue() { revert(0, 0) } if slt(add(calldatasize(), not(3)), 0) { revert(0, 0) } /// @src 0:446:491 "new /// @src 0:149:156 \"new C()\"..." - let _3 := datasize("C_2") - let _4 := add(_1, _3) - let _5 := 0xffffffffffffffff - if or(gt(_4, _5), lt(_4, _1)) + let _2 := datasize("C_2") + let _3 := add(_1, _2) + if or(gt(_3, 0xffffffffffffffff), lt(_3, _1)) { /// @src 0:279:599 "contract D /** @src 0:96:165 \"contract D {...\" *\/ {..." mstore(0, shl(224, 0x4e487b71)) @@ -448,45 +446,53 @@ object "D_27" { revert(0, 0x24) } /// @src 0:446:491 "new /// @src 0:149:156 \"new C()\"..." - datacopy(_1, dataoffset("C_2"), _3) - if iszero(create(/** @src 0:279:599 "contract D /** @src 0:96:165 \"contract D {...\" *\/ {..." */ 0, /** @src 0:446:491 "new /// @src 0:149:156 \"new C()\"..." */ _1, sub(_4, _1))) + datacopy(_1, dataoffset("C_2"), _2) + if iszero(create(/** @src 0:279:599 "contract D /** @src 0:96:165 \"contract D {...\" *\/ {..." */ 0, /** @src 0:446:491 "new /// @src 0:149:156 \"new C()\"..." */ _1, sub(_3, _1))) { /// @src 0:279:599 "contract D /** @src 0:96:165 \"contract D {...\" *\/ {..." - let pos := mload(_2) + let pos := mload(64) returndatacopy(pos, 0, returndatasize()) revert(pos, returndatasize()) } - let memPtr := mload(_2) - let newFreePtr := add(memPtr, _2) - if or(gt(newFreePtr, /** @src 0:446:491 "new /// @src 0:149:156 \"new C()\"..." */ _5), /** @src 0:279:599 "contract D /** @src 0:96:165 \"contract D {...\" *\/ {..." */ lt(newFreePtr, memPtr)) + let memPtr := 0 + let size := 0 + size := 0 + let memPtr_1 := mload(64) + let newFreePtr := add(memPtr_1, 64) + if or(gt(newFreePtr, /** @src 0:446:491 "new /// @src 0:149:156 \"new C()\"..." */ 0xffffffffffffffff), /** @src 0:279:599 "contract D /** @src 0:96:165 \"contract D {...\" *\/ {..." */ lt(newFreePtr, memPtr_1)) { mstore(0, shl(224, 0x4e487b71)) mstore(4, 0x41) revert(0, 0x24) } - mstore(_2, newFreePtr) - mstore(memPtr, 2) - mstore(add(memPtr, 32), "/*") - let memPtr_1 := mload(_2) - let newFreePtr_1 := add(memPtr_1, 96) - if or(gt(newFreePtr_1, /** @src 0:446:491 "new /// @src 0:149:156 \"new C()\"..." */ _5), /** @src 0:279:599 "contract D /** @src 0:96:165 \"contract D {...\" *\/ {..." */ lt(newFreePtr_1, memPtr_1)) + mstore(64, newFreePtr) + memPtr := memPtr_1 + mstore(memPtr_1, 2) + mstore(add(memPtr_1, 32), "/*") + let memPtr_2 := 0 + let size_1 := 0 + size_1 := 0 + let memPtr_3 := mload(64) + let newFreePtr_1 := add(memPtr_3, 96) + if or(gt(newFreePtr_1, /** @src 0:446:491 "new /// @src 0:149:156 \"new C()\"..." */ 0xffffffffffffffff), /** @src 0:279:599 "contract D /** @src 0:96:165 \"contract D {...\" *\/ {..." */ lt(newFreePtr_1, memPtr_3)) { mstore(0, shl(224, 0x4e487b71)) mstore(4, 0x41) revert(0, 0x24) } - mstore(_2, newFreePtr_1) - mstore(memPtr_1, 39) - let _6 := add(memPtr_1, 32) - mstore(_6, 0x2f2a2a204073726320303a39363a313635202022636f6e74726163742044207b) - mstore(add(memPtr_1, _2), shl(200, 0x2e2e2e22202a2f)) - let memPos := mload(_2) + mstore(64, newFreePtr_1) + memPtr_2 := memPtr_3 + mstore(memPtr_3, 39) + let _4 := add(memPtr_3, 32) + mstore(_4, 0x2f2a2a204073726320303a39363a313635202022636f6e74726163742044207b) + mstore(add(memPtr_3, 64), shl(200, 0x2e2e2e22202a2f)) + let memPos := mload(64) mstore(memPos, 32) - let length := mload(memPtr_1) + let length := mload(memPtr_3) mstore(add(memPos, 32), length) - mcopy(add(memPos, _2), _6, length) - mstore(add(add(memPos, length), _2), 0) - return(memPos, add(sub(add(memPos, and(add(length, 31), not(31))), memPos), _2)) + mcopy(add(memPos, 64), _4, length) + mstore(add(add(memPos, length), 64), 0) + return(memPos, add(sub(add(memPos, and(add(length, 31), not(31))), memPos), 64)) } } revert(0, 0) diff --git a/test/cmdlineTests/function_debug_info/output b/test/cmdlineTests/function_debug_info/output index bd7ba1197b96..c1346e33ab0c 100644 --- a/test/cmdlineTests/function_debug_info/output +++ b/test/cmdlineTests/function_debug_info/output @@ -31,7 +31,7 @@ "returnSlots": 2 }, "abi_decode_tuple_t_uint256": { - "entryPoint": 269, + "entryPoint": 271, "parameterSlots": 2, "returnSlots": 1 }, @@ -40,7 +40,7 @@ "returnSlots": 1 }, "panic_error_0x32": { - "entryPoint": 292, + "entryPoint": 294, "parameterSlots": 0, "returnSlots": 0 } diff --git a/test/cmdlineTests/mcopy_bytes_array_returned_from_function/output b/test/cmdlineTests/mcopy_bytes_array_returned_from_function/output index 2441357d97fb..170cdf1a7a3a 100644 --- a/test/cmdlineTests/mcopy_bytes_array_returned_from_function/output +++ b/test/cmdlineTests/mcopy_bytes_array_returned_from_function/output @@ -22,25 +22,24 @@ object "C_14" { { if callvalue() { revert(0, 0) } if slt(add(calldatasize(), not(3)), 0) { revert(0, 0) } - let _2 := 64 - let newFreePtr := add(_1, _2) + let newFreePtr := add(_1, 64) if or(gt(newFreePtr, 0xffffffffffffffff), lt(newFreePtr, _1)) { mstore(0, shl(224, 0x4e487b71)) mstore(4, 0x41) revert(0, 36) } - mstore(_2, newFreePtr) + mstore(64, newFreePtr) mstore(_1, 5) - let _3 := add(_1, 0x20) - mstore(_3, "aaaaa") - let memPos := mload(_2) - mstore(memPos, 0x20) + let _2 := add(_1, 32) + mstore(_2, "aaaaa") + let memPos := mload(64) + mstore(memPos, 32) let length := mload(_1) - mstore(add(memPos, 0x20), length) - mcopy(add(memPos, _2), _3, length) - mstore(add(add(memPos, length), _2), 0) - return(memPos, add(sub(add(memPos, and(add(length, 31), not(31))), memPos), _2)) + mstore(add(memPos, 32), length) + mcopy(add(memPos, 64), _2, length) + mstore(add(add(memPos, length), 64), 0) + return(memPos, add(sub(add(memPos, and(add(length, 31), not(31))), memPos), 64)) } } revert(0, 0) diff --git a/test/cmdlineTests/mcopy_string_literal_returned_from_function/output b/test/cmdlineTests/mcopy_string_literal_returned_from_function/output index 02740ec0d6cb..548c34de8628 100644 --- a/test/cmdlineTests/mcopy_string_literal_returned_from_function/output +++ b/test/cmdlineTests/mcopy_string_literal_returned_from_function/output @@ -22,25 +22,24 @@ object "C_10" { { if callvalue() { revert(0, 0) } if slt(add(calldatasize(), not(3)), 0) { revert(0, 0) } - let _2 := 64 - let newFreePtr := add(_1, _2) + let newFreePtr := add(_1, 64) if or(gt(newFreePtr, 0xffffffffffffffff), lt(newFreePtr, _1)) { mstore(0, shl(224, 0x4e487b71)) mstore(4, 0x41) revert(0, 0x24) } - mstore(_2, newFreePtr) + mstore(64, newFreePtr) mstore(_1, 25) - let _3 := add(_1, 0x20) - mstore(_3, "MCOPY on Cancun vacation.") - let memPos := mload(_2) - mstore(memPos, 0x20) + let _2 := add(_1, 32) + mstore(_2, "MCOPY on Cancun vacation.") + let memPos := mload(64) + mstore(memPos, 32) let length := mload(_1) - mstore(add(memPos, 0x20), length) - mcopy(add(memPos, _2), _3, length) - mstore(add(add(memPos, length), _2), 0) - return(memPos, add(sub(add(memPos, and(add(length, 31), not(31))), memPos), _2)) + mstore(add(memPos, 32), length) + mcopy(add(memPos, 64), _2, length) + mstore(add(add(memPos, length), 64), 0) + return(memPos, add(sub(add(memPos, and(add(length, 31), not(31))), memPos), 64)) } } revert(0, 0) diff --git a/test/cmdlineTests/name_simplifier/output b/test/cmdlineTests/name_simplifier/output index 0a461e3e4af4..04abaf600103 100644 --- a/test/cmdlineTests/name_simplifier/output +++ b/test/cmdlineTests/name_simplifier/output @@ -17,100 +17,104 @@ object "C_59" { code { { /// @src 0:346:625 "contract C {..." - let _1 := memoryguard(0x80) - let _2 := 4 - if iszero(lt(calldatasize(), _2)) + mstore(64, memoryguard(0x80)) + if iszero(lt(calldatasize(), 4)) { if eq(0xf8eddcc6, shr(224, calldataload(0))) { if callvalue() { revert(0, 0) } - let _3 := 32 - if slt(add(calldatasize(), not(3)), _3) { revert(0, 0) } - let offset := calldataload(_2) - let _4 := 0xffffffffffffffff - if gt(offset, _4) { revert(0, 0) } + if slt(add(calldatasize(), not(3)), 32) { revert(0, 0) } + let offset := calldataload(4) + if gt(offset, 0xffffffffffffffff) { revert(0, 0) } if iszero(slt(add(offset, 35), calldatasize())) { revert(0, 0) } - let _5 := calldataload(add(_2, offset)) - let _6 := 36 - if gt(_5, _4) + let length := calldataload(add(4, offset)) + if gt(length, 0xffffffffffffffff) { mstore(0, shl(224, 0x4e487b71)) - mstore(_2, 0x41) - revert(0, _6) + mstore(4, 0x41) + revert(0, 36) } - let _7 := shl(5, _5) - let _8 := not(31) - let newFreePtr := add(_1, and(add(_7, 63), _8)) - if or(gt(newFreePtr, _4), lt(newFreePtr, _1)) + let _1 := shl(5, length) + let memPtr := 0 + memPtr := mload(64) + let newFreePtr := add(memPtr, and(add(_1, 63), not(31))) + if or(gt(newFreePtr, 0xffffffffffffffff), lt(newFreePtr, memPtr)) { mstore(0, shl(224, 0x4e487b71)) - mstore(_2, 0x41) - revert(0, _6) + mstore(4, 0x41) + revert(0, 36) } - let _9 := 64 - mstore(_9, newFreePtr) - let dst := _1 - mstore(_1, _5) - dst := add(_1, _3) + mstore(64, newFreePtr) + let dst := memPtr + mstore(memPtr, length) + dst := add(memPtr, 32) let dst_1 := dst - let srcEnd := add(add(offset, _7), _6) + let srcEnd := add(add(offset, _1), 36) if gt(srcEnd, calldatasize()) { revert(0, 0) } - let src := add(offset, _6) - for { } lt(src, srcEnd) { src := add(src, _3) } + let src := add(offset, 36) + for { } lt(src, srcEnd) { src := add(src, 32) } { - if slt(sub(calldatasize(), src), _3) { revert(0, 0) } - let memPtr := mload(_9) - let newFreePtr_1 := add(memPtr, _3) - if or(gt(newFreePtr_1, _4), lt(newFreePtr_1, memPtr)) + if slt(sub(calldatasize(), src), 32) { revert(0, 0) } + let memPtr_1 := 0 + memPtr_1 := mload(64) + let newFreePtr_1 := add(memPtr_1, 32) + if or(gt(newFreePtr_1, 0xffffffffffffffff), lt(newFreePtr_1, memPtr_1)) { mstore(0, shl(224, 0x4e487b71)) - mstore(_2, 0x41) - revert(0, _6) + mstore(4, 0x41) + revert(0, 36) } - mstore(_9, newFreePtr_1) - mstore(memPtr, calldataload(src)) - mstore(dst, memPtr) - dst := add(dst, _3) + mstore(64, newFreePtr_1) + mstore(memPtr_1, calldataload(src)) + mstore(dst, memPtr_1) + dst := add(dst, 32) } - if iszero(mload(_1)) + /// @src 0:469:474 "_s[0]" + let addr := /** @src 0:346:625 "contract C {..." */ 0 + if iszero(mload(memPtr)) { mstore(0, shl(224, 0x4e487b71)) - mstore(_2, 0x32) - revert(0, _6) + mstore(4, 0x32) + revert(0, 36) } + addr := dst_1 sstore(0, mload(/** @src 0:469:474 "_s[0]" */ mload(dst_1))) - /// @src 0:346:625 "contract C {..." - if iszero(lt(/** @src 0:492:493 "1" */ 0x01, /** @src 0:346:625 "contract C {..." */ mload(_1))) + /// @src 0:489:494 "_s[1]" + let addr_1 := /** @src 0:346:625 "contract C {..." */ 0 + if iszero(lt(/** @src 0:492:493 "1" */ 0x01, /** @src 0:346:625 "contract C {..." */ mload(memPtr))) { mstore(0, shl(224, 0x4e487b71)) - mstore(_2, 0x32) - revert(0, _6) + mstore(4, 0x32) + revert(0, 36) } - let _10 := mload(/** @src 0:489:494 "_s[1]" */ mload(/** @src 0:346:625 "contract C {..." */ add(_1, _9))) - sstore(0x02, _10) - let memPtr_1 := mload(_9) - let newFreePtr_2 := add(memPtr_1, 160) - if or(gt(newFreePtr_2, _4), lt(newFreePtr_2, memPtr_1)) + addr_1 := add(memPtr, 64) + let _2 := mload(/** @src 0:489:494 "_s[1]" */ mload(addr_1)) + /// @src 0:346:625 "contract C {..." + sstore(0x02, _2) + let memPtr_2 := 0 + memPtr_2 := mload(64) + let newFreePtr_2 := add(memPtr_2, 160) + if or(gt(newFreePtr_2, 0xffffffffffffffff), lt(newFreePtr_2, memPtr_2)) { mstore(0, shl(224, 0x4e487b71)) - mstore(_2, 0x41) - revert(0, _6) + mstore(4, 0x41) + revert(0, 36) } - mstore(_9, newFreePtr_2) - mstore(memPtr_1, 100) - let _11 := add(memPtr_1, _3) - mstore(_11, "longstringlongstringlongstringlo") - mstore(add(memPtr_1, _9), "ngstringlongstringlongstringlong") - mstore(add(memPtr_1, 96), "stringlongstringlongstringlongst") - mstore(add(memPtr_1, 128), "ring") - let memPos := mload(_9) - mstore(memPos, _10) - mstore(add(memPos, _3), _9) - let length := mload(memPtr_1) - mstore(add(memPos, _9), length) - mcopy(add(memPos, 96), _11, length) - mstore(add(add(memPos, length), 96), 0) - return(memPos, add(sub(add(memPos, and(add(length, 31), _8)), memPos), 96)) + mstore(64, newFreePtr_2) + mstore(memPtr_2, 100) + let _3 := add(memPtr_2, 32) + mstore(_3, "longstringlongstringlongstringlo") + mstore(add(memPtr_2, 64), "ngstringlongstringlongstringlong") + mstore(add(memPtr_2, 96), "stringlongstringlongstringlongst") + mstore(add(memPtr_2, 128), "ring") + let memPos := mload(64) + mstore(memPos, _2) + mstore(add(memPos, 32), 64) + let length_1 := mload(memPtr_2) + mstore(add(memPos, 64), length_1) + mcopy(add(memPos, 96), _3, length_1) + mstore(add(add(memPos, length_1), 96), 0) + return(memPos, add(sub(add(memPos, and(add(length_1, 0x1f), not(31))), memPos), 96)) } } revert(0, 0) diff --git a/test/cmdlineTests/optimizer_array_sload/output b/test/cmdlineTests/optimizer_array_sload/output index b32d421d0717..c1e0796f56fa 100644 --- a/test/cmdlineTests/optimizer_array_sload/output +++ b/test/cmdlineTests/optimizer_array_sload/output @@ -18,7 +18,6 @@ object "Arraysum_34" { { /// @src 0:80:429 "contract Arraysum {..." mstore(64, memoryguard(0x80)) - let _1 := 4 if iszero(lt(calldatasize(), 4)) { if eq(0x81d73423, shr(224, calldataload(0))) @@ -26,12 +25,14 @@ object "Arraysum_34" { if callvalue() { revert(0, 0) } if slt(add(calldatasize(), not(3)), 0) { revert(0, 0) } let var_sum := 0 + /// @src 0:175:182 "sum = 0" + var_sum := /** @src 0:80:429 "contract Arraysum {..." */ 0 /// @src 0:368:378 "uint i = 0" let var_i := /** @src 0:80:429 "contract Arraysum {..." */ 0 - let _2 := sload(0) + let _1 := sload(0) /// @src 0:364:423 "for(uint i = 0; i < values.length; i++)..." for { } - /** @src 0:380:397 "i < values.length" */ lt(var_i, _2) + /** @src 0:80:429 "contract Arraysum {..." */ 1 /// @src 0:368:378 "uint i = 0" { /// @src 0:399:402 "i++" @@ -39,13 +40,17 @@ object "Arraysum_34" { } /// @src 0:399:402 "i++" { + /// @src 0:380:397 "i < values.length" + let _2 := iszero(lt(var_i, _1)) + if _2 { break } /// @src 0:80:429 "contract Arraysum {..." + _2 := 0 mstore(0, 0) let sum := add(var_sum, sload(add(18569430475105882587588266137607568536673111973893317399460219858819262702947, var_i))) if gt(var_sum, sum) { mstore(0, shl(224, 0x4e487b71)) - mstore(_1, 0x11) + mstore(4, 0x11) revert(0, 0x24) } /// @src 0:407:423 "sum += values[i]" @@ -54,7 +59,7 @@ object "Arraysum_34" { /// @src 0:80:429 "contract Arraysum {..." let memPos := mload(64) mstore(memPos, var_sum) - return(memPos, 32) + return(memPos, 0x20) } } revert(0, 0) diff --git a/test/cmdlineTests/optimizer_user_yul/output b/test/cmdlineTests/optimizer_user_yul/output index 602a7de95b96..689e82ddb4e4 100644 --- a/test/cmdlineTests/optimizer_user_yul/output +++ b/test/cmdlineTests/optimizer_user_yul/output @@ -42,7 +42,6 @@ tag_5: /* "optimizer_user_yul/input.sol":263:269 a := 2 */ swap1 pop - 0x00 /* "optimizer_user_yul/input.sol":369:370 3 */ 0x03 /* "optimizer_user_yul/input.sol":366:367 2 */ @@ -59,18 +58,10 @@ tag_6: /* "optimizer_user_yul/input.sol":384:392 sload(5) */ dup1 /* "optimizer_user_yul/input.sol":376:509 for { } sload(5) { } {... */ - tag_8 + iszero + tag_6 jumpi - /* "optimizer_user_yul/input.sol":495:504 exp(x, y) */ - 0x01 - /* "optimizer_user_yul/input.sol":490:504 z := exp(x, y) */ - swap2 - pop - /* "optimizer_user_yul/input.sol":376:509 for { } sload(5) { } {... */ - jump(tag_6) -tag_8: /* "optimizer_user_yul/input.sol":380:383 { } */ - pop pop /* "optimizer_user_yul/input.sol":340:513 {... */ pop 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 642d07f49af2..4ef3c6df1873 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 @@ -76,25 +76,18 @@ stop sub_0: assembly { /* \"C\":79:503 contract C... */ - 0x80 - 0x40 - swap1 - dup1 - dup3 - mstore + mstore(0x40, 0x80) jumpi(tag_2, iszero(lt(calldatasize, 0x04))) 0x00 dup1 revert tag_2: shr(0xe0, calldataload(0x00)) - swap1 - dup2 + dup1 0x26121ff0 eq tag_4 jumpi - pop dup1 0x793816ec eq @@ -122,19 +115,17 @@ sub_0: assembly { dup2 swap1 sstore - dup2 - mload + mload(0x40) shl(0xe4, 0x026121ff) /* \"C\":475:483 this.f() */ dup2 mstore /* \"C\":79:503 contract C... */ - swap2 swap1 /* \"C\":475:483 this.f() */ 0x20 /* \"C\":79:503 contract C... */ - dup4 + dup3 0x04 dup2 /* \"C\":475:479 this */ @@ -142,50 +133,46 @@ sub_0: assembly { /* \"C\":475:483 this.f() */ gas staticcall - swap3 - dup4 + swap2 + dup3 iszero tag_16 jumpi /* \"C\":79:503 contract C... */ 0x00 /* \"C\":475:483 this.f() */ - swap4 + swap3 tag_18 jumpi /* \"C\":79:503 contract C... */ tag_19: - /* \"C\":464:483 stateVar + this.f() */ - pop - tag_20 /* \"C\":475:483 this.f() */ 0x20 - /* \"C\":464:483 stateVar + this.f() */ - swap4 /* \"C\":464:494 stateVar + this.f() + immutVar */ - tag_21 + tag_20 /* \"C\":464:483 stateVar + this.f() */ - swap3 + tag_21 + dup6 + dup6 tag_1 jump\t// in - tag_20: + tag_21: /* \"C\":486:494 immutVar */ immutable(\"0xe4b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c10\") /* \"C\":464:494 stateVar + this.f() + immutVar */ swap1 tag_1 jump\t// in - tag_21: + tag_20: /* \"C\":79:503 contract C... */ - swap1 - mload + mload(0x40) swap1 dup2 mstore return /* \"C\":475:483 this.f() */ tag_18: - swap3 + swap2 pop 0x20 jumpi(tag_22, gt(0x20, returndatasize)) @@ -196,12 +183,12 @@ sub_0: assembly { add not(0x1f) and - dup5 + dup4 add 0xffffffffffffffff dup2 gt - dup6 + dup5 dup3 lt or @@ -211,9 +198,9 @@ sub_0: assembly { 0x20 /* \"C\":79:503 contract C... */ swap2 - dup6 + dup5 swap2 - dup6 + 0x40 mstore /* \"C\":475:483 this.f() */ dup2 @@ -223,11 +210,11 @@ sub_0: assembly { slt tag_26 jumpi - swap2 + swap1 mload - swap2 + swap1 /* \"C\":464:483 stateVar + this.f() */ - tag_20 + tag_21 /* \"C\":475:483 this.f() */ jump(tag_19) /* \"C\":79:503 contract C... */ @@ -250,8 +237,7 @@ sub_0: assembly { jump(tag_23) tag_16: /* \"C\":79:503 contract C... */ - dup3 - mload + mload(0x40) returndatasize 0x00 dup3 @@ -278,14 +264,11 @@ sub_0: assembly { revert /* \"C\":79:503 contract C... */ tag_6: - pop jumpi(tag_26, callvalue) jumpi(tag_26, slt(add(not(0x03), calldatasize), 0x00)) 0x20 - swap1 sload(0x00) - swap1 - mload + mload(0x40) swap1 dup2 mstore @@ -296,12 +279,11 @@ sub_0: assembly { /* \"C\":326:334 immutVar */ immutable(\"0xe4b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c10\") /* \"C\":120:122 41 */ - swap1 - dup2 + dup1 0x29 add - swap2 - dup3 + swap1 + dup2 slt 0x01 and @@ -309,7 +291,9 @@ sub_0: assembly { jumpi /* \"C\":79:503 contract C... */ 0x20 - swap2 + swap1 + mload(0x40) + swap1 dup2 mstore return @@ -438,25 +422,18 @@ stop sub_0: assembly { /* \"D\":91:181 contract D is C(3)... */ - 0x80 - 0x40 - swap1 - dup1 - dup3 - mstore + mstore(0x40, 0x80) jumpi(tag_2, iszero(lt(calldatasize, 0x04))) 0x00 dup1 revert tag_2: shr(0xe0, calldataload(0x00)) - swap1 - dup2 + dup1 0x26121ff0 eq tag_4 jumpi - pop dup1 0x793816ec eq @@ -484,19 +461,17 @@ sub_0: assembly { dup2 swap1 sstore - dup2 - mload + mload(0x40) shl(0xe4, 0x026121ff) /* \"C\":475:483 this.f() */ dup2 mstore /* \"D\":91:181 contract D is C(3)... */ - swap2 swap1 /* \"C\":475:483 this.f() */ 0x20 /* \"D\":91:181 contract D is C(3)... */ - dup4 + dup3 0x04 dup2 /* \"C\":475:479 this */ @@ -504,50 +479,46 @@ sub_0: assembly { /* \"C\":475:483 this.f() */ gas staticcall - swap3 - dup4 + swap2 + dup3 iszero tag_16 jumpi /* \"D\":91:181 contract D is C(3)... */ 0x00 /* \"C\":475:483 this.f() */ - swap4 + swap3 tag_18 jumpi /* \"D\":91:181 contract D is C(3)... */ tag_19: - /* \"C\":464:483 stateVar + this.f() */ - pop - tag_20 /* \"C\":475:483 this.f() */ 0x20 - /* \"C\":464:483 stateVar + this.f() */ - swap4 /* \"C\":464:494 stateVar + this.f() + immutVar */ - tag_21 + tag_20 /* \"C\":464:483 stateVar + this.f() */ - swap3 + tag_21 + dup6 + dup6 tag_1 jump\t// in - tag_20: + tag_21: /* \"C\":486:494 immutVar */ immutable(\"0xe4b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c10\") /* \"C\":464:494 stateVar + this.f() + immutVar */ swap1 tag_1 jump\t// in - tag_21: + tag_20: /* \"D\":91:181 contract D is C(3)... */ - swap1 - mload + mload(0x40) swap1 dup2 mstore return /* \"C\":475:483 this.f() */ tag_18: - swap3 + swap2 pop 0x20 jumpi(tag_22, gt(0x20, returndatasize)) @@ -558,12 +529,12 @@ sub_0: assembly { add not(0x1f) and - dup5 + dup4 add 0xffffffffffffffff dup2 gt - dup6 + dup5 dup3 lt or @@ -573,9 +544,9 @@ sub_0: assembly { 0x20 /* \"D\":91:181 contract D is C(3)... */ swap2 - dup6 + dup5 swap2 - dup6 + 0x40 mstore /* \"C\":475:483 this.f() */ dup2 @@ -585,11 +556,11 @@ sub_0: assembly { slt tag_26 jumpi - swap2 + swap1 mload - swap2 + swap1 /* \"C\":464:483 stateVar + this.f() */ - tag_20 + tag_21 /* \"C\":475:483 this.f() */ jump(tag_19) /* \"D\":91:181 contract D is C(3)... */ @@ -612,8 +583,7 @@ sub_0: assembly { jump(tag_23) tag_16: /* \"D\":91:181 contract D is C(3)... */ - dup3 - mload + mload(0x40) returndatasize 0x00 dup3 @@ -640,14 +610,11 @@ sub_0: assembly { revert /* \"D\":91:181 contract D is C(3)... */ tag_6: - pop jumpi(tag_26, callvalue) jumpi(tag_26, slt(add(not(0x03), calldatasize), 0x00)) 0x20 - swap1 sload(0x00) - swap1 - mload + mload(0x40) swap1 dup2 mstore @@ -658,12 +625,11 @@ sub_0: assembly { /* \"C\":326:334 immutVar */ immutable(\"0xe4b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c10\") /* \"C\":120:122 41 */ - swap1 - dup2 + dup1 0x29 add - swap2 - dup3 + swap1 + dup2 slt 0x01 and @@ -671,7 +637,9 @@ sub_0: assembly { jumpi /* \"D\":91:181 contract D is C(3)... */ 0x20 - swap2 + swap1 + mload(0x40) + swap1 dup2 mstore return 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 3e687cc1a0fc..8f0d5b5b5d6d 100644 --- a/test/cmdlineTests/standard_debug_info_in_yul_location/output.json +++ b/test/cmdlineTests/standard_debug_info_in_yul_location/output.json @@ -650,9 +650,7 @@ object \"C_54\" { code { { /// @src 0:79:510 \"contract C...\" - let _1 := memoryguard(0x80) - let _2 := 64 - mstore(_2, _1) + mstore(64, memoryguard(0x80)) if iszero(lt(calldatasize(), 4)) { switch shr(224, calldataload(0)) @@ -660,89 +658,91 @@ object \"C_54\" { if callvalue() { revert(0, 0) } if slt(add(calldatasize(), not(3)), 0) { revert(0, 0) } /// @src 0:333:341 \"immutVar\" - let _3 := loadimmutable(\"8\") - /// @src 0:79:510 \"contract C...\" - let sum := add(/** @src 0:127:129 \"41\" */ 0x29, /** @src 0:79:510 \"contract C...\" */ _3) - if and(1, slt(sum, _3)) + let _1 := loadimmutable(\"8\") + /// @src 0:322:341 \"constVar + immutVar\" + let sum := /** @src 0:79:510 \"contract C...\" */ 0 + sum := add(/** @src 0:127:129 \"41\" */ 0x29, /** @src 0:79:510 \"contract C...\" */ _1) + if and(1, slt(sum, _1)) { mstore(0, shl(224, 0x4e487b71)) mstore(4, 0x11) revert(0, 0x24) } - mstore(_1, sum) - return(_1, 32) + let memPos := mload(64) + mstore(memPos, sum) + return(memPos, 32) } case 0x793816ec { if callvalue() { revert(0, 0) } if slt(add(calldatasize(), not(3)), 0) { revert(0, 0) } - let _4 := sload(0) - let memPos := mload(_2) - mstore(memPos, _4) - return(memPos, 32) + let _2 := sload(0) + let memPos_1 := mload(64) + mstore(memPos_1, _2) + return(memPos_1, 32) } case 0x9942ec6f { if callvalue() { revert(0, 0) } if slt(add(calldatasize(), not(3)), 0) { revert(0, 0) } - let _5 := sload(0) - if eq(_5, sub(shl(255, 1), 1)) + let _3 := sload(0) + if eq(_3, sub(shl(255, 1), 1)) { mstore(0, shl(224, 0x4e487b71)) mstore(4, 0x11) revert(0, 0x24) } - let ret := add(_5, 1) + let ret := add(_3, 1) sstore(0, ret) /// @src 0:482:490 \"this.f()\" - let _6 := /** @src 0:79:510 \"contract C...\" */ mload(_2) + let _4 := /** @src 0:79:510 \"contract C...\" */ mload(64) /// @src 0:482:490 \"this.f()\" - mstore(_6, /** @src 0:79:510 \"contract C...\" */ shl(228, 0x026121ff)) + mstore(_4, /** @src 0:79:510 \"contract C...\" */ shl(228, 0x026121ff)) /// @src 0:482:490 \"this.f()\" - let _7 := staticcall(gas(), /** @src 0:482:486 \"this\" */ address(), /** @src 0:482:490 \"this.f()\" */ _6, /** @src 0:79:510 \"contract C...\" */ 4, /** @src 0:482:490 \"this.f()\" */ _6, 32) - if iszero(_7) + let _5 := staticcall(gas(), /** @src 0:482:486 \"this\" */ address(), /** @src 0:482:490 \"this.f()\" */ _4, /** @src 0:79:510 \"contract C...\" */ 4, /** @src 0:482:490 \"this.f()\" */ _4, 32) + if iszero(_5) { /// @src 0:79:510 \"contract C...\" - let pos := mload(_2) + let pos := mload(64) returndatacopy(pos, 0, returndatasize()) revert(pos, returndatasize()) } /// @src 0:482:490 \"this.f()\" let expr := /** @src 0:79:510 \"contract C...\" */ 0 /// @src 0:482:490 \"this.f()\" - if _7 + if _5 { - let _8 := 32 - if gt(32, returndatasize()) { _8 := returndatasize() } + let _6 := 32 + if gt(32, returndatasize()) { _6 := returndatasize() } /// @src 0:79:510 \"contract C...\" - let newFreePtr := add(_6, and(add(_8, 31), not(31))) - if or(gt(newFreePtr, 0xffffffffffffffff), lt(newFreePtr, _6)) + let newFreePtr := add(_4, and(add(_6, 31), not(31))) + if or(gt(newFreePtr, 0xffffffffffffffff), lt(newFreePtr, _4)) { mstore(0, shl(224, 0x4e487b71)) mstore(4, 0x41) revert(0, 0x24) } - mstore(_2, newFreePtr) - if slt(sub(/** @src 0:482:490 \"this.f()\" */ add(_6, _8), /** @src 0:79:510 \"contract C...\" */ _6), /** @src 0:482:490 \"this.f()\" */ 32) + mstore(64, newFreePtr) + if slt(sub(/** @src 0:482:490 \"this.f()\" */ add(_4, _6), /** @src 0:79:510 \"contract C...\" */ _4), /** @src 0:482:490 \"this.f()\" */ 32) /// @src 0:79:510 \"contract C...\" { revert(0, 0) } /// @src 0:482:490 \"this.f()\" - expr := /** @src 0:79:510 \"contract C...\" */ mload(_6) + expr := /** @src 0:79:510 \"contract C...\" */ mload(_4) } /// @src 0:471:490 \"stateVar + this.f()\" let expr_1 := checked_add_int256(ret, expr) /// @src 0:464:501 \"return stateVar + this.f() + immutVar\" let var := /** @src 0:471:501 \"stateVar + this.f() + immutVar\" */ checked_add_int256(expr_1, /** @src 0:493:501 \"immutVar\" */ loadimmutable(\"8\")) /// @src 0:79:510 \"contract C...\" - let memPos_1 := mload(_2) - mstore(memPos_1, var) - return(memPos_1, /** @src 0:482:490 \"this.f()\" */ 32) + let memPos_2 := mload(64) + mstore(memPos_2, var) + return(memPos_2, /** @src 0:482:490 \"this.f()\" */ 32) } case /** @src 0:79:510 \"contract C...\" */ 0xa00b982b { if callvalue() { revert(0, 0) } if slt(add(calldatasize(), not(3)), 0) { revert(0, 0) } - let memPos_2 := mload(_2) - mstore(memPos_2, /** @src 0:127:129 \"41\" */ 0x29) + let memPos_3 := mload(64) + mstore(memPos_3, /** @src 0:127:129 \"41\" */ 0x29) /// @src 0:79:510 \"contract C...\" - return(memPos_2, 32) + return(memPos_3, 32) } } revert(0, 0) @@ -1493,9 +1493,7 @@ object \"D_72\" { code { { /// @src 1:91:181 \"contract D is C(3)...\" - let _1 := memoryguard(0x80) - let _2 := 64 - mstore(_2, _1) + mstore(64, memoryguard(0x80)) if iszero(lt(calldatasize(), 4)) { switch shr(224, calldataload(0)) @@ -1503,89 +1501,91 @@ object \"D_72\" { if callvalue() { revert(0, 0) } if slt(add(calldatasize(), not(3)), 0) { revert(0, 0) } /// @src 0:333:341 \"immutVar\" - let _3 := loadimmutable(\"8\") - /// @src 1:91:181 \"contract D is C(3)...\" - let sum := add(/** @src 0:127:129 \"41\" */ 0x29, /** @src 1:91:181 \"contract D is C(3)...\" */ _3) - if and(1, slt(sum, _3)) + let _1 := loadimmutable(\"8\") + /// @src 0:322:341 \"constVar + immutVar\" + let sum := /** @src 1:91:181 \"contract D is C(3)...\" */ 0 + sum := add(/** @src 0:127:129 \"41\" */ 0x29, /** @src 1:91:181 \"contract D is C(3)...\" */ _1) + if and(1, slt(sum, _1)) { mstore(0, shl(224, 0x4e487b71)) mstore(4, 0x11) revert(0, 0x24) } - mstore(_1, sum) - return(_1, 32) + let memPos := mload(64) + mstore(memPos, sum) + return(memPos, 32) } case 0x793816ec { if callvalue() { revert(0, 0) } if slt(add(calldatasize(), not(3)), 0) { revert(0, 0) } - let _4 := sload(0) - let memPos := mload(_2) - mstore(memPos, _4) - return(memPos, 32) + let _2 := sload(0) + let memPos_1 := mload(64) + mstore(memPos_1, _2) + return(memPos_1, 32) } case 0x9942ec6f { if callvalue() { revert(0, 0) } if slt(add(calldatasize(), not(3)), 0) { revert(0, 0) } - let _5 := sload(0) - if eq(_5, sub(shl(255, 1), 1)) + let _3 := sload(0) + if eq(_3, sub(shl(255, 1), 1)) { mstore(0, shl(224, 0x4e487b71)) mstore(4, 0x11) revert(0, 0x24) } - let ret := add(_5, 1) + let ret := add(_3, 1) sstore(0, ret) /// @src 0:482:490 \"this.f()\" - let _6 := /** @src 1:91:181 \"contract D is C(3)...\" */ mload(_2) + let _4 := /** @src 1:91:181 \"contract D is C(3)...\" */ mload(64) /// @src 0:482:490 \"this.f()\" - mstore(_6, /** @src 1:91:181 \"contract D is C(3)...\" */ shl(228, 0x026121ff)) + mstore(_4, /** @src 1:91:181 \"contract D is C(3)...\" */ shl(228, 0x026121ff)) /// @src 0:482:490 \"this.f()\" - let _7 := staticcall(gas(), /** @src 0:482:486 \"this\" */ address(), /** @src 0:482:490 \"this.f()\" */ _6, /** @src 1:91:181 \"contract D is C(3)...\" */ 4, /** @src 0:482:490 \"this.f()\" */ _6, 32) - if iszero(_7) + let _5 := staticcall(gas(), /** @src 0:482:486 \"this\" */ address(), /** @src 0:482:490 \"this.f()\" */ _4, /** @src 1:91:181 \"contract D is C(3)...\" */ 4, /** @src 0:482:490 \"this.f()\" */ _4, 32) + if iszero(_5) { /// @src 1:91:181 \"contract D is C(3)...\" - let pos := mload(_2) + let pos := mload(64) returndatacopy(pos, 0, returndatasize()) revert(pos, returndatasize()) } /// @src 0:482:490 \"this.f()\" let expr := /** @src 1:91:181 \"contract D is C(3)...\" */ 0 /// @src 0:482:490 \"this.f()\" - if _7 + if _5 { - let _8 := 32 - if gt(32, returndatasize()) { _8 := returndatasize() } + let _6 := 32 + if gt(32, returndatasize()) { _6 := returndatasize() } /// @src 1:91:181 \"contract D is C(3)...\" - let newFreePtr := add(_6, and(add(_8, 31), not(31))) - if or(gt(newFreePtr, 0xffffffffffffffff), lt(newFreePtr, _6)) + let newFreePtr := add(_4, and(add(_6, 31), not(31))) + if or(gt(newFreePtr, 0xffffffffffffffff), lt(newFreePtr, _4)) { mstore(0, shl(224, 0x4e487b71)) mstore(4, 0x41) revert(0, 0x24) } - mstore(_2, newFreePtr) - if slt(sub(/** @src 0:482:490 \"this.f()\" */ add(_6, _8), /** @src 1:91:181 \"contract D is C(3)...\" */ _6), /** @src 0:482:490 \"this.f()\" */ 32) + mstore(64, newFreePtr) + if slt(sub(/** @src 0:482:490 \"this.f()\" */ add(_4, _6), /** @src 1:91:181 \"contract D is C(3)...\" */ _4), /** @src 0:482:490 \"this.f()\" */ 32) /// @src 1:91:181 \"contract D is C(3)...\" { revert(0, 0) } /// @src 0:482:490 \"this.f()\" - expr := /** @src 1:91:181 \"contract D is C(3)...\" */ mload(_6) + expr := /** @src 1:91:181 \"contract D is C(3)...\" */ mload(_4) } /// @src 0:471:490 \"stateVar + this.f()\" let expr_1 := checked_add_int256(ret, expr) /// @src 0:464:501 \"return stateVar + this.f() + immutVar\" let var := /** @src 0:471:501 \"stateVar + this.f() + immutVar\" */ checked_add_int256(expr_1, /** @src 0:493:501 \"immutVar\" */ loadimmutable(\"8\")) /// @src 1:91:181 \"contract D is C(3)...\" - let memPos_1 := mload(_2) - mstore(memPos_1, var) - return(memPos_1, /** @src 0:482:490 \"this.f()\" */ 32) + let memPos_2 := mload(64) + mstore(memPos_2, var) + return(memPos_2, /** @src 0:482:490 \"this.f()\" */ 32) } case /** @src 1:91:181 \"contract D is C(3)...\" */ 0xa00b982b { if callvalue() { revert(0, 0) } if slt(add(calldatasize(), not(3)), 0) { revert(0, 0) } - let memPos_2 := mload(_2) - mstore(memPos_2, /** @src 0:127:129 \"41\" */ 0x29) + let memPos_3 := mload(64) + mstore(memPos_3, /** @src 0:127:129 \"41\" */ 0x29) /// @src 1:91:181 \"contract D is C(3)...\" - return(memPos_2, 32) + return(memPos_3, 32) } } revert(0, 0) diff --git a/test/cmdlineTests/standard_optimizer_generatedSources/output.json b/test/cmdlineTests/standard_optimizer_generatedSources/output.json index 0f8c3d4eae55..e5b276b1b9b6 100644 --- a/test/cmdlineTests/standard_optimizer_generatedSources/output.json +++ b/test/cmdlineTests/standard_optimizer_generatedSources/output.json @@ -11,9 +11,9 @@ "generatedSources": [ { "ast": { - "nativeSrc": "0:1445:1", + "nativeSrc": "0:1505:1", "nodeType": "YulBlock", - "src": "0:1445:1", + "src": "0:1505:1", "statements": [ { "nativeSrc": "6:3:1", @@ -159,71 +159,49 @@ }, { "body": { - "nativeSrc": "241:1020:1", + "nativeSrc": "241:1080:1", "nodeType": "YulBlock", - "src": "241:1020:1", + "src": "241:1080:1", "statements": [ - { - "nativeSrc": "251:12:1", - "nodeType": "YulVariableDeclaration", - "src": "251:12:1", - "value": { - "kind": "number", - "nativeSrc": "261:2:1", - "nodeType": "YulLiteral", - "src": "261:2:1", - "type": "", - "value": "32" - }, - "variables": [ - { - "name": "_1", - "nativeSrc": "255:2:1", - "nodeType": "YulTypedName", - "src": "255:2:1", - "type": "" - } - ] - }, { "body": { - "nativeSrc": "308:16:1", + "nativeSrc": "287:16:1", "nodeType": "YulBlock", - "src": "308:16:1", + "src": "287:16:1", "statements": [ { "expression": { "arguments": [ { "kind": "number", - "nativeSrc": "317:1:1", + "nativeSrc": "296:1:1", "nodeType": "YulLiteral", - "src": "317:1:1", + "src": "296:1:1", "type": "", "value": "0" }, { "kind": "number", - "nativeSrc": "320:1:1", + "nativeSrc": "299:1:1", "nodeType": "YulLiteral", - "src": "320:1:1", + "src": "299:1:1", "type": "", "value": "0" } ], "functionName": { "name": "revert", - "nativeSrc": "310:6:1", + "nativeSrc": "289:6:1", "nodeType": "YulIdentifier", - "src": "310:6:1" + "src": "289:6:1" }, - "nativeSrc": "310:12:1", + "nativeSrc": "289:12:1", "nodeType": "YulFunctionCall", - "src": "310:12:1" + "src": "289:12:1" }, - "nativeSrc": "310:12:1", + "nativeSrc": "289:12:1", "nodeType": "YulExpressionStatement", - "src": "310:12:1" + "src": "289:12:1" } ] }, @@ -233,142 +211,122 @@ "arguments": [ { "name": "dataEnd", - "nativeSrc": "283:7:1", + "nativeSrc": "262:7:1", "nodeType": "YulIdentifier", - "src": "283:7:1" + "src": "262:7:1" }, { "name": "headStart", - "nativeSrc": "292:9:1", + "nativeSrc": "271:9:1", "nodeType": "YulIdentifier", - "src": "292:9:1" + "src": "271:9:1" } ], "functionName": { "name": "sub", - "nativeSrc": "279:3:1", + "nativeSrc": "258:3:1", "nodeType": "YulIdentifier", - "src": "279:3:1" + "src": "258:3:1" }, - "nativeSrc": "279:23:1", + "nativeSrc": "258:23:1", "nodeType": "YulFunctionCall", - "src": "279:23:1" + "src": "258:23:1" }, { - "name": "_1", - "nativeSrc": "304:2:1", - "nodeType": "YulIdentifier", - "src": "304:2:1" + "kind": "number", + "nativeSrc": "283:2:1", + "nodeType": "YulLiteral", + "src": "283:2:1", + "type": "", + "value": "32" } ], "functionName": { "name": "slt", - "nativeSrc": "275:3:1", + "nativeSrc": "254:3:1", "nodeType": "YulIdentifier", - "src": "275:3:1" + "src": "254:3:1" }, - "nativeSrc": "275:32:1", + "nativeSrc": "254:32:1", "nodeType": "YulFunctionCall", - "src": "275:32:1" + "src": "254:32:1" }, - "nativeSrc": "272:52:1", + "nativeSrc": "251:52:1", "nodeType": "YulIf", - "src": "272:52:1" + "src": "251:52:1" }, { - "nativeSrc": "333:37:1", + "nativeSrc": "312:37:1", "nodeType": "YulVariableDeclaration", - "src": "333:37:1", + "src": "312:37:1", "value": { "arguments": [ { "name": "headStart", - "nativeSrc": "360:9:1", + "nativeSrc": "339:9:1", "nodeType": "YulIdentifier", - "src": "360:9:1" + "src": "339:9:1" } ], "functionName": { "name": "calldataload", - "nativeSrc": "347:12:1", + "nativeSrc": "326:12:1", "nodeType": "YulIdentifier", - "src": "347:12:1" + "src": "326:12:1" }, - "nativeSrc": "347:23:1", + "nativeSrc": "326:23:1", "nodeType": "YulFunctionCall", - "src": "347:23:1" + "src": "326:23:1" }, "variables": [ { "name": "offset", - "nativeSrc": "337:6:1", - "nodeType": "YulTypedName", - "src": "337:6:1", - "type": "" - } - ] - }, - { - "nativeSrc": "379:28:1", - "nodeType": "YulVariableDeclaration", - "src": "379:28:1", - "value": { - "kind": "number", - "nativeSrc": "389:18:1", - "nodeType": "YulLiteral", - "src": "389:18:1", - "type": "", - "value": "0xffffffffffffffff" - }, - "variables": [ - { - "name": "_2", - "nativeSrc": "383:2:1", + "nativeSrc": "316:6:1", "nodeType": "YulTypedName", - "src": "383:2:1", + "src": "316:6:1", "type": "" } ] }, { "body": { - "nativeSrc": "434:16:1", + "nativeSrc": "392:16:1", "nodeType": "YulBlock", - "src": "434:16:1", + "src": "392:16:1", "statements": [ { "expression": { "arguments": [ { "kind": "number", - "nativeSrc": "443:1:1", + "nativeSrc": "401:1:1", "nodeType": "YulLiteral", - "src": "443:1:1", + "src": "401:1:1", "type": "", "value": "0" }, { "kind": "number", - "nativeSrc": "446:1:1", + "nativeSrc": "404:1:1", "nodeType": "YulLiteral", - "src": "446:1:1", + "src": "404:1:1", "type": "", "value": "0" } ], "functionName": { "name": "revert", - "nativeSrc": "436:6:1", + "nativeSrc": "394:6:1", "nodeType": "YulIdentifier", - "src": "436:6:1" + "src": "394:6:1" }, - "nativeSrc": "436:12:1", + "nativeSrc": "394:12:1", "nodeType": "YulFunctionCall", - "src": "436:12:1" + "src": "394:12:1" }, - "nativeSrc": "436:12:1", + "nativeSrc": "394:12:1", "nodeType": "YulExpressionStatement", - "src": "436:12:1" + "src": "394:12:1" } ] }, @@ -376,109 +334,111 @@ "arguments": [ { "name": "offset", - "nativeSrc": "422:6:1", + "nativeSrc": "364:6:1", "nodeType": "YulIdentifier", - "src": "422:6:1" + "src": "364:6:1" }, { - "name": "_2", - "nativeSrc": "430:2:1", - "nodeType": "YulIdentifier", - "src": "430:2:1" + "kind": "number", + "nativeSrc": "372:18:1", + "nodeType": "YulLiteral", + "src": "372:18:1", + "type": "", + "value": "0xffffffffffffffff" } ], "functionName": { "name": "gt", - "nativeSrc": "419:2:1", + "nativeSrc": "361:2:1", "nodeType": "YulIdentifier", - "src": "419:2:1" + "src": "361:2:1" }, - "nativeSrc": "419:14:1", + "nativeSrc": "361:30:1", "nodeType": "YulFunctionCall", - "src": "419:14:1" + "src": "361:30:1" }, - "nativeSrc": "416:34:1", + "nativeSrc": "358:50:1", "nodeType": "YulIf", - "src": "416:34:1" + "src": "358:50:1" }, { - "nativeSrc": "459:32:1", + "nativeSrc": "417:32:1", "nodeType": "YulVariableDeclaration", - "src": "459:32:1", + "src": "417:32:1", "value": { "arguments": [ { "name": "headStart", - "nativeSrc": "473:9:1", + "nativeSrc": "431:9:1", "nodeType": "YulIdentifier", - "src": "473:9:1" + "src": "431:9:1" }, { "name": "offset", - "nativeSrc": "484:6:1", + "nativeSrc": "442:6:1", "nodeType": "YulIdentifier", - "src": "484:6:1" + "src": "442:6:1" } ], "functionName": { "name": "add", - "nativeSrc": "469:3:1", + "nativeSrc": "427:3:1", "nodeType": "YulIdentifier", - "src": "469:3:1" + "src": "427:3:1" }, - "nativeSrc": "469:22:1", + "nativeSrc": "427:22:1", "nodeType": "YulFunctionCall", - "src": "469:22:1" + "src": "427:22:1" }, "variables": [ { - "name": "_3", - "nativeSrc": "463:2:1", + "name": "_1", + "nativeSrc": "421:2:1", "nodeType": "YulTypedName", - "src": "463:2:1", + "src": "421:2:1", "type": "" } ] }, { "body": { - "nativeSrc": "539:16:1", + "nativeSrc": "497:16:1", "nodeType": "YulBlock", - "src": "539:16:1", + "src": "497:16:1", "statements": [ { "expression": { "arguments": [ { "kind": "number", - "nativeSrc": "548:1:1", + "nativeSrc": "506:1:1", "nodeType": "YulLiteral", - "src": "548:1:1", + "src": "506:1:1", "type": "", "value": "0" }, { "kind": "number", - "nativeSrc": "551:1:1", + "nativeSrc": "509:1:1", "nodeType": "YulLiteral", - "src": "551:1:1", + "src": "509:1:1", "type": "", "value": "0" } ], "functionName": { "name": "revert", - "nativeSrc": "541:6:1", + "nativeSrc": "499:6:1", "nodeType": "YulIdentifier", - "src": "541:6:1" + "src": "499:6:1" }, - "nativeSrc": "541:12:1", + "nativeSrc": "499:12:1", "nodeType": "YulFunctionCall", - "src": "541:12:1" + "src": "499:12:1" }, - "nativeSrc": "541:12:1", + "nativeSrc": "499:12:1", "nodeType": "YulExpressionStatement", - "src": "541:12:1" + "src": "499:12:1" } ] }, @@ -489,341 +449,343 @@ { "arguments": [ { - "name": "_3", - "nativeSrc": "518:2:1", + "name": "_1", + "nativeSrc": "476:2:1", "nodeType": "YulIdentifier", - "src": "518:2:1" + "src": "476:2:1" }, { "kind": "number", - "nativeSrc": "522:4:1", + "nativeSrc": "480:4:1", "nodeType": "YulLiteral", - "src": "522:4:1", + "src": "480:4:1", "type": "", "value": "0x1f" } ], "functionName": { "name": "add", - "nativeSrc": "514:3:1", + "nativeSrc": "472:3:1", "nodeType": "YulIdentifier", - "src": "514:3:1" + "src": "472:3:1" }, - "nativeSrc": "514:13:1", + "nativeSrc": "472:13:1", "nodeType": "YulFunctionCall", - "src": "514:13:1" + "src": "472:13:1" }, { "name": "dataEnd", - "nativeSrc": "529:7:1", + "nativeSrc": "487:7:1", "nodeType": "YulIdentifier", - "src": "529:7:1" + "src": "487:7:1" } ], "functionName": { "name": "slt", - "nativeSrc": "510:3:1", + "nativeSrc": "468:3:1", "nodeType": "YulIdentifier", - "src": "510:3:1" + "src": "468:3:1" }, - "nativeSrc": "510:27:1", + "nativeSrc": "468:27:1", "nodeType": "YulFunctionCall", - "src": "510:27:1" + "src": "468:27:1" } ], "functionName": { "name": "iszero", - "nativeSrc": "503:6:1", + "nativeSrc": "461:6:1", "nodeType": "YulIdentifier", - "src": "503:6:1" + "src": "461:6:1" }, - "nativeSrc": "503:35:1", + "nativeSrc": "461:35:1", "nodeType": "YulFunctionCall", - "src": "503:35:1" + "src": "461:35:1" }, - "nativeSrc": "500:55:1", + "nativeSrc": "458:55:1", "nodeType": "YulIf", - "src": "500:55:1" + "src": "458:55:1" }, { - "nativeSrc": "564:26:1", + "nativeSrc": "522:30:1", "nodeType": "YulVariableDeclaration", - "src": "564:26:1", + "src": "522:30:1", "value": { "arguments": [ { - "name": "_3", - "nativeSrc": "587:2:1", + "name": "_1", + "nativeSrc": "549:2:1", "nodeType": "YulIdentifier", - "src": "587:2:1" + "src": "549:2:1" } ], "functionName": { "name": "calldataload", - "nativeSrc": "574:12:1", + "nativeSrc": "536:12:1", "nodeType": "YulIdentifier", - "src": "574:12:1" + "src": "536:12:1" }, - "nativeSrc": "574:16:1", + "nativeSrc": "536:16:1", "nodeType": "YulFunctionCall", - "src": "574:16:1" + "src": "536:16:1" }, "variables": [ { - "name": "_4", - "nativeSrc": "568:2:1", + "name": "length", + "nativeSrc": "526:6:1", "nodeType": "YulTypedName", - "src": "568:2:1", + "src": "526:6:1", "type": "" } ] }, { "body": { - "nativeSrc": "613:22:1", + "nativeSrc": "595:22:1", "nodeType": "YulBlock", - "src": "613:22:1", + "src": "595:22:1", "statements": [ { "expression": { "arguments": [], "functionName": { "name": "panic_error_0x41", - "nativeSrc": "615:16:1", + "nativeSrc": "597:16:1", "nodeType": "YulIdentifier", - "src": "615:16:1" + "src": "597:16:1" }, - "nativeSrc": "615:18:1", + "nativeSrc": "597:18:1", "nodeType": "YulFunctionCall", - "src": "615:18:1" + "src": "597:18:1" }, - "nativeSrc": "615:18:1", + "nativeSrc": "597:18:1", "nodeType": "YulExpressionStatement", - "src": "615:18:1" + "src": "597:18:1" } ] }, "condition": { "arguments": [ { - "name": "_4", - "nativeSrc": "605:2:1", + "name": "length", + "nativeSrc": "567:6:1", "nodeType": "YulIdentifier", - "src": "605:2:1" + "src": "567:6:1" }, { - "name": "_2", - "nativeSrc": "609:2:1", - "nodeType": "YulIdentifier", - "src": "609:2:1" + "kind": "number", + "nativeSrc": "575:18:1", + "nodeType": "YulLiteral", + "src": "575:18:1", + "type": "", + "value": "0xffffffffffffffff" } ], "functionName": { "name": "gt", - "nativeSrc": "602:2:1", + "nativeSrc": "564:2:1", "nodeType": "YulIdentifier", - "src": "602:2:1" + "src": "564:2:1" }, - "nativeSrc": "602:10:1", + "nativeSrc": "564:30:1", "nodeType": "YulFunctionCall", - "src": "602:10:1" + "src": "564:30:1" }, - "nativeSrc": "599:36:1", + "nativeSrc": "561:56:1", "nodeType": "YulIf", - "src": "599:36:1" + "src": "561:56:1" }, { - "nativeSrc": "644:20:1", + "nativeSrc": "626:24:1", "nodeType": "YulVariableDeclaration", - "src": "644:20:1", + "src": "626:24:1", "value": { "arguments": [ { "kind": "number", - "nativeSrc": "658:1:1", + "nativeSrc": "640:1:1", "nodeType": "YulLiteral", - "src": "658:1:1", + "src": "640:1:1", "type": "", "value": "5" }, { - "name": "_4", - "nativeSrc": "661:2:1", + "name": "length", + "nativeSrc": "643:6:1", "nodeType": "YulIdentifier", - "src": "661:2:1" + "src": "643:6:1" } ], "functionName": { "name": "shl", - "nativeSrc": "654:3:1", + "nativeSrc": "636:3:1", "nodeType": "YulIdentifier", - "src": "654:3:1" + "src": "636:3:1" }, - "nativeSrc": "654:10:1", + "nativeSrc": "636:14:1", "nodeType": "YulFunctionCall", - "src": "654:10:1" + "src": "636:14:1" }, "variables": [ { - "name": "_5", - "nativeSrc": "648:2:1", + "name": "_2", + "nativeSrc": "630:2:1", "nodeType": "YulTypedName", - "src": "648:2:1", + "src": "630:2:1", "type": "" } ] }, { - "nativeSrc": "673:23:1", + "nativeSrc": "659:23:1", "nodeType": "YulVariableDeclaration", - "src": "673:23:1", + "src": "659:23:1", "value": { "arguments": [ { "kind": "number", - "nativeSrc": "693:2:1", + "nativeSrc": "679:2:1", "nodeType": "YulLiteral", - "src": "693:2:1", + "src": "679:2:1", "type": "", "value": "64" } ], "functionName": { "name": "mload", - "nativeSrc": "687:5:1", + "nativeSrc": "673:5:1", "nodeType": "YulIdentifier", - "src": "687:5:1" + "src": "673:5:1" }, - "nativeSrc": "687:9:1", + "nativeSrc": "673:9:1", "nodeType": "YulFunctionCall", - "src": "687:9:1" + "src": "673:9:1" }, "variables": [ { "name": "memPtr", - "nativeSrc": "677:6:1", + "nativeSrc": "663:6:1", "nodeType": "YulTypedName", - "src": "677:6:1", + "src": "663:6:1", "type": "" } ] }, { - "nativeSrc": "705:56:1", + "nativeSrc": "691:56:1", "nodeType": "YulVariableDeclaration", - "src": "705:56:1", + "src": "691:56:1", "value": { "arguments": [ { "name": "memPtr", - "nativeSrc": "727:6:1", + "nativeSrc": "713:6:1", "nodeType": "YulIdentifier", - "src": "727:6:1" + "src": "713:6:1" }, { "arguments": [ { "arguments": [ { - "name": "_5", - "nativeSrc": "743:2:1", + "name": "_2", + "nativeSrc": "729:2:1", "nodeType": "YulIdentifier", - "src": "743:2:1" + "src": "729:2:1" }, { "kind": "number", - "nativeSrc": "747:2:1", + "nativeSrc": "733:2:1", "nodeType": "YulLiteral", - "src": "747:2:1", + "src": "733:2:1", "type": "", "value": "63" } ], "functionName": { "name": "add", - "nativeSrc": "739:3:1", + "nativeSrc": "725:3:1", "nodeType": "YulIdentifier", - "src": "739:3:1" + "src": "725:3:1" }, - "nativeSrc": "739:11:1", + "nativeSrc": "725:11:1", "nodeType": "YulFunctionCall", - "src": "739:11:1" + "src": "725:11:1" }, { "arguments": [ { "kind": "number", - "nativeSrc": "756:2:1", + "nativeSrc": "742:2:1", "nodeType": "YulLiteral", - "src": "756:2:1", + "src": "742:2:1", "type": "", "value": "31" } ], "functionName": { "name": "not", - "nativeSrc": "752:3:1", + "nativeSrc": "738:3:1", "nodeType": "YulIdentifier", - "src": "752:3:1" + "src": "738:3:1" }, - "nativeSrc": "752:7:1", + "nativeSrc": "738:7:1", "nodeType": "YulFunctionCall", - "src": "752:7:1" + "src": "738:7:1" } ], "functionName": { "name": "and", - "nativeSrc": "735:3:1", + "nativeSrc": "721:3:1", "nodeType": "YulIdentifier", - "src": "735:3:1" + "src": "721:3:1" }, - "nativeSrc": "735:25:1", + "nativeSrc": "721:25:1", "nodeType": "YulFunctionCall", - "src": "735:25:1" + "src": "721:25:1" } ], "functionName": { "name": "add", - "nativeSrc": "723:3:1", + "nativeSrc": "709:3:1", "nodeType": "YulIdentifier", - "src": "723:3:1" + "src": "709:3:1" }, - "nativeSrc": "723:38:1", + "nativeSrc": "709:38:1", "nodeType": "YulFunctionCall", - "src": "723:38:1" + "src": "709:38:1" }, "variables": [ { "name": "newFreePtr", - "nativeSrc": "709:10:1", + "nativeSrc": "695:10:1", "nodeType": "YulTypedName", - "src": "709:10:1", + "src": "695:10:1", "type": "" } ] }, { "body": { - "nativeSrc": "820:22:1", + "nativeSrc": "822:22:1", "nodeType": "YulBlock", - "src": "820:22:1", + "src": "822:22:1", "statements": [ { "expression": { "arguments": [], "functionName": { "name": "panic_error_0x41", - "nativeSrc": "822:16:1", + "nativeSrc": "824:16:1", "nodeType": "YulIdentifier", - "src": "822:16:1" + "src": "824:16:1" }, - "nativeSrc": "822:18:1", + "nativeSrc": "824:18:1", "nodeType": "YulFunctionCall", - "src": "822:18:1" + "src": "824:18:1" }, - "nativeSrc": "822:18:1", + "nativeSrc": "824:18:1", "nodeType": "YulExpressionStatement", - "src": "822:18:1" + "src": "824:18:1" } ] }, @@ -833,115 +795,117 @@ "arguments": [ { "name": "newFreePtr", - "nativeSrc": "779:10:1", + "nativeSrc": "765:10:1", "nodeType": "YulIdentifier", - "src": "779:10:1" + "src": "765:10:1" }, { - "name": "_2", - "nativeSrc": "791:2:1", - "nodeType": "YulIdentifier", - "src": "791:2:1" + "kind": "number", + "nativeSrc": "777:18:1", + "nodeType": "YulLiteral", + "src": "777:18:1", + "type": "", + "value": "0xffffffffffffffff" } ], "functionName": { "name": "gt", - "nativeSrc": "776:2:1", + "nativeSrc": "762:2:1", "nodeType": "YulIdentifier", - "src": "776:2:1" + "src": "762:2:1" }, - "nativeSrc": "776:18:1", + "nativeSrc": "762:34:1", "nodeType": "YulFunctionCall", - "src": "776:18:1" + "src": "762:34:1" }, { "arguments": [ { "name": "newFreePtr", - "nativeSrc": "799:10:1", + "nativeSrc": "801:10:1", "nodeType": "YulIdentifier", - "src": "799:10:1" + "src": "801:10:1" }, { "name": "memPtr", - "nativeSrc": "811:6:1", + "nativeSrc": "813:6:1", "nodeType": "YulIdentifier", - "src": "811:6:1" + "src": "813:6:1" } ], "functionName": { "name": "lt", - "nativeSrc": "796:2:1", + "nativeSrc": "798:2:1", "nodeType": "YulIdentifier", - "src": "796:2:1" + "src": "798:2:1" }, - "nativeSrc": "796:22:1", + "nativeSrc": "798:22:1", "nodeType": "YulFunctionCall", - "src": "796:22:1" + "src": "798:22:1" } ], "functionName": { "name": "or", - "nativeSrc": "773:2:1", + "nativeSrc": "759:2:1", "nodeType": "YulIdentifier", - "src": "773:2:1" + "src": "759:2:1" }, - "nativeSrc": "773:46:1", + "nativeSrc": "759:62:1", "nodeType": "YulFunctionCall", - "src": "773:46:1" + "src": "759:62:1" }, - "nativeSrc": "770:72:1", + "nativeSrc": "756:88:1", "nodeType": "YulIf", - "src": "770:72:1" + "src": "756:88:1" }, { "expression": { "arguments": [ { "kind": "number", - "nativeSrc": "858:2:1", + "nativeSrc": "860:2:1", "nodeType": "YulLiteral", - "src": "858:2:1", + "src": "860:2:1", "type": "", "value": "64" }, { "name": "newFreePtr", - "nativeSrc": "862:10:1", + "nativeSrc": "864:10:1", "nodeType": "YulIdentifier", - "src": "862:10:1" + "src": "864:10:1" } ], "functionName": { "name": "mstore", - "nativeSrc": "851:6:1", + "nativeSrc": "853:6:1", "nodeType": "YulIdentifier", - "src": "851:6:1" + "src": "853:6:1" }, - "nativeSrc": "851:22:1", + "nativeSrc": "853:22:1", "nodeType": "YulFunctionCall", - "src": "851:22:1" + "src": "853:22:1" }, - "nativeSrc": "851:22:1", + "nativeSrc": "853:22:1", "nodeType": "YulExpressionStatement", - "src": "851:22:1" + "src": "853:22:1" }, { - "nativeSrc": "882:17:1", + "nativeSrc": "884:17:1", "nodeType": "YulVariableDeclaration", - "src": "882:17:1", + "src": "884:17:1", "value": { "name": "memPtr", - "nativeSrc": "893:6:1", + "nativeSrc": "895:6:1", "nodeType": "YulIdentifier", - "src": "893:6:1" + "src": "895:6:1" }, "variables": [ { "name": "dst", - "nativeSrc": "886:3:1", + "nativeSrc": "888:3:1", "nodeType": "YulTypedName", - "src": "886:3:1", + "src": "888:3:1", "type": "" } ] @@ -951,166 +915,170 @@ "arguments": [ { "name": "memPtr", - "nativeSrc": "915:6:1", + "nativeSrc": "917:6:1", "nodeType": "YulIdentifier", - "src": "915:6:1" + "src": "917:6:1" }, { - "name": "_4", - "nativeSrc": "923:2:1", + "name": "length", + "nativeSrc": "925:6:1", "nodeType": "YulIdentifier", - "src": "923:2:1" + "src": "925:6:1" } ], "functionName": { "name": "mstore", - "nativeSrc": "908:6:1", + "nativeSrc": "910:6:1", "nodeType": "YulIdentifier", - "src": "908:6:1" + "src": "910:6:1" }, - "nativeSrc": "908:18:1", + "nativeSrc": "910:22:1", "nodeType": "YulFunctionCall", - "src": "908:18:1" + "src": "910:22:1" }, - "nativeSrc": "908:18:1", + "nativeSrc": "910:22:1", "nodeType": "YulExpressionStatement", - "src": "908:18:1" + "src": "910:22:1" }, { - "nativeSrc": "935:22:1", + "nativeSrc": "941:22:1", "nodeType": "YulAssignment", - "src": "935:22:1", + "src": "941:22:1", "value": { "arguments": [ { "name": "memPtr", - "nativeSrc": "946:6:1", + "nativeSrc": "952:6:1", "nodeType": "YulIdentifier", - "src": "946:6:1" + "src": "952:6:1" }, { - "name": "_1", - "nativeSrc": "954:2:1", - "nodeType": "YulIdentifier", - "src": "954:2:1" + "kind": "number", + "nativeSrc": "960:2:1", + "nodeType": "YulLiteral", + "src": "960:2:1", + "type": "", + "value": "32" } ], "functionName": { "name": "add", - "nativeSrc": "942:3:1", + "nativeSrc": "948:3:1", "nodeType": "YulIdentifier", - "src": "942:3:1" + "src": "948:3:1" }, - "nativeSrc": "942:15:1", + "nativeSrc": "948:15:1", "nodeType": "YulFunctionCall", - "src": "942:15:1" + "src": "948:15:1" }, "variableNames": [ { "name": "dst", - "nativeSrc": "935:3:1", + "nativeSrc": "941:3:1", "nodeType": "YulIdentifier", - "src": "935:3:1" + "src": "941:3:1" } ] }, { - "nativeSrc": "966:34:1", + "nativeSrc": "972:34:1", "nodeType": "YulVariableDeclaration", - "src": "966:34:1", + "src": "972:34:1", "value": { "arguments": [ { "arguments": [ { - "name": "_3", - "nativeSrc": "988:2:1", + "name": "_1", + "nativeSrc": "994:2:1", "nodeType": "YulIdentifier", - "src": "988:2:1" + "src": "994:2:1" }, { - "name": "_5", - "nativeSrc": "992:2:1", + "name": "_2", + "nativeSrc": "998:2:1", "nodeType": "YulIdentifier", - "src": "992:2:1" + "src": "998:2:1" } ], "functionName": { "name": "add", - "nativeSrc": "984:3:1", + "nativeSrc": "990:3:1", "nodeType": "YulIdentifier", - "src": "984:3:1" + "src": "990:3:1" }, - "nativeSrc": "984:11:1", + "nativeSrc": "990:11:1", "nodeType": "YulFunctionCall", - "src": "984:11:1" + "src": "990:11:1" }, { - "name": "_1", - "nativeSrc": "997:2:1", - "nodeType": "YulIdentifier", - "src": "997:2:1" + "kind": "number", + "nativeSrc": "1003:2:1", + "nodeType": "YulLiteral", + "src": "1003:2:1", + "type": "", + "value": "32" } ], "functionName": { "name": "add", - "nativeSrc": "980:3:1", + "nativeSrc": "986:3:1", "nodeType": "YulIdentifier", - "src": "980:3:1" + "src": "986:3:1" }, - "nativeSrc": "980:20:1", + "nativeSrc": "986:20:1", "nodeType": "YulFunctionCall", - "src": "980:20:1" + "src": "986:20:1" }, "variables": [ { "name": "srcEnd", - "nativeSrc": "970:6:1", + "nativeSrc": "976:6:1", "nodeType": "YulTypedName", - "src": "970:6:1", + "src": "976:6:1", "type": "" } ] }, { "body": { - "nativeSrc": "1032:16:1", + "nativeSrc": "1038:16:1", "nodeType": "YulBlock", - "src": "1032:16:1", + "src": "1038:16:1", "statements": [ { "expression": { "arguments": [ { "kind": "number", - "nativeSrc": "1041:1:1", + "nativeSrc": "1047:1:1", "nodeType": "YulLiteral", - "src": "1041:1:1", + "src": "1047:1:1", "type": "", "value": "0" }, { "kind": "number", - "nativeSrc": "1044:1:1", + "nativeSrc": "1050:1:1", "nodeType": "YulLiteral", - "src": "1044:1:1", + "src": "1050:1:1", "type": "", "value": "0" } ], "functionName": { "name": "revert", - "nativeSrc": "1034:6:1", + "nativeSrc": "1040:6:1", "nodeType": "YulIdentifier", - "src": "1034:6:1" + "src": "1040:6:1" }, - "nativeSrc": "1034:12:1", + "nativeSrc": "1040:12:1", "nodeType": "YulFunctionCall", - "src": "1034:12:1" + "src": "1040:12:1" }, - "nativeSrc": "1034:12:1", + "nativeSrc": "1040:12:1", "nodeType": "YulExpressionStatement", - "src": "1034:12:1" + "src": "1040:12:1" } ] }, @@ -1118,154 +1086,199 @@ "arguments": [ { "name": "srcEnd", - "nativeSrc": "1015:6:1", + "nativeSrc": "1021:6:1", "nodeType": "YulIdentifier", - "src": "1015:6:1" + "src": "1021:6:1" }, { "name": "dataEnd", - "nativeSrc": "1023:7:1", + "nativeSrc": "1029:7:1", "nodeType": "YulIdentifier", - "src": "1023:7:1" + "src": "1029:7:1" } ], "functionName": { "name": "gt", - "nativeSrc": "1012:2:1", + "nativeSrc": "1018:2:1", "nodeType": "YulIdentifier", - "src": "1012:2:1" + "src": "1018:2:1" }, - "nativeSrc": "1012:19:1", + "nativeSrc": "1018:19:1", "nodeType": "YulFunctionCall", - "src": "1012:19:1" + "src": "1018:19:1" }, - "nativeSrc": "1009:39:1", + "nativeSrc": "1015:39:1", "nodeType": "YulIf", - "src": "1009:39:1" + "src": "1015:39:1" }, { - "nativeSrc": "1057:22:1", + "nativeSrc": "1063:22:1", "nodeType": "YulVariableDeclaration", - "src": "1057:22:1", + "src": "1063:22:1", "value": { "arguments": [ { - "name": "_3", - "nativeSrc": "1072:2:1", + "name": "_1", + "nativeSrc": "1078:2:1", "nodeType": "YulIdentifier", - "src": "1072:2:1" + "src": "1078:2:1" }, { - "name": "_1", - "nativeSrc": "1076:2:1", - "nodeType": "YulIdentifier", - "src": "1076:2:1" + "kind": "number", + "nativeSrc": "1082:2:1", + "nodeType": "YulLiteral", + "src": "1082:2:1", + "type": "", + "value": "32" } ], "functionName": { "name": "add", - "nativeSrc": "1068:3:1", + "nativeSrc": "1074:3:1", "nodeType": "YulIdentifier", - "src": "1068:3:1" + "src": "1074:3:1" }, - "nativeSrc": "1068:11:1", + "nativeSrc": "1074:11:1", "nodeType": "YulFunctionCall", - "src": "1068:11:1" + "src": "1074:11:1" }, "variables": [ { "name": "src", - "nativeSrc": "1061:3:1", + "nativeSrc": "1067:3:1", "nodeType": "YulTypedName", - "src": "1061:3:1", + "src": "1067:3:1", "type": "" } ] }, { "body": { - "nativeSrc": "1144:86:1", + "nativeSrc": "1150:140:1", "nodeType": "YulBlock", - "src": "1144:86:1", + "src": "1150:140:1", "statements": [ + { + "nativeSrc": "1164:14:1", + "nodeType": "YulVariableDeclaration", + "src": "1164:14:1", + "value": { + "kind": "number", + "nativeSrc": "1177:1:1", + "nodeType": "YulLiteral", + "src": "1177:1:1", + "type": "", + "value": "0" + }, + "variables": [ + { + "name": "value", + "nativeSrc": "1168:5:1", + "nodeType": "YulTypedName", + "src": "1168:5:1", + "type": "" + } + ] + }, + { + "nativeSrc": "1191:26:1", + "nodeType": "YulAssignment", + "src": "1191:26:1", + "value": { + "arguments": [ + { + "name": "src", + "nativeSrc": "1213:3:1", + "nodeType": "YulIdentifier", + "src": "1213:3:1" + } + ], + "functionName": { + "name": "calldataload", + "nativeSrc": "1200:12:1", + "nodeType": "YulIdentifier", + "src": "1200:12:1" + }, + "nativeSrc": "1200:17:1", + "nodeType": "YulFunctionCall", + "src": "1200:17:1" + }, + "variableNames": [ + { + "name": "value", + "nativeSrc": "1191:5:1", + "nodeType": "YulIdentifier", + "src": "1191:5:1" + } + ] + }, { "expression": { "arguments": [ { "name": "dst", - "nativeSrc": "1165:3:1", + "nativeSrc": "1237:3:1", "nodeType": "YulIdentifier", - "src": "1165:3:1" + "src": "1237:3:1" }, { - "arguments": [ - { - "name": "src", - "nativeSrc": "1183:3:1", - "nodeType": "YulIdentifier", - "src": "1183:3:1" - } - ], - "functionName": { - "name": "calldataload", - "nativeSrc": "1170:12:1", - "nodeType": "YulIdentifier", - "src": "1170:12:1" - }, - "nativeSrc": "1170:17:1", - "nodeType": "YulFunctionCall", - "src": "1170:17:1" + "name": "value", + "nativeSrc": "1242:5:1", + "nodeType": "YulIdentifier", + "src": "1242:5:1" } ], "functionName": { "name": "mstore", - "nativeSrc": "1158:6:1", + "nativeSrc": "1230:6:1", "nodeType": "YulIdentifier", - "src": "1158:6:1" + "src": "1230:6:1" }, - "nativeSrc": "1158:30:1", + "nativeSrc": "1230:18:1", "nodeType": "YulFunctionCall", - "src": "1158:30:1" + "src": "1230:18:1" }, - "nativeSrc": "1158:30:1", + "nativeSrc": "1230:18:1", "nodeType": "YulExpressionStatement", - "src": "1158:30:1" + "src": "1230:18:1" }, { - "nativeSrc": "1201:19:1", + "nativeSrc": "1261:19:1", "nodeType": "YulAssignment", - "src": "1201:19:1", + "src": "1261:19:1", "value": { "arguments": [ { "name": "dst", - "nativeSrc": "1212:3:1", + "nativeSrc": "1272:3:1", "nodeType": "YulIdentifier", - "src": "1212:3:1" + "src": "1272:3:1" }, { - "name": "_1", - "nativeSrc": "1217:2:1", - "nodeType": "YulIdentifier", - "src": "1217:2:1" + "kind": "number", + "nativeSrc": "1277:2:1", + "nodeType": "YulLiteral", + "src": "1277:2:1", + "type": "", + "value": "32" } ], "functionName": { "name": "add", - "nativeSrc": "1208:3:1", + "nativeSrc": "1268:3:1", "nodeType": "YulIdentifier", - "src": "1208:3:1" + "src": "1268:3:1" }, - "nativeSrc": "1208:12:1", + "nativeSrc": "1268:12:1", "nodeType": "YulFunctionCall", - "src": "1208:12:1" + "src": "1268:12:1" }, "variableNames": [ { "name": "dst", - "nativeSrc": "1201:3:1", + "nativeSrc": "1261:3:1", "nodeType": "YulIdentifier", - "src": "1201:3:1" + "src": "1261:3:1" } ] } @@ -1275,105 +1288,107 @@ "arguments": [ { "name": "src", - "nativeSrc": "1099:3:1", + "nativeSrc": "1105:3:1", "nodeType": "YulIdentifier", - "src": "1099:3:1" + "src": "1105:3:1" }, { "name": "srcEnd", - "nativeSrc": "1104:6:1", + "nativeSrc": "1110:6:1", "nodeType": "YulIdentifier", - "src": "1104:6:1" + "src": "1110:6:1" } ], "functionName": { "name": "lt", - "nativeSrc": "1096:2:1", + "nativeSrc": "1102:2:1", "nodeType": "YulIdentifier", - "src": "1096:2:1" + "src": "1102:2:1" }, - "nativeSrc": "1096:15:1", + "nativeSrc": "1102:15:1", "nodeType": "YulFunctionCall", - "src": "1096:15:1" + "src": "1102:15:1" }, - "nativeSrc": "1088:142:1", + "nativeSrc": "1094:196:1", "nodeType": "YulForLoop", "post": { - "nativeSrc": "1112:23:1", + "nativeSrc": "1118:23:1", "nodeType": "YulBlock", - "src": "1112:23:1", + "src": "1118:23:1", "statements": [ { - "nativeSrc": "1114:19:1", + "nativeSrc": "1120:19:1", "nodeType": "YulAssignment", - "src": "1114:19:1", + "src": "1120:19:1", "value": { "arguments": [ { "name": "src", - "nativeSrc": "1125:3:1", + "nativeSrc": "1131:3:1", "nodeType": "YulIdentifier", - "src": "1125:3:1" + "src": "1131:3:1" }, { - "name": "_1", - "nativeSrc": "1130:2:1", - "nodeType": "YulIdentifier", - "src": "1130:2:1" + "kind": "number", + "nativeSrc": "1136:2:1", + "nodeType": "YulLiteral", + "src": "1136:2:1", + "type": "", + "value": "32" } ], "functionName": { "name": "add", - "nativeSrc": "1121:3:1", + "nativeSrc": "1127:3:1", "nodeType": "YulIdentifier", - "src": "1121:3:1" + "src": "1127:3:1" }, - "nativeSrc": "1121:12:1", + "nativeSrc": "1127:12:1", "nodeType": "YulFunctionCall", - "src": "1121:12:1" + "src": "1127:12:1" }, "variableNames": [ { "name": "src", - "nativeSrc": "1114:3:1", + "nativeSrc": "1120:3:1", "nodeType": "YulIdentifier", - "src": "1114:3:1" + "src": "1120:3:1" } ] } ] }, "pre": { - "nativeSrc": "1092:3:1", + "nativeSrc": "1098:3:1", "nodeType": "YulBlock", - "src": "1092:3:1", + "src": "1098:3:1", "statements": [] }, - "src": "1088:142:1" + "src": "1094:196:1" }, { - "nativeSrc": "1239:16:1", + "nativeSrc": "1299:16:1", "nodeType": "YulAssignment", - "src": "1239:16:1", + "src": "1299:16:1", "value": { "name": "memPtr", - "nativeSrc": "1249:6:1", + "nativeSrc": "1309:6:1", "nodeType": "YulIdentifier", - "src": "1249:6:1" + "src": "1309:6:1" }, "variableNames": [ { "name": "value0", - "nativeSrc": "1239:6:1", + "nativeSrc": "1299:6:1", "nodeType": "YulIdentifier", - "src": "1239:6:1" + "src": "1299:6:1" } ] } ] }, "name": "abi_decode_tuple_t_array$_t_uint256_$dyn_memory_ptr", - "nativeSrc": "146:1115:1", + "nativeSrc": "146:1175:1", "nodeType": "YulFunctionDefinition", "parameters": [ { @@ -1400,51 +1415,51 @@ "type": "" } ], - "src": "146:1115:1" + "src": "146:1175:1" }, { "body": { - "nativeSrc": "1367:76:1", + "nativeSrc": "1427:76:1", "nodeType": "YulBlock", - "src": "1367:76:1", + "src": "1427:76:1", "statements": [ { - "nativeSrc": "1377:26:1", + "nativeSrc": "1437:26:1", "nodeType": "YulAssignment", - "src": "1377:26:1", + "src": "1437:26:1", "value": { "arguments": [ { "name": "headStart", - "nativeSrc": "1389:9:1", + "nativeSrc": "1449:9:1", "nodeType": "YulIdentifier", - "src": "1389:9:1" + "src": "1449:9:1" }, { "kind": "number", - "nativeSrc": "1400:2:1", + "nativeSrc": "1460:2:1", "nodeType": "YulLiteral", - "src": "1400:2:1", + "src": "1460:2:1", "type": "", "value": "32" } ], "functionName": { "name": "add", - "nativeSrc": "1385:3:1", + "nativeSrc": "1445:3:1", "nodeType": "YulIdentifier", - "src": "1385:3:1" + "src": "1445:3:1" }, - "nativeSrc": "1385:18:1", + "nativeSrc": "1445:18:1", "nodeType": "YulFunctionCall", - "src": "1385:18:1" + "src": "1445:18:1" }, "variableNames": [ { "name": "tail", - "nativeSrc": "1377:4:1", + "nativeSrc": "1437:4:1", "nodeType": "YulIdentifier", - "src": "1377:4:1" + "src": "1437:4:1" } ] }, @@ -1453,62 +1468,62 @@ "arguments": [ { "name": "headStart", - "nativeSrc": "1419:9:1", + "nativeSrc": "1479:9:1", "nodeType": "YulIdentifier", - "src": "1419:9:1" + "src": "1479:9:1" }, { "name": "value0", - "nativeSrc": "1430:6:1", + "nativeSrc": "1490:6:1", "nodeType": "YulIdentifier", - "src": "1430:6:1" + "src": "1490:6:1" } ], "functionName": { "name": "mstore", - "nativeSrc": "1412:6:1", + "nativeSrc": "1472:6:1", "nodeType": "YulIdentifier", - "src": "1412:6:1" + "src": "1472:6:1" }, - "nativeSrc": "1412:25:1", + "nativeSrc": "1472:25:1", "nodeType": "YulFunctionCall", - "src": "1412:25:1" + "src": "1472:25:1" }, - "nativeSrc": "1412:25:1", + "nativeSrc": "1472:25:1", "nodeType": "YulExpressionStatement", - "src": "1412:25:1" + "src": "1472:25:1" } ] }, "name": "abi_encode_tuple_t_uint256__to_t_uint256__fromStack_reversed", - "nativeSrc": "1266:177:1", + "nativeSrc": "1326:177:1", "nodeType": "YulFunctionDefinition", "parameters": [ { "name": "headStart", - "nativeSrc": "1336:9:1", + "nativeSrc": "1396:9:1", "nodeType": "YulTypedName", - "src": "1336:9:1", + "src": "1396:9:1", "type": "" }, { "name": "value0", - "nativeSrc": "1347:6:1", + "nativeSrc": "1407:6:1", "nodeType": "YulTypedName", - "src": "1347:6:1", + "src": "1407:6:1", "type": "" } ], "returnVariables": [ { "name": "tail", - "nativeSrc": "1358:4:1", + "nativeSrc": "1418:4:1", "nodeType": "YulTypedName", - "src": "1358:4:1", + "src": "1418:4:1", "type": "" } ], - "src": "1266:177:1" + "src": "1326:177:1" } ] }, @@ -1522,30 +1537,30 @@ } function abi_decode_tuple_t_array$_t_uint256_$dyn_memory_ptr(headStart, dataEnd) -> value0 { - let _1 := 32 - if slt(sub(dataEnd, headStart), _1) { revert(0, 0) } + if slt(sub(dataEnd, headStart), 32) { revert(0, 0) } let offset := calldataload(headStart) - let _2 := 0xffffffffffffffff - if gt(offset, _2) { revert(0, 0) } - let _3 := add(headStart, offset) - if iszero(slt(add(_3, 0x1f), dataEnd)) { revert(0, 0) } - let _4 := calldataload(_3) - if gt(_4, _2) { panic_error_0x41() } - let _5 := shl(5, _4) + if gt(offset, 0xffffffffffffffff) { revert(0, 0) } + let _1 := add(headStart, offset) + if iszero(slt(add(_1, 0x1f), dataEnd)) { revert(0, 0) } + let length := calldataload(_1) + if gt(length, 0xffffffffffffffff) { panic_error_0x41() } + let _2 := shl(5, length) let memPtr := mload(64) - let newFreePtr := add(memPtr, and(add(_5, 63), not(31))) - if or(gt(newFreePtr, _2), lt(newFreePtr, memPtr)) { panic_error_0x41() } + let newFreePtr := add(memPtr, and(add(_2, 63), not(31))) + if or(gt(newFreePtr, 0xffffffffffffffff), lt(newFreePtr, memPtr)) { panic_error_0x41() } mstore(64, newFreePtr) let dst := memPtr - mstore(memPtr, _4) - dst := add(memPtr, _1) - let srcEnd := add(add(_3, _5), _1) + mstore(memPtr, length) + dst := add(memPtr, 32) + let srcEnd := add(add(_1, _2), 32) if gt(srcEnd, dataEnd) { revert(0, 0) } - let src := add(_3, _1) - for { } lt(src, srcEnd) { src := add(src, _1) } + let src := add(_1, 32) + for { } lt(src, srcEnd) { src := add(src, 32) } { - mstore(dst, calldataload(src)) - dst := add(dst, _1) + let value := 0 + value := calldataload(src) + mstore(dst, value) + dst := add(dst, 32) } value0 := memPtr } diff --git a/test/cmdlineTests/viair_subobject_optimization/output b/test/cmdlineTests/viair_subobject_optimization/output index 5090c282bb24..dafba2771c5d 100644 --- a/test/cmdlineTests/viair_subobject_optimization/output +++ b/test/cmdlineTests/viair_subobject_optimization/output @@ -119,53 +119,50 @@ sub_0: assembly { jumpi(tag_7, slt(add(not(0x03), calldatasize), 0x00)) /* "viair_subobject_optimization/input.sol":745:765 type(C).creationCode */ dataSize(sub_0) - /* "viair_subobject_optimization/input.sol":669:772 contract D {... */ - swap1 - not(0x1f) swap1 - dup2 + /* "viair_subobject_optimization/input.sol":669:772 contract D {... */ 0x3f - dup5 + dup3 add + not(0x1f) and dup2 add - swap2 + swap1 + 0xffffffffffffffff + dup3 + gt dup2 dup4 lt - 0xffffffffffffffff - dup5 - gt or tag_9 jumpi 0x40 - swap3 - dup4 + swap2 + dup3 mstore /* "viair_subobject_optimization/input.sol":745:765 type(C).creationCode */ - dup4 dup3 + dup2 mstore 0x20 - dup3 + dup2 add - swap4 + swap3 dataOffset(sub_0) - dup6 + dup5 codecopy /* "viair_subobject_optimization/input.sol":669:772 contract D {... */ - 0x1f - dup4 + dup2 mload - swap5 - dup6 - swap4 + swap3 + dup4 + swap2 /* "viair_subobject_optimization/input.sol":745:765 type(C).creationCode */ 0x20 /* "viair_subobject_optimization/input.sol":669:772 contract D {... */ - dup6 + dup4 mstore mload dup1 @@ -174,21 +171,23 @@ sub_0: assembly { /* "viair_subobject_optimization/input.sol":745:765 type(C).creationCode */ 0x20 /* "viair_subobject_optimization/input.sol":669:772 contract D {... */ - dup8 + dup6 add mstore - dup7 - dup7 + dup5 + dup5 add mcopy 0x00 - dup6 dup3 - dup7 + dup3 add + dup5 add mstore + 0x1f add + not(0x1f) and dup2 add diff --git a/test/libsolidity/syntaxTests/sizeLimits/combined_too_large_paris.sol b/test/libsolidity/syntaxTests/sizeLimits/combined_too_large_paris.sol index 0a97c87dfa9c..82a3415d0cbe 100644 --- a/test/libsolidity/syntaxTests/sizeLimits/combined_too_large_paris.sol +++ b/test/libsolidity/syntaxTests/sizeLimits/combined_too_large_paris.sol @@ -26,6 +26,6 @@ contract test { // ==== // EVMVersion: =paris // ---- -// Warning 5574: (0-27130): Contract code size is 27193 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. -// Warning 5574: (27132-27224): Contract code size is 27219 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. -// Warning 5574: (27226-27319): Contract code size is 27219 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. +// Warning 5574: (0-27130): Contract code size is 27192 bytes and exceeds 24576 bytes (a limit introduced in Spurious Dragon). This contract may not be deployable on Mainnet. Consider enabling the optimizer (with a low "runs" value!), turning off revert strings, or using libraries. +// Warning 5574: (27132-27224): Contract code size is 27218 bytes and exceeds 24576 bytes (a limit introduced in Spurious Dragon). This contract may not be deployable on Mainnet. Consider enabling the optimizer (with a low "runs" value!), turning off revert strings, or using libraries. +// Warning 5574: (27226-27319): Contract code size is 27218 bytes and exceeds 24576 bytes (a limit introduced in Spurious Dragon). This contract may not be deployable on Mainnet. Consider enabling the optimizer (with a low "runs" value!), turning off revert strings, or using libraries. diff --git a/test/libsolidity/syntaxTests/sizeLimits/combined_too_large_shanghai.sol b/test/libsolidity/syntaxTests/sizeLimits/combined_too_large_shanghai.sol index 32e8d9133be2..dd0122971d8e 100644 --- a/test/libsolidity/syntaxTests/sizeLimits/combined_too_large_shanghai.sol +++ b/test/libsolidity/syntaxTests/sizeLimits/combined_too_large_shanghai.sol @@ -26,7 +26,7 @@ contract test { // ==== // EVMVersion: =shanghai // ---- -// Warning 5574: (0-27130): Contract code size is 27187 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. -// Warning 5574: (27132-27224): Contract code size is 27213 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. -// Warning 5574: (27226-27319): Contract code size is 27212 bytes and exceeds 24576 bytes (a limit introduced in Spurious Dragon). This contract may not be deployable on Mainnet. Consider enabling the optimizer (with a low "runs" value!), turning off revert strings, or using libraries. -// Warning 3860: (27321-27398): Contract initcode size is 54618 bytes and exceeds 49152 bytes (a limit introduced in Shanghai). This contract may not be deployable on Mainnet. Consider enabling the optimizer (with a low "runs" value!), turning off revert strings, or using libraries. +// Warning 5574: (0-27130): Contract code size is 27186 bytes and exceeds 24576 bytes (a limit introduced in Spurious Dragon). This contract may not be deployable on Mainnet. Consider enabling the optimizer (with a low "runs" value!), turning off revert strings, or using libraries. +// Warning 5574: (27132-27224): Contract code size is 27212 bytes and exceeds 24576 bytes (a limit introduced in Spurious Dragon). This contract may not be deployable on Mainnet. Consider enabling the optimizer (with a low "runs" value!), turning off revert strings, or using libraries. +// Warning 5574: (27226-27319): Contract code size is 27211 bytes and exceeds 24576 bytes (a limit introduced in Spurious Dragon). This contract may not be deployable on Mainnet. Consider enabling the optimizer (with a low "runs" value!), turning off revert strings, or using libraries. +// Warning 3860: (27321-27398): Contract initcode size is 54616 bytes and exceeds 49152 bytes (a limit introduced in Shanghai). This contract may not be deployable on Mainnet. Consider enabling the optimizer (with a low "runs" value!), turning off revert strings, or using libraries. diff --git a/test/libsolidity/syntaxTests/sizeLimits/initcode_too_large_shanghai.sol b/test/libsolidity/syntaxTests/sizeLimits/initcode_too_large_shanghai.sol index d48693db05b1..15273c66a7c0 100644 --- a/test/libsolidity/syntaxTests/sizeLimits/initcode_too_large_shanghai.sol +++ b/test/libsolidity/syntaxTests/sizeLimits/initcode_too_large_shanghai.sol @@ -27,4 +27,4 @@ contract test { // ==== // EVMVersion: =shanghai // ---- -// Warning 3860: (20321-20415): Contract initcode size is 60882 bytes and exceeds 49152 bytes (a limit introduced in Shanghai). This contract may not be deployable on Mainnet. Consider enabling the optimizer (with a low "runs" value!), turning off revert strings, or using libraries. +// Warning 3860: (20321-20415): Contract initcode size is 60879 bytes and exceeds 49152 bytes (a limit introduced in Shanghai). This contract may not be deployable on Mainnet. Consider enabling the optimizer (with a low "runs" value!), turning off revert strings, or using libraries. diff --git a/test/libyul/yulOptimizerTests/fullSuite/abi2.yul b/test/libyul/yulOptimizerTests/fullSuite/abi2.yul index d8c8e90558ef..2f2e060be089 100644 --- a/test/libyul/yulOptimizerTests/fullSuite/abi2.yul +++ b/test/libyul/yulOptimizerTests/fullSuite/abi2.yul @@ -1093,25 +1093,21 @@ // value0 := and(calldataload(headStart), sub(shl(160, 1), 1)) // value1 := calldataload(add(headStart, 32)) // let offset := calldataload(add(headStart, 64)) -// let _1 := 0xffffffffffffffff -// if gt(offset, _1) { revert(0, 0) } -// let _2 := add(headStart, offset) -// if iszero(slt(add(_2, 0x1f), dataEnd)) { revert(0, 0) } -// let length := calldataload(_2) -// if gt(length, _1) { revert(0, 0) } -// if gt(add(add(_2, length), 32), dataEnd) { revert(0, 0) } -// value2 := add(_2, 32) +// if gt(offset, 0xffffffffffffffff) { revert(0, 0) } +// let _1 := add(headStart, offset) +// if iszero(slt(add(_1, 0x1f), dataEnd)) { revert(0, 0) } +// let length := calldataload(_1) +// if gt(length, 0xffffffffffffffff) { revert(0, 0) } +// if gt(add(add(_1, length), 32), dataEnd) { revert(0, 0) } +// value2 := add(_1, 32) // value3 := length -// let _3 := calldataload(add(headStart, 96)) -// if iszero(lt(_3, 3)) { revert(0, 0) } -// value4 := _3 +// value4 := cleanup_revert_enum_Operation(calldataload(add(headStart, 96))) // } // function abi_encode_bytes32_address_uint256_bytes32_enum_Operation_uint256_uint256_uint256_address_address_uint256(headStart, value10, value9, value8, value7, value6, value5, value4, value3, value2, value1, value0) -> tail // { // tail := add(headStart, 352) // mstore(headStart, value0) -// let _1 := sub(shl(160, 1), 1) -// mstore(add(headStart, 32), and(value1, _1)) +// mstore(add(headStart, 32), and(value1, sub(shl(160, 1), 1))) // mstore(add(headStart, 64), value2) // mstore(add(headStart, 96), value3) // if iszero(lt(value4, 3)) { invalid() } @@ -1119,8 +1115,13 @@ // mstore(add(headStart, 160), value5) // mstore(add(headStart, 192), value6) // mstore(add(headStart, 224), value7) -// mstore(add(headStart, 256), and(value8, _1)) -// mstore(add(headStart, 288), and(value9, _1)) +// mstore(add(headStart, 256), and(value8, sub(shl(160, 1), 1))) +// mstore(add(headStart, 288), and(value9, sub(shl(160, 1), 1))) // mstore(add(headStart, 320), value10) // } +// function cleanup_revert_enum_Operation(value) -> cleaned +// { +// if iszero(lt(value, 3)) { revert(0, 0) } +// cleaned := value +// } // } diff --git a/test/libyul/yulOptimizerTests/fullSuite/abi_example1.yul b/test/libyul/yulOptimizerTests/fullSuite/abi_example1.yul index 2abdf6d9c283..dbb87439f637 100644 --- a/test/libyul/yulOptimizerTests/fullSuite/abi_example1.yul +++ b/test/libyul/yulOptimizerTests/fullSuite/abi_example1.yul @@ -492,68 +492,64 @@ // } // function abi_decode_array_array_uint256_memory_dyn(offset, end) -> array // { -// let _1 := 0x1f // if iszero(slt(add(offset, 0x1f), end)) { revert(0, 0) } // let length := calldataload(offset) // array := allocateMemory(array_allocation_size_array_address_dyn_memory(length)) // let dst := array // mstore(array, length) -// let _2 := 0x20 -// dst := add(array, _2) -// let src := add(offset, _2) -// if gt(add(add(offset, shl(6, length)), _2), end) { revert(0, 0) } +// dst := add(array, 0x20) +// let src := add(offset, 0x20) +// if gt(add(add(offset, shl(6, length)), 0x20), end) { revert(0, 0) } // let i := 0 // for { } lt(i, length) { i := add(i, 1) } // { -// if iszero(slt(add(src, _1), end)) { revert(0, 0) } -// let dst_1 := allocateMemory_967() -// let dst_2 := dst_1 +// if iszero(slt(add(src, 0x1f), end)) { revert(0, 0) } +// let dst_1 := allocateMemory_823() +// let array_1 := dst_1 // let src_1 := src -// let _3 := add(src, 64) -// if gt(_3, end) { revert(0, 0) } +// let _1 := add(src, 64) +// if gt(_1, end) { revert(0, 0) } // let i_1 := 0 // for { } lt(i_1, 0x2) { i_1 := add(i_1, 1) } // { // mstore(dst_1, calldataload(src_1)) -// dst_1 := add(dst_1, _2) -// src_1 := add(src_1, _2) +// dst_1 := add(dst_1, 0x20) +// src_1 := add(src_1, 0x20) // } -// mstore(dst, dst_2) -// dst := add(dst, _2) -// src := _3 +// mstore(dst, array_1) +// dst := add(dst, 0x20) +// src := _1 // } // } // function abi_decode_uint256t_uint256t_array_uint256_dynt_array_array_uint256_memory_dyn(headStart, dataEnd) -> value0, value1, value2, value3 // { // if slt(sub(dataEnd, headStart), 128) { revert(0, 0) } // value0 := calldataload(headStart) -// let _1 := 32 -// value1 := calldataload(add(headStart, _1)) +// value1 := calldataload(add(headStart, 32)) // let offset := calldataload(add(headStart, 64)) -// let _2 := 0xffffffffffffffff -// if gt(offset, _2) { revert(0, 0) } -// let _3 := add(headStart, offset) -// if iszero(slt(add(_3, 0x1f), dataEnd)) { revert(0, 0) } -// let length := calldataload(_3) +// if gt(offset, 0xffffffffffffffff) { revert(0, 0) } +// let _1 := add(headStart, offset) +// if iszero(slt(add(_1, 0x1f), dataEnd)) { revert(0, 0) } +// let length := calldataload(_1) // let dst := allocateMemory(array_allocation_size_array_address_dyn_memory(length)) -// let dst_1 := dst +// let array := dst // mstore(dst, length) -// dst := add(dst, _1) -// let src := add(_3, _1) -// if gt(add(add(_3, shl(5, length)), _1), dataEnd) { revert(0, 0) } +// dst := add(dst, 32) +// let src := add(_1, 32) +// if gt(add(add(_1, shl(5, length)), 32), dataEnd) { revert(0, 0) } // let i := 0 // for { } lt(i, length) { i := add(i, 1) } // { // mstore(dst, calldataload(src)) -// dst := add(dst, _1) -// src := add(src, _1) +// dst := add(dst, 32) +// src := add(src, 32) // } -// value2 := dst_1 +// value2 := array // let offset_1 := calldataload(add(headStart, 96)) -// if gt(offset_1, _2) { revert(0, 0) } +// if gt(offset_1, 0xffffffffffffffff) { revert(0, 0) } // value3 := abi_decode_array_array_uint256_memory_dyn(add(headStart, offset_1), dataEnd) // } -// function allocateMemory_967() -> memPtr +// function allocateMemory_823() -> memPtr // { // memPtr := mload(64) // let newFreePtr := add(memPtr, 64) diff --git a/test/libyul/yulOptimizerTests/fullSuite/ackermann_function.yul b/test/libyul/yulOptimizerTests/fullSuite/ackermann_function.yul index dd5facaf0315..bf419017bf15 100644 --- a/test/libyul/yulOptimizerTests/fullSuite/ackermann_function.yul +++ b/test/libyul/yulOptimizerTests/fullSuite/ackermann_function.yul @@ -36,8 +36,7 @@ // switch n // case 0 { ret := A(add(m, not(0)), 1) } // default { -// let _1 := not(0) -// ret := A(add(m, _1), A(m, add(n, _1))) +// ret := A(add(m, not(0)), A(m, add(n, not(0)))) // } // } // } diff --git a/test/libyul/yulOptimizerTests/fullSuite/ackermann_function_if.yul b/test/libyul/yulOptimizerTests/fullSuite/ackermann_function_if.yul index 005c58778b87..edf1a086faaa 100644 --- a/test/libyul/yulOptimizerTests/fullSuite/ackermann_function_if.yul +++ b/test/libyul/yulOptimizerTests/fullSuite/ackermann_function_if.yul @@ -45,7 +45,6 @@ // ret := A(add(m, not(0)), 1) // leave // } -// let _1 := not(0) -// ret := A(add(m, _1), A(m, add(n, _1))) +// ret := A(add(m, not(0)), A(m, add(n, not(0)))) // } // } diff --git a/test/libyul/yulOptimizerTests/fullSuite/aztec.yul b/test/libyul/yulOptimizerTests/fullSuite/aztec.yul index 2b22055794c6..8b26a7ba3723 100644 --- a/test/libyul/yulOptimizerTests/fullSuite/aztec.yul +++ b/test/libyul/yulOptimizerTests/fullSuite/aztec.yul @@ -237,53 +237,56 @@ // { // mstore(0x80, 7673901602397024137095011250362199966051872585513276903826533215767972925880) // mstore(0xa0, 8489654445897228341090914135473290831551238522473825886865492707826370766375) -// let notes := add(0x04, calldataload(0x04)) +// let _1 := calldataload(0x04) +// let notes := add(0x04, _1) +// let m := calldataload(0x24) // let n := calldataload(notes) -// if gt(calldataload(0x24), n) +// let challenge := mod(calldataload(0x44), 0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001) +// if gt(m, n) // { // mstore(0x00, 404) // revert(0x00, 0x20) // } // let kn := calldataload(add(calldatasize(), not(191))) -// let _1 := 0x2a0 -// mstore(_1, caller()) +// mstore(0x2a0, caller()) // mstore(0x2c0, kn) -// mstore(0x2e0, calldataload(0x24)) -// kn := mulmod(sub(0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001, kn), mod(calldataload(0x44), 0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001), 0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001) +// mstore(0x2e0, m) +// kn := mulmod(sub(0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001, kn), challenge, 0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001) // hashCommitments(notes, n) // let b := add(0x300, shl(7, n)) // let i := 0 // for { } lt(i, n) { i := add(i, 0x01) } // { -// let noteIndex := add(add(calldataload(0x04), mul(i, 0xc0)), 0x24) +// let _2 := add(_1, mul(i, 0xc0)) +// let noteIndex := add(_2, 0x24) // let k := 0 -// 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) +// let a := calldataload(add(_2, 0x44)) +// let c := challenge +// let _3 := add(i, 0x01) +// switch eq(_3, n) // case 1 { // k := kn -// if eq(calldataload(0x24), n) +// if eq(m, n) // { // k := sub(0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001, kn) // } // } // case 0 { k := calldataload(noteIndex) } // validateCommitment(noteIndex, k, a) -// switch gt(_2, calldataload(0x24)) +// switch gt(_3, m) // case 1 { // 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) +// c := mulmod(challenge, x, 0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001) // mstore(0, keccak256(0, 0x20)) // } // 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) +// calldatacopy(0xe0, add(_2, 164), 0x40) +// calldatacopy(0x20, add(_2, 100), 0x40) // mstore(0x120, sub(0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001, c)) // mstore(0x60, k) // mstore(0xc0, a) @@ -292,19 +295,18 @@ // 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)) +// if eq(i, m) // { // mstore(0x260, mload(0x20)) // mstore(0x280, mload(0x40)) // mstore(0x1e0, mload(0xe0)) // mstore(0x200, sub(0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47, mload(0x100))) // } -// if gt(i, calldataload(0x24)) +// if gt(i, m) // { // 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)) +// let result_4 := and(result, call(gas(), 7, 0, 0x20, 0x60, 0x220, 0x40)) +// let result_5 := and(result_4, call(gas(), 6, 0, 0x220, 0x80, 0x260, 0x40)) // result := and(result_5, call(gas(), 6, 0, 0x1a0, 0x80, 0x1e0, 0x40)) // } // if iszero(result) @@ -314,8 +316,8 @@ // } // b := add(b, 0x40) // } -// if lt(calldataload(0x24), n) { validatePairing() } -// if iszero(eq(mod(keccak256(_1, add(b, not(671))), 0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001), mod(calldataload(0x44), 0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001))) +// if lt(m, n) { validatePairing() } +// if iszero(eq(mod(keccak256(0x2a0, add(b, not(671))), 0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001), challenge)) // { // mstore(0, 404) // revert(0, 0x20) @@ -329,35 +331,28 @@ // let t2_x_1 := calldataload(132) // let t2_y := calldataload(164) // let t2_y_1 := calldataload(196) -// let _1 := 0x90689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b -// let _2 := 0x12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa -// let _3 := 0x198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c2 -// let _4 := 0x1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed -// if or(or(or(or(or(or(or(iszero(t2_x), iszero(t2_x_1)), iszero(t2_y)), iszero(t2_y_1)), eq(t2_x, _4)), eq(t2_x_1, _3)), eq(t2_y, _2)), eq(t2_y_1, _1)) +// if or(or(or(or(or(or(or(iszero(t2_x), iszero(t2_x_1)), iszero(t2_y)), iszero(t2_y_1)), eq(t2_x, 0x1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed)), eq(t2_x_1, 0x198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c2)), eq(t2_y, 0x12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa)), eq(t2_y_1, 0x90689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b)) // { // mstore(0x00, 400) // revert(0x00, 0x20) // } -// let _5 := mload(0x1e0) -// let _6 := 0x20 -// mstore(_6, _5) +// mstore(0x20, mload(0x1e0)) // mstore(0x40, mload(0x200)) -// mstore(0x80, _4) -// mstore(0x60, _3) -// mstore(0xc0, _2) -// mstore(0xa0, _1) +// mstore(0x80, 0x1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed) +// mstore(0x60, 0x198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c2) +// mstore(0xc0, 0x12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa) +// mstore(0xa0, 0x90689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b) // mstore(0xe0, mload(0x260)) // mstore(0x100, mload(0x280)) // mstore(0x140, t2_x) // mstore(0x120, t2_x_1) -// let _7 := 0x180 -// mstore(_7, t2_y) +// mstore(0x180, t2_y) // mstore(0x160, t2_y_1) -// let success := call(gas(), 8, 0, _6, _7, _6, _6) -// if or(iszero(success), iszero(mload(_6))) +// let success := call(gas(), 8, 0, 0x20, 0x180, 0x20, 0x20) +// if or(iszero(success), iszero(mload(0x20))) // { // mstore(0, 400) -// revert(0, _6) +// revert(0, 0x20) // } // } // function validateCommitment(note, k, a) @@ -366,9 +361,7 @@ // let gammaY := calldataload(add(note, 0x60)) // let sigmaX := calldataload(add(note, 0x80)) // let sigmaY := calldataload(add(note, 0xa0)) -// let _1 := 0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47 -// let _2 := 0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001 -// if iszero(and(and(and(eq(mod(a, _2), a), gt(a, 1)), and(eq(mod(k, _2), k), gt(k, 1))), and(eq(addmod(mulmod(mulmod(sigmaX, sigmaX, _1), sigmaX, _1), 3, _1), mulmod(sigmaY, sigmaY, _1)), eq(addmod(mulmod(mulmod(gammaX, gammaX, _1), gammaX, _1), 3, _1), mulmod(gammaY, gammaY, _1))))) +// if iszero(and(and(and(eq(mod(a, 0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001), a), gt(a, 1)), and(eq(mod(k, 0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001), k), gt(k, 1))), and(eq(addmod(mulmod(mulmod(sigmaX, sigmaX, 0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47), sigmaX, 0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47), 3, 0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47), mulmod(sigmaY, sigmaY, 0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47)), eq(addmod(mulmod(mulmod(gammaX, gammaX, 0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47), gammaX, 0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47), 3, 0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47), mulmod(gammaY, gammaY, 0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47))))) // { // mstore(0x00, 400) // revert(0x00, 0x20) diff --git a/test/libyul/yulOptimizerTests/fullSuite/call_arguments_without_side_effects.yul b/test/libyul/yulOptimizerTests/fullSuite/call_arguments_without_side_effects.yul index fc36bdfa37a0..5f42470f65a4 100644 --- a/test/libyul/yulOptimizerTests/fullSuite/call_arguments_without_side_effects.yul +++ b/test/libyul/yulOptimizerTests/fullSuite/call_arguments_without_side_effects.yul @@ -28,21 +28,20 @@ // // { // { -// let _1 := 1 -// mstore(_1, _1) -// mstore(2, _1) -// mstore(3, _1) -// mstore(4, _1) -// mstore(5, _1) -// mstore(6, _1) -// let _2 := sload(8) -// mstore(mload(7), _1) -// mstore(_2, _1) -// mstore(calldataload(9), _1) -// let _3 := mload(13) -// mstore(11, _1) -// mstore(12, _1) -// mstore(_3, _1) +// mstore(1, 1) +// mstore(2, 1) +// mstore(3, 1) +// mstore(4, 1) +// mstore(5, 1) +// mstore(6, 1) +// let _1 := sload(8) +// mstore(mload(7), 1) +// mstore(_1, 1) +// mstore(calldataload(9), 1) +// let _2 := mload(13) +// mstore(11, 1) +// mstore(12, 1) +// mstore(_2, 1) // return(0, 32) // } // } diff --git a/test/libyul/yulOptimizerTests/fullSuite/create2_and_mask.yul b/test/libyul/yulOptimizerTests/fullSuite/create2_and_mask.yul index f9d248e2feeb..6ebca20f5bbb 100644 --- a/test/libyul/yulOptimizerTests/fullSuite/create2_and_mask.yul +++ b/test/libyul/yulOptimizerTests/fullSuite/create2_and_mask.yul @@ -13,8 +13,7 @@ // // { // { -// let _1 := sub(shl(160, 1), 1) -// let a := and(create2(0, 0, 0x20, 0), _1) -// sstore(a, and(_1, create2(0, 0, 0x20, 0))) +// let a := and(create2(0, 0, 0x20, 0), sub(shl(160, 1), 1)) +// sstore(a, and(sub(shl(160, 1), 1), create2(0, 0, 0x20, 0))) // } // } diff --git a/test/libyul/yulOptimizerTests/fullSuite/create_and_mask.yul b/test/libyul/yulOptimizerTests/fullSuite/create_and_mask.yul index c89c620bb52d..078616bb3b7e 100644 --- a/test/libyul/yulOptimizerTests/fullSuite/create_and_mask.yul +++ b/test/libyul/yulOptimizerTests/fullSuite/create_and_mask.yul @@ -13,8 +13,7 @@ // // { // { -// let _1 := sub(shl(160, 1), 1) -// let a := and(create(0, 0, 0x20), _1) -// sstore(a, and(_1, create(0, 0, 0x20))) +// let a := and(create(0, 0, 0x20), sub(shl(160, 1), 1)) +// sstore(a, and(sub(shl(160, 1), 1), create(0, 0, 0x20))) // } // } diff --git a/test/libyul/yulOptimizerTests/fullSuite/devcon_example.yul b/test/libyul/yulOptimizerTests/fullSuite/devcon_example.yul index fe06f1629bc3..fca4a6366bdf 100644 --- a/test/libyul/yulOptimizerTests/fullSuite/devcon_example.yul +++ b/test/libyul/yulOptimizerTests/fullSuite/devcon_example.yul @@ -25,8 +25,11 @@ // let sum := 0 // let length := calldataload(_1) // let i := 0 -// for { } lt(i, length) { i := add(i, 1) } +// for { } true { i := add(i, 1) } // { +// let _2 := iszero(lt(i, length)) +// if _2 { break } +// _2 := 0 // sum := add(sum, calldataload(add(add(_1, shl(5, i)), 0x20))) // } // sstore(0, sum) diff --git a/test/libyul/yulOptimizerTests/fullSuite/extcodelength.yul b/test/libyul/yulOptimizerTests/fullSuite/extcodelength.yul index 436f5d5fafc4..dd6cdc0e44c4 100644 --- a/test/libyul/yulOptimizerTests/fullSuite/extcodelength.yul +++ b/test/libyul/yulOptimizerTests/fullSuite/extcodelength.yul @@ -26,12 +26,10 @@ // let value := calldataload(4) // if iszero(eq(value, and(value, sub(shl(160, 1), 1)))) { revert(0, 0) } // let length := extcodesize(value) -// let _1 := 0xffffffffffffffff -// if gt(length, _1) { revert(0, 0) } +// if gt(length, 0xffffffffffffffff) { revert(0, 0) } // let memPtr := mload(64) -// let _2 := not(31) -// let newFreePtr := add(memPtr, and(add(and(add(length, 31), _2), 63), _2)) -// if or(gt(newFreePtr, _1), lt(newFreePtr, memPtr)) { revert(0, 0) } +// let newFreePtr := add(memPtr, and(add(and(add(length, 31), not(31)), 63), not(31))) +// if or(gt(newFreePtr, 0xffffffffffffffff), lt(newFreePtr, memPtr)) { revert(0, 0) } // mstore(64, newFreePtr) // mstore(memPtr, length) // extcodecopy(value, add(memPtr, 32), 0, length) diff --git a/test/libyul/yulOptimizerTests/fullSuite/loopInvariantCodeMotion.yul b/test/libyul/yulOptimizerTests/fullSuite/loopInvariantCodeMotion.yul index 86329c3275f0..76d671bfc3e2 100644 --- a/test/libyul/yulOptimizerTests/fullSuite/loopInvariantCodeMotion.yul +++ b/test/libyul/yulOptimizerTests/fullSuite/loopInvariantCodeMotion.yul @@ -29,8 +29,11 @@ // let length := calldataload(_1) // let i := 0 // let _2 := calldataload(7) -// for { } lt(i, length) { i := add(i, 1) } +// for { } true { i := add(i, 1) } // { +// let _3 := iszero(lt(i, length)) +// if _3 { break } +// _3 := 0 // sum := add(sum, add(calldataload(add(add(_1, shl(5, i)), 0x20)), _2)) // } // sstore(0, sum) diff --git a/test/libyul/yulOptimizerTests/fullSuite/name_dependent_cse_bug_part_1_pre_shanghai.yul b/test/libyul/yulOptimizerTests/fullSuite/name_dependent_cse_bug_part_1_pre_shanghai.yul index d041cff1041f..4d3ed471b4e1 100644 --- a/test/libyul/yulOptimizerTests/fullSuite/name_dependent_cse_bug_part_1_pre_shanghai.yul +++ b/test/libyul/yulOptimizerTests/fullSuite/name_dependent_cse_bug_part_1_pre_shanghai.yul @@ -33,14 +33,13 @@ // { // { // let a := 0 -// let a_1 := 0 -// for { } a_1 { } +// for { } a { } // { -// let _1 := add(a_1, a_1) +// let _1 := add(a, a) // let var := add(_1, _1) -// switch a_1 -// case 0 { a_1 := var } -// default { sstore(a, var) } +// switch a +// case 0 { a := var } +// default { sstore(0, var) } // } // } // } diff --git a/test/libyul/yulOptimizerTests/fullSuite/name_dependent_cse_bug_part_2_pre_shanghai.yul b/test/libyul/yulOptimizerTests/fullSuite/name_dependent_cse_bug_part_2_pre_shanghai.yul index 06965e3ca695..3161dc2efac4 100644 --- a/test/libyul/yulOptimizerTests/fullSuite/name_dependent_cse_bug_part_2_pre_shanghai.yul +++ b/test/libyul/yulOptimizerTests/fullSuite/name_dependent_cse_bug_part_2_pre_shanghai.yul @@ -33,14 +33,13 @@ // { // { // let a := 0 -// let a_1 := 0 -// for { } a_1 { } +// for { } a { } // { -// let _1 := add(a_1, a_1) +// let _1 := add(a, a) // let var := add(_1, _1) -// switch a_1 -// case 0 { a_1 := var } -// default { sstore(a, var) } +// switch a +// case 0 { a := var } +// default { sstore(0, var) } // } // } // } diff --git a/test/libyul/yulOptimizerTests/fullSuite/stack_compressor_msize.yul b/test/libyul/yulOptimizerTests/fullSuite/stack_compressor_msize.yul index 75e2ff4c2010..5fbe8d22e615 100644 --- a/test/libyul/yulOptimizerTests/fullSuite/stack_compressor_msize.yul +++ b/test/libyul/yulOptimizerTests/fullSuite/stack_compressor_msize.yul @@ -40,22 +40,18 @@ // // { // { -// 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(2, _1) -// extcodecopy(_1, msize(), _1, _1) +// let _1 := gt(not(gcd(10, 15)), 1) +// let _2 := gcd(10, 15) +// let _3 := lt(or(1, add(gcd(10, 15), not(0))), 1) +// let _4 := gcd(10, 15) +// let _5 := 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(not(0), _5), 1), _4), _3), _2), 1), 1), _1), 1)), 1), 1), 1) +// sstore(not(gcd(10, 15)), 1) +// sstore(2, 1) +// foo_singlereturn() // sstore(0, 0) -// sstore(3, _1) +// sstore(3, 1) // } // function gcd(_a, _b) -> out // { @@ -63,4 +59,6 @@ // case 0 { out := _a } // default { out := gcd(_b, mod(_a, _b)) } // } +// function foo_singlereturn() +// { extcodecopy(1, msize(), 1, 1) } // } diff --git a/test/libyul/yulOptimizerTests/fullSuite/structural_simplification.yul b/test/libyul/yulOptimizerTests/fullSuite/structural_simplification.yul index 85a975fde188..aabc14f15106 100644 --- a/test/libyul/yulOptimizerTests/fullSuite/structural_simplification.yul +++ b/test/libyul/yulOptimizerTests/fullSuite/structural_simplification.yul @@ -8,4 +8,11 @@ // ---- // step: fullSuite // -// { { sstore(1, 0x20) } } +// { +// { +// mstore(0x40, 0x20) +// for { } iszero(1) { } +// { } +// sstore(1, mload(0x40)) +// } +// } diff --git a/test/libyul/yulOptimizerTests/fullSuite/unusedFunctionParameterPruner_loop.yul b/test/libyul/yulOptimizerTests/fullSuite/unusedFunctionParameterPruner_loop.yul index 148f4a1e7ea0..f0b7546d0592 100644 --- a/test/libyul/yulOptimizerTests/fullSuite/unusedFunctionParameterPruner_loop.yul +++ b/test/libyul/yulOptimizerTests/fullSuite/unusedFunctionParameterPruner_loop.yul @@ -20,46 +20,18 @@ // { // { // f() -// f_72() -// f_73() +// f() +// f() // sstore(0, 1) // } // function f() // { -// let a := 1 -// let b := 10 -// let a_1 := calldataload(0) -// let _1 := iszero(a_1) -// for { } iszero(b) { b := add(b, not(0)) } -// { -// a := a_1 -// mstore(a_1, 0) -// if _1 { leave } -// } -// } -// function f_72() -// { -// let a := 2 -// let b := 10 -// let a_1 := calldataload(0) -// let _1 := iszero(a_1) -// for { } iszero(b) { b := add(b, not(0)) } -// { -// a := a_1 -// mstore(a_1, 0) -// if _1 { leave } -// } -// } -// function f_73() -// { -// let a := 3 // let b := 10 -// let a_1 := calldataload(0) -// let _1 := iszero(a_1) +// let a := calldataload(0) +// let _1 := iszero(a) // for { } iszero(b) { b := add(b, not(0)) } // { -// a := a_1 -// mstore(a_1, 0) +// mstore(a, 0) // if _1 { leave } // } // } From d5f5742bfc5fff81e5958a5ff230c75d01d222f4 Mon Sep 17 00:00:00 2001 From: Martin Blicha Date: Wed, 8 May 2024 17:25:50 +0200 Subject: [PATCH 0203/1022] CI: Stop installing cvc4 on archlinux This change is in preparation for upgrading to cvc5. Since archlinux is not running SMT tests anyway, we can drop cvc4 from the build immediately. --- .circleci/config.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 38bcaea7b311..6feb033deaf3 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1146,7 +1146,7 @@ jobs: - run: name: Install build dependencies command: | - pacman --noconfirm -Syu --noprogressbar --needed base-devel boost cmake cvc4 git openssh tar + pacman --noconfirm -Syu --noprogressbar --needed base-devel boost cmake git openssh tar - checkout - run_build - store_artifacts_solc @@ -1273,7 +1273,7 @@ jobs: - run: name: Install runtime dependencies command: | - pacman --noconfirm -Syu --noprogressbar --needed base-devel boost cmake z3 cvc4 git openssh tar + pacman --noconfirm -Syu --noprogressbar --needed z3 - soltest t_ubu_clang_soltest: &t_ubu_clang_soltest From 5ffd39a79245be31ffa766e1ed8bba943aac6524 Mon Sep 17 00:00:00 2001 From: r0qs Date: Wed, 8 May 2024 15:02:07 +0200 Subject: [PATCH 0204/1022] Fix segmentation fault when assigning to a parenthesized non-tuple expression of a tuple type MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Kamil Śliwak --- Changelog.md | 1 + libsolidity/analysis/TypeChecker.cpp | 3 +- ...d_non_tuple_expressions_of_tuple_types.sol | 40 +++++++++++++++++++ 3 files changed, 43 insertions(+), 1 deletion(-) create mode 100644 test/libsolidity/syntaxTests/tupleAssignments/assignments_to_tuple_and_non_tuple_expressions_of_tuple_types.sol diff --git a/Changelog.md b/Changelog.md index f34f803e68be..252f228c5330 100644 --- a/Changelog.md +++ b/Changelog.md @@ -16,6 +16,7 @@ Bugfixes: * SMTChecker: Fix internal error when using bitwise operators with an array element as argument. * Standard JSON Interface: Fix ICE when the optimizer is disabled and an empty/blank string is used for ``optimizerSteps`` sequence. * StaticAnalyzer: Only raise a compile time error for division and modulo by zero when it's between literals. + * TypeChecker: Fix compiler crash when the left-hand side of an assignment was a parenthesized non-tuple expression of a tuple type. * Yul Optimizer: Fix the order of assignments generated by ``SSATransform`` being dependent on AST IDs, sometimes resulting in different (but equivalent) bytecode when unrelated files were added to the compilation pipeline. diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp index a7402ba40f60..42c98a8f056e 100644 --- a/libsolidity/analysis/TypeChecker.cpp +++ b/libsolidity/analysis/TypeChecker.cpp @@ -116,7 +116,8 @@ void TypeChecker::checkDoubleStorageAssignment(Assignment const& _assignment) TupleType const& lhsType = dynamic_cast(*type(_lhs)); TupleExpression const* lhsResolved = dynamic_cast(resolveOuterUnaryTuples(&_lhs)); - if (lhsType.components().size() != _rhs.components().size() || lhsResolved->components().size() != _rhs.components().size()) + solAssert(!lhsResolved || lhsResolved->components().size() == lhsType.components().size()); + if (lhsType.components().size() != _rhs.components().size()) { solAssert(m_errorReporter.hasErrors(), ""); return; diff --git a/test/libsolidity/syntaxTests/tupleAssignments/assignments_to_tuple_and_non_tuple_expressions_of_tuple_types.sol b/test/libsolidity/syntaxTests/tupleAssignments/assignments_to_tuple_and_non_tuple_expressions_of_tuple_types.sol new file mode 100644 index 000000000000..e88d82b85c35 --- /dev/null +++ b/test/libsolidity/syntaxTests/tupleAssignments/assignments_to_tuple_and_non_tuple_expressions_of_tuple_types.sol @@ -0,0 +1,40 @@ +contract C { + uint[] public array; + + function f() public { + // (f()) is not a tuple expression, but its value is a tuple. + (f()) = (); + } + + function g() public { + // (revert()) is not a tuple expression, but its value is a tuple. + (revert()) = (); + } + + function h() internal returns (uint, uint) {} + + function i() public { + // (h()) is not a tuple expression, but its value is a tuple (uint, uint). + (h()) = (1, 1); + } + + function j() public returns (uint, uint) { + // (j()) is not a tuple expression, but its value is a tuple (uint, uint). + (j()) = (1, 1); + } + + function m() public { + // (uint x, uint y) is a tuple expression, and its value is a tuple (uint, uint). + (uint x, uint y) = (1, 1); + } + + function n() public { + // ((array.push(), array.push())) is not a tuple expression, but contains a tuple expression, and the value of both is a tuple (pointer uint, pointer uint). + ((array.push(), array.push())) = (1, 1); + } +} +// ---- +// TypeError 4247: (126-129): Expression has to be an lvalue. +// TypeError 4247: (236-244): Expression has to be an lvalue. +// TypeError 4247: (407-410): Expression has to be an lvalue. +// TypeError 4247: (550-553): Expression has to be an lvalue. From 9a60c27c3c88a07f7fa69102a5a60f921b1e94b5 Mon Sep 17 00:00:00 2001 From: Daniel Kirchner Date: Tue, 14 May 2024 12:28:08 +0200 Subject: [PATCH 0205/1022] Update bytecode size test for byzantium. --- .../syntaxTests/sizeLimits/bytecode_too_large_byzantium.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/libsolidity/syntaxTests/sizeLimits/bytecode_too_large_byzantium.sol b/test/libsolidity/syntaxTests/sizeLimits/bytecode_too_large_byzantium.sol index 67dee4cad6ea..4f3239c2272a 100644 --- a/test/libsolidity/syntaxTests/sizeLimits/bytecode_too_large_byzantium.sol +++ b/test/libsolidity/syntaxTests/sizeLimits/bytecode_too_large_byzantium.sol @@ -7,4 +7,4 @@ contract test { // ==== // EVMVersion: =byzantium // ---- -// Warning 5574: (0-27133): Contract code size is 27221 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. +// Warning 5574: (0-27133): Contract code size is 27220 bytes and exceeds 24576 bytes (a limit introduced in Spurious Dragon). This contract may not be deployable on Mainnet. Consider enabling the optimizer (with a low "runs" value!), turning off revert strings, or using libraries. From febe38a27a9aaa0b31a6094d89f97a9c13628f39 Mon Sep 17 00:00:00 2001 From: Pawel Gebal Date: Wed, 8 May 2024 18:10:58 +0200 Subject: [PATCH 0206/1022] SMTChecker: add insufficient funds verification target for CHC engine --- Changelog.md | 2 +- libsolidity/formal/BMC.cpp | 6 +++ libsolidity/formal/CHC.cpp | 18 +++++++ .../model_checker_targets_all_all_engines/err | 14 +----- .../model_checker_targets_all_chc/err | 2 + .../model_checker_targets_balance_chc/err | 1 + .../err | 14 +----- .../model_checker_targets_default_chc/err | 2 + .../output.json | 12 +++++ .../output.json | 49 ++++--------------- .../output.json | 10 ++++ .../blockchain_state/balance_spend.sol | 3 +- .../blockchain_state/balance_spend_2.sol | 6 +-- .../blockchain_state/decreasing_balance.sol | 2 +- .../blockchain_state/free_function_2.sol | 3 +- .../blockchain_state/library_internal_2.sol | 3 +- .../blockchain_state/library_public_2.sol | 2 +- .../{transfer.sol => transfer_1.sol} | 3 +- .../blockchain_state/transfer_2.sol | 14 ++++++ .../blockchain_state/transfer_3.sol | 11 +++++ .../blockchain_state/transfer_4.sol | 12 +++++ .../smtCheckerTests/functions/this_state.sol | 14 +++--- .../types/address_transfer.sol | 2 +- .../types/address_transfer_2.sol | 4 +- .../types/address_transfer_3.sol | 3 +- .../types/address_transfer_insufficient.sol | 4 +- 26 files changed, 125 insertions(+), 91 deletions(-) create mode 100644 test/cmdlineTests/model_checker_targets_balance_chc/err rename test/libsolidity/smtCheckerTests/blockchain_state/{transfer.sol => transfer_1.sol} (66%) create mode 100644 test/libsolidity/smtCheckerTests/blockchain_state/transfer_2.sol create mode 100644 test/libsolidity/smtCheckerTests/blockchain_state/transfer_3.sol create mode 100644 test/libsolidity/smtCheckerTests/blockchain_state/transfer_4.sol diff --git a/Changelog.md b/Changelog.md index 252f228c5330..4ed7bd2a360c 100644 --- a/Changelog.md +++ b/Changelog.md @@ -5,7 +5,7 @@ Language Features: Compiler Features: - +* SMTChecker: Create balance check verification target for CHC engine. Bugfixes: * Commandline Interface: Fix ICE when the optimizer is disabled and an empty/blank string is used for ``--yul-optimizations`` sequence. diff --git a/libsolidity/formal/BMC.cpp b/libsolidity/formal/BMC.cpp index 932a315a703a..97dd7050fef8 100644 --- a/libsolidity/formal/BMC.cpp +++ b/libsolidity/formal/BMC.cpp @@ -1050,6 +1050,12 @@ void BMC::checkDivByZero(BMCVerificationTarget& _target) void BMC::checkBalance(BMCVerificationTarget& _target) { solAssert(_target.type == VerificationTargetType::Balance, ""); + + if ( + m_solvedTargets.count(_target.expression) && + m_solvedTargets.at(_target.expression).count(VerificationTargetType::Balance) + ) + return; checkCondition( _target, _target.constraints && _target.value, diff --git a/libsolidity/formal/CHC.cpp b/libsolidity/formal/CHC.cpp index 2c9075abcc4a..b6ffd5954ffb 100644 --- a/libsolidity/formal/CHC.cpp +++ b/libsolidity/formal/CHC.cpp @@ -607,6 +607,22 @@ void CHC::endVisit(FunctionCall const& _funCall) SMTEncoder::endVisit(_funCall); unknownFunctionCall(_funCall); break; + case FunctionType::Kind::Send: + case FunctionType::Kind::Transfer: + { + auto value = _funCall.arguments().front(); + solAssert(value, ""); + smtutil::Expression thisBalance = state().balance(); + + verificationTargetEncountered( + &_funCall, + VerificationTargetType::Balance, + thisBalance < expr(*value) + ); + + SMTEncoder::endVisit(_funCall); + break; + } case FunctionType::Kind::KECCAK256: case FunctionType::Kind::ECRecover: case FunctionType::Kind::SHA256: @@ -2013,6 +2029,8 @@ std::pair CHC::targetDescription(CHCVerificationTarget con return {"Division by zero", 4281_error}; else if (_target.type == VerificationTargetType::Assert) return {"Assertion violation", 6328_error}; + else if (_target.type == VerificationTargetType::Balance) + return {"Insufficient funds", 8656_error}; else solAssert(false); } diff --git a/test/cmdlineTests/model_checker_targets_all_all_engines/err b/test/cmdlineTests/model_checker_targets_all_all_engines/err index cc8a8ea33d1c..c67d97b61216 100644 --- a/test/cmdlineTests/model_checker_targets_all_all_engines/err +++ b/test/cmdlineTests/model_checker_targets_all_all_engines/err @@ -88,21 +88,11 @@ test.f(0x0, 1) 13 | arr[x]; | ^^^^^^ +Info: CHC: 1 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. + Warning: BMC: Condition is always true. --> model_checker_targets_all_all_engines/input.sol:6:11: | 6 | require(x >= 0); | ^^^^^^ Note: Callstack: - -Warning: BMC: Insufficient funds happens here. - --> model_checker_targets_all_all_engines/input.sol:10:3: - | -10 | a.transfer(x); - | ^^^^^^^^^^^^^ -Note: Counterexample: - a = 0 - x = 0 - -Note: Callstack: -Note: diff --git a/test/cmdlineTests/model_checker_targets_all_chc/err b/test/cmdlineTests/model_checker_targets_all_chc/err index d0404ecfb6b9..9c257cefe9eb 100644 --- a/test/cmdlineTests/model_checker_targets_all_chc/err +++ b/test/cmdlineTests/model_checker_targets_all_chc/err @@ -87,3 +87,5 @@ test.f(0x0, 1) | 13 | arr[x]; | ^^^^^^ + +Info: CHC: 1 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/cmdlineTests/model_checker_targets_balance_chc/err b/test/cmdlineTests/model_checker_targets_balance_chc/err new file mode 100644 index 000000000000..57bfe42678e4 --- /dev/null +++ b/test/cmdlineTests/model_checker_targets_balance_chc/err @@ -0,0 +1 @@ +Info: CHC: 1 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/cmdlineTests/model_checker_targets_default_all_engines/err b/test/cmdlineTests/model_checker_targets_default_all_engines/err index c1fe2f5b3e59..62d3b203cb9c 100644 --- a/test/cmdlineTests/model_checker_targets_default_all_engines/err +++ b/test/cmdlineTests/model_checker_targets_default_all_engines/err @@ -58,21 +58,11 @@ test.f(0x0, 1) 13 | arr[x]; | ^^^^^^ +Info: CHC: 1 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. + Warning: BMC: Condition is always true. --> model_checker_targets_default_all_engines/input.sol:6:11: | 6 | require(x >= 0); | ^^^^^^ Note: Callstack: - -Warning: BMC: Insufficient funds happens here. - --> model_checker_targets_default_all_engines/input.sol:10:3: - | -10 | a.transfer(x); - | ^^^^^^^^^^^^^ -Note: Counterexample: - a = 0 - x = 0 - -Note: Callstack: -Note: diff --git a/test/cmdlineTests/model_checker_targets_default_chc/err b/test/cmdlineTests/model_checker_targets_default_chc/err index bd2aa0b4de1d..70f3c5bc6072 100644 --- a/test/cmdlineTests/model_checker_targets_default_chc/err +++ b/test/cmdlineTests/model_checker_targets_default_chc/err @@ -57,3 +57,5 @@ test.f(0x0, 1) | 13 | arr[x]; | ^^^^^^ + +Info: CHC: 1 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/cmdlineTests/standard_model_checker_targets_balance_chc/output.json b/test/cmdlineTests/standard_model_checker_targets_balance_chc/output.json index f047ff70a9eb..9d3e40b708f1 100644 --- a/test/cmdlineTests/standard_model_checker_targets_balance_chc/output.json +++ b/test/cmdlineTests/standard_model_checker_targets_balance_chc/output.json @@ -1,4 +1,16 @@ { + "errors": [ + { + "component": "general", + "errorCode": "1391", + "formattedMessage": "Info: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them. + +", + "message": "CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.", + "severity": "info", + "type": "Info" + } + ], "sources": { "A": { "id": 0 diff --git a/test/cmdlineTests/standard_model_checker_targets_default_all_engines/output.json b/test/cmdlineTests/standard_model_checker_targets_default_all_engines/output.json index 2318e5adfaba..8f20d854bfb5 100644 --- a/test/cmdlineTests/standard_model_checker_targets_default_all_engines/output.json +++ b/test/cmdlineTests/standard_model_checker_targets_default_all_engines/output.json @@ -148,6 +148,16 @@ test.f(0x0, 1)", }, "type": "Warning" }, + { + "component": "general", + "errorCode": "1391", + "formattedMessage": "Info: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them. + +", + "message": "CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.", + "severity": "info", + "type": "Info" + }, { "component": "general", "errorCode": "6838", @@ -172,45 +182,6 @@ Note: Callstack: "start": 159 }, "type": "Warning" - }, - { - "component": "general", - "errorCode": "1236", - "formattedMessage": "Warning: BMC: Insufficient funds happens here. - --> A:11:7: - | -11 | \t\t\t\t\t\ta.transfer(x); - | \t\t\t\t\t\t^^^^^^^^^^^^^ -Note: Counterexample: - a = 0 - x = 0 - -Note: Callstack: -Note: - -", - "message": "BMC: Insufficient funds happens here.", - "secondarySourceLocations": [ - { - "message": "Counterexample: - a = 0 - x = 0 -" - }, - { - "message": "Callstack:" - }, - { - "message": "" - } - ], - "severity": "warning", - "sourceLocation": { - "end": 237, - "file": "A", - "start": 224 - }, - "type": "Warning" } ], "sources": { diff --git a/test/cmdlineTests/standard_model_checker_targets_default_chc/output.json b/test/cmdlineTests/standard_model_checker_targets_default_chc/output.json index eb39e0271233..e045a8bff49a 100644 --- a/test/cmdlineTests/standard_model_checker_targets_default_chc/output.json +++ b/test/cmdlineTests/standard_model_checker_targets_default_chc/output.json @@ -147,6 +147,16 @@ test.f(0x0, 1)", "start": 283 }, "type": "Warning" + }, + { + "component": "general", + "errorCode": "1391", + "formattedMessage": "Info: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them. + +", + "message": "CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.", + "severity": "info", + "type": "Info" } ], "sources": { diff --git a/test/libsolidity/smtCheckerTests/blockchain_state/balance_spend.sol b/test/libsolidity/smtCheckerTests/blockchain_state/balance_spend.sol index 387e45bb9f46..720ab5695029 100644 --- a/test/libsolidity/smtCheckerTests/blockchain_state/balance_spend.sol +++ b/test/libsolidity/smtCheckerTests/blockchain_state/balance_spend.sol @@ -19,5 +19,4 @@ contract C { // SMTIgnoreCex: yes // ---- // Warning 6328: (280-314): CHC: Assertion violation happens here. -// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. -// Warning 1236: (175-190): BMC: Insufficient funds happens here. +// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/blockchain_state/balance_spend_2.sol b/test/libsolidity/smtCheckerTests/blockchain_state/balance_spend_2.sol index 5df0b99956f2..3ceac964f111 100644 --- a/test/libsolidity/smtCheckerTests/blockchain_state/balance_spend_2.sol +++ b/test/libsolidity/smtCheckerTests/blockchain_state/balance_spend_2.sol @@ -15,9 +15,9 @@ contract C { // ==== // SMTEngine: all // SMTIgnoreCex: yes +// SMTIgnoreOS: macos // ---- -// Warning 6328: (193-226): CHC: Assertion violation might happen here. +// Warning 8656: (141-156): CHC: Insufficient funds happens here. +// Warning 6328: (193-226): CHC: Assertion violation happens here. // Warning 6328: (245-279): CHC: Assertion violation happens here. // Warning 6328: (298-332): CHC: Assertion violation happens here. -// Warning 1236: (141-156): BMC: Insufficient funds happens here. -// Warning 4661: (193-226): BMC: Assertion violation happens here. diff --git a/test/libsolidity/smtCheckerTests/blockchain_state/decreasing_balance.sol b/test/libsolidity/smtCheckerTests/blockchain_state/decreasing_balance.sol index 76455060d8d5..df35a2785824 100644 --- a/test/libsolidity/smtCheckerTests/blockchain_state/decreasing_balance.sol +++ b/test/libsolidity/smtCheckerTests/blockchain_state/decreasing_balance.sol @@ -18,4 +18,4 @@ contract C { // ==== // SMTEngine: all // ---- -// Info 6002: BMC: 1 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. +// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/blockchain_state/free_function_2.sol b/test/libsolidity/smtCheckerTests/blockchain_state/free_function_2.sol index e2e187038ca1..3b7c0f9dce34 100644 --- a/test/libsolidity/smtCheckerTests/blockchain_state/free_function_2.sol +++ b/test/libsolidity/smtCheckerTests/blockchain_state/free_function_2.sol @@ -20,5 +20,4 @@ contract C { // SMTIgnoreCex: yes // ---- // Warning 6328: (258-274): CHC: Assertion violation happens here. -// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. -// Warning 1236: (33-46): BMC: Insufficient funds happens here. +// Info 1391: CHC: 4 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/blockchain_state/library_internal_2.sol b/test/libsolidity/smtCheckerTests/blockchain_state/library_internal_2.sol index f16a57acf68f..826af0bf867d 100644 --- a/test/libsolidity/smtCheckerTests/blockchain_state/library_internal_2.sol +++ b/test/libsolidity/smtCheckerTests/blockchain_state/library_internal_2.sol @@ -23,5 +23,4 @@ contract C { // SMTIgnoreCex: yes // ---- // Warning 6328: (315-331): CHC: Assertion violation happens here. -// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. -// Warning 1236: (87-100): BMC: Insufficient funds happens here. +// Info 1391: CHC: 4 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/blockchain_state/library_public_2.sol b/test/libsolidity/smtCheckerTests/blockchain_state/library_public_2.sol index 4b500581d323..02e29be8de9c 100644 --- a/test/libsolidity/smtCheckerTests/blockchain_state/library_public_2.sol +++ b/test/libsolidity/smtCheckerTests/blockchain_state/library_public_2.sol @@ -21,6 +21,6 @@ contract C { // SMTIgnoreCex: yes // ---- // Warning 4588: (238-243): Assertion checker does not yet implement this type of function call. +// Warning 8656: (54-67): CHC: Insufficient funds happens here. // Warning 6328: (282-298): CHC: Assertion violation happens here. // Warning 6328: (317-331): CHC: Assertion violation happens here. -// Warning 1236: (54-67): BMC: Insufficient funds happens here. diff --git a/test/libsolidity/smtCheckerTests/blockchain_state/transfer.sol b/test/libsolidity/smtCheckerTests/blockchain_state/transfer_1.sol similarity index 66% rename from test/libsolidity/smtCheckerTests/blockchain_state/transfer.sol rename to test/libsolidity/smtCheckerTests/blockchain_state/transfer_1.sol index c099ffb2e5c9..3118086b921a 100644 --- a/test/libsolidity/smtCheckerTests/blockchain_state/transfer.sol +++ b/test/libsolidity/smtCheckerTests/blockchain_state/transfer_1.sol @@ -12,5 +12,4 @@ contract C { // SMTIgnoreCex: yes // ---- // Warning 6328: (166-201): CHC: Assertion violation happens here. -// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. -// Info 6002: BMC: 1 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. +// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. \ No newline at end of file diff --git a/test/libsolidity/smtCheckerTests/blockchain_state/transfer_2.sol b/test/libsolidity/smtCheckerTests/blockchain_state/transfer_2.sol new file mode 100644 index 000000000000..ed5b4c90f2cf --- /dev/null +++ b/test/libsolidity/smtCheckerTests/blockchain_state/transfer_2.sol @@ -0,0 +1,14 @@ +contract C { + address payable recipient; + uint amount; + + function shouldHold() public { + uint tempAmount = address(this).balance; + recipient.transfer(tempAmount); + recipient.transfer(amount); + } +} +// ==== +// SMTEngine: chc +// ---- +// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/blockchain_state/transfer_3.sol b/test/libsolidity/smtCheckerTests/blockchain_state/transfer_3.sol new file mode 100644 index 000000000000..4b3318b6bece --- /dev/null +++ b/test/libsolidity/smtCheckerTests/blockchain_state/transfer_3.sol @@ -0,0 +1,11 @@ +contract C { + address payable recipient; + + function shouldFail() public { + recipient.transfer(1); + } +} +// ==== +// SMTEngine: all +// ---- +// Warning 8656: (76-97): CHC: Insufficient funds happens here. diff --git a/test/libsolidity/smtCheckerTests/blockchain_state/transfer_4.sol b/test/libsolidity/smtCheckerTests/blockchain_state/transfer_4.sol new file mode 100644 index 000000000000..ab0c4a81efeb --- /dev/null +++ b/test/libsolidity/smtCheckerTests/blockchain_state/transfer_4.sol @@ -0,0 +1,12 @@ +contract C { + address payable recipient; + + function f() public payable { + require(msg.value > 1); + recipient.transfer(1); + } +} +// ==== +// SMTEngine: all +// ---- +// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/functions/this_state.sol b/test/libsolidity/smtCheckerTests/functions/this_state.sol index dec101060d8c..d069bd90f8e1 100644 --- a/test/libsolidity/smtCheckerTests/functions/this_state.sol +++ b/test/libsolidity/smtCheckerTests/functions/this_state.sol @@ -1,14 +1,14 @@ contract C { - uint public x; - function g() public { + uint public x; + function g() public { x = 0; - this.h(); + this.h(); assert(x == 2); - } - function h() public { - x = 2; - } + } + function h() public { + x = 2; + } } // ==== // SMTEngine: all diff --git a/test/libsolidity/smtCheckerTests/types/address_transfer.sol b/test/libsolidity/smtCheckerTests/types/address_transfer.sol index 89e8ae10274e..1430e15cb8e7 100644 --- a/test/libsolidity/smtCheckerTests/types/address_transfer.sol +++ b/test/libsolidity/smtCheckerTests/types/address_transfer.sol @@ -11,5 +11,5 @@ contract C // ==== // SMTEngine: all // ---- +// Warning 8656: (98-113): CHC: Insufficient funds happens here. // Warning 6328: (162-186): CHC: Assertion violation happens here. -// Warning 1236: (98-113): BMC: Insufficient funds happens here. diff --git a/test/libsolidity/smtCheckerTests/types/address_transfer_2.sol b/test/libsolidity/smtCheckerTests/types/address_transfer_2.sol index 0a2c08d0caab..ce6492d9e57a 100644 --- a/test/libsolidity/smtCheckerTests/types/address_transfer_2.sol +++ b/test/libsolidity/smtCheckerTests/types/address_transfer_2.sol @@ -15,6 +15,6 @@ contract C // SMTEngine: all // SMTIgnoreCex: yes // ---- +// Warning 8656: (184-199): CHC: Insufficient funds happens here. +// Warning 8656: (203-218): CHC: Insufficient funds happens here. // Warning 6328: (262-291): CHC: Assertion violation happens here. -// Warning 1236: (184-199): BMC: Insufficient funds happens here. -// Warning 1236: (203-218): BMC: Insufficient funds happens here. diff --git a/test/libsolidity/smtCheckerTests/types/address_transfer_3.sol b/test/libsolidity/smtCheckerTests/types/address_transfer_3.sol index 02d20c4f5bc4..3f9cc22c7bd6 100644 --- a/test/libsolidity/smtCheckerTests/types/address_transfer_3.sol +++ b/test/libsolidity/smtCheckerTests/types/address_transfer_3.sol @@ -13,5 +13,4 @@ contract C // ==== // SMTEngine: all // ---- -// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. -// Info 6002: BMC: 1 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. +// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/types/address_transfer_insufficient.sol b/test/libsolidity/smtCheckerTests/types/address_transfer_insufficient.sol index 59568cb5be91..55a96026ee51 100644 --- a/test/libsolidity/smtCheckerTests/types/address_transfer_insufficient.sol +++ b/test/libsolidity/smtCheckerTests/types/address_transfer_insufficient.sol @@ -12,6 +12,6 @@ contract C // SMTEngine: all // SMTIgnoreCex: yes // ---- +// Warning 8656: (101-116): CHC: Insufficient funds happens here. +// Warning 8656: (120-136): CHC: Insufficient funds happens here. // Warning 6328: (180-204): CHC: Assertion violation happens here. -// Warning 1236: (101-116): BMC: Insufficient funds happens here. -// Warning 1236: (120-136): BMC: Insufficient funds happens here. From c84863f90773523beec4ce871d527655e5d7be9f Mon Sep 17 00:00:00 2001 From: Daniel Kirchner Date: Tue, 9 May 2023 17:27:30 +0200 Subject: [PATCH 0207/1022] Do not allocate memory on reverts with small errors. Do not allocate memory on reverts with small errors. Workaround for StringLiteralType Addition require error test coverage --- Changelog.md | 4 +- libsolidity/codegen/YulUtilFunctions.cpp | 42 ++++++++++++++++- .../cmdlineTests/require_with_error_ir/output | 4 ++ .../require_with_string_ir/output | 4 ++ .../errors/errors_by_parameter_type.sol | 45 +++++++++++++++++++ .../errors/small_error_optimization.sol | 22 +++++++++ 6 files changed, 118 insertions(+), 3 deletions(-) create mode 100644 test/libsolidity/semanticTests/errors/errors_by_parameter_type.sol create mode 100644 test/libsolidity/semanticTests/errors/small_error_optimization.sol diff --git a/Changelog.md b/Changelog.md index 4ed7bd2a360c..6f129732c7fe 100644 --- a/Changelog.md +++ b/Changelog.md @@ -5,7 +5,9 @@ Language Features: Compiler Features: -* SMTChecker: Create balance check verification target for CHC engine. + * SMTChecker: Create balance check verification target for CHC engine. + * Yul IR Code Generation: Cheaper code for reverting with errors of a small static encoding size. + Bugfixes: * Commandline Interface: Fix ICE when the optimizer is disabled and an empty/blank string is used for ``--yul-optimizations`` sequence. diff --git a/libsolidity/codegen/YulUtilFunctions.cpp b/libsolidity/codegen/YulUtilFunctions.cpp index b71dfd566a75..9d1929fe1ef6 100644 --- a/libsolidity/codegen/YulUtilFunctions.cpp +++ b/libsolidity/codegen/YulUtilFunctions.cpp @@ -32,11 +32,30 @@ #include #include +#include + using namespace solidity; using namespace solidity::util; using namespace solidity::frontend; using namespace std::string_literals; +namespace +{ + +std::optional staticEncodingSize(std::vector const& _parameterTypes) +{ + size_t encodedSize = 0; + for (auto* type: _parameterTypes) + { + if (type->isDynamicallyEncoded()) + return std::nullopt; + encodedSize += type->calldataHeadSize(); + } + return encodedSize; +} + +} + std::string YulUtilFunctions::identityFunction() { std::string functionName = "identity"; @@ -226,9 +245,26 @@ std::string YulUtilFunctions::revertWithError( { solAssert((!_posVar.empty() && !_endVar.empty()) || (_posVar.empty() && _endVar.empty())); bool const needsNewVariable = !_posVar.empty() && !_endVar.empty(); + bool needsAllocation = true; + + if (std::optional size = staticEncodingSize(_parameterTypes)) + if ( + ranges::all_of(_parameterTypes, [](auto const* type) { + solAssert(!dynamic_cast(type)); + return type && type->isValueType(); + }) + ) + { + constexpr size_t errorSelectorSize = 4; + needsAllocation = *size + errorSelectorSize > CompilerUtils::generalPurposeMemoryStart; + } Whiskers templ(R"({ + let := () + + let := 0 + mstore(, ) let := (add(, 4) ) revert(, sub(, )) @@ -236,7 +272,9 @@ std::string YulUtilFunctions::revertWithError( templ("pos", needsNewVariable ? _posVar : "memPtr"); templ("end", needsNewVariable ? _endVar : "end"); templ("hash", formatNumber(util::selectorFromSignatureU256(_signature))); - templ("allocateUnbounded", allocateUnboundedFunction()); + templ("needsAllocation", needsAllocation); + if (needsAllocation) + templ("allocateUnbounded", allocateUnboundedFunction()); std::vector errorArgumentVars; std::vector errorArgumentTypes; @@ -282,7 +320,7 @@ std::string YulUtilFunctions::requireOrAssertFunction(bool _assert, Type const* } )") ("functionName", functionName) - ("revertWithError", revertWithError("Error(string)", {_messageType}, {_stringArgumentExpression})) + ("revertWithError", revertWithError("Error(string)", {TypeProvider::stringMemory()}, {_stringArgumentExpression})) ("functionParameterNames", joinHumanReadablePrefixed(functionParameterNames)) .render(); }); diff --git a/test/cmdlineTests/require_with_error_ir/output b/test/cmdlineTests/require_with_error_ir/output index 232f0d76fce9..09515f3cd82e 100644 --- a/test/cmdlineTests/require_with_error_ir/output +++ b/test/cmdlineTests/require_with_error_ir/output @@ -186,7 +186,9 @@ object "C_36" { function require_helper_t_error_7_CustomError_t_rational_1_by_1_t_stringliteral_332c39dcd398ea34a48b871898d589f55fc4c7bce00562fb670c972e7e1b0720(condition , expr_15) { if iszero(condition) { + let memPtr := allocate_unbounded() + mstore(memPtr, 0x97ea5a2f00000000000000000000000000000000000000000000000000000000) let end := abi_encode_tuple_t_rational_1_by_1_t_stringliteral_332c39dcd398ea34a48b871898d589f55fc4c7bce00562fb670c972e7e1b0720__to_t_uint256_t_string_memory_ptr__fromStack(add(memPtr, 4) , expr_15) revert(memPtr, sub(end, memPtr)) @@ -241,7 +243,9 @@ object "C_36" { function require_helper_t_error_7_CustomError_t_rational_2_by_1_t_stringliteral_89027a4db8d1d3a0787296eb1553fba0dc506f981f9697f1a66994c458d392b5(condition , expr_29) { if iszero(condition) { + let memPtr := allocate_unbounded() + mstore(memPtr, 0x97ea5a2f00000000000000000000000000000000000000000000000000000000) let end := abi_encode_tuple_t_rational_2_by_1_t_stringliteral_89027a4db8d1d3a0787296eb1553fba0dc506f981f9697f1a66994c458d392b5__to_t_uint256_t_string_memory_ptr__fromStack(add(memPtr, 4) , expr_29) revert(memPtr, sub(end, memPtr)) diff --git a/test/cmdlineTests/require_with_string_ir/output b/test/cmdlineTests/require_with_string_ir/output index 21828ac2a5ec..3a19db372796 100644 --- a/test/cmdlineTests/require_with_string_ir/output +++ b/test/cmdlineTests/require_with_string_ir/output @@ -228,7 +228,9 @@ object "C_28" { function require_helper_t_string_memory_ptr(condition , expr_12_mpos) { if iszero(condition) { + let memPtr := allocate_unbounded() + mstore(memPtr, 0x08c379a000000000000000000000000000000000000000000000000000000000) let end := abi_encode_tuple_t_string_memory_ptr__to_t_string_memory_ptr__fromStack(add(memPtr, 4) , expr_12_mpos) revert(memPtr, sub(end, memPtr)) @@ -266,7 +268,9 @@ object "C_28" { function require_helper_t_stringliteral_b25d43cff48de8365ad132c5f45b74f4593f9e69e5b749d86685f77282c88e46(condition ) { if iszero(condition) { + let memPtr := allocate_unbounded() + mstore(memPtr, 0x08c379a000000000000000000000000000000000000000000000000000000000) let end := abi_encode_tuple_t_stringliteral_b25d43cff48de8365ad132c5f45b74f4593f9e69e5b749d86685f77282c88e46__to_t_string_memory_ptr__fromStack(add(memPtr, 4) ) revert(memPtr, sub(end, memPtr)) diff --git a/test/libsolidity/semanticTests/errors/errors_by_parameter_type.sol b/test/libsolidity/semanticTests/errors/errors_by_parameter_type.sol new file mode 100644 index 000000000000..bc70b5bef757 --- /dev/null +++ b/test/libsolidity/semanticTests/errors/errors_by_parameter_type.sol @@ -0,0 +1,45 @@ +pragma abicoder v2; + +struct S { + uint256 a; + bool b; + string s; +} + +error E(); +error E1(uint256); +error E2(string); +error E3(S); +error E4(address); +error E5(function() external pure); + +contract C { + function a() external pure { + require(false, E()); + } + function b() external pure { + require(false, E1(1)); + } + function c() external pure { + require(false, E2("string literal")); + } + function d() external pure { + require(false, E3(S(1, true, "string literal"))); + } + function e() external view { + require(false, E4(address(this))); + } + function f() external view { + require(false, E5(this.a)); + } +} + +// ==== +// compileViaYul: true +// ---- +// a() -> FAILURE, hex"92bbf6e8" +// b() -> FAILURE, hex"47e26897", hex"0000000000000000000000000000000000000000000000000000000000000001" +// c() -> FAILURE, hex"8f372c34", hex"0000000000000000000000000000000000000000000000000000000000000020", hex"000000000000000000000000000000000000000000000000000000000000000e", hex"737472696e67206c69746572616c000000000000000000000000000000000000" +// d() -> FAILURE, hex"5717173e", hex"0000000000000000000000000000000000000000000000000000000000000020", hex"0000000000000000000000000000000000000000000000000000000000000001", hex"0000000000000000000000000000000000000000000000000000000000000001", hex"0000000000000000000000000000000000000000000000000000000000000060", hex"000000000000000000000000000000000000000000000000000000000000000e", hex"737472696e67206c69746572616c000000000000000000000000000000000000" +// e() -> FAILURE, hex"7efef9ea", hex"000000000000000000000000c06afe3a8444fc0004668591e8306bfb9968e79e" +// f() -> FAILURE, hex"0c3f12eb", hex"c06afe3a8444fc0004668591e8306bfb9968e79e0dbe671f0000000000000000" diff --git a/test/libsolidity/semanticTests/errors/small_error_optimization.sol b/test/libsolidity/semanticTests/errors/small_error_optimization.sol new file mode 100644 index 000000000000..0c9cd750aa32 --- /dev/null +++ b/test/libsolidity/semanticTests/errors/small_error_optimization.sol @@ -0,0 +1,22 @@ +error E(); +contract A { + uint8[] x; + function f() public { + for (uint i = 0; i < 100; ++i) + x.push(uint8(i)); + revert E(); + } +} +contract B { + function f() public { + (new A()).f(); + } +} +// ---- +// f() -> FAILURE, hex"92bbf6e8" +// gas irOptimized: 221918 +// gas irOptimized code: 42800 +// gas legacy: 233746 +// gas legacy code: 37400 +// gas legacyOptimized: 224864 +// gas legacyOptimized code: 34200 From e3e4f665232fbd77d81260a7f8f65f529cef68b3 Mon Sep 17 00:00:00 2001 From: r0qs Date: Mon, 13 May 2024 16:40:17 +0200 Subject: [PATCH 0208/1022] Remove bzzr entries from static binary section in the docs --- docs/installing-solidity.rst | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/docs/installing-solidity.rst b/docs/installing-solidity.rst index 8d5b421d3a19..f079fb0245a8 100644 --- a/docs/installing-solidity.rst +++ b/docs/installing-solidity.rst @@ -249,7 +249,6 @@ Each one includes a ``list.json`` file listing the available binaries. For examp "keccak256": "0x300330ecd127756b824aa13e843cb1f43c473cb22eaf3750d5fb9c99279af8c3", "sha256": "0x2b55ed5fec4d9625b6c7b3ab1abd2b7fb7dd2a9c68543bf0323db2c7e2d55af2", "urls": [ - "bzzr://16c5f09109c793db99fe35f037c6092b061bd39260ee7a677c8a97f18c955ab1", "dweb:/ipfs/QmTLs5MuLEWXQkths41HiACoXDiH8zxyqBHGFDRSzVE5CS" ] } @@ -264,7 +263,7 @@ This means that: In this case git is not necessary and symlinks are resolved transparently, either by serving a copy of the file or returning a HTTP redirect. - The file is also available on IPFS at `QmTLs5MuLEWXQkths41HiACoXDiH8zxyqBHGFDRSzVE5CS`_. -- The file might in future be available on Swarm at `16c5f09109c793db99fe35f037c6092b061bd39260ee7a677c8a97f18c955ab1`_. + Please, be aware that the order of items in the ``urls`` array is not predetermined or guaranteed and users should not rely on it. - You can verify the integrity of the binary by comparing its keccak256 hash to ``0x300330ecd127756b824aa13e843cb1f43c473cb22eaf3750d5fb9c99279af8c3``. The hash can be computed on the command-line using ``keccak256sum`` utility provided by `sha3sum`_ or `keccak256() function @@ -305,14 +304,12 @@ This means that: in the long-term. .. _IPFS: https://ipfs.io -.. _Swarm: https://swarm-gateways.net/bzz:/swarm.eth .. _solc-bin: https://github.com/ethereum/solc-bin/ .. _Solidity release page on GitHub: https://github.com/ethereum/solidity/releases .. _sha3sum: https://github.com/maandree/sha3sum .. _keccak256() function from ethereumjs-util: https://github.com/ethereumjs/ethereumjs-util/blob/master/docs/modules/_hash_.md#const-keccak256 .. _WebAssembly builds: https://emscripten.org/docs/compiling/WebAssembly.html .. _QmTLs5MuLEWXQkths41HiACoXDiH8zxyqBHGFDRSzVE5CS: https://gateway.ipfs.io/ipfs/QmTLs5MuLEWXQkths41HiACoXDiH8zxyqBHGFDRSzVE5CS -.. _16c5f09109c793db99fe35f037c6092b061bd39260ee7a677c8a97f18c955ab1: https://swarm-gateways.net/bzz:/16c5f09109c793db99fe35f037c6092b061bd39260ee7a677c8a97f18c955ab1/ .. _building-from-source: From 8216a70e5b308da5c0302395f62d89ec281ec99e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Wed, 15 May 2024 14:58:05 +0200 Subject: [PATCH 0209/1022] Add the missing changelog entry for the new default optimizer sequence --- Changelog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/Changelog.md b/Changelog.md index 6f129732c7fe..c6ec0a5533c4 100644 --- a/Changelog.md +++ b/Changelog.md @@ -7,6 +7,7 @@ Language Features: Compiler Features: * SMTChecker: Create balance check verification target for CHC engine. * Yul IR Code Generation: Cheaper code for reverting with errors of a small static encoding size. + * Yul Optimizer: New, faster default optimizer step sequence. Bugfixes: From 108d398a7cb9200087b1b0f5baf036414ea8c14c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Wed, 15 May 2024 16:14:33 +0200 Subject: [PATCH 0210/1022] Changelog: Optimizer -> Yul Optimizer in the entry for the superfluous sequence repetition bugfix --- Changelog.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Changelog.md b/Changelog.md index c6ec0a5533c4..443259806f63 100644 --- a/Changelog.md +++ b/Changelog.md @@ -12,7 +12,6 @@ Compiler Features: Bugfixes: * Commandline Interface: Fix ICE when the optimizer is disabled and an empty/blank string is used for ``--yul-optimizations`` sequence. - * Optimizer: Fix optimizer executing each repeating part of the step sequence at least twice, even if the code size already became stable after the first iteration. * SMTChecker: Fix false positive when comparing hashes of same array or string literals. * SMTChecker: Fix internal error on mapping access caused by too strong requirements on sort compatibility of the index and mapping domain. * SMTChecker: Fix internal error when using an empty tuple in a conditional operator. @@ -20,6 +19,7 @@ Bugfixes: * Standard JSON Interface: Fix ICE when the optimizer is disabled and an empty/blank string is used for ``optimizerSteps`` sequence. * StaticAnalyzer: Only raise a compile time error for division and modulo by zero when it's between literals. * TypeChecker: Fix compiler crash when the left-hand side of an assignment was a parenthesized non-tuple expression of a tuple type. + * Yul Optimizer: Fix optimizer executing each repeating part of the step sequence at least twice, even if the code size already became stable after the first iteration. * Yul Optimizer: Fix the order of assignments generated by ``SSATransform`` being dependent on AST IDs, sometimes resulting in different (but equivalent) bytecode when unrelated files were added to the compilation pipeline. From bbf5aa2f5b662b1d522e4eb280325ba2a30d5979 Mon Sep 17 00:00:00 2001 From: Daniel Kirchner Date: Wed, 15 May 2024 18:42:19 +0200 Subject: [PATCH 0211/1022] Remove json-cpp from create source tarball script. --- scripts/create_source_tarball.sh | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/scripts/create_source_tarball.sh b/scripts/create_source_tarball.sh index 1ea8c0b570f6..4af1cf586a47 100755 --- a/scripts/create_source_tarball.sh +++ b/scripts/create_source_tarball.sh @@ -29,17 +29,6 @@ REPO_ROOT="$(dirname "$0")"/.. then cp prerelease.txt "$SOLDIR/" fi - # Add dependencies - mkdir -p "$SOLDIR/deps/downloads/" 2>/dev/null || true - jsoncpp_version="1.9.3" - jsoncpp_package_path="$SOLDIR/deps/downloads/jsoncpp-${jsoncpp_version}.tar.gz" - jsoncpp_sha256=8593c1d69e703563d94d8c12244e2e18893eeb9a8a9f8aa3d09a327aa45c8f7d - wget -O "$jsoncpp_package_path" "https://github.com/open-source-parsers/jsoncpp/archive/${jsoncpp_version}.tar.gz" - if ! [ "$(sha256sum "$jsoncpp_package_path")" = "${jsoncpp_sha256} ${jsoncpp_package_path}" ] - then - >&2 echo "ERROR: Downloaded jsoncpp source package has wrong checksum." - exit 1 - fi mkdir -p "$REPO_ROOT/upload" tar --owner 0 --group 0 -czf "$REPO_ROOT/upload/solidity_$versionstring.tar.gz" -C "$TEMPDIR" "solidity_$versionstring" rm -r "$TEMPDIR" From 70e1edcebe3c0e5621ca590afae2744e9a284e92 Mon Sep 17 00:00:00 2001 From: Daniel Kirchner Date: Wed, 15 May 2024 18:39:25 +0200 Subject: [PATCH 0212/1022] Update PPA release script. --- scripts/deps-ppa/static_z3.sh | 2 +- scripts/release_ppa.sh | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/scripts/deps-ppa/static_z3.sh b/scripts/deps-ppa/static_z3.sh index be45f44526f8..016cd5d21e01 100755 --- a/scripts/deps-ppa/static_z3.sh +++ b/scripts/deps-ppa/static_z3.sh @@ -41,7 +41,7 @@ sourcePPAConfig # Sanity check checkDputEntries "\[cpp-build-deps\]" -DISTRIBUTIONS="focal jammy mantic" +DISTRIBUTIONS="focal jammy mantic noble" for distribution in $DISTRIBUTIONS do diff --git a/scripts/release_ppa.sh b/scripts/release_ppa.sh index 9a94fbcf2c56..0e4eb7ed4d92 100755 --- a/scripts/release_ppa.sh +++ b/scripts/release_ppa.sh @@ -68,7 +68,7 @@ packagename=solc # This needs to be a still active release static_build_distribution=focal -DISTRIBUTIONS="focal jammy mantic" +DISTRIBUTIONS="focal jammy mantic noble" if is_release then @@ -125,7 +125,8 @@ mv solidity solc # Fetch dependencies mkdir -p ./solc/deps/downloads/ 2>/dev/null || true -wget -O ./solc/deps/downloads/jsoncpp-1.9.3.tar.gz https://github.com/open-source-parsers/jsoncpp/archive/1.9.3.tar.gz +mkdir -p ./solc/deps/nlohmann/nlohmann/ 2>/dev/null || true +wget -O ./solc/deps/nlohmann/nlohmann/json.hpp https://github.com/nlohmann/json/releases/download/v3.11.3/json.hpp wget -O ./solc/deps/downloads/range-v3-0.12.0.tar.gz https://github.com/ericniebler/range-v3/archive/0.12.0.tar.gz wget -O ./solc/deps/downloads/fmt-9.1.0.tar.gz https://github.com/fmtlib/fmt/archive/9.1.0.tar.gz From 659d13fcbe97cd89ace325c3493e38253bb9f889 Mon Sep 17 00:00:00 2001 From: Daniel Kirchner Date: Wed, 15 May 2024 18:00:36 +0200 Subject: [PATCH 0213/1022] Add header include for docker builds. --- liblangutil/Token.h | 1 + 1 file changed, 1 insertion(+) diff --git a/liblangutil/Token.h b/liblangutil/Token.h index d1073a872b69..d9438271ca6a 100644 --- a/liblangutil/Token.h +++ b/liblangutil/Token.h @@ -42,6 +42,7 @@ #pragma once +#include #include #include #include From acec7170bad18b3dce83badec128e3cb75caec53 Mon Sep 17 00:00:00 2001 From: Daniel Kirchner Date: Wed, 15 May 2024 18:53:04 +0200 Subject: [PATCH 0214/1022] Update license template. --- cmake/templates/license.h.in | 221 ++++++++++++++++++++++++++++------- 1 file changed, 176 insertions(+), 45 deletions(-) diff --git a/cmake/templates/license.h.in b/cmake/templates/license.h.in index 2d7f2691a81c..7ade6be05929 100644 --- a/cmake/templates/license.h.in +++ b/cmake/templates/license.h.in @@ -3,7 +3,7 @@ #include static std::string const otherLicenses{R"(Most of the code is licensed under GPLv3 (see below), the license for individual -parts are as follows: +parts and dependencies are as follows: libkeccak-tiny: The file libsolutil/Keccak256.cpp incorporates libkeccak-tiny. @@ -11,6 +11,26 @@ 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. +nlohmann-json: + The source code of nlohmann-json is licensed under the following + conditions: + + The class is licensed under the MIT License: + + Copyright © 2013-2022 Niels Lohmann + + 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. + + The class contains the UTF-8 Decoder from Bjoern Hoehrmann which is licensed under the MIT License (see above). Copyright © 2008-2009 Björn Hoehrmann bjoern@hoehrmann.de + + The class contains a slightly modified version of the Grisu2 algorithm from Florian Loitsch which is licensed under the MIT License (see above). Copyright © 2009 Florian Loitsch + + The class contains a copy of Hedley from Evan Nemerson which is licensed as CC0-1.0. + picosha2: The file libsolutil/picosha2.h is imported. @@ -34,62 +54,160 @@ picosha2: 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 - conditions... +range-v3: + The range-v3 library is licensed under the following conditions: + + ======================================================== + Boost Software License - Version 1.0 - August 17th, 2003 + ======================================================== - The JsonCpp Authors explicitly disclaim copyright in all - jurisdictions which recognize such a disclaimer. In such jurisdictions, - this software is released into the Public Domain. + Permission is hereby granted, free of charge, to any person or organization + obtaining a copy of the software and accompanying documentation covered by + this license (the "Software") to use, reproduce, display, distribute, + execute, and transmit the Software, and to prepare derivative works of the + Software, and to permit third-parties to whom the Software is furnished to + do so, all subject to the following: - In jurisdictions which do not recognize Public Domain property (e.g. Germany as of - 2010), this software is Copyright (c) 2007-2010 by The JsonCpp Authors, and is - released under the terms of the MIT License (see below). + The copyright notices in the Software and this entire statement, including + the above license grant, this restriction and the following disclaimer, + must be included in all copies of the Software, in whole or in part, and + all derivative works of the Software, unless such copies or derivative + works are solely in the form of machine-executable object code generated by + a source language processor. - In jurisdictions which recognize Public Domain property, the user of this - software may choose to accept it either as 1) Public Domain, 2) under the - conditions of the MIT License (see below), or 3) under the terms of dual - Public Domain/MIT License conditions described here, as they choose. + 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, TITLE AND NON-INFRINGEMENT. IN NO EVENT + SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE + FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, + ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. - The MIT License is about as close to Public Domain as a license can get, and is - described in clear, concise terms at: + ============================================================================== + libc++ License + ============================================================================== - http://en.wikipedia.org/wiki/MIT_License + The libc++ library is dual licensed under both the University of Illinois + "BSD-Like" license and the MIT license. As a user of this code you may choose + to use it under either license. As a contributor, you agree to allow your code + to be used under both. - The full text of the MIT License follows: + Full text of the relevant licenses is included below. - ======================================================================== - Copyright (c) 2007-2010 The JsonCpp Authors + ============================================================================== - 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: + University of Illinois/NCSA + Open Source License - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. + Copyright (c) 2009-2014 by the contributors listed in CREDITS.TXT + http://llvm.org/svn/llvm-project/libcxx/trunk/CREDITS.TXT - 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 + All rights reserved. + + Developed by: + + LLVM Team + + University of Illinois at Urbana-Champaign + + http://llvm.org + + Permission is hereby granted, free of charge, to any person obtaining a copy of + this software and associated documentation files (the "Software"), to deal with + 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: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimers. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimers in the + documentation and/or other materials provided with the distribution. + + * Neither the names of the LLVM Team, University of Illinois at + Urbana-Champaign, nor the names of its contributors may be used to + endorse or promote products derived from this Software without specific + prior written permission. + + 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 + CONTRIBUTORS 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 WITH THE SOFTWARE. - ======================================================================== - (END LICENSE TEXT) - The MIT license is compatible with both the GPL and commercial - software, affording one all of the rights of Public Domain with the - minor nuisance of being required to keep the above copyright notice - and license text in the source code. Note also that by accepting the - Public Domain "license" you can re-license your copy using whatever - license you like. + ============================================================================== + + Copyright (c) 2009-2014 by the contributors listed in CREDITS.TXT + http://llvm.org/svn/llvm-project/libcxx/trunk/CREDITS.TXT + + 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. + + ============================================================================== + Stepanov and McJones, "Elements of Programming" license + ============================================================================== + + // Copyright (c) 2009 Alexander Stepanov and Paul McJones + // + // Permission to use, copy, modify, distribute and sell this software + // and its documentation for any purpose is hereby granted without + // fee, provided that the above copyright notice appear in all copies + // and that both that copyright notice and this permission notice + // appear in supporting documentation. The authors make no + // representations about the suitability of this software for any + // purpose. It is provided "as is" without express or implied + // warranty. + // + // Algorithms from + // Elements of Programming + // by Alexander Stepanov and Paul McJones + // Addison-Wesley Professional, 2009 + + ============================================================================== + SGI C++ Standard Template Library license + ============================================================================== + + // Copyright (c) 1994 + // Hewlett-Packard Company + // + // Permission to use, copy, modify, distribute and sell this software + // and its documentation for any purpose is hereby granted without fee, + // provided that the above copyright notice appear in all copies and + // that both that copyright notice and this permission notice appear + // in supporting documentation. Hewlett-Packard Company makes no + // representations about the suitability of this software for any + // purpose. It is provided "as is" without express or implied warranty. + // + // Copyright (c) 1996 + // Silicon Graphics Computer Systems, Inc. + // + // Permission to use, copy, modify, distribute and sell this software + // and its documentation for any purpose is hereby granted without fee, + // provided that the above copyright notice appear in all copies and + // that both that copyright notice and this permission notice appear + // in supporting documentation. Silicon Graphics makes no + // representations about the suitability of this software for any + // purpose. It is provided "as is" without express or implied warranty. + // scanner/token: The liblangutil/{CharStream,Scanner,Token}.{h,cpp} files are derived from @@ -167,6 +285,19 @@ base64: Any copyright is dedicated to the Public Domain. http://creativecommons.org/publicdomain/zero/1.0/ +Z3: + The Z3 library is licensed under the following terms: + + Copyright (c) Microsoft Corporation + All rights reserved. + MIT License + + 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. + All other code is licensed under GPL version 3: From 24f18e83a6c81935daa150c129b4007d5a41a014 Mon Sep 17 00:00:00 2001 From: hydai Date: Wed, 15 May 2024 23:39:26 +0800 Subject: [PATCH 0215/1022] Remove using namespace std from testing tools, ossfuzz and yulPhaser Signed-off-by: hydai --- scripts/check_style.sh | 4 + test/tools/afl_fuzzer.cpp | 23 +- test/tools/fuzzer_common.cpp | 43 ++- test/tools/isoltest.cpp | 121 ++++--- test/tools/ossfuzz/AbiV2IsabelleFuzzer.cpp | 11 +- .../SolidityCustomMutatorInterface.cpp | 7 +- .../tools/ossfuzz/SolidityEvmoneInterface.cpp | 19 +- test/tools/ossfuzz/SolidityGenerator.cpp | 53 ++- .../tools/ossfuzz/StackReuseCodegenFuzzer.cpp | 23 +- test/tools/ossfuzz/abiV2ProtoFuzzer.cpp | 13 +- test/tools/ossfuzz/const_opt_ossfuzz.cpp | 4 +- test/tools/ossfuzz/protoToAbiV2.cpp | 321 +++++++++--------- test/tools/ossfuzz/protoToSol.cpp | 59 ++-- test/tools/ossfuzz/protoToYul.cpp | 151 ++++---- .../ossfuzz/protomutators/YulProtoMutator.cpp | 9 +- test/tools/ossfuzz/solProtoFuzzer.cpp | 15 +- test/tools/ossfuzz/solc_ossfuzz.cpp | 9 +- .../ossfuzz/strictasm_assembly_ossfuzz.cpp | 5 +- test/tools/ossfuzz/strictasm_diff_ossfuzz.cpp | 9 +- test/tools/ossfuzz/strictasm_opt_ossfuzz.cpp | 5 +- test/tools/ossfuzz/yulFuzzerCommon.cpp | 5 +- test/tools/ossfuzz/yulProtoFuzzer.cpp | 11 +- test/tools/ossfuzz/yulProto_diff_ossfuzz.cpp | 19 +- test/tools/yulopti.cpp | 93 +++-- test/tools/yulrun.cpp | 31 +- tools/yulPhaser/AlgorithmRunner.cpp | 41 ++- tools/yulPhaser/Chromosome.cpp | 25 +- tools/yulPhaser/Common.cpp | 15 +- tools/yulPhaser/FitnessMetrics.cpp | 9 +- tools/yulPhaser/GeneticAlgorithms.cpp | 13 +- tools/yulPhaser/Mutations.cpp | 65 ++-- tools/yulPhaser/PairSelections.cpp | 23 +- tools/yulPhaser/Phaser.cpp | 195 ++++++----- tools/yulPhaser/Population.cpp | 53 ++- tools/yulPhaser/Program.cpp | 63 ++-- tools/yulPhaser/ProgramCache.cpp | 29 +- tools/yulPhaser/Selections.cpp | 27 +- tools/yulPhaser/SimulationRNG.cpp | 5 +- 38 files changed, 796 insertions(+), 830 deletions(-) diff --git a/scripts/check_style.sh b/scripts/check_style.sh index 3c9acf86ca74..e9d470b761bc 100755 --- a/scripts/check_style.sh +++ b/scripts/check_style.sh @@ -50,8 +50,12 @@ NAMESPACE_STD_FREE_FILES=( test/libsolidity/util/* test/libyul/* test/solc/* + test/tools/* + test/tools/ossfuzz/* + test/tools/ossfuzz/protomutators/* test/tools/yulInterpreter/* test/yulPhaser/* + tools/yulPhaser/* ) ( diff --git a/test/tools/afl_fuzzer.cpp b/test/tools/afl_fuzzer.cpp index af0939c2bd2c..bac98d76bf9b 100644 --- a/test/tools/afl_fuzzer.cpp +++ b/test/tools/afl_fuzzer.cpp @@ -28,7 +28,6 @@ #include #include -using namespace std; using namespace solidity; using namespace solidity::util; @@ -60,11 +59,11 @@ Allowed options)", ) ( "input-file", - po::value(), + po::value(), "input file" )( "input-files", - po::value>()->multitoken(), + po::value>()->multitoken(), "input files" ) ( @@ -86,7 +85,7 @@ Allowed options)", } catch (po::error const& _exception) { - cerr << _exception.what() << endl; + std::cerr << _exception.what() << std::endl; return 1; } @@ -95,26 +94,26 @@ Allowed options)", if (arguments.count("help")) { - cout << options; + std::cout << options; return 0; } - vector inputs; + std::vector inputs; if (arguments.count("input-file")) - inputs.push_back(arguments["input-file"].as()); + inputs.push_back(arguments["input-file"].as()); else if (arguments.count("input-files")) - inputs = arguments["input-files"].as>(); + inputs = arguments["input-files"].as>(); else inputs.emplace_back(""); bool optimize = !arguments.count("without-optimizer"); int retResult = 0; - for (string const& inputFile: inputs) + for (std::string const& inputFile: inputs) { - string input; + std::string input; if (inputFile.size() == 0) - input = readUntilEnd(cin); + input = readUntilEnd(std::cin); else input = readFileAsString(inputFile); @@ -134,7 +133,7 @@ Allowed options)", if (inputFile.size() == 0) throw; - cerr << "Fuzzer " + std::cerr << "Fuzzer " << (optimize ? "" : "(without optimizer) ") << "failed on " << inputFile; diff --git a/test/tools/fuzzer_common.cpp b/test/tools/fuzzer_common.cpp index c7e94f40b779..b054883820fc 100644 --- a/test/tools/fuzzer_common.cpp +++ b/test/tools/fuzzer_common.cpp @@ -33,14 +33,13 @@ #include -using namespace std; using namespace solidity; using namespace solidity::evmasm; using namespace solidity::frontend; using namespace solidity::langutil; using namespace solidity::util; -static vector s_evmVersions = { +static std::vector s_evmVersions = { EVMVersion::homestead(), EVMVersion::tangerineWhistle(), EVMVersion::spuriousDragon(), @@ -53,10 +52,10 @@ static vector s_evmVersions = { EVMVersion::paris() }; -void FuzzerUtil::testCompilerJsonInterface(string const& _input, bool _optimize, bool _quiet) +void FuzzerUtil::testCompilerJsonInterface(std::string const& _input, bool _optimize, bool _quiet) { if (!_quiet) - cout << "Testing compiler " << (_optimize ? "with" : "without") << " optimizer." << endl; + std::cout << "Testing compiler " << (_optimize ? "with" : "without") << " optimizer." << std::endl; Json config; config["language"] = "Solidity"; @@ -82,7 +81,7 @@ void FuzzerUtil::forceSMT(StringMap& _input) // Add SMT checker pragma if not already present in source static auto constexpr smtPragma = "pragma experimental SMTChecker;"; for (auto &sourceUnit: _input) - if (sourceUnit.second.find(smtPragma) == string::npos) + if (sourceUnit.second.find(smtPragma) == std::string::npos) sourceUnit.second += smtPragma; } @@ -144,13 +143,13 @@ void FuzzerUtil::testCompiler( } } -void FuzzerUtil::runCompiler(string const& _input, bool _quiet) +void FuzzerUtil::runCompiler(std::string const& _input, bool _quiet) { if (!_quiet) - cout << "Input JSON: " << _input << endl; - string outputString(solidity_compile(_input.c_str(), nullptr, nullptr)); + std::cout << "Input JSON: " << _input << std::endl; + std::string outputString(solidity_compile(_input.c_str(), nullptr, nullptr)); if (!_quiet) - cout << "Output JSON: " << outputString << endl; + std::cout << "Output JSON: " << outputString << std::endl; // This should be safe given the above copies the output. solidity_reset(); @@ -158,32 +157,32 @@ void FuzzerUtil::runCompiler(string const& _input, bool _quiet) Json output; if (!jsonParseStrict(outputString, output)) { - string msg{"Compiler produced invalid JSON output."}; - cout << msg << endl; + std::string msg{"Compiler produced invalid JSON output."}; + std::cout << msg << std::endl; BOOST_THROW_EXCEPTION(std::runtime_error(std::move(msg))); } if (output.contains("errors")) for (auto const& error: output["errors"]) { - string invalid = findAnyOf(error["type"].get(), vector{ + std::string invalid = findAnyOf(error["type"].get(), std::vector{ "Exception", "InternalCompilerError" }); if (!invalid.empty()) { - string msg = "Invalid error: \"" + error["type"].get() + "\""; - cout << msg << endl; + std::string msg = "Invalid error: \"" + error["type"].get() + "\""; + std::cout << msg << std::endl; BOOST_THROW_EXCEPTION(std::runtime_error(std::move(msg))); } } } -void FuzzerUtil::testConstantOptimizer(string const& _input, bool _quiet) +void FuzzerUtil::testConstantOptimizer(std::string const& _input, bool _quiet) { if (!_quiet) - cout << "Testing constant optimizer" << endl; - vector numbers; - stringstream sin(_input); + std::cout << "Testing constant optimizer" << std::endl; + std::vector numbers; + std::stringstream sin(_input); while (!sin.eof()) { @@ -192,7 +191,7 @@ void FuzzerUtil::testConstantOptimizer(string const& _input, bool _quiet) numbers.push_back(u256(data)); } if (!_quiet) - cout << "Got " << numbers.size() << " inputs:" << endl; + std::cout << "Got " << numbers.size() << " inputs:" << std::endl; for (bool isCreation: {false, true}) { @@ -200,7 +199,7 @@ void FuzzerUtil::testConstantOptimizer(string const& _input, bool _quiet) for (u256 const& n: numbers) { if (!_quiet) - cout << n << endl; + std::cout << n << std::endl; assembly.append(n); } for (unsigned runs: {1u, 2u, 3u, 20u, 40u, 100u, 200u, 400u, 1000u}) @@ -217,10 +216,10 @@ void FuzzerUtil::testConstantOptimizer(string const& _input, bool _quiet) } } -void FuzzerUtil::testStandardCompiler(string const& _input, bool _quiet) +void FuzzerUtil::testStandardCompiler(std::string const& _input, bool _quiet) { if (!_quiet) - cout << "Testing compiler via JSON interface." << endl; + std::cout << "Testing compiler via JSON interface." << std::endl; runCompiler(_input, _quiet); } diff --git a/test/tools/isoltest.cpp b/test/tools/isoltest.cpp index 9d20f1059fb3..fa56b35d7dc2 100644 --- a/test/tools/isoltest.cpp +++ b/test/tools/isoltest.cpp @@ -38,7 +38,6 @@ #include #endif -using namespace std; using namespace solidity; using namespace solidity::util; using namespace solidity::frontend; @@ -69,24 +68,24 @@ struct TestStats class TestFilter { public: - explicit TestFilter(string _filter): m_filter(std::move(_filter)) + explicit TestFilter(std::string _filter): m_filter(std::move(_filter)) { - string filter{m_filter}; + std::string filter{m_filter}; boost::replace_all(filter, "/", "\\/"); boost::replace_all(filter, "*", ".*"); - m_filterExpression = regex{"(" + filter + "(\\.sol|\\.yul|\\.stack))"}; + m_filterExpression = std::regex{"(" + filter + "(\\.sol|\\.yul|\\.stack))"}; } - bool matches(fs::path const& _path, string const& _name) const + bool matches(fs::path const& _path, std::string const& _name) const { - return regex_match(_name, m_filterExpression) && solidity::test::isValidSemanticTestPath(_path); + return std::regex_match(_name, m_filterExpression) && solidity::test::isValidSemanticTestPath(_path); } private: - string m_filter; - regex m_filterExpression; + std::string m_filter; + std::regex m_filterExpression; }; class TestTool @@ -96,7 +95,7 @@ class TestTool TestCreator _testCaseCreator, TestOptions const& _options, fs::path _path, - string _name + std::string _name ): m_testCaseCreator(_testCaseCreator), m_options(_options), @@ -137,9 +136,9 @@ class TestTool TestOptions const& m_options; TestFilter m_filter; fs::path const m_path; - string const m_name; + std::string const m_name; - unique_ptr m_test; + std::unique_ptr m_test; static bool m_exitRequested; }; @@ -154,7 +153,7 @@ TestTool::Result TestTool::process() { if (m_filter.matches(m_path, m_name)) { - (AnsiColorized(cout, formatted, {BOLD}) << m_name << ": ").flush(); + (AnsiColorized(std::cout, formatted, {BOLD}) << m_name << ": ").flush(); m_test = m_testCaseCreator(TestCase::Config{ m_path.string(), @@ -170,22 +169,22 @@ TestTool::Result TestTool::process() switch (TestCase::TestResult result = m_test->run(outputMessages, " ", formatted)) { case TestCase::TestResult::Success: - AnsiColorized(cout, formatted, {BOLD, GREEN}) << "OK" << endl; + AnsiColorized(std::cout, formatted, {BOLD, GREEN}) << "OK" << std::endl; return Result::Success; default: - AnsiColorized(cout, formatted, {BOLD, RED}) << "FAIL" << endl; + AnsiColorized(std::cout, formatted, {BOLD, RED}) << "FAIL" << std::endl; - AnsiColorized(cout, formatted, {BOLD, CYAN}) << " Contract:" << endl; - m_test->printSource(cout, " ", formatted); - m_test->printSettings(cout, " ", formatted); + AnsiColorized(std::cout, formatted, {BOLD, CYAN}) << " Contract:" << std::endl; + m_test->printSource(std::cout, " ", formatted); + m_test->printSettings(std::cout, " ", formatted); - cout << endl << outputMessages.str() << endl; + std::cout << std::endl << outputMessages.str() << std::endl; return result == TestCase::TestResult::FatalError ? Result::Exception : Result::Failure; } } else { - AnsiColorized(cout, formatted, {BOLD, YELLOW}) << "NOT RUN" << endl; + AnsiColorized(std::cout, formatted, {BOLD, YELLOW}) << "NOT RUN" << std::endl; return Result::Skipped; } } @@ -194,30 +193,30 @@ TestTool::Result TestTool::process() } catch (boost::exception const& _e) { - AnsiColorized(cout, formatted, {BOLD, RED}) << - "Exception during test: " << boost::diagnostic_information(_e) << endl; + AnsiColorized(std::cout, formatted, {BOLD, RED}) << + "Exception during test: " << boost::diagnostic_information(_e) << std::endl; return Result::Exception; } catch (std::exception const& _e) { - AnsiColorized(cout, formatted, {BOLD, RED}) << - "Exception during test: " << boost::diagnostic_information(_e) << endl; + AnsiColorized(std::cout, formatted, {BOLD, RED}) << + "Exception during test: " << boost::diagnostic_information(_e) << std::endl; return Result::Exception; } catch (...) { - AnsiColorized(cout, formatted, {BOLD, RED}) << - "Unknown exception during test: " << boost::current_exception_diagnostic_information() << endl; + AnsiColorized(std::cout, formatted, {BOLD, RED}) << + "Unknown exception during test: " << boost::current_exception_diagnostic_information() << std::endl; return Result::Exception; } } void TestTool::updateTestCase() { - ofstream file(m_path.string(), ios::trunc); + std::ofstream file(m_path.string(), std::ios::trunc); m_test->printSource(file); m_test->printUpdatedSettings(file); - file << "// ----" << endl; + file << "// ----" << std::endl; m_test->printUpdatedExpectations(file, "// "); } @@ -230,34 +229,34 @@ TestTool::Request TestTool::handleResponse(bool _exception) } if (_exception) - cout << "(e)dit/(s)kip/(q)uit? "; + std::cout << "(e)dit/(s)kip/(q)uit? "; else - cout << "(e)dit/(u)pdate expectations/(s)kip/(q)uit? "; - cout.flush(); + std::cout << "(e)dit/(u)pdate expectations/(s)kip/(q)uit? "; + std::cout.flush(); while (true) { switch(readStandardInputChar()) { case 's': - cout << endl; + std::cout << std::endl; return Request::Skip; case 'u': if (_exception) break; else { - cout << endl; + std::cout << std::endl; updateTestCase(); return Request::Rerun; } case 'e': - cout << endl << endl; + std::cout << std::endl << std::endl; if (system((m_options.editor + " \"" + m_path.string() + "\"").c_str())) - cerr << "Error running editor command." << endl << endl; + std::cerr << "Error running editor command." << std::endl << std::endl; return Request::Rerun; case 'q': - cout << endl; + std::cout << std::endl; return Request::Quit; default: break; @@ -326,7 +325,7 @@ TestStats TestTool::processPath( m_exitRequested = true; break; case Request::Rerun: - cout << "Re-running test case..." << endl; + std::cout << "Re-running test case..." << std::endl; --testCount; break; case Request::Skip: @@ -379,7 +378,7 @@ std::optional runTestSuite( TestOptions const& _options, fs::path const& _basePath, fs::path const& _subdirectory, - string const& _name, + std::string const& _name, solidity::test::Batcher& _batcher ) { @@ -388,7 +387,7 @@ std::optional runTestSuite( if (!fs::exists(testPath) || !fs::is_directory(testPath)) { - cerr << _name << " tests not found. Use the --testpath argument." << endl; + std::cerr << _name << " tests not found. Use the --testpath argument." << std::endl; return std::nullopt; } @@ -402,19 +401,19 @@ std::optional runTestSuite( if (stats.skippedCount != stats.testCount) { - cout << endl << _name << " Test Summary: "; - AnsiColorized(cout, formatted, {BOLD, stats ? GREEN : RED}) << + std::cout << std::endl << _name << " Test Summary: "; + AnsiColorized(std::cout, formatted, {BOLD, stats ? GREEN : RED}) << stats.successCount << "/" << stats.testCount; - cout << " tests successful"; + std::cout << " tests successful"; if (stats.skippedCount > 0) { - cout << " ("; - AnsiColorized(cout, formatted, {BOLD, YELLOW}) << stats.skippedCount; - cout<< " tests skipped)"; + std::cout << " ("; + AnsiColorized(std::cout, formatted, {BOLD, YELLOW}) << stats.skippedCount; + std::cout<< " tests skipped)"; } - cout << "." << endl << endl; + std::cout << "." << std::endl << std::endl; } return stats; } @@ -446,14 +445,14 @@ int main(int argc, char const *argv[]) return EXIT_FAILURE; if (options.disableSemanticTests) - cout << endl << "--- SKIPPING ALL SEMANTICS TESTS ---" << endl << endl; + std::cout << std::endl << "--- SKIPPING ALL SEMANTICS TESTS ---" << std::endl << std::endl; TestStats global_stats{0, 0}; - cout << "Running tests..." << endl << endl; + std::cout << "Running tests..." << std::endl << std::endl; Batcher batcher(CommonOptions::get().selectedBatch, CommonOptions::get().batches); if (CommonOptions::get().batches > 1) - cout << "Batch " << CommonOptions::get().selectedBatch << " out of " << CommonOptions::get().batches << endl; + std::cout << "Batch " << CommonOptions::get().selectedBatch << " out of " << CommonOptions::get().batches << std::endl; // Actually run the tests. // Interactive tests are added in InteractiveTests.h @@ -479,42 +478,42 @@ int main(int argc, char const *argv[]) return EXIT_FAILURE; } - cout << endl << "Summary: "; - AnsiColorized(cout, !options.noColor, {BOLD, global_stats ? GREEN : RED}) << + std::cout << std::endl << "Summary: "; + AnsiColorized(std::cout, !options.noColor, {BOLD, global_stats ? GREEN : RED}) << global_stats.successCount << "/" << global_stats.testCount; - cout << " tests successful"; + std::cout << " tests successful"; if (global_stats.skippedCount > 0) { - cout << " ("; - AnsiColorized(cout, !options.noColor, {BOLD, YELLOW}) << global_stats.skippedCount; - cout << " tests skipped)"; + std::cout << " ("; + AnsiColorized(std::cout, !options.noColor, {BOLD, YELLOW}) << global_stats.skippedCount; + std::cout << " tests skipped)"; } - cout << "." << endl; + std::cout << "." << std::endl; if (options.disableSemanticTests) - cout << "\nNOTE: Skipped semantics tests.\n" << endl; + std::cout << "\nNOTE: Skipped semantics tests.\n" << std::endl; return global_stats ? EXIT_SUCCESS : EXIT_FAILURE; } catch (boost::program_options::error const& exception) { - cerr << exception.what() << endl; + std::cerr << exception.what() << std::endl; return 2; } catch (std::runtime_error const& exception) { - cerr << exception.what() << endl; + std::cerr << exception.what() << std::endl; return 2; } catch (solidity::test::ConfigException const& exception) { - cerr << exception.what() << endl; + std::cerr << exception.what() << std::endl; return 2; } catch (...) { - cerr << "Unhandled exception caught." << endl; - cerr << boost::current_exception_diagnostic_information() << endl; + std::cerr << "Unhandled exception caught." << std::endl; + std::cerr << boost::current_exception_diagnostic_information() << std::endl; return 2; } } diff --git a/test/tools/ossfuzz/AbiV2IsabelleFuzzer.cpp b/test/tools/ossfuzz/AbiV2IsabelleFuzzer.cpp index 78697a9ddd10..e10979ee13e2 100644 --- a/test/tools/ossfuzz/AbiV2IsabelleFuzzer.cpp +++ b/test/tools/ossfuzz/AbiV2IsabelleFuzzer.cpp @@ -29,7 +29,6 @@ using namespace solidity::test::abiv2fuzzer; using namespace solidity::test; using namespace solidity::util; using namespace solidity; -using namespace std; static constexpr size_t abiCoderHeapSize = 1024 * 512; static evmc::VM evmone = evmc::VM{evmc_create_evmone()}; @@ -37,18 +36,18 @@ static evmc::VM evmone = evmc::VM{evmc_create_evmone()}; DEFINE_PROTO_FUZZER(Contract const& _contract) { ProtoConverter converter(_contract.seed()); - string contractSource = converter.contractToString(_contract); + std::string contractSource = converter.contractToString(_contract); if (const char* dump_path = getenv("PROTO_FUZZER_DUMP_PATH")) { // With libFuzzer binary run this to generate the solidity source file x.sol from a proto input: // PROTO_FUZZER_DUMP_PATH=x.sol ./a.out proto-input - ofstream of(dump_path); + std::ofstream of(dump_path); of << contractSource; } - string typeString = converter.isabelleTypeString(); - string valueString = converter.isabelleValueString(); + std::string typeString = converter.isabelleTypeString(); + std::string valueString = converter.isabelleValueString(); abicoder::ABICoder coder(abiCoderHeapSize); if (!typeString.empty() && converter.coderFunction()) { @@ -58,7 +57,7 @@ DEFINE_PROTO_FUZZER(Contract const& _contract) // We target the default EVM which is the latest langutil::EVMVersion version; EVMHost hostContext(version, evmone); - string contractName = "C"; + std::string contractName = "C"; StringMap source({{"test.sol", contractSource}}); CompilerInput cInput(version, source, contractName, OptimiserSettings::minimal(), {}); EvmoneUtility evmoneUtil( diff --git a/test/tools/ossfuzz/SolidityCustomMutatorInterface.cpp b/test/tools/ossfuzz/SolidityCustomMutatorInterface.cpp index ea5fa20ce4a7..738d69b8c0af 100644 --- a/test/tools/ossfuzz/SolidityCustomMutatorInterface.cpp +++ b/test/tools/ossfuzz/SolidityCustomMutatorInterface.cpp @@ -21,7 +21,6 @@ #include -using namespace std; using namespace solidity::test::fuzzer::mutator; // Prototype as we can't use the FuzzerInterface.h header. @@ -54,17 +53,17 @@ SolidityCustomMutatorInterface::SolidityCustomMutatorInterface( data(_data), size(_size), maxMutantSize(_maxSize), - generator(make_shared(_seed)) + generator(std::make_shared(_seed)) {} size_t SolidityCustomMutatorInterface::generate() { - string testCase = generator->generateTestProgram(); + std::string testCase = generator->generateTestProgram(); solAssert( !testCase.empty() && data, "Solc custom mutator: Invalid mutant or memory pointer" ); - size_t mutantSize = min(testCase.size(), maxMutantSize - 1); + size_t mutantSize = std::min(testCase.size(), maxMutantSize - 1); mempcpy(data, testCase.data(), mutantSize); return mutantSize; } diff --git a/test/tools/ossfuzz/SolidityEvmoneInterface.cpp b/test/tools/ossfuzz/SolidityEvmoneInterface.cpp index 9d98190ddacf..425239808be7 100644 --- a/test/tools/ossfuzz/SolidityEvmoneInterface.cpp +++ b/test/tools/ossfuzz/SolidityEvmoneInterface.cpp @@ -28,9 +28,8 @@ using namespace solidity::test::fuzzer; using namespace solidity::frontend; using namespace solidity::langutil; using namespace solidity::util; -using namespace std; -optional SolidityCompilationFramework::compileContract() +std::optional SolidityCompilationFramework::compileContract() { m_compiler.setSources(m_compilerInput.sourceCode); m_compiler.setLibraries(m_compilerInput.libraryAddresses); @@ -41,8 +40,8 @@ optional SolidityCompilationFramework::compileContract() { if (m_compilerInput.debugFailure) { - cerr << "Compiling contract failed" << endl; - cerr << SourceReferenceFormatter::formatErrorInformation( + std::cerr << "Compiling contract failed" << std::endl; + std::cerr << SourceReferenceFormatter::formatErrorInformation( m_compiler.errors(), m_compiler ); @@ -51,7 +50,7 @@ optional SolidityCompilationFramework::compileContract() } else { - string contractName; + std::string contractName; if (m_compilerInput.contractName.empty()) contractName = m_compiler.lastContractName(); else @@ -103,7 +102,7 @@ evmc::Result EvmoneUtility::deployContract(bytes const& _code) evmc::Result EvmoneUtility::deployAndExecute( bytes const& _byteCode, - string const& _hexEncodedInput + std::string const& _hexEncodedInput ) { // Deploy contract and signal failure if deploy failed @@ -128,9 +127,9 @@ evmc::Result EvmoneUtility::deployAndExecute( return callResult; } -evmc::Result EvmoneUtility::compileDeployAndExecute(string _fuzzIsabelle) +evmc::Result EvmoneUtility::compileDeployAndExecute(std::string _fuzzIsabelle) { - map libraryAddressMap; + std::map libraryAddressMap; // Stage 1: Compile and deploy library if present. if (!m_libraryName.empty()) { @@ -158,7 +157,7 @@ evmc::Result EvmoneUtility::compileDeployAndExecute(string _fuzzIsabelle) "SolidityEvmoneInterface: Invalid compilation output." ); - string methodName; + std::string methodName; if (!_fuzzIsabelle.empty()) // TODO: Remove this once a cleaner solution is found for querying // isabelle test entry point. At the moment, we are sure that the @@ -175,7 +174,7 @@ evmc::Result EvmoneUtility::compileDeployAndExecute(string _fuzzIsabelle) ); } -optional EvmoneUtility::compileContract() +std::optional EvmoneUtility::compileContract() { try { diff --git a/test/tools/ossfuzz/SolidityGenerator.cpp b/test/tools/ossfuzz/SolidityGenerator.cpp index 1d836a4aee36..1897de6f1209 100644 --- a/test/tools/ossfuzz/SolidityGenerator.cpp +++ b/test/tools/ossfuzz/SolidityGenerator.cpp @@ -23,7 +23,6 @@ using namespace solidity::test::fuzzer::mutator; using namespace solidity::util; -using namespace std; GeneratorBase::GeneratorBase(std::shared_ptr _mutator) { @@ -32,11 +31,11 @@ GeneratorBase::GeneratorBase(std::shared_ptr _mutator) uRandDist = mutator->uniformRandomDist(); } -string GeneratorBase::visitChildren() +std::string GeneratorBase::visitChildren() { - ostringstream os; + std::ostringstream os; // Randomise visit order - vector randomisedChildren; + std::vector randomisedChildren; for (auto const& child: generators) randomisedChildren.push_back(child); shuffle(randomisedChildren.begin(), randomisedChildren.end(), *uRandDist->randomEngine); @@ -47,7 +46,7 @@ string GeneratorBase::visitChildren() return os.str(); } -string TestState::randomPath(set const& _sourceUnitPaths) const +std::string TestState::randomPath(std::set const& _sourceUnitPaths) const { auto it = _sourceUnitPaths.begin(); /// Advance iterator by n where 0 <= n <= sourceUnitPaths.size() - 1 @@ -60,7 +59,7 @@ string TestState::randomPath(set const& _sourceUnitPaths) const return *it; } -string TestState::randomPath() const +std::string TestState::randomPath() const { solAssert(!empty(), "Solc custom mutator: Null test state"); return randomPath(sourceUnitPaths); @@ -73,20 +72,20 @@ void TestState::print(std::ostream& _os) const _os << "Source path: " << item << std::endl; } -string TestState::randomNonCurrentPath() const +std::string TestState::randomNonCurrentPath() const { /// To obtain a source path that is not the currently visited /// source unit itself, we require at least one other source /// unit to be previously visited. solAssert(size() >= 2, "Solc custom mutator: Invalid test state"); - set filteredSourcePaths; - string currentPath = currentSourceUnitPath; - copy_if( + std::set filteredSourcePaths; + std::string currentPath = currentSourceUnitPath; + std::copy_if( sourceUnitPaths.begin(), sourceUnitPaths.end(), inserter(filteredSourcePaths, filteredSourcePaths.begin()), - [currentPath](string const& _item) { + [currentPath](std::string const& _item) { return _item != currentPath; } ); @@ -100,12 +99,12 @@ void TestCaseGenerator::setup() }); } -string TestCaseGenerator::visit() +std::string TestCaseGenerator::visit() { - ostringstream os; + std::ostringstream os; for (unsigned i = 0; i < uRandDist->distributionOneToN(s_maxSourceUnits); i++) { - string sourcePath = path(); + std::string sourcePath = path(); os << "\n" << "==== Source: " << sourcePath @@ -126,32 +125,32 @@ void SourceUnitGenerator::setup() }); } -string SourceUnitGenerator::visit() +std::string SourceUnitGenerator::visit() { return visitChildren(); } -string PragmaGenerator::visit() +std::string PragmaGenerator::visit() { static constexpr const char* preamble = R"( pragma solidity >= 0.0.0; pragma experimental SMTChecker; )"; // Choose equally at random from coder v1 and v2 - string abiPragma = "pragma abicoder v" + - to_string(uRandDist->distributionOneToN(2)) + + std::string abiPragma = "pragma abicoder v" + + std::to_string(uRandDist->distributionOneToN(2)) + ";\n"; return preamble + abiPragma; } -string ImportGenerator::visit() +std::string ImportGenerator::visit() { /* * Case 1: No source units defined * Case 2: One source unit defined * Case 3: At least two source units defined */ - ostringstream os; + std::ostringstream os; // Self import with a small probability only if // there is one source unit present in test. if (state->size() == 1) @@ -175,19 +174,19 @@ string ImportGenerator::visit() } template -shared_ptr SolidityGenerator::generator() +std::shared_ptr SolidityGenerator::generator() { for (auto& g: m_generators) - if (holds_alternative>(g)) - return get>(g); + if (std::holds_alternative>(g)) + return std::get>(g); solAssert(false, ""); } SolidityGenerator::SolidityGenerator(unsigned _seed) { m_generators = {}; - m_urd = make_shared(make_unique(_seed)); - m_state = make_shared(m_urd); + m_urd = std::make_shared(std::make_unique(_seed)); + m_state = std::make_shared(m_urd); } template @@ -200,14 +199,14 @@ void SolidityGenerator::createGenerators() } } -string SolidityGenerator::generateTestProgram() +std::string SolidityGenerator::generateTestProgram() { createGenerators(); for (auto& g: m_generators) std::visit(GenericVisitor{ [&](auto const& _item) { return _item->setup(); } }, g); - string program = generator()->generate(); + std::string program = generator()->generate(); destroyGenerators(); return program; } diff --git a/test/tools/ossfuzz/StackReuseCodegenFuzzer.cpp b/test/tools/ossfuzz/StackReuseCodegenFuzzer.cpp index fb502af52778..25559bc66f27 100644 --- a/test/tools/ossfuzz/StackReuseCodegenFuzzer.cpp +++ b/test/tools/ossfuzz/StackReuseCodegenFuzzer.cpp @@ -46,7 +46,6 @@ using namespace solidity::test::fuzzer; using namespace solidity::yul; using namespace solidity::yul::test::yul_fuzzer; using namespace solidity::langutil; -using namespace std; static evmc::VM evmone = evmc::VM{evmc_create_evmone()}; @@ -80,7 +79,7 @@ DEFINE_PROTO_FUZZER(Program const& _input) filterStatefulInstructions, filterUnboundedLoops ); - string yul_source = converter.programToString(_input); + std::string yul_source = converter.programToString(_input); // Do not fuzz the EVM Version field. // See https://github.com/ethereum/solidity/issues/12590 langutil::EVMVersion version; @@ -89,8 +88,8 @@ DEFINE_PROTO_FUZZER(Program const& _input) if (const char* dump_path = getenv("PROTO_FUZZER_DUMP_PATH")) { - ofstream of(dump_path); - of.write(yul_source.data(), static_cast(yul_source.size())); + std::ofstream of(dump_path); + of.write(yul_source.data(), static_cast(yul_source.size())); } YulStringRepository::reset(); @@ -103,7 +102,7 @@ DEFINE_PROTO_FUZZER(Program const& _input) bool unoptimizedStackTooDeep = false; try { - YulAssembler assembler{version, nullopt, settings, yul_source}; + YulAssembler assembler{version, std::nullopt, settings, yul_source}; unoptimisedByteCode = assembler.assemble(); auto yulObject = assembler.object(); recursiveFunction = recursiveFunctionExists( @@ -116,7 +115,7 @@ DEFINE_PROTO_FUZZER(Program const& _input) unoptimizedStackTooDeep = true; } - ostringstream unoptimizedState; + std::ostringstream unoptimizedState; bool noRevertInSource = true; bool noInvalidInSource = true; if (!unoptimizedStackTooDeep) @@ -128,8 +127,8 @@ DEFINE_PROTO_FUZZER(Program const& _input) evmc::Result callResult = hostContext.call(callMessage); // If the fuzzer synthesized input does not contain the revert opcode which // we lazily check by string find, the EVM call should not revert. - noRevertInSource = yul_source.find("revert") == string::npos; - noInvalidInSource = yul_source.find("invalid") == string::npos; + noRevertInSource = yul_source.find("revert") == std::string::npos; + noInvalidInSource = yul_source.find("invalid") == std::string::npos; if (noInvalidInSource) solAssert( callResult.status_code != EVMC_INVALID_INSTRUCTION, @@ -157,7 +156,7 @@ DEFINE_PROTO_FUZZER(Program const& _input) bytes optimisedByteCode; try { - optimisedByteCode = YulAssembler{version, nullopt, settings, yul_source}.assemble(); + optimisedByteCode = YulAssembler{version, std::nullopt, settings, yul_source}.assemble(); } catch (solidity::yul::StackTooDeepError const&) { @@ -194,13 +193,13 @@ DEFINE_PROTO_FUZZER(Program const& _input) (!noInvalidInSource && callResultOpt.status_code == EVMC_INVALID_INSTRUCTION)), "Optimised call failed." ); - ostringstream optimizedState; + std::ostringstream optimizedState; optimizedState << EVMHostPrinter{hostContext, deployResultOpt.create_address}.state(); if (unoptimizedState.str() != optimizedState.str()) { - cout << unoptimizedState.str() << endl; - cout << optimizedState.str() << endl; + std::cout << unoptimizedState.str() << std::endl; + std::cout << optimizedState.str() << std::endl; solAssert( false, "State of unoptimised and optimised stack reused code do not match." diff --git a/test/tools/ossfuzz/abiV2ProtoFuzzer.cpp b/test/tools/ossfuzz/abiV2ProtoFuzzer.cpp index 6d792a70c56f..bdfe4e48c61b 100644 --- a/test/tools/ossfuzz/abiV2ProtoFuzzer.cpp +++ b/test/tools/ossfuzz/abiV2ProtoFuzzer.cpp @@ -29,27 +29,26 @@ using namespace solidity::test::abiv2fuzzer; using namespace solidity::test; using namespace solidity::util; using namespace solidity; -using namespace std; static evmc::VM evmone = evmc::VM{evmc_create_evmone()}; DEFINE_PROTO_FUZZER(Contract const& _input) { - string contract_source = ProtoConverter{_input.seed()}.contractToString(_input); + std::string contract_source = ProtoConverter{_input.seed()}.contractToString(_input); if (const char* dump_path = getenv("PROTO_FUZZER_DUMP_PATH")) { // With libFuzzer binary run this to generate the solidity source file x.sol from a proto input: // PROTO_FUZZER_DUMP_PATH=x.sol ./a.out proto-input - ofstream of(dump_path); + std::ofstream of(dump_path); of << contract_source; } // We target the default EVM which is the latest langutil::EVMVersion version; EVMHost hostContext(version, evmone); - string contractName = "C"; - string methodName = "test()"; + std::string contractName = "C"; + std::string methodName = "test()"; StringMap source({{"test.sol", contract_source}}); CompilerInput cInput(version, source, contractName, OptimiserSettings::minimal(), {}); EvmoneUtility evmoneUtil( @@ -67,9 +66,9 @@ DEFINE_PROTO_FUZZER(Contract const& _input) if (!EvmoneUtility::zeroWord(result.output_data, result.output_size)) { solidity::bytes res; - for (size_t i = 0; i < result.output_size; i++) + for (std::size_t i = 0; i < result.output_size; i++) res.push_back(result.output_data[i]); - cout << solidity::util::toHex(res) << endl; + std::cout << solidity::util::toHex(res) << std::endl; solAssert( false, "Proto ABIv2 fuzzer: ABIv2 coding failure found" diff --git a/test/tools/ossfuzz/const_opt_ossfuzz.cpp b/test/tools/ossfuzz/const_opt_ossfuzz.cpp index 0b799c956e6e..84ad87e7f8e8 100644 --- a/test/tools/ossfuzz/const_opt_ossfuzz.cpp +++ b/test/tools/ossfuzz/const_opt_ossfuzz.cpp @@ -18,8 +18,6 @@ #include -using namespace std; - // Prototype as we can't use the FuzzerInterface.h header. extern "C" int LLVMFuzzerTestOneInput(uint8_t const* _data, size_t _size); @@ -27,7 +25,7 @@ extern "C" int LLVMFuzzerTestOneInput(uint8_t const* _data, size_t _size) { if (_size <= 250) { - string input(reinterpret_cast(_data), _size); + std::string input(reinterpret_cast(_data), _size); FuzzerUtil::testConstantOptimizer(input, /*quiet=*/true); } return 0; diff --git a/test/tools/ossfuzz/protoToAbiV2.cpp b/test/tools/ossfuzz/protoToAbiV2.cpp index af2e5ede1b78..1511390ebb35 100644 --- a/test/tools/ossfuzz/protoToAbiV2.cpp +++ b/test/tools/ossfuzz/protoToAbiV2.cpp @@ -50,14 +50,13 @@ BOOST_PP_REPEAT(32, USINGDECL, 0) /// Switch implementation that instantiates case statements for (un)signed /// Solidity integer types. #define SWITCHIMPL(sign) \ - ostringstream stream; \ + std::ostringstream stream; \ switch (_intWidth) \ { \ BOOST_PP_REPEAT(32, CASEIMPL, sign) \ } \ return stream.str(); -using namespace std; using namespace solidity::util; using namespace solidity::test::abiv2fuzzer; @@ -75,17 +74,17 @@ static V integerValue(unsigned _counter) return value; } -static string signedIntegerValue(unsigned _counter, unsigned _intWidth) +static std::string signedIntegerValue(unsigned _counter, unsigned _intWidth) { SWITCHIMPL(1) } -static string unsignedIntegerValue(unsigned _counter, unsigned _intWidth) +static std::string unsignedIntegerValue(unsigned _counter, unsigned _intWidth) { SWITCHIMPL(0) } -static string integerValue(unsigned _counter, unsigned _intWidth, bool _signed) +static std::string integerValue(unsigned _counter, unsigned _intWidth, bool _signed) { if (_signed) return signedIntegerValue(_counter, _intWidth); @@ -94,10 +93,10 @@ static string integerValue(unsigned _counter, unsigned _intWidth, bool _signed) } } -string ProtoConverter::getVarDecl( - string const& _type, - string const& _varName, - string const& _qualifier +std::string ProtoConverter::getVarDecl( + std::string const& _type, + std::string const& _varName, + std::string const& _qualifier ) { // One level of indentation for state variable declarations @@ -114,7 +113,7 @@ string ProtoConverter::getVarDecl( "\n"; } -pair ProtoConverter::visit(Type const& _type) +std::pair ProtoConverter::visit(Type const& _type) { switch (_type.type_oneof_case()) { @@ -123,11 +122,11 @@ pair ProtoConverter::visit(Type const& _type) case Type::kNvtype: return visit(_type.nvtype()); case Type::TYPE_ONEOF_NOT_SET: - return make_pair("", ""); + return std::make_pair("", ""); } } -pair ProtoConverter::visit(ValueType const& _type) +std::pair ProtoConverter::visit(ValueType const& _type) { switch (_type.value_type_oneof_case()) { @@ -140,11 +139,11 @@ pair ProtoConverter::visit(ValueType const& _type) case ValueType::kAdty: return visit(_type.adty()); case ValueType::VALUE_TYPE_ONEOF_NOT_SET: - return make_pair("", ""); + return std::make_pair("", ""); } } -pair ProtoConverter::visit(NonValueType const& _type) +std::pair ProtoConverter::visit(NonValueType const& _type) { switch (_type.nonvalue_type_oneof_case()) { @@ -154,56 +153,56 @@ pair ProtoConverter::visit(NonValueType const& _type) if (ValidityVisitor().visit(_type.arrtype())) return visit(_type.arrtype()); else - return make_pair("", ""); + return std::make_pair("", ""); case NonValueType::kStype: if (ValidityVisitor().visit(_type.stype())) return visit(_type.stype()); else - return make_pair("", ""); + return std::make_pair("", ""); case NonValueType::NONVALUE_TYPE_ONEOF_NOT_SET: - return make_pair("", ""); + return std::make_pair("", ""); } } -pair ProtoConverter::visit(BoolType const& _type) +std::pair ProtoConverter::visit(BoolType const& _type) { return processType(_type, true); } -pair ProtoConverter::visit(IntegerType const& _type) +std::pair ProtoConverter::visit(IntegerType const& _type) { return processType(_type, true); } -pair ProtoConverter::visit(FixedByteType const& _type) +std::pair ProtoConverter::visit(FixedByteType const& _type) { return processType(_type, true); } -pair ProtoConverter::visit(AddressType const& _type) +std::pair ProtoConverter::visit(AddressType const& _type) { return processType(_type, true); } -pair ProtoConverter::visit(DynamicByteArrayType const& _type) +std::pair ProtoConverter::visit(DynamicByteArrayType const& _type) { return processType(_type, false); } -pair ProtoConverter::visit(ArrayType const& _type) +std::pair ProtoConverter::visit(ArrayType const& _type) { return processType(_type, false); } -pair ProtoConverter::visit(StructType const& _type) +std::pair ProtoConverter::visit(StructType const& _type) { return processType(_type, false); } template -pair ProtoConverter::processType(T const& _type, bool _isValueType) +std::pair ProtoConverter::processType(T const& _type, bool _isValueType) { - ostringstream local, global; + std::ostringstream local, global; auto [varName, paramName] = newVarNames(getNextVarCounter(), m_isStateVar); // Add variable name to the argument list of coder function call @@ -212,7 +211,7 @@ pair ProtoConverter::processType(T const& _type, bool _isValueTy else m_argsCoder << ", " << varName; - string location{}; + std::string location{}; if (!m_isStateVar && !_isValueType) location = "memory"; @@ -230,24 +229,24 @@ pair ProtoConverter::processType(T const& _type, bool _isValueTy local << assignCheckBuffers.second; m_structCounter += m_numStructsAdded; - return make_pair(global.str(), local.str()); + return std::make_pair(global.str(), local.str()); } template -pair ProtoConverter::varDecl( - string const& _varName, - string const& _paramName, +std::pair ProtoConverter::varDecl( + std::string const& _varName, + std::string const& _paramName, T _type, bool _isValueType, - string const& _location + std::string const& _location ) { - ostringstream local, global; + std::ostringstream local, global; TypeVisitor tVisitor(m_structCounter); - string typeStr = tVisitor.visit(_type); + std::string typeStr = tVisitor.visit(_type); if (typeStr.empty()) - return make_pair("", ""); + return std::make_pair("", ""); // Append struct defs global << tVisitor.structDef(); @@ -292,17 +291,17 @@ pair ProtoConverter::varDecl( if (tVisitor.isLastDynParamRightPadded()) m_isLastDynParamRightPadded = true; - return make_pair(global.str(), local.str()); + return std::make_pair(global.str(), local.str()); } template -pair ProtoConverter::assignChecker( - string const& _varName, - string const& _paramName, +std::pair ProtoConverter::assignChecker( + std::string const& _varName, + std::string const& _paramName, T _type ) { - ostringstream local; + std::ostringstream local; AssignCheckVisitor acVisitor( _varName, _paramName, @@ -311,7 +310,7 @@ pair ProtoConverter::assignChecker( m_counter, m_structCounter ); - pair assignCheckStrPair = acVisitor.visit(_type); + std::pair assignCheckStrPair = acVisitor.visit(_type); m_returnValue += acVisitor.errorStmts(); m_counter += acVisitor.counted(); @@ -325,10 +324,10 @@ pair ProtoConverter::assignChecker( // Therefore, we buffer their assignments and // render them in function scope later. local << assignCheckStrPair.first; - return make_pair("", local.str()); + return std::make_pair("", local.str()); } -pair ProtoConverter::visit(VarDecl const& _x) +std::pair ProtoConverter::visit(VarDecl const& _x) { return visit(_x.type()); } @@ -375,11 +374,11 @@ void ProtoConverter::appendTypedParams( void ProtoConverter::appendTypes( bool _isValueType, - string const& _typeString, + std::string const& _typeString, Delimiter _delimiter ) { - string qualifiedTypeString = ( + std::string qualifiedTypeString = ( _isValueType ? _typeString : _typeString + " memory" @@ -392,11 +391,11 @@ void ProtoConverter::appendTypes( void ProtoConverter::appendTypedReturn( bool _isValueType, - string const& _typeString, + std::string const& _typeString, Delimiter _delimiter ) { - string qualifiedTypeString = ( + std::string qualifiedTypeString = ( _isValueType ? _typeString : _typeString + " memory" @@ -404,7 +403,7 @@ void ProtoConverter::appendTypedReturn( m_typedReturn << Whiskers(R"( )") ("delimiter", delimiterToString(_delimiter)) ("type", qualifiedTypeString) - ("varName", "lv_" + to_string(m_varCounter - 1)) + ("varName", "lv_" + std::to_string(m_varCounter - 1)) .render(); } @@ -467,16 +466,16 @@ std::string ProtoConverter::typedParametersAsString(CalleeType _calleeType) return m_typedParamsPublic.str(); case CalleeType::EXTERNAL: { - ostringstream typedParamsExternal; + std::ostringstream typedParamsExternal; for (auto const& i: m_externalParamsRep) { - Delimiter del = get<0>(i); - bool valueType = get<1>(i); - string typeString = get<2>(i); - string varName = get<3>(i); + Delimiter del = std::get<0>(i); + bool valueType = std::get<1>(i); + std::string typeString = std::get<2>(i); + std::string varName = std::get<3>(i); bool isCalldata = randomBool(/*probability=*/0.5); - string location = (isCalldata ? "calldata" : "memory"); - string qualifiedTypeString = (valueType ? typeString : typeString + " " + location); + std::string location = (isCalldata ? "calldata" : "memory"); + std::string qualifiedTypeString = (valueType ? typeString : typeString + " " + location); typedParamsExternal << Whiskers(R"( )") ("delimiter", delimiterToString(del)) ("type", qualifiedTypeString) @@ -488,17 +487,17 @@ std::string ProtoConverter::typedParametersAsString(CalleeType _calleeType) } } -string ProtoConverter::visit(TestFunction const& _x, string const& _storageVarDefs) +std::string ProtoConverter::visit(TestFunction const& _x, std::string const& _storageVarDefs) { // TODO: Support more than one but less than N local variables auto localVarBuffers = visit(_x.local_vars()); - string structTypeDecl = localVarBuffers.first; - string localVarDefs = localVarBuffers.second; + std::string structTypeDecl = localVarBuffers.first; + std::string localVarDefs = localVarBuffers.second; - ostringstream testBuffer; + std::ostringstream testBuffer; - string testFunction = Whiskers(R"( + std::string testFunction = Whiskers(R"( function test() public returns (uint) { return test_calldata_coding(); return test_returndata_coding(); @@ -507,8 +506,8 @@ string ProtoConverter::visit(TestFunction const& _x, string const& _storageVarDe ("returndata", m_test == Contract_Test::Contract_Test_RETURNDATA_CODER) .render(); - string functionDeclCalldata = "function test_calldata_coding() internal returns (uint)"; - string functionDeclReturndata = "function test_returndata_coding() internal returns (uint)"; + std::string functionDeclCalldata = "function test_calldata_coding() internal returns (uint)"; + std::string functionDeclReturndata = "function test_returndata_coding() internal returns (uint)"; testBuffer << Whiskers(R"( @@ -551,7 +550,7 @@ string ProtoConverter::visit(TestFunction const& _x, string const& _storageVarDe return testBuffer.str(); } -string ProtoConverter::testCallDataFunction(unsigned _invalidLength) +std::string ProtoConverter::testCallDataFunction(unsigned _invalidLength) { return Whiskers(R"( uint returnVal = this.coder_calldata_public(); @@ -592,7 +591,7 @@ string ProtoConverter::testCallDataFunction(unsigned _invalidLength) .render(); } -string ProtoConverter::testReturnDataFunction() +std::string ProtoConverter::testReturnDataFunction() { return Whiskers(R"( @@ -607,9 +606,9 @@ string ProtoConverter::testReturnDataFunction() .render(); } -string ProtoConverter::calldataHelperFunctions() +std::string ProtoConverter::calldataHelperFunctions() { - stringstream calldataHelperFuncs; + std::stringstream calldataHelperFuncs; calldataHelperFuncs << R"( /// Accepts function selector, correct argument encoding, and length of /// invalid encoding and returns the correct and incorrect abi encoding @@ -676,12 +675,12 @@ string ProtoConverter::calldataHelperFunctions() })"; /// These are indirections to test memory-calldata codings more robustly. - stringstream indirections; + std::stringstream indirections; unsigned numIndirections = randomNumberOneToN(s_maxIndirections); for (unsigned i = 1; i <= numIndirections; i++) { bool finalIndirection = i == numIndirections; - string mutability = (finalIndirection ? "pure" : "view"); + std::string mutability = (finalIndirection ? "pure" : "view"); indirections << Whiskers(R"( function coder_calldata_external_i() external returns (uint) { @@ -692,12 +691,12 @@ string ProtoConverter::calldataHelperFunctions() } )") - ("N", to_string(i)) + ("N", std::to_string(i)) ("parameters", typedParametersAsString(CalleeType::EXTERNAL)) ("mutability", mutability) ("finalIndirection", finalIndirection) ("equality_checks", equalityChecksAsString()) - ("NPlusOne", to_string(i + 1)) + ("NPlusOne", std::to_string(i + 1)) ("untyped_parameters", m_untypedParamsExternal.str()) .render(); } @@ -726,9 +725,9 @@ string ProtoConverter::calldataHelperFunctions() return calldataHelperFuncs.str(); } -string ProtoConverter::commonHelperFunctions() +std::string ProtoConverter::commonHelperFunctions() { - stringstream helperFuncs; + std::stringstream helperFuncs; helperFuncs << R"( /// Compares bytes, returning true if they are equal and false otherwise. function bytesCompare(bytes memory a, bytes memory b) internal pure returns (bool) { @@ -746,7 +745,7 @@ string ProtoConverter::commonHelperFunctions() void ProtoConverter::visit(Contract const& _x) { - string pragmas = R"(pragma solidity >=0.0; + std::string pragmas = R"(pragma solidity >=0.0; pragma experimental ABIEncoderV2;)"; // Record test spec @@ -754,10 +753,10 @@ pragma experimental ABIEncoderV2;)"; // TODO: Support more than one but less than N state variables auto storageBuffers = visit(_x.state_vars()); - string storageVarDecls = storageBuffers.first; - string storageVarDefs = storageBuffers.second; + std::string storageVarDecls = storageBuffers.first; + std::string storageVarDefs = storageBuffers.second; m_isStateVar = false; - string testFunction = visit(_x.testfunction(), storageVarDefs); + std::string testFunction = visit(_x.testfunction(), storageVarDefs); /* Structure of contract body * - Storage variable declarations * - Struct definitions @@ -767,7 +766,7 @@ pragma experimental ABIEncoderV2;)"; * - Test code proper (calls public and external functions) * - Helper functions */ - ostringstream contractBody; + std::ostringstream contractBody; contractBody << storageVarDecls << testFunction << commonHelperFunctions(); @@ -782,32 +781,32 @@ pragma experimental ABIEncoderV2;)"; .render(); } -string ProtoConverter::isabelleTypeString() const +std::string ProtoConverter::isabelleTypeString() const { - string typeString = m_isabelleTypeString.str(); + std::string typeString = m_isabelleTypeString.str(); if (!typeString.empty()) return "(" + typeString + ")"; else return typeString; } -string ProtoConverter::isabelleValueString() const +std::string ProtoConverter::isabelleValueString() const { - string valueString = m_isabelleValueString.str(); + std::string valueString = m_isabelleValueString.str(); if (!valueString.empty()) return "(" + valueString + ")"; else return valueString; } -string ProtoConverter::contractToString(Contract const& _input) +std::string ProtoConverter::contractToString(Contract const& _input) { visit(_input); return m_output.str(); } /// Type visitor -void TypeVisitor::StructTupleString::addTypeStringToTuple(string& _typeString) +void TypeVisitor::StructTupleString::addTypeStringToTuple(std::string& _typeString) { index++; if (index > 1) @@ -815,51 +814,51 @@ void TypeVisitor::StructTupleString::addTypeStringToTuple(string& _typeString) stream << _typeString; } -void TypeVisitor::StructTupleString::addArrayBracketToType(string& _arrayBracket) +void TypeVisitor::StructTupleString::addArrayBracketToType(std::string& _arrayBracket) { stream << _arrayBracket; } -string TypeVisitor::visit(BoolType const&) +std::string TypeVisitor::visit(BoolType const&) { m_baseType = "bool"; m_structTupleString.addTypeStringToTuple(m_baseType); return m_baseType; } -string TypeVisitor::visit(IntegerType const& _type) +std::string TypeVisitor::visit(IntegerType const& _type) { m_baseType = getIntTypeAsString(_type); m_structTupleString.addTypeStringToTuple(m_baseType); return m_baseType; } -string TypeVisitor::visit(FixedByteType const& _type) +std::string TypeVisitor::visit(FixedByteType const& _type) { m_baseType = getFixedByteTypeAsString(_type); m_structTupleString.addTypeStringToTuple(m_baseType); return m_baseType; } -string TypeVisitor::visit(AddressType const&) +std::string TypeVisitor::visit(AddressType const&) { m_baseType = "address"; m_structTupleString.addTypeStringToTuple(m_baseType); return m_baseType; } -string TypeVisitor::visit(ArrayType const& _type) +std::string TypeVisitor::visit(ArrayType const& _type) { if (!ValidityVisitor().visit(_type)) return ""; - string baseType = visit(_type.t()); + std::string baseType = visit(_type.t()); solAssert(!baseType.empty(), ""); - string arrayBracket = _type.is_static() ? - string("[") + - to_string(getStaticArrayLengthFromFuzz(_type.length())) + - string("]") : - string("[]"); + std::string arrayBracket = _type.is_static() ? + std::string("[") + + std::to_string(getStaticArrayLengthFromFuzz(_type.length())) + + std::string("]") : + std::string("[]"); m_baseType += arrayBracket; m_structTupleString.addArrayBracketToType(arrayBracket); @@ -872,7 +871,7 @@ string TypeVisitor::visit(ArrayType const& _type) return baseType + arrayBracket; } -string TypeVisitor::visit(DynamicByteArrayType const&) +std::string TypeVisitor::visit(DynamicByteArrayType const&) { m_isLastDynParamRightPadded = true; m_baseType = "bytes"; @@ -893,10 +892,10 @@ void TypeVisitor::structDefinition(StructType const& _type) m_structFieldCounter = 0; // Commence struct declaration - string structDef = lineString( + std::string structDef = lineString( "struct " + - string(s_structNamePrefix) + - to_string(m_structCounter) + + std::string(s_structNamePrefix) + + std::to_string(m_structCounter) + " {" ); // Start tuple of types with parenthesis @@ -905,7 +904,7 @@ void TypeVisitor::structDefinition(StructType const& _type) m_indentation++; for (auto const& t: _type.t()) { - string type{}; + std::string type{}; if (!ValidityVisitor().visit(t)) continue; @@ -920,10 +919,10 @@ void TypeVisitor::structDefinition(StructType const& _type) structDef += lineString( Whiskers(R"( ;)") ("type", type) - ("member", "m" + to_string(m_structFieldCounter++)) + ("member", "m" + std::to_string(m_structFieldCounter++)) .render() ); - string isabelleTypeStr = tVisitor.isabelleTypeString(); + std::string isabelleTypeStr = tVisitor.isabelleTypeString(); m_structTupleString.addTypeStringToTuple(isabelleTypeStr); } m_indentation--; @@ -936,7 +935,7 @@ void TypeVisitor::structDefinition(StructType const& _type) m_structFieldCounter = wasFieldCounter; } -string TypeVisitor::visit(StructType const& _type) +std::string TypeVisitor::visit(StructType const& _type) { if (ValidityVisitor().visit(_type)) { @@ -945,7 +944,7 @@ string TypeVisitor::visit(StructType const& _type) // Set last dyn param if struct contains a dyn param e.g., bytes, array etc. m_isLastDynParamRightPadded = DynParamVisitor().visit(_type); // If top-level struct is a non-empty struct, assign the name S - m_baseType = s_structTypeName + to_string(m_structStartCounter); + m_baseType = s_structTypeName + std::to_string(m_structStartCounter); } else m_baseType = {}; @@ -954,7 +953,7 @@ string TypeVisitor::visit(StructType const& _type) } /// AssignCheckVisitor implementation -void AssignCheckVisitor::ValueStream::appendValue(string& _value) +void AssignCheckVisitor::ValueStream::appendValue(std::string& _value) { solAssert(!_value.empty(), "Abiv2 fuzzer: Empty value"); index++; @@ -963,77 +962,77 @@ void AssignCheckVisitor::ValueStream::appendValue(string& _value) stream << _value; } -pair AssignCheckVisitor::visit(BoolType const& _type) +std::pair AssignCheckVisitor::visit(BoolType const& _type) { - string value = ValueGetterVisitor(counter()).visit(_type); + std::string value = ValueGetterVisitor(counter()).visit(_type); if (!m_forcedVisit) m_valueStream.appendValue(value); return assignAndCheckStringPair(m_varName, m_paramName, value, value, DataType::VALUE); } -pair AssignCheckVisitor::visit(IntegerType const& _type) +std::pair AssignCheckVisitor::visit(IntegerType const& _type) { - string value = ValueGetterVisitor(counter()).visit(_type); + std::string value = ValueGetterVisitor(counter()).visit(_type); if (!m_forcedVisit) m_valueStream.appendValue(value); return assignAndCheckStringPair(m_varName, m_paramName, value, value, DataType::VALUE); } -pair AssignCheckVisitor::visit(FixedByteType const& _type) +std::pair AssignCheckVisitor::visit(FixedByteType const& _type) { - string value = ValueGetterVisitor(counter()).visit(_type); + std::string value = ValueGetterVisitor(counter()).visit(_type); if (!m_forcedVisit) { - string isabelleValue = ValueGetterVisitor{}.isabelleBytesValueAsString(value); + std::string isabelleValue = ValueGetterVisitor{}.isabelleBytesValueAsString(value); m_valueStream.appendValue(isabelleValue); } return assignAndCheckStringPair(m_varName, m_paramName, value, value, DataType::VALUE); } -pair AssignCheckVisitor::visit(AddressType const& _type) +std::pair AssignCheckVisitor::visit(AddressType const& _type) { - string value = ValueGetterVisitor(counter()).visit(_type); + std::string value = ValueGetterVisitor(counter()).visit(_type); if (!m_forcedVisit) { - string isabelleValue = ValueGetterVisitor{}.isabelleAddressValueAsString(value); + std::string isabelleValue = ValueGetterVisitor{}.isabelleAddressValueAsString(value); m_valueStream.appendValue(isabelleValue); } return assignAndCheckStringPair(m_varName, m_paramName, value, value, DataType::VALUE); } -pair AssignCheckVisitor::visit(DynamicByteArrayType const& _type) +std::pair AssignCheckVisitor::visit(DynamicByteArrayType const& _type) { - string value = ValueGetterVisitor(counter()).visit(_type); + std::string value = ValueGetterVisitor(counter()).visit(_type); if (!m_forcedVisit) { - string isabelleValue = ValueGetterVisitor{}.isabelleBytesValueAsString(value); + std::string isabelleValue = ValueGetterVisitor{}.isabelleBytesValueAsString(value); m_valueStream.appendValue(isabelleValue); } DataType dataType = DataType::BYTES; return assignAndCheckStringPair(m_varName, m_paramName, value, value, dataType); } -pair AssignCheckVisitor::visit(ArrayType const& _type) +std::pair AssignCheckVisitor::visit(ArrayType const& _type) { if (!ValidityVisitor().visit(_type)) - return make_pair("", ""); + return std::make_pair("", ""); // Obtain type of array to be resized and initialized - string typeStr{}; + std::string typeStr{}; unsigned wasStructCounter = m_structCounter; TypeVisitor tVisitor(m_structCounter); typeStr = tVisitor.visit(_type); - pair resizeBuffer; - string lengthStr; + std::pair resizeBuffer; + std::string lengthStr; unsigned length; // Resize dynamic arrays if (!_type.is_static()) { length = getDynArrayLengthFromFuzz(_type.length(), counter()); - lengthStr = to_string(length); + lengthStr = std::to_string(length); if (m_stateVar) { // Dynamic storage arrays are resized via the empty push() operation @@ -1048,7 +1047,7 @@ pair AssignCheckVisitor::visit(ArrayType const& _type) else { // Resizing memory arrays via the new operator - string resizeOp = Whiskers(R"(new ())") + std::string resizeOp = Whiskers(R"(new ())") ("fullTypeStr", typeStr) ("length", lengthStr) .render(); @@ -1064,22 +1063,22 @@ pair AssignCheckVisitor::visit(ArrayType const& _type) else { length = getStaticArrayLengthFromFuzz(_type.length()); - lengthStr = to_string(length); + lengthStr = std::to_string(length); // Add check on length resizeBuffer.second = checkString(m_paramName + ".length", lengthStr, DataType::VALUE); } // Add assignCheckBuffer and check statements - pair assignCheckBuffer; - string wasVarName = m_varName; - string wasParamName = m_paramName; + std::pair assignCheckBuffer; + std::string wasVarName = m_varName; + std::string wasParamName = m_paramName; if (!m_forcedVisit) m_valueStream.startArray(); for (unsigned i = 0; i < length; i++) { - m_varName = wasVarName + "[" + to_string(i) + "]"; - m_paramName = wasParamName + "[" + to_string(i) + "]"; - pair assign = visit(_type.t()); + m_varName = wasVarName + "[" + std::to_string(i) + "]"; + m_paramName = wasParamName + "[" + std::to_string(i) + "]"; + std::pair assign = visit(_type.t()); assignCheckBuffer.first += assign.first; assignCheckBuffer.second += assign.second; if (i < length - 1) @@ -1102,33 +1101,33 @@ pair AssignCheckVisitor::visit(ArrayType const& _type) m_paramName = wasParamName; // Compose resize and initialization assignment and check - return make_pair( + return std::make_pair( resizeBuffer.first + assignCheckBuffer.first, resizeBuffer.second + assignCheckBuffer.second ); } -pair AssignCheckVisitor::visit(StructType const& _type) +std::pair AssignCheckVisitor::visit(StructType const& _type) { if (!ValidityVisitor().visit(_type)) - return make_pair("", ""); + return std::make_pair("", ""); - pair assignCheckBuffer; + std::pair assignCheckBuffer; unsigned i = 0; // Increment struct counter m_structCounter++; - string wasVarName = m_varName; - string wasParamName = m_paramName; + std::string wasVarName = m_varName; + std::string wasParamName = m_paramName; if (!m_forcedVisit) m_valueStream.startStruct(); for (auto const& t: _type.t()) { - m_varName = wasVarName + ".m" + to_string(i); - m_paramName = wasParamName + ".m" + to_string(i); - pair assign = visit(t); + m_varName = wasVarName + ".m" + std::to_string(i); + m_paramName = wasParamName + ".m" + std::to_string(i); + std::pair assign = visit(t); // If type is not well formed continue without // updating state. if (assign.first.empty() && assign.second.empty()) @@ -1144,29 +1143,29 @@ pair AssignCheckVisitor::visit(StructType const& _type) return assignCheckBuffer; } -pair AssignCheckVisitor::assignAndCheckStringPair( - string const& _varRef, - string const& _checkRef, - string const& _assignValue, - string const& _checkValue, +std::pair AssignCheckVisitor::assignAndCheckStringPair( + std::string const& _varRef, + std::string const& _checkRef, + std::string const& _assignValue, + std::string const& _checkValue, DataType _type ) { - return make_pair(assignString(_varRef, _assignValue), checkString(_checkRef, _checkValue, _type)); + return std::make_pair(assignString(_varRef, _assignValue), checkString(_checkRef, _checkValue, _type)); } -string AssignCheckVisitor::assignString(string const& _ref, string const& _value) +std::string AssignCheckVisitor::assignString(std::string const& _ref, std::string const& _value) { - string assignStmt = Whiskers(R"( = ;)") + std::string assignStmt = Whiskers(R"( = ;)") ("ref", _ref) ("value", _value) .render(); return indentation() + assignStmt + "\n"; } -string AssignCheckVisitor::checkString(string const& _ref, string const& _value, DataType _type) +std::string AssignCheckVisitor::checkString(std::string const& _ref, std::string const& _value, DataType _type) { - string checkPred; + std::string checkPred; switch (_type) { case DataType::BYTES: @@ -1184,25 +1183,25 @@ string AssignCheckVisitor::checkString(string const& _ref, string const& _value, case DataType::ARRAY: solUnimplemented("Proto ABIv2 fuzzer: Invalid data type."); } - string checkStmt = Whiskers(R"(if () return ;)") + std::string checkStmt = Whiskers(R"(if () return ;)") ("checkPred", checkPred) - ("errCode", to_string(m_errorCode++)) + ("errCode", std::to_string(m_errorCode++)) .render(); return indentation() + checkStmt + "\n"; } /// ValueGetterVisitor -string ValueGetterVisitor::visit(BoolType const&) +std::string ValueGetterVisitor::visit(BoolType const&) { return counter() % 2 ? "true" : "false"; } -string ValueGetterVisitor::visit(IntegerType const& _type) +std::string ValueGetterVisitor::visit(IntegerType const& _type) { return integerValue(counter(), getIntWidth(_type), _type.is_signed()); } -string ValueGetterVisitor::visit(FixedByteType const& _type) +std::string ValueGetterVisitor::visit(FixedByteType const& _type) { return fixedByteValueAsString( getFixedByteWidth(_type), @@ -1210,12 +1209,12 @@ string ValueGetterVisitor::visit(FixedByteType const& _type) ); } -string ValueGetterVisitor::visit(AddressType const&) +std::string ValueGetterVisitor::visit(AddressType const&) { return addressValueAsString(counter()); } -string ValueGetterVisitor::visit(DynamicByteArrayType const&) +std::string ValueGetterVisitor::visit(DynamicByteArrayType const&) { return bytesArrayValueAsString( counter(), @@ -1331,7 +1330,7 @@ std::string ValueGetterVisitor::variableLengthValueAsString( unsigned numBytesRemaining = _numBytes; // Stores the literal - string output{}; + std::string output{}; // If requested value is shorter than or exactly 32 bytes, // the literal is the return value of hexValueAsString. if (numBytesRemaining <= 32) @@ -1350,7 +1349,7 @@ std::string ValueGetterVisitor::variableLengthValueAsString( // update number of bytes to be appended. // Stores the cached literal that saves us // (expensive) calls to keccak256. - string cachedString = hexValueAsString( + std::string cachedString = hexValueAsString( /*numBytes=*/32, _counter, _isHexLiteral, @@ -1398,7 +1397,7 @@ std::string ValueGetterVisitor::variableLengthValueAsString( .render(); } -string ValueGetterVisitor::bytesArrayValueAsString(unsigned _counter, bool _isHexLiteral) +std::string ValueGetterVisitor::bytesArrayValueAsString(unsigned _counter, bool _isHexLiteral) { return variableLengthValueAsString( getVarLength(_counter), diff --git a/test/tools/ossfuzz/protoToSol.cpp b/test/tools/ossfuzz/protoToSol.cpp index 73ed34b0d352..f8a60c4a0040 100644 --- a/test/tools/ossfuzz/protoToSol.cpp +++ b/test/tools/ossfuzz/protoToSol.cpp @@ -26,30 +26,29 @@ using namespace solidity::test::solprotofuzzer; using namespace solidity::util; -using namespace std; -string ProtoConverter::protoToSolidity(Program const& _p) +std::string ProtoConverter::protoToSolidity(Program const& _p) { // Create random number generator with fuzzer supplied // seed. - m_randomGen = make_shared(_p.seed()); + m_randomGen = std::make_shared(_p.seed()); return visit(_p); } -pair ProtoConverter::generateTestCase(TestContract const& _testContract) +std::pair ProtoConverter::generateTestCase(TestContract const& _testContract) { - ostringstream testCode; - string usingLibDecl; + std::ostringstream testCode; + std::string usingLibDecl; switch (_testContract.type()) { case TestContract::LIBRARY: { m_libraryTest = true; auto testTuple = pseudoRandomLibraryTest(); - m_libraryName = get<0>(testTuple); + m_libraryName = std::get<0>(testTuple); Whiskers u(R"(using for uint;)"); u("ind", "\t"); - u("libraryName", get<0>(testTuple)); + u("libraryName", std::get<0>(testTuple)); usingLibDecl = u.render(); Whiskers test(R"()"); test("endl", "\n"); @@ -57,8 +56,8 @@ pair ProtoConverter::generateTestCase(TestContract const& _testC test("varDecl", "uint x;"); Whiskers ifStmt(R"(if ()return 1;)"); Whiskers ifCond(R"(x.() != )"); - ifCond("testFunction", get<1>(testTuple)); - ifCond("expectedOutput", get<2>(testTuple)); + ifCond("testFunction", std::get<1>(testTuple)); + ifCond("expectedOutput", std::get<2>(testTuple)); ifStmt("cond", ifCond.render()); ifStmt("endl", "\n"); ifStmt("ind", "\t\t\t"); @@ -77,8 +76,8 @@ pair ProtoConverter::generateTestCase(TestContract const& _testC // running into stack too deep errors if (contractVarIndex >= s_maxVars) break; - string contractName = testTuple.first; - string contractVarName = "tc" + to_string(contractVarIndex); + std::string contractName = testTuple.first; + std::string contractVarName = "tc" + std::to_string(contractVarIndex); Whiskers init(R"( = new ();)"); init("endl", "\n"); init("ind", "\t\t"); @@ -98,7 +97,7 @@ pair ProtoConverter::generateTestCase(TestContract const& _testC ifStmt("endl", "\n"); ifStmt("cond", ifCond.render()); ifStmt("ind", "\t\t\t"); - ifStmt("errorCode", to_string(errorCode)); + ifStmt("errorCode", std::to_string(errorCode)); tc("ifStmt", ifStmt.render()); testCode << tc.render(); errorCode++; @@ -113,10 +112,10 @@ pair ProtoConverter::generateTestCase(TestContract const& _testC return {usingLibDecl, testCode.str()}; } -string ProtoConverter::visit(TestContract const& _testContract) +std::string ProtoConverter::visit(TestContract const& _testContract) { - string testCode; - string usingLibDecl; + std::string testCode; + std::string usingLibDecl; m_libraryTest = false; // Simply return valid uint (zero) if there are @@ -143,15 +142,15 @@ bool ProtoConverter::libraryTest() const return m_libraryTest; } -string ProtoConverter::libraryName() const +std::string ProtoConverter::libraryName() const { return m_libraryName; } -string ProtoConverter::visit(Program const& _p) +std::string ProtoConverter::visit(Program const& _p) { - ostringstream program; - ostringstream contracts; + std::ostringstream program; + std::ostringstream contracts; for (auto &contract: _p.contracts()) contracts << visit(contract); @@ -163,7 +162,7 @@ string ProtoConverter::visit(Program const& _p) return p.render(); } -string ProtoConverter::visit(ContractType const& _contractType) +std::string ProtoConverter::visit(ContractType const& _contractType) { switch (_contractType.contract_type_oneof_case()) { @@ -178,25 +177,25 @@ string ProtoConverter::visit(ContractType const& _contractType) } } -string ProtoConverter::visit(Contract const& _contract) +std::string ProtoConverter::visit(Contract const& _contract) { openProgramScope(&_contract); return ""; } -string ProtoConverter::visit(Interface const& _interface) +std::string ProtoConverter::visit(Interface const& _interface) { openProgramScope(&_interface); return ""; } -string ProtoConverter::visit(Library const& _library) +std::string ProtoConverter::visit(Library const& _library) { openProgramScope(&_library); return ""; } -tuple ProtoConverter::pseudoRandomLibraryTest() +std::tuple ProtoConverter::pseudoRandomLibraryTest() { solAssert(m_libraryTests.size() > 0, "Sol proto fuzzer: No library tests found"); unsigned index = randomNumber() % m_libraryTests.size(); @@ -205,18 +204,18 @@ tuple ProtoConverter::pseudoRandomLibraryTest() void ProtoConverter::openProgramScope(CIL _program) { - string programNamePrefix; - if (holds_alternative(_program)) + std::string programNamePrefix; + if (std::holds_alternative(_program)) programNamePrefix = "C"; - else if (holds_alternative(_program)) + else if (std::holds_alternative(_program)) programNamePrefix = "I"; else programNamePrefix = "L"; - string programName = programNamePrefix + to_string(m_programNumericSuffix++); + std::string programName = programNamePrefix + std::to_string(m_programNumericSuffix++); m_programNameMap.emplace(_program, programName); } -string ProtoConverter::programName(CIL _program) +std::string ProtoConverter::programName(CIL _program) { solAssert(m_programNameMap.count(_program), "Sol proto fuzzer: Unregistered program"); return m_programNameMap[_program]; diff --git a/test/tools/ossfuzz/protoToYul.cpp b/test/tools/ossfuzz/protoToYul.cpp index 1ba0d599d4b7..8822666c8b02 100644 --- a/test/tools/ossfuzz/protoToYul.cpp +++ b/test/tools/ossfuzz/protoToYul.cpp @@ -32,14 +32,13 @@ #include -using namespace std; using namespace solidity::yul::test::yul_fuzzer; using namespace solidity::yul::test; using namespace solidity::langutil; using namespace solidity::util; using namespace solidity; -string ProtoConverter::dictionaryToken(HexPrefix _p) +std::string ProtoConverter::dictionaryToken(HexPrefix _p) { std::string token; // If dictionary constant is requested while converting @@ -57,9 +56,9 @@ string ProtoConverter::dictionaryToken(HexPrefix _p) return _p == HexPrefix::Add ? "0x" + token : token; } -string ProtoConverter::createHex(string const& _hexBytes) +std::string ProtoConverter::createHex(std::string const& _hexBytes) { - string tmp{_hexBytes}; + std::string tmp{_hexBytes}; if (!tmp.empty()) { ranges::actions::remove_if(tmp, [=](char c) -> bool { @@ -79,9 +78,9 @@ string ProtoConverter::createHex(string const& _hexBytes) return tmp; } -string ProtoConverter::createAlphaNum(string const& _strBytes) +std::string ProtoConverter::createAlphaNum(std::string const& _strBytes) { - string tmp{_strBytes}; + std::string tmp{_strBytes}; if (!tmp.empty()) { ranges::actions::remove_if(tmp, [=](char c) -> bool { @@ -123,12 +122,12 @@ EVMVersion ProtoConverter::evmVersionMapping(Program_Version const& _ver) } } -string ProtoConverter::visit(Literal const& _x) +std::string ProtoConverter::visit(Literal const& _x) { switch (_x.literal_oneof_case()) { case Literal::kIntval: - return to_string(_x.intval()); + return std::to_string(_x.intval()); case Literal::kHexval: return "0x" + createHex(_x.hexval()); case Literal::kStrval: @@ -238,7 +237,7 @@ void ProtoConverter::visit(Expression const& _x) case Expression::kFuncExpr: if (auto v = functionExists(NumFunctionReturns::Single); v.has_value()) { - string functionName = v.value(); + std::string functionName = v.value(); visit(_x.func_expr(), functionName, true); } else @@ -359,11 +358,11 @@ void ProtoConverter::visit(BinaryOp const& _x) { m_output << "mod("; visit(_x.left()); - m_output << ", " << to_string(s_maxMemory - s_maxSize) << ")"; + m_output << ", " << std::to_string(s_maxMemory - s_maxSize) << ")"; m_output << ","; m_output << "mod("; visit(_x.right()); - m_output << ", " << to_string(s_maxSize) << ")"; + m_output << ", " << std::to_string(s_maxSize) << ")"; } else { @@ -374,7 +373,7 @@ void ProtoConverter::visit(BinaryOp const& _x) m_output << ")"; } -void ProtoConverter::scopeVariables(vector const& _varNames) +void ProtoConverter::scopeVariables(std::vector const& _varNames) { // If we are inside a for-init block, there are two places // where the visited vardecl may have been defined: @@ -443,7 +442,7 @@ void ProtoConverter::scopeVariables(vector const& _varNames) void ProtoConverter::visit(VarDecl const& _x) { - string varName = newVarName(); + std::string varName = newVarName(); m_output << "let " << varName << " := "; visit(_x.expr()); m_output << "\n"; @@ -453,14 +452,14 @@ void ProtoConverter::visit(VarDecl const& _x) void ProtoConverter::visit(MultiVarDecl const& _x) { m_output << "let "; - vector varNames; + std::vector varNames; // We support up to 4 variables in a single // declaration statement. unsigned numVars = _x.num_vars() % 3 + 2; - string delimiter; + std::string delimiter; for (unsigned i = 0; i < numVars; i++) { - string varName = newVarName(); + std::string varName = newVarName(); varNames.push_back(varName); m_output << delimiter << varName; if (i == 0) @@ -472,7 +471,7 @@ void ProtoConverter::visit(MultiVarDecl const& _x) void ProtoConverter::visit(TypedVarDecl const& _x) { - string varName = newVarName(); + std::string varName = newVarName(); m_output << "let " << varName; switch (_x.type()) { @@ -662,7 +661,7 @@ void ProtoConverter::visit(UnaryOp const& _x) { m_output << "mod("; visit(_x.operand()); - m_output << ", " << to_string(s_maxMemory - 32) << ")"; + m_output << ", " << std::to_string(s_maxMemory - 32) << ")"; } else visit(_x.operand()); @@ -844,20 +843,20 @@ void ProtoConverter::visit(CopyFunc const& _x) m_output << "("; m_output << "mod("; visit(_x.target()); - m_output << ", " << to_string(s_maxMemory - s_maxSize) << ")"; + m_output << ", " << std::to_string(s_maxMemory - s_maxSize) << ")"; m_output << ", "; if (type == CopyFunc::MEMORY) { m_output << "mod("; visit(_x.source()); - m_output << ", " << to_string(s_maxMemory - s_maxSize) << ")"; + m_output << ", " << std::to_string(s_maxMemory - s_maxSize) << ")"; } else visit(_x.source()); m_output << ", "; m_output << "mod("; visit(_x.size()); - m_output << ", " << to_string(s_maxSize) << ")"; + m_output << ", " << std::to_string(s_maxSize) << ")"; m_output << ")\n"; } @@ -869,13 +868,13 @@ void ProtoConverter::visit(ExtCodeCopy const& _x) m_output << ", "; m_output << "mod("; visit(_x.target()); - m_output << ", " << to_string(s_maxMemory - s_maxSize) << ")"; + m_output << ", " << std::to_string(s_maxMemory - s_maxSize) << ")"; m_output << ", "; visit(_x.source()); m_output << ", "; m_output << "mod("; visit(_x.size()); - m_output << ", " << to_string(s_maxSize) << ")"; + m_output << ", " << std::to_string(s_maxSize) << ")"; m_output << ")\n"; } @@ -884,11 +883,11 @@ void ProtoConverter::visit(LogFunc const& _x) auto visitPosAndSize = [&](LogFunc const& _y) { m_output << "mod("; visit(_y.pos()); - m_output << ", " << to_string(s_maxMemory - s_maxSize) << ")"; + m_output << ", " << std::to_string(s_maxMemory - s_maxSize) << ")"; m_output << ", "; m_output << "mod("; visit(_y.size()); - m_output << ", " << to_string(s_maxSize) << ")"; + m_output << ", " << std::to_string(s_maxSize) << ")"; }; switch (_x.num_topics()) @@ -984,7 +983,7 @@ void ProtoConverter::visitFunctionInputParams(FunctionCall const& _x, unsigned _ void ProtoConverter::convertFunctionCall( FunctionCall const& _x, - string const& _name, + std::string const& _name, unsigned _numInParams, bool _newLine ) @@ -996,10 +995,10 @@ void ProtoConverter::convertFunctionCall( m_output << "\n"; } -vector ProtoConverter::createVarDecls(unsigned _start, unsigned _end, bool _isAssignment) +std::vector ProtoConverter::createVarDecls(unsigned _start, unsigned _end, bool _isAssignment) { m_output << "let "; - vector varsVec = createVars(_start, _end); + std::vector varsVec = createVars(_start, _end); if (_isAssignment) m_output << " := "; else @@ -1007,7 +1006,7 @@ vector ProtoConverter::createVarDecls(unsigned _start, unsigned _end, bo return varsVec; } -optional ProtoConverter::functionExists(NumFunctionReturns _numReturns) +std::optional ProtoConverter::functionExists(NumFunctionReturns _numReturns) { for (auto const& item: m_functionSigMap) if (_numReturns == NumFunctionReturns::None || _numReturns == NumFunctionReturns::Single) @@ -1020,10 +1019,10 @@ optional ProtoConverter::functionExists(NumFunctionReturns _numReturns) if (item.second.second >= static_cast(_numReturns)) return item.first; } - return nullopt; + return std::nullopt; } -void ProtoConverter::visit(FunctionCall const& _x, string const& _functionName, bool _expression) +void ProtoConverter::visit(FunctionCall const& _x, std::string const& _functionName, bool _expression) { yulAssert(m_functionSigMap.count(_functionName), "Proto fuzzer: Invalid function."); auto ret = m_functionSigMap.at(_functionName); @@ -1038,7 +1037,7 @@ void ProtoConverter::visit(FunctionCall const& _x, string const& _functionName, else { yulAssert(numOutParams > 0, ""); - vector varsVec; + std::vector varsVec; if (!_expression) { // Obtain variable name suffix @@ -1096,19 +1095,19 @@ void ProtoConverter::visit(LowLevelCall const& _x) } m_output << "mod("; visit(_x.in()); - m_output << ", " << to_string(s_maxMemory - s_maxSize) << ")"; + m_output << ", " << std::to_string(s_maxMemory - s_maxSize) << ")"; m_output << ", "; m_output << "mod("; visit(_x.insize()); - m_output << ", " << to_string(s_maxSize) << ")"; + m_output << ", " << std::to_string(s_maxSize) << ")"; m_output << ", "; m_output << "mod("; visit(_x.out()); - m_output << ", " << to_string(s_maxMemory - s_maxSize) << ")"; + m_output << ", " << std::to_string(s_maxMemory - s_maxSize) << ")"; m_output << ", "; m_output << "mod("; visit(_x.outsize()); - m_output << ", " << to_string(s_maxSize) << ")"; + m_output << ", " << std::to_string(s_maxSize) << ")"; m_output << ")"; } @@ -1137,11 +1136,11 @@ void ProtoConverter::visit(Create const& _x) m_output << ", "; m_output << "mod("; visit(_x.position()); - m_output << ", " << to_string(s_maxMemory - s_maxSize) << ")"; + m_output << ", " << std::to_string(s_maxMemory - s_maxSize) << ")"; m_output << ", "; m_output << "mod("; visit(_x.size()); - m_output << ", " << to_string(s_maxSize) << ")"; + m_output << ", " << std::to_string(s_maxSize) << ")"; if (type == Create::CREATE2) { m_output << ", "; @@ -1183,7 +1182,7 @@ void ProtoConverter::visit(StoreFunc const& _x) { m_output << "mod("; visit(_x.loc()); - m_output << ", " << to_string(s_maxMemory) << ")"; + m_output << ", " << std::to_string(s_maxMemory) << ")"; } else if (storeType == StoreFunc::MSTORE) { @@ -1191,7 +1190,7 @@ void ProtoConverter::visit(StoreFunc const& _x) // upper bound on memory. m_output << "mod("; visit(_x.loc()); - m_output << ", " << to_string(s_maxMemory - 32) << ")"; + m_output << ", " << std::to_string(s_maxMemory - 32) << ")"; } m_output << ", "; @@ -1261,7 +1260,7 @@ void ProtoConverter::visit(BoundedForStmt const& _x) void ProtoConverter::visit(CaseStmt const& _x) { - string literal = visit(_x.case_lit()); + std::string literal = visit(_x.case_lit()); // u256 value of literal u256 literalVal; @@ -1278,7 +1277,7 @@ void ProtoConverter::visit(CaseStmt const& _x) // a case statement containing a case literal that has already been used in a // previous case statement. If the hash (u256 value) matches a previous hash, // then we simply don't create a new case statement. - string noDoubleQuoteStr; + std::string noDoubleQuoteStr; if (literal.size() > 2) { // Ensure that all characters in the string literal except the first @@ -1376,11 +1375,11 @@ void ProtoConverter::visit(RetRevStmt const& _x) m_output << "("; m_output << "mod("; visit(_x.pos()); - m_output << ", " << to_string(s_maxMemory - s_maxSize) << ")"; + m_output << ", " << std::to_string(s_maxMemory - s_maxSize) << ")"; m_output << ", "; m_output << "mod("; visit(_x.size()); - m_output << ", " << to_string(s_maxSize) << ")"; + m_output << ", " << std::to_string(s_maxSize) << ")"; m_output << ")\n"; } @@ -1527,14 +1526,14 @@ void ProtoConverter::openBlockScope() !m_funcVars.empty(), "Proto fuzzer: Invalid data structure" ); - m_funcVars.back().push_back(vector{}); + m_funcVars.back().push_back(std::vector{}); if (m_inForInitScope && m_forInitScopeExtEnabled) { yulAssert( !m_funcForLoopInitVars.empty(), "Proto fuzzer: Invalid data structure" ); - m_funcForLoopInitVars.back().push_back(vector{}); + m_funcForLoopInitVars.back().push_back(std::vector{}); } } else @@ -1545,13 +1544,13 @@ void ProtoConverter::openBlockScope() } } -void ProtoConverter::openFunctionScope(vector const& _funcParams) +void ProtoConverter::openFunctionScope(std::vector const& _funcParams) { - m_funcVars.push_back(vector>({_funcParams})); - m_funcForLoopInitVars.push_back(vector>({})); + m_funcVars.push_back(std::vector>({_funcParams})); + m_funcForLoopInitVars.push_back(std::vector>({})); } -void ProtoConverter::updateFunctionMaps(string const& _var) +void ProtoConverter::updateFunctionMaps(std::string const& _var) { size_t erased = m_functionSigMap.erase(_var); @@ -1609,7 +1608,7 @@ void ProtoConverter::closeFunctionScope() m_funcForLoopInitVars.pop_back(); } -void ProtoConverter::addVarsToScope(vector const& _vars) +void ProtoConverter::addVarsToScope(std::vector const& _vars) { // If we are in function definition, add the new vars to current function scope if (m_inFunctionDef) @@ -1706,12 +1705,12 @@ void ProtoConverter::visit(Block const& _x) closeBlockScope(); } -vector ProtoConverter::createVars(unsigned _startIdx, unsigned _endIdx) +std::vector ProtoConverter::createVars(unsigned _startIdx, unsigned _endIdx) { yulAssert(_endIdx > _startIdx, "Proto fuzzer: Variable indices not in range"); - string varsStr = suffixedVariableNameList("x_", _startIdx, _endIdx); + std::string varsStr = suffixedVariableNameList("x_", _startIdx, _endIdx); m_output << varsStr; - vector varsVec; + std::vector varsVec; boost::split( varsVec, varsStr, @@ -1740,14 +1739,14 @@ void ProtoConverter::registerFunction(FunctionDef const* _x) numReturns = NumFunctionReturns::Multiple; // Generate function name - string funcName = functionName(numReturns); + std::string funcName = functionName(numReturns); // Register function - auto ret = m_functionSigMap.emplace(make_pair(funcName, make_pair(numInParams, numOutParams))); + auto ret = m_functionSigMap.emplace(std::make_pair(funcName, std::make_pair(numInParams, numOutParams))); yulAssert(ret.second, "Proto fuzzer: Function already exists."); m_functions.push_back(funcName); m_scopeFuncs.back().push_back(funcName); - m_functionDefMap.emplace(make_pair(_x, funcName)); + m_functionDefMap.emplace(std::make_pair(_x, funcName)); } void ProtoConverter::fillFunctionCallInput(unsigned _numInParams) @@ -1760,7 +1759,7 @@ void ProtoConverter::fillFunctionCallInput(unsigned _numInParams) unsigned diceValue = counter() % 4; // Pseudo-randomly choose one of the first ten 32-byte // aligned slots. - string slot = to_string((counter() % 10) * 32); + std::string slot = std::to_string((counter() % 10) * 32); switch (diceValue) { case 0: @@ -1769,7 +1768,7 @@ void ProtoConverter::fillFunctionCallInput(unsigned _numInParams) case 1: { // Access memory within stipulated bounds - slot = "mod(" + dictionaryToken() + ", " + to_string(s_maxMemory - 32) + ")"; + slot = "mod(" + dictionaryToken() + ", " + std::to_string(s_maxMemory - 32) + ")"; m_output << "mload(" << slot << ")"; break; } @@ -1787,19 +1786,19 @@ void ProtoConverter::fillFunctionCallInput(unsigned _numInParams) } } -void ProtoConverter::saveFunctionCallOutput(vector const& _varsVec) +void ProtoConverter::saveFunctionCallOutput(std::vector const& _varsVec) { constexpr auto numSlots = 10; constexpr auto slotSize = 32; - for (string const& var: _varsVec) + for (std::string const& var: _varsVec) { // Flip a dice to choose whether to save output values // in storage or memory. unsigned diceThrow = counter() % (m_evmVersion.supportsTransientStorage() ? 3 : 2); // Pseudo-randomly choose one of the first ten 32-byte // aligned slots. - string slot = std::to_string((counter() % numSlots) * slotSize); + std::string slot = std::to_string((counter() % numSlots) * slotSize); if (diceThrow == 0) m_output << "sstore(" << slot << ", " << var << ")\n"; else if (diceThrow == 1) @@ -1816,12 +1815,12 @@ void ProtoConverter::saveFunctionCallOutput(vector const& _varsVec) } void ProtoConverter::createFunctionCall( - string const& _funcName, + std::string const& _funcName, unsigned _numInParams, unsigned _numOutParams ) { - vector varsVec{}; + std::vector varsVec{}; if (_numOutParams > 0) { unsigned startIdx = counter(); @@ -1864,16 +1863,16 @@ void ProtoConverter::createFunctionDefAndCall( // Obtain function name yulAssert(m_functionDefMap.count(&_x), "Proto fuzzer: Unregistered function"); - string funcName = m_functionDefMap.at(&_x); + std::string funcName = m_functionDefMap.at(&_x); - vector varsVec = {}; + std::vector varsVec = {}; m_output << "function " << funcName << "("; unsigned startIdx = counter(); if (_numInParams > 0) varsVec = createVars(startIdx, startIdx + _numInParams); m_output << ")"; - vector outVarsVec = {}; + std::vector outVarsVec = {}; // This creates -> x_n+1,...,x_r if (_numOutParams > 0) { @@ -1937,15 +1936,15 @@ void ProtoConverter::visit(LeaveStmt const&) m_output << "leave\n"; } -string ProtoConverter::getObjectIdentifier(unsigned _x) +std::string ProtoConverter::getObjectIdentifier(unsigned _x) { unsigned currentId = currentObjectId(); - string currentObjName = "object" + to_string(currentId); + std::string currentObjName = "object" + std::to_string(currentId); yulAssert( m_objectScope.count(currentObjName) && !m_objectScope.at(currentObjName).empty(), "Yul proto fuzzer: Error referencing object" ); - vector objectIdsInScope = m_objectScope.at(currentObjName); + std::vector objectIdsInScope = m_objectScope.at(currentObjName); return objectIdsInScope[_x % objectIdsInScope.size()]; } @@ -1979,8 +1978,8 @@ void ProtoConverter::visit(Object const& _x) void ProtoConverter::buildObjectScopeTree(Object const& _x) { // Identifies object being visited - string objectName = newObjectId(false); - vector node{objectName}; + std::string objectName = newObjectId(false); + std::vector node{objectName}; if (_x.has_data()) node.emplace_back(s_dataIdentifier); for (auto const& subObj: _x.sub_obj()) @@ -1988,12 +1987,12 @@ void ProtoConverter::buildObjectScopeTree(Object const& _x) // Identifies sub object whose numeric suffix is // m_objectId unsigned subObjectId = m_objectId; - string subObjectName = "object" + to_string(subObjectId); + std::string subObjectName = "object" + std::to_string(subObjectId); node.push_back(subObjectName); buildObjectScopeTree(subObj); // Add sub-object to object's ancestors yulAssert(m_objectScope.count(subObjectName), "Yul proto fuzzer: Invalid object hierarchy"); - for (string const& item: m_objectScope.at(subObjectName)) + for (std::string const& item: m_objectScope.at(subObjectName)) if (item != subObjectName) node.emplace_back(subObjectName + "." + item); } @@ -2033,13 +2032,13 @@ void ProtoConverter::visit(Program const& _x) } } -string ProtoConverter::programToString(Program const& _input) +std::string ProtoConverter::programToString(Program const& _input) { visit(_input); return m_output.str(); } -string ProtoConverter::functionTypeToString(NumFunctionReturns _type) +std::string ProtoConverter::functionTypeToString(NumFunctionReturns _type) { switch (_type) { diff --git a/test/tools/ossfuzz/protomutators/YulProtoMutator.cpp b/test/tools/ossfuzz/protomutators/YulProtoMutator.cpp index 9b0c97a22df0..bf370dd37851 100644 --- a/test/tools/ossfuzz/protomutators/YulProtoMutator.cpp +++ b/test/tools/ossfuzz/protomutators/YulProtoMutator.cpp @@ -6,11 +6,10 @@ using namespace solidity::yul::test::yul_fuzzer; using namespace protobuf_mutator; -using namespace std; using YPM = YulProtoMutator; -MutationInfo::MutationInfo(ProtobufMessage const* _message, string const& _info): +MutationInfo::MutationInfo(ProtobufMessage const* _message, std::string const& _info): ScopeGuard([&]{ exitInfo(); }), m_protobufMsg(_message) { @@ -60,7 +59,7 @@ struct addControlFlow /// Unused variable registers callback. LPMPostProcessor callback(function); } - function function; + std::function function; }; } @@ -182,7 +181,7 @@ void YPM::addControlFlow(T* _msg, unsigned _seed) Leave, Termination }; - uniform_int_distribution d( + std::uniform_int_distribution d( static_cast(ControlFlowStmt::For), static_cast(ControlFlowStmt::Termination) ); @@ -229,7 +228,7 @@ Block* YPM::randomBlock(ForStmt* _stmt, unsigned _seed) Post = 1, Body = 2 }; - uniform_int_distribution d( + std::uniform_int_distribution d( static_cast(ForBlocks::Init), static_cast(ForBlocks::Body) ); diff --git a/test/tools/ossfuzz/solProtoFuzzer.cpp b/test/tools/ossfuzz/solProtoFuzzer.cpp index f7acc6c10de7..06edd3e99ae8 100644 --- a/test/tools/ossfuzz/solProtoFuzzer.cpp +++ b/test/tools/ossfuzz/solProtoFuzzer.cpp @@ -35,19 +35,18 @@ using namespace solidity; using namespace solidity::frontend; using namespace solidity::test; using namespace solidity::util; -using namespace std; DEFINE_PROTO_FUZZER(Program const& _input) { ProtoConverter converter; - string sol_source = converter.protoToSolidity(_input); + std::string sol_source = converter.protoToSolidity(_input); if (char const* dump_path = getenv("PROTO_FUZZER_DUMP_PATH")) { // With libFuzzer binary run this to generate a YUL source file x.yul: // PROTO_FUZZER_DUMP_PATH=x.yul ./a.out proto-input - ofstream of(dump_path); - of.write(sol_source.data(), static_cast(sol_source.size())); + std::ofstream of(dump_path); + of.write(sol_source.data(), static_cast(sol_source.size())); } if (char const* dump_path = getenv("SOL_DEBUG_FILE")) @@ -55,7 +54,7 @@ DEFINE_PROTO_FUZZER(Program const& _input) sol_source.clear(); // With libFuzzer binary run this to generate a YUL source file x.yul: // PROTO_FUZZER_LOAD_PATH=x.yul ./a.out proto-input - ifstream ifstr(dump_path); + std::ifstream ifstr(dump_path); sol_source = { std::istreambuf_iterator(ifstr), std::istreambuf_iterator() @@ -66,9 +65,9 @@ DEFINE_PROTO_FUZZER(Program const& _input) // We target the default EVM which is the latest langutil::EVMVersion version; EVMHost hostContext(version, evmone); - string contractName = "C"; - string libraryName = converter.libraryTest() ? converter.libraryName() : ""; - string methodName = "test()"; + std::string contractName = "C"; + std::string libraryName = converter.libraryTest() ? converter.libraryName() : ""; + std::string methodName = "test()"; StringMap source({{"test.sol", sol_source}}); CompilerInput cInput(version, source, contractName, OptimiserSettings::minimal(), {}); EvmoneUtility evmoneUtil( diff --git a/test/tools/ossfuzz/solc_ossfuzz.cpp b/test/tools/ossfuzz/solc_ossfuzz.cpp index 620ef332b976..dc7e26a2aeae 100644 --- a/test/tools/ossfuzz/solc_ossfuzz.cpp +++ b/test/tools/ossfuzz/solc_ossfuzz.cpp @@ -23,7 +23,6 @@ #include using namespace solidity::frontend::test; -using namespace std; // Prototype as we can't use the FuzzerInterface.h header. extern "C" int LLVMFuzzerTestOneInput(uint8_t const* _data, size_t _size); @@ -32,13 +31,13 @@ extern "C" int LLVMFuzzerTestOneInput(uint8_t const* _data, size_t _size) { if (_size <= 600) { - string input(reinterpret_cast(_data), _size); - map sourceCode; + std::string input(reinterpret_cast(_data), _size); + std::map sourceCode; try { TestCaseReader t = TestCaseReader(std::istringstream(input)); sourceCode = t.sources().sources; - map settings = t.settings(); + std::map settings = t.settings(); bool compileViaYul = settings.count("compileViaYul") && (settings.at("compileViaYul") == "also" || settings.at("compileViaYul") == "true"); @@ -51,7 +50,7 @@ extern "C" int LLVMFuzzerTestOneInput(uint8_t const* _data, size_t _size) compileViaYul ); } - catch (runtime_error const&) + catch (std::runtime_error const&) { return 0; } diff --git a/test/tools/ossfuzz/strictasm_assembly_ossfuzz.cpp b/test/tools/ossfuzz/strictasm_assembly_ossfuzz.cpp index c7ffd3d417a3..595aecdca3f4 100644 --- a/test/tools/ossfuzz/strictasm_assembly_ossfuzz.cpp +++ b/test/tools/ossfuzz/strictasm_assembly_ossfuzz.cpp @@ -24,7 +24,6 @@ using namespace solidity; using namespace solidity::yul; -using namespace std; // Prototype as we can't use the FuzzerInterface.h header. extern "C" int LLVMFuzzerTestOneInput(uint8_t const* _data, size_t _size); @@ -36,10 +35,10 @@ extern "C" int LLVMFuzzerTestOneInput(uint8_t const* _data, size_t _size) YulStringRepository::reset(); - string input(reinterpret_cast(_data), _size); + std::string input(reinterpret_cast(_data), _size); YulStack stack( langutil::EVMVersion(), - nullopt, + std::nullopt, YulStack::Language::StrictAssembly, solidity::frontend::OptimiserSettings::minimal(), langutil::DebugInfoSelection::All() diff --git a/test/tools/ossfuzz/strictasm_diff_ossfuzz.cpp b/test/tools/ossfuzz/strictasm_diff_ossfuzz.cpp index 5c923a3ea718..e31391b0e15b 100644 --- a/test/tools/ossfuzz/strictasm_diff_ossfuzz.cpp +++ b/test/tools/ossfuzz/strictasm_diff_ossfuzz.cpp @@ -36,7 +36,6 @@ #include #include -using namespace std; using namespace solidity; using namespace solidity::yul; using namespace solidity::util; @@ -51,7 +50,7 @@ extern "C" int LLVMFuzzerTestOneInput(uint8_t const* _data, size_t _size) if (_size > 600) return 0; - string input(reinterpret_cast(_data), _size); + std::string input(reinterpret_cast(_data), _size); if (std::any_of(input.begin(), input.end(), [](char c) { return ((static_cast(c) > 127) || !(isPrint(c) || (c == '\n') || (c == '\t'))); @@ -62,7 +61,7 @@ extern "C" int LLVMFuzzerTestOneInput(uint8_t const* _data, size_t _size) YulStack stack( langutil::EVMVersion(), - nullopt, + std::nullopt, YulStack::Language::StrictAssembly, solidity::frontend::OptimiserSettings::full(), DebugInfoSelection::All() @@ -81,8 +80,8 @@ extern "C" int LLVMFuzzerTestOneInput(uint8_t const* _data, size_t _size) return 0; } - ostringstream os1; - ostringstream os2; + std::ostringstream os1; + std::ostringstream os2; // Disable memory tracing to avoid false positive reports // such as unused write to memory e.g., // { mstore(0, 1) } diff --git a/test/tools/ossfuzz/strictasm_opt_ossfuzz.cpp b/test/tools/ossfuzz/strictasm_opt_ossfuzz.cpp index db35cc865241..7553c81c0f44 100644 --- a/test/tools/ossfuzz/strictasm_opt_ossfuzz.cpp +++ b/test/tools/ossfuzz/strictasm_opt_ossfuzz.cpp @@ -25,7 +25,6 @@ using namespace solidity; using namespace solidity::langutil; using namespace solidity::util; using namespace solidity::yul; -using namespace std; // Prototype as we can't use the FuzzerInterface.h header. extern "C" int LLVMFuzzerTestOneInput(uint8_t const* _data, size_t _size); @@ -37,10 +36,10 @@ extern "C" int LLVMFuzzerTestOneInput(uint8_t const* _data, size_t _size) YulStringRepository::reset(); - string input(reinterpret_cast(_data), _size); + std::string input(reinterpret_cast(_data), _size); YulStack stack( langutil::EVMVersion(), - nullopt, + std::nullopt, YulStack::Language::StrictAssembly, solidity::frontend::OptimiserSettings::full(), DebugInfoSelection::All() diff --git a/test/tools/ossfuzz/yulFuzzerCommon.cpp b/test/tools/ossfuzz/yulFuzzerCommon.cpp index 57f930cfe1e1..4f7a871ac8bf 100644 --- a/test/tools/ossfuzz/yulFuzzerCommon.cpp +++ b/test/tools/ossfuzz/yulFuzzerCommon.cpp @@ -17,14 +17,13 @@ // SPDX-License-Identifier: GPL-3.0 #include -using namespace std; using namespace solidity; using namespace solidity::yul; using namespace solidity::yul::test::yul_fuzzer; yulFuzzerUtil::TerminationReason yulFuzzerUtil::interpret( - ostream& _os, - shared_ptr _ast, + std::ostream& _os, + std::shared_ptr _ast, Dialect const& _dialect, bool _disableMemoryTracing, bool _outputStorageOnly, diff --git a/test/tools/ossfuzz/yulProtoFuzzer.cpp b/test/tools/ossfuzz/yulProtoFuzzer.cpp index c2ac680934e5..b27d879d5606 100644 --- a/test/tools/ossfuzz/yulProtoFuzzer.cpp +++ b/test/tools/ossfuzz/yulProtoFuzzer.cpp @@ -40,20 +40,19 @@ using namespace solidity::langutil; using namespace solidity::yul; using namespace solidity::yul::test; using namespace solidity::yul::test::yul_fuzzer; -using namespace std; DEFINE_PROTO_FUZZER(Program const& _input) { ProtoConverter converter; - string yul_source = converter.programToString(_input); + std::string yul_source = converter.programToString(_input); EVMVersion version = converter.version(); if (const char* dump_path = getenv("PROTO_FUZZER_DUMP_PATH")) { // With libFuzzer binary run this to generate a YUL source file x.yul: // PROTO_FUZZER_DUMP_PATH=x.yul ./a.out proto-input - ofstream of(dump_path); - of.write(yul_source.data(), static_cast(yul_source.size())); + std::ofstream of(dump_path); + of.write(yul_source.data(), static_cast(yul_source.size())); } if (yul_source.size() > 1200) @@ -64,7 +63,7 @@ DEFINE_PROTO_FUZZER(Program const& _input) // YulStack entry point YulStack stack( version, - nullopt, + std::nullopt, YulStack::Language::StrictAssembly, solidity::frontend::OptimiserSettings::full(), DebugInfoSelection::All() @@ -85,6 +84,6 @@ DEFINE_PROTO_FUZZER(Program const& _input) EVMDialect::strictAssemblyForEVMObjects(version) ); optimizerTest.setStep(optimizerTest.randomOptimiserStep(_input.step())); - shared_ptr astBlock = optimizerTest.run(); + std::shared_ptr astBlock = optimizerTest.run(); yulAssert(astBlock != nullptr, "Optimiser error."); } diff --git a/test/tools/ossfuzz/yulProto_diff_ossfuzz.cpp b/test/tools/ossfuzz/yulProto_diff_ossfuzz.cpp index d1717a159a5e..49470f719820 100644 --- a/test/tools/ossfuzz/yulProto_diff_ossfuzz.cpp +++ b/test/tools/ossfuzz/yulProto_diff_ossfuzz.cpp @@ -36,7 +36,6 @@ #include -using namespace std; using namespace solidity; using namespace solidity::util; using namespace solidity::langutil; @@ -47,15 +46,15 @@ using namespace solidity::yul::test::yul_fuzzer; DEFINE_PROTO_FUZZER(Program const& _input) { ProtoConverter converter; - string yul_source = converter.programToString(_input); + std::string yul_source = converter.programToString(_input); EVMVersion version = converter.version(); if (const char* dump_path = getenv("PROTO_FUZZER_DUMP_PATH")) { // With libFuzzer binary run this to generate a YUL source file x.yul: // PROTO_FUZZER_DUMP_PATH=x.yul ./a.out proto-input - ofstream of(dump_path); - of.write(yul_source.data(), static_cast(yul_source.size())); + std::ofstream of(dump_path); + of.write(yul_source.data(), static_cast(yul_source.size())); } YulStringRepository::reset(); @@ -63,7 +62,7 @@ DEFINE_PROTO_FUZZER(Program const& _input) // YulStack entry point YulStack stack( version, - nullopt, + std::nullopt, YulStack::Language::StrictAssembly, solidity::frontend::OptimiserSettings::full(), DebugInfoSelection::All() @@ -81,8 +80,8 @@ DEFINE_PROTO_FUZZER(Program const& _input) yulAssert(false, "Proto fuzzer generated malformed program"); } - ostringstream os1; - ostringstream os2; + std::ostringstream os1; + std::ostringstream os2; // Disable memory tracing to avoid false positive reports // such as unused write to memory e.g., // { mstore(0, 1) } @@ -102,7 +101,7 @@ DEFINE_PROTO_FUZZER(Program const& _input) EVMDialect::strictAssemblyForEVMObjects(version) ); optimizerTest.setStep(optimizerTest.randomOptimiserStep(_input.step())); - shared_ptr astBlock = optimizerTest.run(); + std::shared_ptr astBlock = optimizerTest.run(); yulAssert(astBlock != nullptr, "Optimiser error."); termReason = yulFuzzerUtil::interpret( os2, @@ -116,8 +115,8 @@ DEFINE_PROTO_FUZZER(Program const& _input) bool isTraceEq = (os1.str() == os2.str()); if (!isTraceEq) { - cout << os1.str() << endl; - cout << os2.str() << endl; + std::cout << os1.str() << std::endl; + std::cout << os2.str() << std::endl; yulAssert(false, "Interpreted traces for optimized and unoptimized code differ."); } return; diff --git a/test/tools/yulopti.cpp b/test/tools/yulopti.cpp index 20491afe1657..d16b1da1969b 100644 --- a/test/tools/yulopti.cpp +++ b/test/tools/yulopti.cpp @@ -64,7 +64,6 @@ #include #include -using namespace std; using namespace solidity; using namespace solidity::util; using namespace solidity::langutil; @@ -79,14 +78,14 @@ class YulOpti static void printErrors(CharStream const& _charStream, ErrorList const& _errors) { SourceReferenceFormatter{ - cerr, + std::cerr, SingletonCharStreamProvider(_charStream), true, false }.printErrorInformation(_errors); } - void parse(string const& _input) + void parse(std::string const& _input) { ErrorList errors; ErrorReporter errorReporter(errors); @@ -96,11 +95,11 @@ class YulOpti m_ast = yul::Parser(errorReporter, m_dialect).parse(_charStream); if (!m_ast || !errorReporter.errors().empty()) { - cerr << "Error parsing source." << endl; + std::cerr << "Error parsing source." << std::endl; printErrors(_charStream, errors); throw std::runtime_error("Could not parse source."); } - m_analysisInfo = make_unique(); + m_analysisInfo = std::make_unique(); AsmAnalyzer analyzer( *m_analysisInfo, errorReporter, @@ -108,21 +107,21 @@ class YulOpti ); if (!analyzer.analyze(*m_ast) || !errorReporter.errors().empty()) { - cerr << "Error analyzing source." << endl; + std::cerr << "Error analyzing source." << std::endl; printErrors(_charStream, errors); throw std::runtime_error("Could not analyze source."); } } catch(...) { - cerr << "Fatal error during parsing: " << endl; + std::cerr << "Fatal error during parsing: " << std::endl; printErrors(_charStream, errors); throw; } } void printUsageBanner( - map const& _extraOptions, + std::map const& _extraOptions, size_t _columns ) { @@ -134,10 +133,10 @@ class YulOpti max_element(_extraOptions.begin(), _extraOptions.end(), hasShorterString)->second.size() ); - vector overlappingAbbreviations = + std::vector overlappingAbbreviations = ranges::views::set_intersection(_extraOptions | ranges::views::keys, optimiserSteps | ranges::views::keys) | - ranges::views::transform([](char _abbreviation){ return string(1, _abbreviation); }) | - ranges::to(); + ranges::views::transform([](char _abbreviation){ return std::string(1, _abbreviation); }) | + ranges::to(); yulAssert( overlappingAbbreviations.empty(), @@ -148,10 +147,10 @@ class YulOpti "Please update the code to use a different character and recompile yulopti." ); - vector> sortedOptions = + std::vector> sortedOptions = ranges::views::concat(optimiserSteps, _extraOptions) | - ranges::to>>() | - ranges::actions::sort([](tuple const& _a, tuple const& _b) { + ranges::to>>() | + ranges::actions::sort([](std::tuple const& _a, std::tuple const& _b) { return ( !boost::algorithm::iequals(get<1>(_a), get<1>(_b)) ? boost::algorithm::lexicographical_compare(get<1>(_a), get<1>(_b), boost::algorithm::is_iless()) : @@ -164,9 +163,9 @@ class YulOpti for (size_t row = 0; row < rows; ++row) { for (auto const& [key, name]: sortedOptions | ranges::views::drop(row) | ranges::views::stride(rows)) - cout << key << ": " << setw(static_cast(longestDescriptionLength)) << setiosflags(ios::left) << name << " "; + std::cout << key << ": " << std::setw(static_cast(longestDescriptionLength)) << std::setiosflags(std::ios::left) << name << " "; - cout << endl; + std::cout << std::endl; } } @@ -177,22 +176,22 @@ class YulOpti m_nameDispenser.reset(*m_ast); } - void runSteps(string _source, string _steps) + void runSteps(std::string _source, std::string _steps) { parse(_source); disambiguate(); OptimiserSuite{m_context}.runSequence(_steps, *m_ast); - cout << AsmPrinter{m_dialect}(*m_ast) << endl; + std::cout << AsmPrinter{m_dialect}(*m_ast) << std::endl; } - void runInteractive(string _source, bool _disambiguated = false) + void runInteractive(std::string _source, bool _disambiguated = false) { bool disambiguated = _disambiguated; while (true) { parse(_source); disambiguated = disambiguated || (disambiguate(), true); - map const& extraOptions = { + std::map const& extraOptions = { // QUIT starts with a non-letter character on purpose to get it to show up on top of the list {'#', ">>> QUIT <<<"}, {',', "VarNameCleaner"}, @@ -200,10 +199,10 @@ class YulOpti }; printUsageBanner(extraOptions, 4); - cout << "? "; - cout.flush(); + std::cout << "? "; + std::cout.flush(); char option = static_cast(readStandardInputChar()); - cout << ' ' << option << endl; + std::cout << ' ' << option << std::endl; try { @@ -234,19 +233,19 @@ class YulOpti } catch (...) { - cerr << endl << "Exception during optimiser step:" << endl; - cerr << boost::current_exception_diagnostic_information() << endl; + std::cerr << std::endl << "Exception during optimiser step:" << std::endl; + std::cerr << boost::current_exception_diagnostic_information() << std::endl; } - cout << "----------------------" << endl; - cout << _source << endl; + std::cout << "----------------------" << std::endl; + std::cout << _source << std::endl; } } private: - shared_ptr m_ast; + std::shared_ptr m_ast; Dialect const& m_dialect{EVMDialect::strictAssemblyForEVMObjects(EVMVersion{})}; - unique_ptr m_analysisInfo; - set const m_reservedIdentifiers = {}; + std::unique_ptr m_analysisInfo; + std::set const m_reservedIdentifiers = {}; NameDispenser m_nameDispenser{m_dialect, m_reservedIdentifiers}; OptimiserStepContext m_context{ m_dialect, @@ -275,12 +274,12 @@ int main(int argc, char** argv) options.add_options() ( "input-file", - po::value(), + po::value(), "input file" ) ( "steps", - po::value(), + po::value(), "steps to execute non-interactively" ) ( @@ -302,43 +301,43 @@ int main(int argc, char** argv) if (arguments.count("help")) { - cout << options; + std::cout << options; return 0; } - string input; + std::string input; if (arguments.count("input-file")) { - string filename = arguments["input-file"].as(); + std::string filename = arguments["input-file"].as(); if (filename == "-") { nonInteractive = true; - input = readUntilEnd(cin); + input = readUntilEnd(std::cin); } else - input = readFileAsString(arguments["input-file"].as()); + input = readFileAsString(arguments["input-file"].as()); } else { - cout << options; + std::cout << options; return 1; } if (nonInteractive && !arguments.count("steps")) { - cout << options; + std::cout << options; return 1; } YulOpti yulOpti; bool disambiguated = false; if (!nonInteractive) - cout << input << endl; + std::cout << input << std::endl; if (arguments.count("steps")) { - string sequence = arguments["steps"].as(); + std::string sequence = arguments["steps"].as(); if (!nonInteractive) - cout << "----------------------" << endl; + std::cout << "----------------------" << std::endl; yulOpti.runSteps(input, sequence); disambiguated = true; } @@ -349,23 +348,23 @@ int main(int argc, char** argv) } catch (po::error const& _exception) { - cerr << _exception.what() << endl; + std::cerr << _exception.what() << std::endl; return 1; } catch (FileNotFound const& _exception) { - cerr << "File not found:" << _exception.comment() << endl; + std::cerr << "File not found:" << _exception.comment() << std::endl; return 1; } catch (NotAFile const& _exception) { - cerr << "Not a regular file:" << _exception.comment() << endl; + std::cerr << "Not a regular file:" << _exception.comment() << std::endl; return 1; } catch(...) { - cerr << endl << "Exception:" << endl; - cerr << boost::current_exception_diagnostic_information() << endl; + std::cerr << std::endl << "Exception:" << std::endl; + std::cerr << boost::current_exception_diagnostic_information() << std::endl; return 1; } } diff --git a/test/tools/yulrun.cpp b/test/tools/yulrun.cpp index 2e1bcc013e45..fb18b4e598ee 100644 --- a/test/tools/yulrun.cpp +++ b/test/tools/yulrun.cpp @@ -43,7 +43,6 @@ #include #include -using namespace std; using namespace solidity; using namespace solidity::util; using namespace solidity::langutil; @@ -55,11 +54,11 @@ namespace po = boost::program_options; namespace { -pair, shared_ptr> parse(string const& _source) +std::pair, std::shared_ptr> parse(std::string const& _source) { YulStack stack( langutil::EVMVersion(), - nullopt, + std::nullopt, YulStack::Language::StrictAssembly, solidity::frontend::OptimiserSettings::none(), DebugInfoSelection::Default() @@ -71,15 +70,15 @@ pair, shared_ptr> parse(string const& _source } else { - SourceReferenceFormatter(cout, stack, true, false).printErrorInformation(stack.errors()); + SourceReferenceFormatter(std::cout, stack, true, false).printErrorInformation(stack.errors()); return {}; } } -void interpret(string const& _source, bool _inspect, bool _disableExternalCalls) +void interpret(std::string const& _source, bool _inspect, bool _disableExternalCalls) { - shared_ptr ast; - shared_ptr analysisInfo; + std::shared_ptr ast; + std::shared_ptr analysisInfo; tie(ast, analysisInfo) = parse(_source); if (!ast || !analysisInfo) return; @@ -100,7 +99,7 @@ void interpret(string const& _source, bool _inspect, bool _disableExternalCalls) { } - state.dumpTraceAndState(cout, /*disableMemoryTracing=*/false); + state.dumpTraceAndState(std::cout, /*disableMemoryTracing=*/false); } } @@ -119,7 +118,7 @@ Allowed options)", ("help", "Show this help screen.") ("enable-external-calls", "Enable external calls") ("interactive", "Run interactive") - ("input-file", po::value>(), "input file"); + ("input-file", po::value>(), "input file"); po::positional_options_description filesPositions; filesPositions.add("input-file", -1); @@ -132,17 +131,17 @@ Allowed options)", } catch (po::error const& _exception) { - cerr << _exception.what() << endl; + std::cerr << _exception.what() << std::endl; return 1; } if (arguments.count("help")) - cout << options; + std::cout << options; else { - string input; + std::string input; if (arguments.count("input-file")) - for (string path: arguments["input-file"].as>()) + for (std::string path: arguments["input-file"].as>()) { try { @@ -150,17 +149,17 @@ Allowed options)", } catch (FileNotFound const&) { - cerr << "File not found: " << path << endl; + std::cerr << "File not found: " << path << std::endl; return 1; } catch (NotAFile const&) { - cerr << "Not a regular file: " << path << endl; + std::cerr << "Not a regular file: " << path << std::endl; return 1; } } else - input = readUntilEnd(cin); + input = readUntilEnd(std::cin); interpret(input, arguments.count("interactive"), !arguments.count("enable-external-calls")); } diff --git a/tools/yulPhaser/AlgorithmRunner.cpp b/tools/yulPhaser/AlgorithmRunner.cpp index d5ad75575c54..827261dc0822 100644 --- a/tools/yulPhaser/AlgorithmRunner.cpp +++ b/tools/yulPhaser/AlgorithmRunner.cpp @@ -26,7 +26,6 @@ #include #include -using namespace std; using namespace solidity::phaser; void AlgorithmRunner::run(GeneticAlgorithm& _algorithm) @@ -65,12 +64,12 @@ void AlgorithmRunner::printRoundSummary( if (m_options.showRoundInfo) { m_outputStream << "---------- ROUND " << _round + 1; - m_outputStream << " [round: " << fixed << setprecision(1) << roundTime << " s,"; - m_outputStream << " total: " << fixed << setprecision(1) << totalTime << " s]"; - m_outputStream << " ----------" << endl; + m_outputStream << " [round: " << std::fixed << std::setprecision(1) << roundTime << " s,"; + m_outputStream << " total: " << std::fixed << std::setprecision(1) << totalTime << " s]"; + m_outputStream << " ----------" << std::endl; } else if (m_population.individuals().size() > 0) - m_outputStream << endl; + m_outputStream << std::endl; m_outputStream << m_population; } @@ -78,11 +77,11 @@ void AlgorithmRunner::printRoundSummary( { if (m_options.showRoundInfo) { - m_outputStream << setw(5) << _round + 1 << " | "; - m_outputStream << setw(5) << fixed << setprecision(1) << totalTime << " | "; + m_outputStream << std::setw(5) << _round + 1 << " | "; + m_outputStream << std::setw(5) << std::fixed << std::setprecision(1) << totalTime << " | "; } - m_outputStream << m_population.individuals()[0] << endl; + m_outputStream << m_population.individuals()[0] << std::endl; } } @@ -91,7 +90,7 @@ void AlgorithmRunner::printInitialPopulation() const if (!m_options.showInitialPopulation) return; - m_outputStream << "---------- INITIAL POPULATION ----------" << endl; + m_outputStream << "---------- INITIAL POPULATION ----------" << std::endl; m_outputStream << m_population; } @@ -108,23 +107,23 @@ void AlgorithmRunner::printCacheStats() const else ++disabledCacheCount; - m_outputStream << "---------- CACHE STATS ----------" << endl; + m_outputStream << "---------- CACHE STATS ----------" << std::endl; if (disabledCacheCount < m_programCaches.size()) { for (auto& [round, count]: totalStats.roundEntryCounts) - m_outputStream << "Round " << round << ": " << count << " entries" << endl; - m_outputStream << "Total hits: " << totalStats.hits << endl; - m_outputStream << "Total misses: " << totalStats.misses << endl; - m_outputStream << "Size of cached code: " << totalStats.totalCodeSize << endl; + m_outputStream << "Round " << round << ": " << count << " entries" << std::endl; + m_outputStream << "Total hits: " << totalStats.hits << std::endl; + m_outputStream << "Total misses: " << totalStats.misses << std::endl; + m_outputStream << "Size of cached code: " << totalStats.totalCodeSize << std::endl; } if (disabledCacheCount == m_programCaches.size()) - m_outputStream << "Program cache disabled" << endl; + m_outputStream << "Program cache disabled" << std::endl; else if (disabledCacheCount > 0) { m_outputStream << "Program cache disabled for " << disabledCacheCount << " out of "; - m_outputStream << m_programCaches.size() << " programs" << endl; + m_outputStream << m_programCaches.size() << " programs" << std::endl; } } @@ -133,20 +132,20 @@ void AlgorithmRunner::populationAutosave() const if (!m_options.populationAutosaveFile.has_value()) return; - ofstream outputStream(m_options.populationAutosaveFile.value(), ios::out | ios::trunc); + std::ofstream outputStream(m_options.populationAutosaveFile.value(), std::ios::out | std::ios::trunc); assertThrow( outputStream.is_open(), FileOpenError, - "Could not open file '" + m_options.populationAutosaveFile.value() + "': " + strerror(errno) + "Could not open file '" + m_options.populationAutosaveFile.value() + "': " + std::strerror(errno) ); for (auto& individual: m_population.individuals()) - outputStream << individual.chromosome << endl; + outputStream << individual.chromosome << std::endl; assertThrow( !outputStream.bad(), FileWriteError, - "Error while writing to file '" + m_options.populationAutosaveFile.value() + "': " + strerror(errno) + "Error while writing to file '" + m_options.populationAutosaveFile.value() + "': " + std::strerror(errno) ); } @@ -188,7 +187,7 @@ Population AlgorithmRunner::randomiseDuplicates( if (_population.individuals().size() == 0) return _population; - vector individuals{_population.individuals()[0]}; + std::vector individuals{_population.individuals()[0]}; size_t duplicateCount = 0; for (size_t i = 1; i < _population.individuals().size(); ++i) if (_population.individuals()[i].chromosome == _population.individuals()[i - 1].chromosome) diff --git a/tools/yulPhaser/Chromosome.cpp b/tools/yulPhaser/Chromosome.cpp index 6e8d3544e136..85a97a781c3f 100644 --- a/tools/yulPhaser/Chromosome.cpp +++ b/tools/yulPhaser/Chromosome.cpp @@ -25,7 +25,6 @@ #include -using namespace std; using namespace solidity; using namespace solidity::yul; using namespace solidity::phaser; @@ -33,36 +32,36 @@ using namespace solidity::phaser; namespace solidity::phaser { -ostream& operator<<(ostream& _stream, Chromosome const& _chromosome); +std::ostream& operator<<(std::ostream& _stream, Chromosome const& _chromosome); } Chromosome Chromosome::makeRandom(size_t _length) { - vector steps; + std::vector steps; for (size_t i = 0; i < _length; ++i) steps.push_back(randomOptimisationStep()); return Chromosome(std::move(steps)); } -ostream& phaser::operator<<(ostream& _stream, Chromosome const& _chromosome) +std::ostream& phaser::operator<<(std::ostream& _stream, Chromosome const& _chromosome) { return _stream << _chromosome.m_genes; } -vector Chromosome::allStepNames() +std::vector Chromosome::allStepNames() { - vector stepNames; + std::vector stepNames; for (auto const& step: OptimiserSuite::allSteps()) stepNames.push_back(step.first); return stepNames; } -string const& Chromosome::randomOptimisationStep() +std::string const& Chromosome::randomOptimisationStep() { - static vector stepNames = allStepNames(); + static std::vector stepNames = allStepNames(); return stepNames[SimulationRNG::uniformInt(0, stepNames.size() - 1)]; } @@ -72,18 +71,18 @@ char Chromosome::randomGene() return OptimiserSuite::stepNameToAbbreviationMap().at(randomOptimisationStep()); } -string Chromosome::stepsToGenes(vector const& _optimisationSteps) +std::string Chromosome::stepsToGenes(std::vector const& _optimisationSteps) { - string genes; - for (string const& stepName: _optimisationSteps) + std::string genes; + for (std::string const& stepName: _optimisationSteps) genes.push_back(OptimiserSuite::stepNameToAbbreviationMap().at(stepName)); return genes; } -vector Chromosome::genesToSteps(string const& _genes) +std::vector Chromosome::genesToSteps(std::string const& _genes) { - vector steps; + std::vector steps; for (char abbreviation: _genes) steps.push_back(OptimiserSuite::stepAbbreviationToNameMap().at(abbreviation)); diff --git a/tools/yulPhaser/Common.cpp b/tools/yulPhaser/Common.cpp index a23210172d49..ca5197b7d1c6 100644 --- a/tools/yulPhaser/Common.cpp +++ b/tools/yulPhaser/Common.cpp @@ -26,21 +26,20 @@ #include #include -using namespace std; using namespace solidity; using namespace solidity::phaser; -vector phaser::readLinesFromFile(string const& _path) +std::vector phaser::readLinesFromFile(std::string const& _path) { - ifstream inputStream(_path); - assertThrow(inputStream.is_open(), FileOpenError, "Could not open file '" + _path + "': " + strerror(errno)); + std::ifstream inputStream(_path); + assertThrow(inputStream.is_open(), FileOpenError, "Could not open file '" + _path + "': " + std::strerror(errno)); - string line; - vector lines; - while (!getline(inputStream, line).fail()) + std::string line; + std::vector lines; + while (!std::getline(inputStream, line).fail()) lines.push_back(line); - assertThrow(!inputStream.bad(), FileReadError, "Error while reading from file '" + _path + "': " + strerror(errno)); + assertThrow(!inputStream.bad(), FileReadError, "Error while reading from file '" + _path + "': " + std::strerror(errno)); return lines; } diff --git a/tools/yulPhaser/FitnessMetrics.cpp b/tools/yulPhaser/FitnessMetrics.cpp index e0b719e25555..43ad3aa64183 100644 --- a/tools/yulPhaser/FitnessMetrics.cpp +++ b/tools/yulPhaser/FitnessMetrics.cpp @@ -22,7 +22,6 @@ #include -using namespace std; using namespace solidity::util; using namespace solidity::yul; using namespace solidity::phaser; @@ -62,7 +61,7 @@ size_t ProgramSize::evaluate(Chromosome const& _chromosome) size_t RelativeProgramSize::evaluate(Chromosome const& _chromosome) { - double const scalingFactor = pow(10, m_fixedPointPrecision); + double const scalingFactor = std::pow(10, m_fixedPointPrecision); size_t unoptimisedSize = optimisedProgram(Chromosome("")).codeSize(codeWeights()); if (unoptimisedSize == 0) @@ -70,7 +69,7 @@ size_t RelativeProgramSize::evaluate(Chromosome const& _chromosome) size_t optimisedSize = optimisedProgram(_chromosome).codeSize(codeWeights()); - return static_cast(round( + return static_cast(std::round( double(optimisedSize) / double(unoptimisedSize) * scalingFactor )); } @@ -103,7 +102,7 @@ size_t FitnessMetricMaximum::evaluate(Chromosome const& _chromosome) size_t maximum = m_metrics[0]->evaluate(_chromosome); for (size_t i = 1; i < m_metrics.size(); ++i) - maximum = max(maximum, m_metrics[i]->evaluate(_chromosome)); + maximum = std::max(maximum, m_metrics[i]->evaluate(_chromosome)); return maximum; } @@ -114,7 +113,7 @@ size_t FitnessMetricMinimum::evaluate(Chromosome const& _chromosome) size_t minimum = m_metrics[0]->evaluate(_chromosome); for (size_t i = 1; i < m_metrics.size(); ++i) - minimum = min(minimum, m_metrics[i]->evaluate(_chromosome)); + minimum = std::min(minimum, m_metrics[i]->evaluate(_chromosome)); return minimum; } diff --git a/tools/yulPhaser/GeneticAlgorithms.cpp b/tools/yulPhaser/GeneticAlgorithms.cpp index ff40d222a786..9345fda4f9b0 100644 --- a/tools/yulPhaser/GeneticAlgorithms.cpp +++ b/tools/yulPhaser/GeneticAlgorithms.cpp @@ -21,13 +21,12 @@ #include #include -using namespace std; using namespace solidity; using namespace solidity::phaser; -function phaser::buildCrossoverOperator( +std::function phaser::buildCrossoverOperator( CrossoverChoice _choice, - optional _uniformCrossoverSwapChance + std::optional _uniformCrossoverSwapChance ) { switch (_choice) @@ -44,9 +43,9 @@ function phaser::buildCrossoverOperator( }; } -function phaser::buildSymmetricCrossoverOperator( +std::function phaser::buildSymmetricCrossoverOperator( CrossoverChoice _choice, - optional _uniformCrossoverSwapChance + std::optional _uniformCrossoverSwapChance ) { switch (_choice) @@ -146,14 +145,14 @@ Population ClassicGeneticAlgorithm::select(Population _population, size_t _selec size_t maxFitness = 0; for (auto const& individual: _population.individuals()) - maxFitness = max(maxFitness, individual.fitness); + maxFitness = std::max(maxFitness, individual.fitness); size_t rouletteRange = 0; for (auto const& individual: _population.individuals()) // Add 1 to make sure that every chromosome has non-zero probability of being chosen rouletteRange += maxFitness + 1 - individual.fitness; - vector selectedIndividuals; + std::vector selectedIndividuals; for (size_t i = 0; i < _selectionSize; ++i) { size_t ball = SimulationRNG::uniformInt(0, rouletteRange - 1); diff --git a/tools/yulPhaser/Mutations.cpp b/tools/yulPhaser/Mutations.cpp index 873fbbb9ba65..ac55ae9d4eaa 100644 --- a/tools/yulPhaser/Mutations.cpp +++ b/tools/yulPhaser/Mutations.cpp @@ -28,15 +28,14 @@ #include #include -using namespace std; using namespace solidity; using namespace solidity::phaser; -function phaser::geneRandomisation(double _chance) +std::function phaser::geneRandomisation(double _chance) { return [=](Chromosome const& _chromosome) { - string genes; + std::string genes; for (char gene: _chromosome.genes()) genes.push_back( SimulationRNG::bernoulliTrial(_chance) ? @@ -48,11 +47,11 @@ function phaser::geneRandomisation(double _chance) }; } -function phaser::geneDeletion(double _chance) +std::function phaser::geneDeletion(double _chance) { return [=](Chromosome const& _chromosome) { - string genes; + std::string genes; for (char gene: _chromosome.genes()) if (!SimulationRNG::bernoulliTrial(_chance)) genes.push_back(gene); @@ -61,11 +60,11 @@ function phaser::geneDeletion(double _chance) }; } -function phaser::geneAddition(double _chance) +std::function phaser::geneAddition(double _chance) { return [=](Chromosome const& _chromosome) { - string genes; + std::string genes; if (SimulationRNG::bernoulliTrial(_chance)) genes.push_back(Chromosome::randomGene()); @@ -81,10 +80,10 @@ function phaser::geneAddition(double _chance) }; } -function phaser::alternativeMutations( +std::function phaser::alternativeMutations( double _firstMutationChance, - function _mutation1, - function _mutation2 + std::function _mutation1, + std::function _mutation2 ) { return [=](Chromosome const& _chromosome) @@ -96,7 +95,7 @@ function phaser::alternativeMutations( }; } -function phaser::mutationSequence(vector> _mutations) +std::function phaser::mutationSequence(std::vector> _mutations) { return [=](Chromosome const& _chromosome) { @@ -134,26 +133,26 @@ ChromosomePair fixedPointSwap( } -function phaser::randomPointCrossover() +std::function phaser::randomPointCrossover() { return [=](Chromosome const& _chromosome1, Chromosome const& _chromosome2) { - size_t minLength = min(_chromosome1.length(), _chromosome2.length()); + size_t minLength = std::min(_chromosome1.length(), _chromosome2.length()); // Don't use position 0 (because this just swaps the values) unless it's the only choice. size_t minPoint = (minLength > 0 ? 1 : 0); assert(minPoint <= minLength); size_t randomPoint = SimulationRNG::uniformInt(minPoint, minLength); - return get<0>(fixedPointSwap(_chromosome1, _chromosome2, randomPoint)); + return std::get<0>(fixedPointSwap(_chromosome1, _chromosome2, randomPoint)); }; } -function phaser::symmetricRandomPointCrossover() +std::function phaser::symmetricRandomPointCrossover() { return [=](Chromosome const& _chromosome1, Chromosome const& _chromosome2) { - size_t minLength = min(_chromosome1.length(), _chromosome2.length()); + size_t minLength = std::min(_chromosome1.length(), _chromosome2.length()); // Don't use position 0 (because this just swaps the values) unless it's the only choice. size_t minPoint = (minLength > 0 ? 1 : 0); @@ -164,16 +163,16 @@ function phaser::symmetricRandomPointCrossover() }; } -function phaser::fixedPointCrossover(double _crossoverPoint) +std::function phaser::fixedPointCrossover(double _crossoverPoint) { assert(0.0 <= _crossoverPoint && _crossoverPoint <= 1.0); return [=](Chromosome const& _chromosome1, Chromosome const& _chromosome2) { - size_t minLength = min(_chromosome1.length(), _chromosome2.length()); - size_t concretePoint = static_cast(round(double(minLength) * _crossoverPoint)); + size_t minLength = std::min(_chromosome1.length(), _chromosome2.length()); + size_t concretePoint = static_cast(std::round(double(minLength) * _crossoverPoint)); - return get<0>(fixedPointSwap(_chromosome1, _chromosome2, concretePoint)); + return std::get<0>(fixedPointSwap(_chromosome1, _chromosome2, concretePoint)); }; } @@ -192,8 +191,8 @@ ChromosomePair fixedTwoPointSwap( assert(_crossoverPoint2 <= _chromosome1.length()); assert(_crossoverPoint2 <= _chromosome2.length()); - size_t lowPoint = min(_crossoverPoint1, _crossoverPoint2); - size_t highPoint = max(_crossoverPoint1, _crossoverPoint2); + size_t lowPoint = std::min(_crossoverPoint1, _crossoverPoint2); + size_t highPoint = std::max(_crossoverPoint1, _crossoverPoint2); return { Chromosome( @@ -211,11 +210,11 @@ ChromosomePair fixedTwoPointSwap( } -function phaser::randomTwoPointCrossover() +std::function phaser::randomTwoPointCrossover() { return [=](Chromosome const& _chromosome1, Chromosome const& _chromosome2) { - size_t minLength = min(_chromosome1.length(), _chromosome2.length()); + size_t minLength = std::min(_chromosome1.length(), _chromosome2.length()); // Don't use position 0 (because this just swaps the values) unless it's the only choice. size_t minPoint = (minLength > 0 ? 1 : 0); @@ -223,15 +222,15 @@ function phaser::randomTwoPointCrossover() size_t randomPoint1 = SimulationRNG::uniformInt(minPoint, minLength); size_t randomPoint2 = SimulationRNG::uniformInt(randomPoint1, minLength); - return get<0>(fixedTwoPointSwap(_chromosome1, _chromosome2, randomPoint1, randomPoint2)); + return std::get<0>(fixedTwoPointSwap(_chromosome1, _chromosome2, randomPoint1, randomPoint2)); }; } -function phaser::symmetricRandomTwoPointCrossover() +std::function phaser::symmetricRandomTwoPointCrossover() { return [=](Chromosome const& _chromosome1, Chromosome const& _chromosome2) { - size_t minLength = min(_chromosome1.length(), _chromosome2.length()); + size_t minLength = std::min(_chromosome1.length(), _chromosome2.length()); // Don't use position 0 (because this just swaps the values) unless it's the only choice. size_t minPoint = (minLength > 0 ? 1 : 0); @@ -248,10 +247,10 @@ namespace ChromosomePair uniformSwap(Chromosome const& _chromosome1, Chromosome const& _chromosome2, double _swapChance) { - string steps1; - string steps2; + std::string steps1; + std::string steps2; - size_t minLength = min(_chromosome1.length(), _chromosome2.length()); + size_t minLength = std::min(_chromosome1.length(), _chromosome2.length()); for (size_t i = 0; i < minLength; ++i) if (SimulationRNG::bernoulliTrial(_swapChance)) { @@ -286,15 +285,15 @@ ChromosomePair uniformSwap(Chromosome const& _chromosome1, Chromosome const& _ch } -function phaser::uniformCrossover(double _swapChance) +std::function phaser::uniformCrossover(double _swapChance) { return [=](Chromosome const& _chromosome1, Chromosome const& _chromosome2) { - return get<0>(uniformSwap(_chromosome1, _chromosome2, _swapChance)); + return std::get<0>(uniformSwap(_chromosome1, _chromosome2, _swapChance)); }; } -function phaser::symmetricUniformCrossover(double _swapChance) +std::function phaser::symmetricUniformCrossover(double _swapChance) { return [=](Chromosome const& _chromosome1, Chromosome const& _chromosome2) { diff --git a/tools/yulPhaser/PairSelections.cpp b/tools/yulPhaser/PairSelections.cpp index 4c9d4ee5f961..deff94863039 100644 --- a/tools/yulPhaser/PairSelections.cpp +++ b/tools/yulPhaser/PairSelections.cpp @@ -23,17 +23,16 @@ #include -using namespace std; using namespace solidity::phaser; -vector> RandomPairSelection::materialise(size_t _poolSize) const +std::vector> RandomPairSelection::materialise(size_t _poolSize) const { if (_poolSize < 2) return {}; - auto count = static_cast(round(double(_poolSize) * m_selectionSize)); + auto count = static_cast(std::round(double(_poolSize) * m_selectionSize)); - vector> selection; + std::vector> selection; for (size_t i = 0; i < count; ++i) { size_t index1 = SimulationRNG::uniformInt(0, _poolSize - 1); @@ -49,9 +48,9 @@ vector> RandomPairSelection::materialise(size_t _poolSize) return selection; } -vector> PairsFromRandomSubset::materialise(size_t _poolSize) const +std::vector> PairsFromRandomSubset::materialise(size_t _poolSize) const { - vector selectedIndices = RandomSubset(m_selectionChance).materialise(_poolSize); + std::vector selectedIndices = RandomSubset(m_selectionChance).materialise(_poolSize); if (selectedIndices.size() % 2 != 0) { @@ -72,7 +71,7 @@ vector> PairsFromRandomSubset::materialise(size_t _poolSiz } assert(selectedIndices.size() % 2 == 0); - vector> selectedPairs; + std::vector> selectedPairs; for (size_t i = selectedIndices.size() / 2; i > 0; --i) { size_t position1 = SimulationRNG::uniformInt(0, selectedIndices.size() - 1); @@ -89,18 +88,18 @@ vector> PairsFromRandomSubset::materialise(size_t _poolSiz return selectedPairs; } -vector> PairMosaicSelection::materialise(size_t _poolSize) const +std::vector> PairMosaicSelection::materialise(size_t _poolSize) const { if (_poolSize < 2) return {}; - size_t count = static_cast(round(double(_poolSize) * m_selectionSize)); + size_t count = static_cast(std::round(double(_poolSize) * m_selectionSize)); - vector> selection; + std::vector> selection; for (size_t i = 0; i < count; ++i) { - tuple pair = m_pattern[i % m_pattern.size()]; - selection.emplace_back(min(get<0>(pair), _poolSize - 1), min(get<1>(pair), _poolSize - 1)); + std::tuple pair = m_pattern[i % m_pattern.size()]; + selection.emplace_back(std::min(std::get<0>(pair), _poolSize - 1), std::min(std::get<1>(pair), _poolSize - 1)); } return selection; diff --git a/tools/yulPhaser/Phaser.cpp b/tools/yulPhaser/Phaser.cpp index db5ec35cedfa..6bddf39fc050 100644 --- a/tools/yulPhaser/Phaser.cpp +++ b/tools/yulPhaser/Phaser.cpp @@ -37,7 +37,6 @@ #include -using namespace std; using namespace solidity; using namespace solidity::langutil; using namespace solidity::util; @@ -49,58 +48,58 @@ namespace po = boost::program_options; namespace { -map const PhaserModeToStringMap = +std::map const PhaserModeToStringMap = { {PhaserMode::RunAlgorithm, "run-algorithm"}, {PhaserMode::PrintOptimisedPrograms, "print-optimised-programs"}, {PhaserMode::PrintOptimisedASTs, "print-optimised-asts"}, }; -map const StringToPhaserModeMap = invertMap(PhaserModeToStringMap); +std::map const StringToPhaserModeMap = invertMap(PhaserModeToStringMap); -map const AlgorithmToStringMap = +std::map const AlgorithmToStringMap = { {Algorithm::Random, "random"}, {Algorithm::GEWEP, "GEWEP"}, {Algorithm::Classic, "classic"}, }; -map const StringToAlgorithmMap = invertMap(AlgorithmToStringMap); +std::map const StringToAlgorithmMap = invertMap(AlgorithmToStringMap); -map MetricChoiceToStringMap = +std::map MetricChoiceToStringMap = { {MetricChoice::CodeSize, "code-size"}, {MetricChoice::RelativeCodeSize, "relative-code-size"}, }; -map const StringToMetricChoiceMap = invertMap(MetricChoiceToStringMap); +std::map const StringToMetricChoiceMap = invertMap(MetricChoiceToStringMap); -map const MetricAggregatorChoiceToStringMap = +std::map const MetricAggregatorChoiceToStringMap = { {MetricAggregatorChoice::Average, "average"}, {MetricAggregatorChoice::Sum, "sum"}, {MetricAggregatorChoice::Maximum, "maximum"}, {MetricAggregatorChoice::Minimum, "minimum"}, }; -map const StringToMetricAggregatorChoiceMap = invertMap(MetricAggregatorChoiceToStringMap); +std::map const StringToMetricAggregatorChoiceMap = invertMap(MetricAggregatorChoiceToStringMap); -map const CrossoverChoiceToStringMap = +std::map const CrossoverChoiceToStringMap = { {CrossoverChoice::SinglePoint, "single-point"}, {CrossoverChoice::TwoPoint, "two-point"}, {CrossoverChoice::Uniform, "uniform"}, }; -map const StringToCrossoverChoiceMap = invertMap(CrossoverChoiceToStringMap); +std::map const StringToCrossoverChoiceMap = invertMap(CrossoverChoiceToStringMap); } -istream& phaser::operator>>(istream& _inputStream, PhaserMode& _phaserMode) { return deserializeChoice(_inputStream, _phaserMode, StringToPhaserModeMap); } -ostream& phaser::operator<<(ostream& _outputStream, PhaserMode _phaserMode) { return serializeChoice(_outputStream, _phaserMode, PhaserModeToStringMap); } -istream& phaser::operator>>(istream& _inputStream, Algorithm& _algorithm) { return deserializeChoice(_inputStream, _algorithm, StringToAlgorithmMap); } -ostream& phaser::operator<<(ostream& _outputStream, Algorithm _algorithm) { return serializeChoice(_outputStream, _algorithm, AlgorithmToStringMap); } -istream& phaser::operator>>(istream& _inputStream, MetricChoice& _metric) { return deserializeChoice(_inputStream, _metric, StringToMetricChoiceMap); } -ostream& phaser::operator<<(ostream& _outputStream, MetricChoice _metric) { return serializeChoice(_outputStream, _metric, MetricChoiceToStringMap); } -istream& phaser::operator>>(istream& _inputStream, MetricAggregatorChoice& _aggregator) { return deserializeChoice(_inputStream, _aggregator, StringToMetricAggregatorChoiceMap); } -ostream& phaser::operator<<(ostream& _outputStream, MetricAggregatorChoice _aggregator) { return serializeChoice(_outputStream, _aggregator, MetricAggregatorChoiceToStringMap); } -istream& phaser::operator>>(istream& _inputStream, CrossoverChoice& _crossover) { return deserializeChoice(_inputStream, _crossover, StringToCrossoverChoiceMap); } -ostream& phaser::operator<<(ostream& _outputStream, CrossoverChoice _crossover) { return serializeChoice(_outputStream, _crossover, CrossoverChoiceToStringMap); } +std::istream& phaser::operator>>(std::istream& _inputStream, PhaserMode& _phaserMode) { return deserializeChoice(_inputStream, _phaserMode, StringToPhaserModeMap); } +std::ostream& phaser::operator<<(std::ostream& _outputStream, PhaserMode _phaserMode) { return serializeChoice(_outputStream, _phaserMode, PhaserModeToStringMap); } +std::istream& phaser::operator>>(std::istream& _inputStream, Algorithm& _algorithm) { return deserializeChoice(_inputStream, _algorithm, StringToAlgorithmMap); } +std::ostream& phaser::operator<<(std::ostream& _outputStream, Algorithm _algorithm) { return serializeChoice(_outputStream, _algorithm, AlgorithmToStringMap); } +std::istream& phaser::operator>>(std::istream& _inputStream, MetricChoice& _metric) { return deserializeChoice(_inputStream, _metric, StringToMetricChoiceMap); } +std::ostream& phaser::operator<<(std::ostream& _outputStream, MetricChoice _metric) { return serializeChoice(_outputStream, _metric, MetricChoiceToStringMap); } +std::istream& phaser::operator>>(std::istream& _inputStream, MetricAggregatorChoice& _aggregator) { return deserializeChoice(_inputStream, _aggregator, StringToMetricAggregatorChoiceMap); } +std::ostream& phaser::operator<<(std::ostream& _outputStream, MetricAggregatorChoice _aggregator) { return serializeChoice(_outputStream, _aggregator, MetricAggregatorChoiceToStringMap); } +std::istream& phaser::operator>>(std::istream& _inputStream, CrossoverChoice& _crossover) { return deserializeChoice(_inputStream, _crossover, StringToCrossoverChoiceMap); } +std::ostream& phaser::operator<<(std::ostream& _outputStream, CrossoverChoice _crossover) { return serializeChoice(_outputStream, _crossover, CrossoverChoiceToStringMap); } GeneticAlgorithmFactory::Options GeneticAlgorithmFactory::Options::fromCommandLine(po::variables_map const& _arguments) { @@ -112,17 +111,17 @@ GeneticAlgorithmFactory::Options GeneticAlgorithmFactory::Options::fromCommandLi _arguments["uniform-crossover-swap-chance"].as(), _arguments.count("random-elite-pool-size") > 0 ? _arguments["random-elite-pool-size"].as() : - optional{}, + std::optional{}, _arguments["gewep-mutation-pool-size"].as(), _arguments["gewep-crossover-pool-size"].as(), _arguments["gewep-randomisation-chance"].as(), _arguments["gewep-deletion-vs-addition-chance"].as(), _arguments.count("gewep-genes-to-randomise") > 0 ? _arguments["gewep-genes-to-randomise"].as() : - optional{}, + std::optional{}, _arguments.count("gewep-genes-to-add-or-delete") > 0 ? _arguments["gewep-genes-to-add-or-delete"].as() : - optional{}, + std::optional{}, _arguments["classic-elite-pool-size"].as(), _arguments["classic-crossover-chance"].as(), _arguments["classic-mutation-chance"].as(), @@ -131,7 +130,7 @@ GeneticAlgorithmFactory::Options GeneticAlgorithmFactory::Options::fromCommandLi }; } -unique_ptr GeneticAlgorithmFactory::build( +std::unique_ptr GeneticAlgorithmFactory::build( Options const& _options, size_t _populationSize ) @@ -147,7 +146,7 @@ unique_ptr GeneticAlgorithmFactory::build( if (_options.randomElitePoolSize.has_value()) elitePoolSize = _options.randomElitePoolSize.value(); - return make_unique(RandomAlgorithm::Options{ + return std::make_unique(RandomAlgorithm::Options{ /* elitePoolSize = */ elitePoolSize, /* minChromosomeLength = */ _options.minChromosomeLength, /* maxChromosomeLength = */ _options.maxChromosomeLength, @@ -163,7 +162,7 @@ unique_ptr GeneticAlgorithmFactory::build( if (_options.gewepGenesToAddOrDelete.has_value()) percentGenesToAddOrDelete = _options.gewepGenesToAddOrDelete.value(); - return make_unique(GenerationalElitistWithExclusivePools::Options{ + return std::make_unique(GenerationalElitistWithExclusivePools::Options{ /* mutationPoolSize = */ _options.gewepMutationPoolSize, /* crossoverPoolSize = */ _options.gewepCrossoverPoolSize, /* randomisationChance = */ _options.gewepRandomisationChance, @@ -176,7 +175,7 @@ unique_ptr GeneticAlgorithmFactory::build( } case Algorithm::Classic: { - return make_unique(ClassicGeneticAlgorithm::Options{ + return std::make_unique(ClassicGeneticAlgorithm::Options{ /* elitePoolSize = */ _options.classicElitePoolSize, /* crossoverChance = */ _options.classicCrossoverChance, /* mutationChance = */ _options.classicMutationChance, @@ -222,24 +221,24 @@ FitnessMetricFactory::Options FitnessMetricFactory::Options::fromCommandLine(po: }; } -unique_ptr FitnessMetricFactory::build( +std::unique_ptr FitnessMetricFactory::build( Options const& _options, - vector _programs, - vector> _programCaches, + std::vector _programs, + std::vector> _programCaches, CodeWeights const& _weights ) { assert(_programCaches.size() == _programs.size()); assert(_programs.size() > 0 && "Validations should prevent this from being executed with zero files."); - vector> metrics; + std::vector> metrics; switch (_options.metric) { case MetricChoice::CodeSize: { for (size_t i = 0; i < _programs.size(); ++i) - metrics.push_back(make_unique( - _programCaches[i] != nullptr ? optional{} : std::move(_programs[i]), + metrics.push_back(std::make_unique( + _programCaches[i] != nullptr ? std::optional{} : std::move(_programs[i]), std::move(_programCaches[i]), _weights, _options.chromosomeRepetitions @@ -250,8 +249,8 @@ unique_ptr FitnessMetricFactory::build( case MetricChoice::RelativeCodeSize: { for (size_t i = 0; i < _programs.size(); ++i) - metrics.push_back(make_unique( - _programCaches[i] != nullptr ? optional{} : std::move(_programs[i]), + metrics.push_back(std::make_unique( + _programCaches[i] != nullptr ? std::optional{} : std::move(_programs[i]), std::move(_programCaches[i]), _options.relativeMetricScale, _weights, @@ -266,13 +265,13 @@ unique_ptr FitnessMetricFactory::build( switch (_options.metricAggregator) { case MetricAggregatorChoice::Average: - return make_unique(std::move(metrics)); + return std::make_unique(std::move(metrics)); case MetricAggregatorChoice::Sum: - return make_unique(std::move(metrics)); + return std::make_unique(std::move(metrics)); case MetricAggregatorChoice::Maximum: - return make_unique(std::move(metrics)); + return std::make_unique(std::move(metrics)); case MetricAggregatorChoice::Minimum: - return make_unique(std::move(metrics)); + return std::make_unique(std::move(metrics)); default: assertThrow(false, solidity::util::Exception, "Invalid MetricAggregatorChoice value."); } @@ -287,20 +286,20 @@ PopulationFactory::Options PopulationFactory::Options::fromCommandLine(po::varia _arguments["min-chromosome-length"].as(), _arguments["max-chromosome-length"].as(), _arguments.count("population") > 0 ? - _arguments["population"].as>() : - vector{}, + _arguments["population"].as>() : + std::vector{}, _arguments.count("random-population") > 0 ? - _arguments["random-population"].as>() : - vector{}, + _arguments["random-population"].as>() : + std::vector{}, _arguments.count("population-from-file") > 0 ? - _arguments["population-from-file"].as>() : - vector{}, + _arguments["population-from-file"].as>() : + std::vector{}, }; } Population PopulationFactory::build( Options const& _options, - shared_ptr _fitnessMetric + std::shared_ptr _fitnessMetric ) { Population population = buildFromStrings(_options.population, _fitnessMetric); @@ -316,19 +315,19 @@ Population PopulationFactory::build( _fitnessMetric ); - for (string const& populationFilePath: _options.populationFromFile) + for (std::string const& populationFilePath: _options.populationFromFile) population = std::move(population) + buildFromFile(populationFilePath, _fitnessMetric); return population; } Population PopulationFactory::buildFromStrings( - vector const& _geneSequences, - shared_ptr _fitnessMetric + std::vector const& _geneSequences, + std::shared_ptr _fitnessMetric ) { - vector chromosomes; - for (string const& geneSequence: _geneSequences) + std::vector chromosomes; + for (std::string const& geneSequence: _geneSequences) chromosomes.emplace_back(geneSequence); return Population(std::move(_fitnessMetric), std::move(chromosomes)); @@ -338,7 +337,7 @@ Population PopulationFactory::buildRandom( size_t _populationSize, size_t _minChromosomeLength, size_t _maxChromosomeLength, - shared_ptr _fitnessMetric + std::shared_ptr _fitnessMetric ) { return Population::makeRandom( @@ -350,8 +349,8 @@ Population PopulationFactory::buildRandom( } Population PopulationFactory::buildFromFile( - string const& _filePath, - shared_ptr _fitnessMetric + std::string const& _filePath, + std::shared_ptr _fitnessMetric ) { return buildFromStrings(readLinesFromFile(_filePath), std::move(_fitnessMetric)); @@ -364,14 +363,14 @@ ProgramCacheFactory::Options ProgramCacheFactory::Options::fromCommandLine(po::v }; } -vector> ProgramCacheFactory::build( +std::vector> ProgramCacheFactory::build( Options const& _options, - vector _programs + std::vector _programs ) { - vector> programCaches; + std::vector> programCaches; for (Program& program: _programs) - programCaches.push_back(_options.programCacheEnabled ? make_shared(std::move(program)) : nullptr); + programCaches.push_back(_options.programCacheEnabled ? std::make_shared(std::move(program)) : nullptr); return programCaches; } @@ -379,28 +378,28 @@ vector> ProgramCacheFactory::build( ProgramFactory::Options ProgramFactory::Options::fromCommandLine(po::variables_map const& _arguments) { return { - _arguments["input-files"].as>(), - _arguments["prefix"].as(), + _arguments["input-files"].as>(), + _arguments["prefix"].as(), }; } -vector ProgramFactory::build(Options const& _options) +std::vector ProgramFactory::build(Options const& _options) { - vector inputPrograms; + std::vector inputPrograms; for (auto& path: _options.inputFiles) { CharStream sourceCode = loadSource(path); - variant programOrErrors = Program::load(sourceCode); - if (holds_alternative(programOrErrors)) + std::variant programOrErrors = Program::load(sourceCode); + if (std::holds_alternative(programOrErrors)) { - SourceReferenceFormatter{cerr, SingletonCharStreamProvider(sourceCode), true, false} - .printErrorInformation(get(programOrErrors)); - cerr << endl; + SourceReferenceFormatter{std::cerr, SingletonCharStreamProvider(sourceCode), true, false} + .printErrorInformation(std::get(programOrErrors)); + std::cerr << std::endl; assertThrow(false, InvalidProgram, "Failed to load program " + path); } - get(programOrErrors).optimise(Chromosome(_options.prefix).optimisationSteps()); - inputPrograms.push_back(std::move(get(programOrErrors))); + std::get(programOrErrors).optimise(Chromosome(_options.prefix).optimisationSteps()); + inputPrograms.push_back(std::move(std::get(programOrErrors))); } return inputPrograms; @@ -410,13 +409,13 @@ CharStream ProgramFactory::loadSource(boost::filesystem::path const& _sourcePath { assertThrow(boost::filesystem::exists(_sourcePath), MissingFile, "Source file does not exist: " + _sourcePath.string()); - string sourceCode = readFileAsString(_sourcePath); + std::string sourceCode = readFileAsString(_sourcePath); return CharStream(sourceCode, _sourcePath.string()); } void Phaser::main(int _argc, char** _argv) { - optional arguments = parseCommandLine(_argc, _argv); + std::optional arguments = parseCommandLine(_argc, _argv); if (!arguments.has_value()) return; @@ -447,10 +446,10 @@ Phaser::CommandLineDescription Phaser::buildCommandLineDescription() po::options_description generalDescription("GENERAL", lineLength, minDescriptionLength); generalDescription.add_options() ("help", "Show help message and exit.") - ("input-files", po::value>()->required()->value_name(""), "Input files.") + ("input-files", po::value>()->required()->value_name(""), "Input files.") ( "prefix", - po::value()->value_name("")->default_value(""), + po::value()->value_name("")->default_value(""), "Initial optimisation steps automatically applied to every input program.\n" "The result is treated as if it was the actual input, i.e. the steps are not considered " "a part of the chromosomes and cannot be mutated. The values of relative metric values " @@ -615,24 +614,24 @@ Phaser::CommandLineDescription Phaser::buildCommandLineDescription() populationDescription.add_options() ( "population", - po::value>()->multitoken()->value_name(""), + po::value>()->multitoken()->value_name(""), "List of chromosomes to be included in the initial population. " "You can specify multiple values separated with spaces or invoke the option multiple times " "and all the values will be included." ) ( "random-population", - po::value>()->value_name(""), + po::value>()->value_name(""), "The number of randomly generated chromosomes to be included in the initial population." ) ( "population-from-file", - po::value>()->value_name(""), + po::value>()->value_name(""), "A text file with a list of chromosomes (one per line) to be included in the initial population." ) ( "population-autosave", - po::value()->value_name(""), + po::value()->value_name(""), "If specified, the population is saved in the specified file after each round. (default=autosave disabled)" ) ; @@ -756,7 +755,7 @@ Phaser::CommandLineDescription Phaser::buildCommandLineDescription() return {keywordDescription, positionalDescription}; } -optional Phaser::parseCommandLine(int _argc, char** _argv) +std::optional Phaser::parseCommandLine(int _argc, char** _argv) { auto [keywordDescription, positionalDescription] = buildCommandLineDescription(); @@ -769,8 +768,8 @@ optional Phaser::parseCommandLine(int _argc, char** _argv) if (arguments.count("help") > 0) { - cout << keywordDescription << endl; - return nullopt; + std::cout << keywordDescription << std::endl; + return std::nullopt; } if (arguments.count("input-files") == 0) @@ -789,14 +788,14 @@ void Phaser::initialiseRNG(po::variables_map const& _arguments) SimulationRNG::reset(seed); if (_arguments["show-seed"].as()) - cout << "Random seed: " << seed << endl; + std::cout << "Random seed: " << seed << std::endl; } AlgorithmRunner::Options Phaser::buildAlgorithmRunnerOptions(po::variables_map const& _arguments) { return { - _arguments.count("rounds") > 0 ? static_cast>(_arguments["rounds"].as()) : nullopt, - _arguments.count("population-autosave") > 0 ? static_cast>(_arguments["population-autosave"].as()) : nullopt, + _arguments.count("rounds") > 0 ? static_cast>(_arguments["rounds"].as()) : std::nullopt, + _arguments.count("population-autosave") > 0 ? static_cast>(_arguments["population-autosave"].as()) : std::nullopt, !_arguments["no-randomise-duplicates"].as(), _arguments["min-chromosome-length"].as(), _arguments["max-chromosome-length"].as(), @@ -814,10 +813,10 @@ void Phaser::runPhaser(po::variables_map const& _arguments) auto metricOptions = FitnessMetricFactory::Options::fromCommandLine(_arguments); auto populationOptions = PopulationFactory::Options::fromCommandLine(_arguments); - vector programs = ProgramFactory::build(programOptions); - vector> programCaches = ProgramCacheFactory::build(cacheOptions, programs); + std::vector programs = ProgramFactory::build(programOptions); + std::vector> programCaches = ProgramCacheFactory::build(cacheOptions, programs); CodeWeights codeWeights = CodeWeightFactory::buildFromCommandLine(_arguments); - unique_ptr fitnessMetric = FitnessMetricFactory::build( + std::unique_ptr fitnessMetric = FitnessMetricFactory::build( metricOptions, programs, programCaches, @@ -834,51 +833,51 @@ void Phaser::runPhaser(po::variables_map const& _arguments) void Phaser::runAlgorithm( po::variables_map const& _arguments, Population _population, - vector> _programCaches + std::vector> _programCaches ) { auto algorithmOptions = GeneticAlgorithmFactory::Options::fromCommandLine(_arguments); - unique_ptr geneticAlgorithm = GeneticAlgorithmFactory::build( + std::unique_ptr geneticAlgorithm = GeneticAlgorithmFactory::build( algorithmOptions, _population.individuals().size() ); - AlgorithmRunner algorithmRunner(std::move(_population), std::move(_programCaches), buildAlgorithmRunnerOptions(_arguments), cout); + AlgorithmRunner algorithmRunner(std::move(_population), std::move(_programCaches), buildAlgorithmRunnerOptions(_arguments), std::cout); algorithmRunner.run(*geneticAlgorithm); } void Phaser::printOptimisedProgramsOrASTs( po::variables_map const& _arguments, Population const& _population, - vector _programs, + std::vector _programs, PhaserMode phaserMode ) { assert(phaserMode == PhaserMode::PrintOptimisedPrograms || phaserMode == PhaserMode::PrintOptimisedASTs); - assert(_programs.size() == _arguments["input-files"].as>().size()); + assert(_programs.size() == _arguments["input-files"].as>().size()); if (_population.individuals().size() == 0) { - cout << "" << endl; + std::cout << "" << std::endl; return; } - vector const& paths = _arguments["input-files"].as>(); + std::vector const& paths = _arguments["input-files"].as>(); for (auto& individual: _population.individuals()) { - cout << "Chromosome: " << individual.chromosome << endl; + std::cout << "Chromosome: " << individual.chromosome << std::endl; for (size_t i = 0; i < _programs.size(); ++i) { for (size_t j = 0; j < _arguments["chromosome-repetitions"].as(); ++j) _programs[i].optimise(individual.chromosome.optimisationSteps()); - cout << "Program: " << paths[i] << endl; + std::cout << "Program: " << paths[i] << std::endl; if (phaserMode == PhaserMode::PrintOptimisedPrograms) - cout << _programs[i] << endl; + std::cout << _programs[i] << std::endl; else - cout << _programs[i].toJson() << endl; + std::cout << _programs[i].toJson() << std::endl; } } } diff --git a/tools/yulPhaser/Population.cpp b/tools/yulPhaser/Population.cpp index d4fe1f0bd046..e669dafe56c6 100644 --- a/tools/yulPhaser/Population.cpp +++ b/tools/yulPhaser/Population.cpp @@ -28,7 +28,6 @@ #include #include -using namespace std; using namespace solidity; using namespace solidity::langutil; using namespace solidity::util; @@ -37,12 +36,12 @@ using namespace solidity::phaser; namespace solidity::phaser { -ostream& operator<<(ostream& _stream, Individual const& _individual); -ostream& operator<<(ostream& _stream, Population const& _population); +std::ostream& operator<<(std::ostream& _stream, Individual const& _individual); +std::ostream& operator<<(std::ostream& _stream, Population const& _population); } -ostream& phaser::operator<<(ostream& _stream, Individual const& _individual) +std::ostream& phaser::operator<<(std::ostream& _stream, Individual const& _individual) { _stream << _individual.fitness << " " << _individual.chromosome; @@ -59,12 +58,12 @@ bool phaser::isFitter(Individual const& a, Individual const& b) } Population Population::makeRandom( - shared_ptr _fitnessMetric, + std::shared_ptr _fitnessMetric, size_t _size, - function _chromosomeLengthGenerator + std::function _chromosomeLengthGenerator ) { - vector chromosomes; + std::vector chromosomes; for (size_t i = 0; i < _size; ++i) chromosomes.push_back(Chromosome::makeRandom(_chromosomeLengthGenerator())); @@ -72,7 +71,7 @@ Population Population::makeRandom( } Population Population::makeRandom( - shared_ptr _fitnessMetric, + std::shared_ptr _fitnessMetric, size_t _size, size_t _minChromosomeLength, size_t _maxChromosomeLength @@ -87,25 +86,25 @@ Population Population::makeRandom( Population Population::select(Selection const& _selection) const { - vector selectedIndividuals; + std::vector selectedIndividuals; for (size_t i: _selection.materialise(m_individuals.size())) selectedIndividuals.emplace_back(m_individuals[i]); return Population(m_fitnessMetric, selectedIndividuals); } -Population Population::mutate(Selection const& _selection, function _mutation) const +Population Population::mutate(Selection const& _selection, std::function _mutation) const { - vector mutatedIndividuals; + std::vector mutatedIndividuals; for (size_t i: _selection.materialise(m_individuals.size())) mutatedIndividuals.emplace_back(_mutation(m_individuals[i].chromosome), *m_fitnessMetric); return Population(m_fitnessMetric, mutatedIndividuals); } -Population Population::crossover(PairSelection const& _selection, function _crossover) const +Population Population::crossover(PairSelection const& _selection, std::function _crossover) const { - vector crossedIndividuals; + std::vector crossedIndividuals; for (auto const& [i, j]: _selection.materialise(m_individuals.size())) { auto childChromosome = _crossover( @@ -118,27 +117,27 @@ Population Population::crossover(PairSelection const& _selection, function Population::symmetricCrossoverWithRemainder( +std::tuple Population::symmetricCrossoverWithRemainder( PairSelection const& _selection, - function _symmetricCrossover + std::function _symmetricCrossover ) const { - vector indexSelected(m_individuals.size(), false); + std::vector indexSelected(m_individuals.size(), false); - vector crossedIndividuals; + std::vector crossedIndividuals; for (auto const& [i, j]: _selection.materialise(m_individuals.size())) { auto children = _symmetricCrossover( m_individuals[i].chromosome, m_individuals[j].chromosome ); - crossedIndividuals.emplace_back(std::move(get<0>(children)), *m_fitnessMetric); - crossedIndividuals.emplace_back(std::move(get<1>(children)), *m_fitnessMetric); + crossedIndividuals.emplace_back(std::move(std::get<0>(children)), *m_fitnessMetric); + crossedIndividuals.emplace_back(std::move(std::get<1>(children)), *m_fitnessMetric); indexSelected[i] = true; indexSelected[j] = true; } - vector remainder; + std::vector remainder; for (size_t i = 0; i < indexSelected.size(); ++i) if (!indexSelected[i]) remainder.emplace_back(m_individuals[i]); @@ -166,7 +165,7 @@ Population operator+(Population _a, Population _b) Population Population::combine(std::tuple _populationPair) { - return get<0>(_populationPair) + get<1>(_populationPair); + return std::get<0>(_populationPair) + std::get<1>(_populationPair); } bool Population::operator==(Population const& _other) const @@ -177,28 +176,28 @@ bool Population::operator==(Population const& _other) const return m_individuals == _other.m_individuals && m_fitnessMetric == _other.m_fitnessMetric; } -ostream& phaser::operator<<(ostream& _stream, Population const& _population) +std::ostream& phaser::operator<<(std::ostream& _stream, Population const& _population) { auto individual = _population.m_individuals.begin(); for (; individual != _population.m_individuals.end(); ++individual) - _stream << *individual << endl; + _stream << *individual << std::endl; return _stream; } -vector Population::chromosomesToIndividuals( +std::vector Population::chromosomesToIndividuals( FitnessMetric& _fitnessMetric, - vector _chromosomes + std::vector _chromosomes ) { - vector individuals; + std::vector individuals; for (auto& chromosome: _chromosomes) individuals.emplace_back(std::move(chromosome), _fitnessMetric); return individuals; } -vector Population::sortedIndividuals(vector _individuals) +std::vector Population::sortedIndividuals(std::vector _individuals) { sort(_individuals.begin(), _individuals.end(), isFitter); return _individuals; diff --git a/tools/yulPhaser/Program.cpp b/tools/yulPhaser/Program.cpp index f24f5e03f4bb..00abcc8e5c31 100644 --- a/tools/yulPhaser/Program.cpp +++ b/tools/yulPhaser/Program.cpp @@ -45,7 +45,6 @@ #include #include -using namespace std; using namespace solidity; using namespace solidity::langutil; using namespace solidity::yul; @@ -55,39 +54,39 @@ using namespace solidity::phaser; namespace solidity::phaser { -ostream& operator<<(ostream& _stream, Program const& _program); +std::ostream& operator<<(std::ostream& _stream, Program const& _program); } Program::Program(Program const& program): - m_ast(make_unique(get(ASTCopier{}(*program.m_ast)))), + m_ast(std::make_unique(std::get(ASTCopier{}(*program.m_ast)))), m_dialect{program.m_dialect}, m_nameDispenser(program.m_nameDispenser) { } -variant Program::load(CharStream& _sourceCode) +std::variant Program::load(CharStream& _sourceCode) { // ASSUMPTION: parseSource() rewinds the stream on its own Dialect const& dialect = EVMDialect::strictAssemblyForEVMObjects(EVMVersion{}); - variant, ErrorList> astOrErrors = parseObject(dialect, _sourceCode); - if (holds_alternative(astOrErrors)) - return get(astOrErrors); + std::variant, ErrorList> astOrErrors = parseObject(dialect, _sourceCode); + if (std::holds_alternative(astOrErrors)) + return std::get(astOrErrors); - variant, ErrorList> analysisInfoOrErrors = analyzeAST( + std::variant, ErrorList> analysisInfoOrErrors = analyzeAST( dialect, - *get>(astOrErrors) + *std::get>(astOrErrors) ); - if (holds_alternative(analysisInfoOrErrors)) - return get(analysisInfoOrErrors); + if (std::holds_alternative(analysisInfoOrErrors)) + return std::get(analysisInfoOrErrors); Program program( dialect, disambiguateAST( dialect, - *get>(astOrErrors), - *get>(analysisInfoOrErrors) + *std::get>(astOrErrors), + *std::get>(analysisInfoOrErrors) ) ); program.optimise({ @@ -99,30 +98,30 @@ variant Program::load(CharStream& _sourceCode) return program; } -void Program::optimise(vector const& _optimisationSteps) +void Program::optimise(std::vector const& _optimisationSteps) { m_ast = applyOptimisationSteps(m_dialect, m_nameDispenser, std::move(m_ast), _optimisationSteps); } -ostream& phaser::operator<<(ostream& _stream, Program const& _program) +std::ostream& phaser::operator<<(std::ostream& _stream, Program const& _program) { return _stream << AsmPrinter()(*_program.m_ast); } -string Program::toJson() const +std::string Program::toJson() const { Json serializedAst = AsmJsonConverter(0)(*m_ast); return jsonPrettyPrint(removeNullMembers(std::move(serializedAst))); } -variant, ErrorList> Program::parseObject(Dialect const& _dialect, CharStream _source) +std::variant, ErrorList> Program::parseObject(Dialect const& _dialect, CharStream _source) { ErrorList errors; ErrorReporter errorReporter(errors); - auto scanner = make_shared(_source); + auto scanner = std::make_shared(_source); ObjectParser parser(errorReporter, _dialect); - shared_ptr object = parser.parse(scanner, false); + std::shared_ptr object = parser.parse(scanner, false); if (object == nullptr || !errorReporter.errors().empty()) // NOTE: It's possible to get errors even if the returned object is non-null. // For example when there are errors in a nested object. @@ -150,16 +149,16 @@ variant, ErrorList> Program::parseObject(Dialect const& _diale // The public API of the class does not provide access to the smart pointer so it won't be hard // to switch to shared_ptr if the copying turns out to be an issue (though it would be better // to refactor ObjectParser and Object to use unique_ptr instead). - auto astCopy = make_unique(get(ASTCopier{}(*selectedObject->code))); + auto astCopy = std::make_unique(std::get(ASTCopier{}(*selectedObject->code))); - return variant, ErrorList>(std::move(astCopy)); + return std::variant, ErrorList>(std::move(astCopy)); } -variant, ErrorList> Program::analyzeAST(Dialect const& _dialect, Block const& _ast) +std::variant, ErrorList> Program::analyzeAST(Dialect const& _dialect, Block const& _ast) { ErrorList errors; ErrorReporter errorReporter(errors); - auto analysisInfo = make_unique(); + auto analysisInfo = std::make_unique(); AsmAnalyzer analyzer(*analysisInfo, errorReporter, _dialect); bool analysisSuccessful = analyzer.analyze(_ast); @@ -167,31 +166,31 @@ variant, ErrorList> Program::analyzeAST(Dialect cons return errors; assert(errorReporter.errors().empty()); - return variant, ErrorList>(std::move(analysisInfo)); + return std::variant, ErrorList>(std::move(analysisInfo)); } -unique_ptr Program::disambiguateAST( +std::unique_ptr Program::disambiguateAST( Dialect const& _dialect, Block const& _ast, AsmAnalysisInfo const& _analysisInfo ) { - set const externallyUsedIdentifiers = {}; + std::set const externallyUsedIdentifiers = {}; Disambiguator disambiguator(_dialect, _analysisInfo, externallyUsedIdentifiers); - return make_unique(get(disambiguator(_ast))); + return std::make_unique(std::get(disambiguator(_ast))); } -unique_ptr Program::applyOptimisationSteps( +std::unique_ptr Program::applyOptimisationSteps( Dialect const& _dialect, NameDispenser& _nameDispenser, - unique_ptr _ast, - vector const& _optimisationSteps + std::unique_ptr _ast, + std::vector const& _optimisationSteps ) { // An empty set of reserved identifiers. It could be a constructor parameter but I don't // think it would be useful in this tool. Other tools (like yulopti) have it empty too. - set const externallyUsedIdentifiers = {}; + std::set const externallyUsedIdentifiers = {}; OptimiserStepContext context{ _dialect, _nameDispenser, @@ -199,7 +198,7 @@ unique_ptr Program::applyOptimisationSteps( frontend::OptimiserSettings::standard().expectedExecutionsPerDeployment }; - for (string const& step: _optimisationSteps) + for (std::string const& step: _optimisationSteps) OptimiserSuite::allSteps().at(step)->run(context, *_ast); return _ast; diff --git a/tools/yulPhaser/ProgramCache.cpp b/tools/yulPhaser/ProgramCache.cpp index 351532aa74fa..f8fae50faa16 100644 --- a/tools/yulPhaser/ProgramCache.cpp +++ b/tools/yulPhaser/ProgramCache.cpp @@ -22,7 +22,6 @@ #include -using namespace std; using namespace solidity::yul; using namespace solidity::phaser; @@ -51,16 +50,16 @@ bool CacheStats::operator==(CacheStats const& _other) const } Program ProgramCache::optimiseProgram( - string const& _abbreviatedOptimisationSteps, - size_t _repetitionCount + std::string const& _abbreviatedOptimisationSteps, + std::size_t _repetitionCount ) { - string targetOptimisations = _abbreviatedOptimisationSteps; - for (size_t i = 1; i < _repetitionCount; ++i) + std::string targetOptimisations = _abbreviatedOptimisationSteps; + for (std::size_t i = 1; i < _repetitionCount; ++i) targetOptimisations += _abbreviatedOptimisationSteps; - size_t prefixSize = 0; - for (size_t i = 1; i <= targetOptimisations.size(); ++i) + std::size_t prefixSize = 0; + for (std::size_t i = 1; i <= targetOptimisations.size(); ++i) { auto const& pair = m_entries.find(targetOptimisations.substr(0, i)); if (pair != m_entries.end()) @@ -79,9 +78,9 @@ Program ProgramCache::optimiseProgram( m_entries.at(targetOptimisations.substr(0, prefixSize)).program ); - for (size_t i = prefixSize + 1; i <= targetOptimisations.size(); ++i) + for (std::size_t i = prefixSize + 1; i <= targetOptimisations.size(); ++i) { - string stepName = OptimiserSuite::stepAbbreviationToNameMap().at(targetOptimisations[i - 1]); + std::string stepName = OptimiserSuite::stepAbbreviationToNameMap().at(targetOptimisations[i - 1]); intermediateProgram.optimise({stepName}); m_entries.insert({targetOptimisations.substr(0, i), {intermediateProgram, m_currentRound}}); @@ -91,7 +90,7 @@ Program ProgramCache::optimiseProgram( return intermediateProgram; } -void ProgramCache::startRound(size_t _roundNumber) +void ProgramCache::startRound(std::size_t _roundNumber) { assert(_roundNumber > m_currentRound); m_currentRound = _roundNumber; @@ -113,7 +112,7 @@ void ProgramCache::clear() m_currentRound = 0; } -Program const* ProgramCache::find(string const& _abbreviatedOptimisationSteps) const +Program const* ProgramCache::find(std::string const& _abbreviatedOptimisationSteps) const { auto const& pair = m_entries.find(_abbreviatedOptimisationSteps); if (pair == m_entries.end()) @@ -132,18 +131,18 @@ CacheStats ProgramCache::gatherStats() const }; } -size_t ProgramCache::calculateTotalCachedCodeSize() const +std::size_t ProgramCache::calculateTotalCachedCodeSize() const { - size_t size = 0; + std::size_t size = 0; for (auto const& pair: m_entries) size += pair.second.program.codeSize(CacheStats::StorageWeights); return size; } -map ProgramCache::countRoundEntries() const +std::map ProgramCache::countRoundEntries() const { - map counts; + std::map counts; for (auto& pair: m_entries) if (counts.find(pair.second.roundNumber) != counts.end()) ++counts.at(pair.second.roundNumber); diff --git a/tools/yulPhaser/Selections.cpp b/tools/yulPhaser/Selections.cpp index 5c55706454a9..ca2cefeb4a68 100644 --- a/tools/yulPhaser/Selections.cpp +++ b/tools/yulPhaser/Selections.cpp @@ -23,14 +23,13 @@ #include #include -using namespace std; using namespace solidity::phaser; -vector RangeSelection::materialise(size_t _poolSize) const +std::vector RangeSelection::materialise(size_t _poolSize) const { - size_t beginIndex = static_cast(round(double(_poolSize) * m_startPercent)); - size_t endIndex = static_cast(round(double(_poolSize) * m_endPercent)); - vector selection; + size_t beginIndex = static_cast(std::round(double(_poolSize) * m_startPercent)); + size_t endIndex = static_cast(std::round(double(_poolSize) * m_endPercent)); + std::vector selection; for (size_t i = beginIndex; i < endIndex; ++i) selection.push_back(i); @@ -38,31 +37,31 @@ vector RangeSelection::materialise(size_t _poolSize) const return selection; } -vector MosaicSelection::materialise(size_t _poolSize) const +std::vector MosaicSelection::materialise(size_t _poolSize) const { - size_t count = static_cast(round(double(_poolSize) * m_selectionSize)); + size_t count = static_cast(std::round(double(_poolSize) * m_selectionSize)); - vector selection; + std::vector selection; for (size_t i = 0; i < count; ++i) - selection.push_back(min(m_pattern[i % m_pattern.size()], _poolSize - 1)); + selection.push_back(std::min(m_pattern[i % m_pattern.size()], _poolSize - 1)); return selection; } -vector RandomSelection::materialise(size_t _poolSize) const +std::vector RandomSelection::materialise(size_t _poolSize) const { - size_t count = static_cast(round(double(_poolSize) * m_selectionSize)); + size_t count = static_cast(std::round(double(_poolSize) * m_selectionSize)); - vector selection; + std::vector selection; for (size_t i = 0; i < count; ++i) selection.push_back(SimulationRNG::uniformInt(0, _poolSize - 1)); return selection; } -vector RandomSubset::materialise(size_t _poolSize) const +std::vector RandomSubset::materialise(size_t _poolSize) const { - vector selection; + std::vector selection; for (size_t index = 0; index < _poolSize; ++index) if (SimulationRNG::bernoulliTrial(m_selectionChance)) selection.push_back(index); diff --git a/tools/yulPhaser/SimulationRNG.cpp b/tools/yulPhaser/SimulationRNG.cpp index 5fca4d99e5eb..2306db63a625 100644 --- a/tools/yulPhaser/SimulationRNG.cpp +++ b/tools/yulPhaser/SimulationRNG.cpp @@ -28,7 +28,6 @@ #include #include -using namespace std; using namespace solidity; using namespace solidity::phaser; @@ -51,7 +50,7 @@ size_t SimulationRNG::binomialInt(size_t _numTrials, double _successProbability) { // NOTE: binomial_distribution would not work because it internally tries to use abs() // and fails to compile due to ambiguous conversion. - assert(_numTrials <= static_cast(numeric_limits::max())); + assert(_numTrials <= static_cast(std::numeric_limits::max())); boost::random::binomial_distribution distribution(static_cast(_numTrials), _successProbability); return static_cast(distribution(s_generator)); @@ -62,5 +61,5 @@ uint32_t SimulationRNG::generateSeed() // This is not a secure way to seed the generator but it's good enough for simulation purposes. // The only thing that matters for us is that the sequence is different on each run and that // it fits the expected distribution. It does not have to be 100% unpredictable. - return static_cast(time(nullptr)); + return static_cast(std::time(nullptr)); } From eb4b103ddaf0afe3f3ff82ccf1b4897e6e244ca4 Mon Sep 17 00:00:00 2001 From: Nikola Matic Date: Fri, 17 May 2024 16:41:45 +0200 Subject: [PATCH 0216/1022] Remove included directories check for using std --- scripts/check_style.sh | 42 +----------------------------------------- 1 file changed, 1 insertion(+), 41 deletions(-) diff --git a/scripts/check_style.sh b/scripts/check_style.sh index e9d470b761bc..dbe470c1aeb1 100755 --- a/scripts/check_style.sh +++ b/scripts/check_style.sh @@ -20,44 +20,6 @@ EXCLUDE_FILES=( EXCLUDE_FILES_JOINED=$(printf "%s\|" "${EXCLUDE_FILES[@]}") EXCLUDE_FILES_JOINED=${EXCLUDE_FILES_JOINED%??} -NAMESPACE_STD_FREE_FILES=( - libevmasm/* - liblangutil/* - libsmtutil/* - libsolc/* - libsolidity/analysis/* - libsolidity/ast/* - libsolidity/codegen/ir/* - libsolidity/codegen/* - libsolidity/experimental/* - libsolidity/formal/* - libsolidity/interface/* - libsolidity/lsp/* - libsolidity/parsing/* - libsolutil/* - libyul/* - libyul/backends/evm/* - libyul/optimiser/* - solc/* - test/* - test/contracts/* - test/libevmasm/* - test/liblangutil/* - test/libsolutil/* - test/libsolidity/* - test/libsolidity/analysis/* - test/libsolidity/interface/* - test/libsolidity/util/* - test/libyul/* - test/solc/* - test/tools/* - test/tools/ossfuzz/* - test/tools/ossfuzz/protomutators/* - test/tools/yulInterpreter/* - test/yulPhaser/* - tools/yulPhaser/* -) - ( REPO_ROOT="$(dirname "$0")"/.. cd "$REPO_ROOT" || exit 1 @@ -104,9 +66,7 @@ FORMATERROR=$( # std namespace usage, test directory must also be covered. FORMATSTDERROR=$( ( - # make sure `using namespace std` is not used in INCLUDE_DIRECTORIES - # shellcheck disable=SC2068,SC2068 - grep -nIE -d skip "using namespace std;" ${NAMESPACE_STD_FREE_FILES[@]} + git grep -nIE "using namespace std;" -- '*.h' '*.cpp' ) || true ) From 3e77bdff88b241f9a88852ff73a70381e396bee8 Mon Sep 17 00:00:00 2001 From: Haoyang Ma Date: Mon, 20 May 2024 09:55:48 +0800 Subject: [PATCH 0217/1022] Update ossfuzz's README.md --- test/tools/ossfuzz/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/test/tools/ossfuzz/README.md b/test/tools/ossfuzz/README.md index dae338648980..d00cb3d5191f 100644 --- a/test/tools/ossfuzz/README.md +++ b/test/tools/ossfuzz/README.md @@ -32,6 +32,7 @@ $ rm -rf fuzzer-build && mkdir fuzzer-build && cd fuzzer-build ## Compile protobuf C++ bindings $ protoc --proto_path=../test/tools/ossfuzz yulProto.proto --cpp_out=../test/tools/ossfuzz $ protoc --proto_path=../test/tools/ossfuzz abiV2Proto.proto --cpp_out=../test/tools/ossfuzz +$ protoc --proto_path=../test/tools/ossfuzz solProto.proto --cpp_out=../test/tools/ossfuzz ## Run cmake $ export CC=clang CXX=clang++ $ cmake -DCMAKE_TOOLCHAIN_FILE=cmake/toolchains/libfuzzer.cmake -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE:-Release} .. From 2d0783a74f241777ec01385f9ad55791449a17c4 Mon Sep 17 00:00:00 2001 From: Matheus Aguiar Date: Sun, 19 May 2024 22:59:35 -0300 Subject: [PATCH 0218/1022] Add stopAfter setting to syntax tests --- test/libsolidity/SyntaxTest.cpp | 12 +++++++++++- test/libsolidity/SyntaxTest.h | 1 + 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/test/libsolidity/SyntaxTest.cpp b/test/libsolidity/SyntaxTest.cpp index f17898c042a5..f350ea4624b1 100644 --- a/test/libsolidity/SyntaxTest.cpp +++ b/test/libsolidity/SyntaxTest.cpp @@ -51,6 +51,16 @@ SyntaxTest::SyntaxTest( if (!util::contains(compileViaYulAllowedValues, m_compileViaYul)) BOOST_THROW_EXCEPTION(std::runtime_error("Invalid compileViaYul value: " + m_compileViaYul + ".")); m_optimiseYul = m_reader.boolSetting("optimize-yul", true); + + static std::map const pipelineStages = { + {"parsing", PipelineStage::Parsing}, + {"analysis", PipelineStage::Analysis}, + {"compilation", PipelineStage::Compilation} + }; + std::string stopAfter = m_reader.stringSetting("stopAfter", "compilation"); + if (!pipelineStages.count(stopAfter)) + BOOST_THROW_EXCEPTION(std::runtime_error("Invalid stopAfter value: " + stopAfter + ".")); + m_stopAfter = pipelineStages.at(stopAfter); } void SyntaxTest::setupCompiler(CompilerStack& _compiler) @@ -72,7 +82,7 @@ void SyntaxTest::parseAndAnalyze() { try { - runFramework(withPreamble(m_sources.sources), PipelineStage::Compilation); + runFramework(withPreamble(m_sources.sources), m_stopAfter); if (!pipelineSuccessful() && stageSuccessful(PipelineStage::Analysis) && !compiler().isExperimentalAnalysis()) { ErrorList const& errors = compiler().errors(); diff --git a/test/libsolidity/SyntaxTest.h b/test/libsolidity/SyntaxTest.h index 95df3c6cd80c..085a32f944ea 100644 --- a/test/libsolidity/SyntaxTest.h +++ b/test/libsolidity/SyntaxTest.h @@ -55,6 +55,7 @@ class SyntaxTest: public AnalysisFramework, public solidity::test::CommonSyntaxT bool m_optimiseYul{}; std::string m_compileViaYul{}; langutil::Error::Severity m_minSeverity{}; + PipelineStage m_stopAfter; }; } From 50ad425948072d74b743641eff5968e1d703881b Mon Sep 17 00:00:00 2001 From: Matheus Aguiar Date: Sun, 19 May 2024 23:02:57 -0300 Subject: [PATCH 0219/1022] Add tests --- test/libsolidity/syntaxTests/stopAfterAnalysisError.sol | 8 ++++++++ .../stopAfterParsingAnalysisErrorNotShowing.sol | 6 ++++++ test/libsolidity/syntaxTests/stopAfterParsingError.sol | 7 +++++++ 3 files changed, 21 insertions(+) create mode 100644 test/libsolidity/syntaxTests/stopAfterAnalysisError.sol create mode 100644 test/libsolidity/syntaxTests/stopAfterParsingAnalysisErrorNotShowing.sol create mode 100644 test/libsolidity/syntaxTests/stopAfterParsingError.sol diff --git a/test/libsolidity/syntaxTests/stopAfterAnalysisError.sol b/test/libsolidity/syntaxTests/stopAfterAnalysisError.sol new file mode 100644 index 000000000000..ac74ecf3a3ce --- /dev/null +++ b/test/libsolidity/syntaxTests/stopAfterAnalysisError.sol @@ -0,0 +1,8 @@ +contract C { + function f(uint[] x) public pure { + } +} +// ==== +// stopAfter: analysis +// ---- +// TypeError 6651: (28-36): Data location must be "memory" or "calldata" for parameter in function, but none was given. diff --git a/test/libsolidity/syntaxTests/stopAfterParsingAnalysisErrorNotShowing.sol b/test/libsolidity/syntaxTests/stopAfterParsingAnalysisErrorNotShowing.sol new file mode 100644 index 000000000000..58efffea6fc4 --- /dev/null +++ b/test/libsolidity/syntaxTests/stopAfterParsingAnalysisErrorNotShowing.sol @@ -0,0 +1,6 @@ +contract C { + uint x = address(0xabc); +} +// ==== +// stopAfter: parsing +// ---- diff --git a/test/libsolidity/syntaxTests/stopAfterParsingError.sol b/test/libsolidity/syntaxTests/stopAfterParsingError.sol new file mode 100644 index 000000000000..911a28d77122 --- /dev/null +++ b/test/libsolidity/syntaxTests/stopAfterParsingError.sol @@ -0,0 +1,7 @@ +contract C { + uint storage x; +} +// ==== +// stopAfter:parsing +// ---- +// ParserError 2314: (22-29): Expected identifier but got 'storage' From 31aab83b6653160effa363aac87d4669665d11e3 Mon Sep 17 00:00:00 2001 From: Nikola Matic Date: Mon, 20 May 2024 13:31:52 +0200 Subject: [PATCH 0220/1022] Set release date for 0.8.26 --- Changelog.md | 2 +- docs/bugs_by_version.json | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/Changelog.md b/Changelog.md index 443259806f63..0837a7170e4b 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,4 +1,4 @@ -### 0.8.26 (unreleased) +### 0.8.26 (2024-05-21) Language Features: * Introduce a new overload ``require(bool, Error)`` that allows usage of ``require`` functions with custom errors. This feature is available in the ``via-ir`` pipeline only. diff --git a/docs/bugs_by_version.json b/docs/bugs_by_version.json index 52b6c9f48b3e..037a36341c16 100644 --- a/docs/bugs_by_version.json +++ b/docs/bugs_by_version.json @@ -1894,6 +1894,10 @@ "bugs": [], "released": "2024-03-14" }, + "0.8.26": { + "bugs": [], + "released": "2024-05-21" + }, "0.8.3": { "bugs": [ "FullInlinerNonExpressionSplitArgumentEvaluationOrder", From 9da33a63ea9da6fa5dc1f80e5c0a7102c0f96dab Mon Sep 17 00:00:00 2001 From: Nikola Matic Date: Mon, 20 May 2024 13:35:57 +0200 Subject: [PATCH 0221/1022] Set version to 0.8.27 --- CMakeLists.txt | 2 +- Changelog.md | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 91c1056ec3a4..b1a307afb9e0 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.26") +set(PROJECT_VERSION "0.8.27") # 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 0837a7170e4b..f48fbf080c40 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,3 +1,14 @@ +### 0.8.27 (unreleased) + +Language Features: + + +Compiler Features: + + +Bugfixes: + + ### 0.8.26 (2024-05-21) Language Features: From a8406b5692c00ad4ed7e56c9c00a4f131db06c5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nikola=20Mati=C4=87?= Date: Tue, 21 May 2024 10:03:22 +0200 Subject: [PATCH 0222/1022] Revert "Set version to 0 8 27" --- CMakeLists.txt | 2 +- Changelog.md | 11 ----------- 2 files changed, 1 insertion(+), 12 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b1a307afb9e0..91c1056ec3a4 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.27") +set(PROJECT_VERSION "0.8.26") # 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 f48fbf080c40..0837a7170e4b 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,14 +1,3 @@ -### 0.8.27 (unreleased) - -Language Features: - - -Compiler Features: - - -Bugfixes: - - ### 0.8.26 (2024-05-21) Language Features: From 194d3c107945348ce9fca2192b5d77f54d12f9de Mon Sep 17 00:00:00 2001 From: Nikola Matic Date: Tue, 21 May 2024 12:08:55 +0200 Subject: [PATCH 0223/1022] Set version to 0.8.27 --- CMakeLists.txt | 2 +- Changelog.md | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 91c1056ec3a4..b1a307afb9e0 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.26") +set(PROJECT_VERSION "0.8.27") # 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 0837a7170e4b..f48fbf080c40 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,3 +1,14 @@ +### 0.8.27 (unreleased) + +Language Features: + + +Compiler Features: + + +Bugfixes: + + ### 0.8.26 (2024-05-21) Language Features: From fe944d34f43ef1aa04fef089b6b9a96133085270 Mon Sep 17 00:00:00 2001 From: Nikola Matic Date: Wed, 22 May 2024 13:01:50 +0200 Subject: [PATCH 0224/1022] Add exclusion for require with errors to chk pragma script --- scripts/docs_version_pragma_check.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/docs_version_pragma_check.sh b/scripts/docs_version_pragma_check.sh index d56bed3a191b..c927cfb1e8af 100755 --- a/scripts/docs_version_pragma_check.sh +++ b/scripts/docs_version_pragma_check.sh @@ -154,7 +154,8 @@ SOLTMPDIR=$(mktemp -d) # We expect errors if explicitly stated, or if imports # are used (in the style guide) if ( ! grep -E "This will not compile after" "$f" >/dev/null && \ - grep -E "This will not compile|import \"" "$f" >/dev/null ) + grep -E "This will not compile|import \"" "$f" >/dev/null || \ + grep -R "This will only compile via IR" "$f" >/dev/null ) then opts=(--expect-errors) fi From 53370849855d997def412564b73ce8d2c77fd7dc Mon Sep 17 00:00:00 2001 From: clonker Date: Wed, 22 May 2024 21:10:49 +0200 Subject: [PATCH 0225/1022] formal test smod implementation corresponds to EVM smod --- test/formal/opcodes.py | 10 ++++++- test/formal/smod.py | 65 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+), 1 deletion(-) create mode 100644 test/formal/smod.py diff --git a/test/formal/opcodes.py b/test/formal/opcodes.py index e091e7847b99..a70a26fe5c8d 100644 --- a/test/formal/opcodes.py +++ b/test/formal/opcodes.py @@ -25,7 +25,15 @@ def ADDMOD(x, y, m): return If(m == 0, 0, Extract(x.size() - 1, 0, URem(ZeroExt(1, x) + ZeroExt(1, y), ZeroExt(1, m)))) def SMOD(x, y): - return If(y == 0, 0, x % y) + return If( + y == 0, + 0, + If( + x >= 0, + If(y >= 0, x % y, x % (-y)), + If(y >= 0, -((-x) % y), -((-x) % (-y))) + ) + ) def LT(x, y): return If(ULT(x, y), BitVecVal(1, x.size()), BitVecVal(0, x.size())) diff --git a/test/formal/smod.py b/test/formal/smod.py new file mode 100644 index 000000000000..d82578d18c4b --- /dev/null +++ b/test/formal/smod.py @@ -0,0 +1,65 @@ +from z3 import BitVec +from rule import Rule +from opcodes import SMOD + + +n_bits = 256 +X = BitVec('X', n_bits) +Y = BitVec('Y', n_bits) + + +def smod_test(a, b, r, op=SMOD): + r""" + Tests SMOD with predefined parameters a,b against an expected result r. + """ + to_check = Rule() + to_check.require(X == a) + to_check.require(Y == b) + to_check.check(op(X, Y), r) + + +# tests from: +# https://github.com/ethereum/tests/blob/2e37a9f41167534b07e0e8f247ea934a5fe3cac9/src/GeneralStateTestsFiller/VMTests/vmArithmeticTest/smodFiller.yml +smod_test(2, 3, 2) +smod_test(-1, 2, -1) +smod_test(0, -1, 0) +smod_test(3, 0, 0) +smod_test(-2, 3, -2) +smod_test(-2, 3, -2) +smod_test(16, 0, -1, op=lambda x, y: SMOD(x, y) - 1) + +# more tests +rule = Rule() +rule.require(X == 7) +rule.require(Y == 5) +rule.check(SMOD(X, Y), 2) + +rule = Rule() +rule.require(X == 7) +rule.require(Y == 5) +rule.check(SMOD(X, Y), 2) + +rule = Rule() +rule.require(X == -7) +rule.require(Y == 5) +rule.check(SMOD(X, Y), -2) + +rule = Rule() +rule.require(X == 7) +rule.require(Y == -5) +rule.check(SMOD(X, Y), 2) + +rule = Rule() +rule.require(X == -7) +rule.require(Y == -5) +rule.check(SMOD(X, Y), -2) + +for k in [-7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7]: + for i in [-13, -12, -11, 10, -7, -2, 1, 0, 1, 2, 7, 10, 11, 12, 13]: + rule = Rule() + rule.require(X == i) + rule.require(Y == k) + if k != 0: + rule.check(SMOD(X, Y) % Y, X % Y) + else: + rule.check(SMOD(X, Y), 0) From 6de168040227fe6b2400736812a38f2b305628dd Mon Sep 17 00:00:00 2001 From: Pawel Gebal Date: Thu, 9 May 2024 13:46:05 +0200 Subject: [PATCH 0226/1022] Remove UnderOverflow verification target for BMC engine --- libsolidity/formal/BMC.cpp | 75 ++++++------------- libsolidity/formal/ModelCheckerSettings.h | 2 +- .../blockchain_state/transfer_1.sol | 2 +- .../constructor_state_variable_init.sol | 2 +- .../constructor_state_variable_init.sol | 1 + ...onstructor_state_variable_init_asserts.sol | 1 + ...tructor_state_variable_init_chain_tree.sol | 1 + .../smtCheckerTests/operators/mod.sol | 1 + .../smtCheckerTests/operators/mod_signed.sol | 2 +- .../user_defined_operations_on_constants.sol | 2 +- ...r_defined_operations_on_constants_fail.sol | 1 + ...rator_matches_equivalent_function_call.sol | 7 +- .../unchecked/flipping_sign_tests.sol | 2 + 13 files changed, 41 insertions(+), 58 deletions(-) diff --git a/libsolidity/formal/BMC.cpp b/libsolidity/formal/BMC.cpp index 97dd7050fef8..2bb794cde40f 100644 --- a/libsolidity/formal/BMC.cpp +++ b/libsolidity/formal/BMC.cpp @@ -569,11 +569,18 @@ void BMC::endVisit(UnaryOperation const& _op) return; if (_op.getOperator() == Token::Sub && smt::isInteger(*_op.annotation().type)) + { + addVerificationTarget( + VerificationTargetType::Underflow, + expr(_op), + &_op + ); addVerificationTarget( - VerificationTargetType::UnderOverflow, + VerificationTargetType::Overflow, expr(_op), &_op ); + } } void BMC::endVisit(BinaryOperation const& _op) @@ -813,32 +820,29 @@ std::pair BMC::arithmeticOperation( if (_op == Token::Mod) return values; - VerificationTargetType type; // The order matters here: // If _op is Div and intType is signed, we only care about overflow. if (_op == Token::Div) { if (intType->isSigned()) // Signed division can only overflow. - type = VerificationTargetType::Overflow; + addVerificationTarget(VerificationTargetType::Overflow, values.second, &_expression); else // Unsigned division cannot underflow/overflow. return values; } else if (intType->isSigned()) - type = VerificationTargetType::UnderOverflow; + { + addVerificationTarget(VerificationTargetType::Overflow, values.second, &_expression); + addVerificationTarget(VerificationTargetType::Underflow, values.second, &_expression); + } else if (_op == Token::Sub) - type = VerificationTargetType::Underflow; + addVerificationTarget(VerificationTargetType::Underflow, values.second, &_expression); else if (_op == Token::Add || _op == Token::Mul) - type = VerificationTargetType::Overflow; + addVerificationTarget(VerificationTargetType::Overflow, values.second, &_expression); else solAssert(false, ""); - addVerificationTarget( - type, - values.second, - &_expression - ); return values; } @@ -919,6 +923,12 @@ void BMC::checkVerificationTargets() void BMC::checkVerificationTarget(BMCVerificationTarget& _target) { + if ( + m_solvedTargets.count(_target.expression) && + m_solvedTargets.at(_target.expression).count(_target.type) + ) + return; + switch (_target.type) { case VerificationTargetType::ConstantCondition: @@ -930,10 +940,6 @@ void BMC::checkVerificationTarget(BMCVerificationTarget& _target) case VerificationTargetType::Overflow: checkOverflow(_target); break; - case VerificationTargetType::UnderOverflow: - checkUnderflow(_target); - checkOverflow(_target); - break; case VerificationTargetType::DivByZero: checkDivByZero(_target); break; @@ -961,19 +967,10 @@ void BMC::checkConstantCondition(BMCVerificationTarget& _target) void BMC::checkUnderflow(BMCVerificationTarget& _target) { solAssert( - _target.type == VerificationTargetType::Underflow || - _target.type == VerificationTargetType::UnderOverflow, + _target.type == VerificationTargetType::Underflow, "" ); - if ( - m_solvedTargets.count(_target.expression) && ( - m_solvedTargets.at(_target.expression).count(VerificationTargetType::Underflow) || - m_solvedTargets.at(_target.expression).count(VerificationTargetType::UnderOverflow) - ) - ) - return; - auto const* intType = dynamic_cast(_target.expression->annotation().type); if (!intType) intType = TypeProvider::uint256(); @@ -994,19 +991,10 @@ void BMC::checkUnderflow(BMCVerificationTarget& _target) void BMC::checkOverflow(BMCVerificationTarget& _target) { solAssert( - _target.type == VerificationTargetType::Overflow || - _target.type == VerificationTargetType::UnderOverflow, + _target.type == VerificationTargetType::Overflow, "" ); - if ( - m_solvedTargets.count(_target.expression) && ( - m_solvedTargets.at(_target.expression).count(VerificationTargetType::Overflow) || - m_solvedTargets.at(_target.expression).count(VerificationTargetType::UnderOverflow) - ) - ) - return; - auto const* intType = dynamic_cast(_target.expression->annotation().type); if (!intType) intType = TypeProvider::uint256(); @@ -1028,12 +1016,6 @@ void BMC::checkDivByZero(BMCVerificationTarget& _target) { solAssert(_target.type == VerificationTargetType::DivByZero, ""); - if ( - m_solvedTargets.count(_target.expression) && - m_solvedTargets.at(_target.expression).count(VerificationTargetType::DivByZero) - ) - return; - checkCondition( _target, _target.constraints && (_target.value == 0), @@ -1051,11 +1033,6 @@ void BMC::checkBalance(BMCVerificationTarget& _target) { solAssert(_target.type == VerificationTargetType::Balance, ""); - if ( - m_solvedTargets.count(_target.expression) && - m_solvedTargets.at(_target.expression).count(VerificationTargetType::Balance) - ) - return; checkCondition( _target, _target.constraints && _target.value, @@ -1072,12 +1049,6 @@ void BMC::checkAssert(BMCVerificationTarget& _target) { solAssert(_target.type == VerificationTargetType::Assert, ""); - if ( - m_solvedTargets.count(_target.expression) && - m_solvedTargets.at(_target.expression).count(_target.type) - ) - return; - checkCondition( _target, _target.constraints && !_target.value, diff --git a/libsolidity/formal/ModelCheckerSettings.h b/libsolidity/formal/ModelCheckerSettings.h index 0cfa370c40c8..3dbe472b854b 100644 --- a/libsolidity/formal/ModelCheckerSettings.h +++ b/libsolidity/formal/ModelCheckerSettings.h @@ -113,7 +113,7 @@ struct ModelCheckerInvariants std::set invariants; }; -enum class VerificationTargetType { ConstantCondition, Underflow, Overflow, UnderOverflow, DivByZero, Balance, Assert, PopEmptyArray, OutOfBounds }; +enum class VerificationTargetType { ConstantCondition, Underflow, Overflow, DivByZero, Balance, Assert, PopEmptyArray, OutOfBounds }; struct ModelCheckerTargets { diff --git a/test/libsolidity/smtCheckerTests/blockchain_state/transfer_1.sol b/test/libsolidity/smtCheckerTests/blockchain_state/transfer_1.sol index 3118086b921a..169257edff8a 100644 --- a/test/libsolidity/smtCheckerTests/blockchain_state/transfer_1.sol +++ b/test/libsolidity/smtCheckerTests/blockchain_state/transfer_1.sol @@ -12,4 +12,4 @@ contract C { // SMTIgnoreCex: yes // ---- // Warning 6328: (166-201): CHC: Assertion violation happens here. -// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. \ No newline at end of file +// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/bmc_coverage/branches_with_return/constructor_state_variable_init.sol b/test/libsolidity/smtCheckerTests/bmc_coverage/branches_with_return/constructor_state_variable_init.sol index c262e2481be5..4728a1cb0e61 100644 --- a/test/libsolidity/smtCheckerTests/bmc_coverage/branches_with_return/constructor_state_variable_init.sol +++ b/test/libsolidity/smtCheckerTests/bmc_coverage/branches_with_return/constructor_state_variable_init.sol @@ -39,4 +39,4 @@ contract C is B { // Warning 4661: (389-412): BMC: Assertion violation happens here. // Warning 4661: (489-513): BMC: Assertion violation happens here. // Warning 4661: (533-546): BMC: Assertion violation happens here. -// Info 6002: BMC: 3 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. +// Info 6002: BMC: 4 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/control_flow/branches_with_return/constructor_state_variable_init.sol b/test/libsolidity/smtCheckerTests/control_flow/branches_with_return/constructor_state_variable_init.sol index d33f9571b0c8..594580f898eb 100644 --- a/test/libsolidity/smtCheckerTests/control_flow/branches_with_return/constructor_state_variable_init.sol +++ b/test/libsolidity/smtCheckerTests/control_flow/branches_with_return/constructor_state_variable_init.sol @@ -40,3 +40,4 @@ contract C is B { // Warning 6328: (489-513): CHC: Assertion violation happens here. // Warning 6328: (533-546): CHC: Assertion violation happens here. // Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. +// Info 6002: BMC: 1 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/inheritance/constructor_state_variable_init_asserts.sol b/test/libsolidity/smtCheckerTests/inheritance/constructor_state_variable_init_asserts.sol index 03b634ba941d..40ae96db477b 100644 --- a/test/libsolidity/smtCheckerTests/inheritance/constructor_state_variable_init_asserts.sol +++ b/test/libsolidity/smtCheckerTests/inheritance/constructor_state_variable_init_asserts.sol @@ -38,3 +38,4 @@ contract C is B { // Warning 6328: (439-463): CHC: Assertion violation happens here. // Warning 6328: (483-496): CHC: Assertion violation happens here. // Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. +// Info 6002: BMC: 1 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/inheritance/constructor_state_variable_init_chain_tree.sol b/test/libsolidity/smtCheckerTests/inheritance/constructor_state_variable_init_chain_tree.sol index e98ddcb63c2e..638cb640d3db 100644 --- a/test/libsolidity/smtCheckerTests/inheritance/constructor_state_variable_init_chain_tree.sol +++ b/test/libsolidity/smtCheckerTests/inheritance/constructor_state_variable_init_chain_tree.sol @@ -42,3 +42,4 @@ contract C is B { // Warning 6328: (403-417): CHC: Assertion violation happens here. // Warning 6328: (450-463): CHC: Assertion violation happens here. // Info 1391: CHC: 6 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. +// Info 6002: BMC: 1 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/operators/mod.sol b/test/libsolidity/smtCheckerTests/operators/mod.sol index a600ef03f1d3..bd09b82402d5 100644 --- a/test/libsolidity/smtCheckerTests/operators/mod.sol +++ b/test/libsolidity/smtCheckerTests/operators/mod.sol @@ -11,3 +11,4 @@ contract C { // SMTEngine: all // ---- // Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. +// Info 6002: BMC: 1 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/operators/mod_signed.sol b/test/libsolidity/smtCheckerTests/operators/mod_signed.sol index 2e640f53fd77..c995a158a2f1 100644 --- a/test/libsolidity/smtCheckerTests/operators/mod_signed.sol +++ b/test/libsolidity/smtCheckerTests/operators/mod_signed.sol @@ -13,4 +13,4 @@ contract C { // ---- // Warning 6328: (131-148): CHC: Assertion violation might happen here. // Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. -// Info 6002: BMC: 1 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. +// Info 6002: BMC: 3 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/operators/userDefined/user_defined_operations_on_constants.sol b/test/libsolidity/smtCheckerTests/operators/userDefined/user_defined_operations_on_constants.sol index c39360b656d2..fe12892eaba4 100644 --- a/test/libsolidity/smtCheckerTests/operators/userDefined/user_defined_operations_on_constants.sol +++ b/test/libsolidity/smtCheckerTests/operators/userDefined/user_defined_operations_on_constants.sol @@ -61,4 +61,4 @@ contract C { // SMTEngine: all // ---- // Info 1391: CHC: 21 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. - +// Info 6002: BMC: 1 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/operators/userDefined/user_defined_operations_on_constants_fail.sol b/test/libsolidity/smtCheckerTests/operators/userDefined/user_defined_operations_on_constants_fail.sol index 25674513c0de..8afd995ea06c 100644 --- a/test/libsolidity/smtCheckerTests/operators/userDefined/user_defined_operations_on_constants_fail.sol +++ b/test/libsolidity/smtCheckerTests/operators/userDefined/user_defined_operations_on_constants_fail.sol @@ -77,3 +77,4 @@ contract C { // Warning 6328: (2783-2804): CHC: Assertion violation happens here. // Warning 6328: (2829-2850): CHC: Assertion violation happens here. // Info 1391: CHC: 5 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. +// Info 6002: BMC: 1 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/operators/userDefined/user_defined_operator_matches_equivalent_function_call.sol b/test/libsolidity/smtCheckerTests/operators/userDefined/user_defined_operator_matches_equivalent_function_call.sol index b734079c7df5..b3887bfa002d 100644 --- a/test/libsolidity/smtCheckerTests/operators/userDefined/user_defined_operator_matches_equivalent_function_call.sol +++ b/test/libsolidity/smtCheckerTests/operators/userDefined/user_defined_operator_matches_equivalent_function_call.sol @@ -71,7 +71,12 @@ contract C { // Warning 6328: (2209-2235): CHC: Assertion violation might happen here. // Warning 6328: (2245-2271): CHC: Assertion violation might happen here. // Info 1391: CHC: 10 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. +// Warning 2661: (679-708): BMC: Overflow (resulting value larger than 32767) happens here. +// Warning 4144: (679-708): BMC: Underflow (resulting value less than -32768) happens here. +// Warning 2661: (777-806): BMC: Overflow (resulting value larger than 32767) happens here. +// Warning 2661: (953-982): BMC: Overflow (resulting value larger than 32767) happens here. +// Warning 4144: (953-982): BMC: Underflow (resulting value less than -32768) happens here. // Warning 3046: (1051-1080): BMC: Division by zero happens here. // Warning 3046: (1149-1178): BMC: Division by zero happens here. // Warning 7812: (2245-2271): BMC: Assertion violation might happen here. -// Info 6002: BMC: 6 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. +// Info 6002: BMC: 10 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/unchecked/flipping_sign_tests.sol b/test/libsolidity/smtCheckerTests/unchecked/flipping_sign_tests.sol index 96b415010596..59a4b3d26e23 100644 --- a/test/libsolidity/smtCheckerTests/unchecked/flipping_sign_tests.sol +++ b/test/libsolidity/smtCheckerTests/unchecked/flipping_sign_tests.sol @@ -11,3 +11,5 @@ contract test { // ---- // Warning 6328: (110-125): CHC: Assertion violation happens here. // Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. +// Warning 2661: (117-119): BMC: Overflow (resulting value larger than 2**255 - 1) happens here. +// Info 6002: BMC: 2 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. From f87a88aeab6f93cdbc3bef3ba7a3ee74cd4b0695 Mon Sep 17 00:00:00 2001 From: Pawel Gebal Date: Wed, 22 May 2024 17:08:23 +0200 Subject: [PATCH 0227/1022] SMTChecker: Add CHC engine check for underflow and overflow in unary minus operation --- Changelog.md | 1 + libsolidity/formal/CHC.cpp | 17 +++++++++++++++++ .../constructor_state_variable_init.sol | 3 +-- .../constructor_state_variable_init_asserts.sol | 3 +-- ...nstructor_state_variable_init_chain_tree.sol | 3 +-- .../smtCheckerTests/operators/mod.sol | 3 +-- .../smtCheckerTests/operators/mod_signed.sol | 4 ++-- .../operators/unary_minus_bmc.sol | 11 +++++++++++ .../operators/unary_minus_chc.sol | 11 +++++++++++ .../user_defined_operations_on_constants.sol | 3 +-- ...ser_defined_operations_on_constants_fail.sol | 3 +-- ...perator_matches_equivalent_function_call.sol | 16 +++++++--------- .../unchecked/flipping_sign_tests.sol | 7 +++---- 13 files changed, 58 insertions(+), 27 deletions(-) create mode 100644 test/libsolidity/smtCheckerTests/operators/unary_minus_bmc.sol create mode 100644 test/libsolidity/smtCheckerTests/operators/unary_minus_chc.sol diff --git a/Changelog.md b/Changelog.md index f48fbf080c40..eb9d87ea8902 100644 --- a/Changelog.md +++ b/Changelog.md @@ -4,6 +4,7 @@ Language Features: Compiler Features: + * SMTChecker: Add CHC engine check for underflow and overflow in unary minus operation. Bugfixes: diff --git a/libsolidity/formal/CHC.cpp b/libsolidity/formal/CHC.cpp index b6ffd5954ffb..c520d13f6b0f 100644 --- a/libsolidity/formal/CHC.cpp +++ b/libsolidity/formal/CHC.cpp @@ -554,6 +554,23 @@ void CHC::endVisit(UnaryOperation const& _op) internalFunctionCall(funDef, std::nullopt, _op.userDefinedFunctionType(), arguments, state().thisAddress()); createReturnedExpressions(funDef, _op); + return; + } + + if ( + _op.annotation().type->category() == Type::Category::RationalNumber || + _op.annotation().type->category() == Type::Category::FixedPoint + ) + return; + + if (_op.getOperator() == Token::Sub && smt::isInteger(*_op.annotation().type)) + { + auto const* intType = dynamic_cast(_op.annotation().type); + if (!intType) + intType = TypeProvider::uint256(); + + verificationTargetEncountered(&_op, VerificationTargetType::Underflow, expr(_op) < intType->minValue()); + verificationTargetEncountered(&_op, VerificationTargetType::Overflow, expr(_op) > intType->maxValue()); } } diff --git a/test/libsolidity/smtCheckerTests/control_flow/branches_with_return/constructor_state_variable_init.sol b/test/libsolidity/smtCheckerTests/control_flow/branches_with_return/constructor_state_variable_init.sol index 594580f898eb..88036eb550de 100644 --- a/test/libsolidity/smtCheckerTests/control_flow/branches_with_return/constructor_state_variable_init.sol +++ b/test/libsolidity/smtCheckerTests/control_flow/branches_with_return/constructor_state_variable_init.sol @@ -39,5 +39,4 @@ contract C is B { // Warning 6328: (389-412): CHC: Assertion violation happens here. // Warning 6328: (489-513): CHC: Assertion violation happens here. // Warning 6328: (533-546): CHC: Assertion violation happens here. -// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. -// Info 6002: BMC: 1 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. +// Info 1391: CHC: 4 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/inheritance/constructor_state_variable_init_asserts.sol b/test/libsolidity/smtCheckerTests/inheritance/constructor_state_variable_init_asserts.sol index 40ae96db477b..db81b1d0fdb0 100644 --- a/test/libsolidity/smtCheckerTests/inheritance/constructor_state_variable_init_asserts.sol +++ b/test/libsolidity/smtCheckerTests/inheritance/constructor_state_variable_init_asserts.sol @@ -37,5 +37,4 @@ contract C is B { // Warning 6328: (339-362): CHC: Assertion violation happens here. // Warning 6328: (439-463): CHC: Assertion violation happens here. // Warning 6328: (483-496): CHC: Assertion violation happens here. -// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. -// Info 6002: BMC: 1 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. +// Info 1391: CHC: 4 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/inheritance/constructor_state_variable_init_chain_tree.sol b/test/libsolidity/smtCheckerTests/inheritance/constructor_state_variable_init_chain_tree.sol index 638cb640d3db..8fe0cb28e0f0 100644 --- a/test/libsolidity/smtCheckerTests/inheritance/constructor_state_variable_init_chain_tree.sol +++ b/test/libsolidity/smtCheckerTests/inheritance/constructor_state_variable_init_chain_tree.sol @@ -41,5 +41,4 @@ contract C is B { // ---- // Warning 6328: (403-417): CHC: Assertion violation happens here. // Warning 6328: (450-463): CHC: Assertion violation happens here. -// Info 1391: CHC: 6 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. -// Info 6002: BMC: 1 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. +// Info 1391: CHC: 7 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/operators/mod.sol b/test/libsolidity/smtCheckerTests/operators/mod.sol index bd09b82402d5..d12e5c49d5a3 100644 --- a/test/libsolidity/smtCheckerTests/operators/mod.sol +++ b/test/libsolidity/smtCheckerTests/operators/mod.sol @@ -10,5 +10,4 @@ contract C { // ==== // SMTEngine: all // ---- -// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. -// Info 6002: BMC: 1 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. +// Info 1391: CHC: 4 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/operators/mod_signed.sol b/test/libsolidity/smtCheckerTests/operators/mod_signed.sol index c995a158a2f1..c34bd08e3adb 100644 --- a/test/libsolidity/smtCheckerTests/operators/mod_signed.sol +++ b/test/libsolidity/smtCheckerTests/operators/mod_signed.sol @@ -12,5 +12,5 @@ contract C { // SMTEngine: all // ---- // Warning 6328: (131-148): CHC: Assertion violation might happen here. -// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. -// Info 6002: BMC: 3 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. +// Info 1391: CHC: 5 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. +// Info 6002: BMC: 1 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/operators/unary_minus_bmc.sol b/test/libsolidity/smtCheckerTests/operators/unary_minus_bmc.sol new file mode 100644 index 000000000000..052554d21c63 --- /dev/null +++ b/test/libsolidity/smtCheckerTests/operators/unary_minus_bmc.sol @@ -0,0 +1,11 @@ +contract C +{ + function f(int x) public pure { + assert(x == -x); + } +} +// ==== +// SMTEngine: bmc +// ---- +// Warning 4661: (48-63): BMC: Assertion violation happens here. +// Info 6002: BMC: 1 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/operators/unary_minus_chc.sol b/test/libsolidity/smtCheckerTests/operators/unary_minus_chc.sol new file mode 100644 index 000000000000..0d1bf972be49 --- /dev/null +++ b/test/libsolidity/smtCheckerTests/operators/unary_minus_chc.sol @@ -0,0 +1,11 @@ +contract C +{ + function f(int x) public pure { + assert(x == -x); + } +} +// ==== +// SMTEngine: chc +// ---- +// Warning 6328: (48-63): CHC: Assertion violation happens here. +// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/operators/userDefined/user_defined_operations_on_constants.sol b/test/libsolidity/smtCheckerTests/operators/userDefined/user_defined_operations_on_constants.sol index fe12892eaba4..49420440f456 100644 --- a/test/libsolidity/smtCheckerTests/operators/userDefined/user_defined_operations_on_constants.sol +++ b/test/libsolidity/smtCheckerTests/operators/userDefined/user_defined_operations_on_constants.sol @@ -60,5 +60,4 @@ contract C { // ==== // SMTEngine: all // ---- -// Info 1391: CHC: 21 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. -// Info 6002: BMC: 1 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. +// Info 1391: CHC: 22 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/operators/userDefined/user_defined_operations_on_constants_fail.sol b/test/libsolidity/smtCheckerTests/operators/userDefined/user_defined_operations_on_constants_fail.sol index 8afd995ea06c..106a7c5f09a1 100644 --- a/test/libsolidity/smtCheckerTests/operators/userDefined/user_defined_operations_on_constants_fail.sol +++ b/test/libsolidity/smtCheckerTests/operators/userDefined/user_defined_operations_on_constants_fail.sol @@ -76,5 +76,4 @@ contract C { // Warning 6328: (2741-2758): CHC: Assertion violation happens here. // Warning 6328: (2783-2804): CHC: Assertion violation happens here. // Warning 6328: (2829-2850): CHC: Assertion violation happens here. -// Info 1391: CHC: 5 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. -// Info 6002: BMC: 1 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. +// Info 1391: CHC: 6 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/operators/userDefined/user_defined_operator_matches_equivalent_function_call.sol b/test/libsolidity/smtCheckerTests/operators/userDefined/user_defined_operator_matches_equivalent_function_call.sol index b3887bfa002d..33665ee26dcc 100644 --- a/test/libsolidity/smtCheckerTests/operators/userDefined/user_defined_operator_matches_equivalent_function_call.sol +++ b/test/libsolidity/smtCheckerTests/operators/userDefined/user_defined_operator_matches_equivalent_function_call.sol @@ -56,27 +56,25 @@ contract C { // SMTIgnoreOS: macos // ---- // Warning 3944: (679-708): CHC: Underflow (resulting value less than -32768) might happen here. -// Warning 4984: (679-708): CHC: Overflow (resulting value larger than 32767) might happen here. -// Warning 3944: (777-806): CHC: Underflow (resulting value less than -32768) happens here. +// Warning 4984: (679-708): CHC: Overflow (resulting value larger than 32767) happens here. +// Warning 3944: (777-806): CHC: Underflow (resulting value less than -32768) might happen here. // Warning 4984: (777-806): CHC: Overflow (resulting value larger than 32767) might happen here. +// Warning 4984: (870-884): CHC: Overflow (resulting value larger than 32767) might happen here. // Warning 3944: (953-982): CHC: Underflow (resulting value less than -32768) might happen here. // Warning 4984: (953-982): CHC: Overflow (resulting value larger than 32767) might happen here. // Warning 4984: (1051-1080): CHC: Overflow (resulting value larger than 32767) might happen here. -// Warning 4281: (1051-1080): CHC: Division by zero might happen here. +// Warning 4281: (1051-1080): CHC: Division by zero happens here. // Warning 4281: (1149-1178): CHC: Division by zero might happen here. // Warning 6328: (2069-2095): CHC: Assertion violation might happen here. -// Warning 6328: (2105-2131): CHC: Assertion violation might happen here. // Warning 6328: (2141-2163): CHC: Assertion violation might happen here. -// Warning 6328: (2173-2199): CHC: Assertion violation might happen here. // Warning 6328: (2209-2235): CHC: Assertion violation might happen here. // Warning 6328: (2245-2271): CHC: Assertion violation might happen here. -// Info 1391: CHC: 10 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. -// Warning 2661: (679-708): BMC: Overflow (resulting value larger than 32767) happens here. +// Info 1391: CHC: 13 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. // Warning 4144: (679-708): BMC: Underflow (resulting value less than -32768) happens here. // Warning 2661: (777-806): BMC: Overflow (resulting value larger than 32767) happens here. +// Warning 4144: (777-806): BMC: Underflow (resulting value less than -32768) happens here. // Warning 2661: (953-982): BMC: Overflow (resulting value larger than 32767) happens here. // Warning 4144: (953-982): BMC: Underflow (resulting value less than -32768) happens here. -// Warning 3046: (1051-1080): BMC: Division by zero happens here. // Warning 3046: (1149-1178): BMC: Division by zero happens here. // Warning 7812: (2245-2271): BMC: Assertion violation might happen here. -// Info 6002: BMC: 10 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. +// Info 6002: BMC: 8 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/unchecked/flipping_sign_tests.sol b/test/libsolidity/smtCheckerTests/unchecked/flipping_sign_tests.sol index 59a4b3d26e23..536d2a2b443f 100644 --- a/test/libsolidity/smtCheckerTests/unchecked/flipping_sign_tests.sol +++ b/test/libsolidity/smtCheckerTests/unchecked/flipping_sign_tests.sol @@ -2,14 +2,13 @@ contract test { function f() public pure returns (bool) { int256 x = -2**255; unchecked { assert(-x == x); } - assert(-x == x); // CHC apparently does not create an underflow target for unary minus + assert(-x == x); return true; } } // ==== // SMTEngine: all // ---- +// Warning 4984: (117-119): CHC: Overflow (resulting value larger than 2**255 - 1) happens here. // Warning 6328: (110-125): CHC: Assertion violation happens here. -// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. -// Warning 2661: (117-119): BMC: Overflow (resulting value larger than 2**255 - 1) happens here. -// Info 6002: BMC: 2 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. +// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. From f80d45d07f989315f6d540d629368447397a35ab Mon Sep 17 00:00:00 2001 From: Pawel Gebal Date: Fri, 24 May 2024 17:26:03 +0200 Subject: [PATCH 0228/1022] SMTChecker: Add SMTShowProvedSafe option for use in SMT checker tests --- scripts/error_codes.py | 1 - test/libsolidity/SMTCheckerTest.cpp | 8 ++++++++ test/libsolidity/SMTCheckerTest.h | 2 ++ .../smtCheckerTests/operators/compound_add.sol | 5 ++++- 4 files changed, 14 insertions(+), 2 deletions(-) diff --git a/scripts/error_codes.py b/scripts/error_codes.py index 27e7b1102bbe..8ee5cbbdeda7 100755 --- a/scripts/error_codes.py +++ b/scripts/error_codes.py @@ -206,7 +206,6 @@ def examine_id_coverage(top_dir, source_id_to_file_names, new_ids_only=False): "2339", # SMTChecker, covered by CL tests "2961", # SMTChecker, covered by CL tests "6240", # SMTChecker, covered by CL tests - "9576", # SMTChecker, covered by CL tests } assert len(test_ids & white_ids) == 0, "The sets are not supposed to intersect" test_ids |= white_ids diff --git a/test/libsolidity/SMTCheckerTest.cpp b/test/libsolidity/SMTCheckerTest.cpp index 893ccb0f1537..e3ec14c97c0d 100644 --- a/test/libsolidity/SMTCheckerTest.cpp +++ b/test/libsolidity/SMTCheckerTest.cpp @@ -38,6 +38,14 @@ SMTCheckerTest::SMTCheckerTest(std::string const& _filename): SyntaxTest(_filena else BOOST_THROW_EXCEPTION(std::runtime_error("Invalid SMT external calls mode.")); + auto const& showProvedSafe = m_reader.stringSetting("SMTShowProvedSafe", "no"); + if (showProvedSafe == "no") + m_modelCheckerSettings.showProvedSafe = false; + else if (showProvedSafe == "yes") + m_modelCheckerSettings.showProvedSafe = true; + else + BOOST_THROW_EXCEPTION(std::runtime_error("Invalid SMT \"show proved safe\" choice.")); + auto const& showUnproved = m_reader.stringSetting("SMTShowUnproved", "yes"); if (showUnproved == "no") m_modelCheckerSettings.showUnproved = false; diff --git a/test/libsolidity/SMTCheckerTest.h b/test/libsolidity/SMTCheckerTest.h index d42572dc5b29..aa0f92121a70 100644 --- a/test/libsolidity/SMTCheckerTest.h +++ b/test/libsolidity/SMTCheckerTest.h @@ -52,6 +52,8 @@ class SMTCheckerTest: public SyntaxTest Set in m_ignoreCex. SMTIgnoreInv: `yes`, `no`, where the default is `no`. Set in m_modelCheckerSettings. + SMTShowProvedSafe: `yes`, `no`, where the default is `no`. + Set in m_modelCheckerSettings. SMTShowUnproved: `yes`, `no`, where the default is `yes`. Set in m_modelCheckerSettings. SMTSolvers: `all`, `cvc4`, `z3`, `none`, where the default is `all`. diff --git a/test/libsolidity/smtCheckerTests/operators/compound_add.sol b/test/libsolidity/smtCheckerTests/operators/compound_add.sol index 7a18b1c7ee4e..852956f031a3 100644 --- a/test/libsolidity/smtCheckerTests/operators/compound_add.sol +++ b/test/libsolidity/smtCheckerTests/operators/compound_add.sol @@ -10,6 +10,9 @@ contract C } // ==== // SMTEngine: all +// SMTShowProvedSafe: yes // ---- // Warning 6328: (118-133): CHC: Assertion violation happens here. -// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. +// Info 9576: (90-95): CHC: Overflow (resulting value larger than 2**256 - 1) check is safe! +// Info 9576: (85-95): CHC: Overflow (resulting value larger than 2**256 - 1) check is safe! +// Info 9576: (99-114): CHC: Assertion violation check is safe! From 5240ef3ecbefc0ec29f42fc96aa4fc7683b9e41b Mon Sep 17 00:00:00 2001 From: Nikola Matic Date: Mon, 27 May 2024 10:40:08 +0200 Subject: [PATCH 0229/1022] Move type() helper function from TypeChecker to ASTUtils --- libsolidity/analysis/TypeChecker.cpp | 12 ------------ libsolidity/analysis/TypeChecker.h | 6 ------ libsolidity/ast/ASTUtils.cpp | 12 ++++++++++++ libsolidity/ast/ASTUtils.h | 6 ++++++ 4 files changed, 18 insertions(+), 18 deletions(-) diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp index 42c98a8f056e..5044414bff6d 100644 --- a/libsolidity/analysis/TypeChecker.cpp +++ b/libsolidity/analysis/TypeChecker.cpp @@ -80,18 +80,6 @@ bool TypeChecker::checkTypeRequirements(SourceUnit const& _source) return !Error::containsErrors(m_errorReporter.errors()); } -Type const* TypeChecker::type(Expression const& _expression) const -{ - solAssert(!!_expression.annotation().type, "Type requested but not present."); - return _expression.annotation().type; -} - -Type const* TypeChecker::type(VariableDeclaration const& _variable) const -{ - solAssert(!!_variable.annotation().type, "Type requested but not present."); - return _variable.annotation().type; -} - bool TypeChecker::visit(ContractDefinition const& _contract) { m_currentContract = &_contract; diff --git a/libsolidity/analysis/TypeChecker.h b/libsolidity/analysis/TypeChecker.h index 2ef6b818be6e..d7998d1784c6 100644 --- a/libsolidity/analysis/TypeChecker.h +++ b/libsolidity/analysis/TypeChecker.h @@ -56,12 +56,6 @@ class TypeChecker: private ASTConstVisitor /// @returns true iff all checks passed. Note even if all checks passed, errors() can still contain warnings bool checkTypeRequirements(SourceUnit const& _source); - /// @returns the type of an expression and asserts that it is present. - Type const* type(Expression const& _expression) const; - /// @returns the type of the given variable and throws if the type is not present - /// (this can happen for variables with non-explicit types before their types are resolved) - Type const* type(VariableDeclaration const& _variable) const; - static bool typeSupportedByOldABIEncoder(Type const& _type, bool _isLibraryCall); private: diff --git a/libsolidity/ast/ASTUtils.cpp b/libsolidity/ast/ASTUtils.cpp index 27c0833d26b1..7d434f896d12 100644 --- a/libsolidity/ast/ASTUtils.cpp +++ b/libsolidity/ast/ASTUtils.cpp @@ -95,4 +95,16 @@ Expression const* resolveOuterUnaryTuples(Expression const* _expr) return _expr; } +Type const* type(Expression const& _expression) +{ + solAssert(!!_expression.annotation().type, "Type requested but not present."); + return _expression.annotation().type; +} + +Type const* type(VariableDeclaration const& _variable) +{ + solAssert(!!_variable.annotation().type, "Type requested but not present."); + return _variable.annotation().type; +} + } diff --git a/libsolidity/ast/ASTUtils.h b/libsolidity/ast/ASTUtils.h index f6e3f0641dae..b31bd20d5845 100644 --- a/libsolidity/ast/ASTUtils.h +++ b/libsolidity/ast/ASTUtils.h @@ -42,4 +42,10 @@ ASTNode const* locateInnermostASTNode(int _offsetInFile, SourceUnit const& _sour /// into unary tuples and returns the contained expression. Expression const* resolveOuterUnaryTuples(Expression const* _expr); +/// @returns the type of an expression and asserts that it is present. +Type const* type(Expression const& _expression); +/// @returns the type of the given variable and throws if the type is not present +/// (this can happen for variables with non-explicit types before their types are resolved) +Type const* type(VariableDeclaration const& _variable); + } From c285bf3155a522b1c803d4bd811b0b05bd302240 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Thu, 23 May 2024 19:34:16 +0200 Subject: [PATCH 0230/1022] ReleaseChecklist: Review and approve blog posts before the release starts --- ReleaseChecklist.md | 1 + 1 file changed, 1 insertion(+) diff --git a/ReleaseChecklist.md b/ReleaseChecklist.md index 5db731cfc591..30dc30a49016 100644 --- a/ReleaseChecklist.md +++ b/ReleaseChecklist.md @@ -38,6 +38,7 @@ At least a day before the release: ### Blog Post - [ ] Create a post on [solidity-website](https://github.com/ethereum/solidity-website/tree/main/src/posts) in the ``Releases`` category and explain some of the new features or concepts. - [ ] Create a post on [solidity-website](https://github.com/ethereum/solidity-website/tree/main/src/posts) in the ``Security Alerts`` category in case of important bug(s). + - [ ] Get the posts reviewed and approved **before the release starts**. ### Changelog - [ ] Sort the changelog entries alphabetically and correct any errors you notice. Commit it. From 748d444a232cc4d8a65bd10a2ce333a047390e97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Thu, 23 May 2024 19:34:30 +0200 Subject: [PATCH 0231/1022] ReleaseChecklist: Fix a misplaced backtick --- ReleaseChecklist.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ReleaseChecklist.md b/ReleaseChecklist.md index 30dc30a49016..d5e5abdd1403 100644 --- a/ReleaseChecklist.md +++ b/ReleaseChecklist.md @@ -82,7 +82,7 @@ At least a day before the release: ### PPA - [ ] Create ``.release_ppa_auth`` at the root of your local Solidity checkout and set ``LAUNCHPAD_EMAIL`` and ``LAUNCHPAD_KEYID`` to your key's email and key id. - [ ] Double-check that the ``DISTRIBUTIONS`` list in ``scripts/release_ppa.sh`` and ``scripts/deps-ppa/static_z3.sh`` contains the most recent versions of Ubuntu. - - [ ] Make sure the [``~ethereum/cpp-build-deps`` PPA repository](https://launchpad.net/~ethereum/+archive/ubuntu/cpp-build-deps) contains ``libz3-static-dev builds`` for all current versions of Ubuntu. + - [ ] Make sure the [``~ethereum/cpp-build-deps`` PPA repository](https://launchpad.net/~ethereum/+archive/ubuntu/cpp-build-deps) contains ``libz3-static-dev`` builds for all current versions of Ubuntu. Note that it may be included in the ``z3-static`` multipackage (follow the ``View package details`` link to check). If not present, run ``scripts/deps-ppa/static_z3.sh`` and wait for the builds to succeed before continuing. - [ ] Run ``scripts/release_ppa.sh v$VERSION`` to create the PPA release. From 118362f97cdbc899dbdd40bd61b38eadb3adf86a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Thu, 23 May 2024 19:34:54 +0200 Subject: [PATCH 0232/1022] ReleaseChecklist: Link to "Learning from Past Releases" --- ReleaseChecklist.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ReleaseChecklist.md b/ReleaseChecklist.md index d5e5abdd1403..85d1ff82ea34 100644 --- a/ReleaseChecklist.md +++ b/ReleaseChecklist.md @@ -24,6 +24,7 @@ At least a day before the release: This is recommended especially when dealing with PPA for the first time, when we add a new Ubuntu version or when the PPA scripts were modified in this release cycle. - [ ] Verify that the release tarball of ``solc-js`` works. Bump version locally, add ``soljson.js`` from CI, build it, compare the file structure with the previous version, install it locally and try to use it. + - [ ] Review [Learning from Past Releases](https://notes.ethereum.org/@solidity/release-mistakes) to make sure you don't repeat the same mistakes. ### Drafts At least a day before the release: @@ -117,4 +118,5 @@ At least a day before the release: - [ ] Share the announcement on [Project Updates](https://discord.com/channels/420394352083337236/798974456704925696) - [ ] Share the announcement on [`#solidity` channel on Matrix](https://matrix.to/#/#ethereum_solidity:gitter.im) - [ ] Share the announcement on [`#solc-tooling`](https://matrix.to/#/#solc-tooling:matrix.org) + - [ ] If anything went wrong this time, mention it in [Learning from Past Releases](https://notes.ethereum.org/@solidity/release-mistakes). - [ ] Lean back, wait for bug reports and repeat from step 1 :). From dc9874127544ee142a977f1c36e8879a6718a8cd Mon Sep 17 00:00:00 2001 From: Nikola Matic Date: Fri, 24 May 2024 12:13:58 +0200 Subject: [PATCH 0233/1022] ReleaseChecklist: Mention that docs need to be built before linkcheck --- ReleaseChecklist.md | 1 + 1 file changed, 1 insertion(+) diff --git a/ReleaseChecklist.md b/ReleaseChecklist.md index 85d1ff82ea34..8ca2e7f96ed3 100644 --- a/ReleaseChecklist.md +++ b/ReleaseChecklist.md @@ -15,6 +15,7 @@ At least a day before the release: - [ ] Run ``make linkcheck`` from within ``docs/`` and fix any broken links it finds. Ignore false positives caused by ``href`` anchors and dummy links not meant to work. + **Note**: In order to run the link check, make sure you've built the docs first via ``docs.sh``. - [ ] Double-check that [the most recent docs builds at readthedocs](https://readthedocs.org/projects/solidity/builds/) succeeded. - [ ] Make sure that all merged PRs that should have changelog entries do have them. - [ ] Rerun CI on the top commits of main branches in all repositories that do not have daily activity by creating a test branch or PR: From 75ebcc0147f47c5f55da44ed64697b3d0572ace4 Mon Sep 17 00:00:00 2001 From: Moritz Hoffmann Date: Tue, 28 May 2024 10:42:07 +0200 Subject: [PATCH 0234/1022] test substitution of unlimited string literal in yul - Defines a contract with a name that exceeds 32 characters - programSize is defined as datasize(contractName) - if not correct, programSize can be substituted by optimizations into ctor return value - this is due to u256 words only capturing first 32 chars --- .../long_literals_as_builtin_args.yul | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 test/libyul/yulOptimizerTests/commonSubexpressionEliminator/long_literals_as_builtin_args.yul diff --git a/test/libyul/yulOptimizerTests/commonSubexpressionEliminator/long_literals_as_builtin_args.yul b/test/libyul/yulOptimizerTests/commonSubexpressionEliminator/long_literals_as_builtin_args.yul new file mode 100644 index 000000000000..34b44aad9492 --- /dev/null +++ b/test/libyul/yulOptimizerTests/commonSubexpressionEliminator/long_literals_as_builtin_args.yul @@ -0,0 +1,28 @@ +object "AccessControlDefaultAdminRules4233_14" { + code { + let programSize := datasize("AccessControlDefaultAdminRules4233_14") + let i := mload(64) + // argument of datasize is a literal of length >32 which shares a common substring + // of length 32 with programSize, this should not be substituted + let j := datasize("AccessControlDefaultAdminRules4233_14_deployed") + codecopy(i, dataoffset("AccessControlDefaultAdminRules4233_14_deployed"), j) + } + object "AccessControlDefaultAdminRules4233_14_deployed" { + code {} + } + +} +// ---- +// step: commonSubexpressionEliminator +// +// object "AccessControlDefaultAdminRules4233_14" { +// code { +// let programSize := datasize("AccessControlDefaultAdminRules4233_14") +// let i := mload(64) +// let j := datasize("AccessControlDefaultAdminRules4233_14_deployed") +// codecopy(i, dataoffset("AccessControlDefaultAdminRules4233_14_deployed"), j) +// } +// object "AccessControlDefaultAdminRules4233_14_deployed" { +// code { } +// } +// } From 85396f448f32e8d649e84b84740b52f7f2a605ed Mon Sep 17 00:00:00 2001 From: Matheus Aguiar Date: Mon, 27 May 2024 15:54:16 -0300 Subject: [PATCH 0235/1022] Introduce evm version prague --- .circleci/soltest_all.sh | 2 +- Changelog.md | 1 + docs/using-the-compiler.rst | 3 ++- liblangutil/EVMVersion.h | 34 +++++++++++++++++++++++++++++-- scripts/tests.sh | 2 +- solc/CommandLineParser.cpp | 2 +- test/EVMHost.cpp | 2 ++ test/tools/fuzzer_common.cpp | 3 ++- test/tools/ossfuzz/protoToYul.cpp | 2 ++ test/tools/ossfuzz/yulProto.proto | 1 + 10 files changed, 45 insertions(+), 7 deletions(-) diff --git a/.circleci/soltest_all.sh b/.circleci/soltest_all.sh index 009852710e51..86c14901b22c 100755 --- a/.circleci/soltest_all.sh +++ b/.circleci/soltest_all.sh @@ -31,7 +31,7 @@ REPODIR="$(realpath "$(dirname "$0")"/..)" # shellcheck source=scripts/common.sh source "${REPODIR}/scripts/common.sh" -DEFAULT_EVM_VALUES=(constantinople petersburg istanbul berlin london paris shanghai cancun) +DEFAULT_EVM_VALUES=(constantinople petersburg istanbul berlin london paris shanghai cancun prague) # Deserialize the EVM_VALUES array if it was provided as argument or # set EVM_VALUES to the default values. IFS=" " read -ra EVM_VALUES <<< "${1:-${DEFAULT_EVM_VALUES[@]}}" diff --git a/Changelog.md b/Changelog.md index eb9d87ea8902..e7a1d865ebda 100644 --- a/Changelog.md +++ b/Changelog.md @@ -4,6 +4,7 @@ Language Features: Compiler Features: + * EVM: Support for the EVM version "Prague". * SMTChecker: Add CHC engine check for underflow and overflow in unary minus operation. diff --git a/docs/using-the-compiler.rst b/docs/using-the-compiler.rst index 875c15b09d6d..544f45142383 100644 --- a/docs/using-the-compiler.rst +++ b/docs/using-the-compiler.rst @@ -181,6 +181,7 @@ at each version. Backward compatibility is not guaranteed between each version. - Introduces ``blobhash()`` in inline assembly and a corresponding global function to retrieve versioned hashes of blobs associated with the transaction (see `EIP-4844 `_). - Opcode ``mcopy`` is available in assembly (see `EIP-5656 `_). - Opcodes ``tstore`` and ``tload`` are available in assembly (see `EIP-1153 `_). +- ``prague`` (**experimental**) .. index:: ! standard JSON, ! --standard-json .. _compiler-api: @@ -344,7 +345,7 @@ Input Description // Version of the EVM to compile for. // Affects type checking and code generation. Can be homestead, // tangerineWhistle, spuriousDragon, byzantium, constantinople, - // petersburg, istanbul, berlin, london, paris, shanghai or cancun (default) + // petersburg, istanbul, berlin, london, paris, shanghai, cancun (default) or prague. "evmVersion": "cancun", // Optional: Change compilation pipeline to go through the Yul intermediate representation. // This is false by default. diff --git a/liblangutil/EVMVersion.h b/liblangutil/EVMVersion.h index 58b54f3dcaa7..774268917483 100644 --- a/liblangutil/EVMVersion.h +++ b/liblangutil/EVMVersion.h @@ -60,10 +60,25 @@ class EVMVersion: static EVMVersion paris() { return {Version::Paris}; } static EVMVersion shanghai() { return {Version::Shanghai}; } static EVMVersion cancun() { return {Version::Cancun}; } + static EVMVersion prague() { return {Version::Prague}; } static std::optional fromString(std::string const& _version) { - for (auto const& v: {homestead(), tangerineWhistle(), spuriousDragon(), byzantium(), constantinople(), petersburg(), istanbul(), berlin(), london(), paris(), shanghai(), cancun()}) + for (auto const& v: { + homestead(), + tangerineWhistle(), + spuriousDragon(), + byzantium(), + constantinople(), + petersburg(), + istanbul(), + berlin(), + london(), + paris(), + shanghai(), + cancun(), + prague() + }) if (_version == v.name()) return v; return std::nullopt; @@ -88,6 +103,7 @@ class EVMVersion: case Version::Paris: return "paris"; case Version::Shanghai: return "shanghai"; case Version::Cancun: return "cancun"; + case Version::Prague: return "prague"; } return "INVALID"; } @@ -115,7 +131,21 @@ class EVMVersion: bool canOverchargeGasForCall() const { return *this >= tangerineWhistle(); } private: - enum class Version { Homestead, TangerineWhistle, SpuriousDragon, Byzantium, Constantinople, Petersburg, Istanbul, Berlin, London, Paris, Shanghai, Cancun }; + enum class Version { + Homestead, + TangerineWhistle, + SpuriousDragon, + Byzantium, + Constantinople, + Petersburg, + Istanbul, + Berlin, + London, + Paris, + Shanghai, + Cancun, + Prague + }; EVMVersion(Version _version): m_version(_version) {} diff --git a/scripts/tests.sh b/scripts/tests.sh index 26eaf4b4b15b..dfbc0477342d 100755 --- a/scripts/tests.sh +++ b/scripts/tests.sh @@ -105,7 +105,7 @@ EVM_VERSIONS="homestead byzantium" if [ -z "$CI" ] then - EVM_VERSIONS+=" constantinople petersburg istanbul berlin london paris shanghai cancun" + EVM_VERSIONS+=" constantinople petersburg istanbul berlin london paris shanghai cancun prague" fi # And then run the Solidity unit-tests in the matrix combination of optimizer / no optimizer diff --git a/solc/CommandLineParser.cpp b/solc/CommandLineParser.cpp index 824c899110a2..e61c5ce0a7ae 100644 --- a/solc/CommandLineParser.cpp +++ b/solc/CommandLineParser.cpp @@ -605,7 +605,7 @@ General Information)").c_str(), g_strEVMVersion.c_str(), po::value()->value_name("version")->default_value(EVMVersion{}.name()), "Select desired EVM version. Either homestead, tangerineWhistle, spuriousDragon, " - "byzantium, constantinople, petersburg, istanbul, berlin, london, paris, shanghai or cancun." + "byzantium, constantinople, petersburg, istanbul, berlin, london, paris, shanghai, cancun or prague." ) ; if (!_forHelp) // Note: We intentionally keep this undocumented for now. diff --git a/test/EVMHost.cpp b/test/EVMHost.cpp index 4ab9b2b08d7e..5626f8d436e7 100644 --- a/test/EVMHost.cpp +++ b/test/EVMHost.cpp @@ -119,6 +119,8 @@ EVMHost::EVMHost(langutil::EVMVersion _evmVersion, evmc::VM& _vm): m_evmRevision = EVMC_SHANGHAI; else if (_evmVersion == langutil::EVMVersion::cancun()) m_evmRevision = EVMC_CANCUN; + else if (_evmVersion == langutil::EVMVersion::prague()) + m_evmRevision = EVMC_PRAGUE; else assertThrow(false, Exception, "Unsupported EVM version"); diff --git a/test/tools/fuzzer_common.cpp b/test/tools/fuzzer_common.cpp index b054883820fc..8b7dbffa8cfa 100644 --- a/test/tools/fuzzer_common.cpp +++ b/test/tools/fuzzer_common.cpp @@ -49,7 +49,8 @@ static std::vector s_evmVersions = { EVMVersion::istanbul(), EVMVersion::berlin(), EVMVersion::london(), - EVMVersion::paris() + EVMVersion::paris(), + EVMVersion::prague() }; void FuzzerUtil::testCompilerJsonInterface(std::string const& _input, bool _optimize, bool _quiet) diff --git a/test/tools/ossfuzz/protoToYul.cpp b/test/tools/ossfuzz/protoToYul.cpp index 8822666c8b02..7913f4d63450 100644 --- a/test/tools/ossfuzz/protoToYul.cpp +++ b/test/tools/ossfuzz/protoToYul.cpp @@ -119,6 +119,8 @@ EVMVersion ProtoConverter::evmVersionMapping(Program_Version const& _ver) return EVMVersion::shanghai(); case Program::CANCUN: return EVMVersion::cancun(); + case Program::PRAGUE: + return EVMVersion::prague(); } } diff --git a/test/tools/ossfuzz/yulProto.proto b/test/tools/ossfuzz/yulProto.proto index cf14b887c1b3..15ac01396bcc 100644 --- a/test/tools/ossfuzz/yulProto.proto +++ b/test/tools/ossfuzz/yulProto.proto @@ -406,6 +406,7 @@ message Program { PARIS = 9; SHANGHAI = 10; CANCUN = 11; + PRAGUE = 12; } oneof program_oneof { Block block = 1; From bbd5e2e130024a4ebb49d078338dc6a90059e779 Mon Sep 17 00:00:00 2001 From: clonker Date: Thu, 23 May 2024 13:24:44 +0200 Subject: [PATCH 0236/1022] yul identifiers with leading or trailing dot are restricted --- Changelog.md | 1 + libyul/optimiser/OptimizerUtilities.cpp | 13 +++++- .../leading_and_trailing_dots.yul | 42 +++++++++++++++++++ 3 files changed, 55 insertions(+), 1 deletion(-) create mode 100644 test/libyul/objectCompiler/leading_and_trailing_dots.yul diff --git a/Changelog.md b/Changelog.md index eb9d87ea8902..7689ede6bf34 100644 --- a/Changelog.md +++ b/Changelog.md @@ -8,6 +8,7 @@ Compiler Features: Bugfixes: +Yul Optimizer: Name simplification could lead to forbidden identifiers with a leading and/or trailing dot, e.g., ``x._`` would get simplified into ``x.``. ### 0.8.26 (2024-05-21) diff --git a/libyul/optimiser/OptimizerUtilities.cpp b/libyul/optimiser/OptimizerUtilities.cpp index 17f912762b38..bfa3d888f19b 100644 --- a/libyul/optimiser/OptimizerUtilities.cpp +++ b/libyul/optimiser/OptimizerUtilities.cpp @@ -36,6 +36,17 @@ using namespace solidity::langutil; using namespace solidity::util; using namespace solidity::yul; +namespace +{ + +bool hasLeadingOrTrailingDot(std::string_view const _s) +{ + yulAssert(!_s.empty()); + return _s.front() == '.' || _s.back() == '.'; +} + +} + void yul::removeEmptyBlocks(Block& _block) { auto isEmptyBlock = [](Statement const& _st) -> bool { @@ -46,7 +57,7 @@ void yul::removeEmptyBlocks(Block& _block) bool yul::isRestrictedIdentifier(Dialect const& _dialect, YulString const& _identifier) { - return _identifier.empty() || TokenTraits::isYulKeyword(_identifier.str()) || _dialect.reservedIdentifier(_identifier); + return _identifier.empty() || hasLeadingOrTrailingDot(_identifier.str()) || TokenTraits::isYulKeyword(_identifier.str()) || _dialect.reservedIdentifier(_identifier); } std::optional yul::toEVMInstruction(Dialect const& _dialect, YulString const& _name) diff --git a/test/libyul/objectCompiler/leading_and_trailing_dots.yul b/test/libyul/objectCompiler/leading_and_trailing_dots.yul new file mode 100644 index 000000000000..ea6a8fcd8bd8 --- /dev/null +++ b/test/libyul/objectCompiler/leading_and_trailing_dots.yul @@ -0,0 +1,42 @@ +{ + function e(_._) { + e(0) + } + e(2) + function f(n._) { + f(0) + } + f(2) + function g(_.n) { + g(0) + } + g(2) +} +// ---- +// Assembly: +// /* "source":49:50 */ +// 0x02 +// /* "source":6:42 */ +// tag_1: +// /* "source":34:35 */ +// 0x00 +// /* "source":32:36 */ +// tag_1 +// jump // in +// /* "source":56:92 */ +// tag_2: +// /* "source":84:85 */ +// 0x00 +// /* "source":82:86 */ +// tag_2 +// jump // in +// /* "source":106:142 */ +// tag_3: +// /* "source":134:135 */ +// 0x00 +// /* "source":132:136 */ +// tag_3 +// jump // in +// Bytecode: 60025b5f6002565b5f6007565b5f600c56 +// Opcodes: PUSH1 0x2 JUMPDEST PUSH0 PUSH1 0x2 JUMP JUMPDEST PUSH0 PUSH1 0x7 JUMP JUMPDEST PUSH0 PUSH1 0xC JUMP +// SourceMappings: 49:1:0:-:0;6:36;34:1;32:4;:::i;56:36::-;84:1;82:4;:::i;106:36::-;134:1;132:4;:::i From 69c646a6077f49b3ed0a7842b564106ffe156751 Mon Sep 17 00:00:00 2001 From: Daniel Zahariev Date: Tue, 28 May 2024 20:53:02 +0300 Subject: [PATCH 0237/1022] Update style-guide.rst Update function modifier order in the example to match with the guide. --- docs/style-guide.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/style-guide.rst b/docs/style-guide.rst index 0ac890cb3478..87e604124b87 100644 --- a/docs/style-guide.rst +++ b/docs/style-guide.rst @@ -662,7 +662,7 @@ Yes: return balanceOf[from]; } - function increment(uint x) public onlyOwner pure returns (uint) { + function increment(uint x) public pure onlyOwner returns (uint) { return x + 1; } From 6e6e5e504eb32b42cd522932ce8d07500a8fd2d3 Mon Sep 17 00:00:00 2001 From: shafu Date: Wed, 29 May 2024 14:25:31 +0200 Subject: [PATCH 0238/1022] Update assembly.rst --- docs/assembly.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/assembly.rst b/docs/assembly.rst index e08ff9f627c8..224d7520822b 100644 --- a/docs/assembly.rst +++ b/docs/assembly.rst @@ -9,7 +9,8 @@ Inline Assembly You can interleave Solidity statements with inline assembly in a language close to the one of the Ethereum Virtual Machine. This gives you more fine-grained control, -which is especially useful when you are enhancing the language by writing libraries. +which is especially useful when you are enhancing the language by writing libraries or +trying to optimize gas usage. The language used for inline assembly in Solidity is called :ref:`Yul ` and it is documented in its own section. This section will only cover From 76e31d9f1af12c2fc80343863589b939b0a0953c Mon Sep 17 00:00:00 2001 From: shafu Date: Wed, 29 May 2024 14:27:27 +0200 Subject: [PATCH 0239/1022] Update assembly.rst --- docs/assembly.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/assembly.rst b/docs/assembly.rst index 224d7520822b..cf2ce1bf9487 100644 --- a/docs/assembly.rst +++ b/docs/assembly.rst @@ -10,7 +10,7 @@ Inline Assembly You can interleave Solidity statements with inline assembly in a language close to the one of the Ethereum Virtual Machine. This gives you more fine-grained control, which is especially useful when you are enhancing the language by writing libraries or -trying to optimize gas usage. +optimizing gas usage. The language used for inline assembly in Solidity is called :ref:`Yul ` and it is documented in its own section. This section will only cover From e32b3ddc8a06888d9af047e2418a8e1f94bb1913 Mon Sep 17 00:00:00 2001 From: r0qs Date: Thu, 23 May 2024 16:48:34 +0200 Subject: [PATCH 0240/1022] Add authentication header to circleci api --- .circleci/config.yml | 7 ++ scripts/common/rest_api_helpers.py | 13 ++-- scripts/externalTests/download_benchmarks.py | 20 +++++- ...test_externalTests_benchmark_downloader.py | 64 +++++++++++++++---- 4 files changed, 83 insertions(+), 21 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 6feb033deaf3..3a246d3a5cb6 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1522,6 +1522,13 @@ jobs: c_ext_benchmarks: <<: *base_node_small steps: + - run: + name: Check CircleCI token presence; Skip job if not set. + command: | + if [[ -z "$CIRCLECI_TOKEN" ]]; then + echo "Skipping benchmarks..." + circleci-agent step halt + fi - install_python3: packages: requests - checkout diff --git a/scripts/common/rest_api_helpers.py b/scripts/common/rest_api_helpers.py index 31f973e818eb..caae2b5db813 100644 --- a/scripts/common/rest_api_helpers.py +++ b/scripts/common/rest_api_helpers.py @@ -1,3 +1,4 @@ +from os import environ from pathlib import Path from typing import List, Mapping, Optional import functools @@ -42,13 +43,13 @@ class FileAlreadyExists(APIHelperError): pass -def query_api(url: str, params: Mapping[str, str], debug_requests=False) -> dict: +def query_api(url: str, params: Mapping[str, str], headers: dict, debug_requests=False) -> dict: if debug_requests: print(f'REQUEST URL: {url}') if len(params) > 0: print(f'QUERY: {params}') - response = requests.get(url, params=params, timeout=60) + response = requests.get(url, params=params, headers=headers, timeout=60) response.raise_for_status() if debug_requests: @@ -63,11 +64,11 @@ def query_api(url: str, params: Mapping[str, str], debug_requests=False) -> dict return response.json() -def download_file(url: str, target_path: Path, overwrite=False): +def download_file(url: str, target_path: Path, headers: dict, overwrite=False): if not overwrite and target_path.exists(): raise FileAlreadyExists(f"Refusing to overwrite existing file: '{target_path}'.") - with requests.get(url, stream=True, timeout=60) as request: + with requests.get(url, headers, stream=True, timeout=60) as request: with open(target_path, 'wb') as target_file: shutil.copyfileobj(request.raw, target_file) @@ -86,6 +87,7 @@ def pull_request(self, pr_id: int) -> dict: return query_api( f'{self.BASE_URL}/repos/{self.project_slug}/pulls/{pr_id}', {}, + {}, self.debug_requests ) @@ -108,11 +110,12 @@ def paginated_query_api_iterator(self, url: str, params: Mapping[str, str], max_ page_count = 0 next_page_token = None + headers = {'Circle-Token': str(environ.get('CIRCLECI_TOKEN'))} if 'CIRCLECI_TOKEN' in environ else {} while max_pages is None or page_count < max_pages: if next_page_token is not None: params = {**params, 'page-token': next_page_token} - json_response = query_api(url, params, self.debug_requests) + json_response = query_api(url, params, headers, self.debug_requests) yield json_response['items'] next_page_token = json_response['next_page_token'] diff --git a/scripts/externalTests/download_benchmarks.py b/scripts/externalTests/download_benchmarks.py index 29f5fe4bc764..0f8a6503603d 100755 --- a/scripts/externalTests/download_benchmarks.py +++ b/scripts/externalTests/download_benchmarks.py @@ -2,7 +2,9 @@ from argparse import ArgumentParser, Namespace from enum import Enum, unique +from os import environ from pathlib import Path +from textwrap import dedent from typing import Mapping, Optional import sys @@ -28,8 +30,13 @@ class Status(Enum): def process_commandline() -> Namespace: script_description = ( - "Downloads benchmark results attached as artifacts to the c_ext_benchmarks job on CircleCI. " - "If no options are specified, downloads results for the currently checked out git branch." + """ + Downloads benchmark results attached as artifacts to the c_ext_benchmarks job on CircleCI. + If no options are specified, downloads results for the currently checked out git branch. + + The script requires the CIRCLECI_TOKEN environment variable to be set with a valid CircleCI API token. + You can generate a new token at https://app.circleci.com/settings/user/tokens. + """ ) parser = ArgumentParser(description=script_description) @@ -96,9 +103,11 @@ def download_benchmark_artifact( print(f"Missing artifact: {artifact_path}.") return False + headers = {'Circle-Token': str(environ.get('CIRCLECI_TOKEN'))} if 'CIRCLECI_TOKEN' in environ else {} download_file( artifacts[artifact_path]['url'], Path(f'{benchmark_name}-{branch}-{commit_hash[:8]}.json'), + headers, overwrite, ) @@ -162,6 +171,13 @@ def download_benchmarks( def main(): try: + if 'CIRCLECI_TOKEN' not in environ: + raise RuntimeError( + dedent(""" \ + CIRCLECI_TOKEN environment variable required but not set. + Please generate a new token at https://app.circleci.com/settings/user/tokens and set CIRCLECI_TOKEN. + """) + ) options = process_commandline() return download_benchmarks( options.branch, diff --git a/test/scripts/test_externalTests_benchmark_downloader.py b/test/scripts/test_externalTests_benchmark_downloader.py index aead618470c5..f9ca9ae72132 100644 --- a/test/scripts/test_externalTests_benchmark_downloader.py +++ b/test/scripts/test_externalTests_benchmark_downloader.py @@ -3,6 +3,8 @@ from pathlib import Path from unittest import TestCase from unittest.mock import call, Mock, patch +import os +import requests # NOTE: This test file file only works with scripts/ added to PYTHONPATH so pylint can't find the imports # pragma pylint: disable=import-error @@ -31,7 +33,7 @@ def _git_run_command_mock(command): "If you have updated the code, please remember to add matching command fixtures above." ) -def _requests_get_mock(url, params, timeout): +def _requests_get_mock(url, params, headers, timeout): response_mock = Mock() if url == 'https://api.github.com/repos/ethereum/solidity/pulls/12818': @@ -155,25 +157,37 @@ def _requests_get_mock(url, params, timeout): return response_mock if url == 'https://circleci.com/api/v2/project/gh/ethereum/solidity/1018023/artifacts': - response_mock.json.return_value = { - "next_page_token": None, - "items": [ - { - "path": "reports/externalTests/all-benchmarks.json", - "url": "https://circle-artifacts.com/0/reports/externalTests/all-benchmarks.json" - }, - { - "path": "reports/externalTests/summarized-benchmarks.json", - "url": "https://circle-artifacts.com/0/reports/externalTests/summarized-benchmarks.json" - } - ] - } + if ( + os.environ.get('CIRCLECI_TOKEN') == 'valid_token' and + headers.get('Circle-Token') == os.environ.get('CIRCLECI_TOKEN') + ): + response_mock.json.return_value = { + "next_page_token": None, + "items": [ + { + "path": "reports/externalTests/all-benchmarks.json", + "url": "https://circle-artifacts.com/0/reports/externalTests/all-benchmarks.json" + }, + { + "path": "reports/externalTests/summarized-benchmarks.json", + "url": "https://circle-artifacts.com/0/reports/externalTests/summarized-benchmarks.json" + } + ] + } + else: + response_mock.status_code = 401 + response_mock.json.return_value = { + "message": "Unauthorized" + } + error = requests.exceptions.HTTPError(f"401 Client Error: Unauthorized for url: {url}") + response_mock.raise_for_status.side_effect = error return response_mock raise RuntimeError( "The test tried to perform an unexpected GET request.\n" f"URL: {url}\n" + (f"query: {params}\n" if len(params) > 0 else "") + + (f"headers: {headers}\n" if len(headers) > 0 else "") + f"timeout: {timeout}\n" + "If you have updated the code, please remember to add matching response fixtures above." ) @@ -186,17 +200,20 @@ def setUp(self): @patch('externalTests.download_benchmarks.download_file') @patch('requests.get', _requests_get_mock) @patch('common.git_helpers.run_git_command',_git_run_command_mock) + @patch.dict(os.environ, {'CIRCLECI_TOKEN': 'valid_token'}) def test_download_benchmarks(download_file_mock): download_benchmarks(None, None, None, silent=True) download_file_mock.assert_has_calls([ call( 'https://circle-artifacts.com/0/reports/externalTests/summarized-benchmarks.json', Path('summarized-benchmarks-benchmark-downloader-fa1ddc6f.json'), + {'Circle-Token': 'valid_token'}, False ), call( 'https://circle-artifacts.com/0/reports/externalTests/all-benchmarks.json', Path('all-benchmarks-benchmark-downloader-fa1ddc6f.json'), + {'Circle-Token': 'valid_token'}, False ), ]) @@ -205,17 +222,20 @@ def test_download_benchmarks(download_file_mock): @patch('externalTests.download_benchmarks.download_file') @patch('requests.get', _requests_get_mock) @patch('common.git_helpers.run_git_command',_git_run_command_mock) + @patch.dict(os.environ, {'CIRCLECI_TOKEN': 'valid_token'}) def test_download_benchmarks_branch(download_file_mock): download_benchmarks('develop', None, None, silent=True) download_file_mock.assert_has_calls([ call( 'https://circle-artifacts.com/0/reports/externalTests/summarized-benchmarks.json', Path('summarized-benchmarks-develop-43f29c00.json'), + {'Circle-Token': 'valid_token'}, False ), call( 'https://circle-artifacts.com/0/reports/externalTests/all-benchmarks.json', Path('all-benchmarks-develop-43f29c00.json'), + {'Circle-Token': 'valid_token'}, False ), ]) @@ -224,17 +244,20 @@ def test_download_benchmarks_branch(download_file_mock): @patch('externalTests.download_benchmarks.download_file') @patch('requests.get', _requests_get_mock) @patch('common.git_helpers.run_git_command',_git_run_command_mock) + @patch.dict(os.environ, {'CIRCLECI_TOKEN': 'valid_token'}) def test_download_benchmarks_pr(download_file_mock): download_benchmarks(None, 12818, None, silent=True) download_file_mock.assert_has_calls([ call( 'https://circle-artifacts.com/0/reports/externalTests/summarized-benchmarks.json', Path('summarized-benchmarks-benchmark-downloader-fa1ddc6f.json'), + {'Circle-Token': 'valid_token'}, False ), call( 'https://circle-artifacts.com/0/reports/externalTests/all-benchmarks.json', Path('all-benchmarks-benchmark-downloader-fa1ddc6f.json'), + {'Circle-Token': 'valid_token'}, False ), ]) @@ -243,17 +266,30 @@ def test_download_benchmarks_pr(download_file_mock): @patch('externalTests.download_benchmarks.download_file') @patch('requests.get', _requests_get_mock) @patch('common.git_helpers.run_git_command',_git_run_command_mock) + @patch.dict(os.environ, {'CIRCLECI_TOKEN': 'valid_token'}) def test_download_benchmarks_base_of_pr(download_file_mock): download_benchmarks(None, None, 12818, silent=True) download_file_mock.assert_has_calls([ call( 'https://circle-artifacts.com/0/reports/externalTests/summarized-benchmarks.json', Path('summarized-benchmarks-develop-43f29c00.json'), + {'Circle-Token': 'valid_token'}, False ), call( 'https://circle-artifacts.com/0/reports/externalTests/all-benchmarks.json', Path('all-benchmarks-develop-43f29c00.json'), + {'Circle-Token': 'valid_token'}, False ), ]) + + # NOTE: No circleci token is set in the environment + @patch('externalTests.download_benchmarks.download_file') + @patch('requests.get', _requests_get_mock) + @patch('common.git_helpers.run_git_command',_git_run_command_mock) + def test_download_benchmarks_unauthorized_request(self, _): + with self.assertRaises(requests.exceptions.HTTPError) as manager: + download_benchmarks(None, None, None, silent=True) + + self.assertIn('401 Client Error: Unauthorized', str(manager.exception)) From 6ab7795b41d583d7138e99ae5471ecff64a84b53 Mon Sep 17 00:00:00 2001 From: r0qs Date: Tue, 28 May 2024 17:27:41 +0200 Subject: [PATCH 0241/1022] Update scripts/externalTests/download_benchmarks.py MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Kamil Śliwak --- scripts/externalTests/download_benchmarks.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/externalTests/download_benchmarks.py b/scripts/externalTests/download_benchmarks.py index 0f8a6503603d..508e801da3df 100755 --- a/scripts/externalTests/download_benchmarks.py +++ b/scripts/externalTests/download_benchmarks.py @@ -34,8 +34,8 @@ def process_commandline() -> Namespace: Downloads benchmark results attached as artifacts to the c_ext_benchmarks job on CircleCI. If no options are specified, downloads results for the currently checked out git branch. - The script requires the CIRCLECI_TOKEN environment variable to be set with a valid CircleCI API token. - You can generate a new token at https://app.circleci.com/settings/user/tokens. + The script will use the CIRCLECI_TOKEN environment as a CircleCI API token if set. + You can generate a new personal token at https://app.circleci.com/settings/user/tokens. """ ) From fea0c75a6a4b285ae1438ea7ae5e46102deb548d Mon Sep 17 00:00:00 2001 From: r0qs Date: Thu, 23 May 2024 16:48:34 +0200 Subject: [PATCH 0242/1022] Add authentication header to circleci api --- .circleci/config.yml | 24 +++++++++++--------- scripts/externalTests/download_benchmarks.py | 4 ++-- 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 3a246d3a5cb6..c58d01e32935 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1522,13 +1522,6 @@ jobs: c_ext_benchmarks: <<: *base_node_small steps: - - run: - name: Check CircleCI token presence; Skip job if not set. - command: | - if [[ -z "$CIRCLECI_TOKEN" ]]; then - echo "Skipping benchmarks..." - circleci-agent step halt - fi - install_python3: packages: requests - checkout @@ -1540,6 +1533,19 @@ jobs: - run: name: Summarize reports command: cat reports/externalTests/all-benchmarks.json | scripts/externalTests/summarize_benchmarks.sh > reports/externalTests/summarized-benchmarks.json + - store_artifacts: + path: reports/externalTests/all-benchmarks.json + - store_artifacts: + path: reports/externalTests/summarized-benchmarks.json + - run: + name: Check CircleCI token presence; Skip remaining steps if the token is not present. + command: | + # NOTE: download_benchmarks.py requires CIRCLECI_TOKEN environment variable to be set to + # a valid CircleCI API token to download the benchmark artifacts. + if [[ -z "$CIRCLECI_TOKEN" ]]; then + echo "Skipping download benchmarks..." + circleci-agent step halt + fi - run: name: Download reports from base branch command: | @@ -1584,10 +1590,6 @@ jobs: base-branch/all-benchmarks-*.json \ all-benchmarks.json > diff/benchmark-diff-all-table-inplace-absolute.md fi - - store_artifacts: - path: reports/externalTests/all-benchmarks.json - - store_artifacts: - path: reports/externalTests/summarized-benchmarks.json - store_artifacts: path: reports/externalTests/diff/ - store_artifacts: diff --git a/scripts/externalTests/download_benchmarks.py b/scripts/externalTests/download_benchmarks.py index 508e801da3df..0f8a6503603d 100755 --- a/scripts/externalTests/download_benchmarks.py +++ b/scripts/externalTests/download_benchmarks.py @@ -34,8 +34,8 @@ def process_commandline() -> Namespace: Downloads benchmark results attached as artifacts to the c_ext_benchmarks job on CircleCI. If no options are specified, downloads results for the currently checked out git branch. - The script will use the CIRCLECI_TOKEN environment as a CircleCI API token if set. - You can generate a new personal token at https://app.circleci.com/settings/user/tokens. + The script requires the CIRCLECI_TOKEN environment variable to be set with a valid CircleCI API token. + You can generate a new token at https://app.circleci.com/settings/user/tokens. """ ) From bf4b5e3ce5db68c37e7a512662de400feaac4fae Mon Sep 17 00:00:00 2001 From: Moritz Hoffmann Date: Mon, 3 Jun 2024 10:51:57 +0200 Subject: [PATCH 0243/1022] Fix changelog entry for #15149 missing `*` --- Changelog.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Changelog.md b/Changelog.md index 2dca15562774..4361f1fec8f4 100644 --- a/Changelog.md +++ b/Changelog.md @@ -9,7 +9,7 @@ Compiler Features: Bugfixes: -Yul Optimizer: Name simplification could lead to forbidden identifiers with a leading and/or trailing dot, e.g., ``x._`` would get simplified into ``x.``. + * Yul Optimizer: Name simplification could lead to forbidden identifiers with a leading and/or trailing dot, e.g., ``x._`` would get simplified into ``x.``. ### 0.8.26 (2024-05-21) From 52223ff5bd4cd7e21c59705cb6f90bfa98ec4960 Mon Sep 17 00:00:00 2001 From: Nikola Matic Date: Fri, 24 May 2024 11:25:56 +0200 Subject: [PATCH 0244/1022] Fix segfault in nested tuple to tuple assignments --- Changelog.md | 1 + libsolidity/analysis/StaticAnalyzer.cpp | 114 +++++++++++++++++- libsolidity/analysis/StaticAnalyzer.h | 5 + libsolidity/analysis/TypeChecker.cpp | 101 ---------------- libsolidity/analysis/TypeChecker.h | 3 - .../nested_tuple_to_tuple_assignment.sol | 37 ++++++ 6 files changed, 156 insertions(+), 105 deletions(-) create mode 100644 test/libsolidity/syntaxTests/tupleAssignments/nested_tuple_to_tuple_assignment.sol diff --git a/Changelog.md b/Changelog.md index 4361f1fec8f4..2101f1ec9b19 100644 --- a/Changelog.md +++ b/Changelog.md @@ -9,6 +9,7 @@ Compiler Features: Bugfixes: + * TypeChecker: Fix segfault when assigning nested tuple to tuple. * Yul Optimizer: Name simplification could lead to forbidden identifiers with a leading and/or trailing dot, e.g., ``x._`` would get simplified into ``x.``. diff --git a/libsolidity/analysis/StaticAnalyzer.cpp b/libsolidity/analysis/StaticAnalyzer.cpp index 563295e23c00..dfd262c8deae 100644 --- a/libsolidity/analysis/StaticAnalyzer.cpp +++ b/libsolidity/analysis/StaticAnalyzer.cpp @@ -22,10 +22,13 @@ */ #include - #include #include +#include #include + +#include + #include using namespace solidity; @@ -88,6 +91,18 @@ bool StaticAnalyzer::analyze(SourceUnit const& _sourceUnit) return !Error::containsErrors(m_errorReporter.errors()); } +bool StaticAnalyzer::visit(Assignment const& _assignment) +{ + Type const* lhsType = _assignment.leftHandSide().annotation().type; + Type const* rhsType = _assignment.rightHandSide().annotation().type; + solAssert(lhsType && rhsType, "Both left and right hand side expressions in an assignment must have a type."); + + if (dynamic_cast(lhsType) && dynamic_cast(rhsType)) + checkDoubleStorageAssignment(_assignment); + + return true; +} + bool StaticAnalyzer::visit(ContractDefinition const& _contract) { m_library = _contract.isLibrary(); @@ -348,3 +363,100 @@ bool StaticAnalyzer::visit(FunctionCall const& _functionCall) } return true; } + +void StaticAnalyzer::checkDoubleStorageAssignment(Assignment const& _assignment) +{ + size_t storageToStorageCopies = 0; + size_t toStorageCopies = 0; + size_t storageByteArrayPushes = 0; + size_t storageByteAccesses = 0; + auto count = [&](TupleExpression const& _lhs, TupleType const& _rhs, auto _recurse) -> void { + TupleType const& lhsType = dynamic_cast(*type(_lhs)); + TupleExpression const* lhsResolved = dynamic_cast(resolveOuterUnaryTuples(&_lhs)); + + solAssert(lhsResolved && lhsResolved->components().size() == lhsType.components().size()); + if (lhsType.components().size() != _rhs.components().size()) + { + solAssert(m_errorReporter.hasErrors(), ""); + return; + } + + for (auto&& [index, componentType]: lhsType.components() | ranges::views::enumerate) + { + if (ReferenceType const* ref = dynamic_cast(componentType)) + { + if (ref->dataStoredIn(DataLocation::Storage) && !ref->isPointer()) + { + toStorageCopies++; + if (_rhs.components()[index]->dataStoredIn(DataLocation::Storage)) + storageToStorageCopies++; + } + } + else if (FixedBytesType const* bytesType = dynamic_cast(componentType)) + { + if (bytesType->numBytes() == 1) + { + if (FunctionCall const* lhsCall = dynamic_cast(resolveOuterUnaryTuples(lhsResolved->components().at(index).get()))) + { + FunctionType const& callType = dynamic_cast(*type(lhsCall->expression())); + if (callType.kind() == FunctionType::Kind::ArrayPush) + { + ArrayType const& arrayType = dynamic_cast(*callType.selfType()); + if (arrayType.isByteArray() && arrayType.dataStoredIn(DataLocation::Storage)) + { + ++storageByteAccesses; + ++storageByteArrayPushes; + } + } + } + else if (IndexAccess const* indexAccess = dynamic_cast(resolveOuterUnaryTuples(lhsResolved->components().at(index).get()))) + { + if (ArrayType const* arrayType = dynamic_cast(type(indexAccess->baseExpression()))) + if (arrayType->isByteArray() && arrayType->dataStoredIn(DataLocation::Storage)) + ++storageByteAccesses; + } + } + } + else if (dynamic_cast(componentType)) + if (auto const* lhsNested = dynamic_cast(lhsResolved->components().at(index).get())) + if (auto const* rhsNestedType = dynamic_cast(_rhs.components().at(index))) + _recurse( + *lhsNested, + *rhsNestedType, + _recurse + ); + } + }; + + TupleExpression const* lhsTupleExpression = dynamic_cast(&_assignment.leftHandSide()); + if (!lhsTupleExpression) + { + solAssert(m_errorReporter.hasErrors()); + return; + } + count( + *lhsTupleExpression, + dynamic_cast(*type(_assignment.rightHandSide())), + count + ); + + if (storageToStorageCopies >= 1 && toStorageCopies >= 2) + m_errorReporter.warning( + 7238_error, + _assignment.location(), + "This assignment performs two copies to storage. Since storage copies do not first " + "copy to a temporary location, one of them might be overwritten before the second " + "is executed and thus may have unexpected effects. It is safer to perform the copies " + "separately or assign to storage pointers first." + ); + + if (storageByteArrayPushes >= 1 && storageByteAccesses >= 2) + m_errorReporter.warning( + 7239_error, + _assignment.location(), + "This assignment involves multiple accesses to a bytes array in storage while simultaneously enlarging it. " + "When a bytes array is enlarged, it may transition from short storage layout to long storage layout, " + "which invalidates all references to its elements. It is safer to only enlarge byte arrays in a single " + "operation, one element at a time." + ); +} diff --git a/libsolidity/analysis/StaticAnalyzer.h b/libsolidity/analysis/StaticAnalyzer.h index dc6263d7e583..909af2b02ade 100644 --- a/libsolidity/analysis/StaticAnalyzer.h +++ b/libsolidity/analysis/StaticAnalyzer.h @@ -65,6 +65,7 @@ class StaticAnalyzer: private ASTConstVisitor bool visit(FunctionDefinition const& _function) override; void endVisit(FunctionDefinition const& _function) override; + bool visit(Assignment const& _assignment) override; bool visit(ExpressionStatement const& _statement) override; bool visit(VariableDeclaration const& _variable) override; bool visit(Identifier const& _identifier) override; @@ -74,6 +75,10 @@ class StaticAnalyzer: private ASTConstVisitor bool visit(BinaryOperation const& _operation) override; bool visit(FunctionCall const& _functionCall) override; + /// Checks (and warns) if a tuple assignment might cause unexpected overwrites in storage. + /// Should only be called if the left hand side is tuple-typed. + void checkDoubleStorageAssignment(Assignment const& _assignment); + langutil::ErrorReporter& m_errorReporter; /// Flag that indicates whether the current contract definition is a library. diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp index 5044414bff6d..918e27033329 100644 --- a/libsolidity/analysis/TypeChecker.cpp +++ b/libsolidity/analysis/TypeChecker.cpp @@ -94,103 +94,6 @@ bool TypeChecker::visit(ContractDefinition const& _contract) return false; } -void TypeChecker::checkDoubleStorageAssignment(Assignment const& _assignment) -{ - size_t storageToStorageCopies = 0; - size_t toStorageCopies = 0; - size_t storageByteArrayPushes = 0; - size_t storageByteAccesses = 0; - auto count = [&](TupleExpression const& _lhs, TupleType const& _rhs, auto _recurse) -> void { - TupleType const& lhsType = dynamic_cast(*type(_lhs)); - TupleExpression const* lhsResolved = dynamic_cast(resolveOuterUnaryTuples(&_lhs)); - - solAssert(!lhsResolved || lhsResolved->components().size() == lhsType.components().size()); - if (lhsType.components().size() != _rhs.components().size()) - { - solAssert(m_errorReporter.hasErrors(), ""); - return; - } - - for (auto&& [index, componentType]: lhsType.components() | ranges::views::enumerate) - { - if (ReferenceType const* ref = dynamic_cast(componentType)) - { - if (ref && ref->dataStoredIn(DataLocation::Storage) && !ref->isPointer()) - { - toStorageCopies++; - if (_rhs.components()[index]->dataStoredIn(DataLocation::Storage)) - storageToStorageCopies++; - } - } - else if (FixedBytesType const* bytesType = dynamic_cast(componentType)) - { - if (bytesType && bytesType->numBytes() == 1) - { - if (FunctionCall const* lhsCall = dynamic_cast(resolveOuterUnaryTuples(lhsResolved->components().at(index).get()))) - { - FunctionType const& callType = dynamic_cast(*type(lhsCall->expression())); - if (callType.kind() == FunctionType::Kind::ArrayPush) - { - ArrayType const& arrayType = dynamic_cast(*callType.selfType()); - if (arrayType.isByteArray() && arrayType.dataStoredIn(DataLocation::Storage)) - { - ++storageByteAccesses; - ++storageByteArrayPushes; - } - } - } - else if (IndexAccess const* indexAccess = dynamic_cast(resolveOuterUnaryTuples(lhsResolved->components().at(index).get()))) - { - if (ArrayType const* arrayType = dynamic_cast(type(indexAccess->baseExpression()))) - if (arrayType->isByteArray() && arrayType->dataStoredIn(DataLocation::Storage)) - ++storageByteAccesses; - } - } - } - else if (TupleType const* tupleType = dynamic_cast(componentType)) - if (auto const* lhsNested = dynamic_cast(lhsResolved->components().at(index).get())) - if (auto const* rhsNestedType = dynamic_cast(_rhs.components().at(index))) - _recurse( - *lhsNested, - *rhsNestedType, - _recurse - ); - } - }; - - TupleExpression const* lhsTupleExpression = dynamic_cast(&_assignment.leftHandSide()); - if (!lhsTupleExpression) - { - solAssert(m_errorReporter.hasErrors()); - return; - } - count( - *lhsTupleExpression, - dynamic_cast(*type(_assignment.rightHandSide())), - count - ); - - if (storageToStorageCopies >= 1 && toStorageCopies >= 2) - m_errorReporter.warning( - 7238_error, - _assignment.location(), - "This assignment performs two copies to storage. Since storage copies do not first " - "copy to a temporary location, one of them might be overwritten before the second " - "is executed and thus may have unexpected effects. It is safer to perform the copies " - "separately or assign to storage pointers first." - ); - - if (storageByteArrayPushes >= 1 && storageByteAccesses >= 2) - m_errorReporter.warning( - 7239_error, - _assignment.location(), - "This assignment involves multiple accesses to a bytes array in storage while simultaneously enlarging it. " - "When a bytes array is enlarged, it may transition from short storage layout to long storage layout, " - "which invalidates all references to its elements. It is safer to only enlarge byte arrays in a single " - "operation, one element at a time." - ); -} - TypePointers TypeChecker::typeCheckABIDecodeAndRetrieveReturnType(FunctionCall const& _functionCall, bool _abiEncoderV2) { std::vector> arguments = _functionCall.arguments(); @@ -1575,10 +1478,6 @@ bool TypeChecker::visit(Assignment const& _assignment) _assignment.annotation().type = TypeProvider::emptyTuple(); expectType(_assignment.rightHandSide(), *tupleType); - - // expectType does not cause fatal errors, so we have to check again here. - if (dynamic_cast(type(_assignment.rightHandSide()))) - checkDoubleStorageAssignment(_assignment); } else if (_assignment.assignmentOperator() == Token::Assign) expectType(_assignment.rightHandSide(), *t); diff --git a/libsolidity/analysis/TypeChecker.h b/libsolidity/analysis/TypeChecker.h index d7998d1784c6..b3bd8b91fb09 100644 --- a/libsolidity/analysis/TypeChecker.h +++ b/libsolidity/analysis/TypeChecker.h @@ -61,9 +61,6 @@ class TypeChecker: private ASTConstVisitor private: bool visit(ContractDefinition const& _contract) override; - /// Checks (and warns) if a tuple assignment might cause unexpected overwrites in storage. - /// Should only be called if the left hand side is tuple-typed. - void checkDoubleStorageAssignment(Assignment const& _assignment); // Checks whether the expression @arg _expression can be assigned from type @arg _type // and reports an error, if not. void checkExpressionAssignment(Type const& _type, Expression const& _expression); diff --git a/test/libsolidity/syntaxTests/tupleAssignments/nested_tuple_to_tuple_assignment.sol b/test/libsolidity/syntaxTests/tupleAssignments/nested_tuple_to_tuple_assignment.sol new file mode 100644 index 000000000000..87ebfbd00190 --- /dev/null +++ b/test/libsolidity/syntaxTests/tupleAssignments/nested_tuple_to_tuple_assignment.sol @@ -0,0 +1,37 @@ +contract C { + bool x; + + function foo() external { + (((),x)&x) = ((), true); + (((),x)+x) = ((), true); + (((),x)-x) = ((), true); + (((),x)/x) = ((), true); + (((),x)*x) = ((), true); + (((),x)|x) = ((), true); + } +} +// ---- +// TypeError 6473: (66-68): Tuple component cannot be empty. +// TypeError 2271: (65-73): Built-in binary operator & cannot be applied to types tuple(tuple(),bool) and bool. +// TypeError 4247: (65-73): Expression has to be an lvalue. +// TypeError 6473: (78-80): Tuple component cannot be empty. +// TypeError 6473: (99-101): Tuple component cannot be empty. +// TypeError 2271: (98-106): Built-in binary operator + cannot be applied to types tuple(tuple(),bool) and bool. +// TypeError 4247: (98-106): Expression has to be an lvalue. +// TypeError 6473: (111-113): Tuple component cannot be empty. +// TypeError 6473: (132-134): Tuple component cannot be empty. +// TypeError 2271: (131-139): Built-in binary operator - cannot be applied to types tuple(tuple(),bool) and bool. +// TypeError 4247: (131-139): Expression has to be an lvalue. +// TypeError 6473: (144-146): Tuple component cannot be empty. +// TypeError 6473: (165-167): Tuple component cannot be empty. +// TypeError 2271: (164-172): Built-in binary operator / cannot be applied to types tuple(tuple(),bool) and bool. +// TypeError 4247: (164-172): Expression has to be an lvalue. +// TypeError 6473: (177-179): Tuple component cannot be empty. +// TypeError 6473: (198-200): Tuple component cannot be empty. +// TypeError 2271: (197-205): Built-in binary operator * cannot be applied to types tuple(tuple(),bool) and bool. +// TypeError 4247: (197-205): Expression has to be an lvalue. +// TypeError 6473: (210-212): Tuple component cannot be empty. +// TypeError 6473: (231-233): Tuple component cannot be empty. +// TypeError 2271: (230-238): Built-in binary operator | cannot be applied to types tuple(tuple(),bool) and bool. +// TypeError 4247: (230-238): Expression has to be an lvalue. +// TypeError 6473: (243-245): Tuple component cannot be empty. From 03ecb0f6c0ef20b862b1a1a16e2d144d69c902ab Mon Sep 17 00:00:00 2001 From: Tilak Madichetti Date: Mon, 3 Jun 2024 22:18:13 +0530 Subject: [PATCH 0245/1022] Update 080-breaking-changes.rst --- docs/080-breaking-changes.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/080-breaking-changes.rst b/docs/080-breaking-changes.rst index 524d12ac3b58..9d1f3347b6b2 100644 --- a/docs/080-breaking-changes.rst +++ b/docs/080-breaking-changes.rst @@ -155,7 +155,7 @@ Interface Changes ``storage-layout`` are sub-objects now. Before 0.8.0 they used to be serialised as strings. * The "legacy AST" has been removed (``--ast-json`` on the commandline interface and ``legacyAST`` for standard JSON). - Use the "compact AST" (``--ast-compact--json`` resp. ``AST``) as replacement. + Use the "compact AST" (``--ast-compact-json`` resp. ``AST``) as replacement. * The old error reporter (``--old-reporter``) has been removed. From baddb2193c3716fed09c0edb34a4d289ccd05fb6 Mon Sep 17 00:00:00 2001 From: Daniel Kirchner Date: Wed, 5 Jun 2024 12:23:40 +0200 Subject: [PATCH 0246/1022] Fix default EVM version in CI. --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index c58d01e32935..5826067dddc0 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -30,7 +30,7 @@ parameters: default: "solbuildpackpusher/solidity-buildpack-deps@sha256:c57f2bfb8c15d70fe290629358dd1c73dc126e3760f443b54764797556b887d4" evm-version: type: string - default: london + default: cancun orbs: win: circleci/windows@2.2.0 From 9e49b2c5336d93c20d86ade193cdafa6c446db47 Mon Sep 17 00:00:00 2001 From: snoppy Date: Thu, 6 Jun 2024 15:22:13 +0800 Subject: [PATCH 0247/1022] chore: fix typos Signed-off-by: snoppy --- libsolidity/formal/BMC.cpp | 2 +- libsolutil/CommonData.h | 2 +- libyul/AsmParser.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/libsolidity/formal/BMC.cpp b/libsolidity/formal/BMC.cpp index 2bb794cde40f..e7cf35a7f4d6 100644 --- a/libsolidity/formal/BMC.cpp +++ b/libsolidity/formal/BMC.cpp @@ -376,7 +376,7 @@ bool BMC::visit(WhileStatement const& _node) auto indices = copyVariableIndices(); _node.condition().accept(*this); loopCondition = expr(_node.condition()); - // asseert that the loop is complete + // assert that the loop is complete m_context.addAssertion(!loopCondition || broke || !loopConditionOnPreviousIterations); mergeVariables( broke || !loopConditionOnPreviousIterations, diff --git a/libsolutil/CommonData.h b/libsolutil/CommonData.h index de6873845dea..c52434451b81 100644 --- a/libsolutil/CommonData.h +++ b/libsolutil/CommonData.h @@ -575,7 +575,7 @@ void iterateReplacingWindow(std::vector& _vector, F const& _f) detail::iterateReplacingWindow(_vector, _f, std::make_index_sequence{}); } -/// @returns true iff @a _str passess the hex address checksum test. +/// @returns true iff @a _str passes the hex address checksum test. /// @param _strict if false, hex strings with only uppercase or only lowercase letters /// are considered valid. bool passesAddressChecksum(std::string const& _str, bool _strict); diff --git a/libyul/AsmParser.h b/libyul/AsmParser.h index 3e0af66acc10..dd91e436e234 100644 --- a/libyul/AsmParser.h +++ b/libyul/AsmParser.h @@ -140,7 +140,7 @@ class Parser: public langutil::ParserBase /// Parses a functional expression that has to push exactly one stack element Expression parseExpression(); /// Parses an elementary operation, i.e. a literal, identifier, instruction or - /// builtin functian call (only the name). + /// builtin function call (only the name). std::variant parseLiteralOrIdentifier(); VariableDeclaration parseVariableDeclaration(); FunctionDefinition parseFunctionDefinition(); From c1edf1983b152807f98f374207f8cbc5b89844fc Mon Sep 17 00:00:00 2001 From: r0qs Date: Tue, 14 May 2024 18:41:56 +0200 Subject: [PATCH 0248/1022] Split docker run command in Dockerfile.emscripten --- scripts/docker/buildpack-deps/Dockerfile.emscripten | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/scripts/docker/buildpack-deps/Dockerfile.emscripten b/scripts/docker/buildpack-deps/Dockerfile.emscripten index 961901f00b70..46bf734b6154 100644 --- a/scripts/docker/buildpack-deps/Dockerfile.emscripten +++ b/scripts/docker/buildpack-deps/Dockerfile.emscripten @@ -44,8 +44,10 @@ RUN set -ex && \ python3 \ python3-pip \ sudo && \ - pip3 install requests && \ - \ + pip3 install requests; + +# Install Z3 +RUN set -ex && \ cd /usr/src && \ git clone https://github.com/Z3Prover/z3.git -b z3-4.12.1 --depth 1 && \ cd z3 && \ @@ -63,9 +65,11 @@ RUN set -ex && \ .. && \ make && \ make install && \ - rm -r /usr/src/z3 && \ + rm -r /usr/src/z3 + +# Install Boost +RUN set -ex && \ cd /usr/src && \ - \ wget -q 'https://boostorg.jfrog.io/artifactory/main/release/1.75.0/source/boost_1_75_0.tar.bz2' -O boost.tar.bz2 && \ test "$(sha256sum boost.tar.bz2)" = "953db31e016db7bb207f11432bef7df100516eeb746843fa0486a222e3fd49cb boost.tar.bz2" && \ tar -xf boost.tar.bz2 && \ From e2da441352b5a28acbb8a531452d9c45ac48d104 Mon Sep 17 00:00:00 2001 From: r0qs Date: Tue, 14 May 2024 18:42:46 +0200 Subject: [PATCH 0249/1022] Upgrade to cvc5 in buildpack-deps --- .../buildpack-deps/Dockerfile.emscripten | 11 ++++++++++ .../Dockerfile.ubuntu.clang.ossfuzz | 11 ++++++++++ .../buildpack-deps/Dockerfile.ubuntu2004 | 20 ++++++++++++++++--- .../buildpack-deps/Dockerfile.ubuntu2204 | 16 ++++++++++++--- .../Dockerfile.ubuntu2204.clang | 11 ++++++++++ 5 files changed, 63 insertions(+), 6 deletions(-) diff --git a/scripts/docker/buildpack-deps/Dockerfile.emscripten b/scripts/docker/buildpack-deps/Dockerfile.emscripten index 46bf734b6154..d2726f9a9872 100644 --- a/scripts/docker/buildpack-deps/Dockerfile.emscripten +++ b/scripts/docker/buildpack-deps/Dockerfile.emscripten @@ -83,3 +83,14 @@ RUN set -ex && \ cxxflags="-s DISABLE_EXCEPTION_CATCHING=0 -Wno-unused-local-typedef -Wno-variadic-macros -Wno-c99-extensions -Wno-all" \ --prefix=$(em-config CACHE)/sysroot/usr install && \ rm -r /usr/src/boost_1_75_0 + +# CVC5 +RUN set -ex; \ + cvc5_version="1.1.2"; \ + wget "https://github.com/cvc5/cvc5/releases/download/cvc5-${cvc5_version}/cvc5-Linux-static.zip" -O /opt/cvc5.zip; \ + test "$(sha256sum /opt/cvc5.zip)" = "cf291aef67da8eaa8d425a51f67f3f72f36db8b1040655dc799b64e3d69e6086 /opt/cvc5.zip"; \ + unzip /opt/cvc5.zip -x "cvc5-Linux-static/lib/cmake/*" -d /opt; \ + mv /opt/cvc5-Linux-static/bin/* /usr/bin; \ + mv /opt/cvc5-Linux-static/include/* /usr/include; \ + mv /opt/cvc5-Linux-static/lib/* /usr/lib; \ + rm -rf /opt/cvc5-Linux-static /opt/cvc5.zip; diff --git a/scripts/docker/buildpack-deps/Dockerfile.ubuntu.clang.ossfuzz b/scripts/docker/buildpack-deps/Dockerfile.ubuntu.clang.ossfuzz index f8a4c73ce9b1..02cb05be5e01 100644 --- a/scripts/docker/buildpack-deps/Dockerfile.ubuntu.clang.ossfuzz +++ b/scripts/docker/buildpack-deps/Dockerfile.ubuntu.clang.ossfuzz @@ -109,6 +109,17 @@ RUN set -ex; \ unzip /opt/eld_binaries.zip -d /opt; \ rm -f /opt/eld_binaries.zip; +# CVC5 +RUN set -ex; \ + cvc5_version="1.1.2"; \ + wget "https://github.com/cvc5/cvc5/releases/download/cvc5-${cvc5_version}/cvc5-Linux-static.zip" -O /opt/cvc5.zip; \ + test "$(sha256sum /opt/cvc5.zip)" = "cf291aef67da8eaa8d425a51f67f3f72f36db8b1040655dc799b64e3d69e6086 /opt/cvc5.zip"; \ + unzip /opt/cvc5.zip -x "cvc5-Linux-static/lib/cmake/*" -d /opt; \ + mv /opt/cvc5-Linux-static/bin/* /usr/bin; \ + mv /opt/cvc5-Linux-static/include/* /usr/include; \ + mv /opt/cvc5-Linux-static/lib/* /usr/lib; \ + rm -rf /opt/cvc5-Linux-static /opt/cvc5.zip; + # OSSFUZZ: libprotobuf-mutator RUN set -ex; \ git clone https://github.com/google/libprotobuf-mutator.git \ diff --git a/scripts/docker/buildpack-deps/Dockerfile.ubuntu2004 b/scripts/docker/buildpack-deps/Dockerfile.ubuntu2004 index 815c93ee84b5..9f331e1b8b83 100644 --- a/scripts/docker/buildpack-deps/Dockerfile.ubuntu2004 +++ b/scripts/docker/buildpack-deps/Dockerfile.ubuntu2004 @@ -39,7 +39,6 @@ RUN set -ex; \ libboost-program-options-dev \ libboost-system-dev \ libboost-test-dev \ - libcvc4-dev \ libz3-static-dev \ lsof \ ninja-build \ @@ -47,6 +46,7 @@ RUN set -ex; \ python3-sphinx \ software-properties-common \ sudo \ + unzip \ z3-static; \ pip3 install \ codecov \ @@ -59,18 +59,32 @@ RUN set -ex; \ tabulate \ z3-solver; +# TODO: we could eliminate duplication by using a Dockerfile extension like: +# https://github.com/edrevo/dockerfile-plus?tab=readme-ov-file#dockerfile +# or mult-stage builds, then we could define a base image which would be included/used by all the other Dockerfiles. +# Or we could move the common parts to a shell script, copying and calling it from the Dockerfiles. # Eldarica RUN set -ex; \ apt-get update; \ apt-get install -qqy \ - openjdk-11-jre \ - unzip; \ + openjdk-11-jre; \ eldarica_version="2.1"; \ wget "https://github.com/uuverifiers/eldarica/releases/download/v${eldarica_version}/eldarica-bin-${eldarica_version}.zip" -O /opt/eld_binaries.zip; \ test "$(sha256sum /opt/eld_binaries.zip)" = "0ac43f45c0925383c9d2077f62bbb515fd792375f3b2b101b30c9e81dcd7785c /opt/eld_binaries.zip"; \ unzip /opt/eld_binaries.zip -d /opt; \ rm -f /opt/eld_binaries.zip; +# CVC5 +RUN set -ex; \ + cvc5_version="1.1.2"; \ + wget "https://github.com/cvc5/cvc5/releases/download/cvc5-${cvc5_version}/cvc5-Linux-static.zip" -O /opt/cvc5.zip; \ + test "$(sha256sum /opt/cvc5.zip)" = "cf291aef67da8eaa8d425a51f67f3f72f36db8b1040655dc799b64e3d69e6086 /opt/cvc5.zip"; \ + unzip /opt/cvc5.zip -x "cvc5-Linux-static/lib/cmake/*" -d /opt; \ + mv /opt/cvc5-Linux-static/bin/* /usr/bin; \ + mv /opt/cvc5-Linux-static/include/* /usr/include; \ + mv /opt/cvc5-Linux-static/lib/* /usr/lib; \ + rm -rf /opt/cvc5-Linux-static /opt/cvc5.zip; + FROM base AS libraries # EVMONE diff --git a/scripts/docker/buildpack-deps/Dockerfile.ubuntu2204 b/scripts/docker/buildpack-deps/Dockerfile.ubuntu2204 index 254e83b4cfc7..6bc1df143907 100644 --- a/scripts/docker/buildpack-deps/Dockerfile.ubuntu2204 +++ b/scripts/docker/buildpack-deps/Dockerfile.ubuntu2204 @@ -40,7 +40,6 @@ RUN set -ex; \ libboost-system-dev \ libboost-test-dev \ libcln-dev \ - libcvc4-dev \ libz3-static-dev \ locales-all \ lsof \ @@ -49,6 +48,7 @@ RUN set -ex; \ python3-sphinx \ software-properties-common \ sudo \ + unzip \ z3-static \ zip; \ pip3 install \ @@ -66,14 +66,24 @@ RUN set -ex; \ RUN set -ex; \ apt-get update; \ apt-get install -qqy \ - openjdk-11-jre \ - unzip; \ + openjdk-11-jre; \ eldarica_version="2.1"; \ wget "https://github.com/uuverifiers/eldarica/releases/download/v${eldarica_version}/eldarica-bin-${eldarica_version}.zip" -O /opt/eld_binaries.zip; \ test "$(sha256sum /opt/eld_binaries.zip)" = "0ac43f45c0925383c9d2077f62bbb515fd792375f3b2b101b30c9e81dcd7785c /opt/eld_binaries.zip"; \ unzip /opt/eld_binaries.zip -d /opt; \ rm -f /opt/eld_binaries.zip; +# CVC5 +RUN set -ex; \ + cvc5_version="1.1.2"; \ + wget "https://github.com/cvc5/cvc5/releases/download/cvc5-${cvc5_version}/cvc5-Linux-static.zip" -O /opt/cvc5.zip; \ + test "$(sha256sum /opt/cvc5.zip)" = "cf291aef67da8eaa8d425a51f67f3f72f36db8b1040655dc799b64e3d69e6086 /opt/cvc5.zip"; \ + unzip /opt/cvc5.zip -x "cvc5-Linux-static/lib/cmake/*" -d /opt; \ + mv /opt/cvc5-Linux-static/bin/* /usr/bin; \ + mv /opt/cvc5-Linux-static/include/* /usr/include; \ + mv /opt/cvc5-Linux-static/lib/* /usr/lib; \ + rm -rf /opt/cvc5-Linux-static /opt/cvc5.zip; + FROM base AS libraries # EVMONE diff --git a/scripts/docker/buildpack-deps/Dockerfile.ubuntu2204.clang b/scripts/docker/buildpack-deps/Dockerfile.ubuntu2204.clang index af6155b6e0a0..de9ce4efb683 100644 --- a/scripts/docker/buildpack-deps/Dockerfile.ubuntu2204.clang +++ b/scripts/docker/buildpack-deps/Dockerfile.ubuntu2204.clang @@ -71,6 +71,17 @@ RUN set -ex; \ unzip /opt/eld_binaries.zip -d /opt; \ rm -f /opt/eld_binaries.zip; +# CVC5 +RUN set -ex; \ + cvc5_version="1.1.2"; \ + wget "https://github.com/cvc5/cvc5/releases/download/cvc5-${cvc5_version}/cvc5-Linux-static.zip" -O /opt/cvc5.zip; \ + test "$(sha256sum /opt/cvc5.zip)" = "cf291aef67da8eaa8d425a51f67f3f72f36db8b1040655dc799b64e3d69e6086 /opt/cvc5.zip"; \ + unzip /opt/cvc5.zip -x "cvc5-Linux-static/lib/cmake/*" -d /opt; \ + mv /opt/cvc5-Linux-static/bin/* /usr/bin; \ + mv /opt/cvc5-Linux-static/lib/* /usr/lib; \ + mv /opt/cvc5-Linux-static/include/* /usr/include; \ + rm -rf /opt/cvc5-Linux-static /opt/cvc5.zip; + FROM base AS libraries ENV CC clang From 3127bbccd66e701498b3066ff301a957aee0a250 Mon Sep 17 00:00:00 2001 From: r0qs Date: Thu, 16 May 2024 16:44:42 +0200 Subject: [PATCH 0250/1022] Bump docker image versions --- scripts/docker/buildpack-deps/Dockerfile.emscripten | 2 +- scripts/docker/buildpack-deps/Dockerfile.ubuntu.clang.ossfuzz | 2 +- scripts/docker/buildpack-deps/Dockerfile.ubuntu2004 | 2 +- scripts/docker/buildpack-deps/Dockerfile.ubuntu2204 | 2 +- scripts/docker/buildpack-deps/Dockerfile.ubuntu2204.clang | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/scripts/docker/buildpack-deps/Dockerfile.emscripten b/scripts/docker/buildpack-deps/Dockerfile.emscripten index d2726f9a9872..478d8d947cf5 100644 --- a/scripts/docker/buildpack-deps/Dockerfile.emscripten +++ b/scripts/docker/buildpack-deps/Dockerfile.emscripten @@ -33,7 +33,7 @@ # Using $(em-config CACHE)/sysroot/usr seems to work, though, and still has cmake find the # dependencies automatically. FROM emscripten/emsdk:3.1.19 AS base -LABEL version="17" +LABEL version="18" ADD emscripten.jam /usr/src RUN set -ex && \ diff --git a/scripts/docker/buildpack-deps/Dockerfile.ubuntu.clang.ossfuzz b/scripts/docker/buildpack-deps/Dockerfile.ubuntu.clang.ossfuzz index 02cb05be5e01..aae11521e50d 100644 --- a/scripts/docker/buildpack-deps/Dockerfile.ubuntu.clang.ossfuzz +++ b/scripts/docker/buildpack-deps/Dockerfile.ubuntu.clang.ossfuzz @@ -22,7 +22,7 @@ # (c) 2016-2021 solidity contributors. #------------------------------------------------------------------------------ FROM gcr.io/oss-fuzz-base/base-clang:latest as base -LABEL version="6" +LABEL version="7" ARG DEBIAN_FRONTEND=noninteractive diff --git a/scripts/docker/buildpack-deps/Dockerfile.ubuntu2004 b/scripts/docker/buildpack-deps/Dockerfile.ubuntu2004 index 9f331e1b8b83..8b94fe9dd918 100644 --- a/scripts/docker/buildpack-deps/Dockerfile.ubuntu2004 +++ b/scripts/docker/buildpack-deps/Dockerfile.ubuntu2004 @@ -22,7 +22,7 @@ # (c) 2016-2019 solidity contributors. #------------------------------------------------------------------------------ FROM buildpack-deps:focal AS base -LABEL version="23" +LABEL version="24" ARG DEBIAN_FRONTEND=noninteractive diff --git a/scripts/docker/buildpack-deps/Dockerfile.ubuntu2204 b/scripts/docker/buildpack-deps/Dockerfile.ubuntu2204 index 6bc1df143907..90d5811c3b3c 100644 --- a/scripts/docker/buildpack-deps/Dockerfile.ubuntu2204 +++ b/scripts/docker/buildpack-deps/Dockerfile.ubuntu2204 @@ -22,7 +22,7 @@ # (c) 2016-2019 solidity contributors. #------------------------------------------------------------------------------ FROM buildpack-deps:jammy AS base -LABEL version="8" +LABEL version="9" ARG DEBIAN_FRONTEND=noninteractive diff --git a/scripts/docker/buildpack-deps/Dockerfile.ubuntu2204.clang b/scripts/docker/buildpack-deps/Dockerfile.ubuntu2204.clang index de9ce4efb683..b2f75b0e43d1 100644 --- a/scripts/docker/buildpack-deps/Dockerfile.ubuntu2204.clang +++ b/scripts/docker/buildpack-deps/Dockerfile.ubuntu2204.clang @@ -22,7 +22,7 @@ # (c) 2016-2019 solidity contributors. #------------------------------------------------------------------------------ FROM buildpack-deps:jammy AS base -LABEL version="7" +LABEL version="8" ARG DEBIAN_FRONTEND=noninteractive From 128b17259c468fbe8a7b1f8219d9d8ab891f43f2 Mon Sep 17 00:00:00 2001 From: r0qs Date: Thu, 16 May 2024 16:46:24 +0200 Subject: [PATCH 0251/1022] Install cvc5 on OSX --- .circleci/osx_install_dependencies.sh | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/.circleci/osx_install_dependencies.sh b/.circleci/osx_install_dependencies.sh index 87383ba8f58b..5436c31fe05f 100755 --- a/.circleci/osx_install_dependencies.sh +++ b/.circleci/osx_install_dependencies.sh @@ -84,6 +84,16 @@ then sudo mv /tmp/eldarica/{eld,eld-client,target,eldEnv} /usr/local/bin rm -rf /tmp/{eldarica,eld_binaries.zip} + #cvc5 + cvc5_version="1.1.2" + wget "https://github.com/cvc5/cvc5/releases/download/cvc5-${cvc5_version}/cvc5-macOS-arm64-static.zip" -O /tmp/cvc5.zip + validate_checksum /tmp/cvc5.zip 2017d683d924676cb713865c6d4fcf70115c65b7ec2848f242ab938902f115b5 + unzip /tmp/cvc5.zip -x "cvc5-macOS-arm64-static/lib/cmake/*" -d /tmp + sudo mv /tmp/cvc5-macOS-arm64-static/bin/* /usr/local/bin + sudo mv /tmp/cvc5-macOS-arm64-static/include/* /usr/local/include + sudo mv /tmp/cvc5-macOS-arm64-static/lib/* /usr/local/lib + rm -rf /tmp/{cvc5-macOS-arm64-static,cvc5.zip} + # z3 z3_version="4.12.1" z3_dir="z3-z3-$z3_version" From b8ba5da12f7a6d7622a535b08e6c93bff9384917 Mon Sep 17 00:00:00 2001 From: Martin Blicha Date: Mon, 6 May 2024 18:58:58 +0200 Subject: [PATCH 0252/1022] SMTChecker: Upgrade CVC4 to cvc5 Instead of compiling `solc` itself with CVC4 support, it is now enough to have `cvc5` executable on PATH when running the compiler. Instead of using API of CVC4, we now use SMT-LIB2 interface. That means we write the queries to temporary SMT-LIB2 files and call the solver process directly to run on the file. --- .circleci/config.yml | 4 +- CMakeLists.txt | 10 +- Changelog.md | 1 + cmake/EthCompilerSettings.cmake | 1 - cmake/FindCVC4.cmake | 33 -- cmake/toolchains/libfuzzer.cmake | 3 +- cmake/toolchains/ossfuzz.cmake | 3 +- docs/installing-solidity.rst | 9 - docs/smtchecker.rst | 6 +- docs/using-the-compiler.rst | 2 +- libsmtutil/CMakeLists.txt | 12 +- libsmtutil/CVC4Interface.cpp | 336 ------------------ libsmtutil/CVC4Interface.h | 74 ---- libsmtutil/SMTLib2Interface.cpp | 6 +- libsmtutil/SMTPortfolio.cpp | 9 +- libsmtutil/SolverInterface.h | 18 +- libsolidity/formal/BMC.cpp | 16 +- libsolidity/formal/ModelChecker.cpp | 14 +- libsolidity/interface/CompilerStack.cpp | 4 + libsolidity/interface/SMTSolverCommand.cpp | 30 +- libsolidity/interface/SMTSolverCommand.h | 1 + solc/CommandLineParser.cpp | 2 +- .../model_checker_print_query_all/err | 2 +- .../model_checker_print_query_bmc/err | 2 +- .../model_checker_solvers_cvc5/args | 1 + .../model_checker_solvers_cvc5/err | 10 + .../model_checker_solvers_cvc5/input.sol | 7 + .../model_checker_solvers_smtlib2/err | 2 +- .../output.json | 4 +- .../output.json | 4 +- .../output.json | 4 +- .../output.json | 4 +- test/libsolidity/SMTCheckerTest.h | 2 +- .../imports/duplicated_errors_1.sol | 4 +- 34 files changed, 99 insertions(+), 541 deletions(-) delete mode 100644 cmake/FindCVC4.cmake delete mode 100644 libsmtutil/CVC4Interface.cpp delete mode 100644 libsmtutil/CVC4Interface.h create mode 100644 test/cmdlineTests/model_checker_solvers_cvc5/args create mode 100644 test/cmdlineTests/model_checker_solvers_cvc5/err create mode 100644 test/cmdlineTests/model_checker_solvers_cvc5/input.sol diff --git a/.circleci/config.yml b/.circleci/config.yml index 5826067dddc0..3e65f4ac16ad 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1044,7 +1044,7 @@ jobs: <<: *base_ubuntu2004_xlarge environment: <<: *base_ubuntu2204_xlarge_env - CMAKE_OPTIONS: -DCMAKE_BUILD_TYPE=Release -DUSE_Z3_DLOPEN=ON -DUSE_CVC4=OFF -DSOLC_STATIC_STDLIBS=ON + CMAKE_OPTIONS: -DCMAKE_BUILD_TYPE=Release -DUSE_Z3_DLOPEN=ON -DSOLC_STATIC_STDLIBS=ON steps: - checkout - run_build @@ -1104,7 +1104,7 @@ jobs: environment: <<: *base_ubuntu2204_large_env CMAKE_BUILD_TYPE: Debug - CMAKE_OPTIONS: -DCMAKE_CXX_STANDARD=20 -DUSE_CVC4=OFF + CMAKE_OPTIONS: -DCMAKE_CXX_STANDARD=20 MAKEFLAGS: -j 10 steps: - checkout diff --git a/CMakeLists.txt b/CMakeLists.txt index b1a307afb9e0..71f83b80ed2d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -133,15 +133,11 @@ elseif (${Z3_FOUND}) message("Z3 SMT solver found. This enables optional SMT checking with Z3.") endif() -find_package(CVC4 QUIET) -if (${CVC4_FOUND}) - add_definitions(-DHAVE_CVC4) - message("CVC4 SMT solver found. This enables optional SMT checking with CVC4.") -endif() +find_program(CVC5_PATH cvc5) -if (NOT (${Z3_FOUND} OR ${CVC4_FOUND})) +if (NOT (${Z3_FOUND} OR CVC5_PATH)) message("No SMT solver found (or it has been forcefully disabled). Optional SMT checking will not be available.\ - \nPlease install Z3 or CVC4 or remove the option disabling them (USE_Z3, USE_CVC4).") + \nPlease install Z3 or cvc5 or remove the option disabling them (USE_Z3).") endif() add_subdirectory(libsolutil) diff --git a/Changelog.md b/Changelog.md index 2101f1ec9b19..1c15478d1935 100644 --- a/Changelog.md +++ b/Changelog.md @@ -6,6 +6,7 @@ Language Features: Compiler Features: * EVM: Support for the EVM version "Prague". * SMTChecker: Add CHC engine check for underflow and overflow in unary minus operation. + * SMTChecker: Replace CVC4 as a possible BMC backend with cvc5. Bugfixes: diff --git a/cmake/EthCompilerSettings.cmake b/cmake/EthCompilerSettings.cmake index 5c2802d1fe20..eda0e404ddd6 100644 --- a/cmake/EthCompilerSettings.cmake +++ b/cmake/EthCompilerSettings.cmake @@ -266,7 +266,6 @@ option(USE_Z3 "Allow compiling with Z3 SMT solver integration" ON) if(UNIX AND NOT APPLE) option(USE_Z3_DLOPEN "Dynamically load the Z3 SMT solver instead of linking against it." OFF) endif() -option(USE_CVC4 "Allow compiling with CVC4 SMT solver integration" ON) if (("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU") OR ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")) option(USE_LD_GOLD "Use GNU gold linker" ON) diff --git a/cmake/FindCVC4.cmake b/cmake/FindCVC4.cmake deleted file mode 100644 index 887b907b8320..000000000000 --- a/cmake/FindCVC4.cmake +++ /dev/null @@ -1,33 +0,0 @@ -if (USE_CVC4) - find_path(CVC4_INCLUDE_DIR cvc4/cvc4.h) - find_library(CVC4_LIBRARY NAMES cvc4) - include(FindPackageHandleStandardArgs) - find_package_handle_standard_args(CVC4 DEFAULT_MSG CVC4_LIBRARY CVC4_INCLUDE_DIR) - if(CVC4_FOUND) - # CVC4 may depend on either CLN or GMP. - # We can assume that the one it requires is present on the system, - # so we quietly try to find both and link against them, if they are - # present. - find_package(CLN QUIET) - find_package(GMP QUIET) - - set(CVC4_LIBRARIES ${CVC4_LIBRARY}) - - if (CLN_FOUND) - set(CVC4_LIBRARIES ${CVC4_LIBRARIES} CLN::CLN) - endif () - - if (GMP_FOUND) - set(CVC4_LIBRARIES ${CVC4_LIBRARIES} GMP::GMP) - endif () - - if (NOT TARGET CVC4::CVC4) - add_library(CVC4::CVC4 UNKNOWN IMPORTED) - set_property(TARGET CVC4::CVC4 PROPERTY IMPORTED_LOCATION ${CVC4_LIBRARY}) - set_property(TARGET CVC4::CVC4 PROPERTY INTERFACE_LINK_LIBRARIES ${CVC4_LIBRARIES}) - set_property(TARGET CVC4::CVC4 PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${CVC4_INCLUDE_DIR}) - endif() - endif() -else() - set(CVC4_FOUND FALSE) -endif() diff --git a/cmake/toolchains/libfuzzer.cmake b/cmake/toolchains/libfuzzer.cmake index a734df975ec4..9d83d504f052 100644 --- a/cmake/toolchains/libfuzzer.cmake +++ b/cmake/toolchains/libfuzzer.cmake @@ -1,8 +1,7 @@ # Inherit default options include("${CMAKE_CURRENT_LIST_DIR}/default.cmake") -# Enable Z3, disable CVC4 +# Enable Z3 set(USE_Z3 ON CACHE BOOL "Enable Z3" FORCE) -set(USE_CVC4 OFF CACHE BOOL "Disable CVC4" FORCE) # Build fuzzing binaries set(OSSFUZZ ON CACHE BOOL "Enable fuzzer build" FORCE) # Use libfuzzer as the fuzzing back-end diff --git a/cmake/toolchains/ossfuzz.cmake b/cmake/toolchains/ossfuzz.cmake index fb7b8d0b36cb..88018db9331d 100644 --- a/cmake/toolchains/ossfuzz.cmake +++ b/cmake/toolchains/ossfuzz.cmake @@ -1,7 +1,6 @@ # Inherit default options include("${CMAKE_CURRENT_LIST_DIR}/default.cmake") -# Disable CVC4 and Z3. -set(USE_CVC4 OFF CACHE BOOL "Disable CVC4" FORCE) +# Disable Z3. set(USE_Z3 OFF CACHE BOOL "Disable Z3" FORCE) # Enable fuzzers set(OSSFUZZ ON CACHE BOOL "Enable fuzzer build" FORCE) diff --git a/docs/installing-solidity.rst b/docs/installing-solidity.rst index f079fb0245a8..e37fc19853f1 100644 --- a/docs/installing-solidity.rst +++ b/docs/installing-solidity.rst @@ -333,10 +333,7 @@ The following are dependencies for all builds of Solidity: +-----------------------------------+-------------------------------------------------------+ | `z3`_ (version 4.8.16+, Optional) | For use with SMT checker. | +-----------------------------------+-------------------------------------------------------+ -| `cvc4`_ (Optional) | For use with SMT checker. | -+-----------------------------------+-------------------------------------------------------+ -.. _cvc4: https://cvc4.cs.stanford.edu/web/ .. _Git: https://git-scm.com/download .. _Boost: https://www.boost.org .. _CMake: https://cmake.org/download/ @@ -543,12 +540,6 @@ Inside the build folder you can disable them, since they are enabled by default: # disables only Z3 SMT Solver. cmake .. -DUSE_Z3=OFF - # disables only CVC4 SMT Solver. - cmake .. -DUSE_CVC4=OFF - - # disables both Z3 and CVC4 - cmake .. -DUSE_CVC4=OFF -DUSE_Z3=OFF - The Version String in Detail ============================ diff --git a/docs/smtchecker.rst b/docs/smtchecker.rst index dfdcf465198b..fc7978256a9d 100644 --- a/docs/smtchecker.rst +++ b/docs/smtchecker.rst @@ -822,10 +822,10 @@ which is primarily an SMT solver and makes `Spacer `_ which does both. The user can choose which solvers should be used, if available, via the CLI -option ``--model-checker-solvers {all,cvc4,eld,smtlib2,z3}`` or the JSON option +option ``--model-checker-solvers {all,cvc5,eld,smtlib2,z3}`` or the JSON option ``settings.modelChecker.solvers=[smtlib2,z3]``, where: -- ``cvc4`` is only available if the ``solc`` binary is compiled with it. Only BMC uses ``cvc4``. +- ``cvc5`` is used via its binary which must be installed in the system. Only BMC uses ``cvc5``. - ``eld`` is used via its binary which must be installed in the system. Only CHC uses ``eld``, and only if ``z3`` is not enabled. - ``smtlib2`` outputs SMT/Horn queries in the `smtlib2 `_ format. These can be used together with the compiler's `callback mechanism `_ so that @@ -849,7 +849,7 @@ concerned about this option. More advanced users might apply this option to try alternative solvers on more complex problems. Please note that certain combinations of chosen engine and solver will lead to -the SMTChecker doing nothing, for example choosing CHC and ``cvc4``. +the SMTChecker doing nothing, for example choosing CHC and ``cvc5``. ******************************* Abstraction and False Positives diff --git a/docs/using-the-compiler.rst b/docs/using-the-compiler.rst index 544f45142383..1eb6631df49f 100644 --- a/docs/using-the-compiler.rst +++ b/docs/using-the-compiler.rst @@ -486,7 +486,7 @@ Input Description "showUnsupported": true, // Choose which solvers should be used, if available. // See the Formal Verification section for the solvers description. - "solvers": ["cvc4", "smtlib2", "z3"], + "solvers": ["cvc5", "smtlib2", "z3"], // Choose which targets should be checked: constantCondition, // underflow, overflow, divByZero, balance, assert, popEmptyArray, outOfBounds. // If the option is not given all targets are checked by default, diff --git a/libsmtutil/CMakeLists.txt b/libsmtutil/CMakeLists.txt index cb222e22c4a1..005fbeb8049e 100644 --- a/libsmtutil/CMakeLists.txt +++ b/libsmtutil/CMakeLists.txt @@ -20,12 +20,6 @@ else() set(z3_SRCS) endif() -if (${CVC4_FOUND}) - set(cvc4_SRCS CVC4Interface.cpp CVC4Interface.h) -else() - set(cvc4_SRCS) -endif() - if (${USE_Z3_DLOPEN}) file(GLOB Z3_HEADERS ${Z3_HEADER_PATH}/z3*.h) set(Z3_WRAPPER ${CMAKE_CURRENT_BINARY_DIR}/z3wrapper.cpp) @@ -38,7 +32,7 @@ if (${USE_Z3_DLOPEN}) set(z3_SRCS ${z3_SRCS} ${Z3_WRAPPER} Z3Loader.cpp Z3Loader.h) endif() -add_library(smtutil ${sources} ${z3_SRCS} ${cvc4_SRCS}) +add_library(smtutil ${sources} ${z3_SRCS}) target_link_libraries(smtutil PUBLIC solutil Boost::boost) if (${USE_Z3_DLOPEN}) @@ -47,7 +41,3 @@ if (${USE_Z3_DLOPEN}) elseif (${Z3_FOUND}) target_link_libraries(smtutil PUBLIC z3::libz3) endif() - -if (${CVC4_FOUND}) - target_link_libraries(smtutil PUBLIC CVC4::CVC4) -endif() diff --git a/libsmtutil/CVC4Interface.cpp b/libsmtutil/CVC4Interface.cpp deleted file mode 100644 index f53c92ab5705..000000000000 --- a/libsmtutil/CVC4Interface.cpp +++ /dev/null @@ -1,336 +0,0 @@ -/* - This file is part of solidity. - - solidity is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - solidity is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with solidity. If not, see . -*/ -// SPDX-License-Identifier: GPL-3.0 - -#include - -#include -#include - -#include - -using namespace solidity; -using namespace solidity::util; -using namespace solidity::smtutil; - -CVC4Interface::CVC4Interface(std::optional _queryTimeout): - SolverInterface(_queryTimeout), - m_solver(&m_context) -{ - reset(); -} - -void CVC4Interface::reset() -{ - m_variables.clear(); - m_solver.reset(); - m_solver.setOption("produce-models", true); - if (m_queryTimeout) - m_solver.setTimeLimit(*m_queryTimeout); - else - m_solver.setResourceLimit(resourceLimit); -} - -void CVC4Interface::push() -{ - m_solver.push(); -} - -void CVC4Interface::pop() -{ - m_solver.pop(); -} - -void CVC4Interface::declareVariable(std::string const& _name, SortPointer const& _sort) -{ - smtAssert(_sort, ""); - m_variables[_name] = m_context.mkVar(_name.c_str(), cvc4Sort(*_sort)); -} - -void CVC4Interface::addAssertion(Expression const& _expr) -{ - try - { - m_solver.assertFormula(toCVC4Expr(_expr)); - } - catch (CVC4::TypeCheckingException const& _e) - { - smtAssert(false, _e.what()); - } - catch (CVC4::LogicException const& _e) - { - smtAssert(false, _e.what()); - } - catch (CVC4::UnsafeInterruptException const& _e) - { - smtAssert(false, _e.what()); - } - catch (CVC4::Exception const& _e) - { - smtAssert(false, _e.what()); - } -} - -std::pair> CVC4Interface::check(std::vector const& _expressionsToEvaluate) -{ - CheckResult result; - std::vector values; - try - { - switch (m_solver.checkSat().isSat()) - { - case CVC4::Result::SAT: - result = CheckResult::SATISFIABLE; - break; - case CVC4::Result::UNSAT: - result = CheckResult::UNSATISFIABLE; - break; - case CVC4::Result::SAT_UNKNOWN: - result = CheckResult::UNKNOWN; - break; - default: - smtAssert(false, ""); - } - - if (result == CheckResult::SATISFIABLE && !_expressionsToEvaluate.empty()) - { - for (Expression const& e: _expressionsToEvaluate) - values.push_back(toString(m_solver.getValue(toCVC4Expr(e)))); - } - } - catch (CVC4::Exception const&) - { - result = CheckResult::ERROR; - values.clear(); - } - - return std::make_pair(result, values); -} - -CVC4::Expr CVC4Interface::toCVC4Expr(Expression const& _expr) -{ - // Variable - if (_expr.arguments.empty() && m_variables.count(_expr.name)) - return m_variables.at(_expr.name); - - std::vector arguments; - for (auto const& arg: _expr.arguments) - arguments.push_back(toCVC4Expr(arg)); - - try - { - std::string const& n = _expr.name; - // Function application - if (!arguments.empty() && m_variables.count(_expr.name)) - return m_context.mkExpr(CVC4::kind::APPLY_UF, m_variables.at(n), arguments); - // Literal - else if (arguments.empty()) - { - if (n == "true") - return m_context.mkConst(true); - else if (n == "false") - return m_context.mkConst(false); - else if (auto sortSort = std::dynamic_pointer_cast(_expr.sort)) - return m_context.mkVar(n, cvc4Sort(*sortSort->inner)); - else - try - { - return m_context.mkConst(CVC4::Rational(n)); - } - catch (CVC4::TypeCheckingException const& _e) - { - smtAssert(false, _e.what()); - } - catch (CVC4::Exception const& _e) - { - smtAssert(false, _e.what()); - } - } - - smtAssert(_expr.hasCorrectArity(), ""); - if (n == "ite") - return arguments[0].iteExpr(arguments[1], arguments[2]); - else if (n == "not") - return arguments[0].notExpr(); - else if (n == "and") - return arguments[0].andExpr(arguments[1]); - else if (n == "or") - return arguments[0].orExpr(arguments[1]); - else if (n == "=>") - return m_context.mkExpr(CVC4::kind::IMPLIES, arguments[0], arguments[1]); - else if (n == "=") - return m_context.mkExpr(CVC4::kind::EQUAL, arguments[0], arguments[1]); - else if (n == "<") - return m_context.mkExpr(CVC4::kind::LT, arguments[0], arguments[1]); - else if (n == "<=") - return m_context.mkExpr(CVC4::kind::LEQ, arguments[0], arguments[1]); - else if (n == ">") - return m_context.mkExpr(CVC4::kind::GT, arguments[0], arguments[1]); - else if (n == ">=") - return m_context.mkExpr(CVC4::kind::GEQ, arguments[0], arguments[1]); - else if (n == "+") - return m_context.mkExpr(CVC4::kind::PLUS, arguments[0], arguments[1]); - else if (n == "-") - return m_context.mkExpr(CVC4::kind::MINUS, arguments[0], arguments[1]); - else if (n == "*") - return m_context.mkExpr(CVC4::kind::MULT, arguments[0], arguments[1]); - else if (n == "div") - return m_context.mkExpr(CVC4::kind::INTS_DIVISION_TOTAL, arguments[0], arguments[1]); - else if (n == "mod") - return m_context.mkExpr(CVC4::kind::INTS_MODULUS, arguments[0], arguments[1]); - else if (n == "bvnot") - return m_context.mkExpr(CVC4::kind::BITVECTOR_NOT, arguments[0]); - else if (n == "bvand") - return m_context.mkExpr(CVC4::kind::BITVECTOR_AND, arguments[0], arguments[1]); - else if (n == "bvor") - return m_context.mkExpr(CVC4::kind::BITVECTOR_OR, arguments[0], arguments[1]); - else if (n == "bvxor") - return m_context.mkExpr(CVC4::kind::BITVECTOR_XOR, arguments[0], arguments[1]); - else if (n == "bvshl") - return m_context.mkExpr(CVC4::kind::BITVECTOR_SHL, arguments[0], arguments[1]); - else if (n == "bvlshr") - return m_context.mkExpr(CVC4::kind::BITVECTOR_LSHR, arguments[0], arguments[1]); - else if (n == "bvashr") - return m_context.mkExpr(CVC4::kind::BITVECTOR_ASHR, arguments[0], arguments[1]); - else if (n == "int2bv") - { - size_t size = std::stoul(_expr.arguments[1].name); - auto i2bvOp = m_context.mkConst(CVC4::IntToBitVector(static_cast(size))); - // CVC4 treats all BVs as unsigned, so we need to manually apply 2's complement if needed. - return m_context.mkExpr( - CVC4::kind::ITE, - m_context.mkExpr(CVC4::kind::GEQ, arguments[0], m_context.mkConst(CVC4::Rational(0))), - m_context.mkExpr(CVC4::kind::INT_TO_BITVECTOR, i2bvOp, arguments[0]), - m_context.mkExpr( - CVC4::kind::BITVECTOR_NEG, - m_context.mkExpr(CVC4::kind::INT_TO_BITVECTOR, i2bvOp, m_context.mkExpr(CVC4::kind::UMINUS, arguments[0])) - ) - ); - } - else if (n == "bv2int") - { - auto intSort = std::dynamic_pointer_cast(_expr.sort); - smtAssert(intSort, ""); - auto nat = m_context.mkExpr(CVC4::kind::BITVECTOR_TO_NAT, arguments[0]); - if (!intSort->isSigned) - return nat; - - auto type = arguments[0].getType(); - smtAssert(type.isBitVector(), ""); - auto size = CVC4::BitVectorType(type).getSize(); - // CVC4 treats all BVs as unsigned, so we need to manually apply 2's complement if needed. - auto extractOp = m_context.mkConst(CVC4::BitVectorExtract(size - 1, size - 1)); - return m_context.mkExpr(CVC4::kind::ITE, - m_context.mkExpr( - CVC4::kind::EQUAL, - m_context.mkExpr(CVC4::kind::BITVECTOR_EXTRACT, extractOp, arguments[0]), - m_context.mkConst(CVC4::BitVector(1, uint64_t{0})) - ), - nat, - m_context.mkExpr( - CVC4::kind::UMINUS, - m_context.mkExpr(CVC4::kind::BITVECTOR_TO_NAT, m_context.mkExpr(CVC4::kind::BITVECTOR_NEG, arguments[0])) - ) - ); - } - else if (n == "select") - return m_context.mkExpr(CVC4::kind::SELECT, arguments[0], arguments[1]); - else if (n == "store") - return m_context.mkExpr(CVC4::kind::STORE, arguments[0], arguments[1], arguments[2]); - else if (n == "const_array") - { - std::shared_ptr sortSort = std::dynamic_pointer_cast(_expr.arguments[0].sort); - smtAssert(sortSort, ""); - return m_context.mkConst(CVC4::ArrayStoreAll(cvc4Sort(*sortSort->inner), arguments[1])); - } - else if (n == "tuple_get") - { - std::shared_ptr tupleSort = std::dynamic_pointer_cast(_expr.arguments[0].sort); - smtAssert(tupleSort, ""); - CVC4::DatatypeType tt = m_context.mkTupleType(cvc4Sort(tupleSort->components)); - CVC4::Datatype const& dt = tt.getDatatype(); - size_t index = std::stoul(_expr.arguments[1].name); - CVC4::Expr s = dt[0][index].getSelector(); - return m_context.mkExpr(CVC4::kind::APPLY_SELECTOR, s, arguments[0]); - } - else if (n == "tuple_constructor") - { - std::shared_ptr tupleSort = std::dynamic_pointer_cast(_expr.sort); - smtAssert(tupleSort, ""); - CVC4::DatatypeType tt = m_context.mkTupleType(cvc4Sort(tupleSort->components)); - CVC4::Datatype const& dt = tt.getDatatype(); - CVC4::Expr c = dt[0].getConstructor(); - return m_context.mkExpr(CVC4::kind::APPLY_CONSTRUCTOR, c, arguments); - } - - smtAssert(false); - } - catch (CVC4::TypeCheckingException const& _e) - { - smtAssert(false, _e.what()); - } - catch (CVC4::Exception const& _e) - { - smtAssert(false, _e.what()); - } - - smtAssert(false); - - // FIXME: Workaround for spurious GCC 12.1 warning (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105794) - util::unreachable(); -} - -CVC4::Type CVC4Interface::cvc4Sort(Sort const& _sort) -{ - switch (_sort.kind) - { - case Kind::Bool: - return m_context.booleanType(); - case Kind::Int: - return m_context.integerType(); - case Kind::BitVector: - return m_context.mkBitVectorType(dynamic_cast(_sort).size); - case Kind::Function: - { - FunctionSort const& fSort = dynamic_cast(_sort); - return m_context.mkFunctionType(cvc4Sort(fSort.domain), cvc4Sort(*fSort.codomain)); - } - case Kind::Array: - { - auto const& arraySort = dynamic_cast(_sort); - return m_context.mkArrayType(cvc4Sort(*arraySort.domain), cvc4Sort(*arraySort.range)); - } - case Kind::Tuple: - { - auto const& tupleSort = dynamic_cast(_sort); - return m_context.mkTupleType(cvc4Sort(tupleSort.components)); - } - default: - break; - } - smtAssert(false, ""); - // Cannot be reached. - return m_context.integerType(); -} - -std::vector CVC4Interface::cvc4Sort(std::vector const& _sorts) -{ - std::vector cvc4Sorts; - for (auto const& _sort: _sorts) - cvc4Sorts.push_back(cvc4Sort(*_sort)); - return cvc4Sorts; -} diff --git a/libsmtutil/CVC4Interface.h b/libsmtutil/CVC4Interface.h deleted file mode 100644 index cc3c0577ce45..000000000000 --- a/libsmtutil/CVC4Interface.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - This file is part of solidity. - - solidity is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - solidity is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with solidity. If not, see . -*/ -// SPDX-License-Identifier: GPL-3.0 - -#pragma once - -#include - -#if defined(__GLIBC__) -// The CVC4 headers includes the deprecated system headers -// and . These headers cause a warning that will break the -// build, unless _GLIBCXX_PERMIT_BACKWARD_HASH is set. -#define _GLIBCXX_PERMIT_BACKWARD_HASH -#endif - -#include - -#if defined(__GLIBC__) -#undef _GLIBCXX_PERMIT_BACKWARD_HASH -#endif - -namespace solidity::smtutil -{ - -class CVC4Interface: public SolverInterface -{ -public: - /// Noncopyable. - CVC4Interface(CVC4Interface const&) = delete; - CVC4Interface& operator=(CVC4Interface const&) = delete; - - CVC4Interface(std::optional _queryTimeout = {}); - - void reset() override; - - void push() override; - void pop() override; - - void declareVariable(std::string const&, SortPointer const&) override; - - void addAssertion(Expression const& _expr) override; - std::pair> check(std::vector const& _expressionsToEvaluate) override; - -private: - CVC4::Expr toCVC4Expr(Expression const& _expr); - CVC4::Type cvc4Sort(Sort const& _sort); - std::vector cvc4Sort(std::vector const& _sorts); - - CVC4::ExprManager m_context; - CVC4::SmtEngine m_solver; - std::map m_variables; - - // CVC4 "basic resources" limit. - // This is used to make the runs more deterministic and platform/machine independent. - // The tests start failing for CVC4 with less than 6000, - // so using double that. - static int const resourceLimit = 12000; -}; - -} diff --git a/libsmtutil/SMTLib2Interface.cpp b/libsmtutil/SMTLib2Interface.cpp index 12469a4ae05f..cfe1bc0bef2c 100644 --- a/libsmtutil/SMTLib2Interface.cpp +++ b/libsmtutil/SMTLib2Interface.cpp @@ -123,11 +123,11 @@ std::pair> SMTLib2Interface::check(std::ve CheckResult result; // TODO proper parsing - if (boost::starts_with(response, "sat\n")) + if (boost::starts_with(response, "sat")) result = CheckResult::SATISFIABLE; - else if (boost::starts_with(response, "unsat\n")) + else if (boost::starts_with(response, "unsat")) result = CheckResult::UNSATISFIABLE; - else if (boost::starts_with(response, "unknown\n")) + else if (boost::starts_with(response, "unknown")) result = CheckResult::UNKNOWN; else result = CheckResult::ERROR; diff --git a/libsmtutil/SMTPortfolio.cpp b/libsmtutil/SMTPortfolio.cpp index 76c69d0180a3..1435cc9d801c 100644 --- a/libsmtutil/SMTPortfolio.cpp +++ b/libsmtutil/SMTPortfolio.cpp @@ -21,9 +21,6 @@ #ifdef HAVE_Z3 #include #endif -#ifdef HAVE_CVC4 -#include -#endif #include using namespace solidity; @@ -41,16 +38,12 @@ SMTPortfolio::SMTPortfolio( SolverInterface(_queryTimeout) { solAssert(!_printQuery || _enabledSolvers == smtutil::SMTSolverChoice::SMTLIB2(), "Only SMTLib2 solver can be enabled to print queries"); - if (_enabledSolvers.smtlib2) + if (_enabledSolvers.smtlib2 || _enabledSolvers.cvc5) m_solvers.emplace_back(std::make_unique(std::move(_smtlib2Responses), std::move(_smtCallback), m_queryTimeout)); #ifdef HAVE_Z3 if (_enabledSolvers.z3 && Z3Interface::available()) m_solvers.emplace_back(std::make_unique(m_queryTimeout)); #endif -#ifdef HAVE_CVC4 - if (_enabledSolvers.cvc4) - m_solvers.emplace_back(std::make_unique(m_queryTimeout)); -#endif } void SMTPortfolio::reset() diff --git a/libsmtutil/SolverInterface.h b/libsmtutil/SolverInterface.h index 13803de6e91a..92f9c8f75b7d 100644 --- a/libsmtutil/SolverInterface.h +++ b/libsmtutil/SolverInterface.h @@ -41,13 +41,13 @@ namespace solidity::smtutil struct SMTSolverChoice { - bool cvc4 = false; + bool cvc5 = false; bool eld = false; bool smtlib2 = false; bool z3 = false; static constexpr SMTSolverChoice All() noexcept { return {true, true, true, true}; } - static constexpr SMTSolverChoice CVC4() noexcept { return {true, false, false, false}; } + static constexpr SMTSolverChoice CVC5() noexcept { return {true, false, false, false}; } static constexpr SMTSolverChoice ELD() noexcept { return {false, true, false, false}; } static constexpr SMTSolverChoice SMTLIB2() noexcept { return {false, false, true, false}; } static constexpr SMTSolverChoice Z3() noexcept { return {false, false, false, true}; } @@ -65,7 +65,7 @@ struct SMTSolverChoice SMTSolverChoice& operator&=(SMTSolverChoice const& _other) { - cvc4 &= _other.cvc4; + cvc5 &= _other.cvc5; eld &= _other.eld; smtlib2 &= _other.smtlib2; z3 &= _other.z3; @@ -82,7 +82,7 @@ struct SMTSolverChoice bool operator==(SMTSolverChoice const& _other) const noexcept { - return cvc4 == _other.cvc4 && + return cvc5 == _other.cvc5 && eld == _other.eld && smtlib2 == _other.smtlib2 && z3 == _other.z3; @@ -90,11 +90,11 @@ struct SMTSolverChoice bool setSolver(std::string const& _solver) { - static std::set const solvers{"cvc4", "eld", "smtlib2", "z3"}; + static std::set const solvers{"cvc5", "eld", "smtlib2", "z3"}; if (!solvers.count(_solver)) return false; - if (_solver == "cvc4") - cvc4 = true; + if (_solver == "cvc5") + cvc5 = true; if (_solver == "eld") eld = true; else if (_solver == "smtlib2") @@ -105,8 +105,8 @@ struct SMTSolverChoice } bool none() const noexcept { return !some(); } - bool some() const noexcept { return cvc4 || eld || smtlib2 || z3; } - bool all() const noexcept { return cvc4 && eld && smtlib2 && z3; } + bool some() const noexcept { return cvc5 || eld || smtlib2 || z3; } + bool all() const noexcept { return cvc5 && eld && smtlib2 && z3; } }; enum class CheckResult diff --git a/libsolidity/formal/BMC.cpp b/libsolidity/formal/BMC.cpp index e7cf35a7f4d6..bf6080e7f6ac 100644 --- a/libsolidity/formal/BMC.cpp +++ b/libsolidity/formal/BMC.cpp @@ -51,15 +51,15 @@ BMC::BMC( )) { solAssert(!_settings.printQuery || _settings.solvers == smtutil::SMTSolverChoice::SMTLIB2(), "Only SMTLib2 solver can be enabled to print queries"); -#if defined (HAVE_Z3) || defined (HAVE_CVC4) - if (m_settings.solvers.cvc4 || m_settings.solvers.z3) +#if defined (HAVE_Z3) + if (m_settings.solvers.z3) if (!_smtlib2Responses.empty()) m_errorReporter.warning( 5622_error, "SMT-LIB2 query responses were given in the auxiliary input, " - "but this Solidity binary uses an SMT solver (Z3/CVC4) directly." + "but this Solidity binary uses an SMT solver Z3 directly." "These responses will be ignored." - "Consider disabling Z3/CVC4 at compilation time in order to use SMT-LIB2 responses." + "Consider disabling Z3 at compilation time in order to use SMT-LIB2 responses." ); #endif } @@ -67,13 +67,13 @@ BMC::BMC( void BMC::analyze(SourceUnit const& _source, std::map, smt::EncodingContext::IdCompare> _solvedTargets) { // At this point every enabled solver is available. - if (!m_settings.solvers.cvc4 && !m_settings.solvers.smtlib2 && !m_settings.solvers.z3) + if (!m_settings.solvers.cvc5 && !m_settings.solvers.smtlib2 && !m_settings.solvers.z3) { m_errorReporter.warning( 7710_error, SourceLocation(), "BMC analysis was not possible since no SMT solver was found and enabled." - " The accepted solvers for BMC are cvc4 and z3." + " The accepted solvers for BMC are cvc5 and z3." ); return; } @@ -123,7 +123,7 @@ void BMC::analyze(SourceUnit const& _source, std::map #endif -#if defined(__linux) || defined(__APPLE__) #include -#endif #include #include @@ -163,14 +161,10 @@ std::vector ModelChecker::unhandledQueries() SMTSolverChoice ModelChecker::availableSolvers() { smtutil::SMTSolverChoice available = smtutil::SMTSolverChoice::SMTLIB2(); -#if defined(__linux) || defined(__APPLE__) available.eld = !boost::process::search_path("eld").empty(); -#endif + available.cvc5 = !boost::process::search_path("cvc5").empty(); #ifdef HAVE_Z3 available.z3 = solidity::smtutil::Z3Interface::available(); -#endif -#ifdef HAVE_CVC4 - available.cvc4 = true; #endif return available; } @@ -179,13 +173,13 @@ SMTSolverChoice ModelChecker::checkRequestedSolvers(SMTSolverChoice _enabled, Er { SMTSolverChoice availableSolvers{ModelChecker::availableSolvers()}; - if (_enabled.cvc4 && !availableSolvers.cvc4) + if (_enabled.cvc5 && !availableSolvers.cvc5) { - _enabled.cvc4 = false; + _enabled.cvc5 = false; _errorReporter.warning( 4902_error, SourceLocation(), - "Solver CVC4 was selected for SMTChecker but it is not available." + "Solver cvc5 was selected for SMTChecker but it is not available." ); } diff --git a/libsolidity/interface/CompilerStack.cpp b/libsolidity/interface/CompilerStack.cpp index 2a9005680678..d5fe44ca167a 100644 --- a/libsolidity/interface/CompilerStack.cpp +++ b/libsolidity/interface/CompilerStack.cpp @@ -656,8 +656,12 @@ bool CompilerStack::analyzeLegacy(bool _noErrorsSoFar) { m_modelCheckerSettings.solvers = ModelChecker::checkRequestedSolvers(m_modelCheckerSettings.solvers, m_errorReporter); if (auto* universalCallback = m_readFile.target()) + { if (m_modelCheckerSettings.solvers.eld) universalCallback->smtCommand().setEldarica(m_modelCheckerSettings.timeout, m_modelCheckerSettings.invariants != ModelCheckerInvariants::None()); + if (m_modelCheckerSettings.solvers.cvc5) + universalCallback->smtCommand().setCvc5(m_modelCheckerSettings.timeout); + } } ModelChecker modelChecker(m_errorReporter, *this, m_smtlib2Responses, m_modelCheckerSettings, m_readFile); diff --git a/libsolidity/interface/SMTSolverCommand.cpp b/libsolidity/interface/SMTSolverCommand.cpp index 7d814cd9c3c4..b9eb392c635b 100644 --- a/libsolidity/interface/SMTSolverCommand.cpp +++ b/libsolidity/interface/SMTSolverCommand.cpp @@ -51,6 +51,22 @@ void SMTSolverCommand::setEldarica(std::optional timeoutInMillisec m_arguments.emplace_back("-ssol"); } +void SMTSolverCommand::setCvc5(std::optional timeoutInMilliseconds) +{ + m_arguments.clear(); + m_solverCmd = "cvc5"; + if (timeoutInMilliseconds) + { + m_arguments.push_back("--tlimit-per"); + m_arguments.push_back(std::to_string(timeoutInMilliseconds.value())); + } + else + { + m_arguments.push_back("--rlimit"); + m_arguments.push_back(std::to_string(12000)); + } +} + ReadCallback::Result SMTSolverCommand::solve(std::string const& _kind, std::string const& _query) { try @@ -68,29 +84,29 @@ ReadCallback::Result SMTSolverCommand::solve(std::string const& _kind, std::stri auto queryFile = boost::filesystem::ofstream(queryFileName); queryFile << _query << std::flush; - auto eldBin = boost::process::search_path(m_solverCmd); + auto solverBin = boost::process::search_path(m_solverCmd); - if (eldBin.empty()) + if (solverBin.empty()) return ReadCallback::Result{false, m_solverCmd + " binary not found."}; auto args = m_arguments; args.push_back(queryFileName.string()); boost::process::ipstream pipe; - boost::process::child eld( - eldBin, + boost::process::child solverProcess( + solverBin, args, boost::process::std_out > pipe, - boost::process::std_err >boost::process::null + boost::process::std_err > boost::process::null ); std::vector data; std::string line; - while (eld.running() && std::getline(pipe, line)) + while (solverProcess.running() && std::getline(pipe, line)) if (!line.empty()) data.push_back(line); - eld.wait(); + solverProcess.wait(); return ReadCallback::Result{true, boost::join(data, "\n")}; } diff --git a/libsolidity/interface/SMTSolverCommand.h b/libsolidity/interface/SMTSolverCommand.h index 665c19c1b767..3b1022740524 100644 --- a/libsolidity/interface/SMTSolverCommand.h +++ b/libsolidity/interface/SMTSolverCommand.h @@ -37,6 +37,7 @@ class SMTSolverCommand } void setEldarica(std::optional timeoutInMilliseconds, bool computeInvariants); + void setCvc5(std::optional timeoutInMilliseconds); private: /// The name of the solver's binary. diff --git a/solc/CommandLineParser.cpp b/solc/CommandLineParser.cpp index e61c5ce0a7ae..2697f7ebd09f 100644 --- a/solc/CommandLineParser.cpp +++ b/solc/CommandLineParser.cpp @@ -877,7 +877,7 @@ General Information)").c_str(), ) ( g_strModelCheckerSolvers.c_str(), - po::value()->value_name("cvc4,eld,z3,smtlib2")->default_value("z3"), + po::value()->value_name("cvc5,eld,z3,smtlib2")->default_value("z3"), "Select model checker solvers." ) ( diff --git a/test/cmdlineTests/model_checker_print_query_all/err b/test/cmdlineTests/model_checker_print_query_all/err index 1a04042cd778..fc3bf7c7a3b6 100644 --- a/test/cmdlineTests/model_checker_print_query_all/err +++ b/test/cmdlineTests/model_checker_print_query_all/err @@ -162,4 +162,4 @@ Info: BMC: Requested query: Warning: BMC: 1 verification condition(s) could not be proved. Enable the model checker option "show unproved" to see all of them. Consider choosing a specific contract to be verified in order to reduce the solving problems. Consider increasing the timeout per query. -Warning: BMC analysis was not possible. No SMT solver (Z3 or CVC4) was available. None of the installed solvers was enabled. +Warning: BMC analysis was not possible. No SMT solver (Z3 or cvc5) was available. None of the installed solvers was enabled. diff --git a/test/cmdlineTests/model_checker_print_query_bmc/err b/test/cmdlineTests/model_checker_print_query_bmc/err index 1a59f87b0d95..ff8b796f8785 100644 --- a/test/cmdlineTests/model_checker_print_query_bmc/err +++ b/test/cmdlineTests/model_checker_print_query_bmc/err @@ -29,4 +29,4 @@ Info: BMC: Requested query: Warning: BMC: 1 verification condition(s) could not be proved. Enable the model checker option "show unproved" to see all of them. Consider choosing a specific contract to be verified in order to reduce the solving problems. Consider increasing the timeout per query. -Warning: BMC analysis was not possible. No SMT solver (Z3 or CVC4) was available. None of the installed solvers was enabled. +Warning: BMC analysis was not possible. No SMT solver (Z3 or cvc5) was available. None of the installed solvers was enabled. diff --git a/test/cmdlineTests/model_checker_solvers_cvc5/args b/test/cmdlineTests/model_checker_solvers_cvc5/args new file mode 100644 index 000000000000..84280d4061ce --- /dev/null +++ b/test/cmdlineTests/model_checker_solvers_cvc5/args @@ -0,0 +1 @@ +--model-checker-engine bmc --model-checker-solvers cvc5 diff --git a/test/cmdlineTests/model_checker_solvers_cvc5/err b/test/cmdlineTests/model_checker_solvers_cvc5/err new file mode 100644 index 000000000000..1c36b103a65d --- /dev/null +++ b/test/cmdlineTests/model_checker_solvers_cvc5/err @@ -0,0 +1,10 @@ +Warning: BMC: Assertion violation happens here. + --> model_checker_solvers_cvc5/input.sol:5:3: + | +5 | assert(x > 0); + | ^^^^^^^^^^^^^ +Note: Counterexample: + x = 0 + +Note: Callstack: +Note: diff --git a/test/cmdlineTests/model_checker_solvers_cvc5/input.sol b/test/cmdlineTests/model_checker_solvers_cvc5/input.sol new file mode 100644 index 000000000000..ef11e87eb8fc --- /dev/null +++ b/test/cmdlineTests/model_checker_solvers_cvc5/input.sol @@ -0,0 +1,7 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity >=0.0; +contract test { + function f(uint x) public pure { + assert(x > 0); + } +} diff --git a/test/cmdlineTests/model_checker_solvers_smtlib2/err b/test/cmdlineTests/model_checker_solvers_smtlib2/err index 3aa9893489bc..452e2b31d9f1 100644 --- a/test/cmdlineTests/model_checker_solvers_smtlib2/err +++ b/test/cmdlineTests/model_checker_solvers_smtlib2/err @@ -4,4 +4,4 @@ Warning: CHC analysis was not possible. No Horn solver was available. None of th Warning: BMC: 1 verification condition(s) could not be proved. Enable the model checker option "show unproved" to see all of them. Consider choosing a specific contract to be verified in order to reduce the solving problems. Consider increasing the timeout per query. -Warning: BMC analysis was not possible. No SMT solver (Z3 or CVC4) was available. None of the installed solvers was enabled. +Warning: BMC analysis was not possible. No SMT solver (Z3 or cvc5) was available. None of the installed solvers was enabled. diff --git a/test/cmdlineTests/standard_model_checker_print_query_all/output.json b/test/cmdlineTests/standard_model_checker_print_query_all/output.json index 16ff42e0c306..97aa8857928b 100644 --- a/test/cmdlineTests/standard_model_checker_print_query_all/output.json +++ b/test/cmdlineTests/standard_model_checker_print_query_all/output.json @@ -519,10 +519,10 @@ { "component": "general", "errorCode": "8084", - "formattedMessage": "Warning: BMC analysis was not possible. No SMT solver (Z3 or CVC4) was available. None of the installed solvers was enabled. + "formattedMessage": "Warning: BMC analysis was not possible. No SMT solver (Z3 or cvc5) was available. None of the installed solvers was enabled. ", - "message": "BMC analysis was not possible. No SMT solver (Z3 or CVC4) was available. None of the installed solvers was enabled.", + "message": "BMC analysis was not possible. No SMT solver (Z3 or cvc5) was available. None of the installed solvers was enabled.", "severity": "warning", "type": "Warning" } diff --git a/test/cmdlineTests/standard_model_checker_print_query_bmc/output.json b/test/cmdlineTests/standard_model_checker_print_query_bmc/output.json index 1c9826ad22e0..9fd5f5929adc 100644 --- a/test/cmdlineTests/standard_model_checker_print_query_bmc/output.json +++ b/test/cmdlineTests/standard_model_checker_print_query_bmc/output.json @@ -108,10 +108,10 @@ { "component": "general", "errorCode": "8084", - "formattedMessage": "Warning: BMC analysis was not possible. No SMT solver (Z3 or CVC4) was available. None of the installed solvers was enabled. + "formattedMessage": "Warning: BMC analysis was not possible. No SMT solver (Z3 or cvc5) was available. None of the installed solvers was enabled. ", - "message": "BMC analysis was not possible. No SMT solver (Z3 or CVC4) was available. None of the installed solvers was enabled.", + "message": "BMC analysis was not possible. No SMT solver (Z3 or cvc5) was available. None of the installed solvers was enabled.", "severity": "warning", "type": "Warning" } diff --git a/test/cmdlineTests/standard_model_checker_solvers_none/output.json b/test/cmdlineTests/standard_model_checker_solvers_none/output.json index e8de49d1ede3..a36195e1cae4 100644 --- a/test/cmdlineTests/standard_model_checker_solvers_none/output.json +++ b/test/cmdlineTests/standard_model_checker_solvers_none/output.json @@ -13,10 +13,10 @@ { "component": "general", "errorCode": "7710", - "formattedMessage": "Warning: BMC analysis was not possible since no SMT solver was found and enabled. The accepted solvers for BMC are cvc4 and z3. + "formattedMessage": "Warning: BMC analysis was not possible since no SMT solver was found and enabled. The accepted solvers for BMC are cvc5 and z3. ", - "message": "BMC analysis was not possible since no SMT solver was found and enabled. The accepted solvers for BMC are cvc4 and z3.", + "message": "BMC analysis was not possible since no SMT solver was found and enabled. The accepted solvers for BMC are cvc5 and z3.", "severity": "warning", "type": "Warning" } diff --git a/test/cmdlineTests/standard_model_checker_solvers_smtlib2/output.json b/test/cmdlineTests/standard_model_checker_solvers_smtlib2/output.json index d3bdc6b7eb28..e97227076b3d 100644 --- a/test/cmdlineTests/standard_model_checker_solvers_smtlib2/output.json +++ b/test/cmdlineTests/standard_model_checker_solvers_smtlib2/output.json @@ -187,10 +187,10 @@ { "component": "general", "errorCode": "8084", - "formattedMessage": "Warning: BMC analysis was not possible. No SMT solver (Z3 or CVC4) was available. None of the installed solvers was enabled. + "formattedMessage": "Warning: BMC analysis was not possible. No SMT solver (Z3 or cvc5) was available. None of the installed solvers was enabled. ", - "message": "BMC analysis was not possible. No SMT solver (Z3 or CVC4) was available. None of the installed solvers was enabled.", + "message": "BMC analysis was not possible. No SMT solver (Z3 or cvc5) was available. None of the installed solvers was enabled.", "severity": "warning", "type": "Warning" } diff --git a/test/libsolidity/SMTCheckerTest.h b/test/libsolidity/SMTCheckerTest.h index aa0f92121a70..6a15791522e7 100644 --- a/test/libsolidity/SMTCheckerTest.h +++ b/test/libsolidity/SMTCheckerTest.h @@ -56,7 +56,7 @@ class SMTCheckerTest: public SyntaxTest Set in m_modelCheckerSettings. SMTShowUnproved: `yes`, `no`, where the default is `yes`. Set in m_modelCheckerSettings. - SMTSolvers: `all`, `cvc4`, `z3`, `none`, where the default is `all`. + SMTSolvers: `all`, `cvc5`, `z3`, `none`, where the default is `all`. Set in m_modelCheckerSettings. BMCLoopIterations: number of loop iterations for BMC engine, the default is 1. Set in m_modelCheckerSettings. diff --git a/test/libsolidity/smtCheckerTests/imports/duplicated_errors_1.sol b/test/libsolidity/smtCheckerTests/imports/duplicated_errors_1.sol index a98ba962a7bf..c225fe0b49a7 100644 --- a/test/libsolidity/smtCheckerTests/imports/duplicated_errors_1.sol +++ b/test/libsolidity/smtCheckerTests/imports/duplicated_errors_1.sol @@ -19,8 +19,8 @@ contract C is B { // Warning 6328: (b.sol:62-75): CHC: Assertion violation might happen here. // Warning 3996: CHC analysis was not possible. No Horn solver was available. None of the installed solvers was enabled. // Warning 7812: (b.sol:62-75): BMC: Assertion violation might happen here. -// Warning 8084: BMC analysis was not possible. No SMT solver (Z3 or CVC4) was available. None of the installed solvers was enabled. +// Warning 8084: BMC analysis was not possible. No SMT solver (Z3 or cvc5) was available. None of the installed solvers was enabled. // Warning 6328: (c.sol:68-81): CHC: Assertion violation might happen here. // Warning 3996: CHC analysis was not possible. No Horn solver was available. None of the installed solvers was enabled. // Warning 7812: (c.sol:68-81): BMC: Assertion violation might happen here. -// Warning 8084: BMC analysis was not possible. No SMT solver (Z3 or CVC4) was available. None of the installed solvers was enabled. +// Warning 8084: BMC analysis was not possible. No SMT solver (Z3 or cvc5) was available. None of the installed solvers was enabled. From 025f9a2cedd54fd77f3b0421887e05fe567527ab Mon Sep 17 00:00:00 2001 From: Martin Blicha Date: Wed, 15 May 2024 19:08:53 +0200 Subject: [PATCH 0253/1022] Update CI images --- .circleci/config.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 3e65f4ac16ad..d6c3f33da08a 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -9,16 +9,16 @@ version: 2.1 parameters: ubuntu-2004-docker-image: type: string - # solbuildpackpusher/solidity-buildpack-deps:ubuntu2004-23 - default: "solbuildpackpusher/solidity-buildpack-deps@sha256:84a1fb8771236e8d9aa5c615a425b8929e56a6e4f150a60078c8d74a1ceaa6c2" + # solbuildpackpusher/solidity-buildpack-deps:ubuntu2004-24 + default: "solbuildpackpusher/solidity-buildpack-deps@sha256:b8b645fa7ab40d55f2d16eac295d16ca01ec51d32be7d668ae6eaecd47dbd763" ubuntu-2204-docker-image: type: string - # solbuildpackpusher/solidity-buildpack-deps:ubuntu2204-8 - default: "solbuildpackpusher/solidity-buildpack-deps@sha256:1c3a4118218640b2bf632242979a63d48f3d9c70d48be9574332f2dbbd04b192" + # solbuildpackpusher/solidity-buildpack-deps:ubuntu2204-9 + default: "solbuildpackpusher/solidity-buildpack-deps@sha256:80247de9655b1f39afd4ac22b14266bc9b9a0d64b283ae8fb9cb5b8250e4e77d" ubuntu-2204-clang-docker-image: type: string - # solbuildpackpusher/solidity-buildpack-deps:ubuntu2204.clang-7 - default: "solbuildpackpusher/solidity-buildpack-deps@sha256:0f47e733e100080c4174381c262cfcf974bc8e7c3c41b8dff611b9641c82f714" + # solbuildpackpusher/solidity-buildpack-deps:ubuntu2204.clang-8 + default: "solbuildpackpusher/solidity-buildpack-deps@sha256:2662376fe0e1ec2d346495a19a6d64508c1048d5a7325d8600c33c343fa64a0f" ubuntu-clang-ossfuzz-docker-image: type: string # solbuildpackpusher/solidity-buildpack-deps:ubuntu.clang.ossfuzz-6 From 20ae0f2e07e1928f04ba212477019329956f66ad Mon Sep 17 00:00:00 2001 From: Martin Blicha Date: Sat, 1 Jun 2024 10:04:28 +0200 Subject: [PATCH 0254/1022] SMTChecker: Allow using multiple external solvers in one analysis We are using SMTCommand inside UniversalCallback to call external solvers on queries produced my our engines. Previous mechanism set the external solver once during initialization and it was not possible to change it later. This meant, that it would not be possible to use, e.g., Eldarica and cvc5 at the same time. Here we move the proper setup for SMTCommand just before we call it. This setup is customized by subclasses of (CHC)SmtLib2Interface, which call corresponding external solvers. --- libsmtutil/CHCSmtLib2Interface.cpp | 8 ++-- libsmtutil/CHCSmtLib2Interface.h | 11 ++--- libsmtutil/SMTLib2Interface.cpp | 1 + libsmtutil/SMTLib2Interface.h | 4 +- libsmtutil/SMTPortfolio.cpp | 23 +++-------- libsmtutil/SMTPortfolio.h | 8 +--- libsolidity/CMakeLists.txt | 4 ++ libsolidity/formal/BMC.cpp | 24 ++++++++--- libsolidity/formal/CHC.cpp | 17 ++++++-- libsolidity/formal/Cvc5SMTLib2Interface.cpp | 35 ++++++++++++++++ libsolidity/formal/Cvc5SMTLib2Interface.h | 37 +++++++++++++++++ .../formal/EldaricaCHCSmtLib2Interface.cpp | 37 +++++++++++++++++ .../formal/EldaricaCHCSmtLib2Interface.h | 41 +++++++++++++++++++ libsolidity/interface/CompilerStack.cpp | 9 ---- .../model_checker_solvers_cvc5_eld/args | 1 + .../model_checker_solvers_cvc5_eld/err | 8 ++++ .../model_checker_solvers_cvc5_eld/input.sol | 10 +++++ 17 files changed, 224 insertions(+), 54 deletions(-) create mode 100644 libsolidity/formal/Cvc5SMTLib2Interface.cpp create mode 100644 libsolidity/formal/Cvc5SMTLib2Interface.h create mode 100644 libsolidity/formal/EldaricaCHCSmtLib2Interface.cpp create mode 100644 libsolidity/formal/EldaricaCHCSmtLib2Interface.h create mode 100644 test/cmdlineTests/model_checker_solvers_cvc5_eld/args create mode 100644 test/cmdlineTests/model_checker_solvers_cvc5_eld/err create mode 100644 test/cmdlineTests/model_checker_solvers_cvc5_eld/input.sol diff --git a/libsmtutil/CHCSmtLib2Interface.cpp b/libsmtutil/CHCSmtLib2Interface.cpp index 671ec9b51d6c..a267a843bb68 100644 --- a/libsmtutil/CHCSmtLib2Interface.cpp +++ b/libsmtutil/CHCSmtLib2Interface.cpp @@ -43,16 +43,14 @@ using namespace solidity::frontend; using namespace solidity::smtutil; CHCSmtLib2Interface::CHCSmtLib2Interface( - std::map const& _queryResponses, + std::map _queryResponses, ReadCallback::Callback _smtCallback, - SMTSolverChoice _enabledSolvers, std::optional _queryTimeout ): CHCSolverInterface(_queryTimeout), m_smtlib2(std::make_unique(_queryResponses, _smtCallback, m_queryTimeout)), m_queryResponses(std::move(_queryResponses)), - m_smtCallback(_smtCallback), - m_enabledSolvers(_enabledSolvers) + m_smtCallback(_smtCallback) { reset(); } @@ -186,9 +184,9 @@ std::string CHCSmtLib2Interface::querySolver(std::string const& _input) if (m_queryResponses.count(inputHash)) return m_queryResponses.at(inputHash); - smtAssert(m_enabledSolvers.smtlib2 || m_enabledSolvers.eld); if (m_smtCallback) { + setupSmtCallback(); auto result = m_smtCallback(ReadCallback::kindString(ReadCallback::Kind::SMTQuery), _input); if (result.success) return result.responseOrErrorMessage; diff --git a/libsmtutil/CHCSmtLib2Interface.h b/libsmtutil/CHCSmtLib2Interface.h index f7f656fd0b49..39131973bf7f 100644 --- a/libsmtutil/CHCSmtLib2Interface.h +++ b/libsmtutil/CHCSmtLib2Interface.h @@ -33,9 +33,8 @@ class CHCSmtLib2Interface: public CHCSolverInterface { public: explicit CHCSmtLib2Interface( - std::map const& _queryResponses = {}, + std::map _queryResponses = {}, frontend::ReadCallback::Callback _smtCallback = {}, - SMTSolverChoice _enabledSolvers = SMTSolverChoice::All(), std::optional _queryTimeout = {} ); @@ -59,7 +58,7 @@ class CHCSmtLib2Interface: public CHCSolverInterface auto const& sortNames() const { return m_smtlib2->sortNames(); } -private: +protected: std::string toSmtLibSort(SortPointer _sort); std::string toSmtLibSort(std::vector const& _sort); @@ -79,17 +78,19 @@ class CHCSmtLib2Interface: public CHCSolverInterface /// Translates CHC solver response with a model to our representation of invariants. Returns None on error. std::optional invariantsFromSolverResponse(std::string const& response) const; + /// Hook to setup external solver call + virtual void setupSmtCallback() {} + /// Used to access toSmtLibSort, SExpr, and handle variables. std::unique_ptr m_smtlib2; std::string m_accumulatedOutput; std::set m_variables; - std::map const& m_queryResponses; + std::map m_queryResponses; std::vector m_unhandledQueries; frontend::ReadCallback::Callback m_smtCallback; - SMTSolverChoice m_enabledSolvers; }; } diff --git a/libsmtutil/SMTLib2Interface.cpp b/libsmtutil/SMTLib2Interface.cpp index cfe1bc0bef2c..06ed26f2b26b 100644 --- a/libsmtutil/SMTLib2Interface.cpp +++ b/libsmtutil/SMTLib2Interface.cpp @@ -322,6 +322,7 @@ std::string SMTLib2Interface::querySolver(std::string const& _input) return m_queryResponses.at(inputHash); if (m_smtCallback) { + setupSmtCallback(); auto result = m_smtCallback(ReadCallback::kindString(ReadCallback::Kind::SMTQuery), _input); if (result.success) return result.responseOrErrorMessage; diff --git a/libsmtutil/SMTLib2Interface.h b/libsmtutil/SMTLib2Interface.h index fbfde664d579..d60a5bd250c5 100644 --- a/libsmtutil/SMTLib2Interface.h +++ b/libsmtutil/SMTLib2Interface.h @@ -71,7 +71,9 @@ class SMTLib2Interface: public SolverInterface std::string dumpQuery(std::vector const& _expressionsToEvaluate); -private: +protected: + virtual void setupSmtCallback() {} + void declareFunction(std::string const& _name, SortPointer const& _sort); void write(std::string _data); diff --git a/libsmtutil/SMTPortfolio.cpp b/libsmtutil/SMTPortfolio.cpp index 1435cc9d801c..196f02fdf99c 100644 --- a/libsmtutil/SMTPortfolio.cpp +++ b/libsmtutil/SMTPortfolio.cpp @@ -18,9 +18,6 @@ #include -#ifdef HAVE_Z3 -#include -#endif #include using namespace solidity; @@ -29,22 +26,12 @@ using namespace solidity::frontend; using namespace solidity::smtutil; SMTPortfolio::SMTPortfolio( - std::map _smtlib2Responses, - frontend::ReadCallback::Callback _smtCallback, - [[maybe_unused]] SMTSolverChoice _enabledSolvers, - std::optional _queryTimeout, - bool _printQuery + std::vector> _solvers, + std::optional _queryTimeout ): - SolverInterface(_queryTimeout) -{ - solAssert(!_printQuery || _enabledSolvers == smtutil::SMTSolverChoice::SMTLIB2(), "Only SMTLib2 solver can be enabled to print queries"); - if (_enabledSolvers.smtlib2 || _enabledSolvers.cvc5) - m_solvers.emplace_back(std::make_unique(std::move(_smtlib2Responses), std::move(_smtCallback), m_queryTimeout)); -#ifdef HAVE_Z3 - if (_enabledSolvers.z3 && Z3Interface::available()) - m_solvers.emplace_back(std::make_unique(m_queryTimeout)); -#endif -} + SolverInterface(_queryTimeout), m_solvers(std::move(_solvers)) +{} + void SMTPortfolio::reset() { diff --git a/libsmtutil/SMTPortfolio.h b/libsmtutil/SMTPortfolio.h index cdb33368e80a..5ffb37eb3286 100644 --- a/libsmtutil/SMTPortfolio.h +++ b/libsmtutil/SMTPortfolio.h @@ -42,13 +42,7 @@ class SMTPortfolio: public SolverInterface SMTPortfolio(SMTPortfolio const&) = delete; SMTPortfolio& operator=(SMTPortfolio const&) = delete; - SMTPortfolio( - std::map _smtlib2Responses = {}, - frontend::ReadCallback::Callback _smtCallback = {}, - SMTSolverChoice _enabledSolvers = SMTSolverChoice::All(), - std::optional _queryTimeout = {}, - bool _printQuery = false - ); + SMTPortfolio(std::vector> solvers, std::optional _queryTimeout); void reset() override; diff --git a/libsolidity/CMakeLists.txt b/libsolidity/CMakeLists.txt index 3db857241f28..0b796035d313 100644 --- a/libsolidity/CMakeLists.txt +++ b/libsolidity/CMakeLists.txt @@ -109,6 +109,10 @@ set(sources formal/BMC.h formal/CHC.cpp formal/CHC.h + formal/Cvc5SMTLib2Interface.cpp + formal/Cvc5SMTLib2Interface.h + formal/EldaricaCHCSmtLib2Interface.cpp + formal/EldaricaCHCSmtLib2Interface.h formal/EncodingContext.cpp formal/EncodingContext.h formal/ExpressionFormatter.cpp diff --git a/libsolidity/formal/BMC.cpp b/libsolidity/formal/BMC.cpp index bf6080e7f6ac..916bf5a31db0 100644 --- a/libsolidity/formal/BMC.cpp +++ b/libsolidity/formal/BMC.cpp @@ -18,9 +18,14 @@ #include +#include #include +#include #include +#ifdef HAVE_Z3 +#include +#endif #include #include @@ -35,6 +40,8 @@ using namespace solidity; using namespace solidity::util; using namespace solidity::langutil; using namespace solidity::frontend; +using namespace solidity::frontend::smt; +using namespace solidity::smtutil; BMC::BMC( smt::EncodingContext& _context, @@ -45,12 +52,19 @@ BMC::BMC( ModelCheckerSettings _settings, CharStreamProvider const& _charStreamProvider ): - SMTEncoder(_context, _settings, _errorReporter, _unsupportedErrorReporter, _charStreamProvider), - m_interface(std::make_unique( - _smtlib2Responses, _smtCallback, _settings.solvers, _settings.timeout, _settings.printQuery - )) + SMTEncoder(_context, _settings, _errorReporter, _unsupportedErrorReporter, _charStreamProvider) { - solAssert(!_settings.printQuery || _settings.solvers == smtutil::SMTSolverChoice::SMTLIB2(), "Only SMTLib2 solver can be enabled to print queries"); + solAssert(!_settings.printQuery || _settings.solvers == SMTSolverChoice::SMTLIB2(), "Only SMTLib2 solver can be enabled to print queries"); + std::vector> solvers; + if (_settings.solvers.smtlib2) + solvers.emplace_back(std::make_unique(_smtlib2Responses, _smtCallback, _settings.timeout)); + if (_settings.solvers.cvc5) + solvers.emplace_back(std::make_unique(_smtCallback, _settings.timeout)); +#ifdef HAVE_Z3 + if (_settings.solvers.z3 && Z3Interface::available()) + solvers.emplace_back(std::make_unique(_settings.timeout)); +#endif + m_interface = std::make_unique(std::move(solvers), _settings.timeout); #if defined (HAVE_Z3) if (m_settings.solvers.z3) if (!_smtlib2Responses.empty()) diff --git a/libsolidity/formal/CHC.cpp b/libsolidity/formal/CHC.cpp index c520d13f6b0f..66ebd47edb98 100644 --- a/libsolidity/formal/CHC.cpp +++ b/libsolidity/formal/CHC.cpp @@ -25,6 +25,7 @@ #endif #include +#include #include #include #include @@ -1289,15 +1290,23 @@ void CHC::resetSourceAnalysis() solAssert(false); #endif } - if (!m_settings.solvers.z3) + else { solAssert(m_settings.solvers.smtlib2 || m_settings.solvers.eld); - if (!m_interface) - m_interface = std::make_unique(m_smtlib2Responses, m_smtCallback, m_settings.solvers, m_settings.timeout); + { + if (m_settings.solvers.eld) + m_interface = std::make_unique( + m_smtCallback, + m_settings.timeout, + m_settings.invariants != ModelCheckerInvariants::None() + ); + else + m_interface = std::make_unique(m_smtlib2Responses, m_smtCallback, m_settings.timeout); + } auto smtlib2Interface = dynamic_cast(m_interface.get()); - solAssert(smtlib2Interface, ""); + solAssert(smtlib2Interface); smtlib2Interface->reset(); m_context.setSolver(smtlib2Interface->smtlib2Interface()); } diff --git a/libsolidity/formal/Cvc5SMTLib2Interface.cpp b/libsolidity/formal/Cvc5SMTLib2Interface.cpp new file mode 100644 index 000000000000..8a399c1356df --- /dev/null +++ b/libsolidity/formal/Cvc5SMTLib2Interface.cpp @@ -0,0 +1,35 @@ +/* + 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 + +using namespace solidity::frontend::smt; + +Cvc5SMTLib2Interface::Cvc5SMTLib2Interface( + frontend::ReadCallback::Callback _smtCallback, + std::optional _queryTimeout +): SMTLib2Interface({}, std::move(_smtCallback), _queryTimeout) +{ +} + +void Cvc5SMTLib2Interface::setupSmtCallback() { + if (auto* universalCallback = m_smtCallback.target()) + universalCallback->smtCommand().setCvc5(m_queryTimeout); +} diff --git a/libsolidity/formal/Cvc5SMTLib2Interface.h b/libsolidity/formal/Cvc5SMTLib2Interface.h new file mode 100644 index 000000000000..64bc364da1c8 --- /dev/null +++ b/libsolidity/formal/Cvc5SMTLib2Interface.h @@ -0,0 +1,37 @@ +/* + 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::frontend::smt +{ + +class Cvc5SMTLib2Interface: public smtutil::SMTLib2Interface +{ +public: + explicit Cvc5SMTLib2Interface( + frontend::ReadCallback::Callback _smtCallback = {}, + std::optional _queryTimeout = {} + ); +private: + void setupSmtCallback() override; +}; + +} diff --git a/libsolidity/formal/EldaricaCHCSmtLib2Interface.cpp b/libsolidity/formal/EldaricaCHCSmtLib2Interface.cpp new file mode 100644 index 000000000000..4fa94539d8b8 --- /dev/null +++ b/libsolidity/formal/EldaricaCHCSmtLib2Interface.cpp @@ -0,0 +1,37 @@ +/* + 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 + +using namespace solidity::frontend::smt; + +EldaricaCHCSmtLib2Interface::EldaricaCHCSmtLib2Interface( + frontend::ReadCallback::Callback _smtCallback, + std::optional _queryTimeout, + bool computeInvariants +): CHCSmtLib2Interface({}, std::move(_smtCallback), _queryTimeout), m_computeInvariants(computeInvariants) +{ +} + +void EldaricaCHCSmtLib2Interface::setupSmtCallback() +{ + if (auto* universalCallback = m_smtCallback.target()) + universalCallback->smtCommand().setEldarica(m_queryTimeout, m_computeInvariants); +} diff --git a/libsolidity/formal/EldaricaCHCSmtLib2Interface.h b/libsolidity/formal/EldaricaCHCSmtLib2Interface.h new file mode 100644 index 000000000000..2c83b194ca7d --- /dev/null +++ b/libsolidity/formal/EldaricaCHCSmtLib2Interface.h @@ -0,0 +1,41 @@ +/* + This file is part of solidity. + + solidity is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + solidity is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with solidity. If not, see . +*/ +// SPDX-License-Identifier: GPL-3.0 + +#pragma once + +#include + +namespace solidity::frontend::smt +{ + +class EldaricaCHCSmtLib2Interface: public smtutil::CHCSmtLib2Interface +{ +public: + EldaricaCHCSmtLib2Interface( + frontend::ReadCallback::Callback _smtCallback, + std::optional _queryTimeout, + bool computeInvariants + ); + +private: + void setupSmtCallback() override; + + bool m_computeInvariants; +}; + +} diff --git a/libsolidity/interface/CompilerStack.cpp b/libsolidity/interface/CompilerStack.cpp index d5fe44ca167a..f9f1f0e64206 100644 --- a/libsolidity/interface/CompilerStack.cpp +++ b/libsolidity/interface/CompilerStack.cpp @@ -653,16 +653,7 @@ bool CompilerStack::analyzeLegacy(bool _noErrorsSoFar) // m_modelCheckerSettings is spread to engines and solver interfaces, // so we need to check whether the enabled ones are available before building the classes. if (m_modelCheckerSettings.engine.any()) - { m_modelCheckerSettings.solvers = ModelChecker::checkRequestedSolvers(m_modelCheckerSettings.solvers, m_errorReporter); - if (auto* universalCallback = m_readFile.target()) - { - if (m_modelCheckerSettings.solvers.eld) - universalCallback->smtCommand().setEldarica(m_modelCheckerSettings.timeout, m_modelCheckerSettings.invariants != ModelCheckerInvariants::None()); - if (m_modelCheckerSettings.solvers.cvc5) - universalCallback->smtCommand().setCvc5(m_modelCheckerSettings.timeout); - } - } ModelChecker modelChecker(m_errorReporter, *this, m_smtlib2Responses, m_modelCheckerSettings, m_readFile); modelChecker.checkRequestedSourcesAndContracts(allSources); diff --git a/test/cmdlineTests/model_checker_solvers_cvc5_eld/args b/test/cmdlineTests/model_checker_solvers_cvc5_eld/args new file mode 100644 index 000000000000..fb0c074ab2c4 --- /dev/null +++ b/test/cmdlineTests/model_checker_solvers_cvc5_eld/args @@ -0,0 +1 @@ +--model-checker-engine all --model-checker-solvers cvc5,eld diff --git a/test/cmdlineTests/model_checker_solvers_cvc5_eld/err b/test/cmdlineTests/model_checker_solvers_cvc5_eld/err new file mode 100644 index 000000000000..81a9f3a56342 --- /dev/null +++ b/test/cmdlineTests/model_checker_solvers_cvc5_eld/err @@ -0,0 +1,8 @@ +Info: CHC: 1 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. + +Warning: BMC: Condition is always false. + --> model_checker_solvers_cvc5_eld/input.sol:6:7: + | +6 | if (y == 0) + | ^^^^^^ +Note: Callstack: diff --git a/test/cmdlineTests/model_checker_solvers_cvc5_eld/input.sol b/test/cmdlineTests/model_checker_solvers_cvc5_eld/input.sol new file mode 100644 index 000000000000..eae2d9b48594 --- /dev/null +++ b/test/cmdlineTests/model_checker_solvers_cvc5_eld/input.sol @@ -0,0 +1,10 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity >=0.0; +contract test { + function f() public pure { + uint y = 1; + if (y == 0) + revert(); + assert(y > 0); + } +} From b66df3e36f2660db1ad15e9ddf02042342d9db52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Wed, 5 Jun 2024 20:30:36 +0200 Subject: [PATCH 0255/1022] CompilerStack: Remove some misapplied std:: prefixes from comments and messages --- libsolidity/interface/CompilerStack.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libsolidity/interface/CompilerStack.cpp b/libsolidity/interface/CompilerStack.cpp index f9f1f0e64206..0329aded68ae 100644 --- a/libsolidity/interface/CompilerStack.cpp +++ b/libsolidity/interface/CompilerStack.cpp @@ -279,7 +279,7 @@ void CompilerStack::setOptimiserSettings(OptimiserSettings _settings) void CompilerStack::setRevertStringBehaviour(RevertStrings _revertStrings) { if (m_stackState >= ParsedAndImported) - solThrow(CompilerError, "Must set revert std::string settings before parsing."); + solThrow(CompilerError, "Must set revert string settings before parsing."); solUnimplementedAssert(_revertStrings != RevertStrings::VerboseDebug); m_revertStrings = _revertStrings; } @@ -984,7 +984,7 @@ evmasm::LinkerObject const& CompilerStack::runtimeObject(std::string const& _con return contract(_contractName).runtimeObject; } -/// TODO: cache this std::string +/// TODO: cache this string std::string CompilerStack::assemblyString(std::string const& _contractName, StringMap const& _sourceCodes) const { if (m_stackState != CompilationSuccessful) From e2fb57b80b08d6d29af5b67aa53ce7341dbcf807 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Wed, 5 Jun 2024 20:44:59 +0200 Subject: [PATCH 0256/1022] CompilerStack: Convert overzealous input validations to assertions --- libsolidity/interface/CompilerStack.cpp | 201 +++++++----------------- 1 file changed, 59 insertions(+), 142 deletions(-) diff --git a/libsolidity/interface/CompilerStack.cpp b/libsolidity/interface/CompilerStack.cpp index 0329aded68ae..a07310e2c9d1 100644 --- a/libsolidity/interface/CompilerStack.cpp +++ b/libsolidity/interface/CompilerStack.cpp @@ -215,8 +215,7 @@ void CompilerStack::findAndReportCyclicContractDependencies() void CompilerStack::setRemappings(std::vector _remappings) { - if (m_stackState >= ParsedAndImported) - solThrow(CompilerError, "Must set remappings before parsing."); + solAssert(m_stackState < ParsedAndImported, "Must set remappings before parsing."); for (auto const& remapping: _remappings) solAssert(!remapping.prefix.empty(), ""); m_importRemapper.setRemappings(std::move(_remappings)); @@ -224,15 +223,13 @@ void CompilerStack::setRemappings(std::vector _remapp void CompilerStack::setViaIR(bool _viaIR) { - if (m_stackState >= ParsedAndImported) - solThrow(CompilerError, "Must set viaIR before parsing."); + solAssert(m_stackState < ParsedAndImported, "Must set viaIR before parsing."); m_viaIR = _viaIR; } void CompilerStack::setEVMVersion(langutil::EVMVersion _version) { - if (m_stackState >= ParsedAndImported) - solThrow(CompilerError, "Must set EVM version before parsing."); + solAssert(m_stackState < ParsedAndImported, "Must set EVM version before parsing."); m_evmVersion = _version; // GlobalContext depends on evmVersion since the Cancun hardfork. // Therefore, we reset it whenever we set a new EVM version, ensuring that the context is never reused with a mismatched version. @@ -241,24 +238,20 @@ void CompilerStack::setEVMVersion(langutil::EVMVersion _version) void CompilerStack::setEOFVersion(std::optional _version) { - if (m_stackState >= CompilationSuccessful) - solThrow(CompilerError, "Must set EOF version before compiling."); - if (_version && _version != 1) - solThrow(CompilerError, "Invalid EOF version."); + solAssert(m_stackState < CompilationSuccessful, "Must set EOF version before compiling."); + solAssert(!_version || _version == 1, "Invalid EOF version."); m_eofVersion = _version; } void CompilerStack::setModelCheckerSettings(ModelCheckerSettings _settings) { - if (m_stackState >= ParsedAndImported) - solThrow(CompilerError, "Must set model checking settings before parsing."); + solAssert(m_stackState < ParsedAndImported, "Must set model checking settings before parsing."); m_modelCheckerSettings = _settings; } void CompilerStack::setLibraries(std::map const& _libraries) { - if (m_stackState >= ParsedAndImported) - solThrow(CompilerError, "Must set libraries before parsing."); + solAssert(m_stackState < ParsedAndImported, "Must set libraries before parsing."); m_libraries = _libraries; } @@ -271,44 +264,38 @@ void CompilerStack::setOptimiserSettings(bool _optimize, size_t _runs) void CompilerStack::setOptimiserSettings(OptimiserSettings _settings) { - if (m_stackState >= ParsedAndImported) - solThrow(CompilerError, "Must set optimiser settings before parsing."); + solAssert(m_stackState < ParsedAndImported, "Must set optimiser settings before parsing."); m_optimiserSettings = std::move(_settings); } void CompilerStack::setRevertStringBehaviour(RevertStrings _revertStrings) { - if (m_stackState >= ParsedAndImported) - solThrow(CompilerError, "Must set revert string settings before parsing."); + solAssert(m_stackState < ParsedAndImported, "Must set revert string settings before parsing."); solUnimplementedAssert(_revertStrings != RevertStrings::VerboseDebug); m_revertStrings = _revertStrings; } void CompilerStack::useMetadataLiteralSources(bool _metadataLiteralSources) { - if (m_stackState >= ParsedAndImported) - solThrow(CompilerError, "Must set use literal sources before parsing."); + solAssert(m_stackState < ParsedAndImported, "Must set use literal sources before parsing."); m_metadataLiteralSources = _metadataLiteralSources; } void CompilerStack::setMetadataHash(MetadataHash _metadataHash) { - if (m_stackState >= ParsedAndImported) - solThrow(CompilerError, "Must set metadata hash before parsing."); + solAssert(m_stackState < ParsedAndImported, "Must set metadata hash before parsing."); m_metadataHash = _metadataHash; } void CompilerStack::selectDebugInfo(DebugInfoSelection _debugInfoSelection) { - if (m_stackState >= CompilationSuccessful) - BOOST_THROW_EXCEPTION(CompilerError() << util::errinfo_comment("Must select debug info components before compilation.")); + solAssert(m_stackState < CompilationSuccessful, "Must select debug info components before compilation."); m_debugInfoSelection = _debugInfoSelection; } void CompilerStack::addSMTLib2Response(h256 const& _hash, std::string const& _response) { - if (m_stackState >= ParsedAndImported) - solThrow(CompilerError, "Must add SMTLib2 responses before parsing."); + solAssert(m_stackState < ParsedAndImported, "Must add SMTLib2 responses before parsing."); m_smtlib2Responses[_hash] = _response; } @@ -344,10 +331,8 @@ void CompilerStack::reset(bool _keepSettings) void CompilerStack::setSources(StringMap _sources) { - if (m_stackState == SourcesSet) - solThrow(CompilerError, "Cannot change sources once set."); - if (m_stackState != Empty) - solThrow(CompilerError, "Must set sources before parsing."); + solAssert(m_stackState != SourcesSet, "Cannot change sources once set."); + solAssert(m_stackState == Empty, "Must set sources before parsing."); for (auto source: _sources) m_sources[source.first].charStream = std::make_unique(/*content*/std::move(source.second), /*name*/source.first); m_stackState = SourcesSet; @@ -355,8 +340,7 @@ void CompilerStack::setSources(StringMap _sources) bool CompilerStack::parse() { - if (m_stackState != SourcesSet) - solThrow(CompilerError, "Must call parse only after the SourcesSet state."); + solAssert(m_stackState == SourcesSet, "Must call parse only after the SourcesSet state."); m_errorReporter.clear(); if (SemVerVersion{std::string(VersionString)}.isPrerelease()) @@ -426,8 +410,7 @@ bool CompilerStack::parse() void CompilerStack::importASTs(std::map const& _sources) { - if (m_stackState != Empty) - solThrow(CompilerError, "Must call importASTs only before the SourcesSet state."); + solAssert(m_stackState == Empty, "Must call importASTs only before the SourcesSet state."); std::map> reconstructedSources = ASTJsonImporter(m_evmVersion).jsonToSourceUnit(_sources); for (auto& src: reconstructedSources) { @@ -450,8 +433,7 @@ void CompilerStack::importASTs(std::map const& _sources) bool CompilerStack::analyze() { - if (m_stackState != ParsedAndImported) - solThrow(CompilerError, "Must call analyze only after parsing was successful."); + solAssert(m_stackState == ParsedAndImported, "Must call analyze only after parsing was successful."); if (!resolveImports()) return false; @@ -797,8 +779,7 @@ void CompilerStack::link() std::vector CompilerStack::contractNames() const { - if (m_stackState < Parsed) - solThrow(CompilerError, "Parsing was not successful."); + solAssert(m_stackState >= Parsed, "Parsing was not successful."); std::vector contractNames; for (auto const& contract: m_contracts) contractNames.push_back(contract.first); @@ -807,8 +788,7 @@ std::vector CompilerStack::contractNames() const std::string const CompilerStack::lastContractName(std::optional const& _sourceName) const { - if (m_stackState < AnalysisSuccessful) - solThrow(CompilerError, "Parsing was not successful."); + solAssert(m_stackState >= AnalysisSuccessful, "Parsing was not successful."); // try to find some user-supplied contract std::string contractName; for (auto const& it: m_sources) @@ -820,8 +800,7 @@ std::string const CompilerStack::lastContractName(std::optional con evmasm::AssemblyItems const* CompilerStack::assemblyItems(std::string const& _contractName) const { - if (m_stackState != CompilationSuccessful) - solThrow(CompilerError, "Compilation was not successful."); + solAssert(m_stackState == CompilationSuccessful, "Compilation was not successful."); Contract const& currentContract = contract(_contractName); return currentContract.evmAssembly ? ¤tContract.evmAssembly->items() : nullptr; @@ -829,8 +808,7 @@ evmasm::AssemblyItems const* CompilerStack::assemblyItems(std::string const& _co evmasm::AssemblyItems const* CompilerStack::runtimeAssemblyItems(std::string const& _contractName) const { - if (m_stackState != CompilationSuccessful) - solThrow(CompilerError, "Compilation was not successful."); + solAssert(m_stackState == CompilationSuccessful, "Compilation was not successful."); Contract const& currentContract = contract(_contractName); return currentContract.evmRuntimeAssembly ? ¤tContract.evmRuntimeAssembly->items() : nullptr; @@ -838,8 +816,7 @@ evmasm::AssemblyItems const* CompilerStack::runtimeAssemblyItems(std::string con Json CompilerStack::generatedSources(std::string const& _contractName, bool _runtime) const { - if (m_stackState != CompilationSuccessful) - solThrow(CompilerError, "Compilation was not successful."); + solAssert(m_stackState == CompilationSuccessful, "Compilation was not successful."); Contract const& c = contract(_contractName); util::LazyInit const& sources = @@ -880,8 +857,7 @@ Json CompilerStack::generatedSources(std::string const& _contractName, bool _run std::string const* CompilerStack::sourceMapping(std::string const& _contractName) const { - if (m_stackState != CompilationSuccessful) - solThrow(CompilerError, "Compilation was not successful."); + solAssert(m_stackState == CompilationSuccessful, "Compilation was not successful."); Contract const& c = contract(_contractName); if (!c.sourceMapping) @@ -894,8 +870,7 @@ std::string const* CompilerStack::sourceMapping(std::string const& _contractName std::string const* CompilerStack::runtimeSourceMapping(std::string const& _contractName) const { - if (m_stackState != CompilationSuccessful) - solThrow(CompilerError, "Compilation was not successful."); + solAssert(m_stackState == CompilationSuccessful, "Compilation was not successful."); Contract const& c = contract(_contractName); if (!c.runtimeSourceMapping) @@ -910,8 +885,7 @@ std::string const* CompilerStack::runtimeSourceMapping(std::string const& _contr std::string const CompilerStack::filesystemFriendlyName(std::string const& _contractName) const { - if (m_stackState < AnalysisSuccessful) - solThrow(CompilerError, "No compiled contracts found."); + solAssert(m_stackState >= AnalysisSuccessful, "No compiled contracts found."); // Look up the contract (by its fully-qualified name) Contract const& matchContract = m_contracts.at(_contractName); @@ -934,61 +908,46 @@ std::string const CompilerStack::filesystemFriendlyName(std::string const& _cont std::string const& CompilerStack::yulIR(std::string const& _contractName) const { - if (m_stackState != CompilationSuccessful) - solThrow(CompilerError, "Compilation was not successful."); - + solAssert(m_stackState == CompilationSuccessful, "Compilation was not successful."); return contract(_contractName).yulIR; } Json const& CompilerStack::yulIRAst(std::string const& _contractName) const { - if (m_stackState != CompilationSuccessful) - solThrow(CompilerError, "Compilation was not successful."); - + solAssert(m_stackState == CompilationSuccessful, "Compilation was not successful."); solUnimplementedAssert(!isExperimentalSolidity()); - return contract(_contractName).yulIRAst; } std::string const& CompilerStack::yulIROptimized(std::string const& _contractName) const { - if (m_stackState != CompilationSuccessful) - solThrow(CompilerError, "Compilation was not successful."); - + solAssert(m_stackState == CompilationSuccessful, "Compilation was not successful."); return contract(_contractName).yulIROptimized; } Json const& CompilerStack::yulIROptimizedAst(std::string const& _contractName) const { - if (m_stackState != CompilationSuccessful) - solThrow(CompilerError, "Compilation was not successful."); - + solAssert(m_stackState == CompilationSuccessful, "Compilation was not successful."); solUnimplementedAssert(!isExperimentalSolidity()); - return contract(_contractName).yulIROptimizedAst; } evmasm::LinkerObject const& CompilerStack::object(std::string const& _contractName) const { - if (m_stackState != CompilationSuccessful) - solThrow(CompilerError, "Compilation was not successful."); - + solAssert(m_stackState == CompilationSuccessful, "Compilation was not successful."); return contract(_contractName).object; } evmasm::LinkerObject const& CompilerStack::runtimeObject(std::string const& _contractName) const { - if (m_stackState != CompilationSuccessful) - solThrow(CompilerError, "Compilation was not successful."); - + solAssert(m_stackState == CompilationSuccessful, "Compilation was not successful."); return contract(_contractName).runtimeObject; } /// TODO: cache this string std::string CompilerStack::assemblyString(std::string const& _contractName, StringMap const& _sourceCodes) const { - if (m_stackState != CompilationSuccessful) - solThrow(CompilerError, "Compilation was not successful."); + solAssert(m_stackState == CompilationSuccessful, "Compilation was not successful."); Contract const& currentContract = contract(_contractName); if (currentContract.evmAssembly) @@ -1000,9 +959,7 @@ std::string CompilerStack::assemblyString(std::string const& _contractName, Stri /// TODO: cache the JSON Json CompilerStack::assemblyJSON(std::string const& _contractName) const { - if (m_stackState != CompilationSuccessful) - solThrow(CompilerError, "Compilation was not successful."); - + solAssert(m_stackState == CompilationSuccessful, "Compilation was not successful."); solUnimplementedAssert(!isExperimentalSolidity()); Contract const& currentContract = contract(_contractName); @@ -1030,37 +987,28 @@ std::map CompilerStack::sourceIndices() const Json const& CompilerStack::contractABI(std::string const& _contractName) const { - if (m_stackState < AnalysisSuccessful) - solThrow(CompilerError, "Analysis was not successful."); - + solAssert(m_stackState >= AnalysisSuccessful, "Analysis was not successful."); return contractABI(contract(_contractName)); } Json const& CompilerStack::contractABI(Contract const& _contract) const { - if (m_stackState < AnalysisSuccessful) - solThrow(CompilerError, "Analysis was not successful."); - - solAssert(_contract.contract, ""); + solAssert(m_stackState >= AnalysisSuccessful, "Analysis was not successful."); + solAssert(_contract.contract); solUnimplementedAssert(!isExperimentalSolidity()); - return _contract.abi.init([&]{ return ABI::generate(*_contract.contract); }); } Json const& CompilerStack::storageLayout(std::string const& _contractName) const { - if (m_stackState < AnalysisSuccessful) - solThrow(CompilerError, "Analysis was not successful."); - + solAssert(m_stackState >= AnalysisSuccessful, "Analysis was not successful."); return storageLayout(contract(_contractName)); } Json const& CompilerStack::storageLayout(Contract const& _contract) const { - if (m_stackState < AnalysisSuccessful) - solThrow(CompilerError, "Analysis was not successful."); - - solAssert(_contract.contract, ""); + solAssert(m_stackState >= AnalysisSuccessful, "Analysis was not successful."); + solAssert(_contract.contract); solUnimplementedAssert(!isExperimentalSolidity()); return _contract.storageLayout.init([&]{ return StorageLayout().generate(*_contract.contract); }); @@ -1068,48 +1016,35 @@ Json const& CompilerStack::storageLayout(Contract const& _contract) const Json const& CompilerStack::natspecUser(std::string const& _contractName) const { - if (m_stackState < AnalysisSuccessful) - solThrow(CompilerError, "Analysis was not successful."); - + solAssert(m_stackState >= AnalysisSuccessful, "Analysis was not successful."); return natspecUser(contract(_contractName)); } Json const& CompilerStack::natspecUser(Contract const& _contract) const { - if (m_stackState < AnalysisSuccessful) - solThrow(CompilerError, "Analysis was not successful."); - - solAssert(_contract.contract, ""); + solAssert(m_stackState >= AnalysisSuccessful, "Analysis was not successful."); + solAssert(_contract.contract); solUnimplementedAssert(!isExperimentalSolidity()); - return _contract.userDocumentation.init([&]{ return Natspec::userDocumentation(*_contract.contract); }); } Json const& CompilerStack::natspecDev(std::string const& _contractName) const { - if (m_stackState < AnalysisSuccessful) - solThrow(CompilerError, "Analysis was not successful."); - + solAssert(m_stackState >= AnalysisSuccessful, "Analysis was not successful."); return natspecDev(contract(_contractName)); } Json const& CompilerStack::natspecDev(Contract const& _contract) const { - if (m_stackState < AnalysisSuccessful) - solThrow(CompilerError, "Analysis was not successful."); - - solAssert(_contract.contract, ""); - + solAssert(m_stackState >= AnalysisSuccessful, "Analysis was not successful."); + solAssert(_contract.contract); solUnimplementedAssert(!isExperimentalSolidity()); - return _contract.devDocumentation.init([&]{ return Natspec::devDocumentation(*_contract.contract); }); } Json CompilerStack::interfaceSymbols(std::string const& _contractName) const { - if (m_stackState < AnalysisSuccessful) - solThrow(CompilerError, "Analysis was not successful."); - + solAssert(m_stackState >= AnalysisSuccessful, "Analysis was not successful."); solUnimplementedAssert(!isExperimentalSolidity()); Json interfaceSymbols; @@ -1139,50 +1074,36 @@ Json CompilerStack::interfaceSymbols(std::string const& _contractName) const bytes CompilerStack::cborMetadata(std::string const& _contractName, bool _forIR) const { - if (m_stackState < AnalysisSuccessful) - solThrow(CompilerError, "Analysis was not successful."); - + solAssert(m_stackState >= AnalysisSuccessful, "Analysis was not successful."); return createCBORMetadata(contract(_contractName), _forIR); } std::string const& CompilerStack::metadata(Contract const& _contract) const { - if (m_stackState < AnalysisSuccessful) - solThrow(CompilerError, "Analysis was not successful."); - - solAssert(_contract.contract, ""); - + solAssert(m_stackState >= AnalysisSuccessful, "Analysis was not successful."); + solAssert(_contract.contract); solUnimplementedAssert(!isExperimentalSolidity()); - return _contract.metadata.init([&]{ return createMetadata(_contract, m_viaIR); }); } CharStream const& CompilerStack::charStream(std::string const& _sourceName) const { - if (m_stackState < SourcesSet) - solThrow(CompilerError, "No sources set."); - - solAssert(source(_sourceName).charStream, ""); - + solAssert(m_stackState >= SourcesSet, "No sources set."); + solAssert(source(_sourceName).charStream); return *source(_sourceName).charStream; } SourceUnit const& CompilerStack::ast(std::string const& _sourceName) const { - if (m_stackState < Parsed) - solThrow(CompilerError, "Parsing not yet performed."); - if (!source(_sourceName).ast) - solThrow(CompilerError, "Parsing was not successful."); - + solAssert(m_stackState >= Parsed, "Parsing not yet performed."); + solAssert(source(_sourceName).ast, "Parsing was not successful."); solUnimplementedAssert(!isExperimentalSolidity()); - return *source(_sourceName).ast; } ContractDefinition const& CompilerStack::contractDefinition(std::string const& _contractName) const { - if (m_stackState < AnalysisSuccessful) - solThrow(CompilerError, "Analysis was not successful."); + solAssert(m_stackState >= AnalysisSuccessful, "Analysis was not successful."); return *contract(_contractName).contract; } @@ -1192,8 +1113,7 @@ size_t CompilerStack::functionEntryPoint( FunctionDefinition const& _function ) const { - if (m_stackState != CompilationSuccessful) - solThrow(CompilerError, "Compilation was not successful."); + solAssert(m_stackState == CompilationSuccessful, "Compilation was not successful."); for (auto&& [name, data]: contract(_contractName).runtimeObject.functionDebugData) if (data.sourceID == _function.id()) @@ -1629,14 +1549,13 @@ CompilerStack::Contract const& CompilerStack::contract(std::string const& _contr } // If we get here, both lookup methods failed. - solThrow(CompilerError, "Contract \"" + _contractName + "\" not found."); + solAssert(false, "Contract \"" + _contractName + "\" not found."); } CompilerStack::Source const& CompilerStack::source(std::string const& _sourceName) const { auto it = m_sources.find(_sourceName); - if (it == m_sources.end()) - solThrow(CompilerError, "Given source file not found: " + _sourceName); + solAssert(it != m_sources.end(), "Given source file not found: " + _sourceName); return it->second; } @@ -1902,9 +1821,7 @@ Json gasToJson(GasEstimator::GasConsumption const& _gas) Json CompilerStack::gasEstimates(std::string const& _contractName) const { - if (m_stackState != CompilationSuccessful) - solThrow(CompilerError, "Compilation was not successful."); - + solAssert(m_stackState == CompilationSuccessful, "Compilation was not successful."); solUnimplementedAssert(!isExperimentalSolidity()); if (!assemblyItems(_contractName) && !runtimeAssemblyItems(_contractName)) From 12e8b0cda911ed4661773ee6cd9a2e341d8a77ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Thu, 6 Jun 2024 20:00:41 +0200 Subject: [PATCH 0257/1022] Use solAssert() instead of throwing InternalCompilerError directly --- libsolidity/codegen/ExpressionCompiler.cpp | 4 +--- libsolidity/codegen/LValue.cpp | 5 +---- libsolidity/interface/FileReader.cpp | 1 - libsolidity/interface/SMTSolverCommand.cpp | 4 ---- libsolidity/interface/StandardCompiler.cpp | 9 ++------- 5 files changed, 4 insertions(+), 19 deletions(-) diff --git a/libsolidity/codegen/ExpressionCompiler.cpp b/libsolidity/codegen/ExpressionCompiler.cpp index 54090f960437..c7bc9a8263f5 100644 --- a/libsolidity/codegen/ExpressionCompiler.cpp +++ b/libsolidity/codegen/ExpressionCompiler.cpp @@ -2952,9 +2952,7 @@ void ExpressionCompiler::setLValueFromDeclaration(Declaration const& _declaratio else if (m_context.isStateVariable(&_declaration)) setLValue(_expression, dynamic_cast(_declaration)); else - BOOST_THROW_EXCEPTION(InternalCompilerError() - << errinfo_sourceLocation(_expression.location()) - << util::errinfo_comment("Identifier type not supported or identifier not found.")); + solAssert(false, "Identifier type not supported or identifier not found."); } void ExpressionCompiler::setLValueToStorageItem(Expression const& _expression) diff --git a/libsolidity/codegen/LValue.cpp b/libsolidity/codegen/LValue.cpp index 3fbf10383499..4847cb09388c 100644 --- a/libsolidity/codegen/LValue.cpp +++ b/libsolidity/codegen/LValue.cpp @@ -441,10 +441,7 @@ void StorageItem::storeValue(Type const& _sourceType, SourceLocation const& _loc m_context << Instruction::SWAP1 << Instruction::POP; } else - BOOST_THROW_EXCEPTION( - InternalCompilerError() - << errinfo_sourceLocation(_location) - << util::errinfo_comment("Invalid non-value type for assignment.")); + solAssert(false, "Invalid non-value type for assignment."); } } diff --git a/libsolidity/interface/FileReader.cpp b/libsolidity/interface/FileReader.cpp index 158d4dd2c95c..15181acf607b 100644 --- a/libsolidity/interface/FileReader.cpp +++ b/libsolidity/interface/FileReader.cpp @@ -31,7 +31,6 @@ #include using solidity::frontend::ReadCallback; -using solidity::langutil::InternalCompilerError; using solidity::util::errinfo_comment; using solidity::util::readFileAsString; using solidity::util::joinHumanReadable; diff --git a/libsolidity/interface/SMTSolverCommand.cpp b/libsolidity/interface/SMTSolverCommand.cpp index b9eb392c635b..75f541692ddc 100644 --- a/libsolidity/interface/SMTSolverCommand.cpp +++ b/libsolidity/interface/SMTSolverCommand.cpp @@ -30,10 +30,6 @@ #include #include -using solidity::langutil::InternalCompilerError; -using solidity::util::errinfo_comment; - - namespace solidity::frontend { diff --git a/libsolidity/interface/StandardCompiler.cpp b/libsolidity/interface/StandardCompiler.cpp index a54a9aa10720..2b36f9032349 100644 --- a/libsolidity/interface/StandardCompiler.cpp +++ b/libsolidity/interface/StandardCompiler.cpp @@ -1463,13 +1463,8 @@ Json StandardCompiler::compileSolidity(StandardCompiler::InputsAndSettings _inpu // Note that not completing analysis due to stopAfter does not count as a failure. It's neither failure nor success. bool analysisFailed = !analysisSuccess && _inputsAndSettings.stopAfter >= CompilerStack::State::AnalysisSuccessful; bool compilationFailed = !compilationSuccess && binariesRequested; - - /// Inconsistent state - stop here to receive error reports from users - if ( - (compilationFailed || analysisFailed || !parsingSuccess) && - errors.empty() - ) - return formatFatalError(Error::Type::InternalCompilerError, "No error reported, but compilation failed."); + if (compilationFailed || analysisFailed || !parsingSuccess) + solAssert(!errors.empty(), "No error reported, but compilation failed."); Json output; From 8d561e36aa1b7c1bb1965c8873657615daf87dab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Thu, 6 Jun 2024 19:17:28 +0200 Subject: [PATCH 0258/1022] Assert presence of errors in case of FatalError instead of rethrowing --- libsolidity/analysis/NameAndTypeResolver.cpp | 16 +- libsolidity/interface/CompilerStack.cpp | 9 +- libsolidity/parsing/Parser.cpp | 5 +- libyul/AsmAnalysis.cpp | 9 +- libyul/AsmParser.cpp | 5 +- libyul/ObjectParser.cpp | 6 +- .../more_than_256_analysis_errors.yul | 279 ++++++++++++++++++ 7 files changed, 304 insertions(+), 25 deletions(-) create mode 100644 test/libyul/yulSyntaxTests/more_than_256_analysis_errors.yul diff --git a/libsolidity/analysis/NameAndTypeResolver.cpp b/libsolidity/analysis/NameAndTypeResolver.cpp index 642e87a53b3e..941fbca9bdb1 100644 --- a/libsolidity/analysis/NameAndTypeResolver.cpp +++ b/libsolidity/analysis/NameAndTypeResolver.cpp @@ -30,6 +30,7 @@ #include #include +using namespace std::string_literals; using namespace solidity::langutil; namespace solidity::frontend @@ -60,10 +61,9 @@ bool NameAndTypeResolver::registerDeclarations(SourceUnit& _sourceUnit, ASTNode { DeclarationRegistrationHelper registrar(m_scopes, _sourceUnit, m_errorReporter, m_globalContext, _currentScope); } - catch (langutil::FatalError const&) + catch (langutil::FatalError const& error) { - if (m_errorReporter.errors().empty()) - throw; // Something is weird here, rather throw again. + solAssert(!m_errorReporter.errors().empty(), "Unreported fatal error: "s + error.what()); return false; } return true; @@ -135,10 +135,9 @@ bool NameAndTypeResolver::resolveNamesAndTypes(SourceUnit& _source) return false; } } - catch (langutil::FatalError const&) + catch (langutil::FatalError const& error) { - if (m_errorReporter.errors().empty()) - throw; // Something is weird here, rather throw again. + solAssert(!m_errorReporter.errors().empty(), "Unreported fatal error: "s + error.what()); return false; } return true; @@ -151,10 +150,9 @@ bool NameAndTypeResolver::updateDeclaration(Declaration const& _declaration) m_scopes[nullptr]->registerDeclaration(_declaration, false, true); solAssert(_declaration.scope() == nullptr, "Updated declaration outside global scope."); } - catch (langutil::FatalError const&) + catch (langutil::FatalError const& error) { - if (m_errorReporter.errors().empty()) - throw; // Something is weird here, rather throw again. + solAssert(!m_errorReporter.errors().empty(), "Unreported fatal error: "s + error.what()); return false; } return true; diff --git a/libsolidity/interface/CompilerStack.cpp b/libsolidity/interface/CompilerStack.cpp index a07310e2c9d1..89a7a441a591 100644 --- a/libsolidity/interface/CompilerStack.cpp +++ b/libsolidity/interface/CompilerStack.cpp @@ -489,10 +489,9 @@ bool CompilerStack::analyze() else if (!analyzeLegacy(noErrors)) noErrors = false; } - catch (FatalError const&) + catch (FatalError const& error) { - if (m_errorReporter.errors().empty()) - throw; // Something is weird here, rather throw again. + solAssert(!m_errorReporter.errors().empty(), "Unreported fatal error: "s + error.what()); noErrors = false; } @@ -1174,9 +1173,9 @@ StringMap CompilerStack::loadMissingSources(SourceUnit const& _ast) } } } - catch (FatalError const&) + catch (FatalError const& error) { - solAssert(m_errorReporter.hasErrors(), ""); + solAssert(!m_errorReporter.errors().empty(), "Unreported fatal error: "s + error.what()); } return newSources; } diff --git a/libsolidity/parsing/Parser.cpp b/libsolidity/parsing/Parser.cpp index f650e0dbf1dc..15a84c3f497c 100644 --- a/libsolidity/parsing/Parser.cpp +++ b/libsolidity/parsing/Parser.cpp @@ -176,10 +176,9 @@ ASTPointer Parser::parse(CharStream& _charStream) solAssert(m_recursionDepth == 0, ""); return nodeFactory.createNode(findLicenseString(nodes), nodes, m_experimentalSolidityEnabledInCurrentSourceUnit); } - catch (FatalError const&) + catch (FatalError const& error) { - if (m_errorReporter.errors().empty()) - throw; // Something is weird here, rather throw again. + solAssert(!m_errorReporter.errors().empty(), "Unreported fatal error: "s + error.what()); return nullptr; } } diff --git a/libyul/AsmAnalysis.cpp b/libyul/AsmAnalysis.cpp index 1972d2674516..f85ef95442bd 100644 --- a/libyul/AsmAnalysis.cpp +++ b/libyul/AsmAnalysis.cpp @@ -74,10 +74,13 @@ bool AsmAnalyzer::analyze(Block const& _block) (*this)(_block); } - catch (FatalError const&) + catch (FatalError const& error) { - // This FatalError con occur if the errorReporter has too many errors. - yulAssert(!watcher.ok(), "Fatal error detected, but no error is reported."); + // NOTE: There's a cap on the number of reported errors, but watcher.ok() will work fine even if + // we exceed it because the reporter keeps counting (it just stops adding errors to the list). + // Note also that fact of exceeding the cap triggers a FatalError so one can get thrown even + // if we don't make any of our errors fatal. + yulAssert(!watcher.ok(), "Unreported fatal error: "s + error.what()); } return watcher.ok(); } diff --git a/libyul/AsmParser.cpp b/libyul/AsmParser.cpp index 3635b096af99..7af648a36bbe 100644 --- a/libyul/AsmParser.cpp +++ b/libyul/AsmParser.cpp @@ -37,6 +37,7 @@ #include #include +using namespace std::string_literals; using namespace solidity; using namespace solidity::util; using namespace solidity::langutil; @@ -126,9 +127,9 @@ std::unique_ptr Parser::parseInline(std::shared_ptr const& _scan fetchDebugDataFromComment(); return std::make_unique(parseBlock()); } - catch (FatalError const&) + catch (FatalError const& error) { - yulAssert(!m_errorReporter.errors().empty(), "Fatal error detected, but no error is reported."); + yulAssert(!m_errorReporter.errors().empty(), "Unreported fatal error: "s + error.what()); } return nullptr; diff --git a/libyul/ObjectParser.cpp b/libyul/ObjectParser.cpp index 2038959de4fa..d0519be0ef35 100644 --- a/libyul/ObjectParser.cpp +++ b/libyul/ObjectParser.cpp @@ -32,6 +32,7 @@ #include +using namespace std::string_literals; using namespace solidity; using namespace solidity::yul; using namespace solidity::util; @@ -62,10 +63,9 @@ std::shared_ptr ObjectParser::parse(std::shared_ptr const& _sca expectToken(Token::EOS); return object; } - catch (FatalError const&) + catch (FatalError const& error) { - if (m_errorReporter.errors().empty()) - throw; // Something is weird here, rather throw again. + yulAssert(!m_errorReporter.errors().empty(), "Unreported fatal error: "s + error.what()); } return nullptr; } diff --git a/test/libyul/yulSyntaxTests/more_than_256_analysis_errors.yul b/test/libyul/yulSyntaxTests/more_than_256_analysis_errors.yul new file mode 100644 index 000000000000..0ae2fb15a730 --- /dev/null +++ b/test/libyul/yulSyntaxTests/more_than_256_analysis_errors.yul @@ -0,0 +1,279 @@ +{ + // There's no type called 'x' so every declaration here should trigger an error. + // It's only detected during analysis and is not fatal. Any other non-fatal analysis error would do. + let $00:x let $10:x let $20:x let $30:x let $40:x let $50:x let $60:x let $70:x let $80:x let $90:x let $a0:x let $b0:x let $c0:x let $d0:x let $e0:x let $f0:x + let $01:x let $11:x let $21:x let $31:x let $41:x let $51:x let $61:x let $71:x let $81:x let $91:x let $a1:x let $b1:x let $c1:x let $d1:x let $e1:x let $f1:x + let $02:x let $12:x let $22:x let $32:x let $42:x let $52:x let $62:x let $72:x let $82:x let $92:x let $a2:x let $b2:x let $c2:x let $d2:x let $e2:x let $f2:x + let $03:x let $13:x let $23:x let $33:x let $43:x let $53:x let $63:x let $73:x let $83:x let $93:x let $a3:x let $b3:x let $c3:x let $d3:x let $e3:x let $f3:x + let $04:x let $14:x let $24:x let $34:x let $44:x let $54:x let $64:x let $74:x let $84:x let $94:x let $a4:x let $b4:x let $c4:x let $d4:x let $e4:x let $f4:x + let $05:x let $15:x let $25:x let $35:x let $45:x let $55:x let $65:x let $75:x let $85:x let $95:x let $a5:x let $b5:x let $c5:x let $d5:x let $e5:x let $f5:x + let $06:x let $16:x let $26:x let $36:x let $46:x let $56:x let $66:x let $76:x let $86:x let $96:x let $a6:x let $b6:x let $c6:x let $d6:x let $e6:x let $f6:x + let $07:x let $17:x let $27:x let $37:x let $47:x let $57:x let $67:x let $77:x let $87:x let $97:x let $a7:x let $b7:x let $c7:x let $d7:x let $e7:x let $f7:x + let $08:x let $18:x let $28:x let $38:x let $48:x let $58:x let $68:x let $78:x let $88:x let $98:x let $a8:x let $b8:x let $c8:x let $d8:x let $e8:x let $f8:x + let $09:x let $19:x let $29:x let $39:x let $49:x let $59:x let $69:x let $79:x let $89:x let $99:x let $a9:x let $b9:x let $c9:x let $d9:x let $e9:x let $f9:x + let $0a:x let $1a:x let $2a:x let $3a:x let $4a:x let $5a:x let $6a:x let $7a:x let $8a:x let $9a:x let $aa:x let $ba:x let $ca:x let $da:x let $ea:x let $fa:x + let $0b:x let $1b:x let $2b:x let $3b:x let $4b:x let $5b:x let $6b:x let $7b:x let $8b:x let $9b:x let $ab:x let $bb:x let $cb:x let $db:x let $eb:x let $fb:x + let $0c:x let $1c:x let $2c:x let $3c:x let $4c:x let $5c:x let $6c:x let $7c:x let $8c:x let $9c:x let $ac:x let $bc:x let $cc:x let $dc:x let $ec:x let $fc:x + let $0d:x let $1d:x let $2d:x let $3d:x let $4d:x let $5d:x let $6d:x let $7d:x let $8d:x let $9d:x let $ad:x let $bd:x let $cd:x let $dd:x let $ed:x let $fd:x + let $0e:x let $1e:x let $2e:x let $3e:x let $4e:x let $5e:x let $6e:x let $7e:x let $8e:x let $9e:x let $ae:x let $be:x let $ce:x let $de:x let $ee:x let $fe:x + let $0f:x let $1f:x let $2f:x let $3f:x let $4f:x let $5f:x let $6f:x let $7f:x let $8f:x let $9f:x let $af:x let $bf:x let $cf:x let $df:x let $ef:x let $ff:x + let $100:x +} +// ---- +// TypeError 5473: (200-205): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (210-215): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (220-225): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (230-235): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (240-245): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (250-255): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (260-265): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (270-275): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (280-285): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (290-295): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (300-305): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (310-315): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (320-325): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (330-335): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (340-345): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (350-355): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (364-369): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (374-379): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (384-389): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (394-399): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (404-409): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (414-419): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (424-429): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (434-439): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (444-449): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (454-459): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (464-469): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (474-479): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (484-489): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (494-499): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (504-509): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (514-519): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (528-533): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (538-543): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (548-553): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (558-563): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (568-573): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (578-583): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (588-593): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (598-603): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (608-613): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (618-623): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (628-633): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (638-643): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (648-653): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (658-663): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (668-673): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (678-683): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (692-697): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (702-707): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (712-717): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (722-727): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (732-737): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (742-747): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (752-757): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (762-767): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (772-777): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (782-787): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (792-797): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (802-807): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (812-817): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (822-827): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (832-837): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (842-847): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (856-861): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (866-871): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (876-881): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (886-891): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (896-901): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (906-911): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (916-921): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (926-931): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (936-941): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (946-951): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (956-961): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (966-971): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (976-981): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (986-991): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (996-1001): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (1006-1011): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (1020-1025): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (1030-1035): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (1040-1045): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (1050-1055): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (1060-1065): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (1070-1075): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (1080-1085): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (1090-1095): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (1100-1105): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (1110-1115): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (1120-1125): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (1130-1135): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (1140-1145): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (1150-1155): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (1160-1165): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (1170-1175): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (1184-1189): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (1194-1199): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (1204-1209): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (1214-1219): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (1224-1229): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (1234-1239): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (1244-1249): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (1254-1259): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (1264-1269): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (1274-1279): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (1284-1289): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (1294-1299): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (1304-1309): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (1314-1319): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (1324-1329): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (1334-1339): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (1348-1353): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (1358-1363): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (1368-1373): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (1378-1383): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (1388-1393): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (1398-1403): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (1408-1413): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (1418-1423): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (1428-1433): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (1438-1443): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (1448-1453): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (1458-1463): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (1468-1473): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (1478-1483): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (1488-1493): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (1498-1503): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (1512-1517): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (1522-1527): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (1532-1537): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (1542-1547): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (1552-1557): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (1562-1567): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (1572-1577): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (1582-1587): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (1592-1597): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (1602-1607): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (1612-1617): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (1622-1627): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (1632-1637): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (1642-1647): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (1652-1657): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (1662-1667): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (1676-1681): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (1686-1691): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (1696-1701): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (1706-1711): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (1716-1721): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (1726-1731): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (1736-1741): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (1746-1751): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (1756-1761): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (1766-1771): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (1776-1781): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (1786-1791): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (1796-1801): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (1806-1811): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (1816-1821): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (1826-1831): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (1840-1845): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (1850-1855): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (1860-1865): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (1870-1875): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (1880-1885): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (1890-1895): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (1900-1905): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (1910-1915): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (1920-1925): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (1930-1935): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (1940-1945): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (1950-1955): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (1960-1965): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (1970-1975): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (1980-1985): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (1990-1995): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (2004-2009): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (2014-2019): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (2024-2029): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (2034-2039): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (2044-2049): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (2054-2059): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (2064-2069): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (2074-2079): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (2084-2089): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (2094-2099): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (2104-2109): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (2114-2119): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (2124-2129): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (2134-2139): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (2144-2149): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (2154-2159): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (2168-2173): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (2178-2183): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (2188-2193): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (2198-2203): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (2208-2213): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (2218-2223): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (2228-2233): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (2238-2243): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (2248-2253): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (2258-2263): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (2268-2273): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (2278-2283): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (2288-2293): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (2298-2303): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (2308-2313): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (2318-2323): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (2332-2337): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (2342-2347): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (2352-2357): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (2362-2367): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (2372-2377): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (2382-2387): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (2392-2397): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (2402-2407): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (2412-2417): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (2422-2427): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (2432-2437): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (2442-2447): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (2452-2457): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (2462-2467): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (2472-2477): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (2482-2487): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (2496-2501): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (2506-2511): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (2516-2521): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (2526-2531): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (2536-2541): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (2546-2551): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (2556-2561): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (2566-2571): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (2576-2581): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (2586-2591): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (2596-2601): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (2606-2611): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (2616-2621): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (2626-2631): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (2636-2641): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (2646-2651): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (2660-2665): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (2670-2675): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (2680-2685): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (2690-2695): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (2700-2705): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (2710-2715): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (2720-2725): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (2730-2735): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (2740-2745): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (2750-2755): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (2760-2765): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (2770-2775): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (2780-2785): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (2790-2795): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (2800-2805): "x" is not a valid type (user defined types are not yet supported). +// TypeError 5473: (2810-2815): "x" is not a valid type (user defined types are not yet supported). +// Warning 4013: There are more than 256 errors. Aborting. From 2694190d1dbbc90b001aa76f8d7bd0794923c343 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Thu, 13 Jun 2024 19:32:29 +0200 Subject: [PATCH 0259/1022] Ignore warnings and infos when checking if FatalError was reported --- libsolidity/analysis/NameAndTypeResolver.cpp | 6 +++--- libsolidity/interface/CompilerStack.cpp | 4 ++-- libsolidity/parsing/Parser.cpp | 2 +- libyul/AsmParser.cpp | 2 +- libyul/ObjectParser.cpp | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/libsolidity/analysis/NameAndTypeResolver.cpp b/libsolidity/analysis/NameAndTypeResolver.cpp index 941fbca9bdb1..32ef6d476b22 100644 --- a/libsolidity/analysis/NameAndTypeResolver.cpp +++ b/libsolidity/analysis/NameAndTypeResolver.cpp @@ -63,7 +63,7 @@ bool NameAndTypeResolver::registerDeclarations(SourceUnit& _sourceUnit, ASTNode } catch (langutil::FatalError const& error) { - solAssert(!m_errorReporter.errors().empty(), "Unreported fatal error: "s + error.what()); + solAssert(m_errorReporter.hasErrors(), "Unreported fatal error: "s + error.what()); return false; } return true; @@ -137,7 +137,7 @@ bool NameAndTypeResolver::resolveNamesAndTypes(SourceUnit& _source) } catch (langutil::FatalError const& error) { - solAssert(!m_errorReporter.errors().empty(), "Unreported fatal error: "s + error.what()); + solAssert(m_errorReporter.hasErrors(), "Unreported fatal error: "s + error.what()); return false; } return true; @@ -152,7 +152,7 @@ bool NameAndTypeResolver::updateDeclaration(Declaration const& _declaration) } catch (langutil::FatalError const& error) { - solAssert(!m_errorReporter.errors().empty(), "Unreported fatal error: "s + error.what()); + solAssert(m_errorReporter.hasErrors(), "Unreported fatal error: "s + error.what()); return false; } return true; diff --git a/libsolidity/interface/CompilerStack.cpp b/libsolidity/interface/CompilerStack.cpp index 89a7a441a591..2299155383c0 100644 --- a/libsolidity/interface/CompilerStack.cpp +++ b/libsolidity/interface/CompilerStack.cpp @@ -491,7 +491,7 @@ bool CompilerStack::analyze() } catch (FatalError const& error) { - solAssert(!m_errorReporter.errors().empty(), "Unreported fatal error: "s + error.what()); + solAssert(m_errorReporter.hasErrors(), "Unreported fatal error: "s + error.what()); noErrors = false; } @@ -1175,7 +1175,7 @@ StringMap CompilerStack::loadMissingSources(SourceUnit const& _ast) } catch (FatalError const& error) { - solAssert(!m_errorReporter.errors().empty(), "Unreported fatal error: "s + error.what()); + solAssert(m_errorReporter.hasErrors(), "Unreported fatal error: "s + error.what()); } return newSources; } diff --git a/libsolidity/parsing/Parser.cpp b/libsolidity/parsing/Parser.cpp index 15a84c3f497c..7e2fe030af2c 100644 --- a/libsolidity/parsing/Parser.cpp +++ b/libsolidity/parsing/Parser.cpp @@ -178,7 +178,7 @@ ASTPointer Parser::parse(CharStream& _charStream) } catch (FatalError const& error) { - solAssert(!m_errorReporter.errors().empty(), "Unreported fatal error: "s + error.what()); + solAssert(m_errorReporter.hasErrors(), "Unreported fatal error: "s + error.what()); return nullptr; } } diff --git a/libyul/AsmParser.cpp b/libyul/AsmParser.cpp index 7af648a36bbe..a009b005d6bd 100644 --- a/libyul/AsmParser.cpp +++ b/libyul/AsmParser.cpp @@ -129,7 +129,7 @@ std::unique_ptr Parser::parseInline(std::shared_ptr const& _scan } catch (FatalError const& error) { - yulAssert(!m_errorReporter.errors().empty(), "Unreported fatal error: "s + error.what()); + yulAssert(m_errorReporter.hasErrors(), "Unreported fatal error: "s + error.what()); } return nullptr; diff --git a/libyul/ObjectParser.cpp b/libyul/ObjectParser.cpp index d0519be0ef35..a02b9660b978 100644 --- a/libyul/ObjectParser.cpp +++ b/libyul/ObjectParser.cpp @@ -65,7 +65,7 @@ std::shared_ptr ObjectParser::parse(std::shared_ptr const& _sca } catch (FatalError const& error) { - yulAssert(!m_errorReporter.errors().empty(), "Unreported fatal error: "s + error.what()); + yulAssert(m_errorReporter.hasErrors(), "Unreported fatal error: "s + error.what()); } return nullptr; } From 1ca70c8dc089f6a84dea0d13d70934edd7e78789 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Thu, 6 Jun 2024 15:17:40 +0200 Subject: [PATCH 0260/1022] .gitignore: Mark directories as directories --- .gitignore | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.gitignore b/.gitignore index 8ca5f86e7e43..dc88e1c67e56 100644 --- a/.gitignore +++ b/.gitignore @@ -10,7 +10,7 @@ *.o *.obj *.pyc -__pycache__ +__pycache__/ # Precompiled Headers *.gch @@ -36,12 +36,12 @@ __pycache__ *.app # Build directory -/build* +/build*/ emscripten_build/ -/docs/_build +/docs/_build/ /docs/_static/robots.txt -/deps -/reports +/deps/ +/reports/ # vim stuff [._]*.sw[a-p] From e05c596bd5e931aa4e4c291b76a7765a1437c88f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Wed, 5 Jun 2024 14:47:28 +0200 Subject: [PATCH 0261/1022] Setup for benchmarking solc using external projects and foundry --- .gitignore | 3 + test/benchmarks/external-setup.sh | 113 ++++++++++++++++++++++++++++++ test/benchmarks/external.sh | 108 ++++++++++++++++++++++++++++ 3 files changed, 224 insertions(+) create mode 100755 test/benchmarks/external-setup.sh create mode 100755 test/benchmarks/external.sh diff --git a/.gitignore b/.gitignore index dc88e1c67e56..aafe93f97a0e 100644 --- a/.gitignore +++ b/.gitignore @@ -41,7 +41,10 @@ emscripten_build/ /docs/_build/ /docs/_static/robots.txt /deps/ + +# Reports and benchmarks /reports/ +/benchmarks/ # vim stuff [._]*.sw[a-p] diff --git a/test/benchmarks/external-setup.sh b/test/benchmarks/external-setup.sh new file mode 100755 index 000000000000..b995e8e9fdb0 --- /dev/null +++ b/test/benchmarks/external-setup.sh @@ -0,0 +1,113 @@ +#!/usr/bin/env bash + +#------------------------------------------------------------------------------ +# Downloads and configures external projects used for benchmarking by external.sh. +# +# By default the download location is the benchmarks/ dir at the repository root. +# A different directory can be provided via the BENCHMARK_DIR variable. +# +# Dependencies: foundry, git. +# ------------------------------------------------------------------------------ +# 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) 2024 solidity contributors. +#------------------------------------------------------------------------------ + +set -euo pipefail + +repo_root=$(cd "$(dirname "$0")/../../" && pwd) +BENCHMARK_DIR="${BENCHMARK_DIR:-${repo_root}/benchmarks}" + +function neutralize_version_pragmas { + find . -name '*.sol' -type f -print0 | xargs -0 \ + sed -i -E -e 's/pragma solidity [^;]+;/pragma solidity *;/' +} + +function neutralize_via_ir { + sed -i '/^via_ir\s*=.*$/d' foundry.toml +} + +mkdir -p "$BENCHMARK_DIR" +cd "$BENCHMARK_DIR" + +if [[ ! -e openzeppelin/ ]]; then + git clone --depth=1 https://github.com/OpenZeppelin/openzeppelin-contracts openzeppelin/ --branch v5.0.2 + pushd openzeppelin/ + forge install + neutralize_via_ir + popd +else + echo "Skipped openzeppelin/. Already exists." +fi + +if [[ ! -e uniswap-v4/ ]]; then + git clone --single-branch https://github.com/Uniswap/v4-core uniswap-v4/ + pushd uniswap-v4/ + git checkout d0700ceb251afa48df8cc26d593fe04ee5e6b775 # branch main as of 2024-05-10 + forge install + neutralize_via_ir + popd +else + echo "Skipped uniswap-v4/. Already exists." +fi + +if [[ ! -e seaport/ ]]; then + git clone --single-branch https://github.com/ProjectOpenSea/seaport + pushd seaport/ + # NOTE: Can't select the tag with `git clone` because a branch of the same name exists. + git checkout tags/1.6 + forge install + neutralize_via_ir + neutralize_version_pragmas + popd +else + echo "Skipped seaport/. Already exists." +fi + +if [[ ! -e eigenlayer/ ]]; then + git clone --depth=1 https://github.com/Layr-Labs/eigenlayer-contracts eigenlayer/ --branch v0.3.0-holesky-rewards + pushd eigenlayer/ + neutralize_via_ir + forge install + popd +else + echo "Skipped eigenlayer/. Already exists." +fi + +if [[ ! -e sablier-v2/ ]]; then + git clone --depth=1 https://github.com/sablier-labs/v2-core sablier-v2/ --branch v1.1.2 + pushd sablier-v2/ + # NOTE: To avoid hard-coding dependency versions here we'd have to install them from npm + forge install --no-commit \ + foundry-rs/forge-std@v1.5.6 \ + OpenZeppelin/openzeppelin-contracts@v4.9.2 \ + PaulRBerg/prb-math@v4.0.2 \ + PaulRBerg/prb-test@v0.6.4 \ + evmcheb/solarray@a547630 \ + Vectorized/solady@v0.0.129 + cat < remappings.txt +@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/ +forge-std/=lib/forge-std/ +@prb/math/=lib/prb-math/ +@prb/test/=lib/prb-test/ +solarray/=lib/solarray/ +solady/=lib/solady/ +EOF + neutralize_via_ir + popd +else + echo "Skipped sablier-v2/. Already exists." +fi diff --git a/test/benchmarks/external.sh b/test/benchmarks/external.sh new file mode 100755 index 000000000000..b37c9105d610 --- /dev/null +++ b/test/benchmarks/external.sh @@ -0,0 +1,108 @@ +#!/usr/bin/env bash + +#------------------------------------------------------------------------------ +# Benchmarks a solc binary by compiling several external projects, with and without IR. +# +# The script expects each project to be already downloaded and set up by external-setup.sh. +# A different directory can be provided via the BENCHMARK_DIR variable. +# +# The script will by default attempt to use a solc from the default build directory, +# relative to the script directory. To use a different binary you can provide a different +# location of the build directory (via SOLIDITY_BUILD_DIR variable) or simply specify +# the full path to the binary as the script argument. +# +# Dependencies: foundry, time. +# ------------------------------------------------------------------------------ +# 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) 2024 solidity contributors. +#------------------------------------------------------------------------------ + +set -euo pipefail + +repo_root=$(cd "$(dirname "$0")/../../" && pwd) +SOLIDITY_BUILD_DIR=${SOLIDITY_BUILD_DIR:-${repo_root}/build} +BENCHMARK_DIR="${BENCHMARK_DIR:-${repo_root}/benchmarks}" + +# shellcheck source=scripts/common.sh +source "${repo_root}/scripts/common.sh" +# shellcheck source=scripts/common_cmdline.sh +source "${repo_root}/scripts/common_cmdline.sh" + +(( $# <= 1 )) || fail "Too many arguments. Usage: external.sh []" + +solc="${1:-${SOLIDITY_BUILD_DIR}/solc/solc}" +command_available "$solc" --version + +function benchmark_project { + local pipeline="$1" + local project="$2" + [[ $pipeline == legacy || $pipeline == ir ]] || assertFail + + cd "$project" + local foundry_command=(forge build --use "$solc" --optimize --offline --no-cache) + [[ $pipeline == ir ]] && foundry_command+=(--via-ir) + local time_file="../time-and-status-${project}-${pipeline}.txt" + + # NOTE: The pipeline may fail with "Stack too deep" in some cases. That's fine. + # We note the exit code and will later show full output. + "$time_bin_path" \ + --output "$time_file" \ + --quiet \ + --format '%e s | %x' \ + "${foundry_command[@]}" \ + > /dev/null \ + 2> "../stderr-${project}-${pipeline}.log" || true + + printf '| %-20s | %8s | %21s |\n' \ + "$project" \ + "$pipeline" \ + "$(cat "$time_file")" + cd .. +} + +benchmarks=( + # Fastest ones first so that we get *some* output quickly + openzeppelin + uniswap-v4 + eigenlayer + seaport + sablier-v2 +) +time_bin_path=$(type -P time) + +mkdir -p "$BENCHMARK_DIR" +cd "$BENCHMARK_DIR" + +echo "| Project | Pipeline | Time | Exit code |" +echo "|----------------------|----------|----------:|----------:|" + +for project in "${benchmarks[@]}"; do + benchmark_project legacy "$project" + benchmark_project ir "$project" +done + +for project in "${benchmarks[@]}"; do + for pipeline in legacy ir; do + if [[ -s stderr-${project}-${pipeline}.log ]]; then + echo + echo "==================================" + echo "stderr for ${project} via ${pipeline}" + echo "==================================" + cat "stderr-${project}-${pipeline}.log" + fi + done +done From e1bc6cb95ba8c1786327a7d9e15090378be8160e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Thu, 6 Jun 2024 12:42:36 +0200 Subject: [PATCH 0262/1022] benchmarks: Update Uniswap to the latest revision --- test/benchmarks/external-setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/benchmarks/external-setup.sh b/test/benchmarks/external-setup.sh index b995e8e9fdb0..2316d83d586e 100755 --- a/test/benchmarks/external-setup.sh +++ b/test/benchmarks/external-setup.sh @@ -56,7 +56,7 @@ fi if [[ ! -e uniswap-v4/ ]]; then git clone --single-branch https://github.com/Uniswap/v4-core uniswap-v4/ pushd uniswap-v4/ - git checkout d0700ceb251afa48df8cc26d593fe04ee5e6b775 # branch main as of 2024-05-10 + git checkout ae86975b058d386c9be24e8994236f662affacdb # branch main as of 2024-06-06 forge install neutralize_via_ir popd From 732658fd59d7263a77b37abb2ba3f60f0ebc8834 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Thu, 6 Jun 2024 17:51:22 +0200 Subject: [PATCH 0263/1022] Rename benchmarks/run.sh to benchmarks/local.sh --- test/benchmarks/{run.sh => local.sh} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename test/benchmarks/{run.sh => local.sh} (97%) diff --git a/test/benchmarks/run.sh b/test/benchmarks/local.sh similarity index 97% rename from test/benchmarks/run.sh rename to test/benchmarks/local.sh index 1784b3700bde..9d4f498c1a98 100755 --- a/test/benchmarks/run.sh +++ b/test/benchmarks/local.sh @@ -31,7 +31,7 @@ source "${REPO_ROOT}/scripts/common.sh" # shellcheck source=scripts/common_cmdline.sh source "${REPO_ROOT}/scripts/common_cmdline.sh" -(( $# <= 1 )) || fail "Too many arguments. Usage: run.sh []" +(( $# <= 1 )) || fail "Too many arguments. Usage: local.sh []" solc="${1:-${SOLIDITY_BUILD_DIR}/solc/solc}" command_available "$solc" --version From 9aceb3a3f716c2eea5bef45724ae5df36d19b2a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Fri, 14 Jun 2024 15:25:44 +0200 Subject: [PATCH 0264/1022] Move bytecode_size helper to common.sh --- scripts/common_cmdline.sh | 8 ++++++++ test/benchmarks/local.sh | 6 ------ 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/scripts/common_cmdline.sh b/scripts/common_cmdline.sh index 5e32a76dc9ed..819a4b1c8eaf 100644 --- a/scripts/common_cmdline.sh +++ b/scripts/common_cmdline.sh @@ -169,3 +169,11 @@ function stripEmptyLines { sed -e '/^\s*$/d' } + +# Calculates the total size of bytecode of one or more contracts in bytes. +# Expects the output from `solc --bin` on standard input. +function bytecode_size { + local bytecode_chars + bytecode_chars=$(stripCLIDecorations | stripEmptyLines | wc --chars) + echo $(( bytecode_chars / 2 )) +} diff --git a/test/benchmarks/local.sh b/test/benchmarks/local.sh index 9d4f498c1a98..16a0c3afe32c 100755 --- a/test/benchmarks/local.sh +++ b/test/benchmarks/local.sh @@ -45,12 +45,6 @@ function cleanup() { trap cleanup SIGINT SIGTERM -function bytecode_size { - local bytecode_chars - bytecode_chars=$(stripCLIDecorations | stripEmptyLines | wc --chars) - echo $(( bytecode_chars / 2 )) -} - function benchmark_contract { local pipeline="$1" local input_path="$2" From bb168489d270916aeff498963feb407aebeb83d1 Mon Sep 17 00:00:00 2001 From: Matheus Aguiar Date: Thu, 30 May 2024 23:15:43 -0300 Subject: [PATCH 0265/1022] Catch and report UnimplementedFeatureError --- Changelog.md | 1 + liblangutil/ErrorReporter.cpp | 10 + liblangutil/ErrorReporter.h | 2 + libsolidity/interface/CompilerStack.cpp | 134 ++++++------- libsolidity/interface/CompilerStack.h | 2 + libsolidity/interface/StandardCompiler.cpp | 17 +- libsolutil/Assertions.h | 15 +- libsolutil/CommonData.h | 10 + libsolutil/Exceptions.cpp | 10 + libsolutil/Exceptions.h | 5 + libyul/YulStack.cpp | 189 ++++++++++++------ libyul/YulStack.h | 16 +- scripts/error_codes.py | 2 +- solc/CommandLineInterface.cpp | 6 + solc/main.cpp | 6 - test/libsolidity/SyntaxTest.cpp | 49 ++--- .../operators/shifts/shr_unused.sol | 2 +- .../array/nested_calldata_storage.sol | 2 +- .../array/nested_calldata_storage2.sol | 2 +- .../constants/mod_div_rational.sol | 2 +- .../errors/require_custom_legacy.sol | 2 +- .../builtin/builtin_type_definition.sol | 2 +- .../inline_array_fixed_types.sol | 2 +- .../inline_arrays/inline_array_rationals.sol | 2 +- .../303_fixed_type_int_conversion.sol | 2 +- ...304_fixed_type_rational_int_conversion.sol | 2 +- ...ixed_type_rational_fraction_conversion.sol | 2 +- .../307_rational_unary_minus_operation.sol | 2 +- .../312_leading_zero_rationals_convert.sol | 2 +- .../314_fixed_type_zero_handling.sol | 2 +- ..._fixed_type_valid_explicit_conversions.sol | 2 +- .../323_mapping_with_fixed_literal.sol | 2 +- .../324_fixed_points_inside_structs.sol | 2 +- ...8_rational_to_fixed_literal_expression.sol | 2 +- .../343_integer_and_fixed_interaction.sol | 2 +- .../declaring_fixed_and_ufixed_variables.sol | 2 +- .../lexer_numbers_with_underscores_fixed.sol | 2 +- ...ional_number_literal_to_fixed_implicit.sol | 2 +- 38 files changed, 307 insertions(+), 211 deletions(-) diff --git a/Changelog.md b/Changelog.md index 1c15478d1935..29fb86250b6e 100644 --- a/Changelog.md +++ b/Changelog.md @@ -4,6 +4,7 @@ Language Features: Compiler Features: + * Error Reporting: Unimplemented features are now properly reported as errors instead of being handled as if they were bugs. * EVM: Support for the EVM version "Prague". * SMTChecker: Add CHC engine check for underflow and overflow in unary minus operation. * SMTChecker: Replace CVC4 as a possible BMC backend with cvc5. diff --git a/liblangutil/ErrorReporter.cpp b/liblangutil/ErrorReporter.cpp index bf10483aa5a2..ddb6b70d1253 100644 --- a/liblangutil/ErrorReporter.cpp +++ b/liblangutil/ErrorReporter.cpp @@ -263,6 +263,16 @@ void ErrorReporter::docstringParsingError(ErrorId _error, SourceLocation const& ); } +void ErrorReporter::unimplementedFeatureError(ErrorId _error, SourceLocation const& _location, std::string const& _description) +{ + error( + _error, + Error::Type::UnimplementedFeatureError, + _location, + _description + ); +} + void ErrorReporter::info( ErrorId _error, SourceLocation const& _location, diff --git a/liblangutil/ErrorReporter.h b/liblangutil/ErrorReporter.h index c78b6f498d2e..d7e280ed9049 100644 --- a/liblangutil/ErrorReporter.h +++ b/liblangutil/ErrorReporter.h @@ -118,6 +118,8 @@ class ErrorReporter void docstringParsingError(ErrorId _error, SourceLocation const& _location, std::string const& _description); + void unimplementedFeatureError(ErrorId _error, SourceLocation const& _location, std::string const& _description); + ErrorList const& errors() const; void clear(); diff --git a/libsolidity/interface/CompilerStack.cpp b/libsolidity/interface/CompilerStack.cpp index 2299155383c0..0a5fed3338cf 100644 --- a/libsolidity/interface/CompilerStack.cpp +++ b/libsolidity/interface/CompilerStack.cpp @@ -346,64 +346,71 @@ bool CompilerStack::parse() if (SemVerVersion{std::string(VersionString)}.isPrerelease()) m_errorReporter.warning(3805_error, "This is a pre-release compiler version, please do not use it in production."); - Parser parser{m_errorReporter, m_evmVersion}; + try + { + Parser parser{m_errorReporter, m_evmVersion}; - std::vector sourcesToParse; - for (auto const& s: m_sources) - sourcesToParse.push_back(s.first); + std::vector sourcesToParse; + for (auto const& s: m_sources) + sourcesToParse.push_back(s.first); - for (size_t i = 0; i < sourcesToParse.size(); ++i) - { - std::string const& path = sourcesToParse[i]; - Source& source = m_sources[path]; - source.ast = parser.parse(*source.charStream); - if (!source.ast) - solAssert(Error::containsErrors(m_errorReporter.errors()), "Parser returned null but did not report error."); - else + for (size_t i = 0; i < sourcesToParse.size(); ++i) { - source.ast->annotation().path = path; - - for (auto const& import: ASTNode::filteredNodes(source.ast->nodes())) + std::string const& path = sourcesToParse[i]; + Source& source = m_sources[path]; + source.ast = parser.parse(*source.charStream); + if (!source.ast) + solAssert(Error::containsErrors(m_errorReporter.errors()), "Parser returned null but did not report error."); + else { - solAssert(!import->path().empty(), "Import path cannot be empty."); - // Check whether the import directive is for the standard library, - // and if yes, add specified file to source units to be parsed. - auto it = stdlib::sources.find(import->path()); - if (it != stdlib::sources.end()) + source.ast->annotation().path = path; + + for (auto const& import: ASTNode::filteredNodes(source.ast->nodes())) { - auto [name, content] = *it; - m_sources[name].charStream = std::make_unique(content, name); - sourcesToParse.push_back(name); + solAssert(!import->path().empty(), "Import path cannot be empty."); + // Check whether the import directive is for the standard library, + // and if yes, add specified file to source units to be parsed. + auto it = stdlib::sources.find(import->path()); + if (it != stdlib::sources.end()) + { + auto [name, content] = *it; + m_sources[name].charStream = std::make_unique(content, name); + sourcesToParse.push_back(name); + } + + // 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); } - // 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)) + { + std::string const& newPath = newSource.first; + std::string const& newContents = newSource.second; + m_sources[newPath].charStream = std::make_shared(newContents, newPath); + sourcesToParse.push_back(newPath); + } } - - if (m_stopAfter >= ParsedAndImported) - for (auto const& newSource: loadMissingSources(*source.ast)) - { - std::string const& newPath = newSource.first; - std::string const& newContents = newSource.second; - m_sources[newPath].charStream = std::make_shared(newContents, newPath); - sourcesToParse.push_back(newPath); - } } - } - if (Error::containsErrors(m_errorReporter.errors())) - return false; + if (Error::containsErrors(m_errorReporter.errors())) + return false; - m_stackState = (m_stopAfter <= Parsed ? Parsed : ParsedAndImported); - storeContractDefinitions(); + m_stackState = (m_stopAfter <= Parsed ? Parsed : ParsedAndImported); + storeContractDefinitions(); - solAssert(!m_maxAstId.has_value()); - m_maxAstId = parser.maxID(); + solAssert(!m_maxAstId.has_value()); + m_maxAstId = parser.maxID(); + } + catch (UnimplementedFeatureError const& _error) + { + reportUnimplementedFeatureError(_error); + } return true; } @@ -494,6 +501,11 @@ bool CompilerStack::analyze() solAssert(m_errorReporter.hasErrors(), "Unreported fatal error: "s + error.what()); noErrors = false; } + catch (UnimplementedFeatureError const& _error) + { + reportUnimplementedFeatureError(_error); + noErrors = false; + } if (!noErrors) return false; @@ -737,28 +749,10 @@ bool CompilerStack::compile(State _stopAfter) m_errorReporter.error(_error.errorId(), _error.type(), SourceLocation(), _error.what()); return false; } - catch (UnimplementedFeatureError const& _unimplementedError) + catch (UnimplementedFeatureError const& _error) { - if ( - SourceLocation const* sourceLocation = - boost::get_error_info(_unimplementedError) - ) - { - std::string const* comment = _unimplementedError.comment(); - m_errorReporter.error( - 1834_error, - Error::Type::CodeGenerationError, - *sourceLocation, - fmt::format( - "Unimplemented feature error {} in {}", - (comment && !comment->empty()) ? ": " + *comment : "", - _unimplementedError.lineInfo() - ) - ); - return false; - } - else - throw; + reportUnimplementedFeatureError(_error); + return false; } } m_stackState = CompilationSuccessful; @@ -1908,3 +1902,9 @@ experimental::Analysis const& CompilerStack::experimentalAnalysis() const solAssert(!!m_experimentalAnalysis); return *m_experimentalAnalysis; } + +void CompilerStack::reportUnimplementedFeatureError(UnimplementedFeatureError const& _error) +{ + solAssert(_error.comment(), "Unimplemented feature errors must include a message for the user"); + m_errorReporter.unimplementedFeatureError(1834_error, _error.sourceLocation(), *_error.comment()); +} diff --git a/libsolidity/interface/CompilerStack.h b/libsolidity/interface/CompilerStack.h index ef76764faf70..672067d81cc7 100644 --- a/libsolidity/interface/CompilerStack.h +++ b/libsolidity/interface/CompilerStack.h @@ -503,6 +503,8 @@ class CompilerStack: public langutil::CharStreamProvider, public evmasm::Abstrac FunctionDefinition const& _function ) const; + void reportUnimplementedFeatureError(langutil::UnimplementedFeatureError const& _error); + ReadCallback::Callback m_readFile; OptimiserSettings m_optimiserSettings; RevertStrings m_revertStrings = RevertStrings::Default; diff --git a/libsolidity/interface/StandardCompiler.cpp b/libsolidity/interface/StandardCompiler.cpp index 2b36f9032349..80f788cb6143 100644 --- a/libsolidity/interface/StandardCompiler.cpp +++ b/libsolidity/interface/StandardCompiler.cpp @@ -49,6 +49,7 @@ using namespace solidity; using namespace solidity::yul; using namespace solidity::frontend; using namespace solidity::langutil; +using namespace solidity::util; using namespace std::string_literals; namespace @@ -1402,13 +1403,8 @@ Json StandardCompiler::compileSolidity(StandardCompiler::InputsAndSettings _inpu } catch (UnimplementedFeatureError const& _exception) { - errors.emplace_back(formatErrorWithException( - compilerStack, - _exception, - Error::Type::UnimplementedFeatureError, - "general", - "Unimplemented feature (" + _exception.lineInfo() + ")" - )); + // let StandardCompiler::compile handle this + throw _exception; } catch (yul::YulException const& _exception) { @@ -1469,7 +1465,7 @@ Json StandardCompiler::compileSolidity(StandardCompiler::InputsAndSettings _inpu Json output; if (errors.size() > 0) - output["errors"] = std::move(errors); + output["errors"] = std::move(errors); if (!compilerStack.unhandledSMTLib2Queries().empty()) for (std::string const& query: compilerStack.unhandledSMTLib2Queries()) @@ -1783,6 +1779,11 @@ Json StandardCompiler::compile(Json const& _input) noexcept { return formatFatalError(Error::Type::InternalCompilerError, std::string("JSON runtime exception: ") + util::removeNlohmannInternalErrorIdentifier(_exception.what())); } + catch (UnimplementedFeatureError const& _exception) + { + solAssert(_exception.comment(), "Unimplemented feature errors must include a message for the user"); + return formatFatalError(Error::Type::UnimplementedFeatureError, stringOrDefault(_exception.comment())); + } catch (util::Exception const& _exception) { return formatFatalError(Error::Type::InternalCompilerError, "Internal exception in StandardCompiler::compile: " + boost::diagnostic_information(_exception)); diff --git a/libsolutil/Assertions.h b/libsolutil/Assertions.h index 4879299bf011..dcceb1cfc152 100644 --- a/libsolutil/Assertions.h +++ b/libsolutil/Assertions.h @@ -26,6 +26,7 @@ #pragma once #include +#include #include #include @@ -63,18 +64,6 @@ namespace solidity::util } #endif -namespace assertions -{ - -inline std::string stringOrDefault(std::string _string, std::string _defaultString) -{ - // NOTE: Putting this in a function rather than directly in a macro prevents the string from - // being evaluated multiple times if it's not just a literal. - return (!_string.empty() ? std::move(_string) : std::move(_defaultString)); -} - -} - /// Base macro that can be used to implement assertion macros. /// Throws an exception containing the given description if the condition is not met. /// Allows you to provide the default description for the case where the user of your macro does @@ -86,7 +75,7 @@ inline std::string stringOrDefault(std::string _string, std::string _defaultStri if (!(_condition)) \ solThrow( \ _exceptionType, \ - ::solidity::util::assertions::stringOrDefault((_description), (_defaultDescription)) \ + ::solidity::util::stringOrDefault((_description), (_defaultDescription)) \ ); \ } \ while (false) diff --git a/libsolutil/CommonData.h b/libsolutil/CommonData.h index c52434451b81..6e17e674d6e2 100644 --- a/libsolutil/CommonData.h +++ b/libsolutil/CommonData.h @@ -632,4 +632,14 @@ std::vector make_vector(Args&&... _args) return result; } +inline std::string stringOrDefault(std::string _string, std::string _defaultString = "") +{ + return (!_string.empty() ? std::move(_string) : std::move(_defaultString)); +} + +inline std::string stringOrDefault(std::string const* _string, std::string const& _defaultString = "") +{ + return (_string ? stringOrDefault(*_string, _defaultString) : _defaultString); +} + } diff --git a/libsolutil/Exceptions.cpp b/libsolutil/Exceptions.cpp index 00fe3e26ce92..ba431a808cac 100644 --- a/libsolutil/Exceptions.cpp +++ b/libsolutil/Exceptions.cpp @@ -17,8 +17,10 @@ // SPDX-License-Identifier: GPL-3.0 #include +#include using namespace solidity::util; +using namespace solidity::langutil; char const* Exception::what() const noexcept { @@ -49,3 +51,11 @@ std::string const* Exception::comment() const noexcept { return boost::get_error_info(*this); } + +SourceLocation Exception::sourceLocation() const noexcept +{ + if (SourceLocation const* sourceLocation = boost::get_error_info(*this)) + return *sourceLocation; + + return SourceLocation{}; +} diff --git a/libsolutil/Exceptions.h b/libsolutil/Exceptions.h index 7dd9b6769ad4..2ad2713c357a 100644 --- a/libsolutil/Exceptions.h +++ b/libsolutil/Exceptions.h @@ -18,6 +18,8 @@ #pragma once +#include + #include #include #include @@ -39,6 +41,9 @@ struct Exception: virtual std::exception, virtual boost::exception /// @returns the errinfo_comment of this exception. std::string const* comment() const noexcept; + + /// @returns the errinfo_sourceLocation of this exception + langutil::SourceLocation sourceLocation() const noexcept; }; /// Throws an exception with a given description and extra information about the location the diff --git a/libyul/YulStack.cpp b/libyul/YulStack.cpp index a4341cba308c..94e9ad7a8d55 100644 --- a/libyul/YulStack.cpp +++ b/libyul/YulStack.cpp @@ -71,15 +71,35 @@ CharStream const& YulStack::charStream(std::string const& _sourceName) const return *m_charStream; } +bool YulStack::parse(std::string const& _sourceName, std::string const& _source) +{ + yulAssert(m_stackState == Empty); + try + { + m_charStream = std::make_unique(_source, _sourceName); + std::shared_ptr scanner = std::make_shared(*m_charStream); + m_parserResult = ObjectParser(m_errorReporter, languageToDialect(m_language, m_evmVersion)).parse(scanner, false); + } + catch (UnimplementedFeatureError const& _error) + { + reportUnimplementedFeatureError(_error); + } + + if (m_errorReporter.errors().empty()) + m_stackState = Parsed; + + return m_stackState == Parsed; +} + bool YulStack::parseAndAnalyze(std::string const& _sourceName, std::string const& _source) { m_errors.clear(); - m_analysisSuccessful = false; - m_charStream = std::make_unique(_source, _sourceName); - std::shared_ptr scanner = std::make_shared(*m_charStream); - m_parserResult = ObjectParser(m_errorReporter, languageToDialect(m_language, m_evmVersion)).parse(scanner, false); - if (!m_errorReporter.errors().empty()) + yulAssert(m_stackState == Empty); + + if (!parse(_sourceName, _source)) return false; + + yulAssert(m_stackState == Parsed); yulAssert(m_parserResult, ""); yulAssert(m_parserResult->code, ""); @@ -88,30 +108,37 @@ bool YulStack::parseAndAnalyze(std::string const& _sourceName, std::string const void YulStack::optimize() { - yulAssert(m_analysisSuccessful, "Analysis was not successful."); + yulAssert(m_stackState >= AnalysisSuccessful, "Analysis was not successful."); yulAssert(m_parserResult); - if ( - !m_optimiserSettings.runYulOptimiser && - yul::MSizeFinder::containsMSize(languageToDialect(m_language, m_evmVersion), *m_parserResult) - ) - return; + try + { + if ( + !m_optimiserSettings.runYulOptimiser && + yul::MSizeFinder::containsMSize(languageToDialect(m_language, m_evmVersion), *m_parserResult) + ) + return; - m_analysisSuccessful = false; - yulAssert(m_parserResult, ""); - optimize(*m_parserResult, true); - yulAssert(analyzeParsed(), "Invalid source code after optimization."); + m_stackState = Parsed; + optimize(*m_parserResult, true); + yulAssert(analyzeParsed(), "Invalid source code after optimization."); + } + catch (UnimplementedFeatureError const& _error) + { + reportUnimplementedFeatureError(_error); + } } bool YulStack::analyzeParsed() { + yulAssert(m_stackState >= Parsed); yulAssert(m_parserResult, ""); - m_analysisSuccessful = analyzeParsed(*m_parserResult); - return m_analysisSuccessful; + return analyzeParsed(*m_parserResult); } bool YulStack::analyzeParsed(Object& _object) { + yulAssert(m_stackState >= Parsed); yulAssert(_object.code, ""); _object.analysisInfo = std::make_shared(); @@ -122,11 +149,25 @@ bool YulStack::analyzeParsed(Object& _object) {}, _object.qualifiedDataNames() ); - bool success = analyzer.analyze(*_object.code); - for (auto& subNode: _object.subObjects) - if (auto subObject = dynamic_cast(subNode.get())) - if (!analyzeParsed(*subObject)) - success = false; + + bool success = false; + try + { + success = analyzer.analyze(*_object.code); + for (auto& subNode: _object.subObjects) + if (auto subObject = dynamic_cast(subNode.get())) + if (!analyzeParsed(*subObject)) + success = false; + } + catch (UnimplementedFeatureError const& _error) + { + reportUnimplementedFeatureError(_error); + success = false; + } + + if (success) + m_stackState = AnalysisSuccessful; + return success; } @@ -204,9 +245,9 @@ void YulStack::optimize(Object& _object, bool _isCreation) ); } -MachineAssemblyObject YulStack::assemble(Machine _machine) const +MachineAssemblyObject YulStack::assemble(Machine _machine) { - yulAssert(m_analysisSuccessful, ""); + yulAssert(m_stackState >= AnalysisSuccessful); yulAssert(m_parserResult, ""); yulAssert(m_parserResult->code, ""); yulAssert(m_parserResult->analysisInfo, ""); @@ -221,43 +262,50 @@ MachineAssemblyObject YulStack::assemble(Machine _machine) const } std::pair -YulStack::assembleWithDeployed(std::optional _deployName) const +YulStack::assembleWithDeployed(std::optional _deployName) { auto [creationAssembly, deployedAssembly] = assembleEVMWithDeployed(_deployName); yulAssert(creationAssembly, ""); yulAssert(m_charStream, ""); MachineAssemblyObject creationObject; - creationObject.bytecode = std::make_shared(creationAssembly->assemble()); - yulAssert(creationObject.bytecode->immutableReferences.empty(), "Leftover immutables."); - creationObject.assembly = creationAssembly->assemblyString(m_debugInfoSelection); - creationObject.sourceMappings = std::make_unique( - evmasm::AssemblyItem::computeSourceMapping( - creationAssembly->items(), - {{m_charStream->name(), 0}} - ) - ); - MachineAssemblyObject deployedObject; - if (deployedAssembly) + try { - deployedObject.bytecode = std::make_shared(deployedAssembly->assemble()); - deployedObject.assembly = deployedAssembly->assemblyString(m_debugInfoSelection); - deployedObject.sourceMappings = std::make_unique( + creationObject.bytecode = std::make_shared(creationAssembly->assemble()); + yulAssert(creationObject.bytecode->immutableReferences.empty(), "Leftover immutables."); + creationObject.assembly = creationAssembly->assemblyString(m_debugInfoSelection); + creationObject.sourceMappings = std::make_unique( evmasm::AssemblyItem::computeSourceMapping( - deployedAssembly->items(), + creationAssembly->items(), {{m_charStream->name(), 0}} ) ); + + if (deployedAssembly) + { + deployedObject.bytecode = std::make_shared(deployedAssembly->assemble()); + deployedObject.assembly = deployedAssembly->assemblyString(m_debugInfoSelection); + deployedObject.sourceMappings = std::make_unique( + evmasm::AssemblyItem::computeSourceMapping( + deployedAssembly->items(), + {{m_charStream->name(), 0}} + ) + ); + } + } + catch (UnimplementedFeatureError const& _error) + { + reportUnimplementedFeatureError(_error); } return {std::move(creationObject), std::move(deployedObject)}; } std::pair, std::shared_ptr> -YulStack::assembleEVMWithDeployed(std::optional _deployName) const +YulStack::assembleEVMWithDeployed(std::optional _deployName) { - yulAssert(m_analysisSuccessful, ""); + yulAssert(m_stackState >= AnalysisSuccessful); yulAssert(m_parserResult, ""); yulAssert(m_parserResult->code, ""); yulAssert(m_parserResult->analysisInfo, ""); @@ -272,32 +320,39 @@ YulStack::assembleEVMWithDeployed(std::optional _deployName) c !m_optimiserSettings.runYulOptimiser && !yul::MSizeFinder::containsMSize(languageToDialect(m_language, m_evmVersion), *m_parserResult) ); - compileEVM(adapter, optimize); + try + { + compileEVM(adapter, optimize); - assembly.optimise(evmasm::Assembly::OptimiserSettings::translateSettings(m_optimiserSettings, m_evmVersion)); + assembly.optimise(evmasm::Assembly::OptimiserSettings::translateSettings(m_optimiserSettings, m_evmVersion)); - std::optional subIndex; + std::optional subIndex; - // Pick matching assembly if name was given - if (_deployName.has_value()) - { - for (size_t i = 0; i < assembly.numSubs(); i++) - if (assembly.sub(i).name() == _deployName) - { - subIndex = i; - break; - } + // Pick matching assembly if name was given + if (_deployName.has_value()) + { + for (size_t i = 0; i < assembly.numSubs(); i++) + if (assembly.sub(i).name() == _deployName) + { + subIndex = i; + break; + } + + solAssert(subIndex.has_value(), "Failed to find object to be deployed."); + } + // Otherwise use heuristic: If there is a single sub-assembly, this is likely the object to be deployed. + else if (assembly.numSubs() == 1) + subIndex = 0; - solAssert(subIndex.has_value(), "Failed to find object to be deployed."); + if (subIndex.has_value()) + { + evmasm::Assembly& runtimeAssembly = assembly.sub(*subIndex); + return {std::make_shared(assembly), std::make_shared(runtimeAssembly)}; + } } - // Otherwise use heuristic: If there is a single sub-assembly, this is likely the object to be deployed. - else if (assembly.numSubs() == 1) - subIndex = 0; - - if (subIndex.has_value()) + catch (UnimplementedFeatureError const& _error) { - evmasm::Assembly& runtimeAssembly = assembly.sub(*subIndex); - return {std::make_shared(assembly), std::make_shared(runtimeAssembly)}; + reportUnimplementedFeatureError(_error); } return {std::make_shared(assembly), {}}; @@ -307,6 +362,7 @@ std::string YulStack::print( CharStreamProvider const* _soliditySourceProvider ) const { + yulAssert(m_stackState >= Parsed); yulAssert(m_parserResult, ""); yulAssert(m_parserResult->code, ""); return m_parserResult->toString(&languageToDialect(m_language, m_evmVersion), m_debugInfoSelection, _soliditySourceProvider) + "\n"; @@ -314,6 +370,7 @@ std::string YulStack::print( Json YulStack::astJson() const { + yulAssert(m_stackState >= Parsed); yulAssert(m_parserResult, ""); yulAssert(m_parserResult->code, ""); return m_parserResult->toJson(); @@ -321,8 +378,14 @@ Json YulStack::astJson() const std::shared_ptr YulStack::parserResult() const { - yulAssert(m_analysisSuccessful, "Analysis was not successful."); + yulAssert(m_stackState >= AnalysisSuccessful, "Analysis was not successful."); yulAssert(m_parserResult, ""); yulAssert(m_parserResult->code, ""); return m_parserResult; } + +void YulStack::reportUnimplementedFeatureError(UnimplementedFeatureError const& _error) +{ + solAssert(_error.comment(), "Unimplemented feature errors must include a message for the user"); + m_errorReporter.unimplementedFeatureError(1920_error, _error.sourceLocation(), *_error.comment()); +} diff --git a/libyul/YulStack.h b/libyul/YulStack.h index 27f530b44c4a..d75ff200f5ce 100644 --- a/libyul/YulStack.h +++ b/libyul/YulStack.h @@ -67,6 +67,11 @@ class YulStack: public langutil::CharStreamProvider public: enum class Language { Yul, Assembly, StrictAssembly }; enum class Machine { EVM }; + enum State { + Empty, + Parsed, + AnalysisSuccessful + }; YulStack(): YulStack( @@ -105,7 +110,7 @@ class YulStack: public langutil::CharStreamProvider void optimize(); /// Run the assembly step (should only be called after parseAndAnalyze). - MachineAssemblyObject assemble(Machine _machine) const; + MachineAssemblyObject assemble(Machine _machine); /// Run the assembly step (should only be called after parseAndAnalyze). /// In addition to the value returned by @a assemble, returns @@ -114,7 +119,7 @@ class YulStack: public langutil::CharStreamProvider std::pair assembleWithDeployed( std::optional _deployName = {} - ) const; + ); /// Run the assembly step (should only be called after parseAndAnalyze). /// Similar to @a assemblyWithDeployed, but returns EVM assembly objects. @@ -122,7 +127,7 @@ class YulStack: public langutil::CharStreamProvider std::pair, std::shared_ptr> assembleEVMWithDeployed( std::optional _deployName = {} - ) const; + ); /// @returns the errors generated during parsing, analysis (and potentially assembly). langutil::ErrorList const& errors() const { return m_errors; } @@ -136,6 +141,7 @@ class YulStack: public langutil::CharStreamProvider std::shared_ptr parserResult() const; private: + bool parse(std::string const& _sourceName, std::string const& _source); bool analyzeParsed(); bool analyzeParsed(yul::Object& _object); @@ -143,6 +149,8 @@ class YulStack: public langutil::CharStreamProvider void optimize(yul::Object& _object, bool _isCreation); + void reportUnimplementedFeatureError(langutil::UnimplementedFeatureError const& _error); + Language m_language = Language::Assembly; langutil::EVMVersion m_evmVersion; std::optional m_eofVersion; @@ -151,7 +159,7 @@ class YulStack: public langutil::CharStreamProvider std::unique_ptr m_charStream; - bool m_analysisSuccessful = false; + State m_stackState = Empty; std::shared_ptr m_parserResult; langutil::ErrorList m_errors; langutil::ErrorReporter m_errorReporter; diff --git a/scripts/error_codes.py b/scripts/error_codes.py index 8ee5cbbdeda7..24ec2b06d617 100755 --- a/scripts/error_codes.py +++ b/scripts/error_codes.py @@ -201,7 +201,7 @@ def examine_id_coverage(top_dir, source_id_to_file_names, new_ids_only=False): # The warning may or may not exist in a compiler build. "4591", # "There are more than 256 warnings. Ignoring the rest." # Due to 3805, the warning lists look different for different compiler builds. - "1834", # Unimplemented feature error, as we do not test it anymore via cmdLineTests + "1920", # Unimplemented feature error from YulStack (currently there are no UnimplementedFeatureErrors thrown by libyul) "1180", # SMTChecker, covered by CL tests "2339", # SMTChecker, covered by CL tests "2961", # SMTChecker, covered by CL tests diff --git a/solc/CommandLineInterface.cpp b/solc/CommandLineInterface.cpp index 514f84c209df..edfd4d52c6b8 100644 --- a/solc/CommandLineInterface.cpp +++ b/solc/CommandLineInterface.cpp @@ -691,6 +691,12 @@ bool CommandLineInterface::run(int _argc, char const* const* _argv) return false; } + catch (UnimplementedFeatureError const& _error) + { + solAssert(_error.comment(), "Unimplemented feature errors must include a message for the user"); + report(Error::Severity::Error, stringOrDefault(_error.comment(), "Unimplemented feature")); + return false; + } } bool CommandLineInterface::parseArguments(int _argc, char const* const* _argv) diff --git a/solc/main.cpp b/solc/main.cpp index 4237f9ac6d28..c6c3df7a2eba 100644 --- a/solc/main.cpp +++ b/solc/main.cpp @@ -45,12 +45,6 @@ int main(int argc, char** argv) std::cerr << boost::diagnostic_information(_exception); return 2; } - catch (langutil::UnimplementedFeatureError const& _exception) - { - std::cerr << "Unimplemented feature:" << std::endl; - std::cerr << boost::diagnostic_information(_exception); - return 2; - } catch (langutil::InternalCompilerError const& _exception) { std::cerr << "Internal compiler error:" << std::endl; diff --git a/test/libsolidity/SyntaxTest.cpp b/test/libsolidity/SyntaxTest.cpp index f350ea4624b1..41c1d0568be6 100644 --- a/test/libsolidity/SyntaxTest.cpp +++ b/test/libsolidity/SyntaxTest.cpp @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -80,34 +81,28 @@ void SyntaxTest::setupCompiler(CompilerStack& _compiler) void SyntaxTest::parseAndAnalyze() { - try + runFramework(withPreamble(m_sources.sources), m_stopAfter); + if (!pipelineSuccessful() && stageSuccessful(PipelineStage::Analysis) && !compiler().isExperimentalAnalysis()) { - runFramework(withPreamble(m_sources.sources), m_stopAfter); - if (!pipelineSuccessful() && stageSuccessful(PipelineStage::Analysis) && !compiler().isExperimentalAnalysis()) - { - ErrorList const& errors = compiler().errors(); - auto codeGeneretionErrorCount = count_if(errors.cbegin(), errors.cend(), [](auto const& error) { - return error->type() == Error::Type::CodeGenerationError; - }); - auto errorCount = count_if(errors.cbegin(), errors.cend(), [](auto const& error) { - return Error::isError(error->type()); - }); - // failing compilation after successful analysis is a rare case, - // it assumes that errors contain exactly one error, and the error is of type Error::Type::CodeGenerationError - if (codeGeneretionErrorCount != 1 || errorCount != 1) - BOOST_THROW_EXCEPTION(std::runtime_error("Compilation failed even though analysis was successful.")); - } - } - catch (UnimplementedFeatureError const& _e) - { - m_errorList.emplace_back(SyntaxTestError{ - Error::Type::UnimplementedFeatureError, - std::nullopt, - errorMessage(_e), - "", - -1, - -1 - }); + ErrorList const& errors = compiler().errors(); + static auto isInternalError = [](std::shared_ptr const& _error) { + return + Error::isError(_error->type()) && + _error->type() != Error::Type::CodeGenerationError && + _error->type() != Error::Type::UnimplementedFeatureError + ; + }; + // Most errors are detected during analysis, and should not happen during code generation. + // There are some exceptions, e.g. unimplemented features or stack too deep, but anything else at this stage + // is an internal error that signals a bug in the compiler (rather than in user's code). + if ( + auto error = ranges::find_if(errors, isInternalError); + error != ranges::end(errors) + ) + BOOST_THROW_EXCEPTION(std::runtime_error( + "Unexpected " + Error::formatErrorType((*error)->type()) + " at compilation stage." + " This error should NOT be encoded as expectation and should be fixed instead." + )); } filterObtainedErrors(); diff --git a/test/libsolidity/smtCheckerTests/operators/shifts/shr_unused.sol b/test/libsolidity/smtCheckerTests/operators/shifts/shr_unused.sol index 8f34b530b944..50438175895e 100644 --- a/test/libsolidity/smtCheckerTests/operators/shifts/shr_unused.sol +++ b/test/libsolidity/smtCheckerTests/operators/shifts/shr_unused.sol @@ -7,5 +7,5 @@ contract C { // ==== // SMTEngine: all // ---- -// UnimplementedFeatureError: Not yet implemented - FixedPointType. // Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. +// UnimplementedFeatureError 1834: Not yet implemented - FixedPointType. diff --git a/test/libsolidity/syntaxTests/array/nested_calldata_storage.sol b/test/libsolidity/syntaxTests/array/nested_calldata_storage.sol index e9878fc223e0..18bf550c066b 100644 --- a/test/libsolidity/syntaxTests/array/nested_calldata_storage.sol +++ b/test/libsolidity/syntaxTests/array/nested_calldata_storage.sol @@ -6,4 +6,4 @@ contract C { } // ---- -// UnimplementedFeatureError: Copying nested calldata dynamic arrays to storage is not implemented in the old code generator. +// UnimplementedFeatureError 1834: Copying nested calldata dynamic arrays to storage is not implemented in the old code generator. diff --git a/test/libsolidity/syntaxTests/array/nested_calldata_storage2.sol b/test/libsolidity/syntaxTests/array/nested_calldata_storage2.sol index 2d1c1f5866b1..9f5bb8eab5b1 100644 --- a/test/libsolidity/syntaxTests/array/nested_calldata_storage2.sol +++ b/test/libsolidity/syntaxTests/array/nested_calldata_storage2.sol @@ -6,4 +6,4 @@ contract C { } // ---- -// UnimplementedFeatureError: Copying nested calldata dynamic arrays to storage is not implemented in the old code generator. +// UnimplementedFeatureError 1834: Copying nested calldata dynamic arrays to storage is not implemented in the old code generator. diff --git a/test/libsolidity/syntaxTests/constants/mod_div_rational.sol b/test/libsolidity/syntaxTests/constants/mod_div_rational.sol index d983fa1ee916..5c127eb4a253 100644 --- a/test/libsolidity/syntaxTests/constants/mod_div_rational.sol +++ b/test/libsolidity/syntaxTests/constants/mod_div_rational.sol @@ -5,4 +5,4 @@ contract C { fixed a4 = 0 / -0.123; } // ---- -// UnimplementedFeatureError: Not yet implemented - FixedPointType. +// UnimplementedFeatureError 1834: Not yet implemented - FixedPointType. diff --git a/test/libsolidity/syntaxTests/errors/require_custom_legacy.sol b/test/libsolidity/syntaxTests/errors/require_custom_legacy.sol index 334b847393cb..c1eae591f292 100644 --- a/test/libsolidity/syntaxTests/errors/require_custom_legacy.sol +++ b/test/libsolidity/syntaxTests/errors/require_custom_legacy.sol @@ -5,4 +5,4 @@ contract C { } } // ---- -// UnimplementedFeatureError: Require with a custom error is only available using the via-ir pipeline. +// UnimplementedFeatureError 1834: Require with a custom error is only available using the via-ir pipeline. diff --git a/test/libsolidity/syntaxTests/experimental/builtin/builtin_type_definition.sol b/test/libsolidity/syntaxTests/experimental/builtin/builtin_type_definition.sol index 373d76c339ff..ed7db1ec6c8b 100644 --- a/test/libsolidity/syntaxTests/experimental/builtin/builtin_type_definition.sol +++ b/test/libsolidity/syntaxTests/experimental/builtin/builtin_type_definition.sol @@ -33,7 +33,6 @@ contract C { // EVMVersion: >=constantinople // compileViaYul: true // ---- -// UnimplementedFeatureError: No support for calling functions pointers yet. // Warning 2264: (0-29): Experimental features are turned on. Do not use experimental features on live deployments. // Info 4164: (31-61): Inferred type: void // Info 4164: (63-93): Inferred type: bool @@ -90,3 +89,4 @@ contract C { // Info 4164: (563-574): Inferred type: (bool, word) -> word // Info 4164: (563-567): Inferred type: (?bm:type, ?bn:type) // Info 4164: (575-576): Inferred type: (bool, word) +// UnimplementedFeatureError 1834: No support for calling functions pointers yet. diff --git a/test/libsolidity/syntaxTests/inline_arrays/inline_array_fixed_types.sol b/test/libsolidity/syntaxTests/inline_arrays/inline_array_fixed_types.sol index 56a4d0e201bd..604f9b029800 100644 --- a/test/libsolidity/syntaxTests/inline_arrays/inline_array_fixed_types.sol +++ b/test/libsolidity/syntaxTests/inline_arrays/inline_array_fixed_types.sol @@ -4,6 +4,6 @@ contract test { } } // ---- -// UnimplementedFeatureError: Not yet implemented - FixedPointType. // Warning 2072: (50-67): Unused local variable. // Warning 2018: (20-119): Function state mutability can be restricted to pure +// UnimplementedFeatureError 1834: Not yet implemented - FixedPointType. diff --git a/test/libsolidity/syntaxTests/inline_arrays/inline_array_rationals.sol b/test/libsolidity/syntaxTests/inline_arrays/inline_array_rationals.sol index 78aa35de7c03..63df5c044916 100644 --- a/test/libsolidity/syntaxTests/inline_arrays/inline_array_rationals.sol +++ b/test/libsolidity/syntaxTests/inline_arrays/inline_array_rationals.sol @@ -4,6 +4,6 @@ contract test { } } // ---- -// UnimplementedFeatureError: Not yet implemented - FixedPointType. // Warning 2072: (50-73): Unused local variable. // Warning 2018: (20-118): Function state mutability can be restricted to pure +// UnimplementedFeatureError 1834: Not yet implemented - FixedPointType. diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/303_fixed_type_int_conversion.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/303_fixed_type_int_conversion.sol index ba1eb806910d..58c74b9ad0b8 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/303_fixed_type_int_conversion.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/303_fixed_type_int_conversion.sol @@ -8,5 +8,5 @@ contract test { } } // ---- -// UnimplementedFeatureError: Not yet implemented - FixedPointType. // Warning 2018: (20-147): Function state mutability can be restricted to pure +// UnimplementedFeatureError 1834: Not yet implemented - FixedPointType. diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/304_fixed_type_rational_int_conversion.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/304_fixed_type_rational_int_conversion.sol index 81ad7dbe8ac5..404cbc4bce0d 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/304_fixed_type_rational_int_conversion.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/304_fixed_type_rational_int_conversion.sol @@ -6,5 +6,5 @@ contract test { } } // ---- -// UnimplementedFeatureError: Not yet implemented - FixedPointType. // Warning 2018: (20-104): Function state mutability can be restricted to pure +// UnimplementedFeatureError 1834: Not yet implemented - FixedPointType. diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/305_fixed_type_rational_fraction_conversion.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/305_fixed_type_rational_fraction_conversion.sol index b7642e16a199..b113c6bcce52 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/305_fixed_type_rational_fraction_conversion.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/305_fixed_type_rational_fraction_conversion.sol @@ -6,5 +6,5 @@ contract test { } } // ---- -// UnimplementedFeatureError: Not yet implemented - FixedPointType. // Warning 2018: (20-108): Function state mutability can be restricted to pure +// UnimplementedFeatureError 1834: Not yet implemented - FixedPointType. diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/307_rational_unary_minus_operation.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/307_rational_unary_minus_operation.sol index b8b2f12b5117..e80024a98ad8 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/307_rational_unary_minus_operation.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/307_rational_unary_minus_operation.sol @@ -6,4 +6,4 @@ contract test { } } // ---- -// UnimplementedFeatureError: Not yet implemented - FixedPointType. +// UnimplementedFeatureError 1834: Not yet implemented - FixedPointType. diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/312_leading_zero_rationals_convert.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/312_leading_zero_rationals_convert.sol index 082514ebcf9c..20be0208c11f 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/312_leading_zero_rationals_convert.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/312_leading_zero_rationals_convert.sol @@ -8,4 +8,4 @@ contract A { } } // ---- -// UnimplementedFeatureError: Not yet implemented - FixedPointType. +// UnimplementedFeatureError 1834: Not yet implemented - FixedPointType. diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/314_fixed_type_zero_handling.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/314_fixed_type_zero_handling.sol index 1d1e62cf3614..7415ed6e85f0 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/314_fixed_type_zero_handling.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/314_fixed_type_zero_handling.sol @@ -5,5 +5,5 @@ contract test { } } // ---- -// UnimplementedFeatureError: Not yet implemented - FixedPointType. // Warning 2018: (20-104): Function state mutability can be restricted to pure +// UnimplementedFeatureError 1834: Not yet implemented - FixedPointType. diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/317_fixed_type_valid_explicit_conversions.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/317_fixed_type_valid_explicit_conversions.sol index 4899b3d786f7..fa32ec7dd86a 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/317_fixed_type_valid_explicit_conversions.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/317_fixed_type_valid_explicit_conversions.sol @@ -6,5 +6,5 @@ contract test { } } // ---- -// UnimplementedFeatureError: Not yet implemented - FixedPointType. // Warning 2018: (20-182): Function state mutability can be restricted to pure +// UnimplementedFeatureError 1834: Not yet implemented - FixedPointType. diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/323_mapping_with_fixed_literal.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/323_mapping_with_fixed_literal.sol index 20ebcb1fef37..cb730221dfcd 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/323_mapping_with_fixed_literal.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/323_mapping_with_fixed_literal.sol @@ -5,4 +5,4 @@ contract test { } } // ---- -// UnimplementedFeatureError: Not yet implemented - FixedPointType. +// UnimplementedFeatureError 1834: Not yet implemented - FixedPointType. diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/324_fixed_points_inside_structs.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/324_fixed_points_inside_structs.sol index 24a090127cb2..9bc6243029d1 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/324_fixed_points_inside_structs.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/324_fixed_points_inside_structs.sol @@ -6,4 +6,4 @@ contract test { myStruct a = myStruct(3.125, 3); } // ---- -// UnimplementedFeatureError: Not yet implemented - FixedPointType. +// UnimplementedFeatureError 1834: Not yet implemented - FixedPointType. diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/328_rational_to_fixed_literal_expression.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/328_rational_to_fixed_literal_expression.sol index 4dbcb3f206c0..8391734aec0f 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/328_rational_to_fixed_literal_expression.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/328_rational_to_fixed_literal_expression.sol @@ -11,6 +11,6 @@ contract test { } } // ---- -// UnimplementedFeatureError: Not yet implemented - FixedPointType. // Warning 2519: (238-252): This declaration shadows an existing declaration. // Warning 2018: (20-339): Function state mutability can be restricted to pure +// UnimplementedFeatureError 1834: Not yet implemented - FixedPointType. diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/343_integer_and_fixed_interaction.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/343_integer_and_fixed_interaction.sol index ad7b34fd76ec..15ca25931efd 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/343_integer_and_fixed_interaction.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/343_integer_and_fixed_interaction.sol @@ -4,6 +4,6 @@ contract test { } } // ---- -// UnimplementedFeatureError: Not yet implemented - FixedPointType. // Warning 2072: (50-58): Unused local variable. // Warning 2018: (20-89): Function state mutability can be restricted to pure +// UnimplementedFeatureError 1834: Not yet implemented - FixedPointType. diff --git a/test/libsolidity/syntaxTests/parsing/declaring_fixed_and_ufixed_variables.sol b/test/libsolidity/syntaxTests/parsing/declaring_fixed_and_ufixed_variables.sol index e34522540e8d..ea41bbf3ec7a 100644 --- a/test/libsolidity/syntaxTests/parsing/declaring_fixed_and_ufixed_variables.sol +++ b/test/libsolidity/syntaxTests/parsing/declaring_fixed_and_ufixed_variables.sol @@ -6,9 +6,9 @@ contract A { } } // ---- -// UnimplementedFeatureError: Fixed point types not implemented. // Warning 5667: (52-60): Unused function parameter. Remove or comment out the variable name to silence this warning. // Warning 5667: (62-74): Unused function parameter. Remove or comment out the variable name to silence this warning. // Warning 2072: (93-104): Unused local variable. // Warning 2072: (114-121): Unused local variable. // Warning 2018: (41-128): Function state mutability can be restricted to pure +// UnimplementedFeatureError 1834: Fixed point types not implemented. diff --git a/test/libsolidity/syntaxTests/parsing/lexer_numbers_with_underscores_fixed.sol b/test/libsolidity/syntaxTests/parsing/lexer_numbers_with_underscores_fixed.sol index 00ed4f6540cf..9932c4c3d48b 100644 --- a/test/libsolidity/syntaxTests/parsing/lexer_numbers_with_underscores_fixed.sol +++ b/test/libsolidity/syntaxTests/parsing/lexer_numbers_with_underscores_fixed.sol @@ -7,4 +7,4 @@ contract C { } } // ---- -// UnimplementedFeatureError: Not yet implemented - FixedPointType. +// UnimplementedFeatureError 1834: Not yet implemented - FixedPointType. diff --git a/test/libsolidity/syntaxTests/types/rational_number_literal_to_fixed_implicit.sol b/test/libsolidity/syntaxTests/types/rational_number_literal_to_fixed_implicit.sol index 5bceec60955d..a93555fd7120 100644 --- a/test/libsolidity/syntaxTests/types/rational_number_literal_to_fixed_implicit.sol +++ b/test/libsolidity/syntaxTests/types/rational_number_literal_to_fixed_implicit.sol @@ -13,4 +13,4 @@ contract C { } } // ---- -// UnimplementedFeatureError: Not yet implemented - FixedPointType. +// UnimplementedFeatureError 1834: Not yet implemented - FixedPointType. From 48f97a377aa92b7a466df826a5a57d6de92accc0 Mon Sep 17 00:00:00 2001 From: Pawel Gebal Date: Mon, 10 Jun 2024 17:33:11 +0200 Subject: [PATCH 0266/1022] SMTChecker: Fix error that reported invalid number of verified checks for BMC and CHC engines --- Changelog.md | 1 + libsolidity/formal/BMC.cpp | 7 ++++++- libsolidity/formal/BMC.h | 5 ++++- .../constructor_state_variable_init.sol | 2 +- .../smtCheckerTests/operators/unary_minus_bmc.sol | 2 +- ...ined_operator_matches_equivalent_function_call.sol | 2 +- .../overflow/overflow_and_underflow_bmc.sol | 11 +++++++++++ 7 files changed, 25 insertions(+), 5 deletions(-) create mode 100644 test/libsolidity/smtCheckerTests/overflow/overflow_and_underflow_bmc.sol diff --git a/Changelog.md b/Changelog.md index 29fb86250b6e..de3fc3d6cf13 100644 --- a/Changelog.md +++ b/Changelog.md @@ -11,6 +11,7 @@ Compiler Features: Bugfixes: + * SMTChecker: Fix error that reports invalid number of verified checks for BMC engine. * TypeChecker: Fix segfault when assigning nested tuple to tuple. * Yul Optimizer: Name simplification could lead to forbidden identifiers with a leading and/or trailing dot, e.g., ``x._`` would get simplified into ``x.``. diff --git a/libsolidity/formal/BMC.cpp b/libsolidity/formal/BMC.cpp index 916bf5a31db0..b1a326fc77c4 100644 --- a/libsolidity/formal/BMC.cpp +++ b/libsolidity/formal/BMC.cpp @@ -118,13 +118,18 @@ void BMC::analyze(SourceUnit const& _source, std::mapid() < _b.expression->id(); + if (_a.expression->id() == _b.expression->id()) + return _a.type < _b.type; + else + return _a.expression->id() < _b.expression->id(); } }; diff --git a/test/libsolidity/smtCheckerTests/bmc_coverage/branches_with_return/constructor_state_variable_init.sol b/test/libsolidity/smtCheckerTests/bmc_coverage/branches_with_return/constructor_state_variable_init.sol index 4728a1cb0e61..a5ec4d87f539 100644 --- a/test/libsolidity/smtCheckerTests/bmc_coverage/branches_with_return/constructor_state_variable_init.sol +++ b/test/libsolidity/smtCheckerTests/bmc_coverage/branches_with_return/constructor_state_variable_init.sol @@ -39,4 +39,4 @@ contract C is B { // Warning 4661: (389-412): BMC: Assertion violation happens here. // Warning 4661: (489-513): BMC: Assertion violation happens here. // Warning 4661: (533-546): BMC: Assertion violation happens here. -// Info 6002: BMC: 4 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. +// Info 6002: BMC: 5 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/operators/unary_minus_bmc.sol b/test/libsolidity/smtCheckerTests/operators/unary_minus_bmc.sol index 052554d21c63..66e80539d097 100644 --- a/test/libsolidity/smtCheckerTests/operators/unary_minus_bmc.sol +++ b/test/libsolidity/smtCheckerTests/operators/unary_minus_bmc.sol @@ -8,4 +8,4 @@ contract C // SMTEngine: bmc // ---- // Warning 4661: (48-63): BMC: Assertion violation happens here. -// Info 6002: BMC: 1 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. +// Info 6002: BMC: 2 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/operators/userDefined/user_defined_operator_matches_equivalent_function_call.sol b/test/libsolidity/smtCheckerTests/operators/userDefined/user_defined_operator_matches_equivalent_function_call.sol index 33665ee26dcc..9872a6a92b26 100644 --- a/test/libsolidity/smtCheckerTests/operators/userDefined/user_defined_operator_matches_equivalent_function_call.sol +++ b/test/libsolidity/smtCheckerTests/operators/userDefined/user_defined_operator_matches_equivalent_function_call.sol @@ -77,4 +77,4 @@ contract C { // Warning 4144: (953-982): BMC: Underflow (resulting value less than -32768) happens here. // Warning 3046: (1149-1178): BMC: Division by zero happens here. // Warning 7812: (2245-2271): BMC: Assertion violation might happen here. -// Info 6002: BMC: 8 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. +// Info 6002: BMC: 10 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/overflow/overflow_and_underflow_bmc.sol b/test/libsolidity/smtCheckerTests/overflow/overflow_and_underflow_bmc.sol new file mode 100644 index 000000000000..b788acebf3a5 --- /dev/null +++ b/test/libsolidity/smtCheckerTests/overflow/overflow_and_underflow_bmc.sol @@ -0,0 +1,11 @@ +contract C { + function f(int x, int y) public pure returns (int) { + require(x == 0); + require(y == 0); + return x + y; + } +} +// ==== +// SMTEngine: bmc +// ---- +// Info 6002: BMC: 2 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. From 6ccb3a340c363558900f59c3773cce11ed4957df Mon Sep 17 00:00:00 2001 From: Pawel Gebal Date: Mon, 10 Jun 2024 17:33:11 +0200 Subject: [PATCH 0267/1022] SMTChecker: Fix internal compiler error on reporting proved targets --- Changelog.md | 3 ++- libsolidity/formal/BMC.cpp | 6 +++--- libsolidity/formal/BMC.h | 1 + libsolidity/formal/CHC.cpp | 12 +++++++++--- libsolidity/formal/CHC.h | 16 ++++++++++++++-- libsolidity/formal/ModelChecker.cpp | 11 +++++++++-- libsolidity/formal/ModelChecker.h | 6 ++++++ libsolidity/formal/SMTEncoder.cpp | 2 ++ libsolidity/formal/SMTEncoder.h | 2 ++ scripts/error_codes.py | 1 - .../push_as_lhs_compound_assignment.sol | 2 +- .../constructor_state_variable_init.sol | 2 +- .../constructor_state_variable_init_asserts.sol | 2 +- ...onstructor_state_variable_init_chain_tree.sol | 2 +- .../inheritance/diamond_super_3.sol | 2 +- .../assignment_contract_member_variable.sol | 2 +- ...ssignment_module_contract_member_variable.sol | 2 +- .../smtCheckerTests/operators/division_4.sol | 2 +- .../operators/division_truncates_correctly_2.sol | 2 +- .../operators/division_truncates_correctly_3.sol | 2 +- .../operators/division_truncates_correctly_4.sol | 2 +- .../operators/division_truncates_correctly_5.sol | 2 +- .../smtCheckerTests/operators/mod.sol | 2 +- .../smtCheckerTests/operators/mod_signed.sol | 2 +- .../operators/unary_add_array_push_2.sol | 2 +- .../operators/unary_minus_chc.sol | 2 +- .../user_defined_operations_on_constants.sol | 2 +- ...user_defined_operations_on_constants_fail.sol | 2 +- .../overflow_and_underflow_bmc_show_proved.sol | 13 +++++++++++++ .../overflow/overflow_and_underflow_chc.sol | 11 +++++++++++ .../overflow/signed_guard_sum_overflow.sol | 2 +- .../smtCheckerTests/try_catch/try_3.sol | 2 +- .../smtCheckerTests/typecast/downcast.sol | 2 +- .../unchecked/flipping_sign_tests.sol | 2 +- 34 files changed, 94 insertions(+), 34 deletions(-) create mode 100644 test/libsolidity/smtCheckerTests/overflow/overflow_and_underflow_bmc_show_proved.sol create mode 100644 test/libsolidity/smtCheckerTests/overflow/overflow_and_underflow_chc.sol diff --git a/Changelog.md b/Changelog.md index de3fc3d6cf13..8343d2f72870 100644 --- a/Changelog.md +++ b/Changelog.md @@ -11,7 +11,8 @@ Compiler Features: Bugfixes: - * SMTChecker: Fix error that reports invalid number of verified checks for BMC engine. + * SMTChecker: Fix error that reports invalid number of verified checks for BMC and CHC engines. + * SMTChecker: Fix internal compiler error when reporting proved targets for BMC engine. * TypeChecker: Fix segfault when assigning nested tuple to tuple. * Yul Optimizer: Name simplification could lead to forbidden identifiers with a leading and/or trailing dot, e.g., ``x._`` would get simplified into ``x.``. diff --git a/libsolidity/formal/BMC.cpp b/libsolidity/formal/BMC.cpp index b1a326fc77c4..46812c409b47 100644 --- a/libsolidity/formal/BMC.cpp +++ b/libsolidity/formal/BMC.cpp @@ -47,12 +47,13 @@ BMC::BMC( smt::EncodingContext& _context, UniqueErrorReporter& _errorReporter, UniqueErrorReporter& _unsupportedErrorReporter, + ErrorReporter& _provedSafeReporter, std::map const& _smtlib2Responses, ReadCallback::Callback const& _smtCallback, ModelCheckerSettings _settings, CharStreamProvider const& _charStreamProvider ): - SMTEncoder(_context, _settings, _errorReporter, _unsupportedErrorReporter, _charStreamProvider) + SMTEncoder(_context, _settings, _errorReporter, _unsupportedErrorReporter, _provedSafeReporter, _charStreamProvider) { solAssert(!_settings.printQuery || _settings.solvers == SMTSolverChoice::SMTLIB2(), "Only SMTLib2 solver can be enabled to print queries"); std::vector> solvers; @@ -133,7 +134,7 @@ void BMC::analyze(SourceUnit const& _source, std::maplocation(), "BMC: " + @@ -141,7 +142,6 @@ void BMC::analyze(SourceUnit const& _source, std::map const& _smtlib2Responses, ReadCallback::Callback const& _smtCallback, ModelCheckerSettings _settings, diff --git a/libsolidity/formal/CHC.cpp b/libsolidity/formal/CHC.cpp index 66ebd47edb98..357291f2792b 100644 --- a/libsolidity/formal/CHC.cpp +++ b/libsolidity/formal/CHC.cpp @@ -63,12 +63,13 @@ CHC::CHC( EncodingContext& _context, UniqueErrorReporter& _errorReporter, UniqueErrorReporter& _unsupportedErrorReporter, + ErrorReporter& _provedSafeReporter, std::map const& _smtlib2Responses, ReadCallback::Callback const& _smtCallback, ModelCheckerSettings _settings, CharStreamProvider const& _charStreamProvider ): - SMTEncoder(_context, _settings, _errorReporter, _unsupportedErrorReporter, _charStreamProvider), + SMTEncoder(_context, _settings, _errorReporter, _unsupportedErrorReporter, _provedSafeReporter, _charStreamProvider), m_smtlib2Responses(_smtlib2Responses), m_smtCallback(_smtCallback) { @@ -2113,17 +2114,22 @@ void CHC::checkVerificationTargets() ); if (!m_settings.showProvedSafe && !m_safeTargets.empty()) + { + std::size_t provedSafeNum = 0; + for (auto&& [_, targets]: m_safeTargets) + provedSafeNum += targets.size(); m_errorReporter.info( 1391_error, "CHC: " + - std::to_string(m_safeTargets.size()) + + std::to_string(provedSafeNum) + " verification condition(s) proved safe!" + " Enable the model checker option \"show proved safe\" to see all of them." ); + } else if (m_settings.showProvedSafe) for (auto const& [node, targets]: m_safeTargets) for (auto const& target: targets) - m_errorReporter.info( + m_provedSafeReporter.info( 9576_error, node->location(), "CHC: " + diff --git a/libsolidity/formal/CHC.h b/libsolidity/formal/CHC.h index be150baf1b54..b60e5c3f771e 100644 --- a/libsolidity/formal/CHC.h +++ b/libsolidity/formal/CHC.h @@ -58,6 +58,7 @@ class CHC: public SMTEncoder smt::EncodingContext& _context, langutil::UniqueErrorReporter& _errorReporter, langutil::UniqueErrorReporter& _unsupportedErrorReporter, + langutil::ErrorReporter& _provedSafeReporter, std::map const& _smtlib2Responses, ReadCallback::Callback const& _smtCallback, ModelCheckerSettings _settings, @@ -77,6 +78,17 @@ class CHC: public SMTEncoder } }; + struct SafeTargetsCompare + { + bool operator()(CHCVerificationTarget const & _lhs, CHCVerificationTarget const & _rhs) const + { + if (_lhs.errorNode->id() == _rhs.errorNode->id()) + return _lhs.type < _rhs.type; + else + return _lhs.errorNode->id() == _rhs.errorNode->id(); + } + }; + struct ReportTargetInfo { langutil::ErrorId error; @@ -84,7 +96,7 @@ class CHC: public SMTEncoder std::string message; }; - std::map, smt::EncodingContext::IdCompare> const& safeTargets() const { return m_safeTargets; } + std::map, smt::EncodingContext::IdCompare> const& safeTargets() const { return m_safeTargets; } std::map, smt::EncodingContext::IdCompare> const& unsafeTargets() const { return m_unsafeTargets; } /// This is used if the Horn solver is not directly linked into this binary. @@ -423,7 +435,7 @@ class CHC: public SMTEncoder std::map m_verificationTargets; /// Targets proved safe. - std::map, smt::EncodingContext::IdCompare> m_safeTargets; + std::map, smt::EncodingContext::IdCompare> m_safeTargets; /// Targets proved unsafe. std::map, smt::EncodingContext::IdCompare> m_unsafeTargets; /// Targets not proved. diff --git a/libsolidity/formal/ModelChecker.cpp b/libsolidity/formal/ModelChecker.cpp index 94a927d3b239..91b88cb9c842 100644 --- a/libsolidity/formal/ModelChecker.cpp +++ b/libsolidity/formal/ModelChecker.cpp @@ -43,10 +43,11 @@ ModelChecker::ModelChecker( ReadCallback::Callback const& _smtCallback ): m_errorReporter(_errorReporter), + m_provedSafeReporter(m_provedSafeLogs), m_settings(std::move(_settings)), m_context(), - m_bmc(m_context, m_uniqueErrorReporter, m_unsupportedErrorReporter, _smtlib2Responses, _smtCallback, m_settings, _charStreamProvider), - m_chc(m_context, m_uniqueErrorReporter, m_unsupportedErrorReporter, _smtlib2Responses, _smtCallback, m_settings, _charStreamProvider) + m_bmc(m_context, m_uniqueErrorReporter, m_unsupportedErrorReporter, m_provedSafeReporter, _smtlib2Responses, _smtCallback, m_settings, _charStreamProvider), + m_chc(m_context, m_uniqueErrorReporter, m_unsupportedErrorReporter, m_provedSafeReporter, _smtlib2Responses, _smtCallback, m_settings, _charStreamProvider) { } @@ -151,6 +152,12 @@ void ModelChecker::analyze(SourceUnit const& _source) m_errorReporter.append(m_uniqueErrorReporter.errors()); m_uniqueErrorReporter.clear(); + + if (m_settings.showProvedSafe) + { + m_errorReporter.append(m_provedSafeReporter.errors()); + m_provedSafeReporter.clear(); + } } std::vector ModelChecker::unhandledQueries() diff --git a/libsolidity/formal/ModelChecker.h b/libsolidity/formal/ModelChecker.h index 4c795fa7079d..2fd4885d5a8e 100644 --- a/libsolidity/formal/ModelChecker.h +++ b/libsolidity/formal/ModelChecker.h @@ -95,6 +95,12 @@ class ModelChecker /// to m_errorReporter at the end of the analysis. langutil::UniqueErrorReporter m_unsupportedErrorReporter; + langutil::ErrorList m_provedSafeLogs; + /// Used by SMTEncoder, BMC and CHC to accumulate info about proved targets. + /// This is local to ModelChecker, so needs to be appended + /// to m_errorReporter at the end of the analysis. + langutil::ErrorReporter m_provedSafeReporter; + ModelCheckerSettings m_settings; /// Stores the context of the encoding. diff --git a/libsolidity/formal/SMTEncoder.cpp b/libsolidity/formal/SMTEncoder.cpp index c92c5399a685..44282289d1e2 100644 --- a/libsolidity/formal/SMTEncoder.cpp +++ b/libsolidity/formal/SMTEncoder.cpp @@ -51,10 +51,12 @@ SMTEncoder::SMTEncoder( ModelCheckerSettings _settings, UniqueErrorReporter& _errorReporter, UniqueErrorReporter& _unsupportedErrorReporter, + ErrorReporter& _provedSafeReporter, langutil::CharStreamProvider const& _charStreamProvider ): m_errorReporter(_errorReporter), m_unsupportedErrors(_unsupportedErrorReporter), + m_provedSafeReporter(_provedSafeReporter), m_context(_context), m_settings(std::move(_settings)), m_charStreamProvider(_charStreamProvider) diff --git a/libsolidity/formal/SMTEncoder.h b/libsolidity/formal/SMTEncoder.h index bea3a85ef9c8..c017d5c12389 100644 --- a/libsolidity/formal/SMTEncoder.h +++ b/libsolidity/formal/SMTEncoder.h @@ -57,6 +57,7 @@ class SMTEncoder: public ASTConstVisitor ModelCheckerSettings _settings, langutil::UniqueErrorReporter& _errorReporter, langutil::UniqueErrorReporter& _unsupportedErrorReporter, + langutil::ErrorReporter& _provedSafeReporter, langutil::CharStreamProvider const& _charStreamProvider ); @@ -450,6 +451,7 @@ class SMTEncoder: public ASTConstVisitor langutil::UniqueErrorReporter& m_errorReporter; langutil::UniqueErrorReporter& m_unsupportedErrors; + langutil::ErrorReporter& m_provedSafeReporter; /// Stores the current function/modifier call/invocation path. std::vector m_callStack; diff --git a/scripts/error_codes.py b/scripts/error_codes.py index 24ec2b06d617..6ca9dd085264 100755 --- a/scripts/error_codes.py +++ b/scripts/error_codes.py @@ -204,7 +204,6 @@ def examine_id_coverage(top_dir, source_id_to_file_names, new_ids_only=False): "1920", # Unimplemented feature error from YulStack (currently there are no UnimplementedFeatureErrors thrown by libyul) "1180", # SMTChecker, covered by CL tests "2339", # SMTChecker, covered by CL tests - "2961", # SMTChecker, covered by CL tests "6240", # SMTChecker, covered by CL tests } assert len(test_ids & white_ids) == 0, "The sets are not supposed to intersect" diff --git a/test/libsolidity/smtCheckerTests/array_members/push_as_lhs_compound_assignment.sol b/test/libsolidity/smtCheckerTests/array_members/push_as_lhs_compound_assignment.sol index 4d20c8ae9b68..b059482ac242 100644 --- a/test/libsolidity/smtCheckerTests/array_members/push_as_lhs_compound_assignment.sol +++ b/test/libsolidity/smtCheckerTests/array_members/push_as_lhs_compound_assignment.sol @@ -13,4 +13,4 @@ contract C { // SMTEngine: all // ---- // Warning 6328: (128-145): CHC: Assertion violation happens here. -// Info 1391: CHC: 4 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. +// Info 1391: CHC: 5 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/control_flow/branches_with_return/constructor_state_variable_init.sol b/test/libsolidity/smtCheckerTests/control_flow/branches_with_return/constructor_state_variable_init.sol index 88036eb550de..69be20b5327b 100644 --- a/test/libsolidity/smtCheckerTests/control_flow/branches_with_return/constructor_state_variable_init.sol +++ b/test/libsolidity/smtCheckerTests/control_flow/branches_with_return/constructor_state_variable_init.sol @@ -39,4 +39,4 @@ contract C is B { // Warning 6328: (389-412): CHC: Assertion violation happens here. // Warning 6328: (489-513): CHC: Assertion violation happens here. // Warning 6328: (533-546): CHC: Assertion violation happens here. -// Info 1391: CHC: 4 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. +// Info 1391: CHC: 5 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/inheritance/constructor_state_variable_init_asserts.sol b/test/libsolidity/smtCheckerTests/inheritance/constructor_state_variable_init_asserts.sol index db81b1d0fdb0..23f831d71354 100644 --- a/test/libsolidity/smtCheckerTests/inheritance/constructor_state_variable_init_asserts.sol +++ b/test/libsolidity/smtCheckerTests/inheritance/constructor_state_variable_init_asserts.sol @@ -37,4 +37,4 @@ contract C is B { // Warning 6328: (339-362): CHC: Assertion violation happens here. // Warning 6328: (439-463): CHC: Assertion violation happens here. // Warning 6328: (483-496): CHC: Assertion violation happens here. -// Info 1391: CHC: 4 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. +// Info 1391: CHC: 5 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/inheritance/constructor_state_variable_init_chain_tree.sol b/test/libsolidity/smtCheckerTests/inheritance/constructor_state_variable_init_chain_tree.sol index 8fe0cb28e0f0..767d28d52bad 100644 --- a/test/libsolidity/smtCheckerTests/inheritance/constructor_state_variable_init_chain_tree.sol +++ b/test/libsolidity/smtCheckerTests/inheritance/constructor_state_variable_init_chain_tree.sol @@ -41,4 +41,4 @@ contract C is B { // ---- // Warning 6328: (403-417): CHC: Assertion violation happens here. // Warning 6328: (450-463): CHC: Assertion violation happens here. -// Info 1391: CHC: 7 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. +// Info 1391: CHC: 8 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/inheritance/diamond_super_3.sol b/test/libsolidity/smtCheckerTests/inheritance/diamond_super_3.sol index f6674021ebf0..68bfb883a32e 100644 --- a/test/libsolidity/smtCheckerTests/inheritance/diamond_super_3.sol +++ b/test/libsolidity/smtCheckerTests/inheritance/diamond_super_3.sol @@ -34,4 +34,4 @@ contract E is C,D { // SMTIgnoreCex: no // ---- // Warning 6328: (379-394): CHC: Assertion violation happens here.\nCounterexample:\nx = 111\n\nTransaction trace:\nE.constructor()\nState: x = 0\nE.f()\n C.f() -- internal call\n B.f() -- internal call\n A.f() -- internal call -// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. +// Info 1391: CHC: 5 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/operators/assignment_contract_member_variable.sol b/test/libsolidity/smtCheckerTests/operators/assignment_contract_member_variable.sol index 40eb48672ebe..2c5fdbf003e7 100644 --- a/test/libsolidity/smtCheckerTests/operators/assignment_contract_member_variable.sol +++ b/test/libsolidity/smtCheckerTests/operators/assignment_contract_member_variable.sol @@ -30,4 +30,4 @@ contract A { // SMTIgnoreInv: yes // ---- // Warning 6328: (392-408): CHC: Assertion violation happens here. -// Info 1391: CHC: 17 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. +// Info 1391: CHC: 26 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/operators/assignment_module_contract_member_variable.sol b/test/libsolidity/smtCheckerTests/operators/assignment_module_contract_member_variable.sol index baa1c75a474a..c943dc80019c 100644 --- a/test/libsolidity/smtCheckerTests/operators/assignment_module_contract_member_variable.sol +++ b/test/libsolidity/smtCheckerTests/operators/assignment_module_contract_member_variable.sol @@ -31,4 +31,4 @@ contract A { // ---- // Warning 6328: (AASource:159-178): CHC: Assertion violation happens here. // Warning 6328: (AASource:370-386): CHC: Assertion violation happens here. -// Info 1391: CHC: 16 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. +// Info 1391: CHC: 25 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/operators/division_4.sol b/test/libsolidity/smtCheckerTests/operators/division_4.sol index 54403b1ec1e0..134ddfc5241f 100644 --- a/test/libsolidity/smtCheckerTests/operators/division_4.sol +++ b/test/libsolidity/smtCheckerTests/operators/division_4.sol @@ -8,4 +8,4 @@ contract C { // ==== // SMTEngine: all // ---- -// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. +// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/operators/division_truncates_correctly_2.sol b/test/libsolidity/smtCheckerTests/operators/division_truncates_correctly_2.sol index 29af565a223e..a0ce8024c6aa 100644 --- a/test/libsolidity/smtCheckerTests/operators/division_truncates_correctly_2.sol +++ b/test/libsolidity/smtCheckerTests/operators/division_truncates_correctly_2.sol @@ -8,4 +8,4 @@ contract C { // ==== // SMTEngine: all // ---- -// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. +// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/operators/division_truncates_correctly_3.sol b/test/libsolidity/smtCheckerTests/operators/division_truncates_correctly_3.sol index 573f6d246812..82aac9d4fde4 100644 --- a/test/libsolidity/smtCheckerTests/operators/division_truncates_correctly_3.sol +++ b/test/libsolidity/smtCheckerTests/operators/division_truncates_correctly_3.sol @@ -8,4 +8,4 @@ contract C { // ==== // SMTEngine: all // ---- -// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. +// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/operators/division_truncates_correctly_4.sol b/test/libsolidity/smtCheckerTests/operators/division_truncates_correctly_4.sol index 6610bc524461..a56594554616 100644 --- a/test/libsolidity/smtCheckerTests/operators/division_truncates_correctly_4.sol +++ b/test/libsolidity/smtCheckerTests/operators/division_truncates_correctly_4.sol @@ -8,4 +8,4 @@ contract C { // ==== // SMTEngine: all // ---- -// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. +// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/operators/division_truncates_correctly_5.sol b/test/libsolidity/smtCheckerTests/operators/division_truncates_correctly_5.sol index 97faba60fb3b..2b93bbae13e3 100644 --- a/test/libsolidity/smtCheckerTests/operators/division_truncates_correctly_5.sol +++ b/test/libsolidity/smtCheckerTests/operators/division_truncates_correctly_5.sol @@ -8,4 +8,4 @@ contract C { // ==== // SMTEngine: all // ---- -// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. +// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/operators/mod.sol b/test/libsolidity/smtCheckerTests/operators/mod.sol index d12e5c49d5a3..b5aae4d40e01 100644 --- a/test/libsolidity/smtCheckerTests/operators/mod.sol +++ b/test/libsolidity/smtCheckerTests/operators/mod.sol @@ -10,4 +10,4 @@ contract C { // ==== // SMTEngine: all // ---- -// Info 1391: CHC: 4 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. +// Info 1391: CHC: 5 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/operators/mod_signed.sol b/test/libsolidity/smtCheckerTests/operators/mod_signed.sol index c34bd08e3adb..3741b534793a 100644 --- a/test/libsolidity/smtCheckerTests/operators/mod_signed.sol +++ b/test/libsolidity/smtCheckerTests/operators/mod_signed.sol @@ -12,5 +12,5 @@ contract C { // SMTEngine: all // ---- // Warning 6328: (131-148): CHC: Assertion violation might happen here. -// Info 1391: CHC: 5 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. +// Info 1391: CHC: 7 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. // Info 6002: BMC: 1 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/operators/unary_add_array_push_2.sol b/test/libsolidity/smtCheckerTests/operators/unary_add_array_push_2.sol index a6cacac08a26..a6e07809164d 100644 --- a/test/libsolidity/smtCheckerTests/operators/unary_add_array_push_2.sol +++ b/test/libsolidity/smtCheckerTests/operators/unary_add_array_push_2.sol @@ -18,4 +18,4 @@ contract C { // ==== // SMTEngine: all // ---- -// Info 1391: CHC: 7 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. +// Info 1391: CHC: 8 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/operators/unary_minus_chc.sol b/test/libsolidity/smtCheckerTests/operators/unary_minus_chc.sol index 0d1bf972be49..d36978c688b3 100644 --- a/test/libsolidity/smtCheckerTests/operators/unary_minus_chc.sol +++ b/test/libsolidity/smtCheckerTests/operators/unary_minus_chc.sol @@ -8,4 +8,4 @@ contract C // SMTEngine: chc // ---- // Warning 6328: (48-63): CHC: Assertion violation happens here. -// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. +// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/operators/userDefined/user_defined_operations_on_constants.sol b/test/libsolidity/smtCheckerTests/operators/userDefined/user_defined_operations_on_constants.sol index 49420440f456..7f3f9702cead 100644 --- a/test/libsolidity/smtCheckerTests/operators/userDefined/user_defined_operations_on_constants.sol +++ b/test/libsolidity/smtCheckerTests/operators/userDefined/user_defined_operations_on_constants.sol @@ -60,4 +60,4 @@ contract C { // ==== // SMTEngine: all // ---- -// Info 1391: CHC: 22 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. +// Info 1391: CHC: 27 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/operators/userDefined/user_defined_operations_on_constants_fail.sol b/test/libsolidity/smtCheckerTests/operators/userDefined/user_defined_operations_on_constants_fail.sol index 106a7c5f09a1..dc624393b413 100644 --- a/test/libsolidity/smtCheckerTests/operators/userDefined/user_defined_operations_on_constants_fail.sol +++ b/test/libsolidity/smtCheckerTests/operators/userDefined/user_defined_operations_on_constants_fail.sol @@ -76,4 +76,4 @@ contract C { // Warning 6328: (2741-2758): CHC: Assertion violation happens here. // Warning 6328: (2783-2804): CHC: Assertion violation happens here. // Warning 6328: (2829-2850): CHC: Assertion violation happens here. -// Info 1391: CHC: 6 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. +// Info 1391: CHC: 11 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/overflow/overflow_and_underflow_bmc_show_proved.sol b/test/libsolidity/smtCheckerTests/overflow/overflow_and_underflow_bmc_show_proved.sol new file mode 100644 index 000000000000..2674890f6b8b --- /dev/null +++ b/test/libsolidity/smtCheckerTests/overflow/overflow_and_underflow_bmc_show_proved.sol @@ -0,0 +1,13 @@ +contract C { + function f(int x, int y) public pure returns (int) { + require(x == 0); + require(y == 0); + return x + y; + } +} +// ==== +// SMTEngine: bmc +// SMTShowProvedSafe: yes +// ---- +// Info 2961: (114-119): BMC: Underflow (resulting value less than -2**255) check is safe! +// Info 2961: (114-119): BMC: Overflow (resulting value larger than 2**255 - 1) check is safe! diff --git a/test/libsolidity/smtCheckerTests/overflow/overflow_and_underflow_chc.sol b/test/libsolidity/smtCheckerTests/overflow/overflow_and_underflow_chc.sol new file mode 100644 index 000000000000..783d12b51a7a --- /dev/null +++ b/test/libsolidity/smtCheckerTests/overflow/overflow_and_underflow_chc.sol @@ -0,0 +1,11 @@ +contract C { + function f(int x, int y) public pure returns (int) { + require(x == 0); + require(y == 0); + return x + y; + } +} +// ==== +// SMTEngine: chc +// ---- +// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/overflow/signed_guard_sum_overflow.sol b/test/libsolidity/smtCheckerTests/overflow/signed_guard_sum_overflow.sol index 7704e2d7e001..58b582b4ba4f 100644 --- a/test/libsolidity/smtCheckerTests/overflow/signed_guard_sum_overflow.sol +++ b/test/libsolidity/smtCheckerTests/overflow/signed_guard_sum_overflow.sol @@ -10,4 +10,4 @@ contract C { // ---- // Warning 3944: (78-83): CHC: Underflow (resulting value less than -2**255) happens here. // Warning 4984: (78-83): CHC: Overflow (resulting value larger than 2**255 - 1) happens here. -// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. +// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/try_catch/try_3.sol b/test/libsolidity/smtCheckerTests/try_catch/try_3.sol index 7698eed0f006..aa4b1eed152f 100644 --- a/test/libsolidity/smtCheckerTests/try_catch/try_3.sol +++ b/test/libsolidity/smtCheckerTests/try_catch/try_3.sol @@ -25,4 +25,4 @@ contract C { // ---- // Warning 5667: (259-273): Unused try/catch parameter. Remove or comment out the variable name to silence this warning. // Warning 6328: (280-294): CHC: Assertion violation happens here.\nCounterexample:\nx = 1\ns = []\n\nTransaction trace:\nC.constructor()\nState: x = 0\nC.f()\n C.postinc() -- internal call -// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. +// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/typecast/downcast.sol b/test/libsolidity/smtCheckerTests/typecast/downcast.sol index bba3585f26cf..d2bb89bae073 100644 --- a/test/libsolidity/smtCheckerTests/typecast/downcast.sol +++ b/test/libsolidity/smtCheckerTests/typecast/downcast.sol @@ -46,4 +46,4 @@ contract C { // ==== // SMTEngine: all // ---- -// Info 1391: CHC: 20 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. +// Info 1391: CHC: 24 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/unchecked/flipping_sign_tests.sol b/test/libsolidity/smtCheckerTests/unchecked/flipping_sign_tests.sol index 536d2a2b443f..71cc3754da96 100644 --- a/test/libsolidity/smtCheckerTests/unchecked/flipping_sign_tests.sol +++ b/test/libsolidity/smtCheckerTests/unchecked/flipping_sign_tests.sol @@ -11,4 +11,4 @@ contract test { // ---- // Warning 4984: (117-119): CHC: Overflow (resulting value larger than 2**255 - 1) happens here. // Warning 6328: (110-125): CHC: Assertion violation happens here. -// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. +// Info 1391: CHC: 4 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. From 050a3a109cc78654bb9c3bbf63101dfc2771b1fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Wed, 5 Jun 2024 21:38:49 +0200 Subject: [PATCH 0268/1022] Remove overly specific handlers for internal errors and unexpected exceptions --- libsolidity/interface/FileReader.cpp | 10 +--- libsolidity/interface/SMTSolverCommand.cpp | 2 +- libsolidity/interface/StandardCompiler.cpp | 53 ------------------- libsolidity/lsp/FileRepository.cpp | 6 +-- test/libsolidity/InlineAssembly.cpp | 15 ++---- .../SolidityExpressionCompiler.cpp | 5 -- test/libyul/ObjectParser.cpp | 26 ++++----- test/libyul/Parser.cpp | 41 ++++++-------- test/soltest.cpp | 10 +--- test/tools/fuzzer_common.cpp | 3 -- test/tools/isoltest.cpp | 14 +---- 11 files changed, 34 insertions(+), 151 deletions(-) diff --git a/libsolidity/interface/FileReader.cpp b/libsolidity/interface/FileReader.cpp index 15181acf607b..913051293d9b 100644 --- a/libsolidity/interface/FileReader.cpp +++ b/libsolidity/interface/FileReader.cpp @@ -164,17 +164,9 @@ ReadCallback::Result FileReader::readFile(std::string const& _kind, std::string m_sourceCodes[_sourceUnitName] = contents; return ReadCallback::Result{true, contents}; } - catch (util::Exception const& _exception) - { - return ReadCallback::Result{false, "Exception in read callback: " + boost::diagnostic_information(_exception)}; - } - catch (std::exception const& _exception) - { - return ReadCallback::Result{false, "Exception in read callback: " + boost::diagnostic_information(_exception)}; - } catch (...) { - return ReadCallback::Result{false, "Unknown exception in read callback: " + boost::current_exception_diagnostic_information()}; + return ReadCallback::Result{false, "Exception in read callback: " + boost::current_exception_diagnostic_information()}; } } diff --git a/libsolidity/interface/SMTSolverCommand.cpp b/libsolidity/interface/SMTSolverCommand.cpp index 75f541692ddc..7dfb448f8bc2 100644 --- a/libsolidity/interface/SMTSolverCommand.cpp +++ b/libsolidity/interface/SMTSolverCommand.cpp @@ -108,7 +108,7 @@ ReadCallback::Result SMTSolverCommand::solve(std::string const& _kind, std::stri } catch (...) { - return ReadCallback::Result{false, "Unknown exception in SMTQuery callback: " + boost::current_exception_diagnostic_information()}; + return ReadCallback::Result{false, "Exception in SMTQuery callback: " + boost::current_exception_diagnostic_information()}; } } diff --git a/libsolidity/interface/StandardCompiler.cpp b/libsolidity/interface/StandardCompiler.cpp index 80f788cb6143..e95dd53bdec4 100644 --- a/libsolidity/interface/StandardCompiler.cpp +++ b/libsolidity/interface/StandardCompiler.cpp @@ -1372,15 +1372,6 @@ Json StandardCompiler::compileSolidity(StandardCompiler::InputsAndSettings _inpu "Uncaught error: " )); } - /// This should not be leaked from compile(). - catch (FatalError const& _exception) - { - errors.emplace_back(formatError( - Error::Type::FatalError, - "general", - "Uncaught fatal error: " + boost::diagnostic_information(_exception) - )); - } catch (CompilerError const& _exception) { errors.emplace_back(formatErrorWithException( @@ -1426,22 +1417,6 @@ Json StandardCompiler::compileSolidity(StandardCompiler::InputsAndSettings _inpu "SMT logic exception" )); } - catch (util::Exception const& _exception) - { - errors.emplace_back(formatError( - Error::Type::Exception, - "general", - "Exception during compilation: " + boost::diagnostic_information(_exception) - )); - } - catch (std::exception const& _exception) - { - errors.emplace_back(formatError( - Error::Type::Exception, - "general", - "Unknown exception during compilation: " + boost::diagnostic_information(_exception) - )); - } catch (...) { errors.emplace_back(formatError( @@ -1755,39 +1730,11 @@ Json StandardCompiler::compile(Json const& _input) noexcept else return formatFatalError(Error::Type::JSONError, "Only \"Solidity\", \"Yul\", \"SolidityAST\" or \"EVMAssembly\" is supported as a language."); } - catch (Json::parse_error const& _exception) - { - return formatFatalError(Error::Type::InternalCompilerError, std::string("JSON parse_error exception: ") + util::removeNlohmannInternalErrorIdentifier(_exception.what())); - } - catch (Json::invalid_iterator const& _exception) - { - return formatFatalError(Error::Type::InternalCompilerError, std::string("JSON invalid_iterator exception: ") + util::removeNlohmannInternalErrorIdentifier(_exception.what())); - } - catch (Json::type_error const& _exception) - { - return formatFatalError(Error::Type::InternalCompilerError, std::string("JSON type_error exception: ") + util::removeNlohmannInternalErrorIdentifier(_exception.what())); - } - catch (Json::out_of_range const& _exception) - { - return formatFatalError(Error::Type::InternalCompilerError, std::string("JSON out_of_range exception: ") + util::removeNlohmannInternalErrorIdentifier(_exception.what())); - } - catch (Json::other_error const& _exception) - { - return formatFatalError(Error::Type::InternalCompilerError, std::string("JSON other_error exception: ") + util::removeNlohmannInternalErrorIdentifier(_exception.what())); - } - catch (Json::exception const& _exception) - { - return formatFatalError(Error::Type::InternalCompilerError, std::string("JSON runtime exception: ") + util::removeNlohmannInternalErrorIdentifier(_exception.what())); - } catch (UnimplementedFeatureError const& _exception) { solAssert(_exception.comment(), "Unimplemented feature errors must include a message for the user"); return formatFatalError(Error::Type::UnimplementedFeatureError, stringOrDefault(_exception.comment())); } - catch (util::Exception const& _exception) - { - return formatFatalError(Error::Type::InternalCompilerError, "Internal exception in StandardCompiler::compile: " + boost::diagnostic_information(_exception)); - } catch (...) { return formatFatalError(Error::Type::InternalCompilerError, "Internal exception in StandardCompiler::compile: " + boost::current_exception_diagnostic_information()); diff --git a/libsolidity/lsp/FileRepository.cpp b/libsolidity/lsp/FileRepository.cpp index 7138cbd86adf..7ba37a731056 100644 --- a/libsolidity/lsp/FileRepository.cpp +++ b/libsolidity/lsp/FileRepository.cpp @@ -170,13 +170,9 @@ frontend::ReadCallback::Result FileRepository::readFile(std::string const& _kind m_sourceCodes[_sourceUnitName] = contents; return ReadCallback::Result{true, std::move(contents)}; } - catch (std::exception const& _exception) - { - return ReadCallback::Result{false, "Exception in read callback: " + boost::diagnostic_information(_exception)}; - } catch (...) { - return ReadCallback::Result{false, "Unknown exception in read callback: " + boost::current_exception_diagnostic_information()}; + return ReadCallback::Result{false, "Exception in read callback: " + boost::current_exception_diagnostic_information()}; } } diff --git a/test/libsolidity/InlineAssembly.cpp b/test/libsolidity/InlineAssembly.cpp index 1c848d600d01..a0aa39be4989 100644 --- a/test/libsolidity/InlineAssembly.cpp +++ b/test/libsolidity/InlineAssembly.cpp @@ -66,18 +66,9 @@ std::optional parseAndReturnFirstError( solidity::frontend::OptimiserSettings::none(), DebugInfoSelection::None() ); - bool success = false; - try - { - success = stack.parseAndAnalyze("", _source); - if (success && _assemble) - stack.assemble(_machine); - } - catch (FatalError const&) - { - BOOST_FAIL("Fatal error leaked."); - success = false; - } + bool success = stack.parseAndAnalyze("", _source); + if (success && _assemble) + stack.assemble(_machine); std::shared_ptr error; for (auto const& e: stack.errors()) { diff --git a/test/libsolidity/SolidityExpressionCompiler.cpp b/test/libsolidity/SolidityExpressionCompiler.cpp index 1df1d9430086..4810b01439b2 100644 --- a/test/libsolidity/SolidityExpressionCompiler.cpp +++ b/test/libsolidity/SolidityExpressionCompiler.cpp @@ -112,11 +112,6 @@ bytes compileFirstExpression( if (!sourceUnit) return bytes(); } - catch (boost::exception const& _e) - { - std::string msg = "Parsing source code failed with:\n" + boost::diagnostic_information(_e); - BOOST_FAIL(msg); - } catch (...) { std::string msg = "Parsing source code failed with:\n" + boost::current_exception_diagnostic_information(); diff --git a/test/libyul/ObjectParser.cpp b/test/libyul/ObjectParser.cpp index d9623384a03e..b23e530601da 100644 --- a/test/libyul/ObjectParser.cpp +++ b/test/libyul/ObjectParser.cpp @@ -55,23 +55,15 @@ namespace std::pair parse(std::string const& _source) { - try - { - YulStack asmStack( - solidity::test::CommonOptions::get().evmVersion(), - solidity::test::CommonOptions::get().eofVersion(), - YulStack::Language::StrictAssembly, - solidity::frontend::OptimiserSettings::none(), - DebugInfoSelection::All() - ); - bool success = asmStack.parseAndAnalyze("source", _source); - return {success, asmStack.errors()}; - } - catch (FatalError const&) - { - BOOST_FAIL("Fatal error leaked."); - } - return {false, {}}; + YulStack asmStack( + solidity::test::CommonOptions::get().evmVersion(), + solidity::test::CommonOptions::get().eofVersion(), + YulStack::Language::StrictAssembly, + solidity::frontend::OptimiserSettings::none(), + DebugInfoSelection::All() + ); + bool success = asmStack.parseAndAnalyze("source", _source); + return {success, asmStack.errors()}; } std::optional parseAndReturnFirstError(std::string const& _source, bool _allowWarningsAndInfos = true) diff --git a/test/libyul/Parser.cpp b/test/libyul/Parser.cpp index 69314abee136..46c4f11a8c00 100644 --- a/test/libyul/Parser.cpp +++ b/test/libyul/Parser.cpp @@ -54,32 +54,25 @@ namespace std::shared_ptr parse(std::string const& _source, Dialect const& _dialect, ErrorReporter& errorReporter) { - try + auto stream = CharStream(_source, ""); + std::map> indicesToSourceNames; + indicesToSourceNames[0] = std::make_shared("source0"); + indicesToSourceNames[1] = std::make_shared("source1"); + + auto parserResult = yul::Parser( + errorReporter, + _dialect, + std::move(indicesToSourceNames) + ).parse(stream); + if (parserResult) { - auto stream = CharStream(_source, ""); - std::map> indicesToSourceNames; - indicesToSourceNames[0] = std::make_shared("source0"); - indicesToSourceNames[1] = std::make_shared("source1"); - - auto parserResult = yul::Parser( + yul::AsmAnalysisInfo analysisInfo; + if (yul::AsmAnalyzer( + analysisInfo, errorReporter, - _dialect, - std::move(indicesToSourceNames) - ).parse(stream); - if (parserResult) - { - yul::AsmAnalysisInfo analysisInfo; - if (yul::AsmAnalyzer( - analysisInfo, - errorReporter, - _dialect - ).analyze(*parserResult)) - return parserResult; - } - } - catch (FatalError const&) - { - BOOST_FAIL("Fatal error leaked."); + _dialect + ).analyze(*parserResult)) + return parserResult; } return {}; } diff --git a/test/soltest.cpp b/test/soltest.cpp index 5fde4bda5679..8e7a3ddcd4a9 100644 --- a/test/soltest.cpp +++ b/test/soltest.cpp @@ -115,17 +115,9 @@ void runTestCase(TestCase::Config const& _config, TestCase::TestCaseCreator cons break; } } - catch (boost::exception const& _e) - { - BOOST_ERROR("Exception during extracted test: " << boost::diagnostic_information(_e)); - } - catch (std::exception const& _e) - { - BOOST_ERROR("Exception during extracted test: " << boost::diagnostic_information(_e)); - } catch (...) { - BOOST_ERROR("Unknown exception during extracted test: " << boost::current_exception_diagnostic_information()); + BOOST_ERROR("Exception during extracted test: " << boost::current_exception_diagnostic_information()); } } diff --git a/test/tools/fuzzer_common.cpp b/test/tools/fuzzer_common.cpp index 8b7dbffa8cfa..a469cbebabde 100644 --- a/test/tools/fuzzer_common.cpp +++ b/test/tools/fuzzer_common.cpp @@ -131,9 +131,6 @@ void FuzzerUtil::testCompiler( catch (Error const&) { } - catch (FatalError const&) - { - } catch (UnimplementedFeatureError const&) { } diff --git a/test/tools/isoltest.cpp b/test/tools/isoltest.cpp index fa56b35d7dc2..57ab4af16034 100644 --- a/test/tools/isoltest.cpp +++ b/test/tools/isoltest.cpp @@ -191,22 +191,10 @@ TestTool::Result TestTool::process() else return Result::Skipped; } - catch (boost::exception const& _e) - { - AnsiColorized(std::cout, formatted, {BOLD, RED}) << - "Exception during test: " << boost::diagnostic_information(_e) << std::endl; - return Result::Exception; - } - catch (std::exception const& _e) - { - AnsiColorized(std::cout, formatted, {BOLD, RED}) << - "Exception during test: " << boost::diagnostic_information(_e) << std::endl; - return Result::Exception; - } catch (...) { AnsiColorized(std::cout, formatted, {BOLD, RED}) << - "Unknown exception during test: " << boost::current_exception_diagnostic_information() << std::endl; + "Unhandled exception during test: " << boost::current_exception_diagnostic_information() << std::endl; return Result::Exception; } } From 9b67a390df98195cab0e77dc5723c83431b6a8f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Wed, 5 Jun 2024 21:02:26 +0200 Subject: [PATCH 0269/1022] DocumentationParsingError is never thrown and does not need to be caught --- solc/CommandLineInterface.cpp | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/solc/CommandLineInterface.cpp b/solc/CommandLineInterface.cpp index edfd4d52c6b8..a51b77e8e479 100644 --- a/solc/CommandLineInterface.cpp +++ b/solc/CommandLineInterface.cpp @@ -923,17 +923,9 @@ void CommandLineInterface::compile() } catch (Error const& _error) { - if (_error.type() == Error::Type::DocstringParsingError) - { - report(Error::Severity::Error, *boost::get_error_info(_error)); - solThrow(CommandLineExecutionError, "Documentation parsing failed."); - } - else - { - m_hasOutput = true; - formatter.printErrorInformation(_error); - solThrow(CommandLineExecutionError, ""); - } + m_hasOutput = true; + formatter.printErrorInformation(_error); + solThrow(CommandLineExecutionError, ""); } } From c2c8c2876822792ba4e1f6d779a13d0359fd3fe1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Thu, 6 Jun 2024 20:19:54 +0200 Subject: [PATCH 0270/1022] Treat util::Error as unexpected outside of codegen - In analysis we use an error reporter and never just throw util::Error. We do it in one case in the codegen (CodeGenerationError) but outside of that case this should not be treated as a proper way to report an error. - Now such errors will be treated as unexpected. They're bugs that should be fixed. --- libsolidity/interface/CompilerStack.cpp | 6 ++++-- libsolidity/interface/StandardCompiler.cpp | 11 ----------- solc/CommandLineInterface.cpp | 6 ------ test/tools/fuzzer_common.cpp | 3 --- 4 files changed, 4 insertions(+), 22 deletions(-) diff --git a/libsolidity/interface/CompilerStack.cpp b/libsolidity/interface/CompilerStack.cpp index 0a5fed3338cf..8ee55d87f5a5 100644 --- a/libsolidity/interface/CompilerStack.cpp +++ b/libsolidity/interface/CompilerStack.cpp @@ -744,8 +744,10 @@ bool CompilerStack::compile(State _stopAfter) } catch (Error const& _error) { - if (_error.type() != Error::Type::CodeGenerationError) - throw; + // Since codegen has no access to the error reporter, the only way for it to + // report an error is to throw. In most cases it uses dedicated exceptions, + // but CodeGenerationError is one case where someone decided to just throw Error. + solAssert(_error.type() == Error::Type::CodeGenerationError); m_errorReporter.error(_error.errorId(), _error.type(), SourceLocation(), _error.what()); return false; } diff --git a/libsolidity/interface/StandardCompiler.cpp b/libsolidity/interface/StandardCompiler.cpp index e95dd53bdec4..5510b543077c 100644 --- a/libsolidity/interface/StandardCompiler.cpp +++ b/libsolidity/interface/StandardCompiler.cpp @@ -1361,17 +1361,6 @@ Json StandardCompiler::compileSolidity(StandardCompiler::InputsAndSettings _inpu )); } } - /// This is only thrown in a very few locations. - catch (Error const& _error) - { - errors.emplace_back(formatErrorWithException( - compilerStack, - _error, - _error.type(), - "general", - "Uncaught error: " - )); - } catch (CompilerError const& _exception) { errors.emplace_back(formatErrorWithException( diff --git a/solc/CommandLineInterface.cpp b/solc/CommandLineInterface.cpp index a51b77e8e479..367434c93f2a 100644 --- a/solc/CommandLineInterface.cpp +++ b/solc/CommandLineInterface.cpp @@ -921,12 +921,6 @@ void CommandLineInterface::compile() ); solThrow(CommandLineExecutionError, ""); } - catch (Error const& _error) - { - m_hasOutput = true; - formatter.printErrorInformation(_error); - solThrow(CommandLineExecutionError, ""); - } } void CommandLineInterface::handleCombinedJSON() diff --git a/test/tools/fuzzer_common.cpp b/test/tools/fuzzer_common.cpp index a469cbebabde..adf5a064bef7 100644 --- a/test/tools/fuzzer_common.cpp +++ b/test/tools/fuzzer_common.cpp @@ -128,9 +128,6 @@ void FuzzerUtil::testCompiler( { compiler.compile(); } - catch (Error const&) - { - } catch (UnimplementedFeatureError const&) { } From ad2644c52b3afbe80801322c5fe44edb59383500 Mon Sep 17 00:00:00 2001 From: Matheus Aguiar Date: Sat, 6 Apr 2024 17:17:51 -0300 Subject: [PATCH 0271/1022] Make parser accept transient as location (but not a keyword) --- Changelog.md | 1 + docs/grammar/SolidityLexer.g4 | 1 + docs/grammar/SolidityParser.g4 | 5 ++-- .../analysis/DeclarationTypeChecker.cpp | 27 +++++++++++++++++-- libsolidity/ast/AST.cpp | 4 ++- libsolidity/ast/AST.h | 2 +- libsolidity/ast/ASTJsonExporter.cpp | 2 ++ libsolidity/ast/ASTJsonImporter.cpp | 2 ++ libsolidity/ast/Types.cpp | 17 ++++++++++++ libsolidity/ast/Types.h | 2 +- libsolidity/codegen/ArrayUtils.cpp | 6 +++++ libsolidity/codegen/CompilerUtils.cpp | 9 +++++++ libsolidity/codegen/ContractCompiler.cpp | 1 + libsolidity/codegen/ExpressionCompiler.cpp | 6 +++++ libsolidity/codegen/YulUtilFunctions.cpp | 3 +++ .../codegen/ir/IRGeneratorForStatements.cpp | 13 +++++++++ libsolidity/formal/BMC.cpp | 3 +++ libsolidity/formal/CHC.cpp | 3 +++ libsolidity/formal/SMTEncoder.h | 13 +++++++++ libsolidity/interface/StorageLayout.cpp | 1 + libsolidity/parsing/Parser.cpp | 13 +++++++++ scripts/error_codes.py | 1 + .../in.sol | 10 +++++++ .../input.json | 13 +++++++++ .../output.json | 11 ++++++++ .../transient_data_location.sol | 8 ++++++ .../transient_storage_state_variable.sol | 8 ++++++ ...onstant_state_variable_named_transient.sol | 4 +++ .../constant_transient_state_variable.sol | 5 ++++ .../data_location_in_function_type_fail.sol | 3 +++ ...tion_specifier_test_external_transient.sol | 5 ++++ ...tion_specifier_test_internal_transient.sol | 5 ++++ ..._function_with_data_location_transient.sol | 19 +++++++++++++ ...tion_specifier_test_external_transient.sol | 5 ++++ ...tion_specifier_test_internal_transient.sol | 5 ++++ ...sient_data_location_function_parameter.sol | 6 +++++ ...function_parameters_location_transient.sol | 5 ++++ ...n_return_parameters_location_transient.sol | 5 ++++ ...cation_specifier_test_public_transient.sol | 5 ++++ ...n_return_parameters_location_transient.sol | 5 ++++ ...state_variable_storage_named_transient.sol | 5 ++++ .../state_variable_storage_transient.sol | 5 ++++ .../state_variable_transient_storage.sol | 5 ++++ ...transient_dynamic_array_state_variable.sol | 7 +++++ .../transient_fixed_array_state_variable.sol | 7 +++++ .../dataLocations/transient_function_type.sol | 11 ++++++++ .../transient_function_type_parameter.sol | 5 ++++ .../transient_local_variable.sol | 7 +++++ .../transient_mapping_state_variable.sol | 7 +++++ .../transient_state_variable_visibility.sol | 12 +++++++++ .../transient_struct_state_variable.sol | 12 +++++++++ .../transient_value_type_state_variables.sol | 12 +++++++++ ..._value_type_state_variables_assignment.sol | 10 +++++++ .../errors/invalid_parameter_location.sol | 5 ++++ .../events/invalid_parameter_location.sol | 5 ++++ .../events/transient_indexed_parameter.sol | 5 ++++ .../function_type_with_transient_param.sol | 8 ++++++ ...nction_type_with_param_named_transient.sol | 6 +++++ ...ent_function_type_with_transient_param.sol | 5 ++++ .../immutable_state_var_named_transient.sol | 4 +++ .../state_var_transient_data_location.sol | 5 ++++ .../modifiers/multiple_parameter_location.sol | 7 +++++ .../modifiers/transient_parameter.sol | 5 ++++ .../operators/transient_value_type.sol | 11 ++++++++ .../parsing/contract_named_transient.sol | 1 + .../transient_data_location_member.sol | 5 ++++ ...ate_variable_address_payable_transient.sol | 6 +++++ ...ate_variable_address_transient_payable.sol | 5 ++++ .../transient_as_identifier.sol | 25 +++++++++++++++++ ...nsient_as_identifier_and_data_location.sol | 6 +++++ 70 files changed, 474 insertions(+), 7 deletions(-) create mode 100644 test/cmdlineTests/storage_layout_transient_value_types/in.sol create mode 100644 test/cmdlineTests/storage_layout_transient_value_types/input.json create mode 100644 test/cmdlineTests/storage_layout_transient_value_types/output.json create mode 100644 test/libsolidity/astPropertyTests/transient_data_location.sol create mode 100644 test/libsolidity/smtCheckerTests/unsupported/transient_storage_state_variable.sol create mode 100644 test/libsolidity/syntaxTests/constants/constant_state_variable_named_transient.sol create mode 100644 test/libsolidity/syntaxTests/constants/constant_transient_state_variable.sol create mode 100644 test/libsolidity/syntaxTests/dataLocations/externalFunction/function_argument_location_specifier_test_external_transient.sol create mode 100644 test/libsolidity/syntaxTests/dataLocations/internalFunction/function_argument_location_specifier_test_internal_transient.sol create mode 100644 test/libsolidity/syntaxTests/dataLocations/libraries/library_function_with_data_location_transient.sol create mode 100644 test/libsolidity/syntaxTests/dataLocations/libraryExternalFunction/function_argument_location_specifier_test_external_transient.sol create mode 100644 test/libsolidity/syntaxTests/dataLocations/libraryInternalFunction/function_argument_location_specifier_test_internal_transient.sol create mode 100644 test/libsolidity/syntaxTests/dataLocations/multiple_transient_data_location_function_parameter.sol create mode 100644 test/libsolidity/syntaxTests/dataLocations/privateFunction/private_function_parameters_location_transient.sol create mode 100644 test/libsolidity/syntaxTests/dataLocations/privateFunction/private_function_return_parameters_location_transient.sol create mode 100644 test/libsolidity/syntaxTests/dataLocations/publicFunction/function_argument_location_specifier_test_public_transient.sol create mode 100644 test/libsolidity/syntaxTests/dataLocations/publicFunction/public_function_return_parameters_location_transient.sol create mode 100644 test/libsolidity/syntaxTests/dataLocations/state_variable_storage_named_transient.sol create mode 100644 test/libsolidity/syntaxTests/dataLocations/state_variable_storage_transient.sol create mode 100644 test/libsolidity/syntaxTests/dataLocations/state_variable_transient_storage.sol create mode 100644 test/libsolidity/syntaxTests/dataLocations/transient_dynamic_array_state_variable.sol create mode 100644 test/libsolidity/syntaxTests/dataLocations/transient_fixed_array_state_variable.sol create mode 100644 test/libsolidity/syntaxTests/dataLocations/transient_function_type.sol create mode 100644 test/libsolidity/syntaxTests/dataLocations/transient_function_type_parameter.sol create mode 100644 test/libsolidity/syntaxTests/dataLocations/transient_local_variable.sol create mode 100644 test/libsolidity/syntaxTests/dataLocations/transient_mapping_state_variable.sol create mode 100644 test/libsolidity/syntaxTests/dataLocations/transient_state_variable_visibility.sol create mode 100644 test/libsolidity/syntaxTests/dataLocations/transient_struct_state_variable.sol create mode 100644 test/libsolidity/syntaxTests/dataLocations/transient_value_type_state_variables.sol create mode 100644 test/libsolidity/syntaxTests/dataLocations/transient_value_type_state_variables_assignment.sol create mode 100644 test/libsolidity/syntaxTests/events/transient_indexed_parameter.sol create mode 100644 test/libsolidity/syntaxTests/functionTypes/function_type_with_transient_param.sol create mode 100644 test/libsolidity/syntaxTests/functionTypes/transient_function_type_with_param_named_transient.sol create mode 100644 test/libsolidity/syntaxTests/functionTypes/transient_function_type_with_transient_param.sol create mode 100644 test/libsolidity/syntaxTests/immutable/immutable_state_var_named_transient.sol create mode 100644 test/libsolidity/syntaxTests/immutable/state_var_transient_data_location.sol create mode 100644 test/libsolidity/syntaxTests/modifiers/transient_parameter.sol create mode 100644 test/libsolidity/syntaxTests/operators/transient_value_type.sol create mode 100644 test/libsolidity/syntaxTests/parsing/contract_named_transient.sol create mode 100644 test/libsolidity/syntaxTests/structs/transient_data_location_member.sol create mode 100644 test/libsolidity/syntaxTests/types/address/state_variable_address_payable_transient.sol create mode 100644 test/libsolidity/syntaxTests/types/address/state_variable_address_transient_payable.sol create mode 100644 test/libsolidity/syntaxTests/variableDeclaration/transient_as_identifier.sol create mode 100644 test/libsolidity/syntaxTests/variableDeclaration/transient_as_identifier_and_data_location.sol diff --git a/Changelog.md b/Changelog.md index de3fc3d6cf13..8ac9a7895f34 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,6 +1,7 @@ ### 0.8.27 (unreleased) Language Features: + * Accept declarations of state variables with ``transient`` data location (parser support only, no code generation yet). Compiler Features: diff --git a/docs/grammar/SolidityLexer.g4 b/docs/grammar/SolidityLexer.g4 index 43648ceb5d97..f994c331d536 100644 --- a/docs/grammar/SolidityLexer.g4 +++ b/docs/grammar/SolidityLexer.g4 @@ -85,6 +85,7 @@ SignedIntegerType: Storage: 'storage'; String: 'string'; Struct: 'struct'; +Transient: 'transient'; // not a real keyword True: 'true'; Try: 'try'; Type: 'type'; diff --git a/docs/grammar/SolidityParser.g4 b/docs/grammar/SolidityParser.g4 index e6d3ed7ccaea..a344fad54470 100644 --- a/docs/grammar/SolidityParser.g4 +++ b/docs/grammar/SolidityParser.g4 @@ -262,7 +262,7 @@ userDefinedValueTypeDefinition: * The declaration of a state variable. */ stateVariableDeclaration -locals [boolean constantnessSet = false, boolean visibilitySet = false, boolean overrideSpecifierSet = false] +locals [boolean constantnessSet = false, boolean visibilitySet = false, boolean overrideSpecifierSet = false, boolean locationSet = false] : type=typeName ( @@ -272,6 +272,7 @@ locals [boolean constantnessSet = false, boolean visibilitySet = false, boolean | {!$constantnessSet}? Constant {$constantnessSet = true;} | {!$overrideSpecifierSet}? overrideSpecifier {$overrideSpecifierSet = true;} | {!$constantnessSet}? Immutable {$constantnessSet = true;} + | {!$locationSet}? Transient {$locationSet = true;} )* name=identifier (Assign initialValue=expression)? @@ -419,7 +420,7 @@ inlineArrayExpression: LBrack (expression ( Comma expression)* ) RBrack; /** * Besides regular non-keyword Identifiers, some keywords like 'from' and 'error' can also be used as identifiers. */ -identifier: Identifier | From | Error | Revert | Global; +identifier: Identifier | From | Error | Revert | Global | Transient; literal: stringLiteral | numberLiteral | booleanLiteral | hexStringLiteral | unicodeStringLiteral; diff --git a/libsolidity/analysis/DeclarationTypeChecker.cpp b/libsolidity/analysis/DeclarationTypeChecker.cpp index 28c051c0a000..7e6ab98e1e24 100644 --- a/libsolidity/analysis/DeclarationTypeChecker.cpp +++ b/libsolidity/analysis/DeclarationTypeChecker.cpp @@ -407,6 +407,7 @@ void DeclarationTypeChecker::endVisit(VariableDeclaration const& _variable) { case Location::Memory: return "\"memory\""; case Location::Storage: return "\"storage\""; + case Location::Transient: return "\"transient\""; case Location::CallData: return "\"calldata\""; case Location::Unspecified: return "none"; } @@ -456,8 +457,24 @@ void DeclarationTypeChecker::endVisit(VariableDeclaration const& _variable) } else if (_variable.isStateVariable()) { - solAssert(varLoc == Location::Unspecified, ""); - typeLoc = (_variable.isConstant() || _variable.immutable()) ? DataLocation::Memory : DataLocation::Storage; + switch (varLoc) + { + case Location::Unspecified: + typeLoc = (_variable.isConstant() || _variable.immutable()) ? DataLocation::Memory : DataLocation::Storage; + break; + case Location::Transient: + if (_variable.isConstant() || _variable.immutable()) + m_errorReporter.declarationError( + 2197_error, + _variable.location(), + "Transient cannot be used as data location for constant or immutable variables." + ); + typeLoc = DataLocation::Transient; + break; + default: + solAssert(false); + break; + } } else if ( dynamic_cast(_variable.scope()) || @@ -477,6 +494,9 @@ void DeclarationTypeChecker::endVisit(VariableDeclaration const& _variable) case Location::CallData: typeLoc = DataLocation::CallData; break; + case Location::Transient: + solUnimplemented("Transient data location cannot be used in this kind of variable or parameter declaration."); + break; case Location::Unspecified: solAssert(!_variable.hasReferenceOrMappingType(), "Data location not properly set."); } @@ -497,6 +517,9 @@ void DeclarationTypeChecker::endVisit(VariableDeclaration const& _variable) m_errorReporter.fatalTypeError(9259_error, _variable.location(), "Only constants of value type and byte array type are implemented."); } + if (!type->isValueType()) + solUnimplementedAssert(typeLoc != DataLocation::Transient, "Transient data location is only supported for value types."); + _variable.annotation().type = type; } diff --git a/libsolidity/ast/AST.cpp b/libsolidity/ast/AST.cpp index bae16967595b..a3aab07fba29 100644 --- a/libsolidity/ast/AST.cpp +++ b/libsolidity/ast/AST.cpp @@ -816,7 +816,9 @@ std::set VariableDeclaration::allowedDataLocation { using Location = VariableDeclaration::Location; - if (!hasReferenceOrMappingType() || isStateVariable() || isEventOrErrorParameter()) + if (isStateVariable()) + return std::set{Location::Unspecified, Location::Transient}; + else if (!hasReferenceOrMappingType() || isEventOrErrorParameter()) return std::set{ Location::Unspecified }; else if (isCallableOrCatchParameter()) { diff --git a/libsolidity/ast/AST.h b/libsolidity/ast/AST.h index d8b178377bd8..3494ab94b9b4 100644 --- a/libsolidity/ast/AST.h +++ b/libsolidity/ast/AST.h @@ -1052,7 +1052,7 @@ class FunctionDefinition: public CallableDeclaration, public StructurallyDocumen class VariableDeclaration: public Declaration, public StructurallyDocumented { public: - enum Location { Unspecified, Storage, Memory, CallData }; + enum Location { Unspecified, Storage, Transient, Memory, CallData }; enum class Mutability { Mutable, Immutable, Constant }; static std::string mutabilityToString(Mutability _mutability) { diff --git a/libsolidity/ast/ASTJsonExporter.cpp b/libsolidity/ast/ASTJsonExporter.cpp index f94b91674bcb..69f51618e3d4 100644 --- a/libsolidity/ast/ASTJsonExporter.cpp +++ b/libsolidity/ast/ASTJsonExporter.cpp @@ -1058,6 +1058,8 @@ std::string ASTJsonExporter::location(VariableDeclaration::Location _location) return "memory"; case VariableDeclaration::Location::CallData: return "calldata"; + case VariableDeclaration::Location::Transient: + return "transient"; } // To make the compiler happy return {}; diff --git a/libsolidity/ast/ASTJsonImporter.cpp b/libsolidity/ast/ASTJsonImporter.cpp index 5c1d4bdc0c30..728d77c0de8b 100644 --- a/libsolidity/ast/ASTJsonImporter.cpp +++ b/libsolidity/ast/ASTJsonImporter.cpp @@ -1190,6 +1190,8 @@ VariableDeclaration::Location ASTJsonImporter::location(Json const& _node) return VariableDeclaration::Location::Memory; else if (storageLocStr == "calldata") return VariableDeclaration::Location::CallData; + else if (storageLocStr == "transient") + return VariableDeclaration::Location::Transient; else astAssert(false, "Unknown location declaration"); diff --git a/libsolidity/ast/Types.cpp b/libsolidity/ast/Types.cpp index 028b7667326f..a37cc78a4162 100644 --- a/libsolidity/ast/Types.cpp +++ b/libsolidity/ast/Types.cpp @@ -1544,6 +1544,8 @@ TypeResult ReferenceType::unaryOperatorResult(Token _operator) const return TypeProvider::emptyTuple(); case DataLocation::Storage: return isPointer() ? nullptr : TypeProvider::emptyTuple(); + case DataLocation::Transient: + solUnimplemented("Transient data location is only supported for value types."); } return nullptr; } @@ -1571,6 +1573,9 @@ std::string ReferenceType::stringForReferencePart() const return "calldata"; case DataLocation::Memory: return "memory"; + case DataLocation::Transient: + solUnimplemented("Transient data location is only supported for value types."); + break; } solAssert(false, ""); return ""; @@ -1584,6 +1589,9 @@ std::string ReferenceType::identifierLocationSuffix() const case DataLocation::Storage: id += "_storage"; break; + case DataLocation::Transient: + solUnimplemented("Transient data location is only supported for value types."); + break; case DataLocation::Memory: id += "_memory"; break; @@ -1748,6 +1756,9 @@ BoolResult ArrayType::validForLocation(DataLocation _loc) const if (storageSizeUpperBound() >= bigint(1) << 256) return BoolResult::err("Type too large for storage."); break; + case DataLocation::Transient: + solUnimplemented("Transient data location is only supported for value types."); + break; } return true; } @@ -1828,6 +1839,9 @@ std::vector> ArrayType::makeStackItems() co case DataLocation::Storage: // byte offset inside storage value is omitted return {std::make_tuple("slot", TypeProvider::uint256())}; + case DataLocation::Transient: + solUnimplemented("Transient data location is only supported for value types."); + break; } solAssert(false, ""); } @@ -2568,6 +2582,9 @@ std::vector> StructType::makeStackItems() c return {std::make_tuple("mpos", TypeProvider::uint256())}; case DataLocation::Storage: return {std::make_tuple("slot", TypeProvider::uint256())}; + case DataLocation::Transient: + solUnimplemented("Transient data location is only supported for value types."); + break; } solAssert(false, ""); } diff --git a/libsolidity/ast/Types.h b/libsolidity/ast/Types.h index 3ab4a1d97ebc..1817c97af4dd 100644 --- a/libsolidity/ast/Types.h +++ b/libsolidity/ast/Types.h @@ -70,7 +70,7 @@ inline rational makeRational(bigint const& _numerator, bigint const& _denominato return rational(_numerator, _denominator); } -enum class DataLocation { Storage, CallData, Memory }; +enum class DataLocation { Storage, Transient, CallData, Memory }; /** diff --git a/libsolidity/codegen/ArrayUtils.cpp b/libsolidity/codegen/ArrayUtils.cpp index e73ddfbae819..e653239cfa1a 100644 --- a/libsolidity/codegen/ArrayUtils.cpp +++ b/libsolidity/codegen/ArrayUtils.cpp @@ -1021,6 +1021,9 @@ void ArrayUtils::retrieveLength(ArrayType const& _arrayType, unsigned _stackDept if (_arrayType.isByteArrayOrString()) m_context.callYulFunction(m_context.utilFunctions().extractByteArrayLengthFunction(), 1, 1); break; + case DataLocation::Transient: + solUnimplemented("Transient data location is only supported for value types."); + break; } } } @@ -1118,6 +1121,9 @@ void ArrayUtils::accessIndex(ArrayType const& _arrayType, bool _doBoundsCheck, b m_context << endTag; break; } + case DataLocation::Transient: + solUnimplemented("Transient data location is only supported for value types."); + break; } } diff --git a/libsolidity/codegen/CompilerUtils.cpp b/libsolidity/codegen/CompilerUtils.cpp index bf4f25bf289e..822d9d3dab6a 100644 --- a/libsolidity/codegen/CompilerUtils.cpp +++ b/libsolidity/codegen/CompilerUtils.cpp @@ -1024,6 +1024,9 @@ void CompilerUtils::convertType( "Invalid conversion to storage type." ); break; + case DataLocation::Transient: + solUnimplemented("Transient data location is only supported for value types."); + break; case DataLocation::Memory: { // Copy the array to a free position in memory, unless it is already in memory. @@ -1168,6 +1171,9 @@ void CompilerUtils::convertType( "Invalid conversion to storage type." ); break; + case DataLocation::Transient: + solUnimplemented("Transient data location is only supported for value types."); + break; case DataLocation::Memory: // Copy the array to a free position in memory, unless it is already in memory. switch (typeOnStack.location()) @@ -1207,6 +1213,9 @@ void CompilerUtils::convertType( conversionImpl(m_context); break; } + case DataLocation::Transient: + solUnimplemented("Transient data location is only supported for value types."); + break; case DataLocation::CallData: { if (typeOnStack.isDynamicallyEncoded()) diff --git a/libsolidity/codegen/ContractCompiler.cpp b/libsolidity/codegen/ContractCompiler.cpp index 186cebc787c3..32fb9cae7bcf 100644 --- a/libsolidity/codegen/ContractCompiler.cpp +++ b/libsolidity/codegen/ContractCompiler.cpp @@ -592,6 +592,7 @@ void ContractCompiler::initializeStateVariables(ContractDefinition const& _contr bool ContractCompiler::visit(VariableDeclaration const& _variableDeclaration) { solAssert(_variableDeclaration.isStateVariable(), "Compiler visit to non-state variable declaration."); + solUnimplementedAssert(_variableDeclaration.referenceLocation() != VariableDeclaration::Location::Transient, "Transient storage variables not supported."); CompilerContext::LocationSetter locationSetter(m_context, _variableDeclaration); m_context.startFunction(_variableDeclaration); diff --git a/libsolidity/codegen/ExpressionCompiler.cpp b/libsolidity/codegen/ExpressionCompiler.cpp index c7bc9a8263f5..6027e0404850 100644 --- a/libsolidity/codegen/ExpressionCompiler.cpp +++ b/libsolidity/codegen/ExpressionCompiler.cpp @@ -2047,6 +2047,9 @@ bool ExpressionCompiler::visit(MemberAccess const& _memberAccess) ArrayUtils(m_context).retrieveLength(type); m_context << Instruction::SWAP1 << Instruction::POP; break; + case DataLocation::Transient: + solUnimplemented("Transient data location is only supported for value types."); + break; case DataLocation::Memory: m_context << Instruction::MLOAD; break; @@ -2193,6 +2196,9 @@ bool ExpressionCompiler::visit(IndexAccess const& _indexAccess) else setLValueToStorageItem(_indexAccess); break; + case DataLocation::Transient: + solUnimplemented("Transient data location is only supported for value types."); + break; case DataLocation::Memory: ArrayUtils(m_context).accessIndex(arrayType); setLValue(_indexAccess, *_indexAccess.annotation().type, !arrayType.isByteArrayOrString()); diff --git a/libsolidity/codegen/YulUtilFunctions.cpp b/libsolidity/codegen/YulUtilFunctions.cpp index 9d1929fe1ef6..ebf1d384aa57 100644 --- a/libsolidity/codegen/YulUtilFunctions.cpp +++ b/libsolidity/codegen/YulUtilFunctions.cpp @@ -2563,6 +2563,9 @@ std::string YulUtilFunctions::nextArrayElementFunction(ArrayType const& _type) templ("advance", toCompactHexWithPrefix(size)); break; } + case DataLocation::Transient: + solUnimplemented("Transient data location is only supported for value types."); + break; case DataLocation::CallData: { u256 size = _type.calldataStride(); diff --git a/libsolidity/codegen/ir/IRGeneratorForStatements.cpp b/libsolidity/codegen/ir/IRGeneratorForStatements.cpp index 2464fefc434b..2f823fcbf65c 100644 --- a/libsolidity/codegen/ir/IRGeneratorForStatements.cpp +++ b/libsolidity/codegen/ir/IRGeneratorForStatements.cpp @@ -47,6 +47,7 @@ #include #include +#include #include using namespace solidity; @@ -374,6 +375,15 @@ void IRGeneratorForStatements::endVisit(VariableDeclarationStatement const& _var { setLocation(_varDeclStatement); + auto static notTransient = [](std::shared_ptr const& _varDeclaration) { + return (_varDeclaration ? _varDeclaration->referenceLocation() != VariableDeclaration::Location::Transient : true); + }; + + solUnimplementedAssert( + ranges::all_of(_varDeclStatement.declarations(), notTransient), + "Transient storage variables are not supported." + ); + if (Expression const* expression = _varDeclStatement.initialValue()) { if (_varDeclStatement.declarations().size() > 1) @@ -2314,6 +2324,9 @@ void IRGeneratorForStatements::endVisit(IndexAccess const& _indexAccess) break; } + case DataLocation::Transient: + solUnimplemented("Transient data location is only supported for value types."); + break; case DataLocation::Memory: { std::string const indexAccessFunction = m_utils.memoryArrayIndexAccessFunction(arrayType); diff --git a/libsolidity/formal/BMC.cpp b/libsolidity/formal/BMC.cpp index b1a326fc77c4..2fc24f1f66d5 100644 --- a/libsolidity/formal/BMC.cpp +++ b/libsolidity/formal/BMC.cpp @@ -184,6 +184,9 @@ bool BMC::shouldInlineFunctionCall( bool BMC::visit(ContractDefinition const& _contract) { + // Raises UnimplementedFeatureError in the presence of transient storage variables + TransientDataLocationChecker checker(_contract); + initContract(_contract); SMTEncoder::visit(_contract); diff --git a/libsolidity/formal/CHC.cpp b/libsolidity/formal/CHC.cpp index 66ebd47edb98..5e372771240a 100644 --- a/libsolidity/formal/CHC.cpp +++ b/libsolidity/formal/CHC.cpp @@ -143,6 +143,9 @@ bool CHC::visit(ContractDefinition const& _contract) if (!shouldAnalyze(_contract)) return false; + // Raises UnimplementedFeatureError in the presence of transient storage variables + TransientDataLocationChecker checker(_contract); + resetContractAnalysis(); initContract(_contract); clearIndices(&_contract); diff --git a/libsolidity/formal/SMTEncoder.h b/libsolidity/formal/SMTEncoder.h index bea3a85ef9c8..77e618fedf0a 100644 --- a/libsolidity/formal/SMTEncoder.h +++ b/libsolidity/formal/SMTEncoder.h @@ -129,6 +129,19 @@ class SMTEncoder: public ASTConstVisitor static std::set sourceDependencies(SourceUnit const& _source); protected: + struct TransientDataLocationChecker: ASTConstVisitor + { + TransientDataLocationChecker(ContractDefinition const& _contract) { _contract.accept(*this); } + + void endVisit(VariableDeclaration const& _var) + { + solUnimplementedAssert( + _var.referenceLocation() != VariableDeclaration::Location::Transient, + "Transient storage variables are not supported." + ); + } + }; + void resetSourceAnalysis(); // TODO: Check that we do not have concurrent reads and writes to a variable, diff --git a/libsolidity/interface/StorageLayout.cpp b/libsolidity/interface/StorageLayout.cpp index 7f344f6edf65..0153af1a293a 100644 --- a/libsolidity/interface/StorageLayout.cpp +++ b/libsolidity/interface/StorageLayout.cpp @@ -46,6 +46,7 @@ Json StorageLayout::generate(ContractDefinition const& _contractDef) Json StorageLayout::generate(VariableDeclaration const& _var, u256 const& _slot, unsigned _offset) { + solUnimplementedAssert(_var.referenceLocation() != VariableDeclaration::Location::Transient, "Transient storage layout is not supported yet."); Json varEntry; Type const* varType = _var.type(); diff --git a/libsolidity/parsing/Parser.cpp b/libsolidity/parsing/Parser.cpp index 7e2fe030af2c..b51eb9c44099 100644 --- a/libsolidity/parsing/Parser.cpp +++ b/libsolidity/parsing/Parser.cpp @@ -885,6 +885,19 @@ ASTPointer Parser::parseVariableDeclaration( } } } + else if ( + _options.kind == VarDeclKind::State && + token == Token::Identifier && + m_scanner->currentLiteral() == "transient" && + m_scanner->peekNextToken() != Token::Assign && + m_scanner->peekNextToken() != Token::Semicolon + ) + { + if (location != VariableDeclaration::Location::Unspecified) + parserError(ErrorId{3548}, "Location already specified."); + else + location = VariableDeclaration::Location::Transient; + } else break; nodeFactory.markEndPosition(); diff --git a/scripts/error_codes.py b/scripts/error_codes.py index 24ec2b06d617..54dd00c267ce 100755 --- a/scripts/error_codes.py +++ b/scripts/error_codes.py @@ -202,6 +202,7 @@ def examine_id_coverage(top_dir, source_id_to_file_names, new_ids_only=False): "4591", # "There are more than 256 warnings. Ignoring the rest." # Due to 3805, the warning lists look different for different compiler builds. "1920", # Unimplemented feature error from YulStack (currently there are no UnimplementedFeatureErrors thrown by libyul) + "7053", # Unimplemented feature error (parsing stage), currently has no tests "1180", # SMTChecker, covered by CL tests "2339", # SMTChecker, covered by CL tests "2961", # SMTChecker, covered by CL tests diff --git a/test/cmdlineTests/storage_layout_transient_value_types/in.sol b/test/cmdlineTests/storage_layout_transient_value_types/in.sol new file mode 100644 index 000000000000..ba7943c6a11b --- /dev/null +++ b/test/cmdlineTests/storage_layout_transient_value_types/in.sol @@ -0,0 +1,10 @@ +//SPDX-License-Identifier: GPL-3.0 +pragma solidity >=0.0; +contract A { + uint transient x; + uint y; + bytes32 transient b; + bytes32 c; + address transient a; + address z; +} \ No newline at end of file diff --git a/test/cmdlineTests/storage_layout_transient_value_types/input.json b/test/cmdlineTests/storage_layout_transient_value_types/input.json new file mode 100644 index 000000000000..96d71ed30ec8 --- /dev/null +++ b/test/cmdlineTests/storage_layout_transient_value_types/input.json @@ -0,0 +1,13 @@ +{ + "language": "Solidity", + "sources": { + "fileA": {"urls": ["storage_layout_transient_value_types/in.sol"]} + }, + "settings": { + "outputSelection": { + "fileA": { + "A": ["storageLayout"] + } + } + } +} diff --git a/test/cmdlineTests/storage_layout_transient_value_types/output.json b/test/cmdlineTests/storage_layout_transient_value_types/output.json new file mode 100644 index 000000000000..a446210485f9 --- /dev/null +++ b/test/cmdlineTests/storage_layout_transient_value_types/output.json @@ -0,0 +1,11 @@ +{ + "errors": [ + { + "component": "general", + "formattedMessage": "Transient storage layout is not supported yet.", + "message": "Transient storage layout is not supported yet.", + "severity": "error", + "type": "UnimplementedFeatureError" + } + ] +} diff --git a/test/libsolidity/astPropertyTests/transient_data_location.sol b/test/libsolidity/astPropertyTests/transient_data_location.sol new file mode 100644 index 000000000000..6a937414d6bd --- /dev/null +++ b/test/libsolidity/astPropertyTests/transient_data_location.sol @@ -0,0 +1,8 @@ +contract C { + /// TestVarDataLocation: storageLocation + /// TestVarName: name + uint transient transient; +} +// ---- +// TestVarDataLocation: transient +// TestVarName: transient diff --git a/test/libsolidity/smtCheckerTests/unsupported/transient_storage_state_variable.sol b/test/libsolidity/smtCheckerTests/unsupported/transient_storage_state_variable.sol new file mode 100644 index 000000000000..b2dbc8efe5c7 --- /dev/null +++ b/test/libsolidity/smtCheckerTests/unsupported/transient_storage_state_variable.sol @@ -0,0 +1,8 @@ +contract C { + uint transient x = 42; + function test() public view { assert(x == 42); } +} +// ==== +// SMTEngine: all +// ---- +// UnimplementedFeatureError 1834: Transient storage variables are not supported. diff --git a/test/libsolidity/syntaxTests/constants/constant_state_variable_named_transient.sol b/test/libsolidity/syntaxTests/constants/constant_state_variable_named_transient.sol new file mode 100644 index 000000000000..4d9873d36d07 --- /dev/null +++ b/test/libsolidity/syntaxTests/constants/constant_state_variable_named_transient.sol @@ -0,0 +1,4 @@ +contract C { + int constant public transient = 0; +} +// ---- diff --git a/test/libsolidity/syntaxTests/constants/constant_transient_state_variable.sol b/test/libsolidity/syntaxTests/constants/constant_transient_state_variable.sol new file mode 100644 index 000000000000..f9a722a1b4a8 --- /dev/null +++ b/test/libsolidity/syntaxTests/constants/constant_transient_state_variable.sol @@ -0,0 +1,5 @@ +contract C { + int constant public transient x = 0; +} +// ---- +// DeclarationError 2197: (17-52): Transient cannot be used as data location for constant or immutable variables. diff --git a/test/libsolidity/syntaxTests/dataLocations/data_location_in_function_type_fail.sol b/test/libsolidity/syntaxTests/dataLocations/data_location_in_function_type_fail.sol index 4e5091e8c1cf..cd46b15b0716 100644 --- a/test/libsolidity/syntaxTests/dataLocations/data_location_in_function_type_fail.sol +++ b/test/libsolidity/syntaxTests/dataLocations/data_location_in_function_type_fail.sol @@ -2,7 +2,10 @@ library L { struct Nested { uint y; } function b(function(Nested calldata) external returns (uint)[] storage) external pure {} function d(function(Nested storage) external returns (uint)[] storage) external pure {} + function f(function(Nested transient) external returns (uint)[] storage) external pure {} } // ---- +// Warning 6162: (251-267): Naming function type parameters is deprecated. // TypeError 6651: (159-173): Data location must be "memory" or "calldata" for parameter in function, but "storage" was given. +// TypeError 6651: (251-267): Data location must be "memory" or "calldata" for parameter in function, but none was given. diff --git a/test/libsolidity/syntaxTests/dataLocations/externalFunction/function_argument_location_specifier_test_external_transient.sol b/test/libsolidity/syntaxTests/dataLocations/externalFunction/function_argument_location_specifier_test_external_transient.sol new file mode 100644 index 000000000000..98fbb2d5ee66 --- /dev/null +++ b/test/libsolidity/syntaxTests/dataLocations/externalFunction/function_argument_location_specifier_test_external_transient.sol @@ -0,0 +1,5 @@ +contract test { + function f(bytes transient) external; +} +// ---- +// TypeError 6651: (31-46): Data location must be "memory" or "calldata" for parameter in external function, but none was given. diff --git a/test/libsolidity/syntaxTests/dataLocations/internalFunction/function_argument_location_specifier_test_internal_transient.sol b/test/libsolidity/syntaxTests/dataLocations/internalFunction/function_argument_location_specifier_test_internal_transient.sol new file mode 100644 index 000000000000..4a5b6f999d86 --- /dev/null +++ b/test/libsolidity/syntaxTests/dataLocations/internalFunction/function_argument_location_specifier_test_internal_transient.sol @@ -0,0 +1,5 @@ +contract test { + function f(bytes transient) internal {} +} +// ---- +// TypeError 6651: (31-46): Data location must be "storage", "memory" or "calldata" for parameter in function, but none was given. diff --git a/test/libsolidity/syntaxTests/dataLocations/libraries/library_function_with_data_location_transient.sol b/test/libsolidity/syntaxTests/dataLocations/libraries/library_function_with_data_location_transient.sol new file mode 100644 index 000000000000..75253342c4e0 --- /dev/null +++ b/test/libsolidity/syntaxTests/dataLocations/libraries/library_function_with_data_location_transient.sol @@ -0,0 +1,19 @@ +library L { + function f1(uint[] transient) private pure { } + function f2() private pure returns (uint[] transient) { } + function g1(uint[] transient) internal pure { } + function g2() internal pure returns (uint[] transient) { } + function h1(uint[] transient) public pure { } + function h2() public pure returns (uint[] transient) { } + function i1(uint[] transient) external pure { } + function i2() external pure returns (uint[] transient) { } +} +// ---- +// TypeError 6651: (28-44): Data location must be "storage", "memory" or "calldata" for parameter in function, but none was given. +// TypeError 6651: (103-119): Data location must be "storage", "memory" or "calldata" for return parameter in function, but none was given. +// TypeError 6651: (141-157): Data location must be "storage", "memory" or "calldata" for parameter in function, but none was given. +// TypeError 6651: (218-234): Data location must be "storage", "memory" or "calldata" for return parameter in function, but none was given. +// TypeError 6651: (256-272): Data location must be "storage", "memory" or "calldata" for parameter in function, but none was given. +// TypeError 6651: (329-345): Data location must be "storage", "memory" or "calldata" for return parameter in function, but none was given. +// TypeError 6651: (367-383): Data location must be "storage", "memory" or "calldata" for parameter in external function, but none was given. +// TypeError 6651: (444-460): Data location must be "storage", "memory" or "calldata" for return parameter in function, but none was given. diff --git a/test/libsolidity/syntaxTests/dataLocations/libraryExternalFunction/function_argument_location_specifier_test_external_transient.sol b/test/libsolidity/syntaxTests/dataLocations/libraryExternalFunction/function_argument_location_specifier_test_external_transient.sol new file mode 100644 index 000000000000..1dcedf49adcf --- /dev/null +++ b/test/libsolidity/syntaxTests/dataLocations/libraryExternalFunction/function_argument_location_specifier_test_external_transient.sol @@ -0,0 +1,5 @@ +library test { + function f(bytes transient) external {} +} +// ---- +// TypeError 6651: (30-45): Data location must be "storage", "memory" or "calldata" for parameter in external function, but none was given. diff --git a/test/libsolidity/syntaxTests/dataLocations/libraryInternalFunction/function_argument_location_specifier_test_internal_transient.sol b/test/libsolidity/syntaxTests/dataLocations/libraryInternalFunction/function_argument_location_specifier_test_internal_transient.sol new file mode 100644 index 000000000000..d66fa7fadd2d --- /dev/null +++ b/test/libsolidity/syntaxTests/dataLocations/libraryInternalFunction/function_argument_location_specifier_test_internal_transient.sol @@ -0,0 +1,5 @@ +library test { + function f(bytes transient) internal pure {} +} +// ---- +// TypeError 6651: (30-45): Data location must be "storage", "memory" or "calldata" for parameter in function, but none was given. diff --git a/test/libsolidity/syntaxTests/dataLocations/multiple_transient_data_location_function_parameter.sol b/test/libsolidity/syntaxTests/dataLocations/multiple_transient_data_location_function_parameter.sol new file mode 100644 index 000000000000..193565b2a00d --- /dev/null +++ b/test/libsolidity/syntaxTests/dataLocations/multiple_transient_data_location_function_parameter.sol @@ -0,0 +1,6 @@ +contract C { + function f(uint[] transient transient x) public pure { } +} + +// ---- +// ParserError 2314: (45-54): Expected ',' but got identifier diff --git a/test/libsolidity/syntaxTests/dataLocations/privateFunction/private_function_parameters_location_transient.sol b/test/libsolidity/syntaxTests/dataLocations/privateFunction/private_function_parameters_location_transient.sol new file mode 100644 index 000000000000..750aa4fee522 --- /dev/null +++ b/test/libsolidity/syntaxTests/dataLocations/privateFunction/private_function_parameters_location_transient.sol @@ -0,0 +1,5 @@ +contract C { + function f(uint[] transient) private pure {} +} +// ---- +// TypeError 6651: (28-44): Data location must be "storage", "memory" or "calldata" for parameter in function, but none was given. diff --git a/test/libsolidity/syntaxTests/dataLocations/privateFunction/private_function_return_parameters_location_transient.sol b/test/libsolidity/syntaxTests/dataLocations/privateFunction/private_function_return_parameters_location_transient.sol new file mode 100644 index 000000000000..d1bf8762480f --- /dev/null +++ b/test/libsolidity/syntaxTests/dataLocations/privateFunction/private_function_return_parameters_location_transient.sol @@ -0,0 +1,5 @@ +contract C { + function f() private pure returns (uint[] transient) {} +} +// ---- +// TypeError 6651: (52-68): Data location must be "storage", "memory" or "calldata" for return parameter in function, but none was given. diff --git a/test/libsolidity/syntaxTests/dataLocations/publicFunction/function_argument_location_specifier_test_public_transient.sol b/test/libsolidity/syntaxTests/dataLocations/publicFunction/function_argument_location_specifier_test_public_transient.sol new file mode 100644 index 000000000000..ce4f42f469e4 --- /dev/null +++ b/test/libsolidity/syntaxTests/dataLocations/publicFunction/function_argument_location_specifier_test_public_transient.sol @@ -0,0 +1,5 @@ +contract test { + function f(bytes transient) public; +} +// ---- +// TypeError 6651: (31-46): Data location must be "memory" or "calldata" for parameter in function, but none was given. diff --git a/test/libsolidity/syntaxTests/dataLocations/publicFunction/public_function_return_parameters_location_transient.sol b/test/libsolidity/syntaxTests/dataLocations/publicFunction/public_function_return_parameters_location_transient.sol new file mode 100644 index 000000000000..862b7d236bfa --- /dev/null +++ b/test/libsolidity/syntaxTests/dataLocations/publicFunction/public_function_return_parameters_location_transient.sol @@ -0,0 +1,5 @@ +contract C { + function h() public pure returns(uint[] transient) {} +} +// ---- +// TypeError 6651: (50-66): Data location must be "memory" or "calldata" for return parameter in function, but none was given. diff --git a/test/libsolidity/syntaxTests/dataLocations/state_variable_storage_named_transient.sol b/test/libsolidity/syntaxTests/dataLocations/state_variable_storage_named_transient.sol new file mode 100644 index 000000000000..afa6fd250308 --- /dev/null +++ b/test/libsolidity/syntaxTests/dataLocations/state_variable_storage_named_transient.sol @@ -0,0 +1,5 @@ +contract C { + uint storage transient; +} +// ---- +// ParserError 2314: (22-29): Expected identifier but got 'storage' diff --git a/test/libsolidity/syntaxTests/dataLocations/state_variable_storage_transient.sol b/test/libsolidity/syntaxTests/dataLocations/state_variable_storage_transient.sol new file mode 100644 index 000000000000..d3fb023e0dbd --- /dev/null +++ b/test/libsolidity/syntaxTests/dataLocations/state_variable_storage_transient.sol @@ -0,0 +1,5 @@ +contract C { + uint storage transient x; +} +// ---- +// ParserError 2314: (22-29): Expected identifier but got 'storage' diff --git a/test/libsolidity/syntaxTests/dataLocations/state_variable_transient_storage.sol b/test/libsolidity/syntaxTests/dataLocations/state_variable_transient_storage.sol new file mode 100644 index 000000000000..53260194d1d2 --- /dev/null +++ b/test/libsolidity/syntaxTests/dataLocations/state_variable_transient_storage.sol @@ -0,0 +1,5 @@ +contract C { + uint transient storage x; +} +// ---- +// ParserError 2314: (32-39): Expected identifier but got 'storage' diff --git a/test/libsolidity/syntaxTests/dataLocations/transient_dynamic_array_state_variable.sol b/test/libsolidity/syntaxTests/dataLocations/transient_dynamic_array_state_variable.sol new file mode 100644 index 000000000000..b82f40267edd --- /dev/null +++ b/test/libsolidity/syntaxTests/dataLocations/transient_dynamic_array_state_variable.sol @@ -0,0 +1,7 @@ +contract C { + uint[] transient x; +} +// ==== +// stopAfter: analysis +// ---- +// UnimplementedFeatureError 1834: Transient data location is only supported for value types. diff --git a/test/libsolidity/syntaxTests/dataLocations/transient_fixed_array_state_variable.sol b/test/libsolidity/syntaxTests/dataLocations/transient_fixed_array_state_variable.sol new file mode 100644 index 000000000000..3f7cec2a7588 --- /dev/null +++ b/test/libsolidity/syntaxTests/dataLocations/transient_fixed_array_state_variable.sol @@ -0,0 +1,7 @@ +contract C { + uint[3] transient x; +} +// ==== +// stopAfter: analysis +// ---- +// UnimplementedFeatureError 1834: Transient data location is only supported for value types. diff --git a/test/libsolidity/syntaxTests/dataLocations/transient_function_type.sol b/test/libsolidity/syntaxTests/dataLocations/transient_function_type.sol new file mode 100644 index 000000000000..9deba463c195 --- /dev/null +++ b/test/libsolidity/syntaxTests/dataLocations/transient_function_type.sol @@ -0,0 +1,11 @@ +contract C { + function () transient f; + function (uint) external transient y; + function () transient internal fti; + function () internal transient fit; + function () internal transient internal fiti; + function () internal internal transient fiit; +} +// ==== +// stopAfter: analysis +// ---- diff --git a/test/libsolidity/syntaxTests/dataLocations/transient_function_type_parameter.sol b/test/libsolidity/syntaxTests/dataLocations/transient_function_type_parameter.sol new file mode 100644 index 000000000000..04f20e85c050 --- /dev/null +++ b/test/libsolidity/syntaxTests/dataLocations/transient_function_type_parameter.sol @@ -0,0 +1,5 @@ +contract C { + function (uint transient) external y; +} +// ---- +// Warning 6162: (27-41): Naming function type parameters is deprecated. diff --git a/test/libsolidity/syntaxTests/dataLocations/transient_local_variable.sol b/test/libsolidity/syntaxTests/dataLocations/transient_local_variable.sol new file mode 100644 index 000000000000..7602a4cb9208 --- /dev/null +++ b/test/libsolidity/syntaxTests/dataLocations/transient_local_variable.sol @@ -0,0 +1,7 @@ +contract C { + function f() public pure { + uint transient x = 0; + } +} +// ---- +// ParserError 2314: (67-68): Expected ';' but got identifier diff --git a/test/libsolidity/syntaxTests/dataLocations/transient_mapping_state_variable.sol b/test/libsolidity/syntaxTests/dataLocations/transient_mapping_state_variable.sol new file mode 100644 index 000000000000..cd762df30e62 --- /dev/null +++ b/test/libsolidity/syntaxTests/dataLocations/transient_mapping_state_variable.sol @@ -0,0 +1,7 @@ +contract C { + mapping(uint => uint) transient y; +} +// ==== +// stopAfter: analysis +// ---- +// UnimplementedFeatureError 1834: Transient data location is only supported for value types. diff --git a/test/libsolidity/syntaxTests/dataLocations/transient_state_variable_visibility.sol b/test/libsolidity/syntaxTests/dataLocations/transient_state_variable_visibility.sol new file mode 100644 index 000000000000..2579d5532fee --- /dev/null +++ b/test/libsolidity/syntaxTests/dataLocations/transient_state_variable_visibility.sol @@ -0,0 +1,12 @@ +contract C { + uint public transient pubt; + uint internal transient it; + uint private transient prvt; + + uint transient public tpub; + uint transient internal ti; + uint transient private tprv; +} +// ==== +// stopAfter: parsing +// ---- diff --git a/test/libsolidity/syntaxTests/dataLocations/transient_struct_state_variable.sol b/test/libsolidity/syntaxTests/dataLocations/transient_struct_state_variable.sol new file mode 100644 index 000000000000..19612b9c5728 --- /dev/null +++ b/test/libsolidity/syntaxTests/dataLocations/transient_struct_state_variable.sol @@ -0,0 +1,12 @@ +struct S { + uint x; + address a; +} + +contract C { + S transient s; +} +// ==== +// stopAfter: analysis +// ---- +// UnimplementedFeatureError 1834: Transient data location is only supported for value types. diff --git a/test/libsolidity/syntaxTests/dataLocations/transient_value_type_state_variables.sol b/test/libsolidity/syntaxTests/dataLocations/transient_value_type_state_variables.sol new file mode 100644 index 000000000000..55faa1495d99 --- /dev/null +++ b/test/libsolidity/syntaxTests/dataLocations/transient_value_type_state_variables.sol @@ -0,0 +1,12 @@ +contract D { } + +contract C { + address transient a; + bool transient b; + D transient d; + uint transient x; + bytes32 transient y; +} +// ==== +// stopAfter: parsing +// ---- diff --git a/test/libsolidity/syntaxTests/dataLocations/transient_value_type_state_variables_assignment.sol b/test/libsolidity/syntaxTests/dataLocations/transient_value_type_state_variables_assignment.sol new file mode 100644 index 000000000000..10dad9e32fe9 --- /dev/null +++ b/test/libsolidity/syntaxTests/dataLocations/transient_value_type_state_variables_assignment.sol @@ -0,0 +1,10 @@ +contract D { } + +contract C { + int transient x = -99; + address transient a = address(0xABC); + bool transient b = x > 0 ? false : true; +} +// ==== +// stopAfter: parsing +// ---- diff --git a/test/libsolidity/syntaxTests/errors/invalid_parameter_location.sol b/test/libsolidity/syntaxTests/errors/invalid_parameter_location.sol index a116188d2375..38f1bd9af5b8 100644 --- a/test/libsolidity/syntaxTests/errors/invalid_parameter_location.sol +++ b/test/libsolidity/syntaxTests/errors/invalid_parameter_location.sol @@ -10,7 +10,12 @@ contract test { contract test { error e1(string calldata a); } +==== Source: D ==== +contract test { + error e1(string transient a); +} // ---- // ParserError 2314: (A:36-43): Expected ',' but got 'storage' // ParserError 2314: (B:36-42): Expected ',' but got 'memory' // ParserError 2314: (C:36-44): Expected ',' but got 'calldata' +// ParserError 2314: (D:46-47): Expected ',' but got identifier diff --git a/test/libsolidity/syntaxTests/events/invalid_parameter_location.sol b/test/libsolidity/syntaxTests/events/invalid_parameter_location.sol index 04ee9b7bc4b6..1f13bbf9085e 100644 --- a/test/libsolidity/syntaxTests/events/invalid_parameter_location.sol +++ b/test/libsolidity/syntaxTests/events/invalid_parameter_location.sol @@ -10,7 +10,12 @@ contract test { contract test { event e1(string calldata a); } +==== Source: D ==== +contract test { + event e1(string transient a); +} // ---- // ParserError 2314: (A:36-43): Expected ',' but got 'storage' // ParserError 2314: (B:36-42): Expected ',' but got 'memory' // ParserError 2314: (C:36-44): Expected ',' but got 'calldata' +// ParserError 2314: (D:46-47): Expected ',' but got identifier diff --git a/test/libsolidity/syntaxTests/events/transient_indexed_parameter.sol b/test/libsolidity/syntaxTests/events/transient_indexed_parameter.sol new file mode 100644 index 000000000000..718451de2fb6 --- /dev/null +++ b/test/libsolidity/syntaxTests/events/transient_indexed_parameter.sol @@ -0,0 +1,5 @@ +contract C { + event e(string indexed transient a); +} +// ---- +// ParserError 2314: (50-51): Expected ',' but got identifier diff --git a/test/libsolidity/syntaxTests/functionTypes/function_type_with_transient_param.sol b/test/libsolidity/syntaxTests/functionTypes/function_type_with_transient_param.sol new file mode 100644 index 000000000000..b38e37177ea1 --- /dev/null +++ b/test/libsolidity/syntaxTests/functionTypes/function_type_with_transient_param.sol @@ -0,0 +1,8 @@ +contract C { + function (uint transient) external y; + function (uint[] transient) external z; +} +// ---- +// Warning 6162: (27-41): Naming function type parameters is deprecated. +// Warning 6162: (69-85): Naming function type parameters is deprecated. +// TypeError 6651: (69-85): Data location must be "memory" or "calldata" for parameter in function, but none was given. diff --git a/test/libsolidity/syntaxTests/functionTypes/transient_function_type_with_param_named_transient.sol b/test/libsolidity/syntaxTests/functionTypes/transient_function_type_with_param_named_transient.sol new file mode 100644 index 000000000000..fd28841431d0 --- /dev/null +++ b/test/libsolidity/syntaxTests/functionTypes/transient_function_type_with_param_named_transient.sol @@ -0,0 +1,6 @@ +contract C { + function (uint transient) external transient y; +} +// ==== +// stopAfter: parsing +// ---- diff --git a/test/libsolidity/syntaxTests/functionTypes/transient_function_type_with_transient_param.sol b/test/libsolidity/syntaxTests/functionTypes/transient_function_type_with_transient_param.sol new file mode 100644 index 000000000000..74e5b3413d54 --- /dev/null +++ b/test/libsolidity/syntaxTests/functionTypes/transient_function_type_with_transient_param.sol @@ -0,0 +1,5 @@ +contract C { + function (uint transient x) external transient y; +} +// ---- +// ParserError 2314: (42-43): Expected ',' but got identifier diff --git a/test/libsolidity/syntaxTests/immutable/immutable_state_var_named_transient.sol b/test/libsolidity/syntaxTests/immutable/immutable_state_var_named_transient.sol new file mode 100644 index 000000000000..c0ac3a8abb3c --- /dev/null +++ b/test/libsolidity/syntaxTests/immutable/immutable_state_var_named_transient.sol @@ -0,0 +1,4 @@ +contract C { + address public immutable transient; +} +// ---- diff --git a/test/libsolidity/syntaxTests/immutable/state_var_transient_data_location.sol b/test/libsolidity/syntaxTests/immutable/state_var_transient_data_location.sol new file mode 100644 index 000000000000..a3d93848d9a2 --- /dev/null +++ b/test/libsolidity/syntaxTests/immutable/state_var_transient_data_location.sol @@ -0,0 +1,5 @@ +contract C { + uint public immutable transient x; +} +// ---- +// DeclarationError 2197: (17-50): Transient cannot be used as data location for constant or immutable variables. diff --git a/test/libsolidity/syntaxTests/modifiers/multiple_parameter_location.sol b/test/libsolidity/syntaxTests/modifiers/multiple_parameter_location.sol index e264a593ff2c..24bb1cc32e7d 100644 --- a/test/libsolidity/syntaxTests/modifiers/multiple_parameter_location.sol +++ b/test/libsolidity/syntaxTests/modifiers/multiple_parameter_location.sol @@ -8,6 +8,12 @@ contract A { modifier mod7(string calldata storage a) { _; } modifier mod8(string calldata memory a) { _; } modifier mod9(string calldata calldata a) { _; } + modifier modA(string transient storage a) { _; } + modifier modB(string transient memory a) { _; } + modifier modC(string transient calldata a) { _; } + modifier modD(string storage transient a) { _; } + modifier modE(string memory transient a) { _; } + modifier modF(string calldata transient a) { _; } } // ---- // ParserError 3548: (46-53): Location already specified. @@ -19,3 +25,4 @@ contract A { // ParserError 3548: (350-357): Location already specified. // ParserError 3548: (402-408): Location already specified. // ParserError 3548: (453-461): Location already specified. +// ParserError 2314: (507-514): Expected ',' but got 'storage' diff --git a/test/libsolidity/syntaxTests/modifiers/transient_parameter.sol b/test/libsolidity/syntaxTests/modifiers/transient_parameter.sol new file mode 100644 index 000000000000..be90ca54dc39 --- /dev/null +++ b/test/libsolidity/syntaxTests/modifiers/transient_parameter.sol @@ -0,0 +1,5 @@ +contract A { + modifier mod2(uint[] transient) { _; } +} +// ---- +// TypeError 6651: (31-47): Data location must be "storage", "memory" or "calldata" for parameter in function, but none was given. diff --git a/test/libsolidity/syntaxTests/operators/transient_value_type.sol b/test/libsolidity/syntaxTests/operators/transient_value_type.sol new file mode 100644 index 000000000000..3d83fe240798 --- /dev/null +++ b/test/libsolidity/syntaxTests/operators/transient_value_type.sol @@ -0,0 +1,11 @@ +contract C { + int transient x; + function f() public view returns (int) { + int y = x; + int w = -x; + return (x + w) * (y / x); + } +} +// ==== +// stopAfter: parsing +// ---- diff --git a/test/libsolidity/syntaxTests/parsing/contract_named_transient.sol b/test/libsolidity/syntaxTests/parsing/contract_named_transient.sol new file mode 100644 index 000000000000..853396f21bb5 --- /dev/null +++ b/test/libsolidity/syntaxTests/parsing/contract_named_transient.sol @@ -0,0 +1 @@ +contract transient {} diff --git a/test/libsolidity/syntaxTests/structs/transient_data_location_member.sol b/test/libsolidity/syntaxTests/structs/transient_data_location_member.sol new file mode 100644 index 000000000000..110d4969a6cc --- /dev/null +++ b/test/libsolidity/syntaxTests/structs/transient_data_location_member.sol @@ -0,0 +1,5 @@ +struct S { + int transient x; +} +// ---- +// ParserError 2314: (29-30): Expected ';' but got identifier diff --git a/test/libsolidity/syntaxTests/types/address/state_variable_address_payable_transient.sol b/test/libsolidity/syntaxTests/types/address/state_variable_address_payable_transient.sol new file mode 100644 index 000000000000..0cab967225c5 --- /dev/null +++ b/test/libsolidity/syntaxTests/types/address/state_variable_address_payable_transient.sol @@ -0,0 +1,6 @@ +contract C { + address payable transient a; +} +// ==== +// stopAfter: parsing +// ---- diff --git a/test/libsolidity/syntaxTests/types/address/state_variable_address_transient_payable.sol b/test/libsolidity/syntaxTests/types/address/state_variable_address_transient_payable.sol new file mode 100644 index 000000000000..16d8adb493f8 --- /dev/null +++ b/test/libsolidity/syntaxTests/types/address/state_variable_address_transient_payable.sol @@ -0,0 +1,5 @@ +contract C { + address transient payable a; +} +// ---- +// ParserError 2314: (35-42): Expected identifier but got 'payable' diff --git a/test/libsolidity/syntaxTests/variableDeclaration/transient_as_identifier.sol b/test/libsolidity/syntaxTests/variableDeclaration/transient_as_identifier.sol new file mode 100644 index 000000000000..ced189faf061 --- /dev/null +++ b/test/libsolidity/syntaxTests/variableDeclaration/transient_as_identifier.sol @@ -0,0 +1,25 @@ +contract C { + function transient() public pure { } +} + +error CustomError(uint transient); +event e1(uint transient); +event e2(uint indexed transient); + +struct S { + int transient; +} + +contract D { + function f() public pure returns (uint) { + uint transient = 1; + return transient; + } + + function g(int transient) public pure { } + + modifier m(address transient) { + _; + } +} +// ---- diff --git a/test/libsolidity/syntaxTests/variableDeclaration/transient_as_identifier_and_data_location.sol b/test/libsolidity/syntaxTests/variableDeclaration/transient_as_identifier_and_data_location.sol new file mode 100644 index 000000000000..532df5ba00a3 --- /dev/null +++ b/test/libsolidity/syntaxTests/variableDeclaration/transient_as_identifier_and_data_location.sol @@ -0,0 +1,6 @@ +contract C { + uint transient transient; +} +// ==== +// stopAfter: parsing +// ---- From 06c27a5e06683a23e31413215e6561d33acf32ea Mon Sep 17 00:00:00 2001 From: Nikola Matic Date: Sun, 2 Jun 2024 20:45:27 +0200 Subject: [PATCH 0272/1022] Require with custom error for legacy pipeline --- Changelog.md | 1 + libsolidity/codegen/ExpressionCompiler.cpp | 49 +++++++++++++++++-- ...quire_different_errors_same_parameters.sol | 2 - ...re_error_condition_evaluated_only_once.sol | 24 +++++++++ ...l => require_error_evaluation_order_1.sol} | 2 - .../require_error_evaluation_order_2.sol | 16 ++++++ .../require_error_evaluation_order_3.sol | 15 ++++++ ...quire_error_function_join_control_flow.sol | 18 +++++++ ...quire_error_function_pointer_parameter.sol | 2 - .../require_error_multiple_arguments.sol | 2 - .../errors/require_error_stack_check.sol | 19 +++++++ .../errors/require_error_string_literal.sol | 2 - .../errors/require_error_string_memory.sol | 2 - .../errors/require_error_uint256.sol | 6 +-- .../errors/require_inherited_error.sol | 2 - .../syntaxTests/errors/require_custom.sol | 2 - .../errors/require_custom_legacy.sol | 8 --- .../syntaxTests/errors/require_nested.sol | 2 - 18 files changed, 139 insertions(+), 35 deletions(-) create mode 100644 test/libsolidity/semanticTests/errors/require_error_condition_evaluated_only_once.sol rename test/libsolidity/semanticTests/errors/{require_evaluation_order.sol => require_error_evaluation_order_1.sol} (92%) create mode 100644 test/libsolidity/semanticTests/errors/require_error_evaluation_order_2.sol create mode 100644 test/libsolidity/semanticTests/errors/require_error_evaluation_order_3.sol create mode 100644 test/libsolidity/semanticTests/errors/require_error_function_join_control_flow.sol create mode 100644 test/libsolidity/semanticTests/errors/require_error_stack_check.sol delete mode 100644 test/libsolidity/syntaxTests/errors/require_custom_legacy.sol diff --git a/Changelog.md b/Changelog.md index 8ac9a7895f34..9d1aa77c64fc 100644 --- a/Changelog.md +++ b/Changelog.md @@ -2,6 +2,7 @@ Language Features: * Accept declarations of state variables with ``transient`` data location (parser support only, no code generation yet). + * Make ``require(bool, Error)`` available when using the legacy pipeline. Compiler Features: diff --git a/libsolidity/codegen/ExpressionCompiler.cpp b/libsolidity/codegen/ExpressionCompiler.cpp index 6027e0404850..368ee77a8651 100644 --- a/libsolidity/codegen/ExpressionCompiler.cpp +++ b/libsolidity/codegen/ExpressionCompiler.cpp @@ -990,6 +990,8 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall) } case FunctionType::Kind::Error: { + // This case is part of the ``revert `` path of the codegen. + // For ``require(bool, )`` refer to the ``Kind::Require`` case. _functionCall.expression().accept(*this); std::vector argumentTypes; for (ASTPointer const& arg: _functionCall.sortedArguments()) @@ -1249,9 +1251,8 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall) case FunctionType::Kind::Require: { acceptAndConvert(*arguments.front(), *function.parameterTypes().front(), false); - + // stack: bool haveReasonString = arguments.size() > 1 && m_context.revertStrings() != RevertStrings::Strip; - if (arguments.size() > 1) { // Users probably expect the second argument to be evaluated @@ -1259,11 +1260,49 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall) // function call. solAssert(arguments.size() == 2, ""); solAssert(function.kind() == FunctionType::Kind::Require, ""); - // Check if the function call matches ``require(bool, error)``, and throw an unimplemented error, - // as require with custom errors is not supported in legacy codegen. auto const* magicType = dynamic_cast(arguments[1]->annotation().type); if (magicType && magicType->kind() == MagicType::Kind::Error) - solUnimplemented("Require with a custom error is only available using the via-ir pipeline."); + { + // Make sure that error constructor arguments are evaluated regardless of the require condition + auto const& errorConstructorCall = dynamic_cast(*arguments[1]); + errorConstructorCall.expression().accept(*this); + std::vector errorConstructorArgumentTypes{}; + for (ASTPointer const& errorConstructorArgument: errorConstructorCall.sortedArguments()) + { + errorConstructorArgument->accept(*this); + errorConstructorArgumentTypes.push_back(errorConstructorArgument->annotation().type); + } + unsigned const sizeOfConditionArgument = arguments.at(0)->annotation().type->sizeOnStack(); + unsigned const sizeOfErrorArguments = CompilerUtils::sizeOnStack(errorConstructorArgumentTypes); + // stack: ... + try + { + // Move condition to the top of the stack + utils().moveToStackTop(sizeOfErrorArguments, sizeOfConditionArgument); + } + catch (StackTooDeepError const& _exception) + { + _exception << errinfo_sourceLocation(errorConstructorCall.location()); + throw _exception; + } + // stack: ... + m_context << Instruction::ISZERO << Instruction::ISZERO; + AssemblyItem successBranchTag = m_context.appendConditionalJump(); + + auto const* errorDefinition = dynamic_cast(ASTNode::referencedDeclaration(errorConstructorCall.expression())); + solAssert(errorDefinition && errorDefinition->functionType(true)); + utils().revertWithError( + errorDefinition->functionType(true)->externalSignature(), + errorDefinition->functionType(true)->parameterTypes(), + errorConstructorArgumentTypes + ); + // Here, the argument is consumed, but in the other branch, it is still there. + m_context.adjustStackOffset(static_cast(sizeOfErrorArguments)); + m_context << successBranchTag; + // In case of the success branch i.e. require(true, ...), pop error constructor arguments + utils().popStackSlots(sizeOfErrorArguments); + break; + } if (m_context.revertStrings() == RevertStrings::Strip) { diff --git a/test/libsolidity/semanticTests/errors/require_different_errors_same_parameters.sol b/test/libsolidity/semanticTests/errors/require_different_errors_same_parameters.sol index 37cbb207da59..957cb0bb11da 100644 --- a/test/libsolidity/semanticTests/errors/require_different_errors_same_parameters.sol +++ b/test/libsolidity/semanticTests/errors/require_different_errors_same_parameters.sol @@ -14,8 +14,6 @@ contract C } } -// ==== -// compileViaYul: true // ---- // f() -> FAILURE, hex"f55fefe3", hex"0000000000000000000000000000000000000000000000000000000000000001", hex"0000000000000000000000000000000000000000000000000000000000000060", hex"0000000000000000000000000000000000000000000000000000000000000003", hex"0000000000000000000000000000000000000000000000000000000000000003", hex"74776f0000000000000000000000000000000000000000000000000000000000" // g() -> FAILURE, hex"44a06798", hex"0000000000000000000000000000000000000000000000000000000000000004", hex"0000000000000000000000000000000000000000000000000000000000000060", hex"0000000000000000000000000000000000000000000000000000000000000006", hex"0000000000000000000000000000000000000000000000000000000000000004", hex"6669766500000000000000000000000000000000000000000000000000000000" diff --git a/test/libsolidity/semanticTests/errors/require_error_condition_evaluated_only_once.sol b/test/libsolidity/semanticTests/errors/require_error_condition_evaluated_only_once.sol new file mode 100644 index 000000000000..e344af43f8cf --- /dev/null +++ b/test/libsolidity/semanticTests/errors/require_error_condition_evaluated_only_once.sol @@ -0,0 +1,24 @@ +contract C { + uint256 counter = 0; + + error CustomError(uint256); + + function getCounter() public view returns (uint256) { + return counter; + } + + function g(bool condition) internal returns (bool) { + counter++; + return condition; + } + + function f(bool condition) external { + require(g(condition), CustomError(counter)); + } +} + +// ---- +// f(bool): false -> FAILURE, hex"110b3655", 1 +// getCounter() -> 0 +// f(bool): true -> +// getCounter() -> 1 diff --git a/test/libsolidity/semanticTests/errors/require_evaluation_order.sol b/test/libsolidity/semanticTests/errors/require_error_evaluation_order_1.sol similarity index 92% rename from test/libsolidity/semanticTests/errors/require_evaluation_order.sol rename to test/libsolidity/semanticTests/errors/require_error_evaluation_order_1.sol index 4733b3aee73b..019c282c6b49 100644 --- a/test/libsolidity/semanticTests/errors/require_evaluation_order.sol +++ b/test/libsolidity/semanticTests/errors/require_error_evaluation_order_1.sol @@ -21,8 +21,6 @@ contract C } } -// ==== -// compileViaYul: true // ---- // f() -> 7 // g() -> 7 diff --git a/test/libsolidity/semanticTests/errors/require_error_evaluation_order_2.sol b/test/libsolidity/semanticTests/errors/require_error_evaluation_order_2.sol new file mode 100644 index 000000000000..610caeef6f5d --- /dev/null +++ b/test/libsolidity/semanticTests/errors/require_error_evaluation_order_2.sol @@ -0,0 +1,16 @@ +contract C { + uint y; + function g(bool x) internal returns (bool) { + y = 42; + return x; + } + error E(uint256); + function h() internal returns (uint256) { return y; } + function f(bool c) public { + require(g(c), E(h())); + } +} + +// ---- +// f(bool): false -> FAILURE, hex"002ff067", 42 +// f(bool): true -> diff --git a/test/libsolidity/semanticTests/errors/require_error_evaluation_order_3.sol b/test/libsolidity/semanticTests/errors/require_error_evaluation_order_3.sol new file mode 100644 index 000000000000..0d70b16b982c --- /dev/null +++ b/test/libsolidity/semanticTests/errors/require_error_evaluation_order_3.sol @@ -0,0 +1,15 @@ +contract C { + string failureMessage = "Failure Message"; + function g(bool x) internal returns (bool) { + failureMessage = "Intercepted failure message"; + return x; + } + function h() internal returns (string memory) { return failureMessage; } + function f(bool c) public { + require(g(c), h()); + } +} + +// ---- +// f(bool): false -> FAILURE, hex"08c379a0", 0x20, 0x1b, "Intercepted failure message" +// f(bool): true -> diff --git a/test/libsolidity/semanticTests/errors/require_error_function_join_control_flow.sol b/test/libsolidity/semanticTests/errors/require_error_function_join_control_flow.sol new file mode 100644 index 000000000000..e3d7e5fdde94 --- /dev/null +++ b/test/libsolidity/semanticTests/errors/require_error_function_join_control_flow.sol @@ -0,0 +1,18 @@ +contract C { + uint x = 0; + uint y = 42; + error E(uint); + function f(bool c) public returns (uint256, uint256, uint256) { + uint z = x; + if (y == 42) { + x = 21; + } else { + require(c, E(y)); + } + y /= 2; + return (x,y,z); + } +} +// ---- +// f(bool): true -> 0x15, 0x15, 0 +// f(bool): false -> FAILURE, hex"002ff067", 21 diff --git a/test/libsolidity/semanticTests/errors/require_error_function_pointer_parameter.sol b/test/libsolidity/semanticTests/errors/require_error_function_pointer_parameter.sol index 2e1dcdd5888a..3af19ca64fbf 100644 --- a/test/libsolidity/semanticTests/errors/require_error_function_pointer_parameter.sol +++ b/test/libsolidity/semanticTests/errors/require_error_function_pointer_parameter.sol @@ -14,7 +14,5 @@ contract C } } -// ==== -// compileViaYul: true // ---- // f() -> FAILURE, hex"271b1dfa", hex"c06afe3a8444fc0004668591e8306bfb9968e79ef37cdc8e0000000000000000" diff --git a/test/libsolidity/semanticTests/errors/require_error_multiple_arguments.sol b/test/libsolidity/semanticTests/errors/require_error_multiple_arguments.sol index 6c8521f9d2de..98254cf08d04 100644 --- a/test/libsolidity/semanticTests/errors/require_error_multiple_arguments.sol +++ b/test/libsolidity/semanticTests/errors/require_error_multiple_arguments.sol @@ -13,8 +13,6 @@ contract C } } -// ==== -// compileViaYul: true // ---- // f() -> FAILURE, hex"11a1077e", hex"0000000000000000000000000000000000000000000000000000000000000001", hex"0000000000000000000000000000000000000000000000000000000000000060", hex"0000000000000000000000000000000000000000000000000000000000000003", hex"0000000000000000000000000000000000000000000000000000000000000003", hex"74776f0000000000000000000000000000000000000000000000000000000000" // g() -> FAILURE, hex"11a1077e", hex"0000000000000000000000000000000000000000000000000000000000000004", hex"0000000000000000000000000000000000000000000000000000000000000060", hex"0000000000000000000000000000000000000000000000000000000000000006", hex"0000000000000000000000000000000000000000000000000000000000000004", hex"6669766500000000000000000000000000000000000000000000000000000000" diff --git a/test/libsolidity/semanticTests/errors/require_error_stack_check.sol b/test/libsolidity/semanticTests/errors/require_error_stack_check.sol new file mode 100644 index 000000000000..0f77e252de31 --- /dev/null +++ b/test/libsolidity/semanticTests/errors/require_error_stack_check.sol @@ -0,0 +1,19 @@ +// The purpose of this test is to make sure that error constructor call +// stack items are popped from the stack in the success branch, i.e. when +// require condition is true. +contract C { + error E(uint, uint, uint, function(uint256) external pure returns (uint256)); + uint public x; + + function e(uint256 y) external pure returns (uint256) { + return y; + } + + function f(bool condition, uint a, uint b, uint c) public { + require(condition, E(a, b, c, this.e)); + x = b; + } +} +// ---- +// f(bool,uint256,uint256,uint256): true, 42, 4242, 424242 -> +// x() -> 4242 diff --git a/test/libsolidity/semanticTests/errors/require_error_string_literal.sol b/test/libsolidity/semanticTests/errors/require_error_string_literal.sol index 5a3a140d0b23..6e72253ea129 100644 --- a/test/libsolidity/semanticTests/errors/require_error_string_literal.sol +++ b/test/libsolidity/semanticTests/errors/require_error_string_literal.sol @@ -13,8 +13,6 @@ contract C } } -// ==== -// compileViaYul: true // ---- // f() -> FAILURE, hex"8d6ea8be", hex"0000000000000000000000000000000000000000000000000000000000000020", hex"000000000000000000000000000000000000000000000000000000000000000b", hex"6572726f72526561736f6e000000000000000000000000000000000000000000" // g() -> FAILURE, hex"8d6ea8be", hex"0000000000000000000000000000000000000000000000000000000000000020", hex"000000000000000000000000000000000000000000000000000000000000000d", hex"616e6f74686572526561736f6e00000000000000000000000000000000000000" diff --git a/test/libsolidity/semanticTests/errors/require_error_string_memory.sol b/test/libsolidity/semanticTests/errors/require_error_string_memory.sol index 13947d399036..15178d859e35 100644 --- a/test/libsolidity/semanticTests/errors/require_error_string_memory.sol +++ b/test/libsolidity/semanticTests/errors/require_error_string_memory.sol @@ -15,8 +15,6 @@ contract C } } -// ==== -// compileViaYul: true // ---- // f() -> FAILURE, hex"8d6ea8be", hex"0000000000000000000000000000000000000000000000000000000000000020", hex"000000000000000000000000000000000000000000000000000000000000000b", hex"6572726f72526561736f6e000000000000000000000000000000000000000000" // g() -> FAILURE, hex"8d6ea8be", hex"0000000000000000000000000000000000000000000000000000000000000020", hex"000000000000000000000000000000000000000000000000000000000000000d", hex"616e6f74686572526561736f6e00000000000000000000000000000000000000" diff --git a/test/libsolidity/semanticTests/errors/require_error_uint256.sol b/test/libsolidity/semanticTests/errors/require_error_uint256.sol index d400e5fa7c23..3b8915f8d0ce 100644 --- a/test/libsolidity/semanticTests/errors/require_error_uint256.sol +++ b/test/libsolidity/semanticTests/errors/require_error_uint256.sol @@ -13,8 +13,6 @@ contract C } } -// ==== -// compileViaYul: true // ---- -// f() -> FAILURE, hex"110b3655", hex"0000000000000000000000000000000000000000000000000000000000000001" -// g() -> FAILURE, hex"110b3655", hex"0000000000000000000000000000000000000000000000000000000000000002" +// f() -> FAILURE, hex"110b3655", 1 +// g() -> FAILURE, hex"110b3655", 2 diff --git a/test/libsolidity/semanticTests/errors/require_inherited_error.sol b/test/libsolidity/semanticTests/errors/require_inherited_error.sol index 24b544b73cf9..33cf0e962575 100644 --- a/test/libsolidity/semanticTests/errors/require_inherited_error.sol +++ b/test/libsolidity/semanticTests/errors/require_inherited_error.sol @@ -11,7 +11,5 @@ contract C is Base } } -// ==== -// compileViaYul: true // ---- // f() -> FAILURE, hex"11a1077e", hex"0000000000000000000000000000000000000000000000000000000000000001", hex"0000000000000000000000000000000000000000000000000000000000000060", hex"0000000000000000000000000000000000000000000000000000000000000003", hex"0000000000000000000000000000000000000000000000000000000000000003", hex"74776f0000000000000000000000000000000000000000000000000000000000" diff --git a/test/libsolidity/syntaxTests/errors/require_custom.sol b/test/libsolidity/syntaxTests/errors/require_custom.sol index f428390277fb..0530e8432a17 100644 --- a/test/libsolidity/syntaxTests/errors/require_custom.sol +++ b/test/libsolidity/syntaxTests/errors/require_custom.sol @@ -4,6 +4,4 @@ contract C { require(c, E(2, 7)); } } -// ==== -// compileViaYul: true // ---- diff --git a/test/libsolidity/syntaxTests/errors/require_custom_legacy.sol b/test/libsolidity/syntaxTests/errors/require_custom_legacy.sol deleted file mode 100644 index c1eae591f292..000000000000 --- a/test/libsolidity/syntaxTests/errors/require_custom_legacy.sol +++ /dev/null @@ -1,8 +0,0 @@ -error E(uint a, uint b); -contract C { - function f(bool c) public pure { - require(c, E(2, 7)); - } -} -// ---- -// UnimplementedFeatureError 1834: Require with a custom error is only available using the via-ir pipeline. diff --git a/test/libsolidity/syntaxTests/errors/require_nested.sol b/test/libsolidity/syntaxTests/errors/require_nested.sol index c5dc018242df..0129959a02fc 100644 --- a/test/libsolidity/syntaxTests/errors/require_nested.sol +++ b/test/libsolidity/syntaxTests/errors/require_nested.sol @@ -9,7 +9,5 @@ contract C } } -// ==== -// compileViaYul: true // ---- // TypeError 9322: (118-125): No matching declaration found after argument-dependent lookup. From 20213011040ac85e14ced4bedd20f66d480efa2c Mon Sep 17 00:00:00 2001 From: Nikola Matic Date: Tue, 11 Jun 2024 16:09:32 +0200 Subject: [PATCH 0273/1022] Changelog and docs --- docs/contracts/errors.rst | 3 +-- docs/control-structures.rst | 4 ---- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/docs/contracts/errors.rst b/docs/contracts/errors.rst index 8c57586e96f8..d345b4eacf8a 100644 --- a/docs/contracts/errors.rst +++ b/docs/contracts/errors.rst @@ -19,7 +19,7 @@ as well as the newer approach with ``require`` in function ``transferWithRequire .. code-block:: solidity // SPDX-License-Identifier: GPL-3.0 - pragma solidity ^0.8.26; + pragma solidity ^0.8.27; /// Insufficient balance for transfer. Needed `required` but only /// `available` available. @@ -27,7 +27,6 @@ as well as the newer approach with ``require`` in function ``transferWithRequire /// @param required requested amount to transfer. error InsufficientBalance(uint256 available, uint256 required); - // This will only compile via IR contract TestToken { mapping(address => uint) balance; function transferWithRevertError(address to, uint256 amount) public { diff --git a/docs/control-structures.rst b/docs/control-structures.rst index 81e62ec57bea..238d261152c5 100644 --- a/docs/control-structures.rst +++ b/docs/control-structures.rst @@ -639,10 +639,6 @@ The ``require`` function provides three overloads: For example, in ``require(condition, CustomError(f()));`` and ``require(condition, f());``, function ``f()`` will be called regardless of whether the supplied condition is ``true`` or ``false``. -.. note:: - Using custom errors with ``require`` is only supported by the via IR pipeline, i.e. compilation via Yul. - For the legacy pipeline, please use ``if (!condition) revert CustomError();`` instead. - An ``Error(string)`` exception (or an exception without data) is generated by the compiler in the following situations: From 933598d2eac23bc96521a3cf8febcfe685b48a9f Mon Sep 17 00:00:00 2001 From: Martin Blicha Date: Mon, 17 Jun 2024 21:56:19 +0200 Subject: [PATCH 0274/1022] SMTChecker: Methods returning callback can be const --- libsolidity/interface/SMTSolverCommand.cpp | 2 +- libsolidity/interface/SMTSolverCommand.h | 4 ++-- libsolidity/interface/UniversalCallback.h | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/libsolidity/interface/SMTSolverCommand.cpp b/libsolidity/interface/SMTSolverCommand.cpp index 7dfb448f8bc2..1eaa3f38cae7 100644 --- a/libsolidity/interface/SMTSolverCommand.cpp +++ b/libsolidity/interface/SMTSolverCommand.cpp @@ -63,7 +63,7 @@ void SMTSolverCommand::setCvc5(std::optional timeoutInMilliseconds } } -ReadCallback::Result SMTSolverCommand::solve(std::string const& _kind, std::string const& _query) +ReadCallback::Result SMTSolverCommand::solve(std::string const& _kind, std::string const& _query) const { try { diff --git a/libsolidity/interface/SMTSolverCommand.h b/libsolidity/interface/SMTSolverCommand.h index 3b1022740524..c948ec5d2d65 100644 --- a/libsolidity/interface/SMTSolverCommand.h +++ b/libsolidity/interface/SMTSolverCommand.h @@ -29,9 +29,9 @@ class SMTSolverCommand { public: /// Calls an SMT solver with the given query. - frontend::ReadCallback::Result solve(std::string const& _kind, std::string const& _query); + frontend::ReadCallback::Result solve(std::string const& _kind, std::string const& _query) const; - frontend::ReadCallback::Callback solver() + frontend::ReadCallback::Callback solver() const { return [this](std::string const& _kind, std::string const& _query) { return solve(_kind, _query); }; } diff --git a/libsolidity/interface/UniversalCallback.h b/libsolidity/interface/UniversalCallback.h index ef5450a1c5e4..943d7e50cb81 100644 --- a/libsolidity/interface/UniversalCallback.h +++ b/libsolidity/interface/UniversalCallback.h @@ -46,7 +46,7 @@ class UniversalCallback solAssert(false, "Unknown callback kind."); } - frontend::ReadCallback::Callback callback() + frontend::ReadCallback::Callback callback() const { return *this; } From 3e5516cee5903d6940dd42ee97a8dad21a22c6ec Mon Sep 17 00:00:00 2001 From: Martin Blicha Date: Mon, 17 Jun 2024 21:57:49 +0200 Subject: [PATCH 0275/1022] SMTChecker: Add SMT callback to SMTChecker tests --- test/libsolidity/SMTCheckerTest.cpp | 9 ++++++++- test/libsolidity/SMTCheckerTest.h | 12 ++++++++++-- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/test/libsolidity/SMTCheckerTest.cpp b/test/libsolidity/SMTCheckerTest.cpp index e3ec14c97c0d..8149f3130c5d 100644 --- a/test/libsolidity/SMTCheckerTest.cpp +++ b/test/libsolidity/SMTCheckerTest.cpp @@ -25,8 +25,11 @@ using namespace solidity; using namespace solidity::langutil; using namespace solidity::frontend; using namespace solidity::frontend::test; +using namespace solidity::test; -SMTCheckerTest::SMTCheckerTest(std::string const& _filename): SyntaxTest(_filename, EVMVersion{}) +SMTCheckerTest::SMTCheckerTest(std::string const& _filename): + SyntaxTest(_filename, EVMVersion{}), + universalCallback(nullptr, smtCommand) { auto contract = m_reader.stringSetting("SMTContract", ""); if (!contract.empty()) @@ -168,3 +171,7 @@ void SMTCheckerTest::printUpdatedExpectations(std::ostream &_stream, const std:: else CommonSyntaxTest::printUpdatedExpectations(_stream, _linePrefix); } + +std::unique_ptr SMTCheckerTest::createStack() const { + return std::make_unique(universalCallback.callback()); +} diff --git a/test/libsolidity/SMTCheckerTest.h b/test/libsolidity/SMTCheckerTest.h index 6a15791522e7..07ae3728d42c 100644 --- a/test/libsolidity/SMTCheckerTest.h +++ b/test/libsolidity/SMTCheckerTest.h @@ -24,6 +24,9 @@ #include +#include +#include + #include namespace solidity::frontend::test @@ -36,7 +39,7 @@ class SMTCheckerTest: public SyntaxTest { return std::make_unique(_config.filename); } - SMTCheckerTest(std::string const& _filename); + explicit SMTCheckerTest(std::string const& _filename); void setupCompiler(CompilerStack& _compiler) override; void filterObtainedErrors() override; @@ -44,6 +47,8 @@ class SMTCheckerTest: public SyntaxTest void printUpdatedExpectations(std::ostream& _stream, std::string const& _linePrefix) const override; protected: + std::unique_ptr createStack() const override; + /* Options that can be set in the test: SMTEngine: `all`, `chc`, `bmc`, `none`, where the default is `all`. @@ -56,7 +61,7 @@ class SMTCheckerTest: public SyntaxTest Set in m_modelCheckerSettings. SMTShowUnproved: `yes`, `no`, where the default is `yes`. Set in m_modelCheckerSettings. - SMTSolvers: `all`, `cvc5`, `z3`, `none`, where the default is `all`. + SMTSolvers: `all`, `cvc5`, `z3`, `eld`, `none`, where the default is `z3`. Set in m_modelCheckerSettings. BMCLoopIterations: number of loop iterations for BMC engine, the default is 1. Set in m_modelCheckerSettings. @@ -67,6 +72,9 @@ class SMTCheckerTest: public SyntaxTest bool m_ignoreCex = false; std::vector m_unfilteredErrorList; + + SMTSolverCommand smtCommand; + UniversalCallback universalCallback; }; } From f9be1e3812e426fde2d8ae59c5241cd6969c15cc Mon Sep 17 00:00:00 2001 From: Martin Blicha Date: Mon, 17 Jun 2024 22:01:21 +0200 Subject: [PATCH 0276/1022] SMTChecker: Bring back assertions in "external_calls" SMTChecker tests Several assertions were commented out because of nondeterminism we observed in Spacer, which made these tests brittle. Spacer can now solve some of them, others we can now solve with Eldarica. Note that running Eldarica seems to come with significant overhead, because it starts a new Eldarica process (which starts new JVM) for every query. --- .../external_calls/call_with_value_3.sol | 11 ++++++----- .../external_calls/external_call_with_value_1.sol | 10 +++++----- .../external_hash_known_code_state_reentrancy.sol | 7 +++---- .../external_calls/external_reentrancy_3.sol | 8 ++++---- .../external_calls/mutex_f_no_guard.sol | 7 +++---- 5 files changed, 21 insertions(+), 22 deletions(-) diff --git a/test/libsolidity/smtCheckerTests/external_calls/call_with_value_3.sol b/test/libsolidity/smtCheckerTests/external_calls/call_with_value_3.sol index 6cbe241362e4..4b3dcd091be6 100644 --- a/test/libsolidity/smtCheckerTests/external_calls/call_with_value_3.sol +++ b/test/libsolidity/smtCheckerTests/external_calls/call_with_value_3.sol @@ -3,13 +3,14 @@ contract C { require(address(this).balance > 100); i.call{value: 20}(""); assert(address(this).balance > 0); // should hold - // Disabled due to Spacer nondeterminism - //assert(address(this).balance == 0); // should fail + assert(address(this).balance == 0); // should fail } } // ==== -// SMTEngine: all +// SMTEngine: chc +// SMTIgnoreCex: yes +// SMTSolvers: eld // ---- // Warning 9302: (95-116): Return value of low-level calls not used. -// Warning 6328: (120-153): CHC: Assertion violation might happen here. -// Warning 4661: (120-153): BMC: Assertion violation happens here. +// Warning 6328: (172-206): CHC: Assertion violation happens here. +// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/external_calls/external_call_with_value_1.sol b/test/libsolidity/smtCheckerTests/external_calls/external_call_with_value_1.sol index a5ac8ded97e4..3ecdb00bd32e 100644 --- a/test/libsolidity/smtCheckerTests/external_calls/external_call_with_value_1.sol +++ b/test/libsolidity/smtCheckerTests/external_calls/external_call_with_value_1.sol @@ -7,12 +7,12 @@ contract C { require(address(this).balance == 100); i.f{value: 10}(); assert(address(this).balance == 90); // should hold - // Disabled due to Spacer nondeterminism - //assert(address(this).balance == 100); // should fail + assert(address(this).balance == 100); // should fail } } // ==== -// SMTEngine: all +// SMTEngine: chc +// SMTSolvers: eld // ---- -// Warning 6328: (151-186): CHC: Assertion violation might happen here. -// Warning 4661: (151-186): BMC: Assertion violation happens here. +// Warning 6328: (205-241): CHC: Assertion violation happens here. +// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/external_calls/external_hash_known_code_state_reentrancy.sol b/test/libsolidity/smtCheckerTests/external_calls/external_hash_known_code_state_reentrancy.sol index 29d18489594e..69f76be6b76e 100644 --- a/test/libsolidity/smtCheckerTests/external_calls/external_hash_known_code_state_reentrancy.sol +++ b/test/libsolidity/smtCheckerTests/external_calls/external_hash_known_code_state_reentrancy.sol @@ -19,8 +19,7 @@ contract C { address prevOwner = owner; uint z = s.f(); assert(z == y); - // Disabled because of Spacer nondeterminism. - //assert(prevOwner == owner); + assert(prevOwner == owner); } function g() public view returns (uint) { @@ -31,5 +30,5 @@ contract C { // SMTEngine: all // SMTIgnoreCex: yes // ---- -// Warning 2072: (219-236): Unused local variable. -// Warning 6328: (266-280): CHC: Assertion violation happens here. +// Warning 6328: (266-280): CHC: Assertion violation happens here.\nCounterexample:\nowner = 0x0, y = 0, s = 0\nprevOwner = 0x0\nz = 1\n\nTransaction trace:\nC.constructor(){ msg.sender: 0x0 }\nState: owner = 0x0, y = 0, s = 0\nC.f()\n s.f() -- untrusted external call +// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/external_calls/external_reentrancy_3.sol b/test/libsolidity/smtCheckerTests/external_calls/external_reentrancy_3.sol index cfe12434c3ea..bdae00667b25 100644 --- a/test/libsolidity/smtCheckerTests/external_calls/external_reentrancy_3.sol +++ b/test/libsolidity/smtCheckerTests/external_calls/external_reentrancy_3.sol @@ -21,15 +21,15 @@ contract C is A { function f() public view override { assert(x == 1); // should hold - //Disabled because of Spacer nondeterminism. - //assert(x == 0); // should fail + assert(x == 0); // should fail } } // ==== -// SMTEngine: all +// SMTEngine: chc // SMTIgnoreCex: yes // SMTIgnoreInv: yes -// SMTIgnoreOS: macos +// SMTSolvers: eld // ---- // Warning 6328: (154-168): CHC: Assertion violation happens here. +// Warning 6328: (352-366): CHC: Assertion violation happens here. // Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/external_calls/mutex_f_no_guard.sol b/test/libsolidity/smtCheckerTests/external_calls/mutex_f_no_guard.sol index 76568adf6504..7e66c51e17ca 100644 --- a/test/libsolidity/smtCheckerTests/external_calls/mutex_f_no_guard.sol +++ b/test/libsolidity/smtCheckerTests/external_calls/mutex_f_no_guard.sol @@ -21,12 +21,11 @@ contract C { function f() public { uint y = x; d.d(); - // Disabled because of Spacer nondeterminism. - //assert(y == x); + assert(y == x); } } // ==== -// SMTEngine: all +// SMTEngine: chc // SMTIgnoreCex: yes // ---- -// Warning 2072: (251-257): Unused local variable. +// Warning 6328: (274-288): CHC: Assertion violation happens here.\nCounterexample:\nx = 0, d = 0, lock = false\ny = 1\n\nTransaction trace:\nC.constructor()\nState: x = 0, d = 0, lock = false\nC.set(1)\nState: x = 1, d = 0, lock = false\nC.f()\n d.d() -- untrusted external call, synthesized as:\n C.set(0) -- reentrant call From fbb5eede41433c91ae94e776fdd173435d01e23c Mon Sep 17 00:00:00 2001 From: Martin Blicha Date: Wed, 19 Jun 2024 17:42:38 +0200 Subject: [PATCH 0277/1022] Docs: Small update regarding the use of Eldarica --- docs/contributing.rst | 8 ++++++-- docs/installing-solidity.rst | 13 +++++++++---- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/docs/contributing.rst b/docs/contributing.rst index 8ce402680bb1..36b85867945c 100644 --- a/docs/contributing.rst +++ b/docs/contributing.rst @@ -93,7 +93,8 @@ Prerequisites For running all compiler tests you may want to optionally install a few dependencies (`evmone `_, -`libz3 `_). +`libz3 `_, `Eldarica `_, +`cvc5 `). On macOS systems, some of the testing scripts expect GNU coreutils to be installed. This can be easiest accomplished using Homebrew: ``brew install coreutils``. @@ -133,11 +134,14 @@ extension ``.so`` on Linux, ``.dll`` on Windows systems and ``.dylib`` on macOS. For running SMT tests, the ``libz3`` library must be installed and locatable by ``cmake`` during compiler configure stage. +A few SMT tests use ``Eldarica`` instead of ``Z3``. +``Eldarica`` is a runtime dependency, its executable (``eld``) must be present in ``PATH`` for the tests to pass. +However, if ``Eldarica`` is not found, these tests will be automatically skipped. If the ``libz3`` library is not installed on your system, you should disable the SMT tests by exporting ``SMT_FLAGS=--no-smt`` before running ``./scripts/tests.sh`` or running ``./scripts/soltest.sh --no-smt``. -These tests are ``libsolidity/smtCheckerTests`` and ``libsolidity/smtCheckerTestsJSON``. +These tests are ``libsolidity/smtCheckerTests``. .. note:: diff --git a/docs/installing-solidity.rst b/docs/installing-solidity.rst index e37fc19853f1..b1b3e1a3fbac 100644 --- a/docs/installing-solidity.rst +++ b/docs/installing-solidity.rst @@ -527,19 +527,24 @@ If you are interested what CMake options are available run ``cmake .. -LH``. SMT Solvers ----------- -Solidity can be built against SMT solvers and will do so by default if -they are found in the system. Each solver can be disabled by a ``cmake`` option. +Solidity can be built against Z3 SMT solver and will do so by default if +it is found in the system. Z3 can be disabled by a ``cmake`` option. *Note: In some cases, this can also be a potential workaround for build failures.* -Inside the build folder you can disable them, since they are enabled by default: +Inside the build folder you can disable Z3, since it is enabled by default: .. code-block:: bash - # disables only Z3 SMT Solver. + # disables Z3 SMT Solver. cmake .. -DUSE_Z3=OFF +.. note:: + + Solidity can optionally use other solvers, namely ``cvc5`` and ``Eldarica``, + but their presence is checked only at runtime, they are not needed for the build to succeed. + The Version String in Detail ============================ From d51dbe83a4020b7888b207204576fd9d8b786fbf Mon Sep 17 00:00:00 2001 From: ToonVanHove <9501896+ToonVanHove@users.noreply.github.com> Date: Fri, 21 Jun 2024 09:17:57 +0200 Subject: [PATCH 0278/1022] doc: better specify blobhash() behaviour --- docs/cheatsheet.rst | 1 + docs/units-and-global-variables.rst | 1 + docs/yul.rst | 3 ++- 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/docs/cheatsheet.rst b/docs/cheatsheet.rst index 6b69b81be34a..79aa6e65d552 100644 --- a/docs/cheatsheet.rst +++ b/docs/cheatsheet.rst @@ -66,6 +66,7 @@ Block and Transaction Properties - ``blobhash(uint index) returns (bytes32)``: versioned hash of the ``index``-th blob associated with the current transaction. A versioned hash consists of a single byte representing the version (currently ``0x01``), followed by the last 31 bytes of the SHA256 hash of the KZG commitment (`EIP-4844 `_). + Returns zero if no blob with the given index exists. - ``block.basefee`` (``uint``): current block's base fee (`EIP-3198 `_ and `EIP-1559 `_) - ``block.blobbasefee`` (``uint``): current block's blob base fee (`EIP-7516 `_ and `EIP-4844 `_) - ``block.chainid`` (``uint``): current chain id diff --git a/docs/units-and-global-variables.rst b/docs/units-and-global-variables.rst index a743441d564d..fce4cf96d994 100644 --- a/docs/units-and-global-variables.rst +++ b/docs/units-and-global-variables.rst @@ -77,6 +77,7 @@ Block and Transaction Properties - ``blobhash(uint index) returns (bytes32)``: versioned hash of the ``index``-th blob associated with the current transaction. A versioned hash consists of a single byte representing the version (currently ``0x01``), followed by the last 31 bytes of the SHA256 hash of the KZG commitment (`EIP-4844 `_). + Returns zero if no blob with the given index exists. - ``block.basefee`` (``uint``): current block's base fee (`EIP-3198 `_ and `EIP-1559 `_) - ``block.blobbasefee`` (``uint``): current block's blob base fee (`EIP-7516 `_ and `EIP-4844 `_) - ``block.chainid`` (``uint``): current chain id diff --git a/docs/yul.rst b/docs/yul.rst index 3cf2785fc444..0932c8fa6326 100644 --- a/docs/yul.rst +++ b/docs/yul.rst @@ -934,7 +934,8 @@ the ``dup`` and ``swap`` instructions as well as ``jump`` instructions, labels a +-------------------------+-----+---+-----------------------------------------------------------------+ | blockhash(b) | | F | hash of block nr b - only for last 256 blocks excluding current | +-------------------------+-----+---+-----------------------------------------------------------------+ -| blobhash(i) | | N | versioned hash of transaction's i-th blob | +| blobhash(i) | | N | versioned hash of transaction's i-th blob, 0 if blob does not | +| | | | exist | +-------------------------+-----+---+-----------------------------------------------------------------+ | coinbase() | | F | current mining beneficiary | +-------------------------+-----+---+-----------------------------------------------------------------+ From dd60886c88ad78dccd2ab78dc8a4ab8cf0d7dfe3 Mon Sep 17 00:00:00 2001 From: Nikola Matic Date: Mon, 24 Jun 2024 16:02:33 +0200 Subject: [PATCH 0279/1022] Error out on transient usage in TypeChecker --- libsolidity/analysis/TypeChecker.cpp | 7 +++ libsolidity/codegen/ContractCompiler.cpp | 3 + libsolidity/codegen/ir/IRGenerator.cpp | 3 + .../output.json | 57 ++++++++++++++++++- .../transient_data_location.sol | 8 --- .../transient_storage_state_variable.sol | 2 +- ...transient_dynamic_array_state_variable.sol | 2 - .../transient_fixed_array_state_variable.sol | 2 - .../dataLocations/transient_function_type.sol | 8 ++- .../transient_mapping_state_variable.sol | 3 +- .../transient_state_variable_visibility.sol | 8 ++- .../transient_struct_state_variable.sol | 2 - .../transient_value_type_state_variables.sol | 7 ++- ..._value_type_state_variables_assignment.sol | 5 +- 14 files changed, 89 insertions(+), 28 deletions(-) delete mode 100644 test/libsolidity/astPropertyTests/transient_data_location.sol diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp index 918e27033329..dfd334295a2a 100644 --- a/libsolidity/analysis/TypeChecker.cpp +++ b/libsolidity/analysis/TypeChecker.cpp @@ -478,6 +478,13 @@ bool TypeChecker::visit(VariableDeclaration const& _variable) Type const* varType = _variable.annotation().type; solAssert(!!varType, "Variable type not provided."); + if (_variable.referenceLocation() == VariableDeclaration::Location::Transient) + m_errorReporter.unimplementedFeatureError( + 6715_error, + _variable.location(), + "Transient storage is not yet implemented." + ); + if (_variable.value()) { if (_variable.isStateVariable() && varType->containsNestedMapping()) diff --git a/libsolidity/codegen/ContractCompiler.cpp b/libsolidity/codegen/ContractCompiler.cpp index 32fb9cae7bcf..2326d3336364 100644 --- a/libsolidity/codegen/ContractCompiler.cpp +++ b/libsolidity/codegen/ContractCompiler.cpp @@ -585,8 +585,11 @@ void ContractCompiler::initializeStateVariables(ContractDefinition const& _contr { solAssert(!_contract.isLibrary(), "Tried to initialize state variables of library."); for (VariableDeclaration const* variable: _contract.stateVariables()) + { + solUnimplementedAssert(variable->referenceLocation() != VariableDeclaration::Location::Transient, "Transient storage variables not supported."); if (variable->value() && !variable->isConstant()) ExpressionCompiler(m_context, m_optimiserSettings.runOrderLiterals).appendStateVariableInitialization(*variable); + } } bool ContractCompiler::visit(VariableDeclaration const& _variableDeclaration) diff --git a/libsolidity/codegen/ir/IRGenerator.cpp b/libsolidity/codegen/ir/IRGenerator.cpp index 59585c762eec..93136a1a26cb 100644 --- a/libsolidity/codegen/ir/IRGenerator.cpp +++ b/libsolidity/codegen/ir/IRGenerator.cpp @@ -821,8 +821,11 @@ std::string IRGenerator::initStateVariables(ContractDefinition const& _contract) { IRGeneratorForStatements generator{m_context, m_utils, m_optimiserSettings}; for (VariableDeclaration const* variable: _contract.stateVariables()) + { + solUnimplementedAssert(variable->referenceLocation() != VariableDeclaration::Location::Transient, "Transient storage variables not supported."); if (!variable->isConstant()) generator.initializeStateVar(*variable); + } return generator.code(); } diff --git a/test/cmdlineTests/storage_layout_transient_value_types/output.json b/test/cmdlineTests/storage_layout_transient_value_types/output.json index a446210485f9..b77de9326200 100644 --- a/test/cmdlineTests/storage_layout_transient_value_types/output.json +++ b/test/cmdlineTests/storage_layout_transient_value_types/output.json @@ -2,10 +2,61 @@ "errors": [ { "component": "general", - "formattedMessage": "Transient storage layout is not supported yet.", - "message": "Transient storage layout is not supported yet.", + "errorCode": "6715", + "formattedMessage": "UnimplementedFeatureError: Transient storage is not yet implemented. + --> fileA:4:5: + | +4 | uint transient x; + | ^^^^^^^^^^^^^^^^ + +", + "message": "Transient storage is not yet implemented.", "severity": "error", + "sourceLocation": { + "end": 91, + "file": "fileA", + "start": 75 + }, + "type": "UnimplementedFeatureError" + }, + { + "component": "general", + "errorCode": "6715", + "formattedMessage": "UnimplementedFeatureError: Transient storage is not yet implemented. + --> fileA:6:5: + | +6 | bytes32 transient b; + | ^^^^^^^^^^^^^^^^^^^ + +", + "message": "Transient storage is not yet implemented.", + "severity": "error", + "sourceLocation": { + "end": 128, + "file": "fileA", + "start": 109 + }, + "type": "UnimplementedFeatureError" + }, + { + "component": "general", + "errorCode": "6715", + "formattedMessage": "UnimplementedFeatureError: Transient storage is not yet implemented. + --> fileA:8:5: + | +8 | address transient a; + | ^^^^^^^^^^^^^^^^^^^ + +", + "message": "Transient storage is not yet implemented.", + "severity": "error", + "sourceLocation": { + "end": 168, + "file": "fileA", + "start": 149 + }, "type": "UnimplementedFeatureError" } - ] + ], + "sources": {} } diff --git a/test/libsolidity/astPropertyTests/transient_data_location.sol b/test/libsolidity/astPropertyTests/transient_data_location.sol deleted file mode 100644 index 6a937414d6bd..000000000000 --- a/test/libsolidity/astPropertyTests/transient_data_location.sol +++ /dev/null @@ -1,8 +0,0 @@ -contract C { - /// TestVarDataLocation: storageLocation - /// TestVarName: name - uint transient transient; -} -// ---- -// TestVarDataLocation: transient -// TestVarName: transient diff --git a/test/libsolidity/smtCheckerTests/unsupported/transient_storage_state_variable.sol b/test/libsolidity/smtCheckerTests/unsupported/transient_storage_state_variable.sol index b2dbc8efe5c7..cdb4461656a6 100644 --- a/test/libsolidity/smtCheckerTests/unsupported/transient_storage_state_variable.sol +++ b/test/libsolidity/smtCheckerTests/unsupported/transient_storage_state_variable.sol @@ -5,4 +5,4 @@ contract C { // ==== // SMTEngine: all // ---- -// UnimplementedFeatureError 1834: Transient storage variables are not supported. +// UnimplementedFeatureError 6715: (17-38): Transient storage is not yet implemented. diff --git a/test/libsolidity/syntaxTests/dataLocations/transient_dynamic_array_state_variable.sol b/test/libsolidity/syntaxTests/dataLocations/transient_dynamic_array_state_variable.sol index b82f40267edd..7a3caa86e53b 100644 --- a/test/libsolidity/syntaxTests/dataLocations/transient_dynamic_array_state_variable.sol +++ b/test/libsolidity/syntaxTests/dataLocations/transient_dynamic_array_state_variable.sol @@ -1,7 +1,5 @@ contract C { uint[] transient x; } -// ==== -// stopAfter: analysis // ---- // UnimplementedFeatureError 1834: Transient data location is only supported for value types. diff --git a/test/libsolidity/syntaxTests/dataLocations/transient_fixed_array_state_variable.sol b/test/libsolidity/syntaxTests/dataLocations/transient_fixed_array_state_variable.sol index 3f7cec2a7588..10b942e236e3 100644 --- a/test/libsolidity/syntaxTests/dataLocations/transient_fixed_array_state_variable.sol +++ b/test/libsolidity/syntaxTests/dataLocations/transient_fixed_array_state_variable.sol @@ -1,7 +1,5 @@ contract C { uint[3] transient x; } -// ==== -// stopAfter: analysis // ---- // UnimplementedFeatureError 1834: Transient data location is only supported for value types. diff --git a/test/libsolidity/syntaxTests/dataLocations/transient_function_type.sol b/test/libsolidity/syntaxTests/dataLocations/transient_function_type.sol index 9deba463c195..a3d741bbe2e3 100644 --- a/test/libsolidity/syntaxTests/dataLocations/transient_function_type.sol +++ b/test/libsolidity/syntaxTests/dataLocations/transient_function_type.sol @@ -6,6 +6,10 @@ contract C { function () internal transient internal fiti; function () internal internal transient fiit; } -// ==== -// stopAfter: analysis // ---- +// UnimplementedFeatureError 6715: (17-40): Transient storage is not yet implemented. +// UnimplementedFeatureError 6715: (46-82): Transient storage is not yet implemented. +// UnimplementedFeatureError 6715: (88-122): Transient storage is not yet implemented. +// UnimplementedFeatureError 6715: (128-162): Transient storage is not yet implemented. +// UnimplementedFeatureError 6715: (168-212): Transient storage is not yet implemented. +// UnimplementedFeatureError 6715: (218-262): Transient storage is not yet implemented. diff --git a/test/libsolidity/syntaxTests/dataLocations/transient_mapping_state_variable.sol b/test/libsolidity/syntaxTests/dataLocations/transient_mapping_state_variable.sol index cd762df30e62..2a21b3e00a76 100644 --- a/test/libsolidity/syntaxTests/dataLocations/transient_mapping_state_variable.sol +++ b/test/libsolidity/syntaxTests/dataLocations/transient_mapping_state_variable.sol @@ -1,7 +1,6 @@ contract C { mapping(uint => uint) transient y; } -// ==== -// stopAfter: analysis + // ---- // UnimplementedFeatureError 1834: Transient data location is only supported for value types. diff --git a/test/libsolidity/syntaxTests/dataLocations/transient_state_variable_visibility.sol b/test/libsolidity/syntaxTests/dataLocations/transient_state_variable_visibility.sol index 2579d5532fee..561d9f21dab6 100644 --- a/test/libsolidity/syntaxTests/dataLocations/transient_state_variable_visibility.sol +++ b/test/libsolidity/syntaxTests/dataLocations/transient_state_variable_visibility.sol @@ -7,6 +7,10 @@ contract C { uint transient internal ti; uint transient private tprv; } -// ==== -// stopAfter: parsing // ---- +// UnimplementedFeatureError 6715: (17-43): Transient storage is not yet implemented. +// UnimplementedFeatureError 6715: (49-75): Transient storage is not yet implemented. +// UnimplementedFeatureError 6715: (81-108): Transient storage is not yet implemented. +// UnimplementedFeatureError 6715: (115-141): Transient storage is not yet implemented. +// UnimplementedFeatureError 6715: (147-173): Transient storage is not yet implemented. +// UnimplementedFeatureError 6715: (179-206): Transient storage is not yet implemented. diff --git a/test/libsolidity/syntaxTests/dataLocations/transient_struct_state_variable.sol b/test/libsolidity/syntaxTests/dataLocations/transient_struct_state_variable.sol index 19612b9c5728..f89608be424c 100644 --- a/test/libsolidity/syntaxTests/dataLocations/transient_struct_state_variable.sol +++ b/test/libsolidity/syntaxTests/dataLocations/transient_struct_state_variable.sol @@ -6,7 +6,5 @@ struct S { contract C { S transient s; } -// ==== -// stopAfter: analysis // ---- // UnimplementedFeatureError 1834: Transient data location is only supported for value types. diff --git a/test/libsolidity/syntaxTests/dataLocations/transient_value_type_state_variables.sol b/test/libsolidity/syntaxTests/dataLocations/transient_value_type_state_variables.sol index 55faa1495d99..ce2db200bbac 100644 --- a/test/libsolidity/syntaxTests/dataLocations/transient_value_type_state_variables.sol +++ b/test/libsolidity/syntaxTests/dataLocations/transient_value_type_state_variables.sol @@ -7,6 +7,9 @@ contract C { uint transient x; bytes32 transient y; } -// ==== -// stopAfter: parsing // ---- +// UnimplementedFeatureError 6715: (30-49): Transient storage is not yet implemented. +// UnimplementedFeatureError 6715: (52-68): Transient storage is not yet implemented. +// UnimplementedFeatureError 6715: (71-84): Transient storage is not yet implemented. +// UnimplementedFeatureError 6715: (87-103): Transient storage is not yet implemented. +// UnimplementedFeatureError 6715: (106-125): Transient storage is not yet implemented. diff --git a/test/libsolidity/syntaxTests/dataLocations/transient_value_type_state_variables_assignment.sol b/test/libsolidity/syntaxTests/dataLocations/transient_value_type_state_variables_assignment.sol index 10dad9e32fe9..33b7bb28cb64 100644 --- a/test/libsolidity/syntaxTests/dataLocations/transient_value_type_state_variables_assignment.sol +++ b/test/libsolidity/syntaxTests/dataLocations/transient_value_type_state_variables_assignment.sol @@ -5,6 +5,7 @@ contract C { address transient a = address(0xABC); bool transient b = x > 0 ? false : true; } -// ==== -// stopAfter: parsing // ---- +// UnimplementedFeatureError 6715: (30-51): Transient storage is not yet implemented. +// UnimplementedFeatureError 6715: (54-90): Transient storage is not yet implemented. +// UnimplementedFeatureError 6715: (93-132): Transient storage is not yet implemented. From 0d01c93d96c6bed69b81f5fe784842125f9a887b Mon Sep 17 00:00:00 2001 From: Martin Blicha Date: Tue, 25 Jun 2024 16:28:45 +0200 Subject: [PATCH 0280/1022] SMTChecker: Fix formatting of unary minus expressions in invariants Previously, unary minus expressions actually ended up formatted as binary expressions in infix format, which meant that the unary minus operator actually disappeared. Additionally, SMTCheckerTest was actually always ignoring the invariant message, and we fix that as well. --- Changelog.md | 1 + libsolidity/formal/ExpressionFormatter.cpp | 4 +++- scripts/error_codes.py | 1 - test/libsolidity/SMTCheckerTest.cpp | 5 +++-- .../invariants/unary_minus_formatting.sol | 13 +++++++++++++ 5 files changed, 20 insertions(+), 4 deletions(-) create mode 100644 test/libsolidity/smtCheckerTests/invariants/unary_minus_formatting.sol diff --git a/Changelog.md b/Changelog.md index 698c7fb5d26c..442c4e34f3e8 100644 --- a/Changelog.md +++ b/Changelog.md @@ -14,6 +14,7 @@ Compiler Features: Bugfixes: * SMTChecker: Fix error that reports invalid number of verified checks for BMC and CHC engines. + * SMTChecker: Fix formatting of unary minus expressions in invariants. * SMTChecker: Fix internal compiler error when reporting proved targets for BMC engine. * TypeChecker: Fix segfault when assigning nested tuple to tuple. * Yul Optimizer: Name simplification could lead to forbidden identifiers with a leading and/or trailing dot, e.g., ``x._`` would get simplified into ``x.``. diff --git a/libsolidity/formal/ExpressionFormatter.cpp b/libsolidity/formal/ExpressionFormatter.cpp index cf2f2c3b8126..5a3d11dbefd4 100644 --- a/libsolidity/formal/ExpressionFormatter.cpp +++ b/libsolidity/formal/ExpressionFormatter.cpp @@ -115,6 +115,8 @@ std::string formatUnaryOp(smtutil::Expression const& _expr, std::vector= 2 arguments from z3. - if (infixOps.count(op)) + if (infixOps.count(op) && args.size() >= 2) return formatInfixOp(infixOps.at(op), strArgs); static std::set const arrayOps{"select", "store", "const_array"}; diff --git a/scripts/error_codes.py b/scripts/error_codes.py index 6171714bd7ca..fcb6f0e7f507 100755 --- a/scripts/error_codes.py +++ b/scripts/error_codes.py @@ -203,7 +203,6 @@ def examine_id_coverage(top_dir, source_id_to_file_names, new_ids_only=False): # Due to 3805, the warning lists look different for different compiler builds. "1920", # Unimplemented feature error from YulStack (currently there are no UnimplementedFeatureErrors thrown by libyul) "7053", # Unimplemented feature error (parsing stage), currently has no tests - "1180", # SMTChecker, covered by CL tests "2339", # SMTChecker, covered by CL tests "6240", # SMTChecker, covered by CL tests } diff --git a/test/libsolidity/SMTCheckerTest.cpp b/test/libsolidity/SMTCheckerTest.cpp index 8149f3130c5d..c25025ccf77c 100644 --- a/test/libsolidity/SMTCheckerTest.cpp +++ b/test/libsolidity/SMTCheckerTest.cpp @@ -107,8 +107,6 @@ SMTCheckerTest::SMTCheckerTest(std::string const& _filename): filtered.emplace_back(e); return filtered; }; - if (m_modelCheckerSettings.invariants.invariants.empty()) - m_expectations = removeInv(std::move(m_expectations)); auto const& ignoreInv = m_reader.stringSetting("SMTIgnoreInv", "yes"); if (ignoreInv == "no") @@ -118,6 +116,9 @@ SMTCheckerTest::SMTCheckerTest(std::string const& _filename): else BOOST_THROW_EXCEPTION(std::runtime_error("Invalid SMT invariant choice.")); + if (m_modelCheckerSettings.invariants.invariants.empty()) + m_expectations = removeInv(std::move(m_expectations)); + auto const& ignoreOSSetting = m_reader.stringSetting("SMTIgnoreOS", "none"); for (std::string const& os: ignoreOSSetting | ranges::views::split(',') | ranges::to>()) { diff --git a/test/libsolidity/smtCheckerTests/invariants/unary_minus_formatting.sol b/test/libsolidity/smtCheckerTests/invariants/unary_minus_formatting.sol new file mode 100644 index 000000000000..a41329901969 --- /dev/null +++ b/test/libsolidity/smtCheckerTests/invariants/unary_minus_formatting.sol @@ -0,0 +1,13 @@ +contract C { + int x = -1; + function i() public view { + assert(x == -1); + } +} +// ==== +// SMTEngine: chc +// SMTIgnoreInv: no +// SMTSolvers: eld +// ---- +// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. +// Info 1180: Contract invariant(s) for :C:\n(x = -1)\n From 477c413bd9a5ddfa21f3c421210e0bd0bdb8a513 Mon Sep 17 00:00:00 2001 From: clonker Date: Wed, 15 May 2024 17:29:39 +0200 Subject: [PATCH 0281/1022] yul literal value is struct of u256 + optional formatting hint or 'unlimited' - unlimited is a string literal for which bytes restrictions don't hold; can occur in builtin function arguments --- .../codegen/ir/IRGeneratorForStatements.cpp | 3 +- libsolutil/CommonData.cpp | 4 +- libsolutil/CommonData.h | 4 +- libyul/AST.cpp | 80 +++++++++ libyul/AST.h | 29 +++- libyul/ASTForward.h | 1 + libyul/AsmAnalysis.cpp | 40 +++-- libyul/AsmJsonConverter.cpp | 17 +- libyul/AsmJsonImporter.cpp | 24 +-- libyul/AsmParser.cpp | 20 ++- libyul/AsmParser.h | 4 +- libyul/AsmPrinter.cpp | 14 +- libyul/CMakeLists.txt | 1 + libyul/Dialect.cpp | 10 +- libyul/Dialect.h | 3 +- libyul/Utilities.cpp | 152 ++++++++++++++---- libyul/Utilities.h | 21 ++- libyul/backends/evm/ConstantOptimiser.cpp | 6 +- .../backends/evm/ControlFlowGraphBuilder.cpp | 6 +- libyul/backends/evm/EVMCodeTransform.cpp | 2 +- libyul/backends/evm/EVMDialect.cpp | 16 +- libyul/backends/evm/EVMMetrics.cpp | 2 +- .../evm/OptimizedEVMCodeTransform.cpp | 2 +- libyul/optimiser/BlockHasher.cpp | 28 ++-- libyul/optimiser/BlockHasher.h | 11 +- .../CommonSubexpressionEliminator.cpp | 2 +- libyul/optimiser/ConditionalUnsimplifier.cpp | 4 +- libyul/optimiser/DataFlowAnalyzer.cpp | 2 +- libyul/optimiser/DataFlowAnalyzer.h | 2 +- libyul/optimiser/ExpressionSimplifier.cpp | 4 +- libyul/optimiser/ForLoopConditionIntoBody.cpp | 2 +- .../optimiser/ForLoopConditionOutOfBody.cpp | 2 +- libyul/optimiser/KnowledgeBase.cpp | 4 +- libyul/optimiser/LoadResolver.cpp | 5 +- libyul/optimiser/Metrics.cpp | 8 +- libyul/optimiser/SSAValueTracker.h | 2 +- libyul/optimiser/SimplificationRules.cpp | 6 +- libyul/optimiser/StackLimitEvader.cpp | 4 +- libyul/optimiser/StackToMemoryMover.cpp | 34 ++-- libyul/optimiser/StackToMemoryMover.h | 6 +- libyul/optimiser/StructuralSimplifier.cpp | 6 +- libyul/optimiser/SyntacticalEquality.cpp | 12 +- libyul/optimiser/SyntacticalEquality.h | 3 + libyul/optimiser/UnusedStoreEliminator.cpp | 6 +- .../disambiguator/similar_literals.yul | 23 +++ .../string_as_hex_and_hex_as_string.yul | 13 ++ .../constant_representation.yul | 17 +- .../constant_representation_datasize.yul | 48 ++++++ .../yulSyntaxTests/switch_duplicate_case.yul | 2 +- ...witch_duplicate_case_different_literal.yul | 2 +- .../EVMInstructionInterpreter.cpp | 3 +- test/tools/yulInterpreter/Interpreter.cpp | 18 +-- 52 files changed, 535 insertions(+), 205 deletions(-) create mode 100644 libyul/AST.cpp create mode 100644 test/libyul/yulOptimizerTests/disambiguator/similar_literals.yul create mode 100644 test/libyul/yulOptimizerTests/disambiguator/string_as_hex_and_hex_as_string.yul create mode 100644 test/libyul/yulOptimizerTests/equivalentFunctionCombiner/constant_representation_datasize.yul diff --git a/libsolidity/codegen/ir/IRGeneratorForStatements.cpp b/libsolidity/codegen/ir/IRGeneratorForStatements.cpp index 2f823fcbf65c..1c212cd828c3 100644 --- a/libsolidity/codegen/ir/IRGeneratorForStatements.cpp +++ b/libsolidity/codegen/ir/IRGeneratorForStatements.cpp @@ -37,6 +37,7 @@ #include #include #include +#include #include #include @@ -203,7 +204,7 @@ struct CopyTranslate: public yul::ASTCopier solAssert(false); if (isDigit(value.front())) - return yul::Literal{_identifier.debugData, yul::LiteralKind::Number, yul::YulString{value}, {}}; + return yul::Literal{_identifier.debugData, yul::LiteralKind::Number, yul::valueOfNumberLiteral(value), {}}; else return yul::Identifier{_identifier.debugData, yul::YulString{value}}; } diff --git a/libsolutil/CommonData.cpp b/libsolutil/CommonData.cpp index 69f08308c2e8..7b86bae9f46f 100644 --- a/libsolutil/CommonData.cpp +++ b/libsolutil/CommonData.cpp @@ -161,7 +161,7 @@ std::string solidity::util::getChecksummedAddress(std::string const& _addr) return ret; } -bool solidity::util::isValidHex(std::string const& _string) +bool solidity::util::isValidHex(std::string_view const _string) { if (_string.substr(0, 2) != "0x") return false; @@ -170,7 +170,7 @@ bool solidity::util::isValidHex(std::string const& _string) return true; } -bool solidity::util::isValidDecimal(std::string const& _string) +bool solidity::util::isValidDecimal(std::string_view const _string) { if (_string.empty()) return false; diff --git a/libsolutil/CommonData.h b/libsolutil/CommonData.h index 6e17e674d6e2..c64b3913fc83 100644 --- a/libsolutil/CommonData.h +++ b/libsolutil/CommonData.h @@ -584,8 +584,8 @@ bool passesAddressChecksum(std::string const& _str, bool _strict); /// @param hex strings that look like an address std::string getChecksummedAddress(std::string const& _addr); -bool isValidHex(std::string const& _string); -bool isValidDecimal(std::string const& _string); +bool isValidHex(std::string_view _string); +bool isValidDecimal(std::string_view _string); /// @returns a quoted string if all characters are printable ASCII chars, /// or its hex representation otherwise. diff --git a/libyul/AST.cpp b/libyul/AST.cpp new file mode 100644 index 000000000000..8c9f376415f9 --- /dev/null +++ b/libyul/AST.cpp @@ -0,0 +1,80 @@ +/* +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 + +namespace solidity::yul +{ + +LiteralValue::LiteralValue(std::string _builtinStringLiteralValue): + m_numericValue(std::nullopt), + m_stringValue(std::make_shared(std::move(_builtinStringLiteralValue))) +{ } + +LiteralValue::LiteralValue(solidity::yul::LiteralValue::Data const& _data, std::optional const& _hint): + m_numericValue(_data), + m_stringValue(_hint ? std::make_shared(*_hint) : nullptr) +{ } + +LiteralValue::Data const& LiteralValue::value() const +{ + yulAssert(!unlimited()); + return *m_numericValue; +} + +LiteralValue::BuiltinStringLiteralData const& LiteralValue::builtinStringLiteralValue() const +{ + yulAssert(unlimited()); + return *m_stringValue; +} + +bool LiteralValue::unlimited() const +{ + return !m_numericValue.has_value(); +} + +LiteralValue::RepresentationHint const& LiteralValue::hint() const +{ + yulAssert(!unlimited()); + return m_stringValue; +} + +bool LiteralValue::operator==(LiteralValue const& _rhs) const +{ + if (unlimited() != _rhs.unlimited()) + return false; + + if (unlimited()) + return builtinStringLiteralValue() == _rhs.builtinStringLiteralValue(); + + return value() == _rhs.value(); +} + +bool LiteralValue::operator<(solidity::yul::LiteralValue const& _rhs) const +{ + if (unlimited() != _rhs.unlimited()) + return unlimited() < _rhs.unlimited(); + + if (unlimited()) + return builtinStringLiteralValue() < _rhs.builtinStringLiteralValue(); + + return value() < _rhs.value(); +} + +} diff --git a/libyul/AST.h b/libyul/AST.h index 4e3e92de3dad..ad60e468592a 100644 --- a/libyul/AST.h +++ b/libyul/AST.h @@ -28,6 +28,8 @@ #include +#include + #include #include @@ -41,7 +43,32 @@ using TypedNameList = std::vector; /// Literal number or string (up to 32 bytes) enum class LiteralKind { Number, Boolean, String }; -struct Literal { langutil::DebugData::ConstPtr debugData; LiteralKind kind; YulString value; Type type; }; +/// Literal value that holds a u256 word of data, can be of LiteralKind type and - in case of arguments to +/// builtins - exceed the u256 word (32 bytes), in which case the value is stored as string. The former is constructed +/// via u256 word and optional hint and leads to unlimited == false, the latter is +/// constructed via the string constructor and leads to unlimited == true. +class LiteralValue { +public: + using Data = u256; + using BuiltinStringLiteralData = std::string; + using RepresentationHint = std::shared_ptr; + + LiteralValue() = default; + explicit LiteralValue(std::string _builtinStringLiteralValue); + explicit LiteralValue(Data const& _data, std::optional const& _hint = std::nullopt); + + bool operator==(LiteralValue const& _rhs) const; + bool operator<(LiteralValue const& _rhs) const; + Data const& value() const; + BuiltinStringLiteralData const& builtinStringLiteralValue() const; + bool unlimited() const; + RepresentationHint const& hint() const; + +private: + std::optional m_numericValue; + std::shared_ptr m_stringValue; +}; +struct Literal { langutil::DebugData::ConstPtr debugData; LiteralKind kind; LiteralValue value; Type type; }; /// External / internal identifier or label reference struct Identifier { langutil::DebugData::ConstPtr debugData; YulString name; }; /// Assignment ("x := mload(20:u256)", expects push-1-expression on the right hand diff --git a/libyul/ASTForward.h b/libyul/ASTForward.h index a4dc5be3f8eb..12992edf8872 100644 --- a/libyul/ASTForward.h +++ b/libyul/ASTForward.h @@ -29,6 +29,7 @@ namespace solidity::yul { enum class LiteralKind; +class LiteralValue; struct Literal; struct Label; struct Identifier; diff --git a/libyul/AsmAnalysis.cpp b/libyul/AsmAnalysis.cpp index f85ef95442bd..ac97f988d47d 100644 --- a/libyul/AsmAnalysis.cpp +++ b/libyul/AsmAnalysis.cpp @@ -41,7 +41,6 @@ #include -#include #include using namespace std::string_literals; @@ -104,24 +103,32 @@ AsmAnalysisInfo AsmAnalyzer::analyzeStrictAssertCorrect(Dialect const& _dialect, std::vector AsmAnalyzer::operator()(Literal const& _literal) { expectValidType(_literal.type, nativeLocationOf(_literal)); - if (_literal.kind == LiteralKind::String && _literal.value.str().size() > 32) + bool erroneousLiteralValue = false; + if (_literal.kind == LiteralKind::String && !_literal.value.unlimited() && _literal.value.hint() && _literal.value.hint()->size() > 32) + { + erroneousLiteralValue = true; m_errorReporter.typeError( 3069_error, nativeLocationOf(_literal), - "String literal too long (" + std::to_string(_literal.value.str().size()) + " > 32)" + "String literal too long (" + std::to_string(formatLiteral(_literal, false /* _validated */ ).size()) + " > 32)" ); - else if (_literal.kind == LiteralKind::Number && bigint(_literal.value.str()) > u256(-1)) + } + else if (_literal.kind == LiteralKind::Number && _literal.value.hint() && bigint(*_literal.value.hint()) > u256(-1)) + { + erroneousLiteralValue = true; m_errorReporter.typeError(6708_error, nativeLocationOf(_literal), "Number literal too large (> 256 bits)"); - else if (_literal.kind == LiteralKind::Boolean) - yulAssert(_literal.value == "true"_yulstring || _literal.value == "false"_yulstring, ""); + } if (!m_dialect.validTypeForLiteral(_literal.kind, _literal.value, _literal.type)) + { m_errorReporter.typeError( 5170_error, nativeLocationOf(_literal), - "Invalid type \"" + _literal.type.str() + "\" for literal \"" + _literal.value.str() + "\"." + "Invalid type \"" + _literal.type.str() + "\" for literal \"" + formatLiteral(_literal) + "\"." ); + } + yulAssert(erroneousLiteralValue ^ validLiteral(_literal), "Invalid literal after validating it through AsmAnalyzer."); return {_literal.type}; } @@ -420,23 +427,25 @@ std::vector AsmAnalyzer::operator()(FunctionCall const& _funCall) std::string functionName = _funCall.functionName.name.str(); if (functionName == "datasize" || functionName == "dataoffset") { - if (!m_dataNames.count(std::get(arg).value)) + auto const& argumentAsLiteral = std::get(arg); + if (!m_dataNames.count(YulString(formatLiteral(argumentAsLiteral)))) m_errorReporter.typeError( 3517_error, nativeLocationOf(arg), - "Unknown data object \"" + std::get(arg).value.str() + "\"." + "Unknown data object \"" + formatLiteral(argumentAsLiteral) + "\"." ); } else if (functionName.substr(0, "verbatim_"s.size()) == "verbatim_") { - if (std::get(arg).value.empty()) + auto const& literalValue = std::get(arg).value; + yulAssert(literalValue.unlimited()); // verbatim literals are always unlimited + if (literalValue.builtinStringLiteralValue().empty()) m_errorReporter.typeError( 1844_error, nativeLocationOf(arg), "The \"verbatim_*\" builtins cannot be used with empty bytecode." ); } - argTypes.emplace_back(expectUnlimitedStringLiteral(std::get(arg))); continue; } @@ -495,12 +504,12 @@ void AsmAnalyzer::operator()(Switch const& _switch) (*this)(*_case.value); /// Note: the parser ensures there is only one default case - if (watcher.ok() && !cases.insert(valueOfLiteral(*_case.value)).second) + if (watcher.ok() && !cases.insert(_case.value->value.value()).second) m_errorReporter.declarationError( 6792_error, nativeLocationOf(_case), "Duplicate case \"" + - valueOfLiteral(*_case.value).str() + + formatLiteral(*_case.value) + "\" defined." ); } @@ -560,8 +569,9 @@ YulString AsmAnalyzer::expectExpression(Expression const& _expr) YulString AsmAnalyzer::expectUnlimitedStringLiteral(Literal const& _literal) { - yulAssert(_literal.kind == LiteralKind::String, ""); - yulAssert(m_dialect.validTypeForLiteral(LiteralKind::String, _literal.value, _literal.type), ""); + yulAssert(_literal.kind == LiteralKind::String); + yulAssert(m_dialect.validTypeForLiteral(LiteralKind::String, _literal.value, _literal.type)); + yulAssert(_literal.value.unlimited()); return {_literal.type}; } diff --git a/libyul/AsmJsonConverter.cpp b/libyul/AsmJsonConverter.cpp index a89e4967aa4e..60475497542a 100644 --- a/libyul/AsmJsonConverter.cpp +++ b/libyul/AsmJsonConverter.cpp @@ -20,9 +20,10 @@ * Converts inline assembly AST to JSON format */ -#include #include +#include #include +#include #include #include @@ -47,14 +48,11 @@ Json AsmJsonConverter::operator()(TypedName const& _node) const Json AsmJsonConverter::operator()(Literal const& _node) const { + yulAssert(validLiteral(_node)); Json ret = createAstNode(originLocationOf(_node), nativeLocationOf(_node), "YulLiteral"); switch (_node.kind) { case LiteralKind::Number: - yulAssert( - util::isValidDecimal(_node.value.str()) || util::isValidHex(_node.value.str()), - "Invalid number literal" - ); ret["kind"] = "number"; break; case LiteralKind::Boolean: @@ -62,12 +60,15 @@ Json AsmJsonConverter::operator()(Literal const& _node) const break; case LiteralKind::String: ret["kind"] = "string"; - ret["hexValue"] = util::toHex(util::asBytes(_node.value.str())); + ret["hexValue"] = util::toHex(util::asBytes(formatLiteral(_node))); break; } ret["type"] = _node.type.str(); - if (util::validateUTF8(_node.value.str())) - ret["value"] = _node.value.str(); + { + auto const formattedLiteral = formatLiteral(_node); + if (util::validateUTF8(formattedLiteral)) + ret["value"] = formattedLiteral; + } return ret; } diff --git a/libyul/AsmJsonImporter.cpp b/libyul/AsmJsonImporter.cpp index 41e065853517..63b1d65d26ec 100644 --- a/libyul/AsmJsonImporter.cpp +++ b/libyul/AsmJsonImporter.cpp @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -165,26 +166,25 @@ Literal AsmJsonImporter::createLiteral(Json const& _node) std::string kind = member(_node, "kind").get(); solAssert(member(_node, "hexValue").is_string() || member(_node, "value").is_string(), ""); + std::string value; if (_node.contains("hexValue")) - lit.value = YulString{util::asString(util::fromHex(member(_node, "hexValue").get()))}; + value = util::asString(util::fromHex(member(_node, "hexValue").get())); else - lit.value = YulString{member(_node, "value").get()}; - - lit.type= YulString{member(_node, "type").get()}; - + value = member(_node, "value").get(); + lit.type = YulString{member(_node, "type").get()}; if (kind == "number") { - langutil::CharStream charStream(lit.value.str(), ""); + langutil::CharStream charStream(value, ""); langutil::Scanner scanner{charStream}; lit.kind = LiteralKind::Number; yulAssert( scanner.currentToken() == Token::Number, - "Expected number but got " + langutil::TokenTraits::friendlyName(scanner.currentToken()) + std::string(" while scanning ") + lit.value.str() + "Expected number but got " + langutil::TokenTraits::friendlyName(scanner.currentToken()) + std::string(" while scanning ") + value ); } else if (kind == "bool") { - langutil::CharStream charStream(lit.value.str(), ""); + langutil::CharStream charStream(value, ""); langutil::Scanner scanner{charStream}; lit.kind = LiteralKind::Boolean; yulAssert( @@ -197,13 +197,17 @@ Literal AsmJsonImporter::createLiteral(Json const& _node) { lit.kind = LiteralKind::String; yulAssert( - lit.value.str().size() <= 32, - "String literal too long (" + std::to_string(lit.value.str().size()) + " > 32)" + value.size() <= 32, + "String literal too long (" + std::to_string(value.size()) + " > 32)" ); } else yulAssert(false, "unknown type of literal"); + // import only for inline assembly, no unlimited string literals there + lit.value = valueOfLiteral(value, lit.kind, false /* _unlimitedLiteralArgument */); + + yulAssert(validLiteral(lit)); return lit; } diff --git a/libyul/AsmParser.cpp b/libyul/AsmParser.cpp index a009b005d6bd..ecf3475a8a3b 100644 --- a/libyul/AsmParser.cpp +++ b/libyul/AsmParser.cpp @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -470,11 +471,11 @@ ForLoop Parser::parseForLoop() return forLoop; } -Expression Parser::parseExpression() +Expression Parser::parseExpression(bool _unlimitedLiteralArgument) { RecursionGuard recursionGuard(*this); - std::variant operation = parseLiteralOrIdentifier(); + std::variant operation = parseLiteralOrIdentifier(_unlimitedLiteralArgument); return visit(GenericVisitor{ [&](Identifier& _identifier) -> Expression { @@ -495,7 +496,7 @@ Expression Parser::parseExpression() }, operation); } -std::variant Parser::parseLiteralOrIdentifier() +std::variant Parser::parseLiteralOrIdentifier(bool _unlimitedLiteralArgument) { RecursionGuard recursionGuard(*this); switch (currentToken()) @@ -535,7 +536,7 @@ std::variant Parser::parseLiteralOrIdentifier() Literal literal{ createDebugData(), kind, - YulString{currentLiteral()}, + valueOfLiteral(currentLiteral(), kind, _unlimitedLiteralArgument && kind == LiteralKind::String), kind == LiteralKind::Boolean ? m_dialect.boolType : m_dialect.defaultType }; advance(); @@ -639,15 +640,20 @@ FunctionCall Parser::parseCall(std::variant&& _initialOp) FunctionCall ret; ret.functionName = std::move(std::get(_initialOp)); ret.debugData = ret.functionName.debugData; - + auto const isUnlimitedLiteralArgument = [f=m_dialect.builtin(ret.functionName.name)](size_t const index) { + if (f && index < f->literalArguments.size()) + return f->literalArgument(index).has_value(); + return false; + }; + size_t argumentIndex {0}; expectToken(Token::LParen); if (currentToken() != Token::RParen) { - ret.arguments.emplace_back(parseExpression()); + ret.arguments.emplace_back(parseExpression(isUnlimitedLiteralArgument(argumentIndex++))); while (currentToken() != Token::RParen) { expectToken(Token::Comma); - ret.arguments.emplace_back(parseExpression()); + ret.arguments.emplace_back(parseExpression(isUnlimitedLiteralArgument(argumentIndex++))); } } updateLocationEndFrom(ret.debugData, currentLocation()); diff --git a/libyul/AsmParser.h b/libyul/AsmParser.h index dd91e436e234..3348904091f2 100644 --- a/libyul/AsmParser.h +++ b/libyul/AsmParser.h @@ -138,10 +138,10 @@ class Parser: public langutil::ParserBase Case parseCase(); ForLoop parseForLoop(); /// Parses a functional expression that has to push exactly one stack element - Expression parseExpression(); + Expression parseExpression(bool _unlimitedLiteralArgument = false); /// Parses an elementary operation, i.e. a literal, identifier, instruction or /// builtin function call (only the name). - std::variant parseLiteralOrIdentifier(); + std::variant parseLiteralOrIdentifier(bool _unlimitedLiteralArgument = false); VariableDeclaration parseVariableDeclaration(); FunctionDefinition parseFunctionDefinition(); FunctionCall parseCall(std::variant&& _initialOp); diff --git a/libyul/AsmPrinter.cpp b/libyul/AsmPrinter.cpp index b27af037131b..191fc5d2d6a1 100644 --- a/libyul/AsmPrinter.cpp +++ b/libyul/AsmPrinter.cpp @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -34,8 +35,8 @@ #include -#include #include +#include using namespace solidity; using namespace solidity::langutil; @@ -44,21 +45,22 @@ using namespace solidity::yul; std::string AsmPrinter::operator()(Literal const& _literal) { + yulAssert(validLiteral(_literal)); + std::string const locationComment = formatDebugData(_literal); + std::string const formattedValue = formatLiteral(_literal); switch (_literal.kind) { case LiteralKind::Number: - yulAssert(isValidDecimal(_literal.value.str()) || isValidHex(_literal.value.str()), "Invalid number literal"); - return locationComment + _literal.value.str() + appendTypeName(_literal.type); + return locationComment + formattedValue + appendTypeName(_literal.type); case LiteralKind::Boolean: - yulAssert(_literal.value == "true"_yulstring || _literal.value == "false"_yulstring, "Invalid bool literal."); - return locationComment + ((_literal.value == "true"_yulstring) ? "true" : "false") + appendTypeName(_literal.type, true); + return locationComment + formattedValue + appendTypeName(_literal.type, true); case LiteralKind::String: break; } - return locationComment + escapeAndQuoteString(_literal.value.str()) + appendTypeName(_literal.type); + return locationComment + escapeAndQuoteString(formattedValue) + appendTypeName(_literal.type); } std::string AsmPrinter::operator()(Identifier const& _identifier) diff --git a/libyul/CMakeLists.txt b/libyul/CMakeLists.txt index 811a6239b7f0..92b03facfe93 100644 --- a/libyul/CMakeLists.txt +++ b/libyul/CMakeLists.txt @@ -5,6 +5,7 @@ add_library(yul AsmAnalysis.h AsmAnalysisInfo.h AST.h + AST.cpp ASTForward.h AsmJsonConverter.h AsmJsonConverter.cpp diff --git a/libyul/Dialect.cpp b/libyul/Dialect.cpp index 8440698f1336..69ca1e9dc68d 100644 --- a/libyul/Dialect.cpp +++ b/libyul/Dialect.cpp @@ -28,20 +28,20 @@ using namespace solidity::langutil; Literal Dialect::zeroLiteralForType(solidity::yul::YulString _type) const { if (_type == boolType && _type != defaultType) - return {DebugData::create(), LiteralKind::Boolean, "false"_yulstring, _type}; - return {DebugData::create(), LiteralKind::Number, "0"_yulstring, _type}; + return {DebugData::create(), LiteralKind::Boolean, LiteralValue(false), _type}; + return {DebugData::create(), LiteralKind::Number, LiteralValue(0, std::nullopt), _type}; } Literal Dialect::trueLiteral() const { if (boolType != defaultType) - return {DebugData::create(), LiteralKind::Boolean, "true"_yulstring, boolType}; + return {DebugData::create(), LiteralKind::Boolean, LiteralValue(true), boolType}; else - return {DebugData::create(), LiteralKind::Number, "1"_yulstring, defaultType}; + return {DebugData::create(), LiteralKind::Number, LiteralValue(1), defaultType}; } -bool Dialect::validTypeForLiteral(LiteralKind _kind, YulString, YulString _type) const +bool Dialect::validTypeForLiteral(LiteralKind _kind, LiteralValue const&, YulString _type) const { if (_kind == LiteralKind::Boolean) return _type == boolType; diff --git a/libyul/Dialect.h b/libyul/Dialect.h index e7a5e4827334..e3f270357f91 100644 --- a/libyul/Dialect.h +++ b/libyul/Dialect.h @@ -35,6 +35,7 @@ namespace solidity::yul class YulString; using Type = YulString; enum class LiteralKind; +class LiteralValue; struct Literal; struct BuiltinFunction @@ -85,7 +86,7 @@ struct Dialect /// Check whether the given type is legal for the given literal value. /// Should only be called if the type exists in the dialect at all. - virtual bool validTypeForLiteral(LiteralKind _kind, YulString _value, YulString _type) const; + virtual bool validTypeForLiteral(LiteralKind _kind, LiteralValue const& _value, YulString _type) const; virtual Literal zeroLiteralForType(YulString _type) const; virtual Literal trueLiteral() const; diff --git a/libyul/Utilities.cpp b/libyul/Utilities.cpp index 8242553d3709..6a78441cba2a 100644 --- a/libyul/Utilities.cpp +++ b/libyul/Utilities.cpp @@ -86,56 +86,134 @@ std::string solidity::yul::reindent(std::string const& _code) return out.str(); } -u256 solidity::yul::valueOfNumberLiteral(Literal const& _literal) +LiteralValue solidity::yul::valueOfNumberLiteral(std::string_view const _literal) { - yulAssert(_literal.kind == LiteralKind::Number, "Expected number literal!"); + return LiteralValue{LiteralValue::Data(_literal), std::string(_literal)}; +} + +LiteralValue solidity::yul::valueOfStringLiteral(std::string_view const _literal) +{ + std::string const s(_literal); + return LiteralValue{u256(h256(s, h256::FromBinary, h256::AlignLeft)), s}; +} + +LiteralValue solidity::yul::valueOfBuiltinStringLiteralArgument(std::string_view _literal) +{ + return LiteralValue{std::string(_literal)}; +} - static std::map numberCache; - static YulStringRepository::ResetCallback callback{[&] { numberCache.clear(); }}; +LiteralValue solidity::yul::valueOfBoolLiteral(std::string_view const _literal) +{ + if (_literal == "true") + return LiteralValue{true}; + else if (_literal == "false") + return LiteralValue{false}; + + yulAssert(false, "Unexpected bool literal value!"); +} - auto&& [it, isNew] = numberCache.try_emplace(_literal.value, 0); - if (isNew) +LiteralValue solidity::yul::valueOfLiteral(std::string_view const _literal, LiteralKind const& _kind, bool const _unlimitedLiteralArgument) +{ + switch (_kind) { - std::string const& literalString = _literal.value.str(); - yulAssert(isValidDecimal(literalString) || isValidHex(literalString), "Invalid number literal!"); - it->second = u256(literalString); + case LiteralKind::Number: + return valueOfNumberLiteral(_literal); + case LiteralKind::Boolean: + return valueOfBoolLiteral(_literal); + case LiteralKind::String: + return _unlimitedLiteralArgument ? valueOfBuiltinStringLiteralArgument(_literal) : valueOfStringLiteral(_literal); } - return it->second; + util::unreachable(); } -u256 solidity::yul::valueOfStringLiteral(Literal const& _literal) +std::string solidity::yul::formatLiteral(solidity::yul::Literal const& _literal, bool const _validated) { - yulAssert(_literal.kind == LiteralKind::String, "Expected string literal!"); - yulAssert(_literal.value.str().size() <= 32, "Literal string too long!"); + if (_validated) + yulAssert(validLiteral(_literal), "Encountered invalid literal in formatLiteral."); + + if (_literal.value.unlimited()) + return _literal.value.builtinStringLiteralValue(); + + if (_literal.value.hint()) + return *_literal.value.hint(); + + if (_literal.kind == LiteralKind::Boolean) + return _literal.value.value() == false ? "false" : "true"; - return u256(h256(_literal.value.str(), h256::FromBinary, h256::AlignLeft)); + // if there is no hint and it is not a boolean, just stringify the u256 word + return _literal.value.value().str(); } -u256 yul::valueOfBoolLiteral(Literal const& _literal) +bool solidity::yul::validLiteral(solidity::yul::Literal const& _literal) { - yulAssert(_literal.kind == LiteralKind::Boolean, "Expected bool literal!"); + switch (_literal.kind) + { + case LiteralKind::Number: + return validNumberLiteral(_literal); + case LiteralKind::Boolean: + return validBoolLiteral(_literal); + case LiteralKind::String: + return validStringLiteral(_literal); + } + util::unreachable(); +} - if (_literal.value == "true"_yulstring) - return u256(1); - else if (_literal.value == "false"_yulstring) - return u256(0); +bool solidity::yul::validStringLiteral(solidity::yul::Literal const& _literal) +{ + if (_literal.kind != LiteralKind::String) + return false; - yulAssert(false, "Unexpected bool literal value!"); + if (_literal.value.unlimited()) + return true; + + if (_literal.value.hint()) + return _literal.value.hint()->size() <= 32 && _literal.value.value() == valueOfLiteral(*_literal.value.hint(), _literal.kind).value(); + + return true; } -u256 solidity::yul::valueOfLiteral(Literal const& _literal) +bool solidity::yul::validNumberLiteral(solidity::yul::Literal const& _literal) { - switch (_literal.kind) + if (_literal.kind != LiteralKind::Number || _literal.value.unlimited()) + return false; + + if (!_literal.value.hint()) + return true; + + auto const& repr = *_literal.value.hint(); + + if (!isValidDecimal(repr) && !isValidHex(repr)) + return false; + + if (bigint(repr) > u256(-1)) + return false; + + if (_literal.value.value() != valueOfLiteral(repr, _literal.kind).value()) + return false; + + return true; +} + +bool solidity::yul::validBoolLiteral(solidity::yul::Literal const& _literal) +{ + if (_literal.kind != LiteralKind::Boolean || _literal.value.unlimited()) + return false; + + if (_literal.value.hint() && !(*_literal.value.hint() == "true" || *_literal.value.hint() == "false")) + return false; + + yulAssert(u256(0) == u256(false)); + yulAssert(u256(1) == u256(true)); + + if (_literal.value.hint()) { - case LiteralKind::Number: - return valueOfNumberLiteral(_literal); - case LiteralKind::Boolean: - return valueOfBoolLiteral(_literal); - case LiteralKind::String: - return valueOfStringLiteral(_literal); - default: - yulAssert(false, "Unexpected literal kind!"); + if (*_literal.value.hint() == "false") + return _literal.value.value() == false; + else + return _literal.value.value() == true; } + + return _literal.value.value() == true || _literal.value.value() == false; } template<> @@ -144,10 +222,14 @@ bool Less::operator()(Literal const& _lhs, Literal const& _rhs) const if (std::make_tuple(_lhs.kind, _lhs.type) != std::make_tuple(_rhs.kind, _rhs.type)) return std::make_tuple(_lhs.kind, _lhs.type) < std::make_tuple(_rhs.kind, _rhs.type); - if (_lhs.kind == LiteralKind::Number) - return valueOfNumberLiteral(_lhs) < valueOfNumberLiteral(_rhs); - else - return _lhs.value < _rhs.value; + if (_lhs.value.unlimited() && _rhs.value.unlimited()) + yulAssert( + _lhs.kind == LiteralKind::String && _rhs.kind == LiteralKind::String, + "Cannot have unlimited value that is not of String kind." + ); + + return _lhs.value < _rhs.value; + } bool SwitchCaseCompareByLiteralValue::operator()(Case const* _lhs, Case const* _rhs) const diff --git a/libyul/Utilities.h b/libyul/Utilities.h index e4d496cd4eba..434c5e9c5a3a 100644 --- a/libyul/Utilities.h +++ b/libyul/Utilities.h @@ -25,15 +25,28 @@ #include #include +#include + namespace solidity::yul { std::string reindent(std::string const& _code); -u256 valueOfNumberLiteral(Literal const& _literal); -u256 valueOfStringLiteral(Literal const& _literal); -u256 valueOfBoolLiteral(Literal const& _literal); -u256 valueOfLiteral(Literal const& _literal); +LiteralValue valueOfNumberLiteral(std::string_view _literal); +LiteralValue valueOfStringLiteral(std::string_view _literal); +LiteralValue valueOfBuiltinStringLiteralArgument(std::string_view _literal); +LiteralValue valueOfBoolLiteral(std::string_view _literal); +LiteralValue valueOfLiteral(std::string_view _literal, LiteralKind const& _kind, bool _unlimitedLiteralArgument = false); +bool validLiteral(Literal const& _literal); +bool validStringLiteral(Literal const& _literal); +bool validNumberLiteral(Literal const& _literal); +bool validBoolLiteral(Literal const& _literal); + +/// Produces a string representation of a Literal instance. +/// @param _literal the Literal to be formatted +/// @param _validated whether the Literal was already validated, i.e., assumptions are asserted in the method +/// @returns the literal's string representation +std::string formatLiteral(Literal const& _literal, bool _validated = true); /** * Linear order on Yul AST nodes. diff --git a/libyul/backends/evm/ConstantOptimiser.cpp b/libyul/backends/evm/ConstantOptimiser.cpp index c5a33e52f452..7b17f7d89012 100644 --- a/libyul/backends/evm/ConstantOptimiser.cpp +++ b/libyul/backends/evm/ConstantOptimiser.cpp @@ -81,7 +81,7 @@ struct MiniEVMInterpreter } u256 operator()(Literal const& _literal) { - return valueOfLiteral(_literal); + return _literal.value.value(); } u256 operator()(Identifier const&) { yulAssert(false, ""); } @@ -100,7 +100,7 @@ void ConstantOptimiser::visit(Expression& _e) if ( Expression const* repr = RepresentationFinder(m_dialect, m_meter, debugDataOf(_e), m_cache) - .tryFindRepresentation(valueOfLiteral(literal)) + .tryFindRepresentation(literal.value.value()) ) _e = ASTCopier{}.translate(*repr); } @@ -179,7 +179,7 @@ Representation const& RepresentationFinder::findRepresentation(u256 const& _valu Representation RepresentationFinder::represent(u256 const& _value) const { Representation repr; - repr.expression = std::make_unique(Literal{m_debugData, LiteralKind::Number, YulString{formatNumber(_value)}, {}}); + repr.expression = std::make_unique(Literal{m_debugData, LiteralKind::Number, LiteralValue{_value, formatNumber(_value)}, {}}); repr.cost = m_meter.costs(*repr.expression); return repr; } diff --git a/libyul/backends/evm/ControlFlowGraphBuilder.cpp b/libyul/backends/evm/ControlFlowGraphBuilder.cpp index f048e5717e10..a5e9613b5887 100644 --- a/libyul/backends/evm/ControlFlowGraphBuilder.cpp +++ b/libyul/backends/evm/ControlFlowGraphBuilder.cpp @@ -245,7 +245,7 @@ ControlFlowGraphBuilder::ControlFlowGraphBuilder( StackSlot ControlFlowGraphBuilder::operator()(Literal const& _literal) { - return LiteralSlot{valueOfLiteral(_literal), _literal.debugData}; + return LiteralSlot{_literal.value.value(), _literal.debugData}; } StackSlot ControlFlowGraphBuilder::operator()(Identifier const& _identifier) @@ -361,7 +361,7 @@ void ControlFlowGraphBuilder::operator()(Switch const& _switch) {*_case.value, Identifier{{}, ghostVariableName}} }); CFG::Operation& operation = m_currentBlock->operations.emplace_back(CFG::Operation{ - Stack{ghostVarSlot, LiteralSlot{valueOfLiteral(*_case.value), debugDataOf(*_case.value)}}, + Stack{ghostVarSlot, LiteralSlot{_case.value->value.value(), debugDataOf(*_case.value)}}, Stack{TemporarySlot{ghostCall, 0}}, CFG::BuiltinCall{debugDataOf(_case), *equalityBuiltin, ghostCall, 2}, }); @@ -399,7 +399,7 @@ void ControlFlowGraphBuilder::operator()(ForLoop const& _loop) std::optional constantCondition; if (auto const* literalCondition = std::get_if(_loop.condition.get())) - constantCondition = valueOfLiteral(*literalCondition) != 0; + constantCondition = literalCondition->value.value() != 0; CFG::BasicBlock& loopCondition = m_graph.makeBlock(debugDataOf(*_loop.condition)); CFG::BasicBlock& loopBody = m_graph.makeBlock(debugDataOf(_loop.body)); diff --git a/libyul/backends/evm/EVMCodeTransform.cpp b/libyul/backends/evm/EVMCodeTransform.cpp index 50e48f7681f7..bdce395ef89f 100644 --- a/libyul/backends/evm/EVMCodeTransform.cpp +++ b/libyul/backends/evm/EVMCodeTransform.cpp @@ -297,7 +297,7 @@ void CodeTransform::operator()(Identifier const& _identifier) void CodeTransform::operator()(Literal const& _literal) { m_assembly.setSourceLocation(originLocationOf(_literal)); - m_assembly.appendConstant(valueOfLiteral(_literal)); + m_assembly.appendConstant(_literal.value.value()); } void CodeTransform::operator()(If const& _if) diff --git a/libyul/backends/evm/EVMDialect.cpp b/libyul/backends/evm/EVMDialect.cpp index 6a3b34f97707..856689c91ad4 100644 --- a/libyul/backends/evm/EVMDialect.cpp +++ b/libyul/backends/evm/EVMDialect.cpp @@ -219,7 +219,7 @@ std::map createBuiltins(langutil::EVMVersion _ ) { yulAssert(_call.arguments.size() == 1, ""); Expression const& arg = _call.arguments.front(); - _assembly.appendLinkerSymbol(std::get(arg).value.str()); + _assembly.appendLinkerSymbol(formatLiteral(std::get(arg))); })); builtins.emplace(createFunction( @@ -236,7 +236,7 @@ std::map createBuiltins(langutil::EVMVersion _ yulAssert(_call.arguments.size() == 1, ""); Literal const* literal = std::get_if(&_call.arguments.front()); yulAssert(literal, ""); - _assembly.appendConstant(valueOfLiteral(*literal)); + _assembly.appendConstant(literal->value.value()); }) ); @@ -248,7 +248,7 @@ std::map createBuiltins(langutil::EVMVersion _ yulAssert(_context.currentObject, "No object available."); yulAssert(_call.arguments.size() == 1, ""); Expression const& arg = _call.arguments.front(); - YulString dataName = std::get(arg).value; + YulString const dataName (formatLiteral(std::get(arg))); if (_context.currentObject->name == dataName) _assembly.appendAssemblySize(); else @@ -269,7 +269,7 @@ std::map createBuiltins(langutil::EVMVersion _ yulAssert(_context.currentObject, "No object available."); yulAssert(_call.arguments.size() == 1, ""); Expression const& arg = _call.arguments.front(); - YulString dataName = std::get(arg).value; + YulString const dataName (formatLiteral(std::get(arg))); if (_context.currentObject->name == dataName) _assembly.appendConstant(0); else @@ -328,8 +328,8 @@ std::map createBuiltins(langutil::EVMVersion _ BuiltinContext& ) { yulAssert(_call.arguments.size() == 3, ""); - YulString identifier = std::get(_call.arguments[1]).value; - _assembly.appendImmutableAssignment(identifier.str()); + auto const identifier = (formatLiteral(std::get(_call.arguments[1]))); + _assembly.appendImmutableAssignment(identifier); } )); builtins.emplace(createFunction( @@ -344,7 +344,7 @@ std::map createBuiltins(langutil::EVMVersion _ BuiltinContext& ) { yulAssert(_call.arguments.size() == 1, ""); - _assembly.appendImmutable(std::get(_call.arguments.front()).value.str()); + _assembly.appendImmutable(formatLiteral(std::get(_call.arguments.front()))); } )); } @@ -450,7 +450,7 @@ BuiltinFunctionForEVM const* EVMDialect::verbatimFunction(size_t _arguments, siz Expression const& bytecode = _call.arguments.front(); _assembly.appendVerbatim( - asBytes(std::get(bytecode).value.str()), + asBytes(formatLiteral(std::get(bytecode))), _arguments, _returnVariables ); diff --git a/libyul/backends/evm/EVMMetrics.cpp b/libyul/backends/evm/EVMMetrics.cpp index 09c6abdd14d4..84ebdab1d2be 100644 --- a/libyul/backends/evm/EVMMetrics.cpp +++ b/libyul/backends/evm/EVMMetrics.cpp @@ -91,7 +91,7 @@ void GasMeterVisitor::operator()(Literal const& _lit) m_dataGas += singleByteDataGas() + evmasm::GasMeter::dataGas( - toCompactBigEndian(valueOfLiteral(_lit), 1), + toCompactBigEndian(_lit.value.value(), 1), m_isCreation, m_dialect.evmVersion() ); diff --git a/libyul/backends/evm/OptimizedEVMCodeTransform.cpp b/libyul/backends/evm/OptimizedEVMCodeTransform.cpp index a3052a542f64..047014e3dc43 100644 --- a/libyul/backends/evm/OptimizedEVMCodeTransform.cpp +++ b/libyul/backends/evm/OptimizedEVMCodeTransform.cpp @@ -224,7 +224,7 @@ void OptimizedEVMCodeTransform::validateSlot(StackSlot const& _slot, Expression std::visit(util::GenericVisitor{ [&](yul::Literal const& _literal) { auto* literalSlot = std::get_if(&_slot); - yulAssert(literalSlot && valueOfLiteral(_literal) == literalSlot->value, ""); + yulAssert(literalSlot && _literal.value.value() == literalSlot->value, ""); }, [&](yul::Identifier const& _identifier) { auto* variableSlot = std::get_if(&_slot); diff --git a/libyul/optimiser/BlockHasher.cpp b/libyul/optimiser/BlockHasher.cpp index 380cc15fb399..d5febca932c1 100644 --- a/libyul/optimiser/BlockHasher.cpp +++ b/libyul/optimiser/BlockHasher.cpp @@ -41,6 +41,18 @@ static constexpr uint64_t compileTimeLiteralHash(char const (&_literal)[N]) } } +void ASTHasherBase::hashLiteral(solidity::yul::Literal const& _literal) +{ + hash64(compileTimeLiteralHash("Literal")); + if (!_literal.value.unlimited()) + hash64(std::hash{}(_literal.value.value())); + else + hash64(std::hash{}(_literal.value.builtinStringLiteralValue())); + hash64(_literal.type.hash()); + hash8(static_cast(_literal.kind)); + hash8(_literal.value.unlimited()); +} + std::map BlockHasher::run(Block const& _block) { std::map result; @@ -51,13 +63,7 @@ std::map BlockHasher::run(Block const& _block) void BlockHasher::operator()(Literal const& _literal) { - hash64(compileTimeLiteralHash("Literal")); - if (_literal.kind == LiteralKind::Number) - hash64(std::hash{}(valueOfNumberLiteral(_literal))); - else - hash64(_literal.value.hash()); - hash64(_literal.type.hash()); - hash8(static_cast(_literal.kind)); + hashLiteral(_literal); } void BlockHasher::operator()(Identifier const& _identifier) @@ -203,13 +209,7 @@ uint64_t ExpressionHasher::run(Expression const& _e) void ExpressionHasher::operator()(Literal const& _literal) { - hash64(compileTimeLiteralHash("Literal")); - if (_literal.kind == LiteralKind::Number) - hash64(std::hash{}(valueOfNumberLiteral(_literal))); - else - hash64(_literal.value.hash()); - hash64(_literal.type.hash()); - hash8(static_cast(_literal.kind)); + hashLiteral(_literal); } void ExpressionHasher::operator()(Identifier const& _identifier) diff --git a/libyul/optimiser/BlockHasher.h b/libyul/optimiser/BlockHasher.h index 6dc55371cc8a..2b9a71f101ac 100644 --- a/libyul/optimiser/BlockHasher.h +++ b/libyul/optimiser/BlockHasher.h @@ -55,10 +55,15 @@ class HasherBase hash32(static_cast(_value >> 32)); } - uint64_t m_hash = fnvEmptyHash; }; +class ASTHasherBase: public HasherBase +{ +protected: + void hashLiteral(solidity::yul::Literal const& _literal); +}; + /** * Optimiser component that calculates hash values for blocks. * Syntactically equal blocks will have identical hashes and @@ -73,7 +78,7 @@ class HasherBase * * Prerequisite: Disambiguator, ForLoopInitRewriter */ -class BlockHasher: public ASTWalker, public HasherBase +class BlockHasher: public ASTWalker, public ASTHasherBase { public: @@ -120,7 +125,7 @@ class BlockHasher: public ASTWalker, public HasherBase * have a different name and the same if the name matches. * This means this hasher should only be used on disambiguated sources. */ -class ExpressionHasher: public ASTWalker, public HasherBase +class ExpressionHasher: public ASTWalker, public ASTHasherBase { public: /// Computes a hash of an expression that (in contrast to the behaviour of the class) diff --git a/libyul/optimiser/CommonSubexpressionEliminator.cpp b/libyul/optimiser/CommonSubexpressionEliminator.cpp index ae55f75e9847..1c7879056d61 100644 --- a/libyul/optimiser/CommonSubexpressionEliminator.cpp +++ b/libyul/optimiser/CommonSubexpressionEliminator.cpp @@ -114,7 +114,7 @@ void CommonSubexpressionEliminator::visit(Expression& _e) if ( m_returnVariables.count(variable) && std::holds_alternative(*value->value) && - valueOfLiteral(std::get(*value->value)) == 0 + std::get(*value->value).value.value() == 0 ) continue; // We check for syntactic equality again because the value might have changed. diff --git a/libyul/optimiser/ConditionalUnsimplifier.cpp b/libyul/optimiser/ConditionalUnsimplifier.cpp index 2af09af04b60..104ec1e4f095 100644 --- a/libyul/optimiser/ConditionalUnsimplifier.cpp +++ b/libyul/optimiser/ConditionalUnsimplifier.cpp @@ -59,7 +59,7 @@ void ConditionalUnsimplifier::operator()(Switch& _switch) assignment.variableNames.size() == 1 && assignment.variableNames.front().name == expr && std::holds_alternative(*assignment.value) && - valueOfLiteral(std::get(*assignment.value)) == valueOfLiteral(*_case.value) + std::get(*assignment.value).value == _case.value->value ) _case.body.statements.erase(_case.body.statements.begin()); } @@ -95,7 +95,7 @@ void ConditionalUnsimplifier::operator()(Block& _block) assignment.variableNames.size() == 1 && assignment.variableNames.front().name == condition && std::holds_alternative(*assignment.value) && - valueOfLiteral(std::get(*assignment.value)) == 0 + std::get(*assignment.value).value.value() == 0 ) return {make_vector(std::move(_stmt1))}; } diff --git a/libyul/optimiser/DataFlowAnalyzer.cpp b/libyul/optimiser/DataFlowAnalyzer.cpp index 5992c9b985c6..5ec3cf248df9 100644 --- a/libyul/optimiser/DataFlowAnalyzer.cpp +++ b/libyul/optimiser/DataFlowAnalyzer.cpp @@ -414,7 +414,7 @@ std::optional DataFlowAnalyzer::valueOfIdentifier(YulString const& _name) { if (AssignedValue const* value = variableValue(_name)) if (Literal const* literal = std::get_if(value->value)) - return valueOfLiteral(*literal); + return literal->value.value(); return std::nullopt; } diff --git a/libyul/optimiser/DataFlowAnalyzer.h b/libyul/optimiser/DataFlowAnalyzer.h index b449357e6606..e41620b15f27 100644 --- a/libyul/optimiser/DataFlowAnalyzer.h +++ b/libyul/optimiser/DataFlowAnalyzer.h @@ -217,7 +217,7 @@ class DataFlowAnalyzer: public ASTModifier }; /// Special expression whose address will be used in m_value. /// YulString does not need to be reset because DataFlowAnalyzer is short-lived. - Expression const m_zero{Literal{{}, LiteralKind::Number, YulString{"0"}, {}}}; + Expression const m_zero{Literal{{}, LiteralKind::Number, LiteralValue{0, "0"}, {}}}; /// List of scopes. std::vector m_variableScopes; }; diff --git a/libyul/optimiser/ExpressionSimplifier.cpp b/libyul/optimiser/ExpressionSimplifier.cpp index c87c5df23f36..6d0a8c9d7409 100644 --- a/libyul/optimiser/ExpressionSimplifier.cpp +++ b/libyul/optimiser/ExpressionSimplifier.cpp @@ -60,14 +60,14 @@ void ExpressionSimplifier::visit(Expression& _expression) !knownToBeZero(startArgument) && !std::holds_alternative(startArgument) ) - startArgument = Literal{debugDataOf(startArgument), LiteralKind::Number, "0"_yulstring, {}}; + startArgument = Literal{debugDataOf(startArgument), LiteralKind::Number, LiteralValue{0, "0"}, {}}; } } bool ExpressionSimplifier::knownToBeZero(Expression const& _expression) const { if (auto const* literal = std::get_if(&_expression)) - return valueOfLiteral(*literal) == 0; + return literal->value.value() == 0; else if (auto const* identifier = std::get_if(&_expression)) return valueOfIdentifier(identifier->name) == 0; else diff --git a/libyul/optimiser/ForLoopConditionIntoBody.cpp b/libyul/optimiser/ForLoopConditionIntoBody.cpp index 33d8496f08b5..df9847376af7 100644 --- a/libyul/optimiser/ForLoopConditionIntoBody.cpp +++ b/libyul/optimiser/ForLoopConditionIntoBody.cpp @@ -58,7 +58,7 @@ void ForLoopConditionIntoBody::operator()(ForLoop& _forLoop) Literal { debugData, LiteralKind::Boolean, - "true"_yulstring, + LiteralValue{true}, m_dialect.boolType } ); diff --git a/libyul/optimiser/ForLoopConditionOutOfBody.cpp b/libyul/optimiser/ForLoopConditionOutOfBody.cpp index e2451bc6c6e9..83b1e20a8e33 100644 --- a/libyul/optimiser/ForLoopConditionOutOfBody.cpp +++ b/libyul/optimiser/ForLoopConditionOutOfBody.cpp @@ -38,7 +38,7 @@ void ForLoopConditionOutOfBody::operator()(ForLoop& _forLoop) if ( !m_dialect.booleanNegationFunction() || !std::holds_alternative(*_forLoop.condition) || - valueOfLiteral(std::get(*_forLoop.condition)) == u256(0) || + std::get(*_forLoop.condition).value.value() == 0 || _forLoop.body.statements.empty() || !std::holds_alternative(_forLoop.body.statements.front()) ) diff --git a/libyul/optimiser/KnowledgeBase.cpp b/libyul/optimiser/KnowledgeBase.cpp index c280ecf14e1d..79eb2b317940 100644 --- a/libyul/optimiser/KnowledgeBase.cpp +++ b/libyul/optimiser/KnowledgeBase.cpp @@ -78,7 +78,7 @@ std::optional KnowledgeBase::valueIfKnownConstant(Expression const& _expre if (Identifier const* ident = std::get_if(&_expression)) return valueIfKnownConstant(ident->name); else if (Literal const* lit = std::get_if(&_expression)) - return valueOfLiteral(*lit); + return lit->value.value(); else return std::nullopt; } @@ -113,7 +113,7 @@ KnowledgeBase::VariableOffset KnowledgeBase::explore(YulString _var) std::optional KnowledgeBase::explore(Expression const& _value) { if (Literal const* literal = std::get_if(&_value)) - return VariableOffset{YulString{}, valueOfLiteral(*literal)}; + return VariableOffset{YulString{}, literal->value.value()}; else if (Identifier const* identifier = std::get_if(&_value)) return explore(identifier->name); else if (FunctionCall const* f = std::get_if(&_value)) diff --git a/libyul/optimiser/LoadResolver.cpp b/libyul/optimiser/LoadResolver.cpp index 84094c33e096..170eefc902b5 100644 --- a/libyul/optimiser/LoadResolver.cpp +++ b/libyul/optimiser/LoadResolver.cpp @@ -125,7 +125,7 @@ void LoadResolver::tryEvaluateKeccak( {}, LiteralKind::Number, // a dummy 256-bit number to represent the Keccak256 hash. - YulString{std::numeric_limits::max().str()}, + LiteralValue{std::numeric_limits::max()}, {} } ); @@ -146,10 +146,11 @@ void LoadResolver::tryEvaluateKeccak( { bytes contentAsBytes = toBigEndian(*memoryContent); contentAsBytes.resize(static_cast(*byteLength)); + u256 const contentHash (keccak256(contentAsBytes)); _e = Literal{ debugDataOf(_e), LiteralKind::Number, - YulString{u256(keccak256(contentAsBytes)).str()}, + LiteralValue{contentHash}, m_dialect.defaultType }; } diff --git a/libyul/optimiser/Metrics.cpp b/libyul/optimiser/Metrics.cpp index 42845f3b6627..2f1dee93eabe 100644 --- a/libyul/optimiser/Metrics.cpp +++ b/libyul/optimiser/Metrics.cpp @@ -71,7 +71,7 @@ size_t CodeWeights::costOf(Expression const& _expression) const else if (Literal const* literal = std::get_if(&_expression)) { // Avoid strings because they could be longer than 32 bytes. - if (literal->kind != LiteralKind::String && valueOfLiteral(*literal) == 0) + if (literal->kind != LiteralKind::String && literal->value.value() == 0) return literalZeroCost; else return literalCost; @@ -155,15 +155,15 @@ void CodeCost::operator()(Literal const& _literal) case LiteralKind::Boolean: break; case LiteralKind::Number: - for (u256 n = u256(_literal.value.str()); n >= 0x100; n >>= 8) + for (u256 n = _literal.value.value(); n >= 0x100; n >>= 8) cost++; - if (valueOfLiteral(_literal) == 0) + if (_literal.value.value() == 0) if (auto evmDialect = dynamic_cast(&m_dialect)) if (evmDialect->evmVersion().hasPush0()) --m_cost; break; case LiteralKind::String: - cost = _literal.value.str().size(); + cost = formatLiteral(_literal).size(); break; } diff --git a/libyul/optimiser/SSAValueTracker.h b/libyul/optimiser/SSAValueTracker.h index f1c93ff229de..5a7eee5124b4 100644 --- a/libyul/optimiser/SSAValueTracker.h +++ b/libyul/optimiser/SSAValueTracker.h @@ -57,7 +57,7 @@ class SSAValueTracker: public ASTWalker /// Special expression whose address will be used in m_values. /// YulString does not need to be reset because SSAValueTracker is short-lived. - Expression const m_zero{Literal{{}, LiteralKind::Number, YulString{"0"}, {}}}; + Expression const m_zero{Literal{{}, LiteralKind::Number, LiteralValue(u256{0}), {}}}; std::map m_values; }; diff --git a/libyul/optimiser/SimplificationRules.cpp b/libyul/optimiser/SimplificationRules.cpp index 7fe56026ac95..e2d46832906e 100644 --- a/libyul/optimiser/SimplificationRules.cpp +++ b/libyul/optimiser/SimplificationRules.cpp @@ -160,7 +160,7 @@ bool Pattern::matches( Literal const& literal = std::get(*expr); if (literal.kind != LiteralKind::Number) return false; - if (m_data && *m_data != u256(literal.value.str())) + if (m_data && *m_data != literal.value.value()) return false; assertThrow(m_arguments.empty(), OptimizerException, ""); } @@ -241,7 +241,7 @@ Expression Pattern::toExpression(langutil::DebugData::ConstPtr const& _debugData if (m_kind == PatternKind::Constant) { assertThrow(m_data, OptimizerException, "No match group and no constant value given."); - return Literal{_debugData, LiteralKind::Number, YulString{formatNumber(*m_data)}, {}}; + return Literal{_debugData, LiteralKind::Number, LiteralValue{*m_data, formatNumber(*m_data)}, {}}; } else if (m_kind == PatternKind::Operation) { @@ -261,7 +261,7 @@ Expression Pattern::toExpression(langutil::DebugData::ConstPtr const& _debugData u256 Pattern::d() const { - return valueOfNumberLiteral(std::get(matchGroupValue())); + return std::get(matchGroupValue()).value.value(); } Expression const& Pattern::matchGroupValue() const diff --git a/libyul/optimiser/StackLimitEvader.cpp b/libyul/optimiser/StackLimitEvader.cpp index 5d7f7fe5d430..904ee77e00f9 100644 --- a/libyul/optimiser/StackLimitEvader.cpp +++ b/libyul/optimiser/StackLimitEvader.cpp @@ -113,7 +113,7 @@ u256 literalArgumentValue(FunctionCall const& _call) yulAssert(_call.arguments.size() == 1, ""); Literal const* literal = std::get_if(&_call.arguments.front()); yulAssert(literal && literal->kind == LiteralKind::Number, ""); - return valueOfLiteral(*literal); + return literal->value.value(); } } @@ -210,6 +210,6 @@ void StackLimitEvader::run( { Literal* literal = std::get_if(&memoryGuardCall->arguments.front()); yulAssert(literal && literal->kind == LiteralKind::Number, ""); - literal->value = YulString{toCompactHexWithPrefix(reservedMemory)}; + literal->value = LiteralValue{reservedMemory, toCompactHexWithPrefix(reservedMemory)}; } } diff --git a/libyul/optimiser/StackToMemoryMover.cpp b/libyul/optimiser/StackToMemoryMover.cpp index dedb5cd382ce..dbf3183fb420 100644 --- a/libyul/optimiser/StackToMemoryMover.cpp +++ b/libyul/optimiser/StackToMemoryMover.cpp @@ -20,6 +20,7 @@ #include #include +#include #include @@ -37,7 +38,7 @@ namespace std::vector generateMemoryStore( Dialect const& _dialect, langutil::DebugData::ConstPtr const& _debugData, - YulString _mpos, + LiteralValue const& _mpos, Expression _value ) { @@ -55,7 +56,7 @@ std::vector generateMemoryStore( return result; } -FunctionCall generateMemoryLoad(Dialect const& _dialect, langutil::DebugData::ConstPtr const& _debugData, YulString _mpos) +FunctionCall generateMemoryLoad(Dialect const& _dialect, langutil::DebugData::ConstPtr const& _debugData, LiteralValue const& _mpos) { BuiltinFunction const* memoryLoadFunction = _dialect.memoryLoadFunction(_dialect.defaultType); yulAssert(memoryLoadFunction, ""); @@ -139,7 +140,7 @@ void StackToMemoryMover::operator()(FunctionDefinition& _functionDefinition) m_context.dialect, returnVariable.debugData, *slot, - Literal{returnVariable.debugData, LiteralKind::Number, "0"_yulstring, {}} + Literal{returnVariable.debugData, LiteralKind::Number, LiteralValue(u256{0}), {}} ); // Special case of a function with a single return argument that needs to move to memory. @@ -208,36 +209,36 @@ void StackToMemoryMover::operator()(Block& _block) auto debugData = _stmt.debugData; if (_lhsVars.size() == 1) { - if (std::optional offset = m_memoryOffsetTracker(_lhsVars.front().name)) + if (auto offset = m_memoryOffsetTracker(_lhsVars.front().name)) return generateMemoryStore( m_context.dialect, debugData, *offset, - _stmt.value ? *std::move(_stmt.value) : Literal{debugData, LiteralKind::Number, "0"_yulstring, {}} + _stmt.value ? *std::move(_stmt.value) : Literal{debugData, LiteralKind::Number, LiteralValue(u256{0}), {}} ); else return {}; } - std::vector> rhsMemorySlots; + std::vector> rhsMemorySlots; if (_stmt.value) { FunctionCall const* functionCall = std::get_if(_stmt.value.get()); yulAssert(functionCall, ""); if (m_context.dialect.builtin(functionCall->functionName.name)) - rhsMemorySlots = std::vector>(_lhsVars.size(), std::nullopt); + rhsMemorySlots = std::vector>(_lhsVars.size(), std::nullopt); else rhsMemorySlots = m_functionReturnVariables.at(functionCall->functionName.name) | ranges::views::transform(m_memoryOffsetTracker) | - ranges::to>>; + ranges::to>>; } else - rhsMemorySlots = std::vector>(_lhsVars.size(), std::nullopt); + rhsMemorySlots = std::vector>(_lhsVars.size(), std::nullopt); // Nothing to do, if the right-hand-side remains entirely on the stack and // none of the variables in the left-hand-side are moved. if ( - ranges::none_of(rhsMemorySlots, [](std::optional const& _slot) { return _slot.has_value(); }) && + ranges::none_of(rhsMemorySlots, [](std::optional const& _slot) { return _slot.has_value(); }) && !util::contains_if(_lhsVars, m_memoryOffsetTracker) ) return {}; @@ -259,7 +260,7 @@ void StackToMemoryMover::operator()(Block& _block) rhs = std::make_unique(Identifier{debugData, tempVarName}); } - if (std::optional offset = m_memoryOffsetTracker(lhsVar.name)) + if (auto offset = m_memoryOffsetTracker(lhsVar.name)) memoryAssignments += generateMemoryStore( m_context.dialect, _stmt.debugData, @@ -304,28 +305,29 @@ void StackToMemoryMover::visit(Expression& _expression) { ASTModifier::visit(_expression); if (Identifier* identifier = std::get_if(&_expression)) - if (std::optional offset = m_memoryOffsetTracker(identifier->name)) + if (auto offset = m_memoryOffsetTracker(identifier->name)) _expression = generateMemoryLoad(m_context.dialect, identifier->debugData, *offset); } -std::optional StackToMemoryMover::VariableMemoryOffsetTracker::operator()(YulString _variable) const +std::optional StackToMemoryMover::VariableMemoryOffsetTracker::operator()(YulString const& _variable) const { if (m_memorySlots.count(_variable)) { uint64_t slot = m_memorySlots.at(_variable); yulAssert(slot < m_numRequiredSlots, ""); - return YulString{toCompactHexWithPrefix(m_reservedMemory + 32 * (m_numRequiredSlots - slot - 1))}; + auto const memoryOffset = m_reservedMemory + 32 * (m_numRequiredSlots - slot - 1); + return valueOfNumberLiteral(toCompactHexWithPrefix(memoryOffset)); } else return std::nullopt; } -std::optional StackToMemoryMover::VariableMemoryOffsetTracker::operator()(TypedName const& _variable) const +std::optional StackToMemoryMover::VariableMemoryOffsetTracker::operator()(TypedName const& _variable) const { return (*this)(_variable.name); } -std::optional StackToMemoryMover::VariableMemoryOffsetTracker::operator()(Identifier const& _variable) const +std::optional StackToMemoryMover::VariableMemoryOffsetTracker::operator()(Identifier const& _variable) const { return (*this)(_variable.name); } diff --git a/libyul/optimiser/StackToMemoryMover.h b/libyul/optimiser/StackToMemoryMover.h index 64c661c0bfed..79c7276ede93 100644 --- a/libyul/optimiser/StackToMemoryMover.h +++ b/libyul/optimiser/StackToMemoryMover.h @@ -165,13 +165,13 @@ class StackToMemoryMover: ASTModifier /// @returns a YulString containing the memory offset to be assigned to @a _variable as number literal /// or std::nullopt if the variable should not be moved. - std::optional operator()(YulString _variable) const; + std::optional operator()(YulString const& _variable) const; /// @returns a YulString containing the memory offset to be assigned to @a _variable as number literal /// or std::nullopt if the variable should not be moved. - std::optional operator()(TypedName const& _variable) const; + std::optional operator()(TypedName const& _variable) const; /// @returns a YulString containing the memory offset to be assigned to @a _variable as number literal /// or std::nullopt if the variable should not be moved. - std::optional operator()(Identifier const& _variable) const; + std::optional operator()(Identifier const& _variable) const; private: u256 m_reservedMemory; diff --git a/libyul/optimiser/StructuralSimplifier.cpp b/libyul/optimiser/StructuralSimplifier.cpp index 2af0f7bac044..896c855b0dd4 100644 --- a/libyul/optimiser/StructuralSimplifier.cpp +++ b/libyul/optimiser/StructuralSimplifier.cpp @@ -36,7 +36,7 @@ OptionalStatements replaceConstArgSwitch(Switch& _switchStmt, u256 const& _const for (auto& _case: _switchStmt.cases) { - if (_case.value && valueOfLiteral(*_case.value) == _constExprVal) + if (_case.value && _case.value->value.value() == _constExprVal) { matchingCaseBlock = &_case.body; break; @@ -57,9 +57,9 @@ OptionalStatements replaceConstArgSwitch(Switch& _switchStmt, u256 const& _const std::optional hasLiteralValue(Expression const& _expression) { if (std::holds_alternative(_expression)) - return valueOfLiteral(std::get(_expression)); + return std::get(_expression).value.value(); else - return std::optional(); + return std::nullopt; } bool expressionAlwaysTrue(Expression const& _expression) diff --git a/libyul/optimiser/SyntacticalEquality.cpp b/libyul/optimiser/SyntacticalEquality.cpp index 6f7753827ddc..db562716a2ff 100644 --- a/libyul/optimiser/SyntacticalEquality.cpp +++ b/libyul/optimiser/SyntacticalEquality.cpp @@ -22,6 +22,7 @@ #include #include +#include #include @@ -63,12 +64,13 @@ bool SyntacticallyEqual::expressionEqual(Identifier const& _lhs, Identifier cons } bool SyntacticallyEqual::expressionEqual(Literal const& _lhs, Literal const& _rhs) { - if (_lhs.kind != _rhs.kind || _lhs.type != _rhs.type) + yulAssert(validLiteral(_lhs), "Invalid lhs literal during syntactical equality check"); + yulAssert(validLiteral(_rhs), "Invalid rhs literal during syntactical equality check"); + + if (_lhs.type != _rhs.type) return false; - if (_lhs.kind == LiteralKind::Number) - return valueOfNumberLiteral(_lhs) == valueOfNumberLiteral(_rhs); - else - return _lhs.value == _rhs.value; + + return _lhs.value == _rhs.value; } bool SyntacticallyEqual::statementEqual(ExpressionStatement const& _lhs, ExpressionStatement const& _rhs) diff --git a/libyul/optimiser/SyntacticalEquality.h b/libyul/optimiser/SyntacticalEquality.h index 319da763e8ac..5a8d2b49b267 100644 --- a/libyul/optimiser/SyntacticalEquality.h +++ b/libyul/optimiser/SyntacticalEquality.h @@ -34,6 +34,9 @@ namespace solidity::yul /** * Component that can compare ASTs for equality on a syntactic basis. * Ignores source locations and allows for different variable names but requires exact matches otherwise. + * Literals are compared based on their values, e.g., `0x01`, `1`, `"\x01"` and `true` all evaluate as equal. + * Note that this does not apply to unlimited literal strings, which are never considered equal to normal literals, + * even when the values would look like identical strings in the source. * * Prerequisite: Disambiguator (unless only expressions are compared) */ diff --git a/libyul/optimiser/UnusedStoreEliminator.cpp b/libyul/optimiser/UnusedStoreEliminator.cpp index ed3394847c35..6a0ab1518d08 100644 --- a/libyul/optimiser/UnusedStoreEliminator.cpp +++ b/libyul/optimiser/UnusedStoreEliminator.cpp @@ -61,9 +61,9 @@ void UnusedStoreEliminator::run(OptimiserStepContext& _context, Block& _ast) std::map values; for (auto const& [name, expression]: ssaValues.values()) values[name] = AssignedValue{expression, {}}; - Expression const zeroLiteral{Literal{{}, LiteralKind::Number, YulString{"0"}, {}}}; - Expression const oneLiteral{Literal{{}, LiteralKind::Number, YulString{"1"}, {}}}; - Expression const thirtyTwoLiteral{Literal{{}, LiteralKind::Number, YulString{"32"}, {}}}; + Expression const zeroLiteral{Literal{{}, LiteralKind::Number, LiteralValue(u256{0}), {}}}; + Expression const oneLiteral{Literal{{}, LiteralKind::Number, LiteralValue(u256{1}), {}}}; + Expression const thirtyTwoLiteral{Literal{{}, LiteralKind::Number, LiteralValue(u256{32}), {}}}; values[YulString{zero}] = AssignedValue{&zeroLiteral, {}}; values[YulString{one}] = AssignedValue{&oneLiteral, {}}; values[YulString{thirtyTwo}] = AssignedValue{&thirtyTwoLiteral, {}}; diff --git a/test/libyul/yulOptimizerTests/disambiguator/similar_literals.yul b/test/libyul/yulOptimizerTests/disambiguator/similar_literals.yul new file mode 100644 index 000000000000..87c7d4a19770 --- /dev/null +++ b/test/libyul/yulOptimizerTests/disambiguator/similar_literals.yul @@ -0,0 +1,23 @@ +{ + let a := 1234 + let a_hex := 0x4d2 + let b := "1234" + let b_hex := "0x4d2" + let c := '1234' + let c_hex := '0x4d2' + let d := hex"1234" + let d_hex := hex"04d2" +} +// ---- +// step: disambiguator +// +// { +// let a := 1234 +// let a_hex := 0x4d2 +// let b := "1234" +// let b_hex := "0x4d2" +// let c := "1234" +// let c_hex := "0x4d2" +// let d := "\x124" +// let d_hex := "\x04\xd2" +// } diff --git a/test/libyul/yulOptimizerTests/disambiguator/string_as_hex_and_hex_as_string.yul b/test/libyul/yulOptimizerTests/disambiguator/string_as_hex_and_hex_as_string.yul new file mode 100644 index 000000000000..f0db2af1b220 --- /dev/null +++ b/test/libyul/yulOptimizerTests/disambiguator/string_as_hex_and_hex_as_string.yul @@ -0,0 +1,13 @@ +object "A" { + code { + pop(datasize(hex'616263')) + } + data 'abc' "1234" +} +// ---- +// step: disambiguator +// +// object "A" { +// code { pop(datasize("abc")) } +// data "abc" hex"31323334" +// } diff --git a/test/libyul/yulOptimizerTests/equivalentFunctionCombiner/constant_representation.yul b/test/libyul/yulOptimizerTests/equivalentFunctionCombiner/constant_representation.yul index b7a815dd9703..77df0ae20a1a 100644 --- a/test/libyul/yulOptimizerTests/equivalentFunctionCombiner/constant_representation.yul +++ b/test/libyul/yulOptimizerTests/equivalentFunctionCombiner/constant_representation.yul @@ -1,8 +1,10 @@ { f() g() - function f() { mstore(0x01, mload(0x00)) } - function g() { mstore(1, mload(0)) } + h() + function f() { mstore(29400335157912315244266070412362164103369332044010299463143527189509193072640, mload(0x00)) } + function g() { mstore(0x4100000000000000000000000000000000000000000000000000000000000000, mload(0x00)) } + function h() { mstore("A", mload(0)) } } // ---- // step: equivalentFunctionCombiner @@ -10,8 +12,15 @@ // { // f() // f() +// h() // function f() -// { mstore(0x01, mload(0x00)) } +// { +// mstore(29400335157912315244266070412362164103369332044010299463143527189509193072640, mload(0x00)) +// } // function g() -// { mstore(1, mload(0)) } +// { +// mstore(0x4100000000000000000000000000000000000000000000000000000000000000, mload(0x00)) +// } +// function h() +// { mstore("A", mload(0)) } // } diff --git a/test/libyul/yulOptimizerTests/equivalentFunctionCombiner/constant_representation_datasize.yul b/test/libyul/yulOptimizerTests/equivalentFunctionCombiner/constant_representation_datasize.yul new file mode 100644 index 000000000000..301f50c6ea27 --- /dev/null +++ b/test/libyul/yulOptimizerTests/equivalentFunctionCombiner/constant_representation_datasize.yul @@ -0,0 +1,48 @@ +object "test" +{ + code + { + f() + g() + h() + i() + function f() + { + let x := datasize("A") + } + function g() + { + let x := datasize(hex"41") + } + function h() + { + let x := datasize("\x41") + } + function i() + { + let x := datasize("\u0041") + } + } + data 'A' "A" +} + +// ---- +// step: equivalentFunctionCombiner +// +// object "test" { +// code { +// f() +// f() +// f() +// f() +// function f() +// { let x := datasize("A") } +// function g() +// { let x_1 := datasize("A") } +// function h() +// { let x_2 := datasize("A") } +// function i() +// { let x_3 := datasize("A") } +// } +// data "A" hex"41" +// } diff --git a/test/libyul/yulSyntaxTests/switch_duplicate_case.yul b/test/libyul/yulSyntaxTests/switch_duplicate_case.yul index 861f721acdac..7417f32d6317 100644 --- a/test/libyul/yulSyntaxTests/switch_duplicate_case.yul +++ b/test/libyul/yulSyntaxTests/switch_duplicate_case.yul @@ -6,4 +6,4 @@ // ==== // dialect: evmTyped // ---- -// DeclarationError 6792: (34-50): Duplicate case "0" defined. +// DeclarationError 6792: (34-50): Duplicate case "0x0" defined. diff --git a/test/libyul/yulSyntaxTests/switch_duplicate_case_different_literal.yul b/test/libyul/yulSyntaxTests/switch_duplicate_case_different_literal.yul index e3367b175b6f..91f19efae1d6 100644 --- a/test/libyul/yulSyntaxTests/switch_duplicate_case_different_literal.yul +++ b/test/libyul/yulSyntaxTests/switch_duplicate_case_different_literal.yul @@ -6,4 +6,4 @@ // ==== // dialect: evmTyped // ---- -// DeclarationError 6792: (34-49): Duplicate case "0" defined. +// DeclarationError 6792: (34-49): Duplicate case "" defined. diff --git a/test/tools/yulInterpreter/EVMInstructionInterpreter.cpp b/test/tools/yulInterpreter/EVMInstructionInterpreter.cpp index 2fe2b21847f3..d2cbdb11b360 100644 --- a/test/tools/yulInterpreter/EVMInstructionInterpreter.cpp +++ b/test/tools/yulInterpreter/EVMInstructionInterpreter.cpp @@ -25,6 +25,7 @@ #include #include +#include #include #include @@ -508,7 +509,7 @@ u256 EVMInstructionInterpreter::evalBuiltin( // Evaluate datasize/offset/copy instructions if (fun == "datasize" || fun == "dataoffset") { - std::string arg = std::get(_arguments.at(0)).value.str(); + std::string arg = formatLiteral(std::get(_arguments.at(0))); if (arg.length() < 32) arg.resize(32, 0); if (fun == "datasize") diff --git a/test/tools/yulInterpreter/Interpreter.cpp b/test/tools/yulInterpreter/Interpreter.cpp index a8658e921194..6a0f3a9997ef 100644 --- a/test/tools/yulInterpreter/Interpreter.cpp +++ b/test/tools/yulInterpreter/Interpreter.cpp @@ -296,10 +296,7 @@ void Interpreter::incrementStep() void ExpressionEvaluator::operator()(Literal const& _literal) { incrementStep(); - static YulString const trueString("true"); - static YulString const falseString("false"); - - setValue(valueOfLiteral(_literal)); + setValue(_literal.value.value()); } void ExpressionEvaluator::operator()(Identifier const& _identifier) @@ -389,16 +386,13 @@ void ExpressionEvaluator::evaluateArgs( visit(expr); else { - std::string literal = std::get(expr).value.str(); - - try - { - m_values = {u256(literal)}; - } - catch (std::exception&) + if (std::get(expr).value.unlimited()) { - m_values = {u256(0)}; + yulAssert(std::get(expr).kind == LiteralKind::String); + m_values = {0xdeadbeef}; } + else + m_values = {std::get(expr).value.value()}; } values.push_back(value()); From 21e3b22c900e951d61b3c2d585bfc1893ca49b6e Mon Sep 17 00:00:00 2001 From: Martin Blicha Date: Fri, 28 Jun 2024 12:34:22 +0200 Subject: [PATCH 0282/1022] SMTChecker: Do not depend on predicate name containing numbers --- libsolidity/formal/CHC.cpp | 19 +++++++------------ .../operators/slice_access.sol | 16 ++++++++++++++++ 2 files changed, 23 insertions(+), 12 deletions(-) create mode 100644 test/libsolidity/smtCheckerTests/operators/slice_access.sol diff --git a/libsolidity/formal/CHC.cpp b/libsolidity/formal/CHC.cpp index f0c6ec33a1a4..ff3a6f1da601 100644 --- a/libsolidity/formal/CHC.cpp +++ b/libsolidity/formal/CHC.cpp @@ -2419,22 +2419,17 @@ std::map> CHC::summaryCalls(CHCSolverInterface:: // nondet_call__ // Those have the extra unique numbers based on the traversal order, and are necessary // to infer the call order so that's shown property in the counterexample trace. - // Predicates that do not have a CALLID have a predicate id at the end of , - // so the assertion below should still hold. + // For other predicates, we do not care. auto beg = _s.data(); while (beg != _s.data() + _s.size() && !isDigit(*beg)) ++beg; - auto end = beg; - while (end != _s.data() + _s.size() && isDigit(*end)) ++end; - - solAssert(beg != end, "Expected to find numerical call or predicate id."); - - int result; - auto [p, ec] = std::from_chars(beg, end, result); - solAssert(ec == std::errc(), "Id should be a number."); - + int result = -1; + static_cast(std::from_chars(beg, _s.data() + _s.size(), result)); return result; }; - return extract(_graph.nodes.at(_a).name) > extract(_graph.nodes.at(_b).name); + auto anum = extract(_graph.nodes.at(_a).name); + auto bnum = extract(_graph.nodes.at(_b).name); + // The second part of the condition is needed to ensure that two different predicates are not considered equal + return (anum > bnum) || (anum == bnum && _graph.nodes.at(_a).name > _graph.nodes.at(_b).name); }; std::queue> q; diff --git a/test/libsolidity/smtCheckerTests/operators/slice_access.sol b/test/libsolidity/smtCheckerTests/operators/slice_access.sol new file mode 100644 index 000000000000..6accc54c0eb7 --- /dev/null +++ b/test/libsolidity/smtCheckerTests/operators/slice_access.sol @@ -0,0 +1,16 @@ +contract C { +function f(int[] calldata b) public pure { + require(b.length == 3); + require(b[0] == 0); + require(b[1] == 1); + require(b[2] == 2); + assert(b[1:3][0] == 1); // should hold + assert(b[1:3][1] == 1); // should fail +} +} +// ==== +// SMTEngine: chc +// SMTIgnoreCex: no +// ---- +// Warning 6328: (203-225): CHC: Assertion violation happens here.\nCounterexample:\n\nb = [0, 1, 2]\n\nTransaction trace:\nC.constructor()\nC.f([0, 1, 2]) +// Info 1391: CHC: 6 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. From 762ebc1ce51c5c016df4e49be06f96d048312cfd Mon Sep 17 00:00:00 2001 From: Bhargava Shastry Date: Mon, 1 Jul 2024 10:02:52 +0200 Subject: [PATCH 0283/1022] Yul fuzzer: Skip tstore generation for older EVM versions. --- test/tools/ossfuzz/protoToYul.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/test/tools/ossfuzz/protoToYul.cpp b/test/tools/ossfuzz/protoToYul.cpp index 7913f4d63450..5a57b779dc87 100644 --- a/test/tools/ossfuzz/protoToYul.cpp +++ b/test/tools/ossfuzz/protoToYul.cpp @@ -1162,6 +1162,11 @@ void ProtoConverter::visit(IfStmt const& _x) void ProtoConverter::visit(StoreFunc const& _x) { auto storeType = _x.st(); + // Skip statement generation if tstore is not + // supported in EVM version + if (storeType == StoreFunc::TSTORE && !m_evmVersion.supportsTransientStorage()) + return; + switch (storeType) { case StoreFunc::MSTORE: From 81966bc5f6b504df18bd5a09f23a13008d1ff378 Mon Sep 17 00:00:00 2001 From: Martin Blicha Date: Wed, 26 Jun 2024 21:38:53 +0200 Subject: [PATCH 0284/1022] SMTChecker: Simplify CHC predicate representation There is no need to represent predicates using the symbolic variables. These are not variables that correspond to expression in the code. It is sufficient to store the name of the predicate and its signature (sort), which we can do with the SMT Expression. --- libsmtutil/Z3CHCInterface.cpp | 2 + libsolidity/formal/CHC.cpp | 5 - libsolidity/formal/CHC.h | 1 - libsolidity/formal/Predicate.cpp | 29 +-- libsolidity/formal/Predicate.h | 20 +- .../model_checker_invariants_reentrancy/err | 2 +- .../model_checker_print_query_all/err | 70 +++--- .../model_checker_print_query_chc/err | 70 +++--- .../output.json | 4 +- .../output.json | 212 +++++++++--------- .../output.json | 212 +++++++++--------- .../output.json | 72 +++--- .../deployment/deploy_trusted_flow.sol | 4 +- ...n_code_state_reentrancy_unsafe_trusted.sol | 2 +- .../underflow_only_in_external_call.sol | 4 +- .../operators/index_access_for_bytesNN.sol | 3 +- .../operators/index_access_side_effect.sol | 5 +- ...rator_matches_equivalent_function_call.sol | 14 +- .../smtCheckerTests/out_of_bounds/array_1.sol | 4 +- .../smtCheckerTests/types/array_branch_3d.sol | 14 +- .../types/array_branches_3d.sol | 1 + .../types/array_branches_3d_show_unproved.sol | 1 + .../types/struct_array_branches_2d.sol | 4 +- 23 files changed, 368 insertions(+), 387 deletions(-) diff --git a/libsmtutil/Z3CHCInterface.cpp b/libsmtutil/Z3CHCInterface.cpp index a25890e8d10a..787d46d72e49 100644 --- a/libsmtutil/Z3CHCInterface.cpp +++ b/libsmtutil/Z3CHCInterface.cpp @@ -58,6 +58,8 @@ void Z3CHCInterface::declareVariable(std::string const& _name, SortPointer const void Z3CHCInterface::registerRelation(Expression const& _expr) { + smtAssert(_expr.sort->kind == Kind::Function); + m_z3Interface->declareVariable(_expr.name, _expr.sort); m_solver.register_relation(m_z3Interface->functions().at(_expr.name)); } diff --git a/libsolidity/formal/CHC.cpp b/libsolidity/formal/CHC.cpp index ff3a6f1da601..73b979364211 100644 --- a/libsolidity/formal/CHC.cpp +++ b/libsolidity/formal/CHC.cpp @@ -1657,11 +1657,6 @@ smtutil::Expression CHC::error() return (*m_errorPredicate)({}); } -smtutil::Expression CHC::error(unsigned _idx) -{ - return m_errorPredicate->functor(_idx)({}); -} - smtutil::Expression CHC::initializer(ContractDefinition const& _contract, ContractDefinition const& _contractContext) { return predicate(*m_contractInitializers.at(&_contractContext).at(&_contract)); diff --git a/libsolidity/formal/CHC.h b/libsolidity/formal/CHC.h index b60e5c3f771e..8a40ecb22338 100644 --- a/libsolidity/formal/CHC.h +++ b/libsolidity/formal/CHC.h @@ -225,7 +225,6 @@ class CHC: public SMTEncoder smtutil::Expression interface(ContractDefinition const& _contract); /// Error predicate over current variables. smtutil::Expression error(); - smtutil::Expression error(unsigned _idx); /// Creates a block for the given _node. Predicate const* createBlock(ASTNode const* _node, PredicateType _predType, std::string const& _prefix = ""); diff --git a/libsolidity/formal/Predicate.cpp b/libsolidity/formal/Predicate.cpp index 01316d75ff43..75314d7e9414 100644 --- a/libsolidity/formal/Predicate.cpp +++ b/libsolidity/formal/Predicate.cpp @@ -49,26 +49,25 @@ Predicate const* Predicate::create( std::vector _scopeStack ) { - smt::SymbolicFunctionVariable predicate{_sort, std::move(_name), _context}; - std::string functorName = predicate.currentName(); - solAssert(!m_predicates.count(functorName), ""); + solAssert(!m_predicates.count(_name), ""); return &m_predicates.emplace( std::piecewise_construct, - std::forward_as_tuple(functorName), - std::forward_as_tuple(std::move(predicate), _type, _context.state().hasBytesConcatFunction(), + std::forward_as_tuple(_name), + std::forward_as_tuple(_name, std::move(_sort), _type, _context.state().hasBytesConcatFunction(), _node, _contractContext, std::move(_scopeStack)) ).first->second; } Predicate::Predicate( - smt::SymbolicFunctionVariable&& _predicate, + std::string _name, + SortPointer _sort, PredicateType _type, bool _bytesConcatFunctionInContext, ASTNode const* _node, ContractDefinition const* _contractContext, std::vector _scopeStack ): - m_predicate(std::move(_predicate)), + m_functor(std::move(_name), {}, std::move(_sort)), m_type(_type), m_node(_node), m_contractContext(_contractContext), @@ -89,22 +88,12 @@ void Predicate::reset() smtutil::Expression Predicate::operator()(std::vector const& _args) const { - return m_predicate(_args); -} - -smtutil::Expression Predicate::functor() const -{ - return m_predicate.currentFunctionValue(); -} - -smtutil::Expression Predicate::functor(unsigned _idx) const -{ - return m_predicate.functionValueAtIndex(_idx); + return smtutil::Expression(m_functor.name, _args, SortProvider::boolSort); } -void Predicate::newFunctor() +smtutil::Expression const& Predicate::functor() const { - m_predicate.increaseIndex(); + return m_functor; } ASTNode const* Predicate::programNode() const diff --git a/libsolidity/formal/Predicate.h b/libsolidity/formal/Predicate.h index 638354f921dc..a7df44621849 100644 --- a/libsolidity/formal/Predicate.h +++ b/libsolidity/formal/Predicate.h @@ -18,11 +18,10 @@ #pragma once -#include -#include #include +#include #include #include @@ -37,6 +36,11 @@ class CharStreamProvider; namespace solidity::frontend { +namespace smt +{ +class EncodingContext; +} + enum class PredicateType { Interface, @@ -69,7 +73,8 @@ class Predicate ); Predicate( - smt::SymbolicFunctionVariable&& _predicate, + std::string _name, + smtutil::SortPointer _sort, PredicateType _type, bool _bytesConcatFunctionInContext, ASTNode const* _node = nullptr, @@ -91,11 +96,7 @@ class Predicate smtutil::Expression operator()(std::vector const& _args) const; /// @returns the function declaration of the predicate. - smtutil::Expression functor() const; - /// @returns the function declaration of the predicate with index _idx. - smtutil::Expression functor(unsigned _idx) const; - /// Increases the index of the function declaration of the predicate. - void newFunctor(); + smtutil::Expression const& functor() const; /// @returns the program node this predicate represents. ASTNode const* programNode() const; @@ -204,8 +205,7 @@ class Predicate /// @returns index at which state variables values start in args list size_t firstStateVarIndex() const { return m_bytesConcatFunctionInContext ? 8 : 7; } - /// The actual SMT expression. - smt::SymbolicFunctionVariable m_predicate; + smtutil::Expression m_functor; /// The type of this predicate. PredicateType m_type; diff --git a/test/cmdlineTests/model_checker_invariants_reentrancy/err b/test/cmdlineTests/model_checker_invariants_reentrancy/err index bdd19fa18fa9..68ef6404cdb8 100644 --- a/test/cmdlineTests/model_checker_invariants_reentrancy/err +++ b/test/cmdlineTests/model_checker_invariants_reentrancy/err @@ -7,6 +7,6 @@ Warning: Return value of low-level calls not used. Info: CHC: 1 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. Info: Reentrancy property(ies) for model_checker_invariants_reentrancy/input.sol:test: -(((!(x <= 0) || !(x' >= 1)) && (!(x <= 0) || !( >= 1))) || true) +(((!(x <= 0) || !( >= 1)) && (!(x <= 0) || !(x' >= 1))) || true) = 0 -> no errors = 1 -> Assertion failed at assert(x < 10) diff --git a/test/cmdlineTests/model_checker_print_query_all/err b/test/cmdlineTests/model_checker_print_query_all/err index fc3bf7c7a3b6..7fbaba3ebefc 100644 --- a/test/cmdlineTests/model_checker_print_query_all/err +++ b/test/cmdlineTests/model_checker_print_query_all/err @@ -7,120 +7,120 @@ Info: CHC: Requested query: (declare-datatypes ((|crypto_type| 0)) (((|crypto_type| (|ecrecover| (Array |ecrecover_input_type| Int)) (|keccak256| (Array |bytes_tuple| Int)) (|ripemd160| (Array |bytes_tuple| Int)) (|sha256| (Array |bytes_tuple| Int)))))) (declare-datatypes ((|abi_type| 0)) (((|abi_type|)))) (declare-datatypes ((|state_type| 0)) (((|state_type| (|balances| (Array Int Int)))))) -(declare-fun |interface_0_C_16_0| (Int |abi_type| |crypto_type| |state_type| ) Bool) -(declare-fun |nondet_interface_1_C_16_0| (Int Int |abi_type| |crypto_type| |state_type| |state_type| ) Bool) -(declare-fun |summary_constructor_2_C_16_0| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) +(declare-fun |interface_0_C_16| (Int |abi_type| |crypto_type| |state_type| ) Bool) +(declare-fun |nondet_interface_1_C_16| (Int Int |abi_type| |crypto_type| |state_type| |state_type| ) Bool) +(declare-fun |summary_constructor_2_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (this_0 Int) (tx_0 |tx_type|)) -(=> (= error_0 0) (nondet_interface_1_C_16_0 error_0 this_0 abi_0 crypto_0 state_0 state_0)))) +(=> (= error_0 0) (nondet_interface_1_C_16 error_0 this_0 abi_0 crypto_0 state_0 state_0)))) -(declare-fun |summary_3_function_f__15_16_0| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) -(declare-fun |summary_4_function_f__15_16_0| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) +(declare-fun |summary_3_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) +(declare-fun |summary_4_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|)) -(=> (and (and (nondet_interface_1_C_16_0 error_0 this_0 abi_0 crypto_0 state_0 state_1) true) (and (= error_0 0) (summary_4_function_f__15_16_0 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2))) (nondet_interface_1_C_16_0 error_1 this_0 abi_0 crypto_0 state_0 state_2)))) +(=> (and (and (nondet_interface_1_C_16 error_0 this_0 abi_0 crypto_0 state_0 state_1) true) (and (= error_0 0) (summary_4_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2))) (nondet_interface_1_C_16 error_1 this_0 abi_0 crypto_0 state_0 state_2)))) -(declare-fun |block_5_function_f__15_16_0| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int ) Bool) -(declare-fun |block_6_f_14_16_0| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int ) Bool) +(declare-fun |block_5_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int ) Bool) +(declare-fun |block_6_f_14_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int ) Bool) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int)) -(block_5_function_f__15_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1))) +(block_5_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1))) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int)) -(=> (and (and (block_5_function_f__15_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true)) true) (block_6_f_14_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1)))) +(=> (and (and (block_5_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true)) true) (block_6_f_14_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1)))) -(declare-fun |block_7_return_function_f__15_16_0| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int ) Bool) -(declare-fun |block_8_function_f__15_16_0| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int ) Bool) +(declare-fun |block_7_return_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int ) Bool) +(declare-fun |block_8_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int ) Bool) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (block_6_f_14_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (= expr_11_1 (= expr_9_0 expr_10_0)) (and (=> true true) (and (= expr_10_0 0) (and (=> true (and (>= expr_9_0 0) (<= expr_9_0 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (= expr_9_0 x_5_2) (and (= x_5_2 expr_6_0) (and (=> true true) (and (= expr_6_0 0) (and (= x_5_1 0) true)))))))))) (and (and true (not expr_11_1)) (= error_1 1))) (block_8_function_f__15_16_0 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_2)))) +(=> (and (and (block_6_f_14_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (= expr_11_1 (= expr_9_0 expr_10_0)) (and (=> true true) (and (= expr_10_0 0) (and (=> true (and (>= expr_9_0 0) (<= expr_9_0 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (= expr_9_0 x_5_2) (and (= x_5_2 expr_6_0) (and (=> true true) (and (= expr_6_0 0) (and (= x_5_1 0) true)))))))))) (and (and true (not expr_11_1)) (= error_1 1))) (block_8_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_2)))) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (block_8_function_f__15_16_0 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_2) (summary_3_function_f__15_16_0 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) +(=> (block_8_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_2) (summary_3_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (block_6_f_14_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (= error_1 error_0) (and (= expr_11_1 (= expr_9_0 expr_10_0)) (and (=> true true) (and (= expr_10_0 0) (and (=> true (and (>= expr_9_0 0) (<= expr_9_0 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (= expr_9_0 x_5_2) (and (= x_5_2 expr_6_0) (and (=> true true) (and (= expr_6_0 0) (and (= x_5_1 0) true))))))))))) true) (block_7_return_function_f__15_16_0 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_2)))) +(=> (and (and (block_6_f_14_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (= error_1 error_0) (and (= expr_11_1 (= expr_9_0 expr_10_0)) (and (=> true true) (and (= expr_10_0 0) (and (=> true (and (>= expr_9_0 0) (<= expr_9_0 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (= expr_9_0 x_5_2) (and (= x_5_2 expr_6_0) (and (=> true true) (and (= expr_6_0 0) (and (= x_5_1 0) true))))))))))) true) (block_7_return_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_2)))) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (block_7_return_function_f__15_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) true) true) (summary_3_function_f__15_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) +(=> (and (and (block_7_return_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) true) true) (summary_3_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) -(declare-fun |block_9_function_f__15_16_0| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int ) Bool) +(declare-fun |block_9_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int ) Bool) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(block_9_function_f__15_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1))) +(block_9_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1))) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (block_9_function_f__15_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (summary_3_function_f__15_16_0 error_1 this_0 abi_0 crypto_0 tx_0 state_2 state_3) (and (= state_2 (|state_type| (store (|balances| state_1) this_0 (+ (select (|balances| state_1) this_0) funds_2_0)))) (and (and (>= (+ (select (|balances| state_1) this_0) funds_2_0) 0) (<= (+ (select (|balances| state_1) this_0) funds_2_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935)) (and (>= funds_2_0 (|msg.value| tx_0)) (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (and (and (and (and (and (= (|msg.value| tx_0) 0) (= (|msg.sig| tx_0) 638722032)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 0) 38)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 1) 18)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 2) 31)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 3) 240)) (>= (|bytes_tuple_accessor_length| (|msg.data| tx_0)) 4))) (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true))))))) true) (summary_4_function_f__15_16_0 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_3)))) +(=> (and (and (block_9_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (summary_3_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_2 state_3) (and (= state_2 (|state_type| (store (|balances| state_1) this_0 (+ (select (|balances| state_1) this_0) funds_2_0)))) (and (and (>= (+ (select (|balances| state_1) this_0) funds_2_0) 0) (<= (+ (select (|balances| state_1) this_0) funds_2_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935)) (and (>= funds_2_0 (|msg.value| tx_0)) (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (and (and (and (and (and (= (|msg.value| tx_0) 0) (= (|msg.sig| tx_0) 638722032)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 0) 38)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 1) 18)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 2) 31)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 3) 240)) (>= (|bytes_tuple_accessor_length| (|msg.data| tx_0)) 4))) (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true))))))) true) (summary_4_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_3)))) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (interface_0_C_16_0 this_0 abi_0 crypto_0 state_0) true) (and (summary_4_function_f__15_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (= error_0 0))) (interface_0_C_16_0 this_0 abi_0 crypto_0 state_1)))) +(=> (and (and (interface_0_C_16 this_0 abi_0 crypto_0 state_0) true) (and (summary_4_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (= error_0 0))) (interface_0_C_16 this_0 abi_0 crypto_0 state_1)))) -(declare-fun |contract_initializer_10_C_16_0| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) -(declare-fun |contract_initializer_entry_11_C_16_0| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) +(declare-fun |contract_initializer_10_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) +(declare-fun |contract_initializer_entry_11_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (= state_1 state_0) (= error_0 0)) true) (contract_initializer_entry_11_C_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) +(=> (and (and (= state_1 state_0) (= error_0 0)) true) (contract_initializer_entry_11_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) -(declare-fun |contract_initializer_after_init_12_C_16_0| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) +(declare-fun |contract_initializer_after_init_12_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (contract_initializer_entry_11_C_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) true) (contract_initializer_after_init_12_C_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) +(=> (and (and (contract_initializer_entry_11_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) true) (contract_initializer_after_init_12_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (contract_initializer_after_init_12_C_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) true) (contract_initializer_10_C_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) +(=> (and (and (contract_initializer_after_init_12_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) true) (contract_initializer_10_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) -(declare-fun |implicit_constructor_entry_13_C_16_0| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) +(declare-fun |implicit_constructor_entry_13_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true) (>= (select (|balances| state_1) this_0) (|msg.value| tx_0))) (implicit_constructor_entry_13_C_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) +(=> (and (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true) (>= (select (|balances| state_1) this_0) (|msg.value| tx_0))) (implicit_constructor_entry_13_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (implicit_constructor_entry_13_C_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (and (contract_initializer_10_C_16_0 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2) true)) (> error_1 0)) (summary_constructor_2_C_16_0 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_2)))) +(=> (and (and (implicit_constructor_entry_13_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (and (contract_initializer_10_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2) true)) (> error_1 0)) (summary_constructor_2_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_2)))) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (implicit_constructor_entry_13_C_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (and (= error_1 0) (and (contract_initializer_10_C_16_0 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2) true))) true) (summary_constructor_2_C_16_0 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_2)))) +(=> (and (and (implicit_constructor_entry_13_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (and (= error_1 0) (and (contract_initializer_10_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2) true))) true) (summary_constructor_2_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_2)))) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (summary_constructor_2_C_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (= (|msg.value| tx_0) 0)) (= error_0 0))) (interface_0_C_16_0 this_0 abi_0 crypto_0 state_1)))) +(=> (and (and (summary_constructor_2_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (= (|msg.value| tx_0) 0)) (= error_0 0))) (interface_0_C_16 this_0 abi_0 crypto_0 state_1)))) -(declare-fun |error_target_3_0| () Bool) +(declare-fun |error_target_3| () Bool) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (interface_0_C_16_0 this_0 abi_0 crypto_0 state_0) true) (and (summary_4_function_f__15_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (= error_0 1))) error_target_3_0))) +(=> (and (and (interface_0_C_16 this_0 abi_0 crypto_0 state_0) true) (and (summary_4_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (= error_0 1))) error_target_3))) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> error_target_3_0 false))) +(=> error_target_3 false))) (check-sat) diff --git a/test/cmdlineTests/model_checker_print_query_chc/err b/test/cmdlineTests/model_checker_print_query_chc/err index 1dd7f0c98828..4da0a7cb5a85 100644 --- a/test/cmdlineTests/model_checker_print_query_chc/err +++ b/test/cmdlineTests/model_checker_print_query_chc/err @@ -7,120 +7,120 @@ Info: CHC: Requested query: (declare-datatypes ((|crypto_type| 0)) (((|crypto_type| (|ecrecover| (Array |ecrecover_input_type| Int)) (|keccak256| (Array |bytes_tuple| Int)) (|ripemd160| (Array |bytes_tuple| Int)) (|sha256| (Array |bytes_tuple| Int)))))) (declare-datatypes ((|abi_type| 0)) (((|abi_type|)))) (declare-datatypes ((|state_type| 0)) (((|state_type| (|balances| (Array Int Int)))))) -(declare-fun |interface_0_C_16_0| (Int |abi_type| |crypto_type| |state_type| ) Bool) -(declare-fun |nondet_interface_1_C_16_0| (Int Int |abi_type| |crypto_type| |state_type| |state_type| ) Bool) -(declare-fun |summary_constructor_2_C_16_0| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) +(declare-fun |interface_0_C_16| (Int |abi_type| |crypto_type| |state_type| ) Bool) +(declare-fun |nondet_interface_1_C_16| (Int Int |abi_type| |crypto_type| |state_type| |state_type| ) Bool) +(declare-fun |summary_constructor_2_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (this_0 Int) (tx_0 |tx_type|)) -(=> (= error_0 0) (nondet_interface_1_C_16_0 error_0 this_0 abi_0 crypto_0 state_0 state_0)))) +(=> (= error_0 0) (nondet_interface_1_C_16 error_0 this_0 abi_0 crypto_0 state_0 state_0)))) -(declare-fun |summary_3_function_f__15_16_0| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) -(declare-fun |summary_4_function_f__15_16_0| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) +(declare-fun |summary_3_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) +(declare-fun |summary_4_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|)) -(=> (and (and (nondet_interface_1_C_16_0 error_0 this_0 abi_0 crypto_0 state_0 state_1) true) (and (= error_0 0) (summary_4_function_f__15_16_0 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2))) (nondet_interface_1_C_16_0 error_1 this_0 abi_0 crypto_0 state_0 state_2)))) +(=> (and (and (nondet_interface_1_C_16 error_0 this_0 abi_0 crypto_0 state_0 state_1) true) (and (= error_0 0) (summary_4_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2))) (nondet_interface_1_C_16 error_1 this_0 abi_0 crypto_0 state_0 state_2)))) -(declare-fun |block_5_function_f__15_16_0| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int ) Bool) -(declare-fun |block_6_f_14_16_0| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int ) Bool) +(declare-fun |block_5_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int ) Bool) +(declare-fun |block_6_f_14_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int ) Bool) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int)) -(block_5_function_f__15_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1))) +(block_5_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1))) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int)) -(=> (and (and (block_5_function_f__15_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true)) true) (block_6_f_14_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1)))) +(=> (and (and (block_5_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true)) true) (block_6_f_14_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1)))) -(declare-fun |block_7_return_function_f__15_16_0| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int ) Bool) -(declare-fun |block_8_function_f__15_16_0| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int ) Bool) +(declare-fun |block_7_return_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int ) Bool) +(declare-fun |block_8_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int ) Bool) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (block_6_f_14_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (= expr_11_1 (= expr_9_0 expr_10_0)) (and (=> true true) (and (= expr_10_0 0) (and (=> true (and (>= expr_9_0 0) (<= expr_9_0 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (= expr_9_0 x_5_2) (and (= x_5_2 expr_6_0) (and (=> true true) (and (= expr_6_0 0) (and (= x_5_1 0) true)))))))))) (and (and true (not expr_11_1)) (= error_1 1))) (block_8_function_f__15_16_0 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_2)))) +(=> (and (and (block_6_f_14_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (= expr_11_1 (= expr_9_0 expr_10_0)) (and (=> true true) (and (= expr_10_0 0) (and (=> true (and (>= expr_9_0 0) (<= expr_9_0 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (= expr_9_0 x_5_2) (and (= x_5_2 expr_6_0) (and (=> true true) (and (= expr_6_0 0) (and (= x_5_1 0) true)))))))))) (and (and true (not expr_11_1)) (= error_1 1))) (block_8_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_2)))) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (block_8_function_f__15_16_0 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_2) (summary_3_function_f__15_16_0 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) +(=> (block_8_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_2) (summary_3_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (block_6_f_14_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (= error_1 error_0) (and (= expr_11_1 (= expr_9_0 expr_10_0)) (and (=> true true) (and (= expr_10_0 0) (and (=> true (and (>= expr_9_0 0) (<= expr_9_0 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (= expr_9_0 x_5_2) (and (= x_5_2 expr_6_0) (and (=> true true) (and (= expr_6_0 0) (and (= x_5_1 0) true))))))))))) true) (block_7_return_function_f__15_16_0 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_2)))) +(=> (and (and (block_6_f_14_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (= error_1 error_0) (and (= expr_11_1 (= expr_9_0 expr_10_0)) (and (=> true true) (and (= expr_10_0 0) (and (=> true (and (>= expr_9_0 0) (<= expr_9_0 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (= expr_9_0 x_5_2) (and (= x_5_2 expr_6_0) (and (=> true true) (and (= expr_6_0 0) (and (= x_5_1 0) true))))))))))) true) (block_7_return_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_2)))) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (block_7_return_function_f__15_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) true) true) (summary_3_function_f__15_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) +(=> (and (and (block_7_return_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) true) true) (summary_3_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) -(declare-fun |block_9_function_f__15_16_0| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int ) Bool) +(declare-fun |block_9_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int ) Bool) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(block_9_function_f__15_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1))) +(block_9_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1))) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (block_9_function_f__15_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (summary_3_function_f__15_16_0 error_1 this_0 abi_0 crypto_0 tx_0 state_2 state_3) (and (= state_2 (|state_type| (store (|balances| state_1) this_0 (+ (select (|balances| state_1) this_0) funds_2_0)))) (and (and (>= (+ (select (|balances| state_1) this_0) funds_2_0) 0) (<= (+ (select (|balances| state_1) this_0) funds_2_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935)) (and (>= funds_2_0 (|msg.value| tx_0)) (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (and (and (and (and (and (= (|msg.value| tx_0) 0) (= (|msg.sig| tx_0) 638722032)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 0) 38)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 1) 18)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 2) 31)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 3) 240)) (>= (|bytes_tuple_accessor_length| (|msg.data| tx_0)) 4))) (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true))))))) true) (summary_4_function_f__15_16_0 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_3)))) +(=> (and (and (block_9_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (summary_3_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_2 state_3) (and (= state_2 (|state_type| (store (|balances| state_1) this_0 (+ (select (|balances| state_1) this_0) funds_2_0)))) (and (and (>= (+ (select (|balances| state_1) this_0) funds_2_0) 0) (<= (+ (select (|balances| state_1) this_0) funds_2_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935)) (and (>= funds_2_0 (|msg.value| tx_0)) (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (and (and (and (and (and (= (|msg.value| tx_0) 0) (= (|msg.sig| tx_0) 638722032)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 0) 38)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 1) 18)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 2) 31)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 3) 240)) (>= (|bytes_tuple_accessor_length| (|msg.data| tx_0)) 4))) (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true))))))) true) (summary_4_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_3)))) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (interface_0_C_16_0 this_0 abi_0 crypto_0 state_0) true) (and (summary_4_function_f__15_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (= error_0 0))) (interface_0_C_16_0 this_0 abi_0 crypto_0 state_1)))) +(=> (and (and (interface_0_C_16 this_0 abi_0 crypto_0 state_0) true) (and (summary_4_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (= error_0 0))) (interface_0_C_16 this_0 abi_0 crypto_0 state_1)))) -(declare-fun |contract_initializer_10_C_16_0| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) -(declare-fun |contract_initializer_entry_11_C_16_0| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) +(declare-fun |contract_initializer_10_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) +(declare-fun |contract_initializer_entry_11_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (= state_1 state_0) (= error_0 0)) true) (contract_initializer_entry_11_C_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) +(=> (and (and (= state_1 state_0) (= error_0 0)) true) (contract_initializer_entry_11_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) -(declare-fun |contract_initializer_after_init_12_C_16_0| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) +(declare-fun |contract_initializer_after_init_12_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (contract_initializer_entry_11_C_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) true) (contract_initializer_after_init_12_C_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) +(=> (and (and (contract_initializer_entry_11_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) true) (contract_initializer_after_init_12_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (contract_initializer_after_init_12_C_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) true) (contract_initializer_10_C_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) +(=> (and (and (contract_initializer_after_init_12_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) true) (contract_initializer_10_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) -(declare-fun |implicit_constructor_entry_13_C_16_0| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) +(declare-fun |implicit_constructor_entry_13_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true) (>= (select (|balances| state_1) this_0) (|msg.value| tx_0))) (implicit_constructor_entry_13_C_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) +(=> (and (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true) (>= (select (|balances| state_1) this_0) (|msg.value| tx_0))) (implicit_constructor_entry_13_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (implicit_constructor_entry_13_C_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (and (contract_initializer_10_C_16_0 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2) true)) (> error_1 0)) (summary_constructor_2_C_16_0 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_2)))) +(=> (and (and (implicit_constructor_entry_13_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (and (contract_initializer_10_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2) true)) (> error_1 0)) (summary_constructor_2_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_2)))) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (implicit_constructor_entry_13_C_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (and (= error_1 0) (and (contract_initializer_10_C_16_0 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2) true))) true) (summary_constructor_2_C_16_0 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_2)))) +(=> (and (and (implicit_constructor_entry_13_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (and (= error_1 0) (and (contract_initializer_10_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2) true))) true) (summary_constructor_2_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_2)))) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (summary_constructor_2_C_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (= (|msg.value| tx_0) 0)) (= error_0 0))) (interface_0_C_16_0 this_0 abi_0 crypto_0 state_1)))) +(=> (and (and (summary_constructor_2_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (= (|msg.value| tx_0) 0)) (= error_0 0))) (interface_0_C_16 this_0 abi_0 crypto_0 state_1)))) -(declare-fun |error_target_3_0| () Bool) +(declare-fun |error_target_3| () Bool) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (interface_0_C_16_0 this_0 abi_0 crypto_0 state_0) true) (and (summary_4_function_f__15_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (= error_0 1))) error_target_3_0))) +(=> (and (and (interface_0_C_16 this_0 abi_0 crypto_0 state_0) true) (and (summary_4_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (= error_0 1))) error_target_3))) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> error_target_3_0 false))) +(=> error_target_3 false))) (check-sat) diff --git a/test/cmdlineTests/standard_model_checker_invariants_reentrancy/output.json b/test/cmdlineTests/standard_model_checker_invariants_reentrancy/output.json index bf6b296cdfa3..760f1d7a75ad 100644 --- a/test/cmdlineTests/standard_model_checker_invariants_reentrancy/output.json +++ b/test/cmdlineTests/standard_model_checker_invariants_reentrancy/output.json @@ -33,14 +33,14 @@ "component": "general", "errorCode": "1180", "formattedMessage": "Info: Reentrancy property(ies) for A:test: -(((!(x <= 0) || !(x' >= 1)) && (!(x <= 0) || !( >= 1))) || true) +(((!(x <= 0) || !( >= 1)) && (!(x <= 0) || !(x' >= 1))) || true) = 0 -> no errors = 1 -> Assertion failed at assert(x < 10) ", "message": "Reentrancy property(ies) for A:test: -(((!(x <= 0) || !(x' >= 1)) && (!(x <= 0) || !( >= 1))) || true) +(((!(x <= 0) || !( >= 1)) && (!(x <= 0) || !(x' >= 1))) || true) = 0 -> no errors = 1 -> Assertion failed at assert(x < 10) ", diff --git a/test/cmdlineTests/standard_model_checker_print_query_all/output.json b/test/cmdlineTests/standard_model_checker_print_query_all/output.json index 97aa8857928b..4b5782de314b 100644 --- a/test/cmdlineTests/standard_model_checker_print_query_all/output.json +++ b/test/cmdlineTests/standard_model_checker_print_query_all/output.json @@ -1,7 +1,7 @@ { "auxiliaryInputRequested": { "smtlib2queries": { - "0x1880095c52d8681601c6821e4a5c29740649509af99947bce54102546dd3376a": "(set-option :timeout 1000) + "0xcbd85fe3127d1edfce70355ba6da5a3e9573873d8596ee8b1cfc2222af166628": "(set-option :timeout 1000) (set-logic HORN) (declare-datatypes ((|bytes_tuple| 0)) (((|bytes_tuple| (|bytes_tuple_accessor_array| (Array Int Int)) (|bytes_tuple_accessor_length| Int))))) (declare-datatypes ((|tx_type| 0)) (((|tx_type| (|block.basefee| Int) (|block.chainid| Int) (|block.coinbase| Int) (|block.gaslimit| Int) (|block.number| Int) (|block.prevrandao| Int) (|block.timestamp| Int) (|blockhash| (Array Int Int)) (|msg.data| |bytes_tuple|) (|msg.sender| Int) (|msg.sig| Int) (|msg.value| Int) (|tx.gasprice| Int) (|tx.origin| Int))))) @@ -9,120 +9,120 @@ (declare-datatypes ((|crypto_type| 0)) (((|crypto_type| (|ecrecover| (Array |ecrecover_input_type| Int)) (|keccak256| (Array |bytes_tuple| Int)) (|ripemd160| (Array |bytes_tuple| Int)) (|sha256| (Array |bytes_tuple| Int)))))) (declare-datatypes ((|abi_type| 0)) (((|abi_type|)))) (declare-datatypes ((|state_type| 0)) (((|state_type| (|balances| (Array Int Int)))))) -(declare-fun |interface_0_C_16_0| (Int |abi_type| |crypto_type| |state_type| ) Bool) -(declare-fun |nondet_interface_1_C_16_0| (Int Int |abi_type| |crypto_type| |state_type| |state_type| ) Bool) -(declare-fun |summary_constructor_2_C_16_0| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) +(declare-fun |interface_0_C_16| (Int |abi_type| |crypto_type| |state_type| ) Bool) +(declare-fun |nondet_interface_1_C_16| (Int Int |abi_type| |crypto_type| |state_type| |state_type| ) Bool) +(declare-fun |summary_constructor_2_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (this_0 Int) (tx_0 |tx_type|)) -(=> (= error_0 0) (nondet_interface_1_C_16_0 error_0 this_0 abi_0 crypto_0 state_0 state_0)))) +(=> (= error_0 0) (nondet_interface_1_C_16 error_0 this_0 abi_0 crypto_0 state_0 state_0)))) -(declare-fun |summary_3_function_f__15_16_0| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) -(declare-fun |summary_4_function_f__15_16_0| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) +(declare-fun |summary_3_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) +(declare-fun |summary_4_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|)) -(=> (and (and (nondet_interface_1_C_16_0 error_0 this_0 abi_0 crypto_0 state_0 state_1) true) (and (= error_0 0) (summary_4_function_f__15_16_0 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2))) (nondet_interface_1_C_16_0 error_1 this_0 abi_0 crypto_0 state_0 state_2)))) +(=> (and (and (nondet_interface_1_C_16 error_0 this_0 abi_0 crypto_0 state_0 state_1) true) (and (= error_0 0) (summary_4_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2))) (nondet_interface_1_C_16 error_1 this_0 abi_0 crypto_0 state_0 state_2)))) -(declare-fun |block_5_function_f__15_16_0| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int ) Bool) -(declare-fun |block_6_f_14_16_0| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int ) Bool) +(declare-fun |block_5_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int ) Bool) +(declare-fun |block_6_f_14_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int ) Bool) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int)) -(block_5_function_f__15_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1))) +(block_5_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1))) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int)) -(=> (and (and (block_5_function_f__15_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true)) true) (block_6_f_14_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1)))) +(=> (and (and (block_5_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true)) true) (block_6_f_14_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1)))) -(declare-fun |block_7_return_function_f__15_16_0| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int ) Bool) -(declare-fun |block_8_function_f__15_16_0| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int ) Bool) +(declare-fun |block_7_return_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int ) Bool) +(declare-fun |block_8_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int ) Bool) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (block_6_f_14_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (= expr_11_1 (= expr_9_0 expr_10_0)) (and (=> true true) (and (= expr_10_0 0) (and (=> true (and (>= expr_9_0 0) (<= expr_9_0 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (= expr_9_0 x_5_2) (and (= x_5_2 expr_6_0) (and (=> true true) (and (= expr_6_0 0) (and (= x_5_1 0) true)))))))))) (and (and true (not expr_11_1)) (= error_1 1))) (block_8_function_f__15_16_0 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_2)))) +(=> (and (and (block_6_f_14_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (= expr_11_1 (= expr_9_0 expr_10_0)) (and (=> true true) (and (= expr_10_0 0) (and (=> true (and (>= expr_9_0 0) (<= expr_9_0 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (= expr_9_0 x_5_2) (and (= x_5_2 expr_6_0) (and (=> true true) (and (= expr_6_0 0) (and (= x_5_1 0) true)))))))))) (and (and true (not expr_11_1)) (= error_1 1))) (block_8_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_2)))) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (block_8_function_f__15_16_0 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_2) (summary_3_function_f__15_16_0 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) +(=> (block_8_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_2) (summary_3_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (block_6_f_14_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (= error_1 error_0) (and (= expr_11_1 (= expr_9_0 expr_10_0)) (and (=> true true) (and (= expr_10_0 0) (and (=> true (and (>= expr_9_0 0) (<= expr_9_0 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (= expr_9_0 x_5_2) (and (= x_5_2 expr_6_0) (and (=> true true) (and (= expr_6_0 0) (and (= x_5_1 0) true))))))))))) true) (block_7_return_function_f__15_16_0 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_2)))) +(=> (and (and (block_6_f_14_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (= error_1 error_0) (and (= expr_11_1 (= expr_9_0 expr_10_0)) (and (=> true true) (and (= expr_10_0 0) (and (=> true (and (>= expr_9_0 0) (<= expr_9_0 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (= expr_9_0 x_5_2) (and (= x_5_2 expr_6_0) (and (=> true true) (and (= expr_6_0 0) (and (= x_5_1 0) true))))))))))) true) (block_7_return_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_2)))) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (block_7_return_function_f__15_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) true) true) (summary_3_function_f__15_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) +(=> (and (and (block_7_return_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) true) true) (summary_3_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) -(declare-fun |block_9_function_f__15_16_0| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int ) Bool) +(declare-fun |block_9_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int ) Bool) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(block_9_function_f__15_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1))) +(block_9_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1))) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (block_9_function_f__15_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (summary_3_function_f__15_16_0 error_1 this_0 abi_0 crypto_0 tx_0 state_2 state_3) (and (= state_2 (|state_type| (store (|balances| state_1) this_0 (+ (select (|balances| state_1) this_0) funds_2_0)))) (and (and (>= (+ (select (|balances| state_1) this_0) funds_2_0) 0) (<= (+ (select (|balances| state_1) this_0) funds_2_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935)) (and (>= funds_2_0 (|msg.value| tx_0)) (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (and (and (and (and (and (= (|msg.value| tx_0) 0) (= (|msg.sig| tx_0) 638722032)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 0) 38)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 1) 18)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 2) 31)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 3) 240)) (>= (|bytes_tuple_accessor_length| (|msg.data| tx_0)) 4))) (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true))))))) true) (summary_4_function_f__15_16_0 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_3)))) +(=> (and (and (block_9_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (summary_3_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_2 state_3) (and (= state_2 (|state_type| (store (|balances| state_1) this_0 (+ (select (|balances| state_1) this_0) funds_2_0)))) (and (and (>= (+ (select (|balances| state_1) this_0) funds_2_0) 0) (<= (+ (select (|balances| state_1) this_0) funds_2_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935)) (and (>= funds_2_0 (|msg.value| tx_0)) (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (and (and (and (and (and (= (|msg.value| tx_0) 0) (= (|msg.sig| tx_0) 638722032)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 0) 38)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 1) 18)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 2) 31)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 3) 240)) (>= (|bytes_tuple_accessor_length| (|msg.data| tx_0)) 4))) (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true))))))) true) (summary_4_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_3)))) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (interface_0_C_16_0 this_0 abi_0 crypto_0 state_0) true) (and (summary_4_function_f__15_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (= error_0 0))) (interface_0_C_16_0 this_0 abi_0 crypto_0 state_1)))) +(=> (and (and (interface_0_C_16 this_0 abi_0 crypto_0 state_0) true) (and (summary_4_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (= error_0 0))) (interface_0_C_16 this_0 abi_0 crypto_0 state_1)))) -(declare-fun |contract_initializer_10_C_16_0| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) -(declare-fun |contract_initializer_entry_11_C_16_0| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) +(declare-fun |contract_initializer_10_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) +(declare-fun |contract_initializer_entry_11_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (= state_1 state_0) (= error_0 0)) true) (contract_initializer_entry_11_C_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) +(=> (and (and (= state_1 state_0) (= error_0 0)) true) (contract_initializer_entry_11_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) -(declare-fun |contract_initializer_after_init_12_C_16_0| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) +(declare-fun |contract_initializer_after_init_12_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (contract_initializer_entry_11_C_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) true) (contract_initializer_after_init_12_C_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) +(=> (and (and (contract_initializer_entry_11_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) true) (contract_initializer_after_init_12_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (contract_initializer_after_init_12_C_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) true) (contract_initializer_10_C_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) +(=> (and (and (contract_initializer_after_init_12_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) true) (contract_initializer_10_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) -(declare-fun |implicit_constructor_entry_13_C_16_0| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) +(declare-fun |implicit_constructor_entry_13_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true) (>= (select (|balances| state_1) this_0) (|msg.value| tx_0))) (implicit_constructor_entry_13_C_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) +(=> (and (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true) (>= (select (|balances| state_1) this_0) (|msg.value| tx_0))) (implicit_constructor_entry_13_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (implicit_constructor_entry_13_C_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (and (contract_initializer_10_C_16_0 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2) true)) (> error_1 0)) (summary_constructor_2_C_16_0 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_2)))) +(=> (and (and (implicit_constructor_entry_13_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (and (contract_initializer_10_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2) true)) (> error_1 0)) (summary_constructor_2_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_2)))) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (implicit_constructor_entry_13_C_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (and (= error_1 0) (and (contract_initializer_10_C_16_0 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2) true))) true) (summary_constructor_2_C_16_0 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_2)))) +(=> (and (and (implicit_constructor_entry_13_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (and (= error_1 0) (and (contract_initializer_10_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2) true))) true) (summary_constructor_2_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_2)))) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (summary_constructor_2_C_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (= (|msg.value| tx_0) 0)) (= error_0 0))) (interface_0_C_16_0 this_0 abi_0 crypto_0 state_1)))) +(=> (and (and (summary_constructor_2_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (= (|msg.value| tx_0) 0)) (= error_0 0))) (interface_0_C_16 this_0 abi_0 crypto_0 state_1)))) -(declare-fun |error_target_3_0| () Bool) +(declare-fun |error_target_3| () Bool) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (interface_0_C_16_0 this_0 abi_0 crypto_0 state_0) true) (and (summary_4_function_f__15_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (= error_0 1))) error_target_3_0))) +(=> (and (and (interface_0_C_16 this_0 abi_0 crypto_0 state_0) true) (and (summary_4_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (= error_0 1))) error_target_3))) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> error_target_3_0 false))) +(=> error_target_3 false))) (check-sat) ", "0xcbfcc2413b217c6564ee01f322c9ca1f34fd79d19961dc3e62aa9c2e5dcb6efc": "(set-option :produce-models true) @@ -170,120 +170,120 @@ (declare-datatypes ((|crypto_type| 0)) (((|crypto_type| (|ecrecover| (Array |ecrecover_input_type| Int)) (|keccak256| (Array |bytes_tuple| Int)) (|ripemd160| (Array |bytes_tuple| Int)) (|sha256| (Array |bytes_tuple| Int)))))) (declare-datatypes ((|abi_type| 0)) (((|abi_type|)))) (declare-datatypes ((|state_type| 0)) (((|state_type| (|balances| (Array Int Int)))))) -(declare-fun |interface_0_C_16_0| (Int |abi_type| |crypto_type| |state_type| ) Bool) -(declare-fun |nondet_interface_1_C_16_0| (Int Int |abi_type| |crypto_type| |state_type| |state_type| ) Bool) -(declare-fun |summary_constructor_2_C_16_0| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) +(declare-fun |interface_0_C_16| (Int |abi_type| |crypto_type| |state_type| ) Bool) +(declare-fun |nondet_interface_1_C_16| (Int Int |abi_type| |crypto_type| |state_type| |state_type| ) Bool) +(declare-fun |summary_constructor_2_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (this_0 Int) (tx_0 |tx_type|)) -(=> (= error_0 0) (nondet_interface_1_C_16_0 error_0 this_0 abi_0 crypto_0 state_0 state_0)))) +(=> (= error_0 0) (nondet_interface_1_C_16 error_0 this_0 abi_0 crypto_0 state_0 state_0)))) -(declare-fun |summary_3_function_f__15_16_0| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) -(declare-fun |summary_4_function_f__15_16_0| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) +(declare-fun |summary_3_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) +(declare-fun |summary_4_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|)) -(=> (and (and (nondet_interface_1_C_16_0 error_0 this_0 abi_0 crypto_0 state_0 state_1) true) (and (= error_0 0) (summary_4_function_f__15_16_0 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2))) (nondet_interface_1_C_16_0 error_1 this_0 abi_0 crypto_0 state_0 state_2)))) +(=> (and (and (nondet_interface_1_C_16 error_0 this_0 abi_0 crypto_0 state_0 state_1) true) (and (= error_0 0) (summary_4_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2))) (nondet_interface_1_C_16 error_1 this_0 abi_0 crypto_0 state_0 state_2)))) -(declare-fun |block_5_function_f__15_16_0| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int ) Bool) -(declare-fun |block_6_f_14_16_0| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int ) Bool) +(declare-fun |block_5_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int ) Bool) +(declare-fun |block_6_f_14_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int ) Bool) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int)) -(block_5_function_f__15_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1))) +(block_5_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1))) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int)) -(=> (and (and (block_5_function_f__15_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true)) true) (block_6_f_14_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1)))) +(=> (and (and (block_5_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true)) true) (block_6_f_14_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1)))) -(declare-fun |block_7_return_function_f__15_16_0| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int ) Bool) -(declare-fun |block_8_function_f__15_16_0| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int ) Bool) +(declare-fun |block_7_return_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int ) Bool) +(declare-fun |block_8_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int ) Bool) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (block_6_f_14_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (= expr_11_1 (= expr_9_0 expr_10_0)) (and (=> true true) (and (= expr_10_0 0) (and (=> true (and (>= expr_9_0 0) (<= expr_9_0 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (= expr_9_0 x_5_2) (and (= x_5_2 expr_6_0) (and (=> true true) (and (= expr_6_0 0) (and (= x_5_1 0) true)))))))))) (and (and true (not expr_11_1)) (= error_1 1))) (block_8_function_f__15_16_0 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_2)))) +(=> (and (and (block_6_f_14_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (= expr_11_1 (= expr_9_0 expr_10_0)) (and (=> true true) (and (= expr_10_0 0) (and (=> true (and (>= expr_9_0 0) (<= expr_9_0 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (= expr_9_0 x_5_2) (and (= x_5_2 expr_6_0) (and (=> true true) (and (= expr_6_0 0) (and (= x_5_1 0) true)))))))))) (and (and true (not expr_11_1)) (= error_1 1))) (block_8_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_2)))) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (block_8_function_f__15_16_0 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_2) (summary_3_function_f__15_16_0 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) +(=> (block_8_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_2) (summary_3_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (block_6_f_14_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (= error_1 error_0) (and (= expr_11_1 (= expr_9_0 expr_10_0)) (and (=> true true) (and (= expr_10_0 0) (and (=> true (and (>= expr_9_0 0) (<= expr_9_0 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (= expr_9_0 x_5_2) (and (= x_5_2 expr_6_0) (and (=> true true) (and (= expr_6_0 0) (and (= x_5_1 0) true))))))))))) true) (block_7_return_function_f__15_16_0 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_2)))) +(=> (and (and (block_6_f_14_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (= error_1 error_0) (and (= expr_11_1 (= expr_9_0 expr_10_0)) (and (=> true true) (and (= expr_10_0 0) (and (=> true (and (>= expr_9_0 0) (<= expr_9_0 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (= expr_9_0 x_5_2) (and (= x_5_2 expr_6_0) (and (=> true true) (and (= expr_6_0 0) (and (= x_5_1 0) true))))))))))) true) (block_7_return_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_2)))) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (block_7_return_function_f__15_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) true) true) (summary_3_function_f__15_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) +(=> (and (and (block_7_return_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) true) true) (summary_3_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) -(declare-fun |block_9_function_f__15_16_0| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int ) Bool) +(declare-fun |block_9_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int ) Bool) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(block_9_function_f__15_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1))) +(block_9_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1))) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (block_9_function_f__15_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (summary_3_function_f__15_16_0 error_1 this_0 abi_0 crypto_0 tx_0 state_2 state_3) (and (= state_2 (|state_type| (store (|balances| state_1) this_0 (+ (select (|balances| state_1) this_0) funds_2_0)))) (and (and (>= (+ (select (|balances| state_1) this_0) funds_2_0) 0) (<= (+ (select (|balances| state_1) this_0) funds_2_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935)) (and (>= funds_2_0 (|msg.value| tx_0)) (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (and (and (and (and (and (= (|msg.value| tx_0) 0) (= (|msg.sig| tx_0) 638722032)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 0) 38)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 1) 18)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 2) 31)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 3) 240)) (>= (|bytes_tuple_accessor_length| (|msg.data| tx_0)) 4))) (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true))))))) true) (summary_4_function_f__15_16_0 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_3)))) +(=> (and (and (block_9_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (summary_3_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_2 state_3) (and (= state_2 (|state_type| (store (|balances| state_1) this_0 (+ (select (|balances| state_1) this_0) funds_2_0)))) (and (and (>= (+ (select (|balances| state_1) this_0) funds_2_0) 0) (<= (+ (select (|balances| state_1) this_0) funds_2_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935)) (and (>= funds_2_0 (|msg.value| tx_0)) (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (and (and (and (and (and (= (|msg.value| tx_0) 0) (= (|msg.sig| tx_0) 638722032)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 0) 38)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 1) 18)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 2) 31)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 3) 240)) (>= (|bytes_tuple_accessor_length| (|msg.data| tx_0)) 4))) (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true))))))) true) (summary_4_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_3)))) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (interface_0_C_16_0 this_0 abi_0 crypto_0 state_0) true) (and (summary_4_function_f__15_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (= error_0 0))) (interface_0_C_16_0 this_0 abi_0 crypto_0 state_1)))) +(=> (and (and (interface_0_C_16 this_0 abi_0 crypto_0 state_0) true) (and (summary_4_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (= error_0 0))) (interface_0_C_16 this_0 abi_0 crypto_0 state_1)))) -(declare-fun |contract_initializer_10_C_16_0| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) -(declare-fun |contract_initializer_entry_11_C_16_0| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) +(declare-fun |contract_initializer_10_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) +(declare-fun |contract_initializer_entry_11_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (= state_1 state_0) (= error_0 0)) true) (contract_initializer_entry_11_C_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) +(=> (and (and (= state_1 state_0) (= error_0 0)) true) (contract_initializer_entry_11_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) -(declare-fun |contract_initializer_after_init_12_C_16_0| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) +(declare-fun |contract_initializer_after_init_12_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (contract_initializer_entry_11_C_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) true) (contract_initializer_after_init_12_C_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) +(=> (and (and (contract_initializer_entry_11_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) true) (contract_initializer_after_init_12_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (contract_initializer_after_init_12_C_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) true) (contract_initializer_10_C_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) +(=> (and (and (contract_initializer_after_init_12_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) true) (contract_initializer_10_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) -(declare-fun |implicit_constructor_entry_13_C_16_0| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) +(declare-fun |implicit_constructor_entry_13_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true) (>= (select (|balances| state_1) this_0) (|msg.value| tx_0))) (implicit_constructor_entry_13_C_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) +(=> (and (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true) (>= (select (|balances| state_1) this_0) (|msg.value| tx_0))) (implicit_constructor_entry_13_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (implicit_constructor_entry_13_C_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (and (contract_initializer_10_C_16_0 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2) true)) (> error_1 0)) (summary_constructor_2_C_16_0 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_2)))) +(=> (and (and (implicit_constructor_entry_13_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (and (contract_initializer_10_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2) true)) (> error_1 0)) (summary_constructor_2_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_2)))) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (implicit_constructor_entry_13_C_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (and (= error_1 0) (and (contract_initializer_10_C_16_0 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2) true))) true) (summary_constructor_2_C_16_0 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_2)))) +(=> (and (and (implicit_constructor_entry_13_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (and (= error_1 0) (and (contract_initializer_10_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2) true))) true) (summary_constructor_2_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_2)))) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (summary_constructor_2_C_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (= (|msg.value| tx_0) 0)) (= error_0 0))) (interface_0_C_16_0 this_0 abi_0 crypto_0 state_1)))) +(=> (and (and (summary_constructor_2_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (= (|msg.value| tx_0) 0)) (= error_0 0))) (interface_0_C_16 this_0 abi_0 crypto_0 state_1)))) -(declare-fun |error_target_3_0| () Bool) +(declare-fun |error_target_3| () Bool) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (interface_0_C_16_0 this_0 abi_0 crypto_0 state_0) true) (and (summary_4_function_f__15_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (= error_0 1))) error_target_3_0))) +(=> (and (and (interface_0_C_16 this_0 abi_0 crypto_0 state_0) true) (and (summary_4_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (= error_0 1))) error_target_3))) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> error_target_3_0 false))) +(=> error_target_3 false))) (check-sat) @@ -297,120 +297,120 @@ (declare-datatypes ((|crypto_type| 0)) (((|crypto_type| (|ecrecover| (Array |ecrecover_input_type| Int)) (|keccak256| (Array |bytes_tuple| Int)) (|ripemd160| (Array |bytes_tuple| Int)) (|sha256| (Array |bytes_tuple| Int)))))) (declare-datatypes ((|abi_type| 0)) (((|abi_type|)))) (declare-datatypes ((|state_type| 0)) (((|state_type| (|balances| (Array Int Int)))))) -(declare-fun |interface_0_C_16_0| (Int |abi_type| |crypto_type| |state_type| ) Bool) -(declare-fun |nondet_interface_1_C_16_0| (Int Int |abi_type| |crypto_type| |state_type| |state_type| ) Bool) -(declare-fun |summary_constructor_2_C_16_0| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) +(declare-fun |interface_0_C_16| (Int |abi_type| |crypto_type| |state_type| ) Bool) +(declare-fun |nondet_interface_1_C_16| (Int Int |abi_type| |crypto_type| |state_type| |state_type| ) Bool) +(declare-fun |summary_constructor_2_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (this_0 Int) (tx_0 |tx_type|)) -(=> (= error_0 0) (nondet_interface_1_C_16_0 error_0 this_0 abi_0 crypto_0 state_0 state_0)))) +(=> (= error_0 0) (nondet_interface_1_C_16 error_0 this_0 abi_0 crypto_0 state_0 state_0)))) -(declare-fun |summary_3_function_f__15_16_0| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) -(declare-fun |summary_4_function_f__15_16_0| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) +(declare-fun |summary_3_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) +(declare-fun |summary_4_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|)) -(=> (and (and (nondet_interface_1_C_16_0 error_0 this_0 abi_0 crypto_0 state_0 state_1) true) (and (= error_0 0) (summary_4_function_f__15_16_0 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2))) (nondet_interface_1_C_16_0 error_1 this_0 abi_0 crypto_0 state_0 state_2)))) +(=> (and (and (nondet_interface_1_C_16 error_0 this_0 abi_0 crypto_0 state_0 state_1) true) (and (= error_0 0) (summary_4_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2))) (nondet_interface_1_C_16 error_1 this_0 abi_0 crypto_0 state_0 state_2)))) -(declare-fun |block_5_function_f__15_16_0| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int ) Bool) -(declare-fun |block_6_f_14_16_0| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int ) Bool) +(declare-fun |block_5_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int ) Bool) +(declare-fun |block_6_f_14_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int ) Bool) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int)) -(block_5_function_f__15_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1))) +(block_5_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1))) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int)) -(=> (and (and (block_5_function_f__15_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true)) true) (block_6_f_14_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1)))) +(=> (and (and (block_5_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true)) true) (block_6_f_14_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1)))) -(declare-fun |block_7_return_function_f__15_16_0| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int ) Bool) -(declare-fun |block_8_function_f__15_16_0| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int ) Bool) +(declare-fun |block_7_return_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int ) Bool) +(declare-fun |block_8_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int ) Bool) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (block_6_f_14_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (= expr_11_1 (= expr_9_0 expr_10_0)) (and (=> true true) (and (= expr_10_0 0) (and (=> true (and (>= expr_9_0 0) (<= expr_9_0 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (= expr_9_0 x_5_2) (and (= x_5_2 expr_6_0) (and (=> true true) (and (= expr_6_0 0) (and (= x_5_1 0) true)))))))))) (and (and true (not expr_11_1)) (= error_1 1))) (block_8_function_f__15_16_0 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_2)))) +(=> (and (and (block_6_f_14_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (= expr_11_1 (= expr_9_0 expr_10_0)) (and (=> true true) (and (= expr_10_0 0) (and (=> true (and (>= expr_9_0 0) (<= expr_9_0 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (= expr_9_0 x_5_2) (and (= x_5_2 expr_6_0) (and (=> true true) (and (= expr_6_0 0) (and (= x_5_1 0) true)))))))))) (and (and true (not expr_11_1)) (= error_1 1))) (block_8_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_2)))) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (block_8_function_f__15_16_0 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_2) (summary_3_function_f__15_16_0 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) +(=> (block_8_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_2) (summary_3_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (block_6_f_14_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (= error_1 error_0) (and (= expr_11_1 (= expr_9_0 expr_10_0)) (and (=> true true) (and (= expr_10_0 0) (and (=> true (and (>= expr_9_0 0) (<= expr_9_0 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (= expr_9_0 x_5_2) (and (= x_5_2 expr_6_0) (and (=> true true) (and (= expr_6_0 0) (and (= x_5_1 0) true))))))))))) true) (block_7_return_function_f__15_16_0 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_2)))) +(=> (and (and (block_6_f_14_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (= error_1 error_0) (and (= expr_11_1 (= expr_9_0 expr_10_0)) (and (=> true true) (and (= expr_10_0 0) (and (=> true (and (>= expr_9_0 0) (<= expr_9_0 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (= expr_9_0 x_5_2) (and (= x_5_2 expr_6_0) (and (=> true true) (and (= expr_6_0 0) (and (= x_5_1 0) true))))))))))) true) (block_7_return_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_2)))) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (block_7_return_function_f__15_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) true) true) (summary_3_function_f__15_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) +(=> (and (and (block_7_return_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) true) true) (summary_3_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) -(declare-fun |block_9_function_f__15_16_0| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int ) Bool) +(declare-fun |block_9_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int ) Bool) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(block_9_function_f__15_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1))) +(block_9_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1))) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (block_9_function_f__15_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (summary_3_function_f__15_16_0 error_1 this_0 abi_0 crypto_0 tx_0 state_2 state_3) (and (= state_2 (|state_type| (store (|balances| state_1) this_0 (+ (select (|balances| state_1) this_0) funds_2_0)))) (and (and (>= (+ (select (|balances| state_1) this_0) funds_2_0) 0) (<= (+ (select (|balances| state_1) this_0) funds_2_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935)) (and (>= funds_2_0 (|msg.value| tx_0)) (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (and (and (and (and (and (= (|msg.value| tx_0) 0) (= (|msg.sig| tx_0) 638722032)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 0) 38)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 1) 18)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 2) 31)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 3) 240)) (>= (|bytes_tuple_accessor_length| (|msg.data| tx_0)) 4))) (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true))))))) true) (summary_4_function_f__15_16_0 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_3)))) +(=> (and (and (block_9_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (summary_3_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_2 state_3) (and (= state_2 (|state_type| (store (|balances| state_1) this_0 (+ (select (|balances| state_1) this_0) funds_2_0)))) (and (and (>= (+ (select (|balances| state_1) this_0) funds_2_0) 0) (<= (+ (select (|balances| state_1) this_0) funds_2_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935)) (and (>= funds_2_0 (|msg.value| tx_0)) (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (and (and (and (and (and (= (|msg.value| tx_0) 0) (= (|msg.sig| tx_0) 638722032)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 0) 38)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 1) 18)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 2) 31)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 3) 240)) (>= (|bytes_tuple_accessor_length| (|msg.data| tx_0)) 4))) (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true))))))) true) (summary_4_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_3)))) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (interface_0_C_16_0 this_0 abi_0 crypto_0 state_0) true) (and (summary_4_function_f__15_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (= error_0 0))) (interface_0_C_16_0 this_0 abi_0 crypto_0 state_1)))) +(=> (and (and (interface_0_C_16 this_0 abi_0 crypto_0 state_0) true) (and (summary_4_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (= error_0 0))) (interface_0_C_16 this_0 abi_0 crypto_0 state_1)))) -(declare-fun |contract_initializer_10_C_16_0| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) -(declare-fun |contract_initializer_entry_11_C_16_0| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) +(declare-fun |contract_initializer_10_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) +(declare-fun |contract_initializer_entry_11_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (= state_1 state_0) (= error_0 0)) true) (contract_initializer_entry_11_C_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) +(=> (and (and (= state_1 state_0) (= error_0 0)) true) (contract_initializer_entry_11_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) -(declare-fun |contract_initializer_after_init_12_C_16_0| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) +(declare-fun |contract_initializer_after_init_12_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (contract_initializer_entry_11_C_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) true) (contract_initializer_after_init_12_C_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) +(=> (and (and (contract_initializer_entry_11_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) true) (contract_initializer_after_init_12_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (contract_initializer_after_init_12_C_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) true) (contract_initializer_10_C_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) +(=> (and (and (contract_initializer_after_init_12_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) true) (contract_initializer_10_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) -(declare-fun |implicit_constructor_entry_13_C_16_0| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) +(declare-fun |implicit_constructor_entry_13_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true) (>= (select (|balances| state_1) this_0) (|msg.value| tx_0))) (implicit_constructor_entry_13_C_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) +(=> (and (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true) (>= (select (|balances| state_1) this_0) (|msg.value| tx_0))) (implicit_constructor_entry_13_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (implicit_constructor_entry_13_C_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (and (contract_initializer_10_C_16_0 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2) true)) (> error_1 0)) (summary_constructor_2_C_16_0 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_2)))) +(=> (and (and (implicit_constructor_entry_13_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (and (contract_initializer_10_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2) true)) (> error_1 0)) (summary_constructor_2_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_2)))) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (implicit_constructor_entry_13_C_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (and (= error_1 0) (and (contract_initializer_10_C_16_0 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2) true))) true) (summary_constructor_2_C_16_0 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_2)))) +(=> (and (and (implicit_constructor_entry_13_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (and (= error_1 0) (and (contract_initializer_10_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2) true))) true) (summary_constructor_2_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_2)))) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (summary_constructor_2_C_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (= (|msg.value| tx_0) 0)) (= error_0 0))) (interface_0_C_16_0 this_0 abi_0 crypto_0 state_1)))) +(=> (and (and (summary_constructor_2_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (= (|msg.value| tx_0) 0)) (= error_0 0))) (interface_0_C_16 this_0 abi_0 crypto_0 state_1)))) -(declare-fun |error_target_3_0| () Bool) +(declare-fun |error_target_3| () Bool) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (interface_0_C_16_0 this_0 abi_0 crypto_0 state_0) true) (and (summary_4_function_f__15_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (= error_0 1))) error_target_3_0))) +(=> (and (and (interface_0_C_16 this_0 abi_0 crypto_0 state_0) true) (and (summary_4_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (= error_0 1))) error_target_3))) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> error_target_3_0 false))) +(=> error_target_3 false))) (check-sat) ", "severity": "info", diff --git a/test/cmdlineTests/standard_model_checker_print_query_chc/output.json b/test/cmdlineTests/standard_model_checker_print_query_chc/output.json index a9b0df0fb687..a9956d82b0e3 100644 --- a/test/cmdlineTests/standard_model_checker_print_query_chc/output.json +++ b/test/cmdlineTests/standard_model_checker_print_query_chc/output.json @@ -1,7 +1,7 @@ { "auxiliaryInputRequested": { "smtlib2queries": { - "0x1880095c52d8681601c6821e4a5c29740649509af99947bce54102546dd3376a": "(set-option :timeout 1000) + "0xcbd85fe3127d1edfce70355ba6da5a3e9573873d8596ee8b1cfc2222af166628": "(set-option :timeout 1000) (set-logic HORN) (declare-datatypes ((|bytes_tuple| 0)) (((|bytes_tuple| (|bytes_tuple_accessor_array| (Array Int Int)) (|bytes_tuple_accessor_length| Int))))) (declare-datatypes ((|tx_type| 0)) (((|tx_type| (|block.basefee| Int) (|block.chainid| Int) (|block.coinbase| Int) (|block.gaslimit| Int) (|block.number| Int) (|block.prevrandao| Int) (|block.timestamp| Int) (|blockhash| (Array Int Int)) (|msg.data| |bytes_tuple|) (|msg.sender| Int) (|msg.sig| Int) (|msg.value| Int) (|tx.gasprice| Int) (|tx.origin| Int))))) @@ -9,120 +9,120 @@ (declare-datatypes ((|crypto_type| 0)) (((|crypto_type| (|ecrecover| (Array |ecrecover_input_type| Int)) (|keccak256| (Array |bytes_tuple| Int)) (|ripemd160| (Array |bytes_tuple| Int)) (|sha256| (Array |bytes_tuple| Int)))))) (declare-datatypes ((|abi_type| 0)) (((|abi_type|)))) (declare-datatypes ((|state_type| 0)) (((|state_type| (|balances| (Array Int Int)))))) -(declare-fun |interface_0_C_16_0| (Int |abi_type| |crypto_type| |state_type| ) Bool) -(declare-fun |nondet_interface_1_C_16_0| (Int Int |abi_type| |crypto_type| |state_type| |state_type| ) Bool) -(declare-fun |summary_constructor_2_C_16_0| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) +(declare-fun |interface_0_C_16| (Int |abi_type| |crypto_type| |state_type| ) Bool) +(declare-fun |nondet_interface_1_C_16| (Int Int |abi_type| |crypto_type| |state_type| |state_type| ) Bool) +(declare-fun |summary_constructor_2_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (this_0 Int) (tx_0 |tx_type|)) -(=> (= error_0 0) (nondet_interface_1_C_16_0 error_0 this_0 abi_0 crypto_0 state_0 state_0)))) +(=> (= error_0 0) (nondet_interface_1_C_16 error_0 this_0 abi_0 crypto_0 state_0 state_0)))) -(declare-fun |summary_3_function_f__15_16_0| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) -(declare-fun |summary_4_function_f__15_16_0| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) +(declare-fun |summary_3_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) +(declare-fun |summary_4_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|)) -(=> (and (and (nondet_interface_1_C_16_0 error_0 this_0 abi_0 crypto_0 state_0 state_1) true) (and (= error_0 0) (summary_4_function_f__15_16_0 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2))) (nondet_interface_1_C_16_0 error_1 this_0 abi_0 crypto_0 state_0 state_2)))) +(=> (and (and (nondet_interface_1_C_16 error_0 this_0 abi_0 crypto_0 state_0 state_1) true) (and (= error_0 0) (summary_4_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2))) (nondet_interface_1_C_16 error_1 this_0 abi_0 crypto_0 state_0 state_2)))) -(declare-fun |block_5_function_f__15_16_0| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int ) Bool) -(declare-fun |block_6_f_14_16_0| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int ) Bool) +(declare-fun |block_5_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int ) Bool) +(declare-fun |block_6_f_14_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int ) Bool) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int)) -(block_5_function_f__15_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1))) +(block_5_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1))) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int)) -(=> (and (and (block_5_function_f__15_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true)) true) (block_6_f_14_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1)))) +(=> (and (and (block_5_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true)) true) (block_6_f_14_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1)))) -(declare-fun |block_7_return_function_f__15_16_0| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int ) Bool) -(declare-fun |block_8_function_f__15_16_0| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int ) Bool) +(declare-fun |block_7_return_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int ) Bool) +(declare-fun |block_8_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int ) Bool) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (block_6_f_14_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (= expr_11_1 (= expr_9_0 expr_10_0)) (and (=> true true) (and (= expr_10_0 0) (and (=> true (and (>= expr_9_0 0) (<= expr_9_0 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (= expr_9_0 x_5_2) (and (= x_5_2 expr_6_0) (and (=> true true) (and (= expr_6_0 0) (and (= x_5_1 0) true)))))))))) (and (and true (not expr_11_1)) (= error_1 1))) (block_8_function_f__15_16_0 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_2)))) +(=> (and (and (block_6_f_14_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (= expr_11_1 (= expr_9_0 expr_10_0)) (and (=> true true) (and (= expr_10_0 0) (and (=> true (and (>= expr_9_0 0) (<= expr_9_0 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (= expr_9_0 x_5_2) (and (= x_5_2 expr_6_0) (and (=> true true) (and (= expr_6_0 0) (and (= x_5_1 0) true)))))))))) (and (and true (not expr_11_1)) (= error_1 1))) (block_8_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_2)))) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (block_8_function_f__15_16_0 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_2) (summary_3_function_f__15_16_0 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) +(=> (block_8_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_2) (summary_3_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (block_6_f_14_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (= error_1 error_0) (and (= expr_11_1 (= expr_9_0 expr_10_0)) (and (=> true true) (and (= expr_10_0 0) (and (=> true (and (>= expr_9_0 0) (<= expr_9_0 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (= expr_9_0 x_5_2) (and (= x_5_2 expr_6_0) (and (=> true true) (and (= expr_6_0 0) (and (= x_5_1 0) true))))))))))) true) (block_7_return_function_f__15_16_0 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_2)))) +(=> (and (and (block_6_f_14_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (= error_1 error_0) (and (= expr_11_1 (= expr_9_0 expr_10_0)) (and (=> true true) (and (= expr_10_0 0) (and (=> true (and (>= expr_9_0 0) (<= expr_9_0 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (= expr_9_0 x_5_2) (and (= x_5_2 expr_6_0) (and (=> true true) (and (= expr_6_0 0) (and (= x_5_1 0) true))))))))))) true) (block_7_return_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_2)))) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (block_7_return_function_f__15_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) true) true) (summary_3_function_f__15_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) +(=> (and (and (block_7_return_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) true) true) (summary_3_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) -(declare-fun |block_9_function_f__15_16_0| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int ) Bool) +(declare-fun |block_9_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int ) Bool) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(block_9_function_f__15_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1))) +(block_9_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1))) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (block_9_function_f__15_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (summary_3_function_f__15_16_0 error_1 this_0 abi_0 crypto_0 tx_0 state_2 state_3) (and (= state_2 (|state_type| (store (|balances| state_1) this_0 (+ (select (|balances| state_1) this_0) funds_2_0)))) (and (and (>= (+ (select (|balances| state_1) this_0) funds_2_0) 0) (<= (+ (select (|balances| state_1) this_0) funds_2_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935)) (and (>= funds_2_0 (|msg.value| tx_0)) (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (and (and (and (and (and (= (|msg.value| tx_0) 0) (= (|msg.sig| tx_0) 638722032)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 0) 38)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 1) 18)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 2) 31)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 3) 240)) (>= (|bytes_tuple_accessor_length| (|msg.data| tx_0)) 4))) (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true))))))) true) (summary_4_function_f__15_16_0 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_3)))) +(=> (and (and (block_9_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (summary_3_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_2 state_3) (and (= state_2 (|state_type| (store (|balances| state_1) this_0 (+ (select (|balances| state_1) this_0) funds_2_0)))) (and (and (>= (+ (select (|balances| state_1) this_0) funds_2_0) 0) (<= (+ (select (|balances| state_1) this_0) funds_2_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935)) (and (>= funds_2_0 (|msg.value| tx_0)) (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (and (and (and (and (and (= (|msg.value| tx_0) 0) (= (|msg.sig| tx_0) 638722032)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 0) 38)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 1) 18)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 2) 31)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 3) 240)) (>= (|bytes_tuple_accessor_length| (|msg.data| tx_0)) 4))) (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true))))))) true) (summary_4_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_3)))) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (interface_0_C_16_0 this_0 abi_0 crypto_0 state_0) true) (and (summary_4_function_f__15_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (= error_0 0))) (interface_0_C_16_0 this_0 abi_0 crypto_0 state_1)))) +(=> (and (and (interface_0_C_16 this_0 abi_0 crypto_0 state_0) true) (and (summary_4_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (= error_0 0))) (interface_0_C_16 this_0 abi_0 crypto_0 state_1)))) -(declare-fun |contract_initializer_10_C_16_0| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) -(declare-fun |contract_initializer_entry_11_C_16_0| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) +(declare-fun |contract_initializer_10_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) +(declare-fun |contract_initializer_entry_11_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (= state_1 state_0) (= error_0 0)) true) (contract_initializer_entry_11_C_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) +(=> (and (and (= state_1 state_0) (= error_0 0)) true) (contract_initializer_entry_11_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) -(declare-fun |contract_initializer_after_init_12_C_16_0| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) +(declare-fun |contract_initializer_after_init_12_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (contract_initializer_entry_11_C_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) true) (contract_initializer_after_init_12_C_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) +(=> (and (and (contract_initializer_entry_11_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) true) (contract_initializer_after_init_12_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (contract_initializer_after_init_12_C_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) true) (contract_initializer_10_C_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) +(=> (and (and (contract_initializer_after_init_12_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) true) (contract_initializer_10_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) -(declare-fun |implicit_constructor_entry_13_C_16_0| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) +(declare-fun |implicit_constructor_entry_13_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true) (>= (select (|balances| state_1) this_0) (|msg.value| tx_0))) (implicit_constructor_entry_13_C_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) +(=> (and (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true) (>= (select (|balances| state_1) this_0) (|msg.value| tx_0))) (implicit_constructor_entry_13_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (implicit_constructor_entry_13_C_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (and (contract_initializer_10_C_16_0 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2) true)) (> error_1 0)) (summary_constructor_2_C_16_0 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_2)))) +(=> (and (and (implicit_constructor_entry_13_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (and (contract_initializer_10_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2) true)) (> error_1 0)) (summary_constructor_2_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_2)))) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (implicit_constructor_entry_13_C_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (and (= error_1 0) (and (contract_initializer_10_C_16_0 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2) true))) true) (summary_constructor_2_C_16_0 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_2)))) +(=> (and (and (implicit_constructor_entry_13_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (and (= error_1 0) (and (contract_initializer_10_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2) true))) true) (summary_constructor_2_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_2)))) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (summary_constructor_2_C_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (= (|msg.value| tx_0) 0)) (= error_0 0))) (interface_0_C_16_0 this_0 abi_0 crypto_0 state_1)))) +(=> (and (and (summary_constructor_2_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (= (|msg.value| tx_0) 0)) (= error_0 0))) (interface_0_C_16 this_0 abi_0 crypto_0 state_1)))) -(declare-fun |error_target_3_0| () Bool) +(declare-fun |error_target_3| () Bool) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (interface_0_C_16_0 this_0 abi_0 crypto_0 state_0) true) (and (summary_4_function_f__15_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (= error_0 1))) error_target_3_0))) +(=> (and (and (interface_0_C_16 this_0 abi_0 crypto_0 state_0) true) (and (summary_4_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (= error_0 1))) error_target_3))) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> error_target_3_0 false))) +(=> error_target_3 false))) (check-sat) " } @@ -140,120 +140,120 @@ (declare-datatypes ((|crypto_type| 0)) (((|crypto_type| (|ecrecover| (Array |ecrecover_input_type| Int)) (|keccak256| (Array |bytes_tuple| Int)) (|ripemd160| (Array |bytes_tuple| Int)) (|sha256| (Array |bytes_tuple| Int)))))) (declare-datatypes ((|abi_type| 0)) (((|abi_type|)))) (declare-datatypes ((|state_type| 0)) (((|state_type| (|balances| (Array Int Int)))))) -(declare-fun |interface_0_C_16_0| (Int |abi_type| |crypto_type| |state_type| ) Bool) -(declare-fun |nondet_interface_1_C_16_0| (Int Int |abi_type| |crypto_type| |state_type| |state_type| ) Bool) -(declare-fun |summary_constructor_2_C_16_0| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) +(declare-fun |interface_0_C_16| (Int |abi_type| |crypto_type| |state_type| ) Bool) +(declare-fun |nondet_interface_1_C_16| (Int Int |abi_type| |crypto_type| |state_type| |state_type| ) Bool) +(declare-fun |summary_constructor_2_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (this_0 Int) (tx_0 |tx_type|)) -(=> (= error_0 0) (nondet_interface_1_C_16_0 error_0 this_0 abi_0 crypto_0 state_0 state_0)))) +(=> (= error_0 0) (nondet_interface_1_C_16 error_0 this_0 abi_0 crypto_0 state_0 state_0)))) -(declare-fun |summary_3_function_f__15_16_0| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) -(declare-fun |summary_4_function_f__15_16_0| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) +(declare-fun |summary_3_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) +(declare-fun |summary_4_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|)) -(=> (and (and (nondet_interface_1_C_16_0 error_0 this_0 abi_0 crypto_0 state_0 state_1) true) (and (= error_0 0) (summary_4_function_f__15_16_0 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2))) (nondet_interface_1_C_16_0 error_1 this_0 abi_0 crypto_0 state_0 state_2)))) +(=> (and (and (nondet_interface_1_C_16 error_0 this_0 abi_0 crypto_0 state_0 state_1) true) (and (= error_0 0) (summary_4_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2))) (nondet_interface_1_C_16 error_1 this_0 abi_0 crypto_0 state_0 state_2)))) -(declare-fun |block_5_function_f__15_16_0| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int ) Bool) -(declare-fun |block_6_f_14_16_0| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int ) Bool) +(declare-fun |block_5_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int ) Bool) +(declare-fun |block_6_f_14_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int ) Bool) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int)) -(block_5_function_f__15_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1))) +(block_5_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1))) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int)) -(=> (and (and (block_5_function_f__15_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true)) true) (block_6_f_14_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1)))) +(=> (and (and (block_5_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true)) true) (block_6_f_14_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1)))) -(declare-fun |block_7_return_function_f__15_16_0| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int ) Bool) -(declare-fun |block_8_function_f__15_16_0| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int ) Bool) +(declare-fun |block_7_return_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int ) Bool) +(declare-fun |block_8_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int ) Bool) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (block_6_f_14_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (= expr_11_1 (= expr_9_0 expr_10_0)) (and (=> true true) (and (= expr_10_0 0) (and (=> true (and (>= expr_9_0 0) (<= expr_9_0 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (= expr_9_0 x_5_2) (and (= x_5_2 expr_6_0) (and (=> true true) (and (= expr_6_0 0) (and (= x_5_1 0) true)))))))))) (and (and true (not expr_11_1)) (= error_1 1))) (block_8_function_f__15_16_0 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_2)))) +(=> (and (and (block_6_f_14_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (= expr_11_1 (= expr_9_0 expr_10_0)) (and (=> true true) (and (= expr_10_0 0) (and (=> true (and (>= expr_9_0 0) (<= expr_9_0 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (= expr_9_0 x_5_2) (and (= x_5_2 expr_6_0) (and (=> true true) (and (= expr_6_0 0) (and (= x_5_1 0) true)))))))))) (and (and true (not expr_11_1)) (= error_1 1))) (block_8_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_2)))) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (block_8_function_f__15_16_0 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_2) (summary_3_function_f__15_16_0 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) +(=> (block_8_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_2) (summary_3_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (block_6_f_14_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (= error_1 error_0) (and (= expr_11_1 (= expr_9_0 expr_10_0)) (and (=> true true) (and (= expr_10_0 0) (and (=> true (and (>= expr_9_0 0) (<= expr_9_0 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (= expr_9_0 x_5_2) (and (= x_5_2 expr_6_0) (and (=> true true) (and (= expr_6_0 0) (and (= x_5_1 0) true))))))))))) true) (block_7_return_function_f__15_16_0 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_2)))) +(=> (and (and (block_6_f_14_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (= error_1 error_0) (and (= expr_11_1 (= expr_9_0 expr_10_0)) (and (=> true true) (and (= expr_10_0 0) (and (=> true (and (>= expr_9_0 0) (<= expr_9_0 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (= expr_9_0 x_5_2) (and (= x_5_2 expr_6_0) (and (=> true true) (and (= expr_6_0 0) (and (= x_5_1 0) true))))))))))) true) (block_7_return_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_2)))) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (block_7_return_function_f__15_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) true) true) (summary_3_function_f__15_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) +(=> (and (and (block_7_return_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) true) true) (summary_3_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) -(declare-fun |block_9_function_f__15_16_0| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int ) Bool) +(declare-fun |block_9_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int ) Bool) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(block_9_function_f__15_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1))) +(block_9_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1))) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (block_9_function_f__15_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (summary_3_function_f__15_16_0 error_1 this_0 abi_0 crypto_0 tx_0 state_2 state_3) (and (= state_2 (|state_type| (store (|balances| state_1) this_0 (+ (select (|balances| state_1) this_0) funds_2_0)))) (and (and (>= (+ (select (|balances| state_1) this_0) funds_2_0) 0) (<= (+ (select (|balances| state_1) this_0) funds_2_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935)) (and (>= funds_2_0 (|msg.value| tx_0)) (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (and (and (and (and (and (= (|msg.value| tx_0) 0) (= (|msg.sig| tx_0) 638722032)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 0) 38)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 1) 18)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 2) 31)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 3) 240)) (>= (|bytes_tuple_accessor_length| (|msg.data| tx_0)) 4))) (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true))))))) true) (summary_4_function_f__15_16_0 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_3)))) +(=> (and (and (block_9_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (summary_3_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_2 state_3) (and (= state_2 (|state_type| (store (|balances| state_1) this_0 (+ (select (|balances| state_1) this_0) funds_2_0)))) (and (and (>= (+ (select (|balances| state_1) this_0) funds_2_0) 0) (<= (+ (select (|balances| state_1) this_0) funds_2_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935)) (and (>= funds_2_0 (|msg.value| tx_0)) (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (and (and (and (and (and (= (|msg.value| tx_0) 0) (= (|msg.sig| tx_0) 638722032)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 0) 38)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 1) 18)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 2) 31)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 3) 240)) (>= (|bytes_tuple_accessor_length| (|msg.data| tx_0)) 4))) (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true))))))) true) (summary_4_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_3)))) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (interface_0_C_16_0 this_0 abi_0 crypto_0 state_0) true) (and (summary_4_function_f__15_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (= error_0 0))) (interface_0_C_16_0 this_0 abi_0 crypto_0 state_1)))) +(=> (and (and (interface_0_C_16 this_0 abi_0 crypto_0 state_0) true) (and (summary_4_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (= error_0 0))) (interface_0_C_16 this_0 abi_0 crypto_0 state_1)))) -(declare-fun |contract_initializer_10_C_16_0| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) -(declare-fun |contract_initializer_entry_11_C_16_0| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) +(declare-fun |contract_initializer_10_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) +(declare-fun |contract_initializer_entry_11_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (= state_1 state_0) (= error_0 0)) true) (contract_initializer_entry_11_C_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) +(=> (and (and (= state_1 state_0) (= error_0 0)) true) (contract_initializer_entry_11_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) -(declare-fun |contract_initializer_after_init_12_C_16_0| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) +(declare-fun |contract_initializer_after_init_12_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (contract_initializer_entry_11_C_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) true) (contract_initializer_after_init_12_C_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) +(=> (and (and (contract_initializer_entry_11_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) true) (contract_initializer_after_init_12_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (contract_initializer_after_init_12_C_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) true) (contract_initializer_10_C_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) +(=> (and (and (contract_initializer_after_init_12_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) true) (contract_initializer_10_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) -(declare-fun |implicit_constructor_entry_13_C_16_0| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) +(declare-fun |implicit_constructor_entry_13_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true) (>= (select (|balances| state_1) this_0) (|msg.value| tx_0))) (implicit_constructor_entry_13_C_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) +(=> (and (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true) (>= (select (|balances| state_1) this_0) (|msg.value| tx_0))) (implicit_constructor_entry_13_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (implicit_constructor_entry_13_C_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (and (contract_initializer_10_C_16_0 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2) true)) (> error_1 0)) (summary_constructor_2_C_16_0 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_2)))) +(=> (and (and (implicit_constructor_entry_13_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (and (contract_initializer_10_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2) true)) (> error_1 0)) (summary_constructor_2_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_2)))) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (implicit_constructor_entry_13_C_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (and (= error_1 0) (and (contract_initializer_10_C_16_0 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2) true))) true) (summary_constructor_2_C_16_0 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_2)))) +(=> (and (and (implicit_constructor_entry_13_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (and (= error_1 0) (and (contract_initializer_10_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2) true))) true) (summary_constructor_2_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_2)))) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (summary_constructor_2_C_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (= (|msg.value| tx_0) 0)) (= error_0 0))) (interface_0_C_16_0 this_0 abi_0 crypto_0 state_1)))) +(=> (and (and (summary_constructor_2_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (= (|msg.value| tx_0) 0)) (= error_0 0))) (interface_0_C_16 this_0 abi_0 crypto_0 state_1)))) -(declare-fun |error_target_3_0| () Bool) +(declare-fun |error_target_3| () Bool) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (interface_0_C_16_0 this_0 abi_0 crypto_0 state_0) true) (and (summary_4_function_f__15_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (= error_0 1))) error_target_3_0))) +(=> (and (and (interface_0_C_16 this_0 abi_0 crypto_0 state_0) true) (and (summary_4_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (= error_0 1))) error_target_3))) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> error_target_3_0 false))) +(=> error_target_3 false))) (check-sat) @@ -267,120 +267,120 @@ (declare-datatypes ((|crypto_type| 0)) (((|crypto_type| (|ecrecover| (Array |ecrecover_input_type| Int)) (|keccak256| (Array |bytes_tuple| Int)) (|ripemd160| (Array |bytes_tuple| Int)) (|sha256| (Array |bytes_tuple| Int)))))) (declare-datatypes ((|abi_type| 0)) (((|abi_type|)))) (declare-datatypes ((|state_type| 0)) (((|state_type| (|balances| (Array Int Int)))))) -(declare-fun |interface_0_C_16_0| (Int |abi_type| |crypto_type| |state_type| ) Bool) -(declare-fun |nondet_interface_1_C_16_0| (Int Int |abi_type| |crypto_type| |state_type| |state_type| ) Bool) -(declare-fun |summary_constructor_2_C_16_0| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) +(declare-fun |interface_0_C_16| (Int |abi_type| |crypto_type| |state_type| ) Bool) +(declare-fun |nondet_interface_1_C_16| (Int Int |abi_type| |crypto_type| |state_type| |state_type| ) Bool) +(declare-fun |summary_constructor_2_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (this_0 Int) (tx_0 |tx_type|)) -(=> (= error_0 0) (nondet_interface_1_C_16_0 error_0 this_0 abi_0 crypto_0 state_0 state_0)))) +(=> (= error_0 0) (nondet_interface_1_C_16 error_0 this_0 abi_0 crypto_0 state_0 state_0)))) -(declare-fun |summary_3_function_f__15_16_0| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) -(declare-fun |summary_4_function_f__15_16_0| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) +(declare-fun |summary_3_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) +(declare-fun |summary_4_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|)) -(=> (and (and (nondet_interface_1_C_16_0 error_0 this_0 abi_0 crypto_0 state_0 state_1) true) (and (= error_0 0) (summary_4_function_f__15_16_0 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2))) (nondet_interface_1_C_16_0 error_1 this_0 abi_0 crypto_0 state_0 state_2)))) +(=> (and (and (nondet_interface_1_C_16 error_0 this_0 abi_0 crypto_0 state_0 state_1) true) (and (= error_0 0) (summary_4_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2))) (nondet_interface_1_C_16 error_1 this_0 abi_0 crypto_0 state_0 state_2)))) -(declare-fun |block_5_function_f__15_16_0| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int ) Bool) -(declare-fun |block_6_f_14_16_0| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int ) Bool) +(declare-fun |block_5_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int ) Bool) +(declare-fun |block_6_f_14_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int ) Bool) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int)) -(block_5_function_f__15_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1))) +(block_5_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1))) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int)) -(=> (and (and (block_5_function_f__15_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true)) true) (block_6_f_14_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1)))) +(=> (and (and (block_5_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true)) true) (block_6_f_14_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1)))) -(declare-fun |block_7_return_function_f__15_16_0| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int ) Bool) -(declare-fun |block_8_function_f__15_16_0| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int ) Bool) +(declare-fun |block_7_return_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int ) Bool) +(declare-fun |block_8_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int ) Bool) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (block_6_f_14_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (= expr_11_1 (= expr_9_0 expr_10_0)) (and (=> true true) (and (= expr_10_0 0) (and (=> true (and (>= expr_9_0 0) (<= expr_9_0 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (= expr_9_0 x_5_2) (and (= x_5_2 expr_6_0) (and (=> true true) (and (= expr_6_0 0) (and (= x_5_1 0) true)))))))))) (and (and true (not expr_11_1)) (= error_1 1))) (block_8_function_f__15_16_0 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_2)))) +(=> (and (and (block_6_f_14_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (= expr_11_1 (= expr_9_0 expr_10_0)) (and (=> true true) (and (= expr_10_0 0) (and (=> true (and (>= expr_9_0 0) (<= expr_9_0 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (= expr_9_0 x_5_2) (and (= x_5_2 expr_6_0) (and (=> true true) (and (= expr_6_0 0) (and (= x_5_1 0) true)))))))))) (and (and true (not expr_11_1)) (= error_1 1))) (block_8_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_2)))) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (block_8_function_f__15_16_0 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_2) (summary_3_function_f__15_16_0 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) +(=> (block_8_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_2) (summary_3_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (block_6_f_14_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (= error_1 error_0) (and (= expr_11_1 (= expr_9_0 expr_10_0)) (and (=> true true) (and (= expr_10_0 0) (and (=> true (and (>= expr_9_0 0) (<= expr_9_0 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (= expr_9_0 x_5_2) (and (= x_5_2 expr_6_0) (and (=> true true) (and (= expr_6_0 0) (and (= x_5_1 0) true))))))))))) true) (block_7_return_function_f__15_16_0 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_2)))) +(=> (and (and (block_6_f_14_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (= error_1 error_0) (and (= expr_11_1 (= expr_9_0 expr_10_0)) (and (=> true true) (and (= expr_10_0 0) (and (=> true (and (>= expr_9_0 0) (<= expr_9_0 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (= expr_9_0 x_5_2) (and (= x_5_2 expr_6_0) (and (=> true true) (and (= expr_6_0 0) (and (= x_5_1 0) true))))))))))) true) (block_7_return_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_2)))) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (block_7_return_function_f__15_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) true) true) (summary_3_function_f__15_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) +(=> (and (and (block_7_return_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) true) true) (summary_3_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) -(declare-fun |block_9_function_f__15_16_0| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int ) Bool) +(declare-fun |block_9_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int ) Bool) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(block_9_function_f__15_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1))) +(block_9_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1))) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (block_9_function_f__15_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (summary_3_function_f__15_16_0 error_1 this_0 abi_0 crypto_0 tx_0 state_2 state_3) (and (= state_2 (|state_type| (store (|balances| state_1) this_0 (+ (select (|balances| state_1) this_0) funds_2_0)))) (and (and (>= (+ (select (|balances| state_1) this_0) funds_2_0) 0) (<= (+ (select (|balances| state_1) this_0) funds_2_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935)) (and (>= funds_2_0 (|msg.value| tx_0)) (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (and (and (and (and (and (= (|msg.value| tx_0) 0) (= (|msg.sig| tx_0) 638722032)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 0) 38)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 1) 18)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 2) 31)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 3) 240)) (>= (|bytes_tuple_accessor_length| (|msg.data| tx_0)) 4))) (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true))))))) true) (summary_4_function_f__15_16_0 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_3)))) +(=> (and (and (block_9_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (summary_3_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_2 state_3) (and (= state_2 (|state_type| (store (|balances| state_1) this_0 (+ (select (|balances| state_1) this_0) funds_2_0)))) (and (and (>= (+ (select (|balances| state_1) this_0) funds_2_0) 0) (<= (+ (select (|balances| state_1) this_0) funds_2_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935)) (and (>= funds_2_0 (|msg.value| tx_0)) (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (and (and (and (and (and (= (|msg.value| tx_0) 0) (= (|msg.sig| tx_0) 638722032)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 0) 38)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 1) 18)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 2) 31)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 3) 240)) (>= (|bytes_tuple_accessor_length| (|msg.data| tx_0)) 4))) (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true))))))) true) (summary_4_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_3)))) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (interface_0_C_16_0 this_0 abi_0 crypto_0 state_0) true) (and (summary_4_function_f__15_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (= error_0 0))) (interface_0_C_16_0 this_0 abi_0 crypto_0 state_1)))) +(=> (and (and (interface_0_C_16 this_0 abi_0 crypto_0 state_0) true) (and (summary_4_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (= error_0 0))) (interface_0_C_16 this_0 abi_0 crypto_0 state_1)))) -(declare-fun |contract_initializer_10_C_16_0| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) -(declare-fun |contract_initializer_entry_11_C_16_0| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) +(declare-fun |contract_initializer_10_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) +(declare-fun |contract_initializer_entry_11_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (= state_1 state_0) (= error_0 0)) true) (contract_initializer_entry_11_C_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) +(=> (and (and (= state_1 state_0) (= error_0 0)) true) (contract_initializer_entry_11_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) -(declare-fun |contract_initializer_after_init_12_C_16_0| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) +(declare-fun |contract_initializer_after_init_12_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (contract_initializer_entry_11_C_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) true) (contract_initializer_after_init_12_C_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) +(=> (and (and (contract_initializer_entry_11_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) true) (contract_initializer_after_init_12_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (contract_initializer_after_init_12_C_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) true) (contract_initializer_10_C_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) +(=> (and (and (contract_initializer_after_init_12_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) true) (contract_initializer_10_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) -(declare-fun |implicit_constructor_entry_13_C_16_0| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) +(declare-fun |implicit_constructor_entry_13_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true) (>= (select (|balances| state_1) this_0) (|msg.value| tx_0))) (implicit_constructor_entry_13_C_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) +(=> (and (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true) (>= (select (|balances| state_1) this_0) (|msg.value| tx_0))) (implicit_constructor_entry_13_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (implicit_constructor_entry_13_C_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (and (contract_initializer_10_C_16_0 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2) true)) (> error_1 0)) (summary_constructor_2_C_16_0 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_2)))) +(=> (and (and (implicit_constructor_entry_13_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (and (contract_initializer_10_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2) true)) (> error_1 0)) (summary_constructor_2_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_2)))) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (implicit_constructor_entry_13_C_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (and (= error_1 0) (and (contract_initializer_10_C_16_0 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2) true))) true) (summary_constructor_2_C_16_0 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_2)))) +(=> (and (and (implicit_constructor_entry_13_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (and (= error_1 0) (and (contract_initializer_10_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2) true))) true) (summary_constructor_2_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_2)))) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (summary_constructor_2_C_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (= (|msg.value| tx_0) 0)) (= error_0 0))) (interface_0_C_16_0 this_0 abi_0 crypto_0 state_1)))) +(=> (and (and (summary_constructor_2_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (= (|msg.value| tx_0) 0)) (= error_0 0))) (interface_0_C_16 this_0 abi_0 crypto_0 state_1)))) -(declare-fun |error_target_3_0| () Bool) +(declare-fun |error_target_3| () Bool) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (interface_0_C_16_0 this_0 abi_0 crypto_0 state_0) true) (and (summary_4_function_f__15_16_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (= error_0 1))) error_target_3_0))) +(=> (and (and (interface_0_C_16 this_0 abi_0 crypto_0 state_0) true) (and (summary_4_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (= error_0 1))) error_target_3))) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> error_target_3_0 false))) +(=> error_target_3 false))) (check-sat) ", "severity": "info", diff --git a/test/cmdlineTests/standard_model_checker_solvers_smtlib2/output.json b/test/cmdlineTests/standard_model_checker_solvers_smtlib2/output.json index e97227076b3d..9dff9a3bd470 100644 --- a/test/cmdlineTests/standard_model_checker_solvers_smtlib2/output.json +++ b/test/cmdlineTests/standard_model_checker_solvers_smtlib2/output.json @@ -28,127 +28,127 @@ (check-sat) (get-value (|EVALEXPR_0| )) ", - "0xe3dc20257e2b1bd9c6eb77b75913ec3a5752be174e0fd56af16d9fc95afa1b15": "(set-logic HORN) + "0xf090d88ff3260790818d140ca909b8f4cb311a0d905e4e0318ad4dd790ff5f19": "(set-logic HORN) (declare-datatypes ((|bytes_tuple| 0)) (((|bytes_tuple| (|bytes_tuple_accessor_array| (Array Int Int)) (|bytes_tuple_accessor_length| Int))))) (declare-datatypes ((|tx_type| 0)) (((|tx_type| (|block.basefee| Int) (|block.chainid| Int) (|block.coinbase| Int) (|block.gaslimit| Int) (|block.number| Int) (|block.prevrandao| Int) (|block.timestamp| Int) (|blockhash| (Array Int Int)) (|msg.data| |bytes_tuple|) (|msg.sender| Int) (|msg.sig| Int) (|msg.value| Int) (|tx.gasprice| Int) (|tx.origin| Int))))) (declare-datatypes ((|ecrecover_input_type| 0)) (((|ecrecover_input_type| (|hash| Int) (|v| Int) (|r| Int) (|s| Int))))) (declare-datatypes ((|crypto_type| 0)) (((|crypto_type| (|ecrecover| (Array |ecrecover_input_type| Int)) (|keccak256| (Array |bytes_tuple| Int)) (|ripemd160| (Array |bytes_tuple| Int)) (|sha256| (Array |bytes_tuple| Int)))))) (declare-datatypes ((|abi_type| 0)) (((|abi_type|)))) (declare-datatypes ((|state_type| 0)) (((|state_type| (|balances| (Array Int Int)))))) -(declare-fun |interface_0_C_14_0| (Int |abi_type| |crypto_type| |state_type| ) Bool) -(declare-fun |nondet_interface_1_C_14_0| (Int Int |abi_type| |crypto_type| |state_type| |state_type| ) Bool) -(declare-fun |summary_constructor_2_C_14_0| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) +(declare-fun |interface_0_C_14| (Int |abi_type| |crypto_type| |state_type| ) Bool) +(declare-fun |nondet_interface_1_C_14| (Int Int |abi_type| |crypto_type| |state_type| |state_type| ) Bool) +(declare-fun |summary_constructor_2_C_14| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (this_0 Int) (tx_0 |tx_type|)) -(=> (= error_0 0) (nondet_interface_1_C_14_0 error_0 this_0 abi_0 crypto_0 state_0 state_0)))) +(=> (= error_0 0) (nondet_interface_1_C_14 error_0 this_0 abi_0 crypto_0 state_0 state_0)))) -(declare-fun |summary_3_function_f__13_14_0| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| Int |state_type| Int ) Bool) -(declare-fun |summary_4_function_f__13_14_0| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| Int |state_type| Int ) Bool) +(declare-fun |summary_3_function_f__13_14| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| Int |state_type| Int ) Bool) +(declare-fun |summary_4_function_f__13_14| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| Int |state_type| Int ) Bool) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_3_0 Int) (x_3_1 Int)) -(=> (and (and (nondet_interface_1_C_14_0 error_0 this_0 abi_0 crypto_0 state_0 state_1) true) (and (= error_0 0) (summary_4_function_f__13_14_0 error_1 this_0 abi_0 crypto_0 tx_0 state_1 x_3_0 state_2 x_3_1))) (nondet_interface_1_C_14_0 error_1 this_0 abi_0 crypto_0 state_0 state_2)))) +(=> (and (and (nondet_interface_1_C_14 error_0 this_0 abi_0 crypto_0 state_0 state_1) true) (and (= error_0 0) (summary_4_function_f__13_14 error_1 this_0 abi_0 crypto_0 tx_0 state_1 x_3_0 state_2 x_3_1))) (nondet_interface_1_C_14 error_1 this_0 abi_0 crypto_0 state_0 state_2)))) -(declare-fun |block_5_function_f__13_14_0| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| Int |state_type| Int ) Bool) -(declare-fun |block_6_f_12_14_0| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| Int |state_type| Int ) Bool) +(declare-fun |block_5_function_f__13_14| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| Int |state_type| Int ) Bool) +(declare-fun |block_6_f_12_14| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| Int |state_type| Int ) Bool) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_3_0 Int) (x_3_1 Int)) -(block_5_function_f__13_14_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 x_3_0 state_1 x_3_1))) +(block_5_function_f__13_14 error_0 this_0 abi_0 crypto_0 tx_0 state_0 x_3_0 state_1 x_3_1))) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_3_0 Int) (x_3_1 Int)) -(=> (and (and (block_5_function_f__13_14_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 x_3_0 state_1 x_3_1) (and (and (and (and (= state_1 state_0) (= error_0 0)) true) (and true (= x_3_1 x_3_0))) true)) true) (block_6_f_12_14_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 x_3_0 state_1 x_3_1)))) +(=> (and (and (block_5_function_f__13_14 error_0 this_0 abi_0 crypto_0 tx_0 state_0 x_3_0 state_1 x_3_1) (and (and (and (and (= state_1 state_0) (= error_0 0)) true) (and true (= x_3_1 x_3_0))) true)) true) (block_6_f_12_14 error_0 this_0 abi_0 crypto_0 tx_0 state_0 x_3_0 state_1 x_3_1)))) -(declare-fun |block_7_return_function_f__13_14_0| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| Int |state_type| Int ) Bool) -(declare-fun |block_8_function_f__13_14_0| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| Int |state_type| Int ) Bool) +(declare-fun |block_7_return_function_f__13_14| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| Int |state_type| Int ) Bool) +(declare-fun |block_8_function_f__13_14| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| Int |state_type| Int ) Bool) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_7_0 Int) (expr_8_0 Int) (expr_9_1 Bool) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_3_0 Int) (x_3_1 Int)) -(=> (and (and (block_6_f_12_14_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 x_3_0 state_1 x_3_1) (and (= expr_9_1 (> expr_7_0 expr_8_0)) (and (=> true true) (and (= expr_8_0 0) (and (=> true (and (>= expr_7_0 0) (<= expr_7_0 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (= expr_7_0 x_3_1) (and (and (>= x_3_1 0) (<= x_3_1 115792089237316195423570985008687907853269984665640564039457584007913129639935)) true))))))) (and (and true (not expr_9_1)) (= error_1 1))) (block_8_function_f__13_14_0 error_1 this_0 abi_0 crypto_0 tx_0 state_0 x_3_0 state_1 x_3_1)))) +(=> (and (and (block_6_f_12_14 error_0 this_0 abi_0 crypto_0 tx_0 state_0 x_3_0 state_1 x_3_1) (and (= expr_9_1 (> expr_7_0 expr_8_0)) (and (=> true true) (and (= expr_8_0 0) (and (=> true (and (>= expr_7_0 0) (<= expr_7_0 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (= expr_7_0 x_3_1) (and (and (>= x_3_1 0) (<= x_3_1 115792089237316195423570985008687907853269984665640564039457584007913129639935)) true))))))) (and (and true (not expr_9_1)) (= error_1 1))) (block_8_function_f__13_14 error_1 this_0 abi_0 crypto_0 tx_0 state_0 x_3_0 state_1 x_3_1)))) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_7_0 Int) (expr_8_0 Int) (expr_9_1 Bool) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_3_0 Int) (x_3_1 Int)) -(=> (block_8_function_f__13_14_0 error_1 this_0 abi_0 crypto_0 tx_0 state_0 x_3_0 state_1 x_3_1) (summary_3_function_f__13_14_0 error_1 this_0 abi_0 crypto_0 tx_0 state_0 x_3_0 state_1 x_3_1)))) +(=> (block_8_function_f__13_14 error_1 this_0 abi_0 crypto_0 tx_0 state_0 x_3_0 state_1 x_3_1) (summary_3_function_f__13_14 error_1 this_0 abi_0 crypto_0 tx_0 state_0 x_3_0 state_1 x_3_1)))) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_7_0 Int) (expr_8_0 Int) (expr_9_1 Bool) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_3_0 Int) (x_3_1 Int)) -(=> (and (and (block_6_f_12_14_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 x_3_0 state_1 x_3_1) (and (= error_1 error_0) (and (= expr_9_1 (> expr_7_0 expr_8_0)) (and (=> true true) (and (= expr_8_0 0) (and (=> true (and (>= expr_7_0 0) (<= expr_7_0 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (= expr_7_0 x_3_1) (and (and (>= x_3_1 0) (<= x_3_1 115792089237316195423570985008687907853269984665640564039457584007913129639935)) true)))))))) true) (block_7_return_function_f__13_14_0 error_1 this_0 abi_0 crypto_0 tx_0 state_0 x_3_0 state_1 x_3_1)))) +(=> (and (and (block_6_f_12_14 error_0 this_0 abi_0 crypto_0 tx_0 state_0 x_3_0 state_1 x_3_1) (and (= error_1 error_0) (and (= expr_9_1 (> expr_7_0 expr_8_0)) (and (=> true true) (and (= expr_8_0 0) (and (=> true (and (>= expr_7_0 0) (<= expr_7_0 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (= expr_7_0 x_3_1) (and (and (>= x_3_1 0) (<= x_3_1 115792089237316195423570985008687907853269984665640564039457584007913129639935)) true)))))))) true) (block_7_return_function_f__13_14 error_1 this_0 abi_0 crypto_0 tx_0 state_0 x_3_0 state_1 x_3_1)))) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_7_0 Int) (expr_8_0 Int) (expr_9_1 Bool) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_3_0 Int) (x_3_1 Int)) -(=> (and (and (block_7_return_function_f__13_14_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 x_3_0 state_1 x_3_1) true) true) (summary_3_function_f__13_14_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 x_3_0 state_1 x_3_1)))) +(=> (and (and (block_7_return_function_f__13_14 error_0 this_0 abi_0 crypto_0 tx_0 state_0 x_3_0 state_1 x_3_1) true) true) (summary_3_function_f__13_14 error_0 this_0 abi_0 crypto_0 tx_0 state_0 x_3_0 state_1 x_3_1)))) -(declare-fun |block_9_function_f__13_14_0| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| Int |state_type| Int ) Bool) +(declare-fun |block_9_function_f__13_14| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| Int |state_type| Int ) Bool) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_7_0 Int) (expr_8_0 Int) (expr_9_1 Bool) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_3_0 Int) (x_3_1 Int)) -(block_9_function_f__13_14_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 x_3_0 state_1 x_3_1))) +(block_9_function_f__13_14 error_0 this_0 abi_0 crypto_0 tx_0 state_0 x_3_0 state_1 x_3_1))) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_7_0 Int) (expr_8_0 Int) (expr_9_1 Bool) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_3_0 Int) (x_3_1 Int) (x_3_2 Int)) -(=> (and (and (block_9_function_f__13_14_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 x_3_0 state_1 x_3_1) (and (summary_3_function_f__13_14_0 error_1 this_0 abi_0 crypto_0 tx_0 state_2 x_3_1 state_3 x_3_2) (and (= state_2 (|state_type| (store (|balances| state_1) this_0 (+ (select (|balances| state_1) this_0) funds_2_0)))) (and (and (>= (+ (select (|balances| state_1) this_0) funds_2_0) 0) (<= (+ (select (|balances| state_1) this_0) funds_2_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935)) (and (>= funds_2_0 (|msg.value| tx_0)) (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (and (and (and (and (and (= (|msg.value| tx_0) 0) (= (|msg.sig| tx_0) 3017696395)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 0) 179)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 1) 222)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 2) 100)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 3) 139)) (>= (|bytes_tuple_accessor_length| (|msg.data| tx_0)) 4))) (and (and (and (and (= state_1 state_0) (= error_0 0)) true) (and true (= x_3_1 x_3_0))) true))))))) true) (summary_4_function_f__13_14_0 error_1 this_0 abi_0 crypto_0 tx_0 state_0 x_3_0 state_3 x_3_2)))) +(=> (and (and (block_9_function_f__13_14 error_0 this_0 abi_0 crypto_0 tx_0 state_0 x_3_0 state_1 x_3_1) (and (summary_3_function_f__13_14 error_1 this_0 abi_0 crypto_0 tx_0 state_2 x_3_1 state_3 x_3_2) (and (= state_2 (|state_type| (store (|balances| state_1) this_0 (+ (select (|balances| state_1) this_0) funds_2_0)))) (and (and (>= (+ (select (|balances| state_1) this_0) funds_2_0) 0) (<= (+ (select (|balances| state_1) this_0) funds_2_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935)) (and (>= funds_2_0 (|msg.value| tx_0)) (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (and (and (and (and (and (= (|msg.value| tx_0) 0) (= (|msg.sig| tx_0) 3017696395)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 0) 179)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 1) 222)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 2) 100)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 3) 139)) (>= (|bytes_tuple_accessor_length| (|msg.data| tx_0)) 4))) (and (and (and (and (= state_1 state_0) (= error_0 0)) true) (and true (= x_3_1 x_3_0))) true))))))) true) (summary_4_function_f__13_14 error_1 this_0 abi_0 crypto_0 tx_0 state_0 x_3_0 state_3 x_3_2)))) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_7_0 Int) (expr_8_0 Int) (expr_9_1 Bool) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_3_0 Int) (x_3_1 Int) (x_3_2 Int)) -(=> (and (and (interface_0_C_14_0 this_0 abi_0 crypto_0 state_0) true) (and (summary_4_function_f__13_14_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 x_3_0 state_1 x_3_1) (= error_0 0))) (interface_0_C_14_0 this_0 abi_0 crypto_0 state_1)))) +(=> (and (and (interface_0_C_14 this_0 abi_0 crypto_0 state_0) true) (and (summary_4_function_f__13_14 error_0 this_0 abi_0 crypto_0 tx_0 state_0 x_3_0 state_1 x_3_1) (= error_0 0))) (interface_0_C_14 this_0 abi_0 crypto_0 state_1)))) -(declare-fun |contract_initializer_10_C_14_0| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) -(declare-fun |contract_initializer_entry_11_C_14_0| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) +(declare-fun |contract_initializer_10_C_14| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) +(declare-fun |contract_initializer_entry_11_C_14| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_7_0 Int) (expr_8_0 Int) (expr_9_1 Bool) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_3_0 Int) (x_3_1 Int) (x_3_2 Int)) -(=> (and (and (= state_1 state_0) (= error_0 0)) true) (contract_initializer_entry_11_C_14_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) +(=> (and (and (= state_1 state_0) (= error_0 0)) true) (contract_initializer_entry_11_C_14 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) -(declare-fun |contract_initializer_after_init_12_C_14_0| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) +(declare-fun |contract_initializer_after_init_12_C_14| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_7_0 Int) (expr_8_0 Int) (expr_9_1 Bool) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_3_0 Int) (x_3_1 Int) (x_3_2 Int)) -(=> (and (and (contract_initializer_entry_11_C_14_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) true) (contract_initializer_after_init_12_C_14_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) +(=> (and (and (contract_initializer_entry_11_C_14 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) true) (contract_initializer_after_init_12_C_14 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_7_0 Int) (expr_8_0 Int) (expr_9_1 Bool) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_3_0 Int) (x_3_1 Int) (x_3_2 Int)) -(=> (and (and (contract_initializer_after_init_12_C_14_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) true) (contract_initializer_10_C_14_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) +(=> (and (and (contract_initializer_after_init_12_C_14 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) true) (contract_initializer_10_C_14 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) -(declare-fun |implicit_constructor_entry_13_C_14_0| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) +(declare-fun |implicit_constructor_entry_13_C_14| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_7_0 Int) (expr_8_0 Int) (expr_9_1 Bool) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_3_0 Int) (x_3_1 Int) (x_3_2 Int)) -(=> (and (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true) (>= (select (|balances| state_1) this_0) (|msg.value| tx_0))) (implicit_constructor_entry_13_C_14_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) +(=> (and (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true) (>= (select (|balances| state_1) this_0) (|msg.value| tx_0))) (implicit_constructor_entry_13_C_14 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_7_0 Int) (expr_8_0 Int) (expr_9_1 Bool) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_3_0 Int) (x_3_1 Int) (x_3_2 Int)) -(=> (and (and (implicit_constructor_entry_13_C_14_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (and (contract_initializer_10_C_14_0 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2) true)) (> error_1 0)) (summary_constructor_2_C_14_0 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_2)))) +(=> (and (and (implicit_constructor_entry_13_C_14 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (and (contract_initializer_10_C_14 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2) true)) (> error_1 0)) (summary_constructor_2_C_14 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_2)))) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_7_0 Int) (expr_8_0 Int) (expr_9_1 Bool) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_3_0 Int) (x_3_1 Int) (x_3_2 Int)) -(=> (and (and (implicit_constructor_entry_13_C_14_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (and (= error_1 0) (and (contract_initializer_10_C_14_0 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2) true))) true) (summary_constructor_2_C_14_0 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_2)))) +(=> (and (and (implicit_constructor_entry_13_C_14 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (and (= error_1 0) (and (contract_initializer_10_C_14 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2) true))) true) (summary_constructor_2_C_14 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_2)))) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_7_0 Int) (expr_8_0 Int) (expr_9_1 Bool) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_3_0 Int) (x_3_1 Int) (x_3_2 Int)) -(=> (and (and (summary_constructor_2_C_14_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (= (|msg.value| tx_0) 0)) (= error_0 0))) (interface_0_C_14_0 this_0 abi_0 crypto_0 state_1)))) +(=> (and (and (summary_constructor_2_C_14 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (= (|msg.value| tx_0) 0)) (= error_0 0))) (interface_0_C_14 this_0 abi_0 crypto_0 state_1)))) -(declare-fun |error_target_3_0| () Bool) +(declare-fun |error_target_3| () Bool) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_7_0 Int) (expr_8_0 Int) (expr_9_1 Bool) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_3_0 Int) (x_3_1 Int) (x_3_2 Int)) -(=> (and (and (interface_0_C_14_0 this_0 abi_0 crypto_0 state_0) true) (and (summary_4_function_f__13_14_0 error_0 this_0 abi_0 crypto_0 tx_0 state_0 x_3_0 state_1 x_3_1) (= error_0 1))) error_target_3_0))) +(=> (and (and (interface_0_C_14 this_0 abi_0 crypto_0 state_0) true) (and (summary_4_function_f__13_14 error_0 this_0 abi_0 crypto_0 tx_0 state_0 x_3_0 state_1 x_3_1) (= error_0 1))) error_target_3))) (assert (forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_7_0 Int) (expr_8_0 Int) (expr_9_1 Bool) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_3_0 Int) (x_3_1 Int) (x_3_2 Int)) -(=> error_target_3_0 false))) +(=> error_target_3 false))) (check-sat) " } diff --git a/test/libsolidity/smtCheckerTests/deployment/deploy_trusted_flow.sol b/test/libsolidity/smtCheckerTests/deployment/deploy_trusted_flow.sol index 09f001719fbe..2148324ad911 100644 --- a/test/libsolidity/smtCheckerTests/deployment/deploy_trusted_flow.sol +++ b/test/libsolidity/smtCheckerTests/deployment/deploy_trusted_flow.sol @@ -21,10 +21,10 @@ contract C { // SMTIgnoreOS: macos // ---- // Warning 4984: (47-50): CHC: Overflow (resulting value larger than 2**256 - 1) might happen here. -// Warning 6328: (167-185): CHC: Assertion violation might happen here. // Warning 6328: (215-233): CHC: Assertion violation might happen here. +// Warning 6328: (267-285): CHC: Assertion violation might happen here. // Warning 6328: (304-322): CHC: Assertion violation happens here. // Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. // Warning 2661: (47-50): BMC: Overflow (resulting value larger than 2**256 - 1) happens here. -// Warning 4661: (167-185): BMC: Assertion violation happens here. // Warning 4661: (215-233): BMC: Assertion violation happens here. +// Warning 4661: (267-285): BMC: Assertion violation happens here. diff --git a/test/libsolidity/smtCheckerTests/external_calls/external_hash_known_code_state_reentrancy_unsafe_trusted.sol b/test/libsolidity/smtCheckerTests/external_calls/external_hash_known_code_state_reentrancy_unsafe_trusted.sol index 4d179ddf8254..afd1f111b6de 100644 --- a/test/libsolidity/smtCheckerTests/external_calls/external_hash_known_code_state_reentrancy_unsafe_trusted.sol +++ b/test/libsolidity/smtCheckerTests/external_calls/external_hash_known_code_state_reentrancy_unsafe_trusted.sol @@ -40,5 +40,5 @@ contract C { // SMTExtCalls: trusted // SMTIgnoreOS: macos // ---- -// Warning 6328: (396-410): CHC: Assertion violation might happen here. // Warning 6328: (429-455): CHC: Assertion violation happens here. +// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/external_calls/underflow_only_in_external_call.sol b/test/libsolidity/smtCheckerTests/external_calls/underflow_only_in_external_call.sol index 0b5c8fa07d73..68f5ea049878 100644 --- a/test/libsolidity/smtCheckerTests/external_calls/underflow_only_in_external_call.sol +++ b/test/libsolidity/smtCheckerTests/external_calls/underflow_only_in_external_call.sol @@ -4,7 +4,7 @@ contract C { bool guard = true; function dec() public returns (uint) { - if (guard) return 0; + require(!guard); --v; return v; } @@ -21,4 +21,4 @@ contract C { // SMTIgnoreCex: no // SMTTargets: underflow // ---- -// Warning 3944: (109-112): CHC: Underflow (resulting value less than 0) happens here.\nCounterexample:\nv = 0, guard = false\n = 0\n\nTransaction trace:\nC.constructor()\nState: v = 0, guard = true\nC.f()\n C.dec() -- trusted external call +// Warning 3944: (105-108): CHC: Underflow (resulting value less than 0) happens here.\nCounterexample:\nv = 0, guard = false\n = 0\n\nTransaction trace:\nC.constructor()\nState: v = 0, guard = true\nC.f()\n C.dec() -- trusted external call diff --git a/test/libsolidity/smtCheckerTests/operators/index_access_for_bytesNN.sol b/test/libsolidity/smtCheckerTests/operators/index_access_for_bytesNN.sol index c516675d6e5f..b18d5426f5b8 100644 --- a/test/libsolidity/smtCheckerTests/operators/index_access_for_bytesNN.sol +++ b/test/libsolidity/smtCheckerTests/operators/index_access_for_bytesNN.sol @@ -8,5 +8,4 @@ contract C { // SMTEngine: all // SMTIgnoreOS: macos // ---- -// Warning 6368: (76-90): CHC: Out of bounds access might happen here. -// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. +// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/operators/index_access_side_effect.sol b/test/libsolidity/smtCheckerTests/operators/index_access_side_effect.sol index 32c9780d1134..d3b6f5895b85 100644 --- a/test/libsolidity/smtCheckerTests/operators/index_access_side_effect.sol +++ b/test/libsolidity/smtCheckerTests/operators/index_access_side_effect.sol @@ -21,6 +21,7 @@ contract C { // ==== // SMTEngine: all // SMTIgnoreCex: yes -// SMTIgnoreOS: macos // ---- -// Info 1391: CHC: 4 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. +// Warning 6328: (335-354): CHC: Assertion violation might happen here. +// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. +// Warning 4661: (335-354): BMC: Assertion violation happens here. diff --git a/test/libsolidity/smtCheckerTests/operators/userDefined/user_defined_operator_matches_equivalent_function_call.sol b/test/libsolidity/smtCheckerTests/operators/userDefined/user_defined_operator_matches_equivalent_function_call.sol index 9872a6a92b26..206c63042488 100644 --- a/test/libsolidity/smtCheckerTests/operators/userDefined/user_defined_operator_matches_equivalent_function_call.sol +++ b/test/libsolidity/smtCheckerTests/operators/userDefined/user_defined_operator_matches_equivalent_function_call.sol @@ -53,28 +53,32 @@ contract C { } // ==== // SMTEngine: all -// SMTIgnoreOS: macos // ---- // Warning 3944: (679-708): CHC: Underflow (resulting value less than -32768) might happen here. -// Warning 4984: (679-708): CHC: Overflow (resulting value larger than 32767) happens here. +// Warning 4984: (679-708): CHC: Overflow (resulting value larger than 32767) might happen here. // Warning 3944: (777-806): CHC: Underflow (resulting value less than -32768) might happen here. // Warning 4984: (777-806): CHC: Overflow (resulting value larger than 32767) might happen here. +// Warning 3944: (870-884): CHC: Underflow (resulting value less than -32768) might happen here. // Warning 4984: (870-884): CHC: Overflow (resulting value larger than 32767) might happen here. // Warning 3944: (953-982): CHC: Underflow (resulting value less than -32768) might happen here. // Warning 4984: (953-982): CHC: Overflow (resulting value larger than 32767) might happen here. // Warning 4984: (1051-1080): CHC: Overflow (resulting value larger than 32767) might happen here. -// Warning 4281: (1051-1080): CHC: Division by zero happens here. +// Warning 4281: (1051-1080): CHC: Division by zero might happen here. // Warning 4281: (1149-1178): CHC: Division by zero might happen here. // Warning 6328: (2069-2095): CHC: Assertion violation might happen here. +// Warning 6328: (2105-2131): CHC: Assertion violation might happen here. // Warning 6328: (2141-2163): CHC: Assertion violation might happen here. +// Warning 6328: (2173-2199): CHC: Assertion violation might happen here. // Warning 6328: (2209-2235): CHC: Assertion violation might happen here. // Warning 6328: (2245-2271): CHC: Assertion violation might happen here. -// Info 1391: CHC: 13 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. +// Info 1391: CHC: 10 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. +// Warning 2661: (679-708): BMC: Overflow (resulting value larger than 32767) happens here. // Warning 4144: (679-708): BMC: Underflow (resulting value less than -32768) happens here. // Warning 2661: (777-806): BMC: Overflow (resulting value larger than 32767) happens here. // Warning 4144: (777-806): BMC: Underflow (resulting value less than -32768) happens here. // Warning 2661: (953-982): BMC: Overflow (resulting value larger than 32767) happens here. // Warning 4144: (953-982): BMC: Underflow (resulting value less than -32768) happens here. +// Warning 3046: (1051-1080): BMC: Division by zero happens here. // Warning 3046: (1149-1178): BMC: Division by zero happens here. // Warning 7812: (2245-2271): BMC: Assertion violation might happen here. -// Info 6002: BMC: 10 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. +// Info 6002: BMC: 14 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/out_of_bounds/array_1.sol b/test/libsolidity/smtCheckerTests/out_of_bounds/array_1.sol index bc37a3130178..65a1dfd39015 100644 --- a/test/libsolidity/smtCheckerTests/out_of_bounds/array_1.sol +++ b/test/libsolidity/smtCheckerTests/out_of_bounds/array_1.sol @@ -21,8 +21,6 @@ contract C { // SMTIgnoreOS: macos // ---- // Warning 4984: (112-115): CHC: Overflow (resulting value larger than 2**256 - 1) might happen here. -// Warning 3944: (181-184): CHC: Underflow (resulting value less than 0) might happen here. // Warning 6368: (259-263): CHC: Out of bounds access happens here. -// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. +// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. // Warning 2661: (112-115): BMC: Overflow (resulting value larger than 2**256 - 1) happens here. -// Warning 4144: (181-184): BMC: Underflow (resulting value less than 0) happens here. diff --git a/test/libsolidity/smtCheckerTests/types/array_branch_3d.sol b/test/libsolidity/smtCheckerTests/types/array_branch_3d.sol index 8ba3f013707d..3aced164c867 100644 --- a/test/libsolidity/smtCheckerTests/types/array_branch_3d.sol +++ b/test/libsolidity/smtCheckerTests/types/array_branch_3d.sol @@ -7,20 +7,14 @@ contract C c[0][0].push(); } function f(bool b) public { - c[0][0][0] = 0; if (b) c[0][0][0] = 1; assert(c[0][0][0] > 0); } } // ==== -// SMTEngine: all +// SMTEngine: chc +// SMTSolvers: eld // ---- -// Warning 6368: (124-131): CHC: Out of bounds access might happen here. -// Warning 6368: (124-134): CHC: Out of bounds access might happen here. -// Warning 6368: (152-159): CHC: Out of bounds access might happen here. -// Warning 6368: (152-162): CHC: Out of bounds access might happen here. -// Warning 6368: (177-184): CHC: Out of bounds access might happen here. -// Warning 6368: (177-187): CHC: Out of bounds access might happen here. -// Warning 6328: (170-192): CHC: Assertion violation happens here. -// Info 1391: CHC: 6 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. +// Warning 6328: (152-174): CHC: Assertion violation happens here. +// Info 1391: CHC: 9 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/types/array_branches_3d.sol b/test/libsolidity/smtCheckerTests/types/array_branches_3d.sol index ecd419eea6ac..8e9499183a6f 100644 --- a/test/libsolidity/smtCheckerTests/types/array_branches_3d.sol +++ b/test/libsolidity/smtCheckerTests/types/array_branches_3d.sol @@ -15,6 +15,7 @@ contract C } // ==== // SMTEngine: all +// SMTIgnoreOS: macos // ---- // Warning 6368: (124-131): CHC: Out of bounds access might happen here. // Warning 6368: (124-134): CHC: Out of bounds access might happen here. diff --git a/test/libsolidity/smtCheckerTests/types/array_branches_3d_show_unproved.sol b/test/libsolidity/smtCheckerTests/types/array_branches_3d_show_unproved.sol index acd5744726d5..7e9aad5b01df 100644 --- a/test/libsolidity/smtCheckerTests/types/array_branches_3d_show_unproved.sol +++ b/test/libsolidity/smtCheckerTests/types/array_branches_3d_show_unproved.sol @@ -16,6 +16,7 @@ contract C // ==== // SMTEngine: all // SMTShowUnproved: yes +// SMTIgnoreOS: macos // ---- // Warning 6368: (124-131): CHC: Out of bounds access might happen here. // Warning 6368: (124-134): CHC: Out of bounds access might happen here. diff --git a/test/libsolidity/smtCheckerTests/types/struct_array_branches_2d.sol b/test/libsolidity/smtCheckerTests/types/struct_array_branches_2d.sol index 0d45aee14216..d5daba699912 100644 --- a/test/libsolidity/smtCheckerTests/types/struct_array_branches_2d.sol +++ b/test/libsolidity/smtCheckerTests/types/struct_array_branches_2d.sol @@ -15,7 +15,5 @@ contract C } // ==== // SMTEngine: all -// SMTIgnoreOS: macos // ---- -// Warning 6368: (216-225): CHC: Out of bounds access might happen here. -// Info 1391: CHC: 9 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. +// Info 1391: CHC: 10 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. From c012b725bb8ce755b93ce0dd05e83c34c499acd6 Mon Sep 17 00:00:00 2001 From: clonker Date: Mon, 1 Jul 2024 18:27:27 +0200 Subject: [PATCH 0285/1022] Scanner: Add SpecialComment mode --- liblangutil/Scanner.cpp | 50 +++++++++++++++++++++++++----------- liblangutil/Scanner.h | 11 ++++---- test/liblangutil/Scanner.cpp | 46 +++++++++++++++++++++++++++++++++ 3 files changed, 86 insertions(+), 21 deletions(-) diff --git a/liblangutil/Scanner.cpp b/liblangutil/Scanner.cpp index 806efa311668..4a41cb97a5f6 100644 --- a/liblangutil/Scanner.cpp +++ b/liblangutil/Scanner.cpp @@ -826,31 +826,48 @@ Token Scanner::scanString(bool const _isUnicode) char const quote = m_char; advance(); // consume quote LiteralScope literal(this, LITERAL_TYPE_STRING); - while (m_char != quote && !isSourcePastEndOfInput() && !isUnicodeLinebreak()) + // for source location comments we allow multiline string literals + while (m_char != quote && !isSourcePastEndOfInput() && (!isUnicodeLinebreak() || m_kind == ScannerKind::SpecialComment)) { char c = m_char; advance(); - if (c == '\\') + + if (m_kind == ScannerKind::SpecialComment) { - if (isSourcePastEndOfInput() || !scanEscape()) - return setError(ScannerError::IllegalEscapeSequence); + if (c == '\\') + { + if (isSourcePastEndOfInput()) + return setError(ScannerError::IllegalEscapeSequence); + advance(); + } + else + addLiteralChar(c); } else { - // Report error on non-printable characters in string literals, however - // allow anything for unicode string literals, because their validity will - // be verified later (in the syntax checker). - // - // We are using a manual range and not isprint() to avoid - // any potential complications with locale. - if (!_isUnicode && (static_cast(c) <= 0x1f || static_cast(c) >= 0x7f)) + if (c == '\\') { - if (m_kind == ScannerKind::Yul) - return setError(ScannerError::IllegalCharacterInString); - return setError(ScannerError::UnicodeCharacterInNonUnicodeString); + if (isSourcePastEndOfInput() || !scanEscape()) + return setError(ScannerError::IllegalEscapeSequence); + } + else + { + // Report error on non-printable characters in string literals, however + // allow anything for unicode string literals, because their validity will + // be verified later (in the syntax checker). + // + // We are using a manual range and not isprint() to avoid + // any potential complications with locale. + if (!_isUnicode && (static_cast(c) <= 0x1f || static_cast(c) >= 0x7f)) + { + if (m_kind == ScannerKind::Yul) + return setError(ScannerError::IllegalCharacterInString); + return setError(ScannerError::UnicodeCharacterInNonUnicodeString); + } + addLiteralChar(c); } - addLiteralChar(c); } + } if (m_char != quote) return setError(ScannerError::IllegalStringEndQuote); @@ -1023,6 +1040,9 @@ std::tuple Scanner::scanIdentifierOrKeyword() auto const token = TokenTraits::fromIdentifierOrKeyword(m_tokens[NextNext].literal); switch (m_kind) { + case ScannerKind::SpecialComment: + // there are no keywords in special comments + return std::make_tuple(Token::Identifier, 0, 0); case ScannerKind::Solidity: // Turn experimental Solidity keywords that are not keywords in legacy Solidity into identifiers. if (TokenTraits::isExperimentalSolidityOnlyKeyword(std::get<0>(token))) diff --git a/liblangutil/Scanner.h b/liblangutil/Scanner.h index eaa2b3b54d1e..c734a368ccae 100644 --- a/liblangutil/Scanner.h +++ b/liblangutil/Scanner.h @@ -62,15 +62,12 @@ namespace solidity::langutil { -class AstRawString; -class AstValueFactory; -class ParserRecorder; - enum class ScannerKind { Solidity, Yul, - ExperimentalSolidity + ExperimentalSolidity, + SpecialComment }; enum class ScannerError @@ -102,11 +99,13 @@ class Scanner { friend class LiteralScope; public: - explicit Scanner(CharStream& _source): + explicit Scanner(CharStream& _source, ScannerKind _kind = ScannerKind::Solidity): m_source(_source), m_sourceName{std::make_shared(_source.name())} { reset(); + if (_kind != ScannerKind::Solidity) + setScannerMode(_kind); } /// Resets scanner to the start of input. diff --git a/test/liblangutil/Scanner.cpp b/test/liblangutil/Scanner.cpp index 8c961a3bab6a..b4043fe86a0c 100644 --- a/test/liblangutil/Scanner.cpp +++ b/test/liblangutil/Scanner.cpp @@ -1026,6 +1026,52 @@ BOOST_AUTO_TEST_CASE(yul_function_with_whitespace) BOOST_CHECK_EQUAL(scanner.next(), Token::EOS); } +BOOST_AUTO_TEST_CASE(special_comment_with_invalid_escapes) +{ + std::string input(R"("test\x\f\g\u\g\a\u\g\a12\uö\xyoof")"); + std::string expectedOutput(R"(test12öyoof)"); + CharStream stream(input, ""); + Scanner scanner(stream, ScannerKind::SpecialComment); + BOOST_REQUIRE(scanner.currentToken() == Token::StringLiteral); + BOOST_REQUIRE(scanner.currentLiteral() == expectedOutput); +} + +BOOST_AUTO_TEST_CASE(special_comment_with_valid_and_invalid_escapes) +{ + std::string input(R"("test\n\x61\t\u01A9test\f")"); + std::string expectedOutput(R"(test6101A9test)"); + CharStream stream(input, ""); + Scanner scanner(stream, ScannerKind::SpecialComment); + BOOST_REQUIRE(scanner.currentToken() == Token::StringLiteral); + BOOST_REQUIRE(scanner.currentLiteral() == expectedOutput); +} + +BOOST_AUTO_TEST_CASE(special_comment_with_unterminated_escape_sequence_at_eos) +{ + CharStream stream(R"("test\)", ""); + std::string expectedOutput(R"(test6101A9test)"); + Scanner scanner(stream, ScannerKind::SpecialComment); + BOOST_REQUIRE(scanner.currentToken() == Token::Illegal); + BOOST_REQUIRE(scanner.currentError() == ScannerError::IllegalEscapeSequence); +} + +BOOST_AUTO_TEST_CASE(special_comment_with_escaped_quotes) +{ + CharStream stream(R"("test\\\"")", ""); + std::string expectedOutput(R"(test)"); + Scanner scanner(stream, ScannerKind::SpecialComment); + BOOST_REQUIRE(scanner.currentToken() == Token::StringLiteral); + BOOST_REQUIRE(scanner.currentLiteral() == expectedOutput); +} + +BOOST_AUTO_TEST_CASE(special_comment_with_unterminated_string) +{ + CharStream stream(R"("test)", ""); + Scanner scanner(stream, ScannerKind::SpecialComment); + BOOST_REQUIRE(scanner.currentToken() == Token::Illegal); + BOOST_REQUIRE(scanner.currentError() == ScannerError::IllegalStringEndQuote); +} + BOOST_AUTO_TEST_SUITE_END() } // end namespaces From ef9aa908b6cb8f8cd6d2b287a8778ca162e5cc04 Mon Sep 17 00:00:00 2001 From: clonker Date: Mon, 1 Jul 2024 18:29:07 +0200 Subject: [PATCH 0286/1022] AsmParser: Use scanner instead of regex for source comment parsing --- Changelog.md | 2 + libyul/AsmParser.cpp | 82 ++++++++++++++++++++++++----------- test/libyul/Parser.cpp | 98 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 158 insertions(+), 24 deletions(-) diff --git a/Changelog.md b/Changelog.md index 442c4e34f3e8..cba038a56b98 100644 --- a/Changelog.md +++ b/Changelog.md @@ -3,6 +3,7 @@ Language Features: * Accept declarations of state variables with ``transient`` data location (parser support only, no code generation yet). * Make ``require(bool, Error)`` available when using the legacy pipeline. + * Yul: Parsing rules for source location comments have been relaxed: Whitespace between the location components as well as single-quoted code snippets are now allowed. Compiler Features: @@ -18,6 +19,7 @@ Bugfixes: * SMTChecker: Fix internal compiler error when reporting proved targets for BMC engine. * TypeChecker: Fix segfault when assigning nested tuple to tuple. * Yul Optimizer: Name simplification could lead to forbidden identifiers with a leading and/or trailing dot, e.g., ``x._`` would get simplified into ``x.``. + * Yul Parser: Fix segfault when parsing very long location comments. ### 0.8.26 (2024-05-21) diff --git a/libyul/AsmParser.cpp b/libyul/AsmParser.cpp index ecf3475a8a3b..2ae4dd805bc1 100644 --- a/libyul/AsmParser.cpp +++ b/libyul/AsmParser.cpp @@ -28,11 +28,10 @@ #include #include #include +#include #include #include -#include - #include #include @@ -53,7 +52,7 @@ std::optional toInt(std::string const& _value) { return stoi(_value); } - catch (...) + catch (std::out_of_range const&) { return std::nullopt; } @@ -193,13 +192,41 @@ std::optional> Parser::parseSrcComme langutil::SourceLocation const& _commentLocation ) { - static std::regex const argsRegex = std::regex( - R"~~(^(-1|\d+):(-1|\d+):(-1|\d+)(?:\s+|$))~~" // index and location, e.g.: 1:234:-1 - R"~~(("(?:[^"\\]|\\.)*"?)?)~~", // optional code snippet, e.g.: "string memory s = \"abc\";..." - std::regex_constants::ECMAScript | std::regex_constants::optimize - ); - std::match_results match; - if (!regex_search(_arguments.cbegin(), _arguments.cend(), match, argsRegex)) + CharStream argumentStream(std::string(_arguments), ""); + Scanner scanner(argumentStream, ScannerKind::SpecialComment); + + std::string_view tail{_arguments.substr(_arguments.size())}; + auto const parseLocationComponent = [](Scanner& _scanner, bool expectTrailingColon) -> std::optional + { + bool negative = false; + if (_scanner.currentToken() == Token::Sub) + { + negative = true; + _scanner.next(); + } + if (_scanner.currentToken() != Token::Number) + return std::nullopt; + if (expectTrailingColon && _scanner.peekNextToken() != Token::Colon) + return std::nullopt; + if (!isValidDecimal(_scanner.currentLiteral())) + return std::nullopt; + std::string decimal = (negative ? "-" : "") + _scanner.currentLiteral(); + _scanner.next(); + if (expectTrailingColon) + _scanner.next(); + return decimal; + }; + std::optional rawSourceIndex = parseLocationComponent(scanner, true); + std::optional rawStart = parseLocationComponent(scanner, true); + std::optional rawEnd = parseLocationComponent(scanner, false); + + size_t const snippetStart = static_cast(scanner.currentLocation().start); + bool const locationScannedSuccessfully = rawSourceIndex && rawStart && rawEnd; + bool const locationIsWhitespaceSeparated = + scanner.peekNextToken() == Token::EOS || + (snippetStart > 0 && langutil::isWhiteSpace(_arguments[snippetStart - 1])); + + if (!locationScannedSuccessfully || !locationIsWhitespaceSeparated) { m_errorReporter.syntaxError( 8387_error, @@ -209,13 +236,16 @@ std::optional> Parser::parseSrcComme return std::nullopt; } - solAssert(match.size() == 5, ""); - std::string_view tail = _arguments.substr(static_cast(match.position() + match.length())); + // captures error cases `"test` (illegal end quote) and `"test\` (illegal escape sequence / dangling backslash) + bool const illegalLiteral = scanner.currentToken() == Token::Illegal && (scanner.currentError() == ScannerError::IllegalStringEndQuote || scanner.currentError() == ScannerError::IllegalEscapeSequence); + if (scanner.currentToken() == Token::StringLiteral || illegalLiteral) + tail = _arguments.substr(static_cast(scanner.currentLocation().end)); + else + tail = _arguments.substr(static_cast(scanner.currentLocation().start)); - if (match[4].matched && ( - !boost::algorithm::ends_with(match[4].str(), "\"") || - boost::algorithm::ends_with(match[4].str(), "\\\"") - )) + // Other scanner errors may occur if there is no string literal which follows + // (f.ex. IllegalHexDigit, IllegalCommentTerminator), but these are ignored + if (illegalLiteral) { m_errorReporter.syntaxError( 1544_error, @@ -225,11 +255,15 @@ std::optional> Parser::parseSrcComme return {{tail, SourceLocation{}}}; } - std::optional const sourceIndex = toInt(match[1].str()); - std::optional const start = toInt(match[2].str()); - std::optional const end = toInt(match[3].str()); + std::optional const sourceIndex = toInt(*rawSourceIndex); + std::optional const start = toInt(*rawStart); + std::optional const end = toInt(*rawEnd); - if (!sourceIndex.has_value() || !start.has_value() || !end.has_value()) + if ( + !sourceIndex.has_value() || *sourceIndex < -1 || + !start.has_value() || *start < -1 || + !end.has_value() || *end < -1 + ) m_errorReporter.syntaxError( 6367_error, _commentLocation, @@ -237,8 +271,8 @@ std::optional> Parser::parseSrcComme "Expected non-negative integer values or -1 for source index and location." ); else if (sourceIndex == -1) - return {{tail, SourceLocation{start.value(), end.value(), nullptr}}}; - else if (!(sourceIndex >= 0 && m_sourceNames->count(static_cast(sourceIndex.value())))) + return {{tail, SourceLocation{*start, *end, nullptr}}}; + else if (!(sourceIndex >= 0 && m_sourceNames->count(static_cast(*sourceIndex)))) m_errorReporter.syntaxError( 2674_error, _commentLocation, @@ -246,9 +280,9 @@ std::optional> Parser::parseSrcComme ); else { - std::shared_ptr sourceName = m_sourceNames->at(static_cast(sourceIndex.value())); + std::shared_ptr sourceName = m_sourceNames->at(static_cast(*sourceIndex)); solAssert(sourceName, ""); - return {{tail, SourceLocation{start.value(), end.value(), std::move(sourceName)}}}; + return {{tail, SourceLocation{*start, *end, std::move(sourceName)}}}; } return {{tail, SourceLocation{}}}; } diff --git a/test/libyul/Parser.cpp b/test/libyul/Parser.cpp index 46c4f11a8c00..ca8784ddb6ef 100644 --- a/test/libyul/Parser.cpp +++ b/test/libyul/Parser.cpp @@ -33,6 +33,8 @@ #include #include +#include +#include #include #include @@ -767,6 +769,102 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_two_locations_with_snippets_untermina CHECK_LOCATION(result->debugData->originLocation, "", -1, -1); } +BOOST_AUTO_TEST_CASE(customSourceLocations_single_quote) +{ + ErrorList errorList; + ErrorReporter reporter(errorList); + auto const sourceText = R"( + /// @src 0:111:222 " + /// + {} + )"; + EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); + std::shared_ptr result = parse(sourceText, dialect, reporter); + BOOST_REQUIRE(!!result); + BOOST_REQUIRE(errorList.size() == 1); + BOOST_TEST(errorList[0]->type() == Error::Type::SyntaxError); + BOOST_TEST(errorList[0]->errorId() == 1544_error); + CHECK_LOCATION(result->debugData->originLocation, "", -1, -1); +} + +BOOST_AUTO_TEST_CASE(customSourceLocations_two_snippets_with_hex_comment) +{ + ErrorList errorList; + ErrorReporter reporter(errorList); + auto const sourceText = R"( + /// @src 0:111:222 hex"abc"@src 1:333:444 "abc" + {} + )"; + EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); + std::shared_ptr result = parse(sourceText, dialect, reporter); + BOOST_REQUIRE(!!result && errorList.size() == 0); + // the second source location is not parsed as such, as the hex string isn't interpreted as snippet but + // as the beginning of the tail in AsmParser + CHECK_LOCATION(result->debugData->originLocation, "source0", 111, 222); +} + +BOOST_AUTO_TEST_CASE(customSourceLocations_invalid_escapes) +{ + ErrorList errorList; + ErrorReporter reporter(errorList); + auto const sourceText = R"( + /// @src 0:111:222 "\n\\x\x\w\uö\xy\z\y\fq" + {} + )"; + EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); + std::shared_ptr result = parse(sourceText, dialect, reporter); + BOOST_REQUIRE(!!result && errorList.size() == 0); + CHECK_LOCATION(result->debugData->originLocation, "source0", 111, 222); +} + +BOOST_AUTO_TEST_CASE(customSourceLocations_single_quote_snippet_with_whitespaces_and_escapes) +{ + ErrorList errorList; + ErrorReporter reporter(errorList); + auto const sourceText = R"( + /// @src 0:111:222 '\n\\x\x\w\uö\xy\z\y\fq' + /// @src 1 : 222 : 333 '\x33\u1234\t\n' + {} + )"; + EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); + std::shared_ptr result = parse(sourceText, dialect, reporter); + BOOST_REQUIRE(!!result && errorList.size() == 0); + CHECK_LOCATION(result->debugData->originLocation, "source1", 222, 333); +} + +BOOST_DATA_TEST_CASE(customSourceLocations_scanner_errors_outside_string_lits_are_ignored, boost::unit_test::data::make({"0x ", "/** unterminated comment", "1_23_4"}), invalid) +{ + ErrorList errorList; + ErrorReporter reporter(errorList); + auto const sourceText = fmt::format(R"( + /// @src 0:111:222 {} + /// @src 1:222:333 + {{}} + )", invalid); + EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); + std::shared_ptr result = parse(sourceText, dialect, reporter); + BOOST_REQUIRE(!!result && errorList.empty()); + CHECK_LOCATION(result->debugData->originLocation, "source1", 222, 333); +} + +BOOST_AUTO_TEST_CASE(customSourceLocations_multi_line_source_loc) +{ + ErrorList errorList; + ErrorReporter reporter(errorList); + auto const sourceText = R"( + /// @src 1 : 111: + /// 222 " + /// abc\"def + /// + /// " @src 0:333:444 + {} + )"; + EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); + std::shared_ptr result = parse(sourceText, dialect, reporter); + BOOST_REQUIRE(!!result && errorList.empty()); + CHECK_LOCATION(result->debugData->originLocation, "source0", 333, 444); +} + BOOST_AUTO_TEST_CASE(customSourceLocations_with_code_snippets_with_nested_locations) { ErrorList errorList; From 8b0bb61a7a9392d07b965e88c267123743869426 Mon Sep 17 00:00:00 2001 From: clonker Date: Mon, 1 Jul 2024 18:30:03 +0200 Subject: [PATCH 0287/1022] CI: Re-enable *_bytecode_too_large_* and *_combined_too_large* tests --- .circleci/parallel_bytecode_report.sh | 3 --- 1 file changed, 3 deletions(-) diff --git a/.circleci/parallel_bytecode_report.sh b/.circleci/parallel_bytecode_report.sh index 7fe22c343283..ee9dfde9f3ae 100755 --- a/.circleci/parallel_bytecode_report.sh +++ b/.circleci/parallel_bytecode_report.sh @@ -44,9 +44,6 @@ cd test-cases/ echo "Preparing input files" python3 ../scripts/isolate_tests.py ../test/ -# FIXME: These cases crash because of https://github.com/ethereum/solidity/issues/13583 -rm ./*_bytecode_too_large_*.sol ./*_combined_too_large_*.sol - if [[ $binary_type == native || $binary_type == "osx_intel" ]]; then interface=$(echo -e "standard-json\ncli" | circleci tests split) echo "Selected interface: ${interface}" From ce02133054e276106a0cfa3784521cb6bed5fda8 Mon Sep 17 00:00:00 2001 From: clonker Date: Mon, 1 Jul 2024 09:53:22 +0200 Subject: [PATCH 0288/1022] BlockHasher: Do not hash literal kind --- Changelog.md | 1 + libyul/optimiser/BlockHasher.cpp | 1 - .../array/copying/function_type_array_to_storage.sol | 2 +- .../equivalentFunctionCombiner/constant_representation.yul | 2 +- test/libyul/yulOptimizerTests/fullSuite/devcon_example.yul | 2 +- .../yulOptimizerTests/fullSuite/loopInvariantCodeMotion.yul | 2 +- 6 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Changelog.md b/Changelog.md index 442c4e34f3e8..16920b50b5a3 100644 --- a/Changelog.md +++ b/Changelog.md @@ -10,6 +10,7 @@ Compiler Features: * EVM: Support for the EVM version "Prague". * SMTChecker: Add CHC engine check for underflow and overflow in unary minus operation. * SMTChecker: Replace CVC4 as a possible BMC backend with cvc5. + * Yul Optimizer: The optimizer now treats some previously unrecognized identical literals as identical. Bugfixes: diff --git a/libyul/optimiser/BlockHasher.cpp b/libyul/optimiser/BlockHasher.cpp index d5febca932c1..9d6db206675f 100644 --- a/libyul/optimiser/BlockHasher.cpp +++ b/libyul/optimiser/BlockHasher.cpp @@ -49,7 +49,6 @@ void ASTHasherBase::hashLiteral(solidity::yul::Literal const& _literal) else hash64(std::hash{}(_literal.value.builtinStringLiteralValue())); hash64(_literal.type.hash()); - hash8(static_cast(_literal.kind)); hash8(_literal.value.unlimited()); } diff --git a/test/libsolidity/semanticTests/array/copying/function_type_array_to_storage.sol b/test/libsolidity/semanticTests/array/copying/function_type_array_to_storage.sol index 097c7b4d10d2..e3490e2db09e 100644 --- a/test/libsolidity/semanticTests/array/copying/function_type_array_to_storage.sol +++ b/test/libsolidity/semanticTests/array/copying/function_type_array_to_storage.sol @@ -46,7 +46,7 @@ contract C { } // ---- // test() -> 0x20, 0x14, "[a called][b called]" -// gas irOptimized: 116530 +// gas irOptimized: 116531 // gas legacy: 118845 // gas legacyOptimized: 116844 // test2() -> 0x20, 0x14, "[b called][a called]" diff --git a/test/libyul/yulOptimizerTests/equivalentFunctionCombiner/constant_representation.yul b/test/libyul/yulOptimizerTests/equivalentFunctionCombiner/constant_representation.yul index 77df0ae20a1a..9d70f75d2af1 100644 --- a/test/libyul/yulOptimizerTests/equivalentFunctionCombiner/constant_representation.yul +++ b/test/libyul/yulOptimizerTests/equivalentFunctionCombiner/constant_representation.yul @@ -12,7 +12,7 @@ // { // f() // f() -// h() +// f() // function f() // { // mstore(29400335157912315244266070412362164103369332044010299463143527189509193072640, mload(0x00)) diff --git a/test/libyul/yulOptimizerTests/fullSuite/devcon_example.yul b/test/libyul/yulOptimizerTests/fullSuite/devcon_example.yul index fca4a6366bdf..5efebed09933 100644 --- a/test/libyul/yulOptimizerTests/fullSuite/devcon_example.yul +++ b/test/libyul/yulOptimizerTests/fullSuite/devcon_example.yul @@ -25,7 +25,7 @@ // let sum := 0 // let length := calldataload(_1) // let i := 0 -// for { } true { i := add(i, 1) } +// for { } 1 { i := add(i, 1) } // { // let _2 := iszero(lt(i, length)) // if _2 { break } diff --git a/test/libyul/yulOptimizerTests/fullSuite/loopInvariantCodeMotion.yul b/test/libyul/yulOptimizerTests/fullSuite/loopInvariantCodeMotion.yul index 76d671bfc3e2..a0be61939b1f 100644 --- a/test/libyul/yulOptimizerTests/fullSuite/loopInvariantCodeMotion.yul +++ b/test/libyul/yulOptimizerTests/fullSuite/loopInvariantCodeMotion.yul @@ -29,7 +29,7 @@ // let length := calldataload(_1) // let i := 0 // let _2 := calldataload(7) -// for { } true { i := add(i, 1) } +// for { } 1 { i := add(i, 1) } // { // let _3 := iszero(lt(i, length)) // if _3 { break } From 2696cff8da228924b7ece37986b124b67c52acb1 Mon Sep 17 00:00:00 2001 From: Daniel Kirchner Date: Tue, 2 Jul 2024 18:28:09 +0200 Subject: [PATCH 0289/1022] Relax memory safety. Co-authored-by: Moritz Hoffmann --- docs/assembly.rst | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/docs/assembly.rst b/docs/assembly.rst index cf2ce1bf9487..04742c504c9a 100644 --- a/docs/assembly.rst +++ b/docs/assembly.rst @@ -377,3 +377,18 @@ of Solidity, you can use a special comment to annotate an assembly block as memo Note that we will disallow the annotation via comment in a future breaking release; so, if you are not concerned with backward-compatibility with older compiler versions, prefer using the dialect string. + +Advanced Safe Use of Memory +--------------------------- + +Beyond the strict definition of memory-safety given above, there are cases in which you may want to use more than 64 bytes +of scratch space starting at memory offset ``0``. If you are careful, it can be admissible to use memory up to (and not +including) offset ``0x80`` and still safely declare the assembly block as ``memory-safe``. +This is admissible under either of the following conditions: + +- By the end of the assembly block, the free memory pointer at offset ``0x40`` is restored to a sane value (i.e. it is either + restored to its original value or an increment of it due to a manual memory allocation), and the memory word at offset ``0x60`` + is restored to a value of zero. + +- The assembly block terminates, i.e. execution can never return to high-level Solidity code. This is the case, for example, + if your assembly block unconditionally ends in a ``revert`` statement. From 22471ea5ae41a674cd8a8e420780b7841dfda283 Mon Sep 17 00:00:00 2001 From: Daniel Kirchner Date: Thu, 4 Jul 2024 13:27:12 +0200 Subject: [PATCH 0290/1022] More details about the zero pointer. --- docs/assembly.rst | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/assembly.rst b/docs/assembly.rst index 04742c504c9a..f57b1f0d92cc 100644 --- a/docs/assembly.rst +++ b/docs/assembly.rst @@ -392,3 +392,9 @@ This is admissible under either of the following conditions: - The assembly block terminates, i.e. execution can never return to high-level Solidity code. This is the case, for example, if your assembly block unconditionally ends in a ``revert`` statement. + +Furthermore, you need to be aware that the default-value of dynamic arrays in Solidity point to memory offset ``0x60``, so +for the duration of temporarily changing the value at memory offset ``0x60``, you can no longer rely on getting accurate +length values when reading dynamic arrays, until you restore the zero value at ``0x60``. To be more precise, we only guarantee +safety when overwriting the zero pointer, if the remainder of the assembly snippet does not interact with the memory of +high-level Solidity objects (including by reading from offsets previously stored in variables). From 318259c5f883cba10dca3ef2ebd039c93c732e63 Mon Sep 17 00:00:00 2001 From: Daniel Kirchner Date: Thu, 4 Jul 2024 13:40:03 +0200 Subject: [PATCH 0291/1022] Phrasing. --- docs/assembly.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/assembly.rst b/docs/assembly.rst index f57b1f0d92cc..34085bccb796 100644 --- a/docs/assembly.rst +++ b/docs/assembly.rst @@ -391,7 +391,7 @@ This is admissible under either of the following conditions: is restored to a value of zero. - The assembly block terminates, i.e. execution can never return to high-level Solidity code. This is the case, for example, - if your assembly block unconditionally ends in a ``revert`` statement. + if your assembly block unconditionally ends in calling the ``revert`` opcode. Furthermore, you need to be aware that the default-value of dynamic arrays in Solidity point to memory offset ``0x60``, so for the duration of temporarily changing the value at memory offset ``0x60``, you can no longer rely on getting accurate From 60eb07376f30cee8dc533b67eedacd3b533c6ac7 Mon Sep 17 00:00:00 2001 From: Martin Blicha Date: Fri, 5 Jul 2024 10:59:55 +0200 Subject: [PATCH 0292/1022] SMTChecker: Move formatting methods out of Predicate Some of the methods related to formatting SMT expressions do not depend on anything from the predicate, so we can make them free and move to more appropriate place. --- libsolidity/formal/ExpressionFormatter.cpp | 176 ++++++++++++++++++++- libsolidity/formal/ExpressionFormatter.h | 11 +- libsolidity/formal/Predicate.cpp | 166 +------------------ libsolidity/formal/Predicate.h | 6 - 4 files changed, 184 insertions(+), 175 deletions(-) diff --git a/libsolidity/formal/ExpressionFormatter.cpp b/libsolidity/formal/ExpressionFormatter.cpp index 5a3d11dbefd4..6571cf6dd7a2 100644 --- a/libsolidity/formal/ExpressionFormatter.cpp +++ b/libsolidity/formal/ExpressionFormatter.cpp @@ -18,13 +18,13 @@ #include +#include + #include #include #include -#include - #include #include #include @@ -182,4 +182,176 @@ std::string toSolidityStr(smtutil::Expression const& _expr) return op + "(" + boost::algorithm::join(strArgs, ", ") + ")"; } +namespace +{ +bool fillArray(smtutil::Expression const& _expr, std::vector& _array, ArrayType const& _type) +{ + // Base case + if (_expr.name == "const_array") + { + auto length = _array.size(); + std::optional elemStr = expressionToString(_expr.arguments.at(1), _type.baseType()); + if (!elemStr) + return false; + _array.clear(); + _array.resize(length, *elemStr); + return true; + } + + // Recursive case. + if (_expr.name == "store") + { + if (!fillArray(_expr.arguments.at(0), _array, _type)) + return false; + std::optional indexStr = expressionToString(_expr.arguments.at(1), TypeProvider::uint256()); + if (!indexStr) + return false; + // Sometimes the solver assigns huge lengths that are not related, + // we should catch and ignore those. + unsigned long index; + try + { + index = stoul(*indexStr); + } + catch (std::out_of_range const&) + { + return true; + } + catch (std::invalid_argument const&) + { + return true; + } + std::optional elemStr = expressionToString(_expr.arguments.at(2), _type.baseType()); + if (!elemStr) + return false; + if (index < _array.size()) + _array.at(index) = *elemStr; + return true; + } + + // Special base case, not supported yet. + if (_expr.name.rfind("(_ as-array") == 0) + { + // Z3 expression representing reinterpretation of a different term as an array + return false; + } + + solAssert(false); +} +} + +std::optional expressionToString(smtutil::Expression const& _expr, frontend::Type const* _type) +{ + if (smt::isNumber(*_type)) + { + solAssert(_expr.sort->kind == Kind::Int); + solAssert(_expr.arguments.empty()); + + if ( + _type->category() == frontend::Type::Category::Address || + _type->category() == frontend::Type::Category::FixedBytes + ) + { + try + { + if (_expr.name == "0") + return "0x0"; + // For some reason the code below returns "0x" for "0". + return util::toHex(toCompactBigEndian(bigint(_expr.name)), util::HexPrefix::Add, util::HexCase::Lower); + } + catch (std::out_of_range const&) + { + } + catch (std::invalid_argument const&) + { + } + } + + return _expr.name; + } + if (smt::isBool(*_type)) + { + solAssert(_expr.sort->kind == Kind::Bool); + solAssert(_expr.arguments.empty()); + solAssert(_expr.name == "true" || _expr.name == "false"); + return _expr.name; + } + if (smt::isFunction(*_type)) + { + solAssert(_expr.arguments.empty()); + return _expr.name; + } + if (smt::isArray(*_type)) + { + auto const& arrayType = dynamic_cast(*_type); + if (_expr.name != "tuple_constructor") + return {}; + + auto const& tupleSort = dynamic_cast(*_expr.sort); + solAssert(tupleSort.components.size() == 2); + + unsigned long length; + try + { + length = stoul(_expr.arguments.at(1).name); + } + catch(std::out_of_range const&) + { + return {}; + } + catch(std::invalid_argument const&) + { + return {}; + } + + // Limit this counterexample size to 1k. + // Some OSs give you "unlimited" memory through swap and other virtual memory, + // so purely relying on bad_alloc being thrown is not a good idea. + // In that case, the array allocation might cause OOM and the program is killed. + if (length >= 1024) + return {}; + try + { + std::vector array(length); + if (!fillArray(_expr.arguments.at(0), array, arrayType)) + return {}; + return "[" + boost::algorithm::join(array, ", ") + "]"; + } + catch (std::bad_alloc const&) + { + // Solver gave a concrete array but length is too large. + } + } + if (smt::isNonRecursiveStruct(*_type)) + { + auto const& structType = dynamic_cast(*_type); + solAssert(_expr.name == "tuple_constructor"); + auto const& tupleSort = dynamic_cast(*_expr.sort); + auto members = structType.structDefinition().members(); + solAssert(tupleSort.components.size() == members.size()); + solAssert(_expr.arguments.size() == members.size()); + std::vector elements; + for (unsigned i = 0; i < members.size(); ++i) + { + std::optional elementStr = expressionToString(_expr.arguments.at(i), members[i]->type()); + elements.push_back(members[i]->name() + (elementStr.has_value() ? ": " + elementStr.value() : "")); + } + return "{" + boost::algorithm::join(elements, ", ") + "}"; + } + + return {}; +} + +std::vector> formatExpressions( + std::vector const& _exprs, + std::vector const& _types +) +{ + solAssert(_exprs.size() == _types.size()); + std::vector> strExprs; + for (unsigned i = 0; i < _exprs.size(); ++i) + strExprs.push_back(expressionToString(_exprs.at(i), _types.at(i))); + return strExprs; +} + } diff --git a/libsolidity/formal/ExpressionFormatter.h b/libsolidity/formal/ExpressionFormatter.h index 3efbeb781f2c..e42fab26e3d9 100644 --- a/libsolidity/formal/ExpressionFormatter.h +++ b/libsolidity/formal/ExpressionFormatter.h @@ -19,10 +19,12 @@ #pragma once /** - * Formats SMT expressions into Solidity-like strings. + * Helper methods for formatting SMT expressions */ -#include +#include + +#include #include #include @@ -38,4 +40,9 @@ smtutil::Expression substitute(smtutil::Expression _from, std::map expressionToString(smtutil::Expression const& _expr, Type const* _type); + +/// @returns the formatted version of the given SMT expressions. Those expressions must be SMT constants. +std::vector> formatExpressions(std::vector const& _exprs, std::vector const& _types); } diff --git a/libsolidity/formal/Predicate.cpp b/libsolidity/formal/Predicate.cpp index 75314d7e9414..5cac3a6a9230 100644 --- a/libsolidity/formal/Predicate.cpp +++ b/libsolidity/formal/Predicate.cpp @@ -18,6 +18,7 @@ #include +#include #include #include @@ -485,171 +486,6 @@ std::map Predicate::expressionSubstitution(smtutil::Ex return subst; } -std::vector> Predicate::formatExpressions(std::vector const& _exprs, std::vector const& _types) const -{ - solAssert(_exprs.size() == _types.size(), ""); - std::vector> strExprs; - for (unsigned i = 0; i < _exprs.size(); ++i) - strExprs.push_back(expressionToString(_exprs.at(i), _types.at(i))); - return strExprs; -} - -std::optional Predicate::expressionToString(smtutil::Expression const& _expr, Type const* _type) const -{ - if (smt::isNumber(*_type)) - { - solAssert(_expr.sort->kind == Kind::Int, ""); - solAssert(_expr.arguments.empty(), ""); - - if ( - _type->category() == Type::Category::Address || - _type->category() == Type::Category::FixedBytes - ) - { - try - { - if (_expr.name == "0") - return "0x0"; - // For some reason the code below returns "0x" for "0". - return util::toHex(toCompactBigEndian(bigint(_expr.name)), util::HexPrefix::Add, util::HexCase::Lower); - } - catch (std::out_of_range const&) - { - } - catch (std::invalid_argument const&) - { - } - } - - return _expr.name; - } - if (smt::isBool(*_type)) - { - solAssert(_expr.sort->kind == Kind::Bool, ""); - solAssert(_expr.arguments.empty(), ""); - solAssert(_expr.name == "true" || _expr.name == "false", ""); - return _expr.name; - } - if (smt::isFunction(*_type)) - { - solAssert(_expr.arguments.empty(), ""); - return _expr.name; - } - if (smt::isArray(*_type)) - { - auto const& arrayType = dynamic_cast(*_type); - if (_expr.name != "tuple_constructor") - return {}; - - auto const& tupleSort = dynamic_cast(*_expr.sort); - solAssert(tupleSort.components.size() == 2, ""); - - unsigned long length; - try - { - length = stoul(_expr.arguments.at(1).name); - } - catch(std::out_of_range const&) - { - return {}; - } - catch(std::invalid_argument const&) - { - return {}; - } - - // Limit this counterexample size to 1k. - // Some OSs give you "unlimited" memory through swap and other virtual memory, - // so purely relying on bad_alloc being thrown is not a good idea. - // In that case, the array allocation might cause OOM and the program is killed. - if (length >= 1024) - return {}; - try - { - std::vector array(length); - if (!fillArray(_expr.arguments.at(0), array, arrayType)) - return {}; - return "[" + boost::algorithm::join(array, ", ") + "]"; - } - catch (std::bad_alloc const&) - { - // Solver gave a concrete array but length is too large. - } - } - if (smt::isNonRecursiveStruct(*_type)) - { - auto const& structType = dynamic_cast(*_type); - solAssert(_expr.name == "tuple_constructor", ""); - auto const& tupleSort = dynamic_cast(*_expr.sort); - auto members = structType.structDefinition().members(); - solAssert(tupleSort.components.size() == members.size(), ""); - solAssert(_expr.arguments.size() == members.size(), ""); - std::vector elements; - for (unsigned i = 0; i < members.size(); ++i) - { - std::optional elementStr = expressionToString(_expr.arguments.at(i), members[i]->type()); - elements.push_back(members[i]->name() + (elementStr.has_value() ? ": " + elementStr.value() : "")); - } - return "{" + boost::algorithm::join(elements, ", ") + "}"; - } - - return {}; -} - -bool Predicate::fillArray(smtutil::Expression const& _expr, std::vector& _array, ArrayType const& _type) const -{ - // Base case - if (_expr.name == "const_array") - { - auto length = _array.size(); - std::optional elemStr = expressionToString(_expr.arguments.at(1), _type.baseType()); - if (!elemStr) - return false; - _array.clear(); - _array.resize(length, *elemStr); - return true; - } - - // Recursive case. - if (_expr.name == "store") - { - if (!fillArray(_expr.arguments.at(0), _array, _type)) - return false; - std::optional indexStr = expressionToString(_expr.arguments.at(1), TypeProvider::uint256()); - if (!indexStr) - return false; - // Sometimes the solver assigns huge lengths that are not related, - // we should catch and ignore those. - unsigned long index; - try - { - index = stoul(*indexStr); - } - catch (std::out_of_range const&) - { - return true; - } - catch (std::invalid_argument const&) - { - return true; - } - std::optional elemStr = expressionToString(_expr.arguments.at(2), _type.baseType()); - if (!elemStr) - return false; - if (index < _array.size()) - _array.at(index) = *elemStr; - return true; - } - - // Special base case, not supported yet. - if (_expr.name.rfind("(_ as-array") == 0) - { - // Z3 expression representing reinterpretation of a different term as an array - return false; - } - - solAssert(false, ""); -} std::map> Predicate::readTxVars(smtutil::Expression const& _tx) const { diff --git a/libsolidity/formal/Predicate.h b/libsolidity/formal/Predicate.h index a7df44621849..f389ab822111 100644 --- a/libsolidity/formal/Predicate.h +++ b/libsolidity/formal/Predicate.h @@ -184,12 +184,6 @@ class Predicate std::map expressionSubstitution(smtutil::Expression const& _predExprs) const; private: - /// @returns the formatted version of the given SMT expressions. Those expressions must be SMT constants. - std::vector> formatExpressions(std::vector const& _exprs, std::vector const& _types) const; - - /// @returns a string representation of the SMT expression based on a Solidity type. - std::optional expressionToString(smtutil::Expression const& _expr, Type const* _type) const; - /// Recursively fills _array from _expr. /// _expr should have the form `store(store(...(const_array(x_0), i_0, e_0), i_m, e_m), i_k, e_k)`. /// @returns true if the construction worked, From 08a98d1914d127dbc755cb20c789ab3a90f9066e Mon Sep 17 00:00:00 2001 From: Meet Mangukiya Date: Sun, 7 Jul 2024 15:19:57 +0530 Subject: [PATCH 0293/1022] OptimizedEVMCodeTransform: tag source location in stack too deep errors in yul --- libyul/backends/evm/OptimizedEVMCodeTransform.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libyul/backends/evm/OptimizedEVMCodeTransform.cpp b/libyul/backends/evm/OptimizedEVMCodeTransform.cpp index 047014e3dc43..8731f2cc5d28 100644 --- a/libyul/backends/evm/OptimizedEVMCodeTransform.cpp +++ b/libyul/backends/evm/OptimizedEVMCodeTransform.cpp @@ -275,7 +275,7 @@ void OptimizedEVMCodeTransform::createStackLayout(langutil::DebugData::ConstPtr varNameDeep.empty() ? varNameTop : varNameDeep, deficit, msg - )); + ) << langutil::errinfo_sourceLocation(sourceLocation)); m_assembly.markAsInvalid(); } }, From 4c857f50ccd73c86b0d1f0b17cc4be298bd99058 Mon Sep 17 00:00:00 2001 From: Martin Blicha Date: Tue, 9 Jul 2024 16:45:27 +0200 Subject: [PATCH 0294/1022] SMTChecker: Increase Z3 resource limit Increasing resource limit of z3 results in more SMTChecker tests correctly solved, without increasing the running time significantly. This is in preparation for switching z3 to SMT-LIB interface, so as to not have significant changes in tests for that switch. --- libsmtutil/Z3Interface.h | 2 +- .../abi_encode_with_selector_array_slice.sol | 4 +-- ...abi_encode_with_selector_array_slice_2.sol | 4 +-- .../deployment/deploy_trusted_flow.sol | 10 ++----- .../external_call_indirect_1.sol | 2 +- .../external_call_indirect_3.sol | 3 +- .../external_call_indirect_4.sol | 3 +- .../external_call_indirect_5.sol | 2 +- ..._loop_array_assignment_storage_storage.sol | 10 +++---- .../operators/index_access_side_effect.sol | 4 +-- .../operators/slice_default_start.sol | 7 ++--- ...rator_matches_equivalent_function_call.sol | 28 ++----------------- .../smtCheckerTests/out_of_bounds/array_1.sol | 7 ++--- 13 files changed, 22 insertions(+), 64 deletions(-) diff --git a/libsmtutil/Z3Interface.h b/libsmtutil/Z3Interface.h index ee268ac41d65..d5dc5792e0ae 100644 --- a/libsmtutil/Z3Interface.h +++ b/libsmtutil/Z3Interface.h @@ -55,7 +55,7 @@ class Z3Interface: public SolverInterface // Z3 "basic resources" limit. // This is used to make the runs more deterministic and platform/machine independent. - static int const resourceLimit = 1000000; + static int const resourceLimit = 2000000; private: void declareFunction(std::string const& _name, Sort const& _sort); diff --git a/test/libsolidity/smtCheckerTests/abi/abi_encode_with_selector_array_slice.sol b/test/libsolidity/smtCheckerTests/abi/abi_encode_with_selector_array_slice.sol index 67c8b92e6203..ed6f627b5adb 100644 --- a/test/libsolidity/smtCheckerTests/abi/abi_encode_with_selector_array_slice.sol +++ b/test/libsolidity/smtCheckerTests/abi/abi_encode_with_selector_array_slice.sol @@ -28,6 +28,4 @@ contract C { // ---- // Warning 6328: (325-355): CHC: Assertion violation happens here. // Warning 6328: (578-608): CHC: Assertion violation happens here. -// Warning 6328: (1079-1109): CHC: Assertion violation might happen here. -// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. -// Warning 4661: (1079-1109): BMC: Assertion violation happens here. +// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/abi/abi_encode_with_selector_array_slice_2.sol b/test/libsolidity/smtCheckerTests/abi/abi_encode_with_selector_array_slice_2.sol index 69a3482b199d..c13e9ce07fc7 100644 --- a/test/libsolidity/smtCheckerTests/abi/abi_encode_with_selector_array_slice_2.sol +++ b/test/libsolidity/smtCheckerTests/abi/abi_encode_with_selector_array_slice_2.sol @@ -28,6 +28,4 @@ contract C { // ---- // Warning 6328: (326-356): CHC: Assertion violation happens here. // Warning 6328: (579-609): CHC: Assertion violation happens here. -// Warning 6328: (1080-1110): CHC: Assertion violation might happen here. -// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. -// Warning 4661: (1080-1110): BMC: Assertion violation happens here. +// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/deployment/deploy_trusted_flow.sol b/test/libsolidity/smtCheckerTests/deployment/deploy_trusted_flow.sol index 2148324ad911..60f3c9415a6e 100644 --- a/test/libsolidity/smtCheckerTests/deployment/deploy_trusted_flow.sol +++ b/test/libsolidity/smtCheckerTests/deployment/deploy_trusted_flow.sol @@ -18,13 +18,9 @@ contract C { // ==== // SMTEngine: all // SMTExtCalls: trusted -// SMTIgnoreOS: macos // ---- // Warning 4984: (47-50): CHC: Overflow (resulting value larger than 2**256 - 1) might happen here. -// Warning 6328: (215-233): CHC: Assertion violation might happen here. -// Warning 6328: (267-285): CHC: Assertion violation might happen here. -// Warning 6328: (304-322): CHC: Assertion violation happens here. -// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. +// Warning 6328: (304-322): CHC: Assertion violation might happen here. +// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. // Warning 2661: (47-50): BMC: Overflow (resulting value larger than 2**256 - 1) happens here. -// Warning 4661: (215-233): BMC: Assertion violation happens here. -// Warning 4661: (267-285): BMC: Assertion violation happens here. +// Warning 4661: (304-322): BMC: Assertion violation happens here. diff --git a/test/libsolidity/smtCheckerTests/external_calls/external_call_indirect_1.sol b/test/libsolidity/smtCheckerTests/external_calls/external_call_indirect_1.sol index c6b46b2f87bf..dd8a529a2f1f 100644 --- a/test/libsolidity/smtCheckerTests/external_calls/external_call_indirect_1.sol +++ b/test/libsolidity/smtCheckerTests/external_calls/external_call_indirect_1.sol @@ -38,5 +38,5 @@ contract C { // SMTIgnoreOS: macos // ---- // Warning 6328: (256-277): CHC: Assertion violation happens here. -// Warning 6328: (533-554): CHC: Assertion violation might happen here. +// Warning 6328: (533-554): CHC: Assertion violation happens here. // Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/external_calls/external_call_indirect_3.sol b/test/libsolidity/smtCheckerTests/external_calls/external_call_indirect_3.sol index ff17649dd968..d7721037fb88 100644 --- a/test/libsolidity/smtCheckerTests/external_calls/external_call_indirect_3.sol +++ b/test/libsolidity/smtCheckerTests/external_calls/external_call_indirect_3.sol @@ -40,7 +40,6 @@ contract C { // ==== // SMTEngine: chc // SMTExtCalls: trusted -// SMTIgnoreOS: macos // ---- -// Warning 6328: (561-582): CHC: Assertion violation might happen here. +// Warning 6328: (561-582): CHC: Assertion violation happens here. // Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/external_calls/external_call_indirect_4.sol b/test/libsolidity/smtCheckerTests/external_calls/external_call_indirect_4.sol index 766f6e133446..96adba8843fb 100644 --- a/test/libsolidity/smtCheckerTests/external_calls/external_call_indirect_4.sol +++ b/test/libsolidity/smtCheckerTests/external_calls/external_call_indirect_4.sol @@ -43,7 +43,6 @@ contract C { // ==== // SMTEngine: chc // SMTExtCalls: trusted -// SMTIgnoreOS: macos // ---- -// Warning 6328: (641-662): CHC: Assertion violation might happen here. +// Warning 6328: (641-662): CHC: Assertion violation happens here. // Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/external_calls/external_call_indirect_5.sol b/test/libsolidity/smtCheckerTests/external_calls/external_call_indirect_5.sol index 9313858ce2b1..26d39838ef4b 100644 --- a/test/libsolidity/smtCheckerTests/external_calls/external_call_indirect_5.sol +++ b/test/libsolidity/smtCheckerTests/external_calls/external_call_indirect_5.sol @@ -47,5 +47,5 @@ contract C { // SMTEngine: chc // SMTExtCalls: trusted // ---- -// Warning 6328: (601-622): CHC: Assertion violation might happen here. +// Warning 6328: (601-622): CHC: Assertion violation happens here. // Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/loops/while_loop_array_assignment_storage_storage.sol b/test/libsolidity/smtCheckerTests/loops/while_loop_array_assignment_storage_storage.sol index ed7ebdfba570..4bfd1750024a 100644 --- a/test/libsolidity/smtCheckerTests/loops/while_loop_array_assignment_storage_storage.sol +++ b/test/libsolidity/smtCheckerTests/loops/while_loop_array_assignment_storage_storage.sol @@ -23,10 +23,8 @@ contract LoopFor2 { } } // ==== -// SMTEngine: all +// SMTEngine: chc +// SMTTargets: assert // ---- -// Warning 6368: (288-292): CHC: Out of bounds access might happen here. -// Warning 6368: (459-463): CHC: Out of bounds access happens here. -// Warning 6328: (452-471): CHC: Assertion violation happens here. -// Warning 6328: (475-494): CHC: Assertion violation happens here. -// Info 1391: CHC: 4 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. +// Warning 6328: (452-471): CHC: Assertion violation happens here.\nCounterexample:\nb = [1, 0], c = [0, 0]\nn = 1\ni = 1\n\nTransaction trace:\nLoopFor2.constructor()\nState: b = [], c = []\nLoopFor2.p()\nState: b = [0], c = [0]\nLoopFor2.p()\nState: b = [0, 0], c = [0, 0]\nLoopFor2.testUnboundedForLoop(1) +// Warning 6328: (475-494): CHC: Assertion violation happens here.\nCounterexample:\nb = [1, 0], c = [0, 0]\nn = 1\ni = 1\n\nTransaction trace:\nLoopFor2.constructor()\nState: b = [], c = []\nLoopFor2.p()\nState: b = [0], c = [0]\nLoopFor2.p()\nState: b = [0, 0], c = [0, 0]\nLoopFor2.testUnboundedForLoop(1) diff --git a/test/libsolidity/smtCheckerTests/operators/index_access_side_effect.sol b/test/libsolidity/smtCheckerTests/operators/index_access_side_effect.sol index d3b6f5895b85..644ecdb122f8 100644 --- a/test/libsolidity/smtCheckerTests/operators/index_access_side_effect.sol +++ b/test/libsolidity/smtCheckerTests/operators/index_access_side_effect.sol @@ -22,6 +22,4 @@ contract C { // SMTEngine: all // SMTIgnoreCex: yes // ---- -// Warning 6328: (335-354): CHC: Assertion violation might happen here. -// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. -// Warning 4661: (335-354): BMC: Assertion violation happens here. +// Info 1391: CHC: 4 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/operators/slice_default_start.sol b/test/libsolidity/smtCheckerTests/operators/slice_default_start.sol index ef422245d3f8..c4da3b4b69ee 100644 --- a/test/libsolidity/smtCheckerTests/operators/slice_default_start.sol +++ b/test/libsolidity/smtCheckerTests/operators/slice_default_start.sol @@ -10,8 +10,5 @@ contract C { // ==== // SMTEngine: all // ---- -// Warning 6328: (150-182): CHC: Assertion violation might happen here. -// Warning 6328: (186-218): CHC: Assertion violation might happen here. -// Info 1391: CHC: 4 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. -// Warning 4661: (150-182): BMC: Assertion violation happens here. -// Warning 4661: (186-218): BMC: Assertion violation happens here. +// Warning 6328: (186-218): CHC: Assertion violation happens here. +// Info 1391: CHC: 5 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/operators/userDefined/user_defined_operator_matches_equivalent_function_call.sol b/test/libsolidity/smtCheckerTests/operators/userDefined/user_defined_operator_matches_equivalent_function_call.sol index 206c63042488..76ad6db55384 100644 --- a/test/libsolidity/smtCheckerTests/operators/userDefined/user_defined_operator_matches_equivalent_function_call.sol +++ b/test/libsolidity/smtCheckerTests/operators/userDefined/user_defined_operator_matches_equivalent_function_call.sol @@ -53,32 +53,10 @@ contract C { } // ==== // SMTEngine: all +// SMTTargets: assert // ---- -// Warning 3944: (679-708): CHC: Underflow (resulting value less than -32768) might happen here. -// Warning 4984: (679-708): CHC: Overflow (resulting value larger than 32767) might happen here. -// Warning 3944: (777-806): CHC: Underflow (resulting value less than -32768) might happen here. -// Warning 4984: (777-806): CHC: Overflow (resulting value larger than 32767) might happen here. -// Warning 3944: (870-884): CHC: Underflow (resulting value less than -32768) might happen here. -// Warning 4984: (870-884): CHC: Overflow (resulting value larger than 32767) might happen here. -// Warning 3944: (953-982): CHC: Underflow (resulting value less than -32768) might happen here. -// Warning 4984: (953-982): CHC: Overflow (resulting value larger than 32767) might happen here. -// Warning 4984: (1051-1080): CHC: Overflow (resulting value larger than 32767) might happen here. -// Warning 4281: (1051-1080): CHC: Division by zero might happen here. -// Warning 4281: (1149-1178): CHC: Division by zero might happen here. -// Warning 6328: (2069-2095): CHC: Assertion violation might happen here. -// Warning 6328: (2105-2131): CHC: Assertion violation might happen here. -// Warning 6328: (2141-2163): CHC: Assertion violation might happen here. -// Warning 6328: (2173-2199): CHC: Assertion violation might happen here. // Warning 6328: (2209-2235): CHC: Assertion violation might happen here. // Warning 6328: (2245-2271): CHC: Assertion violation might happen here. -// Info 1391: CHC: 10 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. -// Warning 2661: (679-708): BMC: Overflow (resulting value larger than 32767) happens here. -// Warning 4144: (679-708): BMC: Underflow (resulting value less than -32768) happens here. -// Warning 2661: (777-806): BMC: Overflow (resulting value larger than 32767) happens here. -// Warning 4144: (777-806): BMC: Underflow (resulting value less than -32768) happens here. -// Warning 2661: (953-982): BMC: Overflow (resulting value larger than 32767) happens here. -// Warning 4144: (953-982): BMC: Underflow (resulting value less than -32768) happens here. -// Warning 3046: (1051-1080): BMC: Division by zero happens here. -// Warning 3046: (1149-1178): BMC: Division by zero happens here. +// Info 1391: CHC: 14 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. // Warning 7812: (2245-2271): BMC: Assertion violation might happen here. -// Info 6002: BMC: 14 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. +// Info 6002: BMC: 1 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/out_of_bounds/array_1.sol b/test/libsolidity/smtCheckerTests/out_of_bounds/array_1.sol index 65a1dfd39015..c52599b03c7a 100644 --- a/test/libsolidity/smtCheckerTests/out_of_bounds/array_1.sol +++ b/test/libsolidity/smtCheckerTests/out_of_bounds/array_1.sol @@ -18,9 +18,6 @@ contract C { } // ==== // SMTEngine: all -// SMTIgnoreOS: macos +// SMTTargets: outOfBounds // ---- -// Warning 4984: (112-115): CHC: Overflow (resulting value larger than 2**256 - 1) might happen here. -// Warning 6368: (259-263): CHC: Out of bounds access happens here. -// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. -// Warning 2661: (112-115): BMC: Overflow (resulting value larger than 2**256 - 1) happens here. +// Warning 6368: (259-263): CHC: Out of bounds access happens here.\nCounterexample:\na = [0], l = 1\n = 0\n\nTransaction trace:\nC.constructor()\nState: a = [], l = 0\nC.p()\nState: a = [0], l = 1\nC.r() From e0c58e539cebdc9a1de8ae1d27bdb69311b5418c Mon Sep 17 00:00:00 2001 From: Martin Blicha Date: Wed, 10 Jul 2024 16:37:04 +0200 Subject: [PATCH 0295/1022] SMTChecker: Simplify some of the long running tests --- .../smtCheckerTests/abi/abi_decode_array.sol | 20 +++++++------------ .../smtCheckerTests/types/array_branch_3d.sol | 4 ++-- .../array_struct_array_struct_memory_safe.sol | 3 ++- ...array_struct_array_struct_storage_safe.sol | 3 ++- .../smtCheckerTests/types/type_minmax.sol | 11 +--------- .../types/type_simple_range.sol | 14 +++++++++++++ 6 files changed, 28 insertions(+), 27 deletions(-) create mode 100644 test/libsolidity/smtCheckerTests/types/type_simple_range.sol diff --git a/test/libsolidity/smtCheckerTests/abi/abi_decode_array.sol b/test/libsolidity/smtCheckerTests/abi/abi_decode_array.sol index da30d302fedf..c7db3645ac00 100644 --- a/test/libsolidity/smtCheckerTests/abi/abi_decode_array.sol +++ b/test/libsolidity/smtCheckerTests/abi/abi_decode_array.sol @@ -7,9 +7,7 @@ contract C { (uint[] memory c, uint[] memory d) = abi.decode(b1, (uint[], uint[])); assert(a.length == c.length); - assert(a.length == d.length); // should fail assert(b.length == d.length); - assert(b.length == c.length); // should fail (uint[] memory e, uint[] memory f, uint[] memory g) = abi.decode(b1, (uint[], uint[], uint[])); assert(e.length == a.length); // should fail @@ -24,7 +22,6 @@ contract C { (uint[] memory k, uint[] memory l) = abi.decode(b2, (uint[], uint[])); assert(k.length == a.length); // should fail - assert(k.length == l.length); // should fail assert(l.length == b.length); // should fail } } @@ -32,14 +29,11 @@ contract C { // SMTEngine: all // SMTIgnoreCex: yes // ---- -// Warning 6328: (182-210): CHC: Assertion violation happens here. -// Warning 6328: (335-363): CHC: Assertion violation happens here. -// Warning 6328: (414-442): CHC: Assertion violation happens here. -// Warning 6328: (560-588): CHC: Assertion violation happens here. -// Warning 6328: (607-635): CHC: Assertion violation happens here. -// Warning 6328: (654-682): CHC: Assertion violation happens here. -// Warning 6328: (879-916): CHC: Assertion violation happens here. -// Warning 6328: (1009-1037): CHC: Assertion violation happens here. -// Warning 6328: (1056-1084): CHC: Assertion violation happens here. -// Warning 6328: (1103-1131): CHC: Assertion violation happens here. +// Warning 6328: (182-210): CHC: Assertion violation happens here.\nCounterexample:\n\nc = []\nd = []\ne = []\nf = []\ng = []\nh = []\ni = []\nj = 0\nk = []\nl = []\n\nTransaction trace:\nC.constructor()\nC.abiDecodeArray(b1, b2) -- counterexample incomplete; parameter name used instead of value +// Warning 6328: (466-494): CHC: Assertion violation happens here.\nCounterexample:\n\nf = [83, 83, 83, 83, 83, 83, 67, 83, 83, 83, 83, 83, 70, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 72, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 71, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83]\ng = [65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 55, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 60, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65]\nh = []\ni = []\nj = 0\nk = []\nl = []\n\nTransaction trace:\nC.constructor()\nC.abiDecodeArray(b1, b2) -- counterexample incomplete; parameter name used instead of value +// Warning 6328: (513-541): CHC: Assertion violation happens here.\nCounterexample:\n\ng = [65, 65, 65, 65, 65, 65, 65, 64, 65, 47, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 48, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65]\nh = []\ni = []\nj = 0\nk = []\nl = []\n\nTransaction trace:\nC.constructor()\nC.abiDecodeArray(b1, b2) -- counterexample incomplete; parameter name used instead of value +// Warning 6328: (560-588): CHC: Assertion violation happens here.\nCounterexample:\n\nb = []\nd = []\nh = []\ni = []\nj = 0\nk = []\nl = []\n\nTransaction trace:\nC.constructor()\nC.abiDecodeArray(b1, b2) -- counterexample incomplete; parameter name used instead of value +// Warning 6328: (785-822): CHC: Assertion violation happens here.\nCounterexample:\n\nf = [144]\nj = 8365\nk = []\nl = []\n\nTransaction trace:\nC.constructor()\nC.abiDecodeArray(b1, b2) -- counterexample incomplete; parameter name used instead of value +// Warning 6328: (915-943): CHC: Assertion violation happens here.\nCounterexample:\n\nj = 8365\nl = [35, 35, 35, 35, 35]\n\nTransaction trace:\nC.constructor()\nC.abiDecodeArray(b1, b2) -- counterexample incomplete; parameter name used instead of value +// Warning 6328: (962-990): CHC: Assertion violation happens here.\nCounterexample:\n\nj = 32285\n\nTransaction trace:\nC.constructor()\nC.abiDecodeArray(b1, b2) -- counterexample incomplete; parameter name used instead of value // Info 1391: CHC: 6 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/types/array_branch_3d.sol b/test/libsolidity/smtCheckerTests/types/array_branch_3d.sol index 3aced164c867..6c6404c117f9 100644 --- a/test/libsolidity/smtCheckerTests/types/array_branch_3d.sol +++ b/test/libsolidity/smtCheckerTests/types/array_branch_3d.sol @@ -15,6 +15,6 @@ contract C // ==== // SMTEngine: chc // SMTSolvers: eld +// SMTTargets: assert // ---- -// Warning 6328: (152-174): CHC: Assertion violation happens here. -// Info 1391: CHC: 9 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. +// Warning 6328: (152-174): CHC: Assertion violation happens here.\nCounterexample:\nc = [[[0]]]\nb = false\n\nTransaction trace:\nC.constructor()\nState: c = [[[0]]]\nC.f(false) diff --git a/test/libsolidity/smtCheckerTests/types/struct/array_struct_array_struct_memory_safe.sol b/test/libsolidity/smtCheckerTests/types/struct/array_struct_array_struct_memory_safe.sol index bc5ddf49ed7a..972c7797075b 100644 --- a/test/libsolidity/smtCheckerTests/types/struct/array_struct_array_struct_memory_safe.sol +++ b/test/libsolidity/smtCheckerTests/types/struct/array_struct_array_struct_memory_safe.sol @@ -32,5 +32,6 @@ contract C { } // ==== // SMTEngine: all +// SMTTargets: assert // ---- -// Info 1391: CHC: 29 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. +// Info 1391: CHC: 6 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/types/struct/array_struct_array_struct_storage_safe.sol b/test/libsolidity/smtCheckerTests/types/struct/array_struct_array_struct_storage_safe.sol index b2f7b9825c7d..ce5f375c464e 100644 --- a/test/libsolidity/smtCheckerTests/types/struct/array_struct_array_struct_storage_safe.sol +++ b/test/libsolidity/smtCheckerTests/types/struct/array_struct_array_struct_storage_safe.sol @@ -52,5 +52,6 @@ contract C { } // ==== // SMTEngine: all +// SMTTargets: assert // ---- -// Info 1391: CHC: 51 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. +// Info 1391: CHC: 5 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/types/type_minmax.sol b/test/libsolidity/smtCheckerTests/types/type_minmax.sol index da9bb1b6d15f..eb739c5e9ea0 100644 --- a/test/libsolidity/smtCheckerTests/types/type_minmax.sol +++ b/test/libsolidity/smtCheckerTests/types/type_minmax.sol @@ -1,12 +1,4 @@ contract C { - function f(uint a) public pure { - assert(a <= type(uint).max); - assert(a >= type(uint).min); - require(a <= type(uint64).max); - assert(a <= type(uint64).max); - assert(a <= type(uint32).max); - } - function int_min() public pure { int8 int8_min = type(int8).min; assert(int8_min == -2**7); @@ -81,5 +73,4 @@ contract C { // ==== // SMTEngine: all // ---- -// Warning 6328: (178-207): CHC: Assertion violation happens here. -// Info 1391: CHC: 24 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. +// Info 1391: CHC: 21 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/types/type_simple_range.sol b/test/libsolidity/smtCheckerTests/types/type_simple_range.sol new file mode 100644 index 000000000000..579b232d73e6 --- /dev/null +++ b/test/libsolidity/smtCheckerTests/types/type_simple_range.sol @@ -0,0 +1,14 @@ +contract C { + function f(uint a) public pure { + assert(a <= type(uint).max); + assert(a >= type(uint).min); + require(a <= type(uint64).max); + assert(a <= type(uint64).max); + assert(a <= type(uint32).max); // should fail + } +} +// ==== +// SMTEngine: all +// ---- +// Warning 6328: (178-207): CHC: Assertion violation happens here.\nCounterexample:\n\na = 4294967296\n\nTransaction trace:\nC.constructor()\nC.f(4294967296) +// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. From 54686862ece4f0e3430600849a7a69df57cf68ac Mon Sep 17 00:00:00 2001 From: clonker Date: Wed, 10 Jul 2024 14:55:07 +0200 Subject: [PATCH 0296/1022] Yul: Add const version of FunctionCallFinder --- libyul/backends/evm/EVMObjectCompiler.cpp | 4 +-- libyul/optimiser/FullInliner.cpp | 2 +- libyul/optimiser/FunctionCallFinder.cpp | 41 ++++++++++++++++++----- libyul/optimiser/FunctionCallFinder.h | 24 ++++++------- libyul/optimiser/StackLimitEvader.cpp | 4 +-- test/libsolidity/MemoryGuardTest.cpp | 2 +- 6 files changed, 49 insertions(+), 28 deletions(-) diff --git a/libyul/backends/evm/EVMObjectCompiler.cpp b/libyul/backends/evm/EVMObjectCompiler.cpp index 28b72c0871ee..0bd064940eb7 100644 --- a/libyul/backends/evm/EVMObjectCompiler.cpp +++ b/libyul/backends/evm/EVMObjectCompiler.cpp @@ -90,8 +90,8 @@ void EVMObjectCompiler::run(Object& _object, bool _optimize) ); if (!stackErrors.empty()) { - std::vector memoryGuardCalls = FunctionCallFinder::run( - *_object.code, + std::vector memoryGuardCalls = findFunctionCalls( + std::as_const(*_object.code), "memoryguard"_yulstring ); auto stackError = stackErrors.front(); diff --git a/libyul/optimiser/FullInliner.cpp b/libyul/optimiser/FullInliner.cpp index 6e4d8497199f..3bf00282c04b 100644 --- a/libyul/optimiser/FullInliner.cpp +++ b/libyul/optimiser/FullInliner.cpp @@ -83,7 +83,7 @@ FullInliner::FullInliner(Block& _ast, NameDispenser& _dispenser, Dialect const& } // Check for memory guard. - std::vector memoryGuardCalls = FunctionCallFinder::run( + std::vector memoryGuardCalls = findFunctionCalls( _ast, "memoryguard"_yulstring ); diff --git a/libyul/optimiser/FunctionCallFinder.cpp b/libyul/optimiser/FunctionCallFinder.cpp index 9d94dc5f9ca1..99f171026e9e 100644 --- a/libyul/optimiser/FunctionCallFinder.cpp +++ b/libyul/optimiser/FunctionCallFinder.cpp @@ -16,23 +16,46 @@ */ #include + +#include #include using namespace solidity; using namespace solidity::yul; -std::vector FunctionCallFinder::run(Block& _block, YulString _functionName) +namespace +{ +template +class MaybeConstFunctionCallFinder: Base { - FunctionCallFinder functionCallFinder(_functionName); - functionCallFinder(_block); - return functionCallFinder.m_calls; +public: + using MaybeConstBlock = std::conditional_t, Block const, Block>; + static std::vector run(MaybeConstBlock& _block, YulString const _functionName) + { + MaybeConstFunctionCallFinder functionCallFinder(_functionName); + functionCallFinder(_block); + return functionCallFinder.m_calls; + } +private: + explicit MaybeConstFunctionCallFinder(YulString const _functionName): m_functionName(_functionName), m_calls() {} + using Base::operator(); + void operator()(ResultType& _functionCall) override + { + Base::operator()(_functionCall); + if (_functionCall.functionName.name == m_functionName) + m_calls.emplace_back(&_functionCall); + } + YulString m_functionName; + std::vector m_calls; +}; } -FunctionCallFinder::FunctionCallFinder(YulString _functionName): m_functionName(_functionName) {} +std::vector solidity::yul::findFunctionCalls(Block& _block, YulString _functionName) +{ + return MaybeConstFunctionCallFinder::run(_block, _functionName); +} -void FunctionCallFinder::operator()(FunctionCall& _functionCall) +std::vector solidity::yul::findFunctionCalls(Block const& _block, YulString _functionName) { - ASTModifier::operator()(_functionCall); - if (_functionCall.functionName.name == m_functionName) - m_calls.emplace_back(&_functionCall); + return MaybeConstFunctionCallFinder::run(_block, _functionName); } diff --git a/libyul/optimiser/FunctionCallFinder.h b/libyul/optimiser/FunctionCallFinder.h index 365f86688b74..a5d4da56e916 100644 --- a/libyul/optimiser/FunctionCallFinder.h +++ b/libyul/optimiser/FunctionCallFinder.h @@ -20,7 +20,8 @@ #pragma once -#include +#include +#include #include @@ -28,20 +29,17 @@ namespace solidity::yul { /** - * AST walker that finds all calls to a function of a given name. + * Finds all calls to a function of a given name using an ASTModifier. * * Prerequisite: Disambiguator */ -class FunctionCallFinder: ASTModifier -{ -public: - static std::vector run(Block& _block, YulString _functionName); -private: - FunctionCallFinder(YulString _functionName); - using ASTModifier::operator(); - void operator()(FunctionCall& _functionCall) override; - YulString m_functionName; - std::vector m_calls; -}; +std::vector findFunctionCalls(Block& _block, YulString _functionName); + +/** + * Finds all calls to a function of a given name using an ASTWalker. + * + * Prerequisite: Disambiguator + */ +std::vector findFunctionCalls(Block const& _block, YulString _functionName); } diff --git a/libyul/optimiser/StackLimitEvader.cpp b/libyul/optimiser/StackLimitEvader.cpp index 904ee77e00f9..0310858a187b 100644 --- a/libyul/optimiser/StackLimitEvader.cpp +++ b/libyul/optimiser/StackLimitEvader.cpp @@ -174,7 +174,7 @@ void StackLimitEvader::run( "StackLimitEvader can only be run on objects using the EVMDialect with object access." ); - std::vector memoryGuardCalls = FunctionCallFinder::run( + std::vector memoryGuardCalls = findFunctionCalls( *_object.code, "memoryguard"_yulstring ); @@ -206,7 +206,7 @@ void StackLimitEvader::run( StackToMemoryMover::run(_context, reservedMemory, memoryOffsetAllocator.slotAllocations, requiredSlots, *_object.code); reservedMemory += 32 * requiredSlots; - for (FunctionCall* memoryGuardCall: FunctionCallFinder::run(*_object.code, "memoryguard"_yulstring)) + for (FunctionCall* memoryGuardCall: findFunctionCalls(*_object.code, "memoryguard"_yulstring)) { Literal* literal = std::get_if(&memoryGuardCall->arguments.front()); yulAssert(literal && literal->kind == LiteralKind::Number, ""); diff --git a/test/libsolidity/MemoryGuardTest.cpp b/test/libsolidity/MemoryGuardTest.cpp index 7f0914cc4ef4..caa85c6fde8f 100644 --- a/test/libsolidity/MemoryGuardTest.cpp +++ b/test/libsolidity/MemoryGuardTest.cpp @@ -73,7 +73,7 @@ TestCase::TestResult MemoryGuardTest::run(std::ostream& _stream, std::string con } auto handleObject = [&](std::string const& _kind, Object const& _object) { - m_obtainedResult += contractName + "(" + _kind + ") " + (FunctionCallFinder::run( + m_obtainedResult += contractName + "(" + _kind + ") " + (findFunctionCalls( *_object.code, "memoryguard"_yulstring ).empty() ? "false" : "true") + "\n"; From f53bb02c52f7c63e59da8299ab9dc72872c2795f Mon Sep 17 00:00:00 2001 From: Martin Blicha Date: Wed, 10 Jul 2024 21:46:10 +0200 Subject: [PATCH 0297/1022] SMTChecker: Further test simplifications --- .../deployment/deploy_trusted_flow.sol | 8 +++--- ...code_state_reentrancy_indirect_trusted.sol | 24 +++++++---------- .../external_calls/external_inc.sol | 8 +++--- .../external_calls/external_safe.sol | 5 ++-- .../types/array_branches_3d.sol | 10 ++----- .../types/array_branches_3d_show_unproved.sol | 27 ------------------- .../types/array_static_mapping_aliasing_1.sol | 10 +++---- .../types/array_static_mapping_aliasing_2.sol | 12 +++------ 8 files changed, 29 insertions(+), 75 deletions(-) delete mode 100644 test/libsolidity/smtCheckerTests/types/array_branches_3d_show_unproved.sol diff --git a/test/libsolidity/smtCheckerTests/deployment/deploy_trusted_flow.sol b/test/libsolidity/smtCheckerTests/deployment/deploy_trusted_flow.sol index 60f3c9415a6e..4a447d63164b 100644 --- a/test/libsolidity/smtCheckerTests/deployment/deploy_trusted_flow.sol +++ b/test/libsolidity/smtCheckerTests/deployment/deploy_trusted_flow.sol @@ -1,6 +1,6 @@ contract D { uint x; - function inc() public { ++x; } + function inc() public { require(x < 5); ++x; } function f() public view returns (uint) { return x; } } @@ -18,9 +18,7 @@ contract C { // ==== // SMTEngine: all // SMTExtCalls: trusted +// SMTTargets: assert // ---- -// Warning 4984: (47-50): CHC: Overflow (resulting value larger than 2**256 - 1) might happen here. -// Warning 6328: (304-322): CHC: Assertion violation might happen here. +// Warning 6328: (320-338): CHC: Assertion violation happens here. // Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. -// Warning 2661: (47-50): BMC: Overflow (resulting value larger than 2**256 - 1) happens here. -// Warning 4661: (304-322): BMC: Assertion violation happens here. diff --git a/test/libsolidity/smtCheckerTests/external_calls/external_hash_known_code_state_reentrancy_indirect_trusted.sol b/test/libsolidity/smtCheckerTests/external_calls/external_hash_known_code_state_reentrancy_indirect_trusted.sol index 8000b3267d9e..e689c21b4b98 100644 --- a/test/libsolidity/smtCheckerTests/external_calls/external_hash_known_code_state_reentrancy_indirect_trusted.sol +++ b/test/libsolidity/smtCheckerTests/external_calls/external_hash_known_code_state_reentrancy_indirect_trusted.sol @@ -1,9 +1,5 @@ contract Other { - C c; - constructor(C _c) { - c = _c; - } - function h() public { + function h(C c) public { c.setOwner(address(0)); } } @@ -11,13 +7,11 @@ contract Other { contract State { uint x; Other o; - C c; - constructor(C _c) { - c = _c; - o = new Other(_c); + constructor() { + o = new Other(); } - function f() public returns (uint) { - o.h(); + function f(C c) public returns (uint) { + o.h(c); return c.g(); } } @@ -29,7 +23,7 @@ contract C { constructor() { owner = msg.sender; - s = new State(this); + s = new State(); } function setOwner(address _owner) public { @@ -38,7 +32,7 @@ contract C { function f() public { address prevOwner = owner; - uint z = s.f(); + uint z = s.f(this); assert(z == y); // should hold assert(prevOwner == owner); // should not hold because of reentrancy } @@ -52,5 +46,5 @@ contract C { // SMTEngine: chc // SMTExtCalls: trusted // ---- -// Warning 6328: (531-545): CHC: Assertion violation might happen here. -// Warning 6328: (564-590): CHC: Assertion violation happens here. +// Warning 6328: (509-535): CHC: Assertion violation happens here. +// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/external_calls/external_inc.sol b/test/libsolidity/smtCheckerTests/external_calls/external_inc.sol index 22a4551c8588..117d3fa72187 100644 --- a/test/libsolidity/smtCheckerTests/external_calls/external_inc.sol +++ b/test/libsolidity/smtCheckerTests/external_calls/external_inc.sol @@ -7,18 +7,18 @@ contract C { D d; function inc() public { + require(x < 10); ++x; } function f() public { d.d(); - assert(x < 10); + assert(x < 5); } } // ==== // SMTEngine: all // SMTIgnoreCex: yes // ---- -// Warning 4984: (113-116): CHC: Overflow (resulting value larger than 2**256 - 1) might happen here. -// Warning 6328: (156-170): CHC: Assertion violation happens here. -// Warning 2661: (113-116): BMC: Overflow (resulting value larger than 2**256 - 1) happens here. +// Warning 6328: (175-188): CHC: Assertion violation happens here.\nCounterexample:\nx = 5, d = 0\n\nTransaction trace:\nC.constructor()\nState: x = 0, d = 0\nC.inc()\nState: x = 1, d = 0\nC.inc()\nState: x = 2, d = 0\nC.inc()\nState: x = 3, d = 0\nC.inc()\nState: x = 4, d = 0\nC.f()\n d.d() -- untrusted external call, synthesized as:\n C.inc() -- reentrant call +// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/external_calls/external_safe.sol b/test/libsolidity/smtCheckerTests/external_calls/external_safe.sol index 593aba289ca3..bfc95b35a2fd 100644 --- a/test/libsolidity/smtCheckerTests/external_calls/external_safe.sol +++ b/test/libsolidity/smtCheckerTests/external_calls/external_safe.sol @@ -6,16 +6,15 @@ contract C { uint x; D d; function f() public { - if (x < 10) + if (x < 5) ++x; } function g() public { d.d(); - assert(x < 11); + assert(x < 6); } } // ==== // SMTEngine: all -// SMTIgnoreOS: macos // ---- // Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/types/array_branches_3d.sol b/test/libsolidity/smtCheckerTests/types/array_branches_3d.sol index 8e9499183a6f..9dbdde90fb85 100644 --- a/test/libsolidity/smtCheckerTests/types/array_branches_3d.sol +++ b/test/libsolidity/smtCheckerTests/types/array_branches_3d.sol @@ -15,12 +15,6 @@ contract C } // ==== // SMTEngine: all -// SMTIgnoreOS: macos +// SMTTargets: assert // ---- -// Warning 6368: (124-131): CHC: Out of bounds access might happen here. -// Warning 6368: (124-134): CHC: Out of bounds access might happen here. -// Warning 6368: (152-159): CHC: Out of bounds access might happen here. -// Warning 6368: (152-162): CHC: Out of bounds access might happen here. -// Warning 6368: (177-184): CHC: Out of bounds access might happen here. -// Warning 6368: (177-187): CHC: Out of bounds access might happen here. -// Info 1391: CHC: 7 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. +// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/types/array_branches_3d_show_unproved.sol b/test/libsolidity/smtCheckerTests/types/array_branches_3d_show_unproved.sol deleted file mode 100644 index 7e9aad5b01df..000000000000 --- a/test/libsolidity/smtCheckerTests/types/array_branches_3d_show_unproved.sol +++ /dev/null @@ -1,27 +0,0 @@ -contract C -{ - uint[][][] c; - constructor() { - c.push(); - c[0].push(); - c[0][0].push(); - } - function f(bool b) public { - c[0][0][0] = 0; - if (b) - c[0][0][0] = 1; - assert(c[0][0][0] < 2); - } -} -// ==== -// SMTEngine: all -// SMTShowUnproved: yes -// SMTIgnoreOS: macos -// ---- -// Warning 6368: (124-131): CHC: Out of bounds access might happen here. -// Warning 6368: (124-134): CHC: Out of bounds access might happen here. -// Warning 6368: (152-159): CHC: Out of bounds access might happen here. -// Warning 6368: (152-162): CHC: Out of bounds access might happen here. -// Warning 6368: (177-184): CHC: Out of bounds access might happen here. -// Warning 6368: (177-187): CHC: Out of bounds access might happen here. -// Info 1391: CHC: 7 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/types/array_static_mapping_aliasing_1.sol b/test/libsolidity/smtCheckerTests/types/array_static_mapping_aliasing_1.sol index 7ee1acf47b35..8d727f018a9b 100644 --- a/test/libsolidity/smtCheckerTests/types/array_static_mapping_aliasing_1.sol +++ b/test/libsolidity/smtCheckerTests/types/array_static_mapping_aliasing_1.sol @@ -5,7 +5,6 @@ contract C mapping (uint => uint8)[2] severalMaps8; mapping (uint => uint)[2][2] severalMaps3d; function f(mapping (uint => uint) storage map) internal { - // Accesses are safe but oob is reported because of aliasing. severalMaps[0][0] = 42; severalMaps8[0][0] = 42; severalMaps3d[0][0][0] = 42; @@ -15,8 +14,7 @@ contract C // Should not fail since knowledge is erased only for mapping (uint => uint). assert(severalMaps8[0][0] == 42); // Should fail since map == severalMaps3d[0][0] is possible. - // Removed because current Spacer seg faults in cex generation. - //assert(severalMaps3d[0][0][0] == 42); + assert(severalMaps3d[0][0][0] == 42); } function g(uint x) public { require(x < severalMaps.length); @@ -26,6 +24,8 @@ contract C // ==== // SMTEngine: all // SMTIgnoreCex: yes +// SMTTargets: assert // ---- -// Warning 6328: (456-487): CHC: Assertion violation happens here. -// Info 1391: CHC: 8 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. +// Warning 6328: (392-423): CHC: Assertion violation happens here.\nCounterexample:\n\nx = 0\n\nTransaction trace:\nC.constructor()\nC.g(0)\n C.f(map) -- counterexample incomplete; parameter name used instead of value -- internal call +// Warning 6328: (606-642): CHC: Assertion violation happens here.\nCounterexample:\n\nx = 0\n\nTransaction trace:\nC.constructor()\nC.g(0)\n C.f(map) -- counterexample incomplete; parameter name used instead of value -- internal call +// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/types/array_static_mapping_aliasing_2.sol b/test/libsolidity/smtCheckerTests/types/array_static_mapping_aliasing_2.sol index 1f167b8586ab..f05487dcb94f 100644 --- a/test/libsolidity/smtCheckerTests/types/array_static_mapping_aliasing_2.sol +++ b/test/libsolidity/smtCheckerTests/types/array_static_mapping_aliasing_2.sol @@ -5,7 +5,6 @@ contract C mapping (uint => uint8)[2] severalMaps8; mapping (uint => uint)[2][2] severalMaps3d; function f(mapping (uint => uint) storage map) internal { - // Accesses are safe but reported as unsafe due to aliasing. map[0] = 42; severalMaps[0][0] = 42; severalMaps8[0][0] = 42; @@ -16,8 +15,7 @@ contract C // Should not fail since knowledge is erased only for mapping (uint => uint). assert(severalMaps8[0][0] == 42); // Should not fail since singleMap == severalMaps3d[0][0] is not possible. - // Removed because of Spacer nondeterminism. - //assert(severalMaps3d[0][0][0] == 42); + assert(severalMaps3d[0][0][0] == 42); // Should fail since singleMap == map is possible. assert(map[0] == 42); } @@ -29,9 +27,7 @@ contract C // ==== // SMTEngine: all // SMTIgnoreCex: yes +// SMTTargets: assert // ---- -// Warning 6368: (340-355): CHC: Out of bounds access might happen here. -// Warning 6368: (612-627): CHC: Out of bounds access might happen here. -// Warning 6328: (860-880): CHC: Assertion violation happens here. -// Warning 6368: (936-952): CHC: Out of bounds access might happen here. -// Info 1391: CHC: 7 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. +// Warning 6328: (748-768): CHC: Assertion violation happens here.\nCounterexample:\n\nx = 0\n\nTransaction trace:\nC.constructor()\nC.g(0)\n C.f(map) -- counterexample incomplete; parameter name used instead of value -- internal call +// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. From 678e352f2093184b5cd1faee54783cfab74978ed Mon Sep 17 00:00:00 2001 From: clonker Date: Mon, 15 Jul 2024 10:55:03 +0200 Subject: [PATCH 0298/1022] Yul: Object node names are std::string instead of YulString --- libsolidity/interface/StandardCompiler.cpp | 2 +- libyul/AsmAnalysis.cpp | 2 +- libyul/AsmAnalysis.h | 4 +-- libyul/Object.cpp | 41 +++++++++++----------- libyul/Object.h | 10 +++--- libyul/ObjectParser.cpp | 18 ++++++---- libyul/ObjectParser.h | 4 +-- libyul/YulStack.cpp | 2 +- libyul/backends/evm/EVMDialect.cpp | 16 ++++----- libyul/backends/evm/EVMDialect.h | 2 +- libyul/backends/evm/EVMObjectCompiler.cpp | 6 ++-- test/libsolidity/MemoryGuardTest.cpp | 2 +- tools/yulPhaser/Program.cpp | 2 +- 13 files changed, 57 insertions(+), 54 deletions(-) diff --git a/libsolidity/interface/StandardCompiler.cpp b/libsolidity/interface/StandardCompiler.cpp index 5510b543077c..b908ab0cc6fd 100644 --- a/libsolidity/interface/StandardCompiler.cpp +++ b/libsolidity/interface/StandardCompiler.cpp @@ -1638,7 +1638,7 @@ Json StandardCompiler::compileYul(InputsAndSettings _inputsAndSettings) return output; } - std::string contractName = stack.parserResult()->name.str(); + std::string contractName = stack.parserResult()->name; bool const wildcardMatchesExperimental = true; if (isArtifactRequested(_inputsAndSettings.outputSelection, sourceName, contractName, "ir", wildcardMatchesExperimental)) diff --git a/libyul/AsmAnalysis.cpp b/libyul/AsmAnalysis.cpp index ac97f988d47d..38b9c782e0fc 100644 --- a/libyul/AsmAnalysis.cpp +++ b/libyul/AsmAnalysis.cpp @@ -428,7 +428,7 @@ std::vector AsmAnalyzer::operator()(FunctionCall const& _funCall) if (functionName == "datasize" || functionName == "dataoffset") { auto const& argumentAsLiteral = std::get(arg); - if (!m_dataNames.count(YulString(formatLiteral(argumentAsLiteral)))) + if (!m_dataNames.count(formatLiteral(argumentAsLiteral))) m_errorReporter.typeError( 3517_error, nativeLocationOf(arg), diff --git a/libyul/AsmAnalysis.h b/libyul/AsmAnalysis.h index c49e6855914d..9dd4b2292383 100644 --- a/libyul/AsmAnalysis.h +++ b/libyul/AsmAnalysis.h @@ -61,7 +61,7 @@ class AsmAnalyzer langutil::ErrorReporter& _errorReporter, Dialect const& _dialect, ExternalIdentifierAccess::Resolver _resolver = ExternalIdentifierAccess::Resolver(), - std::set _dataNames = {} + std::set _dataNames = {} ): m_resolver(std::move(_resolver)), m_info(_analysisInfo), @@ -128,7 +128,7 @@ class AsmAnalyzer langutil::EVMVersion m_evmVersion; Dialect const& m_dialect; /// Names of data objects to be referenced by builtin functions with literal arguments. - std::set m_dataNames; + std::set m_dataNames; ForLoop const* m_currentForLoop = nullptr; /// Worst side effects encountered during analysis (including within defined functions). SideEffects m_sideEffects; diff --git a/libyul/Object.cpp b/libyul/Object.cpp index 260cb733011f..76d8bdc66780 100644 --- a/libyul/Object.cpp +++ b/libyul/Object.cpp @@ -40,7 +40,7 @@ using namespace solidity::yul; std::string Data::toString(Dialect const*, DebugInfoSelection const&, CharStreamProvider const*) const { - return "data \"" + name.str() + "\" hex\"" + util::toHex(data) + "\""; + return "data \"" + name + "\" hex\"" + util::toHex(data) + "\""; } std::string Object::toString( @@ -72,7 +72,7 @@ std::string Object::toString( for (auto const& obj: subObjects) inner += "\n" + obj->toString(_dialect, _debugInfoSelection, _soliditySourceProvider); - return useSrcComment + "object \"" + name.str() + "\" {\n" + indent(inner) + "\n}"; + return useSrcComment + "object \"" + name + "\" {\n" + indent(inner) + "\n}"; } Json Data::toJson() const @@ -97,62 +97,61 @@ Json Object::toJson() const Json ret; ret["nodeType"] = "YulObject"; - ret["name"] = name.str(); + ret["name"] = name; ret["code"] = codeJson; ret["subObjects"] = subObjectsJson; return ret; } -std::set Object::qualifiedDataNames() const +std::set Object::qualifiedDataNames() const { - std::set qualifiedNames = - name.empty() || util::contains(name.str(), '.') ? - std::set{} : - std::set{name}; + std::set qualifiedNames = + name.empty() || util::contains(name, '.') ? + std::set{} : + std::set{name}; for (std::shared_ptr const& subObjectNode: subObjects) { yulAssert(qualifiedNames.count(subObjectNode->name) == 0, ""); - if (util::contains(subObjectNode->name.str(), '.')) + if (util::contains(subObjectNode->name, '.')) continue; qualifiedNames.insert(subObjectNode->name); if (auto const* subObject = dynamic_cast(subObjectNode.get())) - for (YulString const& subSubObj: subObject->qualifiedDataNames()) + for (auto const& subSubObj: subObject->qualifiedDataNames()) if (subObject->name != subSubObj) { - yulAssert(qualifiedNames.count(YulString{subObject->name.str() + "." + subSubObj.str()}) == 0, ""); - qualifiedNames.insert(YulString{subObject->name.str() + "." + subSubObj.str()}); + yulAssert(qualifiedNames.count(subObject->name + "." + subSubObj) == 0, ""); + qualifiedNames.insert(subObject->name + "." + subSubObj); } } - yulAssert(qualifiedNames.count(YulString{}) == 0, ""); - qualifiedNames.erase(YulString{}); + yulAssert(qualifiedNames.count("") == 0, ""); return qualifiedNames; } -std::vector Object::pathToSubObject(YulString _qualifiedName) const +std::vector Object::pathToSubObject(std::string_view _qualifiedName) const { yulAssert(_qualifiedName != name, ""); yulAssert(subIndexByName.count(name) == 0, ""); - if (boost::algorithm::starts_with(_qualifiedName.str(), name.str() + ".")) - _qualifiedName = YulString{_qualifiedName.str().substr(name.str().length() + 1)}; + if (boost::algorithm::starts_with(_qualifiedName, name + ".")) + _qualifiedName = _qualifiedName.substr(name.length() + 1); yulAssert(!_qualifiedName.empty(), ""); std::vector subObjectPathComponents; - boost::algorithm::split(subObjectPathComponents, _qualifiedName.str(), boost::is_any_of(".")); + boost::algorithm::split(subObjectPathComponents, _qualifiedName, boost::is_any_of(".")); std::vector path; Object const* object = this; for (std::string const& currentSubObjectName: subObjectPathComponents) { yulAssert(!currentSubObjectName.empty(), ""); - auto subIndexIt = object->subIndexByName.find(YulString{currentSubObjectName}); + auto subIndexIt = object->subIndexByName.find(currentSubObjectName); yulAssert( subIndexIt != object->subIndexByName.end(), - "Assembly object <" + _qualifiedName.str() + "> not found or does not contain code." + "Assembly object <" + std::string(_qualifiedName) + "> not found or does not contain code." ); object = dynamic_cast(object->subObjects[subIndexIt->second].get()); - yulAssert(object, "Assembly object <" + _qualifiedName.str() + "> not found or does not contain code."); + yulAssert(object, "Assembly object <" + std::string(_qualifiedName) + "> not found or does not contain code."); yulAssert(object->subId != std::numeric_limits::max(), ""); path.push_back({object->subId}); } diff --git a/libyul/Object.h b/libyul/Object.h index 54a8080d08c0..c1ca9244d98d 100644 --- a/libyul/Object.h +++ b/libyul/Object.h @@ -52,7 +52,7 @@ struct ObjectNode /// Name of the object. /// Can be empty since .yul files can also just contain code, without explicitly placing it in an object. - YulString name; + std::string name; virtual std::string toString( Dialect const* _dialect, langutil::DebugInfoSelection const& _debugInfoSelection, @@ -66,7 +66,7 @@ struct ObjectNode */ struct Data: public ObjectNode { - Data(YulString _name, bytes _data): data(std::move(_data)) { name = _name; } + Data(std::string _name, bytes _data): data(std::move(_data)) { name = _name; } bytes data; @@ -102,7 +102,7 @@ struct Object: public ObjectNode /// @returns the set of names of data objects accessible from within the code of /// this object, including the name of object itself /// Handles all names containing dots as reserved identifiers, not accessible as data. - std::set qualifiedDataNames() const; + std::set qualifiedDataNames() const; /// @returns vector of subIDs if possible to reach subobject with @a _qualifiedName, throws otherwise /// For "B.C" should return vector of two values if success (subId of B and subId of C in B). @@ -114,14 +114,14 @@ struct Object: public ObjectNode /// pathToSubObject("E2.F3.H4") == {1, 0, 2} /// pathToSubObject("A1.E2") == {1} /// The path must not lead to a @a Data object (will throw in that case). - std::vector pathToSubObject(YulString _qualifiedName) const; + std::vector pathToSubObject(std::string_view _qualifiedName) const; /// sub id for object if it is subobject of another object, max value if it is not subobject size_t subId = std::numeric_limits::max(); std::shared_ptr code; std::vector> subObjects; - std::map subIndexByName; + std::map> subIndexByName; std::shared_ptr analysisInfo; std::shared_ptr debugData; diff --git a/libyul/ObjectParser.cpp b/libyul/ObjectParser.cpp index a02b9660b978..1f5363fd8d59 100644 --- a/libyul/ObjectParser.cpp +++ b/libyul/ObjectParser.cpp @@ -50,7 +50,7 @@ std::shared_ptr ObjectParser::parse(std::shared_ptr const& _sca { // Special case: Code-only form. object = std::make_shared(); - object->name = "object"_yulstring; + object->name = "object"; auto sourceNameMapping = tryParseSourceNameMapping(); object->debugData = std::make_shared(ObjectDebugData{sourceNameMapping}); object->code = parseBlock(sourceNameMapping); @@ -185,7 +185,7 @@ void ObjectParser::parseData(Object& _containingObject) ); advance(); - YulString name = parseUniqueName(&_containingObject); + auto const name = parseUniqueName(&_containingObject); if (currentToken() == Token::HexStringLiteral) expectToken(Token::HexStringLiteral, false); @@ -195,22 +195,26 @@ void ObjectParser::parseData(Object& _containingObject) advance(); } -YulString ObjectParser::parseUniqueName(Object const* _containingObject) +std::string ObjectParser::parseUniqueName(Object const* _containingObject) { expectToken(Token::StringLiteral, false); - YulString name{currentLiteral()}; + auto const name = currentLiteral(); if (name.empty()) parserError(3287_error, "Object name cannot be empty."); else if (_containingObject && _containingObject->name == name) parserError(8311_error, "Object name cannot be the same as the name of the containing object."); else if (_containingObject && _containingObject->subIndexByName.count(name)) - parserError(8794_error, "Object name \"" + name.str() + "\" already exists inside the containing object."); + parserError(8794_error, "Object name \"" + name + "\" already exists inside the containing object."); advance(); return name; } -void ObjectParser::addNamedSubObject(Object& _container, YulString _name, std::shared_ptr _subObject) +void ObjectParser::addNamedSubObject(Object& _container, std::string_view const _name, std::shared_ptr _subObject) { - _container.subIndexByName[_name] = _container.subObjects.size(); + _container.subIndexByName.emplace( + std::piecewise_construct, + std::forward_as_tuple(_name), + std::forward_as_tuple(_container.subObjects.size()) + ); _container.subObjects.emplace_back(std::move(_subObject)); } diff --git a/libyul/ObjectParser.h b/libyul/ObjectParser.h index 716a191ea878..08a852991203 100644 --- a/libyul/ObjectParser.h +++ b/libyul/ObjectParser.h @@ -63,8 +63,8 @@ class ObjectParser: public langutil::ParserBase void parseData(Object& _containingObject); /// Tries to parse a name that is non-empty and unique inside the containing object. - YulString parseUniqueName(Object const* _containingObject); - void addNamedSubObject(Object& _container, YulString _name, std::shared_ptr _subObject); + std::string parseUniqueName(Object const* _containingObject); + void addNamedSubObject(Object& _container, std::string_view _name, std::shared_ptr _subObject); Dialect const& m_dialect; }; diff --git a/libyul/YulStack.cpp b/libyul/YulStack.cpp index 94e9ad7a8d55..27b4b5526b85 100644 --- a/libyul/YulStack.cpp +++ b/libyul/YulStack.cpp @@ -198,7 +198,7 @@ void YulStack::optimize(Object& _object, bool _isCreation) for (auto& subNode: _object.subObjects) if (auto subObject = dynamic_cast(subNode.get())) { - bool isCreation = !boost::ends_with(subObject->name.str(), "_deployed"); + bool isCreation = !boost::ends_with(subObject->name, "_deployed"); optimize(*subObject, isCreation); } diff --git a/libyul/backends/evm/EVMDialect.cpp b/libyul/backends/evm/EVMDialect.cpp index 856689c91ad4..d3b9c34bcb5a 100644 --- a/libyul/backends/evm/EVMDialect.cpp +++ b/libyul/backends/evm/EVMDialect.cpp @@ -249,14 +249,14 @@ std::map createBuiltins(langutil::EVMVersion _ yulAssert(_call.arguments.size() == 1, ""); Expression const& arg = _call.arguments.front(); YulString const dataName (formatLiteral(std::get(arg))); - if (_context.currentObject->name == dataName) + if (_context.currentObject->name == dataName.str()) _assembly.appendAssemblySize(); else { std::vector subIdPath = - _context.subIDs.count(dataName) == 0 ? - _context.currentObject->pathToSubObject(dataName) : - std::vector{_context.subIDs.at(dataName)}; + _context.subIDs.count(dataName.str()) == 0 ? + _context.currentObject->pathToSubObject(dataName.str()) : + std::vector{_context.subIDs.at(dataName.str())}; yulAssert(!subIdPath.empty(), "Could not find assembly object <" + dataName.str() + ">."); _assembly.appendDataSize(subIdPath); } @@ -270,14 +270,14 @@ std::map createBuiltins(langutil::EVMVersion _ yulAssert(_call.arguments.size() == 1, ""); Expression const& arg = _call.arguments.front(); YulString const dataName (formatLiteral(std::get(arg))); - if (_context.currentObject->name == dataName) + if (_context.currentObject->name == dataName.str()) _assembly.appendConstant(0); else { std::vector subIdPath = - _context.subIDs.count(dataName) == 0 ? - _context.currentObject->pathToSubObject(dataName) : - std::vector{_context.subIDs.at(dataName)}; + _context.subIDs.count(dataName.str()) == 0 ? + _context.currentObject->pathToSubObject(dataName.str()) : + std::vector{_context.subIDs.at(dataName.str())}; yulAssert(!subIdPath.empty(), "Could not find assembly object <" + dataName.str() + ">."); _assembly.appendDataOffset(subIdPath); } diff --git a/libyul/backends/evm/EVMDialect.h b/libyul/backends/evm/EVMDialect.h index 28649f3e5e90..f0455a8e4240 100644 --- a/libyul/backends/evm/EVMDialect.h +++ b/libyul/backends/evm/EVMDialect.h @@ -45,7 +45,7 @@ struct BuiltinContext { Object const* currentObject = nullptr; /// Mapping from named objects to abstract assembly sub IDs. - std::map subIDs; + std::map subIDs; }; struct BuiltinFunctionForEVM: public BuiltinFunction diff --git a/libyul/backends/evm/EVMObjectCompiler.cpp b/libyul/backends/evm/EVMObjectCompiler.cpp index 0bd064940eb7..81a345f90889 100644 --- a/libyul/backends/evm/EVMObjectCompiler.cpp +++ b/libyul/backends/evm/EVMObjectCompiler.cpp @@ -55,8 +55,8 @@ void EVMObjectCompiler::run(Object& _object, bool _optimize) for (auto const& subNode: _object.subObjects) if (auto* subObject = dynamic_cast(subNode.get())) { - bool isCreation = !boost::ends_with(subObject->name.str(), "_deployed"); - auto subAssemblyAndID = m_assembly.createSubAssembly(isCreation, subObject->name.str()); + bool isCreation = !boost::ends_with(subObject->name, "_deployed"); + auto subAssemblyAndID = m_assembly.createSubAssembly(isCreation, subObject->name); context.subIDs[subObject->name] = subAssemblyAndID.second; subObject->subId = subAssemblyAndID.second; compile(*subObject, *subAssemblyAndID.first, m_dialect, _optimize, m_eofVersion); @@ -65,7 +65,7 @@ void EVMObjectCompiler::run(Object& _object, bool _optimize) { Data const& data = dynamic_cast(*subNode); // Special handling of metadata. - if (data.name.str() == Object::metadataName()) + if (data.name == Object::metadataName()) m_assembly.appendToAuxiliaryData(data.data); else context.subIDs[data.name] = m_assembly.appendData(data.data); diff --git a/test/libsolidity/MemoryGuardTest.cpp b/test/libsolidity/MemoryGuardTest.cpp index caa85c6fde8f..6e44afccf4f7 100644 --- a/test/libsolidity/MemoryGuardTest.cpp +++ b/test/libsolidity/MemoryGuardTest.cpp @@ -80,7 +80,7 @@ TestCase::TestResult MemoryGuardTest::run(std::ostream& _stream, std::string con }; handleObject("creation", *object); size_t deployedIndex = object->subIndexByName.at( - YulString(IRNames::deployedObject(compiler().contractDefinition(contractName))) + IRNames::deployedObject(compiler().contractDefinition(contractName)) ); handleObject("runtime", dynamic_cast(*object->subObjects[deployedIndex])); } diff --git a/tools/yulPhaser/Program.cpp b/tools/yulPhaser/Program.cpp index 00abcc8e5c31..1586f602064b 100644 --- a/tools/yulPhaser/Program.cpp +++ b/tools/yulPhaser/Program.cpp @@ -135,7 +135,7 @@ std::variant, ErrorList> Program::parseObject(Dialect con // The other object references the nested one which makes analysis fail. Below we try to // extract just the nested one for that reason. This is just a heuristic. If there's no // subobject with such a suffix we fall back to accepting the whole object as is. - if (subObject != nullptr && subObject->name.str() == object->name.str() + "_deployed") + if (subObject != nullptr && subObject->name == object->name + "_deployed") { deployedObject = dynamic_cast(subObject.get()); if (deployedObject != nullptr) From d6bf14ae3035df916b1b67667467a08b96cd61f1 Mon Sep 17 00:00:00 2001 From: r0qs Date: Wed, 7 Jun 2023 12:17:10 +0200 Subject: [PATCH 0299/1022] Implementation of Lengauer-Tarjan algorithm to find dominators MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Kamil Śliwak --- libsolutil/CMakeLists.txt | 1 + libsolutil/DominatorFinder.h | 412 +++++++++++ test/CMakeLists.txt | 1 + test/libsolutil/DominatorFinderTest.cpp | 920 ++++++++++++++++++++++++ 4 files changed, 1334 insertions(+) create mode 100644 libsolutil/DominatorFinder.h create mode 100644 test/libsolutil/DominatorFinderTest.cpp diff --git a/libsolutil/CMakeLists.txt b/libsolutil/CMakeLists.txt index 0fdb23b0445f..291c95c0d14b 100644 --- a/libsolutil/CMakeLists.txt +++ b/libsolutil/CMakeLists.txt @@ -8,6 +8,7 @@ set(sources CommonIO.cpp CommonIO.h cxx20.h + DominatorFinder.h Exceptions.cpp Exceptions.h ErrorCodes.h diff --git a/libsolutil/DominatorFinder.h b/libsolutil/DominatorFinder.h new file mode 100644 index 000000000000..ba86f6f022e0 --- /dev/null +++ b/libsolutil/DominatorFinder.h @@ -0,0 +1,412 @@ +/* + 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 +/** + * Dominator analysis of a control flow graph. + * The implementation is based on the following paper: + * https://www.cs.princeton.edu/courses/archive/spr03/cs423/download/dominators.pdf + * See appendix B pg. 139. + */ +#pragma once + +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +namespace +{ + template + struct has_id : std::false_type {}; + + template + struct has_id().id)>> : std::true_type {}; +} + +namespace solidity::util +{ + +/// DominatorFinder computes the dominator tree of a directed graph. +/// V is the type of the vertex and it is assumed to have a unique identifier. +/// ForEachSuccessor is a visitor that visits the successors of a vertex. +/// +/// The graph must contain at least one vertex (the entry point) and is assumed to not be disconnected. +/// Only vertices reachable from the entry vertex are visited. +template +class DominatorFinder +{ +public: + static_assert(has_id::value, "vertex must define id member"); + using VId = typename V::Id; + using DfsIndex = size_t; + + DominatorFinder(V const& _entry): + m_immediateDominators(findDominators(_entry)) + { + buildDominatorTree(); + } + + std::vector const& verticesIdsInDFSOrder() const + { + return m_verticesInDFSOrder; + } + + std::map const& dfsIndexById() const + { + return m_dfsIndexByVertexId; + } + + std::map> const immediateDominators() const + { + return m_immediateDominators + | ranges::views::enumerate + | ranges::views::transform([&](auto const& _v) { + std::optional idomId = (_v.second.has_value()) ? std::optional(m_verticesInDFSOrder[_v.second.value()]) : std::nullopt; + return std::make_pair(m_verticesInDFSOrder[_v.first], idomId); + }) + | ranges::to>>; + } + + std::vector> const& immediateDominatorsByDfsIndex() const + { + return m_immediateDominators; + } + + std::map> const& dominatorTree() const + { + return m_dominatorTree; + } + + bool dominates(VId const& _dominatorId, VId const& _dominatedId) const + { + solAssert(!m_dfsIndexByVertexId.empty()); + solAssert(!m_immediateDominators.empty()); + + solAssert(m_dfsIndexByVertexId.count(_dominatorId) && m_dfsIndexByVertexId.count(_dominatedId)); + DfsIndex dominatorIdx = m_dfsIndexByVertexId.at(_dominatorId); + DfsIndex dominatedIdx = m_dfsIndexByVertexId.at(_dominatedId); + + if (dominatorIdx == dominatedIdx) + return true; + + DfsIndex idomIdx = m_immediateDominators.at(dominatedIdx).value_or(0); + while (idomIdx != 0) + { + solAssert(idomIdx < m_immediateDominators.size()); + if (idomIdx == dominatorIdx) + return true; + // The index of the immediate dominator of a vertex is always less than the index of the vertex itself. + solAssert(m_immediateDominators.at(idomIdx).has_value() && m_immediateDominators.at(idomIdx).value() < idomIdx); + idomIdx = m_immediateDominators[idomIdx].value(); + } + // Now that we reached the entry node (i.e. idomIdx = 0), + // either ``dominatorIdx == 0`` or it does not dominate the other node. + solAssert(idomIdx == 0); + return dominatorIdx == 0; + } + + /// Checks whether vertex ``_dominator`` dominates ``_dominated`` by going + /// through the path from ``_dominated`` to the entry node. + /// If ``_dominator`` is found, then it dominates ``_dominated`` + /// otherwise it doesn't. + bool dominates(V const& _dominator, V const& _dominated) const + { + return dominates(_dominator.id, _dominated.id); + } + + std::vector dominatorsOf(VId const& _vId) const + { + solAssert(!m_verticesInDFSOrder.empty()); + solAssert(!m_dfsIndexByVertexId.empty()); + solAssert(!m_immediateDominators.empty()); + + solAssert(m_dfsIndexByVertexId.count(_vId)); + + // No one dominates the entry vertex and we consider self-dominance implicit + // i.e. every node already dominates itself. + if (m_dfsIndexByVertexId.at(_vId) == 0) + return {}; + + solAssert(m_dfsIndexByVertexId.at(_vId) < m_immediateDominators.size()); + DfsIndex idomIdx = m_immediateDominators.at(m_dfsIndexByVertexId.at(_vId)).value_or(0); + solAssert(idomIdx < m_immediateDominators.size()); + + std::vector dominators; + while (idomIdx != 0) + { + solAssert(m_immediateDominators.at(idomIdx).has_value() && m_immediateDominators.at(idomIdx).value() < idomIdx); + dominators.emplace_back(m_verticesInDFSOrder.at(idomIdx)); + idomIdx = m_immediateDominators[idomIdx].value(); + } + + // The loop above discovers the dominators in the reverse order + // i.e. from the given vertex upwards to the entry node (the root of the dominator tree). + // And the entry vertex always dominates all other vertices. + dominators.emplace_back(m_verticesInDFSOrder[0]); + + return dominators; + } + + /// Find all dominators of a node _v + /// @note for a vertex ``_v``, the _v’s inclusion in the set of dominators of ``_v`` is implicit. + std::vector dominatorsOf(V const& _v) const + { + return dominatorsOf(_v.id); + } + +private: + std::vector> findDominators(V const& _entry) + { + solAssert(m_verticesInDFSOrder.empty()); + solAssert(m_dfsIndexByVertexId.empty()); + + // parent(w): The index of the vertex which is the parent of ``w`` in the spanning + // tree generated by the DFS. + std::vector parent; + + // step 1 + // The vertices are assigned indices in DFS order. + std::set visited; + DfsIndex nextUnusedDFSIndex = 0; + + auto dfs = [&](V const& _v, auto _dfs) -> void { + auto [_, inserted] = visited.insert(_v.id); + if (!inserted) + return; + + m_verticesInDFSOrder.emplace_back(_v.id); + m_dfsIndexByVertexId[_v.id] = nextUnusedDFSIndex; + nextUnusedDFSIndex++; + + ForEachSuccessor{}(_v, [&](V const& _successor) { + if (visited.count(_successor.id) == 0) + { + parent.push_back(m_dfsIndexByVertexId[_v.id]); + m_predecessors.push_back({m_dfsIndexByVertexId[_v.id]}); + _dfs(_successor, _dfs); + } + else + { + solAssert(m_dfsIndexByVertexId[_successor.id] < m_predecessors.size()); + m_predecessors[m_dfsIndexByVertexId[_successor.id]].insert(m_dfsIndexByVertexId[_v.id]); + } + }); + }; + + parent.emplace_back(std::numeric_limits::max()); + m_predecessors.emplace_back(); + dfs(_entry, dfs); + + size_t numVertices = visited.size(); + solAssert(nextUnusedDFSIndex == numVertices); + solAssert(m_verticesInDFSOrder.size() == numVertices); + solAssert(visited.size() == numVertices); + solAssert(m_predecessors.size() == numVertices); + solAssert(parent.size() == numVertices); + + // ancestor(w): Parent of vertex ``w`` in the virtual forest traversed by eval(). + // The forest consists of disjoint subtrees of the spanning tree and the parent of ``w`` is + // always one of its ancestors in that spanning tree. + // Initially each subtree consists of a single vertex. As the algorithm iterates over the + // graph, each processed vertex gets connected to its parent from the spanning tree using + // link(). Later on, the path compression performed by eval() may move it up in the subtree. + std::vector ancestor(numVertices, std::numeric_limits::max()); + // label(w): The index of a vertex with the smallest semidominator, on the path between ``w`` + // and the root of its subtree. The value is not updated immediately by link(), but + // only during path compression performed by eval(). + std::vector label; + // bucket(w): The set of all vertices having ``w`` as their semidominator. + // The index of the array represents the vertex' DFS index. + std::vector> bucket(numVertices); + + // semi(w): The DFS index of the semidominator of ``w``. + std::vector semi; + // idom(w): The DFS index of the immediate dominator of ``w``. + std::vector> idom(numVertices, std::nullopt); + + // ``link(v, w)`` adds an edge from ``w`` to ``v`` in the virtual forest. + // It is meant to initially attach vertex ``w`` to its parent from the spanning tree, + // but path compression can later limit the search path upwards. + // TODO: implement sophisticated link-eval algorithm as shown in pg 132 + // See: https://www.cs.princeton.edu/courses/archive/spr03/cs423/download/dominators.pdf + auto link = [&](DfsIndex _parentIdx, DfsIndex _wIdx) + { + solAssert(ancestor[_wIdx] == std::numeric_limits::max()); + ancestor[_wIdx] = _parentIdx; + }; + + // ``eval(v)`` returns a vertex with the smallest semidominator index on the path between + // vertex ``v`` and the root of its subtree in the virtual forest, i.e. the label of ``v``. + // Performs path compression in the process, updating labels and ancestors on the path to + // the subtree root. + auto eval = [&](DfsIndex _vIdx) -> DfsIndex + { + if (ancestor[_vIdx] == std::numeric_limits::max()) + return _vIdx; + + compressPath(ancestor, label, semi, _vIdx); + return label[_vIdx]; + }; + + auto toDfsIndex = [&](VId const& _vId) { return m_dfsIndexByVertexId[_vId]; }; + + for (DfsIndex wIdx = 0; wIdx < m_verticesInDFSOrder.size(); ++wIdx) + { + semi.push_back(wIdx); + label.push_back(wIdx); + } + + // Process the vertices in decreasing order of the DFS number + for (DfsIndex wIdx: m_verticesInDFSOrder | ranges::views::reverse | ranges::views::transform(toDfsIndex)) + { + // step 3 + // NOTE: this is an optimization, i.e. performing the step 3 before step 2. + // The goal is to process the bucket at the beginning of the loop for the vertex ``w`` + // instead of ``parent[w]`` at the end of the loop as described in the original paper. + // Inverting those steps ensures that a bucket is only processed once and + // it does not need to be erased. + // The optimization proposal is available here: https://jgaa.info/index.php/jgaa/article/view/paper119/2847 pg.77 + for (DfsIndex vIdx: bucket[wIdx]) + { + DfsIndex uIdx = eval(vIdx); + solAssert(uIdx <= vIdx); + idom[vIdx] = (semi[uIdx] < semi[vIdx]) ? uIdx : wIdx; + } + + // step 2 + for (DfsIndex vIdx: m_predecessors[wIdx]) + { + DfsIndex uIdx = eval(vIdx); + solAssert(uIdx <= vIdx); + if (semi[uIdx] < semi[wIdx]) + semi[wIdx] = semi[uIdx]; + } + solAssert(semi[wIdx] < wIdx || wIdx == 0); + bucket[semi[wIdx]].emplace_back(wIdx); + link(parent[wIdx], wIdx); + solAssert(ancestor[wIdx] == parent[wIdx]); + } + + // step 4 + // Compute idom in DFS order + // The entry vertex does not have an immediate dominator. + solAssert(idom[0] == std::nullopt); + for (DfsIndex wIdx: m_verticesInDFSOrder | ranges::views::drop(1) | ranges::views::transform(toDfsIndex)) + { + // All the other vertices must have an immediate dominator. + solAssert(idom[wIdx].has_value()); + if (idom[wIdx].value() != semi[wIdx]) + idom[wIdx] = idom[idom[wIdx].value()]; + } + + return idom; + } + + /// Path compression updates the ancestors of vertices along + /// the path to the ancestor with the minimum label value. + static void compressPath( + std::vector& _ancestor, + std::vector& _label, + std::vector const& _semi, + DfsIndex _vIdx + ) + { + solAssert(_vIdx < _ancestor.size() && _vIdx < _semi.size() && _vIdx < _label.size()); + solAssert(_ancestor[_vIdx] != std::numeric_limits::max()); + solAssert(_ancestor[_vIdx] < _vIdx); + if (_ancestor[_ancestor[_vIdx]] != std::numeric_limits::max()) + { + solAssert(_ancestor[_ancestor[_vIdx]] < _ancestor[_vIdx]); + compressPath(_ancestor, _label, _semi, _ancestor[_vIdx]); + if (_semi[_label[_ancestor[_vIdx]]] < _semi[_label[_vIdx]]) + _label[_vIdx] = _label[_ancestor[_vIdx]]; + _ancestor[_vIdx] = _ancestor[_ancestor[_vIdx]]; + } + solAssert(_label[_ancestor[_vIdx]] <= _label[_vIdx]); + } + + /// Build dominator tree from the immediate dominators set. + /// The function groups all the vertex IDs that are immediately dominated by a vertex. + void buildDominatorTree() + { + // m_immediateDominators is guaranteed to have at least one element after findingDominators() is executed. + solAssert(m_immediateDominators.size() > 0); + solAssert(m_immediateDominators.size() == m_verticesInDFSOrder.size()); + solAssert(m_immediateDominators[0] == std::nullopt); + + // Ignoring the entry node since no one dominates it. + for (DfsIndex dominatedIdx = 1; dominatedIdx < m_verticesInDFSOrder.size(); ++dominatedIdx) + { + VId dominatedId = m_verticesInDFSOrder[dominatedIdx]; + solAssert(m_dfsIndexByVertexId.count(dominatedId)); + solAssert(dominatedIdx == m_dfsIndexByVertexId.at(dominatedId)); + + // If the vertex does not have an immediate dominator, it is the entry vertex (i.e. index 0). + // NOTE: `dominatedIdx` will never be 0 since the loop starts from 1. + solAssert(m_immediateDominators[dominatedIdx].has_value()); + DfsIndex dominatorIdx = m_immediateDominators[dominatedIdx].value(); + + solAssert(dominatorIdx < dominatedIdx); + VId dominatorId = m_verticesInDFSOrder[dominatorIdx]; + m_dominatorTree[dominatorId].emplace_back(dominatedId); + } + } + + // predecessors(w): The set of vertices ``v`` such that (``v``, ``w``) is an edge of the graph. + std::vector> m_predecessors; + + /// Keeps the list of vertex IDs in the DFS order. + /// The entry vertex is the first element of the vector. + /// The indices of the other vertices are assigned in the order they are visited during the DFS. + /// I.e. m_verticesInDFSOrder[i] is the ID of the vertex whose DFS index is i. + /// + /// DFS index -> vertex ID + std::vector m_verticesInDFSOrder; + + /// Maps a vertex ID to its DFS order index. + /// + /// Vertex ID -> DFS index + std::map m_dfsIndexByVertexId; + + /// Maps a vertex to all vertices that it dominates. + /// If the vertex does not dominate any other vertex it has no entry in the map. + /// The value is a set of IDs of vertices dominated by the vertex whose ID is the map key. + /// + /// Vertex id -> dominates set {vertex ID} + std::map> m_dominatorTree; + + /// Immediate dominators by DFS index. + /// Maps a vertex' DFS index (i.e. array index) to its immediate dominator DFS index. + /// As the entry vertex does not have immediate dominator, its idom is always set to `std::nullopt`. + /// However note that the DFS index of the entry vertex is 0, since it is the first element of the vector. + /// + /// E.g. to get the immediate dominator of a Vertex w: + /// idomIdx = m_immediateDominators[m_dfsIndexByVertexId[w.id]] + /// idomVertexId = m_verticesInDFSOrder[domIdx] + /// + /// DFS index -> dominates DFS index + std::vector> m_immediateDominators; +}; +} diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index d5435237ec7b..0d19d77960d2 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -31,6 +31,7 @@ set(libsolutil_sources libsolutil/Checksum.cpp libsolutil/CommonData.cpp libsolutil/CommonIO.cpp + libsolutil/DominatorFinderTest.cpp libsolutil/FixedHash.cpp libsolutil/FunctionSelector.cpp libsolutil/IpfsHash.cpp diff --git a/test/libsolutil/DominatorFinderTest.cpp b/test/libsolutil/DominatorFinderTest.cpp new file mode 100644 index 000000000000..22e8010ca4cb --- /dev/null +++ b/test/libsolutil/DominatorFinderTest.cpp @@ -0,0 +1,920 @@ +/* + This file is part of solidity. + + solidity is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + solidity is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with solidity. If not, see . +*/ +/** + * Unit tests for the algorithm to find dominators from a graph. + */ +#include + +#include + +#include + +#include + +#include +#include +#include +#include +#include + +using namespace solidity::util; + +namespace solidity::util::test +{ + +typedef size_t TestVertexId; +typedef std::string TestVertexLabel; +typedef std::pair Edge; + +struct TestVertex { + using Id = TestVertexId; + + TestVertexId id; + TestVertexLabel label; + std::vector successors; +}; + +struct ForEachVertexSuccessorMock { + template + void operator()(TestVertex const& _v, Callable&& _callable) const + { + for (auto const& w: _v.successors) + _callable(*w); + } +}; + +typedef DominatorFinder TestDominatorFinder; + +class DominatorFinderTest +{ +public: + DominatorFinderTest( + std::vector const& _vertices, + std::vector const& _edges, + std::map const& _expectedImmediateDominators, + std::map const& _expectedDFSIndices, + std::map> const& _expectedDominatorTree + ) + { + soltestAssert(!_vertices.empty()); + + // NOTE: We use the indices of the vertices in the ``_vertices`` vector as vertex IDs. + TestVertexId id = 0; + vertices = _vertices | ranges::views::transform([&](TestVertexLabel const& label) -> TestVertex { + vertexIdMap[label] = id; + return {id++, label, {}}; + }) | ranges::to>; + soltestAssert(vertices.size() == _vertices.size()); + soltestAssert(vertexIdMap.size() == _vertices.size()); + soltestAssert(id == _vertices.size()); + + // Populate the successors of the vertices. + for (auto const& [from, to]: _edges) + vertices[vertexIdMap[from]].successors.emplace_back(&vertices[vertexIdMap[to]]); + + // Validate that all vertices used in the expected results are part of the graph. + std::set verticesSet = _vertices | ranges::to>; + auto validateVertices = [&](std::set const& labels) { + if (verticesSet.size() != labels.size()) + soltestAssert(std::includes(verticesSet.begin(), verticesSet.end(), labels.begin(), labels.end())); + else + soltestAssert(std::equal(verticesSet.begin(), verticesSet.end(), labels.begin(), labels.end())); + }; + + validateVertices(_edges + | ranges::views::transform([](Edge const& e) { return e.first; }) + | ranges::to> + ); + validateVertices(_edges + | ranges::views::transform([](Edge const& e) { return e.second; }) + | ranges::to> + ); + validateVertices(_expectedImmediateDominators | ranges::views::keys | ranges::to>); + // The entry vertex does not have an immediate dominator. + validateVertices(_expectedImmediateDominators + | ranges::views::values + | ranges::views::filter([](TestVertexLabel const& label) { return !label.empty(); }) + | ranges::to> + ); + validateVertices(_expectedDFSIndices | ranges::views::keys | ranges::to>); + bool allDFSIndexInRange = std::all_of( + _expectedDFSIndices.begin(), + _expectedDFSIndices.end(), + [&](auto const& pair) { + return pair.second < verticesSet.size(); + } + ); + solAssert(allDFSIndexInRange); + validateVertices(_expectedDominatorTree | ranges::views::keys | ranges::to>); + validateVertices(_expectedDominatorTree | ranges::views::values | ranges::views::join | ranges::to>); + + entry = &vertices[0]; + expectedImmediateDominators = labelMapToIdMap(_expectedImmediateDominators); + expectedDFSIndices = toVertexMapById(_expectedDFSIndices); + expectedDominatorTree = vertexMapToVertexId(_expectedDominatorTree); + } + + // Converts a map of vertex labels to map of vertex IDs + std::map> labelMapToIdMap(std::map const& _vertexLabelMap) const + { + return _vertexLabelMap + | ranges::views::transform([&](auto const& pair) -> std::pair> { + return {vertexIdMap.at(pair.first), (pair.second != "") ? std::optional(vertexIdMap.at(pair.second)) : std::nullopt}; + }) + | ranges::to>>; + } + + // Converts a map with vertex labels as keys to a map with vertex IDs as keys. + template + std::map toVertexMapById(std::map const& _verticesByLabel) const + { + return _verticesByLabel + | ranges::views::transform([&](auto const& pair) -> std::pair { + return {vertexIdMap.at(pair.first), pair.second}; + }) + | ranges::to>; + } + + // Converts a map with vertex labels as keys to a map with vertex IDs as keys. + std::map> vertexMapToVertexId(std::map> const& _vertexMapByLabel) const + { + auto labelVectorToIdVector = [&](std::vector const& labels) -> std::vector { + return labels + | ranges::views::transform([&](TestVertexLabel const& label) { + soltestAssert(vertexIdMap.count(label)); + return vertexIdMap.at(label); + }) + | ranges::to>; + }; + + return toVertexMapById(_vertexMapByLabel | ranges::views::transform([&](auto const& pair) -> std::pair> { + return {pair.first, labelVectorToIdVector(pair.second)}; + }) | ranges::to>>); + } + + TestVertex const* entry = nullptr; + std::vector vertices; + // Reverse map from vertices labels to IDs + std::map vertexIdMap; + std::map> expectedImmediateDominators; + std::map expectedDFSIndices; + std::map> expectedDominatorTree; +}; + +BOOST_AUTO_TEST_SUITE(Dominators) + +BOOST_AUTO_TEST_CASE(immediate_dominator_1) +{ + // A + // │ + // ▼ + // ┌───B + // │ │ + // ▼ │ + // C ──┼───┐ + // │ │ │ + // ▼ │ ▼ + // D◄──┘ G + // │ │ + // ▼ ▼ + // E H + // │ │ + // └──►F◄──┘ + DominatorFinderTest test( + {"A", "B", "C", "D", "E", "F", "G", "H"}, // Vertices + { // Edges + Edge("A", "B"), + Edge("B", "C"), + Edge("B", "D"), + Edge("C", "D"), + Edge("C", "G"), + Edge("D", "E"), + Edge("E", "F"), + Edge("G", "H"), + Edge("H", "F") + }, + { // Immediate dominators + {"A", ""}, + {"B", "A"}, + {"C", "B"}, + {"D", "B"}, + {"E", "D"}, + {"F", "B"}, + {"G", "C"}, + {"H", "G"} + }, + { // DFS indices + {"A", 0}, + {"B", 1}, + {"C", 2}, + {"D", 3}, + {"E", 4}, + {"F", 5}, + {"G", 6}, + {"H", 7} + }, + { // Dominator tree + {"A", {"B"}}, + {"B", {"C", "D", "F"}}, + {"C", {"G"}}, + {"D", {"E"}}, + {"G", {"H"}} + } + ); + + TestDominatorFinder dominatorFinder(*test.entry); + BOOST_TEST(dominatorFinder.immediateDominators() == test.expectedImmediateDominators); + BOOST_TEST(dominatorFinder.dfsIndexById() == test.expectedDFSIndices); + BOOST_TEST(dominatorFinder.dominatorTree() == test.expectedDominatorTree); +} + +BOOST_AUTO_TEST_CASE(immediate_dominator_2) +{ + // ┌────►A──────┐ + // │ │ ▼ + // │ B◄──┘ ┌──D──┐ + // │ │ │ │ + // │ ▼ ▼ ▼ + // └─C◄───┐ E F + // │ │ │ │ + // └───►G◄─┴─────┘ + DominatorFinderTest test( + {"A", "B", "C", "D", "E", "F", "G"}, + { + Edge("A", "B"), + Edge("B", "C"), + Edge("C", "G"), + Edge("C", "A"), + Edge("A", "D"), + Edge("D", "E"), + Edge("D", "F"), + Edge("E", "G"), + Edge("F", "G"), + Edge("G", "C") + }, + { + {"A", ""}, + {"B", "A"}, + {"C", "A"}, + {"D", "A"}, + {"E", "D"}, + {"F", "D"}, + {"G", "A"} + }, + { + {"A", 0}, + {"B", 1}, + {"C", 2}, + {"G", 3}, + {"D", 4}, + {"E", 5}, + {"F", 6} + }, + { + {"A", {"B", "C", "G", "D"}}, + {"D", {"E", "F"}} + } + ); + + TestDominatorFinder dominatorFinder(*test.entry); + BOOST_TEST(dominatorFinder.immediateDominators() == test.expectedImmediateDominators); + BOOST_TEST(dominatorFinder.dfsIndexById() == test.expectedDFSIndices); + BOOST_TEST(dominatorFinder.dominatorTree() == test.expectedDominatorTree); +} + +BOOST_AUTO_TEST_CASE(immediate_dominator_3) +{ + // ┌─────────┐ + // │ ▼ + // │ ┌───A───┐ + // │ │ │ + // │ ▼ ▼ + // │ ┌──►C◄───── B──┬──────┐ + // │ │ │ ▲ │ │ + // │ │ │ ┌────┘ │ │ + // │ │ ▼ │ ▼ ▼ + // │ │ D──┘ ┌───►E◄─────I + // │ │ ▲ │ │ │ + // │ │ │ │ ├───┐ │ + // │ │ │ │ │ │ │ + // │ │ │ │ ▼ │ ▼ + // │ └───┼─────┼────F └─►H + // │ │ │ │ │ + // │ │ │ │ │ + // │ │ │ │ │ + // │ └─────┴─G◄─┴──────┘ + // │ │ + // └─────────────┘ + DominatorFinderTest test( + {"A", "B", "C", "D", "E", "F", "G", "H", "I"}, + { + Edge("A", "B"), + Edge("A", "C"), + Edge("B", "C"), + Edge("B", "I"), + Edge("B", "E"), + Edge("C", "D"), + Edge("D", "B"), + Edge("E", "H"), + Edge("E", "F"), + Edge("F", "G"), + Edge("F", "C"), + Edge("G", "E"), + Edge("G", "A"), + Edge("G", "D"), + Edge("H", "G"), + Edge("I", "E"), + Edge("I", "H") + }, + { + {"A", ""}, + {"B", "A"}, + {"C", "A"}, + {"D", "A"}, + {"E", "B"}, + {"F", "E"}, + {"G", "B"}, + {"H", "B"}, + {"I", "B"} + }, + { + {"A", 0}, + {"B", 1}, + {"C", 2}, + {"D", 3}, + {"I", 4}, + {"E", 5}, + {"H", 6}, + {"G", 7}, + {"F", 8} + }, + { + {"A", {"B", "C", "D"}}, + {"B", {"I", "E", "H", "G"}}, + {"E", {"F"}} + } + ); + + TestDominatorFinder dominatorFinder(*test.entry); + BOOST_TEST(dominatorFinder.immediateDominators() == test.expectedImmediateDominators); + BOOST_TEST(dominatorFinder.dfsIndexById() == test.expectedDFSIndices); + BOOST_TEST(dominatorFinder.dominatorTree() == test.expectedDominatorTree); +} + +BOOST_AUTO_TEST_CASE(langauer_tarjan_p122_fig1) +{ + // T. Lengauer and R. E. Tarjan pg. 122 fig. 1 + // ref: https://www.cs.princeton.edu/courses/archive/spr03/cs423/download/dominators.pdf + DominatorFinderTest test( + {"R", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "L", "K"}, + { + Edge("R", "B"), + Edge("R", "A"), + Edge("R", "C"), + Edge("B", "A"), + Edge("B", "D"), + Edge("B", "E"), + Edge("A", "D"), + Edge("D", "L"), + Edge("L", "H"), + Edge("E", "H"), + Edge("H", "E"), + Edge("H", "K"), + Edge("K", "I"), + Edge("K", "R"), + Edge("C", "F"), + Edge("C", "G"), + Edge("F", "I"), + Edge("G", "I"), + Edge("G", "J"), + Edge("J", "I"), + Edge("I", "K") + }, + { + {"R", ""}, + {"A", "R"}, + {"B", "R"}, + {"C", "R"}, + {"D", "R"}, + {"E", "R"}, + {"F", "C"}, + {"G", "C"}, + {"H", "R"}, + {"I", "R"}, + {"J", "G"}, + {"L", "D"}, + {"K", "R"} + }, + { + {"R", 0}, + {"B", 1}, + {"A", 2}, + {"D", 3}, + {"L", 4}, + {"H", 5}, + {"E", 6}, + {"K", 7}, + {"I", 8}, + {"C", 9}, + {"F", 10}, + {"G", 11}, + {"J", 12} + }, + { + {"R", {"B", "A", "D", "H", "E", "K", "I", "C"}}, + {"D", {"L"}}, + {"C", {"F", "G"}}, + {"G", {"J"}} + } + ); + + TestDominatorFinder dominatorFinder(*test.entry); + BOOST_TEST(dominatorFinder.immediateDominators() == test.expectedImmediateDominators); + BOOST_TEST(dominatorFinder.dfsIndexById() == test.expectedDFSIndices); + BOOST_TEST(dominatorFinder.dominatorTree() == test.expectedDominatorTree); +} + +BOOST_AUTO_TEST_CASE(loukas_georgiadis) +{ + // Extracted from Loukas Georgiadis Dissertation - Linear-Time Algorithms for Dominators and Related Problems + // pg. 12 Fig. 2.2 + // ref: https://www.cs.princeton.edu/techreports/2005/737.pdf + DominatorFinderTest test( + {"R", "W", "X1", "X2", "X3", "X4", "X5", "X6", "X7", "Y"}, + { + Edge("R", "W"), + Edge("R", "Y"), + Edge("W", "X1"), + Edge("Y", "X7"), + Edge("X1", "X2"), + Edge("X2", "X1"), + Edge("X2", "X3"), + Edge("X3", "X2"), + Edge("X3", "X4"), + Edge("X4", "X3"), + Edge("X4", "X5"), + Edge("X5", "X4"), + Edge("X5", "X6"), + Edge("X6", "X5"), + Edge("X6", "X7"), + Edge("X7", "X6") + }, + { + {"R", ""}, + {"W", "R"}, + {"X1", "R"}, + {"X2", "R"}, + {"X3", "R"}, + {"X4", "R"}, + {"X5", "R"}, + {"X6", "R"}, + {"X7", "R"}, + {"Y", "R"} + }, + { + {"R", 0}, + {"W", 1}, + {"X1", 2}, + {"X2", 3}, + {"X3", 4}, + {"X4", 5}, + {"X5", 6}, + {"X6", 7}, + {"X7", 8}, + {"Y", 9} + }, + { + {"R", {"W", "X1", "X2", "X3", "X4", "X5", "X6", "X7", "Y"}}, + } + ); + + TestDominatorFinder dominatorFinder(*test.entry); + BOOST_TEST(dominatorFinder.immediateDominators() == test.expectedImmediateDominators); + BOOST_TEST(dominatorFinder.dfsIndexById() == test.expectedDFSIndices); + BOOST_TEST(dominatorFinder.dominatorTree() == test.expectedDominatorTree); +} + +BOOST_AUTO_TEST_CASE(itworst) +{ + // Worst-case families for k = 3 + // Example itworst(3) pg. 26 fig. 2.9 + // ref: https://www.cs.princeton.edu/techreports/2005/737.pdf + DominatorFinderTest test( + {"R", "W1", "W2", "W3", "X1", "X2", "X3", "Y1", "Y2", "Y3", "Z1", "Z2", "Z3"}, + { + Edge("R", "W1"), + Edge("R", "X1"), + Edge("R", "Z3"), + Edge("W1", "W2"), + Edge("W2", "W3"), + Edge("X1", "X2"), + Edge("X2", "X3"), + Edge("X3", "Y1"), + Edge("Y1", "W1"), + Edge("Y1", "W2"), + Edge("Y1", "W3"), + Edge("Y1", "Y2"), + Edge("Y2", "W1"), + Edge("Y2", "W2"), + Edge("Y2", "W3"), + Edge("Y2", "Y3"), + Edge("Y3", "W1"), + Edge("Y3", "W2"), + Edge("Y3", "W3"), + Edge("Y3", "Z1"), + Edge("Z1", "Z2"), + Edge("Z2", "Z1"), + Edge("Z2", "Z3"), + Edge("Z3", "Z2") + }, + { + {"R", ""}, + {"W1", "R"}, + {"W2", "R"}, + {"W3", "R"}, + {"X1", "R"}, + {"X2", "X1"}, + {"X3", "X2"}, + {"Y1", "X3"}, + {"Y2", "Y1"}, + {"Y3", "Y2"}, + {"Z1", "R"}, + {"Z2", "R"}, + {"Z3", "R"} + }, + { + {"R", 0}, + {"W1", 1}, + {"W2", 2}, + {"W3", 3}, + {"X1", 4}, + {"X2", 5}, + {"X3", 6}, + {"Y1", 7}, + {"Y2", 8}, + {"Y3", 9}, + {"Z1", 10}, + {"Z2", 11}, + {"Z3", 12} + }, + { + {"R", {"W1", "W2", "W3", "X1", "Z1", "Z2", "Z3"}}, + {"X1", {"X2"}}, + {"X2", {"X3"}}, + {"X3", {"Y1"}}, + {"Y1", {"Y2"}}, + {"Y2", {"Y3"}} + } + ); + + TestDominatorFinder dominatorFinder(*test.entry); + BOOST_TEST(dominatorFinder.immediateDominators() == test.expectedImmediateDominators); + BOOST_TEST(dominatorFinder.dfsIndexById() == test.expectedDFSIndices); + BOOST_TEST(dominatorFinder.dominatorTree() == test.expectedDominatorTree); +} + +BOOST_AUTO_TEST_CASE(idfsquad) +{ + // Worst-case families for k = 3 + // Example idfsquad(3) pg. 26 fig. 2.9 + // ref: https://www.cs.princeton.edu/techreports/2005/737.pdf + DominatorFinderTest test( + {"R", "X1", "X2", "X3", "Y1", "Y2", "Y3", "Z1", "Z2", "Z3"}, + { + Edge("R", "X1"), + Edge("R", "Z1"), + Edge("X1", "Y1"), + Edge("X1", "X2"), + Edge("X2", "X3"), + Edge("X2", "Y2"), + Edge("X3", "Y3"), + Edge("Y1", "Z1"), + Edge("Y1", "Z2"), + Edge("Z1", "Y1"), + Edge("Y2", "Z2"), + Edge("Y2", "Z3"), + Edge("Z2", "Y2"), + Edge("Y3", "Z3"), + Edge("Z3", "Y3") + }, + { + {"R", ""}, + {"X1", "R"}, + {"X2", "X1"}, + {"X3", "X2"}, + {"Y1", "R"}, + {"Y2", "R"}, + {"Y3", "R"}, + {"Z1", "R"}, + {"Z2", "R"}, + {"Z3", "R"} + }, + { + {"R", 0}, + {"X1", 1}, + {"Y1", 2}, + {"Z1", 3}, + {"Z2", 4}, + {"Y2", 5}, + {"Z3", 6}, + {"Y3", 7}, + {"X2", 8}, + {"X3", 9} + }, + { + {"R", {"X1", "Y1", "Z1", "Z2", "Y2", "Z3", "Y3"}}, + {"X1", {"X2"}}, + {"X2", {"X3"}} + } + ); + + TestDominatorFinder dominatorFinder(*test.entry); + BOOST_TEST(dominatorFinder.immediateDominators() == test.expectedImmediateDominators); + BOOST_TEST(dominatorFinder.dfsIndexById() == test.expectedDFSIndices); + BOOST_TEST(dominatorFinder.dominatorTree() == test.expectedDominatorTree); +} + +BOOST_AUTO_TEST_CASE(ibsfquad) +{ + // Worst-case families for k = 3 + // Example ibfsquad(3) pg. 26 fig. 2.9 + // ref: https://www.cs.princeton.edu/techreports/2005/737.pdf + DominatorFinderTest test( + {"R", "W", "X1", "X2", "X3", "Y", "Z"}, + { + Edge("R", "W"), + Edge("R", "Y"), + Edge("W", "X1"), + Edge("W", "X2"), + Edge("W", "X3"), + Edge("Y", "Z"), + Edge("Z", "X3"), + Edge("X3", "X2"), + Edge("X2", "X1") + }, + { + {"R", ""}, + {"W", "R"}, + {"X1", "R"}, + {"X2", "R"}, + {"X3", "R"}, + {"Y", "R"}, + {"Z", "Y"} + }, + { + {"R", 0}, + {"W", 1}, + {"X1", 2}, + {"X2", 3}, + {"X3", 4}, + {"Y", 5}, + {"Z", 6} + }, + { + {"R", {"W", "X1", "X2", "X3", "Y"}}, + {"Y", {"Z"}} + } + ); + + TestDominatorFinder dominatorFinder(*test.entry); + BOOST_TEST(dominatorFinder.immediateDominators() == test.expectedImmediateDominators); + BOOST_TEST(dominatorFinder.dfsIndexById() == test.expectedDFSIndices); + BOOST_TEST(dominatorFinder.dominatorTree() == test.expectedDominatorTree); +} + +BOOST_AUTO_TEST_CASE(sncaworst) +{ + // Worst-case families for k = 3 + // Example sncaworst(3) pg. 26 fig. 2.9 + // ref: https://www.cs.princeton.edu/techreports/2005/737.pdf + DominatorFinderTest test( + {"R", "X1", "X2", "X3", "Y1", "Y2", "Y3"}, + { + Edge("R", "X1"), + Edge("R", "Y1"), + Edge("R", "Y2"), + Edge("R", "Y3"), + Edge("X1", "X2"), + Edge("X2", "X3"), + Edge("X3", "Y1"), + Edge("X3", "Y2"), + Edge("X3", "Y3") + }, + { + {"R", ""}, + {"X1", "R"}, + {"X2", "X1"}, + {"X3", "X2"}, + {"Y1", "R"}, + {"Y2", "R"}, + {"Y3", "R"} + }, + { + {"R", 0}, + {"X1", 1}, + {"X2", 2}, + {"X3", 3}, + {"Y1", 4}, + {"Y2", 5}, + {"Y3", 6} + }, + { + {"R", {"X1", "Y1", "Y2", "Y3"}}, + {"X1", {"X2"}}, + {"X2", {"X3"}} + } + ); + + TestDominatorFinder dominatorFinder(*test.entry); + BOOST_TEST(dominatorFinder.immediateDominators() == test.expectedImmediateDominators); + BOOST_TEST(dominatorFinder.dfsIndexById() == test.expectedDFSIndices); + BOOST_TEST(dominatorFinder.dominatorTree() == test.expectedDominatorTree); +} + +BOOST_AUTO_TEST_CASE(collect_all_dominators_of_a_vertex) +{ + // A + // │ + // ▼ + // ┌───B + // │ │ + // ▼ │ + // C ──┼───┐ + // │ │ │ + // ▼ │ ▼ + // D◄──┘ G + // │ │ + // ▼ ▼ + // E H + // │ │ + // └──►F◄──┘ + DominatorFinderTest test( + {"A", "B", "C", "D", "E", "F", "G", "H"}, + { + Edge("A", "B"), + Edge("B", "C"), + Edge("B", "D"), + Edge("C", "D"), + Edge("C", "G"), + Edge("D", "E"), + Edge("E", "F"), + Edge("G", "H"), + Edge("H", "F") + }, + {}, + {}, + {} + ); + + // Converts a vector of vertex IDs to a vector of vertex labels. + auto toVertexLabel = [&](std::vector const& _vertices) + { + return _vertices | ranges::views::transform([&](TestVertexId id){ + return test.vertices[id].label; + }) | ranges::to>; + }; + + TestDominatorFinder dominatorFinder(*test.entry); + BOOST_TEST(toVertexLabel(dominatorFinder.dominatorsOf(test.vertexIdMap["A"])) == std::vector()); + BOOST_TEST(toVertexLabel(dominatorFinder.dominatorsOf(test.vertexIdMap["B"])) == std::vector({"A"})); + BOOST_TEST(toVertexLabel(dominatorFinder.dominatorsOf(test.vertexIdMap["C"])) == std::vector({"B", "A"})); + BOOST_TEST(toVertexLabel(dominatorFinder.dominatorsOf(test.vertexIdMap["D"])) == std::vector({"B", "A"})); + BOOST_TEST(toVertexLabel(dominatorFinder.dominatorsOf(test.vertexIdMap["E"])) == std::vector({"D", "B", "A"})); + BOOST_TEST(toVertexLabel(dominatorFinder.dominatorsOf(test.vertexIdMap["F"])) == std::vector({"B", "A"})); + BOOST_TEST(toVertexLabel(dominatorFinder.dominatorsOf(test.vertexIdMap["G"])) == std::vector({"C", "B", "A"})); + BOOST_TEST(toVertexLabel(dominatorFinder.dominatorsOf(test.vertexIdMap["H"])) == std::vector({"G", "C", "B", "A"})); +} + +BOOST_AUTO_TEST_CASE(check_dominance) +{ + // A + // │ + // ▼ + // ┌───B + // │ │ + // ▼ │ + // C ──┼───┐ + // │ │ │ + // ▼ │ ▼ + // D◄──┘ G + // │ │ + // ▼ ▼ + // E H + // │ │ + // └──►F◄──┘ + DominatorFinderTest test( + {"A", "B", "C", "D", "E", "F", "G", "H"}, + { + Edge("A", "B"), + Edge("B", "C"), + Edge("B", "D"), + Edge("C", "D"), + Edge("C", "G"), + Edge("D", "E"), + Edge("E", "F"), + Edge("G", "H"), + Edge("H", "F") + }, + {}, + { + {"A", 0}, + {"B", 1}, + {"C", 2}, + {"D", 3}, + {"E", 4}, + {"F", 5}, + {"G", 6}, + {"H", 7} + }, + {} + ); + + // Helper function to create a dominance relation for a vertex with all other vertices. + // + // @param _indices: The indices of the vertices that the vertex dominates. + // @return: A vector of booleans where the index represents the vertex and the value + // represents if the vertex dominates the other vertex at that index. + auto makeDominanceVertexRelation = [&](std::vector const& _indices = {}){ + std::vector dominance(test.vertices.size(), false); + for (TestDominatorFinder::DfsIndex i: _indices) + { + soltestAssert(i < test.vertices.size()); + dominance[i] = true; + } + return dominance; + }; + + // Dominance truth table for all vertices. + // Note that it includes self-dominance relation. + std::vector> expectedDominanceTable = { + std::vector(test.vertices.size(), true), // A dominates all vertices, including itself + makeDominanceVertexRelation({1,2,3,4,5,6,7}), // B, C, D, E, F, G, H + makeDominanceVertexRelation({2, 6, 7}), // C, G, H + makeDominanceVertexRelation({3, 4}), // D, E + makeDominanceVertexRelation({4}), // E + makeDominanceVertexRelation({5}), // F + makeDominanceVertexRelation({6, 7}), // G, H + makeDominanceVertexRelation({7}) // H + }; + soltestAssert(expectedDominanceTable.size() == test.vertices.size()); + + TestDominatorFinder dominatorFinder(*test.entry); + BOOST_TEST(dominatorFinder.dfsIndexById() == test.expectedDFSIndices); + // Check if the dominance table is as expected. + for (TestDominatorFinder::DfsIndex i = 0; i < expectedDominanceTable.size(); ++i) + { + soltestAssert(expectedDominanceTable[i].size() == test.vertices.size()); + for (TestDominatorFinder::DfsIndex j = 0; j < expectedDominanceTable[i].size(); ++j) + { + bool iDominatesJ = dominatorFinder.dominates(i, j); + BOOST_CHECK_MESSAGE( + iDominatesJ == expectedDominanceTable[i][j], + fmt::format( + "Vertex: {} expected to {} dominate vertex {} but returned: {}\n", + i, + (iDominatesJ ? "" : "not"), + j, + iDominatesJ + ) + ); + } + } +} + +BOOST_AUTO_TEST_CASE(no_edges) +{ + DominatorFinderTest test( + {"A"}, + {}, + { + {"A", ""}, + }, + { + {"A", 0}, + }, + {} + ); + + TestDominatorFinder dominatorFinder(*test.entry); + BOOST_TEST(dominatorFinder.immediateDominators() == test.expectedImmediateDominators); + BOOST_TEST(dominatorFinder.dfsIndexById() == test.expectedDFSIndices); + BOOST_TEST(dominatorFinder.dominatorTree() == test.expectedDominatorTree); +} + +BOOST_AUTO_TEST_SUITE_END() + +} // namespace solidity::util::test From 6ad92526990091acce9a242749db795c2282d4c5 Mon Sep 17 00:00:00 2001 From: Bhargava Shastry Date: Tue, 16 Jul 2024 09:14:26 +0200 Subject: [PATCH 0300/1022] Add fstream std header to not break build after compiler upgrade. --- test/tools/ossfuzz/AbiV2IsabelleFuzzer.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/test/tools/ossfuzz/AbiV2IsabelleFuzzer.cpp b/test/tools/ossfuzz/AbiV2IsabelleFuzzer.cpp index e10979ee13e2..aaa8e79c4ee5 100644 --- a/test/tools/ossfuzz/AbiV2IsabelleFuzzer.cpp +++ b/test/tools/ossfuzz/AbiV2IsabelleFuzzer.cpp @@ -22,6 +22,7 @@ #include #include +#include using namespace solidity::frontend; using namespace solidity::test::fuzzer; From 630f736cfdbabbfd9015e9180580c32270b7d061 Mon Sep 17 00:00:00 2001 From: Daniel Kirchner Date: Tue, 16 Jul 2024 17:54:26 +0200 Subject: [PATCH 0301/1022] Add test. --- test/cmdlineTests/ir_subobject_order/args | 1 + .../cmdlineTests/ir_subobject_order/input.sol | 14 +++ test/cmdlineTests/ir_subobject_order/output | 95 +++++++++++++++++++ 3 files changed, 110 insertions(+) create mode 100644 test/cmdlineTests/ir_subobject_order/args create mode 100644 test/cmdlineTests/ir_subobject_order/input.sol create mode 100644 test/cmdlineTests/ir_subobject_order/output diff --git a/test/cmdlineTests/ir_subobject_order/args b/test/cmdlineTests/ir_subobject_order/args new file mode 100644 index 000000000000..a536442c5ce2 --- /dev/null +++ b/test/cmdlineTests/ir_subobject_order/args @@ -0,0 +1 @@ +--ir-optimized --optimize --debug-info none diff --git a/test/cmdlineTests/ir_subobject_order/input.sol b/test/cmdlineTests/ir_subobject_order/input.sol new file mode 100644 index 000000000000..70326ac06e8d --- /dev/null +++ b/test/cmdlineTests/ir_subobject_order/input.sol @@ -0,0 +1,14 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity >0.0.0; + +contract B { constructor() payable { assembly { revert(0,0) } } } +contract A { constructor() payable { assembly { revert(0,0) } } } +contract C { + // The subobject order should be determined by reference, not AST ID, + // So the subobject for A should precede the subobject for B. + A a = new A(); + B b = new B(); + fallback() external payable { + assembly { revert(0,0) } + } +} diff --git a/test/cmdlineTests/ir_subobject_order/output b/test/cmdlineTests/ir_subobject_order/output new file mode 100644 index 000000000000..a364e623d7a5 --- /dev/null +++ b/test/cmdlineTests/ir_subobject_order/output @@ -0,0 +1,95 @@ +Optimized IR: +/// @use-src 0:"ir_subobject_order/input.sol" +object "A_13" { + code { { revert(0, 0) } } + /// @use-src 0:"ir_subobject_order/input.sol" + object "A_13_deployed" { + code { { revert(0, 0) } } + data ".metadata" hex"" + } +} + +Optimized IR: +/// @use-src 0:"ir_subobject_order/input.sol" +object "B_7" { + code { { revert(0, 0) } } + /// @use-src 0:"ir_subobject_order/input.sol" + object "B_7_deployed" { + code { { revert(0, 0) } } + data ".metadata" hex"" + } +} + +Optimized IR: +/// @use-src 0:"ir_subobject_order/input.sol" +object "C_33" { + code { + { + let _1 := memoryguard(0x80) + mstore(64, _1) + if callvalue() { revert(0, 0) } + let _2 := datasize("A_13") + let _3 := add(_1, _2) + if or(gt(_3, sub(shl(64, 1), 1)), lt(_3, _1)) + { + mstore(0, shl(224, 0x4e487b71)) + mstore(4, 0x41) + revert(0, 0x24) + } + datacopy(_1, dataoffset("A_13"), _2) + let expr_address := create(0, _1, sub(_3, _1)) + if iszero(expr_address) + { + let pos := mload(64) + returndatacopy(pos, 0, returndatasize()) + revert(pos, returndatasize()) + } + sstore(0, or(and(sload(0), not(sub(shl(160, 1), 1))), and(expr_address, sub(shl(160, 1), 1)))) + let _4 := mload(64) + let _5 := datasize("B_7") + let _6 := add(_4, _5) + if or(gt(_6, sub(shl(64, 1), 1)), lt(_6, _4)) + { + mstore(0, shl(224, 0x4e487b71)) + mstore(4, 0x41) + revert(0, 0x24) + } + datacopy(_4, dataoffset("B_7"), _5) + let expr_address_1 := create(0, _4, sub(_6, _4)) + if iszero(expr_address_1) + { + let pos_1 := mload(64) + returndatacopy(pos_1, 0, returndatasize()) + revert(pos_1, returndatasize()) + } + sstore(0x01, or(and(sload(0x01), not(sub(shl(160, 1), 1))), and(expr_address_1, sub(shl(160, 1), 1)))) + let _7 := mload(64) + let _8 := datasize("C_33_deployed") + codecopy(_7, dataoffset("C_33_deployed"), _8) + return(_7, _8) + } + } + /// @use-src 0:"ir_subobject_order/input.sol" + object "C_33_deployed" { + code { { revert(0, 0) } } + data ".metadata" hex"" + } + /// @use-src 0:"ir_subobject_order/input.sol" + object "B_7" { + code { { revert(0, 0) } } + /// @use-src 0:"ir_subobject_order/input.sol" + object "B_7_deployed" { + code { { revert(0, 0) } } + data ".metadata" hex"" + } + } + /// @use-src 0:"ir_subobject_order/input.sol" + object "A_13" { + code { { revert(0, 0) } } + /// @use-src 0:"ir_subobject_order/input.sol" + object "A_13_deployed" { + code { { revert(0, 0) } } + data ".metadata" hex"" + } + } +} From 8840e33746c26cc6398b0498b5a3ba0abc992eef Mon Sep 17 00:00:00 2001 From: Daniel Kirchner Date: Mon, 15 Jul 2024 17:15:11 +0200 Subject: [PATCH 0302/1022] Order yul subobjects by order of reference. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Kamil Śliwak --- Changelog.md | 1 + libsolidity/codegen/ir/IRGenerationContext.h | 5 +++-- libsolidity/codegen/ir/IRGenerator.cpp | 4 ++-- libsolidity/codegen/ir/IRGeneratorForStatements.cpp | 4 ++-- 4 files changed, 8 insertions(+), 6 deletions(-) diff --git a/Changelog.md b/Changelog.md index 7bffd07e1e29..bfdd45575ff7 100644 --- a/Changelog.md +++ b/Changelog.md @@ -19,6 +19,7 @@ Bugfixes: * SMTChecker: Fix formatting of unary minus expressions in invariants. * SMTChecker: Fix internal compiler error when reporting proved targets for BMC engine. * TypeChecker: Fix segfault when assigning nested tuple to tuple. + * Yul IR Code Generation: Deterministic order of Yul subobjects. * Yul Optimizer: Name simplification could lead to forbidden identifiers with a leading and/or trailing dot, e.g., ``x._`` would get simplified into ``x.``. * Yul Parser: Fix segfault when parsing very long location comments. diff --git a/libsolidity/codegen/ir/IRGenerationContext.h b/libsolidity/codegen/ir/IRGenerationContext.h index 8e03a378b302..2bf837697b47 100644 --- a/libsolidity/codegen/ir/IRGenerationContext.h +++ b/libsolidity/codegen/ir/IRGenerationContext.h @@ -143,7 +143,8 @@ class IRGenerationContext RevertStrings revertStrings() const { return m_revertStrings; } - std::set& subObjectsCreated() { return m_subObjects; } + util::UniqueVector const& subObjectsCreated() const { return m_subObjects; } + void addSubObject(ContractDefinition const* _contractDefinition) { m_subObjects.pushBack(_contractDefinition); } bool memoryUnsafeInlineAssemblySeen() const { return m_memoryUnsafeInlineAssemblySeen; } void setMemoryUnsafeInlineAssemblySeen() { m_memoryUnsafeInlineAssemblySeen = true; } @@ -195,7 +196,7 @@ class IRGenerationContext /// It will fail at runtime but the code must still compile. InternalDispatchMap m_internalDispatchMap; - std::set m_subObjects; + util::UniqueVector m_subObjects; langutil::DebugInfoSelection m_debugInfoSelection = {}; langutil::CharStreamProvider const* m_soliditySourceProvider = nullptr; diff --git a/libsolidity/codegen/ir/IRGenerator.cpp b/libsolidity/codegen/ir/IRGenerator.cpp index 93136a1a26cb..bf0f6d5c0f25 100644 --- a/libsolidity/codegen/ir/IRGenerator.cpp +++ b/libsolidity/codegen/ir/IRGenerator.cpp @@ -101,10 +101,10 @@ std::string IRGenerator::generate( std::map const& _otherYulSources ) { - auto subObjectSources = [&_otherYulSources](std::set const& subObjects) -> std::string + auto subObjectSources = [&_otherYulSources](UniqueVector const& _subObjects) -> std::string { std::string subObjectsSources; - for (ContractDefinition const* subObject: subObjects) + for (ContractDefinition const* subObject: _subObjects) subObjectsSources += _otherYulSources.at(subObject); return subObjectsSources; }; diff --git a/libsolidity/codegen/ir/IRGeneratorForStatements.cpp b/libsolidity/codegen/ir/IRGeneratorForStatements.cpp index 1c212cd828c3..0579f50c2d96 100644 --- a/libsolidity/codegen/ir/IRGeneratorForStatements.cpp +++ b/libsolidity/codegen/ir/IRGeneratorForStatements.cpp @@ -1559,7 +1559,7 @@ void IRGeneratorForStatements::endVisit(FunctionCall const& _functionCall) ContractDefinition const* contract = &dynamic_cast(*functionType->returnParameterTypes().front()).contractDefinition(); - m_context.subObjectsCreated().insert(contract); + m_context.addSubObject(contract); Whiskers t(R"(let := () let := add(, datasize("")) @@ -1947,7 +1947,7 @@ void IRGeneratorForStatements::endVisit(MemberAccess const& _memberAccess) auto const& contractType = dynamic_cast(*arg); solAssert(!contractType.isSuper()); ContractDefinition const& contract = contractType.contractDefinition(); - m_context.subObjectsCreated().insert(&contract); + m_context.addSubObject(&contract); appendCode() << Whiskers(R"( let := datasize("") let := (add(, 32)) From c78b7e25c6ccd5344b6d2319a4a992fe2095ee1b Mon Sep 17 00:00:00 2001 From: Daniel Kirchner Date: Tue, 16 Jul 2024 17:59:02 +0200 Subject: [PATCH 0303/1022] Update test. --- test/cmdlineTests/ir_subobject_order/output | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/cmdlineTests/ir_subobject_order/output b/test/cmdlineTests/ir_subobject_order/output index a364e623d7a5..da4390fff055 100644 --- a/test/cmdlineTests/ir_subobject_order/output +++ b/test/cmdlineTests/ir_subobject_order/output @@ -75,19 +75,19 @@ object "C_33" { data ".metadata" hex"" } /// @use-src 0:"ir_subobject_order/input.sol" - object "B_7" { + object "A_13" { code { { revert(0, 0) } } /// @use-src 0:"ir_subobject_order/input.sol" - object "B_7_deployed" { + object "A_13_deployed" { code { { revert(0, 0) } } data ".metadata" hex"" } } /// @use-src 0:"ir_subobject_order/input.sol" - object "A_13" { + object "B_7" { code { { revert(0, 0) } } /// @use-src 0:"ir_subobject_order/input.sol" - object "A_13_deployed" { + object "B_7_deployed" { code { { revert(0, 0) } } data ".metadata" hex"" } From 3b85fb9ac75f853602779f0541c9f5909640058e Mon Sep 17 00:00:00 2001 From: Nikola Matic Date: Wed, 17 Jul 2024 11:35:34 +0200 Subject: [PATCH 0304/1022] Remove swap from UniqueVector --- libsolutil/CommonData.h | 6 ------ 1 file changed, 6 deletions(-) diff --git a/libsolutil/CommonData.h b/libsolutil/CommonData.h index c64b3913fc83..1a5451ef5191 100644 --- a/libsolutil/CommonData.h +++ b/libsolutil/CommonData.h @@ -380,12 +380,6 @@ class UniqueVector std::vector m_contents; }; -template -void swap(UniqueVector& _lhs, UniqueVector& _rhs) -{ - std::swap(_lhs.contents(), _rhs.contents()); -} - namespace detail { From 94be070ba099d26587af809a7cc54d5348f2fca9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Sun, 30 Jun 2024 17:27:36 +0200 Subject: [PATCH 0305/1022] YulStack: Remove unused m_sourceMappings member --- libyul/YulStack.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/libyul/YulStack.h b/libyul/YulStack.h index d75ff200f5ce..c6d78a115c18 100644 --- a/libyul/YulStack.h +++ b/libyul/YulStack.h @@ -163,8 +163,6 @@ class YulStack: public langutil::CharStreamProvider std::shared_ptr m_parserResult; langutil::ErrorList m_errors; langutil::ErrorReporter m_errorReporter; - - std::unique_ptr m_sourceMappings; }; } From ee839e9a0eee251f6cba9e440397e5f961635f78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Sun, 30 Jun 2024 18:43:12 +0200 Subject: [PATCH 0306/1022] YulStack: Use util::unreachable() instead of returning unnecessary values. --- libyul/YulStack.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libyul/YulStack.cpp b/libyul/YulStack.cpp index 27b4b5526b85..9aaaab2eb20d 100644 --- a/libyul/YulStack.cpp +++ b/libyul/YulStack.cpp @@ -44,6 +44,7 @@ using namespace solidity; using namespace solidity::frontend; using namespace solidity::yul; using namespace solidity::langutil; +using namespace solidity::util; namespace { @@ -257,8 +258,7 @@ MachineAssemblyObject YulStack::assemble(Machine _machine) case Machine::EVM: return assembleWithDeployed().first; } - // unreachable - return MachineAssemblyObject(); + unreachable(); } std::pair From 84b89a5cf358f6c103c79d7ff2732180338745f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Thu, 18 Jul 2024 14:10:25 +0200 Subject: [PATCH 0307/1022] Fix native source locations in optimized IR AST --- Changelog.md | 1 + libsolidity/interface/CompilerStack.cpp | 47 +++--- test/cmdlineTests/ast_ir/output | 92 ++++++------ .../output.json | 142 +++++++++--------- 4 files changed, 147 insertions(+), 135 deletions(-) diff --git a/Changelog.md b/Changelog.md index bfdd45575ff7..7a5adcc4b08d 100644 --- a/Changelog.md +++ b/Changelog.md @@ -19,6 +19,7 @@ Bugfixes: * SMTChecker: Fix formatting of unary minus expressions in invariants. * SMTChecker: Fix internal compiler error when reporting proved targets for BMC engine. * TypeChecker: Fix segfault when assigning nested tuple to tuple. + * Yul AST: Fix ``nativeSrc`` attributes in optimized IR AST referring to locations in unoptimized IR. * Yul IR Code Generation: Deterministic order of Yul subobjects. * Yul Optimizer: Name simplification could lead to forbidden identifiers with a leading and/or trailing dot, e.g., ``x._`` would get simplified into ``x.``. * Yul Parser: Fix segfault when parsing very long location comments. diff --git a/libsolidity/interface/CompilerStack.cpp b/libsolidity/interface/CompilerStack.cpp index 8ee55d87f5a5..adef81793a98 100644 --- a/libsolidity/interface/CompilerStack.cpp +++ b/libsolidity/interface/CompilerStack.cpp @@ -1464,25 +1464,36 @@ void CompilerStack::generateIR(ContractDefinition const& _contract) ); } - yul::YulStack stack( - m_evmVersion, - m_eofVersion, - yul::YulStack::Language::StrictAssembly, - m_optimiserSettings, - m_debugInfoSelection - ); - bool yulAnalysisSuccessful = stack.parseAndAnalyze("", compiledContract.yulIR); - solAssert( - yulAnalysisSuccessful, - compiledContract.yulIR + "\n\n" - "Invalid IR generated:\n" + - langutil::SourceReferenceFormatter::formatErrorInformation(stack.errors(), stack) + "\n" - ); + auto const parseYul = [&](std::string const& _irSource) { + YulStack stack( + m_evmVersion, + m_eofVersion, + YulStack::Language::StrictAssembly, + m_optimiserSettings, + m_debugInfoSelection + ); + bool yulAnalysisSuccessful = stack.parseAndAnalyze("", _irSource); + solAssert( + yulAnalysisSuccessful, + _irSource + "\n\n" + "Invalid IR generated:\n" + + langutil::SourceReferenceFormatter::formatErrorInformation(stack.errors(), stack) + "\n" + ); + return stack; + }; - compiledContract.yulIRAst = stack.astJson(); - stack.optimize(); - compiledContract.yulIROptimized = stack.print(this); - compiledContract.yulIROptimizedAst = stack.astJson(); + { + YulStack stack = parseYul(compiledContract.yulIR); + compiledContract.yulIRAst = stack.astJson(); + stack.optimize(); + compiledContract.yulIROptimized = stack.print(this); + } + { + // Optimizer does not maintain correct native source locations in the AST. + // We can work around it by regenerating the AST from scratch from optimized IR. + YulStack stack = parseYul(compiledContract.yulIROptimized); + compiledContract.yulIROptimizedAst = stack.astJson(); + } } void CompilerStack::generateEVMFromIR(ContractDefinition const& _contract) diff --git a/test/cmdlineTests/ast_ir/output b/test/cmdlineTests/ast_ir/output index c68c77872969..76f111990870 100644 --- a/test/cmdlineTests/ast_ir/output +++ b/test/cmdlineTests/ast_ir/output @@ -637,24 +637,24 @@ Optimized IR AST: { "code": { "block": { - "nativeSrc": "59:790:0", + "nativeSrc": "58:315:0", "nodeType": "YulBlock", "src": "-1:-1:0", "statements": [ { - "nativeSrc": "59:790:0", + "nativeSrc": "68:299:0", "nodeType": "YulBlock", "src": "-1:-1:0", "statements": [ { - "nativeSrc": "122:16:0", + "nativeSrc": "128:27:0", "nodeType": "YulVariableDeclaration", "src": "60:13:0", "value": { "arguments": [ { "kind": "number", - "nativeSrc": "134:3:0", + "nativeSrc": "150:4:0", "nodeType": "YulLiteral", "src": "60:13:0", "type": "", @@ -663,18 +663,18 @@ Optimized IR AST: ], "functionName": { "name": "memoryguard", - "nativeSrc": "122:11:0", + "nativeSrc": "138:11:0", "nodeType": "YulIdentifier", "src": "60:13:0" }, - "nativeSrc": "122:16:0", + "nativeSrc": "138:17:0", "nodeType": "YulFunctionCall", "src": "60:13:0" }, "variables": [ { "name": "_1", - "nativeSrc": "122:16:0", + "nativeSrc": "132:2:0", "nodeType": "YulTypedName", "src": "60:13:0", "type": "" @@ -686,7 +686,7 @@ Optimized IR AST: "arguments": [ { "kind": "number", - "nativeSrc": "118:2:0", + "nativeSrc": "175:2:0", "nodeType": "YulLiteral", "src": "60:13:0", "type": "", @@ -694,28 +694,28 @@ Optimized IR AST: }, { "name": "_1", - "nativeSrc": "122:16:0", + "nativeSrc": "179:2:0", "nodeType": "YulIdentifier", "src": "60:13:0" } ], "functionName": { "name": "mstore", - "nativeSrc": "111:6:0", + "nativeSrc": "168:6:0", "nodeType": "YulIdentifier", "src": "60:13:0" }, - "nativeSrc": "111:28:0", + "nativeSrc": "168:14:0", "nodeType": "YulFunctionCall", "src": "60:13:0" }, - "nativeSrc": "111:28:0", + "nativeSrc": "168:14:0", "nodeType": "YulExpressionStatement", "src": "60:13:0" }, { "body": { - "nativeSrc": "163:83:0", + "nativeSrc": "210:16:0", "nodeType": "YulBlock", "src": "60:13:0", "statements": [ @@ -724,7 +724,7 @@ Optimized IR AST: "arguments": [ { "kind": "number", - "nativeSrc": "650:1:0", + "nativeSrc": "219:1:0", "nodeType": "YulLiteral", "src": "60:13:0", "type": "", @@ -732,7 +732,7 @@ Optimized IR AST: }, { "kind": "number", - "nativeSrc": "650:1:0", + "nativeSrc": "222:1:0", "nodeType": "YulLiteral", "src": "60:13:0", "type": "", @@ -741,15 +741,15 @@ Optimized IR AST: ], "functionName": { "name": "revert", - "nativeSrc": "640:6:0", + "nativeSrc": "212:6:0", "nodeType": "YulIdentifier", "src": "60:13:0" }, - "nativeSrc": "640:12:0", + "nativeSrc": "212:12:0", "nodeType": "YulFunctionCall", "src": "60:13:0" }, - "nativeSrc": "640:12:0", + "nativeSrc": "212:12:0", "nodeType": "YulExpressionStatement", "src": "60:13:0" } @@ -759,20 +759,20 @@ Optimized IR AST: "arguments": [], "functionName": { "name": "callvalue", - "nativeSrc": "151:9:0", + "nativeSrc": "198:9:0", "nodeType": "YulIdentifier", "src": "60:13:0" }, - "nativeSrc": "151:11:0", + "nativeSrc": "198:11:0", "nodeType": "YulFunctionCall", "src": "60:13:0" }, - "nativeSrc": "148:98:0", + "nativeSrc": "195:31:0", "nodeType": "YulIf", "src": "60:13:0" }, { - "nativeSrc": "363:24:0", + "nativeSrc": "239:34:0", "nodeType": "YulVariableDeclaration", "src": "60:13:0", "value": { @@ -780,7 +780,7 @@ Optimized IR AST: { "hexValue": "435f325f6465706c6f796564", "kind": "string", - "nativeSrc": "372:14:0", + "nativeSrc": "258:14:0", "nodeType": "YulLiteral", "src": "60:13:0", "type": "", @@ -789,18 +789,18 @@ Optimized IR AST: ], "functionName": { "name": "datasize", - "nativeSrc": "363:8:0", + "nativeSrc": "249:8:0", "nodeType": "YulIdentifier", "src": "60:13:0" }, - "nativeSrc": "363:24:0", + "nativeSrc": "249:24:0", "nodeType": "YulFunctionCall", "src": "60:13:0" }, "variables": [ { "name": "_2", - "nativeSrc": "363:24:0", + "nativeSrc": "243:2:0", "nodeType": "YulTypedName", "src": "60:13:0", "type": "" @@ -812,7 +812,7 @@ Optimized IR AST: "arguments": [ { "name": "_1", - "nativeSrc": "331:2:0", + "nativeSrc": "295:2:0", "nodeType": "YulIdentifier", "src": "60:13:0" }, @@ -821,7 +821,7 @@ Optimized IR AST: { "hexValue": "435f325f6465706c6f796564", "kind": "string", - "nativeSrc": "346:14:0", + "nativeSrc": "310:14:0", "nodeType": "YulLiteral", "src": "60:13:0", "type": "", @@ -830,32 +830,32 @@ Optimized IR AST: ], "functionName": { "name": "dataoffset", - "nativeSrc": "335:10:0", + "nativeSrc": "299:10:0", "nodeType": "YulIdentifier", "src": "60:13:0" }, - "nativeSrc": "335:26:0", + "nativeSrc": "299:26:0", "nodeType": "YulFunctionCall", "src": "60:13:0" }, { "name": "_2", - "nativeSrc": "363:24:0", + "nativeSrc": "327:2:0", "nodeType": "YulIdentifier", "src": "60:13:0" } ], "functionName": { "name": "codecopy", - "nativeSrc": "322:8:0", + "nativeSrc": "286:8:0", "nodeType": "YulIdentifier", "src": "60:13:0" }, - "nativeSrc": "322:66:0", + "nativeSrc": "286:44:0", "nodeType": "YulFunctionCall", "src": "60:13:0" }, - "nativeSrc": "322:66:0", + "nativeSrc": "286:44:0", "nodeType": "YulExpressionStatement", "src": "60:13:0" }, @@ -864,28 +864,28 @@ Optimized IR AST: "arguments": [ { "name": "_1", - "nativeSrc": "405:2:0", + "nativeSrc": "350:2:0", "nodeType": "YulIdentifier", "src": "60:13:0" }, { "name": "_2", - "nativeSrc": "409:24:0", + "nativeSrc": "354:2:0", "nodeType": "YulIdentifier", "src": "60:13:0" } ], "functionName": { "name": "return", - "nativeSrc": "398:6:0", + "nativeSrc": "343:6:0", "nodeType": "YulIdentifier", "src": "60:13:0" }, - "nativeSrc": "398:36:0", + "nativeSrc": "343:14:0", "nodeType": "YulFunctionCall", "src": "60:13:0" }, - "nativeSrc": "398:36:0", + "nativeSrc": "343:14:0", "nodeType": "YulExpressionStatement", "src": "60:13:0" } @@ -901,12 +901,12 @@ Optimized IR AST: { "code": { "block": { - "nativeSrc": "929:588:0", + "nativeSrc": "453:118:0", "nodeType": "YulBlock", "src": "-1:-1:0", "statements": [ { - "nativeSrc": "929:588:0", + "nativeSrc": "467:94:0", "nodeType": "YulBlock", "src": "-1:-1:0", "statements": [ @@ -915,7 +915,7 @@ Optimized IR AST: "arguments": [ { "kind": "number", - "nativeSrc": "1490:1:0", + "nativeSrc": "542:1:0", "nodeType": "YulLiteral", "src": "60:13:0", "type": "", @@ -923,7 +923,7 @@ Optimized IR AST: }, { "kind": "number", - "nativeSrc": "1490:1:0", + "nativeSrc": "545:1:0", "nodeType": "YulLiteral", "src": "60:13:0", "type": "", @@ -932,15 +932,15 @@ Optimized IR AST: ], "functionName": { "name": "revert", - "nativeSrc": "1480:6:0", + "nativeSrc": "535:6:0", "nodeType": "YulIdentifier", "src": "60:13:0" }, - "nativeSrc": "1480:12:0", + "nativeSrc": "535:12:0", "nodeType": "YulFunctionCall", "src": "60:13:0" }, - "nativeSrc": "1480:12:0", + "nativeSrc": "535:12:0", "nodeType": "YulExpressionStatement", "src": "60:13:0" } diff --git a/test/cmdlineTests/standard_irOptimized_ast_requested/output.json b/test/cmdlineTests/standard_irOptimized_ast_requested/output.json index 91d0e87f3619..5c6762ac9907 100644 --- a/test/cmdlineTests/standard_irOptimized_ast_requested/output.json +++ b/test/cmdlineTests/standard_irOptimized_ast_requested/output.json @@ -5,12 +5,12 @@ "irOptimizedAst": { "code": { "block": { - "nativeSrc": "44:790:0", + "nativeSrc": "43:639:0", "nodeType": "YulBlock", "src": "-1:-1:0", "statements": [ { - "nativeSrc": "44:790:0", + "nativeSrc": "53:421:0", "nodeType": "YulBlock", "src": "-1:-1:0", "statements": [ @@ -19,7 +19,7 @@ "arguments": [ { "kind": "number", - "nativeSrc": "103:2:0", + "nativeSrc": "120:2:0", "nodeType": "YulLiteral", "src": "56:13:0", "type": "", @@ -29,7 +29,7 @@ "arguments": [ { "kind": "number", - "nativeSrc": "119:3:0", + "nativeSrc": "136:4:0", "nodeType": "YulLiteral", "src": "56:13:0", "type": "", @@ -38,32 +38,32 @@ ], "functionName": { "name": "memoryguard", - "nativeSrc": "107:11:0", + "nativeSrc": "124:11:0", "nodeType": "YulIdentifier", "src": "56:13:0" }, - "nativeSrc": "107:16:0", + "nativeSrc": "124:17:0", "nodeType": "YulFunctionCall", "src": "56:13:0" } ], "functionName": { "name": "mstore", - "nativeSrc": "96:6:0", + "nativeSrc": "113:6:0", "nodeType": "YulIdentifier", "src": "56:13:0" }, - "nativeSrc": "96:28:0", + "nativeSrc": "113:29:0", "nodeType": "YulFunctionCall", "src": "56:13:0" }, - "nativeSrc": "96:28:0", + "nativeSrc": "113:29:0", "nodeType": "YulExpressionStatement", "src": "56:13:0" }, { "body": { - "nativeSrc": "148:83:0", + "nativeSrc": "182:111:0", "nodeType": "YulBlock", "src": "56:13:0", "statements": [ @@ -72,15 +72,15 @@ "arguments": [], "functionName": { "name": "revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb", - "nativeSrc": "150:77:0", + "nativeSrc": "200:77:0", "nodeType": "YulIdentifier", "src": "56:13:0" }, - "nativeSrc": "150:79:0", + "nativeSrc": "200:79:0", "nodeType": "YulFunctionCall", "src": "56:13:0" }, - "nativeSrc": "150:79:0", + "nativeSrc": "200:79:0", "nodeType": "YulExpressionStatement", "src": "56:13:0" } @@ -90,38 +90,38 @@ "arguments": [], "functionName": { "name": "callvalue", - "nativeSrc": "136:9:0", + "nativeSrc": "158:9:0", "nodeType": "YulIdentifier", "src": "56:13:0" }, - "nativeSrc": "136:11:0", + "nativeSrc": "158:11:0", "nodeType": "YulFunctionCall", "src": "56:13:0" }, - "nativeSrc": "133:98:0", + "nativeSrc": "155:138:0", "nodeType": "YulIf", "src": "56:13:0" }, { - "nativeSrc": "268:30:0", + "nativeSrc": "306:30:0", "nodeType": "YulVariableDeclaration", "src": "56:13:0", "value": { "arguments": [], "functionName": { "name": "allocate_unbounded", - "nativeSrc": "278:18:0", + "nativeSrc": "316:18:0", "nodeType": "YulIdentifier", "src": "56:13:0" }, - "nativeSrc": "278:20:0", + "nativeSrc": "316:20:0", "nodeType": "YulFunctionCall", "src": "56:13:0" }, "variables": [ { "name": "_1", - "nativeSrc": "272:2:0", + "nativeSrc": "310:2:0", "nodeType": "YulTypedName", "src": "56:13:0", "type": "" @@ -133,7 +133,7 @@ "arguments": [ { "name": "_1", - "nativeSrc": "316:2:0", + "nativeSrc": "358:2:0", "nodeType": "YulIdentifier", "src": "56:13:0" }, @@ -142,7 +142,7 @@ { "hexValue": "435f325f6465706c6f796564", "kind": "string", - "nativeSrc": "331:14:0", + "nativeSrc": "373:14:0", "nodeType": "YulLiteral", "src": "56:13:0", "type": "", @@ -151,11 +151,11 @@ ], "functionName": { "name": "dataoffset", - "nativeSrc": "320:10:0", + "nativeSrc": "362:10:0", "nodeType": "YulIdentifier", "src": "56:13:0" }, - "nativeSrc": "320:26:0", + "nativeSrc": "362:26:0", "nodeType": "YulFunctionCall", "src": "56:13:0" }, @@ -164,7 +164,7 @@ { "hexValue": "435f325f6465706c6f796564", "kind": "string", - "nativeSrc": "357:14:0", + "nativeSrc": "399:14:0", "nodeType": "YulLiteral", "src": "56:13:0", "type": "", @@ -173,26 +173,26 @@ ], "functionName": { "name": "datasize", - "nativeSrc": "348:8:0", + "nativeSrc": "390:8:0", "nodeType": "YulIdentifier", "src": "56:13:0" }, - "nativeSrc": "348:24:0", + "nativeSrc": "390:24:0", "nodeType": "YulFunctionCall", "src": "56:13:0" } ], "functionName": { "name": "codecopy", - "nativeSrc": "307:8:0", + "nativeSrc": "349:8:0", "nodeType": "YulIdentifier", "src": "56:13:0" }, - "nativeSrc": "307:66:0", + "nativeSrc": "349:66:0", "nodeType": "YulFunctionCall", "src": "56:13:0" }, - "nativeSrc": "307:66:0", + "nativeSrc": "349:66:0", "nodeType": "YulExpressionStatement", "src": "56:13:0" }, @@ -201,7 +201,7 @@ "arguments": [ { "name": "_1", - "nativeSrc": "390:2:0", + "nativeSrc": "435:2:0", "nodeType": "YulIdentifier", "src": "56:13:0" }, @@ -210,7 +210,7 @@ { "hexValue": "435f325f6465706c6f796564", "kind": "string", - "nativeSrc": "403:14:0", + "nativeSrc": "448:14:0", "nodeType": "YulLiteral", "src": "56:13:0", "type": "", @@ -219,26 +219,26 @@ ], "functionName": { "name": "datasize", - "nativeSrc": "394:8:0", + "nativeSrc": "439:8:0", "nodeType": "YulIdentifier", "src": "56:13:0" }, - "nativeSrc": "394:24:0", + "nativeSrc": "439:24:0", "nodeType": "YulFunctionCall", "src": "56:13:0" } ], "functionName": { "name": "return", - "nativeSrc": "383:6:0", + "nativeSrc": "428:6:0", "nodeType": "YulIdentifier", "src": "56:13:0" }, - "nativeSrc": "383:36:0", + "nativeSrc": "428:36:0", "nodeType": "YulFunctionCall", "src": "56:13:0" }, - "nativeSrc": "383:36:0", + "nativeSrc": "428:36:0", "nodeType": "YulExpressionStatement", "src": "56:13:0" } @@ -246,19 +246,19 @@ }, { "body": { - "nativeSrc": "469:43:0", + "nativeSrc": "531:23:0", "nodeType": "YulBlock", "src": "56:13:0", "statements": [ { - "nativeSrc": "483:19:0", + "nativeSrc": "533:19:0", "nodeType": "YulAssignment", "src": "56:13:0", "value": { "arguments": [ { "kind": "number", - "nativeSrc": "499:2:0", + "nativeSrc": "549:2:0", "nodeType": "YulLiteral", "src": "56:13:0", "type": "", @@ -267,18 +267,18 @@ ], "functionName": { "name": "mload", - "nativeSrc": "493:5:0", + "nativeSrc": "543:5:0", "nodeType": "YulIdentifier", "src": "56:13:0" }, - "nativeSrc": "493:9:0", + "nativeSrc": "543:9:0", "nodeType": "YulFunctionCall", "src": "56:13:0" }, "variableNames": [ { "name": "memPtr", - "nativeSrc": "483:6:0", + "nativeSrc": "533:6:0", "nodeType": "YulIdentifier", "src": "56:13:0" } @@ -287,12 +287,12 @@ ] }, "name": "allocate_unbounded", - "nativeSrc": "429:83:0", + "nativeSrc": "483:71:0", "nodeType": "YulFunctionDefinition", "returnVariables": [ { "name": "memPtr", - "nativeSrc": "462:6:0", + "nativeSrc": "516:6:0", "nodeType": "YulTypedName", "src": "56:13:0", "type": "" @@ -302,7 +302,7 @@ }, { "body": { - "nativeSrc": "611:36:0", + "nativeSrc": "660:16:0", "nodeType": "YulBlock", "src": "56:13:0", "statements": [ @@ -311,7 +311,7 @@ "arguments": [ { "kind": "number", - "nativeSrc": "632:1:0", + "nativeSrc": "669:1:0", "nodeType": "YulLiteral", "src": "56:13:0", "type": "", @@ -319,7 +319,7 @@ }, { "kind": "number", - "nativeSrc": "635:1:0", + "nativeSrc": "672:1:0", "nodeType": "YulLiteral", "src": "56:13:0", "type": "", @@ -328,22 +328,22 @@ ], "functionName": { "name": "revert", - "nativeSrc": "625:6:0", + "nativeSrc": "662:6:0", "nodeType": "YulIdentifier", "src": "56:13:0" }, - "nativeSrc": "625:12:0", + "nativeSrc": "662:12:0", "nodeType": "YulFunctionCall", "src": "56:13:0" }, - "nativeSrc": "625:12:0", + "nativeSrc": "662:12:0", "nodeType": "YulExpressionStatement", "src": "56:13:0" } ] }, "name": "revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb", - "nativeSrc": "522:125:0", + "nativeSrc": "563:113:0", "nodeType": "YulFunctionDefinition", "src": "56:13:0" } @@ -357,12 +357,12 @@ { "code": { "block": { - "nativeSrc": "899:588:0", + "nativeSrc": "747:361:0", "nodeType": "YulBlock", "src": "-1:-1:0", "statements": [ { - "nativeSrc": "899:588:0", + "nativeSrc": "761:207:0", "nodeType": "YulBlock", "src": "-1:-1:0", "statements": [ @@ -371,7 +371,7 @@ "arguments": [ { "kind": "number", - "nativeSrc": "966:2:0", + "nativeSrc": "836:2:0", "nodeType": "YulLiteral", "src": "56:13:0", "type": "", @@ -381,7 +381,7 @@ "arguments": [ { "kind": "number", - "nativeSrc": "982:3:0", + "nativeSrc": "852:4:0", "nodeType": "YulLiteral", "src": "56:13:0", "type": "", @@ -390,26 +390,26 @@ ], "functionName": { "name": "memoryguard", - "nativeSrc": "970:11:0", + "nativeSrc": "840:11:0", "nodeType": "YulIdentifier", "src": "56:13:0" }, - "nativeSrc": "970:16:0", + "nativeSrc": "840:17:0", "nodeType": "YulFunctionCall", "src": "56:13:0" } ], "functionName": { "name": "mstore", - "nativeSrc": "959:6:0", + "nativeSrc": "829:6:0", "nodeType": "YulIdentifier", "src": "56:13:0" }, - "nativeSrc": "959:28:0", + "nativeSrc": "829:29:0", "nodeType": "YulFunctionCall", "src": "56:13:0" }, - "nativeSrc": "959:28:0", + "nativeSrc": "829:29:0", "nodeType": "YulExpressionStatement", "src": "56:13:0" }, @@ -418,15 +418,15 @@ "arguments": [], "functionName": { "name": "revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74", - "nativeSrc": "1001:77:0", + "nativeSrc": "875:77:0", "nodeType": "YulIdentifier", "src": "56:13:0" }, - "nativeSrc": "1001:79:0", + "nativeSrc": "875:79:0", "nodeType": "YulFunctionCall", "src": "56:13:0" }, - "nativeSrc": "1001:79:0", + "nativeSrc": "875:79:0", "nodeType": "YulExpressionStatement", "src": "56:13:0" } @@ -434,7 +434,7 @@ }, { "body": { - "nativeSrc": "1432:44:0", + "nativeSrc": "1082:16:0", "nodeType": "YulBlock", "src": "56:13:0", "statements": [ @@ -443,7 +443,7 @@ "arguments": [ { "kind": "number", - "nativeSrc": "1457:1:0", + "nativeSrc": "1091:1:0", "nodeType": "YulLiteral", "src": "56:13:0", "type": "", @@ -451,7 +451,7 @@ }, { "kind": "number", - "nativeSrc": "1460:1:0", + "nativeSrc": "1094:1:0", "nodeType": "YulLiteral", "src": "56:13:0", "type": "", @@ -460,22 +460,22 @@ ], "functionName": { "name": "revert", - "nativeSrc": "1450:6:0", + "nativeSrc": "1084:6:0", "nodeType": "YulIdentifier", "src": "56:13:0" }, - "nativeSrc": "1450:12:0", + "nativeSrc": "1084:12:0", "nodeType": "YulFunctionCall", "src": "56:13:0" }, - "nativeSrc": "1450:12:0", + "nativeSrc": "1084:12:0", "nodeType": "YulExpressionStatement", "src": "56:13:0" } ] }, "name": "revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74", - "nativeSrc": "1343:133:0", + "nativeSrc": "981:117:0", "nodeType": "YulFunctionDefinition", "src": "56:13:0" } From 198d2393ce504e108ee0bbb531f8ad3f375a87ca Mon Sep 17 00:00:00 2001 From: Nikola Matic Date: Fri, 19 Jul 2024 09:56:15 +0200 Subject: [PATCH 0308/1022] Downgrade nodejs in base_node_small image to fix CI --- .circleci/config.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index d6c3f33da08a..20f57b41312e 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -487,7 +487,8 @@ defaults: - base_node_small: &base_node_small docker: - - image: cimg/node:current + # TODO: Revert to cimg/node:current once https://github.com/npm/cli/issues/7657 is resolved. + - image: cimg/node:22.4 resource_class: small environment: &base_node_small_env TERM: xterm @@ -761,6 +762,7 @@ defaults: # which does not support shanghai EVM. compile_only: 1 resource_class: medium + image: cimg/node:18.16 - job_native_test_ext_yield_liquidator: &job_native_test_ext_yield_liquidator <<: *requires_b_ubu_static From 1a5335a48688bd19dbb95d9279e7e1af5e4044d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Wed, 17 Jul 2024 17:01:16 +0200 Subject: [PATCH 0309/1022] Fix isoltest crash when formatting call arguments in a contract whose ABI includes entries without names - functionSignatureFromABI() would attempt to calculate signature for a function even if it had no name (i.e. was a constructor, fallback or receive). This would lead to a crash. - The buggy logic is used only for formatting expectations when an test fails in interactive mode. --- test/libsolidity/util/ContractABIUtils.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/test/libsolidity/util/ContractABIUtils.cpp b/test/libsolidity/util/ContractABIUtils.cpp index fb2f4eb62679..dcbdcbc5d166 100644 --- a/test/libsolidity/util/ContractABIUtils.cpp +++ b/test/libsolidity/util/ContractABIUtils.cpp @@ -142,6 +142,8 @@ std::optional isFixedPoint(std::string const& type) std::string functionSignatureFromABI(Json const& _functionABI) { + soltestAssert(_functionABI.contains("name")); + auto inputs = _functionABI["inputs"]; std::string signature = {_functionABI["name"].get() + "("}; size_t parameterCount = 0; @@ -169,7 +171,9 @@ std::optional ContractABIUtils::paramet return std::nullopt; for (auto const& function: _contractABI) - if (_functionSignature == functionSignatureFromABI(function)) + // ABI may contain functions without names (constructor, fallback, receive). Since name is + // necessary to calculate the signature, these cannot possibly match and can be safely ignored. + if (function.contains("name") && _functionSignature == functionSignatureFromABI(function)) { ParameterList inplaceTypeParams; ParameterList dynamicTypeParams; From 96fdcc3d040d05209f561e78a50dee2ebe4252c3 Mon Sep 17 00:00:00 2001 From: clonker Date: Thu, 18 Jul 2024 14:15:22 +0200 Subject: [PATCH 0310/1022] Yul: Prepare removal of YulString by replacing its occurrences by YulName typedef --- libsolc/libsolc.cpp | 2 +- libsolidity/analysis/ReferencesResolver.cpp | 2 +- libsolidity/analysis/ReferencesResolver.h | 2 +- libsolidity/codegen/CompilerContext.cpp | 10 +- libsolidity/codegen/CompilerContext.h | 2 +- libsolidity/codegen/ContractCompiler.cpp | 2 +- .../codegen/ir/IRGeneratorForStatements.cpp | 6 +- .../codegen/IRGeneratorForStatements.cpp | 6 +- libsolidity/interface/CompilerStack.cpp | 2 +- libyul/AST.h | 10 +- libyul/AsmAnalysis.cpp | 52 ++++---- libyul/AsmAnalysis.h | 18 +-- libyul/AsmJsonImporter.cpp | 10 +- libyul/AsmParser.cpp | 6 +- libyul/AsmParser.h | 2 +- libyul/AsmPrinter.cpp | 2 +- libyul/AsmPrinter.h | 4 +- libyul/CMakeLists.txt | 1 + libyul/CompilabilityChecker.h | 4 +- libyul/ControlFlowSideEffectsCollector.cpp | 4 +- libyul/ControlFlowSideEffectsCollector.h | 2 +- libyul/Dialect.cpp | 31 +++-- libyul/Dialect.h | 37 +++--- libyul/Exceptions.h | 10 +- libyul/FunctionReferenceResolver.h | 2 +- libyul/Object.h | 1 - libyul/ObjectParser.h | 1 - libyul/Scope.cpp | 8 +- libyul/Scope.h | 20 +-- libyul/YulName.h | 26 ++++ libyul/YulString.h | 2 +- libyul/backends/evm/ConstantOptimiser.cpp | 16 +-- libyul/backends/evm/ConstantOptimiser.h | 6 +- .../backends/evm/ControlFlowGraphBuilder.cpp | 10 +- libyul/backends/evm/ControlFlowGraphBuilder.h | 4 +- libyul/backends/evm/EVMCodeTransform.cpp | 12 +- libyul/backends/evm/EVMCodeTransform.h | 8 +- libyul/backends/evm/EVMDialect.cpp | 122 +++++++++--------- libyul/backends/evm/EVMDialect.h | 33 +++-- libyul/backends/evm/EVMObjectCompiler.cpp | 2 +- .../evm/OptimizedEVMCodeTransform.cpp | 14 +- libyul/backends/evm/StackLayoutGenerator.cpp | 10 +- libyul/backends/evm/StackLayoutGenerator.h | 6 +- .../backends/evm/VariableReferenceCounter.cpp | 2 +- .../backends/evm/VariableReferenceCounter.h | 2 +- libyul/optimiser/ASTCopier.cpp | 4 +- libyul/optimiser/ASTCopier.h | 10 +- libyul/optimiser/ASTWalker.h | 2 +- libyul/optimiser/BlockHasher.h | 6 +- libyul/optimiser/CallGraphGenerator.cpp | 14 +- libyul/optimiser/CallGraphGenerator.h | 8 +- libyul/optimiser/CircularReferencesPruner.cpp | 12 +- libyul/optimiser/CircularReferencesPruner.h | 7 +- .../CommonSubexpressionEliminator.cpp | 6 +- .../optimiser/CommonSubexpressionEliminator.h | 8 +- libyul/optimiser/ConditionalSimplifier.cpp | 4 +- libyul/optimiser/ConditionalSimplifier.h | 4 +- libyul/optimiser/ConditionalUnsimplifier.cpp | 4 +- libyul/optimiser/ConditionalUnsimplifier.h | 4 +- libyul/optimiser/ControlFlowSimplifier.cpp | 2 +- libyul/optimiser/DataFlowAnalyzer.cpp | 64 ++++----- libyul/optimiser/DataFlowAnalyzer.h | 56 ++++---- libyul/optimiser/DeadCodeEliminator.h | 6 +- libyul/optimiser/Disambiguator.cpp | 2 +- libyul/optimiser/Disambiguator.h | 8 +- libyul/optimiser/EqualStoreEliminator.cpp | 4 +- libyul/optimiser/EqualStoreEliminator.h | 2 +- libyul/optimiser/EquivalentFunctionCombiner.h | 4 +- libyul/optimiser/EquivalentFunctionDetector.h | 4 +- libyul/optimiser/ExpressionInliner.cpp | 4 +- libyul/optimiser/ExpressionInliner.h | 9 +- libyul/optimiser/ExpressionJoiner.h | 2 +- libyul/optimiser/ExpressionSimplifier.cpp | 2 +- libyul/optimiser/ExpressionSplitter.cpp | 4 +- .../optimiser/ForLoopConditionOutOfBody.cpp | 2 +- libyul/optimiser/FullInliner.cpp | 35 +++-- libyul/optimiser/FullInliner.h | 32 ++--- libyul/optimiser/FunctionCallFinder.cpp | 10 +- libyul/optimiser/FunctionCallFinder.h | 6 +- libyul/optimiser/FunctionSpecializer.cpp | 12 +- libyul/optimiser/FunctionSpecializer.h | 8 +- .../InlinableExpressionFunctionFinder.cpp | 4 +- .../InlinableExpressionFunctionFinder.h | 8 +- libyul/optimiser/KnowledgeBase.cpp | 36 +++--- libyul/optimiser/KnowledgeBase.h | 38 +++--- libyul/optimiser/LoadResolver.cpp | 4 +- libyul/optimiser/LoadResolver.h | 2 +- libyul/optimiser/LoopInvariantCodeMotion.cpp | 8 +- libyul/optimiser/LoopInvariantCodeMotion.h | 10 +- libyul/optimiser/Metrics.cpp | 2 +- libyul/optimiser/Metrics.h | 4 +- libyul/optimiser/NameCollector.cpp | 22 ++-- libyul/optimiser/NameCollector.h | 31 ++--- libyul/optimiser/NameDispenser.cpp | 13 +- libyul/optimiser/NameDispenser.h | 18 +-- libyul/optimiser/NameDisplacer.cpp | 4 +- libyul/optimiser/NameDisplacer.h | 14 +- libyul/optimiser/NameSimplifier.cpp | 14 +- libyul/optimiser/NameSimplifier.h | 8 +- libyul/optimiser/OptimiserStep.h | 3 +- libyul/optimiser/OptimizerUtilities.cpp | 4 +- libyul/optimiser/OptimizerUtilities.h | 6 +- libyul/optimiser/Rematerialiser.cpp | 8 +- libyul/optimiser/Rematerialiser.h | 8 +- libyul/optimiser/SSATransform.cpp | 52 ++++---- libyul/optimiser/SSAValueTracker.cpp | 6 +- libyul/optimiser/SSAValueTracker.h | 12 +- libyul/optimiser/Semantics.cpp | 18 +-- libyul/optimiser/Semantics.h | 22 ++-- libyul/optimiser/SimplificationRules.cpp | 8 +- libyul/optimiser/SimplificationRules.h | 6 +- libyul/optimiser/StackCompressor.cpp | 44 +++---- libyul/optimiser/StackLimitEvader.cpp | 33 +++-- libyul/optimiser/StackLimitEvader.h | 4 +- libyul/optimiser/StackToMemoryMover.cpp | 16 +-- libyul/optimiser/StackToMemoryMover.h | 21 +-- libyul/optimiser/Substitution.cpp | 2 +- libyul/optimiser/Substitution.h | 6 +- libyul/optimiser/Suite.cpp | 4 +- libyul/optimiser/Suite.h | 4 +- libyul/optimiser/SyntacticalEquality.h | 6 +- libyul/optimiser/TypeInfo.cpp | 12 +- libyul/optimiser/TypeInfo.h | 16 +-- libyul/optimiser/UnusedAssignEliminator.cpp | 4 +- libyul/optimiser/UnusedAssignEliminator.h | 8 +- .../UnusedFunctionParameterPruner.cpp | 14 +- libyul/optimiser/UnusedFunctionsCommon.cpp | 4 +- libyul/optimiser/UnusedFunctionsCommon.h | 4 +- libyul/optimiser/UnusedPruner.cpp | 20 +-- libyul/optimiser/UnusedPruner.h | 26 ++-- libyul/optimiser/UnusedStoreBase.h | 2 +- libyul/optimiser/UnusedStoreEliminator.cpp | 24 ++-- libyul/optimiser/UnusedStoreEliminator.h | 22 ++-- libyul/optimiser/VarNameCleaner.cpp | 16 +-- libyul/optimiser/VarNameCleaner.h | 16 +-- test/libsolidity/MemoryGuardTest.cpp | 2 +- test/libyul/FunctionSideEffects.cpp | 2 +- test/libyul/KnowledgeBaseTest.cpp | 50 +++---- test/libyul/Parser.cpp | 6 +- test/libyul/StackShufflingTest.cpp | 8 +- test/libyul/StackShufflingTest.h | 4 +- test/libyul/YulOptimizerTestCommon.cpp | 10 +- test/libyul/YulOptimizerTestCommon.h | 4 +- test/tools/yulInterpreter/Inspector.h | 10 +- test/tools/yulInterpreter/Interpreter.cpp | 6 +- test/tools/yulInterpreter/Interpreter.h | 14 +- test/tools/yulopti.cpp | 2 +- tools/yulPhaser/Program.cpp | 6 +- 148 files changed, 879 insertions(+), 871 deletions(-) create mode 100644 libyul/YulName.h diff --git a/libsolc/libsolc.cpp b/libsolc/libsolc.cpp index 105949253260..b49905130ccc 100644 --- a/libsolc/libsolc.cpp +++ b/libsolc/libsolc.cpp @@ -24,7 +24,7 @@ #include #include #include -#include +#include #include #include diff --git a/libsolidity/analysis/ReferencesResolver.cpp b/libsolidity/analysis/ReferencesResolver.cpp index fd7def71459a..270e1a55abc5 100644 --- a/libsolidity/analysis/ReferencesResolver.cpp +++ b/libsolidity/analysis/ReferencesResolver.cpp @@ -488,7 +488,7 @@ void ReferencesResolver::resolveInheritDoc(StructuredDocumentation const& _docum } } -void ReferencesResolver::validateYulIdentifierName(yul::YulString _name, SourceLocation const& _location) +void ReferencesResolver::validateYulIdentifierName(yul::YulName _name, SourceLocation const& _location) { if (util::contains(_name.str(), '.')) m_errorReporter.declarationError( diff --git a/libsolidity/analysis/ReferencesResolver.h b/libsolidity/analysis/ReferencesResolver.h index 13752e9c9345..0b7f9d37329f 100644 --- a/libsolidity/analysis/ReferencesResolver.h +++ b/libsolidity/analysis/ReferencesResolver.h @@ -94,7 +94,7 @@ class ReferencesResolver: private ASTConstVisitor, private yul::ASTWalker void resolveInheritDoc(StructuredDocumentation const& _documentation, StructurallyDocumentedAnnotation& _annotation); /// Checks if the name contains a '.'. - void validateYulIdentifierName(yul::YulString _name, langutil::SourceLocation const& _location); + void validateYulIdentifierName(yul::YulName _name, langutil::SourceLocation const& _location); langutil::ErrorReporter& m_errorReporter; NameAndTypeResolver& m_resolver; diff --git a/libsolidity/codegen/CompilerContext.cpp b/libsolidity/codegen/CompilerContext.cpp index d9264c6ac5f1..4d522072af06 100644 --- a/libsolidity/codegen/CompilerContext.cpp +++ b/libsolidity/codegen/CompilerContext.cpp @@ -38,7 +38,7 @@ #include #include #include -#include +#include #include #include @@ -388,11 +388,11 @@ void CompilerContext::appendInlineAssembly( { unsigned startStackHeight = stackHeight(); - std::set externallyUsedIdentifiers; + std::set externallyUsedIdentifiers; for (auto const& fun: _externallyUsedFunctions) - externallyUsedIdentifiers.insert(yul::YulString(fun)); + externallyUsedIdentifiers.insert(yul::YulName(fun)); for (auto const& var: _localVariables) - externallyUsedIdentifiers.insert(yul::YulString(var)); + externallyUsedIdentifiers.insert(yul::YulName(var)); yul::ExternalIdentifierAccess identifierAccess; identifierAccess.resolve = [&]( @@ -532,7 +532,7 @@ void CompilerContext::appendInlineAssembly( } -void CompilerContext::optimizeYul(yul::Object& _object, yul::EVMDialect const& _dialect, OptimiserSettings const& _optimiserSettings, std::set const& _externalIdentifiers) +void CompilerContext::optimizeYul(yul::Object& _object, yul::EVMDialect const& _dialect, OptimiserSettings const& _optimiserSettings, std::set const& _externalIdentifiers) { #ifdef SOL_OUTPUT_ASM cout << yul::AsmPrinter(*dialect)(*_object.code) << endl; diff --git a/libsolidity/codegen/CompilerContext.h b/libsolidity/codegen/CompilerContext.h index 8eba084eba7b..c6972f92b83b 100644 --- a/libsolidity/codegen/CompilerContext.h +++ b/libsolidity/codegen/CompilerContext.h @@ -277,7 +277,7 @@ class CompilerContext /// Otherwise returns "revert(0, 0)". std::string revertReasonIfDebug(std::string const& _message = ""); - void optimizeYul(yul::Object& _object, yul::EVMDialect const& _dialect, OptimiserSettings const& _optimiserSetting, std::set const& _externalIdentifiers = {}); + void optimizeYul(yul::Object& _object, yul::EVMDialect const& _dialect, OptimiserSettings const& _optimiserSetting, std::set const& _externalIdentifiers = {}); /// Appends arbitrary data to the end of the bytecode. void appendToAuxiliaryData(bytes const& _data) { m_asm->appendToAuxiliaryData(_data); } diff --git a/libsolidity/codegen/ContractCompiler.cpp b/libsolidity/codegen/ContractCompiler.cpp index 2326d3336364..0ed17f6d02b0 100644 --- a/libsolidity/codegen/ContractCompiler.cpp +++ b/libsolidity/codegen/ContractCompiler.cpp @@ -38,7 +38,7 @@ #include #include #include -#include +#include #include #include diff --git a/libsolidity/codegen/ir/IRGeneratorForStatements.cpp b/libsolidity/codegen/ir/IRGeneratorForStatements.cpp index 0579f50c2d96..5be4d550e767 100644 --- a/libsolidity/codegen/ir/IRGeneratorForStatements.cpp +++ b/libsolidity/codegen/ir/IRGeneratorForStatements.cpp @@ -78,7 +78,7 @@ struct CopyTranslate: public yul::ASTCopier return ASTCopier::operator()(_identifier); } - yul::YulString translateIdentifier(yul::YulString _name) override + yul::YulName translateIdentifier(yul::YulName _name) override { // Strictly, the dialect used by inline assembly (m_dialect) could be different // from the Yul dialect we are compiling to. So we are assuming here that the builtin @@ -87,7 +87,7 @@ struct CopyTranslate: public yul::ASTCopier if (m_dialect.builtin(_name)) return _name; else - return yul::YulString{"usr$" + _name.str()}; + return yul::YulName{"usr$" + _name.str()}; } yul::Identifier translate(yul::Identifier const& _identifier) override @@ -206,7 +206,7 @@ struct CopyTranslate: public yul::ASTCopier if (isDigit(value.front())) return yul::Literal{_identifier.debugData, yul::LiteralKind::Number, yul::valueOfNumberLiteral(value), {}}; else - return yul::Identifier{_identifier.debugData, yul::YulString{value}}; + return yul::Identifier{_identifier.debugData, yul::YulName{value}}; } diff --git a/libsolidity/experimental/codegen/IRGeneratorForStatements.cpp b/libsolidity/experimental/codegen/IRGeneratorForStatements.cpp index cb4705f0d189..f9c50cf7a78c 100644 --- a/libsolidity/experimental/codegen/IRGeneratorForStatements.cpp +++ b/libsolidity/experimental/codegen/IRGeneratorForStatements.cpp @@ -70,12 +70,12 @@ struct CopyTranslate: public yul::ASTCopier return ASTCopier::operator()(_identifier); } - yul::YulString translateIdentifier(yul::YulString _name) override + yul::YulName translateIdentifier(yul::YulName _name) override { if (m_dialect.builtin(_name)) return _name; else - return yul::YulString{"usr$" + _name.str()}; + return yul::YulName{"usr$" + _name.str()}; } yul::Identifier translate(yul::Identifier const& _identifier) override @@ -102,7 +102,7 @@ struct CopyTranslate: public yul::ASTCopier solAssert(type); solAssert(m_context.env->typeEquals(*type, m_context.analysis.typeSystem().type(PrimitiveType::Word, {}))); std::string value = IRNames::localVariable(*varDecl); - return yul::Identifier{_identifier.debugData, yul::YulString{value}}; + return yul::Identifier{_identifier.debugData, yul::YulName{value}}; } IRGenerationContext const& m_context; diff --git a/libsolidity/interface/CompilerStack.cpp b/libsolidity/interface/CompilerStack.cpp index adef81793a98..566feb21b171 100644 --- a/libsolidity/interface/CompilerStack.cpp +++ b/libsolidity/interface/CompilerStack.cpp @@ -66,7 +66,7 @@ #include -#include +#include #include #include #include diff --git a/libyul/AST.h b/libyul/AST.h index ad60e468592a..72be60a46843 100644 --- a/libyul/AST.h +++ b/libyul/AST.h @@ -24,7 +24,7 @@ #pragma once #include -#include +#include #include @@ -36,9 +36,9 @@ namespace solidity::yul { -using Type = YulString; +using Type = YulName; -struct TypedName { langutil::DebugData::ConstPtr debugData; YulString name; Type type; }; +struct TypedName { langutil::DebugData::ConstPtr debugData; YulName name; Type type; }; using TypedNameList = std::vector; /// Literal number or string (up to 32 bytes) @@ -70,7 +70,7 @@ class LiteralValue { }; struct Literal { langutil::DebugData::ConstPtr debugData; LiteralKind kind; LiteralValue value; Type type; }; /// External / internal identifier or label reference -struct Identifier { langutil::DebugData::ConstPtr debugData; YulString name; }; +struct Identifier { langutil::DebugData::ConstPtr debugData; YulName name; }; /// Assignment ("x := mload(20:u256)", expects push-1-expression on the right hand /// side and requires x to occupy exactly one stack slot. /// @@ -86,7 +86,7 @@ struct VariableDeclaration { langutil::DebugData::ConstPtr debugData; TypedNameL /// Block that creates a scope (frees declared stack variables) struct Block { langutil::DebugData::ConstPtr debugData; std::vector statements; }; /// Function definition ("function f(a, b) -> (d, e) { ... }") -struct FunctionDefinition { langutil::DebugData::ConstPtr debugData; YulString name; TypedNameList parameters; TypedNameList returnVariables; Block body; }; +struct FunctionDefinition { langutil::DebugData::ConstPtr debugData; YulName name; TypedNameList parameters; TypedNameList returnVariables; Block body; }; /// Conditional execution without "else" part. struct If { langutil::DebugData::ConstPtr debugData; std::unique_ptr condition; Block body; }; /// Switch case or default case diff --git a/libyul/AsmAnalysis.cpp b/libyul/AsmAnalysis.cpp index 38b9c782e0fc..cccb3de42158 100644 --- a/libyul/AsmAnalysis.cpp +++ b/libyul/AsmAnalysis.cpp @@ -100,7 +100,7 @@ AsmAnalysisInfo AsmAnalyzer::analyzeStrictAssertCorrect(Dialect const& _dialect, return analysisInfo; } -std::vector AsmAnalyzer::operator()(Literal const& _literal) +std::vector AsmAnalyzer::operator()(Literal const& _literal) { expectValidType(_literal.type, nativeLocationOf(_literal)); bool erroneousLiteralValue = false; @@ -132,11 +132,11 @@ std::vector AsmAnalyzer::operator()(Literal const& _literal) return {_literal.type}; } -std::vector AsmAnalyzer::operator()(Identifier const& _identifier) +std::vector AsmAnalyzer::operator()(Identifier const& _identifier) { yulAssert(!_identifier.name.empty(), ""); auto watcher = m_errorReporter.errorWatcher(); - YulString type = m_dialect.defaultType; + YulName type = m_dialect.defaultType; if (m_currentScope->lookup(_identifier.name, GenericVisitor{ [&](Scope::Variable const& _var) @@ -190,7 +190,7 @@ std::vector AsmAnalyzer::operator()(Identifier const& _identifier) void AsmAnalyzer::operator()(ExpressionStatement const& _statement) { auto watcher = m_errorReporter.errorWatcher(); - std::vector types = std::visit(*this, _statement.expression); + std::vector types = std::visit(*this, _statement.expression); if (watcher.ok() && !types.empty()) m_errorReporter.typeError( 3083_error, @@ -209,7 +209,7 @@ void AsmAnalyzer::operator()(Assignment const& _assignment) size_t const numVariables = _assignment.variableNames.size(); yulAssert(numVariables >= 1, ""); - std::set variables; + std::set variables; for (auto const& _variableName: _assignment.variableNames) if (!variables.insert(_variableName.name).second) m_errorReporter.declarationError( @@ -220,7 +220,7 @@ void AsmAnalyzer::operator()(Assignment const& _assignment) " occurs multiple times on the left-hand side of the assignment." ); - std::vector types = std::visit(*this, *_assignment.value); + std::vector types = std::visit(*this, *_assignment.value); if (types.size() != numVariables) m_errorReporter.declarationError( @@ -259,7 +259,7 @@ void AsmAnalyzer::operator()(VariableDeclaration const& _varDecl) if (_varDecl.value) { - std::vector types = std::visit(*this, *_varDecl.value); + std::vector types = std::visit(*this, *_varDecl.value); if (types.size() != numVariables) m_errorReporter.declarationError( 3812_error, @@ -275,7 +275,7 @@ void AsmAnalyzer::operator()(VariableDeclaration const& _varDecl) for (size_t i = 0; i < _varDecl.variables.size(); ++i) { - YulString givenType = m_dialect.defaultType; + YulName givenType = m_dialect.defaultType; if (i < types.size()) givenType = types[i]; TypedName const& variable = _varDecl.variables[i]; @@ -311,17 +311,17 @@ void AsmAnalyzer::operator()(FunctionDefinition const& _funDef) (*this)(_funDef.body); } -std::vector AsmAnalyzer::operator()(FunctionCall const& _funCall) +std::vector AsmAnalyzer::operator()(FunctionCall const& _funCall) { yulAssert(!_funCall.functionName.name.empty(), ""); auto watcher = m_errorReporter.errorWatcher(); - std::vector const* parameterTypes = nullptr; - std::vector const* returnTypes = nullptr; + std::vector const* parameterTypes = nullptr; + std::vector const* returnTypes = nullptr; std::vector> const* literalArguments = nullptr; if (BuiltinFunction const* f = m_dialect.builtin(_funCall.functionName.name)) { - if (_funCall.functionName.name == "selfdestruct"_yulstring) + if (_funCall.functionName.name == "selfdestruct"_yulname) m_errorReporter.warning( 1699_error, nativeLocationOf(_funCall.functionName), @@ -334,7 +334,7 @@ std::vector AsmAnalyzer::operator()(FunctionCall const& _funCall) ); else if ( m_evmVersion.supportsTransientStorage() && - _funCall.functionName.name == "tstore"_yulstring && + _funCall.functionName.name == "tstore"_yulname && !m_errorReporter.hasError({2394}) ) m_errorReporter.warning( @@ -400,7 +400,7 @@ std::vector AsmAnalyzer::operator()(FunctionCall const& _funCall) std::to_string(_funCall.arguments.size()) + "." ); - std::vector argTypes; + std::vector argTypes; for (size_t i = _funCall.arguments.size(); i > 0; i--) { Expression const& arg = _funCall.arguments[i - 1]; @@ -465,7 +465,7 @@ std::vector AsmAnalyzer::operator()(FunctionCall const& _funCall) return *returnTypes; } else if (returnTypes) - return std::vector(returnTypes->size(), m_dialect.defaultType); + return std::vector(returnTypes->size(), m_dialect.defaultType); else return {}; } @@ -488,7 +488,7 @@ void AsmAnalyzer::operator()(Switch const& _switch) "\"switch\" statement with only a default case." ); - YulString valueType = expectExpression(*_switch.expression); + YulName valueType = expectExpression(*_switch.expression); std::set cases; for (auto const& _case: _switch.cases) @@ -553,9 +553,9 @@ void AsmAnalyzer::operator()(Block const& _block) m_currentScope = previousScope; } -YulString AsmAnalyzer::expectExpression(Expression const& _expr) +YulName AsmAnalyzer::expectExpression(Expression const& _expr) { - std::vector types = std::visit(*this, _expr); + std::vector types = std::visit(*this, _expr); if (types.size() != 1) m_errorReporter.typeError( 3950_error, @@ -567,7 +567,7 @@ YulString AsmAnalyzer::expectExpression(Expression const& _expr) return types.empty() ? m_dialect.defaultType : types.front(); } -YulString AsmAnalyzer::expectUnlimitedStringLiteral(Literal const& _literal) +YulName AsmAnalyzer::expectUnlimitedStringLiteral(Literal const& _literal) { yulAssert(_literal.kind == LiteralKind::String); yulAssert(m_dialect.validTypeForLiteral(LiteralKind::String, _literal.value, _literal.type)); @@ -578,7 +578,7 @@ YulString AsmAnalyzer::expectUnlimitedStringLiteral(Literal const& _literal) void AsmAnalyzer::expectBoolExpression(Expression const& _expr) { - YulString type = expectExpression(_expr); + YulName type = expectExpression(_expr); if (type != m_dialect.boolType) m_errorReporter.typeError( 1733_error, @@ -591,11 +591,11 @@ void AsmAnalyzer::expectBoolExpression(Expression const& _expr) ); } -void AsmAnalyzer::checkAssignment(Identifier const& _variable, YulString _valueType) +void AsmAnalyzer::checkAssignment(Identifier const& _variable, YulName _valueType) { yulAssert(!_variable.name.empty(), ""); auto watcher = m_errorReporter.errorWatcher(); - YulString const* variableType = nullptr; + YulName const* variableType = nullptr; bool found = false; if (Scope::Identifier const* var = m_currentScope->lookup(_variable.name)) { @@ -654,7 +654,7 @@ Scope& AsmAnalyzer::scope(Block const* _block) return *scopePtr; } -void AsmAnalyzer::expectValidIdentifier(YulString _identifier, SourceLocation const& _location) +void AsmAnalyzer::expectValidIdentifier(YulName _identifier, SourceLocation const& _location) { // NOTE: the leading dot case is handled by the parser not allowing it. if (boost::ends_with(_identifier.str(), ".")) @@ -679,7 +679,7 @@ void AsmAnalyzer::expectValidIdentifier(YulString _identifier, SourceLocation co ); } -void AsmAnalyzer::expectValidType(YulString _type, SourceLocation const& _location) +void AsmAnalyzer::expectValidType(YulName _type, SourceLocation const& _location) { if (!m_dialect.types.count(_type)) m_errorReporter.typeError( @@ -689,7 +689,7 @@ void AsmAnalyzer::expectValidType(YulString _type, SourceLocation const& _locati ); } -void AsmAnalyzer::expectType(YulString _expectedType, YulString _givenType, SourceLocation const& _location) +void AsmAnalyzer::expectType(YulName _expectedType, YulName _givenType, SourceLocation const& _location) { if (_expectedType != _givenType) m_errorReporter.typeError( @@ -702,7 +702,7 @@ void AsmAnalyzer::expectType(YulString _expectedType, YulString _givenType, Sour bool AsmAnalyzer::validateInstructions(std::string const& _instructionIdentifier, langutil::SourceLocation const& _location) { // NOTE: This function uses the default EVM version instead of the currently selected one. - auto const builtin = EVMDialect::strictAssemblyForEVM(EVMVersion{}).builtin(YulString(_instructionIdentifier)); + auto const builtin = EVMDialect::strictAssemblyForEVM(EVMVersion{}).builtin(YulName(_instructionIdentifier)); if (builtin && builtin->instruction.has_value()) return validateInstructions(builtin->instruction.value(), _location); else diff --git a/libyul/AsmAnalysis.h b/libyul/AsmAnalysis.h index 9dd4b2292383..5aa7fe4968f6 100644 --- a/libyul/AsmAnalysis.h +++ b/libyul/AsmAnalysis.h @@ -79,13 +79,13 @@ class AsmAnalyzer /// Asserts on failure. static AsmAnalysisInfo analyzeStrictAssertCorrect(Dialect const& _dialect, Object const& _object); - std::vector operator()(Literal const& _literal); - std::vector operator()(Identifier const&); + std::vector operator()(Literal const& _literal); + std::vector operator()(Identifier const&); void operator()(ExpressionStatement const&); void operator()(Assignment const& _assignment); void operator()(VariableDeclaration const& _variableDeclaration); void operator()(FunctionDefinition const& _functionDefinition); - std::vector operator()(FunctionCall const& _functionCall); + std::vector operator()(FunctionCall const& _functionCall); void operator()(If const& _if); void operator()(Switch const& _switch); void operator()(ForLoop const& _forLoop); @@ -99,20 +99,20 @@ class AsmAnalyzer private: /// Visits the expression, expects that it evaluates to exactly one value and /// returns the type. Reports errors on errors and returns the default type. - YulString expectExpression(Expression const& _expr); - YulString expectUnlimitedStringLiteral(Literal const& _literal); + YulName expectExpression(Expression const& _expr); + YulName expectUnlimitedStringLiteral(Literal const& _literal); /// Visits the expression and expects it to return a single boolean value. /// Reports an error otherwise. void expectBoolExpression(Expression const& _expr); /// Verifies that a variable to be assigned to exists, can be assigned to /// and has the same type as the value. - void checkAssignment(Identifier const& _variable, YulString _valueType); + void checkAssignment(Identifier const& _variable, YulName _valueType); Scope& scope(Block const* _block); - void expectValidIdentifier(YulString _identifier, langutil::SourceLocation const& _location); - void expectValidType(YulString _type, langutil::SourceLocation const& _location); - void expectType(YulString _expectedType, YulString _givenType, langutil::SourceLocation const& _location); + void expectValidIdentifier(YulName _identifier, langutil::SourceLocation const& _location); + void expectValidType(YulName _type, langutil::SourceLocation const& _location); + void expectType(YulName _expectedType, YulName _givenType, langutil::SourceLocation const& _location); bool validateInstructions(evmasm::Instruction _instr, langutil::SourceLocation const& _location); bool validateInstructions(std::string const& _instrIdentifier, langutil::SourceLocation const& _location); diff --git a/libyul/AsmJsonImporter.cpp b/libyul/AsmJsonImporter.cpp index 63b1d65d26ec..8f211f31b435 100644 --- a/libyul/AsmJsonImporter.cpp +++ b/libyul/AsmJsonImporter.cpp @@ -72,8 +72,8 @@ Json AsmJsonImporter::member(Json const& _node, std::string const& _name) TypedName AsmJsonImporter::createTypedName(Json const& _node) { auto typedName = createAsmNode(_node); - typedName.type = YulString{member(_node, "type").get()}; - typedName.name = YulString{member(_node, "name").get()}; + typedName.type = YulName{member(_node, "type").get()}; + typedName.name = YulName{member(_node, "name").get()}; return typedName; } @@ -171,7 +171,7 @@ Literal AsmJsonImporter::createLiteral(Json const& _node) value = util::asString(util::fromHex(member(_node, "hexValue").get())); else value = member(_node, "value").get(); - lit.type = YulString{member(_node, "type").get()}; + lit.type = YulName{member(_node, "type").get()}; if (kind == "number") { langutil::CharStream charStream(value, ""); @@ -219,7 +219,7 @@ Leave AsmJsonImporter::createLeave(Json const& _node) Identifier AsmJsonImporter::createIdentifier(Json const& _node) { auto identifier = createAsmNode(_node); - identifier.name = YulString(member(_node, "name").get()); + identifier.name = YulName(member(_node, "name").get()); return identifier; } @@ -269,7 +269,7 @@ VariableDeclaration AsmJsonImporter::createVariableDeclaration(Json const& _node FunctionDefinition AsmJsonImporter::createFunctionDefinition(Json const& _node) { auto funcDef = createAsmNode(_node); - funcDef.name = YulString{member(_node, "name").get()}; + funcDef.name = YulName{member(_node, "name").get()}; if (_node.contains("parameters")) for (auto const& var: member(_node, "parameters")) diff --git a/libyul/AsmParser.cpp b/libyul/AsmParser.cpp index 2ae4dd805bc1..41bef57fe0f1 100644 --- a/libyul/AsmParser.cpp +++ b/libyul/AsmParser.cpp @@ -537,7 +537,7 @@ std::variant Parser::parseLiteralOrIdentifier(bool _unlimit { case Token::Identifier: { - Identifier identifier{createDebugData(), YulString{currentLiteral()}}; + Identifier identifier{createDebugData(), YulName{currentLiteral()}}; advance(); return identifier; } @@ -712,9 +712,9 @@ TypedName Parser::parseTypedName() return typedName; } -YulString Parser::expectAsmIdentifier() +YulName Parser::expectAsmIdentifier() { - YulString name{currentLiteral()}; + YulName name{currentLiteral()}; if (currentToken() == Token::Identifier && m_dialect.builtin(name)) fatalParserError(5568_error, "Cannot use builtin function name \"" + name.str() + "\" as identifier name."); // NOTE: We keep the expectation here to ensure the correct source location for the error above. diff --git a/libyul/AsmParser.h b/libyul/AsmParser.h index 3348904091f2..408c8029cf58 100644 --- a/libyul/AsmParser.h +++ b/libyul/AsmParser.h @@ -146,7 +146,7 @@ class Parser: public langutil::ParserBase FunctionDefinition parseFunctionDefinition(); FunctionCall parseCall(std::variant&& _initialOp); TypedName parseTypedName(); - YulString expectAsmIdentifier(); + YulName expectAsmIdentifier(); /// Reports an error if we are currently not inside the body part of a for loop. void checkBreakContinuePosition(std::string const& _which); diff --git a/libyul/AsmPrinter.cpp b/libyul/AsmPrinter.cpp index 191fc5d2d6a1..054f83a91398 100644 --- a/libyul/AsmPrinter.cpp +++ b/libyul/AsmPrinter.cpp @@ -243,7 +243,7 @@ std::string AsmPrinter::formatTypedName(TypedName _variable) return formatDebugData(_variable) + _variable.name.str() + appendTypeName(_variable.type); } -std::string AsmPrinter::appendTypeName(YulString _type, bool _isBoolLiteral) const +std::string AsmPrinter::appendTypeName(YulName _type, bool _isBoolLiteral) const { if (m_dialect && !_type.empty()) { diff --git a/libyul/AsmPrinter.h b/libyul/AsmPrinter.h index d3f80b9a09d5..36ea06c76769 100644 --- a/libyul/AsmPrinter.h +++ b/libyul/AsmPrinter.h @@ -24,7 +24,7 @@ #pragma once #include -#include +#include #include @@ -92,7 +92,7 @@ class AsmPrinter private: std::string formatTypedName(TypedName _variable); - std::string appendTypeName(YulString _type, bool _isBoolLiteral = false) const; + std::string appendTypeName(YulName _type, bool _isBoolLiteral = false) const; std::string formatDebugData(langutil::DebugData::ConstPtr const& _debugData, bool _statement); template std::string formatDebugData(T const& _node) diff --git a/libyul/CMakeLists.txt b/libyul/CMakeLists.txt index 92b03facfe93..ee78d525dfc7 100644 --- a/libyul/CMakeLists.txt +++ b/libyul/CMakeLists.txt @@ -37,6 +37,7 @@ add_library(yul ScopeFiller.h Utilities.cpp Utilities.h + YulName.h YulString.h backends/evm/AbstractAssembly.h backends/evm/AsmCodeGen.cpp diff --git a/libyul/CompilabilityChecker.h b/libyul/CompilabilityChecker.h index c046df94ffb9..89bb7aa7c993 100644 --- a/libyul/CompilabilityChecker.h +++ b/libyul/CompilabilityChecker.h @@ -45,8 +45,8 @@ namespace solidity::yul struct CompilabilityChecker { CompilabilityChecker(Dialect const& _dialect, Object const& _object, bool _optimizeStackAllocation); - std::map> unreachableVariables; - std::map stackDeficit; + std::map> unreachableVariables; + std::map stackDeficit; }; } diff --git a/libyul/ControlFlowSideEffectsCollector.cpp b/libyul/ControlFlowSideEffectsCollector.cpp index c657fa17cba2..471a164e523b 100644 --- a/libyul/ControlFlowSideEffectsCollector.cpp +++ b/libyul/ControlFlowSideEffectsCollector.cpp @@ -229,9 +229,9 @@ ControlFlowSideEffectsCollector::ControlFlowSideEffectsCollector( } } -std::map ControlFlowSideEffectsCollector::functionSideEffectsNamed() const +std::map ControlFlowSideEffectsCollector::functionSideEffectsNamed() const { - std::map result; + std::map result; for (auto&& [function, sideEffects]: m_functionSideEffects) yulAssert(result.insert({function->name, sideEffects}).second); return result; diff --git a/libyul/ControlFlowSideEffectsCollector.h b/libyul/ControlFlowSideEffectsCollector.h index a4ab2bfae770..5a1c76297012 100644 --- a/libyul/ControlFlowSideEffectsCollector.h +++ b/libyul/ControlFlowSideEffectsCollector.h @@ -101,7 +101,7 @@ class ControlFlowSideEffectsCollector return m_functionSideEffects; } /// Returns the side effects by function name, requires unique function names. - std::map functionSideEffectsNamed() const; + std::map functionSideEffectsNamed() const; private: /// @returns false if nothing could be processed. diff --git a/libyul/Dialect.cpp b/libyul/Dialect.cpp index 69ca1e9dc68d..f4f59ec26aa7 100644 --- a/libyul/Dialect.cpp +++ b/libyul/Dialect.cpp @@ -25,7 +25,7 @@ using namespace solidity::yul; using namespace solidity::langutil; -Literal Dialect::zeroLiteralForType(solidity::yul::YulString _type) const +Literal Dialect::zeroLiteralForType(solidity::yul::YulName _type) const { if (_type == boolType && _type != defaultType) return {DebugData::create(), LiteralKind::Boolean, LiteralValue(false), _type}; @@ -41,7 +41,7 @@ Literal Dialect::trueLiteral() const return {DebugData::create(), LiteralKind::Number, LiteralValue(1), defaultType}; } -bool Dialect::validTypeForLiteral(LiteralKind _kind, LiteralValue const&, YulString _type) const +bool Dialect::validTypeForLiteral(LiteralKind _kind, LiteralValue const&, YulName _type) const { if (_kind == LiteralKind::Boolean) return _type == boolType; @@ -58,21 +58,20 @@ Dialect const& Dialect::yulDeprecated() { // TODO will probably change, especially the list of types. dialect = std::make_unique(); - dialect->defaultType = "u256"_yulstring; - dialect->boolType = "bool"_yulstring; + dialect->defaultType = "u256"_yulname; + dialect->boolType = "bool"_yulname; dialect->types = { - "bool"_yulstring, - "u8"_yulstring, - "s8"_yulstring, - "u32"_yulstring, - "s32"_yulstring, - "u64"_yulstring, - "s64"_yulstring, - "u128"_yulstring, - "s128"_yulstring, - "u256"_yulstring, - "s256"_yulstring - }; + "bool"_yulname, + "u8"_yulname, + "s8"_yulname, + "u32"_yulname, + "s32"_yulname, + "u64"_yulname, + "s64"_yulname, + "u128"_yulname, + "s128"_yulname, + "u256"_yulname, + "s256"_yulname}; }; return *dialect; diff --git a/libyul/Dialect.h b/libyul/Dialect.h index e3f270357f91..3362246a063a 100644 --- a/libyul/Dialect.h +++ b/libyul/Dialect.h @@ -21,7 +21,7 @@ #pragma once -#include +#include #include #include @@ -32,15 +32,14 @@ namespace solidity::yul { -class YulString; -using Type = YulString; +using Type = YulName; enum class LiteralKind; class LiteralValue; struct Literal; struct BuiltinFunction { - YulString name; + YulName name; std::vector parameters; std::vector returns; SideEffects sideEffects; @@ -63,35 +62,35 @@ struct Dialect Dialect& operator=(Dialect const&) = delete; /// Default type, can be omitted. - YulString defaultType; + YulName defaultType; /// Type used for the literals "true" and "false". - YulString boolType; - std::set types = {{}}; + YulName boolType; + std::set types = {{}}; /// @returns the builtin function of the given name or a nullptr if it is not a builtin function. - virtual BuiltinFunction const* builtin(YulString /*_name*/) const { return nullptr; } + virtual BuiltinFunction const* builtin(YulName /*_name*/) const { return nullptr; } /// @returns true if the identifier is reserved. This includes the builtins too. - virtual bool reservedIdentifier(YulString _name) const { return builtin(_name) != nullptr; } + virtual bool reservedIdentifier(YulName _name) const { return builtin(_name) != nullptr; } - virtual BuiltinFunction const* discardFunction(YulString /* _type */) const { return nullptr; } - virtual BuiltinFunction const* equalityFunction(YulString /* _type */) const { return nullptr; } + virtual BuiltinFunction const* discardFunction(YulName /* _type */) const { return nullptr; } + virtual BuiltinFunction const* equalityFunction(YulName /* _type */) const { return nullptr; } virtual BuiltinFunction const* booleanNegationFunction() const { return nullptr; } - virtual BuiltinFunction const* memoryStoreFunction(YulString /* _type */) const { return nullptr; } - virtual BuiltinFunction const* memoryLoadFunction(YulString /* _type */) const { return nullptr; } - virtual BuiltinFunction const* storageStoreFunction(YulString /* _type */) const { return nullptr; } - virtual BuiltinFunction const* storageLoadFunction(YulString /* _type */) const { return nullptr; } - virtual YulString hashFunction(YulString /* _type */ ) const { return YulString{}; } + virtual BuiltinFunction const* memoryStoreFunction(YulName /* _type */) const { return nullptr; } + virtual BuiltinFunction const* memoryLoadFunction(YulName /* _type */) const { return nullptr; } + virtual BuiltinFunction const* storageStoreFunction(YulName /* _type */) const { return nullptr; } + virtual BuiltinFunction const* storageLoadFunction(YulName /* _type */) const { return nullptr; } + virtual YulName hashFunction(YulName /* _type */ ) const { return YulName{}; } /// Check whether the given type is legal for the given literal value. /// Should only be called if the type exists in the dialect at all. - virtual bool validTypeForLiteral(LiteralKind _kind, LiteralValue const& _value, YulString _type) const; + virtual bool validTypeForLiteral(LiteralKind _kind, LiteralValue const& _value, YulName _type) const; - virtual Literal zeroLiteralForType(YulString _type) const; + virtual Literal zeroLiteralForType(YulName _type) const; virtual Literal trueLiteral() const; - virtual std::set fixedFunctionNames() const { return {}; } + virtual std::set fixedFunctionNames() const { return {}; } Dialect() = default; virtual ~Dialect() = default; diff --git a/libyul/Exceptions.h b/libyul/Exceptions.h index 45c681a5d6e5..f92268180971 100644 --- a/libyul/Exceptions.h +++ b/libyul/Exceptions.h @@ -24,7 +24,7 @@ #include #include -#include +#include #include #include @@ -40,18 +40,18 @@ struct YulAssertion: virtual YulException {}; struct StackTooDeepError: virtual YulException { - StackTooDeepError(YulString _variable, int _depth, std::string const& _message): + StackTooDeepError(YulName _variable, int _depth, std::string const& _message): variable(_variable), depth(_depth) { *this << util::errinfo_comment(_message); } - StackTooDeepError(YulString _functionName, YulString _variable, int _depth, std::string const& _message): + StackTooDeepError(YulName _functionName, YulName _variable, int _depth, std::string const& _message): functionName(_functionName), variable(_variable), depth(_depth) { *this << util::errinfo_comment(_message); } - YulString functionName; - YulString variable; + YulName functionName; + YulName variable; int depth; }; diff --git a/libyul/FunctionReferenceResolver.h b/libyul/FunctionReferenceResolver.h index 8c1385adb6c7..dcc5f50e5b76 100644 --- a/libyul/FunctionReferenceResolver.h +++ b/libyul/FunctionReferenceResolver.h @@ -41,7 +41,7 @@ class FunctionReferenceResolver: private ASTWalker void operator()(Block const& _block) override; std::map m_functionReferences; - std::vector> m_scopes; + std::vector> m_scopes; }; diff --git a/libyul/Object.h b/libyul/Object.h index c1ca9244d98d..af354005b66b 100644 --- a/libyul/Object.h +++ b/libyul/Object.h @@ -22,7 +22,6 @@ #pragma once #include -#include #include #include diff --git a/libyul/ObjectParser.h b/libyul/ObjectParser.h index 08a852991203..a8f75d373c9b 100644 --- a/libyul/ObjectParser.h +++ b/libyul/ObjectParser.h @@ -21,7 +21,6 @@ #pragma once -#include #include #include diff --git a/libyul/Scope.cpp b/libyul/Scope.cpp index 4471aa53130d..89bdfc674c56 100644 --- a/libyul/Scope.cpp +++ b/libyul/Scope.cpp @@ -25,7 +25,7 @@ using namespace solidity; using namespace solidity::yul; using namespace solidity::util; -bool Scope::registerVariable(YulString _name, YulType const& _type) +bool Scope::registerVariable(YulName _name, YulType const& _type) { if (exists(_name)) return false; @@ -36,7 +36,7 @@ bool Scope::registerVariable(YulString _name, YulType const& _type) return true; } -bool Scope::registerFunction(YulString _name, std::vector _arguments, std::vector _returns) +bool Scope::registerFunction(YulName _name, std::vector _arguments, std::vector _returns) { if (exists(_name)) return false; @@ -44,7 +44,7 @@ bool Scope::registerFunction(YulString _name, std::vector _arguments, s return true; } -Scope::Identifier* Scope::lookup(YulString _name) +Scope::Identifier* Scope::lookup(YulName _name) { bool crossedFunctionBoundary = false; for (Scope* s = this; s; s = s->superScope) @@ -64,7 +64,7 @@ Scope::Identifier* Scope::lookup(YulString _name) return nullptr; } -bool Scope::exists(YulString _name) const +bool Scope::exists(YulName _name) const { if (identifiers.count(_name)) return true; diff --git a/libyul/Scope.h b/libyul/Scope.h index f9ac3830a295..027597290063 100644 --- a/libyul/Scope.h +++ b/libyul/Scope.h @@ -23,7 +23,7 @@ #include -#include +#include #include #include @@ -35,25 +35,25 @@ namespace solidity::yul struct Scope { - using YulType = YulString; + using YulType = YulName; struct Variable { YulType type; - YulString name; + YulName name; }; struct Function { std::vector arguments; std::vector returns; - YulString name; + YulName name; }; using Identifier = std::variant; - bool registerVariable(YulString _name, YulType const& _type); + bool registerVariable(YulName _name, YulType const& _type); bool registerFunction( - YulString _name, + YulName _name, std::vector _arguments, std::vector _returns ); @@ -63,12 +63,12 @@ struct Scope /// will any lookups across assembly boundaries. /// The pointer will be invalidated if the scope is modified. /// @param _crossedFunction if true, we already crossed a function boundary during recursive lookup - Identifier* lookup(YulString _name); + Identifier* lookup(YulName _name); /// Looks up the identifier in this and super scopes (will not find variables across function /// boundaries and generally stops at assembly boundaries) and calls the visitor, returns /// false if not found. template - bool lookup(YulString _name, V const& _visitor) + bool lookup(YulName _name, V const& _visitor) { if (Identifier* id = lookup(_name)) { @@ -80,7 +80,7 @@ struct Scope } /// @returns true if the name exists in this scope or in super scopes (also searches /// across function and assembly boundaries). - bool exists(YulString _name) const; + bool exists(YulName _name) const; /// @returns the number of variables directly registered inside the scope. size_t numberOfVariables() const; @@ -91,7 +91,7 @@ struct Scope /// If true, variables from the super scope are not visible here (other identifiers are), /// but they are still taken into account to prevent shadowing. bool functionScope = false; - std::map identifiers; + std::map identifiers; }; } diff --git a/libyul/YulName.h b/libyul/YulName.h new file mode 100644 index 000000000000..34fd6a5a26b0 --- /dev/null +++ b/libyul/YulName.h @@ -0,0 +1,26 @@ +/* + 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 +{ +using YulName = YulString; +} diff --git a/libyul/YulString.h b/libyul/YulString.h index 7dbaf1b84a03..89d35b123cab 100644 --- a/libyul/YulString.h +++ b/libyul/YulString.h @@ -162,7 +162,7 @@ class YulString YulStringRepository::Handle m_handle{ 0, YulStringRepository::emptyHash() }; }; -inline YulString operator "" _yulstring(char const* _string, std::size_t _size) +inline YulString operator "" _yulname(char const* _string, std::size_t _size) { return YulString(std::string(_string, _size)); } diff --git a/libyul/backends/evm/ConstantOptimiser.cpp b/libyul/backends/evm/ConstantOptimiser.cpp index 7b17f7d89012..2ab77f84e92d 100644 --- a/libyul/backends/evm/ConstantOptimiser.cpp +++ b/libyul/backends/evm/ConstantOptimiser.cpp @@ -129,7 +129,7 @@ Representation const& RepresentationFinder::findRepresentation(u256 const& _valu if (numberEncodingSize(~_value) < numberEncodingSize(_value)) // Negated is shorter to represent - routine = min(std::move(routine), represent("not"_yulstring, findRepresentation(~_value))); + routine = min(std::move(routine), represent("not"_yulname, findRepresentation(~_value))); // Decompose value into a * 2**k + b where abs(b) << 2**k for (unsigned bits = 255; bits > 8 && m_maxSteps > 0; --bits) @@ -152,21 +152,21 @@ Representation const& RepresentationFinder::findRepresentation(u256 const& _valu continue; Representation newRoutine; if (m_dialect.evmVersion().hasBitwiseShifting()) - newRoutine = represent("shl"_yulstring, represent(bits), findRepresentation(upperPart)); + newRoutine = represent("shl"_yulname, represent(bits), findRepresentation(upperPart)); else { - newRoutine = represent("exp"_yulstring, represent(2), represent(bits)); + newRoutine = represent("exp"_yulname, represent(2), represent(bits)); if (upperPart != 1) - newRoutine = represent("mul"_yulstring, findRepresentation(upperPart), newRoutine); + newRoutine = represent("mul"_yulname, findRepresentation(upperPart), newRoutine); } if (newRoutine.cost >= routine.cost) continue; if (lowerPart > 0) - newRoutine = represent("add"_yulstring, newRoutine, findRepresentation(u256(abs(lowerPart)))); + newRoutine = represent("add"_yulname, newRoutine, findRepresentation(u256(abs(lowerPart)))); else if (lowerPart < 0) - newRoutine = represent("sub"_yulstring, newRoutine, findRepresentation(u256(abs(lowerPart)))); + newRoutine = represent("sub"_yulname, newRoutine, findRepresentation(u256(abs(lowerPart)))); if (m_maxSteps > 0) m_maxSteps--; @@ -185,7 +185,7 @@ Representation RepresentationFinder::represent(u256 const& _value) const } Representation RepresentationFinder::represent( - YulString _instruction, + YulName _instruction, Representation const& _argument ) const { @@ -200,7 +200,7 @@ Representation RepresentationFinder::represent( } Representation RepresentationFinder::represent( - YulString _instruction, + YulName _instruction, Representation const& _arg1, Representation const& _arg2 ) const diff --git a/libyul/backends/evm/ConstantOptimiser.h b/libyul/backends/evm/ConstantOptimiser.h index 280f50bf9b97..35d7dfa43254 100644 --- a/libyul/backends/evm/ConstantOptimiser.h +++ b/libyul/backends/evm/ConstantOptimiser.h @@ -22,7 +22,7 @@ #pragma once #include -#include +#include #include #include #include @@ -93,8 +93,8 @@ class RepresentationFinder Representation const& findRepresentation(u256 const& _value); Representation represent(u256 const& _value) const; - Representation represent(YulString _instruction, Representation const& _arg) const; - Representation represent(YulString _instruction, Representation const& _arg1, Representation const& _arg2) const; + Representation represent(YulName _instruction, Representation const& _arg) const; + Representation represent(YulName _instruction, Representation const& _arg1, Representation const& _arg2) const; Representation min(Representation _a, Representation _b); diff --git a/libyul/backends/evm/ControlFlowGraphBuilder.cpp b/libyul/backends/evm/ControlFlowGraphBuilder.cpp index a5e9613b5887..b4d1cdf15c3a 100644 --- a/libyul/backends/evm/ControlFlowGraphBuilder.cpp +++ b/libyul/backends/evm/ControlFlowGraphBuilder.cpp @@ -336,8 +336,8 @@ void ControlFlowGraphBuilder::operator()(Switch const& _switch) langutil::DebugData::ConstPtr preSwitchDebugData = debugDataOf(_switch); auto ghostVariableId = m_graph.ghostVariables.size(); - YulString ghostVariableName("GHOST[" + std::to_string(ghostVariableId) + "]"); - auto& ghostVar = m_graph.ghostVariables.emplace_back(Scope::Variable{""_yulstring, ghostVariableName}); + YulName ghostVariableName("GHOST[" + std::to_string(ghostVariableId) + "]"); + auto& ghostVar = m_graph.ghostVariables.emplace_back(Scope::Variable{""_yulname, ghostVariableName}); // Artificially generate: // let := @@ -357,7 +357,7 @@ void ControlFlowGraphBuilder::operator()(Switch const& _switch) auto makeValueCompare = [&](Case const& _case) { yul::FunctionCall const& ghostCall = m_graph.ghostCalls.emplace_back(yul::FunctionCall{ debugDataOf(_case), - yul::Identifier{{}, "eq"_yulstring}, + yul::Identifier{{}, "eq"_yulname}, {*_case.value, Identifier{{}, ghostVariableName}} }); CFG::Operation& operation = m_currentBlock->operations.emplace_back(CFG::Operation{ @@ -578,7 +578,7 @@ Stack ControlFlowGraphBuilder::visitAssignmentRightHandSide(Expression const& _e }, _expression); } -Scope::Function const& ControlFlowGraphBuilder::lookupFunction(YulString _name) const +Scope::Function const& ControlFlowGraphBuilder::lookupFunction(YulName _name) const { Scope::Function const* function = nullptr; yulAssert(m_scope->lookup(_name, util::GenericVisitor{ @@ -589,7 +589,7 @@ Scope::Function const& ControlFlowGraphBuilder::lookupFunction(YulString _name) return *function; } -Scope::Variable const& ControlFlowGraphBuilder::lookupVariable(YulString _name) const +Scope::Variable const& ControlFlowGraphBuilder::lookupVariable(YulName _name) const { yulAssert(m_scope, ""); Scope::Variable const* var = nullptr; diff --git a/libyul/backends/evm/ControlFlowGraphBuilder.h b/libyul/backends/evm/ControlFlowGraphBuilder.h index 5007d361089b..77feaea7b469 100644 --- a/libyul/backends/evm/ControlFlowGraphBuilder.h +++ b/libyul/backends/evm/ControlFlowGraphBuilder.h @@ -63,8 +63,8 @@ class ControlFlowGraphBuilder Stack const& visitFunctionCall(FunctionCall const&); Stack visitAssignmentRightHandSide(Expression const& _expression, size_t _expectedSlotCount); - Scope::Function const& lookupFunction(YulString _name) const; - Scope::Variable const& lookupVariable(YulString _name) const; + Scope::Function const& lookupFunction(YulName _name) const; + Scope::Variable const& lookupVariable(YulName _name) const; /// Resets m_currentBlock to enforce a subsequent explicit reassignment. void makeConditionalJump( langutil::DebugData::ConstPtr _debugData, diff --git a/libyul/backends/evm/EVMCodeTransform.cpp b/libyul/backends/evm/EVMCodeTransform.cpp index bdce395ef89f..21124723003b 100644 --- a/libyul/backends/evm/EVMCodeTransform.cpp +++ b/libyul/backends/evm/EVMCodeTransform.cpp @@ -79,7 +79,7 @@ CodeTransform::CodeTransform( } } -void CodeTransform::decreaseReference(YulString, Scope::Variable const& _var) +void CodeTransform::decreaseReference(YulName, Scope::Variable const& _var) { if (!m_allowStackOpt) return; @@ -158,7 +158,7 @@ void CodeTransform::operator()(VariableDeclaration const& _varDecl) for (size_t varIndex = 0; varIndex < numVariables; ++varIndex) { size_t varIndexReverse = numVariables - 1 - varIndex; - YulString varName = _varDecl.variables[varIndexReverse].name; + YulName varName = _varDecl.variables[varIndexReverse].name; auto& var = std::get(m_scope->identifiers.at(varName)); m_context->variableStackHeights[&var] = heightAtStart + varIndexReverse; if (!m_allowStackOpt) @@ -457,7 +457,7 @@ void CodeTransform::operator()(FunctionDefinition const& _function) { StackTooDeepError error( _function.name, - YulString{}, + YulName{}, static_cast(stackLayout.size()) - 17, "The function " + _function.name.str() + @@ -667,7 +667,7 @@ bool statementNeedsReturnVariableSetup(Statement const& _statement, std::vector< std::holds_alternative(_statement) ) { - std::map references = VariableReferencesCounter::countReferences(_statement); + std::map references = VariableReferencesCounter::countReferences(_statement); auto isReferenced = [&references](TypedName const& _returnVariable) { return references.count(_returnVariable.name); }; @@ -771,7 +771,7 @@ void CodeTransform::generateAssignment(Identifier const& _variableName) } } -size_t CodeTransform::variableHeightDiff(Scope::Variable const& _var, YulString _varName, bool _forSwap) +size_t CodeTransform::variableHeightDiff(Scope::Variable const& _var, YulName _varName, bool _forSwap) { yulAssert(m_context->variableStackHeights.count(&_var), ""); size_t heightDiff = static_cast(m_assembly.stackHeight()) - m_context->variableStackHeights[&_var]; @@ -795,7 +795,7 @@ size_t CodeTransform::variableHeightDiff(Scope::Variable const& _var, YulString return heightDiff; } -int CodeTransform::variableStackHeight(YulString _name) const +int CodeTransform::variableStackHeight(YulName _name) const { Scope::Variable const* var = std::get_if(m_scope->lookup(_name)); yulAssert(var, ""); diff --git a/libyul/backends/evm/EVMCodeTransform.h b/libyul/backends/evm/EVMCodeTransform.h index bad9a357ff29..0e6a9d8be1db 100644 --- a/libyul/backends/evm/EVMCodeTransform.h +++ b/libyul/backends/evm/EVMCodeTransform.h @@ -118,7 +118,7 @@ class CodeTransform std::optional _functionExitLabel ); - void decreaseReference(YulString _name, Scope::Variable const& _var); + void decreaseReference(YulName _name, Scope::Variable const& _var); bool unreferenced(Scope::Variable const& _var) const; /// Marks slots of variables that are not used anymore /// and were defined in the current scope for reuse. @@ -165,10 +165,10 @@ class CodeTransform /// the (positive) stack height difference otherwise. /// @param _forSwap if true, produces stack error if the difference is invalid for a swap /// opcode, otherwise checks for validity for a dup opcode. - size_t variableHeightDiff(Scope::Variable const& _var, YulString _name, bool _forSwap); + size_t variableHeightDiff(Scope::Variable const& _var, YulName _name, bool _forSwap); /// Determines the stack height of the given variable. Throws if the variable is not in scope. - int variableStackHeight(YulString _name) const; + int variableStackHeight(YulName _name) const; void expectDeposit(int _deposit, int _oldHeight) const; @@ -198,7 +198,7 @@ class CodeTransform BuiltinContext& m_builtinContext; bool const m_allowStackOpt = true; UseNamedLabels const m_useNamedLabelsForFunctions = UseNamedLabels::Never; - std::set m_assignedNamedLabels; + std::set m_assignedNamedLabels; ExternalIdentifierAccess::CodeGenerator m_identifierAccessCodeGen; std::shared_ptr m_context; diff --git a/libyul/backends/evm/EVMDialect.cpp b/libyul/backends/evm/EVMDialect.cpp index d3b9c34bcb5a..50ede8c760f0 100644 --- a/libyul/backends/evm/EVMDialect.cpp +++ b/libyul/backends/evm/EVMDialect.cpp @@ -46,7 +46,7 @@ using namespace solidity::util; namespace { -std::pair createEVMFunction( +std::pair createEVMFunction( langutil::EVMVersion _evmVersion, std::string const& _name, evmasm::Instruction _instruction @@ -54,7 +54,7 @@ std::pair createEVMFunction( { evmasm::InstructionInfo info = evmasm::instructionInfo(_instruction, _evmVersion); BuiltinFunctionForEVM f; - f.name = YulString{_name}; + f.name = YulName{_name}; f.parameters.resize(static_cast(info.args)); f.returns.resize(static_cast(info.ret)); f.sideEffects = EVMDialect::sideEffectsOfInstruction(_instruction); @@ -83,11 +83,11 @@ std::pair createEVMFunction( _assembly.appendInstruction(_instruction); }; - YulString name = f.name; + YulName name = f.name; return {name, std::move(f)}; } -std::pair createFunction( +std::pair createFunction( std::string _name, size_t _params, size_t _returns, @@ -98,7 +98,7 @@ std::pair createFunction( { yulAssert(_literalArguments.size() == _params || _literalArguments.empty(), ""); - YulString name{std::move(_name)}; + YulName name{std::move(_name)}; BuiltinFunctionForEVM f; f.name = name; f.parameters.resize(_params); @@ -111,7 +111,7 @@ std::pair createFunction( return {name, f}; } -std::set createReservedIdentifiers(langutil::EVMVersion _evmVersion) +std::set createReservedIdentifiers(langutil::EVMVersion _evmVersion) { // TODO remove this in 0.9.0. We allow creating functions or identifiers in Yul with the name // basefee for VMs before london. @@ -157,7 +157,7 @@ std::set createReservedIdentifiers(langutil::EVMVersion _evmVersion) (_instr == evmasm::Instruction::TSTORE || _instr == evmasm::Instruction::TLOAD); }; - std::set reserved; + std::set reserved; for (auto const& instr: evmasm::c_instructions) { std::string name = toLower(instr.first); @@ -171,18 +171,18 @@ std::set createReservedIdentifiers(langutil::EVMVersion _evmVersion) ) reserved.emplace(name); } - reserved += std::vector{ - "linkersymbol"_yulstring, - "datasize"_yulstring, - "dataoffset"_yulstring, - "datacopy"_yulstring, - "setimmutable"_yulstring, - "loadimmutable"_yulstring, + reserved += std::vector{ + "linkersymbol"_yulname, + "datasize"_yulname, + "dataoffset"_yulname, + "datacopy"_yulname, + "setimmutable"_yulname, + "loadimmutable"_yulname, }; return reserved; } -std::map createBuiltins(langutil::EVMVersion _evmVersion, bool _objectAccess) +std::map createBuiltins(langutil::EVMVersion _evmVersion, bool _objectAccess) { // Exclude prevrandao as builtin for VMs before paris and difficulty for VMs after paris. @@ -191,7 +191,7 @@ std::map createBuiltins(langutil::EVMVersion _ return (_instrName == "prevrandao" && _evmVersion < langutil::EVMVersion::paris()) || (_instrName == "difficulty" && _evmVersion >= langutil::EVMVersion::paris()); }; - std::map builtins; + std::map builtins; for (auto const& instr: evmasm::c_instructions) { std::string name = toLower(instr.first); @@ -248,7 +248,7 @@ std::map createBuiltins(langutil::EVMVersion _ yulAssert(_context.currentObject, "No object available."); yulAssert(_call.arguments.size() == 1, ""); Expression const& arg = _call.arguments.front(); - YulString const dataName (formatLiteral(std::get(arg))); + YulName const dataName (formatLiteral(std::get(arg))); if (_context.currentObject->name == dataName.str()) _assembly.appendAssemblySize(); else @@ -269,7 +269,7 @@ std::map createBuiltins(langutil::EVMVersion _ yulAssert(_context.currentObject, "No object available."); yulAssert(_call.arguments.size() == 1, ""); Expression const& arg = _call.arguments.front(); - YulString const dataName (formatLiteral(std::get(arg))); + YulName const dataName (formatLiteral(std::get(arg))); if (_context.currentObject->name == dataName.str()) _assembly.appendConstant(0); else @@ -368,7 +368,7 @@ EVMDialect::EVMDialect(langutil::EVMVersion _evmVersion, bool _objectAccess): { } -BuiltinFunctionForEVM const* EVMDialect::builtin(YulString _name) const +BuiltinFunctionForEVM const* EVMDialect::builtin(YulName _name) const { if (m_objectAccess) { @@ -383,7 +383,7 @@ BuiltinFunctionForEVM const* EVMDialect::builtin(YulString _name) const return nullptr; } -bool EVMDialect::reservedIdentifier(YulString _name) const +bool EVMDialect::reservedIdentifier(YulName _name) const { if (m_objectAccess) if (_name.str().substr(0, "verbatim"s.size()) == "verbatim") @@ -465,8 +465,8 @@ BuiltinFunctionForEVM const* EVMDialect::verbatimFunction(size_t _arguments, siz EVMDialectTyped::EVMDialectTyped(langutil::EVMVersion _evmVersion, bool _objectAccess): EVMDialect(_evmVersion, _objectAccess) { - defaultType = "u256"_yulstring; - boolType = "bool"_yulstring; + defaultType = "u256"_yulname; + boolType = "bool"_yulname; types = {defaultType, boolType}; // Set all types to ``defaultType`` @@ -478,43 +478,43 @@ EVMDialectTyped::EVMDialectTyped(langutil::EVMVersion _evmVersion, bool _objectA r = defaultType; } - m_functions["lt"_yulstring].returns = {"bool"_yulstring}; - m_functions["gt"_yulstring].returns = {"bool"_yulstring}; - m_functions["slt"_yulstring].returns = {"bool"_yulstring}; - m_functions["sgt"_yulstring].returns = {"bool"_yulstring}; - m_functions["eq"_yulstring].returns = {"bool"_yulstring}; + m_functions["lt"_yulname].returns = {"bool"_yulname}; + m_functions["gt"_yulname].returns = {"bool"_yulname}; + m_functions["slt"_yulname].returns = {"bool"_yulname}; + m_functions["sgt"_yulname].returns = {"bool"_yulname}; + m_functions["eq"_yulname].returns = {"bool"_yulname}; // "not" and "bitnot" replace "iszero" and "not" - m_functions["bitnot"_yulstring] = m_functions["not"_yulstring]; - m_functions["bitnot"_yulstring].name = "bitnot"_yulstring; - m_functions["not"_yulstring] = m_functions["iszero"_yulstring]; - m_functions["not"_yulstring].name = "not"_yulstring; - m_functions["not"_yulstring].returns = {"bool"_yulstring}; - m_functions["not"_yulstring].parameters = {"bool"_yulstring}; - m_functions.erase("iszero"_yulstring); - - m_functions["bitand"_yulstring] = m_functions["and"_yulstring]; - m_functions["bitand"_yulstring].name = "bitand"_yulstring; - m_functions["bitor"_yulstring] = m_functions["or"_yulstring]; - m_functions["bitor"_yulstring].name = "bitor"_yulstring; - m_functions["bitxor"_yulstring] = m_functions["xor"_yulstring]; - m_functions["bitxor"_yulstring].name = "bitxor"_yulstring; - m_functions["and"_yulstring].parameters = {"bool"_yulstring, "bool"_yulstring}; - m_functions["and"_yulstring].returns = {"bool"_yulstring}; - m_functions["or"_yulstring].parameters = {"bool"_yulstring, "bool"_yulstring}; - m_functions["or"_yulstring].returns = {"bool"_yulstring}; - m_functions["xor"_yulstring].parameters = {"bool"_yulstring, "bool"_yulstring}; - m_functions["xor"_yulstring].returns = {"bool"_yulstring}; - m_functions["popbool"_yulstring] = m_functions["pop"_yulstring]; - m_functions["popbool"_yulstring].name = "popbool"_yulstring; - m_functions["popbool"_yulstring].parameters = {"bool"_yulstring}; + m_functions["bitnot"_yulname] = m_functions["not"_yulname]; + m_functions["bitnot"_yulname].name = "bitnot"_yulname; + m_functions["not"_yulname] = m_functions["iszero"_yulname]; + m_functions["not"_yulname].name = "not"_yulname; + m_functions["not"_yulname].returns = {"bool"_yulname}; + m_functions["not"_yulname].parameters = {"bool"_yulname}; + m_functions.erase("iszero"_yulname); + + m_functions["bitand"_yulname] = m_functions["and"_yulname]; + m_functions["bitand"_yulname].name = "bitand"_yulname; + m_functions["bitor"_yulname] = m_functions["or"_yulname]; + m_functions["bitor"_yulname].name = "bitor"_yulname; + m_functions["bitxor"_yulname] = m_functions["xor"_yulname]; + m_functions["bitxor"_yulname].name = "bitxor"_yulname; + m_functions["and"_yulname].parameters = {"bool"_yulname, "bool"_yulname}; + m_functions["and"_yulname].returns = {"bool"_yulname}; + m_functions["or"_yulname].parameters = {"bool"_yulname, "bool"_yulname}; + m_functions["or"_yulname].returns = {"bool"_yulname}; + m_functions["xor"_yulname].parameters = {"bool"_yulname, "bool"_yulname}; + m_functions["xor"_yulname].returns = {"bool"_yulname}; + m_functions["popbool"_yulname] = m_functions["pop"_yulname]; + m_functions["popbool"_yulname].name = "popbool"_yulname; + m_functions["popbool"_yulname].parameters = {"bool"_yulname}; m_functions.insert(createFunction("bool_to_u256", 1, 1, {}, {}, []( FunctionCall const&, AbstractAssembly&, BuiltinContext& ) {})); - m_functions["bool_to_u256"_yulstring].parameters = {"bool"_yulstring}; - m_functions["bool_to_u256"_yulstring].returns = {"u256"_yulstring}; + m_functions["bool_to_u256"_yulname].parameters = {"bool"_yulname}; + m_functions["bool_to_u256"_yulname].returns = {"u256"_yulname}; m_functions.insert(createFunction("u256_to_bool", 1, 1, {}, {}, []( FunctionCall const&, AbstractAssembly& _assembly, @@ -530,29 +530,29 @@ EVMDialectTyped::EVMDialectTyped(langutil::EVMVersion _evmVersion, bool _objectA _assembly.appendInstruction(evmasm::Instruction::INVALID); _assembly.appendLabel(inRange); })); - m_functions["u256_to_bool"_yulstring].parameters = {"u256"_yulstring}; - m_functions["u256_to_bool"_yulstring].returns = {"bool"_yulstring}; + m_functions["u256_to_bool"_yulname].parameters = {"u256"_yulname}; + m_functions["u256_to_bool"_yulname].returns = {"bool"_yulname}; } -BuiltinFunctionForEVM const* EVMDialectTyped::discardFunction(YulString _type) const +BuiltinFunctionForEVM const* EVMDialectTyped::discardFunction(YulName _type) const { - if (_type == "bool"_yulstring) - return builtin("popbool"_yulstring); + if (_type == "bool"_yulname) + return builtin("popbool"_yulname); else { yulAssert(_type == defaultType, ""); - return builtin("pop"_yulstring); + return builtin("pop"_yulname); } } -BuiltinFunctionForEVM const* EVMDialectTyped::equalityFunction(YulString _type) const +BuiltinFunctionForEVM const* EVMDialectTyped::equalityFunction(YulName _type) const { - if (_type == "bool"_yulstring) + if (_type == "bool"_yulname) return nullptr; else { yulAssert(_type == defaultType, ""); - return builtin("eq"_yulstring); + return builtin("eq"_yulname); } } diff --git a/libyul/backends/evm/EVMDialect.h b/libyul/backends/evm/EVMDialect.h index f0455a8e4240..7db1ec09d32b 100644 --- a/libyul/backends/evm/EVMDialect.h +++ b/libyul/backends/evm/EVMDialect.h @@ -33,8 +33,7 @@ namespace solidity::yul { -class YulString; -using Type = YulString; +using Type = YulName; struct FunctionCall; struct Object; @@ -70,19 +69,19 @@ struct EVMDialect: public Dialect EVMDialect(langutil::EVMVersion _evmVersion, bool _objectAccess); /// @returns the builtin function of the given name or a nullptr if it is not a builtin function. - BuiltinFunctionForEVM const* builtin(YulString _name) const override; + BuiltinFunctionForEVM const* builtin(YulName _name) const override; /// @returns true if the identifier is reserved. This includes the builtins too. - bool reservedIdentifier(YulString _name) const override; + bool reservedIdentifier(YulName _name) const override; - BuiltinFunctionForEVM const* discardFunction(YulString /*_type*/) const override { return builtin("pop"_yulstring); } - BuiltinFunctionForEVM const* equalityFunction(YulString /*_type*/) const override { return builtin("eq"_yulstring); } - BuiltinFunctionForEVM const* booleanNegationFunction() const override { return builtin("iszero"_yulstring); } - BuiltinFunctionForEVM const* memoryStoreFunction(YulString /*_type*/) const override { return builtin("mstore"_yulstring); } - BuiltinFunctionForEVM const* memoryLoadFunction(YulString /*_type*/) const override { return builtin("mload"_yulstring); } - BuiltinFunctionForEVM const* storageStoreFunction(YulString /*_type*/) const override { return builtin("sstore"_yulstring); } - BuiltinFunctionForEVM const* storageLoadFunction(YulString /*_type*/) const override { return builtin("sload"_yulstring); } - YulString hashFunction(YulString /*_type*/) const override { return "keccak256"_yulstring; } + BuiltinFunctionForEVM const* discardFunction(YulName /*_type*/) const override { return builtin("pop"_yulname); } + BuiltinFunctionForEVM const* equalityFunction(YulName /*_type*/) const override { return builtin("eq"_yulname); } + BuiltinFunctionForEVM const* booleanNegationFunction() const override { return builtin("iszero"_yulname); } + BuiltinFunctionForEVM const* memoryStoreFunction(YulName /*_type*/) const override { return builtin("mstore"_yulname); } + BuiltinFunctionForEVM const* memoryLoadFunction(YulName /*_type*/) const override { return builtin("mload"_yulname); } + BuiltinFunctionForEVM const* storageStoreFunction(YulName /*_type*/) const override { return builtin("sstore"_yulname); } + BuiltinFunctionForEVM const* storageLoadFunction(YulName /*_type*/) const override { return builtin("sload"_yulname); } + YulName hashFunction(YulName /*_type*/) const override { return "keccak256"_yulname; } static EVMDialect const& strictAssemblyForEVM(langutil::EVMVersion _version); static EVMDialect const& strictAssemblyForEVMObjects(langutil::EVMVersion _version); @@ -98,9 +97,9 @@ struct EVMDialect: public Dialect bool const m_objectAccess; langutil::EVMVersion const m_evmVersion; - std::map m_functions; + std::map m_functions; std::map, std::shared_ptr> mutable m_verbatimFunctions; - std::set m_reserved; + std::set m_reserved; }; /** @@ -118,9 +117,9 @@ struct EVMDialectTyped: public EVMDialect /// Constructor, should only be used internally. Use the factory function below. EVMDialectTyped(langutil::EVMVersion _evmVersion, bool _objectAccess); - BuiltinFunctionForEVM const* discardFunction(YulString _type) const override; - BuiltinFunctionForEVM const* equalityFunction(YulString _type) const override; - BuiltinFunctionForEVM const* booleanNegationFunction() const override { return builtin("not"_yulstring); } + BuiltinFunctionForEVM const* discardFunction(YulName _type) const override; + BuiltinFunctionForEVM const* equalityFunction(YulName _type) const override; + BuiltinFunctionForEVM const* booleanNegationFunction() const override { return builtin("not"_yulname); } static EVMDialectTyped const& instance(langutil::EVMVersion _version); }; diff --git a/libyul/backends/evm/EVMObjectCompiler.cpp b/libyul/backends/evm/EVMObjectCompiler.cpp index 81a345f90889..422c08bf96aa 100644 --- a/libyul/backends/evm/EVMObjectCompiler.cpp +++ b/libyul/backends/evm/EVMObjectCompiler.cpp @@ -92,7 +92,7 @@ void EVMObjectCompiler::run(Object& _object, bool _optimize) { std::vector memoryGuardCalls = findFunctionCalls( std::as_const(*_object.code), - "memoryguard"_yulstring + "memoryguard"_yulname ); auto stackError = stackErrors.front(); std::string msg = stackError.comment() ? *stackError.comment() : ""; diff --git a/libyul/backends/evm/OptimizedEVMCodeTransform.cpp b/libyul/backends/evm/OptimizedEVMCodeTransform.cpp index 047014e3dc43..a6b867aba167 100644 --- a/libyul/backends/evm/OptimizedEVMCodeTransform.cpp +++ b/libyul/backends/evm/OptimizedEVMCodeTransform.cpp @@ -185,7 +185,7 @@ OptimizedEVMCodeTransform::OptimizedEVMCodeTransform( m_stackLayout(_stackLayout), m_functionLabels([&](){ std::map functionLabels; - std::set assignedFunctionNames; + std::set assignedFunctionNames; for (Scope::Function const* function: m_dfg.functions) { CFG::FunctionInfo const& functionInfo = m_dfg.functionInfo.at(function); @@ -242,7 +242,7 @@ void OptimizedEVMCodeTransform::createStackLayout(langutil::DebugData::ConstPtr static constexpr auto slotVariableName = [](StackSlot const& _slot) { return std::visit(util::GenericVisitor{ [](VariableSlot const& _var) { return _var.variable.get().name; }, - [](auto const&) { return YulString{}; } + [](auto const&) { return YulName{}; } }, _slot); }; @@ -264,14 +264,14 @@ void OptimizedEVMCodeTransform::createStackLayout(langutil::DebugData::ConstPtr { int deficit = static_cast(_i) - 16; StackSlot const& deepSlot = m_stack.at(m_stack.size() - _i - 1); - YulString varNameDeep = slotVariableName(deepSlot); - YulString varNameTop = slotVariableName(m_stack.back()); + YulName varNameDeep = slotVariableName(deepSlot); + YulName varNameTop = slotVariableName(m_stack.back()); std::string msg = "Cannot swap " + (varNameDeep.empty() ? "Slot " + stackSlotToString(deepSlot) : "Variable " + varNameDeep.str()) + " with " + (varNameTop.empty() ? "Slot " + stackSlotToString(m_stack.back()) : "Variable " + varNameTop.str()) + ": too deep in the stack by " + std::to_string(deficit) + " slots in " + stackToString(m_stack); m_stackErrors.emplace_back(StackTooDeepError( - m_currentFunctionInfo ? m_currentFunctionInfo->function.name : YulString{}, + m_currentFunctionInfo ? m_currentFunctionInfo->function.name : YulName{}, varNameDeep.empty() ? varNameTop : varNameDeep, deficit, msg @@ -295,12 +295,12 @@ void OptimizedEVMCodeTransform::createStackLayout(langutil::DebugData::ConstPtr else if (!canBeFreelyGenerated(_slot)) { int deficit = static_cast(*depth - 15); - YulString varName = slotVariableName(_slot); + YulName varName = slotVariableName(_slot); std::string msg = (varName.empty() ? "Slot " + stackSlotToString(_slot) : "Variable " + varName.str()) + " is " + std::to_string(*depth - 15) + " too deep in the stack " + stackToString(m_stack); m_stackErrors.emplace_back(StackTooDeepError( - m_currentFunctionInfo ? m_currentFunctionInfo->function.name : YulString{}, + m_currentFunctionInfo ? m_currentFunctionInfo->function.name : YulName{}, varName, deficit, msg diff --git a/libyul/backends/evm/StackLayoutGenerator.cpp b/libyul/backends/evm/StackLayoutGenerator.cpp index 954c9f2af7af..c781d7c1b813 100644 --- a/libyul/backends/evm/StackLayoutGenerator.cpp +++ b/libyul/backends/evm/StackLayoutGenerator.cpp @@ -58,17 +58,17 @@ StackLayout StackLayoutGenerator::run(CFG const& _cfg) return stackLayout; } -std::map> StackLayoutGenerator::reportStackTooDeep(CFG const& _cfg) +std::map> StackLayoutGenerator::reportStackTooDeep(CFG const& _cfg) { - std::map> stackTooDeepErrors; - stackTooDeepErrors[YulString{}] = reportStackTooDeep(_cfg, YulString{}); + std::map> stackTooDeepErrors; + stackTooDeepErrors[YulName{}] = reportStackTooDeep(_cfg, YulName{}); for (auto const& function: _cfg.functions) if (auto errors = reportStackTooDeep(_cfg, function->name); !errors.empty()) stackTooDeepErrors[function->name] = std::move(errors); return stackTooDeepErrors; } -std::vector StackLayoutGenerator::reportStackTooDeep(CFG const& _cfg, YulString _functionName) +std::vector StackLayoutGenerator::reportStackTooDeep(CFG const& _cfg, YulName _functionName) { StackLayout stackLayout; CFG::FunctionInfo const* functionInfo = nullptr; @@ -102,7 +102,7 @@ std::vector findStackTooDeep(Stack const& _s Stack currentStack = _source; std::vector stackTooDeepErrors; auto getVariableChoices = [](auto&& _range) { - std::vector result; + std::vector result; for (auto const& slot: _range) if (auto const* variableSlot = std::get_if(&slot)) if (!util::contains(result, variableSlot->variable.get().name)) diff --git a/libyul/backends/evm/StackLayoutGenerator.h b/libyul/backends/evm/StackLayoutGenerator.h index d04b80bdc02a..fc846a9deced 100644 --- a/libyul/backends/evm/StackLayoutGenerator.h +++ b/libyul/backends/evm/StackLayoutGenerator.h @@ -52,18 +52,18 @@ class StackLayoutGenerator /// Number of slots that need to be saved. size_t deficit = 0; /// Set of variables, eliminating which would decrease the stack deficit. - std::vector variableChoices; + std::vector variableChoices; }; static StackLayout run(CFG const& _cfg); /// @returns a map from function names to the stack too deep errors occurring in that function. /// Requires @a _cfg to be a control flow graph generated from disambiguated Yul. /// The empty string is mapped to the stack too deep errors of the main entry point. - static std::map> reportStackTooDeep(CFG const& _cfg); + static std::map> reportStackTooDeep(CFG const& _cfg); /// @returns all stack too deep errors in the function named @a _functionName. /// Requires @a _cfg to be a control flow graph generated from disambiguated Yul. /// If @a _functionName is empty, the stack too deep errors of the main entry point are reported instead. - static std::vector reportStackTooDeep(CFG const& _cfg, YulString _functionName); + static std::vector reportStackTooDeep(CFG const& _cfg, YulName _functionName); private: StackLayoutGenerator(StackLayout& _context, CFG::FunctionInfo const* _functionInfo); diff --git a/libyul/backends/evm/VariableReferenceCounter.cpp b/libyul/backends/evm/VariableReferenceCounter.cpp index c2afb399d28f..9f4857887754 100644 --- a/libyul/backends/evm/VariableReferenceCounter.cpp +++ b/libyul/backends/evm/VariableReferenceCounter.cpp @@ -71,7 +71,7 @@ void VariableReferenceCounter::operator()(Block const& _block) m_scope = originalScope; } -void VariableReferenceCounter::increaseRefIfFound(YulString _variableName) +void VariableReferenceCounter::increaseRefIfFound(YulName _variableName) { m_scope->lookup(_variableName, util::GenericVisitor{ [&](Scope::Variable const& _var) diff --git a/libyul/backends/evm/VariableReferenceCounter.h b/libyul/backends/evm/VariableReferenceCounter.h index ba6404b17180..75552279359b 100644 --- a/libyul/backends/evm/VariableReferenceCounter.h +++ b/libyul/backends/evm/VariableReferenceCounter.h @@ -58,7 +58,7 @@ struct VariableReferenceCounter: public yul::ASTWalker ): m_info(_assemblyInfo) {} - void increaseRefIfFound(YulString _variableName); + void increaseRefIfFound(YulName _variableName); AsmAnalysisInfo const& m_info; Scope* m_scope = nullptr; diff --git a/libyul/optimiser/ASTCopier.cpp b/libyul/optimiser/ASTCopier.cpp index 9f41079418b2..8efe29613e93 100644 --- a/libyul/optimiser/ASTCopier.cpp +++ b/libyul/optimiser/ASTCopier.cpp @@ -83,7 +83,7 @@ Statement ASTCopier::operator()(Switch const& _switch) Statement ASTCopier::operator()(FunctionDefinition const& _function) { - YulString translatedName = translateIdentifier(_function.name); + YulName translatedName = translateIdentifier(_function.name); enterFunction(_function); ScopeGuard g([&]() { this->leaveFunction(_function); }); @@ -168,7 +168,7 @@ TypedName ASTCopier::translate(TypedName const& _typedName) return TypedName{_typedName.debugData, translateIdentifier(_typedName.name), _typedName.type}; } -YulString FunctionCopier::translateIdentifier(YulString _name) +YulName FunctionCopier::translateIdentifier(YulName _name) { if (m_translations.count(_name)) return m_translations.at(_name); diff --git a/libyul/optimiser/ASTCopier.h b/libyul/optimiser/ASTCopier.h index db9d72af35ec..88d2a34510ad 100644 --- a/libyul/optimiser/ASTCopier.h +++ b/libyul/optimiser/ASTCopier.h @@ -23,7 +23,7 @@ #include -#include +#include #include #include @@ -106,7 +106,7 @@ class ASTCopier: public ExpressionCopier, public StatementCopier virtual void leaveScope(Block const&) { } virtual void enterFunction(FunctionDefinition const&) { } virtual void leaveFunction(FunctionDefinition const&) { } - virtual YulString translateIdentifier(YulString _name) { return _name; } + virtual YulName translateIdentifier(YulName _name) { return _name; } }; template @@ -124,16 +124,16 @@ class FunctionCopier: public ASTCopier { public: FunctionCopier( - std::map const& _translations + std::map const& _translations ): m_translations(_translations) {} using ASTCopier::operator(); - YulString translateIdentifier(YulString _name) override; + YulName translateIdentifier(YulName _name) override; private: /// A mapping between old and new names. We replace the names of variable declarations contained /// in the mapping with their new names. - std::map const& m_translations; + std::map const& m_translations; }; } diff --git a/libyul/optimiser/ASTWalker.h b/libyul/optimiser/ASTWalker.h index b937f7eae423..0c23a836e624 100644 --- a/libyul/optimiser/ASTWalker.h +++ b/libyul/optimiser/ASTWalker.h @@ -24,7 +24,7 @@ #include #include -#include +#include #include #include diff --git a/libyul/optimiser/BlockHasher.h b/libyul/optimiser/BlockHasher.h index 2b9a71f101ac..427161b3c784 100644 --- a/libyul/optimiser/BlockHasher.h +++ b/libyul/optimiser/BlockHasher.h @@ -22,7 +22,7 @@ #include #include -#include +#include namespace solidity::yul { @@ -112,8 +112,8 @@ class BlockHasher: public ASTWalker, public ASTHasherBase size_t id = 0; bool isExternal = false; }; - std::map m_variableReferences; - std::vector m_externalReferences; + std::map m_variableReferences; + std::vector m_externalReferences; size_t m_externalIdentifierCount = 0; size_t m_internalIdentifierCount = 0; }; diff --git a/libyul/optimiser/CallGraphGenerator.cpp b/libyul/optimiser/CallGraphGenerator.cpp index 87035e68a0e7..f457f55838d3 100644 --- a/libyul/optimiser/CallGraphGenerator.cpp +++ b/libyul/optimiser/CallGraphGenerator.cpp @@ -35,11 +35,11 @@ namespace struct CallGraphCycleFinder { CallGraph const& callGraph; - std::set containedInCycle{}; - std::set visited{}; - std::vector currentPath{}; + std::set containedInCycle{}; + std::set visited{}; + std::vector currentPath{}; - void visit(YulString _function) + void visit(YulName _function) { if (visited.count(_function)) return; @@ -61,7 +61,7 @@ struct CallGraphCycleFinder }; } -std::set CallGraph::recursiveFunctions() const +std::set CallGraph::recursiveFunctions() const { CallGraphCycleFinder cycleFinder{*this}; // Visiting the root only is not enough, since there may be disconnected recursive functions. @@ -93,7 +93,7 @@ void CallGraphGenerator::operator()(ForLoop const& _forLoop) void CallGraphGenerator::operator()(FunctionDefinition const& _functionDefinition) { - YulString previousFunction = m_currentFunction; + YulName previousFunction = m_currentFunction; m_currentFunction = _functionDefinition.name; yulAssert(m_callGraph.functionCalls.count(m_currentFunction) == 0, ""); m_callGraph.functionCalls[m_currentFunction] = {}; @@ -103,6 +103,6 @@ void CallGraphGenerator::operator()(FunctionDefinition const& _functionDefinitio CallGraphGenerator::CallGraphGenerator() { - m_callGraph.functionCalls[YulString{}] = {}; + m_callGraph.functionCalls[YulName{}] = {}; } diff --git a/libyul/optimiser/CallGraphGenerator.h b/libyul/optimiser/CallGraphGenerator.h index ad19878b6892..23e9a2511588 100644 --- a/libyul/optimiser/CallGraphGenerator.h +++ b/libyul/optimiser/CallGraphGenerator.h @@ -32,12 +32,12 @@ namespace solidity::yul struct CallGraph { - std::map> functionCalls; - std::set functionsWithLoops; + std::map> functionCalls; + std::set functionsWithLoops; /// @returns the set of functions contained in cycles in the call graph, i.e. /// functions that are part of a (mutual) recursion. /// Note that this does not include functions that merely call recursive functions. - std::set recursiveFunctions() const; + std::set recursiveFunctions() const; }; /** @@ -62,7 +62,7 @@ class CallGraphGenerator: public ASTWalker CallGraph m_callGraph; /// The name of the function we are currently visiting during traversal. - YulString m_currentFunction; + YulName m_currentFunction; }; } diff --git a/libyul/optimiser/CircularReferencesPruner.cpp b/libyul/optimiser/CircularReferencesPruner.cpp index 824d2be39fb0..a34f3f4e2aa3 100644 --- a/libyul/optimiser/CircularReferencesPruner.cpp +++ b/libyul/optimiser/CircularReferencesPruner.cpp @@ -34,7 +34,7 @@ void CircularReferencesPruner::run(OptimiserStepContext& _context, Block& _ast) void CircularReferencesPruner::operator()(Block& _block) { - std::set functionsToKeep = + std::set functionsToKeep = functionsCalledFromOutermostContext(CallGraphGenerator::callGraph(_block)); for (auto&& statement: _block.statements) @@ -48,13 +48,13 @@ void CircularReferencesPruner::operator()(Block& _block) removeEmptyBlocks(_block); } -std::set CircularReferencesPruner::functionsCalledFromOutermostContext(CallGraph const& _callGraph) +std::set CircularReferencesPruner::functionsCalledFromOutermostContext(CallGraph const& _callGraph) { - std::set verticesToTraverse = m_reservedIdentifiers; - verticesToTraverse.insert(YulString("")); + std::set verticesToTraverse = m_reservedIdentifiers; + verticesToTraverse.insert(YulName("")); - return util::BreadthFirstSearch{{verticesToTraverse.begin(), verticesToTraverse.end()}}.run( - [&_callGraph](YulString _function, auto&& _addChild) { + return util::BreadthFirstSearch{{verticesToTraverse.begin(), verticesToTraverse.end()}}.run( + [&_callGraph](YulName _function, auto&& _addChild) { if (_callGraph.functionCalls.count(_function)) for (auto const& callee: _callGraph.functionCalls.at(_function)) if (_callGraph.functionCalls.count(callee)) diff --git a/libyul/optimiser/CircularReferencesPruner.h b/libyul/optimiser/CircularReferencesPruner.h index 0602445af4ab..090b0617fc8e 100644 --- a/libyul/optimiser/CircularReferencesPruner.h +++ b/libyul/optimiser/CircularReferencesPruner.h @@ -27,6 +27,7 @@ #include #include #include +#include namespace solidity::yul { @@ -44,16 +45,16 @@ class CircularReferencesPruner: public ASTModifier using ASTModifier::operator(); void operator()(Block& _block) override; private: - CircularReferencesPruner(std::set const& _reservedIdentifiers): + CircularReferencesPruner(std::set const& _reservedIdentifiers): m_reservedIdentifiers(_reservedIdentifiers) {} /// Run a breadth-first search starting from the outermost context and /// externally referenced functions to find all the functions that are /// called from there either directly or indirectly. - std::set functionsCalledFromOutermostContext(CallGraph const& _callGraph); + std::set functionsCalledFromOutermostContext(CallGraph const& _callGraph); - std::set const& m_reservedIdentifiers; + std::set const& m_reservedIdentifiers; }; } diff --git a/libyul/optimiser/CommonSubexpressionEliminator.cpp b/libyul/optimiser/CommonSubexpressionEliminator.cpp index 1c7879056d61..073d621cc2cf 100644 --- a/libyul/optimiser/CommonSubexpressionEliminator.cpp +++ b/libyul/optimiser/CommonSubexpressionEliminator.cpp @@ -46,7 +46,7 @@ void CommonSubexpressionEliminator::run(OptimiserStepContext& _context, Block& _ CommonSubexpressionEliminator::CommonSubexpressionEliminator( Dialect const& _dialect, - std::map _functionSideEffects + std::map _functionSideEffects ): DataFlowAnalyzer(_dialect, MemoryAndStorage::Ignore, std::move(_functionSideEffects)) { @@ -95,7 +95,7 @@ void CommonSubexpressionEliminator::visit(Expression& _e) if (Identifier const* identifier = std::get_if(&_e)) { - YulString identifierName = identifier->name; + YulName identifierName = identifier->name; if (AssignedValue const* assignedValue = variableValue(identifierName)) { assertThrow(assignedValue->value, OptimizerException, ""); @@ -126,7 +126,7 @@ void CommonSubexpressionEliminator::visit(Expression& _e) } } -void CommonSubexpressionEliminator::assignValue(YulString _variable, Expression const* _value) +void CommonSubexpressionEliminator::assignValue(YulName _variable, Expression const* _value) { if (_value) m_replacementCandidates[*_value].insert(_variable); diff --git a/libyul/optimiser/CommonSubexpressionEliminator.h b/libyul/optimiser/CommonSubexpressionEliminator.h index 163c9df994e4..d7dc42596ca4 100644 --- a/libyul/optimiser/CommonSubexpressionEliminator.h +++ b/libyul/optimiser/CommonSubexpressionEliminator.h @@ -53,19 +53,19 @@ class CommonSubexpressionEliminator: public DataFlowAnalyzer private: CommonSubexpressionEliminator( Dialect const& _dialect, - std::map _functionSideEffects + std::map _functionSideEffects ); protected: using ASTModifier::visit; void visit(Expression& _e) override; - void assignValue(YulString _variable, Expression const* _value) override; + void assignValue(YulName _variable, Expression const* _value) override; private: - std::set m_returnVariables; + std::set m_returnVariables; std::unordered_map< std::reference_wrapper, - std::set, + std::set, ExpressionHash, SyntacticallyEqualExpression > m_replacementCandidates; diff --git a/libyul/optimiser/ConditionalSimplifier.cpp b/libyul/optimiser/ConditionalSimplifier.cpp index 7119091257d3..a2656fed390e 100644 --- a/libyul/optimiser/ConditionalSimplifier.cpp +++ b/libyul/optimiser/ConditionalSimplifier.cpp @@ -42,7 +42,7 @@ void ConditionalSimplifier::operator()(Switch& _switch) ASTModifier::operator()(_switch); return; } - YulString expr = std::get(*_switch.expression).name; + YulName expr = std::get(*_switch.expression).name; for (auto& _case: _switch.cases) { if (_case.value) @@ -77,7 +77,7 @@ void ConditionalSimplifier::operator()(Block& _block) TerminationFinder::ControlFlow::FlowOut ) { - YulString condition = std::get(*_if.condition).name; + YulName condition = std::get(*_if.condition).name; langutil::DebugData::ConstPtr debugData = _if.debugData; return make_vector( std::move(_s), diff --git a/libyul/optimiser/ConditionalSimplifier.h b/libyul/optimiser/ConditionalSimplifier.h index e558a1c6cf5c..c78052126f5f 100644 --- a/libyul/optimiser/ConditionalSimplifier.h +++ b/libyul/optimiser/ConditionalSimplifier.h @@ -62,12 +62,12 @@ class ConditionalSimplifier: public ASTModifier private: explicit ConditionalSimplifier( Dialect const& _dialect, - std::map _sideEffects + std::map _sideEffects ): m_dialect(_dialect), m_functionSideEffects(std::move(_sideEffects)) {} Dialect const& m_dialect; - std::map m_functionSideEffects; + std::map m_functionSideEffects; }; } diff --git a/libyul/optimiser/ConditionalUnsimplifier.cpp b/libyul/optimiser/ConditionalUnsimplifier.cpp index 104ec1e4f095..06348e9977a1 100644 --- a/libyul/optimiser/ConditionalUnsimplifier.cpp +++ b/libyul/optimiser/ConditionalUnsimplifier.cpp @@ -43,7 +43,7 @@ void ConditionalUnsimplifier::operator()(Switch& _switch) ASTModifier::operator()(_switch); return; } - YulString expr = std::get(*_switch.expression).name; + YulName expr = std::get(*_switch.expression).name; for (auto& _case: _switch.cases) { if (_case.value) @@ -83,7 +83,7 @@ void ConditionalUnsimplifier::operator()(Block& _block) !_if.body.statements.empty() ) { - YulString condition = std::get(*_if.condition).name; + YulName condition = std::get(*_if.condition).name; if ( std::holds_alternative(_stmt2) && TerminationFinder(m_dialect, &m_functionSideEffects).controlFlowKind(_if.body.statements.back()) != diff --git a/libyul/optimiser/ConditionalUnsimplifier.h b/libyul/optimiser/ConditionalUnsimplifier.h index 8025b661b96b..dc1c6e24544e 100644 --- a/libyul/optimiser/ConditionalUnsimplifier.h +++ b/libyul/optimiser/ConditionalUnsimplifier.h @@ -42,12 +42,12 @@ class ConditionalUnsimplifier: public ASTModifier private: explicit ConditionalUnsimplifier( Dialect const& _dialect, - std::map const& _sideEffects + std::map const& _sideEffects ): m_dialect(_dialect), m_functionSideEffects(_sideEffects) {} Dialect const& m_dialect; - std::map const& m_functionSideEffects; + std::map const& m_functionSideEffects; }; } diff --git a/libyul/optimiser/ControlFlowSimplifier.cpp b/libyul/optimiser/ControlFlowSimplifier.cpp index 10f479a421b4..9d56583a0611 100644 --- a/libyul/optimiser/ControlFlowSimplifier.cpp +++ b/libyul/optimiser/ControlFlowSimplifier.cpp @@ -197,7 +197,7 @@ OptionalStatements ControlFlowSimplifier::reduceSingleCaseSwitch(Switch& _switch auto& switchCase = _switchStmt.cases.front(); langutil::DebugData::ConstPtr debugData = debugDataOf(*_switchStmt.expression); - YulString type = m_typeInfo.typeOf(*_switchStmt.expression); + YulName type = m_typeInfo.typeOf(*_switchStmt.expression); if (switchCase.value) { if (!m_dialect.equalityFunction(type)) diff --git a/libyul/optimiser/DataFlowAnalyzer.cpp b/libyul/optimiser/DataFlowAnalyzer.cpp index 5ec3cf248df9..a51ca912399d 100644 --- a/libyul/optimiser/DataFlowAnalyzer.cpp +++ b/libyul/optimiser/DataFlowAnalyzer.cpp @@ -45,22 +45,22 @@ using namespace solidity::yul; DataFlowAnalyzer::DataFlowAnalyzer( Dialect const& _dialect, MemoryAndStorage _analyzeStores, - std::map _functionSideEffects + std::map _functionSideEffects ): m_dialect(_dialect), m_functionSideEffects(std::move(_functionSideEffects)), - m_knowledgeBase([this](YulString _var) { return variableValue(_var); }), + m_knowledgeBase([this](YulName _var) { return variableValue(_var); }), m_analyzeStores(_analyzeStores == MemoryAndStorage::Analyze) { if (m_analyzeStores) { - if (auto const* builtin = _dialect.memoryStoreFunction(YulString{})) + if (auto const* builtin = _dialect.memoryStoreFunction(YulName{})) m_storeFunctionName[static_cast(StoreLoadLocation::Memory)] = builtin->name; - if (auto const* builtin = _dialect.memoryLoadFunction(YulString{})) + if (auto const* builtin = _dialect.memoryLoadFunction(YulName{})) m_loadFunctionName[static_cast(StoreLoadLocation::Memory)] = builtin->name; - if (auto const* builtin = _dialect.storageStoreFunction(YulString{})) + if (auto const* builtin = _dialect.storageStoreFunction(YulName{})) m_storeFunctionName[static_cast(StoreLoadLocation::Storage)] = builtin->name; - if (auto const* builtin = _dialect.storageLoadFunction(YulString{})) + if (auto const* builtin = _dialect.storageLoadFunction(YulName{})) m_loadFunctionName[static_cast(StoreLoadLocation::Storage)] = builtin->name; } } @@ -98,7 +98,7 @@ void DataFlowAnalyzer::operator()(ExpressionStatement& _statement) void DataFlowAnalyzer::operator()(Assignment& _assignment) { - std::set names; + std::set names; for (auto const& var: _assignment.variableNames) names.emplace(var.name); assertThrow(_assignment.value, OptimizerException, ""); @@ -109,7 +109,7 @@ void DataFlowAnalyzer::operator()(Assignment& _assignment) void DataFlowAnalyzer::operator()(VariableDeclaration& _varDecl) { - std::set names; + std::set names; for (auto const& var: _varDecl.variables) names.emplace(var.name); m_variableScopes.back().variables += names; @@ -138,14 +138,14 @@ void DataFlowAnalyzer::operator()(Switch& _switch) { clearKnowledgeIfInvalidated(*_switch.expression); visit(*_switch.expression); - std::set assignedVariables; + std::set assignedVariables; for (auto& _case: _switch.cases) { Environment preEnvironment = m_state.environment; (*this)(_case.body); joinKnowledge(preEnvironment); - std::set variables = assignedVariableNames(_case.body); + std::set variables = assignedVariableNames(_case.body); assignedVariables += variables; // This is a little too destructive, we could retain the old values. clearValues(variables); @@ -191,7 +191,7 @@ void DataFlowAnalyzer::operator()(ForLoop& _for) AssignmentsSinceContinue assignmentsSinceCont; assignmentsSinceCont(_for.body); - std::set assignedVariables = + std::set assignedVariables = assignedVariableNames(_for.body) + assignedVariableNames(_for.post); clearValues(assignedVariables); @@ -222,31 +222,31 @@ void DataFlowAnalyzer::operator()(Block& _block) assertThrow(numScopes == m_variableScopes.size(), OptimizerException, ""); } -std::optional DataFlowAnalyzer::storageValue(YulString _key) const +std::optional DataFlowAnalyzer::storageValue(YulName _key) const { - if (YulString const* value = valueOrNullptr(m_state.environment.storage, _key)) + if (YulName const* value = valueOrNullptr(m_state.environment.storage, _key)) return *value; else return std::nullopt; } -std::optional DataFlowAnalyzer::memoryValue(YulString _key) const +std::optional DataFlowAnalyzer::memoryValue(YulName _key) const { - if (YulString const* value = valueOrNullptr(m_state.environment.memory, _key)) + if (YulName const* value = valueOrNullptr(m_state.environment.memory, _key)) return *value; else return std::nullopt; } -std::optional DataFlowAnalyzer::keccakValue(YulString _start, YulString _length) const +std::optional DataFlowAnalyzer::keccakValue(YulName _start, YulName _length) const { - if (YulString const* value = valueOrNullptr(m_state.environment.keccak, std::make_pair(_start, _length))) + if (YulName const* value = valueOrNullptr(m_state.environment.keccak, std::make_pair(_start, _length))) return *value; else return std::nullopt; } -void DataFlowAnalyzer::handleAssignment(std::set const& _variables, Expression* _value, bool _isDeclaration) +void DataFlowAnalyzer::handleAssignment(std::set const& _variables, Expression* _value, bool _isDeclaration) { if (!_isDeclaration) clearValues(_variables); @@ -260,7 +260,7 @@ void DataFlowAnalyzer::handleAssignment(std::set const& _variables, E if (_value && _variables.size() == 1) { - YulString name = *_variables.begin(); + YulName name = *_variables.begin(); // Expression has to be movable and cannot contain a reference // to the variable that will be assigned to. if (movableChecker.movable() && !movableChecker.referencedVariables().count(name)) @@ -289,7 +289,7 @@ void DataFlowAnalyzer::handleAssignment(std::set const& _variables, E if (_value && _variables.size() == 1) { - YulString variable = *_variables.begin(); + YulName variable = *_variables.begin(); if (!movableChecker.referencedVariables().count(variable)) { // This might erase additional knowledge about the slot. @@ -320,7 +320,7 @@ void DataFlowAnalyzer::popScope() m_variableScopes.pop_back(); } -void DataFlowAnalyzer::clearValues(std::set _variables) +void DataFlowAnalyzer::clearValues(std::set _variables) { // All variables that reference variables to be cleared also have to be // cleared, but not recursively, since only the value of the original @@ -351,7 +351,7 @@ void DataFlowAnalyzer::clearValues(std::set _variables) }); // Also clear variables that reference variables to be cleared. - std::set referencingVariables; + std::set referencingVariables; for (auto const& variableToClear: _variables) for (auto const& [ref, names]: m_state.references) if (names.count(variableToClear)) @@ -365,7 +365,7 @@ void DataFlowAnalyzer::clearValues(std::set _variables) } } -void DataFlowAnalyzer::assignValue(YulString _variable, Expression const* _value) +void DataFlowAnalyzer::assignValue(YulName _variable, Expression const* _value) { m_state.value[_variable] = {_value, m_loopDepth}; } @@ -398,7 +398,7 @@ void DataFlowAnalyzer::clearKnowledgeIfInvalidated(Expression const& _expr) } } -bool DataFlowAnalyzer::inScope(YulString _variableName) const +bool DataFlowAnalyzer::inScope(YulName _variableName) const { for (auto const& scope: m_variableScopes | ranges::views::reverse) { @@ -410,7 +410,7 @@ bool DataFlowAnalyzer::inScope(YulString _variableName) const return false; } -std::optional DataFlowAnalyzer::valueOfIdentifier(YulString const& _name) const +std::optional DataFlowAnalyzer::valueOfIdentifier(YulName const& _name) const { if (AssignedValue const* value = variableValue(_name)) if (Literal const* literal = std::get_if(value->value)) @@ -418,7 +418,7 @@ std::optional DataFlowAnalyzer::valueOfIdentifier(YulString const& _name) return std::nullopt; } -std::optional> DataFlowAnalyzer::isSimpleStore( +std::optional> DataFlowAnalyzer::isSimpleStore( StoreLoadLocation _location, ExpressionStatement const& _statement ) const @@ -431,7 +431,7 @@ std::optional> DataFlowAnalyzer::isSimpleStore( return {}; } -std::optional DataFlowAnalyzer::isSimpleLoad( +std::optional DataFlowAnalyzer::isSimpleLoad( StoreLoadLocation _location, Expression const& _expression ) const @@ -443,7 +443,7 @@ std::optional DataFlowAnalyzer::isSimpleLoad( return {}; } -std::optional> DataFlowAnalyzer::isKeccak(Expression const& _expression) const +std::optional> DataFlowAnalyzer::isKeccak(Expression const& _expression) const { if (FunctionCall const* funCall = std::get_if(&_expression)) if (funCall->functionName.name == m_dialect.hashFunction({})) @@ -460,14 +460,14 @@ void DataFlowAnalyzer::joinKnowledge(Environment const& _olderEnvironment) joinKnowledgeHelper(m_state.environment.storage, _olderEnvironment.storage); joinKnowledgeHelper(m_state.environment.memory, _olderEnvironment.memory); cxx20::erase_if(m_state.environment.keccak, mapTuple([&_olderEnvironment](auto&& key, auto&& currentValue) { - YulString const* oldValue = valueOrNullptr(_olderEnvironment.keccak, key); + YulName const* oldValue = valueOrNullptr(_olderEnvironment.keccak, key); return !oldValue || *oldValue != currentValue; })); } void DataFlowAnalyzer::joinKnowledgeHelper( - std::unordered_map& _this, - std::unordered_map const& _older + std::unordered_map& _this, + std::unordered_map const& _older ) { // We clear if the key does not exist in the older map or if the value is different. @@ -475,7 +475,7 @@ void DataFlowAnalyzer::joinKnowledgeHelper( // of m_state.environment.memory and thus any overlapping write would have cleared the keys // that are not known to be different inside m_state.environment.memory already. cxx20::erase_if(_this, mapTuple([&_older](auto&& key, auto&& currentValue){ - YulString const* oldValue = valueOrNullptr(_older, key); + YulName const* oldValue = valueOrNullptr(_older, key); return !oldValue || *oldValue != currentValue; })); } diff --git a/libyul/optimiser/DataFlowAnalyzer.h b/libyul/optimiser/DataFlowAnalyzer.h index e41620b15f27..6b23a86b9c9d 100644 --- a/libyul/optimiser/DataFlowAnalyzer.h +++ b/libyul/optimiser/DataFlowAnalyzer.h @@ -25,7 +25,7 @@ #include #include -#include +#include #include // Needed for m_zero below. #include @@ -89,7 +89,7 @@ class DataFlowAnalyzer: public ASTModifier explicit DataFlowAnalyzer( Dialect const& _dialect, MemoryAndStorage _analyzeStores, - std::map _functionSideEffects = {} + std::map _functionSideEffects = {} ); using ASTModifier::operator(); @@ -103,16 +103,16 @@ class DataFlowAnalyzer: public ASTModifier void operator()(Block& _block) override; /// @returns the current value of the given variable, if known - always movable. - AssignedValue const* variableValue(YulString _variable) const { return util::valueOrNullptr(m_state.value, _variable); } - std::set const* references(YulString _variable) const { return util::valueOrNullptr(m_state.references, _variable); } - std::map const& allValues() const { return m_state.value; } - std::optional storageValue(YulString _key) const; - std::optional memoryValue(YulString _key) const; - std::optional keccakValue(YulString _start, YulString _length) const; + AssignedValue const* variableValue(YulName _variable) const { return util::valueOrNullptr(m_state.value, _variable); } + std::set const* references(YulName _variable) const { return util::valueOrNullptr(m_state.references, _variable); } + std::map const& allValues() const { return m_state.value; } + std::optional storageValue(YulName _key) const; + std::optional memoryValue(YulName _key) const; + std::optional keccakValue(YulName _start, YulName _length) const; protected: /// Registers the assignment. - void handleAssignment(std::set const& _names, Expression* _value, bool _isDeclaration); + void handleAssignment(std::set const& _names, Expression* _value, bool _isDeclaration); /// Creates a new inner scope. void pushScope(bool _functionScope); @@ -122,9 +122,9 @@ class DataFlowAnalyzer: public ASTModifier /// Clears information about the values assigned to the given variables, /// for example at points where control flow is merged. - void clearValues(std::set _names); + void clearValues(std::set _names); - virtual void assignValue(YulString _variable, Expression const* _value); + virtual void assignValue(YulName _variable, Expression const* _value); /// Clears knowledge about storage or memory if they may be modified inside the block. void clearKnowledgeIfInvalidated(Block const& _block); @@ -133,10 +133,10 @@ class DataFlowAnalyzer: public ASTModifier void clearKnowledgeIfInvalidated(Expression const& _expression); /// Returns true iff the variable is in scope. - bool inScope(YulString _variableName) const; + bool inScope(YulName _variableName) const; /// Returns the literal value of the identifier, if it exists. - std::optional valueOfIdentifier(YulString const& _name) const; + std::optional valueOfIdentifier(YulName const& _name) const; enum class StoreLoadLocation { Memory = 0, @@ -146,41 +146,41 @@ class DataFlowAnalyzer: public ASTModifier /// Checks if the statement is sstore(a, b) / mstore(a, b) /// where a and b are variables and returns these variables in that case. - std::optional> isSimpleStore( + std::optional> isSimpleStore( StoreLoadLocation _location, ExpressionStatement const& _statement ) const; /// Checks if the expression is sload(a) / mload(a) /// where a is a variable and returns the variable in that case. - std::optional isSimpleLoad( + std::optional isSimpleLoad( StoreLoadLocation _location, Expression const& _expression ) const; /// Checks if the expression is keccak256(s, l) /// where s and l are variables and returns these variables in that case. - std::optional> isKeccak(Expression const& _expression) const; + std::optional> isKeccak(Expression const& _expression) const; Dialect const& m_dialect; /// Side-effects of user-defined functions. Worst-case side-effects are assumed /// if this is not provided or the function is not found. - std::map m_functionSideEffects; + std::map m_functionSideEffects; private: struct Environment { - std::unordered_map storage; - std::unordered_map memory; + std::unordered_map storage; + std::unordered_map memory; /// If keccak[s, l] = y then y := keccak256(s, l) occurs in the code. - std::map, YulString> keccak; + std::map, YulName> keccak; }; struct State { /// Current values of variables, always movable. - std::map value; + std::map value; /// m_references[a].contains(b) <=> the current expression assigned to a references b - std::unordered_map> references; + std::unordered_map> references; Environment environment; }; @@ -192,8 +192,8 @@ class DataFlowAnalyzer: public ASTModifier void joinKnowledge(Environment const& _olderEnvironment); static void joinKnowledgeHelper( - std::unordered_map& _thisData, - std::unordered_map const& _olderData + std::unordered_map& _thisData, + std::unordered_map const& _olderData ); State m_state; @@ -203,8 +203,8 @@ class DataFlowAnalyzer: public ASTModifier /// If true, analyzes memory and storage content via mload/mstore and sload/sstore. bool m_analyzeStores = true; - YulString m_storeFunctionName[static_cast(StoreLoadLocation::Last) + 1]; - YulString m_loadFunctionName[static_cast(StoreLoadLocation::Last) + 1]; + YulName m_storeFunctionName[static_cast(StoreLoadLocation::Last) + 1]; + YulName m_loadFunctionName[static_cast(StoreLoadLocation::Last) + 1]; /// Current nesting depth of loops. size_t m_loopDepth{0}; @@ -212,11 +212,11 @@ class DataFlowAnalyzer: public ASTModifier struct Scope { explicit Scope(bool _isFunction): isFunction(_isFunction) {} - std::set variables; + std::set variables; bool isFunction; }; /// Special expression whose address will be used in m_value. - /// YulString does not need to be reset because DataFlowAnalyzer is short-lived. + /// YulName does not need to be reset because DataFlowAnalyzer is short-lived. Expression const m_zero{Literal{{}, LiteralKind::Number, LiteralValue{0, "0"}, {}}}; /// List of scopes. std::vector m_variableScopes; diff --git a/libyul/optimiser/DeadCodeEliminator.h b/libyul/optimiser/DeadCodeEliminator.h index ae8c1b2a6a4a..f252536c599e 100644 --- a/libyul/optimiser/DeadCodeEliminator.h +++ b/libyul/optimiser/DeadCodeEliminator.h @@ -22,7 +22,7 @@ #pragma once #include -#include +#include #include #include @@ -62,11 +62,11 @@ class DeadCodeEliminator: public ASTModifier private: DeadCodeEliminator( Dialect const& _dialect, - std::map _sideEffects + std::map _sideEffects ): m_dialect(_dialect), m_functionSideEffects(std::move(_sideEffects)) {} Dialect const& m_dialect; - std::map m_functionSideEffects; + std::map m_functionSideEffects; }; } diff --git a/libyul/optimiser/Disambiguator.cpp b/libyul/optimiser/Disambiguator.cpp index 34e6bc7e6a9b..11325936c7c6 100644 --- a/libyul/optimiser/Disambiguator.cpp +++ b/libyul/optimiser/Disambiguator.cpp @@ -30,7 +30,7 @@ using namespace solidity; using namespace solidity::yul; using namespace solidity::util; -YulString Disambiguator::translateIdentifier(YulString _originalName) +YulName Disambiguator::translateIdentifier(YulName _originalName) { if (m_dialect.builtin(_originalName) || m_externallyUsedIdentifiers.count(_originalName)) return _originalName; diff --git a/libyul/optimiser/Disambiguator.h b/libyul/optimiser/Disambiguator.h index 062173882761..08d8d158f699 100644 --- a/libyul/optimiser/Disambiguator.h +++ b/libyul/optimiser/Disambiguator.h @@ -42,7 +42,7 @@ class Disambiguator: public ASTCopier explicit Disambiguator( Dialect const& _dialect, AsmAnalysisInfo const& _analysisInfo, - std::set const& _externallyUsedIdentifiers = {} + std::set const& _externallyUsedIdentifiers = {} ): m_info(_analysisInfo), m_dialect(_dialect), @@ -56,17 +56,17 @@ class Disambiguator: public ASTCopier void leaveScope(Block const& _block) override; void enterFunction(FunctionDefinition const& _function) override; void leaveFunction(FunctionDefinition const& _function) override; - YulString translateIdentifier(YulString _name) override; + YulName translateIdentifier(YulName _name) override; void enterScopeInternal(Scope& _scope); void leaveScopeInternal(Scope& _scope); AsmAnalysisInfo const& m_info; Dialect const& m_dialect; - std::set const& m_externallyUsedIdentifiers; + std::set const& m_externallyUsedIdentifiers; std::vector m_scopes; - std::map m_translations; + std::map m_translations; NameDispenser m_nameDispenser; }; diff --git a/libyul/optimiser/EqualStoreEliminator.cpp b/libyul/optimiser/EqualStoreEliminator.cpp index 1e894608e9f9..0d7ff9e9c5a4 100644 --- a/libyul/optimiser/EqualStoreEliminator.cpp +++ b/libyul/optimiser/EqualStoreEliminator.cpp @@ -53,13 +53,13 @@ void EqualStoreEliminator::visit(Statement& _statement) { if (auto vars = isSimpleStore(StoreLoadLocation::Storage, *expression)) { - if (std::optional currentValue = storageValue(vars->first)) + if (std::optional currentValue = storageValue(vars->first)) if (*currentValue == vars->second) m_pendingRemovals.insert(&_statement); } else if (auto vars = isSimpleStore(StoreLoadLocation::Memory, *expression)) { - if (std::optional currentValue = memoryValue(vars->first)) + if (std::optional currentValue = memoryValue(vars->first)) if (*currentValue == vars->second) m_pendingRemovals.insert(&_statement); } diff --git a/libyul/optimiser/EqualStoreEliminator.h b/libyul/optimiser/EqualStoreEliminator.h index b8572f4667fd..a0b54c590ff5 100644 --- a/libyul/optimiser/EqualStoreEliminator.h +++ b/libyul/optimiser/EqualStoreEliminator.h @@ -45,7 +45,7 @@ class EqualStoreEliminator: public DataFlowAnalyzer private: EqualStoreEliminator( Dialect const& _dialect, - std::map _functionSideEffects + std::map _functionSideEffects ): DataFlowAnalyzer(_dialect, MemoryAndStorage::Analyze, std::move(_functionSideEffects)) {} diff --git a/libyul/optimiser/EquivalentFunctionCombiner.h b/libyul/optimiser/EquivalentFunctionCombiner.h index 5337f76842d6..627dcb3ff4fd 100644 --- a/libyul/optimiser/EquivalentFunctionCombiner.h +++ b/libyul/optimiser/EquivalentFunctionCombiner.h @@ -46,8 +46,8 @@ class EquivalentFunctionCombiner: public ASTModifier void operator()(FunctionCall& _funCall) override; private: - EquivalentFunctionCombiner(std::map _duplicates): m_duplicates(std::move(_duplicates)) {} - std::map m_duplicates; + EquivalentFunctionCombiner(std::map _duplicates): m_duplicates(std::move(_duplicates)) {} + std::map m_duplicates; }; diff --git a/libyul/optimiser/EquivalentFunctionDetector.h b/libyul/optimiser/EquivalentFunctionDetector.h index d3ddc25f7bdb..7cd161af1a45 100644 --- a/libyul/optimiser/EquivalentFunctionDetector.h +++ b/libyul/optimiser/EquivalentFunctionDetector.h @@ -35,7 +35,7 @@ namespace solidity::yul class EquivalentFunctionDetector: public ASTWalker { public: - static std::map run(Block& _block) + static std::map run(Block& _block) { EquivalentFunctionDetector detector{BlockHasher::run(_block)}; detector(_block); @@ -50,7 +50,7 @@ class EquivalentFunctionDetector: public ASTWalker std::map m_blockHashes; std::map> m_candidates; - std::map m_duplicates; + std::map m_duplicates; }; diff --git a/libyul/optimiser/ExpressionInliner.cpp b/libyul/optimiser/ExpressionInliner.cpp index cacf5843d6b3..ab4bbcfa43a8 100644 --- a/libyul/optimiser/ExpressionInliner.cpp +++ b/libyul/optimiser/ExpressionInliner.cpp @@ -56,11 +56,11 @@ void ExpressionInliner::visit(Expression& _expression) return; FunctionDefinition const& fun = *m_inlinableFunctions.at(funCall.functionName.name); - std::map substitutions; + std::map substitutions; for (size_t i = 0; i < funCall.arguments.size(); i++) { Expression const& arg = funCall.arguments[i]; - YulString paraName = fun.parameters[i].name; + YulName paraName = fun.parameters[i].name; if (!SideEffectsCollector(m_dialect, arg).movable()) return; diff --git a/libyul/optimiser/ExpressionInliner.h b/libyul/optimiser/ExpressionInliner.h index ff7da67b8832..08ff08648428 100644 --- a/libyul/optimiser/ExpressionInliner.h +++ b/libyul/optimiser/ExpressionInliner.h @@ -22,6 +22,7 @@ #include #include +#include #include #include @@ -59,16 +60,16 @@ class ExpressionInliner: public ASTModifier private: ExpressionInliner( Dialect const& _dialect, - std::map const& _inlinableFunctions + std::map const& _inlinableFunctions ): m_dialect(_dialect), m_inlinableFunctions(_inlinableFunctions) {} Dialect const& m_dialect; - std::map const& m_inlinableFunctions; + std::map const& m_inlinableFunctions; - std::map m_varReplacements; + std::map m_varReplacements; /// Set of functions we are currently visiting inside. - std::set m_currentFunctions; + std::set m_currentFunctions; }; } diff --git a/libyul/optimiser/ExpressionJoiner.h b/libyul/optimiser/ExpressionJoiner.h index 3a1fdf743579..07f86ddce73a 100644 --- a/libyul/optimiser/ExpressionJoiner.h +++ b/libyul/optimiser/ExpressionJoiner.h @@ -93,7 +93,7 @@ class ExpressionJoiner: public ASTModifier private: Block* m_currentBlock = nullptr; ///< Pointer to current block holding the statement being visited. size_t m_latestStatementInBlock = 0; ///< Offset to m_currentBlock's statements of the last visited statement. - std::map m_references; ///< Holds reference counts to all variable declarations in current block. + std::map m_references; ///< Holds reference counts to all variable declarations in current block. }; } diff --git a/libyul/optimiser/ExpressionSimplifier.cpp b/libyul/optimiser/ExpressionSimplifier.cpp index 6d0a8c9d7409..482ade8f87d5 100644 --- a/libyul/optimiser/ExpressionSimplifier.cpp +++ b/libyul/optimiser/ExpressionSimplifier.cpp @@ -44,7 +44,7 @@ void ExpressionSimplifier::visit(Expression& _expression) while (auto const* match = SimplificationRules::findFirstMatch( _expression, m_dialect, - [this](YulString _var) { return variableValue(_var); } + [this](YulName _var) { return variableValue(_var); } )) _expression = match->action().toExpression(debugDataOf(_expression), evmVersionFromDialect(m_dialect)); diff --git a/libyul/optimiser/ExpressionSplitter.cpp b/libyul/optimiser/ExpressionSplitter.cpp index 6f0834d7760e..acaa40dbf0e1 100644 --- a/libyul/optimiser/ExpressionSplitter.cpp +++ b/libyul/optimiser/ExpressionSplitter.cpp @@ -99,8 +99,8 @@ void ExpressionSplitter::outlineExpression(Expression& _expr) visit(_expr); langutil::DebugData::ConstPtr debugData = debugDataOf(_expr); - YulString var = m_nameDispenser.newName({}); - YulString type = m_typeInfo.typeOf(_expr); + YulName var = m_nameDispenser.newName({}); + YulName type = m_typeInfo.typeOf(_expr); m_statementsToPrefix.emplace_back(VariableDeclaration{ debugData, {{TypedName{debugData, var, type}}}, diff --git a/libyul/optimiser/ForLoopConditionOutOfBody.cpp b/libyul/optimiser/ForLoopConditionOutOfBody.cpp index 83b1e20a8e33..afd005b719d5 100644 --- a/libyul/optimiser/ForLoopConditionOutOfBody.cpp +++ b/libyul/optimiser/ForLoopConditionOutOfBody.cpp @@ -53,7 +53,7 @@ void ForLoopConditionOutOfBody::operator()(ForLoop& _forLoop) if (!SideEffectsCollector(m_dialect, *firstStatement.condition).movable()) return; - YulString iszero = m_dialect.booleanNegationFunction()->name; + YulName iszero = m_dialect.booleanNegationFunction()->name; langutil::DebugData::ConstPtr debugData = debugDataOf(*firstStatement.condition); if ( diff --git a/libyul/optimiser/FullInliner.cpp b/libyul/optimiser/FullInliner.cpp index 3bf00282c04b..5cdde8f0fdd5 100644 --- a/libyul/optimiser/FullInliner.cpp +++ b/libyul/optimiser/FullInliner.cpp @@ -66,8 +66,8 @@ FullInliner::FullInliner(Block& _ast, NameDispenser& _dispenser, Dialect const& m_constants.emplace(ssaValue.first); // Store size of global statements. - m_functionSizes[YulString{}] = CodeSize::codeSize(_ast); - std::map references = ReferencesCounter::countReferences(m_ast); + m_functionSizes[YulName{}] = CodeSize::codeSize(_ast); + std::map references = ReferencesCounter::countReferences(m_ast); for (auto& statement: m_ast.statements) { if (!std::holds_alternative(statement)) @@ -83,10 +83,7 @@ FullInliner::FullInliner(Block& _ast, NameDispenser& _dispenser, Dialect const& } // Check for memory guard. - std::vector memoryGuardCalls = findFunctionCalls( - _ast, - "memoryguard"_yulstring - ); + std::vector memoryGuardCalls = findFunctionCalls(_ast, "memoryguard"_yulname); // We will perform less aggressive inlining, if no ``memoryguard`` call is found. if (!memoryGuardCalls.empty()) m_hasMemoryGuard = true; @@ -104,7 +101,7 @@ void FullInliner::run(Pass _pass) // function name) order. // We use stable_sort below to keep the inlining order of two functions // with the same depth. - std::map depths = callDepths(); + std::map depths = callDepths(); std::vector functions; for (auto& statement: m_ast.statements) if (std::holds_alternative(statement)) @@ -126,10 +123,10 @@ void FullInliner::run(Pass _pass) handleBlock({}, std::get(statement)); } -std::map FullInliner::callDepths() const +std::map FullInliner::callDepths() const { CallGraph cg = CallGraphGenerator::callGraph(m_ast); - cg.functionCalls.erase(""_yulstring); + cg.functionCalls.erase(""_yulname); // Remove calls to builtin functions. for (auto& call: cg.functionCalls) @@ -139,12 +136,12 @@ std::map FullInliner::callDepths() const else ++it; - std::map depths; + std::map depths; size_t currentDepth = 0; while (true) { - std::vector removed; + std::vector removed; for (auto it = cg.functionCalls.begin(); it != cg.functionCalls.end();) { auto const& [fun, callees] = *it; @@ -159,7 +156,7 @@ std::map FullInliner::callDepths() const } for (auto& call: cg.functionCalls) - for (YulString toBeRemoved: removed) + for (YulName toBeRemoved: removed) ranges::actions::remove(call.second, toBeRemoved); currentDepth++; @@ -175,7 +172,7 @@ std::map FullInliner::callDepths() const return depths; } -bool FullInliner::shallInline(FunctionCall const& _funCall, YulString _callSite) +bool FullInliner::shallInline(FunctionCall const& _funCall, YulName _callSite) { // No recursive inlining if (_funCall.functionName.name == _callSite) @@ -237,7 +234,7 @@ bool FullInliner::shallInline(FunctionCall const& _funCall, YulString _callSite) return (size < (aggressiveInlining ? 8u : 6u) || (constantArg && size < (aggressiveInlining ? 16u : 12u))); } -void FullInliner::tentativelyUpdateCodeSize(YulString _function, YulString _callSite) +void FullInliner::tentativelyUpdateCodeSize(YulName _function, YulName _callSite) { m_functionSizes.at(_callSite) += m_functionSizes.at(_function); } @@ -247,14 +244,14 @@ void FullInliner::updateCodeSize(FunctionDefinition const& _fun) m_functionSizes[_fun.name] = CodeSize::codeSize(_fun.body); } -void FullInliner::handleBlock(YulString _currentFunctionName, Block& _block) +void FullInliner::handleBlock(YulName _currentFunctionName, Block& _block) { InlineModifier{*this, m_nameDispenser, _currentFunctionName, m_dialect}(_block); } bool FullInliner::recursive(FunctionDefinition const& _fun) const { - std::map references = ReferencesCounter::countReferences(_fun); + std::map references = ReferencesCounter::countReferences(_fun); return references[_fun.name] > 0; } @@ -292,7 +289,7 @@ std::optional> InlineModifier::tryInlineStatement(Stateme std::vector InlineModifier::performInline(Statement& _statement, FunctionCall& _funCall) { std::vector newStatements; - std::map variableReplacements; + std::map variableReplacements; FunctionDefinition* function = m_driver.function(_funCall.functionName.name); assertThrow(!!function, OptimizerException, "Attempt to inline invalid function."); @@ -302,7 +299,7 @@ std::vector InlineModifier::performInline(Statement& _statement, Func // helper function to create a new variable that is supposed to model // an existing variable. auto newVariable = [&](TypedName const& _existingVariable, Expression* _value) { - YulString newName = m_nameDispenser.newName(_existingVariable.name); + YulName newName = m_nameDispenser.newName(_existingVariable.name); variableReplacements[_existingVariable.name] = newName; VariableDeclaration varDecl{_funCall.debugData, {{_funCall.debugData, newName, _existingVariable.type}}, {}}; if (_value) @@ -364,7 +361,7 @@ Statement BodyCopier::operator()(FunctionDefinition const&) return {}; } -YulString BodyCopier::translateIdentifier(YulString _name) +YulName BodyCopier::translateIdentifier(YulName _name) { if (m_variableReplacements.count(_name)) return m_variableReplacements.at(_name); diff --git a/libyul/optimiser/FullInliner.h b/libyul/optimiser/FullInliner.h index 931315305c57..e939070238e5 100644 --- a/libyul/optimiser/FullInliner.h +++ b/libyul/optimiser/FullInliner.h @@ -75,9 +75,9 @@ class FullInliner: public ASTModifier /// Inlining heuristic. /// @param _callSite the name of the function in which the function call is located. - bool shallInline(FunctionCall const& _funCall, YulString _callSite); + bool shallInline(FunctionCall const& _funCall, YulName _callSite); - FunctionDefinition* function(YulString _name) + FunctionDefinition* function(YulName _name) { auto it = m_functions.find(_name); if (it != m_functions.end()) @@ -88,7 +88,7 @@ class FullInliner: public ASTModifier /// Adds the size of _funCall to the size of _callSite. This is just /// a rough estimate that is done during inlining. The proper size /// should be determined after inlining is completed. - void tentativelyUpdateCodeSize(YulString _function, YulString _callSite); + void tentativelyUpdateCodeSize(YulName _function, YulName _callSite); private: enum Pass { InlineTiny, InlineRest }; @@ -98,28 +98,28 @@ class FullInliner: public ASTModifier /// @returns a map containing the maximum depths of a call chain starting at each /// function. For recursive functions, the value is one larger than for all others. - std::map callDepths() const; + std::map callDepths() const; void updateCodeSize(FunctionDefinition const& _fun); - void handleBlock(YulString _currentFunctionName, Block& _block); + void handleBlock(YulName _currentFunctionName, Block& _block); bool recursive(FunctionDefinition const& _fun) const; Pass m_pass; /// The AST to be modified. The root block itself will not be modified, because /// we store pointers to functions. Block& m_ast; - std::map m_functions; + std::map m_functions; /// Functions not to be inlined (because they contain the ``leave`` statement). - std::set m_noInlineFunctions; + std::set m_noInlineFunctions; /// True, if the code contains a ``memoryguard`` and we can expect to be able to move variables to memory later. bool m_hasMemoryGuard = false; /// Set of recursive functions. - std::set m_recursiveFunctions; + std::set m_recursiveFunctions; /// Names of functions to always inline. - std::set m_singleUse; + std::set m_singleUse; /// Variables that are constants (used for inlining heuristic) - std::set m_constants; - std::map m_functionSizes; + std::set m_constants; + std::map m_functionSizes; NameDispenser& m_nameDispenser; Dialect const& m_dialect; }; @@ -131,7 +131,7 @@ class FullInliner: public ASTModifier class InlineModifier: public ASTModifier { public: - InlineModifier(FullInliner& _driver, NameDispenser& _nameDispenser, YulString _functionName, Dialect const& _dialect): + InlineModifier(FullInliner& _driver, NameDispenser& _nameDispenser, YulName _functionName, Dialect const& _dialect): m_currentFunction(std::move(_functionName)), m_driver(_driver), m_nameDispenser(_nameDispenser), @@ -144,7 +144,7 @@ class InlineModifier: public ASTModifier std::optional> tryInlineStatement(Statement& _statement); std::vector performInline(Statement& _statement, FunctionCall& _funCall); - YulString m_currentFunction; + YulName m_currentFunction; FullInliner& m_driver; NameDispenser& m_nameDispenser; Dialect const& m_dialect; @@ -160,7 +160,7 @@ class BodyCopier: public ASTCopier public: BodyCopier( NameDispenser& _nameDispenser, - std::map _variableReplacements + std::map _variableReplacements ): m_nameDispenser(_nameDispenser), m_variableReplacements(std::move(_variableReplacements)) @@ -171,10 +171,10 @@ class BodyCopier: public ASTCopier Statement operator()(VariableDeclaration const& _varDecl) override; Statement operator()(FunctionDefinition const& _funDef) override; - YulString translateIdentifier(YulString _name) override; + YulName translateIdentifier(YulName _name) override; NameDispenser& m_nameDispenser; - std::map m_variableReplacements; + std::map m_variableReplacements; }; diff --git a/libyul/optimiser/FunctionCallFinder.cpp b/libyul/optimiser/FunctionCallFinder.cpp index 99f171026e9e..aaf8b9f68232 100644 --- a/libyul/optimiser/FunctionCallFinder.cpp +++ b/libyul/optimiser/FunctionCallFinder.cpp @@ -30,14 +30,14 @@ class MaybeConstFunctionCallFinder: Base { public: using MaybeConstBlock = std::conditional_t, Block const, Block>; - static std::vector run(MaybeConstBlock& _block, YulString const _functionName) + static std::vector run(MaybeConstBlock& _block, YulName const _functionName) { MaybeConstFunctionCallFinder functionCallFinder(_functionName); functionCallFinder(_block); return functionCallFinder.m_calls; } private: - explicit MaybeConstFunctionCallFinder(YulString const _functionName): m_functionName(_functionName), m_calls() {} + explicit MaybeConstFunctionCallFinder(YulName const _functionName): m_functionName(_functionName), m_calls() {} using Base::operator(); void operator()(ResultType& _functionCall) override { @@ -45,17 +45,17 @@ class MaybeConstFunctionCallFinder: Base if (_functionCall.functionName.name == m_functionName) m_calls.emplace_back(&_functionCall); } - YulString m_functionName; + YulName m_functionName; std::vector m_calls; }; } -std::vector solidity::yul::findFunctionCalls(Block& _block, YulString _functionName) +std::vector solidity::yul::findFunctionCalls(Block& _block, YulName _functionName) { return MaybeConstFunctionCallFinder::run(_block, _functionName); } -std::vector solidity::yul::findFunctionCalls(Block const& _block, YulString _functionName) +std::vector solidity::yul::findFunctionCalls(Block const& _block, YulName _functionName) { return MaybeConstFunctionCallFinder::run(_block, _functionName); } diff --git a/libyul/optimiser/FunctionCallFinder.h b/libyul/optimiser/FunctionCallFinder.h index a5d4da56e916..41a19fe99fc7 100644 --- a/libyul/optimiser/FunctionCallFinder.h +++ b/libyul/optimiser/FunctionCallFinder.h @@ -21,7 +21,7 @@ #pragma once #include -#include +#include #include @@ -33,13 +33,13 @@ namespace solidity::yul * * Prerequisite: Disambiguator */ -std::vector findFunctionCalls(Block& _block, YulString _functionName); +std::vector findFunctionCalls(Block& _block, YulName _functionName); /** * Finds all calls to a function of a given name using an ASTWalker. * * Prerequisite: Disambiguator */ -std::vector findFunctionCalls(Block const& _block, YulString _functionName); +std::vector findFunctionCalls(Block const& _block, YulName _functionName); } diff --git a/libyul/optimiser/FunctionSpecializer.cpp b/libyul/optimiser/FunctionSpecializer.cpp index 7e6d486327ea..49da50032dfe 100644 --- a/libyul/optimiser/FunctionSpecializer.cpp +++ b/libyul/optimiser/FunctionSpecializer.cpp @@ -24,7 +24,7 @@ #include #include -#include +#include #include #include @@ -64,7 +64,7 @@ void FunctionSpecializer::operator()(FunctionCall& _f) if (ranges::any_of(arguments, [](auto& _a) { return _a.has_value(); })) { - YulString oldName = std::move(_f.functionName.name); + YulName oldName = std::move(_f.functionName.name); auto newName = m_nameDispenser.newName(oldName); m_oldToNewMap[oldName].emplace_back(std::make_pair(newName, arguments)); @@ -79,19 +79,19 @@ void FunctionSpecializer::operator()(FunctionCall& _f) FunctionDefinition FunctionSpecializer::specialize( FunctionDefinition const& _f, - YulString _newName, + YulName _newName, FunctionSpecializer::LiteralArguments _arguments ) { yulAssert(_arguments.size() == _f.parameters.size(), ""); - std::map translatedNames = applyMap( + std::map translatedNames = applyMap( NameCollector{_f, NameCollector::OnlyVariables}.names(), - [&](auto& _name) -> std::pair + [&](auto& _name) -> std::pair { return std::make_pair(_name, m_nameDispenser.newName(_name)); }, - std::map{} + std::map{} ); FunctionDefinition newFunction = std::get(FunctionCopier{translatedNames}(_f)); diff --git a/libyul/optimiser/FunctionSpecializer.h b/libyul/optimiser/FunctionSpecializer.h index b922ece8b09f..784ec4311e0f 100644 --- a/libyul/optimiser/FunctionSpecializer.h +++ b/libyul/optimiser/FunctionSpecializer.h @@ -67,7 +67,7 @@ class FunctionSpecializer: public ASTModifier private: explicit FunctionSpecializer( - std::set _recursiveFunctions, + std::set _recursiveFunctions, NameDispenser& _nameDispenser, Dialect const& _dialect ): @@ -96,15 +96,15 @@ class FunctionSpecializer: public ASTModifier /// FunctionDefinition specialize( FunctionDefinition const& _f, - YulString _newName, + YulName _newName, FunctionSpecializer::LiteralArguments _arguments ); /// A mapping between the old function name and a pair of new function name and its arguments. /// Note that at least one of the argument will have a literal value. - std::map>> m_oldToNewMap; + std::map>> m_oldToNewMap; /// We skip specializing recursive functions. Need backtracking to properly deal with them. - std::set const m_recursiveFunctions; + std::set const m_recursiveFunctions; NameDispenser& m_nameDispenser; Dialect const& m_dialect; diff --git a/libyul/optimiser/InlinableExpressionFunctionFinder.cpp b/libyul/optimiser/InlinableExpressionFunctionFinder.cpp index 0bb4d368d841..d719302dcbc2 100644 --- a/libyul/optimiser/InlinableExpressionFunctionFinder.cpp +++ b/libyul/optimiser/InlinableExpressionFunctionFinder.cpp @@ -43,7 +43,7 @@ void InlinableExpressionFunctionFinder::operator()(FunctionDefinition const& _fu { if (_function.returnVariables.size() == 1 && _function.body.statements.size() == 1) { - YulString retVariable = _function.returnVariables.front().name; + YulName retVariable = _function.returnVariables.front().name; Statement const& bodyStatement = _function.body.statements.front(); if (std::holds_alternative(bodyStatement)) { @@ -56,7 +56,7 @@ void InlinableExpressionFunctionFinder::operator()(FunctionDefinition const& _fu // would not be valid here if we were searching inside a functionally inlinable // function body. assertThrow(m_disallowedIdentifiers.empty() && !m_foundDisallowedIdentifier, OptimizerException, ""); - m_disallowedIdentifiers = std::set{retVariable, _function.name}; + m_disallowedIdentifiers = std::set{retVariable, _function.name}; std::visit(*this, *assignment.value); if (!m_foundDisallowedIdentifier) m_inlinableFunctions[_function.name] = &_function; diff --git a/libyul/optimiser/InlinableExpressionFunctionFinder.h b/libyul/optimiser/InlinableExpressionFunctionFinder.h index 587bdca91172..e7210da69a0a 100644 --- a/libyul/optimiser/InlinableExpressionFunctionFinder.h +++ b/libyul/optimiser/InlinableExpressionFunctionFinder.h @@ -42,7 +42,7 @@ class InlinableExpressionFunctionFinder: public ASTWalker { public: - std::map const& inlinableFunctions() const + std::map const& inlinableFunctions() const { return m_inlinableFunctions; } @@ -53,15 +53,15 @@ class InlinableExpressionFunctionFinder: public ASTWalker void operator()(FunctionDefinition const& _function) override; private: - void checkAllowed(YulString _name) + void checkAllowed(YulName _name) { if (m_disallowedIdentifiers.count(_name)) m_foundDisallowedIdentifier = true; } bool m_foundDisallowedIdentifier = false; - std::set m_disallowedIdentifiers; - std::map m_inlinableFunctions; + std::set m_disallowedIdentifiers; + std::map m_inlinableFunctions; }; } diff --git a/libyul/optimiser/KnowledgeBase.cpp b/libyul/optimiser/KnowledgeBase.cpp index 79eb2b317940..731f4b3b8195 100644 --- a/libyul/optimiser/KnowledgeBase.cpp +++ b/libyul/optimiser/KnowledgeBase.cpp @@ -32,19 +32,19 @@ using namespace solidity; using namespace solidity::yul; -KnowledgeBase::KnowledgeBase(std::map const& _ssaValues): +KnowledgeBase::KnowledgeBase(std::map const& _ssaValues): m_valuesAreSSA(true), - m_variableValues([_ssaValues](YulString _var) { return util::valueOrNullptr(_ssaValues, _var); }) + m_variableValues([_ssaValues](YulName _var) { return util::valueOrNullptr(_ssaValues, _var); }) {} -bool KnowledgeBase::knownToBeDifferent(YulString _a, YulString _b) +bool KnowledgeBase::knownToBeDifferent(YulName _a, YulName _b) { if (std::optional difference = differenceIfKnownConstant(_a, _b)) return difference != 0; return false; } -std::optional KnowledgeBase::differenceIfKnownConstant(YulString _a, YulString _b) +std::optional KnowledgeBase::differenceIfKnownConstant(YulName _a, YulName _b) { VariableOffset offA = explore(_a); VariableOffset offB = explore(_b); @@ -55,7 +55,7 @@ std::optional KnowledgeBase::differenceIfKnownConstant(YulString _a, YulSt } -bool KnowledgeBase::knownToBeDifferentByAtLeast32(YulString _a, YulString _b) +bool KnowledgeBase::knownToBeDifferentByAtLeast32(YulName _a, YulName _b) { if (std::optional difference = differenceIfKnownConstant(_a, _b)) return difference >= 32 && difference <= u256(0) - 32; @@ -63,12 +63,12 @@ bool KnowledgeBase::knownToBeDifferentByAtLeast32(YulString _a, YulString _b) return false; } -bool KnowledgeBase::knownToBeZero(YulString _a) +bool KnowledgeBase::knownToBeZero(YulName _a) { return valueIfKnownConstant(_a) == 0; } -std::optional KnowledgeBase::valueIfKnownConstant(YulString _a) +std::optional KnowledgeBase::valueIfKnownConstant(YulName _a) { return explore(_a).absoluteValue(); } @@ -83,7 +83,7 @@ std::optional KnowledgeBase::valueIfKnownConstant(Expression const& _expre return std::nullopt; } -KnowledgeBase::VariableOffset KnowledgeBase::explore(YulString _var) +KnowledgeBase::VariableOffset KnowledgeBase::explore(YulName _var) { Expression const* value = nullptr; if (m_valuesAreSSA) @@ -113,12 +113,12 @@ KnowledgeBase::VariableOffset KnowledgeBase::explore(YulString _var) std::optional KnowledgeBase::explore(Expression const& _value) { if (Literal const* literal = std::get_if(&_value)) - return VariableOffset{YulString{}, literal->value.value()}; + return VariableOffset{YulName{}, literal->value.value()}; else if (Identifier const* identifier = std::get_if(&_value)) return explore(identifier->name); else if (FunctionCall const* f = std::get_if(&_value)) { - if (f->functionName.name == "add"_yulstring) + if (f->functionName.name == "add"_yulname) { if (std::optional a = explore(f->arguments[0])) if (std::optional b = explore(f->arguments[1])) @@ -132,13 +132,13 @@ std::optional KnowledgeBase::explore(Expression c return VariableOffset{a->reference, offset}; } } - else if (f->functionName.name == "sub"_yulstring) + else if (f->functionName.name == "sub"_yulname) if (std::optional a = explore(f->arguments[0])) if (std::optional b = explore(f->arguments[1])) { u256 offset = a->offset - b->offset; if (a->reference == b->reference) - return VariableOffset{YulString{}, offset}; + return VariableOffset{YulName{}, offset}; else if (b->isAbsolute()) // b is constant return VariableOffset{a->reference, offset}; @@ -148,7 +148,7 @@ std::optional KnowledgeBase::explore(Expression c return std::nullopt; } -Expression const* KnowledgeBase::valueOf(YulString _var) +Expression const* KnowledgeBase::valueOf(YulName _var) { AssignedValue const* assignedValue = m_variableValues(_var); Expression const* currentValue = assignedValue ? assignedValue->value : nullptr; @@ -162,7 +162,7 @@ Expression const* KnowledgeBase::valueOf(YulString _var) return currentValue; } -void KnowledgeBase::reset(YulString _var) +void KnowledgeBase::reset(YulName _var) { yulAssert(!m_valuesAreSSA); @@ -174,16 +174,16 @@ void KnowledgeBase::reset(YulString _var) m_groupMembers[offset->reference].erase(_var); m_offsets.erase(_var); } - if (std::set* group = util::valueOrNullptr(m_groupMembers, _var)) + if (std::set* group = util::valueOrNullptr(m_groupMembers, _var)) { // _var was a representative, we might have to find a new one. if (!group->empty()) { - YulString newRepresentative = *group->begin(); + YulName newRepresentative = *group->begin(); yulAssert(newRepresentative != _var); u256 newOffset = m_offsets[newRepresentative].offset; // newOffset = newRepresentative - _var - for (YulString groupMember: *group) + for (YulName groupMember: *group) { yulAssert(m_offsets[groupMember].reference == _var); m_offsets[groupMember].reference = newRepresentative; @@ -200,7 +200,7 @@ void KnowledgeBase::reset(YulString _var) } } -KnowledgeBase::VariableOffset KnowledgeBase::setOffset(YulString _variable, VariableOffset _value) +KnowledgeBase::VariableOffset KnowledgeBase::setOffset(YulName _variable, VariableOffset _value) { m_offsets[_variable] = _value; // Constants are not tracked in m_groupMembers because diff --git a/libyul/optimiser/KnowledgeBase.h b/libyul/optimiser/KnowledgeBase.h index f83c5ac66105..46ea7b96af66 100644 --- a/libyul/optimiser/KnowledgeBase.h +++ b/libyul/optimiser/KnowledgeBase.h @@ -22,7 +22,7 @@ #pragma once #include -#include +#include #include #include @@ -55,34 +55,34 @@ struct AssignedValue; * representative variable of the group. * * There is a special group which is the constant values. Those use the - * empty YulString as representative "variable". + * empty YulName as representative "variable". */ class KnowledgeBase { public: /// Constructor for arbitrary value callback that allows for variable values /// to change in between calls to functions of this class. - explicit KnowledgeBase(std::function _variableValues): + explicit KnowledgeBase(std::function _variableValues): m_variableValues(std::move(_variableValues)) {} /// Constructor to use if source code is in SSA form and values are constant. - explicit KnowledgeBase(std::map const& _ssaValues); + explicit KnowledgeBase(std::map const& _ssaValues); - bool knownToBeDifferent(YulString _a, YulString _b); - std::optional differenceIfKnownConstant(YulString _a, YulString _b); - bool knownToBeDifferentByAtLeast32(YulString _a, YulString _b); - bool knownToBeZero(YulString _a); - std::optional valueIfKnownConstant(YulString _a); + bool knownToBeDifferent(YulName _a, YulName _b); + std::optional differenceIfKnownConstant(YulName _a, YulName _b); + bool knownToBeDifferentByAtLeast32(YulName _a, YulName _b); + bool knownToBeZero(YulName _a); + std::optional valueIfKnownConstant(YulName _a); std::optional valueIfKnownConstant(Expression const& _expression); private: /** * Constant offset relative to a reference variable, or absolute constant if the - * reference variable is the empty YulString. + * reference variable is the empty YulName. */ struct VariableOffset { - YulString reference; + YulName reference; u256 offset; bool isAbsolute() const @@ -99,30 +99,30 @@ class KnowledgeBase } }; - VariableOffset explore(YulString _var); + VariableOffset explore(YulName _var); std::optional explore(Expression const& _value); /// Retrieves the current value of a variable and potentially resets the variable if it is not up to date. - Expression const* valueOf(YulString _var); + Expression const* valueOf(YulName _var); /// Resets all information about the variable and removes it from its group, /// potentially finding a new representative. - void reset(YulString _var); + void reset(YulName _var); - VariableOffset setOffset(YulString _variable, VariableOffset _value); + VariableOffset setOffset(YulName _variable, VariableOffset _value); /// If true, we can assume that variable values never change and skip some steps. bool m_valuesAreSSA = false; /// Callback to retrieve the current value of a variable. - std::function m_variableValues; + std::function m_variableValues; /// Offsets for each variable to one representative per group. /// The empty string is the representative of the constant value zero. - std::map m_offsets; + std::map m_offsets; /// Last known value of each variable we queried. - std::map m_lastKnownValue; + std::map m_lastKnownValue; /// For each representative, variables that use it to offset from. - std::map> m_groupMembers; + std::map> m_groupMembers; }; } diff --git a/libyul/optimiser/LoadResolver.cpp b/libyul/optimiser/LoadResolver.cpp index 170eefc902b5..a7ee5dd0b92c 100644 --- a/libyul/optimiser/LoadResolver.cpp +++ b/libyul/optimiser/LoadResolver.cpp @@ -87,7 +87,7 @@ void LoadResolver::tryResolve( if (_arguments.empty() || !std::holds_alternative(_arguments.at(0))) return; - YulString key = std::get(_arguments.at(0)).name; + YulName key = std::get(_arguments.at(0)).name; if (_location == StoreLoadLocation::Storage) { if (auto value = storageValue(key)) @@ -137,7 +137,7 @@ void LoadResolver::tryEvaluateKeccak( if (costOfLiteral > costOfKeccak) return; - std::optional value = memoryValue(memoryKey->name); + std::optional value = memoryValue(memoryKey->name); if (value && inScope(*value)) { std::optional memoryContent = valueOfIdentifier(*value); diff --git a/libyul/optimiser/LoadResolver.h b/libyul/optimiser/LoadResolver.h index e56bc6c4a206..b4a496303373 100644 --- a/libyul/optimiser/LoadResolver.h +++ b/libyul/optimiser/LoadResolver.h @@ -49,7 +49,7 @@ class LoadResolver: public DataFlowAnalyzer private: LoadResolver( Dialect const& _dialect, - std::map _functionSideEffects, + std::map _functionSideEffects, bool _containsMSize, std::optional _expectedExecutionsPerDeployment ): diff --git a/libyul/optimiser/LoopInvariantCodeMotion.cpp b/libyul/optimiser/LoopInvariantCodeMotion.cpp index da3c5e3e0a5a..2a196a68f956 100644 --- a/libyul/optimiser/LoopInvariantCodeMotion.cpp +++ b/libyul/optimiser/LoopInvariantCodeMotion.cpp @@ -32,10 +32,10 @@ using namespace solidity::yul; void LoopInvariantCodeMotion::run(OptimiserStepContext& _context, Block& _ast) { - std::map functionSideEffects = + std::map functionSideEffects = SideEffectsPropagator::sideEffects(_context.dialect, CallGraphGenerator::callGraph(_ast)); bool containsMSize = MSizeFinder::containsMSize(_context.dialect, _ast); - std::set ssaVars = SSAValueTracker::ssaVariables(_ast); + std::set ssaVars = SSAValueTracker::ssaVariables(_ast); LoopInvariantCodeMotion{_context.dialect, ssaVars, functionSideEffects, containsMSize}(_ast); } @@ -56,7 +56,7 @@ void LoopInvariantCodeMotion::operator()(Block& _block) bool LoopInvariantCodeMotion::canBePromoted( VariableDeclaration const& _varDecl, - std::set const& _varsDefinedInCurrentScope, + std::set const& _varsDefinedInCurrentScope, SideEffects const& _forLoopSideEffects ) const { @@ -90,7 +90,7 @@ std::optional> LoopInvariantCodeMotion::rewriteLoop(ForLo std::vector replacement; for (Block* block: {&_for.post, &_for.body}) { - std::set varsDefinedInScope; + std::set varsDefinedInScope; util::iterateReplacing( block->statements, [&](Statement& _s) -> std::optional> diff --git a/libyul/optimiser/LoopInvariantCodeMotion.h b/libyul/optimiser/LoopInvariantCodeMotion.h index 1b264792470c..c85b87a01c32 100644 --- a/libyul/optimiser/LoopInvariantCodeMotion.h +++ b/libyul/optimiser/LoopInvariantCodeMotion.h @@ -48,8 +48,8 @@ class LoopInvariantCodeMotion: public ASTModifier private: explicit LoopInvariantCodeMotion( Dialect const& _dialect, - std::set const& _ssaVariables, - std::map const& _functionSideEffects, + std::set const& _ssaVariables, + std::map const& _functionSideEffects, bool _containsMSize ): m_containsMSize(_containsMSize), @@ -61,15 +61,15 @@ class LoopInvariantCodeMotion: public ASTModifier /// @returns true if the given variable declaration can be moved to in front of the loop. bool canBePromoted( VariableDeclaration const& _varDecl, - std::set const& _varsDefinedInCurrentScope, + std::set const& _varsDefinedInCurrentScope, SideEffects const& _forLoopSideEffects ) const; std::optional> rewriteLoop(ForLoop& _for); bool m_containsMSize = true; Dialect const& m_dialect; - std::set const& m_ssaVariables; - std::map const& m_functionSideEffects; + std::set const& m_ssaVariables; + std::map const& m_functionSideEffects; }; } diff --git a/libyul/optimiser/Metrics.cpp b/libyul/optimiser/Metrics.cpp index 2f1dee93eabe..546c465b5c43 100644 --- a/libyul/optimiser/Metrics.cpp +++ b/libyul/optimiser/Metrics.cpp @@ -199,7 +199,7 @@ void AssignmentCounter::operator()(Assignment const& _assignment) ++m_assignmentCounters[variable.name]; } -size_t AssignmentCounter::assignmentCount(YulString _name) const +size_t AssignmentCounter::assignmentCount(YulName _name) const { auto it = m_assignmentCounters.find(_name); return (it == m_assignmentCounters.end()) ? 0 : it->second; diff --git a/libyul/optimiser/Metrics.h b/libyul/optimiser/Metrics.h index f86e3b28dfad..01ab1adbd7e3 100644 --- a/libyul/optimiser/Metrics.h +++ b/libyul/optimiser/Metrics.h @@ -139,9 +139,9 @@ class AssignmentCounter: public ASTWalker public: using ASTWalker::operator(); void operator()(Assignment const& _assignment) override; - std::size_t assignmentCount(YulString _name) const; + std::size_t assignmentCount(YulName _name) const; private: - std::map m_assignmentCounters; + std::map m_assignmentCounters; }; } diff --git a/libyul/optimiser/NameCollector.cpp b/libyul/optimiser/NameCollector.cpp index 7fb0c7ed28e9..d6db837f8485 100644 --- a/libyul/optimiser/NameCollector.cpp +++ b/libyul/optimiser/NameCollector.cpp @@ -59,21 +59,21 @@ void ReferencesCounter::operator()(FunctionCall const& _funCall) ASTWalker::operator()(_funCall); } -std::map ReferencesCounter::countReferences(Block const& _block) +std::map ReferencesCounter::countReferences(Block const& _block) { ReferencesCounter counter; counter(_block); return std::move(counter.m_references); } -std::map ReferencesCounter::countReferences(FunctionDefinition const& _function) +std::map ReferencesCounter::countReferences(FunctionDefinition const& _function) { ReferencesCounter counter; counter(_function); return std::move(counter.m_references); } -std::map ReferencesCounter::countReferences(Expression const& _expression) +std::map ReferencesCounter::countReferences(Expression const& _expression) { ReferencesCounter counter; counter.visit(_expression); @@ -85,28 +85,28 @@ void VariableReferencesCounter::operator()(Identifier const& _identifier) ++m_references[_identifier.name]; } -std::map VariableReferencesCounter::countReferences(Block const& _block) +std::map VariableReferencesCounter::countReferences(Block const& _block) { VariableReferencesCounter counter; counter(_block); return std::move(counter.m_references); } -std::map VariableReferencesCounter::countReferences(FunctionDefinition const& _function) +std::map VariableReferencesCounter::countReferences(FunctionDefinition const& _function) { VariableReferencesCounter counter; counter(_function); return std::move(counter.m_references); } -std::map VariableReferencesCounter::countReferences(Expression const& _expression) +std::map VariableReferencesCounter::countReferences(Expression const& _expression) { VariableReferencesCounter counter; counter.visit(_expression); return std::move(counter.m_references); } -std::map VariableReferencesCounter::countReferences(Statement const& _statement) +std::map VariableReferencesCounter::countReferences(Statement const& _statement) { VariableReferencesCounter counter; counter.visit(_statement); @@ -138,9 +138,9 @@ void AssignmentsSinceContinue::operator()(FunctionDefinition const&) yulAssert(false, ""); } -std::set solidity::yul::assignedVariableNames(Block const& _code) +std::set solidity::yul::assignedVariableNames(Block const& _code) { - std::set names; + std::set names; forEach(_code, [&](Assignment const& _assignment) { for (auto const& var: _assignment.variableNames) names.emplace(var.name); @@ -148,9 +148,9 @@ std::set solidity::yul::assignedVariableNames(Block const& _code) return names; } -std::map solidity::yul::allFunctionDefinitions(Block const& _block) +std::map solidity::yul::allFunctionDefinitions(Block const& _block) { - std::map result; + std::map result; forEach(_block, [&](FunctionDefinition const& _function) { result[_function.name] = &_function; }); diff --git a/libyul/optimiser/NameCollector.h b/libyul/optimiser/NameCollector.h index ad18e1e26bb3..0fc2e311ca50 100644 --- a/libyul/optimiser/NameCollector.h +++ b/libyul/optimiser/NameCollector.h @@ -22,6 +22,7 @@ #pragma once #include +#include #include #include @@ -59,9 +60,9 @@ class NameCollector: public ASTWalker void operator()(VariableDeclaration const& _varDecl) override; void operator()(FunctionDefinition const& _funDef) override; - std::set names() const { return m_names; } + std::set names() const { return m_names; } private: - std::set m_names; + std::set m_names; CollectWhat m_collectWhat = VariablesAndFunctions; }; @@ -75,12 +76,12 @@ class ReferencesCounter: public ASTWalker void operator()(Identifier const& _identifier) override; void operator()(FunctionCall const& _funCall) override; - static std::map countReferences(Block const& _block); - static std::map countReferences(FunctionDefinition const& _function); - static std::map countReferences(Expression const& _expression); + static std::map countReferences(Block const& _block); + static std::map countReferences(FunctionDefinition const& _function); + static std::map countReferences(Expression const& _expression); private: - std::map m_references; + std::map m_references; }; /** @@ -92,13 +93,13 @@ class VariableReferencesCounter: public ASTWalker using ASTWalker::operator (); void operator()(Identifier const& _identifier) override; - static std::map countReferences(Block const& _block); - static std::map countReferences(FunctionDefinition const& _function); - static std::map countReferences(Expression const& _expression); - static std::map countReferences(Statement const& _statement); + static std::map countReferences(Block const& _block); + static std::map countReferences(FunctionDefinition const& _function); + static std::map countReferences(Expression const& _expression); + static std::map countReferences(Statement const& _statement); private: - std::map m_references; + std::map m_references; }; /** @@ -117,21 +118,21 @@ class AssignmentsSinceContinue: public ASTWalker void operator()(Assignment const& _assignment) override; void operator()(FunctionDefinition const& _funDef) override; - std::set const& names() const { return m_names; } + std::set const& names() const { return m_names; } bool empty() const noexcept { return m_names.empty(); } private: size_t m_forLoopDepth = 0; bool m_continueFound = false; - std::set m_names; + 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); +std::set assignedVariableNames(Block const& _code); /// @returns all function definitions anywhere in the AST. /// Requires disambiguated source. -std::map allFunctionDefinitions(Block const& _block); +std::map allFunctionDefinitions(Block const& _block); } diff --git a/libyul/optimiser/NameDispenser.cpp b/libyul/optimiser/NameDispenser.cpp index 3a8db5ee449e..c2b6b9847f3c 100644 --- a/libyul/optimiser/NameDispenser.cpp +++ b/libyul/optimiser/NameDispenser.cpp @@ -25,7 +25,6 @@ #include #include #include -#include #include @@ -33,31 +32,31 @@ using namespace solidity; using namespace solidity::yul; using namespace solidity::util; -NameDispenser::NameDispenser(Dialect const& _dialect, Block const& _ast, std::set _reservedNames): +NameDispenser::NameDispenser(Dialect const& _dialect, Block const& _ast, std::set _reservedNames): NameDispenser(_dialect, NameCollector(_ast).names() + _reservedNames) { m_reservedNames = std::move(_reservedNames); } -NameDispenser::NameDispenser(Dialect const& _dialect, std::set _usedNames): +NameDispenser::NameDispenser(Dialect const& _dialect, std::set _usedNames): m_dialect(_dialect), m_usedNames(std::move(_usedNames)) { } -YulString NameDispenser::newName(YulString _nameHint) +YulName NameDispenser::newName(YulName _nameHint) { - YulString name = _nameHint; + YulName name = _nameHint; while (illegalName(name)) { m_counter++; - name = YulString(_nameHint.str() + "_" + std::to_string(m_counter)); + name = YulName(_nameHint.str() + "_" + std::to_string(m_counter)); } m_usedNames.emplace(name); return name; } -bool NameDispenser::illegalName(YulString _name) +bool NameDispenser::illegalName(YulName _name) { return isRestrictedIdentifier(m_dialect, _name) || m_usedNames.count(_name); } diff --git a/libyul/optimiser/NameDispenser.h b/libyul/optimiser/NameDispenser.h index 6e655e416b51..3da50359a764 100644 --- a/libyul/optimiser/NameDispenser.h +++ b/libyul/optimiser/NameDispenser.h @@ -22,7 +22,7 @@ #include -#include +#include #include @@ -40,21 +40,21 @@ class NameDispenser { public: /// Initialize the name dispenser with all the names used in the given AST. - explicit NameDispenser(Dialect const& _dialect, Block const& _ast, std::set _reservedNames = {}); + explicit NameDispenser(Dialect const& _dialect, Block const& _ast, std::set _reservedNames = {}); /// Initialize the name dispenser with the given used names. - explicit NameDispenser(Dialect const& _dialect, std::set _usedNames); + explicit NameDispenser(Dialect const& _dialect, std::set _usedNames); /// @returns a currently unused name that should be similar to _nameHint. - YulString newName(YulString _nameHint); + YulName newName(YulName _nameHint); /// Mark @a _name as used, i.e. the dispenser's newName function will not /// return it. - void markUsed(YulString _name) { m_usedNames.insert(_name); } + void markUsed(YulName _name) { m_usedNames.insert(_name); } - std::set const& usedNames() { return m_usedNames; } + std::set const& usedNames() { return m_usedNames; } /// Returns true if `_name` is either used or is a restricted identifier. - bool illegalName(YulString _name); + bool illegalName(YulName _name); /// Resets `m_usedNames` with *only* the names that are used in the AST. Also resets value of /// `m_counter` to zero. @@ -62,8 +62,8 @@ class NameDispenser private: Dialect const& m_dialect; - std::set m_usedNames; - std::set m_reservedNames; + std::set m_usedNames; + std::set m_reservedNames; size_t m_counter = 0; }; diff --git a/libyul/optimiser/NameDisplacer.cpp b/libyul/optimiser/NameDisplacer.cpp index 4d0d217d8619..fd813fbfc2f1 100644 --- a/libyul/optimiser/NameDisplacer.cpp +++ b/libyul/optimiser/NameDisplacer.cpp @@ -69,14 +69,14 @@ void NameDisplacer::operator()(Block& _block) ASTModifier::operator()(_block); } -void NameDisplacer::checkAndReplaceNew(YulString& _name) +void NameDisplacer::checkAndReplaceNew(YulName& _name) { yulAssert(!m_translations.count(_name), ""); if (m_namesToFree.count(_name)) _name = (m_translations[_name] = m_nameDispenser.newName(_name)); } -void NameDisplacer::checkAndReplace(YulString& _name) const +void NameDisplacer::checkAndReplace(YulName& _name) const { if (m_translations.count(_name)) _name = m_translations.at(_name); diff --git a/libyul/optimiser/NameDisplacer.h b/libyul/optimiser/NameDisplacer.h index 336dd04e42de..3312e203d7ae 100644 --- a/libyul/optimiser/NameDisplacer.h +++ b/libyul/optimiser/NameDisplacer.h @@ -44,12 +44,12 @@ class NameDisplacer: public ASTModifier public: explicit NameDisplacer( NameDispenser& _dispenser, - std::set const& _namesToFree + std::set const& _namesToFree ): m_nameDispenser(_dispenser), m_namesToFree(_namesToFree) { - for (YulString n: _namesToFree) + for (YulName n: _namesToFree) m_nameDispenser.markUsed(n); } @@ -60,17 +60,17 @@ class NameDisplacer: public ASTModifier void operator()(FunctionCall& _funCall) override; void operator()(Block& _block) override; - std::map const& translations() const { return m_translations; } + std::map const& translations() const { return m_translations; } protected: /// Check if the newly introduced identifier @a _name has to be replaced. - void checkAndReplaceNew(YulString& _name); + void checkAndReplaceNew(YulName& _name); /// Replace the identifier @a _name if it is in the translation map. - void checkAndReplace(YulString& _name) const; + void checkAndReplace(YulName& _name) const; NameDispenser& m_nameDispenser; - std::set const& m_namesToFree; - std::map m_translations; + std::set const& m_namesToFree; + std::map m_translations; }; } diff --git a/libyul/optimiser/NameSimplifier.cpp b/libyul/optimiser/NameSimplifier.cpp index f7d732547773..f03a448f0d92 100644 --- a/libyul/optimiser/NameSimplifier.cpp +++ b/libyul/optimiser/NameSimplifier.cpp @@ -19,7 +19,7 @@ #include #include #include -#include +#include #include #include @@ -32,10 +32,10 @@ using namespace solidity::yul; NameSimplifier::NameSimplifier(OptimiserStepContext& _context, Block const& _ast): m_context(_context) { - for (YulString name: _context.reservedIdentifiers) + for (YulName name: _context.reservedIdentifiers) m_translations[name] = name; - for (YulString const& name: NameCollector(_ast).names()) + for (YulName const& name: NameCollector(_ast).names()) findSimplification(name); } @@ -72,7 +72,7 @@ void NameSimplifier::operator()(FunctionCall& _funCall) ASTModifier::operator()(_funCall); } -void NameSimplifier::findSimplification(YulString const& _name) +void NameSimplifier::findSimplification(YulName const& _name) { if (m_translations.count(_name)) return; @@ -102,19 +102,19 @@ void NameSimplifier::findSimplification(YulString const& _name) for (auto const& [pattern, substitute]: replacements) { std::string candidate = regex_replace(name, pattern, substitute); - if (!candidate.empty() && !m_context.dispenser.illegalName(YulString(candidate))) + if (!candidate.empty() && !m_context.dispenser.illegalName(YulName(candidate))) name = candidate; } if (name != _name.str()) { - YulString newName{name}; + YulName newName{name}; m_context.dispenser.markUsed(newName); m_translations[_name] = std::move(newName); } } -void NameSimplifier::translate(YulString& _name) +void NameSimplifier::translate(YulName& _name) { auto it = m_translations.find(_name); if (it != m_translations.end()) diff --git a/libyul/optimiser/NameSimplifier.h b/libyul/optimiser/NameSimplifier.h index 34cf6945115b..848e61f567ac 100644 --- a/libyul/optimiser/NameSimplifier.h +++ b/libyul/optimiser/NameSimplifier.h @@ -20,7 +20,7 @@ #include #include -#include +#include #include #include @@ -62,11 +62,11 @@ class NameSimplifier: public ASTModifier /// Tries to rename a list of variables. void renameVariables(std::vector& _variables); - void findSimplification(YulString const& _name); - void translate(YulString& _name); + void findSimplification(YulName const& _name); + void translate(YulName& _name); OptimiserStepContext& m_context; - std::map m_translations; + std::map m_translations; }; } diff --git a/libyul/optimiser/OptimiserStep.h b/libyul/optimiser/OptimiserStep.h index e3e5fe4c605d..89bfcef814d0 100644 --- a/libyul/optimiser/OptimiserStep.h +++ b/libyul/optimiser/OptimiserStep.h @@ -29,14 +29,13 @@ namespace solidity::yul struct Dialect; struct Block; -class YulString; class NameDispenser; struct OptimiserStepContext { Dialect const& dialect; NameDispenser& dispenser; - std::set const& reservedIdentifiers; + std::set const& reservedIdentifiers; /// The value nullopt represents creation code std::optional expectedExecutionsPerDeployment; }; diff --git a/libyul/optimiser/OptimizerUtilities.cpp b/libyul/optimiser/OptimizerUtilities.cpp index bfa3d888f19b..19f262060fc0 100644 --- a/libyul/optimiser/OptimizerUtilities.cpp +++ b/libyul/optimiser/OptimizerUtilities.cpp @@ -55,12 +55,12 @@ void yul::removeEmptyBlocks(Block& _block) ranges::actions::remove_if(_block.statements, isEmptyBlock); } -bool yul::isRestrictedIdentifier(Dialect const& _dialect, YulString const& _identifier) +bool yul::isRestrictedIdentifier(Dialect const& _dialect, YulName const& _identifier) { return _identifier.empty() || hasLeadingOrTrailingDot(_identifier.str()) || TokenTraits::isYulKeyword(_identifier.str()) || _dialect.reservedIdentifier(_identifier); } -std::optional yul::toEVMInstruction(Dialect const& _dialect, YulString const& _name) +std::optional yul::toEVMInstruction(Dialect const& _dialect, YulName const& _name) { if (auto const* dialect = dynamic_cast(&_dialect)) if (BuiltinFunctionForEVM const* builtin = dialect->builtin(_name)) diff --git a/libyul/optimiser/OptimizerUtilities.h b/libyul/optimiser/OptimizerUtilities.h index cb07f7a53006..911a1be0a812 100644 --- a/libyul/optimiser/OptimizerUtilities.h +++ b/libyul/optimiser/OptimizerUtilities.h @@ -24,7 +24,7 @@ #include #include #include -#include +#include #include #include @@ -45,10 +45,10 @@ void removeEmptyBlocks(Block& _block); /// Returns true if a given literal can not be used as an identifier. /// This includes Yul keywords and builtins of the given dialect. -bool isRestrictedIdentifier(Dialect const& _dialect, YulString const& _identifier); +bool isRestrictedIdentifier(Dialect const& _dialect, YulName const& _identifier); /// Helper function that returns the instruction, if the `_name` is a BuiltinFunction -std::optional toEVMInstruction(Dialect const& _dialect, YulString const& _name); +std::optional toEVMInstruction(Dialect const& _dialect, YulName const& _name); /// Helper function that returns the EVM version from a dialect. /// It returns the default EVM version if dialect is not an EVMDialect. diff --git a/libyul/optimiser/Rematerialiser.cpp b/libyul/optimiser/Rematerialiser.cpp index db6920f2439b..fe33b10a2245 100644 --- a/libyul/optimiser/Rematerialiser.cpp +++ b/libyul/optimiser/Rematerialiser.cpp @@ -31,7 +31,7 @@ using namespace solidity; using namespace solidity::yul; -void Rematerialiser::run(Dialect const& _dialect, Block& _ast, std::set _varsToAlwaysRematerialize, bool _onlySelectedVariables) +void Rematerialiser::run(Dialect const& _dialect, Block& _ast, std::set _varsToAlwaysRematerialize, bool _onlySelectedVariables) { Rematerialiser{_dialect, _ast, std::move(_varsToAlwaysRematerialize), _onlySelectedVariables}(_ast); } @@ -39,7 +39,7 @@ void Rematerialiser::run(Dialect const& _dialect, Block& _ast, std::set _varsToAlwaysRematerialize, + std::set _varsToAlwaysRematerialize, bool _onlySelectedVariables ): DataFlowAnalyzer(_dialect, MemoryAndStorage::Ignore), @@ -54,7 +54,7 @@ void Rematerialiser::visit(Expression& _e) if (std::holds_alternative(_e)) { Identifier& identifier = std::get(_e); - YulString name = identifier.name; + YulName name = identifier.name; if (AssignedValue const* value = variableValue(name)) { assertThrow(value->value, OptimizerException, ""); @@ -93,7 +93,7 @@ void LiteralRematerialiser::visit(Expression& _e) if (std::holds_alternative(_e)) { Identifier& identifier = std::get(_e); - YulString name = identifier.name; + YulName name = identifier.name; if (AssignedValue const* value = variableValue(name)) { assertThrow(value->value, OptimizerException, ""); diff --git a/libyul/optimiser/Rematerialiser.h b/libyul/optimiser/Rematerialiser.h index 9ee5209fdfeb..a482ef53e015 100644 --- a/libyul/optimiser/Rematerialiser.h +++ b/libyul/optimiser/Rematerialiser.h @@ -50,7 +50,7 @@ class Rematerialiser: public DataFlowAnalyzer static void run( Dialect const& _dialect, Block& _ast, - std::set _varsToAlwaysRematerialize = {}, + std::set _varsToAlwaysRematerialize = {}, bool _onlySelectedVariables = false ); @@ -58,7 +58,7 @@ class Rematerialiser: public DataFlowAnalyzer Rematerialiser( Dialect const& _dialect, Block& _ast, - std::set _varsToAlwaysRematerialize = {}, + std::set _varsToAlwaysRematerialize = {}, bool _onlySelectedVariables = false ); @@ -67,8 +67,8 @@ class Rematerialiser: public DataFlowAnalyzer using ASTModifier::visit; void visit(Expression& _e) override; - std::map m_referenceCounts; - std::set m_varsToAlwaysRematerialize; + std::map m_referenceCounts; + std::set m_varsToAlwaysRematerialize; bool m_onlySelectedVariables = false; }; diff --git a/libyul/optimiser/SSATransform.cpp b/libyul/optimiser/SSATransform.cpp index dba2f6f04610..80abdf7e6516 100644 --- a/libyul/optimiser/SSATransform.cpp +++ b/libyul/optimiser/SSATransform.cpp @@ -46,7 +46,7 @@ class IntroduceSSA: public ASTModifier public: explicit IntroduceSSA( NameDispenser& _nameDispenser, - std::set const& _variablesToReplace, + std::set const& _variablesToReplace, TypeInfo& _typeInfo ): m_nameDispenser(_nameDispenser), @@ -58,7 +58,7 @@ class IntroduceSSA: public ASTModifier private: NameDispenser& m_nameDispenser; - std::set const& m_variablesToReplace; + std::set const& m_variablesToReplace; TypeInfo const& m_typeInfo; }; @@ -90,8 +90,8 @@ void IntroduceSSA::operator()(Block& _block) TypedNameList newVariables; for (auto const& var: varDecl.variables) { - YulString oldName = var.name; - YulString newName = m_nameDispenser.newName(oldName); + YulName oldName = var.name; + YulName newName = m_nameDispenser.newName(oldName); newVariables.emplace_back(TypedName{debugData, newName, var.type}); statements.emplace_back(VariableDeclaration{ debugData, @@ -117,8 +117,8 @@ void IntroduceSSA::operator()(Block& _block) TypedNameList newVariables; for (auto const& var: assignment.variableNames) { - YulString oldName = var.name; - YulString newName = m_nameDispenser.newName(oldName); + YulName oldName = var.name; + YulName newName = m_nameDispenser.newName(oldName); newVariables.emplace_back(TypedName{debugData, newName, m_typeInfo.typeOfVariable(oldName) @@ -148,7 +148,7 @@ class IntroduceControlFlowSSA: public ASTModifier public: explicit IntroduceControlFlowSSA( NameDispenser& _nameDispenser, - std::set const& _variablesToReplace, + std::set const& _variablesToReplace, TypeInfo const& _typeInfo ): m_nameDispenser(_nameDispenser), @@ -163,19 +163,19 @@ class IntroduceControlFlowSSA: public ASTModifier private: NameDispenser& m_nameDispenser; - std::set const& m_variablesToReplace; + std::set const& m_variablesToReplace; /// Variables (that are to be replaced) currently in scope. - std::set m_variablesInScope; + std::set m_variablesInScope; /// Variables that do not have a specific value. - util::UniqueVector m_variablesToReassign; + util::UniqueVector m_variablesToReassign; TypeInfo const& m_typeInfo; }; void IntroduceControlFlowSSA::operator()(FunctionDefinition& _function) { - std::set varsInScope; + std::set varsInScope; std::swap(varsInScope, m_variablesInScope); - util::UniqueVector toReassign; + util::UniqueVector toReassign; std::swap(toReassign, m_variablesToReassign); for (auto const& param: _function.parameters) @@ -207,7 +207,7 @@ void IntroduceControlFlowSSA::operator()(Switch& _switch) { yulAssert(m_variablesToReassign.empty(), ""); - util::UniqueVector toReassign; + util::UniqueVector toReassign; for (auto& c: _switch.cases) { (*this)(c.body); @@ -219,17 +219,17 @@ void IntroduceControlFlowSSA::operator()(Switch& _switch) void IntroduceControlFlowSSA::operator()(Block& _block) { - util::UniqueVector variablesDeclaredHere; - util::UniqueVector assignedVariables; + util::UniqueVector variablesDeclaredHere; + util::UniqueVector assignedVariables; util::iterateReplacing( _block.statements, [&](Statement& _s) -> std::optional> { std::vector toPrepend; - for (YulString toReassign: m_variablesToReassign) + for (YulName toReassign: m_variablesToReassign) { - YulString newName = m_nameDispenser.newName(toReassign); + YulName newName = m_nameDispenser.newName(toReassign); toPrepend.emplace_back(VariableDeclaration{ debugDataOf(_s), {TypedName{debugDataOf(_s), newName, m_typeInfo.typeOfVariable(toReassign)}}, @@ -281,7 +281,7 @@ void IntroduceControlFlowSSA::operator()(Block& _block) class PropagateValues: public ASTModifier { public: - explicit PropagateValues(std::set const& _variablesToReplace): + explicit PropagateValues(std::set const& _variablesToReplace): m_variablesToReplace(_variablesToReplace) { } @@ -294,9 +294,9 @@ class PropagateValues: public ASTModifier private: /// This is a set of all variables that are assigned to anywhere in the code. /// Variables that are only declared but never re-assigned are not touched. - std::set const& m_variablesToReplace; - std::map m_currentVariableValues; - std::set m_clearAtEndOfBlock; + std::set const& m_variablesToReplace; + std::map m_currentVariableValues; + std::set m_clearAtEndOfBlock; }; void PropagateValues::operator()(Identifier& _identifier) @@ -312,7 +312,7 @@ void PropagateValues::operator()(VariableDeclaration& _varDecl) if (_varDecl.variables.size() != 1) return; - YulString variable = _varDecl.variables.front().name; + YulName variable = _varDecl.variables.front().name; if (m_variablesToReplace.count(variable)) { // `let a := a_1` - regular declaration of non-SSA variable @@ -323,7 +323,7 @@ void PropagateValues::operator()(VariableDeclaration& _varDecl) else if (_varDecl.value && std::holds_alternative(*_varDecl.value)) { // `let a_1 := a` - assignment to SSA variable after a branch. - YulString value = std::get(*_varDecl.value).name; + YulName value = std::get(*_varDecl.value).name; if (m_variablesToReplace.count(value)) { // This is safe because `a_1` is not a "variable to replace" and thus @@ -341,7 +341,7 @@ void PropagateValues::operator()(Assignment& _assignment) if (_assignment.variableNames.size() != 1) return; - YulString name = _assignment.variableNames.front().name; + YulName name = _assignment.variableNames.front().name; if (!m_variablesToReplace.count(name)) return; @@ -364,7 +364,7 @@ void PropagateValues::operator()(ForLoop& _for) void PropagateValues::operator()(Block& _block) { - std::set clearAtParentBlock = std::move(m_clearAtEndOfBlock); + std::set clearAtParentBlock = std::move(m_clearAtEndOfBlock); m_clearAtEndOfBlock.clear(); ASTModifier::operator()(_block); @@ -380,7 +380,7 @@ void PropagateValues::operator()(Block& _block) void SSATransform::run(OptimiserStepContext& _context, Block& _ast) { TypeInfo typeInfo(_context.dialect, _ast); - std::set assignedVariables = assignedVariableNames(_ast); + std::set assignedVariables = assignedVariableNames(_ast); IntroduceSSA{_context.dispenser, assignedVariables, typeInfo}(_ast); IntroduceControlFlowSSA{_context.dispenser, assignedVariables, typeInfo}(_ast); PropagateValues{assignedVariables}(_ast); diff --git a/libyul/optimiser/SSAValueTracker.cpp b/libyul/optimiser/SSAValueTracker.cpp index 1d25cb54b514..d39ce4b8d263 100644 --- a/libyul/optimiser/SSAValueTracker.cpp +++ b/libyul/optimiser/SSAValueTracker.cpp @@ -49,17 +49,17 @@ void SSAValueTracker::operator()(VariableDeclaration const& _varDecl) setValue(_varDecl.variables.front().name, _varDecl.value.get()); } -std::set SSAValueTracker::ssaVariables(Block const& _ast) +std::set SSAValueTracker::ssaVariables(Block const& _ast) { SSAValueTracker t; t(_ast); - std::set ssaVars; + std::set ssaVars; for (auto const& value: t.values()) ssaVars.insert(value.first); return ssaVars; } -void SSAValueTracker::setValue(YulString _name, Expression const* _value) +void SSAValueTracker::setValue(YulName _name, Expression const* _value) { assertThrow( m_values.count(_name) == 0, diff --git a/libyul/optimiser/SSAValueTracker.h b/libyul/optimiser/SSAValueTracker.h index 5a7eee5124b4..0196ecc40e99 100644 --- a/libyul/optimiser/SSAValueTracker.h +++ b/libyul/optimiser/SSAValueTracker.h @@ -47,18 +47,18 @@ class SSAValueTracker: public ASTWalker void operator()(VariableDeclaration const& _varDecl) override; void operator()(Assignment const& _assignment) override; - std::map const& values() const { return m_values; } - Expression const* value(YulString _name) const { return m_values.at(_name); } + std::map const& values() const { return m_values; } + Expression const* value(YulName _name) const { return m_values.at(_name); } - static std::set ssaVariables(Block const& _ast); + static std::set ssaVariables(Block const& _ast); private: - void setValue(YulString _name, Expression const* _value); + void setValue(YulName _name, Expression const* _value); /// Special expression whose address will be used in m_values. - /// YulString does not need to be reset because SSAValueTracker is short-lived. + /// YulName does not need to be reset because SSAValueTracker is short-lived. Expression const m_zero{Literal{{}, LiteralKind::Number, LiteralValue(u256{0}), {}}}; - std::map m_values; + std::map m_values; }; } diff --git a/libyul/optimiser/Semantics.cpp b/libyul/optimiser/Semantics.cpp index 5d375b1454cb..7dbbb676b43b 100644 --- a/libyul/optimiser/Semantics.cpp +++ b/libyul/optimiser/Semantics.cpp @@ -40,7 +40,7 @@ using namespace solidity::yul; SideEffectsCollector::SideEffectsCollector( Dialect const& _dialect, Expression const& _expression, - std::map const* _functionSideEffects + std::map const* _functionSideEffects ): SideEffectsCollector(_dialect, _functionSideEffects) { @@ -56,7 +56,7 @@ SideEffectsCollector::SideEffectsCollector(Dialect const& _dialect, Statement co SideEffectsCollector::SideEffectsCollector( Dialect const& _dialect, Block const& _ast, - std::map const* _functionSideEffects + std::map const* _functionSideEffects ): SideEffectsCollector(_dialect, _functionSideEffects) { @@ -66,7 +66,7 @@ SideEffectsCollector::SideEffectsCollector( SideEffectsCollector::SideEffectsCollector( Dialect const& _dialect, ForLoop const& _ast, - std::map const* _functionSideEffects + std::map const* _functionSideEffects ): SideEffectsCollector(_dialect, _functionSideEffects) { @@ -77,7 +77,7 @@ void SideEffectsCollector::operator()(FunctionCall const& _functionCall) { ASTWalker::operator()(_functionCall); - YulString functionName = _functionCall.functionName.name; + YulName functionName = _functionCall.functionName.name; if (BuiltinFunction const* f = m_dialect.builtin(functionName)) m_sideEffects += f->sideEffects; else if (m_functionSideEffects && m_functionSideEffects->count(functionName)) @@ -115,7 +115,7 @@ void MSizeFinder::operator()(FunctionCall const& _functionCall) m_msizeFound = true; } -std::map SideEffectsPropagator::sideEffects( +std::map SideEffectsPropagator::sideEffects( Dialect const& _dialect, CallGraph const& _directCallGraph ) @@ -126,7 +126,7 @@ std::map SideEffectsPropagator::sideEffects( // In the future, we should refine that, because the property // is actually a bit different from "not movable". - std::map ret; + std::map ret; for (auto const& function: _directCallGraph.functionsWithLoops + _directCallGraph.recursiveFunctions()) { ret[function].movable = false; @@ -137,9 +137,9 @@ std::map SideEffectsPropagator::sideEffects( for (auto const& call: _directCallGraph.functionCalls) { - YulString funName = call.first; + YulName funName = call.first; SideEffects sideEffects; - auto _visit = [&, visited = std::set{}](YulString _function, auto&& _recurse) mutable { + auto _visit = [&, visited = std::set{}](YulName _function, auto&& _recurse) mutable { if (!visited.insert(_function).second) return; if (sideEffects == SideEffects::worst()) @@ -150,7 +150,7 @@ std::map SideEffectsPropagator::sideEffects( { if (ret.count(_function)) sideEffects += ret[_function]; - for (YulString callee: _directCallGraph.functionCalls.at(_function)) + for (YulName callee: _directCallGraph.functionCalls.at(_function)) _recurse(callee, _recurse); } }; diff --git a/libyul/optimiser/Semantics.h b/libyul/optimiser/Semantics.h index df8ae17a58e1..1d0018897c00 100644 --- a/libyul/optimiser/Semantics.h +++ b/libyul/optimiser/Semantics.h @@ -42,23 +42,23 @@ class SideEffectsCollector: public ASTWalker public: explicit SideEffectsCollector( Dialect const& _dialect, - std::map const* _functionSideEffects = nullptr + std::map const* _functionSideEffects = nullptr ): m_dialect(_dialect), m_functionSideEffects(_functionSideEffects) {} SideEffectsCollector( Dialect const& _dialect, Expression const& _expression, - std::map const* _functionSideEffects = nullptr + std::map const* _functionSideEffects = nullptr ); SideEffectsCollector(Dialect const& _dialect, Statement const& _statement); SideEffectsCollector( Dialect const& _dialect, Block const& _ast, - std::map const* _functionSideEffects = nullptr + std::map const* _functionSideEffects = nullptr ); SideEffectsCollector( Dialect const& _dialect, ForLoop const& _ast, - std::map const* _functionSideEffects = nullptr + std::map const* _functionSideEffects = nullptr ); using ASTWalker::operator(); @@ -117,7 +117,7 @@ class SideEffectsCollector: public ASTWalker private: Dialect const& m_dialect; - std::map const* m_functionSideEffects = nullptr; + std::map const* m_functionSideEffects = nullptr; SideEffects m_sideEffects; }; @@ -130,7 +130,7 @@ class SideEffectsCollector: public ASTWalker class SideEffectsPropagator { public: - static std::map sideEffects( + static std::map sideEffects( Dialect const& _dialect, CallGraph const& _directCallGraph ); @@ -195,7 +195,7 @@ class MovableChecker: public SideEffectsCollector public: explicit MovableChecker( Dialect const& _dialect, - std::map const* _functionSideEffects = nullptr + std::map const* _functionSideEffects = nullptr ): SideEffectsCollector(_dialect, _functionSideEffects) {} MovableChecker(Dialect const& _dialect, Expression const& _expression); @@ -205,11 +205,11 @@ class MovableChecker: public SideEffectsCollector void visit(Statement const&) override; using ASTWalker::visit; - std::set const& referencedVariables() const { return m_variableReferences; } + std::set const& referencedVariables() const { return m_variableReferences; } private: /// Which variables the current expression references. - std::set m_variableReferences; + std::set m_variableReferences; }; struct ControlFlowSideEffects; @@ -231,7 +231,7 @@ class TerminationFinder TerminationFinder( Dialect const& _dialect, - std::map const* _functionSideEffects = nullptr + std::map const* _functionSideEffects = nullptr ): m_dialect(_dialect), m_functionSideEffects(_functionSideEffects) {} /// @returns the index of the first statement in the provided sequence @@ -256,7 +256,7 @@ class TerminationFinder private: Dialect const& m_dialect; - std::map const* m_functionSideEffects; + std::map const* m_functionSideEffects; }; } diff --git a/libyul/optimiser/SimplificationRules.cpp b/libyul/optimiser/SimplificationRules.cpp index e2d46832906e..03e4ccdd0eda 100644 --- a/libyul/optimiser/SimplificationRules.cpp +++ b/libyul/optimiser/SimplificationRules.cpp @@ -40,7 +40,7 @@ using namespace solidity::yul; SimplificationRules::Rule const* SimplificationRules::findFirstMatch( Expression const& _expr, Dialect const& _dialect, - std::function const& _ssaValues + std::function const& _ssaValues ) { auto instruction = instructionAndArguments(_dialect, _expr); @@ -137,7 +137,7 @@ void Pattern::setMatchGroup(unsigned _group, std::map const& _ssaValues + std::function const& _ssaValues ) const { Expression const* expr = &_expr; @@ -146,7 +146,7 @@ bool Pattern::matches( // Do not do it for "Any" because we can check identity better for variables. if (m_kind != PatternKind::Any && std::holds_alternative(_expr)) { - YulString varName = std::get(_expr).name; + YulName varName = std::get(_expr).name; if (AssignedValue const* value = _ssaValues(varName)) if (Expression const* new_expr = value->value) expr = new_expr; @@ -252,7 +252,7 @@ Expression Pattern::toExpression(langutil::DebugData::ConstPtr const& _debugData std::string name = util::toLower(instructionInfo(m_instruction, _evmVersion).name); return FunctionCall{_debugData, - Identifier{_debugData, YulString{name}}, + Identifier{_debugData, YulName{name}}, std::move(arguments) }; } diff --git a/libyul/optimiser/SimplificationRules.h b/libyul/optimiser/SimplificationRules.h index 5e498bd5c9a4..9362ee8557ec 100644 --- a/libyul/optimiser/SimplificationRules.h +++ b/libyul/optimiser/SimplificationRules.h @@ -24,7 +24,7 @@ #include #include -#include +#include #include #include @@ -64,7 +64,7 @@ class SimplificationRules static Rule const* findFirstMatch( Expression const& _expr, Dialect const& _dialect, - std::function const& _ssaValues + std::function const& _ssaValues ); /// Checks whether the rulelist is non-empty. This is usually enforced @@ -121,7 +121,7 @@ class Pattern bool matches( Expression const& _expr, Dialect const& _dialect, - std::function const& _ssaValues + std::function const& _ssaValues ) const; std::vector arguments() const { return m_arguments; } diff --git a/libyul/optimiser/StackCompressor.cpp b/libyul/optimiser/StackCompressor.cpp index 58552147a608..23d47b6ee554 100644 --- a/libyul/optimiser/StackCompressor.cpp +++ b/libyul/optimiser/StackCompressor.cpp @@ -60,9 +60,9 @@ class RematCandidateSelector: public DataFlowAnalyzer /// @returns a map from function name to rematerialisation costs to a vector of variables to rematerialise /// and variables that occur in their expression. /// While the map is sorted by cost, the contained vectors are sorted by the order of occurrence. - std::map>> candidates() + std::map>> candidates() { - std::map>> cand; + std::map>> cand; for (auto const& [functionName, candidate]: m_candidates) { if (size_t const* cost = util::valueOrNullptr(m_expressionCodeCost, candidate)) @@ -88,7 +88,7 @@ class RematCandidateSelector: public DataFlowAnalyzer DataFlowAnalyzer::operator()(_varDecl); if (_varDecl.variables.size() == 1) { - YulString varName = _varDecl.variables.front().name; + YulName varName = _varDecl.variables.front().name; if (AssignedValue const* value = variableValue(varName)) { yulAssert(!m_expressionCodeCost.count(varName), ""); @@ -111,7 +111,7 @@ class RematCandidateSelector: public DataFlowAnalyzer { if (std::holds_alternative(_e)) { - YulString name = std::get(_e).name; + YulName name = std::get(_e).name; if (m_expressionCodeCost.count(name)) { if (!variableValue(name)) @@ -124,29 +124,29 @@ class RematCandidateSelector: public DataFlowAnalyzer } /// Remove the variable from the candidate set. - void rematImpossible(YulString _variable) + void rematImpossible(YulName _variable) { m_numReferences.erase(_variable); m_expressionCodeCost.erase(_variable); } - YulString m_currentFunctionName = {}; + YulName m_currentFunctionName = {}; /// All candidate variables by function name, in order of occurrence. - std::vector> m_candidates; + std::vector> m_candidates; /// Candidate variables and the code cost of their value. - std::map m_expressionCodeCost; + std::map m_expressionCodeCost; /// Number of references to each candidate variable. - std::map m_numReferences; + std::map m_numReferences; }; /// Selects at most @a _numVariables among @a _candidates. -std::set chooseVarsToEliminate( - std::map> const& _candidates, +std::set chooseVarsToEliminate( + std::map> const& _candidates, size_t _numVariables ) { - std::set varsToEliminate; + std::set varsToEliminate; for (auto&& [cost, candidates]: _candidates) for (auto&& candidate: candidates) { @@ -160,15 +160,15 @@ std::set chooseVarsToEliminate( void eliminateVariables( Dialect const& _dialect, Block& _ast, - std::map const& _numVariables, + std::map const& _numVariables, bool _allowMSizeOptimization ) { RematCandidateSelector selector{_dialect}; selector(_ast); - std::map>> candidates = selector.candidates(); + std::map>> candidates = selector.candidates(); - std::set varsToEliminate; + std::set varsToEliminate; for (auto const& [functionName, numVariables]: _numVariables) { yulAssert(numVariables > 0); @@ -177,14 +177,14 @@ void eliminateVariables( Rematerialiser::run(_dialect, _ast, std::move(varsToEliminate)); // Do not remove functions. - std::set allFunctions = NameCollector{_ast, NameCollector::OnlyFunctions}.names(); + std::set allFunctions = NameCollector{_ast, NameCollector::OnlyFunctions}.names(); UnusedPruner::runUntilStabilised(_dialect, _ast, _allowMSizeOptimization, nullptr, allFunctions); } void eliminateVariablesOptimizedCodegen( Dialect const& _dialect, Block& _ast, - std::map> const& _unreachables, + std::map> const& _unreachables, bool _allowMSizeOptimization ) { @@ -194,19 +194,19 @@ void eliminateVariablesOptimizedCodegen( RematCandidateSelector selector{_dialect}; selector(_ast); - std::map candidates; + std::map candidates; for (auto const& [functionName, candidatesInFunction]: selector.candidates()) for (auto [cost, candidatesWithCost]: candidatesInFunction) for (auto candidate: candidatesWithCost) candidates[candidate] = cost; - std::set varsToEliminate; + std::set varsToEliminate; // TODO: this currently ignores the fact that variables may reference other variables we want to eliminate. for (auto const& [functionName, unreachables]: _unreachables) for (auto const& unreachable: unreachables) { - std::map> suitableCandidates; + std::map> suitableCandidates; size_t neededSlots = unreachable.deficit; for (auto varName: unreachable.variableChoices) { @@ -229,7 +229,7 @@ void eliminateVariablesOptimizedCodegen( } Rematerialiser::run(_dialect, _ast, std::move(varsToEliminate), true); // Do not remove functions. - std::set allFunctions = NameCollector{_ast, NameCollector::OnlyFunctions}.names(); + std::set allFunctions = NameCollector{_ast, NameCollector::OnlyFunctions}.names(); UnusedPruner::runUntilStabilised(_dialect, _ast, _allowMSizeOptimization, nullptr, allFunctions); } @@ -268,7 +268,7 @@ bool StackCompressor::run( else for (size_t iterations = 0; iterations < _maxIterations; iterations++) { - std::map stackSurplus = CompilabilityChecker(_dialect, _object, _optimizeStackAllocation).stackDeficit; + std::map stackSurplus = CompilabilityChecker(_dialect, _object, _optimizeStackAllocation).stackDeficit; if (stackSurplus.empty()) return true; eliminateVariables( diff --git a/libyul/optimiser/StackLimitEvader.cpp b/libyul/optimiser/StackLimitEvader.cpp index 0310858a187b..24712938f03b 100644 --- a/libyul/optimiser/StackLimitEvader.cpp +++ b/libyul/optimiser/StackLimitEvader.cpp @@ -56,7 +56,7 @@ namespace */ struct MemoryOffsetAllocator { - uint64_t run(YulString _function = YulString{}) + uint64_t run(YulName _function = YulName{}) { if (slotsRequiredForFunction.count(_function)) return slotsRequiredForFunction[_function]; @@ -66,7 +66,7 @@ struct MemoryOffsetAllocator uint64_t requiredSlots = 0; if (callGraph.count(_function)) - for (YulString child: callGraph.at(_function)) + for (YulName child: callGraph.at(_function)) requiredSlots = std::max(run(child), requiredSlots); if (auto const* unreachables = util::valueOrNullptr(unreachableVariables, _function)) @@ -84,7 +84,7 @@ struct MemoryOffsetAllocator // Assign slots for all variables that become unreachable in the function body, if the above did not // assign a slot for them already. - for (YulString variable: *unreachables) + for (YulName variable: *unreachables) // The empty case is a function with too many arguments or return values, // which was already handled above. if (!variable.empty() && !slotAllocations.count(variable)) @@ -96,16 +96,16 @@ struct MemoryOffsetAllocator /// Maps function names to the set of unreachable variables in that function. /// An empty variable name means that the function has too many arguments or return variables. - std::map> const& unreachableVariables; + std::map> const& unreachableVariables; /// The graph of immediate function calls of all functions. - std::map> const& callGraph; + std::map> const& callGraph; /// Maps the name of each user-defined function to its definition. - std::map const& functionDefinitions; + std::map const& functionDefinitions; /// Maps variable names to the memory slot the respective variable is assigned. - std::map slotAllocations{}; + std::map slotAllocations{}; /// Maps function names to the number of memory slots the respective function requires. - std::map slotsRequiredForFunction{}; + std::map slotsRequiredForFunction{}; }; u256 literalArgumentValue(FunctionCall const& _call) @@ -145,10 +145,10 @@ void StackLimitEvader::run( void StackLimitEvader::run( OptimiserStepContext& _context, Object& _object, - std::map> const& _stackTooDeepErrors + std::map> const& _stackTooDeepErrors ) { - std::map> unreachableVariables; + std::map> unreachableVariables; for (auto&& [function, stackTooDeepErrors]: _stackTooDeepErrors) { auto& unreachables = unreachableVariables[function]; @@ -164,7 +164,7 @@ void StackLimitEvader::run( void StackLimitEvader::run( OptimiserStepContext& _context, Object& _object, - std::map> const& _unreachableVariables + std::map> const& _unreachableVariables ) { yulAssert(_object.code, ""); @@ -174,10 +174,7 @@ void StackLimitEvader::run( "StackLimitEvader can only be run on objects using the EVMDialect with object access." ); - std::vector memoryGuardCalls = findFunctionCalls( - *_object.code, - "memoryguard"_yulstring - ); + std::vector memoryGuardCalls = findFunctionCalls(*_object.code, "memoryguard"_yulname); // Do not optimise, if no ``memoryguard`` call is found. if (memoryGuardCalls.empty()) return; @@ -193,11 +190,11 @@ void StackLimitEvader::run( CallGraph callGraph = CallGraphGenerator::callGraph(*_object.code); // We cannot move variables in recursive functions to fixed memory offsets. - for (YulString function: callGraph.recursiveFunctions()) + for (YulName function: callGraph.recursiveFunctions()) if (_unreachableVariables.count(function)) return; - std::map functionDefinitions = allFunctionDefinitions(*_object.code); + std::map functionDefinitions = allFunctionDefinitions(*_object.code); MemoryOffsetAllocator memoryOffsetAllocator{_unreachableVariables, callGraph.functionCalls, functionDefinitions}; uint64_t requiredSlots = memoryOffsetAllocator.run(); @@ -206,7 +203,7 @@ void StackLimitEvader::run( StackToMemoryMover::run(_context, reservedMemory, memoryOffsetAllocator.slotAllocations, requiredSlots, *_object.code); reservedMemory += 32 * requiredSlots; - for (FunctionCall* memoryGuardCall: findFunctionCalls(*_object.code, "memoryguard"_yulstring)) + for (FunctionCall* memoryGuardCall: findFunctionCalls(*_object.code, "memoryguard"_yulname)) { Literal* literal = std::get_if(&memoryGuardCall->arguments.front()); yulAssert(literal && literal->kind == LiteralKind::Number, ""); diff --git a/libyul/optimiser/StackLimitEvader.h b/libyul/optimiser/StackLimitEvader.h index 025553200f05..0411f05735bc 100644 --- a/libyul/optimiser/StackLimitEvader.h +++ b/libyul/optimiser/StackLimitEvader.h @@ -60,7 +60,7 @@ class StackLimitEvader static void run( OptimiserStepContext& _context, Object& _object, - std::map> const& _unreachableVariables + std::map> const& _unreachableVariables ); /// @a _stackTooDeepErrors can be determined by the StackLayoutGenerator. /// Can only be run on the EVM dialect with objects. @@ -70,7 +70,7 @@ class StackLimitEvader static void run( OptimiserStepContext& _context, Object& _object, - std::map> const& _stackTooDeepErrors + 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. diff --git a/libyul/optimiser/StackToMemoryMover.cpp b/libyul/optimiser/StackToMemoryMover.cpp index dbf3183fb420..7ec57903482f 100644 --- a/libyul/optimiser/StackToMemoryMover.cpp +++ b/libyul/optimiser/StackToMemoryMover.cpp @@ -77,7 +77,7 @@ FunctionCall generateMemoryLoad(Dialect const& _dialect, langutil::DebugData::Co void StackToMemoryMover::run( OptimiserStepContext& _context, u256 _reservedMemory, - std::map const& _memorySlots, + std::map const& _memorySlots, uint64_t _numRequiredSlots, Block& _block ) @@ -88,10 +88,10 @@ void StackToMemoryMover::run( memoryOffsetTracker, util::applyMap( allFunctionDefinitions(_block), - util::mapTuple([](YulString _name, FunctionDefinition const* _funDef) { + util::mapTuple([](YulName _name, FunctionDefinition const* _funDef) { return make_pair(_name, _funDef->returnVariables); }), - std::map{} + std::map{} ) ); stackToMemoryMover(_block); @@ -101,7 +101,7 @@ void StackToMemoryMover::run( StackToMemoryMover::StackToMemoryMover( OptimiserStepContext& _context, VariableMemoryOffsetTracker const& _memoryOffsetTracker, - std::map _functionReturnVariables + std::map _functionReturnVariables ): m_context(_context), m_memoryOffsetTracker(_memoryOffsetTracker), @@ -150,7 +150,7 @@ void StackToMemoryMover::operator()(FunctionDefinition& _functionDefinition) std::not_fn(m_memoryOffsetTracker) ) | ranges::to; // Generate new function without return variable and with only the non-moved parameters. - YulString newFunctionName = m_context.dispenser.newName(_functionDefinition.name); + YulName newFunctionName = m_context.dispenser.newName(_functionDefinition.name); m_newFunctionDefinitions.emplace_back(FunctionDefinition{ _functionDefinition.debugData, newFunctionName, @@ -159,7 +159,7 @@ void StackToMemoryMover::operator()(FunctionDefinition& _functionDefinition) std::move(_functionDefinition.body) }); // Generate new names for the arguments to maintain disambiguation. - std::map newArgumentNames; + std::map newArgumentNames; for (TypedName const& _var: stackParameters) newArgumentNames[_var.name] = m_context.dispenser.newName(_var.name); for (auto& parameter: _functionDefinition.parameters) @@ -255,7 +255,7 @@ void StackToMemoryMover::operator()(Block& _block) rhs = std::make_unique(generateMemoryLoad(m_context.dialect, debugData, *rhsSlot)); else { - YulString tempVarName = m_nameDispenser.newName(lhsVar.name); + YulName tempVarName = m_nameDispenser.newName(lhsVar.name); tempDecl.variables.emplace_back(TypedName{lhsVar.debugData, tempVarName, {}}); rhs = std::make_unique(Identifier{debugData, tempVarName}); } @@ -309,7 +309,7 @@ void StackToMemoryMover::visit(Expression& _expression) _expression = generateMemoryLoad(m_context.dialect, identifier->debugData, *offset); } -std::optional StackToMemoryMover::VariableMemoryOffsetTracker::operator()(YulString const& _variable) const +std::optional StackToMemoryMover::VariableMemoryOffsetTracker::operator()(YulName const& _variable) const { if (m_memorySlots.count(_variable)) { diff --git a/libyul/optimiser/StackToMemoryMover.h b/libyul/optimiser/StackToMemoryMover.h index 79c7276ede93..7392660311bf 100644 --- a/libyul/optimiser/StackToMemoryMover.h +++ b/libyul/optimiser/StackToMemoryMover.h @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -142,7 +143,7 @@ class StackToMemoryMover: ASTModifier static void run( OptimiserStepContext& _context, u256 _reservedMemory, - std::map const& _memorySlots, + std::map const& _memorySlots, uint64_t _numRequiredSlots, Block& _block ); @@ -158,42 +159,42 @@ class StackToMemoryMover: ASTModifier public: VariableMemoryOffsetTracker( u256 _reservedMemory, - std::map const& _memorySlots, + std::map const& _memorySlots, uint64_t _numRequiredSlots ): m_reservedMemory(_reservedMemory), m_memorySlots(_memorySlots), m_numRequiredSlots(_numRequiredSlots) {} - /// @returns a YulString containing the memory offset to be assigned to @a _variable as number literal + /// @returns a YulName containing the memory offset to be assigned to @a _variable as number literal /// or std::nullopt if the variable should not be moved. - std::optional operator()(YulString const& _variable) const; - /// @returns a YulString containing the memory offset to be assigned to @a _variable as number literal + std::optional operator()(YulName const& _variable) const; + /// @returns a YulName containing the memory offset to be assigned to @a _variable as number literal /// or std::nullopt if the variable should not be moved. std::optional operator()(TypedName const& _variable) const; - /// @returns a YulString containing the memory offset to be assigned to @a _variable as number literal + /// @returns a YulName containing the memory offset to be assigned to @a _variable as number literal /// or std::nullopt if the variable should not be moved. std::optional operator()(Identifier const& _variable) const; private: u256 m_reservedMemory; - std::map const& m_memorySlots; + std::map const& m_memorySlots; uint64_t m_numRequiredSlots = 0; }; struct FunctionMoveInfo { - std::vector> returnVariableSlots; + std::vector> returnVariableSlots; }; StackToMemoryMover( OptimiserStepContext& _context, VariableMemoryOffsetTracker const& _memoryOffsetTracker, - std::map> _functionReturnVariables + std::map> _functionReturnVariables ); OptimiserStepContext& m_context; VariableMemoryOffsetTracker const& m_memoryOffsetTracker; NameDispenser& m_nameDispenser; /// Map from function names to the return variables of the function with that name. - std::map> m_functionReturnVariables; + std::map> m_functionReturnVariables; /// List of functions generated while running this step that are to be appended to the code in the end. std::list m_newFunctionDefinitions; }; diff --git a/libyul/optimiser/Substitution.cpp b/libyul/optimiser/Substitution.cpp index b2d4d469e171..5baec51e34a6 100644 --- a/libyul/optimiser/Substitution.cpp +++ b/libyul/optimiser/Substitution.cpp @@ -30,7 +30,7 @@ Expression Substitution::translate(Expression const& _expression) { if (std::holds_alternative(_expression)) { - YulString name = std::get(_expression).name; + YulName name = std::get(_expression).name; if (m_substitutions.count(name)) // No recursive substitution return ASTCopier().translate(*m_substitutions.at(name)); diff --git a/libyul/optimiser/Substitution.h b/libyul/optimiser/Substitution.h index f76dcc72ea47..2d4ccffc0148 100644 --- a/libyul/optimiser/Substitution.h +++ b/libyul/optimiser/Substitution.h @@ -22,7 +22,7 @@ #pragma once #include -#include +#include #include @@ -35,13 +35,13 @@ namespace solidity::yul class Substitution: public ASTCopier { public: - Substitution(std::map const& _substitutions): + Substitution(std::map const& _substitutions): m_substitutions(_substitutions) {} Expression translate(Expression const& _expression) override; private: - std::map const& m_substitutions; + std::map const& m_substitutions; }; } diff --git a/libyul/optimiser/Suite.cpp b/libyul/optimiser/Suite.cpp index 83bc0370092b..c4004948c838 100644 --- a/libyul/optimiser/Suite.cpp +++ b/libyul/optimiser/Suite.cpp @@ -141,7 +141,7 @@ void OptimiserSuite::run( std::string_view _optimisationSequence, std::string_view _optimisationCleanupSequence, std::optional _expectedExecutionsPerDeployment, - std::set const& _externallyUsedIdentifiers + std::set const& _externallyUsedIdentifiers ) { EVMDialect const* evmDialect = dynamic_cast(&_dialect); @@ -150,7 +150,7 @@ void OptimiserSuite::run( evmDialect && evmDialect->evmVersion().canOverchargeGasForCall() && evmDialect->providesObjectAccess(); - std::set reservedIdentifiers = _externallyUsedIdentifiers; + std::set reservedIdentifiers = _externallyUsedIdentifiers; reservedIdentifiers += _dialect.fixedFunctionNames(); *_object.code = std::get(Disambiguator( diff --git a/libyul/optimiser/Suite.h b/libyul/optimiser/Suite.h index 6e3886da3b2d..15a41cb9f3dc 100644 --- a/libyul/optimiser/Suite.h +++ b/libyul/optimiser/Suite.h @@ -22,7 +22,7 @@ #pragma once #include -#include +#include #include #include #include @@ -70,7 +70,7 @@ class OptimiserSuite std::string_view _optimisationSequence, std::string_view _optimisationCleanupSequence, std::optional _expectedExecutionsPerDeployment, - std::set const& _externallyUsedIdentifiers = {} + std::set const& _externallyUsedIdentifiers = {} ); /// Ensures that specified sequence of step abbreviations is well-formed and can be executed. diff --git a/libyul/optimiser/SyntacticalEquality.h b/libyul/optimiser/SyntacticalEquality.h index 5a8d2b49b267..0665a5efbe6e 100644 --- a/libyul/optimiser/SyntacticalEquality.h +++ b/libyul/optimiser/SyntacticalEquality.h @@ -22,7 +22,7 @@ #pragma once #include -#include +#include #include #include @@ -84,8 +84,8 @@ class SyntacticallyEqual } std::size_t m_idsUsed = 0; - std::map m_identifiersLHS; - std::map m_identifiersRHS; + std::map m_identifiersLHS; + std::map m_identifiersRHS; }; /** diff --git a/libyul/optimiser/TypeInfo.cpp b/libyul/optimiser/TypeInfo.cpp index 16ce65496861..754c0bad08f8 100644 --- a/libyul/optimiser/TypeInfo.cpp +++ b/libyul/optimiser/TypeInfo.cpp @@ -62,8 +62,8 @@ class TypeInfo::TypeCollector: public ASTWalker } } - std::map variableTypes; - std::map functionTypes; + std::map variableTypes; + std::map functionTypes; }; @@ -75,12 +75,12 @@ TypeInfo::TypeInfo(Dialect const& _dialect, Block const& _ast): m_variableTypes = std::move(types.variableTypes); } -YulString TypeInfo::typeOf(Expression const& _expression) const +YulName TypeInfo::typeOf(Expression const& _expression) const { return std::visit(GenericVisitor{ [&](FunctionCall const& _funCall) { - YulString name = _funCall.functionName.name; - std::vector const* retTypes = nullptr; + YulName name = _funCall.functionName.name; + std::vector const* retTypes = nullptr; if (BuiltinFunction const* fun = m_dialect.builtin(name)) retTypes = &fun->returns; else @@ -97,7 +97,7 @@ YulString TypeInfo::typeOf(Expression const& _expression) const }, _expression); } -YulString TypeInfo::typeOfVariable(YulString _name) const +YulName TypeInfo::typeOfVariable(YulName _name) const { return m_variableTypes.at(_name); } diff --git a/libyul/optimiser/TypeInfo.h b/libyul/optimiser/TypeInfo.h index 5ed0a0d55c5f..96c43875a638 100644 --- a/libyul/optimiser/TypeInfo.h +++ b/libyul/optimiser/TypeInfo.h @@ -21,7 +21,7 @@ #pragma once #include -#include +#include #include #include @@ -40,26 +40,26 @@ class TypeInfo public: TypeInfo(Dialect const& _dialect, Block const& _ast); - void setVariableType(YulString _name, YulString _type) { m_variableTypes[_name] = _type; } + void setVariableType(YulName _name, YulName _type) { m_variableTypes[_name] = _type; } /// @returns the type of an expression that is assumed to return exactly one value. - YulString typeOf(Expression const& _expression) const; + YulName typeOf(Expression const& _expression) const; /// \returns the type of variable - YulString typeOfVariable(YulString _name) const; + YulName typeOfVariable(YulName _name) const; private: class TypeCollector; struct FunctionType { - std::vector parameters; - std::vector returns; + std::vector parameters; + std::vector returns; }; Dialect const& m_dialect; - std::map m_variableTypes; - std::map m_functionTypes; + std::map m_variableTypes; + std::map m_functionTypes; }; } diff --git a/libyul/optimiser/UnusedAssignEliminator.cpp b/libyul/optimiser/UnusedAssignEliminator.cpp index f3d78288f3ca..13a6ba9ee526 100644 --- a/libyul/optimiser/UnusedAssignEliminator.cpp +++ b/libyul/optimiser/UnusedAssignEliminator.cpp @@ -92,7 +92,7 @@ void UnusedAssignEliminator::operator()(FunctionCall const& _functionCall) void UnusedAssignEliminator::operator()(Leave const&) { - for (YulString name: m_returnVariables) + for (YulName name: m_returnVariables) markUsed(name); m_activeStores.clear(); } @@ -152,7 +152,7 @@ void UnusedAssignEliminator::finalizeFunctionDefinition(FunctionDefinition const markUsed(retParam.name); } -void UnusedAssignEliminator::markUsed(YulString _variable) +void UnusedAssignEliminator::markUsed(YulName _variable) { for (auto& assignment: m_activeStores[_variable]) m_usedStores.insert(assignment); diff --git a/libyul/optimiser/UnusedAssignEliminator.h b/libyul/optimiser/UnusedAssignEliminator.h index 800d626eb840..9c3b1e4bcabf 100644 --- a/libyul/optimiser/UnusedAssignEliminator.h +++ b/libyul/optimiser/UnusedAssignEliminator.h @@ -121,7 +121,7 @@ class UnusedAssignEliminator: public UnusedStoreBase explicit UnusedAssignEliminator( Dialect const& _dialect, - std::map _controlFlowSideEffects + std::map _controlFlowSideEffects ): UnusedStoreBase(_dialect), m_controlFlowSideEffects(_controlFlowSideEffects) @@ -141,10 +141,10 @@ class UnusedAssignEliminator: public UnusedStoreBase void shortcutNestedLoop(ActiveStores const& _beforeLoop) override; void finalizeFunctionDefinition(FunctionDefinition const& _functionDefinition) override; - void markUsed(YulString _variable); + void markUsed(YulName _variable); - std::set m_returnVariables; - std::map m_controlFlowSideEffects; + std::set m_returnVariables; + std::map m_controlFlowSideEffects; }; } diff --git a/libyul/optimiser/UnusedFunctionParameterPruner.cpp b/libyul/optimiser/UnusedFunctionParameterPruner.cpp index 40c2fe80c65d..49c0a9c4d427 100644 --- a/libyul/optimiser/UnusedFunctionParameterPruner.cpp +++ b/libyul/optimiser/UnusedFunctionParameterPruner.cpp @@ -26,7 +26,7 @@ #include #include #include -#include +#include #include #include @@ -42,7 +42,7 @@ using namespace solidity::yul::unusedFunctionsCommon; void UnusedFunctionParameterPruner::run(OptimiserStepContext& _context, Block& _ast) { - std::map references = VariableReferencesCounter::countReferences(_ast); + std::map references = VariableReferencesCounter::countReferences(_ast); auto used = [&](auto v) -> bool { return references.count(v.name); }; // Function name and a pair of boolean masks, the first corresponds to parameters and the second @@ -54,7 +54,7 @@ void UnusedFunctionParameterPruner::run(OptimiserStepContext& _context, Block& _ // Similarly for the second vector in the pair, a value `false` at index `i` indicates that the // return parameter at index `i` in `FunctionDefinition::returnVariables` is unused inside // function body. - std::map, std::vector>> usedParametersAndReturnVariables; + std::map, std::vector>> usedParametersAndReturnVariables; // Step 1 of UnusedFunctionParameterPruner: Find functions whose parameters (both arguments and // return-parameters) are not used in its body. @@ -72,7 +72,7 @@ void UnusedFunctionParameterPruner::run(OptimiserStepContext& _context, Block& _ }; } - std::set functionNamesToFree = util::keys(usedParametersAndReturnVariables); + std::set functionNamesToFree = util::keys(usedParametersAndReturnVariables); // Step 2 of UnusedFunctionParameterPruner: Renames the function and replaces all references to // the function, say `f`, by its new name, say `f_1`. @@ -81,7 +81,7 @@ void UnusedFunctionParameterPruner::run(OptimiserStepContext& _context, Block& _ // Inverse-Map of the above translations. In the above example, this will store an element with // key `f_1` and value `f`. - std::map newToOriginalNames = invertMap(replace.translations()); + std::map newToOriginalNames = invertMap(replace.translations()); // Step 3 of UnusedFunctionParameterPruner: introduce a new function in the block with body of // the old one. Replace the body of the old one with a function call to the new one with reduced @@ -98,8 +98,8 @@ void UnusedFunctionParameterPruner::run(OptimiserStepContext& _context, Block& _ if (newToOriginalNames.count(originalFunction.name)) { - YulString linkingFunctionName = originalFunction.name; - YulString originalFunctionName = newToOriginalNames.at(linkingFunctionName); + YulName linkingFunctionName = originalFunction.name; + YulName originalFunctionName = newToOriginalNames.at(linkingFunctionName); std::pair, std::vector> used = usedParametersAndReturnVariables.at(originalFunctionName); diff --git a/libyul/optimiser/UnusedFunctionsCommon.cpp b/libyul/optimiser/UnusedFunctionsCommon.cpp index ed9d0ba4c371..bd38b33cafd9 100644 --- a/libyul/optimiser/UnusedFunctionsCommon.cpp +++ b/libyul/optimiser/UnusedFunctionsCommon.cpp @@ -30,8 +30,8 @@ using namespace solidity::yul::unusedFunctionsCommon; FunctionDefinition unusedFunctionsCommon::createLinkingFunction( FunctionDefinition const& _original, std::pair, std::vector> const& _usedParametersAndReturns, - YulString const& _originalFunctionName, - YulString const& _linkingFunctionName, + YulName const& _originalFunctionName, + YulName const& _linkingFunctionName, NameDispenser& _nameDispenser ) { diff --git a/libyul/optimiser/UnusedFunctionsCommon.h b/libyul/optimiser/UnusedFunctionsCommon.h index 2b0f3000dfda..5aa231b1e410 100644 --- a/libyul/optimiser/UnusedFunctionsCommon.h +++ b/libyul/optimiser/UnusedFunctionsCommon.h @@ -52,8 +52,8 @@ inline bool tooSimpleToBePruned(FunctionDefinition const& _f) FunctionDefinition createLinkingFunction( FunctionDefinition const& _original, std::pair, std::vector> const& _usedParametersAndReturns, - YulString const& _originalFunctionName, - YulString const& _linkingFunctionName, + YulName const& _originalFunctionName, + YulName const& _linkingFunctionName, NameDispenser& _nameDispenser ); diff --git a/libyul/optimiser/UnusedPruner.cpp b/libyul/optimiser/UnusedPruner.cpp index a64f37ebedeb..9df51cf7f069 100644 --- a/libyul/optimiser/UnusedPruner.cpp +++ b/libyul/optimiser/UnusedPruner.cpp @@ -43,8 +43,8 @@ UnusedPruner::UnusedPruner( Dialect const& _dialect, Block& _ast, bool _allowMSizeOptimization, - std::map const* _functionSideEffects, - std::set const& _externallyUsedFunctions + std::map const* _functionSideEffects, + std::set const& _externallyUsedFunctions ): m_dialect(_dialect), m_allowMSizeOptimization(_allowMSizeOptimization), @@ -59,7 +59,7 @@ UnusedPruner::UnusedPruner( Dialect const& _dialect, FunctionDefinition& _function, bool _allowMSizeOptimization, - std::set const& _externallyUsedFunctions + std::set const& _externallyUsedFunctions ): m_dialect(_dialect), m_allowMSizeOptimization(_allowMSizeOptimization) @@ -135,8 +135,8 @@ void UnusedPruner::runUntilStabilised( Dialect const& _dialect, Block& _ast, bool _allowMSizeOptimization, - std::map const* _functionSideEffects, - std::set const& _externallyUsedFunctions + std::map const* _functionSideEffects, + std::set const& _externallyUsedFunctions ) { while (true) @@ -153,10 +153,10 @@ void UnusedPruner::runUntilStabilised( void UnusedPruner::runUntilStabilisedOnFullAST( Dialect const& _dialect, Block& _ast, - std::set const& _externallyUsedFunctions + std::set const& _externallyUsedFunctions ) { - std::map functionSideEffects = + std::map functionSideEffects = SideEffectsPropagator::sideEffects(_dialect, CallGraphGenerator::callGraph(_ast)); bool allowMSizeOptimization = !MSizeFinder::containsMSize(_dialect, _ast); runUntilStabilised(_dialect, _ast, allowMSizeOptimization, &functionSideEffects, _externallyUsedFunctions); @@ -166,7 +166,7 @@ void UnusedPruner::runUntilStabilised( Dialect const& _dialect, FunctionDefinition& _function, bool _allowMSizeOptimization, - std::set const& _externallyUsedFunctions + std::set const& _externallyUsedFunctions ) { while (true) @@ -178,12 +178,12 @@ void UnusedPruner::runUntilStabilised( } } -bool UnusedPruner::used(YulString _name) const +bool UnusedPruner::used(YulName _name) const { return m_references.count(_name) && m_references.at(_name) > 0; } -void UnusedPruner::subtractReferences(std::map const& _subtrahend) +void UnusedPruner::subtractReferences(std::map const& _subtrahend) { for (auto const& ref: _subtrahend) { diff --git a/libyul/optimiser/UnusedPruner.h b/libyul/optimiser/UnusedPruner.h index e4587d5d725b..b0ba53bce95c 100644 --- a/libyul/optimiser/UnusedPruner.h +++ b/libyul/optimiser/UnusedPruner.h @@ -23,7 +23,7 @@ #include #include -#include +#include #include #include @@ -64,14 +64,14 @@ class UnusedPruner: public ASTModifier Dialect const& _dialect, Block& _ast, bool _allowMSizeOptimization, - std::map const* _functionSideEffects = nullptr, - std::set const& _externallyUsedFunctions = {} + std::map const* _functionSideEffects = nullptr, + std::set const& _externallyUsedFunctions = {} ); static void run( Dialect const& _dialect, Block& _ast, - std::set const& _externallyUsedFunctions = {} + std::set const& _externallyUsedFunctions = {} ) { runUntilStabilisedOnFullAST(_dialect, _ast, _externallyUsedFunctions); @@ -84,7 +84,7 @@ class UnusedPruner: public ASTModifier static void runUntilStabilisedOnFullAST( Dialect const& _dialect, Block& _ast, - std::set const& _externallyUsedFunctions = {} + std::set const& _externallyUsedFunctions = {} ); // Run the pruner until the code does not change anymore. @@ -96,7 +96,7 @@ class UnusedPruner: public ASTModifier Dialect const& _dialect, FunctionDefinition& _functionDefinition, bool _allowMSizeOptimization, - std::set const& _externallyUsedFunctions = {} + std::set const& _externallyUsedFunctions = {} ); private: @@ -104,24 +104,24 @@ class UnusedPruner: public ASTModifier Dialect const& _dialect, Block& _ast, bool _allowMSizeOptimization, - std::map const* _functionSideEffects = nullptr, - std::set const& _externallyUsedFunctions = {} + std::map const* _functionSideEffects = nullptr, + std::set const& _externallyUsedFunctions = {} ); UnusedPruner( Dialect const& _dialect, FunctionDefinition& _function, bool _allowMSizeOptimization, - std::set const& _externallyUsedFunctions = {} + std::set const& _externallyUsedFunctions = {} ); - bool used(YulString _name) const; - void subtractReferences(std::map const& _subtrahend); + bool used(YulName _name) const; + void subtractReferences(std::map const& _subtrahend); Dialect const& m_dialect; bool m_allowMSizeOptimization = false; - std::map const* m_functionSideEffects = nullptr; + std::map const* m_functionSideEffects = nullptr; bool m_shouldRunAgain = false; - std::map m_references; + std::map m_references; }; } diff --git a/libyul/optimiser/UnusedStoreBase.h b/libyul/optimiser/UnusedStoreBase.h index 0d618d8d254f..b6dde8c5511f 100644 --- a/libyul/optimiser/UnusedStoreBase.h +++ b/libyul/optimiser/UnusedStoreBase.h @@ -60,7 +60,7 @@ class UnusedStoreBase: public ASTWalker void operator()(Continue const&) override; protected: - using ActiveStores = std::map>; + using ActiveStores = std::map>; /// This function is called for a loop that is nested too deep to avoid /// horrible runtime and should just resolve the situation in a pragmatic diff --git a/libyul/optimiser/UnusedStoreEliminator.cpp b/libyul/optimiser/UnusedStoreEliminator.cpp index 6a0ab1518d08..d049f59a0262 100644 --- a/libyul/optimiser/UnusedStoreEliminator.cpp +++ b/libyul/optimiser/UnusedStoreEliminator.cpp @@ -51,22 +51,22 @@ static std::string const thirtyTwo{"@ 32"}; void UnusedStoreEliminator::run(OptimiserStepContext& _context, Block& _ast) { - std::map functionSideEffects = SideEffectsPropagator::sideEffects( + std::map functionSideEffects = SideEffectsPropagator::sideEffects( _context.dialect, CallGraphGenerator::callGraph(_ast) ); SSAValueTracker ssaValues; ssaValues(_ast); - std::map values; + std::map values; for (auto const& [name, expression]: ssaValues.values()) values[name] = AssignedValue{expression, {}}; Expression const zeroLiteral{Literal{{}, LiteralKind::Number, LiteralValue(u256{0}), {}}}; Expression const oneLiteral{Literal{{}, LiteralKind::Number, LiteralValue(u256{1}), {}}}; Expression const thirtyTwoLiteral{Literal{{}, LiteralKind::Number, LiteralValue(u256{32}), {}}}; - values[YulString{zero}] = AssignedValue{&zeroLiteral, {}}; - values[YulString{one}] = AssignedValue{&oneLiteral, {}}; - values[YulString{thirtyTwo}] = AssignedValue{&thirtyTwoLiteral, {}}; + values[YulName{zero}] = AssignedValue{&zeroLiteral, {}}; + values[YulName{one}] = AssignedValue{&oneLiteral, {}}; + values[YulName{thirtyTwo}] = AssignedValue{&thirtyTwoLiteral, {}}; bool const ignoreMemory = MSizeFinder::containsMSize(_context.dialect, _ast); UnusedStoreEliminator rse{ @@ -93,9 +93,9 @@ void UnusedStoreEliminator::run(OptimiserStepContext& _context, Block& _ast) UnusedStoreEliminator::UnusedStoreEliminator( Dialect const& _dialect, - std::map const& _functionSideEffects, - std::map _controlFlowSideEffects, - std::map const& _ssaValues, + std::map const& _functionSideEffects, + std::map _controlFlowSideEffects, + std::map const& _ssaValues, bool _ignoreMemory ): UnusedStoreBase(_dialect), @@ -228,7 +228,7 @@ std::vector UnusedStoreEliminator::operationsF { using evmasm::Instruction; - YulString functionName = _functionCall.functionName.name; + YulName functionName = _functionCall.functionName.name; SideEffects sideEffects; if (BuiltinFunction const* f = m_dialect.builtin(functionName)) sideEffects = f->sideEffects; @@ -263,8 +263,8 @@ std::vector UnusedStoreEliminator::operationsF if (_op.lengthConstant) switch (*_op.lengthConstant) { - case 1: ourOp.length = YulString(one); break; - case 32: ourOp.length = YulString(thirtyTwo); break; + case 1: ourOp.length = YulName(one); break; + case 32: ourOp.length = YulName(thirtyTwo); break; default: yulAssert(false); } return ourOp; @@ -435,7 +435,7 @@ void UnusedStoreEliminator::clearActive( activeStorageStores() = {}; } -std::optional UnusedStoreEliminator::identifierNameIfSSA(Expression const& _expression) const +std::optional UnusedStoreEliminator::identifierNameIfSSA(Expression const& _expression) const { if (Identifier const* identifier = std::get_if(&_expression)) if (m_ssaValues.count(identifier->name)) diff --git a/libyul/optimiser/UnusedStoreEliminator.h b/libyul/optimiser/UnusedStoreEliminator.h index 89dbabd78d2c..98023b64cfc6 100644 --- a/libyul/optimiser/UnusedStoreEliminator.h +++ b/libyul/optimiser/UnusedStoreEliminator.h @@ -64,9 +64,9 @@ class UnusedStoreEliminator: public UnusedStoreBase explicit UnusedStoreEliminator( Dialect const& _dialect, - std::map const& _functionSideEffects, - std::map _controlFlowSideEffects, - std::map const& _ssaValues, + std::map const& _functionSideEffects, + std::map _controlFlowSideEffects, + std::map const& _ssaValues, bool _ignoreMemory ); @@ -85,15 +85,15 @@ class UnusedStoreEliminator: public UnusedStoreBase Location location; Effect effect; /// Start of affected area. Unknown if not provided. - std::optional start; + std::optional start; /// Length of affected area, unknown if not provided. /// Unused for storage. - std::optional length; + std::optional length; }; private: - std::set& activeMemoryStores() { return m_activeStores["m"_yulstring]; } - std::set& activeStorageStores() { return m_activeStores["s"_yulstring]; } + std::set& activeMemoryStores() { return m_activeStores["m"_yulname]; } + std::set& activeStorageStores() { return m_activeStores["s"_yulname]; } void shortcutNestedLoop(ActiveStores const&) override { @@ -113,12 +113,12 @@ class UnusedStoreEliminator: public UnusedStoreBase void markActiveAsUsed(std::optional _onlyLocation = std::nullopt); void clearActive(std::optional _onlyLocation = std::nullopt); - std::optional identifierNameIfSSA(Expression const& _expression) const; + std::optional identifierNameIfSSA(Expression const& _expression) const; bool const m_ignoreMemory; - std::map const& m_functionSideEffects; - std::map m_controlFlowSideEffects; - std::map const& m_ssaValues; + std::map const& m_functionSideEffects; + std::map m_controlFlowSideEffects; + std::map const& m_ssaValues; std::map m_storeOperations; diff --git a/libyul/optimiser/VarNameCleaner.cpp b/libyul/optimiser/VarNameCleaner.cpp index b13dc8e6b49b..041ebdeaab23 100644 --- a/libyul/optimiser/VarNameCleaner.cpp +++ b/libyul/optimiser/VarNameCleaner.cpp @@ -34,7 +34,7 @@ using namespace solidity::yul; VarNameCleaner::VarNameCleaner( Block const& _ast, Dialect const& _dialect, - std::set _namesToKeep + std::set _namesToKeep ): m_dialect{_dialect}, m_namesToKeep{std::move(_namesToKeep)}, @@ -51,9 +51,9 @@ void VarNameCleaner::operator()(FunctionDefinition& _funDef) yulAssert(!m_insideFunction, ""); m_insideFunction = true; - std::set globalUsedNames = std::move(m_usedNames); + std::set globalUsedNames = std::move(m_usedNames); m_usedNames = m_namesToKeep; - std::map globalTranslatedNames; + std::map globalTranslatedNames; swap(globalTranslatedNames, m_translatedNames); renameVariables(_funDef.parameters); @@ -93,7 +93,7 @@ void VarNameCleaner::operator()(Identifier& _identifier) _identifier.name = name->second; } -YulString VarNameCleaner::findCleanName(YulString const& _name) const +YulName VarNameCleaner::findCleanName(YulName const& _name) const { auto newName = stripSuffix(_name); if (!isUsedName(newName)) @@ -102,24 +102,24 @@ YulString VarNameCleaner::findCleanName(YulString const& _name) const // create new name with suffix (by finding a free identifier) for (size_t i = 1; i < std::numeric_limits::max(); ++i) { - YulString newNameSuffixed = YulString{newName.str() + "_" + std::to_string(i)}; + YulName newNameSuffixed = YulName{newName.str() + "_" + std::to_string(i)}; if (!isUsedName(newNameSuffixed)) return newNameSuffixed; } yulAssert(false, "Exhausted by attempting to find an available suffix."); } -bool VarNameCleaner::isUsedName(YulString const& _name) const +bool VarNameCleaner::isUsedName(YulName const& _name) const { return isRestrictedIdentifier(m_dialect, _name) || m_usedNames.count(_name); } -YulString VarNameCleaner::stripSuffix(YulString const& _name) const +YulName VarNameCleaner::stripSuffix(YulName const& _name) const { static std::regex const suffixRegex("(_+[0-9]+)+$"); std::smatch suffixMatch; if (regex_search(_name.str(), suffixMatch, suffixRegex)) - return {YulString{suffixMatch.prefix().str()}}; + return {YulName{suffixMatch.prefix().str()}}; return _name; } diff --git a/libyul/optimiser/VarNameCleaner.h b/libyul/optimiser/VarNameCleaner.h index 7823e5716c28..bfb6cfb53369 100644 --- a/libyul/optimiser/VarNameCleaner.h +++ b/libyul/optimiser/VarNameCleaner.h @@ -21,7 +21,7 @@ #include #include -#include +#include #include #include @@ -64,33 +64,33 @@ class VarNameCleaner: public ASTModifier VarNameCleaner( Block const& _ast, Dialect const& _dialect, - std::set _namesToKeep = {} + std::set _namesToKeep = {} ); /// Tries to rename a list of variables. void renameVariables(std::vector& _variables); /// @returns suffix-stripped name, if a suffix was detected, none otherwise. - YulString stripSuffix(YulString const& _name) const; + YulName stripSuffix(YulName const& _name) const; /// Looks out for a "clean name" the given @p name could be trimmed down to. /// @returns a trimmed down and "clean name" in case it found one, none otherwise. - YulString findCleanName(YulString const& name) const; + YulName findCleanName(YulName const& name) const; /// Tests whether a given name was already used within this pass /// or was set to be kept. - bool isUsedName(YulString const& _name) const; + bool isUsedName(YulName const& _name) const; Dialect const& m_dialect; /// These names will not be modified. - std::set m_namesToKeep; + std::set m_namesToKeep; /// Set of names that are in use. - std::set m_usedNames; + std::set m_usedNames; /// Maps old to new names. - std::map m_translatedNames; + std::map m_translatedNames; /// Whether the traverse is inside a function definition. /// Used to assert that a function definition cannot be inside another. diff --git a/test/libsolidity/MemoryGuardTest.cpp b/test/libsolidity/MemoryGuardTest.cpp index 6e44afccf4f7..77274200bbb3 100644 --- a/test/libsolidity/MemoryGuardTest.cpp +++ b/test/libsolidity/MemoryGuardTest.cpp @@ -75,7 +75,7 @@ TestCase::TestResult MemoryGuardTest::run(std::ostream& _stream, std::string con auto handleObject = [&](std::string const& _kind, Object const& _object) { m_obtainedResult += contractName + "(" + _kind + ") " + (findFunctionCalls( *_object.code, - "memoryguard"_yulstring + "memoryguard"_yulname ).empty() ? "false" : "true") + "\n"; }; handleObject("creation", *object); diff --git a/test/libyul/FunctionSideEffects.cpp b/test/libyul/FunctionSideEffects.cpp index a57ec9807843..f1bd0ea379d1 100644 --- a/test/libyul/FunctionSideEffects.cpp +++ b/test/libyul/FunctionSideEffects.cpp @@ -87,7 +87,7 @@ TestCase::TestResult FunctionSideEffects::run(std::ostream& _stream, std::string if (!obj.code) BOOST_THROW_EXCEPTION(std::runtime_error("Parsing input failed.")); - std::map functionSideEffects = SideEffectsPropagator::sideEffects( + std::map functionSideEffects = SideEffectsPropagator::sideEffects( EVMDialect::strictAssemblyForEVMObjects(langutil::EVMVersion()), CallGraphGenerator::callGraph(*obj.code) ); diff --git a/test/libyul/KnowledgeBaseTest.cpp b/test/libyul/KnowledgeBaseTest.cpp index b1dd0e6d19c5..6a9d3e6da8be 100644 --- a/test/libyul/KnowledgeBaseTest.cpp +++ b/test/libyul/KnowledgeBaseTest.cpp @@ -49,7 +49,7 @@ class KnowledgeBaseTest BOOST_REQUIRE(m_object && errorList.empty() && m_object->code); NameDispenser dispenser(m_dialect, *m_object->code); - std::set reserved; + std::set reserved; OptimiserStepContext context{m_dialect, dispenser, reserved, 0}; CommonSubexpressionEliminator::run(context, *m_object->code); @@ -57,13 +57,13 @@ class KnowledgeBaseTest for (auto const& [name, expression]: m_ssaValues.values()) m_values[name].value = expression; - return KnowledgeBase([this](YulString _var) { return util::valueOrNullptr(m_values, _var); }); + return KnowledgeBase([this](YulName _var) { return util::valueOrNullptr(m_values, _var); }); } EVMDialect m_dialect{EVMVersion{}, true}; std::shared_ptr m_object; SSAValueTracker m_ssaValues; - std::map m_values; + std::map m_values; }; BOOST_FIXTURE_TEST_SUITE(KnowledgeBase, KnowledgeBaseTest) @@ -79,14 +79,14 @@ BOOST_AUTO_TEST_CASE(basic) let e := sub(a, b) })"); - BOOST_CHECK(!kb.knownToBeDifferent("a"_yulstring, "b"_yulstring)); + BOOST_CHECK(!kb.knownToBeDifferent("a"_yulname, "b"_yulname)); // This only works if the variable names are the same. // It assumes that SSA+CSE+Simplifier actually replaces the variables. - BOOST_CHECK(!kb.valueIfKnownConstant("a"_yulstring)); - BOOST_CHECK(kb.valueIfKnownConstant("zero"_yulstring) == u256(0)); - BOOST_CHECK(kb.differenceIfKnownConstant("a"_yulstring, "b"_yulstring) == u256(0)); - BOOST_CHECK(kb.differenceIfKnownConstant("a"_yulstring, "c"_yulstring) == u256(0)); - BOOST_CHECK(kb.valueIfKnownConstant("e"_yulstring) == u256(0)); + BOOST_CHECK(!kb.valueIfKnownConstant("a"_yulname)); + BOOST_CHECK(kb.valueIfKnownConstant("zero"_yulname) == u256(0)); + BOOST_CHECK(kb.differenceIfKnownConstant("a"_yulname, "b"_yulname) == u256(0)); + BOOST_CHECK(kb.differenceIfKnownConstant("a"_yulname, "c"_yulname) == u256(0)); + BOOST_CHECK(kb.valueIfKnownConstant("e"_yulname) == u256(0)); } BOOST_AUTO_TEST_CASE(difference) @@ -99,31 +99,21 @@ BOOST_AUTO_TEST_CASE(difference) let e := sub(c, 12) })"); - BOOST_CHECK( - kb.differenceIfKnownConstant("c"_yulstring, "b"_yulstring) == + BOOST_CHECK(kb.differenceIfKnownConstant("c"_yulname, "b"_yulname) == u256(20) ); - BOOST_CHECK( - kb.differenceIfKnownConstant("b"_yulstring, "c"_yulstring) == + BOOST_CHECK(kb.differenceIfKnownConstant("b"_yulname, "c"_yulname) == u256(-20) ); - BOOST_CHECK(!kb.knownToBeDifferentByAtLeast32("b"_yulstring, "c"_yulstring)); - BOOST_CHECK(kb.knownToBeDifferentByAtLeast32("b"_yulstring, "d"_yulstring)); - BOOST_CHECK(kb.knownToBeDifferentByAtLeast32("a"_yulstring, "b"_yulstring)); - BOOST_CHECK(kb.knownToBeDifferentByAtLeast32("b"_yulstring, "a"_yulstring)); - - BOOST_CHECK( - kb.differenceIfKnownConstant("e"_yulstring, "a"_yulstring) == u256(208) - ); - BOOST_CHECK( - kb.differenceIfKnownConstant("e"_yulstring, "b"_yulstring) == u256(8) - ); - BOOST_CHECK( - kb.differenceIfKnownConstant("a"_yulstring, "e"_yulstring) == u256(-208) - ); - BOOST_CHECK( - kb.differenceIfKnownConstant("b"_yulstring, "e"_yulstring) == u256(-8) - ); + BOOST_CHECK(!kb.knownToBeDifferentByAtLeast32("b"_yulname, "c"_yulname)); + BOOST_CHECK(kb.knownToBeDifferentByAtLeast32("b"_yulname, "d"_yulname)); + BOOST_CHECK(kb.knownToBeDifferentByAtLeast32("a"_yulname, "b"_yulname)); + BOOST_CHECK(kb.knownToBeDifferentByAtLeast32("b"_yulname, "a"_yulname)); + + BOOST_CHECK(kb.differenceIfKnownConstant("e"_yulname, "a"_yulname) == u256(208)); + BOOST_CHECK(kb.differenceIfKnownConstant("e"_yulname, "b"_yulname) == u256(8)); + BOOST_CHECK(kb.differenceIfKnownConstant("a"_yulname, "e"_yulname) == u256(-208)); + BOOST_CHECK(kb.differenceIfKnownConstant("b"_yulname, "e"_yulname) == u256(-8)); } diff --git a/test/libyul/Parser.cpp b/test/libyul/Parser.cpp index ca8784ddb6ef..faa6c6105f2d 100644 --- a/test/libyul/Parser.cpp +++ b/test/libyul/Parser.cpp @@ -135,11 +135,11 @@ BOOST_AUTO_TEST_CASE(builtins_analysis) { struct SimpleDialect: public Dialect { - BuiltinFunction const* builtin(YulString _name) const override + BuiltinFunction const* builtin(YulName _name) const override { - return _name == "builtin"_yulstring ? &f : nullptr; + return _name == "builtin"_yulname ? &f : nullptr; } - BuiltinFunction f{"builtin"_yulstring, std::vector(2), std::vector(3), {}, {}, false, {}}; + BuiltinFunction f{"builtin"_yulname, std::vector(2), std::vector(3), {}, {}, false, {}}; }; SimpleDialect dialect; diff --git a/test/libyul/StackShufflingTest.cpp b/test/libyul/StackShufflingTest.cpp index e53eeafbb03c..2da445dd4557 100644 --- a/test/libyul/StackShufflingTest.cpp +++ b/test/libyul/StackShufflingTest.cpp @@ -56,7 +56,7 @@ bool StackShufflingTest::parse(std::string const& _source) scanner.next(); std::string functionName = scanner.currentLiteral(); auto call = yul::FunctionCall{ - {}, yul::Identifier{{}, YulString(functionName)}, {} + {}, yul::Identifier{{}, YulName(functionName)}, {} }; stack.emplace_back(FunctionCallReturnLabelSlot{ m_functions.insert( @@ -78,7 +78,7 @@ bool StackShufflingTest::parse(std::string const& _source) scanner.next(); std::string functionName = scanner.currentLiteral(); auto call = yul::FunctionCall{ - {}, yul::Identifier{{}, YulString(functionName)}, {} + {}, yul::Identifier{{}, YulName(functionName)}, {} }; expectToken(Token::Comma); scanner.next(); @@ -102,7 +102,7 @@ bool StackShufflingTest::parse(std::string const& _source) expectToken(Token::LBrack); scanner.next(); // read number of ghost variables as ghostVariableId std::string ghostVariableId = scanner.currentLiteral(); - Scope::Variable ghostVar = Scope::Variable{""_yulstring, YulString(literal + "[" + ghostVariableId + "]")}; + Scope::Variable ghostVar = Scope::Variable{""_yulname, YulName(literal + "[" + ghostVariableId + "]")}; stack.emplace_back(VariableSlot{ m_variables.insert(std::make_pair(ghostVar.name, ghostVar)).first->second }); @@ -110,7 +110,7 @@ bool StackShufflingTest::parse(std::string const& _source) } else { - Scope::Variable var = Scope::Variable{""_yulstring, YulString(literal)}; + Scope::Variable var = Scope::Variable{""_yulname, YulName(literal)}; stack.emplace_back(VariableSlot{ m_variables.insert( make_pair(literal, var) diff --git a/test/libyul/StackShufflingTest.h b/test/libyul/StackShufflingTest.h index 75715d25b90f..2e2dd12ad325 100644 --- a/test/libyul/StackShufflingTest.h +++ b/test/libyul/StackShufflingTest.h @@ -41,7 +41,7 @@ class StackShufflingTest: public TestCase Stack m_sourceStack; Stack m_targetStack; - std::map m_functions; - std::map m_variables; + std::map m_functions; + std::map m_variables; }; } diff --git a/test/libyul/YulOptimizerTestCommon.cpp b/test/libyul/YulOptimizerTestCommon.cpp index 091a9a0b6cff..80746c93ba9f 100644 --- a/test/libyul/YulOptimizerTestCommon.cpp +++ b/test/libyul/YulOptimizerTestCommon.cpp @@ -89,7 +89,7 @@ YulOptimizerTestCommon::YulOptimizerTestCommon( disambiguate(); NameDisplacer{ *m_nameDispenser, - {"illegal1"_yulstring, "illegal2"_yulstring, "illegal3"_yulstring, "illegal4"_yulstring, "illegal5"_yulstring} + {"illegal1"_yulname, "illegal2"_yulname, "illegal3"_yulname, "illegal4"_yulname, "illegal5"_yulname} }(*m_ast); }}, {"blockFlattener", [&]() { @@ -348,11 +348,11 @@ YulOptimizerTestCommon::YulOptimizerTestCommon( // Mark all variables with a name starting with "$" for escalation to memory. struct FakeUnreachableGenerator: ASTWalker { - std::map> fakeUnreachables; + std::map> fakeUnreachables; using ASTWalker::operator(); void operator()(FunctionDefinition const& _function) override { - YulString originalFunctionName = m_currentFunction; + YulName originalFunctionName = m_currentFunction; m_currentFunction = _function.name; for (TypedName const& _argument: _function.parameters) visitVariableName(_argument.name); @@ -361,7 +361,7 @@ YulOptimizerTestCommon::YulOptimizerTestCommon( ASTWalker::operator()(_function); m_currentFunction = originalFunctionName; } - void visitVariableName(YulString _var) + void visitVariableName(YulName _var) { if (!_var.empty() && _var.str().front() == '$') if (!util::contains(fakeUnreachables[m_currentFunction], _var)) @@ -378,7 +378,7 @@ YulOptimizerTestCommon::YulOptimizerTestCommon( visitVariableName(_identifier.name); ASTWalker::operator()(_identifier); } - YulString m_currentFunction = YulString{}; + YulName m_currentFunction = YulName{}; }; FakeUnreachableGenerator fakeUnreachableGenerator; fakeUnreachableGenerator(*m_ast); diff --git a/test/libyul/YulOptimizerTestCommon.h b/test/libyul/YulOptimizerTestCommon.h index 3dce998c56cc..0a5d63320d6d 100644 --- a/test/libyul/YulOptimizerTestCommon.h +++ b/test/libyul/YulOptimizerTestCommon.h @@ -21,7 +21,7 @@ #include #include -#include +#include #include #include @@ -63,7 +63,7 @@ class YulOptimizerTestCommon std::string m_optimizerStep; Dialect const* m_dialect = nullptr; - std::set m_reservedIdentifiers; + std::set m_reservedIdentifiers; std::unique_ptr m_nameDispenser; std::unique_ptr m_context; diff --git a/test/tools/yulInterpreter/Inspector.h b/test/tools/yulInterpreter/Inspector.h index f4518c7087d3..903ebc1142ea 100644 --- a/test/tools/yulInterpreter/Inspector.h +++ b/test/tools/yulInterpreter/Inspector.h @@ -53,13 +53,13 @@ class Inspector * @returns NodeAction::RunNode if the current AST node (and all children nodes!) should be * processed without stopping, else NodeAction::StepThroughNode. */ - NodeAction queryUser(langutil::DebugData const& _data, std::map const& _variables); + NodeAction queryUser(langutil::DebugData const& _data, std::map const& _variables); void stepMode(NodeAction _action) { m_stepMode = _action; } std::string const& source() const { return m_source; } - void interactiveVisit(langutil::DebugData const& _debugData, std::map const& _variables, std::function _visitNode) + void interactiveVisit(langutil::DebugData const& _debugData, std::map const& _variables, std::function _visitNode) { Inspector::NodeAction action = queryUser(_debugData, _variables); @@ -116,7 +116,7 @@ class InspectedInterpreter: public Interpreter Scope& _scope, bool _disableExternalCalls, bool _disableMemoryTracing, - std::map _variables = {} + std::map _variables = {} ): Interpreter(_state, _dialect, _scope, _disableExternalCalls, _disableMemoryTracing, _variables), m_inspector(_inspector) @@ -160,7 +160,7 @@ class InspectedExpressionEvaluator: public ExpressionEvaluator InterpreterState& _state, Dialect const& _dialect, Scope& _scope, - std::map const& _variables, + std::map const& _variables, bool _disableExternalCalls, bool _disableMemoryTrace ): @@ -180,7 +180,7 @@ class InspectedExpressionEvaluator: public ExpressionEvaluator void operator()(Identifier const& _node) override { helper(_node); } void operator()(FunctionCall const& _node) override { helper(_node); } protected: - std::unique_ptr makeInterpreterCopy(std::map _variables = {}) const override + std::unique_ptr makeInterpreterCopy(std::map _variables = {}) const override { return std::make_unique( m_inspector, diff --git a/test/tools/yulInterpreter/Interpreter.cpp b/test/tools/yulInterpreter/Interpreter.cpp index 6a0f3a9997ef..21e97f0769c8 100644 --- a/test/tools/yulInterpreter/Interpreter.cpp +++ b/test/tools/yulInterpreter/Interpreter.cpp @@ -131,7 +131,7 @@ void Interpreter::operator()(Assignment const& _assignment) solAssert(values.size() == _assignment.variableNames.size(), ""); for (size_t i = 0; i < values.size(); ++i) { - YulString varName = _assignment.variableNames.at(i).name; + YulName varName = _assignment.variableNames.at(i).name; solAssert(m_variables.count(varName), ""); m_variables[varName] = values.at(i); } @@ -146,7 +146,7 @@ void Interpreter::operator()(VariableDeclaration const& _declaration) solAssert(values.size() == _declaration.variables.size(), ""); for (size_t i = 0; i < values.size(); ++i) { - YulString varName = _declaration.variables.at(i).name; + YulName varName = _declaration.variables.at(i).name; solAssert(!m_variables.count(varName), ""); m_variables[varName] = values.at(i); m_scope->names.emplace(varName, nullptr); @@ -343,7 +343,7 @@ void ExpressionEvaluator::operator()(FunctionCall const& _funCall) FunctionDefinition const* fun = scope->names.at(_funCall.functionName.name); yulAssert(fun, "Function not found."); yulAssert(m_values.size() == fun->parameters.size(), ""); - std::map variables; + std::map variables; for (size_t i = 0; i < fun->parameters.size(); ++i) variables[fun->parameters.at(i).name] = m_values.at(i); for (size_t i = 0; i < fun->returnVariables.size(); ++i) diff --git a/test/tools/yulInterpreter/Interpreter.h b/test/tools/yulInterpreter/Interpreter.h index 23a98ca5c350..356a190709a7 100644 --- a/test/tools/yulInterpreter/Interpreter.h +++ b/test/tools/yulInterpreter/Interpreter.h @@ -145,7 +145,7 @@ struct InterpreterState struct Scope { /// Used for variables and functions. Value is nullptr for variables. - std::map names; + std::map names; std::map> subScopes; Scope* parent = nullptr; }; @@ -174,7 +174,7 @@ class Interpreter: public ASTWalker Scope& _scope, bool _disableExternalCalls, bool _disableMemoryTracing, - std::map _variables = {} + std::map _variables = {} ): m_dialect(_dialect), m_state(_state), @@ -200,7 +200,7 @@ class Interpreter: public ASTWalker bytes returnData() const { return m_state.returndata; } std::vector const& trace() const { return m_state.trace; } - u256 valueOfVariable(YulString _name) const { return m_variables.at(_name); } + u256 valueOfVariable(YulName _name) const { return m_variables.at(_name); } protected: /// Asserts that the expression evaluates to exactly one value and returns it. @@ -218,7 +218,7 @@ class Interpreter: public ASTWalker Dialect const& m_dialect; InterpreterState& m_state; /// Values of variables. - std::map m_variables; + std::map m_variables; Scope* m_scope; /// If not set, external calls (e.g. using `call()`) to the same contract /// are evaluated in a new parser instance. @@ -236,7 +236,7 @@ class ExpressionEvaluator: public ASTWalker InterpreterState& _state, Dialect const& _dialect, Scope& _scope, - std::map const& _variables, + std::map const& _variables, bool _disableExternalCalls, bool _disableMemoryTrace ): @@ -259,7 +259,7 @@ class ExpressionEvaluator: public ASTWalker protected: void runExternalCall(evmasm::Instruction _instruction); - virtual std::unique_ptr makeInterpreterCopy(std::map _variables = {}) const + virtual std::unique_ptr makeInterpreterCopy(std::map _variables = {}) const { return std::make_unique( m_state, @@ -298,7 +298,7 @@ class ExpressionEvaluator: public ASTWalker InterpreterState& m_state; Dialect const& m_dialect; /// Values of variables. - std::map const& m_variables; + std::map const& m_variables; Scope& m_scope; /// Current value of the expression std::vector m_values; diff --git a/test/tools/yulopti.cpp b/test/tools/yulopti.cpp index d16b1da1969b..7e81cbf7e34e 100644 --- a/test/tools/yulopti.cpp +++ b/test/tools/yulopti.cpp @@ -245,7 +245,7 @@ class YulOpti std::shared_ptr m_ast; Dialect const& m_dialect{EVMDialect::strictAssemblyForEVMObjects(EVMVersion{})}; std::unique_ptr m_analysisInfo; - std::set const m_reservedIdentifiers = {}; + std::set const m_reservedIdentifiers = {}; NameDispenser m_nameDispenser{m_dialect, m_reservedIdentifiers}; OptimiserStepContext m_context{ m_dialect, diff --git a/tools/yulPhaser/Program.cpp b/tools/yulPhaser/Program.cpp index 1586f602064b..0cb22242d0fe 100644 --- a/tools/yulPhaser/Program.cpp +++ b/tools/yulPhaser/Program.cpp @@ -28,7 +28,7 @@ #include #include #include -#include +#include #include #include #include @@ -175,7 +175,7 @@ std::unique_ptr Program::disambiguateAST( AsmAnalysisInfo const& _analysisInfo ) { - std::set const externallyUsedIdentifiers = {}; + std::set const externallyUsedIdentifiers = {}; Disambiguator disambiguator(_dialect, _analysisInfo, externallyUsedIdentifiers); return std::make_unique(std::get(disambiguator(_ast))); @@ -190,7 +190,7 @@ std::unique_ptr Program::applyOptimisationSteps( { // An empty set of reserved identifiers. It could be a constructor parameter but I don't // think it would be useful in this tool. Other tools (like yulopti) have it empty too. - std::set const externallyUsedIdentifiers = {}; + std::set const externallyUsedIdentifiers = {}; OptimiserStepContext context{ _dialect, _nameDispenser, From b508a63e4a6f10d3f7bb578e9ab7f0fcbb5dd219 Mon Sep 17 00:00:00 2001 From: Francisco Giordano Date: Fri, 19 Jul 2024 15:52:20 -0300 Subject: [PATCH 0311/1022] Fix docs on outputSelection --- docs/using-the-compiler.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/using-the-compiler.rst b/docs/using-the-compiler.rst index 1eb6631df49f..39da067f39f0 100644 --- a/docs/using-the-compiler.rst +++ b/docs/using-the-compiler.rst @@ -404,7 +404,8 @@ Input Description // but to the whole source file like the AST. // A star as contract name refers to all contracts in the file. // Similarly, a star as a file name matches all files. - // To select all outputs the compiler can possibly generate, use + // To select all outputs the compiler can possibly generate, with the exclusion of + // Yul intermediate representation outputs, use // "outputSelection: { "*": { "*": [ "*" ], "": [ "*" ] } }" // but note that this might slow down the compilation process needlessly. // From 535203b58f844335378f0b9567f7abedbd72f904 Mon Sep 17 00:00:00 2001 From: Nikola Matic Date: Fri, 19 Jul 2024 17:27:32 +0200 Subject: [PATCH 0312/1022] Use latest node cimg --- .circleci/config.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 20f57b41312e..d6c3f33da08a 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -487,8 +487,7 @@ defaults: - base_node_small: &base_node_small docker: - # TODO: Revert to cimg/node:current once https://github.com/npm/cli/issues/7657 is resolved. - - image: cimg/node:22.4 + - image: cimg/node:current resource_class: small environment: &base_node_small_env TERM: xterm @@ -762,7 +761,6 @@ defaults: # which does not support shanghai EVM. compile_only: 1 resource_class: medium - image: cimg/node:18.16 - job_native_test_ext_yield_liquidator: &job_native_test_ext_yield_liquidator <<: *requires_b_ubu_static From d0cabf490c97906757d8c8263cdd206fdf5f1547 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kaan=20Uzdo=C4=9Fan?= Date: Mon, 22 Jul 2024 11:56:25 +0200 Subject: [PATCH 0313/1022] Docs: Add note about the library placeholder format change in v0.5.0 The library placeholder string format has changed on v0.5.0. Someone reading the docs would be unaware of this and can assume the format remained the same. This can be important e.g. verifying contracts pre 0.5.0 or working on the bytecode --- docs/contracts/libraries.rst | 2 +- docs/using-the-compiler.rst | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/contracts/libraries.rst b/docs/contracts/libraries.rst index 7256ebe0315a..1c6d837c7cd7 100644 --- a/docs/contracts/libraries.rst +++ b/docs/contracts/libraries.rst @@ -196,7 +196,7 @@ It is possible to obtain the address of a library by converting the library type to the ``address`` type, i.e. using ``address(LibraryName)``. As the compiler does not know the address where the library will be deployed, the compiled hex code -will contain placeholders of the form ``__$30bbc0abd4d6364515865950d3e0d10953$__``. The placeholder +will contain placeholders of the form ``__$30bbc0abd4d6364515865950d3e0d10953$__`` `(format was different `_. The placeholder is a 34 character prefix of the hex encoding of the keccak256 hash of the fully qualified library name, which would be for example ``libraries/bigint.sol:BigInt`` if the library was stored in a file called ``bigint.sol`` in a ``libraries/`` directory. Such bytecode is incomplete and should not be diff --git a/docs/using-the-compiler.rst b/docs/using-the-compiler.rst index 39da067f39f0..c84d6a838c01 100644 --- a/docs/using-the-compiler.rst +++ b/docs/using-the-compiler.rst @@ -71,7 +71,7 @@ For a detailed explanation with examples and discussion of corner cases please r Library Linking --------------- -If your contracts use :ref:`libraries `, you will notice that the bytecode contains substrings of the form ``__$53aea86b7d70b31448b230b20ae141a537$__``. These are placeholders for the actual library addresses. +If your contracts use :ref:`libraries `, you will notice that the bytecode contains substrings of the form ``__$53aea86b7d70b31448b230b20ae141a537$__`` `(format was different `_. These are placeholders for the actual library addresses. The placeholder is a 34 character prefix of the hex encoding of the keccak256 hash of the fully qualified library name. The bytecode file will also contain lines of the form ``// -> `` at the end to help identify which libraries the placeholders represent. Note that the fully qualified library name From 1cbb3220de39f589885faf9e734e743f3b2f8857 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kaan=20Uzdo=C4=9Fan?= Date: Mon, 22 Jul 2024 12:03:48 +0200 Subject: [PATCH 0314/1022] Change link to libraries page --- docs/contracts/libraries.rst | 2 +- docs/using-the-compiler.rst | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/contracts/libraries.rst b/docs/contracts/libraries.rst index 1c6d837c7cd7..a3c04ba06405 100644 --- a/docs/contracts/libraries.rst +++ b/docs/contracts/libraries.rst @@ -196,7 +196,7 @@ It is possible to obtain the address of a library by converting the library type to the ``address`` type, i.e. using ``address(LibraryName)``. As the compiler does not know the address where the library will be deployed, the compiled hex code -will contain placeholders of the form ``__$30bbc0abd4d6364515865950d3e0d10953$__`` `(format was different `_. The placeholder +will contain placeholders of the form ``__$30bbc0abd4d6364515865950d3e0d10953$__`` `(format was different `_. The placeholder is a 34 character prefix of the hex encoding of the keccak256 hash of the fully qualified library name, which would be for example ``libraries/bigint.sol:BigInt`` if the library was stored in a file called ``bigint.sol`` in a ``libraries/`` directory. Such bytecode is incomplete and should not be diff --git a/docs/using-the-compiler.rst b/docs/using-the-compiler.rst index c84d6a838c01..a306fa835d97 100644 --- a/docs/using-the-compiler.rst +++ b/docs/using-the-compiler.rst @@ -71,7 +71,7 @@ For a detailed explanation with examples and discussion of corner cases please r Library Linking --------------- -If your contracts use :ref:`libraries `, you will notice that the bytecode contains substrings of the form ``__$53aea86b7d70b31448b230b20ae141a537$__`` `(format was different `_. These are placeholders for the actual library addresses. +If your contracts use :ref:`libraries `, you will notice that the bytecode contains substrings of the form ``__$53aea86b7d70b31448b230b20ae141a537$__`` `(format was different `_. These are placeholders for the actual library addresses. The placeholder is a 34 character prefix of the hex encoding of the keccak256 hash of the fully qualified library name. The bytecode file will also contain lines of the form ``// -> `` at the end to help identify which libraries the placeholders represent. Note that the fully qualified library name From 755201202e3dfb4aca57780b55f8e6ce06663e91 Mon Sep 17 00:00:00 2001 From: dxo Date: Mon, 22 Jul 2024 20:50:00 +0200 Subject: [PATCH 0315/1022] docs/yul: pc is dissalowed in solc yul pc was removed from solc assembly in 0.7.0 (it introduced an unwelcome semantic dependency on code location). --- docs/yul.rst | 2 -- 1 file changed, 2 deletions(-) diff --git a/docs/yul.rst b/docs/yul.rst index 3cf2785fc444..58cfc992fd99 100644 --- a/docs/yul.rst +++ b/docs/yul.rst @@ -820,8 +820,6 @@ the ``dup`` and ``swap`` instructions as well as ``jump`` instructions, labels a +-------------------------+-----+---+-----------------------------------------------------------------+ | keccak256(p, n) | | F | keccak(mem[p...(p+n))) | +-------------------------+-----+---+-----------------------------------------------------------------+ -| pc() | | F | current position in code | -+-------------------------+-----+---+-----------------------------------------------------------------+ | pop(x) | `-` | F | discard value x | +-------------------------+-----+---+-----------------------------------------------------------------+ | mload(p) | | F | mem[p...(p+32)) | From cccbc122204ed230441ad991fcfd5855caec987f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Tue, 28 May 2024 15:06:46 +0200 Subject: [PATCH 0316/1022] Updated some outdated docs and TODOs related to the optimizer outputs --- libsolidity/interface/CompilerStack.h | 9 ++++++--- solc/CommandLineInterface.cpp | 1 - 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/libsolidity/interface/CompilerStack.h b/libsolidity/interface/CompilerStack.h index 672067d81cc7..6ad868ad09fe 100644 --- a/libsolidity/interface/CompilerStack.h +++ b/libsolidity/interface/CompilerStack.h @@ -387,8 +387,8 @@ class CompilerStack: public langutil::CharStreamProvider, public evmasm::Abstrac std::shared_ptr evmRuntimeAssembly; evmasm::LinkerObject object; ///< Deployment object (includes the runtime sub-object). evmasm::LinkerObject runtimeObject; ///< Runtime object. - std::string yulIR; ///< Yul IR code. - std::string yulIROptimized; ///< Optimized Yul IR code. + std::string yulIR; ///< Yul IR code straight from the code generator. + std::string yulIROptimized; ///< Reparsed and possibly optimized Yul IR code. Json yulIRAst; ///< JSON AST of Yul IR code. Json yulIROptimizedAst; ///< JSON AST of optimized Yul IR code. util::LazyInit metadata; ///< The metadata json that will be hashed into the chain. @@ -449,7 +449,10 @@ class CompilerStack: public langutil::CharStreamProvider, public evmasm::Abstrac ); /// Generate Yul IR for a single contract. - /// The IR is stored but otherwise unused. + /// Unoptimized IR is stored but otherwise unused, while optimized IR may be used for code + /// generation if compilation via IR is enabled. Note that whether "optimized IR" is actually + /// optimized depends on the optimizer settings. + /// @param _contract Contract to generate IR for. void generateIR(ContractDefinition const& _contract); /// Generate EVM representation for a single contract. diff --git a/solc/CommandLineInterface.cpp b/solc/CommandLineInterface.cpp index 367434c93f2a..e2d1e2701dc8 100644 --- a/solc/CommandLineInterface.cpp +++ b/solc/CommandLineInterface.cpp @@ -849,7 +849,6 @@ void CommandLineInterface::compile() m_compiler->setRevertStringBehaviour(m_options.output.revertStrings); if (m_options.output.debugInfoSelection.has_value()) m_compiler->selectDebugInfo(m_options.output.debugInfoSelection.value()); - // TODO: Perhaps we should not compile unless requested m_compiler->enableIRGeneration( m_options.compiler.outputs.ir || m_options.compiler.outputs.irOptimized || From 1a60d1860d9f75b5d115887548fdec0dfc23a70d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Wed, 29 May 2024 21:25:28 +0200 Subject: [PATCH 0317/1022] Do not perform IR optimization if only unoptimized IR is requested --- Changelog.md | 2 + libsolidity/interface/CompilerStack.cpp | 28 ++++++-- libsolidity/interface/CompilerStack.h | 23 ++++-- libsolidity/interface/StandardCompiler.cpp | 27 +++---- solc/CommandLineInterface.cpp | 14 ++-- .../ir_optimized_with_optimize/args | 1 + .../ir_optimized_with_optimize/input.sol | 4 ++ .../ir_optimized_with_optimize/output | 19 +++++ .../ir_unoptimized_with_optimize/args | 1 + .../ir_unoptimized_with_optimize/input.sol | 4 ++ .../ir_unoptimized_with_optimize/output | 58 +++++++++++++++ .../ir_unoptimized_with_optimize_via_ir/args | 1 + .../input.sol | 4 ++ .../output | 58 +++++++++++++++ .../input.json | 11 +++ .../output.json | 72 +++++++++++++++++++ .../input.json | 12 ++++ .../output.json | 72 +++++++++++++++++++ 18 files changed, 381 insertions(+), 30 deletions(-) create mode 100644 test/cmdlineTests/ir_optimized_with_optimize/args create mode 100644 test/cmdlineTests/ir_optimized_with_optimize/input.sol create mode 100644 test/cmdlineTests/ir_optimized_with_optimize/output create mode 100644 test/cmdlineTests/ir_unoptimized_with_optimize/args create mode 100644 test/cmdlineTests/ir_unoptimized_with_optimize/input.sol create mode 100644 test/cmdlineTests/ir_unoptimized_with_optimize/output create mode 100644 test/cmdlineTests/ir_unoptimized_with_optimize_via_ir/args create mode 100644 test/cmdlineTests/ir_unoptimized_with_optimize_via_ir/input.sol create mode 100644 test/cmdlineTests/ir_unoptimized_with_optimize_via_ir/output create mode 100644 test/cmdlineTests/standard_ir_unoptimized_with_optimize/input.json create mode 100644 test/cmdlineTests/standard_ir_unoptimized_with_optimize/output.json create mode 100644 test/cmdlineTests/standard_ir_unoptimized_with_optimize_via_ir/input.json create mode 100644 test/cmdlineTests/standard_ir_unoptimized_with_optimize_via_ir/output.json diff --git a/Changelog.md b/Changelog.md index 7a5adcc4b08d..e67cf0f07d91 100644 --- a/Changelog.md +++ b/Changelog.md @@ -7,10 +7,12 @@ Language Features: Compiler Features: + * Command Line Interface: Do not perform IR optimization when only unoptimized IR is requested. * Error Reporting: Unimplemented features are now properly reported as errors instead of being handled as if they were bugs. * EVM: Support for the EVM version "Prague". * SMTChecker: Add CHC engine check for underflow and overflow in unary minus operation. * SMTChecker: Replace CVC4 as a possible BMC backend with cvc5. + * Standard JSON Interface: Do not perform IR optimization when only unoptimized IR is requested. * Yul Optimizer: The optimizer now treats some previously unrecognized identical literals as identical. diff --git a/libsolidity/interface/CompilerStack.cpp b/libsolidity/interface/CompilerStack.cpp index 566feb21b171..f2c37fa68523 100644 --- a/libsolidity/interface/CompilerStack.cpp +++ b/libsolidity/interface/CompilerStack.cpp @@ -313,7 +313,7 @@ void CompilerStack::reset(bool _keepSettings) m_viaIR = false; m_evmVersion = langutil::EVMVersion(); m_modelCheckerSettings = ModelCheckerSettings{}; - m_generateIR = false; + m_irOutputSelection = IROutputSelection::None; m_revertStrings = RevertStrings::Default; m_optimiserSettings = OptimiserSettings::minimal(); m_metadataLiteralSources = false; @@ -728,8 +728,17 @@ bool CompilerStack::compile(State _stopAfter) { try { - if ((m_generateEvmBytecode && m_viaIR) || m_generateIR) - generateIR(*contract); + // NOTE: Bytecode generation via IR always uses Contract::yulIROptimized. + // When optimization is not enabled, that member simply contains unoptimized code. + bool needIROutput = + (m_generateEvmBytecode && m_viaIR) || + m_irOutputSelection != IROutputSelection::None; + bool needUnoptimizedIROutputOnly = + !(m_generateEvmBytecode && m_viaIR) && + m_irOutputSelection != IROutputSelection::UnoptimizedAndOptimized; + + if (needIROutput) + generateIR(*contract, needUnoptimizedIROutputOnly); if (m_generateEvmBytecode) { if (m_viaIR) @@ -1402,7 +1411,7 @@ void CompilerStack::compileContract( assembleYul(_contract, compiler->assemblyPtr(), compiler->runtimeAssemblyPtr()); } -void CompilerStack::generateIR(ContractDefinition const& _contract) +void CompilerStack::generateIR(ContractDefinition const& _contract, bool _unoptimizedOnly) { solAssert(m_stackState >= AnalysisSuccessful, ""); @@ -1420,7 +1429,7 @@ void CompilerStack::generateIR(ContractDefinition const& _contract) std::string dependenciesSource; for (auto const& [dependency, referencee]: _contract.annotation().contractDependencies) - generateIR(*dependency); + generateIR(*dependency, _unoptimizedOnly); if (!_contract.canBeDeployed()) return; @@ -1485,9 +1494,14 @@ void CompilerStack::generateIR(ContractDefinition const& _contract) { YulStack stack = parseYul(compiledContract.yulIR); compiledContract.yulIRAst = stack.astJson(); - stack.optimize(); - compiledContract.yulIROptimized = stack.print(this); + if (!_unoptimizedOnly) + { + stack.optimize(); + compiledContract.yulIROptimized = stack.print(this); + } } + + if (!_unoptimizedOnly) { // Optimizer does not maintain correct native source locations in the AST. // We can work around it by regenerating the AST from scratch from optimized IR. diff --git a/libsolidity/interface/CompilerStack.h b/libsolidity/interface/CompilerStack.h index 6ad868ad09fe..2c5ecb132b94 100644 --- a/libsolidity/interface/CompilerStack.h +++ b/libsolidity/interface/CompilerStack.h @@ -126,6 +126,12 @@ class CompilerStack: public langutil::CharStreamProvider, public evmasm::Abstrac SolidityAST, }; + enum class IROutputSelection { + None, + UnoptimizedOnly, + UnoptimizedAndOptimized, + }; + /// Creates a new compiler stack. /// @param _readFile callback used to read files for import statements. Must return /// and must not emit exceptions. @@ -192,8 +198,14 @@ class CompilerStack: public langutil::CharStreamProvider, public evmasm::Abstrac /// Enable EVM Bytecode generation. This is enabled by default. void enableEvmBytecodeGeneration(bool _enable = true) { m_generateEvmBytecode = _enable; } - /// Enable generation of Yul IR code. - void enableIRGeneration(bool _enable = true) { m_generateIR = _enable; } + /// Enable generation of Yul IR code so that IR output can be safely requested for all contracts. + /// Note that IR may also be implicitly generated when not requested. In particular + /// @a setViaIR(true) requires access to the IR outputs for bytecode generation. + void requestIROutputs(IROutputSelection _selection = IROutputSelection::UnoptimizedAndOptimized) + { + solAssert(m_stackState < ParsedAndImported); + m_irOutputSelection = _selection; + } /// @arg _metadataLiteralSources When true, store sources as literals in the contract metadata. /// Must be set before parsing. @@ -453,7 +465,10 @@ class CompilerStack: public langutil::CharStreamProvider, public evmasm::Abstrac /// generation if compilation via IR is enabled. Note that whether "optimized IR" is actually /// optimized depends on the optimizer settings. /// @param _contract Contract to generate IR for. - void generateIR(ContractDefinition const& _contract); + /// @param _unoptimizedOnly If true, only the IR coming directly from the codegen is stored. + /// Optimizer is not invoked and optimized IR output is not available, which means that + /// optimized IR, its AST or compilation via IR must not be requested. + void generateIR(ContractDefinition const& _contract, bool _unoptimizedOnly); /// Generate EVM representation for a single contract. /// Depends on output generated by generateIR. @@ -518,7 +533,7 @@ class CompilerStack: public langutil::CharStreamProvider, public evmasm::Abstrac ModelCheckerSettings m_modelCheckerSettings; std::map> m_requestedContractNames; bool m_generateEvmBytecode = true; - bool m_generateIR = false; + IROutputSelection m_irOutputSelection = IROutputSelection::None; std::map m_libraries; ImportRemapper m_importRemapper; std::map m_sources; diff --git a/libsolidity/interface/StandardCompiler.cpp b/libsolidity/interface/StandardCompiler.cpp index b908ab0cc6fd..cb0c8126820e 100644 --- a/libsolidity/interface/StandardCompiler.cpp +++ b/libsolidity/interface/StandardCompiler.cpp @@ -295,25 +295,26 @@ bool isEvmBytecodeRequested(Json const& _outputSelection) return false; } -/// @returns true if any Yul IR was requested. Note that as an exception, '*' does not -/// yet match "ir", "irAst", "irOptimized" or "irOptimizedAst" -bool isIRRequested(Json const& _outputSelection) +/// @returns The IR output selection for CompilerStack, based on outputs requested in the JSON. +/// Note that as an exception, '*' does not yet match "ir", "irAst", "irOptimized" or "irOptimizedAst". +CompilerStack::IROutputSelection irOutputSelection(Json const& _outputSelection) { if (!_outputSelection.is_object()) - return false; + return CompilerStack::IROutputSelection::None; + CompilerStack::IROutputSelection selection = CompilerStack::IROutputSelection::None; for (auto const& fileRequests: _outputSelection) for (auto const& requests: fileRequests) for (auto const& request: requests) - if ( - request == "ir" || - request == "irAst" || - request == "irOptimized" || - request == "irOptimizedAst" - ) - return true; + { + if (request == "irOptimized" || request == "irOptimizedAst") + return CompilerStack::IROutputSelection::UnoptimizedAndOptimized; - return false; + if (request == "ir" || request == "irAst") + selection = CompilerStack::IROutputSelection::UnoptimizedOnly; + } + + return selection; } Json formatLinkReferences(std::map const& linkReferences) @@ -1320,7 +1321,7 @@ Json StandardCompiler::compileSolidity(StandardCompiler::InputsAndSettings _inpu compilerStack.setModelCheckerSettings(_inputsAndSettings.modelCheckerSettings); compilerStack.enableEvmBytecodeGeneration(isEvmBytecodeRequested(_inputsAndSettings.outputSelection)); - compilerStack.enableIRGeneration(isIRRequested(_inputsAndSettings.outputSelection)); + compilerStack.requestIROutputs(irOutputSelection(_inputsAndSettings.outputSelection)); Json errors = std::move(_inputsAndSettings.errors); diff --git a/solc/CommandLineInterface.cpp b/solc/CommandLineInterface.cpp index e2d1e2701dc8..5d0272dfa930 100644 --- a/solc/CommandLineInterface.cpp +++ b/solc/CommandLineInterface.cpp @@ -849,12 +849,14 @@ void CommandLineInterface::compile() m_compiler->setRevertStringBehaviour(m_options.output.revertStrings); if (m_options.output.debugInfoSelection.has_value()) m_compiler->selectDebugInfo(m_options.output.debugInfoSelection.value()); - m_compiler->enableIRGeneration( - m_options.compiler.outputs.ir || - m_options.compiler.outputs.irOptimized || - m_options.compiler.outputs.irAstJson || - m_options.compiler.outputs.irOptimizedAstJson - ); + + CompilerStack::IROutputSelection irOutputSelection = CompilerStack::IROutputSelection::None; + if (m_options.compiler.outputs.irOptimized || m_options.compiler.outputs.irOptimizedAstJson) + irOutputSelection = CompilerStack::IROutputSelection::UnoptimizedAndOptimized; + else if (m_options.compiler.outputs.ir || m_options.compiler.outputs.irAstJson) + irOutputSelection = CompilerStack::IROutputSelection::UnoptimizedOnly; + + m_compiler->requestIROutputs(irOutputSelection); m_compiler->enableEvmBytecodeGeneration( m_options.compiler.estimateGas || m_options.compiler.outputs.asm_ || diff --git a/test/cmdlineTests/ir_optimized_with_optimize/args b/test/cmdlineTests/ir_optimized_with_optimize/args new file mode 100644 index 000000000000..a536442c5ce2 --- /dev/null +++ b/test/cmdlineTests/ir_optimized_with_optimize/args @@ -0,0 +1 @@ +--ir-optimized --optimize --debug-info none diff --git a/test/cmdlineTests/ir_optimized_with_optimize/input.sol b/test/cmdlineTests/ir_optimized_with_optimize/input.sol new file mode 100644 index 000000000000..a3a86cc8d317 --- /dev/null +++ b/test/cmdlineTests/ir_optimized_with_optimize/input.sol @@ -0,0 +1,4 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity *; + +contract C {} diff --git a/test/cmdlineTests/ir_optimized_with_optimize/output b/test/cmdlineTests/ir_optimized_with_optimize/output new file mode 100644 index 000000000000..8790e45d353d --- /dev/null +++ b/test/cmdlineTests/ir_optimized_with_optimize/output @@ -0,0 +1,19 @@ +Optimized IR: +/// @use-src 0:"ir_optimized_with_optimize/input.sol" +object "C_2" { + code { + { + let _1 := memoryguard(0x80) + mstore(64, _1) + if callvalue() { revert(0, 0) } + let _2 := datasize("C_2_deployed") + codecopy(_1, dataoffset("C_2_deployed"), _2) + return(_1, _2) + } + } + /// @use-src 0:"ir_optimized_with_optimize/input.sol" + object "C_2_deployed" { + code { { revert(0, 0) } } + data ".metadata" hex"" + } +} diff --git a/test/cmdlineTests/ir_unoptimized_with_optimize/args b/test/cmdlineTests/ir_unoptimized_with_optimize/args new file mode 100644 index 000000000000..cdfef46500af --- /dev/null +++ b/test/cmdlineTests/ir_unoptimized_with_optimize/args @@ -0,0 +1 @@ +--ir --optimize --debug-info none diff --git a/test/cmdlineTests/ir_unoptimized_with_optimize/input.sol b/test/cmdlineTests/ir_unoptimized_with_optimize/input.sol new file mode 100644 index 000000000000..a3a86cc8d317 --- /dev/null +++ b/test/cmdlineTests/ir_unoptimized_with_optimize/input.sol @@ -0,0 +1,4 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity *; + +contract C {} diff --git a/test/cmdlineTests/ir_unoptimized_with_optimize/output b/test/cmdlineTests/ir_unoptimized_with_optimize/output new file mode 100644 index 000000000000..c5307123f0f5 --- /dev/null +++ b/test/cmdlineTests/ir_unoptimized_with_optimize/output @@ -0,0 +1,58 @@ +IR: + +/// @use-src 0:"ir_unoptimized_with_optimize/input.sol" +object "C_2" { + code { + + mstore(64, memoryguard(128)) + if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } + + constructor_C_2() + + let _1 := allocate_unbounded() + codecopy(_1, dataoffset("C_2_deployed"), datasize("C_2_deployed")) + + return(_1, datasize("C_2_deployed")) + + function allocate_unbounded() -> memPtr { + memPtr := mload(64) + } + + function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() { + revert(0, 0) + } + + function constructor_C_2() { + + } + + } + /// @use-src 0:"ir_unoptimized_with_optimize/input.sol" + object "C_2_deployed" { + code { + + mstore(64, memoryguard(128)) + + revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() + + function shift_right_224_unsigned(value) -> newValue { + newValue := + + shr(224, value) + + } + + function allocate_unbounded() -> memPtr { + memPtr := mload(64) + } + + function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() { + revert(0, 0) + } + + } + + data ".metadata" hex"" + } + +} diff --git a/test/cmdlineTests/ir_unoptimized_with_optimize_via_ir/args b/test/cmdlineTests/ir_unoptimized_with_optimize_via_ir/args new file mode 100644 index 000000000000..c8c9fa85e744 --- /dev/null +++ b/test/cmdlineTests/ir_unoptimized_with_optimize_via_ir/args @@ -0,0 +1 @@ +--ir --optimize --via-ir --debug-info none diff --git a/test/cmdlineTests/ir_unoptimized_with_optimize_via_ir/input.sol b/test/cmdlineTests/ir_unoptimized_with_optimize_via_ir/input.sol new file mode 100644 index 000000000000..a3a86cc8d317 --- /dev/null +++ b/test/cmdlineTests/ir_unoptimized_with_optimize_via_ir/input.sol @@ -0,0 +1,4 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity *; + +contract C {} diff --git a/test/cmdlineTests/ir_unoptimized_with_optimize_via_ir/output b/test/cmdlineTests/ir_unoptimized_with_optimize_via_ir/output new file mode 100644 index 000000000000..f5ecdd8bf5f0 --- /dev/null +++ b/test/cmdlineTests/ir_unoptimized_with_optimize_via_ir/output @@ -0,0 +1,58 @@ +IR: + +/// @use-src 0:"ir_unoptimized_with_optimize_via_ir/input.sol" +object "C_2" { + code { + + mstore(64, memoryguard(128)) + if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } + + constructor_C_2() + + let _1 := allocate_unbounded() + codecopy(_1, dataoffset("C_2_deployed"), datasize("C_2_deployed")) + + return(_1, datasize("C_2_deployed")) + + function allocate_unbounded() -> memPtr { + memPtr := mload(64) + } + + function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() { + revert(0, 0) + } + + function constructor_C_2() { + + } + + } + /// @use-src 0:"ir_unoptimized_with_optimize_via_ir/input.sol" + object "C_2_deployed" { + code { + + mstore(64, memoryguard(128)) + + revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() + + function shift_right_224_unsigned(value) -> newValue { + newValue := + + shr(224, value) + + } + + function allocate_unbounded() -> memPtr { + memPtr := mload(64) + } + + function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() { + revert(0, 0) + } + + } + + data ".metadata" hex"" + } + +} diff --git a/test/cmdlineTests/standard_ir_unoptimized_with_optimize/input.json b/test/cmdlineTests/standard_ir_unoptimized_with_optimize/input.json new file mode 100644 index 000000000000..d12265a3869e --- /dev/null +++ b/test/cmdlineTests/standard_ir_unoptimized_with_optimize/input.json @@ -0,0 +1,11 @@ +{ + "language": "Solidity", + "sources": { + "C.sol": {"content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity *; contract C {}"} + }, + "settings": { + "outputSelection": {"*": {"*": ["ir"]}}, + "optimizer": {"enabled": true}, + "debug": {"debugInfo": []} + } +} diff --git a/test/cmdlineTests/standard_ir_unoptimized_with_optimize/output.json b/test/cmdlineTests/standard_ir_unoptimized_with_optimize/output.json new file mode 100644 index 000000000000..d197231268dd --- /dev/null +++ b/test/cmdlineTests/standard_ir_unoptimized_with_optimize/output.json @@ -0,0 +1,72 @@ +{ + "contracts": { + "C.sol": { + "C": { + "ir": " +/// @use-src 0:\"C.sol\" +object \"C_2\" { + code { + + mstore(64, memoryguard(128)) + if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } + + constructor_C_2() + + let _1 := allocate_unbounded() + codecopy(_1, dataoffset(\"C_2_deployed\"), datasize(\"C_2_deployed\")) + + return(_1, datasize(\"C_2_deployed\")) + + function allocate_unbounded() -> memPtr { + memPtr := mload(64) + } + + function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() { + revert(0, 0) + } + + function constructor_C_2() { + + } + + } + /// @use-src 0:\"C.sol\" + object \"C_2_deployed\" { + code { + + mstore(64, memoryguard(128)) + + revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() + + function shift_right_224_unsigned(value) -> newValue { + newValue := + + shr(224, value) + + } + + function allocate_unbounded() -> memPtr { + memPtr := mload(64) + } + + function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() { + revert(0, 0) + } + + } + + data \".metadata\" hex\"\" + } + +} + +" + } + } + }, + "sources": { + "C.sol": { + "id": 0 + } + } +} diff --git a/test/cmdlineTests/standard_ir_unoptimized_with_optimize_via_ir/input.json b/test/cmdlineTests/standard_ir_unoptimized_with_optimize_via_ir/input.json new file mode 100644 index 000000000000..06b89d0e01bf --- /dev/null +++ b/test/cmdlineTests/standard_ir_unoptimized_with_optimize_via_ir/input.json @@ -0,0 +1,12 @@ +{ + "language": "Solidity", + "sources": { + "C.sol": {"content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity *; contract C {}"} + }, + "settings": { + "outputSelection": {"*": {"*": ["ir"]}}, + "optimizer": {"enabled": true}, + "viaIR": true, + "debug": {"debugInfo": []} + } +} diff --git a/test/cmdlineTests/standard_ir_unoptimized_with_optimize_via_ir/output.json b/test/cmdlineTests/standard_ir_unoptimized_with_optimize_via_ir/output.json new file mode 100644 index 000000000000..d197231268dd --- /dev/null +++ b/test/cmdlineTests/standard_ir_unoptimized_with_optimize_via_ir/output.json @@ -0,0 +1,72 @@ +{ + "contracts": { + "C.sol": { + "C": { + "ir": " +/// @use-src 0:\"C.sol\" +object \"C_2\" { + code { + + mstore(64, memoryguard(128)) + if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } + + constructor_C_2() + + let _1 := allocate_unbounded() + codecopy(_1, dataoffset(\"C_2_deployed\"), datasize(\"C_2_deployed\")) + + return(_1, datasize(\"C_2_deployed\")) + + function allocate_unbounded() -> memPtr { + memPtr := mload(64) + } + + function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() { + revert(0, 0) + } + + function constructor_C_2() { + + } + + } + /// @use-src 0:\"C.sol\" + object \"C_2_deployed\" { + code { + + mstore(64, memoryguard(128)) + + revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() + + function shift_right_224_unsigned(value) -> newValue { + newValue := + + shr(224, value) + + } + + function allocate_unbounded() -> memPtr { + memPtr := mload(64) + } + + function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() { + revert(0, 0) + } + + } + + data \".metadata\" hex\"\" + } + +} + +" + } + } + }, + "sources": { + "C.sol": { + "id": 0 + } + } +} From f89e83bbb091be506105f17eb7caf6ec1f63ec51 Mon Sep 17 00:00:00 2001 From: clonker Date: Fri, 12 Jul 2024 10:13:04 +0200 Subject: [PATCH 0318/1022] yul: AsmPrinter has mode enum to determine printing mode instead of dialect pointer --- libsolidity/codegen/CompilerContext.cpp | 4 ++-- .../codegen/ir/IRGeneratorForStatements.cpp | 3 +-- .../codegen/IRGeneratorForStatements.cpp | 2 +- libyul/AsmPrinter.cpp | 10 +++++++--- libyul/AsmPrinter.h | 20 ++++++++++--------- libyul/Object.cpp | 8 +++++--- libyul/Object.h | 10 +++++++--- libyul/YulStack.cpp | 7 ++++++- libyul/optimiser/Suite.cpp | 2 +- test/libyul/Common.cpp | 4 +++- test/libyul/Parser.cpp | 10 ++++------ test/libyul/YulOptimizerTest.cpp | 2 +- test/tools/yulopti.cpp | 4 ++-- tools/yulPhaser/Program.cpp | 2 +- 14 files changed, 52 insertions(+), 36 deletions(-) diff --git a/libsolidity/codegen/CompilerContext.cpp b/libsolidity/codegen/CompilerContext.cpp index 4d522072af06..962defdbc8e1 100644 --- a/libsolidity/codegen/CompilerContext.cpp +++ b/libsolidity/codegen/CompilerContext.cpp @@ -491,8 +491,8 @@ void CompilerContext::appendInlineAssembly( { // Store as generated sources, but first re-parse to update the source references. solAssert(m_generatedYulUtilityCode.empty(), ""); - m_generatedYulUtilityCode = yul::AsmPrinter(dialect)(*obj.code); - std::string code = yul::AsmPrinter{dialect}(*obj.code); + m_generatedYulUtilityCode = yul::AsmPrinter(yul::AsmPrinter::TypePrinting::OmitDefault, dialect)(*obj.code); + std::string code = yul::AsmPrinter{yul::AsmPrinter::TypePrinting::OmitDefault, dialect}(*obj.code); langutil::CharStream charStream(m_generatedYulUtilityCode, _sourceName); obj.code = yul::Parser(errorReporter, dialect).parse(charStream); *obj.analysisInfo = yul::AsmAnalyzer::analyzeStrictAssertCorrect(dialect, obj); diff --git a/libsolidity/codegen/ir/IRGeneratorForStatements.cpp b/libsolidity/codegen/ir/IRGeneratorForStatements.cpp index 5be4d550e767..4f4f96329aad 100644 --- a/libsolidity/codegen/ir/IRGeneratorForStatements.cpp +++ b/libsolidity/codegen/ir/IRGeneratorForStatements.cpp @@ -2256,8 +2256,7 @@ bool IRGeneratorForStatements::visit(InlineAssembly const& _inlineAsm) solAssert(std::holds_alternative(modified)); - // Do not provide dialect so that we get the full type information. - appendCode() << yul::AsmPrinter()(std::get(modified)) << "\n"; + appendCode() << yul::AsmPrinter(yul::AsmPrinter::TypePrinting::Full, _inlineAsm.dialect())(std::get(modified)) << "\n"; return false; } diff --git a/libsolidity/experimental/codegen/IRGeneratorForStatements.cpp b/libsolidity/experimental/codegen/IRGeneratorForStatements.cpp index f9c50cf7a78c..109c3ee6f103 100644 --- a/libsolidity/experimental/codegen/IRGeneratorForStatements.cpp +++ b/libsolidity/experimental/codegen/IRGeneratorForStatements.cpp @@ -132,7 +132,7 @@ bool IRGeneratorForStatements::visit(InlineAssembly const& _assembly) CopyTranslate bodyCopier{m_context, _assembly.dialect(), _assembly.annotation().externalReferences}; yul::Statement modified = bodyCopier(_assembly.operations()); solAssert(std::holds_alternative(modified)); - m_code << yul::AsmPrinter()(std::get(modified)) << "\n"; + m_code << yul::AsmPrinter(yul::AsmPrinter::TypePrinting::Full, _assembly.dialect())(std::get(modified)) << "\n"; return false; } diff --git a/libyul/AsmPrinter.cpp b/libyul/AsmPrinter.cpp index 054f83a91398..6b840fcfeae4 100644 --- a/libyul/AsmPrinter.cpp +++ b/libyul/AsmPrinter.cpp @@ -245,11 +245,15 @@ std::string AsmPrinter::formatTypedName(TypedName _variable) std::string AsmPrinter::appendTypeName(YulName _type, bool _isBoolLiteral) const { - if (m_dialect && !_type.empty()) + yulAssert( + m_typePrintingMode == TypePrinting::OmitDefault || m_typePrintingMode == TypePrinting::Full, + "unhandled printing mode" + ); + if (m_typePrintingMode == TypePrinting::OmitDefault && !_type.empty()) { - if (!_isBoolLiteral && _type == m_dialect->defaultType) + if (!_isBoolLiteral && _type == m_dialect.defaultType) _type = {}; - else if (_isBoolLiteral && _type == m_dialect->boolType && !m_dialect->defaultType.empty()) + else if (_isBoolLiteral && _type == m_dialect.boolType && !m_dialect.defaultType.empty()) // Special case: If we have a bool type but empty default type, do not remove the type. _type = {}; } diff --git a/libyul/AsmPrinter.h b/libyul/AsmPrinter.h index 36ea06c76769..684ddaacf0d5 100644 --- a/libyul/AsmPrinter.h +++ b/libyul/AsmPrinter.h @@ -46,12 +46,20 @@ struct Dialect; class AsmPrinter { public: + enum class TypePrinting + { + OmitDefault, + Full + }; + explicit AsmPrinter( - Dialect const* _dialect = nullptr, + TypePrinting const _typePrintingMode, + Dialect const& _dialect, std::optional>> _sourceIndexToName = {}, langutil::DebugInfoSelection const& _debugInfoSelection = langutil::DebugInfoSelection::Default(), langutil::CharStreamProvider const* _soliditySourceProvider = nullptr ): + m_typePrintingMode(_typePrintingMode), m_dialect(_dialect), m_debugInfoSelection(_debugInfoSelection), m_soliditySourceProvider(_soliditySourceProvider) @@ -61,13 +69,6 @@ class AsmPrinter m_nameToSourceIndex[*name] = index; } - explicit AsmPrinter( - Dialect const& _dialect, - std::optional>> _sourceIndexToName = {}, - langutil::DebugInfoSelection const& _debugInfoSelection = langutil::DebugInfoSelection::Default(), - langutil::CharStreamProvider const* _soliditySourceProvider = nullptr - ): AsmPrinter(&_dialect, _sourceIndexToName, _debugInfoSelection, _soliditySourceProvider) {} - std::string operator()(Literal const& _literal); std::string operator()(Identifier const& _identifier); std::string operator()(ExpressionStatement const& _expr); @@ -101,7 +102,8 @@ class AsmPrinter return formatDebugData(_node.debugData, !isExpression); } - Dialect const* const m_dialect = nullptr; + TypePrinting const m_typePrintingMode{}; + Dialect const& m_dialect; std::map m_nameToSourceIndex; langutil::SourceLocation m_lastLocation = {}; langutil::DebugInfoSelection m_debugInfoSelection = {}; diff --git a/libyul/Object.cpp b/libyul/Object.cpp index 76d8bdc66780..736c1bb8411e 100644 --- a/libyul/Object.cpp +++ b/libyul/Object.cpp @@ -38,13 +38,14 @@ using namespace solidity::langutil; using namespace solidity::util; using namespace solidity::yul; -std::string Data::toString(Dialect const*, DebugInfoSelection const&, CharStreamProvider const*) const +std::string Data::toString(Dialect const&, AsmPrinter::TypePrinting, DebugInfoSelection const&, CharStreamProvider const*) const { return "data \"" + name + "\" hex\"" + util::toHex(data) + "\""; } std::string Object::toString( - Dialect const* _dialect, + Dialect const& _dialect, + AsmPrinter::TypePrinting const _printingMode, DebugInfoSelection const& _debugInfoSelection, CharStreamProvider const* _soliditySourceProvider ) const @@ -63,6 +64,7 @@ std::string Object::toString( "\n"; std::string inner = "code " + AsmPrinter( + _printingMode, _dialect, debugData->sourceNames, _debugInfoSelection, @@ -70,7 +72,7 @@ std::string Object::toString( )(*code); for (auto const& obj: subObjects) - inner += "\n" + obj->toString(_dialect, _debugInfoSelection, _soliditySourceProvider); + inner += "\n" + obj->toString(_dialect, _printingMode, _debugInfoSelection, _soliditySourceProvider); return useSrcComment + "object \"" + name + "\" {\n" + indent(inner) + "\n}"; } diff --git a/libyul/Object.h b/libyul/Object.h index af354005b66b..4e891c26400a 100644 --- a/libyul/Object.h +++ b/libyul/Object.h @@ -21,6 +21,7 @@ #pragma once +#include #include #include @@ -53,7 +54,8 @@ struct ObjectNode /// Can be empty since .yul files can also just contain code, without explicitly placing it in an object. std::string name; virtual std::string toString( - Dialect const* _dialect, + Dialect const& _dialect, + AsmPrinter::TypePrinting printingMode, langutil::DebugInfoSelection const& _debugInfoSelection, langutil::CharStreamProvider const* _soliditySourceProvider ) const = 0; @@ -70,7 +72,8 @@ struct Data: public ObjectNode bytes data; std::string toString( - Dialect const* _dialect, + Dialect const& _dialect, + AsmPrinter::TypePrinting printingMode, langutil::DebugInfoSelection const& _debugInfoSelection, langutil::CharStreamProvider const* _soliditySourceProvider ) const override; @@ -92,7 +95,8 @@ struct Object: public ObjectNode public: /// @returns a (parseable) string representation. std::string toString( - Dialect const* _dialect, + Dialect const& _dialect, + AsmPrinter::TypePrinting printingMode = AsmPrinter::TypePrinting::Full, langutil::DebugInfoSelection const& _debugInfoSelection = langutil::DebugInfoSelection::Default(), langutil::CharStreamProvider const* _soliditySourceProvider = nullptr ) const; diff --git a/libyul/YulStack.cpp b/libyul/YulStack.cpp index 9aaaab2eb20d..223d6c04a19b 100644 --- a/libyul/YulStack.cpp +++ b/libyul/YulStack.cpp @@ -365,7 +365,12 @@ std::string YulStack::print( yulAssert(m_stackState >= Parsed); yulAssert(m_parserResult, ""); yulAssert(m_parserResult->code, ""); - return m_parserResult->toString(&languageToDialect(m_language, m_evmVersion), m_debugInfoSelection, _soliditySourceProvider) + "\n"; + return m_parserResult->toString( + languageToDialect(m_language, m_evmVersion), + AsmPrinter::TypePrinting::OmitDefault, + m_debugInfoSelection, + _soliditySourceProvider + ) + "\n"; } Json YulStack::astJson() const diff --git a/libyul/optimiser/Suite.cpp b/libyul/optimiser/Suite.cpp index c4004948c838..c022fb0d7451 100644 --- a/libyul/optimiser/Suite.cpp +++ b/libyul/optimiser/Suite.cpp @@ -510,7 +510,7 @@ void OptimiserSuite::runSequence(std::vector const& _steps, Block& else { std::cout << "== Running " << step << " changed the AST." << std::endl; - std::cout << AsmPrinter{}(_ast) << std::endl; + std::cout << AsmPrinter{AsmPrinter::TypePrinting::Full, m_context.dialect}(_ast) << std::endl; copy = std::make_unique(std::get(ASTCopier{}(_ast))); } } diff --git a/test/libyul/Common.cpp b/test/libyul/Common.cpp index 10d7d12adddd..dece0d82b10e 100644 --- a/test/libyul/Common.cpp +++ b/test/libyul/Common.cpp @@ -96,7 +96,9 @@ yul::Block yul::test::disambiguate(std::string const& _source, bool _yul) std::string yul::test::format(std::string const& _source, bool _yul) { - return yul::AsmPrinter()(*parse(_source, _yul).first); + auto const version = solidity::test::CommonOptions::get().evmVersion(); + Dialect const& dialect = _yul ? EVMDialectTyped::instance(version) : EVMDialect::strictAssemblyForEVMObjects(version); + return yul::AsmPrinter(yul::AsmPrinter::TypePrinting::Full, dialect)(*parse(_source, _yul).first); } namespace diff --git a/test/libyul/Parser.cpp b/test/libyul/Parser.cpp index faa6c6105f2d..7b3cdac8b2b1 100644 --- a/test/libyul/Parser.cpp +++ b/test/libyul/Parser.cpp @@ -164,9 +164,8 @@ BOOST_AUTO_TEST_CASE(default_types_set) ); BOOST_REQUIRE(!!result && errorList.size() == 0); - // Use no dialect so that all types are printed. - // This tests that the default types are properly assigned. - BOOST_CHECK_EQUAL(AsmPrinter{}(*result), + // All types are printed. + BOOST_CHECK_EQUAL(AsmPrinter(AsmPrinter::TypePrinting::Full, EVMDialectTyped::instance(EVMVersion()))(*result), "{\n" " let x:bool := true:bool\n" " let z:bool := true:bool\n" @@ -177,9 +176,8 @@ BOOST_AUTO_TEST_CASE(default_types_set) "}" ); - // Now test again with type dialect. Now the default types - // should be omitted. - BOOST_CHECK_EQUAL(AsmPrinter{EVMDialectTyped::instance(EVMVersion{})}(*result), + // Now the default types should be omitted. + BOOST_CHECK_EQUAL(AsmPrinter(AsmPrinter::TypePrinting::OmitDefault, EVMDialectTyped::instance(EVMVersion()))(*result), "{\n" " let x:bool := true\n" " let z:bool := true\n" diff --git a/test/libyul/YulOptimizerTest.cpp b/test/libyul/YulOptimizerTest.cpp index 82e2549809e2..b30fa825112a 100644 --- a/test/libyul/YulOptimizerTest.cpp +++ b/test/libyul/YulOptimizerTest.cpp @@ -78,7 +78,7 @@ TestCase::TestResult YulOptimizerTest::run(std::ostream& _stream, std::string co return TestResult::FatalError; } - auto const printed = (m_object->subObjects.empty() ? AsmPrinter{ *m_dialect }(*m_object->code) : m_object->toString(m_dialect)); + auto const printed = (m_object->subObjects.empty() ? AsmPrinter{AsmPrinter::TypePrinting::OmitDefault, *m_dialect}(*m_object->code) : m_object->toString(*m_dialect)); // Re-parse new code for compilability if (!std::get<0>(parse(_stream, _linePrefix, _formatted, printed))) diff --git a/test/tools/yulopti.cpp b/test/tools/yulopti.cpp index 7e81cbf7e34e..2b9e530e0254 100644 --- a/test/tools/yulopti.cpp +++ b/test/tools/yulopti.cpp @@ -181,7 +181,7 @@ class YulOpti parse(_source); disambiguate(); OptimiserSuite{m_context}.runSequence(_steps, *m_ast); - std::cout << AsmPrinter{m_dialect}(*m_ast) << std::endl; + std::cout << AsmPrinter{AsmPrinter::TypePrinting::OmitDefault, m_dialect}(*m_ast) << std::endl; } void runInteractive(std::string _source, bool _disambiguated = false) @@ -229,7 +229,7 @@ class YulOpti *m_ast ); } - _source = AsmPrinter{m_dialect}(*m_ast); + _source = AsmPrinter{AsmPrinter::TypePrinting::OmitDefault, m_dialect}(*m_ast); } catch (...) { diff --git a/tools/yulPhaser/Program.cpp b/tools/yulPhaser/Program.cpp index 0cb22242d0fe..e0c8ec4fbed6 100644 --- a/tools/yulPhaser/Program.cpp +++ b/tools/yulPhaser/Program.cpp @@ -105,7 +105,7 @@ void Program::optimise(std::vector const& _optimisationSteps) std::ostream& phaser::operator<<(std::ostream& _stream, Program const& _program) { - return _stream << AsmPrinter()(*_program.m_ast); + return _stream << AsmPrinter(AsmPrinter::TypePrinting::Full, _program.m_dialect)(*_program.m_ast); } std::string Program::toJson() const From 5af111584df90e8ff33c62636b419afa4957e50e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kaan=20Uzdo=C4=9Fan?= Date: Thu, 25 Jul 2024 17:41:26 +0200 Subject: [PATCH 0319/1022] Add library abi notes in ABI page --- docs/abi-spec.rst | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/abi-spec.rst b/docs/abi-spec.rst index 0d48b51dd706..91da5127c5aa 100644 --- a/docs/abi-spec.rst +++ b/docs/abi-spec.rst @@ -16,7 +16,7 @@ as described in this specification. The encoding is not self describing and thus We assume that the interface functions of a contract are strongly typed, known at compilation time and static. We assume that all contracts will have the interface definitions of any contracts they call available at compile-time. -This specification does not address contracts whose interface is dynamic or otherwise known only at run-time. +This specification does not address contracts whose interface is dynamic or otherwise known only at run-time. Also, the ABI specification for libraries is :ref:`slightly different `. .. _abi_function_selector: .. index:: ! selector; of a function @@ -47,6 +47,8 @@ without the four bytes specifying the function. Types ===== +Note that the library ABIs can take types different than below e.g. for non-storage structs. See :ref:`library selectors ` for details. + The following elementary types exist: - ``uint``: unsigned integer type of ``M`` bits, ``0 < M <= 256``, ``M % 8 == 0``. e.g. ``uint32``, ``uint8``, ``uint256``. From 911ab3c1b65ae65bbb49a07dffce3520fe700028 Mon Sep 17 00:00:00 2001 From: Martin Blicha Date: Thu, 20 Jun 2024 14:24:11 +0200 Subject: [PATCH 0320/1022] SMTChecker: Introduce SMT-LIB context Maintaining SMT-LIB context has two advantages. First, it simplifies parsing back solvers' answer as we keep around all the declarations of datatypes and variables. Second, it clears SMTLibInterface (CHCSmtLibInterface) as we factor out the members and functinality related to SMT-LIB context. --- libsmtutil/BMCSolverInterface.h | 51 ++ libsmtutil/CHCSmtLib2Interface.cpp | 481 ++++++-------- libsmtutil/CHCSmtLib2Interface.h | 52 +- libsmtutil/CHCSolverInterface.h | 6 +- libsmtutil/CMakeLists.txt | 2 + libsmtutil/SMTLib2Context.cpp | 314 ++++++++++ libsmtutil/SMTLib2Context.h | 109 ++++ libsmtutil/SMTLib2Interface.cpp | 268 +++----- libsmtutil/SMTLib2Interface.h | 60 +- libsmtutil/SMTPortfolio.cpp | 4 +- libsmtutil/SMTPortfolio.h | 8 +- libsmtutil/SolverInterface.h | 19 +- libsmtutil/Z3Interface.cpp | 2 +- libsmtutil/Z3Interface.h | 4 +- libsolidity/formal/BMC.cpp | 2 +- libsolidity/formal/BMC.h | 4 +- libsolidity/formal/CHC.cpp | 3 +- .../formal/EldaricaCHCSmtLib2Interface.cpp | 4 +- .../formal/EldaricaCHCSmtLib2Interface.h | 2 +- .../model_checker_print_query_all/err | 191 +++--- .../model_checker_print_query_bmc/err | 1 - .../model_checker_print_query_chc/err | 190 +++--- .../output.json | 593 +++++++----------- .../output.json | 5 +- .../output.json | 572 +++++++---------- .../output.json | 195 +++--- .../invariants/array_access.sol | 20 + .../invariants/struct_access.sol | 15 + 28 files changed, 1599 insertions(+), 1578 deletions(-) create mode 100644 libsmtutil/BMCSolverInterface.h create mode 100644 libsmtutil/SMTLib2Context.cpp create mode 100644 libsmtutil/SMTLib2Context.h create mode 100644 test/libsolidity/smtCheckerTests/invariants/array_access.sol create mode 100644 test/libsolidity/smtCheckerTests/invariants/struct_access.sol diff --git a/libsmtutil/BMCSolverInterface.h b/libsmtutil/BMCSolverInterface.h new file mode 100644 index 000000000000..3681b21e4323 --- /dev/null +++ b/libsmtutil/BMCSolverInterface.h @@ -0,0 +1,51 @@ +/* + 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::smtutil +{ + +class BMCSolverInterface : public SolverInterface +{ +public: + explicit BMCSolverInterface(std::optional _queryTimeout = {}): m_queryTimeout(_queryTimeout) {} + + ~BMCSolverInterface() override = default; + virtual void reset() = 0; + + virtual void push() = 0; + virtual void pop() = 0; + + virtual void addAssertion(Expression const& _expr) = 0; + + /// Checks for satisfiability, evaluates the expressions if a model + /// is available. Throws SMTSolverError on error. + virtual std::pair> + check(std::vector const& _expressionsToEvaluate) = 0; + + /// @returns a list of queries that the system was not able to respond to. + virtual std::vector unhandledQueries() { return {}; } + +protected: + std::optional m_queryTimeout; +}; + +} diff --git a/libsmtutil/CHCSmtLib2Interface.cpp b/libsmtutil/CHCSmtLib2Interface.cpp index a267a843bb68..8b795b9d5fd9 100644 --- a/libsmtutil/CHCSmtLib2Interface.cpp +++ b/libsmtutil/CHCSmtLib2Interface.cpp @@ -48,48 +48,46 @@ CHCSmtLib2Interface::CHCSmtLib2Interface( std::optional _queryTimeout ): CHCSolverInterface(_queryTimeout), - m_smtlib2(std::make_unique(_queryResponses, _smtCallback, m_queryTimeout)), m_queryResponses(std::move(_queryResponses)), - m_smtCallback(_smtCallback) + m_smtCallback(std::move(_smtCallback)) { reset(); } void CHCSmtLib2Interface::reset() { - m_accumulatedOutput.clear(); - m_variables.clear(); m_unhandledQueries.clear(); - m_smtlib2->reset(); + m_commands.clear(); + m_context.clear(); + createHeader(); + m_context.setTupleDeclarationCallback([&](TupleSort const& _tupleSort){ + m_commands.declareTuple( + _tupleSort.name, + _tupleSort.members, + _tupleSort.components + | ranges::views::transform([&](SortPointer const& _sort){ return m_context.toSmtLibSort(_sort); }) + | ranges::to() + ); + }); } void CHCSmtLib2Interface::registerRelation(Expression const& _expr) { smtAssert(_expr.sort); smtAssert(_expr.sort->kind == Kind::Function); - if (!m_variables.count(_expr.name)) - { - auto fSort = std::dynamic_pointer_cast(_expr.sort); - std::string domain = toSmtLibSort(fSort->domain); - // Relations are predicates which have implicit codomain Bool. - m_variables.insert(_expr.name); - write( - "(declare-fun |" + - _expr.name + - "| " + - domain + - " Bool)" - ); - } + if (m_context.isDeclared(_expr.name)) + return; + auto const& fSort = std::dynamic_pointer_cast(_expr.sort); + smtAssert(fSort->codomain); + auto domain = toSmtLibSort(fSort->domain); + std::string codomain = toSmtLibSort(fSort->codomain); + m_commands.declareFunction(_expr.name, domain, codomain); + m_context.declare(_expr.name, _expr.sort); } void CHCSmtLib2Interface::addRule(Expression const& _expr, std::string const& /*_name*/) { - write( - "(assert\n(forall " + forall() + "\n" + - m_smtlib2->toSExpr(_expr) + - "))\n\n" - ); + m_commands.assertion("(forall" + forall(_expr) + '\n' + m_context.toSExpr(_expr) + ")\n"); } std::tuple CHCSmtLib2Interface::query(Expression const& _block) @@ -117,31 +115,45 @@ std::tuple CHCSmtLib2Inte void CHCSmtLib2Interface::declareVariable(std::string const& _name, SortPointer const& _sort) { smtAssert(_sort); - if (_sort->kind == Kind::Function) - declareFunction(_name, _sort); - else if (!m_variables.count(_name)) - { - m_variables.insert(_name); - write("(declare-var |" + _name + "| " + toSmtLibSort(_sort) + ')'); - } + if (!m_context.isDeclared(_name)) + m_context.declare(_name, _sort); } -std::string CHCSmtLib2Interface::toSmtLibSort(SortPointer _sort) +std::string CHCSmtLib2Interface::toSmtLibSort(SortPointer const& _sort) { - return m_smtlib2->toSmtLibSort(_sort); + return m_context.toSmtLibSort(_sort); } -std::string CHCSmtLib2Interface::toSmtLibSort(std::vector const& _sorts) +std::vector CHCSmtLib2Interface::toSmtLibSort(std::vector const& _sorts) { - return m_smtlib2->toSmtLibSort(_sorts); + return applyMap(_sorts, [this](auto const& sort) { return toSmtLibSort(sort); }); } -std::string CHCSmtLib2Interface::forall() +std::set CHCSmtLib2Interface::collectVariableNames(Expression const& _expr) const { + std::set names; + auto dfs = [&](Expression const& _current, auto _recurse) -> void + { + if (_current.arguments.empty()) + { + if (m_context.isDeclared(_current.name)) + names.insert(_current.name); + } + else + for (auto const& arg: _current.arguments) + _recurse(arg, _recurse); + }; + dfs(_expr, dfs); + return names; +} + +std::string CHCSmtLib2Interface::forall(Expression const& _expr) +{ + auto varNames = collectVariableNames(_expr); std::string vars("("); - for (auto const& [name, sort]: m_smtlib2->variables()) + for (auto const& name: varNames) { - solAssert(sort, ""); + auto sort = m_context.getDeclaredSort(name); if (sort->kind != Kind::Function) vars += " (" + name + " " + toSmtLibSort(sort) + ")"; } @@ -149,35 +161,6 @@ std::string CHCSmtLib2Interface::forall() return vars; } -void CHCSmtLib2Interface::declareFunction(std::string const& _name, SortPointer const& _sort) -{ - smtAssert(_sort); - smtAssert(_sort->kind == Kind::Function); - // TODO Use domain and codomain as key as well - if (!m_variables.count(_name)) - { - auto fSort = std::dynamic_pointer_cast(_sort); - smtAssert(fSort->codomain); - std::string domain = toSmtLibSort(fSort->domain); - std::string codomain = toSmtLibSort(fSort->codomain); - m_variables.insert(_name); - write( - "(declare-fun |" + - _name + - "| " + - domain + - " " + - codomain + - ")" - ); - } -} - -void CHCSmtLib2Interface::write(std::string _data) -{ - m_accumulatedOutput += std::move(_data) + "\n"; -} - std::string CHCSmtLib2Interface::querySolver(std::string const& _input) { util::h256 inputHash = util::keccak256(_input); @@ -186,7 +169,6 @@ std::string CHCSmtLib2Interface::querySolver(std::string const& _input) if (m_smtCallback) { - setupSmtCallback(); auto result = m_smtCallback(ReadCallback::kindString(ReadCallback::Kind::SMTQuery), _input); if (result.success) return result.responseOrErrorMessage; @@ -198,242 +180,194 @@ std::string CHCSmtLib2Interface::querySolver(std::string const& _input) std::string CHCSmtLib2Interface::dumpQuery(Expression const& _expr) { - std::stringstream s; - - s - << createHeaderAndDeclarations() - << m_accumulatedOutput << std::endl - << createQueryAssertion(_expr.name) << std::endl - << "(check-sat)" << std::endl; - - return s.str(); + return m_commands.toString() + createQueryAssertion(_expr.name) + '\n' + "(check-sat)" + '\n'; } -std::string CHCSmtLib2Interface::createHeaderAndDeclarations() { - std::stringstream s; +void CHCSmtLib2Interface::createHeader() +{ if (m_queryTimeout) - s << "(set-option :timeout " + std::to_string(*m_queryTimeout) + ")\n"; - s << "(set-logic HORN)" << std::endl; + m_commands.setOption("timeout", std::to_string(*m_queryTimeout)); + m_commands.setLogic("HORN"); +} - for (auto const& decl: m_smtlib2->userSorts() | ranges::views::values) - s << decl << std::endl; +std::string CHCSmtLib2Interface::createQueryAssertion(std::string _name) { + return "(assert\n(forall ((UNUSED Bool))\n(=> " + std::move(_name) + " false)))"; +} - return s.str(); +namespace +{ +bool isNumber(std::string const& _expr) +{ + return ranges::all_of(_expr, [](char c) { return isDigit(c) || c == '.'; }); +} } -std::string CHCSmtLib2Interface::createQueryAssertion(std::string name) { - return "(assert\n(forall " + forall() + "\n" + "(=> " + name + " false)))"; +void CHCSmtLib2Interface::ScopedParser::addVariableDeclaration(std::string _name, solidity::smtutil::SortPointer _sort) +{ + m_localVariables.emplace(std::move(_name), std::move(_sort)); } -class SMTLibTranslationContext +std::optional CHCSmtLib2Interface::ScopedParser::lookupKnownTupleSort(std::string const& _name) const { - CHCSmtLib2Interface const& m_chcInterface; - std::map m_knownVariables; + return m_context.getTupleType(_name); +} - static bool isNumber(std::string const& _expr) +SortPointer CHCSmtLib2Interface::ScopedParser::toSort(SMTLib2Expression const& _expr) +{ + if (isAtom(_expr)) { - return ranges::all_of(_expr, [](char c) { return isDigit(c) || c == '.'; }); + auto const& name = asAtom(_expr); + if (name == "Int") + return SortProvider::sintSort; + if (name == "Bool") + return SortProvider::boolSort; + auto tupleSort = lookupKnownTupleSort(name); + if (tupleSort) + return tupleSort.value(); } - - -public: - explicit SMTLibTranslationContext(CHCSmtLib2Interface const& _chcInterface) : m_chcInterface(_chcInterface) + else { - // fill user defined sorts and constructors - auto const& userSorts = m_chcInterface.smtlib2Interface()->userSorts(); - for (auto const& declaration: userSorts | ranges::views::values) + auto const& args = asSubExpressions(_expr); + if (asAtom(args[0]) == "Array") { - std::stringstream ss(declaration); - SMTLib2Parser parser(ss); - auto expr = parser.parseExpression(); - smtAssert(parser.isEOF()); - smtAssert(!isAtom(expr)); - auto const& args = asSubExpressions(expr); smtAssert(args.size() == 3); - smtAssert(isAtom(args[0]) && asAtom(args[0]) == "declare-datatypes"); - // args[1] is the name of the type - // args[2] is the constructor with the members - smtAssert(!isAtom(args[2]) && asSubExpressions(args[2]).size() == 1 && !isAtom(asSubExpressions(args[2])[0])); - auto const& constructors = asSubExpressions(asSubExpressions(args[2])[0]); - smtAssert(constructors.size() == 1); - auto const& constructor = constructors[0]; - // constructor is a list: name + members - smtAssert(!isAtom(constructor)); - auto const& constructorArgs = asSubExpressions(constructor); - for (unsigned i = 1u; i < constructorArgs.size(); ++i) - { - auto const& carg = constructorArgs[i]; - smtAssert(!isAtom(carg) && asSubExpressions(carg).size() == 2); - auto const& nameSortPair = asSubExpressions(carg); - m_knownVariables.emplace(asAtom(nameSortPair[0]), toSort(nameSortPair[1])); - } + auto domainSort = toSort(args[1]); + auto codomainSort = toSort(args[2]); + return std::make_shared(std::move(domainSort), std::move(codomainSort)); } + if (args.size() == 3 && isAtom(args[0]) && asAtom(args[0]) == "_" && isAtom(args[1]) + && asAtom(args[1]) == "int2bv") + return std::make_shared(std::stoul(asAtom(args[2]))); } + smtAssert(false, "Unknown sort encountered"); +} - void addVariableDeclaration(std::string name, SortPointer sort) +smtutil::Expression CHCSmtLib2Interface::ScopedParser::parseQuantifier( + std::string const& _quantifierName, + std::vector const& _varList, + SMTLib2Expression const& _coreExpression) +{ + std::vector> boundVariables; + for (auto const& sortedVar: _varList) { - smtAssert(m_knownVariables.find(name) == m_knownVariables.end()); - m_knownVariables.emplace(std::move(name), std::move(sort)); - } - - std::optional lookupKnownTupleSort(std::string const& name) { - auto const& userSorts = m_chcInterface.sortNames(); - std::string quotedName = "|" + name + "|"; - auto it = ranges::find_if(userSorts, [&](auto const& entry) { return entry.second == quotedName; }); - if (it != userSorts.end() && it->first->kind == Kind::Tuple) - { - auto tupleSort = std::dynamic_pointer_cast(it->first); - smtAssert(tupleSort); - return tupleSort; - } - return {}; + smtAssert(!isAtom(sortedVar)); + auto varSortPair = asSubExpressions(sortedVar); + smtAssert(varSortPair.size() == 2); + boundVariables.emplace_back(asAtom(varSortPair[0]), toSort(varSortPair[1])); } - - SortPointer toSort(SMTLib2Expression const& expr) + for (auto const& [var, sort]: boundVariables) { - if (isAtom(expr)) - { - auto const& name = asAtom(expr); - if (name == "Int") - return SortProvider::sintSort; - if (name == "Bool") - return SortProvider::boolSort; - auto tupleSort = lookupKnownTupleSort(name); - if (tupleSort) - return tupleSort.value(); - } else { - auto const& args = asSubExpressions(expr); - if (asAtom(args[0]) == "Array") - { - smtAssert(args.size() == 3); - auto domainSort = toSort(args[1]); - auto codomainSort = toSort(args[2]); - return std::make_shared(std::move(domainSort), std::move(codomainSort)); - } - if (args.size() == 3 && isAtom(args[0]) && asAtom(args[0]) == "_" && isAtom(args[1]) && asAtom(args[1]) == "int2bv") - return std::make_shared(std::stoul(asAtom(args[2]))); - } - smtAssert(false, "Unknown sort encountered"); + smtAssert(m_localVariables.count(var) == 0); // TODO: deal with shadowing? + m_localVariables.emplace(var, sort); } - - smtutil::Expression parseQuantifier( - std::string const& quantifierName, - std::vector const& varList, - SMTLib2Expression const& coreExpression - ) + auto core = toSMTUtilExpression(_coreExpression); + for (auto const& [var, sort]: boundVariables) { - std::vector> boundVariables; - for (auto const& sortedVar: varList) - { - smtAssert(!isAtom(sortedVar)); - auto varSortPair = asSubExpressions(sortedVar); - smtAssert(varSortPair.size() == 2); - boundVariables.emplace_back(asAtom(varSortPair[0]), toSort(varSortPair[1])); - } - for (auto const& [var, sort] : boundVariables) - { - smtAssert(m_knownVariables.find(var) == m_knownVariables.end()); // TODO: deal with shadowing? - m_knownVariables.emplace(var, sort); - } - auto core = toSMTUtilExpression(coreExpression); - for (auto const& [var, sort] : boundVariables) - { - smtAssert(m_knownVariables.find(var) != m_knownVariables.end()); - m_knownVariables.erase(var); - } - return Expression(quantifierName, {core}, SortProvider::boolSort); // TODO: what about the bound variables? - + smtAssert(m_localVariables.count(var) != 0); + m_localVariables.erase(var); } + return Expression(_quantifierName, {core}, SortProvider::boolSort); // TODO: what about the bound variables? +} - smtutil::Expression toSMTUtilExpression(SMTLib2Expression const& _expr) - { - return std::visit( - GenericVisitor{ - [&](std::string const& _atom) +smtutil::Expression CHCSmtLib2Interface::ScopedParser::toSMTUtilExpression(SMTLib2Expression const& _expr) +{ + return std::visit( + GenericVisitor{ + [&](std::string const& _atom) + { + if (_atom == "true" || _atom == "false") + return smtutil::Expression(_atom == "true"); + else if (isNumber(_atom)) + return smtutil::Expression(_atom, {}, SortProvider::sintSort); + else if (auto it = m_localVariables.find(_atom); it != m_localVariables.end()) + return smtutil::Expression(_atom, {}, it->second); + else if (m_context.isDeclared(_atom)) + return smtutil::Expression(_atom, {}, m_context.getDeclaredSort(_atom)); + else if (auto maybeTupleType = m_context.getTupleType(_atom); maybeTupleType.has_value()) { - if (_atom == "true" || _atom == "false") - return smtutil::Expression(_atom == "true"); - else if (isNumber(_atom)) - return smtutil::Expression(_atom, {}, SortProvider::sintSort); - else if (auto it = m_knownVariables.find(_atom); it != m_knownVariables.end()) - return smtutil::Expression(_atom, {}, it->second); - else // assume this is a predicate with sort bool; TODO: Context should be aware of predicates! - return smtutil::Expression(_atom, {}, SortProvider::boolSort); - }, - [&](std::vector const& _subExpr) + // 0-ary tuple type, can happen + return smtutil::Expression(_atom, {}, std::make_shared(_atom, std::vector{}, std::vector{})); + } + else + smtAssert(false, "Unhandled atomic SMT expression"); + }, + [&](std::vector const& _subExpr) + { + SortPointer sort; + std::vector arguments; + if (isAtom(_subExpr.front())) { - SortPointer sort; - std::vector arguments; - if (isAtom(_subExpr.front())) + std::string const& op = asAtom(_subExpr.front()); + if (op == "!") { - std::string const& op = asAtom(_subExpr.front()); - if (op == "!") - { - // named term, we ignore the name - smtAssert(_subExpr.size() > 2); - return toSMTUtilExpression(_subExpr[1]); - } - if (op == "exists" || op == "forall") - { - smtAssert(_subExpr.size() == 3); - smtAssert(!isAtom(_subExpr[1])); - return parseQuantifier(op, asSubExpressions(_subExpr[1]), _subExpr[2]); - } - for (size_t i = 1; i < _subExpr.size(); i++) - arguments.emplace_back(toSMTUtilExpression(_subExpr[i])); - if (auto tupleSort = lookupKnownTupleSort(op); tupleSort) - { - auto sortSort = std::make_shared(tupleSort.value()); - return Expression::tuple_constructor(Expression(sortSort), arguments); - } - if (auto it = m_knownVariables.find(op); it != m_knownVariables.end()) - return smtutil::Expression(op, std::move(arguments), it->second); - else - { - std::set - boolOperators{"and", "or", "not", "=", "<", ">", "<=", ">=", "=>"}; - sort = contains(boolOperators, op) ? SortProvider::boolSort : arguments.back().sort; - return smtutil::Expression(op, std::move(arguments), std::move(sort)); - } - smtAssert(false, "Unhandled case in expression conversion"); + // named term, we ignore the name + smtAssert(_subExpr.size() > 2); + return toSMTUtilExpression(_subExpr[1]); + } + if (op == "exists" || op == "forall") + { + smtAssert(_subExpr.size() == 3); + smtAssert(!isAtom(_subExpr[1])); + return parseQuantifier(op, asSubExpressions(_subExpr[1]), _subExpr[2]); + } + for (size_t i = 1; i < _subExpr.size(); i++) + arguments.emplace_back(toSMTUtilExpression(_subExpr[i])); + if (auto tupleSort = lookupKnownTupleSort(op); tupleSort) + { + auto sortSort = std::make_shared(tupleSort.value()); + return Expression::tuple_constructor(Expression(sortSort), arguments); + } + if (m_context.isDeclared(op)) + return smtutil::Expression(op, std::move(arguments), m_context.getDeclaredSort(op)); + if (auto maybeTupleAccessor = m_context.getTupleAccessor(op); maybeTupleAccessor.has_value()) + { + auto accessor = maybeTupleAccessor.value(); + return smtutil::Expression("dt_accessor_" + accessor.first, std::move(arguments), accessor.second); } else { - // check for const array - if (_subExpr.size() == 2 and !isAtom(_subExpr[0])) + std::set boolOperators{"and", "or", "not", "=", "<", ">", "<=", ">=", "=>"}; + sort = contains(boolOperators, op) ? SortProvider::boolSort : arguments.back().sort; + return smtutil::Expression(op, std::move(arguments), std::move(sort)); + } + smtAssert(false, "Unhandled case in expression conversion"); + } + else + { + // check for const array + if (_subExpr.size() == 2 and !isAtom(_subExpr[0])) + { + auto const& typeArgs = asSubExpressions(_subExpr.front()); + if (typeArgs.size() == 3 && typeArgs[0].toString() == "as" + && typeArgs[1].toString() == "const") { - auto const& typeArgs = asSubExpressions(_subExpr.front()); - if (typeArgs.size() == 3 && typeArgs[0].toString() == "as" - && typeArgs[1].toString() == "const") - { - auto arraySort = toSort(typeArgs[2]); - auto sortSort = std::make_shared(arraySort); - return smtutil::Expression:: - const_array(Expression(sortSort), toSMTUtilExpression(_subExpr[1])); - } - if (typeArgs.size() == 3 && typeArgs[0].toString() == "_" - && typeArgs[1].toString() == "int2bv") - { - auto bvSort = std::dynamic_pointer_cast(toSort(_subExpr[0])); - smtAssert(bvSort); - return smtutil::Expression::int2bv(toSMTUtilExpression(_subExpr[1]), bvSort->size); - } - if (typeArgs.size() == 4 && typeArgs[0].toString() == "_" - && typeArgs[1].toString() == "extract") - return smtutil::Expression( - "extract", - {toSMTUtilExpression(typeArgs[2]), toSMTUtilExpression(typeArgs[3])}, - SortProvider::bitVectorSort // TODO: Compute bit size properly? - ); + auto arraySort = toSort(typeArgs[2]); + auto sortSort = std::make_shared(arraySort); + return smtutil::Expression:: + const_array(Expression(sortSort), toSMTUtilExpression(_subExpr[1])); } - smtAssert(false, "Unhandled case in expression conversion"); + if (typeArgs.size() == 3 && typeArgs[0].toString() == "_" + && typeArgs[1].toString() == "int2bv") + { + auto bvSort = std::dynamic_pointer_cast(toSort(_subExpr[0])); + smtAssert(bvSort); + return smtutil::Expression::int2bv(toSMTUtilExpression(_subExpr[1]), bvSort->size); + } + if (typeArgs.size() == 4 && typeArgs[0].toString() == "_" + && typeArgs[1].toString() == "extract") + return smtutil::Expression( + "extract", + {toSMTUtilExpression(typeArgs[2]), toSMTUtilExpression(typeArgs[3])}, + SortProvider::bitVectorSort // TODO: Compute bit size properly? + ); } + smtAssert(false, "Unhandled case in expression conversion"); } - }, - _expr.data - ); - } -}; + } + }, + _expr.data + ); +} #define precondition(CONDITION) if (!(CONDITION)) return {} @@ -474,7 +408,7 @@ std::optional CHCSmtLib2Interface::invariantsFromSolverResp precondition(isAtom(args[3]) && asAtom(args[3]) == "Bool"); auto& interpretation = args[4]; // inlineLetExpressions(interpretation); - SMTLibTranslationContext context(*this); + ScopedParser scopedParser(m_context); auto const& formalArguments = asSubExpressions(args[2]); std::vector predicateArgs; for (auto const& formalArgument: formalArguments) @@ -483,13 +417,14 @@ std::optional CHCSmtLib2Interface::invariantsFromSolverResp auto const& nameSortPair = asSubExpressions(formalArgument); precondition(nameSortPair.size() == 2); precondition(isAtom(nameSortPair[0])); - SortPointer varSort = context.toSort(nameSortPair[1]); - context.addVariableDeclaration(asAtom(nameSortPair[0]), varSort); - Expression arg = context.toSMTUtilExpression(nameSortPair[0]); + SortPointer varSort = scopedParser.toSort(nameSortPair[1]); + scopedParser.addVariableDeclaration(asAtom(nameSortPair[0]), varSort); + // FIXME: Why Expression here? + Expression arg = scopedParser.toSMTUtilExpression(nameSortPair[0]); predicateArgs.push_back(arg); } - auto parsedInterpretation = context.toSMTUtilExpression(interpretation); + auto parsedInterpretation = scopedParser.toSMTUtilExpression(interpretation); Expression predicate(asAtom(args[1]), predicateArgs, SortProvider::boolSort); definitions.push_back(predicate == parsedInterpretation); diff --git a/libsmtutil/CHCSmtLib2Interface.h b/libsmtutil/CHCSmtLib2Interface.h index 39131973bf7f..0b81b4541c4c 100644 --- a/libsmtutil/CHCSmtLib2Interface.h +++ b/libsmtutil/CHCSmtLib2Interface.h @@ -25,6 +25,7 @@ #include #include +#include namespace solidity::smtutil { @@ -54,38 +55,49 @@ class CHCSmtLib2Interface: public CHCSolverInterface std::vector unhandledQueries() const { return m_unhandledQueries; } - SMTLib2Interface* smtlib2Interface() const { return m_smtlib2.get(); } +protected: + class ScopedParser + { + public: + ScopedParser(SMTLib2Context const& _context): m_context(_context) {} - auto const& sortNames() const { return m_smtlib2->sortNames(); } + smtutil::Expression toSMTUtilExpression(SMTLib2Expression const& _expr); -protected: - std::string toSmtLibSort(SortPointer _sort); - std::string toSmtLibSort(std::vector const& _sort); + SortPointer toSort(SMTLib2Expression const& _expr); + + void addVariableDeclaration(std::string _name, SortPointer _sort); - void writeHeader(); - std::string forall(); + private: + std::optional lookupKnownTupleSort(std::string const& _name) const; - void declareFunction(std::string const& _name, SortPointer const& _sort); + smtutil::Expression parseQuantifier( + std::string const& _quantifierName, + std::vector const& _varList, + SMTLib2Expression const& _coreExpression + ); - void write(std::string _data); + SMTLib2Context const& m_context; + std::unordered_map m_localVariables; + }; - std::string createQueryAssertion(std::string name); - std::string createHeaderAndDeclarations(); + std::string toSmtLibSort(SortPointer const& _sort); + std::vector toSmtLibSort(std::vector const& _sort); + + std::string forall(Expression const& _expr); + + static std::string createQueryAssertion(std::string _name); + void createHeader(); /// Communicates with the solver via the callback. Throws SMTSolverError on error. - std::string querySolver(std::string const& _input); + virtual std::string querySolver(std::string const& _input); /// Translates CHC solver response with a model to our representation of invariants. Returns None on error. - std::optional invariantsFromSolverResponse(std::string const& response) const; - - /// Hook to setup external solver call - virtual void setupSmtCallback() {} + std::optional invariantsFromSolverResponse(std::string const& _response) const; - /// Used to access toSmtLibSort, SExpr, and handle variables. - std::unique_ptr m_smtlib2; + std::set collectVariableNames(Expression const& _expr) const; - std::string m_accumulatedOutput; - std::set m_variables; + SMTLib2Commands m_commands; + SMTLib2Context m_context; std::map m_queryResponses; std::vector m_unhandledQueries; diff --git a/libsmtutil/CHCSolverInterface.h b/libsmtutil/CHCSolverInterface.h index 8385c1c4016e..a20283b4fec1 100644 --- a/libsmtutil/CHCSolverInterface.h +++ b/libsmtutil/CHCSolverInterface.h @@ -30,15 +30,11 @@ namespace solidity::smtutil { -class CHCSolverInterface +class CHCSolverInterface : public SolverInterface { public: CHCSolverInterface(std::optional _queryTimeout = {}): m_queryTimeout(_queryTimeout) {} - virtual ~CHCSolverInterface() = default; - - virtual void declareVariable(std::string const& _name, SortPointer const& _sort) = 0; - /// Takes a function declaration as a relation. virtual void registerRelation(Expression const& _expr) = 0; diff --git a/libsmtutil/CMakeLists.txt b/libsmtutil/CMakeLists.txt index 005fbeb8049e..c89c56f4f583 100644 --- a/libsmtutil/CMakeLists.txt +++ b/libsmtutil/CMakeLists.txt @@ -2,6 +2,8 @@ set(sources CHCSmtLib2Interface.cpp CHCSmtLib2Interface.h Exceptions.h + SMTLib2Context.cpp + SMTLib2Context.h SMTLib2Interface.cpp SMTLib2Interface.h SMTLib2Parser.cpp diff --git a/libsmtutil/SMTLib2Context.cpp b/libsmtutil/SMTLib2Context.cpp new file mode 100644 index 000000000000..95bc2011b873 --- /dev/null +++ b/libsmtutil/SMTLib2Context.cpp @@ -0,0 +1,314 @@ +/* + This file is part of solidity. + + solidity is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + solidity is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with solidity. If not, see . +*/ +// SPDX-License-Identifier: GPL-3.0 + +#include + +#include + +#include + +namespace solidity::smtutil +{ + +std::size_t SortPairHash::operator()(std::pair const& _pair) const +{ + std::size_t seed = 0; + boost::hash_combine(seed, _pair.first); + boost::hash_combine(seed, _pair.second); + return seed; +} + +SMTLib2Context::SMTLib2Context() +{ + clear(); +} + +bool SMTLib2Context::isDeclared(std::string const& _name) const +{ + return m_functions.count(_name) > 0; +} + +void SMTLib2Context::declare(std::string const& _name, SortPointer const& _sort) +{ + auto [_, inserted] = m_functions.insert({_name, _sort}); + smtAssert(inserted, "Trying to redeclare SMT function!"); +} + +SortPointer SMTLib2Context::getDeclaredSort(std::string const& _name) const +{ + smtAssert(isDeclared(_name)); + return m_functions.at(_name); +} + +void SMTLib2Context::clear() { + m_functions.clear(); + m_knownTypes.clear(); + m_arraySorts.clear(); + m_tupleSorts.clear(); + m_bitVectorSorts.clear(); + m_callback = {}; + m_knownTypes.emplace_back(std::make_unique(Kind::Bool, std::string("Bool"), std::vector{}, SortId{0u})); + m_knownTypes.emplace_back(std::make_unique(Kind::Int, std::string("Int"), std::vector{}, SortId{1u})); + assert(m_boolSort == m_knownTypes[0]->id); + assert(m_intSort == m_knownTypes[1]->id); +} + +SortId SMTLib2Context::resolve(SortPointer const& _sort) +{ + switch (_sort->kind) + { + case Kind::Int: + return m_intSort; + case Kind::Bool: + return m_boolSort; + case Kind::BitVector: + return resolveBitVectorSort(dynamic_cast(*_sort)); + case Kind::Array: + return resolveArraySort(dynamic_cast(*_sort)); + case Kind::Tuple: + return resolveTupleSort(dynamic_cast(*_sort)); + default: + smtAssert(false, "Invalid SMT sort"); + } +} + +SortPointer SMTLib2Context::unresolve(SortId _sortId) const +{ + smtAssert(_sortId < m_knownTypes.size()); + auto const& type = *m_knownTypes[_sortId]; + switch (type.kind) + { + case Kind::Int: + return SortProvider::sintSort; + case Kind::Bool: + return SortProvider::boolSort; + case Kind::BitVector: + { + auto it = ranges::find_if(m_bitVectorSorts, [&](auto const& entry) { return entry.second == _sortId; }); + smtAssert(it != m_bitVectorSorts.end()); + return std::make_shared(it->first); + } + case Kind::Array: + { + auto it = ranges::find_if(m_arraySorts, [&](auto const& entry) { return entry.second == _sortId; }); + smtAssert(it != m_arraySorts.end()); + return std::make_shared(unresolve(it->first.first), unresolve(it->first.second)); + } + case Kind::Tuple: + { + auto const& tupleType = dynamic_cast(type); + std::vector memberNames; + std::vector memberTypes; + for (auto&& [name, sortId] : tupleType.accessors) + { + memberNames.push_back(name); + memberTypes.push_back(unresolve(sortId)); + } + return std::make_shared(tupleType.name, std::move(memberNames), std::move(memberTypes)); + } + default: + smtAssert(false, "Invalid SMT sort"); + } +} + +SortId SMTLib2Context::resolveBitVectorSort(BitVectorSort const& _sort) +{ + auto size = _sort.size; + auto it = m_bitVectorSorts.find(size); + if (it == m_bitVectorSorts.end()) + { + auto newId = static_cast(m_knownTypes.size()); + m_knownTypes.emplace_back(std::make_unique(Kind::BitVector, "(_ BitVec " + std::to_string(size) + ')', std::vector{}, SortId{newId})); + auto&& [newIt, inserted] = m_bitVectorSorts.emplace(size, SortId{newId}); + smtAssert(inserted); + return newIt->second; + } + return it->second; +} + +SortId SMTLib2Context::resolveArraySort(ArraySort const& _sort) +{ + smtAssert(_sort.domain && _sort.range); + auto domainSort = resolve(_sort.domain); + auto rangeSort = resolve(_sort.range); + auto pair = std::make_pair(domainSort, rangeSort); + auto it = m_arraySorts.find(pair); + if (it == m_arraySorts.end()) + { + auto newId = static_cast(m_knownTypes.size()); + m_knownTypes.emplace_back(std::make_unique(Kind::Array, "Array", std::vector{domainSort, rangeSort}, SortId{newId})); + auto&& [newIt, inserted] = m_arraySorts.emplace(pair, SortId{newId}); + smtAssert(inserted); + return newIt->second; + } + return it->second; +} + +SortId SMTLib2Context::resolveTupleSort(TupleSort const& _sort) +{ + auto const& tupleName = _sort.name; + auto it = m_tupleSorts.find(tupleName); + if (it == m_tupleSorts.end()) + { + std::vector> accessors; + smtAssert(_sort.members.size() == _sort.components.size()); + for (std::size_t i = 0u; i < _sort.members.size(); ++i) + accessors.emplace_back(_sort.members[i], resolve(_sort.components[i])); + auto newId = static_cast(m_knownTypes.size()); + m_knownTypes.emplace_back(std::make_unique(tupleName, std::move(accessors), SortId{newId})); + auto&& [newIt, inserted] = m_tupleSorts.emplace(tupleName, SortId{newId}); + smtAssert(inserted); + if (m_callback) + m_callback(_sort); + return newIt->second; + } + return it->second; +} + +std::string SMTLib2Context::toString(SortId _id) +{ + auto const& sort = m_knownTypes.at(_id); + switch (sort->kind) + { + case Kind::Int: + return "Int"; + case Kind::Bool: + return "Bool"; + case Kind::BitVector: + return dynamic_cast(*sort).name; + case Kind::Array: + { + auto const& arraySort = dynamic_cast(*sort); + smtAssert(arraySort.args.size() == 2); + return "(Array " + toString(arraySort.args.at(0)) + ' ' + toString(arraySort.args.at(1)) + ')'; + } + case Kind::Tuple: + { + auto const& tupleType = dynamic_cast(*sort); + return '|' + tupleType.name + '|'; + } + default: + smtAssert(false, "Invalid SMT sort"); + } +} + +std::string SMTLib2Context::toSmtLibSort(solidity::smtutil::SortPointer const& _sort) +{ + return toString(resolve(_sort)); +} + +std::string SMTLib2Context::toSExpr(Expression const& _expr) +{ + if (_expr.arguments.empty()) + return _expr.name; + + std::string sexpr = "("; + if (_expr.name == "int2bv") + { + size_t size = std::stoul(_expr.arguments[1].name); + auto arg = toSExpr(_expr.arguments.front()); + auto int2bv = "(_ int2bv " + std::to_string(size) + ")"; + // Some solvers treat all BVs as unsigned, so we need to manually apply 2's complement if needed. + sexpr += std::string("ite ") + + "(>= " + arg + " 0) " + + "(" + int2bv + " " + arg + ") " + + "(bvneg (" + int2bv + " (- " + arg + ")))"; + } + else if (_expr.name == "bv2int") + { + auto intSort = std::dynamic_pointer_cast(_expr.sort); + smtAssert(intSort, ""); + + auto arg = toSExpr(_expr.arguments.front()); + auto nat = "(bv2nat " + arg + ")"; + + if (!intSort->isSigned) + return nat; + + auto bvSort = std::dynamic_pointer_cast(_expr.arguments.front().sort); + smtAssert(bvSort, ""); + auto size = std::to_string(bvSort->size); + auto pos = std::to_string(bvSort->size - 1); + + // Some solvers treat all BVs as unsigned, so we need to manually apply 2's complement if needed. + sexpr += std::string("ite ") + + "(= ((_ extract " + pos + " " + pos + ")" + arg + ") #b0) " + + nat + " " + + "(- (bv2nat (bvneg " + arg + ")))"; + } + else if (_expr.name == "const_array") + { + smtAssert(_expr.arguments.size() == 2, ""); + auto sortSort = std::dynamic_pointer_cast(_expr.arguments.at(0).sort); + smtAssert(sortSort, ""); + auto arraySort = std::dynamic_pointer_cast(sortSort->inner); + smtAssert(arraySort, ""); + sexpr += "(as const " + toSmtLibSort(arraySort) + ") "; + sexpr += toSExpr(_expr.arguments.at(1)); + } + else if (_expr.name == "tuple_get") + { + smtAssert(_expr.arguments.size() == 2, ""); + auto tupleSort = std::dynamic_pointer_cast(_expr.arguments.at(0).sort); + size_t index = std::stoul(_expr.arguments.at(1).name); + smtAssert(index < tupleSort->members.size(), ""); + sexpr += "|" + tupleSort->members.at(index) + "| " + toSExpr(_expr.arguments.at(0)); + } + else if (_expr.name == "tuple_constructor") + { + auto tupleSort = std::dynamic_pointer_cast(_expr.sort); + smtAssert(tupleSort, ""); + sexpr += "|" + tupleSort->name + "|"; + for (auto const& arg: _expr.arguments) + sexpr += " " + toSExpr(arg); + } + else + { + sexpr += _expr.name; + for (auto const& arg: _expr.arguments) + sexpr += " " + toSExpr(arg); + } + sexpr += ")"; + return sexpr; +} + +std::optional SMTLib2Context::getTupleType(std::string const& _name) const +{ + auto it = m_tupleSorts.find(_name); + return it == m_tupleSorts.end() ? std::nullopt : std::optional(unresolve(it->second)); +} + +std::optional> SMTLib2Context::getTupleAccessor(std::string const& _name) const +{ + for (auto&& [_, sortId] : m_tupleSorts) + { + auto const& type = m_knownTypes.at(sortId); + smtAssert(type->kind == Kind::Tuple); + auto const& tupleType = dynamic_cast(*type); + for (auto&& [memberName, memberSort] : tupleType.accessors) + if (memberName == _name) + return std::make_pair(memberName, unresolve(memberSort)); + } + return std::nullopt; +} + +void SMTLib2Context::setTupleDeclarationCallback(TupleDeclarationCallback _callback) +{ + m_callback = std::move(_callback); +} +} // namespace solidity::smtutil diff --git a/libsmtutil/SMTLib2Context.h b/libsmtutil/SMTLib2Context.h new file mode 100644 index 000000000000..30a44605c2ab --- /dev/null +++ b/libsmtutil/SMTLib2Context.h @@ -0,0 +1,109 @@ +/* + This file is part of solidity. + + solidity is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + solidity is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with solidity. If not, see . +*/ +// SPDX-License-Identifier: GPL-3.0 + +#pragma once + +#include +#include + +#include +#include +#include + +namespace solidity::smtutil +{ + +using SortId = uint32_t; +struct SortPairHash +{ + std::size_t operator()(std::pair const& _pair) const; +}; + +struct SMTLibType { + Kind const kind; + SortId const id; + SMTLibType(Kind _kind, SortId _id): kind(_kind), id(_id) {} + virtual ~SMTLibType() = default; +}; + +struct SMTLibSort : public SMTLibType +{ + std::string const name; + std::vector const args; + + SMTLibSort( + Kind _kind, + std::string_view _name, + std::vector _args, + SortId _id + ): SMTLibType(_kind, _id), name(_name), args(std::move(_args)) {} +}; + +struct TupleType : public SMTLibType +{ + std::string const name; + std::vector> accessors; + + TupleType(std::string_view _name, std::vector> _accessors, SortId _id) + : SMTLibType(Kind::Tuple, _id), name(_name), accessors(std::move(_accessors)) {} +}; + +class SMTLib2Context +{ +public: + using TupleDeclarationCallback = std::function; + + SMTLib2Context(); + void clear(); + + bool isDeclared(std::string const& _name) const; + void declare(std::string const& _name, SortPointer const& _sort); + SortPointer getDeclaredSort(std::string const& _name) const; + + SortId resolve(SortPointer const& _sort); + SortPointer unresolve(SortId _sortId) const; + + std::string toString(SortId _id); + + std::string toSExpr(Expression const& _expr); + std::string toSmtLibSort(SortPointer const& _sort); + + std::optional getTupleType(std::string const& _name) const; + std::optional> getTupleAccessor(std::string const& _name) const; + + void setTupleDeclarationCallback(TupleDeclarationCallback _callback); +private: + SortId resolveBitVectorSort(BitVectorSort const& _sort); + SortId resolveArraySort(ArraySort const& _sort); + SortId resolveTupleSort(TupleSort const& _sort); + + using functions_t = std::map; + functions_t m_functions; // Variables are uninterpreted constants = nullary functions + + SortId const m_boolSort{0u}; + SortId const m_intSort{1u}; + std::vector> m_knownTypes; + std::unordered_map, SortId, SortPairHash> m_arraySorts; + std::unordered_map m_bitVectorSorts; + std::unordered_map m_tupleSorts; + + TupleDeclarationCallback m_callback; +}; + +} + diff --git a/libsmtutil/SMTLib2Interface.cpp b/libsmtutil/SMTLib2Interface.cpp index 06ed26f2b26b..81ad5ddd4b25 100644 --- a/libsmtutil/SMTLib2Interface.cpp +++ b/libsmtutil/SMTLib2Interface.cpp @@ -43,7 +43,7 @@ SMTLib2Interface::SMTLib2Interface( ReadCallback::Callback _smtCallback, std::optional _queryTimeout ): - SolverInterface(_queryTimeout), + BMCSolverInterface(_queryTimeout), m_queryResponses(std::move(_queryResponses)), m_smtCallback(std::move(_smtCallback)) { @@ -52,74 +52,67 @@ SMTLib2Interface::SMTLib2Interface( void SMTLib2Interface::reset() { - m_accumulatedOutput.clear(); - m_accumulatedOutput.emplace_back(); - m_variables.clear(); - m_userSorts.clear(); - m_sortNames.clear(); - write("(set-option :produce-models true)"); + m_commands.clear(); + m_context.clear(); + m_commands.setOption("produce-models", "true"); if (m_queryTimeout) - write("(set-option :timeout " + std::to_string(*m_queryTimeout) + ")"); - write("(set-logic ALL)"); + m_commands.setOption("timeout", std::to_string(*m_queryTimeout)); + m_commands.setLogic("ALL"); + m_context.setTupleDeclarationCallback([&](TupleSort const& tupleSort){ + m_commands.declareTuple( + tupleSort.name, + tupleSort.members, + tupleSort.components + | ranges::views::transform([&](SortPointer const& sort){ return m_context.toSmtLibSort(sort); }) + | ranges::to() + ); + }); } void SMTLib2Interface::push() { - m_accumulatedOutput.emplace_back(); + m_commands.push(); } void SMTLib2Interface::pop() { - smtAssert(!m_accumulatedOutput.empty(), ""); - m_accumulatedOutput.pop_back(); + m_commands.pop(); } void SMTLib2Interface::declareVariable(std::string const& _name, SortPointer const& _sort) { - smtAssert(_sort, ""); + smtAssert(_sort); if (_sort->kind == Kind::Function) declareFunction(_name, _sort); - else if (!m_variables.count(_name)) + else if (!m_context.isDeclared(_name)) { - m_variables.emplace(_name, _sort); - write("(declare-fun |" + _name + "| () " + toSmtLibSort(_sort) + ')'); + m_context.declare(_name, _sort); + m_commands.declareVariable(_name, toSmtLibSort(_sort)); } } void SMTLib2Interface::declareFunction(std::string const& _name, SortPointer const& _sort) { - smtAssert(_sort, ""); - smtAssert(_sort->kind == Kind::Function, ""); - // TODO Use domain and codomain as key as well - if (!m_variables.count(_name)) + smtAssert(_sort); + smtAssert(_sort->kind == Kind::Function); + if (!m_context.isDeclared(_name)) { auto const& fSort = std::dynamic_pointer_cast(_sort); - std::string domain = toSmtLibSort(fSort->domain); + auto domain = toSmtLibSort(fSort->domain); std::string codomain = toSmtLibSort(fSort->codomain); - m_variables.emplace(_name, _sort); - write( - "(declare-fun |" + - _name + - "| " + - domain + - " " + - codomain + - ")" - ); + m_context.declare(_name, _sort); + m_commands.declareFunction(_name, domain, codomain); } } void SMTLib2Interface::addAssertion(Expression const& _expr) { - write("(assert " + toSExpr(_expr) + ")"); + m_commands.assertion(toSExpr(_expr)); } std::pair> SMTLib2Interface::check(std::vector const& _expressionsToEvaluate) { - std::string response = querySolver( - boost::algorithm::join(m_accumulatedOutput, "\n") + - checkSatAndGetValuesCommand(_expressionsToEvaluate) - ); + std::string response = querySolver(dumpQuery(_expressionsToEvaluate)); CheckResult result; // TODO proper parsing @@ -138,140 +131,23 @@ std::pair> SMTLib2Interface::check(std::ve return std::make_pair(result, values); } -std::string SMTLib2Interface::toSExpr(Expression const& _expr) +std::string SMTLib2Interface::toSmtLibSort(SortPointer _sort) { - if (_expr.arguments.empty()) - return _expr.name; - - std::string sexpr = "("; - if (_expr.name == "int2bv") - { - size_t size = std::stoul(_expr.arguments[1].name); - auto arg = toSExpr(_expr.arguments.front()); - auto int2bv = "(_ int2bv " + std::to_string(size) + ")"; - // Some solvers treat all BVs as unsigned, so we need to manually apply 2's complement if needed. - sexpr += std::string("ite ") + - "(>= " + arg + " 0) " + - "(" + int2bv + " " + arg + ") " + - "(bvneg (" + int2bv + " (- " + arg + ")))"; - } - else if (_expr.name == "bv2int") - { - auto intSort = std::dynamic_pointer_cast(_expr.sort); - smtAssert(intSort, ""); - - auto arg = toSExpr(_expr.arguments.front()); - auto nat = "(bv2nat " + arg + ")"; - - if (!intSort->isSigned) - return nat; - - auto bvSort = std::dynamic_pointer_cast(_expr.arguments.front().sort); - smtAssert(bvSort, ""); - auto size = std::to_string(bvSort->size); - auto pos = std::to_string(bvSort->size - 1); - - // Some solvers treat all BVs as unsigned, so we need to manually apply 2's complement if needed. - sexpr += std::string("ite ") + - "(= ((_ extract " + pos + " " + pos + ")" + arg + ") #b0) " + - nat + " " + - "(- (bv2nat (bvneg " + arg + ")))"; - } - else if (_expr.name == "const_array") - { - smtAssert(_expr.arguments.size() == 2, ""); - auto sortSort = std::dynamic_pointer_cast(_expr.arguments.at(0).sort); - smtAssert(sortSort, ""); - auto arraySort = std::dynamic_pointer_cast(sortSort->inner); - smtAssert(arraySort, ""); - sexpr += "(as const " + toSmtLibSort(arraySort) + ") "; - sexpr += toSExpr(_expr.arguments.at(1)); - } - else if (_expr.name == "tuple_get") - { - smtAssert(_expr.arguments.size() == 2, ""); - auto tupleSort = std::dynamic_pointer_cast(_expr.arguments.at(0).sort); - size_t index = std::stoul(_expr.arguments.at(1).name); - smtAssert(index < tupleSort->members.size(), ""); - sexpr += "|" + tupleSort->members.at(index) + "| " + toSExpr(_expr.arguments.at(0)); - } - else if (_expr.name == "tuple_constructor") - { - auto tupleSort = std::dynamic_pointer_cast(_expr.sort); - smtAssert(tupleSort, ""); - sexpr += "|" + tupleSort->name + "|"; - for (auto const& arg: _expr.arguments) - sexpr += " " + toSExpr(arg); - } - else - { - sexpr += _expr.name; - for (auto const& arg: _expr.arguments) - sexpr += " " + toSExpr(arg); - } - sexpr += ")"; - return sexpr; + return m_context.toSmtLibSort(std::move(_sort)); } -std::string SMTLib2Interface::toSmtLibSort(solidity::smtutil::SortPointer _sort) +std::vector SMTLib2Interface::toSmtLibSort(std::vector const& _sorts) { - if (!m_sortNames.count(_sort)) - m_sortNames[_sort] = toSmtLibSortInternal(_sort); - return m_sortNames.at(_sort); -} - -std::string SMTLib2Interface::toSmtLibSortInternal(SortPointer _sort) -{ - switch (_sort->kind) - { - case Kind::Int: - return "Int"; - case Kind::Bool: - return "Bool"; - case Kind::BitVector: - return "(_ BitVec " + std::to_string(dynamic_cast(*_sort).size) + ")"; - case Kind::Array: - { - auto const& arraySort = dynamic_cast(*_sort); - smtAssert(arraySort.domain && arraySort.range, ""); - return "(Array " + toSmtLibSort(arraySort.domain) + ' ' + toSmtLibSort(arraySort.range) + ')'; - } - case Kind::Tuple: - { - auto const& tupleSort = dynamic_cast(*_sort); - std::string tupleName = "|" + tupleSort.name + "|"; - auto isName = [&](auto entry) { return entry.first == tupleName; }; - if (ranges::find_if(m_userSorts, isName) == m_userSorts.end()) - { - std::string decl("(declare-datatypes ((" + tupleName + " 0)) (((" + tupleName); - smtAssert(tupleSort.members.size() == tupleSort.components.size(), ""); - for (unsigned i = 0; i < tupleSort.members.size(); ++i) - decl += " (|" + tupleSort.members.at(i) + "| " + toSmtLibSort(tupleSort.components.at(i)) + ")"; - decl += "))))"; - m_userSorts.emplace_back(tupleName, decl); - write(decl); - } - - return tupleName; - } - default: - smtAssert(false, "Invalid SMT sort"); - } -} - -std::string SMTLib2Interface::toSmtLibSort(std::vector const& _sorts) -{ - std::string ssort("("); + std::vector ssorts; + ssorts.reserve(_sorts.size()); for (auto const& sort: _sorts) - ssort += toSmtLibSort(sort) + " "; - ssort += ")"; - return ssort; + ssorts.push_back(toSmtLibSort(sort)); + return ssorts; } -void SMTLib2Interface::write(std::string _data) +std::string SMTLib2Interface::toSExpr(solidity::smtutil::Expression const& _expr) { - smtAssert(!m_accumulatedOutput.empty(), ""); - m_accumulatedOutput.back() += std::move(_data) + "\n"; + return m_context.toSExpr(_expr); } std::string SMTLib2Interface::checkSatAndGetValuesCommand(std::vector const& _expressionsToEvaluate) @@ -333,6 +209,70 @@ std::string SMTLib2Interface::querySolver(std::string const& _input) std::string SMTLib2Interface::dumpQuery(std::vector const& _expressionsToEvaluate) { - return boost::algorithm::join(m_accumulatedOutput, "\n") + - checkSatAndGetValuesCommand(_expressionsToEvaluate); + return m_commands.toString() + '\n' + checkSatAndGetValuesCommand(_expressionsToEvaluate); +} + + +void SMTLib2Commands::push() { + m_frameLimits.push_back(m_commands.size()); +} + +void SMTLib2Commands::pop() { + smtAssert(!m_commands.empty()); + auto limit = m_frameLimits.back(); + m_frameLimits.pop_back(); + while (m_commands.size() > limit) + m_commands.pop_back(); +} + +std::string SMTLib2Commands::toString() const { + return boost::algorithm::join(m_commands, "\n"); +} + +void SMTLib2Commands::clear() { + m_commands.clear(); + m_frameLimits.clear(); +} + +void SMTLib2Commands::assertion(std::string _expr) { + m_commands.push_back("(assert " + std::move(_expr) + ')'); +} + +void SMTLib2Commands::setOption(std::string _name, std::string _value) +{ + m_commands.push_back("(set-option :" + std::move(_name) + ' ' + std::move(_value) + ')'); +} + +void SMTLib2Commands::setLogic(std::string _logic) +{ + m_commands.push_back("(set-logic " + std::move(_logic) + ')'); +} + +void SMTLib2Commands::declareVariable(std::string _name, std::string _sort) +{ + m_commands.push_back("(declare-fun |" + std::move(_name) + "| () " + std::move(_sort) + ')'); +} + +void SMTLib2Commands::declareFunction(std::string const& _name, std::vector const& _domain, std::string const& _codomain) +{ + std::stringstream ss; + ss << "(declare-fun |" << _name << "| " << '(' << boost::join(_domain, " ") + << ')' << ' ' << _codomain << ')'; + m_commands.push_back(ss.str()); +} + +void SMTLib2Commands::declareTuple( + std::string const& _name, + std::vector const& _memberNames, + std::vector const& _memberSorts +) +{ + auto quotedName = '|' + _name + '|'; + std::stringstream ss; + ss << "(declare-datatypes ((" << quotedName << " 0)) (((" << quotedName; + for (auto && [memberName, memberSort]: ranges::views::zip(_memberNames, _memberSorts)) + ss << " (|" << memberName << "| " << memberSort << ")"; + ss << "))))"; + auto declaration = ss.str(); + m_commands.push_back(ss.str()); } diff --git a/libsmtutil/SMTLib2Interface.h b/libsmtutil/SMTLib2Interface.h index d60a5bd250c5..11478223cfdf 100644 --- a/libsmtutil/SMTLib2Interface.h +++ b/libsmtutil/SMTLib2Interface.h @@ -18,7 +18,9 @@ #pragma once -#include +#include + +#include #include @@ -34,7 +36,36 @@ namespace solidity::smtutil { -class SMTLib2Interface: public SolverInterface +class SMTLib2Commands +{ +public: + void push(); + void pop(); + + void clear(); + + void assertion(std::string _expr); + + void setOption(std::string _name, std::string _value); + + void setLogic(std::string _logic); + + void declareVariable(std::string _name, std::string _sort); + void declareFunction(std::string const& _name, std::vector const& _domain, std::string const& _codomain); + void declareTuple( + std::string const& _name, + std::vector const& _memberNames, + std::vector const& _memberSorts + ); + + [[nodiscard]] std::string toString() const; +private: + std::vector m_commands; + std::vector m_frameLimits; + +}; + +class SMTLib2Interface: public BMCSolverInterface { public: /// Noncopyable. @@ -62,12 +93,7 @@ class SMTLib2Interface: public SolverInterface // Used by CHCSmtLib2Interface std::string toSExpr(Expression const& _expr); std::string toSmtLibSort(SortPointer _sort); - std::string toSmtLibSort(std::vector const& _sort); - - std::map variables() { return m_variables; } - - std::vector> const& userSorts() const { return m_userSorts; } - std::map const& sortNames() const { return m_sortNames; } + std::vector toSmtLibSort(std::vector const& _sort); std::string dumpQuery(std::vector const& _expressionsToEvaluate); @@ -76,28 +102,14 @@ class SMTLib2Interface: public SolverInterface void declareFunction(std::string const& _name, SortPointer const& _sort); - void write(std::string _data); - std::string checkSatAndGetValuesCommand(std::vector const& _expressionsToEvaluate); std::vector parseValues(std::string::const_iterator _start, std::string::const_iterator _end); /// Communicates with the solver via the callback. Throws SMTSolverError on error. std::string querySolver(std::string const& _input); - std::string toSmtLibSortInternal(SortPointer _sort); - - std::vector m_accumulatedOutput; - std::map m_variables; - - /// Each pair in this vector represents an SMTChecker created - /// sort (a user sort), and the smtlib2 declaration of that sort. - /// It needs to be a vector so that the declaration order is kept, - /// otherwise solvers cannot parse the queries. - std::vector> m_userSorts; - - /// Maps a user sort to SMT-LIB2 sort. - /// Remembers all declared sorts and is used as a cache as well. - std::map m_sortNames; + SMTLib2Commands m_commands; + SMTLib2Context m_context; std::map m_queryResponses; std::vector m_unhandledQueries; diff --git a/libsmtutil/SMTPortfolio.cpp b/libsmtutil/SMTPortfolio.cpp index 196f02fdf99c..94c92f390a53 100644 --- a/libsmtutil/SMTPortfolio.cpp +++ b/libsmtutil/SMTPortfolio.cpp @@ -26,10 +26,10 @@ using namespace solidity::frontend; using namespace solidity::smtutil; SMTPortfolio::SMTPortfolio( - std::vector> _solvers, + std::vector> _solvers, std::optional _queryTimeout ): - SolverInterface(_queryTimeout), m_solvers(std::move(_solvers)) + BMCSolverInterface(_queryTimeout), m_solvers(std::move(_solvers)) {} diff --git a/libsmtutil/SMTPortfolio.h b/libsmtutil/SMTPortfolio.h index 5ffb37eb3286..b445f40a2b69 100644 --- a/libsmtutil/SMTPortfolio.h +++ b/libsmtutil/SMTPortfolio.h @@ -19,7 +19,7 @@ #pragma once -#include +#include #include #include @@ -35,14 +35,14 @@ namespace solidity::smtutil * It also checks whether different solvers give conflicting answers * to SMT queries. */ -class SMTPortfolio: public SolverInterface +class SMTPortfolio: public BMCSolverInterface { public: /// Noncopyable. SMTPortfolio(SMTPortfolio const&) = delete; SMTPortfolio& operator=(SMTPortfolio const&) = delete; - SMTPortfolio(std::vector> solvers, std::optional _queryTimeout); + SMTPortfolio(std::vector> solvers, std::optional _queryTimeout); void reset() override; @@ -63,7 +63,7 @@ class SMTPortfolio: public SolverInterface private: static bool solverAnswered(CheckResult result); - std::vector> m_solvers; + std::vector> m_solvers; std::vector m_assertions; }; diff --git a/libsmtutil/SolverInterface.h b/libsmtutil/SolverInterface.h index 92f9c8f75b7d..2639ae024034 100644 --- a/libsmtutil/SolverInterface.h +++ b/libsmtutil/SolverInterface.h @@ -512,13 +512,9 @@ DEV_SIMPLE_EXCEPTION(SolverError); class SolverInterface { public: - SolverInterface(std::optional _queryTimeout = {}): m_queryTimeout(_queryTimeout) {} + SolverInterface() = default; virtual ~SolverInterface() = default; - virtual void reset() = 0; - - virtual void push() = 0; - virtual void pop() = 0; virtual void declareVariable(std::string const& _name, SortPointer const& _sort) = 0; Expression newVariable(std::string _name, SortPointer const& _sort) @@ -529,21 +525,8 @@ class SolverInterface return Expression(std::move(_name), {}, _sort); } - virtual void addAssertion(Expression const& _expr) = 0; - - /// Checks for satisfiability, evaluates the expressions if a model - /// is available. Throws SMTSolverError on error. - virtual std::pair> - check(std::vector const& _expressionsToEvaluate) = 0; - - /// @returns a list of queries that the system was not able to respond to. - virtual std::vector unhandledQueries() { return {}; } - /// @returns how many SMT solvers this interface has. virtual size_t solvers() { return 1; } - -protected: - std::optional m_queryTimeout; }; } diff --git a/libsmtutil/Z3Interface.cpp b/libsmtutil/Z3Interface.cpp index 4e1d1cec1236..efd656259819 100644 --- a/libsmtutil/Z3Interface.cpp +++ b/libsmtutil/Z3Interface.cpp @@ -39,7 +39,7 @@ bool Z3Interface::available() } Z3Interface::Z3Interface(std::optional _queryTimeout): - SolverInterface(_queryTimeout), + BMCSolverInterface(_queryTimeout), m_solver(m_context) { // These need to be set globally. diff --git a/libsmtutil/Z3Interface.h b/libsmtutil/Z3Interface.h index d5dc5792e0ae..ee5270f440c9 100644 --- a/libsmtutil/Z3Interface.h +++ b/libsmtutil/Z3Interface.h @@ -18,13 +18,13 @@ #pragma once -#include +#include #include namespace solidity::smtutil { -class Z3Interface: public SolverInterface +class Z3Interface: public BMCSolverInterface { public: /// Noncopyable. diff --git a/libsolidity/formal/BMC.cpp b/libsolidity/formal/BMC.cpp index dbaed2960253..fda573d3d4cf 100644 --- a/libsolidity/formal/BMC.cpp +++ b/libsolidity/formal/BMC.cpp @@ -56,7 +56,7 @@ BMC::BMC( SMTEncoder(_context, _settings, _errorReporter, _unsupportedErrorReporter, _provedSafeReporter, _charStreamProvider) { solAssert(!_settings.printQuery || _settings.solvers == SMTSolverChoice::SMTLIB2(), "Only SMTLib2 solver can be enabled to print queries"); - std::vector> solvers; + std::vector> solvers; if (_settings.solvers.smtlib2) solvers.emplace_back(std::make_unique(_smtlib2Responses, _smtCallback, _settings.timeout)); if (_settings.solvers.cvc5) diff --git a/libsolidity/formal/BMC.h b/libsolidity/formal/BMC.h index bbd8c101731c..a0ee9a3749c2 100644 --- a/libsolidity/formal/BMC.h +++ b/libsolidity/formal/BMC.h @@ -35,7 +35,7 @@ #include -#include +#include #include #include @@ -205,7 +205,7 @@ class BMC: public SMTEncoder smtutil::Expression mergeVariablesFromLoopCheckpoints(); bool isInsideLoop() const; - std::unique_ptr m_interface; + std::unique_ptr m_interface; /// Flags used for better warning messages. bool m_loopExecutionHappened = false; diff --git a/libsolidity/formal/CHC.cpp b/libsolidity/formal/CHC.cpp index 73b979364211..2bd0195375ad 100644 --- a/libsolidity/formal/CHC.cpp +++ b/libsolidity/formal/CHC.cpp @@ -1312,7 +1312,7 @@ void CHC::resetSourceAnalysis() auto smtlib2Interface = dynamic_cast(m_interface.get()); solAssert(smtlib2Interface); smtlib2Interface->reset(); - m_context.setSolver(smtlib2Interface->smtlib2Interface()); + m_context.setSolver(smtlib2Interface); } m_context.reset(); @@ -1743,7 +1743,6 @@ void CHC::createErrorBlock() "error_target_" + std::to_string(m_context.newUniqueId()), PredicateType::Error ); - m_interface->registerRelation(m_errorPredicate->functor()); } void CHC::connectBlocks(smtutil::Expression const& _from, smtutil::Expression const& _to, smtutil::Expression const& _constraints) diff --git a/libsolidity/formal/EldaricaCHCSmtLib2Interface.cpp b/libsolidity/formal/EldaricaCHCSmtLib2Interface.cpp index 4fa94539d8b8..46416f2d9c31 100644 --- a/libsolidity/formal/EldaricaCHCSmtLib2Interface.cpp +++ b/libsolidity/formal/EldaricaCHCSmtLib2Interface.cpp @@ -30,8 +30,10 @@ EldaricaCHCSmtLib2Interface::EldaricaCHCSmtLib2Interface( { } -void EldaricaCHCSmtLib2Interface::setupSmtCallback() +std::string EldaricaCHCSmtLib2Interface::querySolver(std::string const& _input) { if (auto* universalCallback = m_smtCallback.target()) universalCallback->smtCommand().setEldarica(m_queryTimeout, m_computeInvariants); + + return CHCSmtLib2Interface::querySolver(_input); } diff --git a/libsolidity/formal/EldaricaCHCSmtLib2Interface.h b/libsolidity/formal/EldaricaCHCSmtLib2Interface.h index 2c83b194ca7d..a0ebdc33262b 100644 --- a/libsolidity/formal/EldaricaCHCSmtLib2Interface.h +++ b/libsolidity/formal/EldaricaCHCSmtLib2Interface.h @@ -33,7 +33,7 @@ class EldaricaCHCSmtLib2Interface: public smtutil::CHCSmtLib2Interface ); private: - void setupSmtCallback() override; + std::string querySolver(std::string const& _input) override; bool m_computeInvariants; }; diff --git a/test/cmdlineTests/model_checker_print_query_all/err b/test/cmdlineTests/model_checker_print_query_all/err index 7fbaba3ebefc..76dff6664b80 100644 --- a/test/cmdlineTests/model_checker_print_query_all/err +++ b/test/cmdlineTests/model_checker_print_query_all/err @@ -1,125 +1,85 @@ Info: CHC: Requested query: (set-option :timeout 1000) (set-logic HORN) -(declare-datatypes ((|bytes_tuple| 0)) (((|bytes_tuple| (|bytes_tuple_accessor_array| (Array Int Int)) (|bytes_tuple_accessor_length| Int))))) -(declare-datatypes ((|tx_type| 0)) (((|tx_type| (|block.basefee| Int) (|block.chainid| Int) (|block.coinbase| Int) (|block.gaslimit| Int) (|block.number| Int) (|block.prevrandao| Int) (|block.timestamp| Int) (|blockhash| (Array Int Int)) (|msg.data| |bytes_tuple|) (|msg.sender| Int) (|msg.sig| Int) (|msg.value| Int) (|tx.gasprice| Int) (|tx.origin| Int))))) +(declare-datatypes ((|abi_type| 0)) (((|abi_type|)))) (declare-datatypes ((|ecrecover_input_type| 0)) (((|ecrecover_input_type| (|hash| Int) (|v| Int) (|r| Int) (|s| Int))))) +(declare-datatypes ((|bytes_tuple| 0)) (((|bytes_tuple| (|bytes_tuple_accessor_array| (Array Int Int)) (|bytes_tuple_accessor_length| Int))))) (declare-datatypes ((|crypto_type| 0)) (((|crypto_type| (|ecrecover| (Array |ecrecover_input_type| Int)) (|keccak256| (Array |bytes_tuple| Int)) (|ripemd160| (Array |bytes_tuple| Int)) (|sha256| (Array |bytes_tuple| Int)))))) -(declare-datatypes ((|abi_type| 0)) (((|abi_type|)))) (declare-datatypes ((|state_type| 0)) (((|state_type| (|balances| (Array Int Int)))))) -(declare-fun |interface_0_C_16| (Int |abi_type| |crypto_type| |state_type| ) Bool) -(declare-fun |nondet_interface_1_C_16| (Int Int |abi_type| |crypto_type| |state_type| |state_type| ) Bool) -(declare-fun |summary_constructor_2_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (this_0 Int) (tx_0 |tx_type|)) -(=> (= error_0 0) (nondet_interface_1_C_16 error_0 this_0 abi_0 crypto_0 state_0 state_0)))) - - -(declare-fun |summary_3_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) -(declare-fun |summary_4_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|)) -(=> (and (and (nondet_interface_1_C_16 error_0 this_0 abi_0 crypto_0 state_0 state_1) true) (and (= error_0 0) (summary_4_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2))) (nondet_interface_1_C_16 error_1 this_0 abi_0 crypto_0 state_0 state_2)))) - - -(declare-fun |block_5_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int ) Bool) -(declare-fun |block_6_f_14_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int ) Bool) -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int)) -(block_5_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1))) - - -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int)) -(=> (and (and (block_5_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true)) true) (block_6_f_14_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1)))) - - -(declare-fun |block_7_return_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int ) Bool) -(declare-fun |block_8_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int ) Bool) -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (block_6_f_14_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (= expr_11_1 (= expr_9_0 expr_10_0)) (and (=> true true) (and (= expr_10_0 0) (and (=> true (and (>= expr_9_0 0) (<= expr_9_0 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (= expr_9_0 x_5_2) (and (= x_5_2 expr_6_0) (and (=> true true) (and (= expr_6_0 0) (and (= x_5_1 0) true)))))))))) (and (and true (not expr_11_1)) (= error_1 1))) (block_8_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_2)))) - - -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (block_8_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_2) (summary_3_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) - - -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (block_6_f_14_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (= error_1 error_0) (and (= expr_11_1 (= expr_9_0 expr_10_0)) (and (=> true true) (and (= expr_10_0 0) (and (=> true (and (>= expr_9_0 0) (<= expr_9_0 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (= expr_9_0 x_5_2) (and (= x_5_2 expr_6_0) (and (=> true true) (and (= expr_6_0 0) (and (= x_5_1 0) true))))))))))) true) (block_7_return_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_2)))) - - -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (block_7_return_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) true) true) (summary_3_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) - - -(declare-fun |block_9_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int ) Bool) -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(block_9_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1))) - - -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (block_9_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (summary_3_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_2 state_3) (and (= state_2 (|state_type| (store (|balances| state_1) this_0 (+ (select (|balances| state_1) this_0) funds_2_0)))) (and (and (>= (+ (select (|balances| state_1) this_0) funds_2_0) 0) (<= (+ (select (|balances| state_1) this_0) funds_2_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935)) (and (>= funds_2_0 (|msg.value| tx_0)) (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (and (and (and (and (and (= (|msg.value| tx_0) 0) (= (|msg.sig| tx_0) 638722032)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 0) 38)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 1) 18)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 2) 31)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 3) 240)) (>= (|bytes_tuple_accessor_length| (|msg.data| tx_0)) 4))) (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true))))))) true) (summary_4_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_3)))) - - -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (interface_0_C_16 this_0 abi_0 crypto_0 state_0) true) (and (summary_4_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (= error_0 0))) (interface_0_C_16 this_0 abi_0 crypto_0 state_1)))) - - -(declare-fun |contract_initializer_10_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) -(declare-fun |contract_initializer_entry_11_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (= state_1 state_0) (= error_0 0)) true) (contract_initializer_entry_11_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) - - -(declare-fun |contract_initializer_after_init_12_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (contract_initializer_entry_11_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) true) (contract_initializer_after_init_12_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) - - -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (contract_initializer_after_init_12_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) true) (contract_initializer_10_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) - - -(declare-fun |implicit_constructor_entry_13_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true) (>= (select (|balances| state_1) this_0) (|msg.value| tx_0))) (implicit_constructor_entry_13_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) - - -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (implicit_constructor_entry_13_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (and (contract_initializer_10_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2) true)) (> error_1 0)) (summary_constructor_2_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_2)))) - - -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (implicit_constructor_entry_13_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (and (= error_1 0) (and (contract_initializer_10_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2) true))) true) (summary_constructor_2_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_2)))) - - -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (summary_constructor_2_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (= (|msg.value| tx_0) 0)) (= error_0 0))) (interface_0_C_16 this_0 abi_0 crypto_0 state_1)))) - - +(declare-fun |interface_0_C_16| (Int |abi_type| |crypto_type| |state_type|) Bool) +(declare-fun |nondet_interface_1_C_16| (Int Int |abi_type| |crypto_type| |state_type| |state_type|) Bool) +(declare-datatypes ((|tx_type| 0)) (((|tx_type| (|block.basefee| Int) (|block.chainid| Int) (|block.coinbase| Int) (|block.gaslimit| Int) (|block.number| Int) (|block.prevrandao| Int) (|block.timestamp| Int) (|blockhash| (Array Int Int)) (|msg.data| |bytes_tuple|) (|msg.sender| Int) (|msg.sig| Int) (|msg.value| Int) (|tx.gasprice| Int) (|tx.origin| Int))))) +(declare-fun |summary_constructor_2_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (this_0 Int)) +(=> (= error_0 0) (nondet_interface_1_C_16 error_0 this_0 abi_0 crypto_0 state_0 state_0))) +) +(declare-fun |summary_3_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool) +(declare-fun |summary_4_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|)) +(=> (and (and (nondet_interface_1_C_16 error_0 this_0 abi_0 crypto_0 state_0 state_1) true) (and (= error_0 0) (summary_4_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2))) (nondet_interface_1_C_16 error_1 this_0 abi_0 crypto_0 state_0 state_2))) +) +(declare-fun |block_5_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int) Bool) +(declare-fun |block_6_f_14_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int) Bool) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_1 Int)) +(block_5_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1)) +) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_1 Int)) +(=> (and (and (block_5_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true)) true) (block_6_f_14_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1))) +) +(declare-fun |block_7_return_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int) Bool) +(declare-fun |block_8_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int) Bool) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_1 Int) (x_5_2 Int)) +(=> (and (and (block_6_f_14_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (= expr_11_1 (= expr_9_0 expr_10_0)) (and (=> true true) (and (= expr_10_0 0) (and (=> true (and (>= expr_9_0 0) (<= expr_9_0 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (= expr_9_0 x_5_2) (and (= x_5_2 expr_6_0) (and (=> true true) (and (= expr_6_0 0) (and (= x_5_1 0) true)))))))))) (and (and true (not expr_11_1)) (= error_1 1))) (block_8_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_2))) +) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_1 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_2 Int)) +(=> (block_8_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_2) (summary_3_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1))) +) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_1 Int) (x_5_2 Int)) +(=> (and (and (block_6_f_14_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (= error_1 error_0) (and (= expr_11_1 (= expr_9_0 expr_10_0)) (and (=> true true) (and (= expr_10_0 0) (and (=> true (and (>= expr_9_0 0) (<= expr_9_0 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (= expr_9_0 x_5_2) (and (= x_5_2 expr_6_0) (and (=> true true) (and (= expr_6_0 0) (and (= x_5_1 0) true))))))))))) true) (block_7_return_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_2))) +) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_1 Int)) +(=> (and (and (block_7_return_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) true) true) (summary_3_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1))) +) +(declare-fun |block_9_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int) Bool) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_1 Int)) +(block_9_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1)) +) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_1 Int)) +(=> (and (and (block_9_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (summary_3_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_2 state_3) (and (= state_2 (|state_type| (store (|balances| state_1) this_0 (+ (select (|balances| state_1) this_0) funds_2_0)))) (and (and (>= (+ (select (|balances| state_1) this_0) funds_2_0) 0) (<= (+ (select (|balances| state_1) this_0) funds_2_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935)) (and (>= funds_2_0 (|msg.value| tx_0)) (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (and (and (and (and (and (= (|msg.value| tx_0) 0) (= (|msg.sig| tx_0) 638722032)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 0) 38)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 1) 18)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 2) 31)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 3) 240)) (>= (|bytes_tuple_accessor_length| (|msg.data| tx_0)) 4))) (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true))))))) true) (summary_4_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_3))) +) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|)) +(=> (and (and (interface_0_C_16 this_0 abi_0 crypto_0 state_0) true) (and (summary_4_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (= error_0 0))) (interface_0_C_16 this_0 abi_0 crypto_0 state_1))) +) +(declare-fun |contract_initializer_10_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool) +(declare-fun |contract_initializer_entry_11_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|)) +(=> (and (and (= state_1 state_0) (= error_0 0)) true) (contract_initializer_entry_11_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1))) +) +(declare-fun |contract_initializer_after_init_12_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|)) +(=> (and (and (contract_initializer_entry_11_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) true) (contract_initializer_after_init_12_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1))) +) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|)) +(=> (and (and (contract_initializer_after_init_12_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) true) (contract_initializer_10_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1))) +) +(declare-fun |implicit_constructor_entry_13_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|)) +(=> (and (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true) (>= (select (|balances| state_1) this_0) (|msg.value| tx_0))) (implicit_constructor_entry_13_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1))) +) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|)) +(=> (and (and (implicit_constructor_entry_13_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (and (contract_initializer_10_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2) true)) (> error_1 0)) (summary_constructor_2_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_2))) +) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|)) +(=> (and (and (implicit_constructor_entry_13_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (and (= error_1 0) (and (contract_initializer_10_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2) true))) true) (summary_constructor_2_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_2))) +) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|)) +(=> (and (and (summary_constructor_2_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (= (|msg.value| tx_0) 0)) (= error_0 0))) (interface_0_C_16 this_0 abi_0 crypto_0 state_1))) +) (declare-fun |error_target_3| () Bool) -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (interface_0_C_16 this_0 abi_0 crypto_0 state_0) true) (and (summary_4_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (= error_0 1))) error_target_3))) - - - -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|)) +(=> (and (and (interface_0_C_16 this_0 abi_0 crypto_0 state_0) true) (and (summary_4_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (= error_0 1))) error_target_3)) +)(assert +(forall ((UNUSED Bool)) (=> error_target_3 false))) (check-sat) @@ -152,7 +112,6 @@ Info: BMC: Requested query: (declare-fun |expr_9_0| () Int) (declare-fun |expr_10_0| () Int) (declare-fun |expr_11_1| () Bool) - (assert (and (and (and true true) (and (= expr_11_1 (= expr_9_0 expr_10_0)) (and (=> (and true true) true) (and (= expr_10_0 0) (and (=> (and true true) (and (>= expr_9_0 0) (<= expr_9_0 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (= expr_9_0 x_5_1) (and (ite (and true true) (= x_5_1 expr_6_0) (= x_5_1 x_5_0)) (and (=> (and true true) true) (and (= expr_6_0 0) (and (= x_5_0 0) (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (and (and (and (and (and (= (|msg.value| tx_0) 0) (= (|msg.sig| tx_0) 638722032)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 0) 38)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 1) 18)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 2) 31)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 3) 240)) (>= (|bytes_tuple_accessor_length| (|msg.data| tx_0)) 4))) true))))))))))) (not expr_11_1))) (declare-const |EVALEXPR_0| Int) (assert (= |EVALEXPR_0| x_5_1)) diff --git a/test/cmdlineTests/model_checker_print_query_bmc/err b/test/cmdlineTests/model_checker_print_query_bmc/err index ff8b796f8785..6fb8440b7b8b 100644 --- a/test/cmdlineTests/model_checker_print_query_bmc/err +++ b/test/cmdlineTests/model_checker_print_query_bmc/err @@ -19,7 +19,6 @@ Info: BMC: Requested query: (declare-fun |expr_9_0| () Int) (declare-fun |expr_10_0| () Int) (declare-fun |expr_11_1| () Bool) - (assert (and (and (and true true) (and (= expr_11_1 (= expr_9_0 expr_10_0)) (and (=> (and true true) true) (and (= expr_10_0 0) (and (=> (and true true) (and (>= expr_9_0 0) (<= expr_9_0 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (= expr_9_0 x_5_1) (and (ite (and true true) (= x_5_1 expr_6_0) (= x_5_1 x_5_0)) (and (=> (and true true) true) (and (= expr_6_0 0) (and (= x_5_0 0) (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (and (and (and (and (and (= (|msg.value| tx_0) 0) (= (|msg.sig| tx_0) 638722032)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 0) 38)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 1) 18)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 2) 31)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 3) 240)) (>= (|bytes_tuple_accessor_length| (|msg.data| tx_0)) 4))) true))))))))))) (not expr_11_1))) (declare-const |EVALEXPR_0| Int) (assert (= |EVALEXPR_0| x_5_1)) diff --git a/test/cmdlineTests/model_checker_print_query_chc/err b/test/cmdlineTests/model_checker_print_query_chc/err index 4da0a7cb5a85..28368f546205 100644 --- a/test/cmdlineTests/model_checker_print_query_chc/err +++ b/test/cmdlineTests/model_checker_print_query_chc/err @@ -1,125 +1,85 @@ Info: CHC: Requested query: (set-option :timeout 1000) (set-logic HORN) -(declare-datatypes ((|bytes_tuple| 0)) (((|bytes_tuple| (|bytes_tuple_accessor_array| (Array Int Int)) (|bytes_tuple_accessor_length| Int))))) -(declare-datatypes ((|tx_type| 0)) (((|tx_type| (|block.basefee| Int) (|block.chainid| Int) (|block.coinbase| Int) (|block.gaslimit| Int) (|block.number| Int) (|block.prevrandao| Int) (|block.timestamp| Int) (|blockhash| (Array Int Int)) (|msg.data| |bytes_tuple|) (|msg.sender| Int) (|msg.sig| Int) (|msg.value| Int) (|tx.gasprice| Int) (|tx.origin| Int))))) +(declare-datatypes ((|abi_type| 0)) (((|abi_type|)))) (declare-datatypes ((|ecrecover_input_type| 0)) (((|ecrecover_input_type| (|hash| Int) (|v| Int) (|r| Int) (|s| Int))))) +(declare-datatypes ((|bytes_tuple| 0)) (((|bytes_tuple| (|bytes_tuple_accessor_array| (Array Int Int)) (|bytes_tuple_accessor_length| Int))))) (declare-datatypes ((|crypto_type| 0)) (((|crypto_type| (|ecrecover| (Array |ecrecover_input_type| Int)) (|keccak256| (Array |bytes_tuple| Int)) (|ripemd160| (Array |bytes_tuple| Int)) (|sha256| (Array |bytes_tuple| Int)))))) -(declare-datatypes ((|abi_type| 0)) (((|abi_type|)))) (declare-datatypes ((|state_type| 0)) (((|state_type| (|balances| (Array Int Int)))))) -(declare-fun |interface_0_C_16| (Int |abi_type| |crypto_type| |state_type| ) Bool) -(declare-fun |nondet_interface_1_C_16| (Int Int |abi_type| |crypto_type| |state_type| |state_type| ) Bool) -(declare-fun |summary_constructor_2_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (this_0 Int) (tx_0 |tx_type|)) -(=> (= error_0 0) (nondet_interface_1_C_16 error_0 this_0 abi_0 crypto_0 state_0 state_0)))) - - -(declare-fun |summary_3_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) -(declare-fun |summary_4_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|)) -(=> (and (and (nondet_interface_1_C_16 error_0 this_0 abi_0 crypto_0 state_0 state_1) true) (and (= error_0 0) (summary_4_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2))) (nondet_interface_1_C_16 error_1 this_0 abi_0 crypto_0 state_0 state_2)))) - - -(declare-fun |block_5_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int ) Bool) -(declare-fun |block_6_f_14_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int ) Bool) -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int)) -(block_5_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1))) - - -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int)) -(=> (and (and (block_5_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true)) true) (block_6_f_14_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1)))) - - -(declare-fun |block_7_return_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int ) Bool) -(declare-fun |block_8_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int ) Bool) -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (block_6_f_14_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (= expr_11_1 (= expr_9_0 expr_10_0)) (and (=> true true) (and (= expr_10_0 0) (and (=> true (and (>= expr_9_0 0) (<= expr_9_0 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (= expr_9_0 x_5_2) (and (= x_5_2 expr_6_0) (and (=> true true) (and (= expr_6_0 0) (and (= x_5_1 0) true)))))))))) (and (and true (not expr_11_1)) (= error_1 1))) (block_8_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_2)))) - - -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (block_8_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_2) (summary_3_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) - - -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (block_6_f_14_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (= error_1 error_0) (and (= expr_11_1 (= expr_9_0 expr_10_0)) (and (=> true true) (and (= expr_10_0 0) (and (=> true (and (>= expr_9_0 0) (<= expr_9_0 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (= expr_9_0 x_5_2) (and (= x_5_2 expr_6_0) (and (=> true true) (and (= expr_6_0 0) (and (= x_5_1 0) true))))))))))) true) (block_7_return_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_2)))) - - -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (block_7_return_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) true) true) (summary_3_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) - - -(declare-fun |block_9_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int ) Bool) -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(block_9_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1))) - - -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (block_9_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (summary_3_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_2 state_3) (and (= state_2 (|state_type| (store (|balances| state_1) this_0 (+ (select (|balances| state_1) this_0) funds_2_0)))) (and (and (>= (+ (select (|balances| state_1) this_0) funds_2_0) 0) (<= (+ (select (|balances| state_1) this_0) funds_2_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935)) (and (>= funds_2_0 (|msg.value| tx_0)) (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (and (and (and (and (and (= (|msg.value| tx_0) 0) (= (|msg.sig| tx_0) 638722032)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 0) 38)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 1) 18)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 2) 31)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 3) 240)) (>= (|bytes_tuple_accessor_length| (|msg.data| tx_0)) 4))) (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true))))))) true) (summary_4_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_3)))) - - -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (interface_0_C_16 this_0 abi_0 crypto_0 state_0) true) (and (summary_4_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (= error_0 0))) (interface_0_C_16 this_0 abi_0 crypto_0 state_1)))) - - -(declare-fun |contract_initializer_10_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) -(declare-fun |contract_initializer_entry_11_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (= state_1 state_0) (= error_0 0)) true) (contract_initializer_entry_11_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) - - -(declare-fun |contract_initializer_after_init_12_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (contract_initializer_entry_11_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) true) (contract_initializer_after_init_12_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) - - -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (contract_initializer_after_init_12_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) true) (contract_initializer_10_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) - - -(declare-fun |implicit_constructor_entry_13_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true) (>= (select (|balances| state_1) this_0) (|msg.value| tx_0))) (implicit_constructor_entry_13_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) - - -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (implicit_constructor_entry_13_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (and (contract_initializer_10_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2) true)) (> error_1 0)) (summary_constructor_2_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_2)))) - - -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (implicit_constructor_entry_13_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (and (= error_1 0) (and (contract_initializer_10_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2) true))) true) (summary_constructor_2_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_2)))) - - -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (summary_constructor_2_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (= (|msg.value| tx_0) 0)) (= error_0 0))) (interface_0_C_16 this_0 abi_0 crypto_0 state_1)))) - - +(declare-fun |interface_0_C_16| (Int |abi_type| |crypto_type| |state_type|) Bool) +(declare-fun |nondet_interface_1_C_16| (Int Int |abi_type| |crypto_type| |state_type| |state_type|) Bool) +(declare-datatypes ((|tx_type| 0)) (((|tx_type| (|block.basefee| Int) (|block.chainid| Int) (|block.coinbase| Int) (|block.gaslimit| Int) (|block.number| Int) (|block.prevrandao| Int) (|block.timestamp| Int) (|blockhash| (Array Int Int)) (|msg.data| |bytes_tuple|) (|msg.sender| Int) (|msg.sig| Int) (|msg.value| Int) (|tx.gasprice| Int) (|tx.origin| Int))))) +(declare-fun |summary_constructor_2_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (this_0 Int)) +(=> (= error_0 0) (nondet_interface_1_C_16 error_0 this_0 abi_0 crypto_0 state_0 state_0))) +) +(declare-fun |summary_3_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool) +(declare-fun |summary_4_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|)) +(=> (and (and (nondet_interface_1_C_16 error_0 this_0 abi_0 crypto_0 state_0 state_1) true) (and (= error_0 0) (summary_4_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2))) (nondet_interface_1_C_16 error_1 this_0 abi_0 crypto_0 state_0 state_2))) +) +(declare-fun |block_5_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int) Bool) +(declare-fun |block_6_f_14_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int) Bool) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_1 Int)) +(block_5_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1)) +) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_1 Int)) +(=> (and (and (block_5_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true)) true) (block_6_f_14_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1))) +) +(declare-fun |block_7_return_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int) Bool) +(declare-fun |block_8_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int) Bool) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_1 Int) (x_5_2 Int)) +(=> (and (and (block_6_f_14_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (= expr_11_1 (= expr_9_0 expr_10_0)) (and (=> true true) (and (= expr_10_0 0) (and (=> true (and (>= expr_9_0 0) (<= expr_9_0 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (= expr_9_0 x_5_2) (and (= x_5_2 expr_6_0) (and (=> true true) (and (= expr_6_0 0) (and (= x_5_1 0) true)))))))))) (and (and true (not expr_11_1)) (= error_1 1))) (block_8_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_2))) +) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_1 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_2 Int)) +(=> (block_8_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_2) (summary_3_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1))) +) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_1 Int) (x_5_2 Int)) +(=> (and (and (block_6_f_14_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (= error_1 error_0) (and (= expr_11_1 (= expr_9_0 expr_10_0)) (and (=> true true) (and (= expr_10_0 0) (and (=> true (and (>= expr_9_0 0) (<= expr_9_0 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (= expr_9_0 x_5_2) (and (= x_5_2 expr_6_0) (and (=> true true) (and (= expr_6_0 0) (and (= x_5_1 0) true))))))))))) true) (block_7_return_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_2))) +) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_1 Int)) +(=> (and (and (block_7_return_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) true) true) (summary_3_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1))) +) +(declare-fun |block_9_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int) Bool) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_1 Int)) +(block_9_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1)) +) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_1 Int)) +(=> (and (and (block_9_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (summary_3_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_2 state_3) (and (= state_2 (|state_type| (store (|balances| state_1) this_0 (+ (select (|balances| state_1) this_0) funds_2_0)))) (and (and (>= (+ (select (|balances| state_1) this_0) funds_2_0) 0) (<= (+ (select (|balances| state_1) this_0) funds_2_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935)) (and (>= funds_2_0 (|msg.value| tx_0)) (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (and (and (and (and (and (= (|msg.value| tx_0) 0) (= (|msg.sig| tx_0) 638722032)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 0) 38)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 1) 18)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 2) 31)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 3) 240)) (>= (|bytes_tuple_accessor_length| (|msg.data| tx_0)) 4))) (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true))))))) true) (summary_4_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_3))) +) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|)) +(=> (and (and (interface_0_C_16 this_0 abi_0 crypto_0 state_0) true) (and (summary_4_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (= error_0 0))) (interface_0_C_16 this_0 abi_0 crypto_0 state_1))) +) +(declare-fun |contract_initializer_10_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool) +(declare-fun |contract_initializer_entry_11_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|)) +(=> (and (and (= state_1 state_0) (= error_0 0)) true) (contract_initializer_entry_11_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1))) +) +(declare-fun |contract_initializer_after_init_12_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|)) +(=> (and (and (contract_initializer_entry_11_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) true) (contract_initializer_after_init_12_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1))) +) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|)) +(=> (and (and (contract_initializer_after_init_12_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) true) (contract_initializer_10_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1))) +) +(declare-fun |implicit_constructor_entry_13_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|)) +(=> (and (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true) (>= (select (|balances| state_1) this_0) (|msg.value| tx_0))) (implicit_constructor_entry_13_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1))) +) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|)) +(=> (and (and (implicit_constructor_entry_13_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (and (contract_initializer_10_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2) true)) (> error_1 0)) (summary_constructor_2_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_2))) +) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|)) +(=> (and (and (implicit_constructor_entry_13_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (and (= error_1 0) (and (contract_initializer_10_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2) true))) true) (summary_constructor_2_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_2))) +) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|)) +(=> (and (and (summary_constructor_2_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (= (|msg.value| tx_0) 0)) (= error_0 0))) (interface_0_C_16 this_0 abi_0 crypto_0 state_1))) +) (declare-fun |error_target_3| () Bool) -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (interface_0_C_16 this_0 abi_0 crypto_0 state_0) true) (and (summary_4_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (= error_0 1))) error_target_3))) - - - -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|)) +(=> (and (and (interface_0_C_16 this_0 abi_0 crypto_0 state_0) true) (and (summary_4_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (= error_0 1))) error_target_3)) +)(assert +(forall ((UNUSED Bool)) (=> error_target_3 false))) (check-sat) diff --git a/test/cmdlineTests/standard_model_checker_print_query_all/output.json b/test/cmdlineTests/standard_model_checker_print_query_all/output.json index 4b5782de314b..a800fb34d7b6 100644 --- a/test/cmdlineTests/standard_model_checker_print_query_all/output.json +++ b/test/cmdlineTests/standard_model_checker_print_query_all/output.json @@ -1,131 +1,7 @@ { "auxiliaryInputRequested": { "smtlib2queries": { - "0xcbd85fe3127d1edfce70355ba6da5a3e9573873d8596ee8b1cfc2222af166628": "(set-option :timeout 1000) -(set-logic HORN) -(declare-datatypes ((|bytes_tuple| 0)) (((|bytes_tuple| (|bytes_tuple_accessor_array| (Array Int Int)) (|bytes_tuple_accessor_length| Int))))) -(declare-datatypes ((|tx_type| 0)) (((|tx_type| (|block.basefee| Int) (|block.chainid| Int) (|block.coinbase| Int) (|block.gaslimit| Int) (|block.number| Int) (|block.prevrandao| Int) (|block.timestamp| Int) (|blockhash| (Array Int Int)) (|msg.data| |bytes_tuple|) (|msg.sender| Int) (|msg.sig| Int) (|msg.value| Int) (|tx.gasprice| Int) (|tx.origin| Int))))) -(declare-datatypes ((|ecrecover_input_type| 0)) (((|ecrecover_input_type| (|hash| Int) (|v| Int) (|r| Int) (|s| Int))))) -(declare-datatypes ((|crypto_type| 0)) (((|crypto_type| (|ecrecover| (Array |ecrecover_input_type| Int)) (|keccak256| (Array |bytes_tuple| Int)) (|ripemd160| (Array |bytes_tuple| Int)) (|sha256| (Array |bytes_tuple| Int)))))) -(declare-datatypes ((|abi_type| 0)) (((|abi_type|)))) -(declare-datatypes ((|state_type| 0)) (((|state_type| (|balances| (Array Int Int)))))) -(declare-fun |interface_0_C_16| (Int |abi_type| |crypto_type| |state_type| ) Bool) -(declare-fun |nondet_interface_1_C_16| (Int Int |abi_type| |crypto_type| |state_type| |state_type| ) Bool) -(declare-fun |summary_constructor_2_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (this_0 Int) (tx_0 |tx_type|)) -(=> (= error_0 0) (nondet_interface_1_C_16 error_0 this_0 abi_0 crypto_0 state_0 state_0)))) - - -(declare-fun |summary_3_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) -(declare-fun |summary_4_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|)) -(=> (and (and (nondet_interface_1_C_16 error_0 this_0 abi_0 crypto_0 state_0 state_1) true) (and (= error_0 0) (summary_4_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2))) (nondet_interface_1_C_16 error_1 this_0 abi_0 crypto_0 state_0 state_2)))) - - -(declare-fun |block_5_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int ) Bool) -(declare-fun |block_6_f_14_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int ) Bool) -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int)) -(block_5_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1))) - - -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int)) -(=> (and (and (block_5_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true)) true) (block_6_f_14_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1)))) - - -(declare-fun |block_7_return_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int ) Bool) -(declare-fun |block_8_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int ) Bool) -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (block_6_f_14_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (= expr_11_1 (= expr_9_0 expr_10_0)) (and (=> true true) (and (= expr_10_0 0) (and (=> true (and (>= expr_9_0 0) (<= expr_9_0 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (= expr_9_0 x_5_2) (and (= x_5_2 expr_6_0) (and (=> true true) (and (= expr_6_0 0) (and (= x_5_1 0) true)))))))))) (and (and true (not expr_11_1)) (= error_1 1))) (block_8_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_2)))) - - -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (block_8_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_2) (summary_3_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) - - -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (block_6_f_14_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (= error_1 error_0) (and (= expr_11_1 (= expr_9_0 expr_10_0)) (and (=> true true) (and (= expr_10_0 0) (and (=> true (and (>= expr_9_0 0) (<= expr_9_0 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (= expr_9_0 x_5_2) (and (= x_5_2 expr_6_0) (and (=> true true) (and (= expr_6_0 0) (and (= x_5_1 0) true))))))))))) true) (block_7_return_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_2)))) - - -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (block_7_return_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) true) true) (summary_3_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) - - -(declare-fun |block_9_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int ) Bool) -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(block_9_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1))) - - -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (block_9_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (summary_3_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_2 state_3) (and (= state_2 (|state_type| (store (|balances| state_1) this_0 (+ (select (|balances| state_1) this_0) funds_2_0)))) (and (and (>= (+ (select (|balances| state_1) this_0) funds_2_0) 0) (<= (+ (select (|balances| state_1) this_0) funds_2_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935)) (and (>= funds_2_0 (|msg.value| tx_0)) (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (and (and (and (and (and (= (|msg.value| tx_0) 0) (= (|msg.sig| tx_0) 638722032)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 0) 38)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 1) 18)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 2) 31)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 3) 240)) (>= (|bytes_tuple_accessor_length| (|msg.data| tx_0)) 4))) (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true))))))) true) (summary_4_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_3)))) - - -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (interface_0_C_16 this_0 abi_0 crypto_0 state_0) true) (and (summary_4_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (= error_0 0))) (interface_0_C_16 this_0 abi_0 crypto_0 state_1)))) - - -(declare-fun |contract_initializer_10_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) -(declare-fun |contract_initializer_entry_11_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (= state_1 state_0) (= error_0 0)) true) (contract_initializer_entry_11_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) - - -(declare-fun |contract_initializer_after_init_12_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (contract_initializer_entry_11_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) true) (contract_initializer_after_init_12_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) - - -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (contract_initializer_after_init_12_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) true) (contract_initializer_10_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) - - -(declare-fun |implicit_constructor_entry_13_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true) (>= (select (|balances| state_1) this_0) (|msg.value| tx_0))) (implicit_constructor_entry_13_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) - - -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (implicit_constructor_entry_13_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (and (contract_initializer_10_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2) true)) (> error_1 0)) (summary_constructor_2_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_2)))) - - -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (implicit_constructor_entry_13_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (and (= error_1 0) (and (contract_initializer_10_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2) true))) true) (summary_constructor_2_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_2)))) - - -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (summary_constructor_2_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (= (|msg.value| tx_0) 0)) (= error_0 0))) (interface_0_C_16 this_0 abi_0 crypto_0 state_1)))) - - -(declare-fun |error_target_3| () Bool) -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (interface_0_C_16 this_0 abi_0 crypto_0 state_0) true) (and (summary_4_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (= error_0 1))) error_target_3))) - - - -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> error_target_3 false))) -(check-sat) -", - "0xcbfcc2413b217c6564ee01f322c9ca1f34fd79d19961dc3e62aa9c2e5dcb6efc": "(set-option :produce-models true) + "0x54683263097e1c4f5e0e75b68e4ebe3e4f7042f899198181df911c8196a1725b": "(set-option :produce-models true) (set-option :timeout 1000) (set-logic ALL) (declare-fun |x_5_3| () Int) @@ -148,12 +24,95 @@ (declare-fun |expr_9_0| () Int) (declare-fun |expr_10_0| () Int) (declare-fun |expr_11_1| () Bool) - (assert (and (and (and true true) (and (= expr_11_1 (= expr_9_0 expr_10_0)) (and (=> (and true true) true) (and (= expr_10_0 0) (and (=> (and true true) (and (>= expr_9_0 0) (<= expr_9_0 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (= expr_9_0 x_5_1) (and (ite (and true true) (= x_5_1 expr_6_0) (= x_5_1 x_5_0)) (and (=> (and true true) true) (and (= expr_6_0 0) (and (= x_5_0 0) (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (and (and (and (and (and (= (|msg.value| tx_0) 0) (= (|msg.sig| tx_0) 638722032)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 0) 38)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 1) 18)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 2) 31)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 3) 240)) (>= (|bytes_tuple_accessor_length| (|msg.data| tx_0)) 4))) true))))))))))) (not expr_11_1))) (declare-const |EVALEXPR_0| Int) (assert (= |EVALEXPR_0| x_5_1)) (check-sat) (get-value (|EVALEXPR_0| )) +", + "0x9cfcd53712a0be144c8e7983b3635498ead1af2624885fb89762eae8c43233e5": "(set-option :timeout 1000) +(set-logic HORN) +(declare-datatypes ((|abi_type| 0)) (((|abi_type|)))) +(declare-datatypes ((|ecrecover_input_type| 0)) (((|ecrecover_input_type| (|hash| Int) (|v| Int) (|r| Int) (|s| Int))))) +(declare-datatypes ((|bytes_tuple| 0)) (((|bytes_tuple| (|bytes_tuple_accessor_array| (Array Int Int)) (|bytes_tuple_accessor_length| Int))))) +(declare-datatypes ((|crypto_type| 0)) (((|crypto_type| (|ecrecover| (Array |ecrecover_input_type| Int)) (|keccak256| (Array |bytes_tuple| Int)) (|ripemd160| (Array |bytes_tuple| Int)) (|sha256| (Array |bytes_tuple| Int)))))) +(declare-datatypes ((|state_type| 0)) (((|state_type| (|balances| (Array Int Int)))))) +(declare-fun |interface_0_C_16| (Int |abi_type| |crypto_type| |state_type|) Bool) +(declare-fun |nondet_interface_1_C_16| (Int Int |abi_type| |crypto_type| |state_type| |state_type|) Bool) +(declare-datatypes ((|tx_type| 0)) (((|tx_type| (|block.basefee| Int) (|block.chainid| Int) (|block.coinbase| Int) (|block.gaslimit| Int) (|block.number| Int) (|block.prevrandao| Int) (|block.timestamp| Int) (|blockhash| (Array Int Int)) (|msg.data| |bytes_tuple|) (|msg.sender| Int) (|msg.sig| Int) (|msg.value| Int) (|tx.gasprice| Int) (|tx.origin| Int))))) +(declare-fun |summary_constructor_2_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (this_0 Int)) +(=> (= error_0 0) (nondet_interface_1_C_16 error_0 this_0 abi_0 crypto_0 state_0 state_0))) +) +(declare-fun |summary_3_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool) +(declare-fun |summary_4_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|)) +(=> (and (and (nondet_interface_1_C_16 error_0 this_0 abi_0 crypto_0 state_0 state_1) true) (and (= error_0 0) (summary_4_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2))) (nondet_interface_1_C_16 error_1 this_0 abi_0 crypto_0 state_0 state_2))) +) +(declare-fun |block_5_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int) Bool) +(declare-fun |block_6_f_14_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int) Bool) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_1 Int)) +(block_5_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1)) +) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_1 Int)) +(=> (and (and (block_5_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true)) true) (block_6_f_14_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1))) +) +(declare-fun |block_7_return_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int) Bool) +(declare-fun |block_8_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int) Bool) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_1 Int) (x_5_2 Int)) +(=> (and (and (block_6_f_14_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (= expr_11_1 (= expr_9_0 expr_10_0)) (and (=> true true) (and (= expr_10_0 0) (and (=> true (and (>= expr_9_0 0) (<= expr_9_0 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (= expr_9_0 x_5_2) (and (= x_5_2 expr_6_0) (and (=> true true) (and (= expr_6_0 0) (and (= x_5_1 0) true)))))))))) (and (and true (not expr_11_1)) (= error_1 1))) (block_8_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_2))) +) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_1 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_2 Int)) +(=> (block_8_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_2) (summary_3_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1))) +) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_1 Int) (x_5_2 Int)) +(=> (and (and (block_6_f_14_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (= error_1 error_0) (and (= expr_11_1 (= expr_9_0 expr_10_0)) (and (=> true true) (and (= expr_10_0 0) (and (=> true (and (>= expr_9_0 0) (<= expr_9_0 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (= expr_9_0 x_5_2) (and (= x_5_2 expr_6_0) (and (=> true true) (and (= expr_6_0 0) (and (= x_5_1 0) true))))))))))) true) (block_7_return_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_2))) +) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_1 Int)) +(=> (and (and (block_7_return_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) true) true) (summary_3_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1))) +) +(declare-fun |block_9_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int) Bool) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_1 Int)) +(block_9_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1)) +) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_1 Int)) +(=> (and (and (block_9_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (summary_3_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_2 state_3) (and (= state_2 (|state_type| (store (|balances| state_1) this_0 (+ (select (|balances| state_1) this_0) funds_2_0)))) (and (and (>= (+ (select (|balances| state_1) this_0) funds_2_0) 0) (<= (+ (select (|balances| state_1) this_0) funds_2_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935)) (and (>= funds_2_0 (|msg.value| tx_0)) (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (and (and (and (and (and (= (|msg.value| tx_0) 0) (= (|msg.sig| tx_0) 638722032)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 0) 38)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 1) 18)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 2) 31)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 3) 240)) (>= (|bytes_tuple_accessor_length| (|msg.data| tx_0)) 4))) (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true))))))) true) (summary_4_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_3))) +) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|)) +(=> (and (and (interface_0_C_16 this_0 abi_0 crypto_0 state_0) true) (and (summary_4_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (= error_0 0))) (interface_0_C_16 this_0 abi_0 crypto_0 state_1))) +) +(declare-fun |contract_initializer_10_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool) +(declare-fun |contract_initializer_entry_11_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|)) +(=> (and (and (= state_1 state_0) (= error_0 0)) true) (contract_initializer_entry_11_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1))) +) +(declare-fun |contract_initializer_after_init_12_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|)) +(=> (and (and (contract_initializer_entry_11_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) true) (contract_initializer_after_init_12_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1))) +) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|)) +(=> (and (and (contract_initializer_after_init_12_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) true) (contract_initializer_10_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1))) +) +(declare-fun |implicit_constructor_entry_13_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|)) +(=> (and (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true) (>= (select (|balances| state_1) this_0) (|msg.value| tx_0))) (implicit_constructor_entry_13_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1))) +) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|)) +(=> (and (and (implicit_constructor_entry_13_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (and (contract_initializer_10_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2) true)) (> error_1 0)) (summary_constructor_2_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_2))) +) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|)) +(=> (and (and (implicit_constructor_entry_13_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (and (= error_1 0) (and (contract_initializer_10_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2) true))) true) (summary_constructor_2_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_2))) +) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|)) +(=> (and (and (summary_constructor_2_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (= (|msg.value| tx_0) 0)) (= error_0 0))) (interface_0_C_16 this_0 abi_0 crypto_0 state_1))) +) +(declare-fun |error_target_3| () Bool) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|)) +(=> (and (and (interface_0_C_16 this_0 abi_0 crypto_0 state_0) true) (and (summary_4_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (= error_0 1))) error_target_3)) +)(assert +(forall ((UNUSED Bool)) +(=> error_target_3 false))) +(check-sat) " } }, @@ -164,125 +123,85 @@ "formattedMessage": "Info: CHC: Requested query: (set-option :timeout 1000) (set-logic HORN) -(declare-datatypes ((|bytes_tuple| 0)) (((|bytes_tuple| (|bytes_tuple_accessor_array| (Array Int Int)) (|bytes_tuple_accessor_length| Int))))) -(declare-datatypes ((|tx_type| 0)) (((|tx_type| (|block.basefee| Int) (|block.chainid| Int) (|block.coinbase| Int) (|block.gaslimit| Int) (|block.number| Int) (|block.prevrandao| Int) (|block.timestamp| Int) (|blockhash| (Array Int Int)) (|msg.data| |bytes_tuple|) (|msg.sender| Int) (|msg.sig| Int) (|msg.value| Int) (|tx.gasprice| Int) (|tx.origin| Int))))) +(declare-datatypes ((|abi_type| 0)) (((|abi_type|)))) (declare-datatypes ((|ecrecover_input_type| 0)) (((|ecrecover_input_type| (|hash| Int) (|v| Int) (|r| Int) (|s| Int))))) +(declare-datatypes ((|bytes_tuple| 0)) (((|bytes_tuple| (|bytes_tuple_accessor_array| (Array Int Int)) (|bytes_tuple_accessor_length| Int))))) (declare-datatypes ((|crypto_type| 0)) (((|crypto_type| (|ecrecover| (Array |ecrecover_input_type| Int)) (|keccak256| (Array |bytes_tuple| Int)) (|ripemd160| (Array |bytes_tuple| Int)) (|sha256| (Array |bytes_tuple| Int)))))) -(declare-datatypes ((|abi_type| 0)) (((|abi_type|)))) (declare-datatypes ((|state_type| 0)) (((|state_type| (|balances| (Array Int Int)))))) -(declare-fun |interface_0_C_16| (Int |abi_type| |crypto_type| |state_type| ) Bool) -(declare-fun |nondet_interface_1_C_16| (Int Int |abi_type| |crypto_type| |state_type| |state_type| ) Bool) -(declare-fun |summary_constructor_2_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (this_0 Int) (tx_0 |tx_type|)) -(=> (= error_0 0) (nondet_interface_1_C_16 error_0 this_0 abi_0 crypto_0 state_0 state_0)))) - - -(declare-fun |summary_3_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) -(declare-fun |summary_4_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|)) -(=> (and (and (nondet_interface_1_C_16 error_0 this_0 abi_0 crypto_0 state_0 state_1) true) (and (= error_0 0) (summary_4_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2))) (nondet_interface_1_C_16 error_1 this_0 abi_0 crypto_0 state_0 state_2)))) - - -(declare-fun |block_5_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int ) Bool) -(declare-fun |block_6_f_14_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int ) Bool) -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int)) -(block_5_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1))) - - -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int)) -(=> (and (and (block_5_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true)) true) (block_6_f_14_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1)))) - - -(declare-fun |block_7_return_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int ) Bool) -(declare-fun |block_8_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int ) Bool) -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (block_6_f_14_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (= expr_11_1 (= expr_9_0 expr_10_0)) (and (=> true true) (and (= expr_10_0 0) (and (=> true (and (>= expr_9_0 0) (<= expr_9_0 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (= expr_9_0 x_5_2) (and (= x_5_2 expr_6_0) (and (=> true true) (and (= expr_6_0 0) (and (= x_5_1 0) true)))))))))) (and (and true (not expr_11_1)) (= error_1 1))) (block_8_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_2)))) - - -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (block_8_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_2) (summary_3_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) - - -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (block_6_f_14_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (= error_1 error_0) (and (= expr_11_1 (= expr_9_0 expr_10_0)) (and (=> true true) (and (= expr_10_0 0) (and (=> true (and (>= expr_9_0 0) (<= expr_9_0 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (= expr_9_0 x_5_2) (and (= x_5_2 expr_6_0) (and (=> true true) (and (= expr_6_0 0) (and (= x_5_1 0) true))))))))))) true) (block_7_return_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_2)))) - - -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (block_7_return_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) true) true) (summary_3_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) - - -(declare-fun |block_9_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int ) Bool) -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(block_9_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1))) - - -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (block_9_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (summary_3_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_2 state_3) (and (= state_2 (|state_type| (store (|balances| state_1) this_0 (+ (select (|balances| state_1) this_0) funds_2_0)))) (and (and (>= (+ (select (|balances| state_1) this_0) funds_2_0) 0) (<= (+ (select (|balances| state_1) this_0) funds_2_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935)) (and (>= funds_2_0 (|msg.value| tx_0)) (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (and (and (and (and (and (= (|msg.value| tx_0) 0) (= (|msg.sig| tx_0) 638722032)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 0) 38)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 1) 18)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 2) 31)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 3) 240)) (>= (|bytes_tuple_accessor_length| (|msg.data| tx_0)) 4))) (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true))))))) true) (summary_4_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_3)))) - - -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (interface_0_C_16 this_0 abi_0 crypto_0 state_0) true) (and (summary_4_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (= error_0 0))) (interface_0_C_16 this_0 abi_0 crypto_0 state_1)))) - - -(declare-fun |contract_initializer_10_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) -(declare-fun |contract_initializer_entry_11_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (= state_1 state_0) (= error_0 0)) true) (contract_initializer_entry_11_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) - - -(declare-fun |contract_initializer_after_init_12_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (contract_initializer_entry_11_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) true) (contract_initializer_after_init_12_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) - - -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (contract_initializer_after_init_12_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) true) (contract_initializer_10_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) - - -(declare-fun |implicit_constructor_entry_13_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true) (>= (select (|balances| state_1) this_0) (|msg.value| tx_0))) (implicit_constructor_entry_13_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) - - -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (implicit_constructor_entry_13_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (and (contract_initializer_10_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2) true)) (> error_1 0)) (summary_constructor_2_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_2)))) - - -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (implicit_constructor_entry_13_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (and (= error_1 0) (and (contract_initializer_10_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2) true))) true) (summary_constructor_2_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_2)))) - - -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (summary_constructor_2_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (= (|msg.value| tx_0) 0)) (= error_0 0))) (interface_0_C_16 this_0 abi_0 crypto_0 state_1)))) - - +(declare-fun |interface_0_C_16| (Int |abi_type| |crypto_type| |state_type|) Bool) +(declare-fun |nondet_interface_1_C_16| (Int Int |abi_type| |crypto_type| |state_type| |state_type|) Bool) +(declare-datatypes ((|tx_type| 0)) (((|tx_type| (|block.basefee| Int) (|block.chainid| Int) (|block.coinbase| Int) (|block.gaslimit| Int) (|block.number| Int) (|block.prevrandao| Int) (|block.timestamp| Int) (|blockhash| (Array Int Int)) (|msg.data| |bytes_tuple|) (|msg.sender| Int) (|msg.sig| Int) (|msg.value| Int) (|tx.gasprice| Int) (|tx.origin| Int))))) +(declare-fun |summary_constructor_2_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (this_0 Int)) +(=> (= error_0 0) (nondet_interface_1_C_16 error_0 this_0 abi_0 crypto_0 state_0 state_0))) +) +(declare-fun |summary_3_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool) +(declare-fun |summary_4_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|)) +(=> (and (and (nondet_interface_1_C_16 error_0 this_0 abi_0 crypto_0 state_0 state_1) true) (and (= error_0 0) (summary_4_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2))) (nondet_interface_1_C_16 error_1 this_0 abi_0 crypto_0 state_0 state_2))) +) +(declare-fun |block_5_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int) Bool) +(declare-fun |block_6_f_14_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int) Bool) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_1 Int)) +(block_5_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1)) +) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_1 Int)) +(=> (and (and (block_5_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true)) true) (block_6_f_14_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1))) +) +(declare-fun |block_7_return_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int) Bool) +(declare-fun |block_8_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int) Bool) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_1 Int) (x_5_2 Int)) +(=> (and (and (block_6_f_14_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (= expr_11_1 (= expr_9_0 expr_10_0)) (and (=> true true) (and (= expr_10_0 0) (and (=> true (and (>= expr_9_0 0) (<= expr_9_0 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (= expr_9_0 x_5_2) (and (= x_5_2 expr_6_0) (and (=> true true) (and (= expr_6_0 0) (and (= x_5_1 0) true)))))))))) (and (and true (not expr_11_1)) (= error_1 1))) (block_8_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_2))) +) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_1 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_2 Int)) +(=> (block_8_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_2) (summary_3_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1))) +) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_1 Int) (x_5_2 Int)) +(=> (and (and (block_6_f_14_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (= error_1 error_0) (and (= expr_11_1 (= expr_9_0 expr_10_0)) (and (=> true true) (and (= expr_10_0 0) (and (=> true (and (>= expr_9_0 0) (<= expr_9_0 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (= expr_9_0 x_5_2) (and (= x_5_2 expr_6_0) (and (=> true true) (and (= expr_6_0 0) (and (= x_5_1 0) true))))))))))) true) (block_7_return_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_2))) +) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_1 Int)) +(=> (and (and (block_7_return_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) true) true) (summary_3_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1))) +) +(declare-fun |block_9_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int) Bool) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_1 Int)) +(block_9_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1)) +) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_1 Int)) +(=> (and (and (block_9_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (summary_3_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_2 state_3) (and (= state_2 (|state_type| (store (|balances| state_1) this_0 (+ (select (|balances| state_1) this_0) funds_2_0)))) (and (and (>= (+ (select (|balances| state_1) this_0) funds_2_0) 0) (<= (+ (select (|balances| state_1) this_0) funds_2_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935)) (and (>= funds_2_0 (|msg.value| tx_0)) (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (and (and (and (and (and (= (|msg.value| tx_0) 0) (= (|msg.sig| tx_0) 638722032)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 0) 38)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 1) 18)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 2) 31)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 3) 240)) (>= (|bytes_tuple_accessor_length| (|msg.data| tx_0)) 4))) (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true))))))) true) (summary_4_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_3))) +) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|)) +(=> (and (and (interface_0_C_16 this_0 abi_0 crypto_0 state_0) true) (and (summary_4_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (= error_0 0))) (interface_0_C_16 this_0 abi_0 crypto_0 state_1))) +) +(declare-fun |contract_initializer_10_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool) +(declare-fun |contract_initializer_entry_11_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|)) +(=> (and (and (= state_1 state_0) (= error_0 0)) true) (contract_initializer_entry_11_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1))) +) +(declare-fun |contract_initializer_after_init_12_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|)) +(=> (and (and (contract_initializer_entry_11_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) true) (contract_initializer_after_init_12_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1))) +) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|)) +(=> (and (and (contract_initializer_after_init_12_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) true) (contract_initializer_10_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1))) +) +(declare-fun |implicit_constructor_entry_13_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|)) +(=> (and (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true) (>= (select (|balances| state_1) this_0) (|msg.value| tx_0))) (implicit_constructor_entry_13_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1))) +) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|)) +(=> (and (and (implicit_constructor_entry_13_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (and (contract_initializer_10_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2) true)) (> error_1 0)) (summary_constructor_2_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_2))) +) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|)) +(=> (and (and (implicit_constructor_entry_13_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (and (= error_1 0) (and (contract_initializer_10_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2) true))) true) (summary_constructor_2_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_2))) +) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|)) +(=> (and (and (summary_constructor_2_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (= (|msg.value| tx_0) 0)) (= error_0 0))) (interface_0_C_16 this_0 abi_0 crypto_0 state_1))) +) (declare-fun |error_target_3| () Bool) -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (interface_0_C_16 this_0 abi_0 crypto_0 state_0) true) (and (summary_4_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (= error_0 1))) error_target_3))) - - - -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|)) +(=> (and (and (interface_0_C_16 this_0 abi_0 crypto_0 state_0) true) (and (summary_4_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (= error_0 1))) error_target_3)) +)(assert +(forall ((UNUSED Bool)) (=> error_target_3 false))) (check-sat) @@ -291,125 +210,85 @@ "message": "CHC: Requested query: (set-option :timeout 1000) (set-logic HORN) -(declare-datatypes ((|bytes_tuple| 0)) (((|bytes_tuple| (|bytes_tuple_accessor_array| (Array Int Int)) (|bytes_tuple_accessor_length| Int))))) -(declare-datatypes ((|tx_type| 0)) (((|tx_type| (|block.basefee| Int) (|block.chainid| Int) (|block.coinbase| Int) (|block.gaslimit| Int) (|block.number| Int) (|block.prevrandao| Int) (|block.timestamp| Int) (|blockhash| (Array Int Int)) (|msg.data| |bytes_tuple|) (|msg.sender| Int) (|msg.sig| Int) (|msg.value| Int) (|tx.gasprice| Int) (|tx.origin| Int))))) +(declare-datatypes ((|abi_type| 0)) (((|abi_type|)))) (declare-datatypes ((|ecrecover_input_type| 0)) (((|ecrecover_input_type| (|hash| Int) (|v| Int) (|r| Int) (|s| Int))))) +(declare-datatypes ((|bytes_tuple| 0)) (((|bytes_tuple| (|bytes_tuple_accessor_array| (Array Int Int)) (|bytes_tuple_accessor_length| Int))))) (declare-datatypes ((|crypto_type| 0)) (((|crypto_type| (|ecrecover| (Array |ecrecover_input_type| Int)) (|keccak256| (Array |bytes_tuple| Int)) (|ripemd160| (Array |bytes_tuple| Int)) (|sha256| (Array |bytes_tuple| Int)))))) -(declare-datatypes ((|abi_type| 0)) (((|abi_type|)))) (declare-datatypes ((|state_type| 0)) (((|state_type| (|balances| (Array Int Int)))))) -(declare-fun |interface_0_C_16| (Int |abi_type| |crypto_type| |state_type| ) Bool) -(declare-fun |nondet_interface_1_C_16| (Int Int |abi_type| |crypto_type| |state_type| |state_type| ) Bool) -(declare-fun |summary_constructor_2_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (this_0 Int) (tx_0 |tx_type|)) -(=> (= error_0 0) (nondet_interface_1_C_16 error_0 this_0 abi_0 crypto_0 state_0 state_0)))) - - -(declare-fun |summary_3_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) -(declare-fun |summary_4_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|)) -(=> (and (and (nondet_interface_1_C_16 error_0 this_0 abi_0 crypto_0 state_0 state_1) true) (and (= error_0 0) (summary_4_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2))) (nondet_interface_1_C_16 error_1 this_0 abi_0 crypto_0 state_0 state_2)))) - - -(declare-fun |block_5_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int ) Bool) -(declare-fun |block_6_f_14_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int ) Bool) -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int)) -(block_5_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1))) - - -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int)) -(=> (and (and (block_5_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true)) true) (block_6_f_14_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1)))) - - -(declare-fun |block_7_return_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int ) Bool) -(declare-fun |block_8_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int ) Bool) -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (block_6_f_14_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (= expr_11_1 (= expr_9_0 expr_10_0)) (and (=> true true) (and (= expr_10_0 0) (and (=> true (and (>= expr_9_0 0) (<= expr_9_0 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (= expr_9_0 x_5_2) (and (= x_5_2 expr_6_0) (and (=> true true) (and (= expr_6_0 0) (and (= x_5_1 0) true)))))))))) (and (and true (not expr_11_1)) (= error_1 1))) (block_8_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_2)))) - - -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (block_8_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_2) (summary_3_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) - - -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (block_6_f_14_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (= error_1 error_0) (and (= expr_11_1 (= expr_9_0 expr_10_0)) (and (=> true true) (and (= expr_10_0 0) (and (=> true (and (>= expr_9_0 0) (<= expr_9_0 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (= expr_9_0 x_5_2) (and (= x_5_2 expr_6_0) (and (=> true true) (and (= expr_6_0 0) (and (= x_5_1 0) true))))))))))) true) (block_7_return_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_2)))) - - -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (block_7_return_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) true) true) (summary_3_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) - - -(declare-fun |block_9_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int ) Bool) -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(block_9_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1))) - - -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (block_9_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (summary_3_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_2 state_3) (and (= state_2 (|state_type| (store (|balances| state_1) this_0 (+ (select (|balances| state_1) this_0) funds_2_0)))) (and (and (>= (+ (select (|balances| state_1) this_0) funds_2_0) 0) (<= (+ (select (|balances| state_1) this_0) funds_2_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935)) (and (>= funds_2_0 (|msg.value| tx_0)) (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (and (and (and (and (and (= (|msg.value| tx_0) 0) (= (|msg.sig| tx_0) 638722032)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 0) 38)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 1) 18)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 2) 31)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 3) 240)) (>= (|bytes_tuple_accessor_length| (|msg.data| tx_0)) 4))) (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true))))))) true) (summary_4_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_3)))) - - -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (interface_0_C_16 this_0 abi_0 crypto_0 state_0) true) (and (summary_4_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (= error_0 0))) (interface_0_C_16 this_0 abi_0 crypto_0 state_1)))) - - -(declare-fun |contract_initializer_10_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) -(declare-fun |contract_initializer_entry_11_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (= state_1 state_0) (= error_0 0)) true) (contract_initializer_entry_11_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) - - -(declare-fun |contract_initializer_after_init_12_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (contract_initializer_entry_11_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) true) (contract_initializer_after_init_12_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) - - -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (contract_initializer_after_init_12_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) true) (contract_initializer_10_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) - - -(declare-fun |implicit_constructor_entry_13_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true) (>= (select (|balances| state_1) this_0) (|msg.value| tx_0))) (implicit_constructor_entry_13_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) - - -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (implicit_constructor_entry_13_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (and (contract_initializer_10_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2) true)) (> error_1 0)) (summary_constructor_2_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_2)))) - - -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (implicit_constructor_entry_13_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (and (= error_1 0) (and (contract_initializer_10_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2) true))) true) (summary_constructor_2_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_2)))) - - -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (summary_constructor_2_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (= (|msg.value| tx_0) 0)) (= error_0 0))) (interface_0_C_16 this_0 abi_0 crypto_0 state_1)))) - - +(declare-fun |interface_0_C_16| (Int |abi_type| |crypto_type| |state_type|) Bool) +(declare-fun |nondet_interface_1_C_16| (Int Int |abi_type| |crypto_type| |state_type| |state_type|) Bool) +(declare-datatypes ((|tx_type| 0)) (((|tx_type| (|block.basefee| Int) (|block.chainid| Int) (|block.coinbase| Int) (|block.gaslimit| Int) (|block.number| Int) (|block.prevrandao| Int) (|block.timestamp| Int) (|blockhash| (Array Int Int)) (|msg.data| |bytes_tuple|) (|msg.sender| Int) (|msg.sig| Int) (|msg.value| Int) (|tx.gasprice| Int) (|tx.origin| Int))))) +(declare-fun |summary_constructor_2_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (this_0 Int)) +(=> (= error_0 0) (nondet_interface_1_C_16 error_0 this_0 abi_0 crypto_0 state_0 state_0))) +) +(declare-fun |summary_3_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool) +(declare-fun |summary_4_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|)) +(=> (and (and (nondet_interface_1_C_16 error_0 this_0 abi_0 crypto_0 state_0 state_1) true) (and (= error_0 0) (summary_4_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2))) (nondet_interface_1_C_16 error_1 this_0 abi_0 crypto_0 state_0 state_2))) +) +(declare-fun |block_5_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int) Bool) +(declare-fun |block_6_f_14_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int) Bool) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_1 Int)) +(block_5_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1)) +) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_1 Int)) +(=> (and (and (block_5_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true)) true) (block_6_f_14_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1))) +) +(declare-fun |block_7_return_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int) Bool) +(declare-fun |block_8_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int) Bool) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_1 Int) (x_5_2 Int)) +(=> (and (and (block_6_f_14_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (= expr_11_1 (= expr_9_0 expr_10_0)) (and (=> true true) (and (= expr_10_0 0) (and (=> true (and (>= expr_9_0 0) (<= expr_9_0 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (= expr_9_0 x_5_2) (and (= x_5_2 expr_6_0) (and (=> true true) (and (= expr_6_0 0) (and (= x_5_1 0) true)))))))))) (and (and true (not expr_11_1)) (= error_1 1))) (block_8_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_2))) +) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_1 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_2 Int)) +(=> (block_8_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_2) (summary_3_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1))) +) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_1 Int) (x_5_2 Int)) +(=> (and (and (block_6_f_14_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (= error_1 error_0) (and (= expr_11_1 (= expr_9_0 expr_10_0)) (and (=> true true) (and (= expr_10_0 0) (and (=> true (and (>= expr_9_0 0) (<= expr_9_0 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (= expr_9_0 x_5_2) (and (= x_5_2 expr_6_0) (and (=> true true) (and (= expr_6_0 0) (and (= x_5_1 0) true))))))))))) true) (block_7_return_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_2))) +) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_1 Int)) +(=> (and (and (block_7_return_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) true) true) (summary_3_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1))) +) +(declare-fun |block_9_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int) Bool) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_1 Int)) +(block_9_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1)) +) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_1 Int)) +(=> (and (and (block_9_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (summary_3_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_2 state_3) (and (= state_2 (|state_type| (store (|balances| state_1) this_0 (+ (select (|balances| state_1) this_0) funds_2_0)))) (and (and (>= (+ (select (|balances| state_1) this_0) funds_2_0) 0) (<= (+ (select (|balances| state_1) this_0) funds_2_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935)) (and (>= funds_2_0 (|msg.value| tx_0)) (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (and (and (and (and (and (= (|msg.value| tx_0) 0) (= (|msg.sig| tx_0) 638722032)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 0) 38)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 1) 18)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 2) 31)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 3) 240)) (>= (|bytes_tuple_accessor_length| (|msg.data| tx_0)) 4))) (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true))))))) true) (summary_4_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_3))) +) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|)) +(=> (and (and (interface_0_C_16 this_0 abi_0 crypto_0 state_0) true) (and (summary_4_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (= error_0 0))) (interface_0_C_16 this_0 abi_0 crypto_0 state_1))) +) +(declare-fun |contract_initializer_10_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool) +(declare-fun |contract_initializer_entry_11_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|)) +(=> (and (and (= state_1 state_0) (= error_0 0)) true) (contract_initializer_entry_11_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1))) +) +(declare-fun |contract_initializer_after_init_12_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|)) +(=> (and (and (contract_initializer_entry_11_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) true) (contract_initializer_after_init_12_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1))) +) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|)) +(=> (and (and (contract_initializer_after_init_12_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) true) (contract_initializer_10_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1))) +) +(declare-fun |implicit_constructor_entry_13_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|)) +(=> (and (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true) (>= (select (|balances| state_1) this_0) (|msg.value| tx_0))) (implicit_constructor_entry_13_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1))) +) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|)) +(=> (and (and (implicit_constructor_entry_13_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (and (contract_initializer_10_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2) true)) (> error_1 0)) (summary_constructor_2_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_2))) +) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|)) +(=> (and (and (implicit_constructor_entry_13_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (and (= error_1 0) (and (contract_initializer_10_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2) true))) true) (summary_constructor_2_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_2))) +) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|)) +(=> (and (and (summary_constructor_2_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (= (|msg.value| tx_0) 0)) (= error_0 0))) (interface_0_C_16 this_0 abi_0 crypto_0 state_1))) +) (declare-fun |error_target_3| () Bool) -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (interface_0_C_16 this_0 abi_0 crypto_0 state_0) true) (and (summary_4_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (= error_0 1))) error_target_3))) - - - -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|)) +(=> (and (and (interface_0_C_16 this_0 abi_0 crypto_0 state_0) true) (and (summary_4_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (= error_0 1))) error_target_3)) +)(assert +(forall ((UNUSED Bool)) (=> error_target_3 false))) (check-sat) ", @@ -463,7 +342,6 @@ (declare-fun |expr_9_0| () Int) (declare-fun |expr_10_0| () Int) (declare-fun |expr_11_1| () Bool) - (assert (and (and (and true true) (and (= expr_11_1 (= expr_9_0 expr_10_0)) (and (=> (and true true) true) (and (= expr_10_0 0) (and (=> (and true true) (and (>= expr_9_0 0) (<= expr_9_0 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (= expr_9_0 x_5_1) (and (ite (and true true) (= x_5_1 expr_6_0) (= x_5_1 x_5_0)) (and (=> (and true true) true) (and (= expr_6_0 0) (and (= x_5_0 0) (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (and (and (and (and (and (= (|msg.value| tx_0) 0) (= (|msg.sig| tx_0) 638722032)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 0) 38)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 1) 18)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 2) 31)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 3) 240)) (>= (|bytes_tuple_accessor_length| (|msg.data| tx_0)) 4))) true))))))))))) (not expr_11_1))) (declare-const |EVALEXPR_0| Int) (assert (= |EVALEXPR_0| x_5_1)) @@ -496,7 +374,6 @@ (declare-fun |expr_9_0| () Int) (declare-fun |expr_10_0| () Int) (declare-fun |expr_11_1| () Bool) - (assert (and (and (and true true) (and (= expr_11_1 (= expr_9_0 expr_10_0)) (and (=> (and true true) true) (and (= expr_10_0 0) (and (=> (and true true) (and (>= expr_9_0 0) (<= expr_9_0 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (= expr_9_0 x_5_1) (and (ite (and true true) (= x_5_1 expr_6_0) (= x_5_1 x_5_0)) (and (=> (and true true) true) (and (= expr_6_0 0) (and (= x_5_0 0) (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (and (and (and (and (and (= (|msg.value| tx_0) 0) (= (|msg.sig| tx_0) 638722032)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 0) 38)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 1) 18)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 2) 31)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 3) 240)) (>= (|bytes_tuple_accessor_length| (|msg.data| tx_0)) 4))) true))))))))))) (not expr_11_1))) (declare-const |EVALEXPR_0| Int) (assert (= |EVALEXPR_0| x_5_1)) diff --git a/test/cmdlineTests/standard_model_checker_print_query_bmc/output.json b/test/cmdlineTests/standard_model_checker_print_query_bmc/output.json index 9fd5f5929adc..cee9d4b9bf9c 100644 --- a/test/cmdlineTests/standard_model_checker_print_query_bmc/output.json +++ b/test/cmdlineTests/standard_model_checker_print_query_bmc/output.json @@ -1,7 +1,7 @@ { "auxiliaryInputRequested": { "smtlib2queries": { - "0x8704a7b848b706ef33cbfc06e4f185636f568a29621126b7244355dd0de956bb": "(set-option :produce-models true) + "0x2bd3d35071b94d7536d10aad691cee810d94841cca10218c3be21255e258aeb7": "(set-option :produce-models true) (set-logic ALL) (declare-fun |error_0| () Int) (declare-fun |this_0| () Int) @@ -21,7 +21,6 @@ (declare-fun |expr_9_0| () Int) (declare-fun |expr_10_0| () Int) (declare-fun |expr_11_1| () Bool) - (assert (and (and (and true true) (and (= expr_11_1 (= expr_9_0 expr_10_0)) (and (=> (and true true) true) (and (= expr_10_0 0) (and (=> (and true true) (and (>= expr_9_0 0) (<= expr_9_0 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (= expr_9_0 x_5_1) (and (ite (and true true) (= x_5_1 expr_6_0) (= x_5_1 x_5_0)) (and (=> (and true true) true) (and (= expr_6_0 0) (and (= x_5_0 0) (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (and (and (and (and (and (= (|msg.value| tx_0) 0) (= (|msg.sig| tx_0) 638722032)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 0) 38)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 1) 18)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 2) 31)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 3) 240)) (>= (|bytes_tuple_accessor_length| (|msg.data| tx_0)) 4))) true))))))))))) (not expr_11_1))) (declare-const |EVALEXPR_0| Int) (assert (= |EVALEXPR_0| x_5_1)) @@ -55,7 +54,6 @@ (declare-fun |expr_9_0| () Int) (declare-fun |expr_10_0| () Int) (declare-fun |expr_11_1| () Bool) - (assert (and (and (and true true) (and (= expr_11_1 (= expr_9_0 expr_10_0)) (and (=> (and true true) true) (and (= expr_10_0 0) (and (=> (and true true) (and (>= expr_9_0 0) (<= expr_9_0 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (= expr_9_0 x_5_1) (and (ite (and true true) (= x_5_1 expr_6_0) (= x_5_1 x_5_0)) (and (=> (and true true) true) (and (= expr_6_0 0) (and (= x_5_0 0) (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (and (and (and (and (and (= (|msg.value| tx_0) 0) (= (|msg.sig| tx_0) 638722032)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 0) 38)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 1) 18)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 2) 31)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 3) 240)) (>= (|bytes_tuple_accessor_length| (|msg.data| tx_0)) 4))) true))))))))))) (not expr_11_1))) (declare-const |EVALEXPR_0| Int) (assert (= |EVALEXPR_0| x_5_1)) @@ -85,7 +83,6 @@ (declare-fun |expr_9_0| () Int) (declare-fun |expr_10_0| () Int) (declare-fun |expr_11_1| () Bool) - (assert (and (and (and true true) (and (= expr_11_1 (= expr_9_0 expr_10_0)) (and (=> (and true true) true) (and (= expr_10_0 0) (and (=> (and true true) (and (>= expr_9_0 0) (<= expr_9_0 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (= expr_9_0 x_5_1) (and (ite (and true true) (= x_5_1 expr_6_0) (= x_5_1 x_5_0)) (and (=> (and true true) true) (and (= expr_6_0 0) (and (= x_5_0 0) (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (and (and (and (and (and (= (|msg.value| tx_0) 0) (= (|msg.sig| tx_0) 638722032)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 0) 38)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 1) 18)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 2) 31)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 3) 240)) (>= (|bytes_tuple_accessor_length| (|msg.data| tx_0)) 4))) true))))))))))) (not expr_11_1))) (declare-const |EVALEXPR_0| Int) (assert (= |EVALEXPR_0| x_5_1)) diff --git a/test/cmdlineTests/standard_model_checker_print_query_chc/output.json b/test/cmdlineTests/standard_model_checker_print_query_chc/output.json index a9956d82b0e3..9553a3cfb662 100644 --- a/test/cmdlineTests/standard_model_checker_print_query_chc/output.json +++ b/test/cmdlineTests/standard_model_checker_print_query_chc/output.json @@ -1,127 +1,87 @@ { "auxiliaryInputRequested": { "smtlib2queries": { - "0xcbd85fe3127d1edfce70355ba6da5a3e9573873d8596ee8b1cfc2222af166628": "(set-option :timeout 1000) + "0x9cfcd53712a0be144c8e7983b3635498ead1af2624885fb89762eae8c43233e5": "(set-option :timeout 1000) (set-logic HORN) -(declare-datatypes ((|bytes_tuple| 0)) (((|bytes_tuple| (|bytes_tuple_accessor_array| (Array Int Int)) (|bytes_tuple_accessor_length| Int))))) -(declare-datatypes ((|tx_type| 0)) (((|tx_type| (|block.basefee| Int) (|block.chainid| Int) (|block.coinbase| Int) (|block.gaslimit| Int) (|block.number| Int) (|block.prevrandao| Int) (|block.timestamp| Int) (|blockhash| (Array Int Int)) (|msg.data| |bytes_tuple|) (|msg.sender| Int) (|msg.sig| Int) (|msg.value| Int) (|tx.gasprice| Int) (|tx.origin| Int))))) +(declare-datatypes ((|abi_type| 0)) (((|abi_type|)))) (declare-datatypes ((|ecrecover_input_type| 0)) (((|ecrecover_input_type| (|hash| Int) (|v| Int) (|r| Int) (|s| Int))))) +(declare-datatypes ((|bytes_tuple| 0)) (((|bytes_tuple| (|bytes_tuple_accessor_array| (Array Int Int)) (|bytes_tuple_accessor_length| Int))))) (declare-datatypes ((|crypto_type| 0)) (((|crypto_type| (|ecrecover| (Array |ecrecover_input_type| Int)) (|keccak256| (Array |bytes_tuple| Int)) (|ripemd160| (Array |bytes_tuple| Int)) (|sha256| (Array |bytes_tuple| Int)))))) -(declare-datatypes ((|abi_type| 0)) (((|abi_type|)))) (declare-datatypes ((|state_type| 0)) (((|state_type| (|balances| (Array Int Int)))))) -(declare-fun |interface_0_C_16| (Int |abi_type| |crypto_type| |state_type| ) Bool) -(declare-fun |nondet_interface_1_C_16| (Int Int |abi_type| |crypto_type| |state_type| |state_type| ) Bool) -(declare-fun |summary_constructor_2_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (this_0 Int) (tx_0 |tx_type|)) -(=> (= error_0 0) (nondet_interface_1_C_16 error_0 this_0 abi_0 crypto_0 state_0 state_0)))) - - -(declare-fun |summary_3_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) -(declare-fun |summary_4_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|)) -(=> (and (and (nondet_interface_1_C_16 error_0 this_0 abi_0 crypto_0 state_0 state_1) true) (and (= error_0 0) (summary_4_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2))) (nondet_interface_1_C_16 error_1 this_0 abi_0 crypto_0 state_0 state_2)))) - - -(declare-fun |block_5_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int ) Bool) -(declare-fun |block_6_f_14_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int ) Bool) -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int)) -(block_5_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1))) - - -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int)) -(=> (and (and (block_5_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true)) true) (block_6_f_14_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1)))) - - -(declare-fun |block_7_return_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int ) Bool) -(declare-fun |block_8_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int ) Bool) -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (block_6_f_14_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (= expr_11_1 (= expr_9_0 expr_10_0)) (and (=> true true) (and (= expr_10_0 0) (and (=> true (and (>= expr_9_0 0) (<= expr_9_0 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (= expr_9_0 x_5_2) (and (= x_5_2 expr_6_0) (and (=> true true) (and (= expr_6_0 0) (and (= x_5_1 0) true)))))))))) (and (and true (not expr_11_1)) (= error_1 1))) (block_8_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_2)))) - - -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (block_8_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_2) (summary_3_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) - - -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (block_6_f_14_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (= error_1 error_0) (and (= expr_11_1 (= expr_9_0 expr_10_0)) (and (=> true true) (and (= expr_10_0 0) (and (=> true (and (>= expr_9_0 0) (<= expr_9_0 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (= expr_9_0 x_5_2) (and (= x_5_2 expr_6_0) (and (=> true true) (and (= expr_6_0 0) (and (= x_5_1 0) true))))))))))) true) (block_7_return_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_2)))) - - -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (block_7_return_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) true) true) (summary_3_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) - - -(declare-fun |block_9_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int ) Bool) -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(block_9_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1))) - - -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (block_9_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (summary_3_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_2 state_3) (and (= state_2 (|state_type| (store (|balances| state_1) this_0 (+ (select (|balances| state_1) this_0) funds_2_0)))) (and (and (>= (+ (select (|balances| state_1) this_0) funds_2_0) 0) (<= (+ (select (|balances| state_1) this_0) funds_2_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935)) (and (>= funds_2_0 (|msg.value| tx_0)) (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (and (and (and (and (and (= (|msg.value| tx_0) 0) (= (|msg.sig| tx_0) 638722032)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 0) 38)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 1) 18)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 2) 31)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 3) 240)) (>= (|bytes_tuple_accessor_length| (|msg.data| tx_0)) 4))) (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true))))))) true) (summary_4_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_3)))) - - -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (interface_0_C_16 this_0 abi_0 crypto_0 state_0) true) (and (summary_4_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (= error_0 0))) (interface_0_C_16 this_0 abi_0 crypto_0 state_1)))) - - -(declare-fun |contract_initializer_10_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) -(declare-fun |contract_initializer_entry_11_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (= state_1 state_0) (= error_0 0)) true) (contract_initializer_entry_11_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) - - -(declare-fun |contract_initializer_after_init_12_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (contract_initializer_entry_11_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) true) (contract_initializer_after_init_12_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) - - -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (contract_initializer_after_init_12_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) true) (contract_initializer_10_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) - - -(declare-fun |implicit_constructor_entry_13_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true) (>= (select (|balances| state_1) this_0) (|msg.value| tx_0))) (implicit_constructor_entry_13_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) - - -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (implicit_constructor_entry_13_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (and (contract_initializer_10_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2) true)) (> error_1 0)) (summary_constructor_2_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_2)))) - - -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (implicit_constructor_entry_13_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (and (= error_1 0) (and (contract_initializer_10_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2) true))) true) (summary_constructor_2_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_2)))) - - -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (summary_constructor_2_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (= (|msg.value| tx_0) 0)) (= error_0 0))) (interface_0_C_16 this_0 abi_0 crypto_0 state_1)))) - - +(declare-fun |interface_0_C_16| (Int |abi_type| |crypto_type| |state_type|) Bool) +(declare-fun |nondet_interface_1_C_16| (Int Int |abi_type| |crypto_type| |state_type| |state_type|) Bool) +(declare-datatypes ((|tx_type| 0)) (((|tx_type| (|block.basefee| Int) (|block.chainid| Int) (|block.coinbase| Int) (|block.gaslimit| Int) (|block.number| Int) (|block.prevrandao| Int) (|block.timestamp| Int) (|blockhash| (Array Int Int)) (|msg.data| |bytes_tuple|) (|msg.sender| Int) (|msg.sig| Int) (|msg.value| Int) (|tx.gasprice| Int) (|tx.origin| Int))))) +(declare-fun |summary_constructor_2_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (this_0 Int)) +(=> (= error_0 0) (nondet_interface_1_C_16 error_0 this_0 abi_0 crypto_0 state_0 state_0))) +) +(declare-fun |summary_3_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool) +(declare-fun |summary_4_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|)) +(=> (and (and (nondet_interface_1_C_16 error_0 this_0 abi_0 crypto_0 state_0 state_1) true) (and (= error_0 0) (summary_4_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2))) (nondet_interface_1_C_16 error_1 this_0 abi_0 crypto_0 state_0 state_2))) +) +(declare-fun |block_5_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int) Bool) +(declare-fun |block_6_f_14_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int) Bool) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_1 Int)) +(block_5_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1)) +) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_1 Int)) +(=> (and (and (block_5_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true)) true) (block_6_f_14_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1))) +) +(declare-fun |block_7_return_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int) Bool) +(declare-fun |block_8_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int) Bool) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_1 Int) (x_5_2 Int)) +(=> (and (and (block_6_f_14_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (= expr_11_1 (= expr_9_0 expr_10_0)) (and (=> true true) (and (= expr_10_0 0) (and (=> true (and (>= expr_9_0 0) (<= expr_9_0 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (= expr_9_0 x_5_2) (and (= x_5_2 expr_6_0) (and (=> true true) (and (= expr_6_0 0) (and (= x_5_1 0) true)))))))))) (and (and true (not expr_11_1)) (= error_1 1))) (block_8_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_2))) +) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_1 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_2 Int)) +(=> (block_8_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_2) (summary_3_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1))) +) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_1 Int) (x_5_2 Int)) +(=> (and (and (block_6_f_14_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (= error_1 error_0) (and (= expr_11_1 (= expr_9_0 expr_10_0)) (and (=> true true) (and (= expr_10_0 0) (and (=> true (and (>= expr_9_0 0) (<= expr_9_0 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (= expr_9_0 x_5_2) (and (= x_5_2 expr_6_0) (and (=> true true) (and (= expr_6_0 0) (and (= x_5_1 0) true))))))))))) true) (block_7_return_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_2))) +) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_1 Int)) +(=> (and (and (block_7_return_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) true) true) (summary_3_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1))) +) +(declare-fun |block_9_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int) Bool) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_1 Int)) +(block_9_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1)) +) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_1 Int)) +(=> (and (and (block_9_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (summary_3_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_2 state_3) (and (= state_2 (|state_type| (store (|balances| state_1) this_0 (+ (select (|balances| state_1) this_0) funds_2_0)))) (and (and (>= (+ (select (|balances| state_1) this_0) funds_2_0) 0) (<= (+ (select (|balances| state_1) this_0) funds_2_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935)) (and (>= funds_2_0 (|msg.value| tx_0)) (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (and (and (and (and (and (= (|msg.value| tx_0) 0) (= (|msg.sig| tx_0) 638722032)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 0) 38)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 1) 18)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 2) 31)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 3) 240)) (>= (|bytes_tuple_accessor_length| (|msg.data| tx_0)) 4))) (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true))))))) true) (summary_4_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_3))) +) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|)) +(=> (and (and (interface_0_C_16 this_0 abi_0 crypto_0 state_0) true) (and (summary_4_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (= error_0 0))) (interface_0_C_16 this_0 abi_0 crypto_0 state_1))) +) +(declare-fun |contract_initializer_10_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool) +(declare-fun |contract_initializer_entry_11_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|)) +(=> (and (and (= state_1 state_0) (= error_0 0)) true) (contract_initializer_entry_11_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1))) +) +(declare-fun |contract_initializer_after_init_12_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|)) +(=> (and (and (contract_initializer_entry_11_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) true) (contract_initializer_after_init_12_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1))) +) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|)) +(=> (and (and (contract_initializer_after_init_12_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) true) (contract_initializer_10_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1))) +) +(declare-fun |implicit_constructor_entry_13_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|)) +(=> (and (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true) (>= (select (|balances| state_1) this_0) (|msg.value| tx_0))) (implicit_constructor_entry_13_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1))) +) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|)) +(=> (and (and (implicit_constructor_entry_13_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (and (contract_initializer_10_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2) true)) (> error_1 0)) (summary_constructor_2_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_2))) +) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|)) +(=> (and (and (implicit_constructor_entry_13_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (and (= error_1 0) (and (contract_initializer_10_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2) true))) true) (summary_constructor_2_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_2))) +) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|)) +(=> (and (and (summary_constructor_2_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (= (|msg.value| tx_0) 0)) (= error_0 0))) (interface_0_C_16 this_0 abi_0 crypto_0 state_1))) +) (declare-fun |error_target_3| () Bool) -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (interface_0_C_16 this_0 abi_0 crypto_0 state_0) true) (and (summary_4_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (= error_0 1))) error_target_3))) - - - -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|)) +(=> (and (and (interface_0_C_16 this_0 abi_0 crypto_0 state_0) true) (and (summary_4_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (= error_0 1))) error_target_3)) +)(assert +(forall ((UNUSED Bool)) (=> error_target_3 false))) (check-sat) " @@ -134,125 +94,85 @@ "formattedMessage": "Info: CHC: Requested query: (set-option :timeout 1000) (set-logic HORN) -(declare-datatypes ((|bytes_tuple| 0)) (((|bytes_tuple| (|bytes_tuple_accessor_array| (Array Int Int)) (|bytes_tuple_accessor_length| Int))))) -(declare-datatypes ((|tx_type| 0)) (((|tx_type| (|block.basefee| Int) (|block.chainid| Int) (|block.coinbase| Int) (|block.gaslimit| Int) (|block.number| Int) (|block.prevrandao| Int) (|block.timestamp| Int) (|blockhash| (Array Int Int)) (|msg.data| |bytes_tuple|) (|msg.sender| Int) (|msg.sig| Int) (|msg.value| Int) (|tx.gasprice| Int) (|tx.origin| Int))))) +(declare-datatypes ((|abi_type| 0)) (((|abi_type|)))) (declare-datatypes ((|ecrecover_input_type| 0)) (((|ecrecover_input_type| (|hash| Int) (|v| Int) (|r| Int) (|s| Int))))) +(declare-datatypes ((|bytes_tuple| 0)) (((|bytes_tuple| (|bytes_tuple_accessor_array| (Array Int Int)) (|bytes_tuple_accessor_length| Int))))) (declare-datatypes ((|crypto_type| 0)) (((|crypto_type| (|ecrecover| (Array |ecrecover_input_type| Int)) (|keccak256| (Array |bytes_tuple| Int)) (|ripemd160| (Array |bytes_tuple| Int)) (|sha256| (Array |bytes_tuple| Int)))))) -(declare-datatypes ((|abi_type| 0)) (((|abi_type|)))) (declare-datatypes ((|state_type| 0)) (((|state_type| (|balances| (Array Int Int)))))) -(declare-fun |interface_0_C_16| (Int |abi_type| |crypto_type| |state_type| ) Bool) -(declare-fun |nondet_interface_1_C_16| (Int Int |abi_type| |crypto_type| |state_type| |state_type| ) Bool) -(declare-fun |summary_constructor_2_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (this_0 Int) (tx_0 |tx_type|)) -(=> (= error_0 0) (nondet_interface_1_C_16 error_0 this_0 abi_0 crypto_0 state_0 state_0)))) - - -(declare-fun |summary_3_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) -(declare-fun |summary_4_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|)) -(=> (and (and (nondet_interface_1_C_16 error_0 this_0 abi_0 crypto_0 state_0 state_1) true) (and (= error_0 0) (summary_4_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2))) (nondet_interface_1_C_16 error_1 this_0 abi_0 crypto_0 state_0 state_2)))) - - -(declare-fun |block_5_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int ) Bool) -(declare-fun |block_6_f_14_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int ) Bool) -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int)) -(block_5_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1))) - - -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int)) -(=> (and (and (block_5_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true)) true) (block_6_f_14_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1)))) - - -(declare-fun |block_7_return_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int ) Bool) -(declare-fun |block_8_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int ) Bool) -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (block_6_f_14_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (= expr_11_1 (= expr_9_0 expr_10_0)) (and (=> true true) (and (= expr_10_0 0) (and (=> true (and (>= expr_9_0 0) (<= expr_9_0 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (= expr_9_0 x_5_2) (and (= x_5_2 expr_6_0) (and (=> true true) (and (= expr_6_0 0) (and (= x_5_1 0) true)))))))))) (and (and true (not expr_11_1)) (= error_1 1))) (block_8_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_2)))) - - -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (block_8_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_2) (summary_3_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) - - -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (block_6_f_14_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (= error_1 error_0) (and (= expr_11_1 (= expr_9_0 expr_10_0)) (and (=> true true) (and (= expr_10_0 0) (and (=> true (and (>= expr_9_0 0) (<= expr_9_0 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (= expr_9_0 x_5_2) (and (= x_5_2 expr_6_0) (and (=> true true) (and (= expr_6_0 0) (and (= x_5_1 0) true))))))))))) true) (block_7_return_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_2)))) - - -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (block_7_return_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) true) true) (summary_3_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) - - -(declare-fun |block_9_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int ) Bool) -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(block_9_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1))) - - -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (block_9_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (summary_3_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_2 state_3) (and (= state_2 (|state_type| (store (|balances| state_1) this_0 (+ (select (|balances| state_1) this_0) funds_2_0)))) (and (and (>= (+ (select (|balances| state_1) this_0) funds_2_0) 0) (<= (+ (select (|balances| state_1) this_0) funds_2_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935)) (and (>= funds_2_0 (|msg.value| tx_0)) (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (and (and (and (and (and (= (|msg.value| tx_0) 0) (= (|msg.sig| tx_0) 638722032)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 0) 38)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 1) 18)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 2) 31)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 3) 240)) (>= (|bytes_tuple_accessor_length| (|msg.data| tx_0)) 4))) (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true))))))) true) (summary_4_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_3)))) - - -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (interface_0_C_16 this_0 abi_0 crypto_0 state_0) true) (and (summary_4_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (= error_0 0))) (interface_0_C_16 this_0 abi_0 crypto_0 state_1)))) - - -(declare-fun |contract_initializer_10_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) -(declare-fun |contract_initializer_entry_11_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (= state_1 state_0) (= error_0 0)) true) (contract_initializer_entry_11_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) - - -(declare-fun |contract_initializer_after_init_12_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (contract_initializer_entry_11_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) true) (contract_initializer_after_init_12_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) - - -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (contract_initializer_after_init_12_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) true) (contract_initializer_10_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) - - -(declare-fun |implicit_constructor_entry_13_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true) (>= (select (|balances| state_1) this_0) (|msg.value| tx_0))) (implicit_constructor_entry_13_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) - - -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (implicit_constructor_entry_13_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (and (contract_initializer_10_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2) true)) (> error_1 0)) (summary_constructor_2_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_2)))) - - -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (implicit_constructor_entry_13_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (and (= error_1 0) (and (contract_initializer_10_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2) true))) true) (summary_constructor_2_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_2)))) - - -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (summary_constructor_2_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (= (|msg.value| tx_0) 0)) (= error_0 0))) (interface_0_C_16 this_0 abi_0 crypto_0 state_1)))) - - +(declare-fun |interface_0_C_16| (Int |abi_type| |crypto_type| |state_type|) Bool) +(declare-fun |nondet_interface_1_C_16| (Int Int |abi_type| |crypto_type| |state_type| |state_type|) Bool) +(declare-datatypes ((|tx_type| 0)) (((|tx_type| (|block.basefee| Int) (|block.chainid| Int) (|block.coinbase| Int) (|block.gaslimit| Int) (|block.number| Int) (|block.prevrandao| Int) (|block.timestamp| Int) (|blockhash| (Array Int Int)) (|msg.data| |bytes_tuple|) (|msg.sender| Int) (|msg.sig| Int) (|msg.value| Int) (|tx.gasprice| Int) (|tx.origin| Int))))) +(declare-fun |summary_constructor_2_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (this_0 Int)) +(=> (= error_0 0) (nondet_interface_1_C_16 error_0 this_0 abi_0 crypto_0 state_0 state_0))) +) +(declare-fun |summary_3_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool) +(declare-fun |summary_4_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|)) +(=> (and (and (nondet_interface_1_C_16 error_0 this_0 abi_0 crypto_0 state_0 state_1) true) (and (= error_0 0) (summary_4_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2))) (nondet_interface_1_C_16 error_1 this_0 abi_0 crypto_0 state_0 state_2))) +) +(declare-fun |block_5_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int) Bool) +(declare-fun |block_6_f_14_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int) Bool) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_1 Int)) +(block_5_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1)) +) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_1 Int)) +(=> (and (and (block_5_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true)) true) (block_6_f_14_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1))) +) +(declare-fun |block_7_return_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int) Bool) +(declare-fun |block_8_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int) Bool) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_1 Int) (x_5_2 Int)) +(=> (and (and (block_6_f_14_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (= expr_11_1 (= expr_9_0 expr_10_0)) (and (=> true true) (and (= expr_10_0 0) (and (=> true (and (>= expr_9_0 0) (<= expr_9_0 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (= expr_9_0 x_5_2) (and (= x_5_2 expr_6_0) (and (=> true true) (and (= expr_6_0 0) (and (= x_5_1 0) true)))))))))) (and (and true (not expr_11_1)) (= error_1 1))) (block_8_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_2))) +) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_1 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_2 Int)) +(=> (block_8_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_2) (summary_3_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1))) +) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_1 Int) (x_5_2 Int)) +(=> (and (and (block_6_f_14_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (= error_1 error_0) (and (= expr_11_1 (= expr_9_0 expr_10_0)) (and (=> true true) (and (= expr_10_0 0) (and (=> true (and (>= expr_9_0 0) (<= expr_9_0 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (= expr_9_0 x_5_2) (and (= x_5_2 expr_6_0) (and (=> true true) (and (= expr_6_0 0) (and (= x_5_1 0) true))))))))))) true) (block_7_return_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_2))) +) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_1 Int)) +(=> (and (and (block_7_return_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) true) true) (summary_3_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1))) +) +(declare-fun |block_9_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int) Bool) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_1 Int)) +(block_9_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1)) +) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_1 Int)) +(=> (and (and (block_9_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (summary_3_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_2 state_3) (and (= state_2 (|state_type| (store (|balances| state_1) this_0 (+ (select (|balances| state_1) this_0) funds_2_0)))) (and (and (>= (+ (select (|balances| state_1) this_0) funds_2_0) 0) (<= (+ (select (|balances| state_1) this_0) funds_2_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935)) (and (>= funds_2_0 (|msg.value| tx_0)) (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (and (and (and (and (and (= (|msg.value| tx_0) 0) (= (|msg.sig| tx_0) 638722032)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 0) 38)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 1) 18)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 2) 31)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 3) 240)) (>= (|bytes_tuple_accessor_length| (|msg.data| tx_0)) 4))) (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true))))))) true) (summary_4_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_3))) +) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|)) +(=> (and (and (interface_0_C_16 this_0 abi_0 crypto_0 state_0) true) (and (summary_4_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (= error_0 0))) (interface_0_C_16 this_0 abi_0 crypto_0 state_1))) +) +(declare-fun |contract_initializer_10_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool) +(declare-fun |contract_initializer_entry_11_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|)) +(=> (and (and (= state_1 state_0) (= error_0 0)) true) (contract_initializer_entry_11_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1))) +) +(declare-fun |contract_initializer_after_init_12_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|)) +(=> (and (and (contract_initializer_entry_11_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) true) (contract_initializer_after_init_12_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1))) +) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|)) +(=> (and (and (contract_initializer_after_init_12_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) true) (contract_initializer_10_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1))) +) +(declare-fun |implicit_constructor_entry_13_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|)) +(=> (and (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true) (>= (select (|balances| state_1) this_0) (|msg.value| tx_0))) (implicit_constructor_entry_13_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1))) +) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|)) +(=> (and (and (implicit_constructor_entry_13_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (and (contract_initializer_10_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2) true)) (> error_1 0)) (summary_constructor_2_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_2))) +) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|)) +(=> (and (and (implicit_constructor_entry_13_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (and (= error_1 0) (and (contract_initializer_10_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2) true))) true) (summary_constructor_2_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_2))) +) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|)) +(=> (and (and (summary_constructor_2_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (= (|msg.value| tx_0) 0)) (= error_0 0))) (interface_0_C_16 this_0 abi_0 crypto_0 state_1))) +) (declare-fun |error_target_3| () Bool) -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (interface_0_C_16 this_0 abi_0 crypto_0 state_0) true) (and (summary_4_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (= error_0 1))) error_target_3))) - - - -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|)) +(=> (and (and (interface_0_C_16 this_0 abi_0 crypto_0 state_0) true) (and (summary_4_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (= error_0 1))) error_target_3)) +)(assert +(forall ((UNUSED Bool)) (=> error_target_3 false))) (check-sat) @@ -261,125 +181,85 @@ "message": "CHC: Requested query: (set-option :timeout 1000) (set-logic HORN) -(declare-datatypes ((|bytes_tuple| 0)) (((|bytes_tuple| (|bytes_tuple_accessor_array| (Array Int Int)) (|bytes_tuple_accessor_length| Int))))) -(declare-datatypes ((|tx_type| 0)) (((|tx_type| (|block.basefee| Int) (|block.chainid| Int) (|block.coinbase| Int) (|block.gaslimit| Int) (|block.number| Int) (|block.prevrandao| Int) (|block.timestamp| Int) (|blockhash| (Array Int Int)) (|msg.data| |bytes_tuple|) (|msg.sender| Int) (|msg.sig| Int) (|msg.value| Int) (|tx.gasprice| Int) (|tx.origin| Int))))) +(declare-datatypes ((|abi_type| 0)) (((|abi_type|)))) (declare-datatypes ((|ecrecover_input_type| 0)) (((|ecrecover_input_type| (|hash| Int) (|v| Int) (|r| Int) (|s| Int))))) +(declare-datatypes ((|bytes_tuple| 0)) (((|bytes_tuple| (|bytes_tuple_accessor_array| (Array Int Int)) (|bytes_tuple_accessor_length| Int))))) (declare-datatypes ((|crypto_type| 0)) (((|crypto_type| (|ecrecover| (Array |ecrecover_input_type| Int)) (|keccak256| (Array |bytes_tuple| Int)) (|ripemd160| (Array |bytes_tuple| Int)) (|sha256| (Array |bytes_tuple| Int)))))) -(declare-datatypes ((|abi_type| 0)) (((|abi_type|)))) (declare-datatypes ((|state_type| 0)) (((|state_type| (|balances| (Array Int Int)))))) -(declare-fun |interface_0_C_16| (Int |abi_type| |crypto_type| |state_type| ) Bool) -(declare-fun |nondet_interface_1_C_16| (Int Int |abi_type| |crypto_type| |state_type| |state_type| ) Bool) -(declare-fun |summary_constructor_2_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (this_0 Int) (tx_0 |tx_type|)) -(=> (= error_0 0) (nondet_interface_1_C_16 error_0 this_0 abi_0 crypto_0 state_0 state_0)))) - - -(declare-fun |summary_3_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) -(declare-fun |summary_4_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|)) -(=> (and (and (nondet_interface_1_C_16 error_0 this_0 abi_0 crypto_0 state_0 state_1) true) (and (= error_0 0) (summary_4_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2))) (nondet_interface_1_C_16 error_1 this_0 abi_0 crypto_0 state_0 state_2)))) - - -(declare-fun |block_5_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int ) Bool) -(declare-fun |block_6_f_14_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int ) Bool) -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int)) -(block_5_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1))) - - -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int)) -(=> (and (and (block_5_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true)) true) (block_6_f_14_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1)))) - - -(declare-fun |block_7_return_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int ) Bool) -(declare-fun |block_8_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int ) Bool) -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (block_6_f_14_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (= expr_11_1 (= expr_9_0 expr_10_0)) (and (=> true true) (and (= expr_10_0 0) (and (=> true (and (>= expr_9_0 0) (<= expr_9_0 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (= expr_9_0 x_5_2) (and (= x_5_2 expr_6_0) (and (=> true true) (and (= expr_6_0 0) (and (= x_5_1 0) true)))))))))) (and (and true (not expr_11_1)) (= error_1 1))) (block_8_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_2)))) - - -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (block_8_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_2) (summary_3_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) - - -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (block_6_f_14_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (= error_1 error_0) (and (= expr_11_1 (= expr_9_0 expr_10_0)) (and (=> true true) (and (= expr_10_0 0) (and (=> true (and (>= expr_9_0 0) (<= expr_9_0 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (= expr_9_0 x_5_2) (and (= x_5_2 expr_6_0) (and (=> true true) (and (= expr_6_0 0) (and (= x_5_1 0) true))))))))))) true) (block_7_return_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_2)))) - - -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (block_7_return_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) true) true) (summary_3_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) - - -(declare-fun |block_9_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int ) Bool) -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(block_9_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1))) - - -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (block_9_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (summary_3_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_2 state_3) (and (= state_2 (|state_type| (store (|balances| state_1) this_0 (+ (select (|balances| state_1) this_0) funds_2_0)))) (and (and (>= (+ (select (|balances| state_1) this_0) funds_2_0) 0) (<= (+ (select (|balances| state_1) this_0) funds_2_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935)) (and (>= funds_2_0 (|msg.value| tx_0)) (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (and (and (and (and (and (= (|msg.value| tx_0) 0) (= (|msg.sig| tx_0) 638722032)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 0) 38)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 1) 18)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 2) 31)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 3) 240)) (>= (|bytes_tuple_accessor_length| (|msg.data| tx_0)) 4))) (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true))))))) true) (summary_4_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_3)))) - - -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (interface_0_C_16 this_0 abi_0 crypto_0 state_0) true) (and (summary_4_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (= error_0 0))) (interface_0_C_16 this_0 abi_0 crypto_0 state_1)))) - - -(declare-fun |contract_initializer_10_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) -(declare-fun |contract_initializer_entry_11_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (= state_1 state_0) (= error_0 0)) true) (contract_initializer_entry_11_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) - - -(declare-fun |contract_initializer_after_init_12_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (contract_initializer_entry_11_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) true) (contract_initializer_after_init_12_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) - - -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (contract_initializer_after_init_12_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) true) (contract_initializer_10_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) - - -(declare-fun |implicit_constructor_entry_13_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true) (>= (select (|balances| state_1) this_0) (|msg.value| tx_0))) (implicit_constructor_entry_13_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) - - -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (implicit_constructor_entry_13_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (and (contract_initializer_10_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2) true)) (> error_1 0)) (summary_constructor_2_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_2)))) - - -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (implicit_constructor_entry_13_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (and (= error_1 0) (and (contract_initializer_10_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2) true))) true) (summary_constructor_2_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_2)))) - - -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (summary_constructor_2_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (= (|msg.value| tx_0) 0)) (= error_0 0))) (interface_0_C_16 this_0 abi_0 crypto_0 state_1)))) - - +(declare-fun |interface_0_C_16| (Int |abi_type| |crypto_type| |state_type|) Bool) +(declare-fun |nondet_interface_1_C_16| (Int Int |abi_type| |crypto_type| |state_type| |state_type|) Bool) +(declare-datatypes ((|tx_type| 0)) (((|tx_type| (|block.basefee| Int) (|block.chainid| Int) (|block.coinbase| Int) (|block.gaslimit| Int) (|block.number| Int) (|block.prevrandao| Int) (|block.timestamp| Int) (|blockhash| (Array Int Int)) (|msg.data| |bytes_tuple|) (|msg.sender| Int) (|msg.sig| Int) (|msg.value| Int) (|tx.gasprice| Int) (|tx.origin| Int))))) +(declare-fun |summary_constructor_2_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (this_0 Int)) +(=> (= error_0 0) (nondet_interface_1_C_16 error_0 this_0 abi_0 crypto_0 state_0 state_0))) +) +(declare-fun |summary_3_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool) +(declare-fun |summary_4_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|)) +(=> (and (and (nondet_interface_1_C_16 error_0 this_0 abi_0 crypto_0 state_0 state_1) true) (and (= error_0 0) (summary_4_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2))) (nondet_interface_1_C_16 error_1 this_0 abi_0 crypto_0 state_0 state_2))) +) +(declare-fun |block_5_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int) Bool) +(declare-fun |block_6_f_14_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int) Bool) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_1 Int)) +(block_5_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1)) +) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_1 Int)) +(=> (and (and (block_5_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true)) true) (block_6_f_14_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1))) +) +(declare-fun |block_7_return_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int) Bool) +(declare-fun |block_8_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int) Bool) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_1 Int) (x_5_2 Int)) +(=> (and (and (block_6_f_14_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (= expr_11_1 (= expr_9_0 expr_10_0)) (and (=> true true) (and (= expr_10_0 0) (and (=> true (and (>= expr_9_0 0) (<= expr_9_0 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (= expr_9_0 x_5_2) (and (= x_5_2 expr_6_0) (and (=> true true) (and (= expr_6_0 0) (and (= x_5_1 0) true)))))))))) (and (and true (not expr_11_1)) (= error_1 1))) (block_8_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_2))) +) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_1 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_2 Int)) +(=> (block_8_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_2) (summary_3_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1))) +) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_1 Int) (x_5_2 Int)) +(=> (and (and (block_6_f_14_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (= error_1 error_0) (and (= expr_11_1 (= expr_9_0 expr_10_0)) (and (=> true true) (and (= expr_10_0 0) (and (=> true (and (>= expr_9_0 0) (<= expr_9_0 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (= expr_9_0 x_5_2) (and (= x_5_2 expr_6_0) (and (=> true true) (and (= expr_6_0 0) (and (= x_5_1 0) true))))))))))) true) (block_7_return_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_2))) +) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_1 Int)) +(=> (and (and (block_7_return_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) true) true) (summary_3_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1))) +) +(declare-fun |block_9_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int) Bool) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_1 Int)) +(block_9_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1)) +) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_1 Int)) +(=> (and (and (block_9_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (summary_3_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_2 state_3) (and (= state_2 (|state_type| (store (|balances| state_1) this_0 (+ (select (|balances| state_1) this_0) funds_2_0)))) (and (and (>= (+ (select (|balances| state_1) this_0) funds_2_0) 0) (<= (+ (select (|balances| state_1) this_0) funds_2_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935)) (and (>= funds_2_0 (|msg.value| tx_0)) (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (and (and (and (and (and (= (|msg.value| tx_0) 0) (= (|msg.sig| tx_0) 638722032)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 0) 38)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 1) 18)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 2) 31)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 3) 240)) (>= (|bytes_tuple_accessor_length| (|msg.data| tx_0)) 4))) (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true))))))) true) (summary_4_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_3))) +) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|)) +(=> (and (and (interface_0_C_16 this_0 abi_0 crypto_0 state_0) true) (and (summary_4_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (= error_0 0))) (interface_0_C_16 this_0 abi_0 crypto_0 state_1))) +) +(declare-fun |contract_initializer_10_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool) +(declare-fun |contract_initializer_entry_11_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|)) +(=> (and (and (= state_1 state_0) (= error_0 0)) true) (contract_initializer_entry_11_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1))) +) +(declare-fun |contract_initializer_after_init_12_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|)) +(=> (and (and (contract_initializer_entry_11_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) true) (contract_initializer_after_init_12_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1))) +) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|)) +(=> (and (and (contract_initializer_after_init_12_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) true) (contract_initializer_10_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1))) +) +(declare-fun |implicit_constructor_entry_13_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|)) +(=> (and (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true) (>= (select (|balances| state_1) this_0) (|msg.value| tx_0))) (implicit_constructor_entry_13_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1))) +) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|)) +(=> (and (and (implicit_constructor_entry_13_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (and (contract_initializer_10_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2) true)) (> error_1 0)) (summary_constructor_2_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_2))) +) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|)) +(=> (and (and (implicit_constructor_entry_13_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (and (= error_1 0) (and (contract_initializer_10_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2) true))) true) (summary_constructor_2_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_2))) +) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|)) +(=> (and (and (summary_constructor_2_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (= (|msg.value| tx_0) 0)) (= error_0 0))) (interface_0_C_16 this_0 abi_0 crypto_0 state_1))) +) (declare-fun |error_target_3| () Bool) -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (interface_0_C_16 this_0 abi_0 crypto_0 state_0) true) (and (summary_4_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (= error_0 1))) error_target_3))) - - - -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_0 Int) (x_5_1 Int) (x_5_2 Int)) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|)) +(=> (and (and (interface_0_C_16 this_0 abi_0 crypto_0 state_0) true) (and (summary_4_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (= error_0 1))) error_target_3)) +)(assert +(forall ((UNUSED Bool)) (=> error_target_3 false))) (check-sat) ", diff --git a/test/cmdlineTests/standard_model_checker_solvers_smtlib2/output.json b/test/cmdlineTests/standard_model_checker_solvers_smtlib2/output.json index 9dff9a3bd470..a3f4cc03d784 100644 --- a/test/cmdlineTests/standard_model_checker_solvers_smtlib2/output.json +++ b/test/cmdlineTests/standard_model_checker_solvers_smtlib2/output.json @@ -1,7 +1,7 @@ { "auxiliaryInputRequested": { "smtlib2queries": { - "0x75b95497d56c30e254a59358d72ddd4e78f9e90db621cfe677e85d05b2252411": "(set-option :produce-models true) + "0x51b9801f3e8e35f2ff5f4538b0636fae81aa84a482cbb486ae4db63bede5ecb5": "(set-option :produce-models true) (set-logic ALL) (declare-fun |x_3_3| () Int) (declare-fun |error_0| () Int) @@ -21,133 +21,92 @@ (declare-fun |expr_7_0| () Int) (declare-fun |expr_8_0| () Int) (declare-fun |expr_9_1| () Bool) - (assert (and (and (and true true) (and (= expr_9_1 (> expr_7_0 expr_8_0)) (and (=> (and true true) true) (and (= expr_8_0 0) (and (=> (and true true) (and (>= expr_7_0 0) (<= expr_7_0 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (= expr_7_0 x_3_0) (and (and (>= x_3_0 0) (<= x_3_0 115792089237316195423570985008687907853269984665640564039457584007913129639935)) (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (and (and (and (and (and (= (|msg.value| tx_0) 0) (= (|msg.sig| tx_0) 3017696395)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 0) 179)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 1) 222)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 2) 100)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 3) 139)) (>= (|bytes_tuple_accessor_length| (|msg.data| tx_0)) 4))) true)))))))) (not expr_9_1))) (declare-const |EVALEXPR_0| Int) (assert (= |EVALEXPR_0| x_3_0)) (check-sat) (get-value (|EVALEXPR_0| )) ", - "0xf090d88ff3260790818d140ca909b8f4cb311a0d905e4e0318ad4dd790ff5f19": "(set-logic HORN) -(declare-datatypes ((|bytes_tuple| 0)) (((|bytes_tuple| (|bytes_tuple_accessor_array| (Array Int Int)) (|bytes_tuple_accessor_length| Int))))) -(declare-datatypes ((|tx_type| 0)) (((|tx_type| (|block.basefee| Int) (|block.chainid| Int) (|block.coinbase| Int) (|block.gaslimit| Int) (|block.number| Int) (|block.prevrandao| Int) (|block.timestamp| Int) (|blockhash| (Array Int Int)) (|msg.data| |bytes_tuple|) (|msg.sender| Int) (|msg.sig| Int) (|msg.value| Int) (|tx.gasprice| Int) (|tx.origin| Int))))) + "0xdb239809dcdaa42e35abca69790cb7e11b105f839e37faa8841f0dd9736688d7": "(set-logic HORN) +(declare-datatypes ((|abi_type| 0)) (((|abi_type|)))) (declare-datatypes ((|ecrecover_input_type| 0)) (((|ecrecover_input_type| (|hash| Int) (|v| Int) (|r| Int) (|s| Int))))) +(declare-datatypes ((|bytes_tuple| 0)) (((|bytes_tuple| (|bytes_tuple_accessor_array| (Array Int Int)) (|bytes_tuple_accessor_length| Int))))) (declare-datatypes ((|crypto_type| 0)) (((|crypto_type| (|ecrecover| (Array |ecrecover_input_type| Int)) (|keccak256| (Array |bytes_tuple| Int)) (|ripemd160| (Array |bytes_tuple| Int)) (|sha256| (Array |bytes_tuple| Int)))))) -(declare-datatypes ((|abi_type| 0)) (((|abi_type|)))) (declare-datatypes ((|state_type| 0)) (((|state_type| (|balances| (Array Int Int)))))) -(declare-fun |interface_0_C_14| (Int |abi_type| |crypto_type| |state_type| ) Bool) -(declare-fun |nondet_interface_1_C_14| (Int Int |abi_type| |crypto_type| |state_type| |state_type| ) Bool) -(declare-fun |summary_constructor_2_C_14| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (this_0 Int) (tx_0 |tx_type|)) -(=> (= error_0 0) (nondet_interface_1_C_14 error_0 this_0 abi_0 crypto_0 state_0 state_0)))) - - -(declare-fun |summary_3_function_f__13_14| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| Int |state_type| Int ) Bool) -(declare-fun |summary_4_function_f__13_14| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| Int |state_type| Int ) Bool) -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_3_0 Int) (x_3_1 Int)) -(=> (and (and (nondet_interface_1_C_14 error_0 this_0 abi_0 crypto_0 state_0 state_1) true) (and (= error_0 0) (summary_4_function_f__13_14 error_1 this_0 abi_0 crypto_0 tx_0 state_1 x_3_0 state_2 x_3_1))) (nondet_interface_1_C_14 error_1 this_0 abi_0 crypto_0 state_0 state_2)))) - - -(declare-fun |block_5_function_f__13_14| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| Int |state_type| Int ) Bool) -(declare-fun |block_6_f_12_14| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| Int |state_type| Int ) Bool) -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_3_0 Int) (x_3_1 Int)) -(block_5_function_f__13_14 error_0 this_0 abi_0 crypto_0 tx_0 state_0 x_3_0 state_1 x_3_1))) - - -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_3_0 Int) (x_3_1 Int)) -(=> (and (and (block_5_function_f__13_14 error_0 this_0 abi_0 crypto_0 tx_0 state_0 x_3_0 state_1 x_3_1) (and (and (and (and (= state_1 state_0) (= error_0 0)) true) (and true (= x_3_1 x_3_0))) true)) true) (block_6_f_12_14 error_0 this_0 abi_0 crypto_0 tx_0 state_0 x_3_0 state_1 x_3_1)))) - - -(declare-fun |block_7_return_function_f__13_14| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| Int |state_type| Int ) Bool) -(declare-fun |block_8_function_f__13_14| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| Int |state_type| Int ) Bool) -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_7_0 Int) (expr_8_0 Int) (expr_9_1 Bool) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_3_0 Int) (x_3_1 Int)) -(=> (and (and (block_6_f_12_14 error_0 this_0 abi_0 crypto_0 tx_0 state_0 x_3_0 state_1 x_3_1) (and (= expr_9_1 (> expr_7_0 expr_8_0)) (and (=> true true) (and (= expr_8_0 0) (and (=> true (and (>= expr_7_0 0) (<= expr_7_0 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (= expr_7_0 x_3_1) (and (and (>= x_3_1 0) (<= x_3_1 115792089237316195423570985008687907853269984665640564039457584007913129639935)) true))))))) (and (and true (not expr_9_1)) (= error_1 1))) (block_8_function_f__13_14 error_1 this_0 abi_0 crypto_0 tx_0 state_0 x_3_0 state_1 x_3_1)))) - - -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_7_0 Int) (expr_8_0 Int) (expr_9_1 Bool) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_3_0 Int) (x_3_1 Int)) -(=> (block_8_function_f__13_14 error_1 this_0 abi_0 crypto_0 tx_0 state_0 x_3_0 state_1 x_3_1) (summary_3_function_f__13_14 error_1 this_0 abi_0 crypto_0 tx_0 state_0 x_3_0 state_1 x_3_1)))) - - -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_7_0 Int) (expr_8_0 Int) (expr_9_1 Bool) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_3_0 Int) (x_3_1 Int)) -(=> (and (and (block_6_f_12_14 error_0 this_0 abi_0 crypto_0 tx_0 state_0 x_3_0 state_1 x_3_1) (and (= error_1 error_0) (and (= expr_9_1 (> expr_7_0 expr_8_0)) (and (=> true true) (and (= expr_8_0 0) (and (=> true (and (>= expr_7_0 0) (<= expr_7_0 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (= expr_7_0 x_3_1) (and (and (>= x_3_1 0) (<= x_3_1 115792089237316195423570985008687907853269984665640564039457584007913129639935)) true)))))))) true) (block_7_return_function_f__13_14 error_1 this_0 abi_0 crypto_0 tx_0 state_0 x_3_0 state_1 x_3_1)))) - - -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_7_0 Int) (expr_8_0 Int) (expr_9_1 Bool) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_3_0 Int) (x_3_1 Int)) -(=> (and (and (block_7_return_function_f__13_14 error_0 this_0 abi_0 crypto_0 tx_0 state_0 x_3_0 state_1 x_3_1) true) true) (summary_3_function_f__13_14 error_0 this_0 abi_0 crypto_0 tx_0 state_0 x_3_0 state_1 x_3_1)))) - - -(declare-fun |block_9_function_f__13_14| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| Int |state_type| Int ) Bool) -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_7_0 Int) (expr_8_0 Int) (expr_9_1 Bool) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_3_0 Int) (x_3_1 Int)) -(block_9_function_f__13_14 error_0 this_0 abi_0 crypto_0 tx_0 state_0 x_3_0 state_1 x_3_1))) - - -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_7_0 Int) (expr_8_0 Int) (expr_9_1 Bool) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_3_0 Int) (x_3_1 Int) (x_3_2 Int)) -(=> (and (and (block_9_function_f__13_14 error_0 this_0 abi_0 crypto_0 tx_0 state_0 x_3_0 state_1 x_3_1) (and (summary_3_function_f__13_14 error_1 this_0 abi_0 crypto_0 tx_0 state_2 x_3_1 state_3 x_3_2) (and (= state_2 (|state_type| (store (|balances| state_1) this_0 (+ (select (|balances| state_1) this_0) funds_2_0)))) (and (and (>= (+ (select (|balances| state_1) this_0) funds_2_0) 0) (<= (+ (select (|balances| state_1) this_0) funds_2_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935)) (and (>= funds_2_0 (|msg.value| tx_0)) (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (and (and (and (and (and (= (|msg.value| tx_0) 0) (= (|msg.sig| tx_0) 3017696395)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 0) 179)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 1) 222)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 2) 100)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 3) 139)) (>= (|bytes_tuple_accessor_length| (|msg.data| tx_0)) 4))) (and (and (and (and (= state_1 state_0) (= error_0 0)) true) (and true (= x_3_1 x_3_0))) true))))))) true) (summary_4_function_f__13_14 error_1 this_0 abi_0 crypto_0 tx_0 state_0 x_3_0 state_3 x_3_2)))) - - -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_7_0 Int) (expr_8_0 Int) (expr_9_1 Bool) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_3_0 Int) (x_3_1 Int) (x_3_2 Int)) -(=> (and (and (interface_0_C_14 this_0 abi_0 crypto_0 state_0) true) (and (summary_4_function_f__13_14 error_0 this_0 abi_0 crypto_0 tx_0 state_0 x_3_0 state_1 x_3_1) (= error_0 0))) (interface_0_C_14 this_0 abi_0 crypto_0 state_1)))) - - -(declare-fun |contract_initializer_10_C_14| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) -(declare-fun |contract_initializer_entry_11_C_14| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_7_0 Int) (expr_8_0 Int) (expr_9_1 Bool) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_3_0 Int) (x_3_1 Int) (x_3_2 Int)) -(=> (and (and (= state_1 state_0) (= error_0 0)) true) (contract_initializer_entry_11_C_14 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) - - -(declare-fun |contract_initializer_after_init_12_C_14| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_7_0 Int) (expr_8_0 Int) (expr_9_1 Bool) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_3_0 Int) (x_3_1 Int) (x_3_2 Int)) -(=> (and (and (contract_initializer_entry_11_C_14 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) true) (contract_initializer_after_init_12_C_14 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) - - -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_7_0 Int) (expr_8_0 Int) (expr_9_1 Bool) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_3_0 Int) (x_3_1 Int) (x_3_2 Int)) -(=> (and (and (contract_initializer_after_init_12_C_14 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) true) (contract_initializer_10_C_14 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) - - -(declare-fun |implicit_constructor_entry_13_C_14| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| ) Bool) -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_7_0 Int) (expr_8_0 Int) (expr_9_1 Bool) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_3_0 Int) (x_3_1 Int) (x_3_2 Int)) -(=> (and (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true) (>= (select (|balances| state_1) this_0) (|msg.value| tx_0))) (implicit_constructor_entry_13_C_14 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))) - - -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_7_0 Int) (expr_8_0 Int) (expr_9_1 Bool) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_3_0 Int) (x_3_1 Int) (x_3_2 Int)) -(=> (and (and (implicit_constructor_entry_13_C_14 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (and (contract_initializer_10_C_14 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2) true)) (> error_1 0)) (summary_constructor_2_C_14 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_2)))) - - -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_7_0 Int) (expr_8_0 Int) (expr_9_1 Bool) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_3_0 Int) (x_3_1 Int) (x_3_2 Int)) -(=> (and (and (implicit_constructor_entry_13_C_14 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (and (= error_1 0) (and (contract_initializer_10_C_14 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2) true))) true) (summary_constructor_2_C_14 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_2)))) - - -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_7_0 Int) (expr_8_0 Int) (expr_9_1 Bool) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_3_0 Int) (x_3_1 Int) (x_3_2 Int)) -(=> (and (and (summary_constructor_2_C_14 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (= (|msg.value| tx_0) 0)) (= error_0 0))) (interface_0_C_14 this_0 abi_0 crypto_0 state_1)))) - - +(declare-fun |interface_0_C_14| (Int |abi_type| |crypto_type| |state_type|) Bool) +(declare-fun |nondet_interface_1_C_14| (Int Int |abi_type| |crypto_type| |state_type| |state_type|) Bool) +(declare-datatypes ((|tx_type| 0)) (((|tx_type| (|block.basefee| Int) (|block.chainid| Int) (|block.coinbase| Int) (|block.gaslimit| Int) (|block.number| Int) (|block.prevrandao| Int) (|block.timestamp| Int) (|blockhash| (Array Int Int)) (|msg.data| |bytes_tuple|) (|msg.sender| Int) (|msg.sig| Int) (|msg.value| Int) (|tx.gasprice| Int) (|tx.origin| Int))))) +(declare-fun |summary_constructor_2_C_14| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (this_0 Int)) +(=> (= error_0 0) (nondet_interface_1_C_14 error_0 this_0 abi_0 crypto_0 state_0 state_0))) +) +(declare-fun |summary_3_function_f__13_14| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| Int |state_type| Int) Bool) +(declare-fun |summary_4_function_f__13_14| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| Int |state_type| Int) Bool) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_3_0 Int) (x_3_1 Int)) +(=> (and (and (nondet_interface_1_C_14 error_0 this_0 abi_0 crypto_0 state_0 state_1) true) (and (= error_0 0) (summary_4_function_f__13_14 error_1 this_0 abi_0 crypto_0 tx_0 state_1 x_3_0 state_2 x_3_1))) (nondet_interface_1_C_14 error_1 this_0 abi_0 crypto_0 state_0 state_2))) +) +(declare-fun |block_5_function_f__13_14| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| Int |state_type| Int) Bool) +(declare-fun |block_6_f_12_14| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| Int |state_type| Int) Bool) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_3_0 Int) (x_3_1 Int)) +(block_5_function_f__13_14 error_0 this_0 abi_0 crypto_0 tx_0 state_0 x_3_0 state_1 x_3_1)) +) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_3_0 Int) (x_3_1 Int)) +(=> (and (and (block_5_function_f__13_14 error_0 this_0 abi_0 crypto_0 tx_0 state_0 x_3_0 state_1 x_3_1) (and (and (and (and (= state_1 state_0) (= error_0 0)) true) (and true (= x_3_1 x_3_0))) true)) true) (block_6_f_12_14 error_0 this_0 abi_0 crypto_0 tx_0 state_0 x_3_0 state_1 x_3_1))) +) +(declare-fun |block_7_return_function_f__13_14| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| Int |state_type| Int) Bool) +(declare-fun |block_8_function_f__13_14| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| Int |state_type| Int) Bool) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_7_0 Int) (expr_8_0 Int) (expr_9_1 Bool) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_3_0 Int) (x_3_1 Int)) +(=> (and (and (block_6_f_12_14 error_0 this_0 abi_0 crypto_0 tx_0 state_0 x_3_0 state_1 x_3_1) (and (= expr_9_1 (> expr_7_0 expr_8_0)) (and (=> true true) (and (= expr_8_0 0) (and (=> true (and (>= expr_7_0 0) (<= expr_7_0 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (= expr_7_0 x_3_1) (and (and (>= x_3_1 0) (<= x_3_1 115792089237316195423570985008687907853269984665640564039457584007913129639935)) true))))))) (and (and true (not expr_9_1)) (= error_1 1))) (block_8_function_f__13_14 error_1 this_0 abi_0 crypto_0 tx_0 state_0 x_3_0 state_1 x_3_1))) +) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_1 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_3_0 Int) (x_3_1 Int)) +(=> (block_8_function_f__13_14 error_1 this_0 abi_0 crypto_0 tx_0 state_0 x_3_0 state_1 x_3_1) (summary_3_function_f__13_14 error_1 this_0 abi_0 crypto_0 tx_0 state_0 x_3_0 state_1 x_3_1))) +) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_7_0 Int) (expr_8_0 Int) (expr_9_1 Bool) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_3_0 Int) (x_3_1 Int)) +(=> (and (and (block_6_f_12_14 error_0 this_0 abi_0 crypto_0 tx_0 state_0 x_3_0 state_1 x_3_1) (and (= error_1 error_0) (and (= expr_9_1 (> expr_7_0 expr_8_0)) (and (=> true true) (and (= expr_8_0 0) (and (=> true (and (>= expr_7_0 0) (<= expr_7_0 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (= expr_7_0 x_3_1) (and (and (>= x_3_1 0) (<= x_3_1 115792089237316195423570985008687907853269984665640564039457584007913129639935)) true)))))))) true) (block_7_return_function_f__13_14 error_1 this_0 abi_0 crypto_0 tx_0 state_0 x_3_0 state_1 x_3_1))) +) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_3_0 Int) (x_3_1 Int)) +(=> (and (and (block_7_return_function_f__13_14 error_0 this_0 abi_0 crypto_0 tx_0 state_0 x_3_0 state_1 x_3_1) true) true) (summary_3_function_f__13_14 error_0 this_0 abi_0 crypto_0 tx_0 state_0 x_3_0 state_1 x_3_1))) +) +(declare-fun |block_9_function_f__13_14| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| Int |state_type| Int) Bool) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_3_0 Int) (x_3_1 Int)) +(block_9_function_f__13_14 error_0 this_0 abi_0 crypto_0 tx_0 state_0 x_3_0 state_1 x_3_1)) +) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_3_0 Int) (x_3_1 Int) (x_3_2 Int)) +(=> (and (and (block_9_function_f__13_14 error_0 this_0 abi_0 crypto_0 tx_0 state_0 x_3_0 state_1 x_3_1) (and (summary_3_function_f__13_14 error_1 this_0 abi_0 crypto_0 tx_0 state_2 x_3_1 state_3 x_3_2) (and (= state_2 (|state_type| (store (|balances| state_1) this_0 (+ (select (|balances| state_1) this_0) funds_2_0)))) (and (and (>= (+ (select (|balances| state_1) this_0) funds_2_0) 0) (<= (+ (select (|balances| state_1) this_0) funds_2_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935)) (and (>= funds_2_0 (|msg.value| tx_0)) (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (and (and (and (and (and (= (|msg.value| tx_0) 0) (= (|msg.sig| tx_0) 3017696395)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 0) 179)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 1) 222)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 2) 100)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 3) 139)) (>= (|bytes_tuple_accessor_length| (|msg.data| tx_0)) 4))) (and (and (and (and (= state_1 state_0) (= error_0 0)) true) (and true (= x_3_1 x_3_0))) true))))))) true) (summary_4_function_f__13_14 error_1 this_0 abi_0 crypto_0 tx_0 state_0 x_3_0 state_3 x_3_2))) +) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_3_0 Int) (x_3_1 Int)) +(=> (and (and (interface_0_C_14 this_0 abi_0 crypto_0 state_0) true) (and (summary_4_function_f__13_14 error_0 this_0 abi_0 crypto_0 tx_0 state_0 x_3_0 state_1 x_3_1) (= error_0 0))) (interface_0_C_14 this_0 abi_0 crypto_0 state_1))) +) +(declare-fun |contract_initializer_10_C_14| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool) +(declare-fun |contract_initializer_entry_11_C_14| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|)) +(=> (and (and (= state_1 state_0) (= error_0 0)) true) (contract_initializer_entry_11_C_14 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1))) +) +(declare-fun |contract_initializer_after_init_12_C_14| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|)) +(=> (and (and (contract_initializer_entry_11_C_14 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) true) (contract_initializer_after_init_12_C_14 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1))) +) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|)) +(=> (and (and (contract_initializer_after_init_12_C_14 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) true) (contract_initializer_10_C_14 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1))) +) +(declare-fun |implicit_constructor_entry_13_C_14| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|)) +(=> (and (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true) (>= (select (|balances| state_1) this_0) (|msg.value| tx_0))) (implicit_constructor_entry_13_C_14 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1))) +) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|)) +(=> (and (and (implicit_constructor_entry_13_C_14 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (and (contract_initializer_10_C_14 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2) true)) (> error_1 0)) (summary_constructor_2_C_14 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_2))) +) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|)) +(=> (and (and (implicit_constructor_entry_13_C_14 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (and (= error_1 0) (and (contract_initializer_10_C_14 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2) true))) true) (summary_constructor_2_C_14 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_2))) +) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|)) +(=> (and (and (summary_constructor_2_C_14 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (= (|msg.value| tx_0) 0)) (= error_0 0))) (interface_0_C_14 this_0 abi_0 crypto_0 state_1))) +) (declare-fun |error_target_3| () Bool) -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_7_0 Int) (expr_8_0 Int) (expr_9_1 Bool) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_3_0 Int) (x_3_1 Int) (x_3_2 Int)) -(=> (and (and (interface_0_C_14 this_0 abi_0 crypto_0 state_0) true) (and (summary_4_function_f__13_14 error_0 this_0 abi_0 crypto_0 tx_0 state_0 x_3_0 state_1 x_3_1) (= error_0 1))) error_target_3))) - - - -(assert -(forall ( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_7_0 Int) (expr_8_0 Int) (expr_9_1 Bool) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_3_0 Int) (x_3_1 Int) (x_3_2 Int)) +(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_3_0 Int) (x_3_1 Int)) +(=> (and (and (interface_0_C_14 this_0 abi_0 crypto_0 state_0) true) (and (summary_4_function_f__13_14 error_0 this_0 abi_0 crypto_0 tx_0 state_0 x_3_0 state_1 x_3_1) (= error_0 1))) error_target_3)) +)(assert +(forall ((UNUSED Bool)) (=> error_target_3 false))) (check-sat) " diff --git a/test/libsolidity/smtCheckerTests/invariants/array_access.sol b/test/libsolidity/smtCheckerTests/invariants/array_access.sol new file mode 100644 index 000000000000..be3ad2548034 --- /dev/null +++ b/test/libsolidity/smtCheckerTests/invariants/array_access.sol @@ -0,0 +1,20 @@ +contract C { + int[2] a; + + constructor() { + a[0] = 1; + a[1] = 2; + } + + function i() public view { + assert(a[1] > a[0]); + } +} +// ==== +// SMTEngine: chc +// SMTIgnoreInv: no +// SMTSolvers: eld +// SMTTargets: assert +// ---- +// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. +// Info 1180: Contract invariant(s) for :C:\n((a.length = 2) && ((a[1] - a[0]) >= 1))\n diff --git a/test/libsolidity/smtCheckerTests/invariants/struct_access.sol b/test/libsolidity/smtCheckerTests/invariants/struct_access.sol new file mode 100644 index 000000000000..afc4eaed7a7d --- /dev/null +++ b/test/libsolidity/smtCheckerTests/invariants/struct_access.sol @@ -0,0 +1,15 @@ +contract C { + struct S { int x; } + S s = S(1); + + function i() public view { + assert(s.x > 0); + } +} +// ==== +// SMTEngine: chc +// SMTIgnoreInv: no +// SMTSolvers: eld +// ---- +// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. +// Info 1180: Contract invariant(s) for :C:\n(s.x = 1)\n From 9a1d7406bb742f808f1822be8baba5e16924357f Mon Sep 17 00:00:00 2001 From: Alexander Arlt Date: Thu, 12 Oct 2023 17:46:03 +0200 Subject: [PATCH 0321/1022] Add --asm-json option in assembler mode. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: r0qs Co-authored-by: Kamil Śliwak --- Changelog.md | 1 + libevmasm/Assembly.cpp | 23 +- libsolidity/interface/StandardCompiler.cpp | 2 +- libyul/Object.cpp | 30 ++ libyul/Object.h | 8 + libyul/YulStack.cpp | 9 +- libyul/YulStack.h | 7 +- solc/CommandLineInterface.cpp | 28 +- solc/CommandLineParser.cpp | 1 + .../args | 1 + .../err | 1 + .../exit | 1 + .../stdin | 17 + .../asm_json_yul_export_evm_asm_import/args | 1 + .../asm_json_yul_export_evm_asm_import/output | 39 ++ .../asm_json_yul_export_evm_asm_import/stdin | 36 ++ .../args | 1 + .../err | 1 + .../exit | 1 + .../stdin | 6 + .../args | 1 + .../output | 426 ++++++++++++++++++ .../stdin | 51 +++ .../args | 1 + .../output | 384 ++++++++++++++++ .../stdin | 40 ++ .../args | 1 + .../output | 384 ++++++++++++++++ .../stdin | 34 ++ .../strict_asm_asm_json_yul_verbatim/args | 1 + .../strict_asm_asm_json_yul_verbatim/output | 18 + .../strict_asm_asm_json_yul_verbatim/stdin | 4 + .../strict_asm_output_selection_invalid/err | 2 +- test/libyul/ObjectCompilerTest.cpp | 5 +- .../libyul/objectCompiler/sourceLocations.yul | 14 +- test/solc/CommandLineParser.cpp | 2 + 36 files changed, 1556 insertions(+), 26 deletions(-) create mode 100644 test/cmdlineTests/asm_json_import_sourcelist_with_null_elements/args create mode 100644 test/cmdlineTests/asm_json_import_sourcelist_with_null_elements/err create mode 100644 test/cmdlineTests/asm_json_import_sourcelist_with_null_elements/exit create mode 100644 test/cmdlineTests/asm_json_import_sourcelist_with_null_elements/stdin create mode 100644 test/cmdlineTests/asm_json_yul_export_evm_asm_import/args create mode 100644 test/cmdlineTests/asm_json_yul_export_evm_asm_import/output create mode 100644 test/cmdlineTests/asm_json_yul_export_evm_asm_import/stdin create mode 100644 test/cmdlineTests/strict_asm_asm_json_arbitrary_source_index/args create mode 100644 test/cmdlineTests/strict_asm_asm_json_arbitrary_source_index/err create mode 100644 test/cmdlineTests/strict_asm_asm_json_arbitrary_source_index/exit create mode 100644 test/cmdlineTests/strict_asm_asm_json_arbitrary_source_index/stdin create mode 100644 test/cmdlineTests/strict_asm_asm_json_subobjects_with_debug/args create mode 100644 test/cmdlineTests/strict_asm_asm_json_subobjects_with_debug/output create mode 100644 test/cmdlineTests/strict_asm_asm_json_subobjects_with_debug/stdin create mode 100644 test/cmdlineTests/strict_asm_asm_json_with_debug_info_annotations/args create mode 100644 test/cmdlineTests/strict_asm_asm_json_with_debug_info_annotations/output create mode 100644 test/cmdlineTests/strict_asm_asm_json_with_debug_info_annotations/stdin create mode 100644 test/cmdlineTests/strict_asm_asm_json_without_debug_info_annotations/args create mode 100644 test/cmdlineTests/strict_asm_asm_json_without_debug_info_annotations/output create mode 100644 test/cmdlineTests/strict_asm_asm_json_without_debug_info_annotations/stdin create mode 100644 test/cmdlineTests/strict_asm_asm_json_yul_verbatim/args create mode 100644 test/cmdlineTests/strict_asm_asm_json_yul_verbatim/output create mode 100644 test/cmdlineTests/strict_asm_asm_json_yul_verbatim/stdin diff --git a/Changelog.md b/Changelog.md index e67cf0f07d91..9c9a9e8fd91b 100644 --- a/Changelog.md +++ b/Changelog.md @@ -14,6 +14,7 @@ Compiler Features: * SMTChecker: Replace CVC4 as a possible BMC backend with cvc5. * Standard JSON Interface: Do not perform IR optimization when only unoptimized IR is requested. * Yul Optimizer: The optimizer now treats some previously unrecognized identical literals as identical. + * Commandline Interface: Allow the use of ``--asm-json`` output option in assembler mode to export EVM assembly of the contracts in JSON format. Bugfixes: diff --git a/libevmasm/Assembly.cpp b/libevmasm/Assembly.cpp index 356a2818a4cd..f9b800c90884 100644 --- a/libevmasm/Assembly.cpp +++ b/libevmasm/Assembly.cpp @@ -479,8 +479,18 @@ Json Assembly::assemblyJSON(std::map const& _sourceIndice { root["sourceList"] = Json::array(); Json& jsonSourceList = root["sourceList"]; - for (auto const& [name, index]: _sourceIndices) - jsonSourceList[index] = name; + unsigned maxSourceIndex = 0; + for (auto const& [sourceName, sourceIndex]: _sourceIndices) + { + maxSourceIndex = std::max(sourceIndex, maxSourceIndex); + jsonSourceList[sourceIndex] = sourceName; + } + solAssert(maxSourceIndex + 1 >= _sourceIndices.size()); + solRequire( + _sourceIndices.size() == 0 || _sourceIndices.size() == maxSourceIndex + 1, + AssemblyImportException, + "The 'sourceList' array contains invalid 'null' item." + ); } if (!m_data.empty() || !m_subs.empty()) @@ -522,7 +532,14 @@ std::pair, std::vector> Assembly::fromJSO { solRequire(_json["sourceList"].is_array(), AssemblyImportException, "Optional member 'sourceList' is not an array."); for (Json const& sourceName: _json["sourceList"]) - solRequire(sourceName.is_string(), AssemblyImportException, "The 'sourceList' array contains an item that is not a string."); + { + solRequire(!sourceName.is_null(), AssemblyImportException, "The 'sourceList' array contains invalid 'null' item."); + solRequire( + sourceName.is_string(), + AssemblyImportException, + "The 'sourceList' array contains an item that is not a string." + ); + } } } else diff --git a/libsolidity/interface/StandardCompiler.cpp b/libsolidity/interface/StandardCompiler.cpp index cb0c8126820e..e4b9f9f7ae17 100644 --- a/libsolidity/interface/StandardCompiler.cpp +++ b/libsolidity/interface/StandardCompiler.cpp @@ -1694,7 +1694,7 @@ Json StandardCompiler::compileYul(InputsAndSettings _inputsAndSettings) if (isArtifactRequested(_inputsAndSettings.outputSelection, sourceName, contractName, "irOptimized", wildcardMatchesExperimental)) output["contracts"][sourceName][contractName]["irOptimized"] = stack.print(); if (isArtifactRequested(_inputsAndSettings.outputSelection, sourceName, contractName, "evm.assembly", wildcardMatchesExperimental)) - output["contracts"][sourceName][contractName]["evm"]["assembly"] = object.assembly; + output["contracts"][sourceName][contractName]["evm"]["assembly"] = object.assembly->assemblyString(stack.debugInfoSelection()); return output; } diff --git a/libyul/Object.cpp b/libyul/Object.cpp index 736c1bb8411e..989e7ce809de 100644 --- a/libyul/Object.cpp +++ b/libyul/Object.cpp @@ -160,3 +160,33 @@ std::vector Object::pathToSubObject(std::string_view _qualifiedName) con return path; } + +void Object::collectSourceIndices(std::map& _indices) const +{ + if (debugData && debugData->sourceNames.has_value()) + for (auto const& [sourceIndex, sourceName]: debugData->sourceNames.value()) + { + solAssert(_indices.count(*sourceName) == 0 || _indices[*sourceName] == sourceIndex); + _indices[*sourceName] = sourceIndex; + } + for (std::shared_ptr const& subNode: subObjects) + if (auto subObject = dynamic_cast(subNode.get())) + subObject->collectSourceIndices(_indices); +} + +bool Object::hasContiguousSourceIndices() const +{ + std::map sourceIndices; + collectSourceIndices(sourceIndices); + + unsigned maxSourceIndex = 0; + std::set indices; + for (auto const& [sources, sourceIndex]: sourceIndices) + { + maxSourceIndex = std::max(sourceIndex, maxSourceIndex); + indices.insert(sourceIndex); + } + + solAssert(maxSourceIndex + 1 >= indices.size()); + return indices.size() == 0 || indices.size() == maxSourceIndex + 1; +} diff --git a/libyul/Object.h b/libyul/Object.h index 4e891c26400a..c419a6d55e39 100644 --- a/libyul/Object.h +++ b/libyul/Object.h @@ -129,6 +129,14 @@ struct Object: public ObjectNode std::shared_ptr debugData; + /// Collects names of all Solidity source units present in the debug data + /// of the Yul object (including sub-objects) and their assigned indices. + /// @param _indices map that will be filled with source indices of the current Yul object & its sub-objects. + void collectSourceIndices(std::map& _indices) const; + + /// @returns true, if the range of source indices starts at zero and is contiguous, false otherwise. + bool hasContiguousSourceIndices() const; + /// @returns the name of the special metadata data object. static std::string metadataName() { return ".metadata"; } }; diff --git a/libyul/YulStack.cpp b/libyul/YulStack.cpp index 223d6c04a19b..b9fc6388c6bd 100644 --- a/libyul/YulStack.cpp +++ b/libyul/YulStack.cpp @@ -15,10 +15,6 @@ along with solidity. If not, see . */ // SPDX-License-Identifier: GPL-3.0 -/** - * Full assembly stack that can support EVM-assembly and Yul as input and EVM, EVM1.5 - */ - #include @@ -64,7 +60,6 @@ Dialect const& languageToDialect(YulStack::Language _language, EVMVersion _versi } - CharStream const& YulStack::charStream(std::string const& _sourceName) const { yulAssert(m_charStream, ""); @@ -274,7 +269,7 @@ YulStack::assembleWithDeployed(std::optional _deployName) { creationObject.bytecode = std::make_shared(creationAssembly->assemble()); yulAssert(creationObject.bytecode->immutableReferences.empty(), "Leftover immutables."); - creationObject.assembly = creationAssembly->assemblyString(m_debugInfoSelection); + creationObject.assembly = creationAssembly; creationObject.sourceMappings = std::make_unique( evmasm::AssemblyItem::computeSourceMapping( creationAssembly->items(), @@ -285,7 +280,7 @@ YulStack::assembleWithDeployed(std::optional _deployName) if (deployedAssembly) { deployedObject.bytecode = std::make_shared(deployedAssembly->assemble()); - deployedObject.assembly = deployedAssembly->assemblyString(m_debugInfoSelection); + deployedObject.assembly = deployedAssembly; deployedObject.sourceMappings = std::make_unique( evmasm::AssemblyItem::computeSourceMapping( deployedAssembly->items(), diff --git a/libyul/YulStack.h b/libyul/YulStack.h index c6d78a115c18..f547ef77027e 100644 --- a/libyul/YulStack.h +++ b/libyul/YulStack.h @@ -16,7 +16,7 @@ */ // SPDX-License-Identifier: GPL-3.0 /** - * Full assembly stack that can support EVM-assembly and Yul as input and EVM. + * Full assembly stack that can support Yul as input. */ #pragma once @@ -55,7 +55,7 @@ class AbstractAssembly; struct MachineAssemblyObject { std::shared_ptr bytecode; - std::string assembly; + std::shared_ptr assembly; std::unique_ptr sourceMappings; }; @@ -137,9 +137,12 @@ class YulStack: public langutil::CharStreamProvider langutil::CharStreamProvider const* _soliditySourceProvider = nullptr ) const; Json astJson() const; + /// Return the parsed and analyzed object. std::shared_ptr parserResult() const; + langutil::DebugInfoSelection debugInfoSelection() const { return m_debugInfoSelection; } + private: bool parse(std::string const& _sourceName, std::string const& _source); bool analyzeParsed(); diff --git a/solc/CommandLineInterface.cpp b/solc/CommandLineInterface.cpp index 5d0272dfa930..1351858405a1 100644 --- a/solc/CommandLineInterface.cpp +++ b/solc/CommandLineInterface.cpp @@ -177,7 +177,7 @@ void CommandLineInterface::handleEVMAssembly(std::string const& _contract) std::string assembly; if (m_options.compiler.outputs.asmJson) - assembly = util::jsonPrint(removeNullMembers(m_assemblyStack->assemblyJSON(_contract)), m_options.formatting.json); + assembly = util::jsonPrint(m_assemblyStack->assemblyJSON(_contract), m_options.formatting.json); else assembly = m_assemblyStack->assemblyString(_contract, m_fileReader.sourceUnits()); @@ -1197,6 +1197,17 @@ void CommandLineInterface::assembleYul(yul::YulStack::Language _language, yul::Y successful = false; else stack.optimize(); + + if (successful && m_options.compiler.outputs.asmJson) + { + std::shared_ptr result = stack.parserResult(); + if (result && !result->hasContiguousSourceIndices()) + solThrow( + CommandLineExecutionError, + "Generating the assembly JSON output was not possible. " + "Source indices provided in the @use-src annotation in the Yul input do not start at 0 or are not contiguous." + ); + } } for (auto const& sourceAndStack: yulStacks) @@ -1256,11 +1267,22 @@ void CommandLineInterface::assembleYul(yul::YulStack::Language _language, yul::Y if (m_options.compiler.outputs.asm_) { sout() << std::endl << "Text representation:" << std::endl; - if (!object.assembly.empty()) - sout() << object.assembly << std::endl; + std::string assemblyText{object.assembly->assemblyString(stack.debugInfoSelection())}; + if (!assemblyText.empty()) + sout() << assemblyText << std::endl; else report(Error::Severity::Info, "No text representation found."); } + if (m_options.compiler.outputs.asmJson) + { + sout() << std::endl << "EVM assembly:" << std::endl; + std::map sourceIndices; + stack.parserResult()->collectSourceIndices(sourceIndices); + sout() << util::jsonPrint( + object.assembly->assemblyJSON(sourceIndices), + m_options.formatting.json + ) << std::endl; + } } } diff --git a/solc/CommandLineParser.cpp b/solc/CommandLineParser.cpp index 2697f7ebd09f..881c656dad9b 100644 --- a/solc/CommandLineParser.cpp +++ b/solc/CommandLineParser.cpp @@ -472,6 +472,7 @@ void CommandLineParser::parseOutputSelection() CompilerOutputs::componentName(&CompilerOutputs::binary), CompilerOutputs::componentName(&CompilerOutputs::irOptimized), CompilerOutputs::componentName(&CompilerOutputs::astCompactJson), + CompilerOutputs::componentName(&CompilerOutputs::asmJson), }; static std::set const evmAssemblyJsonImportModeOutputs = { CompilerOutputs::componentName(&CompilerOutputs::asm_), diff --git a/test/cmdlineTests/asm_json_import_sourcelist_with_null_elements/args b/test/cmdlineTests/asm_json_import_sourcelist_with_null_elements/args new file mode 100644 index 000000000000..c1bc80dabfcd --- /dev/null +++ b/test/cmdlineTests/asm_json_import_sourcelist_with_null_elements/args @@ -0,0 +1 @@ +--pretty-json --json-indent 4 --import-asm-json - diff --git a/test/cmdlineTests/asm_json_import_sourcelist_with_null_elements/err b/test/cmdlineTests/asm_json_import_sourcelist_with_null_elements/err new file mode 100644 index 000000000000..73f36f97191d --- /dev/null +++ b/test/cmdlineTests/asm_json_import_sourcelist_with_null_elements/err @@ -0,0 +1 @@ +Error: Assembly Import Error: The 'sourceList' array contains invalid 'null' item. diff --git a/test/cmdlineTests/asm_json_import_sourcelist_with_null_elements/exit b/test/cmdlineTests/asm_json_import_sourcelist_with_null_elements/exit new file mode 100644 index 000000000000..d00491fd7e5b --- /dev/null +++ b/test/cmdlineTests/asm_json_import_sourcelist_with_null_elements/exit @@ -0,0 +1 @@ +1 diff --git a/test/cmdlineTests/asm_json_import_sourcelist_with_null_elements/stdin b/test/cmdlineTests/asm_json_import_sourcelist_with_null_elements/stdin new file mode 100644 index 000000000000..923376f40f91 --- /dev/null +++ b/test/cmdlineTests/asm_json_import_sourcelist_with_null_elements/stdin @@ -0,0 +1,17 @@ +{ + ".code": + [ + { + "begin": -1, + "end": -1, + "name": "STOP", + "source": -1 + } + ], + "sourceList": + [ + null, + null, + "L0.sol" + ] +} diff --git a/test/cmdlineTests/asm_json_yul_export_evm_asm_import/args b/test/cmdlineTests/asm_json_yul_export_evm_asm_import/args new file mode 100644 index 000000000000..15c962831667 --- /dev/null +++ b/test/cmdlineTests/asm_json_yul_export_evm_asm_import/args @@ -0,0 +1 @@ +--import-asm-json - --opcodes --asm --bin --asm-json --pretty-json --json-indent 4 diff --git a/test/cmdlineTests/asm_json_yul_export_evm_asm_import/output b/test/cmdlineTests/asm_json_yul_export_evm_asm_import/output new file mode 100644 index 000000000000..9ebef414258d --- /dev/null +++ b/test/cmdlineTests/asm_json_yul_export_evm_asm_import/output @@ -0,0 +1,39 @@ +Opcodes: +PUSH1 0x5 PUSH0 SSTORE STOP +Binary: +60055f5500 +EVM assembly: +{ + ".code": [ + { + "begin": -1, + "end": -1, + "name": "PUSHSIZE", + "source": -1 + }, + { + "begin": -1, + "end": -1, + "name": "PUSH", + "source": -1, + "value": "0" + }, + { + "begin": -1, + "end": -1, + "name": "SSTORE", + "source": -1 + }, + { + "begin": -1, + "end": -1, + "name": "STOP", + "source": -1 + } + ], + "sourceList": [ + "L0.sol", + "L1.sol", + "L2.sol" + ] +} diff --git a/test/cmdlineTests/asm_json_yul_export_evm_asm_import/stdin b/test/cmdlineTests/asm_json_yul_export_evm_asm_import/stdin new file mode 100644 index 000000000000..840660f6bc2e --- /dev/null +++ b/test/cmdlineTests/asm_json_yul_export_evm_asm_import/stdin @@ -0,0 +1,36 @@ +{ + ".code": + [ + { + "begin": -1, + "end": -1, + "name": "PUSHSIZE", + "source": -1 + }, + { + "begin": -1, + "end": -1, + "name": "PUSH", + "source": -1, + "value": "0" + }, + { + "begin": -1, + "end": -1, + "name": "SSTORE", + "source": -1 + }, + { + "begin": -1, + "end": -1, + "name": "STOP", + "source": -1 + } + ], + "sourceList": + [ + "L0.sol", + "L1.sol", + "L2.sol" + ] +} diff --git a/test/cmdlineTests/strict_asm_asm_json_arbitrary_source_index/args b/test/cmdlineTests/strict_asm_asm_json_arbitrary_source_index/args new file mode 100644 index 000000000000..bf9bf8851a8c --- /dev/null +++ b/test/cmdlineTests/strict_asm_asm_json_arbitrary_source_index/args @@ -0,0 +1 @@ +--strict-assembly - --asm-json --pretty-json --json-indent 4 diff --git a/test/cmdlineTests/strict_asm_asm_json_arbitrary_source_index/err b/test/cmdlineTests/strict_asm_asm_json_arbitrary_source_index/err new file mode 100644 index 000000000000..129c4a8cccab --- /dev/null +++ b/test/cmdlineTests/strict_asm_asm_json_arbitrary_source_index/err @@ -0,0 +1 @@ +Error: Generating the assembly JSON output was not possible. Source indices provided in the @use-src annotation in the Yul input do not start at 0 or are not contiguous. diff --git a/test/cmdlineTests/strict_asm_asm_json_arbitrary_source_index/exit b/test/cmdlineTests/strict_asm_asm_json_arbitrary_source_index/exit new file mode 100644 index 000000000000..d00491fd7e5b --- /dev/null +++ b/test/cmdlineTests/strict_asm_asm_json_arbitrary_source_index/exit @@ -0,0 +1 @@ +1 diff --git a/test/cmdlineTests/strict_asm_asm_json_arbitrary_source_index/stdin b/test/cmdlineTests/strict_asm_asm_json_arbitrary_source_index/stdin new file mode 100644 index 000000000000..5b36b4118ff7 --- /dev/null +++ b/test/cmdlineTests/strict_asm_asm_json_arbitrary_source_index/stdin @@ -0,0 +1,6 @@ +/// @use-src 2:"L0.sol" +object "L0" { + code { + sstore(0, datasize("L0")) + } +} diff --git a/test/cmdlineTests/strict_asm_asm_json_subobjects_with_debug/args b/test/cmdlineTests/strict_asm_asm_json_subobjects_with_debug/args new file mode 100644 index 000000000000..bf9bf8851a8c --- /dev/null +++ b/test/cmdlineTests/strict_asm_asm_json_subobjects_with_debug/args @@ -0,0 +1 @@ +--strict-assembly - --asm-json --pretty-json --json-indent 4 diff --git a/test/cmdlineTests/strict_asm_asm_json_subobjects_with_debug/output b/test/cmdlineTests/strict_asm_asm_json_subobjects_with_debug/output new file mode 100644 index 000000000000..dfa7656834c8 --- /dev/null +++ b/test/cmdlineTests/strict_asm_asm_json_subobjects_with_debug/output @@ -0,0 +1,426 @@ + +======= (EVM) ======= + +EVM assembly: +{ + ".code": [ + { + "begin": 41, + "end": 137, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { + "begin": 41, + "end": 137, + "name": "DUP1", + "source": 0 + }, + { + "begin": 41, + "end": 137, + "name": "SSTORE", + "source": 0 + }, + { + "begin": 41, + "end": 137, + "name": "PUSHSIZE", + "source": 0 + }, + { + "begin": 41, + "end": 137, + "name": "PUSH", + "source": 0, + "value": "1" + }, + { + "begin": 41, + "end": 137, + "name": "SSTORE", + "source": 0 + }, + { + "begin": 41, + "end": 137, + "name": "PUSH [$]", + "source": 0, + "value": "0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "begin": 41, + "end": 137, + "name": "PUSH", + "source": 0, + "value": "2" + }, + { + "begin": 41, + "end": 137, + "name": "SSTORE", + "source": 0 + }, + { + "begin": 41, + "end": 137, + "name": "PUSH #[$]", + "source": 0, + "value": "0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "begin": 41, + "end": 137, + "name": "PUSH", + "source": 0, + "value": "3" + }, + { + "begin": 41, + "end": 137, + "name": "SSTORE", + "source": 0 + }, + { + "begin": 41, + "end": 137, + "name": "PUSH [$]", + "source": 0, + "value": "000000000000000000000000000000000000000000000000ffffffffffffffff" + }, + { + "begin": 41, + "end": 137, + "name": "PUSH", + "source": 0, + "value": "4" + }, + { + "begin": 41, + "end": 137, + "name": "SSTORE", + "source": 0 + }, + { + "begin": 41, + "end": 137, + "name": "PUSH #[$]", + "source": 0, + "value": "000000000000000000000000000000000000000000000000ffffffffffffffff" + }, + { + "begin": 41, + "end": 137, + "name": "PUSH", + "source": 0, + "value": "5" + }, + { + "begin": 41, + "end": 137, + "name": "SSTORE", + "source": 0 + }, + { + "begin": 41, + "end": 137, + "name": "PUSH [$]", + "source": 0, + "value": "000000000000000000000000000000000000000000000000fffffffffffffffe" + }, + { + "begin": 41, + "end": 137, + "name": "PUSH", + "source": 0, + "value": "6" + }, + { + "begin": 41, + "end": 137, + "name": "SSTORE", + "source": 0 + }, + { + "begin": 41, + "end": 137, + "name": "PUSH #[$]", + "source": 0, + "value": "000000000000000000000000000000000000000000000000fffffffffffffffe" + }, + { + "begin": 41, + "end": 137, + "name": "PUSH", + "source": 0, + "value": "7" + }, + { + "begin": 41, + "end": 137, + "name": "SSTORE", + "source": 0 + }, + { + "begin": 41, + "end": 137, + "name": "PUSH [$]", + "source": 0, + "value": "000000000000000000000000000000000000000000000000fffffffffffffffd" + }, + { + "begin": 41, + "end": 137, + "name": "PUSH", + "source": 0, + "value": "8" + }, + { + "begin": 41, + "end": 137, + "name": "SSTORE", + "source": 0 + }, + { + "begin": 41, + "end": 137, + "name": "PUSH #[$]", + "source": 0, + "value": "000000000000000000000000000000000000000000000000fffffffffffffffd" + }, + { + "begin": 41, + "end": 137, + "name": "PUSH", + "source": 0, + "value": "9" + }, + { + "begin": 41, + "end": 137, + "name": "SSTORE", + "source": 0 + }, + { + "begin": -1, + "end": -1, + "name": "STOP", + "source": -1 + } + ], + ".data": { + "0": { + ".code": [ + { + "begin": 57, + "end": 158, + "name": "PUSH [$]", + "source": 1, + "value": "0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "begin": 57, + "end": 158, + "name": "PUSH", + "source": 1, + "value": "A" + }, + { + "begin": 57, + "end": 158, + "name": "SSTORE", + "source": 1 + }, + { + "begin": 57, + "end": 158, + "name": "PUSH #[$]", + "source": 1, + "value": "0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "begin": 57, + "end": 158, + "name": "PUSH", + "source": 1, + "value": "B" + }, + { + "begin": 57, + "end": 158, + "name": "SSTORE", + "source": 1 + }, + { + "begin": 57, + "end": 158, + "name": "PUSH [$]", + "source": 1, + "value": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "begin": 57, + "end": 158, + "name": "PUSH", + "source": 1, + "value": "C" + }, + { + "begin": 57, + "end": 158, + "name": "SSTORE", + "source": 1 + }, + { + "begin": 57, + "end": 158, + "name": "PUSH #[$]", + "source": 1, + "value": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "begin": 57, + "end": 158, + "name": "PUSH", + "source": 1, + "value": "D" + }, + { + "begin": 57, + "end": 158, + "name": "SSTORE", + "source": 1 + }, + { + "begin": 57, + "end": 158, + "name": "PUSH [$]", + "source": 1, + "value": "000000000000000000000000000000000000000000000000ffffffffffffffff" + }, + { + "begin": 57, + "end": 158, + "name": "PUSH", + "source": 1, + "value": "E" + }, + { + "begin": 57, + "end": 158, + "name": "SSTORE", + "source": 1 + }, + { + "begin": 57, + "end": 158, + "name": "PUSH #[$]", + "source": 1, + "value": "000000000000000000000000000000000000000000000000ffffffffffffffff" + }, + { + "begin": 57, + "end": 158, + "name": "PUSH", + "source": 1, + "value": "F" + }, + { + "begin": 57, + "end": 158, + "name": "SSTORE", + "source": 1 + }, + { + "begin": -1, + "end": -1, + "name": "STOP", + "source": -1 + } + ], + ".data": { + "0": { + ".code": [ + { + "begin": 41, + "end": 100, + "name": "PUSH [$]", + "source": 2, + "value": "0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "begin": 41, + "end": 100, + "name": "PUSH", + "source": 2, + "value": "10" + }, + { + "begin": 41, + "end": 100, + "name": "SSTORE", + "source": 2 + }, + { + "begin": 41, + "end": 100, + "name": "PUSH #[$]", + "source": 2, + "value": "0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "begin": 41, + "end": 100, + "name": "PUSH", + "source": 2, + "value": "11" + }, + { + "begin": 41, + "end": 100, + "name": "SSTORE", + "source": 2 + }, + { + "begin": -1, + "end": -1, + "name": "STOP", + "source": -1 + } + ], + ".data": { + "0": { + ".code": [ + { + "begin": -1, + "end": -1, + "name": "INVALID", + "source": -1 + } + ] + } + } + }, + "1": { + ".code": [ + { + "begin": -1, + "end": -1, + "name": "INVALID", + "source": -1 + } + ] + } + } + }, + "ACAF3289D7B601CBD114FB36C4D29C85BBFD5E133F14CB355C3FD8D99367964F": "48656c6c6f2c20576f726c6421" + }, + "sourceList": [ + "a.sol", + "b.sol", + "c.sol", + "d.sol", + "e.sol" + ] +} diff --git a/test/cmdlineTests/strict_asm_asm_json_subobjects_with_debug/stdin b/test/cmdlineTests/strict_asm_asm_json_subobjects_with_debug/stdin new file mode 100644 index 000000000000..01db34d6fd2a --- /dev/null +++ b/test/cmdlineTests/strict_asm_asm_json_subobjects_with_debug/stdin @@ -0,0 +1,51 @@ +/// @use-src 0:"a.sol" +object "A" { + code { + /// @src 0:41:137 "contract A {..." + sstore(0, dataoffset("A")) + sstore(1, datasize("A")) + sstore(2, dataoffset("B")) + sstore(3, datasize("B")) + sstore(4, dataoffset("B.C")) + sstore(5, datasize("B.C")) + sstore(6, dataoffset("B.E")) + sstore(7, datasize("B.E")) + sstore(8, dataoffset("B.C.D")) + sstore(9, datasize("B.C.D")) + } + + data "data1" "Hello, World!" + + /// @use-src 1:"b.sol" + object "B" { + code { + /// @src 1:57:158 "contract B {..." + sstore(10, dataoffset("C")) + sstore(11, datasize("C")) + sstore(12, dataoffset("E")) + sstore(13, datasize("E")) + sstore(14, dataoffset("C.D")) + sstore(15, datasize("C.D")) + } + /// @use-src 2:"c.sol" + object "C" { + code { + /// @src 2:41:100 "contract C {..." + sstore(16, dataoffset("D")) + sstore(17, datasize("D")) + } + /// @use-src 3:"d.sol" + object "D" { + code { + invalid() + } + } + } + /// @use-src 4:"e.sol" + object "E" { + code { + invalid() + } + } + } +} diff --git a/test/cmdlineTests/strict_asm_asm_json_with_debug_info_annotations/args b/test/cmdlineTests/strict_asm_asm_json_with_debug_info_annotations/args new file mode 100644 index 000000000000..bf9bf8851a8c --- /dev/null +++ b/test/cmdlineTests/strict_asm_asm_json_with_debug_info_annotations/args @@ -0,0 +1 @@ +--strict-assembly - --asm-json --pretty-json --json-indent 4 diff --git a/test/cmdlineTests/strict_asm_asm_json_with_debug_info_annotations/output b/test/cmdlineTests/strict_asm_asm_json_with_debug_info_annotations/output new file mode 100644 index 000000000000..85642e709a4a --- /dev/null +++ b/test/cmdlineTests/strict_asm_asm_json_with_debug_info_annotations/output @@ -0,0 +1,384 @@ + +======= (EVM) ======= + +EVM assembly: +{ + ".code": [ + { + "begin": 0, + "end": 125, + "name": "PUSH", + "source": 0, + "value": "80" + }, + { + "begin": 0, + "end": 125, + "name": "DUP1", + "source": 0 + }, + { + "begin": 0, + "end": 125, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { + "begin": 0, + "end": 125, + "name": "MSTORE", + "source": 0 + }, + { + "begin": 0, + "end": 125, + "name": "CALLVALUE", + "source": 0 + }, + { + "begin": 0, + "end": 125, + "name": "PUSH [tag]", + "source": 0, + "value": "1" + }, + { + "begin": 0, + "end": 125, + "name": "JUMPI", + "source": 0 + }, + { + "begin": 56, + "end": 57, + "name": "PUSH", + "source": 0, + "value": "2" + }, + { + "begin": 33, + "end": 34, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { + "begin": 0, + "end": 125, + "name": "SSTORE", + "source": 0 + }, + { + "begin": 33, + "end": 34, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { + "begin": 33, + "end": 34, + "name": "PUSH", + "source": 0, + "value": "1" + }, + { + "begin": 0, + "end": 125, + "name": "SSTORE", + "source": 0 + }, + { + "begin": 0, + "end": 125, + "name": "PUSH #[$]", + "source": 0, + "value": "0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "begin": 0, + "end": 125, + "name": "SWAP1", + "source": 0 + }, + { + "begin": 0, + "end": 125, + "name": "DUP2", + "source": 0 + }, + { + "begin": 0, + "end": 125, + "name": "PUSH [$]", + "source": 0, + "value": "0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "begin": 0, + "end": 125, + "name": "DUP3", + "source": 0 + }, + { + "begin": 0, + "end": 125, + "name": "CODECOPY", + "source": 0 + }, + { + "begin": 0, + "end": 125, + "name": "RETURN", + "source": 0 + }, + { + "begin": 0, + "end": 125, + "name": "tag", + "source": 0, + "value": "1" + }, + { + "begin": 0, + "end": 125, + "name": "JUMPDEST", + "source": 0 + }, + { + "begin": 0, + "end": 125, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { + "begin": 0, + "end": 125, + "name": "DUP1", + "source": 0 + }, + { + "begin": 0, + "end": 125, + "name": "REVERT", + "source": 0 + } + ], + ".data": { + "0": { + ".auxdata": "1234abcd", + ".code": [ + { + "begin": 0, + "end": 125, + "name": "PUSH", + "source": 0, + "value": "80" + }, + { + "begin": 0, + "end": 125, + "name": "DUP1", + "source": 0 + }, + { + "begin": 0, + "end": 125, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { + "begin": 0, + "end": 125, + "name": "MSTORE", + "source": 0 + }, + { + "begin": 0, + "end": 125, + "name": "PUSH", + "source": 0, + "value": "4" + }, + { + "begin": 0, + "end": 125, + "name": "CALLDATASIZE", + "source": 0 + }, + { + "begin": 0, + "end": 125, + "name": "LT", + "source": 0 + }, + { + "begin": 0, + "end": 125, + "name": "ISZERO", + "source": 0 + }, + { + "begin": 0, + "end": 125, + "name": "PUSH [tag]", + "source": 0, + "value": "1" + }, + { + "begin": 0, + "end": 125, + "name": "JUMPI", + "source": 0 + }, + { + "begin": -1, + "end": -1, + "name": "tag", + "source": -1, + "value": "2" + }, + { + "begin": -1, + "end": -1, + "name": "JUMPDEST", + "source": -1 + }, + { + "begin": 0, + "end": 125, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { + "begin": 0, + "end": 125, + "name": "DUP1", + "source": 0 + }, + { + "begin": 0, + "end": 125, + "name": "REVERT", + "source": 0 + }, + { + "begin": 0, + "end": 125, + "name": "tag", + "source": 0, + "value": "1" + }, + { + "begin": 0, + "end": 125, + "name": "JUMPDEST", + "source": 0 + }, + { + "begin": 0, + "end": 125, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { + "begin": 0, + "end": 125, + "name": "CALLDATALOAD", + "source": 0 + }, + { + "begin": 0, + "end": 125, + "name": "PUSH", + "source": 0, + "value": "E0" + }, + { + "begin": 0, + "end": 125, + "name": "SHR", + "source": 0 + }, + { + "begin": 0, + "end": 125, + "name": "PUSH", + "source": 0, + "value": "B4F40C61" + }, + { + "begin": 0, + "end": 125, + "name": "SUB", + "source": 0 + }, + { + "begin": 0, + "end": 125, + "name": "PUSH [tag]", + "source": 0, + "value": "2" + }, + { + "begin": 0, + "end": 125, + "name": "JUMPI", + "source": 0 + }, + { + "begin": 0, + "end": 125, + "name": "PUSH", + "source": 0, + "value": "20" + }, + { + "begin": 0, + "end": 125, + "name": "SWAP1", + "source": 0 + }, + { + "begin": 40, + "end": 57, + "name": "PUSH", + "source": 0, + "value": "1" + }, + { + "begin": 0, + "end": 125, + "name": "SLOAD", + "source": 0 + }, + { + "begin": 0, + "end": 125, + "name": "DUP2", + "source": 0 + }, + { + "begin": 0, + "end": 125, + "name": "MSTORE", + "source": 0 + }, + { + "begin": 0, + "end": 125, + "name": "RETURN", + "source": 0 + } + ] + } + }, + "sourceList": [ + "state_var_initialization.sol" + ] +} diff --git a/test/cmdlineTests/strict_asm_asm_json_with_debug_info_annotations/stdin b/test/cmdlineTests/strict_asm_asm_json_with_debug_info_annotations/stdin new file mode 100644 index 000000000000..d96989ec8393 --- /dev/null +++ b/test/cmdlineTests/strict_asm_asm_json_with_debug_info_annotations/stdin @@ -0,0 +1,40 @@ +/// @use-src 0:"state_var_initialization.sol" +object "C_23" { + code { + { + /// @src 0:0:125 "contract C {..." + let _1 := memoryguard(0x80) + mstore(64, _1) + if callvalue() { revert(0, 0) } + sstore(/** @src 0:33:34 "1" */ 0x00, /** @src 0:56:57 "2" */ 0x02) + /// @src 0:0:125 "contract C {..." + sstore(/** @src 0:33:34 "1" */ 0x01, 0x00) + /// @src 0:0:125 "contract C {..." + let _2 := datasize("C_23_deployed") + codecopy(_1, dataoffset("C_23_deployed"), _2) + return(_1, _2) + } + } + /// @use-src 0:"state_var_initialization.sol" + object "C_23_deployed" { + code { + { + /// @src 0:0:125 "contract C {..." + let _1 := memoryguard(0x80) + mstore(64, _1) + if iszero(lt(calldatasize(), 4)) + { + let _2 := 0 + switch shr(224, calldataload(_2)) + case 0xb4f40c61 { + mstore(_1, sload(/** @src 0:40:57 "uint public k = 2" */ 1)) + /// @src 0:0:125 "contract C {..." + return(_1, 32) + } + } + revert(0, 0) + } + } + data ".metadata" hex"1234abcd" + } +} diff --git a/test/cmdlineTests/strict_asm_asm_json_without_debug_info_annotations/args b/test/cmdlineTests/strict_asm_asm_json_without_debug_info_annotations/args new file mode 100644 index 000000000000..bf9bf8851a8c --- /dev/null +++ b/test/cmdlineTests/strict_asm_asm_json_without_debug_info_annotations/args @@ -0,0 +1 @@ +--strict-assembly - --asm-json --pretty-json --json-indent 4 diff --git a/test/cmdlineTests/strict_asm_asm_json_without_debug_info_annotations/output b/test/cmdlineTests/strict_asm_asm_json_without_debug_info_annotations/output new file mode 100644 index 000000000000..25fb482d484e --- /dev/null +++ b/test/cmdlineTests/strict_asm_asm_json_without_debug_info_annotations/output @@ -0,0 +1,384 @@ + +======= (EVM) ======= + +EVM assembly: +{ + ".code": [ + { + "begin": -1, + "end": -1, + "name": "PUSH", + "source": -1, + "value": "80" + }, + { + "begin": -1, + "end": -1, + "name": "DUP1", + "source": -1 + }, + { + "begin": -1, + "end": -1, + "name": "PUSH", + "source": -1, + "value": "40" + }, + { + "begin": -1, + "end": -1, + "name": "MSTORE", + "source": -1 + }, + { + "begin": -1, + "end": -1, + "name": "CALLVALUE", + "source": -1 + }, + { + "begin": -1, + "end": -1, + "name": "PUSH [tag]", + "source": -1, + "value": "1" + }, + { + "begin": -1, + "end": -1, + "name": "JUMPI", + "source": -1 + }, + { + "begin": -1, + "end": -1, + "name": "PUSH", + "source": -1, + "value": "2" + }, + { + "begin": -1, + "end": -1, + "name": "PUSH", + "source": -1, + "value": "0" + }, + { + "begin": -1, + "end": -1, + "name": "SSTORE", + "source": -1 + }, + { + "begin": -1, + "end": -1, + "name": "PUSH", + "source": -1, + "value": "0" + }, + { + "begin": -1, + "end": -1, + "name": "PUSH", + "source": -1, + "value": "1" + }, + { + "begin": -1, + "end": -1, + "name": "SSTORE", + "source": -1 + }, + { + "begin": -1, + "end": -1, + "name": "PUSH #[$]", + "source": -1, + "value": "0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "begin": -1, + "end": -1, + "name": "SWAP1", + "source": -1 + }, + { + "begin": -1, + "end": -1, + "name": "DUP2", + "source": -1 + }, + { + "begin": -1, + "end": -1, + "name": "PUSH [$]", + "source": -1, + "value": "0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "begin": -1, + "end": -1, + "name": "DUP3", + "source": -1 + }, + { + "begin": -1, + "end": -1, + "name": "CODECOPY", + "source": -1 + }, + { + "begin": -1, + "end": -1, + "name": "RETURN", + "source": -1 + }, + { + "begin": -1, + "end": -1, + "name": "tag", + "source": -1, + "value": "1" + }, + { + "begin": -1, + "end": -1, + "name": "JUMPDEST", + "source": -1 + }, + { + "begin": -1, + "end": -1, + "name": "PUSH", + "source": -1, + "value": "0" + }, + { + "begin": -1, + "end": -1, + "name": "DUP1", + "source": -1 + }, + { + "begin": -1, + "end": -1, + "name": "REVERT", + "source": -1 + } + ], + ".data": { + "0": { + ".auxdata": "1234abcd", + ".code": [ + { + "begin": 469, + "end": 486, + "name": "PUSH", + "source": -1, + "value": "80" + }, + { + "begin": 503, + "end": 517, + "name": "DUP1", + "source": -1 + }, + { + "begin": 510, + "end": 512, + "name": "PUSH", + "source": -1, + "value": "40" + }, + { + "begin": 503, + "end": 517, + "name": "MSTORE", + "source": -1 + }, + { + "begin": 563, + "end": 564, + "name": "PUSH", + "source": -1, + "value": "4" + }, + { + "begin": 547, + "end": 561, + "name": "CALLDATASIZE", + "source": -1 + }, + { + "begin": 544, + "end": 565, + "name": "LT", + "source": -1 + }, + { + "begin": 537, + "end": 566, + "name": "ISZERO", + "source": -1 + }, + { + "begin": 534, + "end": 832, + "name": "PUSH [tag]", + "source": -1, + "value": "1" + }, + { + "begin": 534, + "end": 832, + "name": "JUMPI", + "source": -1 + }, + { + "begin": 427, + "end": 885, + "name": "tag", + "source": -1, + "value": "2" + }, + { + "begin": 427, + "end": 885, + "name": "JUMPDEST", + "source": -1 + }, + { + "begin": 859, + "end": 860, + "name": "PUSH", + "source": -1, + "value": "0" + }, + { + "begin": 849, + "end": 861, + "name": "DUP1", + "source": -1 + }, + { + "begin": 849, + "end": 861, + "name": "REVERT", + "source": -1 + }, + { + "begin": 583, + "end": 832, + "name": "tag", + "source": -1, + "value": "1" + }, + { + "begin": 583, + "end": 832, + "name": "JUMPDEST", + "source": -1 + }, + { + "begin": 615, + "end": 616, + "name": "PUSH", + "source": -1, + "value": "0" + }, + { + "begin": 653, + "end": 669, + "name": "CALLDATALOAD", + "source": -1 + }, + { + "begin": 648, + "end": 651, + "name": "PUSH", + "source": -1, + "value": "E0" + }, + { + "begin": 644, + "end": 670, + "name": "SHR", + "source": -1 + }, + { + "begin": 696, + "end": 706, + "name": "PUSH", + "source": -1, + "value": "B4F40C61" + }, + { + "begin": 691, + "end": 814, + "name": "SUB", + "source": -1 + }, + { + "begin": 583, + "end": 832, + "name": "PUSH [tag]", + "source": -1, + "value": "2" + }, + { + "begin": 691, + "end": 814, + "name": "JUMPI", + "source": -1 + }, + { + "begin": 789, + "end": 791, + "name": "PUSH", + "source": -1, + "value": "20" + }, + { + "begin": 744, + "end": 752, + "name": "SWAP1", + "source": -1 + }, + { + "begin": 750, + "end": 751, + "name": "PUSH", + "source": -1, + "value": "1" + }, + { + "begin": 744, + "end": 752, + "name": "SLOAD", + "source": -1 + }, + { + "begin": 733, + "end": 753, + "name": "DUP2", + "source": -1 + }, + { + "begin": 733, + "end": 753, + "name": "MSTORE", + "source": -1 + }, + { + "begin": 778, + "end": 792, + "name": "RETURN", + "source": -1 + } + ] + } + }, + "sourceList": [ + "abc.sol" + ] +} diff --git a/test/cmdlineTests/strict_asm_asm_json_without_debug_info_annotations/stdin b/test/cmdlineTests/strict_asm_asm_json_without_debug_info_annotations/stdin new file mode 100644 index 000000000000..72c1b650c360 --- /dev/null +++ b/test/cmdlineTests/strict_asm_asm_json_without_debug_info_annotations/stdin @@ -0,0 +1,34 @@ +/// @use-src 0: "abc.sol" +object "C_23" { + code { + { + let _1 := memoryguard(0x80) + mstore(64, _1) + if callvalue() { revert(0, 0) } + sstore(0x00, 0x02) + sstore(0x01, 0x00) + let _2 := datasize("C_23_deployed") + codecopy(_1, dataoffset("C_23_deployed"), _2) + return(_1, _2) + } + } + object "C_23_deployed" { + code { + { + let _1 := memoryguard(0x80) + mstore(64, _1) + if iszero(lt(calldatasize(), 4)) + { + let _2 := 0 + switch shr(224, calldataload(_2)) + case 0xb4f40c61 { + mstore(_1, sload(1)) + return(_1, 32) + } + } + revert(0, 0) + } + } + data ".metadata" hex"1234abcd" + } +} diff --git a/test/cmdlineTests/strict_asm_asm_json_yul_verbatim/args b/test/cmdlineTests/strict_asm_asm_json_yul_verbatim/args new file mode 100644 index 000000000000..bf9bf8851a8c --- /dev/null +++ b/test/cmdlineTests/strict_asm_asm_json_yul_verbatim/args @@ -0,0 +1 @@ +--strict-assembly - --asm-json --pretty-json --json-indent 4 diff --git a/test/cmdlineTests/strict_asm_asm_json_yul_verbatim/output b/test/cmdlineTests/strict_asm_asm_json_yul_verbatim/output new file mode 100644 index 000000000000..454f4a6d2d7b --- /dev/null +++ b/test/cmdlineTests/strict_asm_asm_json_yul_verbatim/output @@ -0,0 +1,18 @@ + +======= (EVM) ======= + +EVM assembly: +{ + ".code": [ + { + "begin": -1, + "end": -1, + "name": "VERBATIM", + "source": -1, + "value": "78797a" + } + ], + "sourceList": [ + "abc.sol" + ] +} diff --git a/test/cmdlineTests/strict_asm_asm_json_yul_verbatim/stdin b/test/cmdlineTests/strict_asm_asm_json_yul_verbatim/stdin new file mode 100644 index 000000000000..2dab36854801 --- /dev/null +++ b/test/cmdlineTests/strict_asm_asm_json_yul_verbatim/stdin @@ -0,0 +1,4 @@ +/// @use-src 0: "abc.sol" +{ + verbatim_0i_0o("xyz") +} diff --git a/test/cmdlineTests/strict_asm_output_selection_invalid/err b/test/cmdlineTests/strict_asm_output_selection_invalid/err index 81d6eff8ae72..90fd9470461f 100644 --- a/test/cmdlineTests/strict_asm_output_selection_invalid/err +++ b/test/cmdlineTests/strict_asm_output_selection_invalid/err @@ -1 +1 @@ -Error: The following outputs are not supported in assembler mode: --abi, --asm-json, --bin-runtime, --devdoc, --hashes, --ir, --metadata, --opcodes, --storage-layout, --userdoc. +Error: The following outputs are not supported in assembler mode: --abi, --bin-runtime, --devdoc, --hashes, --ir, --metadata, --opcodes, --storage-layout, --userdoc. diff --git a/test/libyul/ObjectCompilerTest.cpp b/test/libyul/ObjectCompilerTest.cpp index 65ff18a768de..5d6dd1b23dea 100644 --- a/test/libyul/ObjectCompilerTest.cpp +++ b/test/libyul/ObjectCompilerTest.cpp @@ -26,8 +26,9 @@ #include -#include +#include #include +#include #include #include @@ -83,7 +84,7 @@ TestCase::TestResult ObjectCompilerTest::run(std::ostream& _stream, std::string solAssert(obj.bytecode, ""); solAssert(obj.sourceMappings, ""); - m_obtainedResult = "Assembly:\n" + obj.assembly; + m_obtainedResult = "Assembly:\n" + obj.assembly->assemblyString(stack.debugInfoSelection()); if (obj.bytecode->bytecode.empty()) m_obtainedResult += "-- empty bytecode --\n"; else diff --git a/test/libyul/objectCompiler/sourceLocations.yul b/test/libyul/objectCompiler/sourceLocations.yul index 1c84773249d7..883e85b040e6 100644 --- a/test/libyul/objectCompiler/sourceLocations.yul +++ b/test/libyul/objectCompiler/sourceLocations.yul @@ -1,28 +1,28 @@ // something else /*-- another unrelated comment --*/ -/// @use-src 3: "abc.sol" , 2: "def.sol" +/// @use-src 1: "abc.sol" , 0: "def.sol" object "a" { code { - /// @src 3:0:2 + /// @src 1:0:2 datacopy(0, dataoffset("sub"), datasize("sub")) return(0, - /** @src 2:5:6 */ + /** @src 0:5:6 */ datasize("sub") ) } - /// @use-src 3: "abc.sol" , 2: "def.sol" + /// @use-src 1: "abc.sol" , 0: "def.sol" object "sub" { code { - /// @src 2:70:72 + /// @src 0:70:72 sstore(0, dataoffset("sub")) /** * @something else - * @src 3:2:5 + * @src 1:2:5 */ mstore( 0, datasize("data1") - /// @src 3:90:2 + /// @src 1:90:2 ) } data "data1" "Hello, World!" diff --git a/test/solc/CommandLineParser.cpp b/test/solc/CommandLineParser.cpp index 9fe24bcc662f..2ba1d43c8746 100644 --- a/test/solc/CommandLineParser.cpp +++ b/test/solc/CommandLineParser.cpp @@ -310,6 +310,7 @@ BOOST_AUTO_TEST_CASE(assembly_mode_options) "dir1/file1.sol:L=0x1234567890123456789012345678901234567890," "dir2/file2.sol:L=0x1111122222333334444455555666667777788888", "--asm", + "--asm-json", "--bin", "--ir-optimized", "--ast-compact-json", @@ -350,6 +351,7 @@ BOOST_AUTO_TEST_CASE(assembly_mode_options) expectedOptions.formatting.coloredOutput = false; expectedOptions.formatting.withErrorIds = true; expectedOptions.compiler.outputs.asm_ = true; + expectedOptions.compiler.outputs.asmJson = true; expectedOptions.compiler.outputs.binary = true; expectedOptions.compiler.outputs.irOptimized = true; expectedOptions.compiler.outputs.astCompactJson = true; From c458c3ec32d99e95fdbcc5fc7073aed840ad9f70 Mon Sep 17 00:00:00 2001 From: Martin Blicha Date: Wed, 31 Jul 2024 15:05:11 +0200 Subject: [PATCH 0322/1022] SMTChecker: Use pipe instead of temporary file in solver interface Since version 2.1 (released in March 2024) Eldarica supports reading input from standard input. We can therefore update SMTSolverCommand to interact with the solver using pipe instead of creating temporary file on which the solver runs. cvc5 also supports this, and does not require any extra flags to enable this feature. --- libsolidity/interface/SMTSolverCommand.cpp | 30 ++++++++-------------- 1 file changed, 11 insertions(+), 19 deletions(-) diff --git a/libsolidity/interface/SMTSolverCommand.cpp b/libsolidity/interface/SMTSolverCommand.cpp index 1eaa3f38cae7..0558223d66fa 100644 --- a/libsolidity/interface/SMTSolverCommand.cpp +++ b/libsolidity/interface/SMTSolverCommand.cpp @@ -19,15 +19,7 @@ #include -#include -#include -#include -#include - #include -#include -#include -#include #include namespace solidity::frontend @@ -37,6 +29,8 @@ void SMTSolverCommand::setEldarica(std::optional timeoutInMillisec { m_arguments.clear(); m_solverCmd = "eld"; + m_arguments.emplace_back("-hsmt"); + m_arguments.emplace_back("-in"); if (timeoutInMilliseconds) { unsigned int timeoutInSeconds = timeoutInMilliseconds.value() / 1000u; @@ -73,32 +67,30 @@ ReadCallback::Result SMTSolverCommand::solve(std::string const& _kind, std::stri if (m_solverCmd.empty()) return ReadCallback::Result{false, "No solver set."}; - auto tempDir = solidity::util::TemporaryDirectory("smt"); - util::h256 queryHash = util::keccak256(_query); - auto queryFileName = tempDir.path() / ("query_" + queryHash.hex() + ".smt2"); - - auto queryFile = boost::filesystem::ofstream(queryFileName); - queryFile << _query << std::flush; - auto solverBin = boost::process::search_path(m_solverCmd); if (solverBin.empty()) return ReadCallback::Result{false, m_solverCmd + " binary not found."}; auto args = m_arguments; - args.push_back(queryFileName.string()); - boost::process::ipstream pipe; + boost::process::opstream in; // input to subprocess written to by the main process + boost::process::ipstream out; // output from subprocess read by the main process boost::process::child solverProcess( solverBin, args, - boost::process::std_out > pipe, + boost::process::std_out > out, + boost::process::std_in < in, boost::process::std_err > boost::process::null ); + in << _query << std::flush; + in.pipe().close(); + in.close(); + std::vector data; std::string line; - while (solverProcess.running() && std::getline(pipe, line)) + while (solverProcess.running() && std::getline(out, line)) if (!line.empty()) data.push_back(line); From b4917bbc2d8bf37aa9f07958c04857878cf9dfdb Mon Sep 17 00:00:00 2001 From: Martin Blicha Date: Sun, 21 Jul 2024 23:40:16 +0200 Subject: [PATCH 0323/1022] SMTChecker: Do not prematurely end reading solver's response When the main process reads an answer from the solver, it can happen that the solver process has already finished, while the main process is not yet done with reading the output from the pipe. In rare occasions, the caused some test to fail, because SMTChecker could not produced the expected counterexample from partial answer. --- libsolidity/interface/SMTSolverCommand.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libsolidity/interface/SMTSolverCommand.cpp b/libsolidity/interface/SMTSolverCommand.cpp index 0558223d66fa..dd62d2c28dec 100644 --- a/libsolidity/interface/SMTSolverCommand.cpp +++ b/libsolidity/interface/SMTSolverCommand.cpp @@ -90,7 +90,7 @@ ReadCallback::Result SMTSolverCommand::solve(std::string const& _kind, std::stri std::vector data; std::string line; - while (solverProcess.running() && std::getline(out, line)) + while (!(out.fail() || out.eof()) && std::getline(out, line)) if (!line.empty()) data.push_back(line); From ecfe63a08408dcd56bae82fbcaab452dd3cbe1e4 Mon Sep 17 00:00:00 2001 From: Martin Blicha Date: Wed, 31 Jul 2024 22:58:14 +0200 Subject: [PATCH 0324/1022] SMTChecker: Explain command-line arguments of individual solvers --- libsolidity/interface/SMTSolverCommand.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/libsolidity/interface/SMTSolverCommand.cpp b/libsolidity/interface/SMTSolverCommand.cpp index dd62d2c28dec..8120e1f11aca 100644 --- a/libsolidity/interface/SMTSolverCommand.cpp +++ b/libsolidity/interface/SMTSolverCommand.cpp @@ -29,8 +29,8 @@ void SMTSolverCommand::setEldarica(std::optional timeoutInMillisec { m_arguments.clear(); m_solverCmd = "eld"; - m_arguments.emplace_back("-hsmt"); - m_arguments.emplace_back("-in"); + m_arguments.emplace_back("-hsmt"); // Tell Eldarica to expect input in SMT2 format + m_arguments.emplace_back("-in"); // Tell Eldarica to read from standard input if (timeoutInMilliseconds) { unsigned int timeoutInSeconds = timeoutInMilliseconds.value() / 1000u; @@ -38,7 +38,7 @@ void SMTSolverCommand::setEldarica(std::optional timeoutInMillisec m_arguments.push_back("-t:" + std::to_string(timeoutInSeconds)); } if (computeInvariants) - m_arguments.emplace_back("-ssol"); + m_arguments.emplace_back("-ssol"); // Tell Eldarica to produce model (invariant) } void SMTSolverCommand::setCvc5(std::optional timeoutInMilliseconds) @@ -47,12 +47,12 @@ void SMTSolverCommand::setCvc5(std::optional timeoutInMilliseconds m_solverCmd = "cvc5"; if (timeoutInMilliseconds) { - m_arguments.push_back("--tlimit-per"); + m_arguments.emplace_back("--tlimit-per"); m_arguments.push_back(std::to_string(timeoutInMilliseconds.value())); } else { - m_arguments.push_back("--rlimit"); + m_arguments.emplace_back("--rlimit"); // Set resource limit cvc5 can spend on a query m_arguments.push_back(std::to_string(12000)); } } From c5685e70544c86f25d87b93048a8bffa963177c6 Mon Sep 17 00:00:00 2001 From: Matheus Aguiar Date: Mon, 24 Jun 2024 15:53:45 -0300 Subject: [PATCH 0325/1022] generate transient storage layout --- Changelog.md | 2 + docs/internals/layout_in_storage.rst | 14 +- docs/using-the-compiler.rst | 5 +- libsolidity/analysis/TypeChecker.cpp | 7 - libsolidity/ast/Types.cpp | 22 ++- libsolidity/ast/Types.h | 4 +- libsolidity/codegen/Compiler.cpp | 12 ++ libsolidity/codegen/ir/IRGenerator.cpp | 12 ++ libsolidity/interface/CompilerStack.cpp | 17 +- libsolidity/interface/CompilerStack.h | 9 + libsolidity/interface/StandardCompiler.cpp | 2 + libsolidity/interface/StorageLayout.cpp | 7 +- libsolidity/interface/StorageLayout.h | 5 +- solc/CommandLineInterface.cpp | 20 ++- solc/CommandLineInterface.h | 1 + solc/CommandLineParser.cpp | 6 +- solc/CommandLineParser.h | 4 + .../output.json | 4 + .../input.json | 2 +- .../output.json | 159 +++++++++++------- .../transient_storage_layout/args | 1 + .../transient_storage_layout/input.sol | 13 ++ .../transient_storage_layout/output | 67 ++++++++ .../input.json | 15 ++ .../output.json | 17 ++ .../input.json | 21 +++ .../output.json | 51 ++++++ .../in.sol | 23 +++ .../input.json | 13 ++ .../output.json | 123 ++++++++++++++ .../in.sol | 15 ++ .../input.json | 13 ++ .../output.json | 155 +++++++++++++++++ .../in.sol | 24 +++ .../input.json | 13 ++ .../output.json | 131 +++++++++++++++ .../transient_data_location.sol | 14 ++ .../transient_storage_state_variable.sol | 2 +- .../dataLocations/transient_function_type.sol | 7 +- .../transient_state_variable_visibility.sol | 7 +- .../transient_value_type_state_variables.sol | 6 +- ..._value_type_state_variables_assignment.sol | 4 +- test/solc/CommandLineParser.cpp | 9 +- 43 files changed, 948 insertions(+), 110 deletions(-) create mode 100644 test/cmdlineTests/transient_storage_layout/args create mode 100644 test/cmdlineTests/transient_storage_layout/input.sol create mode 100644 test/cmdlineTests/transient_storage_layout/output create mode 100644 test/cmdlineTests/transient_storage_layout_smoke_empty/input.json create mode 100644 test/cmdlineTests/transient_storage_layout_smoke_empty/output.json create mode 100644 test/cmdlineTests/transient_storage_layout_smoke_two_contracts/input.json create mode 100644 test/cmdlineTests/transient_storage_layout_smoke_two_contracts/output.json create mode 100644 test/cmdlineTests/transient_storage_layout_value_types/in.sol create mode 100644 test/cmdlineTests/transient_storage_layout_value_types/input.json create mode 100644 test/cmdlineTests/transient_storage_layout_value_types/output.json create mode 100644 test/cmdlineTests/transient_storage_layout_value_types_interleaved_with_storage/in.sol create mode 100644 test/cmdlineTests/transient_storage_layout_value_types_interleaved_with_storage/input.json create mode 100644 test/cmdlineTests/transient_storage_layout_value_types_interleaved_with_storage/output.json create mode 100644 test/cmdlineTests/transient_storage_layout_value_types_packed/in.sol create mode 100644 test/cmdlineTests/transient_storage_layout_value_types_packed/input.json create mode 100644 test/cmdlineTests/transient_storage_layout_value_types_packed/output.json create mode 100644 test/libsolidity/astPropertyTests/transient_data_location.sol diff --git a/Changelog.md b/Changelog.md index 9c9a9e8fd91b..8acee7422b3d 100644 --- a/Changelog.md +++ b/Changelog.md @@ -8,11 +8,13 @@ Language Features: Compiler Features: * Command Line Interface: Do not perform IR optimization when only unoptimized IR is requested. + * Commandline Interface: Add ``--transient-storage-layout`` output. * Error Reporting: Unimplemented features are now properly reported as errors instead of being handled as if they were bugs. * EVM: Support for the EVM version "Prague". * SMTChecker: Add CHC engine check for underflow and overflow in unary minus operation. * SMTChecker: Replace CVC4 as a possible BMC backend with cvc5. * Standard JSON Interface: Do not perform IR optimization when only unoptimized IR is requested. + * Standard JSON Interface: Add ``transientStorageLayout`` output. * Yul Optimizer: The optimizer now treats some previously unrecognized identical literals as identical. * Commandline Interface: Allow the use of ``--asm-json`` output option in assembler mode to export EVM assembly of the contracts in JSON format. diff --git a/docs/internals/layout_in_storage.rst b/docs/internals/layout_in_storage.rst index 7afcfc2ac5c0..f6b10adeef78 100644 --- a/docs/internals/layout_in_storage.rst +++ b/docs/internals/layout_in_storage.rst @@ -1,11 +1,17 @@ -.. index:: storage, state variable, mapping +.. index:: storage, state variable, mapping, transient storage -************************************ -Layout of State Variables in Storage -************************************ +********************************************************** +Layout of State Variables in Storage and Transient Storage +********************************************************** .. _storage-inplace-encoding: +.. note:: + The rules described in this section apply for both storage and transient storage data locations. + The layouts are completely independent and don't interfere with each other's variable locations. + Thus storage and transient storage state variables can be safely interleaved without any side effects. + Only value types are supported for transient storage. + State variables of contracts are stored in storage in a compact way such that multiple values sometimes use the same storage slot. Except for dynamically-sized arrays and mappings (see below), data is stored diff --git a/docs/using-the-compiler.rst b/docs/using-the-compiler.rst index a306fa835d97..97994e1326ff 100644 --- a/docs/using-the-compiler.rst +++ b/docs/using-the-compiler.rst @@ -423,7 +423,8 @@ Input Description // irAst - AST of Yul intermediate representation of the code before optimization // irOptimized - Intermediate representation after optimization // irOptimizedAst - AST of intermediate representation after optimization - // storageLayout - Slots, offsets and types of the contract's state variables. + // storageLayout - Slots, offsets and types of the contract's state variables in storage. + // transientStorageLayout - Slots, offsets and types of the contract's state variables in transient storage. // evm.assembly - New assembly format // evm.legacyAssembly - Old-style assembly format in JSON // evm.bytecode.functionDebugData - Debugging information at function level @@ -578,6 +579,8 @@ Output Description "irOptimizedAst": {/* ... */}, // See the Storage Layout documentation. "storageLayout": {"storage": [/* ... */], "types": {/* ... */} }, + // See the Storage Layout documentation. + "transientStorageLayout": {"storage": [/* ... */], "types": {/* ... */} }, // EVM-related outputs "evm": { // Assembly (string) diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp index dfd334295a2a..918e27033329 100644 --- a/libsolidity/analysis/TypeChecker.cpp +++ b/libsolidity/analysis/TypeChecker.cpp @@ -478,13 +478,6 @@ bool TypeChecker::visit(VariableDeclaration const& _variable) Type const* varType = _variable.annotation().type; solAssert(!!varType, "Variable type not provided."); - if (_variable.referenceLocation() == VariableDeclaration::Location::Transient) - m_errorReporter.unimplementedFeatureError( - 6715_error, - _variable.location(), - "Transient storage is not yet implemented." - ); - if (_variable.value()) { if (_variable.isStateVariable() && varType->containsNestedMapping()) diff --git a/libsolidity/ast/Types.cpp b/libsolidity/ast/Types.cpp index a37cc78a4162..f6e2a54138b3 100644 --- a/libsolidity/ast/Types.cpp +++ b/libsolidity/ast/Types.cpp @@ -2140,12 +2140,30 @@ FunctionType const* ContractType::newExpressionType() const return m_constructorType; } -std::vector> ContractType::stateVariables() const +std::vector> ContractType::stateVariables(std::optional _location) const { + std::optional location; + if (_location.has_value()) + { + switch (_location.value()) + { + case DataLocation::Storage: + location = std::make_optional(VariableDeclaration::Location::Unspecified); // By default state variables have unspecified (storage) data location + break; + case DataLocation::Transient: + location = std::make_optional(VariableDeclaration::Location::Transient); + break; + default: solAssert(false); + } + } + std::vector variables; for (ContractDefinition const* contract: m_contract.annotation().linearizedBaseContracts | ranges::views::reverse) for (VariableDeclaration const* variable: contract->stateVariables()) - if (!(variable->isConstant() || variable->immutable())) + if ( + !(variable->isConstant() || variable->immutable()) && + variable->referenceLocation() == location.value_or(variable->referenceLocation()) + ) variables.push_back(variable); TypePointers types; for (auto variable: variables) diff --git a/libsolidity/ast/Types.h b/libsolidity/ast/Types.h index 1817c97af4dd..5a5040c40dd2 100644 --- a/libsolidity/ast/Types.h +++ b/libsolidity/ast/Types.h @@ -1001,8 +1001,8 @@ class ContractType: public Type FunctionType const* newExpressionType() const; /// @returns a list of all state variables (including inherited) of the contract and their - /// offsets in storage. - std::vector> stateVariables() const; + /// offsets in storage/transient storage. + std::vector> stateVariables(std::optional _location = std::nullopt) const; /// @returns a list of all immutable variables (including inherited) of the contract. std::vector immutableVariables() const; protected: diff --git a/libsolidity/codegen/Compiler.cpp b/libsolidity/codegen/Compiler.cpp index 844de8ba82c6..07b65fcc8c53 100644 --- a/libsolidity/codegen/Compiler.cpp +++ b/libsolidity/codegen/Compiler.cpp @@ -26,6 +26,8 @@ #include #include +#include + using namespace solidity; using namespace solidity::frontend; @@ -35,6 +37,16 @@ void Compiler::compileContract( bytes const& _metadata ) { + auto static notTransient = [](VariableDeclaration const* _varDeclaration) { + solAssert(_varDeclaration); + return _varDeclaration->referenceLocation() != VariableDeclaration::Location::Transient; + }; + + solUnimplementedAssert( + ranges::all_of(_contract.stateVariables(), notTransient), + "Transient storage variables are not supported." + ); + ContractCompiler runtimeCompiler(nullptr, m_runtimeContext, m_optimiserSettings); runtimeCompiler.compileContract(_contract, _otherCompilers); m_runtimeContext.appendToAuxiliaryData(_metadata); diff --git a/libsolidity/codegen/ir/IRGenerator.cpp b/libsolidity/codegen/ir/IRGenerator.cpp index bf0f6d5c0f25..00c9fa196bd8 100644 --- a/libsolidity/codegen/ir/IRGenerator.cpp +++ b/libsolidity/codegen/ir/IRGenerator.cpp @@ -39,6 +39,8 @@ #include #include +#include + #include #include @@ -101,6 +103,16 @@ std::string IRGenerator::generate( std::map const& _otherYulSources ) { + auto notTransient = [](VariableDeclaration const* _varDeclaration) { + solAssert(_varDeclaration); + return _varDeclaration->referenceLocation() != VariableDeclaration::Location::Transient; + }; + + solUnimplementedAssert( + ranges::all_of(_contract.stateVariables(), notTransient), + "Transient storage variables are not supported." + ); + auto subObjectSources = [&_otherYulSources](UniqueVector const& _subObjects) -> std::string { std::string subObjectsSources; diff --git a/libsolidity/interface/CompilerStack.cpp b/libsolidity/interface/CompilerStack.cpp index f2c37fa68523..de7b185d295e 100644 --- a/libsolidity/interface/CompilerStack.cpp +++ b/libsolidity/interface/CompilerStack.cpp @@ -1015,7 +1015,22 @@ Json const& CompilerStack::storageLayout(Contract const& _contract) const solAssert(_contract.contract); solUnimplementedAssert(!isExperimentalSolidity()); - return _contract.storageLayout.init([&]{ return StorageLayout().generate(*_contract.contract); }); + return _contract.storageLayout.init([&]{ return StorageLayout().generate(*_contract.contract, DataLocation::Storage); }); +} + +Json const& CompilerStack::transientStorageLayout(std::string const& _contractName) const +{ + solAssert(m_stackState >= AnalysisSuccessful, "Analysis was not successful."); + return transientStorageLayout(contract(_contractName)); +} + +Json const& CompilerStack::transientStorageLayout(Contract const& _contract) const +{ + solAssert(m_stackState >= AnalysisSuccessful, "Analysis was not successful."); + solAssert(_contract.contract); + solUnimplementedAssert(!isExperimentalSolidity()); + + return _contract.transientStorageLayout.init([&]{ return StorageLayout().generate(*_contract.contract, DataLocation::Transient); }); } Json const& CompilerStack::natspecUser(std::string const& _contractName) const diff --git a/libsolidity/interface/CompilerStack.h b/libsolidity/interface/CompilerStack.h index 2c5ecb132b94..159a14d8d84d 100644 --- a/libsolidity/interface/CompilerStack.h +++ b/libsolidity/interface/CompilerStack.h @@ -338,6 +338,10 @@ class CompilerStack: public langutil::CharStreamProvider, public evmasm::Abstrac /// Prerequisite: Successful call to parse or compile. Json const& storageLayout(std::string const& _contractName) const; + /// @returns a JSON representing the transient storage layout of the contract. + /// Prerequisite: Successful call to parse or compile. + Json const& transientStorageLayout(std::string const& _contractName) const; + /// @returns a JSON representing the contract's user documentation. /// Prerequisite: Successful call to parse or compile. Json const& natspecUser(std::string const& _contractName) const; @@ -406,6 +410,7 @@ class CompilerStack: public langutil::CharStreamProvider, public evmasm::Abstrac util::LazyInit metadata; ///< The metadata json that will be hashed into the chain. util::LazyInit abi; util::LazyInit storageLayout; + util::LazyInit transientStorageLayout; util::LazyInit userDocumentation; util::LazyInit devDocumentation; util::LazyInit generatedSources; @@ -502,6 +507,10 @@ class CompilerStack: public langutil::CharStreamProvider, public evmasm::Abstrac /// This will generate the JSON object and store it in the Contract object if it is not present yet. Json const& storageLayout(Contract const&) const; + /// @returns the transient storage layout of the contract as a JSON object. + /// This will generate the JSON object and store it in the Contract object if it is not present yet. + Json const& transientStorageLayout(Contract const&) const; + /// @returns the Natspec User documentation as a JSON object. /// This will generate the JSON object and store it in the Contract object if it is not present yet. Json const& natspecUser(Contract const&) const; diff --git a/libsolidity/interface/StandardCompiler.cpp b/libsolidity/interface/StandardCompiler.cpp index e4b9f9f7ae17..b209987ddd3f 100644 --- a/libsolidity/interface/StandardCompiler.cpp +++ b/libsolidity/interface/StandardCompiler.cpp @@ -1466,6 +1466,8 @@ Json StandardCompiler::compileSolidity(StandardCompiler::InputsAndSettings _inpu contractData["abi"] = compilerStack.contractABI(contractName); if (isArtifactRequested(_inputsAndSettings.outputSelection, file, name, "storageLayout", false)) contractData["storageLayout"] = compilerStack.storageLayout(contractName); + if (isArtifactRequested(_inputsAndSettings.outputSelection, file, name, "transientStorageLayout", false)) + contractData["transientStorageLayout"] = compilerStack.transientStorageLayout(contractName); if (isArtifactRequested(_inputsAndSettings.outputSelection, file, name, "metadata", wildcardMatchesExperimental)) contractData["metadata"] = compilerStack.metadata(contractName); if (isArtifactRequested(_inputsAndSettings.outputSelection, file, name, "userdoc", wildcardMatchesExperimental)) diff --git a/libsolidity/interface/StorageLayout.cpp b/libsolidity/interface/StorageLayout.cpp index 0153af1a293a..8565fec68f26 100644 --- a/libsolidity/interface/StorageLayout.cpp +++ b/libsolidity/interface/StorageLayout.cpp @@ -20,10 +20,11 @@ #include +using namespace std::literals; using namespace solidity; using namespace solidity::frontend; -Json StorageLayout::generate(ContractDefinition const& _contractDef) +Json StorageLayout::generate(ContractDefinition const& _contractDef, DataLocation const _location) { solAssert(!m_contract, ""); m_contract = &_contractDef; @@ -35,18 +36,18 @@ Json StorageLayout::generate(ContractDefinition const& _contractDef) solAssert(contractType, ""); Json variables = Json::array(); - for (auto [var, slot, offset]: contractType->stateVariables()) + for (auto [var, slot, offset]: contractType->stateVariables(_location)) variables.emplace_back(generate(*var, slot, offset)); Json layout; layout["storage"] = std::move(variables); layout["types"] = std::move(m_types); + return layout; } Json StorageLayout::generate(VariableDeclaration const& _var, u256 const& _slot, unsigned _offset) { - solUnimplementedAssert(_var.referenceLocation() != VariableDeclaration::Location::Transient, "Transient storage layout is not supported yet."); Json varEntry; Type const* varType = _var.type(); diff --git a/libsolidity/interface/StorageLayout.h b/libsolidity/interface/StorageLayout.h index b0b2d70b6df5..d3c7e2d9f8c7 100644 --- a/libsolidity/interface/StorageLayout.h +++ b/libsolidity/interface/StorageLayout.h @@ -16,7 +16,7 @@ */ // SPDX-License-Identifier: GPL-3.0 /** - * Generates the storage layout of a contract. + * Generates the storage/transient storage layout of a contract. */ #pragma once @@ -33,8 +33,9 @@ class StorageLayout public: /// Generates the storage layout of the contract /// @param _contractDef The contract definition + /// @param _location The location (storage or transient storage) for which to generate the layout /// @return A JSON representation of the contract's storage layout. - Json generate(ContractDefinition const& _contractDef); + Json generate(ContractDefinition const& _contractDef, DataLocation const _location); private: /// Generates the JSON information for a variable and its storage location. diff --git a/solc/CommandLineInterface.cpp b/solc/CommandLineInterface.cpp index 1351858405a1..02b6dcade295 100644 --- a/solc/CommandLineInterface.cpp +++ b/solc/CommandLineInterface.cpp @@ -135,6 +135,7 @@ static std::string const g_strSources = "sources"; static std::string const g_strSrcMap = "srcmap"; static std::string const g_strSrcMapRuntime = "srcmap-runtime"; static std::string const g_strStorageLayout = "storage-layout"; +static std::string const g_strTransientStorageLayout = "transient-storage-layout"; static std::string const g_strVersion = "version"; static bool needsHumanTargetedStdout(CommandLineOptions const& _options) @@ -154,7 +155,8 @@ static bool needsHumanTargetedStdout(CommandLineOptions const& _options) _options.compiler.outputs.natspecDev || _options.compiler.outputs.opcodes || _options.compiler.outputs.signatureHashes || - _options.compiler.outputs.storageLayout; + _options.compiler.outputs.storageLayout || + _options.compiler.outputs.transientStorageLayout; } static bool coloredOutput(CommandLineOptions const& _options) @@ -420,6 +422,19 @@ void CommandLineInterface::handleStorageLayout(std::string const& _contract) sout() << "Contract Storage Layout:" << std::endl << data << std::endl; } +void CommandLineInterface::handleTransientStorageLayout(std::string const& _contract) +{ + solAssert(CompilerInputModes.count(m_options.input.mode) == 1); + + if (!m_options.compiler.outputs.transientStorageLayout) + return; + std::string data = jsonPrint(removeNullMembers(m_compiler->transientStorageLayout(_contract)), m_options.formatting.json); + if (!m_options.output.dir.empty()) + createFile(m_compiler->filesystemFriendlyName(_contract) + "_transient_storage.json", data); + else + sout() << "Contract Transient Storage Layout:" << std::endl << data << std::endl; +} + void CommandLineInterface::handleNatspec(bool _natspecDev, std::string const& _contract) { solAssert(CompilerInputModes.count(m_options.input.mode) == 1); @@ -956,6 +971,8 @@ void CommandLineInterface::handleCombinedJSON() contractData["metadata"] = m_compiler->metadata(contractName); if (m_options.compiler.combinedJsonRequests->storageLayout) contractData[g_strStorageLayout] = m_compiler->storageLayout(contractName); + if (m_options.compiler.combinedJsonRequests->transientStorageLayout) + contractData[g_strTransientStorageLayout] = m_compiler->transientStorageLayout(contractName); if (m_options.compiler.combinedJsonRequests->generatedSources) contractData[g_strGeneratedSources] = m_compiler->generatedSources(contractName, false); if (m_options.compiler.combinedJsonRequests->generatedSourcesRuntime) @@ -1322,6 +1339,7 @@ void CommandLineInterface::outputCompilationResults() handleMetadata(contract); handleABI(contract); handleStorageLayout(contract); + handleTransientStorageLayout(contract); handleNatspec(true, contract); handleNatspec(false, contract); } // end of contracts iteration diff --git a/solc/CommandLineInterface.h b/solc/CommandLineInterface.h index bcebcbcfd3be..c23fd9e17b1f 100644 --- a/solc/CommandLineInterface.h +++ b/solc/CommandLineInterface.h @@ -115,6 +115,7 @@ class CommandLineInterface void handleNatspec(bool _natspecDev, std::string const& _contract); void handleGasEstimation(std::string const& _contract); void handleStorageLayout(std::string const& _contract); + void handleTransientStorageLayout(std::string const& _contract); /// Tries to read @ m_sourceCodes as a JSONs holding ASTs /// such that they can be imported into the compiler (importASTs()) diff --git a/solc/CommandLineParser.cpp b/solc/CommandLineParser.cpp index 881c656dad9b..97c6901400d7 100644 --- a/solc/CommandLineParser.cpp +++ b/solc/CommandLineParser.cpp @@ -760,7 +760,8 @@ General Information)").c_str(), (CompilerOutputs::componentName(&CompilerOutputs::natspecUser).c_str(), "Natspec user documentation of all contracts.") (CompilerOutputs::componentName(&CompilerOutputs::natspecDev).c_str(), "Natspec developer documentation of all contracts.") (CompilerOutputs::componentName(&CompilerOutputs::metadata).c_str(), "Combined Metadata JSON whose IPFS hash is stored on-chain.") - (CompilerOutputs::componentName(&CompilerOutputs::storageLayout).c_str(), "Slots, offsets and types of the contract's state variables.") + (CompilerOutputs::componentName(&CompilerOutputs::storageLayout).c_str(), "Slots, offsets and types of the contract's state variables located in storage.") + (CompilerOutputs::componentName(&CompilerOutputs::transientStorageLayout).c_str(), "Slots, offsets and types of the contract's state variables located in transient storage.") ; desc.add(outputComponents); @@ -1469,7 +1470,8 @@ void CommandLineParser::parseCombinedJsonOption() &CombinedJsonRequests::natspecDev, &CombinedJsonRequests::natspecUser, &CombinedJsonRequests::signatureHashes, - &CombinedJsonRequests::storageLayout + &CombinedJsonRequests::storageLayout, + &CombinedJsonRequests::transientStorageLayout }; for (auto const invalidOption: invalidOptions) diff --git a/solc/CommandLineParser.h b/solc/CommandLineParser.h index b95973562e51..5d941f662c99 100644 --- a/solc/CommandLineParser.h +++ b/solc/CommandLineParser.h @@ -86,6 +86,7 @@ struct CompilerOutputs {"devdoc", &CompilerOutputs::natspecDev}, {"metadata", &CompilerOutputs::metadata}, {"storage-layout", &CompilerOutputs::storageLayout}, + {"transient-storage-layout", &CompilerOutputs::transientStorageLayout}, }; return components; } @@ -106,6 +107,7 @@ struct CompilerOutputs bool natspecDev = false; bool metadata = false; bool storageLayout = false; + bool transientStorageLayout = false; }; struct CombinedJsonRequests @@ -125,6 +127,7 @@ struct CombinedJsonRequests {"opcodes", &CombinedJsonRequests::opcodes}, {"asm", &CombinedJsonRequests::asm_}, {"storage-layout", &CombinedJsonRequests::storageLayout}, + {"transient-storage-layout", &CombinedJsonRequests::transientStorageLayout}, {"generated-sources", &CombinedJsonRequests::generatedSources}, {"generated-sources-runtime", &CombinedJsonRequests::generatedSourcesRuntime}, {"srcmap", &CombinedJsonRequests::srcMap}, @@ -146,6 +149,7 @@ struct CombinedJsonRequests bool opcodes = false; bool asm_ = false; bool storageLayout = false; + bool transientStorageLayout = false; bool generatedSources = false; bool generatedSourcesRuntime = false; bool srcMap = false; diff --git a/test/cmdlineTests/standard_outputs_on_compilation_error/output.json b/test/cmdlineTests/standard_outputs_on_compilation_error/output.json index 09f4afc4ef2d..e0f4e37e6ae0 100644 --- a/test/cmdlineTests/standard_outputs_on_compilation_error/output.json +++ b/test/cmdlineTests/standard_outputs_on_compilation_error/output.json @@ -37,6 +37,10 @@ "storage": [], "types": null }, + "transientStorageLayout": { + "storage": [], + "types": null + }, "userdoc": { "kind": "user", "methods": {}, diff --git a/test/cmdlineTests/storage_layout_transient_value_types/input.json b/test/cmdlineTests/storage_layout_transient_value_types/input.json index 96d71ed30ec8..8c90a7dde233 100644 --- a/test/cmdlineTests/storage_layout_transient_value_types/input.json +++ b/test/cmdlineTests/storage_layout_transient_value_types/input.json @@ -6,7 +6,7 @@ "settings": { "outputSelection": { "fileA": { - "A": ["storageLayout"] + "A": ["storageLayout", "transientStorageLayout"] } } } diff --git a/test/cmdlineTests/storage_layout_transient_value_types/output.json b/test/cmdlineTests/storage_layout_transient_value_types/output.json index b77de9326200..1f688501e854 100644 --- a/test/cmdlineTests/storage_layout_transient_value_types/output.json +++ b/test/cmdlineTests/storage_layout_transient_value_types/output.json @@ -1,62 +1,103 @@ { - "errors": [ - { - "component": "general", - "errorCode": "6715", - "formattedMessage": "UnimplementedFeatureError: Transient storage is not yet implemented. - --> fileA:4:5: - | -4 | uint transient x; - | ^^^^^^^^^^^^^^^^ - -", - "message": "Transient storage is not yet implemented.", - "severity": "error", - "sourceLocation": { - "end": 91, - "file": "fileA", - "start": 75 - }, - "type": "UnimplementedFeatureError" - }, - { - "component": "general", - "errorCode": "6715", - "formattedMessage": "UnimplementedFeatureError: Transient storage is not yet implemented. - --> fileA:6:5: - | -6 | bytes32 transient b; - | ^^^^^^^^^^^^^^^^^^^ - -", - "message": "Transient storage is not yet implemented.", - "severity": "error", - "sourceLocation": { - "end": 128, - "file": "fileA", - "start": 109 - }, - "type": "UnimplementedFeatureError" - }, - { - "component": "general", - "errorCode": "6715", - "formattedMessage": "UnimplementedFeatureError: Transient storage is not yet implemented. - --> fileA:8:5: - | -8 | address transient a; - | ^^^^^^^^^^^^^^^^^^^ - -", - "message": "Transient storage is not yet implemented.", - "severity": "error", - "sourceLocation": { - "end": 168, - "file": "fileA", - "start": 149 - }, - "type": "UnimplementedFeatureError" + "contracts": { + "fileA": { + "A": { + "storageLayout": { + "storage": [ + { + "astId": 5, + "contract": "fileA:A", + "label": "y", + "offset": 0, + "slot": "0", + "type": "t_uint256" + }, + { + "astId": 9, + "contract": "fileA:A", + "label": "c", + "offset": 0, + "slot": "1", + "type": "t_bytes32" + }, + { + "astId": 13, + "contract": "fileA:A", + "label": "z", + "offset": 0, + "slot": "2", + "type": "t_address" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + }, + "t_bytes32": { + "encoding": "inplace", + "label": "bytes32", + "numberOfBytes": "32" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + } + } + }, + "transientStorageLayout": { + "storage": [ + { + "astId": 3, + "contract": "fileA:A", + "label": "x", + "offset": 0, + "slot": "0", + "type": "t_uint256" + }, + { + "astId": 7, + "contract": "fileA:A", + "label": "b", + "offset": 0, + "slot": "1", + "type": "t_bytes32" + }, + { + "astId": 11, + "contract": "fileA:A", + "label": "a", + "offset": 0, + "slot": "2", + "type": "t_address" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + }, + "t_bytes32": { + "encoding": "inplace", + "label": "bytes32", + "numberOfBytes": "32" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + } + } + } + } } - ], - "sources": {} + }, + "sources": { + "fileA": { + "id": 0 + } + } } diff --git a/test/cmdlineTests/transient_storage_layout/args b/test/cmdlineTests/transient_storage_layout/args new file mode 100644 index 000000000000..fe39ed77635c --- /dev/null +++ b/test/cmdlineTests/transient_storage_layout/args @@ -0,0 +1 @@ +--transient-storage-layout --pretty-json --json-indent 4 \ No newline at end of file diff --git a/test/cmdlineTests/transient_storage_layout/input.sol b/test/cmdlineTests/transient_storage_layout/input.sol new file mode 100644 index 000000000000..e1d028698c69 --- /dev/null +++ b/test/cmdlineTests/transient_storage_layout/input.sol @@ -0,0 +1,13 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity > 0.0; + +contract D { } + +contract C { + uint transient x; + uint y; + address transient w; + int z; + bool transient b; + D transient d; +} \ No newline at end of file diff --git a/test/cmdlineTests/transient_storage_layout/output b/test/cmdlineTests/transient_storage_layout/output new file mode 100644 index 000000000000..0736271b44ad --- /dev/null +++ b/test/cmdlineTests/transient_storage_layout/output @@ -0,0 +1,67 @@ + +======= transient_storage_layout/input.sol:C ======= +Contract Transient Storage Layout: +{ + "storage": [ + { + "astId": 4, + "contract": "transient_storage_layout/input.sol:C", + "label": "x", + "offset": 0, + "slot": "0", + "type": "t_uint256" + }, + { + "astId": 8, + "contract": "transient_storage_layout/input.sol:C", + "label": "w", + "offset": 0, + "slot": "1", + "type": "t_address" + }, + { + "astId": 12, + "contract": "transient_storage_layout/input.sol:C", + "label": "b", + "offset": 20, + "slot": "1", + "type": "t_bool" + }, + { + "astId": 15, + "contract": "transient_storage_layout/input.sol:C", + "label": "d", + "offset": 0, + "slot": "2", + "type": "t_contract(D)2" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + }, + "t_bool": { + "encoding": "inplace", + "label": "bool", + "numberOfBytes": "1" + }, + "t_contract(D)2": { + "encoding": "inplace", + "label": "contract D", + "numberOfBytes": "20" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + } + } +} + +======= transient_storage_layout/input.sol:D ======= +Contract Transient Storage Layout: +{ + "storage": [] +} diff --git a/test/cmdlineTests/transient_storage_layout_smoke_empty/input.json b/test/cmdlineTests/transient_storage_layout_smoke_empty/input.json new file mode 100644 index 000000000000..d167f66630ed --- /dev/null +++ b/test/cmdlineTests/transient_storage_layout_smoke_empty/input.json @@ -0,0 +1,15 @@ +{ + "language": "Solidity", + "sources": { + "fileA": { + "content": "//SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract A { }" + } + }, + "settings": { + "outputSelection": { + "fileA": { + "A": ["transientStorageLayout"] + } + } + } +} diff --git a/test/cmdlineTests/transient_storage_layout_smoke_empty/output.json b/test/cmdlineTests/transient_storage_layout_smoke_empty/output.json new file mode 100644 index 000000000000..261442c1d746 --- /dev/null +++ b/test/cmdlineTests/transient_storage_layout_smoke_empty/output.json @@ -0,0 +1,17 @@ +{ + "contracts": { + "fileA": { + "A": { + "transientStorageLayout": { + "storage": [], + "types": null + } + } + } + }, + "sources": { + "fileA": { + "id": 0 + } + } +} diff --git a/test/cmdlineTests/transient_storage_layout_smoke_two_contracts/input.json b/test/cmdlineTests/transient_storage_layout_smoke_two_contracts/input.json new file mode 100644 index 000000000000..4ca3cc455af7 --- /dev/null +++ b/test/cmdlineTests/transient_storage_layout_smoke_two_contracts/input.json @@ -0,0 +1,21 @@ +{ + "language": "Solidity", + "sources": { + "fileA": { + "content": "//SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract A { }" + }, + "fileB": { + "content": "//SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract B { uint transient x; uint transient y; }" + } + }, + "settings": { + "outputSelection": { + "fileA": { + "A": ["transientStorageLayout"] + }, + "fileB": { + "B": ["transientStorageLayout"] + } + } + } +} diff --git a/test/cmdlineTests/transient_storage_layout_smoke_two_contracts/output.json b/test/cmdlineTests/transient_storage_layout_smoke_two_contracts/output.json new file mode 100644 index 000000000000..670ff01257ce --- /dev/null +++ b/test/cmdlineTests/transient_storage_layout_smoke_two_contracts/output.json @@ -0,0 +1,51 @@ +{ + "contracts": { + "fileA": { + "A": { + "transientStorageLayout": { + "storage": [], + "types": null + } + } + }, + "fileB": { + "B": { + "transientStorageLayout": { + "storage": [ + { + "astId": 6, + "contract": "fileB:B", + "label": "x", + "offset": 0, + "slot": "0", + "type": "t_uint256" + }, + { + "astId": 8, + "contract": "fileB:B", + "label": "y", + "offset": 0, + "slot": "1", + "type": "t_uint256" + } + ], + "types": { + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + } + } + } + } + } + }, + "sources": { + "fileA": { + "id": 0 + }, + "fileB": { + "id": 1 + } + } +} diff --git a/test/cmdlineTests/transient_storage_layout_value_types/in.sol b/test/cmdlineTests/transient_storage_layout_value_types/in.sol new file mode 100644 index 000000000000..c2f89a9872dd --- /dev/null +++ b/test/cmdlineTests/transient_storage_layout_value_types/in.sol @@ -0,0 +1,23 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity >=0.0; + +type MyInt is int256; + +enum MyEnum { + None, + Something, + SomethingElse +} + +contract C { } + +contract A { + uint transient x; + int transient y; + address transient addr; + bool transient b; + MyInt transient w; + C transient c; + MyEnum transient e; + function() external transient p; +} diff --git a/test/cmdlineTests/transient_storage_layout_value_types/input.json b/test/cmdlineTests/transient_storage_layout_value_types/input.json new file mode 100644 index 000000000000..65d9a2231b90 --- /dev/null +++ b/test/cmdlineTests/transient_storage_layout_value_types/input.json @@ -0,0 +1,13 @@ +{ + "language": "Solidity", + "sources": { + "fileA": {"urls": ["transient_storage_layout_value_types/in.sol"]} + }, + "settings": { + "outputSelection": { + "fileA": { + "A": ["transientStorageLayout"] + } + } + } +} diff --git a/test/cmdlineTests/transient_storage_layout_value_types/output.json b/test/cmdlineTests/transient_storage_layout_value_types/output.json new file mode 100644 index 000000000000..298a2588a977 --- /dev/null +++ b/test/cmdlineTests/transient_storage_layout_value_types/output.json @@ -0,0 +1,123 @@ +{ + "contracts": { + "fileA": { + "A": { + "transientStorageLayout": { + "storage": [ + { + "astId": 10, + "contract": "fileA:A", + "label": "x", + "offset": 0, + "slot": "0", + "type": "t_uint256" + }, + { + "astId": 12, + "contract": "fileA:A", + "label": "y", + "offset": 0, + "slot": "1", + "type": "t_int256" + }, + { + "astId": 14, + "contract": "fileA:A", + "label": "addr", + "offset": 0, + "slot": "2", + "type": "t_address" + }, + { + "astId": 16, + "contract": "fileA:A", + "label": "b", + "offset": 20, + "slot": "2", + "type": "t_bool" + }, + { + "astId": 19, + "contract": "fileA:A", + "label": "w", + "offset": 0, + "slot": "3", + "type": "t_userDefinedValueType(MyInt)3" + }, + { + "astId": 22, + "contract": "fileA:A", + "label": "c", + "offset": 0, + "slot": "4", + "type": "t_contract(C)8" + }, + { + "astId": 25, + "contract": "fileA:A", + "label": "e", + "offset": 20, + "slot": "4", + "type": "t_enum(MyEnum)7" + }, + { + "astId": 29, + "contract": "fileA:A", + "label": "p", + "offset": 0, + "slot": "5", + "type": "t_function_external_nonpayable()returns()" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + }, + "t_bool": { + "encoding": "inplace", + "label": "bool", + "numberOfBytes": "1" + }, + "t_contract(C)8": { + "encoding": "inplace", + "label": "contract C", + "numberOfBytes": "20" + }, + "t_enum(MyEnum)7": { + "encoding": "inplace", + "label": "enum MyEnum", + "numberOfBytes": "1" + }, + "t_function_external_nonpayable()returns()": { + "encoding": "inplace", + "label": "function () external", + "numberOfBytes": "24" + }, + "t_int256": { + "encoding": "inplace", + "label": "int256", + "numberOfBytes": "32" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + }, + "t_userDefinedValueType(MyInt)3": { + "encoding": "inplace", + "label": "MyInt", + "numberOfBytes": "32" + } + } + } + } + } + }, + "sources": { + "fileA": { + "id": 0 + } + } +} diff --git a/test/cmdlineTests/transient_storage_layout_value_types_interleaved_with_storage/in.sol b/test/cmdlineTests/transient_storage_layout_value_types_interleaved_with_storage/in.sol new file mode 100644 index 000000000000..18af07a1592a --- /dev/null +++ b/test/cmdlineTests/transient_storage_layout_value_types_interleaved_with_storage/in.sol @@ -0,0 +1,15 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity >=0.0; +type MyInt is int8; +contract A { + uint public transient x; + uint public y; + int private transient z; + int private w; + address transient addr; + address d; + bool transient b; + bool c; + MyInt i; + MyInt transient j; +} diff --git a/test/cmdlineTests/transient_storage_layout_value_types_interleaved_with_storage/input.json b/test/cmdlineTests/transient_storage_layout_value_types_interleaved_with_storage/input.json new file mode 100644 index 000000000000..e649fc838b82 --- /dev/null +++ b/test/cmdlineTests/transient_storage_layout_value_types_interleaved_with_storage/input.json @@ -0,0 +1,13 @@ +{ + "language": "Solidity", + "sources": { + "fileA": {"urls": ["transient_storage_layout_value_types_interleaved_with_storage/in.sol"]} + }, + "settings": { + "outputSelection": { + "fileA": { + "A": ["storageLayout", "transientStorageLayout"] + } + } + } +} diff --git a/test/cmdlineTests/transient_storage_layout_value_types_interleaved_with_storage/output.json b/test/cmdlineTests/transient_storage_layout_value_types_interleaved_with_storage/output.json new file mode 100644 index 000000000000..ab967985d483 --- /dev/null +++ b/test/cmdlineTests/transient_storage_layout_value_types_interleaved_with_storage/output.json @@ -0,0 +1,155 @@ +{ + "contracts": { + "fileA": { + "A": { + "storageLayout": { + "storage": [ + { + "astId": 7, + "contract": "fileA:A", + "label": "y", + "offset": 0, + "slot": "0", + "type": "t_uint256" + }, + { + "astId": 11, + "contract": "fileA:A", + "label": "w", + "offset": 0, + "slot": "1", + "type": "t_int256" + }, + { + "astId": 15, + "contract": "fileA:A", + "label": "d", + "offset": 0, + "slot": "2", + "type": "t_address" + }, + { + "astId": 19, + "contract": "fileA:A", + "label": "c", + "offset": 20, + "slot": "2", + "type": "t_bool" + }, + { + "astId": 22, + "contract": "fileA:A", + "label": "i", + "offset": 21, + "slot": "2", + "type": "t_userDefinedValueType(MyInt)3" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + }, + "t_bool": { + "encoding": "inplace", + "label": "bool", + "numberOfBytes": "1" + }, + "t_int256": { + "encoding": "inplace", + "label": "int256", + "numberOfBytes": "32" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + }, + "t_userDefinedValueType(MyInt)3": { + "encoding": "inplace", + "label": "MyInt", + "numberOfBytes": "1" + } + } + }, + "transientStorageLayout": { + "storage": [ + { + "astId": 5, + "contract": "fileA:A", + "label": "x", + "offset": 0, + "slot": "0", + "type": "t_uint256" + }, + { + "astId": 9, + "contract": "fileA:A", + "label": "z", + "offset": 0, + "slot": "1", + "type": "t_int256" + }, + { + "astId": 13, + "contract": "fileA:A", + "label": "addr", + "offset": 0, + "slot": "2", + "type": "t_address" + }, + { + "astId": 17, + "contract": "fileA:A", + "label": "b", + "offset": 20, + "slot": "2", + "type": "t_bool" + }, + { + "astId": 25, + "contract": "fileA:A", + "label": "j", + "offset": 21, + "slot": "2", + "type": "t_userDefinedValueType(MyInt)3" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + }, + "t_bool": { + "encoding": "inplace", + "label": "bool", + "numberOfBytes": "1" + }, + "t_int256": { + "encoding": "inplace", + "label": "int256", + "numberOfBytes": "32" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + }, + "t_userDefinedValueType(MyInt)3": { + "encoding": "inplace", + "label": "MyInt", + "numberOfBytes": "1" + } + } + } + } + } + }, + "sources": { + "fileA": { + "id": 0 + } + } +} diff --git a/test/cmdlineTests/transient_storage_layout_value_types_packed/in.sol b/test/cmdlineTests/transient_storage_layout_value_types_packed/in.sol new file mode 100644 index 000000000000..9b50fd810dc2 --- /dev/null +++ b/test/cmdlineTests/transient_storage_layout_value_types_packed/in.sol @@ -0,0 +1,24 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity >=0.0; + +type MyInt is int128; + +enum MyEnum { + None, + Something, + SomethingElse +} + +contract C { } + +contract A { + uint64 transient x; + uint128 transient y; + uint128 transient z; + address transient addr; + bool transient b; + MyInt transient w; + C transient c; + MyEnum transient e; + function() external transient p; +} diff --git a/test/cmdlineTests/transient_storage_layout_value_types_packed/input.json b/test/cmdlineTests/transient_storage_layout_value_types_packed/input.json new file mode 100644 index 000000000000..ee7fb0dec3b7 --- /dev/null +++ b/test/cmdlineTests/transient_storage_layout_value_types_packed/input.json @@ -0,0 +1,13 @@ +{ + "language": "Solidity", + "sources": { + "fileA": {"urls": ["transient_storage_layout_value_types_packed/in.sol"]} + }, + "settings": { + "outputSelection": { + "fileA": { + "A": ["transientStorageLayout"] + } + } + } +} diff --git a/test/cmdlineTests/transient_storage_layout_value_types_packed/output.json b/test/cmdlineTests/transient_storage_layout_value_types_packed/output.json new file mode 100644 index 000000000000..2be40db848d8 --- /dev/null +++ b/test/cmdlineTests/transient_storage_layout_value_types_packed/output.json @@ -0,0 +1,131 @@ +{ + "contracts": { + "fileA": { + "A": { + "transientStorageLayout": { + "storage": [ + { + "astId": 10, + "contract": "fileA:A", + "label": "x", + "offset": 0, + "slot": "0", + "type": "t_uint64" + }, + { + "astId": 12, + "contract": "fileA:A", + "label": "y", + "offset": 8, + "slot": "0", + "type": "t_uint128" + }, + { + "astId": 14, + "contract": "fileA:A", + "label": "z", + "offset": 0, + "slot": "1", + "type": "t_uint128" + }, + { + "astId": 16, + "contract": "fileA:A", + "label": "addr", + "offset": 0, + "slot": "2", + "type": "t_address" + }, + { + "astId": 18, + "contract": "fileA:A", + "label": "b", + "offset": 20, + "slot": "2", + "type": "t_bool" + }, + { + "astId": 21, + "contract": "fileA:A", + "label": "w", + "offset": 0, + "slot": "3", + "type": "t_userDefinedValueType(MyInt)3" + }, + { + "astId": 24, + "contract": "fileA:A", + "label": "c", + "offset": 0, + "slot": "4", + "type": "t_contract(C)8" + }, + { + "astId": 27, + "contract": "fileA:A", + "label": "e", + "offset": 20, + "slot": "4", + "type": "t_enum(MyEnum)7" + }, + { + "astId": 31, + "contract": "fileA:A", + "label": "p", + "offset": 0, + "slot": "5", + "type": "t_function_external_nonpayable()returns()" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + }, + "t_bool": { + "encoding": "inplace", + "label": "bool", + "numberOfBytes": "1" + }, + "t_contract(C)8": { + "encoding": "inplace", + "label": "contract C", + "numberOfBytes": "20" + }, + "t_enum(MyEnum)7": { + "encoding": "inplace", + "label": "enum MyEnum", + "numberOfBytes": "1" + }, + "t_function_external_nonpayable()returns()": { + "encoding": "inplace", + "label": "function () external", + "numberOfBytes": "24" + }, + "t_uint128": { + "encoding": "inplace", + "label": "uint128", + "numberOfBytes": "16" + }, + "t_uint64": { + "encoding": "inplace", + "label": "uint64", + "numberOfBytes": "8" + }, + "t_userDefinedValueType(MyInt)3": { + "encoding": "inplace", + "label": "MyInt", + "numberOfBytes": "16" + } + } + } + } + } + }, + "sources": { + "fileA": { + "id": 0 + } + } +} diff --git a/test/libsolidity/astPropertyTests/transient_data_location.sol b/test/libsolidity/astPropertyTests/transient_data_location.sol new file mode 100644 index 000000000000..be220a366b0b --- /dev/null +++ b/test/libsolidity/astPropertyTests/transient_data_location.sol @@ -0,0 +1,14 @@ +contract C { + /// TransientDataLocation: storageLocation + /// TransientVarName: name + uint transient x; + /// StorageDataLocation: storageLocation + /// StorageVarName: name + uint y; + +} +// ---- +// TransientDataLocation: transient +// TransientVarName: x +// StorageDataLocation: default +// StorageVarName: y diff --git a/test/libsolidity/smtCheckerTests/unsupported/transient_storage_state_variable.sol b/test/libsolidity/smtCheckerTests/unsupported/transient_storage_state_variable.sol index cdb4461656a6..b2dbc8efe5c7 100644 --- a/test/libsolidity/smtCheckerTests/unsupported/transient_storage_state_variable.sol +++ b/test/libsolidity/smtCheckerTests/unsupported/transient_storage_state_variable.sol @@ -5,4 +5,4 @@ contract C { // ==== // SMTEngine: all // ---- -// UnimplementedFeatureError 6715: (17-38): Transient storage is not yet implemented. +// UnimplementedFeatureError 1834: Transient storage variables are not supported. diff --git a/test/libsolidity/syntaxTests/dataLocations/transient_function_type.sol b/test/libsolidity/syntaxTests/dataLocations/transient_function_type.sol index a3d741bbe2e3..56456290881a 100644 --- a/test/libsolidity/syntaxTests/dataLocations/transient_function_type.sol +++ b/test/libsolidity/syntaxTests/dataLocations/transient_function_type.sol @@ -7,9 +7,4 @@ contract C { function () internal internal transient fiit; } // ---- -// UnimplementedFeatureError 6715: (17-40): Transient storage is not yet implemented. -// UnimplementedFeatureError 6715: (46-82): Transient storage is not yet implemented. -// UnimplementedFeatureError 6715: (88-122): Transient storage is not yet implemented. -// UnimplementedFeatureError 6715: (128-162): Transient storage is not yet implemented. -// UnimplementedFeatureError 6715: (168-212): Transient storage is not yet implemented. -// UnimplementedFeatureError 6715: (218-262): Transient storage is not yet implemented. +// UnimplementedFeatureError 1834: Transient storage variables are not supported. diff --git a/test/libsolidity/syntaxTests/dataLocations/transient_state_variable_visibility.sol b/test/libsolidity/syntaxTests/dataLocations/transient_state_variable_visibility.sol index 561d9f21dab6..f598fb72c823 100644 --- a/test/libsolidity/syntaxTests/dataLocations/transient_state_variable_visibility.sol +++ b/test/libsolidity/syntaxTests/dataLocations/transient_state_variable_visibility.sol @@ -8,9 +8,4 @@ contract C { uint transient private tprv; } // ---- -// UnimplementedFeatureError 6715: (17-43): Transient storage is not yet implemented. -// UnimplementedFeatureError 6715: (49-75): Transient storage is not yet implemented. -// UnimplementedFeatureError 6715: (81-108): Transient storage is not yet implemented. -// UnimplementedFeatureError 6715: (115-141): Transient storage is not yet implemented. -// UnimplementedFeatureError 6715: (147-173): Transient storage is not yet implemented. -// UnimplementedFeatureError 6715: (179-206): Transient storage is not yet implemented. +// UnimplementedFeatureError 1834: Transient storage variables are not supported. diff --git a/test/libsolidity/syntaxTests/dataLocations/transient_value_type_state_variables.sol b/test/libsolidity/syntaxTests/dataLocations/transient_value_type_state_variables.sol index ce2db200bbac..d2eac46f7ba9 100644 --- a/test/libsolidity/syntaxTests/dataLocations/transient_value_type_state_variables.sol +++ b/test/libsolidity/syntaxTests/dataLocations/transient_value_type_state_variables.sol @@ -8,8 +8,4 @@ contract C { bytes32 transient y; } // ---- -// UnimplementedFeatureError 6715: (30-49): Transient storage is not yet implemented. -// UnimplementedFeatureError 6715: (52-68): Transient storage is not yet implemented. -// UnimplementedFeatureError 6715: (71-84): Transient storage is not yet implemented. -// UnimplementedFeatureError 6715: (87-103): Transient storage is not yet implemented. -// UnimplementedFeatureError 6715: (106-125): Transient storage is not yet implemented. +// UnimplementedFeatureError 1834: Transient storage variables are not supported. diff --git a/test/libsolidity/syntaxTests/dataLocations/transient_value_type_state_variables_assignment.sol b/test/libsolidity/syntaxTests/dataLocations/transient_value_type_state_variables_assignment.sol index 33b7bb28cb64..18e6a215dd1a 100644 --- a/test/libsolidity/syntaxTests/dataLocations/transient_value_type_state_variables_assignment.sol +++ b/test/libsolidity/syntaxTests/dataLocations/transient_value_type_state_variables_assignment.sol @@ -6,6 +6,4 @@ contract C { bool transient b = x > 0 ? false : true; } // ---- -// UnimplementedFeatureError 6715: (30-51): Transient storage is not yet implemented. -// UnimplementedFeatureError 6715: (54-90): Transient storage is not yet implemented. -// UnimplementedFeatureError 6715: (93-132): Transient storage is not yet implemented. +// UnimplementedFeatureError 1834: Transient storage variables are not supported. diff --git a/test/solc/CommandLineParser.cpp b/test/solc/CommandLineParser.cpp index 2ba1d43c8746..37c638a3bbba 100644 --- a/test/solc/CommandLineParser.cpp +++ b/test/solc/CommandLineParser.cpp @@ -130,10 +130,11 @@ BOOST_AUTO_TEST_CASE(cli_mode_options) "dir1/file1.sol:L=0x1234567890123456789012345678901234567890," "dir2/file2.sol:L=0x1111122222333334444455555666667777788888", "--ast-compact-json", "--asm", "--asm-json", "--opcodes", "--bin", "--bin-runtime", "--abi", - "--ir", "--ir-ast-json", "--ir-optimized", "--ir-optimized-ast-json", "--hashes", "--userdoc", "--devdoc", "--metadata", "--storage-layout", + "--ir", "--ir-ast-json", "--ir-optimized", "--ir-optimized-ast-json", "--hashes", "--userdoc", "--devdoc", "--metadata", + "--storage-layout", "--transient-storage-layout", "--gas", "--combined-json=" - "abi,metadata,bin,bin-runtime,opcodes,asm,storage-layout,generated-sources,generated-sources-runtime," + "abi,metadata,bin,bin-runtime,opcodes,asm,storage-layout,transient-storage-layout,generated-sources,generated-sources-runtime," "srcmap,srcmap-runtime,function-debug,function-debug-runtime,hashes,devdoc,userdoc,ast", "--metadata-hash=swarm", "--metadata-literal", @@ -192,14 +193,14 @@ BOOST_AUTO_TEST_CASE(cli_mode_options) true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, - true, + true, true, }; expectedOptions.compiler.estimateGas = true; expectedOptions.compiler.combinedJsonRequests = { true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, - true, true, + true, true, true, }; expectedOptions.metadata.hash = CompilerStack::MetadataHash::Bzzr1; expectedOptions.metadata.literalSources = true; From 978f9a0cd7e04cea8ad67dc3b5ef130aa9878e72 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Thu, 11 Jul 2024 11:30:58 +0200 Subject: [PATCH 0326/1022] Yul: Immutable AST class with top-level block --- libsolidity/analysis/ControlFlowBuilder.cpp | 2 +- libsolidity/analysis/PostTypeChecker.cpp | 2 +- libsolidity/analysis/ReferencesResolver.cpp | 2 +- libsolidity/analysis/SyntaxChecker.cpp | 2 +- libsolidity/analysis/TypeChecker.cpp | 2 +- libsolidity/analysis/ViewPureChecker.cpp | 2 +- libsolidity/ast/AST.h | 8 +- libsolidity/ast/ASTJsonExporter.cpp | 2 +- libsolidity/ast/ASTJsonImporter.cpp | 2 +- libsolidity/codegen/CompilerContext.cpp | 10 +- libsolidity/codegen/ContractCompiler.cpp | 6 +- .../codegen/ir/IRGeneratorForStatements.cpp | 2 +- .../experimental/analysis/TypeInference.cpp | 2 +- .../codegen/IRGeneratorForStatements.cpp | 2 +- libsolidity/formal/SMTEncoder.cpp | 4 +- libsolidity/interface/CompilerStack.cpp | 4 +- libsolidity/parsing/Parser.cpp | 8 +- libyul/AST.h | 12 + libyul/ASTForward.h | 1 + libyul/AsmAnalysis.cpp | 13 +- libyul/AsmAnalysis.h | 5 + libyul/AsmJsonImporter.cpp | 5 + libyul/AsmJsonImporter.h | 3 +- libyul/AsmParser.cpp | 10 +- libyul/AsmParser.h | 4 +- libyul/CompilabilityChecker.cpp | 17 +- libyul/CompilabilityChecker.h | 7 +- libyul/Object.cpp | 4 +- libyul/Object.h | 2 +- libyul/ObjectParser.cpp | 10 +- libyul/ObjectParser.h | 4 +- libyul/YulStack.cpp | 2 +- libyul/backends/evm/EVMObjectCompiler.cpp | 8 +- libyul/optimiser/Semantics.cpp | 2 +- libyul/optimiser/StackCompressor.cpp | 30 +- libyul/optimiser/StackCompressor.h | 13 +- libyul/optimiser/StackLimitEvader.cpp | 31 +- libyul/optimiser/StackLimitEvader.h | 7 +- libyul/optimiser/Suite.cpp | 34 +- test/libsolidity/MemoryGuardTest.cpp | 3 +- test/libyul/Common.cpp | 8 +- test/libyul/Common.h | 3 +- test/libyul/ControlFlowGraphTest.cpp | 2 +- test/libyul/ControlFlowSideEffectsTest.cpp | 4 +- test/libyul/FunctionSideEffects.cpp | 2 +- test/libyul/KnowledgeBaseTest.cpp | 9 +- test/libyul/Metrics.cpp | 4 +- test/libyul/Parser.cpp | 280 +++++------ test/libyul/StackLayoutGeneratorTest.cpp | 2 +- test/libyul/YulInterpreterTest.cpp | 3 +- test/libyul/YulInterpreterTest.h | 4 +- test/libyul/YulOptimizerTest.cpp | 15 +- test/libyul/YulOptimizerTestCommon.cpp | 451 +++++++++++------- test/libyul/YulOptimizerTestCommon.h | 19 +- .../tools/ossfuzz/StackReuseCodegenFuzzer.cpp | 2 +- test/tools/ossfuzz/strictasm_diff_ossfuzz.cpp | 5 +- test/tools/ossfuzz/yulFuzzerCommon.cpp | 4 +- test/tools/ossfuzz/yulFuzzerCommon.h | 2 +- test/tools/ossfuzz/yulProtoFuzzer.cpp | 4 +- test/tools/ossfuzz/yulProto_diff_ossfuzz.cpp | 9 +- test/tools/yulopti.cpp | 28 +- test/tools/yulrun.cpp | 8 +- tools/yulPhaser/Program.cpp | 37 +- tools/yulPhaser/Program.h | 22 +- 64 files changed, 699 insertions(+), 517 deletions(-) diff --git a/libsolidity/analysis/ControlFlowBuilder.cpp b/libsolidity/analysis/ControlFlowBuilder.cpp index c20968a14d79..7bc0ebc7bf58 100644 --- a/libsolidity/analysis/ControlFlowBuilder.cpp +++ b/libsolidity/analysis/ControlFlowBuilder.cpp @@ -451,7 +451,7 @@ bool ControlFlowBuilder::visit(InlineAssembly const& _inlineAssembly) solAssert(!!m_currentNode && !m_inlineAssembly, ""); m_inlineAssembly = &_inlineAssembly; - (*this)(_inlineAssembly.operations()); + (*this)(_inlineAssembly.operations().root()); m_inlineAssembly = nullptr; return false; diff --git a/libsolidity/analysis/PostTypeChecker.cpp b/libsolidity/analysis/PostTypeChecker.cpp index 9731ef3cc624..49c5fa4a414d 100644 --- a/libsolidity/analysis/PostTypeChecker.cpp +++ b/libsolidity/analysis/PostTypeChecker.cpp @@ -506,7 +506,7 @@ class LValueChecker: public ASTConstVisitor return; YulLValueChecker yulChecker{m_declaration->name()}; - yulChecker(_inlineAssembly.operations()); + yulChecker(_inlineAssembly.operations().root()); m_willBeWrittenTo = yulChecker.willBeWrittenTo(); } private: diff --git a/libsolidity/analysis/ReferencesResolver.cpp b/libsolidity/analysis/ReferencesResolver.cpp index 270e1a55abc5..bb3b20e93a50 100644 --- a/libsolidity/analysis/ReferencesResolver.cpp +++ b/libsolidity/analysis/ReferencesResolver.cpp @@ -236,7 +236,7 @@ bool ReferencesResolver::visit(UsingForDirective const& _usingFor) bool ReferencesResolver::visit(InlineAssembly const& _inlineAssembly) { m_yulAnnotation = &_inlineAssembly.annotation(); - (*this)(_inlineAssembly.operations()); + (*this)(_inlineAssembly.operations().root()); m_yulAnnotation = nullptr; return false; diff --git a/libsolidity/analysis/SyntaxChecker.cpp b/libsolidity/analysis/SyntaxChecker.cpp index b083690cced6..1e3f5f1c2a56 100644 --- a/libsolidity/analysis/SyntaxChecker.cpp +++ b/libsolidity/analysis/SyntaxChecker.cpp @@ -354,7 +354,7 @@ bool SyntaxChecker::visit(InlineAssembly const& _inlineAssembly) if (!m_useYulOptimizer) return false; - if (yul::MSizeFinder::containsMSize(_inlineAssembly.dialect(), _inlineAssembly.operations())) + if (yul::MSizeFinder::containsMSize(_inlineAssembly.dialect(), _inlineAssembly.operations().root())) m_errorReporter.syntaxError( 6553_error, _inlineAssembly.location(), diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp index 918e27033329..3b7a314fe3ea 100644 --- a/libsolidity/analysis/TypeChecker.cpp +++ b/libsolidity/analysis/TypeChecker.cpp @@ -940,7 +940,7 @@ bool TypeChecker::visit(InlineAssembly const& _inlineAssembly) _inlineAssembly.dialect(), identifierAccess ); - if (!analyzer.analyze(_inlineAssembly.operations())) + if (!analyzer.analyze(_inlineAssembly.operations().root())) solAssert(m_errorReporter.hasErrors()); _inlineAssembly.annotation().hasMemoryEffects = lvalueAccessToMemoryVariable || diff --git a/libsolidity/analysis/ViewPureChecker.cpp b/libsolidity/analysis/ViewPureChecker.cpp index 3f6b954e75da..3b16205e7d86 100644 --- a/libsolidity/analysis/ViewPureChecker.cpp +++ b/libsolidity/analysis/ViewPureChecker.cpp @@ -226,7 +226,7 @@ void ViewPureChecker::endVisit(InlineAssembly const& _inlineAssembly) AssemblyViewPureChecker{ _inlineAssembly.dialect(), [&](StateMutability _mutability, SourceLocation const& _location) { reportMutability(_mutability, _location); } - }(_inlineAssembly.operations()); + }(_inlineAssembly.operations().root()); } void ViewPureChecker::reportMutability( diff --git a/libsolidity/ast/AST.h b/libsolidity/ast/AST.h index 3494ab94b9b4..727652f56000 100644 --- a/libsolidity/ast/AST.h +++ b/libsolidity/ast/AST.h @@ -48,7 +48,7 @@ namespace solidity::yul { // Forward-declaration to -struct Block; +class AST; struct Dialect; } @@ -1569,7 +1569,7 @@ class InlineAssembly: public Statement ASTPointer const& _docString, yul::Dialect const& _dialect, ASTPointer>> _flags, - std::shared_ptr _operations + std::shared_ptr _operations ): Statement(_id, _location, _docString), m_dialect(_dialect), @@ -1580,7 +1580,7 @@ class InlineAssembly: public Statement void accept(ASTConstVisitor& _visitor) const override; yul::Dialect const& dialect() const { return m_dialect; } - yul::Block const& operations() const { return *m_operations; } + yul::AST const& operations() const { return *m_operations; } ASTPointer>> const& flags() const { return m_flags; } InlineAssemblyAnnotation& annotation() const override; @@ -1588,7 +1588,7 @@ class InlineAssembly: public Statement private: yul::Dialect const& m_dialect; ASTPointer>> m_flags; - std::shared_ptr m_operations; + std::shared_ptr m_operations; }; /** diff --git a/libsolidity/ast/ASTJsonExporter.cpp b/libsolidity/ast/ASTJsonExporter.cpp index 69f51618e3d4..910cc257eb4a 100644 --- a/libsolidity/ast/ASTJsonExporter.cpp +++ b/libsolidity/ast/ASTJsonExporter.cpp @@ -665,7 +665,7 @@ bool ASTJsonExporter::visit(InlineAssembly const& _node) externalReferencesJson.emplace_back(std::move(it)); std::vector> attributes = { - std::make_pair("AST", Json(yul::AsmJsonConverter(sourceIndexFromLocation(_node.location()))(_node.operations()))), + std::make_pair("AST", Json(yul::AsmJsonConverter(sourceIndexFromLocation(_node.location()))(_node.operations().root()))), std::make_pair("externalReferences", std::move(externalReferencesJson)), std::make_pair("evmVersion", dynamic_cast(_node.dialect()).evmVersion().name()) }; diff --git a/libsolidity/ast/ASTJsonImporter.cpp b/libsolidity/ast/ASTJsonImporter.cpp index 728d77c0de8b..8d72b41f7579 100644 --- a/libsolidity/ast/ASTJsonImporter.cpp +++ b/libsolidity/ast/ASTJsonImporter.cpp @@ -733,7 +733,7 @@ ASTPointer ASTJsonImporter::createInlineAssembly(Json const& _no flags->emplace_back(std::make_shared(flag.get())); } } - std::shared_ptr operations = std::make_shared(yul::AsmJsonImporter(m_sourceNames).createBlock(member(_node, "AST"))); + std::shared_ptr operations = std::make_shared(yul::AsmJsonImporter(m_sourceNames).createAST(member(_node, "AST"))); return createASTNode( _node, nullOrASTString(_node, "documentation"), diff --git a/libsolidity/codegen/CompilerContext.cpp b/libsolidity/codegen/CompilerContext.cpp index 962defdbc8e1..aa6985503fdb 100644 --- a/libsolidity/codegen/CompilerContext.cpp +++ b/libsolidity/codegen/CompilerContext.cpp @@ -440,7 +440,7 @@ void CompilerContext::appendInlineAssembly( std::optional locationOverride; if (!_system) locationOverride = m_asm->currentSourceLocation(); - std::shared_ptr parserResult = + std::shared_ptr parserResult = yul::Parser(errorReporter, dialect, std::move(locationOverride)) .parse(charStream); #ifdef SOL_OUTPUT_ASM @@ -472,7 +472,7 @@ void CompilerContext::appendInlineAssembly( errorReporter, dialect, identifierAccess.resolve - ).analyze(*parserResult); + ).analyze(parserResult->root()); if (!parserResult || !errorReporter.errors().empty() || !analyzerResult) reportError("Invalid assembly generated by code generator."); @@ -491,8 +491,8 @@ void CompilerContext::appendInlineAssembly( { // Store as generated sources, but first re-parse to update the source references. solAssert(m_generatedYulUtilityCode.empty(), ""); - m_generatedYulUtilityCode = yul::AsmPrinter(yul::AsmPrinter::TypePrinting::OmitDefault, dialect)(*obj.code); - std::string code = yul::AsmPrinter{yul::AsmPrinter::TypePrinting::OmitDefault, dialect}(*obj.code); + m_generatedYulUtilityCode = yul::AsmPrinter(yul::AsmPrinter::TypePrinting::OmitDefault, dialect)(obj.code->root()); + std::string code = yul::AsmPrinter{yul::AsmPrinter::TypePrinting::OmitDefault, dialect}(obj.code->root()); langutil::CharStream charStream(m_generatedYulUtilityCode, _sourceName); obj.code = yul::Parser(errorReporter, dialect).parse(charStream); *obj.analysisInfo = yul::AsmAnalyzer::analyzeStrictAssertCorrect(dialect, obj); @@ -518,7 +518,7 @@ void CompilerContext::appendInlineAssembly( solAssert(errorReporter.errors().empty(), "Failed to analyze inline assembly block."); yul::CodeGenerator::assemble( - *parserResult, + parserResult->root(), analysisInfo, *m_asm, m_evmVersion, diff --git a/libsolidity/codegen/ContractCompiler.cpp b/libsolidity/codegen/ContractCompiler.cpp index 0ed17f6d02b0..21899f72a607 100644 --- a/libsolidity/codegen/ContractCompiler.cpp +++ b/libsolidity/codegen/ContractCompiler.cpp @@ -927,7 +927,7 @@ bool ContractCompiler::visit(InlineAssembly const& _inlineAssembly) } }; - yul::Block const* code = &_inlineAssembly.operations(); + yul::AST const* code = &_inlineAssembly.operations(); yul::AsmAnalysisInfo* analysisInfo = _inlineAssembly.annotation().analysisInfo.get(); // Only used in the scope below, but required to live outside to keep the @@ -944,7 +944,7 @@ bool ContractCompiler::visit(InlineAssembly const& _inlineAssembly) solAssert(dialect, ""); // Create a modifiable copy of the code and analysis - object.code = std::make_shared(yul::ASTCopier().translate(*code)); + object.code = std::make_shared(yul::ASTCopier().translate(code->root())); object.analysisInfo = std::make_shared(yul::AsmAnalyzer::analyzeStrictAssertCorrect(*dialect, object)); m_context.optimizeYul(object, *dialect, m_optimiserSettings); @@ -954,7 +954,7 @@ bool ContractCompiler::visit(InlineAssembly const& _inlineAssembly) } yul::CodeGenerator::assemble( - *code, + code->root(), *analysisInfo, *m_context.assemblyPtr(), m_context.evmVersion(), diff --git a/libsolidity/codegen/ir/IRGeneratorForStatements.cpp b/libsolidity/codegen/ir/IRGeneratorForStatements.cpp index 4f4f96329aad..459959604625 100644 --- a/libsolidity/codegen/ir/IRGeneratorForStatements.cpp +++ b/libsolidity/codegen/ir/IRGeneratorForStatements.cpp @@ -2252,7 +2252,7 @@ bool IRGeneratorForStatements::visit(InlineAssembly const& _inlineAsm) m_context.setMemoryUnsafeInlineAssemblySeen(); CopyTranslate bodyCopier{_inlineAsm.dialect(), m_context, _inlineAsm.annotation().externalReferences}; - yul::Statement modified = bodyCopier(_inlineAsm.operations()); + yul::Statement modified = bodyCopier(_inlineAsm.operations().root()); solAssert(std::holds_alternative(modified)); diff --git a/libsolidity/experimental/analysis/TypeInference.cpp b/libsolidity/experimental/analysis/TypeInference.cpp index 6913dc0bf7cd..19f019c86c4e 100644 --- a/libsolidity/experimental/analysis/TypeInference.cpp +++ b/libsolidity/experimental/analysis/TypeInference.cpp @@ -302,7 +302,7 @@ bool TypeInference::visit(InlineAssembly const& _inlineAssembly) _inlineAssembly.dialect(), identifierAccess ); - if (!analyzer.analyze(_inlineAssembly.operations())) + if (!analyzer.analyze(_inlineAssembly.operations().root())) solAssert(m_errorReporter.hasErrors()); return false; } diff --git a/libsolidity/experimental/codegen/IRGeneratorForStatements.cpp b/libsolidity/experimental/codegen/IRGeneratorForStatements.cpp index 109c3ee6f103..3c8bcc9bbbab 100644 --- a/libsolidity/experimental/codegen/IRGeneratorForStatements.cpp +++ b/libsolidity/experimental/codegen/IRGeneratorForStatements.cpp @@ -130,7 +130,7 @@ bool IRGeneratorForStatements::visit(TupleExpression const& _tupleExpression) bool IRGeneratorForStatements::visit(InlineAssembly const& _assembly) { CopyTranslate bodyCopier{m_context, _assembly.dialect(), _assembly.annotation().externalReferences}; - yul::Statement modified = bodyCopier(_assembly.operations()); + yul::Statement modified = bodyCopier(_assembly.operations().root()); solAssert(std::holds_alternative(modified)); m_code << yul::AsmPrinter(yul::AsmPrinter::TypePrinting::Full, _assembly.dialect())(std::get(modified)) << "\n"; return false; diff --git a/libsolidity/formal/SMTEncoder.cpp b/libsolidity/formal/SMTEncoder.cpp index 44282289d1e2..7e338d9f80b9 100644 --- a/libsolidity/formal/SMTEncoder.cpp +++ b/libsolidity/formal/SMTEncoder.cpp @@ -313,7 +313,7 @@ bool SMTEncoder::visit(InlineAssembly const& _inlineAsm) { AssignedExternalsCollector(InlineAssembly const& _inlineAsm): externalReferences(_inlineAsm.annotation().externalReferences) { - this->operator()(_inlineAsm.operations()); + this->operator()(_inlineAsm.operations().root()); } std::map const& externalReferences; @@ -330,7 +330,7 @@ bool SMTEncoder::visit(InlineAssembly const& _inlineAsm) } }; - yul::SideEffectsCollector sideEffectsCollector(_inlineAsm.dialect(), _inlineAsm.operations()); + yul::SideEffectsCollector sideEffectsCollector(_inlineAsm.dialect(), _inlineAsm.operations().root()); if (sideEffectsCollector.invalidatesMemory()) resetMemoryVariables(); if (sideEffectsCollector.invalidatesStorage()) diff --git a/libsolidity/interface/CompilerStack.cpp b/libsolidity/interface/CompilerStack.cpp index de7b185d295e..dd5d20126ebe 100644 --- a/libsolidity/interface/CompilerStack.cpp +++ b/libsolidity/interface/CompilerStack.cpp @@ -846,9 +846,9 @@ Json CompilerStack::generatedSources(std::string const& _contractName, bool _run ErrorReporter errorReporter(errors); CharStream charStream(source, sourceName); yul::EVMDialect const& dialect = yul::EVMDialect::strictAssemblyForEVM(m_evmVersion); - std::shared_ptr parserResult = yul::Parser{errorReporter, dialect}.parse(charStream); + std::shared_ptr parserResult = yul::Parser{errorReporter, dialect}.parse(charStream); solAssert(parserResult, ""); - sources[0]["ast"] = yul::AsmJsonConverter{sourceIndex}(*parserResult); + sources[0]["ast"] = yul::AsmJsonConverter{sourceIndex}(parserResult->root()); sources[0]["name"] = sourceName; sources[0]["id"] = sourceIndex; sources[0]["language"] = "Yul"; diff --git a/libsolidity/parsing/Parser.cpp b/libsolidity/parsing/Parser.cpp index b51eb9c44099..5c28c44f2c45 100644 --- a/libsolidity/parsing/Parser.cpp +++ b/libsolidity/parsing/Parser.cpp @@ -1473,12 +1473,12 @@ ASTPointer Parser::parseInlineAssembly(ASTPointer con } yul::Parser asmParser(m_errorReporter, dialect); - std::shared_ptr block = asmParser.parseInline(m_scanner); - if (block == nullptr) + std::shared_ptr ast = asmParser.parseInline(m_scanner); + if (ast == nullptr) BOOST_THROW_EXCEPTION(FatalError()); - location.end = nativeLocationOf(*block).end; - return std::make_shared(nextID(), location, _docString, dialect, std::move(flags), block); + location.end = nativeLocationOf(ast->root()).end; + return std::make_shared(nextID(), location, _docString, dialect, std::move(flags), ast); } ASTPointer Parser::parseIfStatement(ASTPointer const& _docString) diff --git a/libyul/AST.h b/libyul/AST.h index 72be60a46843..ca4846907e40 100644 --- a/libyul/AST.h +++ b/libyul/AST.h @@ -101,6 +101,18 @@ struct Continue { langutil::DebugData::ConstPtr debugData; }; /// Leave statement (valid within function) struct Leave { langutil::DebugData::ConstPtr debugData; }; +/// Immutable AST comprised of its top-level block +class AST +{ +public: + explicit AST(Block _root): m_root(std::move(_root)) {} + + Block const& root() const { return m_root; } +private: + Block m_root; +}; + + /// Extracts the IR source location from a Yul node. template inline langutil::SourceLocation nativeLocationOf(T const& _node) { diff --git a/libyul/ASTForward.h b/libyul/ASTForward.h index 12992edf8872..f6fa09387739 100644 --- a/libyul/ASTForward.h +++ b/libyul/ASTForward.h @@ -46,6 +46,7 @@ struct Continue; struct Leave; struct ExpressionStatement; struct Block; +class AST; struct TypedName; diff --git a/libyul/AsmAnalysis.cpp b/libyul/AsmAnalysis.cpp index cccb3de42158..dae945fe8796 100644 --- a/libyul/AsmAnalysis.cpp +++ b/libyul/AsmAnalysis.cpp @@ -85,6 +85,15 @@ bool AsmAnalyzer::analyze(Block const& _block) } AsmAnalysisInfo AsmAnalyzer::analyzeStrictAssertCorrect(Dialect const& _dialect, Object const& _object) +{ + return analyzeStrictAssertCorrect(_dialect, _object.code->root(), _object.qualifiedDataNames()); +} + +AsmAnalysisInfo AsmAnalyzer::analyzeStrictAssertCorrect( + Dialect const& _dialect, + Block const& _astRoot, + std::set const& _qualifiedDataNames +) { ErrorList errorList; langutil::ErrorReporter errors(errorList); @@ -94,8 +103,8 @@ AsmAnalysisInfo AsmAnalyzer::analyzeStrictAssertCorrect(Dialect const& _dialect, errors, _dialect, {}, - _object.qualifiedDataNames() - ).analyze(*_object.code); + _qualifiedDataNames + ).analyze(_astRoot); yulAssert(success && !errors.hasErrors(), "Invalid assembly/yul code."); return analysisInfo; } diff --git a/libyul/AsmAnalysis.h b/libyul/AsmAnalysis.h index 5aa7fe4968f6..d479a9970d71 100644 --- a/libyul/AsmAnalysis.h +++ b/libyul/AsmAnalysis.h @@ -78,6 +78,11 @@ class AsmAnalyzer /// Performs analysis on the outermost code of the given object and returns the analysis info. /// Asserts on failure. static AsmAnalysisInfo analyzeStrictAssertCorrect(Dialect const& _dialect, Object const& _object); + static AsmAnalysisInfo analyzeStrictAssertCorrect( + Dialect const& _dialect, + Block const& _astRoot, + std::set const& _qualifiedDataNames + ); std::vector operator()(Literal const& _literal); std::vector operator()(Identifier const&); diff --git a/libyul/AsmJsonImporter.cpp b/libyul/AsmJsonImporter.cpp index 8f211f31b435..65ff22999b39 100644 --- a/libyul/AsmJsonImporter.cpp +++ b/libyul/AsmJsonImporter.cpp @@ -49,6 +49,11 @@ SourceLocation const AsmJsonImporter::createSourceLocation(Json const& _node) return solidity::langutil::parseSourceLocation(_node["src"].get(), m_sourceNames); } +AST AsmJsonImporter::createAST(solidity::Json const& _node) +{ + return AST(createBlock(_node)); +} + template T AsmJsonImporter::createAsmNode(Json const& _node) { diff --git a/libyul/AsmJsonImporter.h b/libyul/AsmJsonImporter.h index 87933761a654..d835e99e39a3 100644 --- a/libyul/AsmJsonImporter.h +++ b/libyul/AsmJsonImporter.h @@ -41,8 +41,8 @@ class AsmJsonImporter explicit AsmJsonImporter(std::vector> const& _sourceNames): m_sourceNames(_sourceNames) {} - yul::Block createBlock(Json const& _node); + yul::AST createAST(Json const& node); private: langutil::SourceLocation const createSourceLocation(Json const& _node); template @@ -51,6 +51,7 @@ class AsmJsonImporter /// and throw an error if it does not exist Json member(Json const& _node, std::string const& _name); + yul::Block createBlock(Json const& _node); yul::Statement createStatement(Json const& _node); yul::Expression createExpression(Json const& _node); std::vector createStatementVector(Json const& _array); diff --git a/libyul/AsmParser.cpp b/libyul/AsmParser.cpp index 41bef57fe0f1..6223a1a8e1c3 100644 --- a/libyul/AsmParser.cpp +++ b/libyul/AsmParser.cpp @@ -104,15 +104,15 @@ void Parser::updateLocationEndFrom( } } -std::unique_ptr Parser::parse(CharStream& _charStream) +std::unique_ptr Parser::parse(CharStream& _charStream) { m_scanner = std::make_shared(_charStream); - std::unique_ptr block = parseInline(m_scanner); + std::unique_ptr ast = parseInline(m_scanner); expectToken(Token::EOS); - return block; + return ast; } -std::unique_ptr Parser::parseInline(std::shared_ptr const& _scanner) +std::unique_ptr Parser::parseInline(std::shared_ptr const& _scanner) { m_recursionDepth = 0; @@ -125,7 +125,7 @@ std::unique_ptr Parser::parseInline(std::shared_ptr const& _scan m_scanner = _scanner; if (m_useSourceLocationFrom == UseSourceLocationFrom::Comments) fetchDebugDataFromComment(); - return std::make_unique(parseBlock()); + return std::make_unique(parseBlock()); } catch (FatalError const& error) { diff --git a/libyul/AsmParser.h b/libyul/AsmParser.h index 408c8029cf58..dd206b5b1ee8 100644 --- a/libyul/AsmParser.h +++ b/libyul/AsmParser.h @@ -87,12 +87,12 @@ class Parser: public langutil::ParserBase /// Parses an inline assembly block starting with `{` and ending with `}`. /// @returns an empty shared pointer on error. - std::unique_ptr parseInline(std::shared_ptr const& _scanner); + std::unique_ptr parseInline(std::shared_ptr const& _scanner); /// Parses an assembly block starting with `{` and ending with `}` /// and expects end of input after the '}'. /// @returns an empty shared pointer on error. - std::unique_ptr parse(langutil::CharStream& _charStream); + std::unique_ptr parse(langutil::CharStream& _charStream); protected: langutil::SourceLocation currentLocation() const override diff --git a/libyul/CompilabilityChecker.cpp b/libyul/CompilabilityChecker.cpp index 9e18f48d824c..76affbd64756 100644 --- a/libyul/CompilabilityChecker.cpp +++ b/libyul/CompilabilityChecker.cpp @@ -33,15 +33,22 @@ using namespace solidity::util; CompilabilityChecker::CompilabilityChecker( Dialect const& _dialect, Object const& _object, - bool _optimizeStackAllocation + bool _optimizeStackAllocation, + Block const* _block ) { + yulAssert(_object.code || _block); if (auto const* evmDialect = dynamic_cast(&_dialect)) { + if (!_block) + _block = &_object.code->root(); NoOutputEVMDialect noOutputDialect(*evmDialect); - yul::AsmAnalysisInfo analysisInfo = - yul::AsmAnalyzer::analyzeStrictAssertCorrect(noOutputDialect, _object); + yul::AsmAnalysisInfo analysisInfo = yul::AsmAnalyzer::analyzeStrictAssertCorrect( + noOutputDialect, + *_block, + _object.qualifiedDataNames() + ); BuiltinContext builtinContext; builtinContext.currentObject = &_object; @@ -53,12 +60,12 @@ CompilabilityChecker::CompilabilityChecker( CodeTransform transform( assembly, analysisInfo, - *_object.code, + *_block, noOutputDialect, builtinContext, _optimizeStackAllocation ); - transform(*_object.code); + transform(*_block); for (StackTooDeepError const& error: transform.stackErrors()) { diff --git a/libyul/CompilabilityChecker.h b/libyul/CompilabilityChecker.h index 89bb7aa7c993..1dd66999066d 100644 --- a/libyul/CompilabilityChecker.h +++ b/libyul/CompilabilityChecker.h @@ -44,7 +44,12 @@ namespace solidity::yul */ struct CompilabilityChecker { - CompilabilityChecker(Dialect const& _dialect, Object const& _object, bool _optimizeStackAllocation); + CompilabilityChecker( + Dialect const& _dialect, + Object const& _object, + bool _optimizeStackAllocation, + Block const* _blockOverride = nullptr + ); std::map> unreachableVariables; std::map stackDeficit; }; diff --git a/libyul/Object.cpp b/libyul/Object.cpp index 989e7ce809de..98649b29bec6 100644 --- a/libyul/Object.cpp +++ b/libyul/Object.cpp @@ -69,7 +69,7 @@ std::string Object::toString( debugData->sourceNames, _debugInfoSelection, _soliditySourceProvider - )(*code); + )(code->root()); for (auto const& obj: subObjects) inner += "\n" + obj->toString(_dialect, _printingMode, _debugInfoSelection, _soliditySourceProvider); @@ -91,7 +91,7 @@ Json Object::toJson() const Json codeJson; codeJson["nodeType"] = "YulCode"; - codeJson["block"] = AsmJsonConverter(0 /* sourceIndex */)(*code); + codeJson["block"] = AsmJsonConverter(0 /* sourceIndex */)(code->root()); Json subObjectsJson = Json::array(); for (std::shared_ptr const& subObject: subObjects) diff --git a/libyul/Object.h b/libyul/Object.h index c419a6d55e39..cab3bc701bb2 100644 --- a/libyul/Object.h +++ b/libyul/Object.h @@ -122,7 +122,7 @@ struct Object: public ObjectNode /// sub id for object if it is subobject of another object, max value if it is not subobject size_t subId = std::numeric_limits::max(); - std::shared_ptr code; + std::shared_ptr code; std::vector> subObjects; std::map> subIndexByName; std::shared_ptr analysisInfo; diff --git a/libyul/ObjectParser.cpp b/libyul/ObjectParser.cpp index 1f5363fd8d59..6813e5059395 100644 --- a/libyul/ObjectParser.cpp +++ b/libyul/ObjectParser.cpp @@ -106,7 +106,7 @@ std::shared_ptr ObjectParser::parseObject(Object* _containingObject) return ret; } -std::shared_ptr ObjectParser::parseCode(std::optional _sourceNames) +std::shared_ptr ObjectParser::parseCode(std::optional _sourceNames) { if (currentToken() != Token::Identifier || currentLiteral() != "code") fatalParserError(4846_error, "Expected keyword \"code\"."); @@ -169,12 +169,12 @@ std::optional ObjectParser::tryParseSourceNameMapping() const return std::nullopt; } -std::shared_ptr ObjectParser::parseBlock(std::optional _sourceNames) +std::shared_ptr ObjectParser::parseBlock(std::optional _sourceNames) { Parser parser(m_errorReporter, m_dialect, std::move(_sourceNames)); - std::shared_ptr block = parser.parseInline(m_scanner); - yulAssert(block || m_errorReporter.hasErrors(), "Invalid block but no error!"); - return block; + auto ast = parser.parseInline(m_scanner); + yulAssert(ast || m_errorReporter.hasErrors(), "Invalid block but no error!"); + return ast; } void ObjectParser::parseData(Object& _containingObject) diff --git a/libyul/ObjectParser.h b/libyul/ObjectParser.h index a8f75d373c9b..1d7756f5ae71 100644 --- a/libyul/ObjectParser.h +++ b/libyul/ObjectParser.h @@ -57,8 +57,8 @@ class ObjectParser: public langutil::ParserBase private: std::optional tryParseSourceNameMapping() const; std::shared_ptr parseObject(Object* _containingObject = nullptr); - std::shared_ptr parseCode(std::optional _sourceNames); - std::shared_ptr parseBlock(std::optional _sourceNames); + std::shared_ptr parseCode(std::optional _sourceNames); + std::shared_ptr parseBlock(std::optional _sourceNames); void parseData(Object& _containingObject); /// Tries to parse a name that is non-empty and unique inside the containing object. diff --git a/libyul/YulStack.cpp b/libyul/YulStack.cpp index b9fc6388c6bd..426551152a65 100644 --- a/libyul/YulStack.cpp +++ b/libyul/YulStack.cpp @@ -149,7 +149,7 @@ bool YulStack::analyzeParsed(Object& _object) bool success = false; try { - success = analyzer.analyze(*_object.code); + success = analyzer.analyze(_object.code->root()); for (auto& subNode: _object.subObjects) if (auto subObject = dynamic_cast(subNode.get())) if (!analyzeParsed(*subObject)) diff --git a/libyul/backends/evm/EVMObjectCompiler.cpp b/libyul/backends/evm/EVMObjectCompiler.cpp index 422c08bf96aa..c77bf4e37c1c 100644 --- a/libyul/backends/evm/EVMObjectCompiler.cpp +++ b/libyul/backends/evm/EVMObjectCompiler.cpp @@ -83,7 +83,7 @@ void EVMObjectCompiler::run(Object& _object, bool _optimize) auto stackErrors = OptimizedEVMCodeTransform::run( m_assembly, *_object.analysisInfo, - *_object.code, + _object.code->root(), m_dialect, context, OptimizedEVMCodeTransform::UseNamedLabels::ForFirstFunctionOfEachName @@ -91,7 +91,7 @@ void EVMObjectCompiler::run(Object& _object, bool _optimize) if (!stackErrors.empty()) { std::vector memoryGuardCalls = findFunctionCalls( - std::as_const(*_object.code), + _object.code->root(), "memoryguard"_yulname ); auto stackError = stackErrors.front(); @@ -113,14 +113,14 @@ void EVMObjectCompiler::run(Object& _object, bool _optimize) CodeTransform transform{ m_assembly, *_object.analysisInfo, - *_object.code, + _object.code->root(), m_dialect, context, _optimize, {}, CodeTransform::UseNamedLabels::ForFirstFunctionOfEachName }; - transform(*_object.code); + transform(_object.code->root()); if (!transform.stackErrors().empty()) BOOST_THROW_EXCEPTION(transform.stackErrors().front()); } diff --git a/libyul/optimiser/Semantics.cpp b/libyul/optimiser/Semantics.cpp index 7dbbb676b43b..88f4f7c45b5e 100644 --- a/libyul/optimiser/Semantics.cpp +++ b/libyul/optimiser/Semantics.cpp @@ -95,7 +95,7 @@ bool MSizeFinder::containsMSize(Dialect const& _dialect, Block const& _ast) bool MSizeFinder::containsMSize(Dialect const& _dialect, Object const& _object) { - if (containsMSize(_dialect, *_object.code)) + if (containsMSize(_dialect, _object.code->root())) return true; for (std::shared_ptr const& node: _object.subObjects) diff --git a/libyul/optimiser/StackCompressor.cpp b/libyul/optimiser/StackCompressor.cpp index 23d47b6ee554..10360756d670 100644 --- a/libyul/optimiser/StackCompressor.cpp +++ b/libyul/optimiser/StackCompressor.cpp @@ -21,6 +21,7 @@ #include +#include #include #include #include @@ -241,10 +242,23 @@ bool StackCompressor::run( bool _optimizeStackAllocation, size_t _maxIterations ) +{ + yulAssert(_object.code); + auto block = std::get(ASTCopier{}(_object.code->root())); + auto result = run(_dialect, block, _object, _optimizeStackAllocation, _maxIterations); + _object.code = std::make_shared(std::move(block)); + return result; +} + +bool StackCompressor::run( + Dialect const& _dialect, + Block& _astRoot, + Object const& _object, + bool _optimizeStackAllocation, + size_t _maxIterations) { yulAssert( - _object.code && - _object.code->statements.size() > 0 && std::holds_alternative(_object.code->statements.at(0)), + !_astRoot.statements.empty() && std::holds_alternative(_astRoot.statements.at(0)), "Need to run the function grouper before the stack compressor." ); bool usesOptimizedCodeGenerator = false; @@ -253,14 +267,14 @@ bool StackCompressor::run( _optimizeStackAllocation && evmDialect->evmVersion().canOverchargeGasForCall() && evmDialect->providesObjectAccess(); - bool allowMSizeOptimization = !MSizeFinder::containsMSize(_dialect, *_object.code); + bool allowMSizeOptimization = !MSizeFinder::containsMSize(_dialect, _astRoot); if (usesOptimizedCodeGenerator) { - yul::AsmAnalysisInfo analysisInfo = yul::AsmAnalyzer::analyzeStrictAssertCorrect(_dialect, _object); - std::unique_ptr cfg = ControlFlowGraphBuilder::build(analysisInfo, _dialect, *_object.code); + yul::AsmAnalysisInfo analysisInfo = yul::AsmAnalyzer::analyzeStrictAssertCorrect(_dialect, _astRoot, _object.qualifiedDataNames()); + std::unique_ptr cfg = ControlFlowGraphBuilder::build(analysisInfo, _dialect, _astRoot); eliminateVariablesOptimizedCodegen( _dialect, - *_object.code, + _astRoot, StackLayoutGenerator::reportStackTooDeep(*cfg), allowMSizeOptimization ); @@ -268,12 +282,12 @@ bool StackCompressor::run( else for (size_t iterations = 0; iterations < _maxIterations; iterations++) { - std::map stackSurplus = CompilabilityChecker(_dialect, _object, _optimizeStackAllocation).stackDeficit; + std::map stackSurplus = CompilabilityChecker(_dialect, _object, _optimizeStackAllocation, &_astRoot).stackDeficit; if (stackSurplus.empty()) return true; eliminateVariables( _dialect, - *_object.code, + _astRoot, stackSurplus, allowMSizeOptimization ); diff --git a/libyul/optimiser/StackCompressor.h b/libyul/optimiser/StackCompressor.h index d18618667f71..13b9459a28e7 100644 --- a/libyul/optimiser/StackCompressor.h +++ b/libyul/optimiser/StackCompressor.h @@ -44,7 +44,7 @@ struct FunctionDefinition; class StackCompressor { public: - /// Try to remove local variables until the AST is compilable. + /// Try to remove local variables until the AST is compilable. Modifies the object's AST. /// @returns true if it was successful. static bool run( Dialect const& _dialect, @@ -52,6 +52,17 @@ class StackCompressor bool _optimizeStackAllocation, size_t _maxIterations ); + + /// Try to remove local variables until the AST is compilable. Operates on provided block, + /// disregards the AST contained in object. + /// @returns true if it was successful. + static bool run( + Dialect const& _dialect, + Block& _astRoot, + Object const& _object, + bool _optimizeStackAllocation, + size_t _maxIterations + ); }; } diff --git a/libyul/optimiser/StackLimitEvader.cpp b/libyul/optimiser/StackLimitEvader.cpp index 24712938f03b..210be1cf38b6 100644 --- a/libyul/optimiser/StackLimitEvader.cpp +++ b/libyul/optimiser/StackLimitEvader.cpp @@ -119,7 +119,8 @@ u256 literalArgumentValue(FunctionCall const& _call) void StackLimitEvader::run( OptimiserStepContext& _context, - Object& _object + Block& _astRoot, + Object const& _object ) { auto const* evmDialect = dynamic_cast(&_context.dialect); @@ -129,22 +130,23 @@ void StackLimitEvader::run( ); if (evmDialect && evmDialect->evmVersion().canOverchargeGasForCall()) { - yul::AsmAnalysisInfo analysisInfo = yul::AsmAnalyzer::analyzeStrictAssertCorrect(*evmDialect, _object); - std::unique_ptr cfg = ControlFlowGraphBuilder::build(analysisInfo, *evmDialect, *_object.code); - run(_context, _object, StackLayoutGenerator::reportStackTooDeep(*cfg)); + yul::AsmAnalysisInfo analysisInfo = yul::AsmAnalyzer::analyzeStrictAssertCorrect(*evmDialect, _astRoot, _object.qualifiedDataNames()); + std::unique_ptr cfg = ControlFlowGraphBuilder::build(analysisInfo, *evmDialect, _astRoot); + run(_context, _astRoot, StackLayoutGenerator::reportStackTooDeep(*cfg)); } else - run(_context, _object, CompilabilityChecker{ + run(_context, _astRoot, CompilabilityChecker{ _context.dialect, _object, - true + true, + &_astRoot }.unreachableVariables); } void StackLimitEvader::run( OptimiserStepContext& _context, - Object& _object, + Block& _astRoot, std::map> const& _stackTooDeepErrors ) { @@ -158,23 +160,22 @@ void StackLimitEvader::run( if (!util::contains(unreachables, variable)) unreachables.emplace_back(variable); } - run(_context, _object, unreachableVariables); + run(_context, _astRoot, unreachableVariables); } void StackLimitEvader::run( OptimiserStepContext& _context, - Object& _object, + Block& _astRoot, std::map> const& _unreachableVariables ) { - yulAssert(_object.code, ""); auto const* evmDialect = dynamic_cast(&_context.dialect); yulAssert( evmDialect && evmDialect->providesObjectAccess(), "StackLimitEvader can only be run on objects using the EVMDialect with object access." ); - std::vector memoryGuardCalls = findFunctionCalls(*_object.code, "memoryguard"_yulname); + std::vector memoryGuardCalls = findFunctionCalls(_astRoot, "memoryguard"_yulname); // Do not optimise, if no ``memoryguard`` call is found. if (memoryGuardCalls.empty()) return; @@ -187,23 +188,23 @@ void StackLimitEvader::run( if (reservedMemory != literalArgumentValue(*memoryGuardCall)) return; - CallGraph callGraph = CallGraphGenerator::callGraph(*_object.code); + CallGraph callGraph = CallGraphGenerator::callGraph(_astRoot); // We cannot move variables in recursive functions to fixed memory offsets. for (YulName function: callGraph.recursiveFunctions()) if (_unreachableVariables.count(function)) return; - std::map functionDefinitions = allFunctionDefinitions(*_object.code); + std::map functionDefinitions = allFunctionDefinitions(_astRoot); MemoryOffsetAllocator memoryOffsetAllocator{_unreachableVariables, callGraph.functionCalls, functionDefinitions}; uint64_t requiredSlots = memoryOffsetAllocator.run(); yulAssert(requiredSlots < (uint64_t(1) << 32) - 1, ""); - StackToMemoryMover::run(_context, reservedMemory, memoryOffsetAllocator.slotAllocations, requiredSlots, *_object.code); + StackToMemoryMover::run(_context, reservedMemory, memoryOffsetAllocator.slotAllocations, requiredSlots, _astRoot); reservedMemory += 32 * requiredSlots; - for (FunctionCall* memoryGuardCall: findFunctionCalls(*_object.code, "memoryguard"_yulname)) + for (FunctionCall* memoryGuardCall: findFunctionCalls(_astRoot, "memoryguard"_yulname)) { Literal* literal = std::get_if(&memoryGuardCall->arguments.front()); yulAssert(literal && literal->kind == LiteralKind::Number, ""); diff --git a/libyul/optimiser/StackLimitEvader.h b/libyul/optimiser/StackLimitEvader.h index 0411f05735bc..5029f7825f4b 100644 --- a/libyul/optimiser/StackLimitEvader.h +++ b/libyul/optimiser/StackLimitEvader.h @@ -59,7 +59,7 @@ class StackLimitEvader /// are contained in a recursive function. static void run( OptimiserStepContext& _context, - Object& _object, + Block& _astRoot, std::map> const& _unreachableVariables ); /// @a _stackTooDeepErrors can be determined by the StackLayoutGenerator. @@ -69,7 +69,7 @@ class StackLimitEvader /// are contained in a recursive function. static void run( OptimiserStepContext& _context, - Object& _object, + Block& _astRoot, std::map> const& _stackTooDeepErrors ); /// Determines stack too deep errors using the appropriate code generation backend. @@ -79,7 +79,8 @@ class StackLimitEvader /// are contained in a recursive function. static void run( OptimiserStepContext& _context, - Object& _object + Block& _astRoot, + Object const& _object ); }; diff --git a/libyul/optimiser/Suite.cpp b/libyul/optimiser/Suite.cpp index c022fb0d7451..b8826bb8a339 100644 --- a/libyul/optimiser/Suite.cpp +++ b/libyul/optimiser/Suite.cpp @@ -153,74 +153,76 @@ void OptimiserSuite::run( std::set reservedIdentifiers = _externallyUsedIdentifiers; reservedIdentifiers += _dialect.fixedFunctionNames(); - *_object.code = std::get(Disambiguator( + auto astRoot = std::get(Disambiguator( _dialect, *_object.analysisInfo, reservedIdentifiers - )(*_object.code)); - Block& ast = *_object.code; + )(_object.code->root())); - NameDispenser dispenser{_dialect, ast, reservedIdentifiers}; + NameDispenser dispenser{_dialect, astRoot, 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. - suite.runSequence("hgfo", ast); + suite.runSequence("hgfo", astRoot); - NameSimplifier::run(suite.m_context, ast); + NameSimplifier::run(suite.m_context, astRoot); // Now the user-supplied part - suite.runSequence(_optimisationSequence, ast); + suite.runSequence(_optimisationSequence, astRoot); // This is a tuning parameter, but actually just prevents infinite loops. size_t stackCompressorMaxIterations = 16; - suite.runSequence("g", ast); + suite.runSequence("g", astRoot); // We ignore the return value because we will get a much better error // message once we perform code generation. if (!usesOptimizedCodeGenerator) StackCompressor::run( _dialect, + astRoot, _object, _optimizeStackAllocation, stackCompressorMaxIterations ); // Run the user-supplied clean up sequence - suite.runSequence(_optimisationCleanupSequence, ast); + suite.runSequence(_optimisationCleanupSequence, astRoot); // Hard-coded FunctionGrouper step is used to bring the AST into a canonical form required by the StackCompressor // and StackLimitEvader. This is hard-coded as the last step, as some previously executed steps may break the // aforementioned form, thus causing the StackCompressor/StackLimitEvader to throw. - suite.runSequence("g", ast); + suite.runSequence("g", astRoot); if (evmDialect) { yulAssert(_meter, ""); - ConstantOptimiser{*evmDialect, *_meter}(ast); + ConstantOptimiser{*evmDialect, *_meter}(astRoot); if (usesOptimizedCodeGenerator) { StackCompressor::run( _dialect, + astRoot, _object, _optimizeStackAllocation, stackCompressorMaxIterations ); if (evmDialect->providesObjectAccess()) - StackLimitEvader::run(suite.m_context, _object); + StackLimitEvader::run(suite.m_context, astRoot, _object); } else if (evmDialect->providesObjectAccess() && _optimizeStackAllocation) - StackLimitEvader::run(suite.m_context, _object); + StackLimitEvader::run(suite.m_context, astRoot, _object); } - dispenser.reset(ast); - NameSimplifier::run(suite.m_context, ast); - VarNameCleaner::run(suite.m_context, ast); + dispenser.reset(astRoot); + NameSimplifier::run(suite.m_context, astRoot); + VarNameCleaner::run(suite.m_context, astRoot); #ifdef PROFILE_OPTIMIZER_STEPS outputPerformanceMetrics(suite.m_durationPerStepInMicroseconds); #endif + _object.code = std::make_shared(std::move(astRoot)); *_object.analysisInfo = AsmAnalyzer::analyzeStrictAssertCorrect(_dialect, _object); } diff --git a/test/libsolidity/MemoryGuardTest.cpp b/test/libsolidity/MemoryGuardTest.cpp index 77274200bbb3..c5579d84a166 100644 --- a/test/libsolidity/MemoryGuardTest.cpp +++ b/test/libsolidity/MemoryGuardTest.cpp @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -74,7 +75,7 @@ TestCase::TestResult MemoryGuardTest::run(std::ostream& _stream, std::string con auto handleObject = [&](std::string const& _kind, Object const& _object) { m_obtainedResult += contractName + "(" + _kind + ") " + (findFunctionCalls( - *_object.code, + _object.code->root(), "memoryguard"_yulname ).empty() ? "false" : "true") + "\n"; }; diff --git a/test/libyul/Common.cpp b/test/libyul/Common.cpp index dece0d82b10e..26f5e0684602 100644 --- a/test/libyul/Common.cpp +++ b/test/libyul/Common.cpp @@ -50,7 +50,7 @@ Dialect const& defaultDialect(bool _yul) } } -std::pair, std::shared_ptr> yul::test::parse(std::string const& _source, bool _yul) +std::pair, std::shared_ptr> yul::test::parse(std::string const& _source, bool _yul) { YulStack stack( solidity::test::CommonOptions::get().evmVersion(), @@ -83,7 +83,7 @@ std::pair, std::shared_ptr> yul::t std::shared_ptr analysisInfo = std::make_shared(); AsmAnalyzer analyzer(*analysisInfo, errorReporter, _dialect, {}, parserResult->qualifiedDataNames()); // TODO this should be done recursively. - if (!analyzer.analyze(*parserResult->code) || errorReporter.hasErrors()) + if (!analyzer.analyze(parserResult->code->root()) || errorReporter.hasErrors()) return {}; return {std::move(parserResult), std::move(analysisInfo)}; } @@ -91,14 +91,14 @@ std::pair, std::shared_ptr> yul::t yul::Block yul::test::disambiguate(std::string const& _source, bool _yul) { auto result = parse(_source, _yul); - return std::get(Disambiguator(defaultDialect(_yul), *result.second, {})(*result.first)); + return std::get(Disambiguator(defaultDialect(_yul), *result.second, {})(result.first->root())); } std::string yul::test::format(std::string const& _source, bool _yul) { auto const version = solidity::test::CommonOptions::get().evmVersion(); Dialect const& dialect = _yul ? EVMDialectTyped::instance(version) : EVMDialect::strictAssemblyForEVMObjects(version); - return yul::AsmPrinter(yul::AsmPrinter::TypePrinting::Full, dialect)(*parse(_source, _yul).first); + return yul::AsmPrinter(yul::AsmPrinter::TypePrinting::Full, dialect)(parse(_source, _yul).first->root()); } namespace diff --git a/test/libyul/Common.h b/test/libyul/Common.h index f6c63feb9bb2..4a9696cd9d18 100644 --- a/test/libyul/Common.h +++ b/test/libyul/Common.h @@ -39,12 +39,13 @@ struct AsmAnalysisInfo; struct Block; struct Object; struct Dialect; +class AST; } namespace solidity::yul::test { -std::pair, std::shared_ptr> +std::pair, std::shared_ptr> parse(std::string const& _source, bool _yul = true); std::pair, std::shared_ptr> diff --git a/test/libyul/ControlFlowGraphTest.cpp b/test/libyul/ControlFlowGraphTest.cpp index 9a0e6f092ff7..8e08bf488990 100644 --- a/test/libyul/ControlFlowGraphTest.cpp +++ b/test/libyul/ControlFlowGraphTest.cpp @@ -206,7 +206,7 @@ TestCase::TestResult ControlFlowGraphTest::run(std::ostream& _stream, std::strin std::ostringstream output; - std::unique_ptr cfg = ControlFlowGraphBuilder::build(*analysisInfo, *m_dialect, *object->code); + std::unique_ptr cfg = ControlFlowGraphBuilder::build(*analysisInfo, *m_dialect, object->code->root()); output << "digraph CFG {\nnodesep=0.7;\nnode[shape=box];\n\n"; ControlFlowGraphPrinter printer{output}; diff --git a/test/libyul/ControlFlowSideEffectsTest.cpp b/test/libyul/ControlFlowSideEffectsTest.cpp index 6ac5a7b0ad59..054c70547118 100644 --- a/test/libyul/ControlFlowSideEffectsTest.cpp +++ b/test/libyul/ControlFlowSideEffectsTest.cpp @@ -63,10 +63,10 @@ TestCase::TestResult ControlFlowSideEffectsTest::run(std::ostream& _stream, std: ControlFlowSideEffectsCollector sideEffects( EVMDialect::strictAssemblyForEVMObjects(langutil::EVMVersion()), - *obj.code + obj.code->root() ); m_obtainedResult.clear(); - forEach(*obj.code, [&](FunctionDefinition const& _fun) { + forEach(obj.code->root(), [&](FunctionDefinition const& _fun) { std::string effectStr = toString(sideEffects.functionSideEffects().at(&_fun)); m_obtainedResult += _fun.name.str() + (effectStr.empty() ? ":" : ": " + effectStr) + "\n"; }); diff --git a/test/libyul/FunctionSideEffects.cpp b/test/libyul/FunctionSideEffects.cpp index f1bd0ea379d1..3220a8c6f983 100644 --- a/test/libyul/FunctionSideEffects.cpp +++ b/test/libyul/FunctionSideEffects.cpp @@ -89,7 +89,7 @@ TestCase::TestResult FunctionSideEffects::run(std::ostream& _stream, std::string std::map functionSideEffects = SideEffectsPropagator::sideEffects( EVMDialect::strictAssemblyForEVMObjects(langutil::EVMVersion()), - CallGraphGenerator::callGraph(*obj.code) + CallGraphGenerator::callGraph(obj.code->root()) ); std::map functionSideEffectsStr; diff --git a/test/libyul/KnowledgeBaseTest.cpp b/test/libyul/KnowledgeBaseTest.cpp index 6a9d3e6da8be..a149381ca0bc 100644 --- a/test/libyul/KnowledgeBaseTest.cpp +++ b/test/libyul/KnowledgeBaseTest.cpp @@ -23,6 +23,7 @@ #include #include +#include #include #include #include @@ -48,15 +49,17 @@ class KnowledgeBaseTest std::tie(m_object, analysisInfo) = yul::test::parse(_source, m_dialect, errorList); BOOST_REQUIRE(m_object && errorList.empty() && m_object->code); - NameDispenser dispenser(m_dialect, *m_object->code); + auto astRoot = std::get(yul::ASTCopier{}(m_object->code->root())); + NameDispenser dispenser(m_dialect, astRoot); std::set reserved; OptimiserStepContext context{m_dialect, dispenser, reserved, 0}; - CommonSubexpressionEliminator::run(context, *m_object->code); + CommonSubexpressionEliminator::run(context, astRoot); - m_ssaValues(*m_object->code); + m_ssaValues(astRoot); for (auto const& [name, expression]: m_ssaValues.values()) m_values[name].value = expression; + m_object->code = std::make_shared(std::move(astRoot)); return KnowledgeBase([this](YulName _var) { return util::valueOrNullptr(m_values, _var); }); } diff --git a/test/libyul/Metrics.cpp b/test/libyul/Metrics.cpp index ac3153433f56..ce65cf2c8574 100644 --- a/test/libyul/Metrics.cpp +++ b/test/libyul/Metrics.cpp @@ -37,9 +37,9 @@ namespace size_t codeSize(std::string const& _source, CodeWeights const _weights = {}) { - std::shared_ptr ast = parse(_source, false).first; + std::shared_ptr ast = parse(_source, false).first; BOOST_REQUIRE(ast); - return CodeSize::codeSize(*ast, _weights); + return CodeSize::codeSize(ast->root(), _weights); } } diff --git a/test/libyul/Parser.cpp b/test/libyul/Parser.cpp index 7b3cdac8b2b1..0ed09f6a908a 100644 --- a/test/libyul/Parser.cpp +++ b/test/libyul/Parser.cpp @@ -54,7 +54,7 @@ namespace solidity::yul::test namespace { -std::shared_ptr parse(std::string const& _source, Dialect const& _dialect, ErrorReporter& errorReporter) +std::shared_ptr parse(std::string const& _source, Dialect const& _dialect, ErrorReporter& errorReporter) { auto stream = CharStream(_source, ""); std::map> indicesToSourceNames; @@ -73,7 +73,7 @@ std::shared_ptr parse(std::string const& _source, Dialect const& _dialect analysisInfo, errorReporter, _dialect - ).analyze(*parserResult)) + ).analyze(parserResult->root())) return parserResult; } return {}; @@ -152,7 +152,7 @@ BOOST_AUTO_TEST_CASE(default_types_set) { ErrorList errorList; ErrorReporter reporter(errorList); - std::shared_ptr result = parse( + std::shared_ptr result = parse( "{" "let x:bool := true:bool " "let z:bool := true " @@ -165,7 +165,7 @@ BOOST_AUTO_TEST_CASE(default_types_set) BOOST_REQUIRE(!!result && errorList.size() == 0); // All types are printed. - BOOST_CHECK_EQUAL(AsmPrinter(AsmPrinter::TypePrinting::Full, EVMDialectTyped::instance(EVMVersion()))(*result), + BOOST_CHECK_EQUAL(AsmPrinter(AsmPrinter::TypePrinting::Full, EVMDialectTyped::instance(EVMVersion()))(result->root()), "{\n" " let x:bool := true:bool\n" " let z:bool := true:bool\n" @@ -177,7 +177,7 @@ BOOST_AUTO_TEST_CASE(default_types_set) ); // Now the default types should be omitted. - BOOST_CHECK_EQUAL(AsmPrinter(AsmPrinter::TypePrinting::OmitDefault, EVMDialectTyped::instance(EVMVersion()))(*result), + BOOST_CHECK_EQUAL(AsmPrinter(AsmPrinter::TypePrinting::OmitDefault, EVMDialectTyped::instance(EVMVersion()))(result->root()), "{\n" " let x:bool := true\n" " let z:bool := true\n" @@ -204,9 +204,9 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_empty_block) "/// @src 0:234:543\n" "{}\n"; EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); - std::shared_ptr result = parse(sourceText, dialect, reporter); + std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.size() == 0); - CHECK_LOCATION(result->debugData->originLocation, "source0", 234, 543); + CHECK_LOCATION(result->root().debugData->originLocation, "source0", 234, 543); } BOOST_AUTO_TEST_CASE(customSourceLocations_block_with_children) @@ -222,14 +222,14 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_block_with_children) "let y := add(1, 2)\n" "}\n"; EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); - std::shared_ptr result = parse(sourceText, dialect, reporter); + std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result); - CHECK_LOCATION(result->debugData->originLocation, "source0", 234, 543); - BOOST_REQUIRE_EQUAL(3, result->statements.size()); - CHECK_LOCATION(originLocationOf(result->statements.at(0)), "source0", 234, 543); - CHECK_LOCATION(originLocationOf(result->statements.at(1)), "source0", 123, 432); + CHECK_LOCATION(result->root().debugData->originLocation, "source0", 234, 543); + BOOST_REQUIRE_EQUAL(3, result->root().statements.size()); + CHECK_LOCATION(originLocationOf(result->root().statements.at(0)), "source0", 234, 543); + CHECK_LOCATION(originLocationOf(result->root().statements.at(1)), "source0", 123, 432); // [2] is inherited source location - CHECK_LOCATION(originLocationOf(result->statements.at(2)), "source0", 123, 432); + CHECK_LOCATION(originLocationOf(result->root().statements.at(2)), "source0", 123, 432); } BOOST_AUTO_TEST_CASE(customSourceLocations_block_different_sources) @@ -245,14 +245,14 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_block_different_sources) "let y := add(1, 2)\n" "}\n"; EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); - std::shared_ptr result = parse(sourceText, dialect, reporter); + std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.size() == 0); - CHECK_LOCATION(result->debugData->originLocation, "source0", 234, 543); - BOOST_REQUIRE_EQUAL(3, result->statements.size()); - CHECK_LOCATION(originLocationOf(result->statements.at(0)), "source0", 234, 543); - CHECK_LOCATION(originLocationOf(result->statements.at(1)), "source1", 123, 432); + CHECK_LOCATION(result->root().debugData->originLocation, "source0", 234, 543); + BOOST_REQUIRE_EQUAL(3, result->root().statements.size()); + CHECK_LOCATION(originLocationOf(result->root().statements.at(0)), "source0", 234, 543); + CHECK_LOCATION(originLocationOf(result->root().statements.at(1)), "source1", 123, 432); // [2] is inherited source location - CHECK_LOCATION(originLocationOf(result->statements.at(2)), "source1", 123, 432); + CHECK_LOCATION(originLocationOf(result->root().statements.at(2)), "source1", 123, 432); } BOOST_AUTO_TEST_CASE(customSourceLocations_block_nested) @@ -267,11 +267,11 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_block_nested) "switch y case 0 {} default {}\n" "}\n"; EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); - std::shared_ptr result = parse(sourceText, dialect, reporter); + std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.size() == 0); - CHECK_LOCATION(result->debugData->originLocation, "source0", 234, 543); - BOOST_REQUIRE_EQUAL(2, result->statements.size()); - CHECK_LOCATION(originLocationOf(result->statements.at(1)), "source0", 343, 434); + CHECK_LOCATION(result->root().debugData->originLocation, "source0", 234, 543); + BOOST_REQUIRE_EQUAL(2, result->root().statements.size()); + CHECK_LOCATION(originLocationOf(result->root().statements.at(1)), "source0", 343, 434); } BOOST_AUTO_TEST_CASE(customSourceLocations_block_switch_case) @@ -291,13 +291,13 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_block_switch_case) "}\n" "}\n"; EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); - std::shared_ptr result = parse(sourceText, dialect, reporter); + std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.size() == 0); - CHECK_LOCATION(result->debugData->originLocation, "source0", 234, 543); + CHECK_LOCATION(result->root().debugData->originLocation, "source0", 234, 543); - BOOST_REQUIRE_EQUAL(2, result->statements.size()); - BOOST_REQUIRE(std::holds_alternative(result->statements.at(1))); - auto const& switchStmt = std::get(result->statements.at(1)); + BOOST_REQUIRE_EQUAL(2, result->root().statements.size()); + BOOST_REQUIRE(std::holds_alternative(result->root().statements.at(1))); + auto const& switchStmt = std::get(result->root().statements.at(1)); CHECK_LOCATION(switchStmt.debugData->originLocation, "source0", 343, 434); BOOST_REQUIRE_EQUAL(1, switchStmt.cases.size()); @@ -323,22 +323,22 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_inherit_into_outer_scope) "let y := add(1, 2)\n" "}\n"; EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); - std::shared_ptr result = parse(sourceText, dialect, reporter); + std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.size() == 0); - CHECK_LOCATION(result->debugData->originLocation, "source0", 1, 100); + CHECK_LOCATION(result->root().debugData->originLocation, "source0", 1, 100); - BOOST_REQUIRE_EQUAL(3, result->statements.size()); - CHECK_LOCATION(originLocationOf(result->statements.at(0)), "source0", 1, 100); + BOOST_REQUIRE_EQUAL(3, result->root().statements.size()); + CHECK_LOCATION(originLocationOf(result->root().statements.at(0)), "source0", 1, 100); // First child element must be a block itself with one statement. - BOOST_REQUIRE(std::holds_alternative(result->statements.at(0))); - BOOST_REQUIRE_EQUAL(std::get(result->statements.at(0)).statements.size(), 1); - CHECK_LOCATION(originLocationOf(std::get(result->statements.at(0)).statements.at(0)), "source0", 123, 432); + BOOST_REQUIRE(std::holds_alternative(result->root().statements.at(0))); + BOOST_REQUIRE_EQUAL(std::get(result->root().statements.at(0)).statements.size(), 1); + CHECK_LOCATION(originLocationOf(std::get(result->root().statements.at(0)).statements.at(0)), "source0", 123, 432); // The next two elements have an inherited source location from the prior inner scope. - CHECK_LOCATION(originLocationOf(result->statements.at(1)), "source0", 123, 432); - CHECK_LOCATION(originLocationOf(result->statements.at(2)), "source0", 123, 432); + CHECK_LOCATION(originLocationOf(result->root().statements.at(1)), "source0", 123, 432); + CHECK_LOCATION(originLocationOf(result->root().statements.at(2)), "source0", 123, 432); } BOOST_AUTO_TEST_CASE(customSourceLocations_assign_empty) @@ -354,11 +354,11 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_assign_empty) "a := true:bool\n" "}\n"; EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); - std::shared_ptr result = parse(sourceText, dialect, reporter); + std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.size() == 0); // should still parse - BOOST_REQUIRE_EQUAL(2, result->statements.size()); - CHECK_LOCATION(originLocationOf(result->statements.at(0)), "source0", 123, 432); - CHECK_LOCATION(originLocationOf(result->statements.at(1)), "source1", 1, 10); + BOOST_REQUIRE_EQUAL(2, result->root().statements.size()); + CHECK_LOCATION(originLocationOf(result->root().statements.at(0)), "source0", 123, 432); + CHECK_LOCATION(originLocationOf(result->root().statements.at(1)), "source1", 1, 10); } BOOST_AUTO_TEST_CASE(customSourceLocations_invalid_source_index) @@ -375,7 +375,7 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_invalid_source_index) "\n" "}\n"; EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); - std::shared_ptr result = parse(sourceText, dialect, reporter); + std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result); // should still parse BOOST_REQUIRE(errorList.size() == 1); BOOST_TEST(errorList[0]->type() == Error::Type::SyntaxError); @@ -395,13 +395,13 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_mixed_locations_1) ":= true:bool\n" "}\n"; EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); - std::shared_ptr result = parse(sourceText, dialect, reporter); + std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.size() == 0); - BOOST_REQUIRE_EQUAL(1, result->statements.size()); - CHECK_LOCATION(originLocationOf(result->statements.at(0)), "source0", 123, 432); - BOOST_REQUIRE(std::holds_alternative(result->statements.at(0))); - VariableDeclaration const& varDecl = std::get(result->statements.at(0)); + BOOST_REQUIRE_EQUAL(1, result->root().statements.size()); + CHECK_LOCATION(originLocationOf(result->root().statements.at(0)), "source0", 123, 432); + BOOST_REQUIRE(std::holds_alternative(result->root().statements.at(0))); + VariableDeclaration const& varDecl = std::get(result->root().statements.at(0)); CHECK_LOCATION(originLocationOf(*varDecl.value), "source0", 234, 2026); } @@ -418,14 +418,14 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_mixed_locations_2) } )"; EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); - std::shared_ptr result = parse(sourceText, dialect, reporter); + std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.size() == 0); - BOOST_REQUIRE_EQUAL(1, result->statements.size()); - CHECK_LOCATION(result->debugData->originLocation, "source0", 0, 5); + BOOST_REQUIRE_EQUAL(1, result->root().statements.size()); + CHECK_LOCATION(result->root().debugData->originLocation, "source0", 0, 5); // `let x := add(1, ` - BOOST_REQUIRE(std::holds_alternative(result->statements.at(0))); - VariableDeclaration const& varDecl = std::get(result->statements.at(0)); + BOOST_REQUIRE(std::holds_alternative(result->root().statements.at(0))); + VariableDeclaration const& varDecl = std::get(result->root().statements.at(0)); CHECK_LOCATION(varDecl.debugData->originLocation, "source0", 0, 5); BOOST_REQUIRE(!!varDecl.value); BOOST_REQUIRE(std::holds_alternative(*varDecl.value)); @@ -452,24 +452,24 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_mixed_locations_3) } )"; EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); - std::shared_ptr result = parse(sourceText, dialect, reporter); + std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.size() == 0); - BOOST_REQUIRE_EQUAL(2, result->statements.size()); - CHECK_LOCATION(result->debugData->originLocation, "source1", 23, 45); + BOOST_REQUIRE_EQUAL(2, result->root().statements.size()); + CHECK_LOCATION(result->root().debugData->originLocation, "source1", 23, 45); - BOOST_REQUIRE(std::holds_alternative(result->statements.at(0))); - Block const& innerBlock = std::get(result->statements.at(0)); + BOOST_REQUIRE(std::holds_alternative(result->root().statements.at(0))); + Block const& innerBlock = std::get(result->root().statements.at(0)); CHECK_LOCATION(innerBlock.debugData->originLocation, "source1", 23, 45); BOOST_REQUIRE_EQUAL(1, innerBlock.statements.size()); - BOOST_REQUIRE(std::holds_alternative(result->statements.at(1))); + BOOST_REQUIRE(std::holds_alternative(result->root().statements.at(1))); ExpressionStatement const& sstoreStmt = std::get(innerBlock.statements.at(0)); BOOST_REQUIRE(std::holds_alternative(sstoreStmt.expression)); FunctionCall const& sstoreCall = std::get(sstoreStmt.expression); CHECK_LOCATION(sstoreCall.debugData->originLocation, "source1", 23, 45); - BOOST_REQUIRE(std::holds_alternative(result->statements.at(1))); - ExpressionStatement mstoreStmt = std::get(result->statements.at(1)); + BOOST_REQUIRE(std::holds_alternative(result->root().statements.at(1))); + ExpressionStatement mstoreStmt = std::get(result->root().statements.at(1)); BOOST_REQUIRE(std::holds_alternative(mstoreStmt.expression)); FunctionCall const& mstoreCall = std::get(mstoreStmt.expression); CHECK_LOCATION(mstoreCall.debugData->originLocation, "source0", 420, 680); @@ -488,13 +488,13 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_invalid_comments_after_valid) } )"; EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); - std::shared_ptr result = parse(sourceText, dialect, reporter); + std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.size() == 0); - BOOST_REQUIRE_EQUAL(1, result->statements.size()); - CHECK_LOCATION(result->debugData->originLocation, "source1", 23, 45); + BOOST_REQUIRE_EQUAL(1, result->root().statements.size()); + CHECK_LOCATION(result->root().debugData->originLocation, "source1", 23, 45); - BOOST_REQUIRE(std::holds_alternative(result->statements.at(0))); - VariableDeclaration const& varDecl = std::get(result->statements.at(0)); + BOOST_REQUIRE(std::holds_alternative(result->root().statements.at(0))); + VariableDeclaration const& varDecl = std::get(result->root().statements.at(0)); CHECK_LOCATION(varDecl.debugData->originLocation, "source0", 420, 680); } @@ -507,12 +507,12 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_invalid_suffix) {} )"; EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); - std::shared_ptr result = parse(sourceText, dialect, reporter); + std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result); BOOST_REQUIRE(errorList.size() == 1); BOOST_TEST(errorList[0]->type() == Error::Type::SyntaxError); BOOST_TEST(errorList[0]->errorId() == 8387_error); - CHECK_LOCATION(result->debugData->originLocation, "", -1, -1); + CHECK_LOCATION(result->root().debugData->originLocation, "", -1, -1); } BOOST_AUTO_TEST_CASE(customSourceLocations_invalid_prefix) @@ -524,9 +524,9 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_invalid_prefix) {} )"; EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); - std::shared_ptr result = parse(sourceText, dialect, reporter); + std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.size() == 0); - CHECK_LOCATION(result->debugData->originLocation, "", -1, -1); + CHECK_LOCATION(result->root().debugData->originLocation, "", -1, -1); } BOOST_AUTO_TEST_CASE(customSourceLocations_unspecified) @@ -538,9 +538,9 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_unspecified) {} )"; EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); - std::shared_ptr result = parse(sourceText, dialect, reporter); + std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.size() == 0); - CHECK_LOCATION(result->debugData->originLocation, "", -1, -1); + CHECK_LOCATION(result->root().debugData->originLocation, "", -1, -1); } BOOST_AUTO_TEST_CASE(customSourceLocations_non_integer) @@ -552,12 +552,12 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_non_integer) {} )"; EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); - std::shared_ptr result = parse(sourceText, dialect, reporter); + std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result); BOOST_REQUIRE(errorList.size() == 1); BOOST_TEST(errorList[0]->type() == Error::Type::SyntaxError); BOOST_TEST(errorList[0]->errorId() == 8387_error); - CHECK_LOCATION(result->debugData->originLocation, "", -1, -1); + CHECK_LOCATION(result->root().debugData->originLocation, "", -1, -1); } BOOST_AUTO_TEST_CASE(customSourceLocations_bad_integer) @@ -569,12 +569,12 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_bad_integer) {} )"; EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); - std::shared_ptr result = parse(sourceText, dialect, reporter); + std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result); BOOST_REQUIRE(errorList.size() == 1); BOOST_TEST(errorList[0]->type() == Error::Type::SyntaxError); BOOST_TEST(errorList[0]->errorId() == 6367_error); - CHECK_LOCATION(result->debugData->originLocation, "", -1, -1); + CHECK_LOCATION(result->root().debugData->originLocation, "", -1, -1); } BOOST_AUTO_TEST_CASE(customSourceLocations_ensure_last_match) @@ -590,10 +590,10 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_ensure_last_match) } )"; EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); - std::shared_ptr result = parse(sourceText, dialect, reporter); + std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.size() == 0); - BOOST_REQUIRE(std::holds_alternative(result->statements.at(0))); - VariableDeclaration const& varDecl = std::get(result->statements.at(0)); + BOOST_REQUIRE(std::holds_alternative(result->root().statements.at(0))); + VariableDeclaration const& varDecl = std::get(result->root().statements.at(0)); // Ensure the latest @src per documentation-comment is used (0:30:40). CHECK_LOCATION(varDecl.debugData->originLocation, "source0", 30, 40); @@ -608,12 +608,12 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_two_locations_no_whitespace) {} )"; EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); - std::shared_ptr result = parse(sourceText, dialect, reporter); + std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result); BOOST_REQUIRE(errorList.size() == 1); BOOST_TEST(errorList[0]->type() == Error::Type::SyntaxError); BOOST_TEST(errorList[0]->errorId() == 8387_error); - CHECK_LOCATION(result->debugData->originLocation, "", -1, -1); + CHECK_LOCATION(result->root().debugData->originLocation, "", -1, -1); } BOOST_AUTO_TEST_CASE(customSourceLocations_two_locations_separated_with_single_space) @@ -625,9 +625,9 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_two_locations_separated_with_single_s {} )"; EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); - std::shared_ptr result = parse(sourceText, dialect, reporter); + std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.size() == 0); - CHECK_LOCATION(result->debugData->originLocation, "source1", 333, 444); + CHECK_LOCATION(result->root().debugData->originLocation, "source1", 333, 444); } BOOST_AUTO_TEST_CASE(customSourceLocations_leading_trailing_whitespace) @@ -636,9 +636,9 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_leading_trailing_whitespace) ErrorReporter reporter(errorList); auto const sourceText = "/// @src 0:111:222 \n{}"; EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); - std::shared_ptr result = parse(sourceText, dialect, reporter); + std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.size() == 0); - CHECK_LOCATION(result->debugData->originLocation, "source0", 111, 222); + CHECK_LOCATION(result->root().debugData->originLocation, "source0", 111, 222); } BOOST_AUTO_TEST_CASE(customSourceLocations_reference_original_sloc) @@ -653,10 +653,10 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_reference_original_sloc) } )"; EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); - std::shared_ptr result = parse(sourceText, dialect, reporter); + std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.size() == 0); - BOOST_REQUIRE(std::holds_alternative(result->statements.at(0))); - VariableDeclaration const& varDecl = std::get(result->statements.at(0)); + BOOST_REQUIRE(std::holds_alternative(result->root().statements.at(0))); + VariableDeclaration const& varDecl = std::get(result->root().statements.at(0)); // -1 points to original source code, which in this case is `"source0"` (which is also CHECK_LOCATION(varDecl.debugData->originLocation, "", 10, 20); @@ -675,16 +675,16 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_with_code_snippets) } )~~~"; EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); - std::shared_ptr result = parse(sourceText, dialect, reporter); + std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.size() == 0); - BOOST_REQUIRE_EQUAL(result->statements.size(), 2); + BOOST_REQUIRE_EQUAL(result->root().statements.size(), 2); - BOOST_REQUIRE(std::holds_alternative(result->statements.at(0))); - VariableDeclaration const& varX = std::get(result->statements.at(0)); + BOOST_REQUIRE(std::holds_alternative(result->root().statements.at(0))); + VariableDeclaration const& varX = std::get(result->root().statements.at(0)); CHECK_LOCATION(varX.debugData->originLocation, "source0", 149, 156); - BOOST_REQUIRE(std::holds_alternative(result->statements.at(1))); - VariableDeclaration const& varY = std::get(result->statements.at(1)); + BOOST_REQUIRE(std::holds_alternative(result->root().statements.at(1))); + VariableDeclaration const& varY = std::get(result->root().statements.at(1)); BOOST_REQUIRE(!!varY.value); BOOST_REQUIRE(std::holds_alternative(*varY.value)); Literal const& literal128 = std::get(*varY.value); @@ -700,9 +700,9 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_with_code_snippets_empty_snippet) {} )"; EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); - std::shared_ptr result = parse(sourceText, dialect, reporter); + std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.size() == 0); - CHECK_LOCATION(result->debugData->originLocation, "source0", 111, 222); + CHECK_LOCATION(result->root().debugData->originLocation, "source0", 111, 222); } BOOST_AUTO_TEST_CASE(customSourceLocations_with_code_snippets_no_whitespace_before_snippet) @@ -714,12 +714,12 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_with_code_snippets_no_whitespace_befo {} )"; EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); - std::shared_ptr result = parse(sourceText, dialect, reporter); + std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result); BOOST_REQUIRE(errorList.size() == 1); BOOST_TEST(errorList[0]->type() == Error::Type::SyntaxError); BOOST_TEST(errorList[0]->errorId() == 8387_error); - CHECK_LOCATION(result->debugData->originLocation, "", -1, -1); + CHECK_LOCATION(result->root().debugData->originLocation, "", -1, -1); } BOOST_AUTO_TEST_CASE(customSourceLocations_with_code_snippets_no_whitespace_after_snippet) @@ -731,9 +731,9 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_with_code_snippets_no_whitespace_afte {} )"; EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); - std::shared_ptr result = parse(sourceText, dialect, reporter); + std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.size() == 0); - CHECK_LOCATION(result->debugData->originLocation, "source0", 111, 222); + CHECK_LOCATION(result->root().debugData->originLocation, "source0", 111, 222); } BOOST_AUTO_TEST_CASE(customSourceLocations_two_locations_with_snippets_no_whitespace) @@ -745,9 +745,9 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_two_locations_with_snippets_no_whites {} )"; EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); - std::shared_ptr result = parse(sourceText, dialect, reporter); + std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.size() == 0); - CHECK_LOCATION(result->debugData->originLocation, "source1", 333, 444); + CHECK_LOCATION(result->root().debugData->originLocation, "source1", 333, 444); } BOOST_AUTO_TEST_CASE(customSourceLocations_two_locations_with_snippets_unterminated_quote) @@ -759,12 +759,12 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_two_locations_with_snippets_untermina {} )"; EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); - std::shared_ptr result = parse(sourceText, dialect, reporter); + std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result); BOOST_REQUIRE(errorList.size() == 1); BOOST_TEST(errorList[0]->type() == Error::Type::SyntaxError); BOOST_TEST(errorList[0]->errorId() == 1544_error); - CHECK_LOCATION(result->debugData->originLocation, "", -1, -1); + CHECK_LOCATION(result->root().debugData->originLocation, "", -1, -1); } BOOST_AUTO_TEST_CASE(customSourceLocations_single_quote) @@ -777,12 +777,12 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_single_quote) {} )"; EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); - std::shared_ptr result = parse(sourceText, dialect, reporter); + std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result); BOOST_REQUIRE(errorList.size() == 1); BOOST_TEST(errorList[0]->type() == Error::Type::SyntaxError); BOOST_TEST(errorList[0]->errorId() == 1544_error); - CHECK_LOCATION(result->debugData->originLocation, "", -1, -1); + CHECK_LOCATION(result->root().debugData->originLocation, "", -1, -1); } BOOST_AUTO_TEST_CASE(customSourceLocations_two_snippets_with_hex_comment) @@ -794,11 +794,11 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_two_snippets_with_hex_comment) {} )"; EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); - std::shared_ptr result = parse(sourceText, dialect, reporter); + std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.size() == 0); // the second source location is not parsed as such, as the hex string isn't interpreted as snippet but // as the beginning of the tail in AsmParser - CHECK_LOCATION(result->debugData->originLocation, "source0", 111, 222); + CHECK_LOCATION(result->root().debugData->originLocation, "source0", 111, 222); } BOOST_AUTO_TEST_CASE(customSourceLocations_invalid_escapes) @@ -810,9 +810,9 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_invalid_escapes) {} )"; EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); - std::shared_ptr result = parse(sourceText, dialect, reporter); + std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.size() == 0); - CHECK_LOCATION(result->debugData->originLocation, "source0", 111, 222); + CHECK_LOCATION(result->root().debugData->originLocation, "source0", 111, 222); } BOOST_AUTO_TEST_CASE(customSourceLocations_single_quote_snippet_with_whitespaces_and_escapes) @@ -825,9 +825,9 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_single_quote_snippet_with_whitespaces {} )"; EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); - std::shared_ptr result = parse(sourceText, dialect, reporter); + std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.size() == 0); - CHECK_LOCATION(result->debugData->originLocation, "source1", 222, 333); + CHECK_LOCATION(result->root().debugData->originLocation, "source1", 222, 333); } BOOST_DATA_TEST_CASE(customSourceLocations_scanner_errors_outside_string_lits_are_ignored, boost::unit_test::data::make({"0x ", "/** unterminated comment", "1_23_4"}), invalid) @@ -840,9 +840,9 @@ BOOST_DATA_TEST_CASE(customSourceLocations_scanner_errors_outside_string_lits_ar {{}} )", invalid); EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); - std::shared_ptr result = parse(sourceText, dialect, reporter); + std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.empty()); - CHECK_LOCATION(result->debugData->originLocation, "source1", 222, 333); + CHECK_LOCATION(result->root().debugData->originLocation, "source1", 222, 333); } BOOST_AUTO_TEST_CASE(customSourceLocations_multi_line_source_loc) @@ -858,9 +858,9 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_multi_line_source_loc) {} )"; EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); - std::shared_ptr result = parse(sourceText, dialect, reporter); + std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.empty()); - CHECK_LOCATION(result->debugData->originLocation, "source0", 333, 444); + CHECK_LOCATION(result->root().debugData->originLocation, "source0", 333, 444); } BOOST_AUTO_TEST_CASE(customSourceLocations_with_code_snippets_with_nested_locations) @@ -876,16 +876,16 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_with_code_snippets_with_nested_locati } )~~~"; EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); - std::shared_ptr result = parse(sourceText, dialect, reporter); + std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.size() == 0); - BOOST_REQUIRE_EQUAL(result->statements.size(), 2); + BOOST_REQUIRE_EQUAL(result->root().statements.size(), 2); - BOOST_REQUIRE(std::holds_alternative(result->statements.at(0))); - VariableDeclaration const& varX = std::get(result->statements.at(0)); + BOOST_REQUIRE(std::holds_alternative(result->root().statements.at(0))); + VariableDeclaration const& varX = std::get(result->root().statements.at(0)); CHECK_LOCATION(varX.debugData->originLocation, "source0", 149, 156); - BOOST_REQUIRE(std::holds_alternative(result->statements.at(1))); - VariableDeclaration const& varY = std::get(result->statements.at(1)); + BOOST_REQUIRE(std::holds_alternative(result->root().statements.at(1))); + VariableDeclaration const& varY = std::get(result->root().statements.at(1)); BOOST_REQUIRE(!!varY.value); BOOST_REQUIRE(std::holds_alternative(*varY.value)); Literal const& literal128 = std::get(*varY.value); @@ -905,13 +905,13 @@ BOOST_AUTO_TEST_CASE(astid) } )"; EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); - std::shared_ptr result = parse(sourceText, dialect, reporter); + std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result); - BOOST_CHECK(result->debugData->astID == int64_t(7)); - auto const& funDef = std::get(result->statements.at(0)); + BOOST_CHECK(result->root().debugData->astID == int64_t(7)); + auto const& funDef = std::get(result->root().statements.at(0)); BOOST_CHECK(funDef.debugData->astID == int64_t(2)); BOOST_CHECK(funDef.parameters.at(0).debugData->astID == std::nullopt); - BOOST_CHECK(debugDataOf(result->statements.at(1))->astID == std::nullopt); + BOOST_CHECK(debugDataOf(result->root().statements.at(1))->astID == std::nullopt); } BOOST_AUTO_TEST_CASE(astid_reset) @@ -927,13 +927,13 @@ BOOST_AUTO_TEST_CASE(astid_reset) } )"; EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); - std::shared_ptr result = parse(sourceText, dialect, reporter); + std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result); - BOOST_CHECK(result->debugData->astID == int64_t(7)); - auto const& funDef = std::get(result->statements.at(0)); + BOOST_CHECK(result->root().debugData->astID == int64_t(7)); + auto const& funDef = std::get(result->root().statements.at(0)); BOOST_CHECK(funDef.debugData->astID == int64_t(2)); BOOST_CHECK(funDef.parameters.at(0).debugData->astID == std::nullopt); - BOOST_CHECK(debugDataOf(result->statements.at(1))->astID == std::nullopt); + BOOST_CHECK(debugDataOf(result->root().statements.at(1))->astID == std::nullopt); } BOOST_AUTO_TEST_CASE(astid_multi) @@ -945,9 +945,9 @@ BOOST_AUTO_TEST_CASE(astid_multi) {} )"; EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); - std::shared_ptr result = parse(sourceText, dialect, reporter); + std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result); - BOOST_CHECK(result->debugData->astID == int64_t(8)); + BOOST_CHECK(result->root().debugData->astID == int64_t(8)); } BOOST_AUTO_TEST_CASE(astid_invalid) @@ -959,12 +959,12 @@ BOOST_AUTO_TEST_CASE(astid_invalid) {} )"; EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); - std::shared_ptr result = parse(sourceText, dialect, reporter); + std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result); BOOST_REQUIRE(errorList.size() == 1); BOOST_TEST(errorList[0]->type() == Error::Type::SyntaxError); BOOST_TEST(errorList[0]->errorId() == 1749_error); - CHECK_LOCATION(result->debugData->originLocation, "", -1, -1); + CHECK_LOCATION(result->root().debugData->originLocation, "", -1, -1); } BOOST_AUTO_TEST_CASE(astid_too_large) @@ -976,7 +976,7 @@ BOOST_AUTO_TEST_CASE(astid_too_large) {} )"; EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); - std::shared_ptr result = parse(sourceText, dialect, reporter); + std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result); BOOST_REQUIRE(errorList.size() == 1); BOOST_TEST(errorList[0]->type() == Error::Type::SyntaxError); @@ -992,7 +992,7 @@ BOOST_AUTO_TEST_CASE(astid_way_too_large) {} )"; EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); - std::shared_ptr result = parse(sourceText, dialect, reporter); + std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result); BOOST_REQUIRE(errorList.size() == 1); BOOST_TEST(errorList[0]->type() == Error::Type::SyntaxError); @@ -1008,7 +1008,7 @@ BOOST_AUTO_TEST_CASE(astid_not_fully_numeric) {} )"; EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); - std::shared_ptr result = parse(sourceText, dialect, reporter); + std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result); BOOST_REQUIRE(errorList.size() == 1); BOOST_TEST(errorList[0]->type() == Error::Type::SyntaxError); @@ -1030,12 +1030,12 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_multiple_src_tags_on_one_line) " let x := 123\n" "}\n"; EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); - std::shared_ptr result = parse(sourceText, dialect, reporter); + std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.size() == 0); - BOOST_REQUIRE_EQUAL(result->statements.size(), 1); + BOOST_REQUIRE_EQUAL(result->root().statements.size(), 1); - BOOST_REQUIRE(std::holds_alternative(result->statements.at(0))); - VariableDeclaration const& varX = std::get(result->statements.at(0)); + BOOST_REQUIRE(std::holds_alternative(result->root().statements.at(0))); + VariableDeclaration const& varX = std::get(result->root().statements.at(0)); CHECK_LOCATION(varX.debugData->originLocation, "source1", 4, 5); } diff --git a/test/libyul/StackLayoutGeneratorTest.cpp b/test/libyul/StackLayoutGeneratorTest.cpp index 02b03ccea76d..2abac60e5c40 100644 --- a/test/libyul/StackLayoutGeneratorTest.cpp +++ b/test/libyul/StackLayoutGeneratorTest.cpp @@ -224,7 +224,7 @@ TestCase::TestResult StackLayoutGeneratorTest::run(std::ostream& _stream, std::s std::ostringstream output; - std::unique_ptr cfg = ControlFlowGraphBuilder::build(*analysisInfo, *m_dialect, *object->code); + std::unique_ptr cfg = ControlFlowGraphBuilder::build(*analysisInfo, *m_dialect, object->code->root()); StackLayout stackLayout = StackLayoutGenerator::run(*cfg); output << "digraph CFG {\nnodesep=0.7;\nnode[shape=box];\n\n"; diff --git a/test/libyul/YulInterpreterTest.cpp b/test/libyul/YulInterpreterTest.cpp index eb6a447d1273..d987c519c3e7 100644 --- a/test/libyul/YulInterpreterTest.cpp +++ b/test/libyul/YulInterpreterTest.cpp @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -98,7 +99,7 @@ std::string YulInterpreterTest::interpret() Interpreter::run( state, EVMDialect::strictAssemblyForEVMObjects(solidity::test::CommonOptions::get().evmVersion()), - *m_ast, + m_ast->root(), /*disableExternalCalls=*/ !m_simulateExternalCallsToSelf, /*disableMemoryTracing=*/ false ); diff --git a/test/libyul/YulInterpreterTest.h b/test/libyul/YulInterpreterTest.h index a20b0688a236..f5368670240d 100644 --- a/test/libyul/YulInterpreterTest.h +++ b/test/libyul/YulInterpreterTest.h @@ -23,7 +23,7 @@ namespace solidity::yul { struct AsmAnalysisInfo; -struct Block; +class AST; } namespace solidity::yul::test @@ -45,7 +45,7 @@ class YulInterpreterTest: public solidity::frontend::test::EVMVersionRestrictedT bool parse(std::ostream& _stream, std::string const& _linePrefix, bool const _formatted); std::string interpret(); - std::shared_ptr m_ast; + std::shared_ptr m_ast; std::shared_ptr m_analysisInfo; bool m_simulateExternalCallsToSelf = false; }; diff --git a/test/libyul/YulOptimizerTest.cpp b/test/libyul/YulOptimizerTest.cpp index b30fa825112a..df28515c37cb 100644 --- a/test/libyul/YulOptimizerTest.cpp +++ b/test/libyul/YulOptimizerTest.cpp @@ -25,6 +25,7 @@ #include #include +#include #include #include @@ -77,19 +78,23 @@ TestCase::TestResult YulOptimizerTest::run(std::ostream& _stream, std::string co AnsiColorized(_stream, _formatted, {formatting::BOLD, formatting::RED}) << _linePrefix << "Invalid optimizer step: " << m_optimizerStep << std::endl; return TestResult::FatalError; } - - auto const printed = (m_object->subObjects.empty() ? AsmPrinter{AsmPrinter::TypePrinting::OmitDefault, *m_dialect}(*m_object->code) : m_object->toString(*m_dialect)); + auto optimizedObject = tester.optimizedObject(); + std::string printedOptimizedObject; + if (optimizedObject->subObjects.empty()) + printedOptimizedObject = AsmPrinter{AsmPrinter::TypePrinting::OmitDefault, *m_dialect}(optimizedObject->code->root()); + else + printedOptimizedObject = optimizedObject->toString(*m_dialect); // Re-parse new code for compilability - if (!std::get<0>(parse(_stream, _linePrefix, _formatted, printed))) + if (!std::get<0>(parse(_stream, _linePrefix, _formatted, printedOptimizedObject))) { util::AnsiColorized(_stream, _formatted, {util::formatting::BOLD, util::formatting::CYAN}) << _linePrefix << "Result after the optimiser:" << std::endl; - printPrefixed(_stream, printed, _linePrefix + " "); + printPrefixed(_stream, printedOptimizedObject, _linePrefix + " "); return TestResult::FatalError; } - m_obtainedResult = "step: " + m_optimizerStep + "\n\n" + printed + "\n"; + m_obtainedResult = "step: " + m_optimizerStep + "\n\n" + printedOptimizedObject + "\n"; return checkResult(_stream, _linePrefix, _formatted); } diff --git a/test/libyul/YulOptimizerTestCommon.cpp b/test/libyul/YulOptimizerTestCommon.cpp index 80746c93ba9f..357e5b657998 100644 --- a/test/libyul/YulOptimizerTestCommon.cpp +++ b/test/libyul/YulOptimizerTestCommon.cpp @@ -76,275 +76,361 @@ using namespace solidity::frontend; YulOptimizerTestCommon::YulOptimizerTestCommon( std::shared_ptr _obj, Dialect const& _dialect -) +): m_dialect(&_dialect), m_object(_obj), m_optimizedObject(std::make_shared()), m_analysisInfo(m_object->analysisInfo) { - m_object = _obj; - m_ast = m_object->code; - m_analysisInfo = m_object->analysisInfo; - m_dialect = &_dialect; - + *m_optimizedObject = *m_object; m_namedSteps = { - {"disambiguator", [&]() { disambiguate(); }}, + {"disambiguator", [&]() { return disambiguate(); }}, {"nameDisplacer", [&]() { - disambiguate(); + auto block = disambiguate(); + updateContext(block); NameDisplacer{ *m_nameDispenser, {"illegal1"_yulname, "illegal2"_yulname, "illegal3"_yulname, "illegal4"_yulname, "illegal5"_yulname} - }(*m_ast); + }(block); + return block; }}, {"blockFlattener", [&]() { - disambiguate(); - FunctionGrouper::run(*m_context, *m_ast); - BlockFlattener::run(*m_context, *m_ast); + auto block = disambiguate(); + updateContext(block); + FunctionGrouper::run(*m_context, block); + BlockFlattener::run(*m_context, block); + return block; }}, {"constantOptimiser", [&]() { + auto block = std::get(ASTCopier{}(m_object->code->root())); + updateContext(block); GasMeter meter(dynamic_cast(*m_dialect), false, 200); - ConstantOptimiser{dynamic_cast(*m_dialect), meter}(*m_ast); + ConstantOptimiser{dynamic_cast(*m_dialect), meter}(block); + return block; + }}, + {"varDeclInitializer", [&]() { + auto block = std::get(ASTCopier{}(m_object->code->root())); + updateContext(block); + VarDeclInitializer::run(*m_context, block); + return block; }}, - {"varDeclInitializer", [&]() { VarDeclInitializer::run(*m_context, *m_ast); }}, {"varNameCleaner", [&]() { - disambiguate(); - FunctionHoister::run(*m_context, *m_ast); - FunctionGrouper::run(*m_context, *m_ast); - VarNameCleaner::run(*m_context, *m_ast); + auto block = disambiguate(); + updateContext(block); + FunctionHoister::run(*m_context, block); + FunctionGrouper::run(*m_context, block); + VarNameCleaner::run(*m_context, block); + return block; }}, {"forLoopConditionIntoBody", [&]() { - disambiguate(); - ForLoopConditionIntoBody::run(*m_context, *m_ast); + auto block = disambiguate(); + updateContext(block); + ForLoopConditionIntoBody::run(*m_context, block); + return block; }}, {"forLoopInitRewriter", [&]() { - disambiguate(); - ForLoopInitRewriter::run(*m_context, *m_ast); + auto block = disambiguate(); + updateContext(block); + ForLoopInitRewriter::run(*m_context, block); + return block; }}, {"commonSubexpressionEliminator", [&]() { - disambiguate(); - ForLoopInitRewriter::run(*m_context, *m_ast); - FunctionHoister::run(*m_context, *m_ast); - CommonSubexpressionEliminator::run(*m_context, *m_ast); + auto block = disambiguate(); + updateContext(block); + ForLoopInitRewriter::run(*m_context, block); + FunctionHoister::run(*m_context, block); + CommonSubexpressionEliminator::run(*m_context, block); + return block; }}, {"conditionalUnsimplifier", [&]() { - disambiguate(); - ConditionalUnsimplifier::run(*m_context, *m_ast); + auto block = disambiguate(); + updateContext(block); + ConditionalUnsimplifier::run(*m_context, block); + return block; }}, {"conditionalSimplifier", [&]() { - disambiguate(); - ConditionalSimplifier::run(*m_context, *m_ast); + auto block = disambiguate(); + updateContext(block); + ConditionalSimplifier::run(*m_context, block); + return block; + }}, + {"expressionSplitter", [&]() { + auto block = std::get(ASTCopier{}(m_object->code->root())); + updateContext(block); + ExpressionSplitter::run(*m_context, block); + return block; }}, - {"expressionSplitter", [&]() { ExpressionSplitter::run(*m_context, *m_ast); }}, {"expressionJoiner", [&]() { - disambiguate(); - ExpressionJoiner::run(*m_context, *m_ast); + auto block = disambiguate(); + updateContext(block); + ExpressionJoiner::run(*m_context, block); + return block; }}, {"splitJoin", [&]() { - disambiguate(); - ExpressionSplitter::run(*m_context, *m_ast); - ExpressionJoiner::run(*m_context, *m_ast); - ExpressionJoiner::run(*m_context, *m_ast); + auto block = disambiguate(); + updateContext(block); + ExpressionSplitter::run(*m_context, block); + ExpressionJoiner::run(*m_context, block); + ExpressionJoiner::run(*m_context, block); + return block; }}, {"functionGrouper", [&]() { - disambiguate(); - FunctionGrouper::run(*m_context, *m_ast); + auto block = disambiguate(); + updateContext(block); + FunctionGrouper::run(*m_context, block); + return block; }}, {"functionHoister", [&]() { - disambiguate(); - FunctionHoister::run(*m_context, *m_ast); + auto block = disambiguate(); + updateContext(block); + FunctionHoister::run(*m_context, block); + return block; }}, {"functionSpecializer", [&]() { - disambiguate(); - FunctionHoister::run(*m_context, *m_object->code); - FunctionSpecializer::run(*m_context, *m_object->code); + auto block = disambiguate(); + updateContext(block); + FunctionHoister::run(*m_context, block); + FunctionSpecializer::run(*m_context, block); + return block; }}, {"expressionInliner", [&]() { - disambiguate(); - ExpressionInliner::run(*m_context, *m_ast); + auto block = disambiguate(); + updateContext(block); + ExpressionInliner::run(*m_context, block); + return block; }}, {"fullInliner", [&]() { - disambiguate(); - FunctionHoister::run(*m_context, *m_ast); - FunctionGrouper::run(*m_context, *m_ast); - ExpressionSplitter::run(*m_context, *m_ast); - FullInliner::run(*m_context, *m_ast); - ExpressionJoiner::run(*m_context, *m_ast); + auto block = disambiguate(); + updateContext(block); + FunctionHoister::run(*m_context, block); + FunctionGrouper::run(*m_context, block); + ExpressionSplitter::run(*m_context, block); + FullInliner::run(*m_context, block); + ExpressionJoiner::run(*m_context, block); + return block; }}, {"fullInlinerWithoutSplitter", [&]() { - disambiguate(); - FunctionHoister::run(*m_context, *m_ast); - FunctionGrouper::run(*m_context, *m_ast); - FullInliner::run(*m_context, *m_ast); + auto block = disambiguate(); + updateContext(block); + FunctionHoister::run(*m_context, block); + FunctionGrouper::run(*m_context, block); + FullInliner::run(*m_context, block); + return block; }}, {"rematerialiser", [&]() { - disambiguate(); - ForLoopInitRewriter::run(*m_context, *m_ast); - FunctionHoister::run(*m_context, *m_ast); - Rematerialiser::run(*m_context, *m_ast); + auto block = disambiguate(); + updateContext(block); + ForLoopInitRewriter::run(*m_context, block); + FunctionHoister::run(*m_context, block); + Rematerialiser::run(*m_context, block); + return block; }}, {"expressionSimplifier", [&]() { - disambiguate(); - ForLoopInitRewriter::run(*m_context, *m_ast); - FunctionHoister::run(*m_context, *m_ast); - ExpressionSplitter::run(*m_context, *m_ast); - CommonSubexpressionEliminator::run(*m_context, *m_ast); - ExpressionSimplifier::run(*m_context, *m_ast); - ExpressionSimplifier::run(*m_context, *m_ast); - ExpressionSimplifier::run(*m_context, *m_ast); - UnusedPruner::run(*m_context, *m_ast); - ExpressionJoiner::run(*m_context, *m_ast); - ExpressionJoiner::run(*m_context, *m_ast); + auto block = disambiguate(); + updateContext(block); + ForLoopInitRewriter::run(*m_context, block); + FunctionHoister::run(*m_context, block); + ExpressionSplitter::run(*m_context, block); + CommonSubexpressionEliminator::run(*m_context, block); + ExpressionSimplifier::run(*m_context, block); + ExpressionSimplifier::run(*m_context, block); + ExpressionSimplifier::run(*m_context, block); + UnusedPruner::run(*m_context, block); + ExpressionJoiner::run(*m_context, block); + ExpressionJoiner::run(*m_context, block); + return block; }}, {"fullSimplify", [&]() { - disambiguate(); - FunctionGrouper::run(*m_context, *m_ast); - BlockFlattener::run(*m_context, *m_ast); - ExpressionSplitter::run(*m_context, *m_ast); - ForLoopInitRewriter::run(*m_context, *m_ast); - FunctionHoister::run(*m_context, *m_ast); - CommonSubexpressionEliminator::run(*m_context, *m_ast); - ExpressionSimplifier::run(*m_context, *m_ast); - UnusedPruner::run(*m_context, *m_ast); - CircularReferencesPruner::run(*m_context, *m_ast); - DeadCodeEliminator::run(*m_context, *m_ast); - ExpressionJoiner::run(*m_context, *m_ast); - ExpressionJoiner::run(*m_context, *m_ast); + auto block = disambiguate(); + updateContext(block); + FunctionGrouper::run(*m_context, block); + BlockFlattener::run(*m_context, block); + ExpressionSplitter::run(*m_context, block); + ForLoopInitRewriter::run(*m_context, block); + FunctionHoister::run(*m_context, block); + CommonSubexpressionEliminator::run(*m_context, block); + ExpressionSimplifier::run(*m_context, block); + UnusedPruner::run(*m_context, block); + CircularReferencesPruner::run(*m_context, block); + DeadCodeEliminator::run(*m_context, block); + ExpressionJoiner::run(*m_context, block); + ExpressionJoiner::run(*m_context, block); + return block; }}, {"unusedFunctionParameterPruner", [&]() { - disambiguate(); - ForLoopInitRewriter::run(*m_context, *m_ast); - FunctionHoister::run(*m_context, *m_object->code); - LiteralRematerialiser::run(*m_context, *m_object->code); - UnusedFunctionParameterPruner::run(*m_context, *m_object->code); + auto block = disambiguate(); + updateContext(block); + ForLoopInitRewriter::run(*m_context, block); + FunctionHoister::run(*m_context, block); + LiteralRematerialiser::run(*m_context, block); + UnusedFunctionParameterPruner::run(*m_context, block); + return block; }}, {"unusedPruner", [&]() { - disambiguate(); - UnusedPruner::run(*m_context, *m_ast); + auto block = disambiguate(); + updateContext(block); + UnusedPruner::run(*m_context, block); + return block; }}, {"circularReferencesPruner", [&]() { - disambiguate(); - FunctionHoister::run(*m_context, *m_ast); - CircularReferencesPruner::run(*m_context, *m_ast); + auto block = disambiguate(); + updateContext(block); + FunctionHoister::run(*m_context, block); + CircularReferencesPruner::run(*m_context, block); + return block; }}, {"deadCodeEliminator", [&]() { - disambiguate(); - ForLoopInitRewriter::run(*m_context, *m_ast); - DeadCodeEliminator::run(*m_context, *m_ast); + auto block = disambiguate(); + updateContext(block); + ForLoopInitRewriter::run(*m_context, block); + DeadCodeEliminator::run(*m_context, block); + return block; }}, {"ssaTransform", [&]() { - disambiguate(); - ForLoopInitRewriter::run(*m_context, *m_ast); - SSATransform::run(*m_context, *m_ast); + auto block = disambiguate(); + updateContext(block); + ForLoopInitRewriter::run(*m_context, block); + SSATransform::run(*m_context, block); + return block; }}, {"unusedAssignEliminator", [&]() { - disambiguate(); - ForLoopInitRewriter::run(*m_context, *m_ast); - UnusedAssignEliminator::run(*m_context, *m_ast); + auto block = disambiguate(); + updateContext(block); + ForLoopInitRewriter::run(*m_context, block); + UnusedAssignEliminator::run(*m_context, block); + return block; }}, {"unusedStoreEliminator", [&]() { - disambiguate(); - ForLoopInitRewriter::run(*m_context, *m_ast); - ExpressionSplitter::run(*m_context, *m_ast); - SSATransform::run(*m_context, *m_ast); - UnusedStoreEliminator::run(*m_context, *m_ast); - SSAReverser::run(*m_context, *m_ast); - ExpressionJoiner::run(*m_context, *m_ast); + auto block = disambiguate(); + updateContext(block); + ForLoopInitRewriter::run(*m_context, block); + ExpressionSplitter::run(*m_context, block); + SSATransform::run(*m_context, block); + UnusedStoreEliminator::run(*m_context, block); + SSAReverser::run(*m_context, block); + ExpressionJoiner::run(*m_context, block); + return block; }}, {"equalStoreEliminator", [&]() { - disambiguate(); - FunctionHoister::run(*m_context, *m_ast); - ForLoopInitRewriter::run(*m_context, *m_ast); - EqualStoreEliminator::run(*m_context, *m_ast); + auto block = disambiguate(); + updateContext(block); + FunctionHoister::run(*m_context, block); + ForLoopInitRewriter::run(*m_context, block); + EqualStoreEliminator::run(*m_context, block); + return block; }}, {"ssaPlusCleanup", [&]() { - disambiguate(); - ForLoopInitRewriter::run(*m_context, *m_ast); - SSATransform::run(*m_context, *m_ast); - UnusedAssignEliminator::run(*m_context, *m_ast); + auto block = disambiguate(); + updateContext(block); + ForLoopInitRewriter::run(*m_context, block); + SSATransform::run(*m_context, block); + UnusedAssignEliminator::run(*m_context, block); + return block; }}, {"loadResolver", [&]() { - disambiguate(); - FunctionGrouper::run(*m_context, *m_ast); - BlockFlattener::run(*m_context, *m_ast); - ForLoopInitRewriter::run(*m_context, *m_ast); - FunctionHoister::run(*m_context, *m_ast); - ExpressionSplitter::run(*m_context, *m_ast); - CommonSubexpressionEliminator::run(*m_context, *m_ast); - ExpressionSimplifier::run(*m_context, *m_ast); + auto block = disambiguate(); + updateContext(block); + FunctionGrouper::run(*m_context, block); + BlockFlattener::run(*m_context, block); + ForLoopInitRewriter::run(*m_context, block); + FunctionHoister::run(*m_context, block); + ExpressionSplitter::run(*m_context, block); + CommonSubexpressionEliminator::run(*m_context, block); + ExpressionSimplifier::run(*m_context, block); - LoadResolver::run(*m_context, *m_ast); + LoadResolver::run(*m_context, block); - UnusedPruner::run(*m_context, *m_ast); - ExpressionJoiner::run(*m_context, *m_ast); - ExpressionJoiner::run(*m_context, *m_ast); + UnusedPruner::run(*m_context, block); + ExpressionJoiner::run(*m_context, block); + ExpressionJoiner::run(*m_context, block); + return block; }}, {"loopInvariantCodeMotion", [&]() { - disambiguate(); - ForLoopInitRewriter::run(*m_context, *m_ast); - FunctionHoister::run(*m_context, *m_ast); - LoopInvariantCodeMotion::run(*m_context, *m_ast); + auto block = disambiguate(); + updateContext(block); + ForLoopInitRewriter::run(*m_context, block); + FunctionHoister::run(*m_context, block); + LoopInvariantCodeMotion::run(*m_context, block); + return block; }}, {"controlFlowSimplifier", [&]() { - disambiguate(); - ForLoopInitRewriter::run(*m_context, *m_ast); - ControlFlowSimplifier::run(*m_context, *m_ast); + auto block = disambiguate(); + updateContext(block); + ForLoopInitRewriter::run(*m_context, block); + ControlFlowSimplifier::run(*m_context, block); + return block; }}, {"structuralSimplifier", [&]() { - disambiguate(); - ForLoopInitRewriter::run(*m_context, *m_ast); - FunctionHoister::run(*m_context, *m_ast); - LiteralRematerialiser::run(*m_context, *m_ast); - StructuralSimplifier::run(*m_context, *m_ast); + auto block = disambiguate(); + updateContext(block); + ForLoopInitRewriter::run(*m_context, block); + FunctionHoister::run(*m_context, block); + LiteralRematerialiser::run(*m_context, block); + StructuralSimplifier::run(*m_context, block); + return block; }}, {"equivalentFunctionCombiner", [&]() { - disambiguate(); - ForLoopInitRewriter::run(*m_context, *m_ast); - FunctionHoister::run(*m_context, *m_ast); - EquivalentFunctionCombiner::run(*m_context, *m_ast); + auto block = disambiguate(); + updateContext(block); + ForLoopInitRewriter::run(*m_context, block); + FunctionHoister::run(*m_context, block); + EquivalentFunctionCombiner::run(*m_context, block); + return block; }}, {"ssaReverser", [&]() { - disambiguate(); - SSAReverser::run(*m_context, *m_ast); + auto block = disambiguate(); + updateContext(block); + SSAReverser::run(*m_context, block); + return block; }}, {"ssaAndBack", [&]() { - disambiguate(); - ForLoopInitRewriter::run(*m_context, *m_ast); + auto block = disambiguate(); + updateContext(block); + ForLoopInitRewriter::run(*m_context, block); // apply SSA - SSATransform::run(*m_context, *m_ast); - UnusedAssignEliminator::run(*m_context, *m_ast); + SSATransform::run(*m_context, block); + UnusedAssignEliminator::run(*m_context, block); // reverse SSA - SSAReverser::run(*m_context, *m_ast); - FunctionHoister::run(*m_context, *m_ast); - CommonSubexpressionEliminator::run(*m_context, *m_ast); - UnusedPruner::run(*m_context, *m_ast); + SSAReverser::run(*m_context, block); + FunctionHoister::run(*m_context, block); + CommonSubexpressionEliminator::run(*m_context, block); + UnusedPruner::run(*m_context, block); + return block; }}, {"stackCompressor", [&]() { - disambiguate(); - ForLoopInitRewriter::run(*m_context, *m_ast); - FunctionHoister::run(*m_context, *m_ast); - FunctionGrouper::run(*m_context, *m_ast); + auto block = disambiguate(); + updateContext(block); + ForLoopInitRewriter::run(*m_context, block); + FunctionHoister::run(*m_context, block); + FunctionGrouper::run(*m_context, block); size_t maxIterations = 16; - StackCompressor::run(*m_dialect, *m_object, true, maxIterations); - BlockFlattener::run(*m_context, *m_ast); + StackCompressor::run(*m_dialect, block, *m_object, true, maxIterations); + BlockFlattener::run(*m_context, block); + return block; }}, {"fullSuite", [&]() { GasMeter meter(dynamic_cast(*m_dialect), false, 200); OptimiserSuite::run( *m_dialect, &meter, - *m_object, + *m_optimizedObject, true, frontend::OptimiserSettings::DefaultYulOptimiserSteps, frontend::OptimiserSettings::DefaultYulOptimiserCleanupSteps, frontend::OptimiserSettings::standard().expectedExecutionsPerDeployment ); + return std::get(ASTCopier{}(m_optimizedObject->code->root())); }}, {"stackLimitEvader", [&]() { - disambiguate(); - StackLimitEvader::run(*m_context, *m_object, CompilabilityChecker{ + auto block = disambiguate(); + updateContext(block); + StackLimitEvader::run(*m_context, block, CompilabilityChecker{ *m_dialect, *m_object, - true + true, + &block }.unreachableVariables); + return block; }}, {"fakeStackLimitEvader", [&]() { - disambiguate(); + auto block = disambiguate(); + updateContext(block); // Mark all variables with a name starting with "$" for escalation to memory. struct FakeUnreachableGenerator: ASTWalker { @@ -381,8 +467,9 @@ YulOptimizerTestCommon::YulOptimizerTestCommon( YulName m_currentFunction = YulName{}; }; FakeUnreachableGenerator fakeUnreachableGenerator; - fakeUnreachableGenerator(*m_ast); - StackLimitEvader::run(*m_context, *m_object, fakeUnreachableGenerator.fakeUnreachables); + fakeUnreachableGenerator(block); + StackLimitEvader::run(*m_context, block, fakeUnreachableGenerator.fakeUnreachables); + return block; }} }; } @@ -396,10 +483,11 @@ bool YulOptimizerTestCommon::runStep() { yulAssert(m_dialect, "Dialect not set."); - updateContext(); - if (m_namedSteps.count(m_optimizerStep)) - m_namedSteps[m_optimizerStep](); + { + auto block = m_namedSteps[m_optimizerStep](); + m_optimizedObject->code = std::make_shared(std::move(block)); + } else return false; @@ -435,21 +523,21 @@ std::string YulOptimizerTestCommon::randomOptimiserStep(unsigned _seed) yulAssert(false, "Optimiser step selection failed."); } -std::shared_ptr YulOptimizerTestCommon::run() +Block const* YulOptimizerTestCommon::run() { - return runStep() ? m_ast : nullptr; + return runStep() ? &m_optimizedObject->code->root() : nullptr; } -void YulOptimizerTestCommon::disambiguate() +Block YulOptimizerTestCommon::disambiguate() { - *m_object->code = std::get(Disambiguator(*m_dialect, *m_analysisInfo)(*m_object->code)); + auto block = std::get(Disambiguator(*m_dialect, *m_analysisInfo)(m_object->code->root())); m_analysisInfo.reset(); - updateContext(); + return block; } -void YulOptimizerTestCommon::updateContext() +void YulOptimizerTestCommon::updateContext(Block const& _block) { - m_nameDispenser = std::make_unique(*m_dialect, *m_object->code, m_reservedIdentifiers); + m_nameDispenser = std::make_unique(*m_dialect, _block, m_reservedIdentifiers); m_context = std::make_unique(OptimiserStepContext{ *m_dialect, *m_nameDispenser, @@ -457,3 +545,8 @@ void YulOptimizerTestCommon::updateContext() frontend::OptimiserSettings::standard().expectedExecutionsPerDeployment }); } + +std::shared_ptr YulOptimizerTestCommon::optimizedObject() const +{ + return m_optimizedObject; +} diff --git a/test/libyul/YulOptimizerTestCommon.h b/test/libyul/YulOptimizerTestCommon.h index 0a5d63320d6d..8a706c328b49 100644 --- a/test/libyul/YulOptimizerTestCommon.h +++ b/test/libyul/YulOptimizerTestCommon.h @@ -28,9 +28,10 @@ namespace solidity::yul { - struct AsmAnalysisInfo; - struct Object; - struct Dialect; +struct AsmAnalysisInfo; +struct Object; +struct Dialect; +class AST; } namespace solidity::yul::test @@ -47,7 +48,7 @@ class YulOptimizerTestCommon void setStep(std::string const& _optimizerStep); /// Runs chosen optimiser step returning pointer /// to yul AST Block post optimisation. - std::shared_ptr run(); + Block const* run(); /// Runs chosen optimiser step returning true if /// successful, false otherwise. bool runStep(); @@ -56,9 +57,11 @@ class YulOptimizerTestCommon /// @param _seed is an unsigned integer that /// seeds the random selection. std::string randomOptimiserStep(unsigned _seed); + /// the resulting object after performing optimization steps + std::shared_ptr optimizedObject() const; private: - void disambiguate(); - void updateContext(); + Block disambiguate(); + void updateContext(Block const& _block); std::string m_optimizerStep; @@ -68,9 +71,9 @@ class YulOptimizerTestCommon std::unique_ptr m_context; std::shared_ptr m_object; - std::shared_ptr m_ast; + std::shared_ptr m_optimizedObject; std::shared_ptr m_analysisInfo; - std::map> m_namedSteps; + std::map> m_namedSteps; }; } diff --git a/test/tools/ossfuzz/StackReuseCodegenFuzzer.cpp b/test/tools/ossfuzz/StackReuseCodegenFuzzer.cpp index 25559bc66f27..940fc7374ee9 100644 --- a/test/tools/ossfuzz/StackReuseCodegenFuzzer.cpp +++ b/test/tools/ossfuzz/StackReuseCodegenFuzzer.cpp @@ -54,7 +54,7 @@ namespace /// @returns true if there are recursive functions, false otherwise. bool recursiveFunctionExists(Dialect const& _dialect, yul::Object& _object) { - auto recursiveFunctions = CallGraphGenerator::callGraph(*_object.code).recursiveFunctions(); + auto recursiveFunctions = CallGraphGenerator::callGraph(_object.code->root()).recursiveFunctions(); for(auto&& [function, variables]: CompilabilityChecker{ _dialect, _object, diff --git a/test/tools/ossfuzz/strictasm_diff_ossfuzz.cpp b/test/tools/ossfuzz/strictasm_diff_ossfuzz.cpp index e31391b0e15b..40201bd15fad 100644 --- a/test/tools/ossfuzz/strictasm_diff_ossfuzz.cpp +++ b/test/tools/ossfuzz/strictasm_diff_ossfuzz.cpp @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -88,7 +89,7 @@ extern "C" int LLVMFuzzerTestOneInput(uint8_t const* _data, size_t _size) // that would be removed by the redundant store eliminator. yulFuzzerUtil::TerminationReason termReason = yulFuzzerUtil::interpret( os1, - stack.parserResult()->code, + stack.parserResult()->code->root(), EVMDialect::strictAssemblyForEVMObjects(langutil::EVMVersion()), /*disableMemoryTracing=*/true ); @@ -98,7 +99,7 @@ extern "C" int LLVMFuzzerTestOneInput(uint8_t const* _data, size_t _size) stack.optimize(); termReason = yulFuzzerUtil::interpret( os2, - stack.parserResult()->code, + stack.parserResult()->code->root(), EVMDialect::strictAssemblyForEVMObjects(langutil::EVMVersion()), /*disableMemoryTracing=*/true ); diff --git a/test/tools/ossfuzz/yulFuzzerCommon.cpp b/test/tools/ossfuzz/yulFuzzerCommon.cpp index 4f7a871ac8bf..033dfc044d12 100644 --- a/test/tools/ossfuzz/yulFuzzerCommon.cpp +++ b/test/tools/ossfuzz/yulFuzzerCommon.cpp @@ -23,7 +23,7 @@ using namespace solidity::yul::test::yul_fuzzer; yulFuzzerUtil::TerminationReason yulFuzzerUtil::interpret( std::ostream& _os, - std::shared_ptr _ast, + yul::Block const& _astRoot, Dialect const& _dialect, bool _disableMemoryTracing, bool _outputStorageOnly, @@ -52,7 +52,7 @@ yulFuzzerUtil::TerminationReason yulFuzzerUtil::interpret( TerminationReason reason = TerminationReason::None; try { - Interpreter::run(state, _dialect, *_ast, true, _disableMemoryTracing); + Interpreter::run(state, _dialect, _astRoot, true, _disableMemoryTracing); } catch (StepLimitReached const&) { diff --git a/test/tools/ossfuzz/yulFuzzerCommon.h b/test/tools/ossfuzz/yulFuzzerCommon.h index 4c8f665f616c..6575db11face 100644 --- a/test/tools/ossfuzz/yulFuzzerCommon.h +++ b/test/tools/ossfuzz/yulFuzzerCommon.h @@ -40,7 +40,7 @@ struct yulFuzzerUtil /// eliminator. static TerminationReason interpret( std::ostream& _os, - std::shared_ptr _ast, + yul::Block const& _astRoot, Dialect const& _dialect, bool _disableMemoryTracing = false, bool _outputStorageOnly = false, diff --git a/test/tools/ossfuzz/yulProtoFuzzer.cpp b/test/tools/ossfuzz/yulProtoFuzzer.cpp index b27d879d5606..092f2dacb7c7 100644 --- a/test/tools/ossfuzz/yulProtoFuzzer.cpp +++ b/test/tools/ossfuzz/yulProtoFuzzer.cpp @@ -84,6 +84,6 @@ DEFINE_PROTO_FUZZER(Program const& _input) EVMDialect::strictAssemblyForEVMObjects(version) ); optimizerTest.setStep(optimizerTest.randomOptimiserStep(_input.step())); - std::shared_ptr astBlock = optimizerTest.run(); - yulAssert(astBlock != nullptr, "Optimiser error."); + auto const* astRoot = optimizerTest.run(); + yulAssert(astRoot != nullptr, "Optimiser error."); } diff --git a/test/tools/ossfuzz/yulProto_diff_ossfuzz.cpp b/test/tools/ossfuzz/yulProto_diff_ossfuzz.cpp index 49470f719820..4e07eaf6468c 100644 --- a/test/tools/ossfuzz/yulProto_diff_ossfuzz.cpp +++ b/test/tools/ossfuzz/yulProto_diff_ossfuzz.cpp @@ -26,6 +26,7 @@ #include +#include #include #include #include @@ -88,7 +89,7 @@ DEFINE_PROTO_FUZZER(Program const& _input) // that would be removed by the redundant store eliminator. yulFuzzerUtil::TerminationReason termReason = yulFuzzerUtil::interpret( os1, - stack.parserResult()->code, + stack.parserResult()->code->root(), EVMDialect::strictAssemblyForEVMObjects(version), /*disableMemoryTracing=*/true ); @@ -101,11 +102,11 @@ DEFINE_PROTO_FUZZER(Program const& _input) EVMDialect::strictAssemblyForEVMObjects(version) ); optimizerTest.setStep(optimizerTest.randomOptimiserStep(_input.step())); - std::shared_ptr astBlock = optimizerTest.run(); - yulAssert(astBlock != nullptr, "Optimiser error."); + auto const* astRoot = optimizerTest.run(); + yulAssert(astRoot != nullptr, "Optimiser error."); termReason = yulFuzzerUtil::interpret( os2, - astBlock, + *astRoot, EVMDialect::strictAssemblyForEVMObjects(version), true ); diff --git a/test/tools/yulopti.cpp b/test/tools/yulopti.cpp index 2b9e530e0254..1655b13d3863 100644 --- a/test/tools/yulopti.cpp +++ b/test/tools/yulopti.cpp @@ -58,9 +58,7 @@ #include #include -#include #include -#include #include #include @@ -92,20 +90,21 @@ class YulOpti CharStream _charStream(_input, ""); try { - m_ast = yul::Parser(errorReporter, m_dialect).parse(_charStream); - if (!m_ast || !errorReporter.errors().empty()) + auto ast = yul::Parser(errorReporter, m_dialect).parse(_charStream); + if (!m_astRoot || !errorReporter.errors().empty()) { std::cerr << "Error parsing source." << std::endl; printErrors(_charStream, errors); throw std::runtime_error("Could not parse source."); } + m_astRoot = std::make_shared(std::get(ASTCopier{}(ast->root()))); m_analysisInfo = std::make_unique(); AsmAnalyzer analyzer( *m_analysisInfo, errorReporter, m_dialect ); - if (!analyzer.analyze(*m_ast) || !errorReporter.errors().empty()) + if (!analyzer.analyze(*m_astRoot) || !errorReporter.errors().empty()) { std::cerr << "Error analyzing source." << std::endl; printErrors(_charStream, errors); @@ -171,17 +170,17 @@ class YulOpti void disambiguate() { - *m_ast = std::get(Disambiguator(m_dialect, *m_analysisInfo)(*m_ast)); + *m_astRoot = std::get(Disambiguator(m_dialect, *m_analysisInfo)(*m_astRoot)); m_analysisInfo.reset(); - m_nameDispenser.reset(*m_ast); + m_nameDispenser.reset(*m_astRoot); } void runSteps(std::string _source, std::string _steps) { parse(_source); disambiguate(); - OptimiserSuite{m_context}.runSequence(_steps, *m_ast); - std::cout << AsmPrinter{AsmPrinter::TypePrinting::OmitDefault, m_dialect}(*m_ast) << std::endl; + OptimiserSuite{m_context}.runSequence(_steps, *m_astRoot); + std::cout << AsmPrinter{AsmPrinter::TypePrinting::OmitDefault, m_dialect}(*m_astRoot) << std::endl; } void runInteractive(std::string _source, bool _disambiguated = false) @@ -212,24 +211,23 @@ class YulOpti case '#': return; case ',': - VarNameCleaner::run(m_context, *m_ast); + VarNameCleaner::run(m_context, *m_astRoot); // 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); + StackCompressor::run(m_dialect, *m_astRoot, obj, true, 16); break; } default: OptimiserSuite{m_context}.runSequence( std::string_view(&option, 1), - *m_ast + *m_astRoot ); } - _source = AsmPrinter{AsmPrinter::TypePrinting::OmitDefault, m_dialect}(*m_ast); + _source = AsmPrinter{AsmPrinter::TypePrinting::OmitDefault, m_dialect}(*m_astRoot); } catch (...) { @@ -242,7 +240,7 @@ class YulOpti } private: - std::shared_ptr m_ast; + std::shared_ptr m_astRoot; Dialect const& m_dialect{EVMDialect::strictAssemblyForEVMObjects(EVMVersion{})}; std::unique_ptr m_analysisInfo; std::set const m_reservedIdentifiers = {}; diff --git a/test/tools/yulrun.cpp b/test/tools/yulrun.cpp index fb18b4e598ee..9aee616e0e4a 100644 --- a/test/tools/yulrun.cpp +++ b/test/tools/yulrun.cpp @@ -54,7 +54,7 @@ namespace po = boost::program_options; namespace { -std::pair, std::shared_ptr> parse(std::string const& _source) +std::pair, std::shared_ptr> parse(std::string const& _source) { YulStack stack( langutil::EVMVersion(), @@ -77,7 +77,7 @@ std::pair, std::shared_ptr> parse(std::s void interpret(std::string const& _source, bool _inspect, bool _disableExternalCalls) { - std::shared_ptr ast; + std::shared_ptr ast; std::shared_ptr analysisInfo; tie(ast, analysisInfo) = parse(_source); if (!ast || !analysisInfo) @@ -90,10 +90,10 @@ void interpret(std::string const& _source, bool _inspect, bool _disableExternalC Dialect const& dialect(EVMDialect::strictAssemblyForEVMObjects(langutil::EVMVersion{})); if (_inspect) - InspectedInterpreter::run(std::make_shared(_source, state), state, dialect, *ast, _disableExternalCalls, /*disableMemoryTracing=*/false); + InspectedInterpreter::run(std::make_shared(_source, state), state, dialect, ast->root(), _disableExternalCalls, /*disableMemoryTracing=*/false); else - Interpreter::run(state, dialect, *ast, _disableExternalCalls, /*disableMemoryTracing=*/false); + Interpreter::run(state, dialect, ast->root(), _disableExternalCalls, /*disableMemoryTracing=*/false); } catch (InterpreterTerminatedGeneric const&) { diff --git a/tools/yulPhaser/Program.cpp b/tools/yulPhaser/Program.cpp index e0c8ec4fbed6..2d5c31cf11b5 100644 --- a/tools/yulPhaser/Program.cpp +++ b/tools/yulPhaser/Program.cpp @@ -59,7 +59,7 @@ std::ostream& operator<<(std::ostream& _stream, Program const& _program); } Program::Program(Program const& program): - m_ast(std::make_unique(std::get(ASTCopier{}(*program.m_ast)))), + m_ast(std::make_unique(std::get(ASTCopier{}(program.m_ast->root())))), m_dialect{program.m_dialect}, m_nameDispenser(program.m_nameDispenser) { @@ -70,13 +70,13 @@ std::variant Program::load(CharStream& _sourceCode) // ASSUMPTION: parseSource() rewinds the stream on its own Dialect const& dialect = EVMDialect::strictAssemblyForEVMObjects(EVMVersion{}); - std::variant, ErrorList> astOrErrors = parseObject(dialect, _sourceCode); + std::variant, ErrorList> astOrErrors = parseObject(dialect, _sourceCode); if (std::holds_alternative(astOrErrors)) return std::get(astOrErrors); std::variant, ErrorList> analysisInfoOrErrors = analyzeAST( dialect, - *std::get>(astOrErrors) + *std::get>(astOrErrors) ); if (std::holds_alternative(analysisInfoOrErrors)) return std::get(analysisInfoOrErrors); @@ -85,7 +85,7 @@ std::variant Program::load(CharStream& _sourceCode) dialect, disambiguateAST( dialect, - *std::get>(astOrErrors), + *std::get>(astOrErrors), *std::get>(analysisInfoOrErrors) ) ); @@ -105,16 +105,16 @@ void Program::optimise(std::vector const& _optimisationSteps) std::ostream& phaser::operator<<(std::ostream& _stream, Program const& _program) { - return _stream << AsmPrinter(AsmPrinter::TypePrinting::Full, _program.m_dialect)(*_program.m_ast); + return _stream << AsmPrinter(AsmPrinter::TypePrinting::Full, _program.m_dialect)(_program.m_ast->root()); } std::string Program::toJson() const { - Json serializedAst = AsmJsonConverter(0)(*m_ast); + Json serializedAst = AsmJsonConverter(0)(m_ast->root()); return jsonPrettyPrint(removeNullMembers(std::move(serializedAst))); } -std::variant, ErrorList> Program::parseObject(Dialect const& _dialect, CharStream _source) +std::variant, ErrorList> Program::parseObject(Dialect const& _dialect, CharStream _source) { ErrorList errors; ErrorReporter errorReporter(errors); @@ -149,19 +149,19 @@ std::variant, ErrorList> Program::parseObject(Dialect con // The public API of the class does not provide access to the smart pointer so it won't be hard // to switch to shared_ptr if the copying turns out to be an issue (though it would be better // to refactor ObjectParser and Object to use unique_ptr instead). - auto astCopy = std::make_unique(std::get(ASTCopier{}(*selectedObject->code))); + auto astCopy = std::make_unique(std::get(ASTCopier{}(selectedObject->code->root()))); - return std::variant, ErrorList>(std::move(astCopy)); + return std::variant, ErrorList>(std::move(astCopy)); } -std::variant, ErrorList> Program::analyzeAST(Dialect const& _dialect, Block const& _ast) +std::variant, ErrorList> Program::analyzeAST(Dialect const& _dialect, AST const& _ast) { ErrorList errors; ErrorReporter errorReporter(errors); auto analysisInfo = std::make_unique(); AsmAnalyzer analyzer(*analysisInfo, errorReporter, _dialect); - bool analysisSuccessful = analyzer.analyze(_ast); + bool analysisSuccessful = analyzer.analyze(_ast.root()); if (!analysisSuccessful) return errors; @@ -169,22 +169,22 @@ std::variant, ErrorList> Program::analyzeAST(Di return std::variant, ErrorList>(std::move(analysisInfo)); } -std::unique_ptr Program::disambiguateAST( +std::unique_ptr Program::disambiguateAST( Dialect const& _dialect, - Block const& _ast, + AST const& _ast, AsmAnalysisInfo const& _analysisInfo ) { std::set const externallyUsedIdentifiers = {}; Disambiguator disambiguator(_dialect, _analysisInfo, externallyUsedIdentifiers); - return std::make_unique(std::get(disambiguator(_ast))); + return std::make_unique(std::get(disambiguator(_ast.root()))); } -std::unique_ptr Program::applyOptimisationSteps( +std::unique_ptr Program::applyOptimisationSteps( Dialect const& _dialect, NameDispenser& _nameDispenser, - std::unique_ptr _ast, + std::unique_ptr _ast, std::vector const& _optimisationSteps ) { @@ -198,10 +198,11 @@ std::unique_ptr Program::applyOptimisationSteps( frontend::OptimiserSettings::standard().expectedExecutionsPerDeployment }; + auto astRoot = std::get(ASTCopier{}(_ast->root())); for (std::string const& step: _optimisationSteps) - OptimiserSuite::allSteps().at(step)->run(context, *_ast); + OptimiserSuite::allSteps().at(step)->run(context, astRoot); - return _ast; + return std::make_unique(std::move(astRoot)); } size_t Program::computeCodeSize(Block const& _ast, CodeWeights const& _weights) diff --git a/tools/yulPhaser/Program.h b/tools/yulPhaser/Program.h index e42471d77947..be4bf582d665 100644 --- a/tools/yulPhaser/Program.h +++ b/tools/yulPhaser/Program.h @@ -75,8 +75,8 @@ class Program static std::variant load(langutil::CharStream& _sourceCode); void optimise(std::vector const& _optimisationSteps); - size_t codeSize(yul::CodeWeights const& _weights) const { return computeCodeSize(*m_ast, _weights); } - yul::Block const& ast() const { return *m_ast; } + size_t codeSize(yul::CodeWeights const& _weights) const { return computeCodeSize(m_ast->root(), _weights); } + yul::Block const& ast() const { return m_ast->root(); } friend std::ostream& operator<<(std::ostream& _stream, Program const& _program); std::string toJson() const; @@ -84,35 +84,35 @@ class Program private: Program( yul::Dialect const& _dialect, - std::unique_ptr _ast + std::unique_ptr _ast ): m_ast(std::move(_ast)), m_dialect{_dialect}, - m_nameDispenser(_dialect, *m_ast, {}) + m_nameDispenser(_dialect, m_ast->root(), {}) {} - static std::variant, langutil::ErrorList> parseObject( + static std::variant, langutil::ErrorList> parseObject( yul::Dialect const& _dialect, langutil::CharStream _source ); static std::variant, langutil::ErrorList> analyzeAST( yul::Dialect const& _dialect, - yul::Block const& _ast + yul::AST const& _ast ); - static std::unique_ptr disambiguateAST( + static std::unique_ptr disambiguateAST( yul::Dialect const& _dialect, - yul::Block const& _ast, + yul::AST const& _ast, yul::AsmAnalysisInfo const& _analysisInfo ); - static std::unique_ptr applyOptimisationSteps( + static std::unique_ptr applyOptimisationSteps( yul::Dialect const& _dialect, yul::NameDispenser& _nameDispenser, - std::unique_ptr _ast, + std::unique_ptr _ast, std::vector const& _optimisationSteps ); static size_t computeCodeSize(yul::Block const& _ast, yul::CodeWeights const& _weights); - std::unique_ptr m_ast; + std::unique_ptr m_ast; yul::Dialect const& m_dialect; yul::NameDispenser m_nameDispenser; }; From d109d6bf76335f3db6eb8d570e02ecd0f481f180 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Mon, 29 Jul 2024 17:43:00 +0200 Subject: [PATCH 0327/1022] Yul: StackCompressor/StackLimitEvader return modified ast and operate on const object input --- libyul/CompilabilityChecker.cpp | 13 ++++---- libyul/CompilabilityChecker.h | 3 +- libyul/optimiser/StackCompressor.cpp | 41 ++++++++++---------------- libyul/optimiser/StackCompressor.h | 17 ++--------- libyul/optimiser/StackLimitEvader.cpp | 19 +++++++----- libyul/optimiser/StackLimitEvader.h | 3 +- libyul/optimiser/Suite.cpp | 24 ++++++++++----- test/libyul/YulOptimizerTestCommon.cpp | 18 +++++++---- test/tools/yulopti.cpp | 3 +- 9 files changed, 67 insertions(+), 74 deletions(-) diff --git a/libyul/CompilabilityChecker.cpp b/libyul/CompilabilityChecker.cpp index 76affbd64756..af7532c75d07 100644 --- a/libyul/CompilabilityChecker.cpp +++ b/libyul/CompilabilityChecker.cpp @@ -33,20 +33,17 @@ using namespace solidity::util; CompilabilityChecker::CompilabilityChecker( Dialect const& _dialect, Object const& _object, - bool _optimizeStackAllocation, - Block const* _block + bool _optimizeStackAllocation ) { - yulAssert(_object.code || _block); + yulAssert(_object.code); if (auto const* evmDialect = dynamic_cast(&_dialect)) { - if (!_block) - _block = &_object.code->root(); NoOutputEVMDialect noOutputDialect(*evmDialect); yul::AsmAnalysisInfo analysisInfo = yul::AsmAnalyzer::analyzeStrictAssertCorrect( noOutputDialect, - *_block, + _object.code->root(), _object.qualifiedDataNames() ); @@ -60,12 +57,12 @@ CompilabilityChecker::CompilabilityChecker( CodeTransform transform( assembly, analysisInfo, - *_block, + _object.code->root(), noOutputDialect, builtinContext, _optimizeStackAllocation ); - transform(*_block); + transform(_object.code->root()); for (StackTooDeepError const& error: transform.stackErrors()) { diff --git a/libyul/CompilabilityChecker.h b/libyul/CompilabilityChecker.h index 1dd66999066d..160aeca8c783 100644 --- a/libyul/CompilabilityChecker.h +++ b/libyul/CompilabilityChecker.h @@ -47,8 +47,7 @@ struct CompilabilityChecker CompilabilityChecker( Dialect const& _dialect, Object const& _object, - bool _optimizeStackAllocation, - Block const* _blockOverride = nullptr + bool _optimizeStackAllocation ); std::map> unreachableVariables; std::map stackDeficit; diff --git a/libyul/optimiser/StackCompressor.cpp b/libyul/optimiser/StackCompressor.cpp index 10360756d670..bdc20a5a8c71 100644 --- a/libyul/optimiser/StackCompressor.cpp +++ b/libyul/optimiser/StackCompressor.cpp @@ -236,29 +236,15 @@ void eliminateVariablesOptimizedCodegen( } -bool StackCompressor::run( +std::tuple StackCompressor::run( Dialect const& _dialect, - Object& _object, - bool _optimizeStackAllocation, - size_t _maxIterations -) -{ - yulAssert(_object.code); - auto block = std::get(ASTCopier{}(_object.code->root())); - auto result = run(_dialect, block, _object, _optimizeStackAllocation, _maxIterations); - _object.code = std::make_shared(std::move(block)); - return result; -} - -bool StackCompressor::run( - Dialect const& _dialect, - Block& _astRoot, Object const& _object, bool _optimizeStackAllocation, size_t _maxIterations) { + yulAssert(_object.code); yulAssert( - !_astRoot.statements.empty() && std::holds_alternative(_astRoot.statements.at(0)), + !_object.code->root().statements.empty() && std::holds_alternative(_object.code->root().statements.at(0)), "Need to run the function grouper before the stack compressor." ); bool usesOptimizedCodeGenerator = false; @@ -267,31 +253,36 @@ bool StackCompressor::run( _optimizeStackAllocation && evmDialect->evmVersion().canOverchargeGasForCall() && evmDialect->providesObjectAccess(); - bool allowMSizeOptimization = !MSizeFinder::containsMSize(_dialect, _astRoot); + bool allowMSizeOptimization = !MSizeFinder::containsMSize(_dialect, _object.code->root()); + Block astRoot = std::get(ASTCopier{}(_object.code->root())); if (usesOptimizedCodeGenerator) { - yul::AsmAnalysisInfo analysisInfo = yul::AsmAnalyzer::analyzeStrictAssertCorrect(_dialect, _astRoot, _object.qualifiedDataNames()); - std::unique_ptr cfg = ControlFlowGraphBuilder::build(analysisInfo, _dialect, _astRoot); + yul::AsmAnalysisInfo analysisInfo = yul::AsmAnalyzer::analyzeStrictAssertCorrect(_dialect, astRoot, _object.qualifiedDataNames()); + std::unique_ptr cfg = ControlFlowGraphBuilder::build(analysisInfo, _dialect, astRoot); eliminateVariablesOptimizedCodegen( _dialect, - _astRoot, + astRoot, StackLayoutGenerator::reportStackTooDeep(*cfg), allowMSizeOptimization ); } else + { for (size_t iterations = 0; iterations < _maxIterations; iterations++) { - std::map stackSurplus = CompilabilityChecker(_dialect, _object, _optimizeStackAllocation, &_astRoot).stackDeficit; + Object object(_object); + object.code = std::make_shared(std::get(ASTCopier{}(astRoot))); + std::map stackSurplus = CompilabilityChecker(_dialect, object, _optimizeStackAllocation).stackDeficit; if (stackSurplus.empty()) - return true; + return std::make_tuple(true, std::move(astRoot)); eliminateVariables( _dialect, - _astRoot, + astRoot, stackSurplus, allowMSizeOptimization ); } - return false; + } + return std::make_tuple(false, std::move(astRoot)); } diff --git a/libyul/optimiser/StackCompressor.h b/libyul/optimiser/StackCompressor.h index 13b9459a28e7..15d057455ac8 100644 --- a/libyul/optimiser/StackCompressor.h +++ b/libyul/optimiser/StackCompressor.h @@ -44,21 +44,10 @@ struct FunctionDefinition; class StackCompressor { public: - /// Try to remove local variables until the AST is compilable. Modifies the object's AST. - /// @returns true if it was successful. - static bool run( + /// Try to remove local variables until the AST is compilable. + /// @returns tuple with true if it was successful as first element, second element is the modified AST. + static std::tuple run( Dialect const& _dialect, - Object& _object, - bool _optimizeStackAllocation, - size_t _maxIterations - ); - - /// Try to remove local variables until the AST is compilable. Operates on provided block, - /// disregards the AST contained in object. - /// @returns true if it was successful. - static bool run( - Dialect const& _dialect, - Block& _astRoot, Object const& _object, bool _optimizeStackAllocation, size_t _maxIterations diff --git a/libyul/optimiser/StackLimitEvader.cpp b/libyul/optimiser/StackLimitEvader.cpp index 210be1cf38b6..d613ae9937df 100644 --- a/libyul/optimiser/StackLimitEvader.cpp +++ b/libyul/optimiser/StackLimitEvader.cpp @@ -15,6 +15,7 @@ along with solidity. If not, see . */ +#include #include #include #include @@ -117,31 +118,33 @@ u256 literalArgumentValue(FunctionCall const& _call) } } -void StackLimitEvader::run( +Block StackLimitEvader::run( OptimiserStepContext& _context, - Block& _astRoot, Object const& _object ) { + yulAssert(_object.code); auto const* evmDialect = dynamic_cast(&_context.dialect); yulAssert( evmDialect && evmDialect->providesObjectAccess(), "StackLimitEvader can only be run on objects using the EVMDialect with object access." ); + auto astRoot = std::get(ASTCopier{}(_object.code->root())); if (evmDialect && evmDialect->evmVersion().canOverchargeGasForCall()) { - yul::AsmAnalysisInfo analysisInfo = yul::AsmAnalyzer::analyzeStrictAssertCorrect(*evmDialect, _astRoot, _object.qualifiedDataNames()); - std::unique_ptr cfg = ControlFlowGraphBuilder::build(analysisInfo, *evmDialect, _astRoot); - run(_context, _astRoot, StackLayoutGenerator::reportStackTooDeep(*cfg)); + yul::AsmAnalysisInfo analysisInfo = yul::AsmAnalyzer::analyzeStrictAssertCorrect(*evmDialect, astRoot, _object.qualifiedDataNames()); + std::unique_ptr cfg = ControlFlowGraphBuilder::build(analysisInfo, *evmDialect, astRoot); + run(_context, astRoot, StackLayoutGenerator::reportStackTooDeep(*cfg)); } else - run(_context, _astRoot, CompilabilityChecker{ + { + run(_context, astRoot, CompilabilityChecker{ _context.dialect, _object, true, - &_astRoot }.unreachableVariables); - + } + return astRoot; } void StackLimitEvader::run( diff --git a/libyul/optimiser/StackLimitEvader.h b/libyul/optimiser/StackLimitEvader.h index 5029f7825f4b..a5871f7f111d 100644 --- a/libyul/optimiser/StackLimitEvader.h +++ b/libyul/optimiser/StackLimitEvader.h @@ -77,9 +77,8 @@ class StackLimitEvader /// 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( + static Block run( OptimiserStepContext& _context, - Block& _astRoot, Object const& _object ); }; diff --git a/libyul/optimiser/Suite.cpp b/libyul/optimiser/Suite.cpp index b8826bb8a339..cc0c1a7f3086 100644 --- a/libyul/optimiser/Suite.cpp +++ b/libyul/optimiser/Suite.cpp @@ -179,13 +179,15 @@ void OptimiserSuite::run( // We ignore the return value because we will get a much better error // message once we perform code generation. if (!usesOptimizedCodeGenerator) - StackCompressor::run( + { + _object.code = std::make_shared(std::move(astRoot)); + astRoot = std::get<1>(StackCompressor::run( _dialect, - astRoot, _object, _optimizeStackAllocation, stackCompressorMaxIterations - ); + )); + } // Run the user-supplied clean up sequence suite.runSequence(_optimisationCleanupSequence, astRoot); @@ -200,18 +202,24 @@ void OptimiserSuite::run( ConstantOptimiser{*evmDialect, *_meter}(astRoot); if (usesOptimizedCodeGenerator) { - StackCompressor::run( + _object.code = std::make_shared(std::move(astRoot)); + astRoot = std::get<1>(StackCompressor::run( _dialect, - astRoot, _object, _optimizeStackAllocation, stackCompressorMaxIterations - ); + )); if (evmDialect->providesObjectAccess()) - StackLimitEvader::run(suite.m_context, astRoot, _object); + { + _object.code = std::make_shared(std::move(astRoot)); + astRoot = StackLimitEvader::run(suite.m_context, _object); + } } else if (evmDialect->providesObjectAccess() && _optimizeStackAllocation) - StackLimitEvader::run(suite.m_context, astRoot, _object); + { + _object.code = std::make_shared(std::move(astRoot)); + astRoot = StackLimitEvader::run(suite.m_context, _object); + } } dispenser.reset(astRoot); diff --git a/test/libyul/YulOptimizerTestCommon.cpp b/test/libyul/YulOptimizerTestCommon.cpp index 357e5b657998..2190c101035e 100644 --- a/test/libyul/YulOptimizerTestCommon.cpp +++ b/test/libyul/YulOptimizerTestCommon.cpp @@ -400,7 +400,11 @@ YulOptimizerTestCommon::YulOptimizerTestCommon( FunctionHoister::run(*m_context, block); FunctionGrouper::run(*m_context, block); size_t maxIterations = 16; - StackCompressor::run(*m_dialect, block, *m_object, true, maxIterations); + { + Object object(*m_object); + object.code = std::make_shared(std::get(ASTCopier{}(block))); + block = std::get<1>(StackCompressor::run(*m_dialect, object, true, maxIterations)); + } BlockFlattener::run(*m_context, block); return block; }}, @@ -420,12 +424,14 @@ YulOptimizerTestCommon::YulOptimizerTestCommon( {"stackLimitEvader", [&]() { auto block = disambiguate(); updateContext(block); - StackLimitEvader::run(*m_context, block, CompilabilityChecker{ + Object object(*m_object); + object.code = std::make_shared(std::get(ASTCopier{}(block))); + auto const unreachables = CompilabilityChecker{ *m_dialect, - *m_object, - true, - &block - }.unreachableVariables); + object, + true + }.unreachableVariables; + StackLimitEvader::run(*m_context, block, unreachables); return block; }}, {"fakeStackLimitEvader", [&]() { diff --git a/test/tools/yulopti.cpp b/test/tools/yulopti.cpp index 1655b13d3863..ad32337bdd93 100644 --- a/test/tools/yulopti.cpp +++ b/test/tools/yulopti.cpp @@ -218,7 +218,8 @@ class YulOpti case ';': { Object obj; - StackCompressor::run(m_dialect, *m_astRoot, obj, true, 16); + obj.code = std::make_shared(std::get(ASTCopier{}(*m_astRoot))); + *m_astRoot = std::get<1>(StackCompressor::run(m_dialect, obj, true, 16)); break; } default: From d067964b29f25985fb71699bc6802e5e06470663 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Fri, 2 Aug 2024 14:00:00 +0200 Subject: [PATCH 0328/1022] Yul: introduce setCode method for yul::Object to properly clean up resources --- libsolidity/codegen/CompilerContext.cpp | 16 ++++++------- libsolidity/codegen/ContractCompiler.cpp | 4 ++-- libyul/AST.h | 2 +- libyul/AsmAnalysis.cpp | 2 +- libyul/CompilabilityChecker.cpp | 8 +++---- libyul/Object.cpp | 24 +++++++++++++++---- libyul/Object.h | 8 ++++++- libyul/ObjectParser.cpp | 6 ++--- libyul/YulStack.cpp | 18 +++++++------- libyul/backends/evm/EVMObjectCompiler.cpp | 10 ++++---- libyul/optimiser/Semantics.cpp | 2 +- libyul/optimiser/StackCompressor.cpp | 10 ++++---- libyul/optimiser/StackLimitEvader.cpp | 4 ++-- libyul/optimiser/Suite.cpp | 14 +++++------ test/libsolidity/MemoryGuardTest.cpp | 2 +- test/libyul/Common.cpp | 8 +++---- test/libyul/Common.h | 2 +- test/libyul/CompilabilityChecker.cpp | 5 ++-- test/libyul/ControlFlowGraphTest.cpp | 2 +- test/libyul/ControlFlowSideEffectsTest.cpp | 9 +++---- test/libyul/FunctionSideEffects.cpp | 7 +++--- test/libyul/KnowledgeBaseTest.cpp | 6 ++--- test/libyul/Metrics.cpp | 3 ++- test/libyul/StackLayoutGeneratorTest.cpp | 2 +- test/libyul/YulInterpreterTest.cpp | 2 +- test/libyul/YulInterpreterTest.h | 4 ++-- test/libyul/YulOptimizerTest.cpp | 2 +- test/libyul/YulOptimizerTestCommon.cpp | 22 ++++++++--------- .../tools/ossfuzz/StackReuseCodegenFuzzer.cpp | 2 +- test/tools/ossfuzz/YulEvmoneInterface.cpp | 2 +- test/tools/ossfuzz/strictasm_diff_ossfuzz.cpp | 6 ++--- test/tools/ossfuzz/yulProtoFuzzer.cpp | 2 +- test/tools/ossfuzz/yulProto_diff_ossfuzz.cpp | 4 ++-- test/tools/yulopti.cpp | 2 +- test/tools/yulrun.cpp | 6 ++--- tools/yulPhaser/Program.cpp | 2 +- 36 files changed, 128 insertions(+), 102 deletions(-) diff --git a/libsolidity/codegen/CompilerContext.cpp b/libsolidity/codegen/CompilerContext.cpp index aa6985503fdb..b1b76a97b8d6 100644 --- a/libsolidity/codegen/CompilerContext.cpp +++ b/libsolidity/codegen/CompilerContext.cpp @@ -475,14 +475,14 @@ void CompilerContext::appendInlineAssembly( ).analyze(parserResult->root()); if (!parserResult || !errorReporter.errors().empty() || !analyzerResult) reportError("Invalid assembly generated by code generator."); + std::shared_ptr toBeAssembledAST = parserResult; // Several optimizer steps cannot handle externally supplied stack variables, // so we essentially only optimize the ABI functions. if (_optimiserSettings.runYulOptimiser && _localVariables.empty()) { yul::Object obj; - obj.code = parserResult; - obj.analysisInfo = std::make_shared(analysisInfo); + obj.setCode(parserResult, std::make_shared(analysisInfo)); solAssert(!dialect.providesObjectAccess()); optimizeYul(obj, dialect, _optimiserSettings, externallyUsedIdentifiers); @@ -491,15 +491,15 @@ void CompilerContext::appendInlineAssembly( { // Store as generated sources, but first re-parse to update the source references. solAssert(m_generatedYulUtilityCode.empty(), ""); - m_generatedYulUtilityCode = yul::AsmPrinter(yul::AsmPrinter::TypePrinting::OmitDefault, dialect)(obj.code->root()); - std::string code = yul::AsmPrinter{yul::AsmPrinter::TypePrinting::OmitDefault, dialect}(obj.code->root()); + m_generatedYulUtilityCode = yul::AsmPrinter(yul::AsmPrinter::TypePrinting::OmitDefault, dialect)(obj.code()->root()); + std::string code = yul::AsmPrinter{yul::AsmPrinter::TypePrinting::OmitDefault, dialect}(obj.code()->root()); langutil::CharStream charStream(m_generatedYulUtilityCode, _sourceName); - obj.code = yul::Parser(errorReporter, dialect).parse(charStream); - *obj.analysisInfo = yul::AsmAnalyzer::analyzeStrictAssertCorrect(dialect, obj); + obj.setCode(yul::Parser(errorReporter, dialect).parse(charStream)); + obj.analysisInfo = std::make_shared(yul::AsmAnalyzer::analyzeStrictAssertCorrect(dialect, obj)); } analysisInfo = std::move(*obj.analysisInfo); - parserResult = std::move(obj.code); + toBeAssembledAST = obj.code(); #ifdef SOL_OUTPUT_ASM cout << "After optimizer:" << endl; @@ -518,7 +518,7 @@ void CompilerContext::appendInlineAssembly( solAssert(errorReporter.errors().empty(), "Failed to analyze inline assembly block."); yul::CodeGenerator::assemble( - parserResult->root(), + toBeAssembledAST->root(), analysisInfo, *m_asm, m_evmVersion, diff --git a/libsolidity/codegen/ContractCompiler.cpp b/libsolidity/codegen/ContractCompiler.cpp index 21899f72a607..9e0593cdfb27 100644 --- a/libsolidity/codegen/ContractCompiler.cpp +++ b/libsolidity/codegen/ContractCompiler.cpp @@ -944,12 +944,12 @@ bool ContractCompiler::visit(InlineAssembly const& _inlineAssembly) solAssert(dialect, ""); // Create a modifiable copy of the code and analysis - object.code = std::make_shared(yul::ASTCopier().translate(code->root())); + object.setCode(std::make_shared(yul::ASTCopier().translate(code->root()))); object.analysisInfo = std::make_shared(yul::AsmAnalyzer::analyzeStrictAssertCorrect(*dialect, object)); m_context.optimizeYul(object, *dialect, m_optimiserSettings); - code = object.code.get(); + code = object.code().get(); analysisInfo = object.analysisInfo.get(); } diff --git a/libyul/AST.h b/libyul/AST.h index ca4846907e40..6b9682580c0a 100644 --- a/libyul/AST.h +++ b/libyul/AST.h @@ -107,7 +107,7 @@ class AST public: explicit AST(Block _root): m_root(std::move(_root)) {} - Block const& root() const { return m_root; } + [[nodiscard]] Block const& root() const { return m_root; } private: Block m_root; }; diff --git a/libyul/AsmAnalysis.cpp b/libyul/AsmAnalysis.cpp index dae945fe8796..09be5974246b 100644 --- a/libyul/AsmAnalysis.cpp +++ b/libyul/AsmAnalysis.cpp @@ -86,7 +86,7 @@ bool AsmAnalyzer::analyze(Block const& _block) AsmAnalysisInfo AsmAnalyzer::analyzeStrictAssertCorrect(Dialect const& _dialect, Object const& _object) { - return analyzeStrictAssertCorrect(_dialect, _object.code->root(), _object.qualifiedDataNames()); + return analyzeStrictAssertCorrect(_dialect, _object.code()->root(), _object.qualifiedDataNames()); } AsmAnalysisInfo AsmAnalyzer::analyzeStrictAssertCorrect( diff --git a/libyul/CompilabilityChecker.cpp b/libyul/CompilabilityChecker.cpp index af7532c75d07..8ece236bf425 100644 --- a/libyul/CompilabilityChecker.cpp +++ b/libyul/CompilabilityChecker.cpp @@ -36,14 +36,14 @@ CompilabilityChecker::CompilabilityChecker( bool _optimizeStackAllocation ) { - yulAssert(_object.code); + yulAssert(_object.hasCode()); if (auto const* evmDialect = dynamic_cast(&_dialect)) { NoOutputEVMDialect noOutputDialect(*evmDialect); yul::AsmAnalysisInfo analysisInfo = yul::AsmAnalyzer::analyzeStrictAssertCorrect( noOutputDialect, - _object.code->root(), + _object.code()->root(), _object.qualifiedDataNames() ); @@ -57,12 +57,12 @@ CompilabilityChecker::CompilabilityChecker( CodeTransform transform( assembly, analysisInfo, - _object.code->root(), + _object.code()->root(), noOutputDialect, builtinContext, _optimizeStackAllocation ); - transform(_object.code->root()); + transform(_object.code()->root()); for (StackTooDeepError const& error: transform.stackErrors()) { diff --git a/libyul/Object.cpp b/libyul/Object.cpp index 98649b29bec6..afd237b5b7f9 100644 --- a/libyul/Object.cpp +++ b/libyul/Object.cpp @@ -50,7 +50,7 @@ std::string Object::toString( CharStreamProvider const* _soliditySourceProvider ) const { - yulAssert(code, "No code"); + yulAssert(hasCode(), "No code"); yulAssert(debugData, "No debug data"); std::string useSrcComment; @@ -69,7 +69,7 @@ std::string Object::toString( debugData->sourceNames, _debugInfoSelection, _soliditySourceProvider - )(code->root()); + )(code()->root()); for (auto const& obj: subObjects) inner += "\n" + obj->toString(_dialect, _printingMode, _debugInfoSelection, _soliditySourceProvider); @@ -87,11 +87,11 @@ Json Data::toJson() const Json Object::toJson() const { - yulAssert(code, "No code"); + yulAssert(hasCode(), "No code"); Json codeJson; codeJson["nodeType"] = "YulCode"; - codeJson["block"] = AsmJsonConverter(0 /* sourceIndex */)(code->root()); + codeJson["block"] = AsmJsonConverter(0 /* sourceIndex */)(code()->root()); Json subObjectsJson = Json::array(); for (std::shared_ptr const& subObject: subObjects) @@ -161,6 +161,22 @@ std::vector Object::pathToSubObject(std::string_view _qualifiedName) con return path; } +std::shared_ptr Object::code() const +{ + return m_code; +} + +bool Object::hasCode() const { return code() != nullptr; } + +void Object::setCode(std::shared_ptr const& _ast, std::shared_ptr _analysisInfo) +{ + if (_ast.get() != m_code.get()) + { + m_code = _ast; + analysisInfo = std::move(_analysisInfo); + } +} + void Object::collectSourceIndices(std::map& _indices) const { if (debugData && debugData->sourceNames.has_value()) diff --git a/libyul/Object.h b/libyul/Object.h index cab3bc701bb2..41ca74e9f321 100644 --- a/libyul/Object.h +++ b/libyul/Object.h @@ -119,10 +119,13 @@ struct Object: public ObjectNode /// The path must not lead to a @a Data object (will throw in that case). std::vector pathToSubObject(std::string_view _qualifiedName) const; + std::shared_ptr code() const; + void setCode(std::shared_ptr const& _ast, std::shared_ptr = nullptr); + bool hasCode() const; + /// sub id for object if it is subobject of another object, max value if it is not subobject size_t subId = std::numeric_limits::max(); - std::shared_ptr code; std::vector> subObjects; std::map> subIndexByName; std::shared_ptr analysisInfo; @@ -139,6 +142,9 @@ struct Object: public ObjectNode /// @returns the name of the special metadata data object. static std::string metadataName() { return ".metadata"; } + +private: + std::shared_ptr m_code; }; } diff --git a/libyul/ObjectParser.cpp b/libyul/ObjectParser.cpp index 6813e5059395..123dedcb483d 100644 --- a/libyul/ObjectParser.cpp +++ b/libyul/ObjectParser.cpp @@ -53,8 +53,8 @@ std::shared_ptr ObjectParser::parse(std::shared_ptr const& _sca object->name = "object"; auto sourceNameMapping = tryParseSourceNameMapping(); object->debugData = std::make_shared(ObjectDebugData{sourceNameMapping}); - object->code = parseBlock(sourceNameMapping); - if (!object->code) + object->setCode(parseBlock(sourceNameMapping)); + if (!object->hasCode()) return nullptr; } else @@ -87,7 +87,7 @@ std::shared_ptr ObjectParser::parseObject(Object* _containingObject) expectToken(Token::LBrace); - ret->code = parseCode(std::move(sourceNameMapping)); + ret->setCode(parseCode(std::move(sourceNameMapping))); while (currentToken() != Token::RBrace) { diff --git a/libyul/YulStack.cpp b/libyul/YulStack.cpp index 426551152a65..dbe30bb136d5 100644 --- a/libyul/YulStack.cpp +++ b/libyul/YulStack.cpp @@ -97,7 +97,7 @@ bool YulStack::parseAndAnalyze(std::string const& _sourceName, std::string const yulAssert(m_stackState == Parsed); yulAssert(m_parserResult, ""); - yulAssert(m_parserResult->code, ""); + yulAssert(m_parserResult->hasCode()); return analyzeParsed(); } @@ -135,7 +135,7 @@ bool YulStack::analyzeParsed() bool YulStack::analyzeParsed(Object& _object) { yulAssert(m_stackState >= Parsed); - yulAssert(_object.code, ""); + yulAssert(_object.hasCode()); _object.analysisInfo = std::make_shared(); AsmAnalyzer analyzer( @@ -149,7 +149,7 @@ bool YulStack::analyzeParsed(Object& _object) bool success = false; try { - success = analyzer.analyze(_object.code->root()); + success = analyzer.analyze(_object.code()->root()); for (auto& subNode: _object.subObjects) if (auto subObject = dynamic_cast(subNode.get())) if (!analyzeParsed(*subObject)) @@ -189,7 +189,7 @@ void YulStack::compileEVM(AbstractAssembly& _assembly, bool _optimize) const void YulStack::optimize(Object& _object, bool _isCreation) { - yulAssert(_object.code, ""); + yulAssert(_object.hasCode(), ""); yulAssert(_object.analysisInfo, ""); for (auto& subNode: _object.subObjects) if (auto subObject = dynamic_cast(subNode.get())) @@ -245,7 +245,7 @@ MachineAssemblyObject YulStack::assemble(Machine _machine) { yulAssert(m_stackState >= AnalysisSuccessful); yulAssert(m_parserResult, ""); - yulAssert(m_parserResult->code, ""); + yulAssert(m_parserResult->hasCode(), ""); yulAssert(m_parserResult->analysisInfo, ""); switch (_machine) @@ -302,7 +302,7 @@ YulStack::assembleEVMWithDeployed(std::optional _deployName) { yulAssert(m_stackState >= AnalysisSuccessful); yulAssert(m_parserResult, ""); - yulAssert(m_parserResult->code, ""); + yulAssert(m_parserResult->hasCode(), ""); yulAssert(m_parserResult->analysisInfo, ""); evmasm::Assembly assembly(m_evmVersion, true, {}); @@ -359,7 +359,7 @@ std::string YulStack::print( { yulAssert(m_stackState >= Parsed); yulAssert(m_parserResult, ""); - yulAssert(m_parserResult->code, ""); + yulAssert(m_parserResult->hasCode(), ""); return m_parserResult->toString( languageToDialect(m_language, m_evmVersion), AsmPrinter::TypePrinting::OmitDefault, @@ -372,7 +372,7 @@ Json YulStack::astJson() const { yulAssert(m_stackState >= Parsed); yulAssert(m_parserResult, ""); - yulAssert(m_parserResult->code, ""); + yulAssert(m_parserResult->hasCode(), ""); return m_parserResult->toJson(); } @@ -380,7 +380,7 @@ std::shared_ptr YulStack::parserResult() const { yulAssert(m_stackState >= AnalysisSuccessful, "Analysis was not successful."); yulAssert(m_parserResult, ""); - yulAssert(m_parserResult->code, ""); + yulAssert(m_parserResult->hasCode(), ""); return m_parserResult; } diff --git a/libyul/backends/evm/EVMObjectCompiler.cpp b/libyul/backends/evm/EVMObjectCompiler.cpp index c77bf4e37c1c..ca9f90dfae34 100644 --- a/libyul/backends/evm/EVMObjectCompiler.cpp +++ b/libyul/backends/evm/EVMObjectCompiler.cpp @@ -72,7 +72,7 @@ void EVMObjectCompiler::run(Object& _object, bool _optimize) } yulAssert(_object.analysisInfo, "No analysis info."); - yulAssert(_object.code, "No code."); + yulAssert(_object.hasCode(), "No code."); if (m_eofVersion.has_value()) yulAssert( _optimize && (m_dialect.evmVersion() == langutil::EVMVersion()), @@ -83,7 +83,7 @@ void EVMObjectCompiler::run(Object& _object, bool _optimize) auto stackErrors = OptimizedEVMCodeTransform::run( m_assembly, *_object.analysisInfo, - _object.code->root(), + _object.code()->root(), m_dialect, context, OptimizedEVMCodeTransform::UseNamedLabels::ForFirstFunctionOfEachName @@ -91,7 +91,7 @@ void EVMObjectCompiler::run(Object& _object, bool _optimize) if (!stackErrors.empty()) { std::vector memoryGuardCalls = findFunctionCalls( - _object.code->root(), + _object.code()->root(), "memoryguard"_yulname ); auto stackError = stackErrors.front(); @@ -113,14 +113,14 @@ void EVMObjectCompiler::run(Object& _object, bool _optimize) CodeTransform transform{ m_assembly, *_object.analysisInfo, - _object.code->root(), + _object.code()->root(), m_dialect, context, _optimize, {}, CodeTransform::UseNamedLabels::ForFirstFunctionOfEachName }; - transform(_object.code->root()); + transform(_object.code()->root()); if (!transform.stackErrors().empty()) BOOST_THROW_EXCEPTION(transform.stackErrors().front()); } diff --git a/libyul/optimiser/Semantics.cpp b/libyul/optimiser/Semantics.cpp index 88f4f7c45b5e..d945dbcac7f5 100644 --- a/libyul/optimiser/Semantics.cpp +++ b/libyul/optimiser/Semantics.cpp @@ -95,7 +95,7 @@ bool MSizeFinder::containsMSize(Dialect const& _dialect, Block const& _ast) bool MSizeFinder::containsMSize(Dialect const& _dialect, Object const& _object) { - if (containsMSize(_dialect, _object.code->root())) + if (containsMSize(_dialect, _object.code()->root())) return true; for (std::shared_ptr const& node: _object.subObjects) diff --git a/libyul/optimiser/StackCompressor.cpp b/libyul/optimiser/StackCompressor.cpp index bdc20a5a8c71..2c2ef4272904 100644 --- a/libyul/optimiser/StackCompressor.cpp +++ b/libyul/optimiser/StackCompressor.cpp @@ -242,9 +242,9 @@ std::tuple StackCompressor::run( bool _optimizeStackAllocation, size_t _maxIterations) { - yulAssert(_object.code); + yulAssert(_object.hasCode()); yulAssert( - !_object.code->root().statements.empty() && std::holds_alternative(_object.code->root().statements.at(0)), + !_object.code()->root().statements.empty() && std::holds_alternative(_object.code()->root().statements.at(0)), "Need to run the function grouper before the stack compressor." ); bool usesOptimizedCodeGenerator = false; @@ -253,8 +253,8 @@ std::tuple StackCompressor::run( _optimizeStackAllocation && evmDialect->evmVersion().canOverchargeGasForCall() && evmDialect->providesObjectAccess(); - bool allowMSizeOptimization = !MSizeFinder::containsMSize(_dialect, _object.code->root()); - Block astRoot = std::get(ASTCopier{}(_object.code->root())); + bool allowMSizeOptimization = !MSizeFinder::containsMSize(_dialect, _object.code()->root()); + Block astRoot = std::get(ASTCopier{}(_object.code()->root())); if (usesOptimizedCodeGenerator) { yul::AsmAnalysisInfo analysisInfo = yul::AsmAnalyzer::analyzeStrictAssertCorrect(_dialect, astRoot, _object.qualifiedDataNames()); @@ -271,7 +271,7 @@ std::tuple StackCompressor::run( for (size_t iterations = 0; iterations < _maxIterations; iterations++) { Object object(_object); - object.code = std::make_shared(std::get(ASTCopier{}(astRoot))); + object.setCode(std::make_shared(std::get(ASTCopier{}(astRoot)))); std::map stackSurplus = CompilabilityChecker(_dialect, object, _optimizeStackAllocation).stackDeficit; if (stackSurplus.empty()) return std::make_tuple(true, std::move(astRoot)); diff --git a/libyul/optimiser/StackLimitEvader.cpp b/libyul/optimiser/StackLimitEvader.cpp index d613ae9937df..6e6da63e603b 100644 --- a/libyul/optimiser/StackLimitEvader.cpp +++ b/libyul/optimiser/StackLimitEvader.cpp @@ -123,13 +123,13 @@ Block StackLimitEvader::run( Object const& _object ) { - yulAssert(_object.code); + yulAssert(_object.hasCode()); auto const* evmDialect = dynamic_cast(&_context.dialect); yulAssert( evmDialect && evmDialect->providesObjectAccess(), "StackLimitEvader can only be run on objects using the EVMDialect with object access." ); - auto astRoot = std::get(ASTCopier{}(_object.code->root())); + auto astRoot = std::get(ASTCopier{}(_object.code()->root())); if (evmDialect && evmDialect->evmVersion().canOverchargeGasForCall()) { yul::AsmAnalysisInfo analysisInfo = yul::AsmAnalyzer::analyzeStrictAssertCorrect(*evmDialect, astRoot, _object.qualifiedDataNames()); diff --git a/libyul/optimiser/Suite.cpp b/libyul/optimiser/Suite.cpp index cc0c1a7f3086..a06f48a7f236 100644 --- a/libyul/optimiser/Suite.cpp +++ b/libyul/optimiser/Suite.cpp @@ -157,7 +157,7 @@ void OptimiserSuite::run( _dialect, *_object.analysisInfo, reservedIdentifiers - )(_object.code->root())); + )(_object.code()->root())); NameDispenser dispenser{_dialect, astRoot, reservedIdentifiers}; OptimiserStepContext context{_dialect, dispenser, reservedIdentifiers, _expectedExecutionsPerDeployment}; @@ -180,7 +180,7 @@ void OptimiserSuite::run( // message once we perform code generation. if (!usesOptimizedCodeGenerator) { - _object.code = std::make_shared(std::move(astRoot)); + _object.setCode(std::make_shared(std::move(astRoot))); astRoot = std::get<1>(StackCompressor::run( _dialect, _object, @@ -202,7 +202,7 @@ void OptimiserSuite::run( ConstantOptimiser{*evmDialect, *_meter}(astRoot); if (usesOptimizedCodeGenerator) { - _object.code = std::make_shared(std::move(astRoot)); + _object.setCode(std::make_shared(std::move(astRoot))); astRoot = std::get<1>(StackCompressor::run( _dialect, _object, @@ -211,13 +211,13 @@ void OptimiserSuite::run( )); if (evmDialect->providesObjectAccess()) { - _object.code = std::make_shared(std::move(astRoot)); + _object.setCode(std::make_shared(std::move(astRoot))); astRoot = StackLimitEvader::run(suite.m_context, _object); } } else if (evmDialect->providesObjectAccess() && _optimizeStackAllocation) { - _object.code = std::make_shared(std::move(astRoot)); + _object.setCode(std::make_shared(std::move(astRoot))); astRoot = StackLimitEvader::run(suite.m_context, _object); } } @@ -230,8 +230,8 @@ void OptimiserSuite::run( outputPerformanceMetrics(suite.m_durationPerStepInMicroseconds); #endif - _object.code = std::make_shared(std::move(astRoot)); - *_object.analysisInfo = AsmAnalyzer::analyzeStrictAssertCorrect(_dialect, _object); + _object.setCode(std::make_shared(std::move(astRoot))); + _object.analysisInfo = std::make_shared(AsmAnalyzer::analyzeStrictAssertCorrect(_dialect, _object)); } namespace diff --git a/test/libsolidity/MemoryGuardTest.cpp b/test/libsolidity/MemoryGuardTest.cpp index c5579d84a166..b2e0b75d367a 100644 --- a/test/libsolidity/MemoryGuardTest.cpp +++ b/test/libsolidity/MemoryGuardTest.cpp @@ -75,7 +75,7 @@ TestCase::TestResult MemoryGuardTest::run(std::ostream& _stream, std::string con auto handleObject = [&](std::string const& _kind, Object const& _object) { m_obtainedResult += contractName + "(" + _kind + ") " + (findFunctionCalls( - _object.code->root(), + _object.code()->root(), "memoryguard"_yulname ).empty() ? "false" : "true") + "\n"; }; diff --git a/test/libyul/Common.cpp b/test/libyul/Common.cpp index 26f5e0684602..d147e03d0071 100644 --- a/test/libyul/Common.cpp +++ b/test/libyul/Common.cpp @@ -50,7 +50,7 @@ Dialect const& defaultDialect(bool _yul) } } -std::pair, std::shared_ptr> yul::test::parse(std::string const& _source, bool _yul) +std::pair, std::shared_ptr> yul::test::parse(std::string const& _source, bool _yul) { YulStack stack( solidity::test::CommonOptions::get().evmVersion(), @@ -63,7 +63,7 @@ std::pair, std::shared_ptr> yul::test ); if (!stack.parseAndAnalyze("", _source) || !stack.errors().empty()) BOOST_FAIL("Invalid source."); - return make_pair(stack.parserResult()->code, stack.parserResult()->analysisInfo); + return std::make_pair(stack.parserResult()->code(), stack.parserResult()->analysisInfo); } std::pair, std::shared_ptr> yul::test::parse( @@ -78,12 +78,12 @@ std::pair, std::shared_ptr> yul::t std::shared_ptr parserResult = yul::ObjectParser(errorReporter, _dialect).parse(scanner, false); if (!parserResult) return {}; - if (!parserResult->code || errorReporter.hasErrors()) + if (!parserResult->hasCode() || errorReporter.hasErrors()) return {}; std::shared_ptr analysisInfo = std::make_shared(); AsmAnalyzer analyzer(*analysisInfo, errorReporter, _dialect, {}, parserResult->qualifiedDataNames()); // TODO this should be done recursively. - if (!analyzer.analyze(parserResult->code->root()) || errorReporter.hasErrors()) + if (!analyzer.analyze(parserResult->code()->root()) || errorReporter.hasErrors()) return {}; return {std::move(parserResult), std::move(analysisInfo)}; } diff --git a/test/libyul/Common.h b/test/libyul/Common.h index 4a9696cd9d18..14d73d77e18c 100644 --- a/test/libyul/Common.h +++ b/test/libyul/Common.h @@ -45,7 +45,7 @@ class AST; namespace solidity::yul::test { -std::pair, std::shared_ptr> +std::pair, std::shared_ptr> parse(std::string const& _source, bool _yul = true); std::pair, std::shared_ptr> diff --git a/test/libyul/CompilabilityChecker.cpp b/test/libyul/CompilabilityChecker.cpp index 27310cd898c2..5b64b5e5d3cc 100644 --- a/test/libyul/CompilabilityChecker.cpp +++ b/test/libyul/CompilabilityChecker.cpp @@ -35,8 +35,9 @@ namespace std::string check(std::string const& _input) { Object obj; - std::tie(obj.code, obj.analysisInfo) = yul::test::parse(_input, false); - BOOST_REQUIRE(obj.code); + auto parsingResult = yul::test::parse(_input, false); + obj.setCode(parsingResult.first, parsingResult.second); + BOOST_REQUIRE(obj.hasCode()); auto functions = CompilabilityChecker(EVMDialect::strictAssemblyForEVM(solidity::test::CommonOptions::get().evmVersion()), obj, true).stackDeficit; std::string out; for (auto const& function: functions) diff --git a/test/libyul/ControlFlowGraphTest.cpp b/test/libyul/ControlFlowGraphTest.cpp index 8e08bf488990..5c9bba8d41e5 100644 --- a/test/libyul/ControlFlowGraphTest.cpp +++ b/test/libyul/ControlFlowGraphTest.cpp @@ -206,7 +206,7 @@ TestCase::TestResult ControlFlowGraphTest::run(std::ostream& _stream, std::strin std::ostringstream output; - std::unique_ptr cfg = ControlFlowGraphBuilder::build(*analysisInfo, *m_dialect, object->code->root()); + std::unique_ptr cfg = ControlFlowGraphBuilder::build(*analysisInfo, *m_dialect, object->code()->root()); output << "digraph CFG {\nnodesep=0.7;\nnode[shape=box];\n\n"; ControlFlowGraphPrinter printer{output}; diff --git a/test/libyul/ControlFlowSideEffectsTest.cpp b/test/libyul/ControlFlowSideEffectsTest.cpp index 054c70547118..20df176a393c 100644 --- a/test/libyul/ControlFlowSideEffectsTest.cpp +++ b/test/libyul/ControlFlowSideEffectsTest.cpp @@ -57,16 +57,17 @@ ControlFlowSideEffectsTest::ControlFlowSideEffectsTest(std::string const& _filen TestCase::TestResult ControlFlowSideEffectsTest::run(std::ostream& _stream, std::string const& _linePrefix, bool _formatted) { Object obj; - std::tie(obj.code, obj.analysisInfo) = yul::test::parse(m_source, false); - if (!obj.code) + auto parsingResult = yul::test::parse(m_source, false); + obj.setCode(parsingResult.first, parsingResult.second); + if (!obj.hasCode()) BOOST_THROW_EXCEPTION(std::runtime_error("Parsing input failed.")); ControlFlowSideEffectsCollector sideEffects( EVMDialect::strictAssemblyForEVMObjects(langutil::EVMVersion()), - obj.code->root() + obj.code()->root() ); m_obtainedResult.clear(); - forEach(obj.code->root(), [&](FunctionDefinition const& _fun) { + forEach(obj.code()->root(), [&](FunctionDefinition const& _fun) { std::string effectStr = toString(sideEffects.functionSideEffects().at(&_fun)); m_obtainedResult += _fun.name.str() + (effectStr.empty() ? ":" : ": " + effectStr) + "\n"; }); diff --git a/test/libyul/FunctionSideEffects.cpp b/test/libyul/FunctionSideEffects.cpp index 3220a8c6f983..a39024d278ef 100644 --- a/test/libyul/FunctionSideEffects.cpp +++ b/test/libyul/FunctionSideEffects.cpp @@ -83,13 +83,14 @@ FunctionSideEffects::FunctionSideEffects(std::string const& _filename): TestCase::TestResult FunctionSideEffects::run(std::ostream& _stream, std::string const& _linePrefix, bool _formatted) { Object obj; - std::tie(obj.code, obj.analysisInfo) = yul::test::parse(m_source, false); - if (!obj.code) + auto parsingResult = yul::test::parse(m_source, false); + obj.setCode(parsingResult.first, parsingResult.second); + if (!obj.hasCode()) BOOST_THROW_EXCEPTION(std::runtime_error("Parsing input failed.")); std::map functionSideEffects = SideEffectsPropagator::sideEffects( EVMDialect::strictAssemblyForEVMObjects(langutil::EVMVersion()), - CallGraphGenerator::callGraph(obj.code->root()) + CallGraphGenerator::callGraph(obj.code()->root()) ); std::map functionSideEffectsStr; diff --git a/test/libyul/KnowledgeBaseTest.cpp b/test/libyul/KnowledgeBaseTest.cpp index a149381ca0bc..0293f8ee4472 100644 --- a/test/libyul/KnowledgeBaseTest.cpp +++ b/test/libyul/KnowledgeBaseTest.cpp @@ -47,9 +47,9 @@ class KnowledgeBaseTest ErrorList errorList; std::shared_ptr analysisInfo; std::tie(m_object, analysisInfo) = yul::test::parse(_source, m_dialect, errorList); - BOOST_REQUIRE(m_object && errorList.empty() && m_object->code); + BOOST_REQUIRE(m_object && errorList.empty() && m_object->hasCode()); - auto astRoot = std::get(yul::ASTCopier{}(m_object->code->root())); + auto astRoot = std::get(yul::ASTCopier{}(m_object->code()->root())); NameDispenser dispenser(m_dialect, astRoot); std::set reserved; OptimiserStepContext context{m_dialect, dispenser, reserved, 0}; @@ -59,7 +59,7 @@ class KnowledgeBaseTest for (auto const& [name, expression]: m_ssaValues.values()) m_values[name].value = expression; - m_object->code = std::make_shared(std::move(astRoot)); + m_object->setCode(std::make_shared(std::move(astRoot))); return KnowledgeBase([this](YulName _var) { return util::valueOrNullptr(m_values, _var); }); } diff --git a/test/libyul/Metrics.cpp b/test/libyul/Metrics.cpp index ce65cf2c8574..bf09a1c2beec 100644 --- a/test/libyul/Metrics.cpp +++ b/test/libyul/Metrics.cpp @@ -24,6 +24,7 @@ #include #include +#include #include @@ -37,7 +38,7 @@ namespace size_t codeSize(std::string const& _source, CodeWeights const _weights = {}) { - std::shared_ptr ast = parse(_source, false).first; + std::shared_ptr ast = parse(_source, false).first; BOOST_REQUIRE(ast); return CodeSize::codeSize(ast->root(), _weights); } diff --git a/test/libyul/StackLayoutGeneratorTest.cpp b/test/libyul/StackLayoutGeneratorTest.cpp index 2abac60e5c40..9c16eaefc110 100644 --- a/test/libyul/StackLayoutGeneratorTest.cpp +++ b/test/libyul/StackLayoutGeneratorTest.cpp @@ -224,7 +224,7 @@ TestCase::TestResult StackLayoutGeneratorTest::run(std::ostream& _stream, std::s std::ostringstream output; - std::unique_ptr cfg = ControlFlowGraphBuilder::build(*analysisInfo, *m_dialect, object->code->root()); + std::unique_ptr cfg = ControlFlowGraphBuilder::build(*analysisInfo, *m_dialect, object->code()->root()); StackLayout stackLayout = StackLayoutGenerator::run(*cfg); output << "digraph CFG {\nnodesep=0.7;\nnode[shape=box];\n\n"; diff --git a/test/libyul/YulInterpreterTest.cpp b/test/libyul/YulInterpreterTest.cpp index d987c519c3e7..9d4ccd81ba49 100644 --- a/test/libyul/YulInterpreterTest.cpp +++ b/test/libyul/YulInterpreterTest.cpp @@ -75,7 +75,7 @@ bool YulInterpreterTest::parse(std::ostream& _stream, std::string const& _linePr ); if (stack.parseAndAnalyze("", m_source)) { - m_ast = stack.parserResult()->code; + m_ast = stack.parserResult()->code(); m_analysisInfo = stack.parserResult()->analysisInfo; return true; } diff --git a/test/libyul/YulInterpreterTest.h b/test/libyul/YulInterpreterTest.h index f5368670240d..d591591332ce 100644 --- a/test/libyul/YulInterpreterTest.h +++ b/test/libyul/YulInterpreterTest.h @@ -45,8 +45,8 @@ class YulInterpreterTest: public solidity::frontend::test::EVMVersionRestrictedT bool parse(std::ostream& _stream, std::string const& _linePrefix, bool const _formatted); std::string interpret(); - std::shared_ptr m_ast; - std::shared_ptr m_analysisInfo; + std::shared_ptr m_ast; + std::shared_ptr m_analysisInfo; bool m_simulateExternalCallsToSelf = false; }; diff --git a/test/libyul/YulOptimizerTest.cpp b/test/libyul/YulOptimizerTest.cpp index df28515c37cb..048eb7145dc0 100644 --- a/test/libyul/YulOptimizerTest.cpp +++ b/test/libyul/YulOptimizerTest.cpp @@ -81,7 +81,7 @@ TestCase::TestResult YulOptimizerTest::run(std::ostream& _stream, std::string co auto optimizedObject = tester.optimizedObject(); std::string printedOptimizedObject; if (optimizedObject->subObjects.empty()) - printedOptimizedObject = AsmPrinter{AsmPrinter::TypePrinting::OmitDefault, *m_dialect}(optimizedObject->code->root()); + printedOptimizedObject = AsmPrinter{AsmPrinter::TypePrinting::OmitDefault, *m_dialect}(optimizedObject->code()->root()); else printedOptimizedObject = optimizedObject->toString(*m_dialect); diff --git a/test/libyul/YulOptimizerTestCommon.cpp b/test/libyul/YulOptimizerTestCommon.cpp index 2190c101035e..2898086e8aa5 100644 --- a/test/libyul/YulOptimizerTestCommon.cpp +++ b/test/libyul/YulOptimizerTestCommon.cpp @@ -98,14 +98,14 @@ YulOptimizerTestCommon::YulOptimizerTestCommon( return block; }}, {"constantOptimiser", [&]() { - auto block = std::get(ASTCopier{}(m_object->code->root())); + auto block = std::get(ASTCopier{}(m_object->code()->root())); updateContext(block); GasMeter meter(dynamic_cast(*m_dialect), false, 200); ConstantOptimiser{dynamic_cast(*m_dialect), meter}(block); return block; }}, {"varDeclInitializer", [&]() { - auto block = std::get(ASTCopier{}(m_object->code->root())); + auto block = std::get(ASTCopier{}(m_object->code()->root())); updateContext(block); VarDeclInitializer::run(*m_context, block); return block; @@ -151,7 +151,7 @@ YulOptimizerTestCommon::YulOptimizerTestCommon( return block; }}, {"expressionSplitter", [&]() { - auto block = std::get(ASTCopier{}(m_object->code->root())); + auto block = std::get(ASTCopier{}(m_object->code()->root())); updateContext(block); ExpressionSplitter::run(*m_context, block); return block; @@ -401,8 +401,8 @@ YulOptimizerTestCommon::YulOptimizerTestCommon( FunctionGrouper::run(*m_context, block); size_t maxIterations = 16; { - Object object(*m_object); - object.code = std::make_shared(std::get(ASTCopier{}(block))); + Object object; // (*m_object) ?? + object.setCode(std::make_shared(std::get(ASTCopier{}(block)))); block = std::get<1>(StackCompressor::run(*m_dialect, object, true, maxIterations)); } BlockFlattener::run(*m_context, block); @@ -419,13 +419,13 @@ YulOptimizerTestCommon::YulOptimizerTestCommon( frontend::OptimiserSettings::DefaultYulOptimiserCleanupSteps, frontend::OptimiserSettings::standard().expectedExecutionsPerDeployment ); - return std::get(ASTCopier{}(m_optimizedObject->code->root())); + return std::get(ASTCopier{}(m_optimizedObject->code()->root())); }}, {"stackLimitEvader", [&]() { auto block = disambiguate(); updateContext(block); - Object object(*m_object); - object.code = std::make_shared(std::get(ASTCopier{}(block))); + Object object; // (*m_object); + object.setCode(std::make_shared(std::get(ASTCopier{}(block)))); auto const unreachables = CompilabilityChecker{ *m_dialect, object, @@ -492,7 +492,7 @@ bool YulOptimizerTestCommon::runStep() if (m_namedSteps.count(m_optimizerStep)) { auto block = m_namedSteps[m_optimizerStep](); - m_optimizedObject->code = std::make_shared(std::move(block)); + m_optimizedObject->setCode(std::make_shared(std::move(block))); } else return false; @@ -531,12 +531,12 @@ std::string YulOptimizerTestCommon::randomOptimiserStep(unsigned _seed) Block const* YulOptimizerTestCommon::run() { - return runStep() ? &m_optimizedObject->code->root() : nullptr; + return runStep() ? &m_optimizedObject->code()->root() : nullptr; } Block YulOptimizerTestCommon::disambiguate() { - auto block = std::get(Disambiguator(*m_dialect, *m_analysisInfo)(m_object->code->root())); + auto block = std::get(Disambiguator(*m_dialect, *m_analysisInfo)(m_object->code()->root())); m_analysisInfo.reset(); return block; } diff --git a/test/tools/ossfuzz/StackReuseCodegenFuzzer.cpp b/test/tools/ossfuzz/StackReuseCodegenFuzzer.cpp index 940fc7374ee9..a064fcdc80ed 100644 --- a/test/tools/ossfuzz/StackReuseCodegenFuzzer.cpp +++ b/test/tools/ossfuzz/StackReuseCodegenFuzzer.cpp @@ -54,7 +54,7 @@ namespace /// @returns true if there are recursive functions, false otherwise. bool recursiveFunctionExists(Dialect const& _dialect, yul::Object& _object) { - auto recursiveFunctions = CallGraphGenerator::callGraph(_object.code->root()).recursiveFunctions(); + auto recursiveFunctions = CallGraphGenerator::callGraph(_object.code()->root()).recursiveFunctions(); for(auto&& [function, variables]: CompilabilityChecker{ _dialect, _object, diff --git a/test/tools/ossfuzz/YulEvmoneInterface.cpp b/test/tools/ossfuzz/YulEvmoneInterface.cpp index b89245443049..74da5a1f0266 100644 --- a/test/tools/ossfuzz/YulEvmoneInterface.cpp +++ b/test/tools/ossfuzz/YulEvmoneInterface.cpp @@ -27,7 +27,7 @@ bytes YulAssembler::assemble() { if ( !m_stack.parseAndAnalyze("source", m_yulProgram) || - !m_stack.parserResult()->code || + !m_stack.parserResult()->code() || !m_stack.parserResult()->analysisInfo || langutil::Error::containsErrors(m_stack.errors()) ) diff --git a/test/tools/ossfuzz/strictasm_diff_ossfuzz.cpp b/test/tools/ossfuzz/strictasm_diff_ossfuzz.cpp index 40201bd15fad..f685aa90da4b 100644 --- a/test/tools/ossfuzz/strictasm_diff_ossfuzz.cpp +++ b/test/tools/ossfuzz/strictasm_diff_ossfuzz.cpp @@ -71,7 +71,7 @@ extern "C" int LLVMFuzzerTestOneInput(uint8_t const* _data, size_t _size) { if ( !stack.parseAndAnalyze("source", input) || - !stack.parserResult()->code || + !stack.parserResult()->hasCode() || !stack.parserResult()->analysisInfo ) return 0; @@ -89,7 +89,7 @@ extern "C" int LLVMFuzzerTestOneInput(uint8_t const* _data, size_t _size) // that would be removed by the redundant store eliminator. yulFuzzerUtil::TerminationReason termReason = yulFuzzerUtil::interpret( os1, - stack.parserResult()->code->root(), + stack.parserResult()->code()->root(), EVMDialect::strictAssemblyForEVMObjects(langutil::EVMVersion()), /*disableMemoryTracing=*/true ); @@ -99,7 +99,7 @@ extern "C" int LLVMFuzzerTestOneInput(uint8_t const* _data, size_t _size) stack.optimize(); termReason = yulFuzzerUtil::interpret( os2, - stack.parserResult()->code->root(), + stack.parserResult()->code()->root(), EVMDialect::strictAssemblyForEVMObjects(langutil::EVMVersion()), /*disableMemoryTracing=*/true ); diff --git a/test/tools/ossfuzz/yulProtoFuzzer.cpp b/test/tools/ossfuzz/yulProtoFuzzer.cpp index 092f2dacb7c7..cfdb20813007 100644 --- a/test/tools/ossfuzz/yulProtoFuzzer.cpp +++ b/test/tools/ossfuzz/yulProtoFuzzer.cpp @@ -72,7 +72,7 @@ DEFINE_PROTO_FUZZER(Program const& _input) // Parse protobuf mutated YUL code if ( !stack.parseAndAnalyze("source", yul_source) || - !stack.parserResult()->code || + !stack.parserResult()->code() || !stack.parserResult()->analysisInfo || Error::containsErrors(stack.errors()) ) diff --git a/test/tools/ossfuzz/yulProto_diff_ossfuzz.cpp b/test/tools/ossfuzz/yulProto_diff_ossfuzz.cpp index 4e07eaf6468c..13ac4aea8460 100644 --- a/test/tools/ossfuzz/yulProto_diff_ossfuzz.cpp +++ b/test/tools/ossfuzz/yulProto_diff_ossfuzz.cpp @@ -72,7 +72,7 @@ DEFINE_PROTO_FUZZER(Program const& _input) // Parse protobuf mutated YUL code if ( !stack.parseAndAnalyze("source", yul_source) || - !stack.parserResult()->code || + !stack.parserResult()->code() || !stack.parserResult()->analysisInfo || Error::containsErrors(stack.errors()) ) @@ -89,7 +89,7 @@ DEFINE_PROTO_FUZZER(Program const& _input) // that would be removed by the redundant store eliminator. yulFuzzerUtil::TerminationReason termReason = yulFuzzerUtil::interpret( os1, - stack.parserResult()->code->root(), + stack.parserResult()->code()->root(), EVMDialect::strictAssemblyForEVMObjects(version), /*disableMemoryTracing=*/true ); diff --git a/test/tools/yulopti.cpp b/test/tools/yulopti.cpp index ad32337bdd93..faab89e7923e 100644 --- a/test/tools/yulopti.cpp +++ b/test/tools/yulopti.cpp @@ -218,7 +218,7 @@ class YulOpti case ';': { Object obj; - obj.code = std::make_shared(std::get(ASTCopier{}(*m_astRoot))); + obj.setCode(std::make_shared(std::get(ASTCopier{}(*m_astRoot)))); *m_astRoot = std::get<1>(StackCompressor::run(m_dialect, obj, true, 16)); break; } diff --git a/test/tools/yulrun.cpp b/test/tools/yulrun.cpp index 9aee616e0e4a..c3a7fb19fccc 100644 --- a/test/tools/yulrun.cpp +++ b/test/tools/yulrun.cpp @@ -54,7 +54,7 @@ namespace po = boost::program_options; namespace { -std::pair, std::shared_ptr> parse(std::string const& _source) +std::pair, std::shared_ptr> parse(std::string const& _source) { YulStack stack( langutil::EVMVersion(), @@ -66,7 +66,7 @@ std::pair, std::shared_ptr> parse(std::str if (stack.parseAndAnalyze("--INPUT--", _source)) { yulAssert(stack.errors().empty(), "Parsed successfully but had errors."); - return make_pair(stack.parserResult()->code, stack.parserResult()->analysisInfo); + return make_pair(stack.parserResult()->code(), stack.parserResult()->analysisInfo); } else { @@ -77,7 +77,7 @@ std::pair, std::shared_ptr> parse(std::str void interpret(std::string const& _source, bool _inspect, bool _disableExternalCalls) { - std::shared_ptr ast; + std::shared_ptr ast; std::shared_ptr analysisInfo; tie(ast, analysisInfo) = parse(_source); if (!ast || !analysisInfo) diff --git a/tools/yulPhaser/Program.cpp b/tools/yulPhaser/Program.cpp index 2d5c31cf11b5..14b6406493d7 100644 --- a/tools/yulPhaser/Program.cpp +++ b/tools/yulPhaser/Program.cpp @@ -149,7 +149,7 @@ std::variant, ErrorList> Program::parseObject(Dialect const // The public API of the class does not provide access to the smart pointer so it won't be hard // to switch to shared_ptr if the copying turns out to be an issue (though it would be better // to refactor ObjectParser and Object to use unique_ptr instead). - auto astCopy = std::make_unique(std::get(ASTCopier{}(selectedObject->code->root()))); + auto astCopy = std::make_unique(std::get(ASTCopier{}(selectedObject->code()->root()))); return std::variant, ErrorList>(std::move(astCopy)); } From 44bfa720d0bc6d3ab51154bd44fc66776d453276 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Fri, 2 Aug 2024 15:34:20 +0200 Subject: [PATCH 0329/1022] Yul: optimizer tests assert that there are no subobjects but Data --- test/libyul/YulOptimizerTestCommon.cpp | 21 ++++++++++++------- test/libyul/YulOptimizerTestCommon.h | 5 ++--- .../long_literals_as_builtin_args.yul | 8 ++----- 3 files changed, 18 insertions(+), 16 deletions(-) diff --git a/test/libyul/YulOptimizerTestCommon.cpp b/test/libyul/YulOptimizerTestCommon.cpp index 2898086e8aa5..bf374c21fcee 100644 --- a/test/libyul/YulOptimizerTestCommon.cpp +++ b/test/libyul/YulOptimizerTestCommon.cpp @@ -74,11 +74,19 @@ using namespace solidity::yul::test; using namespace solidity::frontend; YulOptimizerTestCommon::YulOptimizerTestCommon( - std::shared_ptr _obj, + std::shared_ptr _obj, Dialect const& _dialect -): m_dialect(&_dialect), m_object(_obj), m_optimizedObject(std::make_shared()), m_analysisInfo(m_object->analysisInfo) +): m_dialect(&_dialect), m_object(_obj), m_optimizedObject(std::make_shared(*_obj)) { - *m_optimizedObject = *m_object; + if ( + std::any_of( + m_object->subObjects.begin(), + m_object->subObjects.end(), + [](auto const& subObject) { return dynamic_cast(subObject.get()) == nullptr;} + ) + ) + solUnimplementedAssert(false, "The current implementation of YulOptimizerTests ignores subobjects that are not Data."); + m_namedSteps = { {"disambiguator", [&]() { return disambiguate(); }}, {"nameDisplacer", [&]() { @@ -401,7 +409,7 @@ YulOptimizerTestCommon::YulOptimizerTestCommon( FunctionGrouper::run(*m_context, block); size_t maxIterations = 16; { - Object object; // (*m_object) ?? + Object object(*m_optimizedObject); object.setCode(std::make_shared(std::get(ASTCopier{}(block)))); block = std::get<1>(StackCompressor::run(*m_dialect, object, true, maxIterations)); } @@ -424,7 +432,7 @@ YulOptimizerTestCommon::YulOptimizerTestCommon( {"stackLimitEvader", [&]() { auto block = disambiguate(); updateContext(block); - Object object; // (*m_object); + Object object(*m_optimizedObject); object.setCode(std::make_shared(std::get(ASTCopier{}(block)))); auto const unreachables = CompilabilityChecker{ *m_dialect, @@ -536,8 +544,7 @@ Block const* YulOptimizerTestCommon::run() Block YulOptimizerTestCommon::disambiguate() { - auto block = std::get(Disambiguator(*m_dialect, *m_analysisInfo)(m_object->code()->root())); - m_analysisInfo.reset(); + auto block = std::get(Disambiguator(*m_dialect, *m_object->analysisInfo)(m_object->code()->root())); return block; } diff --git a/test/libyul/YulOptimizerTestCommon.h b/test/libyul/YulOptimizerTestCommon.h index 8a706c328b49..41806fcd6a5a 100644 --- a/test/libyul/YulOptimizerTestCommon.h +++ b/test/libyul/YulOptimizerTestCommon.h @@ -40,7 +40,7 @@ class YulOptimizerTestCommon { public: explicit YulOptimizerTestCommon( - std::shared_ptr _obj, + std::shared_ptr _obj, Dialect const& _dialect ); /// Sets optimiser step to be run to @param @@ -70,9 +70,8 @@ class YulOptimizerTestCommon std::unique_ptr m_nameDispenser; std::unique_ptr m_context; - std::shared_ptr m_object; + std::shared_ptr m_object; std::shared_ptr m_optimizedObject; - std::shared_ptr m_analysisInfo; std::map> m_namedSteps; }; diff --git a/test/libyul/yulOptimizerTests/commonSubexpressionEliminator/long_literals_as_builtin_args.yul b/test/libyul/yulOptimizerTests/commonSubexpressionEliminator/long_literals_as_builtin_args.yul index 34b44aad9492..f480bec9e1ae 100644 --- a/test/libyul/yulOptimizerTests/commonSubexpressionEliminator/long_literals_as_builtin_args.yul +++ b/test/libyul/yulOptimizerTests/commonSubexpressionEliminator/long_literals_as_builtin_args.yul @@ -7,9 +7,7 @@ object "AccessControlDefaultAdminRules4233_14" { let j := datasize("AccessControlDefaultAdminRules4233_14_deployed") codecopy(i, dataoffset("AccessControlDefaultAdminRules4233_14_deployed"), j) } - object "AccessControlDefaultAdminRules4233_14_deployed" { - code {} - } + data "AccessControlDefaultAdminRules4233_14_deployed" "AccessControlDefaultAdminRules4233_14_deployed" } // ---- @@ -22,7 +20,5 @@ object "AccessControlDefaultAdminRules4233_14" { // let j := datasize("AccessControlDefaultAdminRules4233_14_deployed") // codecopy(i, dataoffset("AccessControlDefaultAdminRules4233_14_deployed"), j) // } -// object "AccessControlDefaultAdminRules4233_14_deployed" { -// code { } -// } +// data "AccessControlDefaultAdminRules4233_14_deployed" hex"416363657373436f6e74726f6c44656661756c7441646d696e52756c6573343233335f31345f6465706c6f796564" // } From 860f0d4601ee2b2ad200344e7e4a133e71432a57 Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Thu, 13 Apr 2023 00:10:31 +0200 Subject: [PATCH 0330/1022] Change the constant optimizer to make use of PUSH0 --- libevmasm/Assembly.cpp | 4 +- libevmasm/AssemblyItem.cpp | 6 +- libevmasm/AssemblyItem.h | 7 +- libevmasm/ConstantOptimiser.cpp | 95 ++++++++++++++------ libevmasm/ConstantOptimiser.h | 4 +- libevmasm/GasMeter.cpp | 16 ++-- libevmasm/GasMeter.h | 3 + libevmasm/Inliner.cpp | 16 ++-- libevmasm/PeepholeOptimiser.cpp | 31 ++++--- libevmasm/PeepholeOptimiser.h | 9 +- libyul/backends/evm/EVMMetrics.cpp | 9 +- libyul/backends/evm/StackLayoutGenerator.cpp | 2 +- test/libevmasm/Optimiser.cpp | 77 +++++++++++++--- test/libsolidity/StandardCompiler.cpp | 13 ++- 14 files changed, 206 insertions(+), 86 deletions(-) diff --git a/libevmasm/Assembly.cpp b/libevmasm/Assembly.cpp index f9b800c90884..91773a8e8403 100644 --- a/libevmasm/Assembly.cpp +++ b/libevmasm/Assembly.cpp @@ -74,7 +74,7 @@ unsigned Assembly::codeSize(unsigned subTagSize) const ret += i.second.size(); for (AssemblyItem const& i: m_items) - ret += i.bytesRequired(tagSize, Precision::Approximate); + ret += i.bytesRequired(tagSize, m_evmVersion, Precision::Approximate); if (numberEncodingSize(ret) <= tagSize) return static_cast(ret); } @@ -753,7 +753,7 @@ std::map const& Assembly::optimiseInternal( if (_settings.runPeephole) { - PeepholeOptimiser peepOpt{m_items}; + PeepholeOptimiser peepOpt{m_items, m_evmVersion}; while (peepOpt.optimise()) { count++; diff --git a/libevmasm/AssemblyItem.cpp b/libevmasm/AssemblyItem.cpp index c88a9663f3b7..837dad8afe1b 100644 --- a/libevmasm/AssemblyItem.cpp +++ b/libevmasm/AssemblyItem.cpp @@ -116,7 +116,7 @@ void AssemblyItem::setPushTagSubIdAndTag(size_t _subId, size_t _tag) setData(data); } -size_t AssemblyItem::bytesRequired(size_t _addressLength, Precision _precision) const +size_t AssemblyItem::bytesRequired(size_t _addressLength, langutil::EVMVersion _evmVersion, Precision _precision) const { switch (m_type) { @@ -124,7 +124,9 @@ size_t AssemblyItem::bytesRequired(size_t _addressLength, Precision _precision) case Tag: // 1 byte for the JUMPDEST return 1; case Push: - return 1 + std::max(1, numberEncodingSize(data())); + return + 1 + + std::max((_evmVersion.hasPush0() ? 0 : 1), numberEncodingSize(data())); case PushSubSize: case PushProgramSize: return 1 + 4; // worst case: a 16MB program diff --git a/libevmasm/AssemblyItem.h b/libevmasm/AssemblyItem.h index c2b3603c6352..f06c72bac2ff 100644 --- a/libevmasm/AssemblyItem.h +++ b/libevmasm/AssemblyItem.h @@ -161,10 +161,11 @@ class AssemblyItem /// @returns an upper bound for the number of bytes required by this item, assuming that /// the value of a jump tag takes @a _addressLength bytes. + /// @param _evmVersion the EVM version /// @param _precision Whether to return a precise count (which involves /// counting immutable references which are only set after /// a call to `assemble()`) or an approx. count. - size_t bytesRequired(size_t _addressLength, Precision _precision = Precision::Precise) const; + size_t bytesRequired(size_t _addressLength, langutil::EVMVersion _evmVersion, Precision _precision = Precision::Precise) const; size_t arguments() const; size_t returnValues() const; size_t deposit() const { return returnValues() - arguments(); } @@ -228,11 +229,11 @@ class AssemblyItem mutable std::optional m_immutableOccurrences; }; -inline size_t bytesRequired(AssemblyItems const& _items, size_t _addressLength, Precision _precision = Precision::Precise) +inline size_t bytesRequired(AssemblyItems const& _items, size_t _addressLength, langutil::EVMVersion _evmVersion, Precision _precision = Precision::Precise) { size_t size = 0; for (AssemblyItem const& item: _items) - size += item.bytesRequired(_addressLength, _precision); + size += item.bytesRequired(_addressLength, _evmVersion, _precision); return size; } diff --git a/libevmasm/ConstantOptimiser.cpp b/libevmasm/ConstantOptimiser.cpp index 62dbc803bbc2..360fb781f4d7 100644 --- a/libevmasm/ConstantOptimiser.cpp +++ b/libevmasm/ConstantOptimiser.cpp @@ -83,7 +83,7 @@ bigint ConstantOptimisationMethod::simpleRunGas(AssemblyItems const& _items, lan bigint gas = 0; for (AssemblyItem const& item: _items) if (item.type() == Push) - gas += GasMeter::runGas(Instruction::PUSH1, _evmVersion); + gas += GasMeter::pushGas(item.data(), _evmVersion); else if (item.type() == Operation) { if (item.instruction() == Instruction::EXP) @@ -100,9 +100,9 @@ bigint ConstantOptimisationMethod::dataGas(bytes const& _data) const return bigint(GasMeter::dataGas(_data, m_params.isCreation, m_params.evmVersion)); } -size_t ConstantOptimisationMethod::bytesRequired(AssemblyItems const& _items) +size_t ConstantOptimisationMethod::bytesRequired(AssemblyItems const& _items, langutil::EVMVersion _evmVersion) { - return evmasm::bytesRequired(_items, 3, Precision::Approximate); // assume 3 byte addresses + return evmasm::bytesRequired(_items, 3, _evmVersion, Precision::Approximate); // assume 3 byte addresses } void ConstantOptimisationMethod::replaceConstants( @@ -143,7 +143,7 @@ bigint CodeCopyMethod::gasNeeded() const // Run gas: we ignore memory increase costs simpleRunGas(copyRoutine(), m_params.evmVersion) + GasCosts::copyGas, // Data gas for copy routines: Some bytes are zero, but we ignore them. - bytesRequired(copyRoutine()) * (m_params.isCreation ? GasCosts::txDataNonZeroGas(m_params.evmVersion) : GasCosts::createDataGas), + bytesRequired(copyRoutine(), m_params.evmVersion) * (m_params.isCreation ? GasCosts::txDataNonZeroGas(m_params.evmVersion) : GasCosts::createDataGas), // Data gas for data itself dataGas(toBigEndian(m_value)) ); @@ -153,37 +153,74 @@ AssemblyItems CodeCopyMethod::execute(Assembly& _assembly) const { bytes data = toBigEndian(m_value); assertThrow(data.size() == 32, OptimizerException, "Invalid number encoding."); - AssemblyItems actualCopyRoutine = copyRoutine(); - actualCopyRoutine[4] = _assembly.newData(data); - return actualCopyRoutine; + AssemblyItem newPushData = _assembly.newData(data); + return copyRoutine(&newPushData); } -AssemblyItems const& CodeCopyMethod::copyRoutine() +AssemblyItems CodeCopyMethod::copyRoutine(AssemblyItem* _pushData) const { - AssemblyItems static copyRoutine{ - // constant to be reused 3+ times - u256(0), + if (_pushData) + assertThrow(_pushData->type() == PushData, OptimizerException, "Invalid Assembly Item."); - // back up memory - // mload(0) - Instruction::DUP1, - Instruction::MLOAD, + AssemblyItem dataUsed = _pushData ? *_pushData : AssemblyItem(PushData, u256(1) << 16); - // codecopy(0, , 32) - u256(32), - AssemblyItem(PushData, u256(1) << 16), // replaced above in actualCopyRoutine[4] - Instruction::DUP4, - Instruction::CODECOPY, + // PUSH0 is cheaper than PUSHn/DUP/SWAP. + if (m_params.evmVersion.hasPush0()) + { + // This costs ~29 gas. + AssemblyItems copyRoutine{ + // back up memory + // mload(0) + u256(0), + Instruction::MLOAD, + + // codecopy(0, , 32) + u256(32), + dataUsed, + u256(0), + Instruction::CODECOPY, + + // mload(0) + u256(0), + Instruction::MLOAD, + + // restore original memory + // mstore(0, x) + Instruction::SWAP1, + u256(0), + Instruction::MSTORE + }; + return copyRoutine; + } + else + { + // This costs ~33 gas. + AssemblyItems copyRoutine{ + // constant to be reused 3+ times + u256(0), + + // back up memory + // mload(0) + Instruction::DUP1, + Instruction::MLOAD, - // mload(0) - Instruction::DUP2, - Instruction::MLOAD, + // codecopy(0, , 32) + u256(32), + dataUsed, + Instruction::DUP4, + Instruction::CODECOPY, - // restore original memory - Instruction::SWAP2, - Instruction::MSTORE - }; - return copyRoutine; + // mload(0) + Instruction::DUP2, + Instruction::MLOAD, + + // restore original memory + // mstore(0, x) + Instruction::SWAP2, + Instruction::MSTORE + }; + return copyRoutine; + } } AssemblyItems ComputeMethod::findRepresentation(u256 const& _value) @@ -323,7 +360,7 @@ bigint ComputeMethod::gasNeeded(AssemblyItems const& _routine) const return combineGas( simpleRunGas(_routine, m_params.evmVersion) + numExps * (GasCosts::expGas + GasCosts::expByteGas(m_params.evmVersion)), // Data gas for routine: Some bytes are zero, but we ignore them. - bytesRequired(_routine) * (m_params.isCreation ? GasCosts::txDataNonZeroGas(m_params.evmVersion) : GasCosts::createDataGas), + bytesRequired(_routine, m_params.evmVersion) * (m_params.isCreation ? GasCosts::txDataNonZeroGas(m_params.evmVersion) : GasCosts::createDataGas), 0 ); } diff --git a/libevmasm/ConstantOptimiser.h b/libevmasm/ConstantOptimiser.h index 139e263ba369..7a929939efe6 100644 --- a/libevmasm/ConstantOptimiser.h +++ b/libevmasm/ConstantOptimiser.h @@ -79,7 +79,7 @@ class ConstantOptimisationMethod static bigint simpleRunGas(AssemblyItems const& _items, langutil::EVMVersion _evmVersion); /// @returns the gas needed to store the given data literally bigint dataGas(bytes const& _data) const; - static size_t bytesRequired(AssemblyItems const& _items); + static size_t bytesRequired(AssemblyItems const& _items, langutil::EVMVersion _evmVersion); /// @returns the combined estimated gas usage taking @a m_params into account. bigint combineGas( bigint const& _runGas, @@ -123,7 +123,7 @@ class CodeCopyMethod: public ConstantOptimisationMethod AssemblyItems execute(Assembly& _assembly) const override; protected: - static AssemblyItems const& copyRoutine(); + AssemblyItems copyRoutine(AssemblyItem* _pushData = nullptr) const; }; /** diff --git a/libevmasm/GasMeter.cpp b/libevmasm/GasMeter.cpp index b3d160585e37..a501b487f45a 100644 --- a/libevmasm/GasMeter.cpp +++ b/libevmasm/GasMeter.cpp @@ -44,12 +44,8 @@ GasMeter::GasConsumption GasMeter::estimateMax(AssemblyItem const& _item, bool _ switch (_item.type()) { case Push: - if (m_evmVersion.hasPush0() && _item.data() == 0) - { - gas = runGas(Instruction::PUSH0, m_evmVersion); - break; - } - [[fallthrough]]; + gas = pushGas(_item.data(), m_evmVersion); + break; case PushTag: case PushData: case PushSub: @@ -290,6 +286,14 @@ unsigned GasMeter::runGas(Instruction _instruction, langutil::EVMVersion _evmVer util::unreachable(); } +unsigned GasMeter::pushGas(u256 _value, langutil::EVMVersion _evmVersion) +{ + return runGas( + (_evmVersion.hasPush0() && _value == u256(0)) ? Instruction::PUSH0 : Instruction::PUSH1, + _evmVersion + ); +} + u256 GasMeter::dataGas(bytes const& _data, bool _inCreation, langutil::EVMVersion _evmVersion) { bigint gas = 0; diff --git a/libevmasm/GasMeter.h b/libevmasm/GasMeter.h index c91e0f0971c9..50a783e1a6e5 100644 --- a/libevmasm/GasMeter.h +++ b/libevmasm/GasMeter.h @@ -225,6 +225,9 @@ class GasMeter /// change with EVM versions) static unsigned runGas(Instruction _instruction, langutil::EVMVersion _evmVersion); + /// @returns gas costs for push instructions (may change depending on EVM version) + static unsigned pushGas(u256 _value, langutil::EVMVersion _evmVersion); + /// @returns the gas cost of the supplied data, depending whether it is in creation code, or not. /// In case of @a _inCreation, the data is only sent as a transaction and is not stored, whereas /// otherwise code will be stored and have to pay "createDataGas" cost. diff --git a/libevmasm/Inliner.cpp b/libevmasm/Inliner.cpp index 67918e558bc3..f3358128c655 100644 --- a/libevmasm/Inliner.cpp +++ b/libevmasm/Inliner.cpp @@ -59,10 +59,10 @@ u256 executionCost(RangeType const& _itemRange, langutil::EVMVersion _evmVersion } /// @returns an estimation of the code size in bytes needed for the AssemblyItems in @a _itemRange. template -uint64_t codeSize(RangeType const& _itemRange) +uint64_t codeSize(RangeType const& _itemRange, langutil::EVMVersion _evmVersion) { return ranges::accumulate(_itemRange | ranges::views::transform( - [](auto const& _item) { return _item.bytesRequired(2, Precision::Approximate); } + [&](auto const& _item) { return _item.bytesRequired(2, _evmVersion, Precision::Approximate); } ), 0u); } /// @returns the tag id, if @a _item is a PushTag or Tag into the current subassembly, std::nullopt otherwise. @@ -139,7 +139,7 @@ std::map Inliner::determineInlinableBlocks(Asse bool Inliner::shouldInlineFullFunctionBody(size_t _tag, ranges::span _block, uint64_t _pushTagCount) const { // Accumulate size of the inline candidate block in bytes (without the return jump). - uint64_t functionBodySize = codeSize(ranges::views::drop_last(_block, 1)); + uint64_t functionBodySize = codeSize(ranges::views::drop_last(_block, 1), m_evmVersion); // Use the number of push tags as approximation of the average number of calls to the function per run. uint64_t numberOfCalls = _pushTagCount; @@ -167,8 +167,8 @@ bool Inliner::shouldInlineFullFunctionBody(size_t _tag, ranges::span Inliner::shouldInline(size_t _tag, AssemblyItem cons AssemblyItem{Instruction::JUMP}, }; if ( - GasMeter::dataGas(codeSize(_block.items), m_isCreation, m_evmVersion) <= - GasMeter::dataGas(codeSize(jumpPattern), m_isCreation, m_evmVersion) + GasMeter::dataGas(codeSize(_block.items, m_evmVersion), m_isCreation, m_evmVersion) <= + GasMeter::dataGas(codeSize(jumpPattern, m_evmVersion), m_isCreation, m_evmVersion) ) return blockExit; } diff --git a/libevmasm/PeepholeOptimiser.cpp b/libevmasm/PeepholeOptimiser.cpp index 257a3727c01d..df33e04e5125 100644 --- a/libevmasm/PeepholeOptimiser.cpp +++ b/libevmasm/PeepholeOptimiser.cpp @@ -38,6 +38,7 @@ struct OptimiserState AssemblyItems const& items; size_t i; std::back_insert_iterator out; + langutil::EVMVersion evmVersion = langutil::EVMVersion(); }; template @@ -199,16 +200,26 @@ struct DoubleSwap: SimplePeepholeOptimizerMethod struct DoublePush: SimplePeepholeOptimizerMethod { - static bool applySimple( - AssemblyItem const& _push1, - AssemblyItem const& _push2, - std::back_insert_iterator _out - ) + static bool apply(OptimiserState& _state) { - if (_push1.type() == Push && _push2.type() == Push && _push1.data() == _push2.data()) + size_t windowSize = 2; + if (_state.i + windowSize > _state.items.size()) + return false; + + auto push1 = _state.items.begin() + static_cast(_state.i); + auto push2 = _state.items.begin() + static_cast(_state.i + 1); + assertThrow(push1 != _state.items.end() && push2 != _state.items.end(), OptimizerException, ""); + + if ( + push1->type() == Push && + push2->type() == Push && + push1->data() == push2->data() && + (!_state.evmVersion.hasPush0() || push1->data() != 0) + ) { - *_out = _push1; - *_out = {Instruction::DUP1, _push2.debugData()}; + *_state.out = *push1; + *_state.out = {Instruction::DUP1, push2->debugData()}; + _state.i += windowSize; return true; } else @@ -510,7 +521,7 @@ bool PeepholeOptimiser::optimise() { // Avoid referencing immutables too early by using approx. counting in bytesRequired() auto const approx = evmasm::Precision::Approximate; - OptimiserState state {m_items, 0, back_inserter(m_optimisedItems)}; + OptimiserState state {m_items, 0, back_inserter(m_optimisedItems), m_evmVersion}; while (state.i < m_items.size()) applyMethods( state, @@ -520,7 +531,7 @@ bool PeepholeOptimiser::optimise() ); if (m_optimisedItems.size() < m_items.size() || ( m_optimisedItems.size() == m_items.size() && ( - evmasm::bytesRequired(m_optimisedItems, 3, approx) < evmasm::bytesRequired(m_items, 3, approx) || + evmasm::bytesRequired(m_optimisedItems, 3, m_evmVersion, approx) < evmasm::bytesRequired(m_items, 3, m_evmVersion, approx) || numberOfPops(m_optimisedItems) > numberOfPops(m_items) ) )) diff --git a/libevmasm/PeepholeOptimiser.h b/libevmasm/PeepholeOptimiser.h index 64ad5227fae1..8e3161b212aa 100644 --- a/libevmasm/PeepholeOptimiser.h +++ b/libevmasm/PeepholeOptimiser.h @@ -25,6 +25,8 @@ #include #include +#include + namespace solidity::evmasm { class AssemblyItem; @@ -41,7 +43,11 @@ class PeepholeOptimisationMethod class PeepholeOptimiser { public: - explicit PeepholeOptimiser(AssemblyItems& _items): m_items(_items) {} + explicit PeepholeOptimiser(AssemblyItems& _items, langutil::EVMVersion const _evmVersion): + m_items(_items), + m_evmVersion(_evmVersion) + { + } virtual ~PeepholeOptimiser() = default; bool optimise(); @@ -49,6 +55,7 @@ class PeepholeOptimiser private: AssemblyItems& m_items; AssemblyItems m_optimisedItems; + langutil::EVMVersion const m_evmVersion; }; } diff --git a/libyul/backends/evm/EVMMetrics.cpp b/libyul/backends/evm/EVMMetrics.cpp index 84ebdab1d2be..539279bf20d9 100644 --- a/libyul/backends/evm/EVMMetrics.cpp +++ b/libyul/backends/evm/EVMMetrics.cpp @@ -87,10 +87,11 @@ void GasMeterVisitor::operator()(FunctionCall const& _funCall) void GasMeterVisitor::operator()(Literal const& _lit) { - m_runGas += evmasm::GasMeter::runGas(evmasm::Instruction::PUSH1, m_dialect.evmVersion()); - m_dataGas += - singleByteDataGas() + - evmasm::GasMeter::dataGas( + m_runGas += evmasm::GasMeter::pushGas(_lit.value.value(), m_dialect.evmVersion()); + + m_dataGas += singleByteDataGas(); + if (!m_dialect.evmVersion().hasPush0() || _lit.value.value() != u256(0)) + m_dataGas += evmasm::GasMeter::dataGas( toCompactBigEndian(_lit.value.value(), 1), m_isCreation, m_dialect.evmVersion() diff --git a/libyul/backends/evm/StackLayoutGenerator.cpp b/libyul/backends/evm/StackLayoutGenerator.cpp index c781d7c1b813..1a30842aecc8 100644 --- a/libyul/backends/evm/StackLayoutGenerator.cpp +++ b/libyul/backends/evm/StackLayoutGenerator.cpp @@ -771,7 +771,7 @@ void StackLayoutGenerator::fillInJunk(CFG::BasicBlock const& _block, CFG::Functi yulAssert(util::contains(m_currentFunctionInfo->returnVariables, std::get(_slot))); // Strictly speaking the cost of the PUSH0 depends on the targeted EVM version, but the difference // will not matter here. - opGas += evmasm::GasMeter::runGas(evmasm::pushInstruction(0), langutil::EVMVersion()); + opGas += evmasm::GasMeter::pushGas(u256(0), langutil::EVMVersion()); } } }; diff --git a/test/libevmasm/Optimiser.cpp b/test/libevmasm/Optimiser.cpp index 04d41fffeb18..afc3c09fa9df 100644 --- a/test/libevmasm/Optimiser.cpp +++ b/test/libevmasm/Optimiser.cpp @@ -1000,7 +1000,7 @@ BOOST_AUTO_TEST_CASE(clear_unreachable_code) AssemblyItem(PushTag, 1), Instruction::JUMP }; - PeepholeOptimiser peepOpt(items); + PeepholeOptimiser peepOpt(items, solidity::test::CommonOptions::get().evmVersion()); BOOST_REQUIRE(peepOpt.optimise()); BOOST_CHECK_EQUAL_COLLECTIONS( items.begin(), items.end(), @@ -1026,7 +1026,19 @@ BOOST_AUTO_TEST_CASE(peephole_double_push) u256(4), u256(5) }; - PeepholeOptimiser peepOpt(items); + + // `PUSH0 PUSH0` is cheaper than `DUP1 PUSH0` + if (solidity::test::CommonOptions::get().evmVersion() >= EVMVersion::shanghai()) + expectation = { + u256(0), + u256(0), + u256(5), + Instruction::DUP1, + u256(4), + u256(5) + }; + + PeepholeOptimiser peepOpt(items, solidity::test::CommonOptions::get().evmVersion()); BOOST_REQUIRE(peepOpt.optimise()); BOOST_CHECK_EQUAL_COLLECTIONS( items.begin(), items.end(), @@ -1042,7 +1054,7 @@ BOOST_AUTO_TEST_CASE(peephole_pop_calldatasize) Instruction::LT, Instruction::POP }; - PeepholeOptimiser peepOpt(items); + PeepholeOptimiser peepOpt(items, solidity::test::CommonOptions::get().evmVersion()); for (size_t i = 0; i < 3; i++) BOOST_CHECK(peepOpt.optimise()); BOOST_CHECK(items.empty()); @@ -1075,7 +1087,7 @@ BOOST_AUTO_TEST_CASE(peephole_commutative_swap1) u256(4), u256(5) }; - PeepholeOptimiser peepOpt(items); + PeepholeOptimiser peepOpt(items, solidity::test::CommonOptions::get().evmVersion()); BOOST_REQUIRE(peepOpt.optimise()); BOOST_CHECK_EQUAL_COLLECTIONS( items.begin(), items.end(), @@ -1113,7 +1125,7 @@ BOOST_AUTO_TEST_CASE(peephole_noncommutative_swap1) u256(4), u256(5) }; - PeepholeOptimiser peepOpt(items); + PeepholeOptimiser peepOpt(items, solidity::test::CommonOptions::get().evmVersion()); BOOST_REQUIRE(!peepOpt.optimise()); BOOST_CHECK_EQUAL_COLLECTIONS( items.begin(), items.end(), @@ -1148,7 +1160,7 @@ BOOST_AUTO_TEST_CASE(peephole_swap_comparison) u256(4), u256(5) }; - PeepholeOptimiser peepOpt(items); + PeepholeOptimiser peepOpt(items, solidity::test::CommonOptions::get().evmVersion()); BOOST_REQUIRE(peepOpt.optimise()); BOOST_CHECK_EQUAL_COLLECTIONS( items.begin(), items.end(), @@ -1174,7 +1186,7 @@ BOOST_AUTO_TEST_CASE(peephole_truthy_and) AssemblyItem(PushTag, 1), Instruction::JUMPI }; - PeepholeOptimiser peepOpt(items); + PeepholeOptimiser peepOpt(items, solidity::test::CommonOptions::get().evmVersion()); BOOST_REQUIRE(peepOpt.optimise()); BOOST_CHECK_EQUAL_COLLECTIONS( items.begin(), items.end(), @@ -1207,7 +1219,7 @@ BOOST_AUTO_TEST_CASE(peephole_iszero_iszero_jumpi) u256(0x20), Instruction::RETURN }; - PeepholeOptimiser peepOpt(items); + PeepholeOptimiser peepOpt(items, solidity::test::CommonOptions::get().evmVersion()); BOOST_REQUIRE(peepOpt.optimise()); BOOST_CHECK_EQUAL_COLLECTIONS( items.begin(), items.end(), @@ -1649,6 +1661,40 @@ BOOST_AUTO_TEST_CASE(cse_replace_too_large_shift) }); } +BOOST_AUTO_TEST_CASE(cse_dup) +{ + AssemblyItems input{ + u256(0), + Instruction::DUP1, + Instruction::REVERT + }; + AssemblyItems output = input; + + checkCSE(input, output); + checkFullCSE(input, output); +} + +BOOST_AUTO_TEST_CASE(cse_push0) +{ + AssemblyItems input{ + u256(0), + u256(0), + Instruction::REVERT + }; + AssemblyItems output{ + u256(0), + Instruction::DUP1, + Instruction::REVERT + }; + // The CSE has a rule to replace with DUP1 PUSH0 + checkCSE(input, output); + + // The full handling by the compiler (Assembly::optimiseInternal) + // will not choose to replace the pattern, because the new size is the same as the old one + output = input; + checkFullCSE(input, output); +} + BOOST_AUTO_TEST_CASE(inliner) { AssemblyItem jumpInto{Instruction::JUMP}; @@ -1873,9 +1919,10 @@ BOOST_AUTO_TEST_CASE(inliner_revert) ); } -BOOST_AUTO_TEST_CASE(inliner_revert_increased_datagas) +BOOST_AUTO_TEST_CASE(inliner_revert_push0) { - // Inlining this would increase data gas (5 bytes v/s 4 bytes), therefore, skipped. + // Inlining this without PUSH0 would increase data gas (5 bytes v/s 4 bytes), therefore, it would be skipped. + // However, with PUSH0 it is inlined (3 bytes vs 4 bytes). AssemblyItems items{ AssemblyItem(PushTag, 1), Instruction::JUMP, @@ -1884,8 +1931,16 @@ BOOST_AUTO_TEST_CASE(inliner_revert_increased_datagas) u256(0), Instruction::REVERT }; + AssemblyItems expectation{ + u256(0), + u256(0), + Instruction::REVERT, + AssemblyItem(Tag, 1), + u256(0), + u256(0), + Instruction::REVERT + }; - AssemblyItems expectation = items; Inliner{items, {}, Assembly::OptimiserSettings{}.expectedExecutionsPerDeployment, false, {}}.optimise(); BOOST_CHECK_EQUAL_COLLECTIONS( items.begin(), items.end(), diff --git a/test/libsolidity/StandardCompiler.cpp b/test/libsolidity/StandardCompiler.cpp index cdb6c5bd2d9d..4cb0b3c93068 100644 --- a/test/libsolidity/StandardCompiler.cpp +++ b/test/libsolidity/StandardCompiler.cpp @@ -29,6 +29,7 @@ #include #include #include +#include #include #include @@ -383,22 +384,20 @@ BOOST_AUTO_TEST_CASE(basic_compilation) BOOST_CHECK(contract["evm"]["bytecode"]["object"].is_string()); BOOST_CHECK_EQUAL( solidity::test::bytecodeSansMetadata(contract["evm"]["bytecode"]["object"].get()), - std::string("6080604052348015600e575f80fd5b5060") + + std::string("6080604052348015600e575f5ffd5b5060") + (VersionIsRelease ? "3e" : util::toHex(bytes{uint8_t(60 + VersionStringStrict.size())})) + - "80601a5f395ff3fe60806040525f80fdfe" + "80601a5f395ff3fe60806040525f5ffdfe" ); BOOST_CHECK(contract["evm"]["assembly"].is_string()); BOOST_CHECK(contract["evm"]["assembly"].get().find( " /* \"fileA\":0:14 contract A { } */\n mstore(0x40, 0x80)\n " "callvalue\n dup1\n " "iszero\n tag_1\n jumpi\n " - "0x00\n " - "dup1\n revert\n" + "revert(0x00, 0x00)\n" "tag_1:\n pop\n dataSize(sub_0)\n dup1\n " "dataOffset(sub_0)\n 0x00\n codecopy\n 0x00\n return\nstop\n\nsub_0: assembly {\n " "/* \"fileA\":0:14 contract A { } */\n mstore(0x40, 0x80)\n " - "0x00\n " - "dup1\n revert\n\n auxdata: 0xa26469706673582212" + "revert(0x00, 0x00)\n\n auxdata: 0xa26469706673582212" ) == 0); BOOST_CHECK(contract["evm"]["gasEstimates"].is_object()); BOOST_CHECK_EQUAL(contract["evm"]["gasEstimates"].size(), 1); @@ -427,7 +426,7 @@ BOOST_AUTO_TEST_CASE(basic_compilation) "{\"begin\":0,\"end\":14,\"name\":\"PUSH [tag]\",\"source\":0,\"value\":\"1\"}," "{\"begin\":0,\"end\":14,\"name\":\"JUMPI\",\"source\":0}," "{\"begin\":0,\"end\":14,\"name\":\"PUSH\",\"source\":0,\"value\":\"0\"}," - "{\"begin\":0,\"end\":14,\"name\":\"DUP1\",\"source\":0}," + "{\"begin\":0,\"end\":14,\"name\":\"PUSH\",\"source\":0,\"value\":\"0\"}," "{\"begin\":0,\"end\":14,\"name\":\"REVERT\",\"source\":0}," "{\"begin\":0,\"end\":14,\"name\":\"tag\",\"source\":0,\"value\":\"1\"}," "{\"begin\":0,\"end\":14,\"name\":\"JUMPDEST\",\"source\":0}," From 6e7d94e886a14e195bc703293e72e2dffe00819b Mon Sep 17 00:00:00 2001 From: Matheus Aguiar Date: Sat, 30 Mar 2024 15:32:16 -0300 Subject: [PATCH 0331/1022] Add new Peephole Optimiser method (deduplicateNextTag) --- Changelog.md | 3 + libevmasm/PeepholeOptimiser.cpp | 99 ++++++++++++++++++++++++++++++- libevmasm/SemanticInformation.cpp | 7 +++ libevmasm/SemanticInformation.h | 1 + test/libevmasm/Optimiser.cpp | 75 +++++++++++++++++++++++ 5 files changed, 182 insertions(+), 3 deletions(-) diff --git a/Changelog.md b/Changelog.md index 8acee7422b3d..632ec787e935 100644 --- a/Changelog.md +++ b/Changelog.md @@ -9,8 +9,11 @@ Language Features: Compiler Features: * Command Line Interface: Do not perform IR optimization when only unoptimized IR is requested. * Commandline Interface: Add ``--transient-storage-layout`` output. + * Constant Optimizer: Uses ``PUSH0`` if supported by the selected evm version. * Error Reporting: Unimplemented features are now properly reported as errors instead of being handled as if they were bugs. * EVM: Support for the EVM version "Prague". + * Peephole Optimizer: ``PUSH0``, when supported, is duplicated explicitly instead of using ``DUP1``. + * Peephole optimizer: Remove identical code snippets that terminate the control flow if they occur one after another. * SMTChecker: Add CHC engine check for underflow and overflow in unary minus operation. * SMTChecker: Replace CVC4 as a possible BMC backend with cvc5. * Standard JSON Interface: Do not perform IR optimization when only unoptimized IR is requested. diff --git a/libevmasm/PeepholeOptimiser.cpp b/libevmasm/PeepholeOptimiser.cpp index df33e04e5125..40937e73f107 100644 --- a/libevmasm/PeepholeOptimiser.cpp +++ b/libevmasm/PeepholeOptimiser.cpp @@ -198,7 +198,7 @@ struct DoubleSwap: SimplePeepholeOptimizerMethod } }; -struct DoublePush: SimplePeepholeOptimizerMethod +struct DoublePush { static bool apply(OptimiserState& _state) { @@ -498,6 +498,99 @@ struct UnreachableCode } }; +struct DeduplicateNextTagSize3 : SimplePeepholeOptimizerMethod +{ + static bool applySimple( + AssemblyItem const& _precedingItem, + AssemblyItem const& _itemA, + AssemblyItem const& _itemB, + AssemblyItem const& _breakingItem, + AssemblyItem const& _tag, + AssemblyItem const& _itemC, + AssemblyItem const& _itemD, + AssemblyItem const& _breakingItem2, + std::back_insert_iterator _out + ) + { + if ( + _precedingItem.type() != Tag && + _itemA == _itemC && + _itemB == _itemD && + _breakingItem == _breakingItem2 && + _tag.type() == Tag && + SemanticInformation::terminatesControlFlow(_breakingItem) + ) + { + *_out = _precedingItem; + *_out = _tag; + *_out = _itemC; + *_out = _itemD; + *_out = _breakingItem2; + return true; + } + + return false; + } +}; + +struct DeduplicateNextTagSize2 : SimplePeepholeOptimizerMethod +{ + static bool applySimple( + AssemblyItem const& _precedingItem, + AssemblyItem const& _itemA, + AssemblyItem const& _breakingItem, + AssemblyItem const& _tag, + AssemblyItem const& _itemC, + AssemblyItem const& _breakingItem2, + std::back_insert_iterator _out + ) + { + if ( + _precedingItem.type() != Tag && + _itemA == _itemC && + _breakingItem == _breakingItem2 && + _tag.type() == Tag && + SemanticInformation::terminatesControlFlow(_breakingItem) + ) + { + *_out = _precedingItem; + *_out = _tag; + *_out = _itemC; + *_out = _breakingItem2; + return true; + } + + return false; + } +}; + +struct DeduplicateNextTagSize1 : SimplePeepholeOptimizerMethod +{ + static bool applySimple( + AssemblyItem const& _precedingItem, + AssemblyItem const& _breakingItem, + AssemblyItem const& _tag, + AssemblyItem const& _breakingItem2, + std::back_insert_iterator _out + ) + { + if ( + _precedingItem.type() != Tag && + _breakingItem == _breakingItem2 && + _tag.type() == Tag && + SemanticInformation::terminatesControlFlow(_breakingItem) + ) + { + *_out = _precedingItem; + *_out = _tag; + *_out = _breakingItem2; + return true; + } + + return false; + } +}; + void applyMethods(OptimiserState&) { assertThrow(false, OptimizerException, "Peephole optimizer failed to apply identity."); @@ -526,8 +619,8 @@ bool PeepholeOptimiser::optimise() applyMethods( state, PushPop(), OpPop(), OpStop(), OpReturnRevert(), DoublePush(), DoubleSwap(), CommutativeSwap(), SwapComparison(), - DupSwap(), IsZeroIsZeroJumpI(), EqIsZeroJumpI(), DoubleJump(), JumpToNext(), UnreachableCode(), - TagConjunctions(), TruthyAnd(), Identity() + DupSwap(), IsZeroIsZeroJumpI(), EqIsZeroJumpI(), DoubleJump(), JumpToNext(), UnreachableCode(), DeduplicateNextTagSize3(), + DeduplicateNextTagSize2(), DeduplicateNextTagSize1(), TagConjunctions(), TruthyAnd(), Identity() ); if (m_optimisedItems.size() < m_items.size() || ( m_optimisedItems.size() == m_items.size() && ( diff --git a/libevmasm/SemanticInformation.cpp b/libevmasm/SemanticInformation.cpp index 978fb7ce2aef..87d41f6c13a0 100644 --- a/libevmasm/SemanticInformation.cpp +++ b/libevmasm/SemanticInformation.cpp @@ -299,6 +299,13 @@ bool SemanticInformation::altersControlFlow(AssemblyItem const& _item) } } +bool SemanticInformation::terminatesControlFlow(AssemblyItem const& _item) +{ + if (_item.type() != evmasm::Operation) + return false; + return terminatesControlFlow(_item.instruction()); +} + bool SemanticInformation::terminatesControlFlow(Instruction _instruction) { switch (_instruction) diff --git a/libevmasm/SemanticInformation.h b/libevmasm/SemanticInformation.h index c3491cda8bd8..b62832f238af 100644 --- a/libevmasm/SemanticInformation.h +++ b/libevmasm/SemanticInformation.h @@ -84,6 +84,7 @@ struct SemanticInformation static bool isSwapInstruction(AssemblyItem const& _item); static bool isJumpInstruction(AssemblyItem const& _item); static bool altersControlFlow(AssemblyItem const& _item); + static bool terminatesControlFlow(AssemblyItem const& _item); static bool terminatesControlFlow(Instruction _instruction); static bool reverts(Instruction _instruction); /// @returns false if the value put on the stack by _item depends on anything else than diff --git a/test/libevmasm/Optimiser.cpp b/test/libevmasm/Optimiser.cpp index afc3c09fa9df..13fa58bf4bdf 100644 --- a/test/libevmasm/Optimiser.cpp +++ b/test/libevmasm/Optimiser.cpp @@ -1008,6 +1008,81 @@ BOOST_AUTO_TEST_CASE(clear_unreachable_code) ); } +BOOST_AUTO_TEST_CASE(deduplicateNextTagBlockSize3) +{ + AssemblyItems items{ + Instruction::JUMP, + u256(0), + u256(1), + Instruction::REVERT, + AssemblyItem(Tag, 2), + u256(0), + u256(1), + Instruction::REVERT + }; + + AssemblyItems expectation{ + Instruction::JUMP, + AssemblyItem(Tag, 2), + u256(0), + u256(1), + Instruction::REVERT + }; + PeepholeOptimiser peepOpt(items, solidity::test::CommonOptions::get().evmVersion()); + BOOST_REQUIRE(peepOpt.optimise()); + BOOST_CHECK_EQUAL_COLLECTIONS( + items.begin(), items.end(), + expectation.begin(), expectation.end() + ); +} + +BOOST_AUTO_TEST_CASE(deduplicateNextTagBlockSize2) +{ + AssemblyItems items{ + Instruction::JUMP, + u256(0), + Instruction::SELFDESTRUCT, + AssemblyItem(Tag, 2), + u256(0), + Instruction::SELFDESTRUCT + }; + + AssemblyItems expectation{ + Instruction::JUMP, + AssemblyItem(Tag, 2), + u256(0), + Instruction::SELFDESTRUCT + }; + PeepholeOptimiser peepOpt(items, solidity::test::CommonOptions::get().evmVersion()); + BOOST_REQUIRE(peepOpt.optimise()); + BOOST_CHECK_EQUAL_COLLECTIONS( + items.begin(), items.end(), + expectation.begin(), expectation.end() + ); +} + +BOOST_AUTO_TEST_CASE(deduplicateNextTagBlockSize1) +{ + AssemblyItems items{ + Instruction::JUMP, + Instruction::STOP, + AssemblyItem(Tag, 2), + Instruction::STOP + }; + + AssemblyItems expectation{ + Instruction::JUMP, + AssemblyItem(Tag, 2), + Instruction::STOP + }; + PeepholeOptimiser peepOpt(items, solidity::test::CommonOptions::get().evmVersion()); + BOOST_REQUIRE(peepOpt.optimise()); + BOOST_CHECK_EQUAL_COLLECTIONS( + items.begin(), items.end(), + expectation.begin(), expectation.end() + ); +} + BOOST_AUTO_TEST_CASE(peephole_double_push) { AssemblyItems items{ From 7e67811a82d55bb280f5a21e9b623e4c3d99fbca Mon Sep 17 00:00:00 2001 From: Matheus Aguiar Date: Sat, 30 Mar 2024 17:34:55 -0300 Subject: [PATCH 0332/1022] Update tests --- test/cmdlineTests/asm_json/output | 30 +++++++++++-------- .../asm_json_no_pretty_print/output | 2 +- .../output | 12 ++------ .../output | 12 ++------ .../output | 12 ++------ test/cmdlineTests/dup_opt_peephole/output | 8 ++--- .../optimize_full_storage_write/output | 12 ++------ .../optimizer_BlockDeDuplicator/output | 12 ++------ .../cmdlineTests/optimizer_inliner_add/output | 12 ++------ .../output | 12 ++------ .../output | 12 ++------ .../output | 12 ++------ .../cmdlineTests/optimizer_inliner_inc/output | 12 ++------ .../optimizer_inliner_multireturn/output | 12 ++------ test/cmdlineTests/optimizer_user_yul/output | 8 ++--- .../output.json | 12 ++------ .../output.json | 12 ++------ .../output.json | 12 ++------ .../output | 5 ++-- .../strict_asm_msize_without_optimizer/output | 4 +-- .../viair_msize_without_optimizer/output | 21 ++++--------- .../abiEncoderV1/abi_decode_v2_storage.sol | 2 +- .../abi_encode_calldata_slice.sol | 8 ++--- .../struct/struct_storage_ptr.sol | 6 ++-- .../abi_encode_calldata_slice.sol | 8 ++--- .../abiEncoderV2/abi_encode_v2.sol | 2 +- ...ode_v2_in_modifier_used_in_v1_contract.sol | 2 +- .../calldata_overlapped_dynamic_arrays.sol | 6 ++-- .../abiEncoderV2/storage_array_encoding.sol | 6 ++-- .../abi_decode_simple_storage.sol | 6 ++-- .../array/array_memory_index_access.sol | 4 +-- .../array/array_storage_index_access.sol | 18 +++++------ .../array_storage_index_boundary_test.sol | 8 ++--- .../array/array_storage_index_zeroed_test.sol | 16 +++++----- .../array/array_storage_push_empty.sol | 4 +-- .../array/array_storage_push_pop.sol | 4 +-- .../arrays_complex_from_and_to_storage.sol | 2 +- .../array/byte_array_storage_layout.sol | 4 +-- .../array/byte_array_transitional_2.sol | 4 +-- .../array/bytes_length_member.sol | 4 +-- .../copying/array_copy_calldata_storage.sol | 4 +-- .../copying/array_copy_cleanup_uint40.sol | 4 +-- .../copying/array_copy_clear_storage.sol | 4 +-- .../copying/array_copy_different_packing.sol | 6 ++-- .../copying/array_copy_including_array.sol | 10 +++---- .../array/copying/array_copy_nested_array.sol | 6 ++-- ...ay_copy_storage_storage_different_base.sol | 2 +- ..._storage_storage_different_base_nested.sol | 4 +-- .../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 | 4 +-- .../array_copy_storage_to_memory_nested.sol | 2 +- .../copying/array_copy_target_leftover.sol | 6 ++-- .../copying/array_copy_target_simple.sol | 4 +-- .../copying/array_copy_target_simple_2.sol | 4 +-- .../copying/array_elements_to_mapping.sol | 6 ++-- .../array_nested_calldata_to_storage.sol | 4 +-- .../array_nested_memory_to_storage.sol | 6 ++-- ...ts_containing_arrays_memory_to_storage.sol | 2 +- .../array_storage_multi_items_per_slot.sol | 2 +- .../array/copying/array_to_mapping.sol | 6 ++-- .../array/copying/bytes_inside_mappings.sol | 4 +-- .../copying/bytes_storage_to_storage.sol | 20 ++++++------- .../calldata_array_dynamic_to_storage.sol | 6 ++-- .../copy_byte_array_in_struct_to_storage.sol | 6 ++-- .../copying/copy_byte_array_to_storage.sol | 6 ++-- .../copy_function_internal_storage_array.sol | 2 +- .../array/copying/copy_removes_bytes_data.sol | 2 +- .../copying/copying_bytes_multiassign.sol | 2 +- .../function_type_array_to_storage.sol | 8 ++--- .../memory_dyn_2d_bytes_to_storage.sol | 2 +- ...ested_array_element_storage_to_storage.sol | 4 +-- ...d_array_of_structs_calldata_to_storage.sol | 4 +-- ...ted_array_of_structs_memory_to_storage.sol | 4 +-- ...amic_array_element_calldata_to_storage.sol | 2 +- .../array/copying/storage_memory_nested.sol | 4 +-- .../copying/storage_memory_nested_bytes.sol | 4 +-- .../storage_memory_nested_from_pointer.sol | 2 +- .../copying/storage_memory_nested_struct.sol | 2 +- .../copying/storage_memory_packed_dyn.sol | 4 +-- .../array/create_memory_array.sol | 2 +- .../array/delete/bytes_delete_element.sol | 4 +-- .../array/dynamic_array_cleanup.sol | 2 +- .../array/dynamic_arrays_in_storage.sol | 4 +-- .../array/fixed_array_cleanup.sol | 2 +- .../array/fixed_arrays_in_constructors.sol | 4 +-- .../array/function_array_cross_calls.sol | 4 +-- ...nvalid_encoding_for_storage_byte_array.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 +- .../pop/byte_array_pop_long_storage_empty.sol | 4 +-- ...ray_pop_long_storage_empty_garbage_ref.sol | 4 +-- .../array/pop/byte_array_pop_masking_long.sol | 4 +-- .../semanticTests/array/push/array_push.sol | 2 +- .../push/array_push_nested_from_calldata.sol | 6 ++-- .../array/push/array_push_struct.sol | 4 +-- .../push/array_push_struct_from_calldata.sol | 4 +-- .../array/push/byte_array_push_transition.sol | 2 +- .../array/push/nested_bytes_push.sol | 4 +-- .../array/push/push_no_args_2d.sol | 6 ++-- .../array/push/push_no_args_bytes.sol | 2 +- .../semanticTests/array/reusing_memory.sol | 2 +- .../byte_array_to_storage_cleanup.sol | 4 +-- .../copy_from_calldata_removes_bytes_data.sol | 2 +- .../constructor/arrays_in_constructors.sol | 4 +-- .../bytes_in_constructors_packer.sol | 4 +-- .../bytes_in_constructors_unpacker.sol | 4 +-- .../constructor_arguments_external.sol | 4 +-- .../constructor_function_complex.sol | 2 +- .../constructor_static_array_argument.sol | 4 +-- .../constructor_inheritance_init_order_2.sol | 2 +- .../semanticTests/constructor_with_params.sol | 2 +- ...ructor_with_params_diamond_inheritance.sol | 4 +-- .../constructor_with_params_inheritance.sol | 4 +-- .../errors/small_error_optimization.sol | 6 ++-- .../events/event_dynamic_array_storage.sol | 4 +-- .../events/event_dynamic_array_storage_v2.sol | 4 +-- .../event_dynamic_nested_array_storage_v2.sol | 4 +-- .../events/event_emit_from_other_contract.sol | 4 +-- .../events/event_indexed_string.sol | 6 ++-- .../externalContracts/base64.sol | 8 ++--- .../externalContracts/deposit_contract.sol | 14 ++++----- .../externalContracts/prbmath_signed.sol | 4 +-- .../externalContracts/prbmath_unsigned.sol | 4 +-- .../externalContracts/ramanujan_pi.sol | 6 ++-- .../semanticTests/externalContracts/snark.sol | 12 ++++---- .../externalContracts/strings.sol | 8 ++--- .../creation_function_call_with_args.sol | 2 +- .../creation_function_call_with_salt.sol | 2 +- .../external_call_to_nonexisting.sol | 8 ++--- ...ernal_call_to_nonexisting_debugstrings.sol | 8 ++--- .../functionCall/failed_create.sol | 4 +-- .../functionCall/gas_and_value_basic.sol | 4 +-- .../gas_and_value_brace_syntax.sol | 4 +-- .../mapping_array_internal_argument.sol | 4 +-- .../functionTypes/store_function.sol | 4 +-- .../immutable/multi_creation.sol | 4 +-- .../semanticTests/immutable/use_scratch.sol | 2 +- ...d_function_calldata_calldata_interface.sol | 2 +- ...ted_function_calldata_memory_interface.sol | 4 +-- .../inheritance/member_notation_ctor.sol | 4 +-- .../inheritance/value_for_constructor.sol | 6 ++-- .../transient_storage_selfdestruct.sol | 12 ++++---- .../tstore_hidden_staticcall.sol | 4 +-- .../balance_other_contract.sol | 2 +- .../libraries/internal_types_in_library.sol | 4 +-- .../using_library_mappings_public.sol | 4 +-- .../using_library_mappings_return.sol | 4 +-- .../libraries/using_library_structs.sol | 2 +- .../operator_making_pure_external_call.sol | 6 ++-- .../operator_making_view_external_call.sol | 6 ++-- .../salted_create/prediction_example.sol | 2 +- .../salted_create_with_value.sol | 4 +-- .../semanticTests/smoke/constructor.sol | 4 +-- .../storage/empty_nonempty_empty.sol | 2 +- .../storage/packed_storage_structs_bytes.sol | 2 +- ...ta_struct_with_nested_array_to_storage.sol | 4 +-- .../conversion/recursive_storage_memory.sol | 4 +-- .../structs/copy_from_mapping.sol | 2 +- .../copy_struct_array_from_storage.sol | 4 +-- .../copy_substructures_from_mapping.sol | 2 +- .../structs/copy_substructures_to_mapping.sol | 12 ++++---- .../semanticTests/structs/copy_to_mapping.sol | 12 ++++---- .../structs/memory_structs_nested_load.sol | 2 +- ...truct_containing_bytes_copy_and_delete.sol | 12 ++++---- .../semanticTests/structs/struct_copy.sol | 6 ++-- .../struct_delete_storage_with_array.sol | 8 ++--- .../struct_memory_to_storage_function_ptr.sol | 2 +- .../semanticTests/structs/structs.sol | 2 +- .../mapping/copy_from_mapping_to_mapping.sol | 2 +- .../userDefinedValueType/calldata.sol | 10 +++---- .../userDefinedValueType/erc20.sol | 2 +- .../using/using_global_invisible.sol | 2 +- .../semanticTests/various/address_code.sol | 2 +- .../various/code_access_content.sol | 4 +-- .../various/code_access_create.sol | 2 +- .../various/code_access_runtime.sol | 2 +- .../semanticTests/various/code_length.sol | 4 +-- .../semanticTests/various/create_calldata.sol | 2 +- .../various/destructuring_assignment.sol | 4 +-- .../semanticTests/various/erc20.sol | 2 +- .../various/external_types_in_calls.sol | 2 +- .../various/selfdestruct_post_cancun.sol | 4 +-- ...uct_post_cancun_multiple_beneficiaries.sol | 6 ++-- .../selfdestruct_post_cancun_redeploy.sol | 10 +++---- .../semanticTests/various/senders_balance.sol | 2 +- .../skip_dynamic_types_for_structs.sol | 4 +-- .../various/staticcall_for_view_and_pure.sol | 8 ++--- .../various/swap_in_storage_overwrite.sol | 2 +- .../semanticTests/various/value_complex.sol | 4 +-- .../semanticTests/various/value_insane.sol | 2 +- .../viaYul/copy_struct_invalid_ir_bug.sol | 4 +-- test/libyul/objectCompiler/datacopy.yul | 6 ++-- .../libyul/objectCompiler/dataoffset_self.yul | 6 ++-- .../libyul/objectCompiler/sourceLocations.yul | 8 ++--- 198 files changed, 472 insertions(+), 566 deletions(-) diff --git a/test/cmdlineTests/asm_json/output b/test/cmdlineTests/asm_json/output index 38d9c9fdf5fe..820eda6ec4a6 100644 --- a/test/cmdlineTests/asm_json/output +++ b/test/cmdlineTests/asm_json/output @@ -64,8 +64,9 @@ EVM assembly: { "begin": 60, "end": 160, - "name": "DUP1", - "source": 0 + "name": "PUSH", + "source": 0, + "value": "0" }, { "begin": 60, @@ -204,8 +205,9 @@ EVM assembly: { "begin": 60, "end": 160, - "name": "DUP1", - "source": 0 + "name": "PUSH", + "source": 0, + "value": "0" }, { "begin": 60, @@ -345,8 +347,9 @@ EVM assembly: { "begin": 60, "end": 160, - "name": "DUP1", - "source": 0 + "name": "PUSH", + "source": 0, + "value": "0" }, { "begin": 60, @@ -622,8 +625,9 @@ EVM assembly: { "begin": 135, "end": 151, - "name": "DUP1", - "source": 0 + "name": "PUSH", + "source": 0, + "value": "0" }, { "begin": 135, @@ -680,8 +684,9 @@ EVM assembly: { "begin": 194, "end": 195, - "name": "DUP1", - "source": 1 + "name": "PUSH", + "source": 1, + "value": "0" }, { "begin": 187, @@ -840,8 +845,9 @@ EVM assembly: { "begin": 526, "end": 527, - "name": "DUP1", - "source": 1 + "name": "PUSH", + "source": 1, + "value": "0" }, { "begin": 519, diff --git a/test/cmdlineTests/asm_json_no_pretty_print/output b/test/cmdlineTests/asm_json_no_pretty_print/output index b713097bbc4c..8fce2f4827d9 100644 --- a/test/cmdlineTests/asm_json_no_pretty_print/output +++ b/test/cmdlineTests/asm_json_no_pretty_print/output @@ -1,4 +1,4 @@ ======= asm_json_no_pretty_print/input.sol:C ======= EVM assembly: -{".code":[{"begin":60,"end":160,"name":"PUSH","source":0,"value":"80"},{"begin":60,"end":160,"name":"PUSH","source":0,"value":"40"},{"begin":60,"end":160,"name":"MSTORE","source":0},{"begin":60,"end":160,"name":"CALLVALUE","source":0},{"begin":60,"end":160,"name":"DUP1","source":0},{"begin":60,"end":160,"name":"ISZERO","source":0},{"begin":60,"end":160,"name":"PUSH [tag]","source":0,"value":"1"},{"begin":60,"end":160,"name":"JUMPI","source":0},{"begin":60,"end":160,"name":"PUSH","source":0,"value":"0"},{"begin":60,"end":160,"name":"DUP1","source":0},{"begin":60,"end":160,"name":"REVERT","source":0},{"begin":60,"end":160,"name":"tag","source":0,"value":"1"},{"begin":60,"end":160,"name":"JUMPDEST","source":0},{"begin":60,"end":160,"name":"POP","source":0},{"begin":60,"end":160,"name":"PUSH #[$]","source":0,"value":"0000000000000000000000000000000000000000000000000000000000000000"},{"begin":60,"end":160,"name":"DUP1","source":0},{"begin":60,"end":160,"name":"PUSH [$]","source":0,"value":"0000000000000000000000000000000000000000000000000000000000000000"},{"begin":60,"end":160,"name":"PUSH","source":0,"value":"0"},{"begin":60,"end":160,"name":"CODECOPY","source":0},{"begin":60,"end":160,"name":"PUSH","source":0,"value":"0"},{"begin":60,"end":160,"name":"RETURN","source":0}],".data":{"0":{".auxdata":"",".code":[{"begin":60,"end":160,"name":"PUSH","source":0,"value":"80"},{"begin":60,"end":160,"name":"PUSH","source":0,"value":"40"},{"begin":60,"end":160,"name":"MSTORE","source":0},{"begin":60,"end":160,"name":"CALLVALUE","source":0},{"begin":60,"end":160,"name":"DUP1","source":0},{"begin":60,"end":160,"name":"ISZERO","source":0},{"begin":60,"end":160,"name":"PUSH [tag]","source":0,"value":"1"},{"begin":60,"end":160,"name":"JUMPI","source":0},{"begin":60,"end":160,"name":"PUSH","source":0,"value":"0"},{"begin":60,"end":160,"name":"DUP1","source":0},{"begin":60,"end":160,"name":"REVERT","source":0},{"begin":60,"end":160,"name":"tag","source":0,"value":"1"},{"begin":60,"end":160,"name":"JUMPDEST","source":0},{"begin":60,"end":160,"name":"POP","source":0},{"begin":60,"end":160,"name":"PUSH","source":0,"value":"4"},{"begin":60,"end":160,"name":"CALLDATASIZE","source":0},{"begin":60,"end":160,"name":"LT","source":0},{"begin":60,"end":160,"name":"PUSH [tag]","source":0,"value":"2"},{"begin":60,"end":160,"name":"JUMPI","source":0},{"begin":60,"end":160,"name":"PUSH","source":0,"value":"0"},{"begin":60,"end":160,"name":"CALLDATALOAD","source":0},{"begin":60,"end":160,"name":"PUSH","source":0,"value":"E0"},{"begin":60,"end":160,"name":"SHR","source":0},{"begin":60,"end":160,"name":"DUP1","source":0},{"begin":60,"end":160,"name":"PUSH","source":0,"value":"B3DE648B"},{"begin":60,"end":160,"name":"EQ","source":0},{"begin":60,"end":160,"name":"PUSH [tag]","source":0,"value":"3"},{"begin":60,"end":160,"name":"JUMPI","source":0},{"begin":60,"end":160,"name":"tag","source":0,"value":"2"},{"begin":60,"end":160,"name":"JUMPDEST","source":0},{"begin":60,"end":160,"name":"PUSH","source":0,"value":"0"},{"begin":60,"end":160,"name":"DUP1","source":0},{"begin":60,"end":160,"name":"REVERT","source":0},{"begin":77,"end":158,"name":"tag","source":0,"value":"3"},{"begin":77,"end":158,"name":"JUMPDEST","source":0},{"begin":77,"end":158,"name":"PUSH [tag]","source":0,"value":"4"},{"begin":77,"end":158,"name":"PUSH","source":0,"value":"4"},{"begin":77,"end":158,"name":"DUP1","source":0},{"begin":77,"end":158,"name":"CALLDATASIZE","source":0},{"begin":77,"end":158,"name":"SUB","source":0},{"begin":77,"end":158,"name":"DUP2","source":0},{"begin":77,"end":158,"name":"ADD","source":0},{"begin":77,"end":158,"name":"SWAP1","source":0},{"begin":77,"end":158,"name":"PUSH [tag]","source":0,"value":"5"},{"begin":77,"end":158,"name":"SWAP2","source":0},{"begin":77,"end":158,"name":"SWAP1","source":0},{"begin":77,"end":158,"name":"PUSH [tag]","source":0,"value":"6"},{"begin":77,"end":158,"jumpType":"[in]","name":"JUMP","source":0},{"begin":77,"end":158,"name":"tag","source":0,"value":"5"},{"begin":77,"end":158,"name":"JUMPDEST","source":0},{"begin":77,"end":158,"name":"PUSH [tag]","source":0,"value":"7"},{"begin":77,"end":158,"jumpType":"[in]","name":"JUMP","source":0},{"begin":77,"end":158,"name":"tag","source":0,"value":"4"},{"begin":77,"end":158,"name":"JUMPDEST","source":0},{"begin":77,"end":158,"name":"STOP","source":0},{"begin":77,"end":158,"name":"tag","source":0,"value":"7"},{"begin":77,"end":158,"name":"JUMPDEST","source":0},{"begin":123,"end":125,"name":"PUSH","source":0,"value":"2A"},{"begin":118,"end":125,"name":"DUP2","source":0},{"begin":118,"end":125,"name":"PUSH [tag]","source":0,"value":"9"},{"begin":118,"end":125,"name":"SWAP2","source":0},{"begin":118,"end":125,"name":"SWAP1","source":0},{"begin":118,"end":125,"name":"PUSH [tag]","source":0,"value":"10"},{"begin":118,"end":125,"jumpType":"[in]","name":"JUMP","source":0},{"begin":118,"end":125,"name":"tag","source":0,"value":"9"},{"begin":118,"end":125,"name":"JUMPDEST","source":0},{"begin":118,"end":125,"name":"SWAP1","source":0},{"begin":118,"end":125,"name":"POP","source":0},{"begin":147,"end":150,"name":"PUSH","source":0,"value":"64"},{"begin":143,"end":144,"name":"DUP2","source":0},{"begin":143,"end":150,"name":"GT","source":0},{"begin":135,"end":151,"name":"PUSH [tag]","source":0,"value":"11"},{"begin":135,"end":151,"name":"JUMPI","source":0},{"begin":135,"end":151,"name":"PUSH","source":0,"value":"0"},{"begin":135,"end":151,"name":"DUP1","source":0},{"begin":135,"end":151,"name":"REVERT","source":0},{"begin":135,"end":151,"name":"tag","source":0,"value":"11"},{"begin":135,"end":151,"name":"JUMPDEST","source":0},{"begin":77,"end":158,"name":"POP","source":0},{"begin":77,"end":158,"jumpType":"[out]","name":"JUMP","source":0},{"begin":88,"end":205,"name":"tag","source":1,"value":"13"},{"begin":88,"end":205,"name":"JUMPDEST","source":1},{"begin":197,"end":198,"name":"PUSH","source":1,"value":"0"},{"begin":194,"end":195,"name":"DUP1","source":1},{"begin":187,"end":199,"name":"REVERT","source":1},{"begin":334,"end":411,"name":"tag","source":1,"value":"15"},{"begin":334,"end":411,"name":"JUMPDEST","source":1},{"begin":371,"end":378,"name":"PUSH","source":1,"value":"0"},{"begin":400,"end":405,"name":"DUP2","source":1},{"begin":389,"end":405,"name":"SWAP1","source":1},{"begin":389,"end":405,"name":"POP","source":1},{"begin":334,"end":411,"name":"SWAP2","source":1},{"begin":334,"end":411,"name":"SWAP1","source":1},{"begin":334,"end":411,"name":"POP","source":1},{"begin":334,"end":411,"jumpType":"[out]","name":"JUMP","source":1},{"begin":417,"end":539,"name":"tag","source":1,"value":"16"},{"begin":417,"end":539,"name":"JUMPDEST","source":1},{"begin":490,"end":514,"name":"PUSH [tag]","source":1,"value":"25"},{"begin":508,"end":513,"name":"DUP2","source":1},{"begin":490,"end":514,"name":"PUSH [tag]","source":1,"value":"15"},{"begin":490,"end":514,"jumpType":"[in]","name":"JUMP","source":1},{"begin":490,"end":514,"name":"tag","source":1,"value":"25"},{"begin":490,"end":514,"name":"JUMPDEST","source":1},{"begin":483,"end":488,"name":"DUP2","source":1},{"begin":480,"end":515,"name":"EQ","source":1},{"begin":470,"end":533,"name":"PUSH [tag]","source":1,"value":"26"},{"begin":470,"end":533,"name":"JUMPI","source":1},{"begin":529,"end":530,"name":"PUSH","source":1,"value":"0"},{"begin":526,"end":527,"name":"DUP1","source":1},{"begin":519,"end":531,"name":"REVERT","source":1},{"begin":470,"end":533,"name":"tag","source":1,"value":"26"},{"begin":470,"end":533,"name":"JUMPDEST","source":1},{"begin":417,"end":539,"name":"POP","source":1},{"begin":417,"end":539,"jumpType":"[out]","name":"JUMP","source":1},{"begin":545,"end":684,"name":"tag","source":1,"value":"17"},{"begin":545,"end":684,"name":"JUMPDEST","source":1},{"begin":591,"end":596,"name":"PUSH","source":1,"value":"0"},{"begin":629,"end":635,"name":"DUP2","source":1},{"begin":616,"end":636,"name":"CALLDATALOAD","source":1},{"begin":607,"end":636,"name":"SWAP1","source":1},{"begin":607,"end":636,"name":"POP","source":1},{"begin":645,"end":678,"name":"PUSH [tag]","source":1,"value":"28"},{"begin":672,"end":677,"name":"DUP2","source":1},{"begin":645,"end":678,"name":"PUSH [tag]","source":1,"value":"16"},{"begin":645,"end":678,"jumpType":"[in]","name":"JUMP","source":1},{"begin":645,"end":678,"name":"tag","source":1,"value":"28"},{"begin":645,"end":678,"name":"JUMPDEST","source":1},{"begin":545,"end":684,"name":"SWAP3","source":1},{"begin":545,"end":684,"name":"SWAP2","source":1},{"begin":545,"end":684,"name":"POP","source":1},{"begin":545,"end":684,"name":"POP","source":1},{"begin":545,"end":684,"jumpType":"[out]","name":"JUMP","source":1},{"begin":690,"end":1019,"name":"tag","source":1,"value":"6"},{"begin":690,"end":1019,"name":"JUMPDEST","source":1},{"begin":749,"end":755,"name":"PUSH","source":1,"value":"0"},{"begin":798,"end":800,"name":"PUSH","source":1,"value":"20"},{"begin":786,"end":795,"name":"DUP3","source":1},{"begin":777,"end":784,"name":"DUP5","source":1},{"begin":773,"end":796,"name":"SUB","source":1},{"begin":769,"end":801,"name":"SLT","source":1},{"begin":766,"end":885,"name":"ISZERO","source":1},{"begin":766,"end":885,"name":"PUSH [tag]","source":1,"value":"30"},{"begin":766,"end":885,"name":"JUMPI","source":1},{"begin":804,"end":883,"name":"PUSH [tag]","source":1,"value":"31"},{"begin":804,"end":883,"name":"PUSH [tag]","source":1,"value":"13"},{"begin":804,"end":883,"jumpType":"[in]","name":"JUMP","source":1},{"begin":804,"end":883,"name":"tag","source":1,"value":"31"},{"begin":804,"end":883,"name":"JUMPDEST","source":1},{"begin":766,"end":885,"name":"tag","source":1,"value":"30"},{"begin":766,"end":885,"name":"JUMPDEST","source":1},{"begin":924,"end":925,"name":"PUSH","source":1,"value":"0"},{"begin":949,"end":1002,"name":"PUSH [tag]","source":1,"value":"32"},{"begin":994,"end":1001,"name":"DUP5","source":1},{"begin":985,"end":991,"name":"DUP3","source":1},{"begin":974,"end":983,"name":"DUP6","source":1},{"begin":970,"end":992,"name":"ADD","source":1},{"begin":949,"end":1002,"name":"PUSH [tag]","source":1,"value":"17"},{"begin":949,"end":1002,"jumpType":"[in]","name":"JUMP","source":1},{"begin":949,"end":1002,"name":"tag","source":1,"value":"32"},{"begin":949,"end":1002,"name":"JUMPDEST","source":1},{"begin":939,"end":1002,"name":"SWAP2","source":1},{"begin":939,"end":1002,"name":"POP","source":1},{"begin":895,"end":1012,"name":"POP","source":1},{"begin":690,"end":1019,"name":"SWAP3","source":1},{"begin":690,"end":1019,"name":"SWAP2","source":1},{"begin":690,"end":1019,"name":"POP","source":1},{"begin":690,"end":1019,"name":"POP","source":1},{"begin":690,"end":1019,"jumpType":"[out]","name":"JUMP","source":1},{"begin":1025,"end":1205,"name":"tag","source":1,"value":"18"},{"begin":1025,"end":1205,"name":"JUMPDEST","source":1},{"begin":1073,"end":1150,"name":"PUSH","source":1,"value":"4E487B7100000000000000000000000000000000000000000000000000000000"},{"begin":1070,"end":1071,"name":"PUSH","source":1,"value":"0"},{"begin":1063,"end":1151,"name":"MSTORE","source":1},{"begin":1170,"end":1174,"name":"PUSH","source":1,"value":"11"},{"begin":1167,"end":1168,"name":"PUSH","source":1,"value":"4"},{"begin":1160,"end":1175,"name":"MSTORE","source":1},{"begin":1194,"end":1198,"name":"PUSH","source":1,"value":"24"},{"begin":1191,"end":1192,"name":"PUSH","source":1,"value":"0"},{"begin":1184,"end":1199,"name":"REVERT","source":1},{"begin":1211,"end":1402,"name":"tag","source":1,"value":"10"},{"begin":1211,"end":1402,"name":"JUMPDEST","source":1},{"begin":1251,"end":1254,"name":"PUSH","source":1,"value":"0"},{"begin":1270,"end":1290,"name":"PUSH [tag]","source":1,"value":"35"},{"begin":1288,"end":1289,"name":"DUP3","source":1},{"begin":1270,"end":1290,"name":"PUSH [tag]","source":1,"value":"15"},{"begin":1270,"end":1290,"jumpType":"[in]","name":"JUMP","source":1},{"begin":1270,"end":1290,"name":"tag","source":1,"value":"35"},{"begin":1270,"end":1290,"name":"JUMPDEST","source":1},{"begin":1265,"end":1290,"name":"SWAP2","source":1},{"begin":1265,"end":1290,"name":"POP","source":1},{"begin":1304,"end":1324,"name":"PUSH [tag]","source":1,"value":"36"},{"begin":1322,"end":1323,"name":"DUP4","source":1},{"begin":1304,"end":1324,"name":"PUSH [tag]","source":1,"value":"15"},{"begin":1304,"end":1324,"jumpType":"[in]","name":"JUMP","source":1},{"begin":1304,"end":1324,"name":"tag","source":1,"value":"36"},{"begin":1304,"end":1324,"name":"JUMPDEST","source":1},{"begin":1299,"end":1324,"name":"SWAP3","source":1},{"begin":1299,"end":1324,"name":"POP","source":1},{"begin":1347,"end":1348,"name":"DUP3","source":1},{"begin":1344,"end":1345,"name":"DUP3","source":1},{"begin":1340,"end":1349,"name":"ADD","source":1},{"begin":1333,"end":1349,"name":"SWAP1","source":1},{"begin":1333,"end":1349,"name":"POP","source":1},{"begin":1368,"end":1371,"name":"DUP1","source":1},{"begin":1365,"end":1366,"name":"DUP3","source":1},{"begin":1362,"end":1372,"name":"GT","source":1},{"begin":1359,"end":1395,"name":"ISZERO","source":1},{"begin":1359,"end":1395,"name":"PUSH [tag]","source":1,"value":"37"},{"begin":1359,"end":1395,"name":"JUMPI","source":1},{"begin":1375,"end":1393,"name":"PUSH [tag]","source":1,"value":"38"},{"begin":1375,"end":1393,"name":"PUSH [tag]","source":1,"value":"18"},{"begin":1375,"end":1393,"jumpType":"[in]","name":"JUMP","source":1},{"begin":1375,"end":1393,"name":"tag","source":1,"value":"38"},{"begin":1375,"end":1393,"name":"JUMPDEST","source":1},{"begin":1359,"end":1395,"name":"tag","source":1,"value":"37"},{"begin":1359,"end":1395,"name":"JUMPDEST","source":1},{"begin":1211,"end":1402,"name":"SWAP3","source":1},{"begin":1211,"end":1402,"name":"SWAP2","source":1},{"begin":1211,"end":1402,"name":"POP","source":1},{"begin":1211,"end":1402,"name":"POP","source":1},{"begin":1211,"end":1402,"jumpType":"[out]","name":"JUMP","source":1}]}},"sourceList":["asm_json_no_pretty_print/input.sol","#utility.yul"]} +{".code":[{"begin":60,"end":160,"name":"PUSH","source":0,"value":"80"},{"begin":60,"end":160,"name":"PUSH","source":0,"value":"40"},{"begin":60,"end":160,"name":"MSTORE","source":0},{"begin":60,"end":160,"name":"CALLVALUE","source":0},{"begin":60,"end":160,"name":"DUP1","source":0},{"begin":60,"end":160,"name":"ISZERO","source":0},{"begin":60,"end":160,"name":"PUSH [tag]","source":0,"value":"1"},{"begin":60,"end":160,"name":"JUMPI","source":0},{"begin":60,"end":160,"name":"PUSH","source":0,"value":"0"},{"begin":60,"end":160,"name":"PUSH","source":0,"value":"0"},{"begin":60,"end":160,"name":"REVERT","source":0},{"begin":60,"end":160,"name":"tag","source":0,"value":"1"},{"begin":60,"end":160,"name":"JUMPDEST","source":0},{"begin":60,"end":160,"name":"POP","source":0},{"begin":60,"end":160,"name":"PUSH #[$]","source":0,"value":"0000000000000000000000000000000000000000000000000000000000000000"},{"begin":60,"end":160,"name":"DUP1","source":0},{"begin":60,"end":160,"name":"PUSH [$]","source":0,"value":"0000000000000000000000000000000000000000000000000000000000000000"},{"begin":60,"end":160,"name":"PUSH","source":0,"value":"0"},{"begin":60,"end":160,"name":"CODECOPY","source":0},{"begin":60,"end":160,"name":"PUSH","source":0,"value":"0"},{"begin":60,"end":160,"name":"RETURN","source":0}],".data":{"0":{".auxdata":"",".code":[{"begin":60,"end":160,"name":"PUSH","source":0,"value":"80"},{"begin":60,"end":160,"name":"PUSH","source":0,"value":"40"},{"begin":60,"end":160,"name":"MSTORE","source":0},{"begin":60,"end":160,"name":"CALLVALUE","source":0},{"begin":60,"end":160,"name":"DUP1","source":0},{"begin":60,"end":160,"name":"ISZERO","source":0},{"begin":60,"end":160,"name":"PUSH [tag]","source":0,"value":"1"},{"begin":60,"end":160,"name":"JUMPI","source":0},{"begin":60,"end":160,"name":"PUSH","source":0,"value":"0"},{"begin":60,"end":160,"name":"PUSH","source":0,"value":"0"},{"begin":60,"end":160,"name":"REVERT","source":0},{"begin":60,"end":160,"name":"tag","source":0,"value":"1"},{"begin":60,"end":160,"name":"JUMPDEST","source":0},{"begin":60,"end":160,"name":"POP","source":0},{"begin":60,"end":160,"name":"PUSH","source":0,"value":"4"},{"begin":60,"end":160,"name":"CALLDATASIZE","source":0},{"begin":60,"end":160,"name":"LT","source":0},{"begin":60,"end":160,"name":"PUSH [tag]","source":0,"value":"2"},{"begin":60,"end":160,"name":"JUMPI","source":0},{"begin":60,"end":160,"name":"PUSH","source":0,"value":"0"},{"begin":60,"end":160,"name":"CALLDATALOAD","source":0},{"begin":60,"end":160,"name":"PUSH","source":0,"value":"E0"},{"begin":60,"end":160,"name":"SHR","source":0},{"begin":60,"end":160,"name":"DUP1","source":0},{"begin":60,"end":160,"name":"PUSH","source":0,"value":"B3DE648B"},{"begin":60,"end":160,"name":"EQ","source":0},{"begin":60,"end":160,"name":"PUSH [tag]","source":0,"value":"3"},{"begin":60,"end":160,"name":"JUMPI","source":0},{"begin":60,"end":160,"name":"tag","source":0,"value":"2"},{"begin":60,"end":160,"name":"JUMPDEST","source":0},{"begin":60,"end":160,"name":"PUSH","source":0,"value":"0"},{"begin":60,"end":160,"name":"PUSH","source":0,"value":"0"},{"begin":60,"end":160,"name":"REVERT","source":0},{"begin":77,"end":158,"name":"tag","source":0,"value":"3"},{"begin":77,"end":158,"name":"JUMPDEST","source":0},{"begin":77,"end":158,"name":"PUSH [tag]","source":0,"value":"4"},{"begin":77,"end":158,"name":"PUSH","source":0,"value":"4"},{"begin":77,"end":158,"name":"DUP1","source":0},{"begin":77,"end":158,"name":"CALLDATASIZE","source":0},{"begin":77,"end":158,"name":"SUB","source":0},{"begin":77,"end":158,"name":"DUP2","source":0},{"begin":77,"end":158,"name":"ADD","source":0},{"begin":77,"end":158,"name":"SWAP1","source":0},{"begin":77,"end":158,"name":"PUSH [tag]","source":0,"value":"5"},{"begin":77,"end":158,"name":"SWAP2","source":0},{"begin":77,"end":158,"name":"SWAP1","source":0},{"begin":77,"end":158,"name":"PUSH [tag]","source":0,"value":"6"},{"begin":77,"end":158,"jumpType":"[in]","name":"JUMP","source":0},{"begin":77,"end":158,"name":"tag","source":0,"value":"5"},{"begin":77,"end":158,"name":"JUMPDEST","source":0},{"begin":77,"end":158,"name":"PUSH [tag]","source":0,"value":"7"},{"begin":77,"end":158,"jumpType":"[in]","name":"JUMP","source":0},{"begin":77,"end":158,"name":"tag","source":0,"value":"4"},{"begin":77,"end":158,"name":"JUMPDEST","source":0},{"begin":77,"end":158,"name":"STOP","source":0},{"begin":77,"end":158,"name":"tag","source":0,"value":"7"},{"begin":77,"end":158,"name":"JUMPDEST","source":0},{"begin":123,"end":125,"name":"PUSH","source":0,"value":"2A"},{"begin":118,"end":125,"name":"DUP2","source":0},{"begin":118,"end":125,"name":"PUSH [tag]","source":0,"value":"9"},{"begin":118,"end":125,"name":"SWAP2","source":0},{"begin":118,"end":125,"name":"SWAP1","source":0},{"begin":118,"end":125,"name":"PUSH [tag]","source":0,"value":"10"},{"begin":118,"end":125,"jumpType":"[in]","name":"JUMP","source":0},{"begin":118,"end":125,"name":"tag","source":0,"value":"9"},{"begin":118,"end":125,"name":"JUMPDEST","source":0},{"begin":118,"end":125,"name":"SWAP1","source":0},{"begin":118,"end":125,"name":"POP","source":0},{"begin":147,"end":150,"name":"PUSH","source":0,"value":"64"},{"begin":143,"end":144,"name":"DUP2","source":0},{"begin":143,"end":150,"name":"GT","source":0},{"begin":135,"end":151,"name":"PUSH [tag]","source":0,"value":"11"},{"begin":135,"end":151,"name":"JUMPI","source":0},{"begin":135,"end":151,"name":"PUSH","source":0,"value":"0"},{"begin":135,"end":151,"name":"PUSH","source":0,"value":"0"},{"begin":135,"end":151,"name":"REVERT","source":0},{"begin":135,"end":151,"name":"tag","source":0,"value":"11"},{"begin":135,"end":151,"name":"JUMPDEST","source":0},{"begin":77,"end":158,"name":"POP","source":0},{"begin":77,"end":158,"jumpType":"[out]","name":"JUMP","source":0},{"begin":88,"end":205,"name":"tag","source":1,"value":"13"},{"begin":88,"end":205,"name":"JUMPDEST","source":1},{"begin":197,"end":198,"name":"PUSH","source":1,"value":"0"},{"begin":194,"end":195,"name":"PUSH","source":1,"value":"0"},{"begin":187,"end":199,"name":"REVERT","source":1},{"begin":334,"end":411,"name":"tag","source":1,"value":"15"},{"begin":334,"end":411,"name":"JUMPDEST","source":1},{"begin":371,"end":378,"name":"PUSH","source":1,"value":"0"},{"begin":400,"end":405,"name":"DUP2","source":1},{"begin":389,"end":405,"name":"SWAP1","source":1},{"begin":389,"end":405,"name":"POP","source":1},{"begin":334,"end":411,"name":"SWAP2","source":1},{"begin":334,"end":411,"name":"SWAP1","source":1},{"begin":334,"end":411,"name":"POP","source":1},{"begin":334,"end":411,"jumpType":"[out]","name":"JUMP","source":1},{"begin":417,"end":539,"name":"tag","source":1,"value":"16"},{"begin":417,"end":539,"name":"JUMPDEST","source":1},{"begin":490,"end":514,"name":"PUSH [tag]","source":1,"value":"25"},{"begin":508,"end":513,"name":"DUP2","source":1},{"begin":490,"end":514,"name":"PUSH [tag]","source":1,"value":"15"},{"begin":490,"end":514,"jumpType":"[in]","name":"JUMP","source":1},{"begin":490,"end":514,"name":"tag","source":1,"value":"25"},{"begin":490,"end":514,"name":"JUMPDEST","source":1},{"begin":483,"end":488,"name":"DUP2","source":1},{"begin":480,"end":515,"name":"EQ","source":1},{"begin":470,"end":533,"name":"PUSH [tag]","source":1,"value":"26"},{"begin":470,"end":533,"name":"JUMPI","source":1},{"begin":529,"end":530,"name":"PUSH","source":1,"value":"0"},{"begin":526,"end":527,"name":"PUSH","source":1,"value":"0"},{"begin":519,"end":531,"name":"REVERT","source":1},{"begin":470,"end":533,"name":"tag","source":1,"value":"26"},{"begin":470,"end":533,"name":"JUMPDEST","source":1},{"begin":417,"end":539,"name":"POP","source":1},{"begin":417,"end":539,"jumpType":"[out]","name":"JUMP","source":1},{"begin":545,"end":684,"name":"tag","source":1,"value":"17"},{"begin":545,"end":684,"name":"JUMPDEST","source":1},{"begin":591,"end":596,"name":"PUSH","source":1,"value":"0"},{"begin":629,"end":635,"name":"DUP2","source":1},{"begin":616,"end":636,"name":"CALLDATALOAD","source":1},{"begin":607,"end":636,"name":"SWAP1","source":1},{"begin":607,"end":636,"name":"POP","source":1},{"begin":645,"end":678,"name":"PUSH [tag]","source":1,"value":"28"},{"begin":672,"end":677,"name":"DUP2","source":1},{"begin":645,"end":678,"name":"PUSH [tag]","source":1,"value":"16"},{"begin":645,"end":678,"jumpType":"[in]","name":"JUMP","source":1},{"begin":645,"end":678,"name":"tag","source":1,"value":"28"},{"begin":645,"end":678,"name":"JUMPDEST","source":1},{"begin":545,"end":684,"name":"SWAP3","source":1},{"begin":545,"end":684,"name":"SWAP2","source":1},{"begin":545,"end":684,"name":"POP","source":1},{"begin":545,"end":684,"name":"POP","source":1},{"begin":545,"end":684,"jumpType":"[out]","name":"JUMP","source":1},{"begin":690,"end":1019,"name":"tag","source":1,"value":"6"},{"begin":690,"end":1019,"name":"JUMPDEST","source":1},{"begin":749,"end":755,"name":"PUSH","source":1,"value":"0"},{"begin":798,"end":800,"name":"PUSH","source":1,"value":"20"},{"begin":786,"end":795,"name":"DUP3","source":1},{"begin":777,"end":784,"name":"DUP5","source":1},{"begin":773,"end":796,"name":"SUB","source":1},{"begin":769,"end":801,"name":"SLT","source":1},{"begin":766,"end":885,"name":"ISZERO","source":1},{"begin":766,"end":885,"name":"PUSH [tag]","source":1,"value":"30"},{"begin":766,"end":885,"name":"JUMPI","source":1},{"begin":804,"end":883,"name":"PUSH [tag]","source":1,"value":"31"},{"begin":804,"end":883,"name":"PUSH [tag]","source":1,"value":"13"},{"begin":804,"end":883,"jumpType":"[in]","name":"JUMP","source":1},{"begin":804,"end":883,"name":"tag","source":1,"value":"31"},{"begin":804,"end":883,"name":"JUMPDEST","source":1},{"begin":766,"end":885,"name":"tag","source":1,"value":"30"},{"begin":766,"end":885,"name":"JUMPDEST","source":1},{"begin":924,"end":925,"name":"PUSH","source":1,"value":"0"},{"begin":949,"end":1002,"name":"PUSH [tag]","source":1,"value":"32"},{"begin":994,"end":1001,"name":"DUP5","source":1},{"begin":985,"end":991,"name":"DUP3","source":1},{"begin":974,"end":983,"name":"DUP6","source":1},{"begin":970,"end":992,"name":"ADD","source":1},{"begin":949,"end":1002,"name":"PUSH [tag]","source":1,"value":"17"},{"begin":949,"end":1002,"jumpType":"[in]","name":"JUMP","source":1},{"begin":949,"end":1002,"name":"tag","source":1,"value":"32"},{"begin":949,"end":1002,"name":"JUMPDEST","source":1},{"begin":939,"end":1002,"name":"SWAP2","source":1},{"begin":939,"end":1002,"name":"POP","source":1},{"begin":895,"end":1012,"name":"POP","source":1},{"begin":690,"end":1019,"name":"SWAP3","source":1},{"begin":690,"end":1019,"name":"SWAP2","source":1},{"begin":690,"end":1019,"name":"POP","source":1},{"begin":690,"end":1019,"name":"POP","source":1},{"begin":690,"end":1019,"jumpType":"[out]","name":"JUMP","source":1},{"begin":1025,"end":1205,"name":"tag","source":1,"value":"18"},{"begin":1025,"end":1205,"name":"JUMPDEST","source":1},{"begin":1073,"end":1150,"name":"PUSH","source":1,"value":"4E487B7100000000000000000000000000000000000000000000000000000000"},{"begin":1070,"end":1071,"name":"PUSH","source":1,"value":"0"},{"begin":1063,"end":1151,"name":"MSTORE","source":1},{"begin":1170,"end":1174,"name":"PUSH","source":1,"value":"11"},{"begin":1167,"end":1168,"name":"PUSH","source":1,"value":"4"},{"begin":1160,"end":1175,"name":"MSTORE","source":1},{"begin":1194,"end":1198,"name":"PUSH","source":1,"value":"24"},{"begin":1191,"end":1192,"name":"PUSH","source":1,"value":"0"},{"begin":1184,"end":1199,"name":"REVERT","source":1},{"begin":1211,"end":1402,"name":"tag","source":1,"value":"10"},{"begin":1211,"end":1402,"name":"JUMPDEST","source":1},{"begin":1251,"end":1254,"name":"PUSH","source":1,"value":"0"},{"begin":1270,"end":1290,"name":"PUSH [tag]","source":1,"value":"35"},{"begin":1288,"end":1289,"name":"DUP3","source":1},{"begin":1270,"end":1290,"name":"PUSH [tag]","source":1,"value":"15"},{"begin":1270,"end":1290,"jumpType":"[in]","name":"JUMP","source":1},{"begin":1270,"end":1290,"name":"tag","source":1,"value":"35"},{"begin":1270,"end":1290,"name":"JUMPDEST","source":1},{"begin":1265,"end":1290,"name":"SWAP2","source":1},{"begin":1265,"end":1290,"name":"POP","source":1},{"begin":1304,"end":1324,"name":"PUSH [tag]","source":1,"value":"36"},{"begin":1322,"end":1323,"name":"DUP4","source":1},{"begin":1304,"end":1324,"name":"PUSH [tag]","source":1,"value":"15"},{"begin":1304,"end":1324,"jumpType":"[in]","name":"JUMP","source":1},{"begin":1304,"end":1324,"name":"tag","source":1,"value":"36"},{"begin":1304,"end":1324,"name":"JUMPDEST","source":1},{"begin":1299,"end":1324,"name":"SWAP3","source":1},{"begin":1299,"end":1324,"name":"POP","source":1},{"begin":1347,"end":1348,"name":"DUP3","source":1},{"begin":1344,"end":1345,"name":"DUP3","source":1},{"begin":1340,"end":1349,"name":"ADD","source":1},{"begin":1333,"end":1349,"name":"SWAP1","source":1},{"begin":1333,"end":1349,"name":"POP","source":1},{"begin":1368,"end":1371,"name":"DUP1","source":1},{"begin":1365,"end":1366,"name":"DUP3","source":1},{"begin":1362,"end":1372,"name":"GT","source":1},{"begin":1359,"end":1395,"name":"ISZERO","source":1},{"begin":1359,"end":1395,"name":"PUSH [tag]","source":1,"value":"37"},{"begin":1359,"end":1395,"name":"JUMPI","source":1},{"begin":1375,"end":1393,"name":"PUSH [tag]","source":1,"value":"38"},{"begin":1375,"end":1393,"name":"PUSH [tag]","source":1,"value":"18"},{"begin":1375,"end":1393,"jumpType":"[in]","name":"JUMP","source":1},{"begin":1375,"end":1393,"name":"tag","source":1,"value":"38"},{"begin":1375,"end":1393,"name":"JUMPDEST","source":1},{"begin":1359,"end":1395,"name":"tag","source":1,"value":"37"},{"begin":1359,"end":1395,"name":"JUMPDEST","source":1},{"begin":1211,"end":1402,"name":"SWAP3","source":1},{"begin":1211,"end":1402,"name":"SWAP2","source":1},{"begin":1211,"end":1402,"name":"POP","source":1},{"begin":1211,"end":1402,"name":"POP","source":1},{"begin":1211,"end":1402,"jumpType":"[out]","name":"JUMP","source":1}]}},"sourceList":["asm_json_no_pretty_print/input.sol","#utility.yul"]} 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 a232fed8fc3b..4833a9f620a7 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 @@ -8,9 +8,7 @@ EVM assembly: iszero tag_1 jumpi - 0x00 - dup1 - revert + revert(0x00, 0x00) tag_1: pop dataSize(sub_0) @@ -30,9 +28,7 @@ sub_0: assembly { iszero tag_1 jumpi - 0x00 - dup1 - revert + revert(0x00, 0x00) tag_1: pop jumpi(tag_2, lt(calldatasize, 0x04)) @@ -43,9 +39,7 @@ sub_0: assembly { tag_3 jumpi tag_2: - 0x00 - dup1 - revert + revert(0x00, 0x00) /* "debug_info_in_yul_and_evm_asm_print_all/input.sol":77:99 function f() public {} */ tag_3: stop 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 00a6b290f826..00b04a01ad1f 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 @@ -8,9 +8,7 @@ EVM assembly: iszero tag_1 jumpi - 0x00 - dup1 - revert + revert(0x00, 0x00) tag_1: pop dataSize(sub_0) @@ -30,9 +28,7 @@ sub_0: assembly { iszero tag_1 jumpi - 0x00 - dup1 - revert + revert(0x00, 0x00) tag_1: pop jumpi(tag_2, lt(calldatasize, 0x04)) @@ -43,9 +39,7 @@ sub_0: assembly { tag_3 jumpi tag_2: - 0x00 - dup1 - revert + revert(0x00, 0x00) /* "debug_info_in_yul_and_evm_asm_print_location_only/input.sol":77:99 */ tag_3: stop 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 c8715df15051..9527edf769a4 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 @@ -7,9 +7,7 @@ EVM assembly: iszero tag_1 jumpi - 0x00 - dup1 - revert + revert(0x00, 0x00) tag_1: pop dataSize(sub_0) @@ -28,9 +26,7 @@ sub_0: assembly { iszero tag_1 jumpi - 0x00 - dup1 - revert + revert(0x00, 0x00) tag_1: pop jumpi(tag_2, lt(calldatasize, 0x04)) @@ -41,9 +37,7 @@ sub_0: assembly { tag_3 jumpi tag_2: - 0x00 - dup1 - revert + revert(0x00, 0x00) tag_3: stop diff --git a/test/cmdlineTests/dup_opt_peephole/output b/test/cmdlineTests/dup_opt_peephole/output index 2f75f2bdda9f..a9e0203ed1ff 100644 --- a/test/cmdlineTests/dup_opt_peephole/output +++ b/test/cmdlineTests/dup_opt_peephole/output @@ -8,9 +8,7 @@ EVM assembly: iszero tag_1 jumpi - 0x00 - dup1 - revert + revert(0x00, 0x00) tag_1: pop dataSize(sub_0) @@ -30,9 +28,7 @@ sub_0: assembly { iszero tag_3 jumpi - 0x00 - dup1 - revert + revert(0x00, 0x00) tag_3: pop /* "dup_opt_peephole/input.sol":134:135 0 */ diff --git a/test/cmdlineTests/optimize_full_storage_write/output b/test/cmdlineTests/optimize_full_storage_write/output index 1a73220308cb..9ebec71f0320 100644 --- a/test/cmdlineTests/optimize_full_storage_write/output +++ b/test/cmdlineTests/optimize_full_storage_write/output @@ -8,9 +8,7 @@ EVM assembly: iszero tag_1 jumpi - 0x00 - dup1 - revert + revert(0x00, 0x00) tag_1: pop dataSize(sub_0) @@ -30,9 +28,7 @@ sub_0: assembly { iszero tag_1 jumpi - 0x00 - dup1 - revert + revert(0x00, 0x00) tag_1: pop jumpi(tag_2, lt(calldatasize, 0x04)) @@ -43,9 +39,7 @@ sub_0: assembly { tag_3 jumpi tag_2: - 0x00 - dup1 - revert + revert(0x00, 0x00) /* "optimize_full_storage_write/input.sol":111:211 function f() public {... */ tag_3: tag_4 diff --git a/test/cmdlineTests/optimizer_BlockDeDuplicator/output b/test/cmdlineTests/optimizer_BlockDeDuplicator/output index ddf17bdae9e5..fb72e4bc1ee8 100644 --- a/test/cmdlineTests/optimizer_BlockDeDuplicator/output +++ b/test/cmdlineTests/optimizer_BlockDeDuplicator/output @@ -23,9 +23,7 @@ EVM assembly: iszero tag_5 jumpi - 0x00 - dup1 - revert + revert(0x00, 0x00) tag_5: pop jump(tag_6) @@ -51,9 +49,7 @@ sub_0: assembly { iszero tag_1 jumpi - 0x00 - dup1 - revert + revert(0x00, 0x00) tag_1: pop jumpi(tag_2, lt(calldatasize, 0x04)) @@ -74,9 +70,7 @@ sub_0: assembly { tag_3 jumpi tag_2: - 0x00 - dup1 - revert + revert(0x00, 0x00) /* "optimizer_BlockDeDuplicator/input.sol":138:174 function f() public { true ? 1 : 3;} */ tag_3: stop diff --git a/test/cmdlineTests/optimizer_inliner_add/output b/test/cmdlineTests/optimizer_inliner_add/output index 648d20fe8ee5..9ebc9977daab 100644 --- a/test/cmdlineTests/optimizer_inliner_add/output +++ b/test/cmdlineTests/optimizer_inliner_add/output @@ -8,9 +8,7 @@ EVM assembly: iszero tag_1 jumpi - 0x00 - dup1 - revert + revert(0x00, 0x00) tag_1: pop dataSize(sub_0) @@ -30,9 +28,7 @@ sub_0: assembly { iszero tag_1 jumpi - 0x00 - dup1 - revert + revert(0x00, 0x00) tag_1: pop jumpi(tag_2, lt(calldatasize, 0x04)) @@ -43,9 +39,7 @@ sub_0: assembly { tag_3 jumpi tag_2: - 0x00 - dup1 - revert + revert(0x00, 0x00) /* "optimizer_inliner_add/input.sol":182:303 function f() public pure {... */ tag_3: tag_4 diff --git a/test/cmdlineTests/optimizer_inliner_call_from_constructor/output b/test/cmdlineTests/optimizer_inliner_call_from_constructor/output index 86c09e27edd9..f42f9de094c6 100644 --- a/test/cmdlineTests/optimizer_inliner_call_from_constructor/output +++ b/test/cmdlineTests/optimizer_inliner_call_from_constructor/output @@ -9,9 +9,7 @@ EVM assembly: iszero tag_1 jumpi - 0x00 - dup1 - revert + revert(0x00, 0x00) tag_1: pop /* "optimizer_inliner_call_from_constructor/input.sol":257:258 6 */ @@ -38,9 +36,7 @@ sub_0: assembly { iszero tag_1 jumpi - 0x00 - dup1 - revert + revert(0x00, 0x00) tag_1: pop jumpi(tag_2, lt(calldatasize, 0x04)) @@ -51,9 +47,7 @@ sub_0: assembly { tag_3 jumpi tag_2: - 0x00 - dup1 - revert + revert(0x00, 0x00) /* "optimizer_inliner_call_from_constructor/input.sol":120:175 function a() public pure returns (uint) { return f(); } */ tag_3: /* "optimizer_inliner_call_from_constructor/input.sol":257:258 6 */ diff --git a/test/cmdlineTests/optimizer_inliner_dynamic_reference/output b/test/cmdlineTests/optimizer_inliner_dynamic_reference/output index 2ddef4d7689e..b1c5c74d9037 100644 --- a/test/cmdlineTests/optimizer_inliner_dynamic_reference/output +++ b/test/cmdlineTests/optimizer_inliner_dynamic_reference/output @@ -8,9 +8,7 @@ EVM assembly: iszero tag_1 jumpi - 0x00 - dup1 - revert + revert(0x00, 0x00) tag_1: pop dataSize(sub_0) @@ -30,9 +28,7 @@ sub_0: assembly { iszero tag_1 jumpi - 0x00 - dup1 - revert + revert(0x00, 0x00) tag_1: pop jumpi(tag_2, lt(calldatasize, 0x04)) @@ -53,9 +49,7 @@ sub_0: assembly { tag_5 jumpi tag_2: - 0x00 - dup1 - revert + revert(0x00, 0x00) /* "optimizer_inliner_dynamic_reference/input.sol":160:215 function a() public pure returns (uint) { return f(); } */ tag_3: /* "optimizer_inliner_dynamic_reference/input.sol":361:362 6 */ diff --git a/test/cmdlineTests/optimizer_inliner_dynamic_reference_constructor/output b/test/cmdlineTests/optimizer_inliner_dynamic_reference_constructor/output index edc93c0becb0..24ecaede0787 100644 --- a/test/cmdlineTests/optimizer_inliner_dynamic_reference_constructor/output +++ b/test/cmdlineTests/optimizer_inliner_dynamic_reference_constructor/output @@ -9,9 +9,7 @@ EVM assembly: iszero tag_1 jumpi - 0x00 - dup1 - revert + revert(0x00, 0x00) tag_1: pop /* "optimizer_inliner_dynamic_reference_constructor/input.sol":93:94 x */ @@ -57,9 +55,7 @@ sub_0: assembly { iszero tag_1 jumpi - 0x00 - dup1 - revert + revert(0x00, 0x00) tag_1: pop jumpi(tag_2, lt(calldatasize, 0x04)) @@ -75,9 +71,7 @@ sub_0: assembly { tag_4 jumpi tag_2: - 0x00 - dup1 - revert + revert(0x00, 0x00) /* "optimizer_inliner_dynamic_reference_constructor/input.sol":154:209 function a() public pure returns (uint) { return f(); } */ tag_3: /* "optimizer_inliner_dynamic_reference_constructor/input.sol":355:356 6 */ diff --git a/test/cmdlineTests/optimizer_inliner_inc/output b/test/cmdlineTests/optimizer_inliner_inc/output index 04f5f745a2fa..3a3639e190a5 100644 --- a/test/cmdlineTests/optimizer_inliner_inc/output +++ b/test/cmdlineTests/optimizer_inliner_inc/output @@ -8,9 +8,7 @@ EVM assembly: iszero tag_1 jumpi - 0x00 - dup1 - revert + revert(0x00, 0x00) tag_1: pop dataSize(sub_0) @@ -30,9 +28,7 @@ sub_0: assembly { iszero tag_1 jumpi - 0x00 - dup1 - revert + revert(0x00, 0x00) tag_1: pop jumpi(tag_2, lt(calldatasize, 0x04)) @@ -43,9 +39,7 @@ sub_0: assembly { tag_3 jumpi tag_2: - 0x00 - dup1 - revert + revert(0x00, 0x00) /* "optimizer_inliner_inc/input.sol":174:277 function f() public pure {... */ tag_3: tag_4 diff --git a/test/cmdlineTests/optimizer_inliner_multireturn/output b/test/cmdlineTests/optimizer_inliner_multireturn/output index ca7b0abdf3a1..46d74055a208 100644 --- a/test/cmdlineTests/optimizer_inliner_multireturn/output +++ b/test/cmdlineTests/optimizer_inliner_multireturn/output @@ -8,9 +8,7 @@ EVM assembly: iszero tag_1 jumpi - 0x00 - dup1 - revert + revert(0x00, 0x00) tag_1: pop dataSize(sub_0) @@ -30,9 +28,7 @@ sub_0: assembly { iszero tag_1 jumpi - 0x00 - dup1 - revert + revert(0x00, 0x00) tag_1: pop jumpi(tag_2, lt(calldatasize, 0x04)) @@ -43,9 +39,7 @@ sub_0: assembly { tag_3 jumpi tag_2: - 0x00 - dup1 - revert + revert(0x00, 0x00) /* "optimizer_inliner_multireturn/input.sol":179:296 function f() public pure {... */ tag_3: tag_4 diff --git a/test/cmdlineTests/optimizer_user_yul/output b/test/cmdlineTests/optimizer_user_yul/output index 689e82ddb4e4..c106c011b37c 100644 --- a/test/cmdlineTests/optimizer_user_yul/output +++ b/test/cmdlineTests/optimizer_user_yul/output @@ -6,9 +6,9 @@ EVM assembly: /* "optimizer_user_yul/input.sol":101:106 int a */ 0x00 /* "optimizer_user_yul/input.sol":181:190 let x,y,z */ - dup1 0x00 - dup1 + 0x00 + 0x00 /* "optimizer_user_yul/input.sol":205:206 1 */ 0x01 /* "optimizer_user_yul/input.sol":202:203 0 */ @@ -78,9 +78,7 @@ stop sub_0: assembly { /* "optimizer_user_yul/input.sol":60:518 contract C... */ mstore(0x40, 0x80) - 0x00 - dup1 - revert + revert(0x00, 0x00) 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 9489a75bf3df..e004ab7424b0 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 @@ -10,9 +10,7 @@ iszero tag_1 jumpi - 0x00 - dup1 - revert + revert(0x00, 0x00) tag_1: pop dataSize(sub_0) @@ -32,9 +30,7 @@ sub_0: assembly { iszero tag_1 jumpi - 0x00 - dup1 - revert + revert(0x00, 0x00) tag_1: pop jumpi(tag_2, lt(calldatasize, 0x04)) @@ -45,9 +41,7 @@ sub_0: assembly { tag_3 jumpi tag_2: - 0x00 - dup1 - revert + revert(0x00, 0x00) /* \"C\":77:99 function f() public {} */ tag_3: stop 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 f8f2958b0384..5c7a93644757 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 @@ -10,9 +10,7 @@ iszero tag_1 jumpi - 0x00 - dup1 - revert + revert(0x00, 0x00) tag_1: pop dataSize(sub_0) @@ -32,9 +30,7 @@ sub_0: assembly { iszero tag_1 jumpi - 0x00 - dup1 - revert + revert(0x00, 0x00) tag_1: pop jumpi(tag_2, lt(calldatasize, 0x04)) @@ -45,9 +41,7 @@ sub_0: assembly { tag_3 jumpi tag_2: - 0x00 - dup1 - revert + revert(0x00, 0x00) /* \"C\":77:99 */ tag_3: stop 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 2a5a2bc2ae15..6f2f9243c63a 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 @@ -9,9 +9,7 @@ iszero tag_1 jumpi - 0x00 - dup1 - revert + revert(0x00, 0x00) tag_1: pop dataSize(sub_0) @@ -30,9 +28,7 @@ sub_0: assembly { iszero tag_1 jumpi - 0x00 - dup1 - revert + revert(0x00, 0x00) tag_1: pop jumpi(tag_2, lt(calldatasize, 0x04)) @@ -43,9 +39,7 @@ sub_0: assembly { tag_3 jumpi tag_2: - 0x00 - dup1 - revert + revert(0x00, 0x00) tag_3: stop diff --git a/test/cmdlineTests/strict_asm_asm_json_subobjects_with_debug/output b/test/cmdlineTests/strict_asm_asm_json_subobjects_with_debug/output index dfa7656834c8..10a0231f52fc 100644 --- a/test/cmdlineTests/strict_asm_asm_json_subobjects_with_debug/output +++ b/test/cmdlineTests/strict_asm_asm_json_subobjects_with_debug/output @@ -14,8 +14,9 @@ EVM assembly: { "begin": 41, "end": 137, - "name": "DUP1", - "source": 0 + "name": "PUSH", + "source": 0, + "value": "0" }, { "begin": 41, diff --git a/test/cmdlineTests/strict_asm_msize_without_optimizer/output b/test/cmdlineTests/strict_asm_msize_without_optimizer/output index fabd2e874a5b..ac19efbcbc78 100644 --- a/test/cmdlineTests/strict_asm_msize_without_optimizer/output +++ b/test/cmdlineTests/strict_asm_msize_without_optimizer/output @@ -15,13 +15,13 @@ object "object" { Binary representation: -600b565b5f8051905090565b5f8060136003565b5f525050 +600b565b5f5f51905090565b5f8060136003565b5f525050 Text representation: jump(tag_2) tag_1: 0x00 - dup1 + 0x00 mload swap1 pop diff --git a/test/cmdlineTests/viair_msize_without_optimizer/output b/test/cmdlineTests/viair_msize_without_optimizer/output index b54f8a3f5647..f94c973bff3a 100644 --- a/test/cmdlineTests/viair_msize_without_optimizer/output +++ b/test/cmdlineTests/viair_msize_without_optimizer/output @@ -31,9 +31,7 @@ tag_1: swap1 jump // out tag_2: - 0x00 - dup1 - revert + revert(0x00, 0x00) tag_3: jump // out stop @@ -84,13 +82,9 @@ sub_0: assembly { swap1 jump // out tag_3: - 0x00 - dup1 - revert + revert(0x00, 0x00) tag_4: - 0x00 - dup1 - revert + revert(0x00, 0x00) tag_5: 0x00 dup2 @@ -110,7 +104,7 @@ sub_0: assembly { jump // out tag_6: 0x00 - dup1 + 0x00 dup3 add swap1 @@ -151,15 +145,12 @@ sub_0: assembly { dup3 return tag_8: - 0x00 - dup1 - revert + revert(0x00, 0x00) tag_9: jump(tag_35) tag_34: 0x00 - dup1 - mload + mload(0x00) swap1 pop swap1 diff --git a/test/libsolidity/semanticTests/abiEncoderV1/abi_decode_v2_storage.sol b/test/libsolidity/semanticTests/abiEncoderV1/abi_decode_v2_storage.sol index 8d74a34f48bb..5c3bcba971c2 100644 --- a/test/libsolidity/semanticTests/abiEncoderV1/abi_decode_v2_storage.sol +++ b/test/libsolidity/semanticTests/abiEncoderV1/abi_decode_v2_storage.sol @@ -21,6 +21,6 @@ contract C { } // ---- // f() -> 0x20, 0x8, 0x40, 0x3, 0x9, 0xa, 0xb -// gas irOptimized: 203173 +// gas irOptimized: 203167 // gas legacy: 206263 // gas legacyOptimized: 203172 diff --git a/test/libsolidity/semanticTests/abiEncoderV1/abi_encode_calldata_slice.sol b/test/libsolidity/semanticTests/abiEncoderV1/abi_encode_calldata_slice.sol index a518a3750ede..a6a4f8fd870d 100644 --- a/test/libsolidity/semanticTests/abiEncoderV1/abi_encode_calldata_slice.sol +++ b/test/libsolidity/semanticTests/abiEncoderV1/abi_encode_calldata_slice.sol @@ -60,9 +60,9 @@ contract C { // ---- // test_bytes() -> // gas irOptimized: 314884 -// gas legacy: 305827 -// gas legacyOptimized: 253681 +// gas legacy: 305816 +// gas legacyOptimized: 253573 // test_uint256() -> // gas irOptimized: 448346 -// gas legacy: 421315 -// gas legacyOptimized: 351650 +// gas legacy: 421304 +// gas legacyOptimized: 351544 diff --git a/test/libsolidity/semanticTests/abiEncoderV1/struct/struct_storage_ptr.sol b/test/libsolidity/semanticTests/abiEncoderV1/struct/struct_storage_ptr.sol index c8eb95418906..ed983c77b506 100644 --- a/test/libsolidity/semanticTests/abiEncoderV1/struct/struct_storage_ptr.sol +++ b/test/libsolidity/semanticTests/abiEncoderV1/struct/struct_storage_ptr.sol @@ -24,6 +24,6 @@ contract C { // ---- // library: L // f() -> 8, 7, 1, 2, 7, 12 -// gas irOptimized: 166759 -// gas legacy: 169283 -// gas legacyOptimized: 167248 +// gas irOptimized: 166761 +// gas legacy: 169273 +// gas legacyOptimized: 167243 diff --git a/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_calldata_slice.sol b/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_calldata_slice.sol index b80d14d6b02b..0c59c33c4b32 100644 --- a/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_calldata_slice.sol +++ b/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_calldata_slice.sol @@ -61,9 +61,9 @@ contract C { // ---- // test_bytes() -> // gas irOptimized: 314884 -// gas legacy: 305827 -// gas legacyOptimized: 253681 +// gas legacy: 305816 +// gas legacyOptimized: 253573 // test_uint256() -> // gas irOptimized: 448346 -// gas legacy: 421315 -// gas legacyOptimized: 351650 +// gas legacy: 421304 +// gas legacyOptimized: 351544 diff --git a/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_v2.sol b/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_v2.sol index f07d4039d5d7..edfe075ddd79 100644 --- a/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_v2.sol +++ b/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_v2.sol @@ -51,5 +51,5 @@ contract C { // f3() -> 0x20, 0xa0, 0x1, 0x60, 0x2, 0x3, "abc" // f4() -> 0x20, 0x160, 0x1, 0x80, 0xc0, 0x2, 0x3, "abc", 0x7, 0x40, 0x2, 0x2, 0x3 // gas irOptimized: 111816 -// gas legacy: 113892 +// gas legacy: 113890 // gas legacyOptimized: 111658 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 7a2395549b5f..8df4090c3662 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 @@ -39,5 +39,5 @@ contract C is B { // ---- // test() -> 5, 10 // gas irOptimized: 87337 -// gas legacy: 66251 +// gas legacy: 66250 // gas legacy code: 36400 diff --git a/test/libsolidity/semanticTests/abiEncoderV2/calldata_overlapped_dynamic_arrays.sol b/test/libsolidity/semanticTests/abiEncoderV2/calldata_overlapped_dynamic_arrays.sol index 81c9c46c6efa..aa1e494c2133 100644 --- a/test/libsolidity/semanticTests/abiEncoderV2/calldata_overlapped_dynamic_arrays.sol +++ b/test/libsolidity/semanticTests/abiEncoderV2/calldata_overlapped_dynamic_arrays.sol @@ -33,8 +33,8 @@ contract C { // f_which(uint256[],uint256[2],uint256): 0x40, 1, 2, 1, 5, 6 -> 0x20, 0x40, 5, 2 // f_which(uint256[],uint256[2],uint256): 0x40, 1, 2, 1 -> FAILURE // f_storage(uint256[],uint256[2]): 0x20, 1, 2 -> 0x20, 0x60, 0x20, 1, 2 -// gas irOptimized: 111415 -// gas legacy: 112709 -// gas legacyOptimized: 111847 +// gas irOptimized: 111409 +// gas legacy: 112707 +// gas legacyOptimized: 111845 // f_storage(uint256[],uint256[2]): 0x40, 1, 2, 5, 6 -> 0x20, 0x80, 0x20, 2, 5, 6 // f_storage(uint256[],uint256[2]): 0x40, 1, 2, 5 -> FAILURE diff --git a/test/libsolidity/semanticTests/abiEncoderV2/storage_array_encoding.sol b/test/libsolidity/semanticTests/abiEncoderV2/storage_array_encoding.sol index 7eb93d401989..9599af6c8815 100644 --- a/test/libsolidity/semanticTests/abiEncoderV2/storage_array_encoding.sol +++ b/test/libsolidity/semanticTests/abiEncoderV2/storage_array_encoding.sol @@ -18,9 +18,9 @@ contract C { // EVMVersion: >homestead // ---- // h(uint256[2][]): 0x20, 3, 123, 124, 223, 224, 323, 324 -> 32, 256, 0x20, 3, 123, 124, 223, 224, 323, 324 -// gas irOptimized: 180086 -// gas legacy: 184235 -// gas legacyOptimized: 180857 +// gas irOptimized: 180080 +// gas legacy: 184233 +// gas legacyOptimized: 180856 // i(uint256[2][2]): 123, 124, 223, 224 -> 32, 128, 123, 124, 223, 224 // gas irOptimized: 112031 // gas legacy: 115091 diff --git a/test/libsolidity/semanticTests/abiencodedecode/abi_decode_simple_storage.sol b/test/libsolidity/semanticTests/abiencodedecode/abi_decode_simple_storage.sol index 93e20b475e9c..54ce693d5ca4 100644 --- a/test/libsolidity/semanticTests/abiencodedecode/abi_decode_simple_storage.sol +++ b/test/libsolidity/semanticTests/abiencodedecode/abi_decode_simple_storage.sol @@ -8,6 +8,6 @@ contract C { } // ---- // f(bytes): 0x20, 0x80, 0x21, 0x40, 0x7, "abcdefg" -> 0x21, 0x40, 0x7, "abcdefg" -// gas irOptimized: 135505 -// gas legacy: 137096 -// gas legacyOptimized: 135824 +// gas irOptimized: 135499 +// gas legacy: 137095 +// gas legacyOptimized: 135823 diff --git a/test/libsolidity/semanticTests/array/array_memory_index_access.sol b/test/libsolidity/semanticTests/array/array_memory_index_access.sol index 49fc58c45de4..d992014c4a50 100644 --- a/test/libsolidity/semanticTests/array/array_memory_index_access.sol +++ b/test/libsolidity/semanticTests/array/array_memory_index_access.sol @@ -27,8 +27,8 @@ contract C { // index(uint256): 20 -> true // index(uint256): 0xFF -> true // gas irOptimized: 108272 -// gas legacy: 181523 -// gas legacyOptimized: 117443 +// gas legacy: 181536 +// gas legacyOptimized: 117442 // accessIndex(uint256,int256): 10, 1 -> 2 // accessIndex(uint256,int256): 10, 0 -> 1 // accessIndex(uint256,int256): 10, 11 -> FAILURE, hex"4e487b71", 0x32 diff --git a/test/libsolidity/semanticTests/array/array_storage_index_access.sol b/test/libsolidity/semanticTests/array/array_storage_index_access.sol index 2957e6d98d61..325323c5cb84 100644 --- a/test/libsolidity/semanticTests/array/array_storage_index_access.sol +++ b/test/libsolidity/semanticTests/array/array_storage_index_access.sol @@ -17,37 +17,37 @@ contract C { // test_indices(uint256): 1 -> // test_indices(uint256): 129 -> // gas irOptimized: 3017687 -// gas legacy: 3038654 +// gas legacy: 3038668 // gas legacyOptimized: 2995964 // test_indices(uint256): 5 -> // gas irOptimized: 579670 -// gas legacy: 573810 +// gas legacy: 573821 // gas legacyOptimized: 571847 // test_indices(uint256): 10 -> // gas irOptimized: 157953 -// gas legacy: 160108 +// gas legacy: 160122 // gas legacyOptimized: 156996 // test_indices(uint256): 15 -> // gas irOptimized: 172733 -// gas legacy: 175973 +// gas legacy: 175987 // gas legacyOptimized: 171596 // test_indices(uint256): 0xFF -> // gas irOptimized: 5673823 -// gas legacy: 5715748 +// gas legacy: 5715762 // gas legacyOptimized: 5632556 // test_indices(uint256): 1000 -> // gas irOptimized: 18173005 -// gas legacy: 18347810 +// gas legacy: 18347824 // gas legacyOptimized: 18037248 // test_indices(uint256): 129 -> // gas irOptimized: 4166279 -// gas legacy: 4140113 +// gas legacy: 4140124 // gas legacyOptimized: 4108272 // test_indices(uint256): 128 -> // gas irOptimized: 405522 -// gas legacy: 433498 +// gas legacy: 433512 // gas legacyOptimized: 400909 // test_indices(uint256): 1 -> // gas irOptimized: 583437 -// gas legacy: 576715 +// gas legacy: 576726 // gas legacyOptimized: 575542 diff --git a/test/libsolidity/semanticTests/array/array_storage_index_boundary_test.sol b/test/libsolidity/semanticTests/array/array_storage_index_boundary_test.sol index 494c99782f22..712a7cdebebb 100644 --- a/test/libsolidity/semanticTests/array/array_storage_index_boundary_test.sol +++ b/test/libsolidity/semanticTests/array/array_storage_index_boundary_test.sol @@ -17,11 +17,11 @@ contract C { // test_boundary_check(uint256,uint256): 10, 10 -> FAILURE, hex"4e487b71", 0x32 // test_boundary_check(uint256,uint256): 256, 256 -> FAILURE, hex"4e487b71", 0x32 // gas irOptimized: 147246 -// gas legacy: 133633 -// gas legacyOptimized: 114354 +// gas legacy: 133632 +// gas legacyOptimized: 114353 // test_boundary_check(uint256,uint256): 256, 255 -> 0 // gas irOptimized: 149422 -// gas legacy: 135949 -// gas legacyOptimized: 116533 +// gas legacy: 135948 +// gas legacyOptimized: 116532 // test_boundary_check(uint256,uint256): 256, 0xFFFF -> FAILURE, hex"4e487b71", 0x32 // test_boundary_check(uint256,uint256): 256, 2 -> 0 diff --git a/test/libsolidity/semanticTests/array/array_storage_index_zeroed_test.sol b/test/libsolidity/semanticTests/array/array_storage_index_zeroed_test.sol index de260b373574..23feb0da11eb 100644 --- a/test/libsolidity/semanticTests/array/array_storage_index_zeroed_test.sol +++ b/test/libsolidity/semanticTests/array/array_storage_index_zeroed_test.sol @@ -53,17 +53,17 @@ contract C { // test_zeroed_indicies(uint256): 1 -> // test_zeroed_indicies(uint256): 5 -> // gas irOptimized: 133763 -// gas legacy: 131671 -// gas legacyOptimized: 129994 +// gas legacy: 131664 +// gas legacyOptimized: 129990 // test_zeroed_indicies(uint256): 10 -> // gas irOptimized: 228556 -// gas legacy: 225237 -// gas legacyOptimized: 222359 +// gas legacy: 225215 +// gas legacyOptimized: 222351 // test_zeroed_indicies(uint256): 15 -> // gas irOptimized: 327360 -// gas legacy: 322937 -// gas legacyOptimized: 318919 +// gas legacy: 322899 +// gas legacyOptimized: 318907 // test_zeroed_indicies(uint256): 0xFF -> // gas irOptimized: 5180120 -// gas legacy: 5093941 -// gas legacyOptimized: 5020727 +// gas legacy: 5093135 +// gas legacyOptimized: 5020523 diff --git a/test/libsolidity/semanticTests/array/array_storage_push_empty.sol b/test/libsolidity/semanticTests/array/array_storage_push_empty.sol index b84cdd90a374..b6965f62b2d7 100644 --- a/test/libsolidity/semanticTests/array/array_storage_push_empty.sol +++ b/test/libsolidity/semanticTests/array/array_storage_push_empty.sol @@ -13,11 +13,11 @@ contract C { // ---- // pushEmpty(uint256): 128 // gas irOptimized: 410745 -// gas legacy: 400640 +// gas legacy: 400519 // gas legacyOptimized: 388804 // pushEmpty(uint256): 256 // gas irOptimized: 698285 -// gas legacy: 685108 +// gas legacy: 684859 // gas legacyOptimized: 671480 // pushEmpty(uint256): 38869 -> FAILURE # out-of-gas # // gas irOptimized: 100000000 diff --git a/test/libsolidity/semanticTests/array/array_storage_push_pop.sol b/test/libsolidity/semanticTests/array/array_storage_push_pop.sol index 78a74ab5d4ff..a4c7d34d7fef 100644 --- a/test/libsolidity/semanticTests/array/array_storage_push_pop.sol +++ b/test/libsolidity/semanticTests/array/array_storage_push_pop.sol @@ -18,10 +18,10 @@ contract C { // gas legacyOptimized: 103508 // set_get_length(uint256): 0xFF -> 0 // gas irOptimized: 833586 -// gas legacy: 808020 +// gas legacy: 807764 // gas legacyOptimized: 784467 // set_get_length(uint256): 0xFFF -> 0 // gas irOptimized: 13029438 -// gas legacy: 12612192 +// gas legacy: 12608096 // gas legacyOptimized: 12239199 // set_get_length(uint256): 0xFFFF -> FAILURE # Out-of-gas # 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 918185e9afa2..a9d08ec0c0cb 100644 --- a/test/libsolidity/semanticTests/array/arrays_complex_from_and_to_storage.sol +++ b/test/libsolidity/semanticTests/array/arrays_complex_from_and_to_storage.sol @@ -12,7 +12,7 @@ contract Test { } // ---- // set(uint24[3][]): 0x20, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12 -> 0x06 -// gas irOptimized: 185219 +// gas irOptimized: 185216 // gas legacy: 211054 // gas legacyOptimized: 206077 // 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 942c7337aa5a..060cafe39a78 100644 --- a/test/libsolidity/semanticTests/array/byte_array_storage_layout.sol +++ b/test/libsolidity/semanticTests/array/byte_array_storage_layout.sol @@ -46,8 +46,8 @@ contract c { // storageEmpty -> 0 // test_long() -> 67 // gas irOptimized: 89148 -// gas legacy: 101601 -// gas legacyOptimized: 100477 +// gas legacy: 101607 +// gas legacyOptimized: 100479 // storageEmpty -> 0 // test_pop() -> 1780731860627700044960722568376592200742329637303199754547598369979433020 // gas legacy: 61930 diff --git a/test/libsolidity/semanticTests/array/byte_array_transitional_2.sol b/test/libsolidity/semanticTests/array/byte_array_transitional_2.sol index 401f97a1c97a..e83cc545809d 100644 --- a/test/libsolidity/semanticTests/array/byte_array_transitional_2.sol +++ b/test/libsolidity/semanticTests/array/byte_array_transitional_2.sol @@ -17,6 +17,6 @@ contract c { } // ---- // test() -> 0 -// gas irOptimized: 122719 -// gas legacy: 147098 +// gas irOptimized: 122717 +// gas legacy: 147108 // gas legacyOptimized: 144200 diff --git a/test/libsolidity/semanticTests/array/bytes_length_member.sol b/test/libsolidity/semanticTests/array/bytes_length_member.sol index 105bbfba8d53..5159538bc1de 100644 --- a/test/libsolidity/semanticTests/array/bytes_length_member.sol +++ b/test/libsolidity/semanticTests/array/bytes_length_member.sol @@ -13,7 +13,7 @@ contract c { // ---- // getLength() -> 0 // set(): 1, 2 -> true -// gas irOptimized: 110425 -// gas legacy: 110952 +// gas irOptimized: 110422 +// gas legacy: 110951 // gas legacyOptimized: 110576 // 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 96580c47db8c..ecfe565f12cb 100644 --- a/test/libsolidity/semanticTests/array/copying/array_copy_calldata_storage.sol +++ b/test/libsolidity/semanticTests/array/copying/array_copy_calldata_storage.sol @@ -21,6 +21,6 @@ contract c { // ---- // store(uint256[9],uint8[3][]): 21, 22, 23, 24, 25, 26, 27, 28, 29, 0x140, 4, 1, 2, 3, 11, 12, 13, 21, 22, 23, 31, 32, 33 -> 32 // gas irOptimized: 647725 -// gas legacy: 694356 -// gas legacyOptimized: 693850 +// gas legacy: 694354 +// gas legacyOptimized: 693849 // retrieve() -> 9, 28, 9, 28, 4, 3, 32 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 9609215a7dca..d65f4f37c104 100644 --- a/test/libsolidity/semanticTests/array/copying/array_copy_cleanup_uint40.sol +++ b/test/libsolidity/semanticTests/array/copying/array_copy_cleanup_uint40.sol @@ -46,6 +46,6 @@ contract C { } // ---- // f() -> true -// gas irOptimized: 122592 -// gas legacy: 124660 +// gas irOptimized: 122541 +// gas legacy: 124643 // gas legacyOptimized: 122801 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 6c0ba7af6928..e9f1448a27b1 100644 --- a/test/libsolidity/semanticTests/array/copying/array_copy_clear_storage.sol +++ b/test/libsolidity/semanticTests/array/copying/array_copy_clear_storage.sol @@ -13,6 +13,6 @@ contract C { } // ---- // f() -> 0 -// gas irOptimized: 108246 -// gas legacy: 108218 +// gas irOptimized: 108229 +// gas legacy: 108216 // gas legacyOptimized: 107625 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 2176655fe389..ee564d01a2d9 100644 --- a/test/libsolidity/semanticTests/array/copying/array_copy_different_packing.sol +++ b/test/libsolidity/semanticTests/array/copying/array_copy_different_packing.sol @@ -18,6 +18,6 @@ contract c { } // ---- // test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x05000000000000000000000000000000000000000000000000 -// gas irOptimized: 208459 -// gas legacy: 220707 -// gas legacyOptimized: 220098 +// gas irOptimized: 208415 +// gas legacy: 220711 +// gas legacyOptimized: 220097 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 20aee3a293f4..bb621fcc84b5 100644 --- a/test/libsolidity/semanticTests/array/copying/array_copy_including_array.sol +++ b/test/libsolidity/semanticTests/array/copying/array_copy_including_array.sol @@ -35,12 +35,12 @@ contract c { } // ---- // test() -> 0x02000202 -// gas irOptimized: 4549703 -// gas legacy: 4475396 +// gas irOptimized: 4549676 +// gas legacy: 4475394 // gas legacyOptimized: 4447665 // storageEmpty -> 1 // clear() -> 0, 0 -// gas irOptimized: 4478226 -// gas legacy: 4407188 -// gas legacyOptimized: 4381336 +// gas irOptimized: 4478184 +// gas legacy: 4407185 +// gas legacyOptimized: 4381337 // 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 0420f953bb56..2d325a804bfa 100644 --- a/test/libsolidity/semanticTests/array/copying/array_copy_nested_array.sol +++ b/test/libsolidity/semanticTests/array/copying/array_copy_nested_array.sol @@ -12,6 +12,6 @@ contract c { } // ---- // test(uint256[2][]): 32, 3, 7, 8, 9, 10, 11, 12 -> 10 -// gas irOptimized: 689558 -// gas legacy: 686178 -// gas legacyOptimized: 685612 +// gas irOptimized: 689552 +// gas legacy: 686176 +// gas legacyOptimized: 685611 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 e292809b800a..54639df55d66 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,4 +19,4 @@ contract c { // test() -> 5, 4 // gas irOptimized: 205667 // gas legacy: 213863 -// gas legacyOptimized: 212902 +// gas legacyOptimized: 212901 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 44fede749cc4..ad745ff4203f 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 @@ -22,5 +22,5 @@ contract c { // ---- // test() -> 3, 4 // gas irOptimized: 169669 -// gas legacy: 175424 -// gas legacyOptimized: 172535 +// gas legacy: 175415 +// gas legacyOptimized: 172533 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 1f102ea14a7c..a38685404dc7 100644 --- a/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_dyn_dyn.sol +++ b/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_dyn_dyn.sol @@ -15,7 +15,7 @@ contract c { // ---- // setData1(uint256,uint256,uint256): 10, 5, 4 -> // copyStorageStorage() -> -// gas irOptimized: 111353 +// gas irOptimized: 111350 // gas legacy: 109272 // gas legacyOptimized: 109262 // 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 03c1f4e8753c..83df3aef8f43 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 @@ -19,4 +19,4 @@ contract c { // test() -> 5, 4 // gas irOptimized: 253591 // gas legacy: 250892 -// gas legacyOptimized: 250046 +// gas legacyOptimized: 250045 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 f4bf1b2d2131..94e57c96da7b 100644 --- a/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_static_dynamic.sol +++ b/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_static_dynamic.sol @@ -12,5 +12,5 @@ contract c { // ---- // test() -> 9, 4 // gas irOptimized: 123180 -// gas legacy: 123567 +// gas legacy: 123566 // gas legacyOptimized: 123202 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 145a8060edb1..d1f2cbdedcde 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 @@ -15,5 +15,5 @@ contract c { // ---- // test() -> 8, 0 // gas irOptimized: 196251 -// gas legacy: 194843 +// gas legacy: 194842 // gas legacyOptimized: 194281 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 7fa5ee515f87..e638f2dad10c 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 @@ -18,6 +18,6 @@ contract c { // ---- // test() -> 4, 5 // gas irOptimized: 190628 -// gas legacy: 190852 -// gas legacyOptimized: 189658 +// gas legacy: 190828 +// gas legacyOptimized: 189657 // 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 d88ac0674672..120e728843ac 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 @@ -16,5 +16,5 @@ contract C { // ---- // f() -> 0x20, 2, 0x40, 0xa0, 2, 0, 1, 2, 2, 3 // gas irOptimized: 161793 -// gas legacy: 162203 +// gas legacy: 162200 // gas legacyOptimized: 159953 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 ebfbdeab9720..22105f6429b9 100644 --- a/test/libsolidity/semanticTests/array/copying/array_copy_target_leftover.sol +++ b/test/libsolidity/semanticTests/array/copying/array_copy_target_leftover.sol @@ -17,6 +17,6 @@ contract c { } // ---- // test() -> 0xffffffff, 0x0000000000000000000000000a00090008000700060005000400030002000100, 0x0000000000000000000000000000000000000000000000000000000000000000 -// gas irOptimized: 100495 -// gas legacy: 158142 -// gas legacyOptimized: 141020 +// gas irOptimized: 100496 +// gas legacy: 158109 +// gas legacyOptimized: 141019 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 309753066510..27fb9f0c5736 100644 --- a/test/libsolidity/semanticTests/array/copying/array_copy_target_simple.sol +++ b/test/libsolidity/semanticTests/array/copying/array_copy_target_simple.sol @@ -18,6 +18,6 @@ contract c { } // ---- // test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x0 -// gas irOptimized: 273545 -// gas legacy: 282604 +// gas irOptimized: 273543 +// gas legacy: 282601 // gas legacyOptimized: 281510 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 b08487417547..980e414d1451 100644 --- a/test/libsolidity/semanticTests/array/copying/array_copy_target_simple_2.sol +++ b/test/libsolidity/semanticTests/array/copying/array_copy_target_simple_2.sol @@ -18,6 +18,6 @@ contract c { } // ---- // test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x00 -// gas irOptimized: 232997 -// gas legacy: 235697 +// gas irOptimized: 232995 +// gas legacy: 235694 // gas legacyOptimized: 235193 diff --git a/test/libsolidity/semanticTests/array/copying/array_elements_to_mapping.sol b/test/libsolidity/semanticTests/array/copying/array_elements_to_mapping.sol index 085f72ed96c1..becc3d4cdefd 100644 --- a/test/libsolidity/semanticTests/array/copying/array_elements_to_mapping.sol +++ b/test/libsolidity/semanticTests/array/copying/array_elements_to_mapping.sol @@ -52,9 +52,9 @@ contract C { } // ---- // from_storage() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 -// gas irOptimized: 149880 -// gas legacy: 150745 -// gas legacyOptimized: 148700 +// gas irOptimized: 149868 +// gas legacy: 150737 +// gas legacyOptimized: 148690 // from_storage_ptr() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 // from_memory() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 // from_calldata(uint8[][]): 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 diff --git a/test/libsolidity/semanticTests/array/copying/array_nested_calldata_to_storage.sol b/test/libsolidity/semanticTests/array/copying/array_nested_calldata_to_storage.sol index ac37f794e147..5d4e5b45e4a9 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: 181041 +// gas irOptimized: 181029 // test2(uint256[][2]): 0x20, 0x40, 0x40, 2, 23, 42 -> 2, 65 // gas irOptimized: 157604 // test3(uint256[2][]): 0x20, 2, 23, 42, 23, 42 -> 2, 65 -// gas irOptimized: 134813 +// gas irOptimized: 134801 // test4(uint256[2][2]): 23, 42, 23, 42 -> 65 // gas irOptimized: 111177 diff --git a/test/libsolidity/semanticTests/array/copying/array_nested_memory_to_storage.sol b/test/libsolidity/semanticTests/array/copying/array_nested_memory_to_storage.sol index e2228f993f07..b892ec991ce3 100644 --- a/test/libsolidity/semanticTests/array/copying/array_nested_memory_to_storage.sol +++ b/test/libsolidity/semanticTests/array/copying/array_nested_memory_to_storage.sol @@ -38,12 +38,12 @@ contract Test { } // ---- // test() -> 24 -// gas irOptimized: 226743 -// gas legacy: 227084 +// gas irOptimized: 226734 +// gas legacy: 227083 // gas legacyOptimized: 226529 // test1() -> 3 // test2() -> 6 // test3() -> 24 -// gas irOptimized: 141325 +// gas irOptimized: 141319 // gas legacy: 142238 // gas legacyOptimized: 141365 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 8b6ad78ea777..355c268f2514 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: 181932 +// gas irOptimized: 181928 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 82e65edf1d49..3578f0a81e73 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 @@ -13,5 +13,5 @@ contract C { // ---- // f() -> 1, 2, 3 // gas irOptimized: 131939 -// gas legacy: 134606 +// gas legacy: 134605 // gas legacyOptimized: 131938 diff --git a/test/libsolidity/semanticTests/array/copying/array_to_mapping.sol b/test/libsolidity/semanticTests/array/copying/array_to_mapping.sol index 75a68759b6e0..c5519e83aa43 100644 --- a/test/libsolidity/semanticTests/array/copying/array_to_mapping.sol +++ b/test/libsolidity/semanticTests/array/copying/array_to_mapping.sol @@ -37,8 +37,8 @@ contract C { } // ---- // from_storage() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 -// gas irOptimized: 147761 -// gas legacy: 148896 -// gas legacyOptimized: 146923 +// gas irOptimized: 147755 +// gas legacy: 148892 +// gas legacyOptimized: 146917 // from_storage_ptr() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 // from_memory() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 diff --git a/test/libsolidity/semanticTests/array/copying/bytes_inside_mappings.sol b/test/libsolidity/semanticTests/array/copying/bytes_inside_mappings.sol index e61b7dff7a5f..90012eed4c77 100644 --- a/test/libsolidity/semanticTests/array/copying/bytes_inside_mappings.sol +++ b/test/libsolidity/semanticTests/array/copying/bytes_inside_mappings.sol @@ -6,11 +6,11 @@ contract c { // ---- // set(uint256): 1, 2 -> true // gas irOptimized: 110550 -// gas legacy: 111312 +// gas legacy: 111310 // gas legacyOptimized: 110741 // set(uint256): 2, 2, 3, 4, 5 -> true // gas irOptimized: 177501 -// gas legacy: 178314 +// gas legacy: 178312 // gas legacyOptimized: 177716 // storageEmpty -> 0 // copy(uint256,uint256): 1, 2 -> true 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 ea364d4378ec..fe758fe8fd13 100644 --- a/test/libsolidity/semanticTests/array/copying/bytes_storage_to_storage.sol +++ b/test/libsolidity/semanticTests/array/copying/bytes_storage_to_storage.sol @@ -17,25 +17,25 @@ contract c { // ---- // f(uint256): 0 -> 0x20, 0x00 // f(uint256): 31 -> 0x20, 0x1f, 0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e00 -// gas irOptimized: 103269 -// gas legacy: 112883 +// gas irOptimized: 103268 +// gas legacy: 112904 // gas legacyOptimized: 112647 // f(uint256): 32 -> 0x20, 0x20, 1780731860627700044960722568376592200742329637303199754547598369979440671 -// gas irOptimized: 117928 -// gas legacy: 128943 +// gas irOptimized: 117825 +// gas legacy: 128964 // gas legacyOptimized: 128854 // f(uint256): 33 -> 0x20, 33, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x2000000000000000000000000000000000000000000000000000000000000000 -// gas irOptimized: 124200 -// gas legacy: 136071 +// gas irOptimized: 124091 +// gas legacy: 136092 // gas legacyOptimized: 135469 // f(uint256): 63 -> 0x20, 0x3f, 1780731860627700044960722568376592200742329637303199754547598369979440671, 14532552714582660066924456880521368950258152170031413196862950297402215316992 -// gas irOptimized: 127350 -// gas legacy: 148671 +// gas irOptimized: 127151 +// gas legacy: 148692 // gas legacyOptimized: 148699 // f(uint256): 12 -> 0x20, 0x0c, 0x0102030405060708090a0b0000000000000000000000000000000000000000 // gas legacy: 59345 // gas legacyOptimized: 57279 // f(uint256): 129 -> 0x20, 0x81, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f, 29063324697304692433803953038474361308315562010425523193971352996434451193439, 0x606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f, -57896044618658097711785492504343953926634992332820282019728792003956564819968 -// gas irOptimized: 417312 -// gas legacy: 458976 +// gas irOptimized: 416918 +// gas legacy: 458997 // gas legacyOptimized: 460664 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 1da1d0a40c78..3df22c725192 100644 --- a/test/libsolidity/semanticTests/array/copying/calldata_array_dynamic_to_storage.sol +++ b/test/libsolidity/semanticTests/array/copying/calldata_array_dynamic_to_storage.sol @@ -9,6 +9,6 @@ contract C { } // ---- // f(uint256[]): 0x20, 0x03, 0x1, 0x2, 0x3 -> 0x1 -// gas irOptimized: 111096 -// gas legacy: 111551 -// gas legacyOptimized: 111323 +// gas irOptimized: 111084 +// gas legacy: 111548 +// gas legacyOptimized: 111321 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 7c0459ef139e..787973c5f0e5 100644 --- a/test/libsolidity/semanticTests/array/copying/copy_byte_array_in_struct_to_storage.sol +++ b/test/libsolidity/semanticTests/array/copying/copy_byte_array_in_struct_to_storage.sol @@ -35,12 +35,12 @@ contract C { } // ---- // f() -> 0x40, 0x80, 6, 0x6162636465660000000000000000000000000000000000000000000000000000, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000 -// gas irOptimized: 179408 +// gas irOptimized: 179405 // gas legacy: 180675 // gas legacyOptimized: 179686 // g() -> 0x40, 0xc0, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000, 0x11, 0x3132333435363738393233343536373839000000000000000000000000000000 -// gas irOptimized: 106344 -// gas legacy: 109394 +// gas irOptimized: 106338 +// gas legacy: 109415 // gas legacyOptimized: 106600 // h() -> 0x40, 0x60, 0x00, 0x00 // storageEmpty -> 1 diff --git a/test/libsolidity/semanticTests/array/copying/copy_byte_array_to_storage.sol b/test/libsolidity/semanticTests/array/copying/copy_byte_array_to_storage.sol index 1fd42ab34621..fc274bf47b28 100644 --- a/test/libsolidity/semanticTests/array/copying/copy_byte_array_to_storage.sol +++ b/test/libsolidity/semanticTests/array/copying/copy_byte_array_to_storage.sol @@ -46,6 +46,6 @@ contract C { } // ---- // f() -> 0xff -// gas irOptimized: 143867 -// gas legacy: 153395 -// gas legacyOptimized: 146689 +// gas irOptimized: 143857 +// gas legacy: 153404 +// gas legacyOptimized: 146676 diff --git a/test/libsolidity/semanticTests/array/copying/copy_function_internal_storage_array.sol b/test/libsolidity/semanticTests/array/copying/copy_function_internal_storage_array.sol index a6a64942d2ad..7db82f891dfb 100644 --- a/test/libsolidity/semanticTests/array/copying/copy_function_internal_storage_array.sol +++ b/test/libsolidity/semanticTests/array/copying/copy_function_internal_storage_array.sol @@ -15,6 +15,6 @@ contract C { } // ---- // test() -> 7 -// gas irOptimized: 122461 +// gas irOptimized: 122459 // gas legacy: 205176 // gas legacyOptimized: 204971 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 48d02bdc7737..46216e912ce4 100644 --- a/test/libsolidity/semanticTests/array/copying/copy_removes_bytes_data.sol +++ b/test/libsolidity/semanticTests/array/copying/copy_removes_bytes_data.sol @@ -8,7 +8,7 @@ contract c { // ---- // set(): 1, 2, 3, 4, 5 -> true // gas irOptimized: 177344 -// gas legacy: 177954 +// gas legacy: 177953 // gas legacyOptimized: 177550 // storageEmpty -> 0 // reset() -> true diff --git a/test/libsolidity/semanticTests/array/copying/copying_bytes_multiassign.sol b/test/libsolidity/semanticTests/array/copying/copying_bytes_multiassign.sol index 58b5dd045449..ce4344e871db 100644 --- a/test/libsolidity/semanticTests/array/copying/copying_bytes_multiassign.sol +++ b/test/libsolidity/semanticTests/array/copying/copying_bytes_multiassign.sol @@ -18,7 +18,7 @@ contract sender { } // ---- // (): 7 -> -// gas irOptimized: 110831 +// gas irOptimized: 110822 // gas legacy: 111388 // gas legacyOptimized: 111065 // val() -> 0 diff --git a/test/libsolidity/semanticTests/array/copying/function_type_array_to_storage.sol b/test/libsolidity/semanticTests/array/copying/function_type_array_to_storage.sol index e3490e2db09e..640046a11a4f 100644 --- a/test/libsolidity/semanticTests/array/copying/function_type_array_to_storage.sol +++ b/test/libsolidity/semanticTests/array/copying/function_type_array_to_storage.sol @@ -46,11 +46,11 @@ contract C { } // ---- // test() -> 0x20, 0x14, "[a called][b called]" -// gas irOptimized: 116531 -// gas legacy: 118845 -// gas legacyOptimized: 116844 +// gas irOptimized: 116518 +// gas legacy: 118841 +// gas legacyOptimized: 116843 // test2() -> 0x20, 0x14, "[b called][a called]" // test3() -> 0x20, 0x14, "[b called][a called]" -// gas irOptimized: 103150 +// gas irOptimized: 103144 // gas legacy: 102654 // gas legacyOptimized: 101556 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 c5497547900f..8a4d870b22f8 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 @@ -19,5 +19,5 @@ contract C { // ---- // f() -> 3 // gas irOptimized: 128296 -// gas legacy: 129050 +// gas legacy: 129077 // gas legacyOptimized: 128210 diff --git a/test/libsolidity/semanticTests/array/copying/nested_array_element_storage_to_storage.sol b/test/libsolidity/semanticTests/array/copying/nested_array_element_storage_to_storage.sol index ad00ee8c513b..f3934fec0f6f 100644 --- a/test/libsolidity/semanticTests/array/copying/nested_array_element_storage_to_storage.sol +++ b/test/libsolidity/semanticTests/array/copying/nested_array_element_storage_to_storage.sol @@ -75,8 +75,8 @@ contract C { // gas legacyOptimized: 150906 // test2() -> FAILURE // gas irOptimized: 150389 -// gas legacy: 150673 -// gas legacyOptimized: 150576 +// gas legacy: 150672 +// gas legacyOptimized: 150575 // test3() -> // gas irOptimized: 124300 // gas legacy: 125333 diff --git a/test/libsolidity/semanticTests/array/copying/nested_array_of_structs_calldata_to_storage.sol b/test/libsolidity/semanticTests/array/copying/nested_array_of_structs_calldata_to_storage.sol index 3b774f56e4eb..7621b2477e03 100644 --- a/test/libsolidity/semanticTests/array/copying/nested_array_of_structs_calldata_to_storage.sol +++ b/test/libsolidity/semanticTests/array/copying/nested_array_of_structs_calldata_to_storage.sol @@ -29,8 +29,8 @@ contract C { // compileViaYul: true // ---- // test1((uint8[],uint8[2])[][]): 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -// gas irOptimized: 304794 +// gas irOptimized: 304788 // test2((uint8[],uint8[2])[][1]): 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13 // gas irOptimized: 116653 // test3((uint8[],uint8[2])[1][]): 0x20, 2, 0x40, 0x0120, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 0x0120, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -// gas irOptimized: 188000 +// gas irOptimized: 187994 diff --git a/test/libsolidity/semanticTests/array/copying/nested_array_of_structs_memory_to_storage.sol b/test/libsolidity/semanticTests/array/copying/nested_array_of_structs_memory_to_storage.sol index 35e7943b8b62..8ec3f77691b5 100644 --- a/test/libsolidity/semanticTests/array/copying/nested_array_of_structs_memory_to_storage.sol +++ b/test/libsolidity/semanticTests/array/copying/nested_array_of_structs_memory_to_storage.sol @@ -29,8 +29,8 @@ contract C { // compileViaYul: true // ---- // test1((uint8[],uint8[2])[][]): 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -// gas irOptimized: 309078 +// gas irOptimized: 309072 // test2((uint8[],uint8[2])[][1]): 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13 // gas irOptimized: 118314 // test3((uint8[],uint8[2])[1][]): 0x20, 2, 0x40, 0x0120, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 0x0120, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -// gas irOptimized: 191051 +// gas irOptimized: 191045 diff --git a/test/libsolidity/semanticTests/array/copying/nested_dynamic_array_element_calldata_to_storage.sol b/test/libsolidity/semanticTests/array/copying/nested_dynamic_array_element_calldata_to_storage.sol index a4222be0b4f1..57b3dc521f65 100644 --- a/test/libsolidity/semanticTests/array/copying/nested_dynamic_array_element_calldata_to_storage.sol +++ b/test/libsolidity/semanticTests/array/copying/nested_dynamic_array_element_calldata_to_storage.sol @@ -32,5 +32,5 @@ contract C { // test(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 // gas irOptimized: 137897 // test2(uint8[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -// gas irOptimized: 164506 +// gas irOptimized: 164482 // gas legacyOptimized: 120228 diff --git a/test/libsolidity/semanticTests/array/copying/storage_memory_nested.sol b/test/libsolidity/semanticTests/array/copying/storage_memory_nested.sol index ac92189e48de..2a486d256355 100644 --- a/test/libsolidity/semanticTests/array/copying/storage_memory_nested.sol +++ b/test/libsolidity/semanticTests/array/copying/storage_memory_nested.sol @@ -18,5 +18,5 @@ contract C { // ---- // f() -> 1, 2, 3, 4, 5, 6, 7 // gas irOptimized: 206440 -// gas legacy: 211765 -// gas legacyOptimized: 211181 +// gas legacy: 211758 +// gas legacyOptimized: 211179 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 b743a5825a75..e5a6ae53b2da 100644 --- a/test/libsolidity/semanticTests/array/copying/storage_memory_nested_bytes.sol +++ b/test/libsolidity/semanticTests/array/copying/storage_memory_nested_bytes.sol @@ -12,5 +12,5 @@ contract C { // ---- // f() -> 0x20, 0x02, 0x40, 0x80, 3, 0x6162630000000000000000000000000000000000000000000000000000000000, 0x99, 44048183304486788312148433451363384677562265908331949128489393215789685032262, 32241931068525137014058842823026578386641954854143559838526554899205067598957, 49951309422467613961193228765530489307475214998374779756599339590522149884499, 0x54555658595a6162636465666768696a6b6c6d6e6f707172737475767778797a, 0x4142434445464748494a4b4c4d4e4f5051525354555658595a00000000000000 // gas irOptimized: 202083 -// gas legacy: 204328 -// gas legacyOptimized: 202900 +// gas legacy: 204327 +// gas legacyOptimized: 202899 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 da7187a27e65..5ec2cbcf43dc 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,4 +20,4 @@ contract C { // f() -> 1, 2, 3, 4, 5, 6, 7 // gas irOptimized: 206440 // gas legacy: 211770 -// gas legacyOptimized: 211186 +// gas legacyOptimized: 211191 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 d4a348ea4095..b37aa96ea6e0 100644 --- a/test/libsolidity/semanticTests/array/copying/storage_memory_nested_struct.sol +++ b/test/libsolidity/semanticTests/array/copying/storage_memory_nested_struct.sol @@ -25,5 +25,5 @@ contract C { // ---- // f() -> 11, 0x0c, 1, 0x15, 22, 4 // gas irOptimized: 291212 -// gas legacy: 293407 +// gas legacy: 293398 // gas legacyOptimized: 290218 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 c5bd7d0b0c28..a8a1b36e1bf1 100644 --- a/test/libsolidity/semanticTests/array/copying/storage_memory_packed_dyn.sol +++ b/test/libsolidity/semanticTests/array/copying/storage_memory_packed_dyn.sol @@ -14,5 +14,5 @@ contract C { // ---- // f() -> 2, 3, 4 // gas irOptimized: 114338 -// gas legacy: 122235 -// gas legacyOptimized: 118411 +// gas legacy: 122231 +// gas legacyOptimized: 118409 diff --git a/test/libsolidity/semanticTests/array/create_memory_array.sol b/test/libsolidity/semanticTests/array/create_memory_array.sol index a95499fd8aa5..00f32a6e0860 100644 --- a/test/libsolidity/semanticTests/array/create_memory_array.sol +++ b/test/libsolidity/semanticTests/array/create_memory_array.sol @@ -19,5 +19,5 @@ contract C { // ---- // f() -> "A", 8, 4, "B" // gas irOptimized: 136664 -// gas legacy: 121382 +// gas legacy: 121380 // gas legacyOptimized: 115488 diff --git a/test/libsolidity/semanticTests/array/delete/bytes_delete_element.sol b/test/libsolidity/semanticTests/array/delete/bytes_delete_element.sol index 5deaa7d4e80c..f776626ae8e3 100644 --- a/test/libsolidity/semanticTests/array/delete/bytes_delete_element.sol +++ b/test/libsolidity/semanticTests/array/delete/bytes_delete_element.sol @@ -16,6 +16,6 @@ contract c { } // ---- // test1() -> true -// gas irOptimized: 218452 -// gas legacy: 242256 +// gas irOptimized: 218449 +// gas legacy: 242263 // gas legacyOptimized: 241182 diff --git a/test/libsolidity/semanticTests/array/dynamic_array_cleanup.sol b/test/libsolidity/semanticTests/array/dynamic_array_cleanup.sol index 380e30242536..b2be566a9df1 100644 --- a/test/libsolidity/semanticTests/array/dynamic_array_cleanup.sol +++ b/test/libsolidity/semanticTests/array/dynamic_array_cleanup.sol @@ -15,7 +15,7 @@ contract c { // storageEmpty -> 1 // fill() -> // gas irOptimized: 519494 -// gas legacy: 518936 +// gas legacy: 518943 // gas legacyOptimized: 515555 // storageEmpty -> 0 // halfClear() -> diff --git a/test/libsolidity/semanticTests/array/dynamic_arrays_in_storage.sol b/test/libsolidity/semanticTests/array/dynamic_arrays_in_storage.sol index 62b611a878e5..f96473739fa5 100644 --- a/test/libsolidity/semanticTests/array/dynamic_arrays_in_storage.sol +++ b/test/libsolidity/semanticTests/array/dynamic_arrays_in_storage.sol @@ -42,8 +42,8 @@ contract c { // getLengths() -> 0, 0 // setLengths(uint256,uint256): 48, 49 -> // gas irOptimized: 112674 -// gas legacy: 108273 -// gas legacyOptimized: 100269 +// gas legacy: 108272 +// gas legacyOptimized: 100268 // getLengths() -> 48, 49 // setIDStatic(uint256): 11 -> // getID(uint256): 2 -> 11 diff --git a/test/libsolidity/semanticTests/array/fixed_array_cleanup.sol b/test/libsolidity/semanticTests/array/fixed_array_cleanup.sol index cc009b7e9e6b..ebe2186fd60f 100644 --- a/test/libsolidity/semanticTests/array/fixed_array_cleanup.sol +++ b/test/libsolidity/semanticTests/array/fixed_array_cleanup.sol @@ -11,7 +11,7 @@ contract c { // storageEmpty -> 1 // fill() -> // gas irOptimized: 465013 -// gas legacy: 468818 +// gas legacy: 468825 // gas legacyOptimized: 466238 // storageEmpty -> 0 // clear() -> diff --git a/test/libsolidity/semanticTests/array/fixed_arrays_in_constructors.sol b/test/libsolidity/semanticTests/array/fixed_arrays_in_constructors.sol index 817d06c0f5a6..8e9780e3376f 100644 --- a/test/libsolidity/semanticTests/array/fixed_arrays_in_constructors.sol +++ b/test/libsolidity/semanticTests/array/fixed_arrays_in_constructors.sol @@ -11,9 +11,9 @@ contract Creator { // constructor(): 1, 2, 3, 4 -> // gas irOptimized: 104102 // gas irOptimized code: 22400 -// gas legacy: 115186 +// gas legacy: 115185 // gas legacy code: 59000 -// gas legacyOptimized: 104909 +// gas legacyOptimized: 104908 // gas legacyOptimized code: 23800 // r() -> 4 // ch() -> 3 diff --git a/test/libsolidity/semanticTests/array/function_array_cross_calls.sol b/test/libsolidity/semanticTests/array/function_array_cross_calls.sol index e9517c0e38a1..f3dea83bfbab 100644 --- a/test/libsolidity/semanticTests/array/function_array_cross_calls.sol +++ b/test/libsolidity/semanticTests/array/function_array_cross_calls.sol @@ -44,7 +44,7 @@ contract C { // test() -> 5, 6, 7 // gas irOptimized: 86484 // gas irOptimized code: 161200 -// gas legacy: 97576 +// gas legacy: 97551 // gas legacy code: 342800 -// gas legacyOptimized: 87811 +// gas legacyOptimized: 87808 // gas legacyOptimized code: 193000 diff --git a/test/libsolidity/semanticTests/array/invalid_encoding_for_storage_byte_array.sol b/test/libsolidity/semanticTests/array/invalid_encoding_for_storage_byte_array.sol index 5fd53c6d1299..95df74b4d77b 100644 --- a/test/libsolidity/semanticTests/array/invalid_encoding_for_storage_byte_array.sol +++ b/test/libsolidity/semanticTests/array/invalid_encoding_for_storage_byte_array.sol @@ -40,7 +40,7 @@ contract C { // copyFromStorageShort() // x() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000 // copyFromStorageLong() -// gas irOptimized: 121104 +// gas irOptimized: 121095 // gas legacy: 121904 // gas legacyOptimized: 121388 // x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000 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 be1916ef131f..96fb11a2dc94 100644 --- a/test/libsolidity/semanticTests/array/pop/array_pop_array_transition.sol +++ b/test/libsolidity/semanticTests/array/pop/array_pop_array_transition.sol @@ -24,6 +24,6 @@ contract c { // ---- // test() -> 1, 2, 3 // gas irOptimized: 1828226 -// gas legacy: 1822466 +// gas legacy: 1822464 // gas legacyOptimized: 1813404 // 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 73870d4285a0..0c68ab70c600 100644 --- a/test/libsolidity/semanticTests/array/pop/array_pop_uint16_transition.sol +++ b/test/libsolidity/semanticTests/array/pop/array_pop_uint16_transition.sol @@ -19,6 +19,6 @@ contract c { // ---- // test() -> 38, 28, 18 // gas irOptimized: 148380 -// gas legacy: 151184 +// gas legacy: 151182 // gas legacyOptimized: 142418 // 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 e0fc1658154f..86165dde2844 100644 --- a/test/libsolidity/semanticTests/array/pop/array_pop_uint24_transition.sol +++ b/test/libsolidity/semanticTests/array/pop/array_pop_uint24_transition.sol @@ -19,6 +19,6 @@ contract c { // ---- // test() -> 20, 10 // gas irOptimized: 125889 -// gas legacy: 127216 +// gas legacy: 127215 // gas legacyOptimized: 122224 // storageEmpty -> 1 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 c567c4509eaf..18afa649c8c5 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 @@ -16,7 +16,7 @@ contract c { } // ---- // test() -> true -// gas irOptimized: 138848 -// gas legacy: 178397 +// gas irOptimized: 138795 +// gas legacy: 178396 // gas legacyOptimized: 163832 // 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 d9d2d9d2d94e..cbb10a0a1b07 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 @@ -15,7 +15,7 @@ contract c { } // ---- // test() -> -// gas irOptimized: 113679 -// gas legacy: 131245 +// gas irOptimized: 113631 +// gas legacy: 131256 // gas legacyOptimized: 126668 // 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 490de759b550..3ef3571f4bab 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 @@ -9,6 +9,6 @@ contract c { } // ---- // test() -> 0x20, 33, 0x303030303030303030303030303030303030303030303030303030303030303, 0x0300000000000000000000000000000000000000000000000000000000000000 -// gas irOptimized: 106778 -// gas legacy: 121245 +// gas irOptimized: 106762 +// gas legacy: 121252 // gas legacyOptimized: 120370 diff --git a/test/libsolidity/semanticTests/array/push/array_push.sol b/test/libsolidity/semanticTests/array/push/array_push.sol index 6198ba163595..b8eab8733304 100644 --- a/test/libsolidity/semanticTests/array/push/array_push.sol +++ b/test/libsolidity/semanticTests/array/push/array_push.sol @@ -17,5 +17,5 @@ contract c { // ---- // test() -> 5, 4, 3, 3 // gas irOptimized: 111834 -// gas legacy: 111807 +// gas legacy: 111804 // gas legacyOptimized: 111122 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 4bcac0f13829..77ae8c4e23e4 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 @@ -12,6 +12,6 @@ contract C { } // ---- // f(uint120[]): 0x20, 3, 1, 2, 3 -> 1 -// gas irOptimized: 112853 -// gas legacy: 113659 -// gas legacyOptimized: 113466 +// gas irOptimized: 112852 +// gas legacy: 113657 +// gas legacyOptimized: 113465 diff --git a/test/libsolidity/semanticTests/array/push/array_push_struct.sol b/test/libsolidity/semanticTests/array/push/array_push_struct.sol index b6db507ea385..92f071e1fb22 100644 --- a/test/libsolidity/semanticTests/array/push/array_push_struct.sol +++ b/test/libsolidity/semanticTests/array/push/array_push_struct.sol @@ -21,5 +21,5 @@ contract c { // ---- // test() -> 2, 3, 4, 5 // gas irOptimized: 135329 -// gas legacy: 147443 -// gas legacyOptimized: 146434 +// gas legacy: 147437 +// gas legacyOptimized: 146429 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 37de90cb695a..254c14b061cf 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 @@ -17,5 +17,5 @@ contract c { // ---- // 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: 137153 -// gas legacy: 142423 -// gas legacyOptimized: 137981 +// gas legacy: 142414 +// gas legacyOptimized: 137975 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 763cb9a040e1..ffc47eaa395b 100644 --- a/test/libsolidity/semanticTests/array/push/byte_array_push_transition.sol +++ b/test/libsolidity/semanticTests/array/push/byte_array_push_transition.sol @@ -16,5 +16,5 @@ contract c { // ---- // test() -> 0 // gas irOptimized: 167569 -// gas legacy: 206219 +// gas legacy: 206218 // gas legacyOptimized: 197297 diff --git a/test/libsolidity/semanticTests/array/push/nested_bytes_push.sol b/test/libsolidity/semanticTests/array/push/nested_bytes_push.sol index aeaeb9ee72a2..5633199d4865 100644 --- a/test/libsolidity/semanticTests/array/push/nested_bytes_push.sol +++ b/test/libsolidity/semanticTests/array/push/nested_bytes_push.sol @@ -14,5 +14,5 @@ contract C { // ---- // f() -> // gas irOptimized: 179534 -// gas legacy: 181014 -// gas legacyOptimized: 180398 +// gas legacy: 181013 +// gas legacyOptimized: 180397 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 00e454516330..3b35719dbb8d 100644 --- a/test/libsolidity/semanticTests/array/push/push_no_args_2d.sol +++ b/test/libsolidity/semanticTests/array/push/push_no_args_2d.sol @@ -28,14 +28,14 @@ contract C { // l() -> 0 // f(uint256,uint256): 42, 64 -> // gas irOptimized: 112288 -// gas legacy: 107920 -// gas legacyOptimized: 101897 +// gas legacy: 107925 +// gas legacyOptimized: 101896 // l() -> 1 // ll(uint256): 0 -> 43 // a(uint256,uint256): 0, 42 -> 64 // f(uint256,uint256): 84, 128 -> // gas irOptimized: 118708 -// gas legacy: 109972 +// gas legacy: 109977 // gas legacyOptimized: 96331 // l() -> 2 // ll(uint256): 1 -> 85 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 b013a7ebbcf1..de737593c099 100644 --- a/test/libsolidity/semanticTests/array/push/push_no_args_bytes.sol +++ b/test/libsolidity/semanticTests/array/push/push_no_args_bytes.sol @@ -22,7 +22,7 @@ contract C { // l() -> 0 // g(uint256): 70 -> // gas irOptimized: 181778 -// gas legacy: 175185 +// gas legacy: 175192 // gas legacyOptimized: 175005 // l() -> 70 // a(uint256): 69 -> left(69) diff --git a/test/libsolidity/semanticTests/array/reusing_memory.sol b/test/libsolidity/semanticTests/array/reusing_memory.sol index 621860c075c8..fd352dd61afd 100644 --- a/test/libsolidity/semanticTests/array/reusing_memory.sol +++ b/test/libsolidity/semanticTests/array/reusing_memory.sol @@ -26,7 +26,7 @@ contract Main { // f(uint256): 0x34 -> 0x46bddb1178e94d7f2892ff5f366840eb658911794f2c3a44c450aa2c505186c1 // gas irOptimized: 99552 // gas irOptimized code: 12400 -// gas legacy: 101554 +// gas legacy: 101551 // gas legacy code: 23600 // gas legacyOptimized: 99612 // gas legacyOptimized code: 13400 diff --git a/test/libsolidity/semanticTests/byte_array_to_storage_cleanup.sol b/test/libsolidity/semanticTests/byte_array_to_storage_cleanup.sol index dab01b5983c6..238f96b7e588 100644 --- a/test/libsolidity/semanticTests/byte_array_to_storage_cleanup.sol +++ b/test/libsolidity/semanticTests/byte_array_to_storage_cleanup.sol @@ -30,8 +30,8 @@ contract C { // constructor() -> // gas irOptimized: 82100 // gas irOptimized code: 357600 -// gas legacy: 101472 -// gas legacy code: 604200 +// gas legacy: 101532 +// gas legacy code: 604800 // gas legacyOptimized: 84956 // gas legacyOptimized code: 391800 // h() -> 0x20, 0x40, 0x00, 0 diff --git a/test/libsolidity/semanticTests/calldata/copy_from_calldata_removes_bytes_data.sol b/test/libsolidity/semanticTests/calldata/copy_from_calldata_removes_bytes_data.sol index 09dcd034796d..33ab18450624 100644 --- a/test/libsolidity/semanticTests/calldata/copy_from_calldata_removes_bytes_data.sol +++ b/test/libsolidity/semanticTests/calldata/copy_from_calldata_removes_bytes_data.sol @@ -9,7 +9,7 @@ contract c { // EVMVersion: >=byzantium // ---- // (): 1, 2, 3, 4, 5 -> -// gas irOptimized: 155125 +// gas irOptimized: 155122 // gas legacy: 155473 // gas legacyOptimized: 155295 // checkIfDataIsEmpty() -> false diff --git a/test/libsolidity/semanticTests/constructor/arrays_in_constructors.sol b/test/libsolidity/semanticTests/constructor/arrays_in_constructors.sol index 685b1a93890c..8fe8d36f9bb8 100644 --- a/test/libsolidity/semanticTests/constructor/arrays_in_constructors.sol +++ b/test/libsolidity/semanticTests/constructor/arrays_in_constructors.sol @@ -26,7 +26,7 @@ contract Creator { // f(uint256,address[]): 7, 0x40, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 -> 7, 8 // gas irOptimized: 327784 // gas irOptimized code: 94000 -// gas legacy: 336626 +// gas legacy: 336623 // gas legacy code: 244800 -// gas legacyOptimized: 329518 +// gas legacyOptimized: 329515 // gas legacyOptimized code: 117000 diff --git a/test/libsolidity/semanticTests/constructor/bytes_in_constructors_packer.sol b/test/libsolidity/semanticTests/constructor/bytes_in_constructors_packer.sol index 0310d58d7a93..69896ebf1584 100644 --- a/test/libsolidity/semanticTests/constructor/bytes_in_constructors_packer.sol +++ b/test/libsolidity/semanticTests/constructor/bytes_in_constructors_packer.sol @@ -26,7 +26,7 @@ contract Creator { // f(uint256,bytes): 7, 0x40, 78, "abcdefghijklmnopqrstuvwxyzabcdef", "ghijklmnopqrstuvwxyzabcdefghijkl", "mnopqrstuvwxyz" -> 7, "h" // gas irOptimized: 169292 // gas irOptimized code: 99600 -// gas legacy: 172944 +// gas legacy: 172941 // gas legacy code: 239800 -// gas legacyOptimized: 169818 +// gas legacyOptimized: 169815 // gas legacyOptimized code: 118600 diff --git a/test/libsolidity/semanticTests/constructor/bytes_in_constructors_unpacker.sol b/test/libsolidity/semanticTests/constructor/bytes_in_constructors_unpacker.sol index 4194e14a69c0..036d6ca629a3 100644 --- a/test/libsolidity/semanticTests/constructor/bytes_in_constructors_unpacker.sol +++ b/test/libsolidity/semanticTests/constructor/bytes_in_constructors_unpacker.sol @@ -10,9 +10,9 @@ contract Test { // constructor(): 7, 0x40, 78, "abcdefghijklmnopqrstuvwxyzabcdef", "ghijklmnopqrstuvwxyzabcdefghijkl", "mnopqrstuvwxyz" -> // gas irOptimized: 181465 // gas irOptimized code: 78400 -// gas legacy: 195165 +// gas legacy: 195212 // gas legacy code: 109400 -// gas legacyOptimized: 181609 +// gas legacyOptimized: 181608 // gas legacyOptimized code: 71400 // m_x() -> 7 // m_s() -> 0x20, 78, "abcdefghijklmnopqrstuvwxyzabcdef", "ghijklmnopqrstuvwxyzabcdefghijkl", "mnopqrstuvwxyz" diff --git a/test/libsolidity/semanticTests/constructor/constructor_arguments_external.sol b/test/libsolidity/semanticTests/constructor/constructor_arguments_external.sol index 8fa725dad569..7d068338b091 100644 --- a/test/libsolidity/semanticTests/constructor/constructor_arguments_external.sol +++ b/test/libsolidity/semanticTests/constructor/constructor_arguments_external.sol @@ -19,9 +19,9 @@ contract Main { // constructor(): "abc", true // gas irOptimized: 80174 // gas irOptimized code: 24200 -// gas legacy: 85100 +// gas legacy: 85098 // gas legacy code: 58200 -// gas legacyOptimized: 80133 +// gas legacyOptimized: 80132 // gas legacyOptimized code: 22800 // getFlag() -> true // getName() -> "abc" diff --git a/test/libsolidity/semanticTests/constructor/constructor_function_complex.sol b/test/libsolidity/semanticTests/constructor/constructor_function_complex.sol index 33650aff6fb6..13abe72c5cce 100644 --- a/test/libsolidity/semanticTests/constructor/constructor_function_complex.sol +++ b/test/libsolidity/semanticTests/constructor/constructor_function_complex.sol @@ -17,5 +17,5 @@ contract C { } // ---- // f() -> 16 -// gas legacy: 78482 +// gas legacy: 78477 // gas legacy code: 23600 diff --git a/test/libsolidity/semanticTests/constructor/constructor_static_array_argument.sol b/test/libsolidity/semanticTests/constructor/constructor_static_array_argument.sol index 327c41d9be81..5947b257363f 100644 --- a/test/libsolidity/semanticTests/constructor/constructor_static_array_argument.sol +++ b/test/libsolidity/semanticTests/constructor/constructor_static_array_argument.sol @@ -11,9 +11,9 @@ contract C { // constructor(): 1, 2, 3, 4 -> // gas irOptimized: 148129 // gas irOptimized code: 23000 -// gas legacy: 157978 +// gas legacy: 157977 // gas legacy code: 60400 -// gas legacyOptimized: 149974 +// gas legacyOptimized: 149973 // gas legacyOptimized code: 26200 // a() -> 1 // b(uint256): 0 -> 2 diff --git a/test/libsolidity/semanticTests/constructor_inheritance_init_order_2.sol b/test/libsolidity/semanticTests/constructor_inheritance_init_order_2.sol index e19ad39cfad7..d5cca6420e09 100644 --- a/test/libsolidity/semanticTests/constructor_inheritance_init_order_2.sol +++ b/test/libsolidity/semanticTests/constructor_inheritance_init_order_2.sol @@ -11,7 +11,7 @@ contract B is A { // constructor() -> // gas irOptimized: 99436 // gas irOptimized code: 20200 -// gas legacy: 100974 +// gas legacy: 100973 // gas legacy code: 32600 // gas legacyOptimized: 99137 // gas legacyOptimized code: 16200 diff --git a/test/libsolidity/semanticTests/constructor_with_params.sol b/test/libsolidity/semanticTests/constructor_with_params.sol index 1c5a170202f3..c88802029258 100644 --- a/test/libsolidity/semanticTests/constructor_with_params.sol +++ b/test/libsolidity/semanticTests/constructor_with_params.sol @@ -11,7 +11,7 @@ contract C { // constructor(): 2, 0 -> // gas irOptimized: 81170 // gas irOptimized code: 20200 -// gas legacy: 83614 +// gas legacy: 83613 // gas legacy code: 32000 // i() -> 2 // k() -> 0 diff --git a/test/libsolidity/semanticTests/constructor_with_params_diamond_inheritance.sol b/test/libsolidity/semanticTests/constructor_with_params_diamond_inheritance.sol index 29f401a77322..decb6fc259d4 100644 --- a/test/libsolidity/semanticTests/constructor_with_params_diamond_inheritance.sol +++ b/test/libsolidity/semanticTests/constructor_with_params_diamond_inheritance.sol @@ -23,9 +23,9 @@ contract D is B, C { // constructor(): 2, 0 -> // gas irOptimized: 124350 // gas irOptimized code: 27600 -// gas legacy: 128223 +// gas legacy: 128222 // gas legacy code: 40400 -// gas legacyOptimized: 123921 +// gas legacyOptimized: 123920 // gas legacyOptimized code: 20600 // i() -> 2 // j() -> 2 diff --git a/test/libsolidity/semanticTests/constructor_with_params_inheritance.sol b/test/libsolidity/semanticTests/constructor_with_params_inheritance.sol index b0373b74f193..097e2f8088c9 100644 --- a/test/libsolidity/semanticTests/constructor_with_params_inheritance.sol +++ b/test/libsolidity/semanticTests/constructor_with_params_inheritance.sol @@ -14,9 +14,9 @@ contract D is C { // constructor(): 2, 0 -> // gas irOptimized: 101581 // gas irOptimized code: 20200 -// gas legacy: 105193 +// gas legacy: 105192 // gas legacy code: 32000 -// gas legacyOptimized: 101504 +// gas legacyOptimized: 101503 // gas legacyOptimized code: 17000 // i() -> 2 // k() -> 1 diff --git a/test/libsolidity/semanticTests/errors/small_error_optimization.sol b/test/libsolidity/semanticTests/errors/small_error_optimization.sol index 0c9cd750aa32..8128193b7056 100644 --- a/test/libsolidity/semanticTests/errors/small_error_optimization.sol +++ b/test/libsolidity/semanticTests/errors/small_error_optimization.sol @@ -16,7 +16,7 @@ contract B { // f() -> FAILURE, hex"92bbf6e8" // gas irOptimized: 221918 // gas irOptimized code: 42800 -// gas legacy: 233746 -// gas legacy code: 37400 -// gas legacyOptimized: 224864 +// gas legacy: 233752 +// gas legacy code: 38000 +// gas legacyOptimized: 224863 // gas legacyOptimized code: 34200 diff --git a/test/libsolidity/semanticTests/events/event_dynamic_array_storage.sol b/test/libsolidity/semanticTests/events/event_dynamic_array_storage.sol index 76acd4a0b23f..bdd355f68927 100644 --- a/test/libsolidity/semanticTests/events/event_dynamic_array_storage.sol +++ b/test/libsolidity/semanticTests/events/event_dynamic_array_storage.sol @@ -14,5 +14,5 @@ contract C { // createEvent(uint256): 42 -> // ~ emit E(uint256[]): 0x20, 0x03, 0x2a, 0x2b, 0x2c // gas irOptimized: 114231 -// gas legacy: 116314 -// gas legacyOptimized: 114408 +// gas legacy: 116313 +// gas legacyOptimized: 114407 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 bdcda3a09370..cecf31b42d9f 100644 --- a/test/libsolidity/semanticTests/events/event_dynamic_array_storage_v2.sol +++ b/test/libsolidity/semanticTests/events/event_dynamic_array_storage_v2.sol @@ -15,5 +15,5 @@ contract C { // createEvent(uint256): 42 -> // ~ emit E(uint256[]): 0x20, 0x03, 0x2a, 0x2b, 0x2c // gas irOptimized: 114231 -// gas legacy: 116314 -// gas legacyOptimized: 114408 +// gas legacy: 116313 +// gas legacyOptimized: 114407 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 324f456f6794..1ff58d65b566 100644 --- a/test/libsolidity/semanticTests/events/event_dynamic_nested_array_storage_v2.sol +++ b/test/libsolidity/semanticTests/events/event_dynamic_nested_array_storage_v2.sol @@ -16,5 +16,5 @@ contract C { // createEvent(uint256): 42 -> // ~ emit E(uint256[][]): 0x20, 0x02, 0x40, 0xa0, 0x02, 0x2a, 0x2b, 0x02, 0x2c, 0x2d // gas irOptimized: 185148 -// gas legacy: 187495 -// gas legacyOptimized: 184550 +// gas legacy: 187493 +// gas legacyOptimized: 184548 diff --git a/test/libsolidity/semanticTests/events/event_emit_from_other_contract.sol b/test/libsolidity/semanticTests/events/event_emit_from_other_contract.sol index 6a01d0019295..61e1bbdd6c0e 100644 --- a/test/libsolidity/semanticTests/events/event_emit_from_other_contract.sol +++ b/test/libsolidity/semanticTests/events/event_emit_from_other_contract.sol @@ -17,8 +17,8 @@ contract C { // constructor() -> // gas irOptimized: 113970 // gas irOptimized code: 51400 -// gas legacy: 119776 -// gas legacy code: 125000 +// gas legacy: 119791 +// gas legacy code: 125200 // gas legacyOptimized: 114187 // gas legacyOptimized code: 57400 // deposit(bytes32), 18 wei: 0x1234 -> diff --git a/test/libsolidity/semanticTests/events/event_indexed_string.sol b/test/libsolidity/semanticTests/events/event_indexed_string.sol index 0ad2affe377a..2e4b110692fb 100644 --- a/test/libsolidity/semanticTests/events/event_indexed_string.sol +++ b/test/libsolidity/semanticTests/events/event_indexed_string.sol @@ -17,6 +17,6 @@ contract C { // ---- // deposit() -> // ~ emit E(string,uint256[4]): #0xa7fb06bb999a5eb9aff9e0779953f4e1e4ce58044936c2f51c7fb879b85c08bd, #0xe755d8cc1a8cde16a2a31160dcd8017ac32d7e2f13215b29a23cdae40a78aa81 -// gas irOptimized: 332789 -// gas legacy: 365828 -// gas legacyOptimized: 362250 +// gas irOptimized: 332788 +// gas legacy: 366022 +// gas legacyOptimized: 362429 diff --git a/test/libsolidity/semanticTests/externalContracts/base64.sol b/test/libsolidity/semanticTests/externalContracts/base64.sol index a986be149b50..6e23da855783 100644 --- a/test/libsolidity/semanticTests/externalContracts/base64.sol +++ b/test/libsolidity/semanticTests/externalContracts/base64.sol @@ -35,8 +35,8 @@ contract test { // constructor() // gas irOptimized: 79076 // gas irOptimized code: 322000 -// gas legacy: 102034 -// gas legacy code: 627400 +// gas legacy: 102214 +// gas legacy code: 629800 // gas legacyOptimized: 87926 // gas legacyOptimized code: 429800 // encode_inline_asm(bytes): 0x20, 0 -> 0x20, 0 @@ -55,9 +55,9 @@ contract test { // encode_no_asm(bytes): 0x20, 6, "foobar" -> 0x20, 8, "Zm9vYmFy" // encode_inline_asm_large() // gas irOptimized: 1406025 -// gas legacy: 1554031 +// gas legacy: 1554038 // gas legacyOptimized: 1132031 // encode_no_asm_large() // gas irOptimized: 3512081 -// gas legacy: 4587075 +// gas legacy: 4600082 // gas legacyOptimized: 2813075 diff --git a/test/libsolidity/semanticTests/externalContracts/deposit_contract.sol b/test/libsolidity/semanticTests/externalContracts/deposit_contract.sol index 9bfa3a340e5f..c53e49f1f032 100644 --- a/test/libsolidity/semanticTests/externalContracts/deposit_contract.sol +++ b/test/libsolidity/semanticTests/externalContracts/deposit_contract.sol @@ -176,10 +176,10 @@ contract DepositContract is IDepositContract, ERC165 { } // ---- // constructor() -// gas irOptimized: 809602 +// gas irOptimized: 809570 // gas irOptimized code: 558000 -// gas legacy: 919945 -// gas legacy code: 1437600 +// gas legacy: 920228 +// gas legacy code: 1438800 // gas legacyOptimized: 848699 // gas legacyOptimized code: 878200 // supportsInterface(bytes4): 0x0 -> 0 @@ -188,26 +188,26 @@ contract DepositContract is IDepositContract, ERC165 { // supportsInterface(bytes4): 0x8564090700000000000000000000000000000000000000000000000000000000 -> true # the deposit interface id # // get_deposit_root() -> 0xd70a234731285c6804c2a4f56711ddb8c82c99740f207854891028af34e27e5e // gas irOptimized: 109178 -// gas legacy: 142735 +// gas legacy: 142741 // gas legacyOptimized: 117558 // 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: 109178 -// gas legacy: 142735 +// gas legacy: 142741 // gas legacyOptimized: 117558 // 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: 109174 -// gas legacy: 142744 +// gas legacy: 142750 // gas legacyOptimized: 117570 // 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: 109174 -// gas legacy: 142744 +// gas legacy: 142750 // gas legacyOptimized: 117570 // 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 4990d24e9a7e..cb345757f8e1 100644 --- a/test/libsolidity/semanticTests/externalContracts/prbmath_signed.sol +++ b/test/libsolidity/semanticTests/externalContracts/prbmath_signed.sol @@ -50,8 +50,8 @@ contract test { // constructor() // gas irOptimized: 177903 // gas irOptimized code: 1674400 -// gas legacy: 209687 -// gas legacy code: 2204400 +// gas legacy: 209723 +// gas legacy code: 2205000 // gas legacyOptimized: 178012 // gas legacyOptimized code: 1669600 // div(int256,int256): 3141592653589793238, 88714123 -> 35412542528203691288251815328 diff --git a/test/libsolidity/semanticTests/externalContracts/prbmath_unsigned.sol b/test/libsolidity/semanticTests/externalContracts/prbmath_unsigned.sol index 5d95c7a75c84..5902ba4905b1 100644 --- a/test/libsolidity/semanticTests/externalContracts/prbmath_unsigned.sol +++ b/test/libsolidity/semanticTests/externalContracts/prbmath_unsigned.sol @@ -50,8 +50,8 @@ contract test { // constructor() // gas irOptimized: 170626 // gas irOptimized code: 1577400 -// gas legacy: 195146 -// gas legacy code: 1998400 +// gas legacy: 195206 +// gas legacy code: 1999000 // gas legacyOptimized: 168857 // gas legacyOptimized code: 1556200 // div(uint256,uint256): 3141592653589793238, 88714123 -> 35412542528203691288251815328 diff --git a/test/libsolidity/semanticTests/externalContracts/ramanujan_pi.sol b/test/libsolidity/semanticTests/externalContracts/ramanujan_pi.sol index 1aa72b897b97..70a3004ac4b6 100644 --- a/test/libsolidity/semanticTests/externalContracts/ramanujan_pi.sol +++ b/test/libsolidity/semanticTests/externalContracts/ramanujan_pi.sol @@ -35,11 +35,11 @@ contract test { // constructor() // gas irOptimized: 77816 // gas irOptimized code: 307600 -// gas legacy: 92086 -// gas legacy code: 523000 +// gas legacy: 92110 +// gas legacy code: 523600 // gas legacyOptimized: 82667 // gas legacyOptimized code: 369200 // prb_pi() -> 3141592656369545286 // gas irOptimized: 57478 -// gas legacy: 100947 +// gas legacy: 100657 // gas legacyOptimized: 75735 diff --git a/test/libsolidity/semanticTests/externalContracts/snark.sol b/test/libsolidity/semanticTests/externalContracts/snark.sol index 97d15183a19b..906279d17935 100644 --- a/test/libsolidity/semanticTests/externalContracts/snark.sol +++ b/test/libsolidity/semanticTests/externalContracts/snark.sol @@ -294,11 +294,11 @@ contract Test { // f() -> true // g() -> true // pair() -> true -// gas irOptimized: 270424 -// gas legacy: 275206 -// gas legacyOptimized: 266925 +// gas irOptimized: 270409 +// gas legacy: 275219 +// gas legacyOptimized: 266862 // verifyTx() -> true // ~ emit Verified(string): 0x20, 0x16, "Successfully verified." -// gas irOptimized: 785783 -// gas legacy: 801868 -// gas legacyOptimized: 770942 +// gas irOptimized: 785720 +// gas legacy: 801903 +// gas legacyOptimized: 770941 diff --git a/test/libsolidity/semanticTests/externalContracts/strings.sol b/test/libsolidity/semanticTests/externalContracts/strings.sol index 773d7156afa3..cb9616bbe40b 100644 --- a/test/libsolidity/semanticTests/externalContracts/strings.sol +++ b/test/libsolidity/semanticTests/externalContracts/strings.sol @@ -51,8 +51,8 @@ contract test { // constructor() // gas irOptimized: 95303 // gas irOptimized code: 520000 -// gas legacy: 126106 -// gas legacy code: 930200 +// gas legacy: 126346 +// gas legacy code: 932600 // gas legacyOptimized: 102639 // gas legacyOptimized code: 612400 // toSlice(string): 0x20, 11, "hello world" -> 11, 0xa0 @@ -73,5 +73,5 @@ contract test { // gas legacyOptimized: 27914 // benchmark(string,bytes32): 0x40, 0x0842021, 8, "solidity" -> 0x2020 // gas irOptimized: 1976778 -// gas legacy: 4233999 -// gas legacyOptimized: 2318670 +// gas legacy: 4234020 +// gas legacyOptimized: 2318668 diff --git a/test/libsolidity/semanticTests/functionCall/creation_function_call_with_args.sol b/test/libsolidity/semanticTests/functionCall/creation_function_call_with_args.sol index f7c05c10c4d6..08e9f36f5981 100644 --- a/test/libsolidity/semanticTests/functionCall/creation_function_call_with_args.sol +++ b/test/libsolidity/semanticTests/functionCall/creation_function_call_with_args.sol @@ -17,7 +17,7 @@ contract D { // constructor(): 2 -> // gas irOptimized: 138930 // gas irOptimized code: 53800 -// gas legacy: 145570 +// gas legacy: 145569 // gas legacy code: 95600 // gas legacyOptimized: 138297 // gas legacyOptimized code: 54600 diff --git a/test/libsolidity/semanticTests/functionCall/creation_function_call_with_salt.sol b/test/libsolidity/semanticTests/functionCall/creation_function_call_with_salt.sol index 9742a1d2f373..320b105637f1 100644 --- a/test/libsolidity/semanticTests/functionCall/creation_function_call_with_salt.sol +++ b/test/libsolidity/semanticTests/functionCall/creation_function_call_with_salt.sol @@ -19,7 +19,7 @@ contract D { // constructor(): 2 -> // gas irOptimized: 139112 // gas irOptimized code: 53800 -// gas legacy: 145936 +// gas legacy: 145935 // gas legacy code: 95600 // gas legacyOptimized: 138529 // gas legacyOptimized code: 54600 diff --git a/test/libsolidity/semanticTests/functionCall/external_call_to_nonexisting.sol b/test/libsolidity/semanticTests/functionCall/external_call_to_nonexisting.sol index 87f7cbebb0d5..472921c1d25c 100644 --- a/test/libsolidity/semanticTests/functionCall/external_call_to_nonexisting.sol +++ b/test/libsolidity/semanticTests/functionCall/external_call_to_nonexisting.sol @@ -24,10 +24,10 @@ contract C { // constructor(), 1 ether -> // gas irOptimized: 88853 // gas irOptimized code: 164400 -// gas legacy: 102626 -// gas legacy code: 333200 -// gas legacyOptimized: 91599 -// gas legacyOptimized code: 197800 +// gas legacy: 102721 +// gas legacy code: 334400 +// gas legacyOptimized: 91499 +// gas legacyOptimized code: 196400 // f(uint256): 0 -> FAILURE // f(uint256): 1 -> FAILURE // f(uint256): 2 -> FAILURE 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 9da010e9bc21..d1b6e8e866ae 100644 --- a/test/libsolidity/semanticTests/functionCall/external_call_to_nonexisting_debugstrings.sol +++ b/test/libsolidity/semanticTests/functionCall/external_call_to_nonexisting_debugstrings.sol @@ -27,10 +27,10 @@ contract C { // constructor(), 1 ether -> // gas irOptimized: 98698 // gas irOptimized code: 284200 -// gas legacy: 123163 -// gas legacy code: 681200 -// gas legacyOptimized: 107069 -// gas legacyOptimized code: 387800 +// gas legacy: 123258 +// gas legacy code: 682400 +// gas legacyOptimized: 106969 +// gas legacyOptimized code: 386400 // 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" diff --git a/test/libsolidity/semanticTests/functionCall/failed_create.sol b/test/libsolidity/semanticTests/functionCall/failed_create.sol index b6c077753a51..657b4b5cfff6 100644 --- a/test/libsolidity/semanticTests/functionCall/failed_create.sol +++ b/test/libsolidity/semanticTests/functionCall/failed_create.sol @@ -29,8 +29,8 @@ contract C { // x() -> 1 // stack(uint256): 1023 -> FAILURE // gas irOptimized: 252410 -// gas legacy: 477722 -// gas legacyOptimized: 299567 +// gas legacy: 476845 +// gas legacyOptimized: 299061 // x() -> 1 // stack(uint256): 10 -> 0x87948bd7ebbe13a00bfd930c93e4828ab18e3908 // x() -> 2 diff --git a/test/libsolidity/semanticTests/functionCall/gas_and_value_basic.sol b/test/libsolidity/semanticTests/functionCall/gas_and_value_basic.sol index bf6f2c4baf4d..e6187d06e2df 100644 --- a/test/libsolidity/semanticTests/functionCall/gas_and_value_basic.sol +++ b/test/libsolidity/semanticTests/functionCall/gas_and_value_basic.sol @@ -40,8 +40,8 @@ contract test { // constructor(), 20 wei -> // gas irOptimized: 120218 // gas irOptimized code: 132000 -// gas legacy: 130568 -// gas legacy code: 261000 +// gas legacy: 130583 +// gas legacy code: 261200 // gas legacyOptimized: 121069 // gas legacyOptimized code: 147000 // sendAmount(uint256): 5 -> 5 diff --git a/test/libsolidity/semanticTests/functionCall/gas_and_value_brace_syntax.sol b/test/libsolidity/semanticTests/functionCall/gas_and_value_brace_syntax.sol index ebc78a437f69..41079af03955 100644 --- a/test/libsolidity/semanticTests/functionCall/gas_and_value_brace_syntax.sol +++ b/test/libsolidity/semanticTests/functionCall/gas_and_value_brace_syntax.sol @@ -39,8 +39,8 @@ contract test { // constructor(), 20 wei -> // gas irOptimized: 120218 // gas irOptimized code: 132000 -// gas legacy: 130568 -// gas legacy code: 261000 +// gas legacy: 130583 +// gas legacy code: 261200 // gas legacyOptimized: 121069 // gas legacyOptimized code: 147000 // sendAmount(uint256): 5 -> 5 diff --git a/test/libsolidity/semanticTests/functionCall/mapping_array_internal_argument.sol b/test/libsolidity/semanticTests/functionCall/mapping_array_internal_argument.sol index 7a9bf6014bad..7505e20cce47 100644 --- a/test/libsolidity/semanticTests/functionCall/mapping_array_internal_argument.sol +++ b/test/libsolidity/semanticTests/functionCall/mapping_array_internal_argument.sol @@ -19,8 +19,8 @@ contract test { // ---- // set(uint8,uint8,uint8,uint8,uint8): 1, 21, 22, 42, 43 -> 0, 0, 0, 0 // gas irOptimized: 111237 -// gas legacy: 113748 -// gas legacyOptimized: 111772 +// gas legacy: 113742 +// gas legacyOptimized: 111768 // get(uint8): 1 -> 21, 22, 42, 43 // set(uint8,uint8,uint8,uint8,uint8): 1, 10, 30, 11, 31 -> 21, 22, 42, 43 // get(uint8): 1 -> 10, 30, 11, 31 diff --git a/test/libsolidity/semanticTests/functionTypes/store_function.sol b/test/libsolidity/semanticTests/functionTypes/store_function.sol index 5397d0b70187..eeab740aa0fb 100644 --- a/test/libsolidity/semanticTests/functionTypes/store_function.sol +++ b/test/libsolidity/semanticTests/functionTypes/store_function.sol @@ -26,7 +26,7 @@ contract C { // ---- // t() -> 9 // gas irOptimized: 99064 -// gas legacy: 79495 +// gas legacy: 79492 // gas legacy code: 69600 -// gas legacyOptimized: 77588 +// gas legacyOptimized: 77587 // gas legacyOptimized code: 28600 diff --git a/test/libsolidity/semanticTests/immutable/multi_creation.sol b/test/libsolidity/semanticTests/immutable/multi_creation.sol index e1eb0621a611..aa8a1ad8a860 100644 --- a/test/libsolidity/semanticTests/immutable/multi_creation.sol +++ b/test/libsolidity/semanticTests/immutable/multi_creation.sol @@ -29,9 +29,9 @@ contract C { // f() -> 3, 7, 5 // gas irOptimized: 86796 // gas irOptimized code: 37200 -// gas legacy: 87728 +// gas legacy: 87727 // gas legacy code: 60800 -// gas legacyOptimized: 86771 +// gas legacyOptimized: 86770 // gas legacyOptimized code: 37200 // x() -> 7 // y() -> 5 diff --git a/test/libsolidity/semanticTests/immutable/use_scratch.sol b/test/libsolidity/semanticTests/immutable/use_scratch.sol index 2ee05af918c7..432c3c207206 100644 --- a/test/libsolidity/semanticTests/immutable/use_scratch.sol +++ b/test/libsolidity/semanticTests/immutable/use_scratch.sol @@ -17,7 +17,7 @@ contract C { // constructor(): 3 -> // gas irOptimized: 81194 // gas irOptimized code: 42400 -// gas legacy: 88245 +// gas legacy: 88244 // gas legacy code: 109400 // gas legacyOptimized: 81858 // gas legacyOptimized code: 55800 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 0567c2ab1412..f64a2e12a10b 100644 --- a/test/libsolidity/semanticTests/inheritance/inherited_function_calldata_calldata_interface.sol +++ b/test/libsolidity/semanticTests/inheritance/inherited_function_calldata_calldata_interface.sol @@ -23,5 +23,5 @@ contract B { // ---- // g() -> 42 // gas irOptimized: 80813 -// gas legacy: 55871 +// gas legacy: 55868 // gas legacy code: 66600 diff --git a/test/libsolidity/semanticTests/inheritance/inherited_function_calldata_memory_interface.sol b/test/libsolidity/semanticTests/inheritance/inherited_function_calldata_memory_interface.sol index 5234c27adf12..07beb2c537d8 100644 --- a/test/libsolidity/semanticTests/inheritance/inherited_function_calldata_memory_interface.sol +++ b/test/libsolidity/semanticTests/inheritance/inherited_function_calldata_memory_interface.sol @@ -23,7 +23,7 @@ contract B { // ---- // g() -> 42 // gas irOptimized: 100282 -// gas legacy: 56840 +// gas legacy: 56839 // gas legacy code: 123600 -// gas legacyOptimized: 55002 +// gas legacyOptimized: 55001 // gas legacyOptimized code: 60600 diff --git a/test/libsolidity/semanticTests/inheritance/member_notation_ctor.sol b/test/libsolidity/semanticTests/inheritance/member_notation_ctor.sol index e704a297bbac..b9697c5ae1d7 100644 --- a/test/libsolidity/semanticTests/inheritance/member_notation_ctor.sol +++ b/test/libsolidity/semanticTests/inheritance/member_notation_ctor.sol @@ -19,8 +19,8 @@ contract A { } // ---- // g(int256): -1 -> -1 -// gas legacy: 77878 +// gas legacy: 77876 // gas legacy code: 24200 // g(int256): 10 -> 10 -// gas legacy: 77506 +// gas legacy: 77504 // gas legacy code: 24200 diff --git a/test/libsolidity/semanticTests/inheritance/value_for_constructor.sol b/test/libsolidity/semanticTests/inheritance/value_for_constructor.sol index fdd0bafaadfe..39b25c005f0e 100644 --- a/test/libsolidity/semanticTests/inheritance/value_for_constructor.sol +++ b/test/libsolidity/semanticTests/inheritance/value_for_constructor.sol @@ -41,9 +41,9 @@ contract Main { // constructor(), 22 wei -> // gas irOptimized: 143864 // gas irOptimized code: 118000 -// gas legacy: 156586 -// gas legacy code: 236200 -// gas legacyOptimized: 143593 +// gas legacy: 156599 +// gas legacy code: 236400 +// gas legacyOptimized: 143592 // gas legacyOptimized code: 118000 // getFlag() -> true // getName() -> "abc" diff --git a/test/libsolidity/semanticTests/inlineAssembly/transient_storage_selfdestruct.sol b/test/libsolidity/semanticTests/inlineAssembly/transient_storage_selfdestruct.sol index a375207252dc..c2066ef8be1e 100644 --- a/test/libsolidity/semanticTests/inlineAssembly/transient_storage_selfdestruct.sol +++ b/test/libsolidity/semanticTests/inlineAssembly/transient_storage_selfdestruct.sol @@ -42,13 +42,13 @@ contract D { // constructor() -> // gas irOptimized: 127596 // gas irOptimized code: 221000 -// gas legacy: 149357 -// gas legacy code: 499800 -// gas legacyOptimized: 125830 -// gas legacyOptimized code: 203200 +// gas legacy: 149480 +// gas legacy code: 501200 +// gas legacyOptimized: 125846 +// gas legacyOptimized code: 203400 // destroy() -> // createAndDestroy() -> -// gas legacy: 67044 +// gas legacy: 67048 // gas legacy code: 92600 -// gas legacyOptimized: 65675 +// gas legacyOptimized: 65677 // gas legacyOptimized code: 39400 diff --git a/test/libsolidity/semanticTests/inlineAssembly/tstore_hidden_staticcall.sol b/test/libsolidity/semanticTests/inlineAssembly/tstore_hidden_staticcall.sol index d64c7dfb5fce..4e4f30a75618 100644 --- a/test/libsolidity/semanticTests/inlineAssembly/tstore_hidden_staticcall.sol +++ b/test/libsolidity/semanticTests/inlineAssembly/tstore_hidden_staticcall.sol @@ -19,5 +19,5 @@ contract C { // ---- // test() -> FAILURE // gas irOptimized: 98437877 -// gas legacy: 98437872 -// gas legacyOptimized: 98437873 +// gas legacy: 98437871 +// gas legacyOptimized: 98437872 diff --git a/test/libsolidity/semanticTests/isoltestTesting/balance_other_contract.sol b/test/libsolidity/semanticTests/isoltestTesting/balance_other_contract.sol index 8ec19fffa573..1240a8251427 100644 --- a/test/libsolidity/semanticTests/isoltestTesting/balance_other_contract.sol +++ b/test/libsolidity/semanticTests/isoltestTesting/balance_other_contract.sol @@ -18,7 +18,7 @@ contract ClientReceipt { // constructor(), 2000 wei -> // gas irOptimized: 114353 // gas irOptimized code: 58800 -// gas legacy: 118618 +// gas legacy: 118617 // gas legacy code: 111400 // gas legacyOptimized: 114067 // gas legacyOptimized code: 59800 diff --git a/test/libsolidity/semanticTests/libraries/internal_types_in_library.sol b/test/libsolidity/semanticTests/libraries/internal_types_in_library.sol index 817118473107..d59cedfdc860 100644 --- a/test/libsolidity/semanticTests/libraries/internal_types_in_library.sol +++ b/test/libsolidity/semanticTests/libraries/internal_types_in_library.sol @@ -23,5 +23,5 @@ contract Test { // library: Lib // f() -> 4, 0x11 // gas irOptimized: 111419 -// gas legacy: 132935 -// gas legacyOptimized: 118023 +// gas legacy: 132930 +// gas legacyOptimized: 118020 diff --git a/test/libsolidity/semanticTests/libraries/using_library_mappings_public.sol b/test/libsolidity/semanticTests/libraries/using_library_mappings_public.sol index bbdc920471bc..17406a907a47 100644 --- a/test/libsolidity/semanticTests/libraries/using_library_mappings_public.sol +++ b/test/libsolidity/semanticTests/libraries/using_library_mappings_public.sol @@ -20,5 +20,5 @@ contract Test { // library: Lib // f() -> 1, 0, 0x2a, 0x17, 0, 0x63 // gas irOptimized: 119837 -// gas legacy: 124674 -// gas legacyOptimized: 119669 +// gas legacy: 124661 +// gas legacyOptimized: 119665 diff --git a/test/libsolidity/semanticTests/libraries/using_library_mappings_return.sol b/test/libsolidity/semanticTests/libraries/using_library_mappings_return.sol index 98cdf4fd18cd..6e852fdce0f4 100644 --- a/test/libsolidity/semanticTests/libraries/using_library_mappings_return.sol +++ b/test/libsolidity/semanticTests/libraries/using_library_mappings_return.sol @@ -18,5 +18,5 @@ contract Test { // library: Lib // f() -> 1, 0, 0x2a, 0x17, 0, 0x63 // gas irOptimized: 119568 -// gas legacy: 125109 -// gas legacyOptimized: 120128 +// gas legacy: 125087 +// gas legacyOptimized: 120120 diff --git a/test/libsolidity/semanticTests/libraries/using_library_structs.sol b/test/libsolidity/semanticTests/libraries/using_library_structs.sol index e709a5b5b93c..c2ecf1036e88 100644 --- a/test/libsolidity/semanticTests/libraries/using_library_structs.sol +++ b/test/libsolidity/semanticTests/libraries/using_library_structs.sol @@ -21,4 +21,4 @@ contract Test { // library: Lib // f() -> 7, 8 // gas irOptimized: 101818 -// gas legacy: 101429 +// gas legacy: 101428 diff --git a/test/libsolidity/semanticTests/operators/userDefined/operator_making_pure_external_call.sol b/test/libsolidity/semanticTests/operators/userDefined/operator_making_pure_external_call.sol index a621b4c12ad5..ec41099eecbb 100644 --- a/test/libsolidity/semanticTests/operators/userDefined/operator_making_pure_external_call.sol +++ b/test/libsolidity/semanticTests/operators/userDefined/operator_making_pure_external_call.sol @@ -53,13 +53,13 @@ contract C { // ---- // testMul(int32,int32): 42, 10 -> 420 // gas irOptimized: 102563 -// gas legacy: 56981 +// gas legacy: 56978 // gas legacy code: 127000 -// gas legacyOptimized: 55163 +// gas legacyOptimized: 55161 // gas legacyOptimized code: 68400 // testInc(int32): 42 -> 43 // gas irOptimized: 102386 -// gas legacy: 56239 +// gas legacy: 56238 // gas legacy code: 127000 // gas legacyOptimized: 54851 // gas legacyOptimized code: 68400 diff --git a/test/libsolidity/semanticTests/operators/userDefined/operator_making_view_external_call.sol b/test/libsolidity/semanticTests/operators/userDefined/operator_making_view_external_call.sol index 84f6bf08e7a6..7e70eb091bf6 100644 --- a/test/libsolidity/semanticTests/operators/userDefined/operator_making_view_external_call.sol +++ b/test/libsolidity/semanticTests/operators/userDefined/operator_making_view_external_call.sol @@ -59,13 +59,13 @@ contract C { // ---- // testMul(int32,int32): 42, 10 -> 420 // gas irOptimized: 102563 -// gas legacy: 56981 +// gas legacy: 56978 // gas legacy code: 127000 -// gas legacyOptimized: 55163 +// gas legacyOptimized: 55161 // gas legacyOptimized code: 68400 // testInc(int32): 42 -> 43 // gas irOptimized: 102386 -// gas legacy: 56239 +// gas legacy: 56238 // gas legacy code: 127000 // gas legacyOptimized: 54851 // gas legacyOptimized code: 68400 diff --git a/test/libsolidity/semanticTests/salted_create/prediction_example.sol b/test/libsolidity/semanticTests/salted_create/prediction_example.sol index 75174729326f..7d0e3c8b0dbc 100644 --- a/test/libsolidity/semanticTests/salted_create/prediction_example.sol +++ b/test/libsolidity/semanticTests/salted_create/prediction_example.sol @@ -26,5 +26,5 @@ contract C { // compileViaYul: also // ---- // createDSalted(bytes32,uint256): 42, 64 -> -// gas legacy: 78574 +// gas legacy: 78573 // gas legacy code: 23600 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 083c9a5e4838..25d1935770d1 100644 --- a/test/libsolidity/semanticTests/salted_create/salted_create_with_value.sol +++ b/test/libsolidity/semanticTests/salted_create/salted_create_with_value.sol @@ -23,7 +23,7 @@ contract A { // f(), 10 ether -> 3007, 3008, 3009 // gas irOptimized: 187022 // gas irOptimized code: 67200 -// gas legacy: 190863 +// gas legacy: 190858 // gas legacy code: 190200 -// gas legacyOptimized: 187258 +// gas legacyOptimized: 187256 // gas legacyOptimized code: 92400 diff --git a/test/libsolidity/semanticTests/smoke/constructor.sol b/test/libsolidity/semanticTests/smoke/constructor.sol index 2783fe4a8c9c..d5c5280aef4b 100644 --- a/test/libsolidity/semanticTests/smoke/constructor.sol +++ b/test/libsolidity/semanticTests/smoke/constructor.sol @@ -14,9 +14,9 @@ contract C { // constructor(), 2 wei: 3 -> // gas irOptimized: 78996 // gas irOptimized code: 25400 -// gas legacy: 83056 +// gas legacy: 83055 // gas legacy code: 65200 -// gas legacyOptimized: 78899 +// gas legacyOptimized: 78898 // gas legacyOptimized code: 27800 // state() -> 3 // balance() -> 2 diff --git a/test/libsolidity/semanticTests/storage/empty_nonempty_empty.sol b/test/libsolidity/semanticTests/storage/empty_nonempty_empty.sol index 0c2f54b9e759..8a795373e061 100644 --- a/test/libsolidity/semanticTests/storage/empty_nonempty_empty.sol +++ b/test/libsolidity/semanticTests/storage/empty_nonempty_empty.sol @@ -22,7 +22,7 @@ contract Test { // set(bytes): 0x20, 0 // storageEmpty -> 1 // set(bytes): 0x20, 66, "12345678901234567890123456789012", "12345678901234567890123456789012", "12" -// gas irOptimized: 111852 +// gas irOptimized: 111849 // gas legacy: 112734 // gas legacyOptimized: 112084 // storageEmpty -> 0 diff --git a/test/libsolidity/semanticTests/storage/packed_storage_structs_bytes.sol b/test/libsolidity/semanticTests/storage/packed_storage_structs_bytes.sol index 75edb1c9e0fe..7d19bc47162e 100644 --- a/test/libsolidity/semanticTests/storage/packed_storage_structs_bytes.sol +++ b/test/libsolidity/semanticTests/storage/packed_storage_structs_bytes.sol @@ -43,5 +43,5 @@ contract C { // ---- // test() -> true // gas irOptimized: 132633 -// gas legacy: 136009 +// gas legacy: 136010 // gas legacyOptimized: 133478 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 ebf546fe2803..2767486131d8 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 @@ -17,5 +17,5 @@ contract C { // ---- // f(uint32,(uint128,uint256[][2],uint32)): 55, 0x40, 77, 0x60, 88, 0x40, 0x40, 2, 1, 2 -> 55, 77, 1, 2, 88 // gas irOptimized: 202902 -// gas legacy: 207384 -// gas legacyOptimized: 203588 +// gas legacy: 207376 +// 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 4465b1a3eece..8ec31a5c109a 100644 --- a/test/libsolidity/semanticTests/structs/conversion/recursive_storage_memory.sol +++ b/test/libsolidity/semanticTests/structs/conversion/recursive_storage_memory.sol @@ -24,5 +24,5 @@ contract CopyTest { // ---- // run() -> 2, 23, 42 // gas irOptimized: 192828 -// gas legacy: 185731 -// gas legacyOptimized: 184458 +// gas legacy: 185730 +// gas legacyOptimized: 184457 diff --git a/test/libsolidity/semanticTests/structs/copy_from_mapping.sol b/test/libsolidity/semanticTests/structs/copy_from_mapping.sol index a072fb0576b7..037ff20679f0 100644 --- a/test/libsolidity/semanticTests/structs/copy_from_mapping.sol +++ b/test/libsolidity/semanticTests/structs/copy_from_mapping.sol @@ -37,7 +37,7 @@ contract C { // ---- // to_state() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 // gas irOptimized: 121282 -// gas legacy: 122978 +// gas legacy: 122977 // gas legacyOptimized: 121652 // to_storage() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 // to_memory() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 diff --git a/test/libsolidity/semanticTests/structs/copy_struct_array_from_storage.sol b/test/libsolidity/semanticTests/structs/copy_struct_array_from_storage.sol index 29e7afca361a..600eb35ab2ee 100644 --- a/test/libsolidity/semanticTests/structs/copy_struct_array_from_storage.sol +++ b/test/libsolidity/semanticTests/structs/copy_struct_array_from_storage.sol @@ -88,8 +88,8 @@ contract Test { // ---- // test1() -> true // gas irOptimized: 152965 -// gas legacy: 153012 -// gas legacyOptimized: 152637 +// gas legacy: 153010 +// gas legacyOptimized: 152636 // test2() -> true // test3() -> true // test4() -> true diff --git a/test/libsolidity/semanticTests/structs/copy_substructures_from_mapping.sol b/test/libsolidity/semanticTests/structs/copy_substructures_from_mapping.sol index 61d2d68aada7..7188e1befe7a 100644 --- a/test/libsolidity/semanticTests/structs/copy_substructures_from_mapping.sol +++ b/test/libsolidity/semanticTests/structs/copy_substructures_from_mapping.sol @@ -45,7 +45,7 @@ contract C { // ---- // to_state() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 // gas irOptimized: 121454 -// gas legacy: 123117 +// gas legacy: 123114 // gas legacyOptimized: 121659 // to_storage() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 // to_memory() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 diff --git a/test/libsolidity/semanticTests/structs/copy_substructures_to_mapping.sol b/test/libsolidity/semanticTests/structs/copy_substructures_to_mapping.sol index 7d458ca29397..54b659ba0757 100644 --- a/test/libsolidity/semanticTests/structs/copy_substructures_to_mapping.sol +++ b/test/libsolidity/semanticTests/structs/copy_substructures_to_mapping.sol @@ -53,13 +53,13 @@ contract C { // ---- // from_memory() -> 0x20, 0x60, 0xa0, 0x15, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 // gas irOptimized: 122720 -// gas legacy: 130136 -// gas legacyOptimized: 128649 +// gas legacy: 130131 +// gas legacyOptimized: 128648 // from_state() -> 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 // gas irOptimized: 121424 -// gas legacy: 123191 -// gas legacyOptimized: 121764 +// gas legacy: 123190 +// gas legacyOptimized: 121758 // from_calldata((bytes,uint16[],uint16)): 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 -> 0x20, 0x60, 0xa0, 0x15, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 // gas irOptimized: 114852 -// gas legacy: 122425 -// gas legacyOptimized: 120700 +// gas legacy: 122423 +// gas legacyOptimized: 120698 diff --git a/test/libsolidity/semanticTests/structs/copy_to_mapping.sol b/test/libsolidity/semanticTests/structs/copy_to_mapping.sol index 068dc3d8c682..d020998b47c5 100644 --- a/test/libsolidity/semanticTests/structs/copy_to_mapping.sol +++ b/test/libsolidity/semanticTests/structs/copy_to_mapping.sol @@ -46,17 +46,17 @@ contract C { // ---- // from_state() -> 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 // gas irOptimized: 121515 -// gas legacy: 123053 +// gas legacy: 123051 // gas legacyOptimized: 121704 // from_storage() -> 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 // gas irOptimized: 121559 -// gas legacy: 123102 +// gas legacy: 123109 // gas legacyOptimized: 121756 // from_memory() -> 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 // gas irOptimized: 122740 -// gas legacy: 129997 -// gas legacyOptimized: 128645 +// gas legacy: 129996 +// gas legacyOptimized: 128644 // from_calldata((bytes,uint16[],uint16)): 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 -> 0x20, 0x60, 0xa0, 21, 3, 0x666f6f0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 // gas irOptimized: 114824 -// gas legacy: 118210 -// gas legacyOptimized: 115329 +// gas legacy: 118207 +// gas legacyOptimized: 115327 diff --git a/test/libsolidity/semanticTests/structs/memory_structs_nested_load.sol b/test/libsolidity/semanticTests/structs/memory_structs_nested_load.sol index 5ba9765415d9..6785f2108b13 100644 --- a/test/libsolidity/semanticTests/structs/memory_structs_nested_load.sol +++ b/test/libsolidity/semanticTests/structs/memory_structs_nested_load.sol @@ -67,6 +67,6 @@ contract Test { // ---- // load() -> 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 // gas irOptimized: 110772 -// gas legacy: 112964 +// gas legacy: 112959 // gas legacyOptimized: 110876 // 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 955e082b72ae..e50265e5175d 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 @@ -23,17 +23,17 @@ contract c { // ---- // storageEmpty -> 1 // set(uint256,bytes,uint256): 12, 0x60, 13, 33, "12345678901234567890123456789012", "3" -> true -// gas irOptimized: 133560 -// gas legacy: 134628 -// gas legacyOptimized: 133858 +// gas irOptimized: 133557 +// gas legacy: 134624 +// gas legacyOptimized: 133856 // test(uint256): 32 -> "3" // storageEmpty -> 0 // copy() -> true // storageEmpty -> 1 // set(uint256,bytes,uint256): 12, 0x60, 13, 33, "12345678901234567890123456789012", "3" -> true -// gas irOptimized: 133560 -// gas legacy: 134628 -// gas legacyOptimized: 133858 +// gas irOptimized: 133557 +// gas legacy: 134624 +// gas legacyOptimized: 133856 // storageEmpty -> 0 // del() -> true // storageEmpty -> 1 diff --git a/test/libsolidity/semanticTests/structs/struct_copy.sol b/test/libsolidity/semanticTests/structs/struct_copy.sol index 1fb9ef2168f6..e148f81cc880 100644 --- a/test/libsolidity/semanticTests/structs/struct_copy.sol +++ b/test/libsolidity/semanticTests/structs/struct_copy.sol @@ -36,13 +36,13 @@ contract c { // ---- // set(uint256): 7 -> true // gas irOptimized: 109932 -// gas legacy: 110597 +// gas legacy: 110593 // gas legacyOptimized: 110003 // retrieve(uint256): 7 -> 1, 3, 4, 2 // copy(uint256,uint256): 7, 8 -> true // gas irOptimized: 118581 -// gas legacy: 119147 -// gas legacyOptimized: 118619 +// gas legacy: 119144 +// gas legacyOptimized: 118618 // retrieve(uint256): 7 -> 1, 3, 4, 2 // retrieve(uint256): 8 -> 1, 3, 4, 2 // copy(uint256,uint256): 0, 7 -> true 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 28998df448dd..cea1105669aa 100644 --- a/test/libsolidity/semanticTests/structs/struct_delete_storage_with_array.sol +++ b/test/libsolidity/semanticTests/structs/struct_delete_storage_with_array.sol @@ -42,10 +42,10 @@ contract C { } // ---- // f() -> -// gas irOptimized: 113477 +// gas irOptimized: 113465 // gas legacy: 113591 -// gas legacyOptimized: 113103 +// gas legacyOptimized: 113098 // g() -> -// gas irOptimized: 118843 +// gas irOptimized: 118828 // gas legacy: 118764 -// gas legacyOptimized: 118172 +// gas legacyOptimized: 118168 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 bd9fcf3e2303..0de21947a4e7 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 @@ -29,5 +29,5 @@ contract C { // ---- // f() -> 42, 23, 34, 42, 42 // gas irOptimized: 110682 -// gas legacy: 111993 +// gas legacy: 111990 // gas legacyOptimized: 110546 diff --git a/test/libsolidity/semanticTests/structs/structs.sol b/test/libsolidity/semanticTests/structs/structs.sol index 190387051349..96503fa11e1f 100644 --- a/test/libsolidity/semanticTests/structs/structs.sol +++ b/test/libsolidity/semanticTests/structs/structs.sol @@ -31,6 +31,6 @@ contract test { // check() -> false // set() -> // gas irOptimized: 134073 -// gas legacy: 135246 +// gas legacy: 135243 // gas legacyOptimized: 134062 // check() -> true diff --git a/test/libsolidity/semanticTests/types/mapping/copy_from_mapping_to_mapping.sol b/test/libsolidity/semanticTests/types/mapping/copy_from_mapping_to_mapping.sol index 19c31f288011..26e8294e3ac9 100644 --- a/test/libsolidity/semanticTests/types/mapping/copy_from_mapping_to_mapping.sol +++ b/test/libsolidity/semanticTests/types/mapping/copy_from_mapping_to_mapping.sol @@ -30,5 +30,5 @@ contract C { // ---- // f() -> 0x20, 7, 8, 9, 0xa0, 13, 2, 0x40, 0xa0, 2, 3, 4, 2, 3, 4 // gas irOptimized: 197102 -// gas legacy: 199891 +// gas legacy: 199887 // gas legacyOptimized: 196845 diff --git a/test/libsolidity/semanticTests/userDefinedValueType/calldata.sol b/test/libsolidity/semanticTests/userDefinedValueType/calldata.sol index 1433386e5a24..015d51c1f54b 100644 --- a/test/libsolidity/semanticTests/userDefinedValueType/calldata.sol +++ b/test/libsolidity/semanticTests/userDefinedValueType/calldata.sol @@ -49,12 +49,12 @@ contract C { } // ---- // test_f() -> true -// gas irOptimized: 122212 -// gas legacy: 125322 -// gas legacyOptimized: 122694 +// gas irOptimized: 122201 +// gas legacy: 125333 +// gas legacyOptimized: 122693 // test_g() -> true -// gas irOptimized: 106428 -// gas legacy: 111120 +// gas irOptimized: 106408 +// gas legacy: 111133 // gas legacyOptimized: 106925 // addresses(uint256): 0 -> 0x18 // addresses(uint256): 1 -> 0x19 diff --git a/test/libsolidity/semanticTests/userDefinedValueType/erc20.sol b/test/libsolidity/semanticTests/userDefinedValueType/erc20.sol index 30aa590d6fa3..0e0759d62aa1 100644 --- a/test/libsolidity/semanticTests/userDefinedValueType/erc20.sol +++ b/test/libsolidity/semanticTests/userDefinedValueType/erc20.sol @@ -115,7 +115,7 @@ contract ERC20 { // ~ emit Transfer(address,address,uint256): #0x00, #0x1212121212121212121212121212120000000012, 0x14 // gas irOptimized: 121322 // gas irOptimized code: 234600 -// gas legacy: 163352 +// gas legacy: 163350 // gas legacy code: 671400 // gas legacyOptimized: 127464 // gas legacyOptimized code: 285400 diff --git a/test/libsolidity/semanticTests/using/using_global_invisible.sol b/test/libsolidity/semanticTests/using/using_global_invisible.sol index 818707f6fe35..1971980131b7 100644 --- a/test/libsolidity/semanticTests/using/using_global_invisible.sol +++ b/test/libsolidity/semanticTests/using/using_global_invisible.sol @@ -40,5 +40,5 @@ contract D { // ---- // library: "A":L // test() -> 3 -// gas legacy: 59681 +// gas legacy: 59680 // gas legacy code: 61200 diff --git a/test/libsolidity/semanticTests/various/address_code.sol b/test/libsolidity/semanticTests/various/address_code.sol index 8b601ca8c14c..549512eb3e44 100644 --- a/test/libsolidity/semanticTests/various/address_code.sol +++ b/test/libsolidity/semanticTests/various/address_code.sol @@ -16,7 +16,7 @@ contract C { // constructor() -> // gas irOptimized: 70760 // gas irOptimized code: 94600 -// gas legacy: 82380 +// gas legacy: 82428 // gas legacy code: 153800 // gas legacyOptimized: 69400 // gas legacyOptimized code: 79200 diff --git a/test/libsolidity/semanticTests/various/code_access_content.sol b/test/libsolidity/semanticTests/various/code_access_content.sol index dc4e49b2dae0..22ceff337f89 100644 --- a/test/libsolidity/semanticTests/various/code_access_content.sol +++ b/test/libsolidity/semanticTests/various/code_access_content.sol @@ -38,8 +38,8 @@ contract C { } // ---- // testRuntime() -> true -// gas legacy: 76577 +// gas legacy: 76575 // gas legacy code: 23600 // testCreation() -> true -// gas legacy: 77000 +// gas legacy: 76999 // gas legacy code: 23600 diff --git a/test/libsolidity/semanticTests/various/code_access_create.sol b/test/libsolidity/semanticTests/various/code_access_create.sol index d2b7f92f4e66..f5f0b8644423 100644 --- a/test/libsolidity/semanticTests/various/code_access_create.sol +++ b/test/libsolidity/semanticTests/various/code_access_create.sol @@ -23,5 +23,5 @@ contract C { } // ---- // test() -> 7 -// gas legacy: 76649 +// gas legacy: 76647 // gas legacy code: 24200 diff --git a/test/libsolidity/semanticTests/various/code_access_runtime.sol b/test/libsolidity/semanticTests/various/code_access_runtime.sol index b62eb0b8535c..10d7c1852e95 100644 --- a/test/libsolidity/semanticTests/various/code_access_runtime.sol +++ b/test/libsolidity/semanticTests/various/code_access_runtime.sol @@ -23,5 +23,5 @@ contract C { // EVMVersion: >=constantinople // ---- // test() -> 42 -// gas legacy: 76035 +// gas legacy: 76034 // gas legacy code: 24200 diff --git a/test/libsolidity/semanticTests/various/code_length.sol b/test/libsolidity/semanticTests/various/code_length.sol index c30ac838fe4c..844a0f65706f 100644 --- a/test/libsolidity/semanticTests/various/code_length.sol +++ b/test/libsolidity/semanticTests/various/code_length.sol @@ -59,6 +59,6 @@ contract C { } // ---- // constructor() -// gas legacy: 66936 -// gas legacy code: 57200 +// gas legacy: 66989 +// gas legacy code: 57800 // f(): true, true -> true, true diff --git a/test/libsolidity/semanticTests/various/create_calldata.sol b/test/libsolidity/semanticTests/various/create_calldata.sol index 3ca50db13661..a5f61d2ddd67 100644 --- a/test/libsolidity/semanticTests/various/create_calldata.sol +++ b/test/libsolidity/semanticTests/various/create_calldata.sol @@ -10,7 +10,7 @@ contract C { // constructor(): 42 -> // gas irOptimized: 68239 // gas irOptimized code: 69000 -// gas legacy: 78029 +// gas legacy: 78076 // gas legacy code: 90200 // gas legacyOptimized: 68321 // gas legacyOptimized code: 64600 diff --git a/test/libsolidity/semanticTests/various/destructuring_assignment.sol b/test/libsolidity/semanticTests/various/destructuring_assignment.sol index 82183a112139..a961870ee5f2 100644 --- a/test/libsolidity/semanticTests/various/destructuring_assignment.sol +++ b/test/libsolidity/semanticTests/various/destructuring_assignment.sol @@ -34,5 +34,5 @@ contract C { // ---- // f(bytes): 0x20, 0x5, "abcde" -> 0 // gas irOptimized: 242027 -// gas legacy: 243284 -// gas legacyOptimized: 242395 +// gas legacy: 243281 +// gas legacyOptimized: 242392 diff --git a/test/libsolidity/semanticTests/various/erc20.sol b/test/libsolidity/semanticTests/various/erc20.sol index 1a7718f6834f..1cc77270f67b 100644 --- a/test/libsolidity/semanticTests/various/erc20.sol +++ b/test/libsolidity/semanticTests/various/erc20.sol @@ -98,7 +98,7 @@ contract ERC20 { // ~ emit Transfer(address,address,uint256): #0x00, #0x1212121212121212121212121212120000000012, 0x14 // gas irOptimized: 121632 // gas irOptimized code: 236800 -// gas legacy: 159959 +// gas legacy: 159957 // gas legacy code: 647600 // gas legacyOptimized: 126934 // gas legacyOptimized code: 282000 diff --git a/test/libsolidity/semanticTests/various/external_types_in_calls.sol b/test/libsolidity/semanticTests/various/external_types_in_calls.sol index aff302d26e8f..84e4d36d500d 100644 --- a/test/libsolidity/semanticTests/various/external_types_in_calls.sol +++ b/test/libsolidity/semanticTests/various/external_types_in_calls.sol @@ -25,5 +25,5 @@ contract C { // ---- // test() -> 9, 7 // gas legacy: 80314 -// gas legacy code: 47200 +// gas legacy code: 47400 // t2() -> 9 diff --git a/test/libsolidity/semanticTests/various/selfdestruct_post_cancun.sol b/test/libsolidity/semanticTests/various/selfdestruct_post_cancun.sol index 263da7133fa9..4cb5c8c713bf 100644 --- a/test/libsolidity/semanticTests/various/selfdestruct_post_cancun.sol +++ b/test/libsolidity/semanticTests/various/selfdestruct_post_cancun.sol @@ -66,8 +66,8 @@ contract D { // constructor(), 1 ether -> // gas irOptimized: 67028 // gas irOptimized code: 175400 -// gas legacy: 76163 -// gas legacy code: 297400 +// gas legacy: 76227 +// gas legacy code: 298200 // gas legacyOptimized: 66516 // gas legacyOptimized code: 168000 // exists() -> false diff --git a/test/libsolidity/semanticTests/various/selfdestruct_post_cancun_multiple_beneficiaries.sol b/test/libsolidity/semanticTests/various/selfdestruct_post_cancun_multiple_beneficiaries.sol index 690bff8d5588..a582649196c3 100644 --- a/test/libsolidity/semanticTests/various/selfdestruct_post_cancun_multiple_beneficiaries.sol +++ b/test/libsolidity/semanticTests/various/selfdestruct_post_cancun_multiple_beneficiaries.sol @@ -37,8 +37,8 @@ contract D { // constructor(), 2 ether -> // gas irOptimized: 108104 // gas irOptimized code: 119200 -// gas legacy: 120424 -// gas legacy code: 253600 +// gas legacy: 120439 +// gas legacy code: 253800 // gas legacyOptimized: 109015 // gas legacyOptimized code: 130800 // balance: 0x1111111111111111111111111111111111111111 -> 0 @@ -48,7 +48,7 @@ contract D { // test_deploy_and_terminate_twice() -> // gas irOptimized: 121395 // gas irOptimized code: 14000 -// gas legacy: 122384 +// gas legacy: 122386 // gas legacy code: 43200 // gas legacyOptimized: 121596 // gas legacyOptimized code: 22800 diff --git a/test/libsolidity/semanticTests/various/selfdestruct_post_cancun_redeploy.sol b/test/libsolidity/semanticTests/various/selfdestruct_post_cancun_redeploy.sol index 1ae89a558e70..dd550d31a0cf 100644 --- a/test/libsolidity/semanticTests/various/selfdestruct_post_cancun_redeploy.sol +++ b/test/libsolidity/semanticTests/various/selfdestruct_post_cancun_redeploy.sol @@ -84,8 +84,8 @@ contract D { // constructor(), 1 ether -> // gas irOptimized: 132974 // gas irOptimized code: 293800 -// gas legacy: 151217 -// gas legacy code: 533400 +// gas legacy: 151236 +// gas legacy code: 533800 // gas legacyOptimized: 131436 // gas legacyOptimized code: 276600 // exists() -> false @@ -95,7 +95,7 @@ contract D { // gas irOptimized code: 20800 // gas legacy: 97788 // gas legacy code: 20800 -// gas legacyOptimized: 96044 +// gas legacyOptimized: 96043 // gas legacyOptimized code: 20800 // exists() -> false // deploy_create2() -> @@ -107,5 +107,5 @@ contract D { // exists() -> true // deploy_create2() -> FAILURE // gas irOptimized: 96903654 -// gas legacy: 96903660 -// gas legacyOptimized: 96903641 +// gas legacy: 96903658 +// gas legacyOptimized: 96903639 diff --git a/test/libsolidity/semanticTests/various/senders_balance.sol b/test/libsolidity/semanticTests/various/senders_balance.sol index 5b4371149f42..fff16befe69e 100644 --- a/test/libsolidity/semanticTests/various/senders_balance.sol +++ b/test/libsolidity/semanticTests/various/senders_balance.sol @@ -18,7 +18,7 @@ contract D { // constructor(), 27 wei -> // gas irOptimized: 114057 // gas irOptimized code: 53800 -// gas legacy: 117835 +// gas legacy: 117834 // gas legacy code: 100600 // gas legacyOptimized: 113676 // gas legacyOptimized code: 53600 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 9d078cfd698c..8430da4e8d12 100644 --- a/test/libsolidity/semanticTests/various/skip_dynamic_types_for_structs.sol +++ b/test/libsolidity/semanticTests/various/skip_dynamic_types_for_structs.sol @@ -20,5 +20,5 @@ contract C { // ---- // g() -> 2, 6 // gas irOptimized: 178195 -// gas legacy: 180657 -// gas legacyOptimized: 179146 +// gas legacy: 180653 +// gas legacyOptimized: 179144 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 2063fff7a571..2a9834aab7e8 100644 --- a/test/libsolidity/semanticTests/various/staticcall_for_view_and_pure.sol +++ b/test/libsolidity/semanticTests/various/staticcall_for_view_and_pure.sol @@ -40,14 +40,14 @@ contract D { // fview() -> FAILURE // gas irOptimized: 98425388 // gas irOptimized code: 13200 -// gas legacy: 98413174 +// gas legacy: 98413173 // gas legacy code: 25600 -// gas legacyOptimized: 98425380 +// gas legacyOptimized: 98425379 // gas legacyOptimized code: 13200 // fpure() -> FAILURE // gas irOptimized: 98425388 // gas irOptimized code: 13200 -// gas legacy: 98413174 +// gas legacy: 98413173 // gas legacy code: 25600 -// gas legacyOptimized: 98425380 +// gas legacyOptimized: 98425379 // gas legacyOptimized code: 13200 diff --git a/test/libsolidity/semanticTests/various/swap_in_storage_overwrite.sol b/test/libsolidity/semanticTests/various/swap_in_storage_overwrite.sol index bd5a59519c8d..3422c812111c 100644 --- a/test/libsolidity/semanticTests/various/swap_in_storage_overwrite.sol +++ b/test/libsolidity/semanticTests/various/swap_in_storage_overwrite.sol @@ -27,7 +27,7 @@ contract c { // y() -> 0, 0 // set() -> // gas irOptimized: 109684 -// gas legacy: 109728 +// gas legacy: 109727 // gas legacyOptimized: 109680 // x() -> 1, 2 // y() -> 3, 4 diff --git a/test/libsolidity/semanticTests/various/value_complex.sol b/test/libsolidity/semanticTests/various/value_complex.sol index dc92e38df59b..4639d34c7071 100644 --- a/test/libsolidity/semanticTests/various/value_complex.sol +++ b/test/libsolidity/semanticTests/various/value_complex.sol @@ -21,8 +21,8 @@ contract test { // constructor(), 20 wei -> // gas irOptimized: 114463 // gas irOptimized code: 58800 -// gas legacy: 120076 -// gas legacy code: 132200 +// gas legacy: 120091 +// gas legacy code: 132400 // gas legacyOptimized: 114536 // gas legacyOptimized code: 65800 // sendAmount(uint256): 5 -> 8 diff --git a/test/libsolidity/semanticTests/various/value_insane.sol b/test/libsolidity/semanticTests/various/value_insane.sol index ad0e95701d07..bc6a803de92f 100644 --- a/test/libsolidity/semanticTests/various/value_insane.sol +++ b/test/libsolidity/semanticTests/various/value_insane.sol @@ -20,7 +20,7 @@ contract test { // constructor(), 20 wei -> // gas irOptimized: 114527 // gas irOptimized code: 59600 -// gas legacy: 120200 +// gas legacy: 120199 // gas legacy code: 133600 // gas legacyOptimized: 114568 // gas legacyOptimized code: 66200 diff --git a/test/libsolidity/semanticTests/viaYul/copy_struct_invalid_ir_bug.sol b/test/libsolidity/semanticTests/viaYul/copy_struct_invalid_ir_bug.sol index fbaa7789ea0e..0db482c040db 100644 --- a/test/libsolidity/semanticTests/viaYul/copy_struct_invalid_ir_bug.sol +++ b/test/libsolidity/semanticTests/viaYul/copy_struct_invalid_ir_bug.sol @@ -21,6 +21,6 @@ contract C { } // ---- // f() -> -// gas irOptimized: 113118 -// gas legacy: 112890 +// gas irOptimized: 113117 +// gas legacy: 112888 // gas legacyOptimized: 112580 diff --git a/test/libyul/objectCompiler/datacopy.yul b/test/libyul/objectCompiler/datacopy.yul index cb9fbcb18ba2..719b109f1db7 100644 --- a/test/libyul/objectCompiler/datacopy.yul +++ b/test/libyul/objectCompiler/datacopy.yul @@ -33,7 +33,7 @@ object "a" { // /* "source":153:170 */ // 0x00 // /* "source":150:151 */ -// dup1 +// 0x00 // /* "source":143:171 */ // sstore // /* "source":188:205 */ @@ -47,6 +47,6 @@ object "a" { // stop // data_acaf3289d7b601cbd114fb36c4d29c85bbfd5e133f14cb355c3fd8d99367964f 48656c6c6f2c20576f726c6421 // } -// Bytecode: 6009600b5f3960095ff3fe5f8055600d5f5200fe -// Opcodes: PUSH1 0x9 PUSH1 0xB PUSH0 CODECOPY PUSH1 0x9 PUSH0 RETURN INVALID PUSH0 DUP1 SSTORE PUSH1 0xD PUSH0 MSTORE STOP INVALID +// Bytecode: 6009600b5f3960095ff3fe5f5f55600d5f5200fe +// Opcodes: PUSH1 0x9 PUSH1 0xB PUSH0 CODECOPY PUSH1 0x9 PUSH0 RETURN INVALID PUSH0 PUSH0 SSTORE PUSH1 0xD PUSH0 MSTORE STOP INVALID // SourceMappings: 57:15:0:-:0;38:17;35:1;26:47;88:15;85:1;78:26 diff --git a/test/libyul/objectCompiler/dataoffset_self.yul b/test/libyul/objectCompiler/dataoffset_self.yul index 7c38b9502a1b..ae123ba49a0b 100644 --- a/test/libyul/objectCompiler/dataoffset_self.yul +++ b/test/libyul/objectCompiler/dataoffset_self.yul @@ -7,13 +7,13 @@ object "a" { // /* "source":32:47 */ // 0x00 // /* "source":29:30 */ -// dup1 +// 0x00 // /* "source":22:48 */ // sstore // /* "source":20:50 */ // stop // stop // data_acaf3289d7b601cbd114fb36c4d29c85bbfd5e133f14cb355c3fd8d99367964f 48656c6c6f2c20576f726c6421 -// Bytecode: 5f805500fe -// Opcodes: PUSH0 DUP1 SSTORE STOP INVALID +// Bytecode: 5f5f5500fe +// Opcodes: PUSH0 PUSH0 SSTORE STOP INVALID // SourceMappings: 32:15:0:-:0;29:1;22:26;20:30 diff --git a/test/libyul/objectCompiler/sourceLocations.yul b/test/libyul/objectCompiler/sourceLocations.yul index 883e85b040e6..d9f1d84fcb4f 100644 --- a/test/libyul/objectCompiler/sourceLocations.yul +++ b/test/libyul/objectCompiler/sourceLocations.yul @@ -41,15 +41,13 @@ object "a" { // // sub_0: assembly { // /* "def.sol":70:72 */ -// 0x00 -// dup1 -// sstore +// sstore(0x00, 0x00) // /* "abc.sol":2:5 */ // mstore(0x00, 0x0d) // stop // stop // data_acaf3289d7b601cbd114fb36c4d29c85bbfd5e133f14cb355c3fd8d99367964f 48656c6c6f2c20576f726c6421 // } -// Bytecode: 6009600b5f3960095ff3fe5f8055600d5f5200fe -// Opcodes: PUSH1 0x9 PUSH1 0xB PUSH0 CODECOPY PUSH1 0x9 PUSH0 RETURN INVALID PUSH0 DUP1 SSTORE PUSH1 0xD PUSH0 MSTORE STOP INVALID +// Bytecode: 6009600b5f3960095ff3fe5f5f55600d5f5200fe +// Opcodes: PUSH1 0x9 PUSH1 0xB PUSH0 CODECOPY PUSH1 0x9 PUSH0 RETURN INVALID PUSH0 PUSH0 SSTORE PUSH1 0xD PUSH0 MSTORE STOP INVALID // SourceMappings: 0:2::-:0;;;;5:1;0:2; From a500a63e7029299928211de433124ae69333b3f2 Mon Sep 17 00:00:00 2001 From: Matheus Aguiar Date: Fri, 28 Jun 2024 16:48:11 -0300 Subject: [PATCH 0333/1022] workaround to skip failing hardhat tests --- .circleci/config.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index d6c3f33da08a..3426db329358 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1438,6 +1438,14 @@ jobs: # TODO: temporarily set hardhat stack traces tests to use cancun hardfork # Remove this when hardhat switch to cancun by default: https://github.com/NomicFoundation/hardhat/issues/4851 sed -i 's/hardfork: "shanghai",/hardfork: "cancun",/' test/internal/hardhat-network/stack-traces/execution.ts + # TODO: Remove these tests because they rely on specific stack sequence which has changed since + # Remove when hardhat properly fix a specific version for the tests: https://github.com/NomicFoundation/hardhat/issues/5443 + rm -rf test/internal/hardhat-network/stack-traces/test-files/0_8/revert-without-message/modifiers/call-message/multiple-modifiers-require/ + rm -rf test/internal/hardhat-network/stack-traces/test-files/0_8/revert-without-message/modifiers/create-message/multiple-modifiers-require/ + rm -rf test/internal/hardhat-network/stack-traces/test-files/0_8/revert-without-message/revert-without-message/within-receive/between-statements/ + rm -rf test/internal/hardhat-network/stack-traces/test-files/0_8/revert-without-message/revert-without-message/within-receive/no-other-statements/ + rm -rf test/internal/hardhat-network/stack-traces/test-files/0_8/revert-without-message/revert-without-message/within-receive/statement-after/ + rm -rf test/internal/hardhat-network/stack-traces/test-files/0_8/revert-without-message/revert-without-message/within-receive/statement-before/ pnpm test - matrix_notify_failure_unless_pr From 57ab4dce5a7031d83915f3c43cd331bba940c63e Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Mon, 5 Aug 2024 10:03:13 +0200 Subject: [PATCH 0334/1022] Parser: Fix spuriously emitted parser error for unary plus operations when used as binary operator in some cases --- Changelog.md | 1 + libsolidity/parsing/Parser.cpp | 2 +- .../declaration_unary_plus_tuple_compound_assign.sol | 9 +++++++++ .../591_access_to_internal_variable.sol | 9 +++++++++ test/libsolidity/syntaxTests/types/binary_add_op.sol | 12 ++++++++++++ 5 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 test/libsolidity/syntaxTests/iceRegressionTests/declarationUnaryTuple/declaration_unary_plus_tuple_compound_assign.sol create mode 100644 test/libsolidity/syntaxTests/nameAndTypeResolution/591_access_to_internal_variable.sol create mode 100644 test/libsolidity/syntaxTests/types/binary_add_op.sol diff --git a/Changelog.md b/Changelog.md index 8acee7422b3d..d6aaf3512526 100644 --- a/Changelog.md +++ b/Changelog.md @@ -20,6 +20,7 @@ Compiler Features: Bugfixes: + * Parser: Fix spuriously emitted parser error for unary plus operations when used as binary operator in some cases. * SMTChecker: Fix error that reports invalid number of verified checks for BMC and CHC engines. * SMTChecker: Fix formatting of unary minus expressions in invariants. * SMTChecker: Fix internal compiler error when reporting proved targets for BMC engine. diff --git a/libsolidity/parsing/Parser.cpp b/libsolidity/parsing/Parser.cpp index b51eb9c44099..a6a4d735ad81 100644 --- a/libsolidity/parsing/Parser.cpp +++ b/libsolidity/parsing/Parser.cpp @@ -2152,7 +2152,7 @@ ASTPointer Parser::parseUnaryExpression( ASTNodeFactory(*this, _partiallyParsedExpression) : ASTNodeFactory(*this); Token token = m_scanner->currentToken(); - if (token == Token::Add) + if (!_partiallyParsedExpression && token == Token::Add) fatalParserError(9636_error, "Use of unary + is disallowed."); if (!_partiallyParsedExpression && (TokenTraits::isUnaryOp(token) || TokenTraits::isCountOp(token))) diff --git a/test/libsolidity/syntaxTests/iceRegressionTests/declarationUnaryTuple/declaration_unary_plus_tuple_compound_assign.sol b/test/libsolidity/syntaxTests/iceRegressionTests/declarationUnaryTuple/declaration_unary_plus_tuple_compound_assign.sol new file mode 100644 index 000000000000..24c795f1404c --- /dev/null +++ b/test/libsolidity/syntaxTests/iceRegressionTests/declarationUnaryTuple/declaration_unary_plus_tuple_compound_assign.sol @@ -0,0 +1,9 @@ +contract C +{ + function f(int x) public + { + (x /= 1) + +(1,1); + } +} +// ---- +// ParserError 9636: (67-68): Use of unary + is disallowed. diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/591_access_to_internal_variable.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/591_access_to_internal_variable.sol new file mode 100644 index 000000000000..f8fba4f7de43 --- /dev/null +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/591_access_to_internal_variable.sol @@ -0,0 +1,9 @@ +contract C { + function f(int32 x) external pure returns (int32) + { + this.x + 1; + return x; + } +} +// ---- +// TypeError 9582: (81-87): Member "x" not found or not visible after argument-dependent lookup in contract C. diff --git a/test/libsolidity/syntaxTests/types/binary_add_op.sol b/test/libsolidity/syntaxTests/types/binary_add_op.sol new file mode 100644 index 000000000000..1217ed2438ba --- /dev/null +++ b/test/libsolidity/syntaxTests/types/binary_add_op.sol @@ -0,0 +1,12 @@ +contract C { + function f(int32 x) external pure returns (int32) + { + x = 1 + 1; + (x /= 1) + 1; + (x = ++x) + 1; + (0) + 1; + return x; + } +} +// ---- +// Warning 6133: (145-152): Statement has no effect. From 40aec73c18b4dc7ed684fac1e574c0de6ff2f142 Mon Sep 17 00:00:00 2001 From: Daniel Date: Tue, 6 Aug 2024 16:26:47 +0200 Subject: [PATCH 0335/1022] Update libyul/Object.cpp --- libyul/Object.cpp | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/libyul/Object.cpp b/libyul/Object.cpp index afd237b5b7f9..c4e7971ab4f7 100644 --- a/libyul/Object.cpp +++ b/libyul/Object.cpp @@ -170,11 +170,8 @@ bool Object::hasCode() const { return code() != nullptr; } void Object::setCode(std::shared_ptr const& _ast, std::shared_ptr _analysisInfo) { - if (_ast.get() != m_code.get()) - { - m_code = _ast; - analysisInfo = std::move(_analysisInfo); - } + m_code = _ast; + analysisInfo = std::move(_analysisInfo); } void Object::collectSourceIndices(std::map& _indices) const From 961c99db087108d406206d50f405b9b4f33d940d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Wed, 31 Jul 2024 19:21:14 +0200 Subject: [PATCH 0336/1022] Tests for warnings sensitive to optimization --- test/cmdlineTests/strict_asm_warning/args | 1 + test/cmdlineTests/strict_asm_warning/err | 11 +++++++++++ test/cmdlineTests/strict_asm_warning/input.yul | 5 +++++ test/cmdlineTests/strict_asm_warning/output | 7 +++++++ .../strict_asm_warning_and_error_optimize/args | 1 + .../strict_asm_warning_and_error_optimize/err | 11 +++++++++++ .../strict_asm_warning_and_error_optimize/exit | 1 + .../strict_asm_warning_and_error_optimize/input.yul | 5 +++++ test/cmdlineTests/strict_asm_warning_optimize/args | 1 + test/cmdlineTests/strict_asm_warning_optimize/err | 11 +++++++++++ .../strict_asm_warning_optimize/input.yul | 5 +++++ test/cmdlineTests/strict_asm_warning_optimize/output | 7 +++++++ .../strict_asm_warning_optimize_unreachable/args | 1 + .../strict_asm_warning_optimize_unreachable/err | 5 +++++ .../strict_asm_warning_optimize_unreachable/input.yul | 8 ++++++++ .../strict_asm_warning_optimize_unreachable/output | 7 +++++++ 16 files changed, 87 insertions(+) create mode 100644 test/cmdlineTests/strict_asm_warning/args create mode 100644 test/cmdlineTests/strict_asm_warning/err create mode 100644 test/cmdlineTests/strict_asm_warning/input.yul create mode 100644 test/cmdlineTests/strict_asm_warning/output create mode 100644 test/cmdlineTests/strict_asm_warning_and_error_optimize/args create mode 100644 test/cmdlineTests/strict_asm_warning_and_error_optimize/err create mode 100644 test/cmdlineTests/strict_asm_warning_and_error_optimize/exit create mode 100644 test/cmdlineTests/strict_asm_warning_and_error_optimize/input.yul create mode 100644 test/cmdlineTests/strict_asm_warning_optimize/args create mode 100644 test/cmdlineTests/strict_asm_warning_optimize/err create mode 100644 test/cmdlineTests/strict_asm_warning_optimize/input.yul create mode 100644 test/cmdlineTests/strict_asm_warning_optimize/output create mode 100644 test/cmdlineTests/strict_asm_warning_optimize_unreachable/args create mode 100644 test/cmdlineTests/strict_asm_warning_optimize_unreachable/err create mode 100644 test/cmdlineTests/strict_asm_warning_optimize_unreachable/input.yul create mode 100644 test/cmdlineTests/strict_asm_warning_optimize_unreachable/output diff --git a/test/cmdlineTests/strict_asm_warning/args b/test/cmdlineTests/strict_asm_warning/args new file mode 100644 index 000000000000..57996b90ac8c --- /dev/null +++ b/test/cmdlineTests/strict_asm_warning/args @@ -0,0 +1 @@ +--strict-assembly --ir-optimized diff --git a/test/cmdlineTests/strict_asm_warning/err b/test/cmdlineTests/strict_asm_warning/err new file mode 100644 index 000000000000..1024e870f968 --- /dev/null +++ b/test/cmdlineTests/strict_asm_warning/err @@ -0,0 +1,11 @@ +Warning: "selfdestruct" has been deprecated. Note that, starting from the Cancun hard fork, the underlying opcode no longer deletes the code and data associated with an account and only transfers its Ether to the beneficiary, unless executed in the same transaction in which the contract was created (see EIP-6780). Any use in newly deployed contracts is strongly discouraged even if the new behavior is taken into account. Future changes to the EVM might further reduce the functionality of the opcode. + --> strict_asm_warning/input.yul:4:5: + | +4 | selfdestruct(0) + | ^^^^^^^^^^^^ + +Warning: "selfdestruct" has been deprecated. Note that, starting from the Cancun hard fork, the underlying opcode no longer deletes the code and data associated with an account and only transfers its Ether to the beneficiary, unless executed in the same transaction in which the contract was created (see EIP-6780). Any use in newly deployed contracts is strongly discouraged even if the new behavior is taken into account. Future changes to the EVM might further reduce the functionality of the opcode. + --> strict_asm_warning/input.yul:4:5: + | +4 | selfdestruct(0) + | ^^^^^^^^^^^^ diff --git a/test/cmdlineTests/strict_asm_warning/input.yul b/test/cmdlineTests/strict_asm_warning/input.yul new file mode 100644 index 000000000000..cfe85c7846df --- /dev/null +++ b/test/cmdlineTests/strict_asm_warning/input.yul @@ -0,0 +1,5 @@ +{ + // The code is valid and will proceed through the whole pipeline, possibly being reparsed multiple times. + // This should produce exactly one warning. + selfdestruct(0) +} diff --git a/test/cmdlineTests/strict_asm_warning/output b/test/cmdlineTests/strict_asm_warning/output new file mode 100644 index 000000000000..71cb2ce69a09 --- /dev/null +++ b/test/cmdlineTests/strict_asm_warning/output @@ -0,0 +1,7 @@ + +======= strict_asm_warning/input.yul (EVM) ======= + +Pretty printed source: +object "object" { + code { { selfdestruct(0) } } +} diff --git a/test/cmdlineTests/strict_asm_warning_and_error_optimize/args b/test/cmdlineTests/strict_asm_warning_and_error_optimize/args new file mode 100644 index 000000000000..90b16d1f0e12 --- /dev/null +++ b/test/cmdlineTests/strict_asm_warning_and_error_optimize/args @@ -0,0 +1 @@ +--strict-assembly --optimize --ir-optimized diff --git a/test/cmdlineTests/strict_asm_warning_and_error_optimize/err b/test/cmdlineTests/strict_asm_warning_and_error_optimize/err new file mode 100644 index 000000000000..22366e3e7bf3 --- /dev/null +++ b/test/cmdlineTests/strict_asm_warning_and_error_optimize/err @@ -0,0 +1,11 @@ +Warning: "selfdestruct" has been deprecated. Note that, starting from the Cancun hard fork, the underlying opcode no longer deletes the code and data associated with an account and only transfers its Ether to the beneficiary, unless executed in the same transaction in which the contract was created (see EIP-6780). Any use in newly deployed contracts is strongly discouraged even if the new behavior is taken into account. Future changes to the EVM might further reduce the functionality of the opcode. + --> strict_asm_warning_and_error_optimize/input.yul:4:5: + | +4 | selfdestruct() + | ^^^^^^^^^^^^ + +Error: Function "selfdestruct" expects 1 arguments but got 0. + --> strict_asm_warning_and_error_optimize/input.yul:4:5: + | +4 | selfdestruct() + | ^^^^^^^^^^^^ diff --git a/test/cmdlineTests/strict_asm_warning_and_error_optimize/exit b/test/cmdlineTests/strict_asm_warning_and_error_optimize/exit new file mode 100644 index 000000000000..d00491fd7e5b --- /dev/null +++ b/test/cmdlineTests/strict_asm_warning_and_error_optimize/exit @@ -0,0 +1 @@ +1 diff --git a/test/cmdlineTests/strict_asm_warning_and_error_optimize/input.yul b/test/cmdlineTests/strict_asm_warning_and_error_optimize/input.yul new file mode 100644 index 000000000000..75800c7ff9c9 --- /dev/null +++ b/test/cmdlineTests/strict_asm_warning_and_error_optimize/input.yul @@ -0,0 +1,5 @@ +{ + // The code does not compile so the optimizer will not run. + // This should generate exactly one warning and one error. + selfdestruct() +} diff --git a/test/cmdlineTests/strict_asm_warning_optimize/args b/test/cmdlineTests/strict_asm_warning_optimize/args new file mode 100644 index 000000000000..90b16d1f0e12 --- /dev/null +++ b/test/cmdlineTests/strict_asm_warning_optimize/args @@ -0,0 +1 @@ +--strict-assembly --optimize --ir-optimized diff --git a/test/cmdlineTests/strict_asm_warning_optimize/err b/test/cmdlineTests/strict_asm_warning_optimize/err new file mode 100644 index 000000000000..2f3c9bb4a0d0 --- /dev/null +++ b/test/cmdlineTests/strict_asm_warning_optimize/err @@ -0,0 +1,11 @@ +Warning: "selfdestruct" has been deprecated. Note that, starting from the Cancun hard fork, the underlying opcode no longer deletes the code and data associated with an account and only transfers its Ether to the beneficiary, unless executed in the same transaction in which the contract was created (see EIP-6780). Any use in newly deployed contracts is strongly discouraged even if the new behavior is taken into account. Future changes to the EVM might further reduce the functionality of the opcode. + --> strict_asm_warning_optimize/input.yul:4:5: + | +4 | selfdestruct(0) + | ^^^^^^^^^^^^ + +Warning: "selfdestruct" has been deprecated. Note that, starting from the Cancun hard fork, the underlying opcode no longer deletes the code and data associated with an account and only transfers its Ether to the beneficiary, unless executed in the same transaction in which the contract was created (see EIP-6780). Any use in newly deployed contracts is strongly discouraged even if the new behavior is taken into account. Future changes to the EVM might further reduce the functionality of the opcode. + --> strict_asm_warning_optimize/input.yul:4:5: + | +4 | selfdestruct(0) + | ^^^^^^^^^^^^ diff --git a/test/cmdlineTests/strict_asm_warning_optimize/input.yul b/test/cmdlineTests/strict_asm_warning_optimize/input.yul new file mode 100644 index 000000000000..cfe85c7846df --- /dev/null +++ b/test/cmdlineTests/strict_asm_warning_optimize/input.yul @@ -0,0 +1,5 @@ +{ + // The code is valid and will proceed through the whole pipeline, possibly being reparsed multiple times. + // This should produce exactly one warning. + selfdestruct(0) +} diff --git a/test/cmdlineTests/strict_asm_warning_optimize/output b/test/cmdlineTests/strict_asm_warning_optimize/output new file mode 100644 index 000000000000..d933dcb05525 --- /dev/null +++ b/test/cmdlineTests/strict_asm_warning_optimize/output @@ -0,0 +1,7 @@ + +======= strict_asm_warning_optimize/input.yul (EVM) ======= + +Pretty printed source: +object "object" { + code { { selfdestruct(0) } } +} diff --git a/test/cmdlineTests/strict_asm_warning_optimize_unreachable/args b/test/cmdlineTests/strict_asm_warning_optimize_unreachable/args new file mode 100644 index 000000000000..90b16d1f0e12 --- /dev/null +++ b/test/cmdlineTests/strict_asm_warning_optimize_unreachable/args @@ -0,0 +1 @@ +--strict-assembly --optimize --ir-optimized diff --git a/test/cmdlineTests/strict_asm_warning_optimize_unreachable/err b/test/cmdlineTests/strict_asm_warning_optimize_unreachable/err new file mode 100644 index 000000000000..4535680baa59 --- /dev/null +++ b/test/cmdlineTests/strict_asm_warning_optimize_unreachable/err @@ -0,0 +1,5 @@ +Warning: "selfdestruct" has been deprecated. Note that, starting from the Cancun hard fork, the underlying opcode no longer deletes the code and data associated with an account and only transfers its Ether to the beneficiary, unless executed in the same transaction in which the contract was created (see EIP-6780). Any use in newly deployed contracts is strongly discouraged even if the new behavior is taken into account. Future changes to the EVM might further reduce the functionality of the opcode. + --> strict_asm_warning_optimize_unreachable/input.yul:7:5: + | +7 | selfdestruct(0) + | ^^^^^^^^^^^^ diff --git a/test/cmdlineTests/strict_asm_warning_optimize_unreachable/input.yul b/test/cmdlineTests/strict_asm_warning_optimize_unreachable/input.yul new file mode 100644 index 000000000000..c07ecd43ea3d --- /dev/null +++ b/test/cmdlineTests/strict_asm_warning_optimize_unreachable/input.yul @@ -0,0 +1,8 @@ +{ + revert(0, 0) + + // The code is valid and will proceed through the whole pipeline, possibly being reparsed multiple times. + // Note that the code is unreachable, so the warning would not appear in the optimized version. + // This should produce exactly one warning. + selfdestruct(0) +} diff --git a/test/cmdlineTests/strict_asm_warning_optimize_unreachable/output b/test/cmdlineTests/strict_asm_warning_optimize_unreachable/output new file mode 100644 index 000000000000..508e9d8ed4ef --- /dev/null +++ b/test/cmdlineTests/strict_asm_warning_optimize_unreachable/output @@ -0,0 +1,7 @@ + +======= strict_asm_warning_optimize_unreachable/input.yul (EVM) ======= + +Pretty printed source: +object "object" { + code { { revert(0, 0) } } +} From ea262ed56c7317f4399262d03fd05f34148c7660 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Wed, 31 Jul 2024 15:45:34 +0200 Subject: [PATCH 0337/1022] EVMObjectCompiler: Don't require a mutable object --- libyul/backends/evm/EVMObjectCompiler.cpp | 4 ++-- libyul/backends/evm/EVMObjectCompiler.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/libyul/backends/evm/EVMObjectCompiler.cpp b/libyul/backends/evm/EVMObjectCompiler.cpp index ca9f90dfae34..ccd8af6d2940 100644 --- a/libyul/backends/evm/EVMObjectCompiler.cpp +++ b/libyul/backends/evm/EVMObjectCompiler.cpp @@ -35,7 +35,7 @@ using namespace solidity::yul; void EVMObjectCompiler::compile( - Object& _object, + Object const& _object, AbstractAssembly& _assembly, EVMDialect const& _dialect, bool _optimize, @@ -46,7 +46,7 @@ void EVMObjectCompiler::compile( compiler.run(_object, _optimize); } -void EVMObjectCompiler::run(Object& _object, bool _optimize) +void EVMObjectCompiler::run(Object const& _object, bool _optimize) { BuiltinContext context; context.currentObject = &_object; diff --git a/libyul/backends/evm/EVMObjectCompiler.h b/libyul/backends/evm/EVMObjectCompiler.h index df8d71c2cef5..d37ade2cd211 100644 --- a/libyul/backends/evm/EVMObjectCompiler.h +++ b/libyul/backends/evm/EVMObjectCompiler.h @@ -34,7 +34,7 @@ class EVMObjectCompiler { public: static void compile( - Object& _object, + Object const& _object, AbstractAssembly& _assembly, EVMDialect const& _dialect, bool _optimize, @@ -45,7 +45,7 @@ class EVMObjectCompiler m_assembly(_assembly), m_dialect(_dialect), m_eofVersion(_eofVersion) {} - void run(Object& _object, bool _optimize); + void run(Object const& _object, bool _optimize); AbstractAssembly& m_assembly; EVMDialect const& m_dialect; From fe4c52e3357ba92da81521c0ad200fa5294ada5f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Wed, 31 Jul 2024 16:47:28 +0200 Subject: [PATCH 0338/1022] Move optimized IR reparsing from CompilerStack to YulStack - This makes it apply to yul compilation as well. - Also fixes warnings being reported again when optimizing IR. --- Changelog.md | 3 +- libsolidity/interface/CompilerStack.cpp | 47 ++- libyul/YulStack.cpp | 33 ++- libyul/YulStack.h | 7 + test/cmdlineTests/ast_ir/output | 92 +++--- .../linking_strict_assembly/output | 8 +- .../output | 16 +- .../output | 16 +- .../output | 16 +- test/cmdlineTests/object_compiler/output | 32 +- .../output.json | 142 ++++----- test/cmdlineTests/standard_yul/output.json | 10 +- .../standard_yul_object/output.json | 10 +- .../standard_yul_object_name/output.json | 14 +- .../standard_yul_optimiserSteps/output.json | 8 +- .../standard_yul_optimized/output.json | 8 +- .../standard_yul_stack_opt/output.json | 14 +- .../output.json | 12 +- .../output | 128 ++++---- .../strict_asm_ast_compact_json/output | 14 +- .../strict_asm_evm_version_byzantium/output | 2 +- .../output | 2 +- .../strict_asm_optimizer_steps/output | 48 +-- .../output | 8 +- test/cmdlineTests/strict_asm_warning/err | 6 - .../strict_asm_warning_optimize/err | 6 - .../output | 26 +- test/cmdlineTests/yul_optimize_runs/output | 20 +- test/cmdlineTests/yul_verbatim_msize/output | 15 +- test/libyul/objectCompiler/data.yul | 4 +- test/libyul/objectCompiler/datacopy.yul | 30 +- .../libyul/objectCompiler/dataoffset_code.yul | 18 +- .../libyul/objectCompiler/dataoffset_data.yul | 10 +- .../libyul/objectCompiler/dataoffset_self.yul | 10 +- test/libyul/objectCompiler/datasize_code.yul | 18 +- test/libyul/objectCompiler/datasize_data.yul | 10 +- test/libyul/objectCompiler/datasize_self.yul | 10 +- ..._long_name_does_not_end_up_in_bytecode.yul | 10 +- .../leading_and_trailing_dots.yul | 22 +- test/libyul/objectCompiler/linkersymbol.yul | 24 +- .../objectCompiler/long_object_name.yul | 12 +- test/libyul/objectCompiler/manySubObjects.yul | 276 +++++++++--------- test/libyul/objectCompiler/metadata.yul | 26 +- test/libyul/objectCompiler/namedObject.yul | 4 +- .../libyul/objectCompiler/namedObjectCode.yul | 10 +- .../objectCompiler/nested_optimizer.yul | 18 +- test/libyul/objectCompiler/simple.yul | 10 +- .../objectCompiler/simple_optimizer.yul | 10 +- test/libyul/objectCompiler/smoke.yul | 4 +- test/libyul/objectCompiler/subObject.yul | 12 +- .../libyul/objectCompiler/subObjectAccess.yul | 138 ++++----- test/libyul/objectCompiler/subSubObject.yul | 20 +- test/libyul/objectCompiler/verbatim_bug.yul | 82 +++--- 53 files changed, 783 insertions(+), 768 deletions(-) diff --git a/Changelog.md b/Changelog.md index 5e8a7bef8432..0395b624b5e0 100644 --- a/Changelog.md +++ b/Changelog.md @@ -28,8 +28,9 @@ Bugfixes: * SMTChecker: Fix formatting of unary minus expressions in invariants. * SMTChecker: Fix internal compiler error when reporting proved targets for BMC engine. * TypeChecker: Fix segfault when assigning nested tuple to tuple. - * Yul AST: Fix ``nativeSrc`` attributes in optimized IR AST referring to locations in unoptimized IR. * Yul IR Code Generation: Deterministic order of Yul subobjects. + * Yul Optimizer: Fix Yul source locations always referring to unoptimized source, even in optimized outputs. + * Yul Optimizer: Fix warnings being generated twice when there are no errors. * Yul Optimizer: Name simplification could lead to forbidden identifiers with a leading and/or trailing dot, e.g., ``x._`` would get simplified into ``x.``. * Yul Parser: Fix segfault when parsing very long location comments. diff --git a/libsolidity/interface/CompilerStack.cpp b/libsolidity/interface/CompilerStack.cpp index dd5d20126ebe..0ea7131db140 100644 --- a/libsolidity/interface/CompilerStack.cpp +++ b/libsolidity/interface/CompilerStack.cpp @@ -1488,39 +1488,26 @@ void CompilerStack::generateIR(ContractDefinition const& _contract, bool _unopti ); } - auto const parseYul = [&](std::string const& _irSource) { - YulStack stack( - m_evmVersion, - m_eofVersion, - YulStack::Language::StrictAssembly, - m_optimiserSettings, - m_debugInfoSelection - ); - bool yulAnalysisSuccessful = stack.parseAndAnalyze("", _irSource); - solAssert( - yulAnalysisSuccessful, - _irSource + "\n\n" - "Invalid IR generated:\n" + - langutil::SourceReferenceFormatter::formatErrorInformation(stack.errors(), stack) + "\n" - ); - return stack; - }; - - { - YulStack stack = parseYul(compiledContract.yulIR); - compiledContract.yulIRAst = stack.astJson(); - if (!_unoptimizedOnly) - { - stack.optimize(); - compiledContract.yulIROptimized = stack.print(this); - } - } + YulStack stack( + m_evmVersion, + m_eofVersion, + YulStack::Language::StrictAssembly, + m_optimiserSettings, + m_debugInfoSelection + ); + bool yulAnalysisSuccessful = stack.parseAndAnalyze("", compiledContract.yulIR); + solAssert( + yulAnalysisSuccessful, + compiledContract.yulIR + "\n\n" + "Invalid IR generated:\n" + + SourceReferenceFormatter::formatErrorInformation(stack.errors(), stack) + "\n" + ); + compiledContract.yulIRAst = stack.astJson(); if (!_unoptimizedOnly) { - // Optimizer does not maintain correct native source locations in the AST. - // We can work around it by regenerating the AST from scratch from optimized IR. - YulStack stack = parseYul(compiledContract.yulIROptimized); + stack.optimize(); + compiledContract.yulIROptimized = stack.print(this); compiledContract.yulIROptimizedAst = stack.astJson(); } } diff --git a/libyul/YulStack.cpp b/libyul/YulStack.cpp index dbe30bb136d5..a391a696354b 100644 --- a/libyul/YulStack.cpp +++ b/libyul/YulStack.cpp @@ -30,6 +30,7 @@ #include #include #include +#include #include #include @@ -117,7 +118,10 @@ void YulStack::optimize() m_stackState = Parsed; optimize(*m_parserResult, true); - yulAssert(analyzeParsed(), "Invalid source code after optimization."); + + // Optimizer does not maintain correct native source locations in the AST. + // We can work around it by regenerating the AST from scratch from optimized IR. + reparse(); } catch (UnimplementedFeatureError const& _error) { @@ -241,6 +245,33 @@ void YulStack::optimize(Object& _object, bool _isCreation) ); } +void YulStack::reparse() +{ + yulAssert(m_parserResult); + yulAssert(m_charStream); + + // NOTE: Without passing in _soliditySourceProvider, printed debug info will not include code + // snippets, but it does not matter - we'll still get the same AST after we parse it. Snippets + // are not stored in the AST and the other info that is (location, AST ID, etc) will still be present. + std::string source = print(nullptr /* _soliditySourceProvider */); + + YulStack cleanStack(m_evmVersion, m_eofVersion, m_language, m_optimiserSettings, m_debugInfoSelection); + bool reanalysisSuccessful = cleanStack.parseAndAnalyze(m_charStream->name(), source); + yulAssert( + reanalysisSuccessful, + source + "\n\n" + "Invalid IR generated:\n" + + SourceReferenceFormatter::formatErrorInformation(cleanStack.errors(), cleanStack) + "\n" + ); + + m_stackState = AnalysisSuccessful; + m_parserResult = std::move(cleanStack.m_parserResult); + + // NOTE: We keep the char stream, and errors, even though they no longer match the object, + // because it's the original source that matters to the user. Optimized code may have different + // locations and fewer warnings. +} + MachineAssemblyObject YulStack::assemble(Machine _machine) { yulAssert(m_stackState >= AnalysisSuccessful); diff --git a/libyul/YulStack.h b/libyul/YulStack.h index f547ef77027e..4dc262a25c76 100644 --- a/libyul/YulStack.h +++ b/libyul/YulStack.h @@ -152,6 +152,13 @@ class YulStack: public langutil::CharStreamProvider void optimize(yul::Object& _object, bool _isCreation); + /// Prints the Yul object stored internally and parses it again. + /// This ensures that the debug info in the AST matches the source that printing would produce + /// rather than the initial source. + /// @warning Does not update the error list or the original source (@a m_charStream) to make + /// it possible to report errors to the user even after the optimization has been performed. + void reparse(); + void reportUnimplementedFeatureError(langutil::UnimplementedFeatureError const& _error); Language m_language = Language::Assembly; diff --git a/test/cmdlineTests/ast_ir/output b/test/cmdlineTests/ast_ir/output index 76f111990870..3211ef49b3bf 100644 --- a/test/cmdlineTests/ast_ir/output +++ b/test/cmdlineTests/ast_ir/output @@ -637,24 +637,24 @@ Optimized IR AST: { "code": { "block": { - "nativeSrc": "58:315:0", + "nativeSrc": "58:298:0", "nodeType": "YulBlock", "src": "-1:-1:0", "statements": [ { - "nativeSrc": "68:299:0", + "nativeSrc": "68:282:0", "nodeType": "YulBlock", "src": "-1:-1:0", "statements": [ { - "nativeSrc": "128:27:0", + "nativeSrc": "111:27:0", "nodeType": "YulVariableDeclaration", "src": "60:13:0", "value": { "arguments": [ { "kind": "number", - "nativeSrc": "150:4:0", + "nativeSrc": "133:4:0", "nodeType": "YulLiteral", "src": "60:13:0", "type": "", @@ -663,18 +663,18 @@ Optimized IR AST: ], "functionName": { "name": "memoryguard", - "nativeSrc": "138:11:0", + "nativeSrc": "121:11:0", "nodeType": "YulIdentifier", "src": "60:13:0" }, - "nativeSrc": "138:17:0", + "nativeSrc": "121:17:0", "nodeType": "YulFunctionCall", "src": "60:13:0" }, "variables": [ { "name": "_1", - "nativeSrc": "132:2:0", + "nativeSrc": "115:2:0", "nodeType": "YulTypedName", "src": "60:13:0", "type": "" @@ -686,7 +686,7 @@ Optimized IR AST: "arguments": [ { "kind": "number", - "nativeSrc": "175:2:0", + "nativeSrc": "158:2:0", "nodeType": "YulLiteral", "src": "60:13:0", "type": "", @@ -694,28 +694,28 @@ Optimized IR AST: }, { "name": "_1", - "nativeSrc": "179:2:0", + "nativeSrc": "162:2:0", "nodeType": "YulIdentifier", "src": "60:13:0" } ], "functionName": { "name": "mstore", - "nativeSrc": "168:6:0", + "nativeSrc": "151:6:0", "nodeType": "YulIdentifier", "src": "60:13:0" }, - "nativeSrc": "168:14:0", + "nativeSrc": "151:14:0", "nodeType": "YulFunctionCall", "src": "60:13:0" }, - "nativeSrc": "168:14:0", + "nativeSrc": "151:14:0", "nodeType": "YulExpressionStatement", "src": "60:13:0" }, { "body": { - "nativeSrc": "210:16:0", + "nativeSrc": "193:16:0", "nodeType": "YulBlock", "src": "60:13:0", "statements": [ @@ -724,7 +724,7 @@ Optimized IR AST: "arguments": [ { "kind": "number", - "nativeSrc": "219:1:0", + "nativeSrc": "202:1:0", "nodeType": "YulLiteral", "src": "60:13:0", "type": "", @@ -732,7 +732,7 @@ Optimized IR AST: }, { "kind": "number", - "nativeSrc": "222:1:0", + "nativeSrc": "205:1:0", "nodeType": "YulLiteral", "src": "60:13:0", "type": "", @@ -741,15 +741,15 @@ Optimized IR AST: ], "functionName": { "name": "revert", - "nativeSrc": "212:6:0", + "nativeSrc": "195:6:0", "nodeType": "YulIdentifier", "src": "60:13:0" }, - "nativeSrc": "212:12:0", + "nativeSrc": "195:12:0", "nodeType": "YulFunctionCall", "src": "60:13:0" }, - "nativeSrc": "212:12:0", + "nativeSrc": "195:12:0", "nodeType": "YulExpressionStatement", "src": "60:13:0" } @@ -759,20 +759,20 @@ Optimized IR AST: "arguments": [], "functionName": { "name": "callvalue", - "nativeSrc": "198:9:0", + "nativeSrc": "181:9:0", "nodeType": "YulIdentifier", "src": "60:13:0" }, - "nativeSrc": "198:11:0", + "nativeSrc": "181:11:0", "nodeType": "YulFunctionCall", "src": "60:13:0" }, - "nativeSrc": "195:31:0", + "nativeSrc": "178:31:0", "nodeType": "YulIf", "src": "60:13:0" }, { - "nativeSrc": "239:34:0", + "nativeSrc": "222:34:0", "nodeType": "YulVariableDeclaration", "src": "60:13:0", "value": { @@ -780,7 +780,7 @@ Optimized IR AST: { "hexValue": "435f325f6465706c6f796564", "kind": "string", - "nativeSrc": "258:14:0", + "nativeSrc": "241:14:0", "nodeType": "YulLiteral", "src": "60:13:0", "type": "", @@ -789,18 +789,18 @@ Optimized IR AST: ], "functionName": { "name": "datasize", - "nativeSrc": "249:8:0", + "nativeSrc": "232:8:0", "nodeType": "YulIdentifier", "src": "60:13:0" }, - "nativeSrc": "249:24:0", + "nativeSrc": "232:24:0", "nodeType": "YulFunctionCall", "src": "60:13:0" }, "variables": [ { "name": "_2", - "nativeSrc": "243:2:0", + "nativeSrc": "226:2:0", "nodeType": "YulTypedName", "src": "60:13:0", "type": "" @@ -812,7 +812,7 @@ Optimized IR AST: "arguments": [ { "name": "_1", - "nativeSrc": "295:2:0", + "nativeSrc": "278:2:0", "nodeType": "YulIdentifier", "src": "60:13:0" }, @@ -821,7 +821,7 @@ Optimized IR AST: { "hexValue": "435f325f6465706c6f796564", "kind": "string", - "nativeSrc": "310:14:0", + "nativeSrc": "293:14:0", "nodeType": "YulLiteral", "src": "60:13:0", "type": "", @@ -830,32 +830,32 @@ Optimized IR AST: ], "functionName": { "name": "dataoffset", - "nativeSrc": "299:10:0", + "nativeSrc": "282:10:0", "nodeType": "YulIdentifier", "src": "60:13:0" }, - "nativeSrc": "299:26:0", + "nativeSrc": "282:26:0", "nodeType": "YulFunctionCall", "src": "60:13:0" }, { "name": "_2", - "nativeSrc": "327:2:0", + "nativeSrc": "310:2:0", "nodeType": "YulIdentifier", "src": "60:13:0" } ], "functionName": { "name": "codecopy", - "nativeSrc": "286:8:0", + "nativeSrc": "269:8:0", "nodeType": "YulIdentifier", "src": "60:13:0" }, - "nativeSrc": "286:44:0", + "nativeSrc": "269:44:0", "nodeType": "YulFunctionCall", "src": "60:13:0" }, - "nativeSrc": "286:44:0", + "nativeSrc": "269:44:0", "nodeType": "YulExpressionStatement", "src": "60:13:0" }, @@ -864,28 +864,28 @@ Optimized IR AST: "arguments": [ { "name": "_1", - "nativeSrc": "350:2:0", + "nativeSrc": "333:2:0", "nodeType": "YulIdentifier", "src": "60:13:0" }, { "name": "_2", - "nativeSrc": "354:2:0", + "nativeSrc": "337:2:0", "nodeType": "YulIdentifier", "src": "60:13:0" } ], "functionName": { "name": "return", - "nativeSrc": "343:6:0", + "nativeSrc": "326:6:0", "nodeType": "YulIdentifier", "src": "60:13:0" }, - "nativeSrc": "343:14:0", + "nativeSrc": "326:14:0", "nodeType": "YulFunctionCall", "src": "60:13:0" }, - "nativeSrc": "343:14:0", + "nativeSrc": "326:14:0", "nodeType": "YulExpressionStatement", "src": "60:13:0" } @@ -901,12 +901,12 @@ Optimized IR AST: { "code": { "block": { - "nativeSrc": "453:118:0", + "nativeSrc": "436:101:0", "nodeType": "YulBlock", "src": "-1:-1:0", "statements": [ { - "nativeSrc": "467:94:0", + "nativeSrc": "450:77:0", "nodeType": "YulBlock", "src": "-1:-1:0", "statements": [ @@ -915,7 +915,7 @@ Optimized IR AST: "arguments": [ { "kind": "number", - "nativeSrc": "542:1:0", + "nativeSrc": "508:1:0", "nodeType": "YulLiteral", "src": "60:13:0", "type": "", @@ -923,7 +923,7 @@ Optimized IR AST: }, { "kind": "number", - "nativeSrc": "545:1:0", + "nativeSrc": "511:1:0", "nodeType": "YulLiteral", "src": "60:13:0", "type": "", @@ -932,15 +932,15 @@ Optimized IR AST: ], "functionName": { "name": "revert", - "nativeSrc": "535:6:0", + "nativeSrc": "501:6:0", "nodeType": "YulIdentifier", "src": "60:13:0" }, - "nativeSrc": "535:12:0", + "nativeSrc": "501:12:0", "nodeType": "YulFunctionCall", "src": "60:13:0" }, - "nativeSrc": "535:12:0", + "nativeSrc": "501:12:0", "nodeType": "YulExpressionStatement", "src": "60:13:0" } diff --git a/test/cmdlineTests/linking_strict_assembly/output b/test/cmdlineTests/linking_strict_assembly/output index 29a8abdfaea8..4fa6edc0c372 100644 --- a/test/cmdlineTests/linking_strict_assembly/output +++ b/test/cmdlineTests/linking_strict_assembly/output @@ -16,11 +16,11 @@ Binary representation: 7312345678901234567890123456789012345678905f5500 Text representation: - /* "linking_strict_assembly/input.yul":44:79 */ + /* "linking_strict_assembly/input.yul":58:93 */ linkerSymbol("f919ba91ac99f96129544b80b9516b27a80e376b9dc693819d0b18b7e0395612") - /* "linking_strict_assembly/input.yul":95:96 */ + /* "linking_strict_assembly/input.yul":113:114 */ 0x00 - /* "linking_strict_assembly/input.yul":88:103 */ + /* "linking_strict_assembly/input.yul":106:121 */ sstore - /* "linking_strict_assembly/input.yul":22:109 */ + /* "linking_strict_assembly/input.yul":22:137 */ stop diff --git a/test/cmdlineTests/linking_strict_assembly_same_library_name_different_files/output b/test/cmdlineTests/linking_strict_assembly_same_library_name_different_files/output index 4aecfc6b26b1..69c0a21f63c1 100644 --- a/test/cmdlineTests/linking_strict_assembly_same_library_name_different_files/output +++ b/test/cmdlineTests/linking_strict_assembly_same_library_name_different_files/output @@ -18,19 +18,19 @@ Binary representation: 731111111111111111111111111111111111111111732222222222222222222222222222222222222222905f5560015500 Text representation: - /* "linking_strict_assembly_same_library_name_different_files/input.yul":45:75 */ + /* "linking_strict_assembly_same_library_name_different_files/input.yul":59:89 */ linkerSymbol("f3ffc10c396a7cc41ae954b050792839d20947bf73497d30c49a9fda1ea477ec") - /* "linking_strict_assembly_same_library_name_different_files/input.yul":97:127 */ + /* "linking_strict_assembly_same_library_name_different_files/input.yul":115:145 */ linkerSymbol("c3523432985587641d17c68161d2f700c57aaf4ed21cda4f25d76193c831f97f") - /* "linking_strict_assembly_same_library_name_different_files/input.yul":136:152 */ + /* "linking_strict_assembly_same_library_name_different_files/input.yul":158:174 */ swap1 - /* "linking_strict_assembly_same_library_name_different_files/input.yul":143:144 */ + /* "linking_strict_assembly_same_library_name_different_files/input.yul":165:166 */ 0x00 - /* "linking_strict_assembly_same_library_name_different_files/input.yul":136:152 */ + /* "linking_strict_assembly_same_library_name_different_files/input.yul":158:174 */ sstore - /* "linking_strict_assembly_same_library_name_different_files/input.yul":168:169 */ + /* "linking_strict_assembly_same_library_name_different_files/input.yul":194:195 */ 0x01 - /* "linking_strict_assembly_same_library_name_different_files/input.yul":161:177 */ + /* "linking_strict_assembly_same_library_name_different_files/input.yul":187:203 */ sstore - /* "linking_strict_assembly_same_library_name_different_files/input.yul":22:183 */ + /* "linking_strict_assembly_same_library_name_different_files/input.yul":22:219 */ stop diff --git a/test/cmdlineTests/linking_strict_assembly_same_library_name_different_files_in_link_references/output b/test/cmdlineTests/linking_strict_assembly_same_library_name_different_files_in_link_references/output index 10a7fe7fe067..14fafa4e4604 100644 --- a/test/cmdlineTests/linking_strict_assembly_same_library_name_different_files_in_link_references/output +++ b/test/cmdlineTests/linking_strict_assembly_same_library_name_different_files_in_link_references/output @@ -18,19 +18,19 @@ Binary representation: 73123456789012345678901234567890123456789073__$c3523432985587641d17c68161d2f700c5$__905f5560015500 Text representation: - /* "linking_strict_assembly_same_library_name_different_files_in_link_references/input.yul":45:75 */ + /* "linking_strict_assembly_same_library_name_different_files_in_link_references/input.yul":59:89 */ linkerSymbol("f3ffc10c396a7cc41ae954b050792839d20947bf73497d30c49a9fda1ea477ec") - /* "linking_strict_assembly_same_library_name_different_files_in_link_references/input.yul":97:127 */ + /* "linking_strict_assembly_same_library_name_different_files_in_link_references/input.yul":115:145 */ linkerSymbol("c3523432985587641d17c68161d2f700c57aaf4ed21cda4f25d76193c831f97f") - /* "linking_strict_assembly_same_library_name_different_files_in_link_references/input.yul":136:152 */ + /* "linking_strict_assembly_same_library_name_different_files_in_link_references/input.yul":158:174 */ swap1 - /* "linking_strict_assembly_same_library_name_different_files_in_link_references/input.yul":143:144 */ + /* "linking_strict_assembly_same_library_name_different_files_in_link_references/input.yul":165:166 */ 0x00 - /* "linking_strict_assembly_same_library_name_different_files_in_link_references/input.yul":136:152 */ + /* "linking_strict_assembly_same_library_name_different_files_in_link_references/input.yul":158:174 */ sstore - /* "linking_strict_assembly_same_library_name_different_files_in_link_references/input.yul":168:169 */ + /* "linking_strict_assembly_same_library_name_different_files_in_link_references/input.yul":194:195 */ 0x01 - /* "linking_strict_assembly_same_library_name_different_files_in_link_references/input.yul":161:177 */ + /* "linking_strict_assembly_same_library_name_different_files_in_link_references/input.yul":187:203 */ sstore - /* "linking_strict_assembly_same_library_name_different_files_in_link_references/input.yul":22:183 */ + /* "linking_strict_assembly_same_library_name_different_files_in_link_references/input.yul":22:219 */ stop diff --git a/test/cmdlineTests/linking_strict_assembly_unresolved_references/output b/test/cmdlineTests/linking_strict_assembly_unresolved_references/output index a110db5a3e4e..3b2d84ab3c6b 100644 --- a/test/cmdlineTests/linking_strict_assembly_unresolved_references/output +++ b/test/cmdlineTests/linking_strict_assembly_unresolved_references/output @@ -18,19 +18,19 @@ Binary representation: 73123456789012345678901234567890123456789073__$fb58009a6b1ecea3b9d99bedd645df4ec3$__905f5560015500 Text representation: - /* "linking_strict_assembly_unresolved_references/input.yul":45:81 */ + /* "linking_strict_assembly_unresolved_references/input.yul":59:95 */ linkerSymbol("05b0326038374a21e0895480a58bda0768cdcc04c8d18f154362d1ca5223d245") - /* "linking_strict_assembly_unresolved_references/input.yul":103:139 */ + /* "linking_strict_assembly_unresolved_references/input.yul":121:157 */ linkerSymbol("fb58009a6b1ecea3b9d99bedd645df4ec308f17bc0087e5f39d078f77f809177") - /* "linking_strict_assembly_unresolved_references/input.yul":148:164 */ + /* "linking_strict_assembly_unresolved_references/input.yul":170:186 */ swap1 - /* "linking_strict_assembly_unresolved_references/input.yul":155:156 */ + /* "linking_strict_assembly_unresolved_references/input.yul":177:178 */ 0x00 - /* "linking_strict_assembly_unresolved_references/input.yul":148:164 */ + /* "linking_strict_assembly_unresolved_references/input.yul":170:186 */ sstore - /* "linking_strict_assembly_unresolved_references/input.yul":180:181 */ + /* "linking_strict_assembly_unresolved_references/input.yul":206:207 */ 0x01 - /* "linking_strict_assembly_unresolved_references/input.yul":173:189 */ + /* "linking_strict_assembly_unresolved_references/input.yul":199:215 */ sstore - /* "linking_strict_assembly_unresolved_references/input.yul":22:195 */ + /* "linking_strict_assembly_unresolved_references/input.yul":22:231 */ stop diff --git a/test/cmdlineTests/object_compiler/output b/test/cmdlineTests/object_compiler/output index 5dd572272a6a..a88851b96c71 100644 --- a/test/cmdlineTests/object_compiler/output +++ b/test/cmdlineTests/object_compiler/output @@ -26,40 +26,40 @@ Binary representation: 335f55600880600d5f395ff3fe5f545f5260205ff3 Text representation: - /* "object_compiler/input.yul":128:136 */ + /* "object_compiler/input.yul":65:73 */ caller - /* "object_compiler/input.yul":125:126 */ + /* "object_compiler/input.yul":62:63 */ 0x00 - /* "object_compiler/input.yul":118:137 */ + /* "object_compiler/input.yul":55:74 */ sstore - /* "object_compiler/input.yul":240:259 */ + /* "object_compiler/input.yul":97:116 */ dataSize(sub_0) - /* "object_compiler/input.yul":217:238 */ + /* "object_compiler/input.yul":141:162 */ dup1 dataOffset(sub_0) - /* "object_compiler/input.yul":125:126 */ + /* "object_compiler/input.yul":138:139 */ 0x00 - /* "object_compiler/input.yul":205:260 */ + /* "object_compiler/input.yul":129:167 */ codecopy - /* "object_compiler/input.yul":125:126 */ + /* "object_compiler/input.yul":187:188 */ 0x00 - /* "object_compiler/input.yul":265:295 */ + /* "object_compiler/input.yul":180:193 */ return stop sub_0: assembly { - /* "object_compiler/input.yul":397:398 */ + /* "object_compiler/input.yul":294:295 */ 0x00 - /* "object_compiler/input.yul":391:399 */ + /* "object_compiler/input.yul":288:296 */ sload - /* "object_compiler/input.yul":397:398 */ + /* "object_compiler/input.yul":285:286 */ 0x00 - /* "object_compiler/input.yul":381:400 */ + /* "object_compiler/input.yul":278:297 */ mstore - /* "object_compiler/input.yul":417:421 */ + /* "object_compiler/input.yul":324:328 */ 0x20 - /* "object_compiler/input.yul":397:398 */ + /* "object_compiler/input.yul":321:322 */ 0x00 - /* "object_compiler/input.yul":407:422 */ + /* "object_compiler/input.yul":314:329 */ return } diff --git a/test/cmdlineTests/standard_irOptimized_ast_requested/output.json b/test/cmdlineTests/standard_irOptimized_ast_requested/output.json index 5c6762ac9907..f80f4466cad8 100644 --- a/test/cmdlineTests/standard_irOptimized_ast_requested/output.json +++ b/test/cmdlineTests/standard_irOptimized_ast_requested/output.json @@ -5,12 +5,12 @@ "irOptimizedAst": { "code": { "block": { - "nativeSrc": "43:639:0", + "nativeSrc": "43:622:0", "nodeType": "YulBlock", "src": "-1:-1:0", "statements": [ { - "nativeSrc": "53:421:0", + "nativeSrc": "53:404:0", "nodeType": "YulBlock", "src": "-1:-1:0", "statements": [ @@ -19,7 +19,7 @@ "arguments": [ { "kind": "number", - "nativeSrc": "120:2:0", + "nativeSrc": "103:2:0", "nodeType": "YulLiteral", "src": "56:13:0", "type": "", @@ -29,7 +29,7 @@ "arguments": [ { "kind": "number", - "nativeSrc": "136:4:0", + "nativeSrc": "119:4:0", "nodeType": "YulLiteral", "src": "56:13:0", "type": "", @@ -38,32 +38,32 @@ ], "functionName": { "name": "memoryguard", - "nativeSrc": "124:11:0", + "nativeSrc": "107:11:0", "nodeType": "YulIdentifier", "src": "56:13:0" }, - "nativeSrc": "124:17:0", + "nativeSrc": "107:17:0", "nodeType": "YulFunctionCall", "src": "56:13:0" } ], "functionName": { "name": "mstore", - "nativeSrc": "113:6:0", + "nativeSrc": "96:6:0", "nodeType": "YulIdentifier", "src": "56:13:0" }, - "nativeSrc": "113:29:0", + "nativeSrc": "96:29:0", "nodeType": "YulFunctionCall", "src": "56:13:0" }, - "nativeSrc": "113:29:0", + "nativeSrc": "96:29:0", "nodeType": "YulExpressionStatement", "src": "56:13:0" }, { "body": { - "nativeSrc": "182:111:0", + "nativeSrc": "165:111:0", "nodeType": "YulBlock", "src": "56:13:0", "statements": [ @@ -72,15 +72,15 @@ "arguments": [], "functionName": { "name": "revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb", - "nativeSrc": "200:77:0", + "nativeSrc": "183:77:0", "nodeType": "YulIdentifier", "src": "56:13:0" }, - "nativeSrc": "200:79:0", + "nativeSrc": "183:79:0", "nodeType": "YulFunctionCall", "src": "56:13:0" }, - "nativeSrc": "200:79:0", + "nativeSrc": "183:79:0", "nodeType": "YulExpressionStatement", "src": "56:13:0" } @@ -90,38 +90,38 @@ "arguments": [], "functionName": { "name": "callvalue", - "nativeSrc": "158:9:0", + "nativeSrc": "141:9:0", "nodeType": "YulIdentifier", "src": "56:13:0" }, - "nativeSrc": "158:11:0", + "nativeSrc": "141:11:0", "nodeType": "YulFunctionCall", "src": "56:13:0" }, - "nativeSrc": "155:138:0", + "nativeSrc": "138:138:0", "nodeType": "YulIf", "src": "56:13:0" }, { - "nativeSrc": "306:30:0", + "nativeSrc": "289:30:0", "nodeType": "YulVariableDeclaration", "src": "56:13:0", "value": { "arguments": [], "functionName": { "name": "allocate_unbounded", - "nativeSrc": "316:18:0", + "nativeSrc": "299:18:0", "nodeType": "YulIdentifier", "src": "56:13:0" }, - "nativeSrc": "316:20:0", + "nativeSrc": "299:20:0", "nodeType": "YulFunctionCall", "src": "56:13:0" }, "variables": [ { "name": "_1", - "nativeSrc": "310:2:0", + "nativeSrc": "293:2:0", "nodeType": "YulTypedName", "src": "56:13:0", "type": "" @@ -133,7 +133,7 @@ "arguments": [ { "name": "_1", - "nativeSrc": "358:2:0", + "nativeSrc": "341:2:0", "nodeType": "YulIdentifier", "src": "56:13:0" }, @@ -142,7 +142,7 @@ { "hexValue": "435f325f6465706c6f796564", "kind": "string", - "nativeSrc": "373:14:0", + "nativeSrc": "356:14:0", "nodeType": "YulLiteral", "src": "56:13:0", "type": "", @@ -151,11 +151,11 @@ ], "functionName": { "name": "dataoffset", - "nativeSrc": "362:10:0", + "nativeSrc": "345:10:0", "nodeType": "YulIdentifier", "src": "56:13:0" }, - "nativeSrc": "362:26:0", + "nativeSrc": "345:26:0", "nodeType": "YulFunctionCall", "src": "56:13:0" }, @@ -164,7 +164,7 @@ { "hexValue": "435f325f6465706c6f796564", "kind": "string", - "nativeSrc": "399:14:0", + "nativeSrc": "382:14:0", "nodeType": "YulLiteral", "src": "56:13:0", "type": "", @@ -173,26 +173,26 @@ ], "functionName": { "name": "datasize", - "nativeSrc": "390:8:0", + "nativeSrc": "373:8:0", "nodeType": "YulIdentifier", "src": "56:13:0" }, - "nativeSrc": "390:24:0", + "nativeSrc": "373:24:0", "nodeType": "YulFunctionCall", "src": "56:13:0" } ], "functionName": { "name": "codecopy", - "nativeSrc": "349:8:0", + "nativeSrc": "332:8:0", "nodeType": "YulIdentifier", "src": "56:13:0" }, - "nativeSrc": "349:66:0", + "nativeSrc": "332:66:0", "nodeType": "YulFunctionCall", "src": "56:13:0" }, - "nativeSrc": "349:66:0", + "nativeSrc": "332:66:0", "nodeType": "YulExpressionStatement", "src": "56:13:0" }, @@ -201,7 +201,7 @@ "arguments": [ { "name": "_1", - "nativeSrc": "435:2:0", + "nativeSrc": "418:2:0", "nodeType": "YulIdentifier", "src": "56:13:0" }, @@ -210,7 +210,7 @@ { "hexValue": "435f325f6465706c6f796564", "kind": "string", - "nativeSrc": "448:14:0", + "nativeSrc": "431:14:0", "nodeType": "YulLiteral", "src": "56:13:0", "type": "", @@ -219,26 +219,26 @@ ], "functionName": { "name": "datasize", - "nativeSrc": "439:8:0", + "nativeSrc": "422:8:0", "nodeType": "YulIdentifier", "src": "56:13:0" }, - "nativeSrc": "439:24:0", + "nativeSrc": "422:24:0", "nodeType": "YulFunctionCall", "src": "56:13:0" } ], "functionName": { "name": "return", - "nativeSrc": "428:6:0", + "nativeSrc": "411:6:0", "nodeType": "YulIdentifier", "src": "56:13:0" }, - "nativeSrc": "428:36:0", + "nativeSrc": "411:36:0", "nodeType": "YulFunctionCall", "src": "56:13:0" }, - "nativeSrc": "428:36:0", + "nativeSrc": "411:36:0", "nodeType": "YulExpressionStatement", "src": "56:13:0" } @@ -246,19 +246,19 @@ }, { "body": { - "nativeSrc": "531:23:0", + "nativeSrc": "514:23:0", "nodeType": "YulBlock", "src": "56:13:0", "statements": [ { - "nativeSrc": "533:19:0", + "nativeSrc": "516:19:0", "nodeType": "YulAssignment", "src": "56:13:0", "value": { "arguments": [ { "kind": "number", - "nativeSrc": "549:2:0", + "nativeSrc": "532:2:0", "nodeType": "YulLiteral", "src": "56:13:0", "type": "", @@ -267,18 +267,18 @@ ], "functionName": { "name": "mload", - "nativeSrc": "543:5:0", + "nativeSrc": "526:5:0", "nodeType": "YulIdentifier", "src": "56:13:0" }, - "nativeSrc": "543:9:0", + "nativeSrc": "526:9:0", "nodeType": "YulFunctionCall", "src": "56:13:0" }, "variableNames": [ { "name": "memPtr", - "nativeSrc": "533:6:0", + "nativeSrc": "516:6:0", "nodeType": "YulIdentifier", "src": "56:13:0" } @@ -287,12 +287,12 @@ ] }, "name": "allocate_unbounded", - "nativeSrc": "483:71:0", + "nativeSrc": "466:71:0", "nodeType": "YulFunctionDefinition", "returnVariables": [ { "name": "memPtr", - "nativeSrc": "516:6:0", + "nativeSrc": "499:6:0", "nodeType": "YulTypedName", "src": "56:13:0", "type": "" @@ -302,7 +302,7 @@ }, { "body": { - "nativeSrc": "660:16:0", + "nativeSrc": "643:16:0", "nodeType": "YulBlock", "src": "56:13:0", "statements": [ @@ -311,7 +311,7 @@ "arguments": [ { "kind": "number", - "nativeSrc": "669:1:0", + "nativeSrc": "652:1:0", "nodeType": "YulLiteral", "src": "56:13:0", "type": "", @@ -319,7 +319,7 @@ }, { "kind": "number", - "nativeSrc": "672:1:0", + "nativeSrc": "655:1:0", "nodeType": "YulLiteral", "src": "56:13:0", "type": "", @@ -328,22 +328,22 @@ ], "functionName": { "name": "revert", - "nativeSrc": "662:6:0", + "nativeSrc": "645:6:0", "nodeType": "YulIdentifier", "src": "56:13:0" }, - "nativeSrc": "662:12:0", + "nativeSrc": "645:12:0", "nodeType": "YulFunctionCall", "src": "56:13:0" }, - "nativeSrc": "662:12:0", + "nativeSrc": "645:12:0", "nodeType": "YulExpressionStatement", "src": "56:13:0" } ] }, "name": "revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb", - "nativeSrc": "563:113:0", + "nativeSrc": "546:113:0", "nodeType": "YulFunctionDefinition", "src": "56:13:0" } @@ -357,12 +357,12 @@ { "code": { "block": { - "nativeSrc": "747:361:0", + "nativeSrc": "730:344:0", "nodeType": "YulBlock", "src": "-1:-1:0", "statements": [ { - "nativeSrc": "761:207:0", + "nativeSrc": "744:190:0", "nodeType": "YulBlock", "src": "-1:-1:0", "statements": [ @@ -371,7 +371,7 @@ "arguments": [ { "kind": "number", - "nativeSrc": "836:2:0", + "nativeSrc": "802:2:0", "nodeType": "YulLiteral", "src": "56:13:0", "type": "", @@ -381,7 +381,7 @@ "arguments": [ { "kind": "number", - "nativeSrc": "852:4:0", + "nativeSrc": "818:4:0", "nodeType": "YulLiteral", "src": "56:13:0", "type": "", @@ -390,26 +390,26 @@ ], "functionName": { "name": "memoryguard", - "nativeSrc": "840:11:0", + "nativeSrc": "806:11:0", "nodeType": "YulIdentifier", "src": "56:13:0" }, - "nativeSrc": "840:17:0", + "nativeSrc": "806:17:0", "nodeType": "YulFunctionCall", "src": "56:13:0" } ], "functionName": { "name": "mstore", - "nativeSrc": "829:6:0", + "nativeSrc": "795:6:0", "nodeType": "YulIdentifier", "src": "56:13:0" }, - "nativeSrc": "829:29:0", + "nativeSrc": "795:29:0", "nodeType": "YulFunctionCall", "src": "56:13:0" }, - "nativeSrc": "829:29:0", + "nativeSrc": "795:29:0", "nodeType": "YulExpressionStatement", "src": "56:13:0" }, @@ -418,15 +418,15 @@ "arguments": [], "functionName": { "name": "revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74", - "nativeSrc": "875:77:0", + "nativeSrc": "841:77:0", "nodeType": "YulIdentifier", "src": "56:13:0" }, - "nativeSrc": "875:79:0", + "nativeSrc": "841:79:0", "nodeType": "YulFunctionCall", "src": "56:13:0" }, - "nativeSrc": "875:79:0", + "nativeSrc": "841:79:0", "nodeType": "YulExpressionStatement", "src": "56:13:0" } @@ -434,7 +434,7 @@ }, { "body": { - "nativeSrc": "1082:16:0", + "nativeSrc": "1048:16:0", "nodeType": "YulBlock", "src": "56:13:0", "statements": [ @@ -443,7 +443,7 @@ "arguments": [ { "kind": "number", - "nativeSrc": "1091:1:0", + "nativeSrc": "1057:1:0", "nodeType": "YulLiteral", "src": "56:13:0", "type": "", @@ -451,7 +451,7 @@ }, { "kind": "number", - "nativeSrc": "1094:1:0", + "nativeSrc": "1060:1:0", "nodeType": "YulLiteral", "src": "56:13:0", "type": "", @@ -460,22 +460,22 @@ ], "functionName": { "name": "revert", - "nativeSrc": "1084:6:0", + "nativeSrc": "1050:6:0", "nodeType": "YulIdentifier", "src": "56:13:0" }, - "nativeSrc": "1084:12:0", + "nativeSrc": "1050:12:0", "nodeType": "YulFunctionCall", "src": "56:13:0" }, - "nativeSrc": "1084:12:0", + "nativeSrc": "1050:12:0", "nodeType": "YulExpressionStatement", "src": "56:13:0" } ] }, "name": "revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74", - "nativeSrc": "981:117:0", + "nativeSrc": "947:117:0", "nodeType": "YulFunctionDefinition", "src": "56:13:0" } diff --git a/test/cmdlineTests/standard_yul/output.json b/test/cmdlineTests/standard_yul/output.json index 8d2ab0074790..30fe1dd7ecb7 100644 --- a/test/cmdlineTests/standard_yul/output.json +++ b/test/cmdlineTests/standard_yul/output.json @@ -3,17 +3,17 @@ "A": { "object": { "evm": { - "assembly": " /* \"A\":38:39 */ + "assembly": " /* \"A\":99:100 */ 0x00 - /* \"A\":11:19 */ + /* \"A\":60:68 */ dup1 dup1 mload - /* \"A\":27:36 */ + /* \"A\":88:97 */ add - /* \"A\":20:40 */ + /* \"A\":81:101 */ sstore - /* \"A\":0:42 */ + /* \"A\":27:117 */ stop ", "bytecode": { diff --git a/test/cmdlineTests/standard_yul_object/output.json b/test/cmdlineTests/standard_yul_object/output.json index 87d0cab8f4ff..3181da426000 100644 --- a/test/cmdlineTests/standard_yul_object/output.json +++ b/test/cmdlineTests/standard_yul_object/output.json @@ -3,16 +3,16 @@ "A": { "NamedObject": { "evm": { - "assembly": " /* \"A\":80:81 */ + "assembly": " /* \"A\":118:119 */ 0x00 - /* \"A\":39:61 */ + /* \"A\":65:87 */ dup1 data_4e03657aea45a94fc7d47ba826c8d667c0d1e6e33a64a036ec44f58fa12d6c45 - /* \"A\":69:78 */ + /* \"A\":107:116 */ add - /* \"A\":62:82 */ + /* \"A\":100:120 */ sstore - /* \"A\":28:84 */ + /* \"A\":32:136 */ stop stop data_4e03657aea45a94fc7d47ba826c8d667c0d1e6e33a64a036ec44f58fa12d6c45 616263 diff --git a/test/cmdlineTests/standard_yul_object_name/output.json b/test/cmdlineTests/standard_yul_object_name/output.json index c6e98130d210..1512900e1c85 100644 --- a/test/cmdlineTests/standard_yul_object_name/output.json +++ b/test/cmdlineTests/standard_yul_object_name/output.json @@ -3,24 +3,24 @@ "A": { "NamedObject": { "evm": { - "assembly": " /* \"A\":80:81 */ + "assembly": " /* \"A\":118:119 */ 0x00 - /* \"A\":39:61 */ + /* \"A\":65:87 */ dup1 data_4e03657aea45a94fc7d47ba826c8d667c0d1e6e33a64a036ec44f58fa12d6c45 - /* \"A\":69:78 */ + /* \"A\":107:116 */ add - /* \"A\":62:82 */ + /* \"A\":100:120 */ sstore - /* \"A\":28:84 */ + /* \"A\":32:136 */ stop stop data_4e03657aea45a94fc7d47ba826c8d667c0d1e6e33a64a036ec44f58fa12d6c45 616263 sub_0: assembly { - /* \"A\":147:148 */ + /* \"A\":223:224 */ 0x00 - /* \"A\":137:149 */ + /* \"A\":213:225 */ dup1 revert } diff --git a/test/cmdlineTests/standard_yul_optimiserSteps/output.json b/test/cmdlineTests/standard_yul_optimiserSteps/output.json index 1c72379c610b..2a654d20a9cb 100644 --- a/test/cmdlineTests/standard_yul_optimiserSteps/output.json +++ b/test/cmdlineTests/standard_yul_optimiserSteps/output.json @@ -3,14 +3,14 @@ "A": { "object": { "evm": { - "assembly": " /* \"A\":38:39 */ + "assembly": " /* \"A\":99:100 */ 0x00 - /* \"A\":11:19 */ + /* \"A\":60:68 */ dup1 mload - /* \"A\":20:40 */ + /* \"A\":81:101 */ sstore - /* \"A\":0:42 */ + /* \"A\":27:117 */ stop ", "bytecode": { diff --git a/test/cmdlineTests/standard_yul_optimized/output.json b/test/cmdlineTests/standard_yul_optimized/output.json index c443b2863f15..513f8148a0f9 100644 --- a/test/cmdlineTests/standard_yul_optimized/output.json +++ b/test/cmdlineTests/standard_yul_optimized/output.json @@ -3,14 +3,14 @@ "A": { "object": { "evm": { - "assembly": " /* \"A\":17:18 */ + "assembly": " /* \"A\":48:49 */ 0x00 - /* \"A\":11:19 */ + /* \"A\":38:46 */ dup1 mload - /* \"A\":20:40 */ + /* \"A\":31:50 */ sstore - /* \"A\":0:42 */ + /* \"A\":27:54 */ stop ", "bytecode": { diff --git a/test/cmdlineTests/standard_yul_stack_opt/output.json b/test/cmdlineTests/standard_yul_stack_opt/output.json index 9d89edfb4ae9..4d7d96b49d0b 100644 --- a/test/cmdlineTests/standard_yul_stack_opt/output.json +++ b/test/cmdlineTests/standard_yul_stack_opt/output.json @@ -3,19 +3,19 @@ "A": { "object": { "evm": { - "assembly": " /* \"A\":16:17 */ + "assembly": " /* \"A\":61:62 */ 0x01 - /* \"A\":27:28 */ + /* \"A\":58:59 */ 0x00 - /* \"A\":20:32 */ + /* \"A\":51:63 */ sstore - /* \"A\":50:51 */ + /* \"A\":87:88 */ 0x02 - /* \"A\":61:63 */ + /* \"A\":83:85 */ 0x20 - /* \"A\":54:67 */ + /* \"A\":76:89 */ sstore - /* \"A\":0:72 */ + /* \"A\":27:105 */ stop " } diff --git a/test/cmdlineTests/standard_yul_stack_opt_disabled/output.json b/test/cmdlineTests/standard_yul_stack_opt_disabled/output.json index f0752b812b44..ca7e2de19979 100644 --- a/test/cmdlineTests/standard_yul_stack_opt_disabled/output.json +++ b/test/cmdlineTests/standard_yul_stack_opt_disabled/output.json @@ -3,17 +3,17 @@ "A": { "object": { "evm": { - "assembly": " /* \"A\":16:17 */ + "assembly": " /* \"A\":61:62 */ 0x01 - /* \"A\":27:28 */ + /* \"A\":58:59 */ 0x00 - /* \"A\":20:32 */ + /* \"A\":51:63 */ sstore - /* \"A\":50:51 */ + /* \"A\":87:88 */ 0x02 - /* \"A\":61:63 */ + /* \"A\":83:85 */ 0x20 - /* \"A\":54:67 */ + /* \"A\":76:89 */ sstore " } diff --git a/test/cmdlineTests/strict_asm_asm_json_without_debug_info_annotations/output b/test/cmdlineTests/strict_asm_asm_json_without_debug_info_annotations/output index 25fb482d484e..305185f016e8 100644 --- a/test/cmdlineTests/strict_asm_asm_json_without_debug_info_annotations/output +++ b/test/cmdlineTests/strict_asm_asm_json_without_debug_info_annotations/output @@ -171,207 +171,207 @@ EVM assembly: ".auxdata": "1234abcd", ".code": [ { - "begin": 469, - "end": 486, + "begin": 468, + "end": 485, "name": "PUSH", "source": -1, "value": "80" }, { - "begin": 503, - "end": 517, + "begin": 502, + "end": 516, "name": "DUP1", "source": -1 }, { - "begin": 510, - "end": 512, + "begin": 509, + "end": 511, "name": "PUSH", "source": -1, "value": "40" }, { - "begin": 503, - "end": 517, + "begin": 502, + "end": 516, "name": "MSTORE", "source": -1 }, { - "begin": 563, - "end": 564, + "begin": 562, + "end": 563, "name": "PUSH", "source": -1, "value": "4" }, { - "begin": 547, - "end": 561, + "begin": 546, + "end": 560, "name": "CALLDATASIZE", "source": -1 }, { - "begin": 544, - "end": 565, + "begin": 543, + "end": 564, "name": "LT", "source": -1 }, { - "begin": 537, - "end": 566, + "begin": 536, + "end": 565, "name": "ISZERO", "source": -1 }, { - "begin": 534, - "end": 832, + "begin": 533, + "end": 831, "name": "PUSH [tag]", "source": -1, "value": "1" }, { - "begin": 534, - "end": 832, + "begin": 533, + "end": 831, "name": "JUMPI", "source": -1 }, { - "begin": 427, - "end": 885, + "begin": 426, + "end": 884, "name": "tag", "source": -1, "value": "2" }, { - "begin": 427, - "end": 885, + "begin": 426, + "end": 884, "name": "JUMPDEST", "source": -1 }, { - "begin": 859, - "end": 860, + "begin": 858, + "end": 859, "name": "PUSH", "source": -1, "value": "0" }, { - "begin": 849, - "end": 861, + "begin": 848, + "end": 860, "name": "DUP1", "source": -1 }, { - "begin": 849, - "end": 861, + "begin": 848, + "end": 860, "name": "REVERT", "source": -1 }, { - "begin": 583, - "end": 832, + "begin": 582, + "end": 831, "name": "tag", "source": -1, "value": "1" }, { - "begin": 583, - "end": 832, + "begin": 582, + "end": 831, "name": "JUMPDEST", "source": -1 }, { - "begin": 615, - "end": 616, + "begin": 614, + "end": 615, "name": "PUSH", "source": -1, "value": "0" }, { - "begin": 653, - "end": 669, + "begin": 652, + "end": 668, "name": "CALLDATALOAD", "source": -1 }, { - "begin": 648, - "end": 651, + "begin": 647, + "end": 650, "name": "PUSH", "source": -1, "value": "E0" }, { - "begin": 644, - "end": 670, + "begin": 643, + "end": 669, "name": "SHR", "source": -1 }, { - "begin": 696, - "end": 706, + "begin": 695, + "end": 705, "name": "PUSH", "source": -1, "value": "B4F40C61" }, { - "begin": 691, - "end": 814, + "begin": 690, + "end": 813, "name": "SUB", "source": -1 }, { - "begin": 583, - "end": 832, + "begin": 582, + "end": 831, "name": "PUSH [tag]", "source": -1, "value": "2" }, { - "begin": 691, - "end": 814, + "begin": 690, + "end": 813, "name": "JUMPI", "source": -1 }, { - "begin": 789, - "end": 791, + "begin": 788, + "end": 790, "name": "PUSH", "source": -1, "value": "20" }, { - "begin": 744, - "end": 752, + "begin": 743, + "end": 751, "name": "SWAP1", "source": -1 }, { - "begin": 750, - "end": 751, + "begin": 749, + "end": 750, "name": "PUSH", "source": -1, "value": "1" }, { - "begin": 744, - "end": 752, + "begin": 743, + "end": 751, "name": "SLOAD", "source": -1 }, { - "begin": 733, - "end": 753, + "begin": 732, + "end": 752, "name": "DUP2", "source": -1 }, { - "begin": 733, - "end": 753, + "begin": 732, + "end": 752, "name": "MSTORE", "source": -1 }, { - "begin": 778, - "end": 792, + "begin": 777, + "end": 791, "name": "RETURN", "source": -1 } diff --git a/test/cmdlineTests/strict_asm_ast_compact_json/output b/test/cmdlineTests/strict_asm_ast_compact_json/output index b4c6dc142467..b2271c36cb05 100644 --- a/test/cmdlineTests/strict_asm_ast_compact_json/output +++ b/test/cmdlineTests/strict_asm_ast_compact_json/output @@ -5,12 +5,12 @@ AST: { "code": { "block": { - "nativeSrc": "60:246:0", + "nativeSrc": "60:85:0", "nodeType": "YulBlock", "src": "-1:-1:0", "statements": [ { - "nativeSrc": "60:246:0", + "nativeSrc": "70:69:0", "nodeType": "YulBlock", "src": "-1:-1:0", "statements": [ @@ -19,7 +19,7 @@ AST: "arguments": [ { "kind": "number", - "nativeSrc": "122:2:0", + "nativeSrc": "121:2:0", "nodeType": "YulLiteral", "src": "60:41:0", "type": "", @@ -27,7 +27,7 @@ AST: }, { "kind": "number", - "nativeSrc": "126:3:0", + "nativeSrc": "125:3:0", "nodeType": "YulLiteral", "src": "60:41:0", "type": "", @@ -36,15 +36,15 @@ AST: ], "functionName": { "name": "mstore", - "nativeSrc": "115:6:0", + "nativeSrc": "114:6:0", "nodeType": "YulIdentifier", "src": "60:41:0" }, - "nativeSrc": "115:15:0", + "nativeSrc": "114:15:0", "nodeType": "YulFunctionCall", "src": "60:41:0" }, - "nativeSrc": "115:15:0", + "nativeSrc": "114:15:0", "nodeType": "YulExpressionStatement", "src": "60:41:0" } diff --git a/test/cmdlineTests/strict_asm_evm_version_byzantium/output b/test/cmdlineTests/strict_asm_evm_version_byzantium/output index 3a23390a4039..2840e1d2b697 100644 --- a/test/cmdlineTests/strict_asm_evm_version_byzantium/output +++ b/test/cmdlineTests/strict_asm_evm_version_byzantium/output @@ -11,5 +11,5 @@ Binary representation: 00 Text representation: - /* "strict_asm_evm_version_byzantium/input.yul":0:2 */ + /* "strict_asm_evm_version_byzantium/input.yul":27:34 */ stop diff --git a/test/cmdlineTests/strict_asm_evm_version_constantinople/output b/test/cmdlineTests/strict_asm_evm_version_constantinople/output index c8febd6f1757..9362866b43dc 100644 --- a/test/cmdlineTests/strict_asm_evm_version_constantinople/output +++ b/test/cmdlineTests/strict_asm_evm_version_constantinople/output @@ -11,5 +11,5 @@ Binary representation: 00 Text representation: - /* "strict_asm_evm_version_constantinople/input.yul":0:2 */ + /* "strict_asm_evm_version_constantinople/input.yul":27:34 */ stop diff --git a/test/cmdlineTests/strict_asm_optimizer_steps/output b/test/cmdlineTests/strict_asm_optimizer_steps/output index c10fb02fb9a9..58c91976185c 100644 --- a/test/cmdlineTests/strict_asm_optimizer_steps/output +++ b/test/cmdlineTests/strict_asm_optimizer_steps/output @@ -27,58 +27,58 @@ Binary representation: 608060405234601357600c60185f39600c5ff35b5f80fdfe608060405236155f555f80fd Text representation: - /* "strict_asm_optimizer_steps/input.yul":45:48 */ + /* "strict_asm_optimizer_steps/input.yul":59:62 */ 0x80 - /* "strict_asm_optimizer_steps/input.yul":41:43 */ + /* "strict_asm_optimizer_steps/input.yul":55:57 */ 0x40 - /* "strict_asm_optimizer_steps/input.yul":34:49 */ + /* "strict_asm_optimizer_steps/input.yul":48:63 */ mstore - /* "strict_asm_optimizer_steps/input.yul":61:72 */ + /* "strict_asm_optimizer_steps/input.yul":79:90 */ callvalue - /* "strict_asm_optimizer_steps/input.yul":58:89 */ + /* "strict_asm_optimizer_steps/input.yul":76:107 */ tag_1 jumpi - /* "strict_asm_optimizer_steps/input.yul":138:162 */ + /* "strict_asm_optimizer_steps/input.yul":160:184 */ dataSize(sub_0) - /* "strict_asm_optimizer_steps/input.yul":110:136 */ + /* "strict_asm_optimizer_steps/input.yul":132:158 */ dataOffset(sub_0) - /* "strict_asm_optimizer_steps/input.yul":107:108 */ + /* "strict_asm_optimizer_steps/input.yul":129:130 */ 0x00 - /* "strict_asm_optimizer_steps/input.yul":98:163 */ + /* "strict_asm_optimizer_steps/input.yul":120:185 */ codecopy - /* "strict_asm_optimizer_steps/input.yul":182:206 */ + /* "strict_asm_optimizer_steps/input.yul":208:232 */ dataSize(sub_0) - /* "strict_asm_optimizer_steps/input.yul":179:180 */ + /* "strict_asm_optimizer_steps/input.yul":205:206 */ 0x00 - /* "strict_asm_optimizer_steps/input.yul":172:207 */ + /* "strict_asm_optimizer_steps/input.yul":198:233 */ return - /* "strict_asm_optimizer_steps/input.yul":73:89 */ + /* "strict_asm_optimizer_steps/input.yul":91:107 */ tag_1: - /* "strict_asm_optimizer_steps/input.yul":85:86 */ + /* "strict_asm_optimizer_steps/input.yul":103:104 */ 0x00 - /* "strict_asm_optimizer_steps/input.yul":75:87 */ + /* "strict_asm_optimizer_steps/input.yul":93:105 */ dup1 revert stop sub_0: assembly { - /* "strict_asm_optimizer_steps/input.yul":298:301 */ + /* "strict_asm_optimizer_steps/input.yul":334:337 */ 0x80 - /* "strict_asm_optimizer_steps/input.yul":294:296 */ + /* "strict_asm_optimizer_steps/input.yul":330:332 */ 0x40 - /* "strict_asm_optimizer_steps/input.yul":287:302 */ + /* "strict_asm_optimizer_steps/input.yul":323:338 */ mstore - /* "strict_asm_optimizer_steps/input.yul":533:547 */ + /* "strict_asm_optimizer_steps/input.yul":372:386 */ calldatasize - /* "strict_asm_optimizer_steps/input.yul":526:548 */ + /* "strict_asm_optimizer_steps/input.yul":365:387 */ iszero - /* "strict_asm_optimizer_steps/input.yul":523:524 */ + /* "strict_asm_optimizer_steps/input.yul":362:363 */ 0x00 - /* "strict_asm_optimizer_steps/input.yul":516:549 */ + /* "strict_asm_optimizer_steps/input.yul":355:388 */ sstore - /* "strict_asm_optimizer_steps/input.yul":576:577 */ + /* "strict_asm_optimizer_steps/input.yul":415:416 */ 0x00 - /* "strict_asm_optimizer_steps/input.yul":566:578 */ + /* "strict_asm_optimizer_steps/input.yul":405:417 */ dup1 revert } diff --git a/test/cmdlineTests/strict_asm_output_selection_asm_only/output b/test/cmdlineTests/strict_asm_output_selection_asm_only/output index abe2143d3f89..317c9a9ae2fd 100644 --- a/test/cmdlineTests/strict_asm_output_selection_asm_only/output +++ b/test/cmdlineTests/strict_asm_output_selection_asm_only/output @@ -2,11 +2,11 @@ ======= strict_asm_output_selection_asm_only/input.yul (EVM) ======= Text representation: - /* "strict_asm_output_selection_asm_only/input.yul":15:17 */ + /* "strict_asm_output_selection_asm_only/input.yul":41:43 */ 0x2a - /* "strict_asm_output_selection_asm_only/input.yul":29:30 */ + /* "strict_asm_output_selection_asm_only/input.yul":38:39 */ 0x00 - /* "strict_asm_output_selection_asm_only/input.yul":22:34 */ + /* "strict_asm_output_selection_asm_only/input.yul":31:44 */ sstore - /* "strict_asm_output_selection_asm_only/input.yul":0:36 */ + /* "strict_asm_output_selection_asm_only/input.yul":27:48 */ stop diff --git a/test/cmdlineTests/strict_asm_warning/err b/test/cmdlineTests/strict_asm_warning/err index 1024e870f968..0661ae1ffec2 100644 --- a/test/cmdlineTests/strict_asm_warning/err +++ b/test/cmdlineTests/strict_asm_warning/err @@ -3,9 +3,3 @@ Warning: "selfdestruct" has been deprecated. Note that, starting from the Cancun | 4 | selfdestruct(0) | ^^^^^^^^^^^^ - -Warning: "selfdestruct" has been deprecated. Note that, starting from the Cancun hard fork, the underlying opcode no longer deletes the code and data associated with an account and only transfers its Ether to the beneficiary, unless executed in the same transaction in which the contract was created (see EIP-6780). Any use in newly deployed contracts is strongly discouraged even if the new behavior is taken into account. Future changes to the EVM might further reduce the functionality of the opcode. - --> strict_asm_warning/input.yul:4:5: - | -4 | selfdestruct(0) - | ^^^^^^^^^^^^ diff --git a/test/cmdlineTests/strict_asm_warning_optimize/err b/test/cmdlineTests/strict_asm_warning_optimize/err index 2f3c9bb4a0d0..098aa00baf69 100644 --- a/test/cmdlineTests/strict_asm_warning_optimize/err +++ b/test/cmdlineTests/strict_asm_warning_optimize/err @@ -3,9 +3,3 @@ Warning: "selfdestruct" has been deprecated. Note that, starting from the Cancun | 4 | selfdestruct(0) | ^^^^^^^^^^^^ - -Warning: "selfdestruct" has been deprecated. Note that, starting from the Cancun hard fork, the underlying opcode no longer deletes the code and data associated with an account and only transfers its Ether to the beneficiary, unless executed in the same transaction in which the contract was created (see EIP-6780). Any use in newly deployed contracts is strongly discouraged even if the new behavior is taken into account. Future changes to the EVM might further reduce the functionality of the opcode. - --> strict_asm_warning_optimize/input.yul:4:5: - | -4 | selfdestruct(0) - | ^^^^^^^^^^^^ diff --git a/test/cmdlineTests/yul_function_name_clashes_different_params/output b/test/cmdlineTests/yul_function_name_clashes_different_params/output index 22cee64c1f48..85884a6a0ede 100644 --- a/test/cmdlineTests/yul_function_name_clashes_different_params/output +++ b/test/cmdlineTests/yul_function_name_clashes_different_params/output @@ -23,37 +23,37 @@ Binary representation: 60056011565b600d60706016565b9055005b5f3590565b359056 Text representation: - /* "yul_function_name_clashes_different_params/input.yul":151:154 */ + /* "yul_function_name_clashes_different_params/input.yul":92:95 */ tag_3 tag_1 jump // in tag_3: - /* "yul_function_name_clashes_different_params/input.yul":260:267 */ + /* "yul_function_name_clashes_different_params/input.yul":113:122 */ tag_4 - /* "yul_function_name_clashes_different_params/input.yul":262:266 */ + /* "yul_function_name_clashes_different_params/input.yul":117:121 */ 0x70 - /* "yul_function_name_clashes_different_params/input.yul":260:267 */ + /* "yul_function_name_clashes_different_params/input.yul":113:122 */ tag_2 jump // in tag_4: - /* "yul_function_name_clashes_different_params/input.yul":286:298 */ + /* "yul_function_name_clashes_different_params/input.yul":135:147 */ swap1 sstore - /* "yul_function_name_clashes_different_params/input.yul":27:304 */ + /* "yul_function_name_clashes_different_params/input.yul":27:284 */ stop - /* "yul_function_name_clashes_different_params/input.yul":79:133 */ + /* "yul_function_name_clashes_different_params/input.yul":166:216 */ tag_1: - /* "yul_function_name_clashes_different_params/input.yul":129:130 */ + /* "yul_function_name_clashes_different_params/input.yul":212:213 */ 0x00 - /* "yul_function_name_clashes_different_params/input.yul":116:131 */ + /* "yul_function_name_clashes_different_params/input.yul":199:214 */ calldataload - /* "yul_function_name_clashes_different_params/input.yul":79:133 */ + /* "yul_function_name_clashes_different_params/input.yul":166:216 */ swap1 jump // out - /* "yul_function_name_clashes_different_params/input.yul":187:242 */ + /* "yul_function_name_clashes_different_params/input.yul":225:278 */ tag_2: - /* "yul_function_name_clashes_different_params/input.yul":225:240 */ + /* "yul_function_name_clashes_different_params/input.yul":261:276 */ calldataload - /* "yul_function_name_clashes_different_params/input.yul":187:242 */ + /* "yul_function_name_clashes_different_params/input.yul":225:278 */ swap1 jump // out diff --git a/test/cmdlineTests/yul_optimize_runs/output b/test/cmdlineTests/yul_optimize_runs/output index b7fcabaaca48..589f8ce1a12c 100644 --- a/test/cmdlineTests/yul_optimize_runs/output +++ b/test/cmdlineTests/yul_optimize_runs/output @@ -24,28 +24,28 @@ Binary representation: 602480600a5f395ff3fe7fabc12345000000000000000000000000000000000000000000000000000000005f5500 Text representation: - /* "yul_optimize_runs/input.yul":115:143 */ + /* "yul_optimize_runs/input.yul":64:92 */ dataSize(sub_0) - /* "yul_optimize_runs/input.yul":83:113 */ + /* "yul_optimize_runs/input.yul":117:147 */ dup1 dataOffset(sub_0) - /* "yul_optimize_runs/input.yul":80:81 */ + /* "yul_optimize_runs/input.yul":114:115 */ 0x00 - /* "yul_optimize_runs/input.yul":71:144 */ + /* "yul_optimize_runs/input.yul":105:152 */ codecopy - /* "yul_optimize_runs/input.yul":80:81 */ + /* "yul_optimize_runs/input.yul":172:173 */ 0x00 - /* "yul_optimize_runs/input.yul":153:192 */ + /* "yul_optimize_runs/input.yul":165:178 */ return stop sub_0: assembly { - /* "yul_optimize_runs/input.yul":273:293 */ + /* "yul_optimize_runs/input.yul":282:348 */ 0xabc1234500000000000000000000000000000000000000000000000000000000 - /* "yul_optimize_runs/input.yul":313:314 */ + /* "yul_optimize_runs/input.yul":279:280 */ 0x00 - /* "yul_optimize_runs/input.yul":306:324 */ + /* "yul_optimize_runs/input.yul":272:349 */ sstore - /* "yul_optimize_runs/input.yul":244:334 */ + /* "yul_optimize_runs/input.yul":240:373 */ stop } diff --git a/test/cmdlineTests/yul_verbatim_msize/output b/test/cmdlineTests/yul_verbatim_msize/output index 22259fff71a1..f684bac21752 100644 --- a/test/cmdlineTests/yul_verbatim_msize/output +++ b/test/cmdlineTests/yul_verbatim_msize/output @@ -17,18 +17,19 @@ Binary representation: 6120005150616160025f5500 Text representation: - /* "yul_verbatim_msize/input.yul":125:131 */ + /* "yul_verbatim_msize/input.yul":61:67 */ 0x2000 - /* "yul_verbatim_msize/input.yul":119:132 */ + /* "yul_verbatim_msize/input.yul":55:68 */ mload + /* "yul_verbatim_msize/input.yul":51:69 */ pop - /* "yul_verbatim_msize/input.yul":137:157 */ + /* "yul_verbatim_msize/input.yul":82:102 */ verbatimbytecode_6161 - /* "yul_verbatim_msize/input.yul":172:173 */ + /* "yul_verbatim_msize/input.yul":125:126 */ 0x02 - /* "yul_verbatim_msize/input.yul":169:170 */ + /* "yul_verbatim_msize/input.yul":122:123 */ 0x00 - /* "yul_verbatim_msize/input.yul":162:174 */ + /* "yul_verbatim_msize/input.yul":115:127 */ sstore - /* "yul_verbatim_msize/input.yul":0:176 */ + /* "yul_verbatim_msize/input.yul":27:143 */ stop diff --git a/test/libyul/objectCompiler/data.yul b/test/libyul/objectCompiler/data.yul index caa6499218db..ad8899fb11bd 100644 --- a/test/libyul/objectCompiler/data.yul +++ b/test/libyul/objectCompiler/data.yul @@ -5,10 +5,10 @@ object "a" { } // ---- // Assembly: -// /* "source":20:22 */ +// /* "source":22:29 */ // stop // stop // data_acaf3289d7b601cbd114fb36c4d29c85bbfd5e133f14cb355c3fd8d99367964f 48656c6c6f2c20576f726c6421 // Bytecode: 00fe // Opcodes: STOP INVALID -// SourceMappings: 20:2:0:-:0 +// SourceMappings: 22:7:0:-:0 diff --git a/test/libyul/objectCompiler/datacopy.yul b/test/libyul/objectCompiler/datacopy.yul index 719b109f1db7..9f7fca9adc8d 100644 --- a/test/libyul/objectCompiler/datacopy.yul +++ b/test/libyul/objectCompiler/datacopy.yul @@ -13,40 +13,40 @@ object "a" { } // ---- // Assembly: -// /* "source":57:72 */ +// /* "source":77:92 */ // dataSize(sub_0) -// /* "source":38:55 */ +// /* "source":58:75 */ // dataOffset(sub_0) -// /* "source":35:36 */ +// /* "source":55:56 */ // 0x00 -// /* "source":26:73 */ +// /* "source":46:93 */ // codecopy -// /* "source":88:103 */ +// /* "source":116:131 */ // dataSize(sub_0) -// /* "source":85:86 */ +// /* "source":113:114 */ // 0x00 -// /* "source":78:104 */ +// /* "source":106:132 */ // return // stop // // sub_0: assembly { -// /* "source":153:170 */ +// /* "source":223:240 */ // 0x00 -// /* "source":150:151 */ +// /* "source":220:221 */ // 0x00 -// /* "source":143:171 */ +// /* "source":213:241 */ // sstore -// /* "source":188:205 */ +// /* "source":268:285 */ // 0x0d -// /* "source":185:186 */ +// /* "source":265:266 */ // 0x00 -// /* "source":178:206 */ +// /* "source":258:286 */ // mstore -// /* "source":135:212 */ +// /* "source":181:310 */ // stop // stop // data_acaf3289d7b601cbd114fb36c4d29c85bbfd5e133f14cb355c3fd8d99367964f 48656c6c6f2c20576f726c6421 // } // Bytecode: 6009600b5f3960095ff3fe5f5f55600d5f5200fe // Opcodes: PUSH1 0x9 PUSH1 0xB PUSH0 CODECOPY PUSH1 0x9 PUSH0 RETURN INVALID PUSH0 PUSH0 SSTORE PUSH1 0xD PUSH0 MSTORE STOP INVALID -// SourceMappings: 57:15:0:-:0;38:17;35:1;26:47;88:15;85:1;78:26 +// SourceMappings: 77:15:0:-:0;58:17;55:1;46:47;116:15;113:1;106:26 diff --git a/test/libyul/objectCompiler/dataoffset_code.yul b/test/libyul/objectCompiler/dataoffset_code.yul index 58521c87f9be..8ca10add2f26 100644 --- a/test/libyul/objectCompiler/dataoffset_code.yul +++ b/test/libyul/objectCompiler/dataoffset_code.yul @@ -7,28 +7,28 @@ object "a" { } // ---- // Assembly: -// /* "source":32:49 */ +// /* "source":44:61 */ // dataOffset(sub_0) -// /* "source":29:30 */ +// /* "source":41:42 */ // 0x00 -// /* "source":22:50 */ +// /* "source":34:62 */ // sstore -// /* "source":20:52 */ +// /* "source":22:70 */ // stop // stop // // sub_0: assembly { -// /* "source":91:92 */ +// /* "source":117:118 */ // 0x08 -// /* "source":88:89 */ +// /* "source":114:115 */ // 0x00 -// /* "source":81:93 */ +// /* "source":107:119 */ // sstore -// /* "source":79:95 */ +// /* "source":103:123 */ // stop // stop // data_acaf3289d7b601cbd114fb36c4d29c85bbfd5e133f14cb355c3fd8d99367964f 48656c6c6f2c20576f726c6421 // } // Bytecode: 60065f5500fe60085f5500fe // Opcodes: PUSH1 0x6 PUSH0 SSTORE STOP INVALID PUSH1 0x8 PUSH0 SSTORE STOP INVALID -// SourceMappings: 32:17:0:-:0;29:1;22:28;20:32 +// SourceMappings: 44:17:0:-:0;41:1;34:28;22:48 diff --git a/test/libyul/objectCompiler/dataoffset_data.yul b/test/libyul/objectCompiler/dataoffset_data.yul index 61f0c4418957..915567489816 100644 --- a/test/libyul/objectCompiler/dataoffset_data.yul +++ b/test/libyul/objectCompiler/dataoffset_data.yul @@ -4,16 +4,16 @@ object "a" { } // ---- // Assembly: -// /* "source":32:51 */ +// /* "source":56:75 */ // data_acaf3289d7b601cbd114fb36c4d29c85bbfd5e133f14cb355c3fd8d99367964f -// /* "source":29:30 */ +// /* "source":53:54 */ // 0x00 -// /* "source":22:52 */ +// /* "source":46:76 */ // sstore -// /* "source":20:54 */ +// /* "source":22:92 */ // stop // stop // data_acaf3289d7b601cbd114fb36c4d29c85bbfd5e133f14cb355c3fd8d99367964f 48656c6c6f2c20576f726c6421 // Bytecode: 60065f5500fe48656c6c6f2c20576f726c6421 // Opcodes: PUSH1 0x6 PUSH0 SSTORE STOP INVALID BASEFEE PUSH6 0x6C6C6F2C2057 PUSH16 0x726C6421000000000000000000000000 -// SourceMappings: 32:19:0:-:0;29:1;22:30;20:34 +// SourceMappings: 56:19:0:-:0;53:1;46:30;22:70 diff --git a/test/libyul/objectCompiler/dataoffset_self.yul b/test/libyul/objectCompiler/dataoffset_self.yul index ae123ba49a0b..681c24c0eecb 100644 --- a/test/libyul/objectCompiler/dataoffset_self.yul +++ b/test/libyul/objectCompiler/dataoffset_self.yul @@ -4,16 +4,16 @@ object "a" { } // ---- // Assembly: -// /* "source":32:47 */ +// /* "source":44:59 */ // 0x00 -// /* "source":29:30 */ +// /* "source":41:42 */ // 0x00 -// /* "source":22:48 */ +// /* "source":34:60 */ // sstore -// /* "source":20:50 */ +// /* "source":22:68 */ // stop // stop // data_acaf3289d7b601cbd114fb36c4d29c85bbfd5e133f14cb355c3fd8d99367964f 48656c6c6f2c20576f726c6421 // Bytecode: 5f5f5500fe // Opcodes: PUSH0 PUSH0 SSTORE STOP INVALID -// SourceMappings: 32:15:0:-:0;29:1;22:26;20:30 +// SourceMappings: 44:15:0:-:0;41:1;34:26;22:46 diff --git a/test/libyul/objectCompiler/datasize_code.yul b/test/libyul/objectCompiler/datasize_code.yul index 4e559ab895c6..cab7987ea9cc 100644 --- a/test/libyul/objectCompiler/datasize_code.yul +++ b/test/libyul/objectCompiler/datasize_code.yul @@ -7,28 +7,28 @@ object "a" { } // ---- // Assembly: -// /* "source":32:47 */ +// /* "source":44:59 */ // dataSize(sub_0) -// /* "source":29:30 */ +// /* "source":41:42 */ // 0x00 -// /* "source":22:48 */ +// /* "source":34:60 */ // sstore -// /* "source":20:50 */ +// /* "source":22:68 */ // stop // stop // // sub_0: assembly { -// /* "source":89:90 */ +// /* "source":115:116 */ // 0x08 -// /* "source":86:87 */ +// /* "source":112:113 */ // 0x00 -// /* "source":79:91 */ +// /* "source":105:117 */ // sstore -// /* "source":77:93 */ +// /* "source":101:121 */ // stop // stop // data_acaf3289d7b601cbd114fb36c4d29c85bbfd5e133f14cb355c3fd8d99367964f 48656c6c6f2c20576f726c6421 // } // Bytecode: 60065f5500fe // Opcodes: PUSH1 0x6 PUSH0 SSTORE STOP INVALID -// SourceMappings: 32:15:0:-:0;29:1;22:26;20:30 +// SourceMappings: 44:15:0:-:0;41:1;34:26;22:46 diff --git a/test/libyul/objectCompiler/datasize_data.yul b/test/libyul/objectCompiler/datasize_data.yul index 3281bd9ba7c3..d1261d2464a4 100644 --- a/test/libyul/objectCompiler/datasize_data.yul +++ b/test/libyul/objectCompiler/datasize_data.yul @@ -4,16 +4,16 @@ object "a" { } // ---- // Assembly: -// /* "source":32:49 */ +// /* "source":44:61 */ // 0x0d -// /* "source":29:30 */ +// /* "source":41:42 */ // 0x00 -// /* "source":22:50 */ +// /* "source":34:62 */ // sstore -// /* "source":20:52 */ +// /* "source":22:70 */ // stop // stop // data_acaf3289d7b601cbd114fb36c4d29c85bbfd5e133f14cb355c3fd8d99367964f 48656c6c6f2c20576f726c6421 // Bytecode: 600d5f5500fe // Opcodes: PUSH1 0xD PUSH0 SSTORE STOP INVALID -// SourceMappings: 32:17:0:-:0;29:1;22:28;20:32 +// SourceMappings: 44:17:0:-:0;41:1;34:28;22:48 diff --git a/test/libyul/objectCompiler/datasize_self.yul b/test/libyul/objectCompiler/datasize_self.yul index 6bc520af58e7..2a19d0a88f69 100644 --- a/test/libyul/objectCompiler/datasize_self.yul +++ b/test/libyul/objectCompiler/datasize_self.yul @@ -4,16 +4,16 @@ object "a" { } // ---- // Assembly: -// /* "source":32:45 */ +// /* "source":36:49 */ // bytecodeSize -// /* "source":29:30 */ +// /* "source":33:34 */ // 0x00 -// /* "source":22:46 */ +// /* "source":26:50 */ // sstore -// /* "source":20:48 */ +// /* "source":22:54 */ // stop // stop // data_acaf3289d7b601cbd114fb36c4d29c85bbfd5e133f14cb355c3fd8d99367964f 48656c6c6f2c20576f726c6421 // Bytecode: 60065f5500fe // Opcodes: PUSH1 0x6 PUSH0 SSTORE STOP INVALID -// SourceMappings: 32:13:0:-:0;29:1;22:24;20:28 +// SourceMappings: 36:13:0:-:0;33:1;26:24;22:32 diff --git a/test/libyul/objectCompiler/immutable_long_name_does_not_end_up_in_bytecode.yul b/test/libyul/objectCompiler/immutable_long_name_does_not_end_up_in_bytecode.yul index 285a8a8d548d..c6fd0ac80527 100644 --- a/test/libyul/objectCompiler/immutable_long_name_does_not_end_up_in_bytecode.yul +++ b/test/libyul/objectCompiler/immutable_long_name_does_not_end_up_in_bytecode.yul @@ -9,14 +9,14 @@ object "a" { } // ---- // Assembly: -// /* "source":167:209 */ +// /* "source":143:185 */ // 0x1234567890123456789012345678901234567890 -// /* "source":58:59 */ +// /* "source":59:60 */ // 0x00 -// /* "source":32:219 */ +// /* "source":46:186 */ // assignImmutable("0x85a5b1db611c82c46f5fa18e39ae218397536256c451e5de155a86de843a9ad6") -// /* "source":22:225 */ +// /* "source":22:202 */ // stop // Bytecode: 7312345678901234567890123456789012345678905f505000 // Opcodes: PUSH20 0x1234567890123456789012345678901234567890 PUSH0 POP POP STOP -// SourceMappings: 167:42:0:-:0;58:1;32:187;;22:203 +// SourceMappings: 143:42:0:-:0;59:1;46:140;;22:180 diff --git a/test/libyul/objectCompiler/leading_and_trailing_dots.yul b/test/libyul/objectCompiler/leading_and_trailing_dots.yul index ea6a8fcd8bd8..13c95235571e 100644 --- a/test/libyul/objectCompiler/leading_and_trailing_dots.yul +++ b/test/libyul/objectCompiler/leading_and_trailing_dots.yul @@ -14,29 +14,29 @@ } // ---- // Assembly: -// /* "source":49:50 */ +// /* "source":53:54 */ // 0x02 -// /* "source":6:42 */ +// /* "source":108:140 */ // tag_1: -// /* "source":34:35 */ +// /* "source":136:137 */ // 0x00 -// /* "source":32:36 */ +// /* "source":134:138 */ // tag_1 // jump // in -// /* "source":56:92 */ +// /* "source":149:181 */ // tag_2: -// /* "source":84:85 */ +// /* "source":177:178 */ // 0x00 -// /* "source":82:86 */ +// /* "source":175:179 */ // tag_2 // jump // in -// /* "source":106:142 */ +// /* "source":190:222 */ // tag_3: -// /* "source":134:135 */ +// /* "source":218:219 */ // 0x00 -// /* "source":132:136 */ +// /* "source":216:220 */ // tag_3 // jump // in // Bytecode: 60025b5f6002565b5f6007565b5f600c56 // Opcodes: PUSH1 0x2 JUMPDEST PUSH0 PUSH1 0x2 JUMP JUMPDEST PUSH0 PUSH1 0x7 JUMP JUMPDEST PUSH0 PUSH1 0xC JUMP -// SourceMappings: 49:1:0:-:0;6:36;34:1;32:4;:::i;56:36::-;84:1;82:4;:::i;106:36::-;134:1;132:4;:::i +// SourceMappings: 53:1:0:-:0;108:32;136:1;134:4;:::i;149:32::-;177:1;175:4;:::i;190:32::-;218:1;216:4;:::i diff --git a/test/libyul/objectCompiler/linkersymbol.yul b/test/libyul/objectCompiler/linkersymbol.yul index c4da288e618f..91a456461f00 100644 --- a/test/libyul/objectCompiler/linkersymbol.yul +++ b/test/libyul/objectCompiler/linkersymbol.yul @@ -7,31 +7,31 @@ object "a" { } // ---- // Assembly: -// /* "source":179:180 */ +// /* "source":190:191 */ // 0x00 -// /* "source":174:177 */ +// /* "source":185:188 */ // 0x80 -// /* "source":171:172 */ +// /* "source":182:183 */ // 0x04 -// /* "source":44:79 */ +// /* "source":58:93 */ // dup2 // dup4 // linkerSymbol("f919ba91ac99f96129544b80b9516b27a80e376b9dc693819d0b18b7e0395612") -// /* "source":109:119 */ +// /* "source":127:137 */ // 0x18530aaf -// /* "source":104:107 */ +// /* "source":122:125 */ // 0xe3 -// /* "source":100:120 */ +// /* "source":118:138 */ // shl -// /* "source":88:121 */ +// /* "source":106:139 */ // dup4 // mstore -// /* "source":150:155 */ +// /* "source":161:166 */ // gas -// /* "source":145:181 */ +// /* "source":156:192 */ // call -// /* "source":130:181 */ +// /* "source":152:193 */ // stop // Bytecode: 5f6080600481837300000000000000000000000000000000000000006318530aaf60e31b83525af100 // Opcodes: PUSH0 PUSH1 0x80 PUSH1 0x4 DUP2 DUP4 PUSH20 0x0 PUSH4 0x18530AAF PUSH1 0xE3 SHL DUP4 MSTORE GAS CALL STOP -// SourceMappings: 179:1:0:-:0;174:3;171:1;44:35;;;109:10;104:3;100:20;88:33;;150:5;145:36;130:51 +// SourceMappings: 190:1:0:-:0;185:3;182:1;58:35;;;127:10;122:3;118:20;106:33;;161:5;156:36;152:41 diff --git a/test/libyul/objectCompiler/long_object_name.yul b/test/libyul/objectCompiler/long_object_name.yul index aa2dd1ac2eee..f75260224005 100644 --- a/test/libyul/objectCompiler/long_object_name.yul +++ b/test/libyul/objectCompiler/long_object_name.yul @@ -10,20 +10,20 @@ object "t" { // optimizationPreset: full // ---- // Assembly: -// /* "source":33:146 */ +// /* "source":56:169 */ // dataSize(sub_0) -// /* "source":30:31 */ +// /* "source":53:54 */ // 0x00 -// /* "source":23:147 */ +// /* "source":46:170 */ // sstore -// /* "source":19:150 */ +// /* "source":22:186 */ // stop // stop // // sub_0: assembly { -// /* "source":272:274 */ +// /* "source":317:324 */ // stop // } // Bytecode: 60015f5500fe // Opcodes: PUSH1 0x1 PUSH0 SSTORE STOP INVALID -// SourceMappings: 33:113:0:-:0;30:1;23:124;19:131 +// SourceMappings: 56:113:0:-:0;53:1;46:124;22:164 diff --git a/test/libyul/objectCompiler/manySubObjects.yul b/test/libyul/objectCompiler/manySubObjects.yul index 2f4b1638765f..c046b182ff21 100644 --- a/test/libyul/objectCompiler/manySubObjects.yul +++ b/test/libyul/objectCompiler/manySubObjects.yul @@ -136,340 +136,340 @@ object "root" { } // ---- // Assembly: -// /* "source":45:61 */ +// /* "source":59:75 */ // bytecodeSize -// /* "source":42:43 */ +// /* "source":56:57 */ // 0x00 -// /* "source":35:62 */ +// /* "source":49:76 */ // sstore -// /* "source":81:94 */ +// /* "source":99:112 */ // dataSize(sub_0) -// /* "source":78:79 */ +// /* "source":96:97 */ // 0x01 -// /* "source":71:95 */ +// /* "source":89:113 */ // sstore -// /* "source":114:127 */ +// /* "source":136:149 */ // dataSize(sub_1) -// /* "source":111:112 */ +// /* "source":133:134 */ // 0x02 -// /* "source":104:128 */ +// /* "source":126:150 */ // sstore -// /* "source":147:160 */ +// /* "source":173:186 */ // dataSize(sub_2) -// /* "source":144:145 */ +// /* "source":170:171 */ // 0x03 -// /* "source":137:161 */ +// /* "source":163:187 */ // sstore -// /* "source":180:193 */ +// /* "source":210:223 */ // dataSize(sub_3) -// /* "source":177:178 */ +// /* "source":207:208 */ // 0x04 -// /* "source":170:194 */ +// /* "source":200:224 */ // sstore -// /* "source":213:226 */ +// /* "source":247:260 */ // dataSize(sub_4) -// /* "source":210:211 */ +// /* "source":244:245 */ // 0x05 -// /* "source":203:227 */ +// /* "source":237:261 */ // sstore -// /* "source":246:259 */ +// /* "source":284:297 */ // dataSize(sub_5) -// /* "source":243:244 */ +// /* "source":281:282 */ // 0x06 -// /* "source":236:260 */ +// /* "source":274:298 */ // sstore -// /* "source":279:292 */ +// /* "source":321:334 */ // dataSize(sub_6) -// /* "source":276:277 */ +// /* "source":318:319 */ // 0x07 -// /* "source":269:293 */ +// /* "source":311:335 */ // sstore -// /* "source":312:325 */ +// /* "source":358:371 */ // dataSize(sub_7) -// /* "source":309:310 */ +// /* "source":355:356 */ // 0x08 -// /* "source":302:326 */ +// /* "source":348:372 */ // sstore -// /* "source":345:358 */ +// /* "source":395:408 */ // dataSize(sub_8) -// /* "source":342:343 */ +// /* "source":392:393 */ // 0x09 -// /* "source":335:359 */ +// /* "source":385:409 */ // sstore -// /* "source":379:392 */ +// /* "source":433:446 */ // dataSize(sub_9) -// /* "source":375:377 */ +// /* "source":429:431 */ // 0x0a -// /* "source":368:393 */ +// /* "source":422:447 */ // sstore -// /* "source":413:426 */ +// /* "source":471:484 */ // dataSize(sub_10) -// /* "source":409:411 */ +// /* "source":467:469 */ // 0x0b -// /* "source":402:427 */ +// /* "source":460:485 */ // sstore -// /* "source":447:460 */ +// /* "source":509:522 */ // dataSize(sub_11) -// /* "source":443:445 */ +// /* "source":505:507 */ // 0x0c -// /* "source":436:461 */ +// /* "source":498:523 */ // sstore -// /* "source":481:494 */ +// /* "source":547:560 */ // dataSize(sub_12) -// /* "source":477:479 */ +// /* "source":543:545 */ // 0x0d -// /* "source":470:495 */ +// /* "source":536:561 */ // sstore -// /* "source":515:528 */ +// /* "source":585:598 */ // dataSize(sub_13) -// /* "source":511:513 */ +// /* "source":581:583 */ // 0x0e -// /* "source":504:529 */ +// /* "source":574:599 */ // sstore -// /* "source":549:562 */ +// /* "source":623:636 */ // dataSize(sub_14) -// /* "source":545:547 */ +// /* "source":619:621 */ // 0x0f -// /* "source":538:563 */ +// /* "source":612:637 */ // sstore -// /* "source":583:596 */ +// /* "source":661:674 */ // dataSize(sub_15) -// /* "source":579:581 */ +// /* "source":657:659 */ // 0x10 -// /* "source":572:597 */ +// /* "source":650:675 */ // sstore -// /* "source":617:631 */ +// /* "source":699:713 */ // dataSize(sub_16) -// /* "source":613:615 */ +// /* "source":695:697 */ // 0x11 -// /* "source":606:632 */ +// /* "source":688:714 */ // sstore -// /* "source":25:638 */ +// /* "source":25:730 */ // stop // stop // // sub_0: assembly { -// /* "source":696:697 */ +// /* "source":805:806 */ // 0x00 -// /* "source":691:694 */ +// /* "source":800:803 */ // 0x64 -// /* "source":684:698 */ +// /* "source":793:807 */ // sstore -// /* "source":723:739 */ +// /* "source":836:852 */ // dataSize(sub_0) -// /* "source":718:721 */ +// /* "source":831:834 */ // 0xc8 -// /* "source":711:740 */ +// /* "source":824:853 */ // sstore -// /* "source":670:750 */ +// /* "source":761:877 */ // stop // stop // // sub_0: assembly { -// /* "source":822:823 */ +// /* "source":935:936 */ // 0x00 -// /* "source":817:820 */ +// /* "source":930:933 */ // 0x012c -// /* "source":810:824 */ +// /* "source":923:937 */ // sstore -// /* "source":792:838 */ +// /* "source":919:941 */ // stop // } // } // // sub_1: assembly { -// /* "source":912:913 */ +// /* "source":1004:1005 */ // 0x01 -// /* "source":907:910 */ +// /* "source":999:1002 */ // 0x64 -// /* "source":900:914 */ +// /* "source":992:1006 */ // sstore -// /* "source":886:924 */ +// /* "source":988:1010 */ // stop // } // // sub_2: assembly { -// /* "source":988:989 */ +// /* "source":1063:1064 */ // 0x02 -// /* "source":983:986 */ +// /* "source":1058:1061 */ // 0x65 -// /* "source":976:990 */ +// /* "source":1051:1065 */ // sstore -// /* "source":962:1000 */ +// /* "source":1047:1069 */ // stop // } // // sub_3: assembly { -// /* "source":1064:1065 */ +// /* "source":1122:1123 */ // 0x03 -// /* "source":1059:1062 */ +// /* "source":1117:1120 */ // 0x66 -// /* "source":1052:1066 */ +// /* "source":1110:1124 */ // sstore -// /* "source":1038:1076 */ +// /* "source":1106:1128 */ // stop // } // // sub_4: assembly { -// /* "source":1140:1141 */ +// /* "source":1181:1182 */ // 0x04 -// /* "source":1135:1138 */ +// /* "source":1176:1179 */ // 0x67 -// /* "source":1128:1142 */ +// /* "source":1169:1183 */ // sstore -// /* "source":1114:1152 */ +// /* "source":1165:1187 */ // stop // } // // sub_5: assembly { -// /* "source":1216:1217 */ +// /* "source":1240:1241 */ // 0x05 -// /* "source":1211:1214 */ +// /* "source":1235:1238 */ // 0x68 -// /* "source":1204:1218 */ +// /* "source":1228:1242 */ // sstore -// /* "source":1190:1228 */ +// /* "source":1224:1246 */ // stop // } // // sub_6: assembly { -// /* "source":1292:1293 */ +// /* "source":1299:1300 */ // 0x06 -// /* "source":1287:1290 */ +// /* "source":1294:1297 */ // 0x69 -// /* "source":1280:1294 */ +// /* "source":1287:1301 */ // sstore -// /* "source":1266:1304 */ +// /* "source":1283:1305 */ // stop // } // // sub_7: assembly { -// /* "source":1368:1369 */ +// /* "source":1358:1359 */ // 0x07 -// /* "source":1363:1366 */ +// /* "source":1353:1356 */ // 0x6a -// /* "source":1356:1370 */ +// /* "source":1346:1360 */ // sstore -// /* "source":1342:1380 */ +// /* "source":1342:1364 */ // stop // } // // sub_8: assembly { -// /* "source":1444:1445 */ +// /* "source":1417:1418 */ // 0x08 -// /* "source":1439:1442 */ +// /* "source":1412:1415 */ // 0x6b -// /* "source":1432:1446 */ +// /* "source":1405:1419 */ // sstore -// /* "source":1418:1456 */ +// /* "source":1401:1423 */ // stop // } // // sub_9: assembly { -// /* "source":1520:1521 */ +// /* "source":1476:1477 */ // 0x09 -// /* "source":1515:1518 */ +// /* "source":1471:1474 */ // 0x6c -// /* "source":1508:1522 */ +// /* "source":1464:1478 */ // sstore -// /* "source":1494:1532 */ +// /* "source":1460:1482 */ // stop // } // // sub_10: assembly { -// /* "source":1596:1598 */ +// /* "source":1535:1537 */ // 0x0a -// /* "source":1591:1594 */ +// /* "source":1530:1533 */ // 0x6d -// /* "source":1584:1599 */ +// /* "source":1523:1538 */ // sstore -// /* "source":1570:1609 */ +// /* "source":1519:1542 */ // stop // } // // sub_11: assembly { -// /* "source":1673:1675 */ +// /* "source":1595:1597 */ // 0x0b -// /* "source":1668:1671 */ +// /* "source":1590:1593 */ // 0x6e -// /* "source":1661:1676 */ +// /* "source":1583:1598 */ // sstore -// /* "source":1647:1686 */ +// /* "source":1579:1602 */ // stop // } // // sub_12: assembly { -// /* "source":1750:1752 */ +// /* "source":1655:1657 */ // 0x0c -// /* "source":1745:1748 */ +// /* "source":1650:1653 */ // 0x6f -// /* "source":1738:1753 */ +// /* "source":1643:1658 */ // sstore -// /* "source":1724:1763 */ +// /* "source":1639:1662 */ // stop // } // // sub_13: assembly { -// /* "source":1827:1829 */ +// /* "source":1715:1717 */ // 0x0d -// /* "source":1822:1825 */ +// /* "source":1710:1713 */ // 0x70 -// /* "source":1815:1830 */ +// /* "source":1703:1718 */ // sstore -// /* "source":1801:1840 */ +// /* "source":1699:1722 */ // stop // } // // sub_14: assembly { -// /* "source":1904:1906 */ +// /* "source":1775:1777 */ // 0x0e -// /* "source":1899:1902 */ +// /* "source":1770:1773 */ // 0x71 -// /* "source":1892:1907 */ +// /* "source":1763:1778 */ // sstore -// /* "source":1878:1917 */ +// /* "source":1759:1782 */ // stop // } // // sub_15: assembly { -// /* "source":1981:1983 */ +// /* "source":1835:1837 */ // 0x0f -// /* "source":1976:1979 */ +// /* "source":1830:1833 */ // 0x72 -// /* "source":1969:1984 */ +// /* "source":1823:1838 */ // sstore -// /* "source":1955:1994 */ +// /* "source":1819:1842 */ // stop // } // // sub_16: assembly { -// /* "source":2059:2061 */ +// /* "source":1924:1926 */ // 0x10 -// /* "source":2054:2057 */ +// /* "source":1919:1922 */ // 0x73 -// /* "source":2047:2062 */ +// /* "source":1912:1927 */ // sstore -// /* "source":2087:2104 */ +// /* "source":1956:1973 */ // dataSize(sub_0) -// /* "source":2082:2085 */ +// /* "source":1951:1954 */ // 0xc9 -// /* "source":2075:2105 */ +// /* "source":1944:1974 */ // sstore -// /* "source":2033:2115 */ +// /* "source":1880:1998 */ // stop // stop // // sub_0: assembly { -// /* "source":2188:2190 */ +// /* "source":2057:2059 */ // 0x10 -// /* "source":2183:2186 */ +// /* "source":2052:2055 */ // 0x012c -// /* "source":2176:2191 */ +// /* "source":2045:2060 */ // sstore -// /* "source":2158:2205 */ +// /* "source":2041:2064 */ // stop // } // } // Bytecode: 61005c5f55600b600155600660025560066003556006600455600660055560066006556006600755600660085560066009556006600a556006600b556006600c556006600d556006600e556006600f556006601055600c60115500fe // Opcodes: PUSH2 0x5C PUSH0 SSTORE PUSH1 0xB PUSH1 0x1 SSTORE PUSH1 0x6 PUSH1 0x2 SSTORE PUSH1 0x6 PUSH1 0x3 SSTORE PUSH1 0x6 PUSH1 0x4 SSTORE PUSH1 0x6 PUSH1 0x5 SSTORE PUSH1 0x6 PUSH1 0x6 SSTORE PUSH1 0x6 PUSH1 0x7 SSTORE PUSH1 0x6 PUSH1 0x8 SSTORE PUSH1 0x6 PUSH1 0x9 SSTORE PUSH1 0x6 PUSH1 0xA SSTORE PUSH1 0x6 PUSH1 0xB SSTORE PUSH1 0x6 PUSH1 0xC SSTORE PUSH1 0x6 PUSH1 0xD SSTORE PUSH1 0x6 PUSH1 0xE SSTORE PUSH1 0x6 PUSH1 0xF SSTORE PUSH1 0x6 PUSH1 0x10 SSTORE PUSH1 0xC PUSH1 0x11 SSTORE STOP INVALID -// SourceMappings: 45:16:0:-:0;42:1;35:27;81:13;78:1;71:24;114:13;111:1;104:24;147:13;144:1;137:24;180:13;177:1;170:24;213:13;210:1;203:24;246:13;243:1;236:24;279:13;276:1;269:24;312:13;309:1;302:24;345:13;342:1;335:24;379:13;375:2;368:25;413:13;409:2;402:25;447:13;443:2;436:25;481:13;477:2;470:25;515:13;511:2;504:25;549:13;545:2;538:25;583:13;579:2;572:25;617:14;613:2;606:26;25:613 +// SourceMappings: 59:16:0:-:0;56:1;49:27;99:13;96:1;89:24;136:13;133:1;126:24;173:13;170:1;163:24;210:13;207:1;200:24;247:13;244:1;237:24;284:13;281:1;274:24;321:13;318:1;311:24;358:13;355:1;348:24;395:13;392:1;385:24;433:13;429:2;422:25;471:13;467:2;460:25;509:13;505:2;498:25;547:13;543:2;536:25;585:13;581:2;574:25;623:13;619:2;612:25;661:13;657:2;650:25;699:14;695:2;688:26;25:705 diff --git a/test/libyul/objectCompiler/metadata.yul b/test/libyul/objectCompiler/metadata.yul index 335522d04d2b..4f8cda7a4c49 100644 --- a/test/libyul/objectCompiler/metadata.yul +++ b/test/libyul/objectCompiler/metadata.yul @@ -21,34 +21,34 @@ object "A" { } // ---- // Assembly: -// /* "source":35:48 */ +// /* "source":55:68 */ // 0x0e -// /* "source":62:75 */ +// /* "source":90:103 */ // 0x03 -// /* "source":80:92 */ +// /* "source":116:128 */ // swap1 -// /* "source":87:88 */ +// /* "source":123:124 */ // 0x00 -// /* "source":80:92 */ +// /* "source":116:128 */ // sstore -// /* "source":104:106 */ +// /* "source":148:150 */ // 0x20 -// /* "source":97:110 */ +// /* "source":141:154 */ // sstore -// /* "source":20:114 */ +// /* "source":22:170 */ // stop // stop // data_211450822d7f8c345093893187e7e1fbebc4ec67af72601920194be14104e336 48656c6c6f2c20576f726c643221 // data_e1629b9dda060bb30c7908346f6af189c16773fa148d3366701fbaa35d54f3c8 414243 // // sub_0: assembly { -// /* "source":157:176 */ +// /* "source":242:261 */ // data_211450822d7f8c345093893187e7e1fbebc4ec67af72601920194be14104e336 -// /* "source":190:191 */ +// /* "source":285:286 */ // 0x00 -// /* "source":183:195 */ +// /* "source":278:290 */ // sstore -// /* "source":140:201 */ +// /* "source":201:314 */ // stop // stop // data_211450822d7f8c345093893187e7e1fbebc4ec67af72601920194be14104e336 48656c6c6f2c20576f726c643221 @@ -59,4 +59,4 @@ object "A" { // auxdata: 0x4d32 // Bytecode: 600e6003905f5560205500fe4d32 // Opcodes: PUSH1 0xE PUSH1 0x3 SWAP1 PUSH0 SSTORE PUSH1 0x20 SSTORE STOP INVALID 0x4D ORIGIN -// SourceMappings: 35:13:0:-:0;62;80:12;87:1;80:12;104:2;97:13;20:94 +// SourceMappings: 55:13:0:-:0;90;116:12;123:1;116:12;148:2;141:13;22:148 diff --git a/test/libyul/objectCompiler/namedObject.yul b/test/libyul/objectCompiler/namedObject.yul index d55c3ca25335..06539dd89373 100644 --- a/test/libyul/objectCompiler/namedObject.yul +++ b/test/libyul/objectCompiler/namedObject.yul @@ -3,8 +3,8 @@ object "a" { } // ---- // Assembly: -// /* "source":20:22 */ +// /* "source":22:29 */ // stop // Bytecode: 00 // Opcodes: STOP -// SourceMappings: 20:2:0:-:0 +// SourceMappings: 22:7:0:-:0 diff --git a/test/libyul/objectCompiler/namedObjectCode.yul b/test/libyul/objectCompiler/namedObjectCode.yul index 5936aa744337..f18535d71189 100644 --- a/test/libyul/objectCompiler/namedObjectCode.yul +++ b/test/libyul/objectCompiler/namedObjectCode.yul @@ -3,14 +3,14 @@ object "a" { } // ---- // Assembly: -// /* "source":32:33 */ +// /* "source":36:37 */ // 0x01 -// /* "source":29:30 */ +// /* "source":33:34 */ // 0x00 -// /* "source":22:34 */ +// /* "source":26:38 */ // sstore -// /* "source":20:36 */ +// /* "source":22:42 */ // stop // Bytecode: 60015f5500 // Opcodes: PUSH1 0x1 PUSH0 SSTORE STOP -// SourceMappings: 32:1:0:-:0;29;22:12;20:16 +// SourceMappings: 36:1:0:-:0;33;26:12;22:20 diff --git a/test/libyul/objectCompiler/nested_optimizer.yul b/test/libyul/objectCompiler/nested_optimizer.yul index cde1210ff885..ae06509429a5 100644 --- a/test/libyul/objectCompiler/nested_optimizer.yul +++ b/test/libyul/objectCompiler/nested_optimizer.yul @@ -18,28 +18,28 @@ object "a" { // optimizationPreset: full // ---- // Assembly: -// /* "source":48:49 */ +// /* "source":58:59 */ // 0x00 -// /* "source":35:50 */ +// /* "source":41:56 */ // dup1 // calldataload -// /* "source":107:127 */ +// /* "source":34:60 */ // sstore -// /* "source":20:131 */ +// /* "source":22:68 */ // stop // stop // // sub_0: assembly { -// /* "source":188:189 */ +// /* "source":141:142 */ // 0x00 -// /* "source":175:190 */ +// /* "source":124:139 */ // dup1 // calldataload -// /* "source":253:273 */ +// /* "source":117:143 */ // sstore -// /* "source":158:279 */ +// /* "source":101:155 */ // stop // } // Bytecode: 5f80355500fe // Opcodes: PUSH0 DUP1 CALLDATALOAD SSTORE STOP INVALID -// SourceMappings: 48:1:0:-:0;35:15;;107:20;20:111 +// SourceMappings: 58:1:0:-:0;41:15;;34:26;22:46 diff --git a/test/libyul/objectCompiler/simple.yul b/test/libyul/objectCompiler/simple.yul index b84c49a5a43d..fb2339cebb09 100644 --- a/test/libyul/objectCompiler/simple.yul +++ b/test/libyul/objectCompiler/simple.yul @@ -3,14 +3,14 @@ } // ---- // Assembly: -// /* "source":14:15 */ +// /* "source":41:42 */ // 0x01 -// /* "source":11:12 */ +// /* "source":38:39 */ // 0x00 -// /* "source":4:16 */ +// /* "source":31:43 */ // sstore -// /* "source":0:18 */ +// /* "source":27:47 */ // stop // Bytecode: 60015f5500 // Opcodes: PUSH1 0x1 PUSH0 SSTORE STOP -// SourceMappings: 14:1:0:-:0;11;4:12;0:18 +// SourceMappings: 41:1:0:-:0;38;31:12;27:20 diff --git a/test/libyul/objectCompiler/simple_optimizer.yul b/test/libyul/objectCompiler/simple_optimizer.yul index 3ce4b7a4bb41..cc630758957a 100644 --- a/test/libyul/objectCompiler/simple_optimizer.yul +++ b/test/libyul/objectCompiler/simple_optimizer.yul @@ -8,15 +8,15 @@ // optimizationPreset: full // ---- // Assembly: -// /* "source":26:27 */ +// /* "source":63:64 */ // 0x00 -// /* "source":13:28 */ +// /* "source":46:61 */ // dup1 // calldataload -// /* "source":79:99 */ +// /* "source":39:65 */ // sstore -// /* "source":0:101 */ +// /* "source":27:73 */ // stop // Bytecode: 5f80355500 // Opcodes: PUSH0 DUP1 CALLDATALOAD SSTORE STOP -// SourceMappings: 26:1:0:-:0;13:15;;79:20;0:101 +// SourceMappings: 63:1:0:-:0;46:15;;39:26;27:46 diff --git a/test/libyul/objectCompiler/smoke.yul b/test/libyul/objectCompiler/smoke.yul index 3f1079aa7090..82aea42f5299 100644 --- a/test/libyul/objectCompiler/smoke.yul +++ b/test/libyul/objectCompiler/smoke.yul @@ -2,8 +2,8 @@ } // ---- // Assembly: -// /* "source":0:3 */ +// /* "source":27:34 */ // stop // Bytecode: 00 // Opcodes: STOP -// SourceMappings: 0:3:0:-:0 +// SourceMappings: 27:7:0:-:0 diff --git a/test/libyul/objectCompiler/subObject.yul b/test/libyul/objectCompiler/subObject.yul index 46fc03f10ea8..a47c4feda27f 100644 --- a/test/libyul/objectCompiler/subObject.yul +++ b/test/libyul/objectCompiler/subObject.yul @@ -6,21 +6,21 @@ object "a" { } // ---- // Assembly: -// /* "source":20:22 */ +// /* "source":22:29 */ // stop // stop // data_acaf3289d7b601cbd114fb36c4d29c85bbfd5e133f14cb355c3fd8d99367964f 48656c6c6f2c20576f726c6421 // // sub_0: assembly { -// /* "source":149:150 */ +// /* "source":123:124 */ // 0x01 -// /* "source":146:147 */ +// /* "source":120:121 */ // 0x00 -// /* "source":139:151 */ +// /* "source":113:125 */ // sstore -// /* "source":137:153 */ +// /* "source":109:129 */ // stop // } // Bytecode: 00fe // Opcodes: STOP INVALID -// SourceMappings: 20:2:0:-:0 +// SourceMappings: 22:7:0:-:0 diff --git a/test/libyul/objectCompiler/subObjectAccess.yul b/test/libyul/objectCompiler/subObjectAccess.yul index 291749220a45..b18c902db60f 100644 --- a/test/libyul/objectCompiler/subObjectAccess.yul +++ b/test/libyul/objectCompiler/subObjectAccess.yul @@ -67,164 +67,164 @@ object "A" { } // ---- // Assembly: -// /* "source":37:52 */ +// /* "source":57:72 */ // 0x00 -// /* "source":68:81 */ +// /* "source":96:109 */ // bytecodeSize -// /* "source":97:112 */ +// /* "source":133:148 */ // dataOffset(sub_0) -// /* "source":128:141 */ +// /* "source":172:185 */ // dataSize(sub_0) -// /* "source":158:175 */ +// /* "source":210:227 */ // dataOffset(sub_0.sub_0) -// /* "source":192:207 */ +// /* "source":252:267 */ // dataSize(sub_0.sub_0) -// /* "source":224:241 */ +// /* "source":292:309 */ // swap1 // dataOffset(sub_0.sub_1) -// /* "source":258:273 */ +// /* "source":334:349 */ // swap3 // dataSize(sub_0.sub_1) -// /* "source":291:310 */ +// /* "source":375:394 */ // swap5 // dataOffset(sub_0.sub_0.sub_0) -// /* "source":328:345 */ +// /* "source":420:437 */ // swap7 // dataSize(sub_0.sub_0.sub_0) -// /* "source":351:365 */ +// /* "source":450:464 */ // swap9 -// /* "source":358:359 */ +// /* "source":457:458 */ // 0x00 -// /* "source":351:365 */ +// /* "source":450:464 */ // sstore -// /* "source":377:379 */ +// /* "source":484:486 */ // 0x20 -// /* "source":370:385 */ +// /* "source":477:492 */ // sstore -// /* "source":397:399 */ +// /* "source":512:514 */ // 0x40 -// /* "source":390:405 */ +// /* "source":505:520 */ // sstore -// /* "source":417:419 */ +// /* "source":540:542 */ // 0x60 -// /* "source":410:425 */ +// /* "source":533:548 */ // sstore -// /* "source":437:440 */ +// /* "source":568:571 */ // 0x80 -// /* "source":430:447 */ +// /* "source":561:578 */ // sstore -// /* "source":459:462 */ +// /* "source":598:601 */ // 0xa0 -// /* "source":452:469 */ +// /* "source":591:608 */ // sstore -// /* "source":481:484 */ +// /* "source":628:631 */ // 0xc0 -// /* "source":474:491 */ +// /* "source":621:638 */ // sstore -// /* "source":503:506 */ +// /* "source":658:661 */ // 0xe0 -// /* "source":496:513 */ +// /* "source":651:668 */ // sstore -// /* "source":525:528 */ +// /* "source":688:691 */ // 0x0100 -// /* "source":518:536 */ +// /* "source":681:699 */ // sstore -// /* "source":548:551 */ +// /* "source":719:722 */ // 0x0120 -// /* "source":541:559 */ +// /* "source":712:730 */ // sstore -// /* "source":574:577 */ +// /* "source":753:756 */ // 0x0140 -// /* "source":571:572 */ +// /* "source":750:751 */ // 0x00 -// /* "source":564:578 */ +// /* "source":743:757 */ // return // stop // data_acaf3289d7b601cbd114fb36c4d29c85bbfd5e133f14cb355c3fd8d99367964f 48656c6c6f2c20576f726c6421 // // sub_0: assembly { -// /* "source":659:674 */ +// /* "source":896:911 */ // dataOffset(sub_0) -// /* "source":692:705 */ +// /* "source":939:952 */ // dataSize(sub_0) -// /* "source":723:738 */ +// /* "source":980:995 */ // dataOffset(sub_1) -// /* "source":756:769 */ +// /* "source":1023:1036 */ // dataSize(sub_1) -// /* "source":788:805 */ +// /* "source":1065:1082 */ // swap1 // dataOffset(sub_0.sub_0) -// /* "source":824:839 */ +// /* "source":1111:1126 */ // swap3 // dataSize(sub_0.sub_0) -// /* "source":847:861 */ +// /* "source":1143:1157 */ // swap5 -// /* "source":854:855 */ +// /* "source":1150:1151 */ // 0x00 -// /* "source":847:861 */ +// /* "source":1143:1157 */ // sstore -// /* "source":875:877 */ +// /* "source":1181:1183 */ // 0x20 -// /* "source":868:883 */ +// /* "source":1174:1189 */ // sstore -// /* "source":897:899 */ +// /* "source":1213:1215 */ // 0x40 -// /* "source":890:905 */ +// /* "source":1206:1221 */ // sstore -// /* "source":919:921 */ +// /* "source":1245:1247 */ // 0x60 -// /* "source":912:927 */ +// /* "source":1238:1253 */ // sstore -// /* "source":941:944 */ +// /* "source":1277:1280 */ // 0x80 -// /* "source":934:951 */ +// /* "source":1270:1287 */ // sstore -// /* "source":965:968 */ +// /* "source":1311:1314 */ // 0xa0 -// /* "source":958:975 */ +// /* "source":1304:1321 */ // sstore -// /* "source":992:995 */ +// /* "source":1348:1351 */ // 0xc0 -// /* "source":989:990 */ +// /* "source":1345:1346 */ // 0x00 -// /* "source":982:996 */ +// /* "source":1338:1352 */ // return // stop // // sub_0: assembly { -// /* "source":1052:1067 */ +// /* "source":1466:1481 */ // dataOffset(sub_0) -// /* "source":1087:1100 */ +// /* "source":1513:1526 */ // dataSize(sub_0) -// /* "source":1110:1124 */ +// /* "source":1547:1561 */ // swap1 -// /* "source":1117:1118 */ +// /* "source":1554:1555 */ // 0x00 -// /* "source":1110:1124 */ +// /* "source":1547:1561 */ // sstore -// /* "source":1140:1142 */ +// /* "source":1589:1591 */ // 0x20 -// /* "source":1133:1148 */ +// /* "source":1582:1597 */ // sstore -// /* "source":1167:1169 */ +// /* "source":1628:1630 */ // 0x40 -// /* "source":1164:1165 */ +// /* "source":1625:1626 */ // 0x00 -// /* "source":1157:1170 */ +// /* "source":1618:1631 */ // return // stop // // sub_0: assembly { -// /* "source":1223:1232 */ +// /* "source":1714:1723 */ // invalid // } // } // // sub_1: assembly { -// /* "source":1295:1304 */ +// /* "source":1794:1803 */ // invalid // } // } // Bytecode: 5f6084603d603660746010906073926001946073966001985f5560205560405560605560805560a05560c05560e05561010055610120556101405ff3fe6025601060356001906035926001945f5560205560405560605560805560a05560c05ff3fe600f6001905f5560205560405ff3fefefefe600f6001905f5560205560405ff3fefe // Opcodes: PUSH0 PUSH1 0x84 PUSH1 0x3D PUSH1 0x36 PUSH1 0x74 PUSH1 0x10 SWAP1 PUSH1 0x73 SWAP3 PUSH1 0x1 SWAP5 PUSH1 0x73 SWAP7 PUSH1 0x1 SWAP9 PUSH0 SSTORE PUSH1 0x20 SSTORE PUSH1 0x40 SSTORE PUSH1 0x60 SSTORE PUSH1 0x80 SSTORE PUSH1 0xA0 SSTORE PUSH1 0xC0 SSTORE PUSH1 0xE0 SSTORE PUSH2 0x100 SSTORE PUSH2 0x120 SSTORE PUSH2 0x140 PUSH0 RETURN INVALID PUSH1 0x25 PUSH1 0x10 PUSH1 0x35 PUSH1 0x1 SWAP1 PUSH1 0x35 SWAP3 PUSH1 0x1 SWAP5 PUSH0 SSTORE PUSH1 0x20 SSTORE PUSH1 0x40 SSTORE PUSH1 0x60 SSTORE PUSH1 0x80 SSTORE PUSH1 0xA0 SSTORE PUSH1 0xC0 PUSH0 RETURN INVALID PUSH1 0xF PUSH1 0x1 SWAP1 PUSH0 SSTORE PUSH1 0x20 SSTORE PUSH1 0x40 PUSH0 RETURN INVALID INVALID INVALID INVALID PUSH1 0xF PUSH1 0x1 SWAP1 PUSH0 SSTORE PUSH1 0x20 SSTORE PUSH1 0x40 PUSH0 RETURN INVALID INVALID -// SourceMappings: 37:15:0:-:0;68:13;97:15;128:13;158:17;192:15;224:17;;258:15;;291:19;;328:17;;351:14;358:1;351:14;377:2;370:15;397:2;390:15;417:2;410:15;437:3;430:17;459:3;452:17;481:3;474:17;503:3;496:17;525:3;518:18;548:3;541:18;574:3;571:1;564:14 +// SourceMappings: 57:15:0:-:0;96:13;133:15;172:13;210:17;252:15;292:17;;334:15;;375:19;;420:17;;450:14;457:1;450:14;484:2;477:15;512:2;505:15;540:2;533:15;568:3;561:17;598:3;591:17;628:3;621:17;658:3;651:17;688:3;681:18;719:3;712:18;753:3;750:1;743:14 diff --git a/test/libyul/objectCompiler/subSubObject.yul b/test/libyul/objectCompiler/subSubObject.yul index a9936d58fbdb..a4511324e901 100644 --- a/test/libyul/objectCompiler/subSubObject.yul +++ b/test/libyul/objectCompiler/subSubObject.yul @@ -12,30 +12,30 @@ object "a" { } // ---- // Assembly: -// /* "source":20:22 */ +// /* "source":22:29 */ // stop // stop // data_acaf3289d7b601cbd114fb36c4d29c85bbfd5e133f14cb355c3fd8d99367964f 48656c6c6f2c20576f726c6421 // // sub_0: assembly { -// /* "source":153:154 */ +// /* "source":123:124 */ // 0x01 -// /* "source":150:151 */ +// /* "source":120:121 */ // 0x00 -// /* "source":143:155 */ +// /* "source":113:125 */ // sstore -// /* "source":141:157 */ +// /* "source":109:129 */ // stop // stop // // sub_0: assembly { -// /* "source":203:204 */ +// /* "source":187:188 */ // 0x03 -// /* "source":200:201 */ +// /* "source":184:185 */ // 0x02 -// /* "source":193:205 */ +// /* "source":177:189 */ // sstore -// /* "source":191:207 */ +// /* "source":173:193 */ // stop // stop // data_6adf031833174bbe4c85eafe59ddb54e6584648c2c962c6f94791ab49caa0ad4 123456 @@ -43,4 +43,4 @@ object "a" { // } // Bytecode: 00fe // Opcodes: STOP INVALID -// SourceMappings: 20:2:0:-:0 +// SourceMappings: 22:7:0:-:0 diff --git a/test/libyul/objectCompiler/verbatim_bug.yul b/test/libyul/objectCompiler/verbatim_bug.yul index 778494f0b311..14a1c02b1f33 100644 --- a/test/libyul/objectCompiler/verbatim_bug.yul +++ b/test/libyul/objectCompiler/verbatim_bug.yul @@ -26,99 +26,99 @@ object "a" { // optimizationPreset: full // ---- // Assembly: -// /* "source":87:88 */ +// /* "source":65:66 */ // 0x00 -// /* "source":81:89 */ +// /* "source":59:67 */ // dup1 // sload -// /* "source":139:307 */ +// /* "source":133:225 */ // dup1 // iszero // tag_1 // jumpi -// /* "source":316:361 */ +// /* "source":238:263 */ // dup1 -// /* "source":321:325 */ +// /* "source":243:247 */ // 0x01 -// /* "source":316:361 */ +// /* "source":238:263 */ // eq // tag_3 // jumpi -// /* "source":370:448 */ +// /* "source":276:368 */ // dup1 -// /* "source":375:379 */ +// /* "source":281:285 */ // 0x02 -// /* "source":370:448 */ +// /* "source":276:368 */ // eq // tag_5 // jumpi -// /* "source":462:466 */ +// /* "source":386:390 */ // 0x03 -// /* "source":457:502 */ +// /* "source":381:406 */ // eq // tag_7 // jumpi -// /* "source":87:88 */ +// /* "source":426:427 */ // 0x00 -// /* "source":512:529 */ +// /* "source":419:436 */ // sstore -// /* "source":118:502 */ +// /* "source":108:406 */ // stop -// /* "source":467:502 */ +// /* "source":391:406 */ // tag_7: -// /* "source":481:492 */ +// /* "source":393:404 */ // pop -// /* "source":491:492 */ +// /* "source":403:404 */ // 0x03 -// /* "source":87:88 */ +// /* "source":426:427 */ // 0x00 -// /* "source":512:529 */ +// /* "source":419:436 */ // sstore -// /* "source":118:502 */ +// /* "source":108:406 */ // stop -// /* "source":380:448 */ +// /* "source":286:368 */ // tag_5: -// /* "source":404:438 */ +// /* "source":314:354 */ // pop // pop -// /* "source":45:59 */ +// /* "source":339:353 */ // 0xaabbccddeeff -// /* "source":404:438 */ +// /* "source":314:354 */ // verbatimbytecode_506002 -// /* "source":87:88 */ +// /* "source":426:427 */ // 0x00 -// /* "source":512:529 */ +// /* "source":419:436 */ // sstore -// /* "source":118:502 */ +// /* "source":108:406 */ // stop -// /* "source":326:361 */ +// /* "source":248:263 */ // tag_3: -// /* "source":340:351 */ +// /* "source":250:261 */ // pop // pop -// /* "source":350:351 */ +// /* "source":260:261 */ // 0x01 -// /* "source":87:88 */ +// /* "source":426:427 */ // 0x00 -// /* "source":512:529 */ +// /* "source":419:436 */ // sstore -// /* "source":118:502 */ +// /* "source":108:406 */ // stop -// /* "source":149:307 */ +// /* "source":143:225 */ // tag_1: -// /* "source":263:297 */ +// /* "source":171:211 */ // pop // pop -// /* "source":45:59 */ +// /* "source":196:210 */ // 0xaabbccddeeff -// /* "source":263:297 */ +// /* "source":171:211 */ // verbatimbytecode_506000 -// /* "source":87:88 */ +// /* "source":426:427 */ // 0x00 -// /* "source":512:529 */ +// /* "source":419:436 */ // sstore -// /* "source":118:502 */ +// /* "source":108:406 */ // stop // Bytecode: 5f80548015603e578060011460365780600214602657600314601f575f55005b5060035f55005b505065aabbccddeeff5060025f55005b505060015f55005b505065aabbccddeeff5060005f5500 // Opcodes: PUSH0 DUP1 SLOAD DUP1 ISZERO PUSH1 0x3E JUMPI DUP1 PUSH1 0x1 EQ PUSH1 0x36 JUMPI DUP1 PUSH1 0x2 EQ PUSH1 0x26 JUMPI PUSH1 0x3 EQ PUSH1 0x1F JUMPI PUSH0 SSTORE STOP JUMPDEST POP PUSH1 0x3 PUSH0 SSTORE STOP JUMPDEST POP POP PUSH6 0xAABBCCDDEEFF POP PUSH1 0x2 PUSH0 SSTORE STOP JUMPDEST POP POP PUSH1 0x1 PUSH0 SSTORE STOP JUMPDEST POP POP PUSH6 0xAABBCCDDEEFF POP PUSH1 0x0 PUSH0 SSTORE STOP -// SourceMappings: 87:1:0:-:0;81:8;;139:168;;;;316:45;321:4;316:45;;;370:78;375:4;370:78;;;462:4;457:45;;;87:1;512:17;118:384;467:35;481:11;491:1;87;512:17;118:384;380:68;404:34;;45:14;404:34;87:1;512:17;118:384;326:35;340:11;;350:1;87;512:17;118:384;149:158;263:34;;45:14;263:34;87:1;512:17;118:384 +// SourceMappings: 65:1:0:-:0;59:8;;133:92;;;;238:25;243:4;238:25;;;276:92;281:4;276:92;;;386:4;381:25;;;426:1;419:17;108:298;391:15;393:11;403:1;426;419:17;108:298;286:82;314:40;;339:14;314:40;426:1;419:17;108:298;248:15;250:11;;260:1;426;419:17;108:298;143:82;171:40;;196:14;171:40;426:1;419:17;108:298 From ea85a788255738d36c0d3f886b7f5919f293bc29 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Tue, 6 Aug 2024 14:45:02 +0200 Subject: [PATCH 0339/1022] CLI: remove --yul flag --- Changelog.md | 1 + solc/CommandLineParser.cpp | 19 ++++++++----- test/cmdlineTests/yul_optimize_runs/args | 2 +- test/cmdlineTests/~assembler_modes/test.sh | 21 ++++++++------ test/solc/CommandLineInterface.cpp | 9 +++--- test/solc/CommandLineParser.cpp | 32 ++++++++++------------ 6 files changed, 45 insertions(+), 39 deletions(-) diff --git a/Changelog.md b/Changelog.md index 5e8a7bef8432..71cff3e1f37d 100644 --- a/Changelog.md +++ b/Changelog.md @@ -18,6 +18,7 @@ Compiler Features: * SMTChecker: Replace CVC4 as a possible BMC backend with cvc5. * Standard JSON Interface: Do not perform IR optimization when only unoptimized IR is requested. * Standard JSON Interface: Add ``transientStorageLayout`` output. + * Yul: Drop the deprecated typed Yul dialect that was only accessible via ``--yul`` in the CLI. * Yul Optimizer: The optimizer now treats some previously unrecognized identical literals as identical. * Commandline Interface: Allow the use of ``--asm-json`` output option in assembler mode to export EVM assembly of the contracts in JSON format. diff --git a/solc/CommandLineParser.cpp b/solc/CommandLineParser.cpp index 97c6901400d7..19089d885ae8 100644 --- a/solc/CommandLineParser.cpp +++ b/solc/CommandLineParser.cpp @@ -618,6 +618,9 @@ General Information)").c_str(), "Select desired EOF version. Currently the only valid value is 1. " "If not specified, legacy non-EOF bytecode will be generated." ) + ( + g_strYul.c_str(), "The typed Yul dialect is no longer supported. For regular Yul compilation use --strict-assembly instead." + ) ; outputOptions.add_options() ( @@ -664,10 +667,6 @@ General Information)").c_str(), g_strAssemble.c_str(), "Switch to assembly mode and assume input is assembly." ) - ( - g_strYul.c_str(), - "Switch to Yul mode and assume input is Yul." - ) ( g_strStrictAssembly.c_str(), "Switch to strict assembly mode and assume input is strict assembly." @@ -956,7 +955,6 @@ void CommandLineParser::processArgs() g_strLink, g_strAssemble, g_strStrictAssembly, - g_strYul, g_strImportAst, g_strLSP, g_strImportEvmAssemblerJson, @@ -972,7 +970,7 @@ void CommandLineParser::processArgs() m_options.input.mode = InputMode::StandardJson; else if (m_args.count(g_strLSP)) m_options.input.mode = InputMode::LanguageServer; - else if (m_args.count(g_strAssemble) > 0 || m_args.count(g_strStrictAssembly) > 0 || m_args.count(g_strYul) > 0) + else if (m_args.count(g_strAssemble) > 0 || m_args.count(g_strStrictAssembly) > 0) m_options.input.mode = InputMode::Assembler; else if (m_args.count(g_strLink) > 0) m_options.input.mode = InputMode::Linker; @@ -990,6 +988,13 @@ void CommandLineParser::processArgs() ) return; + if (m_args.count(g_strYul) > 0) + solThrow( + CommandLineValidationError, + "The typed Yul dialect formerly accessible via --yul is no longer supported, " + "please use --strict-assembly instead." + ); + std::map> validOptionInputModeCombinations = { // TODO: This should eventually contain all options. {g_strExperimentalViaIR, {InputMode::Compiler, InputMode::CompilerWithASTImport}}, @@ -1276,7 +1281,7 @@ void CommandLineParser::processArgs() // switch to assembly mode using Input = yul::YulStack::Language; using Machine = yul::YulStack::Machine; - m_options.assembly.inputLanguage = m_args.count(g_strYul) ? Input::Yul : (m_args.count(g_strStrictAssembly) ? Input::StrictAssembly : Input::Assembly); + m_options.assembly.inputLanguage = m_args.count(g_strStrictAssembly) ? Input::StrictAssembly : Input::Assembly; if (m_args.count(g_strMachine)) { diff --git a/test/cmdlineTests/yul_optimize_runs/args b/test/cmdlineTests/yul_optimize_runs/args index 033abe3bbbfd..3a8567e92458 100644 --- a/test/cmdlineTests/yul_optimize_runs/args +++ b/test/cmdlineTests/yul_optimize_runs/args @@ -1 +1 @@ ---yul --yul-dialect evm --optimize --optimize-runs 10000 +--strict-assembly --yul-dialect evm --optimize --optimize-runs 10000 diff --git a/test/cmdlineTests/~assembler_modes/test.sh b/test/cmdlineTests/~assembler_modes/test.sh index 5ca1bb40f82b..708c76395787 100755 --- a/test/cmdlineTests/~assembler_modes/test.sh +++ b/test/cmdlineTests/~assembler_modes/test.sh @@ -25,19 +25,24 @@ function test_solc_assembly_output } echo '{}' | msg_on_error --silent "$SOLC" - --assemble -echo '{}' | msg_on_error --silent "$SOLC" - --yul echo '{}' | msg_on_error --silent "$SOLC" - --strict-assembly -# Test options above in conjunction with --optimize. -# Using both, --assemble and --optimize should fail. +# Test in conjunction with --optimize. Using both, --assemble and --optimize should fail. echo '{}' | "$SOLC" - --assemble --optimize &>/dev/null && fail "solc --assemble --optimize did not fail as expected." -echo '{}' | "$SOLC" - --yul --optimize &>/dev/null && fail "solc --yul --optimize did not fail as expected." -# Test yul and strict assembly output +# Test strict assembly output # Non-empty code results in non-empty binary representation with optimizations turned off, # while it results in empty binary representation with optimizations turned on. -test_solc_assembly_output "{ let x:u256 := 0:u256 mstore(0, x) }" "{ { let x := 0 mstore(0, x) } }" "--yul" -test_solc_assembly_output "{ let x:u256 := bitnot(7:u256) mstore(0, x) }" "{ { let x := bitnot(7) mstore(0, x) } }" "--yul" -test_solc_assembly_output "{ let t:bool := not(true) if t { mstore(0, 1) } }" "{ { let t:bool := not(true) if t { mstore(0, 1) } } }" "--yul" test_solc_assembly_output "{ let x := 0 mstore(0, x) }" "{ { let x := 0 mstore(0, x) } }" "--strict-assembly" test_solc_assembly_output "{ let x := 0 mstore(0, x) }" "{ { } }" "--strict-assembly --optimize" + +# Test that --yul triggers an error +set +e +output=$(echo '{}' | "$SOLC" - --yul 2>&1) +failed=$? +expected="Error: The typed Yul dialect formerly accessible via --yul is no longer supported, please use --strict-assembly instead." +set -e +if [[ $output != "${expected}" ]] || (( failed == 0 )) +then + fail "Incorrect error response to --yul flag: $output" +fi diff --git a/test/solc/CommandLineInterface.cpp b/test/solc/CommandLineInterface.cpp index b3b93cb3aa11..6d19df01b3f8 100644 --- a/test/solc/CommandLineInterface.cpp +++ b/test/solc/CommandLineInterface.cpp @@ -148,7 +148,7 @@ BOOST_AUTO_TEST_CASE(version) BOOST_AUTO_TEST_CASE(multiple_input_modes) { - std::array inputModeOptions = { + std::array inputModeOptions { "--help", "--license", "--version", @@ -156,17 +156,16 @@ BOOST_AUTO_TEST_CASE(multiple_input_modes) "--link", "--assemble", "--strict-assembly", - "--yul", "--import-ast", "--import-asm-json", }; std::string expectedMessage = "The following options are mutually exclusive: " - "--help, --license, --version, --standard-json, --link, --assemble, --strict-assembly, --yul, --import-ast, --lsp, --import-asm-json. " + "--help, --license, --version, --standard-json, --link, --assemble, --strict-assembly, --import-ast, --lsp, --import-asm-json. " "Select at most one."; - for (std::string const& mode1: inputModeOptions) - for (std::string const& mode2: inputModeOptions) + for (auto const& mode1: inputModeOptions) + for (auto const& mode2: inputModeOptions) if (mode1 != mode2) BOOST_CHECK_EXCEPTION( parseCommandLineAndReadInputFiles({"solc", mode1, mode2}), diff --git a/test/solc/CommandLineParser.cpp b/test/solc/CommandLineParser.cpp index 37c638a3bbba..e0347a18c4b5 100644 --- a/test/solc/CommandLineParser.cpp +++ b/test/solc/CommandLineParser.cpp @@ -250,7 +250,6 @@ BOOST_AUTO_TEST_CASE(no_import_callback) {"solc", "--strict-assembly", "--no-import-callback", "input.yul"}, {"solc", "--import-ast", "--no-import-callback", "ast.json"}, {"solc", "--link", "--no-import-callback", "input.bin"}, - {"solc", "--yul", "--no-import-callback", "input.yul"}, }; for (auto const& commandLine: commandLinePerInputMode) @@ -271,13 +270,10 @@ BOOST_AUTO_TEST_CASE(assembly_mode_options) { static std::vector, YulStack::Machine, YulStack::Language>> const allowedCombinations = { {{"--machine=evm", "--yul-dialect=evm", "--assemble"}, YulStack::Machine::EVM, YulStack::Language::StrictAssembly}, - {{"--machine=evm", "--yul-dialect=evm", "--yul"}, YulStack::Machine::EVM, YulStack::Language::StrictAssembly}, {{"--machine=evm", "--yul-dialect=evm", "--strict-assembly"}, YulStack::Machine::EVM, YulStack::Language::StrictAssembly}, {{"--machine=evm", "--assemble"}, YulStack::Machine::EVM, YulStack::Language::Assembly}, - {{"--machine=evm", "--yul"}, YulStack::Machine::EVM, YulStack::Language::Yul}, {{"--machine=evm", "--strict-assembly"}, YulStack::Machine::EVM, YulStack::Language::StrictAssembly}, {{"--assemble"}, YulStack::Machine::EVM, YulStack::Language::Assembly}, - {{"--yul"}, YulStack::Machine::EVM, YulStack::Language::Yul}, {{"--strict-assembly"}, YulStack::Machine::EVM, YulStack::Language::StrictAssembly}, }; @@ -424,20 +420,20 @@ BOOST_AUTO_TEST_CASE(invalid_options_input_modes_combinations) { std::map> invalidOptionInputModeCombinations = { // TODO: This should eventually contain all options. - {"--experimental-via-ir", {"--assemble", "--yul", "--strict-assembly", "--standard-json", "--link"}}, - {"--via-ir", {"--assemble", "--yul", "--strict-assembly", "--standard-json", "--link"}}, - {"--metadata-literal", {"--assemble", "--yul", "--strict-assembly", "--standard-json", "--link"}}, - {"--metadata-hash=swarm", {"--assemble", "--yul", "--strict-assembly", "--standard-json", "--link"}}, - {"--model-checker-show-proved-safe", {"--assemble", "--yul", "--strict-assembly", "--standard-json", "--link"}}, - {"--model-checker-show-unproved", {"--assemble", "--yul", "--strict-assembly", "--standard-json", "--link"}}, - {"--model-checker-show-unsupported", {"--assemble", "--yul", "--strict-assembly", "--standard-json", "--link"}}, - {"--model-checker-div-mod-no-slacks", {"--assemble", "--yul", "--strict-assembly", "--standard-json", "--link"}}, - {"--model-checker-engine=bmc", {"--assemble", "--yul", "--strict-assembly", "--standard-json", "--link"}}, - {"--model-checker-invariants=contract,reentrancy", {"--assemble", "--yul", "--strict-assembly", "--standard-json", "--link"}}, - {"--model-checker-solvers=z3,smtlib2", {"--assemble", "--yul", "--strict-assembly", "--standard-json", "--link"}}, - {"--model-checker-timeout=5", {"--assemble", "--yul", "--strict-assembly", "--standard-json", "--link"}}, - {"--model-checker-contracts=contract1.yul:A,contract2.yul:B", {"--assemble", "--yul", "--strict-assembly", "--standard-json", "--link"}}, - {"--model-checker-targets=underflow,divByZero", {"--assemble", "--yul", "--strict-assembly", "--standard-json", "--link"}} + {"--experimental-via-ir", {"--assemble", "--strict-assembly", "--standard-json", "--link"}}, + {"--via-ir", {"--assemble", "--strict-assembly", "--standard-json", "--link"}}, + {"--metadata-literal", {"--assemble", "--strict-assembly", "--standard-json", "--link"}}, + {"--metadata-hash=swarm", {"--assemble", "--strict-assembly", "--standard-json", "--link"}}, + {"--model-checker-show-proved-safe", {"--assemble", "--strict-assembly", "--standard-json", "--link"}}, + {"--model-checker-show-unproved", {"--assemble", "--strict-assembly", "--standard-json", "--link"}}, + {"--model-checker-show-unsupported", {"--assemble", "--strict-assembly", "--standard-json", "--link"}}, + {"--model-checker-div-mod-no-slacks", {"--assemble", "--strict-assembly", "--standard-json", "--link"}}, + {"--model-checker-engine=bmc", {"--assemble", "--strict-assembly", "--standard-json", "--link"}}, + {"--model-checker-invariants=contract,reentrancy", {"--assemble", "--strict-assembly", "--standard-json", "--link"}}, + {"--model-checker-solvers=z3,smtlib2", {"--assemble", "--strict-assembly", "--standard-json", "--link"}}, + {"--model-checker-timeout=5", {"--assemble", "--strict-assembly", "--standard-json", "--link"}}, + {"--model-checker-contracts=contract1.yul:A,contract2.yul:B", {"--assemble", "--strict-assembly", "--standard-json", "--link"}}, + {"--model-checker-targets=underflow,divByZero", {"--assemble", "--strict-assembly", "--standard-json", "--link"}} }; for (auto const& [optionName, inputModes]: invalidOptionInputModeCombinations) From 55a5fd9b8bdd2cdcbc4cafdad2c0e4189aaba607 Mon Sep 17 00:00:00 2001 From: pgebal Date: Fri, 9 Aug 2024 14:47:53 +0200 Subject: [PATCH 0340/1022] Fix SMT logic error when assigning to an array of contracts or functions (#15322) --- Changelog.md | 1 + libsolidity/formal/SymbolicTypes.cpp | 8 ++++++++ .../types/array_of_contracts.sol | 17 +++++++++++++++++ .../types/array_of_functions.sol | 16 ++++++++++++++++ 4 files changed, 42 insertions(+) create mode 100644 test/libsolidity/smtCheckerTests/types/array_of_contracts.sol create mode 100644 test/libsolidity/smtCheckerTests/types/array_of_functions.sol diff --git a/Changelog.md b/Changelog.md index 71cff3e1f37d..a3dfc541d174 100644 --- a/Changelog.md +++ b/Changelog.md @@ -28,6 +28,7 @@ Bugfixes: * SMTChecker: Fix error that reports invalid number of verified checks for BMC and CHC engines. * SMTChecker: Fix formatting of unary minus expressions in invariants. * SMTChecker: Fix internal compiler error when reporting proved targets for BMC engine. + * SMTChecker: Fix SMT logic error when assigning to an array of contracts or functions. * TypeChecker: Fix segfault when assigning nested tuple to tuple. * Yul AST: Fix ``nativeSrc`` attributes in optimized IR AST referring to locations in unoptimized IR. * Yul IR Code Generation: Deterministic order of Yul subobjects. diff --git a/libsolidity/formal/SymbolicTypes.cpp b/libsolidity/formal/SymbolicTypes.cpp index 350e18bdcf77..4a4ac8175f08 100644 --- a/libsolidity/formal/SymbolicTypes.cpp +++ b/libsolidity/formal/SymbolicTypes.cpp @@ -110,6 +110,14 @@ SortPointer smtSort(frontend::Type const& _type) // in the tuple's name. if (auto tupleSort = std::dynamic_pointer_cast(array->range)) tupleName = tupleSort->name; + else if (isContract(*baseType)) + // use a common sort for contracts so inheriting contracts do not cause conflicting SMT types + // solc handles types mismtach + tupleName = "contract"; + else if (isFunction(*baseType)) + // use a common sort for functions so pure and view modifier do not cause conflicting SMT types + // solc handles types mismtach + tupleName = "function"; else if ( baseType->category() == frontend::Type::Category::Integer || baseType->category() == frontend::Type::Category::FixedPoint diff --git a/test/libsolidity/smtCheckerTests/types/array_of_contracts.sol b/test/libsolidity/smtCheckerTests/types/array_of_contracts.sol new file mode 100644 index 000000000000..89d2420323e3 --- /dev/null +++ b/test/libsolidity/smtCheckerTests/types/array_of_contracts.sol @@ -0,0 +1,17 @@ +contract A {} + +contract B is A {} + +contract C { + A[10] a; + B[10] b; + + function f() public returns(address) { + a = b; + return address(a[0]); + } +} +// ==== +// SMTEngine: all +// ---- +// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/types/array_of_functions.sol b/test/libsolidity/smtCheckerTests/types/array_of_functions.sol new file mode 100644 index 000000000000..58a73d4ced53 --- /dev/null +++ b/test/libsolidity/smtCheckerTests/types/array_of_functions.sol @@ -0,0 +1,16 @@ +contract C { + function() external returns(uint)[1] a; + + function b() external pure returns(uint) { + return 1; + } + + function test() public returns(uint) { + a = [this.b]; + return a[0](); + } +} +// ==== +// SMTEngine: all +// ---- +// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. From da68f49bc3a523f96c1e5aa525f80ee3e104bc4b Mon Sep 17 00:00:00 2001 From: Matheus Aguiar Date: Tue, 6 Aug 2024 14:47:28 -0300 Subject: [PATCH 0341/1022] Dont allow initialization of transient storage state variables --- libsolidity/analysis/DeclarationTypeChecker.cpp | 8 ++++++++ .../unsupported/transient_storage_state_variable.sol | 4 ++-- .../constants/constant_transient_state_variable.sol | 1 + ...ransient_value_type_state_variables_assignment.sol | 9 --------- ...ient_value_type_state_variables_initialization.sol | 11 +++++++++++ 5 files changed, 22 insertions(+), 11 deletions(-) delete mode 100644 test/libsolidity/syntaxTests/dataLocations/transient_value_type_state_variables_assignment.sol create mode 100644 test/libsolidity/syntaxTests/dataLocations/transient_value_type_state_variables_initialization.sol diff --git a/libsolidity/analysis/DeclarationTypeChecker.cpp b/libsolidity/analysis/DeclarationTypeChecker.cpp index 7e6ab98e1e24..bdf023c5c0b9 100644 --- a/libsolidity/analysis/DeclarationTypeChecker.cpp +++ b/libsolidity/analysis/DeclarationTypeChecker.cpp @@ -469,6 +469,14 @@ void DeclarationTypeChecker::endVisit(VariableDeclaration const& _variable) _variable.location(), "Transient cannot be used as data location for constant or immutable variables." ); + + if (_variable.value()) + m_errorReporter.declarationError( + 9825_error, + _variable.location(), + "Initialization of transient storage state variables is not supported." + ); + typeLoc = DataLocation::Transient; break; default: diff --git a/test/libsolidity/smtCheckerTests/unsupported/transient_storage_state_variable.sol b/test/libsolidity/smtCheckerTests/unsupported/transient_storage_state_variable.sol index b2dbc8efe5c7..c74eb24c3f96 100644 --- a/test/libsolidity/smtCheckerTests/unsupported/transient_storage_state_variable.sol +++ b/test/libsolidity/smtCheckerTests/unsupported/transient_storage_state_variable.sol @@ -1,6 +1,6 @@ contract C { - uint transient x = 42; - function test() public view { assert(x == 42); } + uint transient x; + function test() public view { assert(x == 0); } } // ==== // SMTEngine: all diff --git a/test/libsolidity/syntaxTests/constants/constant_transient_state_variable.sol b/test/libsolidity/syntaxTests/constants/constant_transient_state_variable.sol index f9a722a1b4a8..15913360c38b 100644 --- a/test/libsolidity/syntaxTests/constants/constant_transient_state_variable.sol +++ b/test/libsolidity/syntaxTests/constants/constant_transient_state_variable.sol @@ -3,3 +3,4 @@ contract C { } // ---- // DeclarationError 2197: (17-52): Transient cannot be used as data location for constant or immutable variables. +// DeclarationError 9825: (17-52): Initialization of transient storage state variables is not supported. diff --git a/test/libsolidity/syntaxTests/dataLocations/transient_value_type_state_variables_assignment.sol b/test/libsolidity/syntaxTests/dataLocations/transient_value_type_state_variables_assignment.sol deleted file mode 100644 index 18e6a215dd1a..000000000000 --- a/test/libsolidity/syntaxTests/dataLocations/transient_value_type_state_variables_assignment.sol +++ /dev/null @@ -1,9 +0,0 @@ -contract D { } - -contract C { - int transient x = -99; - address transient a = address(0xABC); - bool transient b = x > 0 ? false : true; -} -// ---- -// UnimplementedFeatureError 1834: Transient storage variables are not supported. diff --git a/test/libsolidity/syntaxTests/dataLocations/transient_value_type_state_variables_initialization.sol b/test/libsolidity/syntaxTests/dataLocations/transient_value_type_state_variables_initialization.sol new file mode 100644 index 000000000000..570642485ea8 --- /dev/null +++ b/test/libsolidity/syntaxTests/dataLocations/transient_value_type_state_variables_initialization.sol @@ -0,0 +1,11 @@ +contract D { } + +contract C { + int transient x = -99; + address transient a = address(0xABC); + bool transient b = x > 0 ? false : true; +} +// ---- +// DeclarationError 9825: (30-51): Initialization of transient storage state variables is not supported. +// DeclarationError 9825: (54-90): Initialization of transient storage state variables is not supported. +// DeclarationError 9825: (93-132): Initialization of transient storage state variables is not supported. From 44e008bb5dc1599f649121da9eb159cf7050d234 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Wed, 7 Aug 2024 11:15:34 +0200 Subject: [PATCH 0342/1022] Yul: remove deprecated dialect --- libyul/Dialect.cpp | 28 ------------------- libyul/Dialect.h | 3 -- libyul/YulStack.cpp | 4 +-- test/libyul/Common.cpp | 11 ++------ test/libyul/Parser.cpp | 4 +-- .../add_correct_type.yul | 2 +- .../disambiguator/for_statement.yul | 10 +++---- .../disambiguator/funtion_call.yul | 2 +- .../disambiguator/if_statement.yul | 2 +- .../disambiguator/long_names.yul | 2 +- .../{smoke_yul.yul => smoke_evmTyped.yul} | 2 +- .../disambiguator/switch_statement.yul | 2 +- .../disambiguator/variables.yul | 2 +- .../disambiguator/variables_clash.yul | 2 +- .../variables_inside_functions.yul | 2 +- .../expressionInliner/simple.yul | 2 +- .../expressionInliner/with_args.yul | 2 +- .../functionGrouper/empty_block.yul | 2 +- .../functionGrouper/multi_fun_mixed.yul | 2 +- .../functionGrouper/nested_fun.yul | 2 +- .../functionGrouper/single_fun.yul | 2 +- .../functionHoister/empty_block.yul | 2 +- .../functionHoister/multi_mixed.yul | 2 +- .../functionHoister/nested.yul | 2 +- .../functionHoister/single.yul | 2 +- test/libyul/yulSyntaxTests/builtin_types.yul | 13 ++------- .../yulSyntaxTests/for_visibility_9.yul | 2 +- .../yulSyntaxTests/for_visibility_A.yul | 2 +- .../yulSyntaxTests/if_statement_invalid_3.yul | 2 +- test/libyul/yulSyntaxTests/instructions.yul | 2 +- test/libyul/yulSyntaxTests/optional_types.yul | 2 +- .../yulSyntaxTests/token_as_identifier.yul | 5 +--- test/libyul/yulSyntaxTests/vardecl.yul | 2 +- .../variable_declaration_complex.yul | 6 ++-- 34 files changed, 43 insertions(+), 91 deletions(-) rename test/libyul/yulOptimizerTests/disambiguator/{smoke_yul.yul => smoke_evmTyped.yul} (71%) diff --git a/libyul/Dialect.cpp b/libyul/Dialect.cpp index f4f59ec26aa7..8afd99a2288f 100644 --- a/libyul/Dialect.cpp +++ b/libyul/Dialect.cpp @@ -48,31 +48,3 @@ bool Dialect::validTypeForLiteral(LiteralKind _kind, LiteralValue const&, YulNam else return true; } - -Dialect const& Dialect::yulDeprecated() -{ - static std::unique_ptr dialect; - static YulStringRepository::ResetCallback callback{[&] { dialect.reset(); }}; - - if (!dialect) - { - // TODO will probably change, especially the list of types. - dialect = std::make_unique(); - dialect->defaultType = "u256"_yulname; - dialect->boolType = "bool"_yulname; - dialect->types = { - "bool"_yulname, - "u8"_yulname, - "s8"_yulname, - "u32"_yulname, - "s32"_yulname, - "u64"_yulname, - "s64"_yulname, - "u128"_yulname, - "s128"_yulname, - "u256"_yulname, - "s256"_yulname}; - }; - - return *dialect; -} diff --git a/libyul/Dialect.h b/libyul/Dialect.h index 3362246a063a..fcec5fe3f981 100644 --- a/libyul/Dialect.h +++ b/libyul/Dialect.h @@ -94,9 +94,6 @@ struct Dialect Dialect() = default; virtual ~Dialect() = default; - - /// Old "yul" dialect. This is only used for testing. - static Dialect const& yulDeprecated(); }; } diff --git a/libyul/YulStack.cpp b/libyul/YulStack.cpp index dbe30bb136d5..385c527d2aad 100644 --- a/libyul/YulStack.cpp +++ b/libyul/YulStack.cpp @@ -54,8 +54,8 @@ Dialect const& languageToDialect(YulStack::Language _language, EVMVersion _versi case YulStack::Language::Yul: return EVMDialectTyped::instance(_version); } - yulAssert(false, ""); - return Dialect::yulDeprecated(); + yulAssert(false); + util::unreachable(); } } diff --git a/test/libyul/Common.cpp b/test/libyul/Common.cpp index d147e03d0071..01956e7f584f 100644 --- a/test/libyul/Common.cpp +++ b/test/libyul/Common.cpp @@ -44,9 +44,9 @@ using namespace solidity::langutil; namespace { -Dialect const& defaultDialect(bool _yul) +Dialect const& defaultDialect() { - return _yul ? yul::Dialect::yulDeprecated() : yul::EVMDialect::strictAssemblyForEVM(solidity::test::CommonOptions::get().evmVersion()); + return yul::EVMDialect::strictAssemblyForEVM(solidity::test::CommonOptions::get().evmVersion()); } } @@ -91,7 +91,7 @@ std::pair, std::shared_ptr> yul::t yul::Block yul::test::disambiguate(std::string const& _source, bool _yul) { auto result = parse(_source, _yul); - return std::get(Disambiguator(defaultDialect(_yul), *result.second, {})(result.first->root())); + return std::get(Disambiguator(defaultDialect(), *result.second, {})(result.first->root())); } std::string yul::test::format(std::string const& _source, bool _yul) @@ -113,11 +113,6 @@ std::map const "evmTyped", [](langutil::EVMVersion _evmVersion) -> yul::Dialect const& { return yul::EVMDialectTyped::instance(_evmVersion); } - }, - { - "yul", - [](langutil::EVMVersion) -> yul::Dialect const& - { return yul::Dialect::yulDeprecated(); } } }; diff --git a/test/libyul/Parser.cpp b/test/libyul/Parser.cpp index 0ed09f6a908a..5ce8b449b578 100644 --- a/test/libyul/Parser.cpp +++ b/test/libyul/Parser.cpp @@ -104,12 +104,12 @@ std::optional parseAndReturnFirstError(std::string const& _source, Dialec return {}; } -bool successParse(std::string const& _source, Dialect const& _dialect = Dialect::yulDeprecated(), bool _allowWarningsAndInfos = true) +bool successParse(std::string const& _source, Dialect const& _dialect, bool _allowWarningsAndInfos = true) { return !parseAndReturnFirstError(_source, _dialect, _allowWarningsAndInfos); } -Error expectError(std::string const& _source, Dialect const& _dialect = Dialect::yulDeprecated(), bool _allowWarningsAndInfos = false) +Error expectError(std::string const& _source, Dialect const& _dialect, bool _allowWarningsAndInfos = false) { auto error = parseAndReturnFirstError(_source, _dialect, _allowWarningsAndInfos); diff --git a/test/libyul/yulOptimizerTests/conditionalSimplifier/add_correct_type.yul b/test/libyul/yulOptimizerTests/conditionalSimplifier/add_correct_type.yul index c7cc17fc8fd4..57785f0b3d08 100644 --- a/test/libyul/yulOptimizerTests/conditionalSimplifier/add_correct_type.yul +++ b/test/libyul/yulOptimizerTests/conditionalSimplifier/add_correct_type.yul @@ -5,7 +5,7 @@ } } // ==== -// dialect: yul +// dialect: evmTyped // ---- // step: conditionalSimplifier // diff --git a/test/libyul/yulOptimizerTests/disambiguator/for_statement.yul b/test/libyul/yulOptimizerTests/disambiguator/for_statement.yul index 30f2e54794a0..fcfbe3242eae 100644 --- a/test/libyul/yulOptimizerTests/disambiguator/for_statement.yul +++ b/test/libyul/yulOptimizerTests/disambiguator/for_statement.yul @@ -1,23 +1,23 @@ { { let a:u256, b:u256 } { - function eq(x: u256, y: u256) -> z: bool {} - for { let a:u256 } eq(a, a) { a := a } { + function eq_function(x: u256, y: u256) -> z: bool {} + for { let a:u256 } eq_function(a, a) { a := a } { let b:u256 := a } } } // ==== -// dialect: yul +// dialect: evmTyped // ---- // step: disambiguator // // { // { let a, b } // { -// function eq(x, y) -> z:bool +// function eq_function(x, y) -> z:bool // { } -// for { let a_1 } eq(a_1, a_1) { a_1 := a_1 } +// for { let a_1 } eq_function(a_1, a_1) { a_1 := a_1 } // { let b_2 := a_1 } // } // } diff --git a/test/libyul/yulOptimizerTests/disambiguator/funtion_call.yul b/test/libyul/yulOptimizerTests/disambiguator/funtion_call.yul index f99c4e4476de..7fc51a5fa54b 100644 --- a/test/libyul/yulOptimizerTests/disambiguator/funtion_call.yul +++ b/test/libyul/yulOptimizerTests/disambiguator/funtion_call.yul @@ -7,7 +7,7 @@ } } // ==== -// dialect: yul +// dialect: evmTyped // ---- // step: disambiguator // diff --git a/test/libyul/yulOptimizerTests/disambiguator/if_statement.yul b/test/libyul/yulOptimizerTests/disambiguator/if_statement.yul index 6b6da1f189fa..512d7fc12bbb 100644 --- a/test/libyul/yulOptimizerTests/disambiguator/if_statement.yul +++ b/test/libyul/yulOptimizerTests/disambiguator/if_statement.yul @@ -6,7 +6,7 @@ } } // ==== -// dialect: yul +// dialect: evmTyped // ---- // step: disambiguator // diff --git a/test/libyul/yulOptimizerTests/disambiguator/long_names.yul b/test/libyul/yulOptimizerTests/disambiguator/long_names.yul index d55afc4828b8..fbd95ef3a2df 100644 --- a/test/libyul/yulOptimizerTests/disambiguator/long_names.yul +++ b/test/libyul/yulOptimizerTests/disambiguator/long_names.yul @@ -1,6 +1,6 @@ { { let aanteuhdaoneudbrgkjiuaothduiathudaoeuh:u256 } { let aanteuhdaoneudbrgkjiuaothduiathudaoeuh:u256 } } // ==== -// dialect: yul +// dialect: evmTyped // ---- // step: disambiguator // diff --git a/test/libyul/yulOptimizerTests/disambiguator/smoke_yul.yul b/test/libyul/yulOptimizerTests/disambiguator/smoke_evmTyped.yul similarity index 71% rename from test/libyul/yulOptimizerTests/disambiguator/smoke_yul.yul rename to test/libyul/yulOptimizerTests/disambiguator/smoke_evmTyped.yul index 676416437795..481cbb588370 100644 --- a/test/libyul/yulOptimizerTests/disambiguator/smoke_yul.yul +++ b/test/libyul/yulOptimizerTests/disambiguator/smoke_evmTyped.yul @@ -1,6 +1,6 @@ { } // ==== -// dialect: yul +// dialect: evmTyped // ---- // step: disambiguator // diff --git a/test/libyul/yulOptimizerTests/disambiguator/switch_statement.yul b/test/libyul/yulOptimizerTests/disambiguator/switch_statement.yul index 16ee5353f79b..86ea9cba28af 100644 --- a/test/libyul/yulOptimizerTests/disambiguator/switch_statement.yul +++ b/test/libyul/yulOptimizerTests/disambiguator/switch_statement.yul @@ -8,7 +8,7 @@ } } // ==== -// dialect: yul +// dialect: evmTyped // ---- // step: disambiguator // diff --git a/test/libyul/yulOptimizerTests/disambiguator/variables.yul b/test/libyul/yulOptimizerTests/disambiguator/variables.yul index 65c93bbb9e88..743eaf0de6d3 100644 --- a/test/libyul/yulOptimizerTests/disambiguator/variables.yul +++ b/test/libyul/yulOptimizerTests/disambiguator/variables.yul @@ -1,6 +1,6 @@ { { let a:u256 } { let a:u256 } } // ==== -// dialect: yul +// dialect: evmTyped // ---- // step: disambiguator // diff --git a/test/libyul/yulOptimizerTests/disambiguator/variables_clash.yul b/test/libyul/yulOptimizerTests/disambiguator/variables_clash.yul index e2cf23756d56..2a94e47697a6 100644 --- a/test/libyul/yulOptimizerTests/disambiguator/variables_clash.yul +++ b/test/libyul/yulOptimizerTests/disambiguator/variables_clash.yul @@ -1,6 +1,6 @@ { { let a:u256 let a_1:u256 } { let a:u256 } } // ==== -// dialect: yul +// dialect: evmTyped // ---- // step: disambiguator // diff --git a/test/libyul/yulOptimizerTests/disambiguator/variables_inside_functions.yul b/test/libyul/yulOptimizerTests/disambiguator/variables_inside_functions.yul index a78af7dabcab..f9e134aff567 100644 --- a/test/libyul/yulOptimizerTests/disambiguator/variables_inside_functions.yul +++ b/test/libyul/yulOptimizerTests/disambiguator/variables_inside_functions.yul @@ -6,7 +6,7 @@ } } // ==== -// dialect: yul +// dialect: evmTyped // ---- // step: disambiguator // diff --git a/test/libyul/yulOptimizerTests/expressionInliner/simple.yul b/test/libyul/yulOptimizerTests/expressionInliner/simple.yul index 2b6dba24069f..dbc80a8595d7 100644 --- a/test/libyul/yulOptimizerTests/expressionInliner/simple.yul +++ b/test/libyul/yulOptimizerTests/expressionInliner/simple.yul @@ -3,7 +3,7 @@ let y:u256 := f() } // ==== -// dialect: yul +// dialect: evmTyped // ---- // step: expressionInliner // diff --git a/test/libyul/yulOptimizerTests/expressionInliner/with_args.yul b/test/libyul/yulOptimizerTests/expressionInliner/with_args.yul index 0456654e3a82..e142f59784d3 100644 --- a/test/libyul/yulOptimizerTests/expressionInliner/with_args.yul +++ b/test/libyul/yulOptimizerTests/expressionInliner/with_args.yul @@ -3,7 +3,7 @@ let y:u256 := f(7:u256) } // ==== -// dialect: yul +// dialect: evmTyped // ---- // step: expressionInliner // diff --git a/test/libyul/yulOptimizerTests/functionGrouper/empty_block.yul b/test/libyul/yulOptimizerTests/functionGrouper/empty_block.yul index 7bfbb340124f..05fa8d249a17 100644 --- a/test/libyul/yulOptimizerTests/functionGrouper/empty_block.yul +++ b/test/libyul/yulOptimizerTests/functionGrouper/empty_block.yul @@ -1,6 +1,6 @@ { let a:u256 { } function f() -> x:bool { let b:u256 := 4:u256 {} for {} f() {} {} } } // ==== -// dialect: yul +// dialect: evmTyped // ---- // step: functionGrouper // diff --git a/test/libyul/yulOptimizerTests/functionGrouper/multi_fun_mixed.yul b/test/libyul/yulOptimizerTests/functionGrouper/multi_fun_mixed.yul index 1aedecf6a348..5d4eaea5e0b5 100644 --- a/test/libyul/yulOptimizerTests/functionGrouper/multi_fun_mixed.yul +++ b/test/libyul/yulOptimizerTests/functionGrouper/multi_fun_mixed.yul @@ -5,7 +5,7 @@ let e:u256 } // ==== -// dialect: yul +// dialect: evmTyped // ---- // step: functionGrouper // diff --git a/test/libyul/yulOptimizerTests/functionGrouper/nested_fun.yul b/test/libyul/yulOptimizerTests/functionGrouper/nested_fun.yul index 9193da739c2b..5b8436540110 100644 --- a/test/libyul/yulOptimizerTests/functionGrouper/nested_fun.yul +++ b/test/libyul/yulOptimizerTests/functionGrouper/nested_fun.yul @@ -9,7 +9,7 @@ } } // ==== -// dialect: yul +// dialect: evmTyped // ---- // step: functionGrouper // diff --git a/test/libyul/yulOptimizerTests/functionGrouper/single_fun.yul b/test/libyul/yulOptimizerTests/functionGrouper/single_fun.yul index b007f1855a30..a62b0ddeba3d 100644 --- a/test/libyul/yulOptimizerTests/functionGrouper/single_fun.yul +++ b/test/libyul/yulOptimizerTests/functionGrouper/single_fun.yul @@ -2,7 +2,7 @@ let a:u256 function f() {} } // ==== -// dialect: yul +// dialect: evmTyped // ---- // step: functionGrouper // diff --git a/test/libyul/yulOptimizerTests/functionHoister/empty_block.yul b/test/libyul/yulOptimizerTests/functionHoister/empty_block.yul index bd66b3a2b1cd..5eed2d2bbe74 100644 --- a/test/libyul/yulOptimizerTests/functionHoister/empty_block.yul +++ b/test/libyul/yulOptimizerTests/functionHoister/empty_block.yul @@ -8,7 +8,7 @@ } } // ==== -// dialect: yul +// dialect: evmTyped // ---- // step: functionHoister // diff --git a/test/libyul/yulOptimizerTests/functionHoister/multi_mixed.yul b/test/libyul/yulOptimizerTests/functionHoister/multi_mixed.yul index 060fab314c96..fc6168ce96ef 100644 --- a/test/libyul/yulOptimizerTests/functionHoister/multi_mixed.yul +++ b/test/libyul/yulOptimizerTests/functionHoister/multi_mixed.yul @@ -6,7 +6,7 @@ let e:u256 } // ==== -// dialect: yul +// dialect: evmTyped // ---- // step: functionHoister // diff --git a/test/libyul/yulOptimizerTests/functionHoister/nested.yul b/test/libyul/yulOptimizerTests/functionHoister/nested.yul index 05eb4803b0a6..65486dc6c5b3 100644 --- a/test/libyul/yulOptimizerTests/functionHoister/nested.yul +++ b/test/libyul/yulOptimizerTests/functionHoister/nested.yul @@ -7,7 +7,7 @@ } } // ==== -// dialect: yul +// dialect: evmTyped // ---- // step: functionHoister // diff --git a/test/libyul/yulOptimizerTests/functionHoister/single.yul b/test/libyul/yulOptimizerTests/functionHoister/single.yul index 205626b57f58..e939ecb85503 100644 --- a/test/libyul/yulOptimizerTests/functionHoister/single.yul +++ b/test/libyul/yulOptimizerTests/functionHoister/single.yul @@ -3,7 +3,7 @@ function f() {} } // ==== -// dialect: yul +// dialect: evmTyped // ---- // step: functionHoister // diff --git a/test/libyul/yulSyntaxTests/builtin_types.yul b/test/libyul/yulSyntaxTests/builtin_types.yul index becf342b8f37..e4d961c300f3 100644 --- a/test/libyul/yulSyntaxTests/builtin_types.yul +++ b/test/libyul/yulSyntaxTests/builtin_types.yul @@ -1,16 +1,7 @@ { let x1:bool := true:bool - let x2:u8 := 1:u8 - let x3:s8 := 1:s8 - let x4:u32 := 1:u32 - let x5:s32 := 1:s32 - let x6:u64 := 1:u64 - let x7:s64 := 1:s64 - let x8:u128 := 1:u128 - let x9:s128 := 1:s128 - let x10:u256 := 1:u256 - let x11:s256 := 1:s256 + let x2:u256 := 1:u256 } // ==== -// dialect: yul +// dialect: evmTyped // ---- diff --git a/test/libyul/yulSyntaxTests/for_visibility_9.yul b/test/libyul/yulSyntaxTests/for_visibility_9.yul index 4cda1b165fd9..6922dc96178f 100644 --- a/test/libyul/yulSyntaxTests/for_visibility_9.yul +++ b/test/libyul/yulSyntaxTests/for_visibility_9.yul @@ -2,6 +2,6 @@ for { let x := 1 } 1 { let x := 1 } {} } // ==== -// dialect: yul +// dialect: evmTyped // ---- // DeclarationError 1395: (26-36): Variable name x already taken in this scope. diff --git a/test/libyul/yulSyntaxTests/for_visibility_A.yul b/test/libyul/yulSyntaxTests/for_visibility_A.yul index a5761f52a919..07766159d3a8 100644 --- a/test/libyul/yulSyntaxTests/for_visibility_A.yul +++ b/test/libyul/yulSyntaxTests/for_visibility_A.yul @@ -2,6 +2,6 @@ for { let x := 1 } 1 {} { let x := 1 } } // ==== -// dialect: yul +// dialect: evm // ---- // DeclarationError 1395: (29-39): Variable name x already taken in this scope. diff --git a/test/libyul/yulSyntaxTests/if_statement_invalid_3.yul b/test/libyul/yulSyntaxTests/if_statement_invalid_3.yul index fa396456fd1a..c99bcac14f88 100644 --- a/test/libyul/yulSyntaxTests/if_statement_invalid_3.yul +++ b/test/libyul/yulSyntaxTests/if_statement_invalid_3.yul @@ -2,6 +2,6 @@ if 32 let x := 3 } // ==== -// dialect: yul +// dialect: evm // ---- // ParserError 2314: (12-15): Expected '{' but got reserved keyword 'let' diff --git a/test/libyul/yulSyntaxTests/instructions.yul b/test/libyul/yulSyntaxTests/instructions.yul index 3d600812fb12..64268bbb4e80 100644 --- a/test/libyul/yulSyntaxTests/instructions.yul +++ b/test/libyul/yulSyntaxTests/instructions.yul @@ -1,5 +1,5 @@ { pop } // ==== -// dialect: yul +// dialect: evm // ---- // ParserError 6913: (6-7): Call or assignment expected. diff --git a/test/libyul/yulSyntaxTests/optional_types.yul b/test/libyul/yulSyntaxTests/optional_types.yul index aa77ffca708c..151edbf46973 100644 --- a/test/libyul/yulSyntaxTests/optional_types.yul +++ b/test/libyul/yulSyntaxTests/optional_types.yul @@ -5,5 +5,5 @@ function g(a:u256) -> b {} } // ==== -// dialect: yul +// dialect: evmTyped // ---- diff --git a/test/libyul/yulSyntaxTests/token_as_identifier.yul b/test/libyul/yulSyntaxTests/token_as_identifier.yul index eaeceb7c46f8..204b76e55533 100644 --- a/test/libyul/yulSyntaxTests/token_as_identifier.yul +++ b/test/libyul/yulSyntaxTests/token_as_identifier.yul @@ -1,9 +1,6 @@ { - let return:u256 := 1:u256 - let byte:u256 := 1:u256 - let address:u256 := 1:u256 let bool:u256 := 1:u256 } // ==== -// dialect: yul +// dialect: evmTyped // ---- diff --git a/test/libyul/yulSyntaxTests/vardecl.yul b/test/libyul/yulSyntaxTests/vardecl.yul index fd7d06bfbc0e..41b58cc2f280 100644 --- a/test/libyul/yulSyntaxTests/vardecl.yul +++ b/test/libyul/yulSyntaxTests/vardecl.yul @@ -2,5 +2,5 @@ let x := 7 } // ==== -// dialect: yul +// dialect: evm // ---- diff --git a/test/libyul/yulSyntaxTests/variable_declaration_complex.yul b/test/libyul/yulSyntaxTests/variable_declaration_complex.yul index 4b93cdb04f15..e7a428fc2c92 100644 --- a/test/libyul/yulSyntaxTests/variable_declaration_complex.yul +++ b/test/libyul/yulSyntaxTests/variable_declaration_complex.yul @@ -1,8 +1,8 @@ { - function add(a:u256, b:u256) -> c:u256 {} + function add_fn(a:u256, b:u256) -> c:u256 {} let y:u256 := 2:u256 - let x:u256 := add(7:u256, add(6:u256, y)) + let x:u256 := add_fn(7:u256, add_fn(6:u256, y)) } // ==== -// dialect: yul +// dialect: evmTyped // ---- From 61d1d9ddbdda0532068299c651c4e6c102b6c287 Mon Sep 17 00:00:00 2001 From: Alireza Arjmand Date: Mon, 12 Aug 2024 11:28:02 -0400 Subject: [PATCH 0343/1022] fix typo in micropayment.rst --- docs/examples/micropayment.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/examples/micropayment.rst b/docs/examples/micropayment.rst index c3aef0d653da..9a3ad845ce1a 100644 --- a/docs/examples/micropayment.rst +++ b/docs/examples/micropayment.rst @@ -482,7 +482,7 @@ The full contract .. note:: The function ``splitSignature`` does not use all security checks. A real implementation should use a more rigorously tested library, - such as openzepplin's `version `_ of this code. + such as openzeppelin's `version `_ of this code. Verifying Payments ------------------ From 1c0b2f5bb760f442c0d71ae37a41ea02f27464f4 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Tue, 13 Aug 2024 08:51:05 +0200 Subject: [PATCH 0344/1022] Yul: Remove EVMDialectTyped --- libyul/YulStack.cpp | 5 -- libyul/YulStack.h | 2 +- libyul/backends/evm/EVMDialect.cpp | 108 ----------------------------- libyul/backends/evm/EVMDialect.h | 22 ------ 4 files changed, 1 insertion(+), 136 deletions(-) diff --git a/libyul/YulStack.cpp b/libyul/YulStack.cpp index 933c3f75e669..8166ed3cfda6 100644 --- a/libyul/YulStack.cpp +++ b/libyul/YulStack.cpp @@ -52,8 +52,6 @@ Dialect const& languageToDialect(YulStack::Language _language, EVMVersion _versi case YulStack::Language::Assembly: case YulStack::Language::StrictAssembly: return EVMDialect::strictAssemblyForEVMObjects(_version); - case YulStack::Language::Yul: - return EVMDialectTyped::instance(_version); } yulAssert(false); util::unreachable(); @@ -180,9 +178,6 @@ void YulStack::compileEVM(AbstractAssembly& _assembly, bool _optimize) const case Language::StrictAssembly: dialect = &EVMDialect::strictAssemblyForEVMObjects(m_evmVersion); break; - case Language::Yul: - dialect = &EVMDialectTyped::instance(m_evmVersion); - break; default: yulAssert(false, "Invalid language."); break; diff --git a/libyul/YulStack.h b/libyul/YulStack.h index 4dc262a25c76..b09fa7975859 100644 --- a/libyul/YulStack.h +++ b/libyul/YulStack.h @@ -65,7 +65,7 @@ struct MachineAssemblyObject class YulStack: public langutil::CharStreamProvider { public: - enum class Language { Yul, Assembly, StrictAssembly }; + enum class Language { Assembly, StrictAssembly }; enum class Machine { EVM }; enum State { Empty, diff --git a/libyul/backends/evm/EVMDialect.cpp b/libyul/backends/evm/EVMDialect.cpp index 50ede8c760f0..aeb825304009 100644 --- a/libyul/backends/evm/EVMDialect.cpp +++ b/libyul/backends/evm/EVMDialect.cpp @@ -23,19 +23,14 @@ #include #include -#include #include #include #include -#include #include #include #include #include -#include -#include - #include using namespace std::string_literals; @@ -461,106 +456,3 @@ BuiltinFunctionForEVM const* EVMDialect::verbatimFunction(size_t _arguments, siz } return function.get(); } - -EVMDialectTyped::EVMDialectTyped(langutil::EVMVersion _evmVersion, bool _objectAccess): - EVMDialect(_evmVersion, _objectAccess) -{ - defaultType = "u256"_yulname; - boolType = "bool"_yulname; - types = {defaultType, boolType}; - - // Set all types to ``defaultType`` - for (auto& fun: m_functions) - { - for (auto& p: fun.second.parameters) - p = defaultType; - for (auto& r: fun.second.returns) - r = defaultType; - } - - m_functions["lt"_yulname].returns = {"bool"_yulname}; - m_functions["gt"_yulname].returns = {"bool"_yulname}; - m_functions["slt"_yulname].returns = {"bool"_yulname}; - m_functions["sgt"_yulname].returns = {"bool"_yulname}; - m_functions["eq"_yulname].returns = {"bool"_yulname}; - - // "not" and "bitnot" replace "iszero" and "not" - m_functions["bitnot"_yulname] = m_functions["not"_yulname]; - m_functions["bitnot"_yulname].name = "bitnot"_yulname; - m_functions["not"_yulname] = m_functions["iszero"_yulname]; - m_functions["not"_yulname].name = "not"_yulname; - m_functions["not"_yulname].returns = {"bool"_yulname}; - m_functions["not"_yulname].parameters = {"bool"_yulname}; - m_functions.erase("iszero"_yulname); - - m_functions["bitand"_yulname] = m_functions["and"_yulname]; - m_functions["bitand"_yulname].name = "bitand"_yulname; - m_functions["bitor"_yulname] = m_functions["or"_yulname]; - m_functions["bitor"_yulname].name = "bitor"_yulname; - m_functions["bitxor"_yulname] = m_functions["xor"_yulname]; - m_functions["bitxor"_yulname].name = "bitxor"_yulname; - m_functions["and"_yulname].parameters = {"bool"_yulname, "bool"_yulname}; - m_functions["and"_yulname].returns = {"bool"_yulname}; - m_functions["or"_yulname].parameters = {"bool"_yulname, "bool"_yulname}; - m_functions["or"_yulname].returns = {"bool"_yulname}; - m_functions["xor"_yulname].parameters = {"bool"_yulname, "bool"_yulname}; - m_functions["xor"_yulname].returns = {"bool"_yulname}; - m_functions["popbool"_yulname] = m_functions["pop"_yulname]; - m_functions["popbool"_yulname].name = "popbool"_yulname; - m_functions["popbool"_yulname].parameters = {"bool"_yulname}; - m_functions.insert(createFunction("bool_to_u256", 1, 1, {}, {}, []( - FunctionCall const&, - AbstractAssembly&, - BuiltinContext& - ) {})); - m_functions["bool_to_u256"_yulname].parameters = {"bool"_yulname}; - m_functions["bool_to_u256"_yulname].returns = {"u256"_yulname}; - m_functions.insert(createFunction("u256_to_bool", 1, 1, {}, {}, []( - FunctionCall const&, - AbstractAssembly& _assembly, - BuiltinContext& - ) { - // TODO this should use a Panic. - // A value larger than 1 causes an invalid instruction. - _assembly.appendConstant(2); - _assembly.appendInstruction(evmasm::Instruction::DUP2); - _assembly.appendInstruction(evmasm::Instruction::LT); - AbstractAssembly::LabelID inRange = _assembly.newLabelId(); - _assembly.appendJumpToIf(inRange); - _assembly.appendInstruction(evmasm::Instruction::INVALID); - _assembly.appendLabel(inRange); - })); - m_functions["u256_to_bool"_yulname].parameters = {"u256"_yulname}; - m_functions["u256_to_bool"_yulname].returns = {"bool"_yulname}; -} - -BuiltinFunctionForEVM const* EVMDialectTyped::discardFunction(YulName _type) const -{ - if (_type == "bool"_yulname) - return builtin("popbool"_yulname); - else - { - yulAssert(_type == defaultType, ""); - return builtin("pop"_yulname); - } -} - -BuiltinFunctionForEVM const* EVMDialectTyped::equalityFunction(YulName _type) const -{ - if (_type == "bool"_yulname) - return nullptr; - else - { - yulAssert(_type == defaultType, ""); - return builtin("eq"_yulname); - } -} - -EVMDialectTyped const& EVMDialectTyped::instance(langutil::EVMVersion _version) -{ - static std::map> dialects; - static YulStringRepository::ResetCallback callback{[&] { dialects.clear(); }}; - if (!dialects[_version]) - dialects[_version] = std::make_unique(_version, true); - return *dialects[_version]; -} diff --git a/libyul/backends/evm/EVMDialect.h b/libyul/backends/evm/EVMDialect.h index 7db1ec09d32b..89df944966f0 100644 --- a/libyul/backends/evm/EVMDialect.h +++ b/libyul/backends/evm/EVMDialect.h @@ -102,26 +102,4 @@ struct EVMDialect: public Dialect std::set m_reserved; }; -/** - * EVM dialect with types u256 (default) and bool. - * Difference to EVMDialect: - * - All comparison functions return type bool - * - bitwise operations are called bitor, bitand, bitxor and bitnot - * - and, or, xor take bool and return bool - * - iszero is replaced by not, which takes bool and returns bool - * - there are conversion functions bool_to_u256 and u256_to_bool. - * - there is popbool - */ -struct EVMDialectTyped: public EVMDialect -{ - /// Constructor, should only be used internally. Use the factory function below. - EVMDialectTyped(langutil::EVMVersion _evmVersion, bool _objectAccess); - - BuiltinFunctionForEVM const* discardFunction(YulName _type) const override; - BuiltinFunctionForEVM const* equalityFunction(YulName _type) const override; - BuiltinFunctionForEVM const* booleanNegationFunction() const override { return builtin("not"_yulname); } - - static EVMDialectTyped const& instance(langutil::EVMVersion _version); -}; - } From 65127220bfab7a6b1b185fa07abbc2f912ad8793 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Tue, 13 Aug 2024 08:51:59 +0200 Subject: [PATCH 0345/1022] Yul tests: Adapt or remove EVMDialectTyped tests --- test/libyul/Common.cpp | 19 +-- test/libyul/Common.h | 6 +- test/libyul/CompilabilityChecker.cpp | 2 +- test/libyul/ControlFlowSideEffectsTest.cpp | 2 +- test/libyul/FunctionSideEffects.cpp | 2 +- test/libyul/Inliner.cpp | 36 +++-- test/libyul/Metrics.cpp | 2 +- test/libyul/Parser.cpp | 157 ++++++++------------- 8 files changed, 89 insertions(+), 137 deletions(-) diff --git a/test/libyul/Common.cpp b/test/libyul/Common.cpp index 01956e7f584f..a0c00c90d781 100644 --- a/test/libyul/Common.cpp +++ b/test/libyul/Common.cpp @@ -50,12 +50,12 @@ Dialect const& defaultDialect() } } -std::pair, std::shared_ptr> yul::test::parse(std::string const& _source, bool _yul) +std::pair, std::shared_ptr> yul::test::parse(std::string const& _source) { YulStack stack( solidity::test::CommonOptions::get().evmVersion(), solidity::test::CommonOptions::get().eofVersion(), - _yul ? YulStack::Language::Yul : YulStack::Language::StrictAssembly, + YulStack::Language::StrictAssembly, solidity::test::CommonOptions::get().optimize ? solidity::frontend::OptimiserSettings::standard() : solidity::frontend::OptimiserSettings::minimal(), @@ -88,17 +88,17 @@ std::pair, std::shared_ptr> yul::t return {std::move(parserResult), std::move(analysisInfo)}; } -yul::Block yul::test::disambiguate(std::string const& _source, bool _yul) +yul::Block yul::test::disambiguate(std::string const& _source) { - auto result = parse(_source, _yul); + auto result = parse(_source); return std::get(Disambiguator(defaultDialect(), *result.second, {})(result.first->root())); } -std::string yul::test::format(std::string const& _source, bool _yul) +std::string yul::test::format(std::string const& _source) { auto const version = solidity::test::CommonOptions::get().evmVersion(); - Dialect const& dialect = _yul ? EVMDialectTyped::instance(version) : EVMDialect::strictAssemblyForEVMObjects(version); - return yul::AsmPrinter(yul::AsmPrinter::TypePrinting::Full, dialect)(parse(_source, _yul).first->root()); + Dialect const& dialect = EVMDialect::strictAssemblyForEVMObjects(version); + return yul::AsmPrinter(yul::AsmPrinter::TypePrinting::Full, dialect)(parse(_source).first->root()); } namespace @@ -108,11 +108,6 @@ std::map const "evm", [](langutil::EVMVersion _evmVersion) -> yul::Dialect const& { return yul::EVMDialect::strictAssemblyForEVMObjects(_evmVersion); } - }, - { - "evmTyped", - [](langutil::EVMVersion _evmVersion) -> yul::Dialect const& - { return yul::EVMDialectTyped::instance(_evmVersion); } } }; diff --git a/test/libyul/Common.h b/test/libyul/Common.h index 14d73d77e18c..c87f1c68be17 100644 --- a/test/libyul/Common.h +++ b/test/libyul/Common.h @@ -46,13 +46,13 @@ namespace solidity::yul::test { std::pair, std::shared_ptr> -parse(std::string const& _source, bool _yul = true); +parse(std::string const& _source); std::pair, std::shared_ptr> parse(std::string const& _source, Dialect const& _dialect, langutil::ErrorList& _errors); -Block disambiguate(std::string const& _source, bool _yul = true); -std::string format(std::string const& _source, bool _yul = true); +Block disambiguate(std::string const& _source); +std::string format(std::string const& _source); solidity::yul::Dialect const& dialect(std::string const& _name, langutil::EVMVersion _evmVersion); diff --git a/test/libyul/CompilabilityChecker.cpp b/test/libyul/CompilabilityChecker.cpp index 5b64b5e5d3cc..13788b75f8ff 100644 --- a/test/libyul/CompilabilityChecker.cpp +++ b/test/libyul/CompilabilityChecker.cpp @@ -35,7 +35,7 @@ namespace std::string check(std::string const& _input) { Object obj; - auto parsingResult = yul::test::parse(_input, false); + auto parsingResult = yul::test::parse(_input); obj.setCode(parsingResult.first, parsingResult.second); BOOST_REQUIRE(obj.hasCode()); auto functions = CompilabilityChecker(EVMDialect::strictAssemblyForEVM(solidity::test::CommonOptions::get().evmVersion()), obj, true).stackDeficit; diff --git a/test/libyul/ControlFlowSideEffectsTest.cpp b/test/libyul/ControlFlowSideEffectsTest.cpp index 20df176a393c..3ad70f5a02ce 100644 --- a/test/libyul/ControlFlowSideEffectsTest.cpp +++ b/test/libyul/ControlFlowSideEffectsTest.cpp @@ -57,7 +57,7 @@ ControlFlowSideEffectsTest::ControlFlowSideEffectsTest(std::string const& _filen TestCase::TestResult ControlFlowSideEffectsTest::run(std::ostream& _stream, std::string const& _linePrefix, bool _formatted) { Object obj; - auto parsingResult = yul::test::parse(m_source, false); + auto parsingResult = yul::test::parse(m_source); obj.setCode(parsingResult.first, parsingResult.second); if (!obj.hasCode()) BOOST_THROW_EXCEPTION(std::runtime_error("Parsing input failed.")); diff --git a/test/libyul/FunctionSideEffects.cpp b/test/libyul/FunctionSideEffects.cpp index a39024d278ef..9d6599f42bc1 100644 --- a/test/libyul/FunctionSideEffects.cpp +++ b/test/libyul/FunctionSideEffects.cpp @@ -83,7 +83,7 @@ FunctionSideEffects::FunctionSideEffects(std::string const& _filename): TestCase::TestResult FunctionSideEffects::run(std::ostream& _stream, std::string const& _linePrefix, bool _formatted) { Object obj; - auto parsingResult = yul::test::parse(m_source, false); + auto parsingResult = yul::test::parse(m_source); obj.setCode(parsingResult.first, parsingResult.second); if (!obj.hasCode()) BOOST_THROW_EXCEPTION(std::runtime_error("Parsing input failed.")); diff --git a/test/libyul/Inliner.cpp b/test/libyul/Inliner.cpp index 6f622b41a4f4..f6da0c95c2b3 100644 --- a/test/libyul/Inliner.cpp +++ b/test/libyul/Inliner.cpp @@ -24,8 +24,6 @@ #include #include -#include -#include #include #include @@ -65,44 +63,44 @@ BOOST_AUTO_TEST_CASE(smoke_test) BOOST_AUTO_TEST_CASE(simple) { - BOOST_CHECK_EQUAL(inlinableFunctions("{ function f() -> x:u256 { x := 2:u256 } }"), "f"); + BOOST_CHECK_EQUAL(inlinableFunctions("{ function f() -> x { x := 2 } }"), "f"); BOOST_CHECK_EQUAL(inlinableFunctions("{" - "function g(a:u256) -> b:u256 { b := a }" - "function f() -> x:u256 { x := g(2:u256) }" + "function g(a) -> b { b := a }" + "function f() -> x { x := g(2) }" "}"), "g,f"); } BOOST_AUTO_TEST_CASE(simple_inside_structures) { BOOST_CHECK_EQUAL(inlinableFunctions("{" - "switch 2:u256 " - "case 2:u256 {" - "function g(a:u256) -> b:u256 { b := a }" - "function f() -> x:u256 { x := g(2:u256) }" + "switch 2 " + "case 2 {" + "function g(a) -> b { b := a }" + "function f() -> x { x := g(2) }" "}" "}"), "g,f"); BOOST_CHECK_EQUAL(inlinableFunctions("{" - "function g(a:u256) -> b:u256 { b := a }" + "function g(a) -> b { b := a }" "for {" "} true {" - "function f() -> x:u256 { x := g(2:u256) }" + "function f() -> x { x := g(2) }" "}" "{" - "function h() -> y:u256 { y := 2:u256 }" + "function h() -> y { y := 2 }" "}" "}"), "h,g,f"); } BOOST_AUTO_TEST_CASE(negative) { - BOOST_CHECK_EQUAL(inlinableFunctions("{ function f() -> x:u256 { } }"), ""); - BOOST_CHECK_EQUAL(inlinableFunctions("{ function f() -> x:u256 { x := 2:u256 {} } }"), ""); - BOOST_CHECK_EQUAL(inlinableFunctions("{ function f() -> x:u256 { x := f() } }"), ""); - BOOST_CHECK_EQUAL(inlinableFunctions("{ function f() -> x:u256 { x := x } }"), ""); - BOOST_CHECK_EQUAL(inlinableFunctions("{ function f() -> x:u256, y:u256 { x := 2:u256 } }"), ""); + BOOST_CHECK_EQUAL(inlinableFunctions("{ function f() -> x { } }"), ""); + BOOST_CHECK_EQUAL(inlinableFunctions("{ function f() -> x { x := 2 {} } }"), ""); + BOOST_CHECK_EQUAL(inlinableFunctions("{ function f() -> x { x := f() } }"), ""); + BOOST_CHECK_EQUAL(inlinableFunctions("{ function f() -> x { x := x } }"), ""); + BOOST_CHECK_EQUAL(inlinableFunctions("{ function f() -> x, y { x := 2 } }"), ""); BOOST_CHECK_EQUAL(inlinableFunctions( - "{ function g() -> x:u256, y:u256 {} function f(y:u256) -> x:u256 { x,y := g() } }"), ""); - BOOST_CHECK_EQUAL(inlinableFunctions("{ function f(y:u256) -> x:u256 { y := 2:u256 } }"), ""); + "{ function g() -> x, y {} function f(y) -> x { x,y := g() } }"), ""); + BOOST_CHECK_EQUAL(inlinableFunctions("{ function f(y) -> x { y := 2 } }"), ""); } diff --git a/test/libyul/Metrics.cpp b/test/libyul/Metrics.cpp index bf09a1c2beec..5c7b5fc34de0 100644 --- a/test/libyul/Metrics.cpp +++ b/test/libyul/Metrics.cpp @@ -38,7 +38,7 @@ namespace size_t codeSize(std::string const& _source, CodeWeights const _weights = {}) { - std::shared_ptr ast = parse(_source, false).first; + std::shared_ptr ast = parse(_source).first; BOOST_REQUIRE(ast); return CodeSize::codeSize(ast->root(), _weights); } diff --git a/test/libyul/Parser.cpp b/test/libyul/Parser.cpp index 5ce8b449b578..2a2f2809296b 100644 --- a/test/libyul/Parser.cpp +++ b/test/libyul/Parser.cpp @@ -148,47 +148,6 @@ BOOST_AUTO_TEST_CASE(builtins_analysis) CHECK_ERROR_DIALECT("{ let a, b := builtin(1, 2) }", DeclarationError, "Variable count mismatch for declaration of \"a, b\": 2 variables and 3 values.", dialect); } -BOOST_AUTO_TEST_CASE(default_types_set) -{ - ErrorList errorList; - ErrorReporter reporter(errorList); - std::shared_ptr result = parse( - "{" - "let x:bool := true:bool " - "let z:bool := true " - "let y := add(1, 2) " - "switch y case 0 {} default {} " - "}", - EVMDialectTyped::instance(EVMVersion{}), - reporter - ); - BOOST_REQUIRE(!!result && errorList.size() == 0); - - // All types are printed. - BOOST_CHECK_EQUAL(AsmPrinter(AsmPrinter::TypePrinting::Full, EVMDialectTyped::instance(EVMVersion()))(result->root()), - "{\n" - " let x:bool := true:bool\n" - " let z:bool := true:bool\n" - " let y:u256 := add(1:u256, 2:u256)\n" - " switch y\n" - " case 0:u256 { }\n" - " default { }\n" - "}" - ); - - // Now the default types should be omitted. - BOOST_CHECK_EQUAL(AsmPrinter(AsmPrinter::TypePrinting::OmitDefault, EVMDialectTyped::instance(EVMVersion()))(result->root()), - "{\n" - " let x:bool := true\n" - " let z:bool := true\n" - " let y := add(1, 2)\n" - " switch y\n" - " case 0 { }\n" - " default { }\n" - "}" - ); -} - #define CHECK_LOCATION(_actual, _sourceName, _start, _end) \ do { \ BOOST_CHECK_EQUAL((_sourceName), ((_actual).sourceName ? *(_actual).sourceName : "")); \ @@ -203,7 +162,7 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_empty_block) auto const sourceText = "/// @src 0:234:543\n" "{}\n"; - EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.size() == 0); CHECK_LOCATION(result->root().debugData->originLocation, "source0", 234, 543); @@ -216,12 +175,12 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_block_with_children) auto const sourceText = "/// @src 0:234:543\n" "{\n" - "let x:bool := true:bool\n" + "let x := true\n" "/// @src 0:123:432\n" - "let z:bool := true\n" + "let z := true\n" "let y := add(1, 2)\n" "}\n"; - EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result); CHECK_LOCATION(result->root().debugData->originLocation, "source0", 234, 543); @@ -239,12 +198,12 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_block_different_sources) auto const sourceText = "/// @src 0:234:543\n" "{\n" - "let x:bool := true:bool\n" + "let x := true\n" "/// @src 1:123:432\n" - "let z:bool := true\n" + "let z := true\n" "let y := add(1, 2)\n" "}\n"; - EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.size() == 0); CHECK_LOCATION(result->root().debugData->originLocation, "source0", 234, 543); @@ -266,7 +225,7 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_block_nested) "/// @src 0:343:434\n" "switch y case 0 {} default {}\n" "}\n"; - EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.size() == 0); CHECK_LOCATION(result->root().debugData->originLocation, "source0", 234, 543); @@ -290,7 +249,7 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_block_switch_case) " let z := add(3, 4)\n" "}\n" "}\n"; - EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.size() == 0); CHECK_LOCATION(result->root().debugData->originLocation, "source0", 234, 543); @@ -317,12 +276,12 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_inherit_into_outer_scope) "{\n" "{\n" "/// @src 0:123:432\n" - "let x:bool := true:bool\n" + "let x := true\n" "}\n" - "let z:bool := true\n" + "let z := true\n" "let y := add(1, 2)\n" "}\n"; - EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.size() == 0); @@ -349,11 +308,11 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_assign_empty) auto const sourceText = "{\n" "/// @src 0:123:432\n" - "let a:bool\n" + "let a\n" "/// @src 1:1:10\n" - "a := true:bool\n" + "a := true\n" "}\n"; - EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.size() == 0); // should still parse BOOST_REQUIRE_EQUAL(2, result->root().statements.size()); @@ -369,12 +328,12 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_invalid_source_index) auto const sourceText = "{\n" "/// @src 1:123:432\n" - "let a:bool := true:bool\n" + "let a := true\n" "/// @src 2345:0:8\n" - "let b:bool := true:bool\n" + "let b := true\n" "\n" "}\n"; - EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result); // should still parse BOOST_REQUIRE(errorList.size() == 1); @@ -390,11 +349,11 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_mixed_locations_1) auto const sourceText = "{\n" "/// @src 0:123:432\n" - "let x:bool \n" + "let x \n" "/// @src 0:234:2026\n" - ":= true:bool\n" + ":= true\n" "}\n"; - EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.size() == 0); @@ -417,7 +376,7 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_mixed_locations_2) 2) } )"; - EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.size() == 0); BOOST_REQUIRE_EQUAL(1, result->root().statements.size()); @@ -451,7 +410,7 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_mixed_locations_3) mstore(1, 2) // FunctionCall } )"; - EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.size() == 0); BOOST_REQUIRE_EQUAL(2, result->root().statements.size()); @@ -484,10 +443,10 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_invalid_comments_after_valid) { /// @src 0:420:680 /// @invalid - let a:bool := true + let a := true } )"; - EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.size() == 0); BOOST_REQUIRE_EQUAL(1, result->root().statements.size()); @@ -506,7 +465,7 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_invalid_suffix) /// @src 0:420:680foo {} )"; - EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result); BOOST_REQUIRE(errorList.size() == 1); @@ -523,7 +482,7 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_invalid_prefix) /// abc@src 0:111:222 {} )"; - EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.size() == 0); CHECK_LOCATION(result->root().debugData->originLocation, "", -1, -1); @@ -537,7 +496,7 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_unspecified) /// @src -1:-1:-1 {} )"; - EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.size() == 0); CHECK_LOCATION(result->root().debugData->originLocation, "", -1, -1); @@ -551,7 +510,7 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_non_integer) /// @src a:b:c {} )"; - EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result); BOOST_REQUIRE(errorList.size() == 1); @@ -568,7 +527,7 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_bad_integer) /// @src 111111111111111111111:222222222222222222222:333333333333333333333 {} )"; - EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result); BOOST_REQUIRE(errorList.size() == 1); @@ -586,10 +545,10 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_ensure_last_match) { /// @src 1:10:20 /// @src 0:30:40 - let x:bool := true + let x := true } )"; - EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.size() == 0); BOOST_REQUIRE(std::holds_alternative(result->root().statements.at(0))); @@ -607,7 +566,7 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_two_locations_no_whitespace) /// @src 0:111:222@src 1:333:444 {} )"; - EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result); BOOST_REQUIRE(errorList.size() == 1); @@ -624,7 +583,7 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_two_locations_separated_with_single_s /// @src 0:111:222 @src 1:333:444 {} )"; - EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.size() == 0); CHECK_LOCATION(result->root().debugData->originLocation, "source1", 333, 444); @@ -635,7 +594,7 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_leading_trailing_whitespace) ErrorList errorList; ErrorReporter reporter(errorList); auto const sourceText = "/// @src 0:111:222 \n{}"; - EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.size() == 0); CHECK_LOCATION(result->root().debugData->originLocation, "source0", 111, 222); @@ -649,10 +608,10 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_reference_original_sloc) /// @src 1:2:3 { /// @src -1:10:20 - let x:bool := true + let x := true } )"; - EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.size() == 0); BOOST_REQUIRE(std::holds_alternative(result->root().statements.at(0))); @@ -674,7 +633,7 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_with_code_snippets) let y := /** @src 1:96:165 "contract D {..." */ 128 } )~~~"; - EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.size() == 0); BOOST_REQUIRE_EQUAL(result->root().statements.size(), 2); @@ -699,7 +658,7 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_with_code_snippets_empty_snippet) /// @src 0:111:222 "" {} )"; - EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.size() == 0); CHECK_LOCATION(result->root().debugData->originLocation, "source0", 111, 222); @@ -713,7 +672,7 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_with_code_snippets_no_whitespace_befo /// @src 0:111:222"abc" def {} )"; - EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result); BOOST_REQUIRE(errorList.size() == 1); @@ -730,7 +689,7 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_with_code_snippets_no_whitespace_afte /// @src 0:111:222 "abc"def {} )"; - EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.size() == 0); CHECK_LOCATION(result->root().debugData->originLocation, "source0", 111, 222); @@ -744,7 +703,7 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_two_locations_with_snippets_no_whites /// @src 0:111:222 "abc"@src 1:333:444 "abc" {} )"; - EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.size() == 0); CHECK_LOCATION(result->root().debugData->originLocation, "source1", 333, 444); @@ -758,7 +717,7 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_two_locations_with_snippets_untermina /// @src 0:111:222 " abc @src 1:333:444 {} )"; - EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result); BOOST_REQUIRE(errorList.size() == 1); @@ -776,7 +735,7 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_single_quote) /// {} )"; - EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result); BOOST_REQUIRE(errorList.size() == 1); @@ -793,7 +752,7 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_two_snippets_with_hex_comment) /// @src 0:111:222 hex"abc"@src 1:333:444 "abc" {} )"; - EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.size() == 0); // the second source location is not parsed as such, as the hex string isn't interpreted as snippet but @@ -809,7 +768,7 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_invalid_escapes) /// @src 0:111:222 "\n\\x\x\w\uö\xy\z\y\fq" {} )"; - EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.size() == 0); CHECK_LOCATION(result->root().debugData->originLocation, "source0", 111, 222); @@ -824,7 +783,7 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_single_quote_snippet_with_whitespaces /// @src 1 : 222 : 333 '\x33\u1234\t\n' {} )"; - EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.size() == 0); CHECK_LOCATION(result->root().debugData->originLocation, "source1", 222, 333); @@ -839,7 +798,7 @@ BOOST_DATA_TEST_CASE(customSourceLocations_scanner_errors_outside_string_lits_ar /// @src 1:222:333 {{}} )", invalid); - EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.empty()); CHECK_LOCATION(result->root().debugData->originLocation, "source1", 222, 333); @@ -857,7 +816,7 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_multi_line_source_loc) /// " @src 0:333:444 {} )"; - EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.empty()); CHECK_LOCATION(result->root().debugData->originLocation, "source0", 333, 444); @@ -875,7 +834,7 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_with_code_snippets_with_nested_locati let y := /** @src 1:96:165 "function f() internal { \"\/** @src 0:6:7 *\/\"; }" */ 128 } )~~~"; - EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.size() == 0); BOOST_REQUIRE_EQUAL(result->root().statements.size(), 2); @@ -904,7 +863,7 @@ BOOST_AUTO_TEST_CASE(astid) mstore(1, 2) } )"; - EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result); BOOST_CHECK(result->root().debugData->astID == int64_t(7)); @@ -926,7 +885,7 @@ BOOST_AUTO_TEST_CASE(astid_reset) mstore(1, 2) } )"; - EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result); BOOST_CHECK(result->root().debugData->astID == int64_t(7)); @@ -944,7 +903,7 @@ BOOST_AUTO_TEST_CASE(astid_multi) /// @src -1:-1:-1 @ast-id 7 @src 1:1:1 @ast-id 8 {} )"; - EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result); BOOST_CHECK(result->root().debugData->astID == int64_t(8)); @@ -958,7 +917,7 @@ BOOST_AUTO_TEST_CASE(astid_invalid) /// @src -1:-1:-1 @ast-id abc @src 1:1:1 {} )"; - EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result); BOOST_REQUIRE(errorList.size() == 1); @@ -975,7 +934,7 @@ BOOST_AUTO_TEST_CASE(astid_too_large) /// @ast-id 9223372036854775808 {} )"; - EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result); BOOST_REQUIRE(errorList.size() == 1); @@ -991,7 +950,7 @@ BOOST_AUTO_TEST_CASE(astid_way_too_large) /// @ast-id 999999999999999999999999999999999999999 {} )"; - EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result); BOOST_REQUIRE(errorList.size() == 1); @@ -1007,7 +966,7 @@ BOOST_AUTO_TEST_CASE(astid_not_fully_numeric) /// @ast-id 9x {} )"; - EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result); BOOST_REQUIRE(errorList.size() == 1); @@ -1029,7 +988,7 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_multiple_src_tags_on_one_line) "\n" " let x := 123\n" "}\n"; - EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.size() == 0); BOOST_REQUIRE_EQUAL(result->root().statements.size(), 1); From 40e05d6e209a6d03afe2085d26a322f6ac8fc56c Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Tue, 13 Aug 2024 08:54:30 +0200 Subject: [PATCH 0346/1022] Yul optimizer tests: Update test expectations to use evm instead of evmTyped --- .../add_correct_type.yul | 19 -------------- .../disambiguator/for_statement.yul | 12 ++++----- .../disambiguator/funtion_call.yul | 8 +++--- .../disambiguator/if_statement.yul | 12 ++++----- .../disambiguator/long_names.yul | 4 +-- .../disambiguator/smoke_evmTyped.yul | 7 ----- .../disambiguator/switch_statement.yul | 10 +++---- .../disambiguator/variables.yul | 4 +-- .../disambiguator/variables_clash.yul | 4 +-- .../variables_inside_functions.yul | 8 +++--- .../expressionInliner/simple.yul | 6 ++--- .../expressionInliner/with_args.yul | 6 ++--- .../fullInliner/multi_return_typed.yul | 23 ---------------- .../functionGrouper/empty_block.yul | 6 ++--- .../functionGrouper/multi_fun_mixed.yul | 10 +++---- .../functionGrouper/nested_fun.yul | 10 +++---- .../functionGrouper/single_fun.yul | 4 +-- .../functionHoister/empty_block.yul | 10 +++---- .../functionHoister/multi_mixed.yul | 12 ++++----- .../functionHoister/nested.yul | 10 +++---- .../functionHoister/single.yul | 4 +-- .../ssaTransform/for_simpler.yul | 24 +++++++++++++++++ .../ssaTransform/switch_no_default_case.yul | 24 +++++++++++++++++ .../yulOptimizerTests/ssaTransform/typed.yul | 20 +++++++------- .../ssaTransform/typed_for.yul | 26 ------------------- .../ssaTransform/typed_switch.yul | 26 ------------------- .../varDeclInitializer/typed.yul | 24 ----------------- 27 files changed, 109 insertions(+), 224 deletions(-) delete mode 100644 test/libyul/yulOptimizerTests/conditionalSimplifier/add_correct_type.yul delete mode 100644 test/libyul/yulOptimizerTests/disambiguator/smoke_evmTyped.yul delete mode 100644 test/libyul/yulOptimizerTests/fullInliner/multi_return_typed.yul create mode 100644 test/libyul/yulOptimizerTests/ssaTransform/for_simpler.yul create mode 100644 test/libyul/yulOptimizerTests/ssaTransform/switch_no_default_case.yul delete mode 100644 test/libyul/yulOptimizerTests/ssaTransform/typed_for.yul delete mode 100644 test/libyul/yulOptimizerTests/ssaTransform/typed_switch.yul delete mode 100644 test/libyul/yulOptimizerTests/varDeclInitializer/typed.yul diff --git a/test/libyul/yulOptimizerTests/conditionalSimplifier/add_correct_type.yul b/test/libyul/yulOptimizerTests/conditionalSimplifier/add_correct_type.yul deleted file mode 100644 index 57785f0b3d08..000000000000 --- a/test/libyul/yulOptimizerTests/conditionalSimplifier/add_correct_type.yul +++ /dev/null @@ -1,19 +0,0 @@ -{ - let y:bool := false - for {} true { } { - if y { break } - } -} -// ==== -// dialect: evmTyped -// ---- -// step: conditionalSimplifier -// -// { -// let y:bool := false -// for { } true { } -// { -// if y { break } -// y := false -// } -// } diff --git a/test/libyul/yulOptimizerTests/disambiguator/for_statement.yul b/test/libyul/yulOptimizerTests/disambiguator/for_statement.yul index fcfbe3242eae..3a01e1ea5c24 100644 --- a/test/libyul/yulOptimizerTests/disambiguator/for_statement.yul +++ b/test/libyul/yulOptimizerTests/disambiguator/for_statement.yul @@ -1,21 +1,19 @@ { - { let a:u256, b:u256 } + { let a, b } { - function eq_function(x: u256, y: u256) -> z: bool {} - for { let a:u256 } eq_function(a, a) { a := a } { - let b:u256 := a + function eq_function(x, y) -> z {} + for { let a } eq_function(a, a) { a := a } { + let b := a } } } -// ==== -// dialect: evmTyped // ---- // step: disambiguator // // { // { let a, b } // { -// function eq_function(x, y) -> z:bool +// function eq_function(x, y) -> z // { } // for { let a_1 } eq_function(a_1, a_1) { a_1 := a_1 } // { let b_2 := a_1 } diff --git a/test/libyul/yulOptimizerTests/disambiguator/funtion_call.yul b/test/libyul/yulOptimizerTests/disambiguator/funtion_call.yul index 7fc51a5fa54b..0c25f3ee5c87 100644 --- a/test/libyul/yulOptimizerTests/disambiguator/funtion_call.yul +++ b/test/libyul/yulOptimizerTests/disambiguator/funtion_call.yul @@ -1,13 +1,11 @@ { - { let a:u256, b:u256, c:u256, d:u256, f:u256 } + { let a, b, c, d, f } { - function f(a:u256) -> c:u256, d:u256 { - let b:u256, c_1:u256 := f(a) + function f(a) -> c, d { + let b, c_1 := f(a) } } } -// ==== -// dialect: evmTyped // ---- // step: disambiguator // diff --git a/test/libyul/yulOptimizerTests/disambiguator/if_statement.yul b/test/libyul/yulOptimizerTests/disambiguator/if_statement.yul index 512d7fc12bbb..e68d9b581b3d 100644 --- a/test/libyul/yulOptimizerTests/disambiguator/if_statement.yul +++ b/test/libyul/yulOptimizerTests/disambiguator/if_statement.yul @@ -1,19 +1,17 @@ { - { let a:u256, b:u256, c:u256 } + { let a, b, c } { - let a:bool - if a { let b:bool := a } + let a + if a { let b := a } } } -// ==== -// dialect: evmTyped // ---- // step: disambiguator // // { // { let a, b, c } // { -// let a_1:bool -// if a_1 { let b_2:bool := a_1 } +// let a_1 +// if a_1 { let b_2 := a_1 } // } // } diff --git a/test/libyul/yulOptimizerTests/disambiguator/long_names.yul b/test/libyul/yulOptimizerTests/disambiguator/long_names.yul index fbd95ef3a2df..1d0530f32a7a 100644 --- a/test/libyul/yulOptimizerTests/disambiguator/long_names.yul +++ b/test/libyul/yulOptimizerTests/disambiguator/long_names.yul @@ -1,6 +1,4 @@ -{ { let aanteuhdaoneudbrgkjiuaothduiathudaoeuh:u256 } { let aanteuhdaoneudbrgkjiuaothduiathudaoeuh:u256 } } -// ==== -// dialect: evmTyped +{ { let aanteuhdaoneudbrgkjiuaothduiathudaoeuh } { let aanteuhdaoneudbrgkjiuaothduiathudaoeuh } } // ---- // step: disambiguator // diff --git a/test/libyul/yulOptimizerTests/disambiguator/smoke_evmTyped.yul b/test/libyul/yulOptimizerTests/disambiguator/smoke_evmTyped.yul deleted file mode 100644 index 481cbb588370..000000000000 --- a/test/libyul/yulOptimizerTests/disambiguator/smoke_evmTyped.yul +++ /dev/null @@ -1,7 +0,0 @@ -{ } -// ==== -// dialect: evmTyped -// ---- -// step: disambiguator -// -// { } diff --git a/test/libyul/yulOptimizerTests/disambiguator/switch_statement.yul b/test/libyul/yulOptimizerTests/disambiguator/switch_statement.yul index 86ea9cba28af..d70a805c3f25 100644 --- a/test/libyul/yulOptimizerTests/disambiguator/switch_statement.yul +++ b/test/libyul/yulOptimizerTests/disambiguator/switch_statement.yul @@ -1,14 +1,12 @@ { - { let a:u256, b:u256, c:u256 } + { let a, b, c } { - let a:u256 + let a switch a - case 0:u256 { let b:u256 := a } - default { let c:u256 := a } + case 0 { let b := a } + default { let c := a } } } -// ==== -// dialect: evmTyped // ---- // step: disambiguator // diff --git a/test/libyul/yulOptimizerTests/disambiguator/variables.yul b/test/libyul/yulOptimizerTests/disambiguator/variables.yul index 743eaf0de6d3..9000903681a2 100644 --- a/test/libyul/yulOptimizerTests/disambiguator/variables.yul +++ b/test/libyul/yulOptimizerTests/disambiguator/variables.yul @@ -1,6 +1,4 @@ -{ { let a:u256 } { let a:u256 } } -// ==== -// dialect: evmTyped +{ { let a } { let a } } // ---- // step: disambiguator // diff --git a/test/libyul/yulOptimizerTests/disambiguator/variables_clash.yul b/test/libyul/yulOptimizerTests/disambiguator/variables_clash.yul index 2a94e47697a6..40ca2b262171 100644 --- a/test/libyul/yulOptimizerTests/disambiguator/variables_clash.yul +++ b/test/libyul/yulOptimizerTests/disambiguator/variables_clash.yul @@ -1,6 +1,4 @@ -{ { let a:u256 let a_1:u256 } { let a:u256 } } -// ==== -// dialect: evmTyped +{ { let a let a_1 } { let a } } // ---- // step: disambiguator // diff --git a/test/libyul/yulOptimizerTests/disambiguator/variables_inside_functions.yul b/test/libyul/yulOptimizerTests/disambiguator/variables_inside_functions.yul index f9e134aff567..f26aaced2ef7 100644 --- a/test/libyul/yulOptimizerTests/disambiguator/variables_inside_functions.yul +++ b/test/libyul/yulOptimizerTests/disambiguator/variables_inside_functions.yul @@ -1,12 +1,10 @@ { - { let c:u256 let b:u256 } - function f(a:u256, c:u256) -> b:u256 { let x:u256 } + { let c let b } + function f(a, c) -> b { let x } { - let a:u256 let x:u256 + let a let x } } -// ==== -// dialect: evmTyped // ---- // step: disambiguator // diff --git a/test/libyul/yulOptimizerTests/expressionInliner/simple.yul b/test/libyul/yulOptimizerTests/expressionInliner/simple.yul index dbc80a8595d7..24508bb7692f 100644 --- a/test/libyul/yulOptimizerTests/expressionInliner/simple.yul +++ b/test/libyul/yulOptimizerTests/expressionInliner/simple.yul @@ -1,9 +1,7 @@ { - function f() -> x:u256 { x := 2:u256 } - let y:u256 := f() + function f() -> x { x := 2 } + let y := f() } -// ==== -// dialect: evmTyped // ---- // step: expressionInliner // diff --git a/test/libyul/yulOptimizerTests/expressionInliner/with_args.yul b/test/libyul/yulOptimizerTests/expressionInliner/with_args.yul index e142f59784d3..caf4cc42eea4 100644 --- a/test/libyul/yulOptimizerTests/expressionInliner/with_args.yul +++ b/test/libyul/yulOptimizerTests/expressionInliner/with_args.yul @@ -1,9 +1,7 @@ { - function f(a:u256) -> x:u256 { x := a } - let y:u256 := f(7:u256) + function f(a) -> x { x := a } + let y := f(7) } -// ==== -// dialect: evmTyped // ---- // step: expressionInliner // diff --git a/test/libyul/yulOptimizerTests/fullInliner/multi_return_typed.yul b/test/libyul/yulOptimizerTests/fullInliner/multi_return_typed.yul deleted file mode 100644 index 143ae35b27b8..000000000000 --- a/test/libyul/yulOptimizerTests/fullInliner/multi_return_typed.yul +++ /dev/null @@ -1,23 +0,0 @@ -{ - function f(a: u256) -> x: bool, y:u256 { - y := mul(a, a) - } - let r: bool, s: u256 := f(mload(3)) -} -// ==== -// dialect: evmTyped -// ---- -// step: fullInliner -// -// { -// { -// let a_3 := mload(3) -// let x_4:bool := false -// let y_5 := 0 -// y_5 := mul(a_3, a_3) -// let r:bool := x_4 -// let s := y_5 -// } -// function f(a) -> x:bool, y -// { y := mul(a, a) } -// } diff --git a/test/libyul/yulOptimizerTests/functionGrouper/empty_block.yul b/test/libyul/yulOptimizerTests/functionGrouper/empty_block.yul index 05fa8d249a17..4d2d2c807f46 100644 --- a/test/libyul/yulOptimizerTests/functionGrouper/empty_block.yul +++ b/test/libyul/yulOptimizerTests/functionGrouper/empty_block.yul @@ -1,6 +1,4 @@ -{ let a:u256 { } function f() -> x:bool { let b:u256 := 4:u256 {} for {} f() {} {} } } -// ==== -// dialect: evmTyped +{ let a { } function f() -> x { let b := 4 {} for {} f() {} {} } } // ---- // step: functionGrouper // @@ -9,7 +7,7 @@ // let a // { } // } -// function f() -> x:bool +// function f() -> x // { // let b := 4 // { } diff --git a/test/libyul/yulOptimizerTests/functionGrouper/multi_fun_mixed.yul b/test/libyul/yulOptimizerTests/functionGrouper/multi_fun_mixed.yul index 5d4eaea5e0b5..9ac43aebdeae 100644 --- a/test/libyul/yulOptimizerTests/functionGrouper/multi_fun_mixed.yul +++ b/test/libyul/yulOptimizerTests/functionGrouper/multi_fun_mixed.yul @@ -1,11 +1,9 @@ { - let a:u256 - function f() { let b:u256 } - let c:u256 function g() { let d:u256 } - let e:u256 + let a + function f() { let b } + let c function g() { let d } + let e } -// ==== -// dialect: evmTyped // ---- // step: functionGrouper // diff --git a/test/libyul/yulOptimizerTests/functionGrouper/nested_fun.yul b/test/libyul/yulOptimizerTests/functionGrouper/nested_fun.yul index 5b8436540110..2c0ac24536a3 100644 --- a/test/libyul/yulOptimizerTests/functionGrouper/nested_fun.yul +++ b/test/libyul/yulOptimizerTests/functionGrouper/nested_fun.yul @@ -1,15 +1,13 @@ { - let a:u256 + let a function f() { - let b:u256 + let b function g() { - let c:u256 + let c } - let d:u256 + let d } } -// ==== -// dialect: evmTyped // ---- // step: functionGrouper // diff --git a/test/libyul/yulOptimizerTests/functionGrouper/single_fun.yul b/test/libyul/yulOptimizerTests/functionGrouper/single_fun.yul index a62b0ddeba3d..295ba1e429d7 100644 --- a/test/libyul/yulOptimizerTests/functionGrouper/single_fun.yul +++ b/test/libyul/yulOptimizerTests/functionGrouper/single_fun.yul @@ -1,8 +1,6 @@ { - let a:u256 function f() {} + let a function f() {} } -// ==== -// dialect: evmTyped // ---- // step: functionGrouper // diff --git a/test/libyul/yulOptimizerTests/functionHoister/empty_block.yul b/test/libyul/yulOptimizerTests/functionHoister/empty_block.yul index 5eed2d2bbe74..a97027bfe812 100644 --- a/test/libyul/yulOptimizerTests/functionHoister/empty_block.yul +++ b/test/libyul/yulOptimizerTests/functionHoister/empty_block.yul @@ -1,20 +1,18 @@ { - let a:u256 + let a { } - function f() -> x:bool { - let b:u256 := 4:u256 + function f() -> x { + let b := 4 { } for {} f() {} {} } } -// ==== -// dialect: evmTyped // ---- // step: functionHoister // // { // let a -// function f() -> x:bool +// function f() -> x // { // let b := 4 // for { } f() { } diff --git a/test/libyul/yulOptimizerTests/functionHoister/multi_mixed.yul b/test/libyul/yulOptimizerTests/functionHoister/multi_mixed.yul index fc6168ce96ef..22feac222f57 100644 --- a/test/libyul/yulOptimizerTests/functionHoister/multi_mixed.yul +++ b/test/libyul/yulOptimizerTests/functionHoister/multi_mixed.yul @@ -1,12 +1,10 @@ { - let a:u256 - function f() { let b:u256 } - let c:u256 - function g() { let d:u256 } - let e:u256 + let a + function f() { let b } + let c + function g() { let d } + let e } -// ==== -// dialect: evmTyped // ---- // step: functionHoister // diff --git a/test/libyul/yulOptimizerTests/functionHoister/nested.yul b/test/libyul/yulOptimizerTests/functionHoister/nested.yul index 65486dc6c5b3..c7182f6074db 100644 --- a/test/libyul/yulOptimizerTests/functionHoister/nested.yul +++ b/test/libyul/yulOptimizerTests/functionHoister/nested.yul @@ -1,13 +1,11 @@ { - let a:u256 + let a function f() { - let b:u256 - function g() { let c:u256 } - let d:u256 + let b + function g() { let c } + let d } } -// ==== -// dialect: evmTyped // ---- // step: functionHoister // diff --git a/test/libyul/yulOptimizerTests/functionHoister/single.yul b/test/libyul/yulOptimizerTests/functionHoister/single.yul index e939ecb85503..e44b41ee2f62 100644 --- a/test/libyul/yulOptimizerTests/functionHoister/single.yul +++ b/test/libyul/yulOptimizerTests/functionHoister/single.yul @@ -1,9 +1,7 @@ { - let a:u256 + let a function f() {} } -// ==== -// dialect: evmTyped // ---- // step: functionHoister // diff --git a/test/libyul/yulOptimizerTests/ssaTransform/for_simpler.yul b/test/libyul/yulOptimizerTests/ssaTransform/for_simpler.yul new file mode 100644 index 000000000000..82ef5a16be13 --- /dev/null +++ b/test/libyul/yulOptimizerTests/ssaTransform/for_simpler.yul @@ -0,0 +1,24 @@ +{ + let b := true + let c := false + for {} b {} { + c := true + } + let d := c +} +// ---- +// step: ssaTransform +// +// { +// let b := true +// let c_1 := false +// let c := c_1 +// for { } b { } +// { +// let c_3 := c +// let c_2 := true +// c := c_2 +// } +// let c_4 := c +// let d := c_4 +// } diff --git a/test/libyul/yulOptimizerTests/ssaTransform/switch_no_default_case.yul b/test/libyul/yulOptimizerTests/ssaTransform/switch_no_default_case.yul new file mode 100644 index 000000000000..18168479b6e9 --- /dev/null +++ b/test/libyul/yulOptimizerTests/ssaTransform/switch_no_default_case.yul @@ -0,0 +1,24 @@ +{ + let b := true + let c := false + switch b + case true { c := true} + case false { } + let d := c +} +// ---- +// step: ssaTransform +// +// { +// let b := true +// let c_1 := false +// let c := c_1 +// switch b +// case true { +// let c_2 := true +// c := c_2 +// } +// case false { } +// let c_3 := c +// let d := c_3 +// } diff --git a/test/libyul/yulOptimizerTests/ssaTransform/typed.yul b/test/libyul/yulOptimizerTests/ssaTransform/typed.yul index 4b1aa164371c..4b722e25cc9d 100644 --- a/test/libyul/yulOptimizerTests/ssaTransform/typed.yul +++ b/test/libyul/yulOptimizerTests/ssaTransform/typed.yul @@ -1,10 +1,10 @@ { - let b:bool := true - let c:bool := false + let b := true + let c := false c := b b := false - let a:u256 := 1 + let a := 1 a := add(a, 1) if c { a := add(a, 1) @@ -12,19 +12,17 @@ a := add(a, 1) mstore(a, 1) } -// ==== -// dialect: evmTyped // ---- // step: ssaTransform // // { -// let b_1:bool := true -// let b:bool := b_1 -// let c_2:bool := false -// let c:bool := c_2 -// let c_3:bool := b_1 +// let b_1 := true +// let b := b_1 +// let c_2 := false +// let c := c_2 +// let c_3 := b_1 // c := c_3 -// let b_4:bool := false +// let b_4 := false // b := b_4 // let a_5 := 1 // let a := a_5 diff --git a/test/libyul/yulOptimizerTests/ssaTransform/typed_for.yul b/test/libyul/yulOptimizerTests/ssaTransform/typed_for.yul deleted file mode 100644 index 596f56cb0369..000000000000 --- a/test/libyul/yulOptimizerTests/ssaTransform/typed_for.yul +++ /dev/null @@ -1,26 +0,0 @@ -{ - let b:bool := true - let c:bool := false - for {} b {} { - c := true - } - let d: bool := c -} -// ==== -// dialect: evmTyped -// ---- -// step: ssaTransform -// -// { -// let b:bool := true -// let c_1:bool := false -// let c:bool := c_1 -// for { } b { } -// { -// let c_3:bool := c -// let c_2:bool := true -// c := c_2 -// } -// let c_4:bool := c -// let d:bool := c_4 -// } diff --git a/test/libyul/yulOptimizerTests/ssaTransform/typed_switch.yul b/test/libyul/yulOptimizerTests/ssaTransform/typed_switch.yul deleted file mode 100644 index b87b5dbbc3e5..000000000000 --- a/test/libyul/yulOptimizerTests/ssaTransform/typed_switch.yul +++ /dev/null @@ -1,26 +0,0 @@ -{ - let b:bool := true - let c:bool := false - switch b - case true { c := true} - case false { } - let d: bool := c -} -// ==== -// dialect: evmTyped -// ---- -// step: ssaTransform -// -// { -// let b:bool := true -// let c_1:bool := false -// let c:bool := c_1 -// switch b -// case true { -// let c_2:bool := true -// c := c_2 -// } -// case false { } -// let c_3:bool := c -// let d:bool := c_3 -// } diff --git a/test/libyul/yulOptimizerTests/varDeclInitializer/typed.yul b/test/libyul/yulOptimizerTests/varDeclInitializer/typed.yul deleted file mode 100644 index 069c68cab89e..000000000000 --- a/test/libyul/yulOptimizerTests/varDeclInitializer/typed.yul +++ /dev/null @@ -1,24 +0,0 @@ -{ - let a1 - let a2: bool - let b1, b2: bool - function f(a:u256, b:u256, c:bool) -> r:bool, t { - let x1: bool, x2 - } -} -// ==== -// dialect: evmTyped -// ---- -// step: varDeclInitializer -// -// { -// let a1 := 0 -// let a2:bool := false -// let b1 := 0 -// let b2:bool := false -// function f(a, b, c:bool) -> r:bool, t -// { -// let x1:bool := false -// let x2 := 0 -// } -// } From d7bfea0c7c8c08afc4d6b62deeae5a9b8ebf384d Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Tue, 13 Aug 2024 09:30:54 +0200 Subject: [PATCH 0347/1022] Yul syntax tests: Update test expectations to use evm instead of evmTyped --- test/libyul/SyntaxTest.cpp | 2 +- test/libyul/yulSyntaxTests/assign_from_stack.yul | 2 +- test/libyul/yulSyntaxTests/assignment.yul | 4 ++-- test/libyul/yulSyntaxTests/assignment_fail.yul | 12 ------------ test/libyul/yulSyntaxTests/blocks.yul | 6 +++--- .../yulSyntaxTests/break_outside_of_for_loop.yul | 6 ++---- test/libyul/yulSyntaxTests/builtin_types.yul | 6 ++---- .../yulSyntaxTests/continue_outside_of_for_loop.yul | 6 ++---- test/libyul/yulSyntaxTests/for_loop_condition.yul | 4 +--- .../yulSyntaxTests/for_loop_condition_fail.yul | 8 -------- test/libyul/yulSyntaxTests/for_statement.yul | 4 +--- test/libyul/yulSyntaxTests/for_statement_break.yul | 4 +--- .../yulSyntaxTests/for_statement_break_init.yul | 6 ++---- .../for_statement_break_nested_body_in_init.yul | 4 +--- .../for_statement_break_nested_body_in_post.yul | 4 +--- .../yulSyntaxTests/for_statement_break_post.yul | 6 ++---- .../libyul/yulSyntaxTests/for_statement_continue.yul | 4 +--- .../for_statement_continue_fail_init.yul | 6 ++---- .../for_statement_continue_fail_post.yul | 6 ++---- .../for_statement_continue_nested_body_in_init.yul | 4 +--- .../for_statement_continue_nested_body_in_post.yul | 4 +--- .../for_statement_continue_nested_init_in_body.yul | 6 ++---- .../yulSyntaxTests/for_statement_nested_break.yul | 6 ++---- .../yulSyntaxTests/for_statement_nested_continue.yul | 2 -- test/libyul/yulSyntaxTests/for_visibility_9.yul | 2 -- test/libyul/yulSyntaxTests/function_calls.yul | 6 +++--- .../function_defined_in_init_block_1.yul | 2 +- .../function_defined_in_init_block_2.yul | 2 +- .../function_defined_in_init_block_3.yul | 2 +- .../function_defined_in_init_nested_1.yul | 4 ++-- .../function_defined_in_init_nested_2.yul | 2 +- .../function_defined_in_init_nested_3.yul | 6 +++--- test/libyul/yulSyntaxTests/function_definitions.yul | 2 +- .../function_shadowing_outside_vars_1.yul | 4 ++-- .../function_shadowing_outside_vars_2.yul | 6 +++--- .../yulSyntaxTests/functions_multiple_args.yul | 4 ++-- test/libyul/yulSyntaxTests/if_statement_1.yul | 4 +--- test/libyul/yulSyntaxTests/if_statement_2.yul | 6 ++---- test/libyul/yulSyntaxTests/if_statement_3.yul | 6 ++---- test/libyul/yulSyntaxTests/if_statement_fail_1.yul | 4 +--- test/libyul/yulSyntaxTests/if_statement_fail_2.yul | 6 ++---- test/libyul/yulSyntaxTests/if_statement_fail_3.yul | 5 ----- test/libyul/yulSyntaxTests/invalid/pc_disallowed.yul | 2 -- test/libyul/yulSyntaxTests/invalid_type.yul | 2 -- test/libyul/yulSyntaxTests/invalid_type2.yul | 4 +--- test/libyul/yulSyntaxTests/invalid_type3.yul | 2 -- test/libyul/yulSyntaxTests/invalid_type4.yul | 4 +--- test/libyul/yulSyntaxTests/linkersymbol_evmtyped.yul | 8 -------- .../linkersymbol_invalid_redefine_builtin.yul | 6 ++++++ test/libyul/yulSyntaxTests/literal_invalid_type.yul | 8 ++++---- test/libyul/yulSyntaxTests/multiple_assignment_1.yul | 10 ++++------ test/libyul/yulSyntaxTests/multiple_assignment_2.yul | 10 ++++------ test/libyul/yulSyntaxTests/multiple_assignment_3.yul | 10 ++++------ test/libyul/yulSyntaxTests/number_literal_1.yul | 2 +- test/libyul/yulSyntaxTests/number_literal_2.yul | 4 ++-- test/libyul/yulSyntaxTests/number_literal_3.yul | 4 ++-- test/libyul/yulSyntaxTests/number_literal_4.yul | 4 ++-- test/libyul/yulSyntaxTests/number_literal_5.yul | 4 ++-- test/libyul/yulSyntaxTests/optional_types.yul | 8 +++----- test/libyul/yulSyntaxTests/period_in_identifier.yul | 2 +- .../yulSyntaxTests/period_in_identifier_spaced_1.yul | 4 ++-- .../yulSyntaxTests/period_in_identifier_spaced_2.yul | 2 +- .../yulSyntaxTests/period_in_identifier_spaced_3.yul | 2 +- .../yulSyntaxTests/period_in_identifier_start.yul | 4 ++-- .../period_in_identifier_start_with_comment.yul | 2 +- .../period_not_as_identifier_start.yul | 2 +- test/libyul/yulSyntaxTests/push.yul | 4 ++-- test/libyul/yulSyntaxTests/recursion_depth.yul | 4 +--- test/libyul/yulSyntaxTests/switch_case.yul | 8 +++----- .../yulSyntaxTests/switch_case_different_literal.yul | 8 +++----- .../switch_case_string_literal_too_long.yul | 8 +++----- .../switch_case_string_literal_very_long.yul | 6 ++---- test/libyul/yulSyntaxTests/switch_duplicate_case.yul | 10 ++++------ .../switch_duplicate_case_different_literal.yul | 10 ++++------ test/libyul/yulSyntaxTests/token_as_identifier.yul | 4 +--- test/libyul/yulSyntaxTests/tuple_assignment.yul | 4 ++-- .../type_check_cases_fail_evmtyped.yul | 10 ---------- .../yulSyntaxTests/user_defined_functions_fail.yul | 11 ++++------- .../yulSyntaxTests/user_defined_functions_fine.yul | 8 +++----- test/libyul/yulSyntaxTests/variable_declaration.yul | 4 +--- .../yulSyntaxTests/variable_declaration_bool.yul | 6 ++---- .../yulSyntaxTests/variable_declaration_complex.yul | 8 +++----- .../yulSyntaxTests/variable_declaration_empty.yul | 2 +- 83 files changed, 145 insertions(+), 275 deletions(-) delete mode 100644 test/libyul/yulSyntaxTests/assignment_fail.yul delete mode 100644 test/libyul/yulSyntaxTests/for_loop_condition_fail.yul delete mode 100644 test/libyul/yulSyntaxTests/if_statement_fail_3.yul delete mode 100644 test/libyul/yulSyntaxTests/linkersymbol_evmtyped.yul create mode 100644 test/libyul/yulSyntaxTests/linkersymbol_invalid_redefine_builtin.yul delete mode 100644 test/libyul/yulSyntaxTests/type_check_cases_fail_evmtyped.yul diff --git a/test/libyul/SyntaxTest.cpp b/test/libyul/SyntaxTest.cpp index 0201e047d847..7ed87bee450a 100644 --- a/test/libyul/SyntaxTest.cpp +++ b/test/libyul/SyntaxTest.cpp @@ -74,6 +74,6 @@ void SyntaxTest::parseAndAnalyze() SyntaxTest::SyntaxTest(std::string const& _filename, langutil::EVMVersion _evmVersion): CommonSyntaxTest(_filename, _evmVersion) { - std::string dialectName = m_reader.stringSetting("dialect", "evmTyped"); + std::string dialectName = m_reader.stringSetting("dialect", "evm"); m_dialect = &dialect(dialectName, solidity::test::CommonOptions::get().evmVersion()); } diff --git a/test/libyul/yulSyntaxTests/assign_from_stack.yul b/test/libyul/yulSyntaxTests/assign_from_stack.yul index 44f50ab5e5f2..ce48abe99acf 100644 --- a/test/libyul/yulSyntaxTests/assign_from_stack.yul +++ b/test/libyul/yulSyntaxTests/assign_from_stack.yul @@ -1,3 +1,3 @@ -{ =: x:u256 } +{ =: x } // ---- // ParserError 1856: (2-3): Literal or identifier expected. diff --git a/test/libyul/yulSyntaxTests/assignment.yul b/test/libyul/yulSyntaxTests/assignment.yul index 6c2c0f5a4c41..5ba2e3437251 100644 --- a/test/libyul/yulSyntaxTests/assignment.yul +++ b/test/libyul/yulSyntaxTests/assignment.yul @@ -1,5 +1,5 @@ { - let x:u256 := 2:u256 - let y:u256 := x + let x := 2 + let y := x } // ---- diff --git a/test/libyul/yulSyntaxTests/assignment_fail.yul b/test/libyul/yulSyntaxTests/assignment_fail.yul deleted file mode 100644 index 1bcf3fbb3fc6..000000000000 --- a/test/libyul/yulSyntaxTests/assignment_fail.yul +++ /dev/null @@ -1,12 +0,0 @@ -{ - let x:u256 - let y := x - let z:bool - z := y - y := z -} -// ==== -// dialect: evmTyped -// ---- -// TypeError 9547: (51-52): Assigning a value of type "u256" to a variable of type "bool". -// TypeError 9547: (62-63): Assigning a value of type "bool" to a variable of type "u256". diff --git a/test/libyul/yulSyntaxTests/blocks.yul b/test/libyul/yulSyntaxTests/blocks.yul index 8c2fdd9a9108..16e52fe738bc 100644 --- a/test/libyul/yulSyntaxTests/blocks.yul +++ b/test/libyul/yulSyntaxTests/blocks.yul @@ -1,10 +1,10 @@ { - let x:u256 := 7:u256 + let x := 7 { - let y:u256 := 3:u256 + let y := 3 } { - let z:u256 := 2:u256 + let z := 2 } } // ---- diff --git a/test/libyul/yulSyntaxTests/break_outside_of_for_loop.yul b/test/libyul/yulSyntaxTests/break_outside_of_for_loop.yul index 1d0f997e61d0..60329f46f0e7 100644 --- a/test/libyul/yulSyntaxTests/break_outside_of_for_loop.yul +++ b/test/libyul/yulSyntaxTests/break_outside_of_for_loop.yul @@ -1,8 +1,6 @@ { - let x:bool + let x if x { break } } -// ==== -// dialect: evmTyped // ---- -// SyntaxError 2592: (22-27): Keyword "break" needs to be inside a for-loop body. +// SyntaxError 2592: (17-22): Keyword "break" needs to be inside a for-loop body. diff --git a/test/libyul/yulSyntaxTests/builtin_types.yul b/test/libyul/yulSyntaxTests/builtin_types.yul index e4d961c300f3..275addf39448 100644 --- a/test/libyul/yulSyntaxTests/builtin_types.yul +++ b/test/libyul/yulSyntaxTests/builtin_types.yul @@ -1,7 +1,5 @@ { - let x1:bool := true:bool - let x2:u256 := 1:u256 + let x1 := true + let x2 := 1 } -// ==== -// dialect: evmTyped // ---- diff --git a/test/libyul/yulSyntaxTests/continue_outside_of_for_loop.yul b/test/libyul/yulSyntaxTests/continue_outside_of_for_loop.yul index c12f7945d453..741a4d5b6b04 100644 --- a/test/libyul/yulSyntaxTests/continue_outside_of_for_loop.yul +++ b/test/libyul/yulSyntaxTests/continue_outside_of_for_loop.yul @@ -1,8 +1,6 @@ { - let x:bool + let x if x { continue } } -// ==== -// dialect: evmTyped // ---- -// SyntaxError 2592: (22-30): Keyword "continue" needs to be inside a for-loop body. +// SyntaxError 2592: (17-25): Keyword "continue" needs to be inside a for-loop body. diff --git a/test/libyul/yulSyntaxTests/for_loop_condition.yul b/test/libyul/yulSyntaxTests/for_loop_condition.yul index 72ed7b71f15f..22db0ce75ae1 100644 --- a/test/libyul/yulSyntaxTests/for_loop_condition.yul +++ b/test/libyul/yulSyntaxTests/for_loop_condition.yul @@ -1,7 +1,5 @@ { - let x:bool + let x for {} x {} {} } -// ==== -// dialect: evmTyped // ---- diff --git a/test/libyul/yulSyntaxTests/for_loop_condition_fail.yul b/test/libyul/yulSyntaxTests/for_loop_condition_fail.yul deleted file mode 100644 index 98a52bf2474e..000000000000 --- a/test/libyul/yulSyntaxTests/for_loop_condition_fail.yul +++ /dev/null @@ -1,8 +0,0 @@ -{ - let x - for {} x {} {} -} -// ==== -// dialect: evmTyped -// ---- -// TypeError 1733: (23-24): Expected a value of boolean type "bool" but got "u256" diff --git a/test/libyul/yulSyntaxTests/for_statement.yul b/test/libyul/yulSyntaxTests/for_statement.yul index 7f180ea8f5a2..6da73b30024c 100644 --- a/test/libyul/yulSyntaxTests/for_statement.yul +++ b/test/libyul/yulSyntaxTests/for_statement.yul @@ -1,7 +1,5 @@ { - let x:bool + let x for {let i := 0} x {i := add(i, 1)} {} } -// ==== -// dialect: evmTyped // ---- diff --git a/test/libyul/yulSyntaxTests/for_statement_break.yul b/test/libyul/yulSyntaxTests/for_statement_break.yul index 4e432557baf9..258cb4c417e5 100644 --- a/test/libyul/yulSyntaxTests/for_statement_break.yul +++ b/test/libyul/yulSyntaxTests/for_statement_break.yul @@ -1,10 +1,8 @@ { - let x:bool + let x for {let i := 0} x {i := add(i, 1)} { break } } -// ==== -// dialect: evmTyped // ---- diff --git a/test/libyul/yulSyntaxTests/for_statement_break_init.yul b/test/libyul/yulSyntaxTests/for_statement_break_init.yul index 7fb15faf0046..bf00d0dfb514 100644 --- a/test/libyul/yulSyntaxTests/for_statement_break_init.yul +++ b/test/libyul/yulSyntaxTests/for_statement_break_init.yul @@ -1,8 +1,6 @@ { - let x:bool + let x for {let i := 0 break} x {i := add(i, 1)} {} } -// ==== -// dialect: evmTyped // ---- -// SyntaxError 9615: (31-36): Keyword "break" in for-loop init block is not allowed. +// SyntaxError 9615: (26-31): Keyword "break" in for-loop init block is not allowed. diff --git a/test/libyul/yulSyntaxTests/for_statement_break_nested_body_in_init.yul b/test/libyul/yulSyntaxTests/for_statement_break_nested_body_in_init.yul index 9ffe751cc0b1..cc0fdd341048 100644 --- a/test/libyul/yulSyntaxTests/for_statement_break_nested_body_in_init.yul +++ b/test/libyul/yulSyntaxTests/for_statement_break_nested_body_in_init.yul @@ -1,7 +1,5 @@ { - for {let x:bool for {} x {} { break }} 1:bool {} + for {let x for {} x {} { break }} 1 {} {} } -// ==== -// dialect: evmTyped // ---- diff --git a/test/libyul/yulSyntaxTests/for_statement_break_nested_body_in_post.yul b/test/libyul/yulSyntaxTests/for_statement_break_nested_body_in_post.yul index ab012a73fa0f..0127e178e217 100644 --- a/test/libyul/yulSyntaxTests/for_statement_break_nested_body_in_post.yul +++ b/test/libyul/yulSyntaxTests/for_statement_break_nested_body_in_post.yul @@ -1,7 +1,5 @@ { - for {} 1:bool {let x:bool for {} x {} { break }} + for {} 1 {let x for {} x {} { break }} {} } -// ==== -// dialect: evmTyped // ---- diff --git a/test/libyul/yulSyntaxTests/for_statement_break_post.yul b/test/libyul/yulSyntaxTests/for_statement_break_post.yul index 93d1475d0696..595ab60d2dc2 100644 --- a/test/libyul/yulSyntaxTests/for_statement_break_post.yul +++ b/test/libyul/yulSyntaxTests/for_statement_break_post.yul @@ -1,8 +1,6 @@ { - let x:bool + let x for {let i := 0 } x {i := add(i, 1) break} {} } -// ==== -// dialect: evmTyped // ---- -// SyntaxError 2461: (51-56): Keyword "break" in for-loop post block is not allowed. +// SyntaxError 2461: (46-51): Keyword "break" in for-loop post block is not allowed. diff --git a/test/libyul/yulSyntaxTests/for_statement_continue.yul b/test/libyul/yulSyntaxTests/for_statement_continue.yul index b7c2b02515af..f9badaf555f7 100644 --- a/test/libyul/yulSyntaxTests/for_statement_continue.yul +++ b/test/libyul/yulSyntaxTests/for_statement_continue.yul @@ -1,10 +1,8 @@ { - let x:bool + let x for {let i := 0} x {i := add(i, 1)} { continue } } -// ==== -// dialect: evmTyped // ---- diff --git a/test/libyul/yulSyntaxTests/for_statement_continue_fail_init.yul b/test/libyul/yulSyntaxTests/for_statement_continue_fail_init.yul index eca0d46928ea..00683f853256 100644 --- a/test/libyul/yulSyntaxTests/for_statement_continue_fail_init.yul +++ b/test/libyul/yulSyntaxTests/for_statement_continue_fail_init.yul @@ -1,10 +1,8 @@ { - let x:bool + let x for {let i := 0 continue} x {i := add(i, 1)} { } } -// ==== -// dialect: evmTyped // ---- -// SyntaxError 9615: (31-39): Keyword "continue" in for-loop init block is not allowed. +// SyntaxError 9615: (26-34): Keyword "continue" in for-loop init block is not allowed. diff --git a/test/libyul/yulSyntaxTests/for_statement_continue_fail_post.yul b/test/libyul/yulSyntaxTests/for_statement_continue_fail_post.yul index 7362b38b285a..d8c5faaa82bc 100644 --- a/test/libyul/yulSyntaxTests/for_statement_continue_fail_post.yul +++ b/test/libyul/yulSyntaxTests/for_statement_continue_fail_post.yul @@ -1,8 +1,6 @@ { - let x:bool + let x for {let i := 0} x {i := add(i, 1) continue} {} } -// ==== -// dialect: evmTyped // ---- -// SyntaxError 2461: (50-58): Keyword "continue" in for-loop post block is not allowed. +// SyntaxError 2461: (45-53): Keyword "continue" in for-loop post block is not allowed. diff --git a/test/libyul/yulSyntaxTests/for_statement_continue_nested_body_in_init.yul b/test/libyul/yulSyntaxTests/for_statement_continue_nested_body_in_init.yul index 305cdd36d4dc..565489a371a5 100644 --- a/test/libyul/yulSyntaxTests/for_statement_continue_nested_body_in_init.yul +++ b/test/libyul/yulSyntaxTests/for_statement_continue_nested_body_in_init.yul @@ -1,8 +1,6 @@ { - for {let x:bool for {} x {} { continue }} 1:bool {} + for {let x for {} x {} { continue }} 1 {} { } } -// ==== -// dialect: evmTyped // ---- diff --git a/test/libyul/yulSyntaxTests/for_statement_continue_nested_body_in_post.yul b/test/libyul/yulSyntaxTests/for_statement_continue_nested_body_in_post.yul index e33bd2457b04..dd7927a8f0fe 100644 --- a/test/libyul/yulSyntaxTests/for_statement_continue_nested_body_in_post.yul +++ b/test/libyul/yulSyntaxTests/for_statement_continue_nested_body_in_post.yul @@ -1,7 +1,5 @@ { - for {} 1:bool {let x:bool for {} x {} { continue }} + for {} 1 {let x for {} x {} { continue }} {} } -// ==== -// dialect: evmTyped // ---- diff --git a/test/libyul/yulSyntaxTests/for_statement_continue_nested_init_in_body.yul b/test/libyul/yulSyntaxTests/for_statement_continue_nested_init_in_body.yul index 1ff20943fbb9..c6abf3b537ac 100644 --- a/test/libyul/yulSyntaxTests/for_statement_continue_nested_init_in_body.yul +++ b/test/libyul/yulSyntaxTests/for_statement_continue_nested_init_in_body.yul @@ -1,11 +1,9 @@ { for {} 1 {} { - let x:bool + let x for { continue } x {} {} } } -// ==== -// dialect: evmTyped // ---- -// SyntaxError 9615: (39-47): Keyword "continue" in for-loop init block is not allowed. +// SyntaxError 9615: (34-42): Keyword "continue" in for-loop init block is not allowed. diff --git a/test/libyul/yulSyntaxTests/for_statement_nested_break.yul b/test/libyul/yulSyntaxTests/for_statement_nested_break.yul index ae3fd9da4732..3b29cd754ab9 100644 --- a/test/libyul/yulSyntaxTests/for_statement_nested_break.yul +++ b/test/libyul/yulSyntaxTests/for_statement_nested_break.yul @@ -1,11 +1,9 @@ { - let x:bool + let x for {let i := 0} x {} { function f() { break } } } -// ==== -// dialect: evmTyped // ---- -// SyntaxError 2592: (57-62): Keyword "break" needs to be inside a for-loop body. +// SyntaxError 2592: (52-57): Keyword "break" needs to be inside a for-loop body. diff --git a/test/libyul/yulSyntaxTests/for_statement_nested_continue.yul b/test/libyul/yulSyntaxTests/for_statement_nested_continue.yul index 8e7eca428e24..6e32d19b7dcf 100644 --- a/test/libyul/yulSyntaxTests/for_statement_nested_continue.yul +++ b/test/libyul/yulSyntaxTests/for_statement_nested_continue.yul @@ -4,7 +4,5 @@ function f() { continue } } } -// ==== -// dialect: evmTyped // ---- // SyntaxError 2592: (61-69): Keyword "continue" needs to be inside a for-loop body. diff --git a/test/libyul/yulSyntaxTests/for_visibility_9.yul b/test/libyul/yulSyntaxTests/for_visibility_9.yul index 6922dc96178f..d12524e882b6 100644 --- a/test/libyul/yulSyntaxTests/for_visibility_9.yul +++ b/test/libyul/yulSyntaxTests/for_visibility_9.yul @@ -1,7 +1,5 @@ { for { let x := 1 } 1 { let x := 1 } {} } -// ==== -// dialect: evmTyped // ---- // DeclarationError 1395: (26-36): Variable name x already taken in this scope. diff --git a/test/libyul/yulSyntaxTests/function_calls.yul b/test/libyul/yulSyntaxTests/function_calls.yul index 777382b125c1..586e778d3da7 100644 --- a/test/libyul/yulSyntaxTests/function_calls.yul +++ b/test/libyul/yulSyntaxTests/function_calls.yul @@ -1,8 +1,8 @@ { - function f(a:u256) -> b:u256 {} - function g(a:u256, b:u256, c:u256) {} + function f(a) -> b {} + function g(a, b, c) {} function x() { - g(1:u256, 2:u256, f(3:u256)) + g(1, 2, f(3)) x() } } diff --git a/test/libyul/yulSyntaxTests/function_defined_in_init_block_1.yul b/test/libyul/yulSyntaxTests/function_defined_in_init_block_1.yul index 6f921a4ea82d..165337bcb709 100644 --- a/test/libyul/yulSyntaxTests/function_defined_in_init_block_1.yul +++ b/test/libyul/yulSyntaxTests/function_defined_in_init_block_1.yul @@ -1,4 +1,4 @@ { - for { } 1:bool { function f() {} } {} + for { } 1 { function f() {} } {} } // ---- diff --git a/test/libyul/yulSyntaxTests/function_defined_in_init_block_2.yul b/test/libyul/yulSyntaxTests/function_defined_in_init_block_2.yul index f6c92d92a490..61a8b1c5602a 100644 --- a/test/libyul/yulSyntaxTests/function_defined_in_init_block_2.yul +++ b/test/libyul/yulSyntaxTests/function_defined_in_init_block_2.yul @@ -1,4 +1,4 @@ { - for { } 1:bool {} { function f() {} } + for { } 1 {} { function f() {} } } // ---- diff --git a/test/libyul/yulSyntaxTests/function_defined_in_init_block_3.yul b/test/libyul/yulSyntaxTests/function_defined_in_init_block_3.yul index 6e616630a112..b9571cbe971e 100644 --- a/test/libyul/yulSyntaxTests/function_defined_in_init_block_3.yul +++ b/test/libyul/yulSyntaxTests/function_defined_in_init_block_3.yul @@ -1,5 +1,5 @@ { - for { function f() {} } 1:bool {} {} + for { function f() {} } 1 {} {} } // ---- // SyntaxError 3441: (9-17): Functions cannot be defined inside a for-loop init block. diff --git a/test/libyul/yulSyntaxTests/function_defined_in_init_nested_1.yul b/test/libyul/yulSyntaxTests/function_defined_in_init_nested_1.yul index 766de17a95f0..e7dca976383c 100644 --- a/test/libyul/yulSyntaxTests/function_defined_in_init_nested_1.yul +++ b/test/libyul/yulSyntaxTests/function_defined_in_init_nested_1.yul @@ -1,8 +1,8 @@ { for { - for {} 1:bool { function f() {} } + for {} 1 { function f() {} } {} - } 1:bool {} + } 1 {} {} } // ---- diff --git a/test/libyul/yulSyntaxTests/function_defined_in_init_nested_2.yul b/test/libyul/yulSyntaxTests/function_defined_in_init_nested_2.yul index f5f3accd248f..db9445d26bd8 100644 --- a/test/libyul/yulSyntaxTests/function_defined_in_init_nested_2.yul +++ b/test/libyul/yulSyntaxTests/function_defined_in_init_nested_2.yul @@ -1,5 +1,5 @@ { - for { for {function foo() {}} 1:bool {} {} } 1:bool {} {} + for { for {function foo() {}} 1 {} {} } 1 {} {} } // ---- // SyntaxError 3441: (14-22): Functions cannot be defined inside a for-loop init block. diff --git a/test/libyul/yulSyntaxTests/function_defined_in_init_nested_3.yul b/test/libyul/yulSyntaxTests/function_defined_in_init_nested_3.yul index d3a794c0afaf..ebae8beabf37 100644 --- a/test/libyul/yulSyntaxTests/function_defined_in_init_nested_3.yul +++ b/test/libyul/yulSyntaxTests/function_defined_in_init_nested_3.yul @@ -1,8 +1,8 @@ { for {} - 1:bool - {for {function foo() {}} 1:bool {} {} } + 1 + {for {function foo() {}} 1 {} {} } {} } // ---- -// SyntaxError 3441: (27-35): Functions cannot be defined inside a for-loop init block. +// SyntaxError 3441: (22-30): Functions cannot be defined inside a for-loop init block. diff --git a/test/libyul/yulSyntaxTests/function_definitions.yul b/test/libyul/yulSyntaxTests/function_definitions.yul index 20dfbb131284..ec36b5b8050f 100644 --- a/test/libyul/yulSyntaxTests/function_definitions.yul +++ b/test/libyul/yulSyntaxTests/function_definitions.yul @@ -1,5 +1,5 @@ { function f() { } - function g(a:u256) -> x:u256 { } + function g(a) -> x { } } // ---- diff --git a/test/libyul/yulSyntaxTests/function_shadowing_outside_vars_1.yul b/test/libyul/yulSyntaxTests/function_shadowing_outside_vars_1.yul index 22c89e2b5769..af1273669b9e 100644 --- a/test/libyul/yulSyntaxTests/function_shadowing_outside_vars_1.yul +++ b/test/libyul/yulSyntaxTests/function_shadowing_outside_vars_1.yul @@ -1,5 +1,5 @@ { - { let x:u256 } - function f() -> x:u256 {} + { let x } + function f() -> x {} } // ---- diff --git a/test/libyul/yulSyntaxTests/function_shadowing_outside_vars_2.yul b/test/libyul/yulSyntaxTests/function_shadowing_outside_vars_2.yul index f7fb87278545..724f31a3dbcf 100644 --- a/test/libyul/yulSyntaxTests/function_shadowing_outside_vars_2.yul +++ b/test/libyul/yulSyntaxTests/function_shadowing_outside_vars_2.yul @@ -1,6 +1,6 @@ { - let x:u256 - function f() -> x:u256 {} + let x + function f() -> x {} } // ---- -// DeclarationError 1395: (15-40): Variable name x already taken in this scope. +// DeclarationError 1395: (10-30): Variable name x already taken in this scope. diff --git a/test/libyul/yulSyntaxTests/functions_multiple_args.yul b/test/libyul/yulSyntaxTests/functions_multiple_args.yul index aa268dc1082d..45d48104211c 100644 --- a/test/libyul/yulSyntaxTests/functions_multiple_args.yul +++ b/test/libyul/yulSyntaxTests/functions_multiple_args.yul @@ -1,5 +1,5 @@ { - function f(a:u256, d:u256) { } - function g(a:u256, d:u256) -> x:u256, y:u256 { } + function f(a, d) { } + function g(a, d) -> x, y { } } // ---- diff --git a/test/libyul/yulSyntaxTests/if_statement_1.yul b/test/libyul/yulSyntaxTests/if_statement_1.yul index b631f8a953e0..7a5630f250d7 100644 --- a/test/libyul/yulSyntaxTests/if_statement_1.yul +++ b/test/libyul/yulSyntaxTests/if_statement_1.yul @@ -1,6 +1,4 @@ { - if true:bool {} + if true {} } -// ==== -// dialect: evmTyped // ---- diff --git a/test/libyul/yulSyntaxTests/if_statement_2.yul b/test/libyul/yulSyntaxTests/if_statement_2.yul index 20be9b525cb0..7d2ffa2253cc 100644 --- a/test/libyul/yulSyntaxTests/if_statement_2.yul +++ b/test/libyul/yulSyntaxTests/if_statement_2.yul @@ -1,9 +1,7 @@ { - if false:bool + if false { - let x:u256 := 3:u256 + let x := 3 } } -// ==== -// dialect: evmTyped // ---- diff --git a/test/libyul/yulSyntaxTests/if_statement_3.yul b/test/libyul/yulSyntaxTests/if_statement_3.yul index 2ba20d39b916..c80d8187d415 100644 --- a/test/libyul/yulSyntaxTests/if_statement_3.yul +++ b/test/libyul/yulSyntaxTests/if_statement_3.yul @@ -1,11 +1,9 @@ { - function f() -> x:bool {} + function f() -> x {} if f() { - let b:bool := f() + let b := f() } } -// ==== -// dialect: evmTyped // ---- diff --git a/test/libyul/yulSyntaxTests/if_statement_fail_1.yul b/test/libyul/yulSyntaxTests/if_statement_fail_1.yul index 6fc409ce3863..8bf70df9842e 100644 --- a/test/libyul/yulSyntaxTests/if_statement_fail_1.yul +++ b/test/libyul/yulSyntaxTests/if_statement_fail_1.yul @@ -1,5 +1,3 @@ -{ if let x:u256 {} } -// ==== -// dialect: evmTyped +{ if let x {} } // ---- // ParserError 1856: (5-8): Literal or identifier expected. diff --git a/test/libyul/yulSyntaxTests/if_statement_fail_2.yul b/test/libyul/yulSyntaxTests/if_statement_fail_2.yul index 97ce0e9f9f2f..8722a7741614 100644 --- a/test/libyul/yulSyntaxTests/if_statement_fail_2.yul +++ b/test/libyul/yulSyntaxTests/if_statement_fail_2.yul @@ -1,5 +1,3 @@ -{ if true:bool let x:u256 := 3:u256 } -// ==== -// dialect: evmTyped +{ if true let x := 3 } // ---- -// ParserError 2314: (15-18): Expected '{' but got reserved keyword 'let' +// ParserError 2314: (10-13): Expected '{' but got reserved keyword 'let' diff --git a/test/libyul/yulSyntaxTests/if_statement_fail_3.yul b/test/libyul/yulSyntaxTests/if_statement_fail_3.yul deleted file mode 100644 index 51e36790b6e9..000000000000 --- a/test/libyul/yulSyntaxTests/if_statement_fail_3.yul +++ /dev/null @@ -1,5 +0,0 @@ -{ if 42:u256 { } } -// ==== -// dialect: evmTyped -// ---- -// TypeError 1733: (5-12): Expected a value of boolean type "bool" but got "u256" diff --git a/test/libyul/yulSyntaxTests/invalid/pc_disallowed.yul b/test/libyul/yulSyntaxTests/invalid/pc_disallowed.yul index e43d7a141b1c..d5b3847b1743 100644 --- a/test/libyul/yulSyntaxTests/invalid/pc_disallowed.yul +++ b/test/libyul/yulSyntaxTests/invalid/pc_disallowed.yul @@ -1,7 +1,5 @@ { pop(pc()) } -// ==== -// dialect: evmTyped // ---- // SyntaxError 2450: (10-12): PC instruction is a low-level EVM feature. Because of that PC is disallowed in strict assembly. diff --git a/test/libyul/yulSyntaxTests/invalid_type.yul b/test/libyul/yulSyntaxTests/invalid_type.yul index 99ed4c43b440..f863816355c6 100644 --- a/test/libyul/yulSyntaxTests/invalid_type.yul +++ b/test/libyul/yulSyntaxTests/invalid_type.yul @@ -1,7 +1,5 @@ { let x: invalidType } -// ==== -// dialect: evmTyped // ---- // TypeError 5473: (10-24): "invalidType" is not a valid type (user defined types are not yet supported). diff --git a/test/libyul/yulSyntaxTests/invalid_type2.yul b/test/libyul/yulSyntaxTests/invalid_type2.yul index 2ad035dcfc74..af30bc2eb244 100644 --- a/test/libyul/yulSyntaxTests/invalid_type2.yul +++ b/test/libyul/yulSyntaxTests/invalid_type2.yul @@ -1,8 +1,6 @@ { let x := 1:invalidType } -// ==== -// dialect: evmTyped // ---- // TypeError 5473: (15-28): "invalidType" is not a valid type (user defined types are not yet supported). -// TypeError 3947: (10-11): Assigning value of type "invalidType" to variable of type "u256". +// TypeError 3947: (10-11): Assigning value of type "invalidType" to variable of type "". diff --git a/test/libyul/yulSyntaxTests/invalid_type3.yul b/test/libyul/yulSyntaxTests/invalid_type3.yul index 1ce7092fe82d..6fc0e35e8ce0 100644 --- a/test/libyul/yulSyntaxTests/invalid_type3.yul +++ b/test/libyul/yulSyntaxTests/invalid_type3.yul @@ -1,8 +1,6 @@ { function f(a: invalidType) -> b: invalidType {} } -// ==== -// dialect: evmTyped // ---- // TypeError 5473: (17-31): "invalidType" is not a valid type (user defined types are not yet supported). // TypeError 5473: (36-50): "invalidType" is not a valid type (user defined types are not yet supported). diff --git a/test/libyul/yulSyntaxTests/invalid_type4.yul b/test/libyul/yulSyntaxTests/invalid_type4.yul index 8195fcf90834..90f00ddaafd2 100644 --- a/test/libyul/yulSyntaxTests/invalid_type4.yul +++ b/test/libyul/yulSyntaxTests/invalid_type4.yul @@ -2,8 +2,6 @@ switch 1 case 8: invalidType {} } -// ==== -// dialect: evmTyped // ---- -// TypeError 3781: (24-38): Expected a value of type "u256" but got "invalidType". +// TypeError 3781: (24-38): Expected a value of type "" but got "invalidType". // TypeError 5473: (24-38): "invalidType" is not a valid type (user defined types are not yet supported). diff --git a/test/libyul/yulSyntaxTests/linkersymbol_evmtyped.yul b/test/libyul/yulSyntaxTests/linkersymbol_evmtyped.yul deleted file mode 100644 index aa9cc3adbf1a..000000000000 --- a/test/libyul/yulSyntaxTests/linkersymbol_evmtyped.yul +++ /dev/null @@ -1,8 +0,0 @@ -{ - let addr:u256 := linkersymbol("contract/library.sol:L") - function linkersymbol(x) {} -} -// ==== -// dialect: evmTyped -// ---- -// ParserError 5568: (75-87): Cannot use builtin function name "linkersymbol" as identifier name. diff --git a/test/libyul/yulSyntaxTests/linkersymbol_invalid_redefine_builtin.yul b/test/libyul/yulSyntaxTests/linkersymbol_invalid_redefine_builtin.yul new file mode 100644 index 000000000000..462886c87739 --- /dev/null +++ b/test/libyul/yulSyntaxTests/linkersymbol_invalid_redefine_builtin.yul @@ -0,0 +1,6 @@ +{ + let addr := linkersymbol("contract/library.sol:L") + function linkersymbol(x) {} +} +// ---- +// ParserError 5568: (70-82): Cannot use builtin function name "linkersymbol" as identifier name. diff --git a/test/libyul/yulSyntaxTests/literal_invalid_type.yul b/test/libyul/yulSyntaxTests/literal_invalid_type.yul index 07a51eb887d3..fd612a0a5a18 100644 --- a/test/libyul/yulSyntaxTests/literal_invalid_type.yul +++ b/test/libyul/yulSyntaxTests/literal_invalid_type.yul @@ -1,7 +1,7 @@ { - let x:bool := true:unhappy + let x := true:unhappy } // ---- -// TypeError 5473: (20-32): "unhappy" is not a valid type (user defined types are not yet supported). -// TypeError 5170: (20-32): Invalid type "unhappy" for literal "true". -// TypeError 3947: (10-16): Assigning value of type "unhappy" to variable of type "bool". +// TypeError 5473: (15-27): "unhappy" is not a valid type (user defined types are not yet supported). +// TypeError 5170: (15-27): Invalid type "unhappy" for literal "true". +// TypeError 3947: (10-11): Assigning value of type "unhappy" to variable of type "". diff --git a/test/libyul/yulSyntaxTests/multiple_assignment_1.yul b/test/libyul/yulSyntaxTests/multiple_assignment_1.yul index b619007a55ea..285374339ea2 100644 --- a/test/libyul/yulSyntaxTests/multiple_assignment_1.yul +++ b/test/libyul/yulSyntaxTests/multiple_assignment_1.yul @@ -1,9 +1,7 @@ { - let x:u256 - function f() -> a:u256, b:u256 {} - 123:u256, x := f() + let x + function f() -> a, b {} + 123, x := f() } -// ==== -// dialect: evmTyped // ---- -// ParserError 2856: (58-59): Variable name must precede "," in multiple assignment. +// ParserError 2856: (38-39): Variable name must precede "," in multiple assignment. diff --git a/test/libyul/yulSyntaxTests/multiple_assignment_2.yul b/test/libyul/yulSyntaxTests/multiple_assignment_2.yul index 852502447f08..5aae7f6687b6 100644 --- a/test/libyul/yulSyntaxTests/multiple_assignment_2.yul +++ b/test/libyul/yulSyntaxTests/multiple_assignment_2.yul @@ -1,9 +1,7 @@ { - let x:u256 - function f() -> a:u256, b:u256 {} - x, 123:u256 := f() + let x + function f() -> a, b {} + x, 123 := f() } -// ==== -// dialect: evmTyped // ---- -// ParserError 2856: (62-64): Variable name must precede ":=" in assignment. +// ParserError 2856: (42-44): Variable name must precede ":=" in assignment. diff --git a/test/libyul/yulSyntaxTests/multiple_assignment_3.yul b/test/libyul/yulSyntaxTests/multiple_assignment_3.yul index c7ac5eb8e5aa..7a6d8a1aea45 100644 --- a/test/libyul/yulSyntaxTests/multiple_assignment_3.yul +++ b/test/libyul/yulSyntaxTests/multiple_assignment_3.yul @@ -1,12 +1,10 @@ { - function f(a:u256) -> r1:u256, r2:u256 { + function f(a) -> r1, r2 { r1 := a - r2 := 7:u256 + r2 := 7 } - let x:u256 := 9:u256 - let y:u256 := 2:u256 + let x := 9 + let y := 2 x, y := f(x) } -// ==== -// dialect: evmTyped // ---- diff --git a/test/libyul/yulSyntaxTests/number_literal_1.yul b/test/libyul/yulSyntaxTests/number_literal_1.yul index 5d5bcd150cc4..f261e3157bad 100644 --- a/test/libyul/yulSyntaxTests/number_literal_1.yul +++ b/test/libyul/yulSyntaxTests/number_literal_1.yul @@ -1,2 +1,2 @@ -{ let x:u256 := 1:u256 } +{ let x := 1 } // ---- diff --git a/test/libyul/yulSyntaxTests/number_literal_2.yul b/test/libyul/yulSyntaxTests/number_literal_2.yul index 94c5929b5381..694112146031 100644 --- a/test/libyul/yulSyntaxTests/number_literal_2.yul +++ b/test/libyul/yulSyntaxTests/number_literal_2.yul @@ -1,3 +1,3 @@ -{ let x:u256 := .1:u256 } +{ let x := .1 } // ---- -// ParserError 4828: (16-18): Invalid number literal. +// ParserError 4828: (11-13): Invalid number literal. diff --git a/test/libyul/yulSyntaxTests/number_literal_3.yul b/test/libyul/yulSyntaxTests/number_literal_3.yul index 4dbb6879a9e5..b1592adc172f 100644 --- a/test/libyul/yulSyntaxTests/number_literal_3.yul +++ b/test/libyul/yulSyntaxTests/number_literal_3.yul @@ -1,3 +1,3 @@ -{ let x:u256 := 1e5:u256 } +{ let x := 1e5 } // ---- -// ParserError 4828: (16-19): Invalid number literal. +// ParserError 4828: (11-14): Invalid number literal. diff --git a/test/libyul/yulSyntaxTests/number_literal_4.yul b/test/libyul/yulSyntaxTests/number_literal_4.yul index 7de784e88c20..339d7802e036 100644 --- a/test/libyul/yulSyntaxTests/number_literal_4.yul +++ b/test/libyul/yulSyntaxTests/number_literal_4.yul @@ -1,3 +1,3 @@ -{ let x:u256 := 67.235:u256 } +{ let x := 67.235 } // ---- -// ParserError 4828: (16-22): Invalid number literal. +// ParserError 4828: (11-17): Invalid number literal. diff --git a/test/libyul/yulSyntaxTests/number_literal_5.yul b/test/libyul/yulSyntaxTests/number_literal_5.yul index df41e69eca0c..327206e044b0 100644 --- a/test/libyul/yulSyntaxTests/number_literal_5.yul +++ b/test/libyul/yulSyntaxTests/number_literal_5.yul @@ -1,3 +1,3 @@ -{ let x:u256 := 0x1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff:u256 } +{ let x := 0x1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff } // ---- -// TypeError 6708: (16-88): Number literal too large (> 256 bits) +// TypeError 6708: (11-78): Number literal too large (> 256 bits) diff --git a/test/libyul/yulSyntaxTests/optional_types.yul b/test/libyul/yulSyntaxTests/optional_types.yul index 151edbf46973..121a7d495e97 100644 --- a/test/libyul/yulSyntaxTests/optional_types.yul +++ b/test/libyul/yulSyntaxTests/optional_types.yul @@ -1,9 +1,7 @@ { - let x := 1:u256 - let y:u256 := 1 + let x := 1 + let y := 1 function f(a) {} - function g(a:u256) -> b {} + function g(a) -> b {} } -// ==== -// dialect: evmTyped // ---- diff --git a/test/libyul/yulSyntaxTests/period_in_identifier.yul b/test/libyul/yulSyntaxTests/period_in_identifier.yul index 4ee80a3f4c11..0fc75185e671 100644 --- a/test/libyul/yulSyntaxTests/period_in_identifier.yul +++ b/test/libyul/yulSyntaxTests/period_in_identifier.yul @@ -1,2 +1,2 @@ -{ let x.y:u256 := 2:u256 } +{ let x.y := 2 } // ---- diff --git a/test/libyul/yulSyntaxTests/period_in_identifier_spaced_1.yul b/test/libyul/yulSyntaxTests/period_in_identifier_spaced_1.yul index dc889a2fbc25..e4ea959d6b87 100644 --- a/test/libyul/yulSyntaxTests/period_in_identifier_spaced_1.yul +++ b/test/libyul/yulSyntaxTests/period_in_identifier_spaced_1.yul @@ -1,3 +1,3 @@ -{ let x. y:u256 } +{ let x. y } // ---- -// ParserError 6913: (10-11): Call or assignment expected. +// ParserError 6913: (11-12): Call or assignment expected. diff --git a/test/libyul/yulSyntaxTests/period_in_identifier_spaced_2.yul b/test/libyul/yulSyntaxTests/period_in_identifier_spaced_2.yul index 5602cbcebc49..290eb28a5a0c 100644 --- a/test/libyul/yulSyntaxTests/period_in_identifier_spaced_2.yul +++ b/test/libyul/yulSyntaxTests/period_in_identifier_spaced_2.yul @@ -1,3 +1,3 @@ -{ let x .y:u256 } +{ let x .y } // ---- // ParserError 1856: (8-9): Literal or identifier expected. diff --git a/test/libyul/yulSyntaxTests/period_in_identifier_spaced_3.yul b/test/libyul/yulSyntaxTests/period_in_identifier_spaced_3.yul index 003341b339c8..3e5ec22a4603 100644 --- a/test/libyul/yulSyntaxTests/period_in_identifier_spaced_3.yul +++ b/test/libyul/yulSyntaxTests/period_in_identifier_spaced_3.yul @@ -1,3 +1,3 @@ -{ let x . y:u256 } +{ let x . y } // ---- // ParserError 1856: (8-9): Literal or identifier expected. diff --git a/test/libyul/yulSyntaxTests/period_in_identifier_start.yul b/test/libyul/yulSyntaxTests/period_in_identifier_start.yul index 83da8389f13f..cb2c66146537 100644 --- a/test/libyul/yulSyntaxTests/period_in_identifier_start.yul +++ b/test/libyul/yulSyntaxTests/period_in_identifier_start.yul @@ -1,5 +1,5 @@ { - x.y(2:u256) - function x.y(a:u256) {} + x.y(2) + function x.y(a) {} } // ---- diff --git a/test/libyul/yulSyntaxTests/period_in_identifier_start_with_comment.yul b/test/libyul/yulSyntaxTests/period_in_identifier_start_with_comment.yul index 51623599d67a..47939019c09e 100644 --- a/test/libyul/yulSyntaxTests/period_in_identifier_start_with_comment.yul +++ b/test/libyul/yulSyntaxTests/period_in_identifier_start_with_comment.yul @@ -1,3 +1,3 @@ /// comment -{ x.y(2:u256) function x.y(a:u256) {} } +{ x.y(2) function x.y(a) {} } // ---- diff --git a/test/libyul/yulSyntaxTests/period_not_as_identifier_start.yul b/test/libyul/yulSyntaxTests/period_not_as_identifier_start.yul index 0002b76fdb8b..cb47ffb2af61 100644 --- a/test/libyul/yulSyntaxTests/period_not_as_identifier_start.yul +++ b/test/libyul/yulSyntaxTests/period_not_as_identifier_start.yul @@ -1,3 +1,3 @@ -{ let .y:u256 } +{ let .y } // ---- // ParserError 2314: (6-7): Expected identifier but got '.' diff --git a/test/libyul/yulSyntaxTests/push.yul b/test/libyul/yulSyntaxTests/push.yul index f3dab144d54e..beea98be994e 100644 --- a/test/libyul/yulSyntaxTests/push.yul +++ b/test/libyul/yulSyntaxTests/push.yul @@ -1,3 +1,3 @@ -{ 0x42:u256 } +{ 0x42 } // ---- -// ParserError 6913: (12-13): Call or assignment expected. +// ParserError 6913: (7-8): Call or assignment expected. diff --git a/test/libyul/yulSyntaxTests/recursion_depth.yul b/test/libyul/yulSyntaxTests/recursion_depth.yul index 9c65013912e5..97dfd74295f1 100644 --- a/test/libyul/yulSyntaxTests/recursion_depth.yul +++ b/test/libyul/yulSyntaxTests/recursion_depth.yul @@ -1,7 +1,5 @@ {{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{ -let x:u256 := 0:u256 +let x := 0 }}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}} -// ==== -// dialect: evmTyped // ---- // ParserError 7319: (600-601): Maximum recursion depth reached during parsing. diff --git a/test/libyul/yulSyntaxTests/switch_case.yul b/test/libyul/yulSyntaxTests/switch_case.yul index 88bda992946a..aef17d570d9d 100644 --- a/test/libyul/yulSyntaxTests/switch_case.yul +++ b/test/libyul/yulSyntaxTests/switch_case.yul @@ -1,8 +1,6 @@ { - switch 0:u256 - case 42:u256 {} - case 0x42:u256 {} + switch 0 + case 42 {} + case 0x42 {} } -// ==== -// dialect: evmTyped // ---- diff --git a/test/libyul/yulSyntaxTests/switch_case_different_literal.yul b/test/libyul/yulSyntaxTests/switch_case_different_literal.yul index 8514b835d2fc..36f8e0ffcfc8 100644 --- a/test/libyul/yulSyntaxTests/switch_case_different_literal.yul +++ b/test/libyul/yulSyntaxTests/switch_case_different_literal.yul @@ -1,8 +1,6 @@ { - switch 1:u256 - case "1":u256 {} - case "2":u256 {} + switch 1 + case "1" {} + case "2" {} } -// ==== -// dialect: evmTyped // ---- diff --git a/test/libyul/yulSyntaxTests/switch_case_string_literal_too_long.yul b/test/libyul/yulSyntaxTests/switch_case_string_literal_too_long.yul index dceb9db16092..f8a5c46bcd94 100644 --- a/test/libyul/yulSyntaxTests/switch_case_string_literal_too_long.yul +++ b/test/libyul/yulSyntaxTests/switch_case_string_literal_too_long.yul @@ -1,9 +1,7 @@ { - let x:u256 + let x switch x - case "012345678901234567890123456789012":u256 {} + case "012345678901234567890123456789012" {} } -// ==== -// dialect: evmTyped // ---- -// TypeError 3069: (30-70): String literal too long (33 > 32) +// TypeError 3069: (25-60): String literal too long (33 > 32) diff --git a/test/libyul/yulSyntaxTests/switch_case_string_literal_very_long.yul b/test/libyul/yulSyntaxTests/switch_case_string_literal_very_long.yul index 55f25124b2ad..94ca50336d21 100644 --- a/test/libyul/yulSyntaxTests/switch_case_string_literal_very_long.yul +++ b/test/libyul/yulSyntaxTests/switch_case_string_literal_very_long.yul @@ -1,8 +1,6 @@ { - let x:u256 + let x switch x - case "01234567890123456789012345678901":u256 {} + case "01234567890123456789012345678901" {} } -// ==== -// dialect: evmTyped // ---- diff --git a/test/libyul/yulSyntaxTests/switch_duplicate_case.yul b/test/libyul/yulSyntaxTests/switch_duplicate_case.yul index 7417f32d6317..1dd5f60ebede 100644 --- a/test/libyul/yulSyntaxTests/switch_duplicate_case.yul +++ b/test/libyul/yulSyntaxTests/switch_duplicate_case.yul @@ -1,9 +1,7 @@ { - switch 0:u256 - case 0:u256 {} - case 0x0:u256 {} + switch 0 + case 0 {} + case 0x0 {} } -// ==== -// dialect: evmTyped // ---- -// DeclarationError 6792: (34-50): Duplicate case "0x0" defined. +// DeclarationError 6792: (24-35): Duplicate case "0x0" defined. diff --git a/test/libyul/yulSyntaxTests/switch_duplicate_case_different_literal.yul b/test/libyul/yulSyntaxTests/switch_duplicate_case_different_literal.yul index 91f19efae1d6..e28ca3be0e12 100644 --- a/test/libyul/yulSyntaxTests/switch_duplicate_case_different_literal.yul +++ b/test/libyul/yulSyntaxTests/switch_duplicate_case_different_literal.yul @@ -1,9 +1,7 @@ { - switch 0:u256 - case 0:u256 {} - case "":u256 {} + switch 0 + case 0 {} + case "" {} } -// ==== -// dialect: evmTyped // ---- -// DeclarationError 6792: (34-49): Duplicate case "" defined. +// DeclarationError 6792: (24-34): Duplicate case "" defined. diff --git a/test/libyul/yulSyntaxTests/token_as_identifier.yul b/test/libyul/yulSyntaxTests/token_as_identifier.yul index 204b76e55533..ebb85bdb06de 100644 --- a/test/libyul/yulSyntaxTests/token_as_identifier.yul +++ b/test/libyul/yulSyntaxTests/token_as_identifier.yul @@ -1,6 +1,4 @@ { - let bool:u256 := 1:u256 + let bool := 1 } -// ==== -// dialect: evmTyped // ---- diff --git a/test/libyul/yulSyntaxTests/tuple_assignment.yul b/test/libyul/yulSyntaxTests/tuple_assignment.yul index 4ac961c265e5..40c4416f02f0 100644 --- a/test/libyul/yulSyntaxTests/tuple_assignment.yul +++ b/test/libyul/yulSyntaxTests/tuple_assignment.yul @@ -1,5 +1,5 @@ { - function f() -> a:u256, b:u256, c:u256 {} - let x:u256, y:u256, z:u256 := f() + function f() -> a, b, c {} + let x, y, z := f() } // ---- diff --git a/test/libyul/yulSyntaxTests/type_check_cases_fail_evmtyped.yul b/test/libyul/yulSyntaxTests/type_check_cases_fail_evmtyped.yul deleted file mode 100644 index 35926ccb29ee..000000000000 --- a/test/libyul/yulSyntaxTests/type_check_cases_fail_evmtyped.yul +++ /dev/null @@ -1,10 +0,0 @@ -{ - switch 7 - case true:bool {} - case true:bool {} -} -// ==== -// dialect: evmTyped -// ---- -// TypeError 3781: (24-33): Expected a value of type "u256" but got "bool". -// TypeError 3781: (46-55): Expected a value of type "u256" but got "bool". diff --git a/test/libyul/yulSyntaxTests/user_defined_functions_fail.yul b/test/libyul/yulSyntaxTests/user_defined_functions_fail.yul index 7b8d012bb597..dc837eb43179 100644 --- a/test/libyul/yulSyntaxTests/user_defined_functions_fail.yul +++ b/test/libyul/yulSyntaxTests/user_defined_functions_fail.yul @@ -1,12 +1,9 @@ { - function f(a:u256, b:u256, c:bool) -> r:bool, t { + function f(a, b, c) -> r, t { r := lt(a, b) - t := bool_to_u256(not(c)) + t := not(c) } - let x, y: bool := f(1, 2: u256, true) + let x, y := f(1, 2, true, false) } -// ==== -// dialect: evmTyped // ---- -// TypeError 3947: (126-127): Assigning value of type "bool" to variable of type "u256". -// TypeError 3947: (129-136): Assigning value of type "u256" to variable of type "bool". +// TypeError 7000: (100-101): Function "f" expects 3 arguments but got 4. diff --git a/test/libyul/yulSyntaxTests/user_defined_functions_fine.yul b/test/libyul/yulSyntaxTests/user_defined_functions_fine.yul index e24ea923ec75..ce79a9b6e931 100644 --- a/test/libyul/yulSyntaxTests/user_defined_functions_fine.yul +++ b/test/libyul/yulSyntaxTests/user_defined_functions_fine.yul @@ -1,10 +1,8 @@ { - function f(a:u256, b:u256, c:bool) -> r:bool, t { + function f(a, b, c) -> r, t { r := lt(a, b) - t := bool_to_u256(not(c)) + t := not(c) } - let x: bool, y: u256 := f(1, 2: u256, true) + let x, y := f(1, 2, true) } -// ==== -// dialect: evmTyped // ---- diff --git a/test/libyul/yulSyntaxTests/variable_declaration.yul b/test/libyul/yulSyntaxTests/variable_declaration.yul index 3d7c9d595c54..2bc22446a9c0 100644 --- a/test/libyul/yulSyntaxTests/variable_declaration.yul +++ b/test/libyul/yulSyntaxTests/variable_declaration.yul @@ -1,4 +1,2 @@ -{ let x:u256 := 7:u256 } -// ==== -// dialect: evmTyped +{ let x := 7 } // ---- diff --git a/test/libyul/yulSyntaxTests/variable_declaration_bool.yul b/test/libyul/yulSyntaxTests/variable_declaration_bool.yul index 3e97d5d4dae1..e49af9b91043 100644 --- a/test/libyul/yulSyntaxTests/variable_declaration_bool.yul +++ b/test/libyul/yulSyntaxTests/variable_declaration_bool.yul @@ -1,7 +1,5 @@ { - let x:bool := true:bool - let y:bool := false:bool + let x := true + let y := false } -// ==== -// dialect: evmTyped // ---- diff --git a/test/libyul/yulSyntaxTests/variable_declaration_complex.yul b/test/libyul/yulSyntaxTests/variable_declaration_complex.yul index e7a428fc2c92..6e07849fcac0 100644 --- a/test/libyul/yulSyntaxTests/variable_declaration_complex.yul +++ b/test/libyul/yulSyntaxTests/variable_declaration_complex.yul @@ -1,8 +1,6 @@ { - function add_fn(a:u256, b:u256) -> c:u256 {} - let y:u256 := 2:u256 - let x:u256 := add_fn(7:u256, add_fn(6:u256, y)) + function add_fn(a, b) -> c {} + let y := 2 + let x := add_fn(7, add_fn(6, y)) } -// ==== -// dialect: evmTyped // ---- diff --git a/test/libyul/yulSyntaxTests/variable_declaration_empty.yul b/test/libyul/yulSyntaxTests/variable_declaration_empty.yul index afbccb293a52..df81f297a770 100644 --- a/test/libyul/yulSyntaxTests/variable_declaration_empty.yul +++ b/test/libyul/yulSyntaxTests/variable_declaration_empty.yul @@ -1,2 +1,2 @@ -{ let x:u256 } +{ let x } // ---- From 83895d0f7d7c5e40f138826f6ce75ec543d0f322 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Tue, 13 Aug 2024 10:10:23 +0200 Subject: [PATCH 0348/1022] Error codes: Whitelist 1733 and 9547 as they rely on Yul types (which have been removed) --- scripts/error_codes.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/scripts/error_codes.py b/scripts/error_codes.py index fcb6f0e7f507..813d08330e31 100755 --- a/scripts/error_codes.py +++ b/scripts/error_codes.py @@ -205,6 +205,8 @@ def examine_id_coverage(top_dir, source_id_to_file_names, new_ids_only=False): "7053", # Unimplemented feature error (parsing stage), currently has no tests "2339", # SMTChecker, covered by CL tests "6240", # SMTChecker, covered by CL tests + "1733", # AsmAnalysis: expecting bool expression (everything is implicitly bool without types in Yul) + "9547", # AsmAnalysis: assigning incompatible types in Yul (whitelisted as there are currently no types) } assert len(test_ids & white_ids) == 0, "The sets are not supposed to intersect" test_ids |= white_ids From 63d87a28684dda2323dbebd3cd62148ab4a548c2 Mon Sep 17 00:00:00 2001 From: Alexander Arlt Date: Wed, 12 Jun 2024 14:36:31 +0200 Subject: [PATCH 0349/1022] Use submodules for some dependencies. --- .circleci/config.yml | 4 +- .gitmodules | 9 +++++ Changelog.md | 2 + cmake/fmtlib.cmake | 23 +++-------- cmake/nlohmann-json.cmake | 24 +++--------- cmake/range-v3.cmake | 41 ++++---------------- cmake/submodules.cmake | 23 +++++++++++ deps/fmtlib | 1 + deps/nlohmann-json | 1 + deps/range-v3 | 1 + libsolutil/CMakeLists.txt | 2 +- scripts/check_style.sh | 1 + scripts/chk_shellscripts/chk_shellscripts.sh | 2 +- scripts/create_source_tarball.sh | 2 + scripts/install_evmone.ps1 | 3 +- scripts/release_ppa.sh | 7 ---- 16 files changed, 64 insertions(+), 82 deletions(-) create mode 100644 .gitmodules create mode 100644 cmake/submodules.cmake create mode 160000 deps/fmtlib create mode 160000 deps/nlohmann-json create mode 160000 deps/range-v3 diff --git a/.circleci/config.yml b/.circleci/config.yml index 3426db329358..343bb6d00693 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -866,7 +866,7 @@ jobs: name: Check spelling command: | ~/.local/bin/codespell \ - --skip "*.enc,.git,Dockerfile*,LICENSE,codespell_whitelist.txt,codespell_ignored_lines.txt" \ + --skip "*.enc,.git,Dockerfile*,LICENSE,codespell_whitelist.txt,codespell_ignored_lines.txt,deps" \ --ignore-words scripts/codespell_whitelist.txt \ --exclude-file scripts/codespell_ignored_lines.txt - matrix_notify_failure_unless_pr @@ -1273,7 +1273,7 @@ jobs: - run: name: Install runtime dependencies command: | - pacman --noconfirm -Syu --noprogressbar --needed z3 + pacman --noconfirm -Syu --noprogressbar --needed z3 git - soltest t_ubu_clang_soltest: &t_ubu_clang_soltest diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 000000000000..47bcbb4fde94 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,9 @@ +[submodule "deps/nlohmann-json"] + path = deps/nlohmann-json + url = https://github.com/nlohmann/json.git +[submodule "deps/range-v3"] + path = deps/range-v3 + url = https://github.com/ericniebler/range-v3.git +[submodule "deps/fmtlib"] + path = deps/fmtlib + url = https://github.com/fmtlib/fmt.git diff --git a/Changelog.md b/Changelog.md index 1aebcc05aac2..2a1249c98a27 100644 --- a/Changelog.md +++ b/Changelog.md @@ -36,6 +36,8 @@ Bugfixes: * Yul Optimizer: Name simplification could lead to forbidden identifiers with a leading and/or trailing dot, e.g., ``x._`` would get simplified into ``x.``. * Yul Parser: Fix segfault when parsing very long location comments. +Build System: + * Change build system to use git submodules for some dependencies (nlohmann-json, fmtlib & range-v3). ### 0.8.26 (2024-05-21) diff --git a/cmake/fmtlib.cmake b/cmake/fmtlib.cmake index 032a68cd52a0..f9522aaecd00 100644 --- a/cmake/fmtlib.cmake +++ b/cmake/fmtlib.cmake @@ -1,20 +1,9 @@ -include(FetchContent) +include(${CMAKE_SOURCE_DIR}/cmake/submodules.cmake) +initialize_submodule(fmtlib) -FetchContent_Declare( - fmtlib - PREFIX "${PROJECT_BINARY_DIR}/deps" - DOWNLOAD_DIR "${PROJECT_SOURCE_DIR}/deps/downloads" - DOWNLOAD_NAME fmt-9.1.0.tar.gz - URL https://github.com/fmtlib/fmt/archive/9.1.0.tar.gz - URL_HASH SHA256=5dea48d1fcddc3ec571ce2058e13910a0d4a6bab4cc09a809d8b1dd1c88ae6f2 +set(FMT_SYSTEM_HEADERS ON) +add_subdirectory( + ${CMAKE_SOURCE_DIR}/deps/fmtlib + EXCLUDE_FROM_ALL ) -if (CMAKE_VERSION VERSION_LESS "3.14.0") - FetchContent_GetProperties(fmtlib) - if (NOT fmtlib_POPULATED) - FetchContent_Populate(fmtlib) - add_subdirectory(${fmtlib_SOURCE_DIR} ${fmtlib_BINARY_DIR}) - endif() -else() - FetchContent_MakeAvailable(fmtlib) -endif() diff --git a/cmake/nlohmann-json.cmake b/cmake/nlohmann-json.cmake index 02891e6a7ba6..638fcdd6502d 100644 --- a/cmake/nlohmann-json.cmake +++ b/cmake/nlohmann-json.cmake @@ -1,21 +1,9 @@ -include(ExternalProject) +include(${CMAKE_SOURCE_DIR}/cmake/submodules.cmake) +initialize_submodule(nlohmann-json) -ExternalProject_Add(nlohmann-json-project - DOWNLOAD_DIR "${CMAKE_SOURCE_DIR}/deps/nlohmann/nlohmann" - DOWNLOAD_NAME json.hpp - DOWNLOAD_NO_EXTRACT 1 - URL https://github.com/nlohmann/json/releases/download/v3.11.3/json.hpp - URL_HASH SHA256=9bea4c8066ef4a1c206b2be5a36302f8926f7fdc6087af5d20b417d0cf103ea6 - CMAKE_COMMAND true - BUILD_COMMAND true - INSTALL_COMMAND true +set(JSON_Install OFF CACHE INTERNAL "") +add_subdirectory( + ${CMAKE_SOURCE_DIR}/deps/nlohmann-json + EXCLUDE_FROM_ALL ) -# Create nlohmann-json imported library -add_library(nlohmann-json INTERFACE IMPORTED) -file(MAKE_DIRECTORY ${CMAKE_SOURCE_DIR}/deps/nlohmann) # Must exist. -set_target_properties(nlohmann-json PROPERTIES - INTERFACE_COMPILE_OPTIONS "\$<\$:/permissive->" - INTERFACE_SYSTEM_INCLUDE_DIRECTORIES ${CMAKE_SOURCE_DIR}/deps/nlohmann - INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_SOURCE_DIR}/deps/nlohmann) -add_dependencies(nlohmann-json nlohmann-json-project) \ No newline at end of file diff --git a/cmake/range-v3.cmake b/cmake/range-v3.cmake index d2f54452b319..eaab3b09e332 100644 --- a/cmake/range-v3.cmake +++ b/cmake/range-v3.cmake @@ -1,38 +1,11 @@ -include(ExternalProject) +include(${CMAKE_SOURCE_DIR}/cmake/submodules.cmake) +initialize_submodule(range-v3) -if (${CMAKE_SYSTEM_NAME} STREQUAL "Emscripten") - set(RANGE_V3_CMAKE_COMMAND emcmake cmake) -else() - set(RANGE_V3_CMAKE_COMMAND ${CMAKE_COMMAND}) -endif() - -set(prefix "${PROJECT_BINARY_DIR}/deps") -set(RANGE_V3_INCLUDE_DIR "${prefix}/include") - -ExternalProject_Add(range-v3-project - PREFIX "${prefix}" - DOWNLOAD_DIR "${PROJECT_SOURCE_DIR}/deps/downloads" - DOWNLOAD_NAME range-v3-0.12.0.tar.gz - URL https://github.com/ericniebler/range-v3/archive/0.12.0.tar.gz - URL_HASH SHA256=015adb2300a98edfceaf0725beec3337f542af4915cec4d0b89fa0886f4ba9cb - CMAKE_COMMAND ${RANGE_V3_CMAKE_COMMAND} - CMAKE_ARGS -DCMAKE_INSTALL_PREFIX= - -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} - -DBUILD_TESTING=OFF - -DRANGES_CXX_STD=${CMAKE_CXX_STANDARD} - -DRANGE_V3_DOCS=OFF - -DRANGE_V3_EXAMPLES=OFF - -DRANGE_V3_TESTS=OFF - -DRANGES_BUILD_CALENDAR_EXAMPLE=OFF - -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} - BUILD_BYPRODUCTS "${RANGE_V3_INCLUDE_DIR}/range/v3/all.hpp" -) - -# Create range-v3 imported library add_library(range-v3 INTERFACE IMPORTED) -file(MAKE_DIRECTORY ${RANGE_V3_INCLUDE_DIR}) # Must exist. set_target_properties(range-v3 PROPERTIES - INTERFACE_COMPILE_OPTIONS "\$<\$:/permissive->" - INTERFACE_SYSTEM_INCLUDE_DIRECTORIES ${RANGE_V3_INCLUDE_DIR} - INTERFACE_INCLUDE_DIRECTORIES ${RANGE_V3_INCLUDE_DIR}) + INTERFACE_COMPILE_OPTIONS "\$<\$:/permissive->" + INTERFACE_SYSTEM_INCLUDE_DIRECTORIES ${CMAKE_SOURCE_DIR}/deps/range-v3/include + INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_SOURCE_DIR}/deps/range-v3/include +) add_dependencies(range-v3 range-v3-project) + diff --git a/cmake/submodules.cmake b/cmake/submodules.cmake new file mode 100644 index 000000000000..099aceaa927d --- /dev/null +++ b/cmake/submodules.cmake @@ -0,0 +1,23 @@ +macro(initialize_submodule SUBMODULE_PATH) + if(NOT USE_SYSTEM_LIBRARIES) + file(GLOB submodule_contents "${CMAKE_SOURCE_DIR}/deps/${SUBMODULE_PATH}/*") + + if(submodule_contents) + message(STATUS "git submodule '${SUBMODULE_PATH}' seem to be already initialized: nothing to do.") + else() + message(STATUS "git submodule '${SUBMODULE_PATH}' seem not to be initialized: implicitly executing 'git submodule update --init '${CMAKE_SOURCE_DIR}/deps/${SUBMODULE_PATH}'.") + find_package(Git) + if(NOT Git_FOUND) + message(FATAL_ERROR "Failed to initialize submodules: 'git' command not found.") + endif() + execute_process( + COMMAND git submodule update --init ${CMAKE_SOURCE_DIR}/deps/${SUBMODULE_PATH} + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} + RESULT_VARIABLE result + ) + if(NOT result EQUAL 0) + message(FATAL_ERROR "Failed to initialize submodules: 'git submodule update --init' failed.") + endif() + endif() + endif() +endmacro() diff --git a/deps/fmtlib b/deps/fmtlib new file mode 160000 index 000000000000..a33701196adf --- /dev/null +++ b/deps/fmtlib @@ -0,0 +1 @@ +Subproject commit a33701196adfad74917046096bf5a2aa0ab0bb50 diff --git a/deps/nlohmann-json b/deps/nlohmann-json new file mode 160000 index 000000000000..9cca280a4d0c --- /dev/null +++ b/deps/nlohmann-json @@ -0,0 +1 @@ +Subproject commit 9cca280a4d0ccf0c08f47a99aa71d1b0e52f8d03 diff --git a/deps/range-v3 b/deps/range-v3 new file mode 160000 index 000000000000..a81477931a8a --- /dev/null +++ b/deps/range-v3 @@ -0,0 +1 @@ +Subproject commit a81477931a8aa2ad025c6bda0609f38e09e4d7ec diff --git a/libsolutil/CMakeLists.txt b/libsolutil/CMakeLists.txt index 291c95c0d14b..a1e9559edef0 100644 --- a/libsolutil/CMakeLists.txt +++ b/libsolutil/CMakeLists.txt @@ -44,7 +44,7 @@ set(sources ) add_library(solutil ${sources}) -target_link_libraries(solutil PUBLIC Boost::boost Boost::filesystem Boost::system range-v3 fmt::fmt-header-only nlohmann-json) +target_link_libraries(solutil PUBLIC Boost::boost Boost::filesystem Boost::system range-v3 fmt::fmt-header-only nlohmann_json::nlohmann_json) target_include_directories(solutil PUBLIC "${PROJECT_SOURCE_DIR}") add_dependencies(solutil solidity_BuildInfo.h) diff --git a/scripts/check_style.sh b/scripts/check_style.sh index dbe470c1aeb1..d67f7b60ca22 100755 --- a/scripts/check_style.sh +++ b/scripts/check_style.sh @@ -6,6 +6,7 @@ ERROR_LOG="$(mktemp -t check_style_XXXXXX.log)" EXCLUDE_FILES=( # The line below is left unquoted to allow the shell globbing path expansion + deps/* test/cmdlineTests/*/{err,output} "libsolutil/picosha2.h" "test/cmdlineTests/strict_asm_only_cr/input.yul" diff --git a/scripts/chk_shellscripts/chk_shellscripts.sh b/scripts/chk_shellscripts/chk_shellscripts.sh index f94d9f2da32d..fff9d2662ec9 100755 --- a/scripts/chk_shellscripts/chk_shellscripts.sh +++ b/scripts/chk_shellscripts/chk_shellscripts.sh @@ -13,5 +13,5 @@ if [ ! -f "${SHELLCHECK}" ]; then exit 1 fi -mapfile -t FILES < <(find . -type f -name "*.sh") +mapfile -t FILES < <(find . -type f -name "*.sh" -not -path "./deps/*") "${SHELLCHECK}" "${FILES[@]}" diff --git a/scripts/create_source_tarball.sh b/scripts/create_source_tarball.sh index 4af1cf586a47..37bee6df18b7 100755 --- a/scripts/create_source_tarball.sh +++ b/scripts/create_source_tarball.sh @@ -23,6 +23,8 @@ REPO_ROOT="$(dirname "$0")"/.. mkdir "$SOLDIR" # Store the current source git checkout-index -a --prefix="$SOLDIR" + # shellcheck disable=SC2016 + SOLDIR="$SOLDIR" git submodule foreach 'git checkout-index -a --prefix="$SOLDIR/$sm_path/"' # Store the commit hash echo "$commithash" > "$SOLDIR/commit_hash.txt" if [ -e prerelease.txt ] && [ ! -s prerelease.txt ] diff --git a/scripts/install_evmone.ps1 b/scripts/install_evmone.ps1 index acbacdafbd01..5864f249159d 100644 --- a/scripts/install_evmone.ps1 +++ b/scripts/install_evmone.ps1 @@ -5,5 +5,4 @@ $progressPreference = "silentlyContinue" Invoke-WebRequest -URI "https://github.com/ethereum/evmone/releases/download/v0.11.0/evmone-0.11.0-windows-amd64.zip" -OutFile "evmone.zip" tar -xf evmone.zip "bin/evmone.dll" -mkdir deps -mv bin/evmone.dll deps +mv bin/evmone.dll deps/ diff --git a/scripts/release_ppa.sh b/scripts/release_ppa.sh index 0e4eb7ed4d92..3b7c8347c067 100755 --- a/scripts/release_ppa.sh +++ b/scripts/release_ppa.sh @@ -123,13 +123,6 @@ ppafilesurl=https://launchpad.net/~ethereum/+archive/ubuntu/${pparepo}/+files git clone --depth 2 --recursive https://github.com/ethereum/solidity.git -b "$branch" mv solidity solc -# Fetch dependencies -mkdir -p ./solc/deps/downloads/ 2>/dev/null || true -mkdir -p ./solc/deps/nlohmann/nlohmann/ 2>/dev/null || true -wget -O ./solc/deps/nlohmann/nlohmann/json.hpp https://github.com/nlohmann/json/releases/download/v3.11.3/json.hpp -wget -O ./solc/deps/downloads/range-v3-0.12.0.tar.gz https://github.com/ericniebler/range-v3/archive/0.12.0.tar.gz -wget -O ./solc/deps/downloads/fmt-9.1.0.tar.gz https://github.com/fmtlib/fmt/archive/9.1.0.tar.gz - # Determine version cd solc version=$("$(dirname "$0")/get_version.sh") From 3de3c7bd98b9da2ef48eaecb48ff6543fb1b398e Mon Sep 17 00:00:00 2001 From: Nikola Matic Date: Fri, 9 Aug 2024 10:36:23 +0200 Subject: [PATCH 0350/1022] Bump evmone to v0.12.0 in CI Bump clang to 15 --- .../Dockerfile.ubuntu.clang.ossfuzz | 16 ++++++---------- .../docker/buildpack-deps/Dockerfile.ubuntu2004 | 6 +++--- .../docker/buildpack-deps/Dockerfile.ubuntu2204 | 16 ++++++---------- .../buildpack-deps/Dockerfile.ubuntu2204.clang | 16 ++++++---------- 4 files changed, 21 insertions(+), 33 deletions(-) diff --git a/scripts/docker/buildpack-deps/Dockerfile.ubuntu.clang.ossfuzz b/scripts/docker/buildpack-deps/Dockerfile.ubuntu.clang.ossfuzz index aae11521e50d..46137b400d45 100644 --- a/scripts/docker/buildpack-deps/Dockerfile.ubuntu.clang.ossfuzz +++ b/scripts/docker/buildpack-deps/Dockerfile.ubuntu.clang.ossfuzz @@ -22,7 +22,7 @@ # (c) 2016-2021 solidity contributors. #------------------------------------------------------------------------------ FROM gcr.io/oss-fuzz-base/base-clang:latest as base -LABEL version="7" +LABEL version="8" ARG DEBIAN_FRONTEND=noninteractive @@ -140,15 +140,11 @@ RUN set -ex; \ # EVMONE RUN set -ex; \ - cd /usr/src; \ - git clone --branch="v0.11.0" --recurse-submodules https://github.com/ethereum/evmone.git; \ - cd evmone; \ - mkdir build; \ - cd build; \ - CXX=clang++ cmake -G Ninja -DBUILD_SHARED_LIBS=OFF -DCMAKE_INSTALL_PREFIX="/usr" ..; \ - ninja; \ - ninja install/strip; \ - rm -rf /usr/src/evmone + wget -O /usr/src/evmone.tar.gz https://github.com/ethereum/evmone/releases/download/v0.12.0/evmone-0.12.0-linux-x86_64.tar.gz; \ + test "$(sha256sum /usr/src/evmone.tar.gz)" = "1c7b5eba0c8c3b3b2a7a05101e2d01a13a2f84b323989a29be66285dba4136ce /usr/src/evmone.tar.gz"; \ + cd /usr; \ + tar -xf /usr/src/evmone.tar.gz; \ + rm -rf /usr/src/evmone.tar.gz # gmp RUN set -ex; \ diff --git a/scripts/docker/buildpack-deps/Dockerfile.ubuntu2004 b/scripts/docker/buildpack-deps/Dockerfile.ubuntu2004 index 8b94fe9dd918..723192e2d0c4 100644 --- a/scripts/docker/buildpack-deps/Dockerfile.ubuntu2004 +++ b/scripts/docker/buildpack-deps/Dockerfile.ubuntu2004 @@ -22,7 +22,7 @@ # (c) 2016-2019 solidity contributors. #------------------------------------------------------------------------------ FROM buildpack-deps:focal AS base -LABEL version="24" +LABEL version="25" ARG DEBIAN_FRONTEND=noninteractive @@ -89,8 +89,8 @@ FROM base AS libraries # EVMONE RUN set -ex; \ - wget -O /usr/src/evmone.tar.gz https://github.com/ethereum/evmone/releases/download/v0.11.0/evmone-0.11.0-linux-x86_64.tar.gz; \ - test "$(sha256sum /usr/src/evmone.tar.gz)" = "051dbe523da165658ced63619ea2c05925516aac3061951da96d3f0962560719 /usr/src/evmone.tar.gz"; \ + wget -O /usr/src/evmone.tar.gz https://github.com/ethereum/evmone/releases/download/v0.12.0/evmone-0.12.0-linux-x86_64.tar.gz; \ + test "$(sha256sum /usr/src/evmone.tar.gz)" = "1c7b5eba0c8c3b3b2a7a05101e2d01a13a2f84b323989a29be66285dba4136ce /usr/src/evmone.tar.gz"; \ cd /usr; \ tar -xf /usr/src/evmone.tar.gz; \ rm -rf /usr/src/evmone.tar.gz diff --git a/scripts/docker/buildpack-deps/Dockerfile.ubuntu2204 b/scripts/docker/buildpack-deps/Dockerfile.ubuntu2204 index 90d5811c3b3c..add03bb00379 100644 --- a/scripts/docker/buildpack-deps/Dockerfile.ubuntu2204 +++ b/scripts/docker/buildpack-deps/Dockerfile.ubuntu2204 @@ -22,7 +22,7 @@ # (c) 2016-2019 solidity contributors. #------------------------------------------------------------------------------ FROM buildpack-deps:jammy AS base -LABEL version="9" +LABEL version="10" ARG DEBIAN_FRONTEND=noninteractive @@ -88,15 +88,11 @@ FROM base AS libraries # EVMONE RUN set -ex; \ - cd /usr/src; \ - git clone --branch="v0.11.0" --recurse-submodules https://github.com/ethereum/evmone.git; \ - cd evmone; \ - mkdir build; \ - cd build; \ - cmake -G Ninja -DBUILD_SHARED_LIBS=ON -DCMAKE_INSTALL_PREFIX="/usr" ..; \ - ninja; \ - ninja install/strip; \ - rm -rf /usr/src/evmone + wget -O /usr/src/evmone.tar.gz https://github.com/ethereum/evmone/releases/download/v0.12.0/evmone-0.12.0-linux-x86_64.tar.gz; \ + test "$(sha256sum /usr/src/evmone.tar.gz)" = "1c7b5eba0c8c3b3b2a7a05101e2d01a13a2f84b323989a29be66285dba4136ce /usr/src/evmone.tar.gz"; \ + cd /usr; \ + tar -xf /usr/src/evmone.tar.gz; \ + rm -rf /usr/src/evmone.tar.gz FROM base COPY --from=libraries /usr/lib /usr/lib diff --git a/scripts/docker/buildpack-deps/Dockerfile.ubuntu2204.clang b/scripts/docker/buildpack-deps/Dockerfile.ubuntu2204.clang index b2f75b0e43d1..b9c9158381eb 100644 --- a/scripts/docker/buildpack-deps/Dockerfile.ubuntu2204.clang +++ b/scripts/docker/buildpack-deps/Dockerfile.ubuntu2204.clang @@ -22,7 +22,7 @@ # (c) 2016-2019 solidity contributors. #------------------------------------------------------------------------------ FROM buildpack-deps:jammy AS base -LABEL version="8" +LABEL version="9" ARG DEBIAN_FRONTEND=noninteractive @@ -89,15 +89,11 @@ ENV CXX clang++ # EVMONE RUN set -ex; \ - cd /usr/src; \ - git clone --branch="v0.11.0" --recurse-submodules https://github.com/ethereum/evmone.git; \ - cd evmone; \ - mkdir build; \ - cd build; \ - cmake -G Ninja -DBUILD_SHARED_LIBS=ON -DCMAKE_INSTALL_PREFIX="/usr" ..; \ - ninja; \ - ninja install/strip; \ - rm -rf /usr/src/evmone + wget -O /usr/src/evmone.tar.gz https://github.com/ethereum/evmone/releases/download/v0.12.0/evmone-0.12.0-linux-x86_64.tar.gz; \ + test "$(sha256sum /usr/src/evmone.tar.gz)" = "1c7b5eba0c8c3b3b2a7a05101e2d01a13a2f84b323989a29be66285dba4136ce /usr/src/evmone.tar.gz"; \ + cd /usr; \ + tar -xf /usr/src/evmone.tar.gz; \ + rm -rf /usr/src/evmone.tar.gz FROM base COPY --from=libraries /usr/lib /usr/lib From 3d3b78e0a39163ef8449defdfa2b4659ded617e7 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Wed, 14 Aug 2024 13:35:20 +0200 Subject: [PATCH 0351/1022] Fix UB introduced by casting difference of two unsigneds to signed --- liblangutil/SemVerHandler.cpp | 2 +- libsolidity/codegen/ExpressionCompiler.cpp | 6 +++--- libyul/backends/evm/EVMCodeTransform.cpp | 2 +- libyul/backends/evm/NoOutputAssembly.cpp | 2 +- libyul/backends/evm/OptimizedEVMCodeTransform.cpp | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/liblangutil/SemVerHandler.cpp b/liblangutil/SemVerHandler.cpp index 2358eec5ef0d..e1a9556ca1a2 100644 --- a/liblangutil/SemVerHandler.cpp +++ b/liblangutil/SemVerHandler.cpp @@ -115,7 +115,7 @@ bool SemVerMatchExpression::MatchComponent::matches(SemVerVersion const& _versio if (version.numbers[i] != std::numeric_limits::max()) { didCompare = true; - cmp = static_cast(_version.numbers[i] - version.numbers[i]); + cmp = static_cast(_version.numbers[i]) - static_cast(version.numbers[i]); } if (cmp == 0 && !_version.prerelease.empty() && didCompare) diff --git a/libsolidity/codegen/ExpressionCompiler.cpp b/libsolidity/codegen/ExpressionCompiler.cpp index 368ee77a8651..95b7435ed608 100644 --- a/libsolidity/codegen/ExpressionCompiler.cpp +++ b/libsolidity/codegen/ExpressionCompiler.cpp @@ -436,7 +436,7 @@ bool ExpressionCompiler::visit(UnaryOperation const& _unaryOperation) unsigned returnParametersSize = CompilerUtils::sizeOnStack(functionType->returnParameterTypes()); // callee adds return parameters, but removes arguments and return label - m_context.adjustStackOffset(static_cast(returnParametersSize - parameterSize) - 1); + m_context.adjustStackOffset(static_cast(returnParametersSize) - static_cast(parameterSize) - 1); return false; } @@ -564,7 +564,7 @@ bool ExpressionCompiler::visit(BinaryOperation const& _binaryOperation) unsigned returnParametersSize = CompilerUtils::sizeOnStack(functionType->returnParameterTypes()); // callee adds return parameters, but removes arguments and return label - m_context.adjustStackOffset(static_cast(returnParametersSize - parameterSize) - 1); + m_context.adjustStackOffset(static_cast(returnParametersSize) - static_cast(parameterSize) - 1); return false; } @@ -721,7 +721,7 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall) unsigned returnParametersSize = CompilerUtils::sizeOnStack(function.returnParameterTypes()); // callee adds return parameters, but removes arguments and return label - m_context.adjustStackOffset(static_cast(returnParametersSize - parameterSize) - 1); + m_context.adjustStackOffset(static_cast(returnParametersSize) - static_cast(parameterSize) - 1); break; } case FunctionType::Kind::BareCall: diff --git a/libyul/backends/evm/EVMCodeTransform.cpp b/libyul/backends/evm/EVMCodeTransform.cpp index 21124723003b..71872a4e8c57 100644 --- a/libyul/backends/evm/EVMCodeTransform.cpp +++ b/libyul/backends/evm/EVMCodeTransform.cpp @@ -255,7 +255,7 @@ void CodeTransform::operator()(FunctionCall const& _call) m_assembly.setSourceLocation(originLocationOf(_call)); m_assembly.appendJumpTo( functionEntryID(*function), - static_cast(function->returns.size() - function->arguments.size()) - 1, + static_cast(function->returns.size()) - static_cast(function->arguments.size()) - 1, AbstractAssembly::JumpType::IntoFunction ); m_assembly.appendLabel(returnLabel); diff --git a/libyul/backends/evm/NoOutputAssembly.cpp b/libyul/backends/evm/NoOutputAssembly.cpp index 2a3cca52cc32..71818d2482f4 100644 --- a/libyul/backends/evm/NoOutputAssembly.cpp +++ b/libyul/backends/evm/NoOutputAssembly.cpp @@ -71,7 +71,7 @@ void NoOutputAssembly::appendLinkerSymbol(std::string const&) void NoOutputAssembly::appendVerbatim(bytes, size_t _arguments, size_t _returnVariables) { - m_stackHeight += static_cast(_returnVariables - _arguments); + m_stackHeight += static_cast(_returnVariables) - static_cast(_arguments); } void NoOutputAssembly::appendJump(int _stackDiffAfter, JumpType) diff --git a/libyul/backends/evm/OptimizedEVMCodeTransform.cpp b/libyul/backends/evm/OptimizedEVMCodeTransform.cpp index a6b867aba167..99f7114e9fb6 100644 --- a/libyul/backends/evm/OptimizedEVMCodeTransform.cpp +++ b/libyul/backends/evm/OptimizedEVMCodeTransform.cpp @@ -92,7 +92,7 @@ void OptimizedEVMCodeTransform::operator()(CFG::FunctionCall const& _call) m_assembly.setSourceLocation(originLocationOf(_call)); m_assembly.appendJumpTo( getFunctionLabel(_call.function), - static_cast(_call.function.get().returns.size() - _call.function.get().arguments.size()) - (_call.canContinue ? 1 : 0), + static_cast(_call.function.get().returns.size()) - static_cast(_call.function.get().arguments.size()) - (_call.canContinue ? 1 : 0), AbstractAssembly::JumpType::IntoFunction ); if (_call.canContinue) From da1bc0bc446d14ae48aca618d878ec3ff6a9d3a3 Mon Sep 17 00:00:00 2001 From: Martin Blicha Date: Wed, 14 Aug 2024 19:53:09 +0200 Subject: [PATCH 0352/1022] SMTChecker: Add setup of z3 to SMTSolverCommand This prepares SMTSolverCommand for invocation of Z3 as an external solver. Command line arguments enusure we match the way we set Z3 in our current code. --- libsolidity/interface/SMTSolverCommand.cpp | 29 ++++++++++++++++++++++ libsolidity/interface/SMTSolverCommand.h | 1 + 2 files changed, 30 insertions(+) diff --git a/libsolidity/interface/SMTSolverCommand.cpp b/libsolidity/interface/SMTSolverCommand.cpp index 8120e1f11aca..66adfd0c5e17 100644 --- a/libsolidity/interface/SMTSolverCommand.cpp +++ b/libsolidity/interface/SMTSolverCommand.cpp @@ -57,6 +57,35 @@ void SMTSolverCommand::setCvc5(std::optional timeoutInMilliseconds } } +void SMTSolverCommand::setZ3(std::optional timeoutInMilliseconds, bool _preprocessing, bool _computeInvariants) +{ + constexpr int Z3ResourceLimit = 2000000; + m_arguments.clear(); + m_solverCmd = "z3"; + m_arguments.emplace_back("-in"); // Read from standard input + m_arguments.emplace_back("-smt2"); // Expect input in SMT-LIB2 format + if (_computeInvariants) + m_arguments.emplace_back("-model"); // Output model automatically after check-sat + if (timeoutInMilliseconds) + m_arguments.emplace_back("-t:" + std::to_string(timeoutInMilliseconds.value())); + else + m_arguments.emplace_back("rlimit=" + std::to_string(Z3ResourceLimit)); + + // These options have been empirically established to be helpful + m_arguments.emplace_back("rewriter.pull_cheap_ite=true"); + m_arguments.emplace_back("fp.spacer.q3.use_qgen=true"); + m_arguments.emplace_back("fp.spacer.mbqi=false"); + m_arguments.emplace_back("fp.spacer.ground_pobs=false"); + + // Spacer optimization should be + // - enabled for better solving (default) + // - disable for counterexample generation + std::string preprocessingArg = _preprocessing ? "true" : "false"; + m_arguments.emplace_back("fp.xform.slice=" + preprocessingArg); + m_arguments.emplace_back("fp.xform.inline_linear=" + preprocessingArg); + m_arguments.emplace_back("fp.xform.inline_eager=" + preprocessingArg); +} + ReadCallback::Result SMTSolverCommand::solve(std::string const& _kind, std::string const& _query) const { try diff --git a/libsolidity/interface/SMTSolverCommand.h b/libsolidity/interface/SMTSolverCommand.h index c948ec5d2d65..13d79fe59583 100644 --- a/libsolidity/interface/SMTSolverCommand.h +++ b/libsolidity/interface/SMTSolverCommand.h @@ -38,6 +38,7 @@ class SMTSolverCommand void setEldarica(std::optional timeoutInMilliseconds, bool computeInvariants); void setCvc5(std::optional timeoutInMilliseconds); + void setZ3(std::optional timeoutInMilliseconds, bool _preprocessing, bool _computeInvariants); private: /// The name of the solver's binary. From 363274df8e113aec83f0b56c8bd612efda97ddb1 Mon Sep 17 00:00:00 2001 From: ljmanini <58728166+lmanini@users.noreply.github.com> Date: Thu, 15 Aug 2024 09:26:19 +0200 Subject: [PATCH 0353/1022] Update ContractCompiler.cpp Error msg fix --- libsolidity/codegen/ContractCompiler.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libsolidity/codegen/ContractCompiler.cpp b/libsolidity/codegen/ContractCompiler.cpp index 9e0593cdfb27..66cfe35c409a 100644 --- a/libsolidity/codegen/ContractCompiler.cpp +++ b/libsolidity/codegen/ContractCompiler.cpp @@ -1396,7 +1396,7 @@ bool ContractCompiler::visit(PlaceholderStatement const& _placeholderStatement) { StackHeightChecker checker(m_context); CompilerContext::LocationSetter locationSetter(m_context, _placeholderStatement); - solAssert(m_context.arithmetic() == Arithmetic::Checked, "Placeholder cannot be used inside checked block."); + solAssert(m_context.arithmetic() == Arithmetic::Checked, "Placeholder cannot be used inside unchecked block."); appendModifierOrFunctionCode(); solAssert(m_context.arithmetic() == Arithmetic::Checked, "Arithmetic not reset to 'checked'."); checker.check(); From fa781b7c4a226340410ddc5a235fd7db7a22fd80 Mon Sep 17 00:00:00 2001 From: Nikola Matic Date: Tue, 13 Aug 2024 13:44:04 +0200 Subject: [PATCH 0354/1022] Remove cmake dependency and bump boost in ossfuzz --- .../Dockerfile.ubuntu.clang.ossfuzz | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/scripts/docker/buildpack-deps/Dockerfile.ubuntu.clang.ossfuzz b/scripts/docker/buildpack-deps/Dockerfile.ubuntu.clang.ossfuzz index 46137b400d45..aae11521e50d 100644 --- a/scripts/docker/buildpack-deps/Dockerfile.ubuntu.clang.ossfuzz +++ b/scripts/docker/buildpack-deps/Dockerfile.ubuntu.clang.ossfuzz @@ -22,7 +22,7 @@ # (c) 2016-2021 solidity contributors. #------------------------------------------------------------------------------ FROM gcr.io/oss-fuzz-base/base-clang:latest as base -LABEL version="8" +LABEL version="7" ARG DEBIAN_FRONTEND=noninteractive @@ -140,11 +140,15 @@ RUN set -ex; \ # EVMONE RUN set -ex; \ - wget -O /usr/src/evmone.tar.gz https://github.com/ethereum/evmone/releases/download/v0.12.0/evmone-0.12.0-linux-x86_64.tar.gz; \ - test "$(sha256sum /usr/src/evmone.tar.gz)" = "1c7b5eba0c8c3b3b2a7a05101e2d01a13a2f84b323989a29be66285dba4136ce /usr/src/evmone.tar.gz"; \ - cd /usr; \ - tar -xf /usr/src/evmone.tar.gz; \ - rm -rf /usr/src/evmone.tar.gz + cd /usr/src; \ + git clone --branch="v0.11.0" --recurse-submodules https://github.com/ethereum/evmone.git; \ + cd evmone; \ + mkdir build; \ + cd build; \ + CXX=clang++ cmake -G Ninja -DBUILD_SHARED_LIBS=OFF -DCMAKE_INSTALL_PREFIX="/usr" ..; \ + ninja; \ + ninja install/strip; \ + rm -rf /usr/src/evmone # gmp RUN set -ex; \ From 1c21f8311a742d47c7621de0c395c441136ac63c Mon Sep 17 00:00:00 2001 From: Nikola Matic Date: Wed, 14 Aug 2024 11:34:28 +0200 Subject: [PATCH 0355/1022] Add ubuntu2404 docker image --- .github/workflows/buildpack-deps.yml | 3 +- scripts/ci/buildpack-deps_test_ubuntu2404.sh | 1 + .../buildpack-deps/Dockerfile.ubuntu2404 | 106 ++++++++++++++++++ 3 files changed, 109 insertions(+), 1 deletion(-) create mode 120000 scripts/ci/buildpack-deps_test_ubuntu2404.sh create mode 100644 scripts/docker/buildpack-deps/Dockerfile.ubuntu2404 diff --git a/.github/workflows/buildpack-deps.yml b/.github/workflows/buildpack-deps.yml index 2cd6e5048c07..5f66487e0798 100644 --- a/.github/workflows/buildpack-deps.yml +++ b/.github/workflows/buildpack-deps.yml @@ -9,6 +9,7 @@ on: - 'scripts/docker/buildpack-deps/Dockerfile.ubuntu2004' - 'scripts/docker/buildpack-deps/Dockerfile.ubuntu2204.clang' - 'scripts/docker/buildpack-deps/Dockerfile.ubuntu2204' + - 'scripts/docker/buildpack-deps/Dockerfile.ubuntu2404' jobs: buildpack-deps: @@ -23,7 +24,7 @@ jobs: strategy: fail-fast: false matrix: - image_variant: [emscripten, ubuntu.clang.ossfuzz, ubuntu2004, ubuntu2204.clang, ubuntu2204] + image_variant: [emscripten, ubuntu.clang.ossfuzz, ubuntu2004, ubuntu2204.clang, ubuntu2204, ubuntu2404] steps: - uses: actions/checkout@v4 diff --git a/scripts/ci/buildpack-deps_test_ubuntu2404.sh b/scripts/ci/buildpack-deps_test_ubuntu2404.sh new file mode 120000 index 000000000000..c07a74de4fb4 --- /dev/null +++ b/scripts/ci/buildpack-deps_test_ubuntu2404.sh @@ -0,0 +1 @@ +build.sh \ No newline at end of file diff --git a/scripts/docker/buildpack-deps/Dockerfile.ubuntu2404 b/scripts/docker/buildpack-deps/Dockerfile.ubuntu2404 new file mode 100644 index 000000000000..c7ad4594aab8 --- /dev/null +++ b/scripts/docker/buildpack-deps/Dockerfile.ubuntu2404 @@ -0,0 +1,106 @@ +# vim:syntax=dockerfile +#------------------------------------------------------------------------------ +# Dockerfile for building and testing Solidity Compiler on CI +# Target: Ubuntu 19.04 (Disco Dingo) +# URL: https://hub.docker.com/r/ethereum/solidity-buildpack-deps +# +# 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-2024 solidity contributors. +#------------------------------------------------------------------------------ +FROM buildpack-deps:noble AS base +LABEL version="1" + +ARG DEBIAN_FRONTEND=noninteractive + +# From Python3.11, pip requires a virtual environment, and will thus terminate when installing packages globally. +# Since we're building this image from scratch, it's perfectly fine to use the below flag. +ENV PIP_BREAK_SYSTEM_PACKAGES 1 + +RUN set -ex; \ + dist=$(grep DISTRIB_CODENAME /etc/lsb-release | cut -d= -f2); \ + echo "deb http://ppa.launchpad.net/ethereum/cpp-build-deps/ubuntu $dist main" >> /etc/apt/sources.list ; \ + apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 1c52189c923f6ca9 ; \ + apt-get update; \ + apt-get install -qqy --no-install-recommends \ + build-essential \ + cmake \ + jq \ + libboost-filesystem-dev \ + libboost-program-options-dev \ + libboost-system-dev \ + libboost-test-dev \ + libcln-dev \ + libz3-static-dev \ + locales-all \ + lsof \ + ninja-build \ + python3-pip \ + python3-sphinx \ + software-properties-common \ + sudo \ + unzip \ + z3-static \ + zip; \ + pip3 install \ + codecov \ + colorama \ + deepdiff \ + parsec \ + pygments-lexer-solidity \ + pylint \ + requests \ + tabulate \ + z3-solver; + +# Eldarica +RUN set -ex; \ + apt-get update; \ + apt-get install -qqy \ + openjdk-11-jre; \ + eldarica_version="2.1"; \ + wget "https://github.com/uuverifiers/eldarica/releases/download/v${eldarica_version}/eldarica-bin-${eldarica_version}.zip" -O /opt/eld_binaries.zip; \ + test "$(sha256sum /opt/eld_binaries.zip)" = "0ac43f45c0925383c9d2077f62bbb515fd792375f3b2b101b30c9e81dcd7785c /opt/eld_binaries.zip"; \ + unzip /opt/eld_binaries.zip -d /opt; \ + rm -f /opt/eld_binaries.zip; + +# CVC5 +RUN set -ex; \ + cvc5_version="1.1.2"; \ + wget "https://github.com/cvc5/cvc5/releases/download/cvc5-${cvc5_version}/cvc5-Linux-static.zip" -O /opt/cvc5.zip; \ + test "$(sha256sum /opt/cvc5.zip)" = "cf291aef67da8eaa8d425a51f67f3f72f36db8b1040655dc799b64e3d69e6086 /opt/cvc5.zip"; \ + unzip /opt/cvc5.zip -x "cvc5-Linux-static/lib/cmake/*" -d /opt; \ + mv /opt/cvc5-Linux-static/bin/* /usr/bin; \ + mv /opt/cvc5-Linux-static/include/* /usr/include; \ + mv /opt/cvc5-Linux-static/lib/* /usr/lib; \ + rm -rf /opt/cvc5-Linux-static /opt/cvc5.zip; + +FROM base AS libraries + +# EVMONE +RUN set -ex; \ + wget -O /usr/src/evmone.tar.gz https://github.com/ethereum/evmone/releases/download/v0.12.0/evmone-0.12.0-linux-x86_64.tar.gz; \ + test "$(sha256sum /usr/src/evmone.tar.gz)" = "1c7b5eba0c8c3b3b2a7a05101e2d01a13a2f84b323989a29be66285dba4136ce /usr/src/evmone.tar.gz"; \ + cd /usr; \ + tar -xf /usr/src/evmone.tar.gz; \ + rm -rf /usr/src/evmone.tar.gz + +FROM base +COPY --from=libraries /usr/lib /usr/lib +COPY --from=libraries /usr/bin /usr/bin +COPY --from=libraries /usr/include /usr/include +COPY --from=libraries /opt/eldarica /opt/eldarica +ENV PATH="$PATH:/opt/eldarica" From b9b1d08eedf2716b3237d239c4e99715e668cd11 Mon Sep 17 00:00:00 2001 From: Zuri Obozuwa Date: Wed, 3 Apr 2024 19:36:40 +0000 Subject: [PATCH 0356/1022] Pass vector of SMT expressions to SymbolicFunctionVariable function operator by const ref instead of by value To avoid the cost of copying the vector --- libsolidity/formal/SymbolicVariables.cpp | 2 +- libsolidity/formal/SymbolicVariables.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/libsolidity/formal/SymbolicVariables.cpp b/libsolidity/formal/SymbolicVariables.cpp index 6d6dbee65da5..f0cebc46c291 100644 --- a/libsolidity/formal/SymbolicVariables.cpp +++ b/libsolidity/formal/SymbolicVariables.cpp @@ -203,7 +203,7 @@ smtutil::Expression SymbolicFunctionVariable::increaseIndex() return m_abstract.currentValue(); } -smtutil::Expression SymbolicFunctionVariable::operator()(std::vector _arguments) const +smtutil::Expression SymbolicFunctionVariable::operator()(std::vector const& _arguments) const { return m_declaration(_arguments); } diff --git a/libsolidity/formal/SymbolicVariables.h b/libsolidity/formal/SymbolicVariables.h index 9fd37fe2a161..7dbe41d9453f 100644 --- a/libsolidity/formal/SymbolicVariables.h +++ b/libsolidity/formal/SymbolicVariables.h @@ -62,7 +62,7 @@ class SymbolicVariable virtual smtutil::Expression resetIndex(); virtual smtutil::Expression setIndex(unsigned _index); virtual smtutil::Expression increaseIndex(); - virtual smtutil::Expression operator()(std::vector /*_arguments*/) const + virtual smtutil::Expression operator()(std::vector const& /*_arguments*/) const { solAssert(false, "Function application to non-function."); } @@ -177,7 +177,7 @@ class SymbolicFunctionVariable: public SymbolicVariable smtutil::Expression setIndex(unsigned _index) override; smtutil::Expression increaseIndex() override; - smtutil::Expression operator()(std::vector _arguments) const override; + smtutil::Expression operator()(std::vector const& _arguments) const override; private: /// Creates a new function declaration. From a197cbe3ee6271479382ed6cd77aff024592006d Mon Sep 17 00:00:00 2001 From: Daniel Kirchner Date: Sun, 18 Aug 2024 22:16:47 +0200 Subject: [PATCH 0357/1022] Add back CLion build directories to .gitignore. --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index aafe93f97a0e..a9430fd98263 100644 --- a/.gitignore +++ b/.gitignore @@ -36,6 +36,7 @@ __pycache__/ *.app # Build directory +/cmake-build-*/ /build*/ emscripten_build/ /docs/_build/ From b172de55e9de0f5058fec7e27e8e41c1e57d2174 Mon Sep 17 00:00:00 2001 From: Martin Blicha Date: Thu, 15 Aug 2024 15:29:45 +0200 Subject: [PATCH 0358/1022] SMTChecker: Inline let expressions in solvers' models Models computed by CHC solvers (especially Z3) can contain SMT-LIB's let expressions. These are used to name a subterm and use the name instead of repeating the subterm possibly many times. The easiest (but not necessary the best) way to deal with let terms is to inline (expand) them. In our current experiments inlining did not pose any problem. If, in the future, this would turn out to cause problems, we can devise a way to process let terms without expanding the term to its full tree-like representation. This is part of the preparation to use Z3 as an external solver. It allows us to properly process models returned by Z3. --- libsmtutil/CHCSmtLib2Interface.cpp | 125 ++++++++++++++++++++++++++++- libsmtutil/CHCSmtLib2Interface.h | 3 + 2 files changed, 127 insertions(+), 1 deletion(-) diff --git a/libsmtutil/CHCSmtLib2Interface.cpp b/libsmtutil/CHCSmtLib2Interface.cpp index 8b795b9d5fd9..e17370562982 100644 --- a/libsmtutil/CHCSmtLib2Interface.cpp +++ b/libsmtutil/CHCSmtLib2Interface.cpp @@ -407,7 +407,7 @@ std::optional CHCSmtLib2Interface::invariantsFromSolverResp precondition(!isAtom(args[2])); precondition(isAtom(args[3]) && asAtom(args[3]) == "Bool"); auto& interpretation = args[4]; -// inlineLetExpressions(interpretation); + inlineLetExpressions(interpretation); ScopedParser scopedParser(m_context); auto const& formalArguments = asSubExpressions(args[2]); std::vector predicateArgs; @@ -432,3 +432,126 @@ std::optional CHCSmtLib2Interface::invariantsFromSolverResp return Expression::mkAnd(std::move(definitions)); } #undef precondition + +namespace +{ + +struct LetBindings +{ + using BindingRecord = std::vector; + std::unordered_map bindings; + std::vector varNames; + std::vector scopeBounds; + + bool has(std::string const& varName) { return bindings.find(varName) != bindings.end(); } + + SMTLib2Expression& operator[](std::string const& varName) + { + auto it = bindings.find(varName); + smtAssert(it != bindings.end()); + smtAssert(!it->second.empty()); + return it->second.back(); + } + + void pushScope() { scopeBounds.push_back(varNames.size()); } + + void popScope() + { + smtAssert(!scopeBounds.empty()); + auto bound = scopeBounds.back(); + while (varNames.size() > bound) + { + auto const& varName = varNames.back(); + auto it = bindings.find(varName); + smtAssert(it != bindings.end()); + auto& record = it->second; + record.pop_back(); + if (record.empty()) + bindings.erase(it); + varNames.pop_back(); + } + scopeBounds.pop_back(); + } + + void addBinding(std::string name, SMTLib2Expression expression) + { + auto it = bindings.find(name); + if (it == bindings.end()) + bindings.insert({name, {std::move(expression)}}); + else + it->second.push_back(std::move(expression)); + varNames.push_back(std::move(name)); + } +}; + +void inlineLetExpressions(SMTLib2Expression& _expr, LetBindings& _bindings) +{ + if (isAtom(_expr)) + { + auto const& atom = asAtom(_expr); + if (_bindings.has(atom)) + _expr = _bindings[atom]; + return; + } + auto& subexprs = asSubExpressions(_expr); + smtAssert(!subexprs.empty()); + auto const& first = subexprs.at(0); + if (isAtom(first) && asAtom(first) == "let") + { + smtAssert(subexprs.size() == 3); + smtAssert(!isAtom(subexprs[1])); + auto& bindingExpressions = asSubExpressions(subexprs[1]); + // process new bindings + std::vector> newBindings; + for (auto& binding: bindingExpressions) + { + smtAssert(!isAtom(binding)); + auto& bindingPair = asSubExpressions(binding); + smtAssert(bindingPair.size() == 2); + smtAssert(isAtom(bindingPair.at(0))); + inlineLetExpressions(bindingPair.at(1), _bindings); + newBindings.emplace_back(asAtom(bindingPair.at(0)), bindingPair.at(1)); + } + _bindings.pushScope(); + for (auto&& [name, expr]: newBindings) + _bindings.addBinding(std::move(name), std::move(expr)); + + newBindings.clear(); + + // get new subexpression + inlineLetExpressions(subexprs.at(2), _bindings); + // remove the new bindings + _bindings.popScope(); + + // update the expression + auto tmp = std::move(subexprs.at(2)); + _expr = std::move(tmp); + return; + } + else if (isAtom(first) && (asAtom(first) == "forall" || asAtom(first) == "exists")) + { + // A little hack to ensure quantified variables are not substituted because of some outer let definition: + // We define the current binding of the variable to itself, before we recurse in to subterm + smtAssert(subexprs.size() == 3); + _bindings.pushScope(); + for (auto const& sortedVar: asSubExpressions(subexprs.at(1))) + { + auto const& varNameExpr = asSubExpressions(sortedVar).at(0); + _bindings.addBinding(asAtom(varNameExpr), varNameExpr); + } + inlineLetExpressions(subexprs.at(2), _bindings); + _bindings.popScope(); + return; + } + + // not a let expression, just process all arguments recursively + for (auto& subexpr: subexprs) + inlineLetExpressions(subexpr, _bindings); +} +} + +void CHCSmtLib2Interface::inlineLetExpressions(SMTLib2Expression& expr) +{ + LetBindings bindings; + ::inlineLetExpressions(expr, bindings); +} diff --git a/libsmtutil/CHCSmtLib2Interface.h b/libsmtutil/CHCSmtLib2Interface.h index 0b81b4541c4c..b5baba7d6985 100644 --- a/libsmtutil/CHCSmtLib2Interface.h +++ b/libsmtutil/CHCSmtLib2Interface.h @@ -80,6 +80,9 @@ class CHCSmtLib2Interface: public CHCSolverInterface std::unordered_map m_localVariables; }; + /* Modifies the passed expression by inlining all let subexpressions */ + static void inlineLetExpressions(SMTLib2Expression& _expr); + std::string toSmtLibSort(SortPointer const& _sort); std::vector toSmtLibSort(std::vector const& _sort); From 3b532e468633e61e6d2660f6c07845dbbe78f31d Mon Sep 17 00:00:00 2001 From: Howe <69898694+DestinyWei@users.noreply.github.com> Date: Sun, 22 Oct 2023 22:03:45 +0800 Subject: [PATCH 0359/1022] docs: add the onlyBuyer modifier in function confirmPurchase() in the function confirmPurchase(), the annotation said 'Confirm the purchase as buyer.' but it doesn't add the `onlyBuyer` modifier --- docs/examples/safe-remote.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/examples/safe-remote.rst b/docs/examples/safe-remote.rst index a2651af23882..065aabdd9b6a 100644 --- a/docs/examples/safe-remote.rst +++ b/docs/examples/safe-remote.rst @@ -106,6 +106,7 @@ you can use state machine-like constructs inside a contract. /// is called. function confirmPurchase() external + onlyBuyer inState(State.Created) condition(msg.value == (2 * value)) payable From 91076d648de7829aa236670ac9a58aac47bb9ee8 Mon Sep 17 00:00:00 2001 From: Vishwa Mehta Date: Mon, 19 Aug 2024 18:13:55 +0530 Subject: [PATCH 0360/1022] Update safe-remote.rst Reverts the docs PR #14632. (see: https://github.com/ethereum/solidity/pull/14632#discussion_r1721715090) --- docs/examples/safe-remote.rst | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/examples/safe-remote.rst b/docs/examples/safe-remote.rst index 065aabdd9b6a..a2651af23882 100644 --- a/docs/examples/safe-remote.rst +++ b/docs/examples/safe-remote.rst @@ -106,7 +106,6 @@ you can use state machine-like constructs inside a contract. /// is called. function confirmPurchase() external - onlyBuyer inState(State.Created) condition(msg.value == (2 * value)) payable From 020bde963a1b9e4d05d8e89df50e7216729e4b81 Mon Sep 17 00:00:00 2001 From: Martin Blicha Date: Sat, 20 Jul 2024 10:23:01 +0200 Subject: [PATCH 0361/1022] SMTChecker: Translate bitvector constants properly Bit-vector constants in solvers' output can be represented in binary (starting with #b) or hexadecimal format (starting with #x). Handling of these constants were previously missing in our translation from SMT-LIB expressions. --- libsmtutil/CHCSmtLib2Interface.cpp | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/libsmtutil/CHCSmtLib2Interface.cpp b/libsmtutil/CHCSmtLib2Interface.cpp index e17370562982..6db1c6e876d0 100644 --- a/libsmtutil/CHCSmtLib2Interface.cpp +++ b/libsmtutil/CHCSmtLib2Interface.cpp @@ -200,6 +200,24 @@ bool isNumber(std::string const& _expr) { return ranges::all_of(_expr, [](char c) { return isDigit(c) || c == '.'; }); } + +bool isBitVectorHexConstant(std::string const& _string) +{ + if (_string.substr(0, 2) != "#x") + return false; + if (_string.find_first_not_of("0123456789abcdefABCDEF", 2) != std::string::npos) + return false; + return true; +} + +bool isBitVectorConstant(std::string const& _string) +{ + if (_string.substr(0, 2) != "#b") + return false; + if (_string.find_first_not_of("01", 2) != std::string::npos) + return false; + return true; +} } void CHCSmtLib2Interface::ScopedParser::addVariableDeclaration(std::string _name, solidity::smtutil::SortPointer _sort) @@ -279,6 +297,10 @@ smtutil::Expression CHCSmtLib2Interface::ScopedParser::toSMTUtilExpression(SMTLi return smtutil::Expression(_atom == "true"); else if (isNumber(_atom)) return smtutil::Expression(_atom, {}, SortProvider::sintSort); + else if (isBitVectorHexConstant(_atom)) + return smtutil::Expression(_atom, {}, std::make_shared((_atom.size() - 2) * 4)); + else if (isBitVectorConstant(_atom)) + return smtutil::Expression(_atom, {}, std::make_shared(_atom.size() - 2)); else if (auto it = m_localVariables.find(_atom); it != m_localVariables.end()) return smtutil::Expression(_atom, {}, it->second); else if (m_context.isDeclared(_atom)) From 06d2bdeb54a6205e7904471dbcd4d9299d2e403e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Mon, 22 Jul 2024 13:32:24 +0200 Subject: [PATCH 0362/1022] Object compiler tests for nested identical objects --- ...identical_subobjects_creation_deployed.yul | 107 +++++++++++ .../identical_subobjects_full_debug_info.yul | 114 ++++++++++++ .../identical_subobjects_no_debug_info.yul | 163 +++++++++++++++++ ...dentical_subobjects_partial_debug_info.yul | 151 ++++++++++++++++ ...bobjects_partial_debug_info_no_use_src.yul | 169 ++++++++++++++++++ ...cal_subobjects_with_subject_references.yul | 166 +++++++++++++++++ 6 files changed, 870 insertions(+) create mode 100644 test/libyul/objectCompiler/identical_subobjects_creation_deployed.yul create mode 100644 test/libyul/objectCompiler/identical_subobjects_full_debug_info.yul create mode 100644 test/libyul/objectCompiler/identical_subobjects_no_debug_info.yul create mode 100644 test/libyul/objectCompiler/identical_subobjects_partial_debug_info.yul create mode 100644 test/libyul/objectCompiler/identical_subobjects_partial_debug_info_no_use_src.yul create mode 100644 test/libyul/objectCompiler/identical_subobjects_with_subject_references.yul diff --git a/test/libyul/objectCompiler/identical_subobjects_creation_deployed.yul b/test/libyul/objectCompiler/identical_subobjects_creation_deployed.yul new file mode 100644 index 000000000000..5eb079db18d0 --- /dev/null +++ b/test/libyul/objectCompiler/identical_subobjects_creation_deployed.yul @@ -0,0 +1,107 @@ +// All objects have identical unoptimized code, but at 200 runs the creation objects will optimized +// differently from deployed objects. + +/// @use-src 0:"A.sol" +object "A" { + code { + function load(i) -> r { r := calldataload(i) } + let x := add(shl(255, 1), shl(127, not(0))) + sstore(load(x), load(1)) + } + + /// @use-src 0:"B.sol" + object "B_deployed" { + code { + function load(i) -> r { r := calldataload(i) } + let x := add(shl(255, 1), shl(127, not(0))) + sstore(load(x), load(1)) + } + + /// @use-src 0:"A.sol" + object "A" { + code { + function load(i) -> r { r := calldataload(i) } + let x := add(shl(255, 1), shl(127, not(0))) + sstore(load(x), load(1)) + } + + /// @use-src 0:"B.sol" + object "B_deployed" { + code { + function load(i) -> r { r := calldataload(i) } + let x := add(shl(255, 1), shl(127, not(0))) + sstore(load(x), load(1)) + } + } + + /// @use-src 0:"C.sol" + object "C" { + code { + function load(i) -> r { r := calldataload(i) } + let x := add(shl(255, 1), shl(127, not(0))) + sstore(load(x), load(1)) + } + } + } + } + + /// @use-src 0:"C.sol" + object "C_deployed" { + code { + function load(i) -> r { r := calldataload(i) } + let x := add(shl(255, 1), shl(127, not(0))) + sstore(load(x), load(1)) + } + } + + /// @use-src 0:"D.sol" + object "D" { + code { + function load(i) -> r { r := calldataload(i) } + let x := add(shl(255, 1), shl(127, not(0))) + sstore(load(x), load(1)) + } + } +} +// ==== +// optimizationPreset: full +// ---- +// Assembly: +// sstore(calldataload(sub(shl(0xff, 0x01), shl(0x7f, 0x01))), calldataload(0x01)) +// stop +// stop +// +// sub_0: assembly { +// sstore(calldataload(shl(0x7f, 0xffffffffffffffffffffffffffffffff)), calldataload(0x01)) +// stop +// stop +// +// sub_0: assembly { +// sstore(calldataload(sub(shl(0xff, 0x01), shl(0x7f, 0x01))), calldataload(0x01)) +// stop +// stop +// +// sub_0: assembly { +// sstore(calldataload(shl(0x7f, 0xffffffffffffffffffffffffffffffff)), calldataload(0x01)) +// stop +// } +// +// sub_1: assembly { +// sstore(calldataload(sub(shl(0xff, 0x01), shl(0x7f, 0x01))), calldataload(0x01)) +// stop +// } +// } +// } +// +// sub_1: assembly { +// sstore(calldataload(shl(0x7f, 0xffffffffffffffffffffffffffffffff)), calldataload(0x01)) +// stop +// } +// +// sub_2: assembly { +// sstore(calldataload(sub(shl(0xff, 0x01), shl(0x7f, 0x01))), calldataload(0x01)) +// stop +// } +// Bytecode: 6001356001607f1b600160ff1b03355500fe +// Opcodes: PUSH1 0x1 CALLDATALOAD PUSH1 0x1 PUSH1 0x7F SHL PUSH1 0x1 PUSH1 0xFF SHL SUB CALLDATALOAD SSTORE STOP INVALID +// SourceMappings: :::-:0;;;;;;;;;;; diff --git a/test/libyul/objectCompiler/identical_subobjects_full_debug_info.yul b/test/libyul/objectCompiler/identical_subobjects_full_debug_info.yul new file mode 100644 index 000000000000..74574be13c3f --- /dev/null +++ b/test/libyul/objectCompiler/identical_subobjects_full_debug_info.yul @@ -0,0 +1,114 @@ +// All objects have identical unoptimized code, but with different debug annotations. +// The optimized Yul will be identical only between objects that have identical debug info. + +/// @use-src 0:"A.sol" +object "A" { + code { + function load(i) -> r { r := calldataload(i) } + /// @src 0:10:20 + sstore(load(0), load(1)) + } + + /// @use-src 0:"B.sol" + object "B" { + code { + function load(i) -> r { r := calldataload(i) } + /// @src 0:10:20 + sstore(load(0), load(1)) + } + + /// @use-src 0:"A.sol" + object "A" { + code { + function load(i) -> r { r := calldataload(i) } + /// @src 0:10:20 + sstore(load(0), load(1)) + } + + /// @use-src 0:"B.sol" + object "B" { + code { + function load(i) -> r { r := calldataload(i) } + /// @src 0:10:20 + sstore(load(0), load(1)) + } + } + + /// @use-src 0:"C.sol" + object "C" { + code { + function load(i) -> r { r := calldataload(i) } + /// @src 0:10:20 + sstore(load(0), load(1)) + } + } + } + } + + /// @use-src 0:"C.sol" + object "C" { + code { + function load(i) -> r { r := calldataload(i) } + /// @src 0:10:20 + sstore(load(0), load(1)) + } + } + + /// @use-src 0:"D.sol" + object "D" { + code { + function load(i) -> r { r := calldataload(i) } + /// @src 0:10:20 + sstore(load(0), load(1)) + } + } +} +// ==== +// optimizationPreset: full +// ---- +// Assembly: +// /* "A.sol":10:20 */ +// sstore(calldataload(0x00), calldataload(0x01)) +// stop +// stop +// +// sub_0: assembly { +// /* "B.sol":10:20 */ +// sstore(calldataload(0x00), calldataload(0x01)) +// stop +// stop +// +// sub_0: assembly { +// /* "A.sol":10:20 */ +// sstore(calldataload(0x00), calldataload(0x01)) +// stop +// stop +// +// sub_0: assembly { +// /* "B.sol":10:20 */ +// sstore(calldataload(0x00), calldataload(0x01)) +// stop +// } +// +// sub_1: assembly { +// /* "C.sol":10:20 */ +// sstore(calldataload(0x00), calldataload(0x01)) +// stop +// } +// } +// } +// +// sub_1: assembly { +// /* "C.sol":10:20 */ +// sstore(calldataload(0x00), calldataload(0x01)) +// stop +// } +// +// sub_2: assembly { +// /* "D.sol":10:20 */ +// sstore(calldataload(0x00), calldataload(0x01)) +// stop +// } +// Bytecode: 6001355f355500fe +// Opcodes: PUSH1 0x1 CALLDATALOAD PUSH0 CALLDATALOAD SSTORE STOP INVALID +// SourceMappings: 10:10::-:0;-1:-1;10:10;-1:-1;10:10;-1:-1 diff --git a/test/libyul/objectCompiler/identical_subobjects_no_debug_info.yul b/test/libyul/objectCompiler/identical_subobjects_no_debug_info.yul new file mode 100644 index 000000000000..aa20ac6799b1 --- /dev/null +++ b/test/libyul/objectCompiler/identical_subobjects_no_debug_info.yul @@ -0,0 +1,163 @@ +// All objects have identical unoptimized code. +// After optimizations we should end up with identical code for all of them. + +object "A" { + code { + function load(i) -> r { r := calldataload(i) } + sstore(load(0), load(1)) + } + + object "B" { + code { + function load(i) -> r { r := calldataload(i) } + sstore(load(0), load(1)) + } + + object "A" { + code { + function load(i) -> r { r := calldataload(i) } + sstore(load(0), load(1)) + } + + object "B" { + code { + function load(i) -> r { r := calldataload(i) } + sstore(load(0), load(1)) + } + } + + object "C" { + code { + function load(i) -> r { r := calldataload(i) } + sstore(load(0), load(1)) + } + } + } + } + + object "C" { + code { + function load(i) -> r { r := calldataload(i) } + sstore(load(0), load(1)) + } + } + + object "D" { + code { + function load(i) -> r { r := calldataload(i) } + sstore(load(0), load(1)) + } + } +} +// ==== +// optimizationPreset: full +// ---- +// Assembly: +// /* "source":83:84 */ +// 0x01 +// /* "source":70:85 */ +// calldataload +// /* "source":66:67 */ +// 0x00 +// /* "source":53:68 */ +// calldataload +// /* "source":46:86 */ +// sstore +// /* "source":22:102 */ +// stop +// stop +// +// sub_0: assembly { +// /* "source":202:203 */ +// 0x01 +// /* "source":189:204 */ +// calldataload +// /* "source":185:186 */ +// 0x00 +// /* "source":172:187 */ +// calldataload +// /* "source":165:205 */ +// sstore +// /* "source":133:229 */ +// stop +// stop +// +// sub_0: assembly { +// /* "source":345:346 */ +// 0x01 +// /* "source":332:347 */ +// calldataload +// /* "source":328:329 */ +// 0x00 +// /* "source":315:330 */ +// calldataload +// /* "source":308:348 */ +// sstore +// /* "source":268:380 */ +// stop +// stop +// +// sub_0: assembly { +// /* "source":512:513 */ +// 0x01 +// /* "source":499:514 */ +// calldataload +// /* "source":495:496 */ +// 0x00 +// /* "source":482:497 */ +// calldataload +// /* "source":475:515 */ +// sstore +// /* "source":427:555 */ +// stop +// } +// +// sub_1: assembly { +// /* "source":701:702 */ +// 0x01 +// /* "source":688:703 */ +// calldataload +// /* "source":684:685 */ +// 0x00 +// /* "source":671:686 */ +// calldataload +// /* "source":664:704 */ +// sstore +// /* "source":616:744 */ +// stop +// } +// } +// } +// +// sub_1: assembly { +// /* "source":874:875 */ +// 0x01 +// /* "source":861:876 */ +// calldataload +// /* "source":857:858 */ +// 0x00 +// /* "source":844:859 */ +// calldataload +// /* "source":837:877 */ +// sstore +// /* "source":805:901 */ +// stop +// } +// +// sub_2: assembly { +// /* "source":1007:1008 */ +// 0x01 +// /* "source":994:1009 */ +// calldataload +// /* "source":990:991 */ +// 0x00 +// /* "source":977:992 */ +// calldataload +// /* "source":970:1010 */ +// sstore +// /* "source":938:1034 */ +// stop +// } +// Bytecode: 6001355f355500fe +// Opcodes: PUSH1 0x1 CALLDATALOAD PUSH0 CALLDATALOAD SSTORE STOP INVALID +// SourceMappings: 83:1:0:-:0;70:15;66:1;53:15;46:40;22:80 diff --git a/test/libyul/objectCompiler/identical_subobjects_partial_debug_info.yul b/test/libyul/objectCompiler/identical_subobjects_partial_debug_info.yul new file mode 100644 index 000000000000..9b63bdc1b12c --- /dev/null +++ b/test/libyul/objectCompiler/identical_subobjects_partial_debug_info.yul @@ -0,0 +1,151 @@ +// All objects have identical unoptimized code, but don't necessarily contain the same location comments. +// The optimized Yul will be identical only between objects that have identical debug info. +// Note that when @use-src is missing, the parser ignores location comments, so they do not become +// a part of the debug info. + +/// @use-src 0:"A.sol" +object "A" { + code { + function load(i) -> r { r := calldataload(i) } + /// @src 0:10:20 + sstore(load(0), load(1)) + } + + /// @use-src 0:"B.sol" + object "B" { + code { + function load(i) -> r { r := calldataload(i) } + /// @src 0:10:20 + sstore(load(0), load(1)) + } + + object "A" { + code { + function load(i) -> r { r := calldataload(i) } + sstore(load(0), load(1)) + } + + object "B" { + code { + function load(i) -> r { r := calldataload(i) } + sstore(load(0), load(1)) + } + } + + /// @use-src 0:"C.sol" + object "C" { + code { + function load(i) -> r { r := calldataload(i) } + /// @src 0:10:20 + sstore(load(0), load(1)) + } + } + } + } + + /// @use-src 0:"C.sol" + object "C" { + code { + function load(i) -> r { r := calldataload(i) } + /// @src 0:10:20 + sstore(load(0), load(1)) + } + } + + /// @use-src 0:"C.sol" + object "D" { + code { + function load(i) -> r { r := calldataload(i) } + sstore(load(0), load(1)) + } + } + + object "E" { + code { + function load(i) -> r { r := calldataload(i) } + /// @src 0:10:20 + sstore(load(0), load(1)) + } + } +} +// ==== +// optimizationPreset: full +// ---- +// Assembly: +// /* "A.sol":10:20 */ +// sstore(calldataload(0x00), calldataload(0x01)) +// stop +// stop +// +// sub_0: assembly { +// /* "B.sol":10:20 */ +// sstore(calldataload(0x00), calldataload(0x01)) +// stop +// stop +// +// sub_0: assembly { +// /* "source":621:622 */ +// 0x01 +// /* "source":608:623 */ +// calldataload +// /* "source":604:605 */ +// 0x00 +// /* "source":591:606 */ +// calldataload +// /* "source":584:624 */ +// sstore +// /* "source":544:656 */ +// stop +// stop +// +// sub_0: assembly { +// /* "source":788:789 */ +// 0x01 +// /* "source":775:790 */ +// calldataload +// /* "source":771:772 */ +// 0x00 +// /* "source":758:773 */ +// calldataload +// /* "source":751:791 */ +// sstore +// /* "source":703:831 */ +// stop +// } +// +// sub_1: assembly { +// /* "C.sol":10:20 */ +// sstore(calldataload(0x00), calldataload(0x01)) +// stop +// } +// } +// } +// +// sub_1: assembly { +// /* "C.sol":10:20 */ +// sstore(calldataload(0x00), calldataload(0x01)) +// stop +// } +// +// sub_2: assembly { +// sstore(calldataload(0x00), calldataload(0x01)) +// stop +// } +// +// sub_3: assembly { +// /* "source":1743:1744 */ +// 0x01 +// /* "source":1730:1745 */ +// calldataload +// /* "source":1726:1727 */ +// 0x00 +// /* "source":1713:1728 */ +// calldataload +// /* "source":1706:1746 */ +// sstore +// /* "source":1674:1770 */ +// stop +// } +// Bytecode: 6001355f355500fe +// Opcodes: PUSH1 0x1 CALLDATALOAD PUSH0 CALLDATALOAD SSTORE STOP INVALID +// SourceMappings: 10:10::-:0;-1:-1;10:10;-1:-1;10:10;-1:-1 diff --git a/test/libyul/objectCompiler/identical_subobjects_partial_debug_info_no_use_src.yul b/test/libyul/objectCompiler/identical_subobjects_partial_debug_info_no_use_src.yul new file mode 100644 index 000000000000..d288503babbf --- /dev/null +++ b/test/libyul/objectCompiler/identical_subobjects_partial_debug_info_no_use_src.yul @@ -0,0 +1,169 @@ +// All objects have identical unoptimized code, but don't necessarily contain the same location comments. +// After optimizations we should end up with identical code for all of them, because location +// comments will be ignored due to missing @use-src annotations and won't end up in the AST. + +object "A" { + code { + function load(i) -> r { r := calldataload(i) } + /// @src 0:10:20 + sstore(load(0), load(1)) + } + + object "B" { + code { + function load(i) -> r { r := calldataload(i) } + /// @src 0:10:20 + sstore(load(0), load(1)) + } + + object "A" { + code { + function load(i) -> r { r := calldataload(i) } + sstore(load(0), load(1)) + } + + object "B" { + code { + function load(i) -> r { r := calldataload(i) } + sstore(load(0), load(1)) + } + } + + object "C" { + code { + function load(i) -> r { r := calldataload(i) } + /// @src 0:10:20 + sstore(load(0), load(1)) + } + } + } + } + + object "C" { + code { + function load(i) -> r { r := calldataload(i) } + /// @src 0:10:20 + sstore(load(0), load(1)) + } + } + + object "D" { + code { + function load(i) -> r { r := calldataload(i) } + /// @src 0:10:20 + sstore(load(0), load(1)) + } + } +} +// ==== +// optimizationPreset: full +// ---- +// Assembly: +// /* "source":83:84 */ +// 0x01 +// /* "source":70:85 */ +// calldataload +// /* "source":66:67 */ +// 0x00 +// /* "source":53:68 */ +// calldataload +// /* "source":46:86 */ +// sstore +// /* "source":22:102 */ +// stop +// stop +// +// sub_0: assembly { +// /* "source":202:203 */ +// 0x01 +// /* "source":189:204 */ +// calldataload +// /* "source":185:186 */ +// 0x00 +// /* "source":172:187 */ +// calldataload +// /* "source":165:205 */ +// sstore +// /* "source":133:229 */ +// stop +// stop +// +// sub_0: assembly { +// /* "source":345:346 */ +// 0x01 +// /* "source":332:347 */ +// calldataload +// /* "source":328:329 */ +// 0x00 +// /* "source":315:330 */ +// calldataload +// /* "source":308:348 */ +// sstore +// /* "source":268:380 */ +// stop +// stop +// +// sub_0: assembly { +// /* "source":512:513 */ +// 0x01 +// /* "source":499:514 */ +// calldataload +// /* "source":495:496 */ +// 0x00 +// /* "source":482:497 */ +// calldataload +// /* "source":475:515 */ +// sstore +// /* "source":427:555 */ +// stop +// } +// +// sub_1: assembly { +// /* "source":701:702 */ +// 0x01 +// /* "source":688:703 */ +// calldataload +// /* "source":684:685 */ +// 0x00 +// /* "source":671:686 */ +// calldataload +// /* "source":664:704 */ +// sstore +// /* "source":616:744 */ +// stop +// } +// } +// } +// +// sub_1: assembly { +// /* "source":874:875 */ +// 0x01 +// /* "source":861:876 */ +// calldataload +// /* "source":857:858 */ +// 0x00 +// /* "source":844:859 */ +// calldataload +// /* "source":837:877 */ +// sstore +// /* "source":805:901 */ +// stop +// } +// +// sub_2: assembly { +// /* "source":1007:1008 */ +// 0x01 +// /* "source":994:1009 */ +// calldataload +// /* "source":990:991 */ +// 0x00 +// /* "source":977:992 */ +// calldataload +// /* "source":970:1010 */ +// sstore +// /* "source":938:1034 */ +// stop +// } +// Bytecode: 6001355f355500fe +// Opcodes: PUSH1 0x1 CALLDATALOAD PUSH0 CALLDATALOAD SSTORE STOP INVALID +// SourceMappings: 83:1:0:-:0;70:15;66:1;53:15;46:40;22:80 diff --git a/test/libyul/objectCompiler/identical_subobjects_with_subject_references.yul b/test/libyul/objectCompiler/identical_subobjects_with_subject_references.yul new file mode 100644 index 000000000000..e14b010083cb --- /dev/null +++ b/test/libyul/objectCompiler/identical_subobjects_with_subject_references.yul @@ -0,0 +1,166 @@ +// All objects have unoptimized code that's identical except for subobject and data object naming. +// The optimized Yul code does not depend on the content of subobjects and data objects, +// only on their names. EVM assembly, on the other hand, is not affected by names - it uses indices +// for subobjects and hashes for data objects. + +/// @use-src 0:"A.sol" +object "A" { + code { + function load(i) -> r { r := calldataload(i) } + sstore(load(0), load(dataoffset("B"))) + } + + /// @use-src 0:"B.sol" + object "B" { + code { + function load(i) -> r { r := calldataload(i) } + sstore(load(0), load(dataoffset("A"))) + } + + /// @use-src 0:"A.sol" + object "A" { + code { + function load(i) -> r { r := calldataload(i) } + sstore(load(0), load(dataoffset("B"))) + } + + /// @use-src 0:"B.sol" + object "B" { + code { + function load(i) -> r { r := calldataload(i) } + sstore(load(0), load(dataoffset("A"))) + } + + /// @use-src 0:"A.sol" + object "A" { + code { + function load(i) -> r { r := calldataload(i) } + sstore(load(0), load(dataoffset("B"))) + } + + data "B" "0xbb" + } + } + + /// @use-src 0:"C.sol" + object "C" { + code { + function load(i) -> r { r := calldataload(i) } + sstore(load(0), load(dataoffset("A"))) + } + + data "A" "0xaa" + } + + /// @use-src 0:"D.sol" + object "D" { + code { + function load(i) -> r { r := calldataload(i) } + sstore(load(0), load(dataoffset("A"))) + } + + data "A" "0xaaaaaa" + } + } + } + + /// @use-src 0:"C.sol" + object "C" { + code { + function load(i) -> r { r := calldataload(i) } + sstore(load(0), load(dataoffset("A"))) + } + + data "A" "0xaaaa" + } + + /// @use-src 0:"D.sol" + object "D" { + code { + function load(i) -> r { r := calldataload(i) } + sstore(load(0), load(dataoffset("B"))) + } + + data "B" "0xbbbb" + } + + /// @use-src 0:"E.sol" + object "E" { + code { + function load(i) -> r { r := calldataload(i) } + sstore(load(0), load(dataoffset("B"))) + } + + data "B" "0xbbbb" + } +} +// ==== +// optimizationPreset: full +// ---- +// Assembly: +// sstore(calldataload(0x00), calldataload(dataOffset(sub_0))) +// stop +// stop +// +// sub_0: assembly { +// sstore(calldataload(0x00), calldataload(dataOffset(sub_0))) +// stop +// stop +// +// sub_0: assembly { +// sstore(calldataload(0x00), calldataload(dataOffset(sub_0))) +// stop +// stop +// +// sub_0: assembly { +// sstore(calldataload(0x00), calldataload(dataOffset(sub_0))) +// stop +// stop +// +// sub_0: assembly { +// sstore(calldataload(0x00), calldataload(data_736ddcdd19b41ff3aa09bd89628fc69562c2e39bdb07c1971217d2e374ce6e27)) +// stop +// stop +// data_736ddcdd19b41ff3aa09bd89628fc69562c2e39bdb07c1971217d2e374ce6e27 30786262 +// } +// } +// +// sub_1: assembly { +// sstore(calldataload(0x00), calldataload(data_89b1fd0f9a40d0a598af5f997daf99fc3d5b98ef4eb429e81755ae0ee49e194e)) +// stop +// stop +// data_89b1fd0f9a40d0a598af5f997daf99fc3d5b98ef4eb429e81755ae0ee49e194e 30786161 +// } +// +// sub_2: assembly { +// sstore(calldataload(0x00), calldataload(data_d8bbdaa6a33092aa88c90c124bdeea5160229ede56dd7d897c2413f9ba7e4f85)) +// stop +// stop +// data_d8bbdaa6a33092aa88c90c124bdeea5160229ede56dd7d897c2413f9ba7e4f85 3078616161616161 +// } +// } +// } +// +// sub_1: assembly { +// sstore(calldataload(0x00), calldataload(data_79f4f313d7d500fd317e5283225bdfe6ea44da3fb73f1fdbf19929f3164bfc1a)) +// stop +// stop +// data_79f4f313d7d500fd317e5283225bdfe6ea44da3fb73f1fdbf19929f3164bfc1a 307861616161 +// } +// +// sub_2: assembly { +// sstore(calldataload(0x00), calldataload(data_257dd53638d790f0311f866044a2856def338f9a4d22fce0bdeed5b2d53851a9)) +// stop +// stop +// data_257dd53638d790f0311f866044a2856def338f9a4d22fce0bdeed5b2d53851a9 307862626262 +// } +// +// sub_3: assembly { +// sstore(calldataload(0x00), calldataload(data_257dd53638d790f0311f866044a2856def338f9a4d22fce0bdeed5b2d53851a9)) +// stop +// stop +// data_257dd53638d790f0311f866044a2856def338f9a4d22fce0bdeed5b2d53851a9 307862626262 +// } +// Bytecode: 6008355f355500fe6008355f355500fe6008355f355500fe6008355f355500fe6008355f355500fe30786262 +// Opcodes: PUSH1 0x8 CALLDATALOAD PUSH0 CALLDATALOAD SSTORE STOP INVALID PUSH1 0x8 CALLDATALOAD PUSH0 CALLDATALOAD SSTORE STOP INVALID PUSH1 0x8 CALLDATALOAD PUSH0 CALLDATALOAD SSTORE STOP INVALID PUSH1 0x8 CALLDATALOAD PUSH0 CALLDATALOAD SSTORE STOP INVALID PUSH1 0x8 CALLDATALOAD PUSH0 CALLDATALOAD SSTORE STOP INVALID ADDRESS PUSH25 0x62620000000000000000000000000000000000000000000000 +// SourceMappings: :::-:0;;;;; From 8f237deb99b2202672262d374259ce184ef648eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Wed, 12 Jun 2024 17:20:57 +0200 Subject: [PATCH 0363/1022] Object: Add missing `override` specifier to overridden methods --- libyul/Object.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libyul/Object.h b/libyul/Object.h index 41ca74e9f321..fe946f1bd102 100644 --- a/libyul/Object.h +++ b/libyul/Object.h @@ -99,9 +99,9 @@ struct Object: public ObjectNode AsmPrinter::TypePrinting printingMode = AsmPrinter::TypePrinting::Full, langutil::DebugInfoSelection const& _debugInfoSelection = langutil::DebugInfoSelection::Default(), langutil::CharStreamProvider const* _soliditySourceProvider = nullptr - ) const; + ) const override; /// @returns a compact JSON representation of the AST. - Json toJson() const; + Json toJson() const override; /// @returns the set of names of data objects accessible from within the code of /// this object, including the name of object itself /// Handles all names containing dots as reserved identifiers, not accessible as data. From 6654e87735d11c265de2e86553a96b865873a239 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Wed, 12 Jun 2024 17:43:53 +0200 Subject: [PATCH 0364/1022] ObjectDebugData: Expose a helper for formatting the @use-src comment --- libyul/Object.cpp | 31 ++++++++++++++++++++----------- libyul/Object.h | 2 ++ 2 files changed, 22 insertions(+), 11 deletions(-) diff --git a/libyul/Object.cpp b/libyul/Object.cpp index c4e7971ab4f7..57c783b83f39 100644 --- a/libyul/Object.cpp +++ b/libyul/Object.cpp @@ -53,16 +53,6 @@ std::string Object::toString( yulAssert(hasCode(), "No code"); yulAssert(debugData, "No debug data"); - std::string useSrcComment; - - if (debugData->sourceNames) - useSrcComment = - "/// @use-src " + - joinHumanReadable(ranges::views::transform(*debugData->sourceNames, [](auto&& _pair) { - return std::to_string(_pair.first) + ":" + util::escapeAndQuoteString(*_pair.second); - })) + - "\n"; - std::string inner = "code " + AsmPrinter( _printingMode, _dialect, @@ -74,7 +64,11 @@ std::string Object::toString( for (auto const& obj: subObjects) inner += "\n" + obj->toString(_dialect, _printingMode, _debugInfoSelection, _soliditySourceProvider); - return useSrcComment + "object \"" + name + "\" {\n" + indent(inner) + "\n}"; + return + debugData->formatUseSrcComment() + + "object \"" + name + "\" {\n" + + indent(inner) + "\n" + + "}"; } Json Data::toJson() const @@ -85,6 +79,21 @@ Json Data::toJson() const return ret; } +std::string ObjectDebugData::formatUseSrcComment() const +{ + if (!sourceNames) + return ""; + + auto formatIdNamePair = [](auto&& _pair) { + return std::to_string(_pair.first) + ":" + util::escapeAndQuoteString(*_pair.second); + }; + + std::string serializedSourceNames = joinHumanReadable( + ranges::views::transform(*sourceNames, formatIdNamePair) + ); + return "/// @use-src " + serializedSourceNames + "\n"; +} + Json Object::toJson() const { yulAssert(hasCode(), "No code"); diff --git a/libyul/Object.h b/libyul/Object.h index fe946f1bd102..fa9ef96eebc7 100644 --- a/libyul/Object.h +++ b/libyul/Object.h @@ -84,6 +84,8 @@ struct Data: public ObjectNode struct ObjectDebugData { std::optional sourceNames = {}; + + std::string formatUseSrcComment() const; }; From 27daf268e1f680662910957dca3f3a31c88545ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Wed, 31 Jul 2024 20:31:29 +0200 Subject: [PATCH 0365/1022] Caching of optimized IR --- Changelog.md | 1 + libsolidity/interface/CompilerStack.cpp | 7 +- libsolidity/interface/CompilerStack.h | 3 + libyul/CMakeLists.txt | 2 + libyul/ObjectOptimizer.cpp | 167 ++++++++++++++++++++++++ libyul/ObjectOptimizer.h | 95 ++++++++++++++ libyul/YulStack.cpp | 112 ++++++---------- libyul/YulStack.h | 13 +- 8 files changed, 319 insertions(+), 81 deletions(-) create mode 100644 libyul/ObjectOptimizer.cpp create mode 100644 libyul/ObjectOptimizer.h diff --git a/Changelog.md b/Changelog.md index 2a1249c98a27..034be57733bc 100644 --- a/Changelog.md +++ b/Changelog.md @@ -19,6 +19,7 @@ Compiler Features: * Standard JSON Interface: Do not perform IR optimization when only unoptimized IR is requested. * Standard JSON Interface: Add ``transientStorageLayout`` output. * Yul: Drop the deprecated typed Yul dialect that was only accessible via ``--yul`` in the CLI. + * Yul Optimizer: Caching of optimized IR to speed up optimization of contracts with bytecode dependencies. * Yul Optimizer: The optimizer now treats some previously unrecognized identical literals as identical. * Commandline Interface: Allow the use of ``--asm-json`` output option in assembler mode to export EVM assembly of the contracts in JSON format. diff --git a/libsolidity/interface/CompilerStack.cpp b/libsolidity/interface/CompilerStack.cpp index 0ea7131db140..1f432db40fca 100644 --- a/libsolidity/interface/CompilerStack.cpp +++ b/libsolidity/interface/CompilerStack.cpp @@ -111,6 +111,7 @@ static int g_compilerStackCounts = 0; CompilerStack::CompilerStack(ReadCallback::Callback _readFile): m_readFile{std::move(_readFile)}, + m_objectOptimizer(std::make_shared()), m_errorReporter{m_errorList} { // Because TypeProvider is currently a singleton API, we must ensure that @@ -1493,7 +1494,8 @@ void CompilerStack::generateIR(ContractDefinition const& _contract, bool _unopti m_eofVersion, YulStack::Language::StrictAssembly, m_optimiserSettings, - m_debugInfoSelection + m_debugInfoSelection, + m_objectOptimizer ); bool yulAnalysisSuccessful = stack.parseAndAnalyze("", compiledContract.yulIR); solAssert( @@ -1530,7 +1532,8 @@ void CompilerStack::generateEVMFromIR(ContractDefinition const& _contract) m_eofVersion, yul::YulStack::Language::StrictAssembly, m_optimiserSettings, - m_debugInfoSelection + m_debugInfoSelection, + m_objectOptimizer ); bool analysisSuccessful = stack.parseAndAnalyze("", compiledContract.yulIROptimized); solAssert(analysisSuccessful); diff --git a/libsolidity/interface/CompilerStack.h b/libsolidity/interface/CompilerStack.h index 159a14d8d84d..6ca792296f27 100644 --- a/libsolidity/interface/CompilerStack.h +++ b/libsolidity/interface/CompilerStack.h @@ -49,6 +49,8 @@ #include #include +#include + #include #include #include @@ -552,6 +554,7 @@ class CompilerStack: public langutil::CharStreamProvider, public evmasm::Abstrac std::shared_ptr m_globalContext; std::vector m_sourceOrder; std::map m_contracts; + std::shared_ptr m_objectOptimizer; langutil::ErrorList m_errorList; langutil::ErrorReporter m_errorReporter; diff --git a/libyul/CMakeLists.txt b/libyul/CMakeLists.txt index ee78d525dfc7..dbf3bfdcd6a1 100644 --- a/libyul/CMakeLists.txt +++ b/libyul/CMakeLists.txt @@ -29,6 +29,8 @@ add_library(yul FunctionReferenceResolver.h Object.cpp Object.h + ObjectOptimizer.cpp + ObjectOptimizer.h ObjectParser.cpp ObjectParser.h Scope.cpp diff --git a/libyul/ObjectOptimizer.cpp b/libyul/ObjectOptimizer.cpp new file mode 100644 index 000000000000..eaaac97d56a4 --- /dev/null +++ b/libyul/ObjectOptimizer.cpp @@ -0,0 +1,167 @@ +/* + This file is part of solidity. + + solidity is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + solidity is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with solidity. If not, see . +*/ +// SPDX-License-Identifier: GPL-3.0 + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +#include + +#include +#include + +using namespace solidity; +using namespace solidity::langutil; +using namespace solidity::util; +using namespace solidity::yul; + + +Dialect const& yul::languageToDialect(Language _language, EVMVersion _version) +{ + switch (_language) + { + case Language::Assembly: + case Language::StrictAssembly: + return EVMDialect::strictAssemblyForEVMObjects(_version); + } + util::unreachable(); +} + +void ObjectOptimizer::optimize(Object& _object, Settings const& _settings) +{ + yulAssert(_object.subId == std::numeric_limits::max(), "Not a top-level object."); + + optimize(_object, _settings, true /* _isCreation */); +} + +void ObjectOptimizer::optimize(Object& _object, Settings const& _settings, bool _isCreation) +{ + yulAssert(_object.code()); + yulAssert(_object.debugData); + + for (auto& subNode: _object.subObjects) + if (auto subObject = dynamic_cast(subNode.get())) + { + bool isCreation = !boost::ends_with(subObject->name, "_deployed"); + optimize( + *subObject, + _settings, + isCreation + ); + } + + Dialect const& dialect = languageToDialect(_settings.language, _settings.evmVersion); + std::unique_ptr meter; + if (EVMDialect const* evmDialect = dynamic_cast(&dialect)) + meter = std::make_unique(*evmDialect, _isCreation, _settings.expectedExecutionsPerDeployment); + + std::optional cacheKey = calculateCacheKey(_object.code()->root(), *_object.debugData, _settings, _isCreation); + if (cacheKey.has_value() && m_cachedObjects.count(*cacheKey) != 0) + { + overwriteWithOptimizedObject(*cacheKey, _object); + return; + } + + OptimiserSuite::run( + dialect, + meter.get(), + _object, + _settings.optimizeStackAllocation, + _settings.yulOptimiserSteps, + _settings.yulOptimiserCleanupSteps, + _isCreation ? std::nullopt : std::make_optional(_settings.expectedExecutionsPerDeployment), + {} + ); + + if (cacheKey.has_value()) + storeOptimizedObject(*cacheKey, _object, dialect); +} + +void ObjectOptimizer::storeOptimizedObject(util::h256 _cacheKey, Object const& _optimizedObject, Dialect const& _dialect) +{ + m_cachedObjects[_cacheKey] = CachedObject{ + std::make_shared(ASTCopier{}.translate(_optimizedObject.code()->root())), + &_dialect, + }; +} + +void ObjectOptimizer::overwriteWithOptimizedObject(util::h256 _cacheKey, Object& _object) const +{ + yulAssert(m_cachedObjects.count(_cacheKey) != 0); + CachedObject const& cachedObject = m_cachedObjects.at(_cacheKey); + + yulAssert(cachedObject.optimizedAST); + _object.setCode(std::make_shared(ASTCopier{}.translate(*cachedObject.optimizedAST))); + yulAssert(_object.code()); + + // There's no point in caching AnalysisInfo because it references AST nodes. It can't be shared + // by multiple ASTs and it's easier to recalculate it than properly clone it. + yulAssert(cachedObject.dialect); + _object.analysisInfo = std::make_shared( + AsmAnalyzer::analyzeStrictAssertCorrect( + *cachedObject.dialect, + _object + ) + ); + + // NOTE: Source name index is included in the key so it must be identical. No need to store and restore it. +} + +std::optional ObjectOptimizer::calculateCacheKey( + Block const& _ast, + ObjectDebugData const& _debugData, + Settings const& _settings, + bool _isCreation +) +{ + AsmPrinter asmPrinter( + AsmPrinter::TypePrinting::OmitDefault, + languageToDialect(_settings.language, _settings.evmVersion), + _debugData.sourceNames, + DebugInfoSelection::All() + ); + + bytes rawKey; + // NOTE: AsmPrinter never prints nativeLocations included in debug data, so ASTs differing only + // in that regard are considered equal here. This is fine because the optimizer does not keep + // them up to date across AST transformations anyway so in any use where they need to be reliable, + // we just regenerate them by reparsing the object. + rawKey += keccak256(asmPrinter(_ast)).asBytes(); + rawKey += keccak256(_debugData.formatUseSrcComment()).asBytes(); + rawKey += h256(u256(_settings.language)).asBytes(); + rawKey += FixedHash<1>(uint8_t(_settings.optimizeStackAllocation ? 0 : 1)).asBytes(); + rawKey += h256(u256(_settings.expectedExecutionsPerDeployment)).asBytes(); + rawKey += FixedHash<1>(uint8_t(_isCreation ? 0 : 1)).asBytes(); + rawKey += keccak256(_settings.evmVersion.name()).asBytes(); + rawKey += keccak256(_settings.yulOptimiserSteps).asBytes(); + rawKey += keccak256(_settings.yulOptimiserCleanupSteps).asBytes(); + + return h256(keccak256(rawKey)); +} diff --git a/libyul/ObjectOptimizer.h b/libyul/ObjectOptimizer.h new file mode 100644 index 000000000000..89e5739be7da --- /dev/null +++ b/libyul/ObjectOptimizer.h @@ -0,0 +1,95 @@ +/* + This file is part of solidity. + + solidity is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + solidity is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with solidity. If not, see . +*/ +// SPDX-License-Identifier: GPL-3.0 + +#pragma once + +#include +#include + +#include + +#include + +#include +#include +#include + +namespace solidity::yul +{ + +enum class Language +{ + Assembly, + StrictAssembly, +}; + +Dialect const& languageToDialect(Language _language, langutil::EVMVersion _version); + +/// Encapsulates logic for applying @a yul::OptimiserSuite to a whole hierarchy of Yul objects. +/// Also, acts as a transparent cache for optimized objects. +/// +/// The cache is designed to allow sharing its instances widely across the compiler, without the +/// need to invalidate entries due to changing settings or context. +/// Caching is performed at the granularity of individual ASTs rather than whole object trees, +/// which means that reuse is possible even within a single hierarchy, e.g. when creation and +/// deployed objects have common dependencies. +class ObjectOptimizer +{ +public: + /// Optimization settings and context information. + /// This information becomes a part of the cache key and, together with the object content, + /// must uniquely determine the result of optimization. + struct Settings + { + Language language; + langutil::EVMVersion evmVersion; + bool optimizeStackAllocation; + std::string yulOptimiserSteps; + std::string yulOptimiserCleanupSteps; + size_t expectedExecutionsPerDeployment; + }; + + /// Recursively optimizes a Yul object with given settings, reusing cached ASTs where possible + /// or caching the result otherwise. The object is modified in-place. + /// Automatically accounts for the difference between creation and deployed objects. + /// @warning Does not ensure that nativeLocations in the resulting AST match the optimized code. + void optimize(Object& _object, Settings const& _settings); + +private: + struct CachedObject + { + std::shared_ptr optimizedAST; + Dialect const* dialect; + }; + + void optimize(Object& _object, Settings const& _settings, bool _isCreation); + + void storeOptimizedObject(util::h256 _cacheKey, Object const& _optimizedObject, Dialect const& _dialect); + void overwriteWithOptimizedObject(util::h256 _cacheKey, Object& _object) const; + + static std::optional calculateCacheKey( + Block const& _ast, + ObjectDebugData const& _debugData, + Settings const& _settings, + bool _isCreation + ); + + std::map m_cachedObjects; +}; + +} diff --git a/libyul/YulStack.cpp b/libyul/YulStack.cpp index 8166ed3cfda6..eac84ae3a13e 100644 --- a/libyul/YulStack.cpp +++ b/libyul/YulStack.cpp @@ -24,14 +24,12 @@ #include #include #include -#include #include #include #include #include #include #include -#include #include @@ -43,22 +41,6 @@ using namespace solidity::yul; using namespace solidity::langutil; using namespace solidity::util; -namespace -{ -Dialect const& languageToDialect(YulStack::Language _language, EVMVersion _version) -{ - switch (_language) - { - case YulStack::Language::Assembly: - case YulStack::Language::StrictAssembly: - return EVMDialect::strictAssemblyForEVMObjects(_version); - } - yulAssert(false); - util::unreachable(); -} - -} - CharStream const& YulStack::charStream(std::string const& _sourceName) const { yulAssert(m_charStream, ""); @@ -114,8 +96,44 @@ void YulStack::optimize() ) return; + auto [optimizeStackAllocation, yulOptimiserSteps, yulOptimiserCleanupSteps] = [&]() -> std::tuple + { + if (!m_optimiserSettings.runYulOptimiser) + { + // Yul optimizer disabled, but empty sequence (:) explicitly provided + if (OptimiserSuite::isEmptyOptimizerSequence(m_optimiserSettings.yulOptimiserSteps + ":" + m_optimiserSettings.yulOptimiserCleanupSteps)) + return std::make_tuple(true, "", ""); + // Yul optimizer disabled, and no sequence explicitly provided (assumes default sequence) + else + { + yulAssert( + m_optimiserSettings.yulOptimiserSteps == OptimiserSettings::DefaultYulOptimiserSteps && + m_optimiserSettings.yulOptimiserCleanupSteps == OptimiserSettings::DefaultYulOptimiserCleanupSteps + ); + // Defaults are the minimum necessary to avoid running into "Stack too deep" constantly. + return std::make_tuple(true, "u", ""); + } + } + return std::make_tuple( + m_optimiserSettings.optimizeStackAllocation, + m_optimiserSettings.yulOptimiserSteps, + m_optimiserSettings.yulOptimiserCleanupSteps + ); + }(); + m_stackState = Parsed; - optimize(*m_parserResult, true); + solAssert(m_objectOptimizer); + m_objectOptimizer->optimize( + *m_parserResult, + ObjectOptimizer::Settings{ + m_language, + m_evmVersion, + optimizeStackAllocation, + yulOptimiserSteps, + yulOptimiserCleanupSteps, + m_optimiserSettings.expectedExecutionsPerDeployment + } + ); // Optimizer does not maintain correct native source locations in the AST. // We can work around it by regenerating the AST from scratch from optimized IR. @@ -186,60 +204,6 @@ void YulStack::compileEVM(AbstractAssembly& _assembly, bool _optimize) const EVMObjectCompiler::compile(*m_parserResult, _assembly, *dialect, _optimize, m_eofVersion); } -void YulStack::optimize(Object& _object, bool _isCreation) -{ - yulAssert(_object.hasCode(), ""); - yulAssert(_object.analysisInfo, ""); - for (auto& subNode: _object.subObjects) - if (auto subObject = dynamic_cast(subNode.get())) - { - bool isCreation = !boost::ends_with(subObject->name, "_deployed"); - optimize(*subObject, isCreation); - } - - Dialect const& dialect = languageToDialect(m_language, m_evmVersion); - std::unique_ptr meter; - if (EVMDialect const* evmDialect = dynamic_cast(&dialect)) - meter = std::make_unique(*evmDialect, _isCreation, m_optimiserSettings.expectedExecutionsPerDeployment); - - auto [optimizeStackAllocation, yulOptimiserSteps, yulOptimiserCleanupSteps] = [&]() -> std::tuple - { - if (!m_optimiserSettings.runYulOptimiser) - { - // Yul optimizer disabled, but empty sequence (:) explicitly provided - if (OptimiserSuite::isEmptyOptimizerSequence(m_optimiserSettings.yulOptimiserSteps + ":" + m_optimiserSettings.yulOptimiserCleanupSteps)) - return std::make_tuple(true, "", ""); - // Yul optimizer disabled, and no sequence explicitly provided (assumes default sequence) - else - { - yulAssert( - m_optimiserSettings.yulOptimiserSteps == OptimiserSettings::DefaultYulOptimiserSteps && - m_optimiserSettings.yulOptimiserCleanupSteps == OptimiserSettings::DefaultYulOptimiserCleanupSteps - ); - return std::make_tuple(true, "u", ""); - } - - } - return std::make_tuple( - m_optimiserSettings.optimizeStackAllocation, - m_optimiserSettings.yulOptimiserSteps, - m_optimiserSettings.yulOptimiserCleanupSteps - ); - }(); - - OptimiserSuite::run( - dialect, - meter.get(), - _object, - // Defaults are the minimum necessary to avoid running into "Stack too deep" constantly. - optimizeStackAllocation, - yulOptimiserSteps, - yulOptimiserCleanupSteps, - _isCreation ? std::nullopt : std::make_optional(m_optimiserSettings.expectedExecutionsPerDeployment), - {} - ); -} - void YulStack::reparse() { yulAssert(m_parserResult); @@ -250,7 +214,7 @@ void YulStack::reparse() // are not stored in the AST and the other info that is (location, AST ID, etc) will still be present. std::string source = print(nullptr /* _soliditySourceProvider */); - YulStack cleanStack(m_evmVersion, m_eofVersion, m_language, m_optimiserSettings, m_debugInfoSelection); + YulStack cleanStack(m_evmVersion, m_eofVersion, m_language, m_optimiserSettings, m_debugInfoSelection, m_objectOptimizer); bool reanalysisSuccessful = cleanStack.parseAndAnalyze(m_charStream->name(), source); yulAssert( reanalysisSuccessful, diff --git a/libyul/YulStack.h b/libyul/YulStack.h index b09fa7975859..69c0f01656f9 100644 --- a/libyul/YulStack.h +++ b/libyul/YulStack.h @@ -28,6 +28,7 @@ #include #include +#include #include #include @@ -65,7 +66,7 @@ struct MachineAssemblyObject class YulStack: public langutil::CharStreamProvider { public: - enum class Language { Assembly, StrictAssembly }; + using Language = yul::Language; enum class Machine { EVM }; enum State { Empty, @@ -88,14 +89,16 @@ class YulStack: public langutil::CharStreamProvider std::optional _eofVersion, Language _language, solidity::frontend::OptimiserSettings _optimiserSettings, - langutil::DebugInfoSelection const& _debugInfoSelection + langutil::DebugInfoSelection const& _debugInfoSelection, + std::shared_ptr _objectOptimizer = nullptr ): m_language(_language), m_evmVersion(_evmVersion), m_eofVersion(_eofVersion), m_optimiserSettings(std::move(_optimiserSettings)), m_debugInfoSelection(_debugInfoSelection), - m_errorReporter(m_errors) + m_errorReporter(m_errors), + m_objectOptimizer(_objectOptimizer ? std::move(_objectOptimizer) : std::make_shared()) {} /// @returns the char stream used during parsing @@ -150,8 +153,6 @@ class YulStack: public langutil::CharStreamProvider void compileEVM(yul::AbstractAssembly& _assembly, bool _optimize) const; - void optimize(yul::Object& _object, bool _isCreation); - /// Prints the Yul object stored internally and parses it again. /// This ensures that the debug info in the AST matches the source that printing would produce /// rather than the initial source. @@ -173,6 +174,8 @@ class YulStack: public langutil::CharStreamProvider std::shared_ptr m_parserResult; langutil::ErrorList m_errors; langutil::ErrorReporter m_errorReporter; + + std::shared_ptr m_objectOptimizer; }; } From 5c7fc0409d3f7d579571eedc8af18945cd08312b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Tue, 30 Jul 2024 15:07:04 +0200 Subject: [PATCH 0366/1022] OptimizedIRCachingTest --- libsolidity/interface/CompilerStack.h | 2 + libyul/ObjectOptimizer.h | 2 + test/CMakeLists.txt | 2 + test/InteractiveTests.h | 2 + test/libsolidity/OptimizedIRCachingTest.cpp | 50 +++++++++++++++++ test/libsolidity/OptimizedIRCachingTest.h | 54 +++++++++++++++++++ .../bytecode_dependency_creation.sol | 7 +++ ...tecode_dependency_creation_and_runtime.sol | 12 +++++ ...dependency_creation_and_runtime_shared.sol | 11 ++++ .../bytecode_dependency_runtime.sol | 9 ++++ ...ependency_shared_by_multiple_contracts.sol | 19 +++++++ .../optimizedIRCaching/multiple_contracts.sol | 5 ++ .../optimizedIRCaching/no_contracts.sol | 2 + .../optimizedIRCaching/single_contract.sol | 3 ++ test/tools/CMakeLists.txt | 2 + 15 files changed, 182 insertions(+) create mode 100644 test/libsolidity/OptimizedIRCachingTest.cpp create mode 100644 test/libsolidity/OptimizedIRCachingTest.h create mode 100644 test/libsolidity/optimizedIRCaching/bytecode_dependency_creation.sol create mode 100644 test/libsolidity/optimizedIRCaching/bytecode_dependency_creation_and_runtime.sol create mode 100644 test/libsolidity/optimizedIRCaching/bytecode_dependency_creation_and_runtime_shared.sol create mode 100644 test/libsolidity/optimizedIRCaching/bytecode_dependency_runtime.sol create mode 100644 test/libsolidity/optimizedIRCaching/bytecode_dependency_shared_by_multiple_contracts.sol create mode 100644 test/libsolidity/optimizedIRCaching/multiple_contracts.sol create mode 100644 test/libsolidity/optimizedIRCaching/no_contracts.sol create mode 100644 test/libsolidity/optimizedIRCaching/single_contract.sol diff --git a/libsolidity/interface/CompilerStack.h b/libsolidity/interface/CompilerStack.h index 6ca792296f27..25863b6d0690 100644 --- a/libsolidity/interface/CompilerStack.h +++ b/libsolidity/interface/CompilerStack.h @@ -381,6 +381,8 @@ class CompilerStack: public langutil::CharStreamProvider, public evmasm::Abstrac return VersionIsRelease ? MetadataFormat::WithReleaseVersionTag : MetadataFormat::WithPrereleaseVersionTag; } + yul::ObjectOptimizer const& objectOptimizer() const { return *m_objectOptimizer; } + private: /// The state per source unit. Filled gradually during parsing. struct Source diff --git a/libyul/ObjectOptimizer.h b/libyul/ObjectOptimizer.h index 89e5739be7da..e570d69c4b8a 100644 --- a/libyul/ObjectOptimizer.h +++ b/libyul/ObjectOptimizer.h @@ -70,6 +70,8 @@ class ObjectOptimizer /// @warning Does not ensure that nativeLocations in the resulting AST match the optimized code. void optimize(Object& _object, Settings const& _settings); + size_t size() const { return m_cachedObjects.size(); } + private: struct CachedObject { diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 0d19d77960d2..5308a55f7826 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -88,6 +88,8 @@ set(libsolidity_sources libsolidity/MemoryGuardTest.h libsolidity/NatspecJSONTest.cpp libsolidity/NatspecJSONTest.h + libsolidity/OptimizedIRCachingTest.cpp + libsolidity/OptimizedIRCachingTest.h libsolidity/SemanticTest.cpp libsolidity/SemanticTest.h libsolidity/SemVerMatcher.cpp diff --git a/test/InteractiveTests.h b/test/InteractiveTests.h index 42e20d7e3919..4c2077576cfa 100644 --- a/test/InteractiveTests.h +++ b/test/InteractiveTests.h @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -82,6 +83,7 @@ Testsuite const g_interactiveTestsuites[] = { {"Memory Guard", "libsolidity", "memoryGuardTests", false, false, &MemoryGuardTest::create}, {"AST Properties", "libsolidity", "astPropertyTests", false, false, &ASTPropertyTest::create}, {"Function Dependency Graph", "libsolidity", "functionDependencyGraphTests", false, false, &FunctionDependencyGraphTest::create}, + {"Optimized IR Caching", "libsolidity", "optimizedIRCaching", false, false, &OptimizedIRCachingTest::create}, }; } diff --git a/test/libsolidity/OptimizedIRCachingTest.cpp b/test/libsolidity/OptimizedIRCachingTest.cpp new file mode 100644 index 000000000000..d1e735eeb7b9 --- /dev/null +++ b/test/libsolidity/OptimizedIRCachingTest.cpp @@ -0,0 +1,50 @@ +/* + 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 solidity::util; +using namespace solidity::langutil; +using namespace solidity::frontend; +using namespace solidity::frontend::test; + +void OptimizedIRCachingTest::setupCompiler(CompilerStack& _compiler) +{ + AnalysisFramework::setupCompiler(_compiler); + _compiler.setOptimiserSettings(true); + _compiler.setViaIR(true); +} + +TestCase::TestResult OptimizedIRCachingTest::run(std::ostream& _stream, std::string const& _linePrefix, bool _formatted) +{ + soltestAssert(compiler().objectOptimizer().size() == 0); + + if (!runFramework(m_source, PipelineStage::Compilation)) + { + printPrefixed(_stream, formatErrors(filteredErrors(), _formatted), _linePrefix); + return TestResult::FatalError; + } + + m_obtainedResult = "cachedObjects: " + toString(compiler().objectOptimizer().size()) + "\n"; + return checkResult(_stream, _linePrefix, _formatted); +} diff --git a/test/libsolidity/OptimizedIRCachingTest.h b/test/libsolidity/OptimizedIRCachingTest.h new file mode 100644 index 000000000000..8681346ca884 --- /dev/null +++ b/test/libsolidity/OptimizedIRCachingTest.h @@ -0,0 +1,54 @@ +/* + 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 +/** + * Unit tests for the optimized IR caching in CompilerStack. + */ + +#pragma once + +#include +#include + +#include +#include + +namespace solidity::frontend::test +{ + +class OptimizedIRCachingTest: public AnalysisFramework, public EVMVersionRestrictedTestCase +{ +public: + OptimizedIRCachingTest(std::string const& _filename): + EVMVersionRestrictedTestCase(_filename) + { + m_source = m_reader.source(); + m_expectation = m_reader.simpleExpectations(); + } + + static std::unique_ptr create(Config const& _config) + { + return std::make_unique(_config.filename); + } + + TestResult run(std::ostream& _stream, std::string const& _linePrefix = "", bool _formatted = false) override; + +protected: + void setupCompiler(CompilerStack& _compiler) override; +}; + +} diff --git a/test/libsolidity/optimizedIRCaching/bytecode_dependency_creation.sol b/test/libsolidity/optimizedIRCaching/bytecode_dependency_creation.sol new file mode 100644 index 000000000000..6e603ee731a7 --- /dev/null +++ b/test/libsolidity/optimizedIRCaching/bytecode_dependency_creation.sol @@ -0,0 +1,7 @@ +contract A {} + +contract C { + A a = new A(); +} +// ---- +// cachedObjects: 4 diff --git a/test/libsolidity/optimizedIRCaching/bytecode_dependency_creation_and_runtime.sol b/test/libsolidity/optimizedIRCaching/bytecode_dependency_creation_and_runtime.sol new file mode 100644 index 000000000000..40ab2993c536 --- /dev/null +++ b/test/libsolidity/optimizedIRCaching/bytecode_dependency_creation_and_runtime.sol @@ -0,0 +1,12 @@ +contract A {} +contract B {} + +contract C { + A a = new A(); + + function f() public returns (B) { + return new B(); + } +} +// ---- +// cachedObjects: 6 diff --git a/test/libsolidity/optimizedIRCaching/bytecode_dependency_creation_and_runtime_shared.sol b/test/libsolidity/optimizedIRCaching/bytecode_dependency_creation_and_runtime_shared.sol new file mode 100644 index 000000000000..86df1b37e0b0 --- /dev/null +++ b/test/libsolidity/optimizedIRCaching/bytecode_dependency_creation_and_runtime_shared.sol @@ -0,0 +1,11 @@ +contract A {} + +contract C { + A a = new A(); + + function f() public returns (A) { + return new A(); + } +} +// ---- +// cachedObjects: 4 diff --git a/test/libsolidity/optimizedIRCaching/bytecode_dependency_runtime.sol b/test/libsolidity/optimizedIRCaching/bytecode_dependency_runtime.sol new file mode 100644 index 000000000000..6cc4d6bdecab --- /dev/null +++ b/test/libsolidity/optimizedIRCaching/bytecode_dependency_runtime.sol @@ -0,0 +1,9 @@ +contract A {} + +contract C { + function f() public returns (A) { + return new A(); + } +} +// ---- +// cachedObjects: 4 diff --git a/test/libsolidity/optimizedIRCaching/bytecode_dependency_shared_by_multiple_contracts.sol b/test/libsolidity/optimizedIRCaching/bytecode_dependency_shared_by_multiple_contracts.sol new file mode 100644 index 000000000000..cd0f97f9546d --- /dev/null +++ b/test/libsolidity/optimizedIRCaching/bytecode_dependency_shared_by_multiple_contracts.sol @@ -0,0 +1,19 @@ +contract A {} + +contract C { + A a = new A(); + + function f() public returns (A) { + return new A(); + } +} + +contract D { + A a = new A(); + + function f() public returns (A) { + return new A(); + } +} +// ---- +// cachedObjects: 6 diff --git a/test/libsolidity/optimizedIRCaching/multiple_contracts.sol b/test/libsolidity/optimizedIRCaching/multiple_contracts.sol new file mode 100644 index 000000000000..b80c99b6528b --- /dev/null +++ b/test/libsolidity/optimizedIRCaching/multiple_contracts.sol @@ -0,0 +1,5 @@ +contract C {} +contract D {} +contract E {} +// ---- +// cachedObjects: 6 diff --git a/test/libsolidity/optimizedIRCaching/no_contracts.sol b/test/libsolidity/optimizedIRCaching/no_contracts.sol new file mode 100644 index 000000000000..c080768cdfd0 --- /dev/null +++ b/test/libsolidity/optimizedIRCaching/no_contracts.sol @@ -0,0 +1,2 @@ +// ---- +// cachedObjects: 0 diff --git a/test/libsolidity/optimizedIRCaching/single_contract.sol b/test/libsolidity/optimizedIRCaching/single_contract.sol new file mode 100644 index 000000000000..6f3ab6df8853 --- /dev/null +++ b/test/libsolidity/optimizedIRCaching/single_contract.sol @@ -0,0 +1,3 @@ +contract C {} +// ---- +// cachedObjects: 2 diff --git a/test/tools/CMakeLists.txt b/test/tools/CMakeLists.txt index 532a08d9fc55..44a5e2aa701e 100644 --- a/test/tools/CMakeLists.txt +++ b/test/tools/CMakeLists.txt @@ -26,6 +26,8 @@ add_executable(isoltest ../libsolidity/GasTest.cpp ../libsolidity/MemoryGuardTest.cpp ../libsolidity/NatspecJSONTest.cpp + ../libsolidity/OptimizedIRCachingTest.cpp + ../libsolidity/OptimizedIRCachingTest.h ../libsolidity/SyntaxTest.cpp ../libsolidity/SemanticTest.cpp ../libsolidity/AnalysisFramework.cpp From f6aee354b3aa379539cd07577d1a61787ad47cd2 Mon Sep 17 00:00:00 2001 From: Alexander Arlt Date: Mon, 19 Aug 2024 17:12:54 +0200 Subject: [PATCH 0367/1022] Fix some submodule related problems. --- .dockerignore | 2 -- scripts/create_source_tarball.sh | 2 ++ scripts/docker_deploy_manual.sh | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.dockerignore b/.dockerignore index ab452ecf2823..8d9330854d0c 100644 --- a/.dockerignore +++ b/.dockerignore @@ -2,5 +2,3 @@ # the build context to the docker image build server /build -# in-tree builds -/deps diff --git a/scripts/create_source_tarball.sh b/scripts/create_source_tarball.sh index 37bee6df18b7..f5e2892aca0f 100755 --- a/scripts/create_source_tarball.sh +++ b/scripts/create_source_tarball.sh @@ -21,6 +21,8 @@ REPO_ROOT="$(dirname "$0")"/.. TEMPDIR=$(mktemp -d) SOLDIR="$TEMPDIR/solidity_$versionstring/" mkdir "$SOLDIR" + # Ensure that submodules are initialized. + git submodule update --init --recursive # Store the current source git checkout-index -a --prefix="$SOLDIR" # shellcheck disable=SC2016 diff --git a/scripts/docker_deploy_manual.sh b/scripts/docker_deploy_manual.sh index 12d3e5ff4562..48d021ff0bf9 100755 --- a/scripts/docker_deploy_manual.sh +++ b/scripts/docker_deploy_manual.sh @@ -16,7 +16,7 @@ DIR=$(mktemp -d) ( cd "$DIR" -git clone --depth 2 https://github.com/ethereum/solidity.git -b "$branch" +git clone --recursive --depth 2 https://github.com/ethereum/solidity.git -b "$branch" cd solidity commithash=$(git rev-parse --short=8 HEAD) echo -n "$commithash" > commit_hash.txt From b6ab05419db0742296c0a35b47561cea8652d7a5 Mon Sep 17 00:00:00 2001 From: Alexander Arlt Date: Mon, 29 Jul 2024 13:43:09 +0200 Subject: [PATCH 0368/1022] Update fmtlib to v11.0.2. --- deps/fmtlib | 2 +- libyul/AsmAnalysis.cpp | 4 ++-- libyul/YulString.h | 19 ------------------- 3 files changed, 3 insertions(+), 22 deletions(-) diff --git a/deps/fmtlib b/deps/fmtlib index a33701196adf..0c9fce2ffefe 160000 --- a/deps/fmtlib +++ b/deps/fmtlib @@ -1 +1 @@ -Subproject commit a33701196adfad74917046096bf5a2aa0ab0bb50 +Subproject commit 0c9fce2ffefecfdce794e1859584e25877b7b592 diff --git a/libyul/AsmAnalysis.cpp b/libyul/AsmAnalysis.cpp index 09be5974246b..22ec8c9944f8 100644 --- a/libyul/AsmAnalysis.cpp +++ b/libyul/AsmAnalysis.cpp @@ -694,7 +694,7 @@ void AsmAnalyzer::expectValidType(YulName _type, SourceLocation const& _location m_errorReporter.typeError( 5473_error, _location, - fmt::format("\"{}\" is not a valid type (user defined types are not yet supported).", _type) + fmt::format("\"{}\" is not a valid type (user defined types are not yet supported).", _type.str()) ); } @@ -704,7 +704,7 @@ void AsmAnalyzer::expectType(YulName _expectedType, YulName _givenType, SourceLo m_errorReporter.typeError( 3781_error, _location, - fmt::format("Expected a value of type \"{}\" but got \"{}\".", _expectedType, _givenType) + fmt::format("Expected a value of type \"{}\" but got \"{}\".", _expectedType.str(), _givenType.str()) ); } diff --git a/libyul/YulString.h b/libyul/YulString.h index 89d35b123cab..bd9438e5abc9 100644 --- a/libyul/YulString.h +++ b/libyul/YulString.h @@ -169,25 +169,6 @@ inline YulString operator "" _yulname(char const* _string, std::size_t _size) } -namespace fmt -{ -template <> -struct formatter -{ - template - constexpr auto parse(ParseContext& _context) - { - return _context.begin(); - } - - template - auto format(solidity::yul::YulString _value, FormatContext& _context) - { - return format_to(_context.out(), "{}", _value.str()); - } -}; -} - namespace std { template<> struct hash From 20fa893f7e6decb502a36fd9e9eee7e4e59b44e0 Mon Sep 17 00:00:00 2001 From: Matheus Aguiar Date: Thu, 22 Aug 2024 23:32:51 -0300 Subject: [PATCH 0369/1022] More precise calculations when evaluating how many bytes immutables require --- Changelog.md | 1 + libevmasm/Assembly.cpp | 2 +- .../immutable/immutable_tag_too_large_bug.sol | 48 +++++++++++++++++++ 3 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 test/libsolidity/semanticTests/immutable/immutable_tag_too_large_bug.sol diff --git a/Changelog.md b/Changelog.md index 034be57733bc..288136dd9181 100644 --- a/Changelog.md +++ b/Changelog.md @@ -25,6 +25,7 @@ Compiler Features: Bugfixes: + * Assembler: Fix ICE caused by imprecise calculation of required size of tags in bytecode when code size is above 255. * Parser: Fix spuriously emitted parser error for unary plus operations when used as binary operator in some cases. * SMTChecker: Fix error that reports invalid number of verified checks for BMC and CHC engines. * SMTChecker: Fix formatting of unary minus expressions in invariants. diff --git a/libevmasm/Assembly.cpp b/libevmasm/Assembly.cpp index 91773a8e8403..ab3879da48c8 100644 --- a/libevmasm/Assembly.cpp +++ b/libevmasm/Assembly.cpp @@ -74,7 +74,7 @@ unsigned Assembly::codeSize(unsigned subTagSize) const ret += i.second.size(); for (AssemblyItem const& i: m_items) - ret += i.bytesRequired(tagSize, m_evmVersion, Precision::Approximate); + ret += i.bytesRequired(tagSize, m_evmVersion, Precision::Precise); if (numberEncodingSize(ret) <= tagSize) return static_cast(ret); } diff --git a/test/libsolidity/semanticTests/immutable/immutable_tag_too_large_bug.sol b/test/libsolidity/semanticTests/immutable/immutable_tag_too_large_bug.sol new file mode 100644 index 000000000000..fed424628c0e --- /dev/null +++ b/test/libsolidity/semanticTests/immutable/immutable_tag_too_large_bug.sol @@ -0,0 +1,48 @@ +contract C { + int immutable x = 1; + int immutable y = 3; + + function f() public payable returns(int, int) { + uint a = uint(y / 1e8); + int256 b = x * y; + int24 c = int24(b * b >> 128); + int24 d = int24((100 * y + 1) >> 128); + int24 e = int24(x >> 128); + int256 f = x * 2; + if (c < 0) { + int256 g = (x * x * y) / x; + require((y >= 0 && g <= x) || (y < 0 && (x - y) > x)); + if (b >= f) { + require(x <= int256(uint256(type(uint168).max)) && x >= 0, ""); + b = (b * b) / f; + for (a = 0; a < a; a++) { + uint8 b; + assembly { + b := and(mload(a), 0xFF) + } + } + b += f; + } + require(d % e != 0); + c = -c; + } + return (x, ((x * (x - y)) / (x + y))); + } + + constructor () { + x--; + --x; + y++; + ++y; + --y; + } +} +// ==== +// compileViaYul: true +// ---- +// constructor() -> +// gas irOptimized: 73171 +// gas irOptimized code: 291200 +// gas legacy: 83499 +// gas legacy code: 408800 +// f() -> -1, 1 From 0e80fbf73b5067affaf22b76588320e649c14f96 Mon Sep 17 00:00:00 2001 From: rodiazet Date: Mon, 22 Jul 2024 11:10:20 +0200 Subject: [PATCH 0370/1022] prep: Extend `StandardCompiler` settings with `eofVersion` flag. Fix typo in input parsing Co-authored-by: Daniel Kirchner --- libsolidity/interface/StandardCompiler.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/libsolidity/interface/StandardCompiler.cpp b/libsolidity/interface/StandardCompiler.cpp index b209987ddd3f..0c1ccb6b7653 100644 --- a/libsolidity/interface/StandardCompiler.cpp +++ b/libsolidity/interface/StandardCompiler.cpp @@ -426,7 +426,7 @@ std::optional checkAuxiliaryInputKeys(Json const& _input) std::optional checkSettingsKeys(Json const& _input) { - static std::set keys{"debug", "evmVersion", "libraries", "metadata", "modelChecker", "optimizer", "outputSelection", "remappings", "stopAfter", "viaIR"}; + static std::set keys{"debug", "evmVersion", "eofVersion", "libraries", "metadata", "modelChecker", "optimizer", "outputSelection", "remappings", "stopAfter", "viaIR"}; return checkKeys(_input, keys, "settings"); } @@ -837,7 +837,7 @@ std::variant StandardCompiler::parseI { if (!settings["eofVersion"].is_number_unsigned()) return formatFatalError(Error::Type::JSONError, "eofVersion must be an unsigned integer."); - auto eofVersion = settings["evmVersion"].get(); + auto eofVersion = settings["eofVersion"].get(); if (eofVersion != 1) return formatFatalError(Error::Type::JSONError, "Invalid EOF version requested."); ret.eofVersion = 1; @@ -1308,6 +1308,7 @@ Json StandardCompiler::compileSolidity(StandardCompiler::InputsAndSettings _inpu compilerStack.addSMTLib2Response(smtLib2Response.first, smtLib2Response.second); compilerStack.setViaIR(_inputsAndSettings.viaIR); compilerStack.setEVMVersion(_inputsAndSettings.evmVersion); + compilerStack.setEOFVersion(_inputsAndSettings.eofVersion); compilerStack.setRemappings(std::move(_inputsAndSettings.remappings)); compilerStack.setOptimiserSettings(std::move(_inputsAndSettings.optimiserSettings)); compilerStack.setRevertStringBehaviour(_inputsAndSettings.revertStrings); From 541452036dc5e17c1e1c973bd45ca3596f1106bc Mon Sep 17 00:00:00 2001 From: rodiazet Date: Mon, 22 Jul 2024 15:16:34 +0200 Subject: [PATCH 0371/1022] prep: Change `toBigEndian` interface to support rvalue ref. Co-authored-by: Daniel Kirchner --- libsolutil/Numeric.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libsolutil/Numeric.h b/libsolutil/Numeric.h index be9f0bea243a..f4e88de3c17d 100644 --- a/libsolutil/Numeric.h +++ b/libsolutil/Numeric.h @@ -96,13 +96,13 @@ bool fitsPrecisionBaseX(bigint const& _mantissa, double _log2OfBase, uint32_t _e /// @a Out will typically be either std::string or bytes. /// @a T will typically by unsigned, u160, u256 or bigint. template -inline void toBigEndian(T _val, Out& o_out) +inline void toBigEndian(T _val, Out&& o_out) { static_assert(std::is_same::value || !std::numeric_limits::is_signed, "only unsigned types or bigint supported"); //bigint does not carry sign bit on shift - for (auto i = o_out.size(); i != 0; _val >>= 8, i--) + for (auto i = o_out.size(); i != 0u; _val >>= 8u, i--) { - T v = _val & (T)0xff; - o_out[i - 1] = (typename Out::value_type)(uint8_t)v; + T v = _val & (T)0xffu; + o_out[i - 1u] = (typename std::remove_reference_t::value_type)(uint8_t)v; } } From 9e752f5c1b0ceff75483518f8750eac4dec50392 Mon Sep 17 00:00:00 2001 From: Ikko Eltociear Ashimine Date: Tue, 27 Aug 2024 00:08:37 +0900 Subject: [PATCH 0372/1022] chore: update array_storage_index_zeroed_test.sol test_zeroed_indicies -> test_zeroed_indices --- .../array/array_storage_index_zeroed_test.sol | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/test/libsolidity/semanticTests/array/array_storage_index_zeroed_test.sol b/test/libsolidity/semanticTests/array/array_storage_index_zeroed_test.sol index 23feb0da11eb..cdd6b70f559d 100644 --- a/test/libsolidity/semanticTests/array/array_storage_index_zeroed_test.sol +++ b/test/libsolidity/semanticTests/array/array_storage_index_zeroed_test.sol @@ -1,6 +1,6 @@ contract C { uint[] storageArray; - function test_zeroed_indicies(uint256 len) public + function test_zeroed_indices(uint256 len) public { while(storageArray.length < len) storageArray.push(); @@ -50,20 +50,20 @@ contract C { } } // ---- -// test_zeroed_indicies(uint256): 1 -> -// test_zeroed_indicies(uint256): 5 -> +// test_zeroed_indices(uint256): 1 -> +// test_zeroed_indices(uint256): 5 -> // gas irOptimized: 133763 // gas legacy: 131664 // gas legacyOptimized: 129990 -// test_zeroed_indicies(uint256): 10 -> +// test_zeroed_indices(uint256): 10 -> // gas irOptimized: 228556 // gas legacy: 225215 // gas legacyOptimized: 222351 -// test_zeroed_indicies(uint256): 15 -> +// test_zeroed_indices(uint256): 15 -> // gas irOptimized: 327360 // gas legacy: 322899 // gas legacyOptimized: 318907 -// test_zeroed_indicies(uint256): 0xFF -> +// test_zeroed_indices(uint256): 0xFF -> // gas irOptimized: 5180120 // gas legacy: 5093135 // gas legacyOptimized: 5020523 From b8373e91297a54e56b4cea31f704a62b97316add Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Wed, 28 Aug 2024 11:16:42 +0200 Subject: [PATCH 0373/1022] CI: explicitly add numpy to LSP test dependencies on windows --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 343bb6d00693..b5d0b76d6ec9 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1656,7 +1656,7 @@ jobs: shell: powershell.exe - run: name: Install LSP test dependencies - command: python -m pip install --user deepdiff colorama + command: python -m pip install --user numpy deepdiff colorama - run: name: Executing solc LSP test suite command: python test/lsp.py build\solc\Release\solc.exe --non-interactive From 47a715ffa548ac0bcd7532defc76f21c3c68a5ed Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Wed, 14 Aug 2024 09:51:15 +0200 Subject: [PATCH 0374/1022] Yul: Remove boolType and defaultType from dialect --- libyul/AsmAnalysis.cpp | 27 +++++++++---------- libyul/AsmParser.cpp | 4 +-- libyul/AsmPrinter.cpp | 13 ++------- libyul/AsmPrinter.h | 2 +- libyul/Dialect.cpp | 23 ++-------------- libyul/Dialect.h | 27 ++++++------------- .../backends/evm/ControlFlowGraphBuilder.cpp | 2 +- libyul/backends/evm/EVMDialect.h | 14 +++++----- libyul/optimiser/ConditionalSimplifier.cpp | 2 +- libyul/optimiser/ControlFlowSimplifier.cpp | 15 +++++------ libyul/optimiser/DataFlowAnalyzer.cpp | 10 +++---- libyul/optimiser/ForLoopConditionIntoBody.cpp | 2 +- libyul/optimiser/FullInliner.cpp | 2 +- libyul/optimiser/LoadResolver.cpp | 4 +-- libyul/optimiser/StackToMemoryMover.cpp | 4 +-- libyul/optimiser/UnusedPruner.cpp | 4 +-- libyul/optimiser/VarDeclInitializer.cpp | 4 +-- 17 files changed, 59 insertions(+), 100 deletions(-) diff --git a/libyul/AsmAnalysis.cpp b/libyul/AsmAnalysis.cpp index 22ec8c9944f8..908e30e62931 100644 --- a/libyul/AsmAnalysis.cpp +++ b/libyul/AsmAnalysis.cpp @@ -128,14 +128,12 @@ std::vector AsmAnalyzer::operator()(Literal const& _literal) m_errorReporter.typeError(6708_error, nativeLocationOf(_literal), "Number literal too large (> 256 bits)"); } - if (!m_dialect.validTypeForLiteral(_literal.kind, _literal.value, _literal.type)) - { + if (_literal.kind == LiteralKind::Boolean && !_literal.type.empty()) m_errorReporter.typeError( 5170_error, nativeLocationOf(_literal), "Invalid type \"" + _literal.type.str() + "\" for literal \"" + formatLiteral(_literal) + "\"." ); - } yulAssert(erroneousLiteralValue ^ validLiteral(_literal), "Invalid literal after validating it through AsmAnalyzer."); return {_literal.type}; @@ -145,7 +143,7 @@ std::vector AsmAnalyzer::operator()(Identifier const& _identifier) { yulAssert(!_identifier.name.empty(), ""); auto watcher = m_errorReporter.errorWatcher(); - YulName type = m_dialect.defaultType; + YulName type{}; if (m_currentScope->lookup(_identifier.name, GenericVisitor{ [&](Scope::Variable const& _var) @@ -284,7 +282,7 @@ void AsmAnalyzer::operator()(VariableDeclaration const& _varDecl) for (size_t i = 0; i < _varDecl.variables.size(); ++i) { - YulName givenType = m_dialect.defaultType; + YulName givenType{}; if (i < types.size()) givenType = types[i]; TypedName const& variable = _varDecl.variables[i]; @@ -474,7 +472,7 @@ std::vector AsmAnalyzer::operator()(FunctionCall const& _funCall) return *returnTypes; } else if (returnTypes) - return std::vector(returnTypes->size(), m_dialect.defaultType); + return std::vector(returnTypes->size(), YulName{}); else return {}; } @@ -573,13 +571,13 @@ YulName AsmAnalyzer::expectExpression(Expression const& _expr) std::to_string(types.size()) + " values instead." ); - return types.empty() ? m_dialect.defaultType : types.front(); + return types.empty() ? YulName{} : types.front(); } YulName AsmAnalyzer::expectUnlimitedStringLiteral(Literal const& _literal) { yulAssert(_literal.kind == LiteralKind::String); - yulAssert(m_dialect.validTypeForLiteral(LiteralKind::String, _literal.value, _literal.type)); + yulAssert(_literal.type.empty()); yulAssert(_literal.value.unlimited()); return {_literal.type}; @@ -588,12 +586,13 @@ YulName AsmAnalyzer::expectUnlimitedStringLiteral(Literal const& _literal) void AsmAnalyzer::expectBoolExpression(Expression const& _expr) { YulName type = expectExpression(_expr); - if (type != m_dialect.boolType) + static YulName boolType = {}; + if (type != boolType) m_errorReporter.typeError( 1733_error, nativeLocationOf(_expr), "Expected a value of boolean type \"" + - m_dialect.boolType.str() + + boolType.str() + "\" but got \"" + type.str() + "\"" @@ -604,7 +603,7 @@ void AsmAnalyzer::checkAssignment(Identifier const& _variable, YulName _valueTyp { yulAssert(!_variable.name.empty(), ""); auto watcher = m_errorReporter.errorWatcher(); - YulName const* variableType = nullptr; + std::optional variableType = std::nullopt; bool found = false; if (Scope::Identifier const* var = m_currentScope->lookup(_variable.name)) { @@ -625,7 +624,7 @@ void AsmAnalyzer::checkAssignment(Identifier const& _variable, YulName _valueTyp "Variable " + _variable.name.str() + " used before it was declared." ); else - variableType = &std::get(*var).type; + variableType = std::get(*var).type; found = true; } else if (m_resolver) @@ -634,7 +633,7 @@ void AsmAnalyzer::checkAssignment(Identifier const& _variable, YulName _valueTyp if (m_resolver(_variable, yul::IdentifierContext::LValue, insideFunction)) { found = true; - variableType = &m_dialect.defaultType; + variableType = YulName{}; } } @@ -690,7 +689,7 @@ void AsmAnalyzer::expectValidIdentifier(YulName _identifier, SourceLocation cons void AsmAnalyzer::expectValidType(YulName _type, SourceLocation const& _location) { - if (!m_dialect.types.count(_type)) + if (!_type.empty()) m_errorReporter.typeError( 5473_error, _location, diff --git a/libyul/AsmParser.cpp b/libyul/AsmParser.cpp index 6223a1a8e1c3..a2a4c36dc056 100644 --- a/libyul/AsmParser.cpp +++ b/libyul/AsmParser.cpp @@ -571,7 +571,7 @@ std::variant Parser::parseLiteralOrIdentifier(bool _unlimit createDebugData(), kind, valueOfLiteral(currentLiteral(), kind, _unlimitedLiteralArgument && kind == LiteralKind::String), - kind == LiteralKind::Boolean ? m_dialect.boolType : m_dialect.defaultType + {} }; advance(); if (currentToken() == Token::Colon) @@ -707,7 +707,7 @@ TypedName Parser::parseTypedName() typedName.type = expectAsmIdentifier(); } else - typedName.type = m_dialect.defaultType; + typedName.type = {}; return typedName; } diff --git a/libyul/AsmPrinter.cpp b/libyul/AsmPrinter.cpp index 6b840fcfeae4..a5ce47d12524 100644 --- a/libyul/AsmPrinter.cpp +++ b/libyul/AsmPrinter.cpp @@ -53,9 +53,8 @@ std::string AsmPrinter::operator()(Literal const& _literal) switch (_literal.kind) { case LiteralKind::Number: - return locationComment + formattedValue + appendTypeName(_literal.type); case LiteralKind::Boolean: - return locationComment + formattedValue + appendTypeName(_literal.type, true); + return locationComment + formattedValue + appendTypeName(_literal.type); case LiteralKind::String: break; } @@ -243,20 +242,12 @@ std::string AsmPrinter::formatTypedName(TypedName _variable) return formatDebugData(_variable) + _variable.name.str() + appendTypeName(_variable.type); } -std::string AsmPrinter::appendTypeName(YulName _type, bool _isBoolLiteral) const +std::string AsmPrinter::appendTypeName(YulName _type) const { yulAssert( m_typePrintingMode == TypePrinting::OmitDefault || m_typePrintingMode == TypePrinting::Full, "unhandled printing mode" ); - if (m_typePrintingMode == TypePrinting::OmitDefault && !_type.empty()) - { - if (!_isBoolLiteral && _type == m_dialect.defaultType) - _type = {}; - else if (_isBoolLiteral && _type == m_dialect.boolType && !m_dialect.defaultType.empty()) - // Special case: If we have a bool type but empty default type, do not remove the type. - _type = {}; - } if (_type.empty()) return {}; else diff --git a/libyul/AsmPrinter.h b/libyul/AsmPrinter.h index 684ddaacf0d5..90fa3a4b5abd 100644 --- a/libyul/AsmPrinter.h +++ b/libyul/AsmPrinter.h @@ -93,7 +93,7 @@ class AsmPrinter private: std::string formatTypedName(TypedName _variable); - std::string appendTypeName(YulName _type, bool _isBoolLiteral = false) const; + std::string appendTypeName(YulName _type) const; std::string formatDebugData(langutil::DebugData::ConstPtr const& _debugData, bool _statement); template std::string formatDebugData(T const& _node) diff --git a/libyul/Dialect.cpp b/libyul/Dialect.cpp index 8afd99a2288f..be6c6705ee61 100644 --- a/libyul/Dialect.cpp +++ b/libyul/Dialect.cpp @@ -25,26 +25,7 @@ using namespace solidity::yul; using namespace solidity::langutil; -Literal Dialect::zeroLiteralForType(solidity::yul::YulName _type) const +Literal Dialect::zeroLiteral() const { - if (_type == boolType && _type != defaultType) - return {DebugData::create(), LiteralKind::Boolean, LiteralValue(false), _type}; - return {DebugData::create(), LiteralKind::Number, LiteralValue(0, std::nullopt), _type}; -} - - -Literal Dialect::trueLiteral() const -{ - if (boolType != defaultType) - return {DebugData::create(), LiteralKind::Boolean, LiteralValue(true), boolType}; - else - return {DebugData::create(), LiteralKind::Number, LiteralValue(1), defaultType}; -} - -bool Dialect::validTypeForLiteral(LiteralKind _kind, LiteralValue const&, YulName _type) const -{ - if (_kind == LiteralKind::Boolean) - return _type == boolType; - else - return true; + return {DebugData::create(), LiteralKind::Number, LiteralValue(0, std::nullopt), {}}; } diff --git a/libyul/Dialect.h b/libyul/Dialect.h index fcec5fe3f981..f9ce01469055 100644 --- a/libyul/Dialect.h +++ b/libyul/Dialect.h @@ -61,34 +61,23 @@ struct Dialect Dialect(Dialect const&) = delete; Dialect& operator=(Dialect const&) = delete; - /// Default type, can be omitted. - YulName defaultType; - /// Type used for the literals "true" and "false". - YulName boolType; - std::set types = {{}}; - /// @returns the builtin function of the given name or a nullptr if it is not a builtin function. virtual BuiltinFunction const* builtin(YulName /*_name*/) const { return nullptr; } /// @returns true if the identifier is reserved. This includes the builtins too. virtual bool reservedIdentifier(YulName _name) const { return builtin(_name) != nullptr; } - virtual BuiltinFunction const* discardFunction(YulName /* _type */) const { return nullptr; } - virtual BuiltinFunction const* equalityFunction(YulName /* _type */) const { return nullptr; } + virtual BuiltinFunction const* discardFunction() const { return nullptr; } + virtual BuiltinFunction const* equalityFunction() const { return nullptr; } virtual BuiltinFunction const* booleanNegationFunction() const { return nullptr; } - virtual BuiltinFunction const* memoryStoreFunction(YulName /* _type */) const { return nullptr; } - virtual BuiltinFunction const* memoryLoadFunction(YulName /* _type */) const { return nullptr; } - virtual BuiltinFunction const* storageStoreFunction(YulName /* _type */) const { return nullptr; } - virtual BuiltinFunction const* storageLoadFunction(YulName /* _type */) const { return nullptr; } - virtual YulName hashFunction(YulName /* _type */ ) const { return YulName{}; } - - /// Check whether the given type is legal for the given literal value. - /// Should only be called if the type exists in the dialect at all. - virtual bool validTypeForLiteral(LiteralKind _kind, LiteralValue const& _value, YulName _type) const; + virtual BuiltinFunction const* memoryStoreFunction() const { return nullptr; } + virtual BuiltinFunction const* memoryLoadFunction() const { return nullptr; } + virtual BuiltinFunction const* storageStoreFunction() const { return nullptr; } + virtual BuiltinFunction const* storageLoadFunction() const { return nullptr; } + virtual YulName hashFunction() const { return YulName{}; } - virtual Literal zeroLiteralForType(YulName _type) const; - virtual Literal trueLiteral() const; + Literal zeroLiteral() const; virtual std::set fixedFunctionNames() const { return {}; } diff --git a/libyul/backends/evm/ControlFlowGraphBuilder.cpp b/libyul/backends/evm/ControlFlowGraphBuilder.cpp index b4d1cdf15c3a..3007566dd50f 100644 --- a/libyul/backends/evm/ControlFlowGraphBuilder.cpp +++ b/libyul/backends/evm/ControlFlowGraphBuilder.cpp @@ -349,7 +349,7 @@ void ControlFlowGraphBuilder::operator()(Switch const& _switch) CFG::Assignment{_switch.debugData, {ghostVarSlot}} }); - BuiltinFunction const* equalityBuiltin = m_dialect.equalityFunction({}); + BuiltinFunction const* equalityBuiltin = m_dialect.equalityFunction(); yulAssert(equalityBuiltin, ""); // Artificially generate: diff --git a/libyul/backends/evm/EVMDialect.h b/libyul/backends/evm/EVMDialect.h index 89df944966f0..3207b8fae025 100644 --- a/libyul/backends/evm/EVMDialect.h +++ b/libyul/backends/evm/EVMDialect.h @@ -74,14 +74,14 @@ struct EVMDialect: public Dialect /// @returns true if the identifier is reserved. This includes the builtins too. bool reservedIdentifier(YulName _name) const override; - BuiltinFunctionForEVM const* discardFunction(YulName /*_type*/) const override { return builtin("pop"_yulname); } - BuiltinFunctionForEVM const* equalityFunction(YulName /*_type*/) const override { return builtin("eq"_yulname); } + BuiltinFunctionForEVM const* discardFunction() const override { return builtin("pop"_yulname); } + BuiltinFunctionForEVM const* equalityFunction() const override { return builtin("eq"_yulname); } BuiltinFunctionForEVM const* booleanNegationFunction() const override { return builtin("iszero"_yulname); } - BuiltinFunctionForEVM const* memoryStoreFunction(YulName /*_type*/) const override { return builtin("mstore"_yulname); } - BuiltinFunctionForEVM const* memoryLoadFunction(YulName /*_type*/) const override { return builtin("mload"_yulname); } - BuiltinFunctionForEVM const* storageStoreFunction(YulName /*_type*/) const override { return builtin("sstore"_yulname); } - BuiltinFunctionForEVM const* storageLoadFunction(YulName /*_type*/) const override { return builtin("sload"_yulname); } - YulName hashFunction(YulName /*_type*/) const override { return "keccak256"_yulname; } + BuiltinFunctionForEVM const* memoryStoreFunction() const override { return builtin("mstore"_yulname); } + BuiltinFunctionForEVM const* memoryLoadFunction() const override { return builtin("mload"_yulname); } + BuiltinFunctionForEVM const* storageStoreFunction() const override { return builtin("sstore"_yulname); } + BuiltinFunctionForEVM const* storageLoadFunction() const override { return builtin("sload"_yulname); } + YulName hashFunction() const override { return "keccak256"_yulname; } static EVMDialect const& strictAssemblyForEVM(langutil::EVMVersion _version); static EVMDialect const& strictAssemblyForEVMObjects(langutil::EVMVersion _version); diff --git a/libyul/optimiser/ConditionalSimplifier.cpp b/libyul/optimiser/ConditionalSimplifier.cpp index a2656fed390e..f81933f41c6f 100644 --- a/libyul/optimiser/ConditionalSimplifier.cpp +++ b/libyul/optimiser/ConditionalSimplifier.cpp @@ -84,7 +84,7 @@ void ConditionalSimplifier::operator()(Block& _block) Assignment{ debugData, {Identifier{debugData, condition}}, - std::make_unique(m_dialect.zeroLiteralForType(m_dialect.boolType)) + std::make_unique(m_dialect.zeroLiteral()) } ); } diff --git a/libyul/optimiser/ControlFlowSimplifier.cpp b/libyul/optimiser/ControlFlowSimplifier.cpp index 9d56583a0611..2d0dbb4679a2 100644 --- a/libyul/optimiser/ControlFlowSimplifier.cpp +++ b/libyul/optimiser/ControlFlowSimplifier.cpp @@ -138,12 +138,12 @@ void ControlFlowSimplifier::simplify(std::vector& _statements) GenericVisitor visitor{ VisitorFallback{}, [&](If& _ifStmt) -> OptionalStatements { - if (_ifStmt.body.statements.empty() && m_dialect.discardFunction(m_dialect.boolType)) + if (_ifStmt.body.statements.empty() && m_dialect.discardFunction()) { OptionalStatements s = std::vector{}; s->emplace_back(makeDiscardCall( _ifStmt.debugData, - *m_dialect.discardFunction(m_dialect.boolType), + *m_dialect.discardFunction(), std::move(*_ifStmt.condition) )); return s; @@ -180,7 +180,7 @@ OptionalStatements ControlFlowSimplifier::reduceNoCaseSwitch(Switch& _switchStmt { yulAssert(_switchStmt.cases.empty(), "Expected no case!"); BuiltinFunction const* discardFunction = - m_dialect.discardFunction(m_typeInfo.typeOf(*_switchStmt.expression)); + m_dialect.discardFunction(); if (!discardFunction) return {}; @@ -197,16 +197,15 @@ OptionalStatements ControlFlowSimplifier::reduceSingleCaseSwitch(Switch& _switch auto& switchCase = _switchStmt.cases.front(); langutil::DebugData::ConstPtr debugData = debugDataOf(*_switchStmt.expression); - YulName type = m_typeInfo.typeOf(*_switchStmt.expression); if (switchCase.value) { - if (!m_dialect.equalityFunction(type)) + if (!m_dialect.equalityFunction()) return {}; return make_vector(If{ std::move(_switchStmt.debugData), std::make_unique(FunctionCall{ debugData, - Identifier{debugData, m_dialect.equalityFunction(type)->name}, + Identifier{debugData, m_dialect.equalityFunction()->name}, {std::move(*switchCase.value), std::move(*_switchStmt.expression)} }), std::move(switchCase.body) @@ -214,13 +213,13 @@ OptionalStatements ControlFlowSimplifier::reduceSingleCaseSwitch(Switch& _switch } else { - if (!m_dialect.discardFunction(type)) + if (!m_dialect.discardFunction()) return {}; return make_vector( makeDiscardCall( debugData, - *m_dialect.discardFunction(type), + *m_dialect.discardFunction(), std::move(*_switchStmt.expression) ), std::move(switchCase.body) diff --git a/libyul/optimiser/DataFlowAnalyzer.cpp b/libyul/optimiser/DataFlowAnalyzer.cpp index a51ca912399d..bf8952355d1f 100644 --- a/libyul/optimiser/DataFlowAnalyzer.cpp +++ b/libyul/optimiser/DataFlowAnalyzer.cpp @@ -54,13 +54,13 @@ DataFlowAnalyzer::DataFlowAnalyzer( { if (m_analyzeStores) { - if (auto const* builtin = _dialect.memoryStoreFunction(YulName{})) + if (auto const* builtin = _dialect.memoryStoreFunction()) m_storeFunctionName[static_cast(StoreLoadLocation::Memory)] = builtin->name; - if (auto const* builtin = _dialect.memoryLoadFunction(YulName{})) + if (auto const* builtin = _dialect.memoryLoadFunction()) m_loadFunctionName[static_cast(StoreLoadLocation::Memory)] = builtin->name; - if (auto const* builtin = _dialect.storageStoreFunction(YulName{})) + if (auto const* builtin = _dialect.storageStoreFunction()) m_storeFunctionName[static_cast(StoreLoadLocation::Storage)] = builtin->name; - if (auto const* builtin = _dialect.storageLoadFunction(YulName{})) + if (auto const* builtin = _dialect.storageLoadFunction()) m_loadFunctionName[static_cast(StoreLoadLocation::Storage)] = builtin->name; } } @@ -446,7 +446,7 @@ std::optional DataFlowAnalyzer::isSimpleLoad( std::optional> DataFlowAnalyzer::isKeccak(Expression const& _expression) const { if (FunctionCall const* funCall = std::get_if(&_expression)) - if (funCall->functionName.name == m_dialect.hashFunction({})) + if (funCall->functionName.name == m_dialect.hashFunction()) if (Identifier const* start = std::get_if(&funCall->arguments.at(0))) if (Identifier const* length = std::get_if(&funCall->arguments.at(1))) return std::make_pair(start->name, length->name); diff --git a/libyul/optimiser/ForLoopConditionIntoBody.cpp b/libyul/optimiser/ForLoopConditionIntoBody.cpp index df9847376af7..cc3f936d9441 100644 --- a/libyul/optimiser/ForLoopConditionIntoBody.cpp +++ b/libyul/optimiser/ForLoopConditionIntoBody.cpp @@ -59,7 +59,7 @@ void ForLoopConditionIntoBody::operator()(ForLoop& _forLoop) debugData, LiteralKind::Boolean, LiteralValue{true}, - m_dialect.boolType + {} } ); } diff --git a/libyul/optimiser/FullInliner.cpp b/libyul/optimiser/FullInliner.cpp index 5cdde8f0fdd5..3daaea658b80 100644 --- a/libyul/optimiser/FullInliner.cpp +++ b/libyul/optimiser/FullInliner.cpp @@ -305,7 +305,7 @@ std::vector InlineModifier::performInline(Statement& _statement, Func if (_value) varDecl.value = std::make_unique(std::move(*_value)); else - varDecl.value = std::make_unique(m_dialect.zeroLiteralForType(varDecl.variables.front().type)); + varDecl.value = std::make_unique(m_dialect.zeroLiteral()); newStatements.emplace_back(std::move(varDecl)); }; diff --git a/libyul/optimiser/LoadResolver.cpp b/libyul/optimiser/LoadResolver.cpp index a7ee5dd0b92c..943860a0ad8d 100644 --- a/libyul/optimiser/LoadResolver.cpp +++ b/libyul/optimiser/LoadResolver.cpp @@ -62,7 +62,7 @@ void LoadResolver::visit(Expression& _e) tryResolve(_e, StoreLoadLocation::Memory, funCall->arguments); else if (funCall->functionName.name == m_loadFunctionName[static_cast(StoreLoadLocation::Storage)]) tryResolve(_e, StoreLoadLocation::Storage, funCall->arguments); - else if (!m_containsMSize && funCall->functionName.name == m_dialect.hashFunction({})) + else if (!m_containsMSize && funCall->functionName.name == m_dialect.hashFunction()) { Identifier const* start = std::get_if(&funCall->arguments.at(0)); Identifier const* length = std::get_if(&funCall->arguments.at(1)); @@ -151,7 +151,7 @@ void LoadResolver::tryEvaluateKeccak( debugDataOf(_e), LiteralKind::Number, LiteralValue{contentHash}, - m_dialect.defaultType + {} }; } } diff --git a/libyul/optimiser/StackToMemoryMover.cpp b/libyul/optimiser/StackToMemoryMover.cpp index 7ec57903482f..d5cb539af477 100644 --- a/libyul/optimiser/StackToMemoryMover.cpp +++ b/libyul/optimiser/StackToMemoryMover.cpp @@ -42,7 +42,7 @@ std::vector generateMemoryStore( Expression _value ) { - BuiltinFunction const* memoryStoreFunction = _dialect.memoryStoreFunction(_dialect.defaultType); + BuiltinFunction const* memoryStoreFunction = _dialect.memoryStoreFunction(); yulAssert(memoryStoreFunction, ""); std::vector result; result.emplace_back(ExpressionStatement{_debugData, FunctionCall{ @@ -58,7 +58,7 @@ std::vector generateMemoryStore( FunctionCall generateMemoryLoad(Dialect const& _dialect, langutil::DebugData::ConstPtr const& _debugData, LiteralValue const& _mpos) { - BuiltinFunction const* memoryLoadFunction = _dialect.memoryLoadFunction(_dialect.defaultType); + BuiltinFunction const* memoryLoadFunction = _dialect.memoryLoadFunction(); yulAssert(memoryLoadFunction, ""); return FunctionCall{ _debugData, diff --git a/libyul/optimiser/UnusedPruner.cpp b/libyul/optimiser/UnusedPruner.cpp index 9df51cf7f069..c71e8077b690 100644 --- a/libyul/optimiser/UnusedPruner.cpp +++ b/libyul/optimiser/UnusedPruner.cpp @@ -105,10 +105,10 @@ void UnusedPruner::operator()(Block& _block) subtractReferences(ReferencesCounter::countReferences(*varDecl.value)); statement = Block{std::move(varDecl.debugData), {}}; } - else if (varDecl.variables.size() == 1 && m_dialect.discardFunction(varDecl.variables.front().type)) + else if (varDecl.variables.size() == 1 && m_dialect.discardFunction()) statement = ExpressionStatement{varDecl.debugData, FunctionCall{ varDecl.debugData, - {varDecl.debugData, m_dialect.discardFunction(varDecl.variables.front().type)->name}, + {varDecl.debugData, m_dialect.discardFunction()->name}, {*std::move(varDecl.value)} }}; } diff --git a/libyul/optimiser/VarDeclInitializer.cpp b/libyul/optimiser/VarDeclInitializer.cpp index 845c7cc41c96..db6d0127e589 100644 --- a/libyul/optimiser/VarDeclInitializer.cpp +++ b/libyul/optimiser/VarDeclInitializer.cpp @@ -40,7 +40,7 @@ void VarDeclInitializer::operator()(Block& _block) if (_varDecl.variables.size() == 1) { - _varDecl.value = std::make_unique(m_dialect.zeroLiteralForType(_varDecl.variables.front().type)); + _varDecl.value = std::make_unique(m_dialect.zeroLiteral()); return {}; } else @@ -48,7 +48,7 @@ void VarDeclInitializer::operator()(Block& _block) OptionalStatements ret{std::vector{}}; for (auto& var: _varDecl.variables) { - std::unique_ptr expr = std::make_unique(m_dialect.zeroLiteralForType(var.type)); + std::unique_ptr expr = std::make_unique(m_dialect.zeroLiteral()); ret->emplace_back(VariableDeclaration{std::move(_varDecl.debugData), {std::move(var)}, std::move(expr)}); } return ret; From f5174e767a01316cd56470de334c233b6dc66cda Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Wed, 14 Aug 2024 10:28:28 +0200 Subject: [PATCH 0375/1022] Yul: Remove dialect and printing mode from AsmPrinter --- libsolidity/codegen/CompilerContext.cpp | 4 ++-- libsolidity/codegen/ir/IRGeneratorForStatements.cpp | 2 +- .../codegen/IRGeneratorForStatements.cpp | 2 +- libyul/AsmPrinter.cpp | 4 ---- libyul/AsmPrinter.h | 12 ------------ libyul/Object.cpp | 8 ++------ libyul/Object.h | 6 ------ libyul/ObjectOptimizer.cpp | 2 -- libyul/YulStack.cpp | 2 -- libyul/optimiser/ControlFlowSimplifier.cpp | 3 +-- libyul/optimiser/ControlFlowSimplifier.h | 6 ++---- libyul/optimiser/Suite.cpp | 2 +- test/libyul/Common.cpp | 4 +--- test/libyul/YulOptimizerTest.cpp | 4 ++-- test/tools/yulopti.cpp | 4 ++-- tools/yulPhaser/Program.cpp | 2 +- 16 files changed, 16 insertions(+), 51 deletions(-) diff --git a/libsolidity/codegen/CompilerContext.cpp b/libsolidity/codegen/CompilerContext.cpp index b1b76a97b8d6..2e94e9f0b8d2 100644 --- a/libsolidity/codegen/CompilerContext.cpp +++ b/libsolidity/codegen/CompilerContext.cpp @@ -491,8 +491,8 @@ void CompilerContext::appendInlineAssembly( { // Store as generated sources, but first re-parse to update the source references. solAssert(m_generatedYulUtilityCode.empty(), ""); - m_generatedYulUtilityCode = yul::AsmPrinter(yul::AsmPrinter::TypePrinting::OmitDefault, dialect)(obj.code()->root()); - std::string code = yul::AsmPrinter{yul::AsmPrinter::TypePrinting::OmitDefault, dialect}(obj.code()->root()); + m_generatedYulUtilityCode = yul::AsmPrinter()(obj.code()->root()); + std::string code = yul::AsmPrinter{}(obj.code()->root()); langutil::CharStream charStream(m_generatedYulUtilityCode, _sourceName); obj.setCode(yul::Parser(errorReporter, dialect).parse(charStream)); obj.analysisInfo = std::make_shared(yul::AsmAnalyzer::analyzeStrictAssertCorrect(dialect, obj)); diff --git a/libsolidity/codegen/ir/IRGeneratorForStatements.cpp b/libsolidity/codegen/ir/IRGeneratorForStatements.cpp index 459959604625..5fed99d21f41 100644 --- a/libsolidity/codegen/ir/IRGeneratorForStatements.cpp +++ b/libsolidity/codegen/ir/IRGeneratorForStatements.cpp @@ -2256,7 +2256,7 @@ bool IRGeneratorForStatements::visit(InlineAssembly const& _inlineAsm) solAssert(std::holds_alternative(modified)); - appendCode() << yul::AsmPrinter(yul::AsmPrinter::TypePrinting::Full, _inlineAsm.dialect())(std::get(modified)) << "\n"; + appendCode() << yul::AsmPrinter()(std::get(modified)) << "\n"; return false; } diff --git a/libsolidity/experimental/codegen/IRGeneratorForStatements.cpp b/libsolidity/experimental/codegen/IRGeneratorForStatements.cpp index 3c8bcc9bbbab..6925a434d0a1 100644 --- a/libsolidity/experimental/codegen/IRGeneratorForStatements.cpp +++ b/libsolidity/experimental/codegen/IRGeneratorForStatements.cpp @@ -132,7 +132,7 @@ bool IRGeneratorForStatements::visit(InlineAssembly const& _assembly) CopyTranslate bodyCopier{m_context, _assembly.dialect(), _assembly.annotation().externalReferences}; yul::Statement modified = bodyCopier(_assembly.operations().root()); solAssert(std::holds_alternative(modified)); - m_code << yul::AsmPrinter(yul::AsmPrinter::TypePrinting::Full, _assembly.dialect())(std::get(modified)) << "\n"; + m_code << yul::AsmPrinter()(std::get(modified)) << "\n"; return false; } diff --git a/libyul/AsmPrinter.cpp b/libyul/AsmPrinter.cpp index a5ce47d12524..612cb8ee0f75 100644 --- a/libyul/AsmPrinter.cpp +++ b/libyul/AsmPrinter.cpp @@ -244,10 +244,6 @@ std::string AsmPrinter::formatTypedName(TypedName _variable) std::string AsmPrinter::appendTypeName(YulName _type) const { - yulAssert( - m_typePrintingMode == TypePrinting::OmitDefault || m_typePrintingMode == TypePrinting::Full, - "unhandled printing mode" - ); if (_type.empty()) return {}; else diff --git a/libyul/AsmPrinter.h b/libyul/AsmPrinter.h index 90fa3a4b5abd..05b6fb9d8f1e 100644 --- a/libyul/AsmPrinter.h +++ b/libyul/AsmPrinter.h @@ -46,21 +46,11 @@ struct Dialect; class AsmPrinter { public: - enum class TypePrinting - { - OmitDefault, - Full - }; - explicit AsmPrinter( - TypePrinting const _typePrintingMode, - Dialect const& _dialect, std::optional>> _sourceIndexToName = {}, langutil::DebugInfoSelection const& _debugInfoSelection = langutil::DebugInfoSelection::Default(), langutil::CharStreamProvider const* _soliditySourceProvider = nullptr ): - m_typePrintingMode(_typePrintingMode), - m_dialect(_dialect), m_debugInfoSelection(_debugInfoSelection), m_soliditySourceProvider(_soliditySourceProvider) { @@ -102,8 +92,6 @@ class AsmPrinter return formatDebugData(_node.debugData, !isExpression); } - TypePrinting const m_typePrintingMode{}; - Dialect const& m_dialect; std::map m_nameToSourceIndex; langutil::SourceLocation m_lastLocation = {}; langutil::DebugInfoSelection m_debugInfoSelection = {}; diff --git a/libyul/Object.cpp b/libyul/Object.cpp index 57c783b83f39..c6ba5311ad5c 100644 --- a/libyul/Object.cpp +++ b/libyul/Object.cpp @@ -38,14 +38,12 @@ using namespace solidity::langutil; using namespace solidity::util; using namespace solidity::yul; -std::string Data::toString(Dialect const&, AsmPrinter::TypePrinting, DebugInfoSelection const&, CharStreamProvider const*) const +std::string Data::toString(DebugInfoSelection const&, CharStreamProvider const*) const { return "data \"" + name + "\" hex\"" + util::toHex(data) + "\""; } std::string Object::toString( - Dialect const& _dialect, - AsmPrinter::TypePrinting const _printingMode, DebugInfoSelection const& _debugInfoSelection, CharStreamProvider const* _soliditySourceProvider ) const @@ -54,15 +52,13 @@ std::string Object::toString( yulAssert(debugData, "No debug data"); std::string inner = "code " + AsmPrinter( - _printingMode, - _dialect, debugData->sourceNames, _debugInfoSelection, _soliditySourceProvider )(code()->root()); for (auto const& obj: subObjects) - inner += "\n" + obj->toString(_dialect, _printingMode, _debugInfoSelection, _soliditySourceProvider); + inner += "\n" + obj->toString(_debugInfoSelection, _soliditySourceProvider); return debugData->formatUseSrcComment() + diff --git a/libyul/Object.h b/libyul/Object.h index fa9ef96eebc7..230f97866e09 100644 --- a/libyul/Object.h +++ b/libyul/Object.h @@ -54,8 +54,6 @@ struct ObjectNode /// Can be empty since .yul files can also just contain code, without explicitly placing it in an object. std::string name; virtual std::string toString( - Dialect const& _dialect, - AsmPrinter::TypePrinting printingMode, langutil::DebugInfoSelection const& _debugInfoSelection, langutil::CharStreamProvider const* _soliditySourceProvider ) const = 0; @@ -72,8 +70,6 @@ struct Data: public ObjectNode bytes data; std::string toString( - Dialect const& _dialect, - AsmPrinter::TypePrinting printingMode, langutil::DebugInfoSelection const& _debugInfoSelection, langutil::CharStreamProvider const* _soliditySourceProvider ) const override; @@ -97,8 +93,6 @@ struct Object: public ObjectNode public: /// @returns a (parseable) string representation. std::string toString( - Dialect const& _dialect, - AsmPrinter::TypePrinting printingMode = AsmPrinter::TypePrinting::Full, langutil::DebugInfoSelection const& _debugInfoSelection = langutil::DebugInfoSelection::Default(), langutil::CharStreamProvider const* _soliditySourceProvider = nullptr ) const override; diff --git a/libyul/ObjectOptimizer.cpp b/libyul/ObjectOptimizer.cpp index eaaac97d56a4..3694367c5e32 100644 --- a/libyul/ObjectOptimizer.cpp +++ b/libyul/ObjectOptimizer.cpp @@ -142,8 +142,6 @@ std::optional ObjectOptimizer::calculateCacheKey( ) { AsmPrinter asmPrinter( - AsmPrinter::TypePrinting::OmitDefault, - languageToDialect(_settings.language, _settings.evmVersion), _debugData.sourceNames, DebugInfoSelection::All() ); diff --git a/libyul/YulStack.cpp b/libyul/YulStack.cpp index eac84ae3a13e..1f57eda48cb3 100644 --- a/libyul/YulStack.cpp +++ b/libyul/YulStack.cpp @@ -351,8 +351,6 @@ std::string YulStack::print( yulAssert(m_parserResult, ""); yulAssert(m_parserResult->hasCode(), ""); return m_parserResult->toString( - languageToDialect(m_language, m_evmVersion), - AsmPrinter::TypePrinting::OmitDefault, m_debugInfoSelection, _soliditySourceProvider ) + "\n"; diff --git a/libyul/optimiser/ControlFlowSimplifier.cpp b/libyul/optimiser/ControlFlowSimplifier.cpp index 2d0dbb4679a2..2bd505a1c8a2 100644 --- a/libyul/optimiser/ControlFlowSimplifier.cpp +++ b/libyul/optimiser/ControlFlowSimplifier.cpp @@ -72,8 +72,7 @@ void removeEmptyCasesFromSwitch(Switch& _switchStmt) void ControlFlowSimplifier::run(OptimiserStepContext& _context, Block& _ast) { - TypeInfo typeInfo(_context.dialect, _ast); - ControlFlowSimplifier{_context.dialect, typeInfo}(_ast); + ControlFlowSimplifier{_context.dialect}(_ast); } void ControlFlowSimplifier::operator()(Block& _block) diff --git a/libyul/optimiser/ControlFlowSimplifier.h b/libyul/optimiser/ControlFlowSimplifier.h index 3ebbe7c9aeee..0f0e725cd0ec 100644 --- a/libyul/optimiser/ControlFlowSimplifier.h +++ b/libyul/optimiser/ControlFlowSimplifier.h @@ -63,9 +63,8 @@ class ControlFlowSimplifier: public ASTModifier void visit(Statement& _st) override; private: - ControlFlowSimplifier(Dialect const& _dialect, TypeInfo const& _typeInfo): - m_dialect(_dialect), - m_typeInfo(_typeInfo) + explicit ControlFlowSimplifier(Dialect const& _dialect): + m_dialect(_dialect) {} void simplify(std::vector& _statements); @@ -74,7 +73,6 @@ class ControlFlowSimplifier: public ASTModifier std::optional> reduceSingleCaseSwitch(Switch& _switchStmt) const; Dialect const& m_dialect; - TypeInfo const& m_typeInfo; size_t m_numBreakStatements = 0; size_t m_numContinueStatements = 0; }; diff --git a/libyul/optimiser/Suite.cpp b/libyul/optimiser/Suite.cpp index a06f48a7f236..d7043e42f30f 100644 --- a/libyul/optimiser/Suite.cpp +++ b/libyul/optimiser/Suite.cpp @@ -520,7 +520,7 @@ void OptimiserSuite::runSequence(std::vector const& _steps, Block& else { std::cout << "== Running " << step << " changed the AST." << std::endl; - std::cout << AsmPrinter{AsmPrinter::TypePrinting::Full, m_context.dialect}(_ast) << std::endl; + std::cout << AsmPrinter{}(_ast) << std::endl; copy = std::make_unique(std::get(ASTCopier{}(_ast))); } } diff --git a/test/libyul/Common.cpp b/test/libyul/Common.cpp index a0c00c90d781..8980adcb1821 100644 --- a/test/libyul/Common.cpp +++ b/test/libyul/Common.cpp @@ -96,9 +96,7 @@ yul::Block yul::test::disambiguate(std::string const& _source) std::string yul::test::format(std::string const& _source) { - auto const version = solidity::test::CommonOptions::get().evmVersion(); - Dialect const& dialect = EVMDialect::strictAssemblyForEVMObjects(version); - return yul::AsmPrinter(yul::AsmPrinter::TypePrinting::Full, dialect)(parse(_source).first->root()); + return yul::AsmPrinter()(parse(_source).first->root()); } namespace diff --git a/test/libyul/YulOptimizerTest.cpp b/test/libyul/YulOptimizerTest.cpp index 048eb7145dc0..7f2f5815a675 100644 --- a/test/libyul/YulOptimizerTest.cpp +++ b/test/libyul/YulOptimizerTest.cpp @@ -81,9 +81,9 @@ TestCase::TestResult YulOptimizerTest::run(std::ostream& _stream, std::string co auto optimizedObject = tester.optimizedObject(); std::string printedOptimizedObject; if (optimizedObject->subObjects.empty()) - printedOptimizedObject = AsmPrinter{AsmPrinter::TypePrinting::OmitDefault, *m_dialect}(optimizedObject->code()->root()); + printedOptimizedObject = AsmPrinter{}(optimizedObject->code()->root()); else - printedOptimizedObject = optimizedObject->toString(*m_dialect); + printedOptimizedObject = optimizedObject->toString(); // Re-parse new code for compilability if (!std::get<0>(parse(_stream, _linePrefix, _formatted, printedOptimizedObject))) diff --git a/test/tools/yulopti.cpp b/test/tools/yulopti.cpp index faab89e7923e..891f39c43365 100644 --- a/test/tools/yulopti.cpp +++ b/test/tools/yulopti.cpp @@ -180,7 +180,7 @@ class YulOpti parse(_source); disambiguate(); OptimiserSuite{m_context}.runSequence(_steps, *m_astRoot); - std::cout << AsmPrinter{AsmPrinter::TypePrinting::OmitDefault, m_dialect}(*m_astRoot) << std::endl; + std::cout << AsmPrinter{}(*m_astRoot) << std::endl; } void runInteractive(std::string _source, bool _disambiguated = false) @@ -228,7 +228,7 @@ class YulOpti *m_astRoot ); } - _source = AsmPrinter{AsmPrinter::TypePrinting::OmitDefault, m_dialect}(*m_astRoot); + _source = AsmPrinter{}(*m_astRoot); } catch (...) { diff --git a/tools/yulPhaser/Program.cpp b/tools/yulPhaser/Program.cpp index 14b6406493d7..bb9eebc4badc 100644 --- a/tools/yulPhaser/Program.cpp +++ b/tools/yulPhaser/Program.cpp @@ -105,7 +105,7 @@ void Program::optimise(std::vector const& _optimisationSteps) std::ostream& phaser::operator<<(std::ostream& _stream, Program const& _program) { - return _stream << AsmPrinter(AsmPrinter::TypePrinting::Full, _program.m_dialect)(_program.m_ast->root()); + return _stream << AsmPrinter()(_program.m_ast->root()); } std::string Program::toJson() const From 0d0f2771654b14ee0e8d317a5eb22dbff8eab332 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Thu, 15 Aug 2024 10:19:02 +0200 Subject: [PATCH 0376/1022] Yul: Remove types from AST --- Changelog.md | 1 + libsolidity/analysis/ReferencesResolver.cpp | 2 +- .../codegen/ir/IRGeneratorForStatements.cpp | 2 +- libyul/AST.h | 12 +- libyul/ASTForward.h | 2 +- libyul/AsmAnalysis.cpp | 178 ++---- libyul/AsmAnalysis.h | 20 +- libyul/AsmJsonConverter.cpp | 6 +- libyul/AsmJsonConverter.h | 2 +- libyul/AsmJsonImporter.cpp | 20 +- libyul/AsmJsonImporter.h | 2 +- libyul/AsmParser.cpp | 30 +- libyul/AsmParser.h | 3 +- libyul/AsmPrinter.cpp | 23 +- libyul/AsmPrinter.h | 5 +- libyul/CMakeLists.txt | 2 - libyul/Dialect.cpp | 2 +- libyul/Scope.cpp | 7 +- libyul/Scope.h | 13 +- libyul/ScopeFiller.cpp | 12 +- libyul/ScopeFiller.h | 4 +- libyul/Utilities.cpp | 4 +- libyul/backends/evm/ConstantOptimiser.cpp | 2 +- .../backends/evm/ControlFlowGraphBuilder.cpp | 6 +- libyul/backends/evm/EVMCodeTransform.cpp | 14 +- libyul/backends/evm/EVMCodeTransform.h | 4 +- .../evm/OptimizedEVMCodeTransform.cpp | 12 +- libyul/optimiser/ASTCopier.cpp | 4 +- libyul/optimiser/ASTCopier.h | 2 +- libyul/optimiser/BlockHasher.cpp | 1 - libyul/optimiser/ControlFlowSimplifier.cpp | 1 - libyul/optimiser/ControlFlowSimplifier.h | 1 - libyul/optimiser/DataFlowAnalyzer.h | 2 +- libyul/optimiser/ExpressionSimplifier.cpp | 2 +- libyul/optimiser/ExpressionSplitter.cpp | 8 +- libyul/optimiser/ExpressionSplitter.h | 8 +- libyul/optimiser/ForLoopConditionIntoBody.cpp | 3 +- libyul/optimiser/FullInliner.cpp | 4 +- libyul/optimiser/FunctionSpecializer.cpp | 2 +- libyul/optimiser/LoadResolver.cpp | 6 +- libyul/optimiser/NameDisplacer.cpp | 2 +- libyul/optimiser/NameSimplifier.cpp | 4 +- libyul/optimiser/NameSimplifier.h | 2 +- libyul/optimiser/SSATransform.cpp | 36 +- libyul/optimiser/SSAValueTracker.h | 2 +- libyul/optimiser/SimplificationRules.cpp | 2 +- libyul/optimiser/StackLimitEvader.cpp | 2 +- libyul/optimiser/StackToMemoryMover.cpp | 31 +- libyul/optimiser/StackToMemoryMover.h | 6 +- libyul/optimiser/SyntacticalEquality.cpp | 11 +- libyul/optimiser/SyntacticalEquality.h | 2 +- libyul/optimiser/TypeInfo.cpp | 103 ---- libyul/optimiser/TypeInfo.h | 65 --- libyul/optimiser/UnusedFunctionsCommon.cpp | 7 +- libyul/optimiser/UnusedPruner.cpp | 2 +- libyul/optimiser/UnusedStoreEliminator.cpp | 6 +- libyul/optimiser/VarNameCleaner.cpp | 14 +- libyul/optimiser/VarNameCleaner.h | 2 +- test/libyul/StackShufflingTest.cpp | 4 +- test/libyul/YulOptimizerTestCommon.cpp | 4 +- test/libyul/yulSyntaxTests/invalid_type.yul | 2 +- test/libyul/yulSyntaxTests/invalid_type2.yul | 3 +- test/libyul/yulSyntaxTests/invalid_type3.yul | 4 +- test/libyul/yulSyntaxTests/invalid_type4.yul | 3 +- .../yulSyntaxTests/literal_invalid_type.yul | 4 +- .../more_than_256_analysis_errors.yul | 512 +++++++++--------- 66 files changed, 481 insertions(+), 788 deletions(-) delete mode 100644 libyul/optimiser/TypeInfo.cpp delete mode 100644 libyul/optimiser/TypeInfo.h diff --git a/Changelog.md b/Changelog.md index 288136dd9181..04bfa929530b 100644 --- a/Changelog.md +++ b/Changelog.md @@ -19,6 +19,7 @@ Compiler Features: * Standard JSON Interface: Do not perform IR optimization when only unoptimized IR is requested. * Standard JSON Interface: Add ``transientStorageLayout`` output. * Yul: Drop the deprecated typed Yul dialect that was only accessible via ``--yul`` in the CLI. + * Yul: The presence of types in untyped Yul dialects is now a parser error. * Yul Optimizer: Caching of optimized IR to speed up optimization of contracts with bytecode dependencies. * Yul Optimizer: The optimizer now treats some previously unrecognized identical literals as identical. * Commandline Interface: Allow the use of ``--asm-json`` output option in assembler mode to export EVM assembly of the contracts in JSON format. diff --git a/libsolidity/analysis/ReferencesResolver.cpp b/libsolidity/analysis/ReferencesResolver.cpp index bb3b20e93a50..079bbf33ceab 100644 --- a/libsolidity/analysis/ReferencesResolver.cpp +++ b/libsolidity/analysis/ReferencesResolver.cpp @@ -272,7 +272,7 @@ void ReferencesResolver::operator()(yul::FunctionDefinition const& _function) { solAssert(nativeLocationOf(_function) == originLocationOf(_function), ""); validateYulIdentifierName(_function.name, nativeLocationOf(_function)); - for (yul::TypedName const& varName: _function.parameters + _function.returnVariables) + for (yul::NameWithDebugData const& varName: _function.parameters + _function.returnVariables) { solAssert(nativeLocationOf(varName) == originLocationOf(varName), ""); validateYulIdentifierName(varName.name, nativeLocationOf(varName)); diff --git a/libsolidity/codegen/ir/IRGeneratorForStatements.cpp b/libsolidity/codegen/ir/IRGeneratorForStatements.cpp index 5fed99d21f41..c3cd69f43e22 100644 --- a/libsolidity/codegen/ir/IRGeneratorForStatements.cpp +++ b/libsolidity/codegen/ir/IRGeneratorForStatements.cpp @@ -204,7 +204,7 @@ struct CopyTranslate: public yul::ASTCopier solAssert(false); if (isDigit(value.front())) - return yul::Literal{_identifier.debugData, yul::LiteralKind::Number, yul::valueOfNumberLiteral(value), {}}; + return yul::Literal{_identifier.debugData, yul::LiteralKind::Number, yul::valueOfNumberLiteral(value)}; else return yul::Identifier{_identifier.debugData, yul::YulName{value}}; } diff --git a/libyul/AST.h b/libyul/AST.h index 6b9682580c0a..f51846280a8f 100644 --- a/libyul/AST.h +++ b/libyul/AST.h @@ -36,10 +36,8 @@ namespace solidity::yul { -using Type = YulName; - -struct TypedName { langutil::DebugData::ConstPtr debugData; YulName name; Type type; }; -using TypedNameList = std::vector; +struct NameWithDebugData { langutil::DebugData::ConstPtr debugData; YulName name; }; +using NameWithDebugDataList = std::vector; /// Literal number or string (up to 32 bytes) enum class LiteralKind { Number, Boolean, String }; @@ -68,7 +66,7 @@ class LiteralValue { std::optional m_numericValue; std::shared_ptr m_stringValue; }; -struct Literal { langutil::DebugData::ConstPtr debugData; LiteralKind kind; LiteralValue value; Type type; }; +struct Literal { langutil::DebugData::ConstPtr debugData; LiteralKind kind; LiteralValue value; }; /// External / internal identifier or label reference struct Identifier { langutil::DebugData::ConstPtr debugData; YulName name; }; /// Assignment ("x := mload(20:u256)", expects push-1-expression on the right hand @@ -82,11 +80,11 @@ struct FunctionCall { langutil::DebugData::ConstPtr debugData; Identifier functi /// Statement that contains only a single expression struct ExpressionStatement { langutil::DebugData::ConstPtr debugData; Expression expression; }; /// Block-scope variable declaration ("let x:u256 := mload(20:u256)"), non-hoisted -struct VariableDeclaration { langutil::DebugData::ConstPtr debugData; TypedNameList variables; std::unique_ptr value; }; +struct VariableDeclaration { langutil::DebugData::ConstPtr debugData; NameWithDebugDataList variables; std::unique_ptr value; }; /// Block that creates a scope (frees declared stack variables) struct Block { langutil::DebugData::ConstPtr debugData; std::vector statements; }; /// Function definition ("function f(a, b) -> (d, e) { ... }") -struct FunctionDefinition { langutil::DebugData::ConstPtr debugData; YulName name; TypedNameList parameters; TypedNameList returnVariables; Block body; }; +struct FunctionDefinition { langutil::DebugData::ConstPtr debugData; YulName name; NameWithDebugDataList parameters; NameWithDebugDataList returnVariables; Block body; }; /// Conditional execution without "else" part. struct If { langutil::DebugData::ConstPtr debugData; std::unique_ptr condition; Block body; }; /// Switch case or default case diff --git a/libyul/ASTForward.h b/libyul/ASTForward.h index f6fa09387739..8aba4f248c07 100644 --- a/libyul/ASTForward.h +++ b/libyul/ASTForward.h @@ -48,7 +48,7 @@ struct ExpressionStatement; struct Block; class AST; -struct TypedName; +struct NameWithDebugData; using Expression = std::variant; using Statement = std::variant; diff --git a/libyul/AsmAnalysis.cpp b/libyul/AsmAnalysis.cpp index 908e30e62931..d039b3b47c08 100644 --- a/libyul/AsmAnalysis.cpp +++ b/libyul/AsmAnalysis.cpp @@ -109,9 +109,8 @@ AsmAnalysisInfo AsmAnalyzer::analyzeStrictAssertCorrect( return analysisInfo; } -std::vector AsmAnalyzer::operator()(Literal const& _literal) +size_t AsmAnalyzer::operator()(Literal const& _literal) { - expectValidType(_literal.type, nativeLocationOf(_literal)); bool erroneousLiteralValue = false; if (_literal.kind == LiteralKind::String && !_literal.value.unlimited() && _literal.value.hint() && _literal.value.hint()->size() > 32) { @@ -128,22 +127,14 @@ std::vector AsmAnalyzer::operator()(Literal const& _literal) m_errorReporter.typeError(6708_error, nativeLocationOf(_literal), "Number literal too large (> 256 bits)"); } - if (_literal.kind == LiteralKind::Boolean && !_literal.type.empty()) - m_errorReporter.typeError( - 5170_error, - nativeLocationOf(_literal), - "Invalid type \"" + _literal.type.str() + "\" for literal \"" + formatLiteral(_literal) + "\"." - ); - yulAssert(erroneousLiteralValue ^ validLiteral(_literal), "Invalid literal after validating it through AsmAnalyzer."); - return {_literal.type}; + return 1; } -std::vector AsmAnalyzer::operator()(Identifier const& _identifier) +size_t AsmAnalyzer::operator()(Identifier const& _identifier) { yulAssert(!_identifier.name.empty(), ""); auto watcher = m_errorReporter.errorWatcher(); - YulName type{}; if (m_currentScope->lookup(_identifier.name, GenericVisitor{ [&](Scope::Variable const& _var) @@ -154,7 +145,6 @@ std::vector AsmAnalyzer::operator()(Identifier const& _identifier) nativeLocationOf(_identifier), "Variable " + _identifier.name.str() + " used before it was declared." ); - type = _var.type; }, [&](Scope::Function const&) { @@ -191,21 +181,21 @@ std::vector AsmAnalyzer::operator()(Identifier const& _identifier) } - return {type}; + return 1; } void AsmAnalyzer::operator()(ExpressionStatement const& _statement) { auto watcher = m_errorReporter.errorWatcher(); - std::vector types = std::visit(*this, _statement.expression); - if (watcher.ok() && !types.empty()) + size_t numReturns = std::visit(*this, _statement.expression); + if (watcher.ok() && numReturns > 0) m_errorReporter.typeError( 3083_error, nativeLocationOf(_statement), "Top-level expressions are not supposed to return values (this expression returns " + - std::to_string(types.size()) + + std::to_string(numReturns) + " value" + - (types.size() == 1 ? "" : "s") + + (numReturns == 1 ? "" : "s") + "). Use ``pop()`` or assign them." ); } @@ -227,9 +217,9 @@ void AsmAnalyzer::operator()(Assignment const& _assignment) " occurs multiple times on the left-hand side of the assignment." ); - std::vector types = std::visit(*this, *_assignment.value); + size_t numRhsValues = std::visit(*this, *_assignment.value); - if (types.size() != numVariables) + if (numRhsValues != numVariables) m_errorReporter.declarationError( 8678_error, nativeLocationOf(_assignment), @@ -238,13 +228,12 @@ void AsmAnalyzer::operator()(Assignment const& _assignment) "\" does not match number of values (" + std::to_string(numVariables) + " vs. " + - std::to_string(types.size()) + + std::to_string(numRhsValues) + ")" ); for (size_t i = 0; i < numVariables; ++i) - if (i < types.size()) - checkAssignment(_assignment.variableNames[i], types[i]); + checkAssignment(_assignment.variableNames[i]); } void AsmAnalyzer::operator()(VariableDeclaration const& _varDecl) @@ -261,13 +250,12 @@ void AsmAnalyzer::operator()(VariableDeclaration const& _varDecl) for (auto const& variable: _varDecl.variables) { expectValidIdentifier(variable.name, nativeLocationOf(variable)); - expectValidType(variable.type, nativeLocationOf(variable)); } if (_varDecl.value) { - std::vector types = std::visit(*this, *_varDecl.value); - if (types.size() != numVariables) + size_t numValues = std::visit(*this, *_varDecl.value); + if (numValues != numVariables) m_errorReporter.declarationError( 3812_error, nativeLocationOf(_varDecl), @@ -276,26 +264,12 @@ void AsmAnalyzer::operator()(VariableDeclaration const& _varDecl) + "\": " + std::to_string(numVariables) + " variables and " + - std::to_string(types.size()) + + std::to_string(numValues) + " values." ); - - for (size_t i = 0; i < _varDecl.variables.size(); ++i) - { - YulName givenType{}; - if (i < types.size()) - givenType = types[i]; - TypedName const& variable = _varDecl.variables[i]; - if (variable.type != givenType) - m_errorReporter.typeError( - 3947_error, - nativeLocationOf(variable), - "Assigning value of type \"" + givenType.str() + "\" to variable of type \"" + variable.type.str() + "\"." - ); - } } - for (TypedName const& variable: _varDecl.variables) + for (NameWithDebugData const& variable: _varDecl.variables) m_activeVariables.insert(&std::get( m_currentScope->identifiers.at(variable.name)) ); @@ -311,19 +285,18 @@ void AsmAnalyzer::operator()(FunctionDefinition const& _funDef) for (auto const& var: _funDef.parameters + _funDef.returnVariables) { expectValidIdentifier(var.name, nativeLocationOf(var)); - expectValidType(var.type, nativeLocationOf(var)); m_activeVariables.insert(&std::get(varScope.identifiers.at(var.name))); } (*this)(_funDef.body); } -std::vector AsmAnalyzer::operator()(FunctionCall const& _funCall) +size_t AsmAnalyzer::operator()(FunctionCall const& _funCall) { yulAssert(!_funCall.functionName.name.empty(), ""); auto watcher = m_errorReporter.errorWatcher(); - std::vector const* parameterTypes = nullptr; - std::vector const* returnTypes = nullptr; + std::optional numParameters; + std::optional numReturns; std::vector> const* literalArguments = nullptr; if (BuiltinFunction const* f = m_dialect.builtin(_funCall.functionName.name)) @@ -354,8 +327,8 @@ std::vector AsmAnalyzer::operator()(FunctionCall const& _funCall) "The use of transient storage for reentrancy guards that are cleared at the end of the call is safe." ); - parameterTypes = &f->parameters; - returnTypes = &f->returns; + numParameters = f->parameters.size(); + numReturns = f->returns.size(); if (!f->literalArguments.empty()) literalArguments = &f->literalArguments; @@ -373,8 +346,8 @@ std::vector AsmAnalyzer::operator()(FunctionCall const& _funCall) }, [&](Scope::Function const& _fun) { - parameterTypes = &_fun.arguments; - returnTypes = &_fun.returns; + numParameters = _fun.numArguments; + numReturns = _fun.numReturns; } })) { @@ -397,17 +370,17 @@ std::vector AsmAnalyzer::operator()(FunctionCall const& _funCall) yulAssert(!watcher.ok(), "Expected a reported error."); } - if (parameterTypes && _funCall.arguments.size() != parameterTypes->size()) + if (numParameters && _funCall.arguments.size() != *numParameters) m_errorReporter.typeError( 7000_error, nativeLocationOf(_funCall.functionName), "Function \"" + _funCall.functionName.name.str() + "\" expects " + - std::to_string(parameterTypes->size()) + + std::to_string(*numParameters) + " arguments but got " + std::to_string(_funCall.arguments.size()) + "." ); - std::vector argTypes; + size_t numArgs{0}; for (size_t i = _funCall.arguments.size(); i > 0; i--) { Expression const& arg = _funCall.arguments[i - 1]; @@ -453,33 +426,30 @@ std::vector AsmAnalyzer::operator()(FunctionCall const& _funCall) "The \"verbatim_*\" builtins cannot be used with empty bytecode." ); } - argTypes.emplace_back(expectUnlimitedStringLiteral(std::get(arg))); + expectUnlimitedStringLiteral(std::get(arg)); + ++numArgs; continue; } } - argTypes.emplace_back(expectExpression(arg)); + expectExpression(arg); + ++numArgs; } - std::reverse(argTypes.begin(), argTypes.end()); - - if (parameterTypes && parameterTypes->size() == argTypes.size()) - for (size_t i = 0; i < parameterTypes->size(); ++i) - expectType((*parameterTypes)[i], argTypes[i], nativeLocationOf(_funCall.arguments[i])); if (watcher.ok()) { - yulAssert(parameterTypes && parameterTypes->size() == argTypes.size(), ""); - yulAssert(returnTypes, ""); - return *returnTypes; + yulAssert(numParameters && numParameters == numArgs, ""); + yulAssert(numReturns, ""); + return *numReturns; } - else if (returnTypes) - return std::vector(returnTypes->size(), YulName{}); + else if (numReturns) + return *numReturns; else return {}; } void AsmAnalyzer::operator()(If const& _if) { - expectBoolExpression(*_if.condition); + expectExpression(*_if.condition); (*this)(_if.body); } @@ -495,7 +465,7 @@ void AsmAnalyzer::operator()(Switch const& _switch) "\"switch\" statement with only a default case." ); - YulName valueType = expectExpression(*_switch.expression); + expectExpression(*_switch.expression); std::set cases; for (auto const& _case: _switch.cases) @@ -504,8 +474,6 @@ void AsmAnalyzer::operator()(Switch const& _switch) { auto watcher = m_errorReporter.errorWatcher(); - expectType(valueType, _case.value->type, nativeLocationOf(*_case.value)); - // We cannot use "expectExpression" here because *_case.value is not an // Expression and would be converted to an Expression otherwise. (*this)(*_case.value); @@ -537,7 +505,7 @@ void AsmAnalyzer::operator()(ForLoop const& _for) // condition, the body and the post part inside. m_currentScope = &scope(&_for.pre); - expectBoolExpression(*_for.condition); + expectExpression(*_for.condition); // backup outer for-loop & create new state auto outerForLoop = m_currentForLoop; m_currentForLoop = &_for; @@ -560,50 +528,30 @@ void AsmAnalyzer::operator()(Block const& _block) m_currentScope = previousScope; } -YulName AsmAnalyzer::expectExpression(Expression const& _expr) +void AsmAnalyzer::expectExpression(Expression const& _expr) { - std::vector types = std::visit(*this, _expr); - if (types.size() != 1) + size_t numValues = std::visit(*this, _expr); + if (numValues != 1) m_errorReporter.typeError( 3950_error, nativeLocationOf(_expr), "Expected expression to evaluate to one value, but got " + - std::to_string(types.size()) + + std::to_string(numValues) + " values instead." ); - return types.empty() ? YulName{} : types.front(); } -YulName AsmAnalyzer::expectUnlimitedStringLiteral(Literal const& _literal) +void AsmAnalyzer::expectUnlimitedStringLiteral(Literal const& _literal) { yulAssert(_literal.kind == LiteralKind::String); - yulAssert(_literal.type.empty()); yulAssert(_literal.value.unlimited()); - - return {_literal.type}; -} - -void AsmAnalyzer::expectBoolExpression(Expression const& _expr) -{ - YulName type = expectExpression(_expr); - static YulName boolType = {}; - if (type != boolType) - m_errorReporter.typeError( - 1733_error, - nativeLocationOf(_expr), - "Expected a value of boolean type \"" + - boolType.str() + - "\" but got \"" + - type.str() + - "\"" - ); } -void AsmAnalyzer::checkAssignment(Identifier const& _variable, YulName _valueType) +void AsmAnalyzer::checkAssignment(Identifier const& _variable) { yulAssert(!_variable.name.empty(), ""); auto watcher = m_errorReporter.errorWatcher(); - std::optional variableType = std::nullopt; + bool hasVariable = false; bool found = false; if (Scope::Identifier const* var = m_currentScope->lookup(_variable.name)) { @@ -624,7 +572,7 @@ void AsmAnalyzer::checkAssignment(Identifier const& _variable, YulName _valueTyp "Variable " + _variable.name.str() + " used before it was declared." ); else - variableType = std::get(*var).type; + hasVariable = true; found = true; } else if (m_resolver) @@ -633,25 +581,15 @@ void AsmAnalyzer::checkAssignment(Identifier const& _variable, YulName _valueTyp if (m_resolver(_variable, yul::IdentifierContext::LValue, insideFunction)) { found = true; - variableType = YulName{}; + hasVariable = true; } } if (!found && watcher.ok()) // Only add message if the callback did not. m_errorReporter.declarationError(4634_error, nativeLocationOf(_variable), "Variable not found or variable not lvalue."); - if (variableType && *variableType != _valueType) - m_errorReporter.typeError( - 9547_error, - nativeLocationOf(_variable), - "Assigning a value of type \"" + - _valueType.str() + - "\" to a variable of type \"" + - variableType->str() + - "\"." - ); - yulAssert(!watcher.ok() || variableType, ""); + yulAssert(!watcher.ok() || hasVariable, ""); } Scope& AsmAnalyzer::scope(Block const* _block) @@ -687,26 +625,6 @@ void AsmAnalyzer::expectValidIdentifier(YulName _identifier, SourceLocation cons ); } -void AsmAnalyzer::expectValidType(YulName _type, SourceLocation const& _location) -{ - if (!_type.empty()) - m_errorReporter.typeError( - 5473_error, - _location, - fmt::format("\"{}\" is not a valid type (user defined types are not yet supported).", _type.str()) - ); -} - -void AsmAnalyzer::expectType(YulName _expectedType, YulName _givenType, SourceLocation const& _location) -{ - if (_expectedType != _givenType) - m_errorReporter.typeError( - 3781_error, - _location, - fmt::format("Expected a value of type \"{}\" but got \"{}\".", _expectedType.str(), _givenType.str()) - ); -} - bool AsmAnalyzer::validateInstructions(std::string const& _instructionIdentifier, langutil::SourceLocation const& _location) { // NOTE: This function uses the default EVM version instead of the currently selected one. diff --git a/libyul/AsmAnalysis.h b/libyul/AsmAnalysis.h index d479a9970d71..d01ecc1901e6 100644 --- a/libyul/AsmAnalysis.h +++ b/libyul/AsmAnalysis.h @@ -84,13 +84,13 @@ class AsmAnalyzer std::set const& _qualifiedDataNames ); - std::vector operator()(Literal const& _literal); - std::vector operator()(Identifier const&); + size_t operator()(Literal const& _literal); + size_t operator()(Identifier const&); void operator()(ExpressionStatement const&); void operator()(Assignment const& _assignment); void operator()(VariableDeclaration const& _variableDeclaration); void operator()(FunctionDefinition const& _functionDefinition); - std::vector operator()(FunctionCall const& _functionCall); + size_t operator()(FunctionCall const& _functionCall); void operator()(If const& _if); void operator()(Switch const& _switch); void operator()(ForLoop const& _forLoop); @@ -104,20 +104,14 @@ class AsmAnalyzer private: /// Visits the expression, expects that it evaluates to exactly one value and /// returns the type. Reports errors on errors and returns the default type. - YulName expectExpression(Expression const& _expr); - YulName expectUnlimitedStringLiteral(Literal const& _literal); - /// Visits the expression and expects it to return a single boolean value. - /// Reports an error otherwise. - void expectBoolExpression(Expression const& _expr); + void expectExpression(Expression const& _expr); + void expectUnlimitedStringLiteral(Literal const& _literal); - /// Verifies that a variable to be assigned to exists, can be assigned to - /// and has the same type as the value. - void checkAssignment(Identifier const& _variable, YulName _valueType); + /// Verifies that a variable to be assigned to exists and can be assigned to. + void checkAssignment(Identifier const& _variable); Scope& scope(Block const* _block); void expectValidIdentifier(YulName _identifier, langutil::SourceLocation const& _location); - void expectValidType(YulName _type, langutil::SourceLocation const& _location); - void expectType(YulName _expectedType, YulName _givenType, langutil::SourceLocation const& _location); bool validateInstructions(evmasm::Instruction _instr, langutil::SourceLocation const& _location); bool validateInstructions(std::string const& _instrIdentifier, langutil::SourceLocation const& _location); diff --git a/libyul/AsmJsonConverter.cpp b/libyul/AsmJsonConverter.cpp index 60475497542a..d85b96f8f980 100644 --- a/libyul/AsmJsonConverter.cpp +++ b/libyul/AsmJsonConverter.cpp @@ -37,12 +37,12 @@ Json AsmJsonConverter::operator()(Block const& _node) const return ret; } -Json AsmJsonConverter::operator()(TypedName const& _node) const +Json AsmJsonConverter::operator()(NameWithDebugData const& _node) const { yulAssert(!_node.name.empty(), "Invalid variable name."); Json ret = createAstNode(originLocationOf(_node), nativeLocationOf(_node), "YulTypedName"); ret["name"] = _node.name.str(); - ret["type"] = _node.type.str(); + ret["type"] = ""; return ret; } @@ -63,7 +63,7 @@ Json AsmJsonConverter::operator()(Literal const& _node) const ret["hexValue"] = util::toHex(util::asBytes(formatLiteral(_node))); break; } - ret["type"] = _node.type.str(); + ret["type"] = ""; { auto const formattedLiteral = formatLiteral(_node); if (util::validateUTF8(formattedLiteral)) diff --git a/libyul/AsmJsonConverter.h b/libyul/AsmJsonConverter.h index 9c4b5d5e8ebc..523825830f46 100644 --- a/libyul/AsmJsonConverter.h +++ b/libyul/AsmJsonConverter.h @@ -44,7 +44,7 @@ class AsmJsonConverter: public boost::static_visitor explicit AsmJsonConverter(std::optional _sourceIndex): m_sourceIndex(_sourceIndex) {} Json operator()(Block const& _node) const; - Json operator()(TypedName const& _node) const; + Json operator()(NameWithDebugData const& _node) const; Json operator()(Literal const& _node) const; Json operator()(Identifier const& _node) const; Json operator()(Assignment const& _node) const; diff --git a/libyul/AsmJsonImporter.cpp b/libyul/AsmJsonImporter.cpp index 65ff22999b39..6de7bb6abc16 100644 --- a/libyul/AsmJsonImporter.cpp +++ b/libyul/AsmJsonImporter.cpp @@ -74,12 +74,11 @@ Json AsmJsonImporter::member(Json const& _node, std::string const& _name) return _node[_name]; } -TypedName AsmJsonImporter::createTypedName(Json const& _node) +NameWithDebugData AsmJsonImporter::createNameWithDebugData(Json const& _node) { - auto typedName = createAsmNode(_node); - typedName.type = YulName{member(_node, "type").get()}; - typedName.name = YulName{member(_node, "name").get()}; - return typedName; + auto nameWithDebugData = createAsmNode(_node); + nameWithDebugData.name = YulName{member(_node, "name").get()}; + return nameWithDebugData; } Statement AsmJsonImporter::createStatement(Json const& _node) @@ -176,7 +175,10 @@ Literal AsmJsonImporter::createLiteral(Json const& _node) value = util::asString(util::fromHex(member(_node, "hexValue").get())); else value = member(_node, "value").get(); - lit.type = YulName{member(_node, "type").get()}; + { + auto const typeNode = member(_node, "type"); + yulAssert(typeNode.empty() || typeNode.get().empty()); + } if (kind == "number") { langutil::CharStream charStream(value, ""); @@ -263,7 +265,7 @@ VariableDeclaration AsmJsonImporter::createVariableDeclaration(Json const& _node { auto varDec = createAsmNode(_node); for (auto const& var: member(_node, "variables")) - varDec.variables.emplace_back(createTypedName(var)); + varDec.variables.emplace_back(createNameWithDebugData(var)); if (_node.contains("value")) varDec.value = std::make_unique(createExpression(member(_node, "value"))); @@ -278,11 +280,11 @@ FunctionDefinition AsmJsonImporter::createFunctionDefinition(Json const& _node) if (_node.contains("parameters")) for (auto const& var: member(_node, "parameters")) - funcDef.parameters.emplace_back(createTypedName(var)); + funcDef.parameters.emplace_back(createNameWithDebugData(var)); if (_node.contains("returnVariables")) for (auto const& var: member(_node, "returnVariables")) - funcDef.returnVariables.emplace_back(createTypedName(var)); + funcDef.returnVariables.emplace_back(createNameWithDebugData(var)); funcDef.body = createBlock(member(_node, "body")); return funcDef; diff --git a/libyul/AsmJsonImporter.h b/libyul/AsmJsonImporter.h index d835e99e39a3..f3df8c178e9d 100644 --- a/libyul/AsmJsonImporter.h +++ b/libyul/AsmJsonImporter.h @@ -57,7 +57,7 @@ class AsmJsonImporter std::vector createStatementVector(Json const& _array); std::vector createExpressionVector(Json const& _array); - yul::TypedName createTypedName(Json const& _node); + yul::NameWithDebugData createNameWithDebugData(Json const& _node); yul::Literal createLiteral(Json const& _node); yul::Leave createLeave(Json const& _node); yul::Identifier createIdentifier(Json const& _node); diff --git a/libyul/AsmParser.cpp b/libyul/AsmParser.cpp index a2a4c36dc056..bd890c4aaa06 100644 --- a/libyul/AsmParser.cpp +++ b/libyul/AsmParser.cpp @@ -567,18 +567,20 @@ std::variant Parser::parseLiteralOrIdentifier(bool _unlimit break; } + auto const beginOfLiteralLoc = currentLocation(); Literal literal{ createDebugData(), kind, - valueOfLiteral(currentLiteral(), kind, _unlimitedLiteralArgument && kind == LiteralKind::String), - {} + valueOfLiteral(currentLiteral(), kind, _unlimitedLiteralArgument && kind == LiteralKind::String) }; advance(); if (currentToken() == Token::Colon) { expectToken(Token::Colon); updateLocationEndFrom(literal.debugData, currentLocation()); - literal.type = expectAsmIdentifier(); + auto const loc = SourceLocation::smallestCovering(beginOfLiteralLoc, currentLocation()); + std::ignore = expectAsmIdentifier(); + expectUntyped(loc); } return literal; @@ -599,7 +601,7 @@ VariableDeclaration Parser::parseVariableDeclaration() expectToken(Token::Let); while (true) { - varDecl.variables.emplace_back(parseTypedName()); + varDecl.variables.emplace_back(parseNameWithDebugData()); if (currentToken() == Token::Comma) expectToken(Token::Comma); else @@ -637,7 +639,7 @@ FunctionDefinition Parser::parseFunctionDefinition() expectToken(Token::LParen); while (currentToken() != Token::RParen) { - funDef.parameters.emplace_back(parseTypedName()); + funDef.parameters.emplace_back(parseNameWithDebugData()); if (currentToken() == Token::RParen) break; expectToken(Token::Comma); @@ -648,7 +650,7 @@ FunctionDefinition Parser::parseFunctionDefinition() expectToken(Token::RightArrow); while (true) { - funDef.returnVariables.emplace_back(parseTypedName()); + funDef.returnVariables.emplace_back(parseNameWithDebugData()); if (currentToken() == Token::LBrace) break; expectToken(Token::Comma); @@ -695,19 +697,20 @@ FunctionCall Parser::parseCall(std::variant&& _initialOp) return ret; } -TypedName Parser::parseTypedName() +NameWithDebugData Parser::parseNameWithDebugData() { RecursionGuard recursionGuard(*this); - TypedName typedName = createWithDebugData(); + NameWithDebugData typedName = createWithDebugData(); + auto const locNameStart = currentLocation(); typedName.name = expectAsmIdentifier(); if (currentToken() == Token::Colon) { expectToken(Token::Colon); updateLocationEndFrom(typedName.debugData, currentLocation()); - typedName.type = expectAsmIdentifier(); + auto const loc = SourceLocation::smallestCovering(locNameStart, currentLocation()); + std::ignore = expectAsmIdentifier(); + expectUntyped(loc); } - else - typedName.type = {}; return typedName; } @@ -756,3 +759,8 @@ bool Parser::isValidNumberLiteral(std::string const& _literal) else return _literal.find_first_not_of("0123456789") == std::string::npos; } + +void Parser::expectUntyped(SourceLocation const& loc) +{ + m_errorReporter.parserError(5473_error, loc, "Types are not valid in untyped Yul."); +} diff --git a/libyul/AsmParser.h b/libyul/AsmParser.h index dd206b5b1ee8..42ed2ca84d9c 100644 --- a/libyul/AsmParser.h +++ b/libyul/AsmParser.h @@ -145,8 +145,9 @@ class Parser: public langutil::ParserBase VariableDeclaration parseVariableDeclaration(); FunctionDefinition parseFunctionDefinition(); FunctionCall parseCall(std::variant&& _initialOp); - TypedName parseTypedName(); + NameWithDebugData parseNameWithDebugData(); YulName expectAsmIdentifier(); + void expectUntyped(langutil::SourceLocation const& loc); /// Reports an error if we are currently not inside the body part of a for loop. void checkBreakContinuePosition(std::string const& _which); diff --git a/libyul/AsmPrinter.cpp b/libyul/AsmPrinter.cpp index 612cb8ee0f75..5841fdfd3249 100644 --- a/libyul/AsmPrinter.cpp +++ b/libyul/AsmPrinter.cpp @@ -24,7 +24,6 @@ #include #include #include -#include #include #include @@ -54,12 +53,12 @@ std::string AsmPrinter::operator()(Literal const& _literal) { case LiteralKind::Number: case LiteralKind::Boolean: - return locationComment + formattedValue + appendTypeName(_literal.type); + return locationComment + formattedValue; case LiteralKind::String: break; } - return locationComment + escapeAndQuoteString(formattedValue) + appendTypeName(_literal.type); + return locationComment + escapeAndQuoteString(formattedValue); } std::string AsmPrinter::operator()(Identifier const& _identifier) @@ -94,7 +93,7 @@ std::string AsmPrinter::operator()(VariableDeclaration const& _variableDeclarati out += "let "; out += boost::algorithm::join( _variableDeclaration.variables | ranges::views::transform( - [this](TypedName argument) { return formatTypedName(argument); } + [this](NameWithDebugData argument) { return formatNameWithDebugData(argument); } ), ", " ); @@ -114,7 +113,7 @@ std::string AsmPrinter::operator()(FunctionDefinition const& _functionDefinition out += "function " + _functionDefinition.name.str() + "("; out += boost::algorithm::join( _functionDefinition.parameters | ranges::views::transform( - [this](TypedName argument) { return formatTypedName(argument); } + [this](NameWithDebugData argument) { return formatNameWithDebugData(argument); } ), ", " ); @@ -124,7 +123,7 @@ std::string AsmPrinter::operator()(FunctionDefinition const& _functionDefinition out += " -> "; out += boost::algorithm::join( _functionDefinition.returnVariables | ranges::views::transform( - [this](TypedName argument) { return formatTypedName(argument); } + [this](NameWithDebugData argument) { return formatNameWithDebugData(argument); } ), ", " ); @@ -236,18 +235,10 @@ std::string AsmPrinter::operator()(Block const& _block) } } -std::string AsmPrinter::formatTypedName(TypedName _variable) +std::string AsmPrinter::formatNameWithDebugData(NameWithDebugData _variable) { yulAssert(!_variable.name.empty(), "Invalid variable name."); - return formatDebugData(_variable) + _variable.name.str() + appendTypeName(_variable.type); -} - -std::string AsmPrinter::appendTypeName(YulName _type) const -{ - if (_type.empty()) - return {}; - else - return ":" + _type.str(); + return formatDebugData(_variable) + _variable.name.str(); } std::string AsmPrinter::formatSourceLocation( diff --git a/libyul/AsmPrinter.h b/libyul/AsmPrinter.h index 05b6fb9d8f1e..cc17c6a04ce3 100644 --- a/libyul/AsmPrinter.h +++ b/libyul/AsmPrinter.h @@ -36,12 +36,10 @@ namespace solidity::yul { -struct Dialect; /** * Converts a parsed Yul AST into readable string representation. * Ignores source locations. - * If a dialect is provided, the dialect's default type is omitted. */ class AsmPrinter { @@ -82,8 +80,7 @@ class AsmPrinter ); private: - std::string formatTypedName(TypedName _variable); - std::string appendTypeName(YulName _type) const; + std::string formatNameWithDebugData(NameWithDebugData _variable); std::string formatDebugData(langutil::DebugData::ConstPtr const& _debugData, bool _statement); template std::string formatDebugData(T const& _node) diff --git a/libyul/CMakeLists.txt b/libyul/CMakeLists.txt index dbf3bfdcd6a1..d38d5f27004d 100644 --- a/libyul/CMakeLists.txt +++ b/libyul/CMakeLists.txt @@ -177,8 +177,6 @@ add_library(yul optimiser/Suite.h optimiser/SyntacticalEquality.cpp optimiser/SyntacticalEquality.h - optimiser/TypeInfo.cpp - optimiser/TypeInfo.h optimiser/UnusedFunctionParameterPruner.cpp optimiser/UnusedFunctionParameterPruner.h optimiser/UnusedFunctionsCommon.h diff --git a/libyul/Dialect.cpp b/libyul/Dialect.cpp index be6c6705ee61..06a53ea5f74b 100644 --- a/libyul/Dialect.cpp +++ b/libyul/Dialect.cpp @@ -27,5 +27,5 @@ using namespace solidity::langutil; Literal Dialect::zeroLiteral() const { - return {DebugData::create(), LiteralKind::Number, LiteralValue(0, std::nullopt), {}}; + return {DebugData::create(), LiteralKind::Number, LiteralValue(0, std::nullopt)}; } diff --git a/libyul/Scope.cpp b/libyul/Scope.cpp index 89bdfc674c56..a73b2f9fd07e 100644 --- a/libyul/Scope.cpp +++ b/libyul/Scope.cpp @@ -25,22 +25,21 @@ using namespace solidity; using namespace solidity::yul; using namespace solidity::util; -bool Scope::registerVariable(YulName _name, YulType const& _type) +bool Scope::registerVariable(YulName _name) { if (exists(_name)) return false; Variable variable; - variable.type = _type; variable.name = _name; identifiers[_name] = variable; return true; } -bool Scope::registerFunction(YulName _name, std::vector _arguments, std::vector _returns) +bool Scope::registerFunction(YulName _name, size_t _numArguments, size_t _numReturns) { if (exists(_name)) return false; - identifiers[_name] = Function{std::move(_arguments), std::move(_returns), _name}; + identifiers[_name] = Function{_numArguments, _numReturns, _name}; return true; } diff --git a/libyul/Scope.h b/libyul/Scope.h index 027597290063..20850cc56f09 100644 --- a/libyul/Scope.h +++ b/libyul/Scope.h @@ -35,27 +35,24 @@ namespace solidity::yul struct Scope { - using YulType = YulName; - struct Variable { - YulType type; YulName name; }; struct Function { - std::vector arguments; - std::vector returns; + size_t numArguments; + size_t numReturns; YulName name; }; using Identifier = std::variant; - bool registerVariable(YulName _name, YulType const& _type); + bool registerVariable(YulName _name); bool registerFunction( YulName _name, - std::vector _arguments, - std::vector _returns + size_t _numArguments, + size_t _numReturns ); /// Looks up the identifier in this or super scopes and returns a valid pointer if found diff --git a/libyul/ScopeFiller.cpp b/libyul/ScopeFiller.cpp index 22c0d17e3289..7d65a2e95519 100644 --- a/libyul/ScopeFiller.cpp +++ b/libyul/ScopeFiller.cpp @@ -133,9 +133,9 @@ bool ScopeFiller::operator()(Block const& _block) return success; } -bool ScopeFiller::registerVariable(TypedName const& _name, SourceLocation const& _location, Scope& _scope) +bool ScopeFiller::registerVariable(NameWithDebugData const& _name, SourceLocation const& _location, Scope& _scope) { - if (!_scope.registerVariable(_name.name, _name.type)) + if (!_scope.registerVariable(_name.name)) { //@TODO secondary location m_errorReporter.declarationError( @@ -150,13 +150,7 @@ bool ScopeFiller::registerVariable(TypedName const& _name, SourceLocation const& bool ScopeFiller::registerFunction(FunctionDefinition const& _funDef) { - std::vector parameters; - for (auto const& parameter: _funDef.parameters) - parameters.emplace_back(parameter.type); - std::vector returns; - for (auto const& returnVariable: _funDef.returnVariables) - returns.emplace_back(returnVariable.type); - if (!m_currentScope->registerFunction(_funDef.name, std::move(parameters), std::move(returns))) + if (!m_currentScope->registerFunction(_funDef.name, _funDef.parameters.size(), _funDef.returnVariables.size())) { //@TODO secondary location m_errorReporter.declarationError( diff --git a/libyul/ScopeFiller.h b/libyul/ScopeFiller.h index b43910874337..7a4834a483a5 100644 --- a/libyul/ScopeFiller.h +++ b/libyul/ScopeFiller.h @@ -35,7 +35,7 @@ struct SourceLocation; namespace solidity::yul { -struct TypedName; +struct NameWithDebugData; struct Scope; struct AsmAnalysisInfo; @@ -65,7 +65,7 @@ class ScopeFiller private: bool registerVariable( - TypedName const& _name, + NameWithDebugData const& _name, langutil::SourceLocation const& _location, Scope& _scope ); diff --git a/libyul/Utilities.cpp b/libyul/Utilities.cpp index 6a78441cba2a..4bbfb42437b0 100644 --- a/libyul/Utilities.cpp +++ b/libyul/Utilities.cpp @@ -219,8 +219,8 @@ bool solidity::yul::validBoolLiteral(solidity::yul::Literal const& _literal) template<> bool Less::operator()(Literal const& _lhs, Literal const& _rhs) const { - if (std::make_tuple(_lhs.kind, _lhs.type) != std::make_tuple(_rhs.kind, _rhs.type)) - return std::make_tuple(_lhs.kind, _lhs.type) < std::make_tuple(_rhs.kind, _rhs.type); + if (_lhs.kind != _rhs.kind) + return _lhs.kind < _rhs.kind; if (_lhs.value.unlimited() && _rhs.value.unlimited()) yulAssert( diff --git a/libyul/backends/evm/ConstantOptimiser.cpp b/libyul/backends/evm/ConstantOptimiser.cpp index 2ab77f84e92d..1bb23cbc9282 100644 --- a/libyul/backends/evm/ConstantOptimiser.cpp +++ b/libyul/backends/evm/ConstantOptimiser.cpp @@ -179,7 +179,7 @@ Representation const& RepresentationFinder::findRepresentation(u256 const& _valu Representation RepresentationFinder::represent(u256 const& _value) const { Representation repr; - repr.expression = std::make_unique(Literal{m_debugData, LiteralKind::Number, LiteralValue{_value, formatNumber(_value)}, {}}); + repr.expression = std::make_unique(Literal{m_debugData, LiteralKind::Number, LiteralValue{_value, formatNumber(_value)}}); repr.cost = m_meter.costs(*repr.expression); return repr; } diff --git a/libyul/backends/evm/ControlFlowGraphBuilder.cpp b/libyul/backends/evm/ControlFlowGraphBuilder.cpp index 3007566dd50f..596c6c961966 100644 --- a/libyul/backends/evm/ControlFlowGraphBuilder.cpp +++ b/libyul/backends/evm/ControlFlowGraphBuilder.cpp @@ -268,7 +268,7 @@ StackSlot ControlFlowGraphBuilder::operator()(FunctionCall const& _call) void ControlFlowGraphBuilder::operator()(VariableDeclaration const& _varDecl) { yulAssert(m_currentBlock, ""); - auto declaredVariables = _varDecl.variables | ranges::views::transform([&](TypedName const& _var) { + auto declaredVariables = _varDecl.variables | ranges::views::transform([&](NameWithDebugData const& _var) { return VariableSlot{lookupVariable(_var.name), _var.debugData}; }) | ranges::to>; Stack input; @@ -337,7 +337,7 @@ void ControlFlowGraphBuilder::operator()(Switch const& _switch) auto ghostVariableId = m_graph.ghostVariables.size(); YulName ghostVariableName("GHOST[" + std::to_string(ghostVariableId) + "]"); - auto& ghostVar = m_graph.ghostVariables.emplace_back(Scope::Variable{""_yulname, ghostVariableName}); + auto& ghostVar = m_graph.ghostVariables.emplace_back(Scope::Variable{ghostVariableName}); // Artificially generate: // let := @@ -548,7 +548,7 @@ Stack const& ControlFlowGraphBuilder::visitFunctionCall(FunctionCall const& _cal // input std::move(inputs), // output - ranges::views::iota(0u, function.returns.size()) | ranges::views::transform([&](size_t _i) { + ranges::views::iota(0u, function.numReturns) | ranges::views::transform([&](size_t _i) { return TemporarySlot{_call, _i}; }) | ranges::to, // operation diff --git a/libyul/backends/evm/EVMCodeTransform.cpp b/libyul/backends/evm/EVMCodeTransform.cpp index 71872a4e8c57..694639565421 100644 --- a/libyul/backends/evm/EVMCodeTransform.cpp +++ b/libyul/backends/evm/EVMCodeTransform.cpp @@ -56,7 +56,7 @@ CodeTransform::CodeTransform( ExternalIdentifierAccess::CodeGenerator _identifierAccessCodeGen, UseNamedLabels _useNamedLabelsForFunctions, std::shared_ptr _context, - std::vector _delayedReturnVariables, + std::vector _delayedReturnVariables, std::optional _functionExitLabel ): m_assembly(_assembly), @@ -249,13 +249,13 @@ void CodeTransform::operator()(FunctionCall const& _call) [&](Scope::Function& _function) { function = &_function; } }), "Function name not found."); yulAssert(function, ""); - yulAssert(function->arguments.size() == _call.arguments.size(), ""); + yulAssert(function->numArguments == _call.arguments.size(), ""); for (auto const& arg: _call.arguments | ranges::views::reverse) visitExpression(arg); m_assembly.setSourceLocation(originLocationOf(_call)); m_assembly.appendJumpTo( functionEntryID(*function), - static_cast(function->returns.size()) - static_cast(function->arguments.size()) - 1, + static_cast(function->numReturns) - static_cast(function->numArguments) - 1, AbstractAssembly::JumpType::IntoFunction ); m_assembly.appendLabel(returnLabel); @@ -646,10 +646,10 @@ void CodeTransform::setupReturnVariablesAndFunctionExit() } // Allocate slots for return variables as if they were declared as variables in the virtual function scope. - for (TypedName const& var: m_delayedReturnVariables) + for (NameWithDebugData const& var: m_delayedReturnVariables) (*this)(VariableDeclaration{var.debugData, {var}, {}}); - m_functionExitStackHeight = ranges::max(m_delayedReturnVariables | ranges::views::transform([&](TypedName const& _name) { + m_functionExitStackHeight = ranges::max(m_delayedReturnVariables | ranges::views::transform([&](NameWithDebugData const& _name) { return variableStackHeight(_name.name); })) + 1; m_delayedReturnVariables.clear(); @@ -658,7 +658,7 @@ void CodeTransform::setupReturnVariablesAndFunctionExit() namespace { -bool statementNeedsReturnVariableSetup(Statement const& _statement, std::vector const& _returnVariables) +bool statementNeedsReturnVariableSetup(Statement const& _statement, std::vector const& _returnVariables) { if (std::holds_alternative(_statement)) return true; @@ -668,7 +668,7 @@ bool statementNeedsReturnVariableSetup(Statement const& _statement, std::vector< ) { std::map references = VariableReferencesCounter::countReferences(_statement); - auto isReferenced = [&references](TypedName const& _returnVariable) { + auto isReferenced = [&references](NameWithDebugData const& _returnVariable) { return references.count(_returnVariable.name); }; if (ranges::none_of(_returnVariables, isReferenced)) diff --git a/libyul/backends/evm/EVMCodeTransform.h b/libyul/backends/evm/EVMCodeTransform.h index 0e6a9d8be1db..c0bbac81b35e 100644 --- a/libyul/backends/evm/EVMCodeTransform.h +++ b/libyul/backends/evm/EVMCodeTransform.h @@ -114,7 +114,7 @@ class CodeTransform ExternalIdentifierAccess::CodeGenerator _identifierAccessCodeGen, UseNamedLabels _useNamedLabelsForFunctions, std::shared_ptr _context, - std::vector _delayedReturnVariables, + std::vector _delayedReturnVariables, std::optional _functionExitLabel ); @@ -209,7 +209,7 @@ class CodeTransform std::set m_unusedStackSlots; /// A list of return variables for which no stack slots have been assigned yet. - std::vector m_delayedReturnVariables; + std::vector m_delayedReturnVariables; /// Function exit label. Used as jump target for ``leave``. std::optional m_functionExitLabel; diff --git a/libyul/backends/evm/OptimizedEVMCodeTransform.cpp b/libyul/backends/evm/OptimizedEVMCodeTransform.cpp index 7690cf27ca06..6395ea64aeb0 100644 --- a/libyul/backends/evm/OptimizedEVMCodeTransform.cpp +++ b/libyul/backends/evm/OptimizedEVMCodeTransform.cpp @@ -70,7 +70,7 @@ void OptimizedEVMCodeTransform::operator()(CFG::FunctionCall const& _call) // Validate stack. { yulAssert(m_assembly.stackHeight() == static_cast(m_stack.size()), ""); - yulAssert(m_stack.size() >= _call.function.get().arguments.size() + (_call.canContinue ? 1 : 0), ""); + yulAssert(m_stack.size() >= _call.function.get().numArguments + (_call.canContinue ? 1 : 0), ""); // Assert that we got the correct arguments on stack for the call. for (auto&& [arg, slot]: ranges::zip_view( _call.functionCall.get().arguments | ranges::views::reverse, @@ -92,7 +92,7 @@ void OptimizedEVMCodeTransform::operator()(CFG::FunctionCall const& _call) m_assembly.setSourceLocation(originLocationOf(_call)); m_assembly.appendJumpTo( getFunctionLabel(_call.function), - static_cast(_call.function.get().returns.size()) - static_cast(_call.function.get().arguments.size()) - (_call.canContinue ? 1 : 0), + static_cast(_call.function.get().numReturns) - static_cast(_call.function.get().numArguments) - (_call.canContinue ? 1 : 0), AbstractAssembly::JumpType::IntoFunction ); if (_call.canContinue) @@ -102,10 +102,10 @@ void OptimizedEVMCodeTransform::operator()(CFG::FunctionCall const& _call) // Update stack. { // Remove arguments and return label from m_stack. - for (size_t i = 0; i < _call.function.get().arguments.size() + (_call.canContinue ? 1 : 0); ++i) + for (size_t i = 0; i < _call.function.get().numArguments + (_call.canContinue ? 1 : 0); ++i) m_stack.pop_back(); // Push return values to m_stack. - for (size_t index: ranges::views::iota(0u, _call.function.get().returns.size())) + for (size_t index: ranges::views::iota(0u, _call.function.get().numReturns)) m_stack.emplace_back(TemporarySlot{_call.functionCall, index}); yulAssert(m_assembly.stackHeight() == static_cast(m_stack.size()), ""); } @@ -196,8 +196,8 @@ OptimizedEVMCodeTransform::OptimizedEVMCodeTransform( functionLabels[&functionInfo] = useNamedLabel ? m_assembly.namedLabel( function->name.str(), - function->arguments.size(), - function->returns.size(), + function->numArguments, + function->numReturns, functionInfo.debugData ? functionInfo.debugData->astID : std::nullopt ) : m_assembly.newLabelId(); diff --git a/libyul/optimiser/ASTCopier.cpp b/libyul/optimiser/ASTCopier.cpp index 8efe29613e93..269c7adeedff 100644 --- a/libyul/optimiser/ASTCopier.cpp +++ b/libyul/optimiser/ASTCopier.cpp @@ -163,9 +163,9 @@ Literal ASTCopier::translate(Literal const& _literal) return _literal; } -TypedName ASTCopier::translate(TypedName const& _typedName) +NameWithDebugData ASTCopier::translate(NameWithDebugData const& _typedName) { - return TypedName{_typedName.debugData, translateIdentifier(_typedName.name), _typedName.type}; + return NameWithDebugData{_typedName.debugData, translateIdentifier(_typedName.name)}; } YulName FunctionCopier::translateIdentifier(YulName _name) diff --git a/libyul/optimiser/ASTCopier.h b/libyul/optimiser/ASTCopier.h index 88d2a34510ad..04b1c96cd2e1 100644 --- a/libyul/optimiser/ASTCopier.h +++ b/libyul/optimiser/ASTCopier.h @@ -100,7 +100,7 @@ class ASTCopier: public ExpressionCopier, public StatementCopier Case translate(Case const& _case); virtual Identifier translate(Identifier const& _identifier); Literal translate(Literal const& _literal); - TypedName translate(TypedName const& _typedName); + NameWithDebugData translate(NameWithDebugData const& _typedName); virtual void enterScope(Block const&) { } virtual void leaveScope(Block const&) { } diff --git a/libyul/optimiser/BlockHasher.cpp b/libyul/optimiser/BlockHasher.cpp index 9d6db206675f..5470558ce93a 100644 --- a/libyul/optimiser/BlockHasher.cpp +++ b/libyul/optimiser/BlockHasher.cpp @@ -48,7 +48,6 @@ void ASTHasherBase::hashLiteral(solidity::yul::Literal const& _literal) hash64(std::hash{}(_literal.value.value())); else hash64(std::hash{}(_literal.value.builtinStringLiteralValue())); - hash64(_literal.type.hash()); hash8(_literal.value.unlimited()); } diff --git a/libyul/optimiser/ControlFlowSimplifier.cpp b/libyul/optimiser/ControlFlowSimplifier.cpp index 2bd505a1c8a2..c078885e8ba4 100644 --- a/libyul/optimiser/ControlFlowSimplifier.cpp +++ b/libyul/optimiser/ControlFlowSimplifier.cpp @@ -18,7 +18,6 @@ #include #include #include -#include #include #include #include diff --git a/libyul/optimiser/ControlFlowSimplifier.h b/libyul/optimiser/ControlFlowSimplifier.h index 0f0e725cd0ec..86ebf296c290 100644 --- a/libyul/optimiser/ControlFlowSimplifier.h +++ b/libyul/optimiser/ControlFlowSimplifier.h @@ -24,7 +24,6 @@ namespace solidity::yul { struct Dialect; struct OptimiserStepContext; -class TypeInfo; /** * Simplifies several control-flow structures: diff --git a/libyul/optimiser/DataFlowAnalyzer.h b/libyul/optimiser/DataFlowAnalyzer.h index 6b23a86b9c9d..5a4b199caefd 100644 --- a/libyul/optimiser/DataFlowAnalyzer.h +++ b/libyul/optimiser/DataFlowAnalyzer.h @@ -217,7 +217,7 @@ class DataFlowAnalyzer: public ASTModifier }; /// Special expression whose address will be used in m_value. /// YulName does not need to be reset because DataFlowAnalyzer is short-lived. - Expression const m_zero{Literal{{}, LiteralKind::Number, LiteralValue{0, "0"}, {}}}; + Expression const m_zero{Literal{{}, LiteralKind::Number, LiteralValue{0, std::nullopt}}}; /// List of scopes. std::vector m_variableScopes; }; diff --git a/libyul/optimiser/ExpressionSimplifier.cpp b/libyul/optimiser/ExpressionSimplifier.cpp index 482ade8f87d5..598d2e90037d 100644 --- a/libyul/optimiser/ExpressionSimplifier.cpp +++ b/libyul/optimiser/ExpressionSimplifier.cpp @@ -60,7 +60,7 @@ void ExpressionSimplifier::visit(Expression& _expression) !knownToBeZero(startArgument) && !std::holds_alternative(startArgument) ) - startArgument = Literal{debugDataOf(startArgument), LiteralKind::Number, LiteralValue{0, "0"}, {}}; + startArgument = Literal{debugDataOf(startArgument), LiteralKind::Number, LiteralValue{0, std::nullopt}}; } } diff --git a/libyul/optimiser/ExpressionSplitter.cpp b/libyul/optimiser/ExpressionSplitter.cpp index acaa40dbf0e1..9f9bf958f129 100644 --- a/libyul/optimiser/ExpressionSplitter.cpp +++ b/libyul/optimiser/ExpressionSplitter.cpp @@ -23,7 +23,6 @@ #include #include -#include #include #include @@ -37,8 +36,7 @@ using namespace solidity::langutil; void ExpressionSplitter::run(OptimiserStepContext& _context, Block& _ast) { - TypeInfo typeInfo(_context.dialect, _ast); - ExpressionSplitter{_context.dialect, _context.dispenser, typeInfo}(_ast); + ExpressionSplitter{_context.dialect, _context.dispenser}(_ast); } void ExpressionSplitter::operator()(FunctionCall& _funCall) @@ -100,13 +98,11 @@ void ExpressionSplitter::outlineExpression(Expression& _expr) langutil::DebugData::ConstPtr debugData = debugDataOf(_expr); YulName var = m_nameDispenser.newName({}); - YulName type = m_typeInfo.typeOf(_expr); m_statementsToPrefix.emplace_back(VariableDeclaration{ debugData, - {{TypedName{debugData, var, type}}}, + {{NameWithDebugData{debugData, var}}}, std::make_unique(std::move(_expr)) }); _expr = Identifier{debugData, var}; - m_typeInfo.setVariableType(var, type); } diff --git a/libyul/optimiser/ExpressionSplitter.h b/libyul/optimiser/ExpressionSplitter.h index bbde8d6a2df0..0b223e9859b2 100644 --- a/libyul/optimiser/ExpressionSplitter.h +++ b/libyul/optimiser/ExpressionSplitter.h @@ -33,7 +33,6 @@ namespace solidity::yul struct Dialect; struct OptimiserStepContext; -class TypeInfo; /** * Optimiser component that modifies an AST in place, turning complex @@ -71,12 +70,10 @@ class ExpressionSplitter: public ASTModifier private: explicit ExpressionSplitter( Dialect const& _dialect, - NameDispenser& _nameDispenser, - TypeInfo& _typeInfo + NameDispenser& _nameDispenser ): m_dialect(_dialect), - m_nameDispenser(_nameDispenser), - m_typeInfo(_typeInfo) + m_nameDispenser(_nameDispenser) { } /// Replaces the expression by a variable if it is a function call or functional @@ -89,7 +86,6 @@ class ExpressionSplitter: public ASTModifier std::vector m_statementsToPrefix; Dialect const& m_dialect; NameDispenser& m_nameDispenser; - TypeInfo& m_typeInfo; }; } diff --git a/libyul/optimiser/ForLoopConditionIntoBody.cpp b/libyul/optimiser/ForLoopConditionIntoBody.cpp index cc3f936d9441..d0839e765ee8 100644 --- a/libyul/optimiser/ForLoopConditionIntoBody.cpp +++ b/libyul/optimiser/ForLoopConditionIntoBody.cpp @@ -58,8 +58,7 @@ void ForLoopConditionIntoBody::operator()(ForLoop& _forLoop) Literal { debugData, LiteralKind::Boolean, - LiteralValue{true}, - {} + LiteralValue{true} } ); } diff --git a/libyul/optimiser/FullInliner.cpp b/libyul/optimiser/FullInliner.cpp index 3daaea658b80..2f138761fc66 100644 --- a/libyul/optimiser/FullInliner.cpp +++ b/libyul/optimiser/FullInliner.cpp @@ -298,10 +298,10 @@ std::vector InlineModifier::performInline(Statement& _statement, Func // helper function to create a new variable that is supposed to model // an existing variable. - auto newVariable = [&](TypedName const& _existingVariable, Expression* _value) { + auto newVariable = [&](NameWithDebugData const& _existingVariable, Expression* _value) { YulName newName = m_nameDispenser.newName(_existingVariable.name); variableReplacements[_existingVariable.name] = newName; - VariableDeclaration varDecl{_funCall.debugData, {{_funCall.debugData, newName, _existingVariable.type}}, {}}; + VariableDeclaration varDecl{_funCall.debugData, {{_funCall.debugData, newName}}, {}}; if (_value) varDecl.value = std::make_unique(std::move(*_value)); else diff --git a/libyul/optimiser/FunctionSpecializer.cpp b/libyul/optimiser/FunctionSpecializer.cpp index 49da50032dfe..cb7cd4164b03 100644 --- a/libyul/optimiser/FunctionSpecializer.cpp +++ b/libyul/optimiser/FunctionSpecializer.cpp @@ -104,7 +104,7 @@ FunctionDefinition FunctionSpecializer::specialize( missingVariableDeclarations.emplace_back( VariableDeclaration{ _f.debugData, - std::vector{newFunction.parameters[index]}, + std::vector{newFunction.parameters[index]}, std::make_unique(std::move(*argument)) } ); diff --git a/libyul/optimiser/LoadResolver.cpp b/libyul/optimiser/LoadResolver.cpp index 943860a0ad8d..98d938a3621e 100644 --- a/libyul/optimiser/LoadResolver.cpp +++ b/libyul/optimiser/LoadResolver.cpp @@ -125,8 +125,7 @@ void LoadResolver::tryEvaluateKeccak( {}, LiteralKind::Number, // a dummy 256-bit number to represent the Keccak256 hash. - LiteralValue{std::numeric_limits::max()}, - {} + LiteralValue{std::numeric_limits::max()} } ); @@ -150,8 +149,7 @@ void LoadResolver::tryEvaluateKeccak( _e = Literal{ debugDataOf(_e), LiteralKind::Number, - LiteralValue{contentHash}, - {} + LiteralValue{contentHash} }; } } diff --git a/libyul/optimiser/NameDisplacer.cpp b/libyul/optimiser/NameDisplacer.cpp index fd813fbfc2f1..c68d52f9a7bb 100644 --- a/libyul/optimiser/NameDisplacer.cpp +++ b/libyul/optimiser/NameDisplacer.cpp @@ -33,7 +33,7 @@ void NameDisplacer::operator()(Identifier& _identifier) void NameDisplacer::operator()(VariableDeclaration& _varDecl) { - for (TypedName& var: _varDecl.variables) + for (NameWithDebugData& var: _varDecl.variables) checkAndReplaceNew(var.name); ASTModifier::operator()(_varDecl); diff --git a/libyul/optimiser/NameSimplifier.cpp b/libyul/optimiser/NameSimplifier.cpp index f03a448f0d92..d57a61332e3e 100644 --- a/libyul/optimiser/NameSimplifier.cpp +++ b/libyul/optimiser/NameSimplifier.cpp @@ -53,9 +53,9 @@ void NameSimplifier::operator()(VariableDeclaration& _varDecl) ASTModifier::operator()(_varDecl); } -void NameSimplifier::renameVariables(std::vector& _variables) +void NameSimplifier::renameVariables(std::vector& _variables) { - for (TypedName& typedName: _variables) + for (NameWithDebugData& typedName: _variables) translate(typedName.name); } diff --git a/libyul/optimiser/NameSimplifier.h b/libyul/optimiser/NameSimplifier.h index 848e61f567ac..0ff5077cc694 100644 --- a/libyul/optimiser/NameSimplifier.h +++ b/libyul/optimiser/NameSimplifier.h @@ -60,7 +60,7 @@ class NameSimplifier: public ASTModifier NameSimplifier(OptimiserStepContext& _context, Block const& _ast); /// Tries to rename a list of variables. - void renameVariables(std::vector& _variables); + void renameVariables(std::vector& _variables); void findSimplification(YulName const& _name); void translate(YulName& _name); diff --git a/libyul/optimiser/SSATransform.cpp b/libyul/optimiser/SSATransform.cpp index 80abdf7e6516..1d5270f8f497 100644 --- a/libyul/optimiser/SSATransform.cpp +++ b/libyul/optimiser/SSATransform.cpp @@ -28,8 +28,6 @@ #include -#include - using namespace solidity; using namespace solidity::yul; using namespace solidity::langutil; @@ -46,12 +44,10 @@ class IntroduceSSA: public ASTModifier public: explicit IntroduceSSA( NameDispenser& _nameDispenser, - std::set const& _variablesToReplace, - TypeInfo& _typeInfo + std::set const& _variablesToReplace ): m_nameDispenser(_nameDispenser), - m_variablesToReplace(_variablesToReplace), - m_typeInfo(_typeInfo) + m_variablesToReplace(_variablesToReplace) { } void operator()(Block& _block) override; @@ -59,7 +55,6 @@ class IntroduceSSA: public ASTModifier private: NameDispenser& m_nameDispenser; std::set const& m_variablesToReplace; - TypeInfo const& m_typeInfo; }; @@ -87,15 +82,15 @@ void IntroduceSSA::operator()(Block& _block) langutil::DebugData::ConstPtr debugData = varDecl.debugData; std::vector statements; statements.emplace_back(VariableDeclaration{debugData, {}, std::move(varDecl.value)}); - TypedNameList newVariables; + NameWithDebugDataList newVariables; for (auto const& var: varDecl.variables) { YulName oldName = var.name; YulName newName = m_nameDispenser.newName(oldName); - newVariables.emplace_back(TypedName{debugData, newName, var.type}); + newVariables.emplace_back(NameWithDebugData{debugData, newName}); statements.emplace_back(VariableDeclaration{ debugData, - {TypedName{debugData, oldName, var.type}}, + {NameWithDebugData{debugData, oldName}}, std::make_unique(Identifier{debugData, newName}) }); } @@ -114,15 +109,12 @@ void IntroduceSSA::operator()(Block& _block) langutil::DebugData::ConstPtr debugData = assignment.debugData; std::vector statements; statements.emplace_back(VariableDeclaration{debugData, {}, std::move(assignment.value)}); - TypedNameList newVariables; + NameWithDebugDataList newVariables; for (auto const& var: assignment.variableNames) { YulName oldName = var.name; YulName newName = m_nameDispenser.newName(oldName); - newVariables.emplace_back(TypedName{debugData, - newName, - m_typeInfo.typeOfVariable(oldName) - }); + newVariables.emplace_back(NameWithDebugData{debugData, newName}); statements.emplace_back(Assignment{ debugData, {Identifier{debugData, oldName}}, @@ -148,12 +140,10 @@ class IntroduceControlFlowSSA: public ASTModifier public: explicit IntroduceControlFlowSSA( NameDispenser& _nameDispenser, - std::set const& _variablesToReplace, - TypeInfo const& _typeInfo + std::set const& _variablesToReplace ): m_nameDispenser(_nameDispenser), - m_variablesToReplace(_variablesToReplace), - m_typeInfo(_typeInfo) + m_variablesToReplace(_variablesToReplace) { } void operator()(FunctionDefinition& _function) override; @@ -168,7 +158,6 @@ class IntroduceControlFlowSSA: public ASTModifier std::set m_variablesInScope; /// Variables that do not have a specific value. util::UniqueVector m_variablesToReassign; - TypeInfo const& m_typeInfo; }; void IntroduceControlFlowSSA::operator()(FunctionDefinition& _function) @@ -232,7 +221,7 @@ void IntroduceControlFlowSSA::operator()(Block& _block) YulName newName = m_nameDispenser.newName(toReassign); toPrepend.emplace_back(VariableDeclaration{ debugDataOf(_s), - {TypedName{debugDataOf(_s), newName, m_typeInfo.typeOfVariable(toReassign)}}, + {NameWithDebugData{debugDataOf(_s), newName}}, std::make_unique(Identifier{debugDataOf(_s), toReassign}) }); assignedVariables.pushBack(toReassign); @@ -379,10 +368,9 @@ void PropagateValues::operator()(Block& _block) void SSATransform::run(OptimiserStepContext& _context, Block& _ast) { - TypeInfo typeInfo(_context.dialect, _ast); std::set assignedVariables = assignedVariableNames(_ast); - IntroduceSSA{_context.dispenser, assignedVariables, typeInfo}(_ast); - IntroduceControlFlowSSA{_context.dispenser, assignedVariables, typeInfo}(_ast); + IntroduceSSA{_context.dispenser, assignedVariables}(_ast); + IntroduceControlFlowSSA{_context.dispenser, assignedVariables}(_ast); PropagateValues{assignedVariables}(_ast); } diff --git a/libyul/optimiser/SSAValueTracker.h b/libyul/optimiser/SSAValueTracker.h index 0196ecc40e99..2448f99a84c4 100644 --- a/libyul/optimiser/SSAValueTracker.h +++ b/libyul/optimiser/SSAValueTracker.h @@ -57,7 +57,7 @@ class SSAValueTracker: public ASTWalker /// Special expression whose address will be used in m_values. /// YulName does not need to be reset because SSAValueTracker is short-lived. - Expression const m_zero{Literal{{}, LiteralKind::Number, LiteralValue(u256{0}), {}}}; + Expression const m_zero{Literal{{}, LiteralKind::Number, LiteralValue(u256{0})}}; std::map m_values; }; diff --git a/libyul/optimiser/SimplificationRules.cpp b/libyul/optimiser/SimplificationRules.cpp index 03e4ccdd0eda..72c0f70ca281 100644 --- a/libyul/optimiser/SimplificationRules.cpp +++ b/libyul/optimiser/SimplificationRules.cpp @@ -241,7 +241,7 @@ Expression Pattern::toExpression(langutil::DebugData::ConstPtr const& _debugData if (m_kind == PatternKind::Constant) { assertThrow(m_data, OptimizerException, "No match group and no constant value given."); - return Literal{_debugData, LiteralKind::Number, LiteralValue{*m_data, formatNumber(*m_data)}, {}}; + return Literal{_debugData, LiteralKind::Number, LiteralValue{*m_data, formatNumber(*m_data)}}; } else if (m_kind == PatternKind::Operation) { diff --git a/libyul/optimiser/StackLimitEvader.cpp b/libyul/optimiser/StackLimitEvader.cpp index 6e6da63e603b..d3cb6418fd30 100644 --- a/libyul/optimiser/StackLimitEvader.cpp +++ b/libyul/optimiser/StackLimitEvader.cpp @@ -77,7 +77,7 @@ struct MemoryOffsetAllocator size_t totalArgCount = functionDefinition->returnVariables.size() + functionDefinition->parameters.size(); totalArgCount > 16 ) - for (TypedName const& var: ranges::concat_view( + for (NameWithDebugData const& var: ranges::concat_view( functionDefinition->parameters, functionDefinition->returnVariables ) | ranges::views::take(totalArgCount - 16)) diff --git a/libyul/optimiser/StackToMemoryMover.cpp b/libyul/optimiser/StackToMemoryMover.cpp index d5cb539af477..7e3f93475f80 100644 --- a/libyul/optimiser/StackToMemoryMover.cpp +++ b/libyul/optimiser/StackToMemoryMover.cpp @@ -49,7 +49,7 @@ std::vector generateMemoryStore( _debugData, Identifier{_debugData, memoryStoreFunction->name}, { - Literal{_debugData, LiteralKind::Number, _mpos, {}}, + Literal{_debugData, LiteralKind::Number, _mpos}, std::move(_value) } }}); @@ -66,8 +66,7 @@ FunctionCall generateMemoryLoad(Dialect const& _dialect, langutil::DebugData::Co Literal{ _debugData, LiteralKind::Number, - _mpos, - {} + _mpos } } }; @@ -91,7 +90,7 @@ void StackToMemoryMover::run( util::mapTuple([](YulName _name, FunctionDefinition const* _funDef) { return make_pair(_name, _funDef->returnVariables); }), - std::map{} + std::map{} ) ); stackToMemoryMover(_block); @@ -101,7 +100,7 @@ void StackToMemoryMover::run( StackToMemoryMover::StackToMemoryMover( OptimiserStepContext& _context, VariableMemoryOffsetTracker const& _memoryOffsetTracker, - std::map _functionReturnVariables + std::map _functionReturnVariables ): m_context(_context), m_memoryOffsetTracker(_memoryOffsetTracker), @@ -124,7 +123,7 @@ void StackToMemoryMover::operator()(FunctionDefinition& _functionDefinition) std::vector memoryVariableInits; // All function parameters with a memory slot are moved at the beginning of the function body. - for (TypedName const& param: _functionDefinition.parameters) + for (NameWithDebugData const& param: _functionDefinition.parameters) if (auto slot = m_memoryOffsetTracker(param.name)) memoryVariableInits += generateMemoryStore( m_context.dialect, @@ -134,21 +133,21 @@ void StackToMemoryMover::operator()(FunctionDefinition& _functionDefinition) ); // All memory return variables have to be initialized to zero in memory. - for (TypedName const& returnVariable: _functionDefinition.returnVariables) + for (NameWithDebugData const& returnVariable: _functionDefinition.returnVariables) if (auto slot = m_memoryOffsetTracker(returnVariable.name)) memoryVariableInits += generateMemoryStore( m_context.dialect, returnVariable.debugData, *slot, - Literal{returnVariable.debugData, LiteralKind::Number, LiteralValue(u256{0}), {}} + Literal{returnVariable.debugData, LiteralKind::Number, LiteralValue(u256{0})} ); // Special case of a function with a single return argument that needs to move to memory. if (_functionDefinition.returnVariables.size() == 1 && m_memoryOffsetTracker(_functionDefinition.returnVariables.front().name)) { - TypedNameList stackParameters = _functionDefinition.parameters | ranges::views::filter( + NameWithDebugDataList stackParameters = _functionDefinition.parameters | ranges::views::filter( std::not_fn(m_memoryOffsetTracker) - ) | ranges::to; + ) | ranges::to; // Generate new function without return variable and with only the non-moved parameters. YulName newFunctionName = m_context.dispenser.newName(_functionDefinition.name); m_newFunctionDefinitions.emplace_back(FunctionDefinition{ @@ -160,7 +159,7 @@ void StackToMemoryMover::operator()(FunctionDefinition& _functionDefinition) }); // Generate new names for the arguments to maintain disambiguation. std::map newArgumentNames; - for (TypedName const& _var: stackParameters) + for (NameWithDebugData const& _var: stackParameters) newArgumentNames[_var.name] = m_context.dispenser.newName(_var.name); for (auto& parameter: _functionDefinition.parameters) parameter.name = util::valueOrDefault(newArgumentNames, parameter.name, parameter.name); @@ -171,7 +170,7 @@ void StackToMemoryMover::operator()(FunctionDefinition& _functionDefinition) FunctionCall{ _functionDefinition.debugData, Identifier{_functionDefinition.debugData, newFunctionName}, - stackParameters | ranges::views::transform([&](TypedName const& _arg) { + stackParameters | ranges::views::transform([&](NameWithDebugData const& _arg) { return Expression{Identifier{_arg.debugData, newArgumentNames.at(_arg.name)}}; }) | ranges::to> } @@ -193,7 +192,7 @@ void StackToMemoryMover::operator()(FunctionDefinition& _functionDefinition) _functionDefinition.returnVariables = _functionDefinition.returnVariables | ranges::views::filter( std::not_fn(m_memoryOffsetTracker) - ) | ranges::to; + ) | ranges::to; } void StackToMemoryMover::operator()(Block& _block) @@ -214,7 +213,7 @@ void StackToMemoryMover::operator()(Block& _block) m_context.dialect, debugData, *offset, - _stmt.value ? *std::move(_stmt.value) : Literal{debugData, LiteralKind::Number, LiteralValue(u256{0}), {}} + _stmt.value ? *std::move(_stmt.value) : Literal{debugData, LiteralKind::Number, LiteralValue(u256{0})} ); else return {}; @@ -256,7 +255,7 @@ void StackToMemoryMover::operator()(Block& _block) else { YulName tempVarName = m_nameDispenser.newName(lhsVar.name); - tempDecl.variables.emplace_back(TypedName{lhsVar.debugData, tempVarName, {}}); + tempDecl.variables.emplace_back(NameWithDebugData{lhsVar.debugData, tempVarName}); rhs = std::make_unique(Identifier{debugData, tempVarName}); } @@ -322,7 +321,7 @@ std::optional StackToMemoryMover::VariableMemoryOffsetTracker::ope return std::nullopt; } -std::optional StackToMemoryMover::VariableMemoryOffsetTracker::operator()(TypedName const& _variable) const +std::optional StackToMemoryMover::VariableMemoryOffsetTracker::operator()(NameWithDebugData const& _variable) const { return (*this)(_variable.name); } diff --git a/libyul/optimiser/StackToMemoryMover.h b/libyul/optimiser/StackToMemoryMover.h index 7392660311bf..89f11c1fe4f8 100644 --- a/libyul/optimiser/StackToMemoryMover.h +++ b/libyul/optimiser/StackToMemoryMover.h @@ -169,7 +169,7 @@ class StackToMemoryMover: ASTModifier std::optional operator()(YulName const& _variable) const; /// @returns a YulName containing the memory offset to be assigned to @a _variable as number literal /// or std::nullopt if the variable should not be moved. - std::optional operator()(TypedName const& _variable) const; + std::optional operator()(NameWithDebugData const& _variable) const; /// @returns a YulName containing the memory offset to be assigned to @a _variable as number literal /// or std::nullopt if the variable should not be moved. std::optional operator()(Identifier const& _variable) const; @@ -187,14 +187,14 @@ class StackToMemoryMover: ASTModifier StackToMemoryMover( OptimiserStepContext& _context, VariableMemoryOffsetTracker const& _memoryOffsetTracker, - std::map> _functionReturnVariables + std::map> _functionReturnVariables ); OptimiserStepContext& m_context; VariableMemoryOffsetTracker const& m_memoryOffsetTracker; NameDispenser& m_nameDispenser; /// Map from function names to the return variables of the function with that name. - std::map> m_functionReturnVariables; + std::map> m_functionReturnVariables; /// List of functions generated while running this step that are to be appended to the code in the end. std::list m_newFunctionDefinitions; }; diff --git a/libyul/optimiser/SyntacticalEquality.cpp b/libyul/optimiser/SyntacticalEquality.cpp index db562716a2ff..0f4aa6e337e1 100644 --- a/libyul/optimiser/SyntacticalEquality.cpp +++ b/libyul/optimiser/SyntacticalEquality.cpp @@ -67,9 +67,6 @@ bool SyntacticallyEqual::expressionEqual(Literal const& _lhs, Literal const& _rh yulAssert(validLiteral(_lhs), "Invalid lhs literal during syntactical equality check"); yulAssert(validLiteral(_rhs), "Invalid rhs literal during syntactical equality check"); - if (_lhs.type != _rhs.type) - return false; - return _lhs.value == _rhs.value; } @@ -93,14 +90,14 @@ bool SyntacticallyEqual::statementEqual(VariableDeclaration const& _lhs, Variabl // first visit expression, then variable declarations if (!compareUniquePtr(_lhs.value, _rhs.value)) return false; - return util::containerEqual(_lhs.variables, _rhs.variables, [this](TypedName const& _lhsVarName, TypedName const& _rhsVarName) -> bool { + return util::containerEqual(_lhs.variables, _rhs.variables, [this](NameWithDebugData const& _lhsVarName, NameWithDebugData const& _rhsVarName) -> bool { return this->visitDeclaration(_lhsVarName, _rhsVarName); }); } bool SyntacticallyEqual::statementEqual(FunctionDefinition const& _lhs, FunctionDefinition const& _rhs) { - auto compare = [this](TypedName const& _lhsVarName, TypedName const& _rhsVarName) -> bool { + auto compare = [this](NameWithDebugData const& _lhsVarName, NameWithDebugData const& _rhsVarName) -> bool { return this->visitDeclaration(_lhsVarName, _rhsVarName); }; // first visit parameter declarations, then body @@ -157,10 +154,8 @@ bool SyntacticallyEqual::statementEqual(Block const& _lhs, Block const& _rhs) }); } -bool SyntacticallyEqual::visitDeclaration(TypedName const& _lhs, TypedName const& _rhs) +bool SyntacticallyEqual::visitDeclaration(NameWithDebugData const& _lhs, NameWithDebugData const& _rhs) { - if (_lhs.type != _rhs.type) - return false; std::size_t id = m_idsUsed++; m_identifiersLHS[_lhs.name] = id; m_identifiersRHS[_rhs.name] = id; diff --git a/libyul/optimiser/SyntacticalEquality.h b/libyul/optimiser/SyntacticalEquality.h index 0665a5efbe6e..1fd888f7af8c 100644 --- a/libyul/optimiser/SyntacticalEquality.h +++ b/libyul/optimiser/SyntacticalEquality.h @@ -63,7 +63,7 @@ class SyntacticallyEqual bool statementEqual(Leave const&, Leave const&) { return true; } bool statementEqual(Block const& _lhs, Block const& _rhs); private: - bool visitDeclaration(TypedName const& _lhs, TypedName const& _rhs); + bool visitDeclaration(NameWithDebugData const& _lhs, NameWithDebugData const& _rhs); template bool expressionEqual(U const&, V const&, std::enable_if_t::value>* = nullptr) diff --git a/libyul/optimiser/TypeInfo.cpp b/libyul/optimiser/TypeInfo.cpp deleted file mode 100644 index 754c0bad08f8..000000000000 --- a/libyul/optimiser/TypeInfo.cpp +++ /dev/null @@ -1,103 +0,0 @@ -/* - This file is part of solidity. - - solidity is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - solidity is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with solidity. If not, see . -*/ -// SPDX-License-Identifier: GPL-3.0 -/** - * Helper class that keeps track of the types while performing optimizations. - */ - -#include - -#include - -#include -#include - -#include - -using namespace solidity::yul; -using namespace solidity::util; - -class TypeInfo::TypeCollector: public ASTWalker -{ -public: - explicit TypeCollector(Block const& _block) - { - (*this)(_block); - } - - using ASTWalker::operator(); - void operator()(VariableDeclaration const& _varDecl) override - { - for (auto const& var: _varDecl.variables) - variableTypes[var.name] = var.type; - } - void operator()(FunctionDefinition const& _funDef) override - { - ASTWalker::operator()(_funDef); - - auto& funType = functionTypes[_funDef.name]; - for (auto const& arg: _funDef.parameters) - { - funType.parameters.emplace_back(arg.type); - variableTypes[arg.name] = arg.type; - } - for (auto const& ret: _funDef.returnVariables) - { - funType.returns.emplace_back(ret.type); - variableTypes[ret.name] = ret.type; - } - } - - std::map variableTypes; - std::map functionTypes; -}; - - -TypeInfo::TypeInfo(Dialect const& _dialect, Block const& _ast): - m_dialect(_dialect) -{ - TypeCollector types(_ast); - m_functionTypes = std::move(types.functionTypes); - m_variableTypes = std::move(types.variableTypes); -} - -YulName TypeInfo::typeOf(Expression const& _expression) const -{ - return std::visit(GenericVisitor{ - [&](FunctionCall const& _funCall) { - YulName name = _funCall.functionName.name; - std::vector const* retTypes = nullptr; - if (BuiltinFunction const* fun = m_dialect.builtin(name)) - retTypes = &fun->returns; - else - retTypes = &m_functionTypes.at(name).returns; - yulAssert(retTypes && retTypes->size() == 1, "Call to typeOf for non-single-value expression."); - return retTypes->front(); - }, - [&](Identifier const& _identifier) { - return m_variableTypes.at(_identifier.name); - }, - [&](Literal const& _literal) { - return _literal.type; - } - }, _expression); -} - -YulName TypeInfo::typeOfVariable(YulName _name) const -{ - return m_variableTypes.at(_name); -} diff --git a/libyul/optimiser/TypeInfo.h b/libyul/optimiser/TypeInfo.h deleted file mode 100644 index 96c43875a638..000000000000 --- a/libyul/optimiser/TypeInfo.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - This file is part of solidity. - - solidity is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - solidity is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with solidity. If not, see . -*/ -// SPDX-License-Identifier: GPL-3.0 -/** - * Helper class that keeps track of the types while performing optimizations. - */ -#pragma once - -#include -#include - -#include -#include - -namespace solidity::yul -{ -struct Dialect; - -/** - * Helper class that keeps track of the types while performing optimizations. - * - * Only works on disambiguated sources! - */ -class TypeInfo -{ -public: - TypeInfo(Dialect const& _dialect, Block const& _ast); - - void setVariableType(YulName _name, YulName _type) { m_variableTypes[_name] = _type; } - - /// @returns the type of an expression that is assumed to return exactly one value. - YulName typeOf(Expression const& _expression) const; - - /// \returns the type of variable - YulName typeOfVariable(YulName _name) const; - -private: - class TypeCollector; - - struct FunctionType - { - std::vector parameters; - std::vector returns; - }; - - Dialect const& m_dialect; - std::map m_variableTypes; - std::map m_functionTypes; -}; - -} diff --git a/libyul/optimiser/UnusedFunctionsCommon.cpp b/libyul/optimiser/UnusedFunctionsCommon.cpp index bd38b33cafd9..a6333a786a5e 100644 --- a/libyul/optimiser/UnusedFunctionsCommon.cpp +++ b/libyul/optimiser/UnusedFunctionsCommon.cpp @@ -35,12 +35,11 @@ FunctionDefinition unusedFunctionsCommon::createLinkingFunction( NameDispenser& _nameDispenser ) { - auto generateTypedName = [&](TypedName t) + auto generateTypedName = [&](NameWithDebugData t) { - return TypedName{ + return NameWithDebugData{ t.debugData, - _nameDispenser.newName(t.name), - t.type + _nameDispenser.newName(t.name) }; }; diff --git a/libyul/optimiser/UnusedPruner.cpp b/libyul/optimiser/UnusedPruner.cpp index c71e8077b690..a3b6c0708b6a 100644 --- a/libyul/optimiser/UnusedPruner.cpp +++ b/libyul/optimiser/UnusedPruner.cpp @@ -92,7 +92,7 @@ void UnusedPruner::operator()(Block& _block) if (std::none_of( varDecl.variables.begin(), varDecl.variables.end(), - [&](TypedName const& _typedName) { return used(_typedName.name); } + [&](NameWithDebugData const& _typedName) { return used(_typedName.name); } )) { if (!varDecl.value) diff --git a/libyul/optimiser/UnusedStoreEliminator.cpp b/libyul/optimiser/UnusedStoreEliminator.cpp index d049f59a0262..c50ddac14412 100644 --- a/libyul/optimiser/UnusedStoreEliminator.cpp +++ b/libyul/optimiser/UnusedStoreEliminator.cpp @@ -61,9 +61,9 @@ void UnusedStoreEliminator::run(OptimiserStepContext& _context, Block& _ast) std::map values; for (auto const& [name, expression]: ssaValues.values()) values[name] = AssignedValue{expression, {}}; - Expression const zeroLiteral{Literal{{}, LiteralKind::Number, LiteralValue(u256{0}), {}}}; - Expression const oneLiteral{Literal{{}, LiteralKind::Number, LiteralValue(u256{1}), {}}}; - Expression const thirtyTwoLiteral{Literal{{}, LiteralKind::Number, LiteralValue(u256{32}), {}}}; + Expression const zeroLiteral{Literal{{}, LiteralKind::Number, LiteralValue(u256{0})}}; + Expression const oneLiteral{Literal{{}, LiteralKind::Number, LiteralValue(u256{1})}}; + Expression const thirtyTwoLiteral{Literal{{}, LiteralKind::Number, LiteralValue(u256{32})}}; values[YulName{zero}] = AssignedValue{&zeroLiteral, {}}; values[YulName{one}] = AssignedValue{&oneLiteral, {}}; values[YulName{thirtyTwo}] = AssignedValue{&thirtyTwoLiteral, {}}; diff --git a/libyul/optimiser/VarNameCleaner.cpp b/libyul/optimiser/VarNameCleaner.cpp index 041ebdeaab23..b3a34d283e7e 100644 --- a/libyul/optimiser/VarNameCleaner.cpp +++ b/libyul/optimiser/VarNameCleaner.cpp @@ -72,17 +72,17 @@ void VarNameCleaner::operator()(VariableDeclaration& _varDecl) ASTModifier::operator()(_varDecl); } -void VarNameCleaner::renameVariables(std::vector& _variables) +void VarNameCleaner::renameVariables(std::vector& _variables) { - for (TypedName& typedName: _variables) + for (NameWithDebugData& variable: _variables) { - auto newName = findCleanName(typedName.name); - if (newName != typedName.name) + auto newName = findCleanName(variable.name); + if (newName != variable.name) { - m_translatedNames[typedName.name] = newName; - typedName.name = newName; + m_translatedNames[variable.name] = newName; + variable.name = newName; } - m_usedNames.insert(typedName.name); + m_usedNames.insert(variable.name); } } diff --git a/libyul/optimiser/VarNameCleaner.h b/libyul/optimiser/VarNameCleaner.h index bfb6cfb53369..7f8bb842e9e1 100644 --- a/libyul/optimiser/VarNameCleaner.h +++ b/libyul/optimiser/VarNameCleaner.h @@ -68,7 +68,7 @@ class VarNameCleaner: public ASTModifier ); /// Tries to rename a list of variables. - void renameVariables(std::vector& _variables); + void renameVariables(std::vector& _variables); /// @returns suffix-stripped name, if a suffix was detected, none otherwise. YulName stripSuffix(YulName const& _name) const; diff --git a/test/libyul/StackShufflingTest.cpp b/test/libyul/StackShufflingTest.cpp index 2da445dd4557..40fdcc5b15f4 100644 --- a/test/libyul/StackShufflingTest.cpp +++ b/test/libyul/StackShufflingTest.cpp @@ -102,7 +102,7 @@ bool StackShufflingTest::parse(std::string const& _source) expectToken(Token::LBrack); scanner.next(); // read number of ghost variables as ghostVariableId std::string ghostVariableId = scanner.currentLiteral(); - Scope::Variable ghostVar = Scope::Variable{""_yulname, YulName(literal + "[" + ghostVariableId + "]")}; + Scope::Variable ghostVar = Scope::Variable{YulName(literal + "[" + ghostVariableId + "]")}; stack.emplace_back(VariableSlot{ m_variables.insert(std::make_pair(ghostVar.name, ghostVar)).first->second }); @@ -110,7 +110,7 @@ bool StackShufflingTest::parse(std::string const& _source) } else { - Scope::Variable var = Scope::Variable{""_yulname, YulName(literal)}; + Scope::Variable var = Scope::Variable{YulName(literal)}; stack.emplace_back(VariableSlot{ m_variables.insert( make_pair(literal, var) diff --git a/test/libyul/YulOptimizerTestCommon.cpp b/test/libyul/YulOptimizerTestCommon.cpp index bf374c21fcee..0f94f309dce4 100644 --- a/test/libyul/YulOptimizerTestCommon.cpp +++ b/test/libyul/YulOptimizerTestCommon.cpp @@ -454,9 +454,9 @@ YulOptimizerTestCommon::YulOptimizerTestCommon( { YulName originalFunctionName = m_currentFunction; m_currentFunction = _function.name; - for (TypedName const& _argument: _function.parameters) + for (NameWithDebugData const& _argument: _function.parameters) visitVariableName(_argument.name); - for (TypedName const& _argument: _function.returnVariables) + for (NameWithDebugData const& _argument: _function.returnVariables) visitVariableName(_argument.name); ASTWalker::operator()(_function); m_currentFunction = originalFunctionName; diff --git a/test/libyul/yulSyntaxTests/invalid_type.yul b/test/libyul/yulSyntaxTests/invalid_type.yul index f863816355c6..e9a4e30c95af 100644 --- a/test/libyul/yulSyntaxTests/invalid_type.yul +++ b/test/libyul/yulSyntaxTests/invalid_type.yul @@ -2,4 +2,4 @@ let x: invalidType } // ---- -// TypeError 5473: (10-24): "invalidType" is not a valid type (user defined types are not yet supported). +// ParserError 5473: (10-24): Types are not valid in untyped Yul. diff --git a/test/libyul/yulSyntaxTests/invalid_type2.yul b/test/libyul/yulSyntaxTests/invalid_type2.yul index af30bc2eb244..5eb514866f00 100644 --- a/test/libyul/yulSyntaxTests/invalid_type2.yul +++ b/test/libyul/yulSyntaxTests/invalid_type2.yul @@ -2,5 +2,4 @@ let x := 1:invalidType } // ---- -// TypeError 5473: (15-28): "invalidType" is not a valid type (user defined types are not yet supported). -// TypeError 3947: (10-11): Assigning value of type "invalidType" to variable of type "". +// ParserError 5473: (15-28): Types are not valid in untyped Yul. diff --git a/test/libyul/yulSyntaxTests/invalid_type3.yul b/test/libyul/yulSyntaxTests/invalid_type3.yul index 6fc0e35e8ce0..9814527b0cc1 100644 --- a/test/libyul/yulSyntaxTests/invalid_type3.yul +++ b/test/libyul/yulSyntaxTests/invalid_type3.yul @@ -2,5 +2,5 @@ function f(a: invalidType) -> b: invalidType {} } // ---- -// TypeError 5473: (17-31): "invalidType" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (36-50): "invalidType" is not a valid type (user defined types are not yet supported). +// ParserError 5473: (17-31): Types are not valid in untyped Yul. +// ParserError 5473: (36-50): Types are not valid in untyped Yul. diff --git a/test/libyul/yulSyntaxTests/invalid_type4.yul b/test/libyul/yulSyntaxTests/invalid_type4.yul index 90f00ddaafd2..4924a592a75e 100644 --- a/test/libyul/yulSyntaxTests/invalid_type4.yul +++ b/test/libyul/yulSyntaxTests/invalid_type4.yul @@ -3,5 +3,4 @@ case 8: invalidType {} } // ---- -// TypeError 3781: (24-38): Expected a value of type "" but got "invalidType". -// TypeError 5473: (24-38): "invalidType" is not a valid type (user defined types are not yet supported). +// ParserError 5473: (24-38): Types are not valid in untyped Yul. diff --git a/test/libyul/yulSyntaxTests/literal_invalid_type.yul b/test/libyul/yulSyntaxTests/literal_invalid_type.yul index fd612a0a5a18..10a280120eb2 100644 --- a/test/libyul/yulSyntaxTests/literal_invalid_type.yul +++ b/test/libyul/yulSyntaxTests/literal_invalid_type.yul @@ -2,6 +2,4 @@ let x := true:unhappy } // ---- -// TypeError 5473: (15-27): "unhappy" is not a valid type (user defined types are not yet supported). -// TypeError 5170: (15-27): Invalid type "unhappy" for literal "true". -// TypeError 3947: (10-11): Assigning value of type "unhappy" to variable of type "". +// ParserError 5473: (15-27): Types are not valid in untyped Yul. diff --git a/test/libyul/yulSyntaxTests/more_than_256_analysis_errors.yul b/test/libyul/yulSyntaxTests/more_than_256_analysis_errors.yul index 0ae2fb15a730..edd7871a7efb 100644 --- a/test/libyul/yulSyntaxTests/more_than_256_analysis_errors.yul +++ b/test/libyul/yulSyntaxTests/more_than_256_analysis_errors.yul @@ -20,260 +20,260 @@ let $100:x } // ---- -// TypeError 5473: (200-205): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (210-215): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (220-225): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (230-235): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (240-245): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (250-255): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (260-265): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (270-275): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (280-285): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (290-295): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (300-305): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (310-315): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (320-325): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (330-335): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (340-345): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (350-355): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (364-369): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (374-379): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (384-389): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (394-399): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (404-409): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (414-419): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (424-429): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (434-439): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (444-449): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (454-459): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (464-469): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (474-479): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (484-489): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (494-499): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (504-509): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (514-519): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (528-533): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (538-543): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (548-553): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (558-563): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (568-573): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (578-583): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (588-593): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (598-603): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (608-613): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (618-623): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (628-633): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (638-643): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (648-653): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (658-663): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (668-673): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (678-683): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (692-697): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (702-707): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (712-717): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (722-727): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (732-737): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (742-747): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (752-757): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (762-767): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (772-777): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (782-787): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (792-797): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (802-807): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (812-817): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (822-827): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (832-837): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (842-847): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (856-861): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (866-871): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (876-881): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (886-891): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (896-901): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (906-911): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (916-921): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (926-931): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (936-941): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (946-951): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (956-961): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (966-971): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (976-981): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (986-991): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (996-1001): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (1006-1011): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (1020-1025): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (1030-1035): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (1040-1045): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (1050-1055): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (1060-1065): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (1070-1075): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (1080-1085): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (1090-1095): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (1100-1105): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (1110-1115): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (1120-1125): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (1130-1135): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (1140-1145): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (1150-1155): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (1160-1165): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (1170-1175): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (1184-1189): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (1194-1199): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (1204-1209): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (1214-1219): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (1224-1229): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (1234-1239): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (1244-1249): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (1254-1259): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (1264-1269): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (1274-1279): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (1284-1289): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (1294-1299): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (1304-1309): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (1314-1319): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (1324-1329): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (1334-1339): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (1348-1353): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (1358-1363): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (1368-1373): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (1378-1383): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (1388-1393): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (1398-1403): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (1408-1413): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (1418-1423): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (1428-1433): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (1438-1443): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (1448-1453): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (1458-1463): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (1468-1473): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (1478-1483): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (1488-1493): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (1498-1503): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (1512-1517): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (1522-1527): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (1532-1537): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (1542-1547): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (1552-1557): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (1562-1567): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (1572-1577): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (1582-1587): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (1592-1597): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (1602-1607): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (1612-1617): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (1622-1627): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (1632-1637): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (1642-1647): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (1652-1657): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (1662-1667): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (1676-1681): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (1686-1691): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (1696-1701): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (1706-1711): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (1716-1721): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (1726-1731): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (1736-1741): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (1746-1751): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (1756-1761): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (1766-1771): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (1776-1781): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (1786-1791): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (1796-1801): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (1806-1811): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (1816-1821): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (1826-1831): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (1840-1845): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (1850-1855): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (1860-1865): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (1870-1875): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (1880-1885): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (1890-1895): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (1900-1905): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (1910-1915): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (1920-1925): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (1930-1935): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (1940-1945): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (1950-1955): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (1960-1965): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (1970-1975): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (1980-1985): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (1990-1995): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (2004-2009): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (2014-2019): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (2024-2029): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (2034-2039): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (2044-2049): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (2054-2059): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (2064-2069): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (2074-2079): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (2084-2089): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (2094-2099): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (2104-2109): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (2114-2119): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (2124-2129): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (2134-2139): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (2144-2149): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (2154-2159): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (2168-2173): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (2178-2183): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (2188-2193): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (2198-2203): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (2208-2213): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (2218-2223): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (2228-2233): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (2238-2243): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (2248-2253): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (2258-2263): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (2268-2273): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (2278-2283): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (2288-2293): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (2298-2303): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (2308-2313): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (2318-2323): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (2332-2337): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (2342-2347): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (2352-2357): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (2362-2367): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (2372-2377): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (2382-2387): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (2392-2397): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (2402-2407): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (2412-2417): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (2422-2427): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (2432-2437): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (2442-2447): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (2452-2457): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (2462-2467): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (2472-2477): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (2482-2487): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (2496-2501): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (2506-2511): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (2516-2521): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (2526-2531): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (2536-2541): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (2546-2551): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (2556-2561): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (2566-2571): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (2576-2581): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (2586-2591): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (2596-2601): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (2606-2611): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (2616-2621): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (2626-2631): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (2636-2641): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (2646-2651): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (2660-2665): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (2670-2675): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (2680-2685): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (2690-2695): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (2700-2705): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (2710-2715): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (2720-2725): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (2730-2735): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (2740-2745): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (2750-2755): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (2760-2765): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (2770-2775): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (2780-2785): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (2790-2795): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (2800-2805): "x" is not a valid type (user defined types are not yet supported). -// TypeError 5473: (2810-2815): "x" is not a valid type (user defined types are not yet supported). +// ParserError 5473: (200-205): Types are not valid in untyped Yul. +// ParserError 5473: (210-215): Types are not valid in untyped Yul. +// ParserError 5473: (220-225): Types are not valid in untyped Yul. +// ParserError 5473: (230-235): Types are not valid in untyped Yul. +// ParserError 5473: (240-245): Types are not valid in untyped Yul. +// ParserError 5473: (250-255): Types are not valid in untyped Yul. +// ParserError 5473: (260-265): Types are not valid in untyped Yul. +// ParserError 5473: (270-275): Types are not valid in untyped Yul. +// ParserError 5473: (280-285): Types are not valid in untyped Yul. +// ParserError 5473: (290-295): Types are not valid in untyped Yul. +// ParserError 5473: (300-305): Types are not valid in untyped Yul. +// ParserError 5473: (310-315): Types are not valid in untyped Yul. +// ParserError 5473: (320-325): Types are not valid in untyped Yul. +// ParserError 5473: (330-335): Types are not valid in untyped Yul. +// ParserError 5473: (340-345): Types are not valid in untyped Yul. +// ParserError 5473: (350-355): Types are not valid in untyped Yul. +// ParserError 5473: (364-369): Types are not valid in untyped Yul. +// ParserError 5473: (374-379): Types are not valid in untyped Yul. +// ParserError 5473: (384-389): Types are not valid in untyped Yul. +// ParserError 5473: (394-399): Types are not valid in untyped Yul. +// ParserError 5473: (404-409): Types are not valid in untyped Yul. +// ParserError 5473: (414-419): Types are not valid in untyped Yul. +// ParserError 5473: (424-429): Types are not valid in untyped Yul. +// ParserError 5473: (434-439): Types are not valid in untyped Yul. +// ParserError 5473: (444-449): Types are not valid in untyped Yul. +// ParserError 5473: (454-459): Types are not valid in untyped Yul. +// ParserError 5473: (464-469): Types are not valid in untyped Yul. +// ParserError 5473: (474-479): Types are not valid in untyped Yul. +// ParserError 5473: (484-489): Types are not valid in untyped Yul. +// ParserError 5473: (494-499): Types are not valid in untyped Yul. +// ParserError 5473: (504-509): Types are not valid in untyped Yul. +// ParserError 5473: (514-519): Types are not valid in untyped Yul. +// ParserError 5473: (528-533): Types are not valid in untyped Yul. +// ParserError 5473: (538-543): Types are not valid in untyped Yul. +// ParserError 5473: (548-553): Types are not valid in untyped Yul. +// ParserError 5473: (558-563): Types are not valid in untyped Yul. +// ParserError 5473: (568-573): Types are not valid in untyped Yul. +// ParserError 5473: (578-583): Types are not valid in untyped Yul. +// ParserError 5473: (588-593): Types are not valid in untyped Yul. +// ParserError 5473: (598-603): Types are not valid in untyped Yul. +// ParserError 5473: (608-613): Types are not valid in untyped Yul. +// ParserError 5473: (618-623): Types are not valid in untyped Yul. +// ParserError 5473: (628-633): Types are not valid in untyped Yul. +// ParserError 5473: (638-643): Types are not valid in untyped Yul. +// ParserError 5473: (648-653): Types are not valid in untyped Yul. +// ParserError 5473: (658-663): Types are not valid in untyped Yul. +// ParserError 5473: (668-673): Types are not valid in untyped Yul. +// ParserError 5473: (678-683): Types are not valid in untyped Yul. +// ParserError 5473: (692-697): Types are not valid in untyped Yul. +// ParserError 5473: (702-707): Types are not valid in untyped Yul. +// ParserError 5473: (712-717): Types are not valid in untyped Yul. +// ParserError 5473: (722-727): Types are not valid in untyped Yul. +// ParserError 5473: (732-737): Types are not valid in untyped Yul. +// ParserError 5473: (742-747): Types are not valid in untyped Yul. +// ParserError 5473: (752-757): Types are not valid in untyped Yul. +// ParserError 5473: (762-767): Types are not valid in untyped Yul. +// ParserError 5473: (772-777): Types are not valid in untyped Yul. +// ParserError 5473: (782-787): Types are not valid in untyped Yul. +// ParserError 5473: (792-797): Types are not valid in untyped Yul. +// ParserError 5473: (802-807): Types are not valid in untyped Yul. +// ParserError 5473: (812-817): Types are not valid in untyped Yul. +// ParserError 5473: (822-827): Types are not valid in untyped Yul. +// ParserError 5473: (832-837): Types are not valid in untyped Yul. +// ParserError 5473: (842-847): Types are not valid in untyped Yul. +// ParserError 5473: (856-861): Types are not valid in untyped Yul. +// ParserError 5473: (866-871): Types are not valid in untyped Yul. +// ParserError 5473: (876-881): Types are not valid in untyped Yul. +// ParserError 5473: (886-891): Types are not valid in untyped Yul. +// ParserError 5473: (896-901): Types are not valid in untyped Yul. +// ParserError 5473: (906-911): Types are not valid in untyped Yul. +// ParserError 5473: (916-921): Types are not valid in untyped Yul. +// ParserError 5473: (926-931): Types are not valid in untyped Yul. +// ParserError 5473: (936-941): Types are not valid in untyped Yul. +// ParserError 5473: (946-951): Types are not valid in untyped Yul. +// ParserError 5473: (956-961): Types are not valid in untyped Yul. +// ParserError 5473: (966-971): Types are not valid in untyped Yul. +// ParserError 5473: (976-981): Types are not valid in untyped Yul. +// ParserError 5473: (986-991): Types are not valid in untyped Yul. +// ParserError 5473: (996-1001): Types are not valid in untyped Yul. +// ParserError 5473: (1006-1011): Types are not valid in untyped Yul. +// ParserError 5473: (1020-1025): Types are not valid in untyped Yul. +// ParserError 5473: (1030-1035): Types are not valid in untyped Yul. +// ParserError 5473: (1040-1045): Types are not valid in untyped Yul. +// ParserError 5473: (1050-1055): Types are not valid in untyped Yul. +// ParserError 5473: (1060-1065): Types are not valid in untyped Yul. +// ParserError 5473: (1070-1075): Types are not valid in untyped Yul. +// ParserError 5473: (1080-1085): Types are not valid in untyped Yul. +// ParserError 5473: (1090-1095): Types are not valid in untyped Yul. +// ParserError 5473: (1100-1105): Types are not valid in untyped Yul. +// ParserError 5473: (1110-1115): Types are not valid in untyped Yul. +// ParserError 5473: (1120-1125): Types are not valid in untyped Yul. +// ParserError 5473: (1130-1135): Types are not valid in untyped Yul. +// ParserError 5473: (1140-1145): Types are not valid in untyped Yul. +// ParserError 5473: (1150-1155): Types are not valid in untyped Yul. +// ParserError 5473: (1160-1165): Types are not valid in untyped Yul. +// ParserError 5473: (1170-1175): Types are not valid in untyped Yul. +// ParserError 5473: (1184-1189): Types are not valid in untyped Yul. +// ParserError 5473: (1194-1199): Types are not valid in untyped Yul. +// ParserError 5473: (1204-1209): Types are not valid in untyped Yul. +// ParserError 5473: (1214-1219): Types are not valid in untyped Yul. +// ParserError 5473: (1224-1229): Types are not valid in untyped Yul. +// ParserError 5473: (1234-1239): Types are not valid in untyped Yul. +// ParserError 5473: (1244-1249): Types are not valid in untyped Yul. +// ParserError 5473: (1254-1259): Types are not valid in untyped Yul. +// ParserError 5473: (1264-1269): Types are not valid in untyped Yul. +// ParserError 5473: (1274-1279): Types are not valid in untyped Yul. +// ParserError 5473: (1284-1289): Types are not valid in untyped Yul. +// ParserError 5473: (1294-1299): Types are not valid in untyped Yul. +// ParserError 5473: (1304-1309): Types are not valid in untyped Yul. +// ParserError 5473: (1314-1319): Types are not valid in untyped Yul. +// ParserError 5473: (1324-1329): Types are not valid in untyped Yul. +// ParserError 5473: (1334-1339): Types are not valid in untyped Yul. +// ParserError 5473: (1348-1353): Types are not valid in untyped Yul. +// ParserError 5473: (1358-1363): Types are not valid in untyped Yul. +// ParserError 5473: (1368-1373): Types are not valid in untyped Yul. +// ParserError 5473: (1378-1383): Types are not valid in untyped Yul. +// ParserError 5473: (1388-1393): Types are not valid in untyped Yul. +// ParserError 5473: (1398-1403): Types are not valid in untyped Yul. +// ParserError 5473: (1408-1413): Types are not valid in untyped Yul. +// ParserError 5473: (1418-1423): Types are not valid in untyped Yul. +// ParserError 5473: (1428-1433): Types are not valid in untyped Yul. +// ParserError 5473: (1438-1443): Types are not valid in untyped Yul. +// ParserError 5473: (1448-1453): Types are not valid in untyped Yul. +// ParserError 5473: (1458-1463): Types are not valid in untyped Yul. +// ParserError 5473: (1468-1473): Types are not valid in untyped Yul. +// ParserError 5473: (1478-1483): Types are not valid in untyped Yul. +// ParserError 5473: (1488-1493): Types are not valid in untyped Yul. +// ParserError 5473: (1498-1503): Types are not valid in untyped Yul. +// ParserError 5473: (1512-1517): Types are not valid in untyped Yul. +// ParserError 5473: (1522-1527): Types are not valid in untyped Yul. +// ParserError 5473: (1532-1537): Types are not valid in untyped Yul. +// ParserError 5473: (1542-1547): Types are not valid in untyped Yul. +// ParserError 5473: (1552-1557): Types are not valid in untyped Yul. +// ParserError 5473: (1562-1567): Types are not valid in untyped Yul. +// ParserError 5473: (1572-1577): Types are not valid in untyped Yul. +// ParserError 5473: (1582-1587): Types are not valid in untyped Yul. +// ParserError 5473: (1592-1597): Types are not valid in untyped Yul. +// ParserError 5473: (1602-1607): Types are not valid in untyped Yul. +// ParserError 5473: (1612-1617): Types are not valid in untyped Yul. +// ParserError 5473: (1622-1627): Types are not valid in untyped Yul. +// ParserError 5473: (1632-1637): Types are not valid in untyped Yul. +// ParserError 5473: (1642-1647): Types are not valid in untyped Yul. +// ParserError 5473: (1652-1657): Types are not valid in untyped Yul. +// ParserError 5473: (1662-1667): Types are not valid in untyped Yul. +// ParserError 5473: (1676-1681): Types are not valid in untyped Yul. +// ParserError 5473: (1686-1691): Types are not valid in untyped Yul. +// ParserError 5473: (1696-1701): Types are not valid in untyped Yul. +// ParserError 5473: (1706-1711): Types are not valid in untyped Yul. +// ParserError 5473: (1716-1721): Types are not valid in untyped Yul. +// ParserError 5473: (1726-1731): Types are not valid in untyped Yul. +// ParserError 5473: (1736-1741): Types are not valid in untyped Yul. +// ParserError 5473: (1746-1751): Types are not valid in untyped Yul. +// ParserError 5473: (1756-1761): Types are not valid in untyped Yul. +// ParserError 5473: (1766-1771): Types are not valid in untyped Yul. +// ParserError 5473: (1776-1781): Types are not valid in untyped Yul. +// ParserError 5473: (1786-1791): Types are not valid in untyped Yul. +// ParserError 5473: (1796-1801): Types are not valid in untyped Yul. +// ParserError 5473: (1806-1811): Types are not valid in untyped Yul. +// ParserError 5473: (1816-1821): Types are not valid in untyped Yul. +// ParserError 5473: (1826-1831): Types are not valid in untyped Yul. +// ParserError 5473: (1840-1845): Types are not valid in untyped Yul. +// ParserError 5473: (1850-1855): Types are not valid in untyped Yul. +// ParserError 5473: (1860-1865): Types are not valid in untyped Yul. +// ParserError 5473: (1870-1875): Types are not valid in untyped Yul. +// ParserError 5473: (1880-1885): Types are not valid in untyped Yul. +// ParserError 5473: (1890-1895): Types are not valid in untyped Yul. +// ParserError 5473: (1900-1905): Types are not valid in untyped Yul. +// ParserError 5473: (1910-1915): Types are not valid in untyped Yul. +// ParserError 5473: (1920-1925): Types are not valid in untyped Yul. +// ParserError 5473: (1930-1935): Types are not valid in untyped Yul. +// ParserError 5473: (1940-1945): Types are not valid in untyped Yul. +// ParserError 5473: (1950-1955): Types are not valid in untyped Yul. +// ParserError 5473: (1960-1965): Types are not valid in untyped Yul. +// ParserError 5473: (1970-1975): Types are not valid in untyped Yul. +// ParserError 5473: (1980-1985): Types are not valid in untyped Yul. +// ParserError 5473: (1990-1995): Types are not valid in untyped Yul. +// ParserError 5473: (2004-2009): Types are not valid in untyped Yul. +// ParserError 5473: (2014-2019): Types are not valid in untyped Yul. +// ParserError 5473: (2024-2029): Types are not valid in untyped Yul. +// ParserError 5473: (2034-2039): Types are not valid in untyped Yul. +// ParserError 5473: (2044-2049): Types are not valid in untyped Yul. +// ParserError 5473: (2054-2059): Types are not valid in untyped Yul. +// ParserError 5473: (2064-2069): Types are not valid in untyped Yul. +// ParserError 5473: (2074-2079): Types are not valid in untyped Yul. +// ParserError 5473: (2084-2089): Types are not valid in untyped Yul. +// ParserError 5473: (2094-2099): Types are not valid in untyped Yul. +// ParserError 5473: (2104-2109): Types are not valid in untyped Yul. +// ParserError 5473: (2114-2119): Types are not valid in untyped Yul. +// ParserError 5473: (2124-2129): Types are not valid in untyped Yul. +// ParserError 5473: (2134-2139): Types are not valid in untyped Yul. +// ParserError 5473: (2144-2149): Types are not valid in untyped Yul. +// ParserError 5473: (2154-2159): Types are not valid in untyped Yul. +// ParserError 5473: (2168-2173): Types are not valid in untyped Yul. +// ParserError 5473: (2178-2183): Types are not valid in untyped Yul. +// ParserError 5473: (2188-2193): Types are not valid in untyped Yul. +// ParserError 5473: (2198-2203): Types are not valid in untyped Yul. +// ParserError 5473: (2208-2213): Types are not valid in untyped Yul. +// ParserError 5473: (2218-2223): Types are not valid in untyped Yul. +// ParserError 5473: (2228-2233): Types are not valid in untyped Yul. +// ParserError 5473: (2238-2243): Types are not valid in untyped Yul. +// ParserError 5473: (2248-2253): Types are not valid in untyped Yul. +// ParserError 5473: (2258-2263): Types are not valid in untyped Yul. +// ParserError 5473: (2268-2273): Types are not valid in untyped Yul. +// ParserError 5473: (2278-2283): Types are not valid in untyped Yul. +// ParserError 5473: (2288-2293): Types are not valid in untyped Yul. +// ParserError 5473: (2298-2303): Types are not valid in untyped Yul. +// ParserError 5473: (2308-2313): Types are not valid in untyped Yul. +// ParserError 5473: (2318-2323): Types are not valid in untyped Yul. +// ParserError 5473: (2332-2337): Types are not valid in untyped Yul. +// ParserError 5473: (2342-2347): Types are not valid in untyped Yul. +// ParserError 5473: (2352-2357): Types are not valid in untyped Yul. +// ParserError 5473: (2362-2367): Types are not valid in untyped Yul. +// ParserError 5473: (2372-2377): Types are not valid in untyped Yul. +// ParserError 5473: (2382-2387): Types are not valid in untyped Yul. +// ParserError 5473: (2392-2397): Types are not valid in untyped Yul. +// ParserError 5473: (2402-2407): Types are not valid in untyped Yul. +// ParserError 5473: (2412-2417): Types are not valid in untyped Yul. +// ParserError 5473: (2422-2427): Types are not valid in untyped Yul. +// ParserError 5473: (2432-2437): Types are not valid in untyped Yul. +// ParserError 5473: (2442-2447): Types are not valid in untyped Yul. +// ParserError 5473: (2452-2457): Types are not valid in untyped Yul. +// ParserError 5473: (2462-2467): Types are not valid in untyped Yul. +// ParserError 5473: (2472-2477): Types are not valid in untyped Yul. +// ParserError 5473: (2482-2487): Types are not valid in untyped Yul. +// ParserError 5473: (2496-2501): Types are not valid in untyped Yul. +// ParserError 5473: (2506-2511): Types are not valid in untyped Yul. +// ParserError 5473: (2516-2521): Types are not valid in untyped Yul. +// ParserError 5473: (2526-2531): Types are not valid in untyped Yul. +// ParserError 5473: (2536-2541): Types are not valid in untyped Yul. +// ParserError 5473: (2546-2551): Types are not valid in untyped Yul. +// ParserError 5473: (2556-2561): Types are not valid in untyped Yul. +// ParserError 5473: (2566-2571): Types are not valid in untyped Yul. +// ParserError 5473: (2576-2581): Types are not valid in untyped Yul. +// ParserError 5473: (2586-2591): Types are not valid in untyped Yul. +// ParserError 5473: (2596-2601): Types are not valid in untyped Yul. +// ParserError 5473: (2606-2611): Types are not valid in untyped Yul. +// ParserError 5473: (2616-2621): Types are not valid in untyped Yul. +// ParserError 5473: (2626-2631): Types are not valid in untyped Yul. +// ParserError 5473: (2636-2641): Types are not valid in untyped Yul. +// ParserError 5473: (2646-2651): Types are not valid in untyped Yul. +// ParserError 5473: (2660-2665): Types are not valid in untyped Yul. +// ParserError 5473: (2670-2675): Types are not valid in untyped Yul. +// ParserError 5473: (2680-2685): Types are not valid in untyped Yul. +// ParserError 5473: (2690-2695): Types are not valid in untyped Yul. +// ParserError 5473: (2700-2705): Types are not valid in untyped Yul. +// ParserError 5473: (2710-2715): Types are not valid in untyped Yul. +// ParserError 5473: (2720-2725): Types are not valid in untyped Yul. +// ParserError 5473: (2730-2735): Types are not valid in untyped Yul. +// ParserError 5473: (2740-2745): Types are not valid in untyped Yul. +// ParserError 5473: (2750-2755): Types are not valid in untyped Yul. +// ParserError 5473: (2760-2765): Types are not valid in untyped Yul. +// ParserError 5473: (2770-2775): Types are not valid in untyped Yul. +// ParserError 5473: (2780-2785): Types are not valid in untyped Yul. +// ParserError 5473: (2790-2795): Types are not valid in untyped Yul. +// ParserError 5473: (2800-2805): Types are not valid in untyped Yul. +// ParserError 5473: (2810-2815): Types are not valid in untyped Yul. // Warning 4013: There are more than 256 errors. Aborting. From fbaa505de5356aed03979b0bbc3395bbbfcd3a9e Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Fri, 16 Aug 2024 12:05:56 +0200 Subject: [PATCH 0377/1022] Yul: Builtins now record number of args and rets instead of respective vectors of types --- libyul/AsmAnalysis.cpp | 4 ++-- libyul/Dialect.h | 5 ++--- libyul/backends/evm/ControlFlowGraphBuilder.cpp | 2 +- libyul/backends/evm/EVMDialect.cpp | 8 ++++---- libyul/backends/evm/EVMDialect.h | 1 - libyul/backends/evm/NoOutputAssembly.cpp | 2 +- libyul/backends/evm/OptimizedEVMCodeTransform.cpp | 2 +- test/libyul/Parser.cpp | 2 +- 8 files changed, 12 insertions(+), 14 deletions(-) diff --git a/libyul/AsmAnalysis.cpp b/libyul/AsmAnalysis.cpp index d039b3b47c08..faa849fe185e 100644 --- a/libyul/AsmAnalysis.cpp +++ b/libyul/AsmAnalysis.cpp @@ -327,8 +327,8 @@ size_t AsmAnalyzer::operator()(FunctionCall const& _funCall) "The use of transient storage for reentrancy guards that are cleared at the end of the call is safe." ); - numParameters = f->parameters.size(); - numReturns = f->returns.size(); + numParameters = f->numParameters; + numReturns = f->numReturns; if (!f->literalArguments.empty()) literalArguments = &f->literalArguments; diff --git a/libyul/Dialect.h b/libyul/Dialect.h index f9ce01469055..3589e953f60f 100644 --- a/libyul/Dialect.h +++ b/libyul/Dialect.h @@ -32,7 +32,6 @@ namespace solidity::yul { -using Type = YulName; enum class LiteralKind; class LiteralValue; struct Literal; @@ -40,8 +39,8 @@ struct Literal; struct BuiltinFunction { YulName name; - std::vector parameters; - std::vector returns; + size_t numParameters; + size_t numReturns; SideEffects sideEffects; ControlFlowSideEffects controlFlowSideEffects; /// If true, this is the msize instruction or might contain it. diff --git a/libyul/backends/evm/ControlFlowGraphBuilder.cpp b/libyul/backends/evm/ControlFlowGraphBuilder.cpp index 596c6c961966..46ef933ba28e 100644 --- a/libyul/backends/evm/ControlFlowGraphBuilder.cpp +++ b/libyul/backends/evm/ControlFlowGraphBuilder.cpp @@ -527,7 +527,7 @@ Stack const& ControlFlowGraphBuilder::visitFunctionCall(FunctionCall const& _cal // input std::move(inputs), // output - ranges::views::iota(0u, builtin->returns.size()) | ranges::views::transform([&](size_t _i) { + ranges::views::iota(0u, builtin->numReturns) | ranges::views::transform([&](size_t _i) { return TemporarySlot{_call, _i}; }) | ranges::to, // operation diff --git a/libyul/backends/evm/EVMDialect.cpp b/libyul/backends/evm/EVMDialect.cpp index aeb825304009..dd5cad1dd700 100644 --- a/libyul/backends/evm/EVMDialect.cpp +++ b/libyul/backends/evm/EVMDialect.cpp @@ -50,8 +50,8 @@ std::pair createEVMFunction( evmasm::InstructionInfo info = evmasm::instructionInfo(_instruction, _evmVersion); BuiltinFunctionForEVM f; f.name = YulName{_name}; - f.parameters.resize(static_cast(info.args)); - f.returns.resize(static_cast(info.ret)); + f.numParameters = static_cast(info.args); + f.numReturns = static_cast(info.ret); f.sideEffects = EVMDialect::sideEffectsOfInstruction(_instruction); if (evmasm::SemanticInformation::terminatesControlFlow(_instruction)) { @@ -96,8 +96,8 @@ std::pair createFunction( YulName name{std::move(_name)}; BuiltinFunctionForEVM f; f.name = name; - f.parameters.resize(_params); - f.returns.resize(_returns); + f.numParameters = _params; + f.numReturns = _returns; f.sideEffects = std::move(_sideEffects); f.literalArguments = std::move(_literalArguments); f.isMSize = false; diff --git a/libyul/backends/evm/EVMDialect.h b/libyul/backends/evm/EVMDialect.h index 3207b8fae025..3627a7fea9b7 100644 --- a/libyul/backends/evm/EVMDialect.h +++ b/libyul/backends/evm/EVMDialect.h @@ -33,7 +33,6 @@ namespace solidity::yul { -using Type = YulName; struct FunctionCall; struct Object; diff --git a/libyul/backends/evm/NoOutputAssembly.cpp b/libyul/backends/evm/NoOutputAssembly.cpp index 71818d2482f4..04324fa06204 100644 --- a/libyul/backends/evm/NoOutputAssembly.cpp +++ b/libyul/backends/evm/NoOutputAssembly.cpp @@ -134,7 +134,7 @@ NoOutputEVMDialect::NoOutputEVMDialect(EVMDialect const& _copyFrom): { for (auto& fun: m_functions) { - size_t returns = fun.second.returns.size(); + size_t returns = fun.second.numReturns; fun.second.generateCode = [=](FunctionCall const& _call, AbstractAssembly& _assembly, BuiltinContext&) { for (size_t i: ranges::views::iota(0u, _call.arguments.size())) diff --git a/libyul/backends/evm/OptimizedEVMCodeTransform.cpp b/libyul/backends/evm/OptimizedEVMCodeTransform.cpp index 6395ea64aeb0..8ef01f0b6a86 100644 --- a/libyul/backends/evm/OptimizedEVMCodeTransform.cpp +++ b/libyul/backends/evm/OptimizedEVMCodeTransform.cpp @@ -147,7 +147,7 @@ void OptimizedEVMCodeTransform::operator()(CFG::BuiltinCall const& _call) for (size_t i = 0; i < _call.arguments; ++i) m_stack.pop_back(); // Push return values to m_stack. - for (size_t index: ranges::views::iota(0u, _call.builtin.get().returns.size())) + for (size_t index: ranges::views::iota(0u, _call.builtin.get().numReturns)) m_stack.emplace_back(TemporarySlot{_call.functionCall, index}); yulAssert(m_assembly.stackHeight() == static_cast(m_stack.size()), ""); } diff --git a/test/libyul/Parser.cpp b/test/libyul/Parser.cpp index 2a2f2809296b..9b8ce42921b6 100644 --- a/test/libyul/Parser.cpp +++ b/test/libyul/Parser.cpp @@ -139,7 +139,7 @@ BOOST_AUTO_TEST_CASE(builtins_analysis) { return _name == "builtin"_yulname ? &f : nullptr; } - BuiltinFunction f{"builtin"_yulname, std::vector(2), std::vector(3), {}, {}, false, {}}; + BuiltinFunction f{"builtin"_yulname, 2, 3, {}, {}, false, {}}; }; SimpleDialect dialect; From 4938075b94089fd4fedb15177f984512f7efd5c6 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Tue, 27 Aug 2024 10:35:59 +0200 Subject: [PATCH 0378/1022] Yul: Improve variable naming and type error message wording, update tests. --- libyul/AsmAnalysis.cpp | 7 +- libyul/AsmAnalysis.h | 4 +- libyul/AsmJsonConverter.cpp | 3 + libyul/AsmJsonImporter.cpp | 8 +- libyul/AsmParser.cpp | 16 +- libyul/AsmParser.h | 2 +- test/libyul/yulSyntaxTests/invalid_type.yul | 2 +- test/libyul/yulSyntaxTests/invalid_type2.yul | 2 +- test/libyul/yulSyntaxTests/invalid_type3.yul | 4 +- test/libyul/yulSyntaxTests/invalid_type4.yul | 2 +- .../yulSyntaxTests/literal_invalid_type.yul | 2 +- .../more_than_256_analysis_errors.yul | 565 +++++++++--------- 12 files changed, 320 insertions(+), 297 deletions(-) diff --git a/libyul/AsmAnalysis.cpp b/libyul/AsmAnalysis.cpp index faa849fe185e..64630fa2bee9 100644 --- a/libyul/AsmAnalysis.cpp +++ b/libyul/AsmAnalysis.cpp @@ -380,7 +380,6 @@ size_t AsmAnalyzer::operator()(FunctionCall const& _funCall) std::to_string(_funCall.arguments.size()) + "." ); - size_t numArgs{0}; for (size_t i = _funCall.arguments.size(); i > 0; i--) { Expression const& arg = _funCall.arguments[i - 1]; @@ -427,18 +426,16 @@ size_t AsmAnalyzer::operator()(FunctionCall const& _funCall) ); } expectUnlimitedStringLiteral(std::get(arg)); - ++numArgs; continue; } } expectExpression(arg); - ++numArgs; } if (watcher.ok()) { - yulAssert(numParameters && numParameters == numArgs, ""); - yulAssert(numReturns, ""); + yulAssert(numParameters && numParameters == _funCall.arguments.size()); + yulAssert(numReturns); return *numReturns; } else if (numReturns) diff --git a/libyul/AsmAnalysis.h b/libyul/AsmAnalysis.h index d01ecc1901e6..64cab51f54c5 100644 --- a/libyul/AsmAnalysis.h +++ b/libyul/AsmAnalysis.h @@ -102,8 +102,8 @@ class AsmAnalyzer /// @returns the worst side effects encountered during analysis (including within defined functions). SideEffects const& sideEffects() const { return m_sideEffects; } private: - /// Visits the expression, expects that it evaluates to exactly one value and - /// returns the type. Reports errors on errors and returns the default type. + /// Visits the expression, expects that it evaluates to exactly one value. + /// Reports errors otherwise. void expectExpression(Expression const& _expr); void expectUnlimitedStringLiteral(Literal const& _literal); diff --git a/libyul/AsmJsonConverter.cpp b/libyul/AsmJsonConverter.cpp index d85b96f8f980..226ac52a5ac8 100644 --- a/libyul/AsmJsonConverter.cpp +++ b/libyul/AsmJsonConverter.cpp @@ -42,6 +42,9 @@ Json AsmJsonConverter::operator()(NameWithDebugData const& _node) const yulAssert(!_node.name.empty(), "Invalid variable name."); Json ret = createAstNode(originLocationOf(_node), nativeLocationOf(_node), "YulTypedName"); ret["name"] = _node.name.str(); + // even though types are removed from Yul, we keep this field in the Json interface to not introduce + // a breaking change + // can be removed with the next breaking version ret["type"] = ""; return ret; } diff --git a/libyul/AsmJsonImporter.cpp b/libyul/AsmJsonImporter.cpp index 6de7bb6abc16..459d9d9becd5 100644 --- a/libyul/AsmJsonImporter.cpp +++ b/libyul/AsmJsonImporter.cpp @@ -177,7 +177,13 @@ Literal AsmJsonImporter::createLiteral(Json const& _node) value = member(_node, "value").get(); { auto const typeNode = member(_node, "type"); - yulAssert(typeNode.empty() || typeNode.get().empty()); + yulAssert( + typeNode.empty() || typeNode.get().empty(), + fmt::format( + "Expected literal types to be either empty or absent in the JSON. Got \"{}\".", + typeNode.get() + ) + ); } if (kind == "number") { diff --git a/libyul/AsmParser.cpp b/libyul/AsmParser.cpp index bd890c4aaa06..d41b41a36a42 100644 --- a/libyul/AsmParser.cpp +++ b/libyul/AsmParser.cpp @@ -567,7 +567,7 @@ std::variant Parser::parseLiteralOrIdentifier(bool _unlimit break; } - auto const beginOfLiteralLoc = currentLocation(); + auto const literalLocation = currentLocation(); Literal literal{ createDebugData(), kind, @@ -578,9 +578,9 @@ std::variant Parser::parseLiteralOrIdentifier(bool _unlimit { expectToken(Token::Colon); updateLocationEndFrom(literal.debugData, currentLocation()); - auto const loc = SourceLocation::smallestCovering(beginOfLiteralLoc, currentLocation()); + auto const typedLiteralLocation = SourceLocation::smallestCovering(literalLocation, currentLocation()); std::ignore = expectAsmIdentifier(); - expectUntyped(loc); + raiseUnsupportedTypesError(typedLiteralLocation); } return literal; @@ -701,15 +701,15 @@ NameWithDebugData Parser::parseNameWithDebugData() { RecursionGuard recursionGuard(*this); NameWithDebugData typedName = createWithDebugData(); - auto const locNameStart = currentLocation(); + auto const nameLocation = currentLocation(); typedName.name = expectAsmIdentifier(); if (currentToken() == Token::Colon) { expectToken(Token::Colon); updateLocationEndFrom(typedName.debugData, currentLocation()); - auto const loc = SourceLocation::smallestCovering(locNameStart, currentLocation()); + auto const typedNameLocation = SourceLocation::smallestCovering(nameLocation, currentLocation()); std::ignore = expectAsmIdentifier(); - expectUntyped(loc); + raiseUnsupportedTypesError(typedNameLocation); } return typedName; @@ -760,7 +760,7 @@ bool Parser::isValidNumberLiteral(std::string const& _literal) return _literal.find_first_not_of("0123456789") == std::string::npos; } -void Parser::expectUntyped(SourceLocation const& loc) +void Parser::raiseUnsupportedTypesError(SourceLocation const& _location) const { - m_errorReporter.parserError(5473_error, loc, "Types are not valid in untyped Yul."); + m_errorReporter.parserError(5473_error, _location, "Types are not supported in untyped Yul."); } diff --git a/libyul/AsmParser.h b/libyul/AsmParser.h index 42ed2ca84d9c..d4616a2a9508 100644 --- a/libyul/AsmParser.h +++ b/libyul/AsmParser.h @@ -147,7 +147,7 @@ class Parser: public langutil::ParserBase FunctionCall parseCall(std::variant&& _initialOp); NameWithDebugData parseNameWithDebugData(); YulName expectAsmIdentifier(); - void expectUntyped(langutil::SourceLocation const& loc); + void raiseUnsupportedTypesError(langutil::SourceLocation const& _location) const; /// Reports an error if we are currently not inside the body part of a for loop. void checkBreakContinuePosition(std::string const& _which); diff --git a/test/libyul/yulSyntaxTests/invalid_type.yul b/test/libyul/yulSyntaxTests/invalid_type.yul index e9a4e30c95af..69f20b7053d9 100644 --- a/test/libyul/yulSyntaxTests/invalid_type.yul +++ b/test/libyul/yulSyntaxTests/invalid_type.yul @@ -2,4 +2,4 @@ let x: invalidType } // ---- -// ParserError 5473: (10-24): Types are not valid in untyped Yul. +// ParserError 5473: (10-24): Types are not supported in untyped Yul. diff --git a/test/libyul/yulSyntaxTests/invalid_type2.yul b/test/libyul/yulSyntaxTests/invalid_type2.yul index 5eb514866f00..ab26f6925e0d 100644 --- a/test/libyul/yulSyntaxTests/invalid_type2.yul +++ b/test/libyul/yulSyntaxTests/invalid_type2.yul @@ -2,4 +2,4 @@ let x := 1:invalidType } // ---- -// ParserError 5473: (15-28): Types are not valid in untyped Yul. +// ParserError 5473: (15-28): Types are not supported in untyped Yul. diff --git a/test/libyul/yulSyntaxTests/invalid_type3.yul b/test/libyul/yulSyntaxTests/invalid_type3.yul index 9814527b0cc1..866d855adb7f 100644 --- a/test/libyul/yulSyntaxTests/invalid_type3.yul +++ b/test/libyul/yulSyntaxTests/invalid_type3.yul @@ -2,5 +2,5 @@ function f(a: invalidType) -> b: invalidType {} } // ---- -// ParserError 5473: (17-31): Types are not valid in untyped Yul. -// ParserError 5473: (36-50): Types are not valid in untyped Yul. +// ParserError 5473: (17-31): Types are not supported in untyped Yul. +// ParserError 5473: (36-50): Types are not supported in untyped Yul. diff --git a/test/libyul/yulSyntaxTests/invalid_type4.yul b/test/libyul/yulSyntaxTests/invalid_type4.yul index 4924a592a75e..e6ec73b7a1f3 100644 --- a/test/libyul/yulSyntaxTests/invalid_type4.yul +++ b/test/libyul/yulSyntaxTests/invalid_type4.yul @@ -3,4 +3,4 @@ case 8: invalidType {} } // ---- -// ParserError 5473: (24-38): Types are not valid in untyped Yul. +// ParserError 5473: (24-38): Types are not supported in untyped Yul. diff --git a/test/libyul/yulSyntaxTests/literal_invalid_type.yul b/test/libyul/yulSyntaxTests/literal_invalid_type.yul index 10a280120eb2..c0e6dccdf696 100644 --- a/test/libyul/yulSyntaxTests/literal_invalid_type.yul +++ b/test/libyul/yulSyntaxTests/literal_invalid_type.yul @@ -2,4 +2,4 @@ let x := true:unhappy } // ---- -// ParserError 5473: (15-27): Types are not valid in untyped Yul. +// ParserError 5473: (15-27): Types are not supported in untyped Yul. diff --git a/test/libyul/yulSyntaxTests/more_than_256_analysis_errors.yul b/test/libyul/yulSyntaxTests/more_than_256_analysis_errors.yul index edd7871a7efb..031944953e86 100644 --- a/test/libyul/yulSyntaxTests/more_than_256_analysis_errors.yul +++ b/test/libyul/yulSyntaxTests/more_than_256_analysis_errors.yul @@ -1,279 +1,296 @@ { - // There's no type called 'x' so every declaration here should trigger an error. + // Using a variable to initialize itself should trigger a "variable is used before declared" error. // It's only detected during analysis and is not fatal. Any other non-fatal analysis error would do. - let $00:x let $10:x let $20:x let $30:x let $40:x let $50:x let $60:x let $70:x let $80:x let $90:x let $a0:x let $b0:x let $c0:x let $d0:x let $e0:x let $f0:x - let $01:x let $11:x let $21:x let $31:x let $41:x let $51:x let $61:x let $71:x let $81:x let $91:x let $a1:x let $b1:x let $c1:x let $d1:x let $e1:x let $f1:x - let $02:x let $12:x let $22:x let $32:x let $42:x let $52:x let $62:x let $72:x let $82:x let $92:x let $a2:x let $b2:x let $c2:x let $d2:x let $e2:x let $f2:x - let $03:x let $13:x let $23:x let $33:x let $43:x let $53:x let $63:x let $73:x let $83:x let $93:x let $a3:x let $b3:x let $c3:x let $d3:x let $e3:x let $f3:x - let $04:x let $14:x let $24:x let $34:x let $44:x let $54:x let $64:x let $74:x let $84:x let $94:x let $a4:x let $b4:x let $c4:x let $d4:x let $e4:x let $f4:x - let $05:x let $15:x let $25:x let $35:x let $45:x let $55:x let $65:x let $75:x let $85:x let $95:x let $a5:x let $b5:x let $c5:x let $d5:x let $e5:x let $f5:x - let $06:x let $16:x let $26:x let $36:x let $46:x let $56:x let $66:x let $76:x let $86:x let $96:x let $a6:x let $b6:x let $c6:x let $d6:x let $e6:x let $f6:x - let $07:x let $17:x let $27:x let $37:x let $47:x let $57:x let $67:x let $77:x let $87:x let $97:x let $a7:x let $b7:x let $c7:x let $d7:x let $e7:x let $f7:x - let $08:x let $18:x let $28:x let $38:x let $48:x let $58:x let $68:x let $78:x let $88:x let $98:x let $a8:x let $b8:x let $c8:x let $d8:x let $e8:x let $f8:x - let $09:x let $19:x let $29:x let $39:x let $49:x let $59:x let $69:x let $79:x let $89:x let $99:x let $a9:x let $b9:x let $c9:x let $d9:x let $e9:x let $f9:x - let $0a:x let $1a:x let $2a:x let $3a:x let $4a:x let $5a:x let $6a:x let $7a:x let $8a:x let $9a:x let $aa:x let $ba:x let $ca:x let $da:x let $ea:x let $fa:x - let $0b:x let $1b:x let $2b:x let $3b:x let $4b:x let $5b:x let $6b:x let $7b:x let $8b:x let $9b:x let $ab:x let $bb:x let $cb:x let $db:x let $eb:x let $fb:x - let $0c:x let $1c:x let $2c:x let $3c:x let $4c:x let $5c:x let $6c:x let $7c:x let $8c:x let $9c:x let $ac:x let $bc:x let $cc:x let $dc:x let $ec:x let $fc:x - let $0d:x let $1d:x let $2d:x let $3d:x let $4d:x let $5d:x let $6d:x let $7d:x let $8d:x let $9d:x let $ad:x let $bd:x let $cd:x let $dd:x let $ed:x let $fd:x - let $0e:x let $1e:x let $2e:x let $3e:x let $4e:x let $5e:x let $6e:x let $7e:x let $8e:x let $9e:x let $ae:x let $be:x let $ce:x let $de:x let $ee:x let $fe:x - let $0f:x let $1f:x let $2f:x let $3f:x let $4f:x let $5f:x let $6f:x let $7f:x let $8f:x let $9f:x let $af:x let $bf:x let $cf:x let $df:x let $ef:x let $ff:x - let $100:x + let x00:=x00 let x01:=x01 let x02:=x02 let x03:=x03 let x04:=x04 let x05:=x05 let x06:=x06 let x07:=x07 + let x08:=x08 let x09:=x09 let x0a:=x0a let x0b:=x0b let x0c:=x0c let x0d:=x0d let x0e:=x0e let x0f:=x0f + let x10:=x10 let x11:=x11 let x12:=x12 let x13:=x13 let x14:=x14 let x15:=x15 let x16:=x16 let x17:=x17 + let x18:=x18 let x19:=x19 let x1a:=x1a let x1b:=x1b let x1c:=x1c let x1d:=x1d let x1e:=x1e let x1f:=x1f + let x20:=x20 let x21:=x21 let x22:=x22 let x23:=x23 let x24:=x24 let x25:=x25 let x26:=x26 let x27:=x27 + let x28:=x28 let x29:=x29 let x2a:=x2a let x2b:=x2b let x2c:=x2c let x2d:=x2d let x2e:=x2e let x2f:=x2f + let x30:=x30 let x31:=x31 let x32:=x32 let x33:=x33 let x34:=x34 let x35:=x35 let x36:=x36 let x37:=x37 + let x38:=x38 let x39:=x39 let x3a:=x3a let x3b:=x3b let x3c:=x3c let x3d:=x3d let x3e:=x3e let x3f:=x3f + let x40:=x40 let x41:=x41 let x42:=x42 let x43:=x43 let x44:=x44 let x45:=x45 let x46:=x46 let x47:=x47 + let x48:=x48 let x49:=x49 let x4a:=x4a let x4b:=x4b let x4c:=x4c let x4d:=x4d let x4e:=x4e let x4f:=x4f + let x50:=x50 let x51:=x51 let x52:=x52 let x53:=x53 let x54:=x54 let x55:=x55 let x56:=x56 let x57:=x57 + let x58:=x58 let x59:=x59 let x5a:=x5a let x5b:=x5b let x5c:=x5c let x5d:=x5d let x5e:=x5e let x5f:=x5f + let x60:=x60 let x61:=x61 let x62:=x62 let x63:=x63 let x64:=x64 let x65:=x65 let x66:=x66 let x67:=x67 + let x68:=x68 let x69:=x69 let x6a:=x6a let x6b:=x6b let x6c:=x6c let x6d:=x6d let x6e:=x6e let x6f:=x6f + let x70:=x70 let x71:=x71 let x72:=x72 let x73:=x73 let x74:=x74 let x75:=x75 let x76:=x76 let x77:=x77 + let x78:=x78 let x79:=x79 let x7a:=x7a let x7b:=x7b let x7c:=x7c let x7d:=x7d let x7e:=x7e let x7f:=x7f + let x80:=x80 let x81:=x81 let x82:=x82 let x83:=x83 let x84:=x84 let x85:=x85 let x86:=x86 let x87:=x87 + let x88:=x88 let x89:=x89 let x8a:=x8a let x8b:=x8b let x8c:=x8c let x8d:=x8d let x8e:=x8e let x8f:=x8f + let x90:=x90 let x91:=x91 let x92:=x92 let x93:=x93 let x94:=x94 let x95:=x95 let x96:=x96 let x97:=x97 + let x98:=x98 let x99:=x99 let x9a:=x9a let x9b:=x9b let x9c:=x9c let x9d:=x9d let x9e:=x9e let x9f:=x9f + let xa0:=xa0 let xa1:=xa1 let xa2:=xa2 let xa3:=xa3 let xa4:=xa4 let xa5:=xa5 let xa6:=xa6 let xa7:=xa7 + let xa8:=xa8 let xa9:=xa9 let xaa:=xaa let xab:=xab let xac:=xac let xad:=xad let xae:=xae let xaf:=xaf + let xb0:=xb0 let xb1:=xb1 let xb2:=xb2 let xb3:=xb3 let xb4:=xb4 let xb5:=xb5 let xb6:=xb6 let xb7:=xb7 + let xb8:=xb8 let xb9:=xb9 let xba:=xba let xbb:=xbb let xbc:=xbc let xbd:=xbd let xbe:=xbe let xbf:=xbf + let xc0:=xc0 let xc1:=xc1 let xc2:=xc2 let xc3:=xc3 let xc4:=xc4 let xc5:=xc5 let xc6:=xc6 let xc7:=xc7 + let xc8:=xc8 let xc9:=xc9 let xca:=xca let xcb:=xcb let xcc:=xcc let xcd:=xcd let xce:=xce let xcf:=xcf + let xd0:=xd0 let xd1:=xd1 let xd2:=xd2 let xd3:=xd3 let xd4:=xd4 let xd5:=xd5 let xd6:=xd6 let xd7:=xd7 + let xd8:=xd8 let xd9:=xd9 let xda:=xda let xdb:=xdb let xdc:=xdc let xdd:=xdd let xde:=xde let xdf:=xdf + let xe0:=xe0 let xe1:=xe1 let xe2:=xe2 let xe3:=xe3 let xe4:=xe4 let xe5:=xe5 let xe6:=xe6 let xe7:=xe7 + let xe8:=xe8 let xe9:=xe9 let xea:=xea let xeb:=xeb let xec:=xec let xed:=xed let xee:=xee let xef:=xef + let xf0:=xf0 let xf1:=xf1 let xf2:=xf2 let xf3:=xf3 let xf4:=xf4 let xf5:=xf5 let xf6:=xf6 let xf7:=xf7 + let xf8:=xf8 let xf9:=xf9 let xfa:=xfa let xfb:=xfb let xfc:=xfc let xfd:=xfd let xfe:=xfe let xff:=xff + let x100:=x100 + } // ---- -// ParserError 5473: (200-205): Types are not valid in untyped Yul. -// ParserError 5473: (210-215): Types are not valid in untyped Yul. -// ParserError 5473: (220-225): Types are not valid in untyped Yul. -// ParserError 5473: (230-235): Types are not valid in untyped Yul. -// ParserError 5473: (240-245): Types are not valid in untyped Yul. -// ParserError 5473: (250-255): Types are not valid in untyped Yul. -// ParserError 5473: (260-265): Types are not valid in untyped Yul. -// ParserError 5473: (270-275): Types are not valid in untyped Yul. -// ParserError 5473: (280-285): Types are not valid in untyped Yul. -// ParserError 5473: (290-295): Types are not valid in untyped Yul. -// ParserError 5473: (300-305): Types are not valid in untyped Yul. -// ParserError 5473: (310-315): Types are not valid in untyped Yul. -// ParserError 5473: (320-325): Types are not valid in untyped Yul. -// ParserError 5473: (330-335): Types are not valid in untyped Yul. -// ParserError 5473: (340-345): Types are not valid in untyped Yul. -// ParserError 5473: (350-355): Types are not valid in untyped Yul. -// ParserError 5473: (364-369): Types are not valid in untyped Yul. -// ParserError 5473: (374-379): Types are not valid in untyped Yul. -// ParserError 5473: (384-389): Types are not valid in untyped Yul. -// ParserError 5473: (394-399): Types are not valid in untyped Yul. -// ParserError 5473: (404-409): Types are not valid in untyped Yul. -// ParserError 5473: (414-419): Types are not valid in untyped Yul. -// ParserError 5473: (424-429): Types are not valid in untyped Yul. -// ParserError 5473: (434-439): Types are not valid in untyped Yul. -// ParserError 5473: (444-449): Types are not valid in untyped Yul. -// ParserError 5473: (454-459): Types are not valid in untyped Yul. -// ParserError 5473: (464-469): Types are not valid in untyped Yul. -// ParserError 5473: (474-479): Types are not valid in untyped Yul. -// ParserError 5473: (484-489): Types are not valid in untyped Yul. -// ParserError 5473: (494-499): Types are not valid in untyped Yul. -// ParserError 5473: (504-509): Types are not valid in untyped Yul. -// ParserError 5473: (514-519): Types are not valid in untyped Yul. -// ParserError 5473: (528-533): Types are not valid in untyped Yul. -// ParserError 5473: (538-543): Types are not valid in untyped Yul. -// ParserError 5473: (548-553): Types are not valid in untyped Yul. -// ParserError 5473: (558-563): Types are not valid in untyped Yul. -// ParserError 5473: (568-573): Types are not valid in untyped Yul. -// ParserError 5473: (578-583): Types are not valid in untyped Yul. -// ParserError 5473: (588-593): Types are not valid in untyped Yul. -// ParserError 5473: (598-603): Types are not valid in untyped Yul. -// ParserError 5473: (608-613): Types are not valid in untyped Yul. -// ParserError 5473: (618-623): Types are not valid in untyped Yul. -// ParserError 5473: (628-633): Types are not valid in untyped Yul. -// ParserError 5473: (638-643): Types are not valid in untyped Yul. -// ParserError 5473: (648-653): Types are not valid in untyped Yul. -// ParserError 5473: (658-663): Types are not valid in untyped Yul. -// ParserError 5473: (668-673): Types are not valid in untyped Yul. -// ParserError 5473: (678-683): Types are not valid in untyped Yul. -// ParserError 5473: (692-697): Types are not valid in untyped Yul. -// ParserError 5473: (702-707): Types are not valid in untyped Yul. -// ParserError 5473: (712-717): Types are not valid in untyped Yul. -// ParserError 5473: (722-727): Types are not valid in untyped Yul. -// ParserError 5473: (732-737): Types are not valid in untyped Yul. -// ParserError 5473: (742-747): Types are not valid in untyped Yul. -// ParserError 5473: (752-757): Types are not valid in untyped Yul. -// ParserError 5473: (762-767): Types are not valid in untyped Yul. -// ParserError 5473: (772-777): Types are not valid in untyped Yul. -// ParserError 5473: (782-787): Types are not valid in untyped Yul. -// ParserError 5473: (792-797): Types are not valid in untyped Yul. -// ParserError 5473: (802-807): Types are not valid in untyped Yul. -// ParserError 5473: (812-817): Types are not valid in untyped Yul. -// ParserError 5473: (822-827): Types are not valid in untyped Yul. -// ParserError 5473: (832-837): Types are not valid in untyped Yul. -// ParserError 5473: (842-847): Types are not valid in untyped Yul. -// ParserError 5473: (856-861): Types are not valid in untyped Yul. -// ParserError 5473: (866-871): Types are not valid in untyped Yul. -// ParserError 5473: (876-881): Types are not valid in untyped Yul. -// ParserError 5473: (886-891): Types are not valid in untyped Yul. -// ParserError 5473: (896-901): Types are not valid in untyped Yul. -// ParserError 5473: (906-911): Types are not valid in untyped Yul. -// ParserError 5473: (916-921): Types are not valid in untyped Yul. -// ParserError 5473: (926-931): Types are not valid in untyped Yul. -// ParserError 5473: (936-941): Types are not valid in untyped Yul. -// ParserError 5473: (946-951): Types are not valid in untyped Yul. -// ParserError 5473: (956-961): Types are not valid in untyped Yul. -// ParserError 5473: (966-971): Types are not valid in untyped Yul. -// ParserError 5473: (976-981): Types are not valid in untyped Yul. -// ParserError 5473: (986-991): Types are not valid in untyped Yul. -// ParserError 5473: (996-1001): Types are not valid in untyped Yul. -// ParserError 5473: (1006-1011): Types are not valid in untyped Yul. -// ParserError 5473: (1020-1025): Types are not valid in untyped Yul. -// ParserError 5473: (1030-1035): Types are not valid in untyped Yul. -// ParserError 5473: (1040-1045): Types are not valid in untyped Yul. -// ParserError 5473: (1050-1055): Types are not valid in untyped Yul. -// ParserError 5473: (1060-1065): Types are not valid in untyped Yul. -// ParserError 5473: (1070-1075): Types are not valid in untyped Yul. -// ParserError 5473: (1080-1085): Types are not valid in untyped Yul. -// ParserError 5473: (1090-1095): Types are not valid in untyped Yul. -// ParserError 5473: (1100-1105): Types are not valid in untyped Yul. -// ParserError 5473: (1110-1115): Types are not valid in untyped Yul. -// ParserError 5473: (1120-1125): Types are not valid in untyped Yul. -// ParserError 5473: (1130-1135): Types are not valid in untyped Yul. -// ParserError 5473: (1140-1145): Types are not valid in untyped Yul. -// ParserError 5473: (1150-1155): Types are not valid in untyped Yul. -// ParserError 5473: (1160-1165): Types are not valid in untyped Yul. -// ParserError 5473: (1170-1175): Types are not valid in untyped Yul. -// ParserError 5473: (1184-1189): Types are not valid in untyped Yul. -// ParserError 5473: (1194-1199): Types are not valid in untyped Yul. -// ParserError 5473: (1204-1209): Types are not valid in untyped Yul. -// ParserError 5473: (1214-1219): Types are not valid in untyped Yul. -// ParserError 5473: (1224-1229): Types are not valid in untyped Yul. -// ParserError 5473: (1234-1239): Types are not valid in untyped Yul. -// ParserError 5473: (1244-1249): Types are not valid in untyped Yul. -// ParserError 5473: (1254-1259): Types are not valid in untyped Yul. -// ParserError 5473: (1264-1269): Types are not valid in untyped Yul. -// ParserError 5473: (1274-1279): Types are not valid in untyped Yul. -// ParserError 5473: (1284-1289): Types are not valid in untyped Yul. -// ParserError 5473: (1294-1299): Types are not valid in untyped Yul. -// ParserError 5473: (1304-1309): Types are not valid in untyped Yul. -// ParserError 5473: (1314-1319): Types are not valid in untyped Yul. -// ParserError 5473: (1324-1329): Types are not valid in untyped Yul. -// ParserError 5473: (1334-1339): Types are not valid in untyped Yul. -// ParserError 5473: (1348-1353): Types are not valid in untyped Yul. -// ParserError 5473: (1358-1363): Types are not valid in untyped Yul. -// ParserError 5473: (1368-1373): Types are not valid in untyped Yul. -// ParserError 5473: (1378-1383): Types are not valid in untyped Yul. -// ParserError 5473: (1388-1393): Types are not valid in untyped Yul. -// ParserError 5473: (1398-1403): Types are not valid in untyped Yul. -// ParserError 5473: (1408-1413): Types are not valid in untyped Yul. -// ParserError 5473: (1418-1423): Types are not valid in untyped Yul. -// ParserError 5473: (1428-1433): Types are not valid in untyped Yul. -// ParserError 5473: (1438-1443): Types are not valid in untyped Yul. -// ParserError 5473: (1448-1453): Types are not valid in untyped Yul. -// ParserError 5473: (1458-1463): Types are not valid in untyped Yul. -// ParserError 5473: (1468-1473): Types are not valid in untyped Yul. -// ParserError 5473: (1478-1483): Types are not valid in untyped Yul. -// ParserError 5473: (1488-1493): Types are not valid in untyped Yul. -// ParserError 5473: (1498-1503): Types are not valid in untyped Yul. -// ParserError 5473: (1512-1517): Types are not valid in untyped Yul. -// ParserError 5473: (1522-1527): Types are not valid in untyped Yul. -// ParserError 5473: (1532-1537): Types are not valid in untyped Yul. -// ParserError 5473: (1542-1547): Types are not valid in untyped Yul. -// ParserError 5473: (1552-1557): Types are not valid in untyped Yul. -// ParserError 5473: (1562-1567): Types are not valid in untyped Yul. -// ParserError 5473: (1572-1577): Types are not valid in untyped Yul. -// ParserError 5473: (1582-1587): Types are not valid in untyped Yul. -// ParserError 5473: (1592-1597): Types are not valid in untyped Yul. -// ParserError 5473: (1602-1607): Types are not valid in untyped Yul. -// ParserError 5473: (1612-1617): Types are not valid in untyped Yul. -// ParserError 5473: (1622-1627): Types are not valid in untyped Yul. -// ParserError 5473: (1632-1637): Types are not valid in untyped Yul. -// ParserError 5473: (1642-1647): Types are not valid in untyped Yul. -// ParserError 5473: (1652-1657): Types are not valid in untyped Yul. -// ParserError 5473: (1662-1667): Types are not valid in untyped Yul. -// ParserError 5473: (1676-1681): Types are not valid in untyped Yul. -// ParserError 5473: (1686-1691): Types are not valid in untyped Yul. -// ParserError 5473: (1696-1701): Types are not valid in untyped Yul. -// ParserError 5473: (1706-1711): Types are not valid in untyped Yul. -// ParserError 5473: (1716-1721): Types are not valid in untyped Yul. -// ParserError 5473: (1726-1731): Types are not valid in untyped Yul. -// ParserError 5473: (1736-1741): Types are not valid in untyped Yul. -// ParserError 5473: (1746-1751): Types are not valid in untyped Yul. -// ParserError 5473: (1756-1761): Types are not valid in untyped Yul. -// ParserError 5473: (1766-1771): Types are not valid in untyped Yul. -// ParserError 5473: (1776-1781): Types are not valid in untyped Yul. -// ParserError 5473: (1786-1791): Types are not valid in untyped Yul. -// ParserError 5473: (1796-1801): Types are not valid in untyped Yul. -// ParserError 5473: (1806-1811): Types are not valid in untyped Yul. -// ParserError 5473: (1816-1821): Types are not valid in untyped Yul. -// ParserError 5473: (1826-1831): Types are not valid in untyped Yul. -// ParserError 5473: (1840-1845): Types are not valid in untyped Yul. -// ParserError 5473: (1850-1855): Types are not valid in untyped Yul. -// ParserError 5473: (1860-1865): Types are not valid in untyped Yul. -// ParserError 5473: (1870-1875): Types are not valid in untyped Yul. -// ParserError 5473: (1880-1885): Types are not valid in untyped Yul. -// ParserError 5473: (1890-1895): Types are not valid in untyped Yul. -// ParserError 5473: (1900-1905): Types are not valid in untyped Yul. -// ParserError 5473: (1910-1915): Types are not valid in untyped Yul. -// ParserError 5473: (1920-1925): Types are not valid in untyped Yul. -// ParserError 5473: (1930-1935): Types are not valid in untyped Yul. -// ParserError 5473: (1940-1945): Types are not valid in untyped Yul. -// ParserError 5473: (1950-1955): Types are not valid in untyped Yul. -// ParserError 5473: (1960-1965): Types are not valid in untyped Yul. -// ParserError 5473: (1970-1975): Types are not valid in untyped Yul. -// ParserError 5473: (1980-1985): Types are not valid in untyped Yul. -// ParserError 5473: (1990-1995): Types are not valid in untyped Yul. -// ParserError 5473: (2004-2009): Types are not valid in untyped Yul. -// ParserError 5473: (2014-2019): Types are not valid in untyped Yul. -// ParserError 5473: (2024-2029): Types are not valid in untyped Yul. -// ParserError 5473: (2034-2039): Types are not valid in untyped Yul. -// ParserError 5473: (2044-2049): Types are not valid in untyped Yul. -// ParserError 5473: (2054-2059): Types are not valid in untyped Yul. -// ParserError 5473: (2064-2069): Types are not valid in untyped Yul. -// ParserError 5473: (2074-2079): Types are not valid in untyped Yul. -// ParserError 5473: (2084-2089): Types are not valid in untyped Yul. -// ParserError 5473: (2094-2099): Types are not valid in untyped Yul. -// ParserError 5473: (2104-2109): Types are not valid in untyped Yul. -// ParserError 5473: (2114-2119): Types are not valid in untyped Yul. -// ParserError 5473: (2124-2129): Types are not valid in untyped Yul. -// ParserError 5473: (2134-2139): Types are not valid in untyped Yul. -// ParserError 5473: (2144-2149): Types are not valid in untyped Yul. -// ParserError 5473: (2154-2159): Types are not valid in untyped Yul. -// ParserError 5473: (2168-2173): Types are not valid in untyped Yul. -// ParserError 5473: (2178-2183): Types are not valid in untyped Yul. -// ParserError 5473: (2188-2193): Types are not valid in untyped Yul. -// ParserError 5473: (2198-2203): Types are not valid in untyped Yul. -// ParserError 5473: (2208-2213): Types are not valid in untyped Yul. -// ParserError 5473: (2218-2223): Types are not valid in untyped Yul. -// ParserError 5473: (2228-2233): Types are not valid in untyped Yul. -// ParserError 5473: (2238-2243): Types are not valid in untyped Yul. -// ParserError 5473: (2248-2253): Types are not valid in untyped Yul. -// ParserError 5473: (2258-2263): Types are not valid in untyped Yul. -// ParserError 5473: (2268-2273): Types are not valid in untyped Yul. -// ParserError 5473: (2278-2283): Types are not valid in untyped Yul. -// ParserError 5473: (2288-2293): Types are not valid in untyped Yul. -// ParserError 5473: (2298-2303): Types are not valid in untyped Yul. -// ParserError 5473: (2308-2313): Types are not valid in untyped Yul. -// ParserError 5473: (2318-2323): Types are not valid in untyped Yul. -// ParserError 5473: (2332-2337): Types are not valid in untyped Yul. -// ParserError 5473: (2342-2347): Types are not valid in untyped Yul. -// ParserError 5473: (2352-2357): Types are not valid in untyped Yul. -// ParserError 5473: (2362-2367): Types are not valid in untyped Yul. -// ParserError 5473: (2372-2377): Types are not valid in untyped Yul. -// ParserError 5473: (2382-2387): Types are not valid in untyped Yul. -// ParserError 5473: (2392-2397): Types are not valid in untyped Yul. -// ParserError 5473: (2402-2407): Types are not valid in untyped Yul. -// ParserError 5473: (2412-2417): Types are not valid in untyped Yul. -// ParserError 5473: (2422-2427): Types are not valid in untyped Yul. -// ParserError 5473: (2432-2437): Types are not valid in untyped Yul. -// ParserError 5473: (2442-2447): Types are not valid in untyped Yul. -// ParserError 5473: (2452-2457): Types are not valid in untyped Yul. -// ParserError 5473: (2462-2467): Types are not valid in untyped Yul. -// ParserError 5473: (2472-2477): Types are not valid in untyped Yul. -// ParserError 5473: (2482-2487): Types are not valid in untyped Yul. -// ParserError 5473: (2496-2501): Types are not valid in untyped Yul. -// ParserError 5473: (2506-2511): Types are not valid in untyped Yul. -// ParserError 5473: (2516-2521): Types are not valid in untyped Yul. -// ParserError 5473: (2526-2531): Types are not valid in untyped Yul. -// ParserError 5473: (2536-2541): Types are not valid in untyped Yul. -// ParserError 5473: (2546-2551): Types are not valid in untyped Yul. -// ParserError 5473: (2556-2561): Types are not valid in untyped Yul. -// ParserError 5473: (2566-2571): Types are not valid in untyped Yul. -// ParserError 5473: (2576-2581): Types are not valid in untyped Yul. -// ParserError 5473: (2586-2591): Types are not valid in untyped Yul. -// ParserError 5473: (2596-2601): Types are not valid in untyped Yul. -// ParserError 5473: (2606-2611): Types are not valid in untyped Yul. -// ParserError 5473: (2616-2621): Types are not valid in untyped Yul. -// ParserError 5473: (2626-2631): Types are not valid in untyped Yul. -// ParserError 5473: (2636-2641): Types are not valid in untyped Yul. -// ParserError 5473: (2646-2651): Types are not valid in untyped Yul. -// ParserError 5473: (2660-2665): Types are not valid in untyped Yul. -// ParserError 5473: (2670-2675): Types are not valid in untyped Yul. -// ParserError 5473: (2680-2685): Types are not valid in untyped Yul. -// ParserError 5473: (2690-2695): Types are not valid in untyped Yul. -// ParserError 5473: (2700-2705): Types are not valid in untyped Yul. -// ParserError 5473: (2710-2715): Types are not valid in untyped Yul. -// ParserError 5473: (2720-2725): Types are not valid in untyped Yul. -// ParserError 5473: (2730-2735): Types are not valid in untyped Yul. -// ParserError 5473: (2740-2745): Types are not valid in untyped Yul. -// ParserError 5473: (2750-2755): Types are not valid in untyped Yul. -// ParserError 5473: (2760-2765): Types are not valid in untyped Yul. -// ParserError 5473: (2770-2775): Types are not valid in untyped Yul. -// ParserError 5473: (2780-2785): Types are not valid in untyped Yul. -// ParserError 5473: (2790-2795): Types are not valid in untyped Yul. -// ParserError 5473: (2800-2805): Types are not valid in untyped Yul. -// ParserError 5473: (2810-2815): Types are not valid in untyped Yul. +// DeclarationError 4990: (224-227): Variable x00 used before it was declared. +// DeclarationError 4990: (237-240): Variable x01 used before it was declared. +// DeclarationError 4990: (250-253): Variable x02 used before it was declared. +// DeclarationError 4990: (263-266): Variable x03 used before it was declared. +// DeclarationError 4990: (276-279): Variable x04 used before it was declared. +// DeclarationError 4990: (289-292): Variable x05 used before it was declared. +// DeclarationError 4990: (302-305): Variable x06 used before it was declared. +// DeclarationError 4990: (315-318): Variable x07 used before it was declared. +// DeclarationError 4990: (332-335): Variable x08 used before it was declared. +// DeclarationError 4990: (345-348): Variable x09 used before it was declared. +// DeclarationError 4990: (358-361): Variable x0a used before it was declared. +// DeclarationError 4990: (371-374): Variable x0b used before it was declared. +// DeclarationError 4990: (384-387): Variable x0c used before it was declared. +// DeclarationError 4990: (397-400): Variable x0d used before it was declared. +// DeclarationError 4990: (410-413): Variable x0e used before it was declared. +// DeclarationError 4990: (423-426): Variable x0f used before it was declared. +// DeclarationError 4990: (440-443): Variable x10 used before it was declared. +// DeclarationError 4990: (453-456): Variable x11 used before it was declared. +// DeclarationError 4990: (466-469): Variable x12 used before it was declared. +// DeclarationError 4990: (479-482): Variable x13 used before it was declared. +// DeclarationError 4990: (492-495): Variable x14 used before it was declared. +// DeclarationError 4990: (505-508): Variable x15 used before it was declared. +// DeclarationError 4990: (518-521): Variable x16 used before it was declared. +// DeclarationError 4990: (531-534): Variable x17 used before it was declared. +// DeclarationError 4990: (548-551): Variable x18 used before it was declared. +// DeclarationError 4990: (561-564): Variable x19 used before it was declared. +// DeclarationError 4990: (574-577): Variable x1a used before it was declared. +// DeclarationError 4990: (587-590): Variable x1b used before it was declared. +// DeclarationError 4990: (600-603): Variable x1c used before it was declared. +// DeclarationError 4990: (613-616): Variable x1d used before it was declared. +// DeclarationError 4990: (626-629): Variable x1e used before it was declared. +// DeclarationError 4990: (639-642): Variable x1f used before it was declared. +// DeclarationError 4990: (656-659): Variable x20 used before it was declared. +// DeclarationError 4990: (669-672): Variable x21 used before it was declared. +// DeclarationError 4990: (682-685): Variable x22 used before it was declared. +// DeclarationError 4990: (695-698): Variable x23 used before it was declared. +// DeclarationError 4990: (708-711): Variable x24 used before it was declared. +// DeclarationError 4990: (721-724): Variable x25 used before it was declared. +// DeclarationError 4990: (734-737): Variable x26 used before it was declared. +// DeclarationError 4990: (747-750): Variable x27 used before it was declared. +// DeclarationError 4990: (764-767): Variable x28 used before it was declared. +// DeclarationError 4990: (777-780): Variable x29 used before it was declared. +// DeclarationError 4990: (790-793): Variable x2a used before it was declared. +// DeclarationError 4990: (803-806): Variable x2b used before it was declared. +// DeclarationError 4990: (816-819): Variable x2c used before it was declared. +// DeclarationError 4990: (829-832): Variable x2d used before it was declared. +// DeclarationError 4990: (842-845): Variable x2e used before it was declared. +// DeclarationError 4990: (855-858): Variable x2f used before it was declared. +// DeclarationError 4990: (872-875): Variable x30 used before it was declared. +// DeclarationError 4990: (885-888): Variable x31 used before it was declared. +// DeclarationError 4990: (898-901): Variable x32 used before it was declared. +// DeclarationError 4990: (911-914): Variable x33 used before it was declared. +// DeclarationError 4990: (924-927): Variable x34 used before it was declared. +// DeclarationError 4990: (937-940): Variable x35 used before it was declared. +// DeclarationError 4990: (950-953): Variable x36 used before it was declared. +// DeclarationError 4990: (963-966): Variable x37 used before it was declared. +// DeclarationError 4990: (980-983): Variable x38 used before it was declared. +// DeclarationError 4990: (993-996): Variable x39 used before it was declared. +// DeclarationError 4990: (1006-1009): Variable x3a used before it was declared. +// DeclarationError 4990: (1019-1022): Variable x3b used before it was declared. +// DeclarationError 4990: (1032-1035): Variable x3c used before it was declared. +// DeclarationError 4990: (1045-1048): Variable x3d used before it was declared. +// DeclarationError 4990: (1058-1061): Variable x3e used before it was declared. +// DeclarationError 4990: (1071-1074): Variable x3f used before it was declared. +// DeclarationError 4990: (1088-1091): Variable x40 used before it was declared. +// DeclarationError 4990: (1101-1104): Variable x41 used before it was declared. +// DeclarationError 4990: (1114-1117): Variable x42 used before it was declared. +// DeclarationError 4990: (1127-1130): Variable x43 used before it was declared. +// DeclarationError 4990: (1140-1143): Variable x44 used before it was declared. +// DeclarationError 4990: (1153-1156): Variable x45 used before it was declared. +// DeclarationError 4990: (1166-1169): Variable x46 used before it was declared. +// DeclarationError 4990: (1179-1182): Variable x47 used before it was declared. +// DeclarationError 4990: (1196-1199): Variable x48 used before it was declared. +// DeclarationError 4990: (1209-1212): Variable x49 used before it was declared. +// DeclarationError 4990: (1222-1225): Variable x4a used before it was declared. +// DeclarationError 4990: (1235-1238): Variable x4b used before it was declared. +// DeclarationError 4990: (1248-1251): Variable x4c used before it was declared. +// DeclarationError 4990: (1261-1264): Variable x4d used before it was declared. +// DeclarationError 4990: (1274-1277): Variable x4e used before it was declared. +// DeclarationError 4990: (1287-1290): Variable x4f used before it was declared. +// DeclarationError 4990: (1304-1307): Variable x50 used before it was declared. +// DeclarationError 4990: (1317-1320): Variable x51 used before it was declared. +// DeclarationError 4990: (1330-1333): Variable x52 used before it was declared. +// DeclarationError 4990: (1343-1346): Variable x53 used before it was declared. +// DeclarationError 4990: (1356-1359): Variable x54 used before it was declared. +// DeclarationError 4990: (1369-1372): Variable x55 used before it was declared. +// DeclarationError 4990: (1382-1385): Variable x56 used before it was declared. +// DeclarationError 4990: (1395-1398): Variable x57 used before it was declared. +// DeclarationError 4990: (1412-1415): Variable x58 used before it was declared. +// DeclarationError 4990: (1425-1428): Variable x59 used before it was declared. +// DeclarationError 4990: (1438-1441): Variable x5a used before it was declared. +// DeclarationError 4990: (1451-1454): Variable x5b used before it was declared. +// DeclarationError 4990: (1464-1467): Variable x5c used before it was declared. +// DeclarationError 4990: (1477-1480): Variable x5d used before it was declared. +// DeclarationError 4990: (1490-1493): Variable x5e used before it was declared. +// DeclarationError 4990: (1503-1506): Variable x5f used before it was declared. +// DeclarationError 4990: (1520-1523): Variable x60 used before it was declared. +// DeclarationError 4990: (1533-1536): Variable x61 used before it was declared. +// DeclarationError 4990: (1546-1549): Variable x62 used before it was declared. +// DeclarationError 4990: (1559-1562): Variable x63 used before it was declared. +// DeclarationError 4990: (1572-1575): Variable x64 used before it was declared. +// DeclarationError 4990: (1585-1588): Variable x65 used before it was declared. +// DeclarationError 4990: (1598-1601): Variable x66 used before it was declared. +// DeclarationError 4990: (1611-1614): Variable x67 used before it was declared. +// DeclarationError 4990: (1628-1631): Variable x68 used before it was declared. +// DeclarationError 4990: (1641-1644): Variable x69 used before it was declared. +// DeclarationError 4990: (1654-1657): Variable x6a used before it was declared. +// DeclarationError 4990: (1667-1670): Variable x6b used before it was declared. +// DeclarationError 4990: (1680-1683): Variable x6c used before it was declared. +// DeclarationError 4990: (1693-1696): Variable x6d used before it was declared. +// DeclarationError 4990: (1706-1709): Variable x6e used before it was declared. +// DeclarationError 4990: (1719-1722): Variable x6f used before it was declared. +// DeclarationError 4990: (1736-1739): Variable x70 used before it was declared. +// DeclarationError 4990: (1749-1752): Variable x71 used before it was declared. +// DeclarationError 4990: (1762-1765): Variable x72 used before it was declared. +// DeclarationError 4990: (1775-1778): Variable x73 used before it was declared. +// DeclarationError 4990: (1788-1791): Variable x74 used before it was declared. +// DeclarationError 4990: (1801-1804): Variable x75 used before it was declared. +// DeclarationError 4990: (1814-1817): Variable x76 used before it was declared. +// DeclarationError 4990: (1827-1830): Variable x77 used before it was declared. +// DeclarationError 4990: (1844-1847): Variable x78 used before it was declared. +// DeclarationError 4990: (1857-1860): Variable x79 used before it was declared. +// DeclarationError 4990: (1870-1873): Variable x7a used before it was declared. +// DeclarationError 4990: (1883-1886): Variable x7b used before it was declared. +// DeclarationError 4990: (1896-1899): Variable x7c used before it was declared. +// DeclarationError 4990: (1909-1912): Variable x7d used before it was declared. +// DeclarationError 4990: (1922-1925): Variable x7e used before it was declared. +// DeclarationError 4990: (1935-1938): Variable x7f used before it was declared. +// DeclarationError 4990: (1952-1955): Variable x80 used before it was declared. +// DeclarationError 4990: (1965-1968): Variable x81 used before it was declared. +// DeclarationError 4990: (1978-1981): Variable x82 used before it was declared. +// DeclarationError 4990: (1991-1994): Variable x83 used before it was declared. +// DeclarationError 4990: (2004-2007): Variable x84 used before it was declared. +// DeclarationError 4990: (2017-2020): Variable x85 used before it was declared. +// DeclarationError 4990: (2030-2033): Variable x86 used before it was declared. +// DeclarationError 4990: (2043-2046): Variable x87 used before it was declared. +// DeclarationError 4990: (2060-2063): Variable x88 used before it was declared. +// DeclarationError 4990: (2073-2076): Variable x89 used before it was declared. +// DeclarationError 4990: (2086-2089): Variable x8a used before it was declared. +// DeclarationError 4990: (2099-2102): Variable x8b used before it was declared. +// DeclarationError 4990: (2112-2115): Variable x8c used before it was declared. +// DeclarationError 4990: (2125-2128): Variable x8d used before it was declared. +// DeclarationError 4990: (2138-2141): Variable x8e used before it was declared. +// DeclarationError 4990: (2151-2154): Variable x8f used before it was declared. +// DeclarationError 4990: (2168-2171): Variable x90 used before it was declared. +// DeclarationError 4990: (2181-2184): Variable x91 used before it was declared. +// DeclarationError 4990: (2194-2197): Variable x92 used before it was declared. +// DeclarationError 4990: (2207-2210): Variable x93 used before it was declared. +// DeclarationError 4990: (2220-2223): Variable x94 used before it was declared. +// DeclarationError 4990: (2233-2236): Variable x95 used before it was declared. +// DeclarationError 4990: (2246-2249): Variable x96 used before it was declared. +// DeclarationError 4990: (2259-2262): Variable x97 used before it was declared. +// DeclarationError 4990: (2276-2279): Variable x98 used before it was declared. +// DeclarationError 4990: (2289-2292): Variable x99 used before it was declared. +// DeclarationError 4990: (2302-2305): Variable x9a used before it was declared. +// DeclarationError 4990: (2315-2318): Variable x9b used before it was declared. +// DeclarationError 4990: (2328-2331): Variable x9c used before it was declared. +// DeclarationError 4990: (2341-2344): Variable x9d used before it was declared. +// DeclarationError 4990: (2354-2357): Variable x9e used before it was declared. +// DeclarationError 4990: (2367-2370): Variable x9f used before it was declared. +// DeclarationError 4990: (2384-2387): Variable xa0 used before it was declared. +// DeclarationError 4990: (2397-2400): Variable xa1 used before it was declared. +// DeclarationError 4990: (2410-2413): Variable xa2 used before it was declared. +// DeclarationError 4990: (2423-2426): Variable xa3 used before it was declared. +// DeclarationError 4990: (2436-2439): Variable xa4 used before it was declared. +// DeclarationError 4990: (2449-2452): Variable xa5 used before it was declared. +// DeclarationError 4990: (2462-2465): Variable xa6 used before it was declared. +// DeclarationError 4990: (2475-2478): Variable xa7 used before it was declared. +// DeclarationError 4990: (2492-2495): Variable xa8 used before it was declared. +// DeclarationError 4990: (2505-2508): Variable xa9 used before it was declared. +// DeclarationError 4990: (2518-2521): Variable xaa used before it was declared. +// DeclarationError 4990: (2531-2534): Variable xab used before it was declared. +// DeclarationError 4990: (2544-2547): Variable xac used before it was declared. +// DeclarationError 4990: (2557-2560): Variable xad used before it was declared. +// DeclarationError 4990: (2570-2573): Variable xae used before it was declared. +// DeclarationError 4990: (2583-2586): Variable xaf used before it was declared. +// DeclarationError 4990: (2600-2603): Variable xb0 used before it was declared. +// DeclarationError 4990: (2613-2616): Variable xb1 used before it was declared. +// DeclarationError 4990: (2626-2629): Variable xb2 used before it was declared. +// DeclarationError 4990: (2639-2642): Variable xb3 used before it was declared. +// DeclarationError 4990: (2652-2655): Variable xb4 used before it was declared. +// DeclarationError 4990: (2665-2668): Variable xb5 used before it was declared. +// DeclarationError 4990: (2678-2681): Variable xb6 used before it was declared. +// DeclarationError 4990: (2691-2694): Variable xb7 used before it was declared. +// DeclarationError 4990: (2708-2711): Variable xb8 used before it was declared. +// DeclarationError 4990: (2721-2724): Variable xb9 used before it was declared. +// DeclarationError 4990: (2734-2737): Variable xba used before it was declared. +// DeclarationError 4990: (2747-2750): Variable xbb used before it was declared. +// DeclarationError 4990: (2760-2763): Variable xbc used before it was declared. +// DeclarationError 4990: (2773-2776): Variable xbd used before it was declared. +// DeclarationError 4990: (2786-2789): Variable xbe used before it was declared. +// DeclarationError 4990: (2799-2802): Variable xbf used before it was declared. +// DeclarationError 4990: (2816-2819): Variable xc0 used before it was declared. +// DeclarationError 4990: (2829-2832): Variable xc1 used before it was declared. +// DeclarationError 4990: (2842-2845): Variable xc2 used before it was declared. +// DeclarationError 4990: (2855-2858): Variable xc3 used before it was declared. +// DeclarationError 4990: (2868-2871): Variable xc4 used before it was declared. +// DeclarationError 4990: (2881-2884): Variable xc5 used before it was declared. +// DeclarationError 4990: (2894-2897): Variable xc6 used before it was declared. +// DeclarationError 4990: (2907-2910): Variable xc7 used before it was declared. +// DeclarationError 4990: (2924-2927): Variable xc8 used before it was declared. +// DeclarationError 4990: (2937-2940): Variable xc9 used before it was declared. +// DeclarationError 4990: (2950-2953): Variable xca used before it was declared. +// DeclarationError 4990: (2963-2966): Variable xcb used before it was declared. +// DeclarationError 4990: (2976-2979): Variable xcc used before it was declared. +// DeclarationError 4990: (2989-2992): Variable xcd used before it was declared. +// DeclarationError 4990: (3002-3005): Variable xce used before it was declared. +// DeclarationError 4990: (3015-3018): Variable xcf used before it was declared. +// DeclarationError 4990: (3032-3035): Variable xd0 used before it was declared. +// DeclarationError 4990: (3045-3048): Variable xd1 used before it was declared. +// DeclarationError 4990: (3058-3061): Variable xd2 used before it was declared. +// DeclarationError 4990: (3071-3074): Variable xd3 used before it was declared. +// DeclarationError 4990: (3084-3087): Variable xd4 used before it was declared. +// DeclarationError 4990: (3097-3100): Variable xd5 used before it was declared. +// DeclarationError 4990: (3110-3113): Variable xd6 used before it was declared. +// DeclarationError 4990: (3123-3126): Variable xd7 used before it was declared. +// DeclarationError 4990: (3140-3143): Variable xd8 used before it was declared. +// DeclarationError 4990: (3153-3156): Variable xd9 used before it was declared. +// DeclarationError 4990: (3166-3169): Variable xda used before it was declared. +// DeclarationError 4990: (3179-3182): Variable xdb used before it was declared. +// DeclarationError 4990: (3192-3195): Variable xdc used before it was declared. +// DeclarationError 4990: (3205-3208): Variable xdd used before it was declared. +// DeclarationError 4990: (3218-3221): Variable xde used before it was declared. +// DeclarationError 4990: (3231-3234): Variable xdf used before it was declared. +// DeclarationError 4990: (3248-3251): Variable xe0 used before it was declared. +// DeclarationError 4990: (3261-3264): Variable xe1 used before it was declared. +// DeclarationError 4990: (3274-3277): Variable xe2 used before it was declared. +// DeclarationError 4990: (3287-3290): Variable xe3 used before it was declared. +// DeclarationError 4990: (3300-3303): Variable xe4 used before it was declared. +// DeclarationError 4990: (3313-3316): Variable xe5 used before it was declared. +// DeclarationError 4990: (3326-3329): Variable xe6 used before it was declared. +// DeclarationError 4990: (3339-3342): Variable xe7 used before it was declared. +// DeclarationError 4990: (3356-3359): Variable xe8 used before it was declared. +// DeclarationError 4990: (3369-3372): Variable xe9 used before it was declared. +// DeclarationError 4990: (3382-3385): Variable xea used before it was declared. +// DeclarationError 4990: (3395-3398): Variable xeb used before it was declared. +// DeclarationError 4990: (3408-3411): Variable xec used before it was declared. +// DeclarationError 4990: (3421-3424): Variable xed used before it was declared. +// DeclarationError 4990: (3434-3437): Variable xee used before it was declared. +// DeclarationError 4990: (3447-3450): Variable xef used before it was declared. +// DeclarationError 4990: (3464-3467): Variable xf0 used before it was declared. +// DeclarationError 4990: (3477-3480): Variable xf1 used before it was declared. +// DeclarationError 4990: (3490-3493): Variable xf2 used before it was declared. +// DeclarationError 4990: (3503-3506): Variable xf3 used before it was declared. +// DeclarationError 4990: (3516-3519): Variable xf4 used before it was declared. +// DeclarationError 4990: (3529-3532): Variable xf5 used before it was declared. +// DeclarationError 4990: (3542-3545): Variable xf6 used before it was declared. +// DeclarationError 4990: (3555-3558): Variable xf7 used before it was declared. +// DeclarationError 4990: (3572-3575): Variable xf8 used before it was declared. +// DeclarationError 4990: (3585-3588): Variable xf9 used before it was declared. +// DeclarationError 4990: (3598-3601): Variable xfa used before it was declared. +// DeclarationError 4990: (3611-3614): Variable xfb used before it was declared. +// DeclarationError 4990: (3624-3627): Variable xfc used before it was declared. +// DeclarationError 4990: (3637-3640): Variable xfd used before it was declared. +// DeclarationError 4990: (3650-3653): Variable xfe used before it was declared. +// DeclarationError 4990: (3663-3666): Variable xff used before it was declared. // Warning 4013: There are more than 256 errors. Aborting. From c5b1ac3532958eed2288e17860171d5e0eb46ee3 Mon Sep 17 00:00:00 2001 From: Ardis Lu Date: Fri, 26 Jul 2024 20:50:59 -0700 Subject: [PATCH 0379/1022] Fix showProvedSafe flag and JSON key name Extend title underline --- docs/smtchecker.rst | 4 ++-- docs/using-the-compiler.rst | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/smtchecker.rst b/docs/smtchecker.rst index fc7978256a9d..92aaa847c921 100644 --- a/docs/smtchecker.rst +++ b/docs/smtchecker.rst @@ -488,8 +488,8 @@ Proved Targets If there are any proved targets, the SMTChecker issues one warning per engine stating how many targets were proved. If the user wishes to see all the specific -proved targets, the CLI option ``--model-checker-show-proved`` and -the JSON option ``settings.modelChecker.showProved = true`` can be used. +proved targets, the CLI option ``--model-checker-show-proved-safe`` and +the JSON option ``settings.modelChecker.showProvedSafe = true`` can be used. Unproved Targets ================ diff --git a/docs/using-the-compiler.rst b/docs/using-the-compiler.rst index 97994e1326ff..004bb4a6141d 100644 --- a/docs/using-the-compiler.rst +++ b/docs/using-the-compiler.rst @@ -481,7 +481,7 @@ Input Description // Choose which types of invariants should be reported to the user: contract, reentrancy. "invariants": ["contract", "reentrancy"], // Choose whether to output all proved targets. The default is `false`. - "showProved": true, + "showProvedSafe": true, // Choose whether to output all unproved targets. The default is `false`. "showUnproved": true, // Choose whether to output all unsupported language features. The default is `false`. From 82a3071b854a7051899e2fc09cc7aa29439f4e70 Mon Sep 17 00:00:00 2001 From: Martin Blicha Date: Mon, 19 Aug 2024 21:59:09 +0200 Subject: [PATCH 0380/1022] SMTChecker: Introduce first draft of Z3CHCSmtlib2Interface This commit introduces the interface class without actually using it. The actual switch will be done later, after all things are set up. --- libsmtutil/CHCSmtLib2Interface.cpp | 4 +- libsolidity/formal/Z3CHCSmtLib2Interface.cpp | 222 +++++++++++++++++++ libsolidity/formal/Z3CHCSmtLib2Interface.h | 50 +++++ 3 files changed, 275 insertions(+), 1 deletion(-) create mode 100644 libsolidity/formal/Z3CHCSmtLib2Interface.cpp create mode 100644 libsolidity/formal/Z3CHCSmtLib2Interface.h diff --git a/libsmtutil/CHCSmtLib2Interface.cpp b/libsmtutil/CHCSmtLib2Interface.cpp index 6db1c6e876d0..6e535f09930f 100644 --- a/libsmtutil/CHCSmtLib2Interface.cpp +++ b/libsmtutil/CHCSmtLib2Interface.cpp @@ -96,7 +96,9 @@ std::tuple CHCSmtLib2Inte std::string response = querySolver(query); CheckResult result; - // TODO proper parsing + // NOTE: Our internal semantics is UNSAT -> SAFE and SAT -> UNSAFE, which corresponds to usual SMT-based model checking + // However, with CHC solvers, the meaning is flipped, UNSAT -> UNSAFE and SAT -> SAFE. + // So we have to flip the answer. if (boost::starts_with(response, "sat")) { auto maybeInvariants = invariantsFromSolverResponse(response); diff --git a/libsolidity/formal/Z3CHCSmtLib2Interface.cpp b/libsolidity/formal/Z3CHCSmtLib2Interface.cpp new file mode 100644 index 000000000000..cd06a9d3313a --- /dev/null +++ b/libsolidity/formal/Z3CHCSmtLib2Interface.cpp @@ -0,0 +1,222 @@ +/* + This file is part of solidity. + + solidity is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + solidity is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with solidity. If not, see . +*/ +// SPDX-License-Identifier: GPL-3.0 + +#include + +#include + +#include + +#include + +#include + +using namespace solidity::frontend::smt; +using namespace solidity::smtutil; + +Z3CHCSmtLib2Interface::Z3CHCSmtLib2Interface( + frontend::ReadCallback::Callback _smtCallback, + std::optional _queryTimeout, + bool _computeInvariants +): CHCSmtLib2Interface({}, std::move(_smtCallback), _queryTimeout), m_computeInvariants(_computeInvariants) +{ +} + +void Z3CHCSmtLib2Interface::setupSmtCallback(bool _enablePreprocessing) +{ + if (auto* universalCallback = m_smtCallback.target()) + universalCallback->smtCommand().setZ3(m_queryTimeout, _enablePreprocessing, m_computeInvariants); +} + +std::tuple Z3CHCSmtLib2Interface::query(smtutil::Expression const& _block) +{ + setupSmtCallback(true); + std::string query = dumpQuery(_block); + std::string response = querySolver(query); + // NOTE: Our internal semantics is UNSAT -> SAFE and SAT -> UNSAFE, which corresponds to usual SMT-based model checking + // However, with CHC solvers, the meaning is flipped, UNSAT -> UNSAFE and SAT -> SAFE. + // So we have to flip the answer. + if (boost::starts_with(response, "unsat")) + { + // Repeat the query with preprocessing disabled, to get the full proof + setupSmtCallback(false); + query = "(set-option :produce-proofs true)" + query + "\n(get-proof)"; + response = querySolver(query); + setupSmtCallback(true); + if (!boost::starts_with(response, "unsat")) + return {CheckResult::SATISFIABLE, Expression(true), {}}; + return {CheckResult::SATISFIABLE, Expression(true), graphFromZ3Answer(response)}; + } + + CheckResult result; + if (boost::starts_with(response, "sat")) + { + auto maybeInvariants = invariantsFromSolverResponse(response); + return {CheckResult::UNSATISFIABLE, maybeInvariants.value_or(Expression(true)), {}}; + } + else if (boost::starts_with(response, "unknown")) + result = CheckResult::UNKNOWN; + else + result = CheckResult::ERROR; + + return {result, Expression(true), {}}; +} + + +CHCSolverInterface::CexGraph Z3CHCSmtLib2Interface::graphFromZ3Answer(std::string const& _proof) const +{ + std::stringstream ss(_proof); + std::string answer; + ss >> answer; + smtAssert(answer == "unsat"); + + SMTLib2Parser parser(ss); + if (parser.isEOF()) // No proof from Z3 + return {}; + // For some reason Z3 outputs everything as a single s-expression + SMTLib2Expression parsedOutput; + try + { + parsedOutput = parser.parseExpression(); + } + catch (SMTLib2Parser::ParsingException&) + { + return {}; + } + solAssert(parser.isEOF()); + solAssert(!isAtom(parsedOutput)); + auto& commands = asSubExpressions(parsedOutput); + ScopedParser expressionParser(m_context); + for (auto& command: commands) + { + if (isAtom(command)) + continue; + + auto const& args = asSubExpressions(command); + solAssert(args.size() > 0); + auto const& head = args[0]; + if (!isAtom(head)) + continue; + + // Z3 can introduce new helper predicates to be used in the proof + // e.g., "(declare-fun query!0 (Bool Bool Bool Int Int Bool Bool Bool Bool Bool Bool Bool Int) Bool)" + if (asAtom(head) == "declare-fun") + { + solAssert(args.size() == 4); + auto const& name = args[1]; + auto const& domainSorts = args[2]; + auto const& codomainSort = args[3]; + solAssert(isAtom(name)); + solAssert(!isAtom(domainSorts)); + expressionParser.addVariableDeclaration(asAtom(name), expressionParser.toSort(codomainSort)); + } + // The subexpression starting with "proof" contains the whole proof, which we need to transform to our internal + // representation + else if (asAtom(head) == "proof") + { + inlineLetExpressions(command); + return graphFromSMTLib2Expression(command, expressionParser); + } + } + return {}; +} + +CHCSolverInterface::CexGraph Z3CHCSmtLib2Interface::graphFromSMTLib2Expression( + SMTLib2Expression const& _proof, + ScopedParser& _context +) +{ + auto fact = [](SMTLib2Expression const& _node) -> SMTLib2Expression const& { + if (isAtom(_node)) + return _node; + smtAssert(!asSubExpressions(_node).empty()); + return asSubExpressions(_node).back(); + }; + smtAssert(!isAtom(_proof)); + auto const& proofArgs = asSubExpressions(_proof); + smtAssert(proofArgs.size() == 2); + smtAssert(isAtom(proofArgs.at(0)) && asAtom(proofArgs.at(0)) == "proof"); + auto const& proofNode = proofArgs.at(1); + auto const& derivedFact = fact(proofNode); + if (isAtom(proofNode) || !isAtom(derivedFact) || asAtom(derivedFact) != "false") + return {}; + + CHCSolverInterface::CexGraph graph; + + std::stack proofStack; + proofStack.push(&asSubExpressions(proofNode).at(1)); + + std::map visitedIds; + unsigned nextId = 0; + + auto const* root = proofStack.top(); + auto const& derivedRootFact = fact(*root); + visitedIds.emplace(root, nextId++); + graph.nodes.emplace(visitedIds.at(root), _context.toSMTUtilExpression(derivedRootFact)); + + auto isHyperRes = [](SMTLib2Expression const& expr) { + if (isAtom(expr)) return false; + auto const& subExprs = asSubExpressions(expr); + smtAssert(!subExprs.empty()); + auto const& op = subExprs.at(0); + if (isAtom(op)) return false; + auto const& opExprs = asSubExpressions(op); + if (opExprs.size() < 2) return false; + auto const& ruleName = opExprs.at(1); + return isAtom(ruleName) && asAtom(ruleName) == "hyper-res"; + }; + + while (!proofStack.empty()) + { + auto const* currentNode = proofStack.top(); + smtAssert(visitedIds.find(currentNode) != visitedIds.end()); + auto id = visitedIds.at(currentNode); + smtAssert(graph.nodes.count(id)); + proofStack.pop(); + + if (isHyperRes(*currentNode)) + { + auto const& args = asSubExpressions(*currentNode); + smtAssert(args.size() > 1); + // args[0] is the name of the rule + // args[1] is the clause used + // last argument is the derived fact + // the arguments in the middle are the facts where we need to recurse + for (unsigned i = 2; i < args.size() - 1; ++i) + { + auto const* child = &args[i]; + if (!visitedIds.count(child)) + { + visitedIds.emplace(child, nextId++); + proofStack.push(child); + } + + auto childId = visitedIds.at(child); + if (!graph.nodes.count(childId)) + { + graph.nodes.emplace(childId, _context.toSMTUtilExpression(fact(*child))); + graph.edges[childId] = {}; + } + + graph.edges[id].push_back(childId); + } + } + } + return graph; +} + diff --git a/libsolidity/formal/Z3CHCSmtLib2Interface.h b/libsolidity/formal/Z3CHCSmtLib2Interface.h new file mode 100644 index 000000000000..39456cde0c1b --- /dev/null +++ b/libsolidity/formal/Z3CHCSmtLib2Interface.h @@ -0,0 +1,50 @@ +/* + 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::frontend::smt +{ + +class Z3CHCSmtLib2Interface: public smtutil::CHCSmtLib2Interface +{ +public: + Z3CHCSmtLib2Interface( + frontend::ReadCallback::Callback _smtCallback, + std::optional _queryTimeout, + bool _computeInvariants + ); + +private: + void setupSmtCallback(bool _disablePreprocessing); + + std::tuple query(smtutil::Expression const& _expr) override; + + CHCSolverInterface::CexGraph graphFromZ3Answer(std::string const& _proof) const; + + static CHCSolverInterface::CexGraph graphFromSMTLib2Expression( + smtutil::SMTLib2Expression const& _proof, + ScopedParser& _context + ); + + bool m_computeInvariants; +}; + +} From 4aff9978a95f2cb6017c6d6df9b1c4e671abf175 Mon Sep 17 00:00:00 2001 From: Daniel Date: Tue, 20 Aug 2024 13:07:57 +0200 Subject: [PATCH 0381/1022] Implementation of direct SSA CFG generation. --- libyul/CMakeLists.txt | 3 + libyul/backends/evm/SSAControlFlowGraph.h | 226 +++++ .../evm/SSAControlFlowGraphBuilder.cpp | 850 ++++++++++++++++++ .../backends/evm/SSAControlFlowGraphBuilder.h | 137 +++ 4 files changed, 1216 insertions(+) create mode 100644 libyul/backends/evm/SSAControlFlowGraph.h create mode 100644 libyul/backends/evm/SSAControlFlowGraphBuilder.cpp create mode 100644 libyul/backends/evm/SSAControlFlowGraphBuilder.h diff --git a/libyul/CMakeLists.txt b/libyul/CMakeLists.txt index d38d5f27004d..c54513d9ab91 100644 --- a/libyul/CMakeLists.txt +++ b/libyul/CMakeLists.txt @@ -63,6 +63,9 @@ add_library(yul backends/evm/NoOutputAssembly.cpp backends/evm/OptimizedEVMCodeTransform.cpp backends/evm/OptimizedEVMCodeTransform.h + backends/evm/SSAControlFlowGraph.h + backends/evm/SSAControlFlowGraphBuilder.cpp + backends/evm/SSAControlFlowGraphBuilder.h backends/evm/StackHelpers.h backends/evm/StackLayoutGenerator.cpp backends/evm/StackLayoutGenerator.h diff --git a/libyul/backends/evm/SSAControlFlowGraph.h b/libyul/backends/evm/SSAControlFlowGraph.h new file mode 100644 index 000000000000..f24b2779f08b --- /dev/null +++ b/libyul/backends/evm/SSAControlFlowGraph.h @@ -0,0 +1,226 @@ +/* + 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 +/** + * Control flow graph and stack layout structures used during code generation. + */ + +#pragma once + +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + +namespace solidity::yul +{ + +class SSACFG +{ +public: + SSACFG() {} + SSACFG(SSACFG const&) = delete; + SSACFG(SSACFG&&) = delete; + SSACFG& operator=(SSACFG const&) = delete; + SSACFG& operator=(SSACFG&&) = delete; + ~SSACFG() = default; + + struct BlockId + { + size_t value = std::numeric_limits::max(); + operator bool() const { return value != std::numeric_limits::max(); } + bool operator<(BlockId const& _rhs) const { return value < _rhs.value; } + bool operator==(BlockId const& _rhs) const { return value == _rhs.value; } + bool operator!=(BlockId const& _rhs) const { return value != _rhs.value; } + }; + struct ValueId + { + size_t value = std::numeric_limits::max(); + operator bool() const { return value != std::numeric_limits::max(); } + bool operator<(ValueId const& _rhs) const { return value < _rhs.value; } + bool operator==(ValueId const& _rhs) const { return value == _rhs.value; } + bool operator!=(ValueId const& _rhs) const { return value != _rhs.value; } + }; + struct BuiltinCall + { + langutil::DebugData::ConstPtr debugData; + std::reference_wrapper builtin; + std::reference_wrapper call; + }; + struct Call + { + langutil::DebugData::ConstPtr debugData; + std::reference_wrapper function; + std::reference_wrapper call; + bool const canContinue = true; + }; + + struct Operation { + std::vector outputs{}; + std::variant kind; + std::vector inputs{}; + }; + struct BasicBlock + { + struct MainExit {}; + struct ConditionalJump + { + langutil::DebugData::ConstPtr debugData; + ValueId condition; + BlockId nonZero; + BlockId zero; + }; + struct Jump + { + langutil::DebugData::ConstPtr debugData; + BlockId target; + }; + struct JumpTable + { + langutil::DebugData::ConstPtr debugData; + ValueId value; + std::map cases; + BlockId defaultCase; + + }; + struct FunctionReturn + { + langutil::DebugData::ConstPtr debugData; + std::vector returnValues; + }; + struct Terminated {}; + langutil::DebugData::ConstPtr debugData; + std::set entries; + std::set phis; + std::list operations; + std::variant exit = MainExit{}; + template + void forEachExit(Callable&& _callable) + { + if (auto* jump = std::get_if(&exit)) + _callable(jump->target); + else if (auto* conditionalJump = std::get_if(&exit)) + { + _callable(conditionalJump->nonZero); + _callable(conditionalJump->zero); + } + else if (auto* jumpTable = std::get_if(&exit)) + { + for (auto _case: jumpTable->cases | ranges::views::values) + _callable(_case); + _callable(jumpTable->defaultCase); + } + } + }; + BlockId makeBlock(langutil::DebugData::ConstPtr _debugData) + { + BlockId blockId { m_blocks.size() }; + m_blocks.emplace_back(BasicBlock{std::move(_debugData), {}, {}, {}, BasicBlock::Terminated{}}); + return blockId; + } + BasicBlock& block(BlockId _id) { return m_blocks.at(_id.value); } + BasicBlock const& block(BlockId _id) const { return m_blocks.at(_id.value); } + size_t numBlocks() const { return m_blocks.size(); } +private: + std::vector m_blocks; +public: + struct LiteralValue { u256 value; }; + struct VariableValue { SSACFG::BlockId definingBlock; }; + struct PhiValue { + BlockId block; + std::vector arguments; + }; + struct UnreachableValue {}; + using ValueInfo = std::variant; + ValueInfo& valueInfo(SSACFG::ValueId _var) + { + yulAssert(_var.value < m_valueInfos.size()); + return m_valueInfos.at(_var.value); + } + ValueInfo const& valueInfo(SSACFG::ValueId _var) const + { + yulAssert(_var.value < m_valueInfos.size()); + return m_valueInfos.at(_var.value); + } + ValueId newPhi(SSACFG::BlockId _definingBlock) + { + SSACFG::ValueId id { m_valueInfos.size() }; + m_valueInfos.emplace_back(PhiValue{_definingBlock, {}}); + return id; + } + ValueId newVariable(SSACFG::BlockId _definingBlock) + { + SSACFG::ValueId id { m_valueInfos.size() }; + m_valueInfos.emplace_back(VariableValue{_definingBlock}); + return id; + } + ValueId unreachableValue() + { + if (!m_unreachableValue) + { + m_unreachableValue = SSACFG::ValueId { m_valueInfos.size() }; + m_valueInfos.emplace_back(UnreachableValue{}); + } + return *m_unreachableValue; + } + ValueId newLiteral(u256 _value) + { + auto [it, inserted] = m_literals.emplace(std::make_pair(_value, SSACFG::ValueId{m_valueInfos.size()})); + if (inserted) + m_valueInfos.emplace_back(LiteralValue{_value}); + else + { + yulAssert(_value == it->first); + yulAssert(std::holds_alternative(m_valueInfos.at(it->second.value))); + yulAssert(std::get(m_valueInfos.at(it->second.value)).value == _value); + } + yulAssert(it->second.value < m_valueInfos.size()); + return it->second; + } +private: + std::deque m_valueInfos; + std::map m_literals; + std::optional m_unreachableValue; +public: + // TODO: the interface for function infos and functions here still sucks. + // Maybe we should split the graphs entirely and just have one SSACFG per function instead. + struct FunctionInfo { + langutil::DebugData::ConstPtr debugData; + std::reference_wrapper function; + BlockId entry; + std::set exits; + bool canContinue = true; + std::vector, ValueId>> arguments; + std::vector> returns; + }; + std::vector> functions; + /// Container for artificial calls generated for switch statements. + /// Ghost calls are used for the equality comparisons of the switch condition ghost variable with + /// the switch case literals when transforming the control flow of a switch to a sequence of conditional jumps. + std::list ghostCalls; +}; + +} diff --git a/libyul/backends/evm/SSAControlFlowGraphBuilder.cpp b/libyul/backends/evm/SSAControlFlowGraphBuilder.cpp new file mode 100644 index 000000000000..8648baa176f7 --- /dev/null +++ b/libyul/backends/evm/SSAControlFlowGraphBuilder.cpp @@ -0,0 +1,850 @@ +/* + 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 +/** + * Transformation of a Yul AST into a control flow graph. + */ + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace solidity; +using namespace solidity::yul; + +namespace +{ +SSACFG::ValueId tryRemoveTrivialPhi(SSACFG& _cfg, SSACFG::ValueId _phi) +{ + // TODO: double-check if this is sane + auto* phiInfo = std::get_if(&_cfg.valueInfo(_phi)); + yulAssert(phiInfo); + + SSACFG::ValueId same; + for (SSACFG::ValueId arg: phiInfo->arguments) + { + if (arg == same || arg == _phi) + continue; + if (same) + return _phi; + same = arg; + } + + struct Use { + std::reference_wrapper operation; + size_t inputIndex = std::numeric_limits::max(); + }; + std::vector uses; + std::vector visited; + std::vector phiUses; + auto isVisited = [&](SSACFG::BlockId _block) -> bool { + if (_block.value < visited.size()) + return visited.at(_block.value); + else + return false; + }; + auto markVisited = [&](SSACFG::BlockId _block) { + if (visited.size() <= _block.value) + visited.resize(_block.value + 1); + visited[_block.value] = true; + }; + // does this even need to be recursive? or can uses only be in the same or neighbouring blocks? + auto findUses = [&](SSACFG::BlockId _blockId, auto _recurse) -> void { + if (isVisited(_blockId)) + return; + markVisited(_blockId); + auto& block = _cfg.block(_blockId); + for (auto blockPhi: block.phis) + { + if (blockPhi == _phi) + continue; + auto const* blockPhiInfo = std::get_if(&_cfg.valueInfo(blockPhi)); + yulAssert(blockPhiInfo); + bool usedInPhi = false; + for (auto input: blockPhiInfo->arguments) + { + if (input == _phi) + usedInPhi = true; + } + if (usedInPhi) + phiUses.emplace_back(blockPhi); + } + for (auto& op: block.operations) + { + // TODO: double check when phiVar occurs in outputs here and what to do about it. + if (op.outputs.size() == 1 && op.outputs.front() == _phi) + continue; + // TODO: check if this always hold - and if so if the assertion is really valuable. + for (auto& output: op.outputs) + yulAssert(output != _phi); + + for (auto&& [n, input]: op.inputs | ranges::views::enumerate) + if (input == _phi) + uses.emplace_back(Use{std::ref(op), n}); + } + block.forEachExit([&](SSACFG::BlockId _block) { + _recurse(_block, _recurse); + }); + }; + auto phiBlock = phiInfo->block; + _cfg.block(phiBlock).phis.erase(_phi); + findUses(phiBlock, findUses); + + if (!same) + { + // This will happen for unreachable paths. + // TODO: check how best to deal with this + same = _cfg.unreachableValue(); + } + + for (auto& use: uses) + use.operation.get().inputs.at(use.inputIndex) = same; + for (auto phiUse: phiUses) + { + auto* blockPhiInfo = std::get_if(&_cfg.valueInfo(phiUse)); + yulAssert(blockPhiInfo); + for (auto& arg: blockPhiInfo->arguments) + if (arg == _phi) + arg = same; + } + + for (auto phiUse: phiUses) + tryRemoveTrivialPhi(_cfg, phiUse); + + return same; +} + +/// Removes edges to blocks that are not reachable. +void cleanUnreachable(SSACFG& _cfg) +{ + // Determine which blocks are reachable from the entry. + util::BreadthFirstSearch reachabilityCheck{{SSACFG::BlockId{0}}}; + for (auto const& functionInfo: _cfg.functionInfos | ranges::views::values) + reachabilityCheck.verticesToTraverse.emplace_back(functionInfo.entry); + + reachabilityCheck.run([&](SSACFG::BlockId _blockId, auto&& _addChild) { + auto const& block = _cfg.block(_blockId); + visit(util::GenericVisitor{ + [&](SSACFG::BasicBlock::Jump const& _jump) { + _addChild(_jump.target); + }, + [&](SSACFG::BasicBlock::ConditionalJump const& _jump) { + _addChild(_jump.zero); + _addChild(_jump.nonZero); + }, + [](SSACFG::BasicBlock::JumpTable const&) { yulAssert(false); }, + [](SSACFG::BasicBlock::FunctionReturn const&) {}, + [](SSACFG::BasicBlock::Terminated const&) {}, + [](SSACFG::BasicBlock::MainExit const&) {} + }, block.exit); + }); + + auto isUnreachableValue = [&](SSACFG::ValueId const& _value) -> bool { + auto* valueInfo = std::get_if(&_cfg.valueInfo(_value)); + return (valueInfo) ? true : false; + }; + + // Remove all entries from unreachable nodes from the graph. + for (SSACFG::BlockId blockId: reachabilityCheck.visited) + { + auto& block = _cfg.block(blockId); + + for (auto phi: block.phis) + { + auto& phiValue = std::get(_cfg.valueInfo(phi)); + yulAssert(block.entries.size() == phiValue.arguments.size()); + for (auto&& [entry, arg]: ranges::zip_view(block.entries, phiValue.arguments)) + yulAssert((reachabilityCheck.visited.count(entry) == 0) == isUnreachableValue(arg)); + } + + std::set maybeTrivialPhi; + for (auto it = block.entries.begin(); it != block.entries.end();) + if (reachabilityCheck.visited.count(*it)) + it++; + else + it = block.entries.erase(it); + for (auto phi: block.phis) + if (auto* phiInfo = std::get_if(&_cfg.valueInfo(phi))) + cxx20::erase_if(phiInfo->arguments, [&](SSACFG::ValueId _arg) { + if (isUnreachableValue(_arg)) + { + maybeTrivialPhi.insert(phi); + return true; + } + return false; + }); + + // After removing a phi argument, we might end up with a trivial phi that can be removed. + for (auto phi: maybeTrivialPhi) + tryRemoveTrivialPhi(_cfg, phi); + } +} + +} + +namespace solidity::yul +{ + +SSAControlFlowGraphBuilder::SSAControlFlowGraphBuilder( + SSACFG& _graph, + AsmAnalysisInfo const& _analysisInfo, + std::map const& _functionSideEffects, + Dialect const& _dialect +): + m_graph(_graph), + m_info(_analysisInfo), + m_functionSideEffects(_functionSideEffects), + m_dialect(_dialect) +{ +} + +std::unique_ptr SSAControlFlowGraphBuilder::build( + AsmAnalysisInfo const& _analysisInfo, + Dialect const& _dialect, + Block const& _block +) +{ + auto result = std::make_unique(); + + ControlFlowSideEffectsCollector sideEffects(_dialect, _block); + SSAControlFlowGraphBuilder builder(*result, _analysisInfo, sideEffects.functionSideEffects(), _dialect); + builder.m_currentBlock = result->makeBlock(debugDataOf(_block)); + builder.sealBlock(builder.m_currentBlock); + builder(_block); + if (!builder.blockInfo(builder.m_currentBlock).sealed) + builder.sealBlock(builder.m_currentBlock); + result->block(builder.m_currentBlock).exit = SSACFG::BasicBlock::MainExit{}; + + cleanUnreachable(*result); + return result; +} + +void SSAControlFlowGraphBuilder::operator()(ExpressionStatement const& _expressionStatement) +{ + auto const* functionCall = std::get_if(&_expressionStatement.expression); + yulAssert(functionCall); + auto results = visitFunctionCall(*functionCall); + yulAssert(results.empty()); +} + +void SSAControlFlowGraphBuilder::operator()(Assignment const& _assignment) +{ + assign( + _assignment.variableNames | ranges::views::transform([&](auto& _var) { return std::ref(lookupVariable(_var.name)); }) | ranges::to, + _assignment.value.get() + ); +} + +void SSAControlFlowGraphBuilder::operator()(VariableDeclaration const& _variableDeclaration) +{ + assign( + _variableDeclaration.variables | ranges::views::transform([&](auto& _var) { return std::ref(lookupVariable(_var.name)); }) | ranges::to, + _variableDeclaration.value.get() + ); +} + +void SSAControlFlowGraphBuilder::operator()(FunctionDefinition const& _functionDefinition) +{ + yulAssert(m_scope, ""); + yulAssert(m_scope->identifiers.count(_functionDefinition.name), ""); + Scope::Function& function = std::get(m_scope->identifiers.at(_functionDefinition.name)); + m_graph.functions.emplace_back(function); + + SSACFG::FunctionInfo& functionInfo = m_graph.functionInfos.at(&function); + + SSAControlFlowGraphBuilder builder{m_graph, m_info, m_functionSideEffects, m_dialect}; + builder.m_currentFunction = &functionInfo; + builder.m_currentBlock = functionInfo.entry; + for (auto&& [var, varId]: functionInfo.arguments) + builder.currentDef(var, functionInfo.entry) = varId; + builder.sealBlock(functionInfo.entry); + builder(_functionDefinition.body); + functionInfo.exits.insert(builder.m_currentBlock); + // Artificial explicit function exit (`leave`) at the end of the body. + builder(Leave{debugDataOf(_functionDefinition)}); +} + +void SSAControlFlowGraphBuilder::operator()(If const& _if) +{ + auto condition = std::visit(*this, *_if.condition); + auto ifBranch = m_graph.makeBlock(debugDataOf(_if.body)); + auto afterIf = m_graph.makeBlock(debugDataOf(currentBlock())); + conditionalJump( + debugDataOf(_if), + condition, + ifBranch, + afterIf + ); + sealBlock(ifBranch); + m_currentBlock = ifBranch; + (*this)(_if.body); + jump(debugDataOf(_if.body), afterIf); + sealBlock(afterIf); +} + +void SSAControlFlowGraphBuilder::operator()(Switch const& _switch) +{ + auto expression = std::visit(*this, *_switch.expression); + + auto useJumpTableForSwitch = [](Switch const&) { + // TODO: check for EOF support & tight switch values. + return false; + }; + if (useJumpTableForSwitch(_switch)) + { + // TODO: also generate a subtraction to shift tight, but non-zero switch cases - or, alternative, + // transform to zero-based tight switches on Yul if possible. + std::map cases; + std::optional defaultCase; + std::vector>> children; + for (auto const& _case: _switch.cases) + { + auto blockId = m_graph.makeBlock(debugDataOf(_case.body)); + if (_case.value) + cases[_case.value->value.value()] = blockId; + children.emplace_back(std::make_tuple(blockId, std::ref(_case.body))); + } + auto afterSwitch = m_graph.makeBlock(debugDataOf(currentBlock())); + + tableJump(debugDataOf(_switch), expression, cases, defaultCase ? *defaultCase : afterSwitch); + for (auto [blockId, block]: children) + { + sealBlock(blockId); + m_currentBlock = blockId; + (*this)(block); + jump(debugDataOf(currentBlock()), afterSwitch); + } + sealBlock(afterSwitch); + m_currentBlock = afterSwitch; + } + else + { + auto makeValueCompare = [&](Case const& _case) { + yul::FunctionCall const& ghostCall = m_graph.ghostCalls.emplace_back(yul::FunctionCall{ + debugDataOf(_case), + yul::Identifier{{}, "eq"_yulname}, + {*_case.value /* skip second argument */ } + }); + auto outputValue = m_graph.newVariable(m_currentBlock); + BuiltinFunction const* builtin = m_dialect.builtin(ghostCall.functionName.name); + currentBlock().operations.emplace_back(SSACFG::Operation{ + {outputValue}, + SSACFG::BuiltinCall{ + debugDataOf(_case), + *builtin, + ghostCall + }, + {m_graph.newLiteral(_case.value->value.value()), expression} + }); + return outputValue; + }; + + auto afterSwitch = m_graph.makeBlock(debugDataOf(currentBlock())); + yulAssert(!_switch.cases.empty(), ""); + for (auto const& switchCase: _switch.cases | ranges::views::drop_last(1)) + { + yulAssert(switchCase.value, ""); + auto caseBranch = m_graph.makeBlock(debugDataOf(switchCase.body)); + auto elseBranch = m_graph.makeBlock(debugDataOf(_switch)); + + conditionalJump(debugDataOf(switchCase), makeValueCompare(switchCase), caseBranch, elseBranch); + sealBlock(caseBranch); + sealBlock(elseBranch); + m_currentBlock = caseBranch; + (*this)(switchCase.body); + jump(debugDataOf(switchCase.body), afterSwitch); + m_currentBlock = elseBranch; + } + Case const& switchCase = _switch.cases.back(); + if (switchCase.value) + { + auto caseBranch = m_graph.makeBlock(debugDataOf(switchCase.body)); + conditionalJump(debugDataOf(switchCase), makeValueCompare(switchCase), caseBranch, afterSwitch); + sealBlock(caseBranch); + m_currentBlock = caseBranch; + } + (*this)(switchCase.body); + jump(debugDataOf(switchCase.body), afterSwitch); + sealBlock(afterSwitch); + } +} +void SSAControlFlowGraphBuilder::operator()(ForLoop const& _loop) +{ + ScopedSaveAndRestore scopeRestore(m_scope, m_info.scopes.at(&_loop.pre).get()); + (*this)(_loop.pre); + auto preLoopDebugData = debugDataOf(currentBlock()); + + std::optional constantCondition; + if (auto const* literalCondition = std::get_if(_loop.condition.get())) + constantCondition = literalCondition->value.value() != 0; + + SSACFG::BlockId loopCondition = m_graph.makeBlock(debugDataOf(*_loop.condition)); + SSACFG::BlockId loopBody = m_graph.makeBlock(debugDataOf(_loop.body)); + SSACFG::BlockId post = m_graph.makeBlock(debugDataOf(_loop.post)); + SSACFG::BlockId afterLoop = m_graph.makeBlock(preLoopDebugData); + + class ForLoopInfoScope { + public: + ForLoopInfoScope(std::stack& _info, SSACFG::BlockId _breakBlock, SSACFG::BlockId _continueBlock): m_info(_info) + { + m_info.push(ForLoopInfo{_breakBlock, _continueBlock}); + } + ~ForLoopInfoScope() { + m_info.pop(); + } + private: + std::stack& m_info; + } forLoopInfoScope(m_forLoopInfo, afterLoop, post); + + if (constantCondition.has_value()) + { + if (*constantCondition) + { + jump(debugDataOf(*_loop.condition), loopBody); + (*this)(_loop.body); + jump(debugDataOf(_loop.body), post); + sealBlock(post); + (*this)(_loop.post); + jump(debugDataOf(_loop.post), loopBody); + sealBlock(loopBody); + } + else + jump(debugDataOf(*_loop.condition), afterLoop); + } + else + { + jump(debugDataOf(_loop.pre), loopCondition); + auto condition = std::visit(*this, *_loop.condition); + conditionalJump(debugDataOf(*_loop.condition), condition, loopBody, afterLoop); + sealBlock(loopBody); + m_currentBlock = loopBody; + (*this)(_loop.body); + jump(debugDataOf(_loop.body), post); + sealBlock(post); + (*this)(_loop.post); + jump(debugDataOf(_loop.post), loopCondition); + sealBlock(loopCondition); + } + + sealBlock(afterLoop); + m_currentBlock = afterLoop; +} + +void SSAControlFlowGraphBuilder::operator()(Break const& _break) +{ + yulAssert(!m_forLoopInfo.empty()); + auto currentBlockDebugData = debugDataOf(currentBlock()); + jump(debugDataOf(_break), m_forLoopInfo.top().breakBlock); + m_currentBlock = m_graph.makeBlock(currentBlockDebugData); + sealBlock(m_currentBlock); +} + +void SSAControlFlowGraphBuilder::operator()(Continue const& _continue) +{ + yulAssert(!m_forLoopInfo.empty()); + auto currentBlockDebugData = debugDataOf(currentBlock()); + jump(debugDataOf(_continue), m_forLoopInfo.top().continueBlock); + m_currentBlock = m_graph.makeBlock(currentBlockDebugData); + sealBlock(m_currentBlock); +} + +void SSAControlFlowGraphBuilder::operator()(Leave const& _leave) +{ + yulAssert(m_currentFunction); + auto currentBlockDebugData = debugDataOf(currentBlock()); + currentBlock().exit = SSACFG::BasicBlock::FunctionReturn{ + debugDataOf(_leave), + m_currentFunction->returns | ranges::views::transform([&](auto _var) { + return readVariable(_var, m_currentBlock); + }) | ranges::to + }; + m_currentBlock = m_graph.makeBlock(currentBlockDebugData); + sealBlock(m_currentBlock); +} + +void SSAControlFlowGraphBuilder::operator()(Block const& _block) +{ + ScopedSaveAndRestore saveScope(m_scope, m_info.scopes.at(&_block).get()); + for (auto const& statement: _block.statements) + if (auto const* function = std::get_if(&statement)) + registerFunction(*function); + for (auto const& statement: _block.statements) + std::visit(*this, statement); +} + +SSACFG::ValueId SSAControlFlowGraphBuilder::operator()(FunctionCall const& _call) +{ + auto results = visitFunctionCall(_call); + yulAssert(results.size() == 1); + return results.front(); +} + +SSACFG::ValueId SSAControlFlowGraphBuilder::operator()(Identifier const& _identifier) +{ + auto const& var = lookupVariable(_identifier.name); + return readVariable(var, m_currentBlock); +} + +SSACFG::ValueId SSAControlFlowGraphBuilder::operator()(Literal const& _literal) +{ + return m_graph.newLiteral(_literal.value.value()); +} + +void SSAControlFlowGraphBuilder::assign(std::vector> _variables, Expression const* _expression) +{ + auto rhs = [&]() -> std::vector { + if (auto const* functionCall = std::get_if(_expression)) + return visitFunctionCall(*functionCall); + else if (_expression) + return {std::visit(*this, *_expression)}; + else + return {_variables.size(), zero()}; + }(); + yulAssert(rhs.size() == _variables.size()); + + for (auto const& [var, value]: ranges::zip_view(_variables, rhs)) + writeVariable(var, m_currentBlock, value); + +} + +void SSAControlFlowGraphBuilder::registerFunction(FunctionDefinition const& _functionDefinition) +{ + yulAssert(m_scope, ""); + yulAssert(m_scope->identifiers.count(_functionDefinition.name), ""); + Scope::Function& function = std::get(m_scope->identifiers.at(_functionDefinition.name)); + + yulAssert(m_info.scopes.at(&_functionDefinition.body), ""); + Scope* virtualFunctionScope = m_info.scopes.at(m_info.virtualBlocks.at(&_functionDefinition).get()).get(); + yulAssert(virtualFunctionScope, ""); + + // TODO: think about using another root node before the function body here (in particular as defining block for the + // arguments below) + SSACFG::BlockId entryBlock = m_graph.makeBlock(debugDataOf(_functionDefinition.body)); + + auto arguments = _functionDefinition.parameters | ranges::views::transform([&](auto const& _param) { + auto const& var = std::get(virtualFunctionScope->identifiers.at(_param.name)); + // Note: cannot use std::make_tuple since it unwraps reference wrappers. + return std::tuple{std::cref(var), m_graph.newVariable(entryBlock)}; + }) | ranges::to; + auto returns = _functionDefinition.returnVariables | ranges::views::transform([&](auto const& _param) { + return std::cref(std::get(virtualFunctionScope->identifiers.at(_param.name))); + }) | ranges::to; + auto [it, inserted] = m_graph.functionInfos.emplace(std::make_pair(&function, SSACFG::FunctionInfo{ + _functionDefinition.debugData, + function, + entryBlock, + {}, + m_functionSideEffects.at(&_functionDefinition).canContinue, + arguments, + returns + })); + yulAssert(inserted); +} + +std::vector SSAControlFlowGraphBuilder::visitFunctionCall(FunctionCall const& _call) +{ + bool canContinue = true; + SSACFG::Operation operation = [&](){ + if (BuiltinFunction const* builtin = m_dialect.builtin(_call.functionName.name)) + { + SSACFG::Operation result{{}, SSACFG::BuiltinCall{_call.debugData, *builtin, _call}, {}}; + for (auto&& [idx, arg]: _call.arguments | ranges::views::enumerate | ranges::views::reverse) + if (!builtin->literalArgument(idx).has_value()) + result.inputs.emplace_back(std::visit(*this, arg)); + for (size_t i = 0; i < builtin->returns.size(); ++i) + result.outputs.emplace_back(m_graph.newVariable(m_currentBlock)); + canContinue = builtin->controlFlowSideEffects.canContinue; + return result; + } + else + { + Scope::Function const& function = lookupFunction(_call.functionName.name); + canContinue = m_graph.functionInfos.at(&function).canContinue; + SSACFG::Operation result{{}, SSACFG::Call{debugDataOf(_call), function, _call, canContinue}, {}}; + for (auto const& arg: _call.arguments | ranges::views::reverse) + result.inputs.emplace_back(std::visit(*this, arg)); + for (size_t i = 0; i < function.returns.size(); ++i) + result.outputs.emplace_back(m_graph.newVariable(m_currentBlock)); + return result; + } + }(); + auto results = operation.outputs; + currentBlock().operations.emplace_back(std::move(operation)); + if (!canContinue) + { + currentBlock().exit = SSACFG::BasicBlock::Terminated{}; + m_currentBlock = m_graph.makeBlock(debugDataOf(currentBlock())); + sealBlock(m_currentBlock); + } + return results; +} + +SSACFG::ValueId SSAControlFlowGraphBuilder::zero() +{ + return m_graph.newLiteral(0u); +} + +SSACFG::ValueId SSAControlFlowGraphBuilder::readVariable(Scope::Variable const& _variable, SSACFG::BlockId _block) +{ + auto& def = currentDef(_variable, _block); + if (def.has_value()) + return *def; + return readVariableRecursive(_variable, _block); +} + +SSACFG::ValueId SSAControlFlowGraphBuilder::readVariableRecursive(Scope::Variable const& _variable, SSACFG::BlockId _block) +{ + auto& block = m_graph.block(_block); + auto& info = blockInfo(_block); + + if (info.sealed && block.entries.size() == 1) + return readVariable(_variable, *block.entries.begin()); + + SSACFG::ValueId phi = m_graph.newPhi(_block); + block.phis.insert(phi); + if (info.sealed) + { + writeVariable(_variable, _block, phi); + phi = addPhiOperands(_variable, phi); + } + else + { + info.incompletePhis.emplace_back(std::make_tuple(phi, std::ref(_variable))); + } + writeVariable(_variable, _block, phi); + return phi; +} + +SSACFG::ValueId SSAControlFlowGraphBuilder::addPhiOperands(Scope::Variable const& _variable, SSACFG::ValueId _phi) +{ + auto* phi = std::get_if(&m_graph.valueInfo(_phi)); + yulAssert(phi); + for (auto pred: m_graph.block(phi->block).entries) + phi->arguments.emplace_back(readVariable(_variable, pred)); + return tryRemoveTrivialPhi(_phi); +} + +SSACFG::ValueId SSAControlFlowGraphBuilder::tryRemoveTrivialPhi(SSACFG::ValueId _phi) +{ + // TODO: double-check if this is sane + auto* phiInfo = std::get_if(&m_graph.valueInfo(_phi)); + yulAssert(phiInfo); + + SSACFG::ValueId same; + for (SSACFG::ValueId arg: phiInfo->arguments) + { + if (arg == same || arg == _phi) + continue; + if (same) + return _phi; + same = arg; + } + + struct Use { + std::reference_wrapper operation; + size_t inputIndex = std::numeric_limits::max(); + }; + std::vector uses; + std::vector visited; + std::vector phiUses; + auto isVisited = [&](SSACFG::BlockId _block) -> bool { + if (_block.value < visited.size()) + return visited.at(_block.value); + else + return false; + }; + auto markVisited = [&](SSACFG::BlockId _block) { + if (visited.size() <= _block.value) + visited.resize(_block.value + 1); + visited[_block.value] = true; + }; + // does this even need to be recursive? or can uses only be in the same or neighbouring blocks? + auto findUses = [&](SSACFG::BlockId _blockId, auto _recurse) -> void { + if (isVisited(_blockId)) + return; + markVisited(_blockId); + auto& block = m_graph.block(_blockId); + for (auto blockPhi: block.phis) + { + if (blockPhi == _phi) + continue; + auto const* blockPhiInfo = std::get_if(&m_graph.valueInfo(blockPhi)); + yulAssert(blockPhiInfo); + bool usedInPhi = false; + for (auto input: blockPhiInfo->arguments) + { + if (input == _phi) + usedInPhi = true; + } + if (usedInPhi) + phiUses.emplace_back(blockPhi); + } + for (auto& op: block.operations) + { + // TODO: double check when phiVar occurs in outputs here and what to do about it. + if (op.outputs.size() == 1 && op.outputs.front() == _phi) + continue; + // TODO: check if this always hold - and if so if the assertion is really valuable. + for (auto& output: op.outputs) + yulAssert(output != _phi); + + for (auto&& [n, input]: op.inputs | ranges::views::enumerate) + if (input == _phi) + uses.emplace_back(Use{std::ref(op), n}); + } + block.forEachExit([&](SSACFG::BlockId _block) { + _recurse(_block, _recurse); + }); + }; + auto phiBlock = phiInfo->block; + m_graph.block(phiBlock).phis.erase(_phi); + findUses(phiBlock, findUses); + + if (!same) + // This will happen for unreachable paths. + // TODO: check how best to deal with this + same = m_graph.unreachableValue(); + + for (auto& use: uses) + use.operation.get().inputs.at(use.inputIndex) = same; + for (auto phiUse: phiUses) + { + auto* blockPhiInfo = std::get_if(&m_graph.valueInfo(phiUse)); + yulAssert(blockPhiInfo); + for (auto& arg: blockPhiInfo->arguments) + if (arg == _phi) + arg = same; + } + + for (auto phiUse: phiUses) + tryRemoveTrivialPhi(phiUse); + + return same; +} + +void SSAControlFlowGraphBuilder::writeVariable(Scope::Variable const& _variable, SSACFG::BlockId _block, SSACFG::ValueId _value) +{ + currentDef(_variable, _block) = _value; +} + +Scope::Function const& SSAControlFlowGraphBuilder::lookupFunction(YulName _name) const +{ + Scope::Function const* function = nullptr; + yulAssert(m_scope->lookup(_name, util::GenericVisitor{ + [](Scope::Variable&) { yulAssert(false, "Expected function name."); }, + [&](Scope::Function& _function) { function = &_function; } + }), "Function name not found."); + yulAssert(function, ""); + return *function; +} + +Scope::Variable const& SSAControlFlowGraphBuilder::lookupVariable(YulName _name) const +{ + yulAssert(m_scope, ""); + Scope::Variable const* var = nullptr; + if (m_scope->lookup(_name, util::GenericVisitor{ + [&](Scope::Variable& _var) { var = &_var; }, + [](Scope::Function&) + { + yulAssert(false, "Function not removed during desugaring."); + } + })) + { + yulAssert(var, ""); + return *var; + }; + yulAssert(false, "External identifier access unimplemented."); +} + +void SSAControlFlowGraphBuilder::sealBlock(SSACFG::BlockId _block) +{ + auto& info = blockInfo(_block); + yulAssert(!info.sealed, "Trying to seal already sealed block."); + for (auto&& [phi, variable] : info.incompletePhis) + addPhiOperands(variable, phi); + info.sealed = true; +} + + +void SSAControlFlowGraphBuilder::conditionalJump( + langutil::DebugData::ConstPtr _debugData, + SSACFG::ValueId _condition, + SSACFG::BlockId _nonZero, + SSACFG::BlockId _zero +) +{ + currentBlock().exit = SSACFG::BasicBlock::ConditionalJump{ + std::move(_debugData), + _condition, + _nonZero, + _zero + }; + m_graph.block(_nonZero).entries.insert(m_currentBlock); + m_graph.block(_zero).entries.insert(m_currentBlock); + m_currentBlock = {}; +} + +void SSAControlFlowGraphBuilder::jump( + langutil::DebugData::ConstPtr _debugData, + SSACFG::BlockId _target +) +{ + currentBlock().exit = SSACFG::BasicBlock::Jump{std::move(_debugData), _target}; + yulAssert(!blockInfo(_target).sealed); + m_graph.block(_target).entries.insert(m_currentBlock); + m_currentBlock = _target; +} + +void SSAControlFlowGraphBuilder::tableJump( + langutil::DebugData::ConstPtr _debugData, + SSACFG::ValueId _value, + std::map _cases, + SSACFG::BlockId _defaultCase +) +{ + for (auto caseBlock: _cases | ranges::views::values) + { + yulAssert(!blockInfo(caseBlock).sealed); + m_graph.block(caseBlock).entries.insert(m_currentBlock); + } + yulAssert(!blockInfo(_defaultCase).sealed); + m_graph.block(_defaultCase).entries.insert(m_currentBlock); + currentBlock().exit = SSACFG::BasicBlock::JumpTable{ + std::move(_debugData), + _value, + std::move(_cases), + _defaultCase + }; + m_currentBlock = {}; +} + +} diff --git a/libyul/backends/evm/SSAControlFlowGraphBuilder.h b/libyul/backends/evm/SSAControlFlowGraphBuilder.h new file mode 100644 index 000000000000..689e5bf884b3 --- /dev/null +++ b/libyul/backends/evm/SSAControlFlowGraphBuilder.h @@ -0,0 +1,137 @@ +/* + 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 +/** +* Transformation of a Yul AST into a control flow graph. +*/ +#pragma once + +#include +#include +#include + +namespace solidity::yul +{ + +class SSAControlFlowGraphBuilder +{ + SSAControlFlowGraphBuilder( + SSACFG& _graph, + AsmAnalysisInfo const& _analysisInfo, + std::map const& _functionSideEffects, + Dialect const& _dialect + ); +public: + SSAControlFlowGraphBuilder(SSAControlFlowGraphBuilder const&) = delete; + SSAControlFlowGraphBuilder& operator=(SSAControlFlowGraphBuilder const&) = delete; + static std::unique_ptr build(AsmAnalysisInfo const& _analysisInfo, Dialect const& _dialect, Block const& _block); + + void operator()(ExpressionStatement const& _statement); + void operator()(Assignment const& _assignment); + void operator()(VariableDeclaration const& _varDecl); + + void operator()(FunctionDefinition const&); + void operator()(If const& _if); + void operator()(Switch const& _switch); + void operator()(ForLoop const&); + void operator()(Break const&); + void operator()(Continue const&); + void operator()(Leave const&); + + void operator()(Block const& _block); + + SSACFG::ValueId operator()(FunctionCall const& _call); + SSACFG::ValueId operator()(Identifier const& _identifier); + SSACFG::ValueId operator()(Literal const& _literal); + +private: + void assign(std::vector> _variables, Expression const* _expression); + + void registerFunction(FunctionDefinition const& _function); + std::vector visitFunctionCall(FunctionCall const& _call); + + SSACFG::ValueId zero(); + SSACFG::ValueId readVariable(Scope::Variable const& _variable, SSACFG::BlockId _block); + SSACFG::ValueId readVariableRecursive(Scope::Variable const& _variable, SSACFG::BlockId _block); + SSACFG::ValueId addPhiOperands(Scope::Variable const& _variable, SSACFG::ValueId _phi); + void writeVariable(Scope::Variable const& _variable, SSACFG::BlockId _block, SSACFG::ValueId _value); + + SSACFG& m_graph; + AsmAnalysisInfo const& m_info; + std::map const& m_functionSideEffects; + Dialect const& m_dialect; + SSACFG::BlockId m_currentBlock; + SSACFG::BasicBlock& currentBlock() { return m_graph.block(m_currentBlock); } + Scope* m_scope = nullptr; + Scope::Function const& lookupFunction(YulName _name) const; + Scope::Variable const& lookupVariable(YulName _name) const; + + struct BlockInfo { + bool sealed = false; + std::vector>> incompletePhis; + }; + std::vector m_blockInfo; + + BlockInfo& blockInfo(SSACFG::BlockId _block) + { + if (_block.value >= m_blockInfo.size()) + m_blockInfo.resize(_block.value + 1, {}); + return m_blockInfo[_block.value]; + } + void sealBlock(SSACFG::BlockId _block); + + std::map< + Scope::Variable const*, + std::vector> + > m_currentDef; + + struct ForLoopInfo { + SSACFG::BlockId breakBlock; + SSACFG::BlockId continueBlock; + }; + std::stack m_forLoopInfo; + SSACFG::FunctionInfo* m_currentFunction = nullptr; + + std::optional& currentDef(Scope::Variable const& _variable, SSACFG::BlockId _block) + { + auto& varDefs = m_currentDef[&_variable]; + if (varDefs.size() <= _block.value) + varDefs.resize(_block.value + 1); + return varDefs.at(_block.value); + } + + void conditionalJump( + langutil::DebugData::ConstPtr _debugData, + SSACFG::ValueId _condition, + SSACFG::BlockId _nonZero, + SSACFG::BlockId _zero + ); + + void jump( + langutil::DebugData::ConstPtr _debugData, + SSACFG::BlockId _target + ); + + void tableJump( + langutil::DebugData::ConstPtr _debugData, + SSACFG::ValueId _value, + std::map _cases, + SSACFG::BlockId _defaultCase + ); +}; + +} From d9116dc41c8daac9bfa6a2efe0dc3dd2f80f1d2e Mon Sep 17 00:00:00 2001 From: r0qs Date: Wed, 21 Aug 2024 15:56:32 +0200 Subject: [PATCH 0382/1022] Yul: Split SSA CFG into separate graphs for functions --- libyul/backends/evm/ControlFlow.h | 43 ++++ libyul/backends/evm/SSAControlFlowGraph.h | 72 +++---- .../evm/SSAControlFlowGraphBuilder.cpp | 196 +++++++++--------- .../backends/evm/SSAControlFlowGraphBuilder.h | 25 ++- .../libyul/yulSSAControlFlowGraph/complex.yul | 179 ++++++++++++++++ .../yulSSAControlFlowGraph/complex2.yul | 195 +++++++++++++++++ .../yulSSAControlFlowGraph/function.yul | 68 ++++++ test/libyul/yulSSAControlFlowGraph/if.yul | 40 ++++ test/libyul/yulSSAControlFlowGraph/switch.yul | 68 ++++++ 9 files changed, 750 insertions(+), 136 deletions(-) create mode 100644 libyul/backends/evm/ControlFlow.h create mode 100644 test/libyul/yulSSAControlFlowGraph/complex.yul create mode 100644 test/libyul/yulSSAControlFlowGraph/complex2.yul create mode 100644 test/libyul/yulSSAControlFlowGraph/function.yul create mode 100644 test/libyul/yulSSAControlFlowGraph/if.yul create mode 100644 test/libyul/yulSSAControlFlowGraph/switch.yul diff --git a/libyul/backends/evm/ControlFlow.h b/libyul/backends/evm/ControlFlow.h new file mode 100644 index 000000000000..18b43431a16f --- /dev/null +++ b/libyul/backends/evm/ControlFlow.h @@ -0,0 +1,43 @@ +/* + This file is part of solidity. + + solidity is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + solidity is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with solidity. If not, see . +*/ +// SPDX-License-Identifier: GPL-3.0 + +#pragma once + +#include +#include +#include + +namespace solidity::yul +{ + +struct ControlFlow +{ + std::unique_ptr mainGraph{std::make_unique()}; + std::vector> functionGraphs{}; + std::vector> functionGraphMapping{}; + + SSACFG const* functionGraph(Scope::Function const* _function) + { + auto it = std::find_if(functionGraphMapping.begin(), functionGraphMapping.end(), [_function](auto const& tup) { return _function == std::get<0>(tup); }); + if (it != functionGraphMapping.end()) + return std::get<1>(*it); + return nullptr; + } +}; + +} diff --git a/libyul/backends/evm/SSAControlFlowGraph.h b/libyul/backends/evm/SSAControlFlowGraph.h index f24b2779f08b..311d23e87c41 100644 --- a/libyul/backends/evm/SSAControlFlowGraph.h +++ b/libyul/backends/evm/SSAControlFlowGraph.h @@ -29,10 +29,10 @@ #include +#include #include #include #include -#include #include namespace solidity::yul @@ -41,7 +41,7 @@ namespace solidity::yul class SSACFG { public: - SSACFG() {} + SSACFG() = default; SSACFG(SSACFG const&) = delete; SSACFG(SSACFG&&) = delete; SSACFG& operator=(SSACFG const&) = delete; @@ -51,7 +51,6 @@ class SSACFG struct BlockId { size_t value = std::numeric_limits::max(); - operator bool() const { return value != std::numeric_limits::max(); } bool operator<(BlockId const& _rhs) const { return value < _rhs.value; } bool operator==(BlockId const& _rhs) const { return value == _rhs.value; } bool operator!=(BlockId const& _rhs) const { return value != _rhs.value; } @@ -59,11 +58,12 @@ class SSACFG struct ValueId { size_t value = std::numeric_limits::max(); - operator bool() const { return value != std::numeric_limits::max(); } + bool hasValue() const { return value != std::numeric_limits::max(); } bool operator<(ValueId const& _rhs) const { return value < _rhs.value; } bool operator==(ValueId const& _rhs) const { return value == _rhs.value; } bool operator!=(ValueId const& _rhs) const { return value != _rhs.value; } }; + struct BuiltinCall { langutil::DebugData::ConstPtr debugData; @@ -104,7 +104,6 @@ class SSACFG ValueId value; std::map cases; BlockId defaultCase; - }; struct FunctionReturn { @@ -115,7 +114,7 @@ class SSACFG langutil::DebugData::ConstPtr debugData; std::set entries; std::set phis; - std::list operations; + std::vector operations; std::variant exit = MainExit{}; template void forEachExit(Callable&& _callable) @@ -147,50 +146,57 @@ class SSACFG private: std::vector m_blocks; public: - struct LiteralValue { u256 value; }; - struct VariableValue { SSACFG::BlockId definingBlock; }; + struct LiteralValue { + langutil::DebugData::ConstPtr debugData; + u256 value; + }; + struct VariableValue { + langutil::DebugData::ConstPtr debugData; + BlockId definingBlock; + }; struct PhiValue { + langutil::DebugData::ConstPtr debugData; BlockId block; std::vector arguments; }; struct UnreachableValue {}; using ValueInfo = std::variant; - ValueInfo& valueInfo(SSACFG::ValueId _var) + ValueInfo& valueInfo(ValueId const _var) { - yulAssert(_var.value < m_valueInfos.size()); return m_valueInfos.at(_var.value); } - ValueInfo const& valueInfo(SSACFG::ValueId _var) const + ValueInfo const& valueInfo(ValueId const _var) const { - yulAssert(_var.value < m_valueInfos.size()); return m_valueInfos.at(_var.value); } - ValueId newPhi(SSACFG::BlockId _definingBlock) + ValueId newPhi(BlockId const _definingBlock) { - SSACFG::ValueId id { m_valueInfos.size() }; - m_valueInfos.emplace_back(PhiValue{_definingBlock, {}}); + ValueId id { m_valueInfos.size() }; + auto block = m_blocks.at(_definingBlock.value); + m_valueInfos.emplace_back(PhiValue{debugDataOf(block), _definingBlock, {}}); return id; } - ValueId newVariable(SSACFG::BlockId _definingBlock) + ValueId newVariable(BlockId const _definingBlock) { - SSACFG::ValueId id { m_valueInfos.size() }; - m_valueInfos.emplace_back(VariableValue{_definingBlock}); + ValueId id { m_valueInfos.size() }; + auto block = m_blocks.at(_definingBlock.value); + m_valueInfos.emplace_back(VariableValue{debugDataOf(block), _definingBlock}); return id; } ValueId unreachableValue() { if (!m_unreachableValue) { - m_unreachableValue = SSACFG::ValueId { m_valueInfos.size() }; + m_unreachableValue = ValueId { m_valueInfos.size() }; m_valueInfos.emplace_back(UnreachableValue{}); } return *m_unreachableValue; } - ValueId newLiteral(u256 _value) + ValueId newLiteral(langutil::DebugData::ConstPtr _debugData, u256 _value) { - auto [it, inserted] = m_literals.emplace(std::make_pair(_value, SSACFG::ValueId{m_valueInfos.size()})); + auto [it, inserted] = m_literals.emplace(_value, ValueId{m_valueInfos.size()}); if (inserted) - m_valueInfos.emplace_back(LiteralValue{_value}); + m_valueInfos.emplace_back(LiteralValue{std::move(_debugData), _value}); else { yulAssert(_value == it->first); @@ -205,21 +211,15 @@ class SSACFG std::map m_literals; std::optional m_unreachableValue; public: - // TODO: the interface for function infos and functions here still sucks. - // Maybe we should split the graphs entirely and just have one SSACFG per function instead. - struct FunctionInfo { - langutil::DebugData::ConstPtr debugData; - std::reference_wrapper function; - BlockId entry; - std::set exits; - bool canContinue = true; - std::vector, ValueId>> arguments; - std::vector> returns; - }; + langutil::DebugData::ConstPtr debugData; + BlockId entry = BlockId{0}; + std::set exits; + Scope::Function const* function = nullptr; + bool canContinue = true; + std::vector, ValueId>> arguments; + std::vector> returns; std::vector> functions; - /// Container for artificial calls generated for switch statements. - /// Ghost calls are used for the equality comparisons of the switch condition ghost variable with - /// the switch case literals when transforming the control flow of a switch to a sequence of conditional jumps. + // Container for artificial calls generated for switch statements. std::list ghostCalls; }; diff --git a/libyul/backends/evm/SSAControlFlowGraphBuilder.cpp b/libyul/backends/evm/SSAControlFlowGraphBuilder.cpp index 8648baa176f7..18720e9bc31a 100644 --- a/libyul/backends/evm/SSAControlFlowGraphBuilder.cpp +++ b/libyul/backends/evm/SSAControlFlowGraphBuilder.cpp @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -54,7 +55,7 @@ SSACFG::ValueId tryRemoveTrivialPhi(SSACFG& _cfg, SSACFG::ValueId _phi) { if (arg == same || arg == _phi) continue; - if (same) + if (same.hasValue()) return _phi; same = arg; } @@ -119,7 +120,7 @@ SSACFG::ValueId tryRemoveTrivialPhi(SSACFG& _cfg, SSACFG::ValueId _phi) _cfg.block(phiBlock).phis.erase(_phi); findUses(phiBlock, findUses); - if (!same) + if (!same.hasValue()) { // This will happen for unreachable paths. // TODO: check how best to deal with this @@ -147,10 +148,7 @@ SSACFG::ValueId tryRemoveTrivialPhi(SSACFG& _cfg, SSACFG::ValueId _phi) void cleanUnreachable(SSACFG& _cfg) { // Determine which blocks are reachable from the entry. - util::BreadthFirstSearch reachabilityCheck{{SSACFG::BlockId{0}}}; - for (auto const& functionInfo: _cfg.functionInfos | ranges::views::values) - reachabilityCheck.verticesToTraverse.emplace_back(functionInfo.entry); - + util::BreadthFirstSearch reachabilityCheck{{_cfg.entry}}; reachabilityCheck.run([&](SSACFG::BlockId _blockId, auto&& _addChild) { auto const& block = _cfg.block(_blockId); visit(util::GenericVisitor{ @@ -217,35 +215,94 @@ namespace solidity::yul SSAControlFlowGraphBuilder::SSAControlFlowGraphBuilder( SSACFG& _graph, AsmAnalysisInfo const& _analysisInfo, - std::map const& _functionSideEffects, Dialect const& _dialect ): m_graph(_graph), m_info(_analysisInfo), - m_functionSideEffects(_functionSideEffects), m_dialect(_dialect) { } -std::unique_ptr SSAControlFlowGraphBuilder::build( +std::unique_ptr SSAControlFlowGraphBuilder::build( AsmAnalysisInfo const& _analysisInfo, Dialect const& _dialect, Block const& _block ) { - auto result = std::make_unique(); - ControlFlowSideEffectsCollector sideEffects(_dialect, _block); - SSAControlFlowGraphBuilder builder(*result, _analysisInfo, sideEffects.functionSideEffects(), _dialect); - builder.m_currentBlock = result->makeBlock(debugDataOf(_block)); + + auto result = std::make_unique(); + auto functions = buildMainGraph(*result->mainGraph, _analysisInfo, _dialect, _block); + buildFunctionGraphs(*result, _analysisInfo, sideEffects, _dialect, functions); + + cleanUnreachable(*result->mainGraph); + for (auto& functionGraph: result->functionGraphs) + cleanUnreachable(*functionGraph); + return result; +} + +void SSAControlFlowGraphBuilder::buildFunctionGraphs( + ControlFlow& _controlFlow, + AsmAnalysisInfo const& _info, + ControlFlowSideEffectsCollector const& _sideEffects, + Dialect const& _dialect, + std::vector> const& _functions +) +{ + for (auto const& [function, functionDefinition]: _functions) + { + _controlFlow.functionGraphs.emplace_back(std::make_unique()); + auto& cfg = *_controlFlow.functionGraphs.back(); + _controlFlow.functionGraphMapping.emplace_back(function, &cfg); + + yulAssert(_info.scopes.at(&functionDefinition->body), ""); + Scope* virtualFunctionScope = _info.scopes.at(_info.virtualBlocks.at(functionDefinition).get()).get(); + yulAssert(virtualFunctionScope, ""); + + cfg.entry = cfg.makeBlock(debugDataOf(functionDefinition->body)); + auto arguments = functionDefinition->parameters | ranges::views::transform([&](auto const& _param) { + auto const& var = std::get(virtualFunctionScope->identifiers.at(_param.name)); + // Note: cannot use std::make_tuple since it unwraps reference wrappers. + return std::tuple{std::cref(var), cfg.newVariable(cfg.entry)}; + }) | ranges::to; + auto returns = functionDefinition->returnVariables | ranges::views::transform([&](auto const& _param) { + return std::cref(std::get(virtualFunctionScope->identifiers.at(_param.name))); + }) | ranges::to; + + cfg.debugData = functionDefinition->debugData; + cfg.function = function; + cfg.canContinue = _sideEffects.functionSideEffects().at(functionDefinition).canContinue; + cfg.arguments = arguments; + cfg.returns = returns; + + SSAControlFlowGraphBuilder builder(cfg, _info, _dialect); + builder.m_currentBlock = cfg.entry; + for (auto&& [var, varId]: cfg.arguments) + builder.currentDef(var, cfg.entry) = varId; + builder.sealBlock(cfg.entry); + builder(functionDefinition->body); + cfg.exits.insert(builder.m_currentBlock); + // Artificial explicit function exit (`leave`) at the end of the body. + builder(Leave{debugDataOf(*functionDefinition)}); + } +} + +std::vector> SSAControlFlowGraphBuilder::buildMainGraph( + SSACFG& _cfg, + AsmAnalysisInfo const& _analysisInfo, + Dialect const& _dialect, + Block const& _block +) +{ + SSAControlFlowGraphBuilder builder(_cfg, _analysisInfo, _dialect); + builder.m_currentBlock = _cfg.makeBlock(debugDataOf(_block)); builder.sealBlock(builder.m_currentBlock); builder(_block); if (!builder.blockInfo(builder.m_currentBlock).sealed) builder.sealBlock(builder.m_currentBlock); - result->block(builder.m_currentBlock).exit = SSACFG::BasicBlock::MainExit{}; + _cfg.block(builder.m_currentBlock).exit = SSACFG::BasicBlock::MainExit{}; - cleanUnreachable(*result); - return result; + return builder.m_functionDefinitions; } void SSAControlFlowGraphBuilder::operator()(ExpressionStatement const& _expressionStatement) @@ -276,21 +333,9 @@ void SSAControlFlowGraphBuilder::operator()(FunctionDefinition const& _functionD { yulAssert(m_scope, ""); yulAssert(m_scope->identifiers.count(_functionDefinition.name), ""); - Scope::Function& function = std::get(m_scope->identifiers.at(_functionDefinition.name)); + auto& function = std::get(m_scope->identifiers.at(_functionDefinition.name)); m_graph.functions.emplace_back(function); - - SSACFG::FunctionInfo& functionInfo = m_graph.functionInfos.at(&function); - - SSAControlFlowGraphBuilder builder{m_graph, m_info, m_functionSideEffects, m_dialect}; - builder.m_currentFunction = &functionInfo; - builder.m_currentBlock = functionInfo.entry; - for (auto&& [var, varId]: functionInfo.arguments) - builder.currentDef(var, functionInfo.entry) = varId; - builder.sealBlock(functionInfo.entry); - builder(_functionDefinition.body); - functionInfo.exits.insert(builder.m_currentBlock); - // Artificial explicit function exit (`leave`) at the end of the body. - builder(Leave{debugDataOf(_functionDefinition)}); + m_functionDefinitions.emplace_back(&function, &_functionDefinition); } void SSAControlFlowGraphBuilder::operator()(If const& _if) @@ -331,7 +376,9 @@ void SSAControlFlowGraphBuilder::operator()(Switch const& _switch) auto blockId = m_graph.makeBlock(debugDataOf(_case.body)); if (_case.value) cases[_case.value->value.value()] = blockId; - children.emplace_back(std::make_tuple(blockId, std::ref(_case.body))); + else + defaultCase = blockId; + children.emplace_back(blockId, std::ref(_case.body)); } auto afterSwitch = m_graph.makeBlock(debugDataOf(currentBlock())); @@ -349,9 +396,9 @@ void SSAControlFlowGraphBuilder::operator()(Switch const& _switch) else { auto makeValueCompare = [&](Case const& _case) { - yul::FunctionCall const& ghostCall = m_graph.ghostCalls.emplace_back(yul::FunctionCall{ + FunctionCall const& ghostCall = m_graph.ghostCalls.emplace_back(FunctionCall{ debugDataOf(_case), - yul::Identifier{{}, "eq"_yulname}, + Identifier{{}, "eq"_yulname}, {*_case.value /* skip second argument */ } }); auto outputValue = m_graph.newVariable(m_currentBlock); @@ -363,7 +410,7 @@ void SSAControlFlowGraphBuilder::operator()(Switch const& _switch) *builtin, ghostCall }, - {m_graph.newLiteral(_case.value->value.value()), expression} + {m_graph.newLiteral(debugDataOf(_case), _case.value->value.value()), expression} }); return outputValue; }; @@ -404,7 +451,7 @@ void SSAControlFlowGraphBuilder::operator()(ForLoop const& _loop) auto preLoopDebugData = debugDataOf(currentBlock()); std::optional constantCondition; - if (auto const* literalCondition = std::get_if(_loop.condition.get())) + if (auto const* literalCondition = std::get_if(_loop.condition.get())) constantCondition = literalCondition->value.value() != 0; SSACFG::BlockId loopCondition = m_graph.makeBlock(debugDataOf(*_loop.condition)); @@ -477,13 +524,12 @@ void SSAControlFlowGraphBuilder::operator()(Continue const& _continue) sealBlock(m_currentBlock); } -void SSAControlFlowGraphBuilder::operator()(Leave const& _leave) +void SSAControlFlowGraphBuilder::operator()(Leave const& _leaveStatement) { - yulAssert(m_currentFunction); auto currentBlockDebugData = debugDataOf(currentBlock()); currentBlock().exit = SSACFG::BasicBlock::FunctionReturn{ - debugDataOf(_leave), - m_currentFunction->returns | ranges::views::transform([&](auto _var) { + debugDataOf(_leaveStatement), + m_graph.returns | ranges::views::transform([&](auto _var) { return readVariable(_var, m_currentBlock); }) | ranges::to }; @@ -494,9 +540,6 @@ void SSAControlFlowGraphBuilder::operator()(Leave const& _leave) void SSAControlFlowGraphBuilder::operator()(Block const& _block) { ScopedSaveAndRestore saveScope(m_scope, m_info.scopes.at(&_block).get()); - for (auto const& statement: _block.statements) - if (auto const* function = std::get_if(&statement)) - registerFunction(*function); for (auto const& statement: _block.statements) std::visit(*this, statement); } @@ -516,7 +559,7 @@ SSACFG::ValueId SSAControlFlowGraphBuilder::operator()(Identifier const& _identi SSACFG::ValueId SSAControlFlowGraphBuilder::operator()(Literal const& _literal) { - return m_graph.newLiteral(_literal.value.value()); + return m_graph.newLiteral(debugDataOf(currentBlock()), _literal.value.value()); } void SSAControlFlowGraphBuilder::assign(std::vector> _variables, Expression const* _expression) @@ -536,40 +579,6 @@ void SSAControlFlowGraphBuilder::assign(std::vectoridentifiers.count(_functionDefinition.name), ""); - Scope::Function& function = std::get(m_scope->identifiers.at(_functionDefinition.name)); - - yulAssert(m_info.scopes.at(&_functionDefinition.body), ""); - Scope* virtualFunctionScope = m_info.scopes.at(m_info.virtualBlocks.at(&_functionDefinition).get()).get(); - yulAssert(virtualFunctionScope, ""); - - // TODO: think about using another root node before the function body here (in particular as defining block for the - // arguments below) - SSACFG::BlockId entryBlock = m_graph.makeBlock(debugDataOf(_functionDefinition.body)); - - auto arguments = _functionDefinition.parameters | ranges::views::transform([&](auto const& _param) { - auto const& var = std::get(virtualFunctionScope->identifiers.at(_param.name)); - // Note: cannot use std::make_tuple since it unwraps reference wrappers. - return std::tuple{std::cref(var), m_graph.newVariable(entryBlock)}; - }) | ranges::to; - auto returns = _functionDefinition.returnVariables | ranges::views::transform([&](auto const& _param) { - return std::cref(std::get(virtualFunctionScope->identifiers.at(_param.name))); - }) | ranges::to; - auto [it, inserted] = m_graph.functionInfos.emplace(std::make_pair(&function, SSACFG::FunctionInfo{ - _functionDefinition.debugData, - function, - entryBlock, - {}, - m_functionSideEffects.at(&_functionDefinition).canContinue, - arguments, - returns - })); - yulAssert(inserted); -} - std::vector SSAControlFlowGraphBuilder::visitFunctionCall(FunctionCall const& _call) { bool canContinue = true; @@ -580,7 +589,7 @@ std::vector SSAControlFlowGraphBuilder::visitFunctionCall(Funct for (auto&& [idx, arg]: _call.arguments | ranges::views::enumerate | ranges::views::reverse) if (!builtin->literalArgument(idx).has_value()) result.inputs.emplace_back(std::visit(*this, arg)); - for (size_t i = 0; i < builtin->returns.size(); ++i) + for (size_t i = 0; i < builtin->numReturns; ++i) result.outputs.emplace_back(m_graph.newVariable(m_currentBlock)); canContinue = builtin->controlFlowSideEffects.canContinue; return result; @@ -588,11 +597,11 @@ std::vector SSAControlFlowGraphBuilder::visitFunctionCall(Funct else { Scope::Function const& function = lookupFunction(_call.functionName.name); - canContinue = m_graph.functionInfos.at(&function).canContinue; + canContinue = m_graph.canContinue; SSACFG::Operation result{{}, SSACFG::Call{debugDataOf(_call), function, _call, canContinue}, {}}; for (auto const& arg: _call.arguments | ranges::views::reverse) result.inputs.emplace_back(std::visit(*this, arg)); - for (size_t i = 0; i < function.returns.size(); ++i) + for (size_t i = 0; i < function.numReturns; ++i) result.outputs.emplace_back(m_graph.newVariable(m_currentBlock)); return result; } @@ -610,13 +619,12 @@ std::vector SSAControlFlowGraphBuilder::visitFunctionCall(Funct SSACFG::ValueId SSAControlFlowGraphBuilder::zero() { - return m_graph.newLiteral(0u); + return m_graph.newLiteral(debugDataOf(currentBlock()), 0u); } SSACFG::ValueId SSAControlFlowGraphBuilder::readVariable(Scope::Variable const& _variable, SSACFG::BlockId _block) { - auto& def = currentDef(_variable, _block); - if (def.has_value()) + if (auto const& def = currentDef(_variable, _block)) return *def; return readVariableRecursive(_variable, _block); } @@ -638,7 +646,7 @@ SSACFG::ValueId SSAControlFlowGraphBuilder::readVariableRecursive(Scope::Variabl } else { - info.incompletePhis.emplace_back(std::make_tuple(phi, std::ref(_variable))); + info.incompletePhis.emplace_back(phi, std::ref(_variable)); } writeVariable(_variable, _block, phi); return phi; @@ -646,25 +654,25 @@ SSACFG::ValueId SSAControlFlowGraphBuilder::readVariableRecursive(Scope::Variabl SSACFG::ValueId SSAControlFlowGraphBuilder::addPhiOperands(Scope::Variable const& _variable, SSACFG::ValueId _phi) { - auto* phi = std::get_if(&m_graph.valueInfo(_phi)); - yulAssert(phi); - for (auto pred: m_graph.block(phi->block).entries) - phi->arguments.emplace_back(readVariable(_variable, pred)); + yulAssert(std::holds_alternative(m_graph.valueInfo(_phi))); + auto& phi = std::get(m_graph.valueInfo(_phi)); + for (auto pred: m_graph.block(phi.block).entries) + phi.arguments.emplace_back(readVariable(_variable, pred)); return tryRemoveTrivialPhi(_phi); } SSACFG::ValueId SSAControlFlowGraphBuilder::tryRemoveTrivialPhi(SSACFG::ValueId _phi) { // TODO: double-check if this is sane - auto* phiInfo = std::get_if(&m_graph.valueInfo(_phi)); - yulAssert(phiInfo); + yulAssert(std::holds_alternative(m_graph.valueInfo(_phi))); + auto& phiInfo = std::get(m_graph.valueInfo(_phi)); SSACFG::ValueId same; - for (SSACFG::ValueId arg: phiInfo->arguments) + for (SSACFG::ValueId arg: phiInfo.arguments) { if (arg == same || arg == _phi) continue; - if (same) + if (same.hasValue()) return _phi; same = arg; } @@ -725,11 +733,11 @@ SSACFG::ValueId SSAControlFlowGraphBuilder::tryRemoveTrivialPhi(SSACFG::ValueId _recurse(_block, _recurse); }); }; - auto phiBlock = phiInfo->block; + auto phiBlock = phiInfo.block; m_graph.block(phiBlock).phis.erase(_phi); findUses(phiBlock, findUses); - if (!same) + if (!same.hasValue()) // This will happen for unreachable paths. // TODO: check how best to deal with this same = m_graph.unreachableValue(); diff --git a/libyul/backends/evm/SSAControlFlowGraphBuilder.h b/libyul/backends/evm/SSAControlFlowGraphBuilder.h index 689e5bf884b3..031016219c87 100644 --- a/libyul/backends/evm/SSAControlFlowGraphBuilder.h +++ b/libyul/backends/evm/SSAControlFlowGraphBuilder.h @@ -20,7 +20,9 @@ */ #pragma once +#include #include +#include #include #include @@ -32,13 +34,25 @@ class SSAControlFlowGraphBuilder SSAControlFlowGraphBuilder( SSACFG& _graph, AsmAnalysisInfo const& _analysisInfo, - std::map const& _functionSideEffects, Dialect const& _dialect ); public: SSAControlFlowGraphBuilder(SSAControlFlowGraphBuilder const&) = delete; SSAControlFlowGraphBuilder& operator=(SSAControlFlowGraphBuilder const&) = delete; - static std::unique_ptr build(AsmAnalysisInfo const& _analysisInfo, Dialect const& _dialect, Block const& _block); + static std::unique_ptr build(AsmAnalysisInfo const& _analysisInfo, Dialect const& _dialect, Block const& _block); + static void buildFunctionGraphs( + ControlFlow& _controlFlow, + AsmAnalysisInfo const& _info, + ControlFlowSideEffectsCollector const& _sideEffects, + Dialect const& _dialect, + std::vector> const& _functions + ); + static std::vector> buildMainGraph( + SSACFG& _cfg, + AsmAnalysisInfo const& _analysisInfo, + Dialect const& _dialect, + Block const& _block + ); void operator()(ExpressionStatement const& _statement); void operator()(Assignment const& _assignment); @@ -60,19 +74,17 @@ class SSAControlFlowGraphBuilder private: void assign(std::vector> _variables, Expression const* _expression); - - void registerFunction(FunctionDefinition const& _function); std::vector visitFunctionCall(FunctionCall const& _call); SSACFG::ValueId zero(); SSACFG::ValueId readVariable(Scope::Variable const& _variable, SSACFG::BlockId _block); SSACFG::ValueId readVariableRecursive(Scope::Variable const& _variable, SSACFG::BlockId _block); SSACFG::ValueId addPhiOperands(Scope::Variable const& _variable, SSACFG::ValueId _phi); + SSACFG::ValueId tryRemoveTrivialPhi(SSACFG::ValueId _phi); void writeVariable(Scope::Variable const& _variable, SSACFG::BlockId _block, SSACFG::ValueId _value); SSACFG& m_graph; AsmAnalysisInfo const& m_info; - std::map const& m_functionSideEffects; Dialect const& m_dialect; SSACFG::BlockId m_currentBlock; SSACFG::BasicBlock& currentBlock() { return m_graph.block(m_currentBlock); } @@ -104,7 +116,6 @@ class SSAControlFlowGraphBuilder SSACFG::BlockId continueBlock; }; std::stack m_forLoopInfo; - SSACFG::FunctionInfo* m_currentFunction = nullptr; std::optional& currentDef(Scope::Variable const& _variable, SSACFG::BlockId _block) { @@ -132,6 +143,8 @@ class SSAControlFlowGraphBuilder std::map _cases, SSACFG::BlockId _defaultCase ); + + std::vector> m_functionDefinitions; }; } diff --git a/test/libyul/yulSSAControlFlowGraph/complex.yul b/test/libyul/yulSSAControlFlowGraph/complex.yul new file mode 100644 index 000000000000..042b313afbe7 --- /dev/null +++ b/test/libyul/yulSSAControlFlowGraph/complex.yul @@ -0,0 +1,179 @@ +{ + function f(a, b) -> c { + for { let x := 42 } lt(x, a) { + x := add(x, 1) + if calldataload(x) + { + sstore(0, x) + leave + sstore(0x01, 0x0101) + } + sstore(0xFF, 0xFFFF) + } + { + switch mload(x) + case 0 { + sstore(0x02, 0x0202) + break + sstore(0x03, 0x0303) + } + case 1 { + sstore(0x04, 0x0404) + leave + sstore(0x05, 0x0505) + } + case 2 { + sstore(0x06, 0x0606) + revert(0, 0) + sstore(0x07, 0x0707) + } + case 3 { + sstore(0x08, 0x0808) + } + default { + if mload(b) { + return(0, 0) + sstore(0x09, 0x0909) + } + sstore(0x0A, 0x0A0A) + } + sstore(0x0B, 0x0B0B) + } + sstore(0x0C, 0x0C0C) + } + pop(f(1,2)) +} +// ---- +// digraph SSACFG { +// nodesep=0.7; +// graph[fontname="DejaVu Sans" ] +// node[shape=box,fontname="DejaVu Sans"]; +// +// Entry0 [label="Entry"]; +// Entry0 -> Block0_0; +// Block0_0 [label="\ +// Block 0\nv2 := f(2, 1)\l\ +// pop(v2)\l\ +// "]; +// Block0_0Exit [label="MainExit"]; +// Block0_0 -> Block0_0Exit; +// FunctionEntry_f_0 [label="function f: +// c := f(v0, v1)"]; +// FunctionEntry_f_0 -> Block1_0; +// Block1_0 [label="\ +// Block 0\n"]; +// Block1_0 -> Block1_0Exit [arrowhead=none]; +// Block1_0Exit [label="Jump" shape=oval]; +// Block1_0Exit -> Block1_1; +// Block1_1 [label="\ +// Block 1\nv4 := φ(\l\ +// Block 0 => 42,\l\ +// Block 21 => v43\l\ +// )\l\ +// v5 := lt(v0, v4)\l\ +// "]; +// Block1_1 -> Block1_1Exit; +// Block1_1Exit [label="{ If v5| { <0> Zero | <1> NonZero }}" shape=Mrecord]; +// Block1_1Exit:0 -> Block1_4; +// Block1_1Exit:1 -> Block1_2; +// Block1_2 [label="\ +// Block 2\nv6 := mload(v4)\l\ +// v7 := eq(0, v6)\l\ +// "]; +// Block1_2 -> Block1_2Exit; +// Block1_2Exit [label="{ If v7| { <0> Zero | <1> NonZero }}" shape=Mrecord]; +// Block1_2Exit:0 -> Block1_7; +// Block1_2Exit:1 -> Block1_6; +// Block1_4 [label="\ +// Block 4\nsstore(3084, 12)\l\ +// "]; +// Block1_4Exit [label="FunctionReturn[v17]"]; +// Block1_4 -> Block1_4Exit; +// Block1_6 [label="\ +// Block 6\nsstore(514, 2)\l\ +// "]; +// Block1_6 -> Block1_6Exit [arrowhead=none]; +// Block1_6Exit [label="Jump" shape=oval]; +// Block1_6Exit -> Block1_4; +// Block1_7 [label="\ +// Block 7\nv13 := eq(1, v6)\l\ +// "]; +// Block1_7 -> Block1_7Exit; +// Block1_7Exit [label="{ If v13| { <0> Zero | <1> NonZero }}" shape=Mrecord]; +// Block1_7Exit:0 -> Block1_10; +// Block1_7Exit:1 -> Block1_9; +// Block1_9 [label="\ +// Block 9\nsstore(1028, 4)\l\ +// "]; +// Block1_9Exit [label="FunctionReturn[v17]"]; +// Block1_9 -> Block1_9Exit; +// Block1_10 [label="\ +// Block 10\nv20 := eq(2, v6)\l\ +// "]; +// Block1_10 -> Block1_10Exit; +// Block1_10Exit [label="{ If v20| { <0> Zero | <1> NonZero }}" shape=Mrecord]; +// Block1_10Exit:0 -> Block1_13; +// Block1_10Exit:1 -> Block1_12; +// Block1_12 [label="\ +// Block 12\nsstore(1542, 6)\l\ +// revert(0, 0)\l\ +// "]; +// Block1_12Exit [label="Terminated"]; +// Block1_12 -> Block1_12Exit; +// Block1_13 [label="\ +// Block 13\nv25 := eq(3, v6)\l\ +// "]; +// Block1_13 -> Block1_13Exit; +// Block1_13Exit [label="{ If v25| { <0> Zero | <1> NonZero }}" shape=Mrecord]; +// Block1_13Exit:0 -> Block1_16; +// Block1_13Exit:1 -> Block1_15; +// Block1_15 [label="\ +// Block 15\nsstore(2056, 8)\l\ +// "]; +// Block1_15 -> Block1_15Exit [arrowhead=none]; +// Block1_15Exit [label="Jump" shape=oval]; +// Block1_15Exit -> Block1_5; +// Block1_16 [label="\ +// Block 16\nv29 := mload(v1)\l\ +// "]; +// Block1_16 -> Block1_16Exit; +// Block1_16Exit [label="{ If v29| { <0> Zero | <1> NonZero }}" shape=Mrecord]; +// Block1_16Exit:0 -> Block1_18; +// Block1_16Exit:1 -> Block1_17; +// Block1_5 [label="\ +// Block 5\nsstore(2827, 11)\l\ +// "]; +// Block1_5 -> Block1_5Exit [arrowhead=none]; +// Block1_5Exit [label="Jump" shape=oval]; +// Block1_5Exit -> Block1_3; +// Block1_17 [label="\ +// Block 17\nreturn(0, 0)\l\ +// "]; +// Block1_17Exit [label="Terminated"]; +// Block1_17 -> Block1_17Exit; +// Block1_18 [label="\ +// Block 18\nsstore(2570, 10)\l\ +// "]; +// Block1_18 -> Block1_18Exit [arrowhead=none]; +// Block1_18Exit [label="Jump" shape=oval]; +// Block1_18Exit -> Block1_5; +// Block1_3 [label="\ +// Block 3\nv43 := add(1, v4)\l\ +// v44 := calldataload(v43)\l\ +// "]; +// Block1_3 -> Block1_3Exit; +// Block1_3Exit [label="{ If v44| { <0> Zero | <1> NonZero }}" shape=Mrecord]; +// Block1_3Exit:0 -> Block1_21; +// Block1_3Exit:1 -> Block1_20; +// Block1_20 [label="\ +// Block 20\nsstore(v43, 0)\l\ +// "]; +// Block1_20Exit [label="FunctionReturn[v45]"]; +// Block1_20 -> Block1_20Exit; +// Block1_21 [label="\ +// Block 21\nsstore(65535, 255)\l\ +// "]; +// Block1_21 -> Block1_21Exit [arrowhead=none]; +// Block1_21Exit [label="Jump" shape=oval]; +// Block1_21Exit -> Block1_1; +// } diff --git a/test/libyul/yulSSAControlFlowGraph/complex2.yul b/test/libyul/yulSSAControlFlowGraph/complex2.yul new file mode 100644 index 000000000000..e7cba5f91681 --- /dev/null +++ b/test/libyul/yulSSAControlFlowGraph/complex2.yul @@ -0,0 +1,195 @@ +{ + function f(a, b) -> c { + for { let x := 42 } lt(x, a) { + x := add(x, 1) + if calldataload(x) + { + sstore(0, x) + leave + sstore(0x01, 0x0101) + } + sstore(0xFF, 0xFFFF) + } + { + switch mload(x) + case 0 { + sstore(0x02, 0x0202) + break + sstore(0x03, 0x0303) + } + case 1 { + sstore(0x04, 0x0404) + leave + sstore(0x05, 0x0505) + } + case 2 { + sstore(0x06, 0x0606) + revert(0, 0) + sstore(0x07, 0x0707) + } + case 3 { + sstore(0x08, 0x0808) + } + default { + if mload(b) { + return(0, 0) + sstore(0x09, 0x0909) + } + sstore(0x0A, 0x0A0A) + } + sstore(0x0B, 0x0B0B) + } + sstore(0x0C, 0x0C0C) + c:=27 + } + sstore(0x1,0x1) + pop(f(1,2)) + let z:= add(5,sload(0)) + let w := f(z,sload(4)) + sstore(z,w) + let x := f(w,sload(5)) + sstore(0x1,x) +} +// ---- +// digraph SSACFG { +// nodesep=0.7; +// graph[fontname="DejaVu Sans" ] +// node[shape=box,fontname="DejaVu Sans"]; +// +// Entry0 [label="Entry"]; +// Entry0 -> Block0_0; +// Block0_0 [label="\ +// Block 0\nsstore(1, 1)\l\ +// v2 := f(2, 1)\l\ +// pop(v2)\l\ +// v4 := sload(0)\l\ +// v6 := add(v4, 5)\l\ +// v8 := sload(4)\l\ +// v9 := f(v8, v6)\l\ +// sstore(v9, v6)\l\ +// v10 := sload(5)\l\ +// v11 := f(v10, v9)\l\ +// sstore(v11, 1)\l\ +// "]; +// Block0_0Exit [label="MainExit"]; +// Block0_0 -> Block0_0Exit; +// FunctionEntry_f_0 [label="function f: +// c := f(v0, v1)"]; +// FunctionEntry_f_0 -> Block1_0; +// Block1_0 [label="\ +// Block 0\n"]; +// Block1_0 -> Block1_0Exit [arrowhead=none]; +// Block1_0Exit [label="Jump" shape=oval]; +// Block1_0Exit -> Block1_1; +// Block1_1 [label="\ +// Block 1\nv4 := φ(\l\ +// Block 0 => 42,\l\ +// Block 21 => v43\l\ +// )\l\ +// v5 := lt(v0, v4)\l\ +// "]; +// Block1_1 -> Block1_1Exit; +// Block1_1Exit [label="{ If v5| { <0> Zero | <1> NonZero }}" shape=Mrecord]; +// Block1_1Exit:0 -> Block1_4; +// Block1_1Exit:1 -> Block1_2; +// Block1_2 [label="\ +// Block 2\nv6 := mload(v4)\l\ +// v7 := eq(0, v6)\l\ +// "]; +// Block1_2 -> Block1_2Exit; +// Block1_2Exit [label="{ If v7| { <0> Zero | <1> NonZero }}" shape=Mrecord]; +// Block1_2Exit:0 -> Block1_7; +// Block1_2Exit:1 -> Block1_6; +// Block1_4 [label="\ +// Block 4\nsstore(3084, 12)\l\ +// "]; +// Block1_4Exit [label="FunctionReturn[27]"]; +// Block1_4 -> Block1_4Exit; +// Block1_6 [label="\ +// Block 6\nsstore(514, 2)\l\ +// "]; +// Block1_6 -> Block1_6Exit [arrowhead=none]; +// Block1_6Exit [label="Jump" shape=oval]; +// Block1_6Exit -> Block1_4; +// Block1_7 [label="\ +// Block 7\nv13 := eq(1, v6)\l\ +// "]; +// Block1_7 -> Block1_7Exit; +// Block1_7Exit [label="{ If v13| { <0> Zero | <1> NonZero }}" shape=Mrecord]; +// Block1_7Exit:0 -> Block1_10; +// Block1_7Exit:1 -> Block1_9; +// Block1_9 [label="\ +// Block 9\nsstore(1028, 4)\l\ +// "]; +// Block1_9Exit [label="FunctionReturn[v17]"]; +// Block1_9 -> Block1_9Exit; +// Block1_10 [label="\ +// Block 10\nv20 := eq(2, v6)\l\ +// "]; +// Block1_10 -> Block1_10Exit; +// Block1_10Exit [label="{ If v20| { <0> Zero | <1> NonZero }}" shape=Mrecord]; +// Block1_10Exit:0 -> Block1_13; +// Block1_10Exit:1 -> Block1_12; +// Block1_12 [label="\ +// Block 12\nsstore(1542, 6)\l\ +// revert(0, 0)\l\ +// "]; +// Block1_12Exit [label="Terminated"]; +// Block1_12 -> Block1_12Exit; +// Block1_13 [label="\ +// Block 13\nv25 := eq(3, v6)\l\ +// "]; +// Block1_13 -> Block1_13Exit; +// Block1_13Exit [label="{ If v25| { <0> Zero | <1> NonZero }}" shape=Mrecord]; +// Block1_13Exit:0 -> Block1_16; +// Block1_13Exit:1 -> Block1_15; +// Block1_15 [label="\ +// Block 15\nsstore(2056, 8)\l\ +// "]; +// Block1_15 -> Block1_15Exit [arrowhead=none]; +// Block1_15Exit [label="Jump" shape=oval]; +// Block1_15Exit -> Block1_5; +// Block1_16 [label="\ +// Block 16\nv29 := mload(v1)\l\ +// "]; +// Block1_16 -> Block1_16Exit; +// Block1_16Exit [label="{ If v29| { <0> Zero | <1> NonZero }}" shape=Mrecord]; +// Block1_16Exit:0 -> Block1_18; +// Block1_16Exit:1 -> Block1_17; +// Block1_5 [label="\ +// Block 5\nsstore(2827, 11)\l\ +// "]; +// Block1_5 -> Block1_5Exit [arrowhead=none]; +// Block1_5Exit [label="Jump" shape=oval]; +// Block1_5Exit -> Block1_3; +// Block1_17 [label="\ +// Block 17\nreturn(0, 0)\l\ +// "]; +// Block1_17Exit [label="Terminated"]; +// Block1_17 -> Block1_17Exit; +// Block1_18 [label="\ +// Block 18\nsstore(2570, 10)\l\ +// "]; +// Block1_18 -> Block1_18Exit [arrowhead=none]; +// Block1_18Exit [label="Jump" shape=oval]; +// Block1_18Exit -> Block1_5; +// Block1_3 [label="\ +// Block 3\nv43 := add(1, v4)\l\ +// v44 := calldataload(v43)\l\ +// "]; +// Block1_3 -> Block1_3Exit; +// Block1_3Exit [label="{ If v44| { <0> Zero | <1> NonZero }}" shape=Mrecord]; +// Block1_3Exit:0 -> Block1_21; +// Block1_3Exit:1 -> Block1_20; +// Block1_20 [label="\ +// Block 20\nsstore(v43, 0)\l\ +// "]; +// Block1_20Exit [label="FunctionReturn[v45]"]; +// Block1_20 -> Block1_20Exit; +// Block1_21 [label="\ +// Block 21\nsstore(65535, 255)\l\ +// "]; +// Block1_21 -> Block1_21Exit [arrowhead=none]; +// Block1_21Exit [label="Jump" shape=oval]; +// Block1_21Exit -> Block1_1; +// } diff --git a/test/libyul/yulSSAControlFlowGraph/function.yul b/test/libyul/yulSSAControlFlowGraph/function.yul new file mode 100644 index 000000000000..11eb1ac6cbe9 --- /dev/null +++ b/test/libyul/yulSSAControlFlowGraph/function.yul @@ -0,0 +1,68 @@ +{ + function f(a, b) -> r { + let x := add(a,b) + r := sub(x,a) + } + function g() { + sstore(0x01, 0x0101) + } + function h(x) { + h(f(x, 0)) + g() + } + function i() -> v, w { + v := 0x0202 + w := 0x0303 + } + let x, y := i() + h(x) + h(y) +} +// ---- +// digraph SSACFG { +// nodesep=0.7; +// graph[fontname="DejaVu Sans" ] +// node[shape=box,fontname="DejaVu Sans"]; +// +// Entry0 [label="Entry"]; +// Entry0 -> Block0_0; +// Block0_0 [label="\ +// Block 0\nv0, v1 := i()\l\ +// h(v0)\l\ +// h(v1)\l\ +// "]; +// Block0_0Exit [label="MainExit"]; +// Block0_0 -> Block0_0Exit; +// FunctionEntry_f_0 [label="function f: +// r := f(v0, v1)"]; +// FunctionEntry_f_0 -> Block1_0; +// Block1_0 [label="\ +// Block 0\nv2 := add(v1, v0)\l\ +// v3 := sub(v0, v2)\l\ +// "]; +// Block1_0Exit [label="FunctionReturn[v3]"]; +// Block1_0 -> Block1_0Exit; +// FunctionEntry_g_0 [label="function g: +// g()"]; +// FunctionEntry_g_0 -> Block2_0; +// Block2_0 [label="\ +// Block 0\nsstore(257, 1)\l\ +// "]; +// Block2_0Exit [label="FunctionReturn[]"]; +// Block2_0 -> Block2_0Exit; +// FunctionEntry_h_0 [label="function h: +// h(v0)"]; +// FunctionEntry_h_0 -> Block3_0; +// Block3_0 [label="\ +// Block 0\nv2 := f(0, v0)\l\ +// "]; +// Block3_0Exit [label="Terminated"]; +// Block3_0 -> Block3_0Exit; +// FunctionEntry_i_0 [label="function i: +// v, w := i()"]; +// FunctionEntry_i_0 -> Block4_0; +// Block4_0 [label="\ +// Block 0\n"]; +// Block4_0Exit [label="FunctionReturn[514, 771]"]; +// Block4_0 -> Block4_0Exit; +// } diff --git a/test/libyul/yulSSAControlFlowGraph/if.yul b/test/libyul/yulSSAControlFlowGraph/if.yul new file mode 100644 index 000000000000..6a47ec28357a --- /dev/null +++ b/test/libyul/yulSSAControlFlowGraph/if.yul @@ -0,0 +1,40 @@ +{ + let x := calldataload(3) + if 0 { + x := calldataload(77) + } + let y := calldataload(x) + sstore(y, 0) +} +// ---- +// digraph SSACFG { +// nodesep=0.7; +// graph[fontname="DejaVu Sans" ] +// node[shape=box,fontname="DejaVu Sans"]; +// +// Entry0 [label="Entry"]; +// Entry0 -> Block0_0; +// Block0_0 [label="\ +// Block 0\nv1 := calldataload(3)\l\ +// "]; +// Block0_0 -> Block0_0Exit; +// Block0_0Exit [label="{ If 0| { <0> Zero | <1> NonZero }}" shape=Mrecord]; +// Block0_0Exit:0 -> Block0_2; +// Block0_0Exit:1 -> Block0_1; +// Block0_1 [label="\ +// Block 1\nv4 := calldataload(77)\l\ +// "]; +// Block0_1 -> Block0_1Exit [arrowhead=none]; +// Block0_1Exit [label="Jump" shape=oval]; +// Block0_1Exit -> Block0_2; +// Block0_2 [label="\ +// Block 2\nv5 := φ(\l\ +// Block 0 => v1,\l\ +// Block 1 => v4\l\ +// )\l\ +// v6 := calldataload(v5)\l\ +// sstore(0, v6)\l\ +// "]; +// Block0_2Exit [label="MainExit"]; +// Block0_2 -> Block0_2Exit; +// } diff --git a/test/libyul/yulSSAControlFlowGraph/switch.yul b/test/libyul/yulSSAControlFlowGraph/switch.yul new file mode 100644 index 000000000000..e0a24dac1367 --- /dev/null +++ b/test/libyul/yulSSAControlFlowGraph/switch.yul @@ -0,0 +1,68 @@ +{ + let x := calldataload(3) + + switch sload(0) + case 0 { + x := calldataload(77) + } + case 1 { + x := calldataload(88) + } + default { + x := calldataload(99) + } + sstore(x, 0) +} +// ---- +// digraph SSACFG { +// nodesep=0.7; +// graph[fontname="DejaVu Sans" ] +// node[shape=box,fontname="DejaVu Sans"]; +// +// Entry0 [label="Entry"]; +// Entry0 -> Block0_0; +// Block0_0 [label="\ +// Block 0\nv1 := calldataload(3)\l\ +// v3 := sload(0)\l\ +// v4 := eq(0, v3)\l\ +// "]; +// Block0_0 -> Block0_0Exit; +// Block0_0Exit [label="{ If v4| { <0> Zero | <1> NonZero }}" shape=Mrecord]; +// Block0_0Exit:0 -> Block0_3; +// Block0_0Exit:1 -> Block0_2; +// Block0_2 [label="\ +// Block 2\nv6 := calldataload(77)\l\ +// "]; +// Block0_2 -> Block0_2Exit [arrowhead=none]; +// Block0_2Exit [label="Jump" shape=oval]; +// Block0_2Exit -> Block0_1; +// Block0_3 [label="\ +// Block 3\nv7 := eq(1, v3)\l\ +// "]; +// Block0_3 -> Block0_3Exit; +// Block0_3Exit [label="{ If v7| { <0> Zero | <1> NonZero }}" shape=Mrecord]; +// Block0_3Exit:0 -> Block0_5; +// Block0_3Exit:1 -> Block0_4; +// Block0_1 [label="\ +// Block 1\nv13 := φ(\l\ +// Block 2 => v6,\l\ +// Block 4 => v10,\l\ +// Block 5 => v12\l\ +// )\l\ +// sstore(0, v13)\l\ +// "]; +// Block0_1Exit [label="MainExit"]; +// Block0_1 -> Block0_1Exit; +// Block0_4 [label="\ +// Block 4\nv10 := calldataload(88)\l\ +// "]; +// Block0_4 -> Block0_4Exit [arrowhead=none]; +// Block0_4Exit [label="Jump" shape=oval]; +// Block0_4Exit -> Block0_1; +// Block0_5 [label="\ +// Block 5\nv12 := calldataload(99)\l\ +// "]; +// Block0_5 -> Block0_5Exit [arrowhead=none]; +// Block0_5Exit [label="Jump" shape=oval]; +// Block0_5Exit -> Block0_1; +// } From 7d87b63991e26dc4a5f2dd78ea8709efd3569506 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Fri, 9 Aug 2024 14:22:30 +0200 Subject: [PATCH 0383/1022] Yul: Dot output of SSA CFG --- libyul/backends/evm/SSAControlFlowGraph.h | 4 +- .../evm/SSAControlFlowGraphBuilder.cpp | 8 - test/CMakeLists.txt | 2 + test/InteractiveTests.h | 2 + test/libyul/ControlFlowGraphTest.cpp | 1 - test/libyul/SSAControlFlowGraphTest.cpp | 318 ++++++++++++++++++ test/libyul/SSAControlFlowGraphTest.h | 42 +++ .../libyul/yulSSAControlFlowGraph/complex.yul | 2 +- .../yulSSAControlFlowGraph/complex2.yul | 2 +- .../yulSSAControlFlowGraph/function.yul | 2 +- test/libyul/yulSSAControlFlowGraph/if.yul | 2 +- test/libyul/yulSSAControlFlowGraph/switch.yul | 2 +- test/tools/CMakeLists.txt | 1 + 13 files changed, 372 insertions(+), 16 deletions(-) create mode 100644 test/libyul/SSAControlFlowGraphTest.cpp create mode 100644 test/libyul/SSAControlFlowGraphTest.h diff --git a/libyul/backends/evm/SSAControlFlowGraph.h b/libyul/backends/evm/SSAControlFlowGraph.h index 311d23e87c41..f4d0ec24232b 100644 --- a/libyul/backends/evm/SSAControlFlowGraph.h +++ b/libyul/backends/evm/SSAControlFlowGraph.h @@ -117,7 +117,7 @@ class SSACFG std::vector operations; std::variant exit = MainExit{}; template - void forEachExit(Callable&& _callable) + void forEachExit(Callable&& _callable) const { if (auto* jump = std::get_if(&exit)) _callable(jump->target); @@ -194,7 +194,7 @@ class SSACFG } ValueId newLiteral(langutil::DebugData::ConstPtr _debugData, u256 _value) { - auto [it, inserted] = m_literals.emplace(_value, ValueId{m_valueInfos.size()}); + auto [it, inserted] = m_literals.emplace(_value, SSACFG::ValueId{m_valueInfos.size()}); if (inserted) m_valueInfos.emplace_back(LiteralValue{std::move(_debugData), _value}); else diff --git a/libyul/backends/evm/SSAControlFlowGraphBuilder.cpp b/libyul/backends/evm/SSAControlFlowGraphBuilder.cpp index 18720e9bc31a..d9dc7663ccec 100644 --- a/libyul/backends/evm/SSAControlFlowGraphBuilder.cpp +++ b/libyul/backends/evm/SSAControlFlowGraphBuilder.cpp @@ -176,14 +176,6 @@ void cleanUnreachable(SSACFG& _cfg) { auto& block = _cfg.block(blockId); - for (auto phi: block.phis) - { - auto& phiValue = std::get(_cfg.valueInfo(phi)); - yulAssert(block.entries.size() == phiValue.arguments.size()); - for (auto&& [entry, arg]: ranges::zip_view(block.entries, phiValue.arguments)) - yulAssert((reachabilityCheck.visited.count(entry) == 0) == isUnreachableValue(arg)); - } - std::set maybeTrivialPhi; for (auto it = block.entries.begin(); it != block.entries.end();) if (reachabilityCheck.visited.count(*it)) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 5308a55f7826..d3498965dc24 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -153,6 +153,8 @@ set(libyul_sources libyul/ObjectCompilerTest.h libyul/ObjectParser.cpp libyul/Parser.cpp + libyul/SSAControlFlowGraphTest.cpp + libyul/SSAControlFlowGraphTest.h libyul/StackLayoutGeneratorTest.cpp libyul/StackLayoutGeneratorTest.h libyul/StackShufflingTest.cpp diff --git a/test/InteractiveTests.h b/test/InteractiveTests.h index 4c2077576cfa..e043fcdbe676 100644 --- a/test/InteractiveTests.h +++ b/test/InteractiveTests.h @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -67,6 +68,7 @@ Testsuite const g_interactiveTestsuites[] = { {"Yul Interpreter", "libyul", "yulInterpreterTests", false, false, &yul::test::YulInterpreterTest::create}, {"Yul Object Compiler", "libyul", "objectCompiler", false, false, &yul::test::ObjectCompilerTest::create}, {"Yul Control Flow Graph", "libyul", "yulControlFlowGraph", false, false, &yul::test::ControlFlowGraphTest::create}, + {"Yul SSA Control Flow Graph", "libyul", "yulSSAControlFlowGraph", false, false, &yul::test::SSAControlFlowGraphTest::create}, {"Yul Stack Layout", "libyul", "yulStackLayout", false, false, &yul::test::StackLayoutGeneratorTest::create}, {"Yul Stack Shuffling", "libyul", "yulStackShuffling", false, false, &yul::test::StackShufflingTest::create}, {"Control Flow Side Effects", "libyul", "controlFlowSideEffects", false, false, &yul::test::ControlFlowSideEffectsTest::create}, diff --git a/test/libyul/ControlFlowGraphTest.cpp b/test/libyul/ControlFlowGraphTest.cpp index 5c9bba8d41e5..0060b850efbb 100644 --- a/test/libyul/ControlFlowGraphTest.cpp +++ b/test/libyul/ControlFlowGraphTest.cpp @@ -130,7 +130,6 @@ class ControlFlowGraphPrinter }, [&](CFG::BuiltinCall const& _call) { m_stream << _call.functionCall.get().functionName.name.str() << ": "; - }, [&](CFG::Assignment const& _assignment) { m_stream << "Assignment("; diff --git a/test/libyul/SSAControlFlowGraphTest.cpp b/test/libyul/SSAControlFlowGraphTest.cpp new file mode 100644 index 000000000000..e12751411c13 --- /dev/null +++ b/test/libyul/SSAControlFlowGraphTest.cpp @@ -0,0 +1,318 @@ +/* + This file is part of solidity. + + solidity is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + solidity is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with solidity. If not, see . +*/ +// SPDX-License-Identifier: GPL-3.0 + +#include +#include +#include + +#include +#include + +#include +#include + +#include +#include + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wtautological-compare" +#include +#pragma GCC diagnostic pop + +#ifdef ISOLTEST +#include +#endif + +using namespace solidity; +using namespace solidity::util; +using namespace solidity::langutil; +using namespace solidity::yul; +using namespace solidity::yul::test; +using namespace solidity::frontend; +using namespace solidity::frontend::test; + +std::unique_ptr SSAControlFlowGraphTest::create(TestCase::Config const& _config) { + return std::make_unique(_config.filename); +} + +SSAControlFlowGraphTest::SSAControlFlowGraphTest(std::string const& _filename): TestCase(_filename) +{ + m_source = m_reader.source(); + auto dialectName = m_reader.stringSetting("dialect", "evm"); + m_dialect = &dialect(dialectName, solidity::test::CommonOptions::get().evmVersion()); + m_expectation = m_reader.simpleExpectations(); +} + +class SSACFGPrinter +{ +public: + SSACFGPrinter(SSACFG const& _cfg, SSACFG::BlockId _blockId) + { + printBlock(_cfg, _blockId, 0); + } + SSACFGPrinter(SSACFG const& _cfg, size_t _functionIndex, Scope::Function const& _function) + { + printFunction(_cfg, _functionIndex, _function); + } + friend std::ostream& operator<<(std::ostream& stream, SSACFGPrinter const& printer) { + stream << printer.m_result.str(); + return stream; + } +private: + std::string varToString(SSACFG const& _cfg, SSACFG::ValueId _var) { + if (_var.value == std::numeric_limits::max()) + return "INVALID"; + auto const& info = _cfg.valueInfo(_var); + return std::visit( + util::GenericVisitor{ + [&](SSACFG::UnreachableValue const&) -> std::string { + return "[unreachable]"; + }, + [&](SSACFG::PhiValue const&) -> std::string { + return fmt::format("v{}", _var.value); + }, + [&](SSACFG::VariableValue const&) -> std::string { + return fmt::format("v{}", _var.value); + }, + [&](SSACFG::LiteralValue const& _literal) -> std::string { + return util::formatNumberReadable(_literal.value); + } + }, + info + ); + } + + std::string formatPhi(SSACFG const& _cfg, SSACFG::PhiValue const& _phiValue) + { + auto const transform = [&](SSACFG::ValueId const& valueId) { return varToString(_cfg, valueId); }; + std::vector formattedArgs; + formattedArgs.reserve(_phiValue.arguments.size()); + for(auto const& [arg, entry] : ranges::zip_view(_phiValue.arguments | ranges::views::transform(transform), _cfg.block(_phiValue.block).entries)) + { + formattedArgs.push_back(fmt::format("Block {} => {}", entry.value, arg)); + } + return fmt::format("φ(\\l\\\n\t{}\\l\\\n)", fmt::join(formattedArgs, ",\\l\\\n\t")); + } + + void writeBlock(SSACFG const& _cfg, SSACFG::BlockId const& _id, SSACFG::BasicBlock const& _block, size_t _functionIndex) + { + auto const transform = [&](SSACFG::ValueId const& valueId) { return varToString(_cfg, valueId); }; + bool entryBlock = _id.value == 0 && _functionIndex == 0; + if (entryBlock) + { + m_result << fmt::format("Entry{} [label=\"Entry\"];\n", _functionIndex); + m_result << fmt::format("Entry{} -> Block{}_{};\n", _functionIndex, _functionIndex, _id.value); + } + { + m_result << fmt::format("Block{1}_{0} [label=\"\\\nBlock {0}\\n", _id.value, _functionIndex); + for (auto const& phi : _block.phis) + { + auto const* phiValue = std::get_if(&_cfg.valueInfo(phi)); + solAssert(phiValue); + m_result << fmt::format("v{} := {}\\l\\\n", phi.value, formatPhi(_cfg, *phiValue)); + } + for (auto const& operation : _block.operations) + { + std::string const label = std::visit(util::GenericVisitor{ + [&](SSACFG::Call const& _call) { + return _call.function.get().name.str(); + }, + [&](SSACFG::BuiltinCall const& _call) { + return _call.builtin.get().name.str(); + }, + }, operation.kind); + if (operation.outputs.empty()) + m_result << fmt::format( + "{}({})\\l\\\n", + label, + fmt::join(operation.inputs | ranges::views::transform(transform), ", ") + ); + else + m_result << fmt::format( + "{} := {}({})\\l\\\n", + fmt::join(operation.outputs | ranges::views::transform(transform), ", "), + label, + fmt::join(operation.inputs | ranges::views::transform(transform), ", ") + ); + } + m_result << "\"];\n"; + std::visit(util::GenericVisitor{ + [&](SSACFG::BasicBlock::MainExit const&) + { + m_result << fmt::format("Block{}_{}Exit [label=\"MainExit\"];\n", _functionIndex, _id.value); + m_result << fmt::format("Block{1}_{0} -> Block{1}_{0}Exit;\n", _id.value, _functionIndex); + }, + [&](SSACFG::BasicBlock::Jump const& _jump) + { + m_result << fmt::format("Block{1}_{0} -> Block{1}_{0}Exit [arrowhead=none];\n", _id.value, _functionIndex); + m_result << fmt::format("Block{}_{}Exit [label=\"Jump\" shape=oval];\n", _functionIndex, _id.value); + m_result << fmt::format("Block{}_{}Exit -> Block{}_{};\n", _functionIndex, _id.value, _functionIndex, _jump.target.value); + }, + [&](SSACFG::BasicBlock::ConditionalJump const& _conditionalJump) + { + m_result << "Block" << _functionIndex << "_" << _id.value << " -> Block" << _functionIndex << "_" << _id.value << "Exit;\n"; + m_result << "Block" << _functionIndex << "_" << _id.value << "Exit [label=\"{ If "; + m_result << varToString(_cfg, _conditionalJump.condition); + m_result << "| { <0> Zero | <1> NonZero }}\" shape=Mrecord];\n"; + m_result << "Block" << _functionIndex << "_" << _id.value; + m_result << "Exit:0 -> Block" << _functionIndex << "_" << _conditionalJump.zero.value << ";\n"; + m_result << "Block" << _functionIndex << "_" << _id.value; + m_result << "Exit:1 -> Block" << _functionIndex << "_" << _conditionalJump.nonZero.value << ";\n"; + }, + [&](SSACFG::BasicBlock::JumpTable const& jt) + { + m_result << "Block" << _functionIndex << "_" << _id.value << " -> Block" << _functionIndex << "_" << _id.value << "Exit;\n"; + std::string options; + for(const auto& jumpCase : jt.cases) + { + if (!options.empty()) + options += " | "; + options += fmt::format("<{0}> {0}", formatNumber(jumpCase.first)); + } + if (!options.empty()) + options += " | "; + options += " default"; + m_result << fmt::format("Block{}_{}Exit [label=\"{{ JT | {{ {} }} }}\" shape=Mrecord];\n", _functionIndex, _id.value, options); + for(const auto& jumpCase : jt.cases) + { + m_result << fmt::format("Block{}_{}Exit:{} -> Block{}_{};\n", _functionIndex, _id.value, formatNumber(jumpCase.first), _functionIndex, jumpCase.second.value); + } + m_result << fmt::format("Block{}_{}Exit:default -> Block{}_{};\n", _functionIndex, _id.value, _functionIndex, jt.defaultCase.value); + }, + [&](SSACFG::BasicBlock::FunctionReturn const& fr) + { + m_result << "Block" << _functionIndex << "_" << _id.value << "Exit [label=\"FunctionReturn[" + << fmt::format("{}", fmt::join(fr.returnValues | ranges::views::transform(transform), ", ")) + << "]\"];\n"; + m_result << "Block" << _functionIndex << "_" << _id.value << " -> Block" << _functionIndex << "_" << _id.value << "Exit;\n"; + }, + [&](SSACFG::BasicBlock::Terminated const&) + { + m_result << "Block" << _functionIndex << "_" << _id.value << "Exit [label=\"Terminated\"];\n"; + m_result << "Block" << _functionIndex << "_" << _id.value << " -> Block" << _functionIndex << "_" << _id.value << "Exit;\n"; + } + }, _block.exit); + } + + } + + void printBlock(SSACFG const& _cfg, SSACFG::BlockId const& _rootId, size_t _functionIndex) + { + std::set explored{}; + explored.insert(_rootId); + + std::deque toVisit{}; + toVisit.emplace_back(_rootId); + + while(!toVisit.empty()) + { + auto const id = toVisit.front(); + toVisit.pop_front(); + auto const& block = _cfg.block(id); + writeBlock(_cfg, id, block, _functionIndex); + block.forEachExit( + [&](SSACFG::BlockId const& _exitBlock) + { + if (explored.count(_exitBlock) == 0) + { + explored.insert(_exitBlock); + toVisit.emplace_back(_exitBlock); + } + } + ); + } + } + + void printFunction(SSACFG const& _cfg, size_t _functionIndex, Scope::Function const& _fun) + { + static auto constexpr returnsTransform = [](auto const& functionReturnValue) { return functionReturnValue.get().name.str(); }; + static auto constexpr argsTransform = [](auto const& arg) { return fmt::format("v{}", std::get<1>(arg).value); }; + m_result << "FunctionEntry_" << _fun.name.str() << "_" << _cfg.entry.value << " [label=\""; + if (!_cfg.returns.empty()) + m_result << fmt::format("function {0}:\n {1} := {0}({2})", _fun.name.str(), fmt::join(_cfg.returns | ranges::views::transform(returnsTransform), ", "), fmt::join(_cfg.arguments | ranges::views::transform(argsTransform), ", ")); + else + m_result << fmt::format("function {0}:\n {0}({1})", _fun.name.str(), fmt::join(_cfg.arguments | ranges::views::transform(argsTransform), ", ")); + m_result << "\"];\n"; + m_result << "FunctionEntry_" << _fun.name.str() << "_" << _cfg.entry.value << " -> Block" << _functionIndex << "_" << _cfg.entry.value << ";\n"; + printBlock(_cfg, _cfg.entry, _functionIndex); + } + + std::stringstream m_result{}; +}; + +TestCase::TestResult SSAControlFlowGraphTest::run(std::ostream& _stream, std::string const& _linePrefix, bool const _formatted) +{ + ErrorList errors; + auto [object, analysisInfo] = parse(m_source, *m_dialect, errors); + if (!object || !analysisInfo || Error::containsErrors(errors)) + { + AnsiColorized(_stream, _formatted, {formatting::BOLD, formatting::RED}) << _linePrefix << "Error parsing source." << std::endl; + return TestResult::FatalError; + } + + std::ostringstream output; + + auto info = AsmAnalyzer::analyzeStrictAssertCorrect(*m_dialect, *object); + std::unique_ptr controlFlow = SSAControlFlowGraphBuilder::build( + info, + *m_dialect, + object->code()->root() + ); + + output << "digraph SSACFG {\nnodesep=0.7;\ngraph[fontname=\"DejaVu Sans\"]\nnode[shape=box,fontname=\"DejaVu Sans\"];\n\n"; + output << SSACFGPrinter(*controlFlow->mainGraph, SSACFG::BlockId{0}); + size_t index = 1; + for (auto const& [function, functionGraph]: controlFlow->functionGraphMapping) + output << SSACFGPrinter(*functionGraph, index++, *function); + output << "}\n"; + + m_obtainedResult = output.str(); + + auto result = checkResult(_stream, _linePrefix, _formatted); + +#ifdef ISOLTEST + char* graphDisplayer = nullptr; + // The environment variables specify an optional command that will receive the graph encoded in DOT through stdin. + // Examples for suitable commands are ``dot -Tx11:cairo`` or ``xdot -``. + if (result == TestResult::Failure) + // ISOLTEST_DISPLAY_GRAPHS_ON_FAILURE_COMMAND will run on all failing tests (intended for use during modifications). + graphDisplayer = getenv("ISOLTEST_DISPLAY_GRAPHS_ON_FAILURE_COMMAND"); + else if (result == TestResult::Success) + // ISOLTEST_DISPLAY_GRAPHS_ON_FAILURE_COMMAND will run on all succeeding tests (intended for use during reviews). + graphDisplayer = getenv("ISOLTEST_DISPLAY_GRAPHS_ON_SUCCESS_COMMAND"); + + if (graphDisplayer) + { + if (result == TestResult::Success) + std::cout << std::endl << m_source << std::endl; + boost::process::opstream pipe; + boost::process::child child(graphDisplayer, boost::process::std_in < pipe); + + pipe << output.str(); + pipe.flush(); + pipe.pipe().close(); + if (result == TestResult::Success) + child.wait(); + else + child.detach(); + } +#endif + + return result; + +} diff --git a/test/libyul/SSAControlFlowGraphTest.h b/test/libyul/SSAControlFlowGraphTest.h new file mode 100644 index 000000000000..f976be03c339 --- /dev/null +++ b/test/libyul/SSAControlFlowGraphTest.h @@ -0,0 +1,42 @@ +/* +This file is part of solidity. + +solidity is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + solidity is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with solidity. If not, see . +*/ +// SPDX-License-Identifier: GPL-3.0 + +#pragma once + +#include + +#include + +namespace solidity::yul +{ +struct Dialect; + +namespace test +{ + +class SSAControlFlowGraphTest: public solidity::frontend::test::TestCase +{ +public: + static std::unique_ptr create(Config const& _config); + explicit SSAControlFlowGraphTest(std::string const& _filename); + TestResult run(std::ostream& _stream, std::string const& _linePrefix = "", bool const _formatted = false) override; +private: + Dialect const* m_dialect = nullptr; +}; +} +} diff --git a/test/libyul/yulSSAControlFlowGraph/complex.yul b/test/libyul/yulSSAControlFlowGraph/complex.yul index 042b313afbe7..d7e16c9f6f99 100644 --- a/test/libyul/yulSSAControlFlowGraph/complex.yul +++ b/test/libyul/yulSSAControlFlowGraph/complex.yul @@ -46,7 +46,7 @@ // ---- // digraph SSACFG { // nodesep=0.7; -// graph[fontname="DejaVu Sans" ] +// graph[fontname="DejaVu Sans"] // node[shape=box,fontname="DejaVu Sans"]; // // Entry0 [label="Entry"]; diff --git a/test/libyul/yulSSAControlFlowGraph/complex2.yul b/test/libyul/yulSSAControlFlowGraph/complex2.yul index e7cba5f91681..863b021d1e7b 100644 --- a/test/libyul/yulSSAControlFlowGraph/complex2.yul +++ b/test/libyul/yulSSAControlFlowGraph/complex2.yul @@ -53,7 +53,7 @@ // ---- // digraph SSACFG { // nodesep=0.7; -// graph[fontname="DejaVu Sans" ] +// graph[fontname="DejaVu Sans"] // node[shape=box,fontname="DejaVu Sans"]; // // Entry0 [label="Entry"]; diff --git a/test/libyul/yulSSAControlFlowGraph/function.yul b/test/libyul/yulSSAControlFlowGraph/function.yul index 11eb1ac6cbe9..aa4b6ac97f56 100644 --- a/test/libyul/yulSSAControlFlowGraph/function.yul +++ b/test/libyul/yulSSAControlFlowGraph/function.yul @@ -21,7 +21,7 @@ // ---- // digraph SSACFG { // nodesep=0.7; -// graph[fontname="DejaVu Sans" ] +// graph[fontname="DejaVu Sans"] // node[shape=box,fontname="DejaVu Sans"]; // // Entry0 [label="Entry"]; diff --git a/test/libyul/yulSSAControlFlowGraph/if.yul b/test/libyul/yulSSAControlFlowGraph/if.yul index 6a47ec28357a..9045d8034003 100644 --- a/test/libyul/yulSSAControlFlowGraph/if.yul +++ b/test/libyul/yulSSAControlFlowGraph/if.yul @@ -9,7 +9,7 @@ // ---- // digraph SSACFG { // nodesep=0.7; -// graph[fontname="DejaVu Sans" ] +// graph[fontname="DejaVu Sans"] // node[shape=box,fontname="DejaVu Sans"]; // // Entry0 [label="Entry"]; diff --git a/test/libyul/yulSSAControlFlowGraph/switch.yul b/test/libyul/yulSSAControlFlowGraph/switch.yul index e0a24dac1367..f6c084b001a7 100644 --- a/test/libyul/yulSSAControlFlowGraph/switch.yul +++ b/test/libyul/yulSSAControlFlowGraph/switch.yul @@ -16,7 +16,7 @@ // ---- // digraph SSACFG { // nodesep=0.7; -// graph[fontname="DejaVu Sans" ] +// graph[fontname="DejaVu Sans"] // node[shape=box,fontname="DejaVu Sans"]; // // Entry0 [label="Entry"]; diff --git a/test/tools/CMakeLists.txt b/test/tools/CMakeLists.txt index 44a5e2aa701e..5c1d41b7f595 100644 --- a/test/tools/CMakeLists.txt +++ b/test/tools/CMakeLists.txt @@ -40,6 +40,7 @@ add_executable(isoltest ../libsolidity/SMTCheckerTest.cpp ../libyul/Common.cpp ../libyul/ControlFlowGraphTest.cpp + ../libyul/SSAControlFlowGraphTest.cpp ../libyul/ControlFlowSideEffectsTest.cpp ../libyul/EVMCodeTransformTest.cpp ../libyul/FunctionSideEffects.cpp From 80533d806b0755dd2fa288af73a1bac35d8ec895 Mon Sep 17 00:00:00 2001 From: r0qs Date: Fri, 31 May 2024 13:50:04 +0200 Subject: [PATCH 0384/1022] Convert Yul CFG to Json --- libsolidity/interface/CompilerStack.cpp | 11 ++ libsolidity/interface/CompilerStack.h | 3 + libsolidity/interface/StandardCompiler.cpp | 13 +- libyul/CMakeLists.txt | 2 + libyul/YulControlFlowGraphExporter.cpp | 212 +++++++++++++++++++++ libyul/YulControlFlowGraphExporter.h | 42 ++++ libyul/YulStack.cpp | 41 ++++ libyul/YulStack.h | 3 + solc/CommandLineInterface.cpp | 32 +++- solc/CommandLineInterface.h | 1 + solc/CommandLineParser.cpp | 2 + solc/CommandLineParser.h | 2 + test/solc/CommandLineParser.cpp | 3 +- 13 files changed, 362 insertions(+), 5 deletions(-) create mode 100644 libyul/YulControlFlowGraphExporter.cpp create mode 100644 libyul/YulControlFlowGraphExporter.h diff --git a/libsolidity/interface/CompilerStack.cpp b/libsolidity/interface/CompilerStack.cpp index 1f432db40fca..ce9525c2b6e6 100644 --- a/libsolidity/interface/CompilerStack.cpp +++ b/libsolidity/interface/CompilerStack.cpp @@ -924,6 +924,16 @@ Json const& CompilerStack::yulIRAst(std::string const& _contractName) const return contract(_contractName).yulIRAst; } +Json const& CompilerStack::yulCFGJson(std::string const& _contractName) const +{ + if (m_stackState != CompilationSuccessful) + solThrow(CompilerError, "Compilation was not successful."); + + solUnimplementedAssert(!isExperimentalSolidity()); + + return contract(_contractName).yulCFGJson; +} + std::string const& CompilerStack::yulIROptimized(std::string const& _contractName) const { solAssert(m_stackState == CompilationSuccessful, "Compilation was not successful."); @@ -1506,6 +1516,7 @@ void CompilerStack::generateIR(ContractDefinition const& _contract, bool _unopti ); compiledContract.yulIRAst = stack.astJson(); + compiledContract.yulCFGJson = stack.cfgJson(); if (!_unoptimizedOnly) { stack.optimize(); diff --git a/libsolidity/interface/CompilerStack.h b/libsolidity/interface/CompilerStack.h index 25863b6d0690..0a62cbf7efaf 100644 --- a/libsolidity/interface/CompilerStack.h +++ b/libsolidity/interface/CompilerStack.h @@ -298,6 +298,8 @@ class CompilerStack: public langutil::CharStreamProvider, public evmasm::Abstrac /// @returns the optimized IR representation of a contract AST in JSON format. Json const& yulIROptimizedAst(std::string const& _contractName) const; + Json const& yulCFGJson(std::string const& _contractName) const; + /// @returns the assembled object for a contract. virtual evmasm::LinkerObject const& object(std::string const& _contractName) const override; @@ -411,6 +413,7 @@ class CompilerStack: public langutil::CharStreamProvider, public evmasm::Abstrac std::string yulIROptimized; ///< Reparsed and possibly optimized Yul IR code. Json yulIRAst; ///< JSON AST of Yul IR code. Json yulIROptimizedAst; ///< JSON AST of optimized Yul IR code. + Json yulCFGJson; ///< JSON CFG of Yul IR code. util::LazyInit metadata; ///< The metadata json that will be hashed into the chain. util::LazyInit abi; util::LazyInit storageLayout; diff --git a/libsolidity/interface/StandardCompiler.cpp b/libsolidity/interface/StandardCompiler.cpp index 0c1ccb6b7653..385e48c2236e 100644 --- a/libsolidity/interface/StandardCompiler.cpp +++ b/libsolidity/interface/StandardCompiler.cpp @@ -180,7 +180,7 @@ bool hashMatchesContent(std::string const& _hash, std::string const& _content) bool isArtifactRequested(Json const& _outputSelection, std::string const& _artifact, bool _wildcardMatchesExperimental) { - static std::set experimental{"ir", "irAst", "irOptimized", "irOptimizedAst"}; + static std::set experimental{"ir", "irAst", "irOptimized", "irOptimizedAst", "yulCFGJson"}; for (auto const& selectedArtifactJson: _outputSelection) { std::string const& selectedArtifact = selectedArtifactJson.get(); @@ -191,6 +191,9 @@ bool isArtifactRequested(Json const& _outputSelection, std::string const& _artif return true; else if (selectedArtifact == "*") { + // TODO: yulCFGJson is only experimental now, so it should not be matched by "*". + if (_artifact == "yulCFGJson") + return false; // "ir", "irOptimized" can only be matched by "*" if activated. if (experimental.count(_artifact) == 0 || _wildcardMatchesExperimental) return true; @@ -264,7 +267,7 @@ bool isBinaryRequested(Json const& _outputSelection) // This does not include "evm.methodIdentifiers" on purpose! static std::vector const outputsThatRequireBinaries = std::vector{ "*", - "ir", "irAst", "irOptimized", "irOptimizedAst", + "ir", "irAst", "irOptimized", "irOptimizedAst", "yulCFGJson", "evm.gasEstimates", "evm.legacyAssembly", "evm.assembly" } + evmObjectComponents("bytecode") + evmObjectComponents("deployedBytecode"); @@ -307,7 +310,7 @@ CompilerStack::IROutputSelection irOutputSelection(Json const& _outputSelection) for (auto const& requests: fileRequests) for (auto const& request: requests) { - if (request == "irOptimized" || request == "irOptimizedAst") + if (request == "irOptimized" || request == "irOptimizedAst" || request == "yulCFGJson") return CompilerStack::IROutputSelection::UnoptimizedAndOptimized; if (request == "ir" || request == "irAst") @@ -1485,6 +1488,8 @@ Json StandardCompiler::compileSolidity(StandardCompiler::InputsAndSettings _inpu contractData["irOptimized"] = compilerStack.yulIROptimized(contractName); if (compilationSuccess && isArtifactRequested(_inputsAndSettings.outputSelection, file, name, "irOptimizedAst", wildcardMatchesExperimental)) contractData["irOptimizedAst"] = compilerStack.yulIROptimizedAst(contractName); + if (compilationSuccess && isArtifactRequested(_inputsAndSettings.outputSelection, file, name, "yulCFGJson", wildcardMatchesExperimental)) + contractData["yulCFGJson"] = compilerStack.yulCFGJson(contractName); // EVM Json evmData; @@ -1698,6 +1703,8 @@ Json StandardCompiler::compileYul(InputsAndSettings _inputsAndSettings) output["contracts"][sourceName][contractName]["irOptimized"] = stack.print(); if (isArtifactRequested(_inputsAndSettings.outputSelection, sourceName, contractName, "evm.assembly", wildcardMatchesExperimental)) output["contracts"][sourceName][contractName]["evm"]["assembly"] = object.assembly->assemblyString(stack.debugInfoSelection()); + if (isArtifactRequested(_inputsAndSettings.outputSelection, sourceName, contractName, "yulCFGJson", wildcardMatchesExperimental)) + output["contracts"][sourceName][contractName]["yulCFGJson"] = stack.cfgJson(); return output; } diff --git a/libyul/CMakeLists.txt b/libyul/CMakeLists.txt index c54513d9ab91..c0082f5d69fd 100644 --- a/libyul/CMakeLists.txt +++ b/libyul/CMakeLists.txt @@ -39,6 +39,8 @@ add_library(yul ScopeFiller.h Utilities.cpp Utilities.h + YulControlFlowGraphExporter.h + YulControlFlowGraphExporter.cpp YulName.h YulString.h backends/evm/AbstractAssembly.h diff --git a/libyul/YulControlFlowGraphExporter.cpp b/libyul/YulControlFlowGraphExporter.cpp new file mode 100644 index 000000000000..3f347fcf4f91 --- /dev/null +++ b/libyul/YulControlFlowGraphExporter.cpp @@ -0,0 +1,212 @@ +/* + This file is part of solidity. + + solidity is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + solidity is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with solidity. If not, see . +*/ +// SPDX-License-Identifier: GPL-3.0 + +#include +#include + +#include +#include + +#include +#include +#include + +using namespace solidity; +using namespace solidity::langutil; +using namespace solidity::util; +using namespace solidity::yul; + +YulControlFlowGraphExporter::YulControlFlowGraphExporter(ControlFlow const& _controlFlow): m_controlFlow(_controlFlow) +{ +} + +std::string YulControlFlowGraphExporter::varToString(SSACFG const& _cfg, SSACFG::ValueId _var) +{ + if (_var.value == std::numeric_limits::max()) + return std::string("INVALID"); + auto const& info = _cfg.valueInfo(_var); + return std::visit( + util::GenericVisitor{ + [&](SSACFG::UnreachableValue const&) -> std::string { + return "[unreachable]"; + }, + [&](SSACFG::LiteralValue const& _literal) { + return toCompactHexWithPrefix(_literal.value); + }, + [&](auto const&) { + return "v" + std::to_string(_var.value); + } + }, + info + ); +} + +Json YulControlFlowGraphExporter::run() +{ + Json yulObjectJson = Json::object(); + yulObjectJson["blocks"] = exportBlock(*m_controlFlow.mainGraph, SSACFG::BlockId{0}); + + Json functionsJson = Json::object(); + for (auto const& [function, functionGraph]: m_controlFlow.functionGraphMapping) + functionsJson[function->name.str()] = exportFunction(*functionGraph); + yulObjectJson["functions"] = functionsJson; + + return yulObjectJson; +} + +Json YulControlFlowGraphExporter::exportFunction(SSACFG const& _cfg) +{ + Json functionJson = Json::object(); + functionJson["type"] = "Function"; + functionJson["entry"] = "Block" + std::to_string(_cfg.entry.value); + functionJson["arguments"] = Json::array(); + for (auto const& [arg, valueId]: _cfg.arguments) + functionJson["arguments"].emplace_back(arg.get().name.str()); + functionJson["returns"] = Json::array(); + for (auto const& ret: _cfg.returns) + functionJson["returns"].emplace_back(ret.get().name.str()); + functionJson["blocks"] = exportBlock(_cfg, _cfg.entry); + return functionJson; +} + +Json YulControlFlowGraphExporter::exportBlock(SSACFG const& _cfg, SSACFG::BlockId _entryId) +{ + Json blocksJson = Json::array(); + util::BreadthFirstSearch bfs{{{_entryId}}}; + bfs.run([&](SSACFG::BlockId _blockId, auto _addChild) { + auto const& block = _cfg.block(_blockId); + // Convert current block to JSON + Json blockJson = toJson(_cfg, _blockId); + + Json exitBlockJson = Json::object(); + std::visit(util::GenericVisitor{ + [&](SSACFG::BasicBlock::MainExit const&) { + exitBlockJson["targets"] = { "Block" + std::to_string(_blockId.value) }; + exitBlockJson["type"] = "MainExit"; + }, + [&](SSACFG::BasicBlock::Jump const& _jump) + { + exitBlockJson["targets"] = { "Block" + std::to_string(_jump.target.value) }; + exitBlockJson["type"] = "Jump"; + _addChild(_jump.target); + }, + [&](SSACFG::BasicBlock::ConditionalJump const& _conditionalJump) + { + exitBlockJson["targets"] = { "Block" + std::to_string(_conditionalJump.zero.value), "Block" + std::to_string(_conditionalJump.nonZero.value) }; + exitBlockJson["cond"] = varToString(_cfg, _conditionalJump.condition); + exitBlockJson["type"] = "ConditionalJump"; + + _addChild(_conditionalJump.zero); + _addChild(_conditionalJump.nonZero); + }, + [&](SSACFG::BasicBlock::FunctionReturn const& _return) { + exitBlockJson["instructions"] = toJson(_cfg, _return.returnValues); + exitBlockJson["targets"] = { "Block" + std::to_string(_blockId.value) }; + exitBlockJson["type"] = "FunctionReturn"; + }, + [&](SSACFG::BasicBlock::Terminated const&) { + exitBlockJson["targets"] = { "Block" + std::to_string(_blockId.value) }; + exitBlockJson["type"] = "Terminated"; + }, + [&](SSACFG::BasicBlock::JumpTable const&) { + yulAssert(false); + } + }, block.exit); + blockJson["exit"] = exitBlockJson; + blocksJson.emplace_back(blockJson); + }); + + return blocksJson; +} + +Json YulControlFlowGraphExporter::toJson(SSACFG const& _cfg, SSACFG::BlockId _blockId) +{ + Json blockJson = Json::object(); + auto const& block = _cfg.block(_blockId); + + blockJson["id"] = "Block" + std::to_string(_blockId.value); + blockJson["instructions"] = Json::array(); + if (!block.phis.empty()) + { + blockJson["entries"] = block.entries + | ranges::views::transform([](auto const& entry) { return "Block" + std::to_string(entry.value); }) + | ranges::to(); + for (auto const& phi: block.phis) + { + auto* phiInfo = std::get_if(&_cfg.valueInfo(phi)); + yulAssert(phiInfo); + Json phiJson = Json::object(); + phiJson["op"] = "PhiFunction"; + phiJson["in"] = toJson(_cfg, phiInfo->arguments); + phiJson["out"] = toJson(_cfg, std::vector{phi}); + blockJson["instructions"].push_back(phiJson); + } + } + for (auto const& operation: block.operations) + blockJson["instructions"].push_back(toJson(blockJson, _cfg, operation)); + + return blockJson; +} + +Json YulControlFlowGraphExporter::toJson(Json& _ret, SSACFG const& _cfg, SSACFG::Operation const& _operation) +{ + Json opJson = Json::object(); + std::visit(util::GenericVisitor{ + [&](SSACFG::Call const& _call) { + _ret["type"] = "FunctionCall"; + opJson["op"] = _call.function.get().name.str(); + }, + [&](SSACFG::BuiltinCall const& _call) { + _ret["type"] = "BuiltinCall"; + Json builtinArgsJson = Json::array(); + auto const& builtin = _call.builtin.get(); + if (!builtin.literalArguments.empty()) + { + auto const& functionCallArgs = _call.call.get().arguments; + for (size_t i = 0; i < builtin.literalArguments.size(); ++i) + { + std::optional const& argument = builtin.literalArguments[i]; + if (argument.has_value() && i < functionCallArgs.size()) + { + // The function call argument at index i must be a literal if builtin.literalArguments[i] is not nullopt + yulAssert(std::holds_alternative(functionCallArgs[i])); + builtinArgsJson.push_back(formatLiteral(std::get(functionCallArgs[i]))); + } + } + } + + if (!builtinArgsJson.empty()) + opJson["builtinArgs"] = builtinArgsJson; + + opJson["op"] = _call.builtin.get().name.str(); + }, + }, _operation.kind); + + opJson["in"] = toJson(_cfg, _operation.inputs); + opJson["out"] = toJson(_cfg, _operation.outputs); + + return opJson; +} + +Json YulControlFlowGraphExporter::toJson(SSACFG const& _cfg, std::vector const& _values) +{ + Json ret = Json::array(); + for (auto const& value: _values) + ret.push_back(varToString(_cfg, value)); + return ret; +} diff --git a/libyul/YulControlFlowGraphExporter.h b/libyul/YulControlFlowGraphExporter.h new file mode 100644 index 000000000000..37520e194b21 --- /dev/null +++ b/libyul/YulControlFlowGraphExporter.h @@ -0,0 +1,42 @@ +/* + This file is part of solidity. + + solidity is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + solidity is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with solidity. If not, see . +*/ +// SPDX-License-Identifier: GPL-3.0 + +#pragma once + +#include +#include +#include + +using namespace solidity; +using namespace yul; + +class YulControlFlowGraphExporter +{ +public: + YulControlFlowGraphExporter(ControlFlow const& _controlFlow); + Json run(); + Json exportBlock(SSACFG const& _cfg, SSACFG::BlockId _blockId); + Json exportFunction(SSACFG const& _cfg); + std::string varToString(SSACFG const& _cfg, SSACFG::ValueId _var); + +private: + ControlFlow const& m_controlFlow; + Json toJson(SSACFG const& _cfg, SSACFG::BlockId _blockId); + Json toJson(Json& _ret, SSACFG const& _cfg, SSACFG::Operation const& _operation); + Json toJson(SSACFG const& _cfg, std::vector const& _values); +}; diff --git a/libyul/YulStack.cpp b/libyul/YulStack.cpp index 1f57eda48cb3..373fb304f8a6 100644 --- a/libyul/YulStack.cpp +++ b/libyul/YulStack.cpp @@ -20,6 +20,7 @@ #include #include +#include #include #include #include @@ -27,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -364,6 +366,45 @@ Json YulStack::astJson() const return m_parserResult->toJson(); } +Json YulStack::cfgJson() const +{ + yulAssert(m_parserResult, ""); + yulAssert(m_parserResult->hasCode(), ""); + yulAssert(m_parserResult->analysisInfo, ""); + // FIXME: we should not regenerate the cfg, but for now this is sufficient for testing purposes + auto exportCFGFromObject = [&](Object const& _object) -> Json { + // NOTE: The block Ids are reset for each object + std::unique_ptr controlFlow = SSAControlFlowGraphBuilder::build( + *_object.analysisInfo.get(), + languageToDialect(m_language, m_evmVersion), + _object.code()->root() + ); + YulControlFlowGraphExporter exporter(*controlFlow); + return exporter.run(); + }; + + std::function>)> exportCFGFromSubObjects; + exportCFGFromSubObjects = [&](std::vector> _subObjects) -> Json { + Json subObjectsJson = Json::object(); + for (std::shared_ptr const& subObjectNode: _subObjects) + if (Object const* subObject = dynamic_cast(subObjectNode.get())) + { + subObjectsJson[subObject->name] = exportCFGFromObject(*subObject); + subObjectsJson["type"] = "subObject"; + if (!subObject->subObjects.empty()) + subObjectsJson["subObjects"] = exportCFGFromSubObjects(subObject->subObjects); + } + return subObjectsJson; + }; + + Object const& object = *m_parserResult.get(); + Json jsonObject = Json::object(); + jsonObject[object.name] = exportCFGFromObject(object); + jsonObject["type"] = "Object"; + jsonObject["subObjects"] = exportCFGFromSubObjects(object.subObjects); + return jsonObject; +} + std::shared_ptr YulStack::parserResult() const { yulAssert(m_stackState >= AnalysisSuccessful, "Analysis was not successful."); diff --git a/libyul/YulStack.h b/libyul/YulStack.h index 69c0f01656f9..746e0c49fa72 100644 --- a/libyul/YulStack.h +++ b/libyul/YulStack.h @@ -141,6 +141,9 @@ class YulStack: public langutil::CharStreamProvider ) const; Json astJson() const; + // return the JSON representation of the YuL CFG (experimental) + Json cfgJson() const; + /// Return the parsed and analyzed object. std::shared_ptr parserResult() const; diff --git a/solc/CommandLineInterface.cpp b/solc/CommandLineInterface.cpp index 02b6dcade295..f78fdfeb81c9 100644 --- a/solc/CommandLineInterface.cpp +++ b/solc/CommandLineInterface.cpp @@ -291,6 +291,30 @@ void CommandLineInterface::handleIRAst(std::string const& _contractName) } } +void CommandLineInterface::handleYulCFGExport(std::string const& _contractName) +{ + solAssert(CompilerInputModes.count(m_options.input.mode) == 1); + + if (!m_options.compiler.outputs.yulCFGJson) + return; + + if (!m_options.output.dir.empty()) + createFile( + m_compiler->filesystemFriendlyName(_contractName) + "_yul_cfg.json", + util::jsonPrint( + m_compiler->yulCFGJson(_contractName), + m_options.formatting.json + ) + ); + else + { + sout() << util::jsonPrint( + m_compiler->yulCFGJson(_contractName), + m_options.formatting.json + ) << std::endl; + } +} + void CommandLineInterface::handleIROptimized(std::string const& _contractName) { solAssert(CompilerInputModes.count(m_options.input.mode) == 1); @@ -866,7 +890,7 @@ void CommandLineInterface::compile() m_compiler->selectDebugInfo(m_options.output.debugInfoSelection.value()); CompilerStack::IROutputSelection irOutputSelection = CompilerStack::IROutputSelection::None; - if (m_options.compiler.outputs.irOptimized || m_options.compiler.outputs.irOptimizedAstJson) + if (m_options.compiler.outputs.irOptimized || m_options.compiler.outputs.irOptimizedAstJson || m_options.compiler.outputs.yulCFGJson) irOutputSelection = CompilerStack::IROutputSelection::UnoptimizedAndOptimized; else if (m_options.compiler.outputs.ir || m_options.compiler.outputs.irAstJson) irOutputSelection = CompilerStack::IROutputSelection::UnoptimizedOnly; @@ -1280,6 +1304,11 @@ void CommandLineInterface::assembleYul(yul::YulStack::Language _language, yul::Y sout() << "AST:" << std::endl << std::endl; sout() << util::jsonPrint(stack.astJson(), m_options.formatting.json) << std::endl; } + if (m_options.compiler.outputs.yulCFGJson) + { + sout() << "Yul Control Flow Graph:" << std::endl << std::endl; + sout() << util::jsonPrint(stack.cfgJson(), m_options.formatting.json) << std::endl; + } solAssert(_targetMachine == yul::YulStack::Machine::EVM, ""); if (m_options.compiler.outputs.asm_) { @@ -1335,6 +1364,7 @@ void CommandLineInterface::outputCompilationResults() handleIRAst(contract); handleIROptimized(contract); handleIROptimizedAst(contract); + handleYulCFGExport(contract); handleSignatureHashes(contract); handleMetadata(contract); handleABI(contract); diff --git a/solc/CommandLineInterface.h b/solc/CommandLineInterface.h index c23fd9e17b1f..ce30a4d71db7 100644 --- a/solc/CommandLineInterface.h +++ b/solc/CommandLineInterface.h @@ -108,6 +108,7 @@ class CommandLineInterface void handleIRAst(std::string const& _contract); void handleIROptimized(std::string const& _contract); void handleIROptimizedAst(std::string const& _contract); + void handleYulCFGExport(std::string const& _contract); void handleBytecode(std::string const& _contract); void handleSignatureHashes(std::string const& _contract); void handleMetadata(std::string const& _contract); diff --git a/solc/CommandLineParser.cpp b/solc/CommandLineParser.cpp index 19089d885ae8..dca68bb1c50b 100644 --- a/solc/CommandLineParser.cpp +++ b/solc/CommandLineParser.cpp @@ -473,6 +473,7 @@ void CommandLineParser::parseOutputSelection() CompilerOutputs::componentName(&CompilerOutputs::irOptimized), CompilerOutputs::componentName(&CompilerOutputs::astCompactJson), CompilerOutputs::componentName(&CompilerOutputs::asmJson), + CompilerOutputs::componentName(&CompilerOutputs::yulCFGJson), }; static std::set const evmAssemblyJsonImportModeOutputs = { CompilerOutputs::componentName(&CompilerOutputs::asm_), @@ -755,6 +756,7 @@ General Information)").c_str(), (CompilerOutputs::componentName(&CompilerOutputs::irAstJson).c_str(), "AST of Intermediate Representation (IR) of all contracts in a compact JSON format.") (CompilerOutputs::componentName(&CompilerOutputs::irOptimized).c_str(), "Optimized Intermediate Representation (IR) of all contracts.") (CompilerOutputs::componentName(&CompilerOutputs::irOptimizedAstJson).c_str(), "AST of optimized Intermediate Representation (IR) of all contracts in a compact JSON format.") + (CompilerOutputs::componentName(&CompilerOutputs::yulCFGJson).c_str(), "Control Flow Graph (CFG) of Yul code in JSON format.") (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.") diff --git a/solc/CommandLineParser.h b/solc/CommandLineParser.h index 5d941f662c99..3d187694e2e0 100644 --- a/solc/CommandLineParser.h +++ b/solc/CommandLineParser.h @@ -87,6 +87,7 @@ struct CompilerOutputs {"metadata", &CompilerOutputs::metadata}, {"storage-layout", &CompilerOutputs::storageLayout}, {"transient-storage-layout", &CompilerOutputs::transientStorageLayout}, + {"yul-cfg-json", &CompilerOutputs::yulCFGJson}, }; return components; } @@ -100,6 +101,7 @@ struct CompilerOutputs bool abi = false; bool ir = false; bool irAstJson = false; + bool yulCFGJson = false; bool irOptimized = false; bool irOptimizedAstJson = false; bool signatureHashes = false; diff --git a/test/solc/CommandLineParser.cpp b/test/solc/CommandLineParser.cpp index e0347a18c4b5..227b1b9213d8 100644 --- a/test/solc/CommandLineParser.cpp +++ b/test/solc/CommandLineParser.cpp @@ -131,6 +131,7 @@ BOOST_AUTO_TEST_CASE(cli_mode_options) "dir2/file2.sol:L=0x1111122222333334444455555666667777788888", "--ast-compact-json", "--asm", "--asm-json", "--opcodes", "--bin", "--bin-runtime", "--abi", "--ir", "--ir-ast-json", "--ir-optimized", "--ir-optimized-ast-json", "--hashes", "--userdoc", "--devdoc", "--metadata", + "--yul-cfg-json", "--storage-layout", "--transient-storage-layout", "--gas", "--combined-json=" @@ -193,7 +194,7 @@ BOOST_AUTO_TEST_CASE(cli_mode_options) true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, - true, true, + true, true, true, }; expectedOptions.compiler.estimateGas = true; expectedOptions.compiler.combinedJsonRequests = { From b167c271141715ffca2b28816ede10dd03ba110e Mon Sep 17 00:00:00 2001 From: rodiazet Date: Mon, 26 Aug 2024 11:31:03 +0200 Subject: [PATCH 0385/1022] prep: Pass `_eofVersion` to `libevmasm/Assembly` class Co-authored-by: Daniel Kirchner --- libevmasm/Assembly.cpp | 23 ++++++++++++++++------ libevmasm/Assembly.h | 11 +++++++++-- libsolidity/codegen/CompilerContext.h | 2 +- libsolidity/interface/CompilerStack.cpp | 8 ++++++++ libyul/YulStack.cpp | 2 +- libyul/backends/evm/EVMObjectCompiler.cpp | 2 +- libyul/backends/evm/EthAssemblyAdapter.cpp | 2 +- test/libevmasm/Assembler.cpp | 21 ++++++++++---------- test/libevmasm/Optimiser.cpp | 4 ++-- test/libyul/EVMCodeTransformTest.cpp | 2 +- test/tools/fuzzer_common.cpp | 2 +- 11 files changed, 53 insertions(+), 26 deletions(-) diff --git a/libevmasm/Assembly.cpp b/libevmasm/Assembly.cpp index ab3879da48c8..7a28208c1b86 100644 --- a/libevmasm/Assembly.cpp +++ b/libevmasm/Assembly.cpp @@ -549,7 +549,7 @@ std::pair, std::vector> Assembly::fromJSO "Member 'sourceList' may only be present in the root JSON object." ); - auto result = std::make_shared(EVMVersion{}, _level == 0 /* _creation */, "" /* _name */); + auto result = std::make_shared(EVMVersion{}, _level == 0 /* _creation */, std::nullopt, "" /* _name */); std::vector parsedSourceList; if (_json.contains("sourceList")) { @@ -735,7 +735,7 @@ std::map const& Assembly::optimiseInternal( { count = 0; - if (_settings.runInliner) + if (_settings.runInliner && !m_eofVersion.has_value()) Inliner{ m_items, _tagsReferencedFromOutside, @@ -762,7 +762,7 @@ std::map const& Assembly::optimiseInternal( } // This only modifies PushTags, we have to run again to actually remove code. - if (_settings.runDeduplicate) + if (_settings.runDeduplicate && !m_eofVersion.has_value()) { BlockDeduplicator deduplicator{m_items}; if (deduplicator.deduplicate()) @@ -787,7 +787,8 @@ std::map const& Assembly::optimiseInternal( } } - if (_settings.runCSE) + // TODO: investigate for EOF + if (_settings.runCSE && !m_eofVersion.has_value()) { // Control flow graph optimization has been here before but is disabled because it // assumes we only jump to tags that are pushed. This is not the case anymore with @@ -839,7 +840,8 @@ std::map const& Assembly::optimiseInternal( } } - if (_settings.runConstantOptimiser) + // TODO: investigate for EOF + if (_settings.runConstantOptimiser && !m_eofVersion.has_value()) ConstantOptimisationMethod::optimiseConstants( isCreation(), isCreation() ? 1 : _settings.expectedExecutionsPerDeployment, @@ -862,6 +864,9 @@ LinkerObject const& Assembly::assemble() const LinkerObject& ret = m_assembledObject; + bool const eof = m_eofVersion.has_value(); + solAssert(!eof || m_eofVersion == 1, "Invalid EOF version."); + size_t subTagSize = 1; std::map>> immutableReferencesBySub; for (auto const& sub: m_subs) @@ -957,6 +962,7 @@ LinkerObject const& Assembly::assemble() const } case PushTag: { + assertThrow(!eof, AssemblyException, "PushTag in EOF code"); ret.bytecode.push_back(tagPush); tagRef[ret.bytecode.size()] = i.splitForeignPushTag(); ret.bytecode.resize(ret.bytecode.size() + bytesPerTag); @@ -968,6 +974,7 @@ LinkerObject const& Assembly::assemble() const ret.bytecode.resize(ret.bytecode.size() + bytesPerDataRef); break; case PushSub: + assertThrow(!eof, AssemblyException, "PushSub in EOF code"); assertThrow(i.data() <= std::numeric_limits::max(), AssemblyException, ""); ret.bytecode.push_back(dataRefPush); subRef.insert(std::make_pair(static_cast(i.data()), ret.bytecode.size())); @@ -975,6 +982,7 @@ LinkerObject const& Assembly::assemble() const break; case PushSubSize: { + assertThrow(!eof, AssemblyException, "PushSubSize in EOF code"); assertThrow(i.data() <= std::numeric_limits::max(), AssemblyException, ""); auto s = subAssemblyById(static_cast(i.data()))->assemble().bytecode.size(); i.setPushedValue(u256(s)); @@ -987,6 +995,7 @@ LinkerObject const& Assembly::assemble() const } case PushProgramSize: { + assertThrow(!eof, AssemblyException, "PushProgramSize in EOF code"); ret.bytecode.push_back(dataRefPush); sizeRef.push_back(static_cast(ret.bytecode.size())); ret.bytecode.resize(ret.bytecode.size() + bytesPerDataRef); @@ -998,6 +1007,7 @@ LinkerObject const& Assembly::assemble() const ret.bytecode.resize(ret.bytecode.size() + 20); break; case PushImmutable: + assertThrow(!eof, AssemblyException, "PushImmutable in EOF code"); ret.bytecode.push_back(static_cast(Instruction::PUSH32)); // Maps keccak back to the "identifier" std::string of that immutable. ret.immutableReferences[i.data()].first = m_immutables.at(i.data()); @@ -1011,6 +1021,7 @@ LinkerObject const& Assembly::assemble() const break; case AssignImmutable: { + assertThrow(!eof, AssemblyException, "AssignImmutable in EOF code"); // Expect 2 elements on stack (source, dest_base) auto const& offsets = immutableReferencesBySub[i.data()].second; for (size_t i = 0; i < offsets.size(); ++i) @@ -1063,7 +1074,7 @@ LinkerObject const& Assembly::assemble() const "Some immutables were read from but never assigned, possibly because of optimization." ); - if (!m_subs.empty() || !m_data.empty() || !m_auxiliaryData.empty()) + if (!eof && (!m_subs.empty() || !m_data.empty() || !m_auxiliaryData.empty())) // Append an INVALID here to help tests find miscompilation. ret.bytecode.push_back(static_cast(Instruction::INVALID)); diff --git a/libevmasm/Assembly.h b/libevmasm/Assembly.h index 123d7f3ddd8c..2b0ef93df220 100644 --- a/libevmasm/Assembly.h +++ b/libevmasm/Assembly.h @@ -48,8 +48,14 @@ using AssemblyPointer = std::shared_ptr; class Assembly { public: - Assembly(langutil::EVMVersion _evmVersion, bool _creation, std::string _name): m_evmVersion(_evmVersion), m_creation(_creation), m_name(std::move(_name)) { } - + Assembly(langutil::EVMVersion _evmVersion, bool _creation, std::optional _eofVersion, std::string _name): + m_evmVersion(_evmVersion), + m_creation(_creation), + m_eofVersion(_eofVersion), + m_name(std::move(_name)) + {} + + std::optional eofVersion() const { return m_eofVersion; } AssemblyItem newTag() { assertThrow(m_usedTags < 0xffffffff, AssemblyException, ""); return AssemblyItem(Tag, m_usedTags++); } AssemblyItem newPushTag() { assertThrow(m_usedTags < 0xffffffff, AssemblyException, ""); return AssemblyItem(PushTag, m_usedTags++); } /// Returns a tag identified by the given name. Creates it if it does not yet exist. @@ -242,6 +248,7 @@ class Assembly int m_deposit = 0; /// True, if the assembly contains contract creation code. bool const m_creation = false; + std::optional m_eofVersion; /// Internal name of the assembly object, only used with the Yul backend /// currently std::string m_name; diff --git a/libsolidity/codegen/CompilerContext.h b/libsolidity/codegen/CompilerContext.h index c6972f92b83b..3469ee7d278a 100644 --- a/libsolidity/codegen/CompilerContext.h +++ b/libsolidity/codegen/CompilerContext.h @@ -65,7 +65,7 @@ class CompilerContext RevertStrings _revertStrings, CompilerContext* _runtimeContext = nullptr ): - m_asm(std::make_shared(_evmVersion, _runtimeContext != nullptr, std::string{})), + m_asm(std::make_shared(_evmVersion, _runtimeContext != nullptr, std::nullopt, std::string{})), m_evmVersion(_evmVersion), m_revertStrings(_revertStrings), m_reservedMemory{0}, diff --git a/libsolidity/interface/CompilerStack.cpp b/libsolidity/interface/CompilerStack.cpp index 1f432db40fca..60f41a7b6b07 100644 --- a/libsolidity/interface/CompilerStack.cpp +++ b/libsolidity/interface/CompilerStack.cpp @@ -864,6 +864,10 @@ std::string const* CompilerStack::sourceMapping(std::string const& _contractName { solAssert(m_stackState == CompilationSuccessful, "Compilation was not successful."); + // TODO + if (m_eofVersion.has_value()) + return nullptr; + Contract const& c = contract(_contractName); if (!c.sourceMapping) { @@ -877,6 +881,10 @@ std::string const* CompilerStack::runtimeSourceMapping(std::string const& _contr { solAssert(m_stackState == CompilationSuccessful, "Compilation was not successful."); + // TODO + if (m_eofVersion.has_value()) + return nullptr; + Contract const& c = contract(_contractName); if (!c.runtimeSourceMapping) { diff --git a/libyul/YulStack.cpp b/libyul/YulStack.cpp index 1f57eda48cb3..da9ac35dc331 100644 --- a/libyul/YulStack.cpp +++ b/libyul/YulStack.cpp @@ -295,7 +295,7 @@ YulStack::assembleEVMWithDeployed(std::optional _deployName) yulAssert(m_parserResult->hasCode(), ""); yulAssert(m_parserResult->analysisInfo, ""); - evmasm::Assembly assembly(m_evmVersion, true, {}); + evmasm::Assembly assembly(m_evmVersion, true, m_eofVersion, {}); EthAssemblyAdapter adapter(assembly); // NOTE: We always need stack optimization when Yul optimizer is disabled (unless code contains diff --git a/libyul/backends/evm/EVMObjectCompiler.cpp b/libyul/backends/evm/EVMObjectCompiler.cpp index ccd8af6d2940..a7ac67c3a6c3 100644 --- a/libyul/backends/evm/EVMObjectCompiler.cpp +++ b/libyul/backends/evm/EVMObjectCompiler.cpp @@ -75,7 +75,7 @@ void EVMObjectCompiler::run(Object const& _object, bool _optimize) yulAssert(_object.hasCode(), "No code."); if (m_eofVersion.has_value()) yulAssert( - _optimize && (m_dialect.evmVersion() == langutil::EVMVersion()), + _optimize && (m_dialect.evmVersion() >= langutil::EVMVersion::prague()), "Experimental EOF support is only available for optimized via-IR compilation and the most recent EVM version." ); if (_optimize && m_dialect.evmVersion().canOverchargeGasForCall()) diff --git a/libyul/backends/evm/EthAssemblyAdapter.cpp b/libyul/backends/evm/EthAssemblyAdapter.cpp index 79146f859c26..e3a2e01e1b1f 100644 --- a/libyul/backends/evm/EthAssemblyAdapter.cpp +++ b/libyul/backends/evm/EthAssemblyAdapter.cpp @@ -123,7 +123,7 @@ void EthAssemblyAdapter::appendAssemblySize() std::pair, AbstractAssembly::SubID> EthAssemblyAdapter::createSubAssembly(bool _creation, std::string _name) { - std::shared_ptr assembly{std::make_shared(m_assembly.evmVersion(), _creation, std::move(_name))}; + std::shared_ptr assembly{std::make_shared(m_assembly.evmVersion(), _creation, m_assembly.eofVersion(), std::move(_name))}; auto sub = m_assembly.newSub(assembly); return {std::make_shared(*assembly), static_cast(sub.data())}; } diff --git a/test/libevmasm/Assembler.cpp b/test/libevmasm/Assembler.cpp index afad9d13ddc5..06c7fb6a97eb 100644 --- a/test/libevmasm/Assembler.cpp +++ b/test/libevmasm/Assembler.cpp @@ -27,6 +27,7 @@ #include #include +#include #include #include @@ -61,15 +62,15 @@ BOOST_AUTO_TEST_CASE(all_assembly_items) { "verbatim.asm", 2 } }; EVMVersion evmVersion = solidity::test::CommonOptions::get().evmVersion(); - Assembly _assembly{evmVersion, false, {}}; + Assembly _assembly{evmVersion, false, solidity::test::CommonOptions::get().eofVersion(), {}}; auto root_asm = std::make_shared("root.asm"); _assembly.setSourceLocation({1, 3, root_asm}); - Assembly _subAsm{evmVersion, false, {}}; + Assembly _subAsm{evmVersion, false, solidity::test::CommonOptions::get().eofVersion(), {}}; auto sub_asm = std::make_shared("sub.asm"); _subAsm.setSourceLocation({6, 8, sub_asm}); - Assembly _verbatimAsm(evmVersion, true, ""); + Assembly _verbatimAsm(evmVersion, true, solidity::test::CommonOptions::get().eofVersion(), ""); auto verbatim_asm = std::make_shared("verbatim.asm"); _verbatimAsm.setSourceLocation({8, 18, verbatim_asm}); @@ -246,7 +247,7 @@ BOOST_AUTO_TEST_CASE(immutables_and_its_source_maps) { *subName, 1 } }; - auto subAsm = std::make_shared(evmVersion, false, std::string{}); + auto subAsm = std::make_shared(evmVersion, false, solidity::test::CommonOptions::get().eofVersion(), std::string{}); for (char i = 0; i < numImmutables; ++i) { for (int r = 0; r < numActualRefs; ++r) @@ -256,7 +257,7 @@ BOOST_AUTO_TEST_CASE(immutables_and_its_source_maps) } } - Assembly assembly{evmVersion, true, {}}; + Assembly assembly{evmVersion, true, solidity::test::CommonOptions::get().eofVersion(), {}}; for (char i = 1; i <= numImmutables; ++i) { assembly.setSourceLocation({10*i, 10*i + 3+i, assemblyName}); @@ -306,11 +307,11 @@ BOOST_AUTO_TEST_CASE(immutable) { "sub.asm", 1 } }; EVMVersion evmVersion = solidity::test::CommonOptions::get().evmVersion(); - Assembly _assembly{evmVersion, true, {}}; + Assembly _assembly{evmVersion, true, solidity::test::CommonOptions::get().eofVersion(), {}}; auto root_asm = std::make_shared("root.asm"); _assembly.setSourceLocation({1, 3, root_asm}); - Assembly _subAsm{evmVersion, false, {}}; + Assembly _subAsm{evmVersion, false, solidity::test::CommonOptions::get().eofVersion(), {}}; auto sub_asm = std::make_shared("sub.asm"); _subAsm.setSourceLocation({6, 8, sub_asm}); _subAsm.appendImmutable("someImmutable"); @@ -404,10 +405,10 @@ BOOST_AUTO_TEST_CASE(immutable) BOOST_AUTO_TEST_CASE(subobject_encode_decode) { EVMVersion evmVersion = solidity::test::CommonOptions::get().evmVersion(); - Assembly assembly{evmVersion, true, {}}; + Assembly assembly{evmVersion, true, solidity::test::CommonOptions::get().eofVersion(), {}}; - std::shared_ptr subAsmPtr = std::make_shared(evmVersion, false, std::string{}); - std::shared_ptr subSubAsmPtr = std::make_shared(evmVersion, false, std::string{}); + std::shared_ptr subAsmPtr = std::make_shared(evmVersion, false, solidity::test::CommonOptions::get().eofVersion(), std::string{}); + std::shared_ptr subSubAsmPtr = std::make_shared(evmVersion, false, solidity::test::CommonOptions::get().eofVersion(), std::string{}); assembly.appendSubroutine(subAsmPtr); subAsmPtr->appendSubroutine(subSubAsmPtr); diff --git a/test/libevmasm/Optimiser.cpp b/test/libevmasm/Optimiser.cpp index 13fa58bf4bdf..13d9d6f2bb6f 100644 --- a/test/libevmasm/Optimiser.cpp +++ b/test/libevmasm/Optimiser.cpp @@ -1346,8 +1346,8 @@ BOOST_AUTO_TEST_CASE(jumpdest_removal_subassemblies) settings.evmVersion = solidity::test::CommonOptions::get().evmVersion(); settings.expectedExecutionsPerDeployment = OptimiserSettings{}.expectedExecutionsPerDeployment; - Assembly main{settings.evmVersion, false, {}}; - AssemblyPointer sub = std::make_shared(settings.evmVersion, true, std::string{}); + Assembly main{settings.evmVersion, false, solidity::test::CommonOptions::get().eofVersion(), {}}; + AssemblyPointer sub = std::make_shared(settings.evmVersion, true, solidity::test::CommonOptions::get().eofVersion(), std::string{}); sub->append(u256(1)); auto t1 = sub->newTag(); diff --git a/test/libyul/EVMCodeTransformTest.cpp b/test/libyul/EVMCodeTransformTest.cpp index 4c2eecab05fe..e54ab9c8f002 100644 --- a/test/libyul/EVMCodeTransformTest.cpp +++ b/test/libyul/EVMCodeTransformTest.cpp @@ -67,7 +67,7 @@ TestCase::TestResult EVMCodeTransformTest::run(std::ostream& _stream, std::strin return TestResult::FatalError; } - evmasm::Assembly assembly{solidity::test::CommonOptions::get().evmVersion(), false, {}}; + evmasm::Assembly assembly{solidity::test::CommonOptions::get().evmVersion(), false, std::nullopt, {}}; EthAssemblyAdapter adapter(assembly); EVMObjectCompiler::compile( *stack.parserResult(), diff --git a/test/tools/fuzzer_common.cpp b/test/tools/fuzzer_common.cpp index adf5a064bef7..1caa5357e534 100644 --- a/test/tools/fuzzer_common.cpp +++ b/test/tools/fuzzer_common.cpp @@ -190,7 +190,7 @@ void FuzzerUtil::testConstantOptimizer(std::string const& _input, bool _quiet) for (bool isCreation: {false, true}) { - Assembly assembly{langutil::EVMVersion{}, isCreation, {}}; + Assembly assembly{langutil::EVMVersion{}, isCreation, std::nullopt, {}}; for (u256 const& n: numbers) { if (!_quiet) From 1854186942cc24e94cfed2708ec4d0fc3e668a62 Mon Sep 17 00:00:00 2001 From: rodiazet Date: Wed, 28 Aug 2024 15:11:44 +0200 Subject: [PATCH 0386/1022] eof: Remove eof experimental test. It should be reintroduced later. --- test/libsolidity/Metadata.cpp | 39 ----------------------------------- 1 file changed, 39 deletions(-) diff --git a/test/libsolidity/Metadata.cpp b/test/libsolidity/Metadata.cpp index 94687f99006d..ed490b9a839b 100644 --- a/test/libsolidity/Metadata.cpp +++ b/test/libsolidity/Metadata.cpp @@ -225,45 +225,6 @@ BOOST_AUTO_TEST_CASE(metadata_stamp_experimental) } } -BOOST_AUTO_TEST_CASE(metadata_eof_experimental) -{ - // Check that setting an EOF version results in the experimental flag being set. - char const* sourceCode = R"( - pragma solidity >=0.0; - contract test { - function g(function(uint) external returns (uint) x) public {} - } - )"; - for (auto metadataFormat: std::set{ - CompilerStack::MetadataFormat::NoMetadata, - CompilerStack::MetadataFormat::WithReleaseVersionTag, - CompilerStack::MetadataFormat::WithPrereleaseVersionTag - }) - { - CompilerStack compilerStack; - compilerStack.setMetadataFormat(metadataFormat); - compilerStack.setSources({{"", sourceCode}}); - compilerStack.setEVMVersion({}); - compilerStack.setViaIR(true); - compilerStack.setEOFVersion(1); - compilerStack.setOptimiserSettings(true); - BOOST_REQUIRE_MESSAGE(compilerStack.compile(), "Compiling contract failed"); - bytes const& bytecode = compilerStack.runtimeObject("test").bytecode; - std::string const& metadata = compilerStack.metadata("test"); - BOOST_CHECK(solidity::test::isValidMetadata(metadata)); - - auto const cborMetadata = requireParsedCBORMetadata(bytecode, metadataFormat); - - if (metadataFormat == CompilerStack::MetadataFormat::NoMetadata) - BOOST_CHECK(cborMetadata.count("experimental") == 0); - else - { - BOOST_CHECK(cborMetadata.count("experimental") == 1); - BOOST_CHECK(cborMetadata.at("experimental") == "true"); - } - } -} - BOOST_AUTO_TEST_CASE(metadata_relevant_sources) { CompilerStack compilerStack; From 92a74edfba8ab97eaecad1d97760d2f70b57f77e Mon Sep 17 00:00:00 2001 From: Martin Blicha Date: Sat, 20 Jul 2024 11:58:08 +0200 Subject: [PATCH 0387/1022] SMTChecker: Introduce helper struct for query result --- libsmtutil/CHCSmtLib2Interface.cpp | 2 +- libsmtutil/CHCSmtLib2Interface.h | 2 +- libsmtutil/CHCSolverInterface.h | 10 +++++++--- libsmtutil/Z3CHCInterface.cpp | 2 +- libsmtutil/Z3CHCInterface.h | 2 +- libsolidity/formal/CHC.cpp | 21 +++++++------------- libsolidity/formal/CHC.h | 2 +- libsolidity/formal/Z3CHCSmtLib2Interface.cpp | 2 +- libsolidity/formal/Z3CHCSmtLib2Interface.h | 2 +- 9 files changed, 21 insertions(+), 24 deletions(-) diff --git a/libsmtutil/CHCSmtLib2Interface.cpp b/libsmtutil/CHCSmtLib2Interface.cpp index 6e535f09930f..d23249d2200d 100644 --- a/libsmtutil/CHCSmtLib2Interface.cpp +++ b/libsmtutil/CHCSmtLib2Interface.cpp @@ -90,7 +90,7 @@ void CHCSmtLib2Interface::addRule(Expression const& _expr, std::string const& /* m_commands.assertion("(forall" + forall(_expr) + '\n' + m_context.toSExpr(_expr) + ")\n"); } -std::tuple CHCSmtLib2Interface::query(Expression const& _block) +CHCSolverInterface::QueryResult CHCSmtLib2Interface::query(Expression const& _block) { std::string query = dumpQuery(_block); std::string response = querySolver(query); diff --git a/libsmtutil/CHCSmtLib2Interface.h b/libsmtutil/CHCSmtLib2Interface.h index b5baba7d6985..0f8fc061d3df 100644 --- a/libsmtutil/CHCSmtLib2Interface.h +++ b/libsmtutil/CHCSmtLib2Interface.h @@ -47,7 +47,7 @@ class CHCSmtLib2Interface: public CHCSolverInterface /// Takes a function application _expr and checks for reachability. /// @returns solving result, an invariant, and counterexample graph, if possible. - std::tuple query(Expression const& _expr) override; + QueryResult query(Expression const& _expr) override; void declareVariable(std::string const& _name, SortPointer const& _sort) override; diff --git a/libsmtutil/CHCSolverInterface.h b/libsmtutil/CHCSolverInterface.h index a20283b4fec1..8feb18aa8245 100644 --- a/libsmtutil/CHCSolverInterface.h +++ b/libsmtutil/CHCSolverInterface.h @@ -49,11 +49,15 @@ class CHCSolverInterface : public SolverInterface std::map> edges; }; + struct QueryResult + { + CheckResult answer; + Expression invariant; + CexGraph cex; + }; /// Takes a function application _expr and checks for reachability. /// @returns solving result, an invariant, and counterexample graph, if possible. - virtual std::tuple query( - Expression const& _expr - ) = 0; + virtual QueryResult query(Expression const& _expr) = 0; protected: std::optional m_queryTimeout; diff --git a/libsmtutil/Z3CHCInterface.cpp b/libsmtutil/Z3CHCInterface.cpp index 787d46d72e49..a79630b6e59b 100644 --- a/libsmtutil/Z3CHCInterface.cpp +++ b/libsmtutil/Z3CHCInterface.cpp @@ -78,7 +78,7 @@ void Z3CHCInterface::addRule(Expression const& _expr, std::string const& _name) } } -std::tuple Z3CHCInterface::query(Expression const& _expr) +CHCSolverInterface::QueryResult Z3CHCInterface::query(Expression const& _expr) { CheckResult result; try diff --git a/libsmtutil/Z3CHCInterface.h b/libsmtutil/Z3CHCInterface.h index 5a768f65cb8f..98f21246c297 100644 --- a/libsmtutil/Z3CHCInterface.h +++ b/libsmtutil/Z3CHCInterface.h @@ -43,7 +43,7 @@ class Z3CHCInterface: public CHCSolverInterface void addRule(Expression const& _expr, std::string const& _name) override; - std::tuple query(Expression const& _expr) override; + QueryResult query(Expression const& _expr) override; Z3Interface* z3Interface() const { return m_z3Interface.get(); } diff --git a/libsolidity/formal/CHC.cpp b/libsolidity/formal/CHC.cpp index 2bd0195375ad..c52a83a26183 100644 --- a/libsolidity/formal/CHC.cpp +++ b/libsolidity/formal/CHC.cpp @@ -1916,11 +1916,8 @@ void CHC::addRule(smtutil::Expression const& _rule, std::string const& _ruleName m_interface->addRule(_rule, _ruleName); } -std::tuple CHC::query(smtutil::Expression const& _query, langutil::SourceLocation const& _location) +CHCSolverInterface::QueryResult CHC::query(smtutil::Expression const& _query, langutil::SourceLocation const& _location) { - CheckResult result; - smtutil::Expression invariant(true); - CHCSolverInterface::CexGraph cex; if (m_settings.printQuery) { auto smtLibInterface = dynamic_cast(m_interface.get()); @@ -1931,8 +1928,8 @@ std::tuple CHC:: "CHC: Requested query:\n" + smtLibCode ); } - std::tie(result, invariant, cex) = m_interface->query(_query); - switch (result) + auto result = m_interface->query(_query); + switch (result.answer) { case CheckResult::SATISFIABLE: { @@ -1946,13 +1943,10 @@ std::tuple CHC:: solAssert(spacer, ""); spacer->setSpacerOptions(false); - CheckResult resultNoOpt; - smtutil::Expression invariantNoOpt(true); - CHCSolverInterface::CexGraph cexNoOpt; - std::tie(resultNoOpt, invariantNoOpt, cexNoOpt) = m_interface->query(_query); + auto resultNoOpt = m_interface->query(_query); - if (resultNoOpt == CheckResult::SATISFIABLE) - cex = std::move(cexNoOpt); + if (resultNoOpt.answer == CheckResult::SATISFIABLE) + result.cex = std::move(resultNoOpt.cex); spacer->setSpacerOptions(true); #else @@ -1962,7 +1956,6 @@ std::tuple CHC:: break; } case CheckResult::UNSATISFIABLE: - break; case CheckResult::UNKNOWN: break; case CheckResult::CONFLICTING: @@ -1972,7 +1965,7 @@ std::tuple CHC:: m_errorReporter.warning(1218_error, _location, "CHC: Error trying to invoke SMT solver."); break; } - return {result, invariant, cex}; + return result; } void CHC::verificationTargetEncountered( diff --git a/libsolidity/formal/CHC.h b/libsolidity/formal/CHC.h index 8a40ecb22338..8ecef3960f6c 100644 --- a/libsolidity/formal/CHC.h +++ b/libsolidity/formal/CHC.h @@ -296,7 +296,7 @@ class CHC: public SMTEncoder void addRule(smtutil::Expression const& _rule, std::string const& _ruleName); /// @returns if query is unsatisfiable (safe). /// @returns otherwise. - std::tuple query(smtutil::Expression const& _query, langutil::SourceLocation const& _location); + smtutil::CHCSolverInterface::QueryResult query(smtutil::Expression const& _query, langutil::SourceLocation const& _location); void verificationTargetEncountered(ASTNode const* const _errorNode, VerificationTargetType _type, smtutil::Expression const& _errorCondition); diff --git a/libsolidity/formal/Z3CHCSmtLib2Interface.cpp b/libsolidity/formal/Z3CHCSmtLib2Interface.cpp index cd06a9d3313a..d8448fc0beca 100644 --- a/libsolidity/formal/Z3CHCSmtLib2Interface.cpp +++ b/libsolidity/formal/Z3CHCSmtLib2Interface.cpp @@ -43,7 +43,7 @@ void Z3CHCSmtLib2Interface::setupSmtCallback(bool _enablePreprocessing) universalCallback->smtCommand().setZ3(m_queryTimeout, _enablePreprocessing, m_computeInvariants); } -std::tuple Z3CHCSmtLib2Interface::query(smtutil::Expression const& _block) +CHCSolverInterface::QueryResult Z3CHCSmtLib2Interface::query(smtutil::Expression const& _block) { setupSmtCallback(true); std::string query = dumpQuery(_block); diff --git a/libsolidity/formal/Z3CHCSmtLib2Interface.h b/libsolidity/formal/Z3CHCSmtLib2Interface.h index 39456cde0c1b..a58e7f8572c3 100644 --- a/libsolidity/formal/Z3CHCSmtLib2Interface.h +++ b/libsolidity/formal/Z3CHCSmtLib2Interface.h @@ -35,7 +35,7 @@ class Z3CHCSmtLib2Interface: public smtutil::CHCSmtLib2Interface private: void setupSmtCallback(bool _disablePreprocessing); - std::tuple query(smtutil::Expression const& _expr) override; + CHCSolverInterface::QueryResult query(smtutil::Expression const& _expr) override; CHCSolverInterface::CexGraph graphFromZ3Answer(std::string const& _proof) const; From 03880e420226de043329b378f0879cd27d073dc4 Mon Sep 17 00:00:00 2001 From: Guilherme Ferreira Date: Tue, 13 Feb 2024 01:01:40 +0100 Subject: [PATCH 0388/1022] Updating copyright year to 2024 --- docs/conf.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/conf.py b/docs/conf.py index ddc3ee81bbdc..9c9e2d5a0643 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -67,7 +67,7 @@ def setup(sphinx): # General information about the project. project = 'Solidity' -project_copyright = '2016-2023, The Solidity Authors' +project_copyright = '2016-2024, The Solidity Authors' # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the From d7865f171226cf282d6f9c099b27b14b746935a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Fri, 30 Aug 2024 15:42:16 +0200 Subject: [PATCH 0389/1022] Do not suppress the original message from unexpected AssemblyExceptions --- libsolidity/interface/CompilerStack.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libsolidity/interface/CompilerStack.cpp b/libsolidity/interface/CompilerStack.cpp index ce9525c2b6e6..3851093571bf 100644 --- a/libsolidity/interface/CompilerStack.cpp +++ b/libsolidity/interface/CompilerStack.cpp @@ -1348,9 +1348,9 @@ void CompilerStack::assembleYul( // Assemble deployment (incl. runtime) object. compiledContract.object = compiledContract.evmAssembly->assemble(); } - catch (evmasm::AssemblyException const&) + catch (evmasm::AssemblyException const& error) { - solAssert(false, "Assembly exception for bytecode"); + solAssert(false, "Assembly exception for bytecode: "s + error.what()); } solAssert(compiledContract.object.immutableReferences.empty(), "Leftover immutables."); @@ -1361,9 +1361,9 @@ void CompilerStack::assembleYul( // Assemble runtime object. compiledContract.runtimeObject = compiledContract.evmRuntimeAssembly->assemble(); } - catch (evmasm::AssemblyException const&) + catch (evmasm::AssemblyException const& error) { - solAssert(false, "Assembly exception for deployed bytecode"); + solAssert(false, "Assembly exception for deployed bytecode"s + error.what()); } // Throw a warning if EIP-170 limits are exceeded: From 2f46323b171bd3fa086d553430b293e8a3141687 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Fri, 30 Aug 2024 16:08:40 +0200 Subject: [PATCH 0390/1022] Bump min Boost dependency to 1.67 on Linux and macOS --- cmake/EthDependencies.cmake | 3 ++- docs/installing-solidity.rst | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/cmake/EthDependencies.cmake b/cmake/EthDependencies.cmake index 16f30a640d27..87a5e1b5e17e 100644 --- a/cmake/EthDependencies.cmake +++ b/cmake/EthDependencies.cmake @@ -37,7 +37,8 @@ if (WIN32) find_package(Boost 1.77.0 QUIET REQUIRED COMPONENTS ${BOOST_COMPONENTS}) else() # Boost 1.65 is the first to also provide boost::get for rvalue-references (#5787). - find_package(Boost 1.65.0 QUIET REQUIRED COMPONENTS ${BOOST_COMPONENTS}) + # Boost 1.67 moved container_hash into is own module. + find_package(Boost 1.67.0 QUIET REQUIRED COMPONENTS ${BOOST_COMPONENTS}) endif() # If cmake is older than boost and boost is older than 1.70, diff --git a/docs/installing-solidity.rst b/docs/installing-solidity.rst index b1b3e1a3fbac..5473dbb5240c 100644 --- a/docs/installing-solidity.rst +++ b/docs/installing-solidity.rst @@ -327,7 +327,7 @@ The following are dependencies for all builds of Solidity: | Windows, 3.13+ otherwise) | | +-----------------------------------+-------------------------------------------------------+ | `Boost`_ (version 1.77+ on | C++ libraries. | -| Windows, 1.65+ otherwise) | | +| Windows, 1.67+ otherwise) | | +-----------------------------------+-------------------------------------------------------+ | `Git`_ | Command-line tool for retrieving source code. | +-----------------------------------+-------------------------------------------------------+ From ad969e2b94be91ce54f614c0d5e74ec5ea7686d7 Mon Sep 17 00:00:00 2001 From: r0qs Date: Mon, 2 Sep 2024 12:34:31 +0200 Subject: [PATCH 0391/1022] Hide undocumented yul export cfg option --- solc/CommandLineParser.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/solc/CommandLineParser.cpp b/solc/CommandLineParser.cpp index dca68bb1c50b..4607250a62fb 100644 --- a/solc/CommandLineParser.cpp +++ b/solc/CommandLineParser.cpp @@ -756,7 +756,6 @@ General Information)").c_str(), (CompilerOutputs::componentName(&CompilerOutputs::irAstJson).c_str(), "AST of Intermediate Representation (IR) of all contracts in a compact JSON format.") (CompilerOutputs::componentName(&CompilerOutputs::irOptimized).c_str(), "Optimized Intermediate Representation (IR) of all contracts.") (CompilerOutputs::componentName(&CompilerOutputs::irOptimizedAstJson).c_str(), "AST of optimized Intermediate Representation (IR) of all contracts in a compact JSON format.") - (CompilerOutputs::componentName(&CompilerOutputs::yulCFGJson).c_str(), "Control Flow Graph (CFG) of Yul code in JSON format.") (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.") @@ -764,6 +763,10 @@ General Information)").c_str(), (CompilerOutputs::componentName(&CompilerOutputs::storageLayout).c_str(), "Slots, offsets and types of the contract's state variables located in storage.") (CompilerOutputs::componentName(&CompilerOutputs::transientStorageLayout).c_str(), "Slots, offsets and types of the contract's state variables located in transient storage.") ; + if (!_forHelp) // Note: We intentionally keep this undocumented for now. + outputComponents.add_options() + (CompilerOutputs::componentName(&CompilerOutputs::yulCFGJson).c_str(), "Control Flow Graph (CFG) of Yul code in JSON format.") + ; desc.add(outputComponents); po::options_description extraOutput("Extra Output"); From b30f1e2af0b9605ae295282188fc4eadc0b10721 Mon Sep 17 00:00:00 2001 From: Vishwa Mehta Date: Mon, 2 Sep 2024 12:39:46 +0200 Subject: [PATCH 0392/1022] Create opRetro.json --- opRetro.json | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 opRetro.json diff --git a/opRetro.json b/opRetro.json new file mode 100644 index 000000000000..6fb1f338bf1f --- /dev/null +++ b/opRetro.json @@ -0,0 +1,5 @@ +{ + "opRetro": { + "projectId": "0xcc8d03e014e121d10602eeff729b755d5dc6a317df0d6302c8a9d3b5424aaba8" + } +} From 1673c5c27ad42a41019a7bafa96e636ef12a0334 Mon Sep 17 00:00:00 2001 From: Nikola Matic Date: Thu, 29 Aug 2024 11:12:22 +0200 Subject: [PATCH 0393/1022] Introduce ubuntu2404 clang docker image wip --- .github/workflows/buildpack-deps.yml | 3 +- .../buildpack-deps_test_ubuntu2404.clang.sh | 1 + .../Dockerfile.ubuntu2404.clang | 107 ++++++++++++++++++ 3 files changed, 110 insertions(+), 1 deletion(-) create mode 120000 scripts/ci/buildpack-deps_test_ubuntu2404.clang.sh create mode 100644 scripts/docker/buildpack-deps/Dockerfile.ubuntu2404.clang diff --git a/.github/workflows/buildpack-deps.yml b/.github/workflows/buildpack-deps.yml index 5f66487e0798..1b9555ddc22d 100644 --- a/.github/workflows/buildpack-deps.yml +++ b/.github/workflows/buildpack-deps.yml @@ -10,6 +10,7 @@ on: - 'scripts/docker/buildpack-deps/Dockerfile.ubuntu2204.clang' - 'scripts/docker/buildpack-deps/Dockerfile.ubuntu2204' - 'scripts/docker/buildpack-deps/Dockerfile.ubuntu2404' + - 'scripts/docker/buildpack-deps/Dockerfile.ubuntu2404.clang' jobs: buildpack-deps: @@ -24,7 +25,7 @@ jobs: strategy: fail-fast: false matrix: - image_variant: [emscripten, ubuntu.clang.ossfuzz, ubuntu2004, ubuntu2204.clang, ubuntu2204, ubuntu2404] + image_variant: [emscripten, ubuntu.clang.ossfuzz, ubuntu2004, ubuntu2204.clang, ubuntu2204, ubuntu2404, ubuntu2404.clang] steps: - uses: actions/checkout@v4 diff --git a/scripts/ci/buildpack-deps_test_ubuntu2404.clang.sh b/scripts/ci/buildpack-deps_test_ubuntu2404.clang.sh new file mode 120000 index 000000000000..c07a74de4fb4 --- /dev/null +++ b/scripts/ci/buildpack-deps_test_ubuntu2404.clang.sh @@ -0,0 +1 @@ +build.sh \ No newline at end of file diff --git a/scripts/docker/buildpack-deps/Dockerfile.ubuntu2404.clang b/scripts/docker/buildpack-deps/Dockerfile.ubuntu2404.clang new file mode 100644 index 000000000000..c6b1fd970731 --- /dev/null +++ b/scripts/docker/buildpack-deps/Dockerfile.ubuntu2404.clang @@ -0,0 +1,107 @@ +# vim:syntax=dockerfile +#------------------------------------------------------------------------------ +# Dockerfile for building and testing Solidity Compiler on CI +# Target: Ubuntu 19.04 (Disco Dingo) Clang variant +# URL: https://hub.docker.com/r/ethereum/solidity-buildpack-deps +# +# 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-2024 solidity contributors. +#------------------------------------------------------------------------------ +FROM buildpack-deps:noble AS base +LABEL version="1" + +ARG DEBIAN_FRONTEND=noninteractive + +# From Python3.11, pip requires a virtual environment, and will thus terminate when installing packages globally. +# Since we're building this image from scratch, it's perfectly fine to use the below flag. +ENV PIP_BREAK_SYSTEM_PACKAGES 1 + +RUN set -ex; \ + dist=$(grep DISTRIB_CODENAME /etc/lsb-release | cut -d= -f2); \ + echo "deb http://ppa.launchpad.net/ethereum/cpp-build-deps/ubuntu $dist main" >> /etc/apt/sources.list ; \ + apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 1c52189c923f6ca9 ; \ + apt-get update; \ + apt-get install -qqy --no-install-recommends \ + build-essential \ + clang \ + cmake \ + jq \ + lsof \ + libboost-filesystem-dev \ + libboost-program-options-dev \ + libboost-system-dev \ + libboost-test-dev \ + libcln-dev \ + libz3-static-dev \ + ninja-build \ + python3-pip \ + software-properties-common \ + sudo \ + z3-static; \ + pip3 install \ + codecov \ + colorama \ + deepdiff \ + parsec \ + pygments-lexer-solidity \ + pylint \ + requests \ + tabulate \ + z3-solver; + +# Eldarica +RUN set -ex; \ + apt-get update; \ + apt-get install -qy \ + openjdk-11-jre \ + unzip; \ + eldarica_version="2.1"; \ + wget "https://github.com/uuverifiers/eldarica/releases/download/v${eldarica_version}/eldarica-bin-${eldarica_version}.zip" -O /opt/eld_binaries.zip; \ + test "$(sha256sum /opt/eld_binaries.zip)" = "0ac43f45c0925383c9d2077f62bbb515fd792375f3b2b101b30c9e81dcd7785c /opt/eld_binaries.zip"; \ + unzip /opt/eld_binaries.zip -d /opt; \ + rm -f /opt/eld_binaries.zip; + +# CVC5 +RUN set -ex; \ + cvc5_version="1.1.2"; \ + wget "https://github.com/cvc5/cvc5/releases/download/cvc5-${cvc5_version}/cvc5-Linux-static.zip" -O /opt/cvc5.zip; \ + test "$(sha256sum /opt/cvc5.zip)" = "cf291aef67da8eaa8d425a51f67f3f72f36db8b1040655dc799b64e3d69e6086 /opt/cvc5.zip"; \ + unzip /opt/cvc5.zip -x "cvc5-Linux-static/lib/cmake/*" -d /opt; \ + mv /opt/cvc5-Linux-static/bin/* /usr/bin; \ + mv /opt/cvc5-Linux-static/lib/* /usr/lib; \ + mv /opt/cvc5-Linux-static/include/* /usr/include; \ + rm -rf /opt/cvc5-Linux-static /opt/cvc5.zip; + +FROM base AS libraries + +ENV CC clang +ENV CXX clang++ + +# EVMONE +RUN set -ex; \ + wget -O /usr/src/evmone.tar.gz https://github.com/ethereum/evmone/releases/download/v0.12.0/evmone-0.12.0-linux-x86_64.tar.gz; \ + test "$(sha256sum /usr/src/evmone.tar.gz)" = "1c7b5eba0c8c3b3b2a7a05101e2d01a13a2f84b323989a29be66285dba4136ce /usr/src/evmone.tar.gz"; \ + cd /usr; \ + tar -xf /usr/src/evmone.tar.gz; \ + rm -rf /usr/src/evmone.tar.gz + +FROM base +COPY --from=libraries /usr/lib /usr/lib +COPY --from=libraries /usr/bin /usr/bin +COPY --from=libraries /usr/include /usr/include +COPY --from=libraries /opt/eldarica /opt/eldarica +ENV PATH="$PATH:/opt/eldarica" From b3ba1b2e373f6ec850733e5ebf12b3808a6f9b74 Mon Sep 17 00:00:00 2001 From: Vishwa Mehta Date: Mon, 2 Sep 2024 14:15:24 +0200 Subject: [PATCH 0394/1022] Rename opRetro.json to funding.json --- opRetro.json => funding.json | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename opRetro.json => funding.json (100%) diff --git a/opRetro.json b/funding.json similarity index 100% rename from opRetro.json rename to funding.json From 79f05ca5738d927ac7d4f25bbb2d5717017c6736 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Fri, 30 Aug 2024 16:46:42 +0200 Subject: [PATCH 0395/1022] Mark PROFILE_OPTIMIZER_STEPS CMake option as advanced --- CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 71f83b80ed2d..02d45d8e6e9b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -40,6 +40,7 @@ option(PROFILE_OPTIMIZER_STEPS "Output performance metrics for the optimiser ste option(USE_SYSTEM_LIBRARIES "Use system libraries" OFF) option(ONLY_BUILD_SOLIDITY_LIBRARIES "Only build solidity libraries" OFF) option(STRICT_NLOHMANN_JSON_VERSION "Strictly check installed nlohmann json version" ON) +mark_as_advanced(PROFILE_OPTIMIZER_STEPS) mark_as_advanced(USE_SYSTEM_LIBRARIES) mark_as_advanced(ONLY_BUILD_SOLIDITY_LIBRARIES) mark_as_advanced(STRICT_NLOHMANN_JSON_VERSION) From b52094bc2832b40c43134990182cc89caabcbf84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Fri, 30 Aug 2024 16:49:43 +0200 Subject: [PATCH 0396/1022] Remove nlohmann JSON version check - The git submodule is pinned to that version, which should be enough of a hint that this is the version we expect. If someone builds with a different version and it passes tests, we should not block that. --- CMakeLists.txt | 2 -- libsolutil/JSON.cpp | 6 ------ 2 files changed, 8 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 02d45d8e6e9b..a08e44da515c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -39,11 +39,9 @@ option(PEDANTIC "Enable extra warnings and pedantic build flags. Treat all warni option(PROFILE_OPTIMIZER_STEPS "Output performance metrics for the optimiser steps." OFF) option(USE_SYSTEM_LIBRARIES "Use system libraries" OFF) option(ONLY_BUILD_SOLIDITY_LIBRARIES "Only build solidity libraries" OFF) -option(STRICT_NLOHMANN_JSON_VERSION "Strictly check installed nlohmann json version" ON) mark_as_advanced(PROFILE_OPTIMIZER_STEPS) mark_as_advanced(USE_SYSTEM_LIBRARIES) mark_as_advanced(ONLY_BUILD_SOLIDITY_LIBRARIES) -mark_as_advanced(STRICT_NLOHMANN_JSON_VERSION) # Setup cccache. include(EthCcache) diff --git a/libsolutil/JSON.cpp b/libsolutil/JSON.cpp index 055024edb3d0..548fdfe0b87c 100644 --- a/libsolutil/JSON.cpp +++ b/libsolutil/JSON.cpp @@ -28,12 +28,6 @@ #include -#ifdef STRICT_NLOHMANN_JSON_VERSION_CHECK -static_assert( - (NLOHMANN_JSON_VERSION_MAJOR == 3) && (NLOHMANN_JSON_VERSION_MINOR == 11) && (NLOHMANN_JSON_VERSION_PATCH == 3), - "Unexpected nlohmann-json version. Expecting 3.11.3."); -#endif - namespace solidity::util { From 01a01eb2e0e7fc802d9d35ad89eb50fa2bdc21da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Fri, 30 Aug 2024 17:20:49 +0200 Subject: [PATCH 0397/1022] Clearer names and descriptions for advanced CMake options --- CMakeLists.txt | 17 +++++++++++++---- cmake/submodules.cmake | 2 +- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a08e44da515c..8b20f1d10287 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -37,10 +37,19 @@ option(SOLC_STATIC_STDLIBS "Link solc against static versions of libgcc and libs option(STRICT_Z3_VERSION "Use the latest version of Z3" ON) option(PEDANTIC "Enable extra warnings and pedantic build flags. Treat all warnings as errors." ON) option(PROFILE_OPTIMIZER_STEPS "Output performance metrics for the optimiser steps." OFF) -option(USE_SYSTEM_LIBRARIES "Use system libraries" OFF) -option(ONLY_BUILD_SOLIDITY_LIBRARIES "Only build solidity libraries" OFF) +option( + IGNORE_VENDORED_DEPENDENCIES + "Ignore libraries provided as submodules of the repository and allow CMake to look for \ +them in the typical locations, including system-wide dirs." + OFF +) +option( + ONLY_BUILD_SOLIDITY_LIBRARIES + "Only build library targets that can be statically linked against. Do not build executables or tests." + OFF +) mark_as_advanced(PROFILE_OPTIMIZER_STEPS) -mark_as_advanced(USE_SYSTEM_LIBRARIES) +mark_as_advanced(IGNORE_VENDORED_DEPENDENCIES) mark_as_advanced(ONLY_BUILD_SOLIDITY_LIBRARIES) # Setup cccache. @@ -48,7 +57,7 @@ include(EthCcache) # Let's find our dependencies include(EthDependencies) -if (NOT USE_SYSTEM_LIBRARIES) +if (NOT IGNORE_VENDORED_DEPENDENCIES) include(fmtlib) include(nlohmann-json) include(range-v3) diff --git a/cmake/submodules.cmake b/cmake/submodules.cmake index 099aceaa927d..1ef55d289ccb 100644 --- a/cmake/submodules.cmake +++ b/cmake/submodules.cmake @@ -1,5 +1,5 @@ macro(initialize_submodule SUBMODULE_PATH) - if(NOT USE_SYSTEM_LIBRARIES) + if(NOT IGNORE_VENDORED_DEPENDENCIES) file(GLOB submodule_contents "${CMAKE_SOURCE_DIR}/deps/${SUBMODULE_PATH}/*") if(submodule_contents) From 3184534fd66579f2fa21bd3896ac0f9b12ae887b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Mon, 2 Sep 2024 13:04:03 +0200 Subject: [PATCH 0398/1022] Improve names/descriptions of Z3-related CMake variables --- CMakeLists.txt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8b20f1d10287..656cec34863f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -34,7 +34,7 @@ endif() option(SOLC_LINK_STATIC "Link solc executable statically on supported platforms" OFF) option(SOLC_STATIC_STDLIBS "Link solc against static versions of libgcc and libstdc++ on supported platforms" OFF) -option(STRICT_Z3_VERSION "Use the latest version of Z3" ON) +option(STRICT_Z3_VERSION "Require the exact version of Z3 solver expected by our test suite." ON) option(PEDANTIC "Enable extra warnings and pedantic build flags. Treat all warnings as errors." ON) option(PROFILE_OPTIMIZER_STEPS "Output performance metrics for the optimiser steps." OFF) option( @@ -94,15 +94,15 @@ configure_file("${PROJECT_SOURCE_DIR}/cmake/templates/license.h.in" include/lice include(EthOptions) configure_project(TESTS) -set(LATEST_Z3_VERSION "4.12.1") +set(TESTED_Z3_VERSION "4.12.1") set(MINIMUM_Z3_VERSION "4.8.16") find_package(Z3) if (${Z3_FOUND}) if (${STRICT_Z3_VERSION}) - if (NOT ("${Z3_VERSION_STRING}" VERSION_EQUAL ${LATEST_Z3_VERSION})) + if (NOT ("${Z3_VERSION_STRING}" VERSION_EQUAL ${TESTED_Z3_VERSION})) message( FATAL_ERROR - "SMTChecker tests require Z3 ${LATEST_Z3_VERSION} for all tests to pass.\n\ + "SMTChecker tests require Z3 ${TESTED_Z3_VERSION} for all tests to pass.\n\ Build with -DSTRICT_Z3_VERSION=OFF if you want to use a different version. \ You can also use -DUSE_Z3=OFF to build without Z3. In both cases use --no-smt when running tests." ) From 3b040385d0926be18eb6b3fdd2f0610d382d4619 Mon Sep 17 00:00:00 2001 From: Nikola Matic Date: Tue, 3 Sep 2024 14:57:30 +0200 Subject: [PATCH 0399/1022] Disable failing import tests introduced by boost upgrade --- test/libsolidity/interface/FileReader.cpp | 14 +++++++++----- .../syntaxTests/imports/boost_filesystem_bug.sol | 5 ----- 2 files changed, 9 insertions(+), 10 deletions(-) delete mode 100644 test/libsolidity/syntaxTests/imports/boost_filesystem_bug.sol diff --git a/test/libsolidity/interface/FileReader.cpp b/test/libsolidity/interface/FileReader.cpp index dbb03c23f24f..2603c4c60d56 100644 --- a/test/libsolidity/interface/FileReader.cpp +++ b/test/libsolidity/interface/FileReader.cpp @@ -151,9 +151,11 @@ BOOST_AUTO_TEST_CASE(normalizeCLIPathForVFS_unc_path) { // UNC paths start with // or \\ followed by a name. They are used for network shares on Windows. // On UNIX systems they are not supported but still treated in a special way. - BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("//host/", resolveSymlinks), "//host/"); - BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("//host/a/b", resolveSymlinks), "//host/a/b"); - BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("//host/a/b/", resolveSymlinks), "//host/a/b/"); + + // TODO: Re-enable these once the boost 1.86 change has been addressed + //BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("//host/", resolveSymlinks), "//host/"); + //BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("//host/a/b", resolveSymlinks), "//host/a/b"); + //BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("//host/a/b/", resolveSymlinks), "//host/a/b/"); #if defined(_WIN32) // On Windows an UNC path can also start with \\ instead of // @@ -187,10 +189,12 @@ BOOST_AUTO_TEST_CASE(normalizeCLIPathForVFS_root_name_only) { // UNC paths BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("//", resolveSymlinks), "//" / expectedWorkDir); - BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("//host", resolveSymlinks), "//host" / expectedWorkDir); + // TODO: Re-enable these once the boost 1.86 change has been addressed + //BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("//host", resolveSymlinks), "//host" / expectedWorkDir); // On UNIX systems root name is empty. - BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("", resolveSymlinks), expectedWorkDir); + // TODO: Re-enable these once the boost 1.86 change has been addressed + //BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("", resolveSymlinks), expectedWorkDir); #if defined(_WIN32) boost::filesystem::path driveLetter = boost::filesystem::current_path().root_name(); diff --git a/test/libsolidity/syntaxTests/imports/boost_filesystem_bug.sol b/test/libsolidity/syntaxTests/imports/boost_filesystem_bug.sol deleted file mode 100644 index 8dc8da06819a..000000000000 --- a/test/libsolidity/syntaxTests/imports/boost_filesystem_bug.sol +++ /dev/null @@ -1,5 +0,0 @@ -==== Source: //// ==== -// This test used to throw due to a bug in boost::filesystem. -// See https://github.com/boostorg/filesystem/issues/176 -import "."; -// ---- From 3f6f2d3f90de9a4f506b196f9fac1d5909693d5f Mon Sep 17 00:00:00 2001 From: Daniel Kirchner Date: Tue, 3 Sep 2024 15:33:33 +0200 Subject: [PATCH 0400/1022] Fix Yul stack output using standard json in the presence of warnings. --- Changelog.md | 1 + libsolidity/interface/StandardCompiler.cpp | 26 ++++---- libyul/YulStack.h | 1 + .../standard_yul_output_warning/input.json | 20 ++++++ .../standard_yul_output_warning/output.json | 61 +++++++++++++++++++ 5 files changed, 95 insertions(+), 14 deletions(-) create mode 100644 test/cmdlineTests/standard_yul_output_warning/input.json create mode 100644 test/cmdlineTests/standard_yul_output_warning/output.json diff --git a/Changelog.md b/Changelog.md index 04bfa929530b..299a7a5bddb2 100644 --- a/Changelog.md +++ b/Changelog.md @@ -32,6 +32,7 @@ Bugfixes: * SMTChecker: Fix formatting of unary minus expressions in invariants. * SMTChecker: Fix internal compiler error when reporting proved targets for BMC engine. * SMTChecker: Fix SMT logic error when assigning to an array of contracts or functions. + * Standard JSON Interface: For Yul input, properly produce output artifacts in case of warnings. * TypeChecker: Fix segfault when assigning nested tuple to tuple. * Yul IR Code Generation: Deterministic order of Yul subobjects. * Yul Optimizer: Fix Yul source locations always referring to unoptimized source, even in optimized outputs. diff --git a/libsolidity/interface/StandardCompiler.cpp b/libsolidity/interface/StandardCompiler.cpp index 385e48c2236e..0194aa937d5e 100644 --- a/libsolidity/interface/StandardCompiler.cpp +++ b/libsolidity/interface/StandardCompiler.cpp @@ -1620,7 +1620,7 @@ Json StandardCompiler::compileYul(InputsAndSettings _inputsAndSettings) std::string const& sourceContents = _inputsAndSettings.sources.begin()->second; // Inconsistent state - stop here to receive error reports from users - if (!stack.parseAndAnalyze(sourceName, sourceContents) && stack.errors().empty()) + if (!stack.parseAndAnalyze(sourceName, sourceContents) && !stack.hasErrors()) { output["errors"].emplace_back(formatError( Error::Type::InternalCompilerError, @@ -1630,22 +1630,20 @@ Json StandardCompiler::compileYul(InputsAndSettings _inputsAndSettings) return output; } - if (!stack.errors().empty()) + for (auto const& error: stack.errors()) { - for (auto const& error: stack.errors()) - { - auto err = std::dynamic_pointer_cast(error); + auto err = std::dynamic_pointer_cast(error); - output["errors"].emplace_back(formatErrorWithException( - stack, - *error, - err->type(), - "general", - "" - )); - } - return output; + output["errors"].emplace_back(formatErrorWithException( + stack, + *error, + err->type(), + "general", + "" + )); } + if (stack.hasErrors()) + return output; std::string contractName = stack.parserResult()->name; diff --git a/libyul/YulStack.h b/libyul/YulStack.h index 746e0c49fa72..0dc90baf890d 100644 --- a/libyul/YulStack.h +++ b/libyul/YulStack.h @@ -134,6 +134,7 @@ class YulStack: public langutil::CharStreamProvider /// @returns the errors generated during parsing, analysis (and potentially assembly). langutil::ErrorList const& errors() const { return m_errors; } + bool hasErrors() const { return m_errorReporter.hasErrors(); } /// Pretty-print the input after having parsed it. std::string print( diff --git a/test/cmdlineTests/standard_yul_output_warning/input.json b/test/cmdlineTests/standard_yul_output_warning/input.json new file mode 100644 index 000000000000..f6f519d82f21 --- /dev/null +++ b/test/cmdlineTests/standard_yul_output_warning/input.json @@ -0,0 +1,20 @@ +{ + "language": "Yul", + "sources": + { + "C": + { + "content": "{ let x := tload(0) tstore(add(x, 1), 0) }" + } + }, + "settings": + { + "outputSelection": + { + "*": { + "*": ["evm.bytecode", "evm.assembly", "irOptimized"], + "": [ "*" ] + } + } + } +} diff --git a/test/cmdlineTests/standard_yul_output_warning/output.json b/test/cmdlineTests/standard_yul_output_warning/output.json new file mode 100644 index 000000000000..3234be1817fd --- /dev/null +++ b/test/cmdlineTests/standard_yul_output_warning/output.json @@ -0,0 +1,61 @@ +{ + "contracts": { + "C": { + "object": { + "evm": { + "assembly": " /* \"C\":99:100 */ + 0x00 + /* \"C\":95:96 */ + 0x01 + /* \"C\":60:68 */ + dup2 + tload + /* \"C\":88:97 */ + add + /* \"C\":81:101 */ + tstore + /* \"C\":27:117 */ + stop +", + "bytecode": { + "functionDebugData": {}, + "generatedSources": [], + "linkReferences": {}, + "object": "", + "opcodes":"", + "sourceMap":"" + } + }, + "irOptimized": "object \"object\" { + code { + { + let x := tload(0) + tstore(add(x, 1), 0) + } + } +} +" + } + } + }, + "errors": [ + { + "component": "general", + "formattedMessage": "Warning: Transient storage as defined by EIP-1153 can break the composability of smart contracts: Since transient storage is cleared only at the end of the transaction and not at the end of the outermost call frame to the contract within a transaction, your contract may unintentionally misbehave when invoked multiple times in a complex transaction. To avoid this, be sure to clear all transient storage at the end of any call to your contract. The use of transient storage for reentrancy guards that are cleared at the end of the call is safe. + --> C:1:21: + | +1 | { let x := tload(0) tstore(add(x, 1), 0) } + | ^^^^^^ + +", + "message": "Transient storage as defined by EIP-1153 can break the composability of smart contracts: Since transient storage is cleared only at the end of the transaction and not at the end of the outermost call frame to the contract within a transaction, your contract may unintentionally misbehave when invoked multiple times in a complex transaction. To avoid this, be sure to clear all transient storage at the end of any call to your contract. The use of transient storage for reentrancy guards that are cleared at the end of the call is safe.", + "severity": "warning", + "sourceLocation": { + "end": 26, + "file": "C", + "start": 20 + }, + "type": "Warning" + } + ] +} From 3e5060c5a45ab92e7bcd3a50e0a481e016449c5d Mon Sep 17 00:00:00 2001 From: Daniel Kirchner Date: Tue, 3 Sep 2024 13:46:07 +0200 Subject: [PATCH 0401/1022] Remove mantic from release PPA script (obsolete). --- scripts/deps-ppa/static_z3.sh | 2 +- scripts/release_ppa.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/deps-ppa/static_z3.sh b/scripts/deps-ppa/static_z3.sh index 016cd5d21e01..9e273188cf62 100755 --- a/scripts/deps-ppa/static_z3.sh +++ b/scripts/deps-ppa/static_z3.sh @@ -41,7 +41,7 @@ sourcePPAConfig # Sanity check checkDputEntries "\[cpp-build-deps\]" -DISTRIBUTIONS="focal jammy mantic noble" +DISTRIBUTIONS="focal jammy noble oracular" for distribution in $DISTRIBUTIONS do diff --git a/scripts/release_ppa.sh b/scripts/release_ppa.sh index 3b7c8347c067..64a81f542e86 100755 --- a/scripts/release_ppa.sh +++ b/scripts/release_ppa.sh @@ -68,7 +68,7 @@ packagename=solc # This needs to be a still active release static_build_distribution=focal -DISTRIBUTIONS="focal jammy mantic noble" +DISTRIBUTIONS="focal jammy noble oracular" if is_release then From b92cabd44be5f1a0dc3ce8fb79eb0408d214556f Mon Sep 17 00:00:00 2001 From: Nikola Matic Date: Tue, 3 Sep 2024 15:05:15 +0200 Subject: [PATCH 0402/1022] Sort changelog for the upcoming release --- Changelog.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Changelog.md b/Changelog.md index 299a7a5bddb2..8802f7b387ef 100644 --- a/Changelog.md +++ b/Changelog.md @@ -7,22 +7,22 @@ Language Features: Compiler Features: - * Command Line Interface: Do not perform IR optimization when only unoptimized IR is requested. * Commandline Interface: Add ``--transient-storage-layout`` output. + * Commandline Interface: Allow the use of ``--asm-json`` output option in assembler mode to export EVM assembly of the contracts in JSON format. + * Commandline Interface: Do not perform IR optimization when only unoptimized IR is requested. * Constant Optimizer: Uses ``PUSH0`` if supported by the selected evm version. * Error Reporting: Unimplemented features are now properly reported as errors instead of being handled as if they were bugs. * EVM: Support for the EVM version "Prague". * Peephole Optimizer: ``PUSH0``, when supported, is duplicated explicitly instead of using ``DUP1``. - * Peephole optimizer: Remove identical code snippets that terminate the control flow if they occur one after another. + * Peephole Optimizer: Remove identical code snippets that terminate the control flow if they occur one after another. * SMTChecker: Add CHC engine check for underflow and overflow in unary minus operation. * SMTChecker: Replace CVC4 as a possible BMC backend with cvc5. - * Standard JSON Interface: Do not perform IR optimization when only unoptimized IR is requested. * Standard JSON Interface: Add ``transientStorageLayout`` output. + * Standard JSON Interface: Do not perform IR optimization when only unoptimized IR is requested. * Yul: Drop the deprecated typed Yul dialect that was only accessible via ``--yul`` in the CLI. * Yul: The presence of types in untyped Yul dialects is now a parser error. * Yul Optimizer: Caching of optimized IR to speed up optimization of contracts with bytecode dependencies. * Yul Optimizer: The optimizer now treats some previously unrecognized identical literals as identical. - * Commandline Interface: Allow the use of ``--asm-json`` output option in assembler mode to export EVM assembly of the contracts in JSON format. Bugfixes: From 830ec2c4190f6a1ea4960def64edd1911c68ef3b Mon Sep 17 00:00:00 2001 From: Nikola Matic Date: Wed, 4 Sep 2024 09:03:36 +0200 Subject: [PATCH 0403/1022] Set changelog release date --- Changelog.md | 2 +- docs/bugs_by_version.json | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/Changelog.md b/Changelog.md index 8802f7b387ef..01abe1af6bef 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,4 +1,4 @@ -### 0.8.27 (unreleased) +### 0.8.27 (2024-09-04) Language Features: * Accept declarations of state variables with ``transient`` data location (parser support only, no code generation yet). diff --git a/docs/bugs_by_version.json b/docs/bugs_by_version.json index 037a36341c16..f9913d812c63 100644 --- a/docs/bugs_by_version.json +++ b/docs/bugs_by_version.json @@ -1898,6 +1898,10 @@ "bugs": [], "released": "2024-05-21" }, + "0.8.27": { + "bugs": [], + "released": "2024-09-04" + }, "0.8.3": { "bugs": [ "FullInlinerNonExpressionSplitArgumentEvaluationOrder", From 7e5836a65ec3354864d5a936e1bc42d78e24186e Mon Sep 17 00:00:00 2001 From: Nikola Matic Date: Wed, 4 Sep 2024 09:14:49 +0200 Subject: [PATCH 0404/1022] Set version to 0.8.28 --- CMakeLists.txt | 2 +- Changelog.md | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 656cec34863f..7770d29e633d 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.27") +set(PROJECT_VERSION "0.8.28") # 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 01abe1af6bef..0ecb280c7d86 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,3 +1,14 @@ +### 0.8.28 (unreleased) + +Language Features: + + +Compiler Features: + + +Bugfixes: + + ### 0.8.27 (2024-09-04) Language Features: From a298438fbb296e4a65aa8e179ac9855ded915a0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Mon, 2 Sep 2024 18:38:48 +0200 Subject: [PATCH 0405/1022] We no longer use a `release` branch --- scripts/docker_deploy_manual.sh | 2 +- scripts/release_ppa.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/docker_deploy_manual.sh b/scripts/docker_deploy_manual.sh index 48d021ff0bf9..11c0b8d3af68 100755 --- a/scripts/docker_deploy_manual.sh +++ b/scripts/docker_deploy_manual.sh @@ -21,7 +21,7 @@ cd solidity commithash=$(git rev-parse --short=8 HEAD) echo -n "$commithash" > commit_hash.txt version=$("$(dirname "$0")/get_version.sh") -if [ "$branch" = "release" ] || [ "$branch" = v"$version" ] +if [ "$branch" = v"$version" ] then echo -n > prerelease.txt else diff --git a/scripts/release_ppa.sh b/scripts/release_ppa.sh index 64a81f542e86..773c43cc9968 100755 --- a/scripts/release_ppa.sh +++ b/scripts/release_ppa.sh @@ -6,7 +6,7 @@ ## You can pass a branch name as argument to this script (which, if no argument is given, ## will default to "develop"). ## -## If the given branch is "release", the resulting package will be uploaded to +## If the given branch matches a release version tag, the resulting package will be uploaded to ## ethereum/ethereum PPA, or ethereum/ethereum-dev PPA otherwise. ## ## It will clone the Solidity git from github, determine the version, From ee08a758dc7d857704d533413f174e4e565216e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Mon, 2 Sep 2024 19:27:02 +0200 Subject: [PATCH 0406/1022] docker_deploy_manual.sh: Make script more configurable to allow testing it in CI --- scripts/docker_deploy_manual.sh | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/scripts/docker_deploy_manual.sh b/scripts/docker_deploy_manual.sh index 11c0b8d3af68..67f5e6b95b13 100755 --- a/scripts/docker_deploy_manual.sh +++ b/scripts/docker_deploy_manual.sh @@ -2,13 +2,25 @@ set -e -if [ -z "$1" ] -then - echo "Usage: $0 " - exit 1 -fi +REPO_ROOT="$(dirname "$0")/.." +# shellcheck source=scripts/common.sh +source "${REPO_ROOT}/scripts/common.sh" + image="ethereum/solc" + +if (( $# < 1 || $# > 3 )); then + fail "Usage: $0 [repo URL] [--no-push]" +fi + branch="$1" +repo_url="${2:-https://github.com/ethereum/solidity.git}" + +if (( $# >= 3 )); then + [[ $3 == --no-push ]] || fail "Invalid flag: $3. Expected --no-push." + publish=false +else + publish=true +fi #docker login @@ -16,7 +28,7 @@ DIR=$(mktemp -d) ( cd "$DIR" -git clone --recursive --depth 2 https://github.com/ethereum/solidity.git -b "$branch" +git clone --recursive --depth 2 "$repo_url" -b "$branch" cd solidity commithash=$(git rev-parse --short=8 HEAD) echo -n "$commithash" > commit_hash.txt @@ -31,7 +43,7 @@ fi function tag_and_push { docker tag "$image:$1" "$image:$2" - docker push "$image:$2" + [[ $publish == false ]] || docker push "$image:$2" } rm -rf .git From 7cca807d218aead77a4c1960d28a5b1dd18e2a41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Mon, 2 Sep 2024 19:27:11 +0200 Subject: [PATCH 0407/1022] b_alpine_docker nightly job --- .circleci/config.yml | 19 +++++++++++++++++++ scripts/docker_deploy_manual.sh | 2 +- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index b5d0b76d6ec9..710d275d431a 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1830,6 +1830,22 @@ jobs: - matrix_notify_failure_unless_pr - matrix_notify_release_unless_pr + b_alpine_docker: + <<: *base_cimg_small + steps: + - setup_remote_docker: + # Always build from scratch to use current packages. + # This job is only meant to run nightly so build time is not an issue. + docker_layer_caching: false + - checkout + - run: + name: Build and tag the container + command: scripts/docker_deploy_manual.sh develop "file://$PWD" --no-push + - run: + name: Smoke test + command: docker run --pull=never ethereum/solc:build-alpine --version + - matrix_notify_failure_unless_pr + workflows: version: 2 @@ -2009,6 +2025,9 @@ workflows: - b_ubu: *requires_nothing - t_ubu_soltest_deprecated_evm_versions: *requires_b_ubu + # Build in a Docker container (on Alpine Linux) + - b_alpine_docker: *requires_nothing + nightly-ossfuzz: triggers: diff --git a/scripts/docker_deploy_manual.sh b/scripts/docker_deploy_manual.sh index 67f5e6b95b13..232fcbe4498d 100755 --- a/scripts/docker_deploy_manual.sh +++ b/scripts/docker_deploy_manual.sh @@ -28,7 +28,7 @@ DIR=$(mktemp -d) ( cd "$DIR" -git clone --recursive --depth 2 "$repo_url" -b "$branch" +git clone --recursive --depth 2 "$repo_url" -b "$branch" solidity cd solidity commithash=$(git rev-parse --short=8 HEAD) echo -n "$commithash" > commit_hash.txt From 32b8b41351c019bec6ea51c984edc18c5fe4bf4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Mon, 2 Sep 2024 20:19:46 +0200 Subject: [PATCH 0408/1022] docker_deploy_manual.sh: Switch to plain docker build output - For some reason it defaults to `tty` on CircleCI which is very spammy and makes logs unreadable. --- scripts/docker_deploy_manual.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/docker_deploy_manual.sh b/scripts/docker_deploy_manual.sh index 232fcbe4498d..8753d59c9a2d 100755 --- a/scripts/docker_deploy_manual.sh +++ b/scripts/docker_deploy_manual.sh @@ -47,13 +47,13 @@ function tag_and_push } rm -rf .git -docker build -t "$image":build -f scripts/Dockerfile . +docker build -t "$image":build -f scripts/Dockerfile . --progress plain tmp_container=$(docker create "$image":build sh) # Alpine image mkdir -p upload docker cp "${tmp_container}":/usr/bin/solc upload/solc-static-linux -docker build -t "$image":build-alpine -f scripts/Dockerfile_alpine . +docker build -t "$image":build-alpine -f scripts/Dockerfile_alpine . --progress plain if [ "$branch" = "develop" ] then From 7f582e4265ed2bcad06415eeaf0d5fa20f1c4ab2 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Thu, 5 Sep 2024 08:58:18 +0200 Subject: [PATCH 0409/1022] Add ContiguousDisjointSet datastructure --- libsolutil/CMakeLists.txt | 2 + libsolutil/DisjointSet.cpp | 109 ++++++++++++++++++++++++++++++++ libsolutil/DisjointSet.h | 66 +++++++++++++++++++ test/CMakeLists.txt | 1 + test/libsolutil/DisjointSet.cpp | 103 ++++++++++++++++++++++++++++++ 5 files changed, 281 insertions(+) create mode 100644 libsolutil/DisjointSet.cpp create mode 100644 libsolutil/DisjointSet.h create mode 100644 test/libsolutil/DisjointSet.cpp diff --git a/libsolutil/CMakeLists.txt b/libsolutil/CMakeLists.txt index a1e9559edef0..6ece23805aac 100644 --- a/libsolutil/CMakeLists.txt +++ b/libsolutil/CMakeLists.txt @@ -8,6 +8,8 @@ set(sources CommonIO.cpp CommonIO.h cxx20.h + DisjointSet.cpp + DisjointSet.h DominatorFinder.h Exceptions.cpp Exceptions.h diff --git a/libsolutil/DisjointSet.cpp b/libsolutil/DisjointSet.cpp new file mode 100644 index 000000000000..43d3bfa188c0 --- /dev/null +++ b/libsolutil/DisjointSet.cpp @@ -0,0 +1,109 @@ +/* + This file is part of solidity. + + solidity is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + solidity is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with solidity. If not, see . +*/ +// SPDX-License-Identifier: GPL-3.0 + +#include + +#include + +#include + +using namespace solidity::util; + +ContiguousDisjointSet::ContiguousDisjointSet(size_t const _numNodes): + m_parents(_numNodes), + m_neighbors(_numNodes), + m_sizes(_numNodes, static_cast(1)), + m_numSets(_numNodes) +{ + // each is their own neighbor and parent + std::iota(m_parents.begin(), m_parents.end(), 0); + std::iota(m_neighbors.begin(), m_neighbors.end(), 0); +} + +size_t ContiguousDisjointSet::numSets() const { return m_numSets; } + +ContiguousDisjointSet::value_type ContiguousDisjointSet::find(value_type const _element) const +{ + solAssert(_element < m_parents.size()); + // path halving + value_type rootElement = _element; + while (rootElement != m_parents[rootElement]) + { + m_parents[rootElement] = m_parents[m_parents[rootElement]]; + rootElement = m_parents[rootElement]; + } + return rootElement; +} + +void ContiguousDisjointSet::merge(value_type const _x, value_type const _y, bool const _mergeBySize) +{ + auto xRoot = find(_x); + auto yRoot = find(_y); + + if (xRoot == yRoot) + return; // we're done, nothing to merge here + + // if merge by size: merge smaller (yRoot) into larger (xRoot) subset; + // otherwise if _x is the representative of subset(_x), it will stay representative + if (_mergeBySize && m_sizes[xRoot] < m_sizes[yRoot]) + std::swap(xRoot, yRoot); + + m_parents[yRoot] = xRoot; + m_sizes[xRoot] += m_sizes[yRoot]; + std::swap(m_neighbors[xRoot], m_neighbors[yRoot]); + --m_numSets; +} + +bool ContiguousDisjointSet::sameSubset(value_type const _x, value_type const _y) const +{ + return find(_x) == find(_y); +} + +ContiguousDisjointSet::size_type ContiguousDisjointSet::sizeOfSubset(value_type const _x) const +{ + return m_sizes[find(_x)]; +} + +std::set ContiguousDisjointSet::subset(value_type const _x) const +{ + solAssert(_x < m_parents.size()); + std::set result{_x}; + value_type neighbor = m_neighbors[_x]; + while (neighbor != _x) + { + result.insert(neighbor); + neighbor = m_neighbors[neighbor]; + } + return result; +} + +std::vector> ContiguousDisjointSet::subsets() const +{ + std::vector> result; + std::vector visited(m_parents.size(), false); + for (value_type x = 0; x < m_parents.size(); ++x) + { + auto xRoot = find(x); + if (!visited[xRoot]) + { + result.push_back(subset(xRoot)); + visited[xRoot] = true; + } + } + return result; +} diff --git a/libsolutil/DisjointSet.h b/libsolutil/DisjointSet.h new file mode 100644 index 000000000000..02792cbe699f --- /dev/null +++ b/libsolutil/DisjointSet.h @@ -0,0 +1,66 @@ +/* + This file is part of solidity. + + solidity is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + solidity is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with solidity. If not, see . +*/ +// SPDX-License-Identifier: GPL-3.0 + +#pragma once + +#include +#include +#include + +namespace solidity::util +{ + +/// Implementation of the Disjoint set data structure [1], also called union-set, with path-halving [2]. +/// This implementation assumes that each set element is identified with an element in a iota range (hence contiguous). +/// +/// [1] https://en.wikipedia.org/wiki/Disjoint-set_data_structure +/// [2] Tarjan, Robert E., and Jan Van Leeuwen. "Worst-case analysis of set union algorithms." +/// Journal of the ACM (JACM) 31.2 (1984): 245-281. +class ContiguousDisjointSet +{ +public: + using size_type = size_t; + using value_type = size_t; + + /// Constructs a new disjoint set datastructure with `_numNodes` elements and each element in its own individual set + explicit ContiguousDisjointSet(size_t _numNodes); + + size_type numSets() const; + + /// finds one representative for a set that contains `_element` + value_type find(value_type _element) const; + + /// joins the two sets containing `_x` and `_y`, returns true if the sets were disjoint, otherwise false + void merge(value_type _x, value_type _y, bool _mergeBySize=true); + + bool sameSubset(value_type _x, value_type _y) const; + + size_type sizeOfSubset(value_type _x) const; + + std::set subset(value_type _x) const; + + std::vector> subsets() const; + +private: + std::vector mutable m_parents; // mutable for path compression, doesn't change semantic state + std::vector m_neighbors; + std::vector m_sizes; + size_type m_numSets; +}; + +} diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index d3498965dc24..da115f0d4a5b 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -31,6 +31,7 @@ set(libsolutil_sources libsolutil/Checksum.cpp libsolutil/CommonData.cpp libsolutil/CommonIO.cpp + libsolutil/DisjointSet.cpp libsolutil/DominatorFinderTest.cpp libsolutil/FixedHash.cpp libsolutil/FunctionSelector.cpp diff --git a/test/libsolutil/DisjointSet.cpp b/test/libsolutil/DisjointSet.cpp new file mode 100644 index 000000000000..338138b6aec1 --- /dev/null +++ b/test/libsolutil/DisjointSet.cpp @@ -0,0 +1,103 @@ +/* + This file is part of solidity. + + solidity is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + solidity is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with solidity. If not, see . +*/ +/** + * Unit tests for DisjointSet. + */ + +#include + +#include + +namespace solidity::util::test +{ + +BOOST_AUTO_TEST_SUITE(DisjointSetTest) + +BOOST_AUTO_TEST_CASE(full_union) +{ + ContiguousDisjointSet ds(10); + for (size_t i = 1; i < 10; ++i) + { + BOOST_CHECK(!ds.sameSubset(0, i)); + ds.merge(0, i); + BOOST_CHECK(ds.sameSubset(0, i)); + } + BOOST_CHECK_EQUAL(ds.numSets(), 1); + auto const& subsets = ds.subsets(); + BOOST_CHECK_EQUAL(subsets.size(), 1); + std::set fullSet{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; + BOOST_CHECK_EQUAL_COLLECTIONS(subsets[0].begin(), subsets[0].end(), fullSet.begin(), fullSet.end()); + + for (size_t i = 1; i < 10; ++i) BOOST_CHECK_EQUAL(ds.find(0), ds.find(i)); +} + +BOOST_AUTO_TEST_CASE(pairs) +{ + ContiguousDisjointSet ds(10); + BOOST_CHECK_EQUAL(ds.numSets(), 10); + BOOST_CHECK_EQUAL(ds.subsets().size(), 10); + + auto const checkPair = [&](size_t expectedNumSubsets, size_t x, size_t y) + { + BOOST_CHECK_EQUAL(ds.numSets(), expectedNumSubsets); + BOOST_CHECK_EQUAL(ds.subsets().size(), expectedNumSubsets); + BOOST_CHECK(ds.sameSubset(x, y)); + auto const subset = ds.subset(x); + std::set subsetRef{x, y}; + BOOST_CHECK_EQUAL_COLLECTIONS(subset.begin(), subset.end(), subsetRef.begin(), subsetRef.end()); + }; + + ds.merge(5, 3); + checkPair(9, 5, 3); + + ds.merge(1, 6); + checkPair(8, 1, 6); + + ds.merge(0, 2); + checkPair(7, 0, 2); + + ds.merge(1, 5); + BOOST_CHECK_EQUAL(ds.sizeOfSubset(3), 4); + + ds.merge(1, 0); + + // now we should have a subset with {0, 1, 2, 3, 5, 6} + std::set subsetRef{0, 1, 2, 3, 5, 6}; + BOOST_CHECK_EQUAL(ds.sizeOfSubset(6), subsetRef.size()); + auto const subset = ds.subset(2); + BOOST_CHECK_EQUAL_COLLECTIONS(subset.begin(), subset.end(), subsetRef.begin(), subsetRef.end()); +} + +BOOST_AUTO_TEST_CASE(merge_with_fixed_representative) +{ + ContiguousDisjointSet ds(10); + ds.merge(5, 3, false); + BOOST_CHECK_EQUAL(ds.find(5), 5); + ds.merge(1, 2); + ds.merge(7, 8); + ds.merge(0, 9); + ds.merge(5, 1, false); + BOOST_CHECK_EQUAL(ds.find(5), 5); + ds.merge(5, 0, false); + BOOST_CHECK_EQUAL(ds.find(5), 5); + ds.merge(5, 7, false); + BOOST_CHECK_EQUAL(ds.find(5), 5); +} + +BOOST_AUTO_TEST_SUITE_END() + +} From fc2e90fdda623768d9d41b6a1ccd8a9995e479c6 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Mon, 9 Sep 2024 10:13:52 +0200 Subject: [PATCH 0410/1022] Add topological sort implementation for forward SSACFG --- libyul/CMakeLists.txt | 2 + libyul/backends/evm/SSACFGTopologicalSort.cpp | 93 +++++++++++++++++++ libyul/backends/evm/SSACFGTopologicalSort.h | 60 ++++++++++++ 3 files changed, 155 insertions(+) create mode 100644 libyul/backends/evm/SSACFGTopologicalSort.cpp create mode 100644 libyul/backends/evm/SSACFGTopologicalSort.h diff --git a/libyul/CMakeLists.txt b/libyul/CMakeLists.txt index c0082f5d69fd..704e04921b67 100644 --- a/libyul/CMakeLists.txt +++ b/libyul/CMakeLists.txt @@ -65,6 +65,8 @@ add_library(yul backends/evm/NoOutputAssembly.cpp backends/evm/OptimizedEVMCodeTransform.cpp backends/evm/OptimizedEVMCodeTransform.h + backends/evm/SSACFGTopologicalSort.cpp + backends/evm/SSACFGTopologicalSort.h backends/evm/SSAControlFlowGraph.h backends/evm/SSAControlFlowGraphBuilder.cpp backends/evm/SSAControlFlowGraphBuilder.h diff --git a/libyul/backends/evm/SSACFGTopologicalSort.cpp b/libyul/backends/evm/SSACFGTopologicalSort.cpp new file mode 100644 index 000000000000..e0370aa275b9 --- /dev/null +++ b/libyul/backends/evm/SSACFGTopologicalSort.cpp @@ -0,0 +1,93 @@ +/* + 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 + +using namespace solidity::yul; + +ForwardSSACFGTopologicalSort::ForwardSSACFGTopologicalSort(SSACFG const& _cfg): + m_cfg(_cfg), + m_explored(m_cfg.numBlocks(), false), + m_reversedPostOrder(m_cfg.numBlocks(), std::numeric_limits::max()), + m_preOrder(m_cfg.numBlocks(), std::numeric_limits::max()), + m_maxSubtreePreOrder(m_cfg.numBlocks(), 0), + m_predecessors(m_cfg.numBlocks()) +{ + for (size_t id = 0; id < m_cfg.numBlocks(); ++id) + { + if (!m_explored[id]) + dfs(id); + } + std::reverse(m_reversedPostOrder.begin(), m_reversedPostOrder.end()); + + for (auto const& [v1, v2]: m_potentialBackEdges) + if (ancestor(v2, v1)) + m_backEdgeTargets.insert(v2); +} + +void ForwardSSACFGTopologicalSort::dfs(size_t const _vertex) { + yulAssert(!m_explored[_vertex]); + m_explored[_vertex] = true; + m_preOrder[_vertex] = m_currentNode++; + m_maxSubtreePreOrder[_vertex] = m_preOrder[_vertex]; + + m_cfg.block(SSACFG::BlockId{_vertex}).forEachExit([&](SSACFG::BlockId const& _exitBlock){ + m_predecessors[_exitBlock.value].insert(_vertex); + if (!m_explored[_exitBlock.value]) + { + dfs(_exitBlock.value); + m_maxSubtreePreOrder[_vertex] = std::max(m_maxSubtreePreOrder[_vertex], m_maxSubtreePreOrder[_exitBlock.value]); + } + else + m_potentialBackEdges.emplace_back(_vertex, _exitBlock.value); + }); + + m_reversedPostOrder[m_preOrder[_vertex]] = _vertex; +} + +std::vector const& ForwardSSACFGTopologicalSort::sortedBlocks() const { return m_reversedPostOrder; } +std::vector const& ForwardSSACFGTopologicalSort::preOrder() const { return m_preOrder; } +std::vector const& ForwardSSACFGTopologicalSort::reversedPostOrder() const { return m_reversedPostOrder; } +std::vector const& ForwardSSACFGTopologicalSort::maxSubtreePreOrder() const { return m_maxSubtreePreOrder; } +std::set const& ForwardSSACFGTopologicalSort::backEdgeTargets() const { return m_backEdgeTargets; } +std::vector> const& ForwardSSACFGTopologicalSort::predecessors() const { return m_predecessors; } +SSACFG const& ForwardSSACFGTopologicalSort::cfg() const { return m_cfg; } + +bool ForwardSSACFGTopologicalSort::ancestor(size_t const _block1, size_t const _block2) const { + yulAssert(_block1 < m_preOrder.size()); + yulAssert(_block2 < m_preOrder.size()); + + auto const preOrderIndex1 = m_preOrder[_block1]; + auto const preOrderIndex2 = m_preOrder[_block2]; + + bool const node1VisitedBeforeNode2 = preOrderIndex1 <= preOrderIndex2; + bool const node2InSubtreeOfNode1 = preOrderIndex2 <= m_maxSubtreePreOrder[_block1]; + return node1VisitedBeforeNode2 && node2InSubtreeOfNode1; +} + +bool ForwardSSACFGTopologicalSort::backEdge(SSACFG::BlockId const& _block1, SSACFG::BlockId const& _block2) const +{ + if (ancestor(_block2.value, _block1.value)) + { + // check that block1 -> block2 is indeed an edge in the cfg + bool isEdge = false; + m_cfg.block(_block1).forEachExit([&_block2, &isEdge](SSACFG::BlockId const& _exit) { isEdge |= _block2 == _exit; }); + return isEdge; + } + return false; +} diff --git a/libyul/backends/evm/SSACFGTopologicalSort.h b/libyul/backends/evm/SSACFGTopologicalSort.h new file mode 100644 index 000000000000..ec62eb01370d --- /dev/null +++ b/libyul/backends/evm/SSACFGTopologicalSort.h @@ -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 + +#pragma once + +#include + +#include +#include +#include + +namespace solidity::yul +{ + +/// Performs a topological sort on the forward CFG (no back/cross edges) +class ForwardSSACFGTopologicalSort +{ +public: + explicit ForwardSSACFGTopologicalSort(SSACFG const& _cfg); + + std::vector const& sortedBlocks() const; + std::vector const& preOrder() const; + std::vector const& reversedPostOrder() const; + std::vector const& maxSubtreePreOrder() const; + std::set const& backEdgeTargets() const; + std::vector> const& predecessors() const; + SSACFG const& cfg() const; + bool ancestor(size_t _block1, size_t _block2) const; + bool backEdge(SSACFG::BlockId const& _block1, SSACFG::BlockId const& _block2) const; + +private: + void dfs(size_t _vertex); + + SSACFG const& m_cfg; + + size_t m_currentNode {0}; + std::vector m_explored{}; + std::vector m_reversedPostOrder{}; + std::vector m_preOrder{}; + std::vector m_maxSubtreePreOrder{}; + std::vector> m_potentialBackEdges{}; + std::set m_backEdgeTargets{}; + std::vector> m_predecessors{}; +}; +} From 13fe5ba98c763ea9e6ed6bb747ee101fdedff679 Mon Sep 17 00:00:00 2001 From: Matheus Aguiar Date: Mon, 17 Jun 2024 22:22:34 -0300 Subject: [PATCH 0411/1022] Replace errors/warning/info empty check with proper errors only check --- liblangutil/ErrorReporter.h | 6 ++++++ liblangutil/Exceptions.h | 5 +++++ libsolidity/analysis/DeclarationTypeChecker.cpp | 2 +- libsolidity/codegen/CompilerContext.cpp | 6 +++--- libsolidity/interface/StandardCompiler.cpp | 9 +-------- libyul/YulStack.cpp | 2 +- test/libsolidity/InlineAssembly.cpp | 4 ++-- test/libyul/Common.cpp | 2 +- test/tools/yulopti.cpp | 4 ++-- test/tools/yulrun.cpp | 2 +- tools/yulPhaser/Program.cpp | 4 ++-- 11 files changed, 25 insertions(+), 21 deletions(-) diff --git a/liblangutil/ErrorReporter.h b/liblangutil/ErrorReporter.h index d7e280ed9049..989cc4d5e3a0 100644 --- a/liblangutil/ErrorReporter.h +++ b/liblangutil/ErrorReporter.h @@ -130,6 +130,12 @@ class ErrorReporter return m_errorCount > 0; } + /// @returns true if there is any error, warning or info. + bool hasErrorsWarningsOrInfos() const + { + return m_errorCount + m_warningCount + m_infoCount > 0; + } + /// @returns the number of errors (ignores warnings and infos). unsigned errorCount() const { diff --git a/liblangutil/Exceptions.h b/liblangutil/Exceptions.h index b0701f99938e..c441a6d2f962 100644 --- a/liblangutil/Exceptions.h +++ b/liblangutil/Exceptions.h @@ -256,6 +256,11 @@ class Error: virtual public util::Exception return false; } + static bool hasErrorsWarningsOrInfos(ErrorList const& _list) + { + return !_list.empty(); + } + static std::string formatErrorSeverity(Severity _severity) { switch (_severity) diff --git a/libsolidity/analysis/DeclarationTypeChecker.cpp b/libsolidity/analysis/DeclarationTypeChecker.cpp index bdf023c5c0b9..f5db21100029 100644 --- a/libsolidity/analysis/DeclarationTypeChecker.cpp +++ b/libsolidity/analysis/DeclarationTypeChecker.cpp @@ -329,7 +329,7 @@ void DeclarationTypeChecker::endVisit(ArrayTypeName const& _typeName) Type const* baseType = _typeName.baseType().annotation().type; if (!baseType) { - solAssert(!m_errorReporter.errors().empty(), ""); + solAssert(m_errorReporter.hasErrors(), ""); return; } diff --git a/libsolidity/codegen/CompilerContext.cpp b/libsolidity/codegen/CompilerContext.cpp index 2e94e9f0b8d2..83b4589fe982 100644 --- a/libsolidity/codegen/CompilerContext.cpp +++ b/libsolidity/codegen/CompilerContext.cpp @@ -473,7 +473,7 @@ void CompilerContext::appendInlineAssembly( dialect, identifierAccess.resolve ).analyze(parserResult->root()); - if (!parserResult || !errorReporter.errors().empty() || !analyzerResult) + if (!parserResult || errorReporter.hasErrorsWarningsOrInfos() || !analyzerResult) reportError("Invalid assembly generated by code generator."); std::shared_ptr toBeAssembledAST = parserResult; @@ -513,10 +513,10 @@ void CompilerContext::appendInlineAssembly( m_generatedYulUtilityCode = _assembly; } - if (!errorReporter.errors().empty()) + if (errorReporter.hasErrorsWarningsOrInfos()) reportError("Failed to analyze inline assembly block."); - solAssert(errorReporter.errors().empty(), "Failed to analyze inline assembly block."); + solAssert(!errorReporter.hasErrorsWarningsOrInfos(), "Failed to analyze inline assembly block."); yul::CodeGenerator::assemble( toBeAssembledAST->root(), analysisInfo, diff --git a/libsolidity/interface/StandardCompiler.cpp b/libsolidity/interface/StandardCompiler.cpp index 0194aa937d5e..7271cce8bee7 100644 --- a/libsolidity/interface/StandardCompiler.cpp +++ b/libsolidity/interface/StandardCompiler.cpp @@ -1621,14 +1621,7 @@ Json StandardCompiler::compileYul(InputsAndSettings _inputsAndSettings) // Inconsistent state - stop here to receive error reports from users if (!stack.parseAndAnalyze(sourceName, sourceContents) && !stack.hasErrors()) - { - output["errors"].emplace_back(formatError( - Error::Type::InternalCompilerError, - "general", - "No error reported, but compilation failed." - )); - return output; - } + solAssert(false, "No error reported, but parsing/analysis failed."); for (auto const& error: stack.errors()) { diff --git a/libyul/YulStack.cpp b/libyul/YulStack.cpp index bd2c7390619b..01eb5b7383cd 100644 --- a/libyul/YulStack.cpp +++ b/libyul/YulStack.cpp @@ -64,7 +64,7 @@ bool YulStack::parse(std::string const& _sourceName, std::string const& _source) reportUnimplementedFeatureError(_error); } - if (m_errorReporter.errors().empty()) + if (!m_errorReporter.hasErrors()) m_stackState = Parsed; return m_stackState == Parsed; diff --git a/test/libsolidity/InlineAssembly.cpp b/test/libsolidity/InlineAssembly.cpp index a0aa39be4989..b3993e39f3df 100644 --- a/test/libsolidity/InlineAssembly.cpp +++ b/test/libsolidity/InlineAssembly.cpp @@ -131,7 +131,7 @@ void parsePrintCompare(std::string const& _source, bool _canWarn = false) if (_canWarn) BOOST_REQUIRE(!Error::containsErrors(stack.errors())); else - BOOST_REQUIRE(stack.errors().empty()); + BOOST_REQUIRE(!Error::hasErrorsWarningsOrInfos(stack.errors())); std::string expectation = "object \"object\" {\n code " + boost::replace_all_copy(_source, "\n", "\n ") + "\n}\n"; BOOST_CHECK_EQUAL(stack.print(), expectation); } @@ -219,7 +219,7 @@ BOOST_AUTO_TEST_CASE(print_string_literal_unicode) DebugInfoSelection::None() ); BOOST_REQUIRE(stack.parseAndAnalyze("", source)); - BOOST_REQUIRE(stack.errors().empty()); + BOOST_REQUIRE(!Error::hasErrorsWarningsOrInfos(stack.errors())); BOOST_CHECK_EQUAL(stack.print(), parsed); std::string parsedInner = "{ let x := \"\\xe1\\xae\\xac\" }"; diff --git a/test/libyul/Common.cpp b/test/libyul/Common.cpp index 8980adcb1821..7640e4a5ddf7 100644 --- a/test/libyul/Common.cpp +++ b/test/libyul/Common.cpp @@ -61,7 +61,7 @@ std::pair, std::shared_ptr> yul solidity::frontend::OptimiserSettings::minimal(), DebugInfoSelection::All() ); - if (!stack.parseAndAnalyze("", _source) || !stack.errors().empty()) + if (!stack.parseAndAnalyze("", _source) || Error::hasErrorsWarningsOrInfos(stack.errors())) BOOST_FAIL("Invalid source."); return std::make_pair(stack.parserResult()->code(), stack.parserResult()->analysisInfo); } diff --git a/test/tools/yulopti.cpp b/test/tools/yulopti.cpp index 891f39c43365..13375f827762 100644 --- a/test/tools/yulopti.cpp +++ b/test/tools/yulopti.cpp @@ -91,7 +91,7 @@ class YulOpti try { auto ast = yul::Parser(errorReporter, m_dialect).parse(_charStream); - if (!m_astRoot || !errorReporter.errors().empty()) + if (!m_astRoot || errorReporter.hasErrors()) { std::cerr << "Error parsing source." << std::endl; printErrors(_charStream, errors); @@ -104,7 +104,7 @@ class YulOpti errorReporter, m_dialect ); - if (!analyzer.analyze(*m_astRoot) || !errorReporter.errors().empty()) + if (!analyzer.analyze(*m_astRoot) || errorReporter.hasErrors()) { std::cerr << "Error analyzing source." << std::endl; printErrors(_charStream, errors); diff --git a/test/tools/yulrun.cpp b/test/tools/yulrun.cpp index c3a7fb19fccc..e857c26645ee 100644 --- a/test/tools/yulrun.cpp +++ b/test/tools/yulrun.cpp @@ -65,7 +65,7 @@ std::pair, std::shared_ptr> parse(st ); if (stack.parseAndAnalyze("--INPUT--", _source)) { - yulAssert(stack.errors().empty(), "Parsed successfully but had errors."); + yulAssert(!Error::hasErrorsWarningsOrInfos(stack.errors()), "Parsed successfully but had errors."); return make_pair(stack.parserResult()->code(), stack.parserResult()->analysisInfo); } else diff --git a/tools/yulPhaser/Program.cpp b/tools/yulPhaser/Program.cpp index bb9eebc4badc..57e1bf2b9342 100644 --- a/tools/yulPhaser/Program.cpp +++ b/tools/yulPhaser/Program.cpp @@ -122,7 +122,7 @@ std::variant, ErrorList> Program::parseObject(Dialect const ObjectParser parser(errorReporter, _dialect); std::shared_ptr object = parser.parse(scanner, false); - if (object == nullptr || !errorReporter.errors().empty()) + if (object == nullptr || errorReporter.hasErrors()) // NOTE: It's possible to get errors even if the returned object is non-null. // For example when there are errors in a nested object. return errors; @@ -165,7 +165,7 @@ std::variant, ErrorList> Program::analyzeAST(Di if (!analysisSuccessful) return errors; - assert(errorReporter.errors().empty()); + assert(!errorReporter.hasErrors()); return std::variant, ErrorList>(std::move(analysisInfo)); } From c446d3bb20bf0689926a428cedc0ac65140d9f30 Mon Sep 17 00:00:00 2001 From: Martin Blicha Date: Thu, 22 Aug 2024 16:19:09 +0200 Subject: [PATCH 0412/1022] SMTChecker: Fix parsing of model values in BMC SMT solvers return model values as pairs (enclosed in parentheses) of name and value. Previous way of parsing model values relied on finding the next closing bracket. However, this does not work for negative numbers, which are themselves wrapped in parentheses, e.g. (- 1). --- libsmtutil/SMTLib2Interface.cpp | 55 +++++++++++++++++++++++---------- libsmtutil/SMTLib2Interface.h | 1 - 2 files changed, 38 insertions(+), 18 deletions(-) diff --git a/libsmtutil/SMTLib2Interface.cpp b/libsmtutil/SMTLib2Interface.cpp index 81ad5ddd4b25..0914f8305dc3 100644 --- a/libsmtutil/SMTLib2Interface.cpp +++ b/libsmtutil/SMTLib2Interface.cpp @@ -18,6 +18,8 @@ #include +#include + #include #include @@ -110,6 +112,41 @@ void SMTLib2Interface::addAssertion(Expression const& _expr) m_commands.assertion(toSExpr(_expr)); } +namespace +{ +std::vector parseValuesFromResponse(std::string const& _response) +{ + std::stringstream ss(_response); + std::string answer; + ss >> answer; + smtAssert(answer == "sat"); + + std::vector parsedOutput; + SMTLib2Parser parser(ss); + try + { + while (!parser.isEOF()) + parsedOutput.push_back(parser.parseExpression()); + } + catch(SMTLib2Parser::ParsingException&) + { + return {}; + } + smtAssert(parsedOutput.size() == 1, "SMT: Expected model values as a single s-expression"); + auto const& values = parsedOutput[0]; + smtAssert(!isAtom(values)); + std::vector parsedValues; + for (auto const& nameValuePair: asSubExpressions(values)) + { + smtAssert(!isAtom(nameValuePair)); + smtAssert(asSubExpressions(nameValuePair).size() == 2); + auto const& value = asSubExpressions(nameValuePair)[1]; + parsedValues.push_back(value.toString()); + } + return parsedValues; +} +} // namespace + std::pair> SMTLib2Interface::check(std::vector const& _expressionsToEvaluate) { std::string response = querySolver(dumpQuery(_expressionsToEvaluate)); @@ -127,7 +164,7 @@ std::pair> SMTLib2Interface::check(std::ve std::vector values; if (result == CheckResult::SATISFIABLE && !_expressionsToEvaluate.empty()) - values = parseValues(find(response.cbegin(), response.cend(), '\n'), response.cend()); + values = parseValuesFromResponse(response); return std::make_pair(result, values); } @@ -175,22 +212,6 @@ std::string SMTLib2Interface::checkSatAndGetValuesCommand(std::vector SMTLib2Interface::parseValues(std::string::const_iterator _start, std::string::const_iterator _end) -{ - std::vector values; - while (_start < _end) - { - auto valStart = find(_start, _end, ' '); - if (valStart < _end) - ++valStart; - auto valEnd = find(valStart, _end, ')'); - values.emplace_back(valStart, valEnd); - _start = find(valEnd, _end, '('); - } - - return values; -} - std::string SMTLib2Interface::querySolver(std::string const& _input) { h256 inputHash = keccak256(_input); diff --git a/libsmtutil/SMTLib2Interface.h b/libsmtutil/SMTLib2Interface.h index 11478223cfdf..02b1c85ffe0e 100644 --- a/libsmtutil/SMTLib2Interface.h +++ b/libsmtutil/SMTLib2Interface.h @@ -103,7 +103,6 @@ class SMTLib2Interface: public BMCSolverInterface void declareFunction(std::string const& _name, SortPointer const& _sort); std::string checkSatAndGetValuesCommand(std::vector const& _expressionsToEvaluate); - std::vector parseValues(std::string::const_iterator _start, std::string::const_iterator _end); /// Communicates with the solver via the callback. Throws SMTSolverError on error. std::string querySolver(std::string const& _input); From a204f475fbcadef3cca82f78a2e0665811dafac1 Mon Sep 17 00:00:00 2001 From: Martin Blicha Date: Thu, 29 Aug 2024 13:42:46 +0200 Subject: [PATCH 0413/1022] SMTChecker: Prepare Z3 SMT-LIB interface for BMC engine This is a first draft and will not be used yet. --- libsolidity/formal/Z3SMTLib2Interface.cpp | 35 +++++++++++++++++++++ libsolidity/formal/Z3SMTLib2Interface.h | 37 +++++++++++++++++++++++ 2 files changed, 72 insertions(+) create mode 100644 libsolidity/formal/Z3SMTLib2Interface.cpp create mode 100644 libsolidity/formal/Z3SMTLib2Interface.h diff --git a/libsolidity/formal/Z3SMTLib2Interface.cpp b/libsolidity/formal/Z3SMTLib2Interface.cpp new file mode 100644 index 000000000000..b76cdd252281 --- /dev/null +++ b/libsolidity/formal/Z3SMTLib2Interface.cpp @@ -0,0 +1,35 @@ +/* + 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 + +using namespace solidity::frontend::smt; + +Z3SMTLib2Interface::Z3SMTLib2Interface( + frontend::ReadCallback::Callback _smtCallback, + std::optional _queryTimeout +): SMTLib2Interface({}, std::move(_smtCallback), _queryTimeout) +{ +} + +void Z3SMTLib2Interface::setupSmtCallback() { + if (auto* universalCallback = m_smtCallback.target()) + universalCallback->smtCommand().setZ3(m_queryTimeout, true, false); +} diff --git a/libsolidity/formal/Z3SMTLib2Interface.h b/libsolidity/formal/Z3SMTLib2Interface.h new file mode 100644 index 000000000000..07e138710624 --- /dev/null +++ b/libsolidity/formal/Z3SMTLib2Interface.h @@ -0,0 +1,37 @@ +/* + 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::frontend::smt +{ + +class Z3SMTLib2Interface: public smtutil::SMTLib2Interface +{ +public: + explicit Z3SMTLib2Interface( + frontend::ReadCallback::Callback _smtCallback = {}, + std::optional _queryTimeout = {} + ); +private: + void setupSmtCallback() override; +}; + +} From 6f548bec194776bef61b8f12172ce41f464c56c8 Mon Sep 17 00:00:00 2001 From: Nikola Matic Date: Mon, 9 Sep 2024 16:20:50 +0200 Subject: [PATCH 0414/1022] Upgrade jobs to run on Ubuntu 2404 --- .circleci/config.yml | 58 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index 710d275d431a..8384f2eeac9e 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -19,6 +19,14 @@ parameters: type: string # solbuildpackpusher/solidity-buildpack-deps:ubuntu2204.clang-8 default: "solbuildpackpusher/solidity-buildpack-deps@sha256:2662376fe0e1ec2d346495a19a6d64508c1048d5a7325d8600c33c343fa64a0f" + ubuntu-2404-docker-image: + type: string + # solbuildpackpusher/solidity-buildpack-deps:ubuntu2404-1 + default: "solbuildpackpusher/solidity-buildpack-deps@sha256:5d6d27551104321a30326d6024bd4e96d9d899a97a78eb9feea364996f1d18b5" + ubuntu-2404-clang-docker-image: + type: string + # solbuildpackpusher/solidity-buildpack-deps:ubuntu2404.clang-1 + default: "solbuildpackpusher/solidity-buildpack-deps@sha256:8df0086907cc1e57068ad48841f2284a87bfbd0a95006286a19a7132d84bb861" ubuntu-clang-ossfuzz-docker-image: type: string # solbuildpackpusher/solidity-buildpack-deps:ubuntu.clang.ossfuzz-6 @@ -602,6 +610,56 @@ defaults: MAKEFLAGS: -j 10 CPUs: 10 + - base_ubuntu2404: &base_ubuntu2404 + docker: + - image: << pipeline.parameters.ubuntu-2404-docker-image >> + environment: &base_ubuntu2404_env + TERM: xterm + MAKEFLAGS: -j 3 + CPUs: 3 + + - base_ubuntu2404_clang: &base_ubuntu2404_clang + docker: + - image: << pipeline.parameters.ubuntu-2404-clang-docker-image >> + environment: &base_ubuntu2404_clang_env + TERM: xterm + CC: clang + CXX: clang++ + MAKEFLAGS: -j 3 + CPUs: 3 + + - base_ubuntu2404_clang_large: &base_ubuntu2404_clang_large + <<: *base_ubuntu2404_clang + resource_class: large + environment: &base_ubuntu2404_clang_large_env + <<: *base_ubuntu2404_clang_env + MAKEFLAGS: -j 5 + CPUs: 5 + + - base_ubuntu2404_small: &base_ubuntu2404_small + <<: *base_ubuntu2404 + resource_class: small + environment: &base_ubuntu2404_small_env + <<: *base_ubuntu2404_env + MAKEFLAGS: -j 2 + CPUs: 2 + + - base_ubuntu2404_large: &base_ubuntu2404_large + <<: *base_ubuntu2404 + resource_class: large + environment: &base_ubuntu2404_large_env + <<: *base_ubuntu2404_env + MAKEFLAGS: -j 5 + CPUs: 5 + + - base_ubuntu2404_xlarge: &base_ubuntu2404_xlarge + <<: *base_ubuntu2404 + resource_class: xlarge + environment: &base_ubuntu2404_xlarge_env + <<: *base_ubuntu2404_env + MAKEFLAGS: -j 10 + CPUs: 10 + - base_win: &base_win executor: name: win/default From 6a695274cc65a68c9f050ff410ee85d6031b8dac Mon Sep 17 00:00:00 2001 From: Pawel Gebal Date: Mon, 9 Sep 2024 15:15:07 +0200 Subject: [PATCH 0415/1022] xSMTChecker: Fix SMT logic error when assigning to an array of addresses --- Changelog.md | 2 +- libsolidity/formal/SymbolicTypes.cpp | 4 ++++ .../smtCheckerTests/types/array_of_addresses.sol | 16 ++++++++++++++++ 3 files changed, 21 insertions(+), 1 deletion(-) create mode 100644 test/libsolidity/smtCheckerTests/types/array_of_addresses.sol diff --git a/Changelog.md b/Changelog.md index 0ecb280c7d86..f001a0efc62a 100644 --- a/Changelog.md +++ b/Changelog.md @@ -7,7 +7,7 @@ Compiler Features: Bugfixes: - + * SMTChecker: Fix SMT logic error when assigning to an array of addresses. ### 0.8.27 (2024-09-04) diff --git a/libsolidity/formal/SymbolicTypes.cpp b/libsolidity/formal/SymbolicTypes.cpp index 4a4ac8175f08..f9ec9b0110ed 100644 --- a/libsolidity/formal/SymbolicTypes.cpp +++ b/libsolidity/formal/SymbolicTypes.cpp @@ -118,6 +118,10 @@ SortPointer smtSort(frontend::Type const& _type) // use a common sort for functions so pure and view modifier do not cause conflicting SMT types // solc handles types mismtach tupleName = "function"; + else if (isAddress(*baseType)) + // use a common sort for address and address payable so it does not cause conflicting SMT types + // solc handles types mismtach + tupleName = "address"; else if ( baseType->category() == frontend::Type::Category::Integer || baseType->category() == frontend::Type::Category::FixedPoint diff --git a/test/libsolidity/smtCheckerTests/types/array_of_addresses.sol b/test/libsolidity/smtCheckerTests/types/array_of_addresses.sol new file mode 100644 index 000000000000..74f8548469f6 --- /dev/null +++ b/test/libsolidity/smtCheckerTests/types/array_of_addresses.sol @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: GPL-3.0 + +pragma solidity >=0.0.0; +contract C { + address[10] a; + address payable[10] b; + + function f() public { + a = b; + assert(a[0] == b[0]); + } +} +// ==== +// SMTEngine: all +// ---- +// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. From 9d7cc42bc1c12bb43e9dccf8c6c36833fdfcbbca Mon Sep 17 00:00:00 2001 From: Matheus Aguiar Date: Mon, 8 Jul 2024 19:27:57 -0300 Subject: [PATCH 0416/1022] legacy codegen transient storage support for state variables --- Changelog.md | 1 + .../analysis/DeclarationTypeChecker.cpp | 7 ++ libsolidity/analysis/ReferencesResolver.cpp | 2 +- libsolidity/analysis/TypeChecker.cpp | 6 +- libsolidity/ast/Types.cpp | 29 +++---- libsolidity/ast/Types.h | 2 +- libsolidity/codegen/Compiler.cpp | 14 +-- libsolidity/codegen/ContractCompiler.cpp | 8 +- libsolidity/codegen/ExpressionCompiler.cpp | 16 +++- libsolidity/codegen/LValue.cpp | 43 ++++++---- libsolidity/codegen/LValue.h | 17 +++- libsolidity/codegen/ir/IRGenerator.cpp | 7 +- .../args | 1 + .../err | 2 +- .../input.sol | 0 .../output | 2 +- .../evmasm_transient_storage_opcodes/args | 1 - .../args | 1 + .../input.sol | 9 ++ .../output | 86 +++++++++++++++++++ .../args | 1 + .../err | 1 + .../exit | 1 + .../input.sol | 9 ++ test/libsolidity/ASTPropertyTest.cpp | 2 +- test/libsolidity/ASTPropertyTest.h | 2 +- .../isSimpleCounterLoop_negative_cases.sol | 11 +++ .../transient_data_location.sol | 2 + .../getters/transient_value_types.sol | 15 ++++ ...transient_value_types_multi_frame_call.sol | 23 +++++ ...ansient_storage_access_inside_function.sol | 23 +++++ .../compound_assign_transient_storage.sol | 23 +++++ ...t_storage_variable_increment_decrement.sol | 16 ++++ .../delete_transient_state_variable.sol | 13 +++ ...transient_function_type_state_variable.sol | 17 ++++ ...ansient_state_address_variable_members.sol | 21 +++++ .../transient_state_enum_variable.sol | 18 ++++ .../variables/transient_state_variable.sol | 22 +++++ ...ient_state_variable_cleanup_assignment.sol | 17 ++++ ...ransient_state_variable_cleanup_tstore.sol | 15 ++++ ...nt_state_variable_slot_inline_assembly.sol | 32 +++++++ ...nsient_state_variable_tuple_assignment.sol | 21 +++++ .../transient_state_variable_udvt.sol | 23 +++++ .../transient_storage_reentrancy_lock.sol | 24 ++++++ .../constant_transient_state_variable.sol | 2 + ...transient_dynamic_array_state_variable.sol | 2 + .../transient_fixed_array_state_variable.sol | 2 + .../dataLocations/transient_function_type.sol | 3 +- .../transient_mapping_state_variable.sol | 3 +- .../transient_state_variable_visibility.sol | 3 +- .../transient_storage_variable_pre_cancun.sol | 7 ++ .../transient_struct_state_variable.sol | 2 + .../transient_value_type_state_variables.sol | 3 +- ...ue_type_state_variables_initialization.sol | 2 + .../state_var_transient_data_location.sol | 2 + .../invalid/constant_variable_via_offset.sol | 2 +- .../invalid/storage_assignment.sol | 2 +- .../storage_assignment_in_modifier.sol | 2 +- .../invalid/transient_storage_assignment.sol | 12 +++ .../invalid/unbalanced_two_stack_load.sol | 2 +- .../storage_reference_assignment_statevar.sol | 4 +- .../inlineAssembly/storage_reference_old.sol | 4 +- ...ient_storage_value_assignment_statevar.sol | 14 +++ ..._both_transient_storage_identical_name.sol | 8 ++ 64 files changed, 614 insertions(+), 73 deletions(-) create mode 100644 test/cmdlineTests/evmasm_transient_storage_inline_assembly/args rename test/cmdlineTests/{evmasm_transient_storage_opcodes => evmasm_transient_storage_inline_assembly}/err (90%) rename test/cmdlineTests/{evmasm_transient_storage_opcodes => evmasm_transient_storage_inline_assembly}/input.sol (100%) rename test/cmdlineTests/{evmasm_transient_storage_opcodes => evmasm_transient_storage_inline_assembly}/output (90%) delete mode 100644 test/cmdlineTests/evmasm_transient_storage_opcodes/args create mode 100644 test/cmdlineTests/evmasm_transient_storage_state_variable/args create mode 100644 test/cmdlineTests/evmasm_transient_storage_state_variable/input.sol create mode 100644 test/cmdlineTests/evmasm_transient_storage_state_variable/output create mode 100644 test/cmdlineTests/evmasm_transient_storage_state_variable_via_ir/args create mode 100644 test/cmdlineTests/evmasm_transient_storage_state_variable_via_ir/err create mode 100644 test/cmdlineTests/evmasm_transient_storage_state_variable_via_ir/exit create mode 100644 test/cmdlineTests/evmasm_transient_storage_state_variable_via_ir/input.sol create mode 100644 test/libsolidity/semanticTests/getters/transient_value_types.sol create mode 100644 test/libsolidity/semanticTests/getters/transient_value_types_multi_frame_call.sol create mode 100644 test/libsolidity/semanticTests/inlineAssembly/inline_assembly_transient_storage_access_inside_function.sol create mode 100644 test/libsolidity/semanticTests/operators/compound_assign_transient_storage.sol create mode 100644 test/libsolidity/semanticTests/operators/transient_storage_variable_increment_decrement.sol create mode 100644 test/libsolidity/semanticTests/variables/delete_transient_state_variable.sol create mode 100644 test/libsolidity/semanticTests/variables/transient_function_type_state_variable.sol create mode 100644 test/libsolidity/semanticTests/variables/transient_state_address_variable_members.sol create mode 100644 test/libsolidity/semanticTests/variables/transient_state_enum_variable.sol create mode 100644 test/libsolidity/semanticTests/variables/transient_state_variable.sol create mode 100644 test/libsolidity/semanticTests/variables/transient_state_variable_cleanup_assignment.sol create mode 100644 test/libsolidity/semanticTests/variables/transient_state_variable_cleanup_tstore.sol create mode 100644 test/libsolidity/semanticTests/variables/transient_state_variable_slot_inline_assembly.sol create mode 100644 test/libsolidity/semanticTests/variables/transient_state_variable_tuple_assignment.sol create mode 100644 test/libsolidity/semanticTests/variables/transient_state_variable_udvt.sol create mode 100644 test/libsolidity/semanticTests/various/transient_storage_reentrancy_lock.sol create mode 100644 test/libsolidity/syntaxTests/dataLocations/transient_storage_variable_pre_cancun.sol create mode 100644 test/libsolidity/syntaxTests/inlineAssembly/invalid/transient_storage_assignment.sol create mode 100644 test/libsolidity/syntaxTests/inlineAssembly/transient_storage_value_assignment_statevar.sol create mode 100644 test/libsolidity/syntaxTests/variableDeclaration/state_variables_both_transient_storage_identical_name.sol diff --git a/Changelog.md b/Changelog.md index f001a0efc62a..9f531daea171 100644 --- a/Changelog.md +++ b/Changelog.md @@ -4,6 +4,7 @@ Language Features: Compiler Features: + * Code Generator: Transient storage value type state variables are now supported by the legacy pipeline. Bugfixes: diff --git a/libsolidity/analysis/DeclarationTypeChecker.cpp b/libsolidity/analysis/DeclarationTypeChecker.cpp index f5db21100029..e5549f0350e5 100644 --- a/libsolidity/analysis/DeclarationTypeChecker.cpp +++ b/libsolidity/analysis/DeclarationTypeChecker.cpp @@ -398,6 +398,13 @@ void DeclarationTypeChecker::endVisit(VariableDeclaration const& _variable) Location varLoc = _variable.referenceLocation(); DataLocation typeLoc = DataLocation::Memory; + if (varLoc == VariableDeclaration::Location::Transient && !m_evmVersion.supportsTransientStorage()) + m_errorReporter.declarationError( + 7985_error, + _variable.location(), + "Transient storage is not supported by EVM versions older than cancun." + ); + std::set allowedDataLocations = _variable.allowedDataLocations(); if (!allowedDataLocations.count(varLoc)) { diff --git a/libsolidity/analysis/ReferencesResolver.cpp b/libsolidity/analysis/ReferencesResolver.cpp index 079bbf33ceab..cfbdec91ab52 100644 --- a/libsolidity/analysis/ReferencesResolver.cpp +++ b/libsolidity/analysis/ReferencesResolver.cpp @@ -370,7 +370,7 @@ void ReferencesResolver::operator()(yul::Identifier const& _identifier) m_errorReporter.declarationError( 9467_error, nativeLocationOf(_identifier), - "Identifier not found. Use \".slot\" and \".offset\" to access storage variables." + "Identifier not found. Use \".slot\" and \".offset\" to access storage or transient storage variables." ); return; } diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp index 3b7a314fe3ea..993541472637 100644 --- a/libsolidity/analysis/TypeChecker.cpp +++ b/libsolidity/analysis/TypeChecker.cpp @@ -785,7 +785,7 @@ bool TypeChecker::visit(InlineAssembly const& _inlineAssembly) } else if (identifierInfo.suffix == "slot" || identifierInfo.suffix == "offset") { - m_errorReporter.typeError(6617_error, nativeLocationOf(_identifier), "The suffixes .offset and .slot can only be used on non-constant storage variables."); + m_errorReporter.typeError(6617_error, nativeLocationOf(_identifier), "The suffixes .offset and .slot can only be used on non-constant storage or transient storage variables."); return false; } else if (var && var->value() && !var->value()->annotation().type && !dynamic_cast(var->value().get())) @@ -824,7 +824,7 @@ bool TypeChecker::visit(InlineAssembly const& _inlineAssembly) { if (var->isStateVariable()) { - m_errorReporter.typeError(4713_error, nativeLocationOf(_identifier), "State variables cannot be assigned to - you have to use \"sstore()\"."); + m_errorReporter.typeError(4713_error, nativeLocationOf(_identifier), "State variables cannot be assigned to - you have to use \"sstore()\" or \"tstore()\"."); return false; } else if (suffix != "slot") @@ -869,7 +869,7 @@ bool TypeChecker::visit(InlineAssembly const& _inlineAssembly) m_errorReporter.typeError( 1408_error, nativeLocationOf(_identifier), - "Only local variables are supported. To access storage variables, use the \".slot\" and \".offset\" suffixes." + "Only local variables are supported. To access state variables, use the \".slot\" and \".offset\" suffixes." ); return false; } diff --git a/libsolidity/ast/Types.cpp b/libsolidity/ast/Types.cpp index f6e2a54138b3..95f249516142 100644 --- a/libsolidity/ast/Types.cpp +++ b/libsolidity/ast/Types.cpp @@ -2140,30 +2140,25 @@ FunctionType const* ContractType::newExpressionType() const return m_constructorType; } -std::vector> ContractType::stateVariables(std::optional _location) const +std::vector> ContractType::stateVariables(DataLocation _location) const { - std::optional location; - if (_location.has_value()) + VariableDeclaration::Location location; + switch (_location) { - switch (_location.value()) - { - case DataLocation::Storage: - location = std::make_optional(VariableDeclaration::Location::Unspecified); // By default state variables have unspecified (storage) data location - break; - case DataLocation::Transient: - location = std::make_optional(VariableDeclaration::Location::Transient); - break; - default: solAssert(false); - } + case DataLocation::Storage: + location = VariableDeclaration::Location::Unspecified; + break; + case DataLocation::Transient: + location = VariableDeclaration::Location::Transient; + break; + default: + solAssert(false); } std::vector variables; for (ContractDefinition const* contract: m_contract.annotation().linearizedBaseContracts | ranges::views::reverse) for (VariableDeclaration const* variable: contract->stateVariables()) - if ( - !(variable->isConstant() || variable->immutable()) && - variable->referenceLocation() == location.value_or(variable->referenceLocation()) - ) + if (!(variable->isConstant() || variable->immutable()) && variable->referenceLocation() == location) variables.push_back(variable); TypePointers types; for (auto variable: variables) diff --git a/libsolidity/ast/Types.h b/libsolidity/ast/Types.h index 5a5040c40dd2..c642362029d9 100644 --- a/libsolidity/ast/Types.h +++ b/libsolidity/ast/Types.h @@ -1002,7 +1002,7 @@ class ContractType: public Type /// @returns a list of all state variables (including inherited) of the contract and their /// offsets in storage/transient storage. - std::vector> stateVariables(std::optional _location = std::nullopt) const; + std::vector> stateVariables(DataLocation _location) const; /// @returns a list of all immutable variables (including inherited) of the contract. std::vector immutableVariables() const; protected: diff --git a/libsolidity/codegen/Compiler.cpp b/libsolidity/codegen/Compiler.cpp index 07b65fcc8c53..3e3f1499694b 100644 --- a/libsolidity/codegen/Compiler.cpp +++ b/libsolidity/codegen/Compiler.cpp @@ -26,7 +26,7 @@ #include #include -#include +#include using namespace solidity; using namespace solidity::frontend; @@ -37,14 +37,16 @@ void Compiler::compileContract( bytes const& _metadata ) { - auto static notTransient = [](VariableDeclaration const* _varDeclaration) { - solAssert(_varDeclaration); - return _varDeclaration->referenceLocation() != VariableDeclaration::Location::Transient; + auto static isTransientReferenceType = [](VariableDeclaration const* _varDeclaration) { + solAssert(_varDeclaration && _varDeclaration->type()); + return + _varDeclaration->referenceLocation() == VariableDeclaration::Location::Transient && + !_varDeclaration->type()->isValueType(); }; solUnimplementedAssert( - ranges::all_of(_contract.stateVariables(), notTransient), - "Transient storage variables are not supported." + ranges::none_of(_contract.stateVariables(), isTransientReferenceType), + "Transient storage reference type variables are not supported." ); ContractCompiler runtimeCompiler(nullptr, m_runtimeContext, m_optimiserSettings); diff --git a/libsolidity/codegen/ContractCompiler.cpp b/libsolidity/codegen/ContractCompiler.cpp index 66cfe35c409a..5ed6e8f96418 100644 --- a/libsolidity/codegen/ContractCompiler.cpp +++ b/libsolidity/codegen/ContractCompiler.cpp @@ -570,8 +570,9 @@ void ContractCompiler::appendReturnValuePacker(TypePointers const& _typeParamete void ContractCompiler::registerStateVariables(ContractDefinition const& _contract) { - for (auto const& var: ContractType(_contract).stateVariables()) - m_context.addStateVariable(*std::get<0>(var), std::get<1>(var), std::get<2>(var)); + for (auto const location: {DataLocation::Storage, DataLocation::Transient}) + for (auto const& var: ContractType(_contract).stateVariables(location)) + m_context.addStateVariable(*std::get<0>(var), std::get<1>(var), std::get<2>(var)); } void ContractCompiler::registerImmutableVariables(ContractDefinition const& _contract) @@ -586,7 +587,7 @@ void ContractCompiler::initializeStateVariables(ContractDefinition const& _contr solAssert(!_contract.isLibrary(), "Tried to initialize state variables of library."); for (VariableDeclaration const* variable: _contract.stateVariables()) { - solUnimplementedAssert(variable->referenceLocation() != VariableDeclaration::Location::Transient, "Transient storage variables not supported."); + solAssert(variable->referenceLocation() != VariableDeclaration::Location::Transient || !variable->value()); if (variable->value() && !variable->isConstant()) ExpressionCompiler(m_context, m_optimiserSettings.runOrderLiterals).appendStateVariableInitialization(*variable); } @@ -595,7 +596,6 @@ void ContractCompiler::initializeStateVariables(ContractDefinition const& _contr bool ContractCompiler::visit(VariableDeclaration const& _variableDeclaration) { solAssert(_variableDeclaration.isStateVariable(), "Compiler visit to non-state variable declaration."); - solUnimplementedAssert(_variableDeclaration.referenceLocation() != VariableDeclaration::Location::Transient, "Transient storage variables not supported."); CompilerContext::LocationSetter locationSetter(m_context, _variableDeclaration); m_context.startFunction(_variableDeclaration); diff --git a/libsolidity/codegen/ExpressionCompiler.cpp b/libsolidity/codegen/ExpressionCompiler.cpp index 95b7435ed608..85634906e01f 100644 --- a/libsolidity/codegen/ExpressionCompiler.cpp +++ b/libsolidity/codegen/ExpressionCompiler.cpp @@ -108,7 +108,10 @@ void ExpressionCompiler::appendStateVariableInitialization(VariableDeclaration c if (_varDecl.immutable()) ImmutableItem(m_context, _varDecl).storeValue(*type, _varDecl.location(), true); else + { + solAssert(_varDecl.referenceLocation() != VariableDeclaration::Location::Transient); StorageItem(m_context, _varDecl).storeValue(*type, _varDecl.location(), true); + } } void ExpressionCompiler::appendConstStateVariableAccessor(VariableDeclaration const& _varDecl) @@ -147,6 +150,7 @@ void ExpressionCompiler::appendStateVariableAccessor(VariableDeclaration const& if (auto mappingType = dynamic_cast(returnType)) { solAssert(CompilerUtils::freeMemoryPointer >= 0x40, ""); + solAssert(_varDecl.referenceLocation() != VariableDeclaration::Location::Transient); // pop offset m_context << Instruction::POP; @@ -196,6 +200,8 @@ void ExpressionCompiler::appendStateVariableAccessor(VariableDeclaration const& } else if (auto arrayType = dynamic_cast(returnType)) { + solAssert(_varDecl.referenceLocation() != VariableDeclaration::Location::Transient); + // pop offset m_context << Instruction::POP; utils().copyToStackTop(static_cast(paramTypes.size() - i + 1), 1); @@ -229,6 +235,7 @@ void ExpressionCompiler::appendStateVariableAccessor(VariableDeclaration const& solAssert(returnTypes.size() >= 1, ""); if (StructType const* structType = dynamic_cast(returnType)) { + solAssert(_varDecl.referenceLocation() != VariableDeclaration::Location::Transient); solAssert(!_varDecl.immutable(), ""); // remove offset m_context << Instruction::POP; @@ -258,6 +265,8 @@ void ExpressionCompiler::appendStateVariableAccessor(VariableDeclaration const& solAssert(returnTypes.size() == 1, ""); if (_varDecl.immutable()) ImmutableItem(m_context, _varDecl).retrieveValue(SourceLocation()); + else if (_varDecl.referenceLocation() == VariableDeclaration::Location::Transient) + TransientStorageItem(m_context, *returnType).retrieveValue(SourceLocation(), true); else StorageItem(m_context, *returnType).retrieveValue(SourceLocation(), true); utils().convertType(*returnType, *returnTypes.front()); @@ -2995,7 +3004,12 @@ void ExpressionCompiler::setLValueFromDeclaration(Declaration const& _declaratio if (m_context.isLocalVariable(&_declaration)) setLValue(_expression, dynamic_cast(_declaration)); else if (m_context.isStateVariable(&_declaration)) - setLValue(_expression, dynamic_cast(_declaration)); + { + if (dynamic_cast(_declaration).referenceLocation() == VariableDeclaration::Location::Transient) + setLValue(_expression, dynamic_cast(_declaration)); + else + setLValue(_expression, dynamic_cast(_declaration)); + } else solAssert(false, "Identifier type not supported or identifier not found."); } diff --git a/libsolidity/codegen/LValue.cpp b/libsolidity/codegen/LValue.cpp index 4847cb09388c..78efb9f811f3 100644 --- a/libsolidity/codegen/LValue.cpp +++ b/libsolidity/codegen/LValue.cpp @@ -36,7 +36,6 @@ using namespace solidity::frontend; using namespace solidity::langutil; using namespace solidity::util; - StackVariable::StackVariable(CompilerContext& _compilerContext, VariableDeclaration const& _declaration): LValue(_compilerContext, _declaration.annotation().type), m_baseStackOffset(m_context.baseStackOffsetOfVariable(_declaration)), @@ -198,15 +197,17 @@ void ImmutableItem::setToZero(SourceLocation const&, bool _removeReference) cons m_context << Instruction::POP; } -StorageItem::StorageItem(CompilerContext& _compilerContext, VariableDeclaration const& _declaration): - StorageItem(_compilerContext, *_declaration.annotation().type) +template +GenericStorageItem::GenericStorageItem(CompilerContext& _compilerContext, VariableDeclaration const& _declaration): + GenericStorageItem(_compilerContext, *_declaration.annotation().type) { solAssert(!_declaration.immutable(), ""); auto const& location = m_context.storageLocationOfVariable(_declaration); m_context << location.first << u256(location.second); } -StorageItem::StorageItem(CompilerContext& _compilerContext, Type const& _type): +template +GenericStorageItem::GenericStorageItem(CompilerContext& _compilerContext, Type const& _type): LValue(_compilerContext, &_type) { if (m_dataType->isValueType()) @@ -217,11 +218,13 @@ StorageItem::StorageItem(CompilerContext& _compilerContext, Type const& _type): } } -void StorageItem::retrieveValue(SourceLocation const&, bool _remove) const +template +void GenericStorageItem::retrieveValue(langutil::SourceLocation const&, bool _remove) const { // stack: storage_key storage_offset if (!m_dataType->isValueType()) { + solUnimplementedAssert(!IsTransient, "Transient storage reference types are not supported yet."); solAssert(m_dataType->sizeOnStack() == 1, "Invalid storage ref size."); if (_remove) m_context << Instruction::POP; // remove byte offset @@ -232,7 +235,7 @@ void StorageItem::retrieveValue(SourceLocation const&, bool _remove) const if (!_remove) CompilerUtils(m_context).copyToStackTop(sizeOnStack(), sizeOnStack()); if (m_dataType->storageBytes() == 32) - m_context << Instruction::POP << Instruction::SLOAD; + m_context << Instruction::POP << s_loadInstruction; else { Type const* type = m_dataType; @@ -240,12 +243,12 @@ void StorageItem::retrieveValue(SourceLocation const&, bool _remove) const type = type->encodingType(); bool cleaned = false; m_context - << Instruction::SWAP1 << Instruction::SLOAD << Instruction::SWAP1 + << Instruction::SWAP1 << s_loadInstruction << Instruction::SWAP1 << u256(0x100) << Instruction::EXP << Instruction::SWAP1 << Instruction::DIV; if (type->category() == Type::Category::FixedPoint) // implementation should be very similar to the integer case. solUnimplemented("Not yet implemented - FixedPointType."); - else if (FunctionType const* fun = dynamic_cast(type)) + else if (auto const* fun = dynamic_cast(type)) { if (fun->kind() == FunctionType::Kind::External) { @@ -281,7 +284,8 @@ void StorageItem::retrieveValue(SourceLocation const&, bool _remove) const } } -void StorageItem::storeValue(Type const& _sourceType, SourceLocation const& _location, bool _move) const +template +void GenericStorageItem::storeValue(Type const& _sourceType, langutil::SourceLocation const& _location, bool _move) const { CompilerUtils utils(m_context); solAssert(m_dataType, ""); @@ -303,7 +307,7 @@ void StorageItem::storeValue(Type const& _sourceType, SourceLocation const& _loc utils.convertType(_sourceType, *m_dataType, true); m_context << Instruction::SWAP1; - m_context << Instruction::SSTORE; + m_context << s_storeInstruction; } else { @@ -311,7 +315,7 @@ void StorageItem::storeValue(Type const& _sourceType, SourceLocation const& _loc m_context << u256(0x100) << Instruction::EXP; // stack: value storage_ref multiplier // fetch old value - m_context << Instruction::DUP2 << Instruction::SLOAD; + m_context << Instruction::DUP2 << s_loadInstruction; // stack: value storage_ref multiplier old_full_value // clear bytes in old value m_context @@ -358,13 +362,14 @@ void StorageItem::storeValue(Type const& _sourceType, SourceLocation const& _loc } m_context << Instruction::MUL << Instruction::OR; // stack: value storage_ref updated_value - m_context << Instruction::SWAP1 << Instruction::SSTORE; + m_context << Instruction::SWAP1 << s_storeInstruction; if (_move) utils.popStackElement(*m_dataType); } } else { + solUnimplementedAssert(!IsTransient, "Transient storage reference types are not supported yet."); solAssert( _sourceType.category() == m_dataType->category(), "Wrong type conversation for assignment." @@ -445,16 +450,19 @@ void StorageItem::storeValue(Type const& _sourceType, SourceLocation const& _loc } } -void StorageItem::setToZero(SourceLocation const&, bool _removeReference) const +template +void GenericStorageItem::setToZero(langutil::SourceLocation const&, bool _removeReference) const { if (m_dataType->category() == Type::Category::Array) { + solUnimplementedAssert(!IsTransient, "Transient storage reference types are not supported yet."); if (!_removeReference) CompilerUtils(m_context).copyToStackTop(sizeOnStack(), sizeOnStack()); ArrayUtils(m_context).clearArray(dynamic_cast(*m_dataType)); } else if (m_dataType->category() == Type::Category::Struct) { + solUnimplementedAssert(!IsTransient, "Transient storage reference types are not supported yet."); // stack layout: storage_key storage_offset // @todo this can be improved: use StorageItem for non-value types, and just store 0 in // all slots that contain value types later. @@ -484,14 +492,14 @@ void StorageItem::setToZero(SourceLocation const&, bool _removeReference) const // offset should be zero m_context << Instruction::POP << u256(0) - << Instruction::SWAP1 << Instruction::SSTORE; + << Instruction::SWAP1 << s_storeInstruction; } else { m_context << u256(0x100) << Instruction::EXP; // stack: storage_ref multiplier // fetch old value - m_context << Instruction::DUP2 << Instruction::SLOAD; + m_context << Instruction::DUP2 << s_loadInstruction; // stack: storage_ref multiplier old_full_value // clear bytes in old value m_context @@ -499,7 +507,7 @@ void StorageItem::setToZero(SourceLocation const&, bool _removeReference) const << Instruction::MUL; m_context << Instruction::NOT << Instruction::AND; // stack: storage_ref cleared_value - m_context << Instruction::SWAP1 << Instruction::SSTORE; + m_context << Instruction::SWAP1 << s_storeInstruction; } } } @@ -610,3 +618,6 @@ void TupleObject::setToZero(SourceLocation const&, bool) const { solAssert(false, "Tried to delete tuple."); } + +template class solidity::frontend::GenericStorageItem; +template class solidity::frontend::GenericStorageItem; diff --git a/libsolidity/codegen/LValue.h b/libsolidity/codegen/LValue.h index 9bf0d1c05c0c..430419727be6 100644 --- a/libsolidity/codegen/LValue.h +++ b/libsolidity/codegen/LValue.h @@ -26,6 +26,7 @@ #include #include #include +#include #include #include @@ -149,17 +150,18 @@ class ImmutableItem: public LValue }; /** - * Reference to some item in storage. On the stack this is , + * Reference to some item in storage/transient storage. On the stack this is , * where 0 <= offset_inside_value < 32 and an offset of i means that the value is multiplied * by 2**i before storing it. */ -class StorageItem: public LValue +template +class GenericStorageItem : public LValue { public: /// Constructs the LValue and pushes the location of @a _declaration onto the stack. - StorageItem(CompilerContext& _compilerContext, VariableDeclaration const& _declaration); + GenericStorageItem(CompilerContext& _compilerContext, VariableDeclaration const& _declaration); /// Constructs the LValue and assumes that the storage reference is already on the stack. - StorageItem(CompilerContext& _compilerContext, Type const& _type); + GenericStorageItem(CompilerContext& _compilerContext, Type const& _type); unsigned sizeOnStack() const override { return 2; } void retrieveValue(langutil::SourceLocation const& _location, bool _remove = false) const override; void storeValue( @@ -171,7 +173,14 @@ class StorageItem: public LValue langutil::SourceLocation const& _location = {}, bool _removeReference = true ) const override; +private: + static constexpr evmasm::Instruction s_storeInstruction = IsTransient ? evmasm::Instruction::TSTORE : evmasm::Instruction::SSTORE; + static constexpr evmasm::Instruction s_loadInstruction = IsTransient ? evmasm::Instruction::TLOAD : evmasm::Instruction::SLOAD; }; +extern template class GenericStorageItem; +extern template class GenericStorageItem; +using StorageItem = GenericStorageItem; +using TransientStorageItem = GenericStorageItem; /** * Reference to a single byte inside a storage byte array. diff --git a/libsolidity/codegen/ir/IRGenerator.cpp b/libsolidity/codegen/ir/IRGenerator.cpp index 00c9fa196bd8..f495d97abdfa 100644 --- a/libsolidity/codegen/ir/IRGenerator.cpp +++ b/libsolidity/codegen/ir/IRGenerator.cpp @@ -110,7 +110,7 @@ std::string IRGenerator::generate( solUnimplementedAssert( ranges::all_of(_contract.stateVariables(), notTransient), - "Transient storage variables are not supported." + "Transient storage variables are not supported when compiling via IR." ); auto subObjectSources = [&_otherYulSources](UniqueVector const& _subObjects) -> std::string @@ -1115,8 +1115,9 @@ void IRGenerator::resetContext(ContractDefinition const& _contract, ExecutionCon m_context = std::move(newContext); m_context.setMostDerivedContract(_contract); - for (auto const& var: ContractType(_contract).stateVariables()) - m_context.addStateVariable(*std::get<0>(var), std::get<1>(var), std::get<2>(var)); + for (auto const location: {DataLocation::Storage, DataLocation::Transient}) + for (auto const& var: ContractType(_contract).stateVariables(location)) + m_context.addStateVariable(*std::get<0>(var), std::get<1>(var), std::get<2>(var)); } std::string IRGenerator::dispenseLocationComment(ASTNode const& _node) diff --git a/test/cmdlineTests/evmasm_transient_storage_inline_assembly/args b/test/cmdlineTests/evmasm_transient_storage_inline_assembly/args new file mode 100644 index 000000000000..8430fd558f6d --- /dev/null +++ b/test/cmdlineTests/evmasm_transient_storage_inline_assembly/args @@ -0,0 +1 @@ +--no-cbor-metadata --via-ir --optimize --opcodes --asm --debug-info none diff --git a/test/cmdlineTests/evmasm_transient_storage_opcodes/err b/test/cmdlineTests/evmasm_transient_storage_inline_assembly/err similarity index 90% rename from test/cmdlineTests/evmasm_transient_storage_opcodes/err rename to test/cmdlineTests/evmasm_transient_storage_inline_assembly/err index a6cd56261e05..5071bc457b7c 100644 --- a/test/cmdlineTests/evmasm_transient_storage_opcodes/err +++ b/test/cmdlineTests/evmasm_transient_storage_inline_assembly/err @@ -1,5 +1,5 @@ Warning: Transient storage as defined by EIP-1153 can break the composability of smart contracts: Since transient storage is cleared only at the end of the transaction and not at the end of the outermost call frame to the contract within a transaction, your contract may unintentionally misbehave when invoked multiple times in a complex transaction. To avoid this, be sure to clear all transient storage at the end of any call to your contract. The use of transient storage for reentrancy guards that are cleared at the end of the call is safe. - --> evmasm_transient_storage_opcodes/input.sol:7:13: + --> evmasm_transient_storage_inline_assembly/input.sol:7:13: | 7 | tstore(0, 0) | ^^^^^^ diff --git a/test/cmdlineTests/evmasm_transient_storage_opcodes/input.sol b/test/cmdlineTests/evmasm_transient_storage_inline_assembly/input.sol similarity index 100% rename from test/cmdlineTests/evmasm_transient_storage_opcodes/input.sol rename to test/cmdlineTests/evmasm_transient_storage_inline_assembly/input.sol diff --git a/test/cmdlineTests/evmasm_transient_storage_opcodes/output b/test/cmdlineTests/evmasm_transient_storage_inline_assembly/output similarity index 90% rename from test/cmdlineTests/evmasm_transient_storage_opcodes/output rename to test/cmdlineTests/evmasm_transient_storage_inline_assembly/output index 3d1eddc9ad02..56dea1afb4c4 100644 --- a/test/cmdlineTests/evmasm_transient_storage_opcodes/output +++ b/test/cmdlineTests/evmasm_transient_storage_inline_assembly/output @@ -1,5 +1,5 @@ -======= evmasm_transient_storage_opcodes/input.sol:C ======= +======= evmasm_transient_storage_inline_assembly/input.sol:C ======= EVM assembly: 0x80 dup1 diff --git a/test/cmdlineTests/evmasm_transient_storage_opcodes/args b/test/cmdlineTests/evmasm_transient_storage_opcodes/args deleted file mode 100644 index 552cea1ca144..000000000000 --- a/test/cmdlineTests/evmasm_transient_storage_opcodes/args +++ /dev/null @@ -1 +0,0 @@ ---evm-version cancun --no-cbor-metadata --via-ir --optimize --opcodes --asm --debug-info none diff --git a/test/cmdlineTests/evmasm_transient_storage_state_variable/args b/test/cmdlineTests/evmasm_transient_storage_state_variable/args new file mode 100644 index 000000000000..0df1b673eb53 --- /dev/null +++ b/test/cmdlineTests/evmasm_transient_storage_state_variable/args @@ -0,0 +1 @@ +--no-cbor-metadata --optimize --asm --debug-info none diff --git a/test/cmdlineTests/evmasm_transient_storage_state_variable/input.sol b/test/cmdlineTests/evmasm_transient_storage_state_variable/input.sol new file mode 100644 index 000000000000..7177bdb64fd5 --- /dev/null +++ b/test/cmdlineTests/evmasm_transient_storage_state_variable/input.sol @@ -0,0 +1,9 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity >=0.0.0; + +contract C { + uint transient x; + function f() public { + x = x + 1; + } +} diff --git a/test/cmdlineTests/evmasm_transient_storage_state_variable/output b/test/cmdlineTests/evmasm_transient_storage_state_variable/output new file mode 100644 index 000000000000..e80eb3c57fc7 --- /dev/null +++ b/test/cmdlineTests/evmasm_transient_storage_state_variable/output @@ -0,0 +1,86 @@ + +======= evmasm_transient_storage_state_variable/input.sol:C ======= +EVM assembly: + mstore(0x40, 0x80) + callvalue + dup1 + iszero + tag_1 + jumpi + revert(0x00, 0x00) +tag_1: + pop + dataSize(sub_0) + dup1 + dataOffset(sub_0) + 0x00 + codecopy + 0x00 + return +stop + +sub_0: assembly { + mstore(0x40, 0x80) + callvalue + dup1 + iszero + tag_1 + jumpi + revert(0x00, 0x00) + tag_1: + pop + jumpi(tag_2, lt(calldatasize, 0x04)) + shr(0xe0, calldataload(0x00)) + dup1 + 0x26121ff0 + eq + tag_3 + jumpi + tag_2: + revert(0x00, 0x00) + tag_3: + tag_4 + tag_5 + jump // in + tag_4: + stop + tag_5: + tag_7 + tload(0x00) + 0x01 + tag_8 + jump // in + tag_7: + dup1 + 0x00 + tstore + pop + jump // out + tag_8: + dup1 + dup3 + add + dup1 + dup3 + gt + iszero + tag_11 + jumpi + 0x4e487b71 + 0xe0 + shl + 0x00 + mstore + 0x11 + 0x04 + mstore + 0x24 + 0x00 + revert + tag_11: + swap3 + swap2 + pop + pop + jump // out +} diff --git a/test/cmdlineTests/evmasm_transient_storage_state_variable_via_ir/args b/test/cmdlineTests/evmasm_transient_storage_state_variable_via_ir/args new file mode 100644 index 000000000000..00dcc37773e8 --- /dev/null +++ b/test/cmdlineTests/evmasm_transient_storage_state_variable_via_ir/args @@ -0,0 +1 @@ +--no-cbor-metadata --ir-optimized --debug-info none \ No newline at end of file diff --git a/test/cmdlineTests/evmasm_transient_storage_state_variable_via_ir/err b/test/cmdlineTests/evmasm_transient_storage_state_variable_via_ir/err new file mode 100644 index 000000000000..2f81d6cd3d7f --- /dev/null +++ b/test/cmdlineTests/evmasm_transient_storage_state_variable_via_ir/err @@ -0,0 +1 @@ +Error: Transient storage variables are not supported when compiling via IR. diff --git a/test/cmdlineTests/evmasm_transient_storage_state_variable_via_ir/exit b/test/cmdlineTests/evmasm_transient_storage_state_variable_via_ir/exit new file mode 100644 index 000000000000..d00491fd7e5b --- /dev/null +++ b/test/cmdlineTests/evmasm_transient_storage_state_variable_via_ir/exit @@ -0,0 +1 @@ +1 diff --git a/test/cmdlineTests/evmasm_transient_storage_state_variable_via_ir/input.sol b/test/cmdlineTests/evmasm_transient_storage_state_variable_via_ir/input.sol new file mode 100644 index 000000000000..7177bdb64fd5 --- /dev/null +++ b/test/cmdlineTests/evmasm_transient_storage_state_variable_via_ir/input.sol @@ -0,0 +1,9 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity >=0.0.0; + +contract C { + uint transient x; + function f() public { + x = x + 1; + } +} diff --git a/test/libsolidity/ASTPropertyTest.cpp b/test/libsolidity/ASTPropertyTest.cpp index 05c9b8786db8..3419d51c577c 100644 --- a/test/libsolidity/ASTPropertyTest.cpp +++ b/test/libsolidity/ASTPropertyTest.cpp @@ -43,7 +43,7 @@ using namespace solidity; using namespace std::string_literals; ASTPropertyTest::ASTPropertyTest(std::string const& _filename): - TestCase(_filename) + EVMVersionRestrictedTestCase(_filename) { if (!boost::algorithm::ends_with(_filename, ".sol")) BOOST_THROW_EXCEPTION(std::runtime_error("Not a Solidity file: \"" + _filename + "\".")); diff --git a/test/libsolidity/ASTPropertyTest.h b/test/libsolidity/ASTPropertyTest.h index 6130cedb299e..9d6414e775cb 100644 --- a/test/libsolidity/ASTPropertyTest.h +++ b/test/libsolidity/ASTPropertyTest.h @@ -35,7 +35,7 @@ namespace solidity::frontend::test using StringPair = std::pair; -class ASTPropertyTest: public TestCase +class ASTPropertyTest: public EVMVersionRestrictedTestCase { public: static std::unique_ptr create(Config const& _config) diff --git a/test/libsolidity/astPropertyTests/forLoop/isSimpleCounterLoop_negative_cases.sol b/test/libsolidity/astPropertyTests/forLoop/isSimpleCounterLoop_negative_cases.sol index cfdda3813c0f..57e160fcf97e 100644 --- a/test/libsolidity/astPropertyTests/forLoop/isSimpleCounterLoop_negative_cases.sol +++ b/test/libsolidity/astPropertyTests/forLoop/isSimpleCounterLoop_negative_cases.sol @@ -20,6 +20,7 @@ function h() pure returns (uint) { contract C { uint z = 0; + uint transient t; function modifyStateVarZ() public returns (uint) { z = type(uint).max; @@ -117,6 +118,12 @@ contract C { for (z = 1; z < 2048; ++z) { modifyStateVarZ(); } + /// StorageStateVarCounter: isSimpleCounterLoop + for (z = 1; z < 2048; ++z) { + } + /// TransientStateVarCounter: isSimpleCounterLoop + for (t = 1; t < 2048; ++t) { + } /// NonIntegerCounter: isSimpleCounterLoop for (address i = address(0x123); i < address(this); i = address(0x123 + 1)) { } @@ -135,6 +142,8 @@ contract C { } } } +// ==== +// EVMVersion: >=cancun // ---- // AdditionLoopExpression: false // ShortHandAdditionLoopExpression: false @@ -160,6 +169,8 @@ contract C { // LiteralDifferentCommonTypeConditionRHS: false // StateVarCounterModifiedFunctionConditionRHS: false // StateVarCounterModifiedFunctionLoopBody: false +// StorageStateVarCounter: false +// TransientStateVarCounter: false // NonIntegerCounter: false // AssemblyAfterAssignmentToCounter: false // ExpressionIncrement: false diff --git a/test/libsolidity/astPropertyTests/transient_data_location.sol b/test/libsolidity/astPropertyTests/transient_data_location.sol index be220a366b0b..327564dab1d9 100644 --- a/test/libsolidity/astPropertyTests/transient_data_location.sol +++ b/test/libsolidity/astPropertyTests/transient_data_location.sol @@ -7,6 +7,8 @@ contract C { uint y; } +// ==== +// EVMVersion: >=cancun // ---- // TransientDataLocation: transient // TransientVarName: x diff --git a/test/libsolidity/semanticTests/getters/transient_value_types.sol b/test/libsolidity/semanticTests/getters/transient_value_types.sol new file mode 100644 index 000000000000..cc345cb91238 --- /dev/null +++ b/test/libsolidity/semanticTests/getters/transient_value_types.sol @@ -0,0 +1,15 @@ +contract C { + int8 public transient x; + + function f() public returns(int8) { + x = -1; + return this.x(); + } +} +// ==== +// EVMVersion: >=cancun +// compileViaYul: false +// ---- +// x() -> 0 +// f() -> -1 +// x() -> 0 diff --git a/test/libsolidity/semanticTests/getters/transient_value_types_multi_frame_call.sol b/test/libsolidity/semanticTests/getters/transient_value_types_multi_frame_call.sol new file mode 100644 index 000000000000..5e6b3f054313 --- /dev/null +++ b/test/libsolidity/semanticTests/getters/transient_value_types_multi_frame_call.sol @@ -0,0 +1,23 @@ +contract C { + int8 public transient x; + + function f() public returns(int8) { + x = -1; + return this.h(); + } + function g() public { + x = x - 1; + } + function h() public returns(int8) { + this.g(); + return this.x(); + } +} +// ==== +// EVMVersion: >=cancun +// compileViaYul: false +// ---- +// x() -> 0 +// f() -> -2 +// h() -> -1 +// x() -> 0 diff --git a/test/libsolidity/semanticTests/inlineAssembly/inline_assembly_transient_storage_access_inside_function.sol b/test/libsolidity/semanticTests/inlineAssembly/inline_assembly_transient_storage_access_inside_function.sol new file mode 100644 index 000000000000..86463473bd26 --- /dev/null +++ b/test/libsolidity/semanticTests/inlineAssembly/inline_assembly_transient_storage_access_inside_function.sol @@ -0,0 +1,23 @@ +contract C { + uint16 transient x; + uint16 public transient y; + uint256 public transient z; + + function f() public returns (uint256) { + uint256 offset; + assembly { + function f() -> o1 { + tstore(z.slot, 7) + o1 := y.offset + } + offset := f() + } + assert(offset == 2); + return z; + } +} +// ==== +// EVMVersion: >=cancun +// compileViaYul: false +// ---- +// f() -> 7 diff --git a/test/libsolidity/semanticTests/operators/compound_assign_transient_storage.sol b/test/libsolidity/semanticTests/operators/compound_assign_transient_storage.sol new file mode 100644 index 000000000000..a20c8403ef06 --- /dev/null +++ b/test/libsolidity/semanticTests/operators/compound_assign_transient_storage.sol @@ -0,0 +1,23 @@ +contract test { + uint value1; + uint transient value2; + function f(uint x, uint y) public returns (uint w) { + uint value3 = y; + value1 += x; + value3 *= x; + value2 += value3 + value1; + return value2 += 7; + } +} +// ==== +// EVMVersion: >=cancun +// compileViaYul: false +// ---- +// f(uint256,uint256): 0, 6 -> 7 +// f(uint256,uint256): 1, 3 -> 11 +// f(uint256,uint256): 2, 25 -> 0x3c +// f(uint256,uint256): 3, 69 -> 0xdc +// f(uint256,uint256): 4, 84 -> 353 +// f(uint256,uint256): 5, 2 -> 0x20 +// f(uint256,uint256): 6, 51 -> 334 +// f(uint256,uint256): 7, 48 -> 371 diff --git a/test/libsolidity/semanticTests/operators/transient_storage_variable_increment_decrement.sol b/test/libsolidity/semanticTests/operators/transient_storage_variable_increment_decrement.sol new file mode 100644 index 000000000000..ac32eee1cdc9 --- /dev/null +++ b/test/libsolidity/semanticTests/operators/transient_storage_variable_increment_decrement.sol @@ -0,0 +1,16 @@ +contract C { + int transient x; + function f() public returns (int) { + ++x; + ++x; + --x; + x++; + x--; + return x; + } +} +// ==== +// EVMVersion: >=cancun +// compileViaYul: false +// ---- +// f() -> 1 diff --git a/test/libsolidity/semanticTests/variables/delete_transient_state_variable.sol b/test/libsolidity/semanticTests/variables/delete_transient_state_variable.sol new file mode 100644 index 000000000000..5f584fc8985b --- /dev/null +++ b/test/libsolidity/semanticTests/variables/delete_transient_state_variable.sol @@ -0,0 +1,13 @@ +contract C { + uint transient x; + function f() public returns (uint) { + x = 10; + delete x; + return x; + } +} +// ==== +// EVMVersion: >=cancun +// compileViaYul: false +// ---- +// f() -> 0 diff --git a/test/libsolidity/semanticTests/variables/transient_function_type_state_variable.sol b/test/libsolidity/semanticTests/variables/transient_function_type_state_variable.sol new file mode 100644 index 000000000000..56a69649eeb0 --- /dev/null +++ b/test/libsolidity/semanticTests/variables/transient_function_type_state_variable.sol @@ -0,0 +1,17 @@ +contract C { + function () external transient f; + function g() external { + } + + function test() public returns (bool) { + assert(f != this.g); + f = this.g; + + return f == this.g; + } +} +// ==== +// EVMVersion: >=cancun +// compileViaYul: false +// ---- +// test() -> true diff --git a/test/libsolidity/semanticTests/variables/transient_state_address_variable_members.sol b/test/libsolidity/semanticTests/variables/transient_state_address_variable_members.sol new file mode 100644 index 000000000000..6a388b3ee108 --- /dev/null +++ b/test/libsolidity/semanticTests/variables/transient_state_address_variable_members.sol @@ -0,0 +1,21 @@ +contract C { + address transient a; + function f() public returns (uint) { + a = msg.sender; + return a.balance; + } + function g() public returns (uint) { + return a.balance; + } +} +// ==== +// EVMVersion: >=cancun +// compileViaYul: false +// ---- +// constructor() -> +// gas legacy: 59027 +// gas legacy code: 70400 +// account: 0 -> 0x1212121212121212121212121212120000000012 +// balance: 0x1212121212121212121212121212120000000012 -> 1267650600228229401496703205376 +// f() -> 1267650600228229401496703205376 +// g() -> 0 \ No newline at end of file diff --git a/test/libsolidity/semanticTests/variables/transient_state_enum_variable.sol b/test/libsolidity/semanticTests/variables/transient_state_enum_variable.sol new file mode 100644 index 000000000000..a472212d401c --- /dev/null +++ b/test/libsolidity/semanticTests/variables/transient_state_enum_variable.sol @@ -0,0 +1,18 @@ +contract C { + enum Pets { Dog, Cat, Bird, Fish } + Pets transient myPet; + + function f() public { + myPet = Pets.Bird; + this.g(); + assert(myPet == Pets.Cat); + } + function g() public { + myPet = Pets.Cat; + } +} +// ==== +// EVMVersion: >=cancun +// compileViaYul: false +// ---- +// f() -> diff --git a/test/libsolidity/semanticTests/variables/transient_state_variable.sol b/test/libsolidity/semanticTests/variables/transient_state_variable.sol new file mode 100644 index 000000000000..71ed212d0bf4 --- /dev/null +++ b/test/libsolidity/semanticTests/variables/transient_state_variable.sol @@ -0,0 +1,22 @@ +contract C { + uint transient public x; + + function f() public { + x = 8; + } + function g() public returns (uint) { + x = 0; + this.f(); + return x; + } + function h() public returns (uint) { + return x; + } +} +// ==== +// EVMVersion: >=cancun +// compileViaYul: false +// ---- +// x() -> 0 +// g() -> 8 +// h() -> 0 diff --git a/test/libsolidity/semanticTests/variables/transient_state_variable_cleanup_assignment.sol b/test/libsolidity/semanticTests/variables/transient_state_variable_cleanup_assignment.sol new file mode 100644 index 000000000000..d1f0cc579713 --- /dev/null +++ b/test/libsolidity/semanticTests/variables/transient_state_variable_cleanup_assignment.sol @@ -0,0 +1,17 @@ +contract C { + uint8 transient x; + function f() public returns(uint256 r) { + uint8 y; + assembly { y := 0xFFFF } + x = y; + assembly { + r := tload(x.slot) + } + + } +} +// ==== +// EVMVersion: >=cancun +// compileViaYul: false +// ---- +// f() -> 0xff diff --git a/test/libsolidity/semanticTests/variables/transient_state_variable_cleanup_tstore.sol b/test/libsolidity/semanticTests/variables/transient_state_variable_cleanup_tstore.sol new file mode 100644 index 000000000000..425be55009bc --- /dev/null +++ b/test/libsolidity/semanticTests/variables/transient_state_variable_cleanup_tstore.sol @@ -0,0 +1,15 @@ +contract C { + uint8 transient x; + function f() public returns(uint256 r) { + assembly { + tstore(x.slot, 0xFFFF) + } + return x; + + } +} +// ==== +// EVMVersion: >=cancun +// compileViaYul: false +// ---- +// f() -> 0xff diff --git a/test/libsolidity/semanticTests/variables/transient_state_variable_slot_inline_assembly.sol b/test/libsolidity/semanticTests/variables/transient_state_variable_slot_inline_assembly.sol new file mode 100644 index 000000000000..6cf05068e3c3 --- /dev/null +++ b/test/libsolidity/semanticTests/variables/transient_state_variable_slot_inline_assembly.sol @@ -0,0 +1,32 @@ +contract C { + uint256 y; + uint256 transient x; + int8 transient w; + int z; + address transient a; + function f() public returns(uint256 s, uint256 o) { + assembly { + s := x.slot + o := x.offset + } + } + function g() public returns(uint256 s, uint256 o) { + assembly { + s := w.slot + o := w.offset + } + } + function h() public returns(uint256 s, uint256 o) { + assembly { + s := a.slot + o := a.offset + } + } +} +// ==== +// EVMVersion: >=cancun +// compileViaYul: false +// ---- +// f() -> 0, 0 +// g() -> 1, 0 +// h() -> 1, 1 diff --git a/test/libsolidity/semanticTests/variables/transient_state_variable_tuple_assignment.sol b/test/libsolidity/semanticTests/variables/transient_state_variable_tuple_assignment.sol new file mode 100644 index 000000000000..1b5180635ce9 --- /dev/null +++ b/test/libsolidity/semanticTests/variables/transient_state_variable_tuple_assignment.sol @@ -0,0 +1,21 @@ +contract C { + uint transient x; + uint y; + uint transient w; + uint z; + + function f() public returns (uint, uint, uint) { + x = 1; + y = 2; + w = 3; + z = 4; + + (x, y, w) = (y, w, z); + return (x, y, w); + } +} +// ==== +// EVMVersion: >=cancun +// compileViaYul: false +// ---- +// f() -> 2, 3, 4 diff --git a/test/libsolidity/semanticTests/variables/transient_state_variable_udvt.sol b/test/libsolidity/semanticTests/variables/transient_state_variable_udvt.sol new file mode 100644 index 000000000000..2f49a32b04b7 --- /dev/null +++ b/test/libsolidity/semanticTests/variables/transient_state_variable_udvt.sol @@ -0,0 +1,23 @@ +type MyInt is int256; +contract C { + MyInt transient public x; + + function f() public { + x = MyInt.wrap(2); + } + function g() public returns (MyInt) { + x = MyInt.wrap(0); + this.f(); + return x; + } + function h() public returns (MyInt) { + return x; + } +} +// ==== +// EVMVersion: >=cancun +// compileViaYul: false +// ---- +// x() -> 0 +// g() -> 2 +// h() -> 0 diff --git a/test/libsolidity/semanticTests/various/transient_storage_reentrancy_lock.sol b/test/libsolidity/semanticTests/various/transient_storage_reentrancy_lock.sol new file mode 100644 index 000000000000..aa3828601524 --- /dev/null +++ b/test/libsolidity/semanticTests/various/transient_storage_reentrancy_lock.sol @@ -0,0 +1,24 @@ +contract C { + bool transient locked; + modifier nonReentrant { + require(!locked, "Reentrancy attempt"); + locked = true; + _; + locked = false; + } + + function test(address newAddress, bool reentrancy) nonReentrant public { + if (reentrancy) + reentrantCall(newAddress); + } + + function reentrantCall(address a) public { + this.test(a, false); + } +} +// ==== +// EVMVersion: >=cancun +// compileViaYul: false +// ---- +// test(address,bool): 0x1234abcd, true -> FAILURE, hex"08c379a0", 0x20, 0x12, "Reentrancy attempt" +// test(address,bool): 0x1234abcd, false -> diff --git a/test/libsolidity/syntaxTests/constants/constant_transient_state_variable.sol b/test/libsolidity/syntaxTests/constants/constant_transient_state_variable.sol index 15913360c38b..f30494286f60 100644 --- a/test/libsolidity/syntaxTests/constants/constant_transient_state_variable.sol +++ b/test/libsolidity/syntaxTests/constants/constant_transient_state_variable.sol @@ -1,6 +1,8 @@ contract C { int constant public transient x = 0; } +// ==== +// EVMVersion: >=cancun // ---- // DeclarationError 2197: (17-52): Transient cannot be used as data location for constant or immutable variables. // DeclarationError 9825: (17-52): Initialization of transient storage state variables is not supported. diff --git a/test/libsolidity/syntaxTests/dataLocations/transient_dynamic_array_state_variable.sol b/test/libsolidity/syntaxTests/dataLocations/transient_dynamic_array_state_variable.sol index 7a3caa86e53b..b1b436732aef 100644 --- a/test/libsolidity/syntaxTests/dataLocations/transient_dynamic_array_state_variable.sol +++ b/test/libsolidity/syntaxTests/dataLocations/transient_dynamic_array_state_variable.sol @@ -1,5 +1,7 @@ contract C { uint[] transient x; } +// ==== +// EVMVersion: >=cancun // ---- // UnimplementedFeatureError 1834: Transient data location is only supported for value types. diff --git a/test/libsolidity/syntaxTests/dataLocations/transient_fixed_array_state_variable.sol b/test/libsolidity/syntaxTests/dataLocations/transient_fixed_array_state_variable.sol index 10b942e236e3..ca3898f29e7b 100644 --- a/test/libsolidity/syntaxTests/dataLocations/transient_fixed_array_state_variable.sol +++ b/test/libsolidity/syntaxTests/dataLocations/transient_fixed_array_state_variable.sol @@ -1,5 +1,7 @@ contract C { uint[3] transient x; } +// ==== +// EVMVersion: >=cancun // ---- // UnimplementedFeatureError 1834: Transient data location is only supported for value types. diff --git a/test/libsolidity/syntaxTests/dataLocations/transient_function_type.sol b/test/libsolidity/syntaxTests/dataLocations/transient_function_type.sol index 56456290881a..1d0ccf0c4063 100644 --- a/test/libsolidity/syntaxTests/dataLocations/transient_function_type.sol +++ b/test/libsolidity/syntaxTests/dataLocations/transient_function_type.sol @@ -6,5 +6,6 @@ contract C { function () internal transient internal fiti; function () internal internal transient fiit; } +// ==== +// EVMVersion: >=cancun // ---- -// UnimplementedFeatureError 1834: Transient storage variables are not supported. diff --git a/test/libsolidity/syntaxTests/dataLocations/transient_mapping_state_variable.sol b/test/libsolidity/syntaxTests/dataLocations/transient_mapping_state_variable.sol index 2a21b3e00a76..6c7822bf31fb 100644 --- a/test/libsolidity/syntaxTests/dataLocations/transient_mapping_state_variable.sol +++ b/test/libsolidity/syntaxTests/dataLocations/transient_mapping_state_variable.sol @@ -1,6 +1,7 @@ contract C { mapping(uint => uint) transient y; } - +// ==== +// EVMVersion: >=cancun // ---- // UnimplementedFeatureError 1834: Transient data location is only supported for value types. diff --git a/test/libsolidity/syntaxTests/dataLocations/transient_state_variable_visibility.sol b/test/libsolidity/syntaxTests/dataLocations/transient_state_variable_visibility.sol index f598fb72c823..45ad6e6c5eb8 100644 --- a/test/libsolidity/syntaxTests/dataLocations/transient_state_variable_visibility.sol +++ b/test/libsolidity/syntaxTests/dataLocations/transient_state_variable_visibility.sol @@ -7,5 +7,6 @@ contract C { uint transient internal ti; uint transient private tprv; } +// ==== +// EVMVersion: >=cancun // ---- -// UnimplementedFeatureError 1834: Transient storage variables are not supported. diff --git a/test/libsolidity/syntaxTests/dataLocations/transient_storage_variable_pre_cancun.sol b/test/libsolidity/syntaxTests/dataLocations/transient_storage_variable_pre_cancun.sol new file mode 100644 index 000000000000..8eb4dd565dff --- /dev/null +++ b/test/libsolidity/syntaxTests/dataLocations/transient_storage_variable_pre_cancun.sol @@ -0,0 +1,7 @@ +contract C { + uint transient x; +} +// ==== +// EVMVersion: =cancun // ---- // UnimplementedFeatureError 1834: Transient data location is only supported for value types. diff --git a/test/libsolidity/syntaxTests/dataLocations/transient_value_type_state_variables.sol b/test/libsolidity/syntaxTests/dataLocations/transient_value_type_state_variables.sol index d2eac46f7ba9..65188a900602 100644 --- a/test/libsolidity/syntaxTests/dataLocations/transient_value_type_state_variables.sol +++ b/test/libsolidity/syntaxTests/dataLocations/transient_value_type_state_variables.sol @@ -7,5 +7,6 @@ contract C { uint transient x; bytes32 transient y; } +// ==== +// EVMVersion: >=cancun // ---- -// UnimplementedFeatureError 1834: Transient storage variables are not supported. diff --git a/test/libsolidity/syntaxTests/dataLocations/transient_value_type_state_variables_initialization.sol b/test/libsolidity/syntaxTests/dataLocations/transient_value_type_state_variables_initialization.sol index 570642485ea8..080ca89ccd1a 100644 --- a/test/libsolidity/syntaxTests/dataLocations/transient_value_type_state_variables_initialization.sol +++ b/test/libsolidity/syntaxTests/dataLocations/transient_value_type_state_variables_initialization.sol @@ -5,6 +5,8 @@ contract C { address transient a = address(0xABC); bool transient b = x > 0 ? false : true; } +// ==== +// EVMVersion: >=cancun // ---- // DeclarationError 9825: (30-51): Initialization of transient storage state variables is not supported. // DeclarationError 9825: (54-90): Initialization of transient storage state variables is not supported. diff --git a/test/libsolidity/syntaxTests/immutable/state_var_transient_data_location.sol b/test/libsolidity/syntaxTests/immutable/state_var_transient_data_location.sol index a3d93848d9a2..f4b7e078ead6 100644 --- a/test/libsolidity/syntaxTests/immutable/state_var_transient_data_location.sol +++ b/test/libsolidity/syntaxTests/immutable/state_var_transient_data_location.sol @@ -1,5 +1,7 @@ contract C { uint public immutable transient x; } +// ==== +// EVMVersion: >=cancun // ---- // DeclarationError 2197: (17-50): Transient cannot be used as data location for constant or immutable variables. diff --git a/test/libsolidity/syntaxTests/inlineAssembly/invalid/constant_variable_via_offset.sol b/test/libsolidity/syntaxTests/inlineAssembly/invalid/constant_variable_via_offset.sol index eab2d2b4ef2f..a6797e05a3c1 100644 --- a/test/libsolidity/syntaxTests/inlineAssembly/invalid/constant_variable_via_offset.sol +++ b/test/libsolidity/syntaxTests/inlineAssembly/invalid/constant_variable_via_offset.sol @@ -7,4 +7,4 @@ contract test { } } // ---- -// TypeError 6617: (112-120): The suffixes .offset and .slot can only be used on non-constant storage variables. +// TypeError 6617: (112-120): The suffixes .offset and .slot can only be used on non-constant storage or transient storage variables. diff --git a/test/libsolidity/syntaxTests/inlineAssembly/invalid/storage_assignment.sol b/test/libsolidity/syntaxTests/inlineAssembly/invalid/storage_assignment.sol index b01f1ee21fbe..bcc5eb87c734 100644 --- a/test/libsolidity/syntaxTests/inlineAssembly/invalid/storage_assignment.sol +++ b/test/libsolidity/syntaxTests/inlineAssembly/invalid/storage_assignment.sol @@ -7,4 +7,4 @@ contract test { } } // ---- -// TypeError 1408: (89-90): Only local variables are supported. To access storage variables, use the ".slot" and ".offset" suffixes. +// TypeError 1408: (89-90): Only local variables are supported. To access state variables, use the ".slot" and ".offset" suffixes. diff --git a/test/libsolidity/syntaxTests/inlineAssembly/invalid/storage_assignment_in_modifier.sol b/test/libsolidity/syntaxTests/inlineAssembly/invalid/storage_assignment_in_modifier.sol index 64cfc862362a..7c1265e974c6 100644 --- a/test/libsolidity/syntaxTests/inlineAssembly/invalid/storage_assignment_in_modifier.sol +++ b/test/libsolidity/syntaxTests/inlineAssembly/invalid/storage_assignment_in_modifier.sol @@ -10,4 +10,4 @@ contract test { } } // ---- -// TypeError 1408: (80-81): Only local variables are supported. To access storage variables, use the ".slot" and ".offset" suffixes. +// TypeError 1408: (80-81): Only local variables are supported. To access state variables, use the ".slot" and ".offset" suffixes. diff --git a/test/libsolidity/syntaxTests/inlineAssembly/invalid/transient_storage_assignment.sol b/test/libsolidity/syntaxTests/inlineAssembly/invalid/transient_storage_assignment.sol new file mode 100644 index 000000000000..4cab6ffa2a16 --- /dev/null +++ b/test/libsolidity/syntaxTests/inlineAssembly/invalid/transient_storage_assignment.sol @@ -0,0 +1,12 @@ +contract test { + uint transient x; + function f() public { + assembly { + x := 2 + } + } +} +// ==== +// EVMVersion: >=cancun +// ---- +// TypeError 1408: (95-96): Only local variables are supported. To access state variables, use the ".slot" and ".offset" suffixes. diff --git a/test/libsolidity/syntaxTests/inlineAssembly/invalid/unbalanced_two_stack_load.sol b/test/libsolidity/syntaxTests/inlineAssembly/invalid/unbalanced_two_stack_load.sol index b1f8ba435ec9..050716609121 100644 --- a/test/libsolidity/syntaxTests/inlineAssembly/invalid/unbalanced_two_stack_load.sol +++ b/test/libsolidity/syntaxTests/inlineAssembly/invalid/unbalanced_two_stack_load.sol @@ -5,4 +5,4 @@ contract c { } } // ---- -// TypeError 1408: (75-76): Only local variables are supported. To access storage variables, use the ".slot" and ".offset" suffixes. +// TypeError 1408: (75-76): Only local variables are supported. To access state variables, use the ".slot" and ".offset" suffixes. diff --git a/test/libsolidity/syntaxTests/inlineAssembly/storage_reference_assignment_statevar.sol b/test/libsolidity/syntaxTests/inlineAssembly/storage_reference_assignment_statevar.sol index f4ed7c378730..5fa0eedbb828 100644 --- a/test/libsolidity/syntaxTests/inlineAssembly/storage_reference_assignment_statevar.sol +++ b/test/libsolidity/syntaxTests/inlineAssembly/storage_reference_assignment_statevar.sol @@ -8,5 +8,5 @@ contract C { } } // ---- -// TypeError 4713: (84-90): State variables cannot be assigned to - you have to use "sstore()". -// TypeError 4713: (108-116): State variables cannot be assigned to - you have to use "sstore()". +// TypeError 4713: (84-90): State variables cannot be assigned to - you have to use "sstore()" or "tstore()". +// TypeError 4713: (108-116): State variables cannot be assigned to - you have to use "sstore()" or "tstore()". diff --git a/test/libsolidity/syntaxTests/inlineAssembly/storage_reference_old.sol b/test/libsolidity/syntaxTests/inlineAssembly/storage_reference_old.sol index d2ca4d7cbfb0..2876ac726e77 100644 --- a/test/libsolidity/syntaxTests/inlineAssembly/storage_reference_old.sol +++ b/test/libsolidity/syntaxTests/inlineAssembly/storage_reference_old.sol @@ -9,5 +9,5 @@ contract C { } } // ---- -// DeclarationError 9467: (118-124): Identifier not found. Use ".slot" and ".offset" to access storage variables. -// DeclarationError 9467: (142-150): Identifier not found. Use ".slot" and ".offset" to access storage variables. +// DeclarationError 9467: (118-124): Identifier not found. Use ".slot" and ".offset" to access storage or transient storage variables. +// DeclarationError 9467: (142-150): Identifier not found. Use ".slot" and ".offset" to access storage or transient storage variables. diff --git a/test/libsolidity/syntaxTests/inlineAssembly/transient_storage_value_assignment_statevar.sol b/test/libsolidity/syntaxTests/inlineAssembly/transient_storage_value_assignment_statevar.sol new file mode 100644 index 000000000000..704a771f7ecb --- /dev/null +++ b/test/libsolidity/syntaxTests/inlineAssembly/transient_storage_value_assignment_statevar.sol @@ -0,0 +1,14 @@ +contract C { + uint transient x; + fallback() external { + assembly { + x.slot := 1 + x.offset := 2 + } + } +} +// ==== +// EVMVersion: >=cancun +// ---- +// TypeError 4713: (92-98): State variables cannot be assigned to - you have to use "sstore()" or "tstore()". +// TypeError 4713: (116-124): State variables cannot be assigned to - you have to use "sstore()" or "tstore()". diff --git a/test/libsolidity/syntaxTests/variableDeclaration/state_variables_both_transient_storage_identical_name.sol b/test/libsolidity/syntaxTests/variableDeclaration/state_variables_both_transient_storage_identical_name.sol new file mode 100644 index 000000000000..d34c1153a615 --- /dev/null +++ b/test/libsolidity/syntaxTests/variableDeclaration/state_variables_both_transient_storage_identical_name.sol @@ -0,0 +1,8 @@ +contract C { + uint public x; + uint public transient x; +} +// ==== +// EVMVersion: >=cancun +// ---- +// DeclarationError 2333: (36-59): Identifier already declared. From 668adbeebd47c8ed581265419a72dceacaf256f0 Mon Sep 17 00:00:00 2001 From: Alexander Arlt Date: Mon, 9 Sep 2024 22:48:17 +0200 Subject: [PATCH 0417/1022] Remove STRICT_NLOHMANN_JSON_VERSION_CHECK leftover. --- CMakeLists.txt | 4 ---- 1 file changed, 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7770d29e633d..7c36ff73b436 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -73,10 +73,6 @@ if (PROFILE_OPTIMIZER_STEPS) add_definitions(-DPROFILE_OPTIMIZER_STEPS) endif() -if (STRICT_NLOHMANN_JSON_VERSION) - add_definitions(-DSTRICT_NLOHMANN_JSON_VERSION_CHECK) -endif() - # Figure out what compiler and system are we using include(EthCompilerSettings) From 16b244791392cb0ff9d8da19db0cf0d209cd498d Mon Sep 17 00:00:00 2001 From: Nikola Matic Date: Mon, 9 Sep 2024 16:20:50 +0200 Subject: [PATCH 0418/1022] Upgrade jobs to run on Ubuntu 2404 --- .circleci/config.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 8384f2eeac9e..68626408f222 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1293,7 +1293,7 @@ jobs: - matrix_notify_failure_unless_pr t_ubu_soltest_all: &t_ubu_soltest_all - <<: *base_ubuntu2204_large + <<: *base_ubuntu2404_large parallelism: 50 steps: - soltest_all @@ -1335,10 +1335,10 @@ jobs: - soltest t_ubu_clang_soltest: &t_ubu_clang_soltest - <<: *base_ubuntu2204_clang + <<: *base_ubuntu2404_clang parallelism: 20 environment: - <<: *base_ubuntu2204_clang_env + <<: *base_ubuntu2404_clang_env EVM: << pipeline.parameters.evm-version >> OPTIMIZE: 0 # The high parallelism in this job is causing the SMT tests to run out of memory, @@ -1353,7 +1353,7 @@ jobs: <<: *t_ubu_soltest_all t_ubu_cli: &t_ubu_cli - <<: *base_ubuntu2204_small + <<: *base_ubuntu2404_small parallelism: 8 # Should match number of tests in .circleci/parallel_cli_tests.py steps: - cmdline_tests From 1d58415f1ed8377404d6597621f1e364a3c5be4e Mon Sep 17 00:00:00 2001 From: rodiazet Date: Fri, 13 Sep 2024 10:11:11 +0200 Subject: [PATCH 0419/1022] Update `evmc to` `12.0.0` and `evmone` to `0.12.0` --- .circleci/config.yml | 12 ++-- .circleci/osx_install_dependencies.sh | 28 ++------ scripts/install_evmone.ps1 | 2 +- test/Common.h | 6 +- test/evmc/README.md | 2 +- test/evmc/bytes.hpp | 93 +++++++++++++++++++++++++++ test/evmc/evmc.h | 65 +++++++++++++------ test/evmc/evmc.hpp | 3 - test/evmc/helpers.h | 2 + test/evmc/hex.hpp | 8 +-- test/evmc/mocked_host.hpp | 5 +- 11 files changed, 160 insertions(+), 66 deletions(-) create mode 100644 test/evmc/bytes.hpp diff --git a/.circleci/config.yml b/.circleci/config.yml index 68626408f222..931ce476a347 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -9,16 +9,16 @@ version: 2.1 parameters: ubuntu-2004-docker-image: type: string - # solbuildpackpusher/solidity-buildpack-deps:ubuntu2004-24 - default: "solbuildpackpusher/solidity-buildpack-deps@sha256:b8b645fa7ab40d55f2d16eac295d16ca01ec51d32be7d668ae6eaecd47dbd763" + # solbuildpackpusher/solidity-buildpack-deps:ubuntu2004-25 + default: "solbuildpackpusher/solidity-buildpack-deps@sha256:b3f321fb2d8e7a41ca9328672061c1840e5cd3fb5be503aa158d1c508deacf0a" ubuntu-2204-docker-image: type: string - # solbuildpackpusher/solidity-buildpack-deps:ubuntu2204-9 - default: "solbuildpackpusher/solidity-buildpack-deps@sha256:80247de9655b1f39afd4ac22b14266bc9b9a0d64b283ae8fb9cb5b8250e4e77d" + # solbuildpackpusher/solidity-buildpack-deps:ubuntu2204-10 + default: "solbuildpackpusher/solidity-buildpack-deps@sha256:ba2d878c26d681a7d6c1922258b47c2e5dd61d0e46ab4c6a4862b473e61997b6" ubuntu-2204-clang-docker-image: type: string - # solbuildpackpusher/solidity-buildpack-deps:ubuntu2204.clang-8 - default: "solbuildpackpusher/solidity-buildpack-deps@sha256:2662376fe0e1ec2d346495a19a6d64508c1048d5a7325d8600c33c343fa64a0f" + # solbuildpackpusher/solidity-buildpack-deps:ubuntu2204.clang-9 + default: "solbuildpackpusher/solidity-buildpack-deps@sha256:703cdad5fa5c8686a3080ebb1aea1485ded2446561bf56e2945a87f2fa20a446" ubuntu-2404-docker-image: type: string # solbuildpackpusher/solidity-buildpack-deps:ubuntu2404-1 diff --git a/.circleci/osx_install_dependencies.sh b/.circleci/osx_install_dependencies.sh index 5436c31fe05f..dff85b489ca3 100755 --- a/.circleci/osx_install_dependencies.sh +++ b/.circleci/osx_install_dependencies.sh @@ -112,26 +112,10 @@ then rm -rf "$z3_dir" # evmone - evmone_version="0.11.0" - if [[ $(uname -m) == 'arm64' ]] - then - # evmone does not provide any builds for apple silicon yet. so lets just build it locally. - # be aware that we are only building the arm version here, we don't build a universal binary. - git clone https://github.com/ethereum/evmone.git - cd evmone - git checkout "v${evmone_version}" - git submodule update --init - cmake -S . -B build - cmake --build build - cd build - sudo make install - cd ../.. - rm -rf evmone - else - evmone_package="evmone-${evmone_version}-darwin-x86_64.tar.gz" - wget "https://github.com/ethereum/evmone/releases/download/v${evmone_version}/${evmone_package}" - validate_checksum "$evmone_package" 83ed20676681d9a31bd30cac399ab7c615ccab8adb8087cc2c7e9cd22b4d2efc - tar xzpf "$evmone_package" -C /usr/local - rm "$evmone_package" - fi + evmone_version="0.12.0" + evmone_package="evmone-${evmone_version}-darwin-arm64.tar.gz" + wget "https://github.com/ethereum/evmone/releases/download/v${evmone_version}/${evmone_package}" + validate_checksum "$evmone_package" e164e0d2b985cc1cca07b501538b2e804bf872d1d8d531f9241d518a886234a6 + sudo tar xzpf "$evmone_package" -C /usr/local + rm "$evmone_package" fi diff --git a/scripts/install_evmone.ps1 b/scripts/install_evmone.ps1 index 5864f249159d..7295afa01ee3 100644 --- a/scripts/install_evmone.ps1 +++ b/scripts/install_evmone.ps1 @@ -3,6 +3,6 @@ $ErrorActionPreference = "Stop" # Needed for Invoke-WebRequest to work via CI. $progressPreference = "silentlyContinue" -Invoke-WebRequest -URI "https://github.com/ethereum/evmone/releases/download/v0.11.0/evmone-0.11.0-windows-amd64.zip" -OutFile "evmone.zip" +Invoke-WebRequest -URI "https://github.com/ethereum/evmone/releases/download/v0.12.0/evmone-0.12.0-windows-amd64.zip" -OutFile "evmone.zip" tar -xf evmone.zip "bin/evmone.dll" mv bin/evmone.dll deps/ diff --git a/test/Common.h b/test/Common.h index b5963c88750a..3adb980a0d05 100644 --- a/test/Common.h +++ b/test/Common.h @@ -34,13 +34,13 @@ namespace solidity::test #ifdef _WIN32 static constexpr auto evmoneFilename = "evmone.dll"; -static constexpr auto evmoneDownloadLink = "https://github.com/ethereum/evmone/releases/download/v0.11.0/evmone-0.11.0-windows-amd64.zip"; +static constexpr auto evmoneDownloadLink = "https://github.com/ethereum/evmone/releases/download/v0.12.0/evmone-0.12.0-windows-amd64.zip"; #elif defined(__APPLE__) static constexpr auto evmoneFilename = "libevmone.dylib"; -static constexpr auto evmoneDownloadLink = "https://github.com/ethereum/evmone/releases/download/v0.11.0/evmone-0.11.0-darwin-x86_64.tar.gz"; +static constexpr auto evmoneDownloadLink = "https://github.com/ethereum/evmone/releases/download/v0.12.0/evmone-0.12.0-darwin-x86_64.tar.gz"; #else static constexpr auto evmoneFilename = "libevmone.so"; -static constexpr auto evmoneDownloadLink = "https://github.com/ethereum/evmone/releases/download/v0.11.0/evmone-0.11.0-linux-x86_64.tar.gz"; +static constexpr auto evmoneDownloadLink = "https://github.com/ethereum/evmone/releases/download/v0.12.0/evmone-0.12.0-linux-x86_64.tar.gz"; #endif struct ConfigException: public util::Exception {}; diff --git a/test/evmc/README.md b/test/evmc/README.md index 9381b4f53eda..35fb11901c49 100644 --- a/test/evmc/README.md +++ b/test/evmc/README.md @@ -1,6 +1,6 @@ # EVMC -This is an import of [EVMC](https://github.com/ethereum/evmc) version [11.0.0](https://github.com/ethereum/evmc/releases/tag/v11.0.0). +This is an import of [EVMC](https://github.com/ethereum/evmc) version [12.0.0](https://github.com/ethereum/evmc/releases/tag/v12.0.0). Steps when upgrading: - Copy all from [include/evmc](https://github.com/ethereum/evmc/tree/master/include/evmc) to [test/evmc](https://github.com/ethereum/solidity/tree/develop/test/evmc) diff --git a/test/evmc/bytes.hpp b/test/evmc/bytes.hpp new file mode 100644 index 000000000000..34ddc2f2cfef --- /dev/null +++ b/test/evmc/bytes.hpp @@ -0,0 +1,93 @@ +// EVMC: Ethereum Client-VM Connector API. +// Copyright 2024 The EVMC Authors. +// Licensed under the Apache License, Version 2.0. +#pragma once + +#include +#include +#include +#include + +namespace evmc +{ +/// The char traits for byte-like types. +/// +/// See: https://en.cppreference.com/w/cpp/string/char_traits. +template +struct byte_traits : std::char_traits +{ + static_assert(sizeof(T) == 1, "type must be a byte"); + + using char_type = T; ///< The byte type. + + /// Assigns c2 to c1. + static constexpr void assign(char_type& c1, const char_type& c2) { c1 = c2; } + + /// Assigns value to each byte in [ptr, ptr+count). + static constexpr char_type* assign(char_type* ptr, std::size_t count, char_type value) + { + std::fill_n(ptr, count, value); + return ptr; + } + + /// Returns true if bytes are equal. + static constexpr bool eq(char_type a, char_type b) { return a == b; } + + /// Returns true if byte a is less than byte b. + static constexpr bool lt(char_type a, char_type b) { return a < b; } + + /// Copies count bytes from src to dest. Performs correctly even if ranges overlap. + static constexpr char_type* move(char_type* dest, const char_type* src, std::size_t count) + { + if (dest < src) + std::copy_n(src, count, dest); + else if (src < dest) + std::copy_backward(src, src + count, dest + count); + return dest; + } + + /// Copies count bytes from src to dest. The ranges must not overlap. + static constexpr char_type* copy(char_type* dest, const char_type* src, std::size_t count) + { + std::copy_n(src, count, dest); + return dest; + } + + /// Compares lexicographically the bytes in two ranges of equal length. + static constexpr int compare(const char_type* a, const char_type* b, std::size_t count) + { + for (; count != 0; --count, ++a, ++b) + { + if (lt(*a, *b)) + return -1; + if (lt(*b, *a)) + return 1; + } + return 0; + } + + /// Returns the length of a null-terminated byte string. + // TODO: Not constexpr + static std::size_t length(const char_type* s) + { + return std::strlen(reinterpret_cast(s)); + } + + /// Finds the value in the range of bytes and returns the pointer to the first occurrence + /// or nullptr if not found. + static constexpr const char_type* find(const char_type* s, + std::size_t count, + const char_type& value) + { + const auto end = s + count; + const auto p = std::find(s, end, value); + return p != end ? p : nullptr; + } +}; + +/// String of unsigned chars representing bytes. +using bytes = std::basic_string>; + +/// String view of unsigned chars representing bytes. +using bytes_view = std::basic_string_view>; +} // namespace evmc diff --git a/test/evmc/evmc.h b/test/evmc/evmc.h index 571c97f474e0..bec847597cc0 100644 --- a/test/evmc/evmc.h +++ b/test/evmc/evmc.h @@ -44,7 +44,7 @@ enum * * @see @ref versioning */ - EVMC_ABI_VERSION = 11 + EVMC_ABI_VERSION = 12 }; @@ -79,7 +79,8 @@ enum evmc_call_kind The value param ignored. */ EVMC_CALLCODE = 2, /**< Request CALLCODE. */ EVMC_CREATE = 3, /**< Request CREATE. */ - EVMC_CREATE2 = 4 /**< Request CREATE2. Valid since Constantinople.*/ + EVMC_CREATE2 = 4, /**< Request CREATE2. Valid since Constantinople.*/ + EVMC_EOFCREATE = 5 /**< Request EOFCREATE. Valid since Prague.*/ }; /** The flags for ::evmc_message. */ @@ -168,7 +169,8 @@ struct evmc_message /** * The optional value used in new contract address construction. * - * Needed only for a Host to calculate created address when kind is ::EVMC_CREATE2. + * Needed only for a Host to calculate created address when kind is ::EVMC_CREATE2 or + * ::EVMC_EOFCREATE. * Ignored in evmc_execute_fn(). */ evmc_bytes32 create2_salt; @@ -179,7 +181,7 @@ struct evmc_message * For ::EVMC_CALLCODE or ::EVMC_DELEGATECALL this may be different from * the evmc_message::recipient. * Not required when invoking evmc_execute_fn(), only when invoking evmc_call_fn(). - * Ignored if kind is ::EVMC_CREATE or ::EVMC_CREATE2. + * Ignored if kind is ::EVMC_CREATE, ::EVMC_CREATE2 or ::EVMC_EOFCREATE. * * In case of ::EVMC_CAPABILITY_PRECOMPILES implementation, this fields should be inspected * to identify the requested precompile. @@ -187,24 +189,43 @@ struct evmc_message * Defined as `c` in the Yellow Paper. */ evmc_address code_address; + + /** + * The code to be executed. + */ + const uint8_t* code; + + /** + * The length of the code to be executed. + */ + size_t code_size; }; +/** The hashed initcode used for TXCREATE instruction. */ +typedef struct evmc_tx_initcode +{ + evmc_bytes32 hash; /**< The initcode hash. */ + const uint8_t* code; /**< The code. */ + size_t code_size; /**< The length of the code. */ +} evmc_tx_initcode; /** The transaction and block data for execution. */ struct evmc_tx_context { - evmc_uint256be tx_gas_price; /**< The transaction gas price. */ - evmc_address tx_origin; /**< The transaction origin account. */ - evmc_address block_coinbase; /**< The miner of the block. */ - int64_t block_number; /**< The block number. */ - int64_t block_timestamp; /**< The block timestamp. */ - int64_t block_gas_limit; /**< The block gas limit. */ - evmc_uint256be block_prev_randao; /**< The block previous RANDAO (EIP-4399). */ - evmc_uint256be chain_id; /**< The blockchain's ChainID. */ - evmc_uint256be block_base_fee; /**< The block base fee per gas (EIP-1559, EIP-3198). */ - evmc_uint256be blob_base_fee; /**< The blob base fee (EIP-7516). */ - const evmc_bytes32* blob_hashes; /**< The array of blob hashes (EIP-4844). */ - size_t blob_hashes_count; /**< The number of blob hashes (EIP-4844). */ + evmc_uint256be tx_gas_price; /**< The transaction gas price. */ + evmc_address tx_origin; /**< The transaction origin account. */ + evmc_address block_coinbase; /**< The miner of the block. */ + int64_t block_number; /**< The block number. */ + int64_t block_timestamp; /**< The block timestamp. */ + int64_t block_gas_limit; /**< The block gas limit. */ + evmc_uint256be block_prev_randao; /**< The block previous RANDAO (EIP-4399). */ + evmc_uint256be chain_id; /**< The blockchain's ChainID. */ + evmc_uint256be block_base_fee; /**< The block base fee per gas (EIP-1559, EIP-3198). */ + evmc_uint256be blob_base_fee; /**< The blob base fee (EIP-7516). */ + const evmc_bytes32* blob_hashes; /**< The array of blob hashes (EIP-4844). */ + size_t blob_hashes_count; /**< The number of blob hashes (EIP-4844). */ + const evmc_tx_initcode* initcodes; /**< The array of transaction initcodes (TXCREATE). */ + size_t initcodes_count; /**< The number of transaction initcodes (TXCREATE). */ }; /** @@ -1007,7 +1028,6 @@ enum evmc_revision /** * The Cancun revision. * - * The future next revision after Shanghai. * https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/cancun.md */ EVMC_CANCUN = 12, @@ -1019,15 +1039,22 @@ enum evmc_revision */ EVMC_PRAGUE = 13, + /** + * The Osaka revision. + * + * The future next revision after Prague. + */ + EVMC_OSAKA = 14, + /** The maximum EVM revision supported. */ - EVMC_MAX_REVISION = EVMC_PRAGUE, + EVMC_MAX_REVISION = EVMC_OSAKA, /** * The latest known EVM revision with finalized specification. * * This is handy for EVM tools to always use the latest revision available. */ - EVMC_LATEST_STABLE_REVISION = EVMC_SHANGHAI + EVMC_LATEST_STABLE_REVISION = EVMC_CANCUN }; diff --git a/test/evmc/evmc.hpp b/test/evmc/evmc.hpp index 91386c46f857..2dfabf82608d 100644 --- a/test/evmc/evmc.hpp +++ b/test/evmc/evmc.hpp @@ -20,9 +20,6 @@ static_assert(EVMC_LATEST_STABLE_REVISION <= EVMC_MAX_REVISION, /// @ingroup cpp namespace evmc { -/// String view of uint8_t chars. -using bytes_view = std::basic_string_view; - /// The big-endian 160-bit hash suitable for keeping an Ethereum address. /// /// This type wraps C ::evmc_address to make sure objects of this type are always initialized. diff --git a/test/evmc/helpers.h b/test/evmc/helpers.h index 683567ef13ff..a5f6c3637ff0 100644 --- a/test/evmc/helpers.h +++ b/test/evmc/helpers.h @@ -301,6 +301,8 @@ static inline const char* evmc_revision_to_string(enum evmc_revision rev) return "Cancun"; case EVMC_PRAGUE: return "Prague"; + case EVMC_OSAKA: + return "Osaka"; } return ""; } diff --git a/test/evmc/hex.hpp b/test/evmc/hex.hpp index 31bbe519534e..a2505b71fed2 100644 --- a/test/evmc/hex.hpp +++ b/test/evmc/hex.hpp @@ -3,6 +3,7 @@ // Licensed under the Apache License, Version 2.0. #pragma once +#include #include #include #include @@ -11,13 +12,6 @@ namespace evmc { -/// String of uint8_t chars. -using bytes = std::basic_string; - -/// String view of uint8_t chars. -using bytes_view = std::basic_string_view; - - /// Encode a byte to a hex string. inline std::string hex(uint8_t b) noexcept { diff --git a/test/evmc/mocked_host.hpp b/test/evmc/mocked_host.hpp index 205a136b3800..2b37113ad10b 100644 --- a/test/evmc/mocked_host.hpp +++ b/test/evmc/mocked_host.hpp @@ -6,16 +6,13 @@ #include #include #include -#include #include +#include #include #include namespace evmc { -/// The string of bytes. -using bytes = std::basic_string; - /// Extended value (with original value and access flag) for account storage. struct StorageValue { From 322d6561360eecf71ce39f6383bc1d95f3083d54 Mon Sep 17 00:00:00 2001 From: Vishwa Mehta Date: Mon, 16 Sep 2024 18:20:44 +0530 Subject: [PATCH 0420/1022] Make it easier for users to discover that copying arrays and structs to storage is unimplemented only in legacy codegen and works via IR (#15432) --- libsolidity/codegen/ArrayUtils.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libsolidity/codegen/ArrayUtils.cpp b/libsolidity/codegen/ArrayUtils.cpp index e653239cfa1a..5dd94aebc4f0 100644 --- a/libsolidity/codegen/ArrayUtils.cpp +++ b/libsolidity/codegen/ArrayUtils.cpp @@ -224,7 +224,7 @@ void ArrayUtils::copyArrayToStorage(ArrayType const& _targetType, ArrayType cons else if (sourceBaseType->isValueType()) CompilerUtils(_context).loadFromMemoryDynamic(*sourceBaseType, fromCalldata, true, false); else - solUnimplemented("Copying of type " + _sourceType.toString(false) + " to storage not yet supported."); + solUnimplemented("Copying of type " + _sourceType.toString(false) + " to storage is not supported in legacy (only supported by the IR pipeline). Hint: try compiling with `--via-ir` (CLI) or the equivalent `viaIR: true` (Standard JSON)"); // stack: target_ref target_data_end source_data_pos target_data_pos source_data_end [target_byte_offset] [source_byte_offset] ... assertThrow( 2 + byteOffsetSize + sourceBaseType->sizeOnStack() <= 16, From 2e6a2d2ba4f0c75c027a949ae57df73b7885c2b7 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Mon, 9 Sep 2024 10:26:22 +0200 Subject: [PATCH 0421/1022] Add SSACFG loop nesting forest --- libyul/CMakeLists.txt | 2 + .../backends/evm/SSACFGLoopNestingForest.cpp | 90 +++++++ libyul/backends/evm/SSACFGLoopNestingForest.h | 61 +++++ libyul/backends/evm/SSACFGTopologicalSort.cpp | 39 ++- libyul/backends/evm/SSACFGTopologicalSort.h | 22 +- .../yulSSAControlFlowGraph/nested_for.yul | 231 ++++++++++++++++++ 6 files changed, 408 insertions(+), 37 deletions(-) create mode 100644 libyul/backends/evm/SSACFGLoopNestingForest.cpp create mode 100644 libyul/backends/evm/SSACFGLoopNestingForest.h create mode 100644 test/libyul/yulSSAControlFlowGraph/nested_for.yul diff --git a/libyul/CMakeLists.txt b/libyul/CMakeLists.txt index 704e04921b67..e790f6c17961 100644 --- a/libyul/CMakeLists.txt +++ b/libyul/CMakeLists.txt @@ -65,6 +65,8 @@ add_library(yul backends/evm/NoOutputAssembly.cpp backends/evm/OptimizedEVMCodeTransform.cpp backends/evm/OptimizedEVMCodeTransform.h + backends/evm/SSACFGLoopNestingForest.cpp + backends/evm/SSACFGLoopNestingForest.h backends/evm/SSACFGTopologicalSort.cpp backends/evm/SSACFGTopologicalSort.h backends/evm/SSAControlFlowGraph.h diff --git a/libyul/backends/evm/SSACFGLoopNestingForest.cpp b/libyul/backends/evm/SSACFGLoopNestingForest.cpp new file mode 100644 index 000000000000..b28597813486 --- /dev/null +++ b/libyul/backends/evm/SSACFGLoopNestingForest.cpp @@ -0,0 +1,90 @@ +/* + 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 + +using namespace solidity::yul; + +SSACFGLoopNestingForest::SSACFGLoopNestingForest(ForwardSSACFGTopologicalSort const& _sort): + m_sort(_sort), + m_cfg(_sort.cfg()), + m_vertexPartition(m_cfg.numBlocks()), + m_loopParents(m_cfg.numBlocks(), std::numeric_limits::max()) +{ + auto dfsOrder = m_sort.preOrder(); + // we go from innermost to outermost + std::reverse(dfsOrder.begin(), dfsOrder.end()); + + for (auto const& blockId: dfsOrder) + findLoop(blockId); + + // get the root nodes + for (auto loopHeader: m_loopNodes) + { + while (m_loopParents[loopHeader] != std::numeric_limits::max()) + loopHeader = m_loopParents[loopHeader]; + m_loopRootNodes.insert(loopHeader); + } +} + +void SSACFGLoopNestingForest::findLoop(size_t const _potentialHeader) +{ + if (m_sort.backEdgeTargets().count(_potentialHeader) > 0) + { + std::set loopBody; + std::set workList; + for (auto const pred: m_cfg.block(SSACFG::BlockId{_potentialHeader}).entries) + { + auto const representative = m_vertexPartition.find(pred.value); + if ( + representative != _potentialHeader && + m_sort.backEdge(SSACFG::BlockId{pred}, SSACFG::BlockId{_potentialHeader}) + ) + workList.insert(representative); + } + + while (!workList.empty()) + { + auto const y = workList.extract(workList.begin()).value(); + loopBody.insert(y); + + for (auto const& predecessor: m_cfg.block(SSACFG::BlockId{y}).entries) + { + if (!m_sort.backEdge(SSACFG::BlockId{predecessor}, SSACFG::BlockId{y})) + { + auto const predecessorHeader = m_vertexPartition.find(predecessor.value); + if (predecessorHeader != _potentialHeader && loopBody.count(predecessorHeader) == 0) + workList.insert(predecessorHeader); + } + } + } + + if (!loopBody.empty()) + collapse(loopBody, _potentialHeader); + } +} +void SSACFGLoopNestingForest::collapse(std::set const& _loopBody, size_t _loopHeader) +{ + for (auto const z: _loopBody) + { + m_loopParents[z] = _loopHeader; + m_vertexPartition.merge(_loopHeader, z, false); // don't merge by size, loop header should be representative + } + yulAssert(m_vertexPartition.find(_loopHeader) == _loopHeader); // representative was preserved + m_loopNodes.insert(_loopHeader); +} diff --git a/libyul/backends/evm/SSACFGLoopNestingForest.h b/libyul/backends/evm/SSACFGLoopNestingForest.h new file mode 100644 index 000000000000..0aad6ab396bd --- /dev/null +++ b/libyul/backends/evm/SSACFGLoopNestingForest.h @@ -0,0 +1,61 @@ +/* + This file is part of solidity. + + solidity is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + solidity is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with solidity. If not, see . +*/ +// SPDX-License-Identifier: GPL-3.0 + +#pragma once + +#include +#include + +#include + +#include +#include +#include + +namespace solidity::yul +{ + +/// Constructs a loop nesting forest for an SSACFG using Tarjan's algorithm [1]. +/// +/// [1] Ramalingam, Ganesan. "Identifying loops in almost linear time." +/// ACM Transactions on Programming Languages and Systems (TOPLAS) 21.2 (1999): 175-188. +class SSACFGLoopNestingForest +{ +public: + explicit SSACFGLoopNestingForest(ForwardSSACFGTopologicalSort const& _sort); + + /// blocks which are not contained in a loop get assigned the loop parent numeric_limit::max() + std::vector const& loopParents() const { return m_loopParents; } + /// all loop nodes (entry blocks for loops), also nested ones + std::set const& loopNodes() const { return m_loopNodes; } + /// root loop nodes in the forest for outer-most loops + std::set const& loopRootNodes() const { return m_loopRootNodes; } +private: + void findLoop(size_t _potentialHeader); + void collapse(std::set const& _loopBody, size_t _loopHeader); + + ForwardSSACFGTopologicalSort const& m_sort; + SSACFG const& m_cfg; + + util::ContiguousDisjointSet m_vertexPartition; + std::vector m_loopParents; + std::set m_loopNodes; + std::set m_loopRootNodes; +}; + +} diff --git a/libyul/backends/evm/SSACFGTopologicalSort.cpp b/libyul/backends/evm/SSACFGTopologicalSort.cpp index e0370aa275b9..5e3e0c0ec61b 100644 --- a/libyul/backends/evm/SSACFGTopologicalSort.cpp +++ b/libyul/backends/evm/SSACFGTopologicalSort.cpp @@ -22,18 +22,17 @@ using namespace solidity::yul; ForwardSSACFGTopologicalSort::ForwardSSACFGTopologicalSort(SSACFG const& _cfg): m_cfg(_cfg), - m_explored(m_cfg.numBlocks(), false), - m_reversedPostOrder(m_cfg.numBlocks(), std::numeric_limits::max()), - m_preOrder(m_cfg.numBlocks(), std::numeric_limits::max()), - m_maxSubtreePreOrder(m_cfg.numBlocks(), 0), - m_predecessors(m_cfg.numBlocks()) + m_explored(m_cfg.numBlocks(), false), m_blockWisePreOrder(m_cfg.numBlocks(), 0), + m_blockWiseMaxSubtreePreOrder(m_cfg.numBlocks(), 0) { + yulAssert(m_cfg.entry.value == 0); + m_preOrder.reserve(m_cfg.numBlocks()); + m_postOrder.reserve(m_cfg.numBlocks()); for (size_t id = 0; id < m_cfg.numBlocks(); ++id) { if (!m_explored[id]) dfs(id); } - std::reverse(m_reversedPostOrder.begin(), m_reversedPostOrder.end()); for (auto const& [v1, v2]: m_potentialBackEdges) if (ancestor(v2, v1)) @@ -43,40 +42,32 @@ ForwardSSACFGTopologicalSort::ForwardSSACFGTopologicalSort(SSACFG const& _cfg): void ForwardSSACFGTopologicalSort::dfs(size_t const _vertex) { yulAssert(!m_explored[_vertex]); m_explored[_vertex] = true; - m_preOrder[_vertex] = m_currentNode++; - m_maxSubtreePreOrder[_vertex] = m_preOrder[_vertex]; + m_blockWisePreOrder[_vertex] = m_preOrder.size(); + m_blockWiseMaxSubtreePreOrder[_vertex] = m_blockWisePreOrder[_vertex]; + m_preOrder.push_back(_vertex); m_cfg.block(SSACFG::BlockId{_vertex}).forEachExit([&](SSACFG::BlockId const& _exitBlock){ - m_predecessors[_exitBlock.value].insert(_vertex); if (!m_explored[_exitBlock.value]) { dfs(_exitBlock.value); - m_maxSubtreePreOrder[_vertex] = std::max(m_maxSubtreePreOrder[_vertex], m_maxSubtreePreOrder[_exitBlock.value]); + m_blockWiseMaxSubtreePreOrder[_vertex] = std::max(m_blockWiseMaxSubtreePreOrder[_vertex], m_blockWiseMaxSubtreePreOrder[_exitBlock.value]); } else m_potentialBackEdges.emplace_back(_vertex, _exitBlock.value); }); - m_reversedPostOrder[m_preOrder[_vertex]] = _vertex; + m_postOrder.push_back(_vertex); } -std::vector const& ForwardSSACFGTopologicalSort::sortedBlocks() const { return m_reversedPostOrder; } -std::vector const& ForwardSSACFGTopologicalSort::preOrder() const { return m_preOrder; } -std::vector const& ForwardSSACFGTopologicalSort::reversedPostOrder() const { return m_reversedPostOrder; } -std::vector const& ForwardSSACFGTopologicalSort::maxSubtreePreOrder() const { return m_maxSubtreePreOrder; } -std::set const& ForwardSSACFGTopologicalSort::backEdgeTargets() const { return m_backEdgeTargets; } -std::vector> const& ForwardSSACFGTopologicalSort::predecessors() const { return m_predecessors; } -SSACFG const& ForwardSSACFGTopologicalSort::cfg() const { return m_cfg; } - bool ForwardSSACFGTopologicalSort::ancestor(size_t const _block1, size_t const _block2) const { - yulAssert(_block1 < m_preOrder.size()); - yulAssert(_block2 < m_preOrder.size()); + yulAssert(_block1 < m_blockWisePreOrder.size()); + yulAssert(_block2 < m_blockWisePreOrder.size()); - auto const preOrderIndex1 = m_preOrder[_block1]; - auto const preOrderIndex2 = m_preOrder[_block2]; + auto const preOrderIndex1 = m_blockWisePreOrder[_block1]; + auto const preOrderIndex2 = m_blockWisePreOrder[_block2]; bool const node1VisitedBeforeNode2 = preOrderIndex1 <= preOrderIndex2; - bool const node2InSubtreeOfNode1 = preOrderIndex2 <= m_maxSubtreePreOrder[_block1]; + bool const node2InSubtreeOfNode1 = preOrderIndex2 <= m_blockWiseMaxSubtreePreOrder[_block1]; return node1VisitedBeforeNode2 && node2InSubtreeOfNode1; } diff --git a/libyul/backends/evm/SSACFGTopologicalSort.h b/libyul/backends/evm/SSACFGTopologicalSort.h index ec62eb01370d..973f286f286a 100644 --- a/libyul/backends/evm/SSACFGTopologicalSort.h +++ b/libyul/backends/evm/SSACFGTopologicalSort.h @@ -33,28 +33,24 @@ class ForwardSSACFGTopologicalSort public: explicit ForwardSSACFGTopologicalSort(SSACFG const& _cfg); - std::vector const& sortedBlocks() const; - std::vector const& preOrder() const; - std::vector const& reversedPostOrder() const; - std::vector const& maxSubtreePreOrder() const; - std::set const& backEdgeTargets() const; - std::vector> const& predecessors() const; - SSACFG const& cfg() const; - bool ancestor(size_t _block1, size_t _block2) const; + std::vector const& preOrder() const { return m_preOrder; } + std::vector const& postOrder() const { return m_postOrder; } + std::set const& backEdgeTargets() const { return m_backEdgeTargets; } + SSACFG const& cfg() const { return m_cfg; } bool backEdge(SSACFG::BlockId const& _block1, SSACFG::BlockId const& _block2) const; private: void dfs(size_t _vertex); + /// Checks if block1 is an ancestor of block2, ie there's a path from block1 to block2 in the dfs tree + bool ancestor(size_t _block1, size_t _block2) const; SSACFG const& m_cfg; - - size_t m_currentNode {0}; std::vector m_explored{}; - std::vector m_reversedPostOrder{}; + std::vector m_postOrder{}; std::vector m_preOrder{}; - std::vector m_maxSubtreePreOrder{}; + std::vector m_blockWisePreOrder{}; + std::vector m_blockWiseMaxSubtreePreOrder{}; std::vector> m_potentialBackEdges{}; std::set m_backEdgeTargets{}; - std::vector> m_predecessors{}; }; } diff --git a/test/libyul/yulSSAControlFlowGraph/nested_for.yul b/test/libyul/yulSSAControlFlowGraph/nested_for.yul new file mode 100644 index 000000000000..e078630a60d9 --- /dev/null +++ b/test/libyul/yulSSAControlFlowGraph/nested_for.yul @@ -0,0 +1,231 @@ +{ + for { let i := 0 } lt(i, 3) { i := add(i, 1) } { + for { let j := 0 } lt(j, 3) { j := add(j, 1) } { + for { let k := 0 } lt(k, 3) { k := add(k, 1) } { + if 0 { + for { let l := 0 } lt(l, 3) { l := add(l, 1) } { + sstore(l, add(add(i,j),k)) + } + } + if 1 { + for { let l := 0 } lt(l, 3) { l := add(l, 1) } { + sstore(l, add(add(i,j),k)) + } + } + } + } + } +} + +// ---- +// digraph SSACFG { +// nodesep=0.7; +// graph[fontname="DejaVu Sans"] +// node[shape=box,fontname="DejaVu Sans"]; +// +// Entry0 [label="Entry"]; +// Entry0 -> Block0_0; +// Block0_0 [label="\ +// Block 0\n"]; +// Block0_0 -> Block0_0Exit [arrowhead=none]; +// Block0_0Exit [label="Jump" shape=oval]; +// Block0_0Exit -> Block0_1; +// Block0_1 [label="\ +// Block 1\nv2 := φ(\l\ +// Block 0 => 0,\l\ +// Block 3 => v36\l\ +// )\l\ +// v3 := lt(3, v2)\l\ +// "]; +// Block0_1 -> Block0_1Exit; +// Block0_1Exit [label="{ If v3| { <0> Zero | <1> NonZero }}" shape=Mrecord]; +// Block0_1Exit:0 -> Block0_4; +// Block0_1Exit:1 -> Block0_2; +// Block0_2 [label="\ +// Block 2\n"]; +// Block0_2 -> Block0_2Exit [arrowhead=none]; +// Block0_2Exit [label="Jump" shape=oval]; +// Block0_2Exit -> Block0_5; +// Block0_4 [label="\ +// Block 4\n"]; +// Block0_4Exit [label="MainExit"]; +// Block0_4 -> Block0_4Exit; +// Block0_5 [label="\ +// Block 5\nv4 := φ(\l\ +// Block 2 => 0,\l\ +// Block 7 => v35\l\ +// )\l\ +// v33 := φ(\l\ +// Block 2 => v2,\l\ +// Block 7 => v18\l\ +// )\l\ +// v5 := lt(3, v4)\l\ +// "]; +// Block0_5 -> Block0_5Exit; +// Block0_5Exit [label="{ If v5| { <0> Zero | <1> NonZero }}" shape=Mrecord]; +// Block0_5Exit:0 -> Block0_8; +// Block0_5Exit:1 -> Block0_6; +// Block0_6 [label="\ +// Block 6\n"]; +// Block0_6 -> Block0_6Exit [arrowhead=none]; +// Block0_6Exit [label="Jump" shape=oval]; +// Block0_6Exit -> Block0_9; +// Block0_8 [label="\ +// Block 8\n"]; +// Block0_8 -> Block0_8Exit [arrowhead=none]; +// Block0_8Exit [label="Jump" shape=oval]; +// Block0_8Exit -> Block0_3; +// Block0_9 [label="\ +// Block 9\nv6 := φ(\l\ +// Block 6 => 0,\l\ +// Block 11 => v31\l\ +// )\l\ +// v17 := φ(\l\ +// Block 6 => v4,\l\ +// Block 11 => v32\l\ +// )\l\ +// v18 := φ(\l\ +// Block 6 => v33,\l\ +// Block 11 => v34\l\ +// )\l\ +// v7 := lt(3, v6)\l\ +// "]; +// Block0_9 -> Block0_9Exit; +// Block0_9Exit [label="{ If v7| { <0> Zero | <1> NonZero }}" shape=Mrecord]; +// Block0_9Exit:0 -> Block0_12; +// Block0_9Exit:1 -> Block0_10; +// Block0_3 [label="\ +// Block 3\nv36 := add(1, v33)\l\ +// "]; +// Block0_3 -> Block0_3Exit [arrowhead=none]; +// Block0_3Exit [label="Jump" shape=oval]; +// Block0_3Exit -> Block0_1; +// Block0_10 [label="\ +// Block 10\n"]; +// Block0_10 -> Block0_10Exit; +// Block0_10Exit [label="{ If 0| { <0> Zero | <1> NonZero }}" shape=Mrecord]; +// Block0_10Exit:0 -> Block0_14; +// Block0_10Exit:1 -> Block0_13; +// Block0_12 [label="\ +// Block 12\n"]; +// Block0_12 -> Block0_12Exit [arrowhead=none]; +// Block0_12Exit [label="Jump" shape=oval]; +// Block0_12Exit -> Block0_7; +// Block0_13 [label="\ +// Block 13\n"]; +// Block0_13 -> Block0_13Exit [arrowhead=none]; +// Block0_13Exit [label="Jump" shape=oval]; +// Block0_13Exit -> Block0_15; +// Block0_14 [label="\ +// Block 14\nv27 := φ(\l\ +// Block 10 => v6,\l\ +// Block 18 => v10\l\ +// )\l\ +// v28 := φ(\l\ +// Block 10 => v17,\l\ +// Block 18 => v11\l\ +// )\l\ +// v29 := φ(\l\ +// Block 10 => v18,\l\ +// Block 18 => v12\l\ +// )\l\ +// "]; +// Block0_14 -> Block0_14Exit; +// Block0_14Exit [label="{ If 1| { <0> Zero | <1> NonZero }}" shape=Mrecord]; +// Block0_14Exit:0 -> Block0_20; +// Block0_14Exit:1 -> Block0_19; +// Block0_7 [label="\ +// Block 7\nv35 := add(1, v17)\l\ +// "]; +// Block0_7 -> Block0_7Exit [arrowhead=none]; +// Block0_7Exit [label="Jump" shape=oval]; +// Block0_7Exit -> Block0_5; +// Block0_15 [label="\ +// Block 15\nv8 := φ(\l\ +// Block 13 => 0,\l\ +// Block 17 => v16\l\ +// )\l\ +// v9 := lt(3, v8)\l\ +// "]; +// Block0_15 -> Block0_15Exit; +// Block0_15Exit [label="{ If v9| { <0> Zero | <1> NonZero }}" shape=Mrecord]; +// Block0_15Exit:0 -> Block0_18; +// Block0_15Exit:1 -> Block0_16; +// Block0_19 [label="\ +// Block 19\n"]; +// Block0_19 -> Block0_19Exit [arrowhead=none]; +// Block0_19Exit [label="Jump" shape=oval]; +// Block0_19Exit -> Block0_21; +// Block0_20 [label="\ +// Block 20\nv30 := φ(\l\ +// Block 14 => v27,\l\ +// Block 24 => v21\l\ +// )\l\ +// v32 := φ(\l\ +// Block 14 => v28,\l\ +// Block 24 => v22\l\ +// )\l\ +// v34 := φ(\l\ +// Block 14 => v29,\l\ +// Block 24 => v23\l\ +// )\l\ +// "]; +// Block0_20 -> Block0_20Exit [arrowhead=none]; +// Block0_20Exit [label="Jump" shape=oval]; +// Block0_20Exit -> Block0_11; +// Block0_16 [label="\ +// Block 16\nv13 := add(v17, v18)\l\ +// v14 := add(v6, v13)\l\ +// sstore(v14, v8)\l\ +// "]; +// Block0_16 -> Block0_16Exit [arrowhead=none]; +// Block0_16Exit [label="Jump" shape=oval]; +// Block0_16Exit -> Block0_17; +// Block0_18 [label="\ +// Block 18\n"]; +// Block0_18 -> Block0_18Exit [arrowhead=none]; +// Block0_18Exit [label="Jump" shape=oval]; +// Block0_18Exit -> Block0_14; +// Block0_21 [label="\ +// Block 21\nv19 := φ(\l\ +// Block 19 => 0,\l\ +// Block 23 => v26\l\ +// )\l\ +// v20 := lt(3, v19)\l\ +// "]; +// Block0_21 -> Block0_21Exit; +// Block0_21Exit [label="{ If v20| { <0> Zero | <1> NonZero }}" shape=Mrecord]; +// Block0_21Exit:0 -> Block0_24; +// Block0_21Exit:1 -> Block0_22; +// Block0_11 [label="\ +// Block 11\nv31 := add(1, v30)\l\ +// "]; +// Block0_11 -> Block0_11Exit [arrowhead=none]; +// Block0_11Exit [label="Jump" shape=oval]; +// Block0_11Exit -> Block0_9; +// Block0_17 [label="\ +// Block 17\nv16 := add(1, v8)\l\ +// "]; +// Block0_17 -> Block0_17Exit [arrowhead=none]; +// Block0_17Exit [label="Jump" shape=oval]; +// Block0_17Exit -> Block0_15; +// Block0_22 [label="\ +// Block 22\nv24 := add(v28, v29)\l\ +// v25 := add(v27, v24)\l\ +// sstore(v25, v19)\l\ +// "]; +// Block0_22 -> Block0_22Exit [arrowhead=none]; +// Block0_22Exit [label="Jump" shape=oval]; +// Block0_22Exit -> Block0_23; +// Block0_24 [label="\ +// Block 24\n"]; +// Block0_24 -> Block0_24Exit [arrowhead=none]; +// Block0_24Exit [label="Jump" shape=oval]; +// Block0_24Exit -> Block0_20; +// Block0_23 [label="\ +// Block 23\nv26 := add(1, v19)\l\ +// "]; +// Block0_23 -> Block0_23Exit [arrowhead=none]; +// Block0_23Exit [label="Jump" shape=oval]; +// Block0_23Exit -> Block0_21; +// } From 2b0d08cb4ef121ee975b76a4af737d4a1ce2c1fa Mon Sep 17 00:00:00 2001 From: Anandu Raveendran <77606647+anandhuRaveendran@users.noreply.github.com> Date: Tue, 17 Sep 2024 14:42:07 +0530 Subject: [PATCH 0422/1022] Apostrophe added in README.md (#15431) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Apostrophe corrected - Update README.md Apostrophe corrected * Update README.md --------- Co-authored-by: Nikola Matić --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e64f8cbfd332..197259998fcd 100644 --- a/README.md +++ b/README.md @@ -72,7 +72,7 @@ The Solidity documentation is hosted using [Read the Docs](https://docs.solidity Solidity is still under development. Contributions are always welcome! Please follow the -[Developers Guide](https://docs.soliditylang.org/en/latest/contributing.html) +[Developer's Guide](https://docs.soliditylang.org/en/latest/contributing.html) if you want to help. You can find our current feature and bug priorities for forthcoming From 963d70ba6c7ca0008147cc533eb7fd5060a30f9f Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Wed, 18 Sep 2024 10:12:38 +0200 Subject: [PATCH 0423/1022] Yul: Add toDot to SSACFG --- libyul/CMakeLists.txt | 1 + libyul/backends/evm/SSAControlFlowGraph.cpp | 242 ++++++++++++++++++++ libyul/backends/evm/SSAControlFlowGraph.h | 2 + test/libyul/SSAControlFlowGraphTest.cpp | 208 +---------------- 4 files changed, 247 insertions(+), 206 deletions(-) create mode 100644 libyul/backends/evm/SSAControlFlowGraph.cpp diff --git a/libyul/CMakeLists.txt b/libyul/CMakeLists.txt index e790f6c17961..f621b2089e9b 100644 --- a/libyul/CMakeLists.txt +++ b/libyul/CMakeLists.txt @@ -69,6 +69,7 @@ add_library(yul backends/evm/SSACFGLoopNestingForest.h backends/evm/SSACFGTopologicalSort.cpp backends/evm/SSACFGTopologicalSort.h + backends/evm/SSAControlFlowGraph.cpp backends/evm/SSAControlFlowGraph.h backends/evm/SSAControlFlowGraphBuilder.cpp backends/evm/SSAControlFlowGraphBuilder.h diff --git a/libyul/backends/evm/SSAControlFlowGraph.cpp b/libyul/backends/evm/SSAControlFlowGraph.cpp new file mode 100644 index 000000000000..e98936aaabbd --- /dev/null +++ b/libyul/backends/evm/SSAControlFlowGraph.cpp @@ -0,0 +1,242 @@ +/* + 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 + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wtautological-compare" +#include +#pragma GCC diagnostic pop + +#include + +using namespace solidity; +using namespace solidity::util; +using namespace solidity::yul; + +namespace +{ +class SSACFGPrinter +{ +public: + SSACFGPrinter(SSACFG const& _cfg, SSACFG::BlockId _blockId) + { + printBlock(_cfg, _blockId, 0); + } + SSACFGPrinter(SSACFG const& _cfg, size_t _functionIndex, Scope::Function const& _function) + { + printFunction(_cfg, _functionIndex, _function); + } + friend std::ostream& operator<<(std::ostream& stream, SSACFGPrinter const& printer) { + stream << printer.m_result.str(); + return stream; + } +private: + static std::string varToString(SSACFG const& _cfg, SSACFG::ValueId _var) { + if (_var.value == std::numeric_limits::max()) + return "INVALID"; + auto const& info = _cfg.valueInfo(_var); + return std::visit( + GenericVisitor{ + [&](SSACFG::UnreachableValue const&) -> std::string { + return "[unreachable]"; + }, + [&](SSACFG::PhiValue const&) -> std::string { + return fmt::format("v{}", _var.value); + }, + [&](SSACFG::VariableValue const&) -> std::string { + return fmt::format("v{}", _var.value); + }, + [&](SSACFG::LiteralValue const& _literal) -> std::string { + return formatNumberReadable(_literal.value); + } + }, + info + ); + } + + static std::string formatPhi(SSACFG const& _cfg, SSACFG::PhiValue const& _phiValue) + { + auto const transform = [&](SSACFG::ValueId const& valueId) { return varToString(_cfg, valueId); }; + std::vector formattedArgs; + formattedArgs.reserve(_phiValue.arguments.size()); + for (auto const& [arg, entry]: ranges::zip_view(_phiValue.arguments | ranges::views::transform(transform), _cfg.block(_phiValue.block).entries)) + formattedArgs.push_back(fmt::format("Block {} => {}", entry.value, arg)); + if (!formattedArgs.empty()) + return fmt::format("φ(\\l\\\n\t{}\\l\\\n)", fmt::join(formattedArgs, ",\\l\\\n\t")); + else + return "φ()"; + } + + void writeBlock(SSACFG const& _cfg, SSACFG::BlockId const& _id, SSACFG::BasicBlock const& _block, size_t const _functionIndex) + { + auto const valueToString = [&](SSACFG::ValueId const& valueId) { return varToString(_cfg, valueId); }; + bool entryBlock = _id.value == 0 && _functionIndex == 0; + if (entryBlock) + { + m_result << fmt::format("Entry{} [label=\"Entry\"];\n", _functionIndex); + m_result << fmt::format("Entry{} -> Block{}_{};\n", _functionIndex, _functionIndex, _id.value); + } + { + m_result << fmt::format("Block{1}_{0} [label=\"\\\nBlock {0}\\n", _id.value, _functionIndex); + for (auto const& phi: _block.phis) + { + auto const* phiValue = std::get_if(&_cfg.valueInfo(phi)); + solAssert(phiValue); + m_result << fmt::format("v{} := {}\\l\\\n", phi.value, formatPhi(_cfg, *phiValue)); + } + for (auto const& operation: _block.operations) + { + std::string const label = std::visit(GenericVisitor{ + [&](SSACFG::Call const& _call) { + return _call.function.get().name.str(); + }, + [&](SSACFG::BuiltinCall const& _call) { + return _call.builtin.get().name.str(); + }, + }, operation.kind); + if (!operation.outputs.empty()) + m_result << fmt::format( + "{} := ", + fmt::join(operation.outputs | ranges::views::transform(valueToString), ", ") + ); + m_result << fmt::format( + "{}({})\\l\\\n", + label, + fmt::join(operation.inputs | ranges::views::transform(valueToString), ", ") + ); + } + m_result << "\"];\n"; + std::visit(GenericVisitor{ + [&](SSACFG::BasicBlock::MainExit const&) + { + m_result << fmt::format("Block{}_{}Exit [label=\"MainExit\"];\n", _functionIndex, _id.value); + m_result << fmt::format("Block{1}_{0} -> Block{1}_{0}Exit;\n", _id.value, _functionIndex); + }, + [&](SSACFG::BasicBlock::Jump const& _jump) + { + m_result << fmt::format("Block{1}_{0} -> Block{1}_{0}Exit [arrowhead=none];\n", _id.value, _functionIndex); + m_result << fmt::format("Block{}_{}Exit [label=\"Jump\" shape=oval];\n", _functionIndex, _id.value); + m_result << fmt::format("Block{}_{}Exit -> Block{}_{};\n", _functionIndex, _id.value, _functionIndex, _jump.target.value); + }, + [&](SSACFG::BasicBlock::ConditionalJump const& _conditionalJump) + { + m_result << "Block" << _functionIndex << "_" << _id.value << " -> Block" << _functionIndex << "_" << _id.value << "Exit;\n"; + m_result << "Block" << _functionIndex << "_" << _id.value << "Exit [label=\"{ If "; + m_result << varToString(_cfg, _conditionalJump.condition); + m_result << "| { <0> Zero | <1> NonZero }}\" shape=Mrecord];\n"; + m_result << "Block" << _functionIndex << "_" << _id.value; + m_result << "Exit:0 -> Block" << _functionIndex << "_" << _conditionalJump.zero.value << ";\n"; + m_result << "Block" << _functionIndex << "_" << _id.value; + m_result << "Exit:1 -> Block" << _functionIndex << "_" << _conditionalJump.nonZero.value << ";\n"; + }, + [&](SSACFG::BasicBlock::JumpTable const& jt) + { + m_result << "Block" << _functionIndex << "_" << _id.value << " -> Block" << _functionIndex << "_" << _id.value << "Exit;\n"; + std::string options; + for (auto const& jumpCase: jt.cases) + { + if (!options.empty()) + options += " | "; + options += fmt::format("<{0}> {0}", formatNumber(jumpCase.first)); + } + if (!options.empty()) + options += " | "; + options += " default"; + m_result << fmt::format("Block{}_{}Exit [label=\"{{ JT | {{ {} }} }}\" shape=Mrecord];\n", _functionIndex, _id.value, options); + for (auto const& jumpCase: jt.cases) + m_result << fmt::format("Block{}_{}Exit:{} -> Block{}_{};\n", _functionIndex, _id.value, formatNumber(jumpCase.first), _functionIndex, jumpCase.second.value); + m_result << fmt::format("Block{}_{}Exit:default -> Block{}_{};\n", _functionIndex, _id.value, _functionIndex, jt.defaultCase.value); + }, + [&](SSACFG::BasicBlock::FunctionReturn const& fr) + { + m_result << "Block" << _functionIndex << "_" << _id.value << "Exit [label=\"FunctionReturn[" + << fmt::format("{}", fmt::join(fr.returnValues | ranges::views::transform(valueToString), ", ")) + << "]\"];\n"; + m_result << "Block" << _functionIndex << "_" << _id.value << " -> Block" << _functionIndex << "_" << _id.value << "Exit;\n"; + }, + [&](SSACFG::BasicBlock::Terminated const&) + { + m_result << "Block" << _functionIndex << "_" << _id.value << "Exit [label=\"Terminated\"];\n"; + m_result << "Block" << _functionIndex << "_" << _id.value << " -> Block" << _functionIndex << "_" << _id.value << "Exit;\n"; + } + }, _block.exit); + } + } + + void printBlock(SSACFG const& _cfg, SSACFG::BlockId const& _rootId, size_t const _functionIndex) + { + std::set explored{}; + explored.insert(_rootId); + + std::deque toVisit{}; + toVisit.emplace_back(_rootId); + + while (!toVisit.empty()) + { + auto const id = toVisit.front(); + toVisit.pop_front(); + auto const& block = _cfg.block(id); + writeBlock(_cfg, id, block, _functionIndex); + block.forEachExit( + [&](SSACFG::BlockId const& _exitBlock) + { + if (explored.count(_exitBlock) == 0) + { + explored.insert(_exitBlock); + toVisit.emplace_back(_exitBlock); + } + } + ); + } + } + + void printFunction(SSACFG const& _cfg, size_t const _functionIndex, Scope::Function const& _fun) + { + static auto constexpr returnsTransform = [](auto const& functionReturnValue) { return functionReturnValue.get().name.str(); }; + static auto constexpr argsTransform = [](auto const& arg) { return fmt::format("v{}", std::get<1>(arg).value); }; + m_result << "FunctionEntry_" << _fun.name.str() << "_" << _cfg.entry.value << " [label=\""; + if (!_cfg.returns.empty()) + m_result << fmt::format("function {0}:\n {1} := {0}({2})", _fun.name.str(), fmt::join(_cfg.returns | ranges::views::transform(returnsTransform), ", "), fmt::join(_cfg.arguments | ranges::views::transform(argsTransform), ", ")); + else + m_result << fmt::format("function {0}:\n {0}({1})", _fun.name.str(), fmt::join(_cfg.arguments | ranges::views::transform(argsTransform), ", ")); + m_result << "\"];\n"; + m_result << "FunctionEntry_" << _fun.name.str() << "_" << _cfg.entry.value << " -> Block" << _functionIndex << "_" << _cfg.entry.value << ";\n"; + printBlock(_cfg, _cfg.entry, _functionIndex); + } + + std::stringstream m_result{}; +}; +} + +std::string SSACFG::toDot(bool _includeDiGraphDefinition, std::optional _functionIndex) const +{ + std::ostringstream output; + if (_includeDiGraphDefinition) + output << "digraph SSACFG {\nnodesep=0.7;\ngraph[fontname=\"DejaVu Sans\"]\nnode[shape=box,fontname=\"DejaVu Sans\"];\n\n"; + if (function) + output << SSACFGPrinter(*this, _functionIndex ? *_functionIndex : static_cast(1), *function); + else + output << SSACFGPrinter(*this, entry); + if (_includeDiGraphDefinition) + output << "}\n"; + return output.str(); +} diff --git a/libyul/backends/evm/SSAControlFlowGraph.h b/libyul/backends/evm/SSAControlFlowGraph.h index f4d0ec24232b..fd24f06cbb2b 100644 --- a/libyul/backends/evm/SSAControlFlowGraph.h +++ b/libyul/backends/evm/SSAControlFlowGraph.h @@ -206,6 +206,8 @@ class SSACFG yulAssert(it->second.value < m_valueInfos.size()); return it->second; } + + std::string toDot(bool _includeDiGraphDefinition=true, std::optional _functionIndex=std::nullopt) const; private: std::deque m_valueInfos; std::map m_literals; diff --git a/test/libyul/SSAControlFlowGraphTest.cpp b/test/libyul/SSAControlFlowGraphTest.cpp index e12751411c13..1deaaa7f6448 100644 --- a/test/libyul/SSAControlFlowGraphTest.cpp +++ b/test/libyul/SSAControlFlowGraphTest.cpp @@ -27,12 +27,6 @@ #include #include -#include - -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wtautological-compare" -#include -#pragma GCC diagnostic pop #ifdef ISOLTEST #include @@ -58,203 +52,6 @@ SSAControlFlowGraphTest::SSAControlFlowGraphTest(std::string const& _filename): m_expectation = m_reader.simpleExpectations(); } -class SSACFGPrinter -{ -public: - SSACFGPrinter(SSACFG const& _cfg, SSACFG::BlockId _blockId) - { - printBlock(_cfg, _blockId, 0); - } - SSACFGPrinter(SSACFG const& _cfg, size_t _functionIndex, Scope::Function const& _function) - { - printFunction(_cfg, _functionIndex, _function); - } - friend std::ostream& operator<<(std::ostream& stream, SSACFGPrinter const& printer) { - stream << printer.m_result.str(); - return stream; - } -private: - std::string varToString(SSACFG const& _cfg, SSACFG::ValueId _var) { - if (_var.value == std::numeric_limits::max()) - return "INVALID"; - auto const& info = _cfg.valueInfo(_var); - return std::visit( - util::GenericVisitor{ - [&](SSACFG::UnreachableValue const&) -> std::string { - return "[unreachable]"; - }, - [&](SSACFG::PhiValue const&) -> std::string { - return fmt::format("v{}", _var.value); - }, - [&](SSACFG::VariableValue const&) -> std::string { - return fmt::format("v{}", _var.value); - }, - [&](SSACFG::LiteralValue const& _literal) -> std::string { - return util::formatNumberReadable(_literal.value); - } - }, - info - ); - } - - std::string formatPhi(SSACFG const& _cfg, SSACFG::PhiValue const& _phiValue) - { - auto const transform = [&](SSACFG::ValueId const& valueId) { return varToString(_cfg, valueId); }; - std::vector formattedArgs; - formattedArgs.reserve(_phiValue.arguments.size()); - for(auto const& [arg, entry] : ranges::zip_view(_phiValue.arguments | ranges::views::transform(transform), _cfg.block(_phiValue.block).entries)) - { - formattedArgs.push_back(fmt::format("Block {} => {}", entry.value, arg)); - } - return fmt::format("φ(\\l\\\n\t{}\\l\\\n)", fmt::join(formattedArgs, ",\\l\\\n\t")); - } - - void writeBlock(SSACFG const& _cfg, SSACFG::BlockId const& _id, SSACFG::BasicBlock const& _block, size_t _functionIndex) - { - auto const transform = [&](SSACFG::ValueId const& valueId) { return varToString(_cfg, valueId); }; - bool entryBlock = _id.value == 0 && _functionIndex == 0; - if (entryBlock) - { - m_result << fmt::format("Entry{} [label=\"Entry\"];\n", _functionIndex); - m_result << fmt::format("Entry{} -> Block{}_{};\n", _functionIndex, _functionIndex, _id.value); - } - { - m_result << fmt::format("Block{1}_{0} [label=\"\\\nBlock {0}\\n", _id.value, _functionIndex); - for (auto const& phi : _block.phis) - { - auto const* phiValue = std::get_if(&_cfg.valueInfo(phi)); - solAssert(phiValue); - m_result << fmt::format("v{} := {}\\l\\\n", phi.value, formatPhi(_cfg, *phiValue)); - } - for (auto const& operation : _block.operations) - { - std::string const label = std::visit(util::GenericVisitor{ - [&](SSACFG::Call const& _call) { - return _call.function.get().name.str(); - }, - [&](SSACFG::BuiltinCall const& _call) { - return _call.builtin.get().name.str(); - }, - }, operation.kind); - if (operation.outputs.empty()) - m_result << fmt::format( - "{}({})\\l\\\n", - label, - fmt::join(operation.inputs | ranges::views::transform(transform), ", ") - ); - else - m_result << fmt::format( - "{} := {}({})\\l\\\n", - fmt::join(operation.outputs | ranges::views::transform(transform), ", "), - label, - fmt::join(operation.inputs | ranges::views::transform(transform), ", ") - ); - } - m_result << "\"];\n"; - std::visit(util::GenericVisitor{ - [&](SSACFG::BasicBlock::MainExit const&) - { - m_result << fmt::format("Block{}_{}Exit [label=\"MainExit\"];\n", _functionIndex, _id.value); - m_result << fmt::format("Block{1}_{0} -> Block{1}_{0}Exit;\n", _id.value, _functionIndex); - }, - [&](SSACFG::BasicBlock::Jump const& _jump) - { - m_result << fmt::format("Block{1}_{0} -> Block{1}_{0}Exit [arrowhead=none];\n", _id.value, _functionIndex); - m_result << fmt::format("Block{}_{}Exit [label=\"Jump\" shape=oval];\n", _functionIndex, _id.value); - m_result << fmt::format("Block{}_{}Exit -> Block{}_{};\n", _functionIndex, _id.value, _functionIndex, _jump.target.value); - }, - [&](SSACFG::BasicBlock::ConditionalJump const& _conditionalJump) - { - m_result << "Block" << _functionIndex << "_" << _id.value << " -> Block" << _functionIndex << "_" << _id.value << "Exit;\n"; - m_result << "Block" << _functionIndex << "_" << _id.value << "Exit [label=\"{ If "; - m_result << varToString(_cfg, _conditionalJump.condition); - m_result << "| { <0> Zero | <1> NonZero }}\" shape=Mrecord];\n"; - m_result << "Block" << _functionIndex << "_" << _id.value; - m_result << "Exit:0 -> Block" << _functionIndex << "_" << _conditionalJump.zero.value << ";\n"; - m_result << "Block" << _functionIndex << "_" << _id.value; - m_result << "Exit:1 -> Block" << _functionIndex << "_" << _conditionalJump.nonZero.value << ";\n"; - }, - [&](SSACFG::BasicBlock::JumpTable const& jt) - { - m_result << "Block" << _functionIndex << "_" << _id.value << " -> Block" << _functionIndex << "_" << _id.value << "Exit;\n"; - std::string options; - for(const auto& jumpCase : jt.cases) - { - if (!options.empty()) - options += " | "; - options += fmt::format("<{0}> {0}", formatNumber(jumpCase.first)); - } - if (!options.empty()) - options += " | "; - options += " default"; - m_result << fmt::format("Block{}_{}Exit [label=\"{{ JT | {{ {} }} }}\" shape=Mrecord];\n", _functionIndex, _id.value, options); - for(const auto& jumpCase : jt.cases) - { - m_result << fmt::format("Block{}_{}Exit:{} -> Block{}_{};\n", _functionIndex, _id.value, formatNumber(jumpCase.first), _functionIndex, jumpCase.second.value); - } - m_result << fmt::format("Block{}_{}Exit:default -> Block{}_{};\n", _functionIndex, _id.value, _functionIndex, jt.defaultCase.value); - }, - [&](SSACFG::BasicBlock::FunctionReturn const& fr) - { - m_result << "Block" << _functionIndex << "_" << _id.value << "Exit [label=\"FunctionReturn[" - << fmt::format("{}", fmt::join(fr.returnValues | ranges::views::transform(transform), ", ")) - << "]\"];\n"; - m_result << "Block" << _functionIndex << "_" << _id.value << " -> Block" << _functionIndex << "_" << _id.value << "Exit;\n"; - }, - [&](SSACFG::BasicBlock::Terminated const&) - { - m_result << "Block" << _functionIndex << "_" << _id.value << "Exit [label=\"Terminated\"];\n"; - m_result << "Block" << _functionIndex << "_" << _id.value << " -> Block" << _functionIndex << "_" << _id.value << "Exit;\n"; - } - }, _block.exit); - } - - } - - void printBlock(SSACFG const& _cfg, SSACFG::BlockId const& _rootId, size_t _functionIndex) - { - std::set explored{}; - explored.insert(_rootId); - - std::deque toVisit{}; - toVisit.emplace_back(_rootId); - - while(!toVisit.empty()) - { - auto const id = toVisit.front(); - toVisit.pop_front(); - auto const& block = _cfg.block(id); - writeBlock(_cfg, id, block, _functionIndex); - block.forEachExit( - [&](SSACFG::BlockId const& _exitBlock) - { - if (explored.count(_exitBlock) == 0) - { - explored.insert(_exitBlock); - toVisit.emplace_back(_exitBlock); - } - } - ); - } - } - - void printFunction(SSACFG const& _cfg, size_t _functionIndex, Scope::Function const& _fun) - { - static auto constexpr returnsTransform = [](auto const& functionReturnValue) { return functionReturnValue.get().name.str(); }; - static auto constexpr argsTransform = [](auto const& arg) { return fmt::format("v{}", std::get<1>(arg).value); }; - m_result << "FunctionEntry_" << _fun.name.str() << "_" << _cfg.entry.value << " [label=\""; - if (!_cfg.returns.empty()) - m_result << fmt::format("function {0}:\n {1} := {0}({2})", _fun.name.str(), fmt::join(_cfg.returns | ranges::views::transform(returnsTransform), ", "), fmt::join(_cfg.arguments | ranges::views::transform(argsTransform), ", ")); - else - m_result << fmt::format("function {0}:\n {0}({1})", _fun.name.str(), fmt::join(_cfg.arguments | ranges::views::transform(argsTransform), ", ")); - m_result << "\"];\n"; - m_result << "FunctionEntry_" << _fun.name.str() << "_" << _cfg.entry.value << " -> Block" << _functionIndex << "_" << _cfg.entry.value << ";\n"; - printBlock(_cfg, _cfg.entry, _functionIndex); - } - - std::stringstream m_result{}; -}; - TestCase::TestResult SSAControlFlowGraphTest::run(std::ostream& _stream, std::string const& _linePrefix, bool const _formatted) { ErrorList errors; @@ -275,10 +72,10 @@ TestCase::TestResult SSAControlFlowGraphTest::run(std::ostream& _stream, std::st ); output << "digraph SSACFG {\nnodesep=0.7;\ngraph[fontname=\"DejaVu Sans\"]\nnode[shape=box,fontname=\"DejaVu Sans\"];\n\n"; - output << SSACFGPrinter(*controlFlow->mainGraph, SSACFG::BlockId{0}); + output << controlFlow->mainGraph->toDot(false); size_t index = 1; for (auto const& [function, functionGraph]: controlFlow->functionGraphMapping) - output << SSACFGPrinter(*functionGraph, index++, *function); + output << functionGraph->toDot(false, index++); output << "}\n"; m_obtainedResult = output.str(); @@ -314,5 +111,4 @@ TestCase::TestResult SSAControlFlowGraphTest::run(std::ostream& _stream, std::st #endif return result; - } From 573d7d8f31c59096925e46c01b69348bc124b7ff Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Wed, 18 Sep 2024 10:16:32 +0200 Subject: [PATCH 0424/1022] Yul: Add toDot to ControlFlow --- libyul/backends/evm/ControlFlow.h | 12 ++++++++++++ test/libyul/SSAControlFlowGraphTest.cpp | 13 ++----------- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/libyul/backends/evm/ControlFlow.h b/libyul/backends/evm/ControlFlow.h index 18b43431a16f..59bc1b677b57 100644 --- a/libyul/backends/evm/ControlFlow.h +++ b/libyul/backends/evm/ControlFlow.h @@ -38,6 +38,18 @@ struct ControlFlow return std::get<1>(*it); return nullptr; } + + std::string toDot() const + { + std::ostringstream output; + output << "digraph SSACFG {\nnodesep=0.7;\ngraph[fontname=\"DejaVu Sans\"]\nnode[shape=box,fontname=\"DejaVu Sans\"];\n\n"; + output << mainGraph->toDot(false); + size_t index = 1; + for (auto const& [function, functionGraph]: functionGraphMapping) + output << functionGraph->toDot(false, index++); + output << "}\n"; + return output.str(); + } }; } diff --git a/test/libyul/SSAControlFlowGraphTest.cpp b/test/libyul/SSAControlFlowGraphTest.cpp index 1deaaa7f6448..a316356dbf0f 100644 --- a/test/libyul/SSAControlFlowGraphTest.cpp +++ b/test/libyul/SSAControlFlowGraphTest.cpp @@ -62,8 +62,6 @@ TestCase::TestResult SSAControlFlowGraphTest::run(std::ostream& _stream, std::st return TestResult::FatalError; } - std::ostringstream output; - auto info = AsmAnalyzer::analyzeStrictAssertCorrect(*m_dialect, *object); std::unique_ptr controlFlow = SSAControlFlowGraphBuilder::build( info, @@ -71,14 +69,7 @@ TestCase::TestResult SSAControlFlowGraphTest::run(std::ostream& _stream, std::st object->code()->root() ); - output << "digraph SSACFG {\nnodesep=0.7;\ngraph[fontname=\"DejaVu Sans\"]\nnode[shape=box,fontname=\"DejaVu Sans\"];\n\n"; - output << controlFlow->mainGraph->toDot(false); - size_t index = 1; - for (auto const& [function, functionGraph]: controlFlow->functionGraphMapping) - output << functionGraph->toDot(false, index++); - output << "}\n"; - - m_obtainedResult = output.str(); + m_obtainedResult = controlFlow->toDot(); auto result = checkResult(_stream, _linePrefix, _formatted); @@ -100,7 +91,7 @@ TestCase::TestResult SSAControlFlowGraphTest::run(std::ostream& _stream, std::st boost::process::opstream pipe; boost::process::child child(graphDisplayer, boost::process::std_in < pipe); - pipe << output.str(); + pipe << m_obtainedResult; pipe.flush(); pipe.pipe().close(); if (result == TestResult::Success) From 515f8ab6c5d9c01203e2499ea5c91a5bb0324b9c Mon Sep 17 00:00:00 2001 From: Nikola Matic Date: Wed, 18 Sep 2024 09:26:19 +0200 Subject: [PATCH 0425/1022] Bump all CI jobs to use Ubuntu 22.04 images --- .circleci/config.yml | 74 ++++++++++++++++++++++---------------------- 1 file changed, 37 insertions(+), 37 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 931ce476a347..d93fc20c0596 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -973,7 +973,7 @@ jobs: - matrix_notify_failure_unless_pr chk_pylint: - <<: *base_ubuntu2204_small + <<: *base_ubuntu2404_small steps: - checkout - run: pylint --version @@ -1012,21 +1012,21 @@ jobs: - matrix_notify_failure_unless_pr chk_proofs: - <<: *base_ubuntu2204_small + <<: *base_ubuntu2404_small steps: - checkout - run_proofs - matrix_notify_failure_unless_pr chk_docs_pragma_min_version: - <<: *base_ubuntu2204_small + <<: *base_ubuntu2404_small steps: - checkout - run_docs_pragma_min_version - matrix_notify_failure_unless_pr t_ubu_pyscripts: - <<: *base_ubuntu2204_small + <<: *base_ubuntu2404_small steps: - checkout - run: @@ -1053,25 +1053,25 @@ jobs: b_ubu: &b_ubu # this runs 2x faster on xlarge but takes 4x more resources (compared to medium). # Enough other jobs depend on it that it's worth it though. - <<: *base_ubuntu2204_xlarge + <<: *base_ubuntu2404_xlarge steps: - build # x64 ASAN build, for testing for memory related bugs b_ubu_asan: &b_ubu_asan # Runs slightly faster on large and xlarge but we only run it nightly so efficiency matters more. - <<: *base_ubuntu2204 + <<: *base_ubuntu2404 environment: - <<: *base_ubuntu2204_env + <<: *base_ubuntu2404_env CMAKE_OPTIONS: -DSANITIZE=address CMAKE_BUILD_TYPE: Release steps: - build b_ubu_clang: &b_ubu_clang - <<: *base_ubuntu2204_clang_large + <<: *base_ubuntu2404_clang_large environment: - <<: *base_ubuntu2204_clang_large_env + <<: *base_ubuntu2404_clang_large_env MAKEFLAGS: -j 10 steps: - build @@ -1081,9 +1081,9 @@ jobs: parameters: cmake_options: type: string - <<: *base_ubuntu2204_clang + <<: *base_ubuntu2404_clang environment: - <<: *base_ubuntu2204_clang_env + <<: *base_ubuntu2404_clang_env CMAKE_OPTIONS: << parameters.cmake_options >> steps: - build @@ -1091,7 +1091,7 @@ jobs: b_ubu_force_release: &b_ubu_force_release <<: *b_ubu environment: - <<: *base_ubuntu2204_xlarge_env + <<: *base_ubuntu2404_xlarge_env FORCE_RELEASE: ON b_ubu_static: @@ -1101,7 +1101,7 @@ jobs: # On large runs 2x faster than on medium. 3x on xlarge. <<: *base_ubuntu2004_xlarge environment: - <<: *base_ubuntu2204_xlarge_env + <<: *base_ubuntu2004_xlarge_env CMAKE_OPTIONS: -DCMAKE_BUILD_TYPE=Release -DUSE_Z3_DLOPEN=ON -DSOLC_STATIC_STDLIBS=ON steps: - checkout @@ -1121,9 +1121,9 @@ jobs: b_ubu_codecov: # Runs ~30% faster on large but we only run it nightly so efficiency matters more. - <<: *base_ubuntu2204 + <<: *base_ubuntu2404 environment: - <<: *base_ubuntu2204_env + <<: *base_ubuntu2404_env COVERAGE: ON CMAKE_BUILD_TYPE: Debug steps: @@ -1133,9 +1133,9 @@ jobs: - matrix_notify_failure_unless_pr t_ubu_codecov: - <<: *base_ubuntu2204_large + <<: *base_ubuntu2404_large environment: - <<: *base_ubuntu2204_large_env + <<: *base_ubuntu2404_large_env EVM: << pipeline.parameters.evm-version >> OPTIMIZE: 1 steps: @@ -1158,9 +1158,9 @@ 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: - <<: *base_ubuntu2204_large + <<: *base_ubuntu2404_large environment: - <<: *base_ubuntu2204_large_env + <<: *base_ubuntu2404_large_env CMAKE_BUILD_TYPE: Debug CMAKE_OPTIONS: -DCMAKE_CXX_STANDARD=20 MAKEFLAGS: -j 10 @@ -1280,7 +1280,7 @@ jobs: - matrix_notify_failure_unless_pr b_docs: - <<: *base_ubuntu2204_small + <<: *base_ubuntu2404_small steps: - checkout - setup_prerelease_commit_hash @@ -1299,7 +1299,7 @@ jobs: - soltest_all t_ubu_soltest_deprecated_evm_versions: &t_ubu_soltest_deprecated_evm_versions - <<: *base_ubuntu2204_large + <<: *base_ubuntu2404_large parallelism: 50 steps: - checkout @@ -1313,7 +1313,7 @@ jobs: - matrix_notify_failure_unless_pr t_ubu_lsp: &t_ubu_lsp - <<: *base_ubuntu2204_small + <<: *base_ubuntu2404_small steps: - test_lsp @@ -1362,7 +1362,7 @@ jobs: <<: *t_ubu_cli t_ubu_locale: - <<: *base_ubuntu2204_small + <<: *base_ubuntu2404_small steps: - checkout - attach_workspace: @@ -1372,10 +1372,10 @@ jobs: t_ubu_asan_cli: # Runs slightly faster on medium but we only run it nightly so efficiency matters more. - <<: *base_ubuntu2204 + <<: *base_ubuntu2404 parallelism: 8 # Should match number of tests in .circleci/parallel_cli_tests.py environment: - <<: *base_ubuntu2204_env + <<: *base_ubuntu2404_env 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 # Suppress CLN memory leak. # See: https://github.com/ethereum/solidity/issues/13891 for details. @@ -1384,10 +1384,10 @@ jobs: - cmdline_tests t_ubu_asan_soltest: - <<: *base_ubuntu2204 + <<: *base_ubuntu2404 parallelism: 20 environment: - <<: *base_ubuntu2204_env + <<: *base_ubuntu2404_env EVM: << pipeline.parameters.evm-version >> OPTIMIZE: 0 SOLTEST_FLAGS: --no-smt @@ -1399,10 +1399,10 @@ jobs: - soltest t_ubu_asan_clang_soltest: - <<: *base_ubuntu2204_clang + <<: *base_ubuntu2404_clang parallelism: 20 environment: - <<: *base_ubuntu2204_clang_env + <<: *base_ubuntu2404_clang_env EVM: << pipeline.parameters.evm-version >> OPTIMIZE: 0 SOLTEST_FLAGS: --no-smt @@ -1411,24 +1411,24 @@ jobs: - soltest t_ubu_ubsan_clang_soltest: - <<: *base_ubuntu2204_clang + <<: *base_ubuntu2404_clang parallelism: 20 environment: - <<: *base_ubuntu2204_clang_env + <<: *base_ubuntu2404_clang_env EVM: << pipeline.parameters.evm-version >> SOLTEST_FLAGS: --no-smt steps: - soltest t_ubu_ubsan_clang_cli: - <<: *base_ubuntu2204_clang + <<: *base_ubuntu2404_clang parallelism: 8 # Should match number of tests in .circleci/parallel_cli_tests.py steps: - cmdline_tests t_ems_solcjs: # Unlike other t_ems jobs this one actually runs 2x faster on medium (compared to small). - <<: *base_ubuntu2204 + <<: *base_ubuntu2404 steps: - checkout - attach_workspace: @@ -1747,7 +1747,7 @@ jobs: parameters: preset: type: string - <<: *base_ubuntu2204_small + <<: *base_ubuntu2404_small parallelism: 2 # For prepare_bytecode_report steps: - checkout @@ -1832,9 +1832,9 @@ jobs: preset: "<< parameters.preset >>" t_bytecode_compare: - <<: *base_ubuntu2204_small + <<: *base_ubuntu2404_small environment: - <<: *base_ubuntu2204_small_env + <<: *base_ubuntu2404_small_env <<: *bytecode_compare_env_presets steps: - checkout @@ -1848,7 +1848,7 @@ jobs: - matrix_notify_failure_unless_pr c_release_binaries: - <<: *base_ubuntu2204 + <<: *base_ubuntu2404 steps: - checkout - attach_workspace: From 38fd087a91340c888f7262f84c3c039facd06679 Mon Sep 17 00:00:00 2001 From: Nikola Matic Date: Wed, 18 Sep 2024 10:06:44 +0200 Subject: [PATCH 0426/1022] Fix pip issues for 24.04 --- docs/docs.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/docs/docs.sh b/docs/docs.sh index f2c566761228..abe4921e306c 100755 --- a/docs/docs.sh +++ b/docs/docs.sh @@ -31,5 +31,8 @@ set -euo pipefail script_dir="$(dirname "$0")" cd "${script_dir}" -pip3 install -r requirements.txt --upgrade --upgrade-strategy eager +# TODO `--ignore-installed` now fixes an issue where pip tries to uninstall a Debian installed package, but is unable to +# TODO since Debian has decided to not use the RECORD file, which then breaks pip. +# TODO https://github.com/pypa/pip/issues/11631 and https://bugs.launchpad.net/ubuntu/+source/wheel/+bug/2063151 +pip3 install -r requirements.txt --ignore-installed --upgrade --upgrade-strategy eager sphinx-build -nW -b html -d _build/doctrees . _build/html From 10f2e601de02b32dd89033baa315fdc44b849ca5 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Thu, 12 Sep 2024 13:27:52 +0200 Subject: [PATCH 0427/1022] Yul: Fix removal of trivial phi functions in SSA CFG Builder --- .../evm/SSAControlFlowGraphBuilder.cpp | 280 ++++++------------ .../backends/evm/SSAControlFlowGraphBuilder.h | 3 +- .../libyul/yulSSAControlFlowGraph/complex.yul | 6 +- .../yulSSAControlFlowGraph/complex2.yul | 4 +- 4 files changed, 94 insertions(+), 199 deletions(-) diff --git a/libyul/backends/evm/SSAControlFlowGraphBuilder.cpp b/libyul/backends/evm/SSAControlFlowGraphBuilder.cpp index d9dc7663ccec..2579b9064dfe 100644 --- a/libyul/backends/evm/SSAControlFlowGraphBuilder.cpp +++ b/libyul/backends/evm/SSAControlFlowGraphBuilder.cpp @@ -33,30 +33,54 @@ #include #include #include -#include #include #include #include -#include using namespace solidity; using namespace solidity::yul; -namespace +namespace solidity::yul { -SSACFG::ValueId tryRemoveTrivialPhi(SSACFG& _cfg, SSACFG::ValueId _phi) + +SSAControlFlowGraphBuilder::SSAControlFlowGraphBuilder( + SSACFG& _graph, + AsmAnalysisInfo const& _analysisInfo, + Dialect const& _dialect +): + m_graph(_graph), + m_info(_analysisInfo), + m_dialect(_dialect) +{ +} + +std::unique_ptr SSAControlFlowGraphBuilder::build( + AsmAnalysisInfo const& _analysisInfo, + Dialect const& _dialect, + Block const& _block +) +{ + ControlFlowSideEffectsCollector sideEffects(_dialect, _block); + + auto result = std::make_unique(); + auto functions = buildMainGraph(*result->mainGraph, _analysisInfo, _dialect, _block); + buildFunctionGraphs(*result, _analysisInfo, sideEffects, _dialect, functions); + return result; +} + +SSACFG::ValueId SSAControlFlowGraphBuilder::tryRemoveTrivialPhi(SSACFG::ValueId _phi) { // TODO: double-check if this is sane - auto* phiInfo = std::get_if(&_cfg.valueInfo(_phi)); + auto const* phiInfo = std::get_if(&m_graph.valueInfo(_phi)); yulAssert(phiInfo); SSACFG::ValueId same; for (SSACFG::ValueId arg: phiInfo->arguments) { if (arg == same || arg == _phi) - continue; + continue; // unique value or self-reference if (same.hasValue()) - return _phi; + return _phi; // phi merges at least two distinct values -> not trivial same = arg; } @@ -65,30 +89,26 @@ SSACFG::ValueId tryRemoveTrivialPhi(SSACFG& _cfg, SSACFG::ValueId _phi) size_t inputIndex = std::numeric_limits::max(); }; std::vector uses; - std::vector visited; std::vector phiUses; - auto isVisited = [&](SSACFG::BlockId _block) -> bool { - if (_block.value < visited.size()) - return visited.at(_block.value); - else - return false; - }; - auto markVisited = [&](SSACFG::BlockId _block) { - if (visited.size() <= _block.value) - visited.resize(_block.value + 1); - visited[_block.value] = true; - }; - // does this even need to be recursive? or can uses only be in the same or neighbouring blocks? - auto findUses = [&](SSACFG::BlockId _blockId, auto _recurse) -> void { - if (isVisited(_blockId)) - return; - markVisited(_blockId); - auto& block = _cfg.block(_blockId); + + if (!same.hasValue()) + { + // This will happen for unreachable paths. + // TODO: check how best to deal with this + same = m_graph.unreachableValue(); + } + + auto phiBlock = phiInfo->block; + m_graph.block(phiBlock).phis.erase(_phi); + + for (size_t blockIdValue = 0; blockIdValue < m_graph.numBlocks(); ++blockIdValue) + { + auto& block = m_graph.block(SSACFG::BlockId{blockIdValue}); for (auto blockPhi: block.phis) { if (blockPhi == _phi) continue; - auto const* blockPhiInfo = std::get_if(&_cfg.valueInfo(blockPhi)); + auto const* blockPhiInfo = std::get_if(&m_graph.valueInfo(blockPhi)); yulAssert(blockPhiInfo); bool usedInPhi = false; for (auto input: blockPhiInfo->arguments) @@ -112,45 +132,45 @@ SSACFG::ValueId tryRemoveTrivialPhi(SSACFG& _cfg, SSACFG::ValueId _phi) if (input == _phi) uses.emplace_back(Use{std::ref(op), n}); } - block.forEachExit([&](SSACFG::BlockId _block) { - _recurse(_block, _recurse); - }); - }; - auto phiBlock = phiInfo->block; - _cfg.block(phiBlock).phis.erase(_phi); - findUses(phiBlock, findUses); - - if (!same.hasValue()) - { - // This will happen for unreachable paths. - // TODO: check how best to deal with this - same = _cfg.unreachableValue(); + // todo check if it is sound to set "unreachable" return values to literal 0 + if (auto* functionReturn = std::get_if(&block.exit)) + std::replace( + functionReturn->returnValues.begin(), + functionReturn->returnValues.end(), + _phi, + same == m_graph.unreachableValue() ? m_graph.newLiteral(block.debugData, 0) : same + ); } - for (auto& use: uses) use.operation.get().inputs.at(use.inputIndex) = same; for (auto phiUse: phiUses) { - auto* blockPhiInfo = std::get_if(&_cfg.valueInfo(phiUse)); + auto* blockPhiInfo = std::get_if(&m_graph.valueInfo(phiUse)); yulAssert(blockPhiInfo); for (auto& arg: blockPhiInfo->arguments) if (arg == _phi) arg = same; } + for (auto& [_, currentVariableDefs]: m_currentDef) + { + for (auto& def: currentVariableDefs) + if (def && *def == _phi) + def = same; + } for (auto phiUse: phiUses) - tryRemoveTrivialPhi(_cfg, phiUse); + tryRemoveTrivialPhi(phiUse); return same; } /// Removes edges to blocks that are not reachable. -void cleanUnreachable(SSACFG& _cfg) +void SSAControlFlowGraphBuilder::cleanUnreachable() { // Determine which blocks are reachable from the entry. - util::BreadthFirstSearch reachabilityCheck{{_cfg.entry}}; + util::BreadthFirstSearch reachabilityCheck{{m_graph.entry}}; reachabilityCheck.run([&](SSACFG::BlockId _blockId, auto&& _addChild) { - auto const& block = _cfg.block(_blockId); + auto const& block = m_graph.block(_blockId); visit(util::GenericVisitor{ [&](SSACFG::BasicBlock::Jump const& _jump) { _addChild(_jump.target); @@ -167,14 +187,14 @@ void cleanUnreachable(SSACFG& _cfg) }); auto isUnreachableValue = [&](SSACFG::ValueId const& _value) -> bool { - auto* valueInfo = std::get_if(&_cfg.valueInfo(_value)); + auto* valueInfo = std::get_if(&m_graph.valueInfo(_value)); return (valueInfo) ? true : false; }; // Remove all entries from unreachable nodes from the graph. for (SSACFG::BlockId blockId: reachabilityCheck.visited) { - auto& block = _cfg.block(blockId); + auto& block = m_graph.block(blockId); std::set maybeTrivialPhi; for (auto it = block.entries.begin(); it != block.entries.end();) @@ -183,7 +203,7 @@ void cleanUnreachable(SSACFG& _cfg) else it = block.entries.erase(it); for (auto phi: block.phis) - if (auto* phiInfo = std::get_if(&_cfg.valueInfo(phi))) + if (auto* phiInfo = std::get_if(&m_graph.valueInfo(phi))) cxx20::erase_if(phiInfo->arguments, [&](SSACFG::ValueId _arg) { if (isUnreachableValue(_arg)) { @@ -195,44 +215,10 @@ void cleanUnreachable(SSACFG& _cfg) // After removing a phi argument, we might end up with a trivial phi that can be removed. for (auto phi: maybeTrivialPhi) - tryRemoveTrivialPhi(_cfg, phi); + tryRemoveTrivialPhi(phi); } } -} - -namespace solidity::yul -{ - -SSAControlFlowGraphBuilder::SSAControlFlowGraphBuilder( - SSACFG& _graph, - AsmAnalysisInfo const& _analysisInfo, - Dialect const& _dialect -): - m_graph(_graph), - m_info(_analysisInfo), - m_dialect(_dialect) -{ -} - -std::unique_ptr SSAControlFlowGraphBuilder::build( - AsmAnalysisInfo const& _analysisInfo, - Dialect const& _dialect, - Block const& _block -) -{ - ControlFlowSideEffectsCollector sideEffects(_dialect, _block); - - auto result = std::make_unique(); - auto functions = buildMainGraph(*result->mainGraph, _analysisInfo, _dialect, _block); - buildFunctionGraphs(*result, _analysisInfo, sideEffects, _dialect, functions); - - cleanUnreachable(*result->mainGraph); - for (auto& functionGraph: result->functionGraphs) - cleanUnreachable(*functionGraph); - return result; -} - void SSAControlFlowGraphBuilder::buildFunctionGraphs( ControlFlow& _controlFlow, AsmAnalysisInfo const& _info, @@ -276,6 +262,7 @@ void SSAControlFlowGraphBuilder::buildFunctionGraphs( cfg.exits.insert(builder.m_currentBlock); // Artificial explicit function exit (`leave`) at the end of the body. builder(Leave{debugDataOf(*functionDefinition)}); + builder.cleanUnreachable(); } } @@ -293,7 +280,7 @@ std::vector> SSACo if (!builder.blockInfo(builder.m_currentBlock).sealed) builder.sealBlock(builder.m_currentBlock); _cfg.block(builder.m_currentBlock).exit = SSACFG::BasicBlock::MainExit{}; - + builder.cleanUnreachable(); return builder.m_functionDefinitions; } @@ -626,22 +613,27 @@ SSACFG::ValueId SSAControlFlowGraphBuilder::readVariableRecursive(Scope::Variabl auto& block = m_graph.block(_block); auto& info = blockInfo(_block); - if (info.sealed && block.entries.size() == 1) - return readVariable(_variable, *block.entries.begin()); - - SSACFG::ValueId phi = m_graph.newPhi(_block); - block.phis.insert(phi); - if (info.sealed) + SSACFG::ValueId val; + if (!info.sealed) { - writeVariable(_variable, _block, phi); - phi = addPhiOperands(_variable, phi); + // incomplete block + val = m_graph.newPhi(_block); + block.phis.insert(val); + info.incompletePhis.emplace_back(val, std::ref(_variable)); } + else if (block.entries.size() == 1) + // one predecessor: no phi needed + val = readVariable(_variable, *block.entries.begin()); else { - info.incompletePhis.emplace_back(phi, std::ref(_variable)); + // Break potential cycles with operandless phi + val = m_graph.newPhi(_block); + block.phis.insert(val); + writeVariable(_variable, _block, val); + val = addPhiOperands(_variable, val); } - writeVariable(_variable, _block, phi); - return phi; + writeVariable(_variable, _block, val); + return val; } SSACFG::ValueId SSAControlFlowGraphBuilder::addPhiOperands(Scope::Variable const& _variable, SSACFG::ValueId _phi) @@ -653,104 +645,6 @@ SSACFG::ValueId SSAControlFlowGraphBuilder::addPhiOperands(Scope::Variable const return tryRemoveTrivialPhi(_phi); } -SSACFG::ValueId SSAControlFlowGraphBuilder::tryRemoveTrivialPhi(SSACFG::ValueId _phi) -{ - // TODO: double-check if this is sane - yulAssert(std::holds_alternative(m_graph.valueInfo(_phi))); - auto& phiInfo = std::get(m_graph.valueInfo(_phi)); - - SSACFG::ValueId same; - for (SSACFG::ValueId arg: phiInfo.arguments) - { - if (arg == same || arg == _phi) - continue; - if (same.hasValue()) - return _phi; - same = arg; - } - - struct Use { - std::reference_wrapper operation; - size_t inputIndex = std::numeric_limits::max(); - }; - std::vector uses; - std::vector visited; - std::vector phiUses; - auto isVisited = [&](SSACFG::BlockId _block) -> bool { - if (_block.value < visited.size()) - return visited.at(_block.value); - else - return false; - }; - auto markVisited = [&](SSACFG::BlockId _block) { - if (visited.size() <= _block.value) - visited.resize(_block.value + 1); - visited[_block.value] = true; - }; - // does this even need to be recursive? or can uses only be in the same or neighbouring blocks? - auto findUses = [&](SSACFG::BlockId _blockId, auto _recurse) -> void { - if (isVisited(_blockId)) - return; - markVisited(_blockId); - auto& block = m_graph.block(_blockId); - for (auto blockPhi: block.phis) - { - if (blockPhi == _phi) - continue; - auto const* blockPhiInfo = std::get_if(&m_graph.valueInfo(blockPhi)); - yulAssert(blockPhiInfo); - bool usedInPhi = false; - for (auto input: blockPhiInfo->arguments) - { - if (input == _phi) - usedInPhi = true; - } - if (usedInPhi) - phiUses.emplace_back(blockPhi); - } - for (auto& op: block.operations) - { - // TODO: double check when phiVar occurs in outputs here and what to do about it. - if (op.outputs.size() == 1 && op.outputs.front() == _phi) - continue; - // TODO: check if this always hold - and if so if the assertion is really valuable. - for (auto& output: op.outputs) - yulAssert(output != _phi); - - for (auto&& [n, input]: op.inputs | ranges::views::enumerate) - if (input == _phi) - uses.emplace_back(Use{std::ref(op), n}); - } - block.forEachExit([&](SSACFG::BlockId _block) { - _recurse(_block, _recurse); - }); - }; - auto phiBlock = phiInfo.block; - m_graph.block(phiBlock).phis.erase(_phi); - findUses(phiBlock, findUses); - - if (!same.hasValue()) - // This will happen for unreachable paths. - // TODO: check how best to deal with this - same = m_graph.unreachableValue(); - - for (auto& use: uses) - use.operation.get().inputs.at(use.inputIndex) = same; - for (auto phiUse: phiUses) - { - auto* blockPhiInfo = std::get_if(&m_graph.valueInfo(phiUse)); - yulAssert(blockPhiInfo); - for (auto& arg: blockPhiInfo->arguments) - if (arg == _phi) - arg = same; - } - - for (auto phiUse: phiUses) - tryRemoveTrivialPhi(phiUse); - - return same; -} - void SSAControlFlowGraphBuilder::writeVariable(Scope::Variable const& _variable, SSACFG::BlockId _block, SSACFG::ValueId _value) { currentDef(_variable, _block) = _value; diff --git a/libyul/backends/evm/SSAControlFlowGraphBuilder.h b/libyul/backends/evm/SSAControlFlowGraphBuilder.h index 031016219c87..0a2ca8064e91 100644 --- a/libyul/backends/evm/SSAControlFlowGraphBuilder.h +++ b/libyul/backends/evm/SSAControlFlowGraphBuilder.h @@ -73,6 +73,8 @@ class SSAControlFlowGraphBuilder SSACFG::ValueId operator()(Literal const& _literal); private: + void cleanUnreachable(); + SSACFG::ValueId tryRemoveTrivialPhi(SSACFG::ValueId _phi); void assign(std::vector> _variables, Expression const* _expression); std::vector visitFunctionCall(FunctionCall const& _call); @@ -80,7 +82,6 @@ class SSAControlFlowGraphBuilder SSACFG::ValueId readVariable(Scope::Variable const& _variable, SSACFG::BlockId _block); SSACFG::ValueId readVariableRecursive(Scope::Variable const& _variable, SSACFG::BlockId _block); SSACFG::ValueId addPhiOperands(Scope::Variable const& _variable, SSACFG::ValueId _phi); - SSACFG::ValueId tryRemoveTrivialPhi(SSACFG::ValueId _phi); void writeVariable(Scope::Variable const& _variable, SSACFG::BlockId _block, SSACFG::ValueId _value); SSACFG& m_graph; diff --git a/test/libyul/yulSSAControlFlowGraph/complex.yul b/test/libyul/yulSSAControlFlowGraph/complex.yul index d7e16c9f6f99..0d2c958fd027 100644 --- a/test/libyul/yulSSAControlFlowGraph/complex.yul +++ b/test/libyul/yulSSAControlFlowGraph/complex.yul @@ -87,7 +87,7 @@ // Block1_4 [label="\ // Block 4\nsstore(3084, 12)\l\ // "]; -// Block1_4Exit [label="FunctionReturn[v17]"]; +// Block1_4Exit [label="FunctionReturn[0]"]; // Block1_4 -> Block1_4Exit; // Block1_6 [label="\ // Block 6\nsstore(514, 2)\l\ @@ -105,7 +105,7 @@ // Block1_9 [label="\ // Block 9\nsstore(1028, 4)\l\ // "]; -// Block1_9Exit [label="FunctionReturn[v17]"]; +// Block1_9Exit [label="FunctionReturn[0]"]; // Block1_9 -> Block1_9Exit; // Block1_10 [label="\ // Block 10\nv20 := eq(2, v6)\l\ @@ -168,7 +168,7 @@ // Block1_20 [label="\ // Block 20\nsstore(v43, 0)\l\ // "]; -// Block1_20Exit [label="FunctionReturn[v45]"]; +// Block1_20Exit [label="FunctionReturn[0]"]; // Block1_20 -> Block1_20Exit; // Block1_21 [label="\ // Block 21\nsstore(65535, 255)\l\ diff --git a/test/libyul/yulSSAControlFlowGraph/complex2.yul b/test/libyul/yulSSAControlFlowGraph/complex2.yul index 863b021d1e7b..8f3b1bd3f62d 100644 --- a/test/libyul/yulSSAControlFlowGraph/complex2.yul +++ b/test/libyul/yulSSAControlFlowGraph/complex2.yul @@ -121,7 +121,7 @@ // Block1_9 [label="\ // Block 9\nsstore(1028, 4)\l\ // "]; -// Block1_9Exit [label="FunctionReturn[v17]"]; +// Block1_9Exit [label="FunctionReturn[0]"]; // Block1_9 -> Block1_9Exit; // Block1_10 [label="\ // Block 10\nv20 := eq(2, v6)\l\ @@ -184,7 +184,7 @@ // Block1_20 [label="\ // Block 20\nsstore(v43, 0)\l\ // "]; -// Block1_20Exit [label="FunctionReturn[v45]"]; +// Block1_20Exit [label="FunctionReturn[0]"]; // Block1_20 -> Block1_20Exit; // Block1_21 [label="\ // Block 21\nsstore(65535, 255)\l\ From 5fc72695bca7533e1c08981ab7e8bce5f6d58a2b Mon Sep 17 00:00:00 2001 From: Nikola Matic Date: Wed, 18 Sep 2024 12:54:34 +0200 Subject: [PATCH 0428/1022] Remove 22.04 images and docker buildpack deps --- .circleci/README.md | 10 +- .circleci/config.yml | 58 ---------- .github/workflows/buildpack-deps.yml | 4 +- scripts/ci/buildpack-deps_test_ubuntu1804.sh | 1 - .../buildpack-deps_test_ubuntu2204.clang.sh | 1 - scripts/ci/buildpack-deps_test_ubuntu2204.sh | 1 - .../buildpack-deps/Dockerfile.ubuntu2204 | 102 ----------------- .../Dockerfile.ubuntu2204.clang | 103 ------------------ 8 files changed, 6 insertions(+), 274 deletions(-) delete mode 120000 scripts/ci/buildpack-deps_test_ubuntu1804.sh delete mode 120000 scripts/ci/buildpack-deps_test_ubuntu2204.clang.sh delete mode 120000 scripts/ci/buildpack-deps_test_ubuntu2204.sh delete mode 100644 scripts/docker/buildpack-deps/Dockerfile.ubuntu2204 delete mode 100644 scripts/docker/buildpack-deps/Dockerfile.ubuntu2204.clang diff --git a/.circleci/README.md b/.circleci/README.md index 6af7fd45cc3d..22b20bc8c267 100644 --- a/.circleci/README.md +++ b/.circleci/README.md @@ -7,15 +7,15 @@ The docker images are build locally on the developer machine: ```sh cd .circleci/docker/ -docker build -t ethereum/solidity-buildpack-deps:ubuntu2204- -f Dockerfile.ubuntu2204 . -docker push ethereum/solidity-buildpack-deps:ubuntu2204- +docker build -t ethereum/solidity-buildpack-deps:ubuntu2404- -f Dockerfile.ubuntu2404 . +docker push ethereum/solidity-buildpack-deps:ubuntu2404- ``` -The current revisions per docker image are stored in [circle ci pipeline parameters](https://github.com/CircleCI-Public/api-preview-docs/blob/master/docs/pipeline-parameters.md#pipeline-parameters) called `-docker-image-rev` (e.g., `ubuntu-2204-docker-image-rev`). Please update the value assigned to the parameter(s) corresponding to the docker image(s) being updated at the time of the update. Please verify that the value assigned to the parameter matches the revision part of the docker image tag (`` in the docker build/push snippet shown above). Otherwise, the docker image used by circle ci and the one actually pushed to docker hub will differ. +The current revisions per docker image are stored in [circle ci pipeline parameters](https://github.com/CircleCI-Public/api-preview-docs/blob/master/docs/pipeline-parameters.md#pipeline-parameters) called `-docker-image-rev` (e.g., `ubuntu-2404-docker-image-rev`). Please update the value assigned to the parameter(s) corresponding to the docker image(s) being updated at the time of the update. Please verify that the value assigned to the parameter matches the revision part of the docker image tag (`` in the docker build/push snippet shown above). Otherwise, the docker image used by circle ci and the one actually pushed to docker hub will differ. Once the docker image has been built and pushed to Dockerhub, you can find it at: - https://hub.docker.com/r/ethereum/solidity-buildpack-deps:ubuntu2204- + https://hub.docker.com/r/ethereum/solidity-buildpack-deps:ubuntu2404- where the image tag reflects the target OS and revision to build Solidity and run its tests on. @@ -24,7 +24,7 @@ where the image tag reflects the target OS and revision to build Solidity and ru ```sh cd solidity # Mounts your local solidity directory in docker container for testing -docker run -v `pwd`:/src/solidity -ti ethereum/solidity-buildpack-deps:ubuntu2204- /bin/bash +docker run -v `pwd`:/src/solidity -ti ethereum/solidity-buildpack-deps:ubuntu2404- /bin/bash cd /src/solidity ``` diff --git a/.circleci/config.yml b/.circleci/config.yml index d93fc20c0596..18ca18f3c563 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -11,14 +11,6 @@ parameters: type: string # solbuildpackpusher/solidity-buildpack-deps:ubuntu2004-25 default: "solbuildpackpusher/solidity-buildpack-deps@sha256:b3f321fb2d8e7a41ca9328672061c1840e5cd3fb5be503aa158d1c508deacf0a" - ubuntu-2204-docker-image: - type: string - # solbuildpackpusher/solidity-buildpack-deps:ubuntu2204-10 - default: "solbuildpackpusher/solidity-buildpack-deps@sha256:ba2d878c26d681a7d6c1922258b47c2e5dd61d0e46ab4c6a4862b473e61997b6" - ubuntu-2204-clang-docker-image: - type: string - # solbuildpackpusher/solidity-buildpack-deps:ubuntu2204.clang-9 - default: "solbuildpackpusher/solidity-buildpack-deps@sha256:703cdad5fa5c8686a3080ebb1aea1485ded2446561bf56e2945a87f2fa20a446" ubuntu-2404-docker-image: type: string # solbuildpackpusher/solidity-buildpack-deps:ubuntu2404-1 @@ -560,56 +552,6 @@ defaults: MAKEFLAGS: -j 10 CPUs: 10 - - base_ubuntu2204: &base_ubuntu2204 - docker: - - image: << pipeline.parameters.ubuntu-2204-docker-image >> - environment: &base_ubuntu2204_env - TERM: xterm - MAKEFLAGS: -j 3 - CPUs: 3 - - - base_ubuntu2204_clang: &base_ubuntu2204_clang - docker: - - image: << pipeline.parameters.ubuntu-2204-clang-docker-image >> - environment: &base_ubuntu2204_clang_env - TERM: xterm - CC: clang - CXX: clang++ - MAKEFLAGS: -j 3 - CPUs: 3 - - - base_ubuntu2204_clang_large: &base_ubuntu2204_clang_large - <<: *base_ubuntu2204_clang - resource_class: large - environment: &base_ubuntu2204_clang_large_env - <<: *base_ubuntu2204_clang_env - MAKEFLAGS: -j 5 - CPUs: 5 - - - base_ubuntu2204_small: &base_ubuntu2204_small - <<: *base_ubuntu2204 - resource_class: small - environment: &base_ubuntu2204_small_env - <<: *base_ubuntu2204_env - MAKEFLAGS: -j 2 - CPUs: 2 - - - base_ubuntu2204_large: &base_ubuntu2204_large - <<: *base_ubuntu2204 - resource_class: large - environment: &base_ubuntu2204_large_env - <<: *base_ubuntu2204_env - MAKEFLAGS: -j 5 - CPUs: 5 - - - base_ubuntu2204_xlarge: &base_ubuntu2204_xlarge - <<: *base_ubuntu2204 - resource_class: xlarge - environment: &base_ubuntu2204_xlarge_env - <<: *base_ubuntu2204_env - MAKEFLAGS: -j 10 - CPUs: 10 - - base_ubuntu2404: &base_ubuntu2404 docker: - image: << pipeline.parameters.ubuntu-2404-docker-image >> diff --git a/.github/workflows/buildpack-deps.yml b/.github/workflows/buildpack-deps.yml index 1b9555ddc22d..fe6da11e16da 100644 --- a/.github/workflows/buildpack-deps.yml +++ b/.github/workflows/buildpack-deps.yml @@ -7,8 +7,6 @@ on: - 'scripts/docker/buildpack-deps/Dockerfile.emscripten' - 'scripts/docker/buildpack-deps/Dockerfile.ubuntu.clang.ossfuzz' - 'scripts/docker/buildpack-deps/Dockerfile.ubuntu2004' - - 'scripts/docker/buildpack-deps/Dockerfile.ubuntu2204.clang' - - 'scripts/docker/buildpack-deps/Dockerfile.ubuntu2204' - 'scripts/docker/buildpack-deps/Dockerfile.ubuntu2404' - 'scripts/docker/buildpack-deps/Dockerfile.ubuntu2404.clang' @@ -25,7 +23,7 @@ jobs: strategy: fail-fast: false matrix: - image_variant: [emscripten, ubuntu.clang.ossfuzz, ubuntu2004, ubuntu2204.clang, ubuntu2204, ubuntu2404, ubuntu2404.clang] + image_variant: [emscripten, ubuntu.clang.ossfuzz, ubuntu2004, ubuntu2404, ubuntu2404.clang] steps: - uses: actions/checkout@v4 diff --git a/scripts/ci/buildpack-deps_test_ubuntu1804.sh b/scripts/ci/buildpack-deps_test_ubuntu1804.sh deleted file mode 120000 index c07a74de4fb4..000000000000 --- a/scripts/ci/buildpack-deps_test_ubuntu1804.sh +++ /dev/null @@ -1 +0,0 @@ -build.sh \ No newline at end of file diff --git a/scripts/ci/buildpack-deps_test_ubuntu2204.clang.sh b/scripts/ci/buildpack-deps_test_ubuntu2204.clang.sh deleted file mode 120000 index c07a74de4fb4..000000000000 --- a/scripts/ci/buildpack-deps_test_ubuntu2204.clang.sh +++ /dev/null @@ -1 +0,0 @@ -build.sh \ No newline at end of file diff --git a/scripts/ci/buildpack-deps_test_ubuntu2204.sh b/scripts/ci/buildpack-deps_test_ubuntu2204.sh deleted file mode 120000 index c07a74de4fb4..000000000000 --- a/scripts/ci/buildpack-deps_test_ubuntu2204.sh +++ /dev/null @@ -1 +0,0 @@ -build.sh \ No newline at end of file diff --git a/scripts/docker/buildpack-deps/Dockerfile.ubuntu2204 b/scripts/docker/buildpack-deps/Dockerfile.ubuntu2204 deleted file mode 100644 index add03bb00379..000000000000 --- a/scripts/docker/buildpack-deps/Dockerfile.ubuntu2204 +++ /dev/null @@ -1,102 +0,0 @@ -# vim:syntax=dockerfile -#------------------------------------------------------------------------------ -# Dockerfile for building and testing Solidity Compiler on CI -# Target: Ubuntu 19.04 (Disco Dingo) -# URL: https://hub.docker.com/r/ethereum/solidity-buildpack-deps -# -# 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-2019 solidity contributors. -#------------------------------------------------------------------------------ -FROM buildpack-deps:jammy AS base -LABEL version="10" - -ARG DEBIAN_FRONTEND=noninteractive - -RUN set -ex; \ - dist=$(grep DISTRIB_CODENAME /etc/lsb-release | cut -d= -f2); \ - echo "deb http://ppa.launchpad.net/ethereum/cpp-build-deps/ubuntu $dist main" >> /etc/apt/sources.list ; \ - apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 1c52189c923f6ca9 ; \ - apt-get update; \ - apt-get install -qqy --no-install-recommends \ - build-essential \ - cmake \ - jq \ - libboost-filesystem-dev \ - libboost-program-options-dev \ - libboost-system-dev \ - libboost-test-dev \ - libcln-dev \ - libz3-static-dev \ - locales-all \ - lsof \ - ninja-build \ - python3-pip \ - python3-sphinx \ - software-properties-common \ - sudo \ - unzip \ - z3-static \ - zip; \ - pip3 install \ - codecov \ - colorama \ - deepdiff \ - parsec \ - pygments-lexer-solidity \ - pylint \ - requests \ - tabulate \ - z3-solver; - -# Eldarica -RUN set -ex; \ - apt-get update; \ - apt-get install -qqy \ - openjdk-11-jre; \ - eldarica_version="2.1"; \ - wget "https://github.com/uuverifiers/eldarica/releases/download/v${eldarica_version}/eldarica-bin-${eldarica_version}.zip" -O /opt/eld_binaries.zip; \ - test "$(sha256sum /opt/eld_binaries.zip)" = "0ac43f45c0925383c9d2077f62bbb515fd792375f3b2b101b30c9e81dcd7785c /opt/eld_binaries.zip"; \ - unzip /opt/eld_binaries.zip -d /opt; \ - rm -f /opt/eld_binaries.zip; - -# CVC5 -RUN set -ex; \ - cvc5_version="1.1.2"; \ - wget "https://github.com/cvc5/cvc5/releases/download/cvc5-${cvc5_version}/cvc5-Linux-static.zip" -O /opt/cvc5.zip; \ - test "$(sha256sum /opt/cvc5.zip)" = "cf291aef67da8eaa8d425a51f67f3f72f36db8b1040655dc799b64e3d69e6086 /opt/cvc5.zip"; \ - unzip /opt/cvc5.zip -x "cvc5-Linux-static/lib/cmake/*" -d /opt; \ - mv /opt/cvc5-Linux-static/bin/* /usr/bin; \ - mv /opt/cvc5-Linux-static/include/* /usr/include; \ - mv /opt/cvc5-Linux-static/lib/* /usr/lib; \ - rm -rf /opt/cvc5-Linux-static /opt/cvc5.zip; - -FROM base AS libraries - -# EVMONE -RUN set -ex; \ - wget -O /usr/src/evmone.tar.gz https://github.com/ethereum/evmone/releases/download/v0.12.0/evmone-0.12.0-linux-x86_64.tar.gz; \ - test "$(sha256sum /usr/src/evmone.tar.gz)" = "1c7b5eba0c8c3b3b2a7a05101e2d01a13a2f84b323989a29be66285dba4136ce /usr/src/evmone.tar.gz"; \ - cd /usr; \ - tar -xf /usr/src/evmone.tar.gz; \ - rm -rf /usr/src/evmone.tar.gz - -FROM base -COPY --from=libraries /usr/lib /usr/lib -COPY --from=libraries /usr/bin /usr/bin -COPY --from=libraries /usr/include /usr/include -COPY --from=libraries /opt/eldarica /opt/eldarica -ENV PATH="$PATH:/opt/eldarica" diff --git a/scripts/docker/buildpack-deps/Dockerfile.ubuntu2204.clang b/scripts/docker/buildpack-deps/Dockerfile.ubuntu2204.clang deleted file mode 100644 index b9c9158381eb..000000000000 --- a/scripts/docker/buildpack-deps/Dockerfile.ubuntu2204.clang +++ /dev/null @@ -1,103 +0,0 @@ -# vim:syntax=dockerfile -#------------------------------------------------------------------------------ -# Dockerfile for building and testing Solidity Compiler on CI -# Target: Ubuntu 19.04 (Disco Dingo) Clang variant -# URL: https://hub.docker.com/r/ethereum/solidity-buildpack-deps -# -# 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-2019 solidity contributors. -#------------------------------------------------------------------------------ -FROM buildpack-deps:jammy AS base -LABEL version="9" - -ARG DEBIAN_FRONTEND=noninteractive - -RUN set -ex; \ - dist=$(grep DISTRIB_CODENAME /etc/lsb-release | cut -d= -f2); \ - echo "deb http://ppa.launchpad.net/ethereum/cpp-build-deps/ubuntu $dist main" >> /etc/apt/sources.list ; \ - apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 1c52189c923f6ca9 ; \ - apt-get update; \ - apt-get install -qqy --no-install-recommends \ - build-essential \ - clang \ - cmake \ - jq \ - lsof \ - libboost-filesystem-dev \ - libboost-program-options-dev \ - libboost-system-dev \ - libboost-test-dev \ - libcln-dev \ - libz3-static-dev \ - ninja-build \ - python3-pip \ - software-properties-common \ - sudo \ - z3-static; \ - pip3 install \ - codecov \ - colorama \ - deepdiff \ - parsec \ - pygments-lexer-solidity \ - pylint \ - requests \ - tabulate \ - z3-solver; - -# Eldarica -RUN set -ex; \ - apt-get update; \ - apt-get install -qy \ - openjdk-11-jre \ - unzip; \ - eldarica_version="2.1"; \ - wget "https://github.com/uuverifiers/eldarica/releases/download/v${eldarica_version}/eldarica-bin-${eldarica_version}.zip" -O /opt/eld_binaries.zip; \ - test "$(sha256sum /opt/eld_binaries.zip)" = "0ac43f45c0925383c9d2077f62bbb515fd792375f3b2b101b30c9e81dcd7785c /opt/eld_binaries.zip"; \ - unzip /opt/eld_binaries.zip -d /opt; \ - rm -f /opt/eld_binaries.zip; - -# CVC5 -RUN set -ex; \ - cvc5_version="1.1.2"; \ - wget "https://github.com/cvc5/cvc5/releases/download/cvc5-${cvc5_version}/cvc5-Linux-static.zip" -O /opt/cvc5.zip; \ - test "$(sha256sum /opt/cvc5.zip)" = "cf291aef67da8eaa8d425a51f67f3f72f36db8b1040655dc799b64e3d69e6086 /opt/cvc5.zip"; \ - unzip /opt/cvc5.zip -x "cvc5-Linux-static/lib/cmake/*" -d /opt; \ - mv /opt/cvc5-Linux-static/bin/* /usr/bin; \ - mv /opt/cvc5-Linux-static/lib/* /usr/lib; \ - mv /opt/cvc5-Linux-static/include/* /usr/include; \ - rm -rf /opt/cvc5-Linux-static /opt/cvc5.zip; - -FROM base AS libraries - -ENV CC clang -ENV CXX clang++ - -# EVMONE -RUN set -ex; \ - wget -O /usr/src/evmone.tar.gz https://github.com/ethereum/evmone/releases/download/v0.12.0/evmone-0.12.0-linux-x86_64.tar.gz; \ - test "$(sha256sum /usr/src/evmone.tar.gz)" = "1c7b5eba0c8c3b3b2a7a05101e2d01a13a2f84b323989a29be66285dba4136ce /usr/src/evmone.tar.gz"; \ - cd /usr; \ - tar -xf /usr/src/evmone.tar.gz; \ - rm -rf /usr/src/evmone.tar.gz - -FROM base -COPY --from=libraries /usr/lib /usr/lib -COPY --from=libraries /usr/bin /usr/bin -COPY --from=libraries /usr/include /usr/include -COPY --from=libraries /opt/eldarica /opt/eldarica -ENV PATH="$PATH:/opt/eldarica" From 7e9ac48c5c227d305a924f11aec11abdb5f0f62d Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Tue, 17 Sep 2024 18:21:45 +0200 Subject: [PATCH 0429/1022] SSACFGBuilder: Only eliminate trivial phi of sealed blocks and add return variables to entry definitions --- .../evm/SSAControlFlowGraphBuilder.cpp | 43 +++++++++++---- .../backends/evm/SSAControlFlowGraphBuilder.h | 9 ++++ .../libyul/yulSSAControlFlowGraph/complex.yul | 20 +++---- .../yulSSAControlFlowGraph/complex2.yul | 20 +++---- .../yulSSAControlFlowGraph/function.yul | 6 +-- .../yulSSAControlFlowGraph/nested_for.yul | 52 +++---------------- 6 files changed, 73 insertions(+), 77 deletions(-) diff --git a/libyul/backends/evm/SSAControlFlowGraphBuilder.cpp b/libyul/backends/evm/SSAControlFlowGraphBuilder.cpp index 2579b9064dfe..26635124edfc 100644 --- a/libyul/backends/evm/SSAControlFlowGraphBuilder.cpp +++ b/libyul/backends/evm/SSAControlFlowGraphBuilder.cpp @@ -73,6 +73,7 @@ SSACFG::ValueId SSAControlFlowGraphBuilder::tryRemoveTrivialPhi(SSACFG::ValueId // TODO: double-check if this is sane auto const* phiInfo = std::get_if(&m_graph.valueInfo(_phi)); yulAssert(phiInfo); + yulAssert(blockInfo(phiInfo->block).sealed); SSACFG::ValueId same; for (SSACFG::ValueId arg: phiInfo->arguments) @@ -132,14 +133,27 @@ SSACFG::ValueId SSAControlFlowGraphBuilder::tryRemoveTrivialPhi(SSACFG::ValueId if (input == _phi) uses.emplace_back(Use{std::ref(op), n}); } - // todo check if it is sound to set "unreachable" return values to literal 0 - if (auto* functionReturn = std::get_if(&block.exit)) - std::replace( - functionReturn->returnValues.begin(), - functionReturn->returnValues.end(), - _phi, - same == m_graph.unreachableValue() ? m_graph.newLiteral(block.debugData, 0) : same - ); + std::visit(util::GenericVisitor{ + [_phi, same](SSACFG::BasicBlock::FunctionReturn& _functionReturn) { + std::replace( + _functionReturn.returnValues.begin(), + _functionReturn.returnValues.end(), + _phi, + same + ); + }, + [_phi, same](SSACFG::BasicBlock::ConditionalJump& _condJump) { + if (_condJump.condition == _phi) + _condJump.condition = same; + }, + [_phi, same](SSACFG::BasicBlock::JumpTable& _jumpTable) { + if (_jumpTable.value == _phi) + _jumpTable.value = same; + }, + [](SSACFG::BasicBlock::Jump&) {}, + [](SSACFG::BasicBlock::MainExit&) {}, + [](SSACFG::BasicBlock::Terminated&) {} + }, block.exit); } for (auto& use: uses) use.operation.get().inputs.at(use.inputIndex) = same; @@ -257,6 +271,8 @@ void SSAControlFlowGraphBuilder::buildFunctionGraphs( builder.m_currentBlock = cfg.entry; for (auto&& [var, varId]: cfg.arguments) builder.currentDef(var, cfg.entry) = varId; + for (auto const& var: cfg.returns) + builder.currentDef(var.get(), cfg.entry) = builder.zero(); builder.sealBlock(cfg.entry); builder(functionDefinition->body); cfg.exits.insert(builder.m_currentBlock); @@ -630,7 +646,9 @@ SSACFG::ValueId SSAControlFlowGraphBuilder::readVariableRecursive(Scope::Variabl val = m_graph.newPhi(_block); block.phis.insert(val); writeVariable(_variable, _block, val); - val = addPhiOperands(_variable, val); + // we call tryRemoveTrivialPhi explicitly opposed to what is presented in Algorithm 2, as our implementation + // does not call it in addPhiOperands to avoid removing phis in unsealed blocks + val = tryRemoveTrivialPhi(addPhiOperands(_variable, val)); } writeVariable(_variable, _block, val); return val; @@ -642,7 +660,8 @@ SSACFG::ValueId SSAControlFlowGraphBuilder::addPhiOperands(Scope::Variable const auto& phi = std::get(m_graph.valueInfo(_phi)); for (auto pred: m_graph.block(phi.block).entries) phi.arguments.emplace_back(readVariable(_variable, pred)); - return tryRemoveTrivialPhi(_phi); + // we call tryRemoveTrivialPhi explicitly to avoid removing trivial phis in unsealed blocks + return _phi; } void SSAControlFlowGraphBuilder::writeVariable(Scope::Variable const& _variable, SSACFG::BlockId _block, SSACFG::ValueId _value) @@ -681,11 +700,15 @@ Scope::Variable const& SSAControlFlowGraphBuilder::lookupVariable(YulName _name) void SSAControlFlowGraphBuilder::sealBlock(SSACFG::BlockId _block) { + // this method deviates from Algorithm 4 in the reference paper, + // as it would lead to tryRemoveTrivialPhi being called on unsealed blocks auto& info = blockInfo(_block); yulAssert(!info.sealed, "Trying to seal already sealed block."); for (auto&& [phi, variable] : info.incompletePhis) addPhiOperands(variable, phi); info.sealed = true; + for (auto& [phi, _]: info.incompletePhis) + phi = tryRemoveTrivialPhi(phi); } diff --git a/libyul/backends/evm/SSAControlFlowGraphBuilder.h b/libyul/backends/evm/SSAControlFlowGraphBuilder.h index 0a2ca8064e91..e4d0d6db6175 100644 --- a/libyul/backends/evm/SSAControlFlowGraphBuilder.h +++ b/libyul/backends/evm/SSAControlFlowGraphBuilder.h @@ -17,6 +17,15 @@ // SPDX-License-Identifier: GPL-3.0 /** * Transformation of a Yul AST into a control flow graph. +* +* Based on https://doi.org/10.1007/978-3-642-37051-9_6 +* Braun, Matthias, et al. "Simple and efficient construction of static single assignment form." +* Compiler Construction: 22nd International Conference, CC 2013, +* ETAPS 2013, Rome, Italy, March 16-24, 2013. Proceedings 22. Springer Berlin Heidelberg, 2013. +* +* We have small deviations in Algorithms 2 and 4, as the paper's presentation leads to trivial phis being spuriously +* removed from not yet sealed blocks via a call to addPhiOperands in Algorithm 4. Instead, we perform the deletion +* of trivial phis only after a block has been sealed, i.e., all block's predecessors are present. */ #pragma once diff --git a/test/libyul/yulSSAControlFlowGraph/complex.yul b/test/libyul/yulSSAControlFlowGraph/complex.yul index 0d2c958fd027..eef0b29fa3c0 100644 --- a/test/libyul/yulSSAControlFlowGraph/complex.yul +++ b/test/libyul/yulSSAControlFlowGraph/complex.yul @@ -66,22 +66,22 @@ // Block1_0Exit [label="Jump" shape=oval]; // Block1_0Exit -> Block1_1; // Block1_1 [label="\ -// Block 1\nv4 := φ(\l\ +// Block 1\nv5 := φ(\l\ // Block 0 => 42,\l\ // Block 21 => v43\l\ // )\l\ -// v5 := lt(v0, v4)\l\ +// v6 := lt(v0, v5)\l\ // "]; // Block1_1 -> Block1_1Exit; -// Block1_1Exit [label="{ If v5| { <0> Zero | <1> NonZero }}" shape=Mrecord]; +// Block1_1Exit [label="{ If v6| { <0> Zero | <1> NonZero }}" shape=Mrecord]; // Block1_1Exit:0 -> Block1_4; // Block1_1Exit:1 -> Block1_2; // Block1_2 [label="\ -// Block 2\nv6 := mload(v4)\l\ -// v7 := eq(0, v6)\l\ +// Block 2\nv7 := mload(v5)\l\ +// v8 := eq(0, v7)\l\ // "]; // Block1_2 -> Block1_2Exit; -// Block1_2Exit [label="{ If v7| { <0> Zero | <1> NonZero }}" shape=Mrecord]; +// Block1_2Exit [label="{ If v8| { <0> Zero | <1> NonZero }}" shape=Mrecord]; // Block1_2Exit:0 -> Block1_7; // Block1_2Exit:1 -> Block1_6; // Block1_4 [label="\ @@ -96,7 +96,7 @@ // Block1_6Exit [label="Jump" shape=oval]; // Block1_6Exit -> Block1_4; // Block1_7 [label="\ -// Block 7\nv13 := eq(1, v6)\l\ +// Block 7\nv13 := eq(1, v7)\l\ // "]; // Block1_7 -> Block1_7Exit; // Block1_7Exit [label="{ If v13| { <0> Zero | <1> NonZero }}" shape=Mrecord]; @@ -108,7 +108,7 @@ // Block1_9Exit [label="FunctionReturn[0]"]; // Block1_9 -> Block1_9Exit; // Block1_10 [label="\ -// Block 10\nv20 := eq(2, v6)\l\ +// Block 10\nv20 := eq(2, v7)\l\ // "]; // Block1_10 -> Block1_10Exit; // Block1_10Exit [label="{ If v20| { <0> Zero | <1> NonZero }}" shape=Mrecord]; @@ -121,7 +121,7 @@ // Block1_12Exit [label="Terminated"]; // Block1_12 -> Block1_12Exit; // Block1_13 [label="\ -// Block 13\nv25 := eq(3, v6)\l\ +// Block 13\nv25 := eq(3, v7)\l\ // "]; // Block1_13 -> Block1_13Exit; // Block1_13Exit [label="{ If v25| { <0> Zero | <1> NonZero }}" shape=Mrecord]; @@ -158,7 +158,7 @@ // Block1_18Exit [label="Jump" shape=oval]; // Block1_18Exit -> Block1_5; // Block1_3 [label="\ -// Block 3\nv43 := add(1, v4)\l\ +// Block 3\nv43 := add(1, v5)\l\ // v44 := calldataload(v43)\l\ // "]; // Block1_3 -> Block1_3Exit; diff --git a/test/libyul/yulSSAControlFlowGraph/complex2.yul b/test/libyul/yulSSAControlFlowGraph/complex2.yul index 8f3b1bd3f62d..743b0513cc56 100644 --- a/test/libyul/yulSSAControlFlowGraph/complex2.yul +++ b/test/libyul/yulSSAControlFlowGraph/complex2.yul @@ -82,22 +82,22 @@ // Block1_0Exit [label="Jump" shape=oval]; // Block1_0Exit -> Block1_1; // Block1_1 [label="\ -// Block 1\nv4 := φ(\l\ +// Block 1\nv5 := φ(\l\ // Block 0 => 42,\l\ // Block 21 => v43\l\ // )\l\ -// v5 := lt(v0, v4)\l\ +// v6 := lt(v0, v5)\l\ // "]; // Block1_1 -> Block1_1Exit; -// Block1_1Exit [label="{ If v5| { <0> Zero | <1> NonZero }}" shape=Mrecord]; +// Block1_1Exit [label="{ If v6| { <0> Zero | <1> NonZero }}" shape=Mrecord]; // Block1_1Exit:0 -> Block1_4; // Block1_1Exit:1 -> Block1_2; // Block1_2 [label="\ -// Block 2\nv6 := mload(v4)\l\ -// v7 := eq(0, v6)\l\ +// Block 2\nv7 := mload(v5)\l\ +// v8 := eq(0, v7)\l\ // "]; // Block1_2 -> Block1_2Exit; -// Block1_2Exit [label="{ If v7| { <0> Zero | <1> NonZero }}" shape=Mrecord]; +// Block1_2Exit [label="{ If v8| { <0> Zero | <1> NonZero }}" shape=Mrecord]; // Block1_2Exit:0 -> Block1_7; // Block1_2Exit:1 -> Block1_6; // Block1_4 [label="\ @@ -112,7 +112,7 @@ // Block1_6Exit [label="Jump" shape=oval]; // Block1_6Exit -> Block1_4; // Block1_7 [label="\ -// Block 7\nv13 := eq(1, v6)\l\ +// Block 7\nv13 := eq(1, v7)\l\ // "]; // Block1_7 -> Block1_7Exit; // Block1_7Exit [label="{ If v13| { <0> Zero | <1> NonZero }}" shape=Mrecord]; @@ -124,7 +124,7 @@ // Block1_9Exit [label="FunctionReturn[0]"]; // Block1_9 -> Block1_9Exit; // Block1_10 [label="\ -// Block 10\nv20 := eq(2, v6)\l\ +// Block 10\nv20 := eq(2, v7)\l\ // "]; // Block1_10 -> Block1_10Exit; // Block1_10Exit [label="{ If v20| { <0> Zero | <1> NonZero }}" shape=Mrecord]; @@ -137,7 +137,7 @@ // Block1_12Exit [label="Terminated"]; // Block1_12 -> Block1_12Exit; // Block1_13 [label="\ -// Block 13\nv25 := eq(3, v6)\l\ +// Block 13\nv25 := eq(3, v7)\l\ // "]; // Block1_13 -> Block1_13Exit; // Block1_13Exit [label="{ If v25| { <0> Zero | <1> NonZero }}" shape=Mrecord]; @@ -174,7 +174,7 @@ // Block1_18Exit [label="Jump" shape=oval]; // Block1_18Exit -> Block1_5; // Block1_3 [label="\ -// Block 3\nv43 := add(1, v4)\l\ +// Block 3\nv43 := add(1, v5)\l\ // v44 := calldataload(v43)\l\ // "]; // Block1_3 -> Block1_3Exit; diff --git a/test/libyul/yulSSAControlFlowGraph/function.yul b/test/libyul/yulSSAControlFlowGraph/function.yul index aa4b6ac97f56..436bcd49956e 100644 --- a/test/libyul/yulSSAControlFlowGraph/function.yul +++ b/test/libyul/yulSSAControlFlowGraph/function.yul @@ -37,10 +37,10 @@ // r := f(v0, v1)"]; // FunctionEntry_f_0 -> Block1_0; // Block1_0 [label="\ -// Block 0\nv2 := add(v1, v0)\l\ -// v3 := sub(v0, v2)\l\ +// Block 0\nv3 := add(v1, v0)\l\ +// v4 := sub(v0, v3)\l\ // "]; -// Block1_0Exit [label="FunctionReturn[v3]"]; +// Block1_0Exit [label="FunctionReturn[v4]"]; // Block1_0 -> Block1_0Exit; // FunctionEntry_g_0 [label="function g: // g()"]; diff --git a/test/libyul/yulSSAControlFlowGraph/nested_for.yul b/test/libyul/yulSSAControlFlowGraph/nested_for.yul index e078630a60d9..0ed17c870a1f 100644 --- a/test/libyul/yulSSAControlFlowGraph/nested_for.yul +++ b/test/libyul/yulSSAControlFlowGraph/nested_for.yul @@ -55,10 +55,6 @@ // Block 2 => 0,\l\ // Block 7 => v35\l\ // )\l\ -// v33 := φ(\l\ -// Block 2 => v2,\l\ -// Block 7 => v18\l\ -// )\l\ // v5 := lt(3, v4)\l\ // "]; // Block0_5 -> Block0_5Exit; @@ -80,14 +76,6 @@ // Block 6 => 0,\l\ // Block 11 => v31\l\ // )\l\ -// v17 := φ(\l\ -// Block 6 => v4,\l\ -// Block 11 => v32\l\ -// )\l\ -// v18 := φ(\l\ -// Block 6 => v33,\l\ -// Block 11 => v34\l\ -// )\l\ // v7 := lt(3, v6)\l\ // "]; // Block0_9 -> Block0_9Exit; @@ -95,7 +83,7 @@ // Block0_9Exit:0 -> Block0_12; // Block0_9Exit:1 -> Block0_10; // Block0_3 [label="\ -// Block 3\nv36 := add(1, v33)\l\ +// Block 3\nv36 := add(1, v2)\l\ // "]; // Block0_3 -> Block0_3Exit [arrowhead=none]; // Block0_3Exit [label="Jump" shape=oval]; @@ -117,25 +105,13 @@ // Block0_13Exit [label="Jump" shape=oval]; // Block0_13Exit -> Block0_15; // Block0_14 [label="\ -// Block 14\nv27 := φ(\l\ -// Block 10 => v6,\l\ -// Block 18 => v10\l\ -// )\l\ -// v28 := φ(\l\ -// Block 10 => v17,\l\ -// Block 18 => v11\l\ -// )\l\ -// v29 := φ(\l\ -// Block 10 => v18,\l\ -// Block 18 => v12\l\ -// )\l\ -// "]; +// Block 14\n"]; // Block0_14 -> Block0_14Exit; // Block0_14Exit [label="{ If 1| { <0> Zero | <1> NonZero }}" shape=Mrecord]; // Block0_14Exit:0 -> Block0_20; // Block0_14Exit:1 -> Block0_19; // Block0_7 [label="\ -// Block 7\nv35 := add(1, v17)\l\ +// Block 7\nv35 := add(1, v4)\l\ // "]; // Block0_7 -> Block0_7Exit [arrowhead=none]; // Block0_7Exit [label="Jump" shape=oval]; @@ -157,24 +133,12 @@ // Block0_19Exit [label="Jump" shape=oval]; // Block0_19Exit -> Block0_21; // Block0_20 [label="\ -// Block 20\nv30 := φ(\l\ -// Block 14 => v27,\l\ -// Block 24 => v21\l\ -// )\l\ -// v32 := φ(\l\ -// Block 14 => v28,\l\ -// Block 24 => v22\l\ -// )\l\ -// v34 := φ(\l\ -// Block 14 => v29,\l\ -// Block 24 => v23\l\ -// )\l\ -// "]; +// Block 20\n"]; // Block0_20 -> Block0_20Exit [arrowhead=none]; // Block0_20Exit [label="Jump" shape=oval]; // Block0_20Exit -> Block0_11; // Block0_16 [label="\ -// Block 16\nv13 := add(v17, v18)\l\ +// Block 16\nv13 := add(v4, v2)\l\ // v14 := add(v6, v13)\l\ // sstore(v14, v8)\l\ // "]; @@ -198,7 +162,7 @@ // Block0_21Exit:0 -> Block0_24; // Block0_21Exit:1 -> Block0_22; // Block0_11 [label="\ -// Block 11\nv31 := add(1, v30)\l\ +// Block 11\nv31 := add(1, v6)\l\ // "]; // Block0_11 -> Block0_11Exit [arrowhead=none]; // Block0_11Exit [label="Jump" shape=oval]; @@ -210,8 +174,8 @@ // Block0_17Exit [label="Jump" shape=oval]; // Block0_17Exit -> Block0_15; // Block0_22 [label="\ -// Block 22\nv24 := add(v28, v29)\l\ -// v25 := add(v27, v24)\l\ +// Block 22\nv24 := add(v4, v2)\l\ +// v25 := add(v6, v24)\l\ // sstore(v25, v19)\l\ // "]; // Block0_22 -> Block0_22Exit [arrowhead=none]; From c4a199a253f958c13ba70dc9f702a37dfbd5f21c Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Thu, 19 Sep 2024 10:21:35 +0200 Subject: [PATCH 0430/1022] SSACFGBuilder: clean up tryRemoveTrivialPhi --- .../evm/SSAControlFlowGraphBuilder.cpp | 57 ++++--------------- 1 file changed, 12 insertions(+), 45 deletions(-) diff --git a/libyul/backends/evm/SSAControlFlowGraphBuilder.cpp b/libyul/backends/evm/SSAControlFlowGraphBuilder.cpp index 26635124edfc..3735892c3664 100644 --- a/libyul/backends/evm/SSAControlFlowGraphBuilder.cpp +++ b/libyul/backends/evm/SSAControlFlowGraphBuilder.cpp @@ -84,14 +84,6 @@ SSACFG::ValueId SSAControlFlowGraphBuilder::tryRemoveTrivialPhi(SSACFG::ValueId return _phi; // phi merges at least two distinct values -> not trivial same = arg; } - - struct Use { - std::reference_wrapper operation; - size_t inputIndex = std::numeric_limits::max(); - }; - std::vector uses; - std::vector phiUses; - if (!same.hasValue()) { // This will happen for unreachable paths. @@ -99,40 +91,29 @@ SSACFG::ValueId SSAControlFlowGraphBuilder::tryRemoveTrivialPhi(SSACFG::ValueId same = m_graph.unreachableValue(); } - auto phiBlock = phiInfo->block; - m_graph.block(phiBlock).phis.erase(_phi); + m_graph.block(phiInfo->block).phis.erase(_phi); + std::set phiUses; for (size_t blockIdValue = 0; blockIdValue < m_graph.numBlocks(); ++blockIdValue) { auto& block = m_graph.block(SSACFG::BlockId{blockIdValue}); for (auto blockPhi: block.phis) { - if (blockPhi == _phi) - continue; - auto const* blockPhiInfo = std::get_if(&m_graph.valueInfo(blockPhi)); + yulAssert(blockPhi != _phi, "Phis should be defined in exactly one block, _phi was erased."); + auto* blockPhiInfo = std::get_if(&m_graph.valueInfo(blockPhi)); yulAssert(blockPhiInfo); bool usedInPhi = false; - for (auto input: blockPhiInfo->arguments) - { - if (input == _phi) + for (auto& arg: blockPhiInfo->arguments) + if (arg == _phi) + { + arg = same; usedInPhi = true; - } + } if (usedInPhi) - phiUses.emplace_back(blockPhi); + phiUses.emplace(blockPhi); } for (auto& op: block.operations) - { - // TODO: double check when phiVar occurs in outputs here and what to do about it. - if (op.outputs.size() == 1 && op.outputs.front() == _phi) - continue; - // TODO: check if this always hold - and if so if the assertion is really valuable. - for (auto& output: op.outputs) - yulAssert(output != _phi); - - for (auto&& [n, input]: op.inputs | ranges::views::enumerate) - if (input == _phi) - uses.emplace_back(Use{std::ref(op), n}); - } + std::replace(op.inputs.begin(), op.inputs.end(), _phi, same); std::visit(util::GenericVisitor{ [_phi, same](SSACFG::BasicBlock::FunctionReturn& _functionReturn) { std::replace( @@ -155,22 +136,8 @@ SSACFG::ValueId SSAControlFlowGraphBuilder::tryRemoveTrivialPhi(SSACFG::ValueId [](SSACFG::BasicBlock::Terminated&) {} }, block.exit); } - for (auto& use: uses) - use.operation.get().inputs.at(use.inputIndex) = same; - for (auto phiUse: phiUses) - { - auto* blockPhiInfo = std::get_if(&m_graph.valueInfo(phiUse)); - yulAssert(blockPhiInfo); - for (auto& arg: blockPhiInfo->arguments) - if (arg == _phi) - arg = same; - } for (auto& [_, currentVariableDefs]: m_currentDef) - { - for (auto& def: currentVariableDefs) - if (def && *def == _phi) - def = same; - } + std::replace(currentVariableDefs.begin(), currentVariableDefs.end(), _phi, same); for (auto phiUse: phiUses) tryRemoveTrivialPhi(phiUse); From 55f746b8c599b76afef97e1b63840b532d43a36c Mon Sep 17 00:00:00 2001 From: rodiazet Date: Thu, 19 Sep 2024 20:23:45 +0200 Subject: [PATCH 0431/1022] eof: Introduce EOF container format support in `Assembly::assemble` (EIP-3540) Co-authored-by: Daniel Kirchner --- libevmasm/Assembly.cpp | 441 +++++++++++++++++++----- libevmasm/Assembly.h | 52 ++- libevmasm/ConstantOptimiser.cpp | 73 ++-- libevmasm/EVMAssemblyStack.cpp | 8 +- libsolidity/interface/CompilerStack.cpp | 13 +- libyul/YulStack.cpp | 10 +- test/libevmasm/Assembler.cpp | 3 +- test/libevmasm/Optimiser.cpp | 6 +- test/libsolidity/Assembly.cpp | 3 +- 9 files changed, 455 insertions(+), 154 deletions(-) diff --git a/libevmasm/Assembly.cpp b/libevmasm/Assembly.cpp index 7a28208c1b86..df78f43ca59f 100644 --- a/libevmasm/Assembly.cpp +++ b/libevmasm/Assembly.cpp @@ -58,11 +58,13 @@ AssemblyItem const& Assembly::append(AssemblyItem _i) { assertThrow(m_deposit >= 0, AssemblyException, "Stack underflow."); m_deposit += static_cast(_i.deposit()); - m_items.emplace_back(std::move(_i)); - if (!m_items.back().location().isValid() && m_currentSourceLocation.isValid()) - m_items.back().setLocation(m_currentSourceLocation); - m_items.back().m_modifierDepth = m_currentModifierDepth; - return m_items.back(); + solAssert(m_currentCodeSection < m_codeSections.size()); + auto& currentItems = m_codeSections.at(m_currentCodeSection).items; + currentItems.emplace_back(std::move(_i)); + if (!currentItems.back().location().isValid() && m_currentSourceLocation.isValid()) + currentItems.back().setLocation(m_currentSourceLocation); + currentItems.back().m_modifierDepth = m_currentModifierDepth; + return currentItems.back(); } unsigned Assembly::codeSize(unsigned subTagSize) const @@ -73,8 +75,9 @@ unsigned Assembly::codeSize(unsigned subTagSize) const for (auto const& i: m_data) ret += i.second.size(); - for (AssemblyItem const& i: m_items) - ret += i.bytesRequired(tagSize, m_evmVersion, Precision::Precise); + for (auto const& codeSection: m_codeSections) + for (AssemblyItem const& i: codeSection.items) + ret += i.bytesRequired(tagSize, m_evmVersion, Precision::Precise); if (numberEncodingSize(ret) <= tagSize) return static_cast(ret); } @@ -82,11 +85,15 @@ unsigned Assembly::codeSize(unsigned subTagSize) const void Assembly::importAssemblyItemsFromJSON(Json const& _code, std::vector const& _sourceList) { - solAssert(m_items.empty()); + // Assembly constructor creates first code section with proper type and empty `items` + solAssert(m_codeSections.size() == 1); + solAssert(m_codeSections[0].items.empty()); + // TODO: Add support for EOF and more than one code sections. + solUnimplementedAssert(!m_eofVersion.has_value(), "Assembly output for EOF is not yet implemented."); solRequire(_code.is_array(), AssemblyImportException, "Supplied JSON is not an array."); for (auto jsonItemIter = std::begin(_code); jsonItemIter != std::end(_code); ++jsonItemIter) { - AssemblyItem const& newItem = m_items.emplace_back(createAssemblyItemFromJSON(*jsonItemIter, _sourceList)); + AssemblyItem const& newItem = m_codeSections[0].items.emplace_back(createAssemblyItemFromJSON(*jsonItemIter, _sourceList)); if (newItem == Instruction::JUMPDEST) solThrow(AssemblyImportException, "JUMPDEST instruction without a tag"); else if (newItem.type() == AssemblyItemType::Tag) @@ -396,7 +403,10 @@ void Assembly::assemblyStream( { Functionalizer f(_out, _prefix, _sourceCodes, *this); - for (auto const& i: m_items) + // TODO: support EOF + solUnimplementedAssert(!m_eofVersion.has_value(), "Assembly output for EOF is not yet implemented."); + solAssert(m_codeSections.size() == 1); + for (auto const& i: m_codeSections.front().items) f.feed(i, _debugInfoSelection); f.flush(); @@ -434,7 +444,10 @@ Json Assembly::assemblyJSON(std::map const& _sourceIndice Json root; root[".code"] = Json::array(); Json& code = root[".code"]; - for (AssemblyItem const& item: m_items) + // TODO: support EOF + solUnimplementedAssert(!m_eofVersion.has_value(), "Assembly output for EOF is not yet implemented."); + solAssert(m_codeSections.size() == 1); + for (AssemblyItem const& item: m_codeSections.front().items) { int sourceIndex = -1; if (item.location().sourceName) @@ -518,7 +531,8 @@ Json Assembly::assemblyJSON(std::map const& _sourceIndice std::pair, std::vector> Assembly::fromJSON( Json const& _json, std::vector const& _sourceList, - size_t _level + size_t _level, + std::optional _eofVersion ) { solRequire(_json.is_object(), AssemblyImportException, "Supplied JSON is not an object."); @@ -549,7 +563,7 @@ std::pair, std::vector> Assembly::fromJSO "Member 'sourceList' may only be present in the root JSON object." ); - auto result = std::make_shared(EVMVersion{}, _level == 0 /* _creation */, std::nullopt, "" /* _name */); + auto result = std::make_shared(EVMVersion{}, _level == 0 /* _creation */, _eofVersion, "" /* _name */); std::vector parsedSourceList; if (_json.contains("sourceList")) { @@ -717,16 +731,21 @@ std::map const& Assembly::optimiseInternal( return *m_tagReplacements; // Run optimisation for sub-assemblies. + // TODO: verify and double-check this for EOF. for (size_t subId = 0; subId < m_subs.size(); ++subId) { OptimiserSettings settings = _settings; Assembly& sub = *m_subs[subId]; + std::set referencedTags; + for (auto& codeSection: m_codeSections) + referencedTags += JumpdestRemover::referencedTags(codeSection.items, subId); std::map const& subTagReplacements = sub.optimiseInternal( settings, - JumpdestRemover::referencedTags(m_items, subId) + referencedTags ); // Apply the replacements (can be empty). - BlockDeduplicator::applyTagReplacement(m_items, subTagReplacements, subId); + for (auto& codeSection: m_codeSections) + BlockDeduplicator::applyTagReplacement(codeSection.items, subTagReplacements, subId); } std::map tagReplacements; @@ -735,57 +754,70 @@ std::map const& Assembly::optimiseInternal( { count = 0; + // TODO: verify this for EOF. if (_settings.runInliner && !m_eofVersion.has_value()) + { + solAssert(m_codeSections.size() == 1); Inliner{ - m_items, + m_codeSections.front().items, _tagsReferencedFromOutside, _settings.expectedExecutionsPerDeployment, isCreation(), - _settings.evmVersion - }.optimise(); - - if (_settings.runJumpdestRemover) + _settings.evmVersion} + .optimise(); + } + // TODO: verify this for EOF. + if (_settings.runJumpdestRemover && !m_eofVersion.has_value()) { - JumpdestRemover jumpdestOpt{m_items}; - if (jumpdestOpt.optimise(_tagsReferencedFromOutside)) - count++; + for (auto& codeSection: m_codeSections) + { + JumpdestRemover jumpdestOpt{codeSection.items}; + if (jumpdestOpt.optimise(_tagsReferencedFromOutside)) + count++; + } } - if (_settings.runPeephole) + // TODO: verify this for EOF. + if (_settings.runPeephole && !m_eofVersion.has_value()) { - PeepholeOptimiser peepOpt{m_items, m_evmVersion}; - while (peepOpt.optimise()) + for (auto& codeSection: m_codeSections) { - count++; - assertThrow(count < 64000, OptimizerException, "Peephole optimizer seems to be stuck."); + PeepholeOptimiser peepOpt{codeSection.items, m_evmVersion}; + while (peepOpt.optimise()) + { + count++; + assertThrow(count < 64000, OptimizerException, "Peephole optimizer seems to be stuck."); + } } } // This only modifies PushTags, we have to run again to actually remove code. + // TODO: implement for EOF. if (_settings.runDeduplicate && !m_eofVersion.has_value()) - { - BlockDeduplicator deduplicator{m_items}; - if (deduplicator.deduplicate()) + for (auto& section: m_codeSections) { - for (auto const& replacement: deduplicator.replacedTags()) + BlockDeduplicator deduplicator{section.items}; + if (deduplicator.deduplicate()) { - assertThrow( - replacement.first <= std::numeric_limits::max() && replacement.second <= std::numeric_limits::max(), - OptimizerException, - "Invalid tag replacement." - ); - assertThrow( - !tagReplacements.count(replacement.first), - OptimizerException, - "Replacement already known." - ); - tagReplacements[replacement.first] = replacement.second; - if (_tagsReferencedFromOutside.erase(static_cast(replacement.first))) - _tagsReferencedFromOutside.insert(static_cast(replacement.second)); + for (auto const& replacement: deduplicator.replacedTags()) + { + assertThrow( + replacement.first <= std::numeric_limits::max() && replacement.second <= std::numeric_limits::max(), + OptimizerException, + "Invalid tag replacement." + ); + assertThrow( + !tagReplacements.count(replacement.first), + OptimizerException, + "Replacement already known." + ); + tagReplacements[replacement.first] = replacement.second; + if (_tagsReferencedFromOutside.erase(static_cast(replacement.first))) + _tagsReferencedFromOutside.insert(static_cast(replacement.second)); + } + count++; } - count++; } - } // TODO: investigate for EOF if (_settings.runCSE && !m_eofVersion.has_value()) @@ -795,17 +827,19 @@ std::map const& Assembly::optimiseInternal( // function types that can be stored in storage. AssemblyItems optimisedItems; - bool usesMSize = ranges::any_of(m_items, [](AssemblyItem const& _i) { + solAssert(m_codeSections.size() == 1); + auto& items = m_codeSections.front().items; + bool usesMSize = ranges::any_of(items, [](AssemblyItem const& _i) { return _i == AssemblyItem{Instruction::MSIZE} || _i.type() == VerbatimBytecode; }); - auto iter = m_items.begin(); - while (iter != m_items.end()) + auto iter = items.begin(); + while (iter != items.end()) { KnownState emptyState; CommonSubexpressionEliminator eliminator{emptyState}; auto orig = iter; - iter = eliminator.feedItems(iter, m_items.end(), usesMSize); + iter = eliminator.feedItems(iter, items.end(), usesMSize); bool shouldReplace = false; AssemblyItems optimisedChunk; try @@ -832,9 +866,9 @@ std::map const& Assembly::optimiseInternal( else copy(orig, iter, back_inserter(optimisedItems)); } - if (optimisedItems.size() < m_items.size()) + if (optimisedItems.size() < items.size()) { - m_items = std::move(optimisedItems); + items = std::move(optimisedItems); count++; } } @@ -853,19 +887,115 @@ std::map const& Assembly::optimiseInternal( return *m_tagReplacements; } +namespace +{ +template +void setBigEndian(bytes& _dest, size_t _offset, size_t _size, ValueT _value) +{ + assertThrow(numberEncodingSize(_value) <= _size, AssemblyException, ""); + toBigEndian(_value, bytesRef(_dest.data() + _offset, _size)); +} + +template +void appendBigEndian(bytes& _dest, size_t _size, ValueT _value) +{ + _dest.resize(_dest.size() + _size); + setBigEndian(_dest, _dest.size() - _size, _size, _value); +} + +template +void setBigEndianUint16(bytes& _dest, size_t _offset, ValueT _value) +{ + setBigEndian(_dest, _offset, 2, _value); +} + +template +void appendBigEndianUint16(bytes& _dest, ValueT _value) +{ + static_assert(!std::numeric_limits::is_signed, "only unsigned types or bigint supported"); + assertThrow(_value <= 0xFFFF, AssemblyException, ""); + appendBigEndian(_dest, 2, static_cast(_value)); +} +} + +std::tuple, size_t> Assembly::createEOFHeader(std::set const& _referencedSubIds) const +{ + bytes retBytecode; + std::vector codeSectionSizeOffsets; + size_t dataSectionSizeOffset; + + retBytecode.push_back(0xef); + retBytecode.push_back(0x00); + retBytecode.push_back(0x01); // version 1 + + retBytecode.push_back(0x01); // kind=type + appendBigEndianUint16(retBytecode, m_codeSections.size() * 4u); // length of type section + + retBytecode.push_back(0x02); // kind=code + appendBigEndianUint16(retBytecode, m_codeSections.size()); // placeholder for number of code sections + + for (auto const& codeSection: m_codeSections) + { + (void) codeSection; + codeSectionSizeOffsets.emplace_back(retBytecode.size()); + appendBigEndianUint16(retBytecode, 0u); // placeholder for length of code + } + + if (!_referencedSubIds.empty()) + { + retBytecode.push_back(0x03); + appendBigEndianUint16(retBytecode, _referencedSubIds.size()); + + for (auto subId: _referencedSubIds) + appendBigEndianUint16(retBytecode, m_subs[subId]->assemble().bytecode.size()); + } + + retBytecode.push_back(0x04); // kind=data + dataSectionSizeOffset = retBytecode.size(); + appendBigEndianUint16(retBytecode, 0u); // length of data + + retBytecode.push_back(0x00); // terminator + + for (auto const& codeSection: m_codeSections) + { + retBytecode.push_back(codeSection.inputs); + retBytecode.push_back(codeSection.outputs); + appendBigEndianUint16(retBytecode, 0xFFFFu); // TODO: Add stack height calculation + } + + return {retBytecode, codeSectionSizeOffsets, dataSectionSizeOffset}; +} + LinkerObject const& Assembly::assemble() const { - assertThrow(!m_invalid, AssemblyException, "Attempted to assemble invalid Assembly object."); + solRequire(!m_invalid, AssemblyException, "Attempted to assemble invalid Assembly object."); // Return the already assembled object, if present. if (!m_assembledObject.bytecode.empty()) return m_assembledObject; - // Otherwise ensure the object is actually clear. - assertThrow(m_assembledObject.linkReferences.empty(), AssemblyException, "Unexpected link references."); - LinkerObject& ret = m_assembledObject; + // Otherwise ensure the object is actually clear. + solRequire(m_assembledObject.linkReferences.empty(), AssemblyException, "Unexpected link references."); bool const eof = m_eofVersion.has_value(); - solAssert(!eof || m_eofVersion == 1, "Invalid EOF version."); + solRequire(!eof || m_eofVersion == 1, AssemblyException, "Invalid EOF version."); + + if (!eof) + return assembleLegacy(); + else + return assembleEOF(); +} + +LinkerObject const& Assembly::assembleLegacy() const +{ + solAssert(!m_eofVersion.has_value()); + solAssert(!m_invalid); + // Return the already assembled object, if present. + if (!m_assembledObject.bytecode.empty()) + return m_assembledObject; + // Otherwise ensure the object is actually clear. + solAssert(m_assembledObject.linkReferences.empty()); + + LinkerObject& ret = m_assembledObject; size_t subTagSize = 1; std::map>> immutableReferencesBySub; @@ -889,13 +1019,16 @@ LinkerObject const& Assembly::assemble() const bool setsImmutables = false; bool pushesImmutables = false; - for (auto const& i: m_items) - if (i.type() == AssignImmutable) + assertThrow(m_codeSections.size() == 1, AssemblyException, "Expected exactly one code section in non-EOF code."); + AssemblyItems const& items = m_codeSections.front().items; + + for (auto const& item: items) + if (item.type() == AssignImmutable) { - i.setImmutableOccurrences(immutableReferencesBySub[i.data()].second.size()); + item.setImmutableOccurrences(immutableReferencesBySub[item.data()].second.size()); setsImmutables = true; } - else if (i.type() == PushImmutable) + else if (item.type() == PushImmutable) pushesImmutables = true; if (setsImmutables || pushesImmutables) assertThrow( @@ -912,10 +1045,10 @@ LinkerObject const& Assembly::assemble() const std::vector sizeRef; ///< Pointers to code locations where the size of the program is inserted unsigned bytesPerTag = numberEncodingSize(bytesRequiredForCode); // Adjust bytesPerTag for references to sub assemblies. - for (AssemblyItem const& i: m_items) - if (i.type() == PushTag) + for (AssemblyItem const& item: items) + if (item.type() == PushTag) { - auto [subId, tagId] = i.splitForeignPushTag(); + auto [subId, tagId] = item.splitForeignPushTag(); if (subId == std::numeric_limits::max()) continue; assertThrow(subId < m_subs.size(), AssemblyException, "Invalid sub id"); @@ -933,20 +1066,20 @@ LinkerObject const& Assembly::assemble() const uint8_t dataRefPush = static_cast(pushInstruction(bytesPerDataRef)); ret.bytecode.reserve(bytesRequiredIncludingData); - for (AssemblyItem const& i: m_items) + for (AssemblyItem const& item: items) { // store position of the invalid jump destination - if (i.type() != Tag && m_tagPositionsInBytecode[0] == std::numeric_limits::max()) + if (item.type() != Tag && m_tagPositionsInBytecode[0] == std::numeric_limits::max()) m_tagPositionsInBytecode[0] = ret.bytecode.size(); - switch (i.type()) + switch (item.type()) { case Operation: - ret.bytecode.push_back(static_cast(i.instruction())); + ret.bytecode.push_back(static_cast(item.instruction())); break; case Push: { - unsigned b = numberEncodingSize(i.data()); + unsigned b = numberEncodingSize(item.data()); if (b == 0 && !m_evmVersion.hasPush0()) { b = 1; @@ -956,36 +1089,33 @@ LinkerObject const& Assembly::assemble() const { ret.bytecode.resize(ret.bytecode.size() + b); bytesRef byr(&ret.bytecode.back() + 1 - b, b); - toBigEndian(i.data(), byr); + toBigEndian(item.data(), byr); } break; } case PushTag: { - assertThrow(!eof, AssemblyException, "PushTag in EOF code"); ret.bytecode.push_back(tagPush); - tagRef[ret.bytecode.size()] = i.splitForeignPushTag(); + tagRef[ret.bytecode.size()] = item.splitForeignPushTag(); ret.bytecode.resize(ret.bytecode.size() + bytesPerTag); break; } case PushData: ret.bytecode.push_back(dataRefPush); - dataRef.insert(std::make_pair(h256(i.data()), ret.bytecode.size())); + dataRef.insert(std::make_pair(h256(item.data()), ret.bytecode.size())); ret.bytecode.resize(ret.bytecode.size() + bytesPerDataRef); break; case PushSub: - assertThrow(!eof, AssemblyException, "PushSub in EOF code"); - assertThrow(i.data() <= std::numeric_limits::max(), AssemblyException, ""); + assertThrow(item.data() <= std::numeric_limits::max(), AssemblyException, ""); ret.bytecode.push_back(dataRefPush); - subRef.insert(std::make_pair(static_cast(i.data()), ret.bytecode.size())); + subRef.insert(std::make_pair(static_cast(item.data()), ret.bytecode.size())); ret.bytecode.resize(ret.bytecode.size() + bytesPerDataRef); break; case PushSubSize: { - assertThrow(!eof, AssemblyException, "PushSubSize in EOF code"); - assertThrow(i.data() <= std::numeric_limits::max(), AssemblyException, ""); - auto s = subAssemblyById(static_cast(i.data()))->assemble().bytecode.size(); - i.setPushedValue(u256(s)); + assertThrow(item.data() <= std::numeric_limits::max(), AssemblyException, ""); + auto s = subAssemblyById(static_cast(item.data()))->assemble().bytecode.size(); + item.setPushedValue(u256(s)); unsigned b = std::max(1, numberEncodingSize(s)); ret.bytecode.push_back(static_cast(pushInstruction(b))); ret.bytecode.resize(ret.bytecode.size() + b); @@ -995,7 +1125,6 @@ LinkerObject const& Assembly::assemble() const } case PushProgramSize: { - assertThrow(!eof, AssemblyException, "PushProgramSize in EOF code"); ret.bytecode.push_back(dataRefPush); sizeRef.push_back(static_cast(ret.bytecode.size())); ret.bytecode.resize(ret.bytecode.size() + bytesPerDataRef); @@ -1003,27 +1132,25 @@ LinkerObject const& Assembly::assemble() const } case PushLibraryAddress: ret.bytecode.push_back(static_cast(Instruction::PUSH20)); - ret.linkReferences[ret.bytecode.size()] = m_libraries.at(i.data()); + ret.linkReferences[ret.bytecode.size()] = m_libraries.at(item.data()); ret.bytecode.resize(ret.bytecode.size() + 20); break; case PushImmutable: - assertThrow(!eof, AssemblyException, "PushImmutable in EOF code"); ret.bytecode.push_back(static_cast(Instruction::PUSH32)); // Maps keccak back to the "identifier" std::string of that immutable. - ret.immutableReferences[i.data()].first = m_immutables.at(i.data()); + ret.immutableReferences[item.data()].first = m_immutables.at(item.data()); // Record the bytecode offset of the PUSH32 argument. - ret.immutableReferences[i.data()].second.emplace_back(ret.bytecode.size()); + ret.immutableReferences[item.data()].second.emplace_back(ret.bytecode.size()); // Advance bytecode by 32 bytes (default initialized). ret.bytecode.resize(ret.bytecode.size() + 32); break; case VerbatimBytecode: - ret.bytecode += i.verbatimData(); + ret.bytecode += item.verbatimData(); break; case AssignImmutable: { - assertThrow(!eof, AssemblyException, "AssignImmutable in EOF code"); // Expect 2 elements on stack (source, dest_base) - auto const& offsets = immutableReferencesBySub[i.data()].second; + auto const& offsets = immutableReferencesBySub[item.data()].second; for (size_t i = 0; i < offsets.size(); ++i) { if (i != offsets.size() - 1) @@ -1043,7 +1170,7 @@ LinkerObject const& Assembly::assemble() const ret.bytecode.push_back(uint8_t(Instruction::POP)); ret.bytecode.push_back(uint8_t(Instruction::POP)); } - immutableReferencesBySub.erase(i.data()); + immutableReferencesBySub.erase(item.data()); break; } case PushDeployTimeAddress: @@ -1052,9 +1179,9 @@ LinkerObject const& Assembly::assemble() const break; case Tag: { - assertThrow(i.data() != 0, AssemblyException, "Invalid tag position."); - assertThrow(i.splitForeignPushTag().first == std::numeric_limits::max(), AssemblyException, "Foreign tag."); - size_t tagId = static_cast(i.data()); + assertThrow(item.data() != 0, AssemblyException, "Invalid tag position."); + assertThrow(item.splitForeignPushTag().first == std::numeric_limits::max(), AssemblyException, "Foreign tag."); + size_t tagId = static_cast(item.data()); assertThrow(ret.bytecode.size() < 0xffffffffL, AssemblyException, "Tag too large."); assertThrow(m_tagPositionsInBytecode[tagId] == std::numeric_limits::max(), AssemblyException, "Duplicate tag position."); m_tagPositionsInBytecode[tagId] = ret.bytecode.size(); @@ -1074,7 +1201,7 @@ LinkerObject const& Assembly::assemble() const "Some immutables were read from but never assigned, possibly because of optimization." ); - if (!eof && (!m_subs.empty() || !m_data.empty() || !m_auxiliaryData.empty())) + if (!m_subs.empty() || !m_data.empty() || !m_auxiliaryData.empty()) // Append an INVALID here to help tests find miscompilation. ret.bytecode.push_back(static_cast(Instruction::INVALID)); @@ -1118,7 +1245,7 @@ LinkerObject const& Assembly::assemble() const { size_t position = m_tagPositionsInBytecode.at(tagInfo.id); std::optional tagIndex; - for (auto&& [index, item]: m_items | ranges::views::enumerate) + for (auto&& [index, item]: items | ranges::views::enumerate) if (item.type() == Tag && static_cast(item.data()) == tagInfo.id) { tagIndex = index; @@ -1156,6 +1283,130 @@ LinkerObject const& Assembly::assemble() const return ret; } +std::map Assembly::findReferencedContainers() const +{ + std::set referencedSubcontainersIds; + solAssert(m_subs.size() <= 0x100); // According to EOF spec + + // TODO: Implement properly when opcodes referring sub containers added. + for (uint16_t i = 0; i < m_subs.size(); ++i) + referencedSubcontainersIds.insert(static_cast(i)); + // END TODO + + std::map replacements; + uint8_t nUnreferenced = 0; + for (uint8_t i = 0; i < static_cast(m_subs.size()); ++i) + { + if (referencedSubcontainersIds.count(i) > 0) + replacements[i] = static_cast(i - nUnreferenced); + else + nUnreferenced++; + } + + return replacements; +} + +LinkerObject const& Assembly::assembleEOF() const +{ + solAssert(m_eofVersion.has_value() && m_eofVersion == 1); + LinkerObject& ret = m_assembledObject; + + auto const subIdsReplacements = findReferencedContainers(); + auto const referencedSubIds = keys(subIdsReplacements); + + solRequire(!m_codeSections.empty(), AssemblyException, "Expected at least one code section."); + solRequire( + m_codeSections.front().inputs == 0 && m_codeSections.front().outputs == 0x80, AssemblyException, + "Expected the first code section to have zero inputs and be non-returning." + ); + + // Insert EOF1 header. + auto [bytecode, codeSectionSizeOffsets, dataSectionSizeOffset] = createEOFHeader(referencedSubIds); + ret.bytecode = bytecode; + + m_tagPositionsInBytecode = std::vector(m_usedTags, std::numeric_limits::max()); + + for (auto&& [codeSectionIndex, codeSection]: m_codeSections | ranges::views::enumerate) + { + auto const sectionStart = ret.bytecode.size(); + + for (AssemblyItem const& item: codeSection.items) + { + // store position of the invalid jump destination + if (item.type() != Tag && m_tagPositionsInBytecode[0] == std::numeric_limits::max()) + m_tagPositionsInBytecode[0] = ret.bytecode.size(); + + switch (item.type()) + { + case Operation: + ret.bytecode.push_back(static_cast(item.instruction())); + break; + case Push: + { + unsigned pushValueSize = numberEncodingSize(item.data()); + if (pushValueSize == 0 && !m_evmVersion.hasPush0()) + { + pushValueSize = 1; + } + ret.bytecode.push_back(static_cast(pushInstruction(pushValueSize))); + if (pushValueSize > 0) + { + ret.bytecode.resize(ret.bytecode.size() + pushValueSize); + bytesRef pushValueBytecodeRef(&ret.bytecode.back() + 1 - pushValueSize, pushValueSize); + toBigEndian(item.data(), pushValueBytecodeRef); + } + break; + } + case PushLibraryAddress: + ret.bytecode.push_back(static_cast(Instruction::PUSH20)); + ret.linkReferences[ret.bytecode.size()] = m_libraries.at(item.data()); + ret.bytecode.resize(ret.bytecode.size() + 20); + break; + case VerbatimBytecode: + ret.bytecode += item.verbatimData(); + break; + case PushDeployTimeAddress: + ret.bytecode.push_back(static_cast(Instruction::PUSH20)); + ret.bytecode.resize(ret.bytecode.size() + 20); + break; + case Tag: + { + solRequire(item.data() != 0, AssemblyException, "Invalid tag position."); + solRequire(item.splitForeignPushTag().first == std::numeric_limits::max(), AssemblyException, "Foreign tag."); + size_t tagId = static_cast(item.data()); + solRequire(ret.bytecode.size() < 0xffffffffL, AssemblyException, "Tag too large."); + solRequire(m_tagPositionsInBytecode[tagId] == std::numeric_limits::max(), AssemblyException, "Duplicate tag position."); + m_tagPositionsInBytecode[tagId] = ret.bytecode.size(); + break; + } + default: + solRequire(false, InvalidOpcode, "Unexpected opcode while assembling."); + } + } + + auto sectionEnd = ret.bytecode.size(); + setBigEndianUint16(ret.bytecode, codeSectionSizeOffsets[codeSectionIndex], sectionEnd - sectionStart); + } + + for (auto i: referencedSubIds) + ret.bytecode += m_subs[i]->assemble().bytecode; + + // TODO: Fill functionDebugData for EOF. It probably should be handled for new code section in the loop above. + solRequire(m_namedTags.empty(), AssemblyException, "Named tags must be empty in EOF context."); + + auto const dataStart = ret.bytecode.size(); + + for (auto const& dataItem: m_data) + ret.bytecode += dataItem.second; + + ret.bytecode += m_auxiliaryData; + + auto dataLength = ret.bytecode.size() - dataStart; + setBigEndianUint16(ret.bytecode, dataSectionSizeOffset, dataLength); + + return ret; +} + std::vector Assembly::decodeSubPath(size_t _subObjectId) const { if (_subObjectId < m_subs.size()) diff --git a/libevmasm/Assembly.h b/libevmasm/Assembly.h index 2b0ef93df220..41e735db612f 100644 --- a/libevmasm/Assembly.h +++ b/libevmasm/Assembly.h @@ -49,11 +49,14 @@ class Assembly { public: Assembly(langutil::EVMVersion _evmVersion, bool _creation, std::optional _eofVersion, std::string _name): - m_evmVersion(_evmVersion), - m_creation(_creation), - m_eofVersion(_eofVersion), - m_name(std::move(_name)) - {} + m_evmVersion(_evmVersion), + m_creation(_creation), + m_eofVersion(_eofVersion), + m_name(std::move(_name)) + { + // Code section number 0 has to be non-returning. + m_codeSections.emplace_back(CodeSection{0, 0x80, {}}); + } std::optional eofVersion() const { return m_eofVersion; } AssemblyItem newTag() { assertThrow(m_usedTags < 0xffffffff, AssemblyException, ""); return AssemblyItem(Tag, m_usedTags++); } @@ -103,12 +106,6 @@ class Assembly /// Appends @a _data literally to the very end of the bytecode. void appendToAuxiliaryData(bytes const& _data) { m_auxiliaryData += _data; } - /// Returns the assembly items. - AssemblyItems const& items() const { return m_items; } - - /// Returns the mutable assembly items. Use with care! - AssemblyItems& items() { return m_items; } - int deposit() const { return m_deposit; } void adjustDeposit(int _adjustment) { m_deposit += _adjustment; assertThrow(m_deposit >= 0, InvalidDeposit, ""); } void setDeposit(int _deposit) { m_deposit = _deposit; assertThrow(m_deposit >= 0, InvalidDeposit, ""); } @@ -170,7 +167,8 @@ class Assembly static std::pair, std::vector> fromJSON( Json const& _json, std::vector const& _sourceList = {}, - size_t _level = 0 + size_t _level = 0, + std::optional _eofVersion = std::nullopt ); /// Mark this assembly as invalid. Calling ``assemble`` on it will throw. @@ -181,12 +179,30 @@ class Assembly bool isCreation() const { return m_creation; } + struct CodeSection + { + uint8_t inputs = 0; + uint8_t outputs = 0; + AssemblyItems items{}; + }; + + std::vector& codeSections() + { + return m_codeSections; + } + + std::vector const& codeSections() const + { + return m_codeSections; + } + protected: /// Does the same operations as @a optimise, but should only be applied to a sub and /// returns the replaced tags. Also takes an argument containing the tags of this assembly /// that are referenced in a super-assembly. std::map const& optimiseInternal(OptimiserSettings const& _settings, std::set _tagsReferencedFromOutside); + /// For EOF and legacy it calculates approximate size of "pure" code without data. unsigned codeSize(unsigned subTagSize) const; /// Add all assembly items from given JSON array. This function imports the items by iterating through @@ -210,6 +226,15 @@ class Assembly std::shared_ptr sharedSourceName(std::string const& _name) const; + /// Returns EOF header bytecode | code section sizes offsets | data section size offset + std::tuple, size_t> createEOFHeader(std::set const& _referencedSubIds) const; + + LinkerObject const& assembleLegacy() const; + LinkerObject const& assembleEOF() const; + + /// Returns map from m_subs to an index of subcontainer in the final EOF bytecode + std::map findReferencedContainers() const; + protected: /// 0 is reserved for exception unsigned m_usedTags = 1; @@ -223,11 +248,12 @@ class Assembly }; std::map m_namedTags; - AssemblyItems m_items; std::map m_data; /// Data that is appended to the very end of the contract. bytes m_auxiliaryData; std::vector> m_subs; + std::vector m_codeSections; + uint16_t m_currentCodeSection = 0; std::map m_strings; std::map m_libraries; ///< Identifiers of libraries to be linked. std::map m_immutables; ///< Identifiers of immutables. diff --git a/libevmasm/ConstantOptimiser.cpp b/libevmasm/ConstantOptimiser.cpp index 360fb781f4d7..6fdb42bd76d0 100644 --- a/libevmasm/ConstantOptimiser.cpp +++ b/libevmasm/ConstantOptimiser.cpp @@ -35,46 +35,49 @@ unsigned ConstantOptimisationMethod::optimiseConstants( ) { // TODO: design the optimiser in a way this is not needed - AssemblyItems& _items = _assembly.items(); - unsigned optimisations = 0; - std::map pushes; - for (AssemblyItem const& item: _items) - if (item.type() == Push) - pushes[item]++; - std::map pendingReplacements; - for (auto it: pushes) + for (auto& codeSection: _assembly.codeSections()) { - AssemblyItem const& item = it.first; - if (item.data() < 0x100) - continue; - Params params; - params.multiplicity = it.second; - params.isCreation = _isCreation; - params.runs = _runs; - params.evmVersion = _evmVersion; - LiteralMethod lit(params, item.data()); - bigint literalGas = lit.gasNeeded(); - CodeCopyMethod copy(params, item.data()); - bigint copyGas = copy.gasNeeded(); - ComputeMethod compute(params, item.data()); - bigint computeGas = compute.gasNeeded(); - AssemblyItems replacement; - if (copyGas < literalGas && copyGas < computeGas) - { - replacement = copy.execute(_assembly); - optimisations++; - } - else if (computeGas < literalGas && computeGas <= copyGas) + AssemblyItems& _items = codeSection.items; + + std::map pushes; + for (AssemblyItem const& item: _items) + if (item.type() == Push) + pushes[item]++; + std::map pendingReplacements; + for (auto it: pushes) { - replacement = compute.execute(_assembly); - optimisations++; + AssemblyItem const& item = it.first; + if (item.data() < 0x100) + continue; + Params params; + params.multiplicity = it.second; + params.isCreation = _isCreation; + params.runs = _runs; + params.evmVersion = _evmVersion; + LiteralMethod lit(params, item.data()); + bigint literalGas = lit.gasNeeded(); + CodeCopyMethod copy(params, item.data()); + bigint copyGas = copy.gasNeeded(); + ComputeMethod compute(params, item.data()); + bigint computeGas = compute.gasNeeded(); + AssemblyItems replacement; + if (copyGas < literalGas && copyGas < computeGas) + { + replacement = copy.execute(_assembly); + optimisations++; + } + else if (computeGas < literalGas && computeGas <= copyGas) + { + replacement = compute.execute(_assembly); + optimisations++; + } + if (!replacement.empty()) + pendingReplacements[item.data()] = replacement; } - if (!replacement.empty()) - pendingReplacements[item.data()] = replacement; + if (!pendingReplacements.empty()) + replaceConstants(_items, pendingReplacements); } - if (!pendingReplacements.empty()) - replaceConstants(_items, pendingReplacements); return optimisations; } diff --git a/libevmasm/EVMAssemblyStack.cpp b/libevmasm/EVMAssemblyStack.cpp index 20605ee354a0..afe67c5fc85e 100644 --- a/libevmasm/EVMAssemblyStack.cpp +++ b/libevmasm/EVMAssemblyStack.cpp @@ -56,12 +56,16 @@ void EVMAssemblyStack::assemble() solAssert(!m_evmRuntimeAssembly); m_object = m_evmAssembly->assemble(); - m_sourceMapping = AssemblyItem::computeSourceMapping(m_evmAssembly->items(), sourceIndices()); + // TODO: Check for EOF + solAssert(m_evmAssembly->codeSections().size() == 1); + m_sourceMapping = AssemblyItem::computeSourceMapping(m_evmAssembly->codeSections().front().items, sourceIndices()); if (m_evmAssembly->numSubs() > 0) { m_evmRuntimeAssembly = std::make_shared(m_evmAssembly->sub(0)); solAssert(m_evmRuntimeAssembly && !m_evmRuntimeAssembly->isCreation()); - m_runtimeSourceMapping = AssemblyItem::computeSourceMapping(m_evmRuntimeAssembly->items(), sourceIndices()); + // TODO: Check for EOF + solAssert(m_evmRuntimeAssembly->codeSections().size() == 1); + m_runtimeSourceMapping = AssemblyItem::computeSourceMapping(m_evmRuntimeAssembly->codeSections().front().items, sourceIndices()); m_runtimeObject = m_evmRuntimeAssembly->assemble(); } } diff --git a/libsolidity/interface/CompilerStack.cpp b/libsolidity/interface/CompilerStack.cpp index 3389e7eca94b..e538823f13ab 100644 --- a/libsolidity/interface/CompilerStack.cpp +++ b/libsolidity/interface/CompilerStack.cpp @@ -808,7 +808,11 @@ evmasm::AssemblyItems const* CompilerStack::assemblyItems(std::string const& _co solAssert(m_stackState == CompilationSuccessful, "Compilation was not successful."); Contract const& currentContract = contract(_contractName); - return currentContract.evmAssembly ? ¤tContract.evmAssembly->items() : nullptr; + if (!currentContract.evmAssembly) + return nullptr; + solUnimplementedAssert(!m_eofVersion.has_value(), "EVM assembly output not implemented for EOF yet."); + solAssert(currentContract.evmAssembly->codeSections().size() == 1, "Expected a single code section in legacy codegen."); + return ¤tContract.evmAssembly->codeSections().front().items; } evmasm::AssemblyItems const* CompilerStack::runtimeAssemblyItems(std::string const& _contractName) const @@ -816,7 +820,12 @@ evmasm::AssemblyItems const* CompilerStack::runtimeAssemblyItems(std::string con solAssert(m_stackState == CompilationSuccessful, "Compilation was not successful."); Contract const& currentContract = contract(_contractName); - return currentContract.evmRuntimeAssembly ? ¤tContract.evmRuntimeAssembly->items() : nullptr; + + if (!currentContract.evmRuntimeAssembly) + return nullptr; + solUnimplementedAssert(!m_eofVersion.has_value(), "EVM assembly output not implemented for EOF yet."); + solAssert(currentContract.evmRuntimeAssembly->codeSections().size() == 1, "Expected a single code section in legacy codegen."); + return ¤tContract.evmRuntimeAssembly->codeSections().front().items; } Json CompilerStack::generatedSources(std::string const& _contractName, bool _runtime) const diff --git a/libyul/YulStack.cpp b/libyul/YulStack.cpp index 01eb5b7383cd..a8e19a69a179 100644 --- a/libyul/YulStack.cpp +++ b/libyul/YulStack.cpp @@ -262,9 +262,12 @@ YulStack::assembleWithDeployed(std::optional _deployName) creationObject.bytecode = std::make_shared(creationAssembly->assemble()); yulAssert(creationObject.bytecode->immutableReferences.empty(), "Leftover immutables."); creationObject.assembly = creationAssembly; + solUnimplementedAssert(!m_eofVersion.has_value(), "EVM assembly output not implemented for EOF yet."); + solAssert(creationAssembly->codeSections().size() == 1); creationObject.sourceMappings = std::make_unique( + // TODO: fix for EOF evmasm::AssemblyItem::computeSourceMapping( - creationAssembly->items(), + creationAssembly->codeSections().front().items, {{m_charStream->name(), 0}} ) ); @@ -273,11 +276,12 @@ YulStack::assembleWithDeployed(std::optional _deployName) { deployedObject.bytecode = std::make_shared(deployedAssembly->assemble()); deployedObject.assembly = deployedAssembly; + solAssert(deployedAssembly->codeSections().size() == 1); deployedObject.sourceMappings = std::make_unique( evmasm::AssemblyItem::computeSourceMapping( - deployedAssembly->items(), + deployedAssembly->codeSections().front().items, {{m_charStream->name(), 0}} - ) + ) ); } } diff --git a/test/libevmasm/Assembler.cpp b/test/libevmasm/Assembler.cpp index 06c7fb6a97eb..b1222b49d1ae 100644 --- a/test/libevmasm/Assembler.cpp +++ b/test/libevmasm/Assembler.cpp @@ -270,7 +270,8 @@ BOOST_AUTO_TEST_CASE(immutables_and_its_source_maps) checkCompilation(assembly); - std::string const sourceMappings = AssemblyItem::computeSourceMapping(assembly.items(), indices); + BOOST_REQUIRE(assembly.codeSections().size() == 1); + std::string const sourceMappings = AssemblyItem::computeSourceMapping(assembly.codeSections().at(0).items, indices); auto const numberOfMappings = std::count(sourceMappings.begin(), sourceMappings.end(), ';'); LinkerObject const& obj = assembly.assemble(); diff --git a/test/libevmasm/Optimiser.cpp b/test/libevmasm/Optimiser.cpp index 13d9d6f2bb6f..8ed413cfe199 100644 --- a/test/libevmasm/Optimiser.cpp +++ b/test/libevmasm/Optimiser.cpp @@ -1381,16 +1381,18 @@ BOOST_AUTO_TEST_CASE(jumpdest_removal_subassemblies) t1.toSubAssemblyTag(subId).pushTag(), u256(8) }; + BOOST_REQUIRE(main.codeSections().size() == 1); BOOST_CHECK_EQUAL_COLLECTIONS( - main.items().begin(), main.items().end(), + main.codeSections().at(0).items.begin(),main.codeSections().at(0).items.end(), expectationMain.begin(), expectationMain.end() ); AssemblyItems expectationSub{ u256(1), t1.tag(), u256(2), Instruction::JUMP, t4.tag(), u256(7), t4.pushTag(), Instruction::JUMP }; + BOOST_REQUIRE(sub->codeSections().size() == 1); BOOST_CHECK_EQUAL_COLLECTIONS( - sub->items().begin(), sub->items().end(), + sub->codeSections().at(0).items.begin(), sub->codeSections().at(0).items.end(), expectationSub.begin(), expectationSub.end() ); } diff --git a/test/libsolidity/Assembly.cpp b/test/libsolidity/Assembly.cpp index 7def76e69fe2..03897c454c37 100644 --- a/test/libsolidity/Assembly.cpp +++ b/test/libsolidity/Assembly.cpp @@ -91,7 +91,8 @@ evmasm::AssemblyItems compileContract(std::shared_ptr _sourceCode) ); compiler.compileContract(*contract, std::map>{}, bytes()); - return compiler.runtimeAssembly().items(); + BOOST_REQUIRE(compiler.runtimeAssembly().codeSections().size() == 1); + return compiler.runtimeAssembly().codeSections().at(0).items; } BOOST_FAIL("No contract found in source."); return AssemblyItems(); From 603d9ded7f9e708e67542f0644d65cdba05c681e Mon Sep 17 00:00:00 2001 From: rodiazet Date: Fri, 20 Sep 2024 10:30:56 +0200 Subject: [PATCH 0432/1022] eof: pass EOF flag to `Assembly::fromJSON` --- libevmasm/Assembly.cpp | 2 +- libevmasm/EVMAssemblyStack.cpp | 2 +- libevmasm/EVMAssemblyStack.h | 4 +++- libsolidity/interface/StandardCompiler.cpp | 2 +- solc/CommandLineInterface.cpp | 2 +- 5 files changed, 7 insertions(+), 5 deletions(-) diff --git a/libevmasm/Assembly.cpp b/libevmasm/Assembly.cpp index df78f43ca59f..0d5468e2678e 100644 --- a/libevmasm/Assembly.cpp +++ b/libevmasm/Assembly.cpp @@ -630,7 +630,7 @@ std::pair, std::vector> Assembly::fromJSO solThrow(AssemblyImportException, "The key '" + key + "' inside '.data' is out of the supported integer range."); } - auto [subAssembly, emptySourceList] = Assembly::fromJSON(value, _level == 0 ? parsedSourceList : _sourceList, _level + 1); + auto [subAssembly, emptySourceList] = Assembly::fromJSON(value, _level == 0 ? parsedSourceList : _sourceList, _level + 1, _eofVersion); solAssert(subAssembly); solAssert(emptySourceList.empty()); solAssert(subAssemblies.count(index) == 0); diff --git a/libevmasm/EVMAssemblyStack.cpp b/libevmasm/EVMAssemblyStack.cpp index afe67c5fc85e..df4517fc522b 100644 --- a/libevmasm/EVMAssemblyStack.cpp +++ b/libevmasm/EVMAssemblyStack.cpp @@ -45,7 +45,7 @@ void EVMAssemblyStack::analyze(std::string const& _sourceName, Json const& _asse { solAssert(!m_evmAssembly); m_name = _sourceName; - std::tie(m_evmAssembly, m_sourceList) = evmasm::Assembly::fromJSON(_assemblyJson); + std::tie(m_evmAssembly, m_sourceList) = evmasm::Assembly::fromJSON(_assemblyJson, {}, 0, m_eofVersion); solRequire(m_evmAssembly != nullptr, AssemblyImportException, "Could not create evm assembly object."); } diff --git a/libevmasm/EVMAssemblyStack.h b/libevmasm/EVMAssemblyStack.h index f2516c0b8a0a..cf959de79c1a 100644 --- a/libevmasm/EVMAssemblyStack.h +++ b/libevmasm/EVMAssemblyStack.h @@ -33,7 +33,8 @@ namespace solidity::evmasm class EVMAssemblyStack: public AbstractAssemblyStack { public: - explicit EVMAssemblyStack(langutil::EVMVersion _evmVersion): m_evmVersion(_evmVersion) {} + explicit EVMAssemblyStack(langutil::EVMVersion _evmVersion, std::optional _eofVersion): + m_evmVersion(_evmVersion), m_eofVersion(_eofVersion) {} /// Runs parsing and analysis steps. /// Multiple calls overwrite the previous state. @@ -76,6 +77,7 @@ class EVMAssemblyStack: public AbstractAssemblyStack private: langutil::EVMVersion m_evmVersion; + std::optional m_eofVersion; std::string m_name; std::shared_ptr m_evmAssembly; std::shared_ptr m_evmRuntimeAssembly; diff --git a/libsolidity/interface/StandardCompiler.cpp b/libsolidity/interface/StandardCompiler.cpp index 7271cce8bee7..cd00caf073b3 100644 --- a/libsolidity/interface/StandardCompiler.cpp +++ b/libsolidity/interface/StandardCompiler.cpp @@ -1204,7 +1204,7 @@ Json StandardCompiler::importEVMAssembly(StandardCompiler::InputsAndSettings _in if (!isBinaryRequested(_inputsAndSettings.outputSelection)) return Json::object(); - evmasm::EVMAssemblyStack stack(_inputsAndSettings.evmVersion); + evmasm::EVMAssemblyStack stack(_inputsAndSettings.evmVersion, _inputsAndSettings.eofVersion); std::string const& sourceName = _inputsAndSettings.jsonSources.begin()->first; // result of structured binding can only be used within lambda from C++20 on. Json const& sourceJson = _inputsAndSettings.jsonSources.begin()->second; try diff --git a/solc/CommandLineInterface.cpp b/solc/CommandLineInterface.cpp index f78fdfeb81c9..2d815facc18d 100644 --- a/solc/CommandLineInterface.cpp +++ b/solc/CommandLineInterface.cpp @@ -843,7 +843,7 @@ void CommandLineInterface::assembleFromEVMAssemblyJSON() solAssert(m_fileReader.sourceUnits().size() == 1); auto&& [sourceUnitName, source] = *m_fileReader.sourceUnits().begin(); - auto evmAssemblyStack = std::make_unique(m_options.output.evmVersion); + auto evmAssemblyStack = std::make_unique(m_options.output.evmVersion, m_options.output.eofVersion); try { evmAssemblyStack->parseAndAnalyze(sourceUnitName, source); From bc9f3e0c20224f9d3b9c8847b6f3c0f4a6f526d3 Mon Sep 17 00:00:00 2001 From: rodiazet Date: Fri, 20 Sep 2024 15:35:49 +0200 Subject: [PATCH 0433/1022] eof: Add container format test --- .../strict_asm_eof_container_prague/args | 1 + .../strict_asm_eof_container_prague/input.yul | 36 +++++++++++++++++++ .../strict_asm_eof_container_prague/output | 5 +++ 3 files changed, 42 insertions(+) create mode 100644 test/cmdlineTests/strict_asm_eof_container_prague/args create mode 100644 test/cmdlineTests/strict_asm_eof_container_prague/input.yul create mode 100644 test/cmdlineTests/strict_asm_eof_container_prague/output diff --git a/test/cmdlineTests/strict_asm_eof_container_prague/args b/test/cmdlineTests/strict_asm_eof_container_prague/args new file mode 100644 index 000000000000..b8cc1ab18211 --- /dev/null +++ b/test/cmdlineTests/strict_asm_eof_container_prague/args @@ -0,0 +1 @@ + --strict-assembly --experimental-eof-version 1 --evm-version prague --bin diff --git a/test/cmdlineTests/strict_asm_eof_container_prague/input.yul b/test/cmdlineTests/strict_asm_eof_container_prague/input.yul new file mode 100644 index 000000000000..09306772c9a9 --- /dev/null +++ b/test/cmdlineTests/strict_asm_eof_container_prague/input.yul @@ -0,0 +1,36 @@ +object "object" { + code { + revert(0, 0) + } + + object "sub0" { + code { + mstore(0, 0) + revert(0, 32) + } + } + object "sub1" { + code { + mstore(0, 1) + revert(0, 32) + } + } + object "sub2" { + code { + mstore(0, 2) + revert(0, 32) + } + object "sub20" { + code { + mstore(0, 0x20) + revert(0, 32) + } + } + } + object "sub3" { + code { + mstore(0, 3) + revert(0, 32) + } + } +} \ No newline at end of file diff --git a/test/cmdlineTests/strict_asm_eof_container_prague/output b/test/cmdlineTests/strict_asm_eof_container_prague/output new file mode 100644 index 000000000000..caf28d91d88e --- /dev/null +++ b/test/cmdlineTests/strict_asm_eof_container_prague/output @@ -0,0 +1,5 @@ + +======= strict_asm_eof_container_prague/input.yul (EVM) ======= + +Binary representation: +ef00010100040200010003030004001a001b003b001b040000000080ffff5f80fdef00010100040200010007040000000080ffff5f805260205ffdef00010100040200010008040000000080ffff60015f5260205ffdef00010100040200010008030001001b040000000080ffff60025f5260205ffdef00010100040200010008040000000080ffff60205f5260205ffdef00010100040200010008040000000080ffff60035f5260205ffd From 1ba4349f859d53cd9fea7d7a66475b193d3d5538 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Mon, 23 Sep 2024 12:58:16 +0200 Subject: [PATCH 0434/1022] Rename Standard JSON output selection tests CLI to match the naming convention --- .../input.json | 0 .../output.json | 0 .../input.json | 0 .../output.json | 0 .../input.json | 0 .../output.json | 0 .../input.json | 0 .../output.json | 0 .../input.json | 0 .../output.json | 0 .../input.json | 0 .../output.json | 0 .../input.json | 0 .../output.json | 0 .../input.json | 0 .../output.json | 0 .../input.json | 0 .../output.json | 0 .../input.json | 0 .../output.json | 0 .../input.json | 0 .../output.json | 0 22 files changed, 0 insertions(+), 0 deletions(-) rename test/cmdlineTests/{output_selection_all_blank => standard_output_selection_all_blank}/input.json (100%) rename test/cmdlineTests/{output_selection_all_blank => standard_output_selection_all_blank}/output.json (100%) rename test/cmdlineTests/{output_selection_all_A2 => standard_output_selection_all_sources_single_contract_multiple_matches}/input.json (100%) rename test/cmdlineTests/{output_selection_all_A2 => standard_output_selection_all_sources_single_contract_multiple_matches}/output.json (100%) rename test/cmdlineTests/{output_selection_all_A1 => standard_output_selection_all_sources_single_contract_single_match}/input.json (100%) rename test/cmdlineTests/{output_selection_all_A1 => standard_output_selection_all_sources_single_contract_single_match}/output.json (100%) rename test/cmdlineTests/{output_selection_all_star => standard_output_selection_all_star}/input.json (100%) rename test/cmdlineTests/{output_selection_all_star => standard_output_selection_all_star}/output.json (100%) rename test/cmdlineTests/{output_selection_single_all => standard_output_selection_single_all}/input.json (100%) rename test/cmdlineTests/{output_selection_single_all => standard_output_selection_single_all}/output.json (100%) rename test/cmdlineTests/{output_selection_single_A1 => standard_output_selection_single_source_single_contract_multiple_matches}/input.json (100%) rename test/cmdlineTests/{output_selection_single_A1 => standard_output_selection_single_source_single_contract_multiple_matches}/output.json (100%) rename test/cmdlineTests/{output_selection_single_B1 => standard_output_selection_single_source_single_contract_single_match}/input.json (100%) rename test/cmdlineTests/{output_selection_single_B1 => standard_output_selection_single_source_single_contract_single_match}/output.json (100%) rename test/cmdlineTests/{standard_wrong_type_output_selection => standard_output_selection_wrong_type}/input.json (100%) rename test/cmdlineTests/{standard_wrong_type_output_selection => standard_output_selection_wrong_type}/output.json (100%) rename test/cmdlineTests/{standard_wrong_type_output_selection_contract => standard_output_selection_wrong_type_contract}/input.json (100%) rename test/cmdlineTests/{standard_wrong_type_output_selection_contract => standard_output_selection_wrong_type_contract}/output.json (100%) rename test/cmdlineTests/{standard_wrong_type_output_selection_output => standard_output_selection_wrong_type_output}/input.json (100%) rename test/cmdlineTests/{standard_wrong_type_output_selection_output => standard_output_selection_wrong_type_output}/output.json (100%) rename test/cmdlineTests/{standard_wrong_type_output_selection_file => standard_output_selection_wrong_type_source}/input.json (100%) rename test/cmdlineTests/{standard_wrong_type_output_selection_file => standard_output_selection_wrong_type_source}/output.json (100%) diff --git a/test/cmdlineTests/output_selection_all_blank/input.json b/test/cmdlineTests/standard_output_selection_all_blank/input.json similarity index 100% rename from test/cmdlineTests/output_selection_all_blank/input.json rename to test/cmdlineTests/standard_output_selection_all_blank/input.json diff --git a/test/cmdlineTests/output_selection_all_blank/output.json b/test/cmdlineTests/standard_output_selection_all_blank/output.json similarity index 100% rename from test/cmdlineTests/output_selection_all_blank/output.json rename to test/cmdlineTests/standard_output_selection_all_blank/output.json diff --git a/test/cmdlineTests/output_selection_all_A2/input.json b/test/cmdlineTests/standard_output_selection_all_sources_single_contract_multiple_matches/input.json similarity index 100% rename from test/cmdlineTests/output_selection_all_A2/input.json rename to test/cmdlineTests/standard_output_selection_all_sources_single_contract_multiple_matches/input.json diff --git a/test/cmdlineTests/output_selection_all_A2/output.json b/test/cmdlineTests/standard_output_selection_all_sources_single_contract_multiple_matches/output.json similarity index 100% rename from test/cmdlineTests/output_selection_all_A2/output.json rename to test/cmdlineTests/standard_output_selection_all_sources_single_contract_multiple_matches/output.json diff --git a/test/cmdlineTests/output_selection_all_A1/input.json b/test/cmdlineTests/standard_output_selection_all_sources_single_contract_single_match/input.json similarity index 100% rename from test/cmdlineTests/output_selection_all_A1/input.json rename to test/cmdlineTests/standard_output_selection_all_sources_single_contract_single_match/input.json diff --git a/test/cmdlineTests/output_selection_all_A1/output.json b/test/cmdlineTests/standard_output_selection_all_sources_single_contract_single_match/output.json similarity index 100% rename from test/cmdlineTests/output_selection_all_A1/output.json rename to test/cmdlineTests/standard_output_selection_all_sources_single_contract_single_match/output.json diff --git a/test/cmdlineTests/output_selection_all_star/input.json b/test/cmdlineTests/standard_output_selection_all_star/input.json similarity index 100% rename from test/cmdlineTests/output_selection_all_star/input.json rename to test/cmdlineTests/standard_output_selection_all_star/input.json diff --git a/test/cmdlineTests/output_selection_all_star/output.json b/test/cmdlineTests/standard_output_selection_all_star/output.json similarity index 100% rename from test/cmdlineTests/output_selection_all_star/output.json rename to test/cmdlineTests/standard_output_selection_all_star/output.json diff --git a/test/cmdlineTests/output_selection_single_all/input.json b/test/cmdlineTests/standard_output_selection_single_all/input.json similarity index 100% rename from test/cmdlineTests/output_selection_single_all/input.json rename to test/cmdlineTests/standard_output_selection_single_all/input.json diff --git a/test/cmdlineTests/output_selection_single_all/output.json b/test/cmdlineTests/standard_output_selection_single_all/output.json similarity index 100% rename from test/cmdlineTests/output_selection_single_all/output.json rename to test/cmdlineTests/standard_output_selection_single_all/output.json diff --git a/test/cmdlineTests/output_selection_single_A1/input.json b/test/cmdlineTests/standard_output_selection_single_source_single_contract_multiple_matches/input.json similarity index 100% rename from test/cmdlineTests/output_selection_single_A1/input.json rename to test/cmdlineTests/standard_output_selection_single_source_single_contract_multiple_matches/input.json diff --git a/test/cmdlineTests/output_selection_single_A1/output.json b/test/cmdlineTests/standard_output_selection_single_source_single_contract_multiple_matches/output.json similarity index 100% rename from test/cmdlineTests/output_selection_single_A1/output.json rename to test/cmdlineTests/standard_output_selection_single_source_single_contract_multiple_matches/output.json diff --git a/test/cmdlineTests/output_selection_single_B1/input.json b/test/cmdlineTests/standard_output_selection_single_source_single_contract_single_match/input.json similarity index 100% rename from test/cmdlineTests/output_selection_single_B1/input.json rename to test/cmdlineTests/standard_output_selection_single_source_single_contract_single_match/input.json diff --git a/test/cmdlineTests/output_selection_single_B1/output.json b/test/cmdlineTests/standard_output_selection_single_source_single_contract_single_match/output.json similarity index 100% rename from test/cmdlineTests/output_selection_single_B1/output.json rename to test/cmdlineTests/standard_output_selection_single_source_single_contract_single_match/output.json diff --git a/test/cmdlineTests/standard_wrong_type_output_selection/input.json b/test/cmdlineTests/standard_output_selection_wrong_type/input.json similarity index 100% rename from test/cmdlineTests/standard_wrong_type_output_selection/input.json rename to test/cmdlineTests/standard_output_selection_wrong_type/input.json diff --git a/test/cmdlineTests/standard_wrong_type_output_selection/output.json b/test/cmdlineTests/standard_output_selection_wrong_type/output.json similarity index 100% rename from test/cmdlineTests/standard_wrong_type_output_selection/output.json rename to test/cmdlineTests/standard_output_selection_wrong_type/output.json diff --git a/test/cmdlineTests/standard_wrong_type_output_selection_contract/input.json b/test/cmdlineTests/standard_output_selection_wrong_type_contract/input.json similarity index 100% rename from test/cmdlineTests/standard_wrong_type_output_selection_contract/input.json rename to test/cmdlineTests/standard_output_selection_wrong_type_contract/input.json diff --git a/test/cmdlineTests/standard_wrong_type_output_selection_contract/output.json b/test/cmdlineTests/standard_output_selection_wrong_type_contract/output.json similarity index 100% rename from test/cmdlineTests/standard_wrong_type_output_selection_contract/output.json rename to test/cmdlineTests/standard_output_selection_wrong_type_contract/output.json diff --git a/test/cmdlineTests/standard_wrong_type_output_selection_output/input.json b/test/cmdlineTests/standard_output_selection_wrong_type_output/input.json similarity index 100% rename from test/cmdlineTests/standard_wrong_type_output_selection_output/input.json rename to test/cmdlineTests/standard_output_selection_wrong_type_output/input.json diff --git a/test/cmdlineTests/standard_wrong_type_output_selection_output/output.json b/test/cmdlineTests/standard_output_selection_wrong_type_output/output.json similarity index 100% rename from test/cmdlineTests/standard_wrong_type_output_selection_output/output.json rename to test/cmdlineTests/standard_output_selection_wrong_type_output/output.json diff --git a/test/cmdlineTests/standard_wrong_type_output_selection_file/input.json b/test/cmdlineTests/standard_output_selection_wrong_type_source/input.json similarity index 100% rename from test/cmdlineTests/standard_wrong_type_output_selection_file/input.json rename to test/cmdlineTests/standard_output_selection_wrong_type_source/input.json diff --git a/test/cmdlineTests/standard_wrong_type_output_selection_file/output.json b/test/cmdlineTests/standard_output_selection_wrong_type_source/output.json similarity index 100% rename from test/cmdlineTests/standard_wrong_type_output_selection_file/output.json rename to test/cmdlineTests/standard_output_selection_wrong_type_source/output.json From 3452ba0189f0a086d2a0926a757226bfeb23fb59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Mon, 23 Sep 2024 14:04:53 +0200 Subject: [PATCH 0435/1022] More CLI tests for output selection in Standard JSON --- .../input.json | 13 ++ .../output.json | 24 +++ .../input.json | 13 ++ .../output.json | 42 ++++++ .../input.json | 29 ++++ .../output.json | 35 +++++ .../input.json | 9 ++ .../output.json | 7 + .../input.json | 29 ++++ .../output.json | 109 ++++++++++++++ .../input.json | 23 +++ .../output.json | 141 ++++++++++++++++++ .../input.json | 16 ++ .../output.json | 13 ++ .../input.json | 24 +++ .../output.json | 18 +++ .../input.json | 21 +++ .../output.json | 21 +++ 18 files changed, 587 insertions(+) create mode 100644 test/cmdlineTests/standard_output_selection_all_sources_blank_contract_named_blank/input.json create mode 100644 test/cmdlineTests/standard_output_selection_all_sources_blank_contract_named_blank/output.json create mode 100644 test/cmdlineTests/standard_output_selection_all_sources_star_contract_named_star/input.json create mode 100644 test/cmdlineTests/standard_output_selection_all_sources_star_contract_named_star/output.json create mode 100644 test/cmdlineTests/standard_output_selection_duplicate_matching_source_and_contract_selectors/input.json create mode 100644 test/cmdlineTests/standard_output_selection_duplicate_matching_source_and_contract_selectors/output.json create mode 100644 test/cmdlineTests/standard_output_selection_empty/input.json create mode 100644 test/cmdlineTests/standard_output_selection_empty/output.json create mode 100644 test/cmdlineTests/standard_output_selection_multiple_matching_source_and_contract_selectors/input.json create mode 100644 test/cmdlineTests/standard_output_selection_multiple_matching_source_and_contract_selectors/output.json create mode 100644 test/cmdlineTests/standard_output_selection_multiple_matching_source_and_contract_selectors_full_pipeline/input.json create mode 100644 test/cmdlineTests/standard_output_selection_multiple_matching_source_and_contract_selectors_full_pipeline/output.json create mode 100644 test/cmdlineTests/standard_output_selection_no_output_selected/input.json create mode 100644 test/cmdlineTests/standard_output_selection_no_output_selected/output.json create mode 100644 test/cmdlineTests/standard_output_selection_unrecognized_output/input.json create mode 100644 test/cmdlineTests/standard_output_selection_unrecognized_output/output.json create mode 100644 test/cmdlineTests/standard_output_selection_unrecognized_source_and_contract_selectors/input.json create mode 100644 test/cmdlineTests/standard_output_selection_unrecognized_source_and_contract_selectors/output.json diff --git a/test/cmdlineTests/standard_output_selection_all_sources_blank_contract_named_blank/input.json b/test/cmdlineTests/standard_output_selection_all_sources_blank_contract_named_blank/input.json new file mode 100644 index 000000000000..9a2634aa7190 --- /dev/null +++ b/test/cmdlineTests/standard_output_selection_all_sources_blank_contract_named_blank/input.json @@ -0,0 +1,13 @@ +{ + "language": "Solidity", + "sources": { + "": {"content": "contract D {}\n//SPDX-License-Identifier: GPL-3.0\npragma solidity *;"}, + "*": {"content": "contract D {}\n//SPDX-License-Identifier: GPL-3.0\npragma solidity *;"}, + "C": {"content": "contract D {}\n//SPDX-License-Identifier: GPL-3.0\npragma solidity *;"} + }, + "settings": { + "outputSelection": { + "": {"D": ["userdoc"]} + } + } +} diff --git a/test/cmdlineTests/standard_output_selection_all_sources_blank_contract_named_blank/output.json b/test/cmdlineTests/standard_output_selection_all_sources_blank_contract_named_blank/output.json new file mode 100644 index 000000000000..ff82564fcf17 --- /dev/null +++ b/test/cmdlineTests/standard_output_selection_all_sources_blank_contract_named_blank/output.json @@ -0,0 +1,24 @@ +{ + "contracts": { + "": { + "D": { + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + } + } + } + }, + "sources": { + "": { + "id": 0 + }, + "*": { + "id": 1 + }, + "C": { + "id": 2 + } + } +} diff --git a/test/cmdlineTests/standard_output_selection_all_sources_star_contract_named_star/input.json b/test/cmdlineTests/standard_output_selection_all_sources_star_contract_named_star/input.json new file mode 100644 index 000000000000..950218048ec3 --- /dev/null +++ b/test/cmdlineTests/standard_output_selection_all_sources_star_contract_named_star/input.json @@ -0,0 +1,13 @@ +{ + "language": "Solidity", + "sources": { + "": {"content": "contract D {}\n//SPDX-License-Identifier: GPL-3.0\npragma solidity *;"}, + "*": {"content": "contract D {}\n//SPDX-License-Identifier: GPL-3.0\npragma solidity *;"}, + "C": {"content": "contract D {}\n//SPDX-License-Identifier: GPL-3.0\npragma solidity *;"} + }, + "settings": { + "outputSelection": { + "*": {"D": ["userdoc"]} + } + } +} diff --git a/test/cmdlineTests/standard_output_selection_all_sources_star_contract_named_star/output.json b/test/cmdlineTests/standard_output_selection_all_sources_star_contract_named_star/output.json new file mode 100644 index 000000000000..b5dda3d597f8 --- /dev/null +++ b/test/cmdlineTests/standard_output_selection_all_sources_star_contract_named_star/output.json @@ -0,0 +1,42 @@ +{ + "contracts": { + "": { + "D": { + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + } + } + }, + "*": { + "D": { + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + } + } + }, + "C": { + "D": { + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + } + } + } + }, + "sources": { + "": { + "id": 0 + }, + "*": { + "id": 1 + }, + "C": { + "id": 2 + } + } +} diff --git a/test/cmdlineTests/standard_output_selection_duplicate_matching_source_and_contract_selectors/input.json b/test/cmdlineTests/standard_output_selection_duplicate_matching_source_and_contract_selectors/input.json new file mode 100644 index 000000000000..70b7b079a4ef --- /dev/null +++ b/test/cmdlineTests/standard_output_selection_duplicate_matching_source_and_contract_selectors/input.json @@ -0,0 +1,29 @@ +{ + "language": "Solidity", + "sources": { + "*": {"content": "contract A {}\ncontract B {}\n//SPDX-License-Identifier: GPL-3.0\npragma solidity *;"}, + "C": {"content": "contract A {}\ncontract B {}\n//SPDX-License-Identifier: GPL-3.0\npragma solidity *;"}, + "D": {"content": "contract A {}\ncontract B {}\n//SPDX-License-Identifier: GPL-3.0\npragma solidity *;"} + }, + "settings": { + "outputSelection": { + // Outputs from duplicate keys are not combined. Last value wins. + "*": { + "*": ["userdoc"], // Ignored + "*": ["devdoc"] // Ignored + }, + "C": { + "*": ["storageLayout"], // Ignored + "*": ["transientStorageLayout"] // Ignored + }, + "C": { + "A": ["evm.bytecode.linkReferences"], // Ignored + "A": ["evm.bytecode.object"] + }, + "*": { + "A": ["evm.deployedBytecode.immutableReferences"], // Ignored + "A": ["abi"] + } + } + } +} diff --git a/test/cmdlineTests/standard_output_selection_duplicate_matching_source_and_contract_selectors/output.json b/test/cmdlineTests/standard_output_selection_duplicate_matching_source_and_contract_selectors/output.json new file mode 100644 index 000000000000..2743eb870a1e --- /dev/null +++ b/test/cmdlineTests/standard_output_selection_duplicate_matching_source_and_contract_selectors/output.json @@ -0,0 +1,35 @@ +{ + "contracts": { + "*": { + "A": { + "abi": [] + } + }, + "C": { + "A": { + "abi": [], + "evm": { + "bytecode": { + "object": "" + } + } + } + }, + "D": { + "A": { + "abi": [] + } + } + }, + "sources": { + "*": { + "id": 0 + }, + "C": { + "id": 1 + }, + "D": { + "id": 2 + } + } +} diff --git a/test/cmdlineTests/standard_output_selection_empty/input.json b/test/cmdlineTests/standard_output_selection_empty/input.json new file mode 100644 index 000000000000..76cc0fb48dac --- /dev/null +++ b/test/cmdlineTests/standard_output_selection_empty/input.json @@ -0,0 +1,9 @@ +{ + "language": "Solidity", + "sources": { + "C": {"content": "contract A {}\n//SPDX-License-Identifier: GPL-3.0\npragma solidity *;"} + }, + "settings": { + "outputSelection": {} + } +} diff --git a/test/cmdlineTests/standard_output_selection_empty/output.json b/test/cmdlineTests/standard_output_selection_empty/output.json new file mode 100644 index 000000000000..264cd37be95e --- /dev/null +++ b/test/cmdlineTests/standard_output_selection_empty/output.json @@ -0,0 +1,7 @@ +{ + "sources": { + "C": { + "id": 0 + } + } +} diff --git a/test/cmdlineTests/standard_output_selection_multiple_matching_source_and_contract_selectors/input.json b/test/cmdlineTests/standard_output_selection_multiple_matching_source_and_contract_selectors/input.json new file mode 100644 index 000000000000..276869377cde --- /dev/null +++ b/test/cmdlineTests/standard_output_selection_multiple_matching_source_and_contract_selectors/input.json @@ -0,0 +1,29 @@ +{ + "language": "Solidity", + "sources": { + "": {"content": "contract A {}\ncontract B {}\n//SPDX-License-Identifier: GPL-3.0\npragma solidity *;"}, + "*": {"content": "contract A {}\ncontract B {}\n//SPDX-License-Identifier: GPL-3.0\npragma solidity *;"}, + "C": {"content": "contract A {}\ncontract B {}\n//SPDX-License-Identifier: GPL-3.0\npragma solidity *;"}, + "D": {"content": "contract A {}\ncontract B {}\n//SPDX-License-Identifier: GPL-3.0\npragma solidity *;"} + }, + "settings": { + "outputSelection": { + // FIXME: Behavior of "" is inconsistent. Sometimes it matches everything, sometimes only empty name. + "": { + "": ["metadata"], // No matches + "*": ["transientStorageLayout"], // All sources, all contracts + "A": ["abi"] // source "", contract A + }, + "*": { + "": ["evm.deployedBytecode.immutableReferences"], // No matches + "*": ["evm.bytecode.object"], // All sources, all contracts + "A": ["evm.bytecode.linkReferences"] // All sources, contract A + }, + "C": { + "": ["userdoc"], // No matches + "*": ["devdoc"], // All contracts in source "C" + "A": ["storageLayout"] // source "C", contract A + } + } + } +} diff --git a/test/cmdlineTests/standard_output_selection_multiple_matching_source_and_contract_selectors/output.json b/test/cmdlineTests/standard_output_selection_multiple_matching_source_and_contract_selectors/output.json new file mode 100644 index 000000000000..6558a5759603 --- /dev/null +++ b/test/cmdlineTests/standard_output_selection_multiple_matching_source_and_contract_selectors/output.json @@ -0,0 +1,109 @@ +{ + "contracts": { + "": { + "A": { + "abi": [], + "evm": { + "bytecode": { + "linkReferences": {}, + "object": "" + } + }, + "transientStorageLayout": { + "storage": [], + "types": null + } + }, + "B": { + "evm": { + "bytecode": { + "object": "" + } + }, + "transientStorageLayout": { + "storage": [], + "types": null + } + } + }, + "*": { + "A": { + "evm": { + "bytecode": { + "linkReferences": {}, + "object": "" + } + } + }, + "B": { + "evm": { + "bytecode": { + "object": "" + } + } + } + }, + "C": { + "A": { + "devdoc": { + "kind": "dev", + "methods": {}, + "version": 1 + }, + "evm": { + "bytecode": { + "linkReferences": {}, + "object": "" + } + }, + "storageLayout": { + "storage": [], + "types": null + } + }, + "B": { + "devdoc": { + "kind": "dev", + "methods": {}, + "version": 1 + }, + "evm": { + "bytecode": { + "object": "" + } + } + } + }, + "D": { + "A": { + "evm": { + "bytecode": { + "linkReferences": {}, + "object": "" + } + } + }, + "B": { + "evm": { + "bytecode": { + "object": "" + } + } + } + } + }, + "sources": { + "": { + "id": 0 + }, + "*": { + "id": 1 + }, + "C": { + "id": 2 + }, + "D": { + "id": 3 + } + } +} diff --git a/test/cmdlineTests/standard_output_selection_multiple_matching_source_and_contract_selectors_full_pipeline/input.json b/test/cmdlineTests/standard_output_selection_multiple_matching_source_and_contract_selectors_full_pipeline/input.json new file mode 100644 index 000000000000..22884c9f82bb --- /dev/null +++ b/test/cmdlineTests/standard_output_selection_multiple_matching_source_and_contract_selectors_full_pipeline/input.json @@ -0,0 +1,23 @@ +{ + "language": "Solidity", + "sources": { + "C": {"content": "contract A {}\ncontract B {}\n//SPDX-License-Identifier: GPL-3.0\npragma solidity *;"}, + "D": {"content": "contract A {}\ncontract B {}\n//SPDX-License-Identifier: GPL-3.0\npragma solidity *;"} + }, + "settings": { + "optimizer": {"enabled": true}, + "debug": {"debugInfo": []}, + "outputSelection": { + // This test uses outputs that require all stages of the pipeline to run, possibly via + // multiple paths, to make sure the later stages handle more complex output selection correctly. + // Currently there are only distinct paths (IR, optimized IR and bytecode generation). + "*": { + "*": ["evm.bytecode.object"], + "A": ["irOptimized"] + }, + "C": { + "A": ["ir"] + } + } + } +} diff --git a/test/cmdlineTests/standard_output_selection_multiple_matching_source_and_contract_selectors_full_pipeline/output.json b/test/cmdlineTests/standard_output_selection_multiple_matching_source_and_contract_selectors_full_pipeline/output.json new file mode 100644 index 000000000000..3ff2b451e23d --- /dev/null +++ b/test/cmdlineTests/standard_output_selection_multiple_matching_source_and_contract_selectors_full_pipeline/output.json @@ -0,0 +1,141 @@ +{ + "contracts": { + "C": { + "A": { + "evm": { + "bytecode": { + "object": "" + } + }, + "ir": " +/// @use-src 0:\"C\" +object \"A_1\" { + code { + + mstore(64, memoryguard(128)) + if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } + + constructor_A_1() + + let _1 := allocate_unbounded() + codecopy(_1, dataoffset(\"A_1_deployed\"), datasize(\"A_1_deployed\")) + + return(_1, datasize(\"A_1_deployed\")) + + function allocate_unbounded() -> memPtr { + memPtr := mload(64) + } + + function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() { + revert(0, 0) + } + + function constructor_A_1() { + + } + + } + /// @use-src 0:\"C\" + object \"A_1_deployed\" { + code { + + mstore(64, memoryguard(128)) + + revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() + + function shift_right_224_unsigned(value) -> newValue { + newValue := + + shr(224, value) + + } + + function allocate_unbounded() -> memPtr { + memPtr := mload(64) + } + + function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() { + revert(0, 0) + } + + } + + data \".metadata\" hex\"\" + } + +} + +", + "irOptimized": "/// @use-src 0:\"C\" +object \"A_1\" { + code { + { + let _1 := memoryguard(0x80) + mstore(64, _1) + if callvalue() { revert(0, 0) } + let _2 := datasize(\"A_1_deployed\") + codecopy(_1, dataoffset(\"A_1_deployed\"), _2) + return(_1, _2) + } + } + /// @use-src 0:\"C\" + object \"A_1_deployed\" { + code { { revert(0, 0) } } + data \".metadata\" hex\"\" + } +} +" + }, + "B": { + "evm": { + "bytecode": { + "object": "" + } + } + } + }, + "D": { + "A": { + "evm": { + "bytecode": { + "object": "" + } + }, + "irOptimized": "/// @use-src 1:\"D\" +object \"A_5\" { + code { + { + let _1 := memoryguard(0x80) + mstore(64, _1) + if callvalue() { revert(0, 0) } + let _2 := datasize(\"A_5_deployed\") + codecopy(_1, dataoffset(\"A_5_deployed\"), _2) + return(_1, _2) + } + } + /// @use-src 1:\"D\" + object \"A_5_deployed\" { + code { { revert(0, 0) } } + data \".metadata\" hex\"\" + } +} +" + }, + "B": { + "evm": { + "bytecode": { + "object": "" + } + } + } + } + }, + "sources": { + "C": { + "id": 0 + }, + "D": { + "id": 1 + } + } +} diff --git a/test/cmdlineTests/standard_output_selection_no_output_selected/input.json b/test/cmdlineTests/standard_output_selection_no_output_selected/input.json new file mode 100644 index 000000000000..4e0fd1c0d04a --- /dev/null +++ b/test/cmdlineTests/standard_output_selection_no_output_selected/input.json @@ -0,0 +1,16 @@ +{ + "language": "Solidity", + "sources": { + "C": {"content": "contract A {}\ncontract B {}\n//SPDX-License-Identifier: GPL-3.0\npragma solidity *;"}, + "D": {"content": "contract A {}\ncontract B {}\n//SPDX-License-Identifier: GPL-3.0\npragma solidity *;"}, + "E": {"content": "contract A {}\ncontract B {}\n//SPDX-License-Identifier: GPL-3.0\npragma solidity *;"} + }, + "settings": { + "outputSelection": { + "C": {}, + "D": {"A": []}, + "*": {"B": []}, + "": {} + } + } +} diff --git a/test/cmdlineTests/standard_output_selection_no_output_selected/output.json b/test/cmdlineTests/standard_output_selection_no_output_selected/output.json new file mode 100644 index 000000000000..2cea05dcffcc --- /dev/null +++ b/test/cmdlineTests/standard_output_selection_no_output_selected/output.json @@ -0,0 +1,13 @@ +{ + "sources": { + "C": { + "id": 0 + }, + "D": { + "id": 1 + }, + "E": { + "id": 2 + } + } +} diff --git a/test/cmdlineTests/standard_output_selection_unrecognized_output/input.json b/test/cmdlineTests/standard_output_selection_unrecognized_output/input.json new file mode 100644 index 000000000000..072d9916e2e9 --- /dev/null +++ b/test/cmdlineTests/standard_output_selection_unrecognized_output/input.json @@ -0,0 +1,24 @@ +{ + "language": "Solidity", + "sources": { + "C": {"content": "contract A {}\ncontract B {}\n//SPDX-License-Identifier: GPL-3.0\npragma solidity *;"} + }, + "settings": { + "outputSelection": { + // Unrecognized outputs are ignored. + "C": { + "A": [ + "X", + "METADATA", + "abi.encode", + "userdoc", // The only valid one here. + ".", + "evm.", + "evm.bytecodeObject", + "evm.bytecode.object.ir", + "evm.bytecode.*" + ] + } + } + } +} diff --git a/test/cmdlineTests/standard_output_selection_unrecognized_output/output.json b/test/cmdlineTests/standard_output_selection_unrecognized_output/output.json new file mode 100644 index 000000000000..7fbddd857172 --- /dev/null +++ b/test/cmdlineTests/standard_output_selection_unrecognized_output/output.json @@ -0,0 +1,18 @@ +{ + "contracts": { + "C": { + "A": { + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + } + } + } + }, + "sources": { + "C": { + "id": 0 + } + } +} diff --git a/test/cmdlineTests/standard_output_selection_unrecognized_source_and_contract_selectors/input.json b/test/cmdlineTests/standard_output_selection_unrecognized_source_and_contract_selectors/input.json new file mode 100644 index 000000000000..b1b4e1bef804 --- /dev/null +++ b/test/cmdlineTests/standard_output_selection_unrecognized_source_and_contract_selectors/input.json @@ -0,0 +1,21 @@ +{ + "language": "Solidity", + "sources": { + "*": {"content": "contract A {}\n//SPDX-License-Identifier: GPL-3.0\npragma solidity *;"}, + "C": {"content": "contract A {}\n//SPDX-License-Identifier: GPL-3.0\npragma solidity *;"} + }, + "settings": { + "outputSelection": { + "*": { + "X": ["userdoc"] // No contract X, but no error, just ignored. + }, + "Y": { + "*": ["devdoc"], // No source "Y", but no error, just ignored. + "Z": ["abi"] // No source "Y", but no error, just ignored. + }, + "C": { + "A": ["evm.bytecode.object"] + } + } + } +} diff --git a/test/cmdlineTests/standard_output_selection_unrecognized_source_and_contract_selectors/output.json b/test/cmdlineTests/standard_output_selection_unrecognized_source_and_contract_selectors/output.json new file mode 100644 index 000000000000..20ab65450f8c --- /dev/null +++ b/test/cmdlineTests/standard_output_selection_unrecognized_source_and_contract_selectors/output.json @@ -0,0 +1,21 @@ +{ + "contracts": { + "C": { + "A": { + "evm": { + "bytecode": { + "object": "" + } + } + } + } + }, + "sources": { + "*": { + "id": 0 + }, + "C": { + "id": 1 + } + } +} From 9b4a07bbb46cd4cba23f7dbf406a38dc199a6177 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Mon, 23 Sep 2024 17:51:49 +0200 Subject: [PATCH 0436/1022] SSACFG: Fix canContinue in user-defined function calls --- .../evm/SSAControlFlowGraphBuilder.cpp | 55 ++++++++++++++----- .../backends/evm/SSAControlFlowGraphBuilder.h | 15 +++-- .../yulSSAControlFlowGraph/function.yul | 4 +- 3 files changed, 54 insertions(+), 20 deletions(-) diff --git a/libyul/backends/evm/SSAControlFlowGraphBuilder.cpp b/libyul/backends/evm/SSAControlFlowGraphBuilder.cpp index 26635124edfc..dc183a085a16 100644 --- a/libyul/backends/evm/SSAControlFlowGraphBuilder.cpp +++ b/libyul/backends/evm/SSAControlFlowGraphBuilder.cpp @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -46,10 +47,12 @@ namespace solidity::yul SSAControlFlowGraphBuilder::SSAControlFlowGraphBuilder( SSACFG& _graph, AsmAnalysisInfo const& _analysisInfo, + ControlFlowSideEffectsCollector const& _sideEffects, Dialect const& _dialect ): m_graph(_graph), m_info(_analysisInfo), + m_sideEffects(_sideEffects), m_dialect(_dialect) { } @@ -63,7 +66,7 @@ std::unique_ptr SSAControlFlowGraphBuilder::build( ControlFlowSideEffectsCollector sideEffects(_dialect, _block); auto result = std::make_unique(); - auto functions = buildMainGraph(*result->mainGraph, _analysisInfo, _dialect, _block); + auto functions = buildMainGraph(*result->mainGraph, _analysisInfo, sideEffects, _dialect, _block); buildFunctionGraphs(*result, _analysisInfo, sideEffects, _dialect, functions); return result; } @@ -267,8 +270,9 @@ void SSAControlFlowGraphBuilder::buildFunctionGraphs( cfg.arguments = arguments; cfg.returns = returns; - SSAControlFlowGraphBuilder builder(cfg, _info, _dialect); + SSAControlFlowGraphBuilder builder(cfg, _info, _sideEffects, _dialect); builder.m_currentBlock = cfg.entry; + builder.m_functionDefinitions = _functions; for (auto&& [var, varId]: cfg.arguments) builder.currentDef(var, cfg.entry) = varId; for (auto const& var: cfg.returns) @@ -285,11 +289,12 @@ void SSAControlFlowGraphBuilder::buildFunctionGraphs( std::vector> SSAControlFlowGraphBuilder::buildMainGraph( SSACFG& _cfg, AsmAnalysisInfo const& _analysisInfo, + ControlFlowSideEffectsCollector const& _sideEffects, Dialect const& _dialect, Block const& _block ) { - SSAControlFlowGraphBuilder builder(_cfg, _analysisInfo, _dialect); + SSAControlFlowGraphBuilder builder(_cfg, _analysisInfo, _sideEffects, _dialect); builder.m_currentBlock = _cfg.makeBlock(debugDataOf(_block)); builder.sealBlock(builder.m_currentBlock); builder(_block); @@ -535,8 +540,22 @@ void SSAControlFlowGraphBuilder::operator()(Leave const& _leaveStatement) void SSAControlFlowGraphBuilder::operator()(Block const& _block) { ScopedSaveAndRestore saveScope(m_scope, m_info.scopes.at(&_block).get()); - for (auto const& statement: _block.statements) - std::visit(*this, statement); + if (m_currentBlock == m_graph.entry) + { + auto const filterFunctionDefinitions = [](bool _yieldDefinitionsOnly) + { + return [b=_yieldDefinitionsOnly](Statement const& _statement) -> bool { return !b ^ std::holds_alternative(_statement);}; + }; + for (auto const& statement: _block.statements | ranges::views::filter(filterFunctionDefinitions(true))) + std::visit(*this, statement); + for (auto const& statement: _block.statements | ranges::views::filter(filterFunctionDefinitions(false))) + std::visit(*this, statement); + } + else + { + for (auto const& statement: _block.statements) + std::visit(*this, statement); + } } SSACFG::ValueId SSAControlFlowGraphBuilder::operator()(FunctionCall const& _call) @@ -592,7 +611,9 @@ std::vector SSAControlFlowGraphBuilder::visitFunctionCall(Funct else { Scope::Function const& function = lookupFunction(_call.functionName.name); - canContinue = m_graph.canContinue; + auto const* definition = findFunctionDefinition(&function); + yulAssert(definition); + canContinue = m_sideEffects.functionSideEffects().at(definition).canContinue; SSACFG::Operation result{{}, SSACFG::Call{debugDataOf(_call), function, _call, canContinue}, {}}; for (auto const& arg: _call.arguments | ranges::views::reverse) result.inputs.emplace_back(std::visit(*this, arg)); @@ -745,8 +766,7 @@ void SSAControlFlowGraphBuilder::tableJump( langutil::DebugData::ConstPtr _debugData, SSACFG::ValueId _value, std::map _cases, - SSACFG::BlockId _defaultCase -) + SSACFG::BlockId _defaultCase) { for (auto caseBlock: _cases | ranges::views::values) { @@ -755,13 +775,20 @@ void SSAControlFlowGraphBuilder::tableJump( } yulAssert(!blockInfo(_defaultCase).sealed); m_graph.block(_defaultCase).entries.insert(m_currentBlock); - currentBlock().exit = SSACFG::BasicBlock::JumpTable{ - std::move(_debugData), - _value, - std::move(_cases), - _defaultCase - }; + currentBlock().exit = SSACFG::BasicBlock::JumpTable{std::move(_debugData), _value, std::move(_cases), _defaultCase}; m_currentBlock = {}; } +FunctionDefinition const* SSAControlFlowGraphBuilder::findFunctionDefinition(Scope::Function const* _function) const +{ + auto it = std::find_if( + m_functionDefinitions.begin(), + m_functionDefinitions.end(), + [&_function](auto const& _entry) { return std::get<0>(_entry) == _function; } + ); + if (it != m_functionDefinitions.end()) + return std::get<1>(*it); + return nullptr; +} + } diff --git a/libyul/backends/evm/SSAControlFlowGraphBuilder.h b/libyul/backends/evm/SSAControlFlowGraphBuilder.h index e4d0d6db6175..8fc537c14eb5 100644 --- a/libyul/backends/evm/SSAControlFlowGraphBuilder.h +++ b/libyul/backends/evm/SSAControlFlowGraphBuilder.h @@ -29,9 +29,8 @@ */ #pragma once -#include -#include #include +#include #include #include @@ -43,12 +42,17 @@ class SSAControlFlowGraphBuilder SSAControlFlowGraphBuilder( SSACFG& _graph, AsmAnalysisInfo const& _analysisInfo, + ControlFlowSideEffectsCollector const& _sideEffects, Dialect const& _dialect ); public: SSAControlFlowGraphBuilder(SSAControlFlowGraphBuilder const&) = delete; SSAControlFlowGraphBuilder& operator=(SSAControlFlowGraphBuilder const&) = delete; - static std::unique_ptr build(AsmAnalysisInfo const& _analysisInfo, Dialect const& _dialect, Block const& _block); + static std::unique_ptr build( + AsmAnalysisInfo const& _analysisInfo, + Dialect const& _dialect, + Block const& _block + ); static void buildFunctionGraphs( ControlFlow& _controlFlow, AsmAnalysisInfo const& _info, @@ -59,6 +63,7 @@ class SSAControlFlowGraphBuilder static std::vector> buildMainGraph( SSACFG& _cfg, AsmAnalysisInfo const& _analysisInfo, + ControlFlowSideEffectsCollector const& _sideEffects, Dialect const& _dialect, Block const& _block ); @@ -95,7 +100,9 @@ class SSAControlFlowGraphBuilder SSACFG& m_graph; AsmAnalysisInfo const& m_info; + ControlFlowSideEffectsCollector const& m_sideEffects; Dialect const& m_dialect; + std::vector> m_functionDefinitions; SSACFG::BlockId m_currentBlock; SSACFG::BasicBlock& currentBlock() { return m_graph.block(m_currentBlock); } Scope* m_scope = nullptr; @@ -154,7 +161,7 @@ class SSAControlFlowGraphBuilder SSACFG::BlockId _defaultCase ); - std::vector> m_functionDefinitions; + FunctionDefinition const* findFunctionDefinition(Scope::Function const* _function) const; }; } diff --git a/test/libyul/yulSSAControlFlowGraph/function.yul b/test/libyul/yulSSAControlFlowGraph/function.yul index 436bcd49956e..20a536b5e556 100644 --- a/test/libyul/yulSSAControlFlowGraph/function.yul +++ b/test/libyul/yulSSAControlFlowGraph/function.yul @@ -29,9 +29,8 @@ // Block0_0 [label="\ // Block 0\nv0, v1 := i()\l\ // h(v0)\l\ -// h(v1)\l\ // "]; -// Block0_0Exit [label="MainExit"]; +// Block0_0Exit [label="Terminated"]; // Block0_0 -> Block0_0Exit; // FunctionEntry_f_0 [label="function f: // r := f(v0, v1)"]; @@ -55,6 +54,7 @@ // FunctionEntry_h_0 -> Block3_0; // Block3_0 [label="\ // Block 0\nv2 := f(0, v0)\l\ +// h(v2)\l\ // "]; // Block3_0Exit [label="Terminated"]; // Block3_0 -> Block3_0Exit; From 4461699a33f7a78df8c28313cd6e76bb9655279c Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Tue, 24 Sep 2024 15:35:34 +0200 Subject: [PATCH 0437/1022] SSACFG: Handle nested function definitions --- .../evm/SSAControlFlowGraphBuilder.cpp | 160 ++++++++---------- .../backends/evm/SSAControlFlowGraphBuilder.h | 18 +- .../nested_function.yul | 142 ++++++++++++++++ 3 files changed, 217 insertions(+), 103 deletions(-) create mode 100644 test/libyul/yulSSAControlFlowGraph/nested_function.yul diff --git a/libyul/backends/evm/SSAControlFlowGraphBuilder.cpp b/libyul/backends/evm/SSAControlFlowGraphBuilder.cpp index dc183a085a16..ceaa8acbd7b4 100644 --- a/libyul/backends/evm/SSAControlFlowGraphBuilder.cpp +++ b/libyul/backends/evm/SSAControlFlowGraphBuilder.cpp @@ -45,11 +45,13 @@ namespace solidity::yul { SSAControlFlowGraphBuilder::SSAControlFlowGraphBuilder( + ControlFlow& _controlFlow, SSACFG& _graph, AsmAnalysisInfo const& _analysisInfo, ControlFlowSideEffectsCollector const& _sideEffects, Dialect const& _dialect ): + m_controlFlow(_controlFlow), m_graph(_graph), m_info(_analysisInfo), m_sideEffects(_sideEffects), @@ -65,10 +67,16 @@ std::unique_ptr SSAControlFlowGraphBuilder::build( { ControlFlowSideEffectsCollector sideEffects(_dialect, _block); - auto result = std::make_unique(); - auto functions = buildMainGraph(*result->mainGraph, _analysisInfo, sideEffects, _dialect, _block); - buildFunctionGraphs(*result, _analysisInfo, sideEffects, _dialect, functions); - return result; + auto controlFlow = std::make_unique(); + SSAControlFlowGraphBuilder builder(*controlFlow, *controlFlow->mainGraph, _analysisInfo, sideEffects, _dialect); + builder.m_currentBlock = controlFlow->mainGraph->makeBlock(debugDataOf(_block)); + builder.sealBlock(builder.m_currentBlock); + builder(_block); + if (!builder.blockInfo(builder.m_currentBlock).sealed) + builder.sealBlock(builder.m_currentBlock); + controlFlow->mainGraph->block(builder.m_currentBlock).exit = SSACFG::BasicBlock::MainExit{}; + builder.cleanUnreachable(); + return controlFlow; } SSACFG::ValueId SSAControlFlowGraphBuilder::tryRemoveTrivialPhi(SSACFG::ValueId _phi) @@ -236,73 +244,48 @@ void SSAControlFlowGraphBuilder::cleanUnreachable() } } -void SSAControlFlowGraphBuilder::buildFunctionGraphs( - ControlFlow& _controlFlow, - AsmAnalysisInfo const& _info, - ControlFlowSideEffectsCollector const& _sideEffects, - Dialect const& _dialect, - std::vector> const& _functions -) -{ - for (auto const& [function, functionDefinition]: _functions) - { - _controlFlow.functionGraphs.emplace_back(std::make_unique()); - auto& cfg = *_controlFlow.functionGraphs.back(); - _controlFlow.functionGraphMapping.emplace_back(function, &cfg); - - yulAssert(_info.scopes.at(&functionDefinition->body), ""); - Scope* virtualFunctionScope = _info.scopes.at(_info.virtualBlocks.at(functionDefinition).get()).get(); - yulAssert(virtualFunctionScope, ""); - - cfg.entry = cfg.makeBlock(debugDataOf(functionDefinition->body)); - auto arguments = functionDefinition->parameters | ranges::views::transform([&](auto const& _param) { - auto const& var = std::get(virtualFunctionScope->identifiers.at(_param.name)); - // Note: cannot use std::make_tuple since it unwraps reference wrappers. - return std::tuple{std::cref(var), cfg.newVariable(cfg.entry)}; - }) | ranges::to; - auto returns = functionDefinition->returnVariables | ranges::views::transform([&](auto const& _param) { - return std::cref(std::get(virtualFunctionScope->identifiers.at(_param.name))); - }) | ranges::to; - - cfg.debugData = functionDefinition->debugData; - cfg.function = function; - cfg.canContinue = _sideEffects.functionSideEffects().at(functionDefinition).canContinue; - cfg.arguments = arguments; - cfg.returns = returns; - - SSAControlFlowGraphBuilder builder(cfg, _info, _sideEffects, _dialect); - builder.m_currentBlock = cfg.entry; - builder.m_functionDefinitions = _functions; - for (auto&& [var, varId]: cfg.arguments) - builder.currentDef(var, cfg.entry) = varId; - for (auto const& var: cfg.returns) - builder.currentDef(var.get(), cfg.entry) = builder.zero(); - builder.sealBlock(cfg.entry); - builder(functionDefinition->body); - cfg.exits.insert(builder.m_currentBlock); - // Artificial explicit function exit (`leave`) at the end of the body. - builder(Leave{debugDataOf(*functionDefinition)}); - builder.cleanUnreachable(); - } -} - -std::vector> SSAControlFlowGraphBuilder::buildMainGraph( - SSACFG& _cfg, - AsmAnalysisInfo const& _analysisInfo, - ControlFlowSideEffectsCollector const& _sideEffects, - Dialect const& _dialect, - Block const& _block +void SSAControlFlowGraphBuilder::buildFunctionGraph( + Scope::Function const* _function, + FunctionDefinition const* _functionDefinition ) { - SSAControlFlowGraphBuilder builder(_cfg, _analysisInfo, _sideEffects, _dialect); - builder.m_currentBlock = _cfg.makeBlock(debugDataOf(_block)); - builder.sealBlock(builder.m_currentBlock); - builder(_block); - if (!builder.blockInfo(builder.m_currentBlock).sealed) - builder.sealBlock(builder.m_currentBlock); - _cfg.block(builder.m_currentBlock).exit = SSACFG::BasicBlock::MainExit{}; + m_controlFlow.functionGraphs.emplace_back(std::make_unique()); + auto& cfg = *m_controlFlow.functionGraphs.back(); + m_controlFlow.functionGraphMapping.emplace_back(_function, &cfg); + + yulAssert(m_info.scopes.at(&_functionDefinition->body), ""); + Scope* virtualFunctionScope = m_info.scopes.at(m_info.virtualBlocks.at(_functionDefinition).get()).get(); + yulAssert(virtualFunctionScope, ""); + + cfg.entry = cfg.makeBlock(debugDataOf(_functionDefinition->body)); + auto arguments = _functionDefinition->parameters | ranges::views::transform([&](auto const& _param) { + auto const& var = std::get(virtualFunctionScope->identifiers.at(_param.name)); + // Note: cannot use std::make_tuple since it unwraps reference wrappers. + return std::tuple{std::cref(var), cfg.newVariable(cfg.entry)}; + }) | ranges::to; + auto returns = _functionDefinition->returnVariables | ranges::views::transform([&](auto const& _param) { + return std::cref(std::get(virtualFunctionScope->identifiers.at(_param.name))); + }) | ranges::to; + + cfg.debugData = _functionDefinition->debugData; + cfg.function = _function; + cfg.canContinue = m_sideEffects.functionSideEffects().at(_functionDefinition).canContinue; + cfg.arguments = arguments; + cfg.returns = returns; + + SSAControlFlowGraphBuilder builder(m_controlFlow, cfg, m_info, m_sideEffects, m_dialect); + builder.m_currentBlock = cfg.entry; + builder.m_functionDefinitions = m_functionDefinitions; + for (auto&& [var, varId]: cfg.arguments) + builder.currentDef(var, cfg.entry) = varId; + for (auto const& var: cfg.returns) + builder.currentDef(var.get(), cfg.entry) = builder.zero(); + builder.sealBlock(cfg.entry); + builder(_functionDefinition->body); + cfg.exits.insert(builder.m_currentBlock); + // Artificial explicit function exit (`leave`) at the end of the body. + builder(Leave{debugDataOf(*_functionDefinition)}); builder.cleanUnreachable(); - return builder.m_functionDefinitions; } void SSAControlFlowGraphBuilder::operator()(ExpressionStatement const& _expressionStatement) @@ -331,11 +314,8 @@ void SSAControlFlowGraphBuilder::operator()(VariableDeclaration const& _variable void SSAControlFlowGraphBuilder::operator()(FunctionDefinition const& _functionDefinition) { - yulAssert(m_scope, ""); - yulAssert(m_scope->identifiers.count(_functionDefinition.name), ""); - auto& function = std::get(m_scope->identifiers.at(_functionDefinition.name)); - m_graph.functions.emplace_back(function); - m_functionDefinitions.emplace_back(&function, &_functionDefinition); + Scope::Function const& function = lookupFunction(_functionDefinition.name); + buildFunctionGraph(&function, &_functionDefinition); } void SSAControlFlowGraphBuilder::operator()(If const& _if) @@ -537,25 +517,27 @@ void SSAControlFlowGraphBuilder::operator()(Leave const& _leaveStatement) sealBlock(m_currentBlock); } +void SSAControlFlowGraphBuilder::registerFunctionDefinition(FunctionDefinition const& _functionDefinition) +{ + yulAssert(m_scope, ""); + yulAssert(m_scope->identifiers.count(_functionDefinition.name), ""); + auto& function = std::get(m_scope->identifiers.at(_functionDefinition.name)); + m_graph.functions.emplace_back(function); + m_functionDefinitions.emplace_back(&function, &_functionDefinition); +} + void SSAControlFlowGraphBuilder::operator()(Block const& _block) { ScopedSaveAndRestore saveScope(m_scope, m_info.scopes.at(&_block).get()); - if (m_currentBlock == m_graph.entry) - { - auto const filterFunctionDefinitions = [](bool _yieldDefinitionsOnly) - { - return [b=_yieldDefinitionsOnly](Statement const& _statement) -> bool { return !b ^ std::holds_alternative(_statement);}; - }; - for (auto const& statement: _block.statements | ranges::views::filter(filterFunctionDefinitions(true))) - std::visit(*this, statement); - for (auto const& statement: _block.statements | ranges::views::filter(filterFunctionDefinitions(false))) - std::visit(*this, statement); - } - else - { - for (auto const& statement: _block.statements) - std::visit(*this, statement); - } + // gather all function definitions so that they are visible to each other's subgraphs + static constexpr auto functionDefinitionFilter = ranges::views::filter( + [](auto const& _statement) { return std::holds_alternative(_statement); } + ); + for (auto const& statement: _block.statements | functionDefinitionFilter) + registerFunctionDefinition(std::get(statement)); + // now visit the rest + for (auto const& statement: _block.statements) + std::visit(*this, statement); } SSACFG::ValueId SSAControlFlowGraphBuilder::operator()(FunctionCall const& _call) diff --git a/libyul/backends/evm/SSAControlFlowGraphBuilder.h b/libyul/backends/evm/SSAControlFlowGraphBuilder.h index 8fc537c14eb5..a3a723f67c42 100644 --- a/libyul/backends/evm/SSAControlFlowGraphBuilder.h +++ b/libyul/backends/evm/SSAControlFlowGraphBuilder.h @@ -40,6 +40,7 @@ namespace solidity::yul class SSAControlFlowGraphBuilder { SSAControlFlowGraphBuilder( + ControlFlow& _controlFlow, SSACFG& _graph, AsmAnalysisInfo const& _analysisInfo, ControlFlowSideEffectsCollector const& _sideEffects, @@ -53,20 +54,6 @@ class SSAControlFlowGraphBuilder Dialect const& _dialect, Block const& _block ); - static void buildFunctionGraphs( - ControlFlow& _controlFlow, - AsmAnalysisInfo const& _info, - ControlFlowSideEffectsCollector const& _sideEffects, - Dialect const& _dialect, - std::vector> const& _functions - ); - static std::vector> buildMainGraph( - SSACFG& _cfg, - AsmAnalysisInfo const& _analysisInfo, - ControlFlowSideEffectsCollector const& _sideEffects, - Dialect const& _dialect, - Block const& _block - ); void operator()(ExpressionStatement const& _statement); void operator()(Assignment const& _assignment); @@ -91,6 +78,8 @@ class SSAControlFlowGraphBuilder SSACFG::ValueId tryRemoveTrivialPhi(SSACFG::ValueId _phi); void assign(std::vector> _variables, Expression const* _expression); std::vector visitFunctionCall(FunctionCall const& _call); + void registerFunctionDefinition(FunctionDefinition const& _functionDefinition); + void buildFunctionGraph(Scope::Function const* _function, FunctionDefinition const* _functionDefinition); SSACFG::ValueId zero(); SSACFG::ValueId readVariable(Scope::Variable const& _variable, SSACFG::BlockId _block); @@ -98,6 +87,7 @@ class SSAControlFlowGraphBuilder SSACFG::ValueId addPhiOperands(Scope::Variable const& _variable, SSACFG::ValueId _phi); void writeVariable(Scope::Variable const& _variable, SSACFG::BlockId _block, SSACFG::ValueId _value); + ControlFlow& m_controlFlow; SSACFG& m_graph; AsmAnalysisInfo const& m_info; ControlFlowSideEffectsCollector const& m_sideEffects; diff --git a/test/libyul/yulSSAControlFlowGraph/nested_function.yul b/test/libyul/yulSSAControlFlowGraph/nested_function.yul new file mode 100644 index 000000000000..859b24151592 --- /dev/null +++ b/test/libyul/yulSSAControlFlowGraph/nested_function.yul @@ -0,0 +1,142 @@ +{ + function f(a, b) -> r { + let x := add(a,b) + r := sub(x,a) + } + function g() { + function z() -> r { + function w() -> rw1 { + rw1 := 0x01 + } + r := w() + } + function v() -> r { + function w() -> rw2 { + rw2 := 0x11 + } + r := w() + } + sstore(z(), f(v(),2)) + } + function cycle1() -> r { + if mload(3) { + r := cycle2() + } + } + function cycle2() -> r { + if mload(4) { + r := cycle1() + } + } +} +// ---- +// digraph SSACFG { +// nodesep=0.7; +// graph[fontname="DejaVu Sans"] +// node[shape=box,fontname="DejaVu Sans"]; +// +// Entry0 [label="Entry"]; +// Entry0 -> Block0_0; +// Block0_0 [label="\ +// Block 0\n"]; +// Block0_0Exit [label="MainExit"]; +// Block0_0 -> Block0_0Exit; +// FunctionEntry_f_0 [label="function f: +// r := f(v0, v1)"]; +// FunctionEntry_f_0 -> Block1_0; +// Block1_0 [label="\ +// Block 0\nv3 := add(v1, v0)\l\ +// v4 := sub(v0, v3)\l\ +// "]; +// Block1_0Exit [label="FunctionReturn[v4]"]; +// Block1_0 -> Block1_0Exit; +// FunctionEntry_g_0 [label="function g: +// g()"]; +// FunctionEntry_g_0 -> Block2_0; +// Block2_0 [label="\ +// Block 0\nv1 := v()\l\ +// v2 := f(2, v1)\l\ +// v3 := z()\l\ +// sstore(v2, v3)\l\ +// "]; +// Block2_0Exit [label="FunctionReturn[]"]; +// Block2_0 -> Block2_0Exit; +// FunctionEntry_z_0 [label="function z: +// r := z()"]; +// FunctionEntry_z_0 -> Block3_0; +// Block3_0 [label="\ +// Block 0\nv1 := w()\l\ +// "]; +// Block3_0Exit [label="FunctionReturn[v1]"]; +// Block3_0 -> Block3_0Exit; +// FunctionEntry_w_0 [label="function w: +// rw1 := w()"]; +// FunctionEntry_w_0 -> Block4_0; +// Block4_0 [label="\ +// Block 0\n"]; +// Block4_0Exit [label="FunctionReturn[1]"]; +// Block4_0 -> Block4_0Exit; +// FunctionEntry_v_0 [label="function v: +// r := v()"]; +// FunctionEntry_v_0 -> Block5_0; +// Block5_0 [label="\ +// Block 0\nv1 := w()\l\ +// "]; +// Block5_0Exit [label="FunctionReturn[v1]"]; +// Block5_0 -> Block5_0Exit; +// FunctionEntry_w_0 [label="function w: +// rw2 := w()"]; +// FunctionEntry_w_0 -> Block6_0; +// Block6_0 [label="\ +// Block 0\n"]; +// Block6_0Exit [label="FunctionReturn[17]"]; +// Block6_0 -> Block6_0Exit; +// FunctionEntry_cycle1_0 [label="function cycle1: +// r := cycle1()"]; +// FunctionEntry_cycle1_0 -> Block7_0; +// Block7_0 [label="\ +// Block 0\nv2 := mload(3)\l\ +// "]; +// Block7_0 -> Block7_0Exit; +// Block7_0Exit [label="{ If v2| { <0> Zero | <1> NonZero }}" shape=Mrecord]; +// Block7_0Exit:0 -> Block7_2; +// Block7_0Exit:1 -> Block7_1; +// Block7_1 [label="\ +// Block 1\nv3 := cycle2()\l\ +// "]; +// Block7_1 -> Block7_1Exit [arrowhead=none]; +// Block7_1Exit [label="Jump" shape=oval]; +// Block7_1Exit -> Block7_2; +// Block7_2 [label="\ +// Block 2\nv4 := φ(\l\ +// Block 0 => 0,\l\ +// Block 1 => v3\l\ +// )\l\ +// "]; +// Block7_2Exit [label="FunctionReturn[v4]"]; +// Block7_2 -> Block7_2Exit; +// FunctionEntry_cycle2_0 [label="function cycle2: +// r := cycle2()"]; +// FunctionEntry_cycle2_0 -> Block8_0; +// Block8_0 [label="\ +// Block 0\nv2 := mload(4)\l\ +// "]; +// Block8_0 -> Block8_0Exit; +// Block8_0Exit [label="{ If v2| { <0> Zero | <1> NonZero }}" shape=Mrecord]; +// Block8_0Exit:0 -> Block8_2; +// Block8_0Exit:1 -> Block8_1; +// Block8_1 [label="\ +// Block 1\nv3 := cycle1()\l\ +// "]; +// Block8_1 -> Block8_1Exit [arrowhead=none]; +// Block8_1Exit [label="Jump" shape=oval]; +// Block8_1Exit -> Block8_2; +// Block8_2 [label="\ +// Block 2\nv4 := φ(\l\ +// Block 0 => 0,\l\ +// Block 1 => v3\l\ +// )\l\ +// "]; +// Block8_2Exit [label="FunctionReturn[v4]"]; +// Block8_2 -> Block8_2Exit; +// } From 47ba76f14018e1570c9ad47ab15760883e2c2dd9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Tue, 24 Sep 2024 16:07:46 +0200 Subject: [PATCH 0438/1022] benchmarks: Move shared code using /usr/bin/time into a helper with JSON output --- scripts/common.sh | 20 ++++++++++++++++++-- test/benchmarks/external.sh | 18 ++++++++---------- test/benchmarks/local.sh | 12 ++++++------ 3 files changed, 32 insertions(+), 18 deletions(-) diff --git a/scripts/common.sh b/scripts/common.sh index 81dd2ec491a8..2061649f7681 100644 --- a/scripts/common.sh +++ b/scripts/common.sh @@ -327,7 +327,7 @@ function gnu_grep function time_to_json_file { - local output_file="$1" + local time_file="$1" local cmd=("${@:2}") (( $# >= 2 )) || assertFail @@ -340,9 +340,25 @@ function time_to_json_file { { time { "${cmd[@]}" 1>&3 2>&4; } - } 2> "$output_file" + } 2> "$time_file" } 3>&1 4>&2 # Restore original format so that it does not spill outside of the function. TIMEFORMAT="$original_timeformat" } + +function gnu_time_to_json_file +{ + local time_file="$1" + local cmd=("${@:2}") + (( $# >= 2 )) || assertFail + + local gnu_time_path + gnu_time_path=$(type -P time) + + "$gnu_time_path" \ + --output "$time_file" \ + --quiet \ + --format '{"real": %e, "user": %U, "sys": %S, "exit": %x}' \ + "${cmd[@]}" +} diff --git a/test/benchmarks/external.sh b/test/benchmarks/external.sh index b37c9105d610..cf75a0c9f2eb 100755 --- a/test/benchmarks/external.sh +++ b/test/benchmarks/external.sh @@ -46,6 +46,7 @@ source "${repo_root}/scripts/common_cmdline.sh" solc="${1:-${SOLIDITY_BUILD_DIR}/solc/solc}" command_available "$solc" --version +command_available "$(type -P time)" --version function benchmark_project { local pipeline="$1" @@ -59,18 +60,16 @@ function benchmark_project { # NOTE: The pipeline may fail with "Stack too deep" in some cases. That's fine. # We note the exit code and will later show full output. - "$time_bin_path" \ - --output "$time_file" \ - --quiet \ - --format '%e s | %x' \ - "${foundry_command[@]}" \ - > /dev/null \ - 2> "../stderr-${project}-${pipeline}.log" || true + gnu_time_to_json_file "$time_file" \ + "${foundry_command[@]}" \ + > /dev/null \ + 2> "../stderr-${project}-${pipeline}.log" || true - printf '| %-20s | %8s | %21s |\n' \ + printf '| %-20s | %8s | %7s s | %9d |\n' \ "$project" \ "$pipeline" \ - "$(cat "$time_file")" + "$(jq '.real' "$time_file")" \ + "$(jq '.exit' "$time_file")" cd .. } @@ -82,7 +81,6 @@ benchmarks=( seaport sablier-v2 ) -time_bin_path=$(type -P time) mkdir -p "$BENCHMARK_DIR" cd "$BENCHMARK_DIR" diff --git a/test/benchmarks/local.sh b/test/benchmarks/local.sh index 16a0c3afe32c..42018e7a1ff7 100755 --- a/test/benchmarks/local.sh +++ b/test/benchmarks/local.sh @@ -35,6 +35,7 @@ source "${REPO_ROOT}/scripts/common_cmdline.sh" solc="${1:-${SOLIDITY_BUILD_DIR}/solc/solc}" command_available "$solc" --version +command_available "$(type -P time)" --version output_dir=$(mktemp -d -t solc-benchmark-XXXXXX) @@ -51,24 +52,23 @@ function benchmark_contract { local solc_command=("${solc}" --optimize --bin --color "${input_path}") [[ $pipeline == via-ir ]] && solc_command+=(--via-ir) - local time_args=(--output "${output_dir}/time-and-status-${pipeline}.txt" --quiet --format '%e s | %x') + local time_file="${output_dir}/time-and-status-${pipeline}.txt" # NOTE: Legacy pipeline may fail with "Stack too deep" in some cases. That's fine. - "$time_bin_path" \ - "${time_args[@]}" \ + gnu_time_to_json_file "$time_file" \ "${solc_command[@]}" \ > "${output_dir}/bytecode-${pipeline}.bin" \ 2>> "${output_dir}/benchmark-warn-err.txt" || [[ $pipeline == legacy ]] - printf '| %-20s | %s | %7d bytes | %20s |\n' \ + printf '| %-20s | %s | %7d bytes | %6s s | %9d |\n' \ '`'"$input_file"'`' \ "$pipeline" \ "$(bytecode_size < "${output_dir}/bytecode-${pipeline}.bin")" \ - "$(< "${output_dir}/time-and-status-${pipeline}.txt")" + "$(jq '.real' "$time_file")" \ + "$(jq '.exit' "$time_file")" } benchmarks=("verifier.sol" "OptimizorClub.sol" "chains.sol") -time_bin_path=$(type -P time) echo "| File | Pipeline | Bytecode size | Time | Exit code |" echo "|----------------------|----------|--------------:|---------:|----------:|" From 8bb279bed90fc7eb494fe2389fc95abe8f4486de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Tue, 24 Sep 2024 16:21:51 +0200 Subject: [PATCH 0439/1022] benchmarks: Switch to displaying CPU time rather than wall clock time and round it for external projects --- test/benchmarks/external.sh | 4 ++-- test/benchmarks/local.sh | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/test/benchmarks/external.sh b/test/benchmarks/external.sh index cf75a0c9f2eb..5188d23d853c 100755 --- a/test/benchmarks/external.sh +++ b/test/benchmarks/external.sh @@ -65,10 +65,10 @@ function benchmark_project { > /dev/null \ 2> "../stderr-${project}-${pipeline}.log" || true - printf '| %-20s | %8s | %7s s | %9d |\n' \ + printf '| %-20s | %8s | %7d s | %9d |\n' \ "$project" \ "$pipeline" \ - "$(jq '.real' "$time_file")" \ + "$(jq '(.user + .sys) | round' "$time_file")" \ "$(jq '.exit' "$time_file")" cd .. } diff --git a/test/benchmarks/local.sh b/test/benchmarks/local.sh index 42018e7a1ff7..f250251b160b 100755 --- a/test/benchmarks/local.sh +++ b/test/benchmarks/local.sh @@ -60,11 +60,11 @@ function benchmark_contract { > "${output_dir}/bytecode-${pipeline}.bin" \ 2>> "${output_dir}/benchmark-warn-err.txt" || [[ $pipeline == legacy ]] - printf '| %-20s | %s | %7d bytes | %6s s | %9d |\n' \ + printf '| %-20s | %s | %7d bytes | %6.2f s | %9d |\n' \ '`'"$input_file"'`' \ "$pipeline" \ "$(bytecode_size < "${output_dir}/bytecode-${pipeline}.bin")" \ - "$(jq '.real' "$time_file")" \ + "$(jq '(.user + .sys) * 100 | round / 100' "$time_file")" \ "$(jq '.exit' "$time_file")" } From 95534b6b200c49bfa5f7d801a2cc7f8b4b402666 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Tue, 24 Sep 2024 16:24:00 +0200 Subject: [PATCH 0440/1022] benchmarks: Show peak memory usage --- scripts/common.sh | 2 +- test/benchmarks/external.sh | 7 ++++--- test/benchmarks/local.sh | 7 ++++--- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/scripts/common.sh b/scripts/common.sh index 2061649f7681..0ca602ee6a60 100644 --- a/scripts/common.sh +++ b/scripts/common.sh @@ -359,6 +359,6 @@ function gnu_time_to_json_file "$gnu_time_path" \ --output "$time_file" \ --quiet \ - --format '{"real": %e, "user": %U, "sys": %S, "exit": %x}' \ + --format '{"real": %e, "user": %U, "sys": %S, "mem": %M, "exit": %x}' \ "${cmd[@]}" } diff --git a/test/benchmarks/external.sh b/test/benchmarks/external.sh index 5188d23d853c..e93c485fac26 100755 --- a/test/benchmarks/external.sh +++ b/test/benchmarks/external.sh @@ -65,10 +65,11 @@ function benchmark_project { > /dev/null \ 2> "../stderr-${project}-${pipeline}.log" || true - printf '| %-20s | %8s | %7d s | %9d |\n' \ + printf '| %-20s | %8s | %7d s | %9d MiB | %9d |\n' \ "$project" \ "$pipeline" \ "$(jq '(.user + .sys) | round' "$time_file")" \ + "$(jq '.mem / 1024 | round' "$time_file")" \ "$(jq '.exit' "$time_file")" cd .. } @@ -85,8 +86,8 @@ benchmarks=( mkdir -p "$BENCHMARK_DIR" cd "$BENCHMARK_DIR" -echo "| Project | Pipeline | Time | Exit code |" -echo "|----------------------|----------|----------:|----------:|" +echo "| Project | Pipeline | Time | Memory (peak) | Exit code |" +echo "|----------------------|----------|----------:|--------------:|----------:|" for project in "${benchmarks[@]}"; do benchmark_project legacy "$project" diff --git a/test/benchmarks/local.sh b/test/benchmarks/local.sh index f250251b160b..c86eb4952642 100755 --- a/test/benchmarks/local.sh +++ b/test/benchmarks/local.sh @@ -60,18 +60,19 @@ function benchmark_contract { > "${output_dir}/bytecode-${pipeline}.bin" \ 2>> "${output_dir}/benchmark-warn-err.txt" || [[ $pipeline == legacy ]] - printf '| %-20s | %s | %7d bytes | %6.2f s | %9d |\n' \ + printf '| %-20s | %s | %7d bytes | %6.2f s | %9d MiB | %9d |\n' \ '`'"$input_file"'`' \ "$pipeline" \ "$(bytecode_size < "${output_dir}/bytecode-${pipeline}.bin")" \ "$(jq '(.user + .sys) * 100 | round / 100' "$time_file")" \ + "$(jq '.mem / 1024 | round' "$time_file")" \ "$(jq '.exit' "$time_file")" } benchmarks=("verifier.sol" "OptimizorClub.sol" "chains.sol") -echo "| File | Pipeline | Bytecode size | Time | Exit code |" -echo "|----------------------|----------|--------------:|---------:|----------:|" +echo "| File | Pipeline | Bytecode size | Time | Memory (peak) | Exit code |" +echo "|----------------------|----------|--------------:|---------:|--------------:|----------:|" for input_file in "${benchmarks[@]}" do From 9bf850bf8887be2558cf9bf9f6e282658d25cb6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Tue, 24 Sep 2024 16:26:26 +0200 Subject: [PATCH 0441/1022] benchmarks: Cosmetic tweaks to how results are displayed - via-ir -> ir - Centered headers --- test/benchmarks/external.sh | 6 +++--- test/benchmarks/local.sh | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/test/benchmarks/external.sh b/test/benchmarks/external.sh index e93c485fac26..9acaccb67f79 100755 --- a/test/benchmarks/external.sh +++ b/test/benchmarks/external.sh @@ -65,7 +65,7 @@ function benchmark_project { > /dev/null \ 2> "../stderr-${project}-${pipeline}.log" || true - printf '| %-20s | %8s | %7d s | %9d MiB | %9d |\n' \ + printf '| %-20s | %8s | %6d s | %9d MiB | %9d |\n' \ "$project" \ "$pipeline" \ "$(jq '(.user + .sys) | round' "$time_file")" \ @@ -86,8 +86,8 @@ benchmarks=( mkdir -p "$BENCHMARK_DIR" cd "$BENCHMARK_DIR" -echo "| Project | Pipeline | Time | Memory (peak) | Exit code |" -echo "|----------------------|----------|----------:|--------------:|----------:|" +echo "| File | Pipeline | Time | Memory (peak) | Exit code |" +echo "|----------------------|----------|---------:|--------------:|----------:|" for project in "${benchmarks[@]}"; do benchmark_project legacy "$project" diff --git a/test/benchmarks/local.sh b/test/benchmarks/local.sh index c86eb4952642..0696443019d9 100755 --- a/test/benchmarks/local.sh +++ b/test/benchmarks/local.sh @@ -51,7 +51,7 @@ function benchmark_contract { local input_path="$2" local solc_command=("${solc}" --optimize --bin --color "${input_path}") - [[ $pipeline == via-ir ]] && solc_command+=(--via-ir) + [[ $pipeline == ir ]] && solc_command+=(--via-ir) local time_file="${output_dir}/time-and-status-${pipeline}.txt" # NOTE: Legacy pipeline may fail with "Stack too deep" in some cases. That's fine. @@ -60,7 +60,7 @@ function benchmark_contract { > "${output_dir}/bytecode-${pipeline}.bin" \ 2>> "${output_dir}/benchmark-warn-err.txt" || [[ $pipeline == legacy ]] - printf '| %-20s | %s | %7d bytes | %6.2f s | %9d MiB | %9d |\n' \ + printf '| %-20s | %8s | %7d bytes | %6.2f s | %9d MiB | %9d |\n' \ '`'"$input_file"'`' \ "$pipeline" \ "$(bytecode_size < "${output_dir}/bytecode-${pipeline}.bin")" \ @@ -71,13 +71,13 @@ function benchmark_contract { benchmarks=("verifier.sol" "OptimizorClub.sol" "chains.sol") -echo "| File | Pipeline | Bytecode size | Time | Memory (peak) | Exit code |" +echo "| File | Pipeline | Bytecode size | Time | Memory (peak) | Exit code |" echo "|----------------------|----------|--------------:|---------:|--------------:|----------:|" for input_file in "${benchmarks[@]}" do benchmark_contract legacy "${REPO_ROOT}/test/benchmarks/${input_file}" - benchmark_contract via-ir "${REPO_ROOT}/test/benchmarks/${input_file}" + benchmark_contract ir "${REPO_ROOT}/test/benchmarks/${input_file}" done echo From 545cab32de0e1c09dcbe489f002bae285e220fd8 Mon Sep 17 00:00:00 2001 From: rodiazet Date: Wed, 25 Sep 2024 09:49:16 +0200 Subject: [PATCH 0442/1022] eof: Refactor `assemble` functions in `evmasm::Assembly`` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Kamil Śliwak --- libevmasm/Assembly.cpp | 226 +++++++++++---------- libevmasm/Assembly.h | 14 ++ libevmasm/LinkerObject.h | 3 +- libsolidity/interface/StandardCompiler.cpp | 2 +- 4 files changed, 140 insertions(+), 105 deletions(-) diff --git a/libevmasm/Assembly.cpp b/libevmasm/Assembly.cpp index 0d5468e2678e..f993095540b7 100644 --- a/libevmasm/Assembly.cpp +++ b/libevmasm/Assembly.cpp @@ -926,19 +926,19 @@ std::tuple, size_t> Assembly::createEOFHeader(std::se retBytecode.push_back(0xef); retBytecode.push_back(0x00); - retBytecode.push_back(0x01); // version 1 + retBytecode.push_back(0x01); // version 1 - retBytecode.push_back(0x01); // kind=type - appendBigEndianUint16(retBytecode, m_codeSections.size() * 4u); // length of type section + retBytecode.push_back(0x01); // kind=type + appendBigEndianUint16(retBytecode, m_codeSections.size() * 4u); // length of type section - retBytecode.push_back(0x02); // kind=code - appendBigEndianUint16(retBytecode, m_codeSections.size()); // placeholder for number of code sections + retBytecode.push_back(0x02); // kind=code + appendBigEndianUint16(retBytecode, m_codeSections.size()); // placeholder for number of code sections for (auto const& codeSection: m_codeSections) { (void) codeSection; codeSectionSizeOffsets.emplace_back(retBytecode.size()); - appendBigEndianUint16(retBytecode, 0u); // placeholder for length of code + appendBigEndianUint16(retBytecode, 0u); // placeholder for length of code } if (!_referencedSubIds.empty()) @@ -950,17 +950,18 @@ std::tuple, size_t> Assembly::createEOFHeader(std::se appendBigEndianUint16(retBytecode, m_subs[subId]->assemble().bytecode.size()); } - retBytecode.push_back(0x04); // kind=data + retBytecode.push_back(0x04); // kind=data dataSectionSizeOffset = retBytecode.size(); - appendBigEndianUint16(retBytecode, 0u); // length of data + appendBigEndianUint16(retBytecode, 0u); // length of data - retBytecode.push_back(0x00); // terminator + retBytecode.push_back(0x00); // terminator for (auto const& codeSection: m_codeSections) { retBytecode.push_back(codeSection.inputs); retBytecode.push_back(codeSection.outputs); - appendBigEndianUint16(retBytecode, 0xFFFFu); // TODO: Add stack height calculation + // TODO: Add stack height calculation + appendBigEndianUint16(retBytecode, 0xFFFFu); } return {retBytecode, codeSectionSizeOffsets, dataSectionSizeOffset}; @@ -985,6 +986,65 @@ LinkerObject const& Assembly::assemble() const return assembleEOF(); } +[[nodiscard]] bytes Assembly::assembleOperation(AssemblyItem const& _item) const +{ + // solidity::evmasm::Instructions underlying type is uint8_t + // TODO: Change to std::to_underlying since C++23 + return {static_cast(_item.instruction())}; +} + +[[nodiscard]] bytes Assembly::assemblePush(AssemblyItem const& _item) const +{ + bytes ret; + unsigned pushValueSize = numberEncodingSize(_item.data()); + if (pushValueSize == 0 && !m_evmVersion.hasPush0()) + pushValueSize = 1; + + // solidity::evmasm::Instructions underlying type is uint8_t + // TODO: Change to std::to_underlying since C++23 + ret.push_back(static_cast(pushInstruction(pushValueSize))); + if (pushValueSize > 0) + appendBigEndian(ret, pushValueSize, _item.data()); + + return ret; +} + +[[nodiscard]] std::pair Assembly::assemblePushLibraryAddress(AssemblyItem const& _item, size_t _pos) const +{ + return { + // solidity::evmasm::Instructions underlying type is uint8_t + // TODO: Change to std::to_underlying since C++23 + bytes(1, static_cast(Instruction::PUSH20)) + bytes(20), + {_pos + 1, m_libraries.at(_item.data())} + }; +} + +[[nodiscard]] bytes Assembly::assembleVerbatimBytecode(AssemblyItem const& item) const +{ + return item.verbatimData(); +} + +[[nodiscard]] bytes Assembly::assemblePushDeployTimeAddress() const +{ + // solidity::evmasm::Instructions underlying type is uint8_t + // TODO: Change to std::to_underlying since C++23 + return bytes(1, static_cast(Instruction::PUSH20)) + bytes(20); +} + +[[nodiscard]] bytes Assembly::assembleTag(AssemblyItem const& _item, size_t _pos, bool _addJumpDest) const +{ + solRequire(_item.data() != 0, AssemblyException, "Invalid tag position."); + solRequire(_item.splitForeignPushTag().first == std::numeric_limits::max(), AssemblyException, "Foreign tag."); + solRequire(_pos < 0xffffffffL, AssemblyException, "Tag too large."); + size_t tagId = static_cast(_item.data()); + solRequire(m_tagPositionsInBytecode[tagId] == std::numeric_limits::max(), AssemblyException, "Duplicate tag position."); + m_tagPositionsInBytecode[tagId] = _pos; + + // solidity::evmasm::Instructions underlying type is uint8_t + // TODO: Change to std::to_underlying since C++23 + return _addJumpDest ? bytes(1, static_cast(Instruction::JUMPDEST)) : bytes(); +} + LinkerObject const& Assembly::assembleLegacy() const { solAssert(!m_eofVersion.has_value()); @@ -998,7 +1058,7 @@ LinkerObject const& Assembly::assembleLegacy() const LinkerObject& ret = m_assembledObject; size_t subTagSize = 1; - std::map>> immutableReferencesBySub; + std::map immutableReferencesBySub; for (auto const& sub: m_subs) { auto const& linkerObject = sub->assemble(); @@ -1039,10 +1099,6 @@ LinkerObject const& Assembly::assembleLegacy() const unsigned bytesRequiredForCode = codeSize(static_cast(subTagSize)); m_tagPositionsInBytecode = std::vector(m_usedTags, std::numeric_limits::max()); - std::map> tagRef; - std::multimap dataRef; - std::multimap subRef; - std::vector sizeRef; ///< Pointers to code locations where the size of the program is inserted unsigned bytesPerTag = numberEncodingSize(bytesRequiredForCode); // Adjust bytesPerTag for references to sub assemblies. for (AssemblyItem const& item: items) @@ -1056,16 +1112,21 @@ LinkerObject const& Assembly::assembleLegacy() const assertThrow(subTagPosition != std::numeric_limits::max(), AssemblyException, "Reference to tag without position."); bytesPerTag = std::max(bytesPerTag, numberEncodingSize(subTagPosition)); } - uint8_t tagPush = static_cast(pushInstruction(bytesPerTag)); unsigned bytesRequiredIncludingData = bytesRequiredForCode + 1 + static_cast(m_auxiliaryData.size()); for (auto const& sub: m_subs) bytesRequiredIncludingData += static_cast(sub->assemble().bytecode.size()); unsigned bytesPerDataRef = numberEncodingSize(bytesRequiredIncludingData); - uint8_t dataRefPush = static_cast(pushInstruction(bytesPerDataRef)); ret.bytecode.reserve(bytesRequiredIncludingData); + TagRefs tagRefs; + DataRefs dataRefs; + SubAssemblyRefs subRefs; + ProgramSizeRefs sizeRefs; + uint8_t tagPush = static_cast(pushInstruction(bytesPerTag)); + uint8_t dataRefPush = static_cast(pushInstruction(bytesPerDataRef)); + for (AssemblyItem const& item: items) { // store position of the invalid jump destination @@ -1075,40 +1136,27 @@ LinkerObject const& Assembly::assembleLegacy() const switch (item.type()) { case Operation: - ret.bytecode.push_back(static_cast(item.instruction())); + ret.bytecode += assembleOperation(item); break; case Push: - { - unsigned b = numberEncodingSize(item.data()); - if (b == 0 && !m_evmVersion.hasPush0()) - { - b = 1; - } - ret.bytecode.push_back(static_cast(pushInstruction(b))); - if (b > 0) - { - ret.bytecode.resize(ret.bytecode.size() + b); - bytesRef byr(&ret.bytecode.back() + 1 - b, b); - toBigEndian(item.data(), byr); - } + ret.bytecode += assemblePush(item); break; - } case PushTag: { ret.bytecode.push_back(tagPush); - tagRef[ret.bytecode.size()] = item.splitForeignPushTag(); + tagRefs[ret.bytecode.size()] = item.splitForeignPushTag(); ret.bytecode.resize(ret.bytecode.size() + bytesPerTag); break; } case PushData: ret.bytecode.push_back(dataRefPush); - dataRef.insert(std::make_pair(h256(item.data()), ret.bytecode.size())); + dataRefs.insert(std::make_pair(h256(item.data()), ret.bytecode.size())); ret.bytecode.resize(ret.bytecode.size() + bytesPerDataRef); break; case PushSub: assertThrow(item.data() <= std::numeric_limits::max(), AssemblyException, ""); ret.bytecode.push_back(dataRefPush); - subRef.insert(std::make_pair(static_cast(item.data()), ret.bytecode.size())); + subRefs.insert(std::make_pair(static_cast(item.data()), ret.bytecode.size())); ret.bytecode.resize(ret.bytecode.size() + bytesPerDataRef); break; case PushSubSize: @@ -1126,15 +1174,17 @@ LinkerObject const& Assembly::assembleLegacy() const case PushProgramSize: { ret.bytecode.push_back(dataRefPush); - sizeRef.push_back(static_cast(ret.bytecode.size())); + sizeRefs.push_back(static_cast(ret.bytecode.size())); ret.bytecode.resize(ret.bytecode.size() + bytesPerDataRef); break; } case PushLibraryAddress: - ret.bytecode.push_back(static_cast(Instruction::PUSH20)); - ret.linkReferences[ret.bytecode.size()] = m_libraries.at(item.data()); - ret.bytecode.resize(ret.bytecode.size() + 20); + { + auto const [bytecode, linkRef] = assemblePushLibraryAddress(item, ret.bytecode.size()); + ret.bytecode += bytecode; + ret.linkReferences.insert(linkRef); break; + } case PushImmutable: ret.bytecode.push_back(static_cast(Instruction::PUSH32)); // Maps keccak back to the "identifier" std::string of that immutable. @@ -1145,7 +1195,7 @@ LinkerObject const& Assembly::assembleLegacy() const ret.bytecode.resize(ret.bytecode.size() + 32); break; case VerbatimBytecode: - ret.bytecode += item.verbatimData(); + ret.bytecode += assembleVerbatimBytecode(item); break; case AssignImmutable: { @@ -1174,20 +1224,11 @@ LinkerObject const& Assembly::assembleLegacy() const break; } case PushDeployTimeAddress: - ret.bytecode.push_back(static_cast(Instruction::PUSH20)); - ret.bytecode.resize(ret.bytecode.size() + 20); + ret.bytecode += assemblePushDeployTimeAddress(); break; case Tag: - { - assertThrow(item.data() != 0, AssemblyException, "Invalid tag position."); - assertThrow(item.splitForeignPushTag().first == std::numeric_limits::max(), AssemblyException, "Foreign tag."); - size_t tagId = static_cast(item.data()); - assertThrow(ret.bytecode.size() < 0xffffffffL, AssemblyException, "Tag too large."); - assertThrow(m_tagPositionsInBytecode[tagId] == std::numeric_limits::max(), AssemblyException, "Duplicate tag position."); - m_tagPositionsInBytecode[tagId] = ret.bytecode.size(); - ret.bytecode.push_back(static_cast(Instruction::JUMPDEST)); + ret.bytecode += assembleTag(item, ret.bytecode.size(), true); break; - } default: assertThrow(false, InvalidOpcode, "Unexpected opcode while assembling."); } @@ -1206,7 +1247,7 @@ LinkerObject const& Assembly::assembleLegacy() const ret.bytecode.push_back(static_cast(Instruction::INVALID)); std::map subAssemblyOffsets; - for (auto const& [subIdPath, bytecodeOffset]: subRef) + for (auto const& [subIdPath, bytecodeOffset]: subRefs) { LinkerObject subObject = subAssemblyById(subIdPath)->assemble(); bytesRef r(ret.bytecode.data() + bytecodeOffset, bytesPerDataRef); @@ -1224,7 +1265,7 @@ LinkerObject const& Assembly::assembleLegacy() const for (auto const& ref: subObject.linkReferences) ret.linkReferences[ref.first + subAssemblyOffsets[subObject]] = ref.second; } - for (auto const& i: tagRef) + for (auto const& i: tagRefs) { size_t subId; size_t tagId; @@ -1262,7 +1303,7 @@ LinkerObject const& Assembly::assembleLegacy() const for (auto const& dataItem: m_data) { - auto references = dataRef.equal_range(dataItem.first); + auto references = dataRefs.equal_range(dataItem.first); if (references.first == references.second) continue; for (auto ref = references.first; ref != references.second; ++ref) @@ -1275,7 +1316,7 @@ LinkerObject const& Assembly::assembleLegacy() const ret.bytecode += m_auxiliaryData; - for (unsigned pos: sizeRef) + for (unsigned pos: sizeRefs) { bytesRef r(ret.bytecode.data() + pos, bytesPerDataRef); toBigEndian(ret.bytecode.size(), r); @@ -1321,15 +1362,14 @@ LinkerObject const& Assembly::assembleEOF() const ); // Insert EOF1 header. - auto [bytecode, codeSectionSizeOffsets, dataSectionSizeOffset] = createEOFHeader(referencedSubIds); - ret.bytecode = bytecode; + auto [headerBytecode, codeSectionSizeOffsets, dataSectionSizeOffset] = createEOFHeader(referencedSubIds); + ret.bytecode = headerBytecode; m_tagPositionsInBytecode = std::vector(m_usedTags, std::numeric_limits::max()); for (auto&& [codeSectionIndex, codeSection]: m_codeSections | ranges::views::enumerate) { auto const sectionStart = ret.bytecode.size(); - for (AssemblyItem const& item: codeSection.items) { // store position of the invalid jump destination @@ -1338,54 +1378,34 @@ LinkerObject const& Assembly::assembleEOF() const switch (item.type()) { - case Operation: - ret.bytecode.push_back(static_cast(item.instruction())); - break; - case Push: - { - unsigned pushValueSize = numberEncodingSize(item.data()); - if (pushValueSize == 0 && !m_evmVersion.hasPush0()) - { - pushValueSize = 1; - } - ret.bytecode.push_back(static_cast(pushInstruction(pushValueSize))); - if (pushValueSize > 0) - { - ret.bytecode.resize(ret.bytecode.size() + pushValueSize); - bytesRef pushValueBytecodeRef(&ret.bytecode.back() + 1 - pushValueSize, pushValueSize); - toBigEndian(item.data(), pushValueBytecodeRef); - } - break; - } - case PushLibraryAddress: - ret.bytecode.push_back(static_cast(Instruction::PUSH20)); - ret.linkReferences[ret.bytecode.size()] = m_libraries.at(item.data()); - ret.bytecode.resize(ret.bytecode.size() + 20); - break; - case VerbatimBytecode: - ret.bytecode += item.verbatimData(); - break; - case PushDeployTimeAddress: - ret.bytecode.push_back(static_cast(Instruction::PUSH20)); - ret.bytecode.resize(ret.bytecode.size() + 20); - break; - case Tag: - { - solRequire(item.data() != 0, AssemblyException, "Invalid tag position."); - solRequire(item.splitForeignPushTag().first == std::numeric_limits::max(), AssemblyException, "Foreign tag."); - size_t tagId = static_cast(item.data()); - solRequire(ret.bytecode.size() < 0xffffffffL, AssemblyException, "Tag too large."); - solRequire(m_tagPositionsInBytecode[tagId] == std::numeric_limits::max(), AssemblyException, "Duplicate tag position."); - m_tagPositionsInBytecode[tagId] = ret.bytecode.size(); - break; - } - default: - solRequire(false, InvalidOpcode, "Unexpected opcode while assembling."); + case Operation: + ret.bytecode += assembleOperation(item); + break; + case Push: + ret.bytecode += assemblePush(item); + break; + case PushLibraryAddress: + { + auto const [pushLibraryAddressBytecode, linkRef] = assemblePushLibraryAddress(item, ret.bytecode.size()); + ret.bytecode += pushLibraryAddressBytecode; + ret.linkReferences.insert(linkRef); + break; + } + case VerbatimBytecode: + ret.bytecode += assembleVerbatimBytecode(item); + break; + case PushDeployTimeAddress: + ret.bytecode += assemblePushDeployTimeAddress(); + break; + case Tag: + ret.bytecode += assembleTag(item, ret.bytecode.size(), false); + break; + default: + solThrow(InvalidOpcode, "Unexpected opcode while assembling."); } } - auto sectionEnd = ret.bytecode.size(); - setBigEndianUint16(ret.bytecode, codeSectionSizeOffsets[codeSectionIndex], sectionEnd - sectionStart); + setBigEndianUint16(ret.bytecode, codeSectionSizeOffsets[codeSectionIndex], ret.bytecode.size() - sectionStart); } for (auto i: referencedSubIds) diff --git a/libevmasm/Assembly.h b/libevmasm/Assembly.h index 41e735db612f..de1ac20f2015 100644 --- a/libevmasm/Assembly.h +++ b/libevmasm/Assembly.h @@ -47,6 +47,12 @@ using AssemblyPointer = std::shared_ptr; class Assembly { + using TagRefs = std::map>; + using DataRefs = std::multimap; + using SubAssemblyRefs = std::multimap; + using ProgramSizeRefs = std::vector; + using LinkRef = std::pair; + public: Assembly(langutil::EVMVersion _evmVersion, bool _creation, std::optional _eofVersion, std::string _name): m_evmVersion(_evmVersion), @@ -235,6 +241,14 @@ class Assembly /// Returns map from m_subs to an index of subcontainer in the final EOF bytecode std::map findReferencedContainers() const; + /// Assemble bytecode for AssemblyItem type. + [[nodiscard]] bytes assembleOperation(AssemblyItem const& _item) const; + [[nodiscard]] bytes assemblePush(AssemblyItem const& _item) const; + [[nodiscard]] std::pair assemblePushLibraryAddress(AssemblyItem const& _item, size_t _pos) const; + [[nodiscard]] bytes assembleVerbatimBytecode(AssemblyItem const& item) const; + [[nodiscard]] bytes assemblePushDeployTimeAddress() const; + [[nodiscard]] bytes assembleTag(AssemblyItem const& _item, size_t _pos, bool _addJumpDest) const; + protected: /// 0 is reserved for exception unsigned m_usedTags = 1; diff --git a/libevmasm/LinkerObject.h b/libevmasm/LinkerObject.h index 90b519e3af25..c103a565a069 100644 --- a/libevmasm/LinkerObject.h +++ b/libevmasm/LinkerObject.h @@ -34,6 +34,7 @@ namespace solidity::evmasm */ struct LinkerObject { + using ImmutableRefs = std::pair>; /// The bytecode. bytes bytecode; @@ -43,7 +44,7 @@ struct LinkerObject /// Map from hashes of the identifiers of immutable variables to the full identifier of the immutable and /// to a list of offsets into the bytecode that refer to their values. - std::map>> immutableReferences; + std::map immutableReferences; struct FunctionDebugData { diff --git a/libsolidity/interface/StandardCompiler.cpp b/libsolidity/interface/StandardCompiler.cpp index cd00caf073b3..06df8a940856 100644 --- a/libsolidity/interface/StandardCompiler.cpp +++ b/libsolidity/interface/StandardCompiler.cpp @@ -349,7 +349,7 @@ Json formatLinkReferences(std::map const& linkReferences) return ret; } -Json formatImmutableReferences(std::map>> const& _immutableReferences) +Json formatImmutableReferences(std::map const& _immutableReferences) { Json ret = Json::object(); From 09c48f57534d1da162409773954d8e98aeba178d Mon Sep 17 00:00:00 2001 From: rodiazet Date: Tue, 24 Sep 2024 15:22:18 +0200 Subject: [PATCH 0443/1022] eof: Support EOF in `assemblyStream` --- libevmasm/Assembly.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/libevmasm/Assembly.cpp b/libevmasm/Assembly.cpp index f993095540b7..ab26526e14c2 100644 --- a/libevmasm/Assembly.cpp +++ b/libevmasm/Assembly.cpp @@ -403,13 +403,14 @@ void Assembly::assemblyStream( { Functionalizer f(_out, _prefix, _sourceCodes, *this); - // TODO: support EOF - solUnimplementedAssert(!m_eofVersion.has_value(), "Assembly output for EOF is not yet implemented."); - solAssert(m_codeSections.size() == 1); for (auto const& i: m_codeSections.front().items) f.feed(i, _debugInfoSelection); f.flush(); + // Implementing this requires introduction of CALLF, RETF and JUMPF + if (m_codeSections.size() > 1) + solUnimplemented("Add support for more code sections"); + if (!m_data.empty() || !m_subs.empty()) { _out << _prefix << "stop" << std::endl; From 9e65fffd58b63ee881f38cb955442b0828ed2ceb Mon Sep 17 00:00:00 2001 From: rodiazet Date: Tue, 24 Sep 2024 15:34:34 +0200 Subject: [PATCH 0444/1022] eof: Support EOF in `computeSourceMapping` --- libevmasm/AssemblyItem.cpp | 5 +++-- libyul/YulStack.cpp | 15 +++++++-------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/libevmasm/AssemblyItem.cpp b/libevmasm/AssemblyItem.cpp index 837dad8afe1b..1bc805780145 100644 --- a/libevmasm/AssemblyItem.cpp +++ b/libevmasm/AssemblyItem.cpp @@ -450,9 +450,10 @@ std::string AssemblyItem::computeSourceMapping( static_cast(_sourceIndicesMap.at(*location.sourceName)) : -1; char jump = '-'; - if (item.getJumpType() == evmasm::AssemblyItem::JumpType::IntoFunction) + // TODO: Uncomment when EOF functions introduced. + if (item.getJumpType() == evmasm::AssemblyItem::JumpType::IntoFunction /*|| item.type() == CallF || item.type() == JumpF*/) jump = 'i'; - else if (item.getJumpType() == evmasm::AssemblyItem::JumpType::OutOfFunction) + else if (item.getJumpType() == evmasm::AssemblyItem::JumpType::OutOfFunction /*|| item.type() == RetF*/) jump = 'o'; int modifierDepth = static_cast(item.m_modifierDepth); diff --git a/libyul/YulStack.cpp b/libyul/YulStack.cpp index a8e19a69a179..59766220cda5 100644 --- a/libyul/YulStack.cpp +++ b/libyul/YulStack.cpp @@ -262,15 +262,14 @@ YulStack::assembleWithDeployed(std::optional _deployName) creationObject.bytecode = std::make_shared(creationAssembly->assemble()); yulAssert(creationObject.bytecode->immutableReferences.empty(), "Leftover immutables."); creationObject.assembly = creationAssembly; - solUnimplementedAssert(!m_eofVersion.has_value(), "EVM assembly output not implemented for EOF yet."); - solAssert(creationAssembly->codeSections().size() == 1); - creationObject.sourceMappings = std::make_unique( - // TODO: fix for EOF - evmasm::AssemblyItem::computeSourceMapping( - creationAssembly->codeSections().front().items, + creationObject.sourceMappings = std::make_unique(); + for (auto const& codeSection: creationAssembly->codeSections()) + { + *creationObject.sourceMappings += evmasm::AssemblyItem::computeSourceMapping( + codeSection.items, {{m_charStream->name(), 0}} - ) - ); + ); + } if (deployedAssembly) { From 415d2fca3692d676f007bfdd9f4acd4227de3c57 Mon Sep 17 00:00:00 2001 From: rodiazet Date: Wed, 25 Sep 2024 10:27:58 +0200 Subject: [PATCH 0445/1022] eof: strict asm output test update --- .../strict_asm_eof_container_prague/args | 2 +- .../strict_asm_eof_container_prague/output | 98 +++++++++++++++++++ 2 files changed, 99 insertions(+), 1 deletion(-) diff --git a/test/cmdlineTests/strict_asm_eof_container_prague/args b/test/cmdlineTests/strict_asm_eof_container_prague/args index b8cc1ab18211..0078e6e68e36 100644 --- a/test/cmdlineTests/strict_asm_eof_container_prague/args +++ b/test/cmdlineTests/strict_asm_eof_container_prague/args @@ -1 +1 @@ - --strict-assembly --experimental-eof-version 1 --evm-version prague --bin + --strict-assembly --experimental-eof-version 1 --evm-version prague --asm --ir-optimized --bin --debug-info none diff --git a/test/cmdlineTests/strict_asm_eof_container_prague/output b/test/cmdlineTests/strict_asm_eof_container_prague/output index caf28d91d88e..17f6df675585 100644 --- a/test/cmdlineTests/strict_asm_eof_container_prague/output +++ b/test/cmdlineTests/strict_asm_eof_container_prague/output @@ -1,5 +1,103 @@ ======= strict_asm_eof_container_prague/input.yul (EVM) ======= +Pretty printed source: +object "object" { + code { { revert(0, 0) } } + object "sub0" { + code { + { + mstore(0, 0) + revert(0, 32) + } + } + } + object "sub1" { + code { + { + mstore(0, 1) + revert(0, 32) + } + } + } + object "sub2" { + code { + { + mstore(0, 2) + revert(0, 32) + } + } + object "sub20" { + code { + { + mstore(0, 0x20) + revert(0, 32) + } + } + } + } + object "sub3" { + code { + { + mstore(0, 3) + revert(0, 32) + } + } + } +} + + Binary representation: ef00010100040200010003030004001a001b003b001b040000000080ffff5f80fdef00010100040200010007040000000080ffff5f805260205ffdef00010100040200010008040000000080ffff60015f5260205ffdef00010100040200010008030001001b040000000080ffff60025f5260205ffdef00010100040200010008040000000080ffff60205f5260205ffdef00010100040200010008040000000080ffff60035f5260205ffd + +Text representation: + 0x00 + dup1 + revert +stop + +sub_0: assembly { + 0x00 + dup1 + mstore + 0x20 + 0x00 + revert +} + +sub_1: assembly { + 0x01 + 0x00 + mstore + 0x20 + 0x00 + revert +} + +sub_2: assembly { + 0x02 + 0x00 + mstore + 0x20 + 0x00 + revert + stop + + sub_0: assembly { + 0x20 + 0x00 + mstore + 0x20 + 0x00 + revert + } +} + +sub_3: assembly { + 0x03 + 0x00 + mstore + 0x20 + 0x00 + revert +} From cffc4f86382de5d611bf81cc50dee1ce2199b93f Mon Sep 17 00:00:00 2001 From: r0qs Date: Wed, 25 Sep 2024 15:33:22 +0200 Subject: [PATCH 0446/1022] Add missing ASAN runtime libraries --- scripts/docker/buildpack-deps/Dockerfile.ubuntu2404.clang | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/scripts/docker/buildpack-deps/Dockerfile.ubuntu2404.clang b/scripts/docker/buildpack-deps/Dockerfile.ubuntu2404.clang index c6b1fd970731..21092e312a7c 100644 --- a/scripts/docker/buildpack-deps/Dockerfile.ubuntu2404.clang +++ b/scripts/docker/buildpack-deps/Dockerfile.ubuntu2404.clang @@ -22,7 +22,7 @@ # (c) 2016-2024 solidity contributors. #------------------------------------------------------------------------------ FROM buildpack-deps:noble AS base -LABEL version="1" +LABEL version="2" ARG DEBIAN_FRONTEND=noninteractive @@ -40,13 +40,14 @@ RUN set -ex; \ clang \ cmake \ jq \ - lsof \ libboost-filesystem-dev \ libboost-program-options-dev \ libboost-system-dev \ libboost-test-dev \ + libclang-rt-dev \ libcln-dev \ libz3-static-dev \ + lsof \ ninja-build \ python3-pip \ software-properties-common \ From 4627827a44745406cc67e0a50916f918eadb552a Mon Sep 17 00:00:00 2001 From: r0qs Date: Wed, 25 Sep 2024 16:40:02 +0200 Subject: [PATCH 0447/1022] Bump ubuntu 24.04 clang image --- .circleci/config.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 18ca18f3c563..9afaa735fc3c 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -17,8 +17,8 @@ parameters: default: "solbuildpackpusher/solidity-buildpack-deps@sha256:5d6d27551104321a30326d6024bd4e96d9d899a97a78eb9feea364996f1d18b5" ubuntu-2404-clang-docker-image: type: string - # solbuildpackpusher/solidity-buildpack-deps:ubuntu2404.clang-1 - default: "solbuildpackpusher/solidity-buildpack-deps@sha256:8df0086907cc1e57068ad48841f2284a87bfbd0a95006286a19a7132d84bb861" + # solbuildpackpusher/solidity-buildpack-deps:ubuntu2404.clang-2 + default: "solbuildpackpusher/solidity-buildpack-deps@sha256:bc99a858ba18e088c1cb889ce631e3e707bb3348f0ae452bfe69116dbb931173" ubuntu-clang-ossfuzz-docker-image: type: string # solbuildpackpusher/solidity-buildpack-deps:ubuntu.clang.ossfuzz-6 From b7051362eeb816eca7dcf6d633b420663555cf65 Mon Sep 17 00:00:00 2001 From: r0qs Date: Wed, 25 Sep 2024 14:04:26 +0200 Subject: [PATCH 0448/1022] Do not treat all warnings as errors when building with sanitizers. --- .circleci/config.yml | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 18ca18f3c563..a71418833906 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1005,7 +1005,11 @@ jobs: <<: *base_ubuntu2404 environment: <<: *base_ubuntu2404_env - CMAKE_OPTIONS: -DSANITIZE=address + # NOTE: Sanitizers may alter the intermediate code, potentially causing false warnings. + # As a result, treating warnings as errors in instrumented builds can lead to build failures due to these false positives. + # Therefore, we disable pedantic builds in such cases. + # See: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105562#c27 + CMAKE_OPTIONS: -DSANITIZE=address -DPEDANTIC=OFF CMAKE_BUILD_TYPE: Release steps: - build @@ -1026,7 +1030,8 @@ jobs: <<: *base_ubuntu2404_clang environment: <<: *base_ubuntu2404_clang_env - CMAKE_OPTIONS: << parameters.cmake_options >> + # NOTE: Disabled pedantic builds to avoid false positives, see b_ubu_asan for a more detailed explanation. + CMAKE_OPTIONS: -DPEDANTIC=OFF << parameters.cmake_options >> steps: - build From 5643e8ee1dd14d9f2478c5c3306bfa8c580352b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Wed, 25 Sep 2024 18:24:46 +0200 Subject: [PATCH 0449/1022] Remove a few unused YulStack imports --- libsolidity/codegen/ir/IRGenerator.cpp | 2 +- libsolidity/experimental/codegen/IRGenerator.cpp | 1 - libsolidity/experimental/codegen/IRGeneratorForStatements.cpp | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/libsolidity/codegen/ir/IRGenerator.cpp b/libsolidity/codegen/ir/IRGenerator.cpp index f495d97abdfa..a80fb4c27f33 100644 --- a/libsolidity/codegen/ir/IRGenerator.cpp +++ b/libsolidity/codegen/ir/IRGenerator.cpp @@ -30,7 +30,7 @@ #include #include -#include +#include #include #include diff --git a/libsolidity/experimental/codegen/IRGenerator.cpp b/libsolidity/experimental/codegen/IRGenerator.cpp index 40deb38c397e..60a93bbf01d9 100644 --- a/libsolidity/experimental/codegen/IRGenerator.cpp +++ b/libsolidity/experimental/codegen/IRGenerator.cpp @@ -27,7 +27,6 @@ #include -#include #include #include #include diff --git a/libsolidity/experimental/codegen/IRGeneratorForStatements.cpp b/libsolidity/experimental/codegen/IRGeneratorForStatements.cpp index 6925a434d0a1..772e8575dbfd 100644 --- a/libsolidity/experimental/codegen/IRGeneratorForStatements.cpp +++ b/libsolidity/experimental/codegen/IRGeneratorForStatements.cpp @@ -25,9 +25,9 @@ #include -#include #include #include +#include #include #include From 372dab41c5dcf1087efa767f4b1ecd2ba3f2fb6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Wed, 25 Sep 2024 18:26:22 +0200 Subject: [PATCH 0450/1022] Store a reference to a Solidity source provider in YulStack --- libsolidity/interface/CompilerStack.cpp | 4 +++- libyul/YulStack.cpp | 16 +++++++++++----- libyul/YulStack.h | 11 ++++++++--- 3 files changed, 22 insertions(+), 9 deletions(-) diff --git a/libsolidity/interface/CompilerStack.cpp b/libsolidity/interface/CompilerStack.cpp index e538823f13ab..9848b6b59ce8 100644 --- a/libsolidity/interface/CompilerStack.cpp +++ b/libsolidity/interface/CompilerStack.cpp @@ -1522,6 +1522,7 @@ void CompilerStack::generateIR(ContractDefinition const& _contract, bool _unopti YulStack::Language::StrictAssembly, m_optimiserSettings, m_debugInfoSelection, + this, // _soliditySourceProvider m_objectOptimizer ); bool yulAnalysisSuccessful = stack.parseAndAnalyze("", compiledContract.yulIR); @@ -1537,7 +1538,7 @@ void CompilerStack::generateIR(ContractDefinition const& _contract, bool _unopti if (!_unoptimizedOnly) { stack.optimize(); - compiledContract.yulIROptimized = stack.print(this); + compiledContract.yulIROptimized = stack.print(); compiledContract.yulIROptimizedAst = stack.astJson(); } } @@ -1561,6 +1562,7 @@ void CompilerStack::generateEVMFromIR(ContractDefinition const& _contract) yul::YulStack::Language::StrictAssembly, m_optimiserSettings, m_debugInfoSelection, + this, // _soliditySourceProvider m_objectOptimizer ); bool analysisSuccessful = stack.parseAndAnalyze("", compiledContract.yulIROptimized); diff --git a/libyul/YulStack.cpp b/libyul/YulStack.cpp index 59766220cda5..f060a1e3339d 100644 --- a/libyul/YulStack.cpp +++ b/libyul/YulStack.cpp @@ -216,7 +216,15 @@ void YulStack::reparse() // are not stored in the AST and the other info that is (location, AST ID, etc) will still be present. std::string source = print(nullptr /* _soliditySourceProvider */); - YulStack cleanStack(m_evmVersion, m_eofVersion, m_language, m_optimiserSettings, m_debugInfoSelection, m_objectOptimizer); + YulStack cleanStack( + m_evmVersion, + m_eofVersion, + m_language, + m_optimiserSettings, + m_debugInfoSelection, + m_soliditySourceProvider, + m_objectOptimizer + ); bool reanalysisSuccessful = cleanStack.parseAndAnalyze(m_charStream->name(), source); yulAssert( reanalysisSuccessful, @@ -348,16 +356,14 @@ YulStack::assembleEVMWithDeployed(std::optional _deployName) return {std::make_shared(assembly), {}}; } -std::string YulStack::print( - CharStreamProvider const* _soliditySourceProvider -) const +std::string YulStack::print() const { yulAssert(m_stackState >= Parsed); yulAssert(m_parserResult, ""); yulAssert(m_parserResult->hasCode(), ""); return m_parserResult->toString( m_debugInfoSelection, - _soliditySourceProvider + m_soliditySourceProvider ) + "\n"; } diff --git a/libyul/YulStack.h b/libyul/YulStack.h index 0dc90baf890d..de391f591044 100644 --- a/libyul/YulStack.h +++ b/libyul/YulStack.h @@ -90,6 +90,7 @@ class YulStack: public langutil::CharStreamProvider Language _language, solidity::frontend::OptimiserSettings _optimiserSettings, langutil::DebugInfoSelection const& _debugInfoSelection, + langutil::CharStreamProvider const* _soliditySourceProvider = nullptr, std::shared_ptr _objectOptimizer = nullptr ): m_language(_language), @@ -97,6 +98,7 @@ class YulStack: public langutil::CharStreamProvider m_eofVersion(_eofVersion), m_optimiserSettings(std::move(_optimiserSettings)), m_debugInfoSelection(_debugInfoSelection), + m_soliditySourceProvider(_soliditySourceProvider), m_errorReporter(m_errors), m_objectOptimizer(_objectOptimizer ? std::move(_objectOptimizer) : std::make_shared()) {} @@ -137,9 +139,7 @@ class YulStack: public langutil::CharStreamProvider bool hasErrors() const { return m_errorReporter.hasErrors(); } /// Pretty-print the input after having parsed it. - std::string print( - langutil::CharStreamProvider const* _soliditySourceProvider = nullptr - ) const; + std::string print() const; Json astJson() const; // return the JSON representation of the YuL CFG (experimental) @@ -172,6 +172,11 @@ class YulStack: public langutil::CharStreamProvider solidity::frontend::OptimiserSettings m_optimiserSettings; langutil::DebugInfoSelection m_debugInfoSelection{}; + /// Provider of the Solidity sources that the Yul code was generated from. + /// Necessary when code snippets are requested as a part of debug info. When null, code snippets are omitted. + /// NOTE: Not owned by YulStack, the user must ensure that it is not destroyed before the stack is. + langutil::CharStreamProvider const* m_soliditySourceProvider{}; + std::unique_ptr m_charStream; State m_stackState = Empty; From 4216aa72df0ef1a6a1b9a20d72b6dd1b6078e931 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Wed, 25 Sep 2024 18:40:39 +0200 Subject: [PATCH 0451/1022] Fix shifted native source locations in Yul AST in presence of code snippets --- Changelog.md | 2 + libyul/YulStack.cpp | 8 +- test/cmdlineTests/ast_ir/output | 92 ++++++------ .../output.json | 142 +++++++++--------- 4 files changed, 123 insertions(+), 121 deletions(-) diff --git a/Changelog.md b/Changelog.md index 9f531daea171..45ec293a15fe 100644 --- a/Changelog.md +++ b/Changelog.md @@ -9,6 +9,8 @@ Compiler Features: Bugfixes: * SMTChecker: Fix SMT logic error when assigning to an array of addresses. + * Yul AST: Fix shifted native source locations when debug info selection included code snippets. + ### 0.8.27 (2024-09-04) diff --git a/libyul/YulStack.cpp b/libyul/YulStack.cpp index f060a1e3339d..67bc6d11a586 100644 --- a/libyul/YulStack.cpp +++ b/libyul/YulStack.cpp @@ -211,10 +211,10 @@ void YulStack::reparse() yulAssert(m_parserResult); yulAssert(m_charStream); - // NOTE: Without passing in _soliditySourceProvider, printed debug info will not include code - // snippets, but it does not matter - we'll still get the same AST after we parse it. Snippets - // are not stored in the AST and the other info that is (location, AST ID, etc) will still be present. - std::string source = print(nullptr /* _soliditySourceProvider */); + // NOTE: it is important for the source printed here to exactly match what the compiler will + // eventually output to the user. In particular, debug info must be exactly the same. + // Otherwise source locations will be off. + std::string source = print(); YulStack cleanStack( m_evmVersion, diff --git a/test/cmdlineTests/ast_ir/output b/test/cmdlineTests/ast_ir/output index 3211ef49b3bf..76f111990870 100644 --- a/test/cmdlineTests/ast_ir/output +++ b/test/cmdlineTests/ast_ir/output @@ -637,24 +637,24 @@ Optimized IR AST: { "code": { "block": { - "nativeSrc": "58:298:0", + "nativeSrc": "58:315:0", "nodeType": "YulBlock", "src": "-1:-1:0", "statements": [ { - "nativeSrc": "68:282:0", + "nativeSrc": "68:299:0", "nodeType": "YulBlock", "src": "-1:-1:0", "statements": [ { - "nativeSrc": "111:27:0", + "nativeSrc": "128:27:0", "nodeType": "YulVariableDeclaration", "src": "60:13:0", "value": { "arguments": [ { "kind": "number", - "nativeSrc": "133:4:0", + "nativeSrc": "150:4:0", "nodeType": "YulLiteral", "src": "60:13:0", "type": "", @@ -663,18 +663,18 @@ Optimized IR AST: ], "functionName": { "name": "memoryguard", - "nativeSrc": "121:11:0", + "nativeSrc": "138:11:0", "nodeType": "YulIdentifier", "src": "60:13:0" }, - "nativeSrc": "121:17:0", + "nativeSrc": "138:17:0", "nodeType": "YulFunctionCall", "src": "60:13:0" }, "variables": [ { "name": "_1", - "nativeSrc": "115:2:0", + "nativeSrc": "132:2:0", "nodeType": "YulTypedName", "src": "60:13:0", "type": "" @@ -686,7 +686,7 @@ Optimized IR AST: "arguments": [ { "kind": "number", - "nativeSrc": "158:2:0", + "nativeSrc": "175:2:0", "nodeType": "YulLiteral", "src": "60:13:0", "type": "", @@ -694,28 +694,28 @@ Optimized IR AST: }, { "name": "_1", - "nativeSrc": "162:2:0", + "nativeSrc": "179:2:0", "nodeType": "YulIdentifier", "src": "60:13:0" } ], "functionName": { "name": "mstore", - "nativeSrc": "151:6:0", + "nativeSrc": "168:6:0", "nodeType": "YulIdentifier", "src": "60:13:0" }, - "nativeSrc": "151:14:0", + "nativeSrc": "168:14:0", "nodeType": "YulFunctionCall", "src": "60:13:0" }, - "nativeSrc": "151:14:0", + "nativeSrc": "168:14:0", "nodeType": "YulExpressionStatement", "src": "60:13:0" }, { "body": { - "nativeSrc": "193:16:0", + "nativeSrc": "210:16:0", "nodeType": "YulBlock", "src": "60:13:0", "statements": [ @@ -724,7 +724,7 @@ Optimized IR AST: "arguments": [ { "kind": "number", - "nativeSrc": "202:1:0", + "nativeSrc": "219:1:0", "nodeType": "YulLiteral", "src": "60:13:0", "type": "", @@ -732,7 +732,7 @@ Optimized IR AST: }, { "kind": "number", - "nativeSrc": "205:1:0", + "nativeSrc": "222:1:0", "nodeType": "YulLiteral", "src": "60:13:0", "type": "", @@ -741,15 +741,15 @@ Optimized IR AST: ], "functionName": { "name": "revert", - "nativeSrc": "195:6:0", + "nativeSrc": "212:6:0", "nodeType": "YulIdentifier", "src": "60:13:0" }, - "nativeSrc": "195:12:0", + "nativeSrc": "212:12:0", "nodeType": "YulFunctionCall", "src": "60:13:0" }, - "nativeSrc": "195:12:0", + "nativeSrc": "212:12:0", "nodeType": "YulExpressionStatement", "src": "60:13:0" } @@ -759,20 +759,20 @@ Optimized IR AST: "arguments": [], "functionName": { "name": "callvalue", - "nativeSrc": "181:9:0", + "nativeSrc": "198:9:0", "nodeType": "YulIdentifier", "src": "60:13:0" }, - "nativeSrc": "181:11:0", + "nativeSrc": "198:11:0", "nodeType": "YulFunctionCall", "src": "60:13:0" }, - "nativeSrc": "178:31:0", + "nativeSrc": "195:31:0", "nodeType": "YulIf", "src": "60:13:0" }, { - "nativeSrc": "222:34:0", + "nativeSrc": "239:34:0", "nodeType": "YulVariableDeclaration", "src": "60:13:0", "value": { @@ -780,7 +780,7 @@ Optimized IR AST: { "hexValue": "435f325f6465706c6f796564", "kind": "string", - "nativeSrc": "241:14:0", + "nativeSrc": "258:14:0", "nodeType": "YulLiteral", "src": "60:13:0", "type": "", @@ -789,18 +789,18 @@ Optimized IR AST: ], "functionName": { "name": "datasize", - "nativeSrc": "232:8:0", + "nativeSrc": "249:8:0", "nodeType": "YulIdentifier", "src": "60:13:0" }, - "nativeSrc": "232:24:0", + "nativeSrc": "249:24:0", "nodeType": "YulFunctionCall", "src": "60:13:0" }, "variables": [ { "name": "_2", - "nativeSrc": "226:2:0", + "nativeSrc": "243:2:0", "nodeType": "YulTypedName", "src": "60:13:0", "type": "" @@ -812,7 +812,7 @@ Optimized IR AST: "arguments": [ { "name": "_1", - "nativeSrc": "278:2:0", + "nativeSrc": "295:2:0", "nodeType": "YulIdentifier", "src": "60:13:0" }, @@ -821,7 +821,7 @@ Optimized IR AST: { "hexValue": "435f325f6465706c6f796564", "kind": "string", - "nativeSrc": "293:14:0", + "nativeSrc": "310:14:0", "nodeType": "YulLiteral", "src": "60:13:0", "type": "", @@ -830,32 +830,32 @@ Optimized IR AST: ], "functionName": { "name": "dataoffset", - "nativeSrc": "282:10:0", + "nativeSrc": "299:10:0", "nodeType": "YulIdentifier", "src": "60:13:0" }, - "nativeSrc": "282:26:0", + "nativeSrc": "299:26:0", "nodeType": "YulFunctionCall", "src": "60:13:0" }, { "name": "_2", - "nativeSrc": "310:2:0", + "nativeSrc": "327:2:0", "nodeType": "YulIdentifier", "src": "60:13:0" } ], "functionName": { "name": "codecopy", - "nativeSrc": "269:8:0", + "nativeSrc": "286:8:0", "nodeType": "YulIdentifier", "src": "60:13:0" }, - "nativeSrc": "269:44:0", + "nativeSrc": "286:44:0", "nodeType": "YulFunctionCall", "src": "60:13:0" }, - "nativeSrc": "269:44:0", + "nativeSrc": "286:44:0", "nodeType": "YulExpressionStatement", "src": "60:13:0" }, @@ -864,28 +864,28 @@ Optimized IR AST: "arguments": [ { "name": "_1", - "nativeSrc": "333:2:0", + "nativeSrc": "350:2:0", "nodeType": "YulIdentifier", "src": "60:13:0" }, { "name": "_2", - "nativeSrc": "337:2:0", + "nativeSrc": "354:2:0", "nodeType": "YulIdentifier", "src": "60:13:0" } ], "functionName": { "name": "return", - "nativeSrc": "326:6:0", + "nativeSrc": "343:6:0", "nodeType": "YulIdentifier", "src": "60:13:0" }, - "nativeSrc": "326:14:0", + "nativeSrc": "343:14:0", "nodeType": "YulFunctionCall", "src": "60:13:0" }, - "nativeSrc": "326:14:0", + "nativeSrc": "343:14:0", "nodeType": "YulExpressionStatement", "src": "60:13:0" } @@ -901,12 +901,12 @@ Optimized IR AST: { "code": { "block": { - "nativeSrc": "436:101:0", + "nativeSrc": "453:118:0", "nodeType": "YulBlock", "src": "-1:-1:0", "statements": [ { - "nativeSrc": "450:77:0", + "nativeSrc": "467:94:0", "nodeType": "YulBlock", "src": "-1:-1:0", "statements": [ @@ -915,7 +915,7 @@ Optimized IR AST: "arguments": [ { "kind": "number", - "nativeSrc": "508:1:0", + "nativeSrc": "542:1:0", "nodeType": "YulLiteral", "src": "60:13:0", "type": "", @@ -923,7 +923,7 @@ Optimized IR AST: }, { "kind": "number", - "nativeSrc": "511:1:0", + "nativeSrc": "545:1:0", "nodeType": "YulLiteral", "src": "60:13:0", "type": "", @@ -932,15 +932,15 @@ Optimized IR AST: ], "functionName": { "name": "revert", - "nativeSrc": "501:6:0", + "nativeSrc": "535:6:0", "nodeType": "YulIdentifier", "src": "60:13:0" }, - "nativeSrc": "501:12:0", + "nativeSrc": "535:12:0", "nodeType": "YulFunctionCall", "src": "60:13:0" }, - "nativeSrc": "501:12:0", + "nativeSrc": "535:12:0", "nodeType": "YulExpressionStatement", "src": "60:13:0" } diff --git a/test/cmdlineTests/standard_irOptimized_ast_requested/output.json b/test/cmdlineTests/standard_irOptimized_ast_requested/output.json index f80f4466cad8..5c6762ac9907 100644 --- a/test/cmdlineTests/standard_irOptimized_ast_requested/output.json +++ b/test/cmdlineTests/standard_irOptimized_ast_requested/output.json @@ -5,12 +5,12 @@ "irOptimizedAst": { "code": { "block": { - "nativeSrc": "43:622:0", + "nativeSrc": "43:639:0", "nodeType": "YulBlock", "src": "-1:-1:0", "statements": [ { - "nativeSrc": "53:404:0", + "nativeSrc": "53:421:0", "nodeType": "YulBlock", "src": "-1:-1:0", "statements": [ @@ -19,7 +19,7 @@ "arguments": [ { "kind": "number", - "nativeSrc": "103:2:0", + "nativeSrc": "120:2:0", "nodeType": "YulLiteral", "src": "56:13:0", "type": "", @@ -29,7 +29,7 @@ "arguments": [ { "kind": "number", - "nativeSrc": "119:4:0", + "nativeSrc": "136:4:0", "nodeType": "YulLiteral", "src": "56:13:0", "type": "", @@ -38,32 +38,32 @@ ], "functionName": { "name": "memoryguard", - "nativeSrc": "107:11:0", + "nativeSrc": "124:11:0", "nodeType": "YulIdentifier", "src": "56:13:0" }, - "nativeSrc": "107:17:0", + "nativeSrc": "124:17:0", "nodeType": "YulFunctionCall", "src": "56:13:0" } ], "functionName": { "name": "mstore", - "nativeSrc": "96:6:0", + "nativeSrc": "113:6:0", "nodeType": "YulIdentifier", "src": "56:13:0" }, - "nativeSrc": "96:29:0", + "nativeSrc": "113:29:0", "nodeType": "YulFunctionCall", "src": "56:13:0" }, - "nativeSrc": "96:29:0", + "nativeSrc": "113:29:0", "nodeType": "YulExpressionStatement", "src": "56:13:0" }, { "body": { - "nativeSrc": "165:111:0", + "nativeSrc": "182:111:0", "nodeType": "YulBlock", "src": "56:13:0", "statements": [ @@ -72,15 +72,15 @@ "arguments": [], "functionName": { "name": "revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb", - "nativeSrc": "183:77:0", + "nativeSrc": "200:77:0", "nodeType": "YulIdentifier", "src": "56:13:0" }, - "nativeSrc": "183:79:0", + "nativeSrc": "200:79:0", "nodeType": "YulFunctionCall", "src": "56:13:0" }, - "nativeSrc": "183:79:0", + "nativeSrc": "200:79:0", "nodeType": "YulExpressionStatement", "src": "56:13:0" } @@ -90,38 +90,38 @@ "arguments": [], "functionName": { "name": "callvalue", - "nativeSrc": "141:9:0", + "nativeSrc": "158:9:0", "nodeType": "YulIdentifier", "src": "56:13:0" }, - "nativeSrc": "141:11:0", + "nativeSrc": "158:11:0", "nodeType": "YulFunctionCall", "src": "56:13:0" }, - "nativeSrc": "138:138:0", + "nativeSrc": "155:138:0", "nodeType": "YulIf", "src": "56:13:0" }, { - "nativeSrc": "289:30:0", + "nativeSrc": "306:30:0", "nodeType": "YulVariableDeclaration", "src": "56:13:0", "value": { "arguments": [], "functionName": { "name": "allocate_unbounded", - "nativeSrc": "299:18:0", + "nativeSrc": "316:18:0", "nodeType": "YulIdentifier", "src": "56:13:0" }, - "nativeSrc": "299:20:0", + "nativeSrc": "316:20:0", "nodeType": "YulFunctionCall", "src": "56:13:0" }, "variables": [ { "name": "_1", - "nativeSrc": "293:2:0", + "nativeSrc": "310:2:0", "nodeType": "YulTypedName", "src": "56:13:0", "type": "" @@ -133,7 +133,7 @@ "arguments": [ { "name": "_1", - "nativeSrc": "341:2:0", + "nativeSrc": "358:2:0", "nodeType": "YulIdentifier", "src": "56:13:0" }, @@ -142,7 +142,7 @@ { "hexValue": "435f325f6465706c6f796564", "kind": "string", - "nativeSrc": "356:14:0", + "nativeSrc": "373:14:0", "nodeType": "YulLiteral", "src": "56:13:0", "type": "", @@ -151,11 +151,11 @@ ], "functionName": { "name": "dataoffset", - "nativeSrc": "345:10:0", + "nativeSrc": "362:10:0", "nodeType": "YulIdentifier", "src": "56:13:0" }, - "nativeSrc": "345:26:0", + "nativeSrc": "362:26:0", "nodeType": "YulFunctionCall", "src": "56:13:0" }, @@ -164,7 +164,7 @@ { "hexValue": "435f325f6465706c6f796564", "kind": "string", - "nativeSrc": "382:14:0", + "nativeSrc": "399:14:0", "nodeType": "YulLiteral", "src": "56:13:0", "type": "", @@ -173,26 +173,26 @@ ], "functionName": { "name": "datasize", - "nativeSrc": "373:8:0", + "nativeSrc": "390:8:0", "nodeType": "YulIdentifier", "src": "56:13:0" }, - "nativeSrc": "373:24:0", + "nativeSrc": "390:24:0", "nodeType": "YulFunctionCall", "src": "56:13:0" } ], "functionName": { "name": "codecopy", - "nativeSrc": "332:8:0", + "nativeSrc": "349:8:0", "nodeType": "YulIdentifier", "src": "56:13:0" }, - "nativeSrc": "332:66:0", + "nativeSrc": "349:66:0", "nodeType": "YulFunctionCall", "src": "56:13:0" }, - "nativeSrc": "332:66:0", + "nativeSrc": "349:66:0", "nodeType": "YulExpressionStatement", "src": "56:13:0" }, @@ -201,7 +201,7 @@ "arguments": [ { "name": "_1", - "nativeSrc": "418:2:0", + "nativeSrc": "435:2:0", "nodeType": "YulIdentifier", "src": "56:13:0" }, @@ -210,7 +210,7 @@ { "hexValue": "435f325f6465706c6f796564", "kind": "string", - "nativeSrc": "431:14:0", + "nativeSrc": "448:14:0", "nodeType": "YulLiteral", "src": "56:13:0", "type": "", @@ -219,26 +219,26 @@ ], "functionName": { "name": "datasize", - "nativeSrc": "422:8:0", + "nativeSrc": "439:8:0", "nodeType": "YulIdentifier", "src": "56:13:0" }, - "nativeSrc": "422:24:0", + "nativeSrc": "439:24:0", "nodeType": "YulFunctionCall", "src": "56:13:0" } ], "functionName": { "name": "return", - "nativeSrc": "411:6:0", + "nativeSrc": "428:6:0", "nodeType": "YulIdentifier", "src": "56:13:0" }, - "nativeSrc": "411:36:0", + "nativeSrc": "428:36:0", "nodeType": "YulFunctionCall", "src": "56:13:0" }, - "nativeSrc": "411:36:0", + "nativeSrc": "428:36:0", "nodeType": "YulExpressionStatement", "src": "56:13:0" } @@ -246,19 +246,19 @@ }, { "body": { - "nativeSrc": "514:23:0", + "nativeSrc": "531:23:0", "nodeType": "YulBlock", "src": "56:13:0", "statements": [ { - "nativeSrc": "516:19:0", + "nativeSrc": "533:19:0", "nodeType": "YulAssignment", "src": "56:13:0", "value": { "arguments": [ { "kind": "number", - "nativeSrc": "532:2:0", + "nativeSrc": "549:2:0", "nodeType": "YulLiteral", "src": "56:13:0", "type": "", @@ -267,18 +267,18 @@ ], "functionName": { "name": "mload", - "nativeSrc": "526:5:0", + "nativeSrc": "543:5:0", "nodeType": "YulIdentifier", "src": "56:13:0" }, - "nativeSrc": "526:9:0", + "nativeSrc": "543:9:0", "nodeType": "YulFunctionCall", "src": "56:13:0" }, "variableNames": [ { "name": "memPtr", - "nativeSrc": "516:6:0", + "nativeSrc": "533:6:0", "nodeType": "YulIdentifier", "src": "56:13:0" } @@ -287,12 +287,12 @@ ] }, "name": "allocate_unbounded", - "nativeSrc": "466:71:0", + "nativeSrc": "483:71:0", "nodeType": "YulFunctionDefinition", "returnVariables": [ { "name": "memPtr", - "nativeSrc": "499:6:0", + "nativeSrc": "516:6:0", "nodeType": "YulTypedName", "src": "56:13:0", "type": "" @@ -302,7 +302,7 @@ }, { "body": { - "nativeSrc": "643:16:0", + "nativeSrc": "660:16:0", "nodeType": "YulBlock", "src": "56:13:0", "statements": [ @@ -311,7 +311,7 @@ "arguments": [ { "kind": "number", - "nativeSrc": "652:1:0", + "nativeSrc": "669:1:0", "nodeType": "YulLiteral", "src": "56:13:0", "type": "", @@ -319,7 +319,7 @@ }, { "kind": "number", - "nativeSrc": "655:1:0", + "nativeSrc": "672:1:0", "nodeType": "YulLiteral", "src": "56:13:0", "type": "", @@ -328,22 +328,22 @@ ], "functionName": { "name": "revert", - "nativeSrc": "645:6:0", + "nativeSrc": "662:6:0", "nodeType": "YulIdentifier", "src": "56:13:0" }, - "nativeSrc": "645:12:0", + "nativeSrc": "662:12:0", "nodeType": "YulFunctionCall", "src": "56:13:0" }, - "nativeSrc": "645:12:0", + "nativeSrc": "662:12:0", "nodeType": "YulExpressionStatement", "src": "56:13:0" } ] }, "name": "revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb", - "nativeSrc": "546:113:0", + "nativeSrc": "563:113:0", "nodeType": "YulFunctionDefinition", "src": "56:13:0" } @@ -357,12 +357,12 @@ { "code": { "block": { - "nativeSrc": "730:344:0", + "nativeSrc": "747:361:0", "nodeType": "YulBlock", "src": "-1:-1:0", "statements": [ { - "nativeSrc": "744:190:0", + "nativeSrc": "761:207:0", "nodeType": "YulBlock", "src": "-1:-1:0", "statements": [ @@ -371,7 +371,7 @@ "arguments": [ { "kind": "number", - "nativeSrc": "802:2:0", + "nativeSrc": "836:2:0", "nodeType": "YulLiteral", "src": "56:13:0", "type": "", @@ -381,7 +381,7 @@ "arguments": [ { "kind": "number", - "nativeSrc": "818:4:0", + "nativeSrc": "852:4:0", "nodeType": "YulLiteral", "src": "56:13:0", "type": "", @@ -390,26 +390,26 @@ ], "functionName": { "name": "memoryguard", - "nativeSrc": "806:11:0", + "nativeSrc": "840:11:0", "nodeType": "YulIdentifier", "src": "56:13:0" }, - "nativeSrc": "806:17:0", + "nativeSrc": "840:17:0", "nodeType": "YulFunctionCall", "src": "56:13:0" } ], "functionName": { "name": "mstore", - "nativeSrc": "795:6:0", + "nativeSrc": "829:6:0", "nodeType": "YulIdentifier", "src": "56:13:0" }, - "nativeSrc": "795:29:0", + "nativeSrc": "829:29:0", "nodeType": "YulFunctionCall", "src": "56:13:0" }, - "nativeSrc": "795:29:0", + "nativeSrc": "829:29:0", "nodeType": "YulExpressionStatement", "src": "56:13:0" }, @@ -418,15 +418,15 @@ "arguments": [], "functionName": { "name": "revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74", - "nativeSrc": "841:77:0", + "nativeSrc": "875:77:0", "nodeType": "YulIdentifier", "src": "56:13:0" }, - "nativeSrc": "841:79:0", + "nativeSrc": "875:79:0", "nodeType": "YulFunctionCall", "src": "56:13:0" }, - "nativeSrc": "841:79:0", + "nativeSrc": "875:79:0", "nodeType": "YulExpressionStatement", "src": "56:13:0" } @@ -434,7 +434,7 @@ }, { "body": { - "nativeSrc": "1048:16:0", + "nativeSrc": "1082:16:0", "nodeType": "YulBlock", "src": "56:13:0", "statements": [ @@ -443,7 +443,7 @@ "arguments": [ { "kind": "number", - "nativeSrc": "1057:1:0", + "nativeSrc": "1091:1:0", "nodeType": "YulLiteral", "src": "56:13:0", "type": "", @@ -451,7 +451,7 @@ }, { "kind": "number", - "nativeSrc": "1060:1:0", + "nativeSrc": "1094:1:0", "nodeType": "YulLiteral", "src": "56:13:0", "type": "", @@ -460,22 +460,22 @@ ], "functionName": { "name": "revert", - "nativeSrc": "1050:6:0", + "nativeSrc": "1084:6:0", "nodeType": "YulIdentifier", "src": "56:13:0" }, - "nativeSrc": "1050:12:0", + "nativeSrc": "1084:12:0", "nodeType": "YulFunctionCall", "src": "56:13:0" }, - "nativeSrc": "1050:12:0", + "nativeSrc": "1084:12:0", "nodeType": "YulExpressionStatement", "src": "56:13:0" } ] }, "name": "revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74", - "nativeSrc": "947:117:0", + "nativeSrc": "981:117:0", "nodeType": "YulFunctionDefinition", "src": "56:13:0" } From 578e1bb850a5a339ab7ada50022b8dd2388204cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Tue, 24 Sep 2024 14:53:45 +0200 Subject: [PATCH 0452/1022] CompilerStack: Helper for Yul parsing --- libsolidity/interface/CompilerStack.cpp | 52 ++++++++++++------------- libsolidity/interface/CompilerStack.h | 10 +++++ 2 files changed, 34 insertions(+), 28 deletions(-) diff --git a/libsolidity/interface/CompilerStack.cpp b/libsolidity/interface/CompilerStack.cpp index 9848b6b59ce8..deb748fbe7d8 100644 --- a/libsolidity/interface/CompilerStack.cpp +++ b/libsolidity/interface/CompilerStack.cpp @@ -782,6 +782,28 @@ void CompilerStack::link() } } +YulStack CompilerStack::loadGeneratedIR(std::string const& _ir) const +{ + YulStack stack( + m_evmVersion, + m_eofVersion, + YulStack::Language::StrictAssembly, + m_optimiserSettings, + m_debugInfoSelection, + this, // _soliditySourceProvider + m_objectOptimizer + ); + bool yulAnalysisSuccessful = stack.parseAndAnalyze("", _ir); + solAssert( + yulAnalysisSuccessful, + _ir + "\n\n" + "Invalid IR generated:\n" + + SourceReferenceFormatter::formatErrorInformation(stack.errors(), stack) + "\n" + ); + + return stack; +} + std::vector CompilerStack::contractNames() const { solAssert(m_stackState >= Parsed, "Parsing was not successful."); @@ -1516,23 +1538,7 @@ void CompilerStack::generateIR(ContractDefinition const& _contract, bool _unopti ); } - YulStack stack( - m_evmVersion, - m_eofVersion, - YulStack::Language::StrictAssembly, - m_optimiserSettings, - m_debugInfoSelection, - this, // _soliditySourceProvider - m_objectOptimizer - ); - bool yulAnalysisSuccessful = stack.parseAndAnalyze("", compiledContract.yulIR); - solAssert( - yulAnalysisSuccessful, - compiledContract.yulIR + "\n\n" - "Invalid IR generated:\n" + - SourceReferenceFormatter::formatErrorInformation(stack.errors(), stack) + "\n" - ); - + YulStack stack = loadGeneratedIR(compiledContract.yulIR); compiledContract.yulIRAst = stack.astJson(); compiledContract.yulCFGJson = stack.cfgJson(); if (!_unoptimizedOnly) @@ -1556,17 +1562,7 @@ void CompilerStack::generateEVMFromIR(ContractDefinition const& _contract) return; // Re-parse the Yul IR in EVM dialect - yul::YulStack stack( - m_evmVersion, - m_eofVersion, - yul::YulStack::Language::StrictAssembly, - m_optimiserSettings, - m_debugInfoSelection, - this, // _soliditySourceProvider - m_objectOptimizer - ); - bool analysisSuccessful = stack.parseAndAnalyze("", compiledContract.yulIROptimized); - solAssert(analysisSuccessful); + YulStack stack = loadGeneratedIR(compiledContract.yulIROptimized); //cout << yul::AsmPrinter{}(*stack.parserResult()->code) << endl; diff --git a/libsolidity/interface/CompilerStack.h b/libsolidity/interface/CompilerStack.h index 0a62cbf7efaf..885438475345 100644 --- a/libsolidity/interface/CompilerStack.h +++ b/libsolidity/interface/CompilerStack.h @@ -71,6 +71,11 @@ class AssemblyItem; using AssemblyItems = std::vector; } +namespace solidity::yul +{ +class YulStack; +} + namespace solidity::frontend { @@ -490,6 +495,11 @@ class CompilerStack: public langutil::CharStreamProvider, public evmasm::Abstrac /// library will still be kept as an unlinked placeholder in the objects. void link(); + /// Parses and analyzes specified Yul source and returns the YulStack that can be used to manipulate it. + /// Assumes that the IR was generated from sources loaded currently into CompilerStack, which + /// means that it is error-free and uses the same settings. + yul::YulStack loadGeneratedIR(std::string const& _ir) const; + /// @returns the contract object for the given @a _contractName. /// Can only be called after state is CompilationSuccessful. Contract const& contract(std::string const& _contractName) const; From 9ccc44a9bac77aa0c75944bd93d57a1ea66d5a23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Tue, 24 Sep 2024 15:19:02 +0200 Subject: [PATCH 0453/1022] CompilerStack: Yul AST generation only on demand - The JSON artifacts take a lot of memory so always generating them is very wasteful. - Even when requested, they are only relevant while the current contract is being copmiled. We only really want to store the serialized JSON that will be returned to the user. - This actually also speeds up compilation quite a bit. --- Changelog.md | 1 + libsolidity/interface/CompilerStack.cpp | 27 ++++++++++++++----------- libsolidity/interface/CompilerStack.h | 9 +++------ 3 files changed, 19 insertions(+), 18 deletions(-) diff --git a/Changelog.md b/Changelog.md index 45ec293a15fe..7d9af1cdbfcc 100644 --- a/Changelog.md +++ b/Changelog.md @@ -5,6 +5,7 @@ Language Features: Compiler Features: * Code Generator: Transient storage value type state variables are now supported by the legacy pipeline. + * General: Generate JSON representations of Yul ASTs only on demand to reduce memory usage. Bugfixes: diff --git a/libsolidity/interface/CompilerStack.cpp b/libsolidity/interface/CompilerStack.cpp index deb748fbe7d8..bac358a939f4 100644 --- a/libsolidity/interface/CompilerStack.cpp +++ b/libsolidity/interface/CompilerStack.cpp @@ -956,21 +956,24 @@ std::string const& CompilerStack::yulIR(std::string const& _contractName) const return contract(_contractName).yulIR; } -Json const& CompilerStack::yulIRAst(std::string const& _contractName) const +Json CompilerStack::yulIRAst(std::string const& _contractName) const { solAssert(m_stackState == CompilationSuccessful, "Compilation was not successful."); solUnimplementedAssert(!isExperimentalSolidity()); - return contract(_contractName).yulIRAst; + + // NOTE: Intentionally not using LazyInit. The artifact can get very large and we don't want to + // keep it around when compiling a large project containing many contracts. + return loadGeneratedIR(contract(_contractName).yulIR).astJson(); } -Json const& CompilerStack::yulCFGJson(std::string const& _contractName) const +Json CompilerStack::yulCFGJson(std::string const& _contractName) const { - if (m_stackState != CompilationSuccessful) - solThrow(CompilerError, "Compilation was not successful."); - + solAssert(m_stackState == CompilationSuccessful, "Compilation was not successful."); solUnimplementedAssert(!isExperimentalSolidity()); - return contract(_contractName).yulCFGJson; + // NOTE: Intentionally not using LazyInit. The artifact can get very large and we don't want to + // keep it around when compiling a large project containing many contracts. + return loadGeneratedIR(contract(_contractName).yulIR).cfgJson(); } std::string const& CompilerStack::yulIROptimized(std::string const& _contractName) const @@ -979,11 +982,14 @@ std::string const& CompilerStack::yulIROptimized(std::string const& _contractNam return contract(_contractName).yulIROptimized; } -Json const& CompilerStack::yulIROptimizedAst(std::string const& _contractName) const +Json CompilerStack::yulIROptimizedAst(std::string const& _contractName) const { solAssert(m_stackState == CompilationSuccessful, "Compilation was not successful."); solUnimplementedAssert(!isExperimentalSolidity()); - return contract(_contractName).yulIROptimizedAst; + + // NOTE: Intentionally not using LazyInit. The artifact can get very large and we don't want to + // keep it around when compiling a large project containing many contracts. + return loadGeneratedIR(contract(_contractName).yulIROptimized).astJson(); } evmasm::LinkerObject const& CompilerStack::object(std::string const& _contractName) const @@ -1539,13 +1545,10 @@ void CompilerStack::generateIR(ContractDefinition const& _contract, bool _unopti } YulStack stack = loadGeneratedIR(compiledContract.yulIR); - compiledContract.yulIRAst = stack.astJson(); - compiledContract.yulCFGJson = stack.cfgJson(); if (!_unoptimizedOnly) { stack.optimize(); compiledContract.yulIROptimized = stack.print(); - compiledContract.yulIROptimizedAst = stack.astJson(); } } diff --git a/libsolidity/interface/CompilerStack.h b/libsolidity/interface/CompilerStack.h index 885438475345..c0166af96d5b 100644 --- a/libsolidity/interface/CompilerStack.h +++ b/libsolidity/interface/CompilerStack.h @@ -295,15 +295,15 @@ class CompilerStack: public langutil::CharStreamProvider, public evmasm::Abstrac std::string const& yulIR(std::string const& _contractName) const; /// @returns the IR representation of a contract AST in format. - Json const& yulIRAst(std::string const& _contractName) const; + Json yulIRAst(std::string const& _contractName) const; /// @returns the optimized IR representation of a contract. std::string const& yulIROptimized(std::string const& _contractName) const; /// @returns the optimized IR representation of a contract AST in JSON format. - Json const& yulIROptimizedAst(std::string const& _contractName) const; + Json yulIROptimizedAst(std::string const& _contractName) const; - Json const& yulCFGJson(std::string const& _contractName) const; + Json yulCFGJson(std::string const& _contractName) const; /// @returns the assembled object for a contract. virtual evmasm::LinkerObject const& object(std::string const& _contractName) const override; @@ -416,9 +416,6 @@ class CompilerStack: public langutil::CharStreamProvider, public evmasm::Abstrac evmasm::LinkerObject runtimeObject; ///< Runtime object. std::string yulIR; ///< Yul IR code straight from the code generator. std::string yulIROptimized; ///< Reparsed and possibly optimized Yul IR code. - Json yulIRAst; ///< JSON AST of Yul IR code. - Json yulIROptimizedAst; ///< JSON AST of optimized Yul IR code. - Json yulCFGJson; ///< JSON CFG of Yul IR code. util::LazyInit metadata; ///< The metadata json that will be hashed into the chain. util::LazyInit abi; util::LazyInit storageLayout; From 5cbfd0d1985aab589c8501998a4459c79e42171d Mon Sep 17 00:00:00 2001 From: Nikola Matic Date: Mon, 22 Jul 2024 12:43:17 +0200 Subject: [PATCH 0454/1022] Via-IR code-gen for transient state variables Alternative approach Set variable declaration location explicitly --- libsolidity/codegen/ABIFunctions.cpp | 2 +- libsolidity/codegen/LValue.cpp | 2 +- libsolidity/codegen/YulUtilFunctions.cpp | 94 +++++++++++++------ libsolidity/codegen/YulUtilFunctions.h | 26 ++++- libsolidity/codegen/ir/IRGenerator.cpp | 15 +-- .../codegen/ir/IRGeneratorForStatements.cpp | 70 +++++++++++--- .../codegen/ir/IRGeneratorForStatements.h | 1 + libsolidity/codegen/ir/IRLValue.h | 6 +- 8 files changed, 153 insertions(+), 63 deletions(-) diff --git a/libsolidity/codegen/ABIFunctions.cpp b/libsolidity/codegen/ABIFunctions.cpp index bbcdb395b369..474848760cef 100644 --- a/libsolidity/codegen/ABIFunctions.cpp +++ b/libsolidity/codegen/ABIFunctions.cpp @@ -616,7 +616,7 @@ std::string ABIFunctions::abiEncodingFunctionSimpleArray( break; case DataLocation::Storage: if (_from.baseType()->isValueType()) - templ("arrayElementAccess", m_utils.readFromStorage(*_from.baseType(), 0, false) + "(srcPtr)"); + templ("arrayElementAccess", m_utils.readFromStorage(*_from.baseType(), 0, false, VariableDeclaration::Location::Unspecified) + "(srcPtr)"); else templ("arrayElementAccess", "srcPtr"); break; diff --git a/libsolidity/codegen/LValue.cpp b/libsolidity/codegen/LValue.cpp index 78efb9f811f3..a1537f01f4ad 100644 --- a/libsolidity/codegen/LValue.cpp +++ b/libsolidity/codegen/LValue.cpp @@ -401,7 +401,7 @@ void GenericStorageItem::storeValue(Type const& _sourceType, langut solAssert(sourceType.sizeOnStack() == 1, ""); solAssert(structType.sizeOnStack() == 1, ""); m_context << Instruction::DUP2 << Instruction::DUP2; - m_context.callYulFunction(m_context.utilFunctions().updateStorageValueFunction(sourceType, structType, 0), 2, 0); + m_context.callYulFunction(m_context.utilFunctions().updateStorageValueFunction(sourceType, structType, VariableDeclaration::Location::Unspecified, 0), 2, 0); } else { diff --git a/libsolidity/codegen/YulUtilFunctions.cpp b/libsolidity/codegen/YulUtilFunctions.cpp index ebf1d384aa57..fc6de832be27 100644 --- a/libsolidity/codegen/YulUtilFunctions.cpp +++ b/libsolidity/codegen/YulUtilFunctions.cpp @@ -1646,7 +1646,7 @@ std::string YulUtilFunctions::storageArrayPopFunction(ArrayType const& _type) ("indexAccess", storageArrayIndexAccessFunction(_type)) ( "setToZero", - _type.baseType()->category() != Type::Category::Mapping ? storageSetToZeroFunction(*_type.baseType()) : "" + _type.baseType()->category() != Type::Category::Mapping ? storageSetToZeroFunction(*_type.baseType(), VariableDeclaration::Location::Unspecified) : "" ) .render(); }); @@ -1691,7 +1691,7 @@ std::string YulUtilFunctions::storageByteArrayPopFunction(ArrayType const& _type ("transitLongToShort", byteArrayTransitLongToShortFunction(_type)) ("encodeUsedSetLen", shortByteArrayEncodeUsedAreaSetLengthFunction()) ("indexAccessNoChecks", longByteArrayStorageIndexAccessNoCheckFunction()) - ("setToZero", storageSetToZeroFunction(*_type.baseType())) + ("setToZero", storageSetToZeroFunction(*_type.baseType(), VariableDeclaration::Location::Unspecified)) .render(); }); } @@ -1760,7 +1760,7 @@ std::string YulUtilFunctions::storageArrayPushFunction(ArrayType const& _type, T ("dataAreaFunction", arrayDataAreaFunction(_type)) ("isByteArrayOrString", _type.isByteArrayOrString()) ("indexAccess", storageArrayIndexAccessFunction(_type)) - ("storeValue", updateStorageValueFunction(*_fromType, *_type.baseType())) + ("storeValue", updateStorageValueFunction(*_fromType, *_type.baseType(), VariableDeclaration::Location::Unspecified)) ("maxArrayLength", (u256(1) << 64).str()) ("shl", shiftLeftFunctionDynamic()) .render(); @@ -1834,7 +1834,7 @@ std::string YulUtilFunctions::clearStorageRangeFunction(Type const& _type) } )") ("functionName", functionName) - ("setToZero", storageSetToZeroFunction(_type.storageBytes() < 32 ? *TypeProvider::uint256() : _type)) + ("setToZero", storageSetToZeroFunction(_type.storageBytes() < 32 ? *TypeProvider::uint256() : _type, VariableDeclaration::Location::Unspecified)) ("increment", _type.storageSize().str()) .render(); }); @@ -1912,7 +1912,7 @@ std::string YulUtilFunctions::clearStorageStructFunction(StructType const& _type memberSetValues.emplace_back().emplace("clearMember", Whiskers(R"( (add(slot, ), ) )") - ("setZero", storageSetToZeroFunction(*member.type)) + ("setZero", storageSetToZeroFunction(*member.type, VariableDeclaration::Location::Unspecified)) ("memberSlotDiff", memberSlotDiff.str()) ("memberStorageOffset", std::to_string(memberStorageOffset)) .render() @@ -2015,7 +2015,7 @@ std::string YulUtilFunctions::copyArrayToStorageFunction(ArrayType const& _fromT 0, _fromType.baseType()->stackItems().size() )); - templ("updateStorageValue", updateStorageValueFunction(*_fromType.baseType(), *_toType.baseType(), 0)); + templ("updateStorageValue", updateStorageValueFunction(*_fromType.baseType(), *_toType.baseType(), VariableDeclaration::Location::Unspecified, 0)); templ("srcStride", fromCalldata ? std::to_string(_fromType.calldataStride()) : @@ -2746,21 +2746,33 @@ std::string YulUtilFunctions::mappingIndexAccessFunction(MappingType const& _map }); } -std::string YulUtilFunctions::readFromStorage(Type const& _type, size_t _offset, bool _splitFunctionTypes) +std::string YulUtilFunctions::readFromStorage( + Type const& _type, + size_t _offset, + bool _splitFunctionTypes, + VariableDeclaration::Location _location +) { if (_type.isValueType()) - return readFromStorageValueType(_type, _offset, _splitFunctionTypes); + return readFromStorageValueType(_type, _offset, _splitFunctionTypes, _location); else { + solAssert(_location != VariableDeclaration::Location::Transient); solAssert(_offset == 0, ""); return readFromStorageReferenceType(_type); } } -std::string YulUtilFunctions::readFromStorageDynamic(Type const& _type, bool _splitFunctionTypes) +std::string YulUtilFunctions::readFromStorageDynamic( + Type const& _type, + bool _splitFunctionTypes, + VariableDeclaration::Location _location +) { if (_type.isValueType()) - return readFromStorageValueType(_type, {}, _splitFunctionTypes); + return readFromStorageValueType(_type, {}, _splitFunctionTypes, _location); + + solAssert(_location != VariableDeclaration::Location::Transient); std::string functionName = "read_from_storage__dynamic_" + std::string(_splitFunctionTypes ? "split_" : "") + @@ -2780,24 +2792,36 @@ std::string YulUtilFunctions::readFromStorageDynamic(Type const& _type, bool _sp }); } -std::string YulUtilFunctions::readFromStorageValueType(Type const& _type, std::optional _offset, bool _splitFunctionTypes) +std::string YulUtilFunctions::readFromStorageValueType( + Type const& _type, + std::optional _offset, + bool _splitFunctionTypes, + VariableDeclaration::Location _location +) { solAssert(_type.isValueType(), ""); + solAssert( + _location == VariableDeclaration::Location::Transient || + _location == VariableDeclaration::Location::Unspecified, + "Variable location can only be transient or plain storage" + ); std::string functionName = - "read_from_storage_" + - std::string(_splitFunctionTypes ? "split_" : "") + ( - _offset.has_value() ? - "offset_" + std::to_string(*_offset) : - "dynamic" - ) + - "_" + - _type.identifier(); + "read_from_" + + (_location == VariableDeclaration::Location::Transient ? "transient_"s : "") + + "storage_" + + std::string(_splitFunctionTypes ? "split_" : "") + ( + _offset.has_value() ? + "offset_" + std::to_string(*_offset) : + "dynamic" + ) + + "_" + + _type.identifier(); return m_functionCollector.createFunction(functionName, [&] { Whiskers templ(R"( function (slot, offset) -> addr, selectorvalue { - let value := (sload(slot), offset) + let value := ((slot), offset) addr, selector := (value) @@ -2805,6 +2829,7 @@ std::string YulUtilFunctions::readFromStorageValueType(Type const& _type, std::o )"); templ("functionName", functionName); templ("dynamic", !_offset.has_value()); + templ("loadOpcode", _location == VariableDeclaration::Location::Transient ? "tload" : "sload"); if (_offset.has_value()) templ("extract", extractFromStorageValue(_type, *_offset)); else @@ -2850,7 +2875,7 @@ std::string YulUtilFunctions::readFromStorageReferenceType(Type const& _type) ("memberValues", suffixedVariableNameList("memberValue_", 0, structMembers[i].type->stackItems().size())) ("memberMemoryOffset", structType.memoryOffsetOfMember(structMembers[i].name).str()) ("memberSlotDiff", memberSlotDiff.str()) - ("readFromStorage", readFromStorage(*structMembers[i].type, memberStorageOffset, true)) + ("readFromStorage", readFromStorage(*structMembers[i].type, memberStorageOffset, true, VariableDeclaration::Location::Unspecified)) ("writeToMemory", writeToMemoryFunction(*structMembers[i].type)) .render(); } @@ -2884,11 +2909,20 @@ std::string YulUtilFunctions::readFromCalldata(Type const& _type) std::string YulUtilFunctions::updateStorageValueFunction( Type const& _fromType, Type const& _toType, + VariableDeclaration::Location _location, std::optional const& _offset ) { + solAssert( + _location == VariableDeclaration::Location::Transient || + _location == VariableDeclaration::Location::Unspecified, + "Variable location can only be transient or plain storage" + ); + std::string const functionName = - "update_storage_value_" + + "update_" + + (_location == VariableDeclaration::Location::Transient ? "transient_"s : "") + + "storage_value_" + (_offset.has_value() ? ("offset_" + std::to_string(*_offset)) : "") + _fromType.identifier() + "_to_" + @@ -2904,7 +2938,7 @@ std::string YulUtilFunctions::updateStorageValueFunction( return Whiskers(R"( function (slot, ) { let := () - sstore(slot, (sload(slot), ())) + (slot, ((slot), ())) } )") @@ -2918,10 +2952,13 @@ std::string YulUtilFunctions::updateStorageValueFunction( ("convert", conversionFunction(_fromType, _toType)) ("fromValues", suffixedVariableNameList("value_", 0, _fromType.sizeOnStack())) ("toValues", suffixedVariableNameList("convertedValue_", 0, _toType.sizeOnStack())) + ("storeOpcode", _location == VariableDeclaration::Location::Transient ? "tstore" : "sstore") + ("loadOpcode", _location == VariableDeclaration::Location::Transient ? "tload" : "sload") ("prepare", prepareStoreFunction(_toType)) .render(); } + solAssert(_location != VariableDeclaration::Location::Transient); auto const* toReferenceType = dynamic_cast(&_toType); auto const* fromReferenceType = dynamic_cast(&_fromType); solAssert(toReferenceType, ""); @@ -3553,7 +3590,7 @@ std::string YulUtilFunctions::conversionFunction(Type const& _from, Type const& body = Whiskers(R"( converted := (value) )") - ("readFromStorage", readFromStorage(toStructType, 0, true)) + ("readFromStorage", readFromStorage(toStructType, 0, true, VariableDeclaration::Location::Unspecified)) .render(); } } @@ -3683,7 +3720,7 @@ std::string YulUtilFunctions::bytesToFixedBytesConversionFunction(ArrayType cons templ( "extractValue", _from.dataStoredIn(DataLocation::Storage) ? - readFromStorage(_to, 32 - _to.numBytes(), false) : + readFromStorage(_to, 32 - _to.numBytes(), false, VariableDeclaration::Location::Unspecified) : readFromMemory(_to) ); templ("shl", shiftLeftFunctionDynamic()); @@ -3787,7 +3824,7 @@ std::string YulUtilFunctions::copyStructToStorageFunction(StructType const& _fro auto const& [srcSlotOffset, srcOffset] = _from.storageOffsetsOfMember(structMembers[i].name); t("memberOffset", formatNumber(srcSlotOffset)); if (memberType.isValueType()) - t("read", readFromStorageValueType(memberType, srcOffset, true)); + t("read", readFromStorageValueType(memberType, srcOffset, true, VariableDeclaration::Location::Unspecified)); else solAssert(srcOffset == 0, ""); @@ -3795,6 +3832,7 @@ std::string YulUtilFunctions::copyStructToStorageFunction(StructType const& _fro t("updateStorageValue", updateStorageValueFunction( memberType, *toStructMembers[i].type, + VariableDeclaration::Location::Unspecified, std::optional{offset} )); memberParams[i]["updateMemberCall"] = t.render(); @@ -4300,7 +4338,7 @@ std::string YulUtilFunctions::zeroValueFunction(Type const& _type, bool _splitFu }); } -std::string YulUtilFunctions::storageSetToZeroFunction(Type const& _type) +std::string YulUtilFunctions::storageSetToZeroFunction(Type const& _type, VariableDeclaration::Location _location) { std::string const functionName = "storage_set_to_zero_" + _type.identifier(); @@ -4313,7 +4351,7 @@ std::string YulUtilFunctions::storageSetToZeroFunction(Type const& _type) } )") ("functionName", functionName) - ("store", updateStorageValueFunction(_type, _type)) + ("store", updateStorageValueFunction(_type, _type, _location)) ("values", suffixedVariableNameList("zero_", 0, _type.sizeOnStack())) ("zeroValue", zeroValueFunction(_type)) .render(); diff --git a/libsolidity/codegen/YulUtilFunctions.h b/libsolidity/codegen/YulUtilFunctions.h index a1b45b656f13..6c06cdcc94e6 100644 --- a/libsolidity/codegen/YulUtilFunctions.h +++ b/libsolidity/codegen/YulUtilFunctions.h @@ -24,6 +24,7 @@ #include #include +#include #include #include @@ -349,8 +350,17 @@ class YulUtilFunctions /// @returns a function that reads a type from storage. /// @param _splitFunctionTypes if false, returns the address and function signature in a /// single variable. - std::string readFromStorage(Type const& _type, size_t _offset, bool _splitFunctionTypes); - std::string readFromStorageDynamic(Type const& _type, bool _splitFunctionTypes); + std::string readFromStorage( + Type const& _type, + size_t _offset, + bool _splitFunctionTypes, + VariableDeclaration::Location _location + ); + std::string readFromStorageDynamic( + Type const& _type, + bool _splitFunctionTypes, + VariableDeclaration::Location _location + ); /// @returns a function that reads a value type from memory. Performs cleanup. /// signature: (addr) -> value @@ -376,6 +386,7 @@ class YulUtilFunctions std::string updateStorageValueFunction( Type const& _fromType, Type const& _toType, + VariableDeclaration::Location _location, std::optional const& _offset = std::optional() ); @@ -496,7 +507,7 @@ class YulUtilFunctions /// @returns the name of a function that will set the given storage item to /// zero /// signature: (slot, offset) -> - std::string storageSetToZeroFunction(Type const& _type); + std::string storageSetToZeroFunction(Type const& _type, VariableDeclaration::Location _location); /// If revertStrings is debug, @returns the name of a function that /// stores @param _message in memory position 0 and reverts. @@ -573,8 +584,13 @@ class YulUtilFunctions /// @param _splitFunctionTypes if false, returns the address and function signature in a /// single variable. /// @param _offset if provided, read from static offset, otherwise offset is a parameter of the Yul function. - std::string readFromStorageValueType(Type const& _type, std::optional _offset, bool _splitFunctionTypes); - + /// @param _location if provided, indicates whether we're reading from storage our transient storage. + std::string readFromStorageValueType( + Type const& _type, + std::optional _offset, + bool _splitFunctionTypes, + VariableDeclaration::Location _location + ); /// @returns a function that reads a reference type from storage to memory (performing a deep copy). std::string readFromStorageReferenceType(Type const& _type); diff --git a/libsolidity/codegen/ir/IRGenerator.cpp b/libsolidity/codegen/ir/IRGenerator.cpp index a80fb4c27f33..44fc5a935a86 100644 --- a/libsolidity/codegen/ir/IRGenerator.cpp +++ b/libsolidity/codegen/ir/IRGenerator.cpp @@ -103,16 +103,6 @@ std::string IRGenerator::generate( std::map const& _otherYulSources ) { - auto notTransient = [](VariableDeclaration const* _varDeclaration) { - solAssert(_varDeclaration); - return _varDeclaration->referenceLocation() != VariableDeclaration::Location::Transient; - }; - - solUnimplementedAssert( - ranges::all_of(_contract.stateVariables(), notTransient), - "Transient storage variables are not supported when compiling via IR." - ); - auto subObjectSources = [&_otherYulSources](UniqueVector const& _subObjects) -> std::string { std::string subObjectsSources; @@ -674,7 +664,7 @@ std::string IRGenerator::generateGetter(VariableDeclaration const& _varDecl) := (add(slot, )) )") ("ret", joinHumanReadable(retVars)) - ("readStorage", m_utils.readFromStorage(*returnTypes[i], offsets.second, true)) + ("readStorage", m_utils.readFromStorage(*returnTypes[i], offsets.second, true, _varDecl.referenceLocation())) ("slotOffset", offsets.first.str()) .render(); } @@ -691,7 +681,7 @@ std::string IRGenerator::generateGetter(VariableDeclaration const& _varDecl) := (slot, offset) )") ("ret", joinHumanReadable(retVars)) - ("readStorage", m_utils.readFromStorageDynamic(*returnTypes.front(), true)) + ("readStorage", m_utils.readFromStorageDynamic(*returnTypes.front(), true, _varDecl.referenceLocation())) .render(); } @@ -834,7 +824,6 @@ std::string IRGenerator::initStateVariables(ContractDefinition const& _contract) IRGeneratorForStatements generator{m_context, m_utils, m_optimiserSettings}; for (VariableDeclaration const* variable: _contract.stateVariables()) { - solUnimplementedAssert(variable->referenceLocation() != VariableDeclaration::Location::Transient, "Transient storage variables not supported."); if (!variable->isConstant()) generator.initializeStateVar(*variable); } diff --git a/libsolidity/codegen/ir/IRGeneratorForStatements.cpp b/libsolidity/codegen/ir/IRGeneratorForStatements.cpp index c3cd69f43e22..283cc4b6b31a 100644 --- a/libsolidity/codegen/ir/IRGeneratorForStatements.cpp +++ b/libsolidity/codegen/ir/IRGeneratorForStatements.cpp @@ -271,6 +271,7 @@ void IRGeneratorForStatements::initializeStateVar(VariableDeclaration const& _va solAssert(!_varDecl.isConstant()); if (!_varDecl.value()) return; + solAssert(_varDecl.referenceLocation() != VariableDeclaration::Location::Transient, "State variables cannot be initialized in place."); _varDecl.value()->accept(*this); @@ -376,15 +377,6 @@ void IRGeneratorForStatements::endVisit(VariableDeclarationStatement const& _var { setLocation(_varDeclStatement); - auto static notTransient = [](std::shared_ptr const& _varDeclaration) { - return (_varDeclaration ? _varDeclaration->referenceLocation() != VariableDeclaration::Location::Transient : true); - }; - - solUnimplementedAssert( - ranges::all_of(_varDeclStatement.declarations(), notTransient), - "Transient storage variables are not supported." - ); - if (Expression const* expression = _varDeclStatement.initialValue()) { if (_varDeclStatement.declarations().size() > 1) @@ -727,7 +719,7 @@ bool IRGeneratorForStatements::visit(UnaryOperation const& _unaryOperation) util::GenericVisitor{ [&](IRLValue::Storage const& _storage) { appendCode() << - m_utils.storageSetToZeroFunction(m_currentLValue->type) << + m_utils.storageSetToZeroFunction(m_currentLValue->type, VariableDeclaration::Location::Unspecified) << "(" << _storage.slot << ", " << @@ -735,6 +727,16 @@ bool IRGeneratorForStatements::visit(UnaryOperation const& _unaryOperation) ")\n"; m_currentLValue.reset(); }, + [&](IRLValue::TransientStorage const& _transientStorage) { + appendCode() << + m_utils.storageSetToZeroFunction(m_currentLValue->type, VariableDeclaration::Location::Transient) << + "(" << + _transientStorage.slot << + ", " << + _transientStorage.offsetString() << + ")\n"; + m_currentLValue.reset(); + }, [&](auto const&) { IRVariable zeroValue(m_context.newYulVariable(), m_currentLValue->type); define(zeroValue) << m_utils.zeroValueFunction(m_currentLValue->type) << "()\n"; @@ -2558,6 +2560,14 @@ void IRGeneratorForStatements::handleVariableReference( *_variable.annotation().type, IRLValue::Stack{m_context.localVariable(_variable)} }); + else if (m_context.isStateVariable(_variable) && _variable.referenceLocation() == VariableDeclaration::Location::Transient) + setLValue(_referencingExpression, IRLValue{ + *_variable.annotation().type, + IRLValue::TransientStorage{ + toCompactHexWithPrefix(m_context.storageLocationOfStateVariable(_variable).first), + m_context.storageLocationOfStateVariable(_variable).second + } + }); else if (m_context.isStateVariable(_variable)) setLValue(_referencingExpression, IRLValue{ *_variable.annotation().type, @@ -3073,13 +3083,29 @@ void IRGeneratorForStatements::writeToLValue(IRLValue const& _lvalue, IRVariable }, _storage.offset); appendCode() << - m_utils.updateStorageValueFunction(_value.type(), _lvalue.type, offsetStatic) << + m_utils.updateStorageValueFunction(_value.type(), _lvalue.type, VariableDeclaration::Location::Unspecified, offsetStatic) << "(" << _storage.slot << offsetArgument << _value.commaSeparatedListPrefixed() << ")\n"; + }, + [&](IRLValue::TransientStorage const& _transientStorage) { + std::string offsetArgument; + std::optional offsetStatic; + std::visit(GenericVisitor{ + [&](unsigned _offset) { offsetStatic = _offset; }, + [&](std::string const& _offset) { offsetArgument = ", " + _offset; } + }, _transientStorage.offset); + + appendCode() << + m_utils.updateStorageValueFunction(_value.type(), _lvalue.type, VariableDeclaration::Location::Transient, offsetStatic) << + "(" << + _transientStorage.slot << + offsetArgument << + _value.commaSeparatedListPrefixed() << + ")\n"; }, [&](IRLValue::Memory const& _memory) { if (_lvalue.type.isValueType()) @@ -3158,7 +3184,7 @@ IRVariable IRGeneratorForStatements::readFromLValue(IRLValue const& _lvalue) define(result) << _storage.slot << "\n"; else if (std::holds_alternative(_storage.offset)) define(result) << - m_utils.readFromStorageDynamic(_lvalue.type, true) << + m_utils.readFromStorageDynamic(_lvalue.type, true, VariableDeclaration::Location::Unspecified) << "(" << _storage.slot << ", " << @@ -3166,11 +3192,29 @@ IRVariable IRGeneratorForStatements::readFromLValue(IRLValue const& _lvalue) ")\n"; else define(result) << - m_utils.readFromStorage(_lvalue.type, std::get(_storage.offset), true) << + m_utils.readFromStorage(_lvalue.type, std::get(_storage.offset), true, VariableDeclaration::Location::Unspecified) << "(" << _storage.slot << ")\n"; }, + [&](IRLValue::TransientStorage const& _transientStorage) { + if (!_lvalue.type.isValueType()) + define(result) << _transientStorage.slot << "\n"; + else if (std::holds_alternative(_transientStorage.offset)) + define(result) << + m_utils.readFromStorageDynamic(_lvalue.type, true, VariableDeclaration::Location::Transient) << + "(" << + _transientStorage.slot << + ", " << + std::get(_transientStorage.offset) << + ")\n"; + else + define(result) << + m_utils.readFromStorage(_lvalue.type, std::get(_transientStorage.offset), true, VariableDeclaration::Location::Transient) << + "(" << + _transientStorage.slot << + ")\n"; + }, [&](IRLValue::Memory const& _memory) { if (_lvalue.type.isValueType()) define(result) << diff --git a/libsolidity/codegen/ir/IRGeneratorForStatements.h b/libsolidity/codegen/ir/IRGeneratorForStatements.h index 15ef71f13844..9537b1f8fac6 100644 --- a/libsolidity/codegen/ir/IRGeneratorForStatements.h +++ b/libsolidity/codegen/ir/IRGeneratorForStatements.h @@ -228,6 +228,7 @@ class IRGeneratorForStatements: public IRGeneratorForStatementsBase /// Assigns the value of @a _value to the lvalue @a _lvalue. void writeToLValue(IRLValue const& _lvalue, IRVariable const& _value); + /// @returns a fresh IR variable containing the value of the lvalue @a _lvalue. IRVariable readFromLValue(IRLValue const& _lvalue); diff --git a/libsolidity/codegen/ir/IRLValue.h b/libsolidity/codegen/ir/IRLValue.h index fef390d4cb89..3f77cdda3b93 100644 --- a/libsolidity/codegen/ir/IRLValue.h +++ b/libsolidity/codegen/ir/IRLValue.h @@ -40,7 +40,7 @@ struct IRLValue { VariableDeclaration const* variable = nullptr; }; - struct Storage + struct GenericStorage { std::string const slot; /// unsigned: Used when the offset is known at compile time, uses optimized @@ -55,6 +55,8 @@ struct IRLValue return std::get(offset); } }; + struct Storage : public GenericStorage {}; + struct TransientStorage : public GenericStorage {}; struct Memory { std::string const address; @@ -64,7 +66,7 @@ struct IRLValue { std::vector> components; }; - std::variant kind; + std::variant kind; }; } From 0968a33d9c22f8fd673f7539f39ec2c5f925d9c8 Mon Sep 17 00:00:00 2001 From: Nikola Matic Date: Fri, 13 Sep 2024 15:55:49 +0200 Subject: [PATCH 0455/1022] Update old tests --- .../err | 1 - .../exit | 1 - .../output | 131 ++++++++++++++++++ .../getters/transient_value_types.sol | 1 - ...transient_value_types_multi_frame_call.sol | 1 - ...ansient_storage_access_inside_function.sol | 1 - .../compound_assign_transient_storage.sol | 1 - ...t_storage_variable_increment_decrement.sol | 1 - .../delete_transient_state_variable.sol | 1 - ...transient_function_type_state_variable.sol | 1 - ...ansient_state_address_variable_members.sol | 1 - .../transient_state_enum_variable.sol | 1 - .../variables/transient_state_variable.sol | 1 - ...ient_state_variable_cleanup_assignment.sol | 1 - ...ransient_state_variable_cleanup_tstore.sol | 1 - ...nt_state_variable_slot_inline_assembly.sol | 1 - ...nsient_state_variable_tuple_assignment.sol | 1 - .../transient_state_variable_udvt.sol | 1 - .../transient_storage_reentrancy_lock.sol | 1 - 19 files changed, 131 insertions(+), 18 deletions(-) delete mode 100644 test/cmdlineTests/evmasm_transient_storage_state_variable_via_ir/err delete mode 100644 test/cmdlineTests/evmasm_transient_storage_state_variable_via_ir/exit create mode 100644 test/cmdlineTests/evmasm_transient_storage_state_variable_via_ir/output diff --git a/test/cmdlineTests/evmasm_transient_storage_state_variable_via_ir/err b/test/cmdlineTests/evmasm_transient_storage_state_variable_via_ir/err deleted file mode 100644 index 2f81d6cd3d7f..000000000000 --- a/test/cmdlineTests/evmasm_transient_storage_state_variable_via_ir/err +++ /dev/null @@ -1 +0,0 @@ -Error: Transient storage variables are not supported when compiling via IR. diff --git a/test/cmdlineTests/evmasm_transient_storage_state_variable_via_ir/exit b/test/cmdlineTests/evmasm_transient_storage_state_variable_via_ir/exit deleted file mode 100644 index d00491fd7e5b..000000000000 --- a/test/cmdlineTests/evmasm_transient_storage_state_variable_via_ir/exit +++ /dev/null @@ -1 +0,0 @@ -1 diff --git a/test/cmdlineTests/evmasm_transient_storage_state_variable_via_ir/output b/test/cmdlineTests/evmasm_transient_storage_state_variable_via_ir/output new file mode 100644 index 000000000000..ec427fe3714e --- /dev/null +++ b/test/cmdlineTests/evmasm_transient_storage_state_variable_via_ir/output @@ -0,0 +1,131 @@ +Optimized IR: +/// @use-src 0:"evmasm_transient_storage_state_variable_via_ir/input.sol" +object "C_14" { + code { + { + mstore(64, memoryguard(0x80)) + if callvalue() + { + revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() + } + let _1 := allocate_unbounded() + codecopy(_1, dataoffset("C_14_deployed"), datasize("C_14_deployed")) + return(_1, datasize("C_14_deployed")) + } + function allocate_unbounded() -> memPtr + { memPtr := mload(64) } + function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() + { revert(0, 0) } + } + /// @use-src 0:"evmasm_transient_storage_state_variable_via_ir/input.sol" + object "C_14_deployed" { + code { + { + mstore(64, memoryguard(0x80)) + if iszero(lt(calldatasize(), 4)) + { + let selector := shift_right_unsigned(calldataload(0)) + switch selector + case 0x26121ff0 { external_fun_f() } + default { } + } + revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() + } + function shift_right_unsigned(value) -> newValue + { newValue := shr(224, value) } + function allocate_unbounded() -> memPtr + { memPtr := mload(64) } + function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() + { revert(0, 0) } + function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() + { revert(0, 0) } + function abi_decode(headStart, dataEnd) + { + if slt(sub(dataEnd, headStart), 0) + { + revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() + } + } + function abi_encode_tuple(headStart) -> tail + { tail := add(headStart, 0) } + function external_fun_f() + { + if callvalue() + { + revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() + } + abi_decode(4, calldatasize()) + fun_f() + let memPos := allocate_unbounded() + let memEnd := abi_encode_tuple(memPos) + return(memPos, sub(memEnd, memPos)) + } + function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() + { revert(0, 0) } + function shift_right_0_unsigned(value) -> newValue + { newValue := shr(0, value) } + function cleanup_from_storage_uint256(value) -> cleaned + { cleaned := value } + function extract_from_storage_value_offsett_uint256(slot_value) -> value + { + value := cleanup_from_storage_uint256(shift_right_0_unsigned(slot_value)) + } + function read_from_transient_storage_split_offset_uint256(slot) -> value + { + value := extract_from_storage_value_offsett_uint256(tload(slot)) + } + function cleanup_rational_by(value) -> cleaned + { cleaned := value } + function cleanup_uint256(value) -> cleaned + { cleaned := value } + function identity(value) -> ret + { ret := value } + function convert_rational_by_to_uint256(value) -> converted + { + converted := cleanup_uint256(identity(cleanup_rational_by(value))) + } + function panic_error_0x11() + { + mstore(0, shl(224, 0x4e487b71)) + mstore(4, 0x11) + revert(0, 0x24) + } + function checked_add_uint256(x, y) -> sum + { + x := cleanup_uint256(x) + y := cleanup_uint256(y) + sum := add(x, y) + if gt(x, sum) { panic_error_0x11() } + } + function shift_left(value) -> newValue + { newValue := shl(0, value) } + function update_byte_slice_shift(value, toInsert) -> result + { + let mask := not(0) + toInsert := shift_left(toInsert) + value := and(value, not(mask)) + result := or(value, and(toInsert, mask)) + } + function convert_uint256_to_uint256(value) -> converted + { + converted := cleanup_uint256(identity(cleanup_uint256(value))) + } + function prepare_store_uint256(value) -> ret + { ret := value } + function update_transient_storage_value_offsett_uint256_to_uint256(slot, value) + { + let convertedValue := convert_uint256_to_uint256(value) + tstore(slot, update_byte_slice_shift(tload(slot), prepare_store_uint256(convertedValue))) + } + function fun_f() + { + let _1 := read_from_transient_storage_split_offset_uint256(0x00) + let expr := _1 + let expr_1 := 0x01 + let expr_2 := checked_add_uint256(expr, convert_rational_by_to_uint256(expr_1)) + update_transient_storage_value_offsett_uint256_to_uint256(0x00, expr_2) + } + } + data ".metadata" hex"" + } +} diff --git a/test/libsolidity/semanticTests/getters/transient_value_types.sol b/test/libsolidity/semanticTests/getters/transient_value_types.sol index cc345cb91238..852e96baf25c 100644 --- a/test/libsolidity/semanticTests/getters/transient_value_types.sol +++ b/test/libsolidity/semanticTests/getters/transient_value_types.sol @@ -8,7 +8,6 @@ contract C { } // ==== // EVMVersion: >=cancun -// compileViaYul: false // ---- // x() -> 0 // f() -> -1 diff --git a/test/libsolidity/semanticTests/getters/transient_value_types_multi_frame_call.sol b/test/libsolidity/semanticTests/getters/transient_value_types_multi_frame_call.sol index 5e6b3f054313..912fca4fc4b0 100644 --- a/test/libsolidity/semanticTests/getters/transient_value_types_multi_frame_call.sol +++ b/test/libsolidity/semanticTests/getters/transient_value_types_multi_frame_call.sol @@ -15,7 +15,6 @@ contract C { } // ==== // EVMVersion: >=cancun -// compileViaYul: false // ---- // x() -> 0 // f() -> -2 diff --git a/test/libsolidity/semanticTests/inlineAssembly/inline_assembly_transient_storage_access_inside_function.sol b/test/libsolidity/semanticTests/inlineAssembly/inline_assembly_transient_storage_access_inside_function.sol index 86463473bd26..489f1a4ca7cc 100644 --- a/test/libsolidity/semanticTests/inlineAssembly/inline_assembly_transient_storage_access_inside_function.sol +++ b/test/libsolidity/semanticTests/inlineAssembly/inline_assembly_transient_storage_access_inside_function.sol @@ -18,6 +18,5 @@ contract C { } // ==== // EVMVersion: >=cancun -// compileViaYul: false // ---- // f() -> 7 diff --git a/test/libsolidity/semanticTests/operators/compound_assign_transient_storage.sol b/test/libsolidity/semanticTests/operators/compound_assign_transient_storage.sol index a20c8403ef06..c3adf3a1c411 100644 --- a/test/libsolidity/semanticTests/operators/compound_assign_transient_storage.sol +++ b/test/libsolidity/semanticTests/operators/compound_assign_transient_storage.sol @@ -11,7 +11,6 @@ contract test { } // ==== // EVMVersion: >=cancun -// compileViaYul: false // ---- // f(uint256,uint256): 0, 6 -> 7 // f(uint256,uint256): 1, 3 -> 11 diff --git a/test/libsolidity/semanticTests/operators/transient_storage_variable_increment_decrement.sol b/test/libsolidity/semanticTests/operators/transient_storage_variable_increment_decrement.sol index ac32eee1cdc9..889153014d1d 100644 --- a/test/libsolidity/semanticTests/operators/transient_storage_variable_increment_decrement.sol +++ b/test/libsolidity/semanticTests/operators/transient_storage_variable_increment_decrement.sol @@ -11,6 +11,5 @@ contract C { } // ==== // EVMVersion: >=cancun -// compileViaYul: false // ---- // f() -> 1 diff --git a/test/libsolidity/semanticTests/variables/delete_transient_state_variable.sol b/test/libsolidity/semanticTests/variables/delete_transient_state_variable.sol index 5f584fc8985b..868149ebc671 100644 --- a/test/libsolidity/semanticTests/variables/delete_transient_state_variable.sol +++ b/test/libsolidity/semanticTests/variables/delete_transient_state_variable.sol @@ -8,6 +8,5 @@ contract C { } // ==== // EVMVersion: >=cancun -// compileViaYul: false // ---- // f() -> 0 diff --git a/test/libsolidity/semanticTests/variables/transient_function_type_state_variable.sol b/test/libsolidity/semanticTests/variables/transient_function_type_state_variable.sol index 56a69649eeb0..eb9d00fa08be 100644 --- a/test/libsolidity/semanticTests/variables/transient_function_type_state_variable.sol +++ b/test/libsolidity/semanticTests/variables/transient_function_type_state_variable.sol @@ -12,6 +12,5 @@ contract C { } // ==== // EVMVersion: >=cancun -// compileViaYul: false // ---- // test() -> true diff --git a/test/libsolidity/semanticTests/variables/transient_state_address_variable_members.sol b/test/libsolidity/semanticTests/variables/transient_state_address_variable_members.sol index 6a388b3ee108..22cc5db05626 100644 --- a/test/libsolidity/semanticTests/variables/transient_state_address_variable_members.sol +++ b/test/libsolidity/semanticTests/variables/transient_state_address_variable_members.sol @@ -10,7 +10,6 @@ contract C { } // ==== // EVMVersion: >=cancun -// compileViaYul: false // ---- // constructor() -> // gas legacy: 59027 diff --git a/test/libsolidity/semanticTests/variables/transient_state_enum_variable.sol b/test/libsolidity/semanticTests/variables/transient_state_enum_variable.sol index a472212d401c..e260ebad629e 100644 --- a/test/libsolidity/semanticTests/variables/transient_state_enum_variable.sol +++ b/test/libsolidity/semanticTests/variables/transient_state_enum_variable.sol @@ -13,6 +13,5 @@ contract C { } // ==== // EVMVersion: >=cancun -// compileViaYul: false // ---- // f() -> diff --git a/test/libsolidity/semanticTests/variables/transient_state_variable.sol b/test/libsolidity/semanticTests/variables/transient_state_variable.sol index 71ed212d0bf4..03163982deef 100644 --- a/test/libsolidity/semanticTests/variables/transient_state_variable.sol +++ b/test/libsolidity/semanticTests/variables/transient_state_variable.sol @@ -15,7 +15,6 @@ contract C { } // ==== // EVMVersion: >=cancun -// compileViaYul: false // ---- // x() -> 0 // g() -> 8 diff --git a/test/libsolidity/semanticTests/variables/transient_state_variable_cleanup_assignment.sol b/test/libsolidity/semanticTests/variables/transient_state_variable_cleanup_assignment.sol index d1f0cc579713..a81572ec18d3 100644 --- a/test/libsolidity/semanticTests/variables/transient_state_variable_cleanup_assignment.sol +++ b/test/libsolidity/semanticTests/variables/transient_state_variable_cleanup_assignment.sol @@ -12,6 +12,5 @@ contract C { } // ==== // EVMVersion: >=cancun -// compileViaYul: false // ---- // f() -> 0xff diff --git a/test/libsolidity/semanticTests/variables/transient_state_variable_cleanup_tstore.sol b/test/libsolidity/semanticTests/variables/transient_state_variable_cleanup_tstore.sol index 425be55009bc..8f3be7ae537a 100644 --- a/test/libsolidity/semanticTests/variables/transient_state_variable_cleanup_tstore.sol +++ b/test/libsolidity/semanticTests/variables/transient_state_variable_cleanup_tstore.sol @@ -10,6 +10,5 @@ contract C { } // ==== // EVMVersion: >=cancun -// compileViaYul: false // ---- // f() -> 0xff diff --git a/test/libsolidity/semanticTests/variables/transient_state_variable_slot_inline_assembly.sol b/test/libsolidity/semanticTests/variables/transient_state_variable_slot_inline_assembly.sol index 6cf05068e3c3..0e7f29ed4239 100644 --- a/test/libsolidity/semanticTests/variables/transient_state_variable_slot_inline_assembly.sol +++ b/test/libsolidity/semanticTests/variables/transient_state_variable_slot_inline_assembly.sol @@ -25,7 +25,6 @@ contract C { } // ==== // EVMVersion: >=cancun -// compileViaYul: false // ---- // f() -> 0, 0 // g() -> 1, 0 diff --git a/test/libsolidity/semanticTests/variables/transient_state_variable_tuple_assignment.sol b/test/libsolidity/semanticTests/variables/transient_state_variable_tuple_assignment.sol index 1b5180635ce9..37912662115a 100644 --- a/test/libsolidity/semanticTests/variables/transient_state_variable_tuple_assignment.sol +++ b/test/libsolidity/semanticTests/variables/transient_state_variable_tuple_assignment.sol @@ -16,6 +16,5 @@ contract C { } // ==== // EVMVersion: >=cancun -// compileViaYul: false // ---- // f() -> 2, 3, 4 diff --git a/test/libsolidity/semanticTests/variables/transient_state_variable_udvt.sol b/test/libsolidity/semanticTests/variables/transient_state_variable_udvt.sol index 2f49a32b04b7..1829491f48a5 100644 --- a/test/libsolidity/semanticTests/variables/transient_state_variable_udvt.sol +++ b/test/libsolidity/semanticTests/variables/transient_state_variable_udvt.sol @@ -16,7 +16,6 @@ contract C { } // ==== // EVMVersion: >=cancun -// compileViaYul: false // ---- // x() -> 0 // g() -> 2 diff --git a/test/libsolidity/semanticTests/various/transient_storage_reentrancy_lock.sol b/test/libsolidity/semanticTests/various/transient_storage_reentrancy_lock.sol index aa3828601524..cc3a9d4a435e 100644 --- a/test/libsolidity/semanticTests/various/transient_storage_reentrancy_lock.sol +++ b/test/libsolidity/semanticTests/various/transient_storage_reentrancy_lock.sol @@ -18,7 +18,6 @@ contract C { } // ==== // EVMVersion: >=cancun -// compileViaYul: false // ---- // test(address,bool): 0x1234abcd, true -> FAILURE, hex"08c379a0", 0x20, 0x12, "Reentrancy attempt" // test(address,bool): 0x1234abcd, false -> From 8dfba6053f2a3d9640cd1452fff74aadf8b1b98b Mon Sep 17 00:00:00 2001 From: Nikola Matic Date: Mon, 16 Sep 2024 12:03:57 +0200 Subject: [PATCH 0456/1022] New tests --- .../args | 2 +- .../output | 45 +++-- .../args | 1 + .../err | 5 + .../input.sol | 11 ++ .../output | 36 ++++ .../args | 2 +- .../output | 184 +++++------------- .../args | 1 + .../input.sol | 9 + .../output | 41 ++++ ...ransient_state_variable_initialization.sol | 16 ++ .../transient_storage_state_variable.sol | 22 +++ ...orage_state_variable_abstract_contract.sol | 26 +++ .../transient_state_variable_value_type.sol | 17 ++ ...ansient_state_variable_non_zero_offset.sol | 14 ++ ...sient_state_variable_slots_and_offsets.sol | 20 ++ .../various/different_call_type_transient.sol | 51 +++++ .../transient_storage_value_type.sol | 15 ++ 19 files changed, 367 insertions(+), 151 deletions(-) create mode 100644 test/cmdlineTests/evmasm_transient_storage_inline_assembly_via_ir/args create mode 100644 test/cmdlineTests/evmasm_transient_storage_inline_assembly_via_ir/err create mode 100644 test/cmdlineTests/evmasm_transient_storage_inline_assembly_via_ir/input.sol create mode 100644 test/cmdlineTests/evmasm_transient_storage_inline_assembly_via_ir/output create mode 100644 test/cmdlineTests/ir_optimized_transient_storage_value_type/args create mode 100644 test/cmdlineTests/ir_optimized_transient_storage_value_type/input.sol create mode 100644 test/cmdlineTests/ir_optimized_transient_storage_value_type/output create mode 100644 test/libsolidity/semanticTests/constructor/transient_state_variable_initialization.sol create mode 100644 test/libsolidity/semanticTests/inheritance/transient_storage_state_variable.sol create mode 100644 test/libsolidity/semanticTests/inheritance/transient_storage_state_variable_abstract_contract.sol create mode 100644 test/libsolidity/semanticTests/modifiers/transient_state_variable_value_type.sol create mode 100644 test/libsolidity/semanticTests/variables/delete_transient_state_variable_non_zero_offset.sol create mode 100644 test/libsolidity/semanticTests/variables/transient_state_variable_slots_and_offsets.sol create mode 100644 test/libsolidity/semanticTests/various/different_call_type_transient.sol create mode 100644 test/libsolidity/syntaxTests/viewPureChecker/transient_storage_value_type.sol diff --git a/test/cmdlineTests/evmasm_transient_storage_inline_assembly/args b/test/cmdlineTests/evmasm_transient_storage_inline_assembly/args index 8430fd558f6d..b73ac2146d2a 100644 --- a/test/cmdlineTests/evmasm_transient_storage_inline_assembly/args +++ b/test/cmdlineTests/evmasm_transient_storage_inline_assembly/args @@ -1 +1 @@ ---no-cbor-metadata --via-ir --optimize --opcodes --asm --debug-info none +--no-cbor-metadata --optimize --opcodes --asm --debug-info none diff --git a/test/cmdlineTests/evmasm_transient_storage_inline_assembly/output b/test/cmdlineTests/evmasm_transient_storage_inline_assembly/output index 56dea1afb4c4..a02eca7d9239 100644 --- a/test/cmdlineTests/evmasm_transient_storage_inline_assembly/output +++ b/test/cmdlineTests/evmasm_transient_storage_inline_assembly/output @@ -1,36 +1,43 @@ ======= evmasm_transient_storage_inline_assembly/input.sol:C ======= EVM assembly: - 0x80 + mstore(0x40, 0x80) + callvalue dup1 - 0x40 - mstore - jumpi(tag_1, callvalue) + iszero + tag_1 + jumpi + revert(0x00, 0x00) +tag_1: + pop dataSize(sub_0) - swap1 - dup2 + dup1 dataOffset(sub_0) - dup3 + 0x00 codecopy - return -tag_1: 0x00 - dup1 - revert + return stop sub_0: assembly { - jumpi(tag_1, callvalue) - 0x00 + mstore(0x40, 0x80) + callvalue dup1 + iszero + tag_3 + jumpi + revert(0x00, 0x00) + tag_3: + pop + 0x00 + 0x00 tstore - sstore(0x00, tload(0x00)) - stop - tag_1: 0x00 - dup1 - revert + tload + 0x00 + sstore + stop } Opcodes: -PUSH1 0x80 DUP1 PUSH1 0x40 MSTORE CALLVALUE PUSH1 0x13 JUMPI PUSH1 0x10 SWAP1 DUP2 PUSH1 0x18 DUP3 CODECOPY RETURN JUMPDEST PUSH0 DUP1 REVERT INVALID CALLVALUE PUSH1 0xC JUMPI PUSH0 DUP1 TSTORE PUSH0 TLOAD PUSH0 SSTORE STOP JUMPDEST PUSH0 DUP1 REVERT +PUSH1 0x80 PUSH1 0x40 MSTORE CALLVALUE DUP1 ISZERO PUSH1 0xE JUMPI PUSH0 PUSH0 REVERT JUMPDEST POP PUSH1 0x18 DUP1 PUSH1 0x1A PUSH0 CODECOPY PUSH0 RETURN INVALID PUSH1 0x80 PUSH1 0x40 MSTORE CALLVALUE DUP1 ISZERO PUSH1 0xE JUMPI PUSH0 PUSH0 REVERT JUMPDEST POP PUSH0 PUSH0 TSTORE PUSH0 TLOAD PUSH0 SSTORE STOP diff --git a/test/cmdlineTests/evmasm_transient_storage_inline_assembly_via_ir/args b/test/cmdlineTests/evmasm_transient_storage_inline_assembly_via_ir/args new file mode 100644 index 000000000000..8430fd558f6d --- /dev/null +++ b/test/cmdlineTests/evmasm_transient_storage_inline_assembly_via_ir/args @@ -0,0 +1 @@ +--no-cbor-metadata --via-ir --optimize --opcodes --asm --debug-info none diff --git a/test/cmdlineTests/evmasm_transient_storage_inline_assembly_via_ir/err b/test/cmdlineTests/evmasm_transient_storage_inline_assembly_via_ir/err new file mode 100644 index 000000000000..b1ccd751c9fd --- /dev/null +++ b/test/cmdlineTests/evmasm_transient_storage_inline_assembly_via_ir/err @@ -0,0 +1,5 @@ +Warning: Transient storage as defined by EIP-1153 can break the composability of smart contracts: Since transient storage is cleared only at the end of the transaction and not at the end of the outermost call frame to the contract within a transaction, your contract may unintentionally misbehave when invoked multiple times in a complex transaction. To avoid this, be sure to clear all transient storage at the end of any call to your contract. The use of transient storage for reentrancy guards that are cleared at the end of the call is safe. + --> evmasm_transient_storage_inline_assembly_via_ir/input.sol:7:13: + | +7 | tstore(0, 0) + | ^^^^^^ diff --git a/test/cmdlineTests/evmasm_transient_storage_inline_assembly_via_ir/input.sol b/test/cmdlineTests/evmasm_transient_storage_inline_assembly_via_ir/input.sol new file mode 100644 index 000000000000..94914ac4eef7 --- /dev/null +++ b/test/cmdlineTests/evmasm_transient_storage_inline_assembly_via_ir/input.sol @@ -0,0 +1,11 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity >=0.0.0; + +contract C { + fallback() external { + assembly { + tstore(0, 0) + sstore(0, tload(0)) + } + } +} diff --git a/test/cmdlineTests/evmasm_transient_storage_inline_assembly_via_ir/output b/test/cmdlineTests/evmasm_transient_storage_inline_assembly_via_ir/output new file mode 100644 index 000000000000..62bf1f456ab8 --- /dev/null +++ b/test/cmdlineTests/evmasm_transient_storage_inline_assembly_via_ir/output @@ -0,0 +1,36 @@ + +======= evmasm_transient_storage_inline_assembly_via_ir/input.sol:C ======= +EVM assembly: + 0x80 + dup1 + 0x40 + mstore + jumpi(tag_1, callvalue) + dataSize(sub_0) + swap1 + dup2 + dataOffset(sub_0) + dup3 + codecopy + return +tag_1: + 0x00 + dup1 + revert +stop + +sub_0: assembly { + jumpi(tag_1, callvalue) + 0x00 + dup1 + tstore + sstore(0x00, tload(0x00)) + stop + tag_1: + 0x00 + dup1 + revert +} + +Opcodes: +PUSH1 0x80 DUP1 PUSH1 0x40 MSTORE CALLVALUE PUSH1 0x13 JUMPI PUSH1 0x10 SWAP1 DUP2 PUSH1 0x18 DUP3 CODECOPY RETURN JUMPDEST PUSH0 DUP1 REVERT INVALID CALLVALUE PUSH1 0xC JUMPI PUSH0 DUP1 TSTORE PUSH0 TLOAD PUSH0 SSTORE STOP JUMPDEST PUSH0 DUP1 REVERT diff --git a/test/cmdlineTests/evmasm_transient_storage_state_variable_via_ir/args b/test/cmdlineTests/evmasm_transient_storage_state_variable_via_ir/args index 00dcc37773e8..e233e0855a41 100644 --- a/test/cmdlineTests/evmasm_transient_storage_state_variable_via_ir/args +++ b/test/cmdlineTests/evmasm_transient_storage_state_variable_via_ir/args @@ -1 +1 @@ ---no-cbor-metadata --ir-optimized --debug-info none \ No newline at end of file +--no-cbor-metadata --via-ir --optimize --asm --debug-info none \ No newline at end of file diff --git a/test/cmdlineTests/evmasm_transient_storage_state_variable_via_ir/output b/test/cmdlineTests/evmasm_transient_storage_state_variable_via_ir/output index ec427fe3714e..5959fad952f1 100644 --- a/test/cmdlineTests/evmasm_transient_storage_state_variable_via_ir/output +++ b/test/cmdlineTests/evmasm_transient_storage_state_variable_via_ir/output @@ -1,131 +1,55 @@ -Optimized IR: -/// @use-src 0:"evmasm_transient_storage_state_variable_via_ir/input.sol" -object "C_14" { - code { - { - mstore(64, memoryguard(0x80)) - if callvalue() - { - revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() - } - let _1 := allocate_unbounded() - codecopy(_1, dataoffset("C_14_deployed"), datasize("C_14_deployed")) - return(_1, datasize("C_14_deployed")) - } - function allocate_unbounded() -> memPtr - { memPtr := mload(64) } - function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() - { revert(0, 0) } - } - /// @use-src 0:"evmasm_transient_storage_state_variable_via_ir/input.sol" - object "C_14_deployed" { - code { - { - mstore(64, memoryguard(0x80)) - if iszero(lt(calldatasize(), 4)) - { - let selector := shift_right_unsigned(calldataload(0)) - switch selector - case 0x26121ff0 { external_fun_f() } - default { } - } - revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() - } - function shift_right_unsigned(value) -> newValue - { newValue := shr(224, value) } - function allocate_unbounded() -> memPtr - { memPtr := mload(64) } - function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() - { revert(0, 0) } - function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() - { revert(0, 0) } - function abi_decode(headStart, dataEnd) - { - if slt(sub(dataEnd, headStart), 0) - { - revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() - } - } - function abi_encode_tuple(headStart) -> tail - { tail := add(headStart, 0) } - function external_fun_f() - { - if callvalue() - { - revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() - } - abi_decode(4, calldatasize()) - fun_f() - let memPos := allocate_unbounded() - let memEnd := abi_encode_tuple(memPos) - return(memPos, sub(memEnd, memPos)) - } - function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() - { revert(0, 0) } - function shift_right_0_unsigned(value) -> newValue - { newValue := shr(0, value) } - function cleanup_from_storage_uint256(value) -> cleaned - { cleaned := value } - function extract_from_storage_value_offsett_uint256(slot_value) -> value - { - value := cleanup_from_storage_uint256(shift_right_0_unsigned(slot_value)) - } - function read_from_transient_storage_split_offset_uint256(slot) -> value - { - value := extract_from_storage_value_offsett_uint256(tload(slot)) - } - function cleanup_rational_by(value) -> cleaned - { cleaned := value } - function cleanup_uint256(value) -> cleaned - { cleaned := value } - function identity(value) -> ret - { ret := value } - function convert_rational_by_to_uint256(value) -> converted - { - converted := cleanup_uint256(identity(cleanup_rational_by(value))) - } - function panic_error_0x11() - { - mstore(0, shl(224, 0x4e487b71)) - mstore(4, 0x11) - revert(0, 0x24) - } - function checked_add_uint256(x, y) -> sum - { - x := cleanup_uint256(x) - y := cleanup_uint256(y) - sum := add(x, y) - if gt(x, sum) { panic_error_0x11() } - } - function shift_left(value) -> newValue - { newValue := shl(0, value) } - function update_byte_slice_shift(value, toInsert) -> result - { - let mask := not(0) - toInsert := shift_left(toInsert) - value := and(value, not(mask)) - result := or(value, and(toInsert, mask)) - } - function convert_uint256_to_uint256(value) -> converted - { - converted := cleanup_uint256(identity(cleanup_uint256(value))) - } - function prepare_store_uint256(value) -> ret - { ret := value } - function update_transient_storage_value_offsett_uint256_to_uint256(slot, value) - { - let convertedValue := convert_uint256_to_uint256(value) - tstore(slot, update_byte_slice_shift(tload(slot), prepare_store_uint256(convertedValue))) - } - function fun_f() - { - let _1 := read_from_transient_storage_split_offset_uint256(0x00) - let expr := _1 - let expr_1 := 0x01 - let expr_2 := checked_add_uint256(expr, convert_rational_by_to_uint256(expr_1)) - update_transient_storage_value_offsett_uint256_to_uint256(0x00, expr_2) - } - } - data ".metadata" hex"" - } + +======= evmasm_transient_storage_state_variable_via_ir/input.sol:C ======= +EVM assembly: + 0x80 + dup1 + 0x40 + mstore + jumpi(tag_1, callvalue) + dataSize(sub_0) + swap1 + dup2 + dataOffset(sub_0) + dup3 + codecopy + return +tag_1: + 0x00 + dup1 + revert +stop + +sub_0: assembly { + jumpi(tag_1, iszero(lt(calldatasize, 0x04))) + 0x00 + dup1 + revert + tag_1: + jumpi(tag_3, eq(0x26121ff0, shr(0xe0, calldataload(0x00)))) + 0x00 + dup1 + revert + tag_3: + jumpi(tag_7, callvalue) + jumpi(tag_7, slt(add(not(0x03), calldatasize), 0x00)) + tload(0x00) + 0x01 + dup2 + add + dup1 + swap2 + gt + tag_9 + jumpi + 0x00 + tstore + stop + tag_9: + mstore(0x00, shl(0xe0, 0x4e487b71)) + mstore(0x04, 0x11) + revert(0x00, 0x24) + tag_7: + 0x00 + dup1 + revert } diff --git a/test/cmdlineTests/ir_optimized_transient_storage_value_type/args b/test/cmdlineTests/ir_optimized_transient_storage_value_type/args new file mode 100644 index 000000000000..20e22da1aeb5 --- /dev/null +++ b/test/cmdlineTests/ir_optimized_transient_storage_value_type/args @@ -0,0 +1 @@ +--via-ir --no-cbor-metadata --ir-optimized --optimize --debug-info none diff --git a/test/cmdlineTests/ir_optimized_transient_storage_value_type/input.sol b/test/cmdlineTests/ir_optimized_transient_storage_value_type/input.sol new file mode 100644 index 000000000000..7177bdb64fd5 --- /dev/null +++ b/test/cmdlineTests/ir_optimized_transient_storage_value_type/input.sol @@ -0,0 +1,9 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity >=0.0.0; + +contract C { + uint transient x; + function f() public { + x = x + 1; + } +} diff --git a/test/cmdlineTests/ir_optimized_transient_storage_value_type/output b/test/cmdlineTests/ir_optimized_transient_storage_value_type/output new file mode 100644 index 000000000000..61d289e3f9e0 --- /dev/null +++ b/test/cmdlineTests/ir_optimized_transient_storage_value_type/output @@ -0,0 +1,41 @@ +Optimized IR: +/// @use-src 0:"ir_optimized_transient_storage_value_type/input.sol" +object "C_14" { + code { + { + let _1 := memoryguard(0x80) + mstore(64, _1) + if callvalue() { revert(0, 0) } + let _2 := datasize("C_14_deployed") + codecopy(_1, dataoffset("C_14_deployed"), _2) + return(_1, _2) + } + } + /// @use-src 0:"ir_optimized_transient_storage_value_type/input.sol" + object "C_14_deployed" { + code { + { + if iszero(lt(calldatasize(), 4)) + { + if eq(0x26121ff0, shr(224, calldataload(0))) + { + if callvalue() { revert(0, 0) } + if slt(add(calldatasize(), not(3)), 0) { revert(0, 0) } + let _1 := tload(0) + let sum := add(_1, 0x01) + if gt(_1, sum) + { + mstore(0, shl(224, 0x4e487b71)) + mstore(4, 0x11) + revert(0, 0x24) + } + tstore(0, sum) + return(0, 0) + } + } + revert(0, 0) + } + } + data ".metadata" hex"" + } +} diff --git a/test/libsolidity/semanticTests/constructor/transient_state_variable_initialization.sol b/test/libsolidity/semanticTests/constructor/transient_state_variable_initialization.sol new file mode 100644 index 000000000000..4c69b58f8307 --- /dev/null +++ b/test/libsolidity/semanticTests/constructor/transient_state_variable_initialization.sol @@ -0,0 +1,16 @@ +contract C { + uint256 transient x; + + constructor() { + x = 100; + } + + function f() external view returns (uint256 x) { + x; + } +} + +// ==== +// EVMVersion: >=cancun +// ---- +// f() -> 0 diff --git a/test/libsolidity/semanticTests/inheritance/transient_storage_state_variable.sol b/test/libsolidity/semanticTests/inheritance/transient_storage_state_variable.sol new file mode 100644 index 000000000000..56c686f825ea --- /dev/null +++ b/test/libsolidity/semanticTests/inheritance/transient_storage_state_variable.sol @@ -0,0 +1,22 @@ +contract A { + uint transient x; + int y; +} + +contract C is A { + uint w; + int transient z; + + function f() public returns (uint, int, uint, int) { + x += 1; + y += 2; + w += 3; + z += 4; + + return (x, y, w, z); + } +} +// ==== +// EVMVersion: >=cancun +// ---- +// f() -> 1, 2, 3, 4 diff --git a/test/libsolidity/semanticTests/inheritance/transient_storage_state_variable_abstract_contract.sol b/test/libsolidity/semanticTests/inheritance/transient_storage_state_variable_abstract_contract.sol new file mode 100644 index 000000000000..5db209f16141 --- /dev/null +++ b/test/libsolidity/semanticTests/inheritance/transient_storage_state_variable_abstract_contract.sol @@ -0,0 +1,26 @@ +abstract contract A { + uint transient x; + int y; + function f() public virtual returns (uint, int, uint, int); +} + +contract C is A { + uint w; + int transient z; + + function g() public { + w += 2; + z += 2; + } + + function f() public override returns (uint, int, uint, int) { + x += 1; + y += 1; + g(); + return (x, y, w, z); + } +} +// ==== +// EVMVersion: >=cancun +// ---- +// f() -> 1, 1, 2, 2 diff --git a/test/libsolidity/semanticTests/modifiers/transient_state_variable_value_type.sol b/test/libsolidity/semanticTests/modifiers/transient_state_variable_value_type.sol new file mode 100644 index 000000000000..4c60ee1a891c --- /dev/null +++ b/test/libsolidity/semanticTests/modifiers/transient_state_variable_value_type.sol @@ -0,0 +1,17 @@ +contract C { + uint16 transient x; + + modifier m(uint16) { + x += 10; + _; + } + + function f() public m(x) returns (uint16 x) { + x *= 10; + } +} + +// ==== +// EVMVersion: >=cancun +// ---- +// f() -> 0 diff --git a/test/libsolidity/semanticTests/variables/delete_transient_state_variable_non_zero_offset.sol b/test/libsolidity/semanticTests/variables/delete_transient_state_variable_non_zero_offset.sol new file mode 100644 index 000000000000..45860599e641 --- /dev/null +++ b/test/libsolidity/semanticTests/variables/delete_transient_state_variable_non_zero_offset.sol @@ -0,0 +1,14 @@ +contract C { + uint128 transient x; + uint128 transient y; + + function f() public returns (uint) { + y = 10; + delete y; + return y; + } +} +// ==== +// EVMVersion: >=cancun +// ---- +// f() -> 0 diff --git a/test/libsolidity/semanticTests/variables/transient_state_variable_slots_and_offsets.sol b/test/libsolidity/semanticTests/variables/transient_state_variable_slots_and_offsets.sol new file mode 100644 index 000000000000..63f23e1857fe --- /dev/null +++ b/test/libsolidity/semanticTests/variables/transient_state_variable_slots_and_offsets.sol @@ -0,0 +1,20 @@ +contract C { + uint128 transient x; + uint64 transient y; + uint64 transient w; + uint256 transient z; + + function f() external returns (uint128, uint64, uint64, uint256) { + x = 1; + y = 2; + w = 3; + z = 4; + + return (x, y, w, z); + } +} + +// ==== +// EVMVersion: >=cancun +// ---- +// f() -> 1, 2, 3, 4 diff --git a/test/libsolidity/semanticTests/various/different_call_type_transient.sol b/test/libsolidity/semanticTests/various/different_call_type_transient.sol new file mode 100644 index 000000000000..b71e8b25253a --- /dev/null +++ b/test/libsolidity/semanticTests/various/different_call_type_transient.sol @@ -0,0 +1,51 @@ +contract B { + uint256 transient public value; + + function setValue(uint256 v) public { + value += v; + } +} + +contract A { + uint256 transient public value; + + function delegateSetValue(address otherContract, uint256 v) public { + (bool success, ) = otherContract.delegatecall(abi.encodeWithSignature("setValue(uint256)", v)); + require(success); + } + function callSetValue(address otherContract, uint256 v) public { + (bool success, ) = otherContract.call(abi.encodeWithSignature("setValue(uint256)", v)); + require(success); + } + function staticSetValue(address otherContract, uint256 v) view public returns (bool) { + (bool success, ) = otherContract.staticcall(abi.encodeWithSignature("setValue(uint256)", v)); + return success; + } +} + +contract Test { + A a = new A(); + B b = new B(); + + function testDelegate() public returns (uint256, uint256) { + a.delegateSetValue(address(b), 7); + return (a.value(), b.value()); + } + function testCall() public returns (uint256, uint256) { + a.callSetValue(address(b), 8); + return (a.value(), b.value()); + } + function testStatic() view public returns (bool) { + return a.staticSetValue(address(b), 0); + } +} + +// ==== +// EVMVersion: >=cancun +// ---- +// testDelegate() -> 7, 0 +// testCall() -> 0, 8 +// testStatic() -> false +// gas irOptimized: 96900694 +// gas legacy: 96901136 +// gas legacyOptimized: 96900725 diff --git a/test/libsolidity/syntaxTests/viewPureChecker/transient_storage_value_type.sol b/test/libsolidity/syntaxTests/viewPureChecker/transient_storage_value_type.sol new file mode 100644 index 000000000000..9c48f17f1350 --- /dev/null +++ b/test/libsolidity/syntaxTests/viewPureChecker/transient_storage_value_type.sol @@ -0,0 +1,15 @@ +contract C { + uint transient x; + + function f() public view { + x = 1; + } + function g() public pure returns (uint a) { + a = x + 1; + } +} +// ==== +// EVMVersion: >=cancun +// ---- +// TypeError 8961: (75-76): Function cannot be declared as view because this expression (potentially) modifies the state. +// TypeError 2527: (148-149): Function declared as pure, but this expression (potentially) reads from the environment or state and thus requires "view". From 6398cb271fe1dfdd8a237bb7cb9625155afa4150 Mon Sep 17 00:00:00 2001 From: Nikola Matic Date: Mon, 16 Sep 2024 14:04:36 +0200 Subject: [PATCH 0457/1022] Changelog --- Changelog.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Changelog.md b/Changelog.md index 7d9af1cdbfcc..b23b5ff9e497 100644 --- a/Changelog.md +++ b/Changelog.md @@ -4,7 +4,7 @@ Language Features: Compiler Features: - * Code Generator: Transient storage value type state variables are now supported by the legacy pipeline. + * Code Generator: Transient storage value type state variables are now supported. * General: Generate JSON representations of Yul ASTs only on demand to reduce memory usage. From 98fdc44b2600b3e7236803b627544ee20eddc6ef Mon Sep 17 00:00:00 2001 From: Nikola Matic Date: Wed, 25 Sep 2024 19:39:00 +0200 Subject: [PATCH 0458/1022] Fix missing underscore in Yul function names --- libsolidity/codegen/YulUtilFunctions.cpp | 4 +-- .../codegen/ir/IRGeneratorForStatements.cpp | 5 +++- .../err | 2 +- .../input.sol | 2 +- .../output | 4 +-- .../err | 2 +- .../input.sol | 2 +- .../output | 6 ++-- .../args | 2 +- .../output | 2 +- .../output.json | 30 +++++++++---------- ...ransient_state_variable_initialization.sol | 10 ++++--- .../transient_storage_state_variable.sol | 10 +++---- .../transient_state_variable_value_type.sol | 5 ++-- ...ansient_state_variable_non_zero_offset.sol | 15 ++++++---- ...ansient_state_address_variable_members.sol | 2 +- .../various/different_call_type_transient.sol | 2 +- 17 files changed, 56 insertions(+), 49 deletions(-) diff --git a/libsolidity/codegen/YulUtilFunctions.cpp b/libsolidity/codegen/YulUtilFunctions.cpp index fc6de832be27..c908c7ae0936 100644 --- a/libsolidity/codegen/YulUtilFunctions.cpp +++ b/libsolidity/codegen/YulUtilFunctions.cpp @@ -2923,7 +2923,7 @@ std::string YulUtilFunctions::updateStorageValueFunction( "update_" + (_location == VariableDeclaration::Location::Transient ? "transient_"s : "") + "storage_value_" + - (_offset.has_value() ? ("offset_" + std::to_string(*_offset)) : "") + + (_offset.has_value() ? ("offset_" + std::to_string(*_offset)) + "_" : "") + _fromType.identifier() + "_to_" + _toType.identifier(); @@ -3106,7 +3106,7 @@ std::string YulUtilFunctions::extractFromStorageValueDynamic(Type const& _type) std::string YulUtilFunctions::extractFromStorageValue(Type const& _type, size_t _offset) { - std::string functionName = "extract_from_storage_value_offset_" + std::to_string(_offset) + _type.identifier(); + std::string functionName = "extract_from_storage_value_offset_" + std::to_string(_offset) + "_" + _type.identifier(); return m_functionCollector.createFunction(functionName, [&] { return Whiskers(R"( function (slot_value) -> value { diff --git a/libsolidity/codegen/ir/IRGeneratorForStatements.cpp b/libsolidity/codegen/ir/IRGeneratorForStatements.cpp index 283cc4b6b31a..911230d224ce 100644 --- a/libsolidity/codegen/ir/IRGeneratorForStatements.cpp +++ b/libsolidity/codegen/ir/IRGeneratorForStatements.cpp @@ -271,7 +271,7 @@ void IRGeneratorForStatements::initializeStateVar(VariableDeclaration const& _va solAssert(!_varDecl.isConstant()); if (!_varDecl.value()) return; - solAssert(_varDecl.referenceLocation() != VariableDeclaration::Location::Transient, "State variables cannot be initialized in place."); + solAssert(_varDecl.referenceLocation() != VariableDeclaration::Location::Transient, "Transient storage state variables cannot be initialized in place."); _varDecl.value()->accept(*this); @@ -2569,6 +2569,8 @@ void IRGeneratorForStatements::handleVariableReference( } }); else if (m_context.isStateVariable(_variable)) + { + solAssert(_variable.referenceLocation() == VariableDeclaration::Location::Unspecified, "Must have storage location."); setLValue(_referencingExpression, IRLValue{ *_variable.annotation().type, IRLValue::Storage{ @@ -2576,6 +2578,7 @@ void IRGeneratorForStatements::handleVariableReference( m_context.storageLocationOfStateVariable(_variable).second } }); + } else solAssert(false, "Invalid variable kind."); } diff --git a/test/cmdlineTests/evmasm_transient_storage_inline_assembly/err b/test/cmdlineTests/evmasm_transient_storage_inline_assembly/err index 5071bc457b7c..2e52d9ced0c6 100644 --- a/test/cmdlineTests/evmasm_transient_storage_inline_assembly/err +++ b/test/cmdlineTests/evmasm_transient_storage_inline_assembly/err @@ -1,5 +1,5 @@ Warning: Transient storage as defined by EIP-1153 can break the composability of smart contracts: Since transient storage is cleared only at the end of the transaction and not at the end of the outermost call frame to the contract within a transaction, your contract may unintentionally misbehave when invoked multiple times in a complex transaction. To avoid this, be sure to clear all transient storage at the end of any call to your contract. The use of transient storage for reentrancy guards that are cleared at the end of the call is safe. --> evmasm_transient_storage_inline_assembly/input.sol:7:13: | -7 | tstore(0, 0) +7 | tstore(0, 123) | ^^^^^^ diff --git a/test/cmdlineTests/evmasm_transient_storage_inline_assembly/input.sol b/test/cmdlineTests/evmasm_transient_storage_inline_assembly/input.sol index 94914ac4eef7..5504944fe416 100644 --- a/test/cmdlineTests/evmasm_transient_storage_inline_assembly/input.sol +++ b/test/cmdlineTests/evmasm_transient_storage_inline_assembly/input.sol @@ -4,7 +4,7 @@ pragma solidity >=0.0.0; contract C { fallback() external { assembly { - tstore(0, 0) + tstore(0, 123) sstore(0, tload(0)) } } diff --git a/test/cmdlineTests/evmasm_transient_storage_inline_assembly/output b/test/cmdlineTests/evmasm_transient_storage_inline_assembly/output index a02eca7d9239..0b4c516baef3 100644 --- a/test/cmdlineTests/evmasm_transient_storage_inline_assembly/output +++ b/test/cmdlineTests/evmasm_transient_storage_inline_assembly/output @@ -29,7 +29,7 @@ sub_0: assembly { revert(0x00, 0x00) tag_3: pop - 0x00 + 0x7b 0x00 tstore 0x00 @@ -40,4 +40,4 @@ sub_0: assembly { } Opcodes: -PUSH1 0x80 PUSH1 0x40 MSTORE CALLVALUE DUP1 ISZERO PUSH1 0xE JUMPI PUSH0 PUSH0 REVERT JUMPDEST POP PUSH1 0x18 DUP1 PUSH1 0x1A PUSH0 CODECOPY PUSH0 RETURN INVALID PUSH1 0x80 PUSH1 0x40 MSTORE CALLVALUE DUP1 ISZERO PUSH1 0xE JUMPI PUSH0 PUSH0 REVERT JUMPDEST POP PUSH0 PUSH0 TSTORE PUSH0 TLOAD PUSH0 SSTORE STOP +PUSH1 0x80 PUSH1 0x40 MSTORE CALLVALUE DUP1 ISZERO PUSH1 0xE JUMPI PUSH0 PUSH0 REVERT JUMPDEST POP PUSH1 0x19 DUP1 PUSH1 0x1A PUSH0 CODECOPY PUSH0 RETURN INVALID PUSH1 0x80 PUSH1 0x40 MSTORE CALLVALUE DUP1 ISZERO PUSH1 0xE JUMPI PUSH0 PUSH0 REVERT JUMPDEST POP PUSH1 0x7B PUSH0 TSTORE PUSH0 TLOAD PUSH0 SSTORE STOP diff --git a/test/cmdlineTests/evmasm_transient_storage_inline_assembly_via_ir/err b/test/cmdlineTests/evmasm_transient_storage_inline_assembly_via_ir/err index b1ccd751c9fd..154da21b6577 100644 --- a/test/cmdlineTests/evmasm_transient_storage_inline_assembly_via_ir/err +++ b/test/cmdlineTests/evmasm_transient_storage_inline_assembly_via_ir/err @@ -1,5 +1,5 @@ Warning: Transient storage as defined by EIP-1153 can break the composability of smart contracts: Since transient storage is cleared only at the end of the transaction and not at the end of the outermost call frame to the contract within a transaction, your contract may unintentionally misbehave when invoked multiple times in a complex transaction. To avoid this, be sure to clear all transient storage at the end of any call to your contract. The use of transient storage for reentrancy guards that are cleared at the end of the call is safe. --> evmasm_transient_storage_inline_assembly_via_ir/input.sol:7:13: | -7 | tstore(0, 0) +7 | tstore(0, 123) | ^^^^^^ diff --git a/test/cmdlineTests/evmasm_transient_storage_inline_assembly_via_ir/input.sol b/test/cmdlineTests/evmasm_transient_storage_inline_assembly_via_ir/input.sol index 94914ac4eef7..5504944fe416 100644 --- a/test/cmdlineTests/evmasm_transient_storage_inline_assembly_via_ir/input.sol +++ b/test/cmdlineTests/evmasm_transient_storage_inline_assembly_via_ir/input.sol @@ -4,7 +4,7 @@ pragma solidity >=0.0.0; contract C { fallback() external { assembly { - tstore(0, 0) + tstore(0, 123) sstore(0, tload(0)) } } diff --git a/test/cmdlineTests/evmasm_transient_storage_inline_assembly_via_ir/output b/test/cmdlineTests/evmasm_transient_storage_inline_assembly_via_ir/output index 62bf1f456ab8..673bdd0a052d 100644 --- a/test/cmdlineTests/evmasm_transient_storage_inline_assembly_via_ir/output +++ b/test/cmdlineTests/evmasm_transient_storage_inline_assembly_via_ir/output @@ -21,9 +21,7 @@ stop sub_0: assembly { jumpi(tag_1, callvalue) - 0x00 - dup1 - tstore + tstore(0x00, 0x7b) sstore(0x00, tload(0x00)) stop tag_1: @@ -33,4 +31,4 @@ sub_0: assembly { } Opcodes: -PUSH1 0x80 DUP1 PUSH1 0x40 MSTORE CALLVALUE PUSH1 0x13 JUMPI PUSH1 0x10 SWAP1 DUP2 PUSH1 0x18 DUP3 CODECOPY RETURN JUMPDEST PUSH0 DUP1 REVERT INVALID CALLVALUE PUSH1 0xC JUMPI PUSH0 DUP1 TSTORE PUSH0 TLOAD PUSH0 SSTORE STOP JUMPDEST PUSH0 DUP1 REVERT +PUSH1 0x80 DUP1 PUSH1 0x40 MSTORE CALLVALUE PUSH1 0x13 JUMPI PUSH1 0x11 SWAP1 DUP2 PUSH1 0x18 DUP3 CODECOPY RETURN JUMPDEST PUSH0 DUP1 REVERT INVALID CALLVALUE PUSH1 0xD JUMPI PUSH1 0x7B PUSH0 TSTORE PUSH0 TLOAD PUSH0 SSTORE STOP JUMPDEST PUSH0 DUP1 REVERT diff --git a/test/cmdlineTests/evmasm_transient_storage_state_variable_via_ir/args b/test/cmdlineTests/evmasm_transient_storage_state_variable_via_ir/args index e233e0855a41..163b19ef4c65 100644 --- a/test/cmdlineTests/evmasm_transient_storage_state_variable_via_ir/args +++ b/test/cmdlineTests/evmasm_transient_storage_state_variable_via_ir/args @@ -1 +1 @@ ---no-cbor-metadata --via-ir --optimize --asm --debug-info none \ No newline at end of file +--no-cbor-metadata --via-ir --optimize --asm --debug-info none diff --git a/test/cmdlineTests/inline_assembly_function_name_clash/output b/test/cmdlineTests/inline_assembly_function_name_clash/output index d7c7bf9e09d9..2fd6ff1f5592 100644 --- a/test/cmdlineTests/inline_assembly_function_name_clash/output +++ b/test/cmdlineTests/inline_assembly_function_name_clash/output @@ -128,7 +128,7 @@ "parameterSlots": 2, "returnSlots": 1 }, - "update_storage_value_offsett_uint256_to_uint256": { + "update_storage_value_offset_uint256_to_uint256": { "entryPoint": 307, "parameterSlots": 2, "returnSlots": 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 8f0d5b5b5d6d..5ff4e7a190fc 100644 --- a/test/cmdlineTests/standard_debug_info_in_yul_location/output.json +++ b/test/cmdlineTests/standard_debug_info_in_yul_location/output.json @@ -127,7 +127,7 @@ object \"C_54\" { ret := value } - function update_storage_value_offset_0t_int256_to_t_int256(slot, value_0) { + function update_storage_value_offset_0_t_int256_to_t_int256(slot, value_0) { let convertedValue_0 := convert_t_int256_to_t_int256(value_0) sstore(slot, update_byte_slice_32_shift_0(sload(slot), prepare_store_t_int256(convertedValue_0))) } @@ -147,7 +147,7 @@ object \"C_54\" { let _4 := var__init_12 let expr_16 := _4 /// @src 0:231:247 \"stateVar = _init\" - update_storage_value_offset_0t_int256_to_t_int256(0x00, expr_16) + update_storage_value_offset_0_t_int256_to_t_int256(0x00, expr_16) let expr_17 := expr_16 } @@ -398,12 +398,12 @@ object \"C_54\" { } - function extract_from_storage_value_offset_0t_int256(slot_value) -> value { + function extract_from_storage_value_offset_0_t_int256(slot_value) -> value { value := cleanup_from_storage_t_int256(shift_right_0_unsigned(slot_value)) } function read_from_storage_split_offset_0_t_int256(slot) -> value { - value := extract_from_storage_value_offset_0t_int256(sload(slot)) + value := extract_from_storage_value_offset_0_t_int256(sload(slot)) } @@ -435,7 +435,7 @@ object \"C_54\" { ret := value } - function update_storage_value_offset_0t_int256_to_t_int256(slot, value_0) { + function update_storage_value_offset_0_t_int256_to_t_int256(slot, value_0) { let convertedValue_0 := convert_t_int256_to_t_int256(value_0) sstore(slot, update_byte_slice_32_shift_0(sload(slot), prepare_store_t_int256(convertedValue_0))) } @@ -448,7 +448,7 @@ object \"C_54\" { /// @src 0:380:390 \"stateVar++\" let _7 := read_from_storage_split_offset_0_t_int256(0x00) let _6 := increment_t_int256(_7) - update_storage_value_offset_0t_int256_to_t_int256(0x00, _6) + update_storage_value_offset_0_t_int256_to_t_int256(0x00, _6) let expr_33 := _7 /// @src 0:400:401 \"_\" _5 := fun_f2_53_inner(var__42) @@ -882,12 +882,12 @@ object \"D_72\" { cleaned := value } - function extract_from_storage_value_offset_0t_int256(slot_value) -> value { + function extract_from_storage_value_offset_0_t_int256(slot_value) -> value { value := cleanup_from_storage_t_int256(shift_right_0_unsigned(slot_value)) } function read_from_storage_split_offset_0_t_int256(slot) -> value { - value := extract_from_storage_value_offset_0t_int256(sload(slot)) + value := extract_from_storage_value_offset_0_t_int256(sload(slot)) } @@ -933,7 +933,7 @@ object \"D_72\" { ret := value } - function update_storage_value_offset_0t_int256_to_t_int256(slot, value_0) { + function update_storage_value_offset_0_t_int256_to_t_int256(slot, value_0) { let convertedValue_0 := convert_t_int256_to_t_int256(value_0) sstore(slot, update_byte_slice_32_shift_0(sload(slot), prepare_store_t_int256(convertedValue_0))) } @@ -955,7 +955,7 @@ object \"D_72\" { let _5 := read_from_storage_split_offset_0_t_int256(0x00) let expr_68 := checked_add_t_int256(_5, expr_67) - update_storage_value_offset_0t_int256_to_t_int256(0x00, expr_68) + update_storage_value_offset_0_t_int256_to_t_int256(0x00, expr_68) } /// @src 1:91:181 \"contract D is C(3)...\" @@ -983,7 +983,7 @@ object \"D_72\" { let _7 := var__init_12 let expr_16 := _7 /// @src 0:231:247 \"stateVar = _init\" - update_storage_value_offset_0t_int256_to_t_int256(0x00, expr_16) + update_storage_value_offset_0_t_int256_to_t_int256(0x00, expr_16) let expr_17 := expr_16 } @@ -1234,12 +1234,12 @@ object \"D_72\" { } - function extract_from_storage_value_offset_0t_int256(slot_value) -> value { + function extract_from_storage_value_offset_0_t_int256(slot_value) -> value { value := cleanup_from_storage_t_int256(shift_right_0_unsigned(slot_value)) } function read_from_storage_split_offset_0_t_int256(slot) -> value { - value := extract_from_storage_value_offset_0t_int256(sload(slot)) + value := extract_from_storage_value_offset_0_t_int256(sload(slot)) } @@ -1271,7 +1271,7 @@ object \"D_72\" { ret := value } - function update_storage_value_offset_0t_int256_to_t_int256(slot, value_0) { + function update_storage_value_offset_0_t_int256_to_t_int256(slot, value_0) { let convertedValue_0 := convert_t_int256_to_t_int256(value_0) sstore(slot, update_byte_slice_32_shift_0(sload(slot), prepare_store_t_int256(convertedValue_0))) } @@ -1284,7 +1284,7 @@ object \"D_72\" { /// @src 0:380:390 \"stateVar++\" let _7 := read_from_storage_split_offset_0_t_int256(0x00) let _6 := increment_t_int256(_7) - update_storage_value_offset_0t_int256_to_t_int256(0x00, _6) + update_storage_value_offset_0_t_int256_to_t_int256(0x00, _6) let expr_33 := _7 /// @src 0:400:401 \"_\" _5 := fun_f2_53_inner(var__42) diff --git a/test/libsolidity/semanticTests/constructor/transient_state_variable_initialization.sol b/test/libsolidity/semanticTests/constructor/transient_state_variable_initialization.sol index 4c69b58f8307..3260fa30ff23 100644 --- a/test/libsolidity/semanticTests/constructor/transient_state_variable_initialization.sol +++ b/test/libsolidity/semanticTests/constructor/transient_state_variable_initialization.sol @@ -1,16 +1,18 @@ contract C { - uint256 transient x; + uint128 transient x; + uint128 y; constructor() { x = 100; + y = x; } - function f() external view returns (uint256 x) { - x; + function f() external view returns (uint128) { + return y; } } // ==== // EVMVersion: >=cancun // ---- -// f() -> 0 +// f() -> 100 diff --git a/test/libsolidity/semanticTests/inheritance/transient_storage_state_variable.sol b/test/libsolidity/semanticTests/inheritance/transient_storage_state_variable.sol index 56c686f825ea..cef016bc0b75 100644 --- a/test/libsolidity/semanticTests/inheritance/transient_storage_state_variable.sol +++ b/test/libsolidity/semanticTests/inheritance/transient_storage_state_variable.sol @@ -1,13 +1,13 @@ contract A { - uint transient x; - int y; + uint24 transient x; + int24 y; } contract C is A { - uint w; - int transient z; + uint24 w; + int24 transient z; - function f() public returns (uint, int, uint, int) { + function f() public returns (uint24, int24, uint24, int24) { x += 1; y += 2; w += 3; diff --git a/test/libsolidity/semanticTests/modifiers/transient_state_variable_value_type.sol b/test/libsolidity/semanticTests/modifiers/transient_state_variable_value_type.sol index 4c60ee1a891c..2d4157ec9b89 100644 --- a/test/libsolidity/semanticTests/modifiers/transient_state_variable_value_type.sol +++ b/test/libsolidity/semanticTests/modifiers/transient_state_variable_value_type.sol @@ -6,12 +6,13 @@ contract C { _; } - function f() public m(x) returns (uint16 x) { + function f() public m(x) returns (uint16) { x *= 10; + return x; } } // ==== // EVMVersion: >=cancun // ---- -// f() -> 0 +// f() -> 100 diff --git a/test/libsolidity/semanticTests/variables/delete_transient_state_variable_non_zero_offset.sol b/test/libsolidity/semanticTests/variables/delete_transient_state_variable_non_zero_offset.sol index 45860599e641..96dfce60265a 100644 --- a/test/libsolidity/semanticTests/variables/delete_transient_state_variable_non_zero_offset.sol +++ b/test/libsolidity/semanticTests/variables/delete_transient_state_variable_non_zero_offset.sol @@ -1,14 +1,17 @@ contract C { - uint128 transient x; - uint128 transient y; + bytes14 transient x; + uint32 transient y; + uint112 transient z; - function f() public returns (uint) { - y = 10; + function f() public returns (bytes14, uint32, uint112) { + x = 0xffffffffffffffffffffffffffff; + y = 0xffffffff; + z = 0xffffffffffffffffffffffffffff; delete y; - return y; + return (x, y, z); } } // ==== // EVMVersion: >=cancun // ---- -// f() -> 0 +// f() -> 0xffffffffffffffffffffffffffff000000000000000000000000000000000000, 0, 0xffffffffffffffffffffffffffff diff --git a/test/libsolidity/semanticTests/variables/transient_state_address_variable_members.sol b/test/libsolidity/semanticTests/variables/transient_state_address_variable_members.sol index 22cc5db05626..f609f9d4de9e 100644 --- a/test/libsolidity/semanticTests/variables/transient_state_address_variable_members.sol +++ b/test/libsolidity/semanticTests/variables/transient_state_address_variable_members.sol @@ -17,4 +17,4 @@ contract C { // account: 0 -> 0x1212121212121212121212121212120000000012 // balance: 0x1212121212121212121212121212120000000012 -> 1267650600228229401496703205376 // f() -> 1267650600228229401496703205376 -// g() -> 0 \ No newline at end of file +// g() -> 0 diff --git a/test/libsolidity/semanticTests/various/different_call_type_transient.sol b/test/libsolidity/semanticTests/various/different_call_type_transient.sol index b71e8b25253a..399cbd02dfa1 100644 --- a/test/libsolidity/semanticTests/various/different_call_type_transient.sol +++ b/test/libsolidity/semanticTests/various/different_call_type_transient.sol @@ -35,7 +35,7 @@ contract Test { a.callSetValue(address(b), 8); return (a.value(), b.value()); } - function testStatic() view public returns (bool) { + function testStatic() view public returns (bool) { return a.staticSetValue(address(b), 0); } } From b54074176a9b751d252650528252a8c8468976ca Mon Sep 17 00:00:00 2001 From: Matheus Aguiar Date: Thu, 5 Sep 2024 14:50:04 -0300 Subject: [PATCH 0459/1022] Transient storage docs --- docs/assembly.rst | 9 +- docs/contracts.rst | 2 + docs/contracts/constant-state-variables.rst | 5 +- docs/contracts/functions.rst | 4 +- docs/contracts/transient-storage.rst | 172 ++++++++++++++++++++ docs/internals/layout_in_storage.rst | 79 +++++++-- docs/introduction-to-smart-contracts.rst | 47 +++++- docs/structure-of-a-contract.rst | 6 +- docs/types/reference-types.rst | 3 + docs/types/value-types.rst | 6 + 10 files changed, 305 insertions(+), 28 deletions(-) create mode 100644 docs/contracts/transient-storage.rst diff --git a/docs/assembly.rst b/docs/assembly.rst index 34085bccb796..a0a9d06dc76c 100644 --- a/docs/assembly.rst +++ b/docs/assembly.rst @@ -163,7 +163,7 @@ their calldata offset (in bytes) and length (number of elements) using ``x.offse Both expressions can also be assigned to, but as for the static case, no validation will be performed to ensure that the resulting data area is within the bounds of ``calldatasize()``. -For local storage variables or state variables, a single Yul identifier +For local storage variables or state variables (including transient storage) a single Yul identifier is not sufficient, since they do not necessarily occupy a single full storage slot. Therefore, their "address" is composed of a slot and a byte-offset inside that slot. To retrieve the slot pointed to by the variable ``x``, you @@ -181,15 +181,18 @@ Local Solidity variables are available for assignments, for example: :force: // SPDX-License-Identifier: GPL-3.0 - pragma solidity >=0.7.0 <0.9.0; + pragma solidity >=0.8.28 <0.9.0; + // This will report a warning contract C { + bool transient a; uint b; - function f(uint x) public view returns (uint r) { + function f(uint x) public returns (uint r) { assembly { // We ignore the storage slot offset, we know it is zero // in this special case. r := mul(x, sload(b.slot)) + tstore(a.slot, true) } } } diff --git a/docs/contracts.rst b/docs/contracts.rst index aee26c95afd8..588b1da00d0b 100644 --- a/docs/contracts.rst +++ b/docs/contracts.rst @@ -20,6 +20,8 @@ There is no "cron" concept in Ethereum to call a function at a particular event .. include:: contracts/function-modifiers.rst +.. include:: contracts/transient-storage.rst + .. include:: contracts/constant-state-variables.rst .. include:: contracts/functions.rst diff --git a/docs/contracts/constant-state-variables.rst b/docs/contracts/constant-state-variables.rst index a1bc24f50c64..4e9698735473 100644 --- a/docs/contracts/constant-state-variables.rst +++ b/docs/contracts/constant-state-variables.rst @@ -13,8 +13,9 @@ for ``immutable``, it can still be assigned at construction time. It is also possible to define ``constant`` variables at the file level. -The compiler does not reserve a storage slot for these variables, and every occurrence is -replaced by the respective value. +Every occurrence of such a variable in the source is replaced by its underlying value +and the compiler does not reserve a storage slot for it. +It cannot be assigned a slot in transient storage using the ``transient`` keyword either. Compared to regular state variables, the gas costs of constant and immutable variables are much lower. For a constant variable, the expression assigned to it is copied to diff --git a/docs/contracts/functions.rst b/docs/contracts/functions.rst index 5b82a93bcc73..e653eb8f09b5 100644 --- a/docs/contracts/functions.rst +++ b/docs/contracts/functions.rst @@ -174,7 +174,7 @@ Functions can be declared ``view`` in which case they promise not to modify the The following statements are considered modifying the state: -#. Writing to state variables. +#. Writing to state variables (storage and transient storage). #. :ref:`Emitting events `. #. :ref:`Creating other contracts `. #. Using ``selfdestruct``. @@ -226,7 +226,7 @@ This means that reading from ``immutable`` variables can be a non-pure operation In addition to the list of state modifying statements explained above, the following are considered reading from the state: -#. Reading from state variables. +#. Reading from state variables (storage and transient storage). #. Accessing ``address(this).balance`` or ``
.balance``. #. Accessing any of the members of ``block``, ``tx``, ``msg`` (with the exception of ``msg.sig`` and ``msg.data``). #. Calling any function not marked ``pure``. diff --git a/docs/contracts/transient-storage.rst b/docs/contracts/transient-storage.rst new file mode 100644 index 000000000000..b2d0be292204 --- /dev/null +++ b/docs/contracts/transient-storage.rst @@ -0,0 +1,172 @@ +.. index:: ! transient storage, ! transient, tstore, tload + +.. _transient-storage: + +***************** +Transient Storage +***************** + +Transient storage is another data location besides memory, storage, calldata +(and return-data and code) which was introduced alongside its respective opcodes +``TSTORE`` and ``TLOAD`` by `EIP-1153 `_. +This new data location behaves as a key-value store similar to storage with the main +difference being that data in transient storage is not permanent, but is scoped to +the current transaction only, after which it will be reset to zero. +Since the content of transient storage has very limited lifetime and size, +it does not need to be stored permanently as a part of state +and the associated gas costs are much lower than in case of storage. +EVM version ``cancun`` or newer is required for transient storage to be available. + +Transient storage variables cannot be initialized in place, i.e., they cannot be assigned +to upon declaration, since the value would be cleared at the end of the creation transaction, +rendering the initialization ineffective. +Transient variables will be :ref:`default value` initialized depending on +their underlying type. +``constant`` and ``immutable`` variables conflict with transient storage, since +their values are either inlined or directly stored in code. + +Transient storage variables have completely independent address space from storage, +so that the order of transient state variables does not affect the layout of storage +state variables and vice-versa. +They do need distinct names though because all state variables share the same namespace. +It is also important to note that the values in transient storage are packed in the +same fashion as those in persistent storage. +See :ref:`Storage Layout ` for more information. + +Besides that, transient variables can have visibility as well and ``public`` ones will +have a getter function generated automatically as usual. + +Note that, currently, such use of ``transient`` as a data location is only allowed for +:ref:`value type ` state variable declarations. +Reference types, such as arrays, mappings and structs, as well as local or parameter +variables are not yet supported. + +An expected canonical use case for transient storage is cheaper reentrancy locks, +which can be readily implemented with the opcodes as showcased next. + +.. code-block:: solidity + + // SPDX-License-Identifier: GPL-3.0 + pragma solidity ^0.8.28; + + contract Generosity { + mapping(address => bool) sentGifts; + bool transient locked; + + modifier nonReentrant { + require(!locked, "Reentrancy attempt"); + locked = true; + _; + // Unlocks the guard, making the pattern composable. + // After the function exits, it can be called again, even in the same transaction. + locked = false; + } + + function claimGift() nonReentrant public { + require(address(this).balance >= 1 ether); + require(!sentGifts[msg.sender]); + (bool success, ) = msg.sender.call{value: 1 ether}(""); + require(success); + + // In a reentrant function, doing this last would open up the vulnerability + sentGifts[msg.sender] = true; + } + } + +Transient storage is private to the contract that owns it, in the same way as persistent storage. +Only owning contract frames may access their transient storage, and when they do, all the frames access the same transient store. + +Transient storage is part of the EVM state and is subject to the same mutability enforcements +as persistent storage. As such, any read access to it is not ``pure`` and writing access is not ``view``. + +If the ``TSTORE`` opcode is called within the context of a ``STATICCALL``, +it will result in an exception instead of performing the modification. +``TLOAD`` is allowed within the context of a ``STATICCALL``. + +When transient storage is used in the context of ``DELEGATECALL`` or ``CALLCODE``, +then the owning contract of the transient storage is the contract that issued ``DELEGATECALL`` +or ``CALLCODE`` instruction (the caller) as with persistent storage. +When transient storage is used in the context of ``CALL`` or ``STATICCALL``, +then the owning contract of the transient storage is the contract that is the target +of the ``CALL`` or ``STATICCALL`` instruction (the callee). + +.. note:: + In the case of ``DELEGATECALL``, since references to transient storage variables + are currently not supported, it is not possible to pass those into library calls. + In libraries, access to transient storage is only possible using inline assembly. + +If a frame reverts, all writes to transient storage that took place between entry +to the frame and the return are reverted, including those that took place in inner calls. +The caller of an external call may employ a ``try ... catch`` block to prevent reverts +bubbling up from the inner calls. + +********************************************************************* +Composability of Smart Contracts and the Caveats of Transient Storage +********************************************************************* + +Given the caveats mentioned in the specification of EIP-1153, +in order to preserve the composability of your smart contract, +utmost care is recommended for more advanced use cases of transient storage. + +For smart contracts, composability is a very important design principle to achieve self-contained behaviour, +such that multiple calls into individual smart contracts can be composed to more complex applications. +So far the EVM largely guaranteed composable behaviour, since multiple calls into a smart contract +within a complex transaction are virtually indistinguishable from multiple calls to the contract +stretched over several transactions. However, transient storage allows a violation of this principle, +and incorrect use may lead to complex bugs that only surface when used across several calls. + +Let's illustrate the problem with a simple example: + +.. code-block:: solidity + + // SPDX-License-Identifier: GPL-3.0 + pragma solidity ^0.8.28; + + contract MulService { + uint transient multiplier; + function setMultiplier(uint mul) external { + multiplier = mul; + } + + function multiply(uint value) external view returns (uint) { + return value * multiplier; + } + } + +and a sequence of external calls: + +.. code-block:: solidity + + setMultiplier(42); + multiply(1); + multiply(2); + +If the example used memory or storage to store the multiplier, it would be fully composable. +It would not matter whether you split the sequence into separate transactions or grouped them in some way. +You would always get the same result: after ``multiplier`` is set to ``42``, the subsequent calls +would return ``42`` and ``84`` respectively. +This enables use cases such as batching calls from multiple transactions +together to reduce gas costs. +Transient storage potentially breaks such use cases since composability can no longer be taken for granted. +In the example, if the calls are not executed in the same transaction, then ``multiplier`` +is reset and the next calls to function ``multiply`` would always return ``0``. + +As another example, since transient storage is constructed as a relatively cheap key-value store, +a smart contract author may be tempted to use transient storage as a replacement for in-memory mappings +without keeping track of the modified keys in the mapping and thereby without clearing the mapping +at the end of the call. +This, however, can easily lead to unexpected behaviour in complex transactions, +in which values set by a previous call into the contract within the same transaction remain. + +The use of transient storage for reentrancy locks that are cleared at the end of the call frame +into the contract, is safe. +However, be sure to resist the temptation to save the 100 gas used for resetting the +reentrancy lock, since failing to do so, will restrict your contract to only one call +within a transaction, preventing its use in complex composed transactions, +which have been a cornerstone for complex applications on chain. + +It is recommend to generally always clear transient storage completely at the end of a call +into your smart contract to avoid these kinds of issues and to simplify +the analysis of the behaviour of your contract within complex transactions. +Check the `Security Considerations section of EIP-1153 `_ +for further details. \ No newline at end of file diff --git a/docs/internals/layout_in_storage.rst b/docs/internals/layout_in_storage.rst index f6b10adeef78..557a0a0e2090 100644 --- a/docs/internals/layout_in_storage.rst +++ b/docs/internals/layout_in_storage.rst @@ -153,7 +153,7 @@ JSON Output .. _storage-layout-top-level: -The storage layout of a contract can be requested via +The storage (or transient storage) layout of a contract can be requested via the :ref:`standard JSON interface `. The output is a JSON object containing two keys, ``storage`` and ``types``. The ``storage`` object is an array where each element has the following form: @@ -218,14 +218,14 @@ the same format as the top-level ``storage`` (see :ref:`above The JSON output format of a contract's storage layout is still considered experimental and is subject to change in non-breaking releases of Solidity. -The following example shows a contract and its storage layout, containing -value and reference types, types that are encoded packed, and nested types. +The following example shows a contract and both its storage and transient storage layout, +containing value and reference types, types that are encoded packed, and nested types. .. code-block:: solidity // SPDX-License-Identifier: GPL-3.0 - pragma solidity >=0.4.0 <0.9.0; + pragma solidity ^0.8.28; contract A { struct S { uint128 a; @@ -235,15 +235,22 @@ value and reference types, types that are encoded packed, and nested types. } uint x; - uint y; + uint transient y; + uint w; + uint transient z; + S s; address addr; + address transient taddr; mapping(uint => mapping(address => bool)) map; uint[] array; string s1; bytes b1; } +Storage Layout +-------------- + .. code-block:: json { @@ -257,15 +264,15 @@ value and reference types, types that are encoded packed, and nested types. "type": "t_uint256" }, { - "astId": 17, + "astId": 19, "contract": "fileA:A", - "label": "y", + "label": "w", "offset": 0, "slot": "1", "type": "t_uint256" }, { - "astId": 20, + "astId": 24, "contract": "fileA:A", "label": "s", "offset": 0, @@ -273,7 +280,7 @@ value and reference types, types that are encoded packed, and nested types. "type": "t_struct(S)13_storage" }, { - "astId": 22, + "astId": 26, "contract": "fileA:A", "label": "addr", "offset": 0, @@ -281,7 +288,7 @@ value and reference types, types that are encoded packed, and nested types. "type": "t_address" }, { - "astId": 28, + "astId": 34, "contract": "fileA:A", "label": "map", "offset": 0, @@ -289,7 +296,7 @@ value and reference types, types that are encoded packed, and nested types. "type": "t_mapping(t_uint256,t_mapping(t_address,t_bool))" }, { - "astId": 31, + "astId": 37, "contract": "fileA:A", "label": "array", "offset": 0, @@ -297,7 +304,7 @@ value and reference types, types that are encoded packed, and nested types. "type": "t_array(t_uint256)dyn_storage" }, { - "astId": 33, + "astId": 39, "contract": "fileA:A", "label": "s1", "offset": 0, @@ -305,7 +312,7 @@ value and reference types, types that are encoded packed, and nested types. "type": "t_string_storage" }, { - "astId": 35, + "astId": 41, "contract": "fileA:A", "label": "b1", "offset": 0, @@ -411,3 +418,49 @@ value and reference types, types that are encoded packed, and nested types. } } } + +Transient Storage Layout +------------------------ + +.. code-block:: json + + { + "storage": [ + { + "astId": 17, + "contract": "fileA:A", + "label": "y", + "offset": 0, + "slot": "0", + "type": "t_uint256" + }, + { + "astId": 21, + "contract": "fileA:A", + "label": "z", + "offset": 0, + "slot": "1", + "type": "t_uint256" + }, + { + "astId": 28, + "contract": "fileA:A", + "label": "taddr", + "offset": 0, + "slot": "2", + "type": "t_address" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + } + } + } \ No newline at end of file diff --git a/docs/introduction-to-smart-contracts.rst b/docs/introduction-to-smart-contracts.rst index c8600579457f..45857c3f891c 100644 --- a/docs/introduction-to-smart-contracts.rst +++ b/docs/introduction-to-smart-contracts.rst @@ -415,13 +415,15 @@ In case of an exception that reverts changes, already used up gas is not refunde Since EVM executors can choose to include a transaction or not, transaction senders cannot abuse the system by setting a low gas price. -.. index:: ! storage, ! memory, ! stack +.. index:: ! storage, ! memory, ! stack, ! transient storage -Storage, Memory and the Stack -============================= +.. _locations: + +Storage, Transient Storage, Memory and the Stack +================================================ -The Ethereum Virtual Machine has three areas where it can store data: -storage, memory and the stack. +The Ethereum Virtual Machine has different areas where it can store data with the most +prominent being storage, transient storage, memory and the stack. Each account has a data area called **storage**, which is persistent between function calls and transactions. @@ -432,7 +434,15 @@ you should minimize what you store in persistent storage to what the contract ne Store data like derived calculations, caching, and aggregates outside of the contract. A contract can neither read nor write to any storage apart from its own. -The second data area is called **memory**, of which a contract obtains +Similar to storage, there is another data area called **transient storage**, +where the main difference is that it is reset at the end of each transaction. +The values stored in this data location persist only across function calls originating +from the first call of the transaction. +When the transaction ends, the transient storage is reset and the values stored there +become unavailable to calls in subsequent transactions. +Despite this, the cost of reading and writing to transient storage is significantly lower than for storage. + +The third data area is called **memory**, of which a contract obtains a freshly cleared instance for each message call. Memory is linear and can be addressed at byte level, but reads are limited to a width of 256 bits, while writes can be either 8 bits or 256 bits wide. Memory is expanded by a word (256-bit), when @@ -454,6 +464,31 @@ in order to get deeper access to the stack, but it is not possible to just access arbitrary elements deeper in the stack without first removing the top of the stack. +Calldata, Returndata and Code +============================= + +There are also other data areas which are not as apparent as those discussed previously. +However, they are routinely used during the execution of smart contract transactions. + +The calldata region is the data sent to a transaction as part of a smart contract transaction. +For example, when creating a contract, calldata would be the constructor code of the new contract. +The parameters of external functions are always initially stored in calldata in an ABI-encoded form +and only then decoded into the location specified in their declaration. +If declared as ``memory``, the compiler will eagerly decode them into memory at the beginning of the function, +while marking them as ``calldata`` means that this will be done lazily, only when accessed. +Value types and ``storage`` pointers are decoded directly onto the stack. + +The returndata is the way a smart contract can return a value after a call. +In general, external Solidity functions use the ``return`` keyword to ABI-encode values into the returndata area. + +The code is the region where the EVM instructions of a smart contract are stored. +Code is the bytes read, interpreted, and executed by the EVM during smart contract execution. +Instruction data stored in the code is persistent as part of a contract account state field. +Immutable and constant variables are stored in the code region. +All references to immutables are replaced with the values assigned to them. +A similar process is performed for constants which have their expressions inlined +in the places where they are referenced in the smart contract code. + .. index:: ! instruction Instruction Set diff --git a/docs/structure-of-a-contract.rst b/docs/structure-of-a-contract.rst index 51d99a803602..eebef172f674 100644 --- a/docs/structure-of-a-contract.rst +++ b/docs/structure-of-a-contract.rst @@ -21,8 +21,10 @@ which serves to provide a quick overview. State Variables =============== -State variables are variables whose values are permanently stored in contract -storage. +State variables are variables whose values are either permanently stored in contract +storage or, alternatively, temporarily stored in transient storage which is cleaned at +the end of each transaction. +See :ref:`data locations ` for more details. .. code-block:: solidity diff --git a/docs/types/reference-types.rst b/docs/types/reference-types.rst index a6c48d2416d9..4a053d51beea 100644 --- a/docs/types/reference-types.rst +++ b/docs/types/reference-types.rst @@ -28,6 +28,9 @@ annotation, the "data location", about where it is stored. There are three data ``memory``, ``storage`` and ``calldata``. Calldata is a non-modifiable, non-persistent area where function arguments are stored, and behaves mostly like memory. +.. note:: + ``transient`` is not yet supported as a data location for reference types. + .. note:: If you can, try to use ``calldata`` as data location because it will avoid copies and also makes sure that the data cannot be modified. Arrays and structs with ``calldata`` diff --git a/docs/types/value-types.rst b/docs/types/value-types.rst index 12fcb0b171d6..27baf5485104 100644 --- a/docs/types/value-types.rst +++ b/docs/types/value-types.rst @@ -7,6 +7,12 @@ Value Types The following are called value types because their variables will always be passed by value, i.e. they are always copied when they are used as function arguments or in assignments. +Unlike :ref:`reference types `, value type declarations do not +specify a data location since they are small enough to be stored on the stack. +The only exception are :ref:`state variables `. +Those are by default located in storage, but can also be marked as +:ref:`transient `, :ref:`constant or immutable `. + .. index:: ! bool, ! true, ! false Booleans From 146e2bc1916c49cdc36a65c81272a65f2e62f50b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Mon, 30 Sep 2024 10:37:58 +0200 Subject: [PATCH 0460/1022] outputPerformanceMetrics(): Add missing std:: prefixes --- libyul/optimiser/Suite.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/libyul/optimiser/Suite.cpp b/libyul/optimiser/Suite.cpp index d7043e42f30f..0233a1cf078a 100644 --- a/libyul/optimiser/Suite.cpp +++ b/libyul/optimiser/Suite.cpp @@ -99,13 +99,13 @@ namespace { #ifdef PROFILE_OPTIMIZER_STEPS -void outputPerformanceMetrics(map const& _metrics) +void outputPerformanceMetrics(std::map const& _metrics) { - vector> durations(_metrics.begin(), _metrics.end()); + std::vector> durations(_metrics.begin(), _metrics.end()); sort( durations.begin(), durations.end(), - [](pair const& _lhs, pair const& _rhs) -> bool + [](std::pair const& _lhs, std::pair const& _rhs) -> bool { return _lhs.second < _rhs.second; } @@ -115,18 +115,18 @@ void outputPerformanceMetrics(map const& _metrics) for (auto&& [step, durationInMicroseconds]: durations) totalDurationInMicroseconds += durationInMicroseconds; - cerr << "Performance metrics of optimizer steps" << endl; - cerr << "======================================" << endl; + std::cerr << "Performance metrics of optimizer steps" << std::endl; + std::cerr << "======================================" << std::endl; constexpr double microsecondsInSecond = 1000000; for (auto&& [step, durationInMicroseconds]: durations) { double percentage = 100.0 * static_cast(durationInMicroseconds) / static_cast(totalDurationInMicroseconds); double sec = static_cast(durationInMicroseconds) / microsecondsInSecond; - cerr << fmt::format("{:>7.3f}% ({} s): {}", percentage, sec, step) << endl; + std::cerr << fmt::format("{:>7.3f}% ({} s): {}", percentage, sec, step) << std::endl; } double totalDurationInSeconds = static_cast(totalDurationInMicroseconds) / microsecondsInSecond; - cerr << "--------------------------------------" << endl; - cerr << fmt::format("{:>7}% ({:.3f} s)", 100, totalDurationInSeconds) << endl; + std::cerr << "--------------------------------------" << std::endl; + std::cerr << fmt::format("{:>7}% ({:.3f} s)", 100, totalDurationInSeconds) << std::endl; } #endif From c6df88707f36bf94ffb62858bcabfdba7b80bbe7 Mon Sep 17 00:00:00 2001 From: Nikola Matic Date: Mon, 30 Sep 2024 12:14:29 +0200 Subject: [PATCH 0461/1022] Fix evmone MacOS link --- test/Common.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/Common.h b/test/Common.h index 3adb980a0d05..409d6f6960e1 100644 --- a/test/Common.h +++ b/test/Common.h @@ -37,7 +37,7 @@ static constexpr auto evmoneFilename = "evmone.dll"; static constexpr auto evmoneDownloadLink = "https://github.com/ethereum/evmone/releases/download/v0.12.0/evmone-0.12.0-windows-amd64.zip"; #elif defined(__APPLE__) static constexpr auto evmoneFilename = "libevmone.dylib"; -static constexpr auto evmoneDownloadLink = "https://github.com/ethereum/evmone/releases/download/v0.12.0/evmone-0.12.0-darwin-x86_64.tar.gz"; +static constexpr auto evmoneDownloadLink = "https://github.com/ethereum/evmone/releases/download/v0.12.0/evmone-0.12.0-darwin-arm64.tar.gz"; #else static constexpr auto evmoneFilename = "libevmone.so"; static constexpr auto evmoneDownloadLink = "https://github.com/ethereum/evmone/releases/download/v0.12.0/evmone-0.12.0-linux-x86_64.tar.gz"; From 891b7c83d7cbc551c8b3a74cb67bcd6ea26ad96a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Thu, 26 Sep 2024 18:38:40 +0200 Subject: [PATCH 0462/1022] Do not cache instances of Compiler in CompilerStack --- libsolidity/interface/CompilerStack.cpp | 14 +++++++++----- libsolidity/interface/CompilerStack.h | 4 +++- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/libsolidity/interface/CompilerStack.cpp b/libsolidity/interface/CompilerStack.cpp index bac358a939f4..8dd390f5edd2 100644 --- a/libsolidity/interface/CompilerStack.cpp +++ b/libsolidity/interface/CompilerStack.cpp @@ -861,15 +861,18 @@ Json CompilerStack::generatedSources(std::string const& _contractName, bool _run c.generatedSources; return sources.init([&]{ Json sources = Json::array(); - // If there is no compiler, then no bytecode was generated and thus no + + solAssert(c.generatedYulUtilityCode.has_value() == c.runtimeGeneratedYulUtilityCode.has_value()); + + // If there is no generated utility code, then no bytecode was generated and thus no // sources were generated (or we compiled "via IR"). - if (c.compiler) + if (c.runtimeGeneratedYulUtilityCode.has_value()) { solAssert(!m_viaIR, ""); std::string source = _runtime ? - c.compiler->runtimeGeneratedYulUtilityCode() : - c.compiler->generatedYulUtilityCode(); + *c.runtimeGeneratedYulUtilityCode : + *c.generatedYulUtilityCode; if (!source.empty()) { std::string sourceName = CompilerContext::yulUtilityFileName(); @@ -1469,13 +1472,14 @@ void CompilerStack::compileContract( Contract& compiledContract = m_contracts.at(_contract.fullyQualifiedName()); std::shared_ptr compiler = std::make_shared(m_evmVersion, m_revertStrings, m_optimiserSettings); - compiledContract.compiler = compiler; solAssert(!m_viaIR, ""); bytes cborEncodedMetadata = createCBORMetadata(compiledContract, /* _forIR */ false); // Run optimiser and compile the contract. compiler->compileContract(_contract, _otherCompilers, cborEncodedMetadata); + compiledContract.generatedYulUtilityCode = compiler->generatedYulUtilityCode(); + compiledContract.runtimeGeneratedYulUtilityCode = compiler->runtimeGeneratedYulUtilityCode(); _otherCompilers[compiledContract.contract] = compiler; diff --git a/libsolidity/interface/CompilerStack.h b/libsolidity/interface/CompilerStack.h index c0166af96d5b..f167477faf3b 100644 --- a/libsolidity/interface/CompilerStack.h +++ b/libsolidity/interface/CompilerStack.h @@ -409,9 +409,11 @@ class CompilerStack: public langutil::CharStreamProvider, public evmasm::Abstrac struct Contract { ContractDefinition const* contract = nullptr; - std::shared_ptr compiler; + std::shared_ptr evmAssembly; std::shared_ptr evmRuntimeAssembly; + std::optional generatedYulUtilityCode; ///< Extra Yul utility code that was used when compiling the creation assembly + std::optional runtimeGeneratedYulUtilityCode; ///< Extra Yul utility code that was used when compiling the deployed assembly evmasm::LinkerObject object; ///< Deployment object (includes the runtime sub-object). evmasm::LinkerObject runtimeObject; ///< Runtime object. std::string yulIR; ///< Yul IR code straight from the code generator. From 3c5e46b7d75172114413c7c775c412ffc41d9d38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Thu, 26 Sep 2024 23:16:19 +0200 Subject: [PATCH 0463/1022] CompilerStack: Do not cache the JSON representation of generated sources --- libsolidity/interface/CompilerStack.cpp | 60 +++++++++++-------------- libsolidity/interface/CompilerStack.h | 2 - 2 files changed, 26 insertions(+), 36 deletions(-) diff --git a/libsolidity/interface/CompilerStack.cpp b/libsolidity/interface/CompilerStack.cpp index 8dd390f5edd2..a9f2708d8023 100644 --- a/libsolidity/interface/CompilerStack.cpp +++ b/libsolidity/interface/CompilerStack.cpp @@ -855,43 +855,35 @@ Json CompilerStack::generatedSources(std::string const& _contractName, bool _run solAssert(m_stackState == CompilationSuccessful, "Compilation was not successful."); Contract const& c = contract(_contractName); - util::LazyInit const& sources = - _runtime ? - c.runtimeGeneratedSources : - c.generatedSources; - return sources.init([&]{ - Json sources = Json::array(); - + Json sources = Json::array(); + // If there is no compiler, then no bytecode was generated and thus no + // sources were generated (or we compiled "via IR"). + if (c.runtimeGeneratedYulUtilityCode.has_value()) + { solAssert(c.generatedYulUtilityCode.has_value() == c.runtimeGeneratedYulUtilityCode.has_value()); - - // If there is no generated utility code, then no bytecode was generated and thus no - // sources were generated (or we compiled "via IR"). - if (c.runtimeGeneratedYulUtilityCode.has_value()) + solAssert(!m_viaIR); + std::string source = + _runtime ? + *c.runtimeGeneratedYulUtilityCode : + *c.generatedYulUtilityCode; + if (!source.empty()) { - solAssert(!m_viaIR, ""); - std::string source = - _runtime ? - *c.runtimeGeneratedYulUtilityCode : - *c.generatedYulUtilityCode; - if (!source.empty()) - { - std::string sourceName = CompilerContext::yulUtilityFileName(); - unsigned sourceIndex = sourceIndices()[sourceName]; - ErrorList errors; - ErrorReporter errorReporter(errors); - CharStream charStream(source, sourceName); - yul::EVMDialect const& dialect = yul::EVMDialect::strictAssemblyForEVM(m_evmVersion); - std::shared_ptr parserResult = yul::Parser{errorReporter, dialect}.parse(charStream); - solAssert(parserResult, ""); - sources[0]["ast"] = yul::AsmJsonConverter{sourceIndex}(parserResult->root()); - sources[0]["name"] = sourceName; - sources[0]["id"] = sourceIndex; - sources[0]["language"] = "Yul"; - sources[0]["contents"] = std::move(source); - } + std::string sourceName = CompilerContext::yulUtilityFileName(); + unsigned sourceIndex = sourceIndices()[sourceName]; + ErrorList errors; + ErrorReporter errorReporter(errors); + CharStream charStream(source, sourceName); + yul::EVMDialect const& dialect = yul::EVMDialect::strictAssemblyForEVM(m_evmVersion); + std::shared_ptr parserResult = yul::Parser{errorReporter, dialect}.parse(charStream); + solAssert(parserResult); + sources[0]["ast"] = yul::AsmJsonConverter{sourceIndex}(parserResult->root()); + sources[0]["name"] = sourceName; + sources[0]["id"] = sourceIndex; + sources[0]["language"] = "Yul"; + sources[0]["contents"] = std::move(source); } - return sources; - }); + } + return sources; } std::string const* CompilerStack::sourceMapping(std::string const& _contractName) const diff --git a/libsolidity/interface/CompilerStack.h b/libsolidity/interface/CompilerStack.h index f167477faf3b..2b891293b3e0 100644 --- a/libsolidity/interface/CompilerStack.h +++ b/libsolidity/interface/CompilerStack.h @@ -424,8 +424,6 @@ class CompilerStack: public langutil::CharStreamProvider, public evmasm::Abstrac util::LazyInit transientStorageLayout; util::LazyInit userDocumentation; util::LazyInit devDocumentation; - util::LazyInit generatedSources; - util::LazyInit runtimeGeneratedSources; mutable std::optional sourceMapping; mutable std::optional runtimeSourceMapping; }; From 6bee17d21c8d17ade1b459ea9c33141e79011534 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Mon, 16 Sep 2024 10:35:49 +0200 Subject: [PATCH 0464/1022] CompilerStack: Add missing members to reset() --- libsolidity/interface/CompilerStack.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libsolidity/interface/CompilerStack.cpp b/libsolidity/interface/CompilerStack.cpp index a9f2708d8023..4d3bacabc98a 100644 --- a/libsolidity/interface/CompilerStack.cpp +++ b/libsolidity/interface/CompilerStack.cpp @@ -313,7 +313,9 @@ void CompilerStack::reset(bool _keepSettings) m_libraries.clear(); m_viaIR = false; m_evmVersion = langutil::EVMVersion(); + m_eofVersion.reset(); m_modelCheckerSettings = ModelCheckerSettings{}; + m_requestedContractNames.clear(); m_irOutputSelection = IROutputSelection::None; m_revertStrings = RevertStrings::Default; m_optimiserSettings = OptimiserSettings::minimal(); @@ -321,6 +323,7 @@ void CompilerStack::reset(bool _keepSettings) m_metadataFormat = defaultMetadataFormat(); m_metadataHash = MetadataHash::IPFS; m_stopAfter = State::CompilationSuccessful; + m_compilationSourceType = CompilationSourceType::Solidity; } m_experimentalAnalysis.reset(); m_globalContext.reset(); From a4fa88646c1ec0a44f2a2b80ee7ae64a1d0de05b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Mon, 16 Sep 2024 13:58:39 +0200 Subject: [PATCH 0465/1022] StandardCompiler: Fix bad `if` indent triggering a warning --- libsolidity/interface/StandardCompiler.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libsolidity/interface/StandardCompiler.cpp b/libsolidity/interface/StandardCompiler.cpp index 06df8a940856..34c9f21a003e 100644 --- a/libsolidity/interface/StandardCompiler.cpp +++ b/libsolidity/interface/StandardCompiler.cpp @@ -1434,7 +1434,7 @@ Json StandardCompiler::compileSolidity(StandardCompiler::InputsAndSettings _inpu Json output; if (errors.size() > 0) - output["errors"] = std::move(errors); + output["errors"] = std::move(errors); if (!compilerStack.unhandledSMTLib2Queries().empty()) for (std::string const& query: compilerStack.unhandledSMTLib2Queries()) From a9d9143007f6a5fb9aa16378b8cfec0a926d70ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Mon, 16 Sep 2024 14:36:38 +0200 Subject: [PATCH 0466/1022] Pass selected outputs down to CompilerStack to avoid generating them when not requested --- Changelog.md | 1 + libsolidity/interface/CompilerStack.cpp | 62 ++++++++----- libsolidity/interface/CompilerStack.h | 86 +++++++++++++------ libsolidity/interface/StandardCompiler.cpp | 69 +++++++-------- solc/CommandLineInterface.cpp | 23 ++--- .../SolidityExecutionFramework.cpp | 1 - 6 files changed, 149 insertions(+), 93 deletions(-) diff --git a/Changelog.md b/Changelog.md index b23b5ff9e497..b171b6dd0155 100644 --- a/Changelog.md +++ b/Changelog.md @@ -6,6 +6,7 @@ Language Features: Compiler Features: * Code Generator: Transient storage value type state variables are now supported. * General: Generate JSON representations of Yul ASTs only on demand to reduce memory usage. + * Standard JSON Interface: Bytecode or IR can now be requested for a subset of all contracts without triggering unnecessary code generation for other contracts. Bugfixes: diff --git a/libsolidity/interface/CompilerStack.cpp b/libsolidity/interface/CompilerStack.cpp index 4d3bacabc98a..39977629d69d 100644 --- a/libsolidity/interface/CompilerStack.cpp +++ b/libsolidity/interface/CompilerStack.cpp @@ -250,6 +250,12 @@ void CompilerStack::setModelCheckerSettings(ModelCheckerSettings _settings) m_modelCheckerSettings = _settings; } +void CompilerStack::selectContracts(ContractSelection const& _selectedContracts) +{ + solAssert(m_stackState < ParsedAndImported, "Must request outputs before parsing."); + m_selectedContracts = _selectedContracts; +} + void CompilerStack::setLibraries(std::map const& _libraries) { solAssert(m_stackState < ParsedAndImported, "Must set libraries before parsing."); @@ -315,8 +321,7 @@ void CompilerStack::reset(bool _keepSettings) m_evmVersion = langutil::EVMVersion(); m_eofVersion.reset(); m_modelCheckerSettings = ModelCheckerSettings{}; - m_requestedContractNames.clear(); - m_irOutputSelection = IROutputSelection::None; + m_selectedContracts.clear(); m_revertStrings = RevertStrings::Default; m_optimiserSettings = OptimiserSettings::minimal(); m_metadataLiteralSources = false; @@ -690,21 +695,21 @@ bool CompilerStack::parseAndAnalyze(State _stopAfter) bool CompilerStack::isRequestedSource(std::string const& _sourceName) const { return - m_requestedContractNames.empty() || - m_requestedContractNames.count("") || - m_requestedContractNames.count(_sourceName); + m_selectedContracts.empty() || + m_selectedContracts.count("") || + m_selectedContracts.count(_sourceName); } bool CompilerStack::isRequestedContract(ContractDefinition const& _contract) const { - /// In case nothing was specified in outputSelection. - if (m_requestedContractNames.empty()) + /// In case nothing was specified in selectedContracts. + if (m_selectedContracts.empty()) return true; for (auto const& key: std::vector{"", _contract.sourceUnitName()}) { - auto const& it = m_requestedContractNames.find(key); - if (it != m_requestedContractNames.end()) + auto const& it = m_selectedContracts.find(key); + if (it != m_selectedContracts.end()) if (it->second.count(_contract.name()) || it->second.count("")) return true; } @@ -712,6 +717,28 @@ bool CompilerStack::isRequestedContract(ContractDefinition const& _contract) con return false; } +CompilerStack::PipelineConfig CompilerStack::requestedPipelineConfig(ContractDefinition const& _contract) const +{ + static PipelineConfig constexpr defaultPipelineConfig = PipelineConfig{ + false, // irCodegen + false, // irOptimization + true, // bytecode + }; + + // If nothing was explicitly selected, all contracts are selected by default. + if (m_selectedContracts.empty()) + return defaultPipelineConfig; + + PipelineConfig combinedConfig; + for (std::string const& sourceUnitName: {""s, _contract.sourceUnitName()}) + if (m_selectedContracts.count(sourceUnitName) != 0) + for (std::string const& contractName: {""s, _contract.name()}) + if (m_selectedContracts.at(sourceUnitName).count(contractName) != 0) + combinedConfig = combinedConfig | m_selectedContracts.at(sourceUnitName).at(contractName); + + return combinedConfig; +} + bool CompilerStack::compile(State _stopAfter) { m_stopAfter = _stopAfter; @@ -730,20 +757,13 @@ bool CompilerStack::compile(State _stopAfter) if (auto contract = dynamic_cast(node.get())) if (isRequestedContract(*contract)) { + PipelineConfig pipelineConfig = requestedPipelineConfig(*contract); + try { - // NOTE: Bytecode generation via IR always uses Contract::yulIROptimized. - // When optimization is not enabled, that member simply contains unoptimized code. - bool needIROutput = - (m_generateEvmBytecode && m_viaIR) || - m_irOutputSelection != IROutputSelection::None; - bool needUnoptimizedIROutputOnly = - !(m_generateEvmBytecode && m_viaIR) && - m_irOutputSelection != IROutputSelection::UnoptimizedAndOptimized; - - if (needIROutput) - generateIR(*contract, needUnoptimizedIROutputOnly); - if (m_generateEvmBytecode) + if (pipelineConfig.needIR(m_viaIR)) + generateIR(*contract, pipelineConfig.needIRCodegenOnly(m_viaIR)); + if (pipelineConfig.needBytecode()) { if (m_viaIR) generateEVMFromIR(*contract); diff --git a/libsolidity/interface/CompilerStack.h b/libsolidity/interface/CompilerStack.h index 2b891293b3e0..8ce2c5d62dfe 100644 --- a/libsolidity/interface/CompilerStack.h +++ b/libsolidity/interface/CompilerStack.h @@ -133,12 +133,54 @@ class CompilerStack: public langutil::CharStreamProvider, public evmasm::Abstrac SolidityAST, }; - enum class IROutputSelection { - None, - UnoptimizedOnly, - UnoptimizedAndOptimized, + /// Indicates which stages of the compilation pipeline were explicitly requested and provides + /// logic to determine which ones are effectively needed to accomplish that. + /// Note that parsing and analysis are not selectable, since they cannot be skipped. + struct PipelineConfig + { + bool irCodegen = false; ///< Want IR output straight from code generator. + bool irOptimization = false; ///< Want reparsed IR that went through YulStack. May be optimized or not, depending on settings. + bool bytecode = false; ///< Want EVM-level outputs, especially EVM assembly and bytecode. May be optimized or not, depending on settings. + + bool needIR(bool _viaIR) const + { + return + irCodegen || + irOptimization || + (bytecode && _viaIR); + } + + bool needIRCodegenOnly(bool _viaIR) const + { + return !(bytecode && _viaIR) && !irOptimization; + } + + bool needBytecode() const + { + return bytecode; + } + + PipelineConfig operator|(PipelineConfig const& _other) const + { + return { + irCodegen || _other.irCodegen, + irOptimization || _other.irOptimization, + bytecode || _other.bytecode, + }; + } + + bool operator!=(PipelineConfig const& _other) const { return !(*this == _other); } + bool operator==(PipelineConfig const& _other) const + { + return + irCodegen == _other.irCodegen && + irOptimization == _other.irOptimization && + bytecode == _other.bytecode; + } }; + using ContractSelection = std::map>; + /// Creates a new compiler stack. /// @param _readFile callback used to read files for import statements. Must return /// and must not emit exceptions. @@ -193,26 +235,13 @@ class CompilerStack: public langutil::CharStreamProvider, public evmasm::Abstrac /// Set model checker settings. void setModelCheckerSettings(ModelCheckerSettings _settings); - /// Sets the requested contract names by source. - /// If empty, no filtering is performed and every contract - /// found in the supplied sources is compiled. - /// Names are cleared iff @a _contractNames is missing. - void setRequestedContractNames(std::map> const& _contractNames = std::map>{}) - { - m_requestedContractNames = _contractNames; - } - - /// Enable EVM Bytecode generation. This is enabled by default. - void enableEvmBytecodeGeneration(bool _enable = true) { m_generateEvmBytecode = _enable; } - - /// Enable generation of Yul IR code so that IR output can be safely requested for all contracts. - /// Note that IR may also be implicitly generated when not requested. In particular - /// @a setViaIR(true) requires access to the IR outputs for bytecode generation. - void requestIROutputs(IROutputSelection _selection = IROutputSelection::UnoptimizedAndOptimized) - { - solAssert(m_stackState < ParsedAndImported); - m_irOutputSelection = _selection; - } + /// Sets names of the contracts from each source that should be compiled. + /// If empty, no filtering is performed and every contract found in the supplied sources goes + /// through the default pipeline stages (bytecode-only, no IR). + /// Source/contract names are not validated - ones that do not exist are ignored. + /// The empty source/contract name can be used as a wildcard that matches all sources/contracts. + /// If a contract matches more than one entry, the pipeline selection from all matches is combined. + void selectContracts(ContractSelection const& _selectedContracts); /// @arg _metadataLiteralSources When true, store sources as literals in the contract metadata. /// Must be set before parsing. @@ -450,6 +479,11 @@ class CompilerStack: public langutil::CharStreamProvider, public evmasm::Abstrac /// @returns true if the contract is requested to be compiled. bool isRequestedContract(ContractDefinition const& _contract) const; + /// @returns The effective pipeline configuration for a given contract. + /// Applies defaults for contracts that were not explicitly selected and combines + /// multiple entries if the contact is matched by wildcards. + PipelineConfig requestedPipelineConfig(ContractDefinition const& _contract) const; + /// Perform the analysis steps of legacy language mode. /// @returns false on error. bool analyzeLegacy(bool _noErrorsSoFar); @@ -554,9 +588,7 @@ class CompilerStack: public langutil::CharStreamProvider, public evmasm::Abstrac langutil::EVMVersion m_evmVersion; std::optional m_eofVersion; ModelCheckerSettings m_modelCheckerSettings; - std::map> m_requestedContractNames; - bool m_generateEvmBytecode = true; - IROutputSelection m_irOutputSelection = IROutputSelection::None; + ContractSelection m_selectedContracts; std::map m_libraries; ImportRemapper m_importRemapper; std::map m_sources; diff --git a/libsolidity/interface/StandardCompiler.cpp b/libsolidity/interface/StandardCompiler.cpp index 34c9f21a003e..d8ce4f2d0c7a 100644 --- a/libsolidity/interface/StandardCompiler.cpp +++ b/libsolidity/interface/StandardCompiler.cpp @@ -150,21 +150,6 @@ Json formatErrorWithException( return error; } -std::map> requestedContractNames(Json const& _outputSelection) -{ - std::map> contracts; - for (auto const& [sourceName, _]: _outputSelection.items()) - { - std::string key = (sourceName == "*") ? "" : sourceName; - for (auto const& [contractName, _]: _outputSelection[sourceName].items()) - { - std::string value = (contractName == "*") ? "" : contractName; - contracts[key].insert(value); - } - } - return contracts; -} - /// Returns true iff @a _hash (hex with 0x prefix) is the Keccak256 hash of the binary data in @a _content. bool hashMatchesContent(std::string const& _hash, std::string const& _content) { @@ -298,26 +283,45 @@ bool isEvmBytecodeRequested(Json const& _outputSelection) return false; } -/// @returns The IR output selection for CompilerStack, based on outputs requested in the JSON. +/// @returns The set of selected contracts, along with their compiler pipeline configuration, based +/// on outputs requested in the JSON. Translates wildcards to the ones understood by CompilerStack. /// Note that as an exception, '*' does not yet match "ir", "irAst", "irOptimized" or "irOptimizedAst". -CompilerStack::IROutputSelection irOutputSelection(Json const& _outputSelection) +CompilerStack::ContractSelection pipelineConfig( + Json const& _jsonOutputSelection +) { - if (!_outputSelection.is_object()) - return CompilerStack::IROutputSelection::None; + if (!_jsonOutputSelection.is_object()) + return {}; - CompilerStack::IROutputSelection selection = CompilerStack::IROutputSelection::None; - for (auto const& fileRequests: _outputSelection) - for (auto const& requests: fileRequests) - for (auto const& request: requests) + CompilerStack::ContractSelection contractSelection; + for (auto const& [sourceUnitName, jsonOutputSelectionForSource]: _jsonOutputSelection.items()) + { + solAssert(jsonOutputSelectionForSource.is_object()); + for (auto const& [contractName, jsonOutputSelectionForContract]: jsonOutputSelectionForSource.items()) + { + solAssert(jsonOutputSelectionForContract.is_array()); + CompilerStack::PipelineConfig pipelineForContract; + for (Json const& request: jsonOutputSelectionForContract) { - if (request == "irOptimized" || request == "irOptimizedAst" || request == "yulCFGJson") - return CompilerStack::IROutputSelection::UnoptimizedAndOptimized; - - if (request == "ir" || request == "irAst") - selection = CompilerStack::IROutputSelection::UnoptimizedOnly; + solAssert(request.is_string()); + pipelineForContract.irOptimization = + pipelineForContract.irOptimization || + request == "irOptimized" || + request == "irOptimizedAst" || + request == "yulCFGJson"; + pipelineForContract.irCodegen = + pipelineForContract.irCodegen || + pipelineForContract.irOptimization || + request == "ir" || + request == "irAst"; + pipelineForContract.bytecode = isEvmBytecodeRequested(_jsonOutputSelection); } - - return selection; + std::string key = (sourceUnitName == "*") ? "" : sourceUnitName; + std::string value = (contractName == "*") ? "" : contractName; + contractSelection[key][value] = pipelineForContract; + } + } + return contractSelection; } Json formatLinkReferences(std::map const& linkReferences) @@ -1321,12 +1325,9 @@ Json StandardCompiler::compileSolidity(StandardCompiler::InputsAndSettings _inpu compilerStack.useMetadataLiteralSources(_inputsAndSettings.metadataLiteralSources); compilerStack.setMetadataFormat(_inputsAndSettings.metadataFormat); compilerStack.setMetadataHash(_inputsAndSettings.metadataHash); - compilerStack.setRequestedContractNames(requestedContractNames(_inputsAndSettings.outputSelection)); + compilerStack.selectContracts(pipelineConfig(_inputsAndSettings.outputSelection)); compilerStack.setModelCheckerSettings(_inputsAndSettings.modelCheckerSettings); - compilerStack.enableEvmBytecodeGeneration(isEvmBytecodeRequested(_inputsAndSettings.outputSelection)); - compilerStack.requestIROutputs(irOutputSelection(_inputsAndSettings.outputSelection)); - Json errors = std::move(_inputsAndSettings.errors); bool const binariesRequested = isBinaryRequested(_inputsAndSettings.outputSelection); diff --git a/solc/CommandLineInterface.cpp b/solc/CommandLineInterface.cpp index 2d815facc18d..b791de3ef361 100644 --- a/solc/CommandLineInterface.cpp +++ b/solc/CommandLineInterface.cpp @@ -889,14 +889,16 @@ void CommandLineInterface::compile() if (m_options.output.debugInfoSelection.has_value()) m_compiler->selectDebugInfo(m_options.output.debugInfoSelection.value()); - CompilerStack::IROutputSelection irOutputSelection = CompilerStack::IROutputSelection::None; - if (m_options.compiler.outputs.irOptimized || m_options.compiler.outputs.irOptimizedAstJson || m_options.compiler.outputs.yulCFGJson) - irOutputSelection = CompilerStack::IROutputSelection::UnoptimizedAndOptimized; - else if (m_options.compiler.outputs.ir || m_options.compiler.outputs.irAstJson) - irOutputSelection = CompilerStack::IROutputSelection::UnoptimizedOnly; - - m_compiler->requestIROutputs(irOutputSelection); - m_compiler->enableEvmBytecodeGeneration( + CompilerStack::PipelineConfig pipelineConfig; + pipelineConfig.irOptimization = + m_options.compiler.outputs.irOptimized || + m_options.compiler.outputs.irOptimizedAstJson || + m_options.compiler.outputs.yulCFGJson; + pipelineConfig.irCodegen = + pipelineConfig.irOptimization || + m_options.compiler.outputs.ir || + m_options.compiler.outputs.irAstJson; + pipelineConfig.bytecode = m_options.compiler.estimateGas || m_options.compiler.outputs.asm_ || m_options.compiler.outputs.asmJson || @@ -914,8 +916,9 @@ void CommandLineInterface::compile() m_options.compiler.combinedJsonRequests->srcMapRuntime || m_options.compiler.combinedJsonRequests->funDebug || m_options.compiler.combinedJsonRequests->funDebugRuntime - )) - ); + )); + + m_compiler->selectContracts({{"", {{"", pipelineConfig}}}}); m_compiler->setOptimiserSettings(m_options.optimiserSettings()); diff --git a/test/libsolidity/SolidityExecutionFramework.cpp b/test/libsolidity/SolidityExecutionFramework.cpp index 27fb39c1217e..57d4d9d9b75b 100644 --- a/test/libsolidity/SolidityExecutionFramework.cpp +++ b/test/libsolidity/SolidityExecutionFramework.cpp @@ -60,7 +60,6 @@ bytes SolidityExecutionFramework::multiSourceCompileContract( m_compiler.setEVMVersion(m_evmVersion); m_compiler.setEOFVersion(m_eofVersion); m_compiler.setOptimiserSettings(m_optimiserSettings); - m_compiler.enableEvmBytecodeGeneration(true); m_compiler.setViaIR(m_compileViaYul); m_compiler.setRevertStringBehaviour(m_revertStrings); if (!m_appendCBORMetadata) { From 8d8ac1c376c75ab1f5a9a1b8b6d0a3e18d0f47af Mon Sep 17 00:00:00 2001 From: rodiazet Date: Tue, 1 Oct 2024 22:29:34 +0200 Subject: [PATCH 0467/1022] eof: Pass `eofVersion` flag to `EVMDialect` --- liblangutil/EVMVersion.cpp | 26 +- liblangutil/EVMVersion.h | 2 +- libsolidity/ast/ASTJsonExporter.cpp | 11 +- libsolidity/ast/ASTJsonImporter.cpp | 11 +- libsolidity/ast/ASTJsonImporter.h | 6 +- libsolidity/codegen/CompilerContext.cpp | 3 +- libsolidity/codegen/ContractCompiler.cpp | 1 + libsolidity/interface/CompilerStack.cpp | 7 +- libsolidity/parsing/Parser.cpp | 2 +- libsolidity/parsing/Parser.h | 7 +- libyul/AsmAnalysis.cpp | 3 +- libyul/ObjectOptimizer.cpp | 8 +- libyul/ObjectOptimizer.h | 3 +- libyul/YulStack.cpp | 13 +- libyul/backends/evm/AsmCodeGen.cpp | 3 +- libyul/backends/evm/AsmCodeGen.h | 1 + libyul/backends/evm/EVMDialect.cpp | 232 +++++++++--------- libyul/backends/evm/EVMDialect.h | 8 +- libyul/backends/evm/NoOutputAssembly.cpp | 2 +- test/libsolidity/Assembly.cpp | 6 +- test/libsolidity/MemoryGuardTest.cpp | 2 +- .../SolidityExpressionCompiler.cpp | 6 +- test/libsolidity/SolidityParser.cpp | 3 +- test/libyul/Common.cpp | 15 +- test/libyul/Common.h | 2 +- test/libyul/CompilabilityChecker.cpp | 6 +- test/libyul/ControlFlowGraphTest.cpp | 6 +- test/libyul/ControlFlowSideEffectsTest.cpp | 3 +- test/libyul/EVMCodeTransformTest.cpp | 4 +- test/libyul/FunctionSideEffects.cpp | 3 +- test/libyul/KnowledgeBaseTest.cpp | 3 +- test/libyul/ObjectParser.cpp | 3 +- test/libyul/Parser.cpp | 129 ++++++---- test/libyul/SSAControlFlowGraphTest.cpp | 6 +- test/libyul/StackLayoutGeneratorTest.cpp | 6 +- test/libyul/SyntaxTest.cpp | 6 +- test/libyul/YulInterpreterTest.cpp | 2 +- test/libyul/YulOptimizerTest.cpp | 6 +- .../tools/ossfuzz/StackReuseCodegenFuzzer.cpp | 3 +- test/tools/ossfuzz/strictasm_diff_ossfuzz.cpp | 5 +- test/tools/ossfuzz/yulProtoFuzzer.cpp | 3 +- test/tools/ossfuzz/yulProto_diff_ossfuzz.cpp | 9 +- test/tools/yulopti.cpp | 2 +- test/tools/yulrun.cpp | 2 +- tools/yulPhaser/Program.cpp | 3 +- 45 files changed, 371 insertions(+), 222 deletions(-) diff --git a/liblangutil/EVMVersion.cpp b/liblangutil/EVMVersion.cpp index 438932a1cdaa..6435e0f15455 100644 --- a/liblangutil/EVMVersion.cpp +++ b/liblangutil/EVMVersion.cpp @@ -26,23 +26,26 @@ using namespace solidity; using namespace solidity::evmasm; using namespace solidity::langutil; -bool EVMVersion::hasOpcode(Instruction _opcode) const +bool EVMVersion::hasOpcode(Instruction _opcode, std::optional _eofVersion) const { + // EOF version can be only defined since prague + assert(!_eofVersion.has_value() || this->m_version >= prague()); + switch (_opcode) { case Instruction::RETURNDATACOPY: case Instruction::RETURNDATASIZE: return supportsReturndata(); case Instruction::STATICCALL: - return hasStaticCall(); + return !_eofVersion.has_value() && hasStaticCall(); case Instruction::SHL: case Instruction::SHR: case Instruction::SAR: return hasBitwiseShifting(); case Instruction::CREATE2: - return hasCreate2(); + return !_eofVersion.has_value() && hasCreate2(); case Instruction::EXTCODEHASH: - return hasExtCodeHash(); + return !_eofVersion.has_value() && hasExtCodeHash(); case Instruction::CHAINID: return hasChainID(); case Instruction::SELFBALANCE: @@ -58,6 +61,21 @@ bool EVMVersion::hasOpcode(Instruction _opcode) const case Instruction::TSTORE: case Instruction::TLOAD: return supportsTransientStorage(); + // Instructions below are deprecated in EOF + case Instruction::CALL: + case Instruction::CALLCODE: + case Instruction::DELEGATECALL: + case Instruction::SELFDESTRUCT: + case Instruction::JUMP: + case Instruction::JUMPI: + case Instruction::PC: + case Instruction::CREATE: + case Instruction::CODESIZE: + case Instruction::CODECOPY: + case Instruction::EXTCODESIZE: + case Instruction::EXTCODECOPY: + case Instruction::GAS: + return !_eofVersion.has_value(); default: return true; } diff --git a/liblangutil/EVMVersion.h b/liblangutil/EVMVersion.h index 774268917483..3d58fed43709 100644 --- a/liblangutil/EVMVersion.h +++ b/liblangutil/EVMVersion.h @@ -124,7 +124,7 @@ class EVMVersion: bool hasMcopy() const { return *this >= cancun(); } bool supportsTransientStorage() const { return *this >= cancun(); } - bool hasOpcode(evmasm::Instruction _opcode) const; + bool hasOpcode(evmasm::Instruction _opcode, std::optional _eofVersion) const; /// Whether we have to retain the costs for the call opcode itself (false), /// or whether we can just forward easily all remaining gas (true). diff --git a/libsolidity/ast/ASTJsonExporter.cpp b/libsolidity/ast/ASTJsonExporter.cpp index 910cc257eb4a..7183c64a3f18 100644 --- a/libsolidity/ast/ASTJsonExporter.cpp +++ b/libsolidity/ast/ASTJsonExporter.cpp @@ -664,12 +664,21 @@ bool ASTJsonExporter::visit(InlineAssembly const& _node) for (Json& it: externalReferences | ranges::views::values) externalReferencesJson.emplace_back(std::move(it)); + auto const& evmDialect = dynamic_cast(_node.dialect()); + std::vector> attributes = { std::make_pair("AST", Json(yul::AsmJsonConverter(sourceIndexFromLocation(_node.location()))(_node.operations().root()))), std::make_pair("externalReferences", std::move(externalReferencesJson)), - std::make_pair("evmVersion", dynamic_cast(_node.dialect()).evmVersion().name()) + std::make_pair("evmVersion", evmDialect.evmVersion().name()) }; + // TODO: Add test in test/linsolidity/ASTJSON/assembly. This requires adding support for eofVersion in ASTJSONTest + if (evmDialect.eofVersion()) + { + solAssert(*evmDialect.eofVersion() > 0); + attributes.push_back(std::make_pair("eofVersion", *evmDialect.eofVersion())); + } + if (_node.flags()) { Json flags = Json::array(); diff --git a/libsolidity/ast/ASTJsonImporter.cpp b/libsolidity/ast/ASTJsonImporter.cpp index 8d72b41f7579..ee52bf53c27d 100644 --- a/libsolidity/ast/ASTJsonImporter.cpp +++ b/libsolidity/ast/ASTJsonImporter.cpp @@ -720,7 +720,16 @@ ASTPointer ASTJsonImporter::createInlineAssembly(Json const& _no astAssert(evmVersion.has_value(), "Invalid EVM version!"); astAssert(m_evmVersion == evmVersion, "Imported tree evm version differs from configured evm version!"); - yul::Dialect const& dialect = yul::EVMDialect::strictAssemblyForEVM(evmVersion.value()); + // TODO: Add test in test/linsolidity/ASTJSON/assembly. This requires adding support for eofVersion in ASTJSONTest + std::optional eofVersion; + if (auto const it = _node.find("eofVersion"); it != _node.end()) + { + eofVersion = it->get(); + astAssert(eofVersion > 0); + } + astAssert(m_eofVersion == eofVersion, "Imported tree EOF version differs from configured EOF version!"); + + yul::Dialect const& dialect = yul::EVMDialect::strictAssemblyForEVM(evmVersion.value(), eofVersion); ASTPointer>> flags; if (_node.contains("flags")) { diff --git a/libsolidity/ast/ASTJsonImporter.h b/libsolidity/ast/ASTJsonImporter.h index 943415df93ca..e4a7c2da3fe9 100644 --- a/libsolidity/ast/ASTJsonImporter.h +++ b/libsolidity/ast/ASTJsonImporter.h @@ -40,8 +40,8 @@ namespace solidity::frontend class ASTJsonImporter { public: - ASTJsonImporter(langutil::EVMVersion _evmVersion) - :m_evmVersion(_evmVersion) + ASTJsonImporter(langutil::EVMVersion _evmVersion, std::optional _eofVersion) + :m_evmVersion(_evmVersion), m_eofVersion(_eofVersion) {} /// Converts the AST from JSON-format to ASTPointer @@ -166,6 +166,8 @@ class ASTJsonImporter std::set m_usedIDs; /// Configured EVM version langutil::EVMVersion m_evmVersion; + /// Configured EOF version. Equals std::nullopt if non-EOF + std::optional m_eofVersion; }; } diff --git a/libsolidity/codegen/CompilerContext.cpp b/libsolidity/codegen/CompilerContext.cpp index 83b4589fe982..4a0f636dc974 100644 --- a/libsolidity/codegen/CompilerContext.cpp +++ b/libsolidity/codegen/CompilerContext.cpp @@ -436,7 +436,7 @@ void CompilerContext::appendInlineAssembly( ErrorList errors; ErrorReporter errorReporter(errors); langutil::CharStream charStream(_assembly, _sourceName); - yul::EVMDialect const& dialect = yul::EVMDialect::strictAssemblyForEVM(m_evmVersion); + yul::EVMDialect const& dialect = yul::EVMDialect::strictAssemblyForEVM(m_evmVersion, std::nullopt); std::optional locationOverride; if (!_system) locationOverride = m_asm->currentSourceLocation(); @@ -522,6 +522,7 @@ void CompilerContext::appendInlineAssembly( analysisInfo, *m_asm, m_evmVersion, + std::nullopt, identifierAccess.generateCode, _system, _optimiserSettings.optimizeStackAllocation diff --git a/libsolidity/codegen/ContractCompiler.cpp b/libsolidity/codegen/ContractCompiler.cpp index 5ed6e8f96418..96b1ea54823d 100644 --- a/libsolidity/codegen/ContractCompiler.cpp +++ b/libsolidity/codegen/ContractCompiler.cpp @@ -958,6 +958,7 @@ bool ContractCompiler::visit(InlineAssembly const& _inlineAssembly) *analysisInfo, *m_context.assemblyPtr(), m_context.evmVersion(), + std::nullopt, identifierAccessCodeGen, false, m_optimiserSettings.optimizeStackAllocation diff --git a/libsolidity/interface/CompilerStack.cpp b/libsolidity/interface/CompilerStack.cpp index 39977629d69d..c68df205f941 100644 --- a/libsolidity/interface/CompilerStack.cpp +++ b/libsolidity/interface/CompilerStack.cpp @@ -357,7 +357,7 @@ bool CompilerStack::parse() try { - Parser parser{m_errorReporter, m_evmVersion}; + Parser parser{m_errorReporter, m_evmVersion, m_eofVersion}; std::vector sourcesToParse; for (auto const& s: m_sources) @@ -427,7 +427,8 @@ bool CompilerStack::parse() void CompilerStack::importASTs(std::map const& _sources) { solAssert(m_stackState == Empty, "Must call importASTs only before the SourcesSet state."); - std::map> reconstructedSources = ASTJsonImporter(m_evmVersion).jsonToSourceUnit(_sources); + std::map> reconstructedSources = + ASTJsonImporter(m_evmVersion, m_eofVersion).jsonToSourceUnit(_sources); for (auto& src: reconstructedSources) { solUnimplementedAssert(!src.second->experimentalSolidity()); @@ -896,7 +897,7 @@ Json CompilerStack::generatedSources(std::string const& _contractName, bool _run ErrorList errors; ErrorReporter errorReporter(errors); CharStream charStream(source, sourceName); - yul::EVMDialect const& dialect = yul::EVMDialect::strictAssemblyForEVM(m_evmVersion); + yul::EVMDialect const& dialect = yul::EVMDialect::strictAssemblyForEVM(m_evmVersion, m_eofVersion); std::shared_ptr parserResult = yul::Parser{errorReporter, dialect}.parse(charStream); solAssert(parserResult); sources[0]["ast"] = yul::AsmJsonConverter{sourceIndex}(parserResult->root()); diff --git a/libsolidity/parsing/Parser.cpp b/libsolidity/parsing/Parser.cpp index 208d7446395b..13303170d6ad 100644 --- a/libsolidity/parsing/Parser.cpp +++ b/libsolidity/parsing/Parser.cpp @@ -1448,7 +1448,7 @@ ASTPointer Parser::parseInlineAssembly(ASTPointer con SourceLocation location = currentLocation(); expectToken(Token::Assembly); - yul::Dialect const& dialect = yul::EVMDialect::strictAssemblyForEVM(m_evmVersion); + yul::Dialect const& dialect = yul::EVMDialect::strictAssemblyForEVM(m_evmVersion, m_eofVersion); if (m_scanner->currentToken() == Token::StringLiteral) { if (m_scanner->currentLiteral() != "evmasm") diff --git a/libsolidity/parsing/Parser.h b/libsolidity/parsing/Parser.h index 8f0868ac1172..830df05c27c8 100644 --- a/libsolidity/parsing/Parser.h +++ b/libsolidity/parsing/Parser.h @@ -40,10 +40,12 @@ class Parser: public langutil::ParserBase public: explicit Parser( langutil::ErrorReporter& _errorReporter, - langutil::EVMVersion _evmVersion + langutil::EVMVersion _evmVersion, + std::optional _eofVersion ): ParserBase(_errorReporter), - m_evmVersion(_evmVersion) + m_evmVersion(_evmVersion), + m_eofVersion(_eofVersion) {} ASTPointer parse(langutil::CharStream& _charStream); @@ -247,6 +249,7 @@ class Parser: public langutil::ParserBase /// Flag that signifies whether '_' is parsed as a PlaceholderStatement or a regular identifier. bool m_insideModifier = false; langutil::EVMVersion m_evmVersion; + std::optional m_eofVersion; /// Counter for the next AST node ID int64_t m_currentNodeID = 0; /// Flag that indicates whether experimental mode is enabled in the current source unit diff --git a/libyul/AsmAnalysis.cpp b/libyul/AsmAnalysis.cpp index 64630fa2bee9..cf8c720f6b36 100644 --- a/libyul/AsmAnalysis.cpp +++ b/libyul/AsmAnalysis.cpp @@ -625,7 +625,8 @@ void AsmAnalyzer::expectValidIdentifier(YulName _identifier, SourceLocation cons bool AsmAnalyzer::validateInstructions(std::string const& _instructionIdentifier, langutil::SourceLocation const& _location) { // NOTE: This function uses the default EVM version instead of the currently selected one. - auto const builtin = EVMDialect::strictAssemblyForEVM(EVMVersion{}).builtin(YulName(_instructionIdentifier)); + // TODO: Add EOF support + auto const builtin = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt).builtin(YulName(_instructionIdentifier)); if (builtin && builtin->instruction.has_value()) return validateInstructions(builtin->instruction.value(), _location); else diff --git a/libyul/ObjectOptimizer.cpp b/libyul/ObjectOptimizer.cpp index 3694367c5e32..511fc979ddb0 100644 --- a/libyul/ObjectOptimizer.cpp +++ b/libyul/ObjectOptimizer.cpp @@ -43,13 +43,13 @@ using namespace solidity::util; using namespace solidity::yul; -Dialect const& yul::languageToDialect(Language _language, EVMVersion _version) +Dialect const& yul::languageToDialect(Language _language, EVMVersion _version, std::optional _eofVersion) { switch (_language) { case Language::Assembly: case Language::StrictAssembly: - return EVMDialect::strictAssemblyForEVMObjects(_version); + return EVMDialect::strictAssemblyForEVMObjects(_version, _eofVersion); } util::unreachable(); } @@ -77,7 +77,7 @@ void ObjectOptimizer::optimize(Object& _object, Settings const& _settings, bool ); } - Dialect const& dialect = languageToDialect(_settings.language, _settings.evmVersion); + Dialect const& dialect = languageToDialect(_settings.language, _settings.evmVersion, _settings.eofVersion); std::unique_ptr meter; if (EVMDialect const* evmDialect = dynamic_cast(&dialect)) meter = std::make_unique(*evmDialect, _isCreation, _settings.expectedExecutionsPerDeployment); @@ -158,6 +158,8 @@ std::optional ObjectOptimizer::calculateCacheKey( rawKey += h256(u256(_settings.expectedExecutionsPerDeployment)).asBytes(); rawKey += FixedHash<1>(uint8_t(_isCreation ? 0 : 1)).asBytes(); rawKey += keccak256(_settings.evmVersion.name()).asBytes(); + yulAssert(!_settings.eofVersion.has_value() || *_settings.eofVersion > 0); + rawKey += FixedHash<1>(uint8_t(_settings.eofVersion ? 0 : *_settings.eofVersion)).asBytes(); rawKey += keccak256(_settings.yulOptimiserSteps).asBytes(); rawKey += keccak256(_settings.yulOptimiserCleanupSteps).asBytes(); diff --git a/libyul/ObjectOptimizer.h b/libyul/ObjectOptimizer.h index e570d69c4b8a..b2019d36b206 100644 --- a/libyul/ObjectOptimizer.h +++ b/libyul/ObjectOptimizer.h @@ -38,7 +38,7 @@ enum class Language StrictAssembly, }; -Dialect const& languageToDialect(Language _language, langutil::EVMVersion _version); +Dialect const& languageToDialect(Language _language, langutil::EVMVersion _version, std::optional _eofVersion); /// Encapsulates logic for applying @a yul::OptimiserSuite to a whole hierarchy of Yul objects. /// Also, acts as a transparent cache for optimized objects. @@ -58,6 +58,7 @@ class ObjectOptimizer { Language language; langutil::EVMVersion evmVersion; + std::optional eofVersion; bool optimizeStackAllocation; std::string yulOptimiserSteps; std::string yulOptimiserCleanupSteps; diff --git a/libyul/YulStack.cpp b/libyul/YulStack.cpp index 67bc6d11a586..8b559e23f46d 100644 --- a/libyul/YulStack.cpp +++ b/libyul/YulStack.cpp @@ -57,7 +57,7 @@ bool YulStack::parse(std::string const& _sourceName, std::string const& _source) { m_charStream = std::make_unique(_source, _sourceName); std::shared_ptr scanner = std::make_shared(*m_charStream); - m_parserResult = ObjectParser(m_errorReporter, languageToDialect(m_language, m_evmVersion)).parse(scanner, false); + m_parserResult = ObjectParser(m_errorReporter, languageToDialect(m_language, m_evmVersion, m_eofVersion)).parse(scanner, false); } catch (UnimplementedFeatureError const& _error) { @@ -94,7 +94,7 @@ void YulStack::optimize() { if ( !m_optimiserSettings.runYulOptimiser && - yul::MSizeFinder::containsMSize(languageToDialect(m_language, m_evmVersion), *m_parserResult) + yul::MSizeFinder::containsMSize(languageToDialect(m_language, m_evmVersion, m_eofVersion), *m_parserResult) ) return; @@ -130,6 +130,7 @@ void YulStack::optimize() ObjectOptimizer::Settings{ m_language, m_evmVersion, + m_eofVersion, optimizeStackAllocation, yulOptimiserSteps, yulOptimiserCleanupSteps, @@ -163,7 +164,7 @@ bool YulStack::analyzeParsed(Object& _object) AsmAnalyzer analyzer( *_object.analysisInfo, m_errorReporter, - languageToDialect(m_language, m_evmVersion), + languageToDialect(m_language, m_evmVersion, m_eofVersion), {}, _object.qualifiedDataNames() ); @@ -196,7 +197,7 @@ void YulStack::compileEVM(AbstractAssembly& _assembly, bool _optimize) const { case Language::Assembly: case Language::StrictAssembly: - dialect = &EVMDialect::strictAssemblyForEVMObjects(m_evmVersion); + dialect = &EVMDialect::strictAssemblyForEVMObjects(m_evmVersion, m_eofVersion); break; default: yulAssert(false, "Invalid language."); @@ -316,7 +317,7 @@ YulStack::assembleEVMWithDeployed(std::optional _deployName) // it with the minimal steps required to avoid "stack too deep". bool optimize = m_optimiserSettings.optimizeStackAllocation || ( !m_optimiserSettings.runYulOptimiser && - !yul::MSizeFinder::containsMSize(languageToDialect(m_language, m_evmVersion), *m_parserResult) + !yul::MSizeFinder::containsMSize(languageToDialect(m_language, m_evmVersion, m_eofVersion), *m_parserResult) ); try { @@ -385,7 +386,7 @@ Json YulStack::cfgJson() const // NOTE: The block Ids are reset for each object std::unique_ptr controlFlow = SSAControlFlowGraphBuilder::build( *_object.analysisInfo.get(), - languageToDialect(m_language, m_evmVersion), + languageToDialect(m_language, m_evmVersion, m_eofVersion), _object.code()->root() ); YulControlFlowGraphExporter exporter(*controlFlow); diff --git a/libyul/backends/evm/AsmCodeGen.cpp b/libyul/backends/evm/AsmCodeGen.cpp index 645d1fd87bc1..91d06e2f0850 100644 --- a/libyul/backends/evm/AsmCodeGen.cpp +++ b/libyul/backends/evm/AsmCodeGen.cpp @@ -38,6 +38,7 @@ void CodeGenerator::assemble( AsmAnalysisInfo& _analysisInfo, evmasm::Assembly& _assembly, langutil::EVMVersion _evmVersion, + std::optional _eofVersion, ExternalIdentifierAccess::CodeGenerator _identifierAccessCodeGen, bool _useNamedLabelsForFunctions, bool _optimizeStackAllocation @@ -49,7 +50,7 @@ void CodeGenerator::assemble( assemblyAdapter, _analysisInfo, _parsedData, - EVMDialect::strictAssemblyForEVM(_evmVersion), + EVMDialect::strictAssemblyForEVM(_evmVersion, _eofVersion), builtinContext, _optimizeStackAllocation, _identifierAccessCodeGen, diff --git a/libyul/backends/evm/AsmCodeGen.h b/libyul/backends/evm/AsmCodeGen.h index b79338074957..d7a6b5c928f5 100644 --- a/libyul/backends/evm/AsmCodeGen.h +++ b/libyul/backends/evm/AsmCodeGen.h @@ -44,6 +44,7 @@ class CodeGenerator AsmAnalysisInfo& _analysisInfo, evmasm::Assembly& _assembly, langutil::EVMVersion _evmVersion, + std::optional _eofVersion, ExternalIdentifierAccess::CodeGenerator _identifierAccess = {}, bool _useNamedLabelsForFunctions = false, bool _optimizeStackAllocation = false diff --git a/libyul/backends/evm/EVMDialect.cpp b/libyul/backends/evm/EVMDialect.cpp index dd5cad1dd700..6bfdc9cb9de3 100644 --- a/libyul/backends/evm/EVMDialect.cpp +++ b/libyul/backends/evm/EVMDialect.cpp @@ -177,7 +177,7 @@ std::set createReservedIdentifiers(langutil::EVMVersion _evmVersion) return reserved; } -std::map createBuiltins(langutil::EVMVersion _evmVersion, bool _objectAccess) +std::map createBuiltins(langutil::EVMVersion _evmVersion, std::optional _eofVersion, bool _objectAccess) { // Exclude prevrandao as builtin for VMs before paris and difficulty for VMs after paris. @@ -199,7 +199,7 @@ std::map createBuiltins(langutil::EVMVersion _ev opcode != evmasm::Instruction::JUMP && opcode != evmasm::Instruction::JUMPI && opcode != evmasm::Instruction::JUMPDEST && - _evmVersion.hasOpcode(opcode) && + _evmVersion.hasOpcode(opcode, _eofVersion) && !prevRandaoException(name) ) builtins.emplace(createEVMFunction(_evmVersion, name, opcode)); @@ -235,113 +235,116 @@ std::map createBuiltins(langutil::EVMVersion _ev }) ); - builtins.emplace(createFunction("datasize", 1, 1, SideEffects{}, {LiteralKind::String}, []( - FunctionCall const& _call, - AbstractAssembly& _assembly, - BuiltinContext& _context - ) { - yulAssert(_context.currentObject, "No object available."); - yulAssert(_call.arguments.size() == 1, ""); - Expression const& arg = _call.arguments.front(); - YulName const dataName (formatLiteral(std::get(arg))); - if (_context.currentObject->name == dataName.str()) - _assembly.appendAssemblySize(); - else - { - std::vector subIdPath = - _context.subIDs.count(dataName.str()) == 0 ? - _context.currentObject->pathToSubObject(dataName.str()) : - std::vector{_context.subIDs.at(dataName.str())}; - yulAssert(!subIdPath.empty(), "Could not find assembly object <" + dataName.str() + ">."); - _assembly.appendDataSize(subIdPath); - } - })); - builtins.emplace(createFunction("dataoffset", 1, 1, SideEffects{}, {LiteralKind::String}, []( - FunctionCall const& _call, - AbstractAssembly& _assembly, - BuiltinContext& _context - ) { - yulAssert(_context.currentObject, "No object available."); - yulAssert(_call.arguments.size() == 1, ""); - Expression const& arg = _call.arguments.front(); - YulName const dataName (formatLiteral(std::get(arg))); - if (_context.currentObject->name == dataName.str()) - _assembly.appendConstant(0); - else - { - std::vector subIdPath = - _context.subIDs.count(dataName.str()) == 0 ? - _context.currentObject->pathToSubObject(dataName.str()) : - std::vector{_context.subIDs.at(dataName.str())}; - yulAssert(!subIdPath.empty(), "Could not find assembly object <" + dataName.str() + ">."); - _assembly.appendDataOffset(subIdPath); - } - })); - builtins.emplace(createFunction( - "datacopy", - 3, - 0, - SideEffects{ - false, // movable - true, // movableApartFromEffects - false, // canBeRemoved - false, // canBeRemovedIfNotMSize - true, // cannotLoop - SideEffects::None, // otherState - SideEffects::None, // storage - SideEffects::Write, // memory - SideEffects::None // transientStorage - }, - {}, - []( - FunctionCall const&, - AbstractAssembly& _assembly, - BuiltinContext& - ) { - _assembly.appendInstruction(evmasm::Instruction::CODECOPY); - } - )); - builtins.emplace(createFunction( - "setimmutable", - 3, - 0, - SideEffects{ - false, // movable - false, // movableApartFromEffects - false, // canBeRemoved - false, // canBeRemovedIfNotMSize - true, // cannotLoop - SideEffects::None, // otherState - SideEffects::None, // storage - SideEffects::Write, // memory - SideEffects::None // transientStorage - }, - {std::nullopt, LiteralKind::String, std::nullopt}, - []( + if (!_eofVersion.has_value()) + { + builtins.emplace(createFunction("datasize", 1, 1, SideEffects{}, {LiteralKind::String}, []( FunctionCall const& _call, AbstractAssembly& _assembly, - BuiltinContext& + BuiltinContext& _context ) { - yulAssert(_call.arguments.size() == 3, ""); - auto const identifier = (formatLiteral(std::get(_call.arguments[1]))); - _assembly.appendImmutableAssignment(identifier); - } - )); - builtins.emplace(createFunction( - "loadimmutable", - 1, - 1, - SideEffects{}, - {LiteralKind::String}, - []( + yulAssert(_context.currentObject, "No object available."); + yulAssert(_call.arguments.size() == 1, ""); + Expression const& arg = _call.arguments.front(); + YulName const dataName (formatLiteral(std::get(arg))); + if (_context.currentObject->name == dataName.str()) + _assembly.appendAssemblySize(); + else + { + std::vector subIdPath = + _context.subIDs.count(dataName.str()) == 0 ? + _context.currentObject->pathToSubObject(dataName.str()) : + std::vector{_context.subIDs.at(dataName.str())}; + yulAssert(!subIdPath.empty(), "Could not find assembly object <" + dataName.str() + ">."); + _assembly.appendDataSize(subIdPath); + } + })); + builtins.emplace(createFunction("dataoffset", 1, 1, SideEffects{}, {LiteralKind::String}, []( FunctionCall const& _call, AbstractAssembly& _assembly, - BuiltinContext& + BuiltinContext& _context ) { + yulAssert(_context.currentObject, "No object available."); yulAssert(_call.arguments.size() == 1, ""); - _assembly.appendImmutable(formatLiteral(std::get(_call.arguments.front()))); - } - )); + Expression const& arg = _call.arguments.front(); + YulName const dataName (formatLiteral(std::get(arg))); + if (_context.currentObject->name == dataName.str()) + _assembly.appendConstant(0); + else + { + std::vector subIdPath = + _context.subIDs.count(dataName.str()) == 0 ? + _context.currentObject->pathToSubObject(dataName.str()) : + std::vector{_context.subIDs.at(dataName.str())}; + yulAssert(!subIdPath.empty(), "Could not find assembly object <" + dataName.str() + ">."); + _assembly.appendDataOffset(subIdPath); + } + })); + builtins.emplace(createFunction( + "datacopy", + 3, + 0, + SideEffects{ + false, // movable + true, // movableApartFromEffects + false, // canBeRemoved + false, // canBeRemovedIfNotMSize + true, // cannotLoop + SideEffects::None, // otherState + SideEffects::None, // storage + SideEffects::Write, // memory + SideEffects::None // transientStorage + }, + {}, + []( + FunctionCall const&, + AbstractAssembly& _assembly, + BuiltinContext& + ) { + _assembly.appendInstruction(evmasm::Instruction::CODECOPY); + } + )); + builtins.emplace(createFunction( + "setimmutable", + 3, + 0, + SideEffects{ + false, // movable + false, // movableApartFromEffects + false, // canBeRemoved + false, // canBeRemovedIfNotMSize + true, // cannotLoop + SideEffects::None, // otherState + SideEffects::None, // storage + SideEffects::Write, // memory + SideEffects::None // transientStorage + }, + {std::nullopt, LiteralKind::String, std::nullopt}, + []( + FunctionCall const& _call, + AbstractAssembly& _assembly, + BuiltinContext& + ) { + yulAssert(_call.arguments.size() == 3, ""); + auto const identifier = (formatLiteral(std::get(_call.arguments[1]))); + _assembly.appendImmutableAssignment(identifier); + } + )); + builtins.emplace(createFunction( + "loadimmutable", + 1, + 1, + SideEffects{}, + {LiteralKind::String}, + []( + FunctionCall const& _call, + AbstractAssembly& _assembly, + BuiltinContext& + ) { + yulAssert(_call.arguments.size() == 1, ""); + _assembly.appendImmutable(formatLiteral(std::get(_call.arguments.front()))); + } + )); + } } return builtins; } @@ -355,10 +358,11 @@ std::regex const& verbatimPattern() } -EVMDialect::EVMDialect(langutil::EVMVersion _evmVersion, bool _objectAccess): +EVMDialect::EVMDialect(langutil::EVMVersion _evmVersion, std::optional _eofVersion, bool _objectAccess): m_objectAccess(_objectAccess), m_evmVersion(_evmVersion), - m_functions(createBuiltins(_evmVersion, _objectAccess)), + m_eofVersion(_eofVersion), + m_functions(createBuiltins(_evmVersion, _eofVersion, _objectAccess)), m_reserved(createReservedIdentifiers(_evmVersion)) { } @@ -386,22 +390,22 @@ bool EVMDialect::reservedIdentifier(YulName _name) const return m_reserved.count(_name) != 0; } -EVMDialect const& EVMDialect::strictAssemblyForEVM(langutil::EVMVersion _version) +EVMDialect const& EVMDialect::strictAssemblyForEVM(langutil::EVMVersion _evmVersion, std::optional _eofVersion) { - static std::map> dialects; + static std::map>, std::unique_ptr> dialects; static YulStringRepository::ResetCallback callback{[&] { dialects.clear(); }}; - if (!dialects[_version]) - dialects[_version] = std::make_unique(_version, false); - return *dialects[_version]; + if (!dialects[{_evmVersion, _eofVersion}]) + dialects[{_evmVersion, _eofVersion}] = std::make_unique(_evmVersion, _eofVersion, false); + return *dialects[{_evmVersion, _eofVersion}]; } -EVMDialect const& EVMDialect::strictAssemblyForEVMObjects(langutil::EVMVersion _version) +EVMDialect const& EVMDialect::strictAssemblyForEVMObjects(langutil::EVMVersion _evmVersion, std::optional _eofVersion) { - static std::map> dialects; + static std::map>, std::unique_ptr> dialects; static YulStringRepository::ResetCallback callback{[&] { dialects.clear(); }}; - if (!dialects[_version]) - dialects[_version] = std::make_unique(_version, true); - return *dialects[_version]; + if (!dialects[{_evmVersion, _eofVersion}]) + dialects[{_evmVersion, _eofVersion}] = std::make_unique(_evmVersion, _eofVersion, true); + return *dialects[{_evmVersion, _eofVersion}]; } SideEffects EVMDialect::sideEffectsOfInstruction(evmasm::Instruction _instruction) diff --git a/libyul/backends/evm/EVMDialect.h b/libyul/backends/evm/EVMDialect.h index 3627a7fea9b7..cc064c3a0f1e 100644 --- a/libyul/backends/evm/EVMDialect.h +++ b/libyul/backends/evm/EVMDialect.h @@ -65,7 +65,7 @@ struct BuiltinFunctionForEVM: public BuiltinFunction struct EVMDialect: public Dialect { /// Constructor, should only be used internally. Use the factory functions below. - EVMDialect(langutil::EVMVersion _evmVersion, bool _objectAccess); + EVMDialect(langutil::EVMVersion _evmVersion, std::optional _eofVersion, bool _objectAccess); /// @returns the builtin function of the given name or a nullptr if it is not a builtin function. BuiltinFunctionForEVM const* builtin(YulName _name) const override; @@ -82,10 +82,11 @@ struct EVMDialect: public Dialect BuiltinFunctionForEVM const* storageLoadFunction() const override { return builtin("sload"_yulname); } YulName hashFunction() const override { return "keccak256"_yulname; } - static EVMDialect const& strictAssemblyForEVM(langutil::EVMVersion _version); - static EVMDialect const& strictAssemblyForEVMObjects(langutil::EVMVersion _version); + static EVMDialect const& strictAssemblyForEVM(langutil::EVMVersion _evmVersion, std::optional _eofVersion); + static EVMDialect const& strictAssemblyForEVMObjects(langutil::EVMVersion _evmVersion, std::optional _eofVersion); langutil::EVMVersion evmVersion() const { return m_evmVersion; } + std::optional eofVersion() const { return m_eofVersion; } bool providesObjectAccess() const { return m_objectAccess; } @@ -96,6 +97,7 @@ struct EVMDialect: public Dialect bool const m_objectAccess; langutil::EVMVersion const m_evmVersion; + std::optional m_eofVersion; std::map m_functions; std::map, std::shared_ptr> mutable m_verbatimFunctions; std::set m_reserved; diff --git a/libyul/backends/evm/NoOutputAssembly.cpp b/libyul/backends/evm/NoOutputAssembly.cpp index 04324fa06204..c444a71435c0 100644 --- a/libyul/backends/evm/NoOutputAssembly.cpp +++ b/libyul/backends/evm/NoOutputAssembly.cpp @@ -130,7 +130,7 @@ void NoOutputAssembly::appendImmutableAssignment(std::string const&) } NoOutputEVMDialect::NoOutputEVMDialect(EVMDialect const& _copyFrom): - EVMDialect(_copyFrom.evmVersion(), _copyFrom.providesObjectAccess()) + EVMDialect(_copyFrom.evmVersion(), _copyFrom.eofVersion(), _copyFrom.providesObjectAccess()) { for (auto& fun: m_functions) { diff --git a/test/libsolidity/Assembly.cpp b/test/libsolidity/Assembly.cpp index 03897c454c37..bf1e5caf7c04 100644 --- a/test/libsolidity/Assembly.cpp +++ b/test/libsolidity/Assembly.cpp @@ -56,7 +56,11 @@ evmasm::AssemblyItems compileContract(std::shared_ptr _sourceCode) { ErrorList errors; ErrorReporter errorReporter(errors); - Parser parser(errorReporter, solidity::test::CommonOptions::get().evmVersion()); + Parser parser( + errorReporter, + solidity::test::CommonOptions::get().evmVersion(), + solidity::test::CommonOptions::get().eofVersion() + ); ASTPointer sourceUnit; BOOST_REQUIRE_NO_THROW(sourceUnit = parser.parse(*_sourceCode)); BOOST_CHECK(!!sourceUnit); diff --git a/test/libsolidity/MemoryGuardTest.cpp b/test/libsolidity/MemoryGuardTest.cpp index b2e0b75d367a..08a2814c95e3 100644 --- a/test/libsolidity/MemoryGuardTest.cpp +++ b/test/libsolidity/MemoryGuardTest.cpp @@ -62,7 +62,7 @@ TestCase::TestResult MemoryGuardTest::run(std::ostream& _stream, std::string con ErrorList errors; auto [object, analysisInfo] = yul::test::parse( compiler().yulIR(contractName), - EVMDialect::strictAssemblyForEVMObjects(CommonOptions::get().evmVersion()), + EVMDialect::strictAssemblyForEVMObjects(CommonOptions::get().evmVersion(), CommonOptions::get().eofVersion()), errors ); diff --git a/test/libsolidity/SolidityExpressionCompiler.cpp b/test/libsolidity/SolidityExpressionCompiler.cpp index 4810b01439b2..20983b650990 100644 --- a/test/libsolidity/SolidityExpressionCompiler.cpp +++ b/test/libsolidity/SolidityExpressionCompiler.cpp @@ -108,7 +108,11 @@ bytes compileFirstExpression( { ErrorList errors; ErrorReporter errorReporter(errors); - sourceUnit = Parser(errorReporter, solidity::test::CommonOptions::get().evmVersion()).parse(stream); + sourceUnit = Parser( + errorReporter, + solidity::test::CommonOptions::get().evmVersion(), + solidity::test::CommonOptions::get().eofVersion() + ).parse(stream); if (!sourceUnit) return bytes(); } diff --git a/test/libsolidity/SolidityParser.cpp b/test/libsolidity/SolidityParser.cpp index e0f010c49e17..a0fd1fe94bec 100644 --- a/test/libsolidity/SolidityParser.cpp +++ b/test/libsolidity/SolidityParser.cpp @@ -44,7 +44,8 @@ ASTPointer parseText(std::string const& _source, ErrorList& auto charStream = CharStream(_source, ""); ASTPointer sourceUnit = Parser( errorReporter, - solidity::test::CommonOptions::get().evmVersion() + solidity::test::CommonOptions::get().evmVersion(), + solidity::test::CommonOptions::get().eofVersion() ).parse(charStream); if (!sourceUnit) return ASTPointer(); diff --git a/test/libyul/Common.cpp b/test/libyul/Common.cpp index 7640e4a5ddf7..6562e1743588 100644 --- a/test/libyul/Common.cpp +++ b/test/libyul/Common.cpp @@ -46,7 +46,10 @@ namespace { Dialect const& defaultDialect() { - return yul::EVMDialect::strictAssemblyForEVM(solidity::test::CommonOptions::get().evmVersion()); + return yul::EVMDialect::strictAssemblyForEVM( + solidity::test::CommonOptions::get().evmVersion(), + solidity::test::CommonOptions::get().eofVersion() + ); } } @@ -101,11 +104,11 @@ std::string yul::test::format(std::string const& _source) namespace { -std::map const validDialects = { +std::map)> const validDialects = { { "evm", - [](langutil::EVMVersion _evmVersion) -> yul::Dialect const& - { return yul::EVMDialect::strictAssemblyForEVMObjects(_evmVersion); } + [](langutil::EVMVersion _evmVersion, std::optional _eofVersion) -> yul::Dialect const& + { return yul::EVMDialect::strictAssemblyForEVMObjects(_evmVersion, _eofVersion); } } }; @@ -118,7 +121,7 @@ std::map const } } -yul::Dialect const& yul::test::dialect(std::string const& _name, langutil::EVMVersion _evmVersion) +yul::Dialect const& yul::test::dialect(std::string const& _name, langutil::EVMVersion _evmVersion, std::optional _eofVersion) { if (!validDialects.count(_name)) BOOST_THROW_EXCEPTION(std::runtime_error{ @@ -129,5 +132,5 @@ yul::Dialect const& yul::test::dialect(std::string const& _name, langutil::EVMVe "." }); - return validDialects.at(_name)(_evmVersion); + return validDialects.at(_name)(_evmVersion, _eofVersion); } diff --git a/test/libyul/Common.h b/test/libyul/Common.h index c87f1c68be17..2255272b6b5e 100644 --- a/test/libyul/Common.h +++ b/test/libyul/Common.h @@ -54,6 +54,6 @@ parse(std::string const& _source, Dialect const& _dialect, langutil::ErrorList& Block disambiguate(std::string const& _source); std::string format(std::string const& _source); -solidity::yul::Dialect const& dialect(std::string const& _name, langutil::EVMVersion _evmVersion); +solidity::yul::Dialect const& dialect(std::string const& _name, langutil::EVMVersion _evmVersion, std::optional _eofVersion); } diff --git a/test/libyul/CompilabilityChecker.cpp b/test/libyul/CompilabilityChecker.cpp index 13788b75f8ff..6c86ac21f32f 100644 --- a/test/libyul/CompilabilityChecker.cpp +++ b/test/libyul/CompilabilityChecker.cpp @@ -38,7 +38,11 @@ std::string check(std::string const& _input) auto parsingResult = yul::test::parse(_input); obj.setCode(parsingResult.first, parsingResult.second); BOOST_REQUIRE(obj.hasCode()); - auto functions = CompilabilityChecker(EVMDialect::strictAssemblyForEVM(solidity::test::CommonOptions::get().evmVersion()), obj, true).stackDeficit; + auto functions = CompilabilityChecker( + EVMDialect::strictAssemblyForEVM( + solidity::test::CommonOptions::get().evmVersion(), + solidity::test::CommonOptions::get().eofVersion() + ), obj, true).stackDeficit; std::string out; for (auto const& function: functions) out += function.first.str() + ": " + std::to_string(function.second) + " "; diff --git a/test/libyul/ControlFlowGraphTest.cpp b/test/libyul/ControlFlowGraphTest.cpp index 0060b850efbb..b7264bc0e96d 100644 --- a/test/libyul/ControlFlowGraphTest.cpp +++ b/test/libyul/ControlFlowGraphTest.cpp @@ -45,7 +45,11 @@ ControlFlowGraphTest::ControlFlowGraphTest(std::string const& _filename): { m_source = m_reader.source(); auto dialectName = m_reader.stringSetting("dialect", "evm"); - m_dialect = &dialect(dialectName, solidity::test::CommonOptions::get().evmVersion()); + m_dialect = &dialect( + dialectName, + solidity::test::CommonOptions::get().evmVersion(), + solidity::test::CommonOptions::get().eofVersion() + ); m_expectation = m_reader.simpleExpectations(); } diff --git a/test/libyul/ControlFlowSideEffectsTest.cpp b/test/libyul/ControlFlowSideEffectsTest.cpp index 3ad70f5a02ce..50c69b179dd1 100644 --- a/test/libyul/ControlFlowSideEffectsTest.cpp +++ b/test/libyul/ControlFlowSideEffectsTest.cpp @@ -62,8 +62,9 @@ TestCase::TestResult ControlFlowSideEffectsTest::run(std::ostream& _stream, std: if (!obj.hasCode()) BOOST_THROW_EXCEPTION(std::runtime_error("Parsing input failed.")); + // TODO: Add EOF support ControlFlowSideEffectsCollector sideEffects( - EVMDialect::strictAssemblyForEVMObjects(langutil::EVMVersion()), + EVMDialect::strictAssemblyForEVMObjects(langutil::EVMVersion(), std::nullopt), obj.code()->root() ); m_obtainedResult.clear(); diff --git a/test/libyul/EVMCodeTransformTest.cpp b/test/libyul/EVMCodeTransformTest.cpp index e54ab9c8f002..23c24ce305fd 100644 --- a/test/libyul/EVMCodeTransformTest.cpp +++ b/test/libyul/EVMCodeTransformTest.cpp @@ -67,12 +67,14 @@ TestCase::TestResult EVMCodeTransformTest::run(std::ostream& _stream, std::strin return TestResult::FatalError; } + // TODO: Add EOF support evmasm::Assembly assembly{solidity::test::CommonOptions::get().evmVersion(), false, std::nullopt, {}}; EthAssemblyAdapter adapter(assembly); EVMObjectCompiler::compile( *stack.parserResult(), adapter, - EVMDialect::strictAssemblyForEVMObjects(EVMVersion{}), + // TODO: Make sure that why we cannot pass here solidity::test::CommonOptions::get().evmVersion() and assembly.eofVersion() + EVMDialect::strictAssemblyForEVMObjects(EVMVersion{}, std::nullopt), m_stackOpt, std::nullopt ); diff --git a/test/libyul/FunctionSideEffects.cpp b/test/libyul/FunctionSideEffects.cpp index 9d6599f42bc1..7a153de7d362 100644 --- a/test/libyul/FunctionSideEffects.cpp +++ b/test/libyul/FunctionSideEffects.cpp @@ -88,8 +88,9 @@ TestCase::TestResult FunctionSideEffects::run(std::ostream& _stream, std::string if (!obj.hasCode()) BOOST_THROW_EXCEPTION(std::runtime_error("Parsing input failed.")); + // TODO: Add EOF support std::map functionSideEffects = SideEffectsPropagator::sideEffects( - EVMDialect::strictAssemblyForEVMObjects(langutil::EVMVersion()), + EVMDialect::strictAssemblyForEVMObjects(langutil::EVMVersion(), std::nullopt), CallGraphGenerator::callGraph(obj.code()->root()) ); diff --git a/test/libyul/KnowledgeBaseTest.cpp b/test/libyul/KnowledgeBaseTest.cpp index 0293f8ee4472..badeb21fe7f9 100644 --- a/test/libyul/KnowledgeBaseTest.cpp +++ b/test/libyul/KnowledgeBaseTest.cpp @@ -63,7 +63,8 @@ class KnowledgeBaseTest return KnowledgeBase([this](YulName _var) { return util::valueOrNullptr(m_values, _var); }); } - EVMDialect m_dialect{EVMVersion{}, true}; + // TODO: Add EOF support + EVMDialect m_dialect{EVMVersion{}, std::nullopt, true}; std::shared_ptr m_object; SSAValueTracker m_ssaValues; std::map m_values; diff --git a/test/libyul/ObjectParser.cpp b/test/libyul/ObjectParser.cpp index b23e530601da..7ed321cd48e6 100644 --- a/test/libyul/ObjectParser.cpp +++ b/test/libyul/ObjectParser.cpp @@ -112,7 +112,8 @@ std::tuple, ErrorList> tryGetSourceLocationMapping( ErrorList errors; ErrorReporter reporter(errors); - Dialect const& dialect = yul::EVMDialect::strictAssemblyForEVM(EVMVersion::berlin()); + // TODO: Add EOF support + Dialect const& dialect = yul::EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); ObjectParser objectParser{reporter, dialect}; CharStream stream(std::move(source), ""); auto object = objectParser.parse(std::make_shared(stream), false); diff --git a/test/libyul/Parser.cpp b/test/libyul/Parser.cpp index 9b8ce42921b6..930a34cf1a04 100644 --- a/test/libyul/Parser.cpp +++ b/test/libyul/Parser.cpp @@ -162,7 +162,8 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_empty_block) auto const sourceText = "/// @src 0:234:543\n" "{}\n"; - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); + // TODO: Add EOF support + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.size() == 0); CHECK_LOCATION(result->root().debugData->originLocation, "source0", 234, 543); @@ -180,7 +181,8 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_block_with_children) "let z := true\n" "let y := add(1, 2)\n" "}\n"; - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); + // TODO: Add EOF support + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result); CHECK_LOCATION(result->root().debugData->originLocation, "source0", 234, 543); @@ -203,7 +205,8 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_block_different_sources) "let z := true\n" "let y := add(1, 2)\n" "}\n"; - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); + // TODO: Add EOF support + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.size() == 0); CHECK_LOCATION(result->root().debugData->originLocation, "source0", 234, 543); @@ -225,7 +228,8 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_block_nested) "/// @src 0:343:434\n" "switch y case 0 {} default {}\n" "}\n"; - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); + // TODO: Add EOF support + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.size() == 0); CHECK_LOCATION(result->root().debugData->originLocation, "source0", 234, 543); @@ -249,7 +253,8 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_block_switch_case) " let z := add(3, 4)\n" "}\n" "}\n"; - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); + // TODO: Add EOF support + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.size() == 0); CHECK_LOCATION(result->root().debugData->originLocation, "source0", 234, 543); @@ -281,7 +286,8 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_inherit_into_outer_scope) "let z := true\n" "let y := add(1, 2)\n" "}\n"; - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); + // TODO: Add EOF support + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.size() == 0); @@ -312,7 +318,8 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_assign_empty) "/// @src 1:1:10\n" "a := true\n" "}\n"; - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); + // TODO: Add EOF support + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.size() == 0); // should still parse BOOST_REQUIRE_EQUAL(2, result->root().statements.size()); @@ -333,7 +340,8 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_invalid_source_index) "let b := true\n" "\n" "}\n"; - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); + // TODO: Add EOF support + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result); // should still parse BOOST_REQUIRE(errorList.size() == 1); @@ -353,7 +361,8 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_mixed_locations_1) "/// @src 0:234:2026\n" ":= true\n" "}\n"; - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); + // TODO: Add EOF support + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.size() == 0); @@ -376,7 +385,8 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_mixed_locations_2) 2) } )"; - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); + // TODO: Add EOF support + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.size() == 0); BOOST_REQUIRE_EQUAL(1, result->root().statements.size()); @@ -410,7 +420,8 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_mixed_locations_3) mstore(1, 2) // FunctionCall } )"; - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); + // TODO: Add EOF support + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.size() == 0); BOOST_REQUIRE_EQUAL(2, result->root().statements.size()); @@ -446,7 +457,8 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_invalid_comments_after_valid) let a := true } )"; - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); + // TODO: Add EOF support + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.size() == 0); BOOST_REQUIRE_EQUAL(1, result->root().statements.size()); @@ -465,7 +477,8 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_invalid_suffix) /// @src 0:420:680foo {} )"; - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); + // TODO: Add EOF support + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result); BOOST_REQUIRE(errorList.size() == 1); @@ -482,7 +495,8 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_invalid_prefix) /// abc@src 0:111:222 {} )"; - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); + // TODO: Add EOF support + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.size() == 0); CHECK_LOCATION(result->root().debugData->originLocation, "", -1, -1); @@ -496,7 +510,8 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_unspecified) /// @src -1:-1:-1 {} )"; - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); + // TODO: Add EOF support + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.size() == 0); CHECK_LOCATION(result->root().debugData->originLocation, "", -1, -1); @@ -510,7 +525,8 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_non_integer) /// @src a:b:c {} )"; - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); + // TODO: Add EOF support + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result); BOOST_REQUIRE(errorList.size() == 1); @@ -527,7 +543,8 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_bad_integer) /// @src 111111111111111111111:222222222222222222222:333333333333333333333 {} )"; - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); + // TODO: Add EOF support + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result); BOOST_REQUIRE(errorList.size() == 1); @@ -548,7 +565,8 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_ensure_last_match) let x := true } )"; - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); + // TODO: Add EOF support + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.size() == 0); BOOST_REQUIRE(std::holds_alternative(result->root().statements.at(0))); @@ -566,7 +584,8 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_two_locations_no_whitespace) /// @src 0:111:222@src 1:333:444 {} )"; - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); + // TODO: Add EOF support + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result); BOOST_REQUIRE(errorList.size() == 1); @@ -583,7 +602,8 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_two_locations_separated_with_single_s /// @src 0:111:222 @src 1:333:444 {} )"; - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); + // TODO: Add EOF support + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.size() == 0); CHECK_LOCATION(result->root().debugData->originLocation, "source1", 333, 444); @@ -594,7 +614,8 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_leading_trailing_whitespace) ErrorList errorList; ErrorReporter reporter(errorList); auto const sourceText = "/// @src 0:111:222 \n{}"; - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); + // TODO: Add EOF support + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.size() == 0); CHECK_LOCATION(result->root().debugData->originLocation, "source0", 111, 222); @@ -611,7 +632,8 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_reference_original_sloc) let x := true } )"; - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); + // TODO: Add EOF support + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.size() == 0); BOOST_REQUIRE(std::holds_alternative(result->root().statements.at(0))); @@ -633,7 +655,8 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_with_code_snippets) let y := /** @src 1:96:165 "contract D {..." */ 128 } )~~~"; - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); + // TODO: Add EOF support + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.size() == 0); BOOST_REQUIRE_EQUAL(result->root().statements.size(), 2); @@ -658,7 +681,8 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_with_code_snippets_empty_snippet) /// @src 0:111:222 "" {} )"; - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); + // TODO: Add EOF support + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.size() == 0); CHECK_LOCATION(result->root().debugData->originLocation, "source0", 111, 222); @@ -672,7 +696,8 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_with_code_snippets_no_whitespace_befo /// @src 0:111:222"abc" def {} )"; - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); + // TODO: Add EOF support + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result); BOOST_REQUIRE(errorList.size() == 1); @@ -689,7 +714,8 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_with_code_snippets_no_whitespace_afte /// @src 0:111:222 "abc"def {} )"; - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); + // TODO: Add EOF support + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.size() == 0); CHECK_LOCATION(result->root().debugData->originLocation, "source0", 111, 222); @@ -703,7 +729,8 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_two_locations_with_snippets_no_whites /// @src 0:111:222 "abc"@src 1:333:444 "abc" {} )"; - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); + // TODO: Add EOF support + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.size() == 0); CHECK_LOCATION(result->root().debugData->originLocation, "source1", 333, 444); @@ -717,7 +744,8 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_two_locations_with_snippets_untermina /// @src 0:111:222 " abc @src 1:333:444 {} )"; - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); + // TODO: Add EOF support + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result); BOOST_REQUIRE(errorList.size() == 1); @@ -735,7 +763,8 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_single_quote) /// {} )"; - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); + // TODO: Add EOF support + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result); BOOST_REQUIRE(errorList.size() == 1); @@ -752,7 +781,8 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_two_snippets_with_hex_comment) /// @src 0:111:222 hex"abc"@src 1:333:444 "abc" {} )"; - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); + // TODO: Add EOF support + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.size() == 0); // the second source location is not parsed as such, as the hex string isn't interpreted as snippet but @@ -768,7 +798,8 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_invalid_escapes) /// @src 0:111:222 "\n\\x\x\w\uö\xy\z\y\fq" {} )"; - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); + // TODO: Add EOF support + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.size() == 0); CHECK_LOCATION(result->root().debugData->originLocation, "source0", 111, 222); @@ -783,7 +814,8 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_single_quote_snippet_with_whitespaces /// @src 1 : 222 : 333 '\x33\u1234\t\n' {} )"; - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); + // TODO: Add EOF support + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.size() == 0); CHECK_LOCATION(result->root().debugData->originLocation, "source1", 222, 333); @@ -798,7 +830,8 @@ BOOST_DATA_TEST_CASE(customSourceLocations_scanner_errors_outside_string_lits_ar /// @src 1:222:333 {{}} )", invalid); - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); + // TODO: Add EOF support + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.empty()); CHECK_LOCATION(result->root().debugData->originLocation, "source1", 222, 333); @@ -816,7 +849,8 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_multi_line_source_loc) /// " @src 0:333:444 {} )"; - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); + // TODO: Add EOF support + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.empty()); CHECK_LOCATION(result->root().debugData->originLocation, "source0", 333, 444); @@ -834,7 +868,8 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_with_code_snippets_with_nested_locati let y := /** @src 1:96:165 "function f() internal { \"\/** @src 0:6:7 *\/\"; }" */ 128 } )~~~"; - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); + // TODO: Add EOF support + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.size() == 0); BOOST_REQUIRE_EQUAL(result->root().statements.size(), 2); @@ -863,7 +898,8 @@ BOOST_AUTO_TEST_CASE(astid) mstore(1, 2) } )"; - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); + // TODO: Add EOF support + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result); BOOST_CHECK(result->root().debugData->astID == int64_t(7)); @@ -885,7 +921,8 @@ BOOST_AUTO_TEST_CASE(astid_reset) mstore(1, 2) } )"; - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); + // TODO: Add EOF support + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result); BOOST_CHECK(result->root().debugData->astID == int64_t(7)); @@ -903,7 +940,8 @@ BOOST_AUTO_TEST_CASE(astid_multi) /// @src -1:-1:-1 @ast-id 7 @src 1:1:1 @ast-id 8 {} )"; - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); + // TODO: Add EOF support + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result); BOOST_CHECK(result->root().debugData->astID == int64_t(8)); @@ -917,7 +955,8 @@ BOOST_AUTO_TEST_CASE(astid_invalid) /// @src -1:-1:-1 @ast-id abc @src 1:1:1 {} )"; - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); + // TODO: Add EOF support + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result); BOOST_REQUIRE(errorList.size() == 1); @@ -934,7 +973,8 @@ BOOST_AUTO_TEST_CASE(astid_too_large) /// @ast-id 9223372036854775808 {} )"; - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); + // TODO: Add EOF support + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result); BOOST_REQUIRE(errorList.size() == 1); @@ -950,7 +990,8 @@ BOOST_AUTO_TEST_CASE(astid_way_too_large) /// @ast-id 999999999999999999999999999999999999999 {} )"; - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); + // TODO: Add EOF support + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result); BOOST_REQUIRE(errorList.size() == 1); @@ -966,7 +1007,8 @@ BOOST_AUTO_TEST_CASE(astid_not_fully_numeric) /// @ast-id 9x {} )"; - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); + // TODO: Add EOF support + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result); BOOST_REQUIRE(errorList.size() == 1); @@ -988,7 +1030,8 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_multiple_src_tags_on_one_line) "\n" " let x := 123\n" "}\n"; - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}); + // TODO: Add EOF support + auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.size() == 0); BOOST_REQUIRE_EQUAL(result->root().statements.size(), 1); diff --git a/test/libyul/SSAControlFlowGraphTest.cpp b/test/libyul/SSAControlFlowGraphTest.cpp index a316356dbf0f..c0d1e87270ef 100644 --- a/test/libyul/SSAControlFlowGraphTest.cpp +++ b/test/libyul/SSAControlFlowGraphTest.cpp @@ -48,7 +48,11 @@ SSAControlFlowGraphTest::SSAControlFlowGraphTest(std::string const& _filename): { m_source = m_reader.source(); auto dialectName = m_reader.stringSetting("dialect", "evm"); - m_dialect = &dialect(dialectName, solidity::test::CommonOptions::get().evmVersion()); + m_dialect = &dialect( + dialectName, + solidity::test::CommonOptions::get().evmVersion(), + solidity::test::CommonOptions::get().eofVersion() + ); m_expectation = m_reader.simpleExpectations(); } diff --git a/test/libyul/StackLayoutGeneratorTest.cpp b/test/libyul/StackLayoutGeneratorTest.cpp index 9c16eaefc110..f50d2d23b028 100644 --- a/test/libyul/StackLayoutGeneratorTest.cpp +++ b/test/libyul/StackLayoutGeneratorTest.cpp @@ -49,7 +49,11 @@ StackLayoutGeneratorTest::StackLayoutGeneratorTest(std::string const& _filename) { m_source = m_reader.source(); auto dialectName = m_reader.stringSetting("dialect", "evm"); - m_dialect = &dialect(dialectName, solidity::test::CommonOptions::get().evmVersion()); + m_dialect = &dialect( + dialectName, + solidity::test::CommonOptions::get().evmVersion(), + solidity::test::CommonOptions::get().eofVersion() + ); m_expectation = m_reader.simpleExpectations(); } diff --git a/test/libyul/SyntaxTest.cpp b/test/libyul/SyntaxTest.cpp index 7ed87bee450a..aa37e85afdd8 100644 --- a/test/libyul/SyntaxTest.cpp +++ b/test/libyul/SyntaxTest.cpp @@ -75,5 +75,9 @@ SyntaxTest::SyntaxTest(std::string const& _filename, langutil::EVMVersion _evmVe CommonSyntaxTest(_filename, _evmVersion) { std::string dialectName = m_reader.stringSetting("dialect", "evm"); - m_dialect = &dialect(dialectName, solidity::test::CommonOptions::get().evmVersion()); + m_dialect = &dialect( + dialectName, + solidity::test::CommonOptions::get().evmVersion(), + solidity::test::CommonOptions::get().eofVersion() + ); } diff --git a/test/libyul/YulInterpreterTest.cpp b/test/libyul/YulInterpreterTest.cpp index 9d4ccd81ba49..343a17b4a4a1 100644 --- a/test/libyul/YulInterpreterTest.cpp +++ b/test/libyul/YulInterpreterTest.cpp @@ -98,7 +98,7 @@ std::string YulInterpreterTest::interpret() { Interpreter::run( state, - EVMDialect::strictAssemblyForEVMObjects(solidity::test::CommonOptions::get().evmVersion()), + EVMDialect::strictAssemblyForEVMObjects(solidity::test::CommonOptions::get().evmVersion(), std::nullopt), m_ast->root(), /*disableExternalCalls=*/ !m_simulateExternalCallsToSelf, /*disableMemoryTracing=*/ false diff --git a/test/libyul/YulOptimizerTest.cpp b/test/libyul/YulOptimizerTest.cpp index 7f2f5815a675..308afef5f904 100644 --- a/test/libyul/YulOptimizerTest.cpp +++ b/test/libyul/YulOptimizerTest.cpp @@ -56,7 +56,11 @@ YulOptimizerTest::YulOptimizerTest(std::string const& _filename): m_source = m_reader.source(); auto dialectName = m_reader.stringSetting("dialect", "evm"); - m_dialect = &dialect(dialectName, solidity::test::CommonOptions::get().evmVersion()); + m_dialect = &dialect( + dialectName, + solidity::test::CommonOptions::get().evmVersion(), + solidity::test::CommonOptions::get().eofVersion() + ); m_expectation = m_reader.simpleExpectations(); } diff --git a/test/tools/ossfuzz/StackReuseCodegenFuzzer.cpp b/test/tools/ossfuzz/StackReuseCodegenFuzzer.cpp index a064fcdc80ed..6f603e335d46 100644 --- a/test/tools/ossfuzz/StackReuseCodegenFuzzer.cpp +++ b/test/tools/ossfuzz/StackReuseCodegenFuzzer.cpp @@ -105,8 +105,9 @@ DEFINE_PROTO_FUZZER(Program const& _input) YulAssembler assembler{version, std::nullopt, settings, yul_source}; unoptimisedByteCode = assembler.assemble(); auto yulObject = assembler.object(); + // TODO: Add EOF support recursiveFunction = recursiveFunctionExists( - EVMDialect::strictAssemblyForEVMObjects(version), + EVMDialect::strictAssemblyForEVMObjects(version, std::nullopt), *yulObject ); } diff --git a/test/tools/ossfuzz/strictasm_diff_ossfuzz.cpp b/test/tools/ossfuzz/strictasm_diff_ossfuzz.cpp index f685aa90da4b..ffeb14702183 100644 --- a/test/tools/ossfuzz/strictasm_diff_ossfuzz.cpp +++ b/test/tools/ossfuzz/strictasm_diff_ossfuzz.cpp @@ -87,10 +87,11 @@ extern "C" int LLVMFuzzerTestOneInput(uint8_t const* _data, size_t _size) // such as unused write to memory e.g., // { mstore(0, 1) } // that would be removed by the redundant store eliminator. + // TODO: Add EOF support yulFuzzerUtil::TerminationReason termReason = yulFuzzerUtil::interpret( os1, stack.parserResult()->code()->root(), - EVMDialect::strictAssemblyForEVMObjects(langutil::EVMVersion()), + EVMDialect::strictAssemblyForEVMObjects(langutil::EVMVersion(), std::nullopt), /*disableMemoryTracing=*/true ); if (yulFuzzerUtil::resourceLimitsExceeded(termReason)) @@ -100,7 +101,7 @@ extern "C" int LLVMFuzzerTestOneInput(uint8_t const* _data, size_t _size) termReason = yulFuzzerUtil::interpret( os2, stack.parserResult()->code()->root(), - EVMDialect::strictAssemblyForEVMObjects(langutil::EVMVersion()), + EVMDialect::strictAssemblyForEVMObjects(langutil::EVMVersion(), std::nullopt), /*disableMemoryTracing=*/true ); diff --git a/test/tools/ossfuzz/yulProtoFuzzer.cpp b/test/tools/ossfuzz/yulProtoFuzzer.cpp index cfdb20813007..4e9387f6f51e 100644 --- a/test/tools/ossfuzz/yulProtoFuzzer.cpp +++ b/test/tools/ossfuzz/yulProtoFuzzer.cpp @@ -78,10 +78,11 @@ DEFINE_PROTO_FUZZER(Program const& _input) ) yulAssert(false, "Proto fuzzer generated malformed program"); + // TODO: Add EOF support // Optimize YulOptimizerTestCommon optimizerTest( stack.parserResult(), - EVMDialect::strictAssemblyForEVMObjects(version) + EVMDialect::strictAssemblyForEVMObjects(version, std::nullopt) ); optimizerTest.setStep(optimizerTest.randomOptimiserStep(_input.step())); auto const* astRoot = optimizerTest.run(); diff --git a/test/tools/ossfuzz/yulProto_diff_ossfuzz.cpp b/test/tools/ossfuzz/yulProto_diff_ossfuzz.cpp index 13ac4aea8460..eff96f831eaf 100644 --- a/test/tools/ossfuzz/yulProto_diff_ossfuzz.cpp +++ b/test/tools/ossfuzz/yulProto_diff_ossfuzz.cpp @@ -87,27 +87,30 @@ DEFINE_PROTO_FUZZER(Program const& _input) // such as unused write to memory e.g., // { mstore(0, 1) } // that would be removed by the redundant store eliminator. + // TODO: Add EOF support yulFuzzerUtil::TerminationReason termReason = yulFuzzerUtil::interpret( os1, stack.parserResult()->code()->root(), - EVMDialect::strictAssemblyForEVMObjects(version), + EVMDialect::strictAssemblyForEVMObjects(version, std::nullopt), /*disableMemoryTracing=*/true ); if (yulFuzzerUtil::resourceLimitsExceeded(termReason)) return; + // TODO: Add EOF support YulOptimizerTestCommon optimizerTest( stack.parserResult(), - EVMDialect::strictAssemblyForEVMObjects(version) + EVMDialect::strictAssemblyForEVMObjects(version, std::nullopt) ); optimizerTest.setStep(optimizerTest.randomOptimiserStep(_input.step())); auto const* astRoot = optimizerTest.run(); yulAssert(astRoot != nullptr, "Optimiser error."); + // TODO: Add EOF support termReason = yulFuzzerUtil::interpret( os2, *astRoot, - EVMDialect::strictAssemblyForEVMObjects(version), + EVMDialect::strictAssemblyForEVMObjects(version, std::nullopt), true ); if (yulFuzzerUtil::resourceLimitsExceeded(termReason)) diff --git a/test/tools/yulopti.cpp b/test/tools/yulopti.cpp index 13375f827762..cbe0219676fa 100644 --- a/test/tools/yulopti.cpp +++ b/test/tools/yulopti.cpp @@ -242,7 +242,7 @@ class YulOpti private: std::shared_ptr m_astRoot; - Dialect const& m_dialect{EVMDialect::strictAssemblyForEVMObjects(EVMVersion{})}; + Dialect const& m_dialect{EVMDialect::strictAssemblyForEVMObjects(EVMVersion{}, std::nullopt)}; std::unique_ptr m_analysisInfo; std::set const m_reservedIdentifiers = {}; NameDispenser m_nameDispenser{m_dialect, m_reservedIdentifiers}; diff --git a/test/tools/yulrun.cpp b/test/tools/yulrun.cpp index e857c26645ee..36d48858620b 100644 --- a/test/tools/yulrun.cpp +++ b/test/tools/yulrun.cpp @@ -87,7 +87,7 @@ void interpret(std::string const& _source, bool _inspect, bool _disableExternalC state.maxTraceSize = 10000; try { - Dialect const& dialect(EVMDialect::strictAssemblyForEVMObjects(langutil::EVMVersion{})); + Dialect const& dialect(EVMDialect::strictAssemblyForEVMObjects(langutil::EVMVersion{}, std::nullopt)); if (_inspect) InspectedInterpreter::run(std::make_shared(_source, state), state, dialect, ast->root(), _disableExternalCalls, /*disableMemoryTracing=*/false); diff --git a/tools/yulPhaser/Program.cpp b/tools/yulPhaser/Program.cpp index 57e1bf2b9342..fa7fbe274c95 100644 --- a/tools/yulPhaser/Program.cpp +++ b/tools/yulPhaser/Program.cpp @@ -68,7 +68,8 @@ Program::Program(Program const& program): std::variant Program::load(CharStream& _sourceCode) { // ASSUMPTION: parseSource() rewinds the stream on its own - Dialect const& dialect = EVMDialect::strictAssemblyForEVMObjects(EVMVersion{}); + // TODO: Add support for EOF + Dialect const& dialect = EVMDialect::strictAssemblyForEVMObjects(EVMVersion{}, std::nullopt); std::variant, ErrorList> astOrErrors = parseObject(dialect, _sourceCode); if (std::holds_alternative(astOrErrors)) From 62dc5975b83d5448acb70ccdcd54ac39e14d7b75 Mon Sep 17 00:00:00 2001 From: Franco Victorio Date: Fri, 27 Sep 2024 11:06:43 +0200 Subject: [PATCH 0468/1022] Replace Hardhat with EDR in CI --- .circleci/config.yml | 42 +++++++++++++++--------------------------- 1 file changed, 15 insertions(+), 27 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 5e6e65809986..58d3803ed22e 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1394,13 +1394,13 @@ jobs: test/externalTests/solc-js/solc-js.sh /tmp/workspace/soljson.js $(cat /tmp/workspace/version.txt) - matrix_notify_failure_unless_pr - t_ems_ext_hardhat: + t_ems_ext_edr: <<: *base_node_small docker: - - image: cimg/rust:1.74.0-node + - image: cimg/rust:1.79.0-node environment: <<: *base_node_small_env - HARDHAT_TESTS_SOLC_PATH: /tmp/workspace/soljson.js + EDR_TESTS_SOLC_PATH: /tmp/workspace/soljson.js steps: - checkout - attach_workspace: @@ -1409,48 +1409,36 @@ jobs: name: Ensure pnpm is installed if npm is present command: sudo npm install -g pnpm - run: - name: Retrieve Hardhat latest release tag + name: Retrieve EDR latest release tag command: | # Make authenticated requests when the Github token is available if [[ -n "$GITHUB_ACCESS_TOKEN" ]]; then EXTRA_HEADERS=(--header "Authorization: Bearer ${GITHUB_ACCESS_TOKEN}") fi - HARDHAT_LATEST_RELEASE_TAG=$( + EDR_LATEST_RELEASE_TAG=$( curl \ --silent \ --location \ --fail \ --show-error \ "${EXTRA_HEADERS[@]}" \ - https://api.github.com/repos/nomiclabs/hardhat/releases/latest \ + https://api.github.com/repos/nomicfoundation/edr/releases/latest \ | jq --raw-output .tag_name \ ) - echo "export HARDHAT_LATEST_RELEASE_TAG='${HARDHAT_LATEST_RELEASE_TAG}'" >> "$BASH_ENV" - - run: git clone --depth 1 https://github.com/nomiclabs/hardhat.git --branch "$HARDHAT_LATEST_RELEASE_TAG" + echo "export EDR_LATEST_RELEASE_TAG='${EDR_LATEST_RELEASE_TAG}'" >> "$BASH_ENV" + - run: git clone --depth 1 https://github.com/nomicfoundation/edr.git --branch "$EDR_LATEST_RELEASE_TAG" - run: name: Install dependencies command: | - cd hardhat + cd edr pnpm install --no-frozen-lockfile - run: - name: Run hardhat-core test suite + name: Run hardhat-tests in EDR repo command: | - HARDHAT_TESTS_SOLC_VERSION=$(scripts/get_version.sh) - export HARDHAT_TESTS_SOLC_VERSION - - # NOTE: This is expected to work without running `pnpm build` first. - cd hardhat/packages/hardhat-core - # TODO: temporarily set hardhat stack traces tests to use cancun hardfork - # Remove this when hardhat switch to cancun by default: https://github.com/NomicFoundation/hardhat/issues/4851 - sed -i 's/hardfork: "shanghai",/hardfork: "cancun",/' test/internal/hardhat-network/stack-traces/execution.ts - # TODO: Remove these tests because they rely on specific stack sequence which has changed since - # Remove when hardhat properly fix a specific version for the tests: https://github.com/NomicFoundation/hardhat/issues/5443 - rm -rf test/internal/hardhat-network/stack-traces/test-files/0_8/revert-without-message/modifiers/call-message/multiple-modifiers-require/ - rm -rf test/internal/hardhat-network/stack-traces/test-files/0_8/revert-without-message/modifiers/create-message/multiple-modifiers-require/ - rm -rf test/internal/hardhat-network/stack-traces/test-files/0_8/revert-without-message/revert-without-message/within-receive/between-statements/ - rm -rf test/internal/hardhat-network/stack-traces/test-files/0_8/revert-without-message/revert-without-message/within-receive/no-other-statements/ - rm -rf test/internal/hardhat-network/stack-traces/test-files/0_8/revert-without-message/revert-without-message/within-receive/statement-after/ - rm -rf test/internal/hardhat-network/stack-traces/test-files/0_8/revert-without-message/revert-without-message/within-receive/statement-before/ + EDR_TESTS_SOLC_VERSION=$(scripts/get_version.sh) + export EDR_TESTS_SOLC_VERSION + + cd edr/hardhat-tests pnpm test - matrix_notify_failure_unless_pr @@ -1904,7 +1892,7 @@ workflows: # Emscripten build and tests that take 15 minutes or less - b_ems: *requires_nothing - t_ems_solcjs: *requires_b_ems - - t_ems_ext_hardhat: *requires_b_ems + - t_ems_ext_edr: *requires_b_ems - t_ext: *job_ems_compile_ext_colony From 2b4184674369e49f5edc1a7cd1cdf77637712221 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Wed, 2 Oct 2024 14:24:11 +0200 Subject: [PATCH 0469/1022] cmake: remove USE_LD_GOLD option --- Changelog.md | 4 ++++ cmake/EthCompilerSettings.cmake | 10 ---------- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/Changelog.md b/Changelog.md index b171b6dd0155..959aff257ccf 100644 --- a/Changelog.md +++ b/Changelog.md @@ -14,6 +14,10 @@ Bugfixes: * Yul AST: Fix shifted native source locations when debug info selection included code snippets. +Build system: +* Removed ``USE_LD_GOLD`` option and default to use the compiler default linker. For custom linkers, ``CMAKE_CXX_FLAGS`` can be used. + + ### 0.8.27 (2024-09-04) Language Features: diff --git a/cmake/EthCompilerSettings.cmake b/cmake/EthCompilerSettings.cmake index eda0e404ddd6..4cf3927d1d06 100644 --- a/cmake/EthCompilerSettings.cmake +++ b/cmake/EthCompilerSettings.cmake @@ -266,13 +266,3 @@ option(USE_Z3 "Allow compiling with Z3 SMT solver integration" ON) if(UNIX AND NOT APPLE) option(USE_Z3_DLOPEN "Dynamically load the Z3 SMT solver instead of linking against it." OFF) endif() - -if (("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU") OR ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")) - option(USE_LD_GOLD "Use GNU gold linker" ON) - if (USE_LD_GOLD) - execute_process(COMMAND ${CMAKE_CXX_COMPILER} -fuse-ld=gold -Wl,--version ERROR_QUIET OUTPUT_VARIABLE LD_VERSION) - if ("${LD_VERSION}" MATCHES "GNU gold") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fuse-ld=gold") - endif () - endif () -endif () From badd1154e87a7170467d7855bfc7e17c55748d55 Mon Sep 17 00:00:00 2001 From: Daniel Kirchner Date: Wed, 2 Oct 2024 19:06:04 +0200 Subject: [PATCH 0470/1022] Avoid unnecessary copy in full inliner. --- libyul/optimiser/FullInliner.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libyul/optimiser/FullInliner.cpp b/libyul/optimiser/FullInliner.cpp index 2f138761fc66..c6387f808e0e 100644 --- a/libyul/optimiser/FullInliner.cpp +++ b/libyul/optimiser/FullInliner.cpp @@ -106,7 +106,7 @@ void FullInliner::run(Pass _pass) for (auto& statement: m_ast.statements) if (std::holds_alternative(statement)) functions.emplace_back(&std::get(statement)); - std::stable_sort(functions.begin(), functions.end(), [depths]( + std::stable_sort(functions.begin(), functions.end(), [&depths]( FunctionDefinition const* _a, FunctionDefinition const* _b ) { From 39e5aeff86151c273c5e8c7b040f371536726b9c Mon Sep 17 00:00:00 2001 From: Nikola Matic Date: Wed, 2 Oct 2024 15:18:40 +0200 Subject: [PATCH 0471/1022] Re-enable cxx20 job --- .circleci/config.yml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 58d3803ed22e..82739dffb5c9 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1105,9 +1105,9 @@ 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: - <<: *base_ubuntu2404_large + <<: *base_ubuntu2404_xlarge environment: - <<: *base_ubuntu2404_large_env + <<: *base_ubuntu2404_xlarge_env CMAKE_BUILD_TYPE: Debug CMAKE_OPTIONS: -DCMAKE_CXX_STANDARD=20 MAKEFLAGS: -j 10 @@ -1859,8 +1859,7 @@ workflows: # build-only - b_docs: *requires_nothing - # DISABLED FOR 0.8.18 - b_ubu_cxx20: *requires_nothing - # Issue: https://github.com/ethereum/solidity/issues/13868 + - b_ubu_cxx20: *requires_nothing - b_ubu_ossfuzz: *requires_nothing # OS/X build and tests From 136fe38f748ee399fd264fc72e641f1d0dcd769f Mon Sep 17 00:00:00 2001 From: Nikola Matic Date: Mon, 7 Oct 2024 11:56:23 +0200 Subject: [PATCH 0472/1022] Disable legacy presets in zeppelin external test --- test/externalTests/zeppelin.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/externalTests/zeppelin.sh b/test/externalTests/zeppelin.sh index 64c901f61428..b9e65562e08f 100755 --- a/test/externalTests/zeppelin.sh +++ b/test/externalTests/zeppelin.sh @@ -52,8 +52,8 @@ function zeppelin_test local settings_presets=( "${compile_only_presets[@]}" ir-optimize-evm+yul - legacy-no-optimize - legacy-optimize-evm-only + #legacy-no-optimize # FIXME: Fails with stack too deep + #legacy-optimize-evm-only # FIXME: Fails with stack too deep legacy-optimize-evm+yul ) From 293bd7fc08d32e3d4871ea745e3cff664d99d48b Mon Sep 17 00:00:00 2001 From: r0qs Date: Mon, 7 Oct 2024 13:41:52 +0200 Subject: [PATCH 0473/1022] Fix broken flyout layout due to RTD addons upgrade --- docs/_static/js/initialize.js | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/docs/_static/js/initialize.js b/docs/_static/js/initialize.js index a20d4fce7190..3cf12e3e1e23 100644 --- a/docs/_static/js/initialize.js +++ b/docs/_static/js/initialize.js @@ -23,18 +23,24 @@ function rearrangeDom() { document.body.prepend(wrapperDiv); const rstVersions = document.querySelector(".rst-versions"); - rstVersions.remove(); const wyNavSide = document.querySelector("nav.wy-nav-side"); - wyNavSide.appendChild(rstVersions); + // NOTE: Since RTD migration to addons, `.rst-versions` is no longer present in the DOM. + // The following code is kept for compatibility with older versions. + // See: https://github.com/readthedocs/readthedocs.org/issues/11474 + if (rstVersions && wyNavSide) { + rstVersions.remove(); + wyNavSide.appendChild(rstVersions); + } const backdrop = document.createElement("div"); backdrop.classList.add("backdrop"); wrapperDiv.appendChild(backdrop); const content = document.querySelector(".wy-nav-content"); - content.id = "content"; - const oldWrap = document.querySelector("section.wy-nav-content-wrap"); - oldWrap.remove(); - document.querySelector(".wy-grid-for-nav").appendChild(content); + if (content) { + content.id = "content"; + document.querySelector("section.wy-nav-content-wrap")?.remove(); + document.querySelector(".wy-grid-for-nav")?.appendChild(content); + } } function buildHeader() { @@ -146,6 +152,8 @@ document.addEventListener("locationchange", updateActiveNavLink); function updateGitHubEditPath() { // Replaces the version number in the GitHub edit path with "develop" const gitHubEditAnchor = document.querySelector(".wy-breadcrumbs-aside > a"); + if (!gitHubEditAnchor) return; + const url = new URL(gitHubEditAnchor.href); const split = url.pathname.split("/"); const versionIndex = split.indexOf("blob") + 1; @@ -195,10 +203,12 @@ function initialize() { .querySelector(":root") .setAttribute("style", `--color-scheme: ${mode}`); + // NOTE: Since RTD migration to addons, the elements below are no longer present in the DOM. + // The following code is kept for compatibility with older versions. // Remove old input and RTD logo anchor element - document.querySelector("input[name=mode]").remove(); - document.querySelector("label[for=switch]").remove(); - document.querySelector(".wy-side-nav-search > a").remove(); + document.querySelector("input[name=mode]")?.remove(); + document.querySelector("label[for=switch]")?.remove(); + document.querySelector(".wy-side-nav-search > a")?.remove(); // Add footer note addFooterNote(); @@ -239,7 +249,7 @@ document.addEventListener("click", handleClick); const handleKeyDown = (e) => { if (e.metaKey && e.key === "k") { - document.querySelector("#rtd-search-form input").focus(); + document.querySelector("#rtd-search-form input")?.focus(); } else if (e.key === "Escape") { toggleMenu({ force: false }); } From f8477584e7fefd0384dd02223d104554097e3bc2 Mon Sep 17 00:00:00 2001 From: r0qs Date: Mon, 7 Oct 2024 17:17:17 +0200 Subject: [PATCH 0474/1022] Fix "Edit on GitHub" button to always point to develop branch --- docs/_static/js/initialize.js | 7 ++++++- docs/conf.py | 7 +++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/docs/_static/js/initialize.js b/docs/_static/js/initialize.js index 3cf12e3e1e23..1c3be8aaddaa 100644 --- a/docs/_static/js/initialize.js +++ b/docs/_static/js/initialize.js @@ -150,7 +150,12 @@ const updateActiveNavLink = () => { document.addEventListener("locationchange", updateActiveNavLink); function updateGitHubEditPath() { - // Replaces the version number in the GitHub edit path with "develop" + // Replaces the version number in the GitHub edit path with "develop" if it exists. + // This is to ensure that the edit path always points to the `develop` branch instead of the specific version branch. + // Note that it will fail silently if the anchor element is not found, i.e. the page is not editable or + // if the sphinx_rtd_theme is updated to a version that changes the anchor element. + // See: https://github.com/readthedocs/sphinx_rtd_theme/blob/a1c2147b17cbf0e57b7d7a6450ad4d9a5ff362cf/sphinx_rtd_theme/breadcrumbs.html#L35 + // TODO: We should consider a more robust way to handle this in the future. const gitHubEditAnchor = document.querySelector(".wy-breadcrumbs-aside > a"); if (!gitHubEditAnchor) return; diff --git a/docs/conf.py b/docs/conf.py index 9c9e2d5a0643..354e1feecce7 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -38,6 +38,13 @@ def setup(sphinx): # -- General configuration ------------------------------------------------ +html_context = { + "display_github": True, + "github_user": "ethereum", + "github_repo": "solidity", + "github_version": os.getenv("READTHEDOCS_VERSION", "develop"), + "conf_py_path": "/docs/", +} # If your documentation needs a minimal Sphinx version, state it here. #needs_sphinx = '1.0' From e354f7b098f46d688c5aadf23d28befd6f4e5749 Mon Sep 17 00:00:00 2001 From: Matheus Aguiar Date: Mon, 7 Oct 2024 12:45:35 -0300 Subject: [PATCH 0475/1022] fix changelog entry --- Changelog.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Changelog.md b/Changelog.md index 959aff257ccf..de1674a15a9d 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,10 +1,10 @@ ### 0.8.28 (unreleased) Language Features: + * Transient storage value type state variables are now fully supported. Compiler Features: - * Code Generator: Transient storage value type state variables are now supported. * General: Generate JSON representations of Yul ASTs only on demand to reduce memory usage. * Standard JSON Interface: Bytecode or IR can now be requested for a subset of all contracts without triggering unnecessary code generation for other contracts. From 8d4dc15588cbe44ff7999d8f73dd251fea04f903 Mon Sep 17 00:00:00 2001 From: r0qs Date: Mon, 7 Oct 2024 18:28:33 +0200 Subject: [PATCH 0476/1022] Fix github user and repo in RTD config for translation projects --- docs/conf.py | 48 ++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 44 insertions(+), 4 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index 354e1feecce7..f57a3b5b904c 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -36,15 +36,55 @@ def setup(sphinx): sphinx.add_css_file('css/custom-dark.css') sphinx.add_css_file('css/pygments.css') -# -- General configuration ------------------------------------------------ +# -- RTD GitHub configuration --------------------------------------------- + +# Taken from: +# https://github.com/readthedocs/readthedocs.org/blob/e366e7fc8649fbcf1b6d06ecc12c5f7766144c46/readthedocs/projects/constants.py#L350 +GITHUB_REGEXS = [ + re.compile(r"github.com/(.+)/(.+)(?:\.git){1}$"), + # This must come before the one without a / to make sure we don't capture the / + re.compile(r"github.com/(.+)/(.+)/"), + re.compile(r"github.com/(.+)/(.+)"), + re.compile(r"github.com:(.+)/(.+)\.git$"), +] + +# Taken and adapted from: +# https://github.com/readthedocs/readthedocs.org/blob/e366e7fc8649fbcf1b6d06ecc12c5f7766144c46/readthedocs/builds/utils.py#L24 +def get_github_username_repo(url): + if "github" in url: + for regex in GITHUB_REGEXS: + match = regex.search(url) + if match: + return match.groups() + return (None, None) + +display_github = False +# NOTE: RTD_DISPLAY_GITHUB, RTD_GITHUB_USER and RTD_GITHUB_REPO are set in the RTD project settings +github_user = os.getenv("RTD_GITHUB_USER") +github_repo = os.getenv("RTD_GITHUB_REPO") + +if github_user and github_repo: + display_github = True +else: + git_clone_url = os.getenv("READTHEDOCS_GIT_CLONE_URL") + if git_clone_url: + github_user, github_repo = get_github_username_repo(git_clone_url) + if github_user and github_repo: + display_github = True + +display_github_env = os.getenv("RTD_DISPLAY_GITHUB") +if display_github_env: + display_github = display_github_env.lower() == "true" html_context = { - "display_github": True, - "github_user": "ethereum", - "github_repo": "solidity", + "display_github": display_github, + "github_user": github_user, + "github_repo": github_repo, "github_version": os.getenv("READTHEDOCS_VERSION", "develop"), "conf_py_path": "/docs/", } + +# -- General configuration ------------------------------------------------ # If your documentation needs a minimal Sphinx version, state it here. #needs_sphinx = '1.0' From 3651f231fd701340927c354c18a598122d7dbf1c Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Mon, 7 Oct 2024 08:13:55 +0200 Subject: [PATCH 0477/1022] Use gold linker for ossfuzz, codecov, and cxx20 builds --- .circleci/config.yml | 10 ++++++---- cmake/toolchains/libfuzzer.cmake | 3 ++- scripts/ci/build.sh | 4 ++-- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 82739dffb5c9..0c8bb02ecbbb 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1073,6 +1073,7 @@ jobs: <<: *base_ubuntu2404_env COVERAGE: ON CMAKE_BUILD_TYPE: Debug + CMAKE_OPTIONS: -DCMAKE_CXX_FLAGS=-fuse-ld=gold steps: - checkout - run_build @@ -1105,12 +1106,13 @@ 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: - <<: *base_ubuntu2404_xlarge + <<: *base_ubuntu2404_large environment: - <<: *base_ubuntu2404_xlarge_env + <<: *base_ubuntu2404_large_env CMAKE_BUILD_TYPE: Debug - CMAKE_OPTIONS: -DCMAKE_CXX_STANDARD=20 - MAKEFLAGS: -j 10 + # gold is more memory-efficient than the default, allows us to stay with the "large" resource class without OOM errors + CMAKE_OPTIONS: -DCMAKE_CXX_STANDARD=20 -DCMAKE_CXX_FLAGS=-fuse-ld=gold + MAKEFLAGS: -j 6 steps: - checkout - run_build diff --git a/cmake/toolchains/libfuzzer.cmake b/cmake/toolchains/libfuzzer.cmake index 9d83d504f052..f9ea64860ae9 100644 --- a/cmake/toolchains/libfuzzer.cmake +++ b/cmake/toolchains/libfuzzer.cmake @@ -7,7 +7,8 @@ set(OSSFUZZ ON CACHE BOOL "Enable fuzzer build" FORCE) # Use libfuzzer as the fuzzing back-end set(LIB_FUZZING_ENGINE "-fsanitize=fuzzer" CACHE STRING "Use libfuzzer back-end" FORCE) # clang/libfuzzer specific flags for UBSan instrumentation -set(CMAKE_CXX_FLAGS "-O1 -fno-omit-frame-pointer -gline-tables-only -DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION -I /usr/local/include/c++/v1 -fsanitize=undefined -fsanitize=fuzzer-no-link -stdlib=libc++" CACHE STRING "Custom compilation flags" FORCE) +# uses the more memory-efficient gold, which allows us to stay with the "large" resource class without OOM errors +set(CMAKE_CXX_FLAGS "-O1 -fno-omit-frame-pointer -gline-tables-only -DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION -I /usr/local/include/c++/v1 -fsanitize=undefined -fsanitize=fuzzer-no-link -fuse-ld=gold -stdlib=libc++" CACHE STRING "Custom compilation flags" FORCE) # Link statically against boost libraries set(BOOST_FOUND ON CACHE BOOL "" FORCE) set(Boost_USE_STATIC_LIBS ON CACHE BOOL "Link against static Boost libraries" FORCE) diff --git a/scripts/ci/build.sh b/scripts/ci/build.sh index d529b03c1aab..e1d119a0649e 100755 --- a/scripts/ci/build.sh +++ b/scripts/ci/build.sh @@ -32,6 +32,6 @@ cd build [ -n "$COVERAGE" -a "$CIRCLE_BRANCH" != release -a -z "$CIRCLE_TAG" ] && CMAKE_OPTIONS="$CMAKE_OPTIONS -DCOVERAGE=ON" # shellcheck disable=SC2086 -cmake .. -DCMAKE_BUILD_TYPE="${CMAKE_BUILD_TYPE:-Release}" $CMAKE_OPTIONS -G "Unix Makefiles" +cmake .. -DCMAKE_BUILD_TYPE="${CMAKE_BUILD_TYPE:-Release}" $CMAKE_OPTIONS -make +cmake --build . From c7ff2175a1dae32dbf80be48f5840e04c5465d15 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Mon, 7 Oct 2024 14:00:12 +0200 Subject: [PATCH 0478/1022] Bump ossfuzz to large resource class --- .circleci/config.yml | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 0c8bb02ecbbb..ed14c8af4d32 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -528,6 +528,14 @@ defaults: MAKEFLAGS: -j 2 CPUs: 2 + - base_ubuntu_clang_large: &base_ubuntu_clang_large + <<: *base_ubuntu_clang + resource_class: large + environment: &base_ubuntu_clang_small_env + <<: *base_ubuntu_clang_env + MAKEFLAGS: -j 5 + CPUs: 5 + - base_ubuntu2004: &base_ubuntu2004 docker: - image: << pipeline.parameters.ubuntu-2004-docker-image >> @@ -1119,7 +1127,7 @@ jobs: - matrix_notify_failure_unless_pr b_ubu_ossfuzz: &b_ubu_ossfuzz - <<: *base_ubuntu_clang + <<: *base_ubuntu_clang_large steps: - checkout - setup_prerelease_commit_hash From 525381c1b5476e37b5ddb57a9390e2b0a57205aa Mon Sep 17 00:00:00 2001 From: backbonexe <117212528+LMAO798@users.noreply.github.com> Date: Fri, 20 Sep 2024 18:26:56 +0200 Subject: [PATCH 0479/1022] docs: fix broken links and typo --- docs/contributing.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/contributing.rst b/docs/contributing.rst index 36b85867945c..28b81626c13f 100644 --- a/docs/contributing.rst +++ b/docs/contributing.rst @@ -556,7 +556,7 @@ topics, issues or feature implementations are debated in detail. The invitation We are also sharing feedback surveys and other content that is relevant to language design in the forum. -If you want to know where the team is standing in terms or implementing new features, you can follow the implementation status in the `Solidity GitHub project `_. +If you want to know where the team is standing in terms of implementing new features, you can follow the implementation status in the `Solidity GitHub project `_. Issues in the design backlog need further specification and will either be discussed in a language design call or in a regular team call. You can see the upcoming changes for the next breaking release by changing from the default branch (`develop`) to the `breaking branch `_. From 1a8efbaf79ecd06206c2f0e2dd62ec8c5b5f8145 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nikola=20Mati=C4=87?= Date: Tue, 8 Oct 2024 09:33:56 +0200 Subject: [PATCH 0480/1022] Update docs/contributing.rst --- docs/contributing.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/contributing.rst b/docs/contributing.rst index 28b81626c13f..bb88d1201678 100644 --- a/docs/contributing.rst +++ b/docs/contributing.rst @@ -556,7 +556,7 @@ topics, issues or feature implementations are debated in detail. The invitation We are also sharing feedback surveys and other content that is relevant to language design in the forum. -If you want to know where the team is standing in terms of implementing new features, you can follow the implementation status in the `Solidity GitHub project `_. +If you want to know where the team is standing in terms of implementing new features, you can follow the implementation status in the `Solidity GitHub project `_. Issues in the design backlog need further specification and will either be discussed in a language design call or in a regular team call. You can see the upcoming changes for the next breaking release by changing from the default branch (`develop`) to the `breaking branch `_. From e8a2c63214457e7e2c4058849d259407964b9a44 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Mon, 9 Sep 2024 11:38:21 +0200 Subject: [PATCH 0481/1022] Yul: Add SSACFG liveness analysis --- libyul/CMakeLists.txt | 2 + libyul/backends/evm/SSACFGLiveness.cpp | 132 +++++++++++++++++++++++++ libyul/backends/evm/SSACFGLiveness.h | 55 +++++++++++ 3 files changed, 189 insertions(+) create mode 100644 libyul/backends/evm/SSACFGLiveness.cpp create mode 100644 libyul/backends/evm/SSACFGLiveness.h diff --git a/libyul/CMakeLists.txt b/libyul/CMakeLists.txt index f621b2089e9b..4265b91d3f3e 100644 --- a/libyul/CMakeLists.txt +++ b/libyul/CMakeLists.txt @@ -65,6 +65,8 @@ add_library(yul backends/evm/NoOutputAssembly.cpp backends/evm/OptimizedEVMCodeTransform.cpp backends/evm/OptimizedEVMCodeTransform.h + backends/evm/SSACFGLiveness.cpp + backends/evm/SSACFGLiveness.h backends/evm/SSACFGLoopNestingForest.cpp backends/evm/SSACFGLoopNestingForest.h backends/evm/SSACFGTopologicalSort.cpp diff --git a/libyul/backends/evm/SSACFGLiveness.cpp b/libyul/backends/evm/SSACFGLiveness.cpp new file mode 100644 index 000000000000..6ed926304db2 --- /dev/null +++ b/libyul/backends/evm/SSACFGLiveness.cpp @@ -0,0 +1,132 @@ +/* + 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 solidity::yul; + +SSACFGLiveness::SSACFGLiveness(SSACFG const& _cfg): + m_cfg(_cfg), + m_topologicalSort(_cfg), + m_loopNestingForest(m_topologicalSort), + m_liveIns(_cfg.numBlocks()), + m_liveOuts(_cfg.numBlocks()) +{ + runDagDfs(); + for (auto const loopRootNode: m_loopNestingForest.loopRootNodes()) + runLoopTreeDfs(loopRootNode); +} +void SSACFGLiveness::runDagDfs() +{ + // SSA Book, Algorithm 9.2 + for(auto const blockIdValue: m_topologicalSort.postOrder()) + { + // post-order traversal + SSACFG::BlockId blockId{blockIdValue}; + auto const filterLiterals = [this](auto const& valueId){ + return !std::holds_alternative(m_cfg.valueInfo(valueId)); + }; + auto const& block = m_cfg.block(blockId); + + // live <- PhiUses(B) + std::set live{}; + block.forEachExit( + [&](SSACFG::BlockId const& _successor) + { + for (auto const& phi: m_cfg.block(_successor).phis) + { + auto const& info = m_cfg.valueInfo(phi); + yulAssert(std::holds_alternative(info), "value info of phi wasn't PhiValue"); + auto const& entries = m_cfg.block(std::get(info).block).entries; + // this is getting the argument index of the phi function corresponding to the path going + // through "blockId", ie, the currently handled block + auto const it = entries.find(blockId); + yulAssert(it != entries.end()); + auto const argIndex = static_cast(std::distance(entries.begin(), it)); + if (argIndex < std::get(info).arguments.size()) + { + // todo not sure why arg index would exceed phi arg length but it does happen + auto const arg = std::get(info).arguments.at(argIndex); + if (!std::holds_alternative(m_cfg.valueInfo(arg))) + live.insert(arg); + } + else + yulAssert(false); + } + }); + + // for each S \in succs(B) s.t. (B, S) not a back edge: live <- live \cup (LiveIn(S) - PhiDefs(S)) + block.forEachExit( + [&](SSACFG::BlockId const& _successor) { + if (!m_topologicalSort.backEdge(blockId, _successor)) + live += m_liveIns[_successor.value] - m_cfg.block(_successor).phis; + }); + if (std::holds_alternative(block.exit)) + live += std::get(block.exit).returnValues + | ranges::views::filter(filterLiterals); + + // clean out unreachables + live = live + | ranges::views::filter( + [&](auto const& valueId) + { return !std::holds_alternative(m_cfg.valueInfo(valueId)); }) + | ranges::to; + + // LiveOut(B) <- live + m_liveOuts[blockId.value] = live; + + // for each program point p in B, backwards, do: + for (auto const& op: block.operations | ranges::views::reverse) + { + // remove variables defined at p from live + live -= op.outputs | ranges::views::filter(filterLiterals) | ranges::to; + // add uses at p to live + live += op.inputs | ranges::views::filter(filterLiterals) | ranges::to; + } + + // livein(b) <- live \cup PhiDefs(B) + m_liveIns[blockId.value] = live + block.phis; + } +} +void SSACFGLiveness::runLoopTreeDfs(size_t const _loopHeader) +{ + // SSA Book, Algorithm 9.3 + if (m_loopNestingForest.loopNodes().count(_loopHeader) > 0) + { + // the loop header block id + auto const& block = m_cfg.block(SSACFG::BlockId{_loopHeader}); + // LiveLoop <- LiveIn(B_N) - PhiDefs(B_N) + auto liveLoop = m_liveIns[_loopHeader] - block.phis; + // must be live out of header if live in of children + m_liveOuts[_loopHeader] += liveLoop; + // for each blockId \in children(loopHeader) + for (size_t blockId = 0; blockId < m_cfg.numBlocks(); ++blockId) + if (m_loopNestingForest.loopParents()[blockId] == _loopHeader) + { + // propagate loop liveness information down to the loop header's children + m_liveIns[blockId] += liveLoop; + m_liveOuts[blockId] += liveLoop; + + runLoopTreeDfs(blockId); + } + } +} diff --git a/libyul/backends/evm/SSACFGLiveness.h b/libyul/backends/evm/SSACFGLiveness.h new file mode 100644 index 000000000000..bc254a03a24b --- /dev/null +++ b/libyul/backends/evm/SSACFGLiveness.h @@ -0,0 +1,55 @@ +/* + This file is part of solidity. + + solidity is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + solidity is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with solidity. If not, see . +*/ +// SPDX-License-Identifier: GPL-3.0 + +#pragma once + +#include +#include +#include + +#include +#include +#include + +namespace solidity::yul +{ + +/// Performs liveness analysis on an SSA CFG following Algorithm 9.1 in [1]. +/// +/// [1] Rastello, Fabrice, and Florent Bouchez Tichadou, eds. SSA-based Compiler Design. Springer, 2022. +class SSACFGLiveness +{ +public: + explicit SSACFGLiveness(SSACFG const& _cfg); + + std::vector> const& liveIns() const { return m_liveIns; } + std::vector> const& liveOuts() const { return m_liveOuts; } + +private: + + void runDagDfs(); + void runLoopTreeDfs(size_t _loopHeader); + + SSACFG const& m_cfg; + ForwardSSACFGTopologicalSort m_topologicalSort; + SSACFGLoopNestingForest m_loopNestingForest; + std::vector> m_liveIns; + std::vector> m_liveOuts; +}; + +} From eb22cb6fd7b55cf70508cb76d6dda63659898df3 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Wed, 18 Sep 2024 14:03:56 +0200 Subject: [PATCH 0482/1022] Yul: add optional liveness output to toDot of SSACFGs --- libyul/CMakeLists.txt | 2 + libyul/backends/evm/ControlFlow.cpp | 28 +++++++++ libyul/backends/evm/ControlFlow.h | 28 +++++++-- libyul/backends/evm/SSAControlFlowGraph.cpp | 30 ++++++++-- libyul/backends/evm/SSAControlFlowGraph.h | 7 ++- test/libyul/SSAControlFlowGraphTest.cpp | 4 +- test/libyul/SSAControlFlowGraphTest.h | 20 +++---- .../libyul/yulSSAControlFlowGraph/complex.yul | 57 ++++++++++++------- .../yulSSAControlFlowGraph/complex2.yul | 57 ++++++++++++------- .../yulSSAControlFlowGraph/function.yul | 15 +++-- test/libyul/yulSSAControlFlowGraph/if.yul | 9 ++- test/libyul/yulSSAControlFlowGraph/switch.yul | 18 ++++-- 12 files changed, 200 insertions(+), 75 deletions(-) create mode 100644 libyul/backends/evm/ControlFlow.cpp diff --git a/libyul/CMakeLists.txt b/libyul/CMakeLists.txt index 4265b91d3f3e..58c1b17b5c33 100644 --- a/libyul/CMakeLists.txt +++ b/libyul/CMakeLists.txt @@ -48,6 +48,8 @@ add_library(yul backends/evm/AsmCodeGen.h backends/evm/ConstantOptimiser.cpp backends/evm/ConstantOptimiser.h + backends/evm/ControlFlow.cpp + backends/evm/ControlFlow.h backends/evm/ControlFlowGraph.h backends/evm/ControlFlowGraphBuilder.cpp backends/evm/ControlFlowGraphBuilder.h diff --git a/libyul/backends/evm/ControlFlow.cpp b/libyul/backends/evm/ControlFlow.cpp new file mode 100644 index 000000000000..3ec123a8ed7c --- /dev/null +++ b/libyul/backends/evm/ControlFlow.cpp @@ -0,0 +1,28 @@ +/* + 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 + +using namespace solidity::yul; + +ControlFlowLiveness::ControlFlowLiveness(ControlFlow const& _controlFlow): + controlFlow(_controlFlow), + mainLiveness(std::make_unique(*_controlFlow.mainGraph)), + functionLiveness(_controlFlow.functionGraphs | ranges::views::transform([](auto const& _cfg) { return std::make_unique(*_cfg); }) | ranges::to) +{ } diff --git a/libyul/backends/evm/ControlFlow.h b/libyul/backends/evm/ControlFlow.h index 59bc1b677b57..6438f330c386 100644 --- a/libyul/backends/evm/ControlFlow.h +++ b/libyul/backends/evm/ControlFlow.h @@ -20,11 +20,22 @@ #include #include +#include #include namespace solidity::yul { +struct ControlFlow; + +struct ControlFlowLiveness{ + explicit ControlFlowLiveness(ControlFlow const& _controlFlow); + + std::reference_wrapper controlFlow; + std::unique_ptr mainLiveness; + std::vector> functionLiveness; +}; + struct ControlFlow { std::unique_ptr mainGraph{std::make_unique()}; @@ -39,14 +50,21 @@ struct ControlFlow return nullptr; } - std::string toDot() const + std::string toDot(ControlFlowLiveness const* _liveness=nullptr) const { + if (_liveness) + yulAssert(&_liveness->controlFlow.get() == this); std::ostringstream output; output << "digraph SSACFG {\nnodesep=0.7;\ngraph[fontname=\"DejaVu Sans\"]\nnode[shape=box,fontname=\"DejaVu Sans\"];\n\n"; - output << mainGraph->toDot(false); - size_t index = 1; - for (auto const& [function, functionGraph]: functionGraphMapping) - output << functionGraph->toDot(false, index++); + output << mainGraph->toDot(false, std::nullopt, _liveness ? _liveness->mainLiveness.get() : nullptr); + + for (size_t index=0; index < functionGraphs.size(); ++index) + output << functionGraphs[index]->toDot( + false, + index+1, + _liveness ? _liveness->functionLiveness[index].get() : nullptr + ); + output << "}\n"; return output.str(); } diff --git a/libyul/backends/evm/SSAControlFlowGraph.cpp b/libyul/backends/evm/SSAControlFlowGraph.cpp index e98936aaabbd..dcbdcdca3b0c 100644 --- a/libyul/backends/evm/SSAControlFlowGraph.cpp +++ b/libyul/backends/evm/SSAControlFlowGraph.cpp @@ -18,6 +18,8 @@ #include +#include + #include #include @@ -37,11 +39,13 @@ namespace class SSACFGPrinter { public: - SSACFGPrinter(SSACFG const& _cfg, SSACFG::BlockId _blockId) + SSACFGPrinter(SSACFG const& _cfg, SSACFG::BlockId _blockId, SSACFGLiveness const* _liveness): + m_liveness(_liveness) { printBlock(_cfg, _blockId, 0); } - SSACFGPrinter(SSACFG const& _cfg, size_t _functionIndex, Scope::Function const& _function) + SSACFGPrinter(SSACFG const& _cfg, size_t _functionIndex, Scope::Function const& _function, SSACFGLiveness const* _liveness): + m_liveness(_liveness) { printFunction(_cfg, _functionIndex, _function); } @@ -97,6 +101,17 @@ class SSACFGPrinter } { m_result << fmt::format("Block{1}_{0} [label=\"\\\nBlock {0}\\n", _id.value, _functionIndex); + if (m_liveness) + { + m_result << fmt::format( + "LiveIn: {}\\l\\\n", + fmt::join(m_liveness->liveIns()[_id.value] | ranges::views::transform(valueToString), ",") + ); + m_result << fmt::format( + "LiveOut: {}\\l\\n", + fmt::join(m_liveness->liveOuts()[_id.value] | ranges::views::transform(valueToString), ",") + ); + } for (auto const& phi: _block.phis) { auto const* phiValue = std::get_if(&_cfg.valueInfo(phi)); @@ -224,18 +239,23 @@ class SSACFGPrinter } std::stringstream m_result{}; + SSACFGLiveness const* m_liveness; }; } -std::string SSACFG::toDot(bool _includeDiGraphDefinition, std::optional _functionIndex) const +std::string SSACFG::toDot( + bool _includeDiGraphDefinition, + std::optional _functionIndex, + SSACFGLiveness const* _liveness +) const { std::ostringstream output; if (_includeDiGraphDefinition) output << "digraph SSACFG {\nnodesep=0.7;\ngraph[fontname=\"DejaVu Sans\"]\nnode[shape=box,fontname=\"DejaVu Sans\"];\n\n"; if (function) - output << SSACFGPrinter(*this, _functionIndex ? *_functionIndex : static_cast(1), *function); + output << SSACFGPrinter(*this, _functionIndex ? *_functionIndex : static_cast(1), *function, _liveness); else - output << SSACFGPrinter(*this, entry); + output << SSACFGPrinter(*this, entry, _liveness); if (_includeDiGraphDefinition) output << "}\n"; return output.str(); diff --git a/libyul/backends/evm/SSAControlFlowGraph.h b/libyul/backends/evm/SSAControlFlowGraph.h index fd24f06cbb2b..00f12fc71de6 100644 --- a/libyul/backends/evm/SSAControlFlowGraph.h +++ b/libyul/backends/evm/SSAControlFlowGraph.h @@ -37,6 +37,7 @@ namespace solidity::yul { +class SSACFGLiveness; class SSACFG { @@ -207,7 +208,11 @@ class SSACFG return it->second; } - std::string toDot(bool _includeDiGraphDefinition=true, std::optional _functionIndex=std::nullopt) const; + std::string toDot( + bool _includeDiGraphDefinition=true, + std::optional _functionIndex=std::nullopt, + SSACFGLiveness const* _liveness=nullptr + ) const; private: std::deque m_valueInfos; std::map m_literals; diff --git a/test/libyul/SSAControlFlowGraphTest.cpp b/test/libyul/SSAControlFlowGraphTest.cpp index c0d1e87270ef..5f0c79da534d 100644 --- a/test/libyul/SSAControlFlowGraphTest.cpp +++ b/test/libyul/SSAControlFlowGraphTest.cpp @@ -72,8 +72,8 @@ TestCase::TestResult SSAControlFlowGraphTest::run(std::ostream& _stream, std::st *m_dialect, object->code()->root() ); - - m_obtainedResult = controlFlow->toDot(); + ControlFlowLiveness liveness(*controlFlow); + m_obtainedResult = controlFlow->toDot(&liveness); auto result = checkResult(_stream, _linePrefix, _formatted); diff --git a/test/libyul/SSAControlFlowGraphTest.h b/test/libyul/SSAControlFlowGraphTest.h index f976be03c339..09c10448695c 100644 --- a/test/libyul/SSAControlFlowGraphTest.h +++ b/test/libyul/SSAControlFlowGraphTest.h @@ -1,18 +1,18 @@ /* -This file is part of solidity. + This file is part of solidity. -solidity is free software: you can redistribute it and/or modify + 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. + 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. + 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 . + You should have received a copy of the GNU General Public License + along with solidity. If not, see . */ // SPDX-License-Identifier: GPL-3.0 diff --git a/test/libyul/yulSSAControlFlowGraph/complex.yul b/test/libyul/yulSSAControlFlowGraph/complex.yul index eef0b29fa3c0..799e53d06d42 100644 --- a/test/libyul/yulSSAControlFlowGraph/complex.yul +++ b/test/libyul/yulSSAControlFlowGraph/complex.yul @@ -52,7 +52,8 @@ // Entry0 [label="Entry"]; // Entry0 -> Block0_0; // Block0_0 [label="\ -// Block 0\nv2 := f(2, 1)\l\ +// Block 0\nLiveIn: \l\ +// LiveOut: \l\nv2 := f(2, 1)\l\ // pop(v2)\l\ // "]; // Block0_0Exit [label="MainExit"]; @@ -61,12 +62,14 @@ // c := f(v0, v1)"]; // FunctionEntry_f_0 -> Block1_0; // Block1_0 [label="\ -// Block 0\n"]; +// Block 0\nLiveIn: v0,v1\l\ +// LiveOut: v0,v1\l\n"]; // Block1_0 -> Block1_0Exit [arrowhead=none]; // Block1_0Exit [label="Jump" shape=oval]; // Block1_0Exit -> Block1_1; // Block1_1 [label="\ -// Block 1\nv5 := φ(\l\ +// Block 1\nLiveIn: v0,v1,v5\l\ +// LiveOut: v0,v1,v5\l\nv5 := φ(\l\ // Block 0 => 42,\l\ // Block 21 => v43\l\ // )\l\ @@ -77,7 +80,8 @@ // Block1_1Exit:0 -> Block1_4; // Block1_1Exit:1 -> Block1_2; // Block1_2 [label="\ -// Block 2\nv7 := mload(v5)\l\ +// Block 2\nLiveIn: v0,v1,v5\l\ +// LiveOut: v0,v1,v5,v7\l\nv7 := mload(v5)\l\ // v8 := eq(0, v7)\l\ // "]; // Block1_2 -> Block1_2Exit; @@ -85,80 +89,93 @@ // Block1_2Exit:0 -> Block1_7; // Block1_2Exit:1 -> Block1_6; // Block1_4 [label="\ -// Block 4\nsstore(3084, 12)\l\ +// Block 4\nLiveIn: \l\ +// LiveOut: \l\nsstore(3084, 12)\l\ // "]; // Block1_4Exit [label="FunctionReturn[0]"]; // Block1_4 -> Block1_4Exit; // Block1_6 [label="\ -// Block 6\nsstore(514, 2)\l\ +// Block 6\nLiveIn: \l\ +// LiveOut: \l\nsstore(514, 2)\l\ // "]; // Block1_6 -> Block1_6Exit [arrowhead=none]; // Block1_6Exit [label="Jump" shape=oval]; // Block1_6Exit -> Block1_4; // Block1_7 [label="\ -// Block 7\nv13 := eq(1, v7)\l\ +// Block 7\nLiveIn: v0,v1,v5,v7\l\ +// LiveOut: v0,v1,v5,v7\l\nv13 := eq(1, v7)\l\ // "]; // Block1_7 -> Block1_7Exit; // Block1_7Exit [label="{ If v13| { <0> Zero | <1> NonZero }}" shape=Mrecord]; // Block1_7Exit:0 -> Block1_10; // Block1_7Exit:1 -> Block1_9; // Block1_9 [label="\ -// Block 9\nsstore(1028, 4)\l\ +// Block 9\nLiveIn: \l\ +// LiveOut: \l\nsstore(1028, 4)\l\ // "]; // Block1_9Exit [label="FunctionReturn[0]"]; // Block1_9 -> Block1_9Exit; // Block1_10 [label="\ -// Block 10\nv20 := eq(2, v7)\l\ +// Block 10\nLiveIn: v0,v1,v5,v7\l\ +// LiveOut: v0,v1,v5,v7\l\nv20 := eq(2, v7)\l\ // "]; // Block1_10 -> Block1_10Exit; // Block1_10Exit [label="{ If v20| { <0> Zero | <1> NonZero }}" shape=Mrecord]; // Block1_10Exit:0 -> Block1_13; // Block1_10Exit:1 -> Block1_12; // Block1_12 [label="\ -// Block 12\nsstore(1542, 6)\l\ +// Block 12\nLiveIn: \l\ +// LiveOut: \l\nsstore(1542, 6)\l\ // revert(0, 0)\l\ // "]; // Block1_12Exit [label="Terminated"]; // Block1_12 -> Block1_12Exit; // Block1_13 [label="\ -// Block 13\nv25 := eq(3, v7)\l\ +// Block 13\nLiveIn: v0,v1,v5,v7\l\ +// LiveOut: v0,v1,v5\l\nv25 := eq(3, v7)\l\ // "]; // Block1_13 -> Block1_13Exit; // Block1_13Exit [label="{ If v25| { <0> Zero | <1> NonZero }}" shape=Mrecord]; // Block1_13Exit:0 -> Block1_16; // Block1_13Exit:1 -> Block1_15; // Block1_15 [label="\ -// Block 15\nsstore(2056, 8)\l\ +// Block 15\nLiveIn: v0,v1,v5\l\ +// LiveOut: v0,v1,v5\l\nsstore(2056, 8)\l\ // "]; // Block1_15 -> Block1_15Exit [arrowhead=none]; // Block1_15Exit [label="Jump" shape=oval]; // Block1_15Exit -> Block1_5; // Block1_16 [label="\ -// Block 16\nv29 := mload(v1)\l\ +// Block 16\nLiveIn: v0,v1,v5\l\ +// LiveOut: v0,v1,v5\l\nv29 := mload(v1)\l\ // "]; // Block1_16 -> Block1_16Exit; // Block1_16Exit [label="{ If v29| { <0> Zero | <1> NonZero }}" shape=Mrecord]; // Block1_16Exit:0 -> Block1_18; // Block1_16Exit:1 -> Block1_17; // Block1_5 [label="\ -// Block 5\nsstore(2827, 11)\l\ +// Block 5\nLiveIn: v0,v1,v5\l\ +// LiveOut: v0,v1,v5\l\nsstore(2827, 11)\l\ // "]; // Block1_5 -> Block1_5Exit [arrowhead=none]; // Block1_5Exit [label="Jump" shape=oval]; // Block1_5Exit -> Block1_3; // Block1_17 [label="\ -// Block 17\nreturn(0, 0)\l\ +// Block 17\nLiveIn: \l\ +// LiveOut: \l\nreturn(0, 0)\l\ // "]; // Block1_17Exit [label="Terminated"]; // Block1_17 -> Block1_17Exit; // Block1_18 [label="\ -// Block 18\nsstore(2570, 10)\l\ +// Block 18\nLiveIn: v0,v1,v5\l\ +// LiveOut: v0,v1,v5\l\nsstore(2570, 10)\l\ // "]; // Block1_18 -> Block1_18Exit [arrowhead=none]; // Block1_18Exit [label="Jump" shape=oval]; // Block1_18Exit -> Block1_5; // Block1_3 [label="\ -// Block 3\nv43 := add(1, v5)\l\ +// Block 3\nLiveIn: v0,v1,v5\l\ +// LiveOut: v0,v1,v43\l\nv43 := add(1, v5)\l\ // v44 := calldataload(v43)\l\ // "]; // Block1_3 -> Block1_3Exit; @@ -166,12 +183,14 @@ // Block1_3Exit:0 -> Block1_21; // Block1_3Exit:1 -> Block1_20; // Block1_20 [label="\ -// Block 20\nsstore(v43, 0)\l\ +// Block 20\nLiveIn: v43\l\ +// LiveOut: \l\nsstore(v43, 0)\l\ // "]; // Block1_20Exit [label="FunctionReturn[0]"]; // Block1_20 -> Block1_20Exit; // Block1_21 [label="\ -// Block 21\nsstore(65535, 255)\l\ +// Block 21\nLiveIn: v0,v1,v43\l\ +// LiveOut: v0,v1,v43\l\nsstore(65535, 255)\l\ // "]; // Block1_21 -> Block1_21Exit [arrowhead=none]; // Block1_21Exit [label="Jump" shape=oval]; diff --git a/test/libyul/yulSSAControlFlowGraph/complex2.yul b/test/libyul/yulSSAControlFlowGraph/complex2.yul index 743b0513cc56..b35f341417a2 100644 --- a/test/libyul/yulSSAControlFlowGraph/complex2.yul +++ b/test/libyul/yulSSAControlFlowGraph/complex2.yul @@ -59,7 +59,8 @@ // Entry0 [label="Entry"]; // Entry0 -> Block0_0; // Block0_0 [label="\ -// Block 0\nsstore(1, 1)\l\ +// Block 0\nLiveIn: \l\ +// LiveOut: \l\nsstore(1, 1)\l\ // v2 := f(2, 1)\l\ // pop(v2)\l\ // v4 := sload(0)\l\ @@ -77,12 +78,14 @@ // c := f(v0, v1)"]; // FunctionEntry_f_0 -> Block1_0; // Block1_0 [label="\ -// Block 0\n"]; +// Block 0\nLiveIn: v0,v1\l\ +// LiveOut: v0,v1\l\n"]; // Block1_0 -> Block1_0Exit [arrowhead=none]; // Block1_0Exit [label="Jump" shape=oval]; // Block1_0Exit -> Block1_1; // Block1_1 [label="\ -// Block 1\nv5 := φ(\l\ +// Block 1\nLiveIn: v0,v1,v5\l\ +// LiveOut: v0,v1,v5\l\nv5 := φ(\l\ // Block 0 => 42,\l\ // Block 21 => v43\l\ // )\l\ @@ -93,7 +96,8 @@ // Block1_1Exit:0 -> Block1_4; // Block1_1Exit:1 -> Block1_2; // Block1_2 [label="\ -// Block 2\nv7 := mload(v5)\l\ +// Block 2\nLiveIn: v0,v1,v5\l\ +// LiveOut: v0,v1,v5,v7\l\nv7 := mload(v5)\l\ // v8 := eq(0, v7)\l\ // "]; // Block1_2 -> Block1_2Exit; @@ -101,80 +105,93 @@ // Block1_2Exit:0 -> Block1_7; // Block1_2Exit:1 -> Block1_6; // Block1_4 [label="\ -// Block 4\nsstore(3084, 12)\l\ +// Block 4\nLiveIn: \l\ +// LiveOut: \l\nsstore(3084, 12)\l\ // "]; // Block1_4Exit [label="FunctionReturn[27]"]; // Block1_4 -> Block1_4Exit; // Block1_6 [label="\ -// Block 6\nsstore(514, 2)\l\ +// Block 6\nLiveIn: \l\ +// LiveOut: \l\nsstore(514, 2)\l\ // "]; // Block1_6 -> Block1_6Exit [arrowhead=none]; // Block1_6Exit [label="Jump" shape=oval]; // Block1_6Exit -> Block1_4; // Block1_7 [label="\ -// Block 7\nv13 := eq(1, v7)\l\ +// Block 7\nLiveIn: v0,v1,v5,v7\l\ +// LiveOut: v0,v1,v5,v7\l\nv13 := eq(1, v7)\l\ // "]; // Block1_7 -> Block1_7Exit; // Block1_7Exit [label="{ If v13| { <0> Zero | <1> NonZero }}" shape=Mrecord]; // Block1_7Exit:0 -> Block1_10; // Block1_7Exit:1 -> Block1_9; // Block1_9 [label="\ -// Block 9\nsstore(1028, 4)\l\ +// Block 9\nLiveIn: \l\ +// LiveOut: \l\nsstore(1028, 4)\l\ // "]; // Block1_9Exit [label="FunctionReturn[0]"]; // Block1_9 -> Block1_9Exit; // Block1_10 [label="\ -// Block 10\nv20 := eq(2, v7)\l\ +// Block 10\nLiveIn: v0,v1,v5,v7\l\ +// LiveOut: v0,v1,v5,v7\l\nv20 := eq(2, v7)\l\ // "]; // Block1_10 -> Block1_10Exit; // Block1_10Exit [label="{ If v20| { <0> Zero | <1> NonZero }}" shape=Mrecord]; // Block1_10Exit:0 -> Block1_13; // Block1_10Exit:1 -> Block1_12; // Block1_12 [label="\ -// Block 12\nsstore(1542, 6)\l\ +// Block 12\nLiveIn: \l\ +// LiveOut: \l\nsstore(1542, 6)\l\ // revert(0, 0)\l\ // "]; // Block1_12Exit [label="Terminated"]; // Block1_12 -> Block1_12Exit; // Block1_13 [label="\ -// Block 13\nv25 := eq(3, v7)\l\ +// Block 13\nLiveIn: v0,v1,v5,v7\l\ +// LiveOut: v0,v1,v5\l\nv25 := eq(3, v7)\l\ // "]; // Block1_13 -> Block1_13Exit; // Block1_13Exit [label="{ If v25| { <0> Zero | <1> NonZero }}" shape=Mrecord]; // Block1_13Exit:0 -> Block1_16; // Block1_13Exit:1 -> Block1_15; // Block1_15 [label="\ -// Block 15\nsstore(2056, 8)\l\ +// Block 15\nLiveIn: v0,v1,v5\l\ +// LiveOut: v0,v1,v5\l\nsstore(2056, 8)\l\ // "]; // Block1_15 -> Block1_15Exit [arrowhead=none]; // Block1_15Exit [label="Jump" shape=oval]; // Block1_15Exit -> Block1_5; // Block1_16 [label="\ -// Block 16\nv29 := mload(v1)\l\ +// Block 16\nLiveIn: v0,v1,v5\l\ +// LiveOut: v0,v1,v5\l\nv29 := mload(v1)\l\ // "]; // Block1_16 -> Block1_16Exit; // Block1_16Exit [label="{ If v29| { <0> Zero | <1> NonZero }}" shape=Mrecord]; // Block1_16Exit:0 -> Block1_18; // Block1_16Exit:1 -> Block1_17; // Block1_5 [label="\ -// Block 5\nsstore(2827, 11)\l\ +// Block 5\nLiveIn: v0,v1,v5\l\ +// LiveOut: v0,v1,v5\l\nsstore(2827, 11)\l\ // "]; // Block1_5 -> Block1_5Exit [arrowhead=none]; // Block1_5Exit [label="Jump" shape=oval]; // Block1_5Exit -> Block1_3; // Block1_17 [label="\ -// Block 17\nreturn(0, 0)\l\ +// Block 17\nLiveIn: \l\ +// LiveOut: \l\nreturn(0, 0)\l\ // "]; // Block1_17Exit [label="Terminated"]; // Block1_17 -> Block1_17Exit; // Block1_18 [label="\ -// Block 18\nsstore(2570, 10)\l\ +// Block 18\nLiveIn: v0,v1,v5\l\ +// LiveOut: v0,v1,v5\l\nsstore(2570, 10)\l\ // "]; // Block1_18 -> Block1_18Exit [arrowhead=none]; // Block1_18Exit [label="Jump" shape=oval]; // Block1_18Exit -> Block1_5; // Block1_3 [label="\ -// Block 3\nv43 := add(1, v5)\l\ +// Block 3\nLiveIn: v0,v1,v5\l\ +// LiveOut: v0,v1,v43\l\nv43 := add(1, v5)\l\ // v44 := calldataload(v43)\l\ // "]; // Block1_3 -> Block1_3Exit; @@ -182,12 +199,14 @@ // Block1_3Exit:0 -> Block1_21; // Block1_3Exit:1 -> Block1_20; // Block1_20 [label="\ -// Block 20\nsstore(v43, 0)\l\ +// Block 20\nLiveIn: v43\l\ +// LiveOut: \l\nsstore(v43, 0)\l\ // "]; // Block1_20Exit [label="FunctionReturn[0]"]; // Block1_20 -> Block1_20Exit; // Block1_21 [label="\ -// Block 21\nsstore(65535, 255)\l\ +// Block 21\nLiveIn: v0,v1,v43\l\ +// LiveOut: v0,v1,v43\l\nsstore(65535, 255)\l\ // "]; // Block1_21 -> Block1_21Exit [arrowhead=none]; // Block1_21Exit [label="Jump" shape=oval]; diff --git a/test/libyul/yulSSAControlFlowGraph/function.yul b/test/libyul/yulSSAControlFlowGraph/function.yul index 20a536b5e556..1b759f8b395a 100644 --- a/test/libyul/yulSSAControlFlowGraph/function.yul +++ b/test/libyul/yulSSAControlFlowGraph/function.yul @@ -27,7 +27,8 @@ // Entry0 [label="Entry"]; // Entry0 -> Block0_0; // Block0_0 [label="\ -// Block 0\nv0, v1 := i()\l\ +// Block 0\nLiveIn: \l\ +// LiveOut: \l\nv0, v1 := i()\l\ // h(v0)\l\ // "]; // Block0_0Exit [label="Terminated"]; @@ -36,7 +37,8 @@ // r := f(v0, v1)"]; // FunctionEntry_f_0 -> Block1_0; // Block1_0 [label="\ -// Block 0\nv3 := add(v1, v0)\l\ +// Block 0\nLiveIn: v0,v1\l\ +// LiveOut: v4\l\nv3 := add(v1, v0)\l\ // v4 := sub(v0, v3)\l\ // "]; // Block1_0Exit [label="FunctionReturn[v4]"]; @@ -45,7 +47,8 @@ // g()"]; // FunctionEntry_g_0 -> Block2_0; // Block2_0 [label="\ -// Block 0\nsstore(257, 1)\l\ +// Block 0\nLiveIn: \l\ +// LiveOut: \l\nsstore(257, 1)\l\ // "]; // Block2_0Exit [label="FunctionReturn[]"]; // Block2_0 -> Block2_0Exit; @@ -53,7 +56,8 @@ // h(v0)"]; // FunctionEntry_h_0 -> Block3_0; // Block3_0 [label="\ -// Block 0\nv2 := f(0, v0)\l\ +// Block 0\nLiveIn: v0\l\ +// LiveOut: \l\nv2 := f(0, v0)\l\ // h(v2)\l\ // "]; // Block3_0Exit [label="Terminated"]; @@ -62,7 +66,8 @@ // v, w := i()"]; // FunctionEntry_i_0 -> Block4_0; // Block4_0 [label="\ -// Block 0\n"]; +// Block 0\nLiveIn: \l\ +// LiveOut: \l\n"]; // Block4_0Exit [label="FunctionReturn[514, 771]"]; // Block4_0 -> Block4_0Exit; // } diff --git a/test/libyul/yulSSAControlFlowGraph/if.yul b/test/libyul/yulSSAControlFlowGraph/if.yul index 9045d8034003..9c4d73a13a25 100644 --- a/test/libyul/yulSSAControlFlowGraph/if.yul +++ b/test/libyul/yulSSAControlFlowGraph/if.yul @@ -15,20 +15,23 @@ // Entry0 [label="Entry"]; // Entry0 -> Block0_0; // Block0_0 [label="\ -// Block 0\nv1 := calldataload(3)\l\ +// Block 0\nLiveIn: \l\ +// LiveOut: v1\l\nv1 := calldataload(3)\l\ // "]; // Block0_0 -> Block0_0Exit; // Block0_0Exit [label="{ If 0| { <0> Zero | <1> NonZero }}" shape=Mrecord]; // Block0_0Exit:0 -> Block0_2; // Block0_0Exit:1 -> Block0_1; // Block0_1 [label="\ -// Block 1\nv4 := calldataload(77)\l\ +// Block 1\nLiveIn: \l\ +// LiveOut: v4\l\nv4 := calldataload(77)\l\ // "]; // Block0_1 -> Block0_1Exit [arrowhead=none]; // Block0_1Exit [label="Jump" shape=oval]; // Block0_1Exit -> Block0_2; // Block0_2 [label="\ -// Block 2\nv5 := φ(\l\ +// Block 2\nLiveIn: v5\l\ +// LiveOut: \l\nv5 := φ(\l\ // Block 0 => v1,\l\ // Block 1 => v4\l\ // )\l\ diff --git a/test/libyul/yulSSAControlFlowGraph/switch.yul b/test/libyul/yulSSAControlFlowGraph/switch.yul index f6c084b001a7..d744bd7bd247 100644 --- a/test/libyul/yulSSAControlFlowGraph/switch.yul +++ b/test/libyul/yulSSAControlFlowGraph/switch.yul @@ -22,7 +22,8 @@ // Entry0 [label="Entry"]; // Entry0 -> Block0_0; // Block0_0 [label="\ -// Block 0\nv1 := calldataload(3)\l\ +// Block 0\nLiveIn: \l\ +// LiveOut: v3\l\nv1 := calldataload(3)\l\ // v3 := sload(0)\l\ // v4 := eq(0, v3)\l\ // "]; @@ -31,20 +32,23 @@ // Block0_0Exit:0 -> Block0_3; // Block0_0Exit:1 -> Block0_2; // Block0_2 [label="\ -// Block 2\nv6 := calldataload(77)\l\ +// Block 2\nLiveIn: \l\ +// LiveOut: v6\l\nv6 := calldataload(77)\l\ // "]; // Block0_2 -> Block0_2Exit [arrowhead=none]; // Block0_2Exit [label="Jump" shape=oval]; // Block0_2Exit -> Block0_1; // Block0_3 [label="\ -// Block 3\nv7 := eq(1, v3)\l\ +// Block 3\nLiveIn: v3\l\ +// LiveOut: \l\nv7 := eq(1, v3)\l\ // "]; // Block0_3 -> Block0_3Exit; // Block0_3Exit [label="{ If v7| { <0> Zero | <1> NonZero }}" shape=Mrecord]; // Block0_3Exit:0 -> Block0_5; // Block0_3Exit:1 -> Block0_4; // Block0_1 [label="\ -// Block 1\nv13 := φ(\l\ +// Block 1\nLiveIn: v13\l\ +// LiveOut: \l\nv13 := φ(\l\ // Block 2 => v6,\l\ // Block 4 => v10,\l\ // Block 5 => v12\l\ @@ -54,13 +58,15 @@ // Block0_1Exit [label="MainExit"]; // Block0_1 -> Block0_1Exit; // Block0_4 [label="\ -// Block 4\nv10 := calldataload(88)\l\ +// Block 4\nLiveIn: \l\ +// LiveOut: v10\l\nv10 := calldataload(88)\l\ // "]; // Block0_4 -> Block0_4Exit [arrowhead=none]; // Block0_4Exit [label="Jump" shape=oval]; // Block0_4Exit -> Block0_1; // Block0_5 [label="\ -// Block 5\nv12 := calldataload(99)\l\ +// Block 5\nLiveIn: \l\ +// LiveOut: v12\l\nv12 := calldataload(99)\l\ // "]; // Block0_5 -> Block0_5Exit [arrowhead=none]; // Block0_5Exit [label="Jump" shape=oval]; From f35fd1f6df3f0d341ead02d9a83c39f018ba168e Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Wed, 18 Sep 2024 15:01:25 +0200 Subject: [PATCH 0483/1022] Yul: display dotted back edges in toDot --- libyul/backends/evm/SSACFGLiveness.cpp | 8 +- libyul/backends/evm/SSACFGLiveness.h | 2 +- libyul/backends/evm/SSACFGTopologicalSort.h | 2 + libyul/backends/evm/SSAControlFlowGraph.cpp | 111 ++++++++----- .../libyul/yulSSAControlFlowGraph/complex.yul | 92 +++++------ .../yulSSAControlFlowGraph/complex2.yul | 92 +++++------ .../yulSSAControlFlowGraph/function.yul | 10 +- test/libyul/yulSSAControlFlowGraph/if.yul | 14 +- .../yulSSAControlFlowGraph/nested_for.yul | 151 ++++++++++-------- .../nested_function.yul | 55 ++++--- test/libyul/yulSSAControlFlowGraph/switch.yul | 30 ++-- 11 files changed, 313 insertions(+), 254 deletions(-) diff --git a/libyul/backends/evm/SSACFGLiveness.cpp b/libyul/backends/evm/SSACFGLiveness.cpp index 6ed926304db2..b9513f70dfce 100644 --- a/libyul/backends/evm/SSACFGLiveness.cpp +++ b/libyul/backends/evm/SSACFGLiveness.cpp @@ -38,7 +38,7 @@ SSACFGLiveness::SSACFGLiveness(SSACFG const& _cfg): void SSACFGLiveness::runDagDfs() { // SSA Book, Algorithm 9.2 - for(auto const blockIdValue: m_topologicalSort.postOrder()) + for (auto const blockIdValue: m_topologicalSort.postOrder()) { // post-order traversal SSACFG::BlockId blockId{blockIdValue}; @@ -85,11 +85,7 @@ void SSACFGLiveness::runDagDfs() | ranges::views::filter(filterLiterals); // clean out unreachables - live = live - | ranges::views::filter( - [&](auto const& valueId) - { return !std::holds_alternative(m_cfg.valueInfo(valueId)); }) - | ranges::to; + live = live | ranges::views::filter([&](auto const& valueId) { return !std::holds_alternative(m_cfg.valueInfo(valueId)); }) | ranges::to; // LiveOut(B) <- live m_liveOuts[blockId.value] = live; diff --git a/libyul/backends/evm/SSACFGLiveness.h b/libyul/backends/evm/SSACFGLiveness.h index bc254a03a24b..6f486b737f13 100644 --- a/libyul/backends/evm/SSACFGLiveness.h +++ b/libyul/backends/evm/SSACFGLiveness.h @@ -39,7 +39,7 @@ class SSACFGLiveness std::vector> const& liveIns() const { return m_liveIns; } std::vector> const& liveOuts() const { return m_liveOuts; } - + ForwardSSACFGTopologicalSort const& topologicalSort() const { return m_topologicalSort; } private: void runDagDfs(); diff --git a/libyul/backends/evm/SSACFGTopologicalSort.h b/libyul/backends/evm/SSACFGTopologicalSort.h index 973f286f286a..025054b9504c 100644 --- a/libyul/backends/evm/SSACFGTopologicalSort.h +++ b/libyul/backends/evm/SSACFGTopologicalSort.h @@ -38,6 +38,8 @@ class ForwardSSACFGTopologicalSort std::set const& backEdgeTargets() const { return m_backEdgeTargets; } SSACFG const& cfg() const { return m_cfg; } bool backEdge(SSACFG::BlockId const& _block1, SSACFG::BlockId const& _block2) const; + size_t preOrderIndexOf(size_t _block) const { return m_blockWisePreOrder[_block]; } + size_t maxSubtreePreOrderIndexOf(size_t _block) const { return m_blockWiseMaxSubtreePreOrder[_block]; } private: void dfs(size_t _vertex); diff --git a/libyul/backends/evm/SSAControlFlowGraph.cpp b/libyul/backends/evm/SSAControlFlowGraph.cpp index dcbdcdca3b0c..ebd6d84a9680 100644 --- a/libyul/backends/evm/SSAControlFlowGraph.cpp +++ b/libyul/backends/evm/SSAControlFlowGraph.cpp @@ -40,14 +40,14 @@ class SSACFGPrinter { public: SSACFGPrinter(SSACFG const& _cfg, SSACFG::BlockId _blockId, SSACFGLiveness const* _liveness): - m_liveness(_liveness) + m_cfg(_cfg), m_functionIndex(0), m_liveness(_liveness) { - printBlock(_cfg, _blockId, 0); + printBlock(_blockId); } SSACFGPrinter(SSACFG const& _cfg, size_t _functionIndex, Scope::Function const& _function, SSACFGLiveness const* _liveness): - m_liveness(_liveness) + m_cfg(_cfg), m_functionIndex(_functionIndex), m_liveness(_liveness) { - printFunction(_cfg, _functionIndex, _function); + printFunction(_function); } friend std::ostream& operator<<(std::ostream& stream, SSACFGPrinter const& printer) { stream << printer.m_result.str(); @@ -77,6 +77,20 @@ class SSACFGPrinter ); } + std::string formatBlockHandle(SSACFG::BlockId const& _id) const + { + return fmt::format("Block{}_{}", m_functionIndex, _id.value); + } + + std::string formatEdge(SSACFG::BlockId const& _v, SSACFG::BlockId const& _w, std::optional const& _vPort = std::nullopt) + { + std::string const style = m_liveness && m_liveness->topologicalSort().backEdge(_v, _w) ? "dashed" : "solid"; + if (_vPort) + return fmt::format("{}Exit:{} -> {} [style=\"{}\"];\n", formatBlockHandle(_v), *_vPort, formatBlockHandle(_w), style); + else + return fmt::format("{}Exit -> {} [style=\"{}\"];\n", formatBlockHandle(_v), formatBlockHandle(_w), style); + } + static std::string formatPhi(SSACFG const& _cfg, SSACFG::PhiValue const& _phiValue) { auto const transform = [&](SSACFG::ValueId const& valueId) { return varToString(_cfg, valueId); }; @@ -90,19 +104,25 @@ class SSACFGPrinter return "φ()"; } - void writeBlock(SSACFG const& _cfg, SSACFG::BlockId const& _id, SSACFG::BasicBlock const& _block, size_t const _functionIndex) + void writeBlock(SSACFG::BlockId const& _id, SSACFG::BasicBlock const& _block) { - auto const valueToString = [&](SSACFG::ValueId const& valueId) { return varToString(_cfg, valueId); }; - bool entryBlock = _id.value == 0 && _functionIndex == 0; + auto const valueToString = [&](SSACFG::ValueId const& valueId) { return varToString(m_cfg, valueId); }; + bool entryBlock = _id.value == 0 && m_functionIndex == 0; if (entryBlock) { - m_result << fmt::format("Entry{} [label=\"Entry\"];\n", _functionIndex); - m_result << fmt::format("Entry{} -> Block{}_{};\n", _functionIndex, _functionIndex, _id.value); + m_result << fmt::format("Entry{} [label=\"Entry\"];\n", m_functionIndex); + m_result << fmt::format("Entry{} -> {};\n", m_functionIndex, formatBlockHandle(_id)); } { - m_result << fmt::format("Block{1}_{0} [label=\"\\\nBlock {0}\\n", _id.value, _functionIndex); if (m_liveness) { + m_result << fmt::format( + "{} [label=\"\\\nBlock {}; ({}, max {})\\n", + formatBlockHandle(_id), + _id.value, + m_liveness->topologicalSort().preOrderIndexOf(_id.value), + m_liveness->topologicalSort().maxSubtreePreOrderIndexOf(_id.value) + ); m_result << fmt::format( "LiveIn: {}\\l\\\n", fmt::join(m_liveness->liveIns()[_id.value] | ranges::views::transform(valueToString), ",") @@ -112,11 +132,13 @@ class SSACFGPrinter fmt::join(m_liveness->liveOuts()[_id.value] | ranges::views::transform(valueToString), ",") ); } + else + m_result << fmt::format("{} [label=\"\\\nBlock {}\\n", formatBlockHandle(_id), _id.value); for (auto const& phi: _block.phis) { - auto const* phiValue = std::get_if(&_cfg.valueInfo(phi)); + auto const* phiValue = std::get_if(&m_cfg.valueInfo(phi)); solAssert(phiValue); - m_result << fmt::format("v{} := {}\\l\\\n", phi.value, formatPhi(_cfg, *phiValue)); + m_result << fmt::format("v{} := {}\\l\\\n", phi.value, formatPhi(m_cfg, *phiValue)); } for (auto const& operation: _block.operations) { @@ -143,29 +165,28 @@ class SSACFGPrinter std::visit(GenericVisitor{ [&](SSACFG::BasicBlock::MainExit const&) { - m_result << fmt::format("Block{}_{}Exit [label=\"MainExit\"];\n", _functionIndex, _id.value); - m_result << fmt::format("Block{1}_{0} -> Block{1}_{0}Exit;\n", _id.value, _functionIndex); + m_result << fmt::format("{}Exit [label=\"MainExit\"];\n", formatBlockHandle(_id)); + m_result << fmt::format("{} -> {}Exit;\n", formatBlockHandle(_id), formatBlockHandle(_id)); }, [&](SSACFG::BasicBlock::Jump const& _jump) { - m_result << fmt::format("Block{1}_{0} -> Block{1}_{0}Exit [arrowhead=none];\n", _id.value, _functionIndex); - m_result << fmt::format("Block{}_{}Exit [label=\"Jump\" shape=oval];\n", _functionIndex, _id.value); - m_result << fmt::format("Block{}_{}Exit -> Block{}_{};\n", _functionIndex, _id.value, _functionIndex, _jump.target.value); + m_result << fmt::format("{} -> {}Exit [arrowhead=none];\n", formatBlockHandle(_id), formatBlockHandle(_id)); + m_result << fmt::format("{}Exit [label=\"Jump\" shape=oval];\n", formatBlockHandle(_id)); + m_result << formatEdge(_id, _jump.target); }, [&](SSACFG::BasicBlock::ConditionalJump const& _conditionalJump) { - m_result << "Block" << _functionIndex << "_" << _id.value << " -> Block" << _functionIndex << "_" << _id.value << "Exit;\n"; - m_result << "Block" << _functionIndex << "_" << _id.value << "Exit [label=\"{ If "; - m_result << varToString(_cfg, _conditionalJump.condition); - m_result << "| { <0> Zero | <1> NonZero }}\" shape=Mrecord];\n"; - m_result << "Block" << _functionIndex << "_" << _id.value; - m_result << "Exit:0 -> Block" << _functionIndex << "_" << _conditionalJump.zero.value << ";\n"; - m_result << "Block" << _functionIndex << "_" << _id.value; - m_result << "Exit:1 -> Block" << _functionIndex << "_" << _conditionalJump.nonZero.value << ";\n"; + m_result << fmt::format("{} -> {}Exit;\n", formatBlockHandle(_id), formatBlockHandle(_id)); + m_result << fmt::format( + "{}Exit [label=\"{{ If {} | {{ <0> Zero | <1> NonZero }}}}\" shape=Mrecord];\n", + formatBlockHandle(_id), varToString(m_cfg, _conditionalJump.condition) + ); + m_result << formatEdge(_id, _conditionalJump.zero, "0"); + m_result << formatEdge(_id, _conditionalJump.nonZero, "1"); }, [&](SSACFG::BasicBlock::JumpTable const& jt) { - m_result << "Block" << _functionIndex << "_" << _id.value << " -> Block" << _functionIndex << "_" << _id.value << "Exit;\n"; + m_result << fmt::format("{} -> {}Exit;\n", formatBlockHandle(_id), formatBlockHandle(_id)); std::string options; for (auto const& jumpCase: jt.cases) { @@ -176,28 +197,28 @@ class SSACFGPrinter if (!options.empty()) options += " | "; options += " default"; - m_result << fmt::format("Block{}_{}Exit [label=\"{{ JT | {{ {} }} }}\" shape=Mrecord];\n", _functionIndex, _id.value, options); + m_result << fmt::format("{}Exit [label=\"{{ JT | {{ {} }} }}\" shape=Mrecord];\n", formatBlockHandle(_id), options); for (auto const& jumpCase: jt.cases) - m_result << fmt::format("Block{}_{}Exit:{} -> Block{}_{};\n", _functionIndex, _id.value, formatNumber(jumpCase.first), _functionIndex, jumpCase.second.value); - m_result << fmt::format("Block{}_{}Exit:default -> Block{}_{};\n", _functionIndex, _id.value, _functionIndex, jt.defaultCase.value); + m_result << formatEdge(_id, jumpCase.second, formatNumber(jumpCase.first)); + m_result << formatEdge(_id, jt.defaultCase, "default"); }, [&](SSACFG::BasicBlock::FunctionReturn const& fr) { - m_result << "Block" << _functionIndex << "_" << _id.value << "Exit [label=\"FunctionReturn[" + m_result << formatBlockHandle(_id) << "Exit [label=\"FunctionReturn[" << fmt::format("{}", fmt::join(fr.returnValues | ranges::views::transform(valueToString), ", ")) << "]\"];\n"; - m_result << "Block" << _functionIndex << "_" << _id.value << " -> Block" << _functionIndex << "_" << _id.value << "Exit;\n"; + m_result << formatBlockHandle(_id) << " -> " << formatBlockHandle(_id) << "Exit;\n"; }, [&](SSACFG::BasicBlock::Terminated const&) { - m_result << "Block" << _functionIndex << "_" << _id.value << "Exit [label=\"Terminated\"];\n"; - m_result << "Block" << _functionIndex << "_" << _id.value << " -> Block" << _functionIndex << "_" << _id.value << "Exit;\n"; + m_result << formatBlockHandle(_id) << "Exit [label=\"Terminated\"];\n"; + m_result << formatBlockHandle(_id) << " -> " << formatBlockHandle(_id) << "Exit;\n"; } }, _block.exit); } } - void printBlock(SSACFG const& _cfg, SSACFG::BlockId const& _rootId, size_t const _functionIndex) + void printBlock(SSACFG::BlockId const& _rootId) { std::set explored{}; explored.insert(_rootId); @@ -209,8 +230,8 @@ class SSACFGPrinter { auto const id = toVisit.front(); toVisit.pop_front(); - auto const& block = _cfg.block(id); - writeBlock(_cfg, id, block, _functionIndex); + auto const& block = m_cfg.block(id); + writeBlock(id, block); block.forEachExit( [&](SSACFG::BlockId const& _exitBlock) { @@ -224,22 +245,24 @@ class SSACFGPrinter } } - void printFunction(SSACFG const& _cfg, size_t const _functionIndex, Scope::Function const& _fun) + void printFunction(Scope::Function const& _fun) { static auto constexpr returnsTransform = [](auto const& functionReturnValue) { return functionReturnValue.get().name.str(); }; static auto constexpr argsTransform = [](auto const& arg) { return fmt::format("v{}", std::get<1>(arg).value); }; - m_result << "FunctionEntry_" << _fun.name.str() << "_" << _cfg.entry.value << " [label=\""; - if (!_cfg.returns.empty()) - m_result << fmt::format("function {0}:\n {1} := {0}({2})", _fun.name.str(), fmt::join(_cfg.returns | ranges::views::transform(returnsTransform), ", "), fmt::join(_cfg.arguments | ranges::views::transform(argsTransform), ", ")); + m_result << "FunctionEntry_" << _fun.name.str() << "_" << m_cfg.entry.value << " [label=\""; + if (!m_cfg.returns.empty()) + m_result << fmt::format("function {0}:\n {1} := {0}({2})", _fun.name.str(), fmt::join(m_cfg.returns | ranges::views::transform(returnsTransform), ", "), fmt::join(m_cfg.arguments | ranges::views::transform(argsTransform), ", ")); else - m_result << fmt::format("function {0}:\n {0}({1})", _fun.name.str(), fmt::join(_cfg.arguments | ranges::views::transform(argsTransform), ", ")); + m_result << fmt::format("function {0}:\n {0}({1})", _fun.name.str(), fmt::join(m_cfg.arguments | ranges::views::transform(argsTransform), ", ")); m_result << "\"];\n"; - m_result << "FunctionEntry_" << _fun.name.str() << "_" << _cfg.entry.value << " -> Block" << _functionIndex << "_" << _cfg.entry.value << ";\n"; - printBlock(_cfg, _cfg.entry, _functionIndex); + m_result << "FunctionEntry_" << _fun.name.str() << "_" << m_cfg.entry.value << " -> Block" << m_functionIndex << "_" << m_cfg.entry.value << ";\n"; + printBlock(m_cfg.entry); } - std::stringstream m_result{}; + SSACFG const& m_cfg; + size_t m_functionIndex; SSACFGLiveness const* m_liveness; + std::stringstream m_result{}; }; } diff --git a/test/libyul/yulSSAControlFlowGraph/complex.yul b/test/libyul/yulSSAControlFlowGraph/complex.yul index 799e53d06d42..6fb0453c186b 100644 --- a/test/libyul/yulSSAControlFlowGraph/complex.yul +++ b/test/libyul/yulSSAControlFlowGraph/complex.yul @@ -52,7 +52,7 @@ // Entry0 [label="Entry"]; // Entry0 -> Block0_0; // Block0_0 [label="\ -// Block 0\nLiveIn: \l\ +// Block 0; (0, max 0)\nLiveIn: \l\ // LiveOut: \l\nv2 := f(2, 1)\l\ // pop(v2)\l\ // "]; @@ -62,13 +62,13 @@ // c := f(v0, v1)"]; // FunctionEntry_f_0 -> Block1_0; // Block1_0 [label="\ -// Block 0\nLiveIn: v0,v1\l\ +// Block 0; (0, max 17)\nLiveIn: v0,v1\l\ // LiveOut: v0,v1\l\n"]; // Block1_0 -> Block1_0Exit [arrowhead=none]; // Block1_0Exit [label="Jump" shape=oval]; -// Block1_0Exit -> Block1_1; +// Block1_0Exit -> Block1_1 [style="solid"]; // Block1_1 [label="\ -// Block 1\nLiveIn: v0,v1,v5\l\ +// Block 1; (1, max 17)\nLiveIn: v0,v1,v5\l\ // LiveOut: v0,v1,v5\l\nv5 := φ(\l\ // Block 0 => 42,\l\ // Block 21 => v43\l\ @@ -76,123 +76,123 @@ // v6 := lt(v0, v5)\l\ // "]; // Block1_1 -> Block1_1Exit; -// Block1_1Exit [label="{ If v6| { <0> Zero | <1> NonZero }}" shape=Mrecord]; -// Block1_1Exit:0 -> Block1_4; -// Block1_1Exit:1 -> Block1_2; +// Block1_1Exit [label="{ If v6 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; +// Block1_1Exit:0 -> Block1_4 [style="solid"]; +// Block1_1Exit:1 -> Block1_2 [style="solid"]; // Block1_2 [label="\ -// Block 2\nLiveIn: v0,v1,v5\l\ +// Block 2; (2, max 17)\nLiveIn: v0,v1,v5\l\ // LiveOut: v0,v1,v5,v7\l\nv7 := mload(v5)\l\ // v8 := eq(0, v7)\l\ // "]; // Block1_2 -> Block1_2Exit; -// Block1_2Exit [label="{ If v8| { <0> Zero | <1> NonZero }}" shape=Mrecord]; -// Block1_2Exit:0 -> Block1_7; -// Block1_2Exit:1 -> Block1_6; +// Block1_2Exit [label="{ If v8 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; +// Block1_2Exit:0 -> Block1_7 [style="solid"]; +// Block1_2Exit:1 -> Block1_6 [style="solid"]; // Block1_4 [label="\ -// Block 4\nLiveIn: \l\ +// Block 4; (4, max 4)\nLiveIn: \l\ // LiveOut: \l\nsstore(3084, 12)\l\ // "]; // Block1_4Exit [label="FunctionReturn[0]"]; // Block1_4 -> Block1_4Exit; // Block1_6 [label="\ -// Block 6\nLiveIn: \l\ +// Block 6; (3, max 4)\nLiveIn: \l\ // LiveOut: \l\nsstore(514, 2)\l\ // "]; // Block1_6 -> Block1_6Exit [arrowhead=none]; // Block1_6Exit [label="Jump" shape=oval]; -// Block1_6Exit -> Block1_4; +// Block1_6Exit -> Block1_4 [style="solid"]; // Block1_7 [label="\ -// Block 7\nLiveIn: v0,v1,v5,v7\l\ +// Block 7; (5, max 17)\nLiveIn: v0,v1,v5,v7\l\ // LiveOut: v0,v1,v5,v7\l\nv13 := eq(1, v7)\l\ // "]; // Block1_7 -> Block1_7Exit; -// Block1_7Exit [label="{ If v13| { <0> Zero | <1> NonZero }}" shape=Mrecord]; -// Block1_7Exit:0 -> Block1_10; -// Block1_7Exit:1 -> Block1_9; +// Block1_7Exit [label="{ If v13 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; +// Block1_7Exit:0 -> Block1_10 [style="solid"]; +// Block1_7Exit:1 -> Block1_9 [style="solid"]; // Block1_9 [label="\ -// Block 9\nLiveIn: \l\ +// Block 9; (6, max 6)\nLiveIn: \l\ // LiveOut: \l\nsstore(1028, 4)\l\ // "]; // Block1_9Exit [label="FunctionReturn[0]"]; // Block1_9 -> Block1_9Exit; // Block1_10 [label="\ -// Block 10\nLiveIn: v0,v1,v5,v7\l\ +// Block 10; (7, max 17)\nLiveIn: v0,v1,v5,v7\l\ // LiveOut: v0,v1,v5,v7\l\nv20 := eq(2, v7)\l\ // "]; // Block1_10 -> Block1_10Exit; -// Block1_10Exit [label="{ If v20| { <0> Zero | <1> NonZero }}" shape=Mrecord]; -// Block1_10Exit:0 -> Block1_13; -// Block1_10Exit:1 -> Block1_12; +// Block1_10Exit [label="{ If v20 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; +// Block1_10Exit:0 -> Block1_13 [style="solid"]; +// Block1_10Exit:1 -> Block1_12 [style="solid"]; // Block1_12 [label="\ -// Block 12\nLiveIn: \l\ +// Block 12; (8, max 8)\nLiveIn: \l\ // LiveOut: \l\nsstore(1542, 6)\l\ // revert(0, 0)\l\ // "]; // Block1_12Exit [label="Terminated"]; // Block1_12 -> Block1_12Exit; // Block1_13 [label="\ -// Block 13\nLiveIn: v0,v1,v5,v7\l\ +// Block 13; (9, max 17)\nLiveIn: v0,v1,v5,v7\l\ // LiveOut: v0,v1,v5\l\nv25 := eq(3, v7)\l\ // "]; // Block1_13 -> Block1_13Exit; -// Block1_13Exit [label="{ If v25| { <0> Zero | <1> NonZero }}" shape=Mrecord]; -// Block1_13Exit:0 -> Block1_16; -// Block1_13Exit:1 -> Block1_15; +// Block1_13Exit [label="{ If v25 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; +// Block1_13Exit:0 -> Block1_16 [style="solid"]; +// Block1_13Exit:1 -> Block1_15 [style="solid"]; // Block1_15 [label="\ -// Block 15\nLiveIn: v0,v1,v5\l\ +// Block 15; (10, max 14)\nLiveIn: v0,v1,v5\l\ // LiveOut: v0,v1,v5\l\nsstore(2056, 8)\l\ // "]; // Block1_15 -> Block1_15Exit [arrowhead=none]; // Block1_15Exit [label="Jump" shape=oval]; -// Block1_15Exit -> Block1_5; +// Block1_15Exit -> Block1_5 [style="solid"]; // Block1_16 [label="\ -// Block 16\nLiveIn: v0,v1,v5\l\ +// Block 16; (15, max 17)\nLiveIn: v0,v1,v5\l\ // LiveOut: v0,v1,v5\l\nv29 := mload(v1)\l\ // "]; // Block1_16 -> Block1_16Exit; -// Block1_16Exit [label="{ If v29| { <0> Zero | <1> NonZero }}" shape=Mrecord]; -// Block1_16Exit:0 -> Block1_18; -// Block1_16Exit:1 -> Block1_17; +// Block1_16Exit [label="{ If v29 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; +// Block1_16Exit:0 -> Block1_18 [style="solid"]; +// Block1_16Exit:1 -> Block1_17 [style="solid"]; // Block1_5 [label="\ -// Block 5\nLiveIn: v0,v1,v5\l\ +// Block 5; (11, max 14)\nLiveIn: v0,v1,v5\l\ // LiveOut: v0,v1,v5\l\nsstore(2827, 11)\l\ // "]; // Block1_5 -> Block1_5Exit [arrowhead=none]; // Block1_5Exit [label="Jump" shape=oval]; -// Block1_5Exit -> Block1_3; +// Block1_5Exit -> Block1_3 [style="solid"]; // Block1_17 [label="\ -// Block 17\nLiveIn: \l\ +// Block 17; (16, max 16)\nLiveIn: \l\ // LiveOut: \l\nreturn(0, 0)\l\ // "]; // Block1_17Exit [label="Terminated"]; // Block1_17 -> Block1_17Exit; // Block1_18 [label="\ -// Block 18\nLiveIn: v0,v1,v5\l\ +// Block 18; (17, max 17)\nLiveIn: v0,v1,v5\l\ // LiveOut: v0,v1,v5\l\nsstore(2570, 10)\l\ // "]; // Block1_18 -> Block1_18Exit [arrowhead=none]; // Block1_18Exit [label="Jump" shape=oval]; -// Block1_18Exit -> Block1_5; +// Block1_18Exit -> Block1_5 [style="solid"]; // Block1_3 [label="\ -// Block 3\nLiveIn: v0,v1,v5\l\ +// Block 3; (12, max 14)\nLiveIn: v0,v1,v5\l\ // LiveOut: v0,v1,v43\l\nv43 := add(1, v5)\l\ // v44 := calldataload(v43)\l\ // "]; // Block1_3 -> Block1_3Exit; -// Block1_3Exit [label="{ If v44| { <0> Zero | <1> NonZero }}" shape=Mrecord]; -// Block1_3Exit:0 -> Block1_21; -// Block1_3Exit:1 -> Block1_20; +// Block1_3Exit [label="{ If v44 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; +// Block1_3Exit:0 -> Block1_21 [style="solid"]; +// Block1_3Exit:1 -> Block1_20 [style="solid"]; // Block1_20 [label="\ -// Block 20\nLiveIn: v43\l\ +// Block 20; (13, max 13)\nLiveIn: v43\l\ // LiveOut: \l\nsstore(v43, 0)\l\ // "]; // Block1_20Exit [label="FunctionReturn[0]"]; // Block1_20 -> Block1_20Exit; // Block1_21 [label="\ -// Block 21\nLiveIn: v0,v1,v43\l\ +// Block 21; (14, max 14)\nLiveIn: v0,v1,v43\l\ // LiveOut: v0,v1,v43\l\nsstore(65535, 255)\l\ // "]; // Block1_21 -> Block1_21Exit [arrowhead=none]; // Block1_21Exit [label="Jump" shape=oval]; -// Block1_21Exit -> Block1_1; +// Block1_21Exit -> Block1_1 [style="dashed"]; // } diff --git a/test/libyul/yulSSAControlFlowGraph/complex2.yul b/test/libyul/yulSSAControlFlowGraph/complex2.yul index b35f341417a2..c3ea8b94f8aa 100644 --- a/test/libyul/yulSSAControlFlowGraph/complex2.yul +++ b/test/libyul/yulSSAControlFlowGraph/complex2.yul @@ -59,7 +59,7 @@ // Entry0 [label="Entry"]; // Entry0 -> Block0_0; // Block0_0 [label="\ -// Block 0\nLiveIn: \l\ +// Block 0; (0, max 0)\nLiveIn: \l\ // LiveOut: \l\nsstore(1, 1)\l\ // v2 := f(2, 1)\l\ // pop(v2)\l\ @@ -78,13 +78,13 @@ // c := f(v0, v1)"]; // FunctionEntry_f_0 -> Block1_0; // Block1_0 [label="\ -// Block 0\nLiveIn: v0,v1\l\ +// Block 0; (0, max 17)\nLiveIn: v0,v1\l\ // LiveOut: v0,v1\l\n"]; // Block1_0 -> Block1_0Exit [arrowhead=none]; // Block1_0Exit [label="Jump" shape=oval]; -// Block1_0Exit -> Block1_1; +// Block1_0Exit -> Block1_1 [style="solid"]; // Block1_1 [label="\ -// Block 1\nLiveIn: v0,v1,v5\l\ +// Block 1; (1, max 17)\nLiveIn: v0,v1,v5\l\ // LiveOut: v0,v1,v5\l\nv5 := φ(\l\ // Block 0 => 42,\l\ // Block 21 => v43\l\ @@ -92,123 +92,123 @@ // v6 := lt(v0, v5)\l\ // "]; // Block1_1 -> Block1_1Exit; -// Block1_1Exit [label="{ If v6| { <0> Zero | <1> NonZero }}" shape=Mrecord]; -// Block1_1Exit:0 -> Block1_4; -// Block1_1Exit:1 -> Block1_2; +// Block1_1Exit [label="{ If v6 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; +// Block1_1Exit:0 -> Block1_4 [style="solid"]; +// Block1_1Exit:1 -> Block1_2 [style="solid"]; // Block1_2 [label="\ -// Block 2\nLiveIn: v0,v1,v5\l\ +// Block 2; (2, max 17)\nLiveIn: v0,v1,v5\l\ // LiveOut: v0,v1,v5,v7\l\nv7 := mload(v5)\l\ // v8 := eq(0, v7)\l\ // "]; // Block1_2 -> Block1_2Exit; -// Block1_2Exit [label="{ If v8| { <0> Zero | <1> NonZero }}" shape=Mrecord]; -// Block1_2Exit:0 -> Block1_7; -// Block1_2Exit:1 -> Block1_6; +// Block1_2Exit [label="{ If v8 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; +// Block1_2Exit:0 -> Block1_7 [style="solid"]; +// Block1_2Exit:1 -> Block1_6 [style="solid"]; // Block1_4 [label="\ -// Block 4\nLiveIn: \l\ +// Block 4; (4, max 4)\nLiveIn: \l\ // LiveOut: \l\nsstore(3084, 12)\l\ // "]; // Block1_4Exit [label="FunctionReturn[27]"]; // Block1_4 -> Block1_4Exit; // Block1_6 [label="\ -// Block 6\nLiveIn: \l\ +// Block 6; (3, max 4)\nLiveIn: \l\ // LiveOut: \l\nsstore(514, 2)\l\ // "]; // Block1_6 -> Block1_6Exit [arrowhead=none]; // Block1_6Exit [label="Jump" shape=oval]; -// Block1_6Exit -> Block1_4; +// Block1_6Exit -> Block1_4 [style="solid"]; // Block1_7 [label="\ -// Block 7\nLiveIn: v0,v1,v5,v7\l\ +// Block 7; (5, max 17)\nLiveIn: v0,v1,v5,v7\l\ // LiveOut: v0,v1,v5,v7\l\nv13 := eq(1, v7)\l\ // "]; // Block1_7 -> Block1_7Exit; -// Block1_7Exit [label="{ If v13| { <0> Zero | <1> NonZero }}" shape=Mrecord]; -// Block1_7Exit:0 -> Block1_10; -// Block1_7Exit:1 -> Block1_9; +// Block1_7Exit [label="{ If v13 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; +// Block1_7Exit:0 -> Block1_10 [style="solid"]; +// Block1_7Exit:1 -> Block1_9 [style="solid"]; // Block1_9 [label="\ -// Block 9\nLiveIn: \l\ +// Block 9; (6, max 6)\nLiveIn: \l\ // LiveOut: \l\nsstore(1028, 4)\l\ // "]; // Block1_9Exit [label="FunctionReturn[0]"]; // Block1_9 -> Block1_9Exit; // Block1_10 [label="\ -// Block 10\nLiveIn: v0,v1,v5,v7\l\ +// Block 10; (7, max 17)\nLiveIn: v0,v1,v5,v7\l\ // LiveOut: v0,v1,v5,v7\l\nv20 := eq(2, v7)\l\ // "]; // Block1_10 -> Block1_10Exit; -// Block1_10Exit [label="{ If v20| { <0> Zero | <1> NonZero }}" shape=Mrecord]; -// Block1_10Exit:0 -> Block1_13; -// Block1_10Exit:1 -> Block1_12; +// Block1_10Exit [label="{ If v20 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; +// Block1_10Exit:0 -> Block1_13 [style="solid"]; +// Block1_10Exit:1 -> Block1_12 [style="solid"]; // Block1_12 [label="\ -// Block 12\nLiveIn: \l\ +// Block 12; (8, max 8)\nLiveIn: \l\ // LiveOut: \l\nsstore(1542, 6)\l\ // revert(0, 0)\l\ // "]; // Block1_12Exit [label="Terminated"]; // Block1_12 -> Block1_12Exit; // Block1_13 [label="\ -// Block 13\nLiveIn: v0,v1,v5,v7\l\ +// Block 13; (9, max 17)\nLiveIn: v0,v1,v5,v7\l\ // LiveOut: v0,v1,v5\l\nv25 := eq(3, v7)\l\ // "]; // Block1_13 -> Block1_13Exit; -// Block1_13Exit [label="{ If v25| { <0> Zero | <1> NonZero }}" shape=Mrecord]; -// Block1_13Exit:0 -> Block1_16; -// Block1_13Exit:1 -> Block1_15; +// Block1_13Exit [label="{ If v25 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; +// Block1_13Exit:0 -> Block1_16 [style="solid"]; +// Block1_13Exit:1 -> Block1_15 [style="solid"]; // Block1_15 [label="\ -// Block 15\nLiveIn: v0,v1,v5\l\ +// Block 15; (10, max 14)\nLiveIn: v0,v1,v5\l\ // LiveOut: v0,v1,v5\l\nsstore(2056, 8)\l\ // "]; // Block1_15 -> Block1_15Exit [arrowhead=none]; // Block1_15Exit [label="Jump" shape=oval]; -// Block1_15Exit -> Block1_5; +// Block1_15Exit -> Block1_5 [style="solid"]; // Block1_16 [label="\ -// Block 16\nLiveIn: v0,v1,v5\l\ +// Block 16; (15, max 17)\nLiveIn: v0,v1,v5\l\ // LiveOut: v0,v1,v5\l\nv29 := mload(v1)\l\ // "]; // Block1_16 -> Block1_16Exit; -// Block1_16Exit [label="{ If v29| { <0> Zero | <1> NonZero }}" shape=Mrecord]; -// Block1_16Exit:0 -> Block1_18; -// Block1_16Exit:1 -> Block1_17; +// Block1_16Exit [label="{ If v29 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; +// Block1_16Exit:0 -> Block1_18 [style="solid"]; +// Block1_16Exit:1 -> Block1_17 [style="solid"]; // Block1_5 [label="\ -// Block 5\nLiveIn: v0,v1,v5\l\ +// Block 5; (11, max 14)\nLiveIn: v0,v1,v5\l\ // LiveOut: v0,v1,v5\l\nsstore(2827, 11)\l\ // "]; // Block1_5 -> Block1_5Exit [arrowhead=none]; // Block1_5Exit [label="Jump" shape=oval]; -// Block1_5Exit -> Block1_3; +// Block1_5Exit -> Block1_3 [style="solid"]; // Block1_17 [label="\ -// Block 17\nLiveIn: \l\ +// Block 17; (16, max 16)\nLiveIn: \l\ // LiveOut: \l\nreturn(0, 0)\l\ // "]; // Block1_17Exit [label="Terminated"]; // Block1_17 -> Block1_17Exit; // Block1_18 [label="\ -// Block 18\nLiveIn: v0,v1,v5\l\ +// Block 18; (17, max 17)\nLiveIn: v0,v1,v5\l\ // LiveOut: v0,v1,v5\l\nsstore(2570, 10)\l\ // "]; // Block1_18 -> Block1_18Exit [arrowhead=none]; // Block1_18Exit [label="Jump" shape=oval]; -// Block1_18Exit -> Block1_5; +// Block1_18Exit -> Block1_5 [style="solid"]; // Block1_3 [label="\ -// Block 3\nLiveIn: v0,v1,v5\l\ +// Block 3; (12, max 14)\nLiveIn: v0,v1,v5\l\ // LiveOut: v0,v1,v43\l\nv43 := add(1, v5)\l\ // v44 := calldataload(v43)\l\ // "]; // Block1_3 -> Block1_3Exit; -// Block1_3Exit [label="{ If v44| { <0> Zero | <1> NonZero }}" shape=Mrecord]; -// Block1_3Exit:0 -> Block1_21; -// Block1_3Exit:1 -> Block1_20; +// Block1_3Exit [label="{ If v44 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; +// Block1_3Exit:0 -> Block1_21 [style="solid"]; +// Block1_3Exit:1 -> Block1_20 [style="solid"]; // Block1_20 [label="\ -// Block 20\nLiveIn: v43\l\ +// Block 20; (13, max 13)\nLiveIn: v43\l\ // LiveOut: \l\nsstore(v43, 0)\l\ // "]; // Block1_20Exit [label="FunctionReturn[0]"]; // Block1_20 -> Block1_20Exit; // Block1_21 [label="\ -// Block 21\nLiveIn: v0,v1,v43\l\ +// Block 21; (14, max 14)\nLiveIn: v0,v1,v43\l\ // LiveOut: v0,v1,v43\l\nsstore(65535, 255)\l\ // "]; // Block1_21 -> Block1_21Exit [arrowhead=none]; // Block1_21Exit [label="Jump" shape=oval]; -// Block1_21Exit -> Block1_1; +// Block1_21Exit -> Block1_1 [style="dashed"]; // } diff --git a/test/libyul/yulSSAControlFlowGraph/function.yul b/test/libyul/yulSSAControlFlowGraph/function.yul index 1b759f8b395a..acf1a37aa43f 100644 --- a/test/libyul/yulSSAControlFlowGraph/function.yul +++ b/test/libyul/yulSSAControlFlowGraph/function.yul @@ -27,7 +27,7 @@ // Entry0 [label="Entry"]; // Entry0 -> Block0_0; // Block0_0 [label="\ -// Block 0\nLiveIn: \l\ +// Block 0; (0, max 0)\nLiveIn: \l\ // LiveOut: \l\nv0, v1 := i()\l\ // h(v0)\l\ // "]; @@ -37,7 +37,7 @@ // r := f(v0, v1)"]; // FunctionEntry_f_0 -> Block1_0; // Block1_0 [label="\ -// Block 0\nLiveIn: v0,v1\l\ +// Block 0; (0, max 0)\nLiveIn: v0,v1\l\ // LiveOut: v4\l\nv3 := add(v1, v0)\l\ // v4 := sub(v0, v3)\l\ // "]; @@ -47,7 +47,7 @@ // g()"]; // FunctionEntry_g_0 -> Block2_0; // Block2_0 [label="\ -// Block 0\nLiveIn: \l\ +// Block 0; (0, max 0)\nLiveIn: \l\ // LiveOut: \l\nsstore(257, 1)\l\ // "]; // Block2_0Exit [label="FunctionReturn[]"]; @@ -56,7 +56,7 @@ // h(v0)"]; // FunctionEntry_h_0 -> Block3_0; // Block3_0 [label="\ -// Block 0\nLiveIn: v0\l\ +// Block 0; (0, max 0)\nLiveIn: v0\l\ // LiveOut: \l\nv2 := f(0, v0)\l\ // h(v2)\l\ // "]; @@ -66,7 +66,7 @@ // v, w := i()"]; // FunctionEntry_i_0 -> Block4_0; // Block4_0 [label="\ -// Block 0\nLiveIn: \l\ +// Block 0; (0, max 0)\nLiveIn: \l\ // LiveOut: \l\n"]; // Block4_0Exit [label="FunctionReturn[514, 771]"]; // Block4_0 -> Block4_0Exit; diff --git a/test/libyul/yulSSAControlFlowGraph/if.yul b/test/libyul/yulSSAControlFlowGraph/if.yul index 9c4d73a13a25..e2a66ab74fba 100644 --- a/test/libyul/yulSSAControlFlowGraph/if.yul +++ b/test/libyul/yulSSAControlFlowGraph/if.yul @@ -15,22 +15,22 @@ // Entry0 [label="Entry"]; // Entry0 -> Block0_0; // Block0_0 [label="\ -// Block 0\nLiveIn: \l\ +// Block 0; (0, max 2)\nLiveIn: \l\ // LiveOut: v1\l\nv1 := calldataload(3)\l\ // "]; // Block0_0 -> Block0_0Exit; -// Block0_0Exit [label="{ If 0| { <0> Zero | <1> NonZero }}" shape=Mrecord]; -// Block0_0Exit:0 -> Block0_2; -// Block0_0Exit:1 -> Block0_1; +// Block0_0Exit [label="{ If 0 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; +// Block0_0Exit:0 -> Block0_2 [style="solid"]; +// Block0_0Exit:1 -> Block0_1 [style="solid"]; // Block0_1 [label="\ -// Block 1\nLiveIn: \l\ +// Block 1; (1, max 2)\nLiveIn: \l\ // LiveOut: v4\l\nv4 := calldataload(77)\l\ // "]; // Block0_1 -> Block0_1Exit [arrowhead=none]; // Block0_1Exit [label="Jump" shape=oval]; -// Block0_1Exit -> Block0_2; +// Block0_1Exit -> Block0_2 [style="solid"]; // Block0_2 [label="\ -// Block 2\nLiveIn: v5\l\ +// Block 2; (2, max 2)\nLiveIn: v5\l\ // LiveOut: \l\nv5 := φ(\l\ // Block 0 => v1,\l\ // Block 1 => v4\l\ diff --git a/test/libyul/yulSSAControlFlowGraph/nested_for.yul b/test/libyul/yulSSAControlFlowGraph/nested_for.yul index 0ed17c870a1f..b088e3b55ed8 100644 --- a/test/libyul/yulSSAControlFlowGraph/nested_for.yul +++ b/test/libyul/yulSSAControlFlowGraph/nested_for.yul @@ -26,170 +26,195 @@ // Entry0 [label="Entry"]; // Entry0 -> Block0_0; // Block0_0 [label="\ -// Block 0\n"]; +// Block 0; (0, max 24)\nLiveIn: \l\ +// LiveOut: \l\n"]; // Block0_0 -> Block0_0Exit [arrowhead=none]; // Block0_0Exit [label="Jump" shape=oval]; -// Block0_0Exit -> Block0_1; +// Block0_0Exit -> Block0_1 [style="solid"]; // Block0_1 [label="\ -// Block 1\nv2 := φ(\l\ +// Block 1; (1, max 24)\nLiveIn: v2\l\ +// LiveOut: v2\l\nv2 := φ(\l\ // Block 0 => 0,\l\ // Block 3 => v36\l\ // )\l\ // v3 := lt(3, v2)\l\ // "]; // Block0_1 -> Block0_1Exit; -// Block0_1Exit [label="{ If v3| { <0> Zero | <1> NonZero }}" shape=Mrecord]; -// Block0_1Exit:0 -> Block0_4; -// Block0_1Exit:1 -> Block0_2; +// Block0_1Exit [label="{ If v3 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; +// Block0_1Exit:0 -> Block0_4 [style="solid"]; +// Block0_1Exit:1 -> Block0_2 [style="solid"]; // Block0_2 [label="\ -// Block 2\n"]; +// Block 2; (2, max 23)\nLiveIn: v2\l\ +// LiveOut: v2\l\n"]; // Block0_2 -> Block0_2Exit [arrowhead=none]; // Block0_2Exit [label="Jump" shape=oval]; -// Block0_2Exit -> Block0_5; +// Block0_2Exit -> Block0_5 [style="solid"]; // Block0_4 [label="\ -// Block 4\n"]; +// Block 4; (24, max 24)\nLiveIn: \l\ +// LiveOut: \l\n"]; // Block0_4Exit [label="MainExit"]; // Block0_4 -> Block0_4Exit; // Block0_5 [label="\ -// Block 5\nv4 := φ(\l\ +// Block 5; (3, max 23)\nLiveIn: v2,v4\l\ +// LiveOut: v2,v4\l\nv4 := φ(\l\ // Block 2 => 0,\l\ // Block 7 => v35\l\ // )\l\ // v5 := lt(3, v4)\l\ // "]; // Block0_5 -> Block0_5Exit; -// Block0_5Exit [label="{ If v5| { <0> Zero | <1> NonZero }}" shape=Mrecord]; -// Block0_5Exit:0 -> Block0_8; -// Block0_5Exit:1 -> Block0_6; +// Block0_5Exit [label="{ If v5 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; +// Block0_5Exit:0 -> Block0_8 [style="solid"]; +// Block0_5Exit:1 -> Block0_6 [style="solid"]; // Block0_6 [label="\ -// Block 6\n"]; +// Block 6; (4, max 21)\nLiveIn: v2,v4\l\ +// LiveOut: v2,v4\l\n"]; // Block0_6 -> Block0_6Exit [arrowhead=none]; // Block0_6Exit [label="Jump" shape=oval]; -// Block0_6Exit -> Block0_9; +// Block0_6Exit -> Block0_9 [style="solid"]; // Block0_8 [label="\ -// Block 8\n"]; +// Block 8; (22, max 23)\nLiveIn: v2\l\ +// LiveOut: v2\l\n"]; // Block0_8 -> Block0_8Exit [arrowhead=none]; // Block0_8Exit [label="Jump" shape=oval]; -// Block0_8Exit -> Block0_3; +// Block0_8Exit -> Block0_3 [style="solid"]; // Block0_9 [label="\ -// Block 9\nv6 := φ(\l\ +// Block 9; (5, max 21)\nLiveIn: v2,v4,v6\l\ +// LiveOut: v2,v4,v6\l\nv6 := φ(\l\ // Block 6 => 0,\l\ // Block 11 => v31\l\ // )\l\ // v7 := lt(3, v6)\l\ // "]; // Block0_9 -> Block0_9Exit; -// Block0_9Exit [label="{ If v7| { <0> Zero | <1> NonZero }}" shape=Mrecord]; -// Block0_9Exit:0 -> Block0_12; -// Block0_9Exit:1 -> Block0_10; +// Block0_9Exit [label="{ If v7 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; +// Block0_9Exit:0 -> Block0_12 [style="solid"]; +// Block0_9Exit:1 -> Block0_10 [style="solid"]; // Block0_3 [label="\ -// Block 3\nv36 := add(1, v2)\l\ +// Block 3; (23, max 23)\nLiveIn: v2\l\ +// LiveOut: v36\l\nv36 := add(1, v2)\l\ // "]; // Block0_3 -> Block0_3Exit [arrowhead=none]; // Block0_3Exit [label="Jump" shape=oval]; -// Block0_3Exit -> Block0_1; +// Block0_3Exit -> Block0_1 [style="dashed"]; // Block0_10 [label="\ -// Block 10\n"]; +// Block 10; (6, max 19)\nLiveIn: v2,v4,v6\l\ +// LiveOut: v2,v4,v6\l\n"]; // Block0_10 -> Block0_10Exit; -// Block0_10Exit [label="{ If 0| { <0> Zero | <1> NonZero }}" shape=Mrecord]; -// Block0_10Exit:0 -> Block0_14; -// Block0_10Exit:1 -> Block0_13; +// Block0_10Exit [label="{ If 0 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; +// Block0_10Exit:0 -> Block0_14 [style="solid"]; +// Block0_10Exit:1 -> Block0_13 [style="solid"]; // Block0_12 [label="\ -// Block 12\n"]; +// Block 12; (20, max 21)\nLiveIn: v2,v4\l\ +// LiveOut: v2,v4\l\n"]; // Block0_12 -> Block0_12Exit [arrowhead=none]; // Block0_12Exit [label="Jump" shape=oval]; -// Block0_12Exit -> Block0_7; +// Block0_12Exit -> Block0_7 [style="solid"]; // Block0_13 [label="\ -// Block 13\n"]; +// Block 13; (7, max 19)\nLiveIn: v2,v4,v6\l\ +// LiveOut: v2,v4,v6\l\n"]; // Block0_13 -> Block0_13Exit [arrowhead=none]; // Block0_13Exit [label="Jump" shape=oval]; -// Block0_13Exit -> Block0_15; +// Block0_13Exit -> Block0_15 [style="solid"]; // Block0_14 [label="\ -// Block 14\n"]; +// Block 14; (12, max 19)\nLiveIn: v2,v4,v6\l\ +// LiveOut: v2,v4,v6\l\n"]; // Block0_14 -> Block0_14Exit; -// Block0_14Exit [label="{ If 1| { <0> Zero | <1> NonZero }}" shape=Mrecord]; -// Block0_14Exit:0 -> Block0_20; -// Block0_14Exit:1 -> Block0_19; +// Block0_14Exit [label="{ If 1 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; +// Block0_14Exit:0 -> Block0_20 [style="solid"]; +// Block0_14Exit:1 -> Block0_19 [style="solid"]; // Block0_7 [label="\ -// Block 7\nv35 := add(1, v4)\l\ +// Block 7; (21, max 21)\nLiveIn: v2,v4\l\ +// LiveOut: v2,v35\l\nv35 := add(1, v4)\l\ // "]; // Block0_7 -> Block0_7Exit [arrowhead=none]; // Block0_7Exit [label="Jump" shape=oval]; -// Block0_7Exit -> Block0_5; +// Block0_7Exit -> Block0_5 [style="dashed"]; // Block0_15 [label="\ -// Block 15\nv8 := φ(\l\ +// Block 15; (8, max 19)\nLiveIn: v2,v4,v6,v8\l\ +// LiveOut: v2,v4,v6,v8\l\nv8 := φ(\l\ // Block 13 => 0,\l\ // Block 17 => v16\l\ // )\l\ // v9 := lt(3, v8)\l\ // "]; // Block0_15 -> Block0_15Exit; -// Block0_15Exit [label="{ If v9| { <0> Zero | <1> NonZero }}" shape=Mrecord]; -// Block0_15Exit:0 -> Block0_18; -// Block0_15Exit:1 -> Block0_16; +// Block0_15Exit [label="{ If v9 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; +// Block0_15Exit:0 -> Block0_18 [style="solid"]; +// Block0_15Exit:1 -> Block0_16 [style="solid"]; // Block0_19 [label="\ -// Block 19\n"]; +// Block 19; (13, max 19)\nLiveIn: v2,v4,v6\l\ +// LiveOut: v2,v4,v6\l\n"]; // Block0_19 -> Block0_19Exit [arrowhead=none]; // Block0_19Exit [label="Jump" shape=oval]; -// Block0_19Exit -> Block0_21; +// Block0_19Exit -> Block0_21 [style="solid"]; // Block0_20 [label="\ -// Block 20\n"]; +// Block 20; (18, max 19)\nLiveIn: v2,v4,v6\l\ +// LiveOut: v2,v4,v6\l\n"]; // Block0_20 -> Block0_20Exit [arrowhead=none]; // Block0_20Exit [label="Jump" shape=oval]; -// Block0_20Exit -> Block0_11; +// Block0_20Exit -> Block0_11 [style="solid"]; // Block0_16 [label="\ -// Block 16\nv13 := add(v4, v2)\l\ +// Block 16; (9, max 10)\nLiveIn: v2,v4,v6,v8\l\ +// LiveOut: v2,v4,v6,v8\l\nv13 := add(v4, v2)\l\ // v14 := add(v6, v13)\l\ // sstore(v14, v8)\l\ // "]; // Block0_16 -> Block0_16Exit [arrowhead=none]; // Block0_16Exit [label="Jump" shape=oval]; -// Block0_16Exit -> Block0_17; +// Block0_16Exit -> Block0_17 [style="solid"]; // Block0_18 [label="\ -// Block 18\n"]; +// Block 18; (11, max 19)\nLiveIn: v2,v4,v6\l\ +// LiveOut: v2,v4,v6\l\n"]; // Block0_18 -> Block0_18Exit [arrowhead=none]; // Block0_18Exit [label="Jump" shape=oval]; -// Block0_18Exit -> Block0_14; +// Block0_18Exit -> Block0_14 [style="solid"]; // Block0_21 [label="\ -// Block 21\nv19 := φ(\l\ +// Block 21; (14, max 19)\nLiveIn: v2,v4,v6,v19\l\ +// LiveOut: v2,v4,v6,v19\l\nv19 := φ(\l\ // Block 19 => 0,\l\ // Block 23 => v26\l\ // )\l\ // v20 := lt(3, v19)\l\ // "]; // Block0_21 -> Block0_21Exit; -// Block0_21Exit [label="{ If v20| { <0> Zero | <1> NonZero }}" shape=Mrecord]; -// Block0_21Exit:0 -> Block0_24; -// Block0_21Exit:1 -> Block0_22; +// Block0_21Exit [label="{ If v20 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; +// Block0_21Exit:0 -> Block0_24 [style="solid"]; +// Block0_21Exit:1 -> Block0_22 [style="solid"]; // Block0_11 [label="\ -// Block 11\nv31 := add(1, v6)\l\ +// Block 11; (19, max 19)\nLiveIn: v2,v4,v6\l\ +// LiveOut: v2,v4,v31\l\nv31 := add(1, v6)\l\ // "]; // Block0_11 -> Block0_11Exit [arrowhead=none]; // Block0_11Exit [label="Jump" shape=oval]; -// Block0_11Exit -> Block0_9; +// Block0_11Exit -> Block0_9 [style="dashed"]; // Block0_17 [label="\ -// Block 17\nv16 := add(1, v8)\l\ +// Block 17; (10, max 10)\nLiveIn: v2,v4,v6,v8\l\ +// LiveOut: v2,v4,v6,v16\l\nv16 := add(1, v8)\l\ // "]; // Block0_17 -> Block0_17Exit [arrowhead=none]; // Block0_17Exit [label="Jump" shape=oval]; -// Block0_17Exit -> Block0_15; +// Block0_17Exit -> Block0_15 [style="dashed"]; // Block0_22 [label="\ -// Block 22\nv24 := add(v4, v2)\l\ +// Block 22; (15, max 16)\nLiveIn: v2,v4,v6,v19\l\ +// LiveOut: v2,v4,v6,v19\l\nv24 := add(v4, v2)\l\ // v25 := add(v6, v24)\l\ // sstore(v25, v19)\l\ // "]; // Block0_22 -> Block0_22Exit [arrowhead=none]; // Block0_22Exit [label="Jump" shape=oval]; -// Block0_22Exit -> Block0_23; +// Block0_22Exit -> Block0_23 [style="solid"]; // Block0_24 [label="\ -// Block 24\n"]; +// Block 24; (17, max 19)\nLiveIn: v2,v4,v6\l\ +// LiveOut: v2,v4,v6\l\n"]; // Block0_24 -> Block0_24Exit [arrowhead=none]; // Block0_24Exit [label="Jump" shape=oval]; -// Block0_24Exit -> Block0_20; +// Block0_24Exit -> Block0_20 [style="solid"]; // Block0_23 [label="\ -// Block 23\nv26 := add(1, v19)\l\ +// Block 23; (16, max 16)\nLiveIn: v2,v4,v6,v19\l\ +// LiveOut: v2,v4,v6,v26\l\nv26 := add(1, v19)\l\ // "]; // Block0_23 -> Block0_23Exit [arrowhead=none]; // Block0_23Exit [label="Jump" shape=oval]; -// Block0_23Exit -> Block0_21; +// Block0_23Exit -> Block0_21 [style="dashed"]; // } diff --git a/test/libyul/yulSSAControlFlowGraph/nested_function.yul b/test/libyul/yulSSAControlFlowGraph/nested_function.yul index 859b24151592..acda15ce81a5 100644 --- a/test/libyul/yulSSAControlFlowGraph/nested_function.yul +++ b/test/libyul/yulSSAControlFlowGraph/nested_function.yul @@ -38,14 +38,16 @@ // Entry0 [label="Entry"]; // Entry0 -> Block0_0; // Block0_0 [label="\ -// Block 0\n"]; +// Block 0; (0, max 0)\nLiveIn: \l\ +// LiveOut: \l\n"]; // Block0_0Exit [label="MainExit"]; // Block0_0 -> Block0_0Exit; // FunctionEntry_f_0 [label="function f: // r := f(v0, v1)"]; // FunctionEntry_f_0 -> Block1_0; // Block1_0 [label="\ -// Block 0\nv3 := add(v1, v0)\l\ +// Block 0; (0, max 0)\nLiveIn: v0,v1\l\ +// LiveOut: v4\l\nv3 := add(v1, v0)\l\ // v4 := sub(v0, v3)\l\ // "]; // Block1_0Exit [label="FunctionReturn[v4]"]; @@ -54,7 +56,8 @@ // g()"]; // FunctionEntry_g_0 -> Block2_0; // Block2_0 [label="\ -// Block 0\nv1 := v()\l\ +// Block 0; (0, max 0)\nLiveIn: \l\ +// LiveOut: \l\nv1 := v()\l\ // v2 := f(2, v1)\l\ // v3 := z()\l\ // sstore(v2, v3)\l\ @@ -65,7 +68,8 @@ // r := z()"]; // FunctionEntry_z_0 -> Block3_0; // Block3_0 [label="\ -// Block 0\nv1 := w()\l\ +// Block 0; (0, max 0)\nLiveIn: \l\ +// LiveOut: v1\l\nv1 := w()\l\ // "]; // Block3_0Exit [label="FunctionReturn[v1]"]; // Block3_0 -> Block3_0Exit; @@ -73,14 +77,16 @@ // rw1 := w()"]; // FunctionEntry_w_0 -> Block4_0; // Block4_0 [label="\ -// Block 0\n"]; +// Block 0; (0, max 0)\nLiveIn: \l\ +// LiveOut: \l\n"]; // Block4_0Exit [label="FunctionReturn[1]"]; // Block4_0 -> Block4_0Exit; // FunctionEntry_v_0 [label="function v: // r := v()"]; // FunctionEntry_v_0 -> Block5_0; // Block5_0 [label="\ -// Block 0\nv1 := w()\l\ +// Block 0; (0, max 0)\nLiveIn: \l\ +// LiveOut: v1\l\nv1 := w()\l\ // "]; // Block5_0Exit [label="FunctionReturn[v1]"]; // Block5_0 -> Block5_0Exit; @@ -88,27 +94,31 @@ // rw2 := w()"]; // FunctionEntry_w_0 -> Block6_0; // Block6_0 [label="\ -// Block 0\n"]; +// Block 0; (0, max 0)\nLiveIn: \l\ +// LiveOut: \l\n"]; // Block6_0Exit [label="FunctionReturn[17]"]; // Block6_0 -> Block6_0Exit; // FunctionEntry_cycle1_0 [label="function cycle1: // r := cycle1()"]; // FunctionEntry_cycle1_0 -> Block7_0; // Block7_0 [label="\ -// Block 0\nv2 := mload(3)\l\ +// Block 0; (0, max 2)\nLiveIn: \l\ +// LiveOut: \l\nv2 := mload(3)\l\ // "]; // Block7_0 -> Block7_0Exit; -// Block7_0Exit [label="{ If v2| { <0> Zero | <1> NonZero }}" shape=Mrecord]; -// Block7_0Exit:0 -> Block7_2; -// Block7_0Exit:1 -> Block7_1; +// Block7_0Exit [label="{ If v2 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; +// Block7_0Exit:0 -> Block7_2 [style="solid"]; +// Block7_0Exit:1 -> Block7_1 [style="solid"]; // Block7_1 [label="\ -// Block 1\nv3 := cycle2()\l\ +// Block 1; (1, max 2)\nLiveIn: \l\ +// LiveOut: v3\l\nv3 := cycle2()\l\ // "]; // Block7_1 -> Block7_1Exit [arrowhead=none]; // Block7_1Exit [label="Jump" shape=oval]; -// Block7_1Exit -> Block7_2; +// Block7_1Exit -> Block7_2 [style="solid"]; // Block7_2 [label="\ -// Block 2\nv4 := φ(\l\ +// Block 2; (2, max 2)\nLiveIn: v4\l\ +// LiveOut: v4\l\nv4 := φ(\l\ // Block 0 => 0,\l\ // Block 1 => v3\l\ // )\l\ @@ -119,20 +129,23 @@ // r := cycle2()"]; // FunctionEntry_cycle2_0 -> Block8_0; // Block8_0 [label="\ -// Block 0\nv2 := mload(4)\l\ +// Block 0; (0, max 2)\nLiveIn: \l\ +// LiveOut: \l\nv2 := mload(4)\l\ // "]; // Block8_0 -> Block8_0Exit; -// Block8_0Exit [label="{ If v2| { <0> Zero | <1> NonZero }}" shape=Mrecord]; -// Block8_0Exit:0 -> Block8_2; -// Block8_0Exit:1 -> Block8_1; +// Block8_0Exit [label="{ If v2 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; +// Block8_0Exit:0 -> Block8_2 [style="solid"]; +// Block8_0Exit:1 -> Block8_1 [style="solid"]; // Block8_1 [label="\ -// Block 1\nv3 := cycle1()\l\ +// Block 1; (1, max 2)\nLiveIn: \l\ +// LiveOut: v3\l\nv3 := cycle1()\l\ // "]; // Block8_1 -> Block8_1Exit [arrowhead=none]; // Block8_1Exit [label="Jump" shape=oval]; -// Block8_1Exit -> Block8_2; +// Block8_1Exit -> Block8_2 [style="solid"]; // Block8_2 [label="\ -// Block 2\nv4 := φ(\l\ +// Block 2; (2, max 2)\nLiveIn: v4\l\ +// LiveOut: v4\l\nv4 := φ(\l\ // Block 0 => 0,\l\ // Block 1 => v3\l\ // )\l\ diff --git a/test/libyul/yulSSAControlFlowGraph/switch.yul b/test/libyul/yulSSAControlFlowGraph/switch.yul index d744bd7bd247..10573b012298 100644 --- a/test/libyul/yulSSAControlFlowGraph/switch.yul +++ b/test/libyul/yulSSAControlFlowGraph/switch.yul @@ -22,32 +22,32 @@ // Entry0 [label="Entry"]; // Entry0 -> Block0_0; // Block0_0 [label="\ -// Block 0\nLiveIn: \l\ +// Block 0; (0, max 5)\nLiveIn: \l\ // LiveOut: v3\l\nv1 := calldataload(3)\l\ // v3 := sload(0)\l\ // v4 := eq(0, v3)\l\ // "]; // Block0_0 -> Block0_0Exit; -// Block0_0Exit [label="{ If v4| { <0> Zero | <1> NonZero }}" shape=Mrecord]; -// Block0_0Exit:0 -> Block0_3; -// Block0_0Exit:1 -> Block0_2; +// Block0_0Exit [label="{ If v4 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; +// Block0_0Exit:0 -> Block0_3 [style="solid"]; +// Block0_0Exit:1 -> Block0_2 [style="solid"]; // Block0_2 [label="\ -// Block 2\nLiveIn: \l\ +// Block 2; (1, max 2)\nLiveIn: \l\ // LiveOut: v6\l\nv6 := calldataload(77)\l\ // "]; // Block0_2 -> Block0_2Exit [arrowhead=none]; // Block0_2Exit [label="Jump" shape=oval]; -// Block0_2Exit -> Block0_1; +// Block0_2Exit -> Block0_1 [style="solid"]; // Block0_3 [label="\ -// Block 3\nLiveIn: v3\l\ +// Block 3; (3, max 5)\nLiveIn: v3\l\ // LiveOut: \l\nv7 := eq(1, v3)\l\ // "]; // Block0_3 -> Block0_3Exit; -// Block0_3Exit [label="{ If v7| { <0> Zero | <1> NonZero }}" shape=Mrecord]; -// Block0_3Exit:0 -> Block0_5; -// Block0_3Exit:1 -> Block0_4; +// Block0_3Exit [label="{ If v7 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; +// Block0_3Exit:0 -> Block0_5 [style="solid"]; +// Block0_3Exit:1 -> Block0_4 [style="solid"]; // Block0_1 [label="\ -// Block 1\nLiveIn: v13\l\ +// Block 1; (2, max 2)\nLiveIn: v13\l\ // LiveOut: \l\nv13 := φ(\l\ // Block 2 => v6,\l\ // Block 4 => v10,\l\ @@ -58,17 +58,17 @@ // Block0_1Exit [label="MainExit"]; // Block0_1 -> Block0_1Exit; // Block0_4 [label="\ -// Block 4\nLiveIn: \l\ +// Block 4; (4, max 4)\nLiveIn: \l\ // LiveOut: v10\l\nv10 := calldataload(88)\l\ // "]; // Block0_4 -> Block0_4Exit [arrowhead=none]; // Block0_4Exit [label="Jump" shape=oval]; -// Block0_4Exit -> Block0_1; +// Block0_4Exit -> Block0_1 [style="solid"]; // Block0_5 [label="\ -// Block 5\nLiveIn: \l\ +// Block 5; (5, max 5)\nLiveIn: \l\ // LiveOut: v12\l\nv12 := calldataload(99)\l\ // "]; // Block0_5 -> Block0_5Exit [arrowhead=none]; // Block0_5Exit [label="Jump" shape=oval]; -// Block0_5Exit -> Block0_1; +// Block0_5Exit -> Block0_1 [style="solid"]; // } From 8a77a26861046a0a2a37cfc908edcc8947ffb91a Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Thu, 19 Sep 2024 14:56:20 +0200 Subject: [PATCH 0484/1022] SSACFGLiveness: add operation-wise live out --- libyul/backends/evm/SSACFGLiveness.cpp | 32 ++++++++++++++++++++- libyul/backends/evm/SSACFGLiveness.h | 12 +++++--- libyul/backends/evm/SSAControlFlowGraph.cpp | 4 +-- 3 files changed, 41 insertions(+), 7 deletions(-) diff --git a/libyul/backends/evm/SSACFGLiveness.cpp b/libyul/backends/evm/SSACFGLiveness.cpp index b9513f70dfce..85bd41d10ed6 100644 --- a/libyul/backends/evm/SSACFGLiveness.cpp +++ b/libyul/backends/evm/SSACFGLiveness.cpp @@ -29,12 +29,16 @@ SSACFGLiveness::SSACFGLiveness(SSACFG const& _cfg): m_topologicalSort(_cfg), m_loopNestingForest(m_topologicalSort), m_liveIns(_cfg.numBlocks()), - m_liveOuts(_cfg.numBlocks()) + m_liveOuts(_cfg.numBlocks()), + m_operationLiveOuts(_cfg.numBlocks()) { runDagDfs(); for (auto const loopRootNode: m_loopNestingForest.loopRootNodes()) runLoopTreeDfs(loopRootNode); + + fillOperationsLiveOut(); } + void SSACFGLiveness::runDagDfs() { // SSA Book, Algorithm 9.2 @@ -103,6 +107,7 @@ void SSACFGLiveness::runDagDfs() m_liveIns[blockId.value] = live + block.phis; } } + void SSACFGLiveness::runLoopTreeDfs(size_t const _loopHeader) { // SSA Book, Algorithm 9.3 @@ -126,3 +131,28 @@ void SSACFGLiveness::runLoopTreeDfs(size_t const _loopHeader) } } } + +void SSACFGLiveness::fillOperationsLiveOut() +{ + auto const filterLiterals = [this](auto const& valueId){ + return !std::holds_alternative(m_cfg.valueInfo(valueId)); + }; + for (size_t blockIdValue = 0; blockIdValue < m_cfg.numBlocks(); ++blockIdValue) + { + auto const& operations = m_cfg.block(SSACFG::BlockId{blockIdValue}).operations; + auto& liveOuts = m_operationLiveOuts[blockIdValue]; + liveOuts.resize(operations.size()); + if (!operations.empty()) + { + auto live = m_liveOuts[blockIdValue]; + auto rit = liveOuts.rbegin(); + for (auto const& op: operations | ranges::views::reverse) + { + *rit = live; + live -= op.outputs | ranges::views::filter(filterLiterals) | ranges::to; + live += op.inputs | ranges::views::filter(filterLiterals) | ranges::to; + ++rit; + } + } + } +} diff --git a/libyul/backends/evm/SSACFGLiveness.h b/libyul/backends/evm/SSACFGLiveness.h index 6f486b737f13..72752cfefd45 100644 --- a/libyul/backends/evm/SSACFGLiveness.h +++ b/libyul/backends/evm/SSACFGLiveness.h @@ -35,21 +35,25 @@ namespace solidity::yul class SSACFGLiveness { public: + using LivenessData = std::set; explicit SSACFGLiveness(SSACFG const& _cfg); - std::vector> const& liveIns() const { return m_liveIns; } - std::vector> const& liveOuts() const { return m_liveOuts; } + LivenessData const& liveIn(SSACFG::BlockId _blockId) const { return m_liveIns[_blockId.value]; } + LivenessData const& liveOut(SSACFG::BlockId _blockId) const { return m_liveOuts[_blockId.value]; } + std::vector const& operationsLiveOut(SSACFG::BlockId _blockId) const { return m_operationLiveOuts[_blockId.value]; } ForwardSSACFGTopologicalSort const& topologicalSort() const { return m_topologicalSort; } private: void runDagDfs(); void runLoopTreeDfs(size_t _loopHeader); + void fillOperationsLiveOut(); SSACFG const& m_cfg; ForwardSSACFGTopologicalSort m_topologicalSort; SSACFGLoopNestingForest m_loopNestingForest; - std::vector> m_liveIns; - std::vector> m_liveOuts; + std::vector m_liveIns; + std::vector m_liveOuts; + std::vector> m_operationLiveOuts; }; } diff --git a/libyul/backends/evm/SSAControlFlowGraph.cpp b/libyul/backends/evm/SSAControlFlowGraph.cpp index ebd6d84a9680..35c9db0dfe8c 100644 --- a/libyul/backends/evm/SSAControlFlowGraph.cpp +++ b/libyul/backends/evm/SSAControlFlowGraph.cpp @@ -125,11 +125,11 @@ class SSACFGPrinter ); m_result << fmt::format( "LiveIn: {}\\l\\\n", - fmt::join(m_liveness->liveIns()[_id.value] | ranges::views::transform(valueToString), ",") + fmt::join(m_liveness->liveIn(_id) | ranges::views::transform(valueToString), ",") ); m_result << fmt::format( "LiveOut: {}\\l\\n", - fmt::join(m_liveness->liveOuts()[_id.value] | ranges::views::transform(valueToString), ",") + fmt::join(m_liveness->liveOut(_id) | ranges::views::transform(valueToString), ",") ); } else From cdfb93edf08ad36d1399fbb5aa960e29812828ab Mon Sep 17 00:00:00 2001 From: Elias Rad <146735585+nnsW3@users.noreply.github.com> Date: Tue, 8 Oct 2024 13:42:05 +0300 Subject: [PATCH 0485/1022] Update functions.rst --- docs/contracts/functions.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/contracts/functions.rst b/docs/contracts/functions.rst index e653eb8f09b5..a3a2755388c8 100644 --- a/docs/contracts/functions.rst +++ b/docs/contracts/functions.rst @@ -267,7 +267,7 @@ This behavior is also in line with the ``STATICCALL`` opcode. .. note:: Prior to version 0.4.17 the compiler did not enforce that ``pure`` is not reading the state. - It is a compile-time type check, which can be circumvented doing invalid explicit conversions + It is a compile-time type check, which can be circumvented by doing invalid explicit conversions between contract types, because the compiler can verify that the type of the contract does not do state-changing operations, but it cannot check that the contract that will be called at runtime is actually of that type. From 11395ad5b4462de08efa294a5e31c221a4d37bda Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Tue, 8 Oct 2024 15:24:26 +0200 Subject: [PATCH 0486/1022] CI: Remove nightly codecov job --- .circleci/config.yml | 46 -------------------------------------------- codecov.yml | 22 --------------------- 2 files changed, 68 deletions(-) delete mode 100644 codecov.yml diff --git a/.circleci/config.yml b/.circleci/config.yml index ed14c8af4d32..ca1043685c1f 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -670,11 +670,6 @@ defaults: requires: - b_archlinux - - requires_b_ubu_codecov: &requires_b_ubu_codecov - <<: *on_all_tags_and_branches - requires: - - b_ubu_codecov - - requires_b_osx: &requires_b_osx <<: *on_all_tags_and_branches requires: @@ -1074,43 +1069,6 @@ jobs: - solc/solc-static-linux - matrix_notify_failure_unless_pr - b_ubu_codecov: - # Runs ~30% faster on large but we only run it nightly so efficiency matters more. - <<: *base_ubuntu2404 - environment: - <<: *base_ubuntu2404_env - COVERAGE: ON - CMAKE_BUILD_TYPE: Debug - CMAKE_OPTIONS: -DCMAKE_CXX_FLAGS=-fuse-ld=gold - steps: - - checkout - - run_build - - persist_executables_to_workspace - - matrix_notify_failure_unless_pr - - t_ubu_codecov: - <<: *base_ubuntu2404_large - environment: - <<: *base_ubuntu2404_large_env - EVM: << pipeline.parameters.evm-version >> - OPTIMIZE: 1 - steps: - - checkout - - attach_workspace: - at: build - - run: - name: "soltest: Syntax Tests" - command: build/test/soltest -t 'syntaxTest*' -- --testpath test - - run: - name: "Code Coverage: Syntax Tests" - command: codecov --flags syntax --gcov-root build - - run_soltest - - run: - name: "Coverage: All" - command: codecov --flags all --gcov-root build - - store_artifacts_test_results - - matrix_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. b_ubu_cxx20: @@ -2007,10 +1965,6 @@ workflows: <<: *on_develop jobs: - # Code Coverage enabled build and tests - - b_ubu_codecov: *requires_nothing - - t_ubu_codecov: *requires_b_ubu_codecov - # ASan build and tests - b_ubu_asan: *requires_nothing - b_ubu_san_clang: *job_b_ubu_asan_clang diff --git a/codecov.yml b/codecov.yml deleted file mode 100644 index c0b72761e411..000000000000 --- a/codecov.yml +++ /dev/null @@ -1,22 +0,0 @@ -codecov: - branch: develop -coverage: - range: 70...100 - status: - patch: - default: - target: "50%" - paths: "!test/" - project: - default: - target: auto - paths: "!test/" - syntax: - target: auto - paths: "libsolidity/analysis" - flags: syntax - tests: - target: auto - paths: "test/" -comment: - layout: "reach, diff, flags" From 5f2b1bf72d9fc2ea87eeecc66f03f2480f2c135c Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Tue, 8 Oct 2024 16:12:54 +0200 Subject: [PATCH 0487/1022] Docs: fix curly bracket language wikipedia anchor --- docs/index.rst | 2 +- docs/language-influences.rst | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/index.rst b/docs/index.rst index 600173d65452..f1608890d757 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -4,7 +4,7 @@ Solidity Solidity is an object-oriented, high-level language for implementing smart contracts. Smart contracts are programs that govern the behavior of accounts within the Ethereum state. -Solidity is a `curly-bracket language `_ designed to target the Ethereum Virtual Machine (EVM). +Solidity is a `curly-bracket language `_ designed to target the Ethereum Virtual Machine (EVM). It is influenced by C++, Python, and JavaScript. You can find more details about which languages Solidity has been inspired by in the :doc:`language influences ` section. diff --git a/docs/language-influences.rst b/docs/language-influences.rst index e4f0ab69023b..a3ab1562e9ff 100644 --- a/docs/language-influences.rst +++ b/docs/language-influences.rst @@ -2,7 +2,7 @@ Language Influences ################### -Solidity is a `curly-bracket language `_ +Solidity is a `curly-bracket language `_ that has been influenced and inspired by several well-known programming languages. Solidity is most profoundly influenced by C++, but also borrowed concepts from languages like From 9b97e52d45b4d94df22b3599dc0411317b056668 Mon Sep 17 00:00:00 2001 From: Matheus Aguiar Date: Tue, 8 Oct 2024 11:58:12 -0300 Subject: [PATCH 0488/1022] sort Changelog --- Changelog.md | 4 ++-- docs/bugs_by_version.json | 4 ++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/Changelog.md b/Changelog.md index de1674a15a9d..eabd5b9eee9d 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,7 +1,7 @@ -### 0.8.28 (unreleased) +### 0.8.28 (2024-10-09) Language Features: - * Transient storage value type state variables are now fully supported. + * Transient storage state variables of value types are now fully supported. Compiler Features: diff --git a/docs/bugs_by_version.json b/docs/bugs_by_version.json index f9913d812c63..2c3b6487ae50 100644 --- a/docs/bugs_by_version.json +++ b/docs/bugs_by_version.json @@ -1902,6 +1902,10 @@ "bugs": [], "released": "2024-09-04" }, + "0.8.28": { + "bugs": [], + "released": "2024-10-09" + }, "0.8.3": { "bugs": [ "FullInlinerNonExpressionSplitArgumentEvaluationOrder", From fecd1329cd7a2bb0b77428ac8d02bb6b86c72d24 Mon Sep 17 00:00:00 2001 From: rodiazet Date: Wed, 9 Oct 2024 13:06:41 +0200 Subject: [PATCH 0489/1022] eof: Support EOF asm analysis --- libyul/AsmAnalysis.cpp | 43 +++++++++++++++++-- libyul/AsmAnalysis.h | 4 ++ test/Common.cpp | 2 + test/TestCase.cpp | 30 ++++++++++++- test/TestCase.h | 4 ++ .../eof/call_intruction_in_eof.yul | 13 ++++++ 6 files changed, 91 insertions(+), 5 deletions(-) create mode 100644 test/libyul/yulSyntaxTests/eof/call_intruction_in_eof.yul diff --git a/libyul/AsmAnalysis.cpp b/libyul/AsmAnalysis.cpp index cf8c720f6b36..682931dc414d 100644 --- a/libyul/AsmAnalysis.cpp +++ b/libyul/AsmAnalysis.cpp @@ -625,12 +625,16 @@ void AsmAnalyzer::expectValidIdentifier(YulName _identifier, SourceLocation cons bool AsmAnalyzer::validateInstructions(std::string const& _instructionIdentifier, langutil::SourceLocation const& _location) { // NOTE: This function uses the default EVM version instead of the currently selected one. - // TODO: Add EOF support auto const builtin = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt).builtin(YulName(_instructionIdentifier)); if (builtin && builtin->instruction.has_value()) return validateInstructions(builtin->instruction.value(), _location); - else - return false; + + // TODO: Change `prague()` to `EVMVersion{}` once EOF gets deployed + auto const eofBuiltin = EVMDialect::strictAssemblyForEVM(EVMVersion::prague(), 1).builtin(YulName(_instructionIdentifier)); + if (eofBuiltin && eofBuiltin->instruction.has_value()) + return validateInstructions(eofBuiltin->instruction.value(), _location); + + return false; } bool AsmAnalyzer::validateInstructions(evmasm::Instruction _instr, SourceLocation const& _location) @@ -702,9 +706,42 @@ bool AsmAnalyzer::validateInstructions(evmasm::Instruction _instr, SourceLocatio "PC instruction is a low-level EVM feature. " "Because of that PC is disallowed in strict assembly." ); + else if (m_eofVersion.has_value() && ( + _instr == evmasm::Instruction::CALL || + _instr == evmasm::Instruction::CALLCODE || + _instr == evmasm::Instruction::DELEGATECALL || + _instr == evmasm::Instruction::SELFDESTRUCT || + _instr == evmasm::Instruction::JUMP || + _instr == evmasm::Instruction::JUMPI || + _instr == evmasm::Instruction::PC || + _instr == evmasm::Instruction::CREATE || + _instr == evmasm::Instruction::CODESIZE || + _instr == evmasm::Instruction::CODECOPY || + _instr == evmasm::Instruction::EXTCODESIZE || + _instr == evmasm::Instruction::EXTCODECOPY || + _instr == evmasm::Instruction::GAS + )) + { + m_errorReporter.typeError( + 9132_error, + _location, + fmt::format( + "The \"{instruction}\" instruction is {kind} VMs (you are currently compiling to EOF).", + fmt::arg("instruction", boost::to_lower_copy(instructionInfo(_instr, m_evmVersion).name)), + fmt::arg("kind", "only available in legacy bytecode") + ) + ); + } else + { + // Sanity check + solAssert(m_evmVersion.hasOpcode(_instr, m_eofVersion)); return false; + } + // Sanity check + // PC is not available in strict assembly but it is always valid opcode in legacy evm. + solAssert(_instr == evmasm::Instruction::PC || !m_evmVersion.hasOpcode(_instr, m_eofVersion)); return true; } diff --git a/libyul/AsmAnalysis.h b/libyul/AsmAnalysis.h index 64cab51f54c5..d8a2b2b1ac5f 100644 --- a/libyul/AsmAnalysis.h +++ b/libyul/AsmAnalysis.h @@ -70,7 +70,10 @@ class AsmAnalyzer m_dataNames(std::move(_dataNames)) { if (EVMDialect const* evmDialect = dynamic_cast(&m_dialect)) + { m_evmVersion = evmDialect->evmVersion(); + m_eofVersion = evmDialect->eofVersion(); + } } bool analyze(Block const& _block); @@ -125,6 +128,7 @@ class AsmAnalyzer AsmAnalysisInfo& m_info; langutil::ErrorReporter& m_errorReporter; langutil::EVMVersion m_evmVersion; + std::optional m_eofVersion; Dialect const& m_dialect; /// Names of data objects to be referenced by builtin functions with literal arguments. std::set m_dataNames; diff --git a/test/Common.cpp b/test/Common.cpp index ae725774c48a..bab95c457b6a 100644 --- a/test/Common.cpp +++ b/test/Common.cpp @@ -155,6 +155,8 @@ void CommonOptions::validate() const std::cout << "- ABI coder: v1 (default: v2)" << std::endl; std::cout << std::endl << "DO NOT COMMIT THE UPDATED EXPECTATIONS." << std::endl << std::endl; } + + assertThrow(!eofVersion().has_value() || evmVersion() >= langutil::EVMVersion::prague(), ConfigException, "EOF is unavailable before Prague fork."); } bool CommonOptions::parse(int argc, char const* const* argv) diff --git a/test/TestCase.cpp b/test/TestCase.cpp index ae89bb56f31a..942153d3cd6c 100644 --- a/test/TestCase.cpp +++ b/test/TestCase.cpp @@ -96,8 +96,7 @@ TestCase::TestResult TestCase::checkResult(std::ostream& _stream, const std::str return TestResult::Success; } -EVMVersionRestrictedTestCase::EVMVersionRestrictedTestCase(std::string const& _filename): - TestCase(_filename) +void EVMVersionRestrictedTestCase::processEVMVersionSetting() { std::string versionString = m_reader.stringSetting("EVMVersion", "any"); if (versionString == "any") @@ -139,3 +138,30 @@ EVMVersionRestrictedTestCase::EVMVersionRestrictedTestCase(std::string const& _f if (!comparisonResult) m_shouldRun = false; } + +void EVMVersionRestrictedTestCase::processBytecodeFormatSetting() +{ + std::optional eofVersion = solidity::test::CommonOptions::get().eofVersion(); + // TODO: Update if EOF moved to Osaka + // EOF only available since Prague + solAssert(!eofVersion.has_value() ||solidity::test::CommonOptions::get().evmVersion() >= langutil::EVMVersion::prague()); + + std::string bytecodeFormatString = m_reader.stringSetting("bytecodeFormat", "legacy"); + if (bytecodeFormatString == "legacy,>=EOFv1" || bytecodeFormatString == ">=EOFv1,legacy") + return; + + // TODO: This is naive implementation because for now we support only one EOF version. + if (bytecodeFormatString == "legacy" && eofVersion.has_value()) + m_shouldRun = false; + else if (bytecodeFormatString == ">=EOFv1" && !eofVersion.has_value()) + m_shouldRun = false; + else if (bytecodeFormatString != "legacy" && bytecodeFormatString != ">=EOFv1" ) + BOOST_THROW_EXCEPTION(std::runtime_error{"Invalid bytecodeFormat flag: \"" + bytecodeFormatString + "\""}); +} + +EVMVersionRestrictedTestCase::EVMVersionRestrictedTestCase(std::string const& _filename): + TestCase(_filename) +{ + processEVMVersionSetting(); + processBytecodeFormatSetting(); +} diff --git a/test/TestCase.h b/test/TestCase.h index 301dbfb658e4..bdf51d2a5566 100644 --- a/test/TestCase.h +++ b/test/TestCase.h @@ -112,6 +112,10 @@ class TestCase class EVMVersionRestrictedTestCase: public TestCase { +private: + void processEVMVersionSetting(); + void processBytecodeFormatSetting(); + protected: EVMVersionRestrictedTestCase(std::string const& _filename); }; diff --git a/test/libyul/yulSyntaxTests/eof/call_intruction_in_eof.yul b/test/libyul/yulSyntaxTests/eof/call_intruction_in_eof.yul new file mode 100644 index 000000000000..d26af22a70dc --- /dev/null +++ b/test/libyul/yulSyntaxTests/eof/call_intruction_in_eof.yul @@ -0,0 +1,13 @@ +object "a" { + code { + let success := call(gas(), 0x1, 0, 128, 4, 128, 0) + } +} +// ==== +// EVMVersion: >=shanghai +// bytecodeFormat: >=EOFv1 +// ---- +// TypeError 9132: (47-51): The "call" instruction is only available in legacy bytecode VMs (you are currently compiling to EOF). +// TypeError 9132: (52-55): The "gas" instruction is only available in legacy bytecode VMs (you are currently compiling to EOF). +// TypeError 3950: (52-57): Expected expression to evaluate to one value, but got 0 values instead. +// DeclarationError 3812: (32-82): Variable count mismatch for declaration of "success": 1 variables and 0 values. From 91a37af31ae42d73aa591fca1e42de2fa37a7007 Mon Sep 17 00:00:00 2001 From: Matheus Aguiar Date: Tue, 8 Oct 2024 12:19:32 -0300 Subject: [PATCH 0490/1022] Set next version (0.8.29) --- CMakeLists.txt | 2 +- Changelog.md | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7c36ff73b436..b78269a3d6c1 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.28") +set(PROJECT_VERSION "0.8.29") # 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 eabd5b9eee9d..13af14b75b97 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,3 +1,14 @@ +### 0.8.29 (unreleased) + +Language Features: + + +Compiler Features: + + +Bugfixes: + + ### 0.8.28 (2024-10-09) Language Features: From 7210680329061d0a1f0e03a1431a9781fd79708d Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Thu, 10 Oct 2024 17:05:48 +0200 Subject: [PATCH 0491/1022] Yul: SSACFGLiveness simplifications --- libyul/backends/evm/SSACFGLiveness.cpp | 50 +++++++++++++------------- libyul/backends/evm/SSACFGLiveness.h | 2 +- 2 files changed, 26 insertions(+), 26 deletions(-) diff --git a/libyul/backends/evm/SSACFGLiveness.cpp b/libyul/backends/evm/SSACFGLiveness.cpp index 85bd41d10ed6..4537c8c5d8fc 100644 --- a/libyul/backends/evm/SSACFGLiveness.cpp +++ b/libyul/backends/evm/SSACFGLiveness.cpp @@ -24,6 +24,17 @@ using namespace solidity::yul; +namespace +{ +constexpr auto literalsFilter(SSACFG const& _cfg) +{ + return [&_cfg](SSACFG::ValueId const& _valueId) -> bool + { + return !std::holds_alternative(_cfg.valueInfo(_valueId));; + }; +} +} + SSACFGLiveness::SSACFGLiveness(SSACFG const& _cfg): m_cfg(_cfg), m_topologicalSort(_cfg), @@ -46,9 +57,6 @@ void SSACFGLiveness::runDagDfs() { // post-order traversal SSACFG::BlockId blockId{blockIdValue}; - auto const filterLiterals = [this](auto const& valueId){ - return !std::holds_alternative(m_cfg.valueInfo(valueId)); - }; auto const& block = m_cfg.block(blockId); // live <- PhiUses(B) @@ -66,15 +74,10 @@ void SSACFGLiveness::runDagDfs() auto const it = entries.find(blockId); yulAssert(it != entries.end()); auto const argIndex = static_cast(std::distance(entries.begin(), it)); - if (argIndex < std::get(info).arguments.size()) - { - // todo not sure why arg index would exceed phi arg length but it does happen - auto const arg = std::get(info).arguments.at(argIndex); - if (!std::holds_alternative(m_cfg.valueInfo(arg))) - live.insert(arg); - } - else - yulAssert(false); + yulAssert(argIndex < std::get(info).arguments.size()); + auto const arg = std::get(info).arguments.at(argIndex); + if (!std::holds_alternative(m_cfg.valueInfo(arg))) + live.insert(arg); } }); @@ -86,7 +89,7 @@ void SSACFGLiveness::runDagDfs() }); if (std::holds_alternative(block.exit)) live += std::get(block.exit).returnValues - | ranges::views::filter(filterLiterals); + | ranges::views::filter(literalsFilter(m_cfg)); // clean out unreachables live = live | ranges::views::filter([&](auto const& valueId) { return !std::holds_alternative(m_cfg.valueInfo(valueId)); }) | ranges::to; @@ -98,9 +101,9 @@ void SSACFGLiveness::runDagDfs() for (auto const& op: block.operations | ranges::views::reverse) { // remove variables defined at p from live - live -= op.outputs | ranges::views::filter(filterLiterals) | ranges::to; + live -= op.outputs | ranges::views::filter(literalsFilter(m_cfg)) | ranges::to; // add uses at p to live - live += op.inputs | ranges::views::filter(filterLiterals) | ranges::to; + live += op.inputs | ranges::views::filter(literalsFilter(m_cfg)) | ranges::to; } // livein(b) <- live \cup PhiDefs(B) @@ -120,23 +123,20 @@ void SSACFGLiveness::runLoopTreeDfs(size_t const _loopHeader) // must be live out of header if live in of children m_liveOuts[_loopHeader] += liveLoop; // for each blockId \in children(loopHeader) - for (size_t blockId = 0; blockId < m_cfg.numBlocks(); ++blockId) - if (m_loopNestingForest.loopParents()[blockId] == _loopHeader) + for (size_t blockIdValue = 0; blockIdValue < m_cfg.numBlocks(); ++blockIdValue) + if (m_loopNestingForest.loopParents()[blockIdValue] == _loopHeader) { // propagate loop liveness information down to the loop header's children - m_liveIns[blockId] += liveLoop; - m_liveOuts[blockId] += liveLoop; + m_liveIns[blockIdValue] += liveLoop; + m_liveOuts[blockIdValue] += liveLoop; - runLoopTreeDfs(blockId); + runLoopTreeDfs(blockIdValue); } } } void SSACFGLiveness::fillOperationsLiveOut() { - auto const filterLiterals = [this](auto const& valueId){ - return !std::holds_alternative(m_cfg.valueInfo(valueId)); - }; for (size_t blockIdValue = 0; blockIdValue < m_cfg.numBlocks(); ++blockIdValue) { auto const& operations = m_cfg.block(SSACFG::BlockId{blockIdValue}).operations; @@ -149,8 +149,8 @@ void SSACFGLiveness::fillOperationsLiveOut() for (auto const& op: operations | ranges::views::reverse) { *rit = live; - live -= op.outputs | ranges::views::filter(filterLiterals) | ranges::to; - live += op.inputs | ranges::views::filter(filterLiterals) | ranges::to; + live -= op.outputs | ranges::views::filter(literalsFilter(m_cfg)) | ranges::to; + live += op.inputs | ranges::views::filter(literalsFilter(m_cfg)) | ranges::to; ++rit; } } diff --git a/libyul/backends/evm/SSACFGLiveness.h b/libyul/backends/evm/SSACFGLiveness.h index 72752cfefd45..b0b9ccb7a3dc 100644 --- a/libyul/backends/evm/SSACFGLiveness.h +++ b/libyul/backends/evm/SSACFGLiveness.h @@ -29,7 +29,7 @@ namespace solidity::yul { -/// Performs liveness analysis on an SSA CFG following Algorithm 9.1 in [1]. +/// Performs liveness analysis on a reducible SSA CFG following Algorithm 9.1 in [1]. /// /// [1] Rastello, Fabrice, and Florent Bouchez Tichadou, eds. SSA-based Compiler Design. Springer, 2022. class SSACFGLiveness From 3edd2e173828737f6250256380e2d1193e232969 Mon Sep 17 00:00:00 2001 From: Ustas <82833595+ustas-eth@users.noreply.github.com> Date: Sun, 21 Jan 2024 13:48:21 +0000 Subject: [PATCH 0492/1022] [docs] Add warning about `codehash` behavior depending on the account state Co-authored-by: r0qs --- docs/types/value-types.rst | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/docs/types/value-types.rst b/docs/types/value-types.rst index 27baf5485104..5efb080554a8 100644 --- a/docs/types/value-types.rst +++ b/docs/types/value-types.rst @@ -344,6 +344,13 @@ You can query the deployed code for any smart contract. Use ``.code`` to get the ``bytes memory``, which might be empty. Use ``.codehash`` to get the Keccak-256 hash of that code (as a ``bytes32``). Note that ``addr.codehash`` is cheaper than using ``keccak256(addr.code)``. +.. warning:: + The output of ``addr.codehash`` may be ``0`` if the account associated with ``addr`` is empty or non-existent + (i.e., it has no code, zero balance, and zero nonce as defined by `EIP-161 `_). + If the account has no code but a non-zero balance or nonce, then ``addr.codehash`` will output the Keccak-256 hash of empty data + (i.e., ``keccak256("")`` which is equal to ``c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470``), as defined by + `EIP-1052 `_. + .. note:: All contracts can be converted to ``address`` type, so it is possible to query the balance of the current contract using ``address(this).balance``. From 79ad9610dd2d94f11b204d418db5159d7c95eea8 Mon Sep 17 00:00:00 2001 From: sukey2008 Date: Thu, 10 Oct 2024 21:33:44 +0200 Subject: [PATCH 0493/1022] docs: fix several spelling and grammar issues --- docs/types/value-types.rst | 6 +++--- test/externalTests/README.md | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/types/value-types.rst b/docs/types/value-types.rst index 5efb080554a8..9b5ee447e6d6 100644 --- a/docs/types/value-types.rst +++ b/docs/types/value-types.rst @@ -9,7 +9,7 @@ are used as function arguments or in assignments. Unlike :ref:`reference types `, value type declarations do not specify a data location since they are small enough to be stored on the stack. -The only exception are :ref:`state variables `. +The only exception is :ref:`state variables `. Those are by default located in storage, but can also be marked as :ref:`transient `, :ref:`constant or immutable `. @@ -204,7 +204,7 @@ must be explicit via ``payable(
)``. Explicit conversions to and from ``address`` are allowed for ``uint160``, integer literals, ``bytes20`` and contract types. -Only expressions of type ``address`` and contract-type can be converted to the type ``address +Only expressions of type ``address`` and contract type can be converted to the type ``address payable`` via the explicit conversion ``payable(...)``. For contract-type, this conversion is only allowed if the contract can receive Ether, i.e., the contract either has a :ref:`receive ` or a payable fallback function. Note that ``payable(0)`` is valid and is @@ -215,7 +215,7 @@ an exception to this rule. declare its type as ``address payable`` to make this requirement visible. Also, try to make this distinction or conversion as early as possible. - The distinction between ``address`` and ``address payable`` was introduced with version 0.5.0. + The distinction between ``address`` and ``address payable`` was introduced in version 0.5.0. Also starting from that version, contracts are not implicitly convertible to the ``address`` type, but can still be explicitly converted to ``address`` or to ``address payable``, if they have a receive or payable fallback function. diff --git a/test/externalTests/README.md b/test/externalTests/README.md index 8df5b4dfe043..91e2ef9aff4d 100644 --- a/test/externalTests/README.md +++ b/test/externalTests/README.md @@ -88,6 +88,6 @@ branches if they exist. If no changes on our part were necessary, it is complete 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 +between different external projects. For example, in one project we could have `master_050` on both `develop` and `breaking` and in another `breaking` could use `master_080` while `develop` still uses `master_060`. From e8b5ca83f37b6a126db6a0a1dcfa00decff63647 Mon Sep 17 00:00:00 2001 From: Jeff Wentworth Date: Fri, 11 Oct 2024 21:25:17 +0900 Subject: [PATCH 0494/1022] Update Natspec format to correct devdoc return parameters (#15187) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Update natspec-format.rst for devdoc return values * update changelog * values ==> returns * Fix Solidity and improve doc output * Update Changelog.md Co-authored-by: Nikola Matić * Apply suggestions from code review Co-authored-by: Nikola Matić --------- Co-authored-by: Nikola Matić --- docs/natspec-format.rst | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/docs/natspec-format.rst b/docs/natspec-format.rst index b187ea84c74f..f1910648378f 100644 --- a/docs/natspec-format.rst +++ b/docs/natspec-format.rst @@ -73,8 +73,9 @@ The following example shows a contract and a function using all available tags. /// @dev The Alexandr N. Tetearing algorithm could increase precision /// @param rings The number of rings from dendrochronological sample /// @return Age in years, rounded up for partial years - function age(uint256 rings) external virtual pure returns (uint256) { - return rings + 1; + /// @return Name of the tree + function age(uint256 rings) external virtual pure returns (uint256, string memory) { + return (rings + 1, "tree"); } /// @notice Returns the amount of leaves the tree has. @@ -91,8 +92,8 @@ The following example shows a contract and a function using all available tags. } contract KumquatTree is Tree, Plant { - function age(uint256 rings) external override pure returns (uint256) { - return rings + 2; + function age(uint256 rings) external override pure returns (uint256, string memory) { + return (rings + 2, "Kumquat"); } /// Return the amount of leaves that this specific kind of tree has @@ -196,7 +197,7 @@ User Documentation ------------------ The above documentation will produce the following user documentation -JSON file as output: +JSON file as output for the ``Tree`` contract: .. code-block:: json @@ -209,6 +210,10 @@ JSON file as output: { "notice" : "Calculate tree age in years, rounded up, for live trees" } + "leaves()" : + { + "notice" : "Returns the amount of leaves the tree has." + } }, "notice" : "You can use this contract for only the most basic simulation" } @@ -243,7 +248,14 @@ file should also be produced and should look like this: { "rings" : "The number of rings from dendrochronological sample" }, - "return" : "age in years, rounded up for partial years" + "returns" : { + "_0" : "Age in years, rounded up for partial years", + "_1" : "Name of the tree" + } + }, + "leaves()" : + { + "details" : "Returns only a fixed number." } }, "title" : "A simulator for trees" From 520ee5a9c009098a4d94cdc9fbb78896585a8057 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Fri, 11 Oct 2024 15:07:47 +0200 Subject: [PATCH 0495/1022] Compiler stack: Protect loadGeneratedIR from contracts that cannot be deployed --- libsolidity/interface/CompilerStack.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/libsolidity/interface/CompilerStack.cpp b/libsolidity/interface/CompilerStack.cpp index c68df205f941..007b6187c747 100644 --- a/libsolidity/interface/CompilerStack.cpp +++ b/libsolidity/interface/CompilerStack.cpp @@ -982,7 +982,9 @@ Json CompilerStack::yulIRAst(std::string const& _contractName) const // NOTE: Intentionally not using LazyInit. The artifact can get very large and we don't want to // keep it around when compiling a large project containing many contracts. - return loadGeneratedIR(contract(_contractName).yulIR).astJson(); + auto const& currentContract = contract(_contractName); + yulAssert(currentContract.contract); + return currentContract.contract->canBeDeployed() ? loadGeneratedIR(currentContract.yulIR).astJson() : Json{}; } Json CompilerStack::yulCFGJson(std::string const& _contractName) const @@ -992,7 +994,9 @@ Json CompilerStack::yulCFGJson(std::string const& _contractName) const // NOTE: Intentionally not using LazyInit. The artifact can get very large and we don't want to // keep it around when compiling a large project containing many contracts. - return loadGeneratedIR(contract(_contractName).yulIR).cfgJson(); + auto const& currentContract = contract(_contractName); + yulAssert(currentContract.contract); + return currentContract.contract->canBeDeployed() ? loadGeneratedIR(currentContract.yulIR).cfgJson() : Json{}; } std::string const& CompilerStack::yulIROptimized(std::string const& _contractName) const @@ -1008,7 +1012,9 @@ Json CompilerStack::yulIROptimizedAst(std::string const& _contractName) const // NOTE: Intentionally not using LazyInit. The artifact can get very large and we don't want to // keep it around when compiling a large project containing many contracts. - return loadGeneratedIR(contract(_contractName).yulIROptimized).astJson(); + auto const& currentContract = contract(_contractName); + yulAssert(currentContract.contract); + return currentContract.contract->canBeDeployed() ? loadGeneratedIR(currentContract.yulIROptimized).astJson() : Json{}; } evmasm::LinkerObject const& CompilerStack::object(std::string const& _contractName) const From c38e4e66a181ff623a21073a78bdefe61ca80c7d Mon Sep 17 00:00:00 2001 From: rodiazet Date: Fri, 11 Oct 2024 14:57:24 +0200 Subject: [PATCH 0496/1022] Pass `evmVersion` and `eofVersion` to `YulStack` in `ObjectCompilerTest` --- test/libyul/ControlFlowSideEffectsTest.cpp | 4 +- test/libyul/EVMCodeTransformTest.cpp | 5 +- test/libyul/FunctionSideEffects.cpp | 4 +- test/libyul/KnowledgeBaseTest.cpp | 4 +- test/libyul/ObjectCompilerTest.cpp | 6 +- test/libyul/ObjectCompilerTest.h | 2 +- test/libyul/ObjectParser.cpp | 4 +- test/libyul/Parser.cpp | 172 +++++++++--------- test/libyul/YulInterpreterTest.cpp | 3 +- test/libyul/objectCompiler/datacopy.yul | 2 + .../libyul/objectCompiler/dataoffset_code.yul | 2 + .../libyul/objectCompiler/dataoffset_data.yul | 2 + .../libyul/objectCompiler/dataoffset_self.yul | 2 + test/libyul/objectCompiler/datasize_code.yul | 2 + test/libyul/objectCompiler/datasize_data.yul | 2 + test/libyul/objectCompiler/datasize_self.yul | 2 + .../libyul/objectCompiler/function_series.yul | 1 + .../identical_subobjects_full_debug_info.yul | 1 + .../identical_subobjects_no_debug_info.yul | 1 + ...dentical_subobjects_partial_debug_info.yul | 1 + ...bobjects_partial_debug_info_no_use_src.yul | 1 + ...cal_subobjects_with_subject_references.yul | 1 + ..._long_name_does_not_end_up_in_bytecode.yul | 2 + .../leading_and_trailing_dots.yul | 2 + test/libyul/objectCompiler/linkersymbol.yul | 2 + .../objectCompiler/long_object_name.yul | 1 + test/libyul/objectCompiler/manySubObjects.yul | 2 + test/libyul/objectCompiler/metadata.yul | 2 + .../libyul/objectCompiler/namedObjectCode.yul | 2 + .../objectCompiler/nested_optimizer.yul | 1 + test/libyul/objectCompiler/simple.yul | 2 + .../objectCompiler/simple_optimizer.yul | 1 + .../libyul/objectCompiler/sourceLocations.yul | 2 + .../libyul/objectCompiler/subObjectAccess.yul | 2 + test/libyul/objectCompiler/verbatim_bug.yul | 1 + 35 files changed, 144 insertions(+), 102 deletions(-) diff --git a/test/libyul/ControlFlowSideEffectsTest.cpp b/test/libyul/ControlFlowSideEffectsTest.cpp index 50c69b179dd1..b9d883dcde06 100644 --- a/test/libyul/ControlFlowSideEffectsTest.cpp +++ b/test/libyul/ControlFlowSideEffectsTest.cpp @@ -62,9 +62,9 @@ TestCase::TestResult ControlFlowSideEffectsTest::run(std::ostream& _stream, std: if (!obj.hasCode()) BOOST_THROW_EXCEPTION(std::runtime_error("Parsing input failed.")); - // TODO: Add EOF support ControlFlowSideEffectsCollector sideEffects( - EVMDialect::strictAssemblyForEVMObjects(langutil::EVMVersion(), std::nullopt), + EVMDialect::strictAssemblyForEVMObjects(solidity::test::CommonOptions::get().evmVersion(), + solidity::test::CommonOptions::get().eofVersion()), obj.code()->root() ); m_obtainedResult.clear(); diff --git a/test/libyul/EVMCodeTransformTest.cpp b/test/libyul/EVMCodeTransformTest.cpp index 23c24ce305fd..75d86136e9e0 100644 --- a/test/libyul/EVMCodeTransformTest.cpp +++ b/test/libyul/EVMCodeTransformTest.cpp @@ -67,14 +67,13 @@ TestCase::TestResult EVMCodeTransformTest::run(std::ostream& _stream, std::strin return TestResult::FatalError; } - // TODO: Add EOF support evmasm::Assembly assembly{solidity::test::CommonOptions::get().evmVersion(), false, std::nullopt, {}}; EthAssemblyAdapter adapter(assembly); EVMObjectCompiler::compile( *stack.parserResult(), adapter, - // TODO: Make sure that why we cannot pass here solidity::test::CommonOptions::get().evmVersion() and assembly.eofVersion() - EVMDialect::strictAssemblyForEVMObjects(EVMVersion{}, std::nullopt), + EVMDialect::strictAssemblyForEVMObjects(solidity::test::CommonOptions::get().evmVersion(), + solidity::test::CommonOptions::get().eofVersion()), m_stackOpt, std::nullopt ); diff --git a/test/libyul/FunctionSideEffects.cpp b/test/libyul/FunctionSideEffects.cpp index 7a153de7d362..a878d375d02b 100644 --- a/test/libyul/FunctionSideEffects.cpp +++ b/test/libyul/FunctionSideEffects.cpp @@ -88,9 +88,9 @@ TestCase::TestResult FunctionSideEffects::run(std::ostream& _stream, std::string if (!obj.hasCode()) BOOST_THROW_EXCEPTION(std::runtime_error("Parsing input failed.")); - // TODO: Add EOF support std::map functionSideEffects = SideEffectsPropagator::sideEffects( - EVMDialect::strictAssemblyForEVMObjects(langutil::EVMVersion(), std::nullopt), + EVMDialect::strictAssemblyForEVMObjects(solidity::test::CommonOptions::get().evmVersion(), + solidity::test::CommonOptions::get().eofVersion()), CallGraphGenerator::callGraph(obj.code()->root()) ); diff --git a/test/libyul/KnowledgeBaseTest.cpp b/test/libyul/KnowledgeBaseTest.cpp index badeb21fe7f9..253e7e0d5ae0 100644 --- a/test/libyul/KnowledgeBaseTest.cpp +++ b/test/libyul/KnowledgeBaseTest.cpp @@ -63,8 +63,8 @@ class KnowledgeBaseTest return KnowledgeBase([this](YulName _var) { return util::valueOrNullptr(m_values, _var); }); } - // TODO: Add EOF support - EVMDialect m_dialect{EVMVersion{}, std::nullopt, true}; + EVMDialect m_dialect{solidity::test::CommonOptions::get().evmVersion(), + solidity::test::CommonOptions::get().eofVersion(), true}; std::shared_ptr m_object; SSAValueTracker m_ssaValues; std::map m_values; diff --git a/test/libyul/ObjectCompilerTest.cpp b/test/libyul/ObjectCompilerTest.cpp index 5d6dd1b23dea..126c3ad6f691 100644 --- a/test/libyul/ObjectCompilerTest.cpp +++ b/test/libyul/ObjectCompilerTest.cpp @@ -46,7 +46,7 @@ using namespace solidity::frontend; using namespace solidity::frontend::test; ObjectCompilerTest::ObjectCompilerTest(std::string const& _filename): - TestCase(_filename) + solidity::frontend::test::EVMVersionRestrictedTestCase(_filename) { m_source = m_reader.source(); m_optimisationPreset = m_reader.enumSetting( @@ -65,8 +65,8 @@ ObjectCompilerTest::ObjectCompilerTest(std::string const& _filename): TestCase::TestResult ObjectCompilerTest::run(std::ostream& _stream, std::string const& _linePrefix, bool const _formatted) { YulStack stack( - EVMVersion(), - std::nullopt, + solidity::test::CommonOptions::get().evmVersion(), + solidity::test::CommonOptions::get().eofVersion(), YulStack::Language::StrictAssembly, OptimiserSettings::preset(m_optimisationPreset), DebugInfoSelection::All() diff --git a/test/libyul/ObjectCompilerTest.h b/test/libyul/ObjectCompilerTest.h index fe899870022e..3310d80b8e26 100644 --- a/test/libyul/ObjectCompilerTest.h +++ b/test/libyul/ObjectCompilerTest.h @@ -38,7 +38,7 @@ struct Block; namespace solidity::yul::test { -class ObjectCompilerTest: public solidity::frontend::test::TestCase +class ObjectCompilerTest: public solidity::frontend::test::EVMVersionRestrictedTestCase { public: static std::unique_ptr create(Config const& _config) diff --git a/test/libyul/ObjectParser.cpp b/test/libyul/ObjectParser.cpp index 7ed321cd48e6..9a891be915d7 100644 --- a/test/libyul/ObjectParser.cpp +++ b/test/libyul/ObjectParser.cpp @@ -112,8 +112,8 @@ std::tuple, ErrorList> tryGetSourceLocationMapping( ErrorList errors; ErrorReporter reporter(errors); - // TODO: Add EOF support - Dialect const& dialect = yul::EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); + Dialect const& dialect = yul::EVMDialect::strictAssemblyForEVM(solidity::test::CommonOptions::get().evmVersion(), + solidity::test::CommonOptions::get().eofVersion()); ObjectParser objectParser{reporter, dialect}; CharStream stream(std::move(source), ""); auto object = objectParser.parse(std::make_shared(stream), false); diff --git a/test/libyul/Parser.cpp b/test/libyul/Parser.cpp index 930a34cf1a04..d0850972b442 100644 --- a/test/libyul/Parser.cpp +++ b/test/libyul/Parser.cpp @@ -162,8 +162,8 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_empty_block) auto const sourceText = "/// @src 0:234:543\n" "{}\n"; - // TODO: Add EOF support - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); + auto const& dialect = EVMDialect::strictAssemblyForEVM(solidity::test::CommonOptions::get().evmVersion(), + solidity::test::CommonOptions::get().eofVersion()); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.size() == 0); CHECK_LOCATION(result->root().debugData->originLocation, "source0", 234, 543); @@ -181,8 +181,8 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_block_with_children) "let z := true\n" "let y := add(1, 2)\n" "}\n"; - // TODO: Add EOF support - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); + auto const& dialect = EVMDialect::strictAssemblyForEVM(solidity::test::CommonOptions::get().evmVersion(), + solidity::test::CommonOptions::get().eofVersion()); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result); CHECK_LOCATION(result->root().debugData->originLocation, "source0", 234, 543); @@ -205,8 +205,8 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_block_different_sources) "let z := true\n" "let y := add(1, 2)\n" "}\n"; - // TODO: Add EOF support - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); + auto const& dialect = EVMDialect::strictAssemblyForEVM(solidity::test::CommonOptions::get().evmVersion(), + solidity::test::CommonOptions::get().eofVersion()); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.size() == 0); CHECK_LOCATION(result->root().debugData->originLocation, "source0", 234, 543); @@ -228,8 +228,8 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_block_nested) "/// @src 0:343:434\n" "switch y case 0 {} default {}\n" "}\n"; - // TODO: Add EOF support - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); + auto const& dialect = EVMDialect::strictAssemblyForEVM(solidity::test::CommonOptions::get().evmVersion(), + solidity::test::CommonOptions::get().eofVersion()); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.size() == 0); CHECK_LOCATION(result->root().debugData->originLocation, "source0", 234, 543); @@ -253,8 +253,8 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_block_switch_case) " let z := add(3, 4)\n" "}\n" "}\n"; - // TODO: Add EOF support - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); + auto const& dialect = EVMDialect::strictAssemblyForEVM(solidity::test::CommonOptions::get().evmVersion(), + solidity::test::CommonOptions::get().eofVersion()); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.size() == 0); CHECK_LOCATION(result->root().debugData->originLocation, "source0", 234, 543); @@ -286,8 +286,8 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_inherit_into_outer_scope) "let z := true\n" "let y := add(1, 2)\n" "}\n"; - // TODO: Add EOF support - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); + auto const& dialect = EVMDialect::strictAssemblyForEVM(solidity::test::CommonOptions::get().evmVersion(), + solidity::test::CommonOptions::get().eofVersion()); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.size() == 0); @@ -318,8 +318,8 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_assign_empty) "/// @src 1:1:10\n" "a := true\n" "}\n"; - // TODO: Add EOF support - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); + auto const& dialect = EVMDialect::strictAssemblyForEVM(solidity::test::CommonOptions::get().evmVersion(), + solidity::test::CommonOptions::get().eofVersion()); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.size() == 0); // should still parse BOOST_REQUIRE_EQUAL(2, result->root().statements.size()); @@ -340,8 +340,8 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_invalid_source_index) "let b := true\n" "\n" "}\n"; - // TODO: Add EOF support - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); + auto const& dialect = EVMDialect::strictAssemblyForEVM(solidity::test::CommonOptions::get().evmVersion(), + solidity::test::CommonOptions::get().eofVersion()); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result); // should still parse BOOST_REQUIRE(errorList.size() == 1); @@ -361,8 +361,8 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_mixed_locations_1) "/// @src 0:234:2026\n" ":= true\n" "}\n"; - // TODO: Add EOF support - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); + auto const& dialect = EVMDialect::strictAssemblyForEVM(solidity::test::CommonOptions::get().evmVersion(), + solidity::test::CommonOptions::get().eofVersion()); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.size() == 0); @@ -385,8 +385,8 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_mixed_locations_2) 2) } )"; - // TODO: Add EOF support - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); + auto const& dialect = EVMDialect::strictAssemblyForEVM(solidity::test::CommonOptions::get().evmVersion(), + solidity::test::CommonOptions::get().eofVersion()); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.size() == 0); BOOST_REQUIRE_EQUAL(1, result->root().statements.size()); @@ -420,8 +420,8 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_mixed_locations_3) mstore(1, 2) // FunctionCall } )"; - // TODO: Add EOF support - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); + auto const& dialect = EVMDialect::strictAssemblyForEVM(solidity::test::CommonOptions::get().evmVersion(), + solidity::test::CommonOptions::get().eofVersion()); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.size() == 0); BOOST_REQUIRE_EQUAL(2, result->root().statements.size()); @@ -457,8 +457,8 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_invalid_comments_after_valid) let a := true } )"; - // TODO: Add EOF support - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); + auto const& dialect = EVMDialect::strictAssemblyForEVM(solidity::test::CommonOptions::get().evmVersion(), + solidity::test::CommonOptions::get().eofVersion()); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.size() == 0); BOOST_REQUIRE_EQUAL(1, result->root().statements.size()); @@ -477,8 +477,8 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_invalid_suffix) /// @src 0:420:680foo {} )"; - // TODO: Add EOF support - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); + auto const& dialect = EVMDialect::strictAssemblyForEVM(solidity::test::CommonOptions::get().evmVersion(), + solidity::test::CommonOptions::get().eofVersion()); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result); BOOST_REQUIRE(errorList.size() == 1); @@ -495,8 +495,8 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_invalid_prefix) /// abc@src 0:111:222 {} )"; - // TODO: Add EOF support - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); + auto const& dialect = EVMDialect::strictAssemblyForEVM(solidity::test::CommonOptions::get().evmVersion(), + solidity::test::CommonOptions::get().eofVersion()); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.size() == 0); CHECK_LOCATION(result->root().debugData->originLocation, "", -1, -1); @@ -510,8 +510,8 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_unspecified) /// @src -1:-1:-1 {} )"; - // TODO: Add EOF support - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); + auto const& dialect = EVMDialect::strictAssemblyForEVM(solidity::test::CommonOptions::get().evmVersion(), + solidity::test::CommonOptions::get().eofVersion()); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.size() == 0); CHECK_LOCATION(result->root().debugData->originLocation, "", -1, -1); @@ -525,8 +525,8 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_non_integer) /// @src a:b:c {} )"; - // TODO: Add EOF support - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); + auto const& dialect = EVMDialect::strictAssemblyForEVM(solidity::test::CommonOptions::get().evmVersion(), + solidity::test::CommonOptions::get().eofVersion()); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result); BOOST_REQUIRE(errorList.size() == 1); @@ -543,8 +543,8 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_bad_integer) /// @src 111111111111111111111:222222222222222222222:333333333333333333333 {} )"; - // TODO: Add EOF support - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); + auto const& dialect = EVMDialect::strictAssemblyForEVM(solidity::test::CommonOptions::get().evmVersion(), + solidity::test::CommonOptions::get().eofVersion()); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result); BOOST_REQUIRE(errorList.size() == 1); @@ -565,8 +565,8 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_ensure_last_match) let x := true } )"; - // TODO: Add EOF support - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); + auto const& dialect = EVMDialect::strictAssemblyForEVM(solidity::test::CommonOptions::get().evmVersion(), + solidity::test::CommonOptions::get().eofVersion()); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.size() == 0); BOOST_REQUIRE(std::holds_alternative(result->root().statements.at(0))); @@ -584,8 +584,8 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_two_locations_no_whitespace) /// @src 0:111:222@src 1:333:444 {} )"; - // TODO: Add EOF support - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); + auto const& dialect = EVMDialect::strictAssemblyForEVM(solidity::test::CommonOptions::get().evmVersion(), + solidity::test::CommonOptions::get().eofVersion()); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result); BOOST_REQUIRE(errorList.size() == 1); @@ -602,8 +602,8 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_two_locations_separated_with_single_s /// @src 0:111:222 @src 1:333:444 {} )"; - // TODO: Add EOF support - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); + auto const& dialect = EVMDialect::strictAssemblyForEVM(solidity::test::CommonOptions::get().evmVersion(), + solidity::test::CommonOptions::get().eofVersion()); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.size() == 0); CHECK_LOCATION(result->root().debugData->originLocation, "source1", 333, 444); @@ -614,8 +614,8 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_leading_trailing_whitespace) ErrorList errorList; ErrorReporter reporter(errorList); auto const sourceText = "/// @src 0:111:222 \n{}"; - // TODO: Add EOF support - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); + auto const& dialect = EVMDialect::strictAssemblyForEVM(solidity::test::CommonOptions::get().evmVersion(), + solidity::test::CommonOptions::get().eofVersion()); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.size() == 0); CHECK_LOCATION(result->root().debugData->originLocation, "source0", 111, 222); @@ -632,8 +632,8 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_reference_original_sloc) let x := true } )"; - // TODO: Add EOF support - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); + auto const& dialect = EVMDialect::strictAssemblyForEVM(solidity::test::CommonOptions::get().evmVersion(), + solidity::test::CommonOptions::get().eofVersion()); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.size() == 0); BOOST_REQUIRE(std::holds_alternative(result->root().statements.at(0))); @@ -655,8 +655,8 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_with_code_snippets) let y := /** @src 1:96:165 "contract D {..." */ 128 } )~~~"; - // TODO: Add EOF support - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); + auto const& dialect = EVMDialect::strictAssemblyForEVM(solidity::test::CommonOptions::get().evmVersion(), + solidity::test::CommonOptions::get().eofVersion()); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.size() == 0); BOOST_REQUIRE_EQUAL(result->root().statements.size(), 2); @@ -681,8 +681,8 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_with_code_snippets_empty_snippet) /// @src 0:111:222 "" {} )"; - // TODO: Add EOF support - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); + auto const& dialect = EVMDialect::strictAssemblyForEVM(solidity::test::CommonOptions::get().evmVersion(), + solidity::test::CommonOptions::get().eofVersion()); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.size() == 0); CHECK_LOCATION(result->root().debugData->originLocation, "source0", 111, 222); @@ -696,8 +696,8 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_with_code_snippets_no_whitespace_befo /// @src 0:111:222"abc" def {} )"; - // TODO: Add EOF support - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); + auto const& dialect = EVMDialect::strictAssemblyForEVM(solidity::test::CommonOptions::get().evmVersion(), + solidity::test::CommonOptions::get().eofVersion()); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result); BOOST_REQUIRE(errorList.size() == 1); @@ -714,8 +714,8 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_with_code_snippets_no_whitespace_afte /// @src 0:111:222 "abc"def {} )"; - // TODO: Add EOF support - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); + auto const& dialect = EVMDialect::strictAssemblyForEVM(solidity::test::CommonOptions::get().evmVersion(), + solidity::test::CommonOptions::get().eofVersion()); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.size() == 0); CHECK_LOCATION(result->root().debugData->originLocation, "source0", 111, 222); @@ -729,8 +729,8 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_two_locations_with_snippets_no_whites /// @src 0:111:222 "abc"@src 1:333:444 "abc" {} )"; - // TODO: Add EOF support - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); + auto const& dialect = EVMDialect::strictAssemblyForEVM(solidity::test::CommonOptions::get().evmVersion(), + solidity::test::CommonOptions::get().eofVersion()); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.size() == 0); CHECK_LOCATION(result->root().debugData->originLocation, "source1", 333, 444); @@ -744,8 +744,8 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_two_locations_with_snippets_untermina /// @src 0:111:222 " abc @src 1:333:444 {} )"; - // TODO: Add EOF support - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); + auto const& dialect = EVMDialect::strictAssemblyForEVM(solidity::test::CommonOptions::get().evmVersion(), + solidity::test::CommonOptions::get().eofVersion()); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result); BOOST_REQUIRE(errorList.size() == 1); @@ -763,8 +763,8 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_single_quote) /// {} )"; - // TODO: Add EOF support - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); + auto const& dialect = EVMDialect::strictAssemblyForEVM(solidity::test::CommonOptions::get().evmVersion(), + solidity::test::CommonOptions::get().eofVersion()); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result); BOOST_REQUIRE(errorList.size() == 1); @@ -781,8 +781,8 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_two_snippets_with_hex_comment) /// @src 0:111:222 hex"abc"@src 1:333:444 "abc" {} )"; - // TODO: Add EOF support - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); + auto const& dialect = EVMDialect::strictAssemblyForEVM(solidity::test::CommonOptions::get().evmVersion(), + solidity::test::CommonOptions::get().eofVersion()); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.size() == 0); // the second source location is not parsed as such, as the hex string isn't interpreted as snippet but @@ -798,8 +798,8 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_invalid_escapes) /// @src 0:111:222 "\n\\x\x\w\uö\xy\z\y\fq" {} )"; - // TODO: Add EOF support - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); + auto const& dialect = EVMDialect::strictAssemblyForEVM(solidity::test::CommonOptions::get().evmVersion(), + solidity::test::CommonOptions::get().eofVersion()); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.size() == 0); CHECK_LOCATION(result->root().debugData->originLocation, "source0", 111, 222); @@ -814,8 +814,8 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_single_quote_snippet_with_whitespaces /// @src 1 : 222 : 333 '\x33\u1234\t\n' {} )"; - // TODO: Add EOF support - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); + auto const& dialect = EVMDialect::strictAssemblyForEVM(solidity::test::CommonOptions::get().evmVersion(), + solidity::test::CommonOptions::get().eofVersion()); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.size() == 0); CHECK_LOCATION(result->root().debugData->originLocation, "source1", 222, 333); @@ -830,8 +830,8 @@ BOOST_DATA_TEST_CASE(customSourceLocations_scanner_errors_outside_string_lits_ar /// @src 1:222:333 {{}} )", invalid); - // TODO: Add EOF support - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); + auto const& dialect = EVMDialect::strictAssemblyForEVM(solidity::test::CommonOptions::get().evmVersion(), + solidity::test::CommonOptions::get().eofVersion()); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.empty()); CHECK_LOCATION(result->root().debugData->originLocation, "source1", 222, 333); @@ -849,8 +849,8 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_multi_line_source_loc) /// " @src 0:333:444 {} )"; - // TODO: Add EOF support - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); + auto const& dialect = EVMDialect::strictAssemblyForEVM(solidity::test::CommonOptions::get().evmVersion(), + solidity::test::CommonOptions::get().eofVersion()); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.empty()); CHECK_LOCATION(result->root().debugData->originLocation, "source0", 333, 444); @@ -868,8 +868,8 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_with_code_snippets_with_nested_locati let y := /** @src 1:96:165 "function f() internal { \"\/** @src 0:6:7 *\/\"; }" */ 128 } )~~~"; - // TODO: Add EOF support - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); + auto const& dialect = EVMDialect::strictAssemblyForEVM(solidity::test::CommonOptions::get().evmVersion(), + solidity::test::CommonOptions::get().eofVersion()); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.size() == 0); BOOST_REQUIRE_EQUAL(result->root().statements.size(), 2); @@ -898,8 +898,8 @@ BOOST_AUTO_TEST_CASE(astid) mstore(1, 2) } )"; - // TODO: Add EOF support - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); + auto const& dialect = EVMDialect::strictAssemblyForEVM(solidity::test::CommonOptions::get().evmVersion(), + solidity::test::CommonOptions::get().eofVersion()); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result); BOOST_CHECK(result->root().debugData->astID == int64_t(7)); @@ -921,8 +921,8 @@ BOOST_AUTO_TEST_CASE(astid_reset) mstore(1, 2) } )"; - // TODO: Add EOF support - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); + auto const& dialect = EVMDialect::strictAssemblyForEVM(solidity::test::CommonOptions::get().evmVersion(), + solidity::test::CommonOptions::get().eofVersion()); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result); BOOST_CHECK(result->root().debugData->astID == int64_t(7)); @@ -940,8 +940,8 @@ BOOST_AUTO_TEST_CASE(astid_multi) /// @src -1:-1:-1 @ast-id 7 @src 1:1:1 @ast-id 8 {} )"; - // TODO: Add EOF support - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); + auto const& dialect = EVMDialect::strictAssemblyForEVM(solidity::test::CommonOptions::get().evmVersion(), + solidity::test::CommonOptions::get().eofVersion()); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result); BOOST_CHECK(result->root().debugData->astID == int64_t(8)); @@ -955,8 +955,8 @@ BOOST_AUTO_TEST_CASE(astid_invalid) /// @src -1:-1:-1 @ast-id abc @src 1:1:1 {} )"; - // TODO: Add EOF support - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); + auto const& dialect = EVMDialect::strictAssemblyForEVM(solidity::test::CommonOptions::get().evmVersion(), + solidity::test::CommonOptions::get().eofVersion()); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result); BOOST_REQUIRE(errorList.size() == 1); @@ -973,8 +973,8 @@ BOOST_AUTO_TEST_CASE(astid_too_large) /// @ast-id 9223372036854775808 {} )"; - // TODO: Add EOF support - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); + auto const& dialect = EVMDialect::strictAssemblyForEVM(solidity::test::CommonOptions::get().evmVersion(), + solidity::test::CommonOptions::get().eofVersion()); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result); BOOST_REQUIRE(errorList.size() == 1); @@ -990,8 +990,8 @@ BOOST_AUTO_TEST_CASE(astid_way_too_large) /// @ast-id 999999999999999999999999999999999999999 {} )"; - // TODO: Add EOF support - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); + auto const& dialect = EVMDialect::strictAssemblyForEVM(solidity::test::CommonOptions::get().evmVersion(), + solidity::test::CommonOptions::get().eofVersion()); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result); BOOST_REQUIRE(errorList.size() == 1); @@ -1007,8 +1007,8 @@ BOOST_AUTO_TEST_CASE(astid_not_fully_numeric) /// @ast-id 9x {} )"; - // TODO: Add EOF support - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); + auto const& dialect = EVMDialect::strictAssemblyForEVM(solidity::test::CommonOptions::get().evmVersion(), + solidity::test::CommonOptions::get().eofVersion()); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result); BOOST_REQUIRE(errorList.size() == 1); @@ -1030,8 +1030,8 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_multiple_src_tags_on_one_line) "\n" " let x := 123\n" "}\n"; - // TODO: Add EOF support - auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); + auto const& dialect = EVMDialect::strictAssemblyForEVM(solidity::test::CommonOptions::get().evmVersion(), + solidity::test::CommonOptions::get().eofVersion()); std::shared_ptr result = parse(sourceText, dialect, reporter); BOOST_REQUIRE(!!result && errorList.size() == 0); BOOST_REQUIRE_EQUAL(result->root().statements.size(), 1); diff --git a/test/libyul/YulInterpreterTest.cpp b/test/libyul/YulInterpreterTest.cpp index 343a17b4a4a1..484a7a241d81 100644 --- a/test/libyul/YulInterpreterTest.cpp +++ b/test/libyul/YulInterpreterTest.cpp @@ -98,7 +98,8 @@ std::string YulInterpreterTest::interpret() { Interpreter::run( state, - EVMDialect::strictAssemblyForEVMObjects(solidity::test::CommonOptions::get().evmVersion(), std::nullopt), + EVMDialect::strictAssemblyForEVMObjects(solidity::test::CommonOptions::get().evmVersion(), + solidity::test::CommonOptions::get().eofVersion()), m_ast->root(), /*disableExternalCalls=*/ !m_simulateExternalCallsToSelf, /*disableMemoryTracing=*/ false diff --git a/test/libyul/objectCompiler/datacopy.yul b/test/libyul/objectCompiler/datacopy.yul index 9f7fca9adc8d..46a0ec0f7a6d 100644 --- a/test/libyul/objectCompiler/datacopy.yul +++ b/test/libyul/objectCompiler/datacopy.yul @@ -11,6 +11,8 @@ object "a" { data "data1" "Hello, World!" } } +// ==== +// EVMVersion: >=shanghai // ---- // Assembly: // /* "source":77:92 */ diff --git a/test/libyul/objectCompiler/dataoffset_code.yul b/test/libyul/objectCompiler/dataoffset_code.yul index 8ca10add2f26..1171303af291 100644 --- a/test/libyul/objectCompiler/dataoffset_code.yul +++ b/test/libyul/objectCompiler/dataoffset_code.yul @@ -5,6 +5,8 @@ object "a" { data "data1" "Hello, World!" } } +// ==== +// EVMVersion: >=shanghai // ---- // Assembly: // /* "source":44:61 */ diff --git a/test/libyul/objectCompiler/dataoffset_data.yul b/test/libyul/objectCompiler/dataoffset_data.yul index 915567489816..381cb999f0ed 100644 --- a/test/libyul/objectCompiler/dataoffset_data.yul +++ b/test/libyul/objectCompiler/dataoffset_data.yul @@ -2,6 +2,8 @@ object "a" { code { sstore(0, dataoffset("data1")) } data "data1" "Hello, World!" } +// ==== +// EVMVersion: >=shanghai // ---- // Assembly: // /* "source":56:75 */ diff --git a/test/libyul/objectCompiler/dataoffset_self.yul b/test/libyul/objectCompiler/dataoffset_self.yul index 681c24c0eecb..b6a0552cb7b1 100644 --- a/test/libyul/objectCompiler/dataoffset_self.yul +++ b/test/libyul/objectCompiler/dataoffset_self.yul @@ -2,6 +2,8 @@ object "a" { code { sstore(0, dataoffset("a")) } data "data1" "Hello, World!" } +// ==== +// EVMVersion: >=shanghai // ---- // Assembly: // /* "source":44:59 */ diff --git a/test/libyul/objectCompiler/datasize_code.yul b/test/libyul/objectCompiler/datasize_code.yul index cab7987ea9cc..7bf365031b5b 100644 --- a/test/libyul/objectCompiler/datasize_code.yul +++ b/test/libyul/objectCompiler/datasize_code.yul @@ -5,6 +5,8 @@ object "a" { data "data1" "Hello, World!" } } +// ==== +// EVMVersion: >=shanghai // ---- // Assembly: // /* "source":44:59 */ diff --git a/test/libyul/objectCompiler/datasize_data.yul b/test/libyul/objectCompiler/datasize_data.yul index d1261d2464a4..f0ae32b1b661 100644 --- a/test/libyul/objectCompiler/datasize_data.yul +++ b/test/libyul/objectCompiler/datasize_data.yul @@ -2,6 +2,8 @@ object "a" { code { sstore(0, datasize("data1")) } data "data1" "Hello, World!" } +// ==== +// EVMVersion: >=shanghai // ---- // Assembly: // /* "source":44:61 */ diff --git a/test/libyul/objectCompiler/datasize_self.yul b/test/libyul/objectCompiler/datasize_self.yul index 2a19d0a88f69..fb5b7fb89489 100644 --- a/test/libyul/objectCompiler/datasize_self.yul +++ b/test/libyul/objectCompiler/datasize_self.yul @@ -2,6 +2,8 @@ object "a" { code { sstore(0, datasize("a")) } data "data1" "Hello, World!" } +// ==== +// EVMVersion: >=shanghai // ---- // Assembly: // /* "source":36:49 */ diff --git a/test/libyul/objectCompiler/function_series.yul b/test/libyul/objectCompiler/function_series.yul index 7be2db96b923..8750f164991a 100644 --- a/test/libyul/objectCompiler/function_series.yul +++ b/test/libyul/objectCompiler/function_series.yul @@ -11,6 +11,7 @@ object "Contract" { } // ==== +// EVMVersion: >=shanghai // optimizationPreset: none // ---- // Assembly: diff --git a/test/libyul/objectCompiler/identical_subobjects_full_debug_info.yul b/test/libyul/objectCompiler/identical_subobjects_full_debug_info.yul index 74574be13c3f..88ec2c3542c7 100644 --- a/test/libyul/objectCompiler/identical_subobjects_full_debug_info.yul +++ b/test/libyul/objectCompiler/identical_subobjects_full_debug_info.yul @@ -64,6 +64,7 @@ object "A" { } } // ==== +// EVMVersion: >=shanghai // optimizationPreset: full // ---- // Assembly: diff --git a/test/libyul/objectCompiler/identical_subobjects_no_debug_info.yul b/test/libyul/objectCompiler/identical_subobjects_no_debug_info.yul index aa20ac6799b1..309d995469a9 100644 --- a/test/libyul/objectCompiler/identical_subobjects_no_debug_info.yul +++ b/test/libyul/objectCompiler/identical_subobjects_no_debug_info.yul @@ -50,6 +50,7 @@ object "A" { } } // ==== +// EVMVersion: >=shanghai // optimizationPreset: full // ---- // Assembly: diff --git a/test/libyul/objectCompiler/identical_subobjects_partial_debug_info.yul b/test/libyul/objectCompiler/identical_subobjects_partial_debug_info.yul index 9b63bdc1b12c..82c2fd766e2c 100644 --- a/test/libyul/objectCompiler/identical_subobjects_partial_debug_info.yul +++ b/test/libyul/objectCompiler/identical_subobjects_partial_debug_info.yul @@ -69,6 +69,7 @@ object "A" { } } // ==== +// EVMVersion: >=shanghai // optimizationPreset: full // ---- // Assembly: diff --git a/test/libyul/objectCompiler/identical_subobjects_partial_debug_info_no_use_src.yul b/test/libyul/objectCompiler/identical_subobjects_partial_debug_info_no_use_src.yul index d288503babbf..230535525007 100644 --- a/test/libyul/objectCompiler/identical_subobjects_partial_debug_info_no_use_src.yul +++ b/test/libyul/objectCompiler/identical_subobjects_partial_debug_info_no_use_src.yul @@ -56,6 +56,7 @@ object "A" { } } // ==== +// EVMVersion: >=shanghai // optimizationPreset: full // ---- // Assembly: diff --git a/test/libyul/objectCompiler/identical_subobjects_with_subject_references.yul b/test/libyul/objectCompiler/identical_subobjects_with_subject_references.yul index e14b010083cb..74f613cdfffa 100644 --- a/test/libyul/objectCompiler/identical_subobjects_with_subject_references.yul +++ b/test/libyul/objectCompiler/identical_subobjects_with_subject_references.yul @@ -95,6 +95,7 @@ object "A" { } } // ==== +// EVMVersion: >=shanghai // optimizationPreset: full // ---- // Assembly: diff --git a/test/libyul/objectCompiler/immutable_long_name_does_not_end_up_in_bytecode.yul b/test/libyul/objectCompiler/immutable_long_name_does_not_end_up_in_bytecode.yul index c6fd0ac80527..18d31087f9c5 100644 --- a/test/libyul/objectCompiler/immutable_long_name_does_not_end_up_in_bytecode.yul +++ b/test/libyul/objectCompiler/immutable_long_name_does_not_end_up_in_bytecode.yul @@ -7,6 +7,8 @@ object "a" { ) } } +// ==== +// EVMVersion: >=shanghai // ---- // Assembly: // /* "source":143:185 */ diff --git a/test/libyul/objectCompiler/leading_and_trailing_dots.yul b/test/libyul/objectCompiler/leading_and_trailing_dots.yul index 13c95235571e..9d32cadc0cd7 100644 --- a/test/libyul/objectCompiler/leading_and_trailing_dots.yul +++ b/test/libyul/objectCompiler/leading_and_trailing_dots.yul @@ -12,6 +12,8 @@ } g(2) } +// ==== +// EVMVersion: >=shanghai // ---- // Assembly: // /* "source":53:54 */ diff --git a/test/libyul/objectCompiler/linkersymbol.yul b/test/libyul/objectCompiler/linkersymbol.yul index 91a456461f00..ba0319108b27 100644 --- a/test/libyul/objectCompiler/linkersymbol.yul +++ b/test/libyul/objectCompiler/linkersymbol.yul @@ -5,6 +5,8 @@ object "a" { let success := call(gas(), addr, 0, 128, 4, 128, 0) } } +// ==== +// EVMVersion: >=shanghai // ---- // Assembly: // /* "source":190:191 */ diff --git a/test/libyul/objectCompiler/long_object_name.yul b/test/libyul/objectCompiler/long_object_name.yul index f75260224005..805beb42495d 100644 --- a/test/libyul/objectCompiler/long_object_name.yul +++ b/test/libyul/objectCompiler/long_object_name.yul @@ -7,6 +7,7 @@ object "t" { } } // ==== +// EVMVersion: >=shanghai // optimizationPreset: full // ---- // Assembly: diff --git a/test/libyul/objectCompiler/manySubObjects.yul b/test/libyul/objectCompiler/manySubObjects.yul index c046b182ff21..1a087f9c9430 100644 --- a/test/libyul/objectCompiler/manySubObjects.yul +++ b/test/libyul/objectCompiler/manySubObjects.yul @@ -134,6 +134,8 @@ object "root" { } } } +// ==== +// EVMVersion: >=shanghai // ---- // Assembly: // /* "source":59:75 */ diff --git a/test/libyul/objectCompiler/metadata.yul b/test/libyul/objectCompiler/metadata.yul index 4f8cda7a4c49..dbd802e3384d 100644 --- a/test/libyul/objectCompiler/metadata.yul +++ b/test/libyul/objectCompiler/metadata.yul @@ -19,6 +19,8 @@ object "A" { data ".metadata" "M2" data "x" "Hello, World2!" } +// ==== +// EVMVersion: >=shanghai // ---- // Assembly: // /* "source":55:68 */ diff --git a/test/libyul/objectCompiler/namedObjectCode.yul b/test/libyul/objectCompiler/namedObjectCode.yul index f18535d71189..efb41524b5cc 100644 --- a/test/libyul/objectCompiler/namedObjectCode.yul +++ b/test/libyul/objectCompiler/namedObjectCode.yul @@ -1,6 +1,8 @@ object "a" { code { sstore(0, 1) } } +// ==== +// EVMVersion: >=shanghai // ---- // Assembly: // /* "source":36:37 */ diff --git a/test/libyul/objectCompiler/nested_optimizer.yul b/test/libyul/objectCompiler/nested_optimizer.yul index ae06509429a5..0275e1665ae5 100644 --- a/test/libyul/objectCompiler/nested_optimizer.yul +++ b/test/libyul/objectCompiler/nested_optimizer.yul @@ -15,6 +15,7 @@ object "a" { } } // ==== +// EVMVersion: >=shanghai // optimizationPreset: full // ---- // Assembly: diff --git a/test/libyul/objectCompiler/simple.yul b/test/libyul/objectCompiler/simple.yul index fb2339cebb09..f7f945abf58a 100644 --- a/test/libyul/objectCompiler/simple.yul +++ b/test/libyul/objectCompiler/simple.yul @@ -1,6 +1,8 @@ { sstore(0, 1) } +// ==== +// EVMVersion: >=shanghai // ---- // Assembly: // /* "source":41:42 */ diff --git a/test/libyul/objectCompiler/simple_optimizer.yul b/test/libyul/objectCompiler/simple_optimizer.yul index cc630758957a..7348b2e20cd4 100644 --- a/test/libyul/objectCompiler/simple_optimizer.yul +++ b/test/libyul/objectCompiler/simple_optimizer.yul @@ -5,6 +5,7 @@ sstore(add(x, 0), z) } // ==== +// EVMVersion: >=shanghai // optimizationPreset: full // ---- // Assembly: diff --git a/test/libyul/objectCompiler/sourceLocations.yul b/test/libyul/objectCompiler/sourceLocations.yul index d9f1d84fcb4f..a1e55ade4ae1 100644 --- a/test/libyul/objectCompiler/sourceLocations.yul +++ b/test/libyul/objectCompiler/sourceLocations.yul @@ -28,6 +28,8 @@ object "a" { data "data1" "Hello, World!" } } +// ==== +// EVMVersion: >=shanghai // ---- // Assembly: // /* "abc.sol":0:2 */ diff --git a/test/libyul/objectCompiler/subObjectAccess.yul b/test/libyul/objectCompiler/subObjectAccess.yul index b18c902db60f..047eae408730 100644 --- a/test/libyul/objectCompiler/subObjectAccess.yul +++ b/test/libyul/objectCompiler/subObjectAccess.yul @@ -65,6 +65,8 @@ object "A" { } } } +// ==== +// EVMVersion: >=shanghai // ---- // Assembly: // /* "source":57:72 */ diff --git a/test/libyul/objectCompiler/verbatim_bug.yul b/test/libyul/objectCompiler/verbatim_bug.yul index 14a1c02b1f33..3858b5984dba 100644 --- a/test/libyul/objectCompiler/verbatim_bug.yul +++ b/test/libyul/objectCompiler/verbatim_bug.yul @@ -23,6 +23,7 @@ object "a" { } } // ==== +// EVMVersion: >=shanghai // optimizationPreset: full // ---- // Assembly: From 69942810512321501c50247b342193e079db53e6 Mon Sep 17 00:00:00 2001 From: Matheus Aguiar Date: Thu, 3 Oct 2024 12:23:19 -0300 Subject: [PATCH 0497/1022] enable euler ext test --- .circleci/config.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index ca1043685c1f..79a149a7ec63 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -760,9 +760,6 @@ defaults: name: t_native_compile_ext_euler project: euler binary_type: native - # NOTE: test suite disabled due to dependence on a specific version of Hardhat - # which does not support shanghai EVM. - compile_only: 1 resource_class: medium - job_native_test_ext_yield_liquidator: &job_native_test_ext_yield_liquidator From e0cf8db3374a4c26d48fc84ac3110b17f694bbf4 Mon Sep 17 00:00:00 2001 From: r0qs Date: Fri, 11 Oct 2024 17:04:09 +0200 Subject: [PATCH 0498/1022] Add tests for irAst and irOptimizedAst --- .../ast_ir_undeployable_contract/args | 1 + .../ast_ir_undeployable_contract/input.sol | 5 +++++ .../ast_ir_undeployable_contract/output | 8 ++++++++ .../in.sol | 5 +++++ .../input.json | 9 +++++++++ .../output.json | 19 +++++++++++++++++++ 6 files changed, 47 insertions(+) create mode 100644 test/cmdlineTests/ast_ir_undeployable_contract/args create mode 100644 test/cmdlineTests/ast_ir_undeployable_contract/input.sol create mode 100644 test/cmdlineTests/ast_ir_undeployable_contract/output create mode 100644 test/cmdlineTests/standard_ir_ast_undeployable_contract_requested/in.sol create mode 100644 test/cmdlineTests/standard_ir_ast_undeployable_contract_requested/input.json create mode 100644 test/cmdlineTests/standard_ir_ast_undeployable_contract_requested/output.json diff --git a/test/cmdlineTests/ast_ir_undeployable_contract/args b/test/cmdlineTests/ast_ir_undeployable_contract/args new file mode 100644 index 000000000000..d254bff83d54 --- /dev/null +++ b/test/cmdlineTests/ast_ir_undeployable_contract/args @@ -0,0 +1 @@ +--ir-ast-json --ir-optimized-ast-json --optimize --pretty-json --json-indent 4 diff --git a/test/cmdlineTests/ast_ir_undeployable_contract/input.sol b/test/cmdlineTests/ast_ir_undeployable_contract/input.sol new file mode 100644 index 000000000000..06496f4a26e7 --- /dev/null +++ b/test/cmdlineTests/ast_ir_undeployable_contract/input.sol @@ -0,0 +1,5 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity >=0.0; + +abstract contract C {} +interface I {} diff --git a/test/cmdlineTests/ast_ir_undeployable_contract/output b/test/cmdlineTests/ast_ir_undeployable_contract/output new file mode 100644 index 000000000000..b64e82bd0d14 --- /dev/null +++ b/test/cmdlineTests/ast_ir_undeployable_contract/output @@ -0,0 +1,8 @@ +IR AST: +null +Optimized IR AST: +null +IR AST: +null +Optimized IR AST: +null diff --git a/test/cmdlineTests/standard_ir_ast_undeployable_contract_requested/in.sol b/test/cmdlineTests/standard_ir_ast_undeployable_contract_requested/in.sol new file mode 100644 index 000000000000..80cc66cd19b7 --- /dev/null +++ b/test/cmdlineTests/standard_ir_ast_undeployable_contract_requested/in.sol @@ -0,0 +1,5 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity *; + +abstract contract C {} +interface I {} diff --git a/test/cmdlineTests/standard_ir_ast_undeployable_contract_requested/input.json b/test/cmdlineTests/standard_ir_ast_undeployable_contract_requested/input.json new file mode 100644 index 000000000000..0b40ad0723d6 --- /dev/null +++ b/test/cmdlineTests/standard_ir_ast_undeployable_contract_requested/input.json @@ -0,0 +1,9 @@ +{ + "language": "Solidity", + "sources": { + "C": {"urls": ["standard_ir_ast_undeployable_contract_requested/in.sol"]} + }, + "settings": { + "outputSelection": {"*": {"*": ["irAst", "irOptimizedAst"]}} + } +} diff --git a/test/cmdlineTests/standard_ir_ast_undeployable_contract_requested/output.json b/test/cmdlineTests/standard_ir_ast_undeployable_contract_requested/output.json new file mode 100644 index 000000000000..dab55ebd1045 --- /dev/null +++ b/test/cmdlineTests/standard_ir_ast_undeployable_contract_requested/output.json @@ -0,0 +1,19 @@ +{ + "contracts": { + "C": { + "C": { + "irAst": null, + "irOptimizedAst": null + }, + "I": { + "irAst": null, + "irOptimizedAst": null + } + } + }, + "sources": { + "C": { + "id": 0 + } + } +} From 1c0695f664bc123a2cdbf502304c16c9ea2b915f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nikola=20Mati=C4=87?= Date: Mon, 14 Oct 2024 10:44:11 +0200 Subject: [PATCH 0499/1022] Fix ObjectCompiler test (#15511) --- .../objectCompiler/identical_subobjects_creation_deployed.yul | 1 + 1 file changed, 1 insertion(+) diff --git a/test/libyul/objectCompiler/identical_subobjects_creation_deployed.yul b/test/libyul/objectCompiler/identical_subobjects_creation_deployed.yul index 5eb079db18d0..01270ef44316 100644 --- a/test/libyul/objectCompiler/identical_subobjects_creation_deployed.yul +++ b/test/libyul/objectCompiler/identical_subobjects_creation_deployed.yul @@ -64,6 +64,7 @@ object "A" { } } // ==== +// EVMVersion: >=constantinople // optimizationPreset: full // ---- // Assembly: From e0ac82d2994e1cb95ad0889d3f1256e3ad8af6ae Mon Sep 17 00:00:00 2001 From: Tran Quang Loc Date: Fri, 11 Oct 2024 22:55:38 +0700 Subject: [PATCH 0500/1022] Use boost's predefined bigint types --- libsolutil/Numeric.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libsolutil/Numeric.h b/libsolutil/Numeric.h index f4e88de3c17d..897952452412 100644 --- a/libsolutil/Numeric.h +++ b/libsolutil/Numeric.h @@ -45,9 +45,9 @@ namespace solidity { // Numeric types. -using bigint = boost::multiprecision::number>; -using u256 = boost::multiprecision::number>; -using s256 = boost::multiprecision::number>; +using bigint = boost::multiprecision::cpp_int; +using u256 = boost::multiprecision::uint256_t; +using s256 = boost::multiprecision::int256_t; /// Interprets @a _u as a two's complement signed number and returns the resulting s256. inline s256 u2s(u256 _u) From bef29f091ca6b9dd62cae29852bf85edad5941ec Mon Sep 17 00:00:00 2001 From: Tran Quang Loc Date: Fri, 11 Oct 2024 22:57:18 +0700 Subject: [PATCH 0501/1022] Move u512 to Numerics. Use boost:multiprecision::uint512_t. --- libsolutil/Numeric.h | 2 ++ test/tools/yulInterpreter/EVMInstructionInterpreter.cpp | 2 -- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libsolutil/Numeric.h b/libsolutil/Numeric.h index 897952452412..3ecc813c3da0 100644 --- a/libsolutil/Numeric.h +++ b/libsolutil/Numeric.h @@ -48,6 +48,8 @@ namespace solidity using bigint = boost::multiprecision::cpp_int; using u256 = boost::multiprecision::uint256_t; using s256 = boost::multiprecision::int256_t; +using u512 = boost::multiprecision::uint512_t; + /// Interprets @a _u as a two's complement signed number and returns the resulting s256. inline s256 u2s(u256 _u) diff --git a/test/tools/yulInterpreter/EVMInstructionInterpreter.cpp b/test/tools/yulInterpreter/EVMInstructionInterpreter.cpp index d2cbdb11b360..18a87f7bf59b 100644 --- a/test/tools/yulInterpreter/EVMInstructionInterpreter.cpp +++ b/test/tools/yulInterpreter/EVMInstructionInterpreter.cpp @@ -106,8 +106,6 @@ void copyZeroExtendedWithOverlap( } -using u512 = boost::multiprecision::number>; - u256 EVMInstructionInterpreter::eval( evmasm::Instruction _instruction, std::vector const& _arguments From 9cafc42f1e913856070302cb0e8a156dabda3ed5 Mon Sep 17 00:00:00 2001 From: rodiazet Date: Tue, 15 Oct 2024 13:09:45 +0200 Subject: [PATCH 0502/1022] eof: Support `DATALOADN` (EIP-7480) --- libevmasm/Assembly.cpp | 71 ++++++++++++++++--- libevmasm/Assembly.h | 4 ++ libevmasm/AssemblyItem.cpp | 38 +++++++--- libevmasm/AssemblyItem.h | 4 ++ libevmasm/Instruction.cpp | 2 + libevmasm/Instruction.h | 1 + liblangutil/EVMVersion.cpp | 3 + libyul/AsmAnalysis.cpp | 14 ++++ libyul/backends/evm/AbstractAssembly.h | 7 ++ libyul/backends/evm/EVMDialect.cpp | 24 ++++++- libyul/backends/evm/EthAssemblyAdapter.cpp | 5 ++ libyul/backends/evm/EthAssemblyAdapter.h | 2 + libyul/backends/evm/NoOutputAssembly.cpp | 5 ++ libyul/backends/evm/NoOutputAssembly.h | 2 + .../strict_asm_eof_dataloadn_prague/args | 1 + .../strict_asm_eof_dataloadn_prague/input.yul | 9 +++ .../strict_asm_eof_dataloadn_prague/output | 27 +++++++ test/libyul/objectCompiler/dataloadn.yul | 32 +++++++++ .../eof/auxdataloadn_in_eof.yul | 12 ++++ ...xdataloadn_in_eof_invalid_literal_type.yul | 14 ++++ .../eof/auxdataloadn_in_eof_invalid_value.yul | 14 ++++ .../eof/auxdataloadn_in_legacy.yul | 15 ++++ .../EVMInstructionInterpreter.cpp | 12 ++-- 23 files changed, 291 insertions(+), 27 deletions(-) create mode 100644 test/cmdlineTests/strict_asm_eof_dataloadn_prague/args create mode 100644 test/cmdlineTests/strict_asm_eof_dataloadn_prague/input.yul create mode 100644 test/cmdlineTests/strict_asm_eof_dataloadn_prague/output create mode 100644 test/libyul/objectCompiler/dataloadn.yul create mode 100644 test/libyul/yulSyntaxTests/eof/auxdataloadn_in_eof.yul create mode 100644 test/libyul/yulSyntaxTests/eof/auxdataloadn_in_eof_invalid_literal_type.yul create mode 100644 test/libyul/yulSyntaxTests/eof/auxdataloadn_in_eof_invalid_value.yul create mode 100644 test/libyul/yulSyntaxTests/eof/auxdataloadn_in_legacy.yul diff --git a/libevmasm/Assembly.cpp b/libevmasm/Assembly.cpp index ab26526e14c2..8f645f6fddcb 100644 --- a/libevmasm/Assembly.cpp +++ b/libevmasm/Assembly.cpp @@ -717,6 +717,11 @@ AssemblyItem Assembly::newImmutableAssignment(std::string const& _identifier) return AssemblyItem{AssignImmutable, h}; } +AssemblyItem Assembly::newAuxDataLoadN(size_t _offset) +{ + return AssemblyItem{AuxDataLoadN, _offset}; +} + Assembly& Assembly::optimise(OptimiserSettings const& _settings) { optimiseInternal(_settings, {}); @@ -922,8 +927,8 @@ void appendBigEndianUint16(bytes& _dest, ValueT _value) std::tuple, size_t> Assembly::createEOFHeader(std::set const& _referencedSubIds) const { bytes retBytecode; - std::vector codeSectionSizeOffsets; - size_t dataSectionSizeOffset; + std::vector codeSectionSizePositions; + size_t dataSectionSizePosition; retBytecode.push_back(0xef); retBytecode.push_back(0x00); @@ -938,7 +943,7 @@ std::tuple, size_t> Assembly::createEOFHeader(std::se for (auto const& codeSection: m_codeSections) { (void) codeSection; - codeSectionSizeOffsets.emplace_back(retBytecode.size()); + codeSectionSizePositions.emplace_back(retBytecode.size()); appendBigEndianUint16(retBytecode, 0u); // placeholder for length of code } @@ -952,7 +957,7 @@ std::tuple, size_t> Assembly::createEOFHeader(std::se } retBytecode.push_back(0x04); // kind=data - dataSectionSizeOffset = retBytecode.size(); + dataSectionSizePosition = retBytecode.size(); appendBigEndianUint16(retBytecode, 0u); // length of data retBytecode.push_back(0x00); // terminator @@ -965,7 +970,7 @@ std::tuple, size_t> Assembly::createEOFHeader(std::se appendBigEndianUint16(retBytecode, 0xFFFFu); } - return {retBytecode, codeSectionSizeOffsets, dataSectionSizeOffset}; + return {retBytecode, codeSectionSizePositions, dataSectionSizePosition}; } LinkerObject const& Assembly::assemble() const @@ -1348,6 +1353,23 @@ std::map Assembly::findReferencedContainers() const return replacements; } +std::optional Assembly::findMaxAuxDataLoadNOffset() const +{ + std::optional maxOffset = std::nullopt; + for (auto&& codeSection: m_codeSections) + for (AssemblyItem const& item: codeSection.items) + if (item.type() == AuxDataLoadN) + { + solAssert(item.data() <= std::numeric_limits::max(), "Invalid auxdataloadn index value."); + auto const offset = static_cast(item.data()); + if (!maxOffset.has_value() || offset > maxOffset.value()) + maxOffset = offset; + + } + + return maxOffset; +} + LinkerObject const& Assembly::assembleEOF() const { solAssert(m_eofVersion.has_value() && m_eofVersion == 1); @@ -1362,11 +1384,14 @@ LinkerObject const& Assembly::assembleEOF() const "Expected the first code section to have zero inputs and be non-returning." ); + auto const maxAuxDataLoadNOffset = findMaxAuxDataLoadNOffset(); + // Insert EOF1 header. - auto [headerBytecode, codeSectionSizeOffsets, dataSectionSizeOffset] = createEOFHeader(referencedSubIds); + auto [headerBytecode, codeSectionSizePositions, dataSectionSizePosition] = createEOFHeader(referencedSubIds); ret.bytecode = headerBytecode; m_tagPositionsInBytecode = std::vector(m_usedTags, std::numeric_limits::max()); + std::map dataSectionRef; for (auto&& [codeSectionIndex, codeSection]: m_codeSections | ranges::views::enumerate) { @@ -1380,6 +1405,8 @@ LinkerObject const& Assembly::assembleEOF() const switch (item.type()) { case Operation: + solAssert(item.instruction() != Instruction::DATALOADN); + solAssert(!(item.instruction() >= Instruction::PUSH0 && item.instruction() <= Instruction::PUSH32)); ret.bytecode += assembleOperation(item); break; case Push: @@ -1401,12 +1428,21 @@ LinkerObject const& Assembly::assembleEOF() const case Tag: ret.bytecode += assembleTag(item, ret.bytecode.size(), false); break; + case AuxDataLoadN: + { + // In findMaxAuxDataLoadNOffset we already verified that unsigned data value fits 2 bytes + solAssert(item.data() <= std::numeric_limits::max(), "Invalid auxdataloadn position."); + ret.bytecode.push_back(uint8_t(Instruction::DATALOADN)); + dataSectionRef[ret.bytecode.size()] = static_cast(item.data()); + appendBigEndianUint16(ret.bytecode, item.data()); + break; + } default: solThrow(InvalidOpcode, "Unexpected opcode while assembling."); } } - setBigEndianUint16(ret.bytecode, codeSectionSizeOffsets[codeSectionIndex], ret.bytecode.size() - sectionStart); + setBigEndianUint16(ret.bytecode, codeSectionSizePositions[codeSectionIndex], ret.bytecode.size() - sectionStart); } for (auto i: referencedSubIds) @@ -1422,8 +1458,25 @@ LinkerObject const& Assembly::assembleEOF() const ret.bytecode += m_auxiliaryData; - auto dataLength = ret.bytecode.size() - dataStart; - setBigEndianUint16(ret.bytecode, dataSectionSizeOffset, dataLength); + auto const preDeployDataSectionSize = ret.bytecode.size() - dataStart; + // DATALOADN loads 32 bytes from EOF data section zero padded if reading out of data bounds. + // In our case we do not allow DATALOADN with offsets which reads out of data bounds. + auto const staticAuxDataSize = maxAuxDataLoadNOffset.has_value() ? (*maxAuxDataLoadNOffset + 32u) : 0u; + solRequire(preDeployDataSectionSize + staticAuxDataSize < std::numeric_limits::max(), AssemblyException, + "Invalid DATALOADN offset."); + + // If some data was already added to data section we need to update data section refs accordingly + if (preDeployDataSectionSize > 0) + for (auto [refPosition, staticAuxDataOffset] : dataSectionRef) + { + // staticAuxDataOffset + preDeployDataSectionSize value is already verified to fit 2 bytes because + // staticAuxDataOffset < staticAuxDataSize + setBigEndianUint16(ret.bytecode, refPosition, staticAuxDataOffset + preDeployDataSectionSize); + } + + auto const preDeployAndStaticAuxDataSize = preDeployDataSectionSize + staticAuxDataSize; + + setBigEndianUint16(ret.bytecode, dataSectionSizePosition, preDeployAndStaticAuxDataSize); return ret; } diff --git a/libevmasm/Assembly.h b/libevmasm/Assembly.h index de1ac20f2015..9b15936d642f 100644 --- a/libevmasm/Assembly.h +++ b/libevmasm/Assembly.h @@ -79,6 +79,7 @@ class Assembly AssemblyItem newPushLibraryAddress(std::string const& _identifier); AssemblyItem newPushImmutable(std::string const& _identifier); AssemblyItem newImmutableAssignment(std::string const& _identifier); + AssemblyItem newAuxDataLoadN(size_t offset); AssemblyItem const& append(AssemblyItem _i); AssemblyItem const& append(bytes const& _data) { return append(newData(_data)); } @@ -91,6 +92,7 @@ class Assembly void appendLibraryAddress(std::string const& _identifier) { append(newPushLibraryAddress(_identifier)); } void appendImmutable(std::string const& _identifier) { append(newPushImmutable(_identifier)); } void appendImmutableAssignment(std::string const& _identifier) { append(newImmutableAssignment(_identifier)); } + void appendAuxDataLoadN(uint16_t _offset) { append(newAuxDataLoadN(_offset));} void appendVerbatim(bytes _data, size_t _arguments, size_t _returnVariables) { @@ -240,6 +242,8 @@ class Assembly /// Returns map from m_subs to an index of subcontainer in the final EOF bytecode std::map findReferencedContainers() const; + /// Returns max AuxDataLoadN offset for the assembly. + std::optional findMaxAuxDataLoadNOffset() const; /// Assemble bytecode for AssemblyItem type. [[nodiscard]] bytes assembleOperation(AssemblyItem const& _item) const; diff --git a/libevmasm/AssemblyItem.cpp b/libevmasm/AssemblyItem.cpp index 1bc805780145..202bb2256463 100644 --- a/libevmasm/AssemblyItem.cpp +++ b/libevmasm/AssemblyItem.cpp @@ -102,9 +102,13 @@ std::pair AssemblyItem::nameAndData(langutil::EVMVersi return {"PUSH data", toStringInHex(data())}; case VerbatimBytecode: return {"VERBATIM", util::toHex(verbatimData())}; - default: - assertThrow(false, InvalidOpcode, ""); + case AuxDataLoadN: + return {"AUXDATALOADN", util::toString(data())}; + case UndefinedItem: + solAssert(false); } + + util::unreachable(); } void AssemblyItem::setPushTagSubIdAndTag(size_t _subId, size_t _tag) @@ -161,10 +165,13 @@ size_t AssemblyItem::bytesRequired(size_t _addressLength, langutil::EVMVersion _ } case VerbatimBytecode: return std::get<2>(*m_verbatimBytecode).size(); - default: - break; + case AuxDataLoadN: + return 1 + 2; + case UndefinedItem: + solAssert(false); } - assertThrow(false, InvalidOpcode, ""); + + util::unreachable(); } size_t AssemblyItem::arguments() const @@ -203,7 +210,10 @@ size_t AssemblyItem::returnValues() const return 0; case VerbatimBytecode: return std::get<1>(*m_verbatimBytecode); - default: + case AuxDataLoadN: + return 1; + case AssignImmutable: + case UndefinedItem: break; } return 0; @@ -226,10 +236,13 @@ bool AssemblyItem::canBeFunctional() const case PushLibraryAddress: case PushDeployTimeAddress: case PushImmutable: + case AuxDataLoadN: return true; case Tag: return false; - default: + case AssignImmutable: + case VerbatimBytecode: + case UndefinedItem: break; } return false; @@ -327,8 +340,10 @@ std::string AssemblyItem::toAssemblyText(Assembly const& _assembly) const case VerbatimBytecode: text = std::string("verbatimbytecode_") + util::toHex(std::get<2>(*m_verbatimBytecode)); break; - default: - assertThrow(false, InvalidOpcode, ""); + case AuxDataLoadN: + assertThrow(data() <= std::numeric_limits::max(), AssemblyException, "Invalid auxdataloadn argument."); + text = "auxdataloadn(" + std::to_string(static_cast(data())) + ")"; + break; } if (m_jumpType == JumpType::IntoFunction || m_jumpType == JumpType::OutOfFunction) { @@ -396,11 +411,12 @@ std::ostream& solidity::evmasm::operator<<(std::ostream& _out, AssemblyItem cons case VerbatimBytecode: _out << " Verbatim " << util::toHex(_item.verbatimData()); break; + case AuxDataLoadN: + _out << " AuxDataLoadN " << util::toString(_item.data()); + break; case UndefinedItem: _out << " ???"; break; - default: - assertThrow(false, InvalidOpcode, ""); } return _out; } diff --git a/libevmasm/AssemblyItem.h b/libevmasm/AssemblyItem.h index f06c72bac2ff..226a126c368c 100644 --- a/libevmasm/AssemblyItem.h +++ b/libevmasm/AssemblyItem.h @@ -51,6 +51,10 @@ enum AssemblyItemType PushDeployTimeAddress, ///< Push an address to be filled at deploy time. Should not be touched by the optimizer. PushImmutable, ///< Push the currently unknown value of an immutable variable. The actual value will be filled in by the constructor. AssignImmutable, ///< Assigns the current value on the stack to an immutable variable. Only valid during creation code. + + /// Loads 32 bytes from static auxiliary data of EOF data section. The offset does *not* have to be always from the beginning + /// of the data EOF section. More details here: https://github.com/ipsilon/eof/blob/main/spec/eof.md#data-section-lifecycle + AuxDataLoadN, VerbatimBytecode ///< Contains data that is inserted into the bytecode code section without modification. }; diff --git a/libevmasm/Instruction.cpp b/libevmasm/Instruction.cpp index 943f34ee4c1f..b9bb21227c29 100644 --- a/libevmasm/Instruction.cpp +++ b/libevmasm/Instruction.cpp @@ -168,6 +168,7 @@ std::map const solidity::evmasm::c_instructions = { "LOG2", Instruction::LOG2 }, { "LOG3", Instruction::LOG3 }, { "LOG4", Instruction::LOG4 }, + { "DATALOADN", Instruction::DATALOADN }, { "CREATE", Instruction::CREATE }, { "CALL", Instruction::CALL }, { "CALLCODE", Instruction::CALLCODE }, @@ -252,6 +253,7 @@ static std::map const c_instructionInfo = {Instruction::MSIZE, {"MSIZE", 0, 0, 1, false, Tier::Base}}, {Instruction::GAS, {"GAS", 0, 0, 1, false, Tier::Base}}, {Instruction::JUMPDEST, {"JUMPDEST", 0, 0, 0, true, Tier::Special}}, + {Instruction::DATALOADN, {"DATALOADN", 2, 0, 1, true, Tier::Low}}, {Instruction::PUSH0, {"PUSH0", 0, 0, 1, false, Tier::Base}}, {Instruction::PUSH1, {"PUSH1", 1, 0, 1, false, Tier::VeryLow}}, {Instruction::PUSH2, {"PUSH2", 2, 0, 1, false, Tier::VeryLow}}, diff --git a/libevmasm/Instruction.h b/libevmasm/Instruction.h index a3629eec2db8..2ed773cc9e7b 100644 --- a/libevmasm/Instruction.h +++ b/libevmasm/Instruction.h @@ -182,6 +182,7 @@ enum class Instruction: uint8_t LOG3, ///< Makes a log entry; 3 topics. LOG4, ///< Makes a log entry; 4 topics. + DATALOADN = 0xd1, ///< load data from EOF data section CREATE = 0xf0, ///< create a new account with associated code CALL, ///< message-call into an account CALLCODE, ///< message-call with another account's code only diff --git a/liblangutil/EVMVersion.cpp b/liblangutil/EVMVersion.cpp index 6435e0f15455..bdd663c411ac 100644 --- a/liblangutil/EVMVersion.cpp +++ b/liblangutil/EVMVersion.cpp @@ -76,6 +76,9 @@ bool EVMVersion::hasOpcode(Instruction _opcode, std::optional _eofVersi case Instruction::EXTCODECOPY: case Instruction::GAS: return !_eofVersion.has_value(); + // Instructions below available only in EOF + case Instruction::DATALOADN: + return _eofVersion.has_value(); default: return true; } diff --git a/libyul/AsmAnalysis.cpp b/libyul/AsmAnalysis.cpp index 682931dc414d..9eb5465475cb 100644 --- a/libyul/AsmAnalysis.cpp +++ b/libyul/AsmAnalysis.cpp @@ -428,6 +428,20 @@ size_t AsmAnalyzer::operator()(FunctionCall const& _funCall) expectUnlimitedStringLiteral(std::get(arg)); continue; } + else if (*literalArgumentKind == LiteralKind::Number) + { + std::string functionName = _funCall.functionName.name.str(); + if (functionName == "auxdataloadn") + { + auto const& argumentAsLiteral = std::get(arg); + if (argumentAsLiteral.value.value() > std::numeric_limits::max()) + m_errorReporter.typeError( + 5202_error, + nativeLocationOf(arg), + "Invalid auxdataloadn argument value. Offset must be in range 0...0xFFFF" + ); + } + } } expectExpression(arg); } diff --git a/libyul/backends/evm/AbstractAssembly.h b/libyul/backends/evm/AbstractAssembly.h index fe45008962c8..ed06bebac90b 100644 --- a/libyul/backends/evm/AbstractAssembly.h +++ b/libyul/backends/evm/AbstractAssembly.h @@ -112,7 +112,14 @@ class AbstractAssembly /// Appends an assignment to an immutable variable. virtual void appendImmutableAssignment(std::string const& _identifier) = 0; + /// Appends an operation that loads 32 bytes of data from a known offset relative to the start of the static_aux_data area of the EOF data section. + /// Note that static_aux_data is only a part or the data section. + /// It is preceded by the pre_deploy_data, whose size is not determined before the bytecode is assembled, and which cannot be accessed using this function. + /// The function is meant to allow indexing into static_aux_data in a way that's independent of the size of pre_deploy_data. + virtual void appendAuxDataLoadN(uint16_t _offset) = 0; + /// Appends data to the very end of the bytecode. Repeated calls concatenate. + /// EOF auxiliary data in data section and the auxiliary data are different things. virtual void appendToAuxiliaryData(bytes const& _data) = 0; /// Mark this assembly as invalid. Any attempt to request bytecode from it should throw. diff --git a/libyul/backends/evm/EVMDialect.cpp b/libyul/backends/evm/EVMDialect.cpp index 6bfdc9cb9de3..9e9d5e542ca6 100644 --- a/libyul/backends/evm/EVMDialect.cpp +++ b/libyul/backends/evm/EVMDialect.cpp @@ -199,6 +199,7 @@ std::map createBuiltins(langutil::EVMVersion _ev opcode != evmasm::Instruction::JUMP && opcode != evmasm::Instruction::JUMPI && opcode != evmasm::Instruction::JUMPDEST && + opcode != evmasm::Instruction::DATALOADN && _evmVersion.hasOpcode(opcode, _eofVersion) && !prevRandaoException(name) ) @@ -235,7 +236,7 @@ std::map createBuiltins(langutil::EVMVersion _ev }) ); - if (!_eofVersion.has_value()) + if (!_eofVersion.has_value()) // non-EOF context { builtins.emplace(createFunction("datasize", 1, 1, SideEffects{}, {LiteralKind::String}, []( FunctionCall const& _call, @@ -345,6 +346,27 @@ std::map createBuiltins(langutil::EVMVersion _ev } )); } + else // EOF context + { + builtins.emplace(createFunction( + "auxdataloadn", + 1, + 1, + SideEffects{}, + {LiteralKind::Number}, + []( + FunctionCall const& _call, + AbstractAssembly& _assembly, + BuiltinContext& + ) { + yulAssert(_call.arguments.size() == 1, ""); + Literal const* literal = std::get_if(&_call.arguments.front()); + yulAssert(literal, ""); + yulAssert(literal->value.value() <= std::numeric_limits::max(), ""); + _assembly.appendAuxDataLoadN(static_cast(literal->value.value())); + } + )); + } } return builtins; } diff --git a/libyul/backends/evm/EthAssemblyAdapter.cpp b/libyul/backends/evm/EthAssemblyAdapter.cpp index e3a2e01e1b1f..36a437c8cecf 100644 --- a/libyul/backends/evm/EthAssemblyAdapter.cpp +++ b/libyul/backends/evm/EthAssemblyAdapter.cpp @@ -175,6 +175,11 @@ void EthAssemblyAdapter::appendImmutableAssignment(std::string const& _identifie m_assembly.appendImmutableAssignment(_identifier); } +void EthAssemblyAdapter::appendAuxDataLoadN(uint16_t _offset) +{ + m_assembly.appendAuxDataLoadN(_offset); +} + void EthAssemblyAdapter::markAsInvalid() { m_assembly.markAsInvalid(); diff --git a/libyul/backends/evm/EthAssemblyAdapter.h b/libyul/backends/evm/EthAssemblyAdapter.h index 011081dedaac..7dc89e38e0e9 100644 --- a/libyul/backends/evm/EthAssemblyAdapter.h +++ b/libyul/backends/evm/EthAssemblyAdapter.h @@ -65,6 +65,8 @@ class EthAssemblyAdapter: public AbstractAssembly void appendImmutable(std::string const& _identifier) override; void appendImmutableAssignment(std::string const& _identifier) override; + void appendAuxDataLoadN(uint16_t _offset) override; + void markAsInvalid() override; langutil::EVMVersion evmVersion() const override; diff --git a/libyul/backends/evm/NoOutputAssembly.cpp b/libyul/backends/evm/NoOutputAssembly.cpp index c444a71435c0..9d8bd73a3465 100644 --- a/libyul/backends/evm/NoOutputAssembly.cpp +++ b/libyul/backends/evm/NoOutputAssembly.cpp @@ -129,6 +129,11 @@ void NoOutputAssembly::appendImmutableAssignment(std::string const&) yulAssert(false, "setimmutable not implemented."); } +void NoOutputAssembly::appendAuxDataLoadN(uint16_t) +{ + yulAssert(false, "auxdataloadn not implemented."); +} + NoOutputEVMDialect::NoOutputEVMDialect(EVMDialect const& _copyFrom): EVMDialect(_copyFrom.evmVersion(), _copyFrom.eofVersion(), _copyFrom.providesObjectAccess()) { diff --git a/libyul/backends/evm/NoOutputAssembly.h b/libyul/backends/evm/NoOutputAssembly.h index 8d7dda0bb50c..6d3aacb248a0 100644 --- a/libyul/backends/evm/NoOutputAssembly.h +++ b/libyul/backends/evm/NoOutputAssembly.h @@ -75,6 +75,8 @@ class NoOutputAssembly: public AbstractAssembly void appendImmutable(std::string const& _identifier) override; void appendImmutableAssignment(std::string const& _identifier) override; + void appendAuxDataLoadN(uint16_t) override; + void markAsInvalid() override {} langutil::EVMVersion evmVersion() const override { return m_evmVersion; } diff --git a/test/cmdlineTests/strict_asm_eof_dataloadn_prague/args b/test/cmdlineTests/strict_asm_eof_dataloadn_prague/args new file mode 100644 index 000000000000..0078e6e68e36 --- /dev/null +++ b/test/cmdlineTests/strict_asm_eof_dataloadn_prague/args @@ -0,0 +1 @@ + --strict-assembly --experimental-eof-version 1 --evm-version prague --asm --ir-optimized --bin --debug-info none diff --git a/test/cmdlineTests/strict_asm_eof_dataloadn_prague/input.yul b/test/cmdlineTests/strict_asm_eof_dataloadn_prague/input.yul new file mode 100644 index 000000000000..bd29cf65979c --- /dev/null +++ b/test/cmdlineTests/strict_asm_eof_dataloadn_prague/input.yul @@ -0,0 +1,9 @@ +object "a" { + code { + mstore(0, auxdataloadn(0)) + return(0, 32) + } + + data "data1" "Hello, World!" +} + diff --git a/test/cmdlineTests/strict_asm_eof_dataloadn_prague/output b/test/cmdlineTests/strict_asm_eof_dataloadn_prague/output new file mode 100644 index 000000000000..5f768feebd32 --- /dev/null +++ b/test/cmdlineTests/strict_asm_eof_dataloadn_prague/output @@ -0,0 +1,27 @@ + +======= strict_asm_eof_dataloadn_prague/input.yul (EVM) ======= + +Pretty printed source: +object "a" { + code { + { + mstore(0, auxdataloadn(0)) + return(0, 32) + } + } + data "data1" hex"48656c6c6f2c20576f726c6421" +} + + +Binary representation: +ef0001010004020001000904002d000080ffffd1000d5f5260205ff348656c6c6f2c20576f726c6421 + +Text representation: + auxdataloadn(0) + 0x00 + mstore + 0x20 + 0x00 + return +stop +data_acaf3289d7b601cbd114fb36c4d29c85bbfd5e133f14cb355c3fd8d99367964f 48656c6c6f2c20576f726c6421 diff --git a/test/libyul/objectCompiler/dataloadn.yul b/test/libyul/objectCompiler/dataloadn.yul new file mode 100644 index 000000000000..8b1c7ab8015c --- /dev/null +++ b/test/libyul/objectCompiler/dataloadn.yul @@ -0,0 +1,32 @@ +object "a" { + code { + { + mstore(0, auxdataloadn(0)) + return(0, 32) + } + } + data "data1" hex"48656c6c6f2c20576f726c6421" +} + +// ==== +// bytecodeFormat: >=EOFv1 +// EVMVersion: >=prague +// ---- +// Assembly: +// /* "source":56:71 */ +// auxdataloadn(0) +// /* "source":53:54 */ +// 0x00 +// /* "source":46:72 */ +// mstore +// /* "source":95:97 */ +// 0x20 +// /* "source":92:93 */ +// 0x00 +// /* "source":85:98 */ +// return +// stop +// data_acaf3289d7b601cbd114fb36c4d29c85bbfd5e133f14cb355c3fd8d99367964f 48656c6c6f2c20576f726c6421 +// Bytecode: ef0001010004020001000904002d000080ffffd1000d5f5260205ff348656c6c6f2c20576f726c6421 +// Opcodes: 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP MULMOD DIV STOP 0x2D STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT DATALOADN 0xD PUSH0 MSTORE PUSH1 0x20 PUSH0 RETURN BASEFEE PUSH6 0x6C6C6F2C2057 PUSH16 0x726C6421000000000000000000000000 +// SourceMappings: 56:15:0:-:0;53:1;46:26;95:2;92:1;85:13 \ No newline at end of file diff --git a/test/libyul/yulSyntaxTests/eof/auxdataloadn_in_eof.yul b/test/libyul/yulSyntaxTests/eof/auxdataloadn_in_eof.yul new file mode 100644 index 000000000000..552620a72a0e --- /dev/null +++ b/test/libyul/yulSyntaxTests/eof/auxdataloadn_in_eof.yul @@ -0,0 +1,12 @@ +object "a" { + code { + mstore(0, auxdataloadn(0)) + return(0, 32) + } + + data "data1" "Hello, World!" +} + +// ==== +// EVMVersion: >=shanghai +// bytecodeFormat: >=EOFv1 \ No newline at end of file diff --git a/test/libyul/yulSyntaxTests/eof/auxdataloadn_in_eof_invalid_literal_type.yul b/test/libyul/yulSyntaxTests/eof/auxdataloadn_in_eof_invalid_literal_type.yul new file mode 100644 index 000000000000..08de0df183af --- /dev/null +++ b/test/libyul/yulSyntaxTests/eof/auxdataloadn_in_eof_invalid_literal_type.yul @@ -0,0 +1,14 @@ +object "a" { + code { + mstore(0, auxdataloadn("0")) + return(0, 32) + } + + data "data1" "Hello, World!" + } + +// ==== +// EVMVersion: >=prague +// bytecodeFormat: >=EOFv1 +// ---- +// TypeError 5859: (55-58): Function expects number literal. \ No newline at end of file diff --git a/test/libyul/yulSyntaxTests/eof/auxdataloadn_in_eof_invalid_value.yul b/test/libyul/yulSyntaxTests/eof/auxdataloadn_in_eof_invalid_value.yul new file mode 100644 index 000000000000..08e8037842ed --- /dev/null +++ b/test/libyul/yulSyntaxTests/eof/auxdataloadn_in_eof_invalid_value.yul @@ -0,0 +1,14 @@ +object "a" { + code { + mstore(0, auxdataloadn(0x01FFFF)) + return(0, 32) + } + + data "data1" "Hello, World!" +} + +// ==== +// EVMVersion: >=shanghai +// bytecodeFormat: >=EOFv1 +// ---- +// TypeError 5202: (55-63): Invalid auxdataloadn argument value. Offset must be in range 0...0xFFFF diff --git a/test/libyul/yulSyntaxTests/eof/auxdataloadn_in_legacy.yul b/test/libyul/yulSyntaxTests/eof/auxdataloadn_in_legacy.yul new file mode 100644 index 000000000000..0fe3221f1a52 --- /dev/null +++ b/test/libyul/yulSyntaxTests/eof/auxdataloadn_in_legacy.yul @@ -0,0 +1,15 @@ +object "a" { + code { + mstore(0, auxdataloadn(0)) + return(0, 32) + } + + data "data1" "Hello, World!" +} + +// ==== +// EVMVersion: >=prague +// bytecodeFormat: legacy +// ---- +// DeclarationError 4619: (42-54): Function "auxdataloadn" not found. +// TypeError 3950: (42-57): Expected expression to evaluate to one value, but got 0 values instead. \ No newline at end of file diff --git a/test/tools/yulInterpreter/EVMInstructionInterpreter.cpp b/test/tools/yulInterpreter/EVMInstructionInterpreter.cpp index d2cbdb11b360..768734458bec 100644 --- a/test/tools/yulInterpreter/EVMInstructionInterpreter.cpp +++ b/test/tools/yulInterpreter/EVMInstructionInterpreter.cpp @@ -30,6 +30,7 @@ #include #include +#include #include #include #include @@ -417,7 +418,7 @@ u256 EVMInstructionInterpreter::eval( m_state.trace.clear(); BOOST_THROW_EXCEPTION(ExplicitlyTerminated()); case Instruction::POP: - break; + return 0; // --------------- invalid in strict assembly --------------- case Instruction::JUMP: case Instruction::JUMPI: @@ -487,13 +488,12 @@ u256 EVMInstructionInterpreter::eval( case Instruction::SWAP14: case Instruction::SWAP15: case Instruction::SWAP16: - { - yulAssert(false, ""); - return 0; - } + yulAssert(false, "Impossible in strict assembly."); + case Instruction::DATALOADN: + solUnimplemented("DATALOADN unimplemented in yul interpreter."); } - return 0; + util::unreachable(); } u256 EVMInstructionInterpreter::evalBuiltin( From 77811b06f0505de6551fc85ec8a0603e3f034a7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Mon, 14 Oct 2024 13:44:53 +0200 Subject: [PATCH 0503/1022] UnusedPruner: Remove dead code --- libyul/optimiser/UnusedPruner.cpp | 38 +++++-------------------------- libyul/optimiser/UnusedPruner.h | 27 ---------------------- 2 files changed, 6 insertions(+), 59 deletions(-) diff --git a/libyul/optimiser/UnusedPruner.cpp b/libyul/optimiser/UnusedPruner.cpp index a3b6c0708b6a..75cdd2dd1796 100644 --- a/libyul/optimiser/UnusedPruner.cpp +++ b/libyul/optimiser/UnusedPruner.cpp @@ -55,20 +55,6 @@ UnusedPruner::UnusedPruner( ++m_references[f]; } -UnusedPruner::UnusedPruner( - Dialect const& _dialect, - FunctionDefinition& _function, - bool _allowMSizeOptimization, - std::set const& _externallyUsedFunctions -): - m_dialect(_dialect), - m_allowMSizeOptimization(_allowMSizeOptimization) -{ - m_references = ReferencesCounter::countReferences(_function); - for (auto const& f: _externallyUsedFunctions) - ++m_references[f]; -} - void UnusedPruner::operator()(Block& _block) { for (auto&& statement: _block.statements) @@ -142,8 +128,12 @@ void UnusedPruner::runUntilStabilised( while (true) { UnusedPruner pruner( - _dialect, _ast, _allowMSizeOptimization, _functionSideEffects, - _externallyUsedFunctions); + _dialect, + _ast, + _allowMSizeOptimization, + _functionSideEffects, + _externallyUsedFunctions + ); pruner(_ast); if (!pruner.shouldRunAgain()) return; @@ -162,22 +152,6 @@ void UnusedPruner::runUntilStabilisedOnFullAST( runUntilStabilised(_dialect, _ast, allowMSizeOptimization, &functionSideEffects, _externallyUsedFunctions); } -void UnusedPruner::runUntilStabilised( - Dialect const& _dialect, - FunctionDefinition& _function, - bool _allowMSizeOptimization, - std::set const& _externallyUsedFunctions -) -{ - while (true) - { - UnusedPruner pruner(_dialect, _function, _allowMSizeOptimization, _externallyUsedFunctions); - pruner(_function); - if (!pruner.shouldRunAgain()) - return; - } -} - bool UnusedPruner::used(YulName _name) const { return m_references.count(_name) && m_references.at(_name) > 0; diff --git a/libyul/optimiser/UnusedPruner.h b/libyul/optimiser/UnusedPruner.h index b0ba53bce95c..040e7ce43b39 100644 --- a/libyul/optimiser/UnusedPruner.h +++ b/libyul/optimiser/UnusedPruner.h @@ -68,15 +68,6 @@ class UnusedPruner: public ASTModifier std::set const& _externallyUsedFunctions = {} ); - static void run( - Dialect const& _dialect, - Block& _ast, - std::set const& _externallyUsedFunctions = {} - ) - { - runUntilStabilisedOnFullAST(_dialect, _ast, _externallyUsedFunctions); - } - /// Run the pruner until the code does not change anymore. /// The provided block has to be a full AST. /// The pruner itself determines if msize is used and which user-defined functions @@ -87,18 +78,6 @@ class UnusedPruner: public ASTModifier std::set const& _externallyUsedFunctions = {} ); - // Run the pruner until the code does not change anymore. - // Only run on the given function. - // @param _allowMSizeOptimization if true, allows to remove instructions - // whose only side-effect is a potential change of the return value of - // the msize instruction. - static void runUntilStabilised( - Dialect const& _dialect, - FunctionDefinition& _functionDefinition, - bool _allowMSizeOptimization, - std::set const& _externallyUsedFunctions = {} - ); - private: UnusedPruner( Dialect const& _dialect, @@ -107,12 +86,6 @@ class UnusedPruner: public ASTModifier std::map const* _functionSideEffects = nullptr, std::set const& _externallyUsedFunctions = {} ); - UnusedPruner( - Dialect const& _dialect, - FunctionDefinition& _function, - bool _allowMSizeOptimization, - std::set const& _externallyUsedFunctions = {} - ); bool used(YulName _name) const; void subtractReferences(std::map const& _subtrahend); From 125d25a21955160ce7c9a0c1a1a94c56a19a0027 Mon Sep 17 00:00:00 2001 From: r0qs Date: Tue, 15 Oct 2024 16:23:29 +0200 Subject: [PATCH 0504/1022] Restrict object compiler tests to exclude deprecated EVM versions (#15516) --- test/libyul/objectCompiler/data.yul | 2 ++ test/libyul/objectCompiler/namedObject.yul | 2 ++ test/libyul/objectCompiler/smoke.yul | 2 ++ test/libyul/objectCompiler/subObject.yul | 2 ++ test/libyul/objectCompiler/subSubObject.yul | 2 ++ 5 files changed, 10 insertions(+) diff --git a/test/libyul/objectCompiler/data.yul b/test/libyul/objectCompiler/data.yul index ad8899fb11bd..4447a0b8e97f 100644 --- a/test/libyul/objectCompiler/data.yul +++ b/test/libyul/objectCompiler/data.yul @@ -3,6 +3,8 @@ object "a" { // Unreferenced data is not added to the assembled bytecode. data "str" "Hello, World!" } +// ==== +// EVMVersion: >=constantinople // ---- // Assembly: // /* "source":22:29 */ diff --git a/test/libyul/objectCompiler/namedObject.yul b/test/libyul/objectCompiler/namedObject.yul index 06539dd89373..66727585dbcb 100644 --- a/test/libyul/objectCompiler/namedObject.yul +++ b/test/libyul/objectCompiler/namedObject.yul @@ -1,6 +1,8 @@ object "a" { code {} } +// ==== +// EVMVersion: >=constantinople // ---- // Assembly: // /* "source":22:29 */ diff --git a/test/libyul/objectCompiler/smoke.yul b/test/libyul/objectCompiler/smoke.yul index 82aea42f5299..2ca3d62f004a 100644 --- a/test/libyul/objectCompiler/smoke.yul +++ b/test/libyul/objectCompiler/smoke.yul @@ -1,5 +1,7 @@ { } +// ==== +// EVMVersion: >=constantinople // ---- // Assembly: // /* "source":27:34 */ diff --git a/test/libyul/objectCompiler/subObject.yul b/test/libyul/objectCompiler/subObject.yul index a47c4feda27f..f394054d74f0 100644 --- a/test/libyul/objectCompiler/subObject.yul +++ b/test/libyul/objectCompiler/subObject.yul @@ -4,6 +4,8 @@ object "a" { data "str" "Hello, World!" object "sub" { code { sstore(0, 1) } } } +// ==== +// EVMVersion: >=constantinople // ---- // Assembly: // /* "source":22:29 */ diff --git a/test/libyul/objectCompiler/subSubObject.yul b/test/libyul/objectCompiler/subSubObject.yul index a4511324e901..a7274ce639db 100644 --- a/test/libyul/objectCompiler/subSubObject.yul +++ b/test/libyul/objectCompiler/subSubObject.yul @@ -10,6 +10,8 @@ object "a" { } } } +// ==== +// EVMVersion: >=constantinople // ---- // Assembly: // /* "source":22:29 */ From 825d69872706a4d0dbdc99744236f71d5746601b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Tue, 8 Oct 2024 17:10:24 +0200 Subject: [PATCH 0505/1022] Generalize the profiler used by optimizer suite and make it a singleton --- libsolutil/CMakeLists.txt | 2 + libsolutil/Profiler.cpp | 88 ++++++++++++++++++++++++++++++++++++++ libsolutil/Profiler.h | 75 ++++++++++++++++++++++++++++++++ libyul/optimiser/Suite.cpp | 65 +++------------------------- libyul/optimiser/Suite.h | 3 -- 5 files changed, 172 insertions(+), 61 deletions(-) create mode 100644 libsolutil/Profiler.cpp create mode 100644 libsolutil/Profiler.h diff --git a/libsolutil/CMakeLists.txt b/libsolutil/CMakeLists.txt index 6ece23805aac..aac943517e02 100644 --- a/libsolutil/CMakeLists.txt +++ b/libsolutil/CMakeLists.txt @@ -27,6 +27,8 @@ set(sources Numeric.cpp Numeric.h picosha2.h + Profiler.cpp + Profiler.h Result.h SetOnce.h StackTooDeepString.h diff --git a/libsolutil/Profiler.cpp b/libsolutil/Profiler.cpp new file mode 100644 index 000000000000..8cc186b92401 --- /dev/null +++ b/libsolutil/Profiler.cpp @@ -0,0 +1,88 @@ +/* + This file is part of solidity. + + solidity is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + solidity is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with solidity. If not, see . +*/ +// SPDX-License-Identifier: GPL-3.0 + +#include + +#include + +#include +#include +#include + +using namespace std::chrono; +using namespace solidity; + +#ifdef PROFILE_OPTIMIZER_STEPS + +util::Profiler::Probe::Probe(std::string _scopeName): + m_scopeName(std::move(_scopeName)), + m_startTime(steady_clock::now()) +{ +} + +util::Profiler::Probe::~Probe() +{ + steady_clock::time_point endTime = steady_clock::now(); + int64_t durationInMicroseconds = duration_cast(endTime - m_startTime).count(); + + auto [durationIt, inserted] = Profiler::singleton().m_durations.try_emplace(m_scopeName, 0); + durationIt->second += durationInMicroseconds; +} + +util::Profiler::~Profiler() +{ + outputPerformanceMetrics(); +} + +util::Profiler& util::Profiler::singleton() +{ + static Profiler profiler; + return profiler; +} + +void util::Profiler::outputPerformanceMetrics() +{ + std::vector> durations(m_durations.begin(), m_durations.end()); + std::sort( + durations.begin(), + durations.end(), + [](std::pair const& _lhs, std::pair const& _rhs) -> bool + { + return _lhs.second < _rhs.second; + } + ); + + int64_t totalDurationInMicroseconds = 0; + for (auto&& [scopeName, durationInMicroseconds]: durations) + totalDurationInMicroseconds += durationInMicroseconds; + + std::cerr << "Performance metrics for profiled scopes" << std::endl; + std::cerr << "=======================================" << std::endl; + constexpr double microsecondsInSecond = 1000000; + for (auto&& [scopeName, durationInMicroseconds]: durations) + { + double percentage = 100.0 * static_cast(durationInMicroseconds) / static_cast(totalDurationInMicroseconds); + double durationInSeconds = static_cast(durationInMicroseconds) / microsecondsInSecond; + std::cerr << fmt::format("{:>7.3f}% ({} s): {}", percentage, durationInSeconds, scopeName) << std::endl; + } + double totalDurationInSeconds = static_cast(totalDurationInMicroseconds) / microsecondsInSecond; + std::cerr << "--------------------------------------" << std::endl; + std::cerr << fmt::format("{:>7}% ({:.3f} s)", 100, totalDurationInSeconds) << std::endl; +} + +#endif diff --git a/libsolutil/Profiler.h b/libsolutil/Profiler.h new file mode 100644 index 000000000000..e5d519bdef00 --- /dev/null +++ b/libsolutil/Profiler.h @@ -0,0 +1,75 @@ +/* + This file is part of solidity. + + solidity is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + solidity is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with solidity. If not, see . +*/ +// SPDX-License-Identifier: GPL-3.0 + +#pragma once + +#include +#include +#include +#include + +#ifdef PROFILE_OPTIMIZER_STEPS +#define PROFILER_PROBE(_scopeName, _variable) solidity::util::Profiler::Probe _variable(_scopeName); +#else +#define PROFILER_PROBE(_scopeName, _variable) void(0); +#endif + +namespace solidity::util +{ + +#ifdef PROFILE_OPTIMIZER_STEPS + +/// Simpler profiler class that gathers metrics during program execution and prints them out on exit. +/// +/// To gather metrics, create a Probe instance and let it live until the end of the scope. +/// The probe will register its creation and destruction time and store the results in the profiler +/// singleton. +/// +/// Use the PROFILER_PROBE macro to create probes conditionally, in a way that will not affect performance +/// unless profiling is enabled at compilation time via PROFILE_OPTIMIZER_STEPS CMake option. +/// +/// Scopes are identified by the name supplied to the probe. Using the same name multiple times +/// will result in metrics for those scopes being aggregated together as if they were the same scope. +class Profiler +{ +public: + class Probe + { + public: + Probe(std::string _scopeName); + ~Probe(); + + private: + std::string m_scopeName; + std::chrono::steady_clock::time_point m_startTime; + }; + + static Profiler& singleton(); + +private: + ~Profiler(); + + /// Summarizes gathered metric and prints a report to standard error output. + void outputPerformanceMetrics(); + + std::map m_durations; +}; + +#endif + +} diff --git a/libyul/optimiser/Suite.cpp b/libyul/optimiser/Suite.cpp index 0233a1cf078a..76f0368ab9ca 100644 --- a/libyul/optimiser/Suite.cpp +++ b/libyul/optimiser/Suite.cpp @@ -72,6 +72,7 @@ #include #include +#include #include @@ -83,56 +84,10 @@ #include #include -#ifdef PROFILE_OPTIMIZER_STEPS -#include -#include -#endif - using namespace solidity; using namespace solidity::yul; -#ifdef PROFILE_OPTIMIZER_STEPS -using namespace std::chrono; -#endif using namespace std::string_literals; -namespace -{ - -#ifdef PROFILE_OPTIMIZER_STEPS -void outputPerformanceMetrics(std::map const& _metrics) -{ - std::vector> durations(_metrics.begin(), _metrics.end()); - sort( - durations.begin(), - durations.end(), - [](std::pair const& _lhs, std::pair const& _rhs) -> bool - { - return _lhs.second < _rhs.second; - } - ); - - int64_t totalDurationInMicroseconds = 0; - for (auto&& [step, durationInMicroseconds]: durations) - totalDurationInMicroseconds += durationInMicroseconds; - - std::cerr << "Performance metrics of optimizer steps" << std::endl; - std::cerr << "======================================" << std::endl; - constexpr double microsecondsInSecond = 1000000; - for (auto&& [step, durationInMicroseconds]: durations) - { - double percentage = 100.0 * static_cast(durationInMicroseconds) / static_cast(totalDurationInMicroseconds); - double sec = static_cast(durationInMicroseconds) / microsecondsInSecond; - std::cerr << fmt::format("{:>7.3f}% ({} s): {}", percentage, sec, step) << std::endl; - } - double totalDurationInSeconds = static_cast(totalDurationInMicroseconds) / microsecondsInSecond; - std::cerr << "--------------------------------------" << std::endl; - std::cerr << fmt::format("{:>7}% ({:.3f} s)", 100, totalDurationInSeconds) << std::endl; -} -#endif - -} - - void OptimiserSuite::run( Dialect const& _dialect, GasMeter const* _meter, @@ -226,10 +181,6 @@ void OptimiserSuite::run( NameSimplifier::run(suite.m_context, astRoot); VarNameCleaner::run(suite.m_context, astRoot); -#ifdef PROFILE_OPTIMIZER_STEPS - outputPerformanceMetrics(suite.m_durationPerStepInMicroseconds); -#endif - _object.setCode(std::make_shared(std::move(astRoot))); _object.analysisInfo = std::make_shared(AsmAnalyzer::analyzeStrictAssertCorrect(_dialect, _object)); } @@ -504,14 +455,12 @@ void OptimiserSuite::runSequence(std::vector const& _steps, Block& { if (m_debug == Debug::PrintStep) std::cout << "Running " << step << std::endl; -#ifdef PROFILE_OPTIMIZER_STEPS - steady_clock::time_point startTime = steady_clock::now(); -#endif - allSteps().at(step)->run(m_context, _ast); -#ifdef PROFILE_OPTIMIZER_STEPS - steady_clock::time_point endTime = steady_clock::now(); - m_durationPerStepInMicroseconds[step] += duration_cast(endTime - startTime).count(); -#endif + + { + PROFILER_PROBE(step, probe); + allSteps().at(step)->run(m_context, _ast); + } + if (m_debug == Debug::PrintChanges) { // TODO should add switch to also compare variable names! diff --git a/libyul/optimiser/Suite.h b/libyul/optimiser/Suite.h index 15a41cb9f3dc..efa82f48c9b7 100644 --- a/libyul/optimiser/Suite.h +++ b/libyul/optimiser/Suite.h @@ -91,9 +91,6 @@ class OptimiserSuite private: OptimiserStepContext& m_context; Debug m_debug; -#ifdef PROFILE_OPTIMIZER_STEPS - std::map m_durationPerStepInMicroseconds; -#endif }; } From c9d2cf2f3cee7aafe906c6a32a45a7b2b7e58edc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Fri, 11 Oct 2024 16:17:28 +0200 Subject: [PATCH 0506/1022] Profiler: Add call count to metrics --- libsolutil/Profiler.cpp | 39 +++++++++++++++++++++++++-------------- libsolutil/Profiler.h | 8 +++++++- 2 files changed, 32 insertions(+), 15 deletions(-) diff --git a/libsolutil/Profiler.cpp b/libsolutil/Profiler.cpp index 8cc186b92401..88c2f7a99811 100644 --- a/libsolutil/Profiler.cpp +++ b/libsolutil/Profiler.cpp @@ -40,8 +40,9 @@ util::Profiler::Probe::~Probe() steady_clock::time_point endTime = steady_clock::now(); int64_t durationInMicroseconds = duration_cast(endTime - m_startTime).count(); - auto [durationIt, inserted] = Profiler::singleton().m_durations.try_emplace(m_scopeName, 0); - durationIt->second += durationInMicroseconds; + auto [metricsIt, inserted] = Profiler::singleton().m_metrics.try_emplace(m_scopeName, Metrics{0, 0}); + metricsIt->second.durationInMicroseconds += durationInMicroseconds; + ++metricsIt->second.callCount; } util::Profiler::~Profiler() @@ -57,32 +58,42 @@ util::Profiler& util::Profiler::singleton() void util::Profiler::outputPerformanceMetrics() { - std::vector> durations(m_durations.begin(), m_durations.end()); + std::vector> sortedMetrics(m_metrics.begin(), m_metrics.end()); std::sort( - durations.begin(), - durations.end(), - [](std::pair const& _lhs, std::pair const& _rhs) -> bool + sortedMetrics.begin(), + sortedMetrics.end(), + [](std::pair const& _lhs, std::pair const& _rhs) -> bool { - return _lhs.second < _rhs.second; + return _lhs.second.durationInMicroseconds < _rhs.second.durationInMicroseconds; } ); int64_t totalDurationInMicroseconds = 0; - for (auto&& [scopeName, durationInMicroseconds]: durations) - totalDurationInMicroseconds += durationInMicroseconds; + size_t totalCallCount = 0; + for (auto&& [scopeName, scopeMetrics]: sortedMetrics) + { + totalDurationInMicroseconds += scopeMetrics.durationInMicroseconds; + totalCallCount += scopeMetrics.callCount; + } std::cerr << "Performance metrics for profiled scopes" << std::endl; std::cerr << "=======================================" << std::endl; constexpr double microsecondsInSecond = 1000000; - for (auto&& [scopeName, durationInMicroseconds]: durations) + for (auto&& [scopeName, scopeMetrics]: sortedMetrics) { - double percentage = 100.0 * static_cast(durationInMicroseconds) / static_cast(totalDurationInMicroseconds); - double durationInSeconds = static_cast(durationInMicroseconds) / microsecondsInSecond; - std::cerr << fmt::format("{:>7.3f}% ({} s): {}", percentage, durationInSeconds, scopeName) << std::endl; + double percentage = 100.0 * static_cast(scopeMetrics.durationInMicroseconds) / static_cast(totalDurationInMicroseconds); + double durationInSeconds = static_cast(scopeMetrics.durationInMicroseconds) / microsecondsInSecond; + std::cerr << fmt::format( + "{:>7.3f}% ({} s, {} calls): {}", + percentage, + durationInSeconds, + scopeMetrics.callCount, + scopeName + ) << std::endl; } double totalDurationInSeconds = static_cast(totalDurationInMicroseconds) / microsecondsInSecond; std::cerr << "--------------------------------------" << std::endl; - std::cerr << fmt::format("{:>7}% ({:.3f} s)", 100, totalDurationInSeconds) << std::endl; + std::cerr << fmt::format("{:>7}% ({:.3f} s, {} calls)", 100, totalDurationInSeconds, totalCallCount) << std::endl; } #endif diff --git a/libsolutil/Profiler.h b/libsolutil/Profiler.h index e5d519bdef00..c87dce2adad6 100644 --- a/libsolutil/Profiler.h +++ b/libsolutil/Profiler.h @@ -64,10 +64,16 @@ class Profiler private: ~Profiler(); + struct Metrics + { + int64_t durationInMicroseconds; + size_t callCount; + }; + /// Summarizes gathered metric and prints a report to standard error output. void outputPerformanceMetrics(); - std::map m_durations; + std::map m_metrics; }; #endif From 3564a75a94ca97e4ae963f7c95a100fe3a2ea9f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Fri, 11 Oct 2024 16:00:35 +0200 Subject: [PATCH 0507/1022] Profiler: Adjust report formatting (markdown table, precision) --- libsolutil/Profiler.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/libsolutil/Profiler.cpp b/libsolutil/Profiler.cpp index 88c2f7a99811..a08636e27272 100644 --- a/libsolutil/Profiler.cpp +++ b/libsolutil/Profiler.cpp @@ -76,24 +76,25 @@ void util::Profiler::outputPerformanceMetrics() totalCallCount += scopeMetrics.callCount; } - std::cerr << "Performance metrics for profiled scopes" << std::endl; - std::cerr << "=======================================" << std::endl; + std::cerr << "PERFORMANCE METRICS FOR PROFILED SCOPES\n\n"; + std::cerr << "| Time % | Time | Calls | Scope |\n"; + std::cerr << "|-------:|-----------:|--------:|--------------------------------|\n"; + constexpr double microsecondsInSecond = 1000000; for (auto&& [scopeName, scopeMetrics]: sortedMetrics) { double percentage = 100.0 * static_cast(scopeMetrics.durationInMicroseconds) / static_cast(totalDurationInMicroseconds); double durationInSeconds = static_cast(scopeMetrics.durationInMicroseconds) / microsecondsInSecond; std::cerr << fmt::format( - "{:>7.3f}% ({} s, {} calls): {}", + "| {:5.1f}% | {:8.3f} s | {:7} | {:30} |\n", percentage, durationInSeconds, scopeMetrics.callCount, scopeName - ) << std::endl; + ); } double totalDurationInSeconds = static_cast(totalDurationInMicroseconds) / microsecondsInSecond; - std::cerr << "--------------------------------------" << std::endl; - std::cerr << fmt::format("{:>7}% ({:.3f} s, {} calls)", 100, totalDurationInSeconds, totalCallCount) << std::endl; + std::cerr << fmt::format("| {:5.1f}% | {:8.3f} s | {:7} | {:30} |\n", 100.0, totalDurationInSeconds, totalCallCount, "**TOTAL**"); } #endif From 89444f5290d216ff0aa9427d68113ff2d440d344 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Tue, 15 Oct 2024 17:46:48 +0200 Subject: [PATCH 0508/1022] Profiler: Refactor to properly use std::chrono types --- libsolutil/Profiler.cpp | 14 ++++++-------- libsolutil/Profiler.h | 2 +- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/libsolutil/Profiler.cpp b/libsolutil/Profiler.cpp index a08636e27272..1792963672fe 100644 --- a/libsolutil/Profiler.cpp +++ b/libsolutil/Profiler.cpp @@ -38,10 +38,9 @@ util::Profiler::Probe::Probe(std::string _scopeName): util::Profiler::Probe::~Probe() { steady_clock::time_point endTime = steady_clock::now(); - int64_t durationInMicroseconds = duration_cast(endTime - m_startTime).count(); - auto [metricsIt, inserted] = Profiler::singleton().m_metrics.try_emplace(m_scopeName, Metrics{0, 0}); - metricsIt->second.durationInMicroseconds += durationInMicroseconds; + auto [metricsIt, inserted] = Profiler::singleton().m_metrics.try_emplace(m_scopeName, Metrics{0us, 0}); + metricsIt->second.durationInMicroseconds += duration_cast(endTime - m_startTime); ++metricsIt->second.callCount; } @@ -68,7 +67,7 @@ void util::Profiler::outputPerformanceMetrics() } ); - int64_t totalDurationInMicroseconds = 0; + std::chrono::microseconds totalDurationInMicroseconds = 0us; size_t totalCallCount = 0; for (auto&& [scopeName, scopeMetrics]: sortedMetrics) { @@ -80,11 +79,11 @@ void util::Profiler::outputPerformanceMetrics() std::cerr << "| Time % | Time | Calls | Scope |\n"; std::cerr << "|-------:|-----------:|--------:|--------------------------------|\n"; - constexpr double microsecondsInSecond = 1000000; + double totalDurationInSeconds = duration_cast>(totalDurationInMicroseconds).count(); for (auto&& [scopeName, scopeMetrics]: sortedMetrics) { - double percentage = 100.0 * static_cast(scopeMetrics.durationInMicroseconds) / static_cast(totalDurationInMicroseconds); - double durationInSeconds = static_cast(scopeMetrics.durationInMicroseconds) / microsecondsInSecond; + double durationInSeconds = duration_cast>(scopeMetrics.durationInMicroseconds).count(); + double percentage = 100.0 * durationInSeconds / totalDurationInSeconds; std::cerr << fmt::format( "| {:5.1f}% | {:8.3f} s | {:7} | {:30} |\n", percentage, @@ -93,7 +92,6 @@ void util::Profiler::outputPerformanceMetrics() scopeName ); } - double totalDurationInSeconds = static_cast(totalDurationInMicroseconds) / microsecondsInSecond; std::cerr << fmt::format("| {:5.1f}% | {:8.3f} s | {:7} | {:30} |\n", 100.0, totalDurationInSeconds, totalCallCount, "**TOTAL**"); } diff --git a/libsolutil/Profiler.h b/libsolutil/Profiler.h index c87dce2adad6..79c516d0197b 100644 --- a/libsolutil/Profiler.h +++ b/libsolutil/Profiler.h @@ -66,7 +66,7 @@ class Profiler struct Metrics { - int64_t durationInMicroseconds; + std::chrono::microseconds durationInMicroseconds; size_t callCount; }; From 9188438b3c846d2eb7302b0a360ae68624b6dcb7 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Mon, 14 Oct 2024 09:41:22 +0200 Subject: [PATCH 0509/1022] CompilerStack: Changes ir and irOptimized to be optional json / string objects. --- Changelog.md | 1 + libsolidity/interface/CompilerStack.cpp | 48 ++++++---- libsolidity/interface/CompilerStack.h | 14 +-- libsolidity/interface/StandardCompiler.cpp | 10 +- solc/CommandLineInterface.cpp | 27 +++--- .../ast_ir_undeployable_contract/args | 2 +- .../ast_ir_undeployable_contract/output | 36 +++++++ .../input.json | 6 +- .../output.json | 94 ++++++++++++++++++- test/libsolidity/MemoryGuardTest.cpp | 4 +- 10 files changed, 196 insertions(+), 46 deletions(-) diff --git a/Changelog.md b/Changelog.md index 13af14b75b97..0ebefa6590f1 100644 --- a/Changelog.md +++ b/Changelog.md @@ -7,6 +7,7 @@ Compiler Features: Bugfixes: +* General: Fix internal compiler error when requesting IR AST outputs for interfaces and abstract contracts. ### 0.8.28 (2024-10-09) diff --git a/libsolidity/interface/CompilerStack.cpp b/libsolidity/interface/CompilerStack.cpp index 007b6187c747..e3927d4dfb1b 100644 --- a/libsolidity/interface/CompilerStack.cpp +++ b/libsolidity/interface/CompilerStack.cpp @@ -969,52 +969,61 @@ std::string const CompilerStack::filesystemFriendlyName(std::string const& _cont return matchContract.contract->name(); } -std::string const& CompilerStack::yulIR(std::string const& _contractName) const +std::optional const& CompilerStack::yulIR(std::string const& _contractName) const { solAssert(m_stackState == CompilationSuccessful, "Compilation was not successful."); return contract(_contractName).yulIR; } -Json CompilerStack::yulIRAst(std::string const& _contractName) const +std::optional CompilerStack::yulIRAst(std::string const& _contractName) const { solAssert(m_stackState == CompilationSuccessful, "Compilation was not successful."); solUnimplementedAssert(!isExperimentalSolidity()); // NOTE: Intentionally not using LazyInit. The artifact can get very large and we don't want to // keep it around when compiling a large project containing many contracts. - auto const& currentContract = contract(_contractName); + Contract const& currentContract = contract(_contractName); yulAssert(currentContract.contract); - return currentContract.contract->canBeDeployed() ? loadGeneratedIR(currentContract.yulIR).astJson() : Json{}; + yulAssert(currentContract.yulIR.has_value() == currentContract.contract->canBeDeployed()); + if (!currentContract.yulIR) + return std::nullopt; + return loadGeneratedIR(*currentContract.yulIR).astJson(); } -Json CompilerStack::yulCFGJson(std::string const& _contractName) const +std::optional CompilerStack::yulCFGJson(std::string const& _contractName) const { solAssert(m_stackState == CompilationSuccessful, "Compilation was not successful."); solUnimplementedAssert(!isExperimentalSolidity()); // NOTE: Intentionally not using LazyInit. The artifact can get very large and we don't want to // keep it around when compiling a large project containing many contracts. - auto const& currentContract = contract(_contractName); + Contract const& currentContract = contract(_contractName); yulAssert(currentContract.contract); - return currentContract.contract->canBeDeployed() ? loadGeneratedIR(currentContract.yulIR).cfgJson() : Json{}; + yulAssert(currentContract.yulIR.has_value() == currentContract.contract->canBeDeployed()); + if (!currentContract.yulIR) + return std::nullopt; + return loadGeneratedIR(*currentContract.yulIR).cfgJson(); } -std::string const& CompilerStack::yulIROptimized(std::string const& _contractName) const +std::optional const& CompilerStack::yulIROptimized(std::string const& _contractName) const { solAssert(m_stackState == CompilationSuccessful, "Compilation was not successful."); return contract(_contractName).yulIROptimized; } -Json CompilerStack::yulIROptimizedAst(std::string const& _contractName) const +std::optional CompilerStack::yulIROptimizedAst(std::string const& _contractName) const { solAssert(m_stackState == CompilationSuccessful, "Compilation was not successful."); solUnimplementedAssert(!isExperimentalSolidity()); // NOTE: Intentionally not using LazyInit. The artifact can get very large and we don't want to // keep it around when compiling a large project containing many contracts. - auto const& currentContract = contract(_contractName); + Contract const& currentContract = contract(_contractName); yulAssert(currentContract.contract); - return currentContract.contract->canBeDeployed() ? loadGeneratedIR(currentContract.yulIROptimized).astJson() : Json{}; + yulAssert(currentContract.yulIROptimized.has_value() == currentContract.contract->canBeDeployed()); + if (!currentContract.yulIROptimized) + return std::nullopt; + return loadGeneratedIR(*currentContract.yulIROptimized).astJson(); } evmasm::LinkerObject const& CompilerStack::object(std::string const& _contractName) const @@ -1513,8 +1522,11 @@ void CompilerStack::generateIR(ContractDefinition const& _contract, bool _unopti solAssert(m_stackState >= AnalysisSuccessful, ""); Contract& compiledContract = m_contracts.at(_contract.fullyQualifiedName()); - if (!compiledContract.yulIR.empty()) + if (compiledContract.yulIR) + { + solAssert(!compiledContract.yulIR->empty()); return; + } if (!*_contract.sourceUnit().annotation().useABICoderV2) m_errorReporter.warning( @@ -1533,7 +1545,7 @@ void CompilerStack::generateIR(ContractDefinition const& _contract, bool _unopti std::map otherYulSources; for (auto const& pair: m_contracts) - otherYulSources.emplace(pair.second.contract, pair.second.yulIR); + otherYulSources.emplace(pair.second.contract, pair.second.yulIR ? *pair.second.yulIR : std::string_view{}); if (m_experimentalAnalysis) { @@ -1570,7 +1582,8 @@ void CompilerStack::generateIR(ContractDefinition const& _contract, bool _unopti ); } - YulStack stack = loadGeneratedIR(compiledContract.yulIR); + yulAssert(compiledContract.yulIR); + YulStack stack = loadGeneratedIR(*compiledContract.yulIR); if (!_unoptimizedOnly) { stack.optimize(); @@ -1586,14 +1599,13 @@ void CompilerStack::generateEVMFromIR(ContractDefinition const& _contract) return; Contract& compiledContract = m_contracts.at(_contract.fullyQualifiedName()); - solAssert(!compiledContract.yulIROptimized.empty(), ""); + solAssert(compiledContract.yulIROptimized); + solAssert(!compiledContract.yulIROptimized->empty()); if (!compiledContract.object.bytecode.empty()) return; // Re-parse the Yul IR in EVM dialect - YulStack stack = loadGeneratedIR(compiledContract.yulIROptimized); - - //cout << yul::AsmPrinter{}(*stack.parserResult()->code) << endl; + YulStack stack = loadGeneratedIR(*compiledContract.yulIROptimized); std::string deployedName = IRNames::deployedObject(_contract); solAssert(!deployedName.empty(), ""); diff --git a/libsolidity/interface/CompilerStack.h b/libsolidity/interface/CompilerStack.h index 8ce2c5d62dfe..009103a498f8 100644 --- a/libsolidity/interface/CompilerStack.h +++ b/libsolidity/interface/CompilerStack.h @@ -321,18 +321,18 @@ class CompilerStack: public langutil::CharStreamProvider, public evmasm::Abstrac virtual std::string const filesystemFriendlyName(std::string const& _contractName) const override; /// @returns the IR representation of a contract. - std::string const& yulIR(std::string const& _contractName) const; + std::optional const& yulIR(std::string const& _contractName) const; /// @returns the IR representation of a contract AST in format. - Json yulIRAst(std::string const& _contractName) const; + std::optional yulIRAst(std::string const& _contractName) const; /// @returns the optimized IR representation of a contract. - std::string const& yulIROptimized(std::string const& _contractName) const; + std::optional const& yulIROptimized(std::string const& _contractName) const; /// @returns the optimized IR representation of a contract AST in JSON format. - Json yulIROptimizedAst(std::string const& _contractName) const; + std::optional yulIROptimizedAst(std::string const& _contractName) const; - Json yulCFGJson(std::string const& _contractName) const; + std::optional yulCFGJson(std::string const& _contractName) const; /// @returns the assembled object for a contract. virtual evmasm::LinkerObject const& object(std::string const& _contractName) const override; @@ -445,8 +445,8 @@ class CompilerStack: public langutil::CharStreamProvider, public evmasm::Abstrac std::optional runtimeGeneratedYulUtilityCode; ///< Extra Yul utility code that was used when compiling the deployed assembly evmasm::LinkerObject object; ///< Deployment object (includes the runtime sub-object). evmasm::LinkerObject runtimeObject; ///< Runtime object. - std::string yulIR; ///< Yul IR code straight from the code generator. - std::string yulIROptimized; ///< Reparsed and possibly optimized Yul IR code. + std::optional yulIR; ///< Yul IR code straight from the code generator. + std::optional yulIROptimized; ///< Reparsed and possibly optimized Yul IR code. util::LazyInit metadata; ///< The metadata json that will be hashed into the chain. util::LazyInit abi; util::LazyInit storageLayout; diff --git a/libsolidity/interface/StandardCompiler.cpp b/libsolidity/interface/StandardCompiler.cpp index d8ce4f2d0c7a..c5248e42e2f4 100644 --- a/libsolidity/interface/StandardCompiler.cpp +++ b/libsolidity/interface/StandardCompiler.cpp @@ -1482,15 +1482,15 @@ Json StandardCompiler::compileSolidity(StandardCompiler::InputsAndSettings _inpu // IR if (compilationSuccess && isArtifactRequested(_inputsAndSettings.outputSelection, file, name, "ir", wildcardMatchesExperimental)) - contractData["ir"] = compilerStack.yulIR(contractName); + contractData["ir"] = compilerStack.yulIR(contractName).value_or(""); if (compilationSuccess && isArtifactRequested(_inputsAndSettings.outputSelection, file, name, "irAst", wildcardMatchesExperimental)) - contractData["irAst"] = compilerStack.yulIRAst(contractName); + contractData["irAst"] = compilerStack.yulIRAst(contractName).value_or(Json{}); if (compilationSuccess && isArtifactRequested(_inputsAndSettings.outputSelection, file, name, "irOptimized", wildcardMatchesExperimental)) - contractData["irOptimized"] = compilerStack.yulIROptimized(contractName); + contractData["irOptimized"] = compilerStack.yulIROptimized(contractName).value_or(""); if (compilationSuccess && isArtifactRequested(_inputsAndSettings.outputSelection, file, name, "irOptimizedAst", wildcardMatchesExperimental)) - contractData["irOptimizedAst"] = compilerStack.yulIROptimizedAst(contractName); + contractData["irOptimizedAst"] = compilerStack.yulIROptimizedAst(contractName).value_or(Json{}); if (compilationSuccess && isArtifactRequested(_inputsAndSettings.outputSelection, file, name, "yulCFGJson", wildcardMatchesExperimental)) - contractData["yulCFGJson"] = compilerStack.yulCFGJson(contractName); + contractData["yulCFGJson"] = compilerStack.yulCFGJson(contractName).value_or(Json{}); // EVM Json evmData; diff --git a/solc/CommandLineInterface.cpp b/solc/CommandLineInterface.cpp index b791de3ef361..33aa08b463e4 100644 --- a/solc/CommandLineInterface.cpp +++ b/solc/CommandLineInterface.cpp @@ -257,12 +257,13 @@ void CommandLineInterface::handleIR(std::string const& _contractName) if (!m_options.compiler.outputs.ir) return; + std::optional const& ir = m_compiler->yulIR(_contractName); if (!m_options.output.dir.empty()) - createFile(m_compiler->filesystemFriendlyName(_contractName) + ".yul", m_compiler->yulIR(_contractName)); + createFile(m_compiler->filesystemFriendlyName(_contractName) + ".yul", ir.value_or("")); else { - sout() << "IR:" << std::endl; - sout() << m_compiler->yulIR(_contractName) << std::endl; + sout() << "IR:\n"; + sout() << ir.value_or("") << std::endl; } } @@ -273,11 +274,12 @@ void CommandLineInterface::handleIRAst(std::string const& _contractName) if (!m_options.compiler.outputs.irAstJson) return; + std::optional const& yulIRAst = m_compiler->yulIRAst(_contractName); if (!m_options.output.dir.empty()) createFile( m_compiler->filesystemFriendlyName(_contractName) + "_yul_ast.json", util::jsonPrint( - m_compiler->yulIRAst(_contractName), + yulIRAst.value_or(Json{}), m_options.formatting.json ) ); @@ -285,7 +287,7 @@ void CommandLineInterface::handleIRAst(std::string const& _contractName) { sout() << "IR AST:" << std::endl; sout() << util::jsonPrint( - m_compiler->yulIRAst(_contractName), + yulIRAst.value_or(Json{}), m_options.formatting.json ) << std::endl; } @@ -298,18 +300,19 @@ void CommandLineInterface::handleYulCFGExport(std::string const& _contractName) if (!m_options.compiler.outputs.yulCFGJson) return; + std::optional const& yulCFGJson = m_compiler->yulCFGJson(_contractName); if (!m_options.output.dir.empty()) createFile( m_compiler->filesystemFriendlyName(_contractName) + "_yul_cfg.json", util::jsonPrint( - m_compiler->yulCFGJson(_contractName), + yulCFGJson.value_or(Json{}), m_options.formatting.json ) ); else { sout() << util::jsonPrint( - m_compiler->yulCFGJson(_contractName), + yulCFGJson.value_or(Json{}), m_options.formatting.json ) << std::endl; } @@ -322,15 +325,16 @@ void CommandLineInterface::handleIROptimized(std::string const& _contractName) if (!m_options.compiler.outputs.irOptimized) return; + std::optional const& irOptimized = m_compiler->yulIROptimized(_contractName); if (!m_options.output.dir.empty()) createFile( m_compiler->filesystemFriendlyName(_contractName) + "_opt.yul", - m_compiler->yulIROptimized(_contractName) + irOptimized.value_or("") ); else { sout() << "Optimized IR:" << std::endl; - sout() << m_compiler->yulIROptimized(_contractName) << std::endl; + sout() << irOptimized.value_or("") << std::endl; } } @@ -341,11 +345,12 @@ void CommandLineInterface::handleIROptimizedAst(std::string const& _contractName if (!m_options.compiler.outputs.irOptimizedAstJson) return; + std::optional const& yulIROptimizedAst = m_compiler->yulIROptimizedAst(_contractName); if (!m_options.output.dir.empty()) createFile( m_compiler->filesystemFriendlyName(_contractName) + "_opt_yul_ast.json", util::jsonPrint( - m_compiler->yulIROptimizedAst(_contractName), + yulIROptimizedAst.value_or(Json{}), m_options.formatting.json ) ); @@ -353,7 +358,7 @@ void CommandLineInterface::handleIROptimizedAst(std::string const& _contractName { sout() << "Optimized IR AST:" << std::endl; sout() << util::jsonPrint( - m_compiler->yulIROptimizedAst(_contractName), + yulIROptimizedAst.value_or(Json{}), m_options.formatting.json ) << std::endl; } diff --git a/test/cmdlineTests/ast_ir_undeployable_contract/args b/test/cmdlineTests/ast_ir_undeployable_contract/args index d254bff83d54..74c8e867fc91 100644 --- a/test/cmdlineTests/ast_ir_undeployable_contract/args +++ b/test/cmdlineTests/ast_ir_undeployable_contract/args @@ -1 +1 @@ ---ir-ast-json --ir-optimized-ast-json --optimize --pretty-json --json-indent 4 +--bin --bin-runtime --opcodes --asm --ir --ir-ast-json --ir-optimized --ir-optimized-ast-json --gas --asm-json --abi --hashes --optimize --pretty-json --json-indent 4 diff --git a/test/cmdlineTests/ast_ir_undeployable_contract/output b/test/cmdlineTests/ast_ir_undeployable_contract/output index b64e82bd0d14..d6089273bf44 100644 --- a/test/cmdlineTests/ast_ir_undeployable_contract/output +++ b/test/cmdlineTests/ast_ir_undeployable_contract/output @@ -1,8 +1,44 @@ + +======= ast_ir_undeployable_contract/input.sol:C ======= +EVM assembly: +null +Gas estimation: +Opcodes: + +Binary: + +Binary of the runtime part: + +IR: + IR AST: null +Optimized IR: + Optimized IR AST: null +Function signatures: +Contract JSON ABI +[] + +======= ast_ir_undeployable_contract/input.sol:I ======= +EVM assembly: +null +Gas estimation: +Opcodes: + +Binary: + +Binary of the runtime part: + +IR: + IR AST: null +Optimized IR: + Optimized IR AST: null +Function signatures: +Contract JSON ABI +[] diff --git a/test/cmdlineTests/standard_ir_ast_undeployable_contract_requested/input.json b/test/cmdlineTests/standard_ir_ast_undeployable_contract_requested/input.json index 0b40ad0723d6..cc87ecd4988e 100644 --- a/test/cmdlineTests/standard_ir_ast_undeployable_contract_requested/input.json +++ b/test/cmdlineTests/standard_ir_ast_undeployable_contract_requested/input.json @@ -4,6 +4,10 @@ "C": {"urls": ["standard_ir_ast_undeployable_contract_requested/in.sol"]} }, "settings": { - "outputSelection": {"*": {"*": ["irAst", "irOptimizedAst"]}} + "outputSelection": { + "*": { + "*": ["*", "ir", "irAst", "irOptimized", "irOptimizedAst"] + } + } } } diff --git a/test/cmdlineTests/standard_ir_ast_undeployable_contract_requested/output.json b/test/cmdlineTests/standard_ir_ast_undeployable_contract_requested/output.json index dab55ebd1045..3869f7c652bd 100644 --- a/test/cmdlineTests/standard_ir_ast_undeployable_contract_requested/output.json +++ b/test/cmdlineTests/standard_ir_ast_undeployable_contract_requested/output.json @@ -2,12 +2,102 @@ "contracts": { "C": { "C": { + "abi": [], + "devdoc": { + "kind": "dev", + "methods": {}, + "version": 1 + }, + "evm": { + "assembly": "", + "bytecode": { + "functionDebugData": {}, + "generatedSources": [], + "linkReferences": {}, + "object": "", + "opcodes": "", + "sourceMap": "" + }, + "deployedBytecode": { + "functionDebugData": {}, + "generatedSources": [], + "immutableReferences": {}, + "linkReferences": {}, + "object": "", + "opcodes": "", + "sourceMap": "" + }, + "gasEstimates": null, + "legacyAssembly": null, + "methodIdentifiers": {} + }, + "ir": "", "irAst": null, - "irOptimizedAst": null + "irOptimized": "", + "irOptimizedAst": null, + "metadata": "{\"compiler\":{\"version\":\"\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"C\":\"C\"},\"evmVersion\":\"cancun\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"C\":{\"keccak256\":\"0xa8b7bfe5eff9112e6573d2860721faef28e8920ee251acb458303a05c1ec7df2\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://a2333e25b5034de4f98729e0a737309ba8e0db4371016f312e8f991f6f01613f\",\"dweb:/ipfs/QmVLwS2grVYV6qiDvNmeEYWzb6WDne9Ze47NXERSLPM4fJ\"]}},\"version\":1}", + "storageLayout": { + "storage": [], + "types": null + }, + "transientStorageLayout": { + "storage": [], + "types": null + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + } }, "I": { + "abi": [], + "devdoc": { + "kind": "dev", + "methods": {}, + "version": 1 + }, + "evm": { + "assembly": "", + "bytecode": { + "functionDebugData": {}, + "generatedSources": [], + "linkReferences": {}, + "object": "", + "opcodes": "", + "sourceMap": "" + }, + "deployedBytecode": { + "functionDebugData": {}, + "generatedSources": [], + "immutableReferences": {}, + "linkReferences": {}, + "object": "", + "opcodes": "", + "sourceMap": "" + }, + "gasEstimates": null, + "legacyAssembly": null, + "methodIdentifiers": {} + }, + "ir": "", "irAst": null, - "irOptimizedAst": null + "irOptimized": "", + "irOptimizedAst": null, + "metadata": "{\"compiler\":{\"version\":\"\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"C\":\"I\"},\"evmVersion\":\"cancun\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"C\":{\"keccak256\":\"0xa8b7bfe5eff9112e6573d2860721faef28e8920ee251acb458303a05c1ec7df2\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://a2333e25b5034de4f98729e0a737309ba8e0db4371016f312e8f991f6f01613f\",\"dweb:/ipfs/QmVLwS2grVYV6qiDvNmeEYWzb6WDne9Ze47NXERSLPM4fJ\"]}},\"version\":1}", + "storageLayout": { + "storage": [], + "types": null + }, + "transientStorageLayout": { + "storage": [], + "types": null + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + } } } }, diff --git a/test/libsolidity/MemoryGuardTest.cpp b/test/libsolidity/MemoryGuardTest.cpp index 08a2814c95e3..a98c7a323015 100644 --- a/test/libsolidity/MemoryGuardTest.cpp +++ b/test/libsolidity/MemoryGuardTest.cpp @@ -60,8 +60,10 @@ TestCase::TestResult MemoryGuardTest::run(std::ostream& _stream, std::string con for (std::string contractName: compiler().contractNames()) { ErrorList errors; + std::optional const& ir = compiler().yulIR(contractName); + solAssert(ir); auto [object, analysisInfo] = yul::test::parse( - compiler().yulIR(contractName), + *ir, EVMDialect::strictAssemblyForEVMObjects(CommonOptions::get().evmVersion(), CommonOptions::get().eofVersion()), errors ); From 7972c5118aa8bee603c3e2dbf3413f78689a12f9 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Wed, 16 Oct 2024 09:04:38 +0200 Subject: [PATCH 0510/1022] Rename undeployable contract tests to reflect they request all outputs --- .../in.sol | 0 .../input.json | 2 +- .../output.json | 0 .../args | 0 .../input.sol | 0 .../output | 4 ++-- 6 files changed, 3 insertions(+), 3 deletions(-) rename test/cmdlineTests/{standard_ir_ast_undeployable_contract_requested => standard_undeployable_contract_all_outputs}/in.sol (100%) rename test/cmdlineTests/{standard_ir_ast_undeployable_contract_requested => standard_undeployable_contract_all_outputs}/input.json (69%) rename test/cmdlineTests/{standard_ir_ast_undeployable_contract_requested => standard_undeployable_contract_all_outputs}/output.json (100%) rename test/cmdlineTests/{ast_ir_undeployable_contract => undeployable_contract_empty_outputs}/args (100%) rename test/cmdlineTests/{ast_ir_undeployable_contract => undeployable_contract_empty_outputs}/input.sol (100%) rename test/cmdlineTests/{ast_ir_undeployable_contract => undeployable_contract_empty_outputs}/output (73%) diff --git a/test/cmdlineTests/standard_ir_ast_undeployable_contract_requested/in.sol b/test/cmdlineTests/standard_undeployable_contract_all_outputs/in.sol similarity index 100% rename from test/cmdlineTests/standard_ir_ast_undeployable_contract_requested/in.sol rename to test/cmdlineTests/standard_undeployable_contract_all_outputs/in.sol diff --git a/test/cmdlineTests/standard_ir_ast_undeployable_contract_requested/input.json b/test/cmdlineTests/standard_undeployable_contract_all_outputs/input.json similarity index 69% rename from test/cmdlineTests/standard_ir_ast_undeployable_contract_requested/input.json rename to test/cmdlineTests/standard_undeployable_contract_all_outputs/input.json index cc87ecd4988e..4d2aea1f147a 100644 --- a/test/cmdlineTests/standard_ir_ast_undeployable_contract_requested/input.json +++ b/test/cmdlineTests/standard_undeployable_contract_all_outputs/input.json @@ -1,7 +1,7 @@ { "language": "Solidity", "sources": { - "C": {"urls": ["standard_ir_ast_undeployable_contract_requested/in.sol"]} + "C": {"urls": ["standard_undeployable_contract_all_outputs/in.sol"]} }, "settings": { "outputSelection": { diff --git a/test/cmdlineTests/standard_ir_ast_undeployable_contract_requested/output.json b/test/cmdlineTests/standard_undeployable_contract_all_outputs/output.json similarity index 100% rename from test/cmdlineTests/standard_ir_ast_undeployable_contract_requested/output.json rename to test/cmdlineTests/standard_undeployable_contract_all_outputs/output.json diff --git a/test/cmdlineTests/ast_ir_undeployable_contract/args b/test/cmdlineTests/undeployable_contract_empty_outputs/args similarity index 100% rename from test/cmdlineTests/ast_ir_undeployable_contract/args rename to test/cmdlineTests/undeployable_contract_empty_outputs/args diff --git a/test/cmdlineTests/ast_ir_undeployable_contract/input.sol b/test/cmdlineTests/undeployable_contract_empty_outputs/input.sol similarity index 100% rename from test/cmdlineTests/ast_ir_undeployable_contract/input.sol rename to test/cmdlineTests/undeployable_contract_empty_outputs/input.sol diff --git a/test/cmdlineTests/ast_ir_undeployable_contract/output b/test/cmdlineTests/undeployable_contract_empty_outputs/output similarity index 73% rename from test/cmdlineTests/ast_ir_undeployable_contract/output rename to test/cmdlineTests/undeployable_contract_empty_outputs/output index d6089273bf44..123edc75ddd6 100644 --- a/test/cmdlineTests/ast_ir_undeployable_contract/output +++ b/test/cmdlineTests/undeployable_contract_empty_outputs/output @@ -1,5 +1,5 @@ -======= ast_ir_undeployable_contract/input.sol:C ======= +======= undeployable_contract_empty_outputs/input.sol:C ======= EVM assembly: null Gas estimation: @@ -21,7 +21,7 @@ Function signatures: Contract JSON ABI [] -======= ast_ir_undeployable_contract/input.sol:I ======= +======= undeployable_contract_empty_outputs/input.sol:I ======= EVM assembly: null Gas estimation: From 740fe29f453efaf60e1b8fb606e3c3833c065ca4 Mon Sep 17 00:00:00 2001 From: r0qs Date: Mon, 14 Oct 2024 15:04:42 +0200 Subject: [PATCH 0511/1022] Add missing Yul CFG output header to CLI --- scripts/common_cmdline.sh | 1 + solc/CommandLineInterface.cpp | 2 ++ 2 files changed, 3 insertions(+) diff --git a/scripts/common_cmdline.sh b/scripts/common_cmdline.sh index 819a4b1c8eaf..51d30ae5d191 100644 --- a/scripts/common_cmdline.sh +++ b/scripts/common_cmdline.sh @@ -152,6 +152,7 @@ function stripCLIDecorations -e '/^IR:$/d' \ -e '/^Optimized IR:$/d' \ -e '/^EVM assembly:$/d' \ + -e '/^Yul Control Flow Graph:$/d' \ -e '/^JSON AST (compact format):$/d' \ -e '/^Function signatures:$/d' \ -e '/^Contract Storage Layout:$/d' \ diff --git a/solc/CommandLineInterface.cpp b/solc/CommandLineInterface.cpp index 33aa08b463e4..4816ee531c07 100644 --- a/solc/CommandLineInterface.cpp +++ b/solc/CommandLineInterface.cpp @@ -148,6 +148,7 @@ static bool needsHumanTargetedStdout(CommandLineOptions const& _options) _options.compiler.outputs.abi || _options.compiler.outputs.asm_ || _options.compiler.outputs.asmJson || + _options.compiler.outputs.yulCFGJson || _options.compiler.outputs.binary || _options.compiler.outputs.binaryRuntime || _options.compiler.outputs.metadata || @@ -311,6 +312,7 @@ void CommandLineInterface::handleYulCFGExport(std::string const& _contractName) ); else { + sout() << "Yul Control Flow Graph:" << std::endl; sout() << util::jsonPrint( yulCFGJson.value_or(Json{}), m_options.formatting.json From 78ecc7c851e440305a72e476c485dab49f2f7ef8 Mon Sep 17 00:00:00 2001 From: r0qs Date: Mon, 14 Oct 2024 16:29:38 +0200 Subject: [PATCH 0512/1022] Remove unecessary fields from Yul CFG Json export --- libyul/YulControlFlowGraphExporter.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/libyul/YulControlFlowGraphExporter.cpp b/libyul/YulControlFlowGraphExporter.cpp index 3f347fcf4f91..52593fab7ced 100644 --- a/libyul/YulControlFlowGraphExporter.cpp +++ b/libyul/YulControlFlowGraphExporter.cpp @@ -96,7 +96,6 @@ Json YulControlFlowGraphExporter::exportBlock(SSACFG const& _cfg, SSACFG::BlockI Json exitBlockJson = Json::object(); std::visit(util::GenericVisitor{ [&](SSACFG::BasicBlock::MainExit const&) { - exitBlockJson["targets"] = { "Block" + std::to_string(_blockId.value) }; exitBlockJson["type"] = "MainExit"; }, [&](SSACFG::BasicBlock::Jump const& _jump) @@ -115,12 +114,10 @@ Json YulControlFlowGraphExporter::exportBlock(SSACFG const& _cfg, SSACFG::BlockI _addChild(_conditionalJump.nonZero); }, [&](SSACFG::BasicBlock::FunctionReturn const& _return) { - exitBlockJson["instructions"] = toJson(_cfg, _return.returnValues); - exitBlockJson["targets"] = { "Block" + std::to_string(_blockId.value) }; + exitBlockJson["returnValues"] = toJson(_cfg, _return.returnValues); exitBlockJson["type"] = "FunctionReturn"; }, [&](SSACFG::BasicBlock::Terminated const&) { - exitBlockJson["targets"] = { "Block" + std::to_string(_blockId.value) }; exitBlockJson["type"] = "Terminated"; }, [&](SSACFG::BasicBlock::JumpTable const&) { From bddf8013140ce534eea9b9083c8ad3b38301571a Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Wed, 16 Oct 2024 14:53:19 +0200 Subject: [PATCH 0513/1022] Yul dialect: Remove fixedFunctionNames --- libyul/Dialect.h | 2 -- libyul/optimiser/Suite.cpp | 1 - 2 files changed, 3 deletions(-) diff --git a/libyul/Dialect.h b/libyul/Dialect.h index 3589e953f60f..3b0d73597dc4 100644 --- a/libyul/Dialect.h +++ b/libyul/Dialect.h @@ -78,8 +78,6 @@ struct Dialect Literal zeroLiteral() const; - virtual std::set fixedFunctionNames() const { return {}; } - Dialect() = default; virtual ~Dialect() = default; }; diff --git a/libyul/optimiser/Suite.cpp b/libyul/optimiser/Suite.cpp index 76f0368ab9ca..21356bffa6c0 100644 --- a/libyul/optimiser/Suite.cpp +++ b/libyul/optimiser/Suite.cpp @@ -106,7 +106,6 @@ void OptimiserSuite::run( evmDialect->evmVersion().canOverchargeGasForCall() && evmDialect->providesObjectAccess(); std::set reservedIdentifiers = _externallyUsedIdentifiers; - reservedIdentifiers += _dialect.fixedFunctionNames(); auto astRoot = std::get(Disambiguator( _dialect, From c38580b8e56949abce4a2b3098db6d27c526dec9 Mon Sep 17 00:00:00 2001 From: r0qs Date: Mon, 14 Oct 2024 17:56:14 +0200 Subject: [PATCH 0514/1022] Add Yul CFG export tests --- .../standard_yul_cfg_json_export/in.sol | 19 + .../standard_yul_cfg_json_export/input.json | 13 + .../standard_yul_cfg_json_export/output.json | 3972 +++++++++++++++++ .../strict_asm_yul_cfg_json_export/args | 1 + .../strict_asm_yul_cfg_json_export/input.yul | 36 + .../strict_asm_yul_cfg_json_export/output | 380 ++ test/cmdlineTests/yul_cfg_json_export/args | 1 + .../yul_cfg_json_export/input.sol | 19 + test/cmdlineTests/yul_cfg_json_export/output | 3964 ++++++++++++++++ 9 files changed, 8405 insertions(+) create mode 100644 test/cmdlineTests/standard_yul_cfg_json_export/in.sol create mode 100644 test/cmdlineTests/standard_yul_cfg_json_export/input.json create mode 100644 test/cmdlineTests/standard_yul_cfg_json_export/output.json create mode 100644 test/cmdlineTests/strict_asm_yul_cfg_json_export/args create mode 100644 test/cmdlineTests/strict_asm_yul_cfg_json_export/input.yul create mode 100644 test/cmdlineTests/strict_asm_yul_cfg_json_export/output create mode 100644 test/cmdlineTests/yul_cfg_json_export/args create mode 100644 test/cmdlineTests/yul_cfg_json_export/input.sol create mode 100644 test/cmdlineTests/yul_cfg_json_export/output diff --git a/test/cmdlineTests/standard_yul_cfg_json_export/in.sol b/test/cmdlineTests/standard_yul_cfg_json_export/in.sol new file mode 100644 index 000000000000..85691014f827 --- /dev/null +++ b/test/cmdlineTests/standard_yul_cfg_json_export/in.sol @@ -0,0 +1,19 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity >=0.0; + +interface I { + function f() external pure returns (uint); +} + +contract C is I { + function f() public pure override returns (uint) { + return 42; + } +} + +contract D { + function f() public returns (uint) { + C c = new C(); + return c.f(); + } +} diff --git a/test/cmdlineTests/standard_yul_cfg_json_export/input.json b/test/cmdlineTests/standard_yul_cfg_json_export/input.json new file mode 100644 index 000000000000..aee56abf8600 --- /dev/null +++ b/test/cmdlineTests/standard_yul_cfg_json_export/input.json @@ -0,0 +1,13 @@ +{ + "language": "Solidity", + "sources": { + "C": {"urls": ["standard_yul_cfg_json_export/in.sol"]} + }, + "settings": { + "optimizer": { + "enabled": true + }, + "viaIR": true, + "outputSelection": {"*": {"*": ["yulCFGJson"]}} + } +} diff --git a/test/cmdlineTests/standard_yul_cfg_json_export/output.json b/test/cmdlineTests/standard_yul_cfg_json_export/output.json new file mode 100644 index 000000000000..d09a6c1a5396 --- /dev/null +++ b/test/cmdlineTests/standard_yul_cfg_json_export/output.json @@ -0,0 +1,3972 @@ +{ + "contracts": { + "C": { + "C": { + "yulCFGJson": { + "C_19": { + "blocks": [ + { + "exit": { + "cond": "v2", + "targets": [ + "Block2", + "Block1" + ], + "type": "ConditionalJump" + }, + "id": "Block0", + "instructions": [ + { + "builtinArgs": [ + "128" + ], + "in": [], + "op": "memoryguard", + "out": [ + "v0" + ] + }, + { + "in": [ + "v0", + "0x40" + ], + "op": "mstore", + "out": [] + }, + { + "in": [], + "op": "callvalue", + "out": [ + "v2" + ] + } + ], + "type": "BuiltinCall" + }, + { + "exit": { + "type": "Terminated" + }, + "id": "Block2", + "instructions": [ + { + "in": [], + "op": "constructor_C_19", + "out": [] + }, + { + "in": [], + "op": "allocate_unbounded", + "out": [ + "v3" + ] + }, + { + "builtinArgs": [ + "C_19_deployed" + ], + "in": [], + "op": "datasize", + "out": [ + "v4" + ] + }, + { + "builtinArgs": [ + "C_19_deployed" + ], + "in": [], + "op": "dataoffset", + "out": [ + "v5" + ] + }, + { + "in": [ + "v4", + "v5", + "v3" + ], + "op": "codecopy", + "out": [] + }, + { + "builtinArgs": [ + "C_19_deployed" + ], + "in": [], + "op": "datasize", + "out": [ + "v6" + ] + }, + { + "in": [ + "v6", + "v3" + ], + "op": "return", + "out": [] + } + ], + "type": "BuiltinCall" + }, + { + "exit": { + "type": "Terminated" + }, + "id": "Block1", + "instructions": [ + { + "in": [], + "op": "revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb", + "out": [] + } + ], + "type": "FunctionCall" + } + ], + "functions": { + "allocate_unbounded": { + "arguments": [], + "blocks": [ + { + "exit": { + "returnValues": [ + "v2" + ], + "type": "FunctionReturn" + }, + "id": "Block0", + "instructions": [ + { + "in": [ + "0x40" + ], + "op": "mload", + "out": [ + "v2" + ] + } + ], + "type": "BuiltinCall" + } + ], + "entry": "Block0", + "returns": [ + "memPtr" + ], + "type": "Function" + }, + "constructor_C_19": { + "arguments": [], + "blocks": [ + { + "exit": { + "returnValues": [], + "type": "FunctionReturn" + }, + "id": "Block0", + "instructions": [ + { + "in": [], + "op": "constructor_I_7", + "out": [] + } + ], + "type": "FunctionCall" + } + ], + "entry": "Block0", + "returns": [], + "type": "Function" + }, + "constructor_I_7": { + "arguments": [], + "blocks": [ + { + "exit": { + "returnValues": [], + "type": "FunctionReturn" + }, + "id": "Block0", + "instructions": [] + } + ], + "entry": "Block0", + "returns": [], + "type": "Function" + }, + "revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb": { + "arguments": [], + "blocks": [ + { + "exit": { + "type": "Terminated" + }, + "id": "Block0", + "instructions": [ + { + "in": [ + "0x00", + "0x00" + ], + "op": "revert", + "out": [] + } + ], + "type": "BuiltinCall" + } + ], + "entry": "Block0", + "returns": [], + "type": "Function" + } + } + }, + "subObjects": { + "C_19_deployed": { + "blocks": [ + { + "exit": { + "cond": "v5", + "targets": [ + "Block2", + "Block1" + ], + "type": "ConditionalJump" + }, + "id": "Block0", + "instructions": [ + { + "builtinArgs": [ + "128" + ], + "in": [], + "op": "memoryguard", + "out": [ + "v0" + ] + }, + { + "in": [ + "v0", + "0x40" + ], + "op": "mstore", + "out": [] + }, + { + "in": [], + "op": "calldatasize", + "out": [ + "v3" + ] + }, + { + "in": [ + "0x04", + "v3" + ], + "op": "lt", + "out": [ + "v4" + ] + }, + { + "in": [ + "v4" + ], + "op": "iszero", + "out": [ + "v5" + ] + } + ], + "type": "BuiltinCall" + }, + { + "exit": { + "type": "Terminated" + }, + "id": "Block2", + "instructions": [ + { + "in": [], + "op": "revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74", + "out": [] + } + ], + "type": "FunctionCall" + }, + { + "exit": { + "cond": "v9", + "targets": [ + "Block5", + "Block4" + ], + "type": "ConditionalJump" + }, + "id": "Block1", + "instructions": [ + { + "in": [ + "0x00" + ], + "op": "calldataload", + "out": [ + "v7" + ] + }, + { + "in": [ + "v7" + ], + "op": "shift_right_224_unsigned", + "out": [ + "v8" + ] + }, + { + "in": [ + "0x26121ff0", + "v8" + ], + "op": "eq", + "out": [ + "v9" + ] + } + ], + "type": "BuiltinCall" + }, + { + "exit": { + "targets": [ + "Block3" + ], + "type": "Jump" + }, + "id": "Block5", + "instructions": [] + }, + { + "exit": { + "type": "Terminated" + }, + "id": "Block4", + "instructions": [ + { + "in": [], + "op": "external_fun_f_18", + "out": [] + } + ], + "type": "FunctionCall" + }, + { + "exit": { + "targets": [ + "Block2" + ], + "type": "Jump" + }, + "id": "Block3", + "instructions": [] + } + ], + "functions": { + "abi_decode_tuple_": { + "arguments": [ + "headStart", + "dataEnd" + ], + "blocks": [ + { + "exit": { + "cond": "v4", + "targets": [ + "Block2", + "Block1" + ], + "type": "ConditionalJump" + }, + "id": "Block0", + "instructions": [ + { + "in": [ + "v0", + "v1" + ], + "op": "sub", + "out": [ + "v3" + ] + }, + { + "in": [ + "0x00", + "v3" + ], + "op": "slt", + "out": [ + "v4" + ] + } + ], + "type": "BuiltinCall" + }, + { + "exit": { + "returnValues": [], + "type": "FunctionReturn" + }, + "id": "Block2", + "instructions": [] + }, + { + "exit": { + "type": "Terminated" + }, + "id": "Block1", + "instructions": [ + { + "in": [], + "op": "revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b", + "out": [] + } + ], + "type": "FunctionCall" + } + ], + "entry": "Block0", + "returns": [], + "type": "Function" + }, + "abi_encode_t_uint256_to_t_uint256_fromStack": { + "arguments": [ + "value", + "pos" + ], + "blocks": [ + { + "exit": { + "returnValues": [], + "type": "FunctionReturn" + }, + "id": "Block0", + "instructions": [ + { + "in": [ + "v0" + ], + "op": "cleanup_t_uint256", + "out": [ + "v2" + ] + }, + { + "in": [ + "v2", + "v1" + ], + "op": "mstore", + "out": [] + } + ], + "type": "BuiltinCall" + } + ], + "entry": "Block0", + "returns": [], + "type": "Function" + }, + "abi_encode_tuple_t_uint256__to_t_uint256__fromStack": { + "arguments": [ + "headStart", + "value0" + ], + "blocks": [ + { + "exit": { + "returnValues": [ + "v4" + ], + "type": "FunctionReturn" + }, + "id": "Block0", + "instructions": [ + { + "in": [ + "0x20", + "v0" + ], + "op": "add", + "out": [ + "v4" + ] + }, + { + "in": [ + "0x00", + "v0" + ], + "op": "add", + "out": [ + "v5" + ] + }, + { + "in": [ + "v5", + "v1" + ], + "op": "abi_encode_t_uint256_to_t_uint256_fromStack", + "out": [] + } + ], + "type": "FunctionCall" + } + ], + "entry": "Block0", + "returns": [ + "tail" + ], + "type": "Function" + }, + "allocate_unbounded": { + "arguments": [], + "blocks": [ + { + "exit": { + "returnValues": [ + "v2" + ], + "type": "FunctionReturn" + }, + "id": "Block0", + "instructions": [ + { + "in": [ + "0x40" + ], + "op": "mload", + "out": [ + "v2" + ] + } + ], + "type": "BuiltinCall" + } + ], + "entry": "Block0", + "returns": [ + "memPtr" + ], + "type": "Function" + }, + "cleanup_t_rational_42_by_1": { + "arguments": [ + "value" + ], + "blocks": [ + { + "exit": { + "returnValues": [ + "v0" + ], + "type": "FunctionReturn" + }, + "id": "Block0", + "instructions": [] + } + ], + "entry": "Block0", + "returns": [ + "cleaned" + ], + "type": "Function" + }, + "cleanup_t_uint256": { + "arguments": [ + "value" + ], + "blocks": [ + { + "exit": { + "returnValues": [ + "v0" + ], + "type": "FunctionReturn" + }, + "id": "Block0", + "instructions": [] + } + ], + "entry": "Block0", + "returns": [ + "cleaned" + ], + "type": "Function" + }, + "convert_t_rational_42_by_1_to_t_uint256": { + "arguments": [ + "value" + ], + "blocks": [ + { + "exit": { + "returnValues": [ + "v4" + ], + "type": "FunctionReturn" + }, + "id": "Block0", + "instructions": [ + { + "in": [ + "v0" + ], + "op": "cleanup_t_rational_42_by_1", + "out": [ + "v2" + ] + }, + { + "in": [ + "v2" + ], + "op": "identity", + "out": [ + "v3" + ] + }, + { + "in": [ + "v3" + ], + "op": "cleanup_t_uint256", + "out": [ + "v4" + ] + } + ], + "type": "FunctionCall" + } + ], + "entry": "Block0", + "returns": [ + "converted" + ], + "type": "Function" + }, + "external_fun_f_18": { + "arguments": [], + "blocks": [ + { + "exit": { + "cond": "v0", + "targets": [ + "Block2", + "Block1" + ], + "type": "ConditionalJump" + }, + "id": "Block0", + "instructions": [ + { + "in": [], + "op": "callvalue", + "out": [ + "v0" + ] + } + ], + "type": "BuiltinCall" + }, + { + "exit": { + "type": "Terminated" + }, + "id": "Block2", + "instructions": [ + { + "in": [], + "op": "calldatasize", + "out": [ + "v1" + ] + }, + { + "in": [ + "v1", + "0x04" + ], + "op": "abi_decode_tuple_", + "out": [] + }, + { + "in": [], + "op": "fun_f_18", + "out": [ + "v3" + ] + }, + { + "in": [], + "op": "allocate_unbounded", + "out": [ + "v4" + ] + }, + { + "in": [ + "v3", + "v4" + ], + "op": "abi_encode_tuple_t_uint256__to_t_uint256__fromStack", + "out": [ + "v5" + ] + }, + { + "in": [ + "v4", + "v5" + ], + "op": "sub", + "out": [ + "v6" + ] + }, + { + "in": [ + "v6", + "v4" + ], + "op": "return", + "out": [] + } + ], + "type": "BuiltinCall" + }, + { + "exit": { + "type": "Terminated" + }, + "id": "Block1", + "instructions": [ + { + "in": [], + "op": "revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb", + "out": [] + } + ], + "type": "FunctionCall" + } + ], + "entry": "Block0", + "returns": [], + "type": "Function" + }, + "fun_f_18": { + "arguments": [], + "blocks": [ + { + "exit": { + "returnValues": [ + "v3" + ], + "type": "FunctionReturn" + }, + "id": "Block0", + "instructions": [ + { + "in": [], + "op": "zero_value_for_split_t_uint256", + "out": [ + "v1" + ] + }, + { + "in": [ + "0x2a" + ], + "op": "convert_t_rational_42_by_1_to_t_uint256", + "out": [ + "v3" + ] + } + ], + "type": "FunctionCall" + } + ], + "entry": "Block0", + "returns": [ + "var__13" + ], + "type": "Function" + }, + "identity": { + "arguments": [ + "value" + ], + "blocks": [ + { + "exit": { + "returnValues": [ + "v0" + ], + "type": "FunctionReturn" + }, + "id": "Block0", + "instructions": [] + } + ], + "entry": "Block0", + "returns": [ + "ret" + ], + "type": "Function" + }, + "revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74": { + "arguments": [], + "blocks": [ + { + "exit": { + "type": "Terminated" + }, + "id": "Block0", + "instructions": [ + { + "in": [ + "0x00", + "0x00" + ], + "op": "revert", + "out": [] + } + ], + "type": "BuiltinCall" + } + ], + "entry": "Block0", + "returns": [], + "type": "Function" + }, + "revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb": { + "arguments": [], + "blocks": [ + { + "exit": { + "type": "Terminated" + }, + "id": "Block0", + "instructions": [ + { + "in": [ + "0x00", + "0x00" + ], + "op": "revert", + "out": [] + } + ], + "type": "BuiltinCall" + } + ], + "entry": "Block0", + "returns": [], + "type": "Function" + }, + "revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b": { + "arguments": [], + "blocks": [ + { + "exit": { + "type": "Terminated" + }, + "id": "Block0", + "instructions": [ + { + "in": [ + "0x00", + "0x00" + ], + "op": "revert", + "out": [] + } + ], + "type": "BuiltinCall" + } + ], + "entry": "Block0", + "returns": [], + "type": "Function" + }, + "shift_right_224_unsigned": { + "arguments": [ + "value" + ], + "blocks": [ + { + "exit": { + "returnValues": [ + "v3" + ], + "type": "FunctionReturn" + }, + "id": "Block0", + "instructions": [ + { + "in": [ + "v0", + "0xe0" + ], + "op": "shr", + "out": [ + "v3" + ] + } + ], + "type": "BuiltinCall" + } + ], + "entry": "Block0", + "returns": [ + "newValue" + ], + "type": "Function" + }, + "zero_value_for_split_t_uint256": { + "arguments": [], + "blocks": [ + { + "exit": { + "returnValues": [ + "0x00" + ], + "type": "FunctionReturn" + }, + "id": "Block0", + "instructions": [] + } + ], + "entry": "Block0", + "returns": [ + "ret" + ], + "type": "Function" + } + } + }, + "subObjects": {}, + "type": "subObject" + }, + "type": "Object" + } + }, + "D": { + "yulCFGJson": { + "D_38": { + "blocks": [ + { + "exit": { + "cond": "v2", + "targets": [ + "Block2", + "Block1" + ], + "type": "ConditionalJump" + }, + "id": "Block0", + "instructions": [ + { + "builtinArgs": [ + "128" + ], + "in": [], + "op": "memoryguard", + "out": [ + "v0" + ] + }, + { + "in": [ + "v0", + "0x40" + ], + "op": "mstore", + "out": [] + }, + { + "in": [], + "op": "callvalue", + "out": [ + "v2" + ] + } + ], + "type": "BuiltinCall" + }, + { + "exit": { + "type": "Terminated" + }, + "id": "Block2", + "instructions": [ + { + "in": [], + "op": "constructor_D_38", + "out": [] + }, + { + "in": [], + "op": "allocate_unbounded", + "out": [ + "v3" + ] + }, + { + "builtinArgs": [ + "D_38_deployed" + ], + "in": [], + "op": "datasize", + "out": [ + "v4" + ] + }, + { + "builtinArgs": [ + "D_38_deployed" + ], + "in": [], + "op": "dataoffset", + "out": [ + "v5" + ] + }, + { + "in": [ + "v4", + "v5", + "v3" + ], + "op": "codecopy", + "out": [] + }, + { + "builtinArgs": [ + "D_38_deployed" + ], + "in": [], + "op": "datasize", + "out": [ + "v6" + ] + }, + { + "in": [ + "v6", + "v3" + ], + "op": "return", + "out": [] + } + ], + "type": "BuiltinCall" + }, + { + "exit": { + "type": "Terminated" + }, + "id": "Block1", + "instructions": [ + { + "in": [], + "op": "revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb", + "out": [] + } + ], + "type": "FunctionCall" + } + ], + "functions": { + "allocate_unbounded": { + "arguments": [], + "blocks": [ + { + "exit": { + "returnValues": [ + "v2" + ], + "type": "FunctionReturn" + }, + "id": "Block0", + "instructions": [ + { + "in": [ + "0x40" + ], + "op": "mload", + "out": [ + "v2" + ] + } + ], + "type": "BuiltinCall" + } + ], + "entry": "Block0", + "returns": [ + "memPtr" + ], + "type": "Function" + }, + "constructor_D_38": { + "arguments": [], + "blocks": [ + { + "exit": { + "returnValues": [], + "type": "FunctionReturn" + }, + "id": "Block0", + "instructions": [] + } + ], + "entry": "Block0", + "returns": [], + "type": "Function" + }, + "revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb": { + "arguments": [], + "blocks": [ + { + "exit": { + "type": "Terminated" + }, + "id": "Block0", + "instructions": [ + { + "in": [ + "0x00", + "0x00" + ], + "op": "revert", + "out": [] + } + ], + "type": "BuiltinCall" + } + ], + "entry": "Block0", + "returns": [], + "type": "Function" + } + } + }, + "subObjects": { + "D_38_deployed": { + "blocks": [ + { + "exit": { + "cond": "v5", + "targets": [ + "Block2", + "Block1" + ], + "type": "ConditionalJump" + }, + "id": "Block0", + "instructions": [ + { + "builtinArgs": [ + "128" + ], + "in": [], + "op": "memoryguard", + "out": [ + "v0" + ] + }, + { + "in": [ + "v0", + "0x40" + ], + "op": "mstore", + "out": [] + }, + { + "in": [], + "op": "calldatasize", + "out": [ + "v3" + ] + }, + { + "in": [ + "0x04", + "v3" + ], + "op": "lt", + "out": [ + "v4" + ] + }, + { + "in": [ + "v4" + ], + "op": "iszero", + "out": [ + "v5" + ] + } + ], + "type": "BuiltinCall" + }, + { + "exit": { + "type": "Terminated" + }, + "id": "Block2", + "instructions": [ + { + "in": [], + "op": "revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74", + "out": [] + } + ], + "type": "FunctionCall" + }, + { + "exit": { + "cond": "v9", + "targets": [ + "Block5", + "Block4" + ], + "type": "ConditionalJump" + }, + "id": "Block1", + "instructions": [ + { + "in": [ + "0x00" + ], + "op": "calldataload", + "out": [ + "v7" + ] + }, + { + "in": [ + "v7" + ], + "op": "shift_right_224_unsigned", + "out": [ + "v8" + ] + }, + { + "in": [ + "0x26121ff0", + "v8" + ], + "op": "eq", + "out": [ + "v9" + ] + } + ], + "type": "BuiltinCall" + }, + { + "exit": { + "targets": [ + "Block3" + ], + "type": "Jump" + }, + "id": "Block5", + "instructions": [] + }, + { + "exit": { + "type": "Terminated" + }, + "id": "Block4", + "instructions": [ + { + "in": [], + "op": "external_fun_f_37", + "out": [] + } + ], + "type": "FunctionCall" + }, + { + "exit": { + "targets": [ + "Block2" + ], + "type": "Jump" + }, + "id": "Block3", + "instructions": [] + } + ], + "functions": { + "abi_decode_t_uint256_fromMemory": { + "arguments": [ + "offset", + "end" + ], + "blocks": [ + { + "exit": { + "returnValues": [ + "v3" + ], + "type": "FunctionReturn" + }, + "id": "Block0", + "instructions": [ + { + "in": [ + "v0" + ], + "op": "mload", + "out": [ + "v3" + ] + }, + { + "in": [ + "v3" + ], + "op": "validator_revert_t_uint256", + "out": [] + } + ], + "type": "FunctionCall" + } + ], + "entry": "Block0", + "returns": [ + "value" + ], + "type": "Function" + }, + "abi_decode_tuple_": { + "arguments": [ + "headStart", + "dataEnd" + ], + "blocks": [ + { + "exit": { + "cond": "v4", + "targets": [ + "Block2", + "Block1" + ], + "type": "ConditionalJump" + }, + "id": "Block0", + "instructions": [ + { + "in": [ + "v0", + "v1" + ], + "op": "sub", + "out": [ + "v3" + ] + }, + { + "in": [ + "0x00", + "v3" + ], + "op": "slt", + "out": [ + "v4" + ] + } + ], + "type": "BuiltinCall" + }, + { + "exit": { + "returnValues": [], + "type": "FunctionReturn" + }, + "id": "Block2", + "instructions": [] + }, + { + "exit": { + "type": "Terminated" + }, + "id": "Block1", + "instructions": [ + { + "in": [], + "op": "revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b", + "out": [] + } + ], + "type": "FunctionCall" + } + ], + "entry": "Block0", + "returns": [], + "type": "Function" + }, + "abi_decode_tuple_t_uint256_fromMemory": { + "arguments": [ + "headStart", + "dataEnd" + ], + "blocks": [ + { + "exit": { + "cond": "v5", + "targets": [ + "Block2", + "Block1" + ], + "type": "ConditionalJump" + }, + "id": "Block0", + "instructions": [ + { + "in": [ + "v0", + "v1" + ], + "op": "sub", + "out": [ + "v4" + ] + }, + { + "in": [ + "0x20", + "v4" + ], + "op": "slt", + "out": [ + "v5" + ] + } + ], + "type": "BuiltinCall" + }, + { + "exit": { + "returnValues": [ + "v12" + ], + "type": "FunctionReturn" + }, + "id": "Block2", + "instructions": [ + { + "in": [ + "0x00", + "v0" + ], + "op": "add", + "out": [ + "v11" + ] + }, + { + "in": [ + "v1", + "v11" + ], + "op": "abi_decode_t_uint256_fromMemory", + "out": [ + "v12" + ] + } + ], + "type": "FunctionCall" + }, + { + "exit": { + "type": "Terminated" + }, + "id": "Block1", + "instructions": [ + { + "in": [], + "op": "revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b", + "out": [] + } + ], + "type": "FunctionCall" + } + ], + "entry": "Block0", + "returns": [ + "value0" + ], + "type": "Function" + }, + "abi_encode_t_uint256_to_t_uint256_fromStack": { + "arguments": [ + "value", + "pos" + ], + "blocks": [ + { + "exit": { + "returnValues": [], + "type": "FunctionReturn" + }, + "id": "Block0", + "instructions": [ + { + "in": [ + "v0" + ], + "op": "cleanup_t_uint256", + "out": [ + "v2" + ] + }, + { + "in": [ + "v2", + "v1" + ], + "op": "mstore", + "out": [] + } + ], + "type": "BuiltinCall" + } + ], + "entry": "Block0", + "returns": [], + "type": "Function" + }, + "abi_encode_tuple__to__fromStack": { + "arguments": [ + "headStart" + ], + "blocks": [ + { + "exit": { + "returnValues": [ + "v2" + ], + "type": "FunctionReturn" + }, + "id": "Block0", + "instructions": [ + { + "in": [ + "0x00", + "v0" + ], + "op": "add", + "out": [ + "v2" + ] + } + ], + "type": "BuiltinCall" + } + ], + "entry": "Block0", + "returns": [ + "tail" + ], + "type": "Function" + }, + "abi_encode_tuple_t_uint256__to_t_uint256__fromStack": { + "arguments": [ + "headStart", + "value0" + ], + "blocks": [ + { + "exit": { + "returnValues": [ + "v4" + ], + "type": "FunctionReturn" + }, + "id": "Block0", + "instructions": [ + { + "in": [ + "0x20", + "v0" + ], + "op": "add", + "out": [ + "v4" + ] + }, + { + "in": [ + "0x00", + "v0" + ], + "op": "add", + "out": [ + "v5" + ] + }, + { + "in": [ + "v5", + "v1" + ], + "op": "abi_encode_t_uint256_to_t_uint256_fromStack", + "out": [] + } + ], + "type": "FunctionCall" + } + ], + "entry": "Block0", + "returns": [ + "tail" + ], + "type": "Function" + }, + "allocate_unbounded": { + "arguments": [], + "blocks": [ + { + "exit": { + "returnValues": [ + "v2" + ], + "type": "FunctionReturn" + }, + "id": "Block0", + "instructions": [ + { + "in": [ + "0x40" + ], + "op": "mload", + "out": [ + "v2" + ] + } + ], + "type": "BuiltinCall" + } + ], + "entry": "Block0", + "returns": [ + "memPtr" + ], + "type": "Function" + }, + "cleanup_t_uint160": { + "arguments": [ + "value" + ], + "blocks": [ + { + "exit": { + "returnValues": [ + "v3" + ], + "type": "FunctionReturn" + }, + "id": "Block0", + "instructions": [ + { + "in": [ + "0xffffffffffffffffffffffffffffffffffffffff", + "v0" + ], + "op": "and", + "out": [ + "v3" + ] + } + ], + "type": "BuiltinCall" + } + ], + "entry": "Block0", + "returns": [ + "cleaned" + ], + "type": "Function" + }, + "cleanup_t_uint256": { + "arguments": [ + "value" + ], + "blocks": [ + { + "exit": { + "returnValues": [ + "v0" + ], + "type": "FunctionReturn" + }, + "id": "Block0", + "instructions": [] + } + ], + "entry": "Block0", + "returns": [ + "cleaned" + ], + "type": "Function" + }, + "convert_t_contract$_C_$19_to_t_address": { + "arguments": [ + "value" + ], + "blocks": [ + { + "exit": { + "returnValues": [ + "v2" + ], + "type": "FunctionReturn" + }, + "id": "Block0", + "instructions": [ + { + "in": [ + "v0" + ], + "op": "convert_t_uint160_to_t_address", + "out": [ + "v2" + ] + } + ], + "type": "FunctionCall" + } + ], + "entry": "Block0", + "returns": [ + "converted" + ], + "type": "Function" + }, + "convert_t_uint160_to_t_address": { + "arguments": [ + "value" + ], + "blocks": [ + { + "exit": { + "returnValues": [ + "v2" + ], + "type": "FunctionReturn" + }, + "id": "Block0", + "instructions": [ + { + "in": [ + "v0" + ], + "op": "convert_t_uint160_to_t_uint160", + "out": [ + "v2" + ] + } + ], + "type": "FunctionCall" + } + ], + "entry": "Block0", + "returns": [ + "converted" + ], + "type": "Function" + }, + "convert_t_uint160_to_t_uint160": { + "arguments": [ + "value" + ], + "blocks": [ + { + "exit": { + "returnValues": [ + "v4" + ], + "type": "FunctionReturn" + }, + "id": "Block0", + "instructions": [ + { + "in": [ + "v0" + ], + "op": "cleanup_t_uint160", + "out": [ + "v2" + ] + }, + { + "in": [ + "v2" + ], + "op": "identity", + "out": [ + "v3" + ] + }, + { + "in": [ + "v3" + ], + "op": "cleanup_t_uint160", + "out": [ + "v4" + ] + } + ], + "type": "FunctionCall" + } + ], + "entry": "Block0", + "returns": [ + "converted" + ], + "type": "Function" + }, + "external_fun_f_37": { + "arguments": [], + "blocks": [ + { + "exit": { + "cond": "v0", + "targets": [ + "Block2", + "Block1" + ], + "type": "ConditionalJump" + }, + "id": "Block0", + "instructions": [ + { + "in": [], + "op": "callvalue", + "out": [ + "v0" + ] + } + ], + "type": "BuiltinCall" + }, + { + "exit": { + "type": "Terminated" + }, + "id": "Block2", + "instructions": [ + { + "in": [], + "op": "calldatasize", + "out": [ + "v1" + ] + }, + { + "in": [ + "v1", + "0x04" + ], + "op": "abi_decode_tuple_", + "out": [] + }, + { + "in": [], + "op": "fun_f_37", + "out": [ + "v3" + ] + }, + { + "in": [], + "op": "allocate_unbounded", + "out": [ + "v4" + ] + }, + { + "in": [ + "v3", + "v4" + ], + "op": "abi_encode_tuple_t_uint256__to_t_uint256__fromStack", + "out": [ + "v5" + ] + }, + { + "in": [ + "v4", + "v5" + ], + "op": "sub", + "out": [ + "v6" + ] + }, + { + "in": [ + "v6", + "v4" + ], + "op": "return", + "out": [] + } + ], + "type": "BuiltinCall" + }, + { + "exit": { + "type": "Terminated" + }, + "id": "Block1", + "instructions": [ + { + "in": [], + "op": "revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb", + "out": [] + } + ], + "type": "FunctionCall" + } + ], + "entry": "Block0", + "returns": [], + "type": "Function" + }, + "finalize_allocation": { + "arguments": [ + "memPtr", + "size" + ], + "blocks": [ + { + "exit": { + "cond": "v7", + "targets": [ + "Block2", + "Block1" + ], + "type": "ConditionalJump" + }, + "id": "Block0", + "instructions": [ + { + "in": [ + "v1" + ], + "op": "round_up_to_mul_of_32", + "out": [ + "v2" + ] + }, + { + "in": [ + "v2", + "v0" + ], + "op": "add", + "out": [ + "v3" + ] + }, + { + "in": [ + "v0", + "v3" + ], + "op": "lt", + "out": [ + "v4" + ] + }, + { + "in": [ + "0xffffffffffffffff", + "v3" + ], + "op": "gt", + "out": [ + "v6" + ] + }, + { + "in": [ + "v4", + "v6" + ], + "op": "or", + "out": [ + "v7" + ] + } + ], + "type": "BuiltinCall" + }, + { + "exit": { + "returnValues": [], + "type": "FunctionReturn" + }, + "id": "Block2", + "instructions": [ + { + "in": [ + "v3", + "0x40" + ], + "op": "mstore", + "out": [] + } + ], + "type": "BuiltinCall" + }, + { + "exit": { + "type": "Terminated" + }, + "id": "Block1", + "instructions": [ + { + "in": [], + "op": "panic_error_0x41", + "out": [] + } + ], + "type": "FunctionCall" + } + ], + "entry": "Block0", + "returns": [], + "type": "Function" + }, + "fun_f_37": { + "arguments": [], + "blocks": [ + { + "exit": { + "cond": "v8", + "targets": [ + "Block2", + "Block1" + ], + "type": "ConditionalJump" + }, + "id": "Block0", + "instructions": [ + { + "in": [], + "op": "zero_value_for_split_t_uint256", + "out": [ + "v1" + ] + }, + { + "in": [], + "op": "allocate_unbounded", + "out": [ + "v2" + ] + }, + { + "builtinArgs": [ + "C_19" + ], + "in": [], + "op": "datasize", + "out": [ + "v3" + ] + }, + { + "in": [ + "v3", + "v2" + ], + "op": "add", + "out": [ + "v4" + ] + }, + { + "in": [ + "v2", + "v4" + ], + "op": "lt", + "out": [ + "v5" + ] + }, + { + "in": [ + "0xffffffffffffffff", + "v4" + ], + "op": "gt", + "out": [ + "v7" + ] + }, + { + "in": [ + "v5", + "v7" + ], + "op": "or", + "out": [ + "v8" + ] + } + ], + "type": "BuiltinCall" + }, + { + "exit": { + "cond": "v19", + "targets": [ + "Block5", + "Block4" + ], + "type": "ConditionalJump" + }, + "id": "Block2", + "instructions": [ + { + "builtinArgs": [ + "C_19" + ], + "in": [], + "op": "datasize", + "out": [ + "v9" + ] + }, + { + "builtinArgs": [ + "C_19" + ], + "in": [], + "op": "dataoffset", + "out": [ + "v10" + ] + }, + { + "in": [ + "v9", + "v10", + "v2" + ], + "op": "datacopy", + "out": [] + }, + { + "in": [ + "v4" + ], + "op": "abi_encode_tuple__to__fromStack", + "out": [ + "v16" + ] + }, + { + "in": [ + "v2", + "v16" + ], + "op": "sub", + "out": [ + "v17" + ] + }, + { + "in": [ + "v17", + "v2", + "0x00" + ], + "op": "create", + "out": [ + "v18" + ] + }, + { + "in": [ + "v18" + ], + "op": "iszero", + "out": [ + "v19" + ] + } + ], + "type": "BuiltinCall" + }, + { + "exit": { + "type": "Terminated" + }, + "id": "Block1", + "instructions": [ + { + "in": [], + "op": "panic_error_0x41", + "out": [] + } + ], + "type": "FunctionCall" + }, + { + "exit": { + "cond": "v33", + "targets": [ + "Block8", + "Block7" + ], + "type": "ConditionalJump" + }, + "id": "Block5", + "instructions": [ + { + "in": [ + "v18" + ], + "op": "convert_t_contract$_C_$19_to_t_address", + "out": [ + "v22" + ] + }, + { + "in": [], + "op": "allocate_unbounded", + "out": [ + "v24" + ] + }, + { + "in": [ + "0x26121ff0" + ], + "op": "shift_left_224", + "out": [ + "v25" + ] + }, + { + "in": [ + "v25", + "v24" + ], + "op": "mstore", + "out": [] + }, + { + "in": [ + "0x04", + "v24" + ], + "op": "add", + "out": [ + "v27" + ] + }, + { + "in": [ + "v27" + ], + "op": "abi_encode_tuple__to__fromStack", + "out": [ + "v28" + ] + }, + { + "in": [ + "v24", + "v28" + ], + "op": "sub", + "out": [ + "v30" + ] + }, + { + "in": [], + "op": "gas", + "out": [ + "v31" + ] + }, + { + "in": [ + "0x20", + "v24", + "v30", + "v24", + "v22", + "v31" + ], + "op": "staticcall", + "out": [ + "v32" + ] + }, + { + "in": [ + "v32" + ], + "op": "iszero", + "out": [ + "v33" + ] + } + ], + "type": "BuiltinCall" + }, + { + "exit": { + "type": "Terminated" + }, + "id": "Block4", + "instructions": [ + { + "in": [], + "op": "revert_forward_1", + "out": [] + } + ], + "type": "FunctionCall" + }, + { + "exit": { + "cond": "v32", + "targets": [ + "Block11", + "Block10" + ], + "type": "ConditionalJump" + }, + "id": "Block8", + "instructions": [] + }, + { + "exit": { + "type": "Terminated" + }, + "id": "Block7", + "instructions": [ + { + "in": [], + "op": "revert_forward_1", + "out": [] + } + ], + "type": "FunctionCall" + }, + { + "entries": [ + "Block8", + "Block13" + ], + "exit": { + "returnValues": [ + "v45" + ], + "type": "FunctionReturn" + }, + "id": "Block11", + "instructions": [ + { + "in": [ + "0x00", + "v44" + ], + "op": "PhiFunction", + "out": [ + "v45" + ] + } + ] + }, + { + "exit": { + "cond": "v37", + "targets": [ + "Block13", + "Block12" + ], + "type": "ConditionalJump" + }, + "id": "Block10", + "instructions": [ + { + "in": [], + "op": "returndatasize", + "out": [ + "v36" + ] + }, + { + "in": [ + "v36", + "0x20" + ], + "op": "gt", + "out": [ + "v37" + ] + } + ], + "type": "BuiltinCall" + }, + { + "entries": [ + "Block10", + "Block12" + ], + "exit": { + "targets": [ + "Block11" + ], + "type": "Jump" + }, + "id": "Block13", + "instructions": [ + { + "in": [ + "0x20", + "v38" + ], + "op": "PhiFunction", + "out": [ + "v39" + ] + }, + { + "in": [ + "v39", + "v24" + ], + "op": "finalize_allocation", + "out": [] + }, + { + "in": [ + "v39", + "v24" + ], + "op": "add", + "out": [ + "v43" + ] + }, + { + "in": [ + "v43", + "v24" + ], + "op": "abi_decode_tuple_t_uint256_fromMemory", + "out": [ + "v44" + ] + } + ], + "type": "FunctionCall" + }, + { + "exit": { + "targets": [ + "Block13" + ], + "type": "Jump" + }, + "id": "Block12", + "instructions": [ + { + "in": [], + "op": "returndatasize", + "out": [ + "v38" + ] + } + ], + "type": "BuiltinCall" + } + ], + "entry": "Block0", + "returns": [ + "var__22" + ], + "type": "Function" + }, + "identity": { + "arguments": [ + "value" + ], + "blocks": [ + { + "exit": { + "returnValues": [ + "v0" + ], + "type": "FunctionReturn" + }, + "id": "Block0", + "instructions": [] + } + ], + "entry": "Block0", + "returns": [ + "ret" + ], + "type": "Function" + }, + "panic_error_0x41": { + "arguments": [], + "blocks": [ + { + "exit": { + "type": "Terminated" + }, + "id": "Block0", + "instructions": [ + { + "in": [ + "0x4e487b7100000000000000000000000000000000000000000000000000000000", + "0x00" + ], + "op": "mstore", + "out": [] + }, + { + "in": [ + "0x41", + "0x04" + ], + "op": "mstore", + "out": [] + }, + { + "in": [ + "0x24", + "0x00" + ], + "op": "revert", + "out": [] + } + ], + "type": "BuiltinCall" + } + ], + "entry": "Block0", + "returns": [], + "type": "Function" + }, + "revert_error_0cc013b6b3b6beabea4e3a74a6d380f0df81852ca99887912475e1f66b2a2c20": { + "arguments": [], + "blocks": [ + { + "exit": { + "type": "Terminated" + }, + "id": "Block0", + "instructions": [ + { + "in": [ + "0x00", + "0x00" + ], + "op": "revert", + "out": [] + } + ], + "type": "BuiltinCall" + } + ], + "entry": "Block0", + "returns": [], + "type": "Function" + }, + "revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74": { + "arguments": [], + "blocks": [ + { + "exit": { + "type": "Terminated" + }, + "id": "Block0", + "instructions": [ + { + "in": [ + "0x00", + "0x00" + ], + "op": "revert", + "out": [] + } + ], + "type": "BuiltinCall" + } + ], + "entry": "Block0", + "returns": [], + "type": "Function" + }, + "revert_error_c1322bf8034eace5e0b5c7295db60986aa89aae5e0ea0873e4689e076861a5db": { + "arguments": [], + "blocks": [ + { + "exit": { + "type": "Terminated" + }, + "id": "Block0", + "instructions": [ + { + "in": [ + "0x00", + "0x00" + ], + "op": "revert", + "out": [] + } + ], + "type": "BuiltinCall" + } + ], + "entry": "Block0", + "returns": [], + "type": "Function" + }, + "revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb": { + "arguments": [], + "blocks": [ + { + "exit": { + "type": "Terminated" + }, + "id": "Block0", + "instructions": [ + { + "in": [ + "0x00", + "0x00" + ], + "op": "revert", + "out": [] + } + ], + "type": "BuiltinCall" + } + ], + "entry": "Block0", + "returns": [], + "type": "Function" + }, + "revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b": { + "arguments": [], + "blocks": [ + { + "exit": { + "type": "Terminated" + }, + "id": "Block0", + "instructions": [ + { + "in": [ + "0x00", + "0x00" + ], + "op": "revert", + "out": [] + } + ], + "type": "BuiltinCall" + } + ], + "entry": "Block0", + "returns": [], + "type": "Function" + }, + "revert_forward_1": { + "arguments": [], + "blocks": [ + { + "exit": { + "type": "Terminated" + }, + "id": "Block0", + "instructions": [ + { + "in": [], + "op": "allocate_unbounded", + "out": [ + "v0" + ] + }, + { + "in": [], + "op": "returndatasize", + "out": [ + "v1" + ] + }, + { + "in": [ + "v1", + "0x00", + "v0" + ], + "op": "returndatacopy", + "out": [] + }, + { + "in": [], + "op": "returndatasize", + "out": [ + "v3" + ] + }, + { + "in": [ + "v3", + "v0" + ], + "op": "revert", + "out": [] + } + ], + "type": "BuiltinCall" + } + ], + "entry": "Block0", + "returns": [], + "type": "Function" + }, + "round_up_to_mul_of_32": { + "arguments": [ + "value" + ], + "blocks": [ + { + "exit": { + "returnValues": [ + "v5" + ], + "type": "FunctionReturn" + }, + "id": "Block0", + "instructions": [ + { + "in": [ + "0x1f" + ], + "op": "not", + "out": [ + "v3" + ] + }, + { + "in": [ + "0x1f", + "v0" + ], + "op": "add", + "out": [ + "v4" + ] + }, + { + "in": [ + "v3", + "v4" + ], + "op": "and", + "out": [ + "v5" + ] + } + ], + "type": "BuiltinCall" + } + ], + "entry": "Block0", + "returns": [ + "result" + ], + "type": "Function" + }, + "shift_left_224": { + "arguments": [ + "value" + ], + "blocks": [ + { + "exit": { + "returnValues": [ + "v3" + ], + "type": "FunctionReturn" + }, + "id": "Block0", + "instructions": [ + { + "in": [ + "v0", + "0xe0" + ], + "op": "shl", + "out": [ + "v3" + ] + } + ], + "type": "BuiltinCall" + } + ], + "entry": "Block0", + "returns": [ + "newValue" + ], + "type": "Function" + }, + "shift_right_224_unsigned": { + "arguments": [ + "value" + ], + "blocks": [ + { + "exit": { + "returnValues": [ + "v3" + ], + "type": "FunctionReturn" + }, + "id": "Block0", + "instructions": [ + { + "in": [ + "v0", + "0xe0" + ], + "op": "shr", + "out": [ + "v3" + ] + } + ], + "type": "BuiltinCall" + } + ], + "entry": "Block0", + "returns": [ + "newValue" + ], + "type": "Function" + }, + "validator_revert_t_uint256": { + "arguments": [ + "value" + ], + "blocks": [ + { + "exit": { + "cond": "v3", + "targets": [ + "Block2", + "Block1" + ], + "type": "ConditionalJump" + }, + "id": "Block0", + "instructions": [ + { + "in": [ + "v0" + ], + "op": "cleanup_t_uint256", + "out": [ + "v1" + ] + }, + { + "in": [ + "v1", + "v0" + ], + "op": "eq", + "out": [ + "v2" + ] + }, + { + "in": [ + "v2" + ], + "op": "iszero", + "out": [ + "v3" + ] + } + ], + "type": "BuiltinCall" + }, + { + "exit": { + "returnValues": [], + "type": "FunctionReturn" + }, + "id": "Block2", + "instructions": [] + }, + { + "exit": { + "type": "Terminated" + }, + "id": "Block1", + "instructions": [ + { + "in": [ + "0x00", + "0x00" + ], + "op": "revert", + "out": [] + } + ], + "type": "BuiltinCall" + } + ], + "entry": "Block0", + "returns": [], + "type": "Function" + }, + "zero_value_for_split_t_uint256": { + "arguments": [], + "blocks": [ + { + "exit": { + "returnValues": [ + "0x00" + ], + "type": "FunctionReturn" + }, + "id": "Block0", + "instructions": [] + } + ], + "entry": "Block0", + "returns": [ + "ret" + ], + "type": "Function" + } + } + }, + "subObjects": { + "C_19": { + "blocks": [ + { + "exit": { + "cond": "v2", + "targets": [ + "Block2", + "Block1" + ], + "type": "ConditionalJump" + }, + "id": "Block0", + "instructions": [ + { + "builtinArgs": [ + "128" + ], + "in": [], + "op": "memoryguard", + "out": [ + "v0" + ] + }, + { + "in": [ + "v0", + "0x40" + ], + "op": "mstore", + "out": [] + }, + { + "in": [], + "op": "callvalue", + "out": [ + "v2" + ] + } + ], + "type": "BuiltinCall" + }, + { + "exit": { + "type": "Terminated" + }, + "id": "Block2", + "instructions": [ + { + "in": [], + "op": "constructor_C_19", + "out": [] + }, + { + "in": [], + "op": "allocate_unbounded", + "out": [ + "v3" + ] + }, + { + "builtinArgs": [ + "C_19_deployed" + ], + "in": [], + "op": "datasize", + "out": [ + "v4" + ] + }, + { + "builtinArgs": [ + "C_19_deployed" + ], + "in": [], + "op": "dataoffset", + "out": [ + "v5" + ] + }, + { + "in": [ + "v4", + "v5", + "v3" + ], + "op": "codecopy", + "out": [] + }, + { + "builtinArgs": [ + "C_19_deployed" + ], + "in": [], + "op": "datasize", + "out": [ + "v6" + ] + }, + { + "in": [ + "v6", + "v3" + ], + "op": "return", + "out": [] + } + ], + "type": "BuiltinCall" + }, + { + "exit": { + "type": "Terminated" + }, + "id": "Block1", + "instructions": [ + { + "in": [], + "op": "revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb", + "out": [] + } + ], + "type": "FunctionCall" + } + ], + "functions": { + "allocate_unbounded": { + "arguments": [], + "blocks": [ + { + "exit": { + "returnValues": [ + "v2" + ], + "type": "FunctionReturn" + }, + "id": "Block0", + "instructions": [ + { + "in": [ + "0x40" + ], + "op": "mload", + "out": [ + "v2" + ] + } + ], + "type": "BuiltinCall" + } + ], + "entry": "Block0", + "returns": [ + "memPtr" + ], + "type": "Function" + }, + "constructor_C_19": { + "arguments": [], + "blocks": [ + { + "exit": { + "returnValues": [], + "type": "FunctionReturn" + }, + "id": "Block0", + "instructions": [ + { + "in": [], + "op": "constructor_I_7", + "out": [] + } + ], + "type": "FunctionCall" + } + ], + "entry": "Block0", + "returns": [], + "type": "Function" + }, + "constructor_I_7": { + "arguments": [], + "blocks": [ + { + "exit": { + "returnValues": [], + "type": "FunctionReturn" + }, + "id": "Block0", + "instructions": [] + } + ], + "entry": "Block0", + "returns": [], + "type": "Function" + }, + "revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb": { + "arguments": [], + "blocks": [ + { + "exit": { + "type": "Terminated" + }, + "id": "Block0", + "instructions": [ + { + "in": [ + "0x00", + "0x00" + ], + "op": "revert", + "out": [] + } + ], + "type": "BuiltinCall" + } + ], + "entry": "Block0", + "returns": [], + "type": "Function" + } + } + }, + "subObjects": { + "C_19_deployed": { + "blocks": [ + { + "exit": { + "cond": "v5", + "targets": [ + "Block2", + "Block1" + ], + "type": "ConditionalJump" + }, + "id": "Block0", + "instructions": [ + { + "builtinArgs": [ + "128" + ], + "in": [], + "op": "memoryguard", + "out": [ + "v0" + ] + }, + { + "in": [ + "v0", + "0x40" + ], + "op": "mstore", + "out": [] + }, + { + "in": [], + "op": "calldatasize", + "out": [ + "v3" + ] + }, + { + "in": [ + "0x04", + "v3" + ], + "op": "lt", + "out": [ + "v4" + ] + }, + { + "in": [ + "v4" + ], + "op": "iszero", + "out": [ + "v5" + ] + } + ], + "type": "BuiltinCall" + }, + { + "exit": { + "type": "Terminated" + }, + "id": "Block2", + "instructions": [ + { + "in": [], + "op": "revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74", + "out": [] + } + ], + "type": "FunctionCall" + }, + { + "exit": { + "cond": "v9", + "targets": [ + "Block5", + "Block4" + ], + "type": "ConditionalJump" + }, + "id": "Block1", + "instructions": [ + { + "in": [ + "0x00" + ], + "op": "calldataload", + "out": [ + "v7" + ] + }, + { + "in": [ + "v7" + ], + "op": "shift_right_224_unsigned", + "out": [ + "v8" + ] + }, + { + "in": [ + "0x26121ff0", + "v8" + ], + "op": "eq", + "out": [ + "v9" + ] + } + ], + "type": "BuiltinCall" + }, + { + "exit": { + "targets": [ + "Block3" + ], + "type": "Jump" + }, + "id": "Block5", + "instructions": [] + }, + { + "exit": { + "type": "Terminated" + }, + "id": "Block4", + "instructions": [ + { + "in": [], + "op": "external_fun_f_18", + "out": [] + } + ], + "type": "FunctionCall" + }, + { + "exit": { + "targets": [ + "Block2" + ], + "type": "Jump" + }, + "id": "Block3", + "instructions": [] + } + ], + "functions": { + "abi_decode_tuple_": { + "arguments": [ + "headStart", + "dataEnd" + ], + "blocks": [ + { + "exit": { + "cond": "v4", + "targets": [ + "Block2", + "Block1" + ], + "type": "ConditionalJump" + }, + "id": "Block0", + "instructions": [ + { + "in": [ + "v0", + "v1" + ], + "op": "sub", + "out": [ + "v3" + ] + }, + { + "in": [ + "0x00", + "v3" + ], + "op": "slt", + "out": [ + "v4" + ] + } + ], + "type": "BuiltinCall" + }, + { + "exit": { + "returnValues": [], + "type": "FunctionReturn" + }, + "id": "Block2", + "instructions": [] + }, + { + "exit": { + "type": "Terminated" + }, + "id": "Block1", + "instructions": [ + { + "in": [], + "op": "revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b", + "out": [] + } + ], + "type": "FunctionCall" + } + ], + "entry": "Block0", + "returns": [], + "type": "Function" + }, + "abi_encode_t_uint256_to_t_uint256_fromStack": { + "arguments": [ + "value", + "pos" + ], + "blocks": [ + { + "exit": { + "returnValues": [], + "type": "FunctionReturn" + }, + "id": "Block0", + "instructions": [ + { + "in": [ + "v0" + ], + "op": "cleanup_t_uint256", + "out": [ + "v2" + ] + }, + { + "in": [ + "v2", + "v1" + ], + "op": "mstore", + "out": [] + } + ], + "type": "BuiltinCall" + } + ], + "entry": "Block0", + "returns": [], + "type": "Function" + }, + "abi_encode_tuple_t_uint256__to_t_uint256__fromStack": { + "arguments": [ + "headStart", + "value0" + ], + "blocks": [ + { + "exit": { + "returnValues": [ + "v4" + ], + "type": "FunctionReturn" + }, + "id": "Block0", + "instructions": [ + { + "in": [ + "0x20", + "v0" + ], + "op": "add", + "out": [ + "v4" + ] + }, + { + "in": [ + "0x00", + "v0" + ], + "op": "add", + "out": [ + "v5" + ] + }, + { + "in": [ + "v5", + "v1" + ], + "op": "abi_encode_t_uint256_to_t_uint256_fromStack", + "out": [] + } + ], + "type": "FunctionCall" + } + ], + "entry": "Block0", + "returns": [ + "tail" + ], + "type": "Function" + }, + "allocate_unbounded": { + "arguments": [], + "blocks": [ + { + "exit": { + "returnValues": [ + "v2" + ], + "type": "FunctionReturn" + }, + "id": "Block0", + "instructions": [ + { + "in": [ + "0x40" + ], + "op": "mload", + "out": [ + "v2" + ] + } + ], + "type": "BuiltinCall" + } + ], + "entry": "Block0", + "returns": [ + "memPtr" + ], + "type": "Function" + }, + "cleanup_t_rational_42_by_1": { + "arguments": [ + "value" + ], + "blocks": [ + { + "exit": { + "returnValues": [ + "v0" + ], + "type": "FunctionReturn" + }, + "id": "Block0", + "instructions": [] + } + ], + "entry": "Block0", + "returns": [ + "cleaned" + ], + "type": "Function" + }, + "cleanup_t_uint256": { + "arguments": [ + "value" + ], + "blocks": [ + { + "exit": { + "returnValues": [ + "v0" + ], + "type": "FunctionReturn" + }, + "id": "Block0", + "instructions": [] + } + ], + "entry": "Block0", + "returns": [ + "cleaned" + ], + "type": "Function" + }, + "convert_t_rational_42_by_1_to_t_uint256": { + "arguments": [ + "value" + ], + "blocks": [ + { + "exit": { + "returnValues": [ + "v4" + ], + "type": "FunctionReturn" + }, + "id": "Block0", + "instructions": [ + { + "in": [ + "v0" + ], + "op": "cleanup_t_rational_42_by_1", + "out": [ + "v2" + ] + }, + { + "in": [ + "v2" + ], + "op": "identity", + "out": [ + "v3" + ] + }, + { + "in": [ + "v3" + ], + "op": "cleanup_t_uint256", + "out": [ + "v4" + ] + } + ], + "type": "FunctionCall" + } + ], + "entry": "Block0", + "returns": [ + "converted" + ], + "type": "Function" + }, + "external_fun_f_18": { + "arguments": [], + "blocks": [ + { + "exit": { + "cond": "v0", + "targets": [ + "Block2", + "Block1" + ], + "type": "ConditionalJump" + }, + "id": "Block0", + "instructions": [ + { + "in": [], + "op": "callvalue", + "out": [ + "v0" + ] + } + ], + "type": "BuiltinCall" + }, + { + "exit": { + "type": "Terminated" + }, + "id": "Block2", + "instructions": [ + { + "in": [], + "op": "calldatasize", + "out": [ + "v1" + ] + }, + { + "in": [ + "v1", + "0x04" + ], + "op": "abi_decode_tuple_", + "out": [] + }, + { + "in": [], + "op": "fun_f_18", + "out": [ + "v3" + ] + }, + { + "in": [], + "op": "allocate_unbounded", + "out": [ + "v4" + ] + }, + { + "in": [ + "v3", + "v4" + ], + "op": "abi_encode_tuple_t_uint256__to_t_uint256__fromStack", + "out": [ + "v5" + ] + }, + { + "in": [ + "v4", + "v5" + ], + "op": "sub", + "out": [ + "v6" + ] + }, + { + "in": [ + "v6", + "v4" + ], + "op": "return", + "out": [] + } + ], + "type": "BuiltinCall" + }, + { + "exit": { + "type": "Terminated" + }, + "id": "Block1", + "instructions": [ + { + "in": [], + "op": "revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb", + "out": [] + } + ], + "type": "FunctionCall" + } + ], + "entry": "Block0", + "returns": [], + "type": "Function" + }, + "fun_f_18": { + "arguments": [], + "blocks": [ + { + "exit": { + "returnValues": [ + "v3" + ], + "type": "FunctionReturn" + }, + "id": "Block0", + "instructions": [ + { + "in": [], + "op": "zero_value_for_split_t_uint256", + "out": [ + "v1" + ] + }, + { + "in": [ + "0x2a" + ], + "op": "convert_t_rational_42_by_1_to_t_uint256", + "out": [ + "v3" + ] + } + ], + "type": "FunctionCall" + } + ], + "entry": "Block0", + "returns": [ + "var__13" + ], + "type": "Function" + }, + "identity": { + "arguments": [ + "value" + ], + "blocks": [ + { + "exit": { + "returnValues": [ + "v0" + ], + "type": "FunctionReturn" + }, + "id": "Block0", + "instructions": [] + } + ], + "entry": "Block0", + "returns": [ + "ret" + ], + "type": "Function" + }, + "revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74": { + "arguments": [], + "blocks": [ + { + "exit": { + "type": "Terminated" + }, + "id": "Block0", + "instructions": [ + { + "in": [ + "0x00", + "0x00" + ], + "op": "revert", + "out": [] + } + ], + "type": "BuiltinCall" + } + ], + "entry": "Block0", + "returns": [], + "type": "Function" + }, + "revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb": { + "arguments": [], + "blocks": [ + { + "exit": { + "type": "Terminated" + }, + "id": "Block0", + "instructions": [ + { + "in": [ + "0x00", + "0x00" + ], + "op": "revert", + "out": [] + } + ], + "type": "BuiltinCall" + } + ], + "entry": "Block0", + "returns": [], + "type": "Function" + }, + "revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b": { + "arguments": [], + "blocks": [ + { + "exit": { + "type": "Terminated" + }, + "id": "Block0", + "instructions": [ + { + "in": [ + "0x00", + "0x00" + ], + "op": "revert", + "out": [] + } + ], + "type": "BuiltinCall" + } + ], + "entry": "Block0", + "returns": [], + "type": "Function" + }, + "shift_right_224_unsigned": { + "arguments": [ + "value" + ], + "blocks": [ + { + "exit": { + "returnValues": [ + "v3" + ], + "type": "FunctionReturn" + }, + "id": "Block0", + "instructions": [ + { + "in": [ + "v0", + "0xe0" + ], + "op": "shr", + "out": [ + "v3" + ] + } + ], + "type": "BuiltinCall" + } + ], + "entry": "Block0", + "returns": [ + "newValue" + ], + "type": "Function" + }, + "zero_value_for_split_t_uint256": { + "arguments": [], + "blocks": [ + { + "exit": { + "returnValues": [ + "0x00" + ], + "type": "FunctionReturn" + }, + "id": "Block0", + "instructions": [] + } + ], + "entry": "Block0", + "returns": [ + "ret" + ], + "type": "Function" + } + } + }, + "subObjects": {}, + "type": "subObject" + }, + "type": "subObject" + }, + "type": "subObject" + }, + "type": "Object" + } + }, + "I": { + "yulCFGJson": null + } + } + }, + "sources": { + "C": { + "id": 0 + } + } +} diff --git a/test/cmdlineTests/strict_asm_yul_cfg_json_export/args b/test/cmdlineTests/strict_asm_yul_cfg_json_export/args new file mode 100644 index 000000000000..1147466b54ef --- /dev/null +++ b/test/cmdlineTests/strict_asm_yul_cfg_json_export/args @@ -0,0 +1 @@ +--strict-assembly --optimize --yul-cfg-json --pretty-json --json-indent 4 diff --git a/test/cmdlineTests/strict_asm_yul_cfg_json_export/input.yul b/test/cmdlineTests/strict_asm_yul_cfg_json_export/input.yul new file mode 100644 index 000000000000..4165f70ba640 --- /dev/null +++ b/test/cmdlineTests/strict_asm_yul_cfg_json_export/input.yul @@ -0,0 +1,36 @@ +/// @use-src 0:"input.sol" +object "C_19" { + code { + { + /// @src 0:124:223 "contract C is I {..." + let _1 := memoryguard(0x80) + mstore(64, _1) + if callvalue() { revert(0, 0) } + let _2 := datasize("C_19_deployed") + codecopy(_1, dataoffset("C_19_deployed"), _2) + return(_1, _2) + } + } + /// @use-src 0:"input.sol" + object "C_19_deployed" { + code { + { + /// @src 0:124:223 "contract C is I {..." + let _1 := memoryguard(0x80) + mstore(64, _1) + if iszero(lt(calldatasize(), 4)) + { + if eq(0x26121ff0, shr(224, calldataload(0))) + { + if callvalue() { revert(0, 0) } + if slt(add(calldatasize(), not(3)), 0) { revert(0, 0) } + mstore(_1, /** @src 0:212:214 "42" */ 0x2a) + /// @src 0:124:223 "contract C is I {..." + return(_1, 32) + } + } + revert(0, 0) + } + } + } +} diff --git a/test/cmdlineTests/strict_asm_yul_cfg_json_export/output b/test/cmdlineTests/strict_asm_yul_cfg_json_export/output new file mode 100644 index 000000000000..18fa4288c5a2 --- /dev/null +++ b/test/cmdlineTests/strict_asm_yul_cfg_json_export/output @@ -0,0 +1,380 @@ + +======= strict_asm_yul_cfg_json_export/input.yul (EVM) ======= +Yul Control Flow Graph: + +{ + "C_19": { + "blocks": [ + { + "exit": { + "cond": "v2", + "targets": [ + "Block2", + "Block1" + ], + "type": "ConditionalJump" + }, + "id": "Block0", + "instructions": [ + { + "builtinArgs": [ + "0x80" + ], + "in": [], + "op": "memoryguard", + "out": [ + "v0" + ] + }, + { + "in": [ + "v0", + "0x40" + ], + "op": "mstore", + "out": [] + }, + { + "in": [], + "op": "callvalue", + "out": [ + "v2" + ] + } + ], + "type": "BuiltinCall" + }, + { + "exit": { + "type": "Terminated" + }, + "id": "Block2", + "instructions": [ + { + "builtinArgs": [ + "C_19_deployed" + ], + "in": [], + "op": "datasize", + "out": [ + "v4" + ] + }, + { + "builtinArgs": [ + "C_19_deployed" + ], + "in": [], + "op": "dataoffset", + "out": [ + "v5" + ] + }, + { + "in": [ + "v4", + "v5", + "v0" + ], + "op": "codecopy", + "out": [] + }, + { + "in": [ + "v4", + "v0" + ], + "op": "return", + "out": [] + } + ], + "type": "BuiltinCall" + }, + { + "exit": { + "type": "Terminated" + }, + "id": "Block1", + "instructions": [ + { + "in": [ + "0x00", + "0x00" + ], + "op": "revert", + "out": [] + } + ], + "type": "BuiltinCall" + } + ], + "functions": {} + }, + "subObjects": { + "C_19_deployed": { + "blocks": [ + { + "exit": { + "cond": "v5", + "targets": [ + "Block2", + "Block1" + ], + "type": "ConditionalJump" + }, + "id": "Block0", + "instructions": [ + { + "builtinArgs": [ + "0x80" + ], + "in": [], + "op": "memoryguard", + "out": [ + "v0" + ] + }, + { + "in": [ + "v0", + "0x40" + ], + "op": "mstore", + "out": [] + }, + { + "in": [], + "op": "calldatasize", + "out": [ + "v3" + ] + }, + { + "in": [ + "0x04", + "v3" + ], + "op": "lt", + "out": [ + "v4" + ] + }, + { + "in": [ + "v4" + ], + "op": "iszero", + "out": [ + "v5" + ] + } + ], + "type": "BuiltinCall" + }, + { + "exit": { + "type": "Terminated" + }, + "id": "Block2", + "instructions": [ + { + "in": [ + "0x00", + "0x00" + ], + "op": "revert", + "out": [] + } + ], + "type": "BuiltinCall" + }, + { + "exit": { + "cond": "v11", + "targets": [ + "Block4", + "Block3" + ], + "type": "ConditionalJump" + }, + "id": "Block1", + "instructions": [ + { + "in": [ + "0x00" + ], + "op": "calldataload", + "out": [ + "v7" + ] + }, + { + "in": [ + "v7", + "0xe0" + ], + "op": "shr", + "out": [ + "v9" + ] + }, + { + "in": [ + "v9", + "0x26121ff0" + ], + "op": "eq", + "out": [ + "v11" + ] + } + ], + "type": "BuiltinCall" + }, + { + "exit": { + "targets": [ + "Block2" + ], + "type": "Jump" + }, + "id": "Block4", + "instructions": [] + }, + { + "exit": { + "cond": "v12", + "targets": [ + "Block6", + "Block5" + ], + "type": "ConditionalJump" + }, + "id": "Block3", + "instructions": [ + { + "in": [], + "op": "callvalue", + "out": [ + "v12" + ] + } + ], + "type": "BuiltinCall" + }, + { + "exit": { + "cond": "v17", + "targets": [ + "Block9", + "Block8" + ], + "type": "ConditionalJump" + }, + "id": "Block6", + "instructions": [ + { + "in": [ + "0x03" + ], + "op": "not", + "out": [ + "v14" + ] + }, + { + "in": [], + "op": "calldatasize", + "out": [ + "v15" + ] + }, + { + "in": [ + "v14", + "v15" + ], + "op": "add", + "out": [ + "v16" + ] + }, + { + "in": [ + "0x00", + "v16" + ], + "op": "slt", + "out": [ + "v17" + ] + } + ], + "type": "BuiltinCall" + }, + { + "exit": { + "type": "Terminated" + }, + "id": "Block5", + "instructions": [ + { + "in": [ + "0x00", + "0x00" + ], + "op": "revert", + "out": [] + } + ], + "type": "BuiltinCall" + }, + { + "exit": { + "type": "Terminated" + }, + "id": "Block9", + "instructions": [ + { + "in": [ + "0x2a", + "v0" + ], + "op": "mstore", + "out": [] + }, + { + "in": [ + "0x20", + "v0" + ], + "op": "return", + "out": [] + } + ], + "type": "BuiltinCall" + }, + { + "exit": { + "type": "Terminated" + }, + "id": "Block8", + "instructions": [ + { + "in": [ + "0x00", + "0x00" + ], + "op": "revert", + "out": [] + } + ], + "type": "BuiltinCall" + } + ], + "functions": {} + }, + "type": "subObject" + }, + "type": "Object" +} diff --git a/test/cmdlineTests/yul_cfg_json_export/args b/test/cmdlineTests/yul_cfg_json_export/args new file mode 100644 index 000000000000..4af41df671fb --- /dev/null +++ b/test/cmdlineTests/yul_cfg_json_export/args @@ -0,0 +1 @@ +--via-ir --optimize --yul-cfg-json --pretty-json --json-indent 4 diff --git a/test/cmdlineTests/yul_cfg_json_export/input.sol b/test/cmdlineTests/yul_cfg_json_export/input.sol new file mode 100644 index 000000000000..85691014f827 --- /dev/null +++ b/test/cmdlineTests/yul_cfg_json_export/input.sol @@ -0,0 +1,19 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity >=0.0; + +interface I { + function f() external pure returns (uint); +} + +contract C is I { + function f() public pure override returns (uint) { + return 42; + } +} + +contract D { + function f() public returns (uint) { + C c = new C(); + return c.f(); + } +} diff --git a/test/cmdlineTests/yul_cfg_json_export/output b/test/cmdlineTests/yul_cfg_json_export/output new file mode 100644 index 000000000000..3a287ee760ad --- /dev/null +++ b/test/cmdlineTests/yul_cfg_json_export/output @@ -0,0 +1,3964 @@ + +======= yul_cfg_json_export/input.sol:C ======= +Yul Control Flow Graph: +{ + "C_19": { + "blocks": [ + { + "exit": { + "cond": "v2", + "targets": [ + "Block2", + "Block1" + ], + "type": "ConditionalJump" + }, + "id": "Block0", + "instructions": [ + { + "builtinArgs": [ + "128" + ], + "in": [], + "op": "memoryguard", + "out": [ + "v0" + ] + }, + { + "in": [ + "v0", + "0x40" + ], + "op": "mstore", + "out": [] + }, + { + "in": [], + "op": "callvalue", + "out": [ + "v2" + ] + } + ], + "type": "BuiltinCall" + }, + { + "exit": { + "type": "Terminated" + }, + "id": "Block2", + "instructions": [ + { + "in": [], + "op": "constructor_C_19", + "out": [] + }, + { + "in": [], + "op": "allocate_unbounded", + "out": [ + "v3" + ] + }, + { + "builtinArgs": [ + "C_19_deployed" + ], + "in": [], + "op": "datasize", + "out": [ + "v4" + ] + }, + { + "builtinArgs": [ + "C_19_deployed" + ], + "in": [], + "op": "dataoffset", + "out": [ + "v5" + ] + }, + { + "in": [ + "v4", + "v5", + "v3" + ], + "op": "codecopy", + "out": [] + }, + { + "builtinArgs": [ + "C_19_deployed" + ], + "in": [], + "op": "datasize", + "out": [ + "v6" + ] + }, + { + "in": [ + "v6", + "v3" + ], + "op": "return", + "out": [] + } + ], + "type": "BuiltinCall" + }, + { + "exit": { + "type": "Terminated" + }, + "id": "Block1", + "instructions": [ + { + "in": [], + "op": "revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb", + "out": [] + } + ], + "type": "FunctionCall" + } + ], + "functions": { + "allocate_unbounded": { + "arguments": [], + "blocks": [ + { + "exit": { + "returnValues": [ + "v2" + ], + "type": "FunctionReturn" + }, + "id": "Block0", + "instructions": [ + { + "in": [ + "0x40" + ], + "op": "mload", + "out": [ + "v2" + ] + } + ], + "type": "BuiltinCall" + } + ], + "entry": "Block0", + "returns": [ + "memPtr" + ], + "type": "Function" + }, + "constructor_C_19": { + "arguments": [], + "blocks": [ + { + "exit": { + "returnValues": [], + "type": "FunctionReturn" + }, + "id": "Block0", + "instructions": [ + { + "in": [], + "op": "constructor_I_7", + "out": [] + } + ], + "type": "FunctionCall" + } + ], + "entry": "Block0", + "returns": [], + "type": "Function" + }, + "constructor_I_7": { + "arguments": [], + "blocks": [ + { + "exit": { + "returnValues": [], + "type": "FunctionReturn" + }, + "id": "Block0", + "instructions": [] + } + ], + "entry": "Block0", + "returns": [], + "type": "Function" + }, + "revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb": { + "arguments": [], + "blocks": [ + { + "exit": { + "type": "Terminated" + }, + "id": "Block0", + "instructions": [ + { + "in": [ + "0x00", + "0x00" + ], + "op": "revert", + "out": [] + } + ], + "type": "BuiltinCall" + } + ], + "entry": "Block0", + "returns": [], + "type": "Function" + } + } + }, + "subObjects": { + "C_19_deployed": { + "blocks": [ + { + "exit": { + "cond": "v5", + "targets": [ + "Block2", + "Block1" + ], + "type": "ConditionalJump" + }, + "id": "Block0", + "instructions": [ + { + "builtinArgs": [ + "128" + ], + "in": [], + "op": "memoryguard", + "out": [ + "v0" + ] + }, + { + "in": [ + "v0", + "0x40" + ], + "op": "mstore", + "out": [] + }, + { + "in": [], + "op": "calldatasize", + "out": [ + "v3" + ] + }, + { + "in": [ + "0x04", + "v3" + ], + "op": "lt", + "out": [ + "v4" + ] + }, + { + "in": [ + "v4" + ], + "op": "iszero", + "out": [ + "v5" + ] + } + ], + "type": "BuiltinCall" + }, + { + "exit": { + "type": "Terminated" + }, + "id": "Block2", + "instructions": [ + { + "in": [], + "op": "revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74", + "out": [] + } + ], + "type": "FunctionCall" + }, + { + "exit": { + "cond": "v9", + "targets": [ + "Block5", + "Block4" + ], + "type": "ConditionalJump" + }, + "id": "Block1", + "instructions": [ + { + "in": [ + "0x00" + ], + "op": "calldataload", + "out": [ + "v7" + ] + }, + { + "in": [ + "v7" + ], + "op": "shift_right_224_unsigned", + "out": [ + "v8" + ] + }, + { + "in": [ + "0x26121ff0", + "v8" + ], + "op": "eq", + "out": [ + "v9" + ] + } + ], + "type": "BuiltinCall" + }, + { + "exit": { + "targets": [ + "Block3" + ], + "type": "Jump" + }, + "id": "Block5", + "instructions": [] + }, + { + "exit": { + "type": "Terminated" + }, + "id": "Block4", + "instructions": [ + { + "in": [], + "op": "external_fun_f_18", + "out": [] + } + ], + "type": "FunctionCall" + }, + { + "exit": { + "targets": [ + "Block2" + ], + "type": "Jump" + }, + "id": "Block3", + "instructions": [] + } + ], + "functions": { + "abi_decode_tuple_": { + "arguments": [ + "headStart", + "dataEnd" + ], + "blocks": [ + { + "exit": { + "cond": "v4", + "targets": [ + "Block2", + "Block1" + ], + "type": "ConditionalJump" + }, + "id": "Block0", + "instructions": [ + { + "in": [ + "v0", + "v1" + ], + "op": "sub", + "out": [ + "v3" + ] + }, + { + "in": [ + "0x00", + "v3" + ], + "op": "slt", + "out": [ + "v4" + ] + } + ], + "type": "BuiltinCall" + }, + { + "exit": { + "returnValues": [], + "type": "FunctionReturn" + }, + "id": "Block2", + "instructions": [] + }, + { + "exit": { + "type": "Terminated" + }, + "id": "Block1", + "instructions": [ + { + "in": [], + "op": "revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b", + "out": [] + } + ], + "type": "FunctionCall" + } + ], + "entry": "Block0", + "returns": [], + "type": "Function" + }, + "abi_encode_t_uint256_to_t_uint256_fromStack": { + "arguments": [ + "value", + "pos" + ], + "blocks": [ + { + "exit": { + "returnValues": [], + "type": "FunctionReturn" + }, + "id": "Block0", + "instructions": [ + { + "in": [ + "v0" + ], + "op": "cleanup_t_uint256", + "out": [ + "v2" + ] + }, + { + "in": [ + "v2", + "v1" + ], + "op": "mstore", + "out": [] + } + ], + "type": "BuiltinCall" + } + ], + "entry": "Block0", + "returns": [], + "type": "Function" + }, + "abi_encode_tuple_t_uint256__to_t_uint256__fromStack": { + "arguments": [ + "headStart", + "value0" + ], + "blocks": [ + { + "exit": { + "returnValues": [ + "v4" + ], + "type": "FunctionReturn" + }, + "id": "Block0", + "instructions": [ + { + "in": [ + "0x20", + "v0" + ], + "op": "add", + "out": [ + "v4" + ] + }, + { + "in": [ + "0x00", + "v0" + ], + "op": "add", + "out": [ + "v5" + ] + }, + { + "in": [ + "v5", + "v1" + ], + "op": "abi_encode_t_uint256_to_t_uint256_fromStack", + "out": [] + } + ], + "type": "FunctionCall" + } + ], + "entry": "Block0", + "returns": [ + "tail" + ], + "type": "Function" + }, + "allocate_unbounded": { + "arguments": [], + "blocks": [ + { + "exit": { + "returnValues": [ + "v2" + ], + "type": "FunctionReturn" + }, + "id": "Block0", + "instructions": [ + { + "in": [ + "0x40" + ], + "op": "mload", + "out": [ + "v2" + ] + } + ], + "type": "BuiltinCall" + } + ], + "entry": "Block0", + "returns": [ + "memPtr" + ], + "type": "Function" + }, + "cleanup_t_rational_42_by_1": { + "arguments": [ + "value" + ], + "blocks": [ + { + "exit": { + "returnValues": [ + "v0" + ], + "type": "FunctionReturn" + }, + "id": "Block0", + "instructions": [] + } + ], + "entry": "Block0", + "returns": [ + "cleaned" + ], + "type": "Function" + }, + "cleanup_t_uint256": { + "arguments": [ + "value" + ], + "blocks": [ + { + "exit": { + "returnValues": [ + "v0" + ], + "type": "FunctionReturn" + }, + "id": "Block0", + "instructions": [] + } + ], + "entry": "Block0", + "returns": [ + "cleaned" + ], + "type": "Function" + }, + "convert_t_rational_42_by_1_to_t_uint256": { + "arguments": [ + "value" + ], + "blocks": [ + { + "exit": { + "returnValues": [ + "v4" + ], + "type": "FunctionReturn" + }, + "id": "Block0", + "instructions": [ + { + "in": [ + "v0" + ], + "op": "cleanup_t_rational_42_by_1", + "out": [ + "v2" + ] + }, + { + "in": [ + "v2" + ], + "op": "identity", + "out": [ + "v3" + ] + }, + { + "in": [ + "v3" + ], + "op": "cleanup_t_uint256", + "out": [ + "v4" + ] + } + ], + "type": "FunctionCall" + } + ], + "entry": "Block0", + "returns": [ + "converted" + ], + "type": "Function" + }, + "external_fun_f_18": { + "arguments": [], + "blocks": [ + { + "exit": { + "cond": "v0", + "targets": [ + "Block2", + "Block1" + ], + "type": "ConditionalJump" + }, + "id": "Block0", + "instructions": [ + { + "in": [], + "op": "callvalue", + "out": [ + "v0" + ] + } + ], + "type": "BuiltinCall" + }, + { + "exit": { + "type": "Terminated" + }, + "id": "Block2", + "instructions": [ + { + "in": [], + "op": "calldatasize", + "out": [ + "v1" + ] + }, + { + "in": [ + "v1", + "0x04" + ], + "op": "abi_decode_tuple_", + "out": [] + }, + { + "in": [], + "op": "fun_f_18", + "out": [ + "v3" + ] + }, + { + "in": [], + "op": "allocate_unbounded", + "out": [ + "v4" + ] + }, + { + "in": [ + "v3", + "v4" + ], + "op": "abi_encode_tuple_t_uint256__to_t_uint256__fromStack", + "out": [ + "v5" + ] + }, + { + "in": [ + "v4", + "v5" + ], + "op": "sub", + "out": [ + "v6" + ] + }, + { + "in": [ + "v6", + "v4" + ], + "op": "return", + "out": [] + } + ], + "type": "BuiltinCall" + }, + { + "exit": { + "type": "Terminated" + }, + "id": "Block1", + "instructions": [ + { + "in": [], + "op": "revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb", + "out": [] + } + ], + "type": "FunctionCall" + } + ], + "entry": "Block0", + "returns": [], + "type": "Function" + }, + "fun_f_18": { + "arguments": [], + "blocks": [ + { + "exit": { + "returnValues": [ + "v3" + ], + "type": "FunctionReturn" + }, + "id": "Block0", + "instructions": [ + { + "in": [], + "op": "zero_value_for_split_t_uint256", + "out": [ + "v1" + ] + }, + { + "in": [ + "0x2a" + ], + "op": "convert_t_rational_42_by_1_to_t_uint256", + "out": [ + "v3" + ] + } + ], + "type": "FunctionCall" + } + ], + "entry": "Block0", + "returns": [ + "var__13" + ], + "type": "Function" + }, + "identity": { + "arguments": [ + "value" + ], + "blocks": [ + { + "exit": { + "returnValues": [ + "v0" + ], + "type": "FunctionReturn" + }, + "id": "Block0", + "instructions": [] + } + ], + "entry": "Block0", + "returns": [ + "ret" + ], + "type": "Function" + }, + "revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74": { + "arguments": [], + "blocks": [ + { + "exit": { + "type": "Terminated" + }, + "id": "Block0", + "instructions": [ + { + "in": [ + "0x00", + "0x00" + ], + "op": "revert", + "out": [] + } + ], + "type": "BuiltinCall" + } + ], + "entry": "Block0", + "returns": [], + "type": "Function" + }, + "revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb": { + "arguments": [], + "blocks": [ + { + "exit": { + "type": "Terminated" + }, + "id": "Block0", + "instructions": [ + { + "in": [ + "0x00", + "0x00" + ], + "op": "revert", + "out": [] + } + ], + "type": "BuiltinCall" + } + ], + "entry": "Block0", + "returns": [], + "type": "Function" + }, + "revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b": { + "arguments": [], + "blocks": [ + { + "exit": { + "type": "Terminated" + }, + "id": "Block0", + "instructions": [ + { + "in": [ + "0x00", + "0x00" + ], + "op": "revert", + "out": [] + } + ], + "type": "BuiltinCall" + } + ], + "entry": "Block0", + "returns": [], + "type": "Function" + }, + "shift_right_224_unsigned": { + "arguments": [ + "value" + ], + "blocks": [ + { + "exit": { + "returnValues": [ + "v3" + ], + "type": "FunctionReturn" + }, + "id": "Block0", + "instructions": [ + { + "in": [ + "v0", + "0xe0" + ], + "op": "shr", + "out": [ + "v3" + ] + } + ], + "type": "BuiltinCall" + } + ], + "entry": "Block0", + "returns": [ + "newValue" + ], + "type": "Function" + }, + "zero_value_for_split_t_uint256": { + "arguments": [], + "blocks": [ + { + "exit": { + "returnValues": [ + "0x00" + ], + "type": "FunctionReturn" + }, + "id": "Block0", + "instructions": [] + } + ], + "entry": "Block0", + "returns": [ + "ret" + ], + "type": "Function" + } + } + }, + "subObjects": {}, + "type": "subObject" + }, + "type": "Object" +} + +======= yul_cfg_json_export/input.sol:D ======= +Yul Control Flow Graph: +{ + "D_38": { + "blocks": [ + { + "exit": { + "cond": "v2", + "targets": [ + "Block2", + "Block1" + ], + "type": "ConditionalJump" + }, + "id": "Block0", + "instructions": [ + { + "builtinArgs": [ + "128" + ], + "in": [], + "op": "memoryguard", + "out": [ + "v0" + ] + }, + { + "in": [ + "v0", + "0x40" + ], + "op": "mstore", + "out": [] + }, + { + "in": [], + "op": "callvalue", + "out": [ + "v2" + ] + } + ], + "type": "BuiltinCall" + }, + { + "exit": { + "type": "Terminated" + }, + "id": "Block2", + "instructions": [ + { + "in": [], + "op": "constructor_D_38", + "out": [] + }, + { + "in": [], + "op": "allocate_unbounded", + "out": [ + "v3" + ] + }, + { + "builtinArgs": [ + "D_38_deployed" + ], + "in": [], + "op": "datasize", + "out": [ + "v4" + ] + }, + { + "builtinArgs": [ + "D_38_deployed" + ], + "in": [], + "op": "dataoffset", + "out": [ + "v5" + ] + }, + { + "in": [ + "v4", + "v5", + "v3" + ], + "op": "codecopy", + "out": [] + }, + { + "builtinArgs": [ + "D_38_deployed" + ], + "in": [], + "op": "datasize", + "out": [ + "v6" + ] + }, + { + "in": [ + "v6", + "v3" + ], + "op": "return", + "out": [] + } + ], + "type": "BuiltinCall" + }, + { + "exit": { + "type": "Terminated" + }, + "id": "Block1", + "instructions": [ + { + "in": [], + "op": "revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb", + "out": [] + } + ], + "type": "FunctionCall" + } + ], + "functions": { + "allocate_unbounded": { + "arguments": [], + "blocks": [ + { + "exit": { + "returnValues": [ + "v2" + ], + "type": "FunctionReturn" + }, + "id": "Block0", + "instructions": [ + { + "in": [ + "0x40" + ], + "op": "mload", + "out": [ + "v2" + ] + } + ], + "type": "BuiltinCall" + } + ], + "entry": "Block0", + "returns": [ + "memPtr" + ], + "type": "Function" + }, + "constructor_D_38": { + "arguments": [], + "blocks": [ + { + "exit": { + "returnValues": [], + "type": "FunctionReturn" + }, + "id": "Block0", + "instructions": [] + } + ], + "entry": "Block0", + "returns": [], + "type": "Function" + }, + "revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb": { + "arguments": [], + "blocks": [ + { + "exit": { + "type": "Terminated" + }, + "id": "Block0", + "instructions": [ + { + "in": [ + "0x00", + "0x00" + ], + "op": "revert", + "out": [] + } + ], + "type": "BuiltinCall" + } + ], + "entry": "Block0", + "returns": [], + "type": "Function" + } + } + }, + "subObjects": { + "D_38_deployed": { + "blocks": [ + { + "exit": { + "cond": "v5", + "targets": [ + "Block2", + "Block1" + ], + "type": "ConditionalJump" + }, + "id": "Block0", + "instructions": [ + { + "builtinArgs": [ + "128" + ], + "in": [], + "op": "memoryguard", + "out": [ + "v0" + ] + }, + { + "in": [ + "v0", + "0x40" + ], + "op": "mstore", + "out": [] + }, + { + "in": [], + "op": "calldatasize", + "out": [ + "v3" + ] + }, + { + "in": [ + "0x04", + "v3" + ], + "op": "lt", + "out": [ + "v4" + ] + }, + { + "in": [ + "v4" + ], + "op": "iszero", + "out": [ + "v5" + ] + } + ], + "type": "BuiltinCall" + }, + { + "exit": { + "type": "Terminated" + }, + "id": "Block2", + "instructions": [ + { + "in": [], + "op": "revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74", + "out": [] + } + ], + "type": "FunctionCall" + }, + { + "exit": { + "cond": "v9", + "targets": [ + "Block5", + "Block4" + ], + "type": "ConditionalJump" + }, + "id": "Block1", + "instructions": [ + { + "in": [ + "0x00" + ], + "op": "calldataload", + "out": [ + "v7" + ] + }, + { + "in": [ + "v7" + ], + "op": "shift_right_224_unsigned", + "out": [ + "v8" + ] + }, + { + "in": [ + "0x26121ff0", + "v8" + ], + "op": "eq", + "out": [ + "v9" + ] + } + ], + "type": "BuiltinCall" + }, + { + "exit": { + "targets": [ + "Block3" + ], + "type": "Jump" + }, + "id": "Block5", + "instructions": [] + }, + { + "exit": { + "type": "Terminated" + }, + "id": "Block4", + "instructions": [ + { + "in": [], + "op": "external_fun_f_37", + "out": [] + } + ], + "type": "FunctionCall" + }, + { + "exit": { + "targets": [ + "Block2" + ], + "type": "Jump" + }, + "id": "Block3", + "instructions": [] + } + ], + "functions": { + "abi_decode_t_uint256_fromMemory": { + "arguments": [ + "offset", + "end" + ], + "blocks": [ + { + "exit": { + "returnValues": [ + "v3" + ], + "type": "FunctionReturn" + }, + "id": "Block0", + "instructions": [ + { + "in": [ + "v0" + ], + "op": "mload", + "out": [ + "v3" + ] + }, + { + "in": [ + "v3" + ], + "op": "validator_revert_t_uint256", + "out": [] + } + ], + "type": "FunctionCall" + } + ], + "entry": "Block0", + "returns": [ + "value" + ], + "type": "Function" + }, + "abi_decode_tuple_": { + "arguments": [ + "headStart", + "dataEnd" + ], + "blocks": [ + { + "exit": { + "cond": "v4", + "targets": [ + "Block2", + "Block1" + ], + "type": "ConditionalJump" + }, + "id": "Block0", + "instructions": [ + { + "in": [ + "v0", + "v1" + ], + "op": "sub", + "out": [ + "v3" + ] + }, + { + "in": [ + "0x00", + "v3" + ], + "op": "slt", + "out": [ + "v4" + ] + } + ], + "type": "BuiltinCall" + }, + { + "exit": { + "returnValues": [], + "type": "FunctionReturn" + }, + "id": "Block2", + "instructions": [] + }, + { + "exit": { + "type": "Terminated" + }, + "id": "Block1", + "instructions": [ + { + "in": [], + "op": "revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b", + "out": [] + } + ], + "type": "FunctionCall" + } + ], + "entry": "Block0", + "returns": [], + "type": "Function" + }, + "abi_decode_tuple_t_uint256_fromMemory": { + "arguments": [ + "headStart", + "dataEnd" + ], + "blocks": [ + { + "exit": { + "cond": "v5", + "targets": [ + "Block2", + "Block1" + ], + "type": "ConditionalJump" + }, + "id": "Block0", + "instructions": [ + { + "in": [ + "v0", + "v1" + ], + "op": "sub", + "out": [ + "v4" + ] + }, + { + "in": [ + "0x20", + "v4" + ], + "op": "slt", + "out": [ + "v5" + ] + } + ], + "type": "BuiltinCall" + }, + { + "exit": { + "returnValues": [ + "v12" + ], + "type": "FunctionReturn" + }, + "id": "Block2", + "instructions": [ + { + "in": [ + "0x00", + "v0" + ], + "op": "add", + "out": [ + "v11" + ] + }, + { + "in": [ + "v1", + "v11" + ], + "op": "abi_decode_t_uint256_fromMemory", + "out": [ + "v12" + ] + } + ], + "type": "FunctionCall" + }, + { + "exit": { + "type": "Terminated" + }, + "id": "Block1", + "instructions": [ + { + "in": [], + "op": "revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b", + "out": [] + } + ], + "type": "FunctionCall" + } + ], + "entry": "Block0", + "returns": [ + "value0" + ], + "type": "Function" + }, + "abi_encode_t_uint256_to_t_uint256_fromStack": { + "arguments": [ + "value", + "pos" + ], + "blocks": [ + { + "exit": { + "returnValues": [], + "type": "FunctionReturn" + }, + "id": "Block0", + "instructions": [ + { + "in": [ + "v0" + ], + "op": "cleanup_t_uint256", + "out": [ + "v2" + ] + }, + { + "in": [ + "v2", + "v1" + ], + "op": "mstore", + "out": [] + } + ], + "type": "BuiltinCall" + } + ], + "entry": "Block0", + "returns": [], + "type": "Function" + }, + "abi_encode_tuple__to__fromStack": { + "arguments": [ + "headStart" + ], + "blocks": [ + { + "exit": { + "returnValues": [ + "v2" + ], + "type": "FunctionReturn" + }, + "id": "Block0", + "instructions": [ + { + "in": [ + "0x00", + "v0" + ], + "op": "add", + "out": [ + "v2" + ] + } + ], + "type": "BuiltinCall" + } + ], + "entry": "Block0", + "returns": [ + "tail" + ], + "type": "Function" + }, + "abi_encode_tuple_t_uint256__to_t_uint256__fromStack": { + "arguments": [ + "headStart", + "value0" + ], + "blocks": [ + { + "exit": { + "returnValues": [ + "v4" + ], + "type": "FunctionReturn" + }, + "id": "Block0", + "instructions": [ + { + "in": [ + "0x20", + "v0" + ], + "op": "add", + "out": [ + "v4" + ] + }, + { + "in": [ + "0x00", + "v0" + ], + "op": "add", + "out": [ + "v5" + ] + }, + { + "in": [ + "v5", + "v1" + ], + "op": "abi_encode_t_uint256_to_t_uint256_fromStack", + "out": [] + } + ], + "type": "FunctionCall" + } + ], + "entry": "Block0", + "returns": [ + "tail" + ], + "type": "Function" + }, + "allocate_unbounded": { + "arguments": [], + "blocks": [ + { + "exit": { + "returnValues": [ + "v2" + ], + "type": "FunctionReturn" + }, + "id": "Block0", + "instructions": [ + { + "in": [ + "0x40" + ], + "op": "mload", + "out": [ + "v2" + ] + } + ], + "type": "BuiltinCall" + } + ], + "entry": "Block0", + "returns": [ + "memPtr" + ], + "type": "Function" + }, + "cleanup_t_uint160": { + "arguments": [ + "value" + ], + "blocks": [ + { + "exit": { + "returnValues": [ + "v3" + ], + "type": "FunctionReturn" + }, + "id": "Block0", + "instructions": [ + { + "in": [ + "0xffffffffffffffffffffffffffffffffffffffff", + "v0" + ], + "op": "and", + "out": [ + "v3" + ] + } + ], + "type": "BuiltinCall" + } + ], + "entry": "Block0", + "returns": [ + "cleaned" + ], + "type": "Function" + }, + "cleanup_t_uint256": { + "arguments": [ + "value" + ], + "blocks": [ + { + "exit": { + "returnValues": [ + "v0" + ], + "type": "FunctionReturn" + }, + "id": "Block0", + "instructions": [] + } + ], + "entry": "Block0", + "returns": [ + "cleaned" + ], + "type": "Function" + }, + "convert_t_contract$_C_$19_to_t_address": { + "arguments": [ + "value" + ], + "blocks": [ + { + "exit": { + "returnValues": [ + "v2" + ], + "type": "FunctionReturn" + }, + "id": "Block0", + "instructions": [ + { + "in": [ + "v0" + ], + "op": "convert_t_uint160_to_t_address", + "out": [ + "v2" + ] + } + ], + "type": "FunctionCall" + } + ], + "entry": "Block0", + "returns": [ + "converted" + ], + "type": "Function" + }, + "convert_t_uint160_to_t_address": { + "arguments": [ + "value" + ], + "blocks": [ + { + "exit": { + "returnValues": [ + "v2" + ], + "type": "FunctionReturn" + }, + "id": "Block0", + "instructions": [ + { + "in": [ + "v0" + ], + "op": "convert_t_uint160_to_t_uint160", + "out": [ + "v2" + ] + } + ], + "type": "FunctionCall" + } + ], + "entry": "Block0", + "returns": [ + "converted" + ], + "type": "Function" + }, + "convert_t_uint160_to_t_uint160": { + "arguments": [ + "value" + ], + "blocks": [ + { + "exit": { + "returnValues": [ + "v4" + ], + "type": "FunctionReturn" + }, + "id": "Block0", + "instructions": [ + { + "in": [ + "v0" + ], + "op": "cleanup_t_uint160", + "out": [ + "v2" + ] + }, + { + "in": [ + "v2" + ], + "op": "identity", + "out": [ + "v3" + ] + }, + { + "in": [ + "v3" + ], + "op": "cleanup_t_uint160", + "out": [ + "v4" + ] + } + ], + "type": "FunctionCall" + } + ], + "entry": "Block0", + "returns": [ + "converted" + ], + "type": "Function" + }, + "external_fun_f_37": { + "arguments": [], + "blocks": [ + { + "exit": { + "cond": "v0", + "targets": [ + "Block2", + "Block1" + ], + "type": "ConditionalJump" + }, + "id": "Block0", + "instructions": [ + { + "in": [], + "op": "callvalue", + "out": [ + "v0" + ] + } + ], + "type": "BuiltinCall" + }, + { + "exit": { + "type": "Terminated" + }, + "id": "Block2", + "instructions": [ + { + "in": [], + "op": "calldatasize", + "out": [ + "v1" + ] + }, + { + "in": [ + "v1", + "0x04" + ], + "op": "abi_decode_tuple_", + "out": [] + }, + { + "in": [], + "op": "fun_f_37", + "out": [ + "v3" + ] + }, + { + "in": [], + "op": "allocate_unbounded", + "out": [ + "v4" + ] + }, + { + "in": [ + "v3", + "v4" + ], + "op": "abi_encode_tuple_t_uint256__to_t_uint256__fromStack", + "out": [ + "v5" + ] + }, + { + "in": [ + "v4", + "v5" + ], + "op": "sub", + "out": [ + "v6" + ] + }, + { + "in": [ + "v6", + "v4" + ], + "op": "return", + "out": [] + } + ], + "type": "BuiltinCall" + }, + { + "exit": { + "type": "Terminated" + }, + "id": "Block1", + "instructions": [ + { + "in": [], + "op": "revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb", + "out": [] + } + ], + "type": "FunctionCall" + } + ], + "entry": "Block0", + "returns": [], + "type": "Function" + }, + "finalize_allocation": { + "arguments": [ + "memPtr", + "size" + ], + "blocks": [ + { + "exit": { + "cond": "v7", + "targets": [ + "Block2", + "Block1" + ], + "type": "ConditionalJump" + }, + "id": "Block0", + "instructions": [ + { + "in": [ + "v1" + ], + "op": "round_up_to_mul_of_32", + "out": [ + "v2" + ] + }, + { + "in": [ + "v2", + "v0" + ], + "op": "add", + "out": [ + "v3" + ] + }, + { + "in": [ + "v0", + "v3" + ], + "op": "lt", + "out": [ + "v4" + ] + }, + { + "in": [ + "0xffffffffffffffff", + "v3" + ], + "op": "gt", + "out": [ + "v6" + ] + }, + { + "in": [ + "v4", + "v6" + ], + "op": "or", + "out": [ + "v7" + ] + } + ], + "type": "BuiltinCall" + }, + { + "exit": { + "returnValues": [], + "type": "FunctionReturn" + }, + "id": "Block2", + "instructions": [ + { + "in": [ + "v3", + "0x40" + ], + "op": "mstore", + "out": [] + } + ], + "type": "BuiltinCall" + }, + { + "exit": { + "type": "Terminated" + }, + "id": "Block1", + "instructions": [ + { + "in": [], + "op": "panic_error_0x41", + "out": [] + } + ], + "type": "FunctionCall" + } + ], + "entry": "Block0", + "returns": [], + "type": "Function" + }, + "fun_f_37": { + "arguments": [], + "blocks": [ + { + "exit": { + "cond": "v8", + "targets": [ + "Block2", + "Block1" + ], + "type": "ConditionalJump" + }, + "id": "Block0", + "instructions": [ + { + "in": [], + "op": "zero_value_for_split_t_uint256", + "out": [ + "v1" + ] + }, + { + "in": [], + "op": "allocate_unbounded", + "out": [ + "v2" + ] + }, + { + "builtinArgs": [ + "C_19" + ], + "in": [], + "op": "datasize", + "out": [ + "v3" + ] + }, + { + "in": [ + "v3", + "v2" + ], + "op": "add", + "out": [ + "v4" + ] + }, + { + "in": [ + "v2", + "v4" + ], + "op": "lt", + "out": [ + "v5" + ] + }, + { + "in": [ + "0xffffffffffffffff", + "v4" + ], + "op": "gt", + "out": [ + "v7" + ] + }, + { + "in": [ + "v5", + "v7" + ], + "op": "or", + "out": [ + "v8" + ] + } + ], + "type": "BuiltinCall" + }, + { + "exit": { + "cond": "v19", + "targets": [ + "Block5", + "Block4" + ], + "type": "ConditionalJump" + }, + "id": "Block2", + "instructions": [ + { + "builtinArgs": [ + "C_19" + ], + "in": [], + "op": "datasize", + "out": [ + "v9" + ] + }, + { + "builtinArgs": [ + "C_19" + ], + "in": [], + "op": "dataoffset", + "out": [ + "v10" + ] + }, + { + "in": [ + "v9", + "v10", + "v2" + ], + "op": "datacopy", + "out": [] + }, + { + "in": [ + "v4" + ], + "op": "abi_encode_tuple__to__fromStack", + "out": [ + "v16" + ] + }, + { + "in": [ + "v2", + "v16" + ], + "op": "sub", + "out": [ + "v17" + ] + }, + { + "in": [ + "v17", + "v2", + "0x00" + ], + "op": "create", + "out": [ + "v18" + ] + }, + { + "in": [ + "v18" + ], + "op": "iszero", + "out": [ + "v19" + ] + } + ], + "type": "BuiltinCall" + }, + { + "exit": { + "type": "Terminated" + }, + "id": "Block1", + "instructions": [ + { + "in": [], + "op": "panic_error_0x41", + "out": [] + } + ], + "type": "FunctionCall" + }, + { + "exit": { + "cond": "v33", + "targets": [ + "Block8", + "Block7" + ], + "type": "ConditionalJump" + }, + "id": "Block5", + "instructions": [ + { + "in": [ + "v18" + ], + "op": "convert_t_contract$_C_$19_to_t_address", + "out": [ + "v22" + ] + }, + { + "in": [], + "op": "allocate_unbounded", + "out": [ + "v24" + ] + }, + { + "in": [ + "0x26121ff0" + ], + "op": "shift_left_224", + "out": [ + "v25" + ] + }, + { + "in": [ + "v25", + "v24" + ], + "op": "mstore", + "out": [] + }, + { + "in": [ + "0x04", + "v24" + ], + "op": "add", + "out": [ + "v27" + ] + }, + { + "in": [ + "v27" + ], + "op": "abi_encode_tuple__to__fromStack", + "out": [ + "v28" + ] + }, + { + "in": [ + "v24", + "v28" + ], + "op": "sub", + "out": [ + "v30" + ] + }, + { + "in": [], + "op": "gas", + "out": [ + "v31" + ] + }, + { + "in": [ + "0x20", + "v24", + "v30", + "v24", + "v22", + "v31" + ], + "op": "staticcall", + "out": [ + "v32" + ] + }, + { + "in": [ + "v32" + ], + "op": "iszero", + "out": [ + "v33" + ] + } + ], + "type": "BuiltinCall" + }, + { + "exit": { + "type": "Terminated" + }, + "id": "Block4", + "instructions": [ + { + "in": [], + "op": "revert_forward_1", + "out": [] + } + ], + "type": "FunctionCall" + }, + { + "exit": { + "cond": "v32", + "targets": [ + "Block11", + "Block10" + ], + "type": "ConditionalJump" + }, + "id": "Block8", + "instructions": [] + }, + { + "exit": { + "type": "Terminated" + }, + "id": "Block7", + "instructions": [ + { + "in": [], + "op": "revert_forward_1", + "out": [] + } + ], + "type": "FunctionCall" + }, + { + "entries": [ + "Block8", + "Block13" + ], + "exit": { + "returnValues": [ + "v45" + ], + "type": "FunctionReturn" + }, + "id": "Block11", + "instructions": [ + { + "in": [ + "0x00", + "v44" + ], + "op": "PhiFunction", + "out": [ + "v45" + ] + } + ] + }, + { + "exit": { + "cond": "v37", + "targets": [ + "Block13", + "Block12" + ], + "type": "ConditionalJump" + }, + "id": "Block10", + "instructions": [ + { + "in": [], + "op": "returndatasize", + "out": [ + "v36" + ] + }, + { + "in": [ + "v36", + "0x20" + ], + "op": "gt", + "out": [ + "v37" + ] + } + ], + "type": "BuiltinCall" + }, + { + "entries": [ + "Block10", + "Block12" + ], + "exit": { + "targets": [ + "Block11" + ], + "type": "Jump" + }, + "id": "Block13", + "instructions": [ + { + "in": [ + "0x20", + "v38" + ], + "op": "PhiFunction", + "out": [ + "v39" + ] + }, + { + "in": [ + "v39", + "v24" + ], + "op": "finalize_allocation", + "out": [] + }, + { + "in": [ + "v39", + "v24" + ], + "op": "add", + "out": [ + "v43" + ] + }, + { + "in": [ + "v43", + "v24" + ], + "op": "abi_decode_tuple_t_uint256_fromMemory", + "out": [ + "v44" + ] + } + ], + "type": "FunctionCall" + }, + { + "exit": { + "targets": [ + "Block13" + ], + "type": "Jump" + }, + "id": "Block12", + "instructions": [ + { + "in": [], + "op": "returndatasize", + "out": [ + "v38" + ] + } + ], + "type": "BuiltinCall" + } + ], + "entry": "Block0", + "returns": [ + "var__22" + ], + "type": "Function" + }, + "identity": { + "arguments": [ + "value" + ], + "blocks": [ + { + "exit": { + "returnValues": [ + "v0" + ], + "type": "FunctionReturn" + }, + "id": "Block0", + "instructions": [] + } + ], + "entry": "Block0", + "returns": [ + "ret" + ], + "type": "Function" + }, + "panic_error_0x41": { + "arguments": [], + "blocks": [ + { + "exit": { + "type": "Terminated" + }, + "id": "Block0", + "instructions": [ + { + "in": [ + "0x4e487b7100000000000000000000000000000000000000000000000000000000", + "0x00" + ], + "op": "mstore", + "out": [] + }, + { + "in": [ + "0x41", + "0x04" + ], + "op": "mstore", + "out": [] + }, + { + "in": [ + "0x24", + "0x00" + ], + "op": "revert", + "out": [] + } + ], + "type": "BuiltinCall" + } + ], + "entry": "Block0", + "returns": [], + "type": "Function" + }, + "revert_error_0cc013b6b3b6beabea4e3a74a6d380f0df81852ca99887912475e1f66b2a2c20": { + "arguments": [], + "blocks": [ + { + "exit": { + "type": "Terminated" + }, + "id": "Block0", + "instructions": [ + { + "in": [ + "0x00", + "0x00" + ], + "op": "revert", + "out": [] + } + ], + "type": "BuiltinCall" + } + ], + "entry": "Block0", + "returns": [], + "type": "Function" + }, + "revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74": { + "arguments": [], + "blocks": [ + { + "exit": { + "type": "Terminated" + }, + "id": "Block0", + "instructions": [ + { + "in": [ + "0x00", + "0x00" + ], + "op": "revert", + "out": [] + } + ], + "type": "BuiltinCall" + } + ], + "entry": "Block0", + "returns": [], + "type": "Function" + }, + "revert_error_c1322bf8034eace5e0b5c7295db60986aa89aae5e0ea0873e4689e076861a5db": { + "arguments": [], + "blocks": [ + { + "exit": { + "type": "Terminated" + }, + "id": "Block0", + "instructions": [ + { + "in": [ + "0x00", + "0x00" + ], + "op": "revert", + "out": [] + } + ], + "type": "BuiltinCall" + } + ], + "entry": "Block0", + "returns": [], + "type": "Function" + }, + "revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb": { + "arguments": [], + "blocks": [ + { + "exit": { + "type": "Terminated" + }, + "id": "Block0", + "instructions": [ + { + "in": [ + "0x00", + "0x00" + ], + "op": "revert", + "out": [] + } + ], + "type": "BuiltinCall" + } + ], + "entry": "Block0", + "returns": [], + "type": "Function" + }, + "revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b": { + "arguments": [], + "blocks": [ + { + "exit": { + "type": "Terminated" + }, + "id": "Block0", + "instructions": [ + { + "in": [ + "0x00", + "0x00" + ], + "op": "revert", + "out": [] + } + ], + "type": "BuiltinCall" + } + ], + "entry": "Block0", + "returns": [], + "type": "Function" + }, + "revert_forward_1": { + "arguments": [], + "blocks": [ + { + "exit": { + "type": "Terminated" + }, + "id": "Block0", + "instructions": [ + { + "in": [], + "op": "allocate_unbounded", + "out": [ + "v0" + ] + }, + { + "in": [], + "op": "returndatasize", + "out": [ + "v1" + ] + }, + { + "in": [ + "v1", + "0x00", + "v0" + ], + "op": "returndatacopy", + "out": [] + }, + { + "in": [], + "op": "returndatasize", + "out": [ + "v3" + ] + }, + { + "in": [ + "v3", + "v0" + ], + "op": "revert", + "out": [] + } + ], + "type": "BuiltinCall" + } + ], + "entry": "Block0", + "returns": [], + "type": "Function" + }, + "round_up_to_mul_of_32": { + "arguments": [ + "value" + ], + "blocks": [ + { + "exit": { + "returnValues": [ + "v5" + ], + "type": "FunctionReturn" + }, + "id": "Block0", + "instructions": [ + { + "in": [ + "0x1f" + ], + "op": "not", + "out": [ + "v3" + ] + }, + { + "in": [ + "0x1f", + "v0" + ], + "op": "add", + "out": [ + "v4" + ] + }, + { + "in": [ + "v3", + "v4" + ], + "op": "and", + "out": [ + "v5" + ] + } + ], + "type": "BuiltinCall" + } + ], + "entry": "Block0", + "returns": [ + "result" + ], + "type": "Function" + }, + "shift_left_224": { + "arguments": [ + "value" + ], + "blocks": [ + { + "exit": { + "returnValues": [ + "v3" + ], + "type": "FunctionReturn" + }, + "id": "Block0", + "instructions": [ + { + "in": [ + "v0", + "0xe0" + ], + "op": "shl", + "out": [ + "v3" + ] + } + ], + "type": "BuiltinCall" + } + ], + "entry": "Block0", + "returns": [ + "newValue" + ], + "type": "Function" + }, + "shift_right_224_unsigned": { + "arguments": [ + "value" + ], + "blocks": [ + { + "exit": { + "returnValues": [ + "v3" + ], + "type": "FunctionReturn" + }, + "id": "Block0", + "instructions": [ + { + "in": [ + "v0", + "0xe0" + ], + "op": "shr", + "out": [ + "v3" + ] + } + ], + "type": "BuiltinCall" + } + ], + "entry": "Block0", + "returns": [ + "newValue" + ], + "type": "Function" + }, + "validator_revert_t_uint256": { + "arguments": [ + "value" + ], + "blocks": [ + { + "exit": { + "cond": "v3", + "targets": [ + "Block2", + "Block1" + ], + "type": "ConditionalJump" + }, + "id": "Block0", + "instructions": [ + { + "in": [ + "v0" + ], + "op": "cleanup_t_uint256", + "out": [ + "v1" + ] + }, + { + "in": [ + "v1", + "v0" + ], + "op": "eq", + "out": [ + "v2" + ] + }, + { + "in": [ + "v2" + ], + "op": "iszero", + "out": [ + "v3" + ] + } + ], + "type": "BuiltinCall" + }, + { + "exit": { + "returnValues": [], + "type": "FunctionReturn" + }, + "id": "Block2", + "instructions": [] + }, + { + "exit": { + "type": "Terminated" + }, + "id": "Block1", + "instructions": [ + { + "in": [ + "0x00", + "0x00" + ], + "op": "revert", + "out": [] + } + ], + "type": "BuiltinCall" + } + ], + "entry": "Block0", + "returns": [], + "type": "Function" + }, + "zero_value_for_split_t_uint256": { + "arguments": [], + "blocks": [ + { + "exit": { + "returnValues": [ + "0x00" + ], + "type": "FunctionReturn" + }, + "id": "Block0", + "instructions": [] + } + ], + "entry": "Block0", + "returns": [ + "ret" + ], + "type": "Function" + } + } + }, + "subObjects": { + "C_19": { + "blocks": [ + { + "exit": { + "cond": "v2", + "targets": [ + "Block2", + "Block1" + ], + "type": "ConditionalJump" + }, + "id": "Block0", + "instructions": [ + { + "builtinArgs": [ + "128" + ], + "in": [], + "op": "memoryguard", + "out": [ + "v0" + ] + }, + { + "in": [ + "v0", + "0x40" + ], + "op": "mstore", + "out": [] + }, + { + "in": [], + "op": "callvalue", + "out": [ + "v2" + ] + } + ], + "type": "BuiltinCall" + }, + { + "exit": { + "type": "Terminated" + }, + "id": "Block2", + "instructions": [ + { + "in": [], + "op": "constructor_C_19", + "out": [] + }, + { + "in": [], + "op": "allocate_unbounded", + "out": [ + "v3" + ] + }, + { + "builtinArgs": [ + "C_19_deployed" + ], + "in": [], + "op": "datasize", + "out": [ + "v4" + ] + }, + { + "builtinArgs": [ + "C_19_deployed" + ], + "in": [], + "op": "dataoffset", + "out": [ + "v5" + ] + }, + { + "in": [ + "v4", + "v5", + "v3" + ], + "op": "codecopy", + "out": [] + }, + { + "builtinArgs": [ + "C_19_deployed" + ], + "in": [], + "op": "datasize", + "out": [ + "v6" + ] + }, + { + "in": [ + "v6", + "v3" + ], + "op": "return", + "out": [] + } + ], + "type": "BuiltinCall" + }, + { + "exit": { + "type": "Terminated" + }, + "id": "Block1", + "instructions": [ + { + "in": [], + "op": "revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb", + "out": [] + } + ], + "type": "FunctionCall" + } + ], + "functions": { + "allocate_unbounded": { + "arguments": [], + "blocks": [ + { + "exit": { + "returnValues": [ + "v2" + ], + "type": "FunctionReturn" + }, + "id": "Block0", + "instructions": [ + { + "in": [ + "0x40" + ], + "op": "mload", + "out": [ + "v2" + ] + } + ], + "type": "BuiltinCall" + } + ], + "entry": "Block0", + "returns": [ + "memPtr" + ], + "type": "Function" + }, + "constructor_C_19": { + "arguments": [], + "blocks": [ + { + "exit": { + "returnValues": [], + "type": "FunctionReturn" + }, + "id": "Block0", + "instructions": [ + { + "in": [], + "op": "constructor_I_7", + "out": [] + } + ], + "type": "FunctionCall" + } + ], + "entry": "Block0", + "returns": [], + "type": "Function" + }, + "constructor_I_7": { + "arguments": [], + "blocks": [ + { + "exit": { + "returnValues": [], + "type": "FunctionReturn" + }, + "id": "Block0", + "instructions": [] + } + ], + "entry": "Block0", + "returns": [], + "type": "Function" + }, + "revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb": { + "arguments": [], + "blocks": [ + { + "exit": { + "type": "Terminated" + }, + "id": "Block0", + "instructions": [ + { + "in": [ + "0x00", + "0x00" + ], + "op": "revert", + "out": [] + } + ], + "type": "BuiltinCall" + } + ], + "entry": "Block0", + "returns": [], + "type": "Function" + } + } + }, + "subObjects": { + "C_19_deployed": { + "blocks": [ + { + "exit": { + "cond": "v5", + "targets": [ + "Block2", + "Block1" + ], + "type": "ConditionalJump" + }, + "id": "Block0", + "instructions": [ + { + "builtinArgs": [ + "128" + ], + "in": [], + "op": "memoryguard", + "out": [ + "v0" + ] + }, + { + "in": [ + "v0", + "0x40" + ], + "op": "mstore", + "out": [] + }, + { + "in": [], + "op": "calldatasize", + "out": [ + "v3" + ] + }, + { + "in": [ + "0x04", + "v3" + ], + "op": "lt", + "out": [ + "v4" + ] + }, + { + "in": [ + "v4" + ], + "op": "iszero", + "out": [ + "v5" + ] + } + ], + "type": "BuiltinCall" + }, + { + "exit": { + "type": "Terminated" + }, + "id": "Block2", + "instructions": [ + { + "in": [], + "op": "revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74", + "out": [] + } + ], + "type": "FunctionCall" + }, + { + "exit": { + "cond": "v9", + "targets": [ + "Block5", + "Block4" + ], + "type": "ConditionalJump" + }, + "id": "Block1", + "instructions": [ + { + "in": [ + "0x00" + ], + "op": "calldataload", + "out": [ + "v7" + ] + }, + { + "in": [ + "v7" + ], + "op": "shift_right_224_unsigned", + "out": [ + "v8" + ] + }, + { + "in": [ + "0x26121ff0", + "v8" + ], + "op": "eq", + "out": [ + "v9" + ] + } + ], + "type": "BuiltinCall" + }, + { + "exit": { + "targets": [ + "Block3" + ], + "type": "Jump" + }, + "id": "Block5", + "instructions": [] + }, + { + "exit": { + "type": "Terminated" + }, + "id": "Block4", + "instructions": [ + { + "in": [], + "op": "external_fun_f_18", + "out": [] + } + ], + "type": "FunctionCall" + }, + { + "exit": { + "targets": [ + "Block2" + ], + "type": "Jump" + }, + "id": "Block3", + "instructions": [] + } + ], + "functions": { + "abi_decode_tuple_": { + "arguments": [ + "headStart", + "dataEnd" + ], + "blocks": [ + { + "exit": { + "cond": "v4", + "targets": [ + "Block2", + "Block1" + ], + "type": "ConditionalJump" + }, + "id": "Block0", + "instructions": [ + { + "in": [ + "v0", + "v1" + ], + "op": "sub", + "out": [ + "v3" + ] + }, + { + "in": [ + "0x00", + "v3" + ], + "op": "slt", + "out": [ + "v4" + ] + } + ], + "type": "BuiltinCall" + }, + { + "exit": { + "returnValues": [], + "type": "FunctionReturn" + }, + "id": "Block2", + "instructions": [] + }, + { + "exit": { + "type": "Terminated" + }, + "id": "Block1", + "instructions": [ + { + "in": [], + "op": "revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b", + "out": [] + } + ], + "type": "FunctionCall" + } + ], + "entry": "Block0", + "returns": [], + "type": "Function" + }, + "abi_encode_t_uint256_to_t_uint256_fromStack": { + "arguments": [ + "value", + "pos" + ], + "blocks": [ + { + "exit": { + "returnValues": [], + "type": "FunctionReturn" + }, + "id": "Block0", + "instructions": [ + { + "in": [ + "v0" + ], + "op": "cleanup_t_uint256", + "out": [ + "v2" + ] + }, + { + "in": [ + "v2", + "v1" + ], + "op": "mstore", + "out": [] + } + ], + "type": "BuiltinCall" + } + ], + "entry": "Block0", + "returns": [], + "type": "Function" + }, + "abi_encode_tuple_t_uint256__to_t_uint256__fromStack": { + "arguments": [ + "headStart", + "value0" + ], + "blocks": [ + { + "exit": { + "returnValues": [ + "v4" + ], + "type": "FunctionReturn" + }, + "id": "Block0", + "instructions": [ + { + "in": [ + "0x20", + "v0" + ], + "op": "add", + "out": [ + "v4" + ] + }, + { + "in": [ + "0x00", + "v0" + ], + "op": "add", + "out": [ + "v5" + ] + }, + { + "in": [ + "v5", + "v1" + ], + "op": "abi_encode_t_uint256_to_t_uint256_fromStack", + "out": [] + } + ], + "type": "FunctionCall" + } + ], + "entry": "Block0", + "returns": [ + "tail" + ], + "type": "Function" + }, + "allocate_unbounded": { + "arguments": [], + "blocks": [ + { + "exit": { + "returnValues": [ + "v2" + ], + "type": "FunctionReturn" + }, + "id": "Block0", + "instructions": [ + { + "in": [ + "0x40" + ], + "op": "mload", + "out": [ + "v2" + ] + } + ], + "type": "BuiltinCall" + } + ], + "entry": "Block0", + "returns": [ + "memPtr" + ], + "type": "Function" + }, + "cleanup_t_rational_42_by_1": { + "arguments": [ + "value" + ], + "blocks": [ + { + "exit": { + "returnValues": [ + "v0" + ], + "type": "FunctionReturn" + }, + "id": "Block0", + "instructions": [] + } + ], + "entry": "Block0", + "returns": [ + "cleaned" + ], + "type": "Function" + }, + "cleanup_t_uint256": { + "arguments": [ + "value" + ], + "blocks": [ + { + "exit": { + "returnValues": [ + "v0" + ], + "type": "FunctionReturn" + }, + "id": "Block0", + "instructions": [] + } + ], + "entry": "Block0", + "returns": [ + "cleaned" + ], + "type": "Function" + }, + "convert_t_rational_42_by_1_to_t_uint256": { + "arguments": [ + "value" + ], + "blocks": [ + { + "exit": { + "returnValues": [ + "v4" + ], + "type": "FunctionReturn" + }, + "id": "Block0", + "instructions": [ + { + "in": [ + "v0" + ], + "op": "cleanup_t_rational_42_by_1", + "out": [ + "v2" + ] + }, + { + "in": [ + "v2" + ], + "op": "identity", + "out": [ + "v3" + ] + }, + { + "in": [ + "v3" + ], + "op": "cleanup_t_uint256", + "out": [ + "v4" + ] + } + ], + "type": "FunctionCall" + } + ], + "entry": "Block0", + "returns": [ + "converted" + ], + "type": "Function" + }, + "external_fun_f_18": { + "arguments": [], + "blocks": [ + { + "exit": { + "cond": "v0", + "targets": [ + "Block2", + "Block1" + ], + "type": "ConditionalJump" + }, + "id": "Block0", + "instructions": [ + { + "in": [], + "op": "callvalue", + "out": [ + "v0" + ] + } + ], + "type": "BuiltinCall" + }, + { + "exit": { + "type": "Terminated" + }, + "id": "Block2", + "instructions": [ + { + "in": [], + "op": "calldatasize", + "out": [ + "v1" + ] + }, + { + "in": [ + "v1", + "0x04" + ], + "op": "abi_decode_tuple_", + "out": [] + }, + { + "in": [], + "op": "fun_f_18", + "out": [ + "v3" + ] + }, + { + "in": [], + "op": "allocate_unbounded", + "out": [ + "v4" + ] + }, + { + "in": [ + "v3", + "v4" + ], + "op": "abi_encode_tuple_t_uint256__to_t_uint256__fromStack", + "out": [ + "v5" + ] + }, + { + "in": [ + "v4", + "v5" + ], + "op": "sub", + "out": [ + "v6" + ] + }, + { + "in": [ + "v6", + "v4" + ], + "op": "return", + "out": [] + } + ], + "type": "BuiltinCall" + }, + { + "exit": { + "type": "Terminated" + }, + "id": "Block1", + "instructions": [ + { + "in": [], + "op": "revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb", + "out": [] + } + ], + "type": "FunctionCall" + } + ], + "entry": "Block0", + "returns": [], + "type": "Function" + }, + "fun_f_18": { + "arguments": [], + "blocks": [ + { + "exit": { + "returnValues": [ + "v3" + ], + "type": "FunctionReturn" + }, + "id": "Block0", + "instructions": [ + { + "in": [], + "op": "zero_value_for_split_t_uint256", + "out": [ + "v1" + ] + }, + { + "in": [ + "0x2a" + ], + "op": "convert_t_rational_42_by_1_to_t_uint256", + "out": [ + "v3" + ] + } + ], + "type": "FunctionCall" + } + ], + "entry": "Block0", + "returns": [ + "var__13" + ], + "type": "Function" + }, + "identity": { + "arguments": [ + "value" + ], + "blocks": [ + { + "exit": { + "returnValues": [ + "v0" + ], + "type": "FunctionReturn" + }, + "id": "Block0", + "instructions": [] + } + ], + "entry": "Block0", + "returns": [ + "ret" + ], + "type": "Function" + }, + "revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74": { + "arguments": [], + "blocks": [ + { + "exit": { + "type": "Terminated" + }, + "id": "Block0", + "instructions": [ + { + "in": [ + "0x00", + "0x00" + ], + "op": "revert", + "out": [] + } + ], + "type": "BuiltinCall" + } + ], + "entry": "Block0", + "returns": [], + "type": "Function" + }, + "revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb": { + "arguments": [], + "blocks": [ + { + "exit": { + "type": "Terminated" + }, + "id": "Block0", + "instructions": [ + { + "in": [ + "0x00", + "0x00" + ], + "op": "revert", + "out": [] + } + ], + "type": "BuiltinCall" + } + ], + "entry": "Block0", + "returns": [], + "type": "Function" + }, + "revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b": { + "arguments": [], + "blocks": [ + { + "exit": { + "type": "Terminated" + }, + "id": "Block0", + "instructions": [ + { + "in": [ + "0x00", + "0x00" + ], + "op": "revert", + "out": [] + } + ], + "type": "BuiltinCall" + } + ], + "entry": "Block0", + "returns": [], + "type": "Function" + }, + "shift_right_224_unsigned": { + "arguments": [ + "value" + ], + "blocks": [ + { + "exit": { + "returnValues": [ + "v3" + ], + "type": "FunctionReturn" + }, + "id": "Block0", + "instructions": [ + { + "in": [ + "v0", + "0xe0" + ], + "op": "shr", + "out": [ + "v3" + ] + } + ], + "type": "BuiltinCall" + } + ], + "entry": "Block0", + "returns": [ + "newValue" + ], + "type": "Function" + }, + "zero_value_for_split_t_uint256": { + "arguments": [], + "blocks": [ + { + "exit": { + "returnValues": [ + "0x00" + ], + "type": "FunctionReturn" + }, + "id": "Block0", + "instructions": [] + } + ], + "entry": "Block0", + "returns": [ + "ret" + ], + "type": "Function" + } + } + }, + "subObjects": {}, + "type": "subObject" + }, + "type": "subObject" + }, + "type": "subObject" + }, + "type": "Object" +} + +======= yul_cfg_json_export/input.sol:I ======= +Yul Control Flow Graph: +null From 6c1ed9d0ebb7629f29bd581579c5751eb03988b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Wed, 16 Oct 2024 17:31:00 +0200 Subject: [PATCH 0515/1022] Add profiler probes for steps outside the sequence --- libyul/optimiser/Suite.cpp | 54 +++++++++++++++++++++++++++----------- 1 file changed, 38 insertions(+), 16 deletions(-) diff --git a/libyul/optimiser/Suite.cpp b/libyul/optimiser/Suite.cpp index 76f0368ab9ca..9509a4b86d4e 100644 --- a/libyul/optimiser/Suite.cpp +++ b/libyul/optimiser/Suite.cpp @@ -108,11 +108,15 @@ void OptimiserSuite::run( std::set reservedIdentifiers = _externallyUsedIdentifiers; reservedIdentifiers += _dialect.fixedFunctionNames(); - auto astRoot = std::get(Disambiguator( - _dialect, - *_object.analysisInfo, - reservedIdentifiers - )(_object.code()->root())); + Block astRoot; + { + PROFILER_PROBE("Disambiguator", probe); + astRoot = std::get(Disambiguator( + _dialect, + *_object.analysisInfo, + reservedIdentifiers + )(_object.code()->root())); + } NameDispenser dispenser{_dialect, astRoot, reservedIdentifiers}; OptimiserStepContext context{_dialect, dispenser, reservedIdentifiers, _expectedExecutionsPerDeployment}; @@ -123,7 +127,10 @@ void OptimiserSuite::run( // ForLoopInitRewriter. Run them first to be able to run arbitrary sequences safely. suite.runSequence("hgfo", astRoot); - NameSimplifier::run(suite.m_context, astRoot); + { + PROFILER_PROBE("NameSimplifier", probe); + NameSimplifier::run(suite.m_context, astRoot); + } // Now the user-supplied part suite.runSequence(_optimisationSequence, astRoot); @@ -135,6 +142,7 @@ void OptimiserSuite::run( // message once we perform code generation. if (!usesOptimizedCodeGenerator) { + PROFILER_PROBE("StackCompressor", probe); _object.setCode(std::make_shared(std::move(astRoot))); astRoot = std::get<1>(StackCompressor::run( _dialect, @@ -154,32 +162,46 @@ void OptimiserSuite::run( if (evmDialect) { yulAssert(_meter, ""); - ConstantOptimiser{*evmDialect, *_meter}(astRoot); + { + PROFILER_PROBE("ConstantOptimiser", probe); + ConstantOptimiser{*evmDialect, *_meter}(astRoot); + } if (usesOptimizedCodeGenerator) { - _object.setCode(std::make_shared(std::move(astRoot))); - astRoot = std::get<1>(StackCompressor::run( - _dialect, - _object, - _optimizeStackAllocation, - stackCompressorMaxIterations - )); + { + PROFILER_PROBE("StackCompressor", probe); + _object.setCode(std::make_shared(std::move(astRoot))); + astRoot = std::get<1>(StackCompressor::run( + _dialect, + _object, + _optimizeStackAllocation, + stackCompressorMaxIterations + )); + } if (evmDialect->providesObjectAccess()) { + PROFILER_PROBE("StackLimitEvader", probe); _object.setCode(std::make_shared(std::move(astRoot))); astRoot = StackLimitEvader::run(suite.m_context, _object); } } else if (evmDialect->providesObjectAccess() && _optimizeStackAllocation) { + PROFILER_PROBE("StackLimitEvader", probe); _object.setCode(std::make_shared(std::move(astRoot))); astRoot = StackLimitEvader::run(suite.m_context, _object); } } dispenser.reset(astRoot); - NameSimplifier::run(suite.m_context, astRoot); - VarNameCleaner::run(suite.m_context, astRoot); + { + PROFILER_PROBE("NameSimplifier", probe); + NameSimplifier::run(suite.m_context, astRoot); + } + { + PROFILER_PROBE("VarNameCleaner", probe); + VarNameCleaner::run(suite.m_context, astRoot); + } _object.setCode(std::make_shared(std::move(astRoot))); _object.analysisInfo = std::make_shared(AsmAnalyzer::analyzeStrictAssertCorrect(_dialect, _object)); From 07dd5475139f2a4d9c97fe509b083785a6ce07f1 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Thu, 17 Oct 2024 14:53:07 +0200 Subject: [PATCH 0516/1022] Yul optimizer suite: Call name simplifier only once --- libyul/optimiser/Suite.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/libyul/optimiser/Suite.cpp b/libyul/optimiser/Suite.cpp index 9509a4b86d4e..1e4c3e21e430 100644 --- a/libyul/optimiser/Suite.cpp +++ b/libyul/optimiser/Suite.cpp @@ -127,10 +127,6 @@ void OptimiserSuite::run( // ForLoopInitRewriter. Run them first to be able to run arbitrary sequences safely. suite.runSequence("hgfo", astRoot); - { - PROFILER_PROBE("NameSimplifier", probe); - NameSimplifier::run(suite.m_context, astRoot); - } // Now the user-supplied part suite.runSequence(_optimisationSequence, astRoot); From a39a725f31adccfe8f4bf03602d0bc9152fe5400 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Wed, 16 Oct 2024 16:53:15 +0200 Subject: [PATCH 0517/1022] Yul: Use builtin handle struct for builtin referencing --- libsolidity/analysis/ControlFlowBuilder.cpp | 9 +- libsolidity/analysis/ViewPureChecker.cpp | 6 +- .../codegen/ir/IRGeneratorForStatements.cpp | 2 +- .../codegen/IRGeneratorForStatements.cpp | 2 +- libyul/AsmAnalysis.cpp | 29 +- libyul/AsmParser.cpp | 15 +- libyul/Builtins.h | 35 ++ libyul/CMakeLists.txt | 1 + libyul/ControlFlowSideEffectsCollector.cpp | 4 +- libyul/Dialect.h | 43 +- libyul/YulControlFlowGraphExporter.cpp | 2 +- libyul/backends/evm/ConstantOptimiser.cpp | 16 +- .../backends/evm/ControlFlowGraphBuilder.cpp | 17 +- libyul/backends/evm/EVMCodeTransform.cpp | 7 +- libyul/backends/evm/EVMDialect.cpp | 471 ++++++++++-------- libyul/backends/evm/EVMDialect.h | 46 +- libyul/backends/evm/EVMMetrics.cpp | 6 +- libyul/backends/evm/NoOutputAssembly.cpp | 25 +- libyul/backends/evm/SSAControlFlowGraph.cpp | 2 +- .../evm/SSAControlFlowGraphBuilder.cpp | 15 +- .../CommonSubexpressionEliminator.cpp | 5 +- libyul/optimiser/ControlFlowSimplifier.cpp | 14 +- libyul/optimiser/DataFlowAnalyzer.cpp | 18 +- libyul/optimiser/Disambiguator.cpp | 2 +- libyul/optimiser/ExpressionSplitter.cpp | 4 +- libyul/optimiser/ForLoopConditionIntoBody.cpp | 2 +- .../optimiser/ForLoopConditionOutOfBody.cpp | 4 +- libyul/optimiser/FullInliner.cpp | 2 +- libyul/optimiser/FunctionSpecializer.cpp | 2 +- libyul/optimiser/LoadResolver.cpp | 2 +- libyul/optimiser/NameSimplifier.cpp | 2 +- libyul/optimiser/OptimizerUtilities.cpp | 6 +- libyul/optimiser/Semantics.cpp | 16 +- libyul/optimiser/SimplificationRules.cpp | 6 +- libyul/optimiser/StackToMemoryMover.cpp | 14 +- libyul/optimiser/UnusedAssignEliminator.cpp | 4 +- libyul/optimiser/UnusedPruner.cpp | 2 +- libyul/optimiser/UnusedStoreEliminator.cpp | 8 +- test/libyul/Parser.cpp | 16 +- .../EVMInstructionInterpreter.cpp | 2 +- test/tools/yulInterpreter/Interpreter.cpp | 20 +- 41 files changed, 535 insertions(+), 369 deletions(-) create mode 100644 libyul/Builtins.h diff --git a/libsolidity/analysis/ControlFlowBuilder.cpp b/libsolidity/analysis/ControlFlowBuilder.cpp index 7bc0ebc7bf58..a42cec172d49 100644 --- a/libsolidity/analysis/ControlFlowBuilder.cpp +++ b/libsolidity/analysis/ControlFlowBuilder.cpp @@ -582,13 +582,14 @@ void ControlFlowBuilder::operator()(yul::FunctionCall const& _functionCall) solAssert(m_currentNode && m_inlineAssembly, ""); yul::ASTWalker::operator()(_functionCall); - if (auto const *builtinFunction = m_inlineAssembly->dialect().builtin(_functionCall.functionName.name)) + if (auto const& builtinHandle = m_inlineAssembly->dialect().findBuiltin(_functionCall.functionName.name.str())) { - if (builtinFunction->controlFlowSideEffects.canTerminate) + auto const& builtinFunction = m_inlineAssembly->dialect().builtin(*builtinHandle); + if (builtinFunction.controlFlowSideEffects.canTerminate) connect(m_currentNode, m_transactionReturnNode); - if (builtinFunction->controlFlowSideEffects.canRevert) + if (builtinFunction.controlFlowSideEffects.canRevert) connect(m_currentNode, m_revertNode); - if (!builtinFunction->controlFlowSideEffects.canContinue) + if (!builtinFunction.controlFlowSideEffects.canContinue) m_currentNode = newLabel(); } } diff --git a/libsolidity/analysis/ViewPureChecker.cpp b/libsolidity/analysis/ViewPureChecker.cpp index 3b16205e7d86..6a3a902edffe 100644 --- a/libsolidity/analysis/ViewPureChecker.cpp +++ b/libsolidity/analysis/ViewPureChecker.cpp @@ -66,9 +66,9 @@ class AssemblyViewPureChecker void operator()(yul::FunctionCall const& _funCall) { if (yul::EVMDialect const* dialect = dynamic_cast(&m_dialect)) - if (yul::BuiltinFunctionForEVM const* fun = dialect->builtin(_funCall.functionName.name)) - if (fun->instruction) - checkInstruction(nativeLocationOf(_funCall), *fun->instruction); + if (std::optional builtinHandle = dialect->findBuiltin(_funCall.functionName.name.str())) + if (auto const& instruction = dialect->builtin(*builtinHandle).instruction) + checkInstruction(nativeLocationOf(_funCall), *instruction); for (auto const& arg: _funCall.arguments) std::visit(*this, arg); diff --git a/libsolidity/codegen/ir/IRGeneratorForStatements.cpp b/libsolidity/codegen/ir/IRGeneratorForStatements.cpp index 911230d224ce..69d24cf42669 100644 --- a/libsolidity/codegen/ir/IRGeneratorForStatements.cpp +++ b/libsolidity/codegen/ir/IRGeneratorForStatements.cpp @@ -84,7 +84,7 @@ struct CopyTranslate: public yul::ASTCopier // from the Yul dialect we are compiling to. So we are assuming here that the builtin // functions are identical. This should not be a problem for now since everything // is EVM anyway. - if (m_dialect.builtin(_name)) + if (m_dialect.findBuiltin(_name.str())) return _name; else return yul::YulName{"usr$" + _name.str()}; diff --git a/libsolidity/experimental/codegen/IRGeneratorForStatements.cpp b/libsolidity/experimental/codegen/IRGeneratorForStatements.cpp index 772e8575dbfd..a9e4fa9313da 100644 --- a/libsolidity/experimental/codegen/IRGeneratorForStatements.cpp +++ b/libsolidity/experimental/codegen/IRGeneratorForStatements.cpp @@ -72,7 +72,7 @@ struct CopyTranslate: public yul::ASTCopier yul::YulName translateIdentifier(yul::YulName _name) override { - if (m_dialect.builtin(_name)) + if (m_dialect.findBuiltin(_name.str())) return _name; else return yul::YulName{"usr$" + _name.str()}; diff --git a/libyul/AsmAnalysis.cpp b/libyul/AsmAnalysis.cpp index 9eb5465475cb..84eb39daa834 100644 --- a/libyul/AsmAnalysis.cpp +++ b/libyul/AsmAnalysis.cpp @@ -299,7 +299,7 @@ size_t AsmAnalyzer::operator()(FunctionCall const& _funCall) std::optional numReturns; std::vector> const* literalArguments = nullptr; - if (BuiltinFunction const* f = m_dialect.builtin(_funCall.functionName.name)) + if (std::optional handle = m_dialect.findBuiltin(_funCall.functionName.name.str())) { if (_funCall.functionName.name == "selfdestruct"_yulname) m_errorReporter.warning( @@ -327,13 +327,14 @@ size_t AsmAnalyzer::operator()(FunctionCall const& _funCall) "The use of transient storage for reentrancy guards that are cleared at the end of the call is safe." ); - numParameters = f->numParameters; - numReturns = f->numReturns; - if (!f->literalArguments.empty()) - literalArguments = &f->literalArguments; + BuiltinFunction const& f = m_dialect.builtin(*handle); + numParameters = f.numParameters; + numReturns = f.numReturns; + if (!f.literalArguments.empty()) + literalArguments = &f.literalArguments; validateInstructions(_funCall); - m_sideEffects += f->sideEffects; + m_sideEffects += f.sideEffects; } else if (m_currentScope->lookup(_funCall.functionName.name, GenericVisitor{ [&](Scope::Variable const&) @@ -628,7 +629,7 @@ void AsmAnalyzer::expectValidIdentifier(YulName _identifier, SourceLocation cons "\"" + _identifier.str() + "\" is not a valid identifier (contains consecutive dots)." ); - if (m_dialect.reservedIdentifier(_identifier)) + if (m_dialect.reservedIdentifier(_identifier.str())) m_errorReporter.declarationError( 5017_error, _location, @@ -639,14 +640,16 @@ void AsmAnalyzer::expectValidIdentifier(YulName _identifier, SourceLocation cons bool AsmAnalyzer::validateInstructions(std::string const& _instructionIdentifier, langutil::SourceLocation const& _location) { // NOTE: This function uses the default EVM version instead of the currently selected one. - auto const builtin = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt).builtin(YulName(_instructionIdentifier)); - if (builtin && builtin->instruction.has_value()) - return validateInstructions(builtin->instruction.value(), _location); + auto const& defaultEVMDialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); + auto const builtinHandle = defaultEVMDialect.findBuiltin(_instructionIdentifier); + if (builtinHandle && defaultEVMDialect.builtin(*builtinHandle).instruction.has_value()) + return validateInstructions(*defaultEVMDialect.builtin(*builtinHandle).instruction, _location); // TODO: Change `prague()` to `EVMVersion{}` once EOF gets deployed - auto const eofBuiltin = EVMDialect::strictAssemblyForEVM(EVMVersion::prague(), 1).builtin(YulName(_instructionIdentifier)); - if (eofBuiltin && eofBuiltin->instruction.has_value()) - return validateInstructions(eofBuiltin->instruction.value(), _location); + auto const& eofDialect = EVMDialect::strictAssemblyForEVM(EVMVersion::prague(), 1); + auto const eofBuiltinHandle = eofDialect.findBuiltin(_instructionIdentifier); + if (eofBuiltinHandle && eofDialect.builtin(*eofBuiltinHandle).instruction.has_value()) + return validateInstructions(*eofDialect.builtin(*eofBuiltinHandle).instruction, _location); return false; } diff --git a/libyul/AsmParser.cpp b/libyul/AsmParser.cpp index d41b41a36a42..f7741dfae924 100644 --- a/libyul/AsmParser.cpp +++ b/libyul/AsmParser.cpp @@ -432,7 +432,7 @@ Statement Parser::parseStatement() auto const& identifier = std::get(elementary); - if (m_dialect.builtin(identifier.name)) + if (m_dialect.findBuiltin(identifier.name.str())) fatalParserError(6272_error, "Cannot assign to builtin function \"" + identifier.name.str() + "\"."); assignment.variableNames.emplace_back(identifier); @@ -515,7 +515,7 @@ Expression Parser::parseExpression(bool _unlimitedLiteralArgument) { if (currentToken() == Token::LParen) return parseCall(std::move(operation)); - if (m_dialect.builtin(_identifier.name)) + if (m_dialect.findBuiltin(_identifier.name.str())) fatalParserError( 7104_error, nativeLocationOf(_identifier), @@ -676,10 +676,11 @@ FunctionCall Parser::parseCall(std::variant&& _initialOp) FunctionCall ret; ret.functionName = std::move(std::get(_initialOp)); ret.debugData = ret.functionName.debugData; - auto const isUnlimitedLiteralArgument = [f=m_dialect.builtin(ret.functionName.name)](size_t const index) { - if (f && index < f->literalArguments.size()) - return f->literalArgument(index).has_value(); - return false; + auto const isUnlimitedLiteralArgument = [handle=m_dialect.findBuiltin(ret.functionName.name.str()), this](size_t const index) { + if (!handle) + return false; + auto const& function = m_dialect.builtin(*handle); + return index < function.literalArguments.size() && function.literalArgument(index).has_value(); }; size_t argumentIndex {0}; expectToken(Token::LParen); @@ -718,7 +719,7 @@ NameWithDebugData Parser::parseNameWithDebugData() YulName Parser::expectAsmIdentifier() { YulName name{currentLiteral()}; - if (currentToken() == Token::Identifier && m_dialect.builtin(name)) + if (currentToken() == Token::Identifier && m_dialect.findBuiltin(name.str())) fatalParserError(5568_error, "Cannot use builtin function name \"" + name.str() + "\" as identifier name."); // NOTE: We keep the expectation here to ensure the correct source location for the error above. expectToken(Token::Identifier); diff --git a/libyul/Builtins.h b/libyul/Builtins.h new file mode 100644 index 000000000000..8ee17de4b668 --- /dev/null +++ b/libyul/Builtins.h @@ -0,0 +1,35 @@ +/* + 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 +{ + +/// Handle to reference a builtin function in the AST +struct BuiltinHandle +{ + size_t id; + + bool operator==(BuiltinHandle const& _other) const { return id == _other.id; } + bool operator<(BuiltinHandle const& _other) const { return id < _other.id; } +}; + +} diff --git a/libyul/CMakeLists.txt b/libyul/CMakeLists.txt index 58c1b17b5c33..cc4c5051c4bd 100644 --- a/libyul/CMakeLists.txt +++ b/libyul/CMakeLists.txt @@ -15,6 +15,7 @@ add_library(yul AsmParser.h AsmPrinter.cpp AsmPrinter.h + Builtins.h YulStack.h YulStack.cpp CompilabilityChecker.cpp diff --git a/libyul/ControlFlowSideEffectsCollector.cpp b/libyul/ControlFlowSideEffectsCollector.cpp index 471a164e523b..2694eef1c385 100644 --- a/libyul/ControlFlowSideEffectsCollector.cpp +++ b/libyul/ControlFlowSideEffectsCollector.cpp @@ -271,8 +271,8 @@ ControlFlowNode const* ControlFlowSideEffectsCollector::nextProcessableNode(Func ControlFlowSideEffects const& ControlFlowSideEffectsCollector::sideEffects(FunctionCall const& _call) const { - if (auto const* builtin = m_dialect.builtin(_call.functionName.name)) - return builtin->controlFlowSideEffects; + if (std::optional builtinHandle = m_dialect.findBuiltin(_call.functionName.name.str())) + return m_dialect.builtin(*builtinHandle).controlFlowSideEffects; else return m_functionSideEffects.at(m_functionReferences.at(&_call)); } diff --git a/libyul/Dialect.h b/libyul/Dialect.h index 3b0d73597dc4..a707771a2512 100644 --- a/libyul/Dialect.h +++ b/libyul/Dialect.h @@ -21,13 +21,16 @@ #pragma once -#include +#include #include +#include #include +#include -#include -#include #include +#include +#include +#include namespace solidity::yul { @@ -38,7 +41,7 @@ struct Literal; struct BuiltinFunction { - YulName name; + std::string name; size_t numParameters; size_t numReturns; SideEffects sideEffects; @@ -56,25 +59,31 @@ struct BuiltinFunction struct Dialect { + static size_t constexpr verbatimMaxInputSlots = 100; + static size_t constexpr verbatimMaxOutputSlots = 100; + /// Noncopiable. Dialect(Dialect const&) = delete; Dialect& operator=(Dialect const&) = delete; - /// @returns the builtin function of the given name or a nullptr if it is not a builtin function. - virtual BuiltinFunction const* builtin(YulName /*_name*/) const { return nullptr; } + /// @returns the builtin function of the given name or a null if it is not a builtin function. + virtual std::optional findBuiltin(std::string_view /*_name*/) const { return std::nullopt; } - /// @returns true if the identifier is reserved. This includes the builtins too. - virtual bool reservedIdentifier(YulName _name) const { return builtin(_name) != nullptr; } - - virtual BuiltinFunction const* discardFunction() const { return nullptr; } - virtual BuiltinFunction const* equalityFunction() const { return nullptr; } - virtual BuiltinFunction const* booleanNegationFunction() const { return nullptr; } + virtual BuiltinFunction const& builtin(BuiltinHandle const&) const { yulAssert(false); } - virtual BuiltinFunction const* memoryStoreFunction() const { return nullptr; } - virtual BuiltinFunction const* memoryLoadFunction() const { return nullptr; } - virtual BuiltinFunction const* storageStoreFunction() const { return nullptr; } - virtual BuiltinFunction const* storageLoadFunction() const { return nullptr; } - virtual YulName hashFunction() const { return YulName{}; } + /// @returns true if the identifier is reserved. This includes the builtins too. + virtual bool reservedIdentifier(std::string_view _name) const { return findBuiltin(_name).has_value(); } + + // todo these are handles, not functions + virtual std::optional discardFunction() const { return std::nullopt; } + virtual std::optional equalityFunction() const { return std::nullopt; } + virtual std::optional booleanNegationFunction() const { return std::nullopt; } + + virtual std::optional memoryStoreFunction() const { return std::nullopt; } + virtual std::optional memoryLoadFunction() const { return std::nullopt; } + virtual std::optional storageStoreFunction() const { return std::nullopt; } + virtual std::optional storageLoadFunction() const { return std::nullopt; } + virtual std::optional hashFunction() const { return std::nullopt; } Literal zeroLiteral() const; diff --git a/libyul/YulControlFlowGraphExporter.cpp b/libyul/YulControlFlowGraphExporter.cpp index 3f347fcf4f91..d86ffbc7a05e 100644 --- a/libyul/YulControlFlowGraphExporter.cpp +++ b/libyul/YulControlFlowGraphExporter.cpp @@ -193,7 +193,7 @@ Json YulControlFlowGraphExporter::toJson(Json& _ret, SSACFG const& _cfg, SSACFG: if (!builtinArgsJson.empty()) opJson["builtinArgs"] = builtinArgsJson; - opJson["op"] = _call.builtin.get().name.str(); + opJson["op"] = _call.builtin.get().name; }, }, _operation.kind); diff --git a/libyul/backends/evm/ConstantOptimiser.cpp b/libyul/backends/evm/ConstantOptimiser.cpp index 1bb23cbc9282..0ea8f4e5a9fc 100644 --- a/libyul/backends/evm/ConstantOptimiser.cpp +++ b/libyul/backends/evm/ConstantOptimiser.cpp @@ -74,10 +74,11 @@ struct MiniEVMInterpreter u256 operator()(FunctionCall const& _funCall) { - BuiltinFunctionForEVM const* fun = m_dialect.builtin(_funCall.functionName.name); - yulAssert(fun, "Expected builtin function."); - yulAssert(fun->instruction, "Expected EVM instruction."); - return eval(*fun->instruction, _funCall.arguments); + std::optional funHandle = m_dialect.findBuiltin(_funCall.functionName.name.str()); + yulAssert(funHandle, "Expected builtin function."); + BuiltinFunctionForEVM const& fun = m_dialect.builtin(*funHandle); + yulAssert(fun.instruction, "Expected EVM instruction."); + return eval(*fun.instruction, _funCall.arguments); } u256 operator()(Literal const& _literal) { @@ -195,7 +196,9 @@ Representation RepresentationFinder::represent( Identifier{m_debugData, _instruction}, {ASTCopier{}.translate(*_argument.expression)} }); - repr.cost = _argument.cost + m_meter.instructionCosts(*m_dialect.builtin(_instruction)->instruction); + repr.cost = _argument.cost + m_meter.instructionCosts( + *m_dialect.builtin(*m_dialect.findBuiltin(_instruction.str())).instruction + ); return repr; } @@ -211,7 +214,8 @@ Representation RepresentationFinder::represent( Identifier{m_debugData, _instruction}, {ASTCopier{}.translate(*_arg1.expression), ASTCopier{}.translate(*_arg2.expression)} }); - repr.cost = m_meter.instructionCosts(*m_dialect.builtin(_instruction)->instruction) + _arg1.cost + _arg2.cost; + repr.cost = m_meter.instructionCosts( + *m_dialect.builtin(*m_dialect.findBuiltin(_instruction.str())).instruction) + _arg1.cost + _arg2.cost; return repr; } diff --git a/libyul/backends/evm/ControlFlowGraphBuilder.cpp b/libyul/backends/evm/ControlFlowGraphBuilder.cpp index 46ef933ba28e..1b523c4dd7e8 100644 --- a/libyul/backends/evm/ControlFlowGraphBuilder.cpp +++ b/libyul/backends/evm/ControlFlowGraphBuilder.cpp @@ -349,8 +349,8 @@ void ControlFlowGraphBuilder::operator()(Switch const& _switch) CFG::Assignment{_switch.debugData, {ghostVarSlot}} }); - BuiltinFunction const* equalityBuiltin = m_dialect.equalityFunction(); - yulAssert(equalityBuiltin, ""); + std::optional const& equalityBuiltinHandle = m_dialect.equalityFunction(); + yulAssert(equalityBuiltinHandle); // Artificially generate: // eq(, ) @@ -363,7 +363,7 @@ void ControlFlowGraphBuilder::operator()(Switch const& _switch) CFG::Operation& operation = m_currentBlock->operations.emplace_back(CFG::Operation{ Stack{ghostVarSlot, LiteralSlot{_case.value->value.value(), debugDataOf(*_case.value)}}, Stack{TemporarySlot{ghostCall, 0}}, - CFG::BuiltinCall{debugDataOf(_case), *equalityBuiltin, ghostCall, 2}, + CFG::BuiltinCall{debugDataOf(_case), m_dialect.builtin(*equalityBuiltinHandle), ghostCall, 2}, }); return operation.output.front(); }; @@ -516,24 +516,25 @@ Stack const& ControlFlowGraphBuilder::visitFunctionCall(FunctionCall const& _cal Stack const* output = nullptr; bool canContinue = true; - if (BuiltinFunction const* builtin = m_dialect.builtin(_call.functionName.name)) + if (std::optional const& builtinHandle = m_dialect.findBuiltin(_call.functionName.name.str())) { + auto const& builtin = m_dialect.builtin(*builtinHandle); Stack inputs; for (auto&& [idx, arg]: _call.arguments | ranges::views::enumerate | ranges::views::reverse) - if (!builtin->literalArgument(idx).has_value()) + if (!builtin.literalArgument(idx).has_value()) inputs.emplace_back(std::visit(*this, arg)); - CFG::BuiltinCall builtinCall{_call.debugData, *builtin, _call, inputs.size()}; + CFG::BuiltinCall builtinCall{_call.debugData, builtin, _call, inputs.size()}; output = &m_currentBlock->operations.emplace_back(CFG::Operation{ // input std::move(inputs), // output - ranges::views::iota(0u, builtin->numReturns) | ranges::views::transform([&](size_t _i) { + ranges::views::iota(0u, builtin.numReturns) | ranges::views::transform([&](size_t _i) { return TemporarySlot{_call, _i}; }) | ranges::to, // operation std::move(builtinCall) }).output; - canContinue = builtin->controlFlowSideEffects.canContinue; + canContinue = builtin.controlFlowSideEffects.canContinue; } else { diff --git a/libyul/backends/evm/EVMCodeTransform.cpp b/libyul/backends/evm/EVMCodeTransform.cpp index 694639565421..e354649e75d6 100644 --- a/libyul/backends/evm/EVMCodeTransform.cpp +++ b/libyul/backends/evm/EVMCodeTransform.cpp @@ -230,13 +230,14 @@ void CodeTransform::operator()(FunctionCall const& _call) yulAssert(m_scope, ""); m_assembly.setSourceLocation(originLocationOf(_call)); - if (BuiltinFunctionForEVM const* builtin = m_dialect.builtin(_call.functionName.name)) + if (std::optional builtinHandle = m_dialect.findBuiltin(_call.functionName.name.str())) { + BuiltinFunctionForEVM const& builtin = m_dialect.builtin(*builtinHandle); for (auto&& [i, arg]: _call.arguments | ranges::views::enumerate | ranges::views::reverse) - if (!builtin->literalArgument(i)) + if (!builtin.literalArgument(i)) visitExpression(arg); m_assembly.setSourceLocation(originLocationOf(_call)); - builtin->generateCode(_call, m_assembly, m_builtinContext); + builtin.generateCode(_call, m_assembly, m_builtinContext); } else { diff --git a/libyul/backends/evm/EVMDialect.cpp b/libyul/backends/evm/EVMDialect.cpp index 9e9d5e542ca6..e50e849d700f 100644 --- a/libyul/backends/evm/EVMDialect.cpp +++ b/libyul/backends/evm/EVMDialect.cpp @@ -25,13 +25,17 @@ #include #include #include -#include #include #include #include #include +#include +#include + #include +#include +#include using namespace std::string_literals; using namespace solidity; @@ -41,15 +45,15 @@ using namespace solidity::util; namespace { -std::pair createEVMFunction( +BuiltinFunctionForEVM createEVMFunction( langutil::EVMVersion _evmVersion, std::string const& _name, evmasm::Instruction _instruction ) { - evmasm::InstructionInfo info = evmasm::instructionInfo(_instruction, _evmVersion); BuiltinFunctionForEVM f; - f.name = YulName{_name}; + evmasm::InstructionInfo info = evmasm::instructionInfo(_instruction, _evmVersion); + f.name = _name; f.numParameters = static_cast(info.args); f.numReturns = static_cast(info.ret); f.sideEffects = EVMDialect::sideEffectsOfInstruction(_instruction); @@ -77,13 +81,11 @@ std::pair createEVMFunction( ) { _assembly.appendInstruction(_instruction); }; - - YulName name = f.name; - return {name, std::move(f)}; + return f; } -std::pair createFunction( - std::string _name, +BuiltinFunctionForEVM createFunction( + std::string const& _name, size_t _params, size_t _returns, SideEffects _sideEffects, @@ -93,20 +95,19 @@ std::pair createFunction( { yulAssert(_literalArguments.size() == _params || _literalArguments.empty(), ""); - YulName name{std::move(_name)}; BuiltinFunctionForEVM f; - f.name = name; + f.name = _name; f.numParameters = _params; f.numReturns = _returns; - f.sideEffects = std::move(_sideEffects); + f.sideEffects = _sideEffects; f.literalArguments = std::move(_literalArguments); f.isMSize = false; f.instruction = {}; f.generateCode = std::move(_generateCode); - return {name, f}; + return f; } -std::set createReservedIdentifiers(langutil::EVMVersion _evmVersion) +std::set> createReservedIdentifiers(langutil::EVMVersion _evmVersion) { // TODO remove this in 0.9.0. We allow creating functions or identifiers in Yul with the name // basefee for VMs before london. @@ -152,7 +153,7 @@ std::set createReservedIdentifiers(langutil::EVMVersion _evmVersion) (_instr == evmasm::Instruction::TSTORE || _instr == evmasm::Instruction::TLOAD); }; - std::set reserved; + std::set> reserved; for (auto const& instr: evmasm::c_instructions) { std::string name = toLower(instr.first); @@ -166,18 +167,18 @@ std::set createReservedIdentifiers(langutil::EVMVersion _evmVersion) ) reserved.emplace(name); } - reserved += std::vector{ - "linkersymbol"_yulname, - "datasize"_yulname, - "dataoffset"_yulname, - "datacopy"_yulname, - "setimmutable"_yulname, - "loadimmutable"_yulname, + reserved += std::vector{ + "linkersymbol", + "datasize", + "dataoffset", + "datacopy", + "setimmutable", + "loadimmutable", }; return reserved; } -std::map createBuiltins(langutil::EVMVersion _evmVersion, std::optional _eofVersion, bool _objectAccess) +std::vector> createBuiltins(langutil::EVMVersion _evmVersion, std::optional _eofVersion, bool _objectAccess) { // Exclude prevrandao as builtin for VMs before paris and difficulty for VMs after paris. @@ -186,7 +187,7 @@ std::map createBuiltins(langutil::EVMVersion _ev return (_instrName == "prevrandao" && _evmVersion < langutil::EVMVersion::paris()) || (_instrName == "difficulty" && _evmVersion >= langutil::EVMVersion::paris()); }; - std::map builtins; + std::vector> builtins; for (auto const& instr: evmasm::c_instructions) { std::string name = toLower(instr.first); @@ -203,171 +204,188 @@ std::map createBuiltins(langutil::EVMVersion _ev _evmVersion.hasOpcode(opcode, _eofVersion) && !prevRandaoException(name) ) - builtins.emplace(createEVMFunction(_evmVersion, name, opcode)); + builtins.emplace_back(createEVMFunction(_evmVersion, name, opcode)); + else + builtins.emplace_back(std::nullopt); } - if (_objectAccess) + auto const createIfObjectAccess = [_objectAccess]( + std::string const& _name, + size_t _params, + size_t _returns, + SideEffects _sideEffects, + std::vector> _literalArguments, + std::function _generateCode + ) -> std::optional { - builtins.emplace(createFunction("linkersymbol", 1, 1, SideEffects{}, {LiteralKind::String}, []( + if (!_objectAccess) + return std::nullopt; + return createFunction(_name, _params, _returns, _sideEffects, std::move(_literalArguments), std::move(_generateCode)); + }; + + builtins.emplace_back(createIfObjectAccess("linkersymbol", 1, 1, SideEffects{}, {LiteralKind::String}, []( + FunctionCall const& _call, + AbstractAssembly& _assembly, + BuiltinContext& + ) { + yulAssert(_call.arguments.size() == 1, ""); + Expression const& arg = _call.arguments.front(); + _assembly.appendLinkerSymbol(formatLiteral(std::get(arg))); + })); + builtins.emplace_back(createIfObjectAccess( + "memoryguard", + 1, + 1, + SideEffects{}, + {LiteralKind::Number}, + []( FunctionCall const& _call, AbstractAssembly& _assembly, BuiltinContext& ) { + yulAssert(_call.arguments.size() == 1, ""); + Literal const* literal = std::get_if(&_call.arguments.front()); + yulAssert(literal, ""); + _assembly.appendConstant(literal->value.value()); + }) + ); + if (!_eofVersion.has_value()) + { + builtins.emplace_back(createIfObjectAccess("datasize", 1, 1, SideEffects{}, {LiteralKind::String}, []( + FunctionCall const& _call, + AbstractAssembly& _assembly, + BuiltinContext& _context + ) { + yulAssert(_context.currentObject, "No object available."); yulAssert(_call.arguments.size() == 1, ""); Expression const& arg = _call.arguments.front(); - _assembly.appendLinkerSymbol(formatLiteral(std::get(arg))); + YulName const dataName (formatLiteral(std::get(arg))); + if (_context.currentObject->name == dataName.str()) + _assembly.appendAssemblySize(); + else + { + std::vector subIdPath = + _context.subIDs.count(dataName.str()) == 0 ? + _context.currentObject->pathToSubObject(dataName.str()) : + std::vector{_context.subIDs.at(dataName.str())}; + yulAssert(!subIdPath.empty(), "Could not find assembly object <" + dataName.str() + ">."); + _assembly.appendDataSize(subIdPath); + } })); - - builtins.emplace(createFunction( - "memoryguard", - 1, - 1, - SideEffects{}, - {LiteralKind::Number}, + builtins.emplace_back(createIfObjectAccess("dataoffset", 1, 1, SideEffects{}, {LiteralKind::String}, []( + FunctionCall const& _call, + AbstractAssembly& _assembly, + BuiltinContext& _context + ) { + yulAssert(_context.currentObject, "No object available."); + yulAssert(_call.arguments.size() == 1, ""); + Expression const& arg = _call.arguments.front(); + YulName const dataName (formatLiteral(std::get(arg))); + if (_context.currentObject->name == dataName.str()) + _assembly.appendConstant(0); + else + { + std::vector subIdPath = + _context.subIDs.count(dataName.str()) == 0 ? + _context.currentObject->pathToSubObject(dataName.str()) : + std::vector{_context.subIDs.at(dataName.str())}; + yulAssert(!subIdPath.empty(), "Could not find assembly object <" + dataName.str() + ">."); + _assembly.appendDataOffset(subIdPath); + } + })); + builtins.emplace_back(createIfObjectAccess( + "datacopy", + 3, + 0, + SideEffects{ + false, // movable + true, // movableApartFromEffects + false, // canBeRemoved + false, // canBeRemovedIfNotMSize + true, // cannotLoop + SideEffects::None, // otherState + SideEffects::None, // storage + SideEffects::Write, // memory + SideEffects::None // transientStorage + }, + {}, + []( + FunctionCall const&, + AbstractAssembly& _assembly, + BuiltinContext& + ) { + _assembly.appendInstruction(evmasm::Instruction::CODECOPY); + } + )); + builtins.emplace_back(createIfObjectAccess( + "setimmutable", + 3, + 0, + SideEffects{ + false, // movable + false, // movableApartFromEffects + false, // canBeRemoved + false, // canBeRemovedIfNotMSize + true, // cannotLoop + SideEffects::None, // otherState + SideEffects::None, // storage + SideEffects::Write, // memory + SideEffects::None // transientStorage + }, + {std::nullopt, LiteralKind::String, std::nullopt}, []( FunctionCall const& _call, AbstractAssembly& _assembly, BuiltinContext& ) { - yulAssert(_call.arguments.size() == 1, ""); - Literal const* literal = std::get_if(&_call.arguments.front()); - yulAssert(literal, ""); - _assembly.appendConstant(literal->value.value()); - }) - ); - - if (!_eofVersion.has_value()) // non-EOF context - { - builtins.emplace(createFunction("datasize", 1, 1, SideEffects{}, {LiteralKind::String}, []( + yulAssert(_call.arguments.size() == 3, ""); + auto const identifier = (formatLiteral(std::get(_call.arguments[1]))); + _assembly.appendImmutableAssignment(identifier); + } + )); + builtins.emplace_back(createIfObjectAccess( + "loadimmutable", + 1, + 1, + SideEffects{}, + {LiteralKind::String}, + []( FunctionCall const& _call, AbstractAssembly& _assembly, - BuiltinContext& _context + BuiltinContext& ) { - yulAssert(_context.currentObject, "No object available."); yulAssert(_call.arguments.size() == 1, ""); - Expression const& arg = _call.arguments.front(); - YulName const dataName (formatLiteral(std::get(arg))); - if (_context.currentObject->name == dataName.str()) - _assembly.appendAssemblySize(); - else - { - std::vector subIdPath = - _context.subIDs.count(dataName.str()) == 0 ? - _context.currentObject->pathToSubObject(dataName.str()) : - std::vector{_context.subIDs.at(dataName.str())}; - yulAssert(!subIdPath.empty(), "Could not find assembly object <" + dataName.str() + ">."); - _assembly.appendDataSize(subIdPath); - } - })); - builtins.emplace(createFunction("dataoffset", 1, 1, SideEffects{}, {LiteralKind::String}, []( + _assembly.appendImmutable(formatLiteral(std::get(_call.arguments.front()))); + } + )); + } + else + { + builtins.emplace_back(createFunction( + "auxdataloadn", + 1, + 1, + SideEffects{}, + {LiteralKind::Number}, + []( FunctionCall const& _call, AbstractAssembly& _assembly, - BuiltinContext& _context + BuiltinContext& ) { - yulAssert(_context.currentObject, "No object available."); yulAssert(_call.arguments.size() == 1, ""); - Expression const& arg = _call.arguments.front(); - YulName const dataName (formatLiteral(std::get(arg))); - if (_context.currentObject->name == dataName.str()) - _assembly.appendConstant(0); - else - { - std::vector subIdPath = - _context.subIDs.count(dataName.str()) == 0 ? - _context.currentObject->pathToSubObject(dataName.str()) : - std::vector{_context.subIDs.at(dataName.str())}; - yulAssert(!subIdPath.empty(), "Could not find assembly object <" + dataName.str() + ">."); - _assembly.appendDataOffset(subIdPath); - } - })); - builtins.emplace(createFunction( - "datacopy", - 3, - 0, - SideEffects{ - false, // movable - true, // movableApartFromEffects - false, // canBeRemoved - false, // canBeRemovedIfNotMSize - true, // cannotLoop - SideEffects::None, // otherState - SideEffects::None, // storage - SideEffects::Write, // memory - SideEffects::None // transientStorage - }, - {}, - []( - FunctionCall const&, - AbstractAssembly& _assembly, - BuiltinContext& - ) { - _assembly.appendInstruction(evmasm::Instruction::CODECOPY); - } - )); - builtins.emplace(createFunction( - "setimmutable", - 3, - 0, - SideEffects{ - false, // movable - false, // movableApartFromEffects - false, // canBeRemoved - false, // canBeRemovedIfNotMSize - true, // cannotLoop - SideEffects::None, // otherState - SideEffects::None, // storage - SideEffects::Write, // memory - SideEffects::None // transientStorage - }, - {std::nullopt, LiteralKind::String, std::nullopt}, - []( - FunctionCall const& _call, - AbstractAssembly& _assembly, - BuiltinContext& - ) { - yulAssert(_call.arguments.size() == 3, ""); - auto const identifier = (formatLiteral(std::get(_call.arguments[1]))); - _assembly.appendImmutableAssignment(identifier); - } - )); - builtins.emplace(createFunction( - "loadimmutable", - 1, - 1, - SideEffects{}, - {LiteralKind::String}, - []( - FunctionCall const& _call, - AbstractAssembly& _assembly, - BuiltinContext& - ) { - yulAssert(_call.arguments.size() == 1, ""); - _assembly.appendImmutable(formatLiteral(std::get(_call.arguments.front()))); - } - )); - } - else // EOF context - { - builtins.emplace(createFunction( - "auxdataloadn", - 1, - 1, - SideEffects{}, - {LiteralKind::Number}, - []( - FunctionCall const& _call, - AbstractAssembly& _assembly, - BuiltinContext& - ) { - yulAssert(_call.arguments.size() == 1, ""); - Literal const* literal = std::get_if(&_call.arguments.front()); - yulAssert(literal, ""); - yulAssert(literal->value.value() <= std::numeric_limits::max(), ""); - _assembly.appendAuxDataLoadN(static_cast(literal->value.value())); - } - )); - } + Literal const* literal = std::get_if(&_call.arguments.front()); + yulAssert(literal, ""); + yulAssert(literal->value.value() <= std::numeric_limits::max(), ""); + _assembly.appendAuxDataLoadN(static_cast(literal->value.value())); + } + )); } + yulAssert( + ranges::all_of(builtins, [](std::optional const& _builtinFunction){ + return !_builtinFunction || _builtinFunction->name.substr(0, "verbatim_"s.size()) != "verbatim_"; + }), + "Builtin functions besides verbatim should not start with the verbatim_ prefix." + ); return builtins; } @@ -387,27 +405,58 @@ EVMDialect::EVMDialect(langutil::EVMVersion _evmVersion, std::optional m_functions(createBuiltins(_evmVersion, _eofVersion, _objectAccess)), m_reserved(createReservedIdentifiers(_evmVersion)) { + for (auto const& [index, maybeBuiltin]: m_functions | ranges::views::enumerate) + if (maybeBuiltin) + // ids are offset by the maximum number of verbatim functions + m_builtinFunctionsByName[maybeBuiltin->name] = BuiltinHandle{index + verbatimIdOffset}; + + m_discardFunction = findBuiltin("pop"); + m_equalityFunction = findBuiltin("eq"); + m_booleanNegationFunction = findBuiltin("iszero"); + m_memoryStoreFunction = findBuiltin("mstore"); + m_memoryLoadFunction = findBuiltin("mload"); + m_storageStoreFunction = findBuiltin("sstore"); + m_storageLoadFunction = findBuiltin("sload"); + m_hashFunction = findBuiltin("keccak256"); } -BuiltinFunctionForEVM const* EVMDialect::builtin(YulName _name) const +std::optional EVMDialect::findBuiltin(std::string_view _name) const { if (m_objectAccess) { std::smatch match; - if (regex_match(_name.str(), match, verbatimPattern())) + std::string name(_name); + if (regex_match(name, match, verbatimPattern())) return verbatimFunction(stoul(match[1]), stoul(match[2])); } - auto it = m_functions.find(_name); - if (it != m_functions.end()) - return &it->second; - else - return nullptr; + auto it = std::find_if(m_functions.begin(), m_functions.end(), [&_name](auto const& builtin) { return builtin && builtin.value().name == _name; }); + if (it != m_functions.end() && *it && it->value().name == _name) + // ids are offset by the maximum number of verbatim functions + return BuiltinHandle{static_cast(std::distance(m_functions.begin(), it)) + verbatimIdOffset}; + return std::nullopt; +} + +BuiltinFunctionForEVM const& EVMDialect::builtin(BuiltinHandle const& handle) const +{ + if (isVerbatimHandle(handle)) + { + yulAssert(handle.id < verbatimIDOffset); + auto const& verbatimFunctionPtr = m_verbatimFunctions[handle.id]; + yulAssert(verbatimFunctionPtr); + return *verbatimFunctionPtr; + } + + yulAssert(handle.id - verbatimIDOffset < m_functions.size()); + auto const& maybeBuiltin = m_functions[handle.id - verbatimIDOffset]; + yulAssert(maybeBuiltin.has_value()); + return *maybeBuiltin; } -bool EVMDialect::reservedIdentifier(YulName _name) const + +bool EVMDialect::reservedIdentifier(std::string_view _name) const { if (m_objectAccess) - if (_name.str().substr(0, "verbatim"s.size()) == "verbatim") + if (_name.substr(0, "verbatim"s.size()) == "verbatim") return true; return m_reserved.count(_name) != 0; } @@ -450,35 +499,49 @@ SideEffects EVMDialect::sideEffectsOfInstruction(evmasm::Instruction _instructio }; } -BuiltinFunctionForEVM const* EVMDialect::verbatimFunction(size_t _arguments, size_t _returnVariables) const +BuiltinHandle EVMDialect::verbatimFunction(size_t _arguments, size_t _returnVariables) const { - std::pair key{_arguments, _returnVariables}; - std::shared_ptr& function = m_verbatimFunctions[key]; - if (!function) - { - BuiltinFunctionForEVM builtinFunction = createFunction( - "verbatim_" + std::to_string(_arguments) + "i_" + std::to_string(_returnVariables) + "o", - 1 + _arguments, - _returnVariables, - SideEffects::worst(), - std::vector>{LiteralKind::String} + std::vector>(_arguments), - [=]( - FunctionCall const& _call, - AbstractAssembly& _assembly, - BuiltinContext& - ) { - yulAssert(_call.arguments.size() == (1 + _arguments), ""); - Expression const& bytecode = _call.arguments.front(); - - _assembly.appendVerbatim( - asBytes(formatLiteral(std::get(bytecode))), - _arguments, - _returnVariables - ); - } - ).second; - builtinFunction.isMSize = true; - function = std::make_shared(std::move(builtinFunction)); - } - return function.get(); + auto const it = std::find_if(m_verbatimFunctions.begin(), m_verbatimFunctions.end(), [&](BuiltinFunctionForEVM const& _function) { + return _function.numParameters == 1 + _arguments && _function.numReturns == _returnVariables; + }); + yulAssert(_arguments <= verbatimMaxInputSlots); + yulAssert(_returnVariables <= verbatimMaxOutputSlots); + if (it != m_verbatimFunctions.end()) + return {static_cast(std::distance(m_verbatimFunctions.begin(), it))}; + + BuiltinFunctionForEVM builtinFunction = createFunction( + "verbatim_" + std::to_string(_arguments) + "i_" + std::to_string(_returnVariables) + "o", + 1 + _arguments, + _returnVariables, + SideEffects::worst(), + std::vector>{LiteralKind::String} + std::vector>(_arguments), + [=]( + FunctionCall const& _call, + AbstractAssembly& _assembly, + BuiltinContext& + ) { + yulAssert(_call.arguments.size() == (1 + _arguments), ""); + Expression const& bytecode = _call.arguments.front(); + + _assembly.appendVerbatim( + asBytes(formatLiteral(std::get(bytecode))), + _arguments, + _returnVariables + ); + } + ); + builtinFunction.isMSize = true; + m_verbatimFunctions.push_back(std::move(builtinFunction)); + yulAssert(m_verbatimFunctions.size() <= verbatimIdOffset); + return {m_verbatimFunctions.size() - 1}; +} + +BuiltinFunctionForEVM const& EVMDialect::builtin(BuiltinHandle const& handle) const +{ + if (handle.id < verbatimIdOffset) + return m_verbatimFunctions.at(handle.id); + + auto const& maybeBuiltin = m_functions.at(handle.id - verbatimIdOffset); + yulAssert(maybeBuiltin.has_value()); + return *maybeBuiltin; } diff --git a/libyul/backends/evm/EVMDialect.h b/libyul/backends/evm/EVMDialect.h index cc064c3a0f1e..45be636d811d 100644 --- a/libyul/backends/evm/EVMDialect.h +++ b/libyul/backends/evm/EVMDialect.h @@ -62,25 +62,26 @@ struct BuiltinFunctionForEVM: public BuiltinFunction * The main difference is that the builtin functions take an AbstractAssembly for the * code generation. */ -struct EVMDialect: public Dialect +struct EVMDialect: Dialect { /// Constructor, should only be used internally. Use the factory functions below. EVMDialect(langutil::EVMVersion _evmVersion, std::optional _eofVersion, bool _objectAccess); - /// @returns the builtin function of the given name or a nullptr if it is not a builtin function. - BuiltinFunctionForEVM const* builtin(YulName _name) const override; + std::optional findBuiltin(std::string_view _name) const override; + + BuiltinFunctionForEVM const& builtin(BuiltinHandle const& handle) const override; /// @returns true if the identifier is reserved. This includes the builtins too. - bool reservedIdentifier(YulName _name) const override; + bool reservedIdentifier(std::string_view _name) const override; - BuiltinFunctionForEVM const* discardFunction() const override { return builtin("pop"_yulname); } - BuiltinFunctionForEVM const* equalityFunction() const override { return builtin("eq"_yulname); } - BuiltinFunctionForEVM const* booleanNegationFunction() const override { return builtin("iszero"_yulname); } - BuiltinFunctionForEVM const* memoryStoreFunction() const override { return builtin("mstore"_yulname); } - BuiltinFunctionForEVM const* memoryLoadFunction() const override { return builtin("mload"_yulname); } - BuiltinFunctionForEVM const* storageStoreFunction() const override { return builtin("sstore"_yulname); } - BuiltinFunctionForEVM const* storageLoadFunction() const override { return builtin("sload"_yulname); } - YulName hashFunction() const override { return "keccak256"_yulname; } + std::optional discardFunction() const override { return m_discardFunction; } + std::optional equalityFunction() const override { return m_equalityFunction; } + std::optional booleanNegationFunction() const override { return m_booleanNegationFunction; } + std::optional memoryStoreFunction() const override { return m_memoryStoreFunction; } + std::optional memoryLoadFunction() const override { return m_memoryLoadFunction; } + std::optional storageStoreFunction() const override { return m_storageStoreFunction; } + std::optional storageLoadFunction() const override { return m_storageLoadFunction; } + std::optional hashFunction() const override { return m_hashFunction; } static EVMDialect const& strictAssemblyForEVM(langutil::EVMVersion _evmVersion, std::optional _eofVersion); static EVMDialect const& strictAssemblyForEVMObjects(langutil::EVMVersion _evmVersion, std::optional _eofVersion); @@ -92,15 +93,28 @@ struct EVMDialect: public Dialect static SideEffects sideEffectsOfInstruction(evmasm::Instruction _instruction); + std::vector const& verbatimFunctions() const { return m_verbatimFunctions; } + protected: - BuiltinFunctionForEVM const* verbatimFunction(size_t _arguments, size_t _returnVariables) const; + BuiltinHandle verbatimFunction(size_t _arguments, size_t _returnVariables) const; + + static size_t constexpr verbatimIdOffset = verbatimMaxInputSlots * verbatimMaxOutputSlots; bool const m_objectAccess; langutil::EVMVersion const m_evmVersion; std::optional m_eofVersion; - std::map m_functions; - std::map, std::shared_ptr> mutable m_verbatimFunctions; - std::set m_reserved; + std::vector> m_functions; + std::vector mutable m_verbatimFunctions; + std::set> m_reserved; + + std::optional m_discardFunction; + std::optional m_equalityFunction; + std::optional m_booleanNegationFunction; + std::optional m_memoryStoreFunction; + std::optional m_memoryLoadFunction; + std::optional m_storageStoreFunction; + std::optional m_storageLoadFunction; + std::optional m_hashFunction; }; } diff --git a/libyul/backends/evm/EVMMetrics.cpp b/libyul/backends/evm/EVMMetrics.cpp index 539279bf20d9..64ff94cf6102 100644 --- a/libyul/backends/evm/EVMMetrics.cpp +++ b/libyul/backends/evm/EVMMetrics.cpp @@ -76,10 +76,10 @@ std::pair GasMeterVisitor::instructionCosts( void GasMeterVisitor::operator()(FunctionCall const& _funCall) { ASTWalker::operator()(_funCall); - if (BuiltinFunctionForEVM const* f = m_dialect.builtin(_funCall.functionName.name)) - if (f->instruction) + if (std::optional handle = m_dialect.findBuiltin(_funCall.functionName.name.str())) + if (std::optional const& instruction = m_dialect.builtin(*handle).instruction) { - instructionCostsInternal(*f->instruction); + instructionCostsInternal(*instruction); return; } yulAssert(false, "Functions not implemented."); diff --git a/libyul/backends/evm/NoOutputAssembly.cpp b/libyul/backends/evm/NoOutputAssembly.cpp index 9d8bd73a3465..19d21bccd54a 100644 --- a/libyul/backends/evm/NoOutputAssembly.cpp +++ b/libyul/backends/evm/NoOutputAssembly.cpp @@ -139,11 +139,30 @@ NoOutputEVMDialect::NoOutputEVMDialect(EVMDialect const& _copyFrom): { for (auto& fun: m_functions) { - size_t returns = fun.second.numReturns; - fun.second.generateCode = [=](FunctionCall const& _call, AbstractAssembly& _assembly, BuiltinContext&) + if (fun) + { + size_t returns = fun.value().numReturns; + fun.value().generateCode = [=](FunctionCall const& _call, AbstractAssembly& _assembly, BuiltinContext&) + { + for (size_t i: ranges::views::iota(0u, _call.arguments.size())) + if (!fun.value().literalArgument(i)) + _assembly.appendInstruction(evmasm::Instruction::POP); + + for (size_t i = 0; i < returns; i++) + _assembly.appendConstant(u256(0)); + }; + } + } + + m_verbatimFunctions = _copyFrom.verbatimFunctions(); + for (auto& entry: m_verbatimFunctions) + { + auto const& fun = entry; + auto returns = fun.numReturns; + entry.generateCode = [returns, fun](FunctionCall const& _call, AbstractAssembly& _assembly, BuiltinContext&) { for (size_t i: ranges::views::iota(0u, _call.arguments.size())) - if (!fun.second.literalArgument(i)) + if (!fun.literalArgument(i)) _assembly.appendInstruction(evmasm::Instruction::POP); for (size_t i = 0; i < returns; i++) diff --git a/libyul/backends/evm/SSAControlFlowGraph.cpp b/libyul/backends/evm/SSAControlFlowGraph.cpp index 35c9db0dfe8c..8e52e78e7983 100644 --- a/libyul/backends/evm/SSAControlFlowGraph.cpp +++ b/libyul/backends/evm/SSAControlFlowGraph.cpp @@ -147,7 +147,7 @@ class SSACFGPrinter return _call.function.get().name.str(); }, [&](SSACFG::BuiltinCall const& _call) { - return _call.builtin.get().name.str(); + return _call.builtin.get().name; }, }, operation.kind); if (!operation.outputs.empty()) diff --git a/libyul/backends/evm/SSAControlFlowGraphBuilder.cpp b/libyul/backends/evm/SSAControlFlowGraphBuilder.cpp index 92b91e8ae1e9..dacd061806aa 100644 --- a/libyul/backends/evm/SSAControlFlowGraphBuilder.cpp +++ b/libyul/backends/evm/SSAControlFlowGraphBuilder.cpp @@ -349,12 +349,12 @@ void SSAControlFlowGraphBuilder::operator()(Switch const& _switch) {*_case.value /* skip second argument */ } }); auto outputValue = m_graph.newVariable(m_currentBlock); - BuiltinFunction const* builtin = m_dialect.builtin(ghostCall.functionName.name); + std::optional builtinHandle = m_dialect.findBuiltin(ghostCall.functionName.name.str()); currentBlock().operations.emplace_back(SSACFG::Operation{ {outputValue}, SSACFG::BuiltinCall{ debugDataOf(_case), - *builtin, + m_dialect.builtin(*builtinHandle), ghostCall }, {m_graph.newLiteral(debugDataOf(_case), _case.value->value.value()), expression} @@ -546,15 +546,16 @@ std::vector SSAControlFlowGraphBuilder::visitFunctionCall(Funct { bool canContinue = true; SSACFG::Operation operation = [&](){ - if (BuiltinFunction const* builtin = m_dialect.builtin(_call.functionName.name)) + if (std::optional const& builtinHandle = m_dialect.findBuiltin(_call.functionName.name.str())) { - SSACFG::Operation result{{}, SSACFG::BuiltinCall{_call.debugData, *builtin, _call}, {}}; + auto const& builtinFunction = m_dialect.builtin(*builtinHandle); + SSACFG::Operation result{{}, SSACFG::BuiltinCall{_call.debugData, builtinFunction, _call}, {}}; for (auto&& [idx, arg]: _call.arguments | ranges::views::enumerate | ranges::views::reverse) - if (!builtin->literalArgument(idx).has_value()) + if (!builtinFunction.literalArgument(idx).has_value()) result.inputs.emplace_back(std::visit(*this, arg)); - for (size_t i = 0; i < builtin->numReturns; ++i) + for (size_t i = 0; i < builtinFunction.numReturns; ++i) result.outputs.emplace_back(m_graph.newVariable(m_currentBlock)); - canContinue = builtin->controlFlowSideEffects.canContinue; + canContinue = builtinFunction.controlFlowSideEffects.canContinue; return result; } else diff --git a/libyul/optimiser/CommonSubexpressionEliminator.cpp b/libyul/optimiser/CommonSubexpressionEliminator.cpp index 073d621cc2cf..f74568421a4f 100644 --- a/libyul/optimiser/CommonSubexpressionEliminator.cpp +++ b/libyul/optimiser/CommonSubexpressionEliminator.cpp @@ -72,13 +72,14 @@ void CommonSubexpressionEliminator::visit(Expression& _e) { FunctionCall& funCall = std::get(_e); - if (BuiltinFunction const* builtin = m_dialect.builtin(funCall.functionName.name)) + if (std::optional builtinHandle = m_dialect.findBuiltin(funCall.functionName.name.str())) { + BuiltinFunction const& builtin = m_dialect.builtin(*builtinHandle); for (size_t i = funCall.arguments.size(); i > 0; i--) // We should not modify function arguments that have to be literals // Note that replacing the function call entirely is fine, // if the function call is movable. - if (!builtin->literalArgument(i - 1)) + if (!builtin.literalArgument(i - 1)) visit(funCall.arguments[i - 1]); descend = false; diff --git a/libyul/optimiser/ControlFlowSimplifier.cpp b/libyul/optimiser/ControlFlowSimplifier.cpp index c078885e8ba4..478d7b9d911b 100644 --- a/libyul/optimiser/ControlFlowSimplifier.cpp +++ b/libyul/optimiser/ControlFlowSimplifier.cpp @@ -43,7 +43,7 @@ ExpressionStatement makeDiscardCall( { return {_debugData, FunctionCall{ _debugData, - Identifier{_debugData, _discardFunction.name}, + Identifier{_debugData, YulName{_discardFunction.name}}, {std::move(_expression)} }}; } @@ -141,7 +141,7 @@ void ControlFlowSimplifier::simplify(std::vector& _statements) OptionalStatements s = std::vector{}; s->emplace_back(makeDiscardCall( _ifStmt.debugData, - *m_dialect.discardFunction(), + m_dialect.builtin(*m_dialect.discardFunction()), std::move(*_ifStmt.condition) )); return s; @@ -177,14 +177,14 @@ void ControlFlowSimplifier::simplify(std::vector& _statements) OptionalStatements ControlFlowSimplifier::reduceNoCaseSwitch(Switch& _switchStmt) const { yulAssert(_switchStmt.cases.empty(), "Expected no case!"); - BuiltinFunction const* discardFunction = + std::optional discardFunctionHandle = m_dialect.discardFunction(); - if (!discardFunction) + if (!discardFunctionHandle) return {}; return make_vector(makeDiscardCall( debugDataOf(*_switchStmt.expression), - *discardFunction, + m_dialect.builtin(*discardFunctionHandle), std::move(*_switchStmt.expression) )); } @@ -203,7 +203,7 @@ OptionalStatements ControlFlowSimplifier::reduceSingleCaseSwitch(Switch& _switch std::move(_switchStmt.debugData), std::make_unique(FunctionCall{ debugData, - Identifier{debugData, m_dialect.equalityFunction()->name}, + Identifier{debugData, YulName{m_dialect.builtin(*m_dialect.equalityFunction()).name}}, {std::move(*switchCase.value), std::move(*_switchStmt.expression)} }), std::move(switchCase.body) @@ -217,7 +217,7 @@ OptionalStatements ControlFlowSimplifier::reduceSingleCaseSwitch(Switch& _switch return make_vector( makeDiscardCall( debugData, - *m_dialect.discardFunction(), + m_dialect.builtin(*m_dialect.discardFunction()), std::move(*_switchStmt.expression) ), std::move(switchCase.body) diff --git a/libyul/optimiser/DataFlowAnalyzer.cpp b/libyul/optimiser/DataFlowAnalyzer.cpp index bf8952355d1f..022ac199ebb2 100644 --- a/libyul/optimiser/DataFlowAnalyzer.cpp +++ b/libyul/optimiser/DataFlowAnalyzer.cpp @@ -54,14 +54,14 @@ DataFlowAnalyzer::DataFlowAnalyzer( { if (m_analyzeStores) { - if (auto const* builtin = _dialect.memoryStoreFunction()) - m_storeFunctionName[static_cast(StoreLoadLocation::Memory)] = builtin->name; - if (auto const* builtin = _dialect.memoryLoadFunction()) - m_loadFunctionName[static_cast(StoreLoadLocation::Memory)] = builtin->name; - if (auto const* builtin = _dialect.storageStoreFunction()) - m_storeFunctionName[static_cast(StoreLoadLocation::Storage)] = builtin->name; - if (auto const* builtin = _dialect.storageLoadFunction()) - m_loadFunctionName[static_cast(StoreLoadLocation::Storage)] = builtin->name; + if (auto const& builtinHandle = _dialect.memoryStoreFunction()) + m_storeFunctionName[static_cast(StoreLoadLocation::Memory)] = YulName{_dialect.builtin(*builtinHandle).name}; + if (auto const& builtinHandle = _dialect.memoryLoadFunction()) + m_loadFunctionName[static_cast(StoreLoadLocation::Memory)] = YulName{_dialect.builtin(*builtinHandle).name}; + if (auto const& builtinHandle = _dialect.storageStoreFunction()) + m_storeFunctionName[static_cast(StoreLoadLocation::Storage)] = YulName{_dialect.builtin(*builtinHandle).name}; + if (auto const& builtinHandle = _dialect.storageLoadFunction()) + m_loadFunctionName[static_cast(StoreLoadLocation::Storage)] = YulName{_dialect.builtin(*builtinHandle).name}; } } @@ -446,7 +446,7 @@ std::optional DataFlowAnalyzer::isSimpleLoad( std::optional> DataFlowAnalyzer::isKeccak(Expression const& _expression) const { if (FunctionCall const* funCall = std::get_if(&_expression)) - if (funCall->functionName.name == m_dialect.hashFunction()) + if (funCall->functionName.name.str() == m_dialect.builtin(*m_dialect.hashFunction()).name) if (Identifier const* start = std::get_if(&funCall->arguments.at(0))) if (Identifier const* length = std::get_if(&funCall->arguments.at(1))) return std::make_pair(start->name, length->name); diff --git a/libyul/optimiser/Disambiguator.cpp b/libyul/optimiser/Disambiguator.cpp index 11325936c7c6..55219f6eae37 100644 --- a/libyul/optimiser/Disambiguator.cpp +++ b/libyul/optimiser/Disambiguator.cpp @@ -32,7 +32,7 @@ using namespace solidity::util; YulName Disambiguator::translateIdentifier(YulName _originalName) { - if (m_dialect.builtin(_originalName) || m_externallyUsedIdentifiers.count(_originalName)) + if (m_dialect.findBuiltin(_originalName.str()) || m_externallyUsedIdentifiers.count(_originalName)) return _originalName; assertThrow(!m_scopes.empty() && m_scopes.back(), OptimizerException, ""); diff --git a/libyul/optimiser/ExpressionSplitter.cpp b/libyul/optimiser/ExpressionSplitter.cpp index 9f9bf958f129..71a0963d5542 100644 --- a/libyul/optimiser/ExpressionSplitter.cpp +++ b/libyul/optimiser/ExpressionSplitter.cpp @@ -41,10 +41,10 @@ void ExpressionSplitter::run(OptimiserStepContext& _context, Block& _ast) void ExpressionSplitter::operator()(FunctionCall& _funCall) { - BuiltinFunction const* builtin = m_dialect.builtin(_funCall.functionName.name); + std::optional builtinHandle = m_dialect.findBuiltin(_funCall.functionName.name.str()); for (size_t i = _funCall.arguments.size(); i > 0; i--) - if (!builtin || !builtin->literalArgument(i - 1)) + if (!builtinHandle || !m_dialect.builtin(*builtinHandle).literalArgument(i - 1)) outlineExpression(_funCall.arguments[i - 1]); } diff --git a/libyul/optimiser/ForLoopConditionIntoBody.cpp b/libyul/optimiser/ForLoopConditionIntoBody.cpp index d0839e765ee8..b1f069e1b434 100644 --- a/libyul/optimiser/ForLoopConditionIntoBody.cpp +++ b/libyul/optimiser/ForLoopConditionIntoBody.cpp @@ -47,7 +47,7 @@ void ForLoopConditionIntoBody::operator()(ForLoop& _forLoop) std::make_unique( FunctionCall { debugData, - {debugData, m_dialect.booleanNegationFunction()->name}, + {debugData, YulName{m_dialect.builtin(*m_dialect.booleanNegationFunction()).name}}, util::make_vector(std::move(*_forLoop.condition)) } ), diff --git a/libyul/optimiser/ForLoopConditionOutOfBody.cpp b/libyul/optimiser/ForLoopConditionOutOfBody.cpp index afd005b719d5..0f6583285c14 100644 --- a/libyul/optimiser/ForLoopConditionOutOfBody.cpp +++ b/libyul/optimiser/ForLoopConditionOutOfBody.cpp @@ -36,7 +36,7 @@ void ForLoopConditionOutOfBody::operator()(ForLoop& _forLoop) ASTModifier::operator()(_forLoop); if ( - !m_dialect.booleanNegationFunction() || + !m_dialect.booleanNegationFunctionHandle() || !std::holds_alternative(*_forLoop.condition) || std::get(*_forLoop.condition).value.value() == 0 || _forLoop.body.statements.empty() || @@ -53,7 +53,7 @@ void ForLoopConditionOutOfBody::operator()(ForLoop& _forLoop) if (!SideEffectsCollector(m_dialect, *firstStatement.condition).movable()) return; - YulName iszero = m_dialect.booleanNegationFunction()->name; + YulName const iszero = YulName{m_dialect.builtin(*m_dialect.booleanNegationFunctionHandle()).name}; langutil::DebugData::ConstPtr debugData = debugDataOf(*firstStatement.condition); if ( diff --git a/libyul/optimiser/FullInliner.cpp b/libyul/optimiser/FullInliner.cpp index c6387f808e0e..df18a687f477 100644 --- a/libyul/optimiser/FullInliner.cpp +++ b/libyul/optimiser/FullInliner.cpp @@ -131,7 +131,7 @@ std::map FullInliner::callDepths() const // Remove calls to builtin functions. for (auto& call: cg.functionCalls) for (auto it = call.second.begin(); it != call.second.end();) - if (m_dialect.builtin(*it)) + if (m_dialect.findBuiltin(it->str())) it = call.second.erase(it); else ++it; diff --git a/libyul/optimiser/FunctionSpecializer.cpp b/libyul/optimiser/FunctionSpecializer.cpp index cb7cd4164b03..bab02a2e1813 100644 --- a/libyul/optimiser/FunctionSpecializer.cpp +++ b/libyul/optimiser/FunctionSpecializer.cpp @@ -55,7 +55,7 @@ void FunctionSpecializer::operator()(FunctionCall& _f) // TODO When backtracking is implemented, the restriction of recursive functions can be lifted. if ( - m_dialect.builtin(_f.functionName.name) || + m_dialect.findBuiltin(_f.functionName.name.str()) || m_recursiveFunctions.count(_f.functionName.name) ) return; diff --git a/libyul/optimiser/LoadResolver.cpp b/libyul/optimiser/LoadResolver.cpp index 98d938a3621e..9402bbfb370f 100644 --- a/libyul/optimiser/LoadResolver.cpp +++ b/libyul/optimiser/LoadResolver.cpp @@ -62,7 +62,7 @@ void LoadResolver::visit(Expression& _e) tryResolve(_e, StoreLoadLocation::Memory, funCall->arguments); else if (funCall->functionName.name == m_loadFunctionName[static_cast(StoreLoadLocation::Storage)]) tryResolve(_e, StoreLoadLocation::Storage, funCall->arguments); - else if (!m_containsMSize && funCall->functionName.name == m_dialect.hashFunction()) + else if (!m_containsMSize && funCall->functionName.name.str() == m_dialect.builtin(*m_dialect.hashFunction()).name) { Identifier const* start = std::get_if(&funCall->arguments.at(0)); Identifier const* length = std::get_if(&funCall->arguments.at(1)); diff --git a/libyul/optimiser/NameSimplifier.cpp b/libyul/optimiser/NameSimplifier.cpp index d57a61332e3e..6f3f1760a852 100644 --- a/libyul/optimiser/NameSimplifier.cpp +++ b/libyul/optimiser/NameSimplifier.cpp @@ -67,7 +67,7 @@ void NameSimplifier::operator()(Identifier& _identifier) void NameSimplifier::operator()(FunctionCall& _funCall) { // The visitor on its own does not visit the function name. - if (!m_context.dialect.builtin(_funCall.functionName.name)) + if (!m_context.dialect.findBuiltin(_funCall.functionName.name.str())) (*this)(_funCall.functionName); ASTModifier::operator()(_funCall); } diff --git a/libyul/optimiser/OptimizerUtilities.cpp b/libyul/optimiser/OptimizerUtilities.cpp index 19f262060fc0..001ff147d4b5 100644 --- a/libyul/optimiser/OptimizerUtilities.cpp +++ b/libyul/optimiser/OptimizerUtilities.cpp @@ -57,14 +57,14 @@ void yul::removeEmptyBlocks(Block& _block) bool yul::isRestrictedIdentifier(Dialect const& _dialect, YulName const& _identifier) { - return _identifier.empty() || hasLeadingOrTrailingDot(_identifier.str()) || TokenTraits::isYulKeyword(_identifier.str()) || _dialect.reservedIdentifier(_identifier); + return _identifier.empty() || hasLeadingOrTrailingDot(_identifier.str()) || TokenTraits::isYulKeyword(_identifier.str()) || _dialect.reservedIdentifier(_identifier.str()); } std::optional yul::toEVMInstruction(Dialect const& _dialect, YulName const& _name) { if (auto const* dialect = dynamic_cast(&_dialect)) - if (BuiltinFunctionForEVM const* builtin = dialect->builtin(_name)) - return builtin->instruction; + if (std::optional const builtinHandle = dialect->findBuiltin(_name.str())) + return dialect->builtin(*builtinHandle).instruction; return std::nullopt; } diff --git a/libyul/optimiser/Semantics.cpp b/libyul/optimiser/Semantics.cpp index d945dbcac7f5..5b5ad0eee197 100644 --- a/libyul/optimiser/Semantics.cpp +++ b/libyul/optimiser/Semantics.cpp @@ -78,8 +78,8 @@ void SideEffectsCollector::operator()(FunctionCall const& _functionCall) ASTWalker::operator()(_functionCall); YulName functionName = _functionCall.functionName.name; - if (BuiltinFunction const* f = m_dialect.builtin(functionName)) - m_sideEffects += f->sideEffects; + if (std::optional builtinHandle = m_dialect.findBuiltin(functionName.str())) + m_sideEffects += m_dialect.builtin(*builtinHandle).sideEffects; else if (m_functionSideEffects && m_functionSideEffects->count(functionName)) m_sideEffects += m_functionSideEffects->at(functionName); else @@ -110,8 +110,8 @@ void MSizeFinder::operator()(FunctionCall const& _functionCall) { ASTWalker::operator()(_functionCall); - if (BuiltinFunction const* f = m_dialect.builtin(_functionCall.functionName.name)) - if (f->isMSize) + if (std::optional builtinHandle = m_dialect.findBuiltin(_functionCall.functionName.name.str())) + if (m_dialect.builtin(*builtinHandle).isMSize) m_msizeFound = true; } @@ -144,8 +144,8 @@ std::map SideEffectsPropagator::sideEffects( return; if (sideEffects == SideEffects::worst()) return; - if (BuiltinFunction const* f = _dialect.builtin(_function)) - sideEffects += f->sideEffects; + if (std::optional builtinHandle = _dialect.findBuiltin(_function.str())) + sideEffects += _dialect.builtin(*builtinHandle).sideEffects; else { if (ret.count(_function)) @@ -227,8 +227,8 @@ bool TerminationFinder::containsNonContinuingFunctionCall(Expression const& _exp if (containsNonContinuingFunctionCall(arg)) return true; - if (auto builtin = m_dialect.builtin(functionCall->functionName.name)) - return !builtin->controlFlowSideEffects.canContinue; + if (std::optional const builtinHandle = m_dialect.findBuiltin(functionCall->functionName.name.str())) + return !m_dialect.builtin(*builtinHandle).controlFlowSideEffects.canContinue; else if (m_functionSideEffects && m_functionSideEffects->count(functionCall->functionName.name)) return !m_functionSideEffects->at(functionCall->functionName.name).canContinue; } diff --git a/libyul/optimiser/SimplificationRules.cpp b/libyul/optimiser/SimplificationRules.cpp index 72c0f70ca281..0fcd35bda1ed 100644 --- a/libyul/optimiser/SimplificationRules.cpp +++ b/libyul/optimiser/SimplificationRules.cpp @@ -79,9 +79,9 @@ std::optional const*>> { if (std::holds_alternative(_expr)) if (auto const* dialect = dynamic_cast(&_dialect)) - if (auto const* builtin = dialect->builtin(std::get(_expr).functionName.name)) - if (builtin->instruction) - return std::make_pair(*builtin->instruction, &std::get(_expr).arguments); + if (std::optional const builtinHandle = dialect->findBuiltin(std::get(_expr).functionName.name.str())) + if (auto const& instruction = dialect->builtin(*builtinHandle).instruction) + return std::make_pair(*instruction, &std::get(_expr).arguments); return {}; } diff --git a/libyul/optimiser/StackToMemoryMover.cpp b/libyul/optimiser/StackToMemoryMover.cpp index 7e3f93475f80..4b242c82f4fd 100644 --- a/libyul/optimiser/StackToMemoryMover.cpp +++ b/libyul/optimiser/StackToMemoryMover.cpp @@ -42,12 +42,12 @@ std::vector generateMemoryStore( Expression _value ) { - BuiltinFunction const* memoryStoreFunction = _dialect.memoryStoreFunction(); - yulAssert(memoryStoreFunction, ""); + std::optional memoryStoreFunctionHandle = _dialect.memoryStoreFunctionHandle(); + yulAssert(memoryStoreFunctionHandle); std::vector result; result.emplace_back(ExpressionStatement{_debugData, FunctionCall{ _debugData, - Identifier{_debugData, memoryStoreFunction->name}, + Identifier{_debugData, YulName{_dialect.builtin(*memoryStoreFunctionHandle).name}}, { Literal{_debugData, LiteralKind::Number, _mpos}, std::move(_value) @@ -58,11 +58,11 @@ std::vector generateMemoryStore( FunctionCall generateMemoryLoad(Dialect const& _dialect, langutil::DebugData::ConstPtr const& _debugData, LiteralValue const& _mpos) { - BuiltinFunction const* memoryLoadFunction = _dialect.memoryLoadFunction(); - yulAssert(memoryLoadFunction, ""); + std::optional const& memoryLoadHandle = _dialect.memoryStoreFunctionHandle(); + yulAssert(memoryLoadHandle); return FunctionCall{ _debugData, - Identifier{_debugData, memoryLoadFunction->name}, { + Identifier{_debugData, YulName{_dialect.builtin(*memoryLoadHandle).name}}, { Literal{ _debugData, LiteralKind::Number, @@ -223,7 +223,7 @@ void StackToMemoryMover::operator()(Block& _block) { FunctionCall const* functionCall = std::get_if(_stmt.value.get()); yulAssert(functionCall, ""); - if (m_context.dialect.builtin(functionCall->functionName.name)) + if (m_context.dialect.findBuiltin(functionCall->functionName.name.str())) rhsMemorySlots = std::vector>(_lhsVars.size(), std::nullopt); else rhsMemorySlots = diff --git a/libyul/optimiser/UnusedAssignEliminator.cpp b/libyul/optimiser/UnusedAssignEliminator.cpp index 13a6ba9ee526..eb639f8a6c3f 100644 --- a/libyul/optimiser/UnusedAssignEliminator.cpp +++ b/libyul/optimiser/UnusedAssignEliminator.cpp @@ -79,8 +79,8 @@ void UnusedAssignEliminator::operator()(FunctionCall const& _functionCall) UnusedStoreBase::operator()(_functionCall); ControlFlowSideEffects sideEffects; - if (auto builtin = m_dialect.builtin(_functionCall.functionName.name)) - sideEffects = builtin->controlFlowSideEffects; + if (std::optional const builtinHandle = m_dialect.findBuiltin(_functionCall.functionName.name.str())) + sideEffects = m_dialect.builtin(*builtinHandle).controlFlowSideEffects; else sideEffects = m_controlFlowSideEffects.at(_functionCall.functionName.name); diff --git a/libyul/optimiser/UnusedPruner.cpp b/libyul/optimiser/UnusedPruner.cpp index 75cdd2dd1796..a88000f09014 100644 --- a/libyul/optimiser/UnusedPruner.cpp +++ b/libyul/optimiser/UnusedPruner.cpp @@ -94,7 +94,7 @@ void UnusedPruner::operator()(Block& _block) else if (varDecl.variables.size() == 1 && m_dialect.discardFunction()) statement = ExpressionStatement{varDecl.debugData, FunctionCall{ varDecl.debugData, - {varDecl.debugData, m_dialect.discardFunction()->name}, + {varDecl.debugData, YulName{m_dialect.builtin(*m_dialect.discardFunction()).name}}, {*std::move(varDecl.value)} }}; } diff --git a/libyul/optimiser/UnusedStoreEliminator.cpp b/libyul/optimiser/UnusedStoreEliminator.cpp index c50ddac14412..f4f056697638 100644 --- a/libyul/optimiser/UnusedStoreEliminator.cpp +++ b/libyul/optimiser/UnusedStoreEliminator.cpp @@ -114,8 +114,8 @@ void UnusedStoreEliminator::operator()(FunctionCall const& _functionCall) applyOperation(op); ControlFlowSideEffects sideEffects; - if (auto builtin = m_dialect.builtin(_functionCall.functionName.name)) - sideEffects = builtin->controlFlowSideEffects; + if (std::optional const builtinHandle = m_dialect.findBuiltin(_functionCall.functionName.name.str())) + sideEffects = m_dialect.builtin(*builtinHandle).controlFlowSideEffects; else sideEffects = m_controlFlowSideEffects.at(_functionCall.functionName.name); @@ -230,8 +230,8 @@ std::vector UnusedStoreEliminator::operationsF YulName functionName = _functionCall.functionName.name; SideEffects sideEffects; - if (BuiltinFunction const* f = m_dialect.builtin(functionName)) - sideEffects = f->sideEffects; + if (std::optional const builtinHandle = m_dialect.findBuiltin(functionName.str())) + sideEffects = m_dialect.builtin(*builtinHandle).sideEffects; else sideEffects = m_functionSideEffects.at(functionName); diff --git a/test/libyul/Parser.cpp b/test/libyul/Parser.cpp index d0850972b442..d9ea91cbd351 100644 --- a/test/libyul/Parser.cpp +++ b/test/libyul/Parser.cpp @@ -133,13 +133,21 @@ BOOST_AUTO_TEST_SUITE(YulParser) BOOST_AUTO_TEST_CASE(builtins_analysis) { - struct SimpleDialect: public Dialect + struct SimpleDialect: Dialect { - BuiltinFunction const* builtin(YulName _name) const override + std::optional findBuiltin(std::string_view _name) const override { - return _name == "builtin"_yulname ? &f : nullptr; + if (_name == "builtin") + return BuiltinHandle{std::numeric_limits::max()}; + return std::nullopt; } - BuiltinFunction f{"builtin"_yulname, 2, 3, {}, {}, false, {}}; + + BuiltinFunction const& builtin(BuiltinHandle const& handle) const override + { + BOOST_REQUIRE(handle.id == std::numeric_limits::max()); + return f; + } + BuiltinFunction f{"builtin", 2, 3, {}, {}, false, {}}; }; SimpleDialect dialect; diff --git a/test/tools/yulInterpreter/EVMInstructionInterpreter.cpp b/test/tools/yulInterpreter/EVMInstructionInterpreter.cpp index 6ac3cd1bd817..b43021ea7a52 100644 --- a/test/tools/yulInterpreter/EVMInstructionInterpreter.cpp +++ b/test/tools/yulInterpreter/EVMInstructionInterpreter.cpp @@ -503,7 +503,7 @@ u256 EVMInstructionInterpreter::evalBuiltin( if (_fun.instruction) return eval(*_fun.instruction, _evaluatedArguments); - std::string fun = _fun.name.str(); + std::string const& fun = _fun.name; // Evaluate datasize/offset/copy instructions if (fun == "datasize" || fun == "dataoffset") { diff --git a/test/tools/yulInterpreter/Interpreter.cpp b/test/tools/yulInterpreter/Interpreter.cpp index 21e97f0769c8..433ff3f072e3 100644 --- a/test/tools/yulInterpreter/Interpreter.cpp +++ b/test/tools/yulInterpreter/Interpreter.cpp @@ -309,25 +309,29 @@ void ExpressionEvaluator::operator()(Identifier const& _identifier) void ExpressionEvaluator::operator()(FunctionCall const& _funCall) { std::vector> const* literalArguments = nullptr; - if (BuiltinFunction const* builtin = m_dialect.builtin(_funCall.functionName.name)) - if (!builtin->literalArguments.empty()) - literalArguments = &builtin->literalArguments; + if (std::optional builtinHandle = m_dialect.findBuiltin(_funCall.functionName.name.str())) + if ( + auto const& args = m_dialect.builtin(*builtinHandle).literalArguments; + !args.empty() + ) + literalArguments = &args; evaluateArgs(_funCall.arguments, literalArguments); if (EVMDialect const* dialect = dynamic_cast(&m_dialect)) { - if (BuiltinFunctionForEVM const* fun = dialect->builtin(_funCall.functionName.name)) + if (std::optional builtinHandle = dialect->findBuiltin(_funCall.functionName.name.str())) { + auto const& fun = dialect->builtin(*builtinHandle); EVMInstructionInterpreter interpreter(dialect->evmVersion(), m_state, m_disableMemoryTrace); - u256 const value = interpreter.evalBuiltin(*fun, _funCall.arguments, values()); + u256 const value = interpreter.evalBuiltin(fun, _funCall.arguments, values()); if ( !m_disableExternalCalls && - fun->instruction && - evmasm::isCallInstruction(*fun->instruction) + fun.instruction && + evmasm::isCallInstruction(*fun.instruction) ) - runExternalCall(*fun->instruction); + runExternalCall(*fun.instruction); setValue(value); return; From d8f69b90162ba3a65ad876a57e5449115ffb6d9b Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Thu, 17 Oct 2024 09:26:14 +0200 Subject: [PATCH 0518/1022] Yul EVM Dialect: Use address table for verbatim functions --- libyul/Dialect.h | 8 +-- .../backends/evm/ControlFlowGraphBuilder.cpp | 3 +- libyul/backends/evm/EVMDialect.cpp | 49 +++++++++------ libyul/backends/evm/EVMDialect.h | 13 ++-- libyul/backends/evm/NoOutputAssembly.cpp | 59 ++++++++++--------- libyul/backends/evm/NoOutputAssembly.h | 5 +- 6 files changed, 81 insertions(+), 56 deletions(-) diff --git a/libyul/Dialect.h b/libyul/Dialect.h index a707771a2512..20c2ae3f022c 100644 --- a/libyul/Dialect.h +++ b/libyul/Dialect.h @@ -59,16 +59,16 @@ struct BuiltinFunction struct Dialect { - static size_t constexpr verbatimMaxInputSlots = 100; - static size_t constexpr verbatimMaxOutputSlots = 100; - /// Noncopiable. Dialect(Dialect const&) = delete; Dialect& operator=(Dialect const&) = delete; - /// @returns the builtin function of the given name or a null if it is not a builtin function. + /// Finds a builtin by name and returns the corresponding handle. + /// @returns Builtin handle or null if the name does not match any builtin in the dialect. virtual std::optional findBuiltin(std::string_view /*_name*/) const { return std::nullopt; } + /// Retrieves the description of a builtin function by its handle. + /// Note that handles are dialect-specific and can be used only with a dialect that created them. virtual BuiltinFunction const& builtin(BuiltinHandle const&) const { yulAssert(false); } /// @returns true if the identifier is reserved. This includes the builtins too. diff --git a/libyul/backends/evm/ControlFlowGraphBuilder.cpp b/libyul/backends/evm/ControlFlowGraphBuilder.cpp index 1b523c4dd7e8..4596b225253e 100644 --- a/libyul/backends/evm/ControlFlowGraphBuilder.cpp +++ b/libyul/backends/evm/ControlFlowGraphBuilder.cpp @@ -360,10 +360,11 @@ void ControlFlowGraphBuilder::operator()(Switch const& _switch) yul::Identifier{{}, "eq"_yulname}, {*_case.value, Identifier{{}, ghostVariableName}} }); + BuiltinFunction const& equalityBuiltin = m_dialect.builtin(*equalityBuiltinHandle); CFG::Operation& operation = m_currentBlock->operations.emplace_back(CFG::Operation{ Stack{ghostVarSlot, LiteralSlot{_case.value->value.value(), debugDataOf(*_case.value)}}, Stack{TemporarySlot{ghostCall, 0}}, - CFG::BuiltinCall{debugDataOf(_case), m_dialect.builtin(*equalityBuiltinHandle), ghostCall, 2}, + CFG::BuiltinCall{debugDataOf(_case), equalityBuiltin, ghostCall, 2}, }); return operation.output.front(); }; diff --git a/libyul/backends/evm/EVMDialect.cpp b/libyul/backends/evm/EVMDialect.cpp index e50e849d700f..e9beabef6df9 100644 --- a/libyul/backends/evm/EVMDialect.cpp +++ b/libyul/backends/evm/EVMDialect.cpp @@ -45,6 +45,17 @@ using namespace solidity::util; namespace { +size_t constexpr toContinuousVerbatimIndex(size_t _arguments, size_t _returnVariables) +{ + return _arguments + _returnVariables * EVMDialect::verbatimMaxInputSlots; +} + +std::tuple constexpr verbatimIndexToArgsAndRets(size_t _index) +{ + size_t const numRets = _index / EVMDialect::verbatimMaxInputSlots; + return std::make_tuple(_index - numRets * EVMDialect::verbatimMaxInputSlots, numRets); +} + BuiltinFunctionForEVM createEVMFunction( langutil::EVMVersion _evmVersion, std::string const& _name, @@ -408,7 +419,7 @@ EVMDialect::EVMDialect(langutil::EVMVersion _evmVersion, std::optional for (auto const& [index, maybeBuiltin]: m_functions | ranges::views::enumerate) if (maybeBuiltin) // ids are offset by the maximum number of verbatim functions - m_builtinFunctionsByName[maybeBuiltin->name] = BuiltinHandle{index + verbatimIdOffset}; + m_builtinFunctionsByName[maybeBuiltin->name] = BuiltinHandle{index + verbatimIDOffset}; m_discardFunction = findBuiltin("pop"); m_equalityFunction = findBuiltin("eq"); @@ -499,16 +510,13 @@ SideEffects EVMDialect::sideEffectsOfInstruction(evmasm::Instruction _instructio }; } -BuiltinHandle EVMDialect::verbatimFunction(size_t _arguments, size_t _returnVariables) const +BuiltinFunctionForEVM EVMDialect::createVerbatimFunctionFromHandle(BuiltinHandle const& _handle) { - auto const it = std::find_if(m_verbatimFunctions.begin(), m_verbatimFunctions.end(), [&](BuiltinFunctionForEVM const& _function) { - return _function.numParameters == 1 + _arguments && _function.numReturns == _returnVariables; - }); - yulAssert(_arguments <= verbatimMaxInputSlots); - yulAssert(_returnVariables <= verbatimMaxOutputSlots); - if (it != m_verbatimFunctions.end()) - return {static_cast(std::distance(m_verbatimFunctions.begin(), it))}; + return std::apply(createVerbatimFunction, verbatimIndexToArgsAndRets(_handle.id)); +} +BuiltinFunctionForEVM EVMDialect::createVerbatimFunction(size_t _arguments, size_t _returnVariables) +{ BuiltinFunctionForEVM builtinFunction = createFunction( "verbatim_" + std::to_string(_arguments) + "i_" + std::to_string(_returnVariables) + "o", 1 + _arguments, @@ -531,17 +539,22 @@ BuiltinHandle EVMDialect::verbatimFunction(size_t _arguments, size_t _returnVari } ); builtinFunction.isMSize = true; - m_verbatimFunctions.push_back(std::move(builtinFunction)); - yulAssert(m_verbatimFunctions.size() <= verbatimIdOffset); - return {m_verbatimFunctions.size() - 1}; + return builtinFunction; } -BuiltinFunctionForEVM const& EVMDialect::builtin(BuiltinHandle const& handle) const +BuiltinHandle EVMDialect::verbatimFunction(size_t _arguments, size_t _returnVariables) const { - if (handle.id < verbatimIdOffset) - return m_verbatimFunctions.at(handle.id); + yulAssert(_arguments <= verbatimMaxInputSlots); + yulAssert(_returnVariables <= verbatimMaxOutputSlots); - auto const& maybeBuiltin = m_functions.at(handle.id - verbatimIdOffset); - yulAssert(maybeBuiltin.has_value()); - return *maybeBuiltin; + auto const verbatimIndex = toContinuousVerbatimIndex(_arguments, _returnVariables); + yulAssert(verbatimIndex < verbatimIDOffset); + + if ( + auto& backingData = m_verbatimFunctions[verbatimIndex]; + !backingData + ) + backingData = std::make_unique(createVerbatimFunction(_arguments, _returnVariables)); + + return {verbatimIndex}; } diff --git a/libyul/backends/evm/EVMDialect.h b/libyul/backends/evm/EVMDialect.h index 45be636d811d..b784866285a7 100644 --- a/libyul/backends/evm/EVMDialect.h +++ b/libyul/backends/evm/EVMDialect.h @@ -62,8 +62,9 @@ struct BuiltinFunctionForEVM: public BuiltinFunction * The main difference is that the builtin functions take an AbstractAssembly for the * code generation. */ -struct EVMDialect: Dialect +class EVMDialect: public Dialect { +public: /// Constructor, should only be used internally. Use the factory functions below. EVMDialect(langutil::EVMVersion _evmVersion, std::optional _eofVersion, bool _objectAccess); @@ -93,18 +94,22 @@ struct EVMDialect: Dialect static SideEffects sideEffectsOfInstruction(evmasm::Instruction _instruction); - std::vector const& verbatimFunctions() const { return m_verbatimFunctions; } + static size_t constexpr verbatimMaxInputSlots = 100; + static size_t constexpr verbatimMaxOutputSlots = 100; protected: + static bool constexpr isVerbatimHandle(BuiltinHandle const& _handle) { return _handle.id < verbatimIDOffset; } + static BuiltinFunctionForEVM createVerbatimFunctionFromHandle(BuiltinHandle const& _handle); + static BuiltinFunctionForEVM createVerbatimFunction(size_t _arguments, size_t _returnVariables); BuiltinHandle verbatimFunction(size_t _arguments, size_t _returnVariables) const; - static size_t constexpr verbatimIdOffset = verbatimMaxInputSlots * verbatimMaxOutputSlots; + static size_t constexpr verbatimIDOffset = verbatimMaxInputSlots * verbatimMaxOutputSlots; bool const m_objectAccess; langutil::EVMVersion const m_evmVersion; std::optional m_eofVersion; std::vector> m_functions; - std::vector mutable m_verbatimFunctions; + std::array, verbatimIDOffset> mutable m_verbatimFunctions{}; std::set> m_reserved; std::optional m_discardFunction; diff --git a/libyul/backends/evm/NoOutputAssembly.cpp b/libyul/backends/evm/NoOutputAssembly.cpp index 19d21bccd54a..97bf962d0a0c 100644 --- a/libyul/backends/evm/NoOutputAssembly.cpp +++ b/libyul/backends/evm/NoOutputAssembly.cpp @@ -33,6 +33,23 @@ using namespace solidity::yul; using namespace solidity::util; using namespace solidity::langutil; +namespace +{ + +void modifyBuiltinToNoOutput(BuiltinFunctionForEVM& _builtin) +{ + _builtin.generateCode = [fun=_builtin](FunctionCall const& _call, AbstractAssembly& _assembly, BuiltinContext&) + { + for (size_t i: ranges::views::iota(0u, _call.arguments.size())) + if (!fun.literalArgument(i)) + _assembly.appendInstruction(evmasm::Instruction::POP); + + for (size_t i = 0; i < fun.numReturns; i++) + _assembly.appendConstant(u256(0)); + }; +} + +} void NoOutputAssembly::appendInstruction(evmasm::Instruction _instr) { @@ -138,35 +155,21 @@ NoOutputEVMDialect::NoOutputEVMDialect(EVMDialect const& _copyFrom): EVMDialect(_copyFrom.evmVersion(), _copyFrom.eofVersion(), _copyFrom.providesObjectAccess()) { for (auto& fun: m_functions) - { if (fun) - { - size_t returns = fun.value().numReturns; - fun.value().generateCode = [=](FunctionCall const& _call, AbstractAssembly& _assembly, BuiltinContext&) - { - for (size_t i: ranges::views::iota(0u, _call.arguments.size())) - if (!fun.value().literalArgument(i)) - _assembly.appendInstruction(evmasm::Instruction::POP); - - for (size_t i = 0; i < returns; i++) - _assembly.appendConstant(u256(0)); - }; - } - } + modifyBuiltinToNoOutput(*fun); +} - m_verbatimFunctions = _copyFrom.verbatimFunctions(); - for (auto& entry: m_verbatimFunctions) - { - auto const& fun = entry; - auto returns = fun.numReturns; - entry.generateCode = [returns, fun](FunctionCall const& _call, AbstractAssembly& _assembly, BuiltinContext&) +BuiltinFunctionForEVM const& NoOutputEVMDialect::builtin(BuiltinHandle const& _handle) const +{ + if (isVerbatimHandle(_handle)) + // for verbatims the modification is performed lazily as they are stored in a lookup table fashion + if ( + auto& builtin = m_verbatimFunctions[_handle.id]; + !builtin + ) { - for (size_t i: ranges::views::iota(0u, _call.arguments.size())) - if (!fun.literalArgument(i)) - _assembly.appendInstruction(evmasm::Instruction::POP); - - for (size_t i = 0; i < returns; i++) - _assembly.appendConstant(u256(0)); - }; - } + builtin = std::make_unique(createVerbatimFunctionFromHandle(_handle)); + modifyBuiltinToNoOutput(*builtin); + } + return EVMDialect::builtin(_handle); } diff --git a/libyul/backends/evm/NoOutputAssembly.h b/libyul/backends/evm/NoOutputAssembly.h index 6d3aacb248a0..cc70d75afdae 100644 --- a/libyul/backends/evm/NoOutputAssembly.h +++ b/libyul/backends/evm/NoOutputAssembly.h @@ -90,9 +90,12 @@ class NoOutputAssembly: public AbstractAssembly /** * EVM dialect that does not generate any code. */ -struct NoOutputEVMDialect: public EVMDialect +class NoOutputEVMDialect: public EVMDialect { +public: explicit NoOutputEVMDialect(EVMDialect const& _copyFrom); + + BuiltinFunctionForEVM const& builtin(BuiltinHandle const& _handle) const override; }; From 308827570328959e75c113201d91338f18da4614 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Thu, 17 Oct 2024 11:06:05 +0200 Subject: [PATCH 0519/1022] Yul EVM Dialect: Helper map for builtin function lookup --- libyul/backends/evm/EVMDialect.cpp | 35 ++++++++++++++++-------------- libyul/backends/evm/EVMDialect.h | 3 ++- 2 files changed, 21 insertions(+), 17 deletions(-) diff --git a/libyul/backends/evm/EVMDialect.cpp b/libyul/backends/evm/EVMDialect.cpp index e9beabef6df9..e95e2246fcf2 100644 --- a/libyul/backends/evm/EVMDialect.cpp +++ b/libyul/backends/evm/EVMDialect.cpp @@ -402,7 +402,7 @@ std::vector> createBuiltins(langutil::EVMVe std::regex const& verbatimPattern() { - std::regex static const pattern{"verbatim_([1-9]?[0-9])i_([1-9]?[0-9])o"}; + std::regex static const pattern{"([1-9]?[0-9])i_([1-9]?[0-9])o"}; return pattern; } @@ -433,32 +433,35 @@ EVMDialect::EVMDialect(langutil::EVMVersion _evmVersion, std::optional std::optional EVMDialect::findBuiltin(std::string_view _name) const { - if (m_objectAccess) + if (m_objectAccess && _name.substr(0, "verbatim_"s.size()) == "verbatim_") { std::smatch match; - std::string name(_name); + std::string name(_name.substr("verbatim_"s.size())); if (regex_match(name, match, verbatimPattern())) return verbatimFunction(stoul(match[1]), stoul(match[2])); } - auto it = std::find_if(m_functions.begin(), m_functions.end(), [&_name](auto const& builtin) { return builtin && builtin.value().name == _name; }); - if (it != m_functions.end() && *it && it->value().name == _name) - // ids are offset by the maximum number of verbatim functions - return BuiltinHandle{static_cast(std::distance(m_functions.begin(), it)) + verbatimIdOffset}; + + if ( + auto it = m_builtinFunctionsByName.find(_name); + it != m_builtinFunctionsByName.end() + ) + return it->second; + return std::nullopt; } -BuiltinFunctionForEVM const& EVMDialect::builtin(BuiltinHandle const& handle) const +BuiltinFunctionForEVM const& EVMDialect::builtin(BuiltinHandle const& _handle) const { - if (isVerbatimHandle(handle)) + if (isVerbatimHandle(_handle)) { - yulAssert(handle.id < verbatimIDOffset); - auto const& verbatimFunctionPtr = m_verbatimFunctions[handle.id]; + yulAssert(_handle.id < verbatimIDOffset); + auto const& verbatimFunctionPtr = m_verbatimFunctions[_handle.id]; yulAssert(verbatimFunctionPtr); return *verbatimFunctionPtr; } - yulAssert(handle.id - verbatimIDOffset < m_functions.size()); - auto const& maybeBuiltin = m_functions[handle.id - verbatimIDOffset]; + yulAssert(_handle.id - verbatimIDOffset < m_functions.size()); + auto const& maybeBuiltin = m_functions[_handle.id - verbatimIDOffset]; yulAssert(maybeBuiltin.has_value()); return *maybeBuiltin; } @@ -551,10 +554,10 @@ BuiltinHandle EVMDialect::verbatimFunction(size_t _arguments, size_t _returnVari yulAssert(verbatimIndex < verbatimIDOffset); if ( - auto& backingData = m_verbatimFunctions[verbatimIndex]; - !backingData + auto& verbatimFunctionPtr = m_verbatimFunctions[verbatimIndex]; + !verbatimFunctionPtr ) - backingData = std::make_unique(createVerbatimFunction(_arguments, _returnVariables)); + verbatimFunctionPtr = std::make_unique(createVerbatimFunction(_arguments, _returnVariables)); return {verbatimIndex}; } diff --git a/libyul/backends/evm/EVMDialect.h b/libyul/backends/evm/EVMDialect.h index b784866285a7..f6ebb93409b0 100644 --- a/libyul/backends/evm/EVMDialect.h +++ b/libyul/backends/evm/EVMDialect.h @@ -70,7 +70,7 @@ class EVMDialect: public Dialect std::optional findBuiltin(std::string_view _name) const override; - BuiltinFunctionForEVM const& builtin(BuiltinHandle const& handle) const override; + BuiltinFunctionForEVM const& builtin(BuiltinHandle const& _handle) const override; /// @returns true if the identifier is reserved. This includes the builtins too. bool reservedIdentifier(std::string_view _name) const override; @@ -108,6 +108,7 @@ class EVMDialect: public Dialect bool const m_objectAccess; langutil::EVMVersion const m_evmVersion; std::optional m_eofVersion; + std::unordered_map m_builtinFunctionsByName; std::vector> m_functions; std::array, verbatimIDOffset> mutable m_verbatimFunctions{}; std::set> m_reserved; From 6a2631e02574a588eb3bac8305133750be9c568e Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Thu, 17 Oct 2024 11:50:33 +0200 Subject: [PATCH 0520/1022] Yul Dialect: Rename functions to function handles --- libyul/Dialect.h | 19 +++++++++---------- .../backends/evm/ControlFlowGraphBuilder.cpp | 2 +- libyul/backends/evm/EVMDialect.h | 17 ++++++++--------- libyul/backends/evm/EVMMetrics.h | 2 +- libyul/backends/evm/EVMObjectCompiler.h | 2 +- libyul/backends/evm/NoOutputAssembly.cpp | 6 +++--- libyul/optimiser/ControlFlowSimplifier.cpp | 14 +++++++------- libyul/optimiser/DataFlowAnalyzer.cpp | 10 +++++----- libyul/optimiser/ForLoopConditionIntoBody.cpp | 4 ++-- .../optimiser/ForLoopConditionOutOfBody.cpp | 2 +- libyul/optimiser/LoadResolver.cpp | 2 +- libyul/optimiser/Metrics.h | 2 +- libyul/optimiser/StackToMemoryMover.cpp | 2 +- libyul/optimiser/UnusedPruner.cpp | 4 ++-- 14 files changed, 43 insertions(+), 45 deletions(-) diff --git a/libyul/Dialect.h b/libyul/Dialect.h index 20c2ae3f022c..62d18bdf0ec8 100644 --- a/libyul/Dialect.h +++ b/libyul/Dialect.h @@ -74,16 +74,15 @@ struct Dialect /// @returns true if the identifier is reserved. This includes the builtins too. virtual bool reservedIdentifier(std::string_view _name) const { return findBuiltin(_name).has_value(); } - // todo these are handles, not functions - virtual std::optional discardFunction() const { return std::nullopt; } - virtual std::optional equalityFunction() const { return std::nullopt; } - virtual std::optional booleanNegationFunction() const { return std::nullopt; } - - virtual std::optional memoryStoreFunction() const { return std::nullopt; } - virtual std::optional memoryLoadFunction() const { return std::nullopt; } - virtual std::optional storageStoreFunction() const { return std::nullopt; } - virtual std::optional storageLoadFunction() const { return std::nullopt; } - virtual std::optional hashFunction() const { return std::nullopt; } + virtual std::optional discardFunctionHandle() const { return std::nullopt; } + virtual std::optional equalityFunctionHandle() const { return std::nullopt; } + virtual std::optional booleanNegationFunctionHandle() const { return std::nullopt; } + + virtual std::optional memoryStoreFunctionHandle() const { return std::nullopt; } + virtual std::optional memoryLoadFunctionHandle() const { return std::nullopt; } + virtual std::optional storageStoreFunctionHandle() const { return std::nullopt; } + virtual std::optional storageLoadFunctionHandle() const { return std::nullopt; } + virtual std::optional hashFunctionHandle() const { return std::nullopt; } Literal zeroLiteral() const; diff --git a/libyul/backends/evm/ControlFlowGraphBuilder.cpp b/libyul/backends/evm/ControlFlowGraphBuilder.cpp index 4596b225253e..fe6e0ec8ee1d 100644 --- a/libyul/backends/evm/ControlFlowGraphBuilder.cpp +++ b/libyul/backends/evm/ControlFlowGraphBuilder.cpp @@ -349,7 +349,7 @@ void ControlFlowGraphBuilder::operator()(Switch const& _switch) CFG::Assignment{_switch.debugData, {ghostVarSlot}} }); - std::optional const& equalityBuiltinHandle = m_dialect.equalityFunction(); + std::optional const& equalityBuiltinHandle = m_dialect.equalityFunctionHandle(); yulAssert(equalityBuiltinHandle); // Artificially generate: diff --git a/libyul/backends/evm/EVMDialect.h b/libyul/backends/evm/EVMDialect.h index f6ebb93409b0..1443b44811fa 100644 --- a/libyul/backends/evm/EVMDialect.h +++ b/libyul/backends/evm/EVMDialect.h @@ -72,17 +72,16 @@ class EVMDialect: public Dialect BuiltinFunctionForEVM const& builtin(BuiltinHandle const& _handle) const override; - /// @returns true if the identifier is reserved. This includes the builtins too. bool reservedIdentifier(std::string_view _name) const override; - std::optional discardFunction() const override { return m_discardFunction; } - std::optional equalityFunction() const override { return m_equalityFunction; } - std::optional booleanNegationFunction() const override { return m_booleanNegationFunction; } - std::optional memoryStoreFunction() const override { return m_memoryStoreFunction; } - std::optional memoryLoadFunction() const override { return m_memoryLoadFunction; } - std::optional storageStoreFunction() const override { return m_storageStoreFunction; } - std::optional storageLoadFunction() const override { return m_storageLoadFunction; } - std::optional hashFunction() const override { return m_hashFunction; } + std::optional discardFunctionHandle() const override { return m_discardFunction; } + std::optional equalityFunctionHandle() const override { return m_equalityFunction; } + std::optional booleanNegationFunctionHandle() const override { return m_booleanNegationFunction; } + std::optional memoryStoreFunctionHandle() const override { return m_memoryStoreFunction; } + std::optional memoryLoadFunctionHandle() const override { return m_memoryLoadFunction; } + std::optional storageStoreFunctionHandle() const override { return m_storageStoreFunction; } + std::optional storageLoadFunctionHandle() const override { return m_storageLoadFunction; } + std::optional hashFunctionHandle() const override { return m_hashFunction; } static EVMDialect const& strictAssemblyForEVM(langutil::EVMVersion _evmVersion, std::optional _eofVersion); static EVMDialect const& strictAssemblyForEVMObjects(langutil::EVMVersion _evmVersion, std::optional _eofVersion); diff --git a/libyul/backends/evm/EVMMetrics.h b/libyul/backends/evm/EVMMetrics.h index b67cb77cdd50..1475246f1686 100644 --- a/libyul/backends/evm/EVMMetrics.h +++ b/libyul/backends/evm/EVMMetrics.h @@ -29,7 +29,7 @@ namespace solidity::yul { -struct EVMDialect; +class EVMDialect; /** * Gas meter for expressions only involving literals, identifiers and diff --git a/libyul/backends/evm/EVMObjectCompiler.h b/libyul/backends/evm/EVMObjectCompiler.h index d37ade2cd211..07ba34a75458 100644 --- a/libyul/backends/evm/EVMObjectCompiler.h +++ b/libyul/backends/evm/EVMObjectCompiler.h @@ -28,7 +28,7 @@ namespace solidity::yul { struct Object; class AbstractAssembly; -struct EVMDialect; +class EVMDialect; class EVMObjectCompiler { diff --git a/libyul/backends/evm/NoOutputAssembly.cpp b/libyul/backends/evm/NoOutputAssembly.cpp index 97bf962d0a0c..5e82cc6fd3a5 100644 --- a/libyul/backends/evm/NoOutputAssembly.cpp +++ b/libyul/backends/evm/NoOutputAssembly.cpp @@ -38,13 +38,13 @@ namespace void modifyBuiltinToNoOutput(BuiltinFunctionForEVM& _builtin) { - _builtin.generateCode = [fun=_builtin](FunctionCall const& _call, AbstractAssembly& _assembly, BuiltinContext&) + _builtin.generateCode = [_builtin](FunctionCall const& _call, AbstractAssembly& _assembly, BuiltinContext&) { for (size_t i: ranges::views::iota(0u, _call.arguments.size())) - if (!fun.literalArgument(i)) + if (!_builtin.literalArgument(i)) _assembly.appendInstruction(evmasm::Instruction::POP); - for (size_t i = 0; i < fun.numReturns; i++) + for (size_t i = 0; i < _builtin.numReturns; i++) _assembly.appendConstant(u256(0)); }; } diff --git a/libyul/optimiser/ControlFlowSimplifier.cpp b/libyul/optimiser/ControlFlowSimplifier.cpp index 478d7b9d911b..a9a8282a680e 100644 --- a/libyul/optimiser/ControlFlowSimplifier.cpp +++ b/libyul/optimiser/ControlFlowSimplifier.cpp @@ -136,12 +136,12 @@ void ControlFlowSimplifier::simplify(std::vector& _statements) GenericVisitor visitor{ VisitorFallback{}, [&](If& _ifStmt) -> OptionalStatements { - if (_ifStmt.body.statements.empty() && m_dialect.discardFunction()) + if (_ifStmt.body.statements.empty() && m_dialect.discardFunctionHandle()) { OptionalStatements s = std::vector{}; s->emplace_back(makeDiscardCall( _ifStmt.debugData, - m_dialect.builtin(*m_dialect.discardFunction()), + m_dialect.builtin(*m_dialect.discardFunctionHandle()), std::move(*_ifStmt.condition) )); return s; @@ -178,7 +178,7 @@ OptionalStatements ControlFlowSimplifier::reduceNoCaseSwitch(Switch& _switchStmt { yulAssert(_switchStmt.cases.empty(), "Expected no case!"); std::optional discardFunctionHandle = - m_dialect.discardFunction(); + m_dialect.discardFunctionHandle(); if (!discardFunctionHandle) return {}; @@ -197,13 +197,13 @@ OptionalStatements ControlFlowSimplifier::reduceSingleCaseSwitch(Switch& _switch langutil::DebugData::ConstPtr debugData = debugDataOf(*_switchStmt.expression); if (switchCase.value) { - if (!m_dialect.equalityFunction()) + if (!m_dialect.equalityFunctionHandle()) return {}; return make_vector(If{ std::move(_switchStmt.debugData), std::make_unique(FunctionCall{ debugData, - Identifier{debugData, YulName{m_dialect.builtin(*m_dialect.equalityFunction()).name}}, + Identifier{debugData, YulName{m_dialect.builtin(*m_dialect.equalityFunctionHandle()).name}}, {std::move(*switchCase.value), std::move(*_switchStmt.expression)} }), std::move(switchCase.body) @@ -211,13 +211,13 @@ OptionalStatements ControlFlowSimplifier::reduceSingleCaseSwitch(Switch& _switch } else { - if (!m_dialect.discardFunction()) + if (!m_dialect.discardFunctionHandle()) return {}; return make_vector( makeDiscardCall( debugData, - m_dialect.builtin(*m_dialect.discardFunction()), + m_dialect.builtin(*m_dialect.discardFunctionHandle()), std::move(*_switchStmt.expression) ), std::move(switchCase.body) diff --git a/libyul/optimiser/DataFlowAnalyzer.cpp b/libyul/optimiser/DataFlowAnalyzer.cpp index 022ac199ebb2..8b3282888865 100644 --- a/libyul/optimiser/DataFlowAnalyzer.cpp +++ b/libyul/optimiser/DataFlowAnalyzer.cpp @@ -54,13 +54,13 @@ DataFlowAnalyzer::DataFlowAnalyzer( { if (m_analyzeStores) { - if (auto const& builtinHandle = _dialect.memoryStoreFunction()) + if (auto const& builtinHandle = _dialect.memoryStoreFunctionHandle()) m_storeFunctionName[static_cast(StoreLoadLocation::Memory)] = YulName{_dialect.builtin(*builtinHandle).name}; - if (auto const& builtinHandle = _dialect.memoryLoadFunction()) + if (auto const& builtinHandle = _dialect.memoryLoadFunctionHandle()) m_loadFunctionName[static_cast(StoreLoadLocation::Memory)] = YulName{_dialect.builtin(*builtinHandle).name}; - if (auto const& builtinHandle = _dialect.storageStoreFunction()) + if (auto const& builtinHandle = _dialect.storageStoreFunctionHandle()) m_storeFunctionName[static_cast(StoreLoadLocation::Storage)] = YulName{_dialect.builtin(*builtinHandle).name}; - if (auto const& builtinHandle = _dialect.storageLoadFunction()) + if (auto const& builtinHandle = _dialect.storageLoadFunctionHandle()) m_loadFunctionName[static_cast(StoreLoadLocation::Storage)] = YulName{_dialect.builtin(*builtinHandle).name}; } } @@ -446,7 +446,7 @@ std::optional DataFlowAnalyzer::isSimpleLoad( std::optional> DataFlowAnalyzer::isKeccak(Expression const& _expression) const { if (FunctionCall const* funCall = std::get_if(&_expression)) - if (funCall->functionName.name.str() == m_dialect.builtin(*m_dialect.hashFunction()).name) + if (funCall->functionName.name.str() == m_dialect.builtin(*m_dialect.hashFunctionHandle()).name) if (Identifier const* start = std::get_if(&funCall->arguments.at(0))) if (Identifier const* length = std::get_if(&funCall->arguments.at(1))) return std::make_pair(start->name, length->name); diff --git a/libyul/optimiser/ForLoopConditionIntoBody.cpp b/libyul/optimiser/ForLoopConditionIntoBody.cpp index b1f069e1b434..7ee9a9b8c5d5 100644 --- a/libyul/optimiser/ForLoopConditionIntoBody.cpp +++ b/libyul/optimiser/ForLoopConditionIntoBody.cpp @@ -33,7 +33,7 @@ void ForLoopConditionIntoBody::run(OptimiserStepContext& _context, Block& _ast) void ForLoopConditionIntoBody::operator()(ForLoop& _forLoop) { if ( - m_dialect.booleanNegationFunction() && + m_dialect.booleanNegationFunctionHandle() && !std::holds_alternative(*_forLoop.condition) && !std::holds_alternative(*_forLoop.condition) ) @@ -47,7 +47,7 @@ void ForLoopConditionIntoBody::operator()(ForLoop& _forLoop) std::make_unique( FunctionCall { debugData, - {debugData, YulName{m_dialect.builtin(*m_dialect.booleanNegationFunction()).name}}, + {debugData, YulName{m_dialect.builtin(*m_dialect.booleanNegationFunctionHandle()).name}}, util::make_vector(std::move(*_forLoop.condition)) } ), diff --git a/libyul/optimiser/ForLoopConditionOutOfBody.cpp b/libyul/optimiser/ForLoopConditionOutOfBody.cpp index 0f6583285c14..d082bb78d676 100644 --- a/libyul/optimiser/ForLoopConditionOutOfBody.cpp +++ b/libyul/optimiser/ForLoopConditionOutOfBody.cpp @@ -53,7 +53,7 @@ void ForLoopConditionOutOfBody::operator()(ForLoop& _forLoop) if (!SideEffectsCollector(m_dialect, *firstStatement.condition).movable()) return; - YulName const iszero = YulName{m_dialect.builtin(*m_dialect.booleanNegationFunctionHandle()).name}; + YulName const iszero{m_dialect.builtin(*m_dialect.booleanNegationFunctionHandle()).name}; langutil::DebugData::ConstPtr debugData = debugDataOf(*firstStatement.condition); if ( diff --git a/libyul/optimiser/LoadResolver.cpp b/libyul/optimiser/LoadResolver.cpp index 9402bbfb370f..d6961b6f8ca3 100644 --- a/libyul/optimiser/LoadResolver.cpp +++ b/libyul/optimiser/LoadResolver.cpp @@ -62,7 +62,7 @@ void LoadResolver::visit(Expression& _e) tryResolve(_e, StoreLoadLocation::Memory, funCall->arguments); else if (funCall->functionName.name == m_loadFunctionName[static_cast(StoreLoadLocation::Storage)]) tryResolve(_e, StoreLoadLocation::Storage, funCall->arguments); - else if (!m_containsMSize && funCall->functionName.name.str() == m_dialect.builtin(*m_dialect.hashFunction()).name) + else if (!m_containsMSize && funCall->functionName.name.str() == m_dialect.builtin(*m_dialect.hashFunctionHandle()).name) { Identifier const* start = std::get_if(&funCall->arguments.at(0)); Identifier const* length = std::get_if(&funCall->arguments.at(1)); diff --git a/libyul/optimiser/Metrics.h b/libyul/optimiser/Metrics.h index 01ab1adbd7e3..53ff25325996 100644 --- a/libyul/optimiser/Metrics.h +++ b/libyul/optimiser/Metrics.h @@ -28,7 +28,7 @@ namespace solidity::yul { struct Dialect; -struct EVMDialect; +class EVMDialect; /** * Weights to be assigned to specific yul statements and expressions by a metric. diff --git a/libyul/optimiser/StackToMemoryMover.cpp b/libyul/optimiser/StackToMemoryMover.cpp index 4b242c82f4fd..e75472f068f5 100644 --- a/libyul/optimiser/StackToMemoryMover.cpp +++ b/libyul/optimiser/StackToMemoryMover.cpp @@ -58,7 +58,7 @@ std::vector generateMemoryStore( FunctionCall generateMemoryLoad(Dialect const& _dialect, langutil::DebugData::ConstPtr const& _debugData, LiteralValue const& _mpos) { - std::optional const& memoryLoadHandle = _dialect.memoryStoreFunctionHandle(); + std::optional const& memoryLoadHandle = _dialect.memoryLoadFunctionHandle(); yulAssert(memoryLoadHandle); return FunctionCall{ _debugData, diff --git a/libyul/optimiser/UnusedPruner.cpp b/libyul/optimiser/UnusedPruner.cpp index a88000f09014..9f6b88412f9c 100644 --- a/libyul/optimiser/UnusedPruner.cpp +++ b/libyul/optimiser/UnusedPruner.cpp @@ -91,10 +91,10 @@ void UnusedPruner::operator()(Block& _block) subtractReferences(ReferencesCounter::countReferences(*varDecl.value)); statement = Block{std::move(varDecl.debugData), {}}; } - else if (varDecl.variables.size() == 1 && m_dialect.discardFunction()) + else if (varDecl.variables.size() == 1 && m_dialect.discardFunctionHandle()) statement = ExpressionStatement{varDecl.debugData, FunctionCall{ varDecl.debugData, - {varDecl.debugData, YulName{m_dialect.builtin(*m_dialect.discardFunction()).name}}, + {varDecl.debugData, YulName{m_dialect.builtin(*m_dialect.discardFunctionHandle()).name}}, {*std::move(varDecl.value)} }}; } From 752c26fbb2f461c311e8aea8381b6efc5091d6c1 Mon Sep 17 00:00:00 2001 From: DaniPopes <57450786+DaniPopes@users.noreply.github.com> Date: Mon, 21 Oct 2024 11:03:18 +0200 Subject: [PATCH 0521/1022] Correct Yul test file extensions (#15527) Some test files in tests/libyul have a .sol file extension but are invalid Solidity code. Rename them to .yul. Command used: ```bash for f in $(fd -e sol . test/libyul); do mv $f $(basename $f .sol).yul; done ``` --- test/libyul/yulOptimizerTests/fullSuite/mcopy.sol => mcopy.yul | 0 .../mcopy_non_zero_size.sol => mcopy_non_zero_size.yul | 0 ...y_redundant_overwritten.sol => mcopy_redundant_overwritten.yul | 0 ...mcopy_redundant_same_area.sol => mcopy_redundant_same_area.yul | 0 ...mcopy_redundant_zero_size.sol => mcopy_redundant_zero_size.yul | 0 .../mcopy_zero_size.sol => mcopy_zero_size.yul | 0 .../fullInlinerWithoutSplitter/simple.sol => simple.yul | 0 ...rection_override.sol => unicode_comment_direction_override.yul | 0 8 files changed, 0 insertions(+), 0 deletions(-) rename test/libyul/yulOptimizerTests/fullSuite/mcopy.sol => mcopy.yul (100%) rename test/libyul/yulOptimizerTests/expressionSimplifier/mcopy_non_zero_size.sol => mcopy_non_zero_size.yul (100%) rename test/libyul/yulOptimizerTests/fullSuite/mcopy_redundant_overwritten.sol => mcopy_redundant_overwritten.yul (100%) rename test/libyul/yulOptimizerTests/fullSuite/mcopy_redundant_same_area.sol => mcopy_redundant_same_area.yul (100%) rename test/libyul/yulOptimizerTests/fullSuite/mcopy_redundant_zero_size.sol => mcopy_redundant_zero_size.yul (100%) rename test/libyul/yulOptimizerTests/expressionSimplifier/mcopy_zero_size.sol => mcopy_zero_size.yul (100%) rename test/libyul/yulOptimizerTests/fullInlinerWithoutSplitter/simple.sol => simple.yul (100%) rename test/libyul/yulSyntaxTests/invalid/unicode_comment_direction_override.sol => unicode_comment_direction_override.yul (100%) diff --git a/test/libyul/yulOptimizerTests/fullSuite/mcopy.sol b/mcopy.yul similarity index 100% rename from test/libyul/yulOptimizerTests/fullSuite/mcopy.sol rename to mcopy.yul diff --git a/test/libyul/yulOptimizerTests/expressionSimplifier/mcopy_non_zero_size.sol b/mcopy_non_zero_size.yul similarity index 100% rename from test/libyul/yulOptimizerTests/expressionSimplifier/mcopy_non_zero_size.sol rename to mcopy_non_zero_size.yul diff --git a/test/libyul/yulOptimizerTests/fullSuite/mcopy_redundant_overwritten.sol b/mcopy_redundant_overwritten.yul similarity index 100% rename from test/libyul/yulOptimizerTests/fullSuite/mcopy_redundant_overwritten.sol rename to mcopy_redundant_overwritten.yul diff --git a/test/libyul/yulOptimizerTests/fullSuite/mcopy_redundant_same_area.sol b/mcopy_redundant_same_area.yul similarity index 100% rename from test/libyul/yulOptimizerTests/fullSuite/mcopy_redundant_same_area.sol rename to mcopy_redundant_same_area.yul diff --git a/test/libyul/yulOptimizerTests/fullSuite/mcopy_redundant_zero_size.sol b/mcopy_redundant_zero_size.yul similarity index 100% rename from test/libyul/yulOptimizerTests/fullSuite/mcopy_redundant_zero_size.sol rename to mcopy_redundant_zero_size.yul diff --git a/test/libyul/yulOptimizerTests/expressionSimplifier/mcopy_zero_size.sol b/mcopy_zero_size.yul similarity index 100% rename from test/libyul/yulOptimizerTests/expressionSimplifier/mcopy_zero_size.sol rename to mcopy_zero_size.yul diff --git a/test/libyul/yulOptimizerTests/fullInlinerWithoutSplitter/simple.sol b/simple.yul similarity index 100% rename from test/libyul/yulOptimizerTests/fullInlinerWithoutSplitter/simple.sol rename to simple.yul diff --git a/test/libyul/yulSyntaxTests/invalid/unicode_comment_direction_override.sol b/unicode_comment_direction_override.yul similarity index 100% rename from test/libyul/yulSyntaxTests/invalid/unicode_comment_direction_override.sol rename to unicode_comment_direction_override.yul From 4cebdc8bf53018d04b470d1f3fbacece761d6027 Mon Sep 17 00:00:00 2001 From: Nikola Matic Date: Mon, 21 Oct 2024 14:52:29 +0200 Subject: [PATCH 0522/1022] Move Yul tests from root to test dir --- .../expressionSimplifier/mcopy_non_zero_size.yul | 0 .../yulOptimizerTests/expressionSimplifier/mcopy_zero_size.yul | 0 .../yulOptimizerTests/fullInlinerWithoutSplitter/simple.yul | 0 mcopy.yul => test/libyul/yulOptimizerTests/fullSuite/mcopy.yul | 0 .../yulOptimizerTests/fullSuite/mcopy_redundant_overwritten.yul | 0 .../yulOptimizerTests/fullSuite/mcopy_redundant_same_area.yul | 0 .../yulOptimizerTests/fullSuite/mcopy_redundant_zero_size.yul | 0 .../yulSyntaxTests/invalid/unicode_comment_direction_override.yul | 0 8 files changed, 0 insertions(+), 0 deletions(-) rename mcopy_non_zero_size.yul => test/libyul/yulOptimizerTests/expressionSimplifier/mcopy_non_zero_size.yul (100%) rename mcopy_zero_size.yul => test/libyul/yulOptimizerTests/expressionSimplifier/mcopy_zero_size.yul (100%) rename simple.yul => test/libyul/yulOptimizerTests/fullInlinerWithoutSplitter/simple.yul (100%) rename mcopy.yul => test/libyul/yulOptimizerTests/fullSuite/mcopy.yul (100%) rename mcopy_redundant_overwritten.yul => test/libyul/yulOptimizerTests/fullSuite/mcopy_redundant_overwritten.yul (100%) rename mcopy_redundant_same_area.yul => test/libyul/yulOptimizerTests/fullSuite/mcopy_redundant_same_area.yul (100%) rename mcopy_redundant_zero_size.yul => test/libyul/yulOptimizerTests/fullSuite/mcopy_redundant_zero_size.yul (100%) rename unicode_comment_direction_override.yul => test/libyul/yulSyntaxTests/invalid/unicode_comment_direction_override.yul (100%) diff --git a/mcopy_non_zero_size.yul b/test/libyul/yulOptimizerTests/expressionSimplifier/mcopy_non_zero_size.yul similarity index 100% rename from mcopy_non_zero_size.yul rename to test/libyul/yulOptimizerTests/expressionSimplifier/mcopy_non_zero_size.yul diff --git a/mcopy_zero_size.yul b/test/libyul/yulOptimizerTests/expressionSimplifier/mcopy_zero_size.yul similarity index 100% rename from mcopy_zero_size.yul rename to test/libyul/yulOptimizerTests/expressionSimplifier/mcopy_zero_size.yul diff --git a/simple.yul b/test/libyul/yulOptimizerTests/fullInlinerWithoutSplitter/simple.yul similarity index 100% rename from simple.yul rename to test/libyul/yulOptimizerTests/fullInlinerWithoutSplitter/simple.yul diff --git a/mcopy.yul b/test/libyul/yulOptimizerTests/fullSuite/mcopy.yul similarity index 100% rename from mcopy.yul rename to test/libyul/yulOptimizerTests/fullSuite/mcopy.yul diff --git a/mcopy_redundant_overwritten.yul b/test/libyul/yulOptimizerTests/fullSuite/mcopy_redundant_overwritten.yul similarity index 100% rename from mcopy_redundant_overwritten.yul rename to test/libyul/yulOptimizerTests/fullSuite/mcopy_redundant_overwritten.yul diff --git a/mcopy_redundant_same_area.yul b/test/libyul/yulOptimizerTests/fullSuite/mcopy_redundant_same_area.yul similarity index 100% rename from mcopy_redundant_same_area.yul rename to test/libyul/yulOptimizerTests/fullSuite/mcopy_redundant_same_area.yul diff --git a/mcopy_redundant_zero_size.yul b/test/libyul/yulOptimizerTests/fullSuite/mcopy_redundant_zero_size.yul similarity index 100% rename from mcopy_redundant_zero_size.yul rename to test/libyul/yulOptimizerTests/fullSuite/mcopy_redundant_zero_size.yul diff --git a/unicode_comment_direction_override.yul b/test/libyul/yulSyntaxTests/invalid/unicode_comment_direction_override.yul similarity index 100% rename from unicode_comment_direction_override.yul rename to test/libyul/yulSyntaxTests/invalid/unicode_comment_direction_override.yul From 5db362cd2190c411a73396746f1754115cf3f3f4 Mon Sep 17 00:00:00 2001 From: rodiazet Date: Tue, 22 Oct 2024 09:11:05 +0200 Subject: [PATCH 0523/1022] eof: Add `auxdataloadn` to reserved identifiers. Move test to `eof` dir --- libyul/backends/evm/EVMDialect.cpp | 10 ++++++++-- test/libyul/objectCompiler/{ => eof}/dataloadn.yul | 0 2 files changed, 8 insertions(+), 2 deletions(-) rename test/libyul/objectCompiler/{ => eof}/dataloadn.yul (100%) diff --git a/libyul/backends/evm/EVMDialect.cpp b/libyul/backends/evm/EVMDialect.cpp index e95e2246fcf2..1ed422551402 100644 --- a/libyul/backends/evm/EVMDialect.cpp +++ b/libyul/backends/evm/EVMDialect.cpp @@ -118,7 +118,7 @@ BuiltinFunctionForEVM createFunction( return f; } -std::set> createReservedIdentifiers(langutil::EVMVersion _evmVersion) +std::set> createReservedIdentifiers(langutil::EVMVersion _evmVersion, std::optional _eofVersion) { // TODO remove this in 0.9.0. We allow creating functions or identifiers in Yul with the name // basefee for VMs before london. @@ -186,6 +186,12 @@ std::set> createReservedIdentifiers(langutil::EVMVersio "setimmutable", "loadimmutable", }; + + if (_eofVersion.has_value()) + reserved += std::vector{ + "auxdataloadn", + }; + return reserved; } @@ -414,7 +420,7 @@ EVMDialect::EVMDialect(langutil::EVMVersion _evmVersion, std::optional m_evmVersion(_evmVersion), m_eofVersion(_eofVersion), m_functions(createBuiltins(_evmVersion, _eofVersion, _objectAccess)), - m_reserved(createReservedIdentifiers(_evmVersion)) + m_reserved(createReservedIdentifiers(_evmVersion, _eofVersion)) { for (auto const& [index, maybeBuiltin]: m_functions | ranges::views::enumerate) if (maybeBuiltin) diff --git a/test/libyul/objectCompiler/dataloadn.yul b/test/libyul/objectCompiler/eof/dataloadn.yul similarity index 100% rename from test/libyul/objectCompiler/dataloadn.yul rename to test/libyul/objectCompiler/eof/dataloadn.yul From 9b329f4c651a1388919d0abdf6650eeb96cb3262 Mon Sep 17 00:00:00 2001 From: Martin Blicha Date: Fri, 5 Jul 2024 11:09:20 +0200 Subject: [PATCH 0524/1022] SMTChecker: Fix formatting of negative numbers --- libsolidity/formal/ExpressionFormatter.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/libsolidity/formal/ExpressionFormatter.cpp b/libsolidity/formal/ExpressionFormatter.cpp index 6571cf6dd7a2..865a568f62da 100644 --- a/libsolidity/formal/ExpressionFormatter.cpp +++ b/libsolidity/formal/ExpressionFormatter.cpp @@ -245,7 +245,14 @@ std::optional expressionToString(smtutil::Expression const& _expr, if (smt::isNumber(*_type)) { solAssert(_expr.sort->kind == Kind::Int); - solAssert(_expr.arguments.empty()); + solAssert(_expr.arguments.empty() || _expr.name == "-"); + if (_expr.name == "-") + { + solAssert(_expr.arguments.size() == 1); + smtutil::Expression const& val = _expr.arguments[0]; + solAssert(val.sort->kind == Kind::Int && val.arguments.empty()); + return "(- " + val.name + ")"; + } if ( _type->category() == frontend::Type::Category::Address || From 86b0b4833315c89377d258e9b4fad2a5383f0857 Mon Sep 17 00:00:00 2001 From: Martin Blicha Date: Fri, 19 Jul 2024 10:37:03 +0200 Subject: [PATCH 0525/1022] SMTChecker: Hack to get around a bug in Z3 type printing --- libsolidity/formal/SymbolicTypes.cpp | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/libsolidity/formal/SymbolicTypes.cpp b/libsolidity/formal/SymbolicTypes.cpp index f9ec9b0110ed..f8e1ebbdc805 100644 --- a/libsolidity/formal/SymbolicTypes.cpp +++ b/libsolidity/formal/SymbolicTypes.cpp @@ -29,6 +29,20 @@ using namespace solidity::util; using namespace solidity::smtutil; + +namespace +{ + // HACK to get around Z3 bug in printing type names with spaces (https://github.com/Z3Prover/z3/issues/6850) + // Should be fixed in Z3 4.13.0 + // TODO: Remove this afterwards + void sanitizeTypeName(std::string& name) + { + std::replace(name.begin(), name.end(), ' ', '_'); + std::replace(name.begin(), name.end(), '(', '['); + std::replace(name.begin(), name.end(), ')', ']'); + } +} + namespace solidity::frontend::smt { @@ -137,6 +151,7 @@ SortPointer smtSort(frontend::Type const& _type) else tupleName = _type.toString(true); + sanitizeTypeName(tupleName); tupleName += "_tuple"; return std::make_shared( @@ -148,7 +163,8 @@ SortPointer smtSort(frontend::Type const& _type) case Kind::Tuple: { std::vector members; - auto const& tupleName = _type.toString(true); + auto tupleName = _type.toString(true); + sanitizeTypeName(tupleName); std::vector sorts; if (auto const* tupleType = dynamic_cast(&_type)) From 8597223c6868cb387f5dc45227d86caab1d03b2c Mon Sep 17 00:00:00 2001 From: Martin Blicha Date: Fri, 2 Aug 2024 14:34:11 +0200 Subject: [PATCH 0526/1022] SMTChecker: Hack to make invariants more stable across platforms --- libsmtutil/CHCSmtLib2Interface.cpp | 9 ++- .../model_checker_invariants_all/err | 4 +- .../model_checker_invariants_contract/err | 2 +- .../err | 10 +-- .../input.sol | 7 +- .../model_checker_invariants_reentrancy/err | 2 +- .../output.json | 4 +- .../input.json | 5 +- .../output.json | 66 ++++++------------- .../input.json | 5 +- .../output.json | 24 +++---- 11 files changed, 56 insertions(+), 82 deletions(-) diff --git a/libsmtutil/CHCSmtLib2Interface.cpp b/libsmtutil/CHCSmtLib2Interface.cpp index d23249d2200d..4c6f2a60f6b0 100644 --- a/libsmtutil/CHCSmtLib2Interface.cpp +++ b/libsmtutil/CHCSmtLib2Interface.cpp @@ -27,8 +27,9 @@ #include #include -#include #include +#include +#include #include #include @@ -450,6 +451,12 @@ std::optional CHCSmtLib2Interface::invariantsFromSolverResp auto parsedInterpretation = scopedParser.toSMTUtilExpression(interpretation); + // Hack to make invariants more stable across operating systems + if (parsedInterpretation.name == "and" || parsedInterpretation.name == "or") + ranges::sort(parsedInterpretation.arguments, [](Expression const& first, Expression const& second) { + return first.name < second.name; + }); + Expression predicate(asAtom(args[1]), predicateArgs, SortProvider::boolSort); definitions.push_back(predicate == parsedInterpretation); } diff --git a/test/cmdlineTests/model_checker_invariants_all/err b/test/cmdlineTests/model_checker_invariants_all/err index 7ec97678e990..cd133dab0b8d 100644 --- a/test/cmdlineTests/model_checker_invariants_all/err +++ b/test/cmdlineTests/model_checker_invariants_all/err @@ -7,8 +7,8 @@ Warning: Return value of low-level calls not used. Info: CHC: 1 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. Info: Contract invariant(s) for model_checker_invariants_all/input.sol:test: -(!(x >= 1) || true) +(true || !(x >= 1)) Reentrancy property(ies) for model_checker_invariants_all/input.sol:test: -(((!(x <= 0) || !( >= 1)) && (!(x <= 0) || !(x' >= 1))) || true) +((( = 0) && (x!6 = x!4) && (x' = x)) || true || true || true || true) = 0 -> no errors = 1 -> Assertion failed at assert(x == 0) diff --git a/test/cmdlineTests/model_checker_invariants_contract/err b/test/cmdlineTests/model_checker_invariants_contract/err index f6b01e9b2cbf..3ecad6b35d48 100644 --- a/test/cmdlineTests/model_checker_invariants_contract/err +++ b/test/cmdlineTests/model_checker_invariants_contract/err @@ -1,4 +1,4 @@ Info: CHC: 1 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. Info: Contract invariant(s) for model_checker_invariants_contract/input.sol:test: -(!(x >= 1) || true) +(true || !(x >= 1)) diff --git a/test/cmdlineTests/model_checker_invariants_contract_reentrancy/err b/test/cmdlineTests/model_checker_invariants_contract_reentrancy/err index 11ee3a702f8c..7764e89abc59 100644 --- a/test/cmdlineTests/model_checker_invariants_contract_reentrancy/err +++ b/test/cmdlineTests/model_checker_invariants_contract_reentrancy/err @@ -1,14 +1,8 @@ -Warning: Return value of low-level calls not used. - --> model_checker_invariants_contract_reentrancy/input.sol:6:3: - | -6 | _a.call(""); - | ^^^^^^^^^^^ - Info: CHC: 1 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. Info: Contract invariant(s) for model_checker_invariants_contract_reentrancy/input.sol:test: -(!(x >= 1) || true) +(true || !(x >= 1)) Reentrancy property(ies) for model_checker_invariants_contract_reentrancy/input.sol:test: -(((!(x <= 0) || !( >= 1)) && (!(x <= 0) || !(x' >= 1))) || true) +((( = 0) && (x!6 = x!4) && (x' = x)) || true || true || true || true) = 0 -> no errors = 1 -> Assertion failed at assert(x == 0) diff --git a/test/cmdlineTests/model_checker_invariants_contract_reentrancy/input.sol b/test/cmdlineTests/model_checker_invariants_contract_reentrancy/input.sol index 8b90cb3c1324..e75a75b5fbb6 100644 --- a/test/cmdlineTests/model_checker_invariants_contract_reentrancy/input.sol +++ b/test/cmdlineTests/model_checker_invariants_contract_reentrancy/input.sol @@ -2,8 +2,7 @@ pragma solidity >=0.0; contract test { uint x; - function f(address _a) public { - _a.call(""); + function f() public view { assert(x == 0); - } -} \ No newline at end of file + } +} diff --git a/test/cmdlineTests/model_checker_invariants_reentrancy/err b/test/cmdlineTests/model_checker_invariants_reentrancy/err index 68ef6404cdb8..78cca4390a61 100644 --- a/test/cmdlineTests/model_checker_invariants_reentrancy/err +++ b/test/cmdlineTests/model_checker_invariants_reentrancy/err @@ -7,6 +7,6 @@ Warning: Return value of low-level calls not used. Info: CHC: 1 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. Info: Reentrancy property(ies) for model_checker_invariants_reentrancy/input.sol:test: -(((!(x <= 0) || !( >= 1)) && (!(x <= 0) || !(x' >= 1))) || true) +((( = 0) && (x!6 = x!4) && (x' = x)) || true || true || true || true) = 0 -> no errors = 1 -> Assertion failed at assert(x < 10) diff --git a/test/cmdlineTests/standard_model_checker_invariants_contract/output.json b/test/cmdlineTests/standard_model_checker_invariants_contract/output.json index f3cd0758c0ea..09d392567c3b 100644 --- a/test/cmdlineTests/standard_model_checker_invariants_contract/output.json +++ b/test/cmdlineTests/standard_model_checker_invariants_contract/output.json @@ -14,12 +14,12 @@ "component": "general", "errorCode": "1180", "formattedMessage": "Info: Contract invariant(s) for A:test: -(!(x >= 1) || true) +(true || !(x >= 1)) ", "message": "Contract invariant(s) for A:test: -(!(x >= 1) || true) +(true || !(x >= 1)) ", "severity": "info", "type": "Info" diff --git a/test/cmdlineTests/standard_model_checker_invariants_contract_reentrancy/input.json b/test/cmdlineTests/standard_model_checker_invariants_contract_reentrancy/input.json index 38f658653641..e4c7c7bd004f 100644 --- a/test/cmdlineTests/standard_model_checker_invariants_contract_reentrancy/input.json +++ b/test/cmdlineTests/standard_model_checker_invariants_contract_reentrancy/input.json @@ -6,9 +6,8 @@ { "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\n\ncontract test { uint x; - function f(address _a) public { - _a.call(\"\"); - assert(x == 10); + function f() view public { + assert(x == 0); } }" } 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 d46fdda8a917..b51effdcb322 100644 --- a/test/cmdlineTests/standard_model_checker_invariants_contract_reentrancy/output.json +++ b/test/cmdlineTests/standard_model_checker_invariants_contract_reentrancy/output.json @@ -2,59 +2,35 @@ "errors": [ { "component": "general", - "errorCode": "9302", - "formattedMessage": "Warning: Return value of low-level calls not used. - --> A:7:7: - | -7 | \t\t\t\t\t\t_a.call(\"\"); - | \t\t\t\t\t\t^^^^^^^^^^^ + "errorCode": "1391", + "formattedMessage": "Info: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them. ", - "message": "Return value of low-level calls not used.", - "severity": "warning", - "sourceLocation": { - "end": 143, - "file": "A", - "start": 132 - }, - "type": "Warning" + "message": "CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.", + "severity": "info", + "type": "Info" }, { "component": "general", - "errorCode": "6328", - "formattedMessage": "Warning: CHC: Assertion violation happens here. -Counterexample: -x = 0 -_a = 0x0 + "errorCode": "1180", + "formattedMessage": "Info: Contract invariant(s) for A:test: +(true || !(x >= 1)) +Reentrancy property(ies) for A:test: +((( = 0) && (x!6 = x!4) && (x' = x)) || true || true || true || true) + = 0 -> no errors + = 1 -> Assertion failed at assert(x == 0) -Transaction trace: -test.constructor() -State: x = 0 -test.f(0x0) - _a.call(\"\") -- untrusted external call - --> A:8:7: - | -8 | \t\t\t\t\t\tassert(x == 10); - | \t\t\t\t\t\t^^^^^^^^^^^^^^^ ", - "message": "CHC: Assertion violation happens here. -Counterexample: -x = 0 -_a = 0x0 - -Transaction trace: -test.constructor() -State: x = 0 -test.f(0x0) - _a.call(\"\") -- untrusted external call", - "severity": "warning", - "sourceLocation": { - "end": 166, - "file": "A", - "start": 151 - }, - "type": "Warning" + "message": "Contract invariant(s) for A:test: +(true || !(x >= 1)) +Reentrancy property(ies) for A:test: +((( = 0) && (x!6 = x!4) && (x' = x)) || true || true || true || true) + = 0 -> no errors + = 1 -> Assertion failed at assert(x == 0) +", + "severity": "info", + "type": "Info" } ], "sources": { diff --git a/test/cmdlineTests/standard_model_checker_invariants_reentrancy/input.json b/test/cmdlineTests/standard_model_checker_invariants_reentrancy/input.json index 1f98000b0ec3..2a3673fade2c 100644 --- a/test/cmdlineTests/standard_model_checker_invariants_reentrancy/input.json +++ b/test/cmdlineTests/standard_model_checker_invariants_reentrancy/input.json @@ -6,9 +6,8 @@ { "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\n\ncontract test { uint x; - function f(address _a) public { - _a.call(\"\"); - assert(x < 10); + function f() public { + assert(x == 0); } }" } diff --git a/test/cmdlineTests/standard_model_checker_invariants_reentrancy/output.json b/test/cmdlineTests/standard_model_checker_invariants_reentrancy/output.json index 760f1d7a75ad..f1f37340e7d1 100644 --- a/test/cmdlineTests/standard_model_checker_invariants_reentrancy/output.json +++ b/test/cmdlineTests/standard_model_checker_invariants_reentrancy/output.json @@ -2,20 +2,20 @@ "errors": [ { "component": "general", - "errorCode": "9302", - "formattedMessage": "Warning: Return value of low-level calls not used. - --> A:7:7: + "errorCode": "2018", + "formattedMessage": "Warning: Function state mutability can be restricted to view + --> A:6:6: | -7 | \t\t\t\t\t\t_a.call(\"\"); - | \t\t\t\t\t\t^^^^^^^^^^^ +6 | \t\t\t\t\tfunction f() public { + | \t\t\t\t\t^ (Relevant source part starts here and spans across multiple lines). ", - "message": "Return value of low-level calls not used.", + "message": "Function state mutability can be restricted to view", "severity": "warning", "sourceLocation": { - "end": 143, + "end": 144, "file": "A", - "start": 132 + "start": 94 }, "type": "Warning" }, @@ -33,16 +33,16 @@ "component": "general", "errorCode": "1180", "formattedMessage": "Info: Reentrancy property(ies) for A:test: -(((!(x <= 0) || !( >= 1)) && (!(x <= 0) || !(x' >= 1))) || true) +((( = 0) && (x!6 = x!4) && (x' = x)) || true || true || true || true) = 0 -> no errors - = 1 -> Assertion failed at assert(x < 10) + = 1 -> Assertion failed at assert(x == 0) ", "message": "Reentrancy property(ies) for A:test: -(((!(x <= 0) || !( >= 1)) && (!(x <= 0) || !(x' >= 1))) || true) +((( = 0) && (x!6 = x!4) && (x' = x)) || true || true || true || true) = 0 -> no errors - = 1 -> Assertion failed at assert(x < 10) + = 1 -> Assertion failed at assert(x == 0) ", "severity": "info", "type": "Info" From 436f6066d2dabd8da141df1fc04bb8f8ee6af982 Mon Sep 17 00:00:00 2001 From: Martin Blicha Date: Wed, 3 Jul 2024 18:04:59 +0200 Subject: [PATCH 0527/1022] SMTChecker: Switch to Z3 SMTLIB interface Instead of interacting with Z3 via its API, we switch to the interaction using our SMT-LIB interface. An exception is the emscripten build, where we keep including Z3. This is for users' convenience. --- CMakeLists.txt | 8 ++ libsmtutil/CHCSmtLib2Interface.cpp | 1 - libsmtutil/CMakeLists.txt | 2 +- libsmtutil/SMTLib2Interface.h | 2 +- libsolidity/CMakeLists.txt | 4 + libsolidity/formal/BMC.cpp | 10 +-- libsolidity/formal/CHC.cpp | 87 +++++-------------- libsolidity/formal/ModelChecker.cpp | 9 +- libsolidity/formal/Z3CHCSmtLib2Interface.cpp | 29 +++++++ libsolidity/formal/Z3SMTLib2Interface.cpp | 25 ++++++ libsolidity/formal/Z3SMTLib2Interface.h | 1 + .../model_checker_divModSlacks_false_all/err | 12 --- .../model_checker_divModSlacks_false_chc/err | 12 --- .../model_checker_invariants_all/err | 6 -- .../model_checker_invariants_all/input.sol | 7 +- .../input.sol | 8 +- .../model_checker_invariants_reentrancy/err | 8 +- .../input.sol | 9 +- .../output.json | 38 -------- .../output.json | 38 -------- .../abi_encode_with_selector_array_slice.sol | 5 +- ...abi_encode_with_selector_array_slice_2.sol | 7 +- .../abi/abi_encode_with_selector_vs_sig.sol | 2 +- .../abi/abi_encode_with_sig_array_slice.sol | 10 ++- .../abi/abi_encode_with_sig_array_slice_2.sol | 10 ++- .../external_calls/call_with_value_1.sol | 7 +- .../external_calls/call_with_value_2.sol | 6 +- .../external_calls/external.sol | 8 +- .../external_call_indirect_1.sol | 3 +- .../external_call_indirect_2.sol | 3 +- .../external_call_indirect_3.sol | 1 + .../external_call_with_value_2.sol | 6 +- .../external_call_with_value_3.sol | 9 +- ...nal_hash_known_code_state_reentrancy_3.sol | 3 +- ...sh_known_code_state_reentrancy_trusted.sol | 4 +- .../external_calls/external_safe.sol | 4 +- .../operators/index_access_for_bytesNN.sol | 4 +- .../operators/index_access_side_effect.sol | 3 +- ...rator_matches_equivalent_function_call.sol | 4 +- .../out_of_bounds/array_2d_4.sol | 10 +-- .../types/array_mapping_aliasing_2.sol | 13 +-- .../types/struct_array_branches_2d.sol | 5 +- 42 files changed, 178 insertions(+), 265 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b78269a3d6c1..a0a8313b095c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -144,6 +144,14 @@ if (NOT (${Z3_FOUND} OR CVC5_PATH)) \nPlease install Z3 or cvc5 or remove the option disabling them (USE_Z3).") endif() +if(EMSCRIPTEN) + if(${Z3_FOUND}) + add_definitions(-DEMSCRIPTEN_BUILD) + else() + message(FATAL_ERROR "Solidity requires Z3 for emscripten build.") + endif() +endif() + add_subdirectory(libsolutil) add_subdirectory(liblangutil) add_subdirectory(libsmtutil) diff --git a/libsmtutil/CHCSmtLib2Interface.cpp b/libsmtutil/CHCSmtLib2Interface.cpp index 4c6f2a60f6b0..02257031a4d9 100644 --- a/libsmtutil/CHCSmtLib2Interface.cpp +++ b/libsmtutil/CHCSmtLib2Interface.cpp @@ -28,7 +28,6 @@ #include #include -#include #include #include diff --git a/libsmtutil/CMakeLists.txt b/libsmtutil/CMakeLists.txt index c89c56f4f583..2bd870549c2d 100644 --- a/libsmtutil/CMakeLists.txt +++ b/libsmtutil/CMakeLists.txt @@ -17,7 +17,7 @@ set(sources ) if (${Z3_FOUND}) - set(z3_SRCS Z3Interface.cpp Z3Interface.h Z3CHCInterface.cpp Z3CHCInterface.h) + set(z3_SRCS) else() set(z3_SRCS) endif() diff --git a/libsmtutil/SMTLib2Interface.h b/libsmtutil/SMTLib2Interface.h index 02b1c85ffe0e..fe5421acd202 100644 --- a/libsmtutil/SMTLib2Interface.h +++ b/libsmtutil/SMTLib2Interface.h @@ -105,7 +105,7 @@ class SMTLib2Interface: public BMCSolverInterface std::string checkSatAndGetValuesCommand(std::vector const& _expressionsToEvaluate); /// Communicates with the solver via the callback. Throws SMTSolverError on error. - std::string querySolver(std::string const& _input); + virtual std::string querySolver(std::string const& _input); SMTLib2Commands m_commands; SMTLib2Context m_context; diff --git a/libsolidity/CMakeLists.txt b/libsolidity/CMakeLists.txt index 0b796035d313..1c4c48090645 100644 --- a/libsolidity/CMakeLists.txt +++ b/libsolidity/CMakeLists.txt @@ -141,6 +141,10 @@ set(sources formal/SymbolicVariables.h formal/VariableUsage.cpp formal/VariableUsage.h + formal/Z3CHCSmtLib2Interface.cpp + formal/Z3CHCSmtLib2Interface.h + formal/Z3SMTLib2Interface.cpp + formal/Z3SMTLib2Interface.h interface/ABI.cpp interface/ABI.h interface/CompilerStack.cpp diff --git a/libsolidity/formal/BMC.cpp b/libsolidity/formal/BMC.cpp index fda573d3d4cf..a7f792453f09 100644 --- a/libsolidity/formal/BMC.cpp +++ b/libsolidity/formal/BMC.cpp @@ -20,12 +20,10 @@ #include #include +#include #include #include -#ifdef HAVE_Z3 -#include -#endif #include #include @@ -61,10 +59,8 @@ BMC::BMC( solvers.emplace_back(std::make_unique(_smtlib2Responses, _smtCallback, _settings.timeout)); if (_settings.solvers.cvc5) solvers.emplace_back(std::make_unique(_smtCallback, _settings.timeout)); -#ifdef HAVE_Z3 - if (_settings.solvers.z3 && Z3Interface::available()) - solvers.emplace_back(std::make_unique(_settings.timeout)); -#endif + if (_settings.solvers.z3 ) + solvers.emplace_back(std::make_unique(_smtCallback, _settings.timeout)); m_interface = std::make_unique(std::move(solvers), _settings.timeout); #if defined (HAVE_Z3) if (m_settings.solvers.z3) diff --git a/libsolidity/formal/CHC.cpp b/libsolidity/formal/CHC.cpp index c52a83a26183..7f413f91a999 100644 --- a/libsolidity/formal/CHC.cpp +++ b/libsolidity/formal/CHC.cpp @@ -18,18 +18,14 @@ #include -#include - -#ifdef HAVE_Z3 -#include -#endif - #include #include #include +#include #include #include #include +#include #include @@ -38,10 +34,6 @@ #include #include -#ifdef HAVE_Z3_DLOPEN -#include -#endif - #include #include @@ -1279,41 +1271,29 @@ void CHC::resetSourceAnalysis() ArraySlicePredicate::reset(); m_blockCounter = 0; - // At this point every enabled solver is available. - // If more than one Horn solver is selected we go with z3. - // We still need the ifdef because of Z3CHCInterface. - if (m_settings.solvers.z3) + solAssert(m_settings.solvers.smtlib2 || m_settings.solvers.eld || m_settings.solvers.z3); + if (!m_interface) { -#ifdef HAVE_Z3 - // z3::fixedpoint does not have a reset mechanism, so we need to create another. - m_interface = std::make_unique(m_settings.timeout); - auto z3Interface = dynamic_cast(m_interface.get()); - solAssert(z3Interface, ""); - m_context.setSolver(z3Interface->z3Interface()); -#else - solAssert(false); -#endif + if (m_settings.solvers.z3) + m_interface = std::make_unique( + m_smtCallback, + m_settings.timeout, + m_settings.invariants != ModelCheckerInvariants::None() + ); + else if (m_settings.solvers.eld) + m_interface = std::make_unique( + m_smtCallback, + m_settings.timeout, + m_settings.invariants != ModelCheckerInvariants::None() + ); + else + m_interface = std::make_unique(m_smtlib2Responses, m_smtCallback, m_settings.timeout); } - else - { - solAssert(m_settings.solvers.smtlib2 || m_settings.solvers.eld); - if (!m_interface) - { - if (m_settings.solvers.eld) - m_interface = std::make_unique( - m_smtCallback, - m_settings.timeout, - m_settings.invariants != ModelCheckerInvariants::None() - ); - else - m_interface = std::make_unique(m_smtlib2Responses, m_smtCallback, m_settings.timeout); - } - auto smtlib2Interface = dynamic_cast(m_interface.get()); - solAssert(smtlib2Interface); - smtlib2Interface->reset(); - m_context.setSolver(smtlib2Interface); - } + auto smtlib2Interface = dynamic_cast(m_interface.get()); + solAssert(smtlib2Interface); + smtlib2Interface->reset(); + m_context.setSolver(smtlib2Interface); m_context.reset(); m_context.resetUniqueId(); @@ -1932,29 +1912,6 @@ CHCSolverInterface::QueryResult CHC::query(smtutil::Expression const& _query, la switch (result.answer) { case CheckResult::SATISFIABLE: - { - // We still need the ifdef because of Z3CHCInterface. - if (m_settings.solvers.z3) - { -#ifdef HAVE_Z3 - // Even though the problem is SAT, Spacer's pre processing makes counterexamples incomplete. - // We now disable those optimizations and check whether we can still solve the problem. - auto* spacer = dynamic_cast(m_interface.get()); - solAssert(spacer, ""); - spacer->setSpacerOptions(false); - - auto resultNoOpt = m_interface->query(_query); - - if (resultNoOpt.answer == CheckResult::SATISFIABLE) - result.cex = std::move(resultNoOpt.cex); - - spacer->setSpacerOptions(true); -#else - solAssert(false); -#endif - } - break; - } case CheckResult::UNSATISFIABLE: case CheckResult::UNKNOWN: break; diff --git a/libsolidity/formal/ModelChecker.cpp b/libsolidity/formal/ModelChecker.cpp index 91b88cb9c842..6368dc1eafcb 100644 --- a/libsolidity/formal/ModelChecker.cpp +++ b/libsolidity/formal/ModelChecker.cpp @@ -17,9 +17,6 @@ // SPDX-License-Identifier: GPL-3.0 #include -#ifdef HAVE_Z3 -#include -#endif #ifdef HAVE_Z3_DLOPEN #include #endif @@ -170,8 +167,10 @@ SMTSolverChoice ModelChecker::availableSolvers() smtutil::SMTSolverChoice available = smtutil::SMTSolverChoice::SMTLIB2(); available.eld = !boost::process::search_path("eld").empty(); available.cvc5 = !boost::process::search_path("cvc5").empty(); -#ifdef HAVE_Z3 - available.z3 = solidity::smtutil::Z3Interface::available(); +#ifdef EMSCRIPTEN_BUILD + available.z3 = true; +#else + available.z3 = !boost::process::search_path("z3").empty(); #endif return available; } diff --git a/libsolidity/formal/Z3CHCSmtLib2Interface.cpp b/libsolidity/formal/Z3CHCSmtLib2Interface.cpp index d8448fc0beca..a3aef325b0b1 100644 --- a/libsolidity/formal/Z3CHCSmtLib2Interface.cpp +++ b/libsolidity/formal/Z3CHCSmtLib2Interface.cpp @@ -26,6 +26,10 @@ #include +#ifdef EMSCRIPTEN_BUILD +#include +#endif + using namespace solidity::frontend::smt; using namespace solidity::smtutil; @@ -35,6 +39,17 @@ Z3CHCSmtLib2Interface::Z3CHCSmtLib2Interface( bool _computeInvariants ): CHCSmtLib2Interface({}, std::move(_smtCallback), _queryTimeout), m_computeInvariants(_computeInvariants) { +#ifdef EMSCRIPTEN_BUILD + constexpr int resourceLimit = 2000000; + if (m_queryTimeout) + z3::set_param("timeout", int(*m_queryTimeout)); + else + z3::set_param("rlimit", resourceLimit); + z3::set_param("rewriter.pull_cheap_ite", true); + z3::set_param("fp.spacer.q3.use_qgen", true); + z3::set_param("fp.spacer.mbqi", false); + z3::set_param("fp.spacer.ground_pobs", false); +#endif } void Z3CHCSmtLib2Interface::setupSmtCallback(bool _enablePreprocessing) @@ -47,7 +62,14 @@ CHCSolverInterface::QueryResult Z3CHCSmtLib2Interface::query(smtutil::Expression { setupSmtCallback(true); std::string query = dumpQuery(_block); +#ifdef EMSCRIPTEN_BUILD + z3::set_param("fp.xform.slice", true); + z3::set_param("fp.xform.inline_linear", true); + z3::set_param("fp.xform.inline_eager", true); + std::string response = Z3_eval_smtlib2_string(z3::context{}, query.c_str()); +#else std::string response = querySolver(query); +#endif // NOTE: Our internal semantics is UNSAT -> SAFE and SAT -> UNSAFE, which corresponds to usual SMT-based model checking // However, with CHC solvers, the meaning is flipped, UNSAT -> UNSAFE and SAT -> SAFE. // So we have to flip the answer. @@ -56,7 +78,14 @@ CHCSolverInterface::QueryResult Z3CHCSmtLib2Interface::query(smtutil::Expression // Repeat the query with preprocessing disabled, to get the full proof setupSmtCallback(false); query = "(set-option :produce-proofs true)" + query + "\n(get-proof)"; +#ifdef EMSCRIPTEN_BUILD + z3::set_param("fp.xform.slice", false); + z3::set_param("fp.xform.inline_linear", false); + z3::set_param("fp.xform.inline_eager", false); + response = Z3_eval_smtlib2_string(z3::context{}, query.c_str()); +#else response = querySolver(query); +#endif setupSmtCallback(true); if (!boost::starts_with(response, "unsat")) return {CheckResult::SATISFIABLE, Expression(true), {}}; diff --git a/libsolidity/formal/Z3SMTLib2Interface.cpp b/libsolidity/formal/Z3SMTLib2Interface.cpp index b76cdd252281..2ecb8cbcc45c 100644 --- a/libsolidity/formal/Z3SMTLib2Interface.cpp +++ b/libsolidity/formal/Z3SMTLib2Interface.cpp @@ -20,6 +20,10 @@ #include +#ifdef EMSCRIPTEN_BUILD +#include +#endif + using namespace solidity::frontend::smt; Z3SMTLib2Interface::Z3SMTLib2Interface( @@ -27,9 +31,30 @@ Z3SMTLib2Interface::Z3SMTLib2Interface( std::optional _queryTimeout ): SMTLib2Interface({}, std::move(_smtCallback), _queryTimeout) { +#ifdef EMSCRIPTEN_BUILD + constexpr int resourceLimit = 2000000; + if (m_queryTimeout) + z3::set_param("timeout", int(*m_queryTimeout)); + else + z3::set_param("rlimit", resourceLimit); + z3::set_param("rewriter.pull_cheap_ite", true); + z3::set_param("fp.spacer.q3.use_qgen", true); + z3::set_param("fp.spacer.mbqi", false); + z3::set_param("fp.spacer.ground_pobs", false); +#endif } void Z3SMTLib2Interface::setupSmtCallback() { if (auto* universalCallback = m_smtCallback.target()) universalCallback->smtCommand().setZ3(m_queryTimeout, true, false); } + +std::string Z3SMTLib2Interface::querySolver(std::string const& _query) +{ +#ifdef EMSCRIPTEN_BUILD + z3::context context; + return Z3_eval_smtlib2_string(context, _query.c_str()); +#else + return SMTLib2Interface::querySolver(_query); +#endif +} diff --git a/libsolidity/formal/Z3SMTLib2Interface.h b/libsolidity/formal/Z3SMTLib2Interface.h index 07e138710624..7ab087bbdb99 100644 --- a/libsolidity/formal/Z3SMTLib2Interface.h +++ b/libsolidity/formal/Z3SMTLib2Interface.h @@ -32,6 +32,7 @@ class Z3SMTLib2Interface: public smtutil::SMTLib2Interface ); private: void setupSmtCallback() override; + std::string querySolver(std::string const& _query) override; }; } diff --git a/test/cmdlineTests/model_checker_divModSlacks_false_all/err b/test/cmdlineTests/model_checker_divModSlacks_false_all/err index 8de36b1ee4e8..bf4337810dc9 100644 --- a/test/cmdlineTests/model_checker_divModSlacks_false_all/err +++ b/test/cmdlineTests/model_checker_divModSlacks_false_all/err @@ -1,15 +1,3 @@ -Warning: CHC: Error trying to invoke SMT solver. - --> model_checker_divModSlacks_false_all/input.sol:6:11: - | -6 | return (a / b, a % b); - | ^^^^^ - -Warning: CHC: Error trying to invoke SMT solver. - --> model_checker_divModSlacks_false_all/input.sol:6:18: - | -6 | return (a / b, a % b); - | ^^^^^ - Warning: CHC: 2 verification condition(s) could not be proved. Enable the model checker option "show unproved" to see all of them. Consider choosing a specific contract to be verified in order to reduce the solving problems. Consider increasing the timeout per query. Info: BMC: 2 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/cmdlineTests/model_checker_divModSlacks_false_chc/err b/test/cmdlineTests/model_checker_divModSlacks_false_chc/err index 56cca82c0832..0d6d7341e52c 100644 --- a/test/cmdlineTests/model_checker_divModSlacks_false_chc/err +++ b/test/cmdlineTests/model_checker_divModSlacks_false_chc/err @@ -1,13 +1 @@ -Warning: CHC: Error trying to invoke SMT solver. - --> model_checker_divModSlacks_false_chc/input.sol:6:11: - | -6 | return (a / b, a % b); - | ^^^^^ - -Warning: CHC: Error trying to invoke SMT solver. - --> model_checker_divModSlacks_false_chc/input.sol:6:18: - | -6 | return (a / b, a % b); - | ^^^^^ - Warning: CHC: 2 verification condition(s) could not be proved. Enable the model checker option "show unproved" to see all of them. Consider choosing a specific contract to be verified in order to reduce the solving problems. Consider increasing the timeout per query. diff --git a/test/cmdlineTests/model_checker_invariants_all/err b/test/cmdlineTests/model_checker_invariants_all/err index cd133dab0b8d..dcef00b5fd0e 100644 --- a/test/cmdlineTests/model_checker_invariants_all/err +++ b/test/cmdlineTests/model_checker_invariants_all/err @@ -1,9 +1,3 @@ -Warning: Return value of low-level calls not used. - --> model_checker_invariants_all/input.sol:6:3: - | -6 | _a.call(""); - | ^^^^^^^^^^^ - Info: CHC: 1 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. Info: Contract invariant(s) for model_checker_invariants_all/input.sol:test: diff --git a/test/cmdlineTests/model_checker_invariants_all/input.sol b/test/cmdlineTests/model_checker_invariants_all/input.sol index 8b90cb3c1324..e75a75b5fbb6 100644 --- a/test/cmdlineTests/model_checker_invariants_all/input.sol +++ b/test/cmdlineTests/model_checker_invariants_all/input.sol @@ -2,8 +2,7 @@ pragma solidity >=0.0; contract test { uint x; - function f(address _a) public { - _a.call(""); + function f() public view { assert(x == 0); - } -} \ No newline at end of file + } +} diff --git a/test/cmdlineTests/model_checker_invariants_contract/input.sol b/test/cmdlineTests/model_checker_invariants_contract/input.sol index 3a857d4848c9..e75a75b5fbb6 100644 --- a/test/cmdlineTests/model_checker_invariants_contract/input.sol +++ b/test/cmdlineTests/model_checker_invariants_contract/input.sol @@ -2,7 +2,7 @@ pragma solidity >=0.0; contract test { uint x; - function f() public view { - assert(x < 10); - } -} \ No newline at end of file + function f() public view { + assert(x == 0); + } +} diff --git a/test/cmdlineTests/model_checker_invariants_reentrancy/err b/test/cmdlineTests/model_checker_invariants_reentrancy/err index 78cca4390a61..8891b0e18c59 100644 --- a/test/cmdlineTests/model_checker_invariants_reentrancy/err +++ b/test/cmdlineTests/model_checker_invariants_reentrancy/err @@ -1,12 +1,6 @@ -Warning: Return value of low-level calls not used. - --> model_checker_invariants_reentrancy/input.sol:6:3: - | -6 | _a.call(""); - | ^^^^^^^^^^^ - Info: CHC: 1 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. Info: Reentrancy property(ies) for model_checker_invariants_reentrancy/input.sol:test: ((( = 0) && (x!6 = x!4) && (x' = x)) || true || true || true || true) = 0 -> no errors - = 1 -> Assertion failed at assert(x < 10) + = 1 -> Assertion failed at assert(x == 0) diff --git a/test/cmdlineTests/model_checker_invariants_reentrancy/input.sol b/test/cmdlineTests/model_checker_invariants_reentrancy/input.sol index f21d4d4c8f46..e75a75b5fbb6 100644 --- a/test/cmdlineTests/model_checker_invariants_reentrancy/input.sol +++ b/test/cmdlineTests/model_checker_invariants_reentrancy/input.sol @@ -2,8 +2,7 @@ pragma solidity >=0.0; contract test { uint x; - function f(address _a) public { - _a.call(""); - assert(x < 10); - } -} \ No newline at end of file + function f() public view { + assert(x == 0); + } +} diff --git a/test/cmdlineTests/standard_model_checker_divModSlacks_false_all/output.json b/test/cmdlineTests/standard_model_checker_divModSlacks_false_all/output.json index eefa60785bb2..f4137ae42961 100644 --- a/test/cmdlineTests/standard_model_checker_divModSlacks_false_all/output.json +++ b/test/cmdlineTests/standard_model_checker_divModSlacks_false_all/output.json @@ -1,43 +1,5 @@ { "errors": [ - { - "component": "general", - "errorCode": "1218", - "formattedMessage": "Warning: CHC: Error trying to invoke SMT solver. - --> A:7:15: - | -7 | \t\t\t\t\t\treturn (a / b, a % b); - | \t\t\t\t\t\t ^^^^^ - -", - "message": "CHC: Error trying to invoke SMT solver.", - "severity": "warning", - "sourceLocation": { - "end": 182, - "file": "A", - "start": 177 - }, - "type": "Warning" - }, - { - "component": "general", - "errorCode": "1218", - "formattedMessage": "Warning: CHC: Error trying to invoke SMT solver. - --> A:7:22: - | -7 | \t\t\t\t\t\treturn (a / b, a % b); - | \t\t\t\t\t\t ^^^^^ - -", - "message": "CHC: Error trying to invoke SMT solver.", - "severity": "warning", - "sourceLocation": { - "end": 189, - "file": "A", - "start": 184 - }, - "type": "Warning" - }, { "component": "general", "errorCode": "5840", diff --git a/test/cmdlineTests/standard_model_checker_divModSlacks_false_chc/output.json b/test/cmdlineTests/standard_model_checker_divModSlacks_false_chc/output.json index 16fb77513081..8690a6e96cf1 100644 --- a/test/cmdlineTests/standard_model_checker_divModSlacks_false_chc/output.json +++ b/test/cmdlineTests/standard_model_checker_divModSlacks_false_chc/output.json @@ -1,43 +1,5 @@ { "errors": [ - { - "component": "general", - "errorCode": "1218", - "formattedMessage": "Warning: CHC: Error trying to invoke SMT solver. - --> A:7:15: - | -7 | \t\t\t\t\t\treturn (a / b, a % b); - | \t\t\t\t\t\t ^^^^^ - -", - "message": "CHC: Error trying to invoke SMT solver.", - "severity": "warning", - "sourceLocation": { - "end": 182, - "file": "A", - "start": 177 - }, - "type": "Warning" - }, - { - "component": "general", - "errorCode": "1218", - "formattedMessage": "Warning: CHC: Error trying to invoke SMT solver. - --> A:7:22: - | -7 | \t\t\t\t\t\treturn (a / b, a % b); - | \t\t\t\t\t\t ^^^^^ - -", - "message": "CHC: Error trying to invoke SMT solver.", - "severity": "warning", - "sourceLocation": { - "end": 189, - "file": "A", - "start": 184 - }, - "type": "Warning" - }, { "component": "general", "errorCode": "5840", diff --git a/test/libsolidity/smtCheckerTests/abi/abi_encode_with_selector_array_slice.sol b/test/libsolidity/smtCheckerTests/abi/abi_encode_with_selector_array_slice.sol index ed6f627b5adb..25f08dff48ee 100644 --- a/test/libsolidity/smtCheckerTests/abi/abi_encode_with_selector_array_slice.sol +++ b/test/libsolidity/smtCheckerTests/abi/abi_encode_with_selector_array_slice.sol @@ -25,7 +25,10 @@ contract C { // ==== // SMTEngine: all // SMTIgnoreCex: yes +// SMTIgnoreOS: macos // ---- // Warning 6328: (325-355): CHC: Assertion violation happens here. // Warning 6328: (578-608): CHC: Assertion violation happens here. -// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. +// Warning 6328: (691-721): CHC: Assertion violation happens here. +// Warning 6328: (959-989): CHC: Assertion violation happens here. +// Warning 6328: (1079-1109): CHC: Assertion violation happens here. diff --git a/test/libsolidity/smtCheckerTests/abi/abi_encode_with_selector_array_slice_2.sol b/test/libsolidity/smtCheckerTests/abi/abi_encode_with_selector_array_slice_2.sol index c13e9ce07fc7..d2446c5f92e6 100644 --- a/test/libsolidity/smtCheckerTests/abi/abi_encode_with_selector_array_slice_2.sol +++ b/test/libsolidity/smtCheckerTests/abi/abi_encode_with_selector_array_slice_2.sol @@ -23,9 +23,12 @@ contract C { } } // ==== -// SMTEngine: all +// SMTEngine: chc // SMTIgnoreCex: yes +// SMTIgnoreOS: macos // ---- // Warning 6328: (326-356): CHC: Assertion violation happens here. // Warning 6328: (579-609): CHC: Assertion violation happens here. -// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. +// Warning 6328: (692-722): CHC: Assertion violation happens here. +// Warning 6328: (960-990): CHC: Assertion violation happens here. +// Warning 6328: (1080-1110): CHC: Assertion violation happens here. diff --git a/test/libsolidity/smtCheckerTests/abi/abi_encode_with_selector_vs_sig.sol b/test/libsolidity/smtCheckerTests/abi/abi_encode_with_selector_vs_sig.sol index 4b4f7a3ace98..e4b42c926378 100644 --- a/test/libsolidity/smtCheckerTests/abi/abi_encode_with_selector_vs_sig.sol +++ b/test/libsolidity/smtCheckerTests/abi/abi_encode_with_selector_vs_sig.sol @@ -12,4 +12,4 @@ contract C { // SMTIgnoreOS: macos // ---- // Warning 6328: (330-360): CHC: Assertion violation might happen here. -// Warning 7812: (330-360): BMC: Assertion violation might happen here. +// Warning 4661: (330-360): BMC: Assertion violation happens here. diff --git a/test/libsolidity/smtCheckerTests/abi/abi_encode_with_sig_array_slice.sol b/test/libsolidity/smtCheckerTests/abi/abi_encode_with_sig_array_slice.sol index b2d1b4acc6d0..3bc9da4d63fe 100644 --- a/test/libsolidity/smtCheckerTests/abi/abi_encode_with_sig_array_slice.sol +++ b/test/libsolidity/smtCheckerTests/abi/abi_encode_with_sig_array_slice.sol @@ -23,8 +23,12 @@ contract C { } } // ==== -// SMTEngine: all +// SMTEngine: chc +// SMTIgnoreOS: macos +// SMTIgnoreCex: yes // ---- -// Warning 6328: (334-364): CHC: Assertion violation happens here.\nCounterexample:\n\ndata = [0x4f]\nb2 = [0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c]\nb3 = []\nb4 = []\nx = 0\ny = 0\nb5 = []\nb6 = []\n\nTransaction trace:\nC.constructor()\nC.abiEncodeSlice(sig, [0x4f]) -- counterexample incomplete; parameter name used instead of value +// Warning 6328: (334-364): CHC: Assertion violation happens here. // Warning 6328: (588-618): CHC: Assertion violation happens here. -// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. +// Warning 6328: (702-732): CHC: Assertion violation happens here. +// Warning 6328: (971-1001): CHC: Assertion violation happens here. +// Warning 6328: (1086-1116): CHC: Assertion violation happens here. diff --git a/test/libsolidity/smtCheckerTests/abi/abi_encode_with_sig_array_slice_2.sol b/test/libsolidity/smtCheckerTests/abi/abi_encode_with_sig_array_slice_2.sol index 4c21a02a6bbb..dbf28814d0ea 100644 --- a/test/libsolidity/smtCheckerTests/abi/abi_encode_with_sig_array_slice_2.sol +++ b/test/libsolidity/smtCheckerTests/abi/abi_encode_with_sig_array_slice_2.sol @@ -23,8 +23,12 @@ contract C { } } // ==== -// SMTEngine: all +// SMTEngine: chc +// SMTIgnoreOS: macos +// SMTIgnoreCex: yes // ---- -// Warning 6328: (335-365): CHC: Assertion violation happens here.\nCounterexample:\n\ndata = [36]\nb3 = []\nb4 = []\nx = 0\ny = 0\nb5 = []\nb6 = []\n\nTransaction trace:\nC.constructor()\nC.abiEncodeSlice(sig, [36]) -- counterexample incomplete; parameter name used instead of value +// Warning 6328: (335-365): CHC: Assertion violation happens here. // Warning 6328: (589-619): CHC: Assertion violation happens here. -// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. +// Warning 6328: (703-733): CHC: Assertion violation happens here. +// Warning 6328: (972-1002): CHC: Assertion violation happens here. +// Warning 6328: (1087-1117): CHC: Assertion violation happens here. diff --git a/test/libsolidity/smtCheckerTests/external_calls/call_with_value_1.sol b/test/libsolidity/smtCheckerTests/external_calls/call_with_value_1.sol index 813185adf497..b785895947f5 100644 --- a/test/libsolidity/smtCheckerTests/external_calls/call_with_value_1.sol +++ b/test/libsolidity/smtCheckerTests/external_calls/call_with_value_1.sol @@ -7,10 +7,9 @@ contract C { } } // ==== -// SMTEngine: all -// SMTIgnoreOS: macos +// SMTEngine: chc +// SMTSolvers: eld // ---- // Warning 9302: (96-117): Return value of low-level calls not used. -// Warning 6328: (121-156): CHC: Assertion violation might happen here. // Warning 6328: (175-211): CHC: Assertion violation happens here. -// Warning 4661: (121-156): BMC: Assertion violation happens here. +// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/external_calls/call_with_value_2.sol b/test/libsolidity/smtCheckerTests/external_calls/call_with_value_2.sol index 968095bb2b19..ef4b19c1d41c 100644 --- a/test/libsolidity/smtCheckerTests/external_calls/call_with_value_2.sol +++ b/test/libsolidity/smtCheckerTests/external_calls/call_with_value_2.sol @@ -7,9 +7,9 @@ contract C { } } // ==== -// SMTEngine: all +// SMTEngine: chc +// SMTSolvers: eld // ---- // Warning 9302: (96-116): Return value of low-level calls not used. -// Warning 6328: (120-156): CHC: Assertion violation might happen here. // Warning 6328: (175-210): CHC: Assertion violation happens here. -// Warning 4661: (120-156): BMC: Assertion violation happens here. +// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/external_calls/external.sol b/test/libsolidity/smtCheckerTests/external_calls/external.sol index 5ddb61a2226d..3e6dbe6411c5 100644 --- a/test/libsolidity/smtCheckerTests/external_calls/external.sol +++ b/test/libsolidity/smtCheckerTests/external_calls/external.sol @@ -15,7 +15,9 @@ contract C { } } // ==== -// SMTEngine: all +// SMTEngine: chc +// SMTTargets: assert +// SMTIgnoreCex: yes +// SMTIgnoreOS: linux // ---- -// Warning 6328: (167-181): CHC: Assertion violation happens here. -// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. +// Warning 6328: (167-181): CHC: Assertion violation happens here.\nCounterexample:\nx = 10, d = 0\n\nTransaction trace:\nC.constructor()\nState: x = 0, d = 0\nC.f()\nState: x = 1, d = 0\nC.f()\nState: x = 2, d = 0\nC.f()\nState: x = 3, d = 0\nC.f()\nState: x = 4, d = 0\nC.f()\nState: x = 5, d = 0\nC.f()\nState: x = 6, d = 0\nC.g()\n d.d() -- untrusted external call, synthesized as:\n C.f() -- reentrant call\n C.f() -- reentrant call\nState: x = 8, d = 0\nC.g()\n d.d() -- untrusted external call, synthesized as:\n C.f() -- reentrant call\n C.f() -- reentrant call diff --git a/test/libsolidity/smtCheckerTests/external_calls/external_call_indirect_1.sol b/test/libsolidity/smtCheckerTests/external_calls/external_call_indirect_1.sol index dd8a529a2f1f..65cd7b72cc3d 100644 --- a/test/libsolidity/smtCheckerTests/external_calls/external_call_indirect_1.sol +++ b/test/libsolidity/smtCheckerTests/external_calls/external_call_indirect_1.sol @@ -35,8 +35,7 @@ contract C { // ==== // SMTEngine: chc // SMTExtCalls: trusted -// SMTIgnoreOS: macos // ---- // Warning 6328: (256-277): CHC: Assertion violation happens here. -// Warning 6328: (533-554): CHC: Assertion violation happens here. +// Warning 6328: (533-554): CHC: Assertion violation might happen here. // Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/external_calls/external_call_indirect_2.sol b/test/libsolidity/smtCheckerTests/external_calls/external_call_indirect_2.sol index c1d567cfec7d..16779bb89a1f 100644 --- a/test/libsolidity/smtCheckerTests/external_calls/external_call_indirect_2.sol +++ b/test/libsolidity/smtCheckerTests/external_calls/external_call_indirect_2.sol @@ -47,7 +47,8 @@ contract C { // ==== // SMTEngine: chc // SMTExtCalls: trusted +// SMTIgnoreOS: macos // ---- // Warning 6328: (434-455): CHC: Assertion violation happens here. -// Warning 6328: (1270-1291): CHC: Assertion violation might happen here. +// Warning 6328: (1270-1291): CHC: Assertion violation happens here. // Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/external_calls/external_call_indirect_3.sol b/test/libsolidity/smtCheckerTests/external_calls/external_call_indirect_3.sol index d7721037fb88..3e8e4f409650 100644 --- a/test/libsolidity/smtCheckerTests/external_calls/external_call_indirect_3.sol +++ b/test/libsolidity/smtCheckerTests/external_calls/external_call_indirect_3.sol @@ -40,6 +40,7 @@ contract C { // ==== // SMTEngine: chc // SMTExtCalls: trusted +// SMTIgnoreOS: macos // ---- // Warning 6328: (561-582): CHC: Assertion violation happens here. // Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/external_calls/external_call_with_value_2.sol b/test/libsolidity/smtCheckerTests/external_calls/external_call_with_value_2.sol index 2b94abc0e02b..256a8870e10b 100644 --- a/test/libsolidity/smtCheckerTests/external_calls/external_call_with_value_2.sol +++ b/test/libsolidity/smtCheckerTests/external_calls/external_call_with_value_2.sol @@ -11,9 +11,9 @@ contract C { } } // ==== -// SMTEngine: all +// SMTEngine: chc // SMTIgnoreCex: yes +// SMTSolvers: eld // ---- -// Warning 6328: (150-186): CHC: Assertion violation might happen here. // Warning 6328: (205-240): CHC: Assertion violation happens here. -// Warning 4661: (150-186): BMC: Assertion violation happens here. +// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/external_calls/external_call_with_value_3.sol b/test/libsolidity/smtCheckerTests/external_calls/external_call_with_value_3.sol index 2a535329aca4..7d87fb07c405 100644 --- a/test/libsolidity/smtCheckerTests/external_calls/external_call_with_value_3.sol +++ b/test/libsolidity/smtCheckerTests/external_calls/external_call_with_value_3.sol @@ -11,9 +11,8 @@ contract C { } } // ==== -// SMTEngine: all -// SMTIgnoreOS: macos +// SMTEngine: chc +// SMTSolvers: eld // ---- -// Warning 6328: (150-183): CHC: Assertion violation might happen here. -// Warning 6328: (202-236): CHC: Assertion violation happens here.\nCounterexample:\n\ni = 0\n\nTransaction trace:\nC.constructor()\nC.g(0)\n i.f{value: 20}() -- untrusted external call -// Warning 4661: (150-183): BMC: Assertion violation happens here. +// Warning 6328: (202-236): CHC: Assertion violation happens here. +// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/external_calls/external_hash_known_code_state_reentrancy_3.sol b/test/libsolidity/smtCheckerTests/external_calls/external_hash_known_code_state_reentrancy_3.sol index 80e27e7e2a77..182bf15cc026 100644 --- a/test/libsolidity/smtCheckerTests/external_calls/external_hash_known_code_state_reentrancy_3.sol +++ b/test/libsolidity/smtCheckerTests/external_calls/external_hash_known_code_state_reentrancy_3.sol @@ -39,7 +39,8 @@ contract C { } } // ==== -// SMTEngine: all +// SMTEngine: chc +// SMTSolvers: eld // SMTIgnoreInv: yes // ---- // Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/external_calls/external_hash_known_code_state_reentrancy_trusted.sol b/test/libsolidity/smtCheckerTests/external_calls/external_hash_known_code_state_reentrancy_trusted.sol index 34df5c0e0fb9..3b6630e6db47 100644 --- a/test/libsolidity/smtCheckerTests/external_calls/external_hash_known_code_state_reentrancy_trusted.sol +++ b/test/libsolidity/smtCheckerTests/external_calls/external_hash_known_code_state_reentrancy_trusted.sol @@ -33,6 +33,6 @@ contract C { // SMTContract: C // SMTEngine: chc // SMTExtCalls: trusted +// SMTSolvers: eld // ---- -// Warning 6328: (314-328): CHC: Assertion violation might happen here. -// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. +// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/external_calls/external_safe.sol b/test/libsolidity/smtCheckerTests/external_calls/external_safe.sol index bfc95b35a2fd..a28e4852b0f2 100644 --- a/test/libsolidity/smtCheckerTests/external_calls/external_safe.sol +++ b/test/libsolidity/smtCheckerTests/external_calls/external_safe.sol @@ -16,5 +16,7 @@ contract C { } // ==== // SMTEngine: all +// SMTTargets: assert +// SMTIgnoreOS: linux // ---- -// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. +// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/operators/index_access_for_bytesNN.sol b/test/libsolidity/smtCheckerTests/operators/index_access_for_bytesNN.sol index b18d5426f5b8..ef02b7839d60 100644 --- a/test/libsolidity/smtCheckerTests/operators/index_access_for_bytesNN.sol +++ b/test/libsolidity/smtCheckerTests/operators/index_access_for_bytesNN.sol @@ -5,7 +5,7 @@ contract C { } } // ==== -// SMTEngine: all -// SMTIgnoreOS: macos +// SMTEngine: chc +// SMTSolvers: eld // ---- // Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/operators/index_access_side_effect.sol b/test/libsolidity/smtCheckerTests/operators/index_access_side_effect.sol index 644ecdb122f8..3057ae0ec4f6 100644 --- a/test/libsolidity/smtCheckerTests/operators/index_access_side_effect.sol +++ b/test/libsolidity/smtCheckerTests/operators/index_access_side_effect.sol @@ -21,5 +21,6 @@ contract C { // ==== // SMTEngine: all // SMTIgnoreCex: yes +// SMTTargets: assert // ---- -// Info 1391: CHC: 4 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. +// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/operators/userDefined/user_defined_operator_matches_equivalent_function_call.sol b/test/libsolidity/smtCheckerTests/operators/userDefined/user_defined_operator_matches_equivalent_function_call.sol index 76ad6db55384..30f6a0ba9781 100644 --- a/test/libsolidity/smtCheckerTests/operators/userDefined/user_defined_operator_matches_equivalent_function_call.sol +++ b/test/libsolidity/smtCheckerTests/operators/userDefined/user_defined_operator_matches_equivalent_function_call.sol @@ -53,10 +53,10 @@ contract C { } // ==== // SMTEngine: all +// SMTIgnoreOS: macos // SMTTargets: assert // ---- // Warning 6328: (2209-2235): CHC: Assertion violation might happen here. // Warning 6328: (2245-2271): CHC: Assertion violation might happen here. // Info 1391: CHC: 14 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. -// Warning 7812: (2245-2271): BMC: Assertion violation might happen here. -// Info 6002: BMC: 1 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. +// Info 6002: BMC: 2 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/out_of_bounds/array_2d_4.sol b/test/libsolidity/smtCheckerTests/out_of_bounds/array_2d_4.sol index 2a9f39d1a2fa..e4d9bfdff56c 100644 --- a/test/libsolidity/smtCheckerTests/out_of_bounds/array_2d_4.sol +++ b/test/libsolidity/smtCheckerTests/out_of_bounds/array_2d_4.sol @@ -15,13 +15,11 @@ contract C { // SMTEngine: all // ---- // Warning 4984: (184-197): CHC: Overflow (resulting value larger than 2**256 - 1) might happen here. -// Warning 4984: (199-202): CHC: Overflow (resulting value larger than 2**256 - 1) might happen here. -// Warning 6368: (228-232): CHC: Out of bounds access happens here. +// Warning 6368: (228-232): CHC: Out of bounds access happens here.\nCounterexample:\na = []\ni = 0\nj = 0\n\nTransaction trace:\nC.constructor()\nState: a = []\nC.r() // Warning 4984: (228-244): CHC: Overflow (resulting value larger than 2**256 - 1) might happen here. -// Warning 4984: (246-249): CHC: Overflow (resulting value larger than 2**256 - 1) might happen here. -// Warning 6368: (255-259): CHC: Out of bounds access happens here. +// Warning 6368: (255-259): CHC: Out of bounds access happens here.\nCounterexample:\na = []\ni = 0\nj = 0\n\nTransaction trace:\nC.constructor()\nState: a = []\nC.r() // Warning 6368: (255-262): CHC: Out of bounds access happens here. -// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. +// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. // Warning 2661: (184-197): BMC: Overflow (resulting value larger than 2**256 - 1) happens here. // Warning 2661: (228-244): BMC: Overflow (resulting value larger than 2**256 - 1) happens here. -// Info 6002: BMC: 4 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. +// Info 6002: BMC: 2 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/types/array_mapping_aliasing_2.sol b/test/libsolidity/smtCheckerTests/types/array_mapping_aliasing_2.sol index fce586987795..bbc3a79cf1a1 100644 --- a/test/libsolidity/smtCheckerTests/types/array_mapping_aliasing_2.sol +++ b/test/libsolidity/smtCheckerTests/types/array_mapping_aliasing_2.sol @@ -34,16 +34,7 @@ contract C // ==== // SMTEngine: all // SMTIgnoreCex: yes -// SMTIgnoreOS: macos +// SMTTargets: assert // ---- -// Warning 6368: (439-453): CHC: Out of bounds access happens here. -// Warning 6368: (465-480): CHC: Out of bounds access might happen here. -// Warning 6368: (492-508): CHC: Out of bounds access happens here. -// Warning 6368: (492-511): CHC: Out of bounds access happens here. -// Warning 6368: (622-636): CHC: Out of bounds access happens here. -// Warning 6368: (737-752): CHC: Out of bounds access might happen here. -// Warning 6368: (850-866): CHC: Out of bounds access happens here. -// Warning 6368: (850-869): CHC: Out of bounds access happens here. -// Warning 6328: (936-956): CHC: Assertion violation happens here. -// Warning 6368: (1029-1043): CHC: Out of bounds access might happen here. +// Warning 6328: (936-956): CHC: Assertion violation happens here.\nCounterexample:\n\nx = 0\n\nTransaction trace:\nC.constructor()\nC.g(0)\n C.f(map) -- counterexample incomplete; parameter name used instead of value -- internal call // Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/types/struct_array_branches_2d.sol b/test/libsolidity/smtCheckerTests/types/struct_array_branches_2d.sol index d5daba699912..5f4fad62abca 100644 --- a/test/libsolidity/smtCheckerTests/types/struct_array_branches_2d.sol +++ b/test/libsolidity/smtCheckerTests/types/struct_array_branches_2d.sol @@ -14,6 +14,7 @@ contract C } } // ==== -// SMTEngine: all +// SMTEngine: chc +// SMTTargets: assert // ---- -// Info 1391: CHC: 10 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. +// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. From 9fffec31b651553977f23f66a7c8443a2c2341b7 Mon Sep 17 00:00:00 2001 From: Martin Blicha Date: Thu, 12 Sep 2024 08:33:00 +0200 Subject: [PATCH 0528/1022] Purge Z3 from CMakeLists where possible --- CMakeLists.txt | 75 ++++++++++---------------------------- libsmtutil/CMakeLists.txt | 26 +------------ libsolidity/CMakeLists.txt | 6 +++ 3 files changed, 27 insertions(+), 80 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a0a8313b095c..836d2cccb79e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -90,63 +90,28 @@ configure_file("${PROJECT_SOURCE_DIR}/cmake/templates/license.h.in" include/lice include(EthOptions) configure_project(TESTS) -set(TESTED_Z3_VERSION "4.12.1") -set(MINIMUM_Z3_VERSION "4.8.16") -find_package(Z3) -if (${Z3_FOUND}) - if (${STRICT_Z3_VERSION}) - if (NOT ("${Z3_VERSION_STRING}" VERSION_EQUAL ${TESTED_Z3_VERSION})) - message( - FATAL_ERROR - "SMTChecker tests require Z3 ${TESTED_Z3_VERSION} for all tests to pass.\n\ -Build with -DSTRICT_Z3_VERSION=OFF if you want to use a different version. \ -You can also use -DUSE_Z3=OFF to build without Z3. In both cases use --no-smt when running tests." - ) - endif() - else() - if ("${Z3_VERSION_STRING}" VERSION_LESS ${MINIMUM_Z3_VERSION}) - message( - FATAL_ERROR - "Solidity requires Z3 ${MINIMUM_Z3_VERSION} or newer. You can also use -DUSE_Z3=OFF to build without Z3." - ) - endif() - endif() -endif() - -if(${USE_Z3_DLOPEN}) - add_definitions(-DHAVE_Z3) - add_definitions(-DHAVE_Z3_DLOPEN) - find_package(Python3 COMPONENTS Interpreter) - if(${Z3_FOUND}) - get_target_property(Z3_HEADER_HINTS z3::libz3 INTERFACE_INCLUDE_DIRECTORIES) - endif() - find_path(Z3_HEADER_PATH z3.h HINTS ${Z3_HEADER_HINTS}) - if(Z3_HEADER_PATH) - set(Z3_FOUND TRUE) - else() - message(SEND_ERROR "Dynamic loading of Z3 requires Z3 headers to be present at build time.") - endif() - if(NOT ${Python3_FOUND}) - message(SEND_ERROR "Dynamic loading of Z3 requires Python 3 to be present at build time.") - endif() - if(${SOLC_LINK_STATIC}) - message(SEND_ERROR "solc cannot be linked statically when dynamically loading Z3.") - endif() -elseif (${Z3_FOUND}) - add_definitions(-DHAVE_Z3) - message("Z3 SMT solver found. This enables optional SMT checking with Z3.") -endif() - -find_program(CVC5_PATH cvc5) - -if (NOT (${Z3_FOUND} OR CVC5_PATH)) - message("No SMT solver found (or it has been forcefully disabled). Optional SMT checking will not be available.\ - \nPlease install Z3 or cvc5 or remove the option disabling them (USE_Z3).") -endif() if(EMSCRIPTEN) - if(${Z3_FOUND}) - add_definitions(-DEMSCRIPTEN_BUILD) + set(TESTED_Z3_VERSION "4.12.1") + set(MINIMUM_Z3_VERSION "4.8.16") + find_package(Z3) + if (${Z3_FOUND}) + add_definitions(-DEMSCRIPTEN_BUILD) + if (${STRICT_Z3_VERSION}) + if (NOT ("${Z3_VERSION_STRING}" VERSION_EQUAL ${TESTED_Z3_VERSION})) + message( + FATAL_ERROR + "SMTChecker tests require Z3 ${TESTED_Z3_VERSION} for all tests to pass.\n" + ) + endif() + else() + if ("${Z3_VERSION_STRING}" VERSION_LESS ${MINIMUM_Z3_VERSION}) + message( + FATAL_ERROR + "Solidity requires Z3 ${MINIMUM_Z3_VERSION} or newer." + ) + endif() + endif() else() message(FATAL_ERROR "Solidity requires Z3 for emscripten build.") endif() diff --git a/libsmtutil/CMakeLists.txt b/libsmtutil/CMakeLists.txt index 2bd870549c2d..8b22da7dbd3b 100644 --- a/libsmtutil/CMakeLists.txt +++ b/libsmtutil/CMakeLists.txt @@ -16,30 +16,6 @@ set(sources Helpers.h ) -if (${Z3_FOUND}) - set(z3_SRCS) -else() - set(z3_SRCS) -endif() -if (${USE_Z3_DLOPEN}) - file(GLOB Z3_HEADERS ${Z3_HEADER_PATH}/z3*.h) - set(Z3_WRAPPER ${CMAKE_CURRENT_BINARY_DIR}/z3wrapper.cpp) - add_custom_command( - OUTPUT ${Z3_WRAPPER} - COMMAND ${Python3_EXECUTABLE} genz3wrapper.py ${Z3_HEADERS} > ${Z3_WRAPPER} - DEPENDS ${Z3_HEADERS} genz3wrapper.py - WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} - ) - set(z3_SRCS ${z3_SRCS} ${Z3_WRAPPER} Z3Loader.cpp Z3Loader.h) -endif() - -add_library(smtutil ${sources} ${z3_SRCS}) +add_library(smtutil ${sources}) target_link_libraries(smtutil PUBLIC solutil Boost::boost) - -if (${USE_Z3_DLOPEN}) - target_include_directories(smtutil PUBLIC ${Z3_HEADER_PATH}) - target_link_libraries(smtutil PUBLIC ${CMAKE_DL_LIBS}) -elseif (${Z3_FOUND}) - target_link_libraries(smtutil PUBLIC z3::libz3) -endif() diff --git a/libsolidity/CMakeLists.txt b/libsolidity/CMakeLists.txt index 1c4c48090645..5925a50ac480 100644 --- a/libsolidity/CMakeLists.txt +++ b/libsolidity/CMakeLists.txt @@ -224,3 +224,9 @@ set(sources add_library(solidity ${sources}) target_link_libraries(solidity PUBLIC yul evmasm langutil smtutil solutil Boost::boost fmt::fmt-header-only Threads::Threads) +if (EMSCRIPTEN) + if(NOT ${Z3_FOUND}) + message(FATAL_ERROR "Z3 library must be present for EMSCRIPTEN build") + endif() + target_link_libraries(solidity PUBLIC z3::libz3) +endif() From 8f4a7e11769661d77e113d41023dc265e7a1afb8 Mon Sep 17 00:00:00 2001 From: Martin Blicha Date: Thu, 12 Sep 2024 09:53:55 +0200 Subject: [PATCH 0529/1022] Docs: Update documentation about usage of Z3 --- docs/contributing.rst | 13 ++++++------- docs/smtchecker.rst | 6 +----- 2 files changed, 7 insertions(+), 12 deletions(-) diff --git a/docs/contributing.rst b/docs/contributing.rst index bb88d1201678..decd51392815 100644 --- a/docs/contributing.rst +++ b/docs/contributing.rst @@ -93,7 +93,7 @@ Prerequisites For running all compiler tests you may want to optionally install a few dependencies (`evmone `_, -`libz3 `_, `Eldarica `_, +`z3 `_, `Eldarica `_, `cvc5 `). On macOS systems, some of the testing scripts expect GNU coreutils to be installed. @@ -132,13 +132,12 @@ flag to ``scripts/soltest.sh``. The ``evmone`` library should end with the file name extension ``.so`` on Linux, ``.dll`` on Windows systems and ``.dylib`` on macOS. -For running SMT tests, the ``libz3`` library must be installed and locatable -by ``cmake`` during compiler configure stage. -A few SMT tests use ``Eldarica`` instead of ``Z3``. -``Eldarica`` is a runtime dependency, its executable (``eld``) must be present in ``PATH`` for the tests to pass. +For running SMT tests, the ``z3`` executable must be present in ``PATH``. +A few SMT tests use ``Eldarica`` instead of ``z3``. +These requry its executable (``eld``) to be present in ``PATH`` for the tests to pass. However, if ``Eldarica`` is not found, these tests will be automatically skipped. -If the ``libz3`` library is not installed on your system, you should disable the +If ``z3`` is not present on your system, you should disable the SMT tests by exporting ``SMT_FLAGS=--no-smt`` before running ``./scripts/tests.sh`` or running ``./scripts/soltest.sh --no-smt``. These tests are ``libsolidity/smtCheckerTests``. @@ -167,7 +166,7 @@ See especially: .. note:: Those working in a Windows environment wanting to run the above basic sets - without libz3. Using Git Bash, you use: ``./build/test/Release/soltest.exe -- --no-smt``. + without z3. Using Git Bash, you use: ``./build/test/Release/soltest.exe -- --no-smt``. If you are running this in plain Command Prompt, use ``.\build\test\Release\soltest.exe -- --no-smt``. If you want to debug using GDB, make sure you build differently than the "usual". diff --git a/docs/smtchecker.rst b/docs/smtchecker.rst index 92aaa847c921..7db996fafc88 100644 --- a/docs/smtchecker.rst +++ b/docs/smtchecker.rst @@ -831,11 +831,7 @@ option ``--model-checker-solvers {all,cvc5,eld,smtlib2,z3}`` or the JSON option These can be used together with the compiler's `callback mechanism `_ so that any solver binary from the system can be employed to synchronously return the results of the queries to the compiler. This can be used by both BMC and CHC depending on which solvers are called. -- ``z3`` is available - - - if ``solc`` is compiled with it; - - if a dynamic ``z3`` library of version >=4.8.x is installed in a Linux system (from Solidity 0.7.6); - - statically in ``soljson.js`` (from Solidity 0.6.9), that is, the JavaScript binary of the compiler. +- ``z3`` is available statically in ``soljson.js`` (from Solidity 0.6.9), that is, the JavaScript binary of the compiler. Otherwise it is used via its binary which must be installed in the system. .. note:: z3 version 4.8.16 broke ABI compatibility with previous versions and cannot From 2c75667266fd129694120780553d603def7a880d Mon Sep 17 00:00:00 2001 From: Martin Blicha Date: Thu, 12 Sep 2024 09:56:11 +0200 Subject: [PATCH 0530/1022] Add changelog entry about Z3 switch --- Changelog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/Changelog.md b/Changelog.md index 0ebefa6590f1..4c2885c9a8b8 100644 --- a/Changelog.md +++ b/Changelog.md @@ -4,6 +4,7 @@ Language Features: Compiler Features: + * SMTChecker: Z3 is now a runtime dependency, not a build dependency (except for emscripten build). Bugfixes: From 2ad9723df2b92d7bfc30a957f0bd8cb0cf936aeb Mon Sep 17 00:00:00 2001 From: Martin Blicha Date: Mon, 16 Sep 2024 16:58:02 +0200 Subject: [PATCH 0531/1022] SMTChecker: Validate interaction with SMT and CHC solvers We introduce new tyoe of check to validate our assumptions when interacting with the solvers. If our assumption is violated, we can gracefully handle that and not crash the whole compiler. --- libsmtutil/CHCSmtLib2Interface.cpp | 114 ++++++++++--------- libsmtutil/Exceptions.h | 12 ++ libsmtutil/SMTLib2Interface.cpp | 12 +- libsolidity/formal/BMC.cpp | 2 +- libsolidity/formal/CHC.cpp | 2 +- libsolidity/formal/Z3CHCSmtLib2Interface.cpp | 105 +++++++++-------- 6 files changed, 136 insertions(+), 111 deletions(-) diff --git a/libsmtutil/CHCSmtLib2Interface.cpp b/libsmtutil/CHCSmtLib2Interface.cpp index 02257031a4d9..0bd74a410300 100644 --- a/libsmtutil/CHCSmtLib2Interface.cpp +++ b/libsmtutil/CHCSmtLib2Interface.cpp @@ -93,25 +93,32 @@ void CHCSmtLib2Interface::addRule(Expression const& _expr, std::string const& /* CHCSolverInterface::QueryResult CHCSmtLib2Interface::query(Expression const& _block) { std::string query = dumpQuery(_block); - std::string response = querySolver(query); + try + { + std::string response = querySolver(query); - CheckResult result; - // NOTE: Our internal semantics is UNSAT -> SAFE and SAT -> UNSAFE, which corresponds to usual SMT-based model checking - // However, with CHC solvers, the meaning is flipped, UNSAT -> UNSAFE and SAT -> SAFE. - // So we have to flip the answer. - if (boost::starts_with(response, "sat")) + CheckResult result; + // NOTE: Our internal semantics is UNSAT -> SAFE and SAT -> UNSAFE, which corresponds to usual SMT-based model checking + // However, with CHC solvers, the meaning is flipped, UNSAT -> UNSAFE and SAT -> SAFE. + // So we have to flip the answer. + if (boost::starts_with(response, "sat")) + { + auto maybeInvariants = invariantsFromSolverResponse(response); + return {CheckResult::UNSATISFIABLE, maybeInvariants.value_or(Expression(true)), {}}; + } + else if (boost::starts_with(response, "unsat")) + result = CheckResult::SATISFIABLE; + else if (boost::starts_with(response, "unknown")) + result = CheckResult::UNKNOWN; + else + result = CheckResult::ERROR; + return {result, Expression(true), {}}; + } + catch(smtutil::SMTSolverInteractionError const&) { - auto maybeInvariants = invariantsFromSolverResponse(response); - return {CheckResult::UNSATISFIABLE, maybeInvariants.value_or(Expression(true)), {}}; + return {CheckResult::ERROR, Expression(true), {}}; } - else if (boost::starts_with(response, "unsat")) - result = CheckResult::SATISFIABLE; - else if (boost::starts_with(response, "unknown")) - result = CheckResult::UNKNOWN; - else - result = CheckResult::ERROR; - return {result, Expression(true), {}}; } void CHCSmtLib2Interface::declareVariable(std::string const& _name, SortPointer const& _sort) @@ -250,7 +257,7 @@ SortPointer CHCSmtLib2Interface::ScopedParser::toSort(SMTLib2Expression const& _ auto const& args = asSubExpressions(_expr); if (asAtom(args[0]) == "Array") { - smtAssert(args.size() == 3); + smtSolverInteractionRequire(args.size() == 3, "Wrong format of Array sort in solver's response"); auto domainSort = toSort(args[1]); auto codomainSort = toSort(args[2]); return std::make_shared(std::move(domainSort), std::move(codomainSort)); @@ -259,7 +266,7 @@ SortPointer CHCSmtLib2Interface::ScopedParser::toSort(SMTLib2Expression const& _ && asAtom(args[1]) == "int2bv") return std::make_shared(std::stoul(asAtom(args[2]))); } - smtAssert(false, "Unknown sort encountered"); + smtSolverInteractionRequire(false, "Unknown sort encountered"); } smtutil::Expression CHCSmtLib2Interface::ScopedParser::parseQuantifier( @@ -270,20 +277,20 @@ smtutil::Expression CHCSmtLib2Interface::ScopedParser::parseQuantifier( std::vector> boundVariables; for (auto const& sortedVar: _varList) { - smtAssert(!isAtom(sortedVar)); + smtSolverInteractionRequire(!isAtom(sortedVar), "Wrong format of quantified expression in solver's response"); auto varSortPair = asSubExpressions(sortedVar); - smtAssert(varSortPair.size() == 2); + smtSolverInteractionRequire(varSortPair.size() == 2, "Wrong format of quantified expression in solver's response"); boundVariables.emplace_back(asAtom(varSortPair[0]), toSort(varSortPair[1])); } for (auto const& [var, sort]: boundVariables) { - smtAssert(m_localVariables.count(var) == 0); // TODO: deal with shadowing? + smtSolverInteractionRequire(m_localVariables.count(var) == 0, "Quantifying over previously encountered variable"); // TODO: deal with shadowing? m_localVariables.emplace(var, sort); } auto core = toSMTUtilExpression(_coreExpression); for (auto const& [var, sort]: boundVariables) { - smtAssert(m_localVariables.count(var) != 0); + smtSolverInteractionRequire(m_localVariables.count(var) != 0, "Error in processing quantified expression"); m_localVariables.erase(var); } return Expression(_quantifierName, {core}, SortProvider::boolSort); // TODO: what about the bound variables? @@ -313,7 +320,7 @@ smtutil::Expression CHCSmtLib2Interface::ScopedParser::toSMTUtilExpression(SMTLi return smtutil::Expression(_atom, {}, std::make_shared(_atom, std::vector{}, std::vector{})); } else - smtAssert(false, "Unhandled atomic SMT expression"); + smtSolverInteractionRequire(false, "Unhandled atomic SMT expression"); }, [&](std::vector const& _subExpr) { @@ -325,13 +332,13 @@ smtutil::Expression CHCSmtLib2Interface::ScopedParser::toSMTUtilExpression(SMTLi if (op == "!") { // named term, we ignore the name - smtAssert(_subExpr.size() > 2); + smtSolverInteractionRequire(_subExpr.size() > 2, "Wrong format of named SMT-LIB term"); return toSMTUtilExpression(_subExpr[1]); } if (op == "exists" || op == "forall") { - smtAssert(_subExpr.size() == 3); - smtAssert(!isAtom(_subExpr[1])); + smtSolverInteractionRequire(_subExpr.size() == 3, "Wrong format of quantified expression"); + smtSolverInteractionRequire(!isAtom(_subExpr[1]), "Wrong format of quantified expression"); return parseQuantifier(op, asSubExpressions(_subExpr[1]), _subExpr[2]); } for (size_t i = 1; i < _subExpr.size(); i++) @@ -354,7 +361,7 @@ smtutil::Expression CHCSmtLib2Interface::ScopedParser::toSMTUtilExpression(SMTLi sort = contains(boolOperators, op) ? SortProvider::boolSort : arguments.back().sort; return smtutil::Expression(op, std::move(arguments), std::move(sort)); } - smtAssert(false, "Unhandled case in expression conversion"); + smtSolverInteractionRequire(false, "Unhandled case in expression conversion"); } else { @@ -374,7 +381,7 @@ smtutil::Expression CHCSmtLib2Interface::ScopedParser::toSMTUtilExpression(SMTLi && typeArgs[1].toString() == "int2bv") { auto bvSort = std::dynamic_pointer_cast(toSort(_subExpr[0])); - smtAssert(bvSort); + smtSolverInteractionRequire(bvSort, "Invalid format of bitvector sort"); return smtutil::Expression::int2bv(toSMTUtilExpression(_subExpr[1]), bvSort->size); } if (typeArgs.size() == 4 && typeArgs[0].toString() == "_" @@ -385,7 +392,7 @@ smtutil::Expression CHCSmtLib2Interface::ScopedParser::toSMTUtilExpression(SMTLi SortProvider::bitVectorSort // TODO: Compute bit size properly? ); } - smtAssert(false, "Unhandled case in expression conversion"); + smtSolverInteractionRequire(false, "Unhandled case in expression conversion"); } } }, @@ -394,15 +401,15 @@ smtutil::Expression CHCSmtLib2Interface::ScopedParser::toSMTUtilExpression(SMTLi } -#define precondition(CONDITION) if (!(CONDITION)) return {} std::optional CHCSmtLib2Interface::invariantsFromSolverResponse(std::string const& _response) const { std::stringstream ss(_response); std::string answer; ss >> answer; - precondition(answer == "sat"); + smtSolverInteractionRequire(answer == "sat", "CHC model can only be extracted from sat answer"); SMTLib2Parser parser(ss); - precondition(!parser.isEOF()); // There has to be a model + if (parser.isEOF()) + return {}; std::vector parsedOutput; try { @@ -411,25 +418,25 @@ std::optional CHCSmtLib2Interface::invariantsFromSolverResp } catch(SMTLib2Parser::ParsingException&) { - return {}; + smtSolverInteractionRequire(false, "Error during parsing CHC model"); } - smtAssert(parser.isEOF()); - precondition(!parsedOutput.empty()); + smtSolverInteractionRequire(parser.isEOF(), "Error during parsing CHC model"); + smtSolverInteractionRequire(!parsedOutput.empty(), "Error during parsing CHC model"); auto& commands = parsedOutput.size() == 1 ? asSubExpressions(parsedOutput[0]) : parsedOutput; std::vector definitions; for (auto& command: commands) { auto& args = asSubExpressions(command); - precondition(args.size() == 5); + smtSolverInteractionRequire(args.size() == 5, "Invalid format of CHC model"); // args[0] = "define-fun" // args[1] = predicate name // args[2] = formal arguments of the predicate // args[3] = return sort // args[4] = body of the predicate's interpretation - precondition(isAtom(args[0]) && asAtom(args[0]) == "define-fun"); - precondition(isAtom(args[1])); - precondition(!isAtom(args[2])); - precondition(isAtom(args[3]) && asAtom(args[3]) == "Bool"); + smtSolverInteractionRequire(isAtom(args[0]) && asAtom(args[0]) == "define-fun", "Invalid format of CHC model"); + smtSolverInteractionRequire(isAtom(args[1]), "Invalid format of CHC model"); + smtSolverInteractionRequire(!isAtom(args[2]), "Invalid format of CHC model"); + smtSolverInteractionRequire(isAtom(args[3]) && asAtom(args[3]) == "Bool", "Invalid format of CHC model"); auto& interpretation = args[4]; inlineLetExpressions(interpretation); ScopedParser scopedParser(m_context); @@ -437,10 +444,10 @@ std::optional CHCSmtLib2Interface::invariantsFromSolverResp std::vector predicateArgs; for (auto const& formalArgument: formalArguments) { - precondition(!isAtom(formalArgument)); + smtSolverInteractionRequire(!isAtom(formalArgument), "Invalid format of CHC model"); auto const& nameSortPair = asSubExpressions(formalArgument); - precondition(nameSortPair.size() == 2); - precondition(isAtom(nameSortPair[0])); + smtSolverInteractionRequire(nameSortPair.size() == 2, "Invalid format of CHC model"); + smtSolverInteractionRequire(isAtom(nameSortPair[0]), "Invalid format of CHC model"); SortPointer varSort = scopedParser.toSort(nameSortPair[1]); scopedParser.addVariableDeclaration(asAtom(nameSortPair[0]), varSort); // FIXME: Why Expression here? @@ -461,7 +468,6 @@ std::optional CHCSmtLib2Interface::invariantsFromSolverResp } return Expression::mkAnd(std::move(definitions)); } -#undef precondition namespace { @@ -478,8 +484,8 @@ struct LetBindings SMTLib2Expression& operator[](std::string const& varName) { auto it = bindings.find(varName); - smtAssert(it != bindings.end()); - smtAssert(!it->second.empty()); + smtSolverInteractionRequire(it != bindings.end(), "Error in processing let bindings"); + smtSolverInteractionRequire(!it->second.empty(), "Error in processing let bindings"); return it->second.back(); } @@ -487,13 +493,13 @@ struct LetBindings void popScope() { - smtAssert(!scopeBounds.empty()); + smtSolverInteractionRequire(!scopeBounds.empty(), "Error in processing let bindings"); auto bound = scopeBounds.back(); while (varNames.size() > bound) { auto const& varName = varNames.back(); auto it = bindings.find(varName); - smtAssert(it != bindings.end()); + smtSolverInteractionRequire(it != bindings.end(), "Error in processing let bindings"); auto& record = it->second; record.pop_back(); if (record.empty()) @@ -524,21 +530,21 @@ void inlineLetExpressions(SMTLib2Expression& _expr, LetBindings& _bindings) return; } auto& subexprs = asSubExpressions(_expr); - smtAssert(!subexprs.empty()); + smtSolverInteractionRequire(!subexprs.empty(), "Invalid let expression"); auto const& first = subexprs.at(0); if (isAtom(first) && asAtom(first) == "let") { - smtAssert(subexprs.size() == 3); - smtAssert(!isAtom(subexprs[1])); + smtSolverInteractionRequire(subexprs.size() == 3, "Invalid let expression"); + smtSolverInteractionRequire(!isAtom(subexprs[1]), "Invalid let expression"); auto& bindingExpressions = asSubExpressions(subexprs[1]); // process new bindings std::vector> newBindings; for (auto& binding: bindingExpressions) { - smtAssert(!isAtom(binding)); + smtSolverInteractionRequire(!isAtom(binding), "Invalid let expression"); auto& bindingPair = asSubExpressions(binding); - smtAssert(bindingPair.size() == 2); - smtAssert(isAtom(bindingPair.at(0))); + smtSolverInteractionRequire(bindingPair.size() == 2, "Invalid let expression"); + smtSolverInteractionRequire(isAtom(bindingPair.at(0)), "Invalid let expression"); inlineLetExpressions(bindingPair.at(1), _bindings); newBindings.emplace_back(asAtom(bindingPair.at(0)), bindingPair.at(1)); } @@ -562,7 +568,7 @@ void inlineLetExpressions(SMTLib2Expression& _expr, LetBindings& _bindings) { // A little hack to ensure quantified variables are not substituted because of some outer let definition: // We define the current binding of the variable to itself, before we recurse in to subterm - smtAssert(subexprs.size() == 3); + smtSolverInteractionRequire(subexprs.size() == 3, "Invalid let expression"); _bindings.pushScope(); for (auto const& sortedVar: asSubExpressions(subexprs.at(1))) { diff --git a/libsmtutil/Exceptions.h b/libsmtutil/Exceptions.h index 2a32c4fcda63..5c642b0e2a64 100644 --- a/libsmtutil/Exceptions.h +++ b/libsmtutil/Exceptions.h @@ -48,4 +48,16 @@ struct SMTLogicError: virtual util::Exception {}; "SMT assertion failed" \ ) + +// Error to indicate that some problem occurred during an interaction with external solver. +// This could be a problem with calling the solver or unexpected situation during the processing of solver's response. +struct SMTSolverInteractionError: virtual util::Exception {}; + +#define smtSolverInteractionRequire(CONDITION, DESCRIPTION) \ + assertThrowWithDefaultDescription( \ + (CONDITION), \ + ::solidity::smtutil::SMTSolverInteractionError, \ + (DESCRIPTION), \ + "Encountered problem during interaction with a solver" \ + ) } diff --git a/libsmtutil/SMTLib2Interface.cpp b/libsmtutil/SMTLib2Interface.cpp index 0914f8305dc3..0430f0d21ea0 100644 --- a/libsmtutil/SMTLib2Interface.cpp +++ b/libsmtutil/SMTLib2Interface.cpp @@ -119,7 +119,7 @@ std::vector parseValuesFromResponse(std::string const& _response) std::stringstream ss(_response); std::string answer; ss >> answer; - smtAssert(answer == "sat"); + smtSolverInteractionRequire(answer == "sat", "SMT: Parsing model values only possible after sat answer"); std::vector parsedOutput; SMTLib2Parser parser(ss); @@ -130,16 +130,16 @@ std::vector parseValuesFromResponse(std::string const& _response) } catch(SMTLib2Parser::ParsingException&) { - return {}; + smtSolverInteractionRequire(false, "Error during parsing SMT answer"); } - smtAssert(parsedOutput.size() == 1, "SMT: Expected model values as a single s-expression"); + smtSolverInteractionRequire(parsedOutput.size() == 1, "SMT: Expected model values as a single s-expression"); auto const& values = parsedOutput[0]; - smtAssert(!isAtom(values)); + smtSolverInteractionRequire(!isAtom(values), "Invalid format of values in SMT answer"); std::vector parsedValues; for (auto const& nameValuePair: asSubExpressions(values)) { - smtAssert(!isAtom(nameValuePair)); - smtAssert(asSubExpressions(nameValuePair).size() == 2); + smtSolverInteractionRequire(!isAtom(nameValuePair), "Invalid format of values in SMT answer"); + smtSolverInteractionRequire(asSubExpressions(nameValuePair).size() == 2, "Invalid format of values in SMT answer"); auto const& value = asSubExpressions(nameValuePair)[1]; parsedValues.push_back(value.toString()); } diff --git a/libsolidity/formal/BMC.cpp b/libsolidity/formal/BMC.cpp index a7f792453f09..6f3eb6c4cd02 100644 --- a/libsolidity/formal/BMC.cpp +++ b/libsolidity/formal/BMC.cpp @@ -1197,7 +1197,7 @@ void BMC::checkCondition( m_errorReporter.warning(1584_error, _location, "BMC: At least two SMT solvers provided conflicting answers. Results might not be sound."); break; case smtutil::CheckResult::ERROR: - m_errorReporter.warning(1823_error, _location, "BMC: Error trying to invoke SMT solver."); + m_errorReporter.warning(1823_error, _location, "BMC: Error during interaction with the SMT solver."); break; } diff --git a/libsolidity/formal/CHC.cpp b/libsolidity/formal/CHC.cpp index 7f413f91a999..9f23aff6fb67 100644 --- a/libsolidity/formal/CHC.cpp +++ b/libsolidity/formal/CHC.cpp @@ -1919,7 +1919,7 @@ CHCSolverInterface::QueryResult CHC::query(smtutil::Expression const& _query, la m_errorReporter.warning(1988_error, _location, "CHC: At least two SMT solvers provided conflicting answers. Results might not be sound."); break; case CheckResult::ERROR: - m_errorReporter.warning(1218_error, _location, "CHC: Error trying to invoke SMT solver."); + m_errorReporter.warning(1218_error, _location, "CHC: Error during interaction with the solver."); break; } return result; diff --git a/libsolidity/formal/Z3CHCSmtLib2Interface.cpp b/libsolidity/formal/Z3CHCSmtLib2Interface.cpp index a3aef325b0b1..2ceecfcf9088 100644 --- a/libsolidity/formal/Z3CHCSmtLib2Interface.cpp +++ b/libsolidity/formal/Z3CHCSmtLib2Interface.cpp @@ -62,48 +62,55 @@ CHCSolverInterface::QueryResult Z3CHCSmtLib2Interface::query(smtutil::Expression { setupSmtCallback(true); std::string query = dumpQuery(_block); + try + { #ifdef EMSCRIPTEN_BUILD - z3::set_param("fp.xform.slice", true); - z3::set_param("fp.xform.inline_linear", true); - z3::set_param("fp.xform.inline_eager", true); - std::string response = Z3_eval_smtlib2_string(z3::context{}, query.c_str()); + z3::set_param("fp.xform.slice", true); + z3::set_param("fp.xform.inline_linear", true); + z3::set_param("fp.xform.inline_eager", true); + std::string response = Z3_eval_smtlib2_string(z3::context{}, query.c_str()); #else - std::string response = querySolver(query); + std::string response = querySolver(query); #endif - // NOTE: Our internal semantics is UNSAT -> SAFE and SAT -> UNSAFE, which corresponds to usual SMT-based model checking - // However, with CHC solvers, the meaning is flipped, UNSAT -> UNSAFE and SAT -> SAFE. - // So we have to flip the answer. - if (boost::starts_with(response, "unsat")) - { - // Repeat the query with preprocessing disabled, to get the full proof - setupSmtCallback(false); - query = "(set-option :produce-proofs true)" + query + "\n(get-proof)"; + // NOTE: Our internal semantics is UNSAT -> SAFE and SAT -> UNSAFE, which corresponds to usual SMT-based model checking + // However, with CHC solvers, the meaning is flipped, UNSAT -> UNSAFE and SAT -> SAFE. + // So we have to flip the answer. + if (boost::starts_with(response, "unsat")) + { + // Repeat the query with preprocessing disabled, to get the full proof + setupSmtCallback(false); + query = "(set-option :produce-proofs true)" + query + "\n(get-proof)"; #ifdef EMSCRIPTEN_BUILD - z3::set_param("fp.xform.slice", false); - z3::set_param("fp.xform.inline_linear", false); - z3::set_param("fp.xform.inline_eager", false); - response = Z3_eval_smtlib2_string(z3::context{}, query.c_str()); + z3::set_param("fp.xform.slice", false); + z3::set_param("fp.xform.inline_linear", false); + z3::set_param("fp.xform.inline_eager", false); + response = Z3_eval_smtlib2_string(z3::context{}, query.c_str()); #else - response = querySolver(query); + response = querySolver(query); #endif - setupSmtCallback(true); - if (!boost::starts_with(response, "unsat")) - return {CheckResult::SATISFIABLE, Expression(true), {}}; - return {CheckResult::SATISFIABLE, Expression(true), graphFromZ3Answer(response)}; - } + setupSmtCallback(true); + if (!boost::starts_with(response, "unsat")) + return {CheckResult::SATISFIABLE, Expression(true), {}}; + return {CheckResult::SATISFIABLE, Expression(true), graphFromZ3Answer(response)}; + } - CheckResult result; - if (boost::starts_with(response, "sat")) + CheckResult result; + if (boost::starts_with(response, "sat")) + { + auto maybeInvariants = invariantsFromSolverResponse(response); + return {CheckResult::UNSATISFIABLE, maybeInvariants.value_or(Expression(true)), {}}; + } + else if (boost::starts_with(response, "unknown")) + result = CheckResult::UNKNOWN; + else + result = CheckResult::ERROR; + + return {result, Expression(true), {}}; + } + catch(smtutil::SMTSolverInteractionError const&) { - auto maybeInvariants = invariantsFromSolverResponse(response); - return {CheckResult::UNSATISFIABLE, maybeInvariants.value_or(Expression(true)), {}}; + return {CheckResult::ERROR, Expression(true), {}}; } - else if (boost::starts_with(response, "unknown")) - result = CheckResult::UNKNOWN; - else - result = CheckResult::ERROR; - - return {result, Expression(true), {}}; } @@ -112,7 +119,7 @@ CHCSolverInterface::CexGraph Z3CHCSmtLib2Interface::graphFromZ3Answer(std::strin std::stringstream ss(_proof); std::string answer; ss >> answer; - smtAssert(answer == "unsat"); + smtSolverInteractionRequire(answer == "unsat", "Proof must follow an unsat answer"); SMTLib2Parser parser(ss); if (parser.isEOF()) // No proof from Z3 @@ -125,10 +132,10 @@ CHCSolverInterface::CexGraph Z3CHCSmtLib2Interface::graphFromZ3Answer(std::strin } catch (SMTLib2Parser::ParsingException&) { - return {}; + smtSolverInteractionRequire(false, "Error during parsing Z3's proof"); } - solAssert(parser.isEOF()); - solAssert(!isAtom(parsedOutput)); + smtSolverInteractionRequire(parser.isEOF(), "Error during parsing Z3's proof"); + smtSolverInteractionRequire(!isAtom(parsedOutput), "Encountered unexpected format of Z3's proof"); auto& commands = asSubExpressions(parsedOutput); ScopedParser expressionParser(m_context); for (auto& command: commands) @@ -137,7 +144,7 @@ CHCSolverInterface::CexGraph Z3CHCSmtLib2Interface::graphFromZ3Answer(std::strin continue; auto const& args = asSubExpressions(command); - solAssert(args.size() > 0); + smtSolverInteractionRequire(args.size() > 0, "Encountered unexpected format of Z3's proof"); auto const& head = args[0]; if (!isAtom(head)) continue; @@ -146,12 +153,12 @@ CHCSolverInterface::CexGraph Z3CHCSmtLib2Interface::graphFromZ3Answer(std::strin // e.g., "(declare-fun query!0 (Bool Bool Bool Int Int Bool Bool Bool Bool Bool Bool Bool Int) Bool)" if (asAtom(head) == "declare-fun") { - solAssert(args.size() == 4); + smtSolverInteractionRequire(args.size() == 4, "Encountered unexpected format of Z3's proof"); auto const& name = args[1]; auto const& domainSorts = args[2]; auto const& codomainSort = args[3]; - solAssert(isAtom(name)); - solAssert(!isAtom(domainSorts)); + smtSolverInteractionRequire(isAtom(name), "Encountered unexpected format of Z3's proof"); + smtSolverInteractionRequire(!isAtom(domainSorts), "Encountered unexpected format of Z3's proof"); expressionParser.addVariableDeclaration(asAtom(name), expressionParser.toSort(codomainSort)); } // The subexpression starting with "proof" contains the whole proof, which we need to transform to our internal @@ -173,13 +180,13 @@ CHCSolverInterface::CexGraph Z3CHCSmtLib2Interface::graphFromSMTLib2Expression( auto fact = [](SMTLib2Expression const& _node) -> SMTLib2Expression const& { if (isAtom(_node)) return _node; - smtAssert(!asSubExpressions(_node).empty()); + smtSolverInteractionRequire(!asSubExpressions(_node).empty(), "Encountered unexpected format of Z3's proof"); return asSubExpressions(_node).back(); }; - smtAssert(!isAtom(_proof)); + smtSolverInteractionRequire(!isAtom(_proof), "Encountered unexpected format of Z3's proof"); auto const& proofArgs = asSubExpressions(_proof); - smtAssert(proofArgs.size() == 2); - smtAssert(isAtom(proofArgs.at(0)) && asAtom(proofArgs.at(0)) == "proof"); + smtSolverInteractionRequire(proofArgs.size() == 2, "Encountered unexpected format of Z3's proof"); + smtSolverInteractionRequire(isAtom(proofArgs.at(0)) && asAtom(proofArgs.at(0)) == "proof", "Encountered unexpected format of Z3's proof"); auto const& proofNode = proofArgs.at(1); auto const& derivedFact = fact(proofNode); if (isAtom(proofNode) || !isAtom(derivedFact) || asAtom(derivedFact) != "false") @@ -201,7 +208,7 @@ CHCSolverInterface::CexGraph Z3CHCSmtLib2Interface::graphFromSMTLib2Expression( auto isHyperRes = [](SMTLib2Expression const& expr) { if (isAtom(expr)) return false; auto const& subExprs = asSubExpressions(expr); - smtAssert(!subExprs.empty()); + smtSolverInteractionRequire(!subExprs.empty(), "Encountered unexpected format of Z3's proof"); auto const& op = subExprs.at(0); if (isAtom(op)) return false; auto const& opExprs = asSubExpressions(op); @@ -213,15 +220,15 @@ CHCSolverInterface::CexGraph Z3CHCSmtLib2Interface::graphFromSMTLib2Expression( while (!proofStack.empty()) { auto const* currentNode = proofStack.top(); - smtAssert(visitedIds.find(currentNode) != visitedIds.end()); + smtSolverInteractionRequire(visitedIds.find(currentNode) != visitedIds.end(), "Error in processing Z3's proof"); auto id = visitedIds.at(currentNode); - smtAssert(graph.nodes.count(id)); + smtSolverInteractionRequire(graph.nodes.count(id), "Error in processing Z3's proof"); proofStack.pop(); if (isHyperRes(*currentNode)) { auto const& args = asSubExpressions(*currentNode); - smtAssert(args.size() > 1); + smtSolverInteractionRequire(args.size() > 1, "Unexpected format of hyper-resolution rule in Z3's proof"); // args[0] is the name of the rule // args[1] is the clause used // last argument is the derived fact From c8d9fc3fb41ae6cec35c8d140d11110d1ffd8805 Mon Sep 17 00:00:00 2001 From: Daniel Kirchner Date: Tue, 22 Oct 2024 15:56:12 +0200 Subject: [PATCH 0532/1022] Remove remaining artifacts of dynamically loading Z3. --- .circleci/config.yml | 2 +- cmake/EthCompilerSettings.cmake | 3 - libsmtutil/Z3CHCInterface.cpp | 244 -------------- libsmtutil/Z3CHCInterface.h | 72 ---- libsmtutil/Z3Interface.cpp | 487 ---------------------------- libsmtutil/Z3Interface.h | 75 ----- libsmtutil/Z3Loader.cpp | 69 ---- libsmtutil/Z3Loader.h | 38 --- libsmtutil/genz3wrapper.py | 99 ------ libsolidity/formal/BMC.cpp | 7 - libsolidity/formal/ModelChecker.cpp | 6 - 11 files changed, 1 insertion(+), 1101 deletions(-) delete mode 100644 libsmtutil/Z3CHCInterface.cpp delete mode 100644 libsmtutil/Z3CHCInterface.h delete mode 100644 libsmtutil/Z3Interface.cpp delete mode 100644 libsmtutil/Z3Interface.h delete mode 100644 libsmtutil/Z3Loader.cpp delete mode 100644 libsmtutil/Z3Loader.h delete mode 100755 libsmtutil/genz3wrapper.py diff --git a/.circleci/config.yml b/.circleci/config.yml index 79a149a7ec63..a8f6d755247b 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1049,7 +1049,7 @@ jobs: <<: *base_ubuntu2004_xlarge environment: <<: *base_ubuntu2004_xlarge_env - CMAKE_OPTIONS: -DCMAKE_BUILD_TYPE=Release -DUSE_Z3_DLOPEN=ON -DSOLC_STATIC_STDLIBS=ON + CMAKE_OPTIONS: -DCMAKE_BUILD_TYPE=Release -DSOLC_STATIC_STDLIBS=ON steps: - checkout - run_build diff --git a/cmake/EthCompilerSettings.cmake b/cmake/EthCompilerSettings.cmake index 4cf3927d1d06..8b40bb2c58ad 100644 --- a/cmake/EthCompilerSettings.cmake +++ b/cmake/EthCompilerSettings.cmake @@ -263,6 +263,3 @@ endif() # SMT Solvers integration option(USE_Z3 "Allow compiling with Z3 SMT solver integration" ON) -if(UNIX AND NOT APPLE) - option(USE_Z3_DLOPEN "Dynamically load the Z3 SMT solver instead of linking against it." OFF) -endif() diff --git a/libsmtutil/Z3CHCInterface.cpp b/libsmtutil/Z3CHCInterface.cpp deleted file mode 100644 index a79630b6e59b..000000000000 --- a/libsmtutil/Z3CHCInterface.cpp +++ /dev/null @@ -1,244 +0,0 @@ -/* - This file is part of solidity. - - solidity is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - solidity is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with solidity. If not, see . -*/ -// SPDX-License-Identifier: GPL-3.0 - -#include - -#include - -#include -#include - -using namespace solidity; -using namespace solidity::smtutil; - -Z3CHCInterface::Z3CHCInterface(std::optional _queryTimeout): - CHCSolverInterface(_queryTimeout), - m_z3Interface(std::make_unique(m_queryTimeout)), - m_context(m_z3Interface->context()), - m_solver(*m_context) -{ - Z3_get_version( - &std::get<0>(m_version), - &std::get<1>(m_version), - &std::get<2>(m_version), - &std::get<3>(m_version) - ); - - // These need to be set globally. - z3::set_param("rewriter.pull_cheap_ite", true); - - if (m_queryTimeout) - m_context->set("timeout", int(*m_queryTimeout)); - else - z3::set_param("rlimit", Z3Interface::resourceLimit); - - setSpacerOptions(); -} - -void Z3CHCInterface::declareVariable(std::string const& _name, SortPointer const& _sort) -{ - smtAssert(_sort, ""); - m_z3Interface->declareVariable(_name, _sort); -} - -void Z3CHCInterface::registerRelation(Expression const& _expr) -{ - smtAssert(_expr.sort->kind == Kind::Function); - m_z3Interface->declareVariable(_expr.name, _expr.sort); - m_solver.register_relation(m_z3Interface->functions().at(_expr.name)); -} - -void Z3CHCInterface::addRule(Expression const& _expr, std::string const& _name) -{ - z3::expr rule = m_z3Interface->toZ3Expr(_expr); - if (m_z3Interface->constants().empty()) - m_solver.add_rule(rule, m_context->str_symbol(_name.c_str())); - else - { - z3::expr_vector variables(*m_context); - for (auto const& var: m_z3Interface->constants()) - variables.push_back(var.second); - z3::expr boundRule = z3::forall(variables, rule); - m_solver.add_rule(boundRule, m_context->str_symbol(_name.c_str())); - } -} - -CHCSolverInterface::QueryResult Z3CHCInterface::query(Expression const& _expr) -{ - CheckResult result; - try - { - z3::expr z3Expr = m_z3Interface->toZ3Expr(_expr); - switch (m_solver.query(z3Expr)) - { - case z3::check_result::sat: - { - result = CheckResult::SATISFIABLE; - // z3 version 4.8.8 modified Spacer to also return - // proofs containing nonlinear clauses. - if (m_version >= std::tuple(4, 8, 8, 0)) - { - auto proof = m_solver.get_answer(); - return {result, Expression(true), cexGraph(proof)}; - } - break; - } - case z3::check_result::unsat: - { - result = CheckResult::UNSATISFIABLE; - auto invariants = m_z3Interface->fromZ3Expr(m_solver.get_answer()); - return {result, std::move(invariants), {}}; - } - case z3::check_result::unknown: - { - result = CheckResult::UNKNOWN; - break; - } - } - // TODO retrieve model / invariants - } - catch (z3::exception const& _err) - { - std::set msgs{ - /// Resource limit (rlimit) exhausted. - "max. resource limit exceeded", - /// User given timeout exhausted. - "canceled" - }; - if (msgs.count(_err.msg())) - result = CheckResult::UNKNOWN; - else - result = CheckResult::ERROR; - } - - return {result, Expression(true), {}}; -} - -void Z3CHCInterface::setSpacerOptions(bool _preProcessing) -{ - // Spacer options. - // These needs to be set in the solver. - // https://github.com/Z3Prover/z3/blob/master/src/muz/base/fp_params.pyg - z3::params p(*m_context); - // These are useful for solving problems with arrays and loops. - // Use quantified lemma generalizer. - p.set("fp.spacer.q3.use_qgen", true); - p.set("fp.spacer.mbqi", false); - // Ground pobs by using values from a model. - p.set("fp.spacer.ground_pobs", false); - - // Spacer optimization should be - // - enabled for better solving (default) - // - disable for counterexample generation - p.set("fp.xform.slice", _preProcessing); - p.set("fp.xform.inline_linear", _preProcessing); - p.set("fp.xform.inline_eager", _preProcessing); - - m_solver.set(p); -} - -/** -Convert a ground refutation into a linear or nonlinear counterexample. -The counterexample is given as an implication graph of the form -`premises => conclusion` where `premises` are the predicates -from the body of nonlinear clauses, representing the proof graph. - -This function is based on and similar to -https://github.com/Z3Prover/z3/blob/z3-4.8.8/src/muz/spacer/spacer_context.cpp#L2919 -(spacer::context::get_ground_sat_answer) -which generates linear counterexamples. -It is modified here to accept nonlinear CHCs as well, generating a DAG -instead of a path. -*/ -CHCSolverInterface::CexGraph Z3CHCInterface::cexGraph(z3::expr const& _proof) -{ - /// The root fact of the refutation proof is `false`. - /// The node itself is not a hyper resolution, so we need to - /// extract the `query` hyper resolution node from the - /// `false` node (the first child). - /// The proof has the shape above for z3 >=4.8.8. - /// If an older version is used, this check will fail and no - /// counterexample will be generated. - if (!_proof.is_app() || fact(_proof).decl().decl_kind() != Z3_OP_FALSE) - return {}; - - CexGraph graph; - - std::stack proofStack; - proofStack.push(_proof.arg(0)); - - auto const& root = proofStack.top(); - graph.nodes.emplace(root.id(), m_z3Interface->fromZ3Expr(fact(root))); - - std::set visited; - visited.insert(root.id()); - - while (!proofStack.empty()) - { - z3::expr proofNode = proofStack.top(); - smtAssert(graph.nodes.count(proofNode.id()), ""); - proofStack.pop(); - - if (proofNode.is_app() && proofNode.decl().decl_kind() == Z3_OP_PR_HYPER_RESOLVE) - { - smtAssert(proofNode.num_args() > 0, ""); - for (unsigned i = 1; i < proofNode.num_args() - 1; ++i) - { - z3::expr child = proofNode.arg(i); - if (!visited.count(child.id())) - { - visited.insert(child.id()); - proofStack.push(child); - } - - if (!graph.nodes.count(child.id())) - { - graph.nodes.emplace(child.id(), m_z3Interface->fromZ3Expr(fact(child))); - graph.edges[child.id()] = {}; - } - - graph.edges[proofNode.id()].push_back(child.id()); - } - } - } - - return graph; -} - -z3::expr Z3CHCInterface::fact(z3::expr const& _node) -{ - smtAssert(_node.is_app(), ""); - if (_node.num_args() == 0) - return _node; - return _node.arg(_node.num_args() - 1); -} - -std::string Z3CHCInterface::name(z3::expr const& _predicate) -{ - smtAssert(_predicate.is_app(), ""); - return _predicate.decl().name().str(); -} - -std::vector Z3CHCInterface::arguments(z3::expr const& _predicate) -{ - smtAssert(_predicate.is_app(), ""); - std::vector args; - for (unsigned i = 0; i < _predicate.num_args(); ++i) - args.emplace_back(_predicate.arg(i).to_string()); - return args; -} diff --git a/libsmtutil/Z3CHCInterface.h b/libsmtutil/Z3CHCInterface.h deleted file mode 100644 index 98f21246c297..000000000000 --- a/libsmtutil/Z3CHCInterface.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - This file is part of solidity. - - solidity is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - solidity is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with solidity. If not, see . -*/ -// SPDX-License-Identifier: GPL-3.0 - -/** - * Z3 specific Horn solver interface. - */ - -#pragma once - -#include -#include - -#include -#include - -namespace solidity::smtutil -{ - -class Z3CHCInterface: public CHCSolverInterface -{ -public: - Z3CHCInterface(std::optional _queryTimeout = {}); - - /// Forwards variable declaration to Z3Interface. - void declareVariable(std::string const& _name, SortPointer const& _sort) override; - - void registerRelation(Expression const& _expr) override; - - void addRule(Expression const& _expr, std::string const& _name) override; - - QueryResult query(Expression const& _expr) override; - - Z3Interface* z3Interface() const { return m_z3Interface.get(); } - - void setSpacerOptions(bool _preProcessing = true); - -private: - /// Constructs a nonlinear counterexample graph from the refutation. - CHCSolverInterface::CexGraph cexGraph(z3::expr const& _proof); - /// @returns the fact from a proof node. - z3::expr fact(z3::expr const& _node); - /// @returns @a _predicate's name. - std::string name(z3::expr const& _predicate); - /// @returns the arguments of @a _predicate. - std::vector arguments(z3::expr const& _predicate); - - // Used to handle variables. - std::unique_ptr m_z3Interface; - - z3::context* m_context; - // Horn solver. - z3::fixedpoint m_solver; - - std::tuple m_version = std::tuple(0, 0, 0, 0); -}; - -} diff --git a/libsmtutil/Z3Interface.cpp b/libsmtutil/Z3Interface.cpp deleted file mode 100644 index efd656259819..000000000000 --- a/libsmtutil/Z3Interface.cpp +++ /dev/null @@ -1,487 +0,0 @@ -/* - This file is part of solidity. - - solidity is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - solidity is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with solidity. If not, see . -*/ -// SPDX-License-Identifier: GPL-3.0 - -#include - -#include -#include -#include - -#ifdef HAVE_Z3_DLOPEN -#include -#endif - -using namespace solidity::smtutil; -using namespace solidity::util; - -bool Z3Interface::available() -{ -#ifdef HAVE_Z3_DLOPEN - return Z3Loader::get().available(); -#else - return true; -#endif -} - -Z3Interface::Z3Interface(std::optional _queryTimeout): - BMCSolverInterface(_queryTimeout), - m_solver(m_context) -{ - // These need to be set globally. - z3::set_param("rewriter.pull_cheap_ite", true); - - if (m_queryTimeout) - m_context.set("timeout", int(*m_queryTimeout)); - else - z3::set_param("rlimit", resourceLimit); -} - -void Z3Interface::reset() -{ - m_constants.clear(); - m_functions.clear(); - m_solver.reset(); -} - -void Z3Interface::push() -{ - m_solver.push(); -} - -void Z3Interface::pop() -{ - m_solver.pop(); -} - -void Z3Interface::declareVariable(std::string const& _name, SortPointer const& _sort) -{ - smtAssert(_sort, ""); - if (_sort->kind == Kind::Function) - declareFunction(_name, *_sort); - else if (m_constants.count(_name)) - m_constants.at(_name) = m_context.constant(_name.c_str(), z3Sort(*_sort)); - else - m_constants.emplace(_name, m_context.constant(_name.c_str(), z3Sort(*_sort))); -} - -void Z3Interface::declareFunction(std::string const& _name, Sort const& _sort) -{ - smtAssert(_sort.kind == Kind::Function, ""); - FunctionSort fSort = dynamic_cast(_sort); - if (m_functions.count(_name)) - m_functions.at(_name) = m_context.function(_name.c_str(), z3Sort(fSort.domain), z3Sort(*fSort.codomain)); - else - m_functions.emplace(_name, m_context.function(_name.c_str(), z3Sort(fSort.domain), z3Sort(*fSort.codomain))); -} - -void Z3Interface::addAssertion(Expression const& _expr) -{ - m_solver.add(toZ3Expr(_expr)); -} - -std::pair> Z3Interface::check(std::vector const& _expressionsToEvaluate) -{ - CheckResult result; - std::vector values; - try - { - switch (m_solver.check()) - { - case z3::check_result::sat: - result = CheckResult::SATISFIABLE; - break; - case z3::check_result::unsat: - result = CheckResult::UNSATISFIABLE; - break; - case z3::check_result::unknown: - result = CheckResult::UNKNOWN; - break; - } - - if (result == CheckResult::SATISFIABLE && !_expressionsToEvaluate.empty()) - { - z3::model m = m_solver.get_model(); - for (Expression const& e: _expressionsToEvaluate) - values.push_back(util::toString(m.eval(toZ3Expr(e)))); - } - } - catch (z3::exception const& _err) - { - std::set msgs{ - /// Resource limit (rlimit) exhausted. - "max. resource limit exceeded", - /// User given timeout exhausted. - "canceled" - }; - - if (msgs.count(_err.msg())) - result = CheckResult::UNKNOWN; - else - result = CheckResult::ERROR; - values.clear(); - } - - return std::make_pair(result, values); -} - -z3::expr Z3Interface::toZ3Expr(Expression const& _expr) -{ - if (_expr.arguments.empty() && m_constants.count(_expr.name)) - return m_constants.at(_expr.name); - z3::expr_vector arguments(m_context); - for (auto const& arg: _expr.arguments) - arguments.push_back(toZ3Expr(arg)); - - try - { - std::string const& n = _expr.name; - if (m_functions.count(n)) - return m_functions.at(n)(arguments); - else if (m_constants.count(n)) - { - smtAssert(arguments.empty(), ""); - return m_constants.at(n); - } - else if (arguments.empty()) - { - if (n == "true") - return m_context.bool_val(true); - else if (n == "false") - return m_context.bool_val(false); - else if (_expr.sort->kind == Kind::Sort) - { - auto sortSort = std::dynamic_pointer_cast(_expr.sort); - smtAssert(sortSort, ""); - return m_context.constant(n.c_str(), z3Sort(*sortSort->inner)); - } - else if (n == "tuple_constructor") - { - auto constructor = z3::func_decl(m_context, Z3_get_tuple_sort_mk_decl(m_context, z3Sort(*_expr.sort))); - smtAssert(constructor.arity() == arguments.size()); - return constructor(); - } - else - try - { - return m_context.int_val(n.c_str()); - } - catch (z3::exception const& _e) - { - smtAssert(false, _e.msg()); - } - } - - smtAssert(_expr.hasCorrectArity(), ""); - if (n == "ite") - return z3::ite(arguments[0], arguments[1], arguments[2]); - else if (n == "not") - return !arguments[0]; - else if (n == "and") - return arguments[0] && arguments[1]; - else if (n == "or") - return arguments[0] || arguments[1]; - else if (n == "=>") - return z3::implies(arguments[0], arguments[1]); - else if (n == "=") - return arguments[0] == arguments[1]; - else if (n == "<") - return arguments[0] < arguments[1]; - else if (n == "<=") - return arguments[0] <= arguments[1]; - else if (n == ">") - return arguments[0] > arguments[1]; - else if (n == ">=") - return arguments[0] >= arguments[1]; - else if (n == "+") - return arguments[0] + arguments[1]; - else if (n == "-") - return arguments[0] - arguments[1]; - else if (n == "*") - return arguments[0] * arguments[1]; - else if (n == "div") - return arguments[0] / arguments[1]; - else if (n == "mod") - return z3::mod(arguments[0], arguments[1]); - else if (n == "bvnot") - return ~arguments[0]; - else if (n == "bvand") - return arguments[0] & arguments[1]; - else if (n == "bvor") - return arguments[0] | arguments[1]; - else if (n == "bvxor") - return arguments[0] ^ arguments[1]; - else if (n == "bvshl") - return z3::shl(arguments[0], arguments[1]); - else if (n == "bvlshr") - return z3::lshr(arguments[0], arguments[1]); - else if (n == "bvashr") - return z3::ashr(arguments[0], arguments[1]); - else if (n == "int2bv") - { - size_t size = std::stoul(_expr.arguments[1].name); - return z3::int2bv(static_cast(size), arguments[0]); - } - else if (n == "bv2int") - { - auto intSort = std::dynamic_pointer_cast(_expr.sort); - smtAssert(intSort, ""); - return z3::bv2int(arguments[0], intSort->isSigned); - } - else if (n == "select") - return z3::select(arguments[0], arguments[1]); - else if (n == "store") - return z3::store(arguments[0], arguments[1], arguments[2]); - else if (n == "const_array") - { - std::shared_ptr sortSort = std::dynamic_pointer_cast(_expr.arguments[0].sort); - smtAssert(sortSort, ""); - auto arraySort = std::dynamic_pointer_cast(sortSort->inner); - smtAssert(arraySort && arraySort->domain, ""); - return z3::const_array(z3Sort(*arraySort->domain), arguments[1]); - } - else if (n == "tuple_get") - { - size_t index = stoul(_expr.arguments[1].name); - return z3::func_decl(m_context, Z3_get_tuple_sort_field_decl(m_context, z3Sort(*_expr.arguments[0].sort), static_cast(index)))(arguments[0]); - } - else if (n == "tuple_constructor") - { - auto constructor = z3::func_decl(m_context, Z3_get_tuple_sort_mk_decl(m_context, z3Sort(*_expr.sort))); - smtAssert(constructor.arity() == arguments.size(), ""); - z3::expr_vector args(m_context); - for (auto const& arg: arguments) - args.push_back(arg); - return constructor(args); - } - - smtAssert(false); - } - catch (z3::exception const& _e) - { - smtAssert(false, _e.msg()); - } - - smtAssert(false); - - // FIXME: Workaround for spurious GCC 12.1 warning (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105794) - util::unreachable(); -} - -Expression Z3Interface::fromZ3Expr(z3::expr const& _expr) -{ - auto sort = fromZ3Sort(_expr.get_sort()); - if (_expr.is_const() || _expr.is_var()) - return Expression(_expr.to_string(), {}, sort); - - if (_expr.is_quantifier()) - { - std::string quantifierName; - if (_expr.is_exists()) - quantifierName = "exists"; - else if (_expr.is_forall()) - quantifierName = "forall"; - else if (_expr.is_lambda()) - quantifierName = "lambda"; - else - smtAssert(false, ""); - return Expression(quantifierName, {fromZ3Expr(_expr.body())}, sort); - } - smtAssert(_expr.is_app(), ""); - std::vector arguments; - for (unsigned i = 0; i < _expr.num_args(); ++i) - arguments.push_back(fromZ3Expr(_expr.arg(i))); - - auto kind = _expr.decl().decl_kind(); - - if (_expr.is_ite()) - return Expression::ite(arguments[0], arguments[1], arguments[2]); - else if (_expr.is_not()) - return !arguments[0]; - else if (_expr.is_and()) - return Expression::mkAnd(arguments); - else if (_expr.is_or()) - return Expression::mkOr(arguments); - else if (_expr.is_implies()) - return Expression::implies(arguments[0], arguments[1]); - else if (_expr.is_eq()) - { - smtAssert(arguments.size() == 2, ""); - return arguments[0] == arguments[1]; - } - else if (kind == Z3_OP_ULT || kind == Z3_OP_SLT) - return arguments[0] < arguments[1]; - else if (kind == Z3_OP_LE || kind == Z3_OP_ULEQ || kind == Z3_OP_SLEQ) - return arguments[0] <= arguments[1]; - else if (kind == Z3_OP_GT || kind == Z3_OP_SGT) - return arguments[0] > arguments[1]; - else if (kind == Z3_OP_GE || kind == Z3_OP_UGEQ || kind == Z3_OP_SGEQ) - return arguments[0] >= arguments[1]; - else if (kind == Z3_OP_ADD) - return Expression::mkPlus(arguments); - else if (kind == Z3_OP_SUB) - { - smtAssert(arguments.size() == 2, ""); - return arguments[0] - arguments[1]; - } - else if (kind == Z3_OP_MUL) - return Expression::mkMul(arguments); - else if (kind == Z3_OP_DIV) - { - smtAssert(arguments.size() == 2, ""); - return arguments[0] / arguments[1]; - } - else if (kind == Z3_OP_MOD) - return arguments[0] % arguments[1]; - else if (kind == Z3_OP_XOR) - return arguments[0] ^ arguments[1]; - else if (kind == Z3_OP_BOR) - return arguments[0] | arguments[1]; - else if (kind == Z3_OP_BAND) - return arguments[0] & arguments[1]; - else if (kind == Z3_OP_BXOR) - return arguments[0] ^ arguments[1]; - else if (kind == Z3_OP_BNOT) - return !arguments[0]; - else if (kind == Z3_OP_BSHL) - return arguments[0] << arguments[1]; - else if (kind == Z3_OP_BLSHR) - return arguments[0] >> arguments[1]; - else if (kind == Z3_OP_BASHR) - return Expression::ashr(arguments[0], arguments[1]); - else if (kind == Z3_OP_INT2BV) - return Expression::int2bv(arguments[0], _expr.get_sort().bv_size()); - else if (kind == Z3_OP_BV2INT) - return Expression::bv2int(arguments[0]); - else if (kind == Z3_OP_EXTRACT) - return Expression("extract", arguments, sort); - else if (kind == Z3_OP_SELECT) - return Expression::select(arguments[0], arguments[1]); - else if (kind == Z3_OP_STORE) - return Expression::store(arguments[0], arguments[1], arguments[2]); - else if (kind == Z3_OP_CONST_ARRAY) - { - auto sortSort = std::make_shared(fromZ3Sort(_expr.get_sort())); - return Expression::const_array(Expression(sortSort), arguments[0]); - } - else if (kind == Z3_OP_DT_CONSTRUCTOR) - { - auto sortSort = std::make_shared(fromZ3Sort(_expr.get_sort())); - return Expression::tuple_constructor(Expression(sortSort), arguments); - } - else if (kind == Z3_OP_DT_ACCESSOR) - return Expression("dt_accessor_" + _expr.decl().name().str(), arguments, sort); - else if (kind == Z3_OP_DT_IS) - return Expression("dt_is", {arguments.at(0)}, sort); - else if ( - kind == Z3_OP_UNINTERPRETED || - kind == Z3_OP_RECURSIVE - ) - return Expression(_expr.decl().name().str(), arguments, fromZ3Sort(_expr.get_sort())); - else if (kind == Z3_OP_CONCAT) - return Expression("concat", arguments, sort); - - smtAssert(false); - - // FIXME: Workaround for spurious GCC 12.1 warning (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105794) - util::unreachable(); -} - -z3::sort Z3Interface::z3Sort(Sort const& _sort) -{ - switch (_sort.kind) - { - case Kind::Bool: - return m_context.bool_sort(); - case Kind::Int: - return m_context.int_sort(); - case Kind::BitVector: - return m_context.bv_sort(dynamic_cast(_sort).size); - case Kind::Array: - { - auto const& arraySort = dynamic_cast(_sort); - return m_context.array_sort(z3Sort(*arraySort.domain), z3Sort(*arraySort.range)); - } - case Kind::Tuple: - { - auto const& tupleSort = dynamic_cast(_sort); - std::vector cMembers; - for (auto const& member: tupleSort.members) - cMembers.emplace_back(member.c_str()); - /// Using this instead of the function below because with that one - /// we can't use `&sorts[0]` here. - std::vector sorts; - for (auto const& sort: tupleSort.components) - sorts.push_back(z3Sort(*sort)); - z3::func_decl_vector projs(m_context); - z3::func_decl tupleConstructor = m_context.tuple_sort( - tupleSort.name.c_str(), - static_cast(tupleSort.members.size()), - cMembers.data(), - sorts.data(), - projs - ); - return tupleConstructor.range(); - } - - default: - break; - } - smtAssert(false, ""); - // Cannot be reached. - return m_context.int_sort(); -} - -z3::sort_vector Z3Interface::z3Sort(std::vector const& _sorts) -{ - z3::sort_vector z3Sorts(m_context); - for (auto const& _sort: _sorts) - z3Sorts.push_back(z3Sort(*_sort)); - return z3Sorts; -} - -SortPointer Z3Interface::fromZ3Sort(z3::sort const& _sort) -{ - if (_sort.is_bool()) - return SortProvider::boolSort; - if (_sort.is_int()) - return SortProvider::sintSort; - if (_sort.is_bv()) - return std::make_shared(_sort.bv_size()); - if (_sort.is_array()) - return std::make_shared(fromZ3Sort(_sort.array_domain()), fromZ3Sort(_sort.array_range())); - if (_sort.is_datatype()) - { - auto name = _sort.name().str(); - auto constructor = z3::func_decl(m_context, Z3_get_tuple_sort_mk_decl(m_context, _sort)); - std::vector memberNames; - std::vector memberSorts; - for (unsigned i = 0; i < constructor.arity(); ++i) - { - auto accessor = z3::func_decl(m_context, Z3_get_tuple_sort_field_decl(m_context, _sort, i)); - memberNames.push_back(accessor.name().str()); - memberSorts.push_back(fromZ3Sort(accessor.range())); - } - return std::make_shared(name, memberNames, memberSorts); - } - smtAssert(false, ""); -} - -std::vector Z3Interface::fromZ3Sort(z3::sort_vector const& _sorts) -{ - return applyMap(_sorts, [this](auto const& sort) { return fromZ3Sort(sort); }); -} diff --git a/libsmtutil/Z3Interface.h b/libsmtutil/Z3Interface.h deleted file mode 100644 index ee5270f440c9..000000000000 --- a/libsmtutil/Z3Interface.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - This file is part of solidity. - - solidity is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - solidity is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with solidity. If not, see . -*/ -// SPDX-License-Identifier: GPL-3.0 - -#pragma once - -#include -#include - -namespace solidity::smtutil -{ - -class Z3Interface: public BMCSolverInterface -{ -public: - /// Noncopyable. - Z3Interface(Z3Interface const&) = delete; - Z3Interface& operator=(Z3Interface const&) = delete; - - Z3Interface(std::optional _queryTimeout = {}); - - static bool available(); - - void reset() override; - - void push() override; - void pop() override; - - void declareVariable(std::string const& _name, SortPointer const& _sort) override; - - void addAssertion(Expression const& _expr) override; - std::pair> check(std::vector const& _expressionsToEvaluate) override; - - z3::expr toZ3Expr(Expression const& _expr); - smtutil::Expression fromZ3Expr(z3::expr const& _expr); - - std::map constants() const { return m_constants; } - std::map functions() const { return m_functions; } - - z3::context* context() { return &m_context; } - - // Z3 "basic resources" limit. - // This is used to make the runs more deterministic and platform/machine independent. - static int const resourceLimit = 2000000; - -private: - void declareFunction(std::string const& _name, Sort const& _sort); - - z3::sort z3Sort(Sort const& _sort); - z3::sort_vector z3Sort(std::vector const& _sorts); - smtutil::SortPointer fromZ3Sort(z3::sort const& _sort); - std::vector fromZ3Sort(z3::sort_vector const& _sorts); - - z3::context m_context; - z3::solver m_solver; - - std::map m_constants; - std::map m_functions; -}; - -} diff --git a/libsmtutil/Z3Loader.cpp b/libsmtutil/Z3Loader.cpp deleted file mode 100644 index 0211f600d9f1..000000000000 --- a/libsmtutil/Z3Loader.cpp +++ /dev/null @@ -1,69 +0,0 @@ -/* - This file is part of solidity. - - solidity is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - solidity is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with solidity. If not, see . -*/ -// SPDX-License-Identifier: GPL-3.0 - -#include -#include -#include -#include -#include - -#ifndef _GNU_SOURCE -#define _GNU_SOURCE -#endif -#include - -using namespace solidity; -using namespace solidity::smtutil; - -Z3Loader const& Z3Loader::get() -{ - static Z3Loader z3; - return z3; -} - -void* Z3Loader::loadSymbol(char const* _name) const -{ - smtAssert(m_handle, "Attempted to use dynamically loaded Z3, even though it is not available."); - void* sym = dlsym(m_handle, _name); - smtAssert(sym, std::string("Symbol \"") + _name + "\" not found in libz3.so"); - return sym; -} - -bool Z3Loader::available() const -{ - if (m_handle == nullptr) - return false; - unsigned major = 0; - unsigned minor = 0; - unsigned build = 0; - unsigned rev = 0; - Z3_get_version(&major, &minor, &build, &rev); - return major == Z3_MAJOR_VERSION && minor == Z3_MINOR_VERSION; -} - -Z3Loader::Z3Loader() -{ - std::string libname{"libz3.so." + std::to_string(Z3_MAJOR_VERSION) + "." + std::to_string(Z3_MINOR_VERSION)}; - m_handle = dlmopen(LM_ID_NEWLM, libname.c_str(), RTLD_NOW); -} - -Z3Loader::~Z3Loader() -{ - if (m_handle) - dlclose(m_handle); -} diff --git a/libsmtutil/Z3Loader.h b/libsmtutil/Z3Loader.h deleted file mode 100644 index 5e755cb24b0a..000000000000 --- a/libsmtutil/Z3Loader.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - This file is part of solidity. - - solidity is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - solidity is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with solidity. If not, see . -*/ -// SPDX-License-Identifier: GPL-3.0 - -#pragma once - -namespace solidity::smtutil -{ - -class Z3Loader -{ -public: - Z3Loader(Z3Loader const&) = delete; - Z3Loader& operator=(Z3Loader const&) = delete; - static Z3Loader const& get(); - void* loadSymbol(char const* _name) const; - bool available() const; -private: - Z3Loader(); - ~Z3Loader(); - void* m_handle = nullptr; -}; - -} \ No newline at end of file diff --git a/libsmtutil/genz3wrapper.py b/libsmtutil/genz3wrapper.py deleted file mode 100755 index 9b24b32dbfe1..000000000000 --- a/libsmtutil/genz3wrapper.py +++ /dev/null @@ -1,99 +0,0 @@ -#!/usr/bin/env python3 -# ------------------------------------------------------------------------------ -# 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 -#------------------------------------------------------------------------------ -# -# Script that generates a dlsym-wrapper for Z3 from the header files. -# Expects all Z3 headers as arguments and outputs the wrapper code to stdout. - -import sys -import re - -# Patterns to match Z3 API entry point definitions. -def_pat = re.compile(" *def_API(.*)") -extradef_pat = re.compile(" *extra_API(.*)") -# Pattern to extract name and arguments from the above. -def_args_pat = re.compile("\('([^']*)'[^\(\)]*\((.*)\)\s*\)") -# Pattern to extract a list of arguments from the above. -arg_list_pat = re.compile("[^\(]*\([^\)]*\)[, ]*") - -def generateEntryPoint(line, args): - m = def_args_pat.match(args) - if not m: - raise Exception('Could not parse entry point definition: ' + line) - name = m.group(1) - num_args = len(arg_list_pat.findall(m.group(2))) - arglist = ', '.join(f"_{i}" for i in range(num_args)) - paramlist = ', '.join(f"ArgType<&{name}, {i}> _{i}" for i in range(num_args)) - print(f'ResultType<&{name}> Z3_API {name}({paramlist})') - print('{') - print(f'\tstatic auto sym = reinterpret_cast(Z3Loader::get().loadSymbol(\"{name}\"));') - print(f'\treturn sym({arglist});') - print('}') - - -print(r"""// This file is auto-generated from genz3wrapper.py -#include -#include -#include - -namespace -{ - -template -struct FunctionTrait; - -template -struct FunctionTrait -{ - using ResultType = R; - template - using ArgType = std::tuple_element_t>; -}; - -template -using ResultType = typename FunctionTrait::ResultType; - -template -using ArgType = typename FunctionTrait::template ArgType; - -} - -using namespace solidity; -using namespace solidity::smtutil; - -extern "C" -{ - -void Z3_API Z3_set_error_handler(Z3_context c, Z3_error_handler h) -{ - static auto sym = reinterpret_cast(Z3Loader::get().loadSymbol("Z3_set_error_handler")); - sym(c, h); -} -""") - -for header in sys.argv[1:]: - with open(header, 'r') as f: - for line in f: - line = line.strip('\r\n\t ') - m = def_pat.match(line) - if m: - generateEntryPoint(line, m.group(1).strip('\r\n\t ')) - m = extradef_pat.match(line) - if m: - generateEntryPoint(line, m.group(1).strip('\r\n\t ')) - -print('}') diff --git a/libsolidity/formal/BMC.cpp b/libsolidity/formal/BMC.cpp index 6f3eb6c4cd02..679309766c36 100644 --- a/libsolidity/formal/BMC.cpp +++ b/libsolidity/formal/BMC.cpp @@ -30,10 +30,6 @@ #include -#ifdef HAVE_Z3_DLOPEN -#include -#endif - using namespace solidity; using namespace solidity::util; using namespace solidity::langutil; @@ -151,9 +147,6 @@ void BMC::analyze(SourceUnit const& _source, std::map -#ifdef HAVE_Z3_DLOPEN -#include -#endif #include @@ -210,9 +207,6 @@ SMTSolverChoice ModelChecker::checkRequestedSolvers(SMTSolverChoice _enabled, Er 8158_error, SourceLocation(), "Solver z3 was selected for SMTChecker but it is not available." -#ifdef HAVE_Z3_DLOPEN - " libz3.so." + std::to_string(Z3_MAJOR_VERSION) + "." + std::to_string(Z3_MINOR_VERSION) + " was not found." -#endif ); } From 66dc47f1f1e57670c237804be274259d461f460f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Tue, 22 Oct 2024 16:05:01 +0200 Subject: [PATCH 0533/1022] EVMVersion::name(): Use util::unreachable() to mark unreachable paths --- liblangutil/EVMVersion.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/liblangutil/EVMVersion.h b/liblangutil/EVMVersion.h index 3d58fed43709..4fdb85aea335 100644 --- a/liblangutil/EVMVersion.h +++ b/liblangutil/EVMVersion.h @@ -21,6 +21,8 @@ #pragma once +#include + #include #include #include @@ -105,7 +107,7 @@ class EVMVersion: case Version::Cancun: return "cancun"; case Version::Prague: return "prague"; } - return "INVALID"; + util::unreachable(); } /// Has the RETURNDATACOPY and RETURNDATASIZE opcodes. From a610a5f0acf32ce8bb31588d88deb71c90bf7ed2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Tue, 22 Oct 2024 15:34:58 +0200 Subject: [PATCH 0534/1022] Make it possible to enumerate EVM versions to avoid repetition --- liblangutil/EVMVersion.h | 15 ++++++++++----- solc/CommandLineParser.cpp | 3 +-- test/tools/fuzzer_common.cpp | 14 +------------- 3 files changed, 12 insertions(+), 20 deletions(-) diff --git a/liblangutil/EVMVersion.h b/liblangutil/EVMVersion.h index 4fdb85aea335..8b41105f1fc8 100644 --- a/liblangutil/EVMVersion.h +++ b/liblangutil/EVMVersion.h @@ -26,6 +26,7 @@ #include #include #include +#include #include @@ -64,9 +65,8 @@ class EVMVersion: static EVMVersion cancun() { return {Version::Cancun}; } static EVMVersion prague() { return {Version::Prague}; } - static std::optional fromString(std::string const& _version) - { - for (auto const& v: { + static std::vector allVersions() { + return { homestead(), tangerineWhistle(), spuriousDragon(), @@ -79,8 +79,13 @@ class EVMVersion: paris(), shanghai(), cancun(), - prague() - }) + prague(), + }; + } + + static std::optional fromString(std::string const& _version) + { + for (auto const& v: allVersions()) if (_version == v.name()) return v; return std::nullopt; diff --git a/solc/CommandLineParser.cpp b/solc/CommandLineParser.cpp index 4607250a62fb..aa38e6c7a0af 100644 --- a/solc/CommandLineParser.cpp +++ b/solc/CommandLineParser.cpp @@ -606,8 +606,7 @@ General Information)").c_str(), ( g_strEVMVersion.c_str(), po::value()->value_name("version")->default_value(EVMVersion{}.name()), - "Select desired EVM version. Either homestead, tangerineWhistle, spuriousDragon, " - "byzantium, constantinople, petersburg, istanbul, berlin, london, paris, shanghai, cancun or prague." + ("Select desired EVM version. Either " + util::joinHumanReadable(EVMVersion::allVersions(), ", ", " or ") + ".").c_str() ) ; if (!_forHelp) // Note: We intentionally keep this undocumented for now. diff --git a/test/tools/fuzzer_common.cpp b/test/tools/fuzzer_common.cpp index 1caa5357e534..6a70c1cc8f77 100644 --- a/test/tools/fuzzer_common.cpp +++ b/test/tools/fuzzer_common.cpp @@ -39,19 +39,7 @@ using namespace solidity::frontend; using namespace solidity::langutil; using namespace solidity::util; -static std::vector s_evmVersions = { - EVMVersion::homestead(), - EVMVersion::tangerineWhistle(), - EVMVersion::spuriousDragon(), - EVMVersion::byzantium(), - EVMVersion::constantinople(), - EVMVersion::petersburg(), - EVMVersion::istanbul(), - EVMVersion::berlin(), - EVMVersion::london(), - EVMVersion::paris(), - EVMVersion::prague() -}; +static std::vector s_evmVersions = EVMVersion::allVersions(); void FuzzerUtil::testCompilerJsonInterface(std::string const& _input, bool _optimize, bool _quiet) { From 167f5547da0e8b14adbd126c5cceb6f27531a3d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Tue, 22 Oct 2024 16:04:27 +0200 Subject: [PATCH 0535/1022] Mark prague as experimental in places where it was not so (docs, --help) --- docs/using-the-compiler.rst | 2 +- liblangutil/EVMVersion.h | 4 ++++ solc/CommandLineParser.cpp | 12 +++++++++++- 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/docs/using-the-compiler.rst b/docs/using-the-compiler.rst index 004bb4a6141d..b2fe490cc597 100644 --- a/docs/using-the-compiler.rst +++ b/docs/using-the-compiler.rst @@ -345,7 +345,7 @@ Input Description // Version of the EVM to compile for. // Affects type checking and code generation. Can be homestead, // tangerineWhistle, spuriousDragon, byzantium, constantinople, - // petersburg, istanbul, berlin, london, paris, shanghai, cancun (default) or prague. + // petersburg, istanbul, berlin, london, paris, shanghai, cancun (default) or prague (experimental). "evmVersion": "cancun", // Optional: Change compilation pipeline to go through the Yul intermediate representation. // This is false by default. diff --git a/liblangutil/EVMVersion.h b/liblangutil/EVMVersion.h index 8b41105f1fc8..2201f3c9dd1e 100644 --- a/liblangutil/EVMVersion.h +++ b/liblangutil/EVMVersion.h @@ -91,6 +91,10 @@ class EVMVersion: return std::nullopt; } + bool isExperimental() const { + return m_version == Version::Prague; + } + bool operator==(EVMVersion const& _other) const { return m_version == _other.m_version; } bool operator<(EVMVersion const& _other) const { return m_version < _other.m_version; } diff --git a/solc/CommandLineParser.cpp b/solc/CommandLineParser.cpp index aa38e6c7a0af..5929144049a2 100644 --- a/solc/CommandLineParser.cpp +++ b/solc/CommandLineParser.cpp @@ -592,6 +592,16 @@ General Information)").c_str(), ; desc.add(inputOptions); + auto const annotateEVMVersion = [](EVMVersion const& _version) { + return _version.name() + (_version.isExperimental() ? " (experimental)" : ""); + }; + std::vector allEVMVersions = EVMVersion::allVersions(); + std::string annotatedEVMVersions = util::joinHumanReadable( + allEVMVersions | ranges::views::transform(annotateEVMVersion), + ", ", + " or " + ); + po::options_description outputOptions("Output Options"); outputOptions.add_options() ( @@ -606,7 +616,7 @@ General Information)").c_str(), ( g_strEVMVersion.c_str(), po::value()->value_name("version")->default_value(EVMVersion{}.name()), - ("Select desired EVM version. Either " + util::joinHumanReadable(EVMVersion::allVersions(), ", ", " or ") + ".").c_str() + ("Select desired EVM version: " + annotatedEVMVersions + ".").c_str() ) ; if (!_forHelp) // Note: We intentionally keep this undocumented for now. From 457bed6c3a003a0946665c9322e8c56db615ce2e Mon Sep 17 00:00:00 2001 From: Daniel Kirchner Date: Tue, 22 Oct 2024 16:16:02 +0200 Subject: [PATCH 0536/1022] Also eliminate USE_Z3. --- .circleci/build_win.ps1 | 2 +- .circleci/config.yml | 2 - cmake/EthCompilerSettings.cmake | 3 -- cmake/FindZ3.cmake | 80 +++++++++++++++----------------- cmake/toolchains/libfuzzer.cmake | 2 - docs/installing-solidity.rst | 17 ++----- 6 files changed, 42 insertions(+), 64 deletions(-) diff --git a/.circleci/build_win.ps1 b/.circleci/build_win.ps1 index 730bb6319586..e95caa7c1cf6 100644 --- a/.circleci/build_win.ps1 +++ b/.circleci/build_win.ps1 @@ -18,7 +18,7 @@ else { mkdir build cd build $boost_dir=(Resolve-Path $PSScriptRoot\..\deps\boost\lib\cmake\Boost-*) -..\deps\cmake\bin\cmake -G "Visual Studio 16 2019" -DBoost_DIR="$boost_dir\" -DCMAKE_MSVC_RUNTIME_LIBRARY=MultiThreaded -DCMAKE_INSTALL_PREFIX="$PSScriptRoot\..\upload" -DUSE_Z3=OFF .. +..\deps\cmake\bin\cmake -G "Visual Studio 16 2019" -DBoost_DIR="$boost_dir\" -DCMAKE_MSVC_RUNTIME_LIBRARY=MultiThreaded -DCMAKE_INSTALL_PREFIX="$PSScriptRoot\..\upload" .. if ( -not $? ) { throw "CMake configure failed." } msbuild solidity.sln /p:Configuration=Release /m:10 /v:minimal if ( -not $? ) { throw "Build failed." } diff --git a/.circleci/config.yml b/.circleci/config.yml index a8f6d755247b..eb516140608e 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1110,8 +1110,6 @@ jobs: <<: *base_archlinux_large environment: <<: *base_archlinux_large_env - # This can be switched off if we run out of sync with Arch. - USE_Z3: ON steps: - run: name: Install build dependencies diff --git a/cmake/EthCompilerSettings.cmake b/cmake/EthCompilerSettings.cmake index 8b40bb2c58ad..ccbd8a6c4e93 100644 --- a/cmake/EthCompilerSettings.cmake +++ b/cmake/EthCompilerSettings.cmake @@ -260,6 +260,3 @@ if(COVERAGE) endif() add_compile_options(-g --coverage) endif() - -# SMT Solvers integration -option(USE_Z3 "Allow compiling with Z3 SMT solver integration" ON) diff --git a/cmake/FindZ3.cmake b/cmake/FindZ3.cmake index 092b8636b8e9..0a00fb1528c4 100644 --- a/cmake/FindZ3.cmake +++ b/cmake/FindZ3.cmake @@ -1,51 +1,47 @@ -if (USE_Z3) - # Save and clear Z3_FIND_VERSION, since the - # Z3 config module cannot handle version requirements. - set(Z3_FIND_VERSION_ORIG ${Z3_FIND_VERSION}) - set(Z3_FIND_VERSION) - # Try to find Z3 using its stock cmake files. - find_package(Z3 QUIET CONFIG) - # Restore Z3_FIND_VERSION for find_package_handle_standard_args. - set(Z3_FIND_VERSION ${Z3_FIND_VERSION_ORIG}) - set(Z3_FIND_VERSION_ORIG) +# Save and clear Z3_FIND_VERSION, since the +# Z3 config module cannot handle version requirements. +set(Z3_FIND_VERSION_ORIG ${Z3_FIND_VERSION}) +set(Z3_FIND_VERSION) +# Try to find Z3 using its stock cmake files. +find_package(Z3 QUIET CONFIG) +# Restore Z3_FIND_VERSION for find_package_handle_standard_args. +set(Z3_FIND_VERSION ${Z3_FIND_VERSION_ORIG}) +set(Z3_FIND_VERSION_ORIG) - include(FindPackageHandleStandardArgs) +include(FindPackageHandleStandardArgs) - if (Z3_FOUND) - set(Z3_VERSION ${Z3_VERSION_STRING}) - find_package_handle_standard_args(Z3 CONFIG_MODE) - else() - find_path(Z3_INCLUDE_DIR NAMES z3++.h PATH_SUFFIXES z3) - find_library(Z3_LIBRARY NAMES z3) - find_program(Z3_EXECUTABLE z3 PATH_SUFFIXES bin) +if (Z3_FOUND) + set(Z3_VERSION ${Z3_VERSION_STRING}) + find_package_handle_standard_args(Z3 CONFIG_MODE) +else() + find_path(Z3_INCLUDE_DIR NAMES z3++.h PATH_SUFFIXES z3) + find_library(Z3_LIBRARY NAMES z3) + find_program(Z3_EXECUTABLE z3 PATH_SUFFIXES bin) - if(Z3_INCLUDE_DIR AND Z3_LIBRARY) - if(Z3_EXECUTABLE) - execute_process (COMMAND ${Z3_EXECUTABLE} -version - OUTPUT_VARIABLE libz3_version_str - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE) + if(Z3_INCLUDE_DIR AND Z3_LIBRARY) + if(Z3_EXECUTABLE) + execute_process (COMMAND ${Z3_EXECUTABLE} -version + OUTPUT_VARIABLE libz3_version_str + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE) - string(REGEX REPLACE "^Z3 version ([0-9.]+).*" "\\1" - Z3_VERSION_STRING "${libz3_version_str}") - unset(libz3_version_str) - else() - message(WARNING "Could not determine the version of z3, since the z3 executable was not found.") - set(Z3_VERSION_STRING "0.0.0") - endif() + string(REGEX REPLACE "^Z3 version ([0-9.]+).*" "\\1" + Z3_VERSION_STRING "${libz3_version_str}") + unset(libz3_version_str) + else() + message(WARNING "Could not determine the version of z3, since the z3 executable was not found.") + set(Z3_VERSION_STRING "0.0.0") endif() - mark_as_advanced(Z3_VERSION_STRING z3_DIR) + endif() + mark_as_advanced(Z3_VERSION_STRING z3_DIR) - find_package_handle_standard_args(Z3 - REQUIRED_VARS Z3_LIBRARY Z3_INCLUDE_DIR - VERSION_VAR Z3_VERSION_STRING) + find_package_handle_standard_args(Z3 + REQUIRED_VARS Z3_LIBRARY Z3_INCLUDE_DIR + VERSION_VAR Z3_VERSION_STRING) - if (NOT TARGET z3::libz3) - add_library(z3::libz3 UNKNOWN IMPORTED) - set_property(TARGET z3::libz3 PROPERTY IMPORTED_LOCATION ${Z3_LIBRARY}) - set_property(TARGET z3::libz3 PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${Z3_INCLUDE_DIR}) - endif() + if (NOT TARGET z3::libz3) + add_library(z3::libz3 UNKNOWN IMPORTED) + set_property(TARGET z3::libz3 PROPERTY IMPORTED_LOCATION ${Z3_LIBRARY}) + set_property(TARGET z3::libz3 PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${Z3_INCLUDE_DIR}) endif() -else() - set(Z3_FOUND FALSE) endif() diff --git a/cmake/toolchains/libfuzzer.cmake b/cmake/toolchains/libfuzzer.cmake index f9ea64860ae9..272d0bc4d6e5 100644 --- a/cmake/toolchains/libfuzzer.cmake +++ b/cmake/toolchains/libfuzzer.cmake @@ -1,7 +1,5 @@ # Inherit default options include("${CMAKE_CURRENT_LIST_DIR}/default.cmake") -# Enable Z3 -set(USE_Z3 ON CACHE BOOL "Enable Z3" FORCE) # Build fuzzing binaries set(OSSFUZZ ON CACHE BOOL "Enable fuzzer build" FORCE) # Use libfuzzer as the fuzzing back-end diff --git a/docs/installing-solidity.rst b/docs/installing-solidity.rst index 5473dbb5240c..0d63d48212f9 100644 --- a/docs/installing-solidity.rst +++ b/docs/installing-solidity.rst @@ -527,23 +527,12 @@ If you are interested what CMake options are available run ``cmake .. -LH``. SMT Solvers ----------- -Solidity can be built against Z3 SMT solver and will do so by default if -it is found in the system. Z3 can be disabled by a ``cmake`` option. - -*Note: In some cases, this can also be a potential workaround for build failures.* - - -Inside the build folder you can disable Z3, since it is enabled by default: - -.. code-block:: bash - - # disables Z3 SMT Solver. - cmake .. -DUSE_Z3=OFF +Solidity can optionally use SMT solvers, namely ``z3``, ``cvc5`` and ``Eldarica``, +but their presence is checked only at runtime, they are not needed for the build to succeed. .. note:: - Solidity can optionally use other solvers, namely ``cvc5`` and ``Eldarica``, - but their presence is checked only at runtime, they are not needed for the build to succeed. + The emscripten builds require Z3 and will statically link against it instead. The Version String in Detail ============================ From 017d24bcc3ec0cc18510e0ce1defee80ce8cd92b Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Wed, 23 Oct 2024 11:03:03 +0200 Subject: [PATCH 0537/1022] SSACFGBuilder: Descent into constant condition for loops' conditions --- libyul/backends/evm/SSAControlFlowGraphBuilder.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/libyul/backends/evm/SSAControlFlowGraphBuilder.cpp b/libyul/backends/evm/SSAControlFlowGraphBuilder.cpp index dacd061806aa..e7b3c9e6d73e 100644 --- a/libyul/backends/evm/SSAControlFlowGraphBuilder.cpp +++ b/libyul/backends/evm/SSAControlFlowGraphBuilder.cpp @@ -421,6 +421,7 @@ void SSAControlFlowGraphBuilder::operator()(ForLoop const& _loop) if (constantCondition.has_value()) { + std::visit(*this, *_loop.condition); if (*constantCondition) { jump(debugDataOf(*_loop.condition), loopBody); From cbb604ead6d0c00f0eddb46126d0f08cc0f2db7e Mon Sep 17 00:00:00 2001 From: rodiazet Date: Wed, 23 Oct 2024 11:51:18 +0200 Subject: [PATCH 0538/1022] Add `ControlFlowSideEffects` parameter to `createFunction` in EVMDialect --- libyul/ControlFlowSideEffects.h | 24 +++++++++++++++++++++ libyul/backends/evm/EVMDialect.cpp | 34 +++++++++++++----------------- 2 files changed, 39 insertions(+), 19 deletions(-) diff --git a/libyul/ControlFlowSideEffects.h b/libyul/ControlFlowSideEffects.h index d4debab9381a..554019135b80 100644 --- a/libyul/ControlFlowSideEffects.h +++ b/libyul/ControlFlowSideEffects.h @@ -18,6 +18,9 @@ #pragma once +#include +#include + namespace solidity::yul { @@ -44,6 +47,27 @@ struct ControlFlowSideEffects { return (canTerminate || canRevert) && !canContinue; } + + static ControlFlowSideEffects fromInstruction(evmasm::Instruction _instruction) + { + ControlFlowSideEffects controlFlowSideEffects; + if (evmasm::SemanticInformation::terminatesControlFlow(_instruction)) + { + controlFlowSideEffects.canContinue = false; + if (evmasm::SemanticInformation::reverts(_instruction)) + { + controlFlowSideEffects.canTerminate = false; + controlFlowSideEffects.canRevert = true; + } + else + { + controlFlowSideEffects.canTerminate = true; + controlFlowSideEffects.canRevert = false; + } + } + + return controlFlowSideEffects; + } }; } diff --git a/libyul/backends/evm/EVMDialect.cpp b/libyul/backends/evm/EVMDialect.cpp index 1ed422551402..27a1f1426d75 100644 --- a/libyul/backends/evm/EVMDialect.cpp +++ b/libyul/backends/evm/EVMDialect.cpp @@ -68,20 +68,7 @@ BuiltinFunctionForEVM createEVMFunction( f.numParameters = static_cast(info.args); f.numReturns = static_cast(info.ret); f.sideEffects = EVMDialect::sideEffectsOfInstruction(_instruction); - if (evmasm::SemanticInformation::terminatesControlFlow(_instruction)) - { - f.controlFlowSideEffects.canContinue = false; - if (evmasm::SemanticInformation::reverts(_instruction)) - { - f.controlFlowSideEffects.canTerminate = false; - f.controlFlowSideEffects.canRevert = true; - } - else - { - f.controlFlowSideEffects.canTerminate = true; - f.controlFlowSideEffects.canRevert = false; - } - } + f.controlFlowSideEffects = ControlFlowSideEffects::fromInstruction(_instruction); f.isMSize = _instruction == evmasm::Instruction::MSIZE; f.literalArguments.clear(); f.instruction = _instruction; @@ -100,6 +87,7 @@ BuiltinFunctionForEVM createFunction( size_t _params, size_t _returns, SideEffects _sideEffects, + ControlFlowSideEffects _controlFlowSideEffects, std::vector> _literalArguments, std::function _generateCode ) @@ -111,6 +99,7 @@ BuiltinFunctionForEVM createFunction( f.numParameters = _params; f.numReturns = _returns; f.sideEffects = _sideEffects; + f.controlFlowSideEffects = _controlFlowSideEffects; f.literalArguments = std::move(_literalArguments); f.isMSize = false; f.instruction = {}; @@ -231,16 +220,17 @@ std::vector> createBuiltins(langutil::EVMVe size_t _params, size_t _returns, SideEffects _sideEffects, + ControlFlowSideEffects _controlFlowSideEffects, std::vector> _literalArguments, std::function _generateCode ) -> std::optional { if (!_objectAccess) return std::nullopt; - return createFunction(_name, _params, _returns, _sideEffects, std::move(_literalArguments), std::move(_generateCode)); + return createFunction(_name, _params, _returns, _sideEffects, _controlFlowSideEffects, std::move(_literalArguments), std::move(_generateCode)); }; - builtins.emplace_back(createIfObjectAccess("linkersymbol", 1, 1, SideEffects{}, {LiteralKind::String}, []( + builtins.emplace_back(createIfObjectAccess("linkersymbol", 1, 1, SideEffects{}, ControlFlowSideEffects{}, {LiteralKind::String}, []( FunctionCall const& _call, AbstractAssembly& _assembly, BuiltinContext& @@ -254,6 +244,7 @@ std::vector> createBuiltins(langutil::EVMVe 1, 1, SideEffects{}, + ControlFlowSideEffects{}, {LiteralKind::Number}, []( FunctionCall const& _call, @@ -268,7 +259,7 @@ std::vector> createBuiltins(langutil::EVMVe ); if (!_eofVersion.has_value()) { - builtins.emplace_back(createIfObjectAccess("datasize", 1, 1, SideEffects{}, {LiteralKind::String}, []( + builtins.emplace_back(createIfObjectAccess("datasize", 1, 1, SideEffects{}, ControlFlowSideEffects{}, {LiteralKind::String}, []( FunctionCall const& _call, AbstractAssembly& _assembly, BuiltinContext& _context @@ -289,7 +280,7 @@ std::vector> createBuiltins(langutil::EVMVe _assembly.appendDataSize(subIdPath); } })); - builtins.emplace_back(createIfObjectAccess("dataoffset", 1, 1, SideEffects{}, {LiteralKind::String}, []( + builtins.emplace_back(createIfObjectAccess("dataoffset", 1, 1, SideEffects{}, ControlFlowSideEffects{}, {LiteralKind::String}, []( FunctionCall const& _call, AbstractAssembly& _assembly, BuiltinContext& _context @@ -325,6 +316,7 @@ std::vector> createBuiltins(langutil::EVMVe SideEffects::Write, // memory SideEffects::None // transientStorage }, + ControlFlowSideEffects::fromInstruction(evmasm::Instruction::CODECOPY), {}, []( FunctionCall const&, @@ -349,6 +341,7 @@ std::vector> createBuiltins(langutil::EVMVe SideEffects::Write, // memory SideEffects::None // transientStorage }, + ControlFlowSideEffects{}, {std::nullopt, LiteralKind::String, std::nullopt}, []( FunctionCall const& _call, @@ -365,6 +358,7 @@ std::vector> createBuiltins(langutil::EVMVe 1, 1, SideEffects{}, + ControlFlowSideEffects{}, {LiteralKind::String}, []( FunctionCall const& _call, @@ -382,7 +376,8 @@ std::vector> createBuiltins(langutil::EVMVe "auxdataloadn", 1, 1, - SideEffects{}, + EVMDialect::sideEffectsOfInstruction(evmasm::Instruction::DATALOADN), + ControlFlowSideEffects::fromInstruction(evmasm::Instruction::DATALOADN), {LiteralKind::Number}, []( FunctionCall const& _call, @@ -531,6 +526,7 @@ BuiltinFunctionForEVM EVMDialect::createVerbatimFunction(size_t _arguments, size 1 + _arguments, _returnVariables, SideEffects::worst(), + ControlFlowSideEffects{}, std::vector>{LiteralKind::String} + std::vector>(_arguments), [=]( FunctionCall const& _call, From edc352b03d28aa87f0311cc08f38533bfc5764be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Fri, 25 Oct 2024 03:17:42 +0200 Subject: [PATCH 0539/1022] cmdlineTests.sh: Compare stderr first and exit code last - Comparing exit code first looks confusing in CI, because we see that there is an error but not what it is. - Similarly, we wnat to see the errors before we see the difference in output (which is usually just the stdout becoming empty) --- test/cmdlineTests.sh | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/test/cmdlineTests.sh b/test/cmdlineTests.sh index 4f7b88fe974f..3c781ea78f07 100755 --- a/test/cmdlineTests.sh +++ b/test/cmdlineTests.sh @@ -275,12 +275,18 @@ EOF sed -i.bak -e 's/^\(Dynamic exception type:\).*/\1/' "$stderr_path" rm "$stderr_path.bak" - if [[ $exitCode -ne "$exit_code_expected" ]] + if [[ "$(cat "$stderr_path")" != "${stderr_expected}" ]] then - printError "Incorrect exit code. Expected $exit_code_expected but got $exitCode." + printError "Incorrect output on stderr received. Expected:" + echo -e "${stderr_expected}" - [[ $exit_code_expectation_file != "" ]] && ask_expectation_update "$exitCode" "$exit_code_expectation_file" - [[ $exit_code_expectation_file == "" ]] && fail + printError "But got:" + echo -e "$(cat "$stderr_path")" + + printError "When running $solc_command" + + [[ $stderr_expectation_file != "" ]] && ask_expectation_update "$(cat "$stderr_path")" "$stderr_expectation_file" + [[ $stderr_expectation_file == "" ]] && fail fi if [[ "$(cat "$stdout_path")" != "${stdout_expected}" ]] @@ -297,18 +303,12 @@ EOF [[ $stdout_expectation_file == "" ]] && fail fi - if [[ "$(cat "$stderr_path")" != "${stderr_expected}" ]] + if [[ $exitCode -ne "$exit_code_expected" ]] then - printError "Incorrect output on stderr received. Expected:" - echo -e "${stderr_expected}" - - printError "But got:" - echo -e "$(cat "$stderr_path")" - - printError "When running $solc_command" + printError "Incorrect exit code. Expected $exit_code_expected but got $exitCode." - [[ $stderr_expectation_file != "" ]] && ask_expectation_update "$(cat "$stderr_path")" "$stderr_expectation_file" - [[ $stderr_expectation_file == "" ]] && fail + [[ $exit_code_expectation_file != "" ]] && ask_expectation_update "$exitCode" "$exit_code_expectation_file" + [[ $exit_code_expectation_file == "" ]] && fail fi rm "$stdout_path" "$stderr_path" From 21df0544c1423da72ec37b5fea121826f56bb9b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Fri, 25 Oct 2024 03:32:32 +0200 Subject: [PATCH 0540/1022] parallel_cli_tests.py: Handle test runner failures gracefully, by printing the error - No need to let the exception escape and print the whole stack trace. This is an expected situation. --- .circleci/parallel_cli_tests.py | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/.circleci/parallel_cli_tests.py b/.circleci/parallel_cli_tests.py index 45cc83aec318..42dabbf05ed3 100755 --- a/.circleci/parallel_cli_tests.py +++ b/.circleci/parallel_cli_tests.py @@ -37,10 +37,13 @@ else: filters = list(selected_tests) -subprocess.run( - ['test/cmdlineTests.sh'] + filters, - stdin=sys.stdin, - stdout=sys.stdout, - stderr=sys.stderr, - check=True, -) +try: + subprocess.run( + ['test/cmdlineTests.sh'] + filters, + stdin=sys.stdin, + stdout=sys.stdout, + stderr=sys.stderr, + check=True, + ) +except subprocess.CalledProcessError as exception: + sys.exit(exception) From f5914232d335df35fe40acecbac6099310ce517d Mon Sep 17 00:00:00 2001 From: rodiazet Date: Fri, 25 Oct 2024 11:59:09 +0200 Subject: [PATCH 0541/1022] eof: Fix `AuxDataLoadN` immediate argument printing --- libevmasm/AssemblyItem.cpp | 2 +- test/cmdlineTests/strict_asm_eof_dataloadn_prague/output | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libevmasm/AssemblyItem.cpp b/libevmasm/AssemblyItem.cpp index 202bb2256463..3ce6238bc8be 100644 --- a/libevmasm/AssemblyItem.cpp +++ b/libevmasm/AssemblyItem.cpp @@ -342,7 +342,7 @@ std::string AssemblyItem::toAssemblyText(Assembly const& _assembly) const break; case AuxDataLoadN: assertThrow(data() <= std::numeric_limits::max(), AssemblyException, "Invalid auxdataloadn argument."); - text = "auxdataloadn(" + std::to_string(static_cast(data())) + ")"; + text = "auxdataloadn{" + std::to_string(static_cast(data())) + "}"; break; } if (m_jumpType == JumpType::IntoFunction || m_jumpType == JumpType::OutOfFunction) diff --git a/test/cmdlineTests/strict_asm_eof_dataloadn_prague/output b/test/cmdlineTests/strict_asm_eof_dataloadn_prague/output index 5f768feebd32..1c06caa5e36d 100644 --- a/test/cmdlineTests/strict_asm_eof_dataloadn_prague/output +++ b/test/cmdlineTests/strict_asm_eof_dataloadn_prague/output @@ -17,7 +17,7 @@ Binary representation: ef0001010004020001000904002d000080ffffd1000d5f5260205ff348656c6c6f2c20576f726c6421 Text representation: - auxdataloadn(0) + auxdataloadn{0} 0x00 mstore 0x20 From 42d94f5ee100303113058e18573c4ed2fc854322 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Fri, 25 Oct 2024 12:14:35 +0200 Subject: [PATCH 0542/1022] Yulopti: Fix parsing error --- test/tools/yulopti.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/tools/yulopti.cpp b/test/tools/yulopti.cpp index cbe0219676fa..e3ea50d099ef 100644 --- a/test/tools/yulopti.cpp +++ b/test/tools/yulopti.cpp @@ -91,7 +91,7 @@ class YulOpti try { auto ast = yul::Parser(errorReporter, m_dialect).parse(_charStream); - if (!m_astRoot || errorReporter.hasErrors()) + if (!ast || errorReporter.hasErrors()) { std::cerr << "Error parsing source." << std::endl; printErrors(_charStream, errors); From e5bfa54f580a0a96943de44afdfb54b0f57660c6 Mon Sep 17 00:00:00 2001 From: monem <119044801+pucedoteth@users.noreply.github.com> Date: Tue, 29 Oct 2024 01:33:55 +0200 Subject: [PATCH 0543/1022] Update ReleaseChecklist.md --- ReleaseChecklist.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ReleaseChecklist.md b/ReleaseChecklist.md index 8ca2e7f96ed3..a70afe0cb503 100644 --- a/ReleaseChecklist.md +++ b/ReleaseChecklist.md @@ -76,7 +76,7 @@ At least a day before the release: - [ ] Create a pull request in solc-bin and merge. ### Homebrew and MacOS - - [ ] Update the version and the hash (``sha256sum solidity_$VERSION.tar.gz``) in the [``solidity`` formula in Homebrew core repository](https://github.com/Homebrew/homebrew-core/blob/master/Formula/solidity.rb). + - [ ] Update the version and the hash (``sha256sum solidity_$VERSION.tar.gz``) in the [``solidity`` formula in Homebrew core repository](https://github.com/Homebrew/homebrew-core/blob/master/Formula/s/solidity.rb). ### Docker - [ ] Run ``./scripts/docker_deploy_manual.sh v$VERSION``. From d4078ee5abed5dbb4ecd20c3990f541666e5fa02 Mon Sep 17 00:00:00 2001 From: rodiazet Date: Tue, 29 Oct 2024 09:38:33 +0100 Subject: [PATCH 0544/1022] eof: Update `dataloadn` test with new immediate arguments notation --- test/libyul/objectCompiler/eof/dataloadn.yul | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/libyul/objectCompiler/eof/dataloadn.yul b/test/libyul/objectCompiler/eof/dataloadn.yul index 8b1c7ab8015c..b38222917af0 100644 --- a/test/libyul/objectCompiler/eof/dataloadn.yul +++ b/test/libyul/objectCompiler/eof/dataloadn.yul @@ -9,12 +9,12 @@ object "a" { } // ==== -// bytecodeFormat: >=EOFv1 // EVMVersion: >=prague +// bytecodeFormat: >=EOFv1 // ---- // Assembly: // /* "source":56:71 */ -// auxdataloadn(0) +// auxdataloadn{0} // /* "source":53:54 */ // 0x00 // /* "source":46:72 */ @@ -29,4 +29,4 @@ object "a" { // data_acaf3289d7b601cbd114fb36c4d29c85bbfd5e133f14cb355c3fd8d99367964f 48656c6c6f2c20576f726c6421 // Bytecode: ef0001010004020001000904002d000080ffffd1000d5f5260205ff348656c6c6f2c20576f726c6421 // Opcodes: 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP MULMOD DIV STOP 0x2D STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT DATALOADN 0xD PUSH0 MSTORE PUSH1 0x20 PUSH0 RETURN BASEFEE PUSH6 0x6C6C6F2C2057 PUSH16 0x726C6421000000000000000000000000 -// SourceMappings: 56:15:0:-:0;53:1;46:26;95:2;92:1;85:13 \ No newline at end of file +// SourceMappings: 56:15:0:-:0;53:1;46:26;95:2;92:1;85:13 From 41edff7100b58780111662043df59ec364ef99f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Tue, 29 Oct 2024 14:22:27 +0100 Subject: [PATCH 0545/1022] via_ir_equivalence test: Fix syntqax used to check for a list match --- test/cmdlineTests/~via_ir_equivalence/test.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/cmdlineTests/~via_ir_equivalence/test.sh b/test/cmdlineTests/~via_ir_equivalence/test.sh index d663bef858c5..0dcfba47135f 100755 --- a/test/cmdlineTests/~via_ir_equivalence/test.sh +++ b/test/cmdlineTests/~via_ir_equivalence/test.sh @@ -86,7 +86,7 @@ requiresOptimizer=( for contractFile in "${externalContracts[@]}" do - if ! [[ "${requiresOptimizer[*]}" =~ $contractFile ]] + if ! [[ " ${requiresOptimizer[*]} " == *" $contractFile "* ]] then printTask " - ${contractFile}" test_via_ir_equivalence "${REPO_ROOT}/test/${contractFile}" From 1f2c5319507e13126fd626ae9c46977196c58b32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Tue, 29 Oct 2024 14:21:44 +0100 Subject: [PATCH 0546/1022] Add an EOF pass to soltest --- .circleci/config.yml | 6 ++++++ .circleci/soltest.sh | 35 +++++++++++++++++++++++++++++++++++ .circleci/soltest_all.sh | 35 +++++++++++++++++++++++------------ 3 files changed, 64 insertions(+), 12 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index eb516140608e..0bd7932ce0eb 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1141,6 +1141,7 @@ jobs: environment: <<: *base_osx_env EVM: << pipeline.parameters.evm-version >> + EOF_VERSION: 0 OPTIMIZE: 0 steps: - checkout @@ -1233,6 +1234,7 @@ jobs: environment: <<: *base_archlinux_env EVM: << pipeline.parameters.evm-version >> + EOF_VERSION: 0 OPTIMIZE: 0 # 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. @@ -1250,6 +1252,7 @@ jobs: environment: <<: *base_ubuntu2404_clang_env EVM: << pipeline.parameters.evm-version >> + EOF_VERSION: 0 OPTIMIZE: 0 # The high parallelism in this job is causing the SMT tests to run out of memory, # so disabling for now. @@ -1299,6 +1302,7 @@ jobs: environment: <<: *base_ubuntu2404_env EVM: << pipeline.parameters.evm-version >> + EOF_VERSION: 0 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 @@ -1314,6 +1318,7 @@ jobs: environment: <<: *base_ubuntu2404_clang_env EVM: << pipeline.parameters.evm-version >> + EOF_VERSION: 0 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 @@ -1326,6 +1331,7 @@ jobs: environment: <<: *base_ubuntu2404_clang_env EVM: << pipeline.parameters.evm-version >> + EOF_VERSION: 0 SOLTEST_FLAGS: --no-smt steps: - soltest diff --git a/.circleci/soltest.sh b/.circleci/soltest.sh index 488201bae3ff..9631a72568c9 100755 --- a/.circleci/soltest.sh +++ b/.circleci/soltest.sh @@ -36,12 +36,44 @@ set -e OPTIMIZE=${OPTIMIZE:-"0"} EVM=${EVM:-"invalid"} +EOF_VERSION=${EOF_VERSION:-0} CPUs=${CPUs:-3} REPODIR="$(realpath "$(dirname "$0")/..")" IFS=" " read -r -a BOOST_TEST_ARGS <<< "$BOOST_TEST_ARGS" IFS=" " read -r -a SOLTEST_FLAGS <<< "$SOLTEST_FLAGS" +# TODO: [EOF] These won't pass on EOF yet. Reenable them when the implementation is complete. +EOF_EXCLUDES=( + --run_test='!Assembler/all_assembly_items' + --run_test='!Assembler/immutable' + --run_test='!Assembler/immutables_and_its_source_maps' + --run_test='!Optimiser/jumpdest_removal_subassemblies' + --run_test='!Optimiser/jumpdest_removal_subassemblies/*' + --run_test='!SolidityCompiler/does_not_include_creation_time_only_internal_functions' + --run_test='!SolidityInlineAssembly/Analysis/create2' + --run_test='!SolidityInlineAssembly/Analysis/inline_assembly_shadowed_instruction_declaration' + --run_test='!SolidityInlineAssembly/Analysis/large_constant' + --run_test='!SolidityInlineAssembly/Analysis/staticcall' + --run_test='!ViewPureChecker/assembly_staticcall' + --run_test='!functionSideEffects/otherImmovables' + --run_test='!functionSideEffects/state' + --run_test='!functionSideEffects/storage' + --run_test='!gasTests/abiv2' + --run_test='!gasTests/abiv2_optimised' + --run_test='!gasTests/data_storage' + --run_test='!gasTests/dispatch_large' + --run_test='!gasTests/dispatch_large_optimised' + --run_test='!gasTests/dispatch_medium' + --run_test='!gasTests/dispatch_medium_optimised' + --run_test='!gasTests/dispatch_small' + --run_test='!gasTests/dispatch_small_optimised' + --run_test='!gasTests/exp' + --run_test='!gasTests/exp_optimized' + --run_test='!gasTests/storage_costs' + --run_test='!yulStackLayout/literal_loop' +) + # shellcheck source=scripts/common.sh source "${REPODIR}/scripts/common.sh" # Test result output directory (CircleCI is reading test results from here) @@ -55,6 +87,7 @@ get_logfile_basename() { local filename="${EVM}" test "${OPTIMIZE}" = "1" && filename="${filename}_opt" test "${ABI_ENCODER_V1}" = "1" && filename="${filename}_abiv1" + (( EOF_VERSION != 0 )) && filename="${filename}_eofv${EOF_VERSION}" filename="${filename}_${run}" echo -ne "${filename}" @@ -78,10 +111,12 @@ do "--logger=HRF,error,stdout" "${BOOST_TEST_ARGS[@]}" ) + (( EOF_VERSION != 0 )) && BOOST_TEST_ARGS_RUN+=("${EOF_EXCLUDES[@]}") SOLTEST_ARGS=("--evm-version=$EVM" "${SOLTEST_FLAGS[@]}") test "${OPTIMIZE}" = "1" && SOLTEST_ARGS+=(--optimize) test "${ABI_ENCODER_V1}" = "1" && SOLTEST_ARGS+=(--abiencoderv1) + (( EOF_VERSION != 0 )) && SOLTEST_ARGS+=(--eof-version "$EOF_VERSION") BATCH_ARGS=("--batches" "$((CPUs * CIRCLE_NODE_TOTAL))" "--selected-batch" "$((CPUs * CIRCLE_NODE_INDEX + run))") diff --git a/.circleci/soltest_all.sh b/.circleci/soltest_all.sh index 86c14901b22c..1c7882448ca1 100755 --- a/.circleci/soltest_all.sh +++ b/.circleci/soltest_all.sh @@ -32,12 +32,15 @@ REPODIR="$(realpath "$(dirname "$0")"/..)" source "${REPODIR}/scripts/common.sh" DEFAULT_EVM_VALUES=(constantinople petersburg istanbul berlin london paris shanghai cancun prague) +EVMS_WITH_EOF=(prague) + # Deserialize the EVM_VALUES array if it was provided as argument or # set EVM_VALUES to the default values. IFS=" " read -ra EVM_VALUES <<< "${1:-${DEFAULT_EVM_VALUES[@]}}" DEFAULT_EVM=cancun OPTIMIZE_VALUES=(0 1) +EOF_VERSIONS=(0 1) # Run for ABI encoder v1, without SMTChecker tests. EVM="${DEFAULT_EVM}" \ @@ -53,19 +56,27 @@ for OPTIMIZE in "${OPTIMIZE_VALUES[@]}" do for EVM in "${EVM_VALUES[@]}" do - ENFORCE_GAS_ARGS="" - [ "${EVM}" = "${DEFAULT_EVM}" ] && ENFORCE_GAS_ARGS="--enforce-gas-cost" - # Run SMTChecker tests only when OPTIMIZE == 0 - DISABLE_SMTCHECKER="" - [ "${OPTIMIZE}" != "0" ] && DISABLE_SMTCHECKER="-t !smtCheckerTests" + for EOF_VERSION in "${EOF_VERSIONS[@]}" + do + if (( EOF_VERSION > 0 )) && [[ ! " ${EVMS_WITH_EOF[*]} " == *" $EVM "* ]]; then + continue + fi + + ENFORCE_GAS_ARGS="" + [ "${EVM}" = "${DEFAULT_EVM}" ] && ENFORCE_GAS_ARGS="--enforce-gas-cost" + # Run SMTChecker tests only when OPTIMIZE == 0 + DISABLE_SMTCHECKER="" + [ "${OPTIMIZE}" != "0" ] && DISABLE_SMTCHECKER="-t !smtCheckerTests" - EVM="$EVM" \ - OPTIMIZE="$OPTIMIZE" \ - SOLTEST_FLAGS="$SOLTEST_FLAGS $ENFORCE_GAS_ARGS" \ - BOOST_TEST_ARGS="-t !@nooptions $DISABLE_SMTCHECKER" \ - INDEX_SHIFT="$INDEX_SHIFT" \ - "${REPODIR}/.circleci/soltest.sh" + EVM="$EVM" \ + EOF_VERSION="$EOF_VERSION" \ + OPTIMIZE="$OPTIMIZE" \ + SOLTEST_FLAGS="$SOLTEST_FLAGS $ENFORCE_GAS_ARGS" \ + BOOST_TEST_ARGS="-t !@nooptions $DISABLE_SMTCHECKER" \ + INDEX_SHIFT="$INDEX_SHIFT" \ + "${REPODIR}/.circleci/soltest.sh" - INDEX_SHIFT=$((INDEX_SHIFT + 1)) + INDEX_SHIFT=$((INDEX_SHIFT + 1)) + done done done From e6b0856e1ce910c6477db76e0c3cdd2cae820c63 Mon Sep 17 00:00:00 2001 From: rodiazet Date: Wed, 30 Oct 2024 10:20:56 +0100 Subject: [PATCH 0547/1022] Pass object name to `AsmAnalyzer` --- libyul/AsmAnalysis.cpp | 23 +++++++-- libyul/AsmAnalysis.h | 11 +++-- libyul/CompilabilityChecker.cpp | 2 +- libyul/Object.cpp | 49 +++++++++++++++---- libyul/Object.h | 24 ++++++++- libyul/YulStack.cpp | 2 +- libyul/optimiser/StackCompressor.cpp | 6 ++- libyul/optimiser/StackLimitEvader.cpp | 6 ++- test/libyul/Common.cpp | 2 +- .../yulSyntaxTests/eof/object_name_in_eof.yul | 9 ++++ 10 files changed, 111 insertions(+), 23 deletions(-) create mode 100644 test/libyul/yulSyntaxTests/eof/object_name_in_eof.yul diff --git a/libyul/AsmAnalysis.cpp b/libyul/AsmAnalysis.cpp index 84eb39daa834..a234fdb813d1 100644 --- a/libyul/AsmAnalysis.cpp +++ b/libyul/AsmAnalysis.cpp @@ -68,6 +68,8 @@ bool AsmAnalyzer::analyze(Block const& _block) auto watcher = m_errorReporter.errorWatcher(); try { + // FIXME: Pass location of the object name. Now it's a location of first code section in yul + validateObjectStructure(nativeLocationOf(_block)); if (!(ScopeFiller(m_info, m_errorReporter))(_block)) return false; @@ -86,13 +88,13 @@ bool AsmAnalyzer::analyze(Block const& _block) AsmAnalysisInfo AsmAnalyzer::analyzeStrictAssertCorrect(Dialect const& _dialect, Object const& _object) { - return analyzeStrictAssertCorrect(_dialect, _object.code()->root(), _object.qualifiedDataNames()); + return analyzeStrictAssertCorrect(_dialect, _object.code()->root(), _object.summarizeStructure()); } AsmAnalysisInfo AsmAnalyzer::analyzeStrictAssertCorrect( Dialect const& _dialect, Block const& _astRoot, - std::set const& _qualifiedDataNames + Object::Structure const _objectStructure ) { ErrorList errorList; @@ -103,7 +105,7 @@ AsmAnalysisInfo AsmAnalyzer::analyzeStrictAssertCorrect( errors, _dialect, {}, - _qualifiedDataNames + std::move(_objectStructure) ).analyze(_astRoot); yulAssert(success && !errors.hasErrors(), "Invalid assembly/yul code."); return analysisInfo; @@ -408,7 +410,7 @@ size_t AsmAnalyzer::operator()(FunctionCall const& _funCall) if (functionName == "datasize" || functionName == "dataoffset") { auto const& argumentAsLiteral = std::get(arg); - if (!m_dataNames.count(formatLiteral(argumentAsLiteral))) + if (!m_objectStructure.contains(formatLiteral(argumentAsLiteral))) m_errorReporter.typeError( 3517_error, nativeLocationOf(arg), @@ -766,3 +768,16 @@ bool AsmAnalyzer::validateInstructions(FunctionCall const& _functionCall) { return validateInstructions(_functionCall.functionName.name.str(), nativeLocationOf(_functionCall.functionName)); } + +void AsmAnalyzer::validateObjectStructure(langutil::SourceLocation _astRootLocation) +{ + if (m_eofVersion.has_value() && util::contains(m_objectStructure.objectName, '.')) // No dots in object name for EOF + m_errorReporter.syntaxError( + 9822_error, + _astRootLocation, + fmt::format( + "The object name \"{objectName}\" is invalid in EOF context. Object names must not contain 'dot' character.", + fmt::arg("objectName", m_objectStructure.objectName) + ) + ); +} diff --git a/libyul/AsmAnalysis.h b/libyul/AsmAnalysis.h index d8a2b2b1ac5f..7673e375ad20 100644 --- a/libyul/AsmAnalysis.h +++ b/libyul/AsmAnalysis.h @@ -30,6 +30,7 @@ #include #include +#include #include #include @@ -61,13 +62,13 @@ class AsmAnalyzer langutil::ErrorReporter& _errorReporter, Dialect const& _dialect, ExternalIdentifierAccess::Resolver _resolver = ExternalIdentifierAccess::Resolver(), - std::set _dataNames = {} + Object::Structure const _objectStructure = {} ): m_resolver(std::move(_resolver)), m_info(_analysisInfo), m_errorReporter(_errorReporter), m_dialect(_dialect), - m_dataNames(std::move(_dataNames)) + m_objectStructure(std::move(_objectStructure)) { if (EVMDialect const* evmDialect = dynamic_cast(&m_dialect)) { @@ -84,7 +85,7 @@ class AsmAnalyzer static AsmAnalysisInfo analyzeStrictAssertCorrect( Dialect const& _dialect, Block const& _astRoot, - std::set const& _qualifiedDataNames + Object::Structure const _objectStructure ); size_t operator()(Literal const& _literal); @@ -120,6 +121,8 @@ class AsmAnalyzer bool validateInstructions(std::string const& _instrIdentifier, langutil::SourceLocation const& _location); bool validateInstructions(FunctionCall const& _functionCall); + void validateObjectStructure(langutil::SourceLocation _astRootLocation); + yul::ExternalIdentifierAccess::Resolver m_resolver; Scope* m_currentScope = nullptr; /// Variables that are active at the current point in assembly (as opposed to @@ -131,7 +134,7 @@ class AsmAnalyzer std::optional m_eofVersion; Dialect const& m_dialect; /// Names of data objects to be referenced by builtin functions with literal arguments. - std::set m_dataNames; + Object::Structure m_objectStructure; ForLoop const* m_currentForLoop = nullptr; /// Worst side effects encountered during analysis (including within defined functions). SideEffects m_sideEffects; diff --git a/libyul/CompilabilityChecker.cpp b/libyul/CompilabilityChecker.cpp index 8ece236bf425..9cc6bd864320 100644 --- a/libyul/CompilabilityChecker.cpp +++ b/libyul/CompilabilityChecker.cpp @@ -44,7 +44,7 @@ CompilabilityChecker::CompilabilityChecker( yul::AsmAnalysisInfo analysisInfo = yul::AsmAnalyzer::analyzeStrictAssertCorrect( noOutputDialect, _object.code()->root(), - _object.qualifiedDataNames() + _object.summarizeStructure() ); BuiltinContext builtinContext; diff --git a/libyul/Object.cpp b/libyul/Object.cpp index c6ba5311ad5c..4b8119ffa5b4 100644 --- a/libyul/Object.cpp +++ b/libyul/Object.cpp @@ -110,29 +110,60 @@ Json Object::toJson() const return ret; } -std::set Object::qualifiedDataNames() const + +std::set Object::Structure::topLevelSubObjectNames() const +{ + std::set topLevelObjectNames; + + for (auto const& path: objectPaths) + if (!util::contains(path, '.') && path != objectName) + topLevelObjectNames.insert(path); + + return topLevelObjectNames; +} + +Object::Structure Object::summarizeStructure() const { - std::set qualifiedNames = + Structure structure; + + structure.objectPaths = name.empty() || util::contains(name, '.') ? std::set{} : std::set{name}; + + structure.objectName = name; + for (std::shared_ptr const& subObjectNode: subObjects) { - yulAssert(qualifiedNames.count(subObjectNode->name) == 0, ""); + yulAssert(!structure.contains(subObjectNode->name)); if (util::contains(subObjectNode->name, '.')) continue; - qualifiedNames.insert(subObjectNode->name); + if (auto const* subObject = dynamic_cast(subObjectNode.get())) - for (auto const& subSubObj: subObject->qualifiedDataNames()) + { + structure.objectPaths.insert(subObjectNode->name); + + auto const subObjectStructure = subObject->summarizeStructure(); + + for (auto const& subSubObj: subObjectStructure.objectPaths) if (subObject->name != subSubObj) { - yulAssert(qualifiedNames.count(subObject->name + "." + subSubObj) == 0, ""); - qualifiedNames.insert(subObject->name + "." + subSubObj); + yulAssert(!structure.contains(subObject->name + "." + subSubObj)); + structure.objectPaths.insert(subObject->name + "." + subSubObj); + } + for (auto const& subSubObjData: subObjectStructure.dataPaths) + if (subObject->name != subSubObjData) + { + yulAssert(!structure.contains(subObject->name + "." + subSubObjData)); + structure.dataPaths.insert(subObject->name + "." + subSubObjData); } + } + else + structure.dataPaths.insert(subObjectNode->name); } - yulAssert(qualifiedNames.count("") == 0, ""); - return qualifiedNames; + yulAssert(!structure.contains("")); + return structure; } std::vector Object::pathToSubObject(std::string_view _qualifiedName) const diff --git a/libyul/Object.h b/libyul/Object.h index 230f97866e09..3a89db4bcc23 100644 --- a/libyul/Object.h +++ b/libyul/Object.h @@ -98,10 +98,32 @@ struct Object: public ObjectNode ) const override; /// @returns a compact JSON representation of the AST. Json toJson() const override; + + /// Summarizes the structure of the subtree rooted at a given object, + /// in particular the paths that can be used from within to refer to nested nodes (objects and data). + struct Structure + { + /// The name of the object + std::string objectName; + /// Available dot-separated paths to nested objects (relative to current object). + std::set objectPaths; + /// Available dot-separated paths to nested data entries (relative to current object). + std::set dataPaths; + + /// Checks if a path is available. + bool contains(std::string const& _path) const { return containsObject(_path) || containsData(_path); } + /// Checks if a path is available and leads to an object. + bool containsObject(std::string const& _path) const { return objectPaths.count(_path) > 0; } + /// Checks if a path is available and leads to a data entry. + bool containsData(std::string const& _path) const { return dataPaths.count(_path) > 0; } + + std::set topLevelSubObjectNames() const; + }; + /// @returns the set of names of data objects accessible from within the code of /// this object, including the name of object itself /// Handles all names containing dots as reserved identifiers, not accessible as data. - std::set qualifiedDataNames() const; + Structure summarizeStructure() const; /// @returns vector of subIDs if possible to reach subobject with @a _qualifiedName, throws otherwise /// For "B.C" should return vector of two values if success (subId of B and subId of C in B). diff --git a/libyul/YulStack.cpp b/libyul/YulStack.cpp index 8b559e23f46d..877e447c78db 100644 --- a/libyul/YulStack.cpp +++ b/libyul/YulStack.cpp @@ -166,7 +166,7 @@ bool YulStack::analyzeParsed(Object& _object) m_errorReporter, languageToDialect(m_language, m_evmVersion, m_eofVersion), {}, - _object.qualifiedDataNames() + _object.summarizeStructure() ); bool success = false; diff --git a/libyul/optimiser/StackCompressor.cpp b/libyul/optimiser/StackCompressor.cpp index 2c2ef4272904..6ad3899e96c5 100644 --- a/libyul/optimiser/StackCompressor.cpp +++ b/libyul/optimiser/StackCompressor.cpp @@ -257,7 +257,11 @@ std::tuple StackCompressor::run( Block astRoot = std::get(ASTCopier{}(_object.code()->root())); if (usesOptimizedCodeGenerator) { - yul::AsmAnalysisInfo analysisInfo = yul::AsmAnalyzer::analyzeStrictAssertCorrect(_dialect, astRoot, _object.qualifiedDataNames()); + yul::AsmAnalysisInfo analysisInfo = yul::AsmAnalyzer::analyzeStrictAssertCorrect( + _dialect, + astRoot, + _object.summarizeStructure() + ); std::unique_ptr cfg = ControlFlowGraphBuilder::build(analysisInfo, _dialect, astRoot); eliminateVariablesOptimizedCodegen( _dialect, diff --git a/libyul/optimiser/StackLimitEvader.cpp b/libyul/optimiser/StackLimitEvader.cpp index d3cb6418fd30..6ef4b267b67e 100644 --- a/libyul/optimiser/StackLimitEvader.cpp +++ b/libyul/optimiser/StackLimitEvader.cpp @@ -132,7 +132,11 @@ Block StackLimitEvader::run( auto astRoot = std::get(ASTCopier{}(_object.code()->root())); if (evmDialect && evmDialect->evmVersion().canOverchargeGasForCall()) { - yul::AsmAnalysisInfo analysisInfo = yul::AsmAnalyzer::analyzeStrictAssertCorrect(*evmDialect, astRoot, _object.qualifiedDataNames()); + yul::AsmAnalysisInfo analysisInfo = yul::AsmAnalyzer::analyzeStrictAssertCorrect( + *evmDialect, + astRoot, + _object.summarizeStructure() + ); std::unique_ptr cfg = ControlFlowGraphBuilder::build(analysisInfo, *evmDialect, astRoot); run(_context, astRoot, StackLayoutGenerator::reportStackTooDeep(*cfg)); } diff --git a/test/libyul/Common.cpp b/test/libyul/Common.cpp index 6562e1743588..41b856edd2f0 100644 --- a/test/libyul/Common.cpp +++ b/test/libyul/Common.cpp @@ -84,7 +84,7 @@ std::pair, std::shared_ptr> yul::t if (!parserResult->hasCode() || errorReporter.hasErrors()) return {}; std::shared_ptr analysisInfo = std::make_shared(); - AsmAnalyzer analyzer(*analysisInfo, errorReporter, _dialect, {}, parserResult->qualifiedDataNames()); + AsmAnalyzer analyzer(*analysisInfo, errorReporter, _dialect, {}, parserResult->summarizeStructure()); // TODO this should be done recursively. if (!analyzer.analyze(parserResult->code()->root()) || errorReporter.hasErrors()) return {}; diff --git a/test/libyul/yulSyntaxTests/eof/object_name_in_eof.yul b/test/libyul/yulSyntaxTests/eof/object_name_in_eof.yul new file mode 100644 index 000000000000..bcbbca624cef --- /dev/null +++ b/test/libyul/yulSyntaxTests/eof/object_name_in_eof.yul @@ -0,0 +1,9 @@ +object "a.b" { + code {} +} + +// ==== +// EVMVersion: >=shanghai +// bytecodeFormat: >=EOFv1 +// ---- +// SyntaxError 9822: (24-26): The object name "a.b" is invalid in EOF context. Object names must not contain 'dot' character. From 974c11229c14edea3d94f1d7ef7af27cc8d6a2a1 Mon Sep 17 00:00:00 2001 From: rodiazet Date: Wed, 30 Oct 2024 11:13:17 +0100 Subject: [PATCH 0548/1022] eof: Support EOF contract creation. --- libevmasm/Assembly.cpp | 30 ++++- libevmasm/Assembly.h | 11 ++ libevmasm/AssemblyItem.cpp | 20 +++- libevmasm/AssemblyItem.h | 33 +++++- libevmasm/Instruction.cpp | 4 + libevmasm/Instruction.h | 2 + libevmasm/SemanticInformation.cpp | 50 +++++++- liblangutil/EVMVersion.cpp | 2 + .../codegen/ir/IRGenerationContext.cpp | 47 ++++++++ libsolidity/codegen/ir/IRGenerationContext.h | 10 ++ libsolidity/codegen/ir/IRGenerator.cpp | 109 +++++++++++++----- libsolidity/codegen/ir/IRGenerator.h | 1 + .../codegen/ir/IRGeneratorForStatements.cpp | 37 ++++-- .../experimental/codegen/IRGenerator.cpp | 1 + libyul/AsmAnalysis.cpp | 29 +++++ libyul/backends/evm/AbstractAssembly.h | 5 + libyul/backends/evm/EVMDialect.cpp | 56 ++++++++- libyul/backends/evm/EthAssemblyAdapter.cpp | 10 ++ libyul/backends/evm/EthAssemblyAdapter.h | 2 + libyul/backends/evm/NoOutputAssembly.cpp | 10 ++ libyul/backends/evm/NoOutputAssembly.h | 2 + .../debug_info_in_yul_snippet_escaping/output | 1 + .../standard_viair_requested/output.json | 1 + .../strict_asm_eof_container_prague/input.yul | 27 ++--- .../strict_asm_eof_container_prague/output | 87 +++++++------- .../eof/creation_with_immutables.yul | 100 ++++++++++++++++ test/libyul/yulSyntaxTests/eof/eofcreate.yul | 13 +++ .../eof/eofcreate_invalid_object.yul | 11 ++ .../eofcreate_invalid_object_name_data.yul | 13 +++ .../eofcreate_invalid_object_name_path.yul | 18 +++ .../yulSyntaxTests/eof/returncontract.yul | 12 ++ .../eof/returncontract_invalid_object.yul | 10 ++ .../EVMInstructionInterpreter.cpp | 4 +- 33 files changed, 661 insertions(+), 107 deletions(-) create mode 100644 test/libyul/objectCompiler/eof/creation_with_immutables.yul create mode 100644 test/libyul/yulSyntaxTests/eof/eofcreate.yul create mode 100644 test/libyul/yulSyntaxTests/eof/eofcreate_invalid_object.yul create mode 100644 test/libyul/yulSyntaxTests/eof/eofcreate_invalid_object_name_data.yul create mode 100644 test/libyul/yulSyntaxTests/eof/eofcreate_invalid_object_name_path.yul create mode 100644 test/libyul/yulSyntaxTests/eof/returncontract.yul create mode 100644 test/libyul/yulSyntaxTests/eof/returncontract_invalid_object.yul diff --git a/libevmasm/Assembly.cpp b/libevmasm/Assembly.cpp index 8f645f6fddcb..153ab547e9a8 100644 --- a/libevmasm/Assembly.cpp +++ b/libevmasm/Assembly.cpp @@ -1335,10 +1335,14 @@ std::map Assembly::findReferencedContainers() const std::set referencedSubcontainersIds; solAssert(m_subs.size() <= 0x100); // According to EOF spec - // TODO: Implement properly when opcodes referring sub containers added. - for (uint16_t i = 0; i < m_subs.size(); ++i) - referencedSubcontainersIds.insert(static_cast(i)); - // END TODO + for (auto&& codeSection: m_codeSections) + for (AssemblyItem const& item: codeSection.items) + if (item.type() == EOFCreate || item.type() == ReturnContract) + { + solAssert(item.data() <= m_subs.size(), "Invalid subcontainer index."); + auto const containerId = static_cast(item.data()); + referencedSubcontainersIds.insert(containerId); + } std::map replacements; uint8_t nUnreferenced = 0; @@ -1405,7 +1409,11 @@ LinkerObject const& Assembly::assembleEOF() const switch (item.type()) { case Operation: - solAssert(item.instruction() != Instruction::DATALOADN); + solAssert( + item.instruction() != Instruction::DATALOADN && + item.instruction() != Instruction::RETURNCONTRACT && + item.instruction() != Instruction::EOFCREATE + ); solAssert(!(item.instruction() >= Instruction::PUSH0 && item.instruction() <= Instruction::PUSH32)); ret.bytecode += assembleOperation(item); break; @@ -1419,6 +1427,18 @@ LinkerObject const& Assembly::assembleEOF() const ret.linkReferences.insert(linkRef); break; } + case EOFCreate: + { + ret.bytecode.push_back(static_cast(Instruction::EOFCREATE)); + ret.bytecode.push_back(static_cast(item.data())); + break; + } + case ReturnContract: + { + ret.bytecode.push_back(static_cast(Instruction::RETURNCONTRACT)); + ret.bytecode.push_back(static_cast(item.data())); + break; + } case VerbatimBytecode: ret.bytecode += assembleVerbatimBytecode(item); break; diff --git a/libevmasm/Assembly.h b/libevmasm/Assembly.h index 9b15936d642f..daeea6e8cf0e 100644 --- a/libevmasm/Assembly.h +++ b/libevmasm/Assembly.h @@ -99,6 +99,17 @@ class Assembly append(AssemblyItem(std::move(_data), _arguments, _returnVariables)); } + AssemblyItem appendEOFCreate(ContainerID _containerId) + { + solAssert(_containerId < m_subs.size(), "EOF Create of undefined container."); + return append(AssemblyItem::eofCreate(_containerId)); + } + AssemblyItem appendReturnContract(ContainerID _containerId) + { + solAssert(_containerId < m_subs.size(), "Return undefined container ID."); + return append(AssemblyItem::returnContract(_containerId)); + } + AssemblyItem appendJump() { auto ret = append(newPushTag()); append(Instruction::JUMP); return ret; } AssemblyItem appendJumpI() { auto ret = append(newPushTag()); append(Instruction::JUMPI); return ret; } AssemblyItem appendJump(AssemblyItem const& _tag) { auto ret = append(_tag.pushTag()); append(Instruction::JUMP); return ret; } diff --git a/libevmasm/AssemblyItem.cpp b/libevmasm/AssemblyItem.cpp index 3ce6238bc8be..d26e01f8a7ab 100644 --- a/libevmasm/AssemblyItem.cpp +++ b/libevmasm/AssemblyItem.cpp @@ -74,6 +74,8 @@ std::pair AssemblyItem::nameAndData(langutil::EVMVersi switch (type()) { case Operation: + case EOFCreate: + case ReturnContract: return {instructionInfo(instruction(), _evmVersion).name, m_data != nullptr ? toStringInHex(*m_data) : ""}; case Push: return {"PUSH", toStringInHex(data())}; @@ -167,6 +169,10 @@ size_t AssemblyItem::bytesRequired(size_t _addressLength, langutil::EVMVersion _ return std::get<2>(*m_verbatimBytecode).size(); case AuxDataLoadN: return 1 + 2; + case EOFCreate: + return 2; + case ReturnContract: + return 2; case UndefinedItem: solAssert(false); } @@ -176,7 +182,7 @@ size_t AssemblyItem::bytesRequired(size_t _addressLength, langutil::EVMVersion _ size_t AssemblyItem::arguments() const { - if (type() == Operation) + if (hasInstruction()) // The latest EVMVersion is used here, since the InstructionInfo is assumed to be // the same across all EVM versions except for the instruction name. return static_cast(instructionInfo(instruction(), EVMVersion()).args); @@ -193,6 +199,8 @@ size_t AssemblyItem::returnValues() const switch (m_type) { case Operation: + case EOFCreate: + case ReturnContract: // The latest EVMVersion is used here, since the InstructionInfo is assumed to be // the same across all EVM versions except for the instruction name. return static_cast(instructionInfo(instruction(), EVMVersion()).ret); @@ -226,6 +234,8 @@ bool AssemblyItem::canBeFunctional() const switch (m_type) { case Operation: + case EOFCreate: + case ReturnContract: return !isDupInstruction(instruction()) && !isSwapInstruction(instruction()); case Push: case PushTag: @@ -344,6 +354,12 @@ std::string AssemblyItem::toAssemblyText(Assembly const& _assembly) const assertThrow(data() <= std::numeric_limits::max(), AssemblyException, "Invalid auxdataloadn argument."); text = "auxdataloadn{" + std::to_string(static_cast(data())) + "}"; break; + case EOFCreate: + text = "eofcreate{" + std::to_string(static_cast(data())) + "}"; + break; + case ReturnContract: + text = "returcontract{" + std::to_string(static_cast(data())) + "}"; + break; } if (m_jumpType == JumpType::IntoFunction || m_jumpType == JumpType::OutOfFunction) { @@ -362,6 +378,8 @@ std::ostream& solidity::evmasm::operator<<(std::ostream& _out, AssemblyItem cons switch (_item.type()) { case Operation: + case EOFCreate: + case ReturnContract: _out << " " << instructionInfo(_item.instruction(), EVMVersion()).name; if (_item.instruction() == Instruction::JUMP || _item.instruction() == Instruction::JUMPI) _out << "\t" << _item.getJumpTypeAsString(); diff --git a/libevmasm/AssemblyItem.h b/libevmasm/AssemblyItem.h index 226a126c368c..e51d07b16150 100644 --- a/libevmasm/AssemblyItem.h +++ b/libevmasm/AssemblyItem.h @@ -55,6 +55,8 @@ enum AssemblyItemType /// Loads 32 bytes from static auxiliary data of EOF data section. The offset does *not* have to be always from the beginning /// of the data EOF section. More details here: https://github.com/ipsilon/eof/blob/main/spec/eof.md#data-section-lifecycle AuxDataLoadN, + EOFCreate, ///< Creates new contract using subcontainer as initcode + ReturnContract, ///< Returns new container (with auxiliary data filled in) to be deployed VerbatimBytecode ///< Contains data that is inserted into the bytecode code section without modification. }; @@ -63,6 +65,7 @@ enum class Precision { Precise , Approximate }; class Assembly; class AssemblyItem; using AssemblyItems = std::vector; +using ContainerID = uint8_t; class AssemblyItem { @@ -85,6 +88,14 @@ class AssemblyItem else m_data = std::make_shared(std::move(_data)); } + + explicit AssemblyItem(AssemblyItemType _type, Instruction _instruction, u256 _data = 0, langutil::DebugData::ConstPtr _debugData = langutil::DebugData::create()): + m_type(_type), + m_instruction(_instruction), + m_data(std::make_shared(std::move(_data))), + m_debugData(std::move(_debugData)) + {} + explicit AssemblyItem(bytes _verbatimData, size_t _arguments, size_t _returnVariables): m_type(VerbatimBytecode), m_instruction{}, @@ -92,6 +103,15 @@ class AssemblyItem m_debugData{langutil::DebugData::create()} {} + static AssemblyItem eofCreate(ContainerID _containerID, langutil::DebugData::ConstPtr _debugData = langutil::DebugData::create()) + { + return AssemblyItem(EOFCreate, Instruction::EOFCREATE, _containerID, std::move(_debugData)); + } + static AssemblyItem returnContract(ContainerID _containerID, langutil::DebugData::ConstPtr _debugData = langutil::DebugData::create()) + { + return AssemblyItem(ReturnContract, Instruction::RETURNCONTRACT, _containerID, std::move(_debugData)); + } + AssemblyItem(AssemblyItem const&) = default; AssemblyItem(AssemblyItem&&) = default; AssemblyItem& operator=(AssemblyItem const&) = default; @@ -122,8 +142,17 @@ class AssemblyItem bytes const& verbatimData() const { assertThrow(m_type == VerbatimBytecode, util::Exception, ""); return std::get<2>(*m_verbatimBytecode); } - /// @returns the instruction of this item (only valid if type() == Operation) - Instruction instruction() const { assertThrow(m_type == Operation, util::Exception, ""); return m_instruction; } + /// @returns true if the item has m_instruction properly set. + bool hasInstruction() const + { + return m_type == Operation || m_type == EOFCreate || m_type == ReturnContract; + } + /// @returns the instruction of this item (only valid if type() == Operation || EOFCreate || ReturnContract) + Instruction instruction() const + { + solAssert(hasInstruction()); + return m_instruction; + } /// @returns true if the type and data of the items are equal. bool operator==(AssemblyItem const& _other) const diff --git a/libevmasm/Instruction.cpp b/libevmasm/Instruction.cpp index b9bb21227c29..5122fb01f604 100644 --- a/libevmasm/Instruction.cpp +++ b/libevmasm/Instruction.cpp @@ -169,6 +169,8 @@ std::map const solidity::evmasm::c_instructions = { "LOG3", Instruction::LOG3 }, { "LOG4", Instruction::LOG4 }, { "DATALOADN", Instruction::DATALOADN }, + { "EOFCREATE", Instruction::EOFCREATE }, + { "RETURNCONTRACT", Instruction::RETURNCONTRACT }, { "CREATE", Instruction::CREATE }, { "CALL", Instruction::CALL }, { "CALLCODE", Instruction::CALLCODE }, @@ -324,6 +326,8 @@ static std::map const c_instructionInfo = {Instruction::LOG2, {"LOG2", 0, 4, 0, true, Tier::Special}}, {Instruction::LOG3, {"LOG3", 0, 5, 0, true, Tier::Special}}, {Instruction::LOG4, {"LOG4", 0, 6, 0, true, Tier::Special}}, + {Instruction::EOFCREATE, {"EOFCREATE", 1, 4, 1, true, Tier::Special}}, + {Instruction::RETURNCONTRACT, {"RETURNCONTRACT", 1, 2, 0, true, Tier::Special}}, {Instruction::CREATE, {"CREATE", 0, 3, 1, true, Tier::Special}}, {Instruction::CALL, {"CALL", 0, 7, 1, true, Tier::Special}}, {Instruction::CALLCODE, {"CALLCODE", 0, 7, 1, true, Tier::Special}}, diff --git a/libevmasm/Instruction.h b/libevmasm/Instruction.h index 2ed773cc9e7b..d9e96c49ad48 100644 --- a/libevmasm/Instruction.h +++ b/libevmasm/Instruction.h @@ -183,6 +183,8 @@ enum class Instruction: uint8_t LOG4, ///< Makes a log entry; 4 topics. DATALOADN = 0xd1, ///< load data from EOF data section + EOFCREATE = 0xec, ///< create a new account with associated container code. + RETURNCONTRACT = 0xee, ///< return container to be deployed with axiliary data filled in. CREATE = 0xf0, ///< create a new account with associated code CALL, ///< message-call into an account CALLCODE, ///< message-call with another account's code only diff --git a/libevmasm/SemanticInformation.cpp b/libevmasm/SemanticInformation.cpp index 87d41f6c13a0..e909a7074dbb 100644 --- a/libevmasm/SemanticInformation.cpp +++ b/libevmasm/SemanticInformation.cpp @@ -184,6 +184,34 @@ std::vector SemanticInformation::readWriteOperat Operation{Location::TransientStorage, Effect::Read, {}, {}, {}}, Operation{Location::TransientStorage, Effect::Write, {}, {}, {}} }; + case Instruction::EOFCREATE: + return std::vector{ + Operation{ + Location::Memory, + Effect::Read, + 2, + 3, + {} + }, + Operation{Location::Storage, Effect::Read, {}, {}, {}}, + Operation{Location::Storage, Effect::Write, {}, {}, {}}, + Operation{Location::TransientStorage, Effect::Read, {}, {}, {}}, + Operation{Location::TransientStorage, Effect::Write, {}, {}, {}} + }; + case Instruction::RETURNCONTRACT: + return std::vector{ + Operation{ + Location::Memory, + Effect::Read, + 0, + 1, + {} + }, + Operation{Location::Storage, Effect::Read, {}, {}, {}}, + Operation{Location::Storage, Effect::Write, {}, {}, {}}, + Operation{Location::TransientStorage, Effect::Read, {}, {}, {}}, + Operation{Location::TransientStorage, Effect::Write, {}, {}, {}} + }; case Instruction::MSIZE: // This is just to satisfy the assert below. return std::vector{}; @@ -280,8 +308,9 @@ bool SemanticInformation::isJumpInstruction(AssemblyItem const& _item) bool SemanticInformation::altersControlFlow(AssemblyItem const& _item) { - if (_item.type() != evmasm::Operation) + if (!_item.hasInstruction()) return false; + switch (_item.instruction()) { // note that CALL, CALLCODE and CREATE do not really alter the control flow, because we @@ -293,6 +322,7 @@ bool SemanticInformation::altersControlFlow(AssemblyItem const& _item) case Instruction::STOP: case Instruction::INVALID: case Instruction::REVERT: + case Instruction::RETURNCONTRACT: return true; default: return false; @@ -301,7 +331,7 @@ bool SemanticInformation::altersControlFlow(AssemblyItem const& _item) bool SemanticInformation::terminatesControlFlow(AssemblyItem const& _item) { - if (_item.type() != evmasm::Operation) + if (!_item.hasInstruction()) return false; return terminatesControlFlow(_item.instruction()); } @@ -315,6 +345,7 @@ bool SemanticInformation::terminatesControlFlow(Instruction _instruction) case Instruction::STOP: case Instruction::INVALID: case Instruction::REVERT: + case Instruction::RETURNCONTRACT: return true; default: return false; @@ -337,7 +368,7 @@ bool SemanticInformation::isDeterministic(AssemblyItem const& _item) { assertThrow(_item.type() != VerbatimBytecode, AssemblyException, ""); - if (_item.type() != evmasm::Operation) + if (!_item.hasInstruction()) return true; switch (_item.instruction()) @@ -357,6 +388,7 @@ bool SemanticInformation::isDeterministic(AssemblyItem const& _item) case Instruction::EXTCODEHASH: case Instruction::RETURNDATACOPY: // depends on previous calls case Instruction::RETURNDATASIZE: + case Instruction::EOFCREATE: return false; default: return true; @@ -436,6 +468,8 @@ SemanticInformation::Effect SemanticInformation::memory(Instruction _instruction case Instruction::LOG2: case Instruction::LOG3: case Instruction::LOG4: + case Instruction::EOFCREATE: + case Instruction::RETURNCONTRACT: return SemanticInformation::Read; default: @@ -473,6 +507,8 @@ SemanticInformation::Effect SemanticInformation::storage(Instruction _instructio case Instruction::CREATE: case Instruction::CREATE2: case Instruction::SSTORE: + case Instruction::EOFCREATE: + case Instruction::RETURNCONTRACT: return SemanticInformation::Write; case Instruction::SLOAD: @@ -494,6 +530,8 @@ SemanticInformation::Effect SemanticInformation::transientStorage(Instruction _i case Instruction::CREATE: case Instruction::CREATE2: case Instruction::TSTORE: + case Instruction::EOFCREATE: + case Instruction::RETURNCONTRACT: return SemanticInformation::Write; case Instruction::TLOAD: @@ -514,6 +552,8 @@ SemanticInformation::Effect SemanticInformation::otherState(Instruction _instruc case Instruction::DELEGATECALL: case Instruction::CREATE: case Instruction::CREATE2: + case Instruction::EOFCREATE: + case Instruction::RETURNCONTRACT: case Instruction::SELFDESTRUCT: case Instruction::STATICCALL: // because it can affect returndatasize // Strictly speaking, log0, .., log4 writes to the state, but the EVM cannot read it, so they @@ -588,6 +628,10 @@ bool SemanticInformation::invalidInViewFunctions(Instruction _instruction) case Instruction::CALL: case Instruction::CALLCODE: case Instruction::DELEGATECALL: + // According to EOF spec https://eips.ethereum.org/EIPS/eip-7620#eofcreate + case Instruction::EOFCREATE: + // According to EOF spec https://eips.ethereum.org/EIPS/eip-7620#returncontract + case Instruction::RETURNCONTRACT: case Instruction::CREATE2: case Instruction::SELFDESTRUCT: return true; diff --git a/liblangutil/EVMVersion.cpp b/liblangutil/EVMVersion.cpp index bdd663c411ac..9041ae793492 100644 --- a/liblangutil/EVMVersion.cpp +++ b/liblangutil/EVMVersion.cpp @@ -77,6 +77,8 @@ bool EVMVersion::hasOpcode(Instruction _opcode, std::optional _eofVersi case Instruction::GAS: return !_eofVersion.has_value(); // Instructions below available only in EOF + case Instruction::EOFCREATE: + case Instruction::RETURNCONTRACT: case Instruction::DATALOADN: return _eofVersion.has_value(); default: diff --git a/libsolidity/codegen/ir/IRGenerationContext.cpp b/libsolidity/codegen/ir/IRGenerationContext.cpp index e087dc69a575..fd47fec10184 100644 --- a/libsolidity/codegen/ir/IRGenerationContext.cpp +++ b/libsolidity/codegen/ir/IRGenerationContext.cpp @@ -107,10 +107,57 @@ size_t IRGenerationContext::immutableMemoryOffset(VariableDeclaration const& _va return m_immutableVariables.at(&_variable); } +size_t IRGenerationContext::immutableMemoryOffsetRelative(VariableDeclaration const& _variable) const +{ + auto const absoluteOffset = immutableMemoryOffset(_variable); + solAssert(absoluteOffset >= CompilerUtils::generalPurposeMemoryStart); + return absoluteOffset - CompilerUtils::generalPurposeMemoryStart; +} + +size_t IRGenerationContext::reservedMemorySize() const +{ + solAssert(m_reservedMemory.has_value()); + return *m_reservedMemory; +} + +void IRGenerationContext::registerLibraryAddressImmutable() +{ + solAssert(m_reservedMemory.has_value(), "Reserved memory has already been reset."); + solAssert(!m_libraryAddressImmutableOffset.has_value()); + m_libraryAddressImmutableOffset = CompilerUtils::generalPurposeMemoryStart + *m_reservedMemory; + *m_reservedMemory += 32; +} + +size_t IRGenerationContext::libraryAddressImmutableOffset() const +{ + solAssert(m_libraryAddressImmutableOffset.has_value()); + return *m_libraryAddressImmutableOffset; +} + +size_t IRGenerationContext::libraryAddressImmutableOffsetRelative() const +{ + solAssert(m_libraryAddressImmutableOffset.has_value()); + solAssert(m_libraryAddressImmutableOffset >= CompilerUtils::generalPurposeMemoryStart); + return *m_libraryAddressImmutableOffset - CompilerUtils::generalPurposeMemoryStart; +} + size_t IRGenerationContext::reservedMemory() { solAssert(m_reservedMemory.has_value(), "Reserved memory was used before."); size_t reservedMemory = *m_reservedMemory; + + // We assume reserved memory contains only immutable variables. + // This memory is used i.e. by RETURNCONTRACT to create new EOF container with aux data. + size_t immutableVariablesSize = 0; + for (auto const* var: keys(m_immutableVariables)) + { + solUnimplementedAssert(var->type()->isValueType()); + solUnimplementedAssert(var->type()->sizeOnStack() == 1); + immutableVariablesSize += var->type()->sizeOnStack() * 32; + } + + solAssert(immutableVariablesSize == reservedMemory); + m_reservedMemory = std::nullopt; return reservedMemory; } diff --git a/libsolidity/codegen/ir/IRGenerationContext.h b/libsolidity/codegen/ir/IRGenerationContext.h index 2bf837697b47..01220e87b86d 100644 --- a/libsolidity/codegen/ir/IRGenerationContext.h +++ b/libsolidity/codegen/ir/IRGenerationContext.h @@ -58,6 +58,7 @@ class IRGenerationContext IRGenerationContext( langutil::EVMVersion _evmVersion, + std::optional _eofVersion, ExecutionContext _executionContext, RevertStrings _revertStrings, std::map _sourceIndices, @@ -65,6 +66,7 @@ class IRGenerationContext langutil::CharStreamProvider const* _soliditySourceProvider ): m_evmVersion(_evmVersion), + m_eofVersion(_eofVersion), m_executionContext(_executionContext), m_revertStrings(_revertStrings), m_sourceIndices(std::move(_sourceIndices)), @@ -99,13 +101,18 @@ class IRGenerationContext /// Registers an immutable variable of the contract. /// Should only be called at construction time. void registerImmutableVariable(VariableDeclaration const& _varDecl); + void registerLibraryAddressImmutable(); + size_t libraryAddressImmutableOffset() const; + size_t libraryAddressImmutableOffsetRelative() const; /// @returns the reserved memory for storing the value of the /// immutable @a _variable during contract creation. size_t immutableMemoryOffset(VariableDeclaration const& _variable) const; + size_t immutableMemoryOffsetRelative(VariableDeclaration const& _variable) const; /// @returns the reserved memory and resets it to mark it as used. /// Intended to be used only once for initializing the free memory pointer /// to after the area used for immutables. size_t reservedMemory(); + size_t reservedMemorySize() const; void addStateVariable(VariableDeclaration const& _varDecl, u256 _storageOffset, unsigned _byteOffset); bool isStateVariable(VariableDeclaration const& _varDecl) const { return m_stateVariables.count(&_varDecl); } @@ -134,6 +141,7 @@ class IRGenerationContext YulUtilFunctions utils(); langutil::EVMVersion evmVersion() const { return m_evmVersion; } + std::optional eofVersion() const { return m_eofVersion; } ExecutionContext executionContext() const { return m_executionContext; } void setArithmetic(Arithmetic _value) { m_arithmetic = _value; } @@ -160,6 +168,7 @@ class IRGenerationContext private: langutil::EVMVersion m_evmVersion; + std::optional m_eofVersion; ExecutionContext m_executionContext; RevertStrings m_revertStrings; std::map m_sourceIndices; @@ -169,6 +178,7 @@ class IRGenerationContext /// Memory offsets reserved for the values of immutable variables during contract creation. /// This map is empty in the runtime context. std::map m_immutableVariables; + std::optional m_libraryAddressImmutableOffset; /// Total amount of reserved memory. Reserved memory is used to store /// immutable variables during contract creation. std::optional m_reservedMemory = {0}; diff --git a/libsolidity/codegen/ir/IRGenerator.cpp b/libsolidity/codegen/ir/IRGenerator.cpp index 44fc5a935a86..48b646d3536c 100644 --- a/libsolidity/codegen/ir/IRGenerator.cpp +++ b/libsolidity/codegen/ir/IRGenerator.cpp @@ -141,7 +141,11 @@ std::string IRGenerator::generate( - let called_via_delegatecall := iszero(eq(loadimmutable(""), address())) + + let called_via_delegatecall := iszero(eq(auxdataloadn(), address())) + + let called_via_delegatecall := iszero(eq(loadimmutable(""), address())) + @@ -154,6 +158,9 @@ std::string IRGenerator::generate( )"); resetContext(_contract, ExecutionContext::Creation); + auto const eof = m_context.eofVersion().has_value(); + if (eof && _contract.isLibrary()) + m_context.registerLibraryAddressImmutable(); for (VariableDeclaration const* var: ContractType(_contract).immutableVariables()) m_context.registerImmutableVariable(*var); @@ -200,7 +207,15 @@ std::string IRGenerator::generate( // Do not register immutables to avoid assignment. t("DeployedObject", IRNames::deployedObject(_contract)); t("sourceLocationCommentDeployed", dispenseLocationComment(_contract)); - t("library_address", IRNames::libraryAddressImmutable()); + t("eof", eof); + if (_contract.isLibrary()) + { + if (!eof) + t("library_address", IRNames::libraryAddressImmutable()); + else + t("library_address_immutable_offset", std::to_string(m_context.libraryAddressImmutableOffsetRelative())); + } + t("dispatch", dispatchRoutine(_contract)); std::set deployedFunctionList = generateQueuedFunctions(); generateInternalDispatchFunctions(_contract); @@ -532,27 +547,39 @@ std::string IRGenerator::generateGetter(VariableDeclaration const& _varDecl) { solAssert(paramTypes.empty(), ""); solUnimplementedAssert(type->sizeOnStack() == 1); - return Whiskers(R"( + + auto t = Whiskers(R"( function () -> rval { - rval := loadimmutable("") + + rval := auxdataloadn() + + rval := loadimmutable("") + } - )") - ( + )"); + t( "astIDComment", m_context.debugInfoSelection().astID ? "/// @ast-id " + std::to_string(_varDecl.id()) + "\n" : "" - ) - ("sourceLocationComment", dispenseLocationComment(_varDecl)) - ( + ); + t("sourceLocationComment", dispenseLocationComment(_varDecl)); + t( "contractSourceLocationComment", dispenseLocationComment(m_context.mostDerivedContract()) - ) - ("functionName", functionName) - ("id", std::to_string(_varDecl.id())) - .render(); + ); + t("functionName", functionName); + + auto const eof = m_context.eofVersion().has_value(); + t("eof", eof); + if (!eof) + t("id", std::to_string(_varDecl.id())); + else + t("immutableOffset", std::to_string(m_context.immutableMemoryOffsetRelative(_varDecl))); + + return t.render(); } else if (_varDecl.isConstant()) { @@ -940,13 +967,22 @@ void IRGenerator::generateConstructors(ContractDefinition const& _contract) std::string IRGenerator::deployCode(ContractDefinition const& _contract) { Whiskers t(R"X( - let := () - codecopy(, dataoffset(""), datasize("")) - <#immutables> - setimmutable(, "", ) - - return(, datasize("")) + + + mstore(, address()) + + returncontract("", , ) + + let := () + codecopy(, dataoffset(""), datasize("")) + <#immutables> + setimmutable(, "", ) + + return(, datasize("")) + )X"); + auto const eof = m_context.eofVersion().has_value(); + t("eof", eof); t("allocateUnbounded", m_utils.allocateUnboundedFunction()); t("codeOffset", m_context.newYulVariable()); t("object", IRNames::deployedObject(_contract)); @@ -955,23 +991,37 @@ std::string IRGenerator::deployCode(ContractDefinition const& _contract) if (_contract.isLibrary()) { solAssert(ContractType(_contract).immutableVariables().empty(), ""); - immutables.emplace_back(std::map{ - {"immutableName"s, IRNames::libraryAddressImmutable()}, - {"value"s, "address()"} - }); - + if (!eof) + immutables.emplace_back(std::map{ + {"immutableName"s, IRNames::libraryAddressImmutable()}, + {"value"s, "address()"} + }); + else + t("libraryAddressImmutableOffset", std::to_string(m_context.libraryAddressImmutableOffset())); } else + { for (VariableDeclaration const* immutable: ContractType(_contract).immutableVariables()) { solUnimplementedAssert(immutable->type()->isValueType()); solUnimplementedAssert(immutable->type()->sizeOnStack() == 1); - immutables.emplace_back(std::map{ - {"immutableName"s, std::to_string(immutable->id())}, - {"value"s, "mload(" + std::to_string(m_context.immutableMemoryOffset(*immutable)) + ")"} - }); + if (!eof) + immutables.emplace_back(std::map{ + {"immutableName"s, std::to_string(immutable->id())}, + {"value"s, "mload(" + std::to_string(m_context.immutableMemoryOffset(*immutable)) + ")"} + }); } - t("immutables", std::move(immutables)); + } + + if (eof) + { + t("auxDataStart", std::to_string(CompilerUtils::generalPurposeMemoryStart)); + solAssert(m_context.reservedMemorySize() <= 0xFFFF, "Reserved memory size exceeded maximum allowed EOF data section size."); + t("auxDataSize", std::to_string(m_context.reservedMemorySize())); + } + else + t("immutables", std::move(immutables)); + return t.render(); } @@ -1095,6 +1145,7 @@ void IRGenerator::resetContext(ContractDefinition const& _contract, ExecutionCon ); IRGenerationContext newContext( m_evmVersion, + m_eofVersion, _context, m_context.revertStrings(), m_context.sourceIndices(), diff --git a/libsolidity/codegen/ir/IRGenerator.h b/libsolidity/codegen/ir/IRGenerator.h index 9f01b74fc246..ed29a8bb3971 100644 --- a/libsolidity/codegen/ir/IRGenerator.h +++ b/libsolidity/codegen/ir/IRGenerator.h @@ -59,6 +59,7 @@ class IRGenerator m_eofVersion(_eofVersion), m_context( _evmVersion, + _eofVersion, ExecutionContext::Creation, _revertStrings, std::move(_sourceIndices), diff --git a/libsolidity/codegen/ir/IRGeneratorForStatements.cpp b/libsolidity/codegen/ir/IRGeneratorForStatements.cpp index 69d24cf42669..1304eca9a3e8 100644 --- a/libsolidity/codegen/ir/IRGeneratorForStatements.cpp +++ b/libsolidity/codegen/ir/IRGeneratorForStatements.cpp @@ -1563,22 +1563,30 @@ void IRGeneratorForStatements::endVisit(FunctionCall const& _functionCall) &dynamic_cast(*functionType->returnParameterTypes().front()).contractDefinition(); m_context.addSubObject(contract); - Whiskers t(R"(let := () - let := add(, datasize("")) - if or(gt(, 0xffffffffffffffff), lt(, )) { () } - datacopy(, dataoffset(""), datasize("")) - := () - - let
:= create2(, , sub(, ), ) - - let
:= create(, , sub(, )) - + Whiskers t(R"( + + let := () + let := () + let
:= eofcreate("", , , , sub(, )) + + let := () + let := add(, datasize("")) + if or(gt(, 0xffffffffffffffff), lt(, )) { () } + datacopy(, dataoffset(""), datasize("")) + := () + + let
:= create2(, , sub(, ), ) + + let
:= create(, , sub(, )) + + let := iszero(iszero(
)) if iszero(
) { () } )"); + t("eof", m_context.eofVersion().has_value()); t("memPos", m_context.newYulVariable()); t("memEnd", m_context.newYulVariable()); t("allocateUnbounded", m_utils.allocateUnboundedFunction()); @@ -1592,6 +1600,8 @@ void IRGeneratorForStatements::endVisit(FunctionCall const& _functionCall) t("saltSet", functionType->saltSet()); if (functionType->saltSet()) t("salt", IRVariable(_functionCall.expression()).part("salt").name()); + else if (m_context.eofVersion().has_value()) // Set salt to 0 if not defined. + t("salt", "0"); // TODO: We should reject non-salted creation during analysis and not set here solAssert(IRVariable(_functionCall).stackSlots().size() == 1); t("address", IRVariable(_functionCall).commaSeparatedList()); t("isTryCall", _functionCall.annotation().tryCall); @@ -3245,7 +3255,12 @@ IRVariable IRGeneratorForStatements::readFromLValue(IRLValue const& _lvalue) ")\n"; } else - define(result) << "loadimmutable(\"" << std::to_string(_immutable.variable->id()) << "\")\n"; + { + if (!m_context.eofVersion().has_value()) + define(result) << "loadimmutable(\"" << std::to_string(_immutable.variable->id()) << "\")\n"; + else + define(result) << "auxdataloadn(" << std::to_string(m_context.immutableMemoryOffsetRelative(*_immutable.variable)) << ")\n"; + } }, [&](IRLValue::Tuple const&) { solAssert(false, "Attempted to read from tuple lvalue."); diff --git a/libsolidity/experimental/codegen/IRGenerator.cpp b/libsolidity/experimental/codegen/IRGenerator.cpp index 60a93bbf01d9..457b28e37396 100644 --- a/libsolidity/experimental/codegen/IRGenerator.cpp +++ b/libsolidity/experimental/codegen/IRGenerator.cpp @@ -67,6 +67,7 @@ std::string IRGenerator::run( std::map const& /*_otherYulSources*/ ) { + solUnimplementedAssert(!m_eofVersion.has_value(), "Experimental IRGenerator not implemented for EOF"); Whiskers t(R"( object "" { diff --git a/libyul/AsmAnalysis.cpp b/libyul/AsmAnalysis.cpp index a234fdb813d1..8ed0b414211c 100644 --- a/libyul/AsmAnalysis.cpp +++ b/libyul/AsmAnalysis.cpp @@ -428,6 +428,35 @@ size_t AsmAnalyzer::operator()(FunctionCall const& _funCall) "The \"verbatim_*\" builtins cannot be used with empty bytecode." ); } + else if (functionName == "eofcreate" || functionName == "returncontract") + { + auto const& argumentAsLiteral = std::get(arg); + auto const formattedLiteral = formatLiteral(argumentAsLiteral); + + if (util::contains(formattedLiteral, '.')) + m_errorReporter.typeError( + 2186_error, + nativeLocationOf(arg), + "Name required but path given as \"" + functionName + "\" argument." + ); + + if (!m_objectStructure.topLevelSubObjectNames().count(formattedLiteral)) + { + if (m_objectStructure.containsData(formattedLiteral)) + m_errorReporter.typeError( + 7575_error, + nativeLocationOf(arg), + "Data name \"" + formattedLiteral + "\" cannot be used as an argument of eofcreate/returncontract. " + + "An object name is only acceptable." + ); + else + m_errorReporter.typeError( + 8970_error, + nativeLocationOf(arg), + "Unknown object \"" + formattedLiteral + "\"." + ); + } + } expectUnlimitedStringLiteral(std::get(arg)); continue; } diff --git a/libyul/backends/evm/AbstractAssembly.h b/libyul/backends/evm/AbstractAssembly.h index ed06bebac90b..7c44dfa78dc1 100644 --- a/libyul/backends/evm/AbstractAssembly.h +++ b/libyul/backends/evm/AbstractAssembly.h @@ -56,6 +56,7 @@ class AbstractAssembly public: using LabelID = size_t; using SubID = size_t; + using ContainerID = uint8_t; enum class JumpType { Ordinary, IntoFunction, OutOfFunction }; virtual ~AbstractAssembly() = default; @@ -118,6 +119,10 @@ class AbstractAssembly /// The function is meant to allow indexing into static_aux_data in a way that's independent of the size of pre_deploy_data. virtual void appendAuxDataLoadN(uint16_t _offset) = 0; + /// Appends EOF contract creation instruction which takes creation code from subcontainer with _containerID. + virtual void appendEOFCreate(ContainerID _containerID) = 0; + /// Appends EOF contract return instruction which returns a subcontainer ID (_containerID) with auxiliary data filled in. + virtual void appendReturnContract(ContainerID _containerID) = 0; /// Appends data to the very end of the bytecode. Repeated calls concatenate. /// EOF auxiliary data in data section and the auxiliary data are different things. virtual void appendToAuxiliaryData(bytes const& _data) = 0; diff --git a/libyul/backends/evm/EVMDialect.cpp b/libyul/backends/evm/EVMDialect.cpp index 27a1f1426d75..9de3e40fc598 100644 --- a/libyul/backends/evm/EVMDialect.cpp +++ b/libyul/backends/evm/EVMDialect.cpp @@ -207,6 +207,8 @@ std::vector> createBuiltins(langutil::EVMVe opcode != evmasm::Instruction::JUMPI && opcode != evmasm::Instruction::JUMPDEST && opcode != evmasm::Instruction::DATALOADN && + opcode != evmasm::Instruction::EOFCREATE && + opcode != evmasm::Instruction::RETURNCONTRACT && _evmVersion.hasOpcode(opcode, _eofVersion) && !prevRandaoException(name) ) @@ -370,7 +372,7 @@ std::vector> createBuiltins(langutil::EVMVe } )); } - else + else // EOF context { builtins.emplace_back(createFunction( "auxdataloadn", @@ -384,13 +386,61 @@ std::vector> createBuiltins(langutil::EVMVe AbstractAssembly& _assembly, BuiltinContext& ) { - yulAssert(_call.arguments.size() == 1, ""); + yulAssert(_call.arguments.size() == 1); Literal const* literal = std::get_if(&_call.arguments.front()); yulAssert(literal, ""); - yulAssert(literal->value.value() <= std::numeric_limits::max(), ""); + yulAssert(literal->value.value() <= std::numeric_limits::max()); _assembly.appendAuxDataLoadN(static_cast(literal->value.value())); } )); + + builtins.emplace_back(createFunction( + "eofcreate", + 5, + 1, + EVMDialect::sideEffectsOfInstruction(evmasm::Instruction::EOFCREATE), + ControlFlowSideEffects::fromInstruction(evmasm::Instruction::EOFCREATE), + {LiteralKind::String, std::nullopt, std::nullopt, std::nullopt, std::nullopt}, + []( + FunctionCall const& _call, + AbstractAssembly& _assembly, + BuiltinContext& context + ) { + yulAssert(_call.arguments.size() == 5); + Literal const* literal = std::get_if(&_call.arguments.front()); + auto const formattedLiteral = formatLiteral(*literal); + yulAssert(!util::contains(formattedLiteral, '.')); + auto const* containerID = valueOrNullptr(context.subIDs, formattedLiteral); + yulAssert(containerID != nullptr); + yulAssert(*containerID <= std::numeric_limits::max()); + _assembly.appendEOFCreate(static_cast(*containerID)); + } + )); + + if (_objectAccess) + builtins.emplace_back(createFunction( + "returncontract", + 3, + 0, + EVMDialect::sideEffectsOfInstruction(evmasm::Instruction::RETURNCONTRACT), + ControlFlowSideEffects::fromInstruction(evmasm::Instruction::RETURNCONTRACT), + {LiteralKind::String, std::nullopt, std::nullopt}, + []( + FunctionCall const& _call, + AbstractAssembly& _assembly, + BuiltinContext& context + ) { + yulAssert(_call.arguments.size() == 3); + Literal const* literal = std::get_if(&_call.arguments.front()); + yulAssert(literal); + auto const formattedLiteral = formatLiteral(*literal); + yulAssert(!util::contains(formattedLiteral, '.')); + auto const* containerID = valueOrNullptr(context.subIDs, formattedLiteral); + yulAssert(containerID != nullptr); + yulAssert(*containerID <= std::numeric_limits::max()); + _assembly.appendReturnContract(static_cast(*containerID)); + } + )); } yulAssert( ranges::all_of(builtins, [](std::optional const& _builtinFunction){ diff --git a/libyul/backends/evm/EthAssemblyAdapter.cpp b/libyul/backends/evm/EthAssemblyAdapter.cpp index 36a437c8cecf..604177c4f78a 100644 --- a/libyul/backends/evm/EthAssemblyAdapter.cpp +++ b/libyul/backends/evm/EthAssemblyAdapter.cpp @@ -128,6 +128,16 @@ std::pair, AbstractAssembly::SubID> EthAssembl return {std::make_shared(*assembly), static_cast(sub.data())}; } +void EthAssemblyAdapter::appendEOFCreate(ContainerID _containerID) +{ + m_assembly.appendEOFCreate(_containerID); +} + +void EthAssemblyAdapter::appendReturnContract(ContainerID _containerID) +{ + m_assembly.appendReturnContract(_containerID); +} + void EthAssemblyAdapter::appendDataOffset(std::vector const& _subPath) { if (auto it = m_dataHashBySubId.find(_subPath[0]); it != m_dataHashBySubId.end()) diff --git a/libyul/backends/evm/EthAssemblyAdapter.h b/libyul/backends/evm/EthAssemblyAdapter.h index 7dc89e38e0e9..d0bd3e14aff5 100644 --- a/libyul/backends/evm/EthAssemblyAdapter.h +++ b/libyul/backends/evm/EthAssemblyAdapter.h @@ -56,6 +56,8 @@ class EthAssemblyAdapter: public AbstractAssembly void appendJumpToIf(LabelID _labelId, JumpType _jumpType) override; void appendAssemblySize() override; std::pair, SubID> createSubAssembly(bool _creation, std::string _name = {}) override; + void appendEOFCreate(ContainerID _containerID) override; + void appendReturnContract(ContainerID _containerID) override; void appendDataOffset(std::vector const& _subPath) override; void appendDataSize(std::vector const& _subPath) override; SubID appendData(bytes const& _data) override; diff --git a/libyul/backends/evm/NoOutputAssembly.cpp b/libyul/backends/evm/NoOutputAssembly.cpp index 5e82cc6fd3a5..0497b11b63fb 100644 --- a/libyul/backends/evm/NoOutputAssembly.cpp +++ b/libyul/backends/evm/NoOutputAssembly.cpp @@ -151,6 +151,16 @@ void NoOutputAssembly::appendAuxDataLoadN(uint16_t) yulAssert(false, "auxdataloadn not implemented."); } +void NoOutputAssembly::appendEOFCreate(ContainerID) +{ + yulAssert(false, "eofcreate not implemented."); + +} +void NoOutputAssembly::appendReturnContract(ContainerID) +{ + yulAssert(false, "returncontract not implemented."); +} + NoOutputEVMDialect::NoOutputEVMDialect(EVMDialect const& _copyFrom): EVMDialect(_copyFrom.evmVersion(), _copyFrom.eofVersion(), _copyFrom.providesObjectAccess()) { diff --git a/libyul/backends/evm/NoOutputAssembly.h b/libyul/backends/evm/NoOutputAssembly.h index cc70d75afdae..5af1bd418026 100644 --- a/libyul/backends/evm/NoOutputAssembly.h +++ b/libyul/backends/evm/NoOutputAssembly.h @@ -76,6 +76,8 @@ class NoOutputAssembly: public AbstractAssembly void appendImmutableAssignment(std::string const& _identifier) override; void appendAuxDataLoadN(uint16_t) override; + void appendEOFCreate(ContainerID) override; + void appendReturnContract(ContainerID) override; void markAsInvalid() override {} diff --git a/test/cmdlineTests/debug_info_in_yul_snippet_escaping/output b/test/cmdlineTests/debug_info_in_yul_snippet_escaping/output index d5c02fc82151..975582f669ba 100644 --- a/test/cmdlineTests/debug_info_in_yul_snippet_escaping/output +++ b/test/cmdlineTests/debug_info_in_yul_snippet_escaping/output @@ -312,6 +312,7 @@ object "D_27" { var__5_mpos := zero_t_string_memory_ptr_1_mpos /// @src 0:446:491 "new /// @src 0:149:156 \"new C()\"..." + let _2 := allocate_unbounded() let _3 := add(_2, datasize("C_2")) if or(gt(_3, 0xffffffffffffffff), lt(_3, _2)) { panic_error_0x41() } diff --git a/test/cmdlineTests/standard_viair_requested/output.json b/test/cmdlineTests/standard_viair_requested/output.json index 0105ea97298a..133815b97dd7 100644 --- a/test/cmdlineTests/standard_viair_requested/output.json +++ b/test/cmdlineTests/standard_viair_requested/output.json @@ -201,6 +201,7 @@ object \"D_16\" { function fun_f_15() { /// @src 0:134:141 \"new C()\" + let _1 := allocate_unbounded() let _2 := add(_1, datasize(\"C_3\")) if or(gt(_2, 0xffffffffffffffff), lt(_2, _1)) { panic_error_0x41() } diff --git a/test/cmdlineTests/strict_asm_eof_container_prague/input.yul b/test/cmdlineTests/strict_asm_eof_container_prague/input.yul index 09306772c9a9..d4d9190ff68d 100644 --- a/test/cmdlineTests/strict_asm_eof_container_prague/input.yul +++ b/test/cmdlineTests/strict_asm_eof_container_prague/input.yul @@ -1,33 +1,34 @@ object "object" { code { - revert(0, 0) + mstore(0, eofcreate("sub0", 0, 0, 0, 0)) + mstore(32, eofcreate("sub1", 0, 0, 0, 0)) + return(0, 64) } object "sub0" { code { - mstore(0, 0) - revert(0, 32) + returncontract("sub00", 0, 0) } - } - object "sub1" { - code { - mstore(0, 1) - revert(0, 32) + object "sub00" { + code { + mstore(0, 1) + revert(0, 32) + } } } - object "sub2" { + + object "sub1" { code { - mstore(0, 2) - revert(0, 32) + returncontract("sub10", 0, 0) } - object "sub20" { + object "sub10" { code { mstore(0, 0x20) revert(0, 32) } } } - object "sub3" { + object "sub2" { code { mstore(0, 3) revert(0, 32) diff --git a/test/cmdlineTests/strict_asm_eof_container_prague/output b/test/cmdlineTests/strict_asm_eof_container_prague/output index 17f6df675585..26d37caf4625 100644 --- a/test/cmdlineTests/strict_asm_eof_container_prague/output +++ b/test/cmdlineTests/strict_asm_eof_container_prague/output @@ -3,31 +3,31 @@ Pretty printed source: object "object" { - code { { revert(0, 0) } } - object "sub0" { - code { - { - mstore(0, 0) - revert(0, 32) - } + code { + { + mstore(0, eofcreate("sub0", 0, 0, 0, 0)) + mstore(32, eofcreate("sub1", 0, 0, 0, 0)) + return(0, 64) } } - object "sub1" { + object "sub0" { code { - { - mstore(0, 1) - revert(0, 32) + { returncontract("sub00", 0, 0) } + } + object "sub00" { + code { + { + mstore(0, 1) + revert(0, 32) + } } } } - object "sub2" { + object "sub1" { code { - { - mstore(0, 2) - revert(0, 32) - } + { returncontract("sub10", 0, 0) } } - object "sub20" { + object "sub10" { code { { mstore(0, 0x20) @@ -36,7 +36,7 @@ object "object" { } } } - object "sub3" { + object "sub2" { code { { mstore(0, 3) @@ -48,39 +48,48 @@ object "object" { Binary representation: -ef00010100040200010003030004001a001b003b001b040000000080ffff5f80fdef00010100040200010007040000000080ffff5f805260205ffdef00010100040200010008040000000080ffff60015f5260205ffdef00010100040200010008030001001b040000000080ffff60025f5260205ffdef00010100040200010008040000000080ffff60205f5260205ffdef00010100040200010008040000000080ffff60035f5260205ffd +ef0001010004020001001503000200370037040000000080ffff5f808080ec005f525f808080ec0160205260405ff3ef00010100040200010004030001001b040000000080ffff5f80ee00ef00010100040200010008040000000080ffff60015f5260205ffdef00010100040200010004030001001b040000000080ffff5f80ee00ef00010100040200010008040000000080ffff60205f5260205ffd Text representation: 0x00 dup1 - revert + dup1 + dup1 + eofcreate{0} + 0x00 + mstore + 0x00 + dup1 + dup1 + dup1 + eofcreate{1} + 0x20 + mstore + 0x40 + 0x00 + return stop sub_0: assembly { 0x00 dup1 - mstore - 0x20 - 0x00 - revert -} + returcontract{0} + stop -sub_1: assembly { - 0x01 - 0x00 - mstore - 0x20 - 0x00 - revert + sub_0: assembly { + 0x01 + 0x00 + mstore + 0x20 + 0x00 + revert + } } -sub_2: assembly { - 0x02 - 0x00 - mstore - 0x20 +sub_1: assembly { 0x00 - revert + dup1 + returcontract{0} stop sub_0: assembly { @@ -93,7 +102,7 @@ sub_2: assembly { } } -sub_3: assembly { +sub_2: assembly { 0x03 0x00 mstore diff --git a/test/libyul/objectCompiler/eof/creation_with_immutables.yul b/test/libyul/objectCompiler/eof/creation_with_immutables.yul new file mode 100644 index 000000000000..63558294f120 --- /dev/null +++ b/test/libyul/objectCompiler/eof/creation_with_immutables.yul @@ -0,0 +1,100 @@ +object "a" { + code { + mstore(0, eofcreate("b", 0, 0, 0, 0)) + return(0, 32) + } + + object "b" { + code { + mstore(0, 0x1122334455667788990011223344556677889900112233445566778899001122) + mstore(32, 0x1122334455667788990011223344556677889900112233445566778899001122) + returncontract("c", 0, 64) + } + object "c" { + code { + let d0 := auxdataloadn(0) + let d1 := auxdataloadn(32) + + mstore(0, d0) + mstore(32, d1) + + return(0, 64) + } + } + } + + data "data1" hex"48656c6c6f2c20576f726c6421" +} + +// ==== +// EVMVersion: >=prague +// bytecodeFormat: >=EOFv1 +// ---- +// Assembly: +// /* "source":80:81 */ +// 0x00 +// /* "source":56:82 */ +// dup1 +// dup1 +// dup1 +// eofcreate{0} +// /* "source":53:54 */ +// 0x00 +// /* "source":46:83 */ +// mstore +// /* "source":106:108 */ +// 0x20 +// /* "source":103:104 */ +// 0x00 +// /* "source":96:109 */ +// return +// stop +// data_acaf3289d7b601cbd114fb36c4d29c85bbfd5e133f14cb355c3fd8d99367964f 48656c6c6f2c20576f726c6421 +// +// sub_0: assembly { +// /* "source":198:264 */ +// 0x1122334455667788990011223344556677889900112233445566778899001122 +// /* "source":195:196 */ +// 0x00 +// /* "source":188:265 */ +// mstore +// /* "source":293:359 */ +// 0x1122334455667788990011223344556677889900112233445566778899001122 +// /* "source":289:291 */ +// 0x20 +// /* "source":282:360 */ +// mstore +// /* "source":400:402 */ +// 0x40 +// /* "source":397:398 */ +// 0x00 +// /* "source":377:403 */ +// returcontract{0} +// stop +// +// sub_0: assembly { +// /* "source":516:531 */ +// auxdataloadn{0} +// /* "source":562:578 */ +// auxdataloadn{32} +// /* "source":599:612 */ +// swap1 +// /* "source":606:607 */ +// 0x00 +// /* "source":599:612 */ +// mstore +// /* "source":640:642 */ +// 0x20 +// /* "source":633:647 */ +// mstore +// /* "source":678:680 */ +// 0x40 +// /* "source":675:676 */ +// 0x00 +// /* "source":668:681 */ +// return +// } +// } +// Bytecode: ef0001010004020001000c030001008704000d000080ffff5f808080ec005f5260205ff3ef0001010004020001004c0300010023040000000080ffff7f11223344556677889900112233445566778899001122334455667788990011225f527f112233445566778899001122334455667788990011223344556677889900112260205260405fee00ef00010100040200010010040040000080ffffd10000d10020905f5260205260405ff348656c6c6f2c20576f726c6421 +// Opcodes: 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP 0xC SUB STOP ADD STOP DUP8 DIV STOP 0xD STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x0 PUSH0 MSTORE PUSH1 0x20 PUSH0 RETURN 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP 0x4C SUB STOP ADD STOP 0x23 DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT PUSH32 0x1122334455667788990011223344556677889900112233445566778899001122 PUSH0 MSTORE PUSH32 0x1122334455667788990011223344556677889900112233445566778899001122 PUSH1 0x20 MSTORE PUSH1 0x40 PUSH0 RETURNCONTRACT 0x0 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP LT DIV STOP BLOCKHASH STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT DATALOADN 0x0 DATALOADN 0x20 SWAP1 PUSH0 MSTORE PUSH1 0x20 MSTORE PUSH1 0x40 PUSH0 RETURN BASEFEE PUSH6 0x6C6C6F2C2057 PUSH16 0x726C6421000000000000000000000000 +// SourceMappings: 80:1:0:-:0;56:26;;;;53:1;46:37;106:2;103:1;96:13 diff --git a/test/libyul/yulSyntaxTests/eof/eofcreate.yul b/test/libyul/yulSyntaxTests/eof/eofcreate.yul new file mode 100644 index 000000000000..4169d52ab3b8 --- /dev/null +++ b/test/libyul/yulSyntaxTests/eof/eofcreate.yul @@ -0,0 +1,13 @@ +object "a" { + code { + let addr := eofcreate("b", 0, 0, 0, 0) + return(0, 0) + } + + object "b" { + code {} + } +} +// ==== +// EVMVersion: >=shanghai +// bytecodeFormat: >=EOFv1 diff --git a/test/libyul/yulSyntaxTests/eof/eofcreate_invalid_object.yul b/test/libyul/yulSyntaxTests/eof/eofcreate_invalid_object.yul new file mode 100644 index 000000000000..f3acc8277511 --- /dev/null +++ b/test/libyul/yulSyntaxTests/eof/eofcreate_invalid_object.yul @@ -0,0 +1,11 @@ +object "a" { + code { + mstore(0, eofcreate("b", 0, 0, 0, 0)) + return(0, 32) + } +} +// ==== +// EVMVersion: >=shanghai +// bytecodeFormat: >=EOFv1 +// ---- +// TypeError 8970: (52-55): Unknown object "b". diff --git a/test/libyul/yulSyntaxTests/eof/eofcreate_invalid_object_name_data.yul b/test/libyul/yulSyntaxTests/eof/eofcreate_invalid_object_name_data.yul new file mode 100644 index 000000000000..1e9fad7d0244 --- /dev/null +++ b/test/libyul/yulSyntaxTests/eof/eofcreate_invalid_object_name_data.yul @@ -0,0 +1,13 @@ +object "a" { + code { + mstore(0, eofcreate("data1", 0, 0, 0, 0)) + return(0, 32) + } + + data "data1" "Hello, World!" +} +// ==== +// EVMVersion: >=shanghai +// bytecodeFormat: >=EOFv1 +// ---- +// TypeError 7575: (52-59): Data name "data1" cannot be used as an argument of eofcreate/returncontract. An object name is only acceptable. diff --git a/test/libyul/yulSyntaxTests/eof/eofcreate_invalid_object_name_path.yul b/test/libyul/yulSyntaxTests/eof/eofcreate_invalid_object_name_path.yul new file mode 100644 index 000000000000..7efaada8bcd4 --- /dev/null +++ b/test/libyul/yulSyntaxTests/eof/eofcreate_invalid_object_name_path.yul @@ -0,0 +1,18 @@ +object "a" { + code { + mstore(0, eofcreate("a.b", 0, 0, 0, 0)) + mstore(0, eofcreate("a", 0, 0, 0, 0)) + return(0, 32) + } + + object "b" { + code {} + } +} +// ==== +// EVMVersion: >=shanghai +// bytecodeFormat: >=EOFv1 +// ---- +// TypeError 2186: (52-57): Name required but path given as "eofcreate" argument. +// TypeError 8970: (52-57): Unknown object "a.b". +// TypeError 8970: (100-103): Unknown object "a". diff --git a/test/libyul/yulSyntaxTests/eof/returncontract.yul b/test/libyul/yulSyntaxTests/eof/returncontract.yul new file mode 100644 index 000000000000..2d193a800d17 --- /dev/null +++ b/test/libyul/yulSyntaxTests/eof/returncontract.yul @@ -0,0 +1,12 @@ +object "b" { + code { + returncontract("c", 0, 0) + } + + object "c" { + code {} + } +} +// ==== +// EVMVersion: >=shanghai +// bytecodeFormat: >=EOFv1 diff --git a/test/libyul/yulSyntaxTests/eof/returncontract_invalid_object.yul b/test/libyul/yulSyntaxTests/eof/returncontract_invalid_object.yul new file mode 100644 index 000000000000..be345ff0a925 --- /dev/null +++ b/test/libyul/yulSyntaxTests/eof/returncontract_invalid_object.yul @@ -0,0 +1,10 @@ +object "a" { + code { + returncontract("b", 0, 0) + } +} +// ==== +// EVMVersion: >=shanghai +// bytecodeFormat: >=EOFv1 +// ---- +// TypeError 8970: (47-50): Unknown object "b". diff --git a/test/tools/yulInterpreter/EVMInstructionInterpreter.cpp b/test/tools/yulInterpreter/EVMInstructionInterpreter.cpp index b43021ea7a52..0f1f37451569 100644 --- a/test/tools/yulInterpreter/EVMInstructionInterpreter.cpp +++ b/test/tools/yulInterpreter/EVMInstructionInterpreter.cpp @@ -488,7 +488,9 @@ u256 EVMInstructionInterpreter::eval( case Instruction::SWAP16: yulAssert(false, "Impossible in strict assembly."); case Instruction::DATALOADN: - solUnimplemented("DATALOADN unimplemented in yul interpreter."); + case Instruction::EOFCREATE: + case Instruction::RETURNCONTRACT: + solUnimplemented("EOF not yet supported by Yul interpreter."); } util::unreachable(); From c66905a18999b5c4be2678a7829b6703f902e341 Mon Sep 17 00:00:00 2001 From: Daniel Kirchner Date: Tue, 8 Oct 2024 18:20:28 +0200 Subject: [PATCH 0549/1022] Avoid multiple lookups during body-copying while inlining. --- libyul/optimiser/FullInliner.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/libyul/optimiser/FullInliner.cpp b/libyul/optimiser/FullInliner.cpp index df18a687f477..328ef83b8e7b 100644 --- a/libyul/optimiser/FullInliner.cpp +++ b/libyul/optimiser/FullInliner.cpp @@ -363,8 +363,5 @@ Statement BodyCopier::operator()(FunctionDefinition const&) YulName BodyCopier::translateIdentifier(YulName _name) { - if (m_variableReplacements.count(_name)) - return m_variableReplacements.at(_name); - else - return _name; + return util::valueOrDefault(m_variableReplacements, _name, _name); } From fff9260306fe66e81ecd75c195181590db0bcb83 Mon Sep 17 00:00:00 2001 From: Daniel Kirchner Date: Thu, 15 Aug 2024 17:22:25 +0200 Subject: [PATCH 0550/1022] Remove special "m" and "s" strings from UnusedStoreEliminator. --- libyul/optimiser/UnusedAssignEliminator.h | 2 +- libyul/optimiser/UnusedStoreBase.cpp | 27 ++++++++++++++++------- libyul/optimiser/UnusedStoreBase.h | 6 ++++- libyul/optimiser/UnusedStoreEliminator.h | 8 +++---- 4 files changed, 28 insertions(+), 15 deletions(-) diff --git a/libyul/optimiser/UnusedAssignEliminator.h b/libyul/optimiser/UnusedAssignEliminator.h index 9c3b1e4bcabf..ea2116f0352a 100644 --- a/libyul/optimiser/UnusedAssignEliminator.h +++ b/libyul/optimiser/UnusedAssignEliminator.h @@ -113,7 +113,7 @@ struct Dialect; * * Prerequisite: Disambiguator, ForLoopInitRewriter. */ -class UnusedAssignEliminator: public UnusedStoreBase +class UnusedAssignEliminator: public UnusedStoreBase { public: static constexpr char const* name{"UnusedAssignEliminator"}; diff --git a/libyul/optimiser/UnusedStoreBase.cpp b/libyul/optimiser/UnusedStoreBase.cpp index 977db11c4c12..4159b875f39d 100644 --- a/libyul/optimiser/UnusedStoreBase.cpp +++ b/libyul/optimiser/UnusedStoreBase.cpp @@ -32,7 +32,8 @@ using namespace solidity; using namespace solidity::yul; -void UnusedStoreBase::operator()(If const& _if) +template +void UnusedStoreBase::operator()(If const& _if) { visit(*_if.condition); @@ -42,7 +43,8 @@ void UnusedStoreBase::operator()(If const& _if) merge(m_activeStores, std::move(skipBranch)); } -void UnusedStoreBase::operator()(Switch const& _switch) +template +void UnusedStoreBase::operator()(Switch const& _switch) { visit(*_switch.expression); @@ -68,7 +70,8 @@ void UnusedStoreBase::operator()(Switch const& _switch) merge(m_activeStores, std::move(branch)); } -void UnusedStoreBase::operator()(FunctionDefinition const& _functionDefinition) +template +void UnusedStoreBase::operator()(FunctionDefinition const& _functionDefinition) { ScopedSaveAndRestore allStores(m_allStores, {}); ScopedSaveAndRestore usedStores(m_usedStores, {}); @@ -82,7 +85,8 @@ void UnusedStoreBase::operator()(FunctionDefinition const& _functionDefinition) m_storesToRemove += m_allStores - m_usedStores; } -void UnusedStoreBase::operator()(ForLoop const& _forLoop) +template +void UnusedStoreBase::operator()(ForLoop const& _forLoop) { ScopedSaveAndRestore outerForLoopInfo(m_forLoopInfo, {}); ScopedSaveAndRestore forLoopNestingDepth(m_forLoopNestingDepth, m_forLoopNestingDepth + 1); @@ -130,19 +134,22 @@ void UnusedStoreBase::operator()(ForLoop const& _forLoop) m_forLoopInfo.pendingBreakStmts.clear(); } -void UnusedStoreBase::operator()(Break const&) +template +void UnusedStoreBase::operator()(Break const&) { m_forLoopInfo.pendingBreakStmts.emplace_back(std::move(m_activeStores)); m_activeStores.clear(); } -void UnusedStoreBase::operator()(Continue const&) +template +void UnusedStoreBase::operator()(Continue const&) { m_forLoopInfo.pendingContinueStmts.emplace_back(std::move(m_activeStores)); m_activeStores.clear(); } -void UnusedStoreBase::merge(ActiveStores& _target, ActiveStores&& _other) +template +void UnusedStoreBase::merge(ActiveStores& _target, ActiveStores&& _other) { util::joinMap(_target, std::move(_other), []( std::set& _storesHere, @@ -153,9 +160,13 @@ void UnusedStoreBase::merge(ActiveStores& _target, ActiveStores&& _other) }); } -void UnusedStoreBase::merge(ActiveStores& _target, std::vector&& _source) +template +void UnusedStoreBase::merge(ActiveStores& _target, std::vector&& _source) { for (ActiveStores& ts: _source) merge(_target, std::move(ts)); _source.clear(); } + +template class solidity::yul::UnusedStoreBase; +template class solidity::yul::UnusedStoreBase; diff --git a/libyul/optimiser/UnusedStoreBase.h b/libyul/optimiser/UnusedStoreBase.h index b6dde8c5511f..e5c11c491462 100644 --- a/libyul/optimiser/UnusedStoreBase.h +++ b/libyul/optimiser/UnusedStoreBase.h @@ -46,6 +46,7 @@ struct Dialect; * * Prerequisite: Disambiguator, ForLoopInitRewriter. */ +template class UnusedStoreBase: public ASTWalker { public: @@ -60,7 +61,7 @@ class UnusedStoreBase: public ASTWalker void operator()(Continue const&) override; protected: - using ActiveStores = std::map>; + using ActiveStores = std::map>; /// This function is called for a loop that is nested too deep to avoid /// horrible runtime and should just resolve the situation in a pragmatic @@ -98,4 +99,7 @@ class UnusedStoreBase: public ASTWalker size_t m_forLoopNestingDepth = 0; }; +enum class UnusedStoreEliminatorKey { Memory, Storage }; +extern template class UnusedStoreBase; +extern template class UnusedStoreBase; } diff --git a/libyul/optimiser/UnusedStoreEliminator.h b/libyul/optimiser/UnusedStoreEliminator.h index 98023b64cfc6..6f50636a77cb 100644 --- a/libyul/optimiser/UnusedStoreEliminator.h +++ b/libyul/optimiser/UnusedStoreEliminator.h @@ -50,13 +50,11 @@ struct AssignedValue; * to sstore, as we don't know whether the memory location will be read once we leave the function's scope, * so the statement will be removed only if all code code paths lead to a memory overwrite. * - * The m_store member of UnusedStoreBase uses the key "m" for memory and "s" for storage stores. - * * Best run in SSA form. * * Prerequisite: Disambiguator, ForLoopInitRewriter. */ -class UnusedStoreEliminator: public UnusedStoreBase +class UnusedStoreEliminator: public UnusedStoreBase { public: static constexpr char const* name{"UnusedStoreEliminator"}; @@ -92,8 +90,8 @@ class UnusedStoreEliminator: public UnusedStoreBase }; private: - std::set& activeMemoryStores() { return m_activeStores["m"_yulname]; } - std::set& activeStorageStores() { return m_activeStores["s"_yulname]; } + std::set& activeMemoryStores() { return m_activeStores[UnusedStoreEliminatorKey::Memory]; } + std::set& activeStorageStores() { return m_activeStores[UnusedStoreEliminatorKey::Storage]; } void shortcutNestedLoop(ActiveStores const&) override { From cbfe4a1f77fdf6301c53b205f7eac802fd0126c4 Mon Sep 17 00:00:00 2001 From: Daniel Kirchner Date: Thu, 15 Aug 2024 17:41:13 +0200 Subject: [PATCH 0551/1022] Replace special names for literals in UnusedStoreEliminator. --- libyul/optimiser/UnusedStoreEliminator.cpp | 38 ++++++++-------------- libyul/optimiser/UnusedStoreEliminator.h | 10 +++++- 2 files changed, 22 insertions(+), 26 deletions(-) diff --git a/libyul/optimiser/UnusedStoreEliminator.cpp b/libyul/optimiser/UnusedStoreEliminator.cpp index f4f056697638..7c68d577bb74 100644 --- a/libyul/optimiser/UnusedStoreEliminator.cpp +++ b/libyul/optimiser/UnusedStoreEliminator.cpp @@ -43,12 +43,6 @@ using namespace solidity; using namespace solidity::yul; -/// Variable names for special constants that can never appear in actual Yul code. -static std::string const zero{"@ 0"}; -static std::string const one{"@ 1"}; -static std::string const thirtyTwo{"@ 32"}; - - void UnusedStoreEliminator::run(OptimiserStepContext& _context, Block& _ast) { std::map functionSideEffects = SideEffectsPropagator::sideEffects( @@ -61,12 +55,6 @@ void UnusedStoreEliminator::run(OptimiserStepContext& _context, Block& _ast) std::map values; for (auto const& [name, expression]: ssaValues.values()) values[name] = AssignedValue{expression, {}}; - Expression const zeroLiteral{Literal{{}, LiteralKind::Number, LiteralValue(u256{0})}}; - Expression const oneLiteral{Literal{{}, LiteralKind::Number, LiteralValue(u256{1})}}; - Expression const thirtyTwoLiteral{Literal{{}, LiteralKind::Number, LiteralValue(u256{32})}}; - values[YulName{zero}] = AssignedValue{&zeroLiteral, {}}; - values[YulName{one}] = AssignedValue{&oneLiteral, {}}; - values[YulName{thirtyTwo}] = AssignedValue{&thirtyTwoLiteral, {}}; bool const ignoreMemory = MSizeFinder::containsMSize(_context.dialect, _ast); UnusedStoreEliminator rse{ @@ -263,8 +251,8 @@ std::vector UnusedStoreEliminator::operationsF if (_op.lengthConstant) switch (*_op.lengthConstant) { - case 1: ourOp.length = YulName(one); break; - case 32: ourOp.length = YulName(thirtyTwo); break; + case 1: ourOp.length = u256(1); break; + case 32: ourOp.length = u256(32); break; default: yulAssert(false); } return ourOp; @@ -312,8 +300,8 @@ bool UnusedStoreEliminator::knownUnrelated( yulAssert( _op1.length && _op2.length && - m_knowledgeBase.valueIfKnownConstant(*_op1.length) == 1 && - m_knowledgeBase.valueIfKnownConstant(*_op2.length) == 1 + lengthValue(*_op1.length) == 1 && + lengthValue(*_op2.length) == 1 ); return m_knowledgeBase.knownToBeDifferent(*_op1.start, *_op2.start); } @@ -322,14 +310,14 @@ bool UnusedStoreEliminator::knownUnrelated( { yulAssert(_op1.location == Location::Memory, ""); if ( - (_op1.length && m_knowledgeBase.knownToBeZero(*_op1.length)) || - (_op2.length && m_knowledgeBase.knownToBeZero(*_op2.length)) + (_op1.length && lengthValue(*_op1.length) == 0) || + (_op2.length && lengthValue(*_op2.length) == 0) ) return true; if (_op1.start && _op1.length && _op2.start) { - std::optional length1 = m_knowledgeBase.valueIfKnownConstant(*_op1.length); + std::optional length1 = lengthValue(*_op1.length); std::optional start1 = m_knowledgeBase.valueIfKnownConstant(*_op1.start); std::optional start2 = m_knowledgeBase.valueIfKnownConstant(*_op2.start); if ( @@ -341,7 +329,7 @@ bool UnusedStoreEliminator::knownUnrelated( } if (_op2.start && _op2.length && _op1.start) { - std::optional length2 = m_knowledgeBase.valueIfKnownConstant(*_op2.length); + std::optional length2 = lengthValue(*_op2.length); std::optional start2 = m_knowledgeBase.valueIfKnownConstant(*_op2.start); std::optional start1 = m_knowledgeBase.valueIfKnownConstant(*_op1.start); if ( @@ -354,8 +342,8 @@ bool UnusedStoreEliminator::knownUnrelated( if (_op1.start && _op1.length && _op2.start && _op2.length) { - std::optional length1 = m_knowledgeBase.valueIfKnownConstant(*_op1.length); - std::optional length2 = m_knowledgeBase.valueIfKnownConstant(*_op2.length); + std::optional length1 = lengthValue(*_op1.length); + std::optional length2 = lengthValue(*_op2.length); if ( (length1 && *length1 <= 32) && (length2 && *length2 <= 32) && @@ -382,15 +370,15 @@ bool UnusedStoreEliminator::knownCovered( return true; if (_covered.location == Location::Memory) { - if (_covered.length && m_knowledgeBase.knownToBeZero(*_covered.length)) + if (_covered.length && lengthValue(*_covered.length) == 0) return true; // Condition (i = cover_i_ng, e = cover_e_d): // i.start <= e.start && e.start + e.length <= i.start + i.length if (!_covered.start || !_covering.start || !_covered.length || !_covering.length) return false; - std::optional coveredLength = m_knowledgeBase.valueIfKnownConstant(*_covered.length); - std::optional coveringLength = m_knowledgeBase.valueIfKnownConstant(*_covering.length); + std::optional coveredLength = lengthValue(*_covered.length); + std::optional coveringLength = lengthValue(*_covering.length); if (*_covered.start == *_covering.start) if (coveredLength && coveringLength && *coveredLength <= *coveringLength) return true; diff --git a/libyul/optimiser/UnusedStoreEliminator.h b/libyul/optimiser/UnusedStoreEliminator.h index 6f50636a77cb..f749a229ca11 100644 --- a/libyul/optimiser/UnusedStoreEliminator.h +++ b/libyul/optimiser/UnusedStoreEliminator.h @@ -78,6 +78,7 @@ class UnusedStoreEliminator: public UnusedStoreBase using Location = evmasm::SemanticInformation::Location; using Effect = evmasm::SemanticInformation::Effect; + using OperationLength = std::variant; struct Operation { Location location; @@ -86,12 +87,19 @@ class UnusedStoreEliminator: public UnusedStoreBase std::optional start; /// Length of affected area, unknown if not provided. /// Unused for storage. - std::optional length; + std::optional length; }; private: std::set& activeMemoryStores() { return m_activeStores[UnusedStoreEliminatorKey::Memory]; } std::set& activeStorageStores() { return m_activeStores[UnusedStoreEliminatorKey::Storage]; } + std::optional lengthValue(OperationLength const& _length) const + { + if (YulName const* length = std::get_if(&_length)) + return m_knowledgeBase.valueIfKnownConstant(*length); + else + return std::get(_length); + } void shortcutNestedLoop(ActiveStores const&) override { From 371647ca13f960e32c72971cee8bdc50608c7251 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Fri, 18 Oct 2024 15:32:49 +0200 Subject: [PATCH 0552/1022] Yul: Object contains dialect --- libsolidity/ast/ASTJsonExporter.cpp | 2 +- libsolidity/codegen/CompilerContext.cpp | 6 +++--- libsolidity/codegen/ContractCompiler.cpp | 2 +- libsolidity/codegen/ir/IRGeneratorForStatements.cpp | 2 +- .../codegen/IRGeneratorForStatements.cpp | 2 +- libsolidity/interface/CompilerStack.cpp | 2 +- libyul/AsmJsonConverter.h | 4 +++- libyul/AsmPrinter.h | 3 +++ libyul/Object.cpp | 3 ++- libyul/Object.h | 8 ++++++-- libyul/ObjectOptimizer.cpp | 1 + libyul/ObjectParser.cpp | 4 ++-- libyul/backends/evm/EVMDialect.h | 2 +- libyul/backends/evm/EVMObjectCompiler.h | 2 +- libyul/optimiser/StackCompressor.h | 2 +- libyul/optimiser/StackLimitEvader.h | 2 +- libyul/optimiser/Suite.cpp | 2 +- libyul/optimiser/Suite.h | 2 +- test/libyul/Common.cpp | 7 ++++++- test/libyul/Common.h | 2 +- test/libyul/CompilabilityChecker.cpp | 12 ++++++------ test/libyul/ControlFlowSideEffectsTest.cpp | 9 ++++++--- test/libyul/FunctionSideEffects.cpp | 9 ++++++--- test/libyul/YulOptimizerTest.cpp | 2 +- test/libyul/YulOptimizerTest.h | 2 +- test/libyul/YulOptimizerTestCommon.h | 2 +- test/tools/yulopti.cpp | 6 +++--- tools/yulPhaser/Program.cpp | 4 ++-- 28 files changed, 64 insertions(+), 42 deletions(-) diff --git a/libsolidity/ast/ASTJsonExporter.cpp b/libsolidity/ast/ASTJsonExporter.cpp index 7183c64a3f18..4e7a5cd508b4 100644 --- a/libsolidity/ast/ASTJsonExporter.cpp +++ b/libsolidity/ast/ASTJsonExporter.cpp @@ -667,7 +667,7 @@ bool ASTJsonExporter::visit(InlineAssembly const& _node) auto const& evmDialect = dynamic_cast(_node.dialect()); std::vector> attributes = { - std::make_pair("AST", Json(yul::AsmJsonConverter(sourceIndexFromLocation(_node.location()))(_node.operations().root()))), + std::make_pair("AST", Json(yul::AsmJsonConverter(evmDialect, sourceIndexFromLocation(_node.location()))(_node.operations().root()))), std::make_pair("externalReferences", std::move(externalReferencesJson)), std::make_pair("evmVersion", evmDialect.evmVersion().name()) }; diff --git a/libsolidity/codegen/CompilerContext.cpp b/libsolidity/codegen/CompilerContext.cpp index 4a0f636dc974..84de00656e90 100644 --- a/libsolidity/codegen/CompilerContext.cpp +++ b/libsolidity/codegen/CompilerContext.cpp @@ -481,7 +481,7 @@ void CompilerContext::appendInlineAssembly( // so we essentially only optimize the ABI functions. if (_optimiserSettings.runYulOptimiser && _localVariables.empty()) { - yul::Object obj; + yul::Object obj{dialect}; obj.setCode(parserResult, std::make_shared(analysisInfo)); solAssert(!dialect.providesObjectAccess()); @@ -491,8 +491,8 @@ void CompilerContext::appendInlineAssembly( { // Store as generated sources, but first re-parse to update the source references. solAssert(m_generatedYulUtilityCode.empty(), ""); - m_generatedYulUtilityCode = yul::AsmPrinter()(obj.code()->root()); - std::string code = yul::AsmPrinter{}(obj.code()->root()); + m_generatedYulUtilityCode = yul::AsmPrinter(obj.dialect())(obj.code()->root()); + std::string code = yul::AsmPrinter{obj.dialect()}(obj.code()->root()); langutil::CharStream charStream(m_generatedYulUtilityCode, _sourceName); obj.setCode(yul::Parser(errorReporter, dialect).parse(charStream)); obj.analysisInfo = std::make_shared(yul::AsmAnalyzer::analyzeStrictAssertCorrect(dialect, obj)); diff --git a/libsolidity/codegen/ContractCompiler.cpp b/libsolidity/codegen/ContractCompiler.cpp index 96b1ea54823d..97ffb17e917f 100644 --- a/libsolidity/codegen/ContractCompiler.cpp +++ b/libsolidity/codegen/ContractCompiler.cpp @@ -932,7 +932,7 @@ bool ContractCompiler::visit(InlineAssembly const& _inlineAssembly) // Only used in the scope below, but required to live outside to keep the // std::shared_ptr's alive - yul::Object object = {}; + yul::Object object{_inlineAssembly.dialect()}; // The optimiser cannot handle external references if ( diff --git a/libsolidity/codegen/ir/IRGeneratorForStatements.cpp b/libsolidity/codegen/ir/IRGeneratorForStatements.cpp index 69d24cf42669..5054e1aa1d03 100644 --- a/libsolidity/codegen/ir/IRGeneratorForStatements.cpp +++ b/libsolidity/codegen/ir/IRGeneratorForStatements.cpp @@ -2258,7 +2258,7 @@ bool IRGeneratorForStatements::visit(InlineAssembly const& _inlineAsm) solAssert(std::holds_alternative(modified)); - appendCode() << yul::AsmPrinter()(std::get(modified)) << "\n"; + appendCode() << yul::AsmPrinter(_inlineAsm.dialect())(std::get(modified)) << "\n"; return false; } diff --git a/libsolidity/experimental/codegen/IRGeneratorForStatements.cpp b/libsolidity/experimental/codegen/IRGeneratorForStatements.cpp index a9e4fa9313da..80c442b88146 100644 --- a/libsolidity/experimental/codegen/IRGeneratorForStatements.cpp +++ b/libsolidity/experimental/codegen/IRGeneratorForStatements.cpp @@ -132,7 +132,7 @@ bool IRGeneratorForStatements::visit(InlineAssembly const& _assembly) CopyTranslate bodyCopier{m_context, _assembly.dialect(), _assembly.annotation().externalReferences}; yul::Statement modified = bodyCopier(_assembly.operations().root()); solAssert(std::holds_alternative(modified)); - m_code << yul::AsmPrinter()(std::get(modified)) << "\n"; + m_code << yul::AsmPrinter(_assembly.dialect())(std::get(modified)) << "\n"; return false; } diff --git a/libsolidity/interface/CompilerStack.cpp b/libsolidity/interface/CompilerStack.cpp index e3927d4dfb1b..f24fae3cd476 100644 --- a/libsolidity/interface/CompilerStack.cpp +++ b/libsolidity/interface/CompilerStack.cpp @@ -900,7 +900,7 @@ Json CompilerStack::generatedSources(std::string const& _contractName, bool _run yul::EVMDialect const& dialect = yul::EVMDialect::strictAssemblyForEVM(m_evmVersion, m_eofVersion); std::shared_ptr parserResult = yul::Parser{errorReporter, dialect}.parse(charStream); solAssert(parserResult); - sources[0]["ast"] = yul::AsmJsonConverter{sourceIndex}(parserResult->root()); + sources[0]["ast"] = yul::AsmJsonConverter{dialect, sourceIndex}(parserResult->root()); sources[0]["name"] = sourceName; sources[0]["id"] = sourceIndex; sources[0]["language"] = "Yul"; diff --git a/libyul/AsmJsonConverter.h b/libyul/AsmJsonConverter.h index 523825830f46..75e3400b7d3e 100644 --- a/libyul/AsmJsonConverter.h +++ b/libyul/AsmJsonConverter.h @@ -33,6 +33,8 @@ namespace solidity::yul { +struct Dialect; + /** * Converter of the yul AST into JSON format */ @@ -41,7 +43,7 @@ class AsmJsonConverter: public boost::static_visitor public: /// Create a converter to JSON for any block of inline assembly /// @a _sourceIndex to be used to abbreviate source name in the source locations - explicit AsmJsonConverter(std::optional _sourceIndex): m_sourceIndex(_sourceIndex) {} + explicit AsmJsonConverter(Dialect const&, std::optional _sourceIndex): m_sourceIndex(_sourceIndex) {} Json operator()(Block const& _node) const; Json operator()(NameWithDebugData const& _node) const; diff --git a/libyul/AsmPrinter.h b/libyul/AsmPrinter.h index cc17c6a04ce3..6eda13fcd83a 100644 --- a/libyul/AsmPrinter.h +++ b/libyul/AsmPrinter.h @@ -37,6 +37,8 @@ namespace solidity::yul { +struct Dialect; + /** * Converts a parsed Yul AST into readable string representation. * Ignores source locations. @@ -45,6 +47,7 @@ class AsmPrinter { public: explicit AsmPrinter( + Dialect const&, std::optional>> _sourceIndexToName = {}, langutil::DebugInfoSelection const& _debugInfoSelection = langutil::DebugInfoSelection::Default(), langutil::CharStreamProvider const* _soliditySourceProvider = nullptr diff --git a/libyul/Object.cpp b/libyul/Object.cpp index c6ba5311ad5c..0d5e120a8b85 100644 --- a/libyul/Object.cpp +++ b/libyul/Object.cpp @@ -52,6 +52,7 @@ std::string Object::toString( yulAssert(debugData, "No debug data"); std::string inner = "code " + AsmPrinter( + m_dialect, debugData->sourceNames, _debugInfoSelection, _soliditySourceProvider @@ -96,7 +97,7 @@ Json Object::toJson() const Json codeJson; codeJson["nodeType"] = "YulCode"; - codeJson["block"] = AsmJsonConverter(0 /* sourceIndex */)(code()->root()); + codeJson["block"] = AsmJsonConverter(m_dialect, 0 /* sourceIndex */)(code()->root()); Json subObjectsJson = Json::array(); for (std::shared_ptr const& subObject: subObjects) diff --git a/libyul/Object.h b/libyul/Object.h index 230f97866e09..15b94044b838 100644 --- a/libyul/Object.h +++ b/libyul/Object.h @@ -41,7 +41,7 @@ struct AsmAnalysisInfo; using SourceNameMap = std::map>; -struct Object; +class Object; /** * Generic base class for both Yul objects and Yul data. @@ -88,9 +88,10 @@ struct ObjectDebugData /** * Yul code and data object container. */ -struct Object: public ObjectNode +class Object: public ObjectNode { public: + explicit Object(Dialect const& _dialect): m_dialect(_dialect) {} /// @returns a (parseable) string representation. std::string toString( langutil::DebugInfoSelection const& _debugInfoSelection = langutil::DebugInfoSelection::Default(), @@ -139,7 +140,10 @@ struct Object: public ObjectNode /// @returns the name of the special metadata data object. static std::string metadataName() { return ".metadata"; } + Dialect const& dialect() const { return m_dialect; } + private: + Dialect const& m_dialect; std::shared_ptr m_code; }; diff --git a/libyul/ObjectOptimizer.cpp b/libyul/ObjectOptimizer.cpp index 511fc979ddb0..6a6354f94b36 100644 --- a/libyul/ObjectOptimizer.cpp +++ b/libyul/ObjectOptimizer.cpp @@ -142,6 +142,7 @@ std::optional ObjectOptimizer::calculateCacheKey( ) { AsmPrinter asmPrinter( + languageToDialect(_settings.language, _settings.evmVersion, _settings.eofVersion), _debugData.sourceNames, DebugInfoSelection::All() ); diff --git a/libyul/ObjectParser.cpp b/libyul/ObjectParser.cpp index 123dedcb483d..67f5b70dd003 100644 --- a/libyul/ObjectParser.cpp +++ b/libyul/ObjectParser.cpp @@ -49,7 +49,7 @@ std::shared_ptr ObjectParser::parse(std::shared_ptr const& _sca if (currentToken() == Token::LBrace) { // Special case: Code-only form. - object = std::make_shared(); + object = std::make_shared(m_dialect); object->name = "object"; auto sourceNameMapping = tryParseSourceNameMapping(); object->debugData = std::make_shared(ObjectDebugData{sourceNameMapping}); @@ -74,7 +74,7 @@ std::shared_ptr ObjectParser::parseObject(Object* _containingObject) { RecursionGuard guard(*this); - std::shared_ptr ret = std::make_shared(); + std::shared_ptr ret = std::make_shared(m_dialect); auto sourceNameMapping = tryParseSourceNameMapping(); ret->debugData = std::make_shared(ObjectDebugData{sourceNameMapping}); diff --git a/libyul/backends/evm/EVMDialect.h b/libyul/backends/evm/EVMDialect.h index 1443b44811fa..65cc70f162b7 100644 --- a/libyul/backends/evm/EVMDialect.h +++ b/libyul/backends/evm/EVMDialect.h @@ -34,7 +34,7 @@ namespace solidity::yul { struct FunctionCall; -struct Object; +class Object; /** * Context used during code generation. diff --git a/libyul/backends/evm/EVMObjectCompiler.h b/libyul/backends/evm/EVMObjectCompiler.h index 07ba34a75458..5154bd37fe1c 100644 --- a/libyul/backends/evm/EVMObjectCompiler.h +++ b/libyul/backends/evm/EVMObjectCompiler.h @@ -26,7 +26,7 @@ namespace solidity::yul { -struct Object; +class Object; class AbstractAssembly; class EVMDialect; diff --git a/libyul/optimiser/StackCompressor.h b/libyul/optimiser/StackCompressor.h index 15d057455ac8..70c020b9cee3 100644 --- a/libyul/optimiser/StackCompressor.h +++ b/libyul/optimiser/StackCompressor.h @@ -30,7 +30,7 @@ namespace solidity::yul { struct Dialect; -struct Object; +class Object; struct FunctionDefinition; /** diff --git a/libyul/optimiser/StackLimitEvader.h b/libyul/optimiser/StackLimitEvader.h index a5871f7f111d..d63c3287dd41 100644 --- a/libyul/optimiser/StackLimitEvader.h +++ b/libyul/optimiser/StackLimitEvader.h @@ -27,7 +27,7 @@ namespace solidity::yul { -struct Object; +class Object; /** * Optimisation stage that assigns memory offsets to variables that would become unreachable if diff --git a/libyul/optimiser/Suite.cpp b/libyul/optimiser/Suite.cpp index ff8c2b7cff28..c6b5f8cfc63c 100644 --- a/libyul/optimiser/Suite.cpp +++ b/libyul/optimiser/Suite.cpp @@ -486,7 +486,7 @@ void OptimiserSuite::runSequence(std::vector const& _steps, Block& else { std::cout << "== Running " << step << " changed the AST." << std::endl; - std::cout << AsmPrinter{}(_ast) << std::endl; + std::cout << AsmPrinter{m_context.dialect}(_ast) << std::endl; copy = std::make_unique(std::get(ASTCopier{}(_ast))); } } diff --git a/libyul/optimiser/Suite.h b/libyul/optimiser/Suite.h index efa82f48c9b7..e4eac31df505 100644 --- a/libyul/optimiser/Suite.h +++ b/libyul/optimiser/Suite.h @@ -38,7 +38,7 @@ namespace solidity::yul struct AsmAnalysisInfo; struct Dialect; class GasMeter; -struct Object; +class Object; /** * Optimiser suite that combines all steps and also provides the settings for the heuristics. diff --git a/test/libyul/Common.cpp b/test/libyul/Common.cpp index 6562e1743588..9b72fdc29389 100644 --- a/test/libyul/Common.cpp +++ b/test/libyul/Common.cpp @@ -99,7 +99,12 @@ yul::Block yul::test::disambiguate(std::string const& _source) std::string yul::test::format(std::string const& _source) { - return yul::AsmPrinter()(parse(_source).first->root()); + Dialect const& dialect = languageToDialect( + YulStack::Language::StrictAssembly, + solidity::test::CommonOptions::get().evmVersion(), + solidity::test::CommonOptions::get().eofVersion() + ); + return AsmPrinter(dialect)(parse(_source).first->root()); } namespace diff --git a/test/libyul/Common.h b/test/libyul/Common.h index 2255272b6b5e..54c61f875a79 100644 --- a/test/libyul/Common.h +++ b/test/libyul/Common.h @@ -37,7 +37,7 @@ namespace solidity::yul { struct AsmAnalysisInfo; struct Block; -struct Object; +class Object; struct Dialect; class AST; } diff --git a/test/libyul/CompilabilityChecker.cpp b/test/libyul/CompilabilityChecker.cpp index 6c86ac21f32f..9691efa216b4 100644 --- a/test/libyul/CompilabilityChecker.cpp +++ b/test/libyul/CompilabilityChecker.cpp @@ -34,15 +34,15 @@ namespace { std::string check(std::string const& _input) { - Object obj; + auto const& dialect = EVMDialect::strictAssemblyForEVM( + solidity::test::CommonOptions::get().evmVersion(), + solidity::test::CommonOptions::get().eofVersion() + ); + Object obj{dialect}; auto parsingResult = yul::test::parse(_input); obj.setCode(parsingResult.first, parsingResult.second); BOOST_REQUIRE(obj.hasCode()); - auto functions = CompilabilityChecker( - EVMDialect::strictAssemblyForEVM( - solidity::test::CommonOptions::get().evmVersion(), - solidity::test::CommonOptions::get().eofVersion() - ), obj, true).stackDeficit; + auto functions = CompilabilityChecker(dialect, obj, true).stackDeficit; std::string out; for (auto const& function: functions) out += function.first.str() + ": " + std::to_string(function.second) + " "; diff --git a/test/libyul/ControlFlowSideEffectsTest.cpp b/test/libyul/ControlFlowSideEffectsTest.cpp index b9d883dcde06..799f64ce7948 100644 --- a/test/libyul/ControlFlowSideEffectsTest.cpp +++ b/test/libyul/ControlFlowSideEffectsTest.cpp @@ -56,15 +56,18 @@ ControlFlowSideEffectsTest::ControlFlowSideEffectsTest(std::string const& _filen TestCase::TestResult ControlFlowSideEffectsTest::run(std::ostream& _stream, std::string const& _linePrefix, bool _formatted) { - Object obj; + auto const& dialect = EVMDialect::strictAssemblyForEVMObjects( + solidity::test::CommonOptions::get().evmVersion(), + solidity::test::CommonOptions::get().eofVersion() + ); + Object obj{dialect}; auto parsingResult = yul::test::parse(m_source); obj.setCode(parsingResult.first, parsingResult.second); if (!obj.hasCode()) BOOST_THROW_EXCEPTION(std::runtime_error("Parsing input failed.")); ControlFlowSideEffectsCollector sideEffects( - EVMDialect::strictAssemblyForEVMObjects(solidity::test::CommonOptions::get().evmVersion(), - solidity::test::CommonOptions::get().eofVersion()), + dialect, obj.code()->root() ); m_obtainedResult.clear(); diff --git a/test/libyul/FunctionSideEffects.cpp b/test/libyul/FunctionSideEffects.cpp index a878d375d02b..bd9a9da07918 100644 --- a/test/libyul/FunctionSideEffects.cpp +++ b/test/libyul/FunctionSideEffects.cpp @@ -82,15 +82,18 @@ FunctionSideEffects::FunctionSideEffects(std::string const& _filename): TestCase::TestResult FunctionSideEffects::run(std::ostream& _stream, std::string const& _linePrefix, bool _formatted) { - Object obj; + auto const& dialect = EVMDialect::strictAssemblyForEVMObjects( + solidity::test::CommonOptions::get().evmVersion(), + solidity::test::CommonOptions::get().eofVersion() + ); + Object obj{dialect}; auto parsingResult = yul::test::parse(m_source); obj.setCode(parsingResult.first, parsingResult.second); if (!obj.hasCode()) BOOST_THROW_EXCEPTION(std::runtime_error("Parsing input failed.")); std::map functionSideEffects = SideEffectsPropagator::sideEffects( - EVMDialect::strictAssemblyForEVMObjects(solidity::test::CommonOptions::get().evmVersion(), - solidity::test::CommonOptions::get().eofVersion()), + dialect, CallGraphGenerator::callGraph(obj.code()->root()) ); diff --git a/test/libyul/YulOptimizerTest.cpp b/test/libyul/YulOptimizerTest.cpp index 308afef5f904..c17beb84d5c8 100644 --- a/test/libyul/YulOptimizerTest.cpp +++ b/test/libyul/YulOptimizerTest.cpp @@ -85,7 +85,7 @@ TestCase::TestResult YulOptimizerTest::run(std::ostream& _stream, std::string co auto optimizedObject = tester.optimizedObject(); std::string printedOptimizedObject; if (optimizedObject->subObjects.empty()) - printedOptimizedObject = AsmPrinter{}(optimizedObject->code()->root()); + printedOptimizedObject = AsmPrinter{optimizedObject->dialect()}(optimizedObject->code()->root()); else printedOptimizedObject = optimizedObject->toString(); diff --git a/test/libyul/YulOptimizerTest.h b/test/libyul/YulOptimizerTest.h index 832b5dfb8f7c..2412812888b0 100644 --- a/test/libyul/YulOptimizerTest.h +++ b/test/libyul/YulOptimizerTest.h @@ -29,7 +29,7 @@ using ErrorList = std::vector>; namespace solidity::yul { struct AsmAnalysisInfo; -struct Object; +class Object; struct Dialect; } diff --git a/test/libyul/YulOptimizerTestCommon.h b/test/libyul/YulOptimizerTestCommon.h index 41806fcd6a5a..b214b80c01c4 100644 --- a/test/libyul/YulOptimizerTestCommon.h +++ b/test/libyul/YulOptimizerTestCommon.h @@ -29,7 +29,7 @@ namespace solidity::yul { struct AsmAnalysisInfo; -struct Object; +class Object; struct Dialect; class AST; } diff --git a/test/tools/yulopti.cpp b/test/tools/yulopti.cpp index cbe0219676fa..a1a5e8c583b0 100644 --- a/test/tools/yulopti.cpp +++ b/test/tools/yulopti.cpp @@ -180,7 +180,7 @@ class YulOpti parse(_source); disambiguate(); OptimiserSuite{m_context}.runSequence(_steps, *m_astRoot); - std::cout << AsmPrinter{}(*m_astRoot) << std::endl; + std::cout << AsmPrinter{m_dialect}(*m_astRoot) << std::endl; } void runInteractive(std::string _source, bool _disambiguated = false) @@ -217,7 +217,7 @@ class YulOpti break; case ';': { - Object obj; + Object obj{m_dialect}; obj.setCode(std::make_shared(std::get(ASTCopier{}(*m_astRoot)))); *m_astRoot = std::get<1>(StackCompressor::run(m_dialect, obj, true, 16)); break; @@ -228,7 +228,7 @@ class YulOpti *m_astRoot ); } - _source = AsmPrinter{}(*m_astRoot); + _source = AsmPrinter{m_dialect}(*m_astRoot); } catch (...) { diff --git a/tools/yulPhaser/Program.cpp b/tools/yulPhaser/Program.cpp index fa7fbe274c95..25cc8c5505f5 100644 --- a/tools/yulPhaser/Program.cpp +++ b/tools/yulPhaser/Program.cpp @@ -106,12 +106,12 @@ void Program::optimise(std::vector const& _optimisationSteps) std::ostream& phaser::operator<<(std::ostream& _stream, Program const& _program) { - return _stream << AsmPrinter()(_program.m_ast->root()); + return _stream << AsmPrinter(_program.m_dialect)(_program.m_ast->root()); } std::string Program::toJson() const { - Json serializedAst = AsmJsonConverter(0)(m_ast->root()); + Json serializedAst = AsmJsonConverter(m_dialect, 0)(m_ast->root()); return jsonPrettyPrint(removeNullMembers(std::move(serializedAst))); } From 2162dec0c92e1b68bd2e10c9f8732354fa8cf6d6 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Thu, 31 Oct 2024 10:38:43 +0100 Subject: [PATCH 0553/1022] Yul SSACFG JSON export fix: Function arguments are referenced by their value ids --- libyul/YulControlFlowGraphExporter.cpp | 5 +- .../standard_yul_cfg_json_export/output.json | 90 +++++++++---------- test/cmdlineTests/yul_cfg_json_export/output | 90 +++++++++---------- 3 files changed, 92 insertions(+), 93 deletions(-) diff --git a/libyul/YulControlFlowGraphExporter.cpp b/libyul/YulControlFlowGraphExporter.cpp index 13770989b91d..6219d51b81e5 100644 --- a/libyul/YulControlFlowGraphExporter.cpp +++ b/libyul/YulControlFlowGraphExporter.cpp @@ -74,9 +74,8 @@ Json YulControlFlowGraphExporter::exportFunction(SSACFG const& _cfg) Json functionJson = Json::object(); functionJson["type"] = "Function"; functionJson["entry"] = "Block" + std::to_string(_cfg.entry.value); - functionJson["arguments"] = Json::array(); - for (auto const& [arg, valueId]: _cfg.arguments) - functionJson["arguments"].emplace_back(arg.get().name.str()); + static auto constexpr argsTransform = [](auto const& _arg) { return fmt::format("v{}", std::get<1>(_arg).value); }; + functionJson["arguments"] = _cfg.arguments | ranges::views::transform(argsTransform) | ranges::to; functionJson["returns"] = Json::array(); for (auto const& ret: _cfg.returns) functionJson["returns"].emplace_back(ret.get().name.str()); diff --git a/test/cmdlineTests/standard_yul_cfg_json_export/output.json b/test/cmdlineTests/standard_yul_cfg_json_export/output.json index d09a6c1a5396..a43c553c4839 100644 --- a/test/cmdlineTests/standard_yul_cfg_json_export/output.json +++ b/test/cmdlineTests/standard_yul_cfg_json_export/output.json @@ -380,8 +380,8 @@ "functions": { "abi_decode_tuple_": { "arguments": [ - "headStart", - "dataEnd" + "v0", + "v1" ], "blocks": [ { @@ -447,8 +447,8 @@ }, "abi_encode_t_uint256_to_t_uint256_fromStack": { "arguments": [ - "value", - "pos" + "v0", + "v1" ], "blocks": [ { @@ -485,8 +485,8 @@ }, "abi_encode_tuple_t_uint256__to_t_uint256__fromStack": { "arguments": [ - "headStart", - "value0" + "v0", + "v1" ], "blocks": [ { @@ -569,7 +569,7 @@ }, "cleanup_t_rational_42_by_1": { "arguments": [ - "value" + "v0" ], "blocks": [ { @@ -591,7 +591,7 @@ }, "cleanup_t_uint256": { "arguments": [ - "value" + "v0" ], "blocks": [ { @@ -613,7 +613,7 @@ }, "convert_t_rational_42_by_1_to_t_uint256": { "arguments": [ - "value" + "v0" ], "blocks": [ { @@ -811,7 +811,7 @@ }, "identity": { "arguments": [ - "value" + "v0" ], "blocks": [ { @@ -908,7 +908,7 @@ }, "shift_right_224_unsigned": { "arguments": [ - "value" + "v0" ], "blocks": [ { @@ -1324,8 +1324,8 @@ "functions": { "abi_decode_t_uint256_fromMemory": { "arguments": [ - "offset", - "end" + "v0", + "v1" ], "blocks": [ { @@ -1365,8 +1365,8 @@ }, "abi_decode_tuple_": { "arguments": [ - "headStart", - "dataEnd" + "v0", + "v1" ], "blocks": [ { @@ -1432,8 +1432,8 @@ }, "abi_decode_tuple_t_uint256_fromMemory": { "arguments": [ - "headStart", - "dataEnd" + "v0", + "v1" ], "blocks": [ { @@ -1525,8 +1525,8 @@ }, "abi_encode_t_uint256_to_t_uint256_fromStack": { "arguments": [ - "value", - "pos" + "v0", + "v1" ], "blocks": [ { @@ -1563,7 +1563,7 @@ }, "abi_encode_tuple__to__fromStack": { "arguments": [ - "headStart" + "v0" ], "blocks": [ { @@ -1597,8 +1597,8 @@ }, "abi_encode_tuple_t_uint256__to_t_uint256__fromStack": { "arguments": [ - "headStart", - "value0" + "v0", + "v1" ], "blocks": [ { @@ -1681,7 +1681,7 @@ }, "cleanup_t_uint160": { "arguments": [ - "value" + "v0" ], "blocks": [ { @@ -1715,7 +1715,7 @@ }, "cleanup_t_uint256": { "arguments": [ - "value" + "v0" ], "blocks": [ { @@ -1737,7 +1737,7 @@ }, "convert_t_contract$_C_$19_to_t_address": { "arguments": [ - "value" + "v0" ], "blocks": [ { @@ -1770,7 +1770,7 @@ }, "convert_t_uint160_to_t_address": { "arguments": [ - "value" + "v0" ], "blocks": [ { @@ -1803,7 +1803,7 @@ }, "convert_t_uint160_to_t_uint160": { "arguments": [ - "value" + "v0" ], "blocks": [ { @@ -1963,8 +1963,8 @@ }, "finalize_allocation": { "arguments": [ - "memPtr", - "size" + "v0", + "v1" ], "blocks": [ { @@ -2528,7 +2528,7 @@ }, "identity": { "arguments": [ - "value" + "v0" ], "blocks": [ { @@ -2771,7 +2771,7 @@ }, "round_up_to_mul_of_32": { "arguments": [ - "value" + "v0" ], "blocks": [ { @@ -2824,7 +2824,7 @@ }, "shift_left_224": { "arguments": [ - "value" + "v0" ], "blocks": [ { @@ -2858,7 +2858,7 @@ }, "shift_right_224_unsigned": { "arguments": [ - "value" + "v0" ], "blocks": [ { @@ -2892,7 +2892,7 @@ }, "validator_revert_t_uint256": { "arguments": [ - "value" + "v0" ], "blocks": [ { @@ -3367,8 +3367,8 @@ "functions": { "abi_decode_tuple_": { "arguments": [ - "headStart", - "dataEnd" + "v0", + "v1" ], "blocks": [ { @@ -3434,8 +3434,8 @@ }, "abi_encode_t_uint256_to_t_uint256_fromStack": { "arguments": [ - "value", - "pos" + "v0", + "v1" ], "blocks": [ { @@ -3472,8 +3472,8 @@ }, "abi_encode_tuple_t_uint256__to_t_uint256__fromStack": { "arguments": [ - "headStart", - "value0" + "v0", + "v1" ], "blocks": [ { @@ -3556,7 +3556,7 @@ }, "cleanup_t_rational_42_by_1": { "arguments": [ - "value" + "v0" ], "blocks": [ { @@ -3578,7 +3578,7 @@ }, "cleanup_t_uint256": { "arguments": [ - "value" + "v0" ], "blocks": [ { @@ -3600,7 +3600,7 @@ }, "convert_t_rational_42_by_1_to_t_uint256": { "arguments": [ - "value" + "v0" ], "blocks": [ { @@ -3798,7 +3798,7 @@ }, "identity": { "arguments": [ - "value" + "v0" ], "blocks": [ { @@ -3895,7 +3895,7 @@ }, "shift_right_224_unsigned": { "arguments": [ - "value" + "v0" ], "blocks": [ { diff --git a/test/cmdlineTests/yul_cfg_json_export/output b/test/cmdlineTests/yul_cfg_json_export/output index 3a287ee760ad..d68997bff969 100644 --- a/test/cmdlineTests/yul_cfg_json_export/output +++ b/test/cmdlineTests/yul_cfg_json_export/output @@ -379,8 +379,8 @@ Yul Control Flow Graph: "functions": { "abi_decode_tuple_": { "arguments": [ - "headStart", - "dataEnd" + "v0", + "v1" ], "blocks": [ { @@ -446,8 +446,8 @@ Yul Control Flow Graph: }, "abi_encode_t_uint256_to_t_uint256_fromStack": { "arguments": [ - "value", - "pos" + "v0", + "v1" ], "blocks": [ { @@ -484,8 +484,8 @@ Yul Control Flow Graph: }, "abi_encode_tuple_t_uint256__to_t_uint256__fromStack": { "arguments": [ - "headStart", - "value0" + "v0", + "v1" ], "blocks": [ { @@ -568,7 +568,7 @@ Yul Control Flow Graph: }, "cleanup_t_rational_42_by_1": { "arguments": [ - "value" + "v0" ], "blocks": [ { @@ -590,7 +590,7 @@ Yul Control Flow Graph: }, "cleanup_t_uint256": { "arguments": [ - "value" + "v0" ], "blocks": [ { @@ -612,7 +612,7 @@ Yul Control Flow Graph: }, "convert_t_rational_42_by_1_to_t_uint256": { "arguments": [ - "value" + "v0" ], "blocks": [ { @@ -810,7 +810,7 @@ Yul Control Flow Graph: }, "identity": { "arguments": [ - "value" + "v0" ], "blocks": [ { @@ -907,7 +907,7 @@ Yul Control Flow Graph: }, "shift_right_224_unsigned": { "arguments": [ - "value" + "v0" ], "blocks": [ { @@ -1324,8 +1324,8 @@ Yul Control Flow Graph: "functions": { "abi_decode_t_uint256_fromMemory": { "arguments": [ - "offset", - "end" + "v0", + "v1" ], "blocks": [ { @@ -1365,8 +1365,8 @@ Yul Control Flow Graph: }, "abi_decode_tuple_": { "arguments": [ - "headStart", - "dataEnd" + "v0", + "v1" ], "blocks": [ { @@ -1432,8 +1432,8 @@ Yul Control Flow Graph: }, "abi_decode_tuple_t_uint256_fromMemory": { "arguments": [ - "headStart", - "dataEnd" + "v0", + "v1" ], "blocks": [ { @@ -1525,8 +1525,8 @@ Yul Control Flow Graph: }, "abi_encode_t_uint256_to_t_uint256_fromStack": { "arguments": [ - "value", - "pos" + "v0", + "v1" ], "blocks": [ { @@ -1563,7 +1563,7 @@ Yul Control Flow Graph: }, "abi_encode_tuple__to__fromStack": { "arguments": [ - "headStart" + "v0" ], "blocks": [ { @@ -1597,8 +1597,8 @@ Yul Control Flow Graph: }, "abi_encode_tuple_t_uint256__to_t_uint256__fromStack": { "arguments": [ - "headStart", - "value0" + "v0", + "v1" ], "blocks": [ { @@ -1681,7 +1681,7 @@ Yul Control Flow Graph: }, "cleanup_t_uint160": { "arguments": [ - "value" + "v0" ], "blocks": [ { @@ -1715,7 +1715,7 @@ Yul Control Flow Graph: }, "cleanup_t_uint256": { "arguments": [ - "value" + "v0" ], "blocks": [ { @@ -1737,7 +1737,7 @@ Yul Control Flow Graph: }, "convert_t_contract$_C_$19_to_t_address": { "arguments": [ - "value" + "v0" ], "blocks": [ { @@ -1770,7 +1770,7 @@ Yul Control Flow Graph: }, "convert_t_uint160_to_t_address": { "arguments": [ - "value" + "v0" ], "blocks": [ { @@ -1803,7 +1803,7 @@ Yul Control Flow Graph: }, "convert_t_uint160_to_t_uint160": { "arguments": [ - "value" + "v0" ], "blocks": [ { @@ -1963,8 +1963,8 @@ Yul Control Flow Graph: }, "finalize_allocation": { "arguments": [ - "memPtr", - "size" + "v0", + "v1" ], "blocks": [ { @@ -2528,7 +2528,7 @@ Yul Control Flow Graph: }, "identity": { "arguments": [ - "value" + "v0" ], "blocks": [ { @@ -2771,7 +2771,7 @@ Yul Control Flow Graph: }, "round_up_to_mul_of_32": { "arguments": [ - "value" + "v0" ], "blocks": [ { @@ -2824,7 +2824,7 @@ Yul Control Flow Graph: }, "shift_left_224": { "arguments": [ - "value" + "v0" ], "blocks": [ { @@ -2858,7 +2858,7 @@ Yul Control Flow Graph: }, "shift_right_224_unsigned": { "arguments": [ - "value" + "v0" ], "blocks": [ { @@ -2892,7 +2892,7 @@ Yul Control Flow Graph: }, "validator_revert_t_uint256": { "arguments": [ - "value" + "v0" ], "blocks": [ { @@ -3367,8 +3367,8 @@ Yul Control Flow Graph: "functions": { "abi_decode_tuple_": { "arguments": [ - "headStart", - "dataEnd" + "v0", + "v1" ], "blocks": [ { @@ -3434,8 +3434,8 @@ Yul Control Flow Graph: }, "abi_encode_t_uint256_to_t_uint256_fromStack": { "arguments": [ - "value", - "pos" + "v0", + "v1" ], "blocks": [ { @@ -3472,8 +3472,8 @@ Yul Control Flow Graph: }, "abi_encode_tuple_t_uint256__to_t_uint256__fromStack": { "arguments": [ - "headStart", - "value0" + "v0", + "v1" ], "blocks": [ { @@ -3556,7 +3556,7 @@ Yul Control Flow Graph: }, "cleanup_t_rational_42_by_1": { "arguments": [ - "value" + "v0" ], "blocks": [ { @@ -3578,7 +3578,7 @@ Yul Control Flow Graph: }, "cleanup_t_uint256": { "arguments": [ - "value" + "v0" ], "blocks": [ { @@ -3600,7 +3600,7 @@ Yul Control Flow Graph: }, "convert_t_rational_42_by_1_to_t_uint256": { "arguments": [ - "value" + "v0" ], "blocks": [ { @@ -3798,7 +3798,7 @@ Yul Control Flow Graph: }, "identity": { "arguments": [ - "value" + "v0" ], "blocks": [ { @@ -3895,7 +3895,7 @@ Yul Control Flow Graph: }, "shift_right_224_unsigned": { "arguments": [ - "value" + "v0" ], "blocks": [ { From 85318c927695fdfa5443b16108a9f681c6eabc89 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Thu, 31 Oct 2024 13:33:22 +0100 Subject: [PATCH 0554/1022] Yul SSACFG JSON export: Change returns field to numReturns --- libyul/YulControlFlowGraphExporter.cpp | 4 +- .../standard_yul_cfg_json_export/output.json | 212 ++++++------------ test/cmdlineTests/yul_cfg_json_export/output | 212 ++++++------------ 3 files changed, 139 insertions(+), 289 deletions(-) diff --git a/libyul/YulControlFlowGraphExporter.cpp b/libyul/YulControlFlowGraphExporter.cpp index 6219d51b81e5..17737533fd16 100644 --- a/libyul/YulControlFlowGraphExporter.cpp +++ b/libyul/YulControlFlowGraphExporter.cpp @@ -76,9 +76,7 @@ Json YulControlFlowGraphExporter::exportFunction(SSACFG const& _cfg) functionJson["entry"] = "Block" + std::to_string(_cfg.entry.value); static auto constexpr argsTransform = [](auto const& _arg) { return fmt::format("v{}", std::get<1>(_arg).value); }; functionJson["arguments"] = _cfg.arguments | ranges::views::transform(argsTransform) | ranges::to; - functionJson["returns"] = Json::array(); - for (auto const& ret: _cfg.returns) - functionJson["returns"].emplace_back(ret.get().name.str()); + functionJson["numReturns"] = _cfg.returns.size(); functionJson["blocks"] = exportBlock(_cfg, _cfg.entry); return functionJson; } diff --git a/test/cmdlineTests/standard_yul_cfg_json_export/output.json b/test/cmdlineTests/standard_yul_cfg_json_export/output.json index a43c553c4839..8d3fc5b7e057 100644 --- a/test/cmdlineTests/standard_yul_cfg_json_export/output.json +++ b/test/cmdlineTests/standard_yul_cfg_json_export/output.json @@ -154,9 +154,7 @@ } ], "entry": "Block0", - "returns": [ - "memPtr" - ], + "numReturns": 1, "type": "Function" }, "constructor_C_19": { @@ -179,7 +177,7 @@ } ], "entry": "Block0", - "returns": [], + "numReturns": 0, "type": "Function" }, "constructor_I_7": { @@ -195,7 +193,7 @@ } ], "entry": "Block0", - "returns": [], + "numReturns": 0, "type": "Function" }, "revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb": { @@ -220,7 +218,7 @@ } ], "entry": "Block0", - "returns": [], + "numReturns": 0, "type": "Function" } } @@ -442,7 +440,7 @@ } ], "entry": "Block0", - "returns": [], + "numReturns": 0, "type": "Function" }, "abi_encode_t_uint256_to_t_uint256_fromStack": { @@ -480,7 +478,7 @@ } ], "entry": "Block0", - "returns": [], + "numReturns": 0, "type": "Function" }, "abi_encode_tuple_t_uint256__to_t_uint256__fromStack": { @@ -531,9 +529,7 @@ } ], "entry": "Block0", - "returns": [ - "tail" - ], + "numReturns": 1, "type": "Function" }, "allocate_unbounded": { @@ -562,9 +558,7 @@ } ], "entry": "Block0", - "returns": [ - "memPtr" - ], + "numReturns": 1, "type": "Function" }, "cleanup_t_rational_42_by_1": { @@ -584,9 +578,7 @@ } ], "entry": "Block0", - "returns": [ - "cleaned" - ], + "numReturns": 1, "type": "Function" }, "cleanup_t_uint256": { @@ -606,9 +598,7 @@ } ], "entry": "Block0", - "returns": [ - "cleaned" - ], + "numReturns": 1, "type": "Function" }, "convert_t_rational_42_by_1_to_t_uint256": { @@ -657,9 +647,7 @@ } ], "entry": "Block0", - "returns": [ - "converted" - ], + "numReturns": 1, "type": "Function" }, "external_fun_f_18": { @@ -768,7 +756,7 @@ } ], "entry": "Block0", - "returns": [], + "numReturns": 0, "type": "Function" }, "fun_f_18": { @@ -804,9 +792,7 @@ } ], "entry": "Block0", - "returns": [ - "var__13" - ], + "numReturns": 1, "type": "Function" }, "identity": { @@ -826,9 +812,7 @@ } ], "entry": "Block0", - "returns": [ - "ret" - ], + "numReturns": 1, "type": "Function" }, "revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74": { @@ -853,7 +837,7 @@ } ], "entry": "Block0", - "returns": [], + "numReturns": 0, "type": "Function" }, "revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb": { @@ -878,7 +862,7 @@ } ], "entry": "Block0", - "returns": [], + "numReturns": 0, "type": "Function" }, "revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b": { @@ -903,7 +887,7 @@ } ], "entry": "Block0", - "returns": [], + "numReturns": 0, "type": "Function" }, "shift_right_224_unsigned": { @@ -935,9 +919,7 @@ } ], "entry": "Block0", - "returns": [ - "newValue" - ], + "numReturns": 1, "type": "Function" }, "zero_value_for_split_t_uint256": { @@ -955,9 +937,7 @@ } ], "entry": "Block0", - "returns": [ - "ret" - ], + "numReturns": 1, "type": "Function" } } @@ -1121,9 +1101,7 @@ } ], "entry": "Block0", - "returns": [ - "memPtr" - ], + "numReturns": 1, "type": "Function" }, "constructor_D_38": { @@ -1139,7 +1117,7 @@ } ], "entry": "Block0", - "returns": [], + "numReturns": 0, "type": "Function" }, "revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb": { @@ -1164,7 +1142,7 @@ } ], "entry": "Block0", - "returns": [], + "numReturns": 0, "type": "Function" } } @@ -1358,9 +1336,7 @@ } ], "entry": "Block0", - "returns": [ - "value" - ], + "numReturns": 1, "type": "Function" }, "abi_decode_tuple_": { @@ -1427,7 +1403,7 @@ } ], "entry": "Block0", - "returns": [], + "numReturns": 0, "type": "Function" }, "abi_decode_tuple_t_uint256_fromMemory": { @@ -1518,9 +1494,7 @@ } ], "entry": "Block0", - "returns": [ - "value0" - ], + "numReturns": 1, "type": "Function" }, "abi_encode_t_uint256_to_t_uint256_fromStack": { @@ -1558,7 +1532,7 @@ } ], "entry": "Block0", - "returns": [], + "numReturns": 0, "type": "Function" }, "abi_encode_tuple__to__fromStack": { @@ -1590,9 +1564,7 @@ } ], "entry": "Block0", - "returns": [ - "tail" - ], + "numReturns": 1, "type": "Function" }, "abi_encode_tuple_t_uint256__to_t_uint256__fromStack": { @@ -1643,9 +1615,7 @@ } ], "entry": "Block0", - "returns": [ - "tail" - ], + "numReturns": 1, "type": "Function" }, "allocate_unbounded": { @@ -1674,9 +1644,7 @@ } ], "entry": "Block0", - "returns": [ - "memPtr" - ], + "numReturns": 1, "type": "Function" }, "cleanup_t_uint160": { @@ -1708,9 +1676,7 @@ } ], "entry": "Block0", - "returns": [ - "cleaned" - ], + "numReturns": 1, "type": "Function" }, "cleanup_t_uint256": { @@ -1730,9 +1696,7 @@ } ], "entry": "Block0", - "returns": [ - "cleaned" - ], + "numReturns": 1, "type": "Function" }, "convert_t_contract$_C_$19_to_t_address": { @@ -1763,9 +1727,7 @@ } ], "entry": "Block0", - "returns": [ - "converted" - ], + "numReturns": 1, "type": "Function" }, "convert_t_uint160_to_t_address": { @@ -1796,9 +1758,7 @@ } ], "entry": "Block0", - "returns": [ - "converted" - ], + "numReturns": 1, "type": "Function" }, "convert_t_uint160_to_t_uint160": { @@ -1847,9 +1807,7 @@ } ], "entry": "Block0", - "returns": [ - "converted" - ], + "numReturns": 1, "type": "Function" }, "external_fun_f_37": { @@ -1958,7 +1916,7 @@ } ], "entry": "Block0", - "returns": [], + "numReturns": 0, "type": "Function" }, "finalize_allocation": { @@ -2064,7 +2022,7 @@ } ], "entry": "Block0", - "returns": [], + "numReturns": 0, "type": "Function" }, "fun_f_37": { @@ -2521,9 +2479,7 @@ } ], "entry": "Block0", - "returns": [ - "var__22" - ], + "numReturns": 1, "type": "Function" }, "identity": { @@ -2543,9 +2499,7 @@ } ], "entry": "Block0", - "returns": [ - "ret" - ], + "numReturns": 1, "type": "Function" }, "panic_error_0x41": { @@ -2586,7 +2540,7 @@ } ], "entry": "Block0", - "returns": [], + "numReturns": 0, "type": "Function" }, "revert_error_0cc013b6b3b6beabea4e3a74a6d380f0df81852ca99887912475e1f66b2a2c20": { @@ -2611,7 +2565,7 @@ } ], "entry": "Block0", - "returns": [], + "numReturns": 0, "type": "Function" }, "revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74": { @@ -2636,7 +2590,7 @@ } ], "entry": "Block0", - "returns": [], + "numReturns": 0, "type": "Function" }, "revert_error_c1322bf8034eace5e0b5c7295db60986aa89aae5e0ea0873e4689e076861a5db": { @@ -2661,7 +2615,7 @@ } ], "entry": "Block0", - "returns": [], + "numReturns": 0, "type": "Function" }, "revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb": { @@ -2686,7 +2640,7 @@ } ], "entry": "Block0", - "returns": [], + "numReturns": 0, "type": "Function" }, "revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b": { @@ -2711,7 +2665,7 @@ } ], "entry": "Block0", - "returns": [], + "numReturns": 0, "type": "Function" }, "revert_forward_1": { @@ -2766,7 +2720,7 @@ } ], "entry": "Block0", - "returns": [], + "numReturns": 0, "type": "Function" }, "round_up_to_mul_of_32": { @@ -2817,9 +2771,7 @@ } ], "entry": "Block0", - "returns": [ - "result" - ], + "numReturns": 1, "type": "Function" }, "shift_left_224": { @@ -2851,9 +2803,7 @@ } ], "entry": "Block0", - "returns": [ - "newValue" - ], + "numReturns": 1, "type": "Function" }, "shift_right_224_unsigned": { @@ -2885,9 +2835,7 @@ } ], "entry": "Block0", - "returns": [ - "newValue" - ], + "numReturns": 1, "type": "Function" }, "validator_revert_t_uint256": { @@ -2964,7 +2912,7 @@ } ], "entry": "Block0", - "returns": [], + "numReturns": 0, "type": "Function" }, "zero_value_for_split_t_uint256": { @@ -2982,9 +2930,7 @@ } ], "entry": "Block0", - "returns": [ - "ret" - ], + "numReturns": 1, "type": "Function" } } @@ -3141,9 +3087,7 @@ } ], "entry": "Block0", - "returns": [ - "memPtr" - ], + "numReturns": 1, "type": "Function" }, "constructor_C_19": { @@ -3166,7 +3110,7 @@ } ], "entry": "Block0", - "returns": [], + "numReturns": 0, "type": "Function" }, "constructor_I_7": { @@ -3182,7 +3126,7 @@ } ], "entry": "Block0", - "returns": [], + "numReturns": 0, "type": "Function" }, "revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb": { @@ -3207,7 +3151,7 @@ } ], "entry": "Block0", - "returns": [], + "numReturns": 0, "type": "Function" } } @@ -3429,7 +3373,7 @@ } ], "entry": "Block0", - "returns": [], + "numReturns": 0, "type": "Function" }, "abi_encode_t_uint256_to_t_uint256_fromStack": { @@ -3467,7 +3411,7 @@ } ], "entry": "Block0", - "returns": [], + "numReturns": 0, "type": "Function" }, "abi_encode_tuple_t_uint256__to_t_uint256__fromStack": { @@ -3518,9 +3462,7 @@ } ], "entry": "Block0", - "returns": [ - "tail" - ], + "numReturns": 1, "type": "Function" }, "allocate_unbounded": { @@ -3549,9 +3491,7 @@ } ], "entry": "Block0", - "returns": [ - "memPtr" - ], + "numReturns": 1, "type": "Function" }, "cleanup_t_rational_42_by_1": { @@ -3571,9 +3511,7 @@ } ], "entry": "Block0", - "returns": [ - "cleaned" - ], + "numReturns": 1, "type": "Function" }, "cleanup_t_uint256": { @@ -3593,9 +3531,7 @@ } ], "entry": "Block0", - "returns": [ - "cleaned" - ], + "numReturns": 1, "type": "Function" }, "convert_t_rational_42_by_1_to_t_uint256": { @@ -3644,9 +3580,7 @@ } ], "entry": "Block0", - "returns": [ - "converted" - ], + "numReturns": 1, "type": "Function" }, "external_fun_f_18": { @@ -3755,7 +3689,7 @@ } ], "entry": "Block0", - "returns": [], + "numReturns": 0, "type": "Function" }, "fun_f_18": { @@ -3791,9 +3725,7 @@ } ], "entry": "Block0", - "returns": [ - "var__13" - ], + "numReturns": 1, "type": "Function" }, "identity": { @@ -3813,9 +3745,7 @@ } ], "entry": "Block0", - "returns": [ - "ret" - ], + "numReturns": 1, "type": "Function" }, "revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74": { @@ -3840,7 +3770,7 @@ } ], "entry": "Block0", - "returns": [], + "numReturns": 0, "type": "Function" }, "revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb": { @@ -3865,7 +3795,7 @@ } ], "entry": "Block0", - "returns": [], + "numReturns": 0, "type": "Function" }, "revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b": { @@ -3890,7 +3820,7 @@ } ], "entry": "Block0", - "returns": [], + "numReturns": 0, "type": "Function" }, "shift_right_224_unsigned": { @@ -3922,9 +3852,7 @@ } ], "entry": "Block0", - "returns": [ - "newValue" - ], + "numReturns": 1, "type": "Function" }, "zero_value_for_split_t_uint256": { @@ -3942,9 +3870,7 @@ } ], "entry": "Block0", - "returns": [ - "ret" - ], + "numReturns": 1, "type": "Function" } } diff --git a/test/cmdlineTests/yul_cfg_json_export/output b/test/cmdlineTests/yul_cfg_json_export/output index d68997bff969..d8f2025b3ed3 100644 --- a/test/cmdlineTests/yul_cfg_json_export/output +++ b/test/cmdlineTests/yul_cfg_json_export/output @@ -153,9 +153,7 @@ Yul Control Flow Graph: } ], "entry": "Block0", - "returns": [ - "memPtr" - ], + "numReturns": 1, "type": "Function" }, "constructor_C_19": { @@ -178,7 +176,7 @@ Yul Control Flow Graph: } ], "entry": "Block0", - "returns": [], + "numReturns": 0, "type": "Function" }, "constructor_I_7": { @@ -194,7 +192,7 @@ Yul Control Flow Graph: } ], "entry": "Block0", - "returns": [], + "numReturns": 0, "type": "Function" }, "revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb": { @@ -219,7 +217,7 @@ Yul Control Flow Graph: } ], "entry": "Block0", - "returns": [], + "numReturns": 0, "type": "Function" } } @@ -441,7 +439,7 @@ Yul Control Flow Graph: } ], "entry": "Block0", - "returns": [], + "numReturns": 0, "type": "Function" }, "abi_encode_t_uint256_to_t_uint256_fromStack": { @@ -479,7 +477,7 @@ Yul Control Flow Graph: } ], "entry": "Block0", - "returns": [], + "numReturns": 0, "type": "Function" }, "abi_encode_tuple_t_uint256__to_t_uint256__fromStack": { @@ -530,9 +528,7 @@ Yul Control Flow Graph: } ], "entry": "Block0", - "returns": [ - "tail" - ], + "numReturns": 1, "type": "Function" }, "allocate_unbounded": { @@ -561,9 +557,7 @@ Yul Control Flow Graph: } ], "entry": "Block0", - "returns": [ - "memPtr" - ], + "numReturns": 1, "type": "Function" }, "cleanup_t_rational_42_by_1": { @@ -583,9 +577,7 @@ Yul Control Flow Graph: } ], "entry": "Block0", - "returns": [ - "cleaned" - ], + "numReturns": 1, "type": "Function" }, "cleanup_t_uint256": { @@ -605,9 +597,7 @@ Yul Control Flow Graph: } ], "entry": "Block0", - "returns": [ - "cleaned" - ], + "numReturns": 1, "type": "Function" }, "convert_t_rational_42_by_1_to_t_uint256": { @@ -656,9 +646,7 @@ Yul Control Flow Graph: } ], "entry": "Block0", - "returns": [ - "converted" - ], + "numReturns": 1, "type": "Function" }, "external_fun_f_18": { @@ -767,7 +755,7 @@ Yul Control Flow Graph: } ], "entry": "Block0", - "returns": [], + "numReturns": 0, "type": "Function" }, "fun_f_18": { @@ -803,9 +791,7 @@ Yul Control Flow Graph: } ], "entry": "Block0", - "returns": [ - "var__13" - ], + "numReturns": 1, "type": "Function" }, "identity": { @@ -825,9 +811,7 @@ Yul Control Flow Graph: } ], "entry": "Block0", - "returns": [ - "ret" - ], + "numReturns": 1, "type": "Function" }, "revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74": { @@ -852,7 +836,7 @@ Yul Control Flow Graph: } ], "entry": "Block0", - "returns": [], + "numReturns": 0, "type": "Function" }, "revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb": { @@ -877,7 +861,7 @@ Yul Control Flow Graph: } ], "entry": "Block0", - "returns": [], + "numReturns": 0, "type": "Function" }, "revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b": { @@ -902,7 +886,7 @@ Yul Control Flow Graph: } ], "entry": "Block0", - "returns": [], + "numReturns": 0, "type": "Function" }, "shift_right_224_unsigned": { @@ -934,9 +918,7 @@ Yul Control Flow Graph: } ], "entry": "Block0", - "returns": [ - "newValue" - ], + "numReturns": 1, "type": "Function" }, "zero_value_for_split_t_uint256": { @@ -954,9 +936,7 @@ Yul Control Flow Graph: } ], "entry": "Block0", - "returns": [ - "ret" - ], + "numReturns": 1, "type": "Function" } } @@ -1121,9 +1101,7 @@ Yul Control Flow Graph: } ], "entry": "Block0", - "returns": [ - "memPtr" - ], + "numReturns": 1, "type": "Function" }, "constructor_D_38": { @@ -1139,7 +1117,7 @@ Yul Control Flow Graph: } ], "entry": "Block0", - "returns": [], + "numReturns": 0, "type": "Function" }, "revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb": { @@ -1164,7 +1142,7 @@ Yul Control Flow Graph: } ], "entry": "Block0", - "returns": [], + "numReturns": 0, "type": "Function" } } @@ -1358,9 +1336,7 @@ Yul Control Flow Graph: } ], "entry": "Block0", - "returns": [ - "value" - ], + "numReturns": 1, "type": "Function" }, "abi_decode_tuple_": { @@ -1427,7 +1403,7 @@ Yul Control Flow Graph: } ], "entry": "Block0", - "returns": [], + "numReturns": 0, "type": "Function" }, "abi_decode_tuple_t_uint256_fromMemory": { @@ -1518,9 +1494,7 @@ Yul Control Flow Graph: } ], "entry": "Block0", - "returns": [ - "value0" - ], + "numReturns": 1, "type": "Function" }, "abi_encode_t_uint256_to_t_uint256_fromStack": { @@ -1558,7 +1532,7 @@ Yul Control Flow Graph: } ], "entry": "Block0", - "returns": [], + "numReturns": 0, "type": "Function" }, "abi_encode_tuple__to__fromStack": { @@ -1590,9 +1564,7 @@ Yul Control Flow Graph: } ], "entry": "Block0", - "returns": [ - "tail" - ], + "numReturns": 1, "type": "Function" }, "abi_encode_tuple_t_uint256__to_t_uint256__fromStack": { @@ -1643,9 +1615,7 @@ Yul Control Flow Graph: } ], "entry": "Block0", - "returns": [ - "tail" - ], + "numReturns": 1, "type": "Function" }, "allocate_unbounded": { @@ -1674,9 +1644,7 @@ Yul Control Flow Graph: } ], "entry": "Block0", - "returns": [ - "memPtr" - ], + "numReturns": 1, "type": "Function" }, "cleanup_t_uint160": { @@ -1708,9 +1676,7 @@ Yul Control Flow Graph: } ], "entry": "Block0", - "returns": [ - "cleaned" - ], + "numReturns": 1, "type": "Function" }, "cleanup_t_uint256": { @@ -1730,9 +1696,7 @@ Yul Control Flow Graph: } ], "entry": "Block0", - "returns": [ - "cleaned" - ], + "numReturns": 1, "type": "Function" }, "convert_t_contract$_C_$19_to_t_address": { @@ -1763,9 +1727,7 @@ Yul Control Flow Graph: } ], "entry": "Block0", - "returns": [ - "converted" - ], + "numReturns": 1, "type": "Function" }, "convert_t_uint160_to_t_address": { @@ -1796,9 +1758,7 @@ Yul Control Flow Graph: } ], "entry": "Block0", - "returns": [ - "converted" - ], + "numReturns": 1, "type": "Function" }, "convert_t_uint160_to_t_uint160": { @@ -1847,9 +1807,7 @@ Yul Control Flow Graph: } ], "entry": "Block0", - "returns": [ - "converted" - ], + "numReturns": 1, "type": "Function" }, "external_fun_f_37": { @@ -1958,7 +1916,7 @@ Yul Control Flow Graph: } ], "entry": "Block0", - "returns": [], + "numReturns": 0, "type": "Function" }, "finalize_allocation": { @@ -2064,7 +2022,7 @@ Yul Control Flow Graph: } ], "entry": "Block0", - "returns": [], + "numReturns": 0, "type": "Function" }, "fun_f_37": { @@ -2521,9 +2479,7 @@ Yul Control Flow Graph: } ], "entry": "Block0", - "returns": [ - "var__22" - ], + "numReturns": 1, "type": "Function" }, "identity": { @@ -2543,9 +2499,7 @@ Yul Control Flow Graph: } ], "entry": "Block0", - "returns": [ - "ret" - ], + "numReturns": 1, "type": "Function" }, "panic_error_0x41": { @@ -2586,7 +2540,7 @@ Yul Control Flow Graph: } ], "entry": "Block0", - "returns": [], + "numReturns": 0, "type": "Function" }, "revert_error_0cc013b6b3b6beabea4e3a74a6d380f0df81852ca99887912475e1f66b2a2c20": { @@ -2611,7 +2565,7 @@ Yul Control Flow Graph: } ], "entry": "Block0", - "returns": [], + "numReturns": 0, "type": "Function" }, "revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74": { @@ -2636,7 +2590,7 @@ Yul Control Flow Graph: } ], "entry": "Block0", - "returns": [], + "numReturns": 0, "type": "Function" }, "revert_error_c1322bf8034eace5e0b5c7295db60986aa89aae5e0ea0873e4689e076861a5db": { @@ -2661,7 +2615,7 @@ Yul Control Flow Graph: } ], "entry": "Block0", - "returns": [], + "numReturns": 0, "type": "Function" }, "revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb": { @@ -2686,7 +2640,7 @@ Yul Control Flow Graph: } ], "entry": "Block0", - "returns": [], + "numReturns": 0, "type": "Function" }, "revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b": { @@ -2711,7 +2665,7 @@ Yul Control Flow Graph: } ], "entry": "Block0", - "returns": [], + "numReturns": 0, "type": "Function" }, "revert_forward_1": { @@ -2766,7 +2720,7 @@ Yul Control Flow Graph: } ], "entry": "Block0", - "returns": [], + "numReturns": 0, "type": "Function" }, "round_up_to_mul_of_32": { @@ -2817,9 +2771,7 @@ Yul Control Flow Graph: } ], "entry": "Block0", - "returns": [ - "result" - ], + "numReturns": 1, "type": "Function" }, "shift_left_224": { @@ -2851,9 +2803,7 @@ Yul Control Flow Graph: } ], "entry": "Block0", - "returns": [ - "newValue" - ], + "numReturns": 1, "type": "Function" }, "shift_right_224_unsigned": { @@ -2885,9 +2835,7 @@ Yul Control Flow Graph: } ], "entry": "Block0", - "returns": [ - "newValue" - ], + "numReturns": 1, "type": "Function" }, "validator_revert_t_uint256": { @@ -2964,7 +2912,7 @@ Yul Control Flow Graph: } ], "entry": "Block0", - "returns": [], + "numReturns": 0, "type": "Function" }, "zero_value_for_split_t_uint256": { @@ -2982,9 +2930,7 @@ Yul Control Flow Graph: } ], "entry": "Block0", - "returns": [ - "ret" - ], + "numReturns": 1, "type": "Function" } } @@ -3141,9 +3087,7 @@ Yul Control Flow Graph: } ], "entry": "Block0", - "returns": [ - "memPtr" - ], + "numReturns": 1, "type": "Function" }, "constructor_C_19": { @@ -3166,7 +3110,7 @@ Yul Control Flow Graph: } ], "entry": "Block0", - "returns": [], + "numReturns": 0, "type": "Function" }, "constructor_I_7": { @@ -3182,7 +3126,7 @@ Yul Control Flow Graph: } ], "entry": "Block0", - "returns": [], + "numReturns": 0, "type": "Function" }, "revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb": { @@ -3207,7 +3151,7 @@ Yul Control Flow Graph: } ], "entry": "Block0", - "returns": [], + "numReturns": 0, "type": "Function" } } @@ -3429,7 +3373,7 @@ Yul Control Flow Graph: } ], "entry": "Block0", - "returns": [], + "numReturns": 0, "type": "Function" }, "abi_encode_t_uint256_to_t_uint256_fromStack": { @@ -3467,7 +3411,7 @@ Yul Control Flow Graph: } ], "entry": "Block0", - "returns": [], + "numReturns": 0, "type": "Function" }, "abi_encode_tuple_t_uint256__to_t_uint256__fromStack": { @@ -3518,9 +3462,7 @@ Yul Control Flow Graph: } ], "entry": "Block0", - "returns": [ - "tail" - ], + "numReturns": 1, "type": "Function" }, "allocate_unbounded": { @@ -3549,9 +3491,7 @@ Yul Control Flow Graph: } ], "entry": "Block0", - "returns": [ - "memPtr" - ], + "numReturns": 1, "type": "Function" }, "cleanup_t_rational_42_by_1": { @@ -3571,9 +3511,7 @@ Yul Control Flow Graph: } ], "entry": "Block0", - "returns": [ - "cleaned" - ], + "numReturns": 1, "type": "Function" }, "cleanup_t_uint256": { @@ -3593,9 +3531,7 @@ Yul Control Flow Graph: } ], "entry": "Block0", - "returns": [ - "cleaned" - ], + "numReturns": 1, "type": "Function" }, "convert_t_rational_42_by_1_to_t_uint256": { @@ -3644,9 +3580,7 @@ Yul Control Flow Graph: } ], "entry": "Block0", - "returns": [ - "converted" - ], + "numReturns": 1, "type": "Function" }, "external_fun_f_18": { @@ -3755,7 +3689,7 @@ Yul Control Flow Graph: } ], "entry": "Block0", - "returns": [], + "numReturns": 0, "type": "Function" }, "fun_f_18": { @@ -3791,9 +3725,7 @@ Yul Control Flow Graph: } ], "entry": "Block0", - "returns": [ - "var__13" - ], + "numReturns": 1, "type": "Function" }, "identity": { @@ -3813,9 +3745,7 @@ Yul Control Flow Graph: } ], "entry": "Block0", - "returns": [ - "ret" - ], + "numReturns": 1, "type": "Function" }, "revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74": { @@ -3840,7 +3770,7 @@ Yul Control Flow Graph: } ], "entry": "Block0", - "returns": [], + "numReturns": 0, "type": "Function" }, "revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb": { @@ -3865,7 +3795,7 @@ Yul Control Flow Graph: } ], "entry": "Block0", - "returns": [], + "numReturns": 0, "type": "Function" }, "revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b": { @@ -3890,7 +3820,7 @@ Yul Control Flow Graph: } ], "entry": "Block0", - "returns": [], + "numReturns": 0, "type": "Function" }, "shift_right_224_unsigned": { @@ -3922,9 +3852,7 @@ Yul Control Flow Graph: } ], "entry": "Block0", - "returns": [ - "newValue" - ], + "numReturns": 1, "type": "Function" }, "zero_value_for_split_t_uint256": { @@ -3942,9 +3870,7 @@ Yul Control Flow Graph: } ], "entry": "Block0", - "returns": [ - "ret" - ], + "numReturns": 1, "type": "Function" } } From c7621f9ceeef8879456d34df1216c0cba4f05d80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Fri, 1 Nov 2024 01:19:18 +0100 Subject: [PATCH 0555/1022] Refactor external benchmark downloader to reduce duplication --- test/benchmarks/external-setup.sh | 87 ++++++++++++++----------------- 1 file changed, 39 insertions(+), 48 deletions(-) diff --git a/test/benchmarks/external-setup.sh b/test/benchmarks/external-setup.sh index 2316d83d586e..451e766ddf52 100755 --- a/test/benchmarks/external-setup.sh +++ b/test/benchmarks/external-setup.sh @@ -40,56 +40,41 @@ function neutralize_via_ir { sed -i '/^via_ir\s*=.*$/d' foundry.toml } -mkdir -p "$BENCHMARK_DIR" -cd "$BENCHMARK_DIR" +function setup_foundry_project { + local subdir="$1" + local ref_type="$2" + local ref="$3" + local repo_url="$4" + local install_function="${5:-}" -if [[ ! -e openzeppelin/ ]]; then - git clone --depth=1 https://github.com/OpenZeppelin/openzeppelin-contracts openzeppelin/ --branch v5.0.2 - pushd openzeppelin/ - forge install - neutralize_via_ir - popd -else - echo "Skipped openzeppelin/. Already exists." -fi + printf ">>> %-22s | " "$subdir" -if [[ ! -e uniswap-v4/ ]]; then - git clone --single-branch https://github.com/Uniswap/v4-core uniswap-v4/ - pushd uniswap-v4/ - git checkout ae86975b058d386c9be24e8994236f662affacdb # branch main as of 2024-06-06 - forge install - neutralize_via_ir - popd -else - echo "Skipped uniswap-v4/. Already exists." -fi + [[ $ref_type == commit || $ref_type == tag ]] || assertFail -if [[ ! -e seaport/ ]]; then - git clone --single-branch https://github.com/ProjectOpenSea/seaport - pushd seaport/ - # NOTE: Can't select the tag with `git clone` because a branch of the same name exists. - git checkout tags/1.6 - forge install - neutralize_via_ir - neutralize_version_pragmas - popd -else - echo "Skipped seaport/. Already exists." -fi + [[ ! -e "$subdir" ]] || { printf "already exists\n"; return; } + printf "downloading...\n\n" + + if [[ $ref_type == tag ]]; then + git clone --depth=1 "$repo_url" "$subdir" --branch "$ref" + pushd "$subdir" + else + git clone "$repo_url" "$subdir" + pushd "$subdir" + git checkout "$ref" + fi + if [[ -z $install_function ]]; then + forge install + else + "$install_function" + fi -if [[ ! -e eigenlayer/ ]]; then - git clone --depth=1 https://github.com/Layr-Labs/eigenlayer-contracts eigenlayer/ --branch v0.3.0-holesky-rewards - pushd eigenlayer/ neutralize_via_ir - forge install + neutralize_version_pragmas popd -else - echo "Skipped eigenlayer/. Already exists." -fi + echo +} -if [[ ! -e sablier-v2/ ]]; then - git clone --depth=1 https://github.com/sablier-labs/v2-core sablier-v2/ --branch v1.1.2 - pushd sablier-v2/ +function install_sablier { # NOTE: To avoid hard-coding dependency versions here we'd have to install them from npm forge install --no-commit \ foundry-rs/forge-std@v1.5.6 \ @@ -106,8 +91,14 @@ forge-std/=lib/forge-std/ solarray/=lib/solarray/ solady/=lib/solady/ EOF - neutralize_via_ir - popd -else - echo "Skipped sablier-v2/. Already exists." -fi +} + +mkdir -p "$BENCHMARK_DIR" +cd "$BENCHMARK_DIR" + +setup_foundry_project openzeppelin/ tag v5.0.2 https://github.com/OpenZeppelin/openzeppelin-contracts +setup_foundry_project uniswap-v4/ commit ae86975b058d386c9be24e8994236f662affacdb https://github.com/Uniswap/v4-core +# NOTE: Can't select the tag with `git clone` because a branch of the same name exists. +setup_foundry_project seaport/ commit tags/1.6 https://github.com/ProjectOpenSea/seaport +setup_foundry_project eigenlayer/ tag v0.3.0-holesky-rewards https://github.com/Layr-Labs/eigenlayer-contracts +setup_foundry_project sablier-v2/ tag v1.1.2 https://github.com/sablier-labs/v2-core install_sablier From 897dbcce2d82e0e568a8d860c43a4ac3ba499ff3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Fri, 1 Nov 2024 01:19:18 +0100 Subject: [PATCH 0556/1022] Add liquity and farcaster as external benchmarks --- test/benchmarks/external-setup.sh | 7 +++++++ test/benchmarks/external.sh | 2 ++ 2 files changed, 9 insertions(+) diff --git a/test/benchmarks/external-setup.sh b/test/benchmarks/external-setup.sh index 451e766ddf52..30235c4785b2 100755 --- a/test/benchmarks/external-setup.sh +++ b/test/benchmarks/external-setup.sh @@ -74,6 +74,11 @@ function setup_foundry_project { echo } +function install_liquity { + sed -i -e 's|git@github.com:|https://github.com/|g' .gitmodules + forge install +} + function install_sablier { # NOTE: To avoid hard-coding dependency versions here we'd have to install them from npm forge install --no-commit \ @@ -97,8 +102,10 @@ mkdir -p "$BENCHMARK_DIR" cd "$BENCHMARK_DIR" setup_foundry_project openzeppelin/ tag v5.0.2 https://github.com/OpenZeppelin/openzeppelin-contracts +setup_foundry_project liquity/ commit 7f93a3f1781dfce2c4e0b6a7262deddd8a10e45b https://github.com/liquity/V2-gov install_liquity setup_foundry_project uniswap-v4/ commit ae86975b058d386c9be24e8994236f662affacdb https://github.com/Uniswap/v4-core # NOTE: Can't select the tag with `git clone` because a branch of the same name exists. setup_foundry_project seaport/ commit tags/1.6 https://github.com/ProjectOpenSea/seaport setup_foundry_project eigenlayer/ tag v0.3.0-holesky-rewards https://github.com/Layr-Labs/eigenlayer-contracts +setup_foundry_project farcaster/ tag v3.1.0 https://github.com/farcasterxyz/contracts setup_foundry_project sablier-v2/ tag v1.1.2 https://github.com/sablier-labs/v2-core install_sablier diff --git a/test/benchmarks/external.sh b/test/benchmarks/external.sh index 9acaccb67f79..3f5fe0bbfd5b 100755 --- a/test/benchmarks/external.sh +++ b/test/benchmarks/external.sh @@ -77,9 +77,11 @@ function benchmark_project { benchmarks=( # Fastest ones first so that we get *some* output quickly openzeppelin + liquity uniswap-v4 eigenlayer seaport + farcaster sablier-v2 ) From 14f0c6edc294775a5f12e41851f8b0bfae254ce3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Fri, 1 Nov 2024 01:19:18 +0100 Subject: [PATCH 0557/1022] Add older OpenZeppelin and Uniswap versions to external benchmarks - Also use explicit versions for all projects --- test/benchmarks/external-setup.sh | 33 +++++++++++++++++++++++-------- test/benchmarks/external.sh | 24 ++++++++++++---------- 2 files changed, 39 insertions(+), 18 deletions(-) diff --git a/test/benchmarks/external-setup.sh b/test/benchmarks/external-setup.sh index 30235c4785b2..bbba60bad6fc 100755 --- a/test/benchmarks/external-setup.sh +++ b/test/benchmarks/external-setup.sh @@ -68,7 +68,7 @@ function setup_foundry_project { "$install_function" fi - neutralize_via_ir + [[ ! -e foundry.toml ]] || neutralize_via_ir neutralize_version_pragmas popd echo @@ -79,6 +79,13 @@ function install_liquity { forge install } +function install_old_uniswap { + openzeppelin_version=$(sed -n 's|\s\+"@openzeppelin/contracts": "\([0-9.]\+\)"|\1|p' package.json) + rm package.json + rm yarn.lock + npm install "@openzeppelin/contracts@${openzeppelin_version}" +} + function install_sablier { # NOTE: To avoid hard-coding dependency versions here we'd have to install them from npm forge install --no-commit \ @@ -101,11 +108,21 @@ EOF mkdir -p "$BENCHMARK_DIR" cd "$BENCHMARK_DIR" -setup_foundry_project openzeppelin/ tag v5.0.2 https://github.com/OpenZeppelin/openzeppelin-contracts -setup_foundry_project liquity/ commit 7f93a3f1781dfce2c4e0b6a7262deddd8a10e45b https://github.com/liquity/V2-gov install_liquity -setup_foundry_project uniswap-v4/ commit ae86975b058d386c9be24e8994236f662affacdb https://github.com/Uniswap/v4-core +setup_foundry_project openzeppelin-5.0.2/ tag v5.0.2 https://github.com/OpenZeppelin/openzeppelin-contracts +setup_foundry_project openzeppelin-4.9.0/ tag v4.9.0 https://github.com/OpenZeppelin/openzeppelin-contracts +setup_foundry_project openzeppelin-4.8.0/ tag v4.8.0 https://github.com/OpenZeppelin/openzeppelin-contracts +setup_foundry_project openzeppelin-4.7.0/ tag v4.7.0 https://github.com/OpenZeppelin/openzeppelin-contracts + +setup_foundry_project liquity-2024-10-30/ commit 7f93a3f1781dfce2c4e0b6a7262deddd8a10e45b https://github.com/liquity/V2-gov install_liquity + +setup_foundry_project uniswap-v4-2024-06-06/ commit ae86975b058d386c9be24e8994236f662affacdb https://github.com/Uniswap/v4-core +setup_foundry_project uniswap-v4-2022-06-16/ commit 9aeddf76e1b8646908fbcc7519c882bf458b794d https://github.com/Uniswap/v4-core install_old_uniswap + +setup_foundry_project farcaster-3.1.0/ tag v3.1.0 https://github.com/farcasterxyz/contracts + # NOTE: Can't select the tag with `git clone` because a branch of the same name exists. -setup_foundry_project seaport/ commit tags/1.6 https://github.com/ProjectOpenSea/seaport -setup_foundry_project eigenlayer/ tag v0.3.0-holesky-rewards https://github.com/Layr-Labs/eigenlayer-contracts -setup_foundry_project farcaster/ tag v3.1.0 https://github.com/farcasterxyz/contracts -setup_foundry_project sablier-v2/ tag v1.1.2 https://github.com/sablier-labs/v2-core install_sablier +setup_foundry_project seaport-1.6/ commit tags/1.6 https://github.com/ProjectOpenSea/seaport + +setup_foundry_project eigenlayer-0.3.0/ tag v0.3.0-holesky-rewards https://github.com/Layr-Labs/eigenlayer-contracts + +setup_foundry_project sablier-v2-1.1.2/ tag v1.1.2 https://github.com/sablier-labs/v2-core install_sablier diff --git a/test/benchmarks/external.sh b/test/benchmarks/external.sh index 3f5fe0bbfd5b..16e47ee4fb38 100755 --- a/test/benchmarks/external.sh +++ b/test/benchmarks/external.sh @@ -65,7 +65,7 @@ function benchmark_project { > /dev/null \ 2> "../stderr-${project}-${pipeline}.log" || true - printf '| %-20s | %8s | %6d s | %9d MiB | %9d |\n' \ + printf '| %-21s | %8s | %6d s | %9d MiB | %9d |\n' \ "$project" \ "$pipeline" \ "$(jq '(.user + .sys) | round' "$time_file")" \ @@ -76,20 +76,24 @@ function benchmark_project { benchmarks=( # Fastest ones first so that we get *some* output quickly - openzeppelin - liquity - uniswap-v4 - eigenlayer - seaport - farcaster - sablier-v2 + uniswap-v4-2022-06-16 # compiles via IR with solc >=0.8.12 + openzeppelin-5.0.2 # compiles via IR with solc >=0.8.26 + openzeppelin-4.9.0 # compiles via IR with solc 0.8.10-0.8.14 and >=0.8.26 + liquity-2024-10-30 # compiles via IR with solc >=0.8.24 + openzeppelin-4.7.0 # compiles via IR with solc >=0.8.10 + openzeppelin-4.8.0 # compiles via IR with solc >=0.8.10 + uniswap-v4-2024-06-06 # compiles via IR with solc >=0.8.24 + eigenlayer-0.3.0 # compiles via IR with solc >=0.8.18 + seaport-1.6 # StackTooDeep via IR + farcaster-3.1.0 # StackTooDeep via IR + sablier-v2-1.1.2 # StackTooDeep via IR ) mkdir -p "$BENCHMARK_DIR" cd "$BENCHMARK_DIR" -echo "| File | Pipeline | Time | Memory (peak) | Exit code |" -echo "|----------------------|----------|---------:|--------------:|----------:|" +echo "| File | Pipeline | Time | Memory (peak) | Exit code |" +echo "|-----------------------|----------|---------:|--------------:|----------:|" for project in "${benchmarks[@]}"; do benchmark_project legacy "$project" From 249c3357f2b51de7d4468858dd575985ad510962 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Fri, 1 Nov 2024 04:41:29 +0100 Subject: [PATCH 0558/1022] Switch to a more recent Sablier version that does compile in external benchmarks --- test/benchmarks/external-setup.sh | 12 +++++------- test/benchmarks/external.sh | 2 +- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/test/benchmarks/external-setup.sh b/test/benchmarks/external-setup.sh index bbba60bad6fc..9b82c5767cf7 100755 --- a/test/benchmarks/external-setup.sh +++ b/test/benchmarks/external-setup.sh @@ -89,17 +89,15 @@ function install_old_uniswap { function install_sablier { # NOTE: To avoid hard-coding dependency versions here we'd have to install them from npm forge install --no-commit \ - foundry-rs/forge-std@v1.5.6 \ - OpenZeppelin/openzeppelin-contracts@v4.9.2 \ - PaulRBerg/prb-math@v4.0.2 \ - PaulRBerg/prb-test@v0.6.4 \ + foundry-rs/forge-std@v1.8.2 \ + OpenZeppelin/openzeppelin-contracts@v5.0.2 \ + PaulRBerg/prb-math@v4.0.3 \ evmcheb/solarray@a547630 \ - Vectorized/solady@v0.0.129 + Vectorized/solady@v0.0.208 cat < remappings.txt @openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/ forge-std/=lib/forge-std/ @prb/math/=lib/prb-math/ -@prb/test/=lib/prb-test/ solarray/=lib/solarray/ solady/=lib/solady/ EOF @@ -125,4 +123,4 @@ setup_foundry_project seaport-1.6/ commit tags/1.6 https://github.com/ProjectOpe setup_foundry_project eigenlayer-0.3.0/ tag v0.3.0-holesky-rewards https://github.com/Layr-Labs/eigenlayer-contracts -setup_foundry_project sablier-v2-1.1.2/ tag v1.1.2 https://github.com/sablier-labs/v2-core install_sablier +setup_foundry_project sablier-v2-1.2.0/ tag v1.2.0 https://github.com/sablier-labs/v2-core install_sablier diff --git a/test/benchmarks/external.sh b/test/benchmarks/external.sh index 16e47ee4fb38..b003f0ba18d2 100755 --- a/test/benchmarks/external.sh +++ b/test/benchmarks/external.sh @@ -84,9 +84,9 @@ benchmarks=( openzeppelin-4.8.0 # compiles via IR with solc >=0.8.10 uniswap-v4-2024-06-06 # compiles via IR with solc >=0.8.24 eigenlayer-0.3.0 # compiles via IR with solc >=0.8.18 + sablier-v2-1.2.0 # compiles via IR with solc >=0.8.28 (maybe >=0.8.26) seaport-1.6 # StackTooDeep via IR farcaster-3.1.0 # StackTooDeep via IR - sablier-v2-1.1.2 # StackTooDeep via IR ) mkdir -p "$BENCHMARK_DIR" From eb7dc2169b58a59a0d57ea6ca61d2fa0b548c324 Mon Sep 17 00:00:00 2001 From: haoyang9804 Date: Fri, 18 Oct 2024 22:20:54 +0100 Subject: [PATCH 0559/1022] refine the doc about calldata --- docs/types/reference-types.rst | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/docs/types/reference-types.rst b/docs/types/reference-types.rst index 4a053d51beea..23119484d103 100644 --- a/docs/types/reference-types.rst +++ b/docs/types/reference-types.rst @@ -37,6 +37,14 @@ non-persistent area where function arguments are stored, and behaves mostly like data location can also be returned from functions, but it is not possible to allocate such types. +.. note:: + Arrays and structs with ``calldata`` location declared in a function body + or as its return parameters must be assigned before being used or returned. + There are certain cases in which non-trivial control flow is used and the compiler + can't properly detect the initialization. + A common workaround in such cases is to assign the affected variable to itself before + the correct initialization takes place. + .. note:: Prior to version 0.6.9 data location for reference-type arguments was limited to ``calldata`` in external functions, ``memory`` in public functions and either From 40e92c9d7dd526aa12a43e8a350344f81bf9bb9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Wed, 30 Oct 2024 20:45:21 +0100 Subject: [PATCH 0560/1022] Fix movableApartFromEffects flag for datacopy() builtin in Yul - Side effects should have been identical to those of `CODECOPY`, but movableApartFromEffects was different. --- libyul/backends/evm/EVMDialect.cpp | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/libyul/backends/evm/EVMDialect.cpp b/libyul/backends/evm/EVMDialect.cpp index 9de3e40fc598..d7167fc77eea 100644 --- a/libyul/backends/evm/EVMDialect.cpp +++ b/libyul/backends/evm/EVMDialect.cpp @@ -307,17 +307,7 @@ std::vector> createBuiltins(langutil::EVMVe "datacopy", 3, 0, - SideEffects{ - false, // movable - true, // movableApartFromEffects - false, // canBeRemoved - false, // canBeRemovedIfNotMSize - true, // cannotLoop - SideEffects::None, // otherState - SideEffects::None, // storage - SideEffects::Write, // memory - SideEffects::None // transientStorage - }, + EVMDialect::sideEffectsOfInstruction(evmasm::Instruction::CODECOPY), ControlFlowSideEffects::fromInstruction(evmasm::Instruction::CODECOPY), {}, []( From d9a231cb109a49043b0eca40ba01aa4a5735fa1d Mon Sep 17 00:00:00 2001 From: Hopium <135053852+Hopium21@users.noreply.github.com> Date: Wed, 20 Nov 2024 13:54:53 +0100 Subject: [PATCH 0561/1022] Fix minor text errors in READMEs and checklists (#15577) * Update README.md * Update ReviewChecklist.md * Update README.md --- .circleci/README.md | 2 +- README.md | 2 +- ReviewChecklist.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.circleci/README.md b/.circleci/README.md index 22b20bc8c267..cd1a88ab7c1f 100644 --- a/.circleci/README.md +++ b/.circleci/README.md @@ -2,7 +2,7 @@ ### Docker images -The docker images are build locally on the developer machine: +The docker images are built locally on the developer machine: ```sh cd .circleci/docker/ diff --git a/README.md b/README.md index 197259998fcd..2d8e023220ac 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ You can talk to us on Gitter and Matrix, tweet at us on X (previously Twitter) or create a new topic in the Solidity forum. Questions, feedback, and suggestions are welcome! -Solidity is a statically typed, contract-oriented, high-level language for implementing smart contracts on the Ethereum platform. +Solidity is a statically-typed, contract-oriented, high-level language for implementing smart contracts on the Ethereum platform. For a good overview and starting point, please check out the official [Solidity Language Portal](https://soliditylang.org). diff --git a/ReviewChecklist.md b/ReviewChecklist.md index 3f0af6f981d2..35563d890712 100644 --- a/ReviewChecklist.md +++ b/ReviewChecklist.md @@ -123,7 +123,7 @@ The following points are all covered by the coding style but come up so often th - If it is a bugfix: - [ ] **The PR must include tests that reproduce the bug.** - [ ] **Are there gaps in test coverage of the buggy feature?** Fill them by adding more tests. - - [ ] **Try to break it.** Can you of any similar features that could also be buggy? + - [ ] **Try to break it.** Can you think of any similar features that could also be buggy? Play with the repro and include prominent variants as separate test cases, even if they don't trigger a bug. - [ ] **Positive cases (code that compiles) should have a semantic test.** - [ ] **Negative cases (code with compilation errors) should have a syntax test.** From 8548a93197e83773847ad5d1c67853ef4667b3ef Mon Sep 17 00:00:00 2001 From: Martin Blicha Date: Thu, 14 Nov 2024 16:56:00 +0100 Subject: [PATCH 0562/1022] Yul: Avoid expensive check in frequently called function The equality comparison is called very often in CommonSubexpressionEliminator, presumably because it is the comparison operator used for the map `CommonSubexpressionEliminator::m_replacementCandidates`. The method `validLiteral` is nontrivial and should not be called (twice!) on every call to the equality comparison. --- libyul/optimiser/SyntacticalEquality.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/libyul/optimiser/SyntacticalEquality.cpp b/libyul/optimiser/SyntacticalEquality.cpp index 0f4aa6e337e1..73b4d5083c54 100644 --- a/libyul/optimiser/SyntacticalEquality.cpp +++ b/libyul/optimiser/SyntacticalEquality.cpp @@ -64,9 +64,8 @@ bool SyntacticallyEqual::expressionEqual(Identifier const& _lhs, Identifier cons } bool SyntacticallyEqual::expressionEqual(Literal const& _lhs, Literal const& _rhs) { - yulAssert(validLiteral(_lhs), "Invalid lhs literal during syntactical equality check"); - yulAssert(validLiteral(_rhs), "Invalid rhs literal during syntactical equality check"); - + assert(validLiteral(_lhs)); + assert(validLiteral(_rhs)); return _lhs.value == _rhs.value; } From 515001595266add692de272d433c0021767acd56 Mon Sep 17 00:00:00 2001 From: Martin Blicha Date: Thu, 14 Nov 2024 18:19:03 +0100 Subject: [PATCH 0563/1022] Yul: Avoid expensive check against std::regex when possible --- libyul/AsmParser.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/libyul/AsmParser.cpp b/libyul/AsmParser.cpp index f7741dfae924..26a4d386dddc 100644 --- a/libyul/AsmParser.cpp +++ b/libyul/AsmParser.cpp @@ -147,12 +147,17 @@ void Parser::fetchDebugDataFromComment() { solAssert(m_sourceNames.has_value(), ""); + std::string_view commentLiteral = m_scanner->currentCommentLiteral(); + if (commentLiteral.empty()) + { + m_astIDFromComment = std::nullopt; + return; + } static std::regex const tagRegex = std::regex( R"~~((?:^|\s+)(@[a-zA-Z0-9\-_]+)(?:\s+|$))~~", // tag, e.g: @src std::regex_constants::ECMAScript | std::regex_constants::optimize ); - std::string_view commentLiteral = m_scanner->currentCommentLiteral(); std::match_results match; langutil::SourceLocation originLocation = m_locationFromComment; From d282afcddf4deab86ef212046c4eab237429d463 Mon Sep 17 00:00:00 2001 From: Nikola Matic Date: Thu, 21 Nov 2024 08:30:30 +0100 Subject: [PATCH 0564/1022] Update package list before installing Python 2 --- .circleci/config.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index 0bd7932ce0eb..a39fad80b0a6 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1458,6 +1458,7 @@ jobs: - run: name: Install Python 2 and make it the default command: | + sudo apt update # python is used by node-gyp to build native modules (needed for Colony). # In the 14.x image node-gyp still requires Python 2. sudo apt install python2 --assume-yes --no-install-recommends From 48d40d5eaf97c835cf55896a7a161eedc57c57f9 Mon Sep 17 00:00:00 2001 From: Martin Blicha Date: Sun, 17 Nov 2024 04:24:06 +0100 Subject: [PATCH 0565/1022] AST: More efficient way to collect referenced source units Previous implementation of the method SourceUnit::referencedSourceUnits contained a subtle performance bug. Because the skip list was passed by value into the recursive call, the dependency graph of the imports were effectively traversed as if expanded into a full tree, instead of as a DAG (directed acyclic graph). An example to illustrate that previously the same source was visited more than once: Suppose `A.sol` imports `B.sol` and `C.sol` and both of these import `D.sol`. Previosuly, the method would process `A` by first recursing into `B` and then `C`. When processing `B`, the source `D` is processed and then added to the skip list. When the recursion returns from processing `B`, any changes made to the skip list there were discarded, so that during processing `C`, the source `D` is not find in the skip list and processed again. Now, in most cases the import/dependency graph is probably shallow or does not contain such diamond-like subgraphs, and the performance is not affected. However, for a deeper dependency graph with multiple layers of diamond-like subgraphs this quickly leads to very bad performance, because every source unit is visited a number of times equal to the number of paths by which the source unit is reachable from the root source unit. This change seems to shave off *tens* of seconds on **both** legacy and ir pipeline for `sablier-v2-1.2.0` project. --- libsolidity/ast/AST.cpp | 15 ++++++++++----- libsolidity/ast/AST.h | 6 ++++++ 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/libsolidity/ast/AST.cpp b/libsolidity/ast/AST.cpp index a3aab07fba29..b62ea3e2df8a 100644 --- a/libsolidity/ast/AST.cpp +++ b/libsolidity/ast/AST.cpp @@ -130,18 +130,23 @@ SourceUnitAnnotation& SourceUnit::annotation() const std::set SourceUnit::referencedSourceUnits(bool _recurse, std::set _skipList) const { std::set sourceUnits; + referencedSourceUnits(sourceUnits, _recurse, _skipList); + return sourceUnits; +} + +void SourceUnit::referencedSourceUnits(std::set& _referencedSourceUnits, bool _recurse, std::set& _skipList) const +{ for (ImportDirective const* importDirective: filteredNodes(nodes())) { auto const& sourceUnit = importDirective->annotation().sourceUnit; - if (!_skipList.count(sourceUnit)) + auto [skipListIt, notOnSkipListYet] = _skipList.insert(sourceUnit); + if (notOnSkipListYet) { - _skipList.insert(sourceUnit); - sourceUnits.insert(sourceUnit); + _referencedSourceUnits.insert(sourceUnit); if (_recurse) - sourceUnits += sourceUnit->referencedSourceUnits(true, _skipList); + sourceUnit->referencedSourceUnits(_referencedSourceUnits, true, _skipList); } } - return sourceUnits; } ImportAnnotation& ImportDirective::annotation() const diff --git a/libsolidity/ast/AST.h b/libsolidity/ast/AST.h index 727652f56000..0e2df8a900fc 100644 --- a/libsolidity/ast/AST.h +++ b/libsolidity/ast/AST.h @@ -193,6 +193,12 @@ class SourceUnit: public ASTNode, public ScopeOpener bool experimentalSolidity() const { return m_experimentalSolidity; } private: + void referencedSourceUnits( + std::set& _referencedSourceUnits, + bool _recurse, + std::set& _skipList + ) const; + std::optional m_licenseString; std::vector> m_nodes; bool m_experimentalSolidity = false; From 1d595b28df80d335afacbabe29e6036a887c1d08 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Wed, 20 Nov 2024 17:15:02 +0100 Subject: [PATCH 0566/1022] OptimiserSettings: fix mismatched docstrings on several settings --- libsolidity/interface/OptimiserSettings.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libsolidity/interface/OptimiserSettings.h b/libsolidity/interface/OptimiserSettings.h index 1ca46ccbc260..1f702851c066 100644 --- a/libsolidity/interface/OptimiserSettings.h +++ b/libsolidity/interface/OptimiserSettings.h @@ -149,11 +149,11 @@ struct OptimiserSettings /// Constant optimizer, which tries to find better representations that satisfy the given /// size/cost-trade-off. bool runConstantOptimiser = false; - /// Perform more efficient stack allocation for variables during code generation from Yul to bytecode. + /// Allow unchecked arithmetic when incrementing the counter of certain kinds of 'for' loop bool simpleCounterForLoopUncheckedIncrement = false; - /// Yul optimiser with default settings. Will only run on certain parts of the code for now. + /// Perform more efficient stack allocation for variables during code generation from Yul to bytecode. bool optimizeStackAllocation = false; - /// Allow unchecked arithmetic when incrementing the counter of certain kinds of 'for' loop + /// Yul optimiser with default settings. Will only run on certain parts of the code for now. bool runYulOptimiser = false; /// Sequence of optimisation steps to be performed by Yul optimiser. /// Note that there are some hard-coded steps in the optimiser and you cannot disable From 8a8b543dfdc247ed37ad688a557d649455e49f2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Wed, 20 Nov 2024 18:33:43 +0100 Subject: [PATCH 0567/1022] More precise description of optimizer settings and their defaults in the docs --- docs/using-the-compiler.rst | 84 +++++++++++++++++++------------------ 1 file changed, 44 insertions(+), 40 deletions(-) diff --git a/docs/using-the-compiler.rst b/docs/using-the-compiler.rst index b2fe490cc597..48151a637713 100644 --- a/docs/using-the-compiler.rst +++ b/docs/using-the-compiler.rst @@ -281,63 +281,67 @@ Input Description "remappings": [ ":g=/dir" ], // Optional: Optimizer settings "optimizer": { - // Disabled by default. - // NOTE: enabled=false still leaves some optimizations on. See comments below. - // WARNING: Before version 0.8.6 omitting the 'enabled' key was not equivalent to setting - // it to false and would actually disable all the optimizations. + // Turn on the optimizer. Optional. Default: false. + // NOTE: The state of the optimizer is fully determined by the 'details' dict and this setting + // only affects its defaults - when enabled, all components default to being enabled. + // The opposite is not true - there are several components that always default to being + // enabled an can only be explicitly disabled via 'details'. + // WARNING: Before version 0.8.6 omitting this setting was not equivalent to setting + // it to false and would result in all components being disabled instead. "enabled": true, - // Optimize for how many times you intend to run the code. + // Optimize for how many times you intend to run the code. Optional. Default: 200. // Lower values will optimize more for initial deployment cost, higher // values will optimize more for high-frequency usage. "runs": 200, - // Switch optimizer components on or off in detail. - // The "enabled" switch above provides two defaults which can be - // tweaked here. If "details" is given, "enabled" can be omitted. + // State of all optimizer components. Optional. + // Default values are determined by whether the optimizer is enabled or not. + // Note that the 'enabled' setting only affects the defaults here and has no effect when + // all values are provided explicitly. "details": { - // The peephole optimizer is always on if no details are given, - // use details to switch it off. + // Peephole optimizer (opcode-based). Optional. Default: true. + // NOTE: Always runs (even with optimization disabled) unless explicitly turned off here. "peephole": true, - // The inliner is always off if no details are given, - // use details to switch it on. + // Inliner (opcode-based). Optional. Default: true when optimization is enabled. "inliner": false, - // The unused jumpdest remover is always on if no details are given, - // use details to switch it off. + // Unused JUMPDEST remover (opcode-based). Optional. Default: true. + // NOTE: Always runs (even with optimization disabled) unless explicitly turned off here. "jumpdestRemover": true, - // Sometimes re-orders literals in commutative operations. + // Literal reordering (codegen-based). Optional. Default: true when optimization is enabled. + // Moves literals to the right of commutative binary operators during code generation, helping exploit associativity. "orderLiterals": false, - // Removes duplicate code blocks + // Block deduplicator (opcode-based). Optional. Default: true when optimization is enabled. + // Unifies assembly code blocks that share content. "deduplicate": false, - // Common subexpression elimination, this is the most complicated step but - // can also provide the largest gain. + // Common subexpression elimination (opcode-based). Optional. Default: true when optimization is enabled. + // This is the most complicated step but can also provide the largest gain. "cse": false, - // Optimize representation of literal numbers and strings in code. + // Constant optimizer (opcode-based). Optional. Default: true when optimization is enabled. + // Tries to find better representations of literal numbers and strings, that satisfy the + // size/cost trade-off determined by the 'runs' setting. "constantOptimizer": false, - // Use unchecked arithmetic when incrementing the counter of for loops - // under certain circumstances. It is always on if no details are given. + // Unchecked loop increment (codegen-based). Optional. Default: true. + // Use unchecked arithmetic when incrementing the counter of 'for' loops under certain circumstances. + // NOTE: Always runs (even with optimization disabled) unless explicitly turned off here. "simpleCounterForLoopUncheckedIncrement": true, - // The new Yul optimizer. Mostly operates on the code of ABI coder v2 - // and inline assembly. - // It is activated together with the global optimizer setting - // and can be deactivated here. - // Before Solidity 0.6.0 it had to be activated through this switch. + // Yul optimizer. Optional. Default: true when optimization is enabled. + // Used to optimize the IR produced by the Yul IR-based pipeline as well as inline assembly + // and utility Yul code generated by the compiler. + // NOTE: Before Solidity 0.6.0 the default was false. "yul": false, - // Tuning options for the Yul optimizer. + // Tuning options for the Yul optimizer. Optional. "yulDetails": { // Improve allocation of stack slots for variables, can free up stack slots early. - // Activated by default if the Yul optimizer is activated. + // Optional. Default: true if Yul optimizer is enabled. "stackAllocation": true, - // Select optimization steps to be applied. It is also possible to modify both the - // optimization sequence and the clean-up sequence. Instructions for each sequence - // are separated with the ":" delimiter and the values are provided in the form of - // optimization-sequence:clean-up-sequence. For more information see - // "The Optimizer > Selecting Optimizations". - // This field is optional, and if not provided, the default sequences for both - // optimization and clean-up are used. If only one of the sequences is provided - // the other will not be run. - // If only the delimiter ":" is provided then neither the optimization nor the clean-up - // sequence will be run. - // If set to an empty value, only the default clean-up sequence is used and - // no optimization steps are applied. + // Optimization step sequence. + // The general form of the value is "
:". + // The setting is optional and when omitted, default values are used for both sequences. + // If the value does not contain the ':' delimiter, it is interpreted as the main + // sequence and the default is used for the cleanup sequence. + // To make one of the sequences empty, the delimiter must be present at the first or last position. + // In particular if the whole value consists only of the delimiter, both sequences are empty. + // Note that there are several hard-coded steps that always run, even when both sequences are empty. + // For more information see "The Optimizer > Selecting Optimizations". "optimizerSteps": "dhfoDgvulfnTUtnIf..." } } From 379b7248b8c057eb6ca63ef6ed2fddd3543fdf4a Mon Sep 17 00:00:00 2001 From: rodiazet Date: Fri, 22 Nov 2024 13:26:01 +0100 Subject: [PATCH 0568/1022] eof: Implement relative jumps support --- libevmasm/Assembly.cpp | 25 +++- libevmasm/Assembly.h | 1 + libevmasm/AssemblyItem.cpp | 29 +++- libevmasm/AssemblyItem.h | 27 +++- libevmasm/BlockDeduplicator.cpp | 4 +- libevmasm/GasMeter.cpp | 2 + libevmasm/GasMeter.h | 1 + libevmasm/Instruction.cpp | 4 + libevmasm/Instruction.h | 5 + libevmasm/JumpdestRemover.cpp | 2 +- libevmasm/PeepholeOptimiser.cpp | 126 +++++++++++++++++- libevmasm/SemanticInformation.cpp | 12 +- liblangutil/EVMVersion.cpp | 2 + libyul/backends/evm/EthAssemblyAdapter.cpp | 25 +++- test/libyul/objectCompiler/eof/rjumps.yul | 40 ++++++ .../EVMInstructionInterpreter.cpp | 2 + 16 files changed, 289 insertions(+), 18 deletions(-) create mode 100644 test/libyul/objectCompiler/eof/rjumps.yul diff --git a/libevmasm/Assembly.cpp b/libevmasm/Assembly.cpp index 153ab547e9a8..fdc27241550b 100644 --- a/libevmasm/Assembly.cpp +++ b/libevmasm/Assembly.cpp @@ -1396,6 +1396,7 @@ LinkerObject const& Assembly::assembleEOF() const m_tagPositionsInBytecode = std::vector(m_usedTags, std::numeric_limits::max()); std::map dataSectionRef; + std::map tagRef; for (auto&& [codeSectionIndex, codeSection]: m_codeSections | ranges::views::enumerate) { @@ -1412,7 +1413,9 @@ LinkerObject const& Assembly::assembleEOF() const solAssert( item.instruction() != Instruction::DATALOADN && item.instruction() != Instruction::RETURNCONTRACT && - item.instruction() != Instruction::EOFCREATE + item.instruction() != Instruction::EOFCREATE && + item.instruction() != Instruction::RJUMP && + item.instruction() != Instruction::RJUMPI ); solAssert(!(item.instruction() >= Instruction::PUSH0 && item.instruction() <= Instruction::PUSH32)); ret.bytecode += assembleOperation(item); @@ -1427,6 +1430,14 @@ LinkerObject const& Assembly::assembleEOF() const ret.linkReferences.insert(linkRef); break; } + case RelativeJump: + case ConditionalRelativeJump: + { + ret.bytecode.push_back(static_cast(item.instruction())); + tagRef[ret.bytecode.size()] = item.relativeJumpTagID(); + appendBigEndianUint16(ret.bytecode, 0u); + break; + } case EOFCreate: { ret.bytecode.push_back(static_cast(Instruction::EOFCREATE)); @@ -1465,6 +1476,18 @@ LinkerObject const& Assembly::assembleEOF() const setBigEndianUint16(ret.bytecode, codeSectionSizePositions[codeSectionIndex], ret.bytecode.size() - sectionStart); } + for (auto const& [refPos, tagId]: tagRef) + { + solAssert(tagId < m_tagPositionsInBytecode.size(), "Reference to non-existing tag."); + size_t tagPos = m_tagPositionsInBytecode[tagId]; + solAssert(tagPos != std::numeric_limits::max(), "Reference to tag without position."); + + ptrdiff_t const relativeJumpOffset = static_cast(tagPos) - (static_cast(refPos) + 2); + solRequire(-0x8000 <= relativeJumpOffset && relativeJumpOffset <= 0x7FFF, AssemblyException, "Relative jump too far"); + solAssert(relativeJumpOffset < -2 || 0 <= relativeJumpOffset, "Relative jump offset into immediate argument."); + setBigEndianUint16(ret.bytecode, refPos, static_cast(static_cast(relativeJumpOffset))); + } + for (auto i: referencedSubIds) ret.bytecode += m_subs[i]->assemble().bytecode; diff --git a/libevmasm/Assembly.h b/libevmasm/Assembly.h index daeea6e8cf0e..4b52ca3d7970 100644 --- a/libevmasm/Assembly.h +++ b/libevmasm/Assembly.h @@ -65,6 +65,7 @@ class Assembly } std::optional eofVersion() const { return m_eofVersion; } + bool supportsRelativeJumps() const { return m_eofVersion.has_value(); } AssemblyItem newTag() { assertThrow(m_usedTags < 0xffffffff, AssemblyException, ""); return AssemblyItem(Tag, m_usedTags++); } AssemblyItem newPushTag() { assertThrow(m_usedTags < 0xffffffff, AssemblyException, ""); return AssemblyItem(PushTag, m_usedTags++); } /// Returns a tag identified by the given name. Creates it if it does not yet exist. diff --git a/libevmasm/AssemblyItem.cpp b/libevmasm/AssemblyItem.cpp index d26e01f8a7ab..96c007ea5ce7 100644 --- a/libevmasm/AssemblyItem.cpp +++ b/libevmasm/AssemblyItem.cpp @@ -62,13 +62,21 @@ AssemblyItem AssemblyItem::toSubAssemblyTag(size_t _subId) const std::pair AssemblyItem::splitForeignPushTag() const { - assertThrow(m_type == PushTag || m_type == Tag, util::Exception, ""); + solAssert(m_type == PushTag || m_type == Tag || m_type == RelativeJump || m_type == ConditionalRelativeJump); u256 combined = u256(data()); size_t subId = static_cast((combined >> 64) - 1); size_t tag = static_cast(combined & 0xffffffffffffffffULL); return std::make_pair(subId, tag); } +size_t AssemblyItem::relativeJumpTagID() const +{ + solAssert(m_type == RelativeJump || m_type == ConditionalRelativeJump); + auto const [subId, tagId] = splitForeignPushTag(); + solAssert(subId == std::numeric_limits::max(), "Relative jump to sub"); + return tagId; +} + std::pair AssemblyItem::nameAndData(langutil::EVMVersion _evmVersion) const { switch (type()) @@ -76,6 +84,8 @@ std::pair AssemblyItem::nameAndData(langutil::EVMVersi case Operation: case EOFCreate: case ReturnContract: + case RelativeJump: + case ConditionalRelativeJump: return {instructionInfo(instruction(), _evmVersion).name, m_data != nullptr ? toStringInHex(*m_data) : ""}; case Push: return {"PUSH", toStringInHex(data())}; @@ -115,7 +125,8 @@ std::pair AssemblyItem::nameAndData(langutil::EVMVersi void AssemblyItem::setPushTagSubIdAndTag(size_t _subId, size_t _tag) { - assertThrow(m_type == PushTag || m_type == Tag, util::Exception, ""); + solAssert(m_type == PushTag || m_type == Tag || m_type == RelativeJump || m_type == ConditionalRelativeJump); + solAssert(!(m_type == RelativeJump || m_type == ConditionalRelativeJump) || _subId == std::numeric_limits::max()); u256 data = _tag; if (_subId != std::numeric_limits::max()) data |= (u256(_subId) + 1) << 64; @@ -167,6 +178,8 @@ size_t AssemblyItem::bytesRequired(size_t _addressLength, langutil::EVMVersion _ } case VerbatimBytecode: return std::get<2>(*m_verbatimBytecode).size(); + case RelativeJump: + case ConditionalRelativeJump: case AuxDataLoadN: return 1 + 2; case EOFCreate: @@ -201,6 +214,8 @@ size_t AssemblyItem::returnValues() const case Operation: case EOFCreate: case ReturnContract: + case RelativeJump: + case ConditionalRelativeJump: // The latest EVMVersion is used here, since the InstructionInfo is assumed to be // the same across all EVM versions except for the instruction name. return static_cast(instructionInfo(instruction(), EVMVersion()).ret); @@ -236,6 +251,8 @@ bool AssemblyItem::canBeFunctional() const case Operation: case EOFCreate: case ReturnContract: + case RelativeJump: + case ConditionalRelativeJump: return !isDupInstruction(instruction()) && !isSwapInstruction(instruction()); case Push: case PushTag: @@ -360,6 +377,12 @@ std::string AssemblyItem::toAssemblyText(Assembly const& _assembly) const case ReturnContract: text = "returcontract{" + std::to_string(static_cast(data())) + "}"; break; + case RelativeJump: + text = "rjump{" + std::string("tag_") + std::to_string(relativeJumpTagID()) + "}"; + break; + case ConditionalRelativeJump: + text = "rjumpi{" + std::string("tag_") + std::to_string(relativeJumpTagID()) + "}"; + break; } if (m_jumpType == JumpType::IntoFunction || m_jumpType == JumpType::OutOfFunction) { @@ -380,6 +403,8 @@ std::ostream& solidity::evmasm::operator<<(std::ostream& _out, AssemblyItem cons case Operation: case EOFCreate: case ReturnContract: + case RelativeJump: + case ConditionalRelativeJump: _out << " " << instructionInfo(_item.instruction(), EVMVersion()).name; if (_item.instruction() == Instruction::JUMP || _item.instruction() == Instruction::JUMPI) _out << "\t" << _item.getJumpTypeAsString(); diff --git a/libevmasm/AssemblyItem.h b/libevmasm/AssemblyItem.h index e51d07b16150..a9c46bb14edb 100644 --- a/libevmasm/AssemblyItem.h +++ b/libevmasm/AssemblyItem.h @@ -57,6 +57,8 @@ enum AssemblyItemType AuxDataLoadN, EOFCreate, ///< Creates new contract using subcontainer as initcode ReturnContract, ///< Returns new container (with auxiliary data filled in) to be deployed + RelativeJump, ///< Jumps to relative position accordingly to its argument + ConditionalRelativeJump, ///< Same as RelativeJump but takes condition from the stack VerbatimBytecode ///< Contains data that is inserted into the bytecode code section without modification. }; @@ -111,20 +113,32 @@ class AssemblyItem { return AssemblyItem(ReturnContract, Instruction::RETURNCONTRACT, _containerID, std::move(_debugData)); } + static AssemblyItem relativeJumpTo(AssemblyItem _tag, langutil::DebugData::ConstPtr _debugData = langutil::DebugData::create()) + { + solAssert(_tag.type() == Tag); + return AssemblyItem(RelativeJump, Instruction::RJUMP, _tag.data(), _debugData); + } + static AssemblyItem conditionalRelativeJumpTo(AssemblyItem _tag, langutil::DebugData::ConstPtr _debugData = langutil::DebugData::create()) + { + solAssert(_tag.type() == Tag); + return AssemblyItem(ConditionalRelativeJump, Instruction::RJUMPI, _tag.data(), _debugData); + } AssemblyItem(AssemblyItem const&) = default; AssemblyItem(AssemblyItem&&) = default; AssemblyItem& operator=(AssemblyItem const&) = default; AssemblyItem& operator=(AssemblyItem&&) = default; - AssemblyItem tag() const { assertThrow(m_type == PushTag || m_type == Tag, util::Exception, ""); return AssemblyItem(Tag, data()); } - AssemblyItem pushTag() const { assertThrow(m_type == PushTag || m_type == Tag, util::Exception, ""); return AssemblyItem(PushTag, data()); } + AssemblyItem tag() const { solAssert(m_type == PushTag || m_type == Tag || m_type == RelativeJump || m_type == ConditionalRelativeJump); return AssemblyItem(Tag, data()); } + AssemblyItem pushTag() const { solAssert(m_type == PushTag || m_type == Tag || m_type == RelativeJump || m_type == ConditionalRelativeJump); return AssemblyItem(PushTag, data()); } /// Converts the tag to a subassembly tag. This has to be called in order to move a tag across assemblies. /// @param _subId the identifier of the subassembly the tag is taken from. AssemblyItem toSubAssemblyTag(size_t _subId) const; /// @returns splits the data of the push tag into sub assembly id and actual tag id. /// The sub assembly id of non-foreign push tags is -1. std::pair splitForeignPushTag() const; + /// @returns relative jump target tag ID. Asserts that it is not foreign tag. + size_t relativeJumpTagID() const; /// Sets sub-assembly part and tag for a push tag. void setPushTagSubIdAndTag(size_t _subId, size_t _tag); @@ -145,9 +159,14 @@ class AssemblyItem /// @returns true if the item has m_instruction properly set. bool hasInstruction() const { - return m_type == Operation || m_type == EOFCreate || m_type == ReturnContract; + return + m_type == Operation || + m_type == EOFCreate || + m_type == ReturnContract || + m_type == RelativeJump || + m_type == ConditionalRelativeJump; } - /// @returns the instruction of this item (only valid if type() == Operation || EOFCreate || ReturnContract) + /// @returns the instruction of this item (only valid if hasInstruction returns true) Instruction instruction() const { solAssert(hasInstruction()); diff --git a/libevmasm/BlockDeduplicator.cpp b/libevmasm/BlockDeduplicator.cpp index c978bae2bb39..3ba8cfcd3523 100644 --- a/libevmasm/BlockDeduplicator.cpp +++ b/libevmasm/BlockDeduplicator.cpp @@ -106,7 +106,7 @@ bool BlockDeduplicator::applyTagReplacement( { bool changed = false; for (AssemblyItem& item: _items) - if (item.type() == PushTag) + if (item.type() == PushTag || item.type() == RelativeJump || item.type() == ConditionalRelativeJump) { size_t subId; size_t tagId; @@ -131,7 +131,7 @@ BlockDeduplicator::BlockIterator& BlockDeduplicator::BlockIterator::operator++() { if (it == end) return *this; - if (SemanticInformation::altersControlFlow(*it) && *it != AssemblyItem{Instruction::JUMPI}) + if (SemanticInformation::altersControlFlow(*it) && *it != AssemblyItem{Instruction::JUMPI} && it->type() != ConditionalRelativeJump) it = end; else { diff --git a/libevmasm/GasMeter.cpp b/libevmasm/GasMeter.cpp index a501b487f45a..3ee3a39cbdc4 100644 --- a/libevmasm/GasMeter.cpp +++ b/libevmasm/GasMeter.cpp @@ -272,6 +272,8 @@ unsigned GasMeter::runGas(Instruction _instruction, langutil::EVMVersion _evmVer { case Tier::Zero: return GasCosts::tier0Gas; case Tier::Base: return GasCosts::tier1Gas; + case Tier::RJump: return GasCosts::tier1Gas; + case Tier::RJumpI: return GasCosts::rjumpiGas; case Tier::VeryLow: return GasCosts::tier2Gas; case Tier::Low: return GasCosts::tier3Gas; case Tier::Mid: return GasCosts::tier4Gas; diff --git a/libevmasm/GasMeter.h b/libevmasm/GasMeter.h index 50a783e1a6e5..f202b358e5f0 100644 --- a/libevmasm/GasMeter.h +++ b/libevmasm/GasMeter.h @@ -177,6 +177,7 @@ namespace GasCosts return _evmVersion >= langutil::EVMVersion::istanbul() ? 16 : 68; } static unsigned const copyGas = 3; + static unsigned const rjumpiGas = 4; } /** diff --git a/libevmasm/Instruction.cpp b/libevmasm/Instruction.cpp index 5122fb01f604..60ec75f9284e 100644 --- a/libevmasm/Instruction.cpp +++ b/libevmasm/Instruction.cpp @@ -169,6 +169,8 @@ std::map const solidity::evmasm::c_instructions = { "LOG3", Instruction::LOG3 }, { "LOG4", Instruction::LOG4 }, { "DATALOADN", Instruction::DATALOADN }, + { "RJUMP", Instruction::RJUMP }, + { "RJUMPI", Instruction::RJUMPI }, { "EOFCREATE", Instruction::EOFCREATE }, { "RETURNCONTRACT", Instruction::RETURNCONTRACT }, { "CREATE", Instruction::CREATE }, @@ -256,6 +258,8 @@ static std::map const c_instructionInfo = {Instruction::GAS, {"GAS", 0, 0, 1, false, Tier::Base}}, {Instruction::JUMPDEST, {"JUMPDEST", 0, 0, 0, true, Tier::Special}}, {Instruction::DATALOADN, {"DATALOADN", 2, 0, 1, true, Tier::Low}}, + {Instruction::RJUMP, {"RJUMP", 2, 0, 0, true, Tier::RJump}}, + {Instruction::RJUMPI, {"RJUMPI", 2, 1, 0, true, Tier::RJumpI}}, {Instruction::PUSH0, {"PUSH0", 0, 0, 1, false, Tier::Base}}, {Instruction::PUSH1, {"PUSH1", 1, 0, 1, false, Tier::VeryLow}}, {Instruction::PUSH2, {"PUSH2", 2, 0, 1, false, Tier::VeryLow}}, diff --git a/libevmasm/Instruction.h b/libevmasm/Instruction.h index d9e96c49ad48..76998c538d5f 100644 --- a/libevmasm/Instruction.h +++ b/libevmasm/Instruction.h @@ -183,6 +183,9 @@ enum class Instruction: uint8_t LOG4, ///< Makes a log entry; 4 topics. DATALOADN = 0xd1, ///< load data from EOF data section + + RJUMP = 0xe0, ///< relative jump + RJUMPI = 0xe1, ///< conditional relative jump EOFCREATE = 0xec, ///< create a new account with associated container code. RETURNCONTRACT = 0xee, ///< return container to be deployed with axiliary data filled in. CREATE = 0xf0, ///< create a new account with associated code @@ -298,7 +301,9 @@ enum class Tier // NOTE: Tiers should be ordered by cost, since we sometimes perform comparisons between them. Zero = 0, // 0, Zero Base, // 2, Quick + RJump, // 2, RJump VeryLow, // 3, Fastest + RJumpI, // 4, Low, // 5, Fast Mid, // 8, Mid High, // 10, Slow diff --git a/libevmasm/JumpdestRemover.cpp b/libevmasm/JumpdestRemover.cpp index 7afa715a88df..7ded5ae90889 100644 --- a/libevmasm/JumpdestRemover.cpp +++ b/libevmasm/JumpdestRemover.cpp @@ -58,7 +58,7 @@ std::set JumpdestRemover::referencedTags(AssemblyItems const& _items, si { std::set ret; for (auto const& item: _items) - if (item.type() == PushTag) + if (item.type() == PushTag || item.type() == RelativeJump || item.type() == ConditionalRelativeJump) { auto subAndTag = item.splitForeignPushTag(); if (subAndTag.first == _subId) diff --git a/libevmasm/PeepholeOptimiser.cpp b/libevmasm/PeepholeOptimiser.cpp index 40937e73f107..64650eaeea9f 100644 --- a/libevmasm/PeepholeOptimiser.cpp +++ b/libevmasm/PeepholeOptimiser.cpp @@ -328,6 +328,29 @@ struct IsZeroIsZeroJumpI: SimplePeepholeOptimizerMethod } }; +struct IsZeroIsZeroRJumpI: SimplePeepholeOptimizerMethod +{ + static size_t applySimple( + AssemblyItem const& _iszero1, + AssemblyItem const& _iszero2, + AssemblyItem const& _rjumpi, + std::back_insert_iterator _out + ) + { + if ( + _iszero1 == Instruction::ISZERO && + _iszero2 == Instruction::ISZERO && + _rjumpi.type() == ConditionalRelativeJump + ) + { + *_out = _rjumpi; + return true; + } + else + return false; + } +}; + struct EqIsZeroJumpI: SimplePeepholeOptimizerMethod { static size_t applySimple( @@ -355,6 +378,30 @@ struct EqIsZeroJumpI: SimplePeepholeOptimizerMethod } }; +struct EqIsZeroRJumpI: SimplePeepholeOptimizerMethod +{ + static size_t applySimple( + AssemblyItem const& _eq, + AssemblyItem const& _iszero, + AssemblyItem const& _rjumpi, + std::back_insert_iterator _out + ) + { + if ( + _eq == Instruction::EQ && + _iszero == Instruction::ISZERO && + _rjumpi.type() == ConditionalRelativeJump + ) + { + *_out = AssemblyItem(Instruction::SUB, _eq.debugData()); + *_out = _rjumpi; + return true; + } + else + return false; + } +}; + // push_tag_1 jumpi push_tag_2 jump tag_1: -> iszero push_tag_2 jumpi tag_1: struct DoubleJump: SimplePeepholeOptimizerMethod { @@ -387,6 +434,33 @@ struct DoubleJump: SimplePeepholeOptimizerMethod } }; +// rjumpi(tag_1) rjump(tag_2) tag_1: -> iszero rjumpi(tag_2) tag_1: +struct DoubleRJump: SimplePeepholeOptimizerMethod +{ + static size_t applySimple( + AssemblyItem const& _rjumpi, + AssemblyItem const& _rjump, + AssemblyItem const& _tag1, + std::back_insert_iterator _out + ) + { + if ( + _rjumpi.type() == ConditionalRelativeJump && + _rjump.type() == RelativeJump && + _tag1.type() == Tag && + _rjumpi.data() == _tag1.data() + ) + { + *_out = AssemblyItem(Instruction::ISZERO, _rjumpi.debugData()); + *_out = AssemblyItem::conditionalRelativeJumpTo(_rjump.tag(), _rjump.debugData()); + *_out = _tag1; + return true; + } + else + return false; + } +}; + struct JumpToNext: SimplePeepholeOptimizerMethod { static size_t applySimple( @@ -413,6 +487,30 @@ struct JumpToNext: SimplePeepholeOptimizerMethod } }; +struct RJumpToNext: SimplePeepholeOptimizerMethod +{ + static size_t applySimple( + AssemblyItem const& _rjump, + AssemblyItem const& _tag, + std::back_insert_iterator _out + ) + { + if ( + (_rjump.type() == ConditionalRelativeJump || _rjump.type() == RelativeJump) && + _tag.type() == Tag && + _rjump.data() == _tag.data() + ) + { + if (_rjump.type() == ConditionalRelativeJump) + *_out = AssemblyItem(Instruction::POP, _rjump.debugData()); + *_out = _tag; + return true; + } + else + return false; + } +}; + struct TagConjunctions: SimplePeepholeOptimizerMethod { static bool applySimple( @@ -476,6 +574,7 @@ struct UnreachableCode return false; if ( it[0] != Instruction::JUMP && + it[0] != Instruction::RJUMP && it[0] != Instruction::RETURN && it[0] != Instruction::STOP && it[0] != Instruction::INVALID && @@ -618,9 +717,30 @@ bool PeepholeOptimiser::optimise() while (state.i < m_items.size()) applyMethods( state, - PushPop(), OpPop(), OpStop(), OpReturnRevert(), DoublePush(), DoubleSwap(), CommutativeSwap(), SwapComparison(), - DupSwap(), IsZeroIsZeroJumpI(), EqIsZeroJumpI(), DoubleJump(), JumpToNext(), UnreachableCode(), DeduplicateNextTagSize3(), - DeduplicateNextTagSize2(), DeduplicateNextTagSize1(), TagConjunctions(), TruthyAnd(), Identity() + PushPop(), + OpPop(), + OpStop(), + OpReturnRevert(), + DoublePush(), + DoubleSwap(), + CommutativeSwap(), + SwapComparison(), + DupSwap(), + IsZeroIsZeroJumpI(), + IsZeroIsZeroRJumpI(), // EOF specific + EqIsZeroJumpI(), + EqIsZeroRJumpI(), // EOF specific + DoubleJump(), + DoubleRJump(), // EOF specific + JumpToNext(), + RJumpToNext(), // EOF specific + UnreachableCode(), + DeduplicateNextTagSize3(), + DeduplicateNextTagSize2(), + DeduplicateNextTagSize1(), + TagConjunctions(), + TruthyAnd(), + Identity() ); if (m_optimisedItems.size() < m_items.size() || ( m_optimisedItems.size() == m_items.size() && ( diff --git a/libevmasm/SemanticInformation.cpp b/libevmasm/SemanticInformation.cpp index e909a7074dbb..99a5a0f4348e 100644 --- a/libevmasm/SemanticInformation.cpp +++ b/libevmasm/SemanticInformation.cpp @@ -303,7 +303,13 @@ bool SemanticInformation::isSwapInstruction(AssemblyItem const& _item) bool SemanticInformation::isJumpInstruction(AssemblyItem const& _item) { - return _item == Instruction::JUMP || _item == Instruction::JUMPI; + return + _item == Instruction::JUMP || + _item == Instruction::JUMPI || + _item == Instruction::RJUMP || + _item == Instruction::RJUMPI || + _item.type() == RelativeJump || + _item.type() == ConditionalRelativeJump; } bool SemanticInformation::altersControlFlow(AssemblyItem const& _item) @@ -317,6 +323,8 @@ bool SemanticInformation::altersControlFlow(AssemblyItem const& _item) // continue on the next instruction case Instruction::JUMP: case Instruction::JUMPI: + case Instruction::RJUMP: + case Instruction::RJUMPI: case Instruction::RETURN: case Instruction::SELFDESTRUCT: case Instruction::STOP: @@ -613,6 +621,8 @@ bool SemanticInformation::invalidInPureFunctions(Instruction _instruction) bool SemanticInformation::invalidInViewFunctions(Instruction _instruction) { + // Relative jumps cannot jump out of the current code section of EOF so they are valid in view functions + // (under the assumption that every Solidity function actually gets its own code section). switch (_instruction) { case Instruction::SSTORE: diff --git a/liblangutil/EVMVersion.cpp b/liblangutil/EVMVersion.cpp index 9041ae793492..f469f337d632 100644 --- a/liblangutil/EVMVersion.cpp +++ b/liblangutil/EVMVersion.cpp @@ -80,6 +80,8 @@ bool EVMVersion::hasOpcode(Instruction _opcode, std::optional _eofVersi case Instruction::EOFCREATE: case Instruction::RETURNCONTRACT: case Instruction::DATALOADN: + case Instruction::RJUMP: + case Instruction::RJUMPI: return _eofVersion.has_value(); default: return true; diff --git a/libyul/backends/evm/EthAssemblyAdapter.cpp b/libyul/backends/evm/EthAssemblyAdapter.cpp index 604177c4f78a..d8810b261db3 100644 --- a/libyul/backends/evm/EthAssemblyAdapter.cpp +++ b/libyul/backends/evm/EthAssemblyAdapter.cpp @@ -106,14 +106,31 @@ void EthAssemblyAdapter::appendJump(int _stackDiffAfter, JumpType _jumpType) void EthAssemblyAdapter::appendJumpTo(LabelID _labelId, int _stackDiffAfter, JumpType _jumpType) { - appendLabelReference(_labelId); - appendJump(_stackDiffAfter, _jumpType); + if (m_assembly.supportsRelativeJumps()) + { + m_assembly.append(evmasm::AssemblyItem::relativeJumpTo(evmasm::AssemblyItem(evmasm::Tag, _labelId))); + yulAssert(_jumpType == JumpType::Ordinary); + m_assembly.adjustDeposit(_stackDiffAfter); + } + else + { + appendLabelReference(_labelId); + appendJump(_stackDiffAfter, _jumpType); + } } void EthAssemblyAdapter::appendJumpToIf(LabelID _labelId, JumpType _jumpType) { - appendLabelReference(_labelId); - appendJumpInstruction(evmasm::Instruction::JUMPI, _jumpType); + if (m_assembly.supportsRelativeJumps()) + { + m_assembly.append(evmasm::AssemblyItem::conditionalRelativeJumpTo(evmasm::AssemblyItem(evmasm::Tag, _labelId))); + yulAssert(_jumpType == JumpType::Ordinary); + } + else + { + appendLabelReference(_labelId); + appendJumpInstruction(evmasm::Instruction::JUMPI, _jumpType); + } } void EthAssemblyAdapter::appendAssemblySize() diff --git a/test/libyul/objectCompiler/eof/rjumps.yul b/test/libyul/objectCompiler/eof/rjumps.yul new file mode 100644 index 000000000000..b13f3c3625e5 --- /dev/null +++ b/test/libyul/objectCompiler/eof/rjumps.yul @@ -0,0 +1,40 @@ +object "a" { + code { + if true { + mstore(0, 1) + } + + return(0, 32) + } +} + +// ==== +// EVMVersion: >=prague +// bytecodeFormat: >=EOFv1 +// ---- +// Assembly: +// /* "source":49:53 */ +// 0x01 +// /* "source":46:70 */ +// rjumpi{tag_1} +// /* "source":22:112 */ +// tag_2: +// /* "source":93:95 */ +// 0x20 +// /* "source":90:91 */ +// 0x00 +// /* "source":83:96 */ +// return +// /* "source":54:70 */ +// tag_1: +// /* "source":66:67 */ +// 0x01 +// /* "source":63:64 */ +// 0x00 +// /* "source":56:68 */ +// mstore +// /* "source":54:70 */ +// rjump{tag_2} +// Bytecode: ef00010100040200010010040000000080ffff6001e1000460205ff360015f52e0fff5 +// Opcodes: 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP LT DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT PUSH1 0x1 RJUMPI 0x4 PUSH1 0x20 PUSH0 RETURN PUSH1 0x1 PUSH0 MSTORE RJUMP 0xFFF5 +// SourceMappings: 49:4:0:-:0;46:24;22:90;93:2;90:1;83:13;54:16;66:1;63;56:12;54:16 diff --git a/test/tools/yulInterpreter/EVMInstructionInterpreter.cpp b/test/tools/yulInterpreter/EVMInstructionInterpreter.cpp index 0f1f37451569..044fff8ce6f4 100644 --- a/test/tools/yulInterpreter/EVMInstructionInterpreter.cpp +++ b/test/tools/yulInterpreter/EVMInstructionInterpreter.cpp @@ -490,6 +490,8 @@ u256 EVMInstructionInterpreter::eval( case Instruction::DATALOADN: case Instruction::EOFCREATE: case Instruction::RETURNCONTRACT: + case Instruction::RJUMP: + case Instruction::RJUMPI: solUnimplemented("EOF not yet supported by Yul interpreter."); } From 1b3d549df61f0d7fbd9207679e8fc6df0a2e529b Mon Sep 17 00:00:00 2001 From: rodiazet Date: Fri, 22 Nov 2024 13:28:51 +0100 Subject: [PATCH 0569/1022] Fix verbatim control flow size effects. --- docs/yul.rst | 3 ++- libyul/ControlFlowSideEffects.h | 6 ++++++ libyul/backends/evm/EVMDialect.cpp | 2 +- ...ore_before_terminating_verbatim_revert.yul | 20 +++++++++++++++++++ 4 files changed, 29 insertions(+), 2 deletions(-) create mode 100644 test/libyul/yulOptimizerTests/unusedStoreEliminator/store_before_terminating_verbatim_revert.yul diff --git a/docs/yul.rst b/docs/yul.rst index dd29d9a498a2..2642c0f5c821 100644 --- a/docs/yul.rst +++ b/docs/yul.rst @@ -1094,7 +1094,8 @@ the compiler. Violations of these restrictions can result in undefined behavior. - Control-flow should not jump into or out of verbatim blocks, - but it can jump within the same verbatim block. + but it can jump within the same verbatim block. In particular, + reverting or returning from the block is *not* allowed. - Stack contents apart from the input and output parameters should not be accessed. - The stack height difference should be exactly ``m - n`` diff --git a/libyul/ControlFlowSideEffects.h b/libyul/ControlFlowSideEffects.h index 554019135b80..8de6b53d4832 100644 --- a/libyul/ControlFlowSideEffects.h +++ b/libyul/ControlFlowSideEffects.h @@ -68,6 +68,12 @@ struct ControlFlowSideEffects return controlFlowSideEffects; } + + /// @returns the worst-case control flow side effects. + static ControlFlowSideEffects worst() + { + return ControlFlowSideEffects{true, true, true}; + } }; } diff --git a/libyul/backends/evm/EVMDialect.cpp b/libyul/backends/evm/EVMDialect.cpp index d7167fc77eea..f998b7abbc6d 100644 --- a/libyul/backends/evm/EVMDialect.cpp +++ b/libyul/backends/evm/EVMDialect.cpp @@ -566,7 +566,7 @@ BuiltinFunctionForEVM EVMDialect::createVerbatimFunction(size_t _arguments, size 1 + _arguments, _returnVariables, SideEffects::worst(), - ControlFlowSideEffects{}, + ControlFlowSideEffects::worst(), // Worst control flow side effects because verbatim can do anything. std::vector>{LiteralKind::String} + std::vector>(_arguments), [=]( FunctionCall const& _call, diff --git a/test/libyul/yulOptimizerTests/unusedStoreEliminator/store_before_terminating_verbatim_revert.yul b/test/libyul/yulOptimizerTests/unusedStoreEliminator/store_before_terminating_verbatim_revert.yul new file mode 100644 index 000000000000..cbc76b1dea17 --- /dev/null +++ b/test/libyul/yulOptimizerTests/unusedStoreEliminator/store_before_terminating_verbatim_revert.yul @@ -0,0 +1,20 @@ +{ + let x := 0 + let y := 1 + sstore(x, y) + // opcodes: PUSH1 0x00 DUP1 RETURN + // SSTORE is not redundant due to the RETURN hidden in the verbatim block. It must not be removed. + verbatim_0i_0o(hex"600080F3") + revert(0,0) +} +// ---- +// step: unusedStoreEliminator +// +// { +// { +// let x := 0 +// sstore(x, 1) +// verbatim_0i_0o("`\x00\x80\xf3") +// revert(0, 0) +// } +// } From d74c1c72bda0e0c9b51eb78608f1612aadebb932 Mon Sep 17 00:00:00 2001 From: Cypher Pepe <125112044+cypherpepe@users.noreply.github.com> Date: Mon, 25 Nov 2024 23:01:06 +0300 Subject: [PATCH 0570/1022] Fix box-shadow value in .wy-side-nav-search custom.css The box-shadow property in .wy-side-nav-search was incorrectly specified with four values, omitting the necessary units. --- docs/_static/css/custom.css | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/_static/css/custom.css b/docs/_static/css/custom.css index 25ab26544318..d2c9c86e7b2e 100644 --- a/docs/_static/css/custom.css +++ b/docs/_static/css/custom.css @@ -229,7 +229,7 @@ small * { .wy-side-nav-search { background-color: transparent !important; color: var(--color-a) !important; - box-shadow: 0 4 4 0 var(--color-a); + box-shadow: 0 4px 4px 0 var(--color-a); border-bottom: 1px solid var(--color-d) !important; } @@ -823,4 +823,4 @@ a.skip-to-content:focus { #content { scroll-margin-top: 6rem; scroll-behavior: smooth; -} \ No newline at end of file +} From 6fc4c033500ce68543d087ee6c4ab1cd1677efaa Mon Sep 17 00:00:00 2001 From: Cypher Pepe <125112044+cypherpepe@users.noreply.github.com> Date: Tue, 26 Nov 2024 00:42:49 +0300 Subject: [PATCH 0571/1022] typo contributing.rst --- docs/contributing.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/contributing.rst b/docs/contributing.rst index decd51392815..3cdadef95300 100644 --- a/docs/contributing.rst +++ b/docs/contributing.rst @@ -134,7 +134,7 @@ extension ``.so`` on Linux, ``.dll`` on Windows systems and ``.dylib`` on macOS. For running SMT tests, the ``z3`` executable must be present in ``PATH``. A few SMT tests use ``Eldarica`` instead of ``z3``. -These requry its executable (``eld``) to be present in ``PATH`` for the tests to pass. +These require its executable (``eld``) to be present in ``PATH`` for the tests to pass. However, if ``Eldarica`` is not found, these tests will be automatically skipped. If ``z3`` is not present on your system, you should disable the From 0462db28b0f2c15d40eb8849efc16b33697a5bb6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Tue, 26 Nov 2024 20:30:10 +0100 Subject: [PATCH 0572/1022] CI: Replace base_python_small with Ubuntu to keep python up to date - I could just bump the current image to 3.13 but this would require manual bumping in the future again. --- .circleci/config.yml | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index a39fad80b0a6..994a200329bf 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -503,15 +503,6 @@ defaults: MAKEFLAGS: -j5 CPUs: 5 - - base_python_small: &base_python_small - docker: - - image: cimg/python:3.6 - resource_class: small - environment: &base_python_small_env - TERM: xterm - MAKEFLAGS: -j 2 - CPUs: 2 - - base_ubuntu_clang: &base_ubuntu_clang docker: - image: << pipeline.parameters.ubuntu-clang-ossfuzz-docker-image >> @@ -853,7 +844,7 @@ defaults: jobs: chk_spelling: - <<: *base_python_small + <<: *base_ubuntu2404_small steps: - checkout - attach_workspace: @@ -906,7 +897,7 @@ jobs: - matrix_notify_failure_unless_pr chk_errorcodes: - <<: *base_python_small + <<: *base_ubuntu2404_small steps: - checkout - run: From 297230ad32a4ba0ac2505fc1a0d391d1cd1c25a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Tue, 26 Nov 2024 20:41:48 +0100 Subject: [PATCH 0573/1022] Fix (or whitelist) new typos found by codespell --- CODE_OF_CONDUCT.md | 2 +- docs/bugs.json | 4 ++-- docs/internals/optimizer.rst | 4 ++-- docs/yul.rst | 2 +- scripts/codespell_ignored_lines.txt | 1 + scripts/codespell_whitelist.txt | 1 + .../abiencodedecode/abi_encode_with_signature.sol | 2 +- .../abi_encode_with_signaturev2.sol | 2 +- .../stackReuse/function_params_and_retparams.yul | 14 +++++++------- .../unassigned_return.yul | 4 ++-- 10 files changed, 19 insertions(+), 17 deletions(-) diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index 4c75649ae8a0..273eac6020ed 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -6,7 +6,7 @@ In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, sex characteristics, gender identity and expression, -level of experience, education, socio-economic status, nationality, personal +level of experience, education, socioeconomic status, nationality, personal appearance, race, religion, or sexual identity and orientation. ## Our Standards diff --git a/docs/bugs.json b/docs/bugs.json index c853f95eddea..800524669048 100644 --- a/docs/bugs.json +++ b/docs/bugs.json @@ -151,7 +151,7 @@ { "uid": "SOL-2021-1", "name": "KeccakCaching", - "summary": "The bytecode optimizer incorrectly re-used previously evaluated Keccak-256 hashes. You are unlikely to be affected if you do not compute Keccak-256 hashes in inline assembly.", + "summary": "The bytecode optimizer incorrectly reused previously evaluated Keccak-256 hashes. You are unlikely to be affected if you do not compute Keccak-256 hashes in inline assembly.", "description": "Solidity's bytecode optimizer has a step that can compute Keccak-256 hashes, if the contents of the memory are known during compilation time. This step also has a mechanism to determine that two Keccak-256 hashes are equal even if the values in memory are not known during compile time. This mechanism had a bug where Keccak-256 of the same memory content, but different sizes were considered equal. More specifically, ``keccak256(mpos1, length1)`` and ``keccak256(mpos2, length2)`` in some cases were considered equal if ``length1`` and ``length2``, when rounded up to nearest multiple of 32 were the same, and when the memory contents at ``mpos1`` and ``mpos2`` can be deduced to be equal. You maybe affected if you compute multiple Keccak-256 hashes of the same content, but with different lengths inside inline assembly. You are unaffected if your code uses ``keccak256`` with a length that is not a compile-time constant or if it is always a multiple of 32.", "link": "https://blog.soliditylang.org/2021/03/23/keccak-optimizer-bug/", "fixed": "0.8.3", @@ -200,7 +200,7 @@ "uid": "SOL-2020-7", "name": "MissingEscapingInFormatting", "summary": "String literals containing double backslash characters passed directly to external or encoding function calls can lead to a different string being used when ABIEncoderV2 is enabled.", - "description": "When ABIEncoderV2 is enabled, string literals passed directly to encoding functions or external function calls are stored as strings in the intemediate code. Characters outside the printable range are handled correctly, but backslashes are not escaped in this procedure. This leads to double backslashes being reduced to single backslashes and consequently re-interpreted as escapes potentially resulting in a different string being encoded.", + "description": "When ABIEncoderV2 is enabled, string literals passed directly to encoding functions or external function calls are stored as strings in the intermediate code. Characters outside the printable range are handled correctly, but backslashes are not escaped in this procedure. This leads to double backslashes being reduced to single backslashes and consequently re-interpreted as escapes potentially resulting in a different string being encoded.", "introduced": "0.5.14", "fixed": "0.6.8", "severity": "very low", diff --git a/docs/internals/optimizer.rst b/docs/internals/optimizer.rst index 604560554ad5..4d02d3e181fe 100644 --- a/docs/internals/optimizer.rst +++ b/docs/internals/optimizer.rst @@ -982,7 +982,7 @@ no other store in between and the values of ``k`` and ``v`` did not change. This simple step is effective if run after the SSATransform and the CommonSubexpressionEliminator, because SSA will make sure that the variables -will not change and the CommonSubexpressionEliminator re-uses exactly the same +will not change and the CommonSubexpressionEliminator reuses exactly the same variable if the value is known to be the same. Prerequisites: Disambiguator, ForLoopInitRewriter. @@ -1287,7 +1287,7 @@ UnusedPruner. The SSA form we generate is detrimental to code generation because it produces many local variables. It would -be better to just re-use existing variables with assignments instead of +be better to just reuse existing variables with assignments instead of fresh variable declarations. The SSATransform rewrites diff --git a/docs/yul.rst b/docs/yul.rst index 2642c0f5c821..c81c9562a58c 100644 --- a/docs/yul.rst +++ b/docs/yul.rst @@ -1069,7 +1069,7 @@ by two, without the optimizer touching the constant two, you can use let double := verbatim_1i_1o(hex"600202", x) This code will result in a ``dup1`` opcode to retrieve ``x`` -(the optimizer might directly re-use result of the +(the optimizer might directly reuse result of the ``calldataload`` opcode, though) directly followed by ``600202``. The code is assumed to consume the copied value of ``x`` and produce the result diff --git a/scripts/codespell_ignored_lines.txt b/scripts/codespell_ignored_lines.txt index b7987cc001aa..7ad83795cae7 100644 --- a/scripts/codespell_ignored_lines.txt +++ b/scripts/codespell_ignored_lines.txt @@ -18,3 +18,4 @@ docker run --rm -v "${OUTPUTDIR}":/tmp/output -v "${SCRIPTDIR}":/tmp/scripts:ro templ("assignEnd", "end := pos"); templ("assignEnd", "end := tail"); templ("assignEnd", ""); + self.assertIn('401 Client Error: Unauthorized', str(manager.exception)) diff --git a/scripts/codespell_whitelist.txt b/scripts/codespell_whitelist.txt index 7de8a42fe521..7bcbf6ad14fb 100644 --- a/scripts/codespell_whitelist.txt +++ b/scripts/codespell_whitelist.txt @@ -1,3 +1,4 @@ nd compilability keypair +wast diff --git a/test/libsolidity/semanticTests/abiencodedecode/abi_encode_with_signature.sol b/test/libsolidity/semanticTests/abiencodedecode/abi_encode_with_signature.sol index 61a8d0b431b1..97d7273e9424 100644 --- a/test/libsolidity/semanticTests/abiencodedecode/abi_encode_with_signature.sol +++ b/test/libsolidity/semanticTests/abiencodedecode/abi_encode_with_signature.sol @@ -20,7 +20,7 @@ contract C { y[2] = type(uint).max - 2; y[3] = type(uint).max - 3; r = abi.encodeWithSignature(x, y); - // The hash uses temporary memory. This allocation re-uses the memory + // The hash uses temporary memory. This allocation reuses the memory // and should initialize it properly. ar = new uint[](2); } diff --git a/test/libsolidity/semanticTests/abiencodedecode/abi_encode_with_signaturev2.sol b/test/libsolidity/semanticTests/abiencodedecode/abi_encode_with_signaturev2.sol index 4020530864a0..b44d39c3498e 100644 --- a/test/libsolidity/semanticTests/abiencodedecode/abi_encode_with_signaturev2.sol +++ b/test/libsolidity/semanticTests/abiencodedecode/abi_encode_with_signaturev2.sol @@ -20,7 +20,7 @@ contract C { y[2] = type(uint).max - 2; y[3] = type(uint).max - 3; r = abi.encodeWithSignature(x, y); - // The hash uses temporary memory. This allocation re-uses the memory + // The hash uses temporary memory. This allocation reuses the memory // and should initialize it properly. ar = new uint[](2); } diff --git a/test/libyul/evmCodeTransform/stackReuse/function_params_and_retparams.yul b/test/libyul/evmCodeTransform/stackReuse/function_params_and_retparams.yul index 52920340055a..1d157663a56d 100644 --- a/test/libyul/evmCodeTransform/stackReuse/function_params_and_retparams.yul +++ b/test/libyul/evmCodeTransform/stackReuse/function_params_and_retparams.yul @@ -1,25 +1,25 @@ -// This does not re-use the parameters for the return parameters +// This does not reuse the parameters for the return parameters // We do not expect parameters to be fully unused, so the stack // layout for a function is still fixed, even though parameters -// can be re-used. +// can be reused. { function f(a, b, c, d) -> x, y { } } // ==== // stackOptimization: true // ---- -// /* "":212:254 */ +// /* "":210:252 */ // stop -// /* "":218:252 */ +// /* "":216:250 */ // tag_1: // pop // pop // pop // pop -// /* "":247:248 */ +// /* "":245:246 */ // 0x00 -// /* "":244:245 */ +// /* "":242:243 */ // 0x00 -// /* "":218:252 */ +// /* "":216:250 */ // swap2 // jump // out diff --git a/test/libyul/yulOptimizerTests/commonSubexpressionEliminator/unassigned_return.yul b/test/libyul/yulOptimizerTests/commonSubexpressionEliminator/unassigned_return.yul index 35891b459939..d26901c230cc 100644 --- a/test/libyul/yulOptimizerTests/commonSubexpressionEliminator/unassigned_return.yul +++ b/test/libyul/yulOptimizerTests/commonSubexpressionEliminator/unassigned_return.yul @@ -1,11 +1,11 @@ { function f() -> x { - // can re-use x + // can reuse x let y := 0 mstore(y, 7) } let a - // can re-use a + // can reuse a let b := 0 sstore(a, b) } From 7039ab618c14e110d0e71b4441a9bb4499560031 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Tue, 26 Nov 2024 20:53:52 +0100 Subject: [PATCH 0574/1022] Move codespell options to a config file - This makes it move convenient to use on the CLI --- .circleci/config.yml | 6 +----- .codespellrc | 4 ++++ 2 files changed, 5 insertions(+), 5 deletions(-) create mode 100644 .codespellrc diff --git a/.circleci/config.yml b/.circleci/config.yml index 994a200329bf..15d3b4fc5c46 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -855,11 +855,7 @@ jobs: pip install --user codespell - run: name: Check spelling - command: | - ~/.local/bin/codespell \ - --skip "*.enc,.git,Dockerfile*,LICENSE,codespell_whitelist.txt,codespell_ignored_lines.txt,deps" \ - --ignore-words scripts/codespell_whitelist.txt \ - --exclude-file scripts/codespell_ignored_lines.txt + command: ~/.local/bin/codespell - matrix_notify_failure_unless_pr chk_docs_examples: diff --git a/.codespellrc b/.codespellrc new file mode 100644 index 000000000000..df31cd316abd --- /dev/null +++ b/.codespellrc @@ -0,0 +1,4 @@ +[codespell] +skip = .git,deps,LICENSE,*.enc,Dockerfile*,codespell_whitelist.txt,codespell_ignored_lines.txt +ignore-words = scripts/codespell_whitelist.txt +exclude-file = scripts/codespell_ignored_lines.txt From b887be9eafea1d1e7465e9ca09975d3508dda5c0 Mon Sep 17 00:00:00 2001 From: Noisy <125606576+donatik27@users.noreply.github.com> Date: Wed, 27 Nov 2024 20:54:17 +0100 Subject: [PATCH 0575/1022] Update README.md --- .circleci/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/README.md b/.circleci/README.md index cd1a88ab7c1f..b3e879574689 100644 --- a/.circleci/README.md +++ b/.circleci/README.md @@ -13,7 +13,7 @@ docker push ethereum/solidity-buildpack-deps:ubuntu2404- The current revisions per docker image are stored in [circle ci pipeline parameters](https://github.com/CircleCI-Public/api-preview-docs/blob/master/docs/pipeline-parameters.md#pipeline-parameters) called `-docker-image-rev` (e.g., `ubuntu-2404-docker-image-rev`). Please update the value assigned to the parameter(s) corresponding to the docker image(s) being updated at the time of the update. Please verify that the value assigned to the parameter matches the revision part of the docker image tag (`` in the docker build/push snippet shown above). Otherwise, the docker image used by circle ci and the one actually pushed to docker hub will differ. -Once the docker image has been built and pushed to Dockerhub, you can find it at: +Once the docker image has been built and pushed to Docker Hub, you can find it at: https://hub.docker.com/r/ethereum/solidity-buildpack-deps:ubuntu2404- From 9404c86f9d64437484c3105d53503915285434b0 Mon Sep 17 00:00:00 2001 From: Noisy <125606576+donatik27@users.noreply.github.com> Date: Wed, 27 Nov 2024 20:57:40 +0100 Subject: [PATCH 0576/1022] Update README.md --- test/externalTests/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/externalTests/README.md b/test/externalTests/README.md index 91e2ef9aff4d..327920e216d2 100644 --- a/test/externalTests/README.md +++ b/test/externalTests/README.md @@ -15,7 +15,7 @@ these projects *can* be upgraded at all. #### Adding a new external project 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). +2. In our fork, remove all the branches except for the 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, From dd4b6d3c4f23ee73e6daefd030374d5f0a79abdf Mon Sep 17 00:00:00 2001 From: Noisy <125606576+donatik27@users.noreply.github.com> Date: Wed, 27 Nov 2024 21:01:08 +0100 Subject: [PATCH 0577/1022] Update README.md --- scripts/docker/buildpack-deps/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/docker/buildpack-deps/README.md b/scripts/docker/buildpack-deps/README.md index 15cb71f5be8c..9cfcafd4bf27 100644 --- a/scripts/docker/buildpack-deps/README.md +++ b/scripts/docker/buildpack-deps/README.md @@ -4,7 +4,7 @@ The `buildpack-deps` docker images are used to compile and test solidity within ## GitHub Workflow -The creation of the images are triggered by a single workflow, defined in `.github/workflows/buildpack-deps.yml`. +The creation of the images is triggered by a single workflow, defined in `.github/workflows/buildpack-deps.yml`. For each resulting `buildpack-deps` docker image a strategy is defined in the workflow file - the image variant. The workflow gets triggered, if any Dockerfile defined in `scripts/docker/buildpack-deps/Dockerfile.*` were changed within the PR. From 1cce974400d80e4002d4fd37ab432c79260cca8b Mon Sep 17 00:00:00 2001 From: Vishwa Mehta Date: Thu, 28 Nov 2024 23:40:51 +0530 Subject: [PATCH 0578/1022] Update the "Resources" section in the docs (#15076) --- docs/resources.rst | 54 ++++++++++++++++++++++++++++++++-------------- 1 file changed, 38 insertions(+), 16 deletions(-) diff --git a/docs/resources.rst b/docs/resources.rst index 1773859d4eaf..e8e8fed5880b 100644 --- a/docs/resources.rst +++ b/docs/resources.rst @@ -5,37 +5,46 @@ Resources General Resources ================= -* `Ethereum.org Developer Portal `_ +* `Ethereum.org Developers page `_ * `Ethereum StackExchange `_ -* `Solidity Portal `_ -* `Solidity Changelog `_ -* `Solidity Source Code on GitHub `_ -* `Solidity Language Users Chat `_ -* `Solidity Compiler Developers Chat `_ -* `Awesome Solidity `_ +* `Solidity website `_ +* `Solidity changelog `_ +* `Solidity codebase on GitHub `_ +* `Solidity language users chat `_ +* `Solidity compiler developers chat `_ +* `awesome-solidity `_ * `Solidity by Example `_ -* `Solidity Documentation Community Translations `_ +* `Solidity documentation community translations `_ Integrated (Ethereum) Development Environments ============================================== - * `Brownie `_ - Python-based development and testing framework for smart contracts targeting the Ethereum Virtual Machine. +* `Ape `_ + A Python-based web3 development tool for compiling, testing, and interacting with smart contracts. - * `Dapp `_ +* `Brownie `_ + A Python-based development and testing framework for smart contracts targeting the Ethereum Virtual Machine. + 💡 Note: As per the official docs, Brownie is no longer actively maintained. + Future releases may come sporadically - or never at all. + Check out Ape Framework (first in list) for all your python Ethereum development needs. + +* `Dapp `_ Tool for building, testing and deploying smart contracts from the command-line. - * `Foundry `_ +* `Foundry `_ Fast, portable and modular toolkit for Ethereum application development written in Rust. - * `Hardhat `_ +* `Hardhat `_ Ethereum development environment with local Ethereum network, debugging features and plugin ecosystem. - * `Remix `_ +* `Remix `_ Browser-based IDE with integrated compiler and Solidity runtime environment without server-side components. - * `Truffle `_ +* `Truffle `_ Ethereum development framework. + 💡 Note: Consensys announced the sunset of Truffle on September 21, 2023. + Current users may check out the migration path and available product support `here. + `_ Editor Integrations =================== @@ -70,6 +79,7 @@ Editor Integrations * `Ethereum Remix Visual Studio Code extension `_ Ethereum Remix extension pack for VS Code + 💡 Note: As per the official repository, this extension has been removed from the VSCODE marketplace and will be replaced by a dedicated stand-alone desktop application. * `Solidity Visual Studio Code extension, by Juan Blanco `_ Solidity plugin for Microsoft Visual Studio Code that includes syntax highlighting and the Solidity compiler. @@ -82,6 +92,9 @@ Editor Integrations * `Truffle for VS Code `_ Build, debug and deploy smart contracts on Ethereum and EVM-compatible blockchains. + 💡 Note: This extension has built-in support for the Truffle Suite which is being sunset. + For information on ongoing support, migration options and FAQs, visit the `Consensys blog. + `_ Solidity Tools ============== @@ -92,9 +105,15 @@ Solidity Tools * `abi-to-sol `_ Tool to generate Solidity interface source from a given ABI JSON. +* `Aderyn `_ + Rust-based solidity smart contract static analyzer designed to help find vulnerabilities in Solidity code bases. + * `Doxity `_ Documentation Generator for Solidity. +* `ethdebug `_ + A standard debugging data format for smart contracts on Ethereum-compatible networks. + * `Ethlint `_ Linter to identify and fix style and security issues in Solidity. @@ -102,7 +121,7 @@ Solidity Tools EVM Disassembler that performs static analysis on the bytecode to provide a higher level of abstraction than raw EVM operations. * `EVM Lab `_ - Rich tool package to interact with the EVM. Includes a VM, Etherchain API, and a trace-viewer with gas cost display. + A collection of tools to interact with the EVM. The package includes a VM, Etherchain API, and a trace-viewer with gas cost display. * `hevm `_ EVM debugger and symbolic execution engine. @@ -140,6 +159,9 @@ Solidity Tools * `Universal Mutator `_ A tool for mutation generation, with configurable rules and support for Solidity and Vyper. +* `Wake `_ + A Python-based Solidity development and testing framework with built-in vulnerability detectors. + Third-Party Solidity Parsers and Grammars ========================================= From 6634b9ee9e558789d5673df6ba2f712eb1f10412 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Thu, 28 Nov 2024 23:35:58 +0100 Subject: [PATCH 0579/1022] Replace InvalidDeposit exception with assertions - We never actually catch it so it's already de facto handled like a failed assert, just with worse diagnostics. --- libevmasm/Assembly.h | 4 ++-- libevmasm/Exceptions.h | 1 - libevmasm/KnownState.cpp | 4 ++-- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/libevmasm/Assembly.h b/libevmasm/Assembly.h index 4b52ca3d7970..f2da01e22f9a 100644 --- a/libevmasm/Assembly.h +++ b/libevmasm/Assembly.h @@ -127,8 +127,8 @@ class Assembly void appendToAuxiliaryData(bytes const& _data) { m_auxiliaryData += _data; } int deposit() const { return m_deposit; } - void adjustDeposit(int _adjustment) { m_deposit += _adjustment; assertThrow(m_deposit >= 0, InvalidDeposit, ""); } - void setDeposit(int _deposit) { m_deposit = _deposit; assertThrow(m_deposit >= 0, InvalidDeposit, ""); } + void adjustDeposit(int _adjustment) { m_deposit += _adjustment; solAssert(m_deposit >= 0); } + void setDeposit(int _deposit) { m_deposit = _deposit; solAssert(m_deposit >= 0); } std::string const& name() const { return m_name; } /// Changes the source location used for each appended item. diff --git a/libevmasm/Exceptions.h b/libevmasm/Exceptions.h index ae6d1bf9c617..032ed4411aca 100644 --- a/libevmasm/Exceptions.h +++ b/libevmasm/Exceptions.h @@ -33,7 +33,6 @@ struct OptimizerException: virtual AssemblyException {}; struct StackTooDeepException: virtual OptimizerException {}; struct ItemNotAvailableException: virtual OptimizerException {}; -DEV_SIMPLE_EXCEPTION(InvalidDeposit); DEV_SIMPLE_EXCEPTION(InvalidOpcode); } diff --git a/libevmasm/KnownState.cpp b/libevmasm/KnownState.cpp index 3878ae0fdd75..66553bc06633 100644 --- a/libevmasm/KnownState.cpp +++ b/libevmasm/KnownState.cpp @@ -120,7 +120,7 @@ KnownState::StoreOperation KnownState::feedItem(AssemblyItem const& _item, bool } else if (_item.type() != Operation) { - assertThrow(_item.deposit() == 1, InvalidDeposit, ""); + solAssert(_item.deposit() == 1); if (_item.pushedValue()) // only available after assembly stage, should not be used for optimisation setStackElement(++m_stackHeight, m_expressionClasses->find(*_item.pushedValue())); @@ -194,7 +194,7 @@ KnownState::StoreOperation KnownState::feedItem(AssemblyItem const& _item, bool resetStorage(); if (invMem || invStor) m_sequenceNumber += 2; // Increment by two because it can read and write - assertThrow(info.ret <= 1, InvalidDeposit, ""); + solAssert(info.ret <= 1); if (info.ret == 1) setStackElement( m_stackHeight + static_cast(_item.deposit()), From c127395fabcf87605693829132de30501aa8e21e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Fri, 29 Nov 2024 02:17:14 +0100 Subject: [PATCH 0580/1022] Replace InvalidOpcode exception with AssemblyImportException and asserts - The only case where it needs to be an exception is assembly import. In other situations we don't catch it so it's effectively an assert. --- libevmasm/Assembly.cpp | 6 +++--- libevmasm/Exceptions.h | 2 -- libevmasm/Instruction.h | 9 +++++---- libsolidity/interface/StandardCompiler.cpp | 4 ---- .../standard_import_asm_json_invalid_opcode/output.json | 4 ++-- 5 files changed, 10 insertions(+), 15 deletions(-) diff --git a/libevmasm/Assembly.cpp b/libevmasm/Assembly.cpp index fdc27241550b..5bf8e25082e9 100644 --- a/libevmasm/Assembly.cpp +++ b/libevmasm/Assembly.cpp @@ -281,7 +281,7 @@ AssemblyItem Assembly::createAssemblyItemFromJSON(Json const& _json, std::vector result = item; } else - solThrow(InvalidOpcode, "Invalid opcode: " + name); + solThrow(AssemblyImportException, "Invalid opcode (" + name + ")"); } result.setLocation(location); result.m_modifierDepth = modifierDepth; @@ -1236,7 +1236,7 @@ LinkerObject const& Assembly::assembleLegacy() const ret.bytecode += assembleTag(item, ret.bytecode.size(), true); break; default: - assertThrow(false, InvalidOpcode, "Unexpected opcode while assembling."); + solAssert(false, "Unexpected opcode while assembling."); } } @@ -1469,7 +1469,7 @@ LinkerObject const& Assembly::assembleEOF() const break; } default: - solThrow(InvalidOpcode, "Unexpected opcode while assembling."); + solAssert(false, "Unexpected opcode while assembling."); } } diff --git a/libevmasm/Exceptions.h b/libevmasm/Exceptions.h index 032ed4411aca..c9d0633e4c2c 100644 --- a/libevmasm/Exceptions.h +++ b/libevmasm/Exceptions.h @@ -33,6 +33,4 @@ struct OptimizerException: virtual AssemblyException {}; struct StackTooDeepException: virtual OptimizerException {}; struct ItemNotAvailableException: virtual OptimizerException {}; -DEV_SIMPLE_EXCEPTION(InvalidOpcode); - } diff --git a/libevmasm/Instruction.h b/libevmasm/Instruction.h index 76998c538d5f..84c6e34e6272 100644 --- a/libevmasm/Instruction.h +++ b/libevmasm/Instruction.h @@ -26,6 +26,7 @@ #include #include #include +#include namespace solidity::evmasm { @@ -267,28 +268,28 @@ inline unsigned getLogNumber(Instruction _inst) /// @returns the PUSH<_number> instruction inline Instruction pushInstruction(unsigned _number) { - assertThrow(_number <= 32, InvalidOpcode, std::string("Invalid PUSH instruction requested (") + std::to_string(_number) + ")."); + solAssert(_number <= 32); return Instruction(unsigned(Instruction::PUSH0) + _number); } /// @returns the DUP<_number> instruction inline Instruction dupInstruction(unsigned _number) { - assertThrow(1 <= _number && _number <= 16, InvalidOpcode, std::string("Invalid DUP instruction requested (") + std::to_string(_number) + ")."); + solAssert(1 <= _number && _number <= 16); return Instruction(unsigned(Instruction::DUP1) + _number - 1); } /// @returns the SWAP<_number> instruction inline Instruction swapInstruction(unsigned _number) { - assertThrow(1 <= _number && _number <= 16, InvalidOpcode, std::string("Invalid SWAP instruction requested (") + std::to_string(_number) + ")."); + solAssert(1 <= _number && _number <= 16); return Instruction(unsigned(Instruction::SWAP1) + _number - 1); } /// @returns the LOG<_number> instruction inline Instruction logInstruction(unsigned _number) { - assertThrow(_number <= 4, InvalidOpcode, std::string("Invalid LOG instruction requested (") + std::to_string(_number) + ")."); + solAssert(_number <= 4); return Instruction(unsigned(Instruction::LOG0) + _number); } diff --git a/libsolidity/interface/StandardCompiler.cpp b/libsolidity/interface/StandardCompiler.cpp index c5248e42e2f4..351a17b897d6 100644 --- a/libsolidity/interface/StandardCompiler.cpp +++ b/libsolidity/interface/StandardCompiler.cpp @@ -1220,10 +1220,6 @@ Json StandardCompiler::importEVMAssembly(StandardCompiler::InputsAndSettings _in { return formatFatalError(Error::Type::Exception, "Assembly import error: " + std::string(e.what())); } - catch (evmasm::InvalidOpcode const& e) - { - return formatFatalError(Error::Type::Exception, "Assembly import error: " + std::string(e.what())); - } catch (...) { return formatError( diff --git a/test/cmdlineTests/standard_import_asm_json_invalid_opcode/output.json b/test/cmdlineTests/standard_import_asm_json_invalid_opcode/output.json index cccd241d9416..14e502301f20 100644 --- a/test/cmdlineTests/standard_import_asm_json_invalid_opcode/output.json +++ b/test/cmdlineTests/standard_import_asm_json_invalid_opcode/output.json @@ -2,8 +2,8 @@ "errors": [ { "component": "general", - "formattedMessage": "Assembly import error: InvalidOpcode", - "message": "Assembly import error: InvalidOpcode", + "formattedMessage": "Assembly import error: Invalid opcode (INVALID_OPCODE)", + "message": "Assembly import error: Invalid opcode (INVALID_OPCODE)", "severity": "error", "type": "Exception" } From 8fdbee88055542adfebca6d74f8701d7d7b08e5b Mon Sep 17 00:00:00 2001 From: Martin Blicha Date: Thu, 31 Oct 2024 20:33:56 +0100 Subject: [PATCH 0581/1022] CI: Limit parallelism when building Z3 on MacOS Unlimited parallelism led to overwhelmed worker and unsuccessful builds. --- .circleci/osx_install_dependencies.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/osx_install_dependencies.sh b/.circleci/osx_install_dependencies.sh index dff85b489ca3..4c359c4117f9 100755 --- a/.circleci/osx_install_dependencies.sh +++ b/.circleci/osx_install_dependencies.sh @@ -106,7 +106,7 @@ then mkdir build cd build cmake -DCMAKE_OSX_ARCHITECTURES:STRING="x86_64;arm64" -DZ3_BUILD_LIBZ3_SHARED=false .. - make -j + make -j "$(nproc)" sudo make install cd ../.. rm -rf "$z3_dir" From ff62b340523d98d63d3d006474d14a3e92afa70b Mon Sep 17 00:00:00 2001 From: Martin Blicha Date: Fri, 1 Nov 2024 10:53:55 +0100 Subject: [PATCH 0582/1022] Pylint: Disable check for too many positional arguments --- scripts/pylintrc | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/pylintrc b/scripts/pylintrc index 5ef5a6eff333..191e803861e2 100644 --- a/scripts/pylintrc +++ b/scripts/pylintrc @@ -29,6 +29,7 @@ disable= too-many-branches, too-many-instance-attributes, too-many-locals, + too-many-positional-arguments, too-many-public-methods, too-many-statements, ungrouped-imports From 973b403f30e91cdcbb4fe0c335e38700b161617d Mon Sep 17 00:00:00 2001 From: Martin Blicha Date: Thu, 31 Oct 2024 15:09:00 +0100 Subject: [PATCH 0583/1022] SMTChecker: Update solvers' versions in CI and update test expectations This includes using new version of docker images, and updating the MacOS environment --- .circleci/config.yml | 16 ++++++++-------- .circleci/osx_install_dependencies.sh | 18 ++++++++---------- CMakeLists.txt | 2 +- scripts/build_emscripten.sh | 4 ++-- .../types/fixed_bytes_access_3.sol | 4 ++-- .../types/tuple_assignment_array_empty.sol | 5 +++-- 6 files changed, 24 insertions(+), 25 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 15d3b4fc5c46..542118f6deef 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -9,16 +9,16 @@ version: 2.1 parameters: ubuntu-2004-docker-image: type: string - # solbuildpackpusher/solidity-buildpack-deps:ubuntu2004-25 - default: "solbuildpackpusher/solidity-buildpack-deps@sha256:b3f321fb2d8e7a41ca9328672061c1840e5cd3fb5be503aa158d1c508deacf0a" + # solbuildpackpusher/solidity-buildpack-deps:ubuntu2004-26 + default: "solbuildpackpusher/solidity-buildpack-deps@sha256:1f387a77be889f65a2a25986a5c5eccc88cec23fabe6aeaf351790751145c81e" ubuntu-2404-docker-image: type: string - # solbuildpackpusher/solidity-buildpack-deps:ubuntu2404-1 - default: "solbuildpackpusher/solidity-buildpack-deps@sha256:5d6d27551104321a30326d6024bd4e96d9d899a97a78eb9feea364996f1d18b5" + # solbuildpackpusher/solidity-buildpack-deps:ubuntu2404-2 + default: "solbuildpackpusher/solidity-buildpack-deps@sha256:92efa8581887e5389b29d3a150112a8433a04ebf5fddf2c65ed6794b4cdf1fe3" ubuntu-2404-clang-docker-image: type: string - # solbuildpackpusher/solidity-buildpack-deps:ubuntu2404.clang-2 - default: "solbuildpackpusher/solidity-buildpack-deps@sha256:bc99a858ba18e088c1cb889ce631e3e707bb3348f0ae452bfe69116dbb931173" + # solbuildpackpusher/solidity-buildpack-deps:ubuntu2404.clang-3 + default: "solbuildpackpusher/solidity-buildpack-deps@sha256:534c4eea1ba370a85cf3c106b4a30b43152ba4f695fab5e18577009a5e272146" ubuntu-clang-ossfuzz-docker-image: type: string # solbuildpackpusher/solidity-buildpack-deps:ubuntu.clang.ossfuzz-6 @@ -26,8 +26,8 @@ parameters: emscripten-docker-image: type: string # NOTE: Please remember to update the `scripts/build_emscripten.sh` whenever the hash of this image changes. - # solbuildpackpusher/solidity-buildpack-deps:emscripten-17 - default: "solbuildpackpusher/solidity-buildpack-deps@sha256:c57f2bfb8c15d70fe290629358dd1c73dc126e3760f443b54764797556b887d4" + # solbuildpackpusher/solidity-buildpack-deps:emscripten-19 + default: "solbuildpackpusher/solidity-buildpack-deps@sha256:170b159c82ce70e639500551394460f01798c18a5e17b45ea91277b0cf8eae37" evm-version: type: string default: cancun diff --git a/.circleci/osx_install_dependencies.sh b/.circleci/osx_install_dependencies.sh index 4c359c4117f9..c606913e4e93 100755 --- a/.circleci/osx_install_dependencies.sh +++ b/.circleci/osx_install_dependencies.sh @@ -85,21 +85,19 @@ then rm -rf /tmp/{eldarica,eld_binaries.zip} #cvc5 - cvc5_version="1.1.2" - wget "https://github.com/cvc5/cvc5/releases/download/cvc5-${cvc5_version}/cvc5-macOS-arm64-static.zip" -O /tmp/cvc5.zip - validate_checksum /tmp/cvc5.zip 2017d683d924676cb713865c6d4fcf70115c65b7ec2848f242ab938902f115b5 - unzip /tmp/cvc5.zip -x "cvc5-macOS-arm64-static/lib/cmake/*" -d /tmp - sudo mv /tmp/cvc5-macOS-arm64-static/bin/* /usr/local/bin - sudo mv /tmp/cvc5-macOS-arm64-static/include/* /usr/local/include - sudo mv /tmp/cvc5-macOS-arm64-static/lib/* /usr/local/lib - rm -rf /tmp/{cvc5-macOS-arm64-static,cvc5.zip} + cvc5_version="1.2.0" + cvc5_archive_name="cvc5-macOS-arm64-static" + wget "https://github.com/cvc5/cvc5/releases/download/cvc5-${cvc5_version}/${cvc5_archive_name}.zip" -O /tmp/cvc5.zip + validate_checksum /tmp/cvc5.zip 57d2d4855af3f3865110a254e415098b4e150a655f297010e27eb292f48f7da7 + sudo unzip -j /tmp/cvc5.zip "${cvc5_archive_name}/bin/cvc5" -d /usr/local/bin + rm -f /tmp/cvc5.zip # z3 - z3_version="4.12.1" + z3_version="4.13.3" z3_dir="z3-z3-$z3_version" z3_package="z3-$z3_version.tar.gz" wget "https://github.com/Z3Prover/z3/archive/refs/tags/$z3_package" - validate_checksum "$z3_package" a3735fabf00e1341adcc70394993c05fd3e2ae167a3e9bb46045e33084eb64a3 + validate_checksum "$z3_package" f59c9cf600ea57fb64ffeffbffd0f2d2b896854f339e846f48f069d23bc14ba0 tar xf "$z3_package" rm "$z3_package" cd "$z3_dir" diff --git a/CMakeLists.txt b/CMakeLists.txt index 836d2cccb79e..729da0d72e23 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -92,7 +92,7 @@ include(EthOptions) configure_project(TESTS) if(EMSCRIPTEN) - set(TESTED_Z3_VERSION "4.12.1") + set(TESTED_Z3_VERSION "4.13.3") set(MINIMUM_Z3_VERSION "4.8.16") find_package(Z3) if (${Z3_FOUND}) diff --git a/scripts/build_emscripten.sh b/scripts/build_emscripten.sh index dc862b1f7efc..a53393f1d34c 100755 --- a/scripts/build_emscripten.sh +++ b/scripts/build_emscripten.sh @@ -33,9 +33,9 @@ if (( $# != 0 )); then params="$(printf "%q " "${@}")" fi -# solbuildpackpusher/solidity-buildpack-deps:emscripten-17 +# solbuildpackpusher/solidity-buildpack-deps:emscripten-19 # NOTE: Without `safe.directory` git would assume it's not safe to operate on /root/project since it's owned by a different user. # See https://github.blog/2022-04-12-git-security-vulnerability-announced/ docker run -v "$(pwd):/root/project" -w /root/project \ - solbuildpackpusher/solidity-buildpack-deps@sha256:c57f2bfb8c15d70fe290629358dd1c73dc126e3760f443b54764797556b887d4 \ + solbuildpackpusher/solidity-buildpack-deps@sha256:170b159c82ce70e639500551394460f01798c18a5e17b45ea91277b0cf8eae37 \ /bin/bash -c "git config --global --add safe.directory /root/project && ./scripts/ci/build_emscripten.sh ${params}" diff --git a/test/libsolidity/smtCheckerTests/types/fixed_bytes_access_3.sol b/test/libsolidity/smtCheckerTests/types/fixed_bytes_access_3.sol index bb4ef03428e7..54f3233531fa 100644 --- a/test/libsolidity/smtCheckerTests/types/fixed_bytes_access_3.sol +++ b/test/libsolidity/smtCheckerTests/types/fixed_bytes_access_3.sol @@ -30,7 +30,7 @@ contract C { } // ==== // SMTEngine: all -// SMTIgnoreOS: macos // ---- +// Warning 6368: (374-381): CHC: Out of bounds access might happen here. // Warning 6368: (456-462): CHC: Out of bounds access happens here. -// Info 1391: CHC: 13 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. +// Info 1391: CHC: 12 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/types/tuple_assignment_array_empty.sol b/test/libsolidity/smtCheckerTests/types/tuple_assignment_array_empty.sol index 79be48b3ae81..3b9a4798688a 100644 --- a/test/libsolidity/smtCheckerTests/types/tuple_assignment_array_empty.sol +++ b/test/libsolidity/smtCheckerTests/types/tuple_assignment_array_empty.sol @@ -16,6 +16,7 @@ contract C // ==== // SMTEngine: all // SMTIgnoreCex: yes +// SMTTargets: assert // ---- -// Warning 6328: (198-215): CHC: Assertion violation happens here. -// Info 1391: CHC: 4 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. +// Warning 6328: (198-215): CHC: Assertion violation happens here.\nCounterexample:\na = [3212, 4]\nx = 0\ny = 1\n\nTransaction trace:\nC.constructor()\nState: a = []\nC.f(3212)\nState: a = [3212]\nC.f(1573)\nState: a = [3212, 1573]\nC.g(0, 1) +// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. From 311e8dba3abbb5aede0741f7e8761673a490257e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Igor=20=C5=BBuk?= Date: Fri, 29 Nov 2024 15:35:33 +0100 Subject: [PATCH 0584/1022] Document memory alignment (#15586) --- docs/assembly.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/assembly.rst b/docs/assembly.rst index a0a9d06dc76c..09e158e489c6 100644 --- a/docs/assembly.rst +++ b/docs/assembly.rst @@ -257,6 +257,8 @@ starting from where this pointer points at and update it. There is no guarantee that the memory has not been used before and thus you cannot assume that its contents are zero bytes. There is no built-in mechanism to release or free allocated memory. +Solidity does not guarantee and does not require that the values in memory +are placed at positions aligned to a multiple of any value. Here is an assembly snippet you can use for allocating memory that follows the process outlined above: .. code-block:: yul From 7a5e5a6e82e9630449736f080935527692521fa0 Mon Sep 17 00:00:00 2001 From: rodiazet Date: Fri, 29 Nov 2024 11:20:24 +0100 Subject: [PATCH 0585/1022] eof: Refactor of`findReferencedContainers` and `createEOFHeader`. --- libevmasm/Assembly.cpp | 13 +- libevmasm/Assembly.h | 4 +- .../objectCompiler/eof/256_subcontainers.yul | 4113 +++++++++++++++++ 3 files changed, 4122 insertions(+), 8 deletions(-) create mode 100644 test/libyul/objectCompiler/eof/256_subcontainers.yul diff --git a/libevmasm/Assembly.cpp b/libevmasm/Assembly.cpp index 5bf8e25082e9..584c46455aa4 100644 --- a/libevmasm/Assembly.cpp +++ b/libevmasm/Assembly.cpp @@ -924,7 +924,7 @@ void appendBigEndianUint16(bytes& _dest, ValueT _value) } } -std::tuple, size_t> Assembly::createEOFHeader(std::set const& _referencedSubIds) const +std::tuple, size_t> Assembly::createEOFHeader(std::set const& _referencedSubIds) const { bytes retBytecode; std::vector codeSectionSizePositions; @@ -1330,9 +1330,9 @@ LinkerObject const& Assembly::assembleLegacy() const return ret; } -std::map Assembly::findReferencedContainers() const +std::map Assembly::findReferencedContainers() const { - std::set referencedSubcontainersIds; + std::set referencedSubcontainersIds; solAssert(m_subs.size() <= 0x100); // According to EOF spec for (auto&& codeSection: m_codeSections) @@ -1344,12 +1344,13 @@ std::map Assembly::findReferencedContainers() const referencedSubcontainersIds.insert(containerId); } - std::map replacements; + std::map replacements; uint8_t nUnreferenced = 0; for (uint8_t i = 0; i < static_cast(m_subs.size()); ++i) { - if (referencedSubcontainersIds.count(i) > 0) - replacements[i] = static_cast(i - nUnreferenced); + solAssert(i <= std::numeric_limits::max()); + if (referencedSubcontainersIds.count(static_cast(i)) > 0) + replacements[static_cast(i)] = static_cast(i - nUnreferenced); else nUnreferenced++; } diff --git a/libevmasm/Assembly.h b/libevmasm/Assembly.h index f2da01e22f9a..7ef03460cbcb 100644 --- a/libevmasm/Assembly.h +++ b/libevmasm/Assembly.h @@ -247,13 +247,13 @@ class Assembly std::shared_ptr sharedSourceName(std::string const& _name) const; /// Returns EOF header bytecode | code section sizes offsets | data section size offset - std::tuple, size_t> createEOFHeader(std::set const& _referencedSubIds) const; + std::tuple, size_t> createEOFHeader(std::set const& _referencedSubIds) const; LinkerObject const& assembleLegacy() const; LinkerObject const& assembleEOF() const; /// Returns map from m_subs to an index of subcontainer in the final EOF bytecode - std::map findReferencedContainers() const; + std::map findReferencedContainers() const; /// Returns max AuxDataLoadN offset for the assembly. std::optional findMaxAuxDataLoadNOffset() const; diff --git a/test/libyul/objectCompiler/eof/256_subcontainers.yul b/test/libyul/objectCompiler/eof/256_subcontainers.yul new file mode 100644 index 000000000000..06aebd6742da --- /dev/null +++ b/test/libyul/objectCompiler/eof/256_subcontainers.yul @@ -0,0 +1,4113 @@ +object "a" { + code { + pop(eofcreate("s0000", 0, 0, 0, 0)) + pop(eofcreate("s0001", 0, 0, 0, 0)) + pop(eofcreate("s0002", 0, 0, 0, 0)) + pop(eofcreate("s0003", 0, 0, 0, 0)) + pop(eofcreate("s0004", 0, 0, 0, 0)) + pop(eofcreate("s0005", 0, 0, 0, 0)) + pop(eofcreate("s0006", 0, 0, 0, 0)) + pop(eofcreate("s0007", 0, 0, 0, 0)) + pop(eofcreate("s0008", 0, 0, 0, 0)) + pop(eofcreate("s0009", 0, 0, 0, 0)) + pop(eofcreate("s0010", 0, 0, 0, 0)) + pop(eofcreate("s0011", 0, 0, 0, 0)) + pop(eofcreate("s0012", 0, 0, 0, 0)) + pop(eofcreate("s0013", 0, 0, 0, 0)) + pop(eofcreate("s0014", 0, 0, 0, 0)) + pop(eofcreate("s0015", 0, 0, 0, 0)) + pop(eofcreate("s0016", 0, 0, 0, 0)) + pop(eofcreate("s0017", 0, 0, 0, 0)) + pop(eofcreate("s0018", 0, 0, 0, 0)) + pop(eofcreate("s0019", 0, 0, 0, 0)) + pop(eofcreate("s0020", 0, 0, 0, 0)) + pop(eofcreate("s0021", 0, 0, 0, 0)) + pop(eofcreate("s0022", 0, 0, 0, 0)) + pop(eofcreate("s0023", 0, 0, 0, 0)) + pop(eofcreate("s0024", 0, 0, 0, 0)) + pop(eofcreate("s0025", 0, 0, 0, 0)) + pop(eofcreate("s0026", 0, 0, 0, 0)) + pop(eofcreate("s0027", 0, 0, 0, 0)) + pop(eofcreate("s0028", 0, 0, 0, 0)) + pop(eofcreate("s0029", 0, 0, 0, 0)) + pop(eofcreate("s0030", 0, 0, 0, 0)) + pop(eofcreate("s0031", 0, 0, 0, 0)) + pop(eofcreate("s0032", 0, 0, 0, 0)) + pop(eofcreate("s0033", 0, 0, 0, 0)) + pop(eofcreate("s0034", 0, 0, 0, 0)) + pop(eofcreate("s0035", 0, 0, 0, 0)) + pop(eofcreate("s0036", 0, 0, 0, 0)) + pop(eofcreate("s0037", 0, 0, 0, 0)) + pop(eofcreate("s0038", 0, 0, 0, 0)) + pop(eofcreate("s0039", 0, 0, 0, 0)) + pop(eofcreate("s0040", 0, 0, 0, 0)) + pop(eofcreate("s0041", 0, 0, 0, 0)) + pop(eofcreate("s0042", 0, 0, 0, 0)) + pop(eofcreate("s0043", 0, 0, 0, 0)) + pop(eofcreate("s0044", 0, 0, 0, 0)) + pop(eofcreate("s0045", 0, 0, 0, 0)) + pop(eofcreate("s0046", 0, 0, 0, 0)) + pop(eofcreate("s0047", 0, 0, 0, 0)) + pop(eofcreate("s0048", 0, 0, 0, 0)) + pop(eofcreate("s0049", 0, 0, 0, 0)) + pop(eofcreate("s0050", 0, 0, 0, 0)) + pop(eofcreate("s0051", 0, 0, 0, 0)) + pop(eofcreate("s0052", 0, 0, 0, 0)) + pop(eofcreate("s0053", 0, 0, 0, 0)) + pop(eofcreate("s0054", 0, 0, 0, 0)) + pop(eofcreate("s0055", 0, 0, 0, 0)) + pop(eofcreate("s0056", 0, 0, 0, 0)) + pop(eofcreate("s0057", 0, 0, 0, 0)) + pop(eofcreate("s0058", 0, 0, 0, 0)) + pop(eofcreate("s0059", 0, 0, 0, 0)) + pop(eofcreate("s0060", 0, 0, 0, 0)) + pop(eofcreate("s0061", 0, 0, 0, 0)) + pop(eofcreate("s0062", 0, 0, 0, 0)) + pop(eofcreate("s0063", 0, 0, 0, 0)) + pop(eofcreate("s0064", 0, 0, 0, 0)) + pop(eofcreate("s0065", 0, 0, 0, 0)) + pop(eofcreate("s0066", 0, 0, 0, 0)) + pop(eofcreate("s0067", 0, 0, 0, 0)) + pop(eofcreate("s0068", 0, 0, 0, 0)) + pop(eofcreate("s0069", 0, 0, 0, 0)) + pop(eofcreate("s0070", 0, 0, 0, 0)) + pop(eofcreate("s0071", 0, 0, 0, 0)) + pop(eofcreate("s0072", 0, 0, 0, 0)) + pop(eofcreate("s0073", 0, 0, 0, 0)) + pop(eofcreate("s0074", 0, 0, 0, 0)) + pop(eofcreate("s0075", 0, 0, 0, 0)) + pop(eofcreate("s0076", 0, 0, 0, 0)) + pop(eofcreate("s0077", 0, 0, 0, 0)) + pop(eofcreate("s0078", 0, 0, 0, 0)) + pop(eofcreate("s0079", 0, 0, 0, 0)) + pop(eofcreate("s0080", 0, 0, 0, 0)) + pop(eofcreate("s0081", 0, 0, 0, 0)) + pop(eofcreate("s0082", 0, 0, 0, 0)) + pop(eofcreate("s0083", 0, 0, 0, 0)) + pop(eofcreate("s0084", 0, 0, 0, 0)) + pop(eofcreate("s0085", 0, 0, 0, 0)) + pop(eofcreate("s0086", 0, 0, 0, 0)) + pop(eofcreate("s0087", 0, 0, 0, 0)) + pop(eofcreate("s0088", 0, 0, 0, 0)) + pop(eofcreate("s0089", 0, 0, 0, 0)) + pop(eofcreate("s0090", 0, 0, 0, 0)) + pop(eofcreate("s0091", 0, 0, 0, 0)) + pop(eofcreate("s0092", 0, 0, 0, 0)) + pop(eofcreate("s0093", 0, 0, 0, 0)) + pop(eofcreate("s0094", 0, 0, 0, 0)) + pop(eofcreate("s0095", 0, 0, 0, 0)) + pop(eofcreate("s0096", 0, 0, 0, 0)) + pop(eofcreate("s0097", 0, 0, 0, 0)) + pop(eofcreate("s0098", 0, 0, 0, 0)) + pop(eofcreate("s0099", 0, 0, 0, 0)) + pop(eofcreate("s0100", 0, 0, 0, 0)) + pop(eofcreate("s0101", 0, 0, 0, 0)) + pop(eofcreate("s0102", 0, 0, 0, 0)) + pop(eofcreate("s0103", 0, 0, 0, 0)) + pop(eofcreate("s0104", 0, 0, 0, 0)) + pop(eofcreate("s0105", 0, 0, 0, 0)) + pop(eofcreate("s0106", 0, 0, 0, 0)) + pop(eofcreate("s0107", 0, 0, 0, 0)) + pop(eofcreate("s0108", 0, 0, 0, 0)) + pop(eofcreate("s0109", 0, 0, 0, 0)) + pop(eofcreate("s0110", 0, 0, 0, 0)) + pop(eofcreate("s0111", 0, 0, 0, 0)) + pop(eofcreate("s0112", 0, 0, 0, 0)) + pop(eofcreate("s0113", 0, 0, 0, 0)) + pop(eofcreate("s0114", 0, 0, 0, 0)) + pop(eofcreate("s0115", 0, 0, 0, 0)) + pop(eofcreate("s0116", 0, 0, 0, 0)) + pop(eofcreate("s0117", 0, 0, 0, 0)) + pop(eofcreate("s0118", 0, 0, 0, 0)) + pop(eofcreate("s0119", 0, 0, 0, 0)) + pop(eofcreate("s0120", 0, 0, 0, 0)) + pop(eofcreate("s0121", 0, 0, 0, 0)) + pop(eofcreate("s0122", 0, 0, 0, 0)) + pop(eofcreate("s0123", 0, 0, 0, 0)) + pop(eofcreate("s0124", 0, 0, 0, 0)) + pop(eofcreate("s0125", 0, 0, 0, 0)) + pop(eofcreate("s0126", 0, 0, 0, 0)) + pop(eofcreate("s0127", 0, 0, 0, 0)) + pop(eofcreate("s0128", 0, 0, 0, 0)) + pop(eofcreate("s0129", 0, 0, 0, 0)) + pop(eofcreate("s0130", 0, 0, 0, 0)) + pop(eofcreate("s0131", 0, 0, 0, 0)) + pop(eofcreate("s0132", 0, 0, 0, 0)) + pop(eofcreate("s0133", 0, 0, 0, 0)) + pop(eofcreate("s0134", 0, 0, 0, 0)) + pop(eofcreate("s0135", 0, 0, 0, 0)) + pop(eofcreate("s0136", 0, 0, 0, 0)) + pop(eofcreate("s0137", 0, 0, 0, 0)) + pop(eofcreate("s0138", 0, 0, 0, 0)) + pop(eofcreate("s0139", 0, 0, 0, 0)) + pop(eofcreate("s0140", 0, 0, 0, 0)) + pop(eofcreate("s0141", 0, 0, 0, 0)) + pop(eofcreate("s0142", 0, 0, 0, 0)) + pop(eofcreate("s0143", 0, 0, 0, 0)) + pop(eofcreate("s0144", 0, 0, 0, 0)) + pop(eofcreate("s0145", 0, 0, 0, 0)) + pop(eofcreate("s0146", 0, 0, 0, 0)) + pop(eofcreate("s0147", 0, 0, 0, 0)) + pop(eofcreate("s0148", 0, 0, 0, 0)) + pop(eofcreate("s0149", 0, 0, 0, 0)) + pop(eofcreate("s0150", 0, 0, 0, 0)) + pop(eofcreate("s0151", 0, 0, 0, 0)) + pop(eofcreate("s0152", 0, 0, 0, 0)) + pop(eofcreate("s0153", 0, 0, 0, 0)) + pop(eofcreate("s0154", 0, 0, 0, 0)) + pop(eofcreate("s0155", 0, 0, 0, 0)) + pop(eofcreate("s0156", 0, 0, 0, 0)) + pop(eofcreate("s0157", 0, 0, 0, 0)) + pop(eofcreate("s0158", 0, 0, 0, 0)) + pop(eofcreate("s0159", 0, 0, 0, 0)) + pop(eofcreate("s0160", 0, 0, 0, 0)) + pop(eofcreate("s0161", 0, 0, 0, 0)) + pop(eofcreate("s0162", 0, 0, 0, 0)) + pop(eofcreate("s0163", 0, 0, 0, 0)) + pop(eofcreate("s0164", 0, 0, 0, 0)) + pop(eofcreate("s0165", 0, 0, 0, 0)) + pop(eofcreate("s0166", 0, 0, 0, 0)) + pop(eofcreate("s0167", 0, 0, 0, 0)) + pop(eofcreate("s0168", 0, 0, 0, 0)) + pop(eofcreate("s0169", 0, 0, 0, 0)) + pop(eofcreate("s0170", 0, 0, 0, 0)) + pop(eofcreate("s0171", 0, 0, 0, 0)) + pop(eofcreate("s0172", 0, 0, 0, 0)) + pop(eofcreate("s0173", 0, 0, 0, 0)) + pop(eofcreate("s0174", 0, 0, 0, 0)) + pop(eofcreate("s0175", 0, 0, 0, 0)) + pop(eofcreate("s0176", 0, 0, 0, 0)) + pop(eofcreate("s0177", 0, 0, 0, 0)) + pop(eofcreate("s0178", 0, 0, 0, 0)) + pop(eofcreate("s0179", 0, 0, 0, 0)) + pop(eofcreate("s0180", 0, 0, 0, 0)) + pop(eofcreate("s0181", 0, 0, 0, 0)) + pop(eofcreate("s0182", 0, 0, 0, 0)) + pop(eofcreate("s0183", 0, 0, 0, 0)) + pop(eofcreate("s0184", 0, 0, 0, 0)) + pop(eofcreate("s0185", 0, 0, 0, 0)) + pop(eofcreate("s0186", 0, 0, 0, 0)) + pop(eofcreate("s0187", 0, 0, 0, 0)) + pop(eofcreate("s0188", 0, 0, 0, 0)) + pop(eofcreate("s0189", 0, 0, 0, 0)) + pop(eofcreate("s0190", 0, 0, 0, 0)) + pop(eofcreate("s0191", 0, 0, 0, 0)) + pop(eofcreate("s0192", 0, 0, 0, 0)) + pop(eofcreate("s0193", 0, 0, 0, 0)) + pop(eofcreate("s0194", 0, 0, 0, 0)) + pop(eofcreate("s0195", 0, 0, 0, 0)) + pop(eofcreate("s0196", 0, 0, 0, 0)) + pop(eofcreate("s0197", 0, 0, 0, 0)) + pop(eofcreate("s0198", 0, 0, 0, 0)) + pop(eofcreate("s0199", 0, 0, 0, 0)) + pop(eofcreate("s0200", 0, 0, 0, 0)) + pop(eofcreate("s0201", 0, 0, 0, 0)) + pop(eofcreate("s0202", 0, 0, 0, 0)) + pop(eofcreate("s0203", 0, 0, 0, 0)) + pop(eofcreate("s0204", 0, 0, 0, 0)) + pop(eofcreate("s0205", 0, 0, 0, 0)) + pop(eofcreate("s0206", 0, 0, 0, 0)) + pop(eofcreate("s0207", 0, 0, 0, 0)) + pop(eofcreate("s0208", 0, 0, 0, 0)) + pop(eofcreate("s0209", 0, 0, 0, 0)) + pop(eofcreate("s0210", 0, 0, 0, 0)) + pop(eofcreate("s0211", 0, 0, 0, 0)) + pop(eofcreate("s0212", 0, 0, 0, 0)) + pop(eofcreate("s0213", 0, 0, 0, 0)) + pop(eofcreate("s0214", 0, 0, 0, 0)) + pop(eofcreate("s0215", 0, 0, 0, 0)) + pop(eofcreate("s0216", 0, 0, 0, 0)) + pop(eofcreate("s0217", 0, 0, 0, 0)) + pop(eofcreate("s0218", 0, 0, 0, 0)) + pop(eofcreate("s0219", 0, 0, 0, 0)) + pop(eofcreate("s0220", 0, 0, 0, 0)) + pop(eofcreate("s0221", 0, 0, 0, 0)) + pop(eofcreate("s0222", 0, 0, 0, 0)) + pop(eofcreate("s0223", 0, 0, 0, 0)) + pop(eofcreate("s0224", 0, 0, 0, 0)) + pop(eofcreate("s0225", 0, 0, 0, 0)) + pop(eofcreate("s0226", 0, 0, 0, 0)) + pop(eofcreate("s0227", 0, 0, 0, 0)) + pop(eofcreate("s0228", 0, 0, 0, 0)) + pop(eofcreate("s0229", 0, 0, 0, 0)) + pop(eofcreate("s0230", 0, 0, 0, 0)) + pop(eofcreate("s0231", 0, 0, 0, 0)) + pop(eofcreate("s0232", 0, 0, 0, 0)) + pop(eofcreate("s0233", 0, 0, 0, 0)) + pop(eofcreate("s0234", 0, 0, 0, 0)) + pop(eofcreate("s0235", 0, 0, 0, 0)) + pop(eofcreate("s0236", 0, 0, 0, 0)) + pop(eofcreate("s0237", 0, 0, 0, 0)) + pop(eofcreate("s0238", 0, 0, 0, 0)) + pop(eofcreate("s0239", 0, 0, 0, 0)) + pop(eofcreate("s0240", 0, 0, 0, 0)) + pop(eofcreate("s0241", 0, 0, 0, 0)) + pop(eofcreate("s0242", 0, 0, 0, 0)) + pop(eofcreate("s0243", 0, 0, 0, 0)) + pop(eofcreate("s0244", 0, 0, 0, 0)) + pop(eofcreate("s0245", 0, 0, 0, 0)) + pop(eofcreate("s0246", 0, 0, 0, 0)) + pop(eofcreate("s0247", 0, 0, 0, 0)) + pop(eofcreate("s0248", 0, 0, 0, 0)) + pop(eofcreate("s0249", 0, 0, 0, 0)) + pop(eofcreate("s0250", 0, 0, 0, 0)) + pop(eofcreate("s0251", 0, 0, 0, 0)) + pop(eofcreate("s0252", 0, 0, 0, 0)) + pop(eofcreate("s0253", 0, 0, 0, 0)) + pop(eofcreate("s0254", 0, 0, 0, 0)) + pop(eofcreate("s0255", 0, 0, 0, 0)) + } + + object "s0000" {code{}} + object "s0001" {code{}} + object "s0002" {code{}} + object "s0003" {code{}} + object "s0004" {code{}} + object "s0005" {code{}} + object "s0006" {code{}} + object "s0007" {code{}} + object "s0008" {code{}} + object "s0009" {code{}} + object "s0010" {code{}} + object "s0011" {code{}} + object "s0012" {code{}} + object "s0013" {code{}} + object "s0014" {code{}} + object "s0015" {code{}} + object "s0016" {code{}} + object "s0017" {code{}} + object "s0018" {code{}} + object "s0019" {code{}} + object "s0020" {code{}} + object "s0021" {code{}} + object "s0022" {code{}} + object "s0023" {code{}} + object "s0024" {code{}} + object "s0025" {code{}} + object "s0026" {code{}} + object "s0027" {code{}} + object "s0028" {code{}} + object "s0029" {code{}} + object "s0030" {code{}} + object "s0031" {code{}} + object "s0032" {code{}} + object "s0033" {code{}} + object "s0034" {code{}} + object "s0035" {code{}} + object "s0036" {code{}} + object "s0037" {code{}} + object "s0038" {code{}} + object "s0039" {code{}} + object "s0040" {code{}} + object "s0041" {code{}} + object "s0042" {code{}} + object "s0043" {code{}} + object "s0044" {code{}} + object "s0045" {code{}} + object "s0046" {code{}} + object "s0047" {code{}} + object "s0048" {code{}} + object "s0049" {code{}} + object "s0050" {code{}} + object "s0051" {code{}} + object "s0052" {code{}} + object "s0053" {code{}} + object "s0054" {code{}} + object "s0055" {code{}} + object "s0056" {code{}} + object "s0057" {code{}} + object "s0058" {code{}} + object "s0059" {code{}} + object "s0060" {code{}} + object "s0061" {code{}} + object "s0062" {code{}} + object "s0063" {code{}} + object "s0064" {code{}} + object "s0065" {code{}} + object "s0066" {code{}} + object "s0067" {code{}} + object "s0068" {code{}} + object "s0069" {code{}} + object "s0070" {code{}} + object "s0071" {code{}} + object "s0072" {code{}} + object "s0073" {code{}} + object "s0074" {code{}} + object "s0075" {code{}} + object "s0076" {code{}} + object "s0077" {code{}} + object "s0078" {code{}} + object "s0079" {code{}} + object "s0080" {code{}} + object "s0081" {code{}} + object "s0082" {code{}} + object "s0083" {code{}} + object "s0084" {code{}} + object "s0085" {code{}} + object "s0086" {code{}} + object "s0087" {code{}} + object "s0088" {code{}} + object "s0089" {code{}} + object "s0090" {code{}} + object "s0091" {code{}} + object "s0092" {code{}} + object "s0093" {code{}} + object "s0094" {code{}} + object "s0095" {code{}} + object "s0096" {code{}} + object "s0097" {code{}} + object "s0098" {code{}} + object "s0099" {code{}} + object "s0100" {code{}} + object "s0101" {code{}} + object "s0102" {code{}} + object "s0103" {code{}} + object "s0104" {code{}} + object "s0105" {code{}} + object "s0106" {code{}} + object "s0107" {code{}} + object "s0108" {code{}} + object "s0109" {code{}} + object "s0110" {code{}} + object "s0111" {code{}} + object "s0112" {code{}} + object "s0113" {code{}} + object "s0114" {code{}} + object "s0115" {code{}} + object "s0116" {code{}} + object "s0117" {code{}} + object "s0118" {code{}} + object "s0119" {code{}} + object "s0120" {code{}} + object "s0121" {code{}} + object "s0122" {code{}} + object "s0123" {code{}} + object "s0124" {code{}} + object "s0125" {code{}} + object "s0126" {code{}} + object "s0127" {code{}} + object "s0128" {code{}} + object "s0129" {code{}} + object "s0130" {code{}} + object "s0131" {code{}} + object "s0132" {code{}} + object "s0133" {code{}} + object "s0134" {code{}} + object "s0135" {code{}} + object "s0136" {code{}} + object "s0137" {code{}} + object "s0138" {code{}} + object "s0139" {code{}} + object "s0140" {code{}} + object "s0141" {code{}} + object "s0142" {code{}} + object "s0143" {code{}} + object "s0144" {code{}} + object "s0145" {code{}} + object "s0146" {code{}} + object "s0147" {code{}} + object "s0148" {code{}} + object "s0149" {code{}} + object "s0150" {code{}} + object "s0151" {code{}} + object "s0152" {code{}} + object "s0153" {code{}} + object "s0154" {code{}} + object "s0155" {code{}} + object "s0156" {code{}} + object "s0157" {code{}} + object "s0158" {code{}} + object "s0159" {code{}} + object "s0160" {code{}} + object "s0161" {code{}} + object "s0162" {code{}} + object "s0163" {code{}} + object "s0164" {code{}} + object "s0165" {code{}} + object "s0166" {code{}} + object "s0167" {code{}} + object "s0168" {code{}} + object "s0169" {code{}} + object "s0170" {code{}} + object "s0171" {code{}} + object "s0172" {code{}} + object "s0173" {code{}} + object "s0174" {code{}} + object "s0175" {code{}} + object "s0176" {code{}} + object "s0177" {code{}} + object "s0178" {code{}} + object "s0179" {code{}} + object "s0180" {code{}} + object "s0181" {code{}} + object "s0182" {code{}} + object "s0183" {code{}} + object "s0184" {code{}} + object "s0185" {code{}} + object "s0186" {code{}} + object "s0187" {code{}} + object "s0188" {code{}} + object "s0189" {code{}} + object "s0190" {code{}} + object "s0191" {code{}} + object "s0192" {code{}} + object "s0193" {code{}} + object "s0194" {code{}} + object "s0195" {code{}} + object "s0196" {code{}} + object "s0197" {code{}} + object "s0198" {code{}} + object "s0199" {code{}} + object "s0200" {code{}} + object "s0201" {code{}} + object "s0202" {code{}} + object "s0203" {code{}} + object "s0204" {code{}} + object "s0205" {code{}} + object "s0206" {code{}} + object "s0207" {code{}} + object "s0208" {code{}} + object "s0209" {code{}} + object "s0210" {code{}} + object "s0211" {code{}} + object "s0212" {code{}} + object "s0213" {code{}} + object "s0214" {code{}} + object "s0215" {code{}} + object "s0216" {code{}} + object "s0217" {code{}} + object "s0218" {code{}} + object "s0219" {code{}} + object "s0220" {code{}} + object "s0221" {code{}} + object "s0222" {code{}} + object "s0223" {code{}} + object "s0224" {code{}} + object "s0225" {code{}} + object "s0226" {code{}} + object "s0227" {code{}} + object "s0228" {code{}} + object "s0229" {code{}} + object "s0230" {code{}} + object "s0231" {code{}} + object "s0232" {code{}} + object "s0233" {code{}} + object "s0234" {code{}} + object "s0235" {code{}} + object "s0236" {code{}} + object "s0237" {code{}} + object "s0238" {code{}} + object "s0239" {code{}} + object "s0240" {code{}} + object "s0241" {code{}} + object "s0242" {code{}} + object "s0243" {code{}} + object "s0244" {code{}} + object "s0245" {code{}} + object "s0246" {code{}} + object "s0247" {code{}} + object "s0248" {code{}} + object "s0249" {code{}} + object "s0250" {code{}} + object "s0251" {code{}} + object "s0252" {code{}} + object "s0253" {code{}} + object "s0254" {code{}} + object "s0255" {code{}} +} + +// ==== +// EVMVersion: >=prague +// bytecodeFormat: >=EOFv1 +// ---- +// Assembly: +// /* "source":78:79 */ +// 0x00 +// /* "source":50:80 */ +// dup1 +// dup1 +// dup1 +// eofcreate{0} +// /* "source":46:81 */ +// pop +// /* "source":126:127 */ +// 0x00 +// /* "source":98:128 */ +// dup1 +// dup1 +// dup1 +// eofcreate{1} +// /* "source":94:129 */ +// pop +// /* "source":174:175 */ +// 0x00 +// /* "source":146:176 */ +// dup1 +// dup1 +// dup1 +// eofcreate{2} +// /* "source":142:177 */ +// pop +// /* "source":222:223 */ +// 0x00 +// /* "source":194:224 */ +// dup1 +// dup1 +// dup1 +// eofcreate{3} +// /* "source":190:225 */ +// pop +// /* "source":270:271 */ +// 0x00 +// /* "source":242:272 */ +// dup1 +// dup1 +// dup1 +// eofcreate{4} +// /* "source":238:273 */ +// pop +// /* "source":318:319 */ +// 0x00 +// /* "source":290:320 */ +// dup1 +// dup1 +// dup1 +// eofcreate{5} +// /* "source":286:321 */ +// pop +// /* "source":366:367 */ +// 0x00 +// /* "source":338:368 */ +// dup1 +// dup1 +// dup1 +// eofcreate{6} +// /* "source":334:369 */ +// pop +// /* "source":414:415 */ +// 0x00 +// /* "source":386:416 */ +// dup1 +// dup1 +// dup1 +// eofcreate{7} +// /* "source":382:417 */ +// pop +// /* "source":462:463 */ +// 0x00 +// /* "source":434:464 */ +// dup1 +// dup1 +// dup1 +// eofcreate{8} +// /* "source":430:465 */ +// pop +// /* "source":510:511 */ +// 0x00 +// /* "source":482:512 */ +// dup1 +// dup1 +// dup1 +// eofcreate{9} +// /* "source":478:513 */ +// pop +// /* "source":558:559 */ +// 0x00 +// /* "source":530:560 */ +// dup1 +// dup1 +// dup1 +// eofcreate{10} +// /* "source":526:561 */ +// pop +// /* "source":606:607 */ +// 0x00 +// /* "source":578:608 */ +// dup1 +// dup1 +// dup1 +// eofcreate{11} +// /* "source":574:609 */ +// pop +// /* "source":654:655 */ +// 0x00 +// /* "source":626:656 */ +// dup1 +// dup1 +// dup1 +// eofcreate{12} +// /* "source":622:657 */ +// pop +// /* "source":702:703 */ +// 0x00 +// /* "source":674:704 */ +// dup1 +// dup1 +// dup1 +// eofcreate{13} +// /* "source":670:705 */ +// pop +// /* "source":750:751 */ +// 0x00 +// /* "source":722:752 */ +// dup1 +// dup1 +// dup1 +// eofcreate{14} +// /* "source":718:753 */ +// pop +// /* "source":798:799 */ +// 0x00 +// /* "source":770:800 */ +// dup1 +// dup1 +// dup1 +// eofcreate{15} +// /* "source":766:801 */ +// pop +// /* "source":846:847 */ +// 0x00 +// /* "source":818:848 */ +// dup1 +// dup1 +// dup1 +// eofcreate{16} +// /* "source":814:849 */ +// pop +// /* "source":894:895 */ +// 0x00 +// /* "source":866:896 */ +// dup1 +// dup1 +// dup1 +// eofcreate{17} +// /* "source":862:897 */ +// pop +// /* "source":942:943 */ +// 0x00 +// /* "source":914:944 */ +// dup1 +// dup1 +// dup1 +// eofcreate{18} +// /* "source":910:945 */ +// pop +// /* "source":990:991 */ +// 0x00 +// /* "source":962:992 */ +// dup1 +// dup1 +// dup1 +// eofcreate{19} +// /* "source":958:993 */ +// pop +// /* "source":1038:1039 */ +// 0x00 +// /* "source":1010:1040 */ +// dup1 +// dup1 +// dup1 +// eofcreate{20} +// /* "source":1006:1041 */ +// pop +// /* "source":1086:1087 */ +// 0x00 +// /* "source":1058:1088 */ +// dup1 +// dup1 +// dup1 +// eofcreate{21} +// /* "source":1054:1089 */ +// pop +// /* "source":1134:1135 */ +// 0x00 +// /* "source":1106:1136 */ +// dup1 +// dup1 +// dup1 +// eofcreate{22} +// /* "source":1102:1137 */ +// pop +// /* "source":1182:1183 */ +// 0x00 +// /* "source":1154:1184 */ +// dup1 +// dup1 +// dup1 +// eofcreate{23} +// /* "source":1150:1185 */ +// pop +// /* "source":1230:1231 */ +// 0x00 +// /* "source":1202:1232 */ +// dup1 +// dup1 +// dup1 +// eofcreate{24} +// /* "source":1198:1233 */ +// pop +// /* "source":1278:1279 */ +// 0x00 +// /* "source":1250:1280 */ +// dup1 +// dup1 +// dup1 +// eofcreate{25} +// /* "source":1246:1281 */ +// pop +// /* "source":1326:1327 */ +// 0x00 +// /* "source":1298:1328 */ +// dup1 +// dup1 +// dup1 +// eofcreate{26} +// /* "source":1294:1329 */ +// pop +// /* "source":1374:1375 */ +// 0x00 +// /* "source":1346:1376 */ +// dup1 +// dup1 +// dup1 +// eofcreate{27} +// /* "source":1342:1377 */ +// pop +// /* "source":1422:1423 */ +// 0x00 +// /* "source":1394:1424 */ +// dup1 +// dup1 +// dup1 +// eofcreate{28} +// /* "source":1390:1425 */ +// pop +// /* "source":1470:1471 */ +// 0x00 +// /* "source":1442:1472 */ +// dup1 +// dup1 +// dup1 +// eofcreate{29} +// /* "source":1438:1473 */ +// pop +// /* "source":1518:1519 */ +// 0x00 +// /* "source":1490:1520 */ +// dup1 +// dup1 +// dup1 +// eofcreate{30} +// /* "source":1486:1521 */ +// pop +// /* "source":1566:1567 */ +// 0x00 +// /* "source":1538:1568 */ +// dup1 +// dup1 +// dup1 +// eofcreate{31} +// /* "source":1534:1569 */ +// pop +// /* "source":1614:1615 */ +// 0x00 +// /* "source":1586:1616 */ +// dup1 +// dup1 +// dup1 +// eofcreate{32} +// /* "source":1582:1617 */ +// pop +// /* "source":1662:1663 */ +// 0x00 +// /* "source":1634:1664 */ +// dup1 +// dup1 +// dup1 +// eofcreate{33} +// /* "source":1630:1665 */ +// pop +// /* "source":1710:1711 */ +// 0x00 +// /* "source":1682:1712 */ +// dup1 +// dup1 +// dup1 +// eofcreate{34} +// /* "source":1678:1713 */ +// pop +// /* "source":1758:1759 */ +// 0x00 +// /* "source":1730:1760 */ +// dup1 +// dup1 +// dup1 +// eofcreate{35} +// /* "source":1726:1761 */ +// pop +// /* "source":1806:1807 */ +// 0x00 +// /* "source":1778:1808 */ +// dup1 +// dup1 +// dup1 +// eofcreate{36} +// /* "source":1774:1809 */ +// pop +// /* "source":1854:1855 */ +// 0x00 +// /* "source":1826:1856 */ +// dup1 +// dup1 +// dup1 +// eofcreate{37} +// /* "source":1822:1857 */ +// pop +// /* "source":1902:1903 */ +// 0x00 +// /* "source":1874:1904 */ +// dup1 +// dup1 +// dup1 +// eofcreate{38} +// /* "source":1870:1905 */ +// pop +// /* "source":1950:1951 */ +// 0x00 +// /* "source":1922:1952 */ +// dup1 +// dup1 +// dup1 +// eofcreate{39} +// /* "source":1918:1953 */ +// pop +// /* "source":1998:1999 */ +// 0x00 +// /* "source":1970:2000 */ +// dup1 +// dup1 +// dup1 +// eofcreate{40} +// /* "source":1966:2001 */ +// pop +// /* "source":2046:2047 */ +// 0x00 +// /* "source":2018:2048 */ +// dup1 +// dup1 +// dup1 +// eofcreate{41} +// /* "source":2014:2049 */ +// pop +// /* "source":2094:2095 */ +// 0x00 +// /* "source":2066:2096 */ +// dup1 +// dup1 +// dup1 +// eofcreate{42} +// /* "source":2062:2097 */ +// pop +// /* "source":2142:2143 */ +// 0x00 +// /* "source":2114:2144 */ +// dup1 +// dup1 +// dup1 +// eofcreate{43} +// /* "source":2110:2145 */ +// pop +// /* "source":2190:2191 */ +// 0x00 +// /* "source":2162:2192 */ +// dup1 +// dup1 +// dup1 +// eofcreate{44} +// /* "source":2158:2193 */ +// pop +// /* "source":2238:2239 */ +// 0x00 +// /* "source":2210:2240 */ +// dup1 +// dup1 +// dup1 +// eofcreate{45} +// /* "source":2206:2241 */ +// pop +// /* "source":2286:2287 */ +// 0x00 +// /* "source":2258:2288 */ +// dup1 +// dup1 +// dup1 +// eofcreate{46} +// /* "source":2254:2289 */ +// pop +// /* "source":2334:2335 */ +// 0x00 +// /* "source":2306:2336 */ +// dup1 +// dup1 +// dup1 +// eofcreate{47} +// /* "source":2302:2337 */ +// pop +// /* "source":2382:2383 */ +// 0x00 +// /* "source":2354:2384 */ +// dup1 +// dup1 +// dup1 +// eofcreate{48} +// /* "source":2350:2385 */ +// pop +// /* "source":2430:2431 */ +// 0x00 +// /* "source":2402:2432 */ +// dup1 +// dup1 +// dup1 +// eofcreate{49} +// /* "source":2398:2433 */ +// pop +// /* "source":2478:2479 */ +// 0x00 +// /* "source":2450:2480 */ +// dup1 +// dup1 +// dup1 +// eofcreate{50} +// /* "source":2446:2481 */ +// pop +// /* "source":2526:2527 */ +// 0x00 +// /* "source":2498:2528 */ +// dup1 +// dup1 +// dup1 +// eofcreate{51} +// /* "source":2494:2529 */ +// pop +// /* "source":2574:2575 */ +// 0x00 +// /* "source":2546:2576 */ +// dup1 +// dup1 +// dup1 +// eofcreate{52} +// /* "source":2542:2577 */ +// pop +// /* "source":2622:2623 */ +// 0x00 +// /* "source":2594:2624 */ +// dup1 +// dup1 +// dup1 +// eofcreate{53} +// /* "source":2590:2625 */ +// pop +// /* "source":2670:2671 */ +// 0x00 +// /* "source":2642:2672 */ +// dup1 +// dup1 +// dup1 +// eofcreate{54} +// /* "source":2638:2673 */ +// pop +// /* "source":2718:2719 */ +// 0x00 +// /* "source":2690:2720 */ +// dup1 +// dup1 +// dup1 +// eofcreate{55} +// /* "source":2686:2721 */ +// pop +// /* "source":2766:2767 */ +// 0x00 +// /* "source":2738:2768 */ +// dup1 +// dup1 +// dup1 +// eofcreate{56} +// /* "source":2734:2769 */ +// pop +// /* "source":2814:2815 */ +// 0x00 +// /* "source":2786:2816 */ +// dup1 +// dup1 +// dup1 +// eofcreate{57} +// /* "source":2782:2817 */ +// pop +// /* "source":2862:2863 */ +// 0x00 +// /* "source":2834:2864 */ +// dup1 +// dup1 +// dup1 +// eofcreate{58} +// /* "source":2830:2865 */ +// pop +// /* "source":2910:2911 */ +// 0x00 +// /* "source":2882:2912 */ +// dup1 +// dup1 +// dup1 +// eofcreate{59} +// /* "source":2878:2913 */ +// pop +// /* "source":2958:2959 */ +// 0x00 +// /* "source":2930:2960 */ +// dup1 +// dup1 +// dup1 +// eofcreate{60} +// /* "source":2926:2961 */ +// pop +// /* "source":3006:3007 */ +// 0x00 +// /* "source":2978:3008 */ +// dup1 +// dup1 +// dup1 +// eofcreate{61} +// /* "source":2974:3009 */ +// pop +// /* "source":3054:3055 */ +// 0x00 +// /* "source":3026:3056 */ +// dup1 +// dup1 +// dup1 +// eofcreate{62} +// /* "source":3022:3057 */ +// pop +// /* "source":3102:3103 */ +// 0x00 +// /* "source":3074:3104 */ +// dup1 +// dup1 +// dup1 +// eofcreate{63} +// /* "source":3070:3105 */ +// pop +// /* "source":3150:3151 */ +// 0x00 +// /* "source":3122:3152 */ +// dup1 +// dup1 +// dup1 +// eofcreate{64} +// /* "source":3118:3153 */ +// pop +// /* "source":3198:3199 */ +// 0x00 +// /* "source":3170:3200 */ +// dup1 +// dup1 +// dup1 +// eofcreate{65} +// /* "source":3166:3201 */ +// pop +// /* "source":3246:3247 */ +// 0x00 +// /* "source":3218:3248 */ +// dup1 +// dup1 +// dup1 +// eofcreate{66} +// /* "source":3214:3249 */ +// pop +// /* "source":3294:3295 */ +// 0x00 +// /* "source":3266:3296 */ +// dup1 +// dup1 +// dup1 +// eofcreate{67} +// /* "source":3262:3297 */ +// pop +// /* "source":3342:3343 */ +// 0x00 +// /* "source":3314:3344 */ +// dup1 +// dup1 +// dup1 +// eofcreate{68} +// /* "source":3310:3345 */ +// pop +// /* "source":3390:3391 */ +// 0x00 +// /* "source":3362:3392 */ +// dup1 +// dup1 +// dup1 +// eofcreate{69} +// /* "source":3358:3393 */ +// pop +// /* "source":3438:3439 */ +// 0x00 +// /* "source":3410:3440 */ +// dup1 +// dup1 +// dup1 +// eofcreate{70} +// /* "source":3406:3441 */ +// pop +// /* "source":3486:3487 */ +// 0x00 +// /* "source":3458:3488 */ +// dup1 +// dup1 +// dup1 +// eofcreate{71} +// /* "source":3454:3489 */ +// pop +// /* "source":3534:3535 */ +// 0x00 +// /* "source":3506:3536 */ +// dup1 +// dup1 +// dup1 +// eofcreate{72} +// /* "source":3502:3537 */ +// pop +// /* "source":3582:3583 */ +// 0x00 +// /* "source":3554:3584 */ +// dup1 +// dup1 +// dup1 +// eofcreate{73} +// /* "source":3550:3585 */ +// pop +// /* "source":3630:3631 */ +// 0x00 +// /* "source":3602:3632 */ +// dup1 +// dup1 +// dup1 +// eofcreate{74} +// /* "source":3598:3633 */ +// pop +// /* "source":3678:3679 */ +// 0x00 +// /* "source":3650:3680 */ +// dup1 +// dup1 +// dup1 +// eofcreate{75} +// /* "source":3646:3681 */ +// pop +// /* "source":3726:3727 */ +// 0x00 +// /* "source":3698:3728 */ +// dup1 +// dup1 +// dup1 +// eofcreate{76} +// /* "source":3694:3729 */ +// pop +// /* "source":3774:3775 */ +// 0x00 +// /* "source":3746:3776 */ +// dup1 +// dup1 +// dup1 +// eofcreate{77} +// /* "source":3742:3777 */ +// pop +// /* "source":3822:3823 */ +// 0x00 +// /* "source":3794:3824 */ +// dup1 +// dup1 +// dup1 +// eofcreate{78} +// /* "source":3790:3825 */ +// pop +// /* "source":3870:3871 */ +// 0x00 +// /* "source":3842:3872 */ +// dup1 +// dup1 +// dup1 +// eofcreate{79} +// /* "source":3838:3873 */ +// pop +// /* "source":3918:3919 */ +// 0x00 +// /* "source":3890:3920 */ +// dup1 +// dup1 +// dup1 +// eofcreate{80} +// /* "source":3886:3921 */ +// pop +// /* "source":3966:3967 */ +// 0x00 +// /* "source":3938:3968 */ +// dup1 +// dup1 +// dup1 +// eofcreate{81} +// /* "source":3934:3969 */ +// pop +// /* "source":4014:4015 */ +// 0x00 +// /* "source":3986:4016 */ +// dup1 +// dup1 +// dup1 +// eofcreate{82} +// /* "source":3982:4017 */ +// pop +// /* "source":4062:4063 */ +// 0x00 +// /* "source":4034:4064 */ +// dup1 +// dup1 +// dup1 +// eofcreate{83} +// /* "source":4030:4065 */ +// pop +// /* "source":4110:4111 */ +// 0x00 +// /* "source":4082:4112 */ +// dup1 +// dup1 +// dup1 +// eofcreate{84} +// /* "source":4078:4113 */ +// pop +// /* "source":4158:4159 */ +// 0x00 +// /* "source":4130:4160 */ +// dup1 +// dup1 +// dup1 +// eofcreate{85} +// /* "source":4126:4161 */ +// pop +// /* "source":4206:4207 */ +// 0x00 +// /* "source":4178:4208 */ +// dup1 +// dup1 +// dup1 +// eofcreate{86} +// /* "source":4174:4209 */ +// pop +// /* "source":4254:4255 */ +// 0x00 +// /* "source":4226:4256 */ +// dup1 +// dup1 +// dup1 +// eofcreate{87} +// /* "source":4222:4257 */ +// pop +// /* "source":4302:4303 */ +// 0x00 +// /* "source":4274:4304 */ +// dup1 +// dup1 +// dup1 +// eofcreate{88} +// /* "source":4270:4305 */ +// pop +// /* "source":4350:4351 */ +// 0x00 +// /* "source":4322:4352 */ +// dup1 +// dup1 +// dup1 +// eofcreate{89} +// /* "source":4318:4353 */ +// pop +// /* "source":4398:4399 */ +// 0x00 +// /* "source":4370:4400 */ +// dup1 +// dup1 +// dup1 +// eofcreate{90} +// /* "source":4366:4401 */ +// pop +// /* "source":4446:4447 */ +// 0x00 +// /* "source":4418:4448 */ +// dup1 +// dup1 +// dup1 +// eofcreate{91} +// /* "source":4414:4449 */ +// pop +// /* "source":4494:4495 */ +// 0x00 +// /* "source":4466:4496 */ +// dup1 +// dup1 +// dup1 +// eofcreate{92} +// /* "source":4462:4497 */ +// pop +// /* "source":4542:4543 */ +// 0x00 +// /* "source":4514:4544 */ +// dup1 +// dup1 +// dup1 +// eofcreate{93} +// /* "source":4510:4545 */ +// pop +// /* "source":4590:4591 */ +// 0x00 +// /* "source":4562:4592 */ +// dup1 +// dup1 +// dup1 +// eofcreate{94} +// /* "source":4558:4593 */ +// pop +// /* "source":4638:4639 */ +// 0x00 +// /* "source":4610:4640 */ +// dup1 +// dup1 +// dup1 +// eofcreate{95} +// /* "source":4606:4641 */ +// pop +// /* "source":4686:4687 */ +// 0x00 +// /* "source":4658:4688 */ +// dup1 +// dup1 +// dup1 +// eofcreate{96} +// /* "source":4654:4689 */ +// pop +// /* "source":4734:4735 */ +// 0x00 +// /* "source":4706:4736 */ +// dup1 +// dup1 +// dup1 +// eofcreate{97} +// /* "source":4702:4737 */ +// pop +// /* "source":4782:4783 */ +// 0x00 +// /* "source":4754:4784 */ +// dup1 +// dup1 +// dup1 +// eofcreate{98} +// /* "source":4750:4785 */ +// pop +// /* "source":4830:4831 */ +// 0x00 +// /* "source":4802:4832 */ +// dup1 +// dup1 +// dup1 +// eofcreate{99} +// /* "source":4798:4833 */ +// pop +// /* "source":4878:4879 */ +// 0x00 +// /* "source":4850:4880 */ +// dup1 +// dup1 +// dup1 +// eofcreate{100} +// /* "source":4846:4881 */ +// pop +// /* "source":4926:4927 */ +// 0x00 +// /* "source":4898:4928 */ +// dup1 +// dup1 +// dup1 +// eofcreate{101} +// /* "source":4894:4929 */ +// pop +// /* "source":4974:4975 */ +// 0x00 +// /* "source":4946:4976 */ +// dup1 +// dup1 +// dup1 +// eofcreate{102} +// /* "source":4942:4977 */ +// pop +// /* "source":5022:5023 */ +// 0x00 +// /* "source":4994:5024 */ +// dup1 +// dup1 +// dup1 +// eofcreate{103} +// /* "source":4990:5025 */ +// pop +// /* "source":5070:5071 */ +// 0x00 +// /* "source":5042:5072 */ +// dup1 +// dup1 +// dup1 +// eofcreate{104} +// /* "source":5038:5073 */ +// pop +// /* "source":5118:5119 */ +// 0x00 +// /* "source":5090:5120 */ +// dup1 +// dup1 +// dup1 +// eofcreate{105} +// /* "source":5086:5121 */ +// pop +// /* "source":5166:5167 */ +// 0x00 +// /* "source":5138:5168 */ +// dup1 +// dup1 +// dup1 +// eofcreate{106} +// /* "source":5134:5169 */ +// pop +// /* "source":5214:5215 */ +// 0x00 +// /* "source":5186:5216 */ +// dup1 +// dup1 +// dup1 +// eofcreate{107} +// /* "source":5182:5217 */ +// pop +// /* "source":5262:5263 */ +// 0x00 +// /* "source":5234:5264 */ +// dup1 +// dup1 +// dup1 +// eofcreate{108} +// /* "source":5230:5265 */ +// pop +// /* "source":5310:5311 */ +// 0x00 +// /* "source":5282:5312 */ +// dup1 +// dup1 +// dup1 +// eofcreate{109} +// /* "source":5278:5313 */ +// pop +// /* "source":5358:5359 */ +// 0x00 +// /* "source":5330:5360 */ +// dup1 +// dup1 +// dup1 +// eofcreate{110} +// /* "source":5326:5361 */ +// pop +// /* "source":5406:5407 */ +// 0x00 +// /* "source":5378:5408 */ +// dup1 +// dup1 +// dup1 +// eofcreate{111} +// /* "source":5374:5409 */ +// pop +// /* "source":5454:5455 */ +// 0x00 +// /* "source":5426:5456 */ +// dup1 +// dup1 +// dup1 +// eofcreate{112} +// /* "source":5422:5457 */ +// pop +// /* "source":5502:5503 */ +// 0x00 +// /* "source":5474:5504 */ +// dup1 +// dup1 +// dup1 +// eofcreate{113} +// /* "source":5470:5505 */ +// pop +// /* "source":5550:5551 */ +// 0x00 +// /* "source":5522:5552 */ +// dup1 +// dup1 +// dup1 +// eofcreate{114} +// /* "source":5518:5553 */ +// pop +// /* "source":5598:5599 */ +// 0x00 +// /* "source":5570:5600 */ +// dup1 +// dup1 +// dup1 +// eofcreate{115} +// /* "source":5566:5601 */ +// pop +// /* "source":5646:5647 */ +// 0x00 +// /* "source":5618:5648 */ +// dup1 +// dup1 +// dup1 +// eofcreate{116} +// /* "source":5614:5649 */ +// pop +// /* "source":5694:5695 */ +// 0x00 +// /* "source":5666:5696 */ +// dup1 +// dup1 +// dup1 +// eofcreate{117} +// /* "source":5662:5697 */ +// pop +// /* "source":5742:5743 */ +// 0x00 +// /* "source":5714:5744 */ +// dup1 +// dup1 +// dup1 +// eofcreate{118} +// /* "source":5710:5745 */ +// pop +// /* "source":5790:5791 */ +// 0x00 +// /* "source":5762:5792 */ +// dup1 +// dup1 +// dup1 +// eofcreate{119} +// /* "source":5758:5793 */ +// pop +// /* "source":5838:5839 */ +// 0x00 +// /* "source":5810:5840 */ +// dup1 +// dup1 +// dup1 +// eofcreate{120} +// /* "source":5806:5841 */ +// pop +// /* "source":5886:5887 */ +// 0x00 +// /* "source":5858:5888 */ +// dup1 +// dup1 +// dup1 +// eofcreate{121} +// /* "source":5854:5889 */ +// pop +// /* "source":5934:5935 */ +// 0x00 +// /* "source":5906:5936 */ +// dup1 +// dup1 +// dup1 +// eofcreate{122} +// /* "source":5902:5937 */ +// pop +// /* "source":5982:5983 */ +// 0x00 +// /* "source":5954:5984 */ +// dup1 +// dup1 +// dup1 +// eofcreate{123} +// /* "source":5950:5985 */ +// pop +// /* "source":6030:6031 */ +// 0x00 +// /* "source":6002:6032 */ +// dup1 +// dup1 +// dup1 +// eofcreate{124} +// /* "source":5998:6033 */ +// pop +// /* "source":6078:6079 */ +// 0x00 +// /* "source":6050:6080 */ +// dup1 +// dup1 +// dup1 +// eofcreate{125} +// /* "source":6046:6081 */ +// pop +// /* "source":6126:6127 */ +// 0x00 +// /* "source":6098:6128 */ +// dup1 +// dup1 +// dup1 +// eofcreate{126} +// /* "source":6094:6129 */ +// pop +// /* "source":6174:6175 */ +// 0x00 +// /* "source":6146:6176 */ +// dup1 +// dup1 +// dup1 +// eofcreate{127} +// /* "source":6142:6177 */ +// pop +// /* "source":6222:6223 */ +// 0x00 +// /* "source":6194:6224 */ +// dup1 +// dup1 +// dup1 +// eofcreate{128} +// /* "source":6190:6225 */ +// pop +// /* "source":6270:6271 */ +// 0x00 +// /* "source":6242:6272 */ +// dup1 +// dup1 +// dup1 +// eofcreate{129} +// /* "source":6238:6273 */ +// pop +// /* "source":6318:6319 */ +// 0x00 +// /* "source":6290:6320 */ +// dup1 +// dup1 +// dup1 +// eofcreate{130} +// /* "source":6286:6321 */ +// pop +// /* "source":6366:6367 */ +// 0x00 +// /* "source":6338:6368 */ +// dup1 +// dup1 +// dup1 +// eofcreate{131} +// /* "source":6334:6369 */ +// pop +// /* "source":6414:6415 */ +// 0x00 +// /* "source":6386:6416 */ +// dup1 +// dup1 +// dup1 +// eofcreate{132} +// /* "source":6382:6417 */ +// pop +// /* "source":6462:6463 */ +// 0x00 +// /* "source":6434:6464 */ +// dup1 +// dup1 +// dup1 +// eofcreate{133} +// /* "source":6430:6465 */ +// pop +// /* "source":6510:6511 */ +// 0x00 +// /* "source":6482:6512 */ +// dup1 +// dup1 +// dup1 +// eofcreate{134} +// /* "source":6478:6513 */ +// pop +// /* "source":6558:6559 */ +// 0x00 +// /* "source":6530:6560 */ +// dup1 +// dup1 +// dup1 +// eofcreate{135} +// /* "source":6526:6561 */ +// pop +// /* "source":6606:6607 */ +// 0x00 +// /* "source":6578:6608 */ +// dup1 +// dup1 +// dup1 +// eofcreate{136} +// /* "source":6574:6609 */ +// pop +// /* "source":6654:6655 */ +// 0x00 +// /* "source":6626:6656 */ +// dup1 +// dup1 +// dup1 +// eofcreate{137} +// /* "source":6622:6657 */ +// pop +// /* "source":6702:6703 */ +// 0x00 +// /* "source":6674:6704 */ +// dup1 +// dup1 +// dup1 +// eofcreate{138} +// /* "source":6670:6705 */ +// pop +// /* "source":6750:6751 */ +// 0x00 +// /* "source":6722:6752 */ +// dup1 +// dup1 +// dup1 +// eofcreate{139} +// /* "source":6718:6753 */ +// pop +// /* "source":6798:6799 */ +// 0x00 +// /* "source":6770:6800 */ +// dup1 +// dup1 +// dup1 +// eofcreate{140} +// /* "source":6766:6801 */ +// pop +// /* "source":6846:6847 */ +// 0x00 +// /* "source":6818:6848 */ +// dup1 +// dup1 +// dup1 +// eofcreate{141} +// /* "source":6814:6849 */ +// pop +// /* "source":6894:6895 */ +// 0x00 +// /* "source":6866:6896 */ +// dup1 +// dup1 +// dup1 +// eofcreate{142} +// /* "source":6862:6897 */ +// pop +// /* "source":6942:6943 */ +// 0x00 +// /* "source":6914:6944 */ +// dup1 +// dup1 +// dup1 +// eofcreate{143} +// /* "source":6910:6945 */ +// pop +// /* "source":6990:6991 */ +// 0x00 +// /* "source":6962:6992 */ +// dup1 +// dup1 +// dup1 +// eofcreate{144} +// /* "source":6958:6993 */ +// pop +// /* "source":7038:7039 */ +// 0x00 +// /* "source":7010:7040 */ +// dup1 +// dup1 +// dup1 +// eofcreate{145} +// /* "source":7006:7041 */ +// pop +// /* "source":7086:7087 */ +// 0x00 +// /* "source":7058:7088 */ +// dup1 +// dup1 +// dup1 +// eofcreate{146} +// /* "source":7054:7089 */ +// pop +// /* "source":7134:7135 */ +// 0x00 +// /* "source":7106:7136 */ +// dup1 +// dup1 +// dup1 +// eofcreate{147} +// /* "source":7102:7137 */ +// pop +// /* "source":7182:7183 */ +// 0x00 +// /* "source":7154:7184 */ +// dup1 +// dup1 +// dup1 +// eofcreate{148} +// /* "source":7150:7185 */ +// pop +// /* "source":7230:7231 */ +// 0x00 +// /* "source":7202:7232 */ +// dup1 +// dup1 +// dup1 +// eofcreate{149} +// /* "source":7198:7233 */ +// pop +// /* "source":7278:7279 */ +// 0x00 +// /* "source":7250:7280 */ +// dup1 +// dup1 +// dup1 +// eofcreate{150} +// /* "source":7246:7281 */ +// pop +// /* "source":7326:7327 */ +// 0x00 +// /* "source":7298:7328 */ +// dup1 +// dup1 +// dup1 +// eofcreate{151} +// /* "source":7294:7329 */ +// pop +// /* "source":7374:7375 */ +// 0x00 +// /* "source":7346:7376 */ +// dup1 +// dup1 +// dup1 +// eofcreate{152} +// /* "source":7342:7377 */ +// pop +// /* "source":7422:7423 */ +// 0x00 +// /* "source":7394:7424 */ +// dup1 +// dup1 +// dup1 +// eofcreate{153} +// /* "source":7390:7425 */ +// pop +// /* "source":7470:7471 */ +// 0x00 +// /* "source":7442:7472 */ +// dup1 +// dup1 +// dup1 +// eofcreate{154} +// /* "source":7438:7473 */ +// pop +// /* "source":7518:7519 */ +// 0x00 +// /* "source":7490:7520 */ +// dup1 +// dup1 +// dup1 +// eofcreate{155} +// /* "source":7486:7521 */ +// pop +// /* "source":7566:7567 */ +// 0x00 +// /* "source":7538:7568 */ +// dup1 +// dup1 +// dup1 +// eofcreate{156} +// /* "source":7534:7569 */ +// pop +// /* "source":7614:7615 */ +// 0x00 +// /* "source":7586:7616 */ +// dup1 +// dup1 +// dup1 +// eofcreate{157} +// /* "source":7582:7617 */ +// pop +// /* "source":7662:7663 */ +// 0x00 +// /* "source":7634:7664 */ +// dup1 +// dup1 +// dup1 +// eofcreate{158} +// /* "source":7630:7665 */ +// pop +// /* "source":7710:7711 */ +// 0x00 +// /* "source":7682:7712 */ +// dup1 +// dup1 +// dup1 +// eofcreate{159} +// /* "source":7678:7713 */ +// pop +// /* "source":7758:7759 */ +// 0x00 +// /* "source":7730:7760 */ +// dup1 +// dup1 +// dup1 +// eofcreate{160} +// /* "source":7726:7761 */ +// pop +// /* "source":7806:7807 */ +// 0x00 +// /* "source":7778:7808 */ +// dup1 +// dup1 +// dup1 +// eofcreate{161} +// /* "source":7774:7809 */ +// pop +// /* "source":7854:7855 */ +// 0x00 +// /* "source":7826:7856 */ +// dup1 +// dup1 +// dup1 +// eofcreate{162} +// /* "source":7822:7857 */ +// pop +// /* "source":7902:7903 */ +// 0x00 +// /* "source":7874:7904 */ +// dup1 +// dup1 +// dup1 +// eofcreate{163} +// /* "source":7870:7905 */ +// pop +// /* "source":7950:7951 */ +// 0x00 +// /* "source":7922:7952 */ +// dup1 +// dup1 +// dup1 +// eofcreate{164} +// /* "source":7918:7953 */ +// pop +// /* "source":7998:7999 */ +// 0x00 +// /* "source":7970:8000 */ +// dup1 +// dup1 +// dup1 +// eofcreate{165} +// /* "source":7966:8001 */ +// pop +// /* "source":8046:8047 */ +// 0x00 +// /* "source":8018:8048 */ +// dup1 +// dup1 +// dup1 +// eofcreate{166} +// /* "source":8014:8049 */ +// pop +// /* "source":8094:8095 */ +// 0x00 +// /* "source":8066:8096 */ +// dup1 +// dup1 +// dup1 +// eofcreate{167} +// /* "source":8062:8097 */ +// pop +// /* "source":8142:8143 */ +// 0x00 +// /* "source":8114:8144 */ +// dup1 +// dup1 +// dup1 +// eofcreate{168} +// /* "source":8110:8145 */ +// pop +// /* "source":8190:8191 */ +// 0x00 +// /* "source":8162:8192 */ +// dup1 +// dup1 +// dup1 +// eofcreate{169} +// /* "source":8158:8193 */ +// pop +// /* "source":8238:8239 */ +// 0x00 +// /* "source":8210:8240 */ +// dup1 +// dup1 +// dup1 +// eofcreate{170} +// /* "source":8206:8241 */ +// pop +// /* "source":8286:8287 */ +// 0x00 +// /* "source":8258:8288 */ +// dup1 +// dup1 +// dup1 +// eofcreate{171} +// /* "source":8254:8289 */ +// pop +// /* "source":8334:8335 */ +// 0x00 +// /* "source":8306:8336 */ +// dup1 +// dup1 +// dup1 +// eofcreate{172} +// /* "source":8302:8337 */ +// pop +// /* "source":8382:8383 */ +// 0x00 +// /* "source":8354:8384 */ +// dup1 +// dup1 +// dup1 +// eofcreate{173} +// /* "source":8350:8385 */ +// pop +// /* "source":8430:8431 */ +// 0x00 +// /* "source":8402:8432 */ +// dup1 +// dup1 +// dup1 +// eofcreate{174} +// /* "source":8398:8433 */ +// pop +// /* "source":8478:8479 */ +// 0x00 +// /* "source":8450:8480 */ +// dup1 +// dup1 +// dup1 +// eofcreate{175} +// /* "source":8446:8481 */ +// pop +// /* "source":8526:8527 */ +// 0x00 +// /* "source":8498:8528 */ +// dup1 +// dup1 +// dup1 +// eofcreate{176} +// /* "source":8494:8529 */ +// pop +// /* "source":8574:8575 */ +// 0x00 +// /* "source":8546:8576 */ +// dup1 +// dup1 +// dup1 +// eofcreate{177} +// /* "source":8542:8577 */ +// pop +// /* "source":8622:8623 */ +// 0x00 +// /* "source":8594:8624 */ +// dup1 +// dup1 +// dup1 +// eofcreate{178} +// /* "source":8590:8625 */ +// pop +// /* "source":8670:8671 */ +// 0x00 +// /* "source":8642:8672 */ +// dup1 +// dup1 +// dup1 +// eofcreate{179} +// /* "source":8638:8673 */ +// pop +// /* "source":8718:8719 */ +// 0x00 +// /* "source":8690:8720 */ +// dup1 +// dup1 +// dup1 +// eofcreate{180} +// /* "source":8686:8721 */ +// pop +// /* "source":8766:8767 */ +// 0x00 +// /* "source":8738:8768 */ +// dup1 +// dup1 +// dup1 +// eofcreate{181} +// /* "source":8734:8769 */ +// pop +// /* "source":8814:8815 */ +// 0x00 +// /* "source":8786:8816 */ +// dup1 +// dup1 +// dup1 +// eofcreate{182} +// /* "source":8782:8817 */ +// pop +// /* "source":8862:8863 */ +// 0x00 +// /* "source":8834:8864 */ +// dup1 +// dup1 +// dup1 +// eofcreate{183} +// /* "source":8830:8865 */ +// pop +// /* "source":8910:8911 */ +// 0x00 +// /* "source":8882:8912 */ +// dup1 +// dup1 +// dup1 +// eofcreate{184} +// /* "source":8878:8913 */ +// pop +// /* "source":8958:8959 */ +// 0x00 +// /* "source":8930:8960 */ +// dup1 +// dup1 +// dup1 +// eofcreate{185} +// /* "source":8926:8961 */ +// pop +// /* "source":9006:9007 */ +// 0x00 +// /* "source":8978:9008 */ +// dup1 +// dup1 +// dup1 +// eofcreate{186} +// /* "source":8974:9009 */ +// pop +// /* "source":9054:9055 */ +// 0x00 +// /* "source":9026:9056 */ +// dup1 +// dup1 +// dup1 +// eofcreate{187} +// /* "source":9022:9057 */ +// pop +// /* "source":9102:9103 */ +// 0x00 +// /* "source":9074:9104 */ +// dup1 +// dup1 +// dup1 +// eofcreate{188} +// /* "source":9070:9105 */ +// pop +// /* "source":9150:9151 */ +// 0x00 +// /* "source":9122:9152 */ +// dup1 +// dup1 +// dup1 +// eofcreate{189} +// /* "source":9118:9153 */ +// pop +// /* "source":9198:9199 */ +// 0x00 +// /* "source":9170:9200 */ +// dup1 +// dup1 +// dup1 +// eofcreate{190} +// /* "source":9166:9201 */ +// pop +// /* "source":9246:9247 */ +// 0x00 +// /* "source":9218:9248 */ +// dup1 +// dup1 +// dup1 +// eofcreate{191} +// /* "source":9214:9249 */ +// pop +// /* "source":9294:9295 */ +// 0x00 +// /* "source":9266:9296 */ +// dup1 +// dup1 +// dup1 +// eofcreate{192} +// /* "source":9262:9297 */ +// pop +// /* "source":9342:9343 */ +// 0x00 +// /* "source":9314:9344 */ +// dup1 +// dup1 +// dup1 +// eofcreate{193} +// /* "source":9310:9345 */ +// pop +// /* "source":9390:9391 */ +// 0x00 +// /* "source":9362:9392 */ +// dup1 +// dup1 +// dup1 +// eofcreate{194} +// /* "source":9358:9393 */ +// pop +// /* "source":9438:9439 */ +// 0x00 +// /* "source":9410:9440 */ +// dup1 +// dup1 +// dup1 +// eofcreate{195} +// /* "source":9406:9441 */ +// pop +// /* "source":9486:9487 */ +// 0x00 +// /* "source":9458:9488 */ +// dup1 +// dup1 +// dup1 +// eofcreate{196} +// /* "source":9454:9489 */ +// pop +// /* "source":9534:9535 */ +// 0x00 +// /* "source":9506:9536 */ +// dup1 +// dup1 +// dup1 +// eofcreate{197} +// /* "source":9502:9537 */ +// pop +// /* "source":9582:9583 */ +// 0x00 +// /* "source":9554:9584 */ +// dup1 +// dup1 +// dup1 +// eofcreate{198} +// /* "source":9550:9585 */ +// pop +// /* "source":9630:9631 */ +// 0x00 +// /* "source":9602:9632 */ +// dup1 +// dup1 +// dup1 +// eofcreate{199} +// /* "source":9598:9633 */ +// pop +// /* "source":9678:9679 */ +// 0x00 +// /* "source":9650:9680 */ +// dup1 +// dup1 +// dup1 +// eofcreate{200} +// /* "source":9646:9681 */ +// pop +// /* "source":9726:9727 */ +// 0x00 +// /* "source":9698:9728 */ +// dup1 +// dup1 +// dup1 +// eofcreate{201} +// /* "source":9694:9729 */ +// pop +// /* "source":9774:9775 */ +// 0x00 +// /* "source":9746:9776 */ +// dup1 +// dup1 +// dup1 +// eofcreate{202} +// /* "source":9742:9777 */ +// pop +// /* "source":9822:9823 */ +// 0x00 +// /* "source":9794:9824 */ +// dup1 +// dup1 +// dup1 +// eofcreate{203} +// /* "source":9790:9825 */ +// pop +// /* "source":9870:9871 */ +// 0x00 +// /* "source":9842:9872 */ +// dup1 +// dup1 +// dup1 +// eofcreate{204} +// /* "source":9838:9873 */ +// pop +// /* "source":9918:9919 */ +// 0x00 +// /* "source":9890:9920 */ +// dup1 +// dup1 +// dup1 +// eofcreate{205} +// /* "source":9886:9921 */ +// pop +// /* "source":9966:9967 */ +// 0x00 +// /* "source":9938:9968 */ +// dup1 +// dup1 +// dup1 +// eofcreate{206} +// /* "source":9934:9969 */ +// pop +// /* "source":10014:10015 */ +// 0x00 +// /* "source":9986:10016 */ +// dup1 +// dup1 +// dup1 +// eofcreate{207} +// /* "source":9982:10017 */ +// pop +// /* "source":10062:10063 */ +// 0x00 +// /* "source":10034:10064 */ +// dup1 +// dup1 +// dup1 +// eofcreate{208} +// /* "source":10030:10065 */ +// pop +// /* "source":10110:10111 */ +// 0x00 +// /* "source":10082:10112 */ +// dup1 +// dup1 +// dup1 +// eofcreate{209} +// /* "source":10078:10113 */ +// pop +// /* "source":10158:10159 */ +// 0x00 +// /* "source":10130:10160 */ +// dup1 +// dup1 +// dup1 +// eofcreate{210} +// /* "source":10126:10161 */ +// pop +// /* "source":10206:10207 */ +// 0x00 +// /* "source":10178:10208 */ +// dup1 +// dup1 +// dup1 +// eofcreate{211} +// /* "source":10174:10209 */ +// pop +// /* "source":10254:10255 */ +// 0x00 +// /* "source":10226:10256 */ +// dup1 +// dup1 +// dup1 +// eofcreate{212} +// /* "source":10222:10257 */ +// pop +// /* "source":10302:10303 */ +// 0x00 +// /* "source":10274:10304 */ +// dup1 +// dup1 +// dup1 +// eofcreate{213} +// /* "source":10270:10305 */ +// pop +// /* "source":10350:10351 */ +// 0x00 +// /* "source":10322:10352 */ +// dup1 +// dup1 +// dup1 +// eofcreate{214} +// /* "source":10318:10353 */ +// pop +// /* "source":10398:10399 */ +// 0x00 +// /* "source":10370:10400 */ +// dup1 +// dup1 +// dup1 +// eofcreate{215} +// /* "source":10366:10401 */ +// pop +// /* "source":10446:10447 */ +// 0x00 +// /* "source":10418:10448 */ +// dup1 +// dup1 +// dup1 +// eofcreate{216} +// /* "source":10414:10449 */ +// pop +// /* "source":10494:10495 */ +// 0x00 +// /* "source":10466:10496 */ +// dup1 +// dup1 +// dup1 +// eofcreate{217} +// /* "source":10462:10497 */ +// pop +// /* "source":10542:10543 */ +// 0x00 +// /* "source":10514:10544 */ +// dup1 +// dup1 +// dup1 +// eofcreate{218} +// /* "source":10510:10545 */ +// pop +// /* "source":10590:10591 */ +// 0x00 +// /* "source":10562:10592 */ +// dup1 +// dup1 +// dup1 +// eofcreate{219} +// /* "source":10558:10593 */ +// pop +// /* "source":10638:10639 */ +// 0x00 +// /* "source":10610:10640 */ +// dup1 +// dup1 +// dup1 +// eofcreate{220} +// /* "source":10606:10641 */ +// pop +// /* "source":10686:10687 */ +// 0x00 +// /* "source":10658:10688 */ +// dup1 +// dup1 +// dup1 +// eofcreate{221} +// /* "source":10654:10689 */ +// pop +// /* "source":10734:10735 */ +// 0x00 +// /* "source":10706:10736 */ +// dup1 +// dup1 +// dup1 +// eofcreate{222} +// /* "source":10702:10737 */ +// pop +// /* "source":10782:10783 */ +// 0x00 +// /* "source":10754:10784 */ +// dup1 +// dup1 +// dup1 +// eofcreate{223} +// /* "source":10750:10785 */ +// pop +// /* "source":10830:10831 */ +// 0x00 +// /* "source":10802:10832 */ +// dup1 +// dup1 +// dup1 +// eofcreate{224} +// /* "source":10798:10833 */ +// pop +// /* "source":10878:10879 */ +// 0x00 +// /* "source":10850:10880 */ +// dup1 +// dup1 +// dup1 +// eofcreate{225} +// /* "source":10846:10881 */ +// pop +// /* "source":10926:10927 */ +// 0x00 +// /* "source":10898:10928 */ +// dup1 +// dup1 +// dup1 +// eofcreate{226} +// /* "source":10894:10929 */ +// pop +// /* "source":10974:10975 */ +// 0x00 +// /* "source":10946:10976 */ +// dup1 +// dup1 +// dup1 +// eofcreate{227} +// /* "source":10942:10977 */ +// pop +// /* "source":11022:11023 */ +// 0x00 +// /* "source":10994:11024 */ +// dup1 +// dup1 +// dup1 +// eofcreate{228} +// /* "source":10990:11025 */ +// pop +// /* "source":11070:11071 */ +// 0x00 +// /* "source":11042:11072 */ +// dup1 +// dup1 +// dup1 +// eofcreate{229} +// /* "source":11038:11073 */ +// pop +// /* "source":11118:11119 */ +// 0x00 +// /* "source":11090:11120 */ +// dup1 +// dup1 +// dup1 +// eofcreate{230} +// /* "source":11086:11121 */ +// pop +// /* "source":11166:11167 */ +// 0x00 +// /* "source":11138:11168 */ +// dup1 +// dup1 +// dup1 +// eofcreate{231} +// /* "source":11134:11169 */ +// pop +// /* "source":11214:11215 */ +// 0x00 +// /* "source":11186:11216 */ +// dup1 +// dup1 +// dup1 +// eofcreate{232} +// /* "source":11182:11217 */ +// pop +// /* "source":11262:11263 */ +// 0x00 +// /* "source":11234:11264 */ +// dup1 +// dup1 +// dup1 +// eofcreate{233} +// /* "source":11230:11265 */ +// pop +// /* "source":11310:11311 */ +// 0x00 +// /* "source":11282:11312 */ +// dup1 +// dup1 +// dup1 +// eofcreate{234} +// /* "source":11278:11313 */ +// pop +// /* "source":11358:11359 */ +// 0x00 +// /* "source":11330:11360 */ +// dup1 +// dup1 +// dup1 +// eofcreate{235} +// /* "source":11326:11361 */ +// pop +// /* "source":11406:11407 */ +// 0x00 +// /* "source":11378:11408 */ +// dup1 +// dup1 +// dup1 +// eofcreate{236} +// /* "source":11374:11409 */ +// pop +// /* "source":11454:11455 */ +// 0x00 +// /* "source":11426:11456 */ +// dup1 +// dup1 +// dup1 +// eofcreate{237} +// /* "source":11422:11457 */ +// pop +// /* "source":11502:11503 */ +// 0x00 +// /* "source":11474:11504 */ +// dup1 +// dup1 +// dup1 +// eofcreate{238} +// /* "source":11470:11505 */ +// pop +// /* "source":11550:11551 */ +// 0x00 +// /* "source":11522:11552 */ +// dup1 +// dup1 +// dup1 +// eofcreate{239} +// /* "source":11518:11553 */ +// pop +// /* "source":11598:11599 */ +// 0x00 +// /* "source":11570:11600 */ +// dup1 +// dup1 +// dup1 +// eofcreate{240} +// /* "source":11566:11601 */ +// pop +// /* "source":11646:11647 */ +// 0x00 +// /* "source":11618:11648 */ +// dup1 +// dup1 +// dup1 +// eofcreate{241} +// /* "source":11614:11649 */ +// pop +// /* "source":11694:11695 */ +// 0x00 +// /* "source":11666:11696 */ +// dup1 +// dup1 +// dup1 +// eofcreate{242} +// /* "source":11662:11697 */ +// pop +// /* "source":11742:11743 */ +// 0x00 +// /* "source":11714:11744 */ +// dup1 +// dup1 +// dup1 +// eofcreate{243} +// /* "source":11710:11745 */ +// pop +// /* "source":11790:11791 */ +// 0x00 +// /* "source":11762:11792 */ +// dup1 +// dup1 +// dup1 +// eofcreate{244} +// /* "source":11758:11793 */ +// pop +// /* "source":11838:11839 */ +// 0x00 +// /* "source":11810:11840 */ +// dup1 +// dup1 +// dup1 +// eofcreate{245} +// /* "source":11806:11841 */ +// pop +// /* "source":11886:11887 */ +// 0x00 +// /* "source":11858:11888 */ +// dup1 +// dup1 +// dup1 +// eofcreate{246} +// /* "source":11854:11889 */ +// pop +// /* "source":11934:11935 */ +// 0x00 +// /* "source":11906:11936 */ +// dup1 +// dup1 +// dup1 +// eofcreate{247} +// /* "source":11902:11937 */ +// pop +// /* "source":11982:11983 */ +// 0x00 +// /* "source":11954:11984 */ +// dup1 +// dup1 +// dup1 +// eofcreate{248} +// /* "source":11950:11985 */ +// pop +// /* "source":12030:12031 */ +// 0x00 +// /* "source":12002:12032 */ +// dup1 +// dup1 +// dup1 +// eofcreate{249} +// /* "source":11998:12033 */ +// pop +// /* "source":12078:12079 */ +// 0x00 +// /* "source":12050:12080 */ +// dup1 +// dup1 +// dup1 +// eofcreate{250} +// /* "source":12046:12081 */ +// pop +// /* "source":12126:12127 */ +// 0x00 +// /* "source":12098:12128 */ +// dup1 +// dup1 +// dup1 +// eofcreate{251} +// /* "source":12094:12129 */ +// pop +// /* "source":12174:12175 */ +// 0x00 +// /* "source":12146:12176 */ +// dup1 +// dup1 +// dup1 +// eofcreate{252} +// /* "source":12142:12177 */ +// pop +// /* "source":12222:12223 */ +// 0x00 +// /* "source":12194:12224 */ +// dup1 +// dup1 +// dup1 +// eofcreate{253} +// /* "source":12190:12225 */ +// pop +// /* "source":12270:12271 */ +// 0x00 +// /* "source":12242:12272 */ +// dup1 +// dup1 +// dup1 +// eofcreate{254} +// /* "source":12238:12273 */ +// pop +// /* "source":12318:12319 */ +// 0x00 +// /* "source":12290:12320 */ +// dup1 +// dup1 +// dup1 +// eofcreate{255} +// /* "source":12286:12321 */ +// pop +// /* "source":22:12337 */ +// stop +// stop +// +// sub_0: assembly { +// /* "source":12372:12379 */ +// stop +// } +// +// sub_1: assembly { +// /* "source":12420:12427 */ +// stop +// } +// +// sub_2: assembly { +// /* "source":12468:12475 */ +// stop +// } +// +// sub_3: assembly { +// /* "source":12516:12523 */ +// stop +// } +// +// sub_4: assembly { +// /* "source":12564:12571 */ +// stop +// } +// +// sub_5: assembly { +// /* "source":12612:12619 */ +// stop +// } +// +// sub_6: assembly { +// /* "source":12660:12667 */ +// stop +// } +// +// sub_7: assembly { +// /* "source":12708:12715 */ +// stop +// } +// +// sub_8: assembly { +// /* "source":12756:12763 */ +// stop +// } +// +// sub_9: assembly { +// /* "source":12804:12811 */ +// stop +// } +// +// sub_10: assembly { +// /* "source":12852:12859 */ +// stop +// } +// +// sub_11: assembly { +// /* "source":12900:12907 */ +// stop +// } +// +// sub_12: assembly { +// /* "source":12948:12955 */ +// stop +// } +// +// sub_13: assembly { +// /* "source":12996:13003 */ +// stop +// } +// +// sub_14: assembly { +// /* "source":13044:13051 */ +// stop +// } +// +// sub_15: assembly { +// /* "source":13092:13099 */ +// stop +// } +// +// sub_16: assembly { +// /* "source":13140:13147 */ +// stop +// } +// +// sub_17: assembly { +// /* "source":13188:13195 */ +// stop +// } +// +// sub_18: assembly { +// /* "source":13236:13243 */ +// stop +// } +// +// sub_19: assembly { +// /* "source":13284:13291 */ +// stop +// } +// +// sub_20: assembly { +// /* "source":13332:13339 */ +// stop +// } +// +// sub_21: assembly { +// /* "source":13380:13387 */ +// stop +// } +// +// sub_22: assembly { +// /* "source":13428:13435 */ +// stop +// } +// +// sub_23: assembly { +// /* "source":13476:13483 */ +// stop +// } +// +// sub_24: assembly { +// /* "source":13524:13531 */ +// stop +// } +// +// sub_25: assembly { +// /* "source":13572:13579 */ +// stop +// } +// +// sub_26: assembly { +// /* "source":13620:13627 */ +// stop +// } +// +// sub_27: assembly { +// /* "source":13668:13675 */ +// stop +// } +// +// sub_28: assembly { +// /* "source":13716:13723 */ +// stop +// } +// +// sub_29: assembly { +// /* "source":13764:13771 */ +// stop +// } +// +// sub_30: assembly { +// /* "source":13812:13819 */ +// stop +// } +// +// sub_31: assembly { +// /* "source":13860:13867 */ +// stop +// } +// +// sub_32: assembly { +// /* "source":13908:13915 */ +// stop +// } +// +// sub_33: assembly { +// /* "source":13956:13963 */ +// stop +// } +// +// sub_34: assembly { +// /* "source":14004:14011 */ +// stop +// } +// +// sub_35: assembly { +// /* "source":14052:14059 */ +// stop +// } +// +// sub_36: assembly { +// /* "source":14100:14107 */ +// stop +// } +// +// sub_37: assembly { +// /* "source":14148:14155 */ +// stop +// } +// +// sub_38: assembly { +// /* "source":14196:14203 */ +// stop +// } +// +// sub_39: assembly { +// /* "source":14244:14251 */ +// stop +// } +// +// sub_40: assembly { +// /* "source":14292:14299 */ +// stop +// } +// +// sub_41: assembly { +// /* "source":14340:14347 */ +// stop +// } +// +// sub_42: assembly { +// /* "source":14388:14395 */ +// stop +// } +// +// sub_43: assembly { +// /* "source":14436:14443 */ +// stop +// } +// +// sub_44: assembly { +// /* "source":14484:14491 */ +// stop +// } +// +// sub_45: assembly { +// /* "source":14532:14539 */ +// stop +// } +// +// sub_46: assembly { +// /* "source":14580:14587 */ +// stop +// } +// +// sub_47: assembly { +// /* "source":14628:14635 */ +// stop +// } +// +// sub_48: assembly { +// /* "source":14676:14683 */ +// stop +// } +// +// sub_49: assembly { +// /* "source":14724:14731 */ +// stop +// } +// +// sub_50: assembly { +// /* "source":14772:14779 */ +// stop +// } +// +// sub_51: assembly { +// /* "source":14820:14827 */ +// stop +// } +// +// sub_52: assembly { +// /* "source":14868:14875 */ +// stop +// } +// +// sub_53: assembly { +// /* "source":14916:14923 */ +// stop +// } +// +// sub_54: assembly { +// /* "source":14964:14971 */ +// stop +// } +// +// sub_55: assembly { +// /* "source":15012:15019 */ +// stop +// } +// +// sub_56: assembly { +// /* "source":15060:15067 */ +// stop +// } +// +// sub_57: assembly { +// /* "source":15108:15115 */ +// stop +// } +// +// sub_58: assembly { +// /* "source":15156:15163 */ +// stop +// } +// +// sub_59: assembly { +// /* "source":15204:15211 */ +// stop +// } +// +// sub_60: assembly { +// /* "source":15252:15259 */ +// stop +// } +// +// sub_61: assembly { +// /* "source":15300:15307 */ +// stop +// } +// +// sub_62: assembly { +// /* "source":15348:15355 */ +// stop +// } +// +// sub_63: assembly { +// /* "source":15396:15403 */ +// stop +// } +// +// sub_64: assembly { +// /* "source":15444:15451 */ +// stop +// } +// +// sub_65: assembly { +// /* "source":15492:15499 */ +// stop +// } +// +// sub_66: assembly { +// /* "source":15540:15547 */ +// stop +// } +// +// sub_67: assembly { +// /* "source":15588:15595 */ +// stop +// } +// +// sub_68: assembly { +// /* "source":15636:15643 */ +// stop +// } +// +// sub_69: assembly { +// /* "source":15684:15691 */ +// stop +// } +// +// sub_70: assembly { +// /* "source":15732:15739 */ +// stop +// } +// +// sub_71: assembly { +// /* "source":15780:15787 */ +// stop +// } +// +// sub_72: assembly { +// /* "source":15828:15835 */ +// stop +// } +// +// sub_73: assembly { +// /* "source":15876:15883 */ +// stop +// } +// +// sub_74: assembly { +// /* "source":15924:15931 */ +// stop +// } +// +// sub_75: assembly { +// /* "source":15972:15979 */ +// stop +// } +// +// sub_76: assembly { +// /* "source":16020:16027 */ +// stop +// } +// +// sub_77: assembly { +// /* "source":16068:16075 */ +// stop +// } +// +// sub_78: assembly { +// /* "source":16116:16123 */ +// stop +// } +// +// sub_79: assembly { +// /* "source":16164:16171 */ +// stop +// } +// +// sub_80: assembly { +// /* "source":16212:16219 */ +// stop +// } +// +// sub_81: assembly { +// /* "source":16260:16267 */ +// stop +// } +// +// sub_82: assembly { +// /* "source":16308:16315 */ +// stop +// } +// +// sub_83: assembly { +// /* "source":16356:16363 */ +// stop +// } +// +// sub_84: assembly { +// /* "source":16404:16411 */ +// stop +// } +// +// sub_85: assembly { +// /* "source":16452:16459 */ +// stop +// } +// +// sub_86: assembly { +// /* "source":16500:16507 */ +// stop +// } +// +// sub_87: assembly { +// /* "source":16548:16555 */ +// stop +// } +// +// sub_88: assembly { +// /* "source":16596:16603 */ +// stop +// } +// +// sub_89: assembly { +// /* "source":16644:16651 */ +// stop +// } +// +// sub_90: assembly { +// /* "source":16692:16699 */ +// stop +// } +// +// sub_91: assembly { +// /* "source":16740:16747 */ +// stop +// } +// +// sub_92: assembly { +// /* "source":16788:16795 */ +// stop +// } +// +// sub_93: assembly { +// /* "source":16836:16843 */ +// stop +// } +// +// sub_94: assembly { +// /* "source":16884:16891 */ +// stop +// } +// +// sub_95: assembly { +// /* "source":16932:16939 */ +// stop +// } +// +// sub_96: assembly { +// /* "source":16980:16987 */ +// stop +// } +// +// sub_97: assembly { +// /* "source":17028:17035 */ +// stop +// } +// +// sub_98: assembly { +// /* "source":17076:17083 */ +// stop +// } +// +// sub_99: assembly { +// /* "source":17124:17131 */ +// stop +// } +// +// sub_100: assembly { +// /* "source":17172:17179 */ +// stop +// } +// +// sub_101: assembly { +// /* "source":17220:17227 */ +// stop +// } +// +// sub_102: assembly { +// /* "source":17268:17275 */ +// stop +// } +// +// sub_103: assembly { +// /* "source":17316:17323 */ +// stop +// } +// +// sub_104: assembly { +// /* "source":17364:17371 */ +// stop +// } +// +// sub_105: assembly { +// /* "source":17412:17419 */ +// stop +// } +// +// sub_106: assembly { +// /* "source":17460:17467 */ +// stop +// } +// +// sub_107: assembly { +// /* "source":17508:17515 */ +// stop +// } +// +// sub_108: assembly { +// /* "source":17556:17563 */ +// stop +// } +// +// sub_109: assembly { +// /* "source":17604:17611 */ +// stop +// } +// +// sub_110: assembly { +// /* "source":17652:17659 */ +// stop +// } +// +// sub_111: assembly { +// /* "source":17700:17707 */ +// stop +// } +// +// sub_112: assembly { +// /* "source":17748:17755 */ +// stop +// } +// +// sub_113: assembly { +// /* "source":17796:17803 */ +// stop +// } +// +// sub_114: assembly { +// /* "source":17844:17851 */ +// stop +// } +// +// sub_115: assembly { +// /* "source":17892:17899 */ +// stop +// } +// +// sub_116: assembly { +// /* "source":17940:17947 */ +// stop +// } +// +// sub_117: assembly { +// /* "source":17988:17995 */ +// stop +// } +// +// sub_118: assembly { +// /* "source":18036:18043 */ +// stop +// } +// +// sub_119: assembly { +// /* "source":18084:18091 */ +// stop +// } +// +// sub_120: assembly { +// /* "source":18132:18139 */ +// stop +// } +// +// sub_121: assembly { +// /* "source":18180:18187 */ +// stop +// } +// +// sub_122: assembly { +// /* "source":18228:18235 */ +// stop +// } +// +// sub_123: assembly { +// /* "source":18276:18283 */ +// stop +// } +// +// sub_124: assembly { +// /* "source":18324:18331 */ +// stop +// } +// +// sub_125: assembly { +// /* "source":18372:18379 */ +// stop +// } +// +// sub_126: assembly { +// /* "source":18420:18427 */ +// stop +// } +// +// sub_127: assembly { +// /* "source":18468:18475 */ +// stop +// } +// +// sub_128: assembly { +// /* "source":18516:18523 */ +// stop +// } +// +// sub_129: assembly { +// /* "source":18564:18571 */ +// stop +// } +// +// sub_130: assembly { +// /* "source":18612:18619 */ +// stop +// } +// +// sub_131: assembly { +// /* "source":18660:18667 */ +// stop +// } +// +// sub_132: assembly { +// /* "source":18708:18715 */ +// stop +// } +// +// sub_133: assembly { +// /* "source":18756:18763 */ +// stop +// } +// +// sub_134: assembly { +// /* "source":18804:18811 */ +// stop +// } +// +// sub_135: assembly { +// /* "source":18852:18859 */ +// stop +// } +// +// sub_136: assembly { +// /* "source":18900:18907 */ +// stop +// } +// +// sub_137: assembly { +// /* "source":18948:18955 */ +// stop +// } +// +// sub_138: assembly { +// /* "source":18996:19003 */ +// stop +// } +// +// sub_139: assembly { +// /* "source":19044:19051 */ +// stop +// } +// +// sub_140: assembly { +// /* "source":19092:19099 */ +// stop +// } +// +// sub_141: assembly { +// /* "source":19140:19147 */ +// stop +// } +// +// sub_142: assembly { +// /* "source":19188:19195 */ +// stop +// } +// +// sub_143: assembly { +// /* "source":19236:19243 */ +// stop +// } +// +// sub_144: assembly { +// /* "source":19284:19291 */ +// stop +// } +// +// sub_145: assembly { +// /* "source":19332:19339 */ +// stop +// } +// +// sub_146: assembly { +// /* "source":19380:19387 */ +// stop +// } +// +// sub_147: assembly { +// /* "source":19428:19435 */ +// stop +// } +// +// sub_148: assembly { +// /* "source":19476:19483 */ +// stop +// } +// +// sub_149: assembly { +// /* "source":19524:19531 */ +// stop +// } +// +// sub_150: assembly { +// /* "source":19572:19579 */ +// stop +// } +// +// sub_151: assembly { +// /* "source":19620:19627 */ +// stop +// } +// +// sub_152: assembly { +// /* "source":19668:19675 */ +// stop +// } +// +// sub_153: assembly { +// /* "source":19716:19723 */ +// stop +// } +// +// sub_154: assembly { +// /* "source":19764:19771 */ +// stop +// } +// +// sub_155: assembly { +// /* "source":19812:19819 */ +// stop +// } +// +// sub_156: assembly { +// /* "source":19860:19867 */ +// stop +// } +// +// sub_157: assembly { +// /* "source":19908:19915 */ +// stop +// } +// +// sub_158: assembly { +// /* "source":19956:19963 */ +// stop +// } +// +// sub_159: assembly { +// /* "source":20004:20011 */ +// stop +// } +// +// sub_160: assembly { +// /* "source":20052:20059 */ +// stop +// } +// +// sub_161: assembly { +// /* "source":20100:20107 */ +// stop +// } +// +// sub_162: assembly { +// /* "source":20148:20155 */ +// stop +// } +// +// sub_163: assembly { +// /* "source":20196:20203 */ +// stop +// } +// +// sub_164: assembly { +// /* "source":20244:20251 */ +// stop +// } +// +// sub_165: assembly { +// /* "source":20292:20299 */ +// stop +// } +// +// sub_166: assembly { +// /* "source":20340:20347 */ +// stop +// } +// +// sub_167: assembly { +// /* "source":20388:20395 */ +// stop +// } +// +// sub_168: assembly { +// /* "source":20436:20443 */ +// stop +// } +// +// sub_169: assembly { +// /* "source":20484:20491 */ +// stop +// } +// +// sub_170: assembly { +// /* "source":20532:20539 */ +// stop +// } +// +// sub_171: assembly { +// /* "source":20580:20587 */ +// stop +// } +// +// sub_172: assembly { +// /* "source":20628:20635 */ +// stop +// } +// +// sub_173: assembly { +// /* "source":20676:20683 */ +// stop +// } +// +// sub_174: assembly { +// /* "source":20724:20731 */ +// stop +// } +// +// sub_175: assembly { +// /* "source":20772:20779 */ +// stop +// } +// +// sub_176: assembly { +// /* "source":20820:20827 */ +// stop +// } +// +// sub_177: assembly { +// /* "source":20868:20875 */ +// stop +// } +// +// sub_178: assembly { +// /* "source":20916:20923 */ +// stop +// } +// +// sub_179: assembly { +// /* "source":20964:20971 */ +// stop +// } +// +// sub_180: assembly { +// /* "source":21012:21019 */ +// stop +// } +// +// sub_181: assembly { +// /* "source":21060:21067 */ +// stop +// } +// +// sub_182: assembly { +// /* "source":21108:21115 */ +// stop +// } +// +// sub_183: assembly { +// /* "source":21156:21163 */ +// stop +// } +// +// sub_184: assembly { +// /* "source":21204:21211 */ +// stop +// } +// +// sub_185: assembly { +// /* "source":21252:21259 */ +// stop +// } +// +// sub_186: assembly { +// /* "source":21300:21307 */ +// stop +// } +// +// sub_187: assembly { +// /* "source":21348:21355 */ +// stop +// } +// +// sub_188: assembly { +// /* "source":21396:21403 */ +// stop +// } +// +// sub_189: assembly { +// /* "source":21444:21451 */ +// stop +// } +// +// sub_190: assembly { +// /* "source":21492:21499 */ +// stop +// } +// +// sub_191: assembly { +// /* "source":21540:21547 */ +// stop +// } +// +// sub_192: assembly { +// /* "source":21588:21595 */ +// stop +// } +// +// sub_193: assembly { +// /* "source":21636:21643 */ +// stop +// } +// +// sub_194: assembly { +// /* "source":21684:21691 */ +// stop +// } +// +// sub_195: assembly { +// /* "source":21732:21739 */ +// stop +// } +// +// sub_196: assembly { +// /* "source":21780:21787 */ +// stop +// } +// +// sub_197: assembly { +// /* "source":21828:21835 */ +// stop +// } +// +// sub_198: assembly { +// /* "source":21876:21883 */ +// stop +// } +// +// sub_199: assembly { +// /* "source":21924:21931 */ +// stop +// } +// +// sub_200: assembly { +// /* "source":21972:21979 */ +// stop +// } +// +// sub_201: assembly { +// /* "source":22020:22027 */ +// stop +// } +// +// sub_202: assembly { +// /* "source":22068:22075 */ +// stop +// } +// +// sub_203: assembly { +// /* "source":22116:22123 */ +// stop +// } +// +// sub_204: assembly { +// /* "source":22164:22171 */ +// stop +// } +// +// sub_205: assembly { +// /* "source":22212:22219 */ +// stop +// } +// +// sub_206: assembly { +// /* "source":22260:22267 */ +// stop +// } +// +// sub_207: assembly { +// /* "source":22308:22315 */ +// stop +// } +// +// sub_208: assembly { +// /* "source":22356:22363 */ +// stop +// } +// +// sub_209: assembly { +// /* "source":22404:22411 */ +// stop +// } +// +// sub_210: assembly { +// /* "source":22452:22459 */ +// stop +// } +// +// sub_211: assembly { +// /* "source":22500:22507 */ +// stop +// } +// +// sub_212: assembly { +// /* "source":22548:22555 */ +// stop +// } +// +// sub_213: assembly { +// /* "source":22596:22603 */ +// stop +// } +// +// sub_214: assembly { +// /* "source":22644:22651 */ +// stop +// } +// +// sub_215: assembly { +// /* "source":22692:22699 */ +// stop +// } +// +// sub_216: assembly { +// /* "source":22740:22747 */ +// stop +// } +// +// sub_217: assembly { +// /* "source":22788:22795 */ +// stop +// } +// +// sub_218: assembly { +// /* "source":22836:22843 */ +// stop +// } +// +// sub_219: assembly { +// /* "source":22884:22891 */ +// stop +// } +// +// sub_220: assembly { +// /* "source":22932:22939 */ +// stop +// } +// +// sub_221: assembly { +// /* "source":22980:22987 */ +// stop +// } +// +// sub_222: assembly { +// /* "source":23028:23035 */ +// stop +// } +// +// sub_223: assembly { +// /* "source":23076:23083 */ +// stop +// } +// +// sub_224: assembly { +// /* "source":23124:23131 */ +// stop +// } +// +// sub_225: assembly { +// /* "source":23172:23179 */ +// stop +// } +// +// sub_226: assembly { +// /* "source":23220:23227 */ +// stop +// } +// +// sub_227: assembly { +// /* "source":23268:23275 */ +// stop +// } +// +// sub_228: assembly { +// /* "source":23316:23323 */ +// stop +// } +// +// sub_229: assembly { +// /* "source":23364:23371 */ +// stop +// } +// +// sub_230: assembly { +// /* "source":23412:23419 */ +// stop +// } +// +// sub_231: assembly { +// /* "source":23460:23467 */ +// stop +// } +// +// sub_232: assembly { +// /* "source":23508:23515 */ +// stop +// } +// +// sub_233: assembly { +// /* "source":23556:23563 */ +// stop +// } +// +// sub_234: assembly { +// /* "source":23604:23611 */ +// stop +// } +// +// sub_235: assembly { +// /* "source":23652:23659 */ +// stop +// } +// +// sub_236: assembly { +// /* "source":23700:23707 */ +// stop +// } +// +// sub_237: assembly { +// /* "source":23748:23755 */ +// stop +// } +// +// sub_238: assembly { +// /* "source":23796:23803 */ +// stop +// } +// +// sub_239: assembly { +// /* "source":23844:23851 */ +// stop +// } +// +// sub_240: assembly { +// /* "source":23892:23899 */ +// stop +// } +// +// sub_241: assembly { +// /* "source":23940:23947 */ +// stop +// } +// +// sub_242: assembly { +// /* "source":23988:23995 */ +// stop +// } +// +// sub_243: assembly { +// /* "source":24036:24043 */ +// stop +// } +// +// sub_244: assembly { +// /* "source":24084:24091 */ +// stop +// } +// +// sub_245: assembly { +// /* "source":24132:24139 */ +// stop +// } +// +// sub_246: assembly { +// /* "source":24180:24187 */ +// stop +// } +// +// sub_247: assembly { +// /* "source":24228:24235 */ +// stop +// } +// +// sub_248: assembly { +// /* "source":24276:24283 */ +// stop +// } +// +// sub_249: assembly { +// /* "source":24324:24331 */ +// stop +// } +// +// sub_250: assembly { +// /* "source":24372:24379 */ +// stop +// } +// +// sub_251: assembly { +// /* "source":24420:24427 */ +// stop +// } +// +// sub_252: assembly { +// /* "source":24468:24475 */ +// stop +// } +// +// sub_253: assembly { +// /* "source":24516:24523 */ +// stop +// } +// +// sub_254: assembly { +// /* "source":24564:24571 */ +// stop +// } +// +// sub_255: assembly { +// /* "source":24612:24619 */ +// stop +// } +// Bytecode: ef000101000402000107010301000014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014040000000080ffff5f808080ec00505f808080ec01505f808080ec02505f808080ec03505f808080ec04505f808080ec05505f808080ec06505f808080ec07505f808080ec08505f808080ec09505f808080ec0a505f808080ec0b505f808080ec0c505f808080ec0d505f808080ec0e505f808080ec0f505f808080ec10505f808080ec11505f808080ec12505f808080ec13505f808080ec14505f808080ec15505f808080ec16505f808080ec17505f808080ec18505f808080ec19505f808080ec1a505f808080ec1b505f808080ec1c505f808080ec1d505f808080ec1e505f808080ec1f505f808080ec20505f808080ec21505f808080ec22505f808080ec23505f808080ec24505f808080ec25505f808080ec26505f808080ec27505f808080ec28505f808080ec29505f808080ec2a505f808080ec2b505f808080ec2c505f808080ec2d505f808080ec2e505f808080ec2f505f808080ec30505f808080ec31505f808080ec32505f808080ec33505f808080ec34505f808080ec35505f808080ec36505f808080ec37505f808080ec38505f808080ec39505f808080ec3a505f808080ec3b505f808080ec3c505f808080ec3d505f808080ec3e505f808080ec3f505f808080ec40505f808080ec41505f808080ec42505f808080ec43505f808080ec44505f808080ec45505f808080ec46505f808080ec47505f808080ec48505f808080ec49505f808080ec4a505f808080ec4b505f808080ec4c505f808080ec4d505f808080ec4e505f808080ec4f505f808080ec50505f808080ec51505f808080ec52505f808080ec53505f808080ec54505f808080ec55505f808080ec56505f808080ec57505f808080ec58505f808080ec59505f808080ec5a505f808080ec5b505f808080ec5c505f808080ec5d505f808080ec5e505f808080ec5f505f808080ec60505f808080ec61505f808080ec62505f808080ec63505f808080ec64505f808080ec65505f808080ec66505f808080ec67505f808080ec68505f808080ec69505f808080ec6a505f808080ec6b505f808080ec6c505f808080ec6d505f808080ec6e505f808080ec6f505f808080ec70505f808080ec71505f808080ec72505f808080ec73505f808080ec74505f808080ec75505f808080ec76505f808080ec77505f808080ec78505f808080ec79505f808080ec7a505f808080ec7b505f808080ec7c505f808080ec7d505f808080ec7e505f808080ec7f505f808080ec80505f808080ec81505f808080ec82505f808080ec83505f808080ec84505f808080ec85505f808080ec86505f808080ec87505f808080ec88505f808080ec89505f808080ec8a505f808080ec8b505f808080ec8c505f808080ec8d505f808080ec8e505f808080ec8f505f808080ec90505f808080ec91505f808080ec92505f808080ec93505f808080ec94505f808080ec95505f808080ec96505f808080ec97505f808080ec98505f808080ec99505f808080ec9a505f808080ec9b505f808080ec9c505f808080ec9d505f808080ec9e505f808080ec9f505f808080eca0505f808080eca1505f808080eca2505f808080eca3505f808080eca4505f808080eca5505f808080eca6505f808080eca7505f808080eca8505f808080eca9505f808080ecaa505f808080ecab505f808080ecac505f808080ecad505f808080ecae505f808080ecaf505f808080ecb0505f808080ecb1505f808080ecb2505f808080ecb3505f808080ecb4505f808080ecb5505f808080ecb6505f808080ecb7505f808080ecb8505f808080ecb9505f808080ecba505f808080ecbb505f808080ecbc505f808080ecbd505f808080ecbe505f808080ecbf505f808080ecc0505f808080ecc1505f808080ecc2505f808080ecc3505f808080ecc4505f808080ecc5505f808080ecc6505f808080ecc7505f808080ecc8505f808080ecc9505f808080ecca505f808080eccb505f808080eccc505f808080eccd505f808080ecce505f808080eccf505f808080ecd0505f808080ecd1505f808080ecd2505f808080ecd3505f808080ecd4505f808080ecd5505f808080ecd6505f808080ecd7505f808080ecd8505f808080ecd9505f808080ecda505f808080ecdb505f808080ecdc505f808080ecdd505f808080ecde505f808080ecdf505f808080ece0505f808080ece1505f808080ece2505f808080ece3505f808080ece4505f808080ece5505f808080ece6505f808080ece7505f808080ece8505f808080ece9505f808080ecea505f808080eceb505f808080ecec505f808080eced505f808080ecee505f808080ecef505f808080ecf0505f808080ecf1505f808080ecf2505f808080ecf3505f808080ecf4505f808080ecf5505f808080ecf6505f808080ecf7505f808080ecf8505f808080ecf9505f808080ecfa505f808080ecfb505f808080ecfc505f808080ecfd505f808080ecfe505f808080ecff5000ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00 +// Opcodes: 0xEF STOP ADD ADD STOP DIV MUL STOP ADD SMOD ADD SUB ADD STOP STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x0 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x1 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x2 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x3 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x4 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x5 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x6 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x7 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x8 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x9 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xA POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xB POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xC POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xD POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xE POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xF POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x10 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x11 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x12 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x13 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x14 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x15 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x16 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x17 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x18 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x19 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x1A POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x1B POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x1C POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x1D POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x1E POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x1F POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x20 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x21 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x22 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x23 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x24 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x25 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x26 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x27 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x28 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x29 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x2A POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x2B POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x2C POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x2D POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x2E POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x2F POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x30 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x31 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x32 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x33 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x34 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x35 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x36 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x37 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x38 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x39 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x3A POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x3B POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x3C POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x3D POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x3E POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x3F POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x40 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x41 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x42 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x43 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x44 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x45 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x46 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x47 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x48 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x49 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x4A POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x4B POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x4C POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x4D POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x4E POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x4F POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x50 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x51 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x52 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x53 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x54 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x55 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x56 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x57 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x58 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x59 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x5A POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x5B POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x5C POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x5D POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x5E POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x5F POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x60 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x61 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x62 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x63 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x64 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x65 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x66 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x67 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x68 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x69 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x6A POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x6B POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x6C POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x6D POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x6E POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x6F POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x70 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x71 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x72 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x73 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x74 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x75 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x76 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x77 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x78 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x79 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x7A POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x7B POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x7C POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x7D POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x7E POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x7F POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x80 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x81 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x82 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x83 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x84 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x85 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x86 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x87 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x88 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x89 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x8A POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x8B POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x8C POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x8D POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x8E POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x8F POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x90 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x91 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x92 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x93 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x94 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x95 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x96 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x97 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x98 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x99 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x9A POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x9B POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x9C POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x9D POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x9E POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x9F POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xA0 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xA1 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xA2 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xA3 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xA4 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xA5 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xA6 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xA7 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xA8 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xA9 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xAA POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xAB POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xAC POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xAD POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xAE POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xAF POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xB0 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xB1 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xB2 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xB3 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xB4 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xB5 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xB6 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xB7 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xB8 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xB9 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xBA POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xBB POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xBC POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xBD POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xBE POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xBF POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xC0 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xC1 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xC2 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xC3 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xC4 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xC5 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xC6 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xC7 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xC8 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xC9 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xCA POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xCB POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xCC POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xCD POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xCE POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xCF POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xD0 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xD1 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xD2 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xD3 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xD4 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xD5 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xD6 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xD7 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xD8 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xD9 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xDA POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xDB POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xDC POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xDD POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xDE POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xDF POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xE0 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xE1 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xE2 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xE3 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xE4 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xE5 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xE6 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xE7 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xE8 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xE9 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xEA POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xEB POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xEC POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xED POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xEE POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xEF POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xF0 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xF1 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xF2 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xF3 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xF4 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xF5 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xF6 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xF7 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xF8 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xF9 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xFA POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xFB POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xFC POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xFD POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xFE POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xFF POP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP +// SourceMappings: 78:1:0:-:0;50:30;;;;46:35;126:1;98:30;;;;94:35;174:1;146:30;;;;142:35;222:1;194:30;;;;190:35;270:1;242:30;;;;238:35;318:1;290:30;;;;286:35;366:1;338:30;;;;334:35;414:1;386:30;;;;382:35;462:1;434:30;;;;430:35;510:1;482:30;;;;478:35;558:1;530:30;;;;526:35;606:1;578:30;;;;574:35;654:1;626:30;;;;622:35;702:1;674:30;;;;670:35;750:1;722:30;;;;718:35;798:1;770:30;;;;766:35;846:1;818:30;;;;814:35;894:1;866:30;;;;862:35;942:1;914:30;;;;910:35;990:1;962:30;;;;958:35;1038:1;1010:30;;;;1006:35;1086:1;1058:30;;;;1054:35;1134:1;1106:30;;;;1102:35;1182:1;1154:30;;;;1150:35;1230:1;1202:30;;;;1198:35;1278:1;1250:30;;;;1246:35;1326:1;1298:30;;;;1294:35;1374:1;1346:30;;;;1342:35;1422:1;1394:30;;;;1390:35;1470:1;1442:30;;;;1438:35;1518:1;1490:30;;;;1486:35;1566:1;1538:30;;;;1534:35;1614:1;1586:30;;;;1582:35;1662:1;1634:30;;;;1630:35;1710:1;1682:30;;;;1678:35;1758:1;1730:30;;;;1726:35;1806:1;1778:30;;;;1774:35;1854:1;1826:30;;;;1822:35;1902:1;1874:30;;;;1870:35;1950:1;1922:30;;;;1918:35;1998:1;1970:30;;;;1966:35;2046:1;2018:30;;;;2014:35;2094:1;2066:30;;;;2062:35;2142:1;2114:30;;;;2110:35;2190:1;2162:30;;;;2158:35;2238:1;2210:30;;;;2206:35;2286:1;2258:30;;;;2254:35;2334:1;2306:30;;;;2302:35;2382:1;2354:30;;;;2350:35;2430:1;2402:30;;;;2398:35;2478:1;2450:30;;;;2446:35;2526:1;2498:30;;;;2494:35;2574:1;2546:30;;;;2542:35;2622:1;2594:30;;;;2590:35;2670:1;2642:30;;;;2638:35;2718:1;2690:30;;;;2686:35;2766:1;2738:30;;;;2734:35;2814:1;2786:30;;;;2782:35;2862:1;2834:30;;;;2830:35;2910:1;2882:30;;;;2878:35;2958:1;2930:30;;;;2926:35;3006:1;2978:30;;;;2974:35;3054:1;3026:30;;;;3022:35;3102:1;3074:30;;;;3070:35;3150:1;3122:30;;;;3118:35;3198:1;3170:30;;;;3166:35;3246:1;3218:30;;;;3214:35;3294:1;3266:30;;;;3262:35;3342:1;3314:30;;;;3310:35;3390:1;3362:30;;;;3358:35;3438:1;3410:30;;;;3406:35;3486:1;3458:30;;;;3454:35;3534:1;3506:30;;;;3502:35;3582:1;3554:30;;;;3550:35;3630:1;3602:30;;;;3598:35;3678:1;3650:30;;;;3646:35;3726:1;3698:30;;;;3694:35;3774:1;3746:30;;;;3742:35;3822:1;3794:30;;;;3790:35;3870:1;3842:30;;;;3838:35;3918:1;3890:30;;;;3886:35;3966:1;3938:30;;;;3934:35;4014:1;3986:30;;;;3982:35;4062:1;4034:30;;;;4030:35;4110:1;4082:30;;;;4078:35;4158:1;4130:30;;;;4126:35;4206:1;4178:30;;;;4174:35;4254:1;4226:30;;;;4222:35;4302:1;4274:30;;;;4270:35;4350:1;4322:30;;;;4318:35;4398:1;4370:30;;;;4366:35;4446:1;4418:30;;;;4414:35;4494:1;4466:30;;;;4462:35;4542:1;4514:30;;;;4510:35;4590:1;4562:30;;;;4558:35;4638:1;4610:30;;;;4606:35;4686:1;4658:30;;;;4654:35;4734:1;4706:30;;;;4702:35;4782:1;4754:30;;;;4750:35;4830:1;4802:30;;;;4798:35;4878:1;4850:30;;;;4846:35;4926:1;4898:30;;;;4894:35;4974:1;4946:30;;;;4942:35;5022:1;4994:30;;;;4990:35;5070:1;5042:30;;;;5038:35;5118:1;5090:30;;;;5086:35;5166:1;5138:30;;;;5134:35;5214:1;5186:30;;;;5182:35;5262:1;5234:30;;;;5230:35;5310:1;5282:30;;;;5278:35;5358:1;5330:30;;;;5326:35;5406:1;5378:30;;;;5374:35;5454:1;5426:30;;;;5422:35;5502:1;5474:30;;;;5470:35;5550:1;5522:30;;;;5518:35;5598:1;5570:30;;;;5566:35;5646:1;5618:30;;;;5614:35;5694:1;5666:30;;;;5662:35;5742:1;5714:30;;;;5710:35;5790:1;5762:30;;;;5758:35;5838:1;5810:30;;;;5806:35;5886:1;5858:30;;;;5854:35;5934:1;5906:30;;;;5902:35;5982:1;5954:30;;;;5950:35;6030:1;6002:30;;;;5998:35;6078:1;6050:30;;;;6046:35;6126:1;6098:30;;;;6094:35;6174:1;6146:30;;;;6142:35;6222:1;6194:30;;;;6190:35;6270:1;6242:30;;;;6238:35;6318:1;6290:30;;;;6286:35;6366:1;6338:30;;;;6334:35;6414:1;6386:30;;;;6382:35;6462:1;6434:30;;;;6430:35;6510:1;6482:30;;;;6478:35;6558:1;6530:30;;;;6526:35;6606:1;6578:30;;;;6574:35;6654:1;6626:30;;;;6622:35;6702:1;6674:30;;;;6670:35;6750:1;6722:30;;;;6718:35;6798:1;6770:30;;;;6766:35;6846:1;6818:30;;;;6814:35;6894:1;6866:30;;;;6862:35;6942:1;6914:30;;;;6910:35;6990:1;6962:30;;;;6958:35;7038:1;7010:30;;;;7006:35;7086:1;7058:30;;;;7054:35;7134:1;7106:30;;;;7102:35;7182:1;7154:30;;;;7150:35;7230:1;7202:30;;;;7198:35;7278:1;7250:30;;;;7246:35;7326:1;7298:30;;;;7294:35;7374:1;7346:30;;;;7342:35;7422:1;7394:30;;;;7390:35;7470:1;7442:30;;;;7438:35;7518:1;7490:30;;;;7486:35;7566:1;7538:30;;;;7534:35;7614:1;7586:30;;;;7582:35;7662:1;7634:30;;;;7630:35;7710:1;7682:30;;;;7678:35;7758:1;7730:30;;;;7726:35;7806:1;7778:30;;;;7774:35;7854:1;7826:30;;;;7822:35;7902:1;7874:30;;;;7870:35;7950:1;7922:30;;;;7918:35;7998:1;7970:30;;;;7966:35;8046:1;8018:30;;;;8014:35;8094:1;8066:30;;;;8062:35;8142:1;8114:30;;;;8110:35;8190:1;8162:30;;;;8158:35;8238:1;8210:30;;;;8206:35;8286:1;8258:30;;;;8254:35;8334:1;8306:30;;;;8302:35;8382:1;8354:30;;;;8350:35;8430:1;8402:30;;;;8398:35;8478:1;8450:30;;;;8446:35;8526:1;8498:30;;;;8494:35;8574:1;8546:30;;;;8542:35;8622:1;8594:30;;;;8590:35;8670:1;8642:30;;;;8638:35;8718:1;8690:30;;;;8686:35;8766:1;8738:30;;;;8734:35;8814:1;8786:30;;;;8782:35;8862:1;8834:30;;;;8830:35;8910:1;8882:30;;;;8878:35;8958:1;8930:30;;;;8926:35;9006:1;8978:30;;;;8974:35;9054:1;9026:30;;;;9022:35;9102:1;9074:30;;;;9070:35;9150:1;9122:30;;;;9118:35;9198:1;9170:30;;;;9166:35;9246:1;9218:30;;;;9214:35;9294:1;9266:30;;;;9262:35;9342:1;9314:30;;;;9310:35;9390:1;9362:30;;;;9358:35;9438:1;9410:30;;;;9406:35;9486:1;9458:30;;;;9454:35;9534:1;9506:30;;;;9502:35;9582:1;9554:30;;;;9550:35;9630:1;9602:30;;;;9598:35;9678:1;9650:30;;;;9646:35;9726:1;9698:30;;;;9694:35;9774:1;9746:30;;;;9742:35;9822:1;9794:30;;;;9790:35;9870:1;9842:30;;;;9838:35;9918:1;9890:30;;;;9886:35;9966:1;9938:30;;;;9934:35;10014:1;9986:30;;;;9982:35;10062:1;10034:30;;;;10030:35;10110:1;10082:30;;;;10078:35;10158:1;10130:30;;;;10126:35;10206:1;10178:30;;;;10174:35;10254:1;10226:30;;;;10222:35;10302:1;10274:30;;;;10270:35;10350:1;10322:30;;;;10318:35;10398:1;10370:30;;;;10366:35;10446:1;10418:30;;;;10414:35;10494:1;10466:30;;;;10462:35;10542:1;10514:30;;;;10510:35;10590:1;10562:30;;;;10558:35;10638:1;10610:30;;;;10606:35;10686:1;10658:30;;;;10654:35;10734:1;10706:30;;;;10702:35;10782:1;10754:30;;;;10750:35;10830:1;10802:30;;;;10798:35;10878:1;10850:30;;;;10846:35;10926:1;10898:30;;;;10894:35;10974:1;10946:30;;;;10942:35;11022:1;10994:30;;;;10990:35;11070:1;11042:30;;;;11038:35;11118:1;11090:30;;;;11086:35;11166:1;11138:30;;;;11134:35;11214:1;11186:30;;;;11182:35;11262:1;11234:30;;;;11230:35;11310:1;11282:30;;;;11278:35;11358:1;11330:30;;;;11326:35;11406:1;11378:30;;;;11374:35;11454:1;11426:30;;;;11422:35;11502:1;11474:30;;;;11470:35;11550:1;11522:30;;;;11518:35;11598:1;11570:30;;;;11566:35;11646:1;11618:30;;;;11614:35;11694:1;11666:30;;;;11662:35;11742:1;11714:30;;;;11710:35;11790:1;11762:30;;;;11758:35;11838:1;11810:30;;;;11806:35;11886:1;11858:30;;;;11854:35;11934:1;11906:30;;;;11902:35;11982:1;11954:30;;;;11950:35;12030:1;12002:30;;;;11998:35;12078:1;12050:30;;;;12046:35;12126:1;12098:30;;;;12094:35;12174:1;12146:30;;;;12142:35;12222:1;12194:30;;;;12190:35;12270:1;12242:30;;;;12238:35;12318:1;12290:30;;;;12286:35;22:12315 From c73c4d2871fd510fbb7e560587ab07ba8f4837ba Mon Sep 17 00:00:00 2001 From: rodiazet Date: Fri, 29 Nov 2024 11:20:24 +0100 Subject: [PATCH 0586/1022] eof: Fix wrong int type for subcontainers iteration --- libevmasm/Assembly.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libevmasm/Assembly.cpp b/libevmasm/Assembly.cpp index 584c46455aa4..f8734b5fc3da 100644 --- a/libevmasm/Assembly.cpp +++ b/libevmasm/Assembly.cpp @@ -1346,7 +1346,7 @@ std::map Assembly::findReferencedContainers() const std::map replacements; uint8_t nUnreferenced = 0; - for (uint8_t i = 0; i < static_cast(m_subs.size()); ++i) + for (size_t i = 0; i < m_subs.size(); ++i) { solAssert(i <= std::numeric_limits::max()); if (referencedSubcontainersIds.count(static_cast(i)) > 0) From a87c49d104cae74bab502cc40771befcf04204e0 Mon Sep 17 00:00:00 2001 From: rodiazet Date: Fri, 29 Nov 2024 11:21:02 +0100 Subject: [PATCH 0587/1022] eof: Fix container id bug --- libevmasm/Assembly.cpp | 10 ++- .../eof/prune_unreferenced_container.yul | 81 +++++++++++++++++++ 2 files changed, 89 insertions(+), 2 deletions(-) create mode 100644 test/libyul/objectCompiler/eof/prune_unreferenced_container.yul diff --git a/libevmasm/Assembly.cpp b/libevmasm/Assembly.cpp index f8734b5fc3da..4719d357fc40 100644 --- a/libevmasm/Assembly.cpp +++ b/libevmasm/Assembly.cpp @@ -1442,13 +1442,19 @@ LinkerObject const& Assembly::assembleEOF() const case EOFCreate: { ret.bytecode.push_back(static_cast(Instruction::EOFCREATE)); - ret.bytecode.push_back(static_cast(item.data())); + solAssert(item.data() <= std::numeric_limits::max()); + auto const containerID = static_cast(item.data()); + solAssert(subIdsReplacements.count(containerID) == 1); + ret.bytecode.push_back(subIdsReplacements.at(containerID)); break; } case ReturnContract: { ret.bytecode.push_back(static_cast(Instruction::RETURNCONTRACT)); - ret.bytecode.push_back(static_cast(item.data())); + solAssert(item.data() <= std::numeric_limits::max()); + auto const containerID = static_cast(item.data()); + solAssert(subIdsReplacements.count(containerID) == 1); + ret.bytecode.push_back(subIdsReplacements.at(containerID)); break; } case VerbatimBytecode: diff --git a/test/libyul/objectCompiler/eof/prune_unreferenced_container.yul b/test/libyul/objectCompiler/eof/prune_unreferenced_container.yul new file mode 100644 index 000000000000..2225fe6ebbd2 --- /dev/null +++ b/test/libyul/objectCompiler/eof/prune_unreferenced_container.yul @@ -0,0 +1,81 @@ +object "a" { + code { + mstore(0, eofcreate("c", 0, 0, 0, 0)) + return(0, 32) + } + + object "b" { + code { + mstore(0, 0x1122334455667788990011223344556677889900112233445566778899001122) + mstore(32, 0x1122334455667788990011223344556677889900112233445566778899001122) + } + } + + object "c" { + code { + mstore(0, 0x1122334455667788990011223344556677889900112233445566778899001122) + mstore(32, 0x1122334455667788990011223344556677889900112233445566778899001122) + } + } +} + +// ==== +// EVMVersion: >=prague +// bytecodeFormat: >=EOFv1 +// ---- +// Assembly: +// /* "source":80:81 */ +// 0x00 +// /* "source":56:82 */ +// dup1 +// dup1 +// dup1 +// eofcreate{1} +// /* "source":53:54 */ +// 0x00 +// /* "source":46:83 */ +// mstore +// /* "source":106:108 */ +// 0x20 +// /* "source":103:104 */ +// 0x00 +// /* "source":96:109 */ +// return +// stop +// +// sub_0: assembly { +// /* "source":198:264 */ +// 0x1122334455667788990011223344556677889900112233445566778899001122 +// /* "source":195:196 */ +// 0x00 +// /* "source":188:265 */ +// mstore +// /* "source":293:359 */ +// 0x1122334455667788990011223344556677889900112233445566778899001122 +// /* "source":289:291 */ +// 0x20 +// /* "source":282:360 */ +// mstore +// /* "source":156:384 */ +// stop +// } +// +// sub_1: assembly { +// /* "source":463:529 */ +// 0x1122334455667788990011223344556677889900112233445566778899001122 +// /* "source":460:461 */ +// 0x00 +// /* "source":453:530 */ +// mstore +// /* "source":558:624 */ +// 0x1122334455667788990011223344556677889900112233445566778899001122 +// /* "source":554:556 */ +// 0x20 +// /* "source":547:625 */ +// mstore +// /* "source":421:649 */ +// stop +// } +// Bytecode: ef0001010004020001000c030001005b040000000080ffff5f808080ec005f5260205ff3ef00010100040200010048040000000080ffff7f11223344556677889900112233445566778899001122334455667788990011225f527f112233445566778899001122334455667788990011223344556677889900112260205200 +// Opcodes: 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP 0xC SUB STOP ADD STOP JUMPDEST DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x0 PUSH0 MSTORE PUSH1 0x20 PUSH0 RETURN 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP BASEFEE DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT PUSH32 0x1122334455667788990011223344556677889900112233445566778899001122 PUSH0 MSTORE PUSH32 0x1122334455667788990011223344556677889900112233445566778899001122 PUSH1 0x20 MSTORE STOP +// SourceMappings: 80:1:0:-:0;56:26;;;;53:1;46:37;106:2;103:1;96:13 From 6b347a13d0092de83041b08b5904a6ee50ca44ce Mon Sep 17 00:00:00 2001 From: rodiazet Date: Fri, 29 Nov 2024 11:23:18 +0100 Subject: [PATCH 0588/1022] eof: Add yul syntax test and proper error for too many subcontainers --- libyul/AsmAnalysis.cpp | 32 ++- .../eof/too_many_subcontainers.yul | 270 ++++++++++++++++++ 2 files changed, 293 insertions(+), 9 deletions(-) create mode 100644 test/libyul/yulSyntaxTests/eof/too_many_subcontainers.yul diff --git a/libyul/AsmAnalysis.cpp b/libyul/AsmAnalysis.cpp index 8ed0b414211c..aedf4fd0708f 100644 --- a/libyul/AsmAnalysis.cpp +++ b/libyul/AsmAnalysis.cpp @@ -800,13 +800,27 @@ bool AsmAnalyzer::validateInstructions(FunctionCall const& _functionCall) void AsmAnalyzer::validateObjectStructure(langutil::SourceLocation _astRootLocation) { - if (m_eofVersion.has_value() && util::contains(m_objectStructure.objectName, '.')) // No dots in object name for EOF - m_errorReporter.syntaxError( - 9822_error, - _astRootLocation, - fmt::format( - "The object name \"{objectName}\" is invalid in EOF context. Object names must not contain 'dot' character.", - fmt::arg("objectName", m_objectStructure.objectName) - ) - ); + if (m_eofVersion.has_value()) + { + if (util::contains(m_objectStructure.objectName, '.')) // No dots in object name for EOF + m_errorReporter.syntaxError( + 9822_error, + _astRootLocation, + fmt::format( + "The object name \"{objectName}\" is invalid in EOF context. Object names must not contain 'dot' character.", + fmt::arg("objectName", m_objectStructure.objectName) + ) + ); + else if (m_objectStructure.topLevelSubObjectNames().size() > 256) + { + m_errorReporter.syntaxError( + 1305_error, + _astRootLocation, + fmt::format( + "Too many subobjects in \"{objectName}\". At most 256 subobjects allowed when compiling to EOF", + fmt::arg("objectName", m_objectStructure.objectName) + ) + ); + } + } } diff --git a/test/libyul/yulSyntaxTests/eof/too_many_subcontainers.yul b/test/libyul/yulSyntaxTests/eof/too_many_subcontainers.yul new file mode 100644 index 000000000000..f39d6f2d8639 --- /dev/null +++ b/test/libyul/yulSyntaxTests/eof/too_many_subcontainers.yul @@ -0,0 +1,270 @@ +object "a" { + code { + mstore(0, eofcreate("s0000", 0, 0, 0, 0)) + return(0, 32) + } + + object "s0000" {code{}} + object "s0001" {code{}} + object "s0002" {code{}} + object "s0003" {code{}} + object "s0004" {code{}} + object "s0005" {code{}} + object "s0006" {code{}} + object "s0007" {code{}} + object "s0008" {code{}} + object "s0009" {code{}} + object "s0010" {code{}} + object "s0011" {code{}} + object "s0012" {code{}} + object "s0013" {code{}} + object "s0014" {code{}} + object "s0015" {code{}} + object "s0016" {code{}} + object "s0017" {code{}} + object "s0018" {code{}} + object "s0019" {code{}} + object "s0020" {code{}} + object "s0021" {code{}} + object "s0022" {code{}} + object "s0023" {code{}} + object "s0024" {code{}} + object "s0025" {code{}} + object "s0026" {code{}} + object "s0027" {code{}} + object "s0028" {code{}} + object "s0029" {code{}} + object "s0030" {code{}} + object "s0031" {code{}} + object "s0032" {code{}} + object "s0033" {code{}} + object "s0034" {code{}} + object "s0035" {code{}} + object "s0036" {code{}} + object "s0037" {code{}} + object "s0038" {code{}} + object "s0039" {code{}} + object "s0040" {code{}} + object "s0041" {code{}} + object "s0042" {code{}} + object "s0043" {code{}} + object "s0044" {code{}} + object "s0045" {code{}} + object "s0046" {code{}} + object "s0047" {code{}} + object "s0048" {code{}} + object "s0049" {code{}} + object "s0050" {code{}} + object "s0051" {code{}} + object "s0052" {code{}} + object "s0053" {code{}} + object "s0054" {code{}} + object "s0055" {code{}} + object "s0056" {code{}} + object "s0057" {code{}} + object "s0058" {code{}} + object "s0059" {code{}} + object "s0060" {code{}} + object "s0061" {code{}} + object "s0062" {code{}} + object "s0063" {code{}} + object "s0064" {code{}} + object "s0065" {code{}} + object "s0066" {code{}} + object "s0067" {code{}} + object "s0068" {code{}} + object "s0069" {code{}} + object "s0070" {code{}} + object "s0071" {code{}} + object "s0072" {code{}} + object "s0073" {code{}} + object "s0074" {code{}} + object "s0075" {code{}} + object "s0076" {code{}} + object "s0077" {code{}} + object "s0078" {code{}} + object "s0079" {code{}} + object "s0080" {code{}} + object "s0081" {code{}} + object "s0082" {code{}} + object "s0083" {code{}} + object "s0084" {code{}} + object "s0085" {code{}} + object "s0086" {code{}} + object "s0087" {code{}} + object "s0088" {code{}} + object "s0089" {code{}} + object "s0090" {code{}} + object "s0091" {code{}} + object "s0092" {code{}} + object "s0093" {code{}} + object "s0094" {code{}} + object "s0095" {code{}} + object "s0096" {code{}} + object "s0097" {code{}} + object "s0098" {code{}} + object "s0099" {code{}} + object "s0100" {code{}} + object "s0101" {code{}} + object "s0102" {code{}} + object "s0103" {code{}} + object "s0104" {code{}} + object "s0105" {code{}} + object "s0106" {code{}} + object "s0107" {code{}} + object "s0108" {code{}} + object "s0109" {code{}} + object "s0110" {code{}} + object "s0111" {code{}} + object "s0112" {code{}} + object "s0113" {code{}} + object "s0114" {code{}} + object "s0115" {code{}} + object "s0116" {code{}} + object "s0117" {code{}} + object "s0118" {code{}} + object "s0119" {code{}} + object "s0120" {code{}} + object "s0121" {code{}} + object "s0122" {code{}} + object "s0123" {code{}} + object "s0124" {code{}} + object "s0125" {code{}} + object "s0126" {code{}} + object "s0127" {code{}} + object "s0128" {code{}} + object "s0129" {code{}} + object "s0130" {code{}} + object "s0131" {code{}} + object "s0132" {code{}} + object "s0133" {code{}} + object "s0134" {code{}} + object "s0135" {code{}} + object "s0136" {code{}} + object "s0137" {code{}} + object "s0138" {code{}} + object "s0139" {code{}} + object "s0140" {code{}} + object "s0141" {code{}} + object "s0142" {code{}} + object "s0143" {code{}} + object "s0144" {code{}} + object "s0145" {code{}} + object "s0146" {code{}} + object "s0147" {code{}} + object "s0148" {code{}} + object "s0149" {code{}} + object "s0150" {code{}} + object "s0151" {code{}} + object "s0152" {code{}} + object "s0153" {code{}} + object "s0154" {code{}} + object "s0155" {code{}} + object "s0156" {code{}} + object "s0157" {code{}} + object "s0158" {code{}} + object "s0159" {code{}} + object "s0160" {code{}} + object "s0161" {code{}} + object "s0162" {code{}} + object "s0163" {code{}} + object "s0164" {code{}} + object "s0165" {code{}} + object "s0166" {code{}} + object "s0167" {code{}} + object "s0168" {code{}} + object "s0169" {code{}} + object "s0170" {code{}} + object "s0171" {code{}} + object "s0172" {code{}} + object "s0173" {code{}} + object "s0174" {code{}} + object "s0175" {code{}} + object "s0176" {code{}} + object "s0177" {code{}} + object "s0178" {code{}} + object "s0179" {code{}} + object "s0180" {code{}} + object "s0181" {code{}} + object "s0182" {code{}} + object "s0183" {code{}} + object "s0184" {code{}} + object "s0185" {code{}} + object "s0186" {code{}} + object "s0187" {code{}} + object "s0188" {code{}} + object "s0189" {code{}} + object "s0190" {code{}} + object "s0191" {code{}} + object "s0192" {code{}} + object "s0193" {code{}} + object "s0194" {code{}} + object "s0195" {code{}} + object "s0196" {code{}} + object "s0197" {code{}} + object "s0198" {code{}} + object "s0199" {code{}} + object "s0200" {code{}} + object "s0201" {code{}} + object "s0202" {code{}} + object "s0203" {code{}} + object "s0204" {code{}} + object "s0205" {code{}} + object "s0206" {code{}} + object "s0207" {code{}} + object "s0208" {code{}} + object "s0209" {code{}} + object "s0210" {code{}} + object "s0211" {code{}} + object "s0212" {code{}} + object "s0213" {code{}} + object "s0214" {code{}} + object "s0215" {code{}} + object "s0216" {code{}} + object "s0217" {code{}} + object "s0218" {code{}} + object "s0219" {code{}} + object "s0220" {code{}} + object "s0221" {code{}} + object "s0222" {code{}} + object "s0223" {code{}} + object "s0224" {code{}} + object "s0225" {code{}} + object "s0226" {code{}} + object "s0227" {code{}} + object "s0228" {code{}} + object "s0229" {code{}} + object "s0230" {code{}} + object "s0231" {code{}} + object "s0232" {code{}} + object "s0233" {code{}} + object "s0234" {code{}} + object "s0235" {code{}} + object "s0236" {code{}} + object "s0237" {code{}} + object "s0238" {code{}} + object "s0239" {code{}} + object "s0240" {code{}} + object "s0241" {code{}} + object "s0242" {code{}} + object "s0243" {code{}} + object "s0244" {code{}} + object "s0245" {code{}} + object "s0246" {code{}} + object "s0247" {code{}} + object "s0248" {code{}} + object "s0249" {code{}} + object "s0250" {code{}} + object "s0251" {code{}} + object "s0252" {code{}} + object "s0253" {code{}} + object "s0254" {code{}} + object "s0255" {code{}} + object "s0256" {code{}} +} + +// ==== +// EVMVersion: >=prague +// bytecodeFormat: >=EOFv1 +// ---- +// SyntaxError 1305: (22-101): Too many subobjects in "a". At most 256 subobjects allowed when compiling to EOF From 515ad3654075f2fea16b2ae90e3b2e8793870770 Mon Sep 17 00:00:00 2001 From: Haoyang Ma Date: Mon, 4 Nov 2024 17:24:51 +0000 Subject: [PATCH 0589/1022] refine specification to add rules about calldata in constructor --- docs/types/reference-types.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/types/reference-types.rst b/docs/types/reference-types.rst index 23119484d103..79ba8da6e5be 100644 --- a/docs/types/reference-types.rst +++ b/docs/types/reference-types.rst @@ -51,6 +51,9 @@ non-persistent area where function arguments are stored, and behaves mostly like ``memory`` or ``storage`` in internal and private ones. Now ``memory`` and ``calldata`` are allowed in all functions regardless of their visibility. +.. note:: + Constructor parameters cannot use ``calldata`` as their data location. + .. note:: Prior to version 0.5.0 the data location could be omitted, and would default to different locations depending on the kind of variable, function type, etc., but all complex types must now give an explicit From 68ff34b094483bb8dc263f42ad39e1c45548e7cb Mon Sep 17 00:00:00 2001 From: rodiazet Date: Fri, 29 Nov 2024 20:21:58 +0100 Subject: [PATCH 0590/1022] eof: Introduce new instructions set. --- libevmasm/GasMeter.cpp | 3 +++ libevmasm/Instruction.cpp | 6 ++++++ libevmasm/Instruction.h | 6 ++++++ libevmasm/SemanticInformation.cpp | 2 ++ liblangutil/EVMVersion.cpp | 3 +++ libyul/backends/evm/EVMDialect.cpp | 3 +++ test/libyul/yulSyntaxTests/eof/callf_jumpf_retf.yul | 11 +++++++++++ .../yulInterpreter/EVMInstructionInterpreter.cpp | 3 +++ 8 files changed, 37 insertions(+) create mode 100644 test/libyul/yulSyntaxTests/eof/callf_jumpf_retf.yul diff --git a/libevmasm/GasMeter.cpp b/libevmasm/GasMeter.cpp index 3ee3a39cbdc4..1eff35fb2d66 100644 --- a/libevmasm/GasMeter.cpp +++ b/libevmasm/GasMeter.cpp @@ -275,7 +275,10 @@ unsigned GasMeter::runGas(Instruction _instruction, langutil::EVMVersion _evmVer case Tier::RJump: return GasCosts::tier1Gas; case Tier::RJumpI: return GasCosts::rjumpiGas; case Tier::VeryLow: return GasCosts::tier2Gas; + case Tier::RetF: return GasCosts::tier2Gas; case Tier::Low: return GasCosts::tier3Gas; + case Tier::CallF: return GasCosts::tier3Gas; + case Tier::JumpF: return GasCosts::tier3Gas; case Tier::Mid: return GasCosts::tier4Gas; case Tier::High: return GasCosts::tier5Gas; case Tier::BlockHash: return GasCosts::tier6Gas; diff --git a/libevmasm/Instruction.cpp b/libevmasm/Instruction.cpp index 60ec75f9284e..82ed73cc994e 100644 --- a/libevmasm/Instruction.cpp +++ b/libevmasm/Instruction.cpp @@ -169,6 +169,9 @@ std::map const solidity::evmasm::c_instructions = { "LOG3", Instruction::LOG3 }, { "LOG4", Instruction::LOG4 }, { "DATALOADN", Instruction::DATALOADN }, + { "CALLF", Instruction::CALLF }, + { "RETF", Instruction::RETF }, + { "JUMPF", Instruction::JUMPF }, { "RJUMP", Instruction::RJUMP }, { "RJUMPI", Instruction::RJUMPI }, { "EOFCREATE", Instruction::EOFCREATE }, @@ -330,6 +333,9 @@ static std::map const c_instructionInfo = {Instruction::LOG2, {"LOG2", 0, 4, 0, true, Tier::Special}}, {Instruction::LOG3, {"LOG3", 0, 5, 0, true, Tier::Special}}, {Instruction::LOG4, {"LOG4", 0, 6, 0, true, Tier::Special}}, + {Instruction::RETF, {"RETF", 0, 0, 0, true, Tier::RetF}}, + {Instruction::CALLF, {"CALLF", 2, 0, 0, true, Tier::CallF}}, + {Instruction::JUMPF, {"JUMPF", 2, 0, 0, true, Tier::JumpF}}, {Instruction::EOFCREATE, {"EOFCREATE", 1, 4, 1, true, Tier::Special}}, {Instruction::RETURNCONTRACT, {"RETURNCONTRACT", 1, 2, 0, true, Tier::Special}}, {Instruction::CREATE, {"CREATE", 0, 3, 1, true, Tier::Special}}, diff --git a/libevmasm/Instruction.h b/libevmasm/Instruction.h index 84c6e34e6272..351a6981c070 100644 --- a/libevmasm/Instruction.h +++ b/libevmasm/Instruction.h @@ -187,6 +187,9 @@ enum class Instruction: uint8_t RJUMP = 0xe0, ///< relative jump RJUMPI = 0xe1, ///< conditional relative jump + CALLF = 0xe3, ///< call function in a EOF code section + RETF = 0xe4, ///< return to caller from the code section of EOF container + JUMPF = 0xe5, ///< jump to a code section of EOF container without adding a new return stack frame. EOFCREATE = 0xec, ///< create a new account with associated container code. RETURNCONTRACT = 0xee, ///< return container to be deployed with axiliary data filled in. CREATE = 0xf0, ///< create a new account with associated code @@ -304,8 +307,11 @@ enum class Tier Base, // 2, Quick RJump, // 2, RJump VeryLow, // 3, Fastest + RetF, // 3, RJumpI, // 4, Low, // 5, Fast + CallF, // 5, + JumpF, // 5, Mid, // 8, Mid High, // 10, Slow BlockHash, // 20 diff --git a/libevmasm/SemanticInformation.cpp b/libevmasm/SemanticInformation.cpp index 99a5a0f4348e..4d61240fb198 100644 --- a/libevmasm/SemanticInformation.cpp +++ b/libevmasm/SemanticInformation.cpp @@ -397,6 +397,8 @@ bool SemanticInformation::isDeterministic(AssemblyItem const& _item) case Instruction::RETURNDATACOPY: // depends on previous calls case Instruction::RETURNDATASIZE: case Instruction::EOFCREATE: + case Instruction::CALLF: + case Instruction::JUMPF: return false; default: return true; diff --git a/liblangutil/EVMVersion.cpp b/liblangutil/EVMVersion.cpp index f469f337d632..26364f2af2a2 100644 --- a/liblangutil/EVMVersion.cpp +++ b/liblangutil/EVMVersion.cpp @@ -82,6 +82,9 @@ bool EVMVersion::hasOpcode(Instruction _opcode, std::optional _eofVersi case Instruction::DATALOADN: case Instruction::RJUMP: case Instruction::RJUMPI: + case Instruction::CALLF: + case Instruction::JUMPF: + case Instruction::RETF: return _eofVersion.has_value(); default: return true; diff --git a/libyul/backends/evm/EVMDialect.cpp b/libyul/backends/evm/EVMDialect.cpp index f998b7abbc6d..de1201481a3c 100644 --- a/libyul/backends/evm/EVMDialect.cpp +++ b/libyul/backends/evm/EVMDialect.cpp @@ -209,6 +209,9 @@ std::vector> createBuiltins(langutil::EVMVe opcode != evmasm::Instruction::DATALOADN && opcode != evmasm::Instruction::EOFCREATE && opcode != evmasm::Instruction::RETURNCONTRACT && + opcode != evmasm::Instruction::CALLF && + opcode != evmasm::Instruction::JUMPF && + opcode != evmasm::Instruction::RETF && _evmVersion.hasOpcode(opcode, _eofVersion) && !prevRandaoException(name) ) diff --git a/test/libyul/yulSyntaxTests/eof/callf_jumpf_retf.yul b/test/libyul/yulSyntaxTests/eof/callf_jumpf_retf.yul new file mode 100644 index 000000000000..2dcd04ca62a2 --- /dev/null +++ b/test/libyul/yulSyntaxTests/eof/callf_jumpf_retf.yul @@ -0,0 +1,11 @@ +object "a" { + code { + callf() + jumpf() + retf() + } +} +// ---- +// DeclarationError 4619: (32-37): Function "callf" not found. +// DeclarationError 4619: (48-53): Function "jumpf" not found. +// DeclarationError 4619: (64-68): Function "retf" not found. diff --git a/test/tools/yulInterpreter/EVMInstructionInterpreter.cpp b/test/tools/yulInterpreter/EVMInstructionInterpreter.cpp index 044fff8ce6f4..92ac56d6919f 100644 --- a/test/tools/yulInterpreter/EVMInstructionInterpreter.cpp +++ b/test/tools/yulInterpreter/EVMInstructionInterpreter.cpp @@ -488,6 +488,9 @@ u256 EVMInstructionInterpreter::eval( case Instruction::SWAP16: yulAssert(false, "Impossible in strict assembly."); case Instruction::DATALOADN: + case Instruction::CALLF: + case Instruction::RETF: + case Instruction::JUMPF: case Instruction::EOFCREATE: case Instruction::RETURNCONTRACT: case Instruction::RJUMP: From 6f29e6a29e4b5ec6e0b893d8e92947ebef83d296 Mon Sep 17 00:00:00 2001 From: rodiazet Date: Fri, 29 Nov 2024 20:21:58 +0100 Subject: [PATCH 0591/1022] eof: Introduce new AssemblyItem types --- libevmasm/AssemblyItem.cpp | 39 +++++++++++++++++++++++++++---- libevmasm/AssemblyItem.h | 8 ++++++- libevmasm/SemanticInformation.cpp | 17 +++++--------- libevmasm/SemanticInformation.h | 1 - 4 files changed, 47 insertions(+), 18 deletions(-) diff --git a/libevmasm/AssemblyItem.cpp b/libevmasm/AssemblyItem.cpp index 96c007ea5ce7..ea670eb0a2b3 100644 --- a/libevmasm/AssemblyItem.cpp +++ b/libevmasm/AssemblyItem.cpp @@ -86,7 +86,10 @@ std::pair AssemblyItem::nameAndData(langutil::EVMVersi case ReturnContract: case RelativeJump: case ConditionalRelativeJump: - return {instructionInfo(instruction(), _evmVersion).name, m_data != nullptr ? toStringInHex(*m_data) : ""}; + case CallF: + case JumpF: + case RetF: + return {instructionInfo(instruction(), _evmVersion).name, ""}; case Push: return {"PUSH", toStringInHex(data())}; case PushTag: @@ -139,6 +142,7 @@ size_t AssemblyItem::bytesRequired(size_t _addressLength, langutil::EVMVersion _ { case Operation: case Tag: // 1 byte for the JUMPDEST + case RetF: return 1; case Push: return @@ -181,6 +185,8 @@ size_t AssemblyItem::bytesRequired(size_t _addressLength, langutil::EVMVersion _ case RelativeJump: case ConditionalRelativeJump: case AuxDataLoadN: + case JumpF: + case CallF: return 1 + 2; case EOFCreate: return 2; @@ -195,10 +201,15 @@ size_t AssemblyItem::bytesRequired(size_t _addressLength, langutil::EVMVersion _ size_t AssemblyItem::arguments() const { - if (hasInstruction()) + if (type() == CallF || type() == JumpF) + return functionSignature().argsNum; + else if (hasInstruction()) + { + solAssert(instruction() != Instruction::CALLF && instruction() != Instruction::JUMPF); // The latest EVMVersion is used here, since the InstructionInfo is assumed to be // the same across all EVM versions except for the instruction name. return static_cast(instructionInfo(instruction(), EVMVersion()).args); + } else if (type() == VerbatimBytecode) return std::get<0>(*m_verbatimBytecode); else if (type() == AssignImmutable) @@ -216,6 +227,7 @@ size_t AssemblyItem::returnValues() const case ReturnContract: case RelativeJump: case ConditionalRelativeJump: + case RetF: // The latest EVMVersion is used here, since the InstructionInfo is assumed to be // the same across all EVM versions except for the instruction name. return static_cast(instructionInfo(instruction(), EVMVersion()).ret); @@ -235,6 +247,9 @@ size_t AssemblyItem::returnValues() const return std::get<1>(*m_verbatimBytecode); case AuxDataLoadN: return 1; + case JumpF: + case CallF: + return functionSignature().canContinue() ? functionSignature().retsNum : 0; case AssignImmutable: case UndefinedItem: break; @@ -253,6 +268,9 @@ bool AssemblyItem::canBeFunctional() const case ReturnContract: case RelativeJump: case ConditionalRelativeJump: + case CallF: + case JumpF: + case RetF: return !isDupInstruction(instruction()) && !isSwapInstruction(instruction()); case Push: case PushTag: @@ -383,6 +401,15 @@ std::string AssemblyItem::toAssemblyText(Assembly const& _assembly) const case ConditionalRelativeJump: text = "rjumpi{" + std::string("tag_") + std::to_string(relativeJumpTagID()) + "}"; break; + case CallF: + text = "callf{" + std::string("code_section_") + std::to_string(static_cast(data())) + "}"; + break; + case JumpF: + text = "jumpf{" + std::string("code_section_") + std::to_string(static_cast(data())) + "}"; + break; + case RetF: + text = "retf"; + break; } if (m_jumpType == JumpType::IntoFunction || m_jumpType == JumpType::OutOfFunction) { @@ -405,6 +432,9 @@ std::ostream& solidity::evmasm::operator<<(std::ostream& _out, AssemblyItem cons case ReturnContract: case RelativeJump: case ConditionalRelativeJump: + case CallF: + case JumpF: + case RetF: _out << " " << instructionInfo(_item.instruction(), EVMVersion()).name; if (_item.instruction() == Instruction::JUMP || _item.instruction() == Instruction::JUMPI) _out << "\t" << _item.getJumpTypeAsString(); @@ -509,10 +539,9 @@ std::string AssemblyItem::computeSourceMapping( static_cast(_sourceIndicesMap.at(*location.sourceName)) : -1; char jump = '-'; - // TODO: Uncomment when EOF functions introduced. - if (item.getJumpType() == evmasm::AssemblyItem::JumpType::IntoFunction /*|| item.type() == CallF || item.type() == JumpF*/) + if (item.getJumpType() == evmasm::AssemblyItem::JumpType::IntoFunction || item.type() == CallF || item.type() == JumpF) jump = 'i'; - else if (item.getJumpType() == evmasm::AssemblyItem::JumpType::OutOfFunction /*|| item.type() == RetF*/) + else if (item.getJumpType() == evmasm::AssemblyItem::JumpType::OutOfFunction || item.type() == RetF) jump = 'o'; int modifierDepth = static_cast(item.m_modifierDepth); diff --git a/libevmasm/AssemblyItem.h b/libevmasm/AssemblyItem.h index a9c46bb14edb..62e21008b769 100644 --- a/libevmasm/AssemblyItem.h +++ b/libevmasm/AssemblyItem.h @@ -59,6 +59,9 @@ enum AssemblyItemType ReturnContract, ///< Returns new container (with auxiliary data filled in) to be deployed RelativeJump, ///< Jumps to relative position accordingly to its argument ConditionalRelativeJump, ///< Same as RelativeJump but takes condition from the stack + CallF, ///< Jumps to a returning EOF function, adding a new frame to the return stack. + JumpF, ///< Jumps to a returning or non-returning EOF function without changing the return stack. + RetF, ///< Returns from an EOF function, removing a frame from the return stack. VerbatimBytecode ///< Contains data that is inserted into the bytecode code section without modification. }; @@ -164,7 +167,10 @@ class AssemblyItem m_type == EOFCreate || m_type == ReturnContract || m_type == RelativeJump || - m_type == ConditionalRelativeJump; + m_type == ConditionalRelativeJump || + m_type == CallF || + m_type == JumpF || + m_type == RetF; } /// @returns the instruction of this item (only valid if hasInstruction returns true) Instruction instruction() const diff --git a/libevmasm/SemanticInformation.cpp b/libevmasm/SemanticInformation.cpp index 4d61240fb198..c27945b82e51 100644 --- a/libevmasm/SemanticInformation.cpp +++ b/libevmasm/SemanticInformation.cpp @@ -231,6 +231,9 @@ bool SemanticInformation::breaksCSEAnalysisBlock(AssemblyItem const& _item, bool case PushDeployTimeAddress: case AssignImmutable: case VerbatimBytecode: + case CallF: + case JumpF: + case RetF: return true; case Push: case PushTag: @@ -301,17 +304,6 @@ bool SemanticInformation::isSwapInstruction(AssemblyItem const& _item) return evmasm::isSwapInstruction(_item.instruction()); } -bool SemanticInformation::isJumpInstruction(AssemblyItem const& _item) -{ - return - _item == Instruction::JUMP || - _item == Instruction::JUMPI || - _item == Instruction::RJUMP || - _item == Instruction::RJUMPI || - _item.type() == RelativeJump || - _item.type() == ConditionalRelativeJump; -} - bool SemanticInformation::altersControlFlow(AssemblyItem const& _item) { if (!_item.hasInstruction()) @@ -331,6 +323,9 @@ bool SemanticInformation::altersControlFlow(AssemblyItem const& _item) case Instruction::INVALID: case Instruction::REVERT: case Instruction::RETURNCONTRACT: + case Instruction::CALLF: + case Instruction::JUMPF: + case Instruction::RETF: return true; default: return false; diff --git a/libevmasm/SemanticInformation.h b/libevmasm/SemanticInformation.h index b62832f238af..457f60052a6a 100644 --- a/libevmasm/SemanticInformation.h +++ b/libevmasm/SemanticInformation.h @@ -82,7 +82,6 @@ struct SemanticInformation static bool isCommutativeOperation(AssemblyItem const& _item); static bool isDupInstruction(AssemblyItem const& _item); static bool isSwapInstruction(AssemblyItem const& _item); - static bool isJumpInstruction(AssemblyItem const& _item); static bool altersControlFlow(AssemblyItem const& _item); static bool terminatesControlFlow(AssemblyItem const& _item); static bool terminatesControlFlow(Instruction _instruction); From 15ebc748a77bac100f62ee3d2133a69d382212c9 Mon Sep 17 00:00:00 2001 From: rodiazet Date: Fri, 29 Nov 2024 20:21:58 +0100 Subject: [PATCH 0592/1022] eof: Implement new instructions assembly interface and logic --- libevmasm/Assembly.cpp | 81 ++++++++++++++++++++-- libevmasm/Assembly.h | 19 +++++ libevmasm/AssemblyItem.h | 41 ++++++++++- libyul/backends/evm/AbstractAssembly.h | 21 ++++++ libyul/backends/evm/EthAssemblyAdapter.cpp | 25 +++++++ libyul/backends/evm/EthAssemblyAdapter.h | 5 ++ libyul/backends/evm/NoOutputAssembly.cpp | 37 ++++++++++ libyul/backends/evm/NoOutputAssembly.h | 14 ++++ 8 files changed, 238 insertions(+), 5 deletions(-) diff --git a/libevmasm/Assembly.cpp b/libevmasm/Assembly.cpp index 4719d357fc40..29b8c8a4057c 100644 --- a/libevmasm/Assembly.cpp +++ b/libevmasm/Assembly.cpp @@ -407,9 +407,15 @@ void Assembly::assemblyStream( f.feed(i, _debugInfoSelection); f.flush(); - // Implementing this requires introduction of CALLF, RETF and JUMPF - if (m_codeSections.size() > 1) - solUnimplemented("Add support for more code sections"); + for (size_t i = 1; i < m_codeSections.size(); ++i) + { + _out << std::endl << _prefix << "code_section_" << i << ": assembly {\n"; + Functionalizer codeSectionF(_out, _prefix + " ", _sourceCodes, *this); + for (auto const& item: m_codeSections[i].items) + codeSectionF.feed(item, _debugInfoSelection); + codeSectionF.flush(); + _out << _prefix << "}" << std::endl; + } if (!m_data.empty() || !m_subs.empty()) { @@ -696,6 +702,49 @@ AssemblyItem Assembly::namedTag(std::string const& _name, size_t _params, size_t return AssemblyItem{Tag, m_namedTags.at(_name).id}; } +AssemblyItem Assembly::newFunctionCall(uint16_t _functionID) const +{ + solAssert(_functionID < m_codeSections.size(), "Call to undeclared function."); + solAssert(_functionID > 0, "Cannot call section 0"); + auto const& section = m_codeSections.at(_functionID); + if (section.outputs != 0x80) + return AssemblyItem::functionCall(_functionID, section.inputs, section.outputs); + else + return AssemblyItem::jumpToFunction(_functionID, section.inputs, section.outputs); +} + +AssemblyItem Assembly::newFunctionReturn() const +{ + solAssert(m_currentCodeSection != 0, "Appending function return without begin function."); + return AssemblyItem::functionReturn(); +} + +uint16_t Assembly::createFunction(uint8_t _args, uint8_t _rets) +{ + size_t functionID = m_codeSections.size(); + solRequire(functionID < 1024, AssemblyException, "Too many functions for EOF"); + solAssert(m_currentCodeSection == 0, "Functions need to be declared from the main block."); + solAssert(_rets <= 0x80, "Too many function returns."); + solAssert(_args <= 127, "Too many function inputs."); + m_codeSections.emplace_back(CodeSection{_args, _rets, {}}); + return static_cast(functionID); +} + +void Assembly::beginFunction(uint16_t _functionID) +{ + solAssert(m_currentCodeSection == 0, "Attempted to begin a function before ending the last one."); + solAssert(_functionID != 0, "Attempt to begin a function with id 0"); + solAssert(_functionID < m_codeSections.size(), "Attempt to begin an undeclared function."); + auto& section = m_codeSections.at(_functionID); + solAssert(section.items.empty(), "Function already defined."); + m_currentCodeSection = _functionID; +} +void Assembly::endFunction() +{ + solAssert(m_currentCodeSection != 0, "End function without begin function."); + m_currentCodeSection = 0; +} + AssemblyItem Assembly::newPushLibraryAddress(std::string const& _identifier) { h256 h(util::keccak256(_identifier)); @@ -1402,6 +1451,7 @@ LinkerObject const& Assembly::assembleEOF() const for (auto&& [codeSectionIndex, codeSection]: m_codeSections | ranges::views::enumerate) { auto const sectionStart = ret.bytecode.size(); + solAssert(!codeSection.items.empty(), "Empty code section."); for (AssemblyItem const& item: codeSection.items) { // store position of the invalid jump destination @@ -1416,7 +1466,10 @@ LinkerObject const& Assembly::assembleEOF() const item.instruction() != Instruction::RETURNCONTRACT && item.instruction() != Instruction::EOFCREATE && item.instruction() != Instruction::RJUMP && - item.instruction() != Instruction::RJUMPI + item.instruction() != Instruction::RJUMPI && + item.instruction() != Instruction::CALLF && + item.instruction() != Instruction::JUMPF && + item.instruction() != Instruction::RETF ); solAssert(!(item.instruction() >= Instruction::PUSH0 && item.instruction() <= Instruction::PUSH32)); ret.bytecode += assembleOperation(item); @@ -1475,6 +1528,26 @@ LinkerObject const& Assembly::assembleEOF() const appendBigEndianUint16(ret.bytecode, item.data()); break; } + case CallF: + case JumpF: + { + ret.bytecode.push_back(static_cast(item.instruction())); + solAssert(item.data() <= std::numeric_limits::max(), "Invalid callf/jumpf index value."); + size_t const index = static_cast(item.data()); + solAssert(index < m_codeSections.size()); + solAssert(item.functionSignature().argsNum <= 127); + solAssert(item.type() == JumpF || item.functionSignature().retsNum <= 127); + solAssert(item.type() == CallF || item.functionSignature().retsNum <= 128); + solAssert(m_codeSections[index].inputs == item.functionSignature().argsNum); + solAssert(m_codeSections[index].outputs == item.functionSignature().retsNum); + // If CallF the function can continue. + solAssert(item.type() == JumpF || item.functionSignature().canContinue()); + appendBigEndianUint16(ret.bytecode, item.data()); + break; + } + case RetF: + ret.bytecode.push_back(static_cast(Instruction::RETF)); + break; default: solAssert(false, "Unexpected opcode while assembling."); } diff --git a/libevmasm/Assembly.h b/libevmasm/Assembly.h index 7ef03460cbcb..db567a917b10 100644 --- a/libevmasm/Assembly.h +++ b/libevmasm/Assembly.h @@ -65,9 +65,17 @@ class Assembly } std::optional eofVersion() const { return m_eofVersion; } + bool supportsFunctions() const { return m_eofVersion.has_value(); } bool supportsRelativeJumps() const { return m_eofVersion.has_value(); } AssemblyItem newTag() { assertThrow(m_usedTags < 0xffffffff, AssemblyException, ""); return AssemblyItem(Tag, m_usedTags++); } AssemblyItem newPushTag() { assertThrow(m_usedTags < 0xffffffff, AssemblyException, ""); return AssemblyItem(PushTag, m_usedTags++); } + + AssemblyItem newFunctionCall(uint16_t _functionID) const; + AssemblyItem newFunctionReturn() const; + uint16_t createFunction(uint8_t _args, uint8_t _rets); + void beginFunction(uint16_t _functionID); + void endFunction(); + /// Returns a tag identified by the given name. Creates it if it does not yet exist. AssemblyItem namedTag(std::string const& _name, size_t _params, size_t _returns, std::optional _sourceID); AssemblyItem newData(bytes const& _data) { util::h256 h(util::keccak256(util::asString(_data))); m_data[h] = _data; return AssemblyItem(PushData, h); } @@ -111,6 +119,17 @@ class Assembly return append(AssemblyItem::returnContract(_containerId)); } + AssemblyItem appendFunctionCall(uint16_t _functionID) + { + return append(newFunctionCall(_functionID)); + } + + AssemblyItem appendFunctionReturn() + { + solAssert(m_currentCodeSection != 0, "Appending function return without begin function."); + return append(newFunctionReturn()); + } + AssemblyItem appendJump() { auto ret = append(newPushTag()); append(Instruction::JUMP); return ret; } AssemblyItem appendJumpI() { auto ret = append(newPushTag()); append(Instruction::JUMPI); return ret; } AssemblyItem appendJump(AssemblyItem const& _tag) { auto ret = append(_tag.pushTag()); append(Instruction::JUMP); return ret; } diff --git a/libevmasm/AssemblyItem.h b/libevmasm/AssemblyItem.h index 62e21008b769..28b2fb537545 100644 --- a/libevmasm/AssemblyItem.h +++ b/libevmasm/AssemblyItem.h @@ -108,6 +108,27 @@ class AssemblyItem m_debugData{langutil::DebugData::create()} {} + static AssemblyItem functionCall(uint16_t _functionID, uint8_t _args, uint8_t _rets, langutil::DebugData::ConstPtr _debugData = langutil::DebugData::create()) + { + // TODO: Make this constructor this way that it's impossible to create it without setting functions signature. + // It can be done by template constructor with Instruction as template parameter i.e. Same for JumpF below. + AssemblyItem result(CallF, Instruction::CALLF, _functionID, _debugData); + solAssert(_args <= 127 && _rets <= 127); + result.m_functionSignature = {_args, _rets}; + return result; + } + static AssemblyItem jumpToFunction(uint16_t _functionID, uint8_t _args, uint8_t _rets, langutil::DebugData::ConstPtr _debugData = langutil::DebugData::create()) + { + AssemblyItem result(JumpF, Instruction::JUMPF, _functionID, _debugData); + solAssert(_args <= 127 && _rets <= 128); + result.m_functionSignature = {_args, _rets}; + return result; + } + static AssemblyItem functionReturn(langutil::DebugData::ConstPtr _debugData = langutil::DebugData::create()) + { + return AssemblyItem(RetF, Instruction::RETF, 0, std::move(_debugData)); + } + static AssemblyItem eofCreate(ContainerID _containerID, langutil::DebugData::ConstPtr _debugData = langutil::DebugData::create()) { return AssemblyItem(EOFCreate, Instruction::EOFCREATE, _containerID, std::move(_debugData)); @@ -146,7 +167,7 @@ class AssemblyItem void setPushTagSubIdAndTag(size_t _subId, size_t _tag); AssemblyItemType type() const { return m_type; } - u256 const& data() const { assertThrow(m_type != Operation, util::Exception, ""); return *m_data; } + u256 const& data() const { solAssert(m_type != Operation && m_data != nullptr); return *m_data; } void setData(u256 const& _data) { assertThrow(m_type != Operation, util::Exception, ""); m_data = std::make_shared(_data); } /// This function is used in `Assembly::assemblyJSON`. @@ -269,12 +290,30 @@ class AssemblyItem void setImmutableOccurrences(size_t _n) const { m_immutableOccurrences = _n; } + struct FunctionSignature + { + /// Number of EOF function arguments. must be less than 127 + uint8_t argsNum; + /// Number of EOF function return values. Must be less than 128. 128(0x80) means that it's non-returning. + uint8_t retsNum; + + bool canContinue() const { return retsNum != 0x80;} + }; + + FunctionSignature const& functionSignature() const + { + solAssert(m_type == CallF || m_type == JumpF); + solAssert(m_functionSignature.has_value()); + return *m_functionSignature; + } + private: size_t opcodeCount() const noexcept; AssemblyItemType m_type; Instruction m_instruction; ///< Only valid if m_type == Operation std::shared_ptr m_data; ///< Only valid if m_type != Operation + std::optional m_functionSignature; ///< Only valid if m_type == CallF or JumpF /// If m_type == VerbatimBytecode, this holds number of arguments, number of /// return variables and verbatim bytecode. std::optional> m_verbatimBytecode; diff --git a/libyul/backends/evm/AbstractAssembly.h b/libyul/backends/evm/AbstractAssembly.h index 7c44dfa78dc1..6fe234782e10 100644 --- a/libyul/backends/evm/AbstractAssembly.h +++ b/libyul/backends/evm/AbstractAssembly.h @@ -57,6 +57,7 @@ class AbstractAssembly using LabelID = size_t; using SubID = size_t; using ContainerID = uint8_t; + using FunctionID = uint16_t; enum class JumpType { Ordinary, IntoFunction, OutOfFunction }; virtual ~AbstractAssembly() = default; @@ -101,6 +102,26 @@ class AbstractAssembly virtual void appendAssemblySize() = 0; /// Creates a new sub-assembly, which can be referenced using dataSize and dataOffset. virtual std::pair, SubID> createSubAssembly(bool _creation, std::string _name = "") = 0; + + /// Registers a new function with given signature and returns its ID. + /// The function is initially empty and its body must be filled with instructions. + virtual FunctionID registerFunction(uint8_t _args, uint8_t _rets) = 0; + /// Selects a function as a target for newly appended instructions. + /// May only be called after the main code section is already filled and + /// must not be called when another function is already selected. + /// Filling the same function more than once is not allowed. + /// @a endFunction() must be called at the end to finalize the function. + virtual void beginFunction(FunctionID _functionID) = 0; + /// Finalizes the process of filling a function body and switches back to the main code section. + /// Must not be called if no function is selected. + /// Must be called after filling the main yul section + virtual void endFunction() = 0; + /// Appends function call to a function under given ID + virtual void appendFunctionCall(FunctionID _functionID) = 0; + /// Appends an instruction that returns values from the current function. + /// Only allowed inside a function body. + virtual void appendFunctionReturn() = 0; + /// Appends the offset of the given sub-assembly or data. virtual void appendDataOffset(std::vector const& _subPath) = 0; /// Appends the size of the given sub-assembly or data. diff --git a/libyul/backends/evm/EthAssemblyAdapter.cpp b/libyul/backends/evm/EthAssemblyAdapter.cpp index d8810b261db3..d9cf47f4dabe 100644 --- a/libyul/backends/evm/EthAssemblyAdapter.cpp +++ b/libyul/backends/evm/EthAssemblyAdapter.cpp @@ -145,6 +145,31 @@ std::pair, AbstractAssembly::SubID> EthAssembl return {std::make_shared(*assembly), static_cast(sub.data())}; } +AbstractAssembly::FunctionID EthAssemblyAdapter::registerFunction(uint8_t _args, uint8_t _rets) +{ + return m_assembly.createFunction(_args, _rets); +} + +void EthAssemblyAdapter::beginFunction(AbstractAssembly::FunctionID _functionID) +{ + m_assembly.beginFunction(_functionID); +} + +void EthAssemblyAdapter::endFunction() +{ + m_assembly.endFunction(); +} + +void EthAssemblyAdapter::appendFunctionReturn() +{ + m_assembly.appendFunctionReturn(); +} + +void EthAssemblyAdapter::appendFunctionCall(FunctionID _functionID) +{ + m_assembly.appendFunctionCall(_functionID); +} + void EthAssemblyAdapter::appendEOFCreate(ContainerID _containerID) { m_assembly.appendEOFCreate(_containerID); diff --git a/libyul/backends/evm/EthAssemblyAdapter.h b/libyul/backends/evm/EthAssemblyAdapter.h index d0bd3e14aff5..29a6fba7bef1 100644 --- a/libyul/backends/evm/EthAssemblyAdapter.h +++ b/libyul/backends/evm/EthAssemblyAdapter.h @@ -56,6 +56,11 @@ class EthAssemblyAdapter: public AbstractAssembly void appendJumpToIf(LabelID _labelId, JumpType _jumpType) override; void appendAssemblySize() override; std::pair, SubID> createSubAssembly(bool _creation, std::string _name = {}) override; + AbstractAssembly::FunctionID registerFunction(uint8_t _args, uint8_t _rets) override; + void beginFunction(AbstractAssembly::FunctionID _functionID) override; + void endFunction() override; + void appendFunctionCall(FunctionID _functionID) override; + void appendFunctionReturn() override; void appendEOFCreate(ContainerID _containerID) override; void appendReturnContract(ContainerID _containerID) override; void appendDataOffset(std::vector const& _subPath) override; diff --git a/libyul/backends/evm/NoOutputAssembly.cpp b/libyul/backends/evm/NoOutputAssembly.cpp index 0497b11b63fb..c9d6c6292fb5 100644 --- a/libyul/backends/evm/NoOutputAssembly.cpp +++ b/libyul/backends/evm/NoOutputAssembly.cpp @@ -120,6 +120,43 @@ std::pair, AbstractAssembly::SubID> NoOutputAs return {}; } +AbstractAssembly::FunctionID NoOutputAssembly::registerFunction(uint8_t _args, uint8_t _rets) +{ + yulAssert(m_context.numFunctions <= std::numeric_limits::max()); + AbstractAssembly::FunctionID id = static_cast(m_context.numFunctions++); + m_context.functionSignatures[id] = std::make_pair(_args, _rets); + return id; +} + +void NoOutputAssembly::beginFunction(FunctionID _functionID) +{ + yulAssert(m_currentFunctionID == 0, "Attempted to begin a function before ending the last one."); + yulAssert(m_context.functionSignatures.count(_functionID) == 1, "Filling unregistered function."); + yulAssert(m_stackHeight == 0, "Non-empty stack on beginFunction call."); + m_currentFunctionID = _functionID; +} + +void NoOutputAssembly::endFunction() +{ + yulAssert(m_currentFunctionID != 0, "End function without begin function."); + auto const rets = m_context.functionSignatures.at(m_currentFunctionID).second; + yulAssert(rets == 0x80 || m_stackHeight == rets, "Stack height mismatch at function end."); + m_currentFunctionID = 0; +} + +void NoOutputAssembly::appendFunctionCall(FunctionID _functionID) +{ + auto [args, rets] = m_context.functionSignatures.at(_functionID); + m_stackHeight += static_cast(rets) - static_cast(args); +} + +void NoOutputAssembly::appendFunctionReturn() +{ + yulAssert(m_currentFunctionID != 0, "End function without begin function."); + auto const rets = m_context.functionSignatures.at(m_currentFunctionID).second; + yulAssert(rets == 0x80 || m_stackHeight == rets, "Stack height mismatch at function end."); +} + void NoOutputAssembly::appendDataOffset(std::vector const&) { appendInstruction(evmasm::Instruction::PUSH1); diff --git a/libyul/backends/evm/NoOutputAssembly.h b/libyul/backends/evm/NoOutputAssembly.h index 5af1bd418026..2669a277c4a4 100644 --- a/libyul/backends/evm/NoOutputAssembly.h +++ b/libyul/backends/evm/NoOutputAssembly.h @@ -37,6 +37,13 @@ struct SourceLocation; namespace solidity::yul { +class NoOutputAssembly; + +struct NoOutputAssemblyContext +{ + size_t numFunctions = 0; + std::map> functionSignatures; +}; /** * Assembly class that just ignores everything and only performs stack counting. @@ -66,6 +73,11 @@ class NoOutputAssembly: public AbstractAssembly void appendAssemblySize() override; std::pair, SubID> createSubAssembly(bool _creation, std::string _name = "") override; + FunctionID registerFunction(uint8_t _args, uint8_t _rets) override; + void beginFunction(FunctionID) override; + void endFunction() override; + void appendFunctionCall(FunctionID _functionID) override; + void appendFunctionReturn() override; void appendDataOffset(std::vector const& _subPath) override; void appendDataSize(std::vector const& _subPath) override; SubID appendData(bytes const& _data) override; @@ -84,7 +96,9 @@ class NoOutputAssembly: public AbstractAssembly langutil::EVMVersion evmVersion() const override { return m_evmVersion; } private: + NoOutputAssemblyContext m_context = {}; int m_stackHeight = 0; + FunctionID m_currentFunctionID = 0; langutil::EVMVersion m_evmVersion; }; From a00ceb90b1c463747c7f8995b03a9dc74173eebc Mon Sep 17 00:00:00 2001 From: rodiazet Date: Fri, 29 Nov 2024 20:21:58 +0100 Subject: [PATCH 0593/1022] eof: Adjust EVM code transform and graph builder for EOF functions --- .../backends/evm/ControlFlowGraphBuilder.cpp | 10 ++- libyul/backends/evm/ControlFlowGraphBuilder.h | 2 + libyul/backends/evm/EVMDialect.h | 3 + .../evm/OptimizedEVMCodeTransform.cpp | 73 ++++++++++++++----- .../backends/evm/OptimizedEVMCodeTransform.h | 6 +- libyul/backends/evm/StackLayoutGenerator.cpp | 31 ++++---- libyul/backends/evm/StackLayoutGenerator.h | 10 ++- libyul/optimiser/StackCompressor.cpp | 6 +- libyul/optimiser/StackLimitEvader.cpp | 2 +- 9 files changed, 103 insertions(+), 40 deletions(-) diff --git a/libyul/backends/evm/ControlFlowGraphBuilder.cpp b/libyul/backends/evm/ControlFlowGraphBuilder.cpp index fe6e0ec8ee1d..e92515e988ad 100644 --- a/libyul/backends/evm/ControlFlowGraphBuilder.cpp +++ b/libyul/backends/evm/ControlFlowGraphBuilder.cpp @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -211,6 +212,10 @@ std::unique_ptr ControlFlowGraphBuilder::build( Block const& _block ) { + std::optional eofVersion; + if (EVMDialect const* evmDialect = dynamic_cast(&_dialect)) + eofVersion = evmDialect->eofVersion(); + auto result = std::make_unique(); result->entry = &result->makeBlock(debugDataOf(_block)); @@ -241,6 +246,8 @@ ControlFlowGraphBuilder::ControlFlowGraphBuilder( m_functionSideEffects(_functionSideEffects), m_dialect(_dialect) { + if (EVMDialect const* evmDialect = dynamic_cast(&m_dialect)) + m_simulateFunctionsWithJumps = !evmDialect->eofVersion().has_value(); } StackSlot ControlFlowGraphBuilder::operator()(Literal const& _literal) @@ -542,7 +549,8 @@ Stack const& ControlFlowGraphBuilder::visitFunctionCall(FunctionCall const& _cal Scope::Function const& function = lookupFunction(_call.functionName.name); canContinue = m_graph.functionInfo.at(&function).canContinue; Stack inputs; - if (canContinue) + // For EOF (m_simulateFunctionsWithJumps == false) we do not have to put return label on stack. + if (m_simulateFunctionsWithJumps && canContinue) inputs.emplace_back(FunctionCallReturnLabelSlot{_call}); for (auto const& arg: _call.arguments | ranges::views::reverse) inputs.emplace_back(std::visit(*this, arg)); diff --git a/libyul/backends/evm/ControlFlowGraphBuilder.h b/libyul/backends/evm/ControlFlowGraphBuilder.h index 77feaea7b469..1d0227a56b71 100644 --- a/libyul/backends/evm/ControlFlowGraphBuilder.h +++ b/libyul/backends/evm/ControlFlowGraphBuilder.h @@ -90,6 +90,8 @@ class ControlFlowGraphBuilder }; std::optional m_forLoopInfo; std::optional m_currentFunction; + /// True if control flow graph simulates functions with jumps. False otherwise. True for legacy bytecode + bool m_simulateFunctionsWithJumps = true; }; } diff --git a/libyul/backends/evm/EVMDialect.h b/libyul/backends/evm/EVMDialect.h index 65cc70f162b7..58944bdc701f 100644 --- a/libyul/backends/evm/EVMDialect.h +++ b/libyul/backends/evm/EVMDialect.h @@ -22,6 +22,7 @@ #pragma once #include +#include #include #include @@ -44,6 +45,8 @@ struct BuiltinContext Object const* currentObject = nullptr; /// Mapping from named objects to abstract assembly sub IDs. std::map subIDs; + + std::map functionIDs; }; struct BuiltinFunctionForEVM: public BuiltinFunction diff --git a/libyul/backends/evm/OptimizedEVMCodeTransform.cpp b/libyul/backends/evm/OptimizedEVMCodeTransform.cpp index 8ef01f0b6a86..89a75019ec31 100644 --- a/libyul/backends/evm/OptimizedEVMCodeTransform.cpp +++ b/libyul/backends/evm/OptimizedEVMCodeTransform.cpp @@ -49,13 +49,31 @@ std::vector OptimizedEVMCodeTransform::run( ) { std::unique_ptr dfg = ControlFlowGraphBuilder::build(_analysisInfo, _dialect, _block); - StackLayout stackLayout = StackLayoutGenerator::run(*dfg); + StackLayout stackLayout = StackLayoutGenerator::run(*dfg, !_dialect.eofVersion().has_value()); + + if (_dialect.eofVersion().has_value()) + { + for (Scope::Function const* function: dfg->functions) + { + auto const& info = dfg->functionInfo.at(function); + yulAssert(info.parameters.size() <= 0x7f); + yulAssert(info.returnVariables.size() <= 0x7f); + // According to EOF spec function output num equals 0x80 means non-returning function + auto functionID = _assembly.registerFunction( + static_cast(info.parameters.size()), + static_cast(info.canContinue ? info.returnVariables.size() : 0x80) + ); + _builtinContext.functionIDs[function] = functionID; + } + } + OptimizedEVMCodeTransform optimizedCodeTransform( _assembly, _builtinContext, _useNamedLabelsForFunctions, *dfg, - stackLayout + stackLayout, + !_dialect.eofVersion().has_value() ); // Create initial entry layout. optimizedCodeTransform.createStackLayout(debugDataOf(*dfg->entry), stackLayout.blockInfos.at(dfg->entry).entryLayout); @@ -67,10 +85,11 @@ std::vector OptimizedEVMCodeTransform::run( void OptimizedEVMCodeTransform::operator()(CFG::FunctionCall const& _call) { + bool useReturnLabel = m_simulateFunctionsWithJumps && _call.canContinue; // Validate stack. { yulAssert(m_assembly.stackHeight() == static_cast(m_stack.size()), ""); - yulAssert(m_stack.size() >= _call.function.get().numArguments + (_call.canContinue ? 1 : 0), ""); + yulAssert(m_stack.size() >= _call.function.get().numArguments + (useReturnLabel ? 1 : 0), ""); // Assert that we got the correct arguments on stack for the call. for (auto&& [arg, slot]: ranges::zip_view( _call.functionCall.get().arguments | ranges::views::reverse, @@ -78,7 +97,7 @@ void OptimizedEVMCodeTransform::operator()(CFG::FunctionCall const& _call) )) validateSlot(slot, arg); // Assert that we got the correct return label on stack. - if (_call.canContinue) + if (useReturnLabel) { auto const* returnLabelSlot = std::get_if( &m_stack.at(m_stack.size() - _call.functionCall.get().arguments.size() - 1) @@ -90,21 +109,26 @@ void OptimizedEVMCodeTransform::operator()(CFG::FunctionCall const& _call) // Emit code. { m_assembly.setSourceLocation(originLocationOf(_call)); - m_assembly.appendJumpTo( - getFunctionLabel(_call.function), - static_cast(_call.function.get().numReturns) - static_cast(_call.function.get().numArguments) - (_call.canContinue ? 1 : 0), - AbstractAssembly::JumpType::IntoFunction - ); - if (_call.canContinue) + if (!m_simulateFunctionsWithJumps) + m_assembly.appendFunctionCall(m_builtinContext.functionIDs.at(&_call.function.get())); + else + m_assembly.appendJumpTo( + getFunctionLabel(_call.function), + static_cast(_call.function.get().numReturns) - static_cast(_call.function.get().numArguments) - (_call.canContinue ? 1 : 0), + AbstractAssembly::JumpType::IntoFunction + ); + if (useReturnLabel) m_assembly.appendLabel(m_returnLabels.at(&_call.functionCall.get())); } // Update stack. { // Remove arguments and return label from m_stack. - for (size_t i = 0; i < _call.function.get().numArguments + (_call.canContinue ? 1 : 0); ++i) + for (size_t i = 0; i < _call.function.get().numArguments + (useReturnLabel ? 1 : 0); ++i) m_stack.pop_back(); // Push return values to m_stack. + if (!m_simulateFunctionsWithJumps) + yulAssert(_call.function.get().numReturns < 0x80, "Num of function output >= 128"); for (size_t index: ranges::views::iota(0u, _call.function.get().numReturns)) m_stack.emplace_back(TemporarySlot{_call.functionCall, index}); yulAssert(m_assembly.stackHeight() == static_cast(m_stack.size()), ""); @@ -177,13 +201,14 @@ OptimizedEVMCodeTransform::OptimizedEVMCodeTransform( BuiltinContext& _builtinContext, UseNamedLabels _useNamedLabelsForFunctions, CFG const& _dfg, - StackLayout const& _stackLayout + StackLayout const& _stackLayout, + bool _simulateFunctionsWithJumps ): m_assembly(_assembly), m_builtinContext(_builtinContext), m_dfg(_dfg), m_stackLayout(_stackLayout), - m_functionLabels([&](){ + m_functionLabels(!_simulateFunctionsWithJumps ? decltype(m_functionLabels)() : [&](){ std::map functionLabels; std::set assignedFunctionNames; for (Scope::Function const* function: m_dfg.functions) @@ -203,7 +228,8 @@ OptimizedEVMCodeTransform::OptimizedEVMCodeTransform( m_assembly.newLabelId(); } return functionLabels; - }()) + }()), + m_simulateFunctionsWithJumps(_simulateFunctionsWithJumps) { } @@ -216,6 +242,7 @@ void OptimizedEVMCodeTransform::assertLayoutCompatibility(Stack const& _currentS AbstractAssembly::LabelID OptimizedEVMCodeTransform::getFunctionLabel(Scope::Function const& _function) { + yulAssert(m_simulateFunctionsWithJumps); return m_functionLabels.at(&m_dfg.functionInfo.at(&_function)); } @@ -493,11 +520,15 @@ void OptimizedEVMCodeTransform::operator()(CFG::BasicBlock const& _block) Stack exitStack = m_currentFunctionInfo->returnVariables | ranges::views::transform([](auto const& _varSlot){ return StackSlot{_varSlot}; }) | ranges::to; - exitStack.emplace_back(FunctionReturnLabelSlot{_functionReturn.info->function}); + if (m_simulateFunctionsWithJumps) + exitStack.emplace_back(FunctionReturnLabelSlot{_functionReturn.info->function}); // Create the function return layout and jump. createStackLayout(debugDataOf(_functionReturn), exitStack); - m_assembly.appendJump(0, AbstractAssembly::JumpType::OutOfFunction); + if (!m_simulateFunctionsWithJumps) + m_assembly.appendFunctionReturn(); + else + m_assembly.appendJump(0, AbstractAssembly::JumpType::OutOfFunction); }, [&](CFG::BasicBlock::Terminated const&) { @@ -518,25 +549,31 @@ void OptimizedEVMCodeTransform::operator()(CFG::BasicBlock const& _block) void OptimizedEVMCodeTransform::operator()(CFG::FunctionInfo const& _functionInfo) { + bool useReturnLabel = m_simulateFunctionsWithJumps && _functionInfo.canContinue; yulAssert(!m_currentFunctionInfo, ""); ScopedSaveAndRestore currentFunctionInfoRestore(m_currentFunctionInfo, &_functionInfo); yulAssert(m_stack.empty() && m_assembly.stackHeight() == 0, ""); // Create function entry layout in m_stack. - if (_functionInfo.canContinue) + if (useReturnLabel) m_stack.emplace_back(FunctionReturnLabelSlot{_functionInfo.function}); for (auto const& param: _functionInfo.parameters | ranges::views::reverse) m_stack.emplace_back(param); + if (!m_simulateFunctionsWithJumps) + m_assembly.beginFunction(m_builtinContext.functionIDs[&_functionInfo.function]); m_assembly.setStackHeight(static_cast(m_stack.size())); m_assembly.setSourceLocation(originLocationOf(_functionInfo)); - m_assembly.appendLabel(getFunctionLabel(_functionInfo.function)); + if (m_simulateFunctionsWithJumps) + m_assembly.appendLabel(getFunctionLabel(_functionInfo.function)); // Create the entry layout of the function body block and visit. createStackLayout(debugDataOf(_functionInfo), m_stackLayout.blockInfos.at(_functionInfo.entry).entryLayout); (*this)(*_functionInfo.entry); m_stack.clear(); + if (!m_simulateFunctionsWithJumps) + m_assembly.endFunction(); m_assembly.setStackHeight(0); } diff --git a/libyul/backends/evm/OptimizedEVMCodeTransform.h b/libyul/backends/evm/OptimizedEVMCodeTransform.h index 7e648ca964bb..2c072bcca2f6 100644 --- a/libyul/backends/evm/OptimizedEVMCodeTransform.h +++ b/libyul/backends/evm/OptimizedEVMCodeTransform.h @@ -68,7 +68,8 @@ class OptimizedEVMCodeTransform BuiltinContext& _builtinContext, UseNamedLabels _useNamedLabelsForFunctions, CFG const& _dfg, - StackLayout const& _stackLayout + StackLayout const& _stackLayout, + bool _simulateFunctionsWithJumps ); /// Assert that it is valid to transition from @a _currentStack to @a _desiredStack. @@ -104,12 +105,15 @@ class OptimizedEVMCodeTransform Stack m_stack; std::map m_returnLabels; std::map m_blockLabels; + /// Non-empty only if m_dfg.simulateFunctionsWithJumps == true 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; CFG::FunctionInfo const* m_currentFunctionInfo = nullptr; std::vector m_stackErrors; + /// True if it simulates functions with jumps. False otherwise. True for legacy bytecode + bool m_simulateFunctionsWithJumps = true; }; } diff --git a/libyul/backends/evm/StackLayoutGenerator.cpp b/libyul/backends/evm/StackLayoutGenerator.cpp index 1a30842aecc8..3d1d5f7b0d76 100644 --- a/libyul/backends/evm/StackLayoutGenerator.cpp +++ b/libyul/backends/evm/StackLayoutGenerator.cpp @@ -47,30 +47,30 @@ using namespace solidity; using namespace solidity::yul; -StackLayout StackLayoutGenerator::run(CFG const& _cfg) +StackLayout StackLayoutGenerator::run(CFG const& _cfg, bool _simulateFunctionsWithJumps) { - StackLayout stackLayout; - StackLayoutGenerator{stackLayout, nullptr}.processEntryPoint(*_cfg.entry); + StackLayout stackLayout{{}, {}}; + StackLayoutGenerator{stackLayout, nullptr, _simulateFunctionsWithJumps}.processEntryPoint(*_cfg.entry); for (auto& functionInfo: _cfg.functionInfo | ranges::views::values) - StackLayoutGenerator{stackLayout, &functionInfo}.processEntryPoint(*functionInfo.entry, &functionInfo); + StackLayoutGenerator{stackLayout, &functionInfo, _simulateFunctionsWithJumps}.processEntryPoint(*functionInfo.entry, &functionInfo); return stackLayout; } -std::map> StackLayoutGenerator::reportStackTooDeep(CFG const& _cfg) +std::map> StackLayoutGenerator::reportStackTooDeep(CFG const& _cfg, bool _simulateFunctionsWithJumps) { std::map> stackTooDeepErrors; - stackTooDeepErrors[YulName{}] = reportStackTooDeep(_cfg, YulName{}); + stackTooDeepErrors[YulName{}] = reportStackTooDeep(_cfg, YulName{}, _simulateFunctionsWithJumps); for (auto const& function: _cfg.functions) - if (auto errors = reportStackTooDeep(_cfg, function->name); !errors.empty()) + if (auto errors = reportStackTooDeep(_cfg, function->name, _simulateFunctionsWithJumps); !errors.empty()) stackTooDeepErrors[function->name] = std::move(errors); return stackTooDeepErrors; } -std::vector StackLayoutGenerator::reportStackTooDeep(CFG const& _cfg, YulName _functionName) +std::vector StackLayoutGenerator::reportStackTooDeep(CFG const& _cfg, YulName _functionName, bool _simulateFunctionsWithJumps) { - StackLayout stackLayout; + StackLayout stackLayout{{}, {}}; CFG::FunctionInfo const* functionInfo = nullptr; if (!_functionName.empty()) { @@ -82,15 +82,16 @@ std::vector StackLayoutGenerator::reportStac yulAssert(functionInfo, "Function not found."); } - StackLayoutGenerator generator{stackLayout, functionInfo}; + StackLayoutGenerator generator{stackLayout, functionInfo, _simulateFunctionsWithJumps}; CFG::BasicBlock const* entry = functionInfo ? functionInfo->entry : _cfg.entry; generator.processEntryPoint(*entry); return generator.reportStackTooDeep(*entry); } -StackLayoutGenerator::StackLayoutGenerator(StackLayout& _layout, CFG::FunctionInfo const* _functionInfo): +StackLayoutGenerator::StackLayoutGenerator(StackLayout& _layout, CFG::FunctionInfo const* _functionInfo, bool _simulateFunctionsWithJumps): m_layout(_layout), - m_currentFunctionInfo(_functionInfo) + m_currentFunctionInfo(_functionInfo), + m_simulateFunctionsWithJumps(_simulateFunctionsWithJumps) { } @@ -464,7 +465,9 @@ std::optional StackLayoutGenerator::getExitLayoutOrStageDependencies( Stack stack = _functionReturn.info->returnVariables | ranges::views::transform([](auto const& _varSlot){ return StackSlot{_varSlot}; }) | ranges::to; - stack.emplace_back(FunctionReturnLabelSlot{_functionReturn.info->function}); + + if (m_simulateFunctionsWithJumps) + stack.emplace_back(FunctionReturnLabelSlot{_functionReturn.info->function}); return stack; }, [&](CFG::BasicBlock::Terminated const&) -> std::optional @@ -735,7 +738,7 @@ void StackLayoutGenerator::fillInJunk(CFG::BasicBlock const& _block, CFG::Functi _addChild(_conditionalJump.zero); _addChild(_conditionalJump.nonZero); }, - [&](CFG::BasicBlock::FunctionReturn const&) { yulAssert(false); }, + [&](CFG::BasicBlock::FunctionReturn const&) { yulAssert(!m_simulateFunctionsWithJumps); }, [&](CFG::BasicBlock::Terminated const&) {}, }, _block->exit); }); diff --git a/libyul/backends/evm/StackLayoutGenerator.h b/libyul/backends/evm/StackLayoutGenerator.h index fc846a9deced..44cbbd43a4b3 100644 --- a/libyul/backends/evm/StackLayoutGenerator.h +++ b/libyul/backends/evm/StackLayoutGenerator.h @@ -55,18 +55,18 @@ class StackLayoutGenerator std::vector variableChoices; }; - static StackLayout run(CFG const& _cfg); + static StackLayout run(CFG const& _cfg, bool _simulateFunctionsWithJumps); /// @returns a map from function names to the stack too deep errors occurring in that function. /// Requires @a _cfg to be a control flow graph generated from disambiguated Yul. /// The empty string is mapped to the stack too deep errors of the main entry point. - static std::map> reportStackTooDeep(CFG const& _cfg); + static std::map> reportStackTooDeep(CFG const& _cfg, bool _simulateFunctionsWithJumps); /// @returns all stack too deep errors in the function named @a _functionName. /// Requires @a _cfg to be a control flow graph generated from disambiguated Yul. /// If @a _functionName is empty, the stack too deep errors of the main entry point are reported instead. - static std::vector reportStackTooDeep(CFG const& _cfg, YulName _functionName); + static std::vector reportStackTooDeep(CFG const& _cfg, YulName _functionName, bool _simulateFunctionsWithJumps); private: - StackLayoutGenerator(StackLayout& _context, CFG::FunctionInfo const* _functionInfo); + StackLayoutGenerator(StackLayout& _context, CFG::FunctionInfo const* _functionInfo, bool _simulateFunctionsWithJumps); /// @returns the optimal entry stack layout, s.t. @a _operation can be applied to it and /// the result can be transformed to @a _exitStack with minimal stack shuffling. @@ -116,6 +116,8 @@ class StackLayoutGenerator StackLayout& m_layout; CFG::FunctionInfo const* m_currentFunctionInfo = nullptr; + /// True if it simulates functions with jumps. False otherwise. True for legacy bytecode + bool m_simulateFunctionsWithJumps = true; }; } diff --git a/libyul/optimiser/StackCompressor.cpp b/libyul/optimiser/StackCompressor.cpp index 6ad3899e96c5..71a0463c9b17 100644 --- a/libyul/optimiser/StackCompressor.cpp +++ b/libyul/optimiser/StackCompressor.cpp @@ -248,11 +248,15 @@ std::tuple StackCompressor::run( "Need to run the function grouper before the stack compressor." ); bool usesOptimizedCodeGenerator = false; + bool simulateFunctionsWithJumps = true; if (auto evmDialect = dynamic_cast(&_dialect)) + { usesOptimizedCodeGenerator = _optimizeStackAllocation && evmDialect->evmVersion().canOverchargeGasForCall() && evmDialect->providesObjectAccess(); + simulateFunctionsWithJumps = !evmDialect->eofVersion().has_value(); + } bool allowMSizeOptimization = !MSizeFinder::containsMSize(_dialect, _object.code()->root()); Block astRoot = std::get(ASTCopier{}(_object.code()->root())); if (usesOptimizedCodeGenerator) @@ -266,7 +270,7 @@ std::tuple StackCompressor::run( eliminateVariablesOptimizedCodegen( _dialect, astRoot, - StackLayoutGenerator::reportStackTooDeep(*cfg), + StackLayoutGenerator::reportStackTooDeep(*cfg, simulateFunctionsWithJumps), allowMSizeOptimization ); } diff --git a/libyul/optimiser/StackLimitEvader.cpp b/libyul/optimiser/StackLimitEvader.cpp index 6ef4b267b67e..02c6de1594e3 100644 --- a/libyul/optimiser/StackLimitEvader.cpp +++ b/libyul/optimiser/StackLimitEvader.cpp @@ -138,7 +138,7 @@ Block StackLimitEvader::run( _object.summarizeStructure() ); std::unique_ptr cfg = ControlFlowGraphBuilder::build(analysisInfo, *evmDialect, astRoot); - run(_context, astRoot, StackLayoutGenerator::reportStackTooDeep(*cfg)); + run(_context, astRoot, StackLayoutGenerator::reportStackTooDeep(*cfg, !evmDialect->eofVersion().has_value())); } else { From 2bae7e16d9de49c3bccbbe5ac9a84893052767c9 Mon Sep 17 00:00:00 2001 From: rodiazet Date: Fri, 29 Nov 2024 20:21:58 +0100 Subject: [PATCH 0594/1022] eof: Add proper errors on arguments and return values count limit exceeded. --- libyul/AsmAnalysis.cpp | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/libyul/AsmAnalysis.cpp b/libyul/AsmAnalysis.cpp index aedf4fd0708f..491effe8e619 100644 --- a/libyul/AsmAnalysis.cpp +++ b/libyul/AsmAnalysis.cpp @@ -290,6 +290,23 @@ void AsmAnalyzer::operator()(FunctionDefinition const& _funDef) m_activeVariables.insert(&std::get(varScope.identifiers.at(var.name))); } + if (m_eofVersion.has_value()) + { + if (_funDef.parameters.size() >= 0x80) + m_errorReporter.typeError( + 8534_error, + nativeLocationOf(_funDef), + "Too many function parameters. At most 127 parameters allowed for EOF" + ); + + if (_funDef.returnVariables.size() >= 0x80) + m_errorReporter.typeError( + 2101_error, + nativeLocationOf(_funDef), + "Too many function return variables. At most 127 return variables allowed for EOF" + ); + } + (*this)(_funDef.body); } From 363f3ddee21019336f4d777457781e4627f72acf Mon Sep 17 00:00:00 2001 From: rodiazet Date: Fri, 29 Nov 2024 20:21:58 +0100 Subject: [PATCH 0595/1022] eof: Add test, make needed test support bytecodeFormat flag, adjust subcontainers tests --- test/libyul/ControlFlowGraphTest.cpp | 2 +- test/libyul/ControlFlowGraphTest.h | 2 +- test/libyul/StackLayoutGeneratorTest.cpp | 10 ++- test/libyul/StackLayoutGeneratorTest.h | 2 +- .../objectCompiler/eof/256_subcontainers.yul | 1 - test/libyul/objectCompiler/eof/functions.yul | 84 +++++++++++++++++++ ...oo_many_functions_arguments_or_returns.yul | 26 ++++++ .../eof/too_many_subcontainers.yul | 1 - 8 files changed, 121 insertions(+), 7 deletions(-) create mode 100644 test/libyul/objectCompiler/eof/functions.yul create mode 100644 test/libyul/yulSyntaxTests/eof/too_many_functions_arguments_or_returns.yul diff --git a/test/libyul/ControlFlowGraphTest.cpp b/test/libyul/ControlFlowGraphTest.cpp index b7264bc0e96d..0aaaea58105c 100644 --- a/test/libyul/ControlFlowGraphTest.cpp +++ b/test/libyul/ControlFlowGraphTest.cpp @@ -41,7 +41,7 @@ using namespace solidity::frontend; using namespace solidity::frontend::test; ControlFlowGraphTest::ControlFlowGraphTest(std::string const& _filename): - TestCase(_filename) + EVMVersionRestrictedTestCase(_filename) { m_source = m_reader.source(); auto dialectName = m_reader.stringSetting("dialect", "evm"); diff --git a/test/libyul/ControlFlowGraphTest.h b/test/libyul/ControlFlowGraphTest.h index 44cea06d3f7c..e9de50a610c3 100644 --- a/test/libyul/ControlFlowGraphTest.h +++ b/test/libyul/ControlFlowGraphTest.h @@ -27,7 +27,7 @@ struct Dialect; namespace test { -class ControlFlowGraphTest: public solidity::frontend::test::TestCase +class ControlFlowGraphTest: public frontend::test::EVMVersionRestrictedTestCase { public: static std::unique_ptr create(Config const& _config) diff --git a/test/libyul/StackLayoutGeneratorTest.cpp b/test/libyul/StackLayoutGeneratorTest.cpp index f50d2d23b028..49af089ef82f 100644 --- a/test/libyul/StackLayoutGeneratorTest.cpp +++ b/test/libyul/StackLayoutGeneratorTest.cpp @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -45,7 +46,7 @@ using namespace solidity::frontend; using namespace solidity::frontend::test; StackLayoutGeneratorTest::StackLayoutGeneratorTest(std::string const& _filename): - TestCase(_filename) + EVMVersionRestrictedTestCase(_filename) { m_source = m_reader.source(); auto dialectName = m_reader.stringSetting("dialect", "evm"); @@ -229,7 +230,12 @@ TestCase::TestResult StackLayoutGeneratorTest::run(std::ostream& _stream, std::s std::ostringstream output; std::unique_ptr cfg = ControlFlowGraphBuilder::build(*analysisInfo, *m_dialect, object->code()->root()); - StackLayout stackLayout = StackLayoutGenerator::run(*cfg); + + bool simulateFunctionsWithJumps = true; + if (auto const* evmDialect = dynamic_cast(m_dialect)) + simulateFunctionsWithJumps = !evmDialect->eofVersion().has_value(); + + StackLayout stackLayout = StackLayoutGenerator::run(*cfg, simulateFunctionsWithJumps); output << "digraph CFG {\nnodesep=0.7;\nnode[shape=box];\n\n"; StackLayoutPrinter printer{output, stackLayout}; diff --git a/test/libyul/StackLayoutGeneratorTest.h b/test/libyul/StackLayoutGeneratorTest.h index 9f570045f78e..6116b1df7347 100644 --- a/test/libyul/StackLayoutGeneratorTest.h +++ b/test/libyul/StackLayoutGeneratorTest.h @@ -27,7 +27,7 @@ struct Dialect; namespace test { -class StackLayoutGeneratorTest: public solidity::frontend::test::TestCase +class StackLayoutGeneratorTest: public frontend::test::EVMVersionRestrictedTestCase { public: static std::unique_ptr create(Config const& _config) diff --git a/test/libyul/objectCompiler/eof/256_subcontainers.yul b/test/libyul/objectCompiler/eof/256_subcontainers.yul index 06aebd6742da..46df86355091 100644 --- a/test/libyul/objectCompiler/eof/256_subcontainers.yul +++ b/test/libyul/objectCompiler/eof/256_subcontainers.yul @@ -517,7 +517,6 @@ object "a" { } // ==== -// EVMVersion: >=prague // bytecodeFormat: >=EOFv1 // ---- // Assembly: diff --git a/test/libyul/objectCompiler/eof/functions.yul b/test/libyul/objectCompiler/eof/functions.yul new file mode 100644 index 000000000000..72167f72ab04 --- /dev/null +++ b/test/libyul/objectCompiler/eof/functions.yul @@ -0,0 +1,84 @@ +object "a" { + code { + mstore(0, fun1(calldataload(0))) + + if calldataload(32) { + non_ret_fun() + } + + return(0, 32) + + function fun1(i) -> r { + if i { + r := 5 + leave + } + r := 99 + } + + function non_ret_fun() { + revert(0, 0) + } + } +} + +// ==== +// bytecodeFormat: >=EOFv1 +// ---- +// Assembly: +// /* "source":74:75 */ +// 0x00 +// /* "source":61:76 */ +// calldataload +// /* "source":56:77 */ +// callf{code_section_1} +// /* "source":53:54 */ +// 0x00 +// /* "source":46:78 */ +// mstore +// /* "source":107:109 */ +// 0x20 +// /* "source":94:110 */ +// calldataload +// /* "source":91:128 */ +// rjumpi{tag_1} +// /* "source":22:386 */ +// tag_2: +// /* "source":151:153 */ +// 0x20 +// /* "source":148:149 */ +// 0x00 +// /* "source":141:154 */ +// return +// /* "source":111:128 */ +// tag_1: +// /* "source":113:126 */ +// jumpf{code_section_2} +// +// code_section_1: assembly { +// /* "source":217:294 */ +// rjumpi{tag_3} +// /* "source":203:324 */ +// tag_4: +// /* "source":312:314 */ +// 0x63 +// /* "source":173:324 */ +// retf +// /* "source":234:294 */ +// tag_3: +// /* "source":257:258 */ +// 0x05 +// /* "source":275:280 */ +// retf +// } +// +// code_section_2: assembly { +// /* "source":376:377 */ +// 0x00 +// /* "source":366:378 */ +// dup1 +// revert +// } +// Bytecode: ef000101000c020003001400090003040000000080ffff0101ffff0080ffff5f35e300015f52602035e1000460205ff3e50002e100036063e46005e45f80fd +// Opcodes: 0xEF STOP ADD ADD STOP 0xC MUL STOP SUB STOP EQ STOP MULMOD STOP SUB DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT ADD ADD SELFDESTRUCT SELFDESTRUCT STOP DUP1 SELFDESTRUCT SELFDESTRUCT PUSH0 CALLDATALOAD CALLF 0x1 PUSH0 MSTORE PUSH1 0x20 CALLDATALOAD RJUMPI 0x4 PUSH1 0x20 PUSH0 RETURN JUMPF 0x2 RJUMPI 0x3 PUSH1 0x63 RETF PUSH1 0x5 RETF PUSH0 DUP1 REVERT +// SourceMappings: 74:1:0:-:0;61:15;56:21::i;53:1::-;46:32;107:2;94:16;91:37;22:364;151:2;148:1;141:13;111:17;113:13::i217:77:0:-:0;203:121;312:2;173:151::o;234:60::-;257:1;275:5::o376:1:0:-:0;366:12; diff --git a/test/libyul/yulSyntaxTests/eof/too_many_functions_arguments_or_returns.yul b/test/libyul/yulSyntaxTests/eof/too_many_functions_arguments_or_returns.yul new file mode 100644 index 000000000000..623bf6ded6fb --- /dev/null +++ b/test/libyul/yulSyntaxTests/eof/too_many_functions_arguments_or_returns.yul @@ -0,0 +1,26 @@ +object "a" { + code { + function too_many_arguments( + i1, i2, i3, i4, i5, i6, i7, i8, i9, i10, i11, i12, i13, i14, i15, i16, i17, i18, i19, i20, i21, i22, i23, i24, i25, i26, i27, i28, i29, i30, + i31, i32, i33, i34, i35, i36, i37, i38, i39, i40, i41, i42, i43, i44, i45, i46, i47, i48, i49, i50, i51, i52, i53, i54, i55, i56, i57, i58, i59, i60, + i61, i62, i63, i64, i65, i66, i67, i68, i69, i70, i71, i72, i73, i74, i75, i76, i77, i78, i79, i80, i81, i82, i83, i84, i85, i86, i87, i88, i89, i90, + i91, i92, i93, i94, i95, i96, i97, i98, i99, i100, i101, i102, i103, i104, i105, i106, i107, i108, i109, i110, i111, i112, i113, i114, i115, i116, i117, i118, i119, i120, + i121, i122, i123, i124, i125, i126, i127, i128 + ) + {} + + function too_many_returns()-> + i1, i2, i3, i4, i5, i6, i7, i8, i9, i10, i11, i12, i13, i14, i15, i16, i17, i18, i19, i20, i21, i22, i23, i24, i25, i26, i27, i28, i29, i30, + i31, i32, i33, i34, i35, i36, i37, i38, i39, i40, i41, i42, i43, i44, i45, i46, i47, i48, i49, i50, i51, i52, i53, i54, i55, i56, i57, i58, i59, i60, + i61, i62, i63, i64, i65, i66, i67, i68, i69, i70, i71, i72, i73, i74, i75, i76, i77, i78, i79, i80, i81, i82, i83, i84, i85, i86, i87, i88, i89, i90, + i91, i92, i93, i94, i95, i96, i97, i98, i99, i100, i101, i102, i103, i104, i105, i106, i107, i108, i109, i110, i111, i112, i113, i114, i115, i116, i117, i118, i119, i120, + i121, i122, i123, i124, i125, i126, i127, i128 + {} + } +} + +// ==== +// bytecodeFormat: >=EOFv1 +// ---- +// TypeError 8534: (32-800): Too many function parameters. At most 127 parameters allowed for EOF +// TypeError 2101: (810-1569): Too many function return variables. At most 127 return variables allowed for EOF diff --git a/test/libyul/yulSyntaxTests/eof/too_many_subcontainers.yul b/test/libyul/yulSyntaxTests/eof/too_many_subcontainers.yul index f39d6f2d8639..314d4fa3df72 100644 --- a/test/libyul/yulSyntaxTests/eof/too_many_subcontainers.yul +++ b/test/libyul/yulSyntaxTests/eof/too_many_subcontainers.yul @@ -264,7 +264,6 @@ object "a" { } // ==== -// EVMVersion: >=prague // bytecodeFormat: >=EOFv1 // ---- // SyntaxError 1305: (22-101): Too many subobjects in "a". At most 256 subobjects allowed when compiling to EOF From 120e344b4eca4c42a405fe2da84b02468f921ada Mon Sep 17 00:00:00 2001 From: rodiazet Date: Sat, 30 Nov 2024 12:10:16 +0100 Subject: [PATCH 0596/1022] eof: Hide rjumps in yul --- libyul/backends/evm/EVMDialect.cpp | 2 ++ test/libyul/yulSyntaxTests/eof/rjump_rjumpi.yul | 11 +++++++++++ 2 files changed, 13 insertions(+) create mode 100644 test/libyul/yulSyntaxTests/eof/rjump_rjumpi.yul diff --git a/libyul/backends/evm/EVMDialect.cpp b/libyul/backends/evm/EVMDialect.cpp index de1201481a3c..4d160b03049e 100644 --- a/libyul/backends/evm/EVMDialect.cpp +++ b/libyul/backends/evm/EVMDialect.cpp @@ -209,6 +209,8 @@ std::vector> createBuiltins(langutil::EVMVe opcode != evmasm::Instruction::DATALOADN && opcode != evmasm::Instruction::EOFCREATE && opcode != evmasm::Instruction::RETURNCONTRACT && + opcode != evmasm::Instruction::RJUMP && + opcode != evmasm::Instruction::RJUMPI && opcode != evmasm::Instruction::CALLF && opcode != evmasm::Instruction::JUMPF && opcode != evmasm::Instruction::RETF && diff --git a/test/libyul/yulSyntaxTests/eof/rjump_rjumpi.yul b/test/libyul/yulSyntaxTests/eof/rjump_rjumpi.yul new file mode 100644 index 000000000000..00042ae65076 --- /dev/null +++ b/test/libyul/yulSyntaxTests/eof/rjump_rjumpi.yul @@ -0,0 +1,11 @@ +object "a" { + code { + rjump() + rjumpi() + } +} +// ==== +// bytecodeFormat: legacy,>=EOFv1 +// ---- +// DeclarationError 4619: (32-37): Function "rjump" not found. +// DeclarationError 4619: (48-54): Function "rjumpi" not found. From a0ec6a49955867775dbfe3d2afdce6d19e45c9fa Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Thu, 31 Oct 2024 11:27:10 +0100 Subject: [PATCH 0597/1022] Yul: Store dialect in the AST --- libsolidity/ast/ASTJsonImporter.cpp | 2 +- libsolidity/codegen/CompilerContext.cpp | 7 ++++--- libsolidity/codegen/ContractCompiler.cpp | 4 ++-- libyul/AST.h | 8 ++++++-- libyul/AsmJsonImporter.cpp | 2 +- libyul/AsmJsonImporter.h | 6 +++++- libyul/AsmParser.cpp | 2 +- libyul/Object.cpp | 13 +++++++++++-- libyul/Object.h | 6 ++---- libyul/ObjectOptimizer.cpp | 4 ++-- libyul/ObjectParser.cpp | 4 ++-- libyul/optimiser/StackCompressor.cpp | 3 ++- libyul/optimiser/Suite.cpp | 10 +++++----- test/libyul/CompilabilityChecker.cpp | 3 ++- test/libyul/ControlFlowSideEffectsTest.cpp | 2 +- test/libyul/FunctionSideEffects.cpp | 2 +- test/libyul/KnowledgeBaseTest.cpp | 2 +- test/libyul/YulOptimizerTest.cpp | 3 ++- test/libyul/YulOptimizerTestCommon.cpp | 6 +++--- test/tools/yulopti.cpp | 4 ++-- tools/yulPhaser/Program.cpp | 8 ++++---- 21 files changed, 60 insertions(+), 41 deletions(-) diff --git a/libsolidity/ast/ASTJsonImporter.cpp b/libsolidity/ast/ASTJsonImporter.cpp index ee52bf53c27d..5d59308ae3d9 100644 --- a/libsolidity/ast/ASTJsonImporter.cpp +++ b/libsolidity/ast/ASTJsonImporter.cpp @@ -742,7 +742,7 @@ ASTPointer ASTJsonImporter::createInlineAssembly(Json const& _no flags->emplace_back(std::make_shared(flag.get())); } } - std::shared_ptr operations = std::make_shared(yul::AsmJsonImporter(m_sourceNames).createAST(member(_node, "AST"))); + std::shared_ptr operations = std::make_shared(yul::AsmJsonImporter(dialect, m_sourceNames).createAST(member(_node, "AST"))); return createASTNode( _node, nullOrASTString(_node, "documentation"), diff --git a/libsolidity/codegen/CompilerContext.cpp b/libsolidity/codegen/CompilerContext.cpp index 84de00656e90..c09b33a0081e 100644 --- a/libsolidity/codegen/CompilerContext.cpp +++ b/libsolidity/codegen/CompilerContext.cpp @@ -481,7 +481,7 @@ void CompilerContext::appendInlineAssembly( // so we essentially only optimize the ABI functions. if (_optimiserSettings.runYulOptimiser && _localVariables.empty()) { - yul::Object obj{dialect}; + yul::Object obj; obj.setCode(parserResult, std::make_shared(analysisInfo)); solAssert(!dialect.providesObjectAccess()); @@ -491,8 +491,9 @@ void CompilerContext::appendInlineAssembly( { // Store as generated sources, but first re-parse to update the source references. solAssert(m_generatedYulUtilityCode.empty(), ""); - m_generatedYulUtilityCode = yul::AsmPrinter(obj.dialect())(obj.code()->root()); - std::string code = yul::AsmPrinter{obj.dialect()}(obj.code()->root()); + solAssert(obj.dialect()); + m_generatedYulUtilityCode = yul::AsmPrinter(*obj.dialect())(obj.code()->root()); + std::string code = yul::AsmPrinter{*obj.dialect()}(obj.code()->root()); langutil::CharStream charStream(m_generatedYulUtilityCode, _sourceName); obj.setCode(yul::Parser(errorReporter, dialect).parse(charStream)); obj.analysisInfo = std::make_shared(yul::AsmAnalyzer::analyzeStrictAssertCorrect(dialect, obj)); diff --git a/libsolidity/codegen/ContractCompiler.cpp b/libsolidity/codegen/ContractCompiler.cpp index 97ffb17e917f..3548d0ae7850 100644 --- a/libsolidity/codegen/ContractCompiler.cpp +++ b/libsolidity/codegen/ContractCompiler.cpp @@ -932,7 +932,7 @@ bool ContractCompiler::visit(InlineAssembly const& _inlineAssembly) // Only used in the scope below, but required to live outside to keep the // std::shared_ptr's alive - yul::Object object{_inlineAssembly.dialect()}; + yul::Object object; // The optimiser cannot handle external references if ( @@ -944,7 +944,7 @@ bool ContractCompiler::visit(InlineAssembly const& _inlineAssembly) solAssert(dialect, ""); // Create a modifiable copy of the code and analysis - object.setCode(std::make_shared(yul::ASTCopier().translate(code->root()))); + object.setCode(std::make_shared(_inlineAssembly.dialect(), yul::ASTCopier().translate(code->root()))); object.analysisInfo = std::make_shared(yul::AsmAnalyzer::analyzeStrictAssertCorrect(*dialect, object)); m_context.optimizeYul(object, *dialect, m_optimiserSettings); diff --git a/libyul/AST.h b/libyul/AST.h index f51846280a8f..be734fa6b906 100644 --- a/libyul/AST.h +++ b/libyul/AST.h @@ -36,6 +36,8 @@ namespace solidity::yul { +struct Dialect; + struct NameWithDebugData { langutil::DebugData::ConstPtr debugData; YulName name; }; using NameWithDebugDataList = std::vector; @@ -103,10 +105,12 @@ struct Leave { langutil::DebugData::ConstPtr debugData; }; class AST { public: - explicit AST(Block _root): m_root(std::move(_root)) {} + AST(Dialect const& _dialect, Block _root): m_dialect(_dialect), m_root(std::move(_root)) {} - [[nodiscard]] Block const& root() const { return m_root; } + Dialect const& dialect() const { return m_dialect; } + Block const& root() const { return m_root; } private: + Dialect const& m_dialect; Block m_root; }; diff --git a/libyul/AsmJsonImporter.cpp b/libyul/AsmJsonImporter.cpp index 459d9d9becd5..692169fd29c6 100644 --- a/libyul/AsmJsonImporter.cpp +++ b/libyul/AsmJsonImporter.cpp @@ -51,7 +51,7 @@ SourceLocation const AsmJsonImporter::createSourceLocation(Json const& _node) AST AsmJsonImporter::createAST(solidity::Json const& _node) { - return AST(createBlock(_node)); + return {m_dialect, createBlock(_node)}; } template diff --git a/libyul/AsmJsonImporter.h b/libyul/AsmJsonImporter.h index f3df8c178e9d..2d7ff472c5e9 100644 --- a/libyul/AsmJsonImporter.h +++ b/libyul/AsmJsonImporter.h @@ -32,13 +32,16 @@ namespace solidity::yul { +struct Dialect; + /** * Component that imports an AST from json format to the internal format */ class AsmJsonImporter { public: - explicit AsmJsonImporter(std::vector> const& _sourceNames): + explicit AsmJsonImporter(Dialect const& _dialect, std::vector> const& _sourceNames): + m_dialect(_dialect), m_sourceNames(_sourceNames) {} @@ -73,6 +76,7 @@ class AsmJsonImporter yul::Break createBreak(Json const& _node); yul::Continue createContinue(Json const& _node); + Dialect const& m_dialect; std::vector> const& m_sourceNames; }; diff --git a/libyul/AsmParser.cpp b/libyul/AsmParser.cpp index 26a4d386dddc..baef6a3c52ad 100644 --- a/libyul/AsmParser.cpp +++ b/libyul/AsmParser.cpp @@ -125,7 +125,7 @@ std::unique_ptr Parser::parseInline(std::shared_ptr const& _scanne m_scanner = _scanner; if (m_useSourceLocationFrom == UseSourceLocationFrom::Comments) fetchDebugDataFromComment(); - return std::make_unique(parseBlock()); + return std::make_unique(m_dialect, parseBlock()); } catch (FatalError const& error) { diff --git a/libyul/Object.cpp b/libyul/Object.cpp index 3bd0531f4fdd..0dfa610d07ae 100644 --- a/libyul/Object.cpp +++ b/libyul/Object.cpp @@ -49,10 +49,11 @@ std::string Object::toString( ) const { yulAssert(hasCode(), "No code"); + yulAssert(dialect(), "No dialect"); yulAssert(debugData, "No debug data"); std::string inner = "code " + AsmPrinter( - m_dialect, + *dialect(), debugData->sourceNames, _debugInfoSelection, _soliditySourceProvider @@ -94,10 +95,11 @@ std::string ObjectDebugData::formatUseSrcComment() const Json Object::toJson() const { yulAssert(hasCode(), "No code"); + yulAssert(dialect(), "No dialect"); Json codeJson; codeJson["nodeType"] = "YulCode"; - codeJson["block"] = AsmJsonConverter(m_dialect, 0 /* sourceIndex */)(code()->root()); + codeJson["block"] = AsmJsonConverter(*dialect(), 0 /* sourceIndex */)(code()->root()); Json subObjectsJson = Json::array(); for (std::shared_ptr const& subObject: subObjects) @@ -240,3 +242,10 @@ bool Object::hasContiguousSourceIndices() const solAssert(maxSourceIndex + 1 >= indices.size()); return indices.size() == 0 || indices.size() == maxSourceIndex + 1; } + +Dialect const* Object::dialect() const +{ + if (!m_code) + return nullptr; + return &m_code->dialect(); +} diff --git a/libyul/Object.h b/libyul/Object.h index 2109b69ae7ee..295c4a87c786 100644 --- a/libyul/Object.h +++ b/libyul/Object.h @@ -21,8 +21,8 @@ #pragma once -#include #include +#include #include #include @@ -91,7 +91,6 @@ struct ObjectDebugData class Object: public ObjectNode { public: - explicit Object(Dialect const& _dialect): m_dialect(_dialect) {} /// @returns a (parseable) string representation. std::string toString( langutil::DebugInfoSelection const& _debugInfoSelection = langutil::DebugInfoSelection::Default(), @@ -162,10 +161,9 @@ class Object: public ObjectNode /// @returns the name of the special metadata data object. static std::string metadataName() { return ".metadata"; } - Dialect const& dialect() const { return m_dialect; } + Dialect const* dialect() const; private: - Dialect const& m_dialect; std::shared_ptr m_code; }; diff --git a/libyul/ObjectOptimizer.cpp b/libyul/ObjectOptimizer.cpp index 6a6354f94b36..d7c1526cb587 100644 --- a/libyul/ObjectOptimizer.cpp +++ b/libyul/ObjectOptimizer.cpp @@ -118,12 +118,12 @@ void ObjectOptimizer::overwriteWithOptimizedObject(util::h256 _cacheKey, Object& CachedObject const& cachedObject = m_cachedObjects.at(_cacheKey); yulAssert(cachedObject.optimizedAST); - _object.setCode(std::make_shared(ASTCopier{}.translate(*cachedObject.optimizedAST))); + yulAssert(cachedObject.dialect); + _object.setCode(std::make_shared(*cachedObject.dialect, ASTCopier{}.translate(*cachedObject.optimizedAST))); yulAssert(_object.code()); // There's no point in caching AnalysisInfo because it references AST nodes. It can't be shared // by multiple ASTs and it's easier to recalculate it than properly clone it. - yulAssert(cachedObject.dialect); _object.analysisInfo = std::make_shared( AsmAnalyzer::analyzeStrictAssertCorrect( *cachedObject.dialect, diff --git a/libyul/ObjectParser.cpp b/libyul/ObjectParser.cpp index 67f5b70dd003..123dedcb483d 100644 --- a/libyul/ObjectParser.cpp +++ b/libyul/ObjectParser.cpp @@ -49,7 +49,7 @@ std::shared_ptr ObjectParser::parse(std::shared_ptr const& _sca if (currentToken() == Token::LBrace) { // Special case: Code-only form. - object = std::make_shared(m_dialect); + object = std::make_shared(); object->name = "object"; auto sourceNameMapping = tryParseSourceNameMapping(); object->debugData = std::make_shared(ObjectDebugData{sourceNameMapping}); @@ -74,7 +74,7 @@ std::shared_ptr ObjectParser::parseObject(Object* _containingObject) { RecursionGuard guard(*this); - std::shared_ptr ret = std::make_shared(m_dialect); + std::shared_ptr ret = std::make_shared(); auto sourceNameMapping = tryParseSourceNameMapping(); ret->debugData = std::make_shared(ObjectDebugData{sourceNameMapping}); diff --git a/libyul/optimiser/StackCompressor.cpp b/libyul/optimiser/StackCompressor.cpp index 71a0463c9b17..686fb6695e89 100644 --- a/libyul/optimiser/StackCompressor.cpp +++ b/libyul/optimiser/StackCompressor.cpp @@ -243,6 +243,7 @@ std::tuple StackCompressor::run( size_t _maxIterations) { yulAssert(_object.hasCode()); + yulAssert(_object.dialect(), "No dialect"); yulAssert( !_object.code()->root().statements.empty() && std::holds_alternative(_object.code()->root().statements.at(0)), "Need to run the function grouper before the stack compressor." @@ -279,7 +280,7 @@ std::tuple StackCompressor::run( for (size_t iterations = 0; iterations < _maxIterations; iterations++) { Object object(_object); - object.setCode(std::make_shared(std::get(ASTCopier{}(astRoot)))); + object.setCode(std::make_shared(*_object.dialect(), std::get(ASTCopier{}(astRoot)))); std::map stackSurplus = CompilabilityChecker(_dialect, object, _optimizeStackAllocation).stackDeficit; if (stackSurplus.empty()) return std::make_tuple(true, std::move(astRoot)); diff --git a/libyul/optimiser/Suite.cpp b/libyul/optimiser/Suite.cpp index c6b5f8cfc63c..0bef31472e49 100644 --- a/libyul/optimiser/Suite.cpp +++ b/libyul/optimiser/Suite.cpp @@ -138,7 +138,7 @@ void OptimiserSuite::run( if (!usesOptimizedCodeGenerator) { PROFILER_PROBE("StackCompressor", probe); - _object.setCode(std::make_shared(std::move(astRoot))); + _object.setCode(std::make_shared(_dialect, std::move(astRoot))); astRoot = std::get<1>(StackCompressor::run( _dialect, _object, @@ -165,7 +165,7 @@ void OptimiserSuite::run( { { PROFILER_PROBE("StackCompressor", probe); - _object.setCode(std::make_shared(std::move(astRoot))); + _object.setCode(std::make_shared(_dialect, std::move(astRoot))); astRoot = std::get<1>(StackCompressor::run( _dialect, _object, @@ -176,14 +176,14 @@ void OptimiserSuite::run( if (evmDialect->providesObjectAccess()) { PROFILER_PROBE("StackLimitEvader", probe); - _object.setCode(std::make_shared(std::move(astRoot))); + _object.setCode(std::make_shared(_dialect, std::move(astRoot))); astRoot = StackLimitEvader::run(suite.m_context, _object); } } else if (evmDialect->providesObjectAccess() && _optimizeStackAllocation) { PROFILER_PROBE("StackLimitEvader", probe); - _object.setCode(std::make_shared(std::move(astRoot))); + _object.setCode(std::make_shared(_dialect, std::move(astRoot))); astRoot = StackLimitEvader::run(suite.m_context, _object); } } @@ -198,7 +198,7 @@ void OptimiserSuite::run( VarNameCleaner::run(suite.m_context, astRoot); } - _object.setCode(std::make_shared(std::move(astRoot))); + _object.setCode(std::make_shared(_dialect, std::move(astRoot))); _object.analysisInfo = std::make_shared(AsmAnalyzer::analyzeStrictAssertCorrect(_dialect, _object)); } diff --git a/test/libyul/CompilabilityChecker.cpp b/test/libyul/CompilabilityChecker.cpp index 9691efa216b4..daa8f61aa81b 100644 --- a/test/libyul/CompilabilityChecker.cpp +++ b/test/libyul/CompilabilityChecker.cpp @@ -38,10 +38,11 @@ std::string check(std::string const& _input) solidity::test::CommonOptions::get().evmVersion(), solidity::test::CommonOptions::get().eofVersion() ); - Object obj{dialect}; + Object obj; auto parsingResult = yul::test::parse(_input); obj.setCode(parsingResult.first, parsingResult.second); BOOST_REQUIRE(obj.hasCode()); + BOOST_REQUIRE(obj.dialect()); auto functions = CompilabilityChecker(dialect, obj, true).stackDeficit; std::string out; for (auto const& function: functions) diff --git a/test/libyul/ControlFlowSideEffectsTest.cpp b/test/libyul/ControlFlowSideEffectsTest.cpp index 799f64ce7948..3dc576c8ed20 100644 --- a/test/libyul/ControlFlowSideEffectsTest.cpp +++ b/test/libyul/ControlFlowSideEffectsTest.cpp @@ -60,7 +60,7 @@ TestCase::TestResult ControlFlowSideEffectsTest::run(std::ostream& _stream, std: solidity::test::CommonOptions::get().evmVersion(), solidity::test::CommonOptions::get().eofVersion() ); - Object obj{dialect}; + Object obj; auto parsingResult = yul::test::parse(m_source); obj.setCode(parsingResult.first, parsingResult.second); if (!obj.hasCode()) diff --git a/test/libyul/FunctionSideEffects.cpp b/test/libyul/FunctionSideEffects.cpp index bd9a9da07918..46a7c99fea51 100644 --- a/test/libyul/FunctionSideEffects.cpp +++ b/test/libyul/FunctionSideEffects.cpp @@ -86,7 +86,7 @@ TestCase::TestResult FunctionSideEffects::run(std::ostream& _stream, std::string solidity::test::CommonOptions::get().evmVersion(), solidity::test::CommonOptions::get().eofVersion() ); - Object obj{dialect}; + Object obj; auto parsingResult = yul::test::parse(m_source); obj.setCode(parsingResult.first, parsingResult.second); if (!obj.hasCode()) diff --git a/test/libyul/KnowledgeBaseTest.cpp b/test/libyul/KnowledgeBaseTest.cpp index 253e7e0d5ae0..0e7d411a3d3d 100644 --- a/test/libyul/KnowledgeBaseTest.cpp +++ b/test/libyul/KnowledgeBaseTest.cpp @@ -59,7 +59,7 @@ class KnowledgeBaseTest for (auto const& [name, expression]: m_ssaValues.values()) m_values[name].value = expression; - m_object->setCode(std::make_shared(std::move(astRoot))); + m_object->setCode(std::make_shared(m_dialect, std::move(astRoot))); return KnowledgeBase([this](YulName _var) { return util::valueOrNullptr(m_values, _var); }); } diff --git a/test/libyul/YulOptimizerTest.cpp b/test/libyul/YulOptimizerTest.cpp index c17beb84d5c8..ad7485aeae15 100644 --- a/test/libyul/YulOptimizerTest.cpp +++ b/test/libyul/YulOptimizerTest.cpp @@ -84,8 +84,9 @@ TestCase::TestResult YulOptimizerTest::run(std::ostream& _stream, std::string co } auto optimizedObject = tester.optimizedObject(); std::string printedOptimizedObject; + soltestAssert(optimizedObject->dialect()); if (optimizedObject->subObjects.empty()) - printedOptimizedObject = AsmPrinter{optimizedObject->dialect()}(optimizedObject->code()->root()); + printedOptimizedObject = AsmPrinter{*optimizedObject->dialect()}(optimizedObject->code()->root()); else printedOptimizedObject = optimizedObject->toString(); diff --git a/test/libyul/YulOptimizerTestCommon.cpp b/test/libyul/YulOptimizerTestCommon.cpp index 0f94f309dce4..9b8d2073cdcd 100644 --- a/test/libyul/YulOptimizerTestCommon.cpp +++ b/test/libyul/YulOptimizerTestCommon.cpp @@ -410,7 +410,7 @@ YulOptimizerTestCommon::YulOptimizerTestCommon( size_t maxIterations = 16; { Object object(*m_optimizedObject); - object.setCode(std::make_shared(std::get(ASTCopier{}(block)))); + object.setCode(std::make_shared(*m_dialect, std::get(ASTCopier{}(block)))); block = std::get<1>(StackCompressor::run(*m_dialect, object, true, maxIterations)); } BlockFlattener::run(*m_context, block); @@ -433,7 +433,7 @@ YulOptimizerTestCommon::YulOptimizerTestCommon( auto block = disambiguate(); updateContext(block); Object object(*m_optimizedObject); - object.setCode(std::make_shared(std::get(ASTCopier{}(block)))); + object.setCode(std::make_shared(*m_dialect, std::get(ASTCopier{}(block)))); auto const unreachables = CompilabilityChecker{ *m_dialect, object, @@ -500,7 +500,7 @@ bool YulOptimizerTestCommon::runStep() if (m_namedSteps.count(m_optimizerStep)) { auto block = m_namedSteps[m_optimizerStep](); - m_optimizedObject->setCode(std::make_shared(std::move(block))); + m_optimizedObject->setCode(std::make_shared(*m_dialect, std::move(block))); } else return false; diff --git a/test/tools/yulopti.cpp b/test/tools/yulopti.cpp index 3221dce8c699..5b634de36232 100644 --- a/test/tools/yulopti.cpp +++ b/test/tools/yulopti.cpp @@ -217,8 +217,8 @@ class YulOpti break; case ';': { - Object obj{m_dialect}; - obj.setCode(std::make_shared(std::get(ASTCopier{}(*m_astRoot)))); + Object obj; + obj.setCode(std::make_shared(m_dialect, std::get(ASTCopier{}(*m_astRoot)))); *m_astRoot = std::get<1>(StackCompressor::run(m_dialect, obj, true, 16)); break; } diff --git a/tools/yulPhaser/Program.cpp b/tools/yulPhaser/Program.cpp index 25cc8c5505f5..9e16826d9c7e 100644 --- a/tools/yulPhaser/Program.cpp +++ b/tools/yulPhaser/Program.cpp @@ -59,7 +59,7 @@ std::ostream& operator<<(std::ostream& _stream, Program const& _program); } Program::Program(Program const& program): - m_ast(std::make_unique(std::get(ASTCopier{}(program.m_ast->root())))), + m_ast(std::make_unique(program.m_dialect, std::get(ASTCopier{}(program.m_ast->root())))), m_dialect{program.m_dialect}, m_nameDispenser(program.m_nameDispenser) { @@ -150,7 +150,7 @@ std::variant, ErrorList> Program::parseObject(Dialect const // The public API of the class does not provide access to the smart pointer so it won't be hard // to switch to shared_ptr if the copying turns out to be an issue (though it would be better // to refactor ObjectParser and Object to use unique_ptr instead). - auto astCopy = std::make_unique(std::get(ASTCopier{}(selectedObject->code()->root()))); + auto astCopy = std::make_unique(_dialect, std::get(ASTCopier{}(selectedObject->code()->root()))); return std::variant, ErrorList>(std::move(astCopy)); } @@ -179,7 +179,7 @@ std::unique_ptr Program::disambiguateAST( std::set const externallyUsedIdentifiers = {}; Disambiguator disambiguator(_dialect, _analysisInfo, externallyUsedIdentifiers); - return std::make_unique(std::get(disambiguator(_ast.root()))); + return std::make_unique(_dialect, std::get(disambiguator(_ast.root()))); } std::unique_ptr Program::applyOptimisationSteps( @@ -203,7 +203,7 @@ std::unique_ptr Program::applyOptimisationSteps( for (std::string const& step: _optimisationSteps) OptimiserSuite::allSteps().at(step)->run(context, astRoot); - return std::make_unique(std::move(astRoot)); + return std::make_unique(_dialect, std::move(astRoot)); } size_t Program::computeCodeSize(Block const& _ast, CodeWeights const& _weights) From aee13b208afcd18cf39eb09bb6b5bd63fc956747 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Thu, 31 Oct 2024 16:26:13 +0100 Subject: [PATCH 0598/1022] Yul: add static format method to AsmPrinter --- libsolidity/codegen/CompilerContext.cpp | 16 +++++++--------- libyul/AsmPrinter.cpp | 10 ++++++++++ libyul/AsmPrinter.h | 9 ++++++++- libyul/Object.cpp | 6 +++--- test/libyul/Common.cpp | 7 +------ test/libyul/YulOptimizerTest.cpp | 2 +- tools/yulPhaser/Program.cpp | 2 +- 7 files changed, 31 insertions(+), 21 deletions(-) diff --git a/libsolidity/codegen/CompilerContext.cpp b/libsolidity/codegen/CompilerContext.cpp index c09b33a0081e..5c859f54f872 100644 --- a/libsolidity/codegen/CompilerContext.cpp +++ b/libsolidity/codegen/CompilerContext.cpp @@ -444,7 +444,7 @@ void CompilerContext::appendInlineAssembly( yul::Parser(errorReporter, dialect, std::move(locationOverride)) .parse(charStream); #ifdef SOL_OUTPUT_ASM - cout << yul::AsmPrinter(&dialect)(*parserResult) << endl; + std::cout << yul::AsmPrinter::format(*parserResult) << std::endl; #endif auto reportError = [&](std::string const& _context) @@ -491,9 +491,7 @@ void CompilerContext::appendInlineAssembly( { // Store as generated sources, but first re-parse to update the source references. solAssert(m_generatedYulUtilityCode.empty(), ""); - solAssert(obj.dialect()); - m_generatedYulUtilityCode = yul::AsmPrinter(*obj.dialect())(obj.code()->root()); - std::string code = yul::AsmPrinter{*obj.dialect()}(obj.code()->root()); + m_generatedYulUtilityCode = yul::AsmPrinter::format(*obj.code()); langutil::CharStream charStream(m_generatedYulUtilityCode, _sourceName); obj.setCode(yul::Parser(errorReporter, dialect).parse(charStream)); obj.analysisInfo = std::make_shared(yul::AsmAnalyzer::analyzeStrictAssertCorrect(dialect, obj)); @@ -503,8 +501,8 @@ void CompilerContext::appendInlineAssembly( toBeAssembledAST = obj.code(); #ifdef SOL_OUTPUT_ASM - cout << "After optimizer:" << endl; - cout << yul::AsmPrinter(&dialect)(*parserResult) << endl; + std::cout << "After optimizer:" << std::endl; + std::cout << yul::AsmPrinter::format(*parserResult) << std::endl; #endif } else if (_system) @@ -537,7 +535,7 @@ void CompilerContext::appendInlineAssembly( void CompilerContext::optimizeYul(yul::Object& _object, yul::EVMDialect const& _dialect, OptimiserSettings const& _optimiserSettings, std::set const& _externalIdentifiers) { #ifdef SOL_OUTPUT_ASM - cout << yul::AsmPrinter(*dialect)(*_object.code) << endl; + std::cout << yul::AsmPrinter::format(*_object.code()) << std::endl; #endif bool const isCreation = runtimeContext() != nullptr; @@ -554,8 +552,8 @@ void CompilerContext::optimizeYul(yul::Object& _object, yul::EVMDialect const& _ ); #ifdef SOL_OUTPUT_ASM - cout << "After optimizer:" << endl; - cout << yul::AsmPrinter(*dialect)(*object.code) << endl; + std::cout << "After optimizer:" << std::endl; + std::cout << yul::AsmPrinter::format(*_object.code()) << std::endl; #endif } diff --git a/libyul/AsmPrinter.cpp b/libyul/AsmPrinter.cpp index 5841fdfd3249..5ba19014995b 100644 --- a/libyul/AsmPrinter.cpp +++ b/libyul/AsmPrinter.cpp @@ -42,6 +42,16 @@ using namespace solidity::langutil; using namespace solidity::util; using namespace solidity::yul; +std::string AsmPrinter::format( + AST const& _ast, + std::optional>> const& _sourceIndexToName, + DebugInfoSelection const& _debugInfoSelection, + CharStreamProvider const* _soliditySourceProvider) +{ + return AsmPrinter{_ast.dialect(), _sourceIndexToName, _debugInfoSelection, _soliditySourceProvider}(_ast.root()); +} + + std::string AsmPrinter::operator()(Literal const& _literal) { yulAssert(validLiteral(_literal)); diff --git a/libyul/AsmPrinter.h b/libyul/AsmPrinter.h index 6eda13fcd83a..6b63c863883e 100644 --- a/libyul/AsmPrinter.h +++ b/libyul/AsmPrinter.h @@ -46,9 +46,16 @@ struct Dialect; class AsmPrinter { public: + static std::string format( + AST const& _ast, + std::optional>> const& _sourceIndexToName = {}, + langutil::DebugInfoSelection const& _debugInfoSelection = langutil::DebugInfoSelection::Default(), + langutil::CharStreamProvider const* _soliditySourceProvider = nullptr + ); + explicit AsmPrinter( Dialect const&, - std::optional>> _sourceIndexToName = {}, + std::optional>> const& _sourceIndexToName = {}, langutil::DebugInfoSelection const& _debugInfoSelection = langutil::DebugInfoSelection::Default(), langutil::CharStreamProvider const* _soliditySourceProvider = nullptr ): diff --git a/libyul/Object.cpp b/libyul/Object.cpp index 0dfa610d07ae..54ec6a3cfd7a 100644 --- a/libyul/Object.cpp +++ b/libyul/Object.cpp @@ -52,12 +52,12 @@ std::string Object::toString( yulAssert(dialect(), "No dialect"); yulAssert(debugData, "No debug data"); - std::string inner = "code " + AsmPrinter( - *dialect(), + std::string inner = "code " + AsmPrinter::format( + *code(), debugData->sourceNames, _debugInfoSelection, _soliditySourceProvider - )(code()->root()); + ); for (auto const& obj: subObjects) inner += "\n" + obj->toString(_debugInfoSelection, _soliditySourceProvider); diff --git a/test/libyul/Common.cpp b/test/libyul/Common.cpp index 10a55217ca59..32f60c8ebe6f 100644 --- a/test/libyul/Common.cpp +++ b/test/libyul/Common.cpp @@ -99,12 +99,7 @@ yul::Block yul::test::disambiguate(std::string const& _source) std::string yul::test::format(std::string const& _source) { - Dialect const& dialect = languageToDialect( - YulStack::Language::StrictAssembly, - solidity::test::CommonOptions::get().evmVersion(), - solidity::test::CommonOptions::get().eofVersion() - ); - return AsmPrinter(dialect)(parse(_source).first->root()); + return AsmPrinter::format(*parse(_source).first); } namespace diff --git a/test/libyul/YulOptimizerTest.cpp b/test/libyul/YulOptimizerTest.cpp index ad7485aeae15..dc05810bc672 100644 --- a/test/libyul/YulOptimizerTest.cpp +++ b/test/libyul/YulOptimizerTest.cpp @@ -86,7 +86,7 @@ TestCase::TestResult YulOptimizerTest::run(std::ostream& _stream, std::string co std::string printedOptimizedObject; soltestAssert(optimizedObject->dialect()); if (optimizedObject->subObjects.empty()) - printedOptimizedObject = AsmPrinter{*optimizedObject->dialect()}(optimizedObject->code()->root()); + printedOptimizedObject = AsmPrinter::format(*optimizedObject->code()); else printedOptimizedObject = optimizedObject->toString(); diff --git a/tools/yulPhaser/Program.cpp b/tools/yulPhaser/Program.cpp index 9e16826d9c7e..6d182782701e 100644 --- a/tools/yulPhaser/Program.cpp +++ b/tools/yulPhaser/Program.cpp @@ -106,7 +106,7 @@ void Program::optimise(std::vector const& _optimisationSteps) std::ostream& phaser::operator<<(std::ostream& _stream, Program const& _program) { - return _stream << AsmPrinter(_program.m_dialect)(_program.m_ast->root()); + return _stream << AsmPrinter::format(*_program.m_ast); } std::string Program::toJson() const From b7f676a98b1db778aacf1599f5571819bf523bbf Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Thu, 31 Oct 2024 17:01:33 +0100 Subject: [PATCH 0599/1022] Yul compiler context runs optimizeYul on dialect contained in object --- libsolidity/codegen/CompilerContext.cpp | 11 +++++++---- libsolidity/codegen/CompilerContext.h | 2 +- libsolidity/codegen/ContractCompiler.cpp | 2 +- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/libsolidity/codegen/CompilerContext.cpp b/libsolidity/codegen/CompilerContext.cpp index 5c859f54f872..25829d96a9f4 100644 --- a/libsolidity/codegen/CompilerContext.cpp +++ b/libsolidity/codegen/CompilerContext.cpp @@ -485,7 +485,7 @@ void CompilerContext::appendInlineAssembly( obj.setCode(parserResult, std::make_shared(analysisInfo)); solAssert(!dialect.providesObjectAccess()); - optimizeYul(obj, dialect, _optimiserSettings, externallyUsedIdentifiers); + optimizeYul(obj, _optimiserSettings, externallyUsedIdentifiers); if (_system) { @@ -532,16 +532,19 @@ void CompilerContext::appendInlineAssembly( } -void CompilerContext::optimizeYul(yul::Object& _object, yul::EVMDialect const& _dialect, OptimiserSettings const& _optimiserSettings, std::set const& _externalIdentifiers) +void CompilerContext::optimizeYul(yul::Object& _object, OptimiserSettings const& _optimiserSettings, std::set const& _externalIdentifiers) { + yulAssert(_object.dialect()); + auto const* evmDialect = dynamic_cast(_object.dialect()); + yulAssert(evmDialect); #ifdef SOL_OUTPUT_ASM std::cout << yul::AsmPrinter::format(*_object.code()) << std::endl; #endif bool const isCreation = runtimeContext() != nullptr; - yul::GasMeter meter(_dialect, isCreation, _optimiserSettings.expectedExecutionsPerDeployment); + yul::GasMeter meter(*evmDialect, isCreation, _optimiserSettings.expectedExecutionsPerDeployment); yul::OptimiserSuite::run( - _dialect, + *evmDialect, &meter, _object, _optimiserSettings.optimizeStackAllocation, diff --git a/libsolidity/codegen/CompilerContext.h b/libsolidity/codegen/CompilerContext.h index 3469ee7d278a..2805b8daf8d0 100644 --- a/libsolidity/codegen/CompilerContext.h +++ b/libsolidity/codegen/CompilerContext.h @@ -277,7 +277,7 @@ class CompilerContext /// Otherwise returns "revert(0, 0)". std::string revertReasonIfDebug(std::string const& _message = ""); - void optimizeYul(yul::Object& _object, yul::EVMDialect const& _dialect, OptimiserSettings const& _optimiserSetting, std::set const& _externalIdentifiers = {}); + void optimizeYul(yul::Object& _object, OptimiserSettings const& _optimiserSetting, std::set const& _externalIdentifiers = {}); /// Appends arbitrary data to the end of the bytecode. void appendToAuxiliaryData(bytes const& _data) { m_asm->appendToAuxiliaryData(_data); } diff --git a/libsolidity/codegen/ContractCompiler.cpp b/libsolidity/codegen/ContractCompiler.cpp index 3548d0ae7850..d7db52e7616a 100644 --- a/libsolidity/codegen/ContractCompiler.cpp +++ b/libsolidity/codegen/ContractCompiler.cpp @@ -947,7 +947,7 @@ bool ContractCompiler::visit(InlineAssembly const& _inlineAssembly) object.setCode(std::make_shared(_inlineAssembly.dialect(), yul::ASTCopier().translate(code->root()))); object.analysisInfo = std::make_shared(yul::AsmAnalyzer::analyzeStrictAssertCorrect(*dialect, object)); - m_context.optimizeYul(object, *dialect, m_optimiserSettings); + m_context.optimizeYul(object, m_optimiserSettings); code = object.code().get(); analysisInfo = object.analysisInfo.get(); From 34919223e25d51a4b4639d566e9b68276b7551e9 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Thu, 31 Oct 2024 17:09:30 +0100 Subject: [PATCH 0600/1022] AsmAnalysis: analyzeStrictAssertCorrect only on object --- libsolidity/codegen/CompilerContext.cpp | 2 +- libsolidity/codegen/ContractCompiler.cpp | 2 +- libyul/AsmAnalysis.cpp | 5 +++-- libyul/AsmAnalysis.h | 2 +- libyul/ObjectOptimizer.cpp | 2 +- libyul/optimiser/Suite.cpp | 2 +- test/libyul/SSAControlFlowGraphTest.cpp | 2 +- 7 files changed, 9 insertions(+), 8 deletions(-) diff --git a/libsolidity/codegen/CompilerContext.cpp b/libsolidity/codegen/CompilerContext.cpp index 25829d96a9f4..3cf713a942fe 100644 --- a/libsolidity/codegen/CompilerContext.cpp +++ b/libsolidity/codegen/CompilerContext.cpp @@ -494,7 +494,7 @@ void CompilerContext::appendInlineAssembly( m_generatedYulUtilityCode = yul::AsmPrinter::format(*obj.code()); langutil::CharStream charStream(m_generatedYulUtilityCode, _sourceName); obj.setCode(yul::Parser(errorReporter, dialect).parse(charStream)); - obj.analysisInfo = std::make_shared(yul::AsmAnalyzer::analyzeStrictAssertCorrect(dialect, obj)); + obj.analysisInfo = std::make_shared(yul::AsmAnalyzer::analyzeStrictAssertCorrect(obj)); } analysisInfo = std::move(*obj.analysisInfo); diff --git a/libsolidity/codegen/ContractCompiler.cpp b/libsolidity/codegen/ContractCompiler.cpp index d7db52e7616a..57a23fb803ce 100644 --- a/libsolidity/codegen/ContractCompiler.cpp +++ b/libsolidity/codegen/ContractCompiler.cpp @@ -945,7 +945,7 @@ bool ContractCompiler::visit(InlineAssembly const& _inlineAssembly) // Create a modifiable copy of the code and analysis object.setCode(std::make_shared(_inlineAssembly.dialect(), yul::ASTCopier().translate(code->root()))); - object.analysisInfo = std::make_shared(yul::AsmAnalyzer::analyzeStrictAssertCorrect(*dialect, object)); + object.analysisInfo = std::make_shared(yul::AsmAnalyzer::analyzeStrictAssertCorrect(object)); m_context.optimizeYul(object, m_optimiserSettings); diff --git a/libyul/AsmAnalysis.cpp b/libyul/AsmAnalysis.cpp index 491effe8e619..b00982faf882 100644 --- a/libyul/AsmAnalysis.cpp +++ b/libyul/AsmAnalysis.cpp @@ -86,9 +86,10 @@ bool AsmAnalyzer::analyze(Block const& _block) return watcher.ok(); } -AsmAnalysisInfo AsmAnalyzer::analyzeStrictAssertCorrect(Dialect const& _dialect, Object const& _object) +AsmAnalysisInfo AsmAnalyzer::analyzeStrictAssertCorrect(Object const& _object) { - return analyzeStrictAssertCorrect(_dialect, _object.code()->root(), _object.summarizeStructure()); + yulAssert(_object.dialect()); + return analyzeStrictAssertCorrect(*_object.dialect(), _object.code()->root(), _object.summarizeStructure()); } AsmAnalysisInfo AsmAnalyzer::analyzeStrictAssertCorrect( diff --git a/libyul/AsmAnalysis.h b/libyul/AsmAnalysis.h index 7673e375ad20..6235b530d16d 100644 --- a/libyul/AsmAnalysis.h +++ b/libyul/AsmAnalysis.h @@ -81,7 +81,7 @@ class AsmAnalyzer /// Performs analysis on the outermost code of the given object and returns the analysis info. /// Asserts on failure. - static AsmAnalysisInfo analyzeStrictAssertCorrect(Dialect const& _dialect, Object const& _object); + static AsmAnalysisInfo analyzeStrictAssertCorrect(Object const& _object); static AsmAnalysisInfo analyzeStrictAssertCorrect( Dialect const& _dialect, Block const& _astRoot, diff --git a/libyul/ObjectOptimizer.cpp b/libyul/ObjectOptimizer.cpp index d7c1526cb587..992c41b4d921 100644 --- a/libyul/ObjectOptimizer.cpp +++ b/libyul/ObjectOptimizer.cpp @@ -121,12 +121,12 @@ void ObjectOptimizer::overwriteWithOptimizedObject(util::h256 _cacheKey, Object& yulAssert(cachedObject.dialect); _object.setCode(std::make_shared(*cachedObject.dialect, ASTCopier{}.translate(*cachedObject.optimizedAST))); yulAssert(_object.code()); + yulAssert(_object.dialect()); // There's no point in caching AnalysisInfo because it references AST nodes. It can't be shared // by multiple ASTs and it's easier to recalculate it than properly clone it. _object.analysisInfo = std::make_shared( AsmAnalyzer::analyzeStrictAssertCorrect( - *cachedObject.dialect, _object ) ); diff --git a/libyul/optimiser/Suite.cpp b/libyul/optimiser/Suite.cpp index 0bef31472e49..a9c5b0f2a05b 100644 --- a/libyul/optimiser/Suite.cpp +++ b/libyul/optimiser/Suite.cpp @@ -199,7 +199,7 @@ void OptimiserSuite::run( } _object.setCode(std::make_shared(_dialect, std::move(astRoot))); - _object.analysisInfo = std::make_shared(AsmAnalyzer::analyzeStrictAssertCorrect(_dialect, _object)); + _object.analysisInfo = std::make_shared(AsmAnalyzer::analyzeStrictAssertCorrect(_object)); } namespace diff --git a/test/libyul/SSAControlFlowGraphTest.cpp b/test/libyul/SSAControlFlowGraphTest.cpp index 5f0c79da534d..ad825cdf5073 100644 --- a/test/libyul/SSAControlFlowGraphTest.cpp +++ b/test/libyul/SSAControlFlowGraphTest.cpp @@ -66,7 +66,7 @@ TestCase::TestResult SSAControlFlowGraphTest::run(std::ostream& _stream, std::st return TestResult::FatalError; } - auto info = AsmAnalyzer::analyzeStrictAssertCorrect(*m_dialect, *object); + auto info = AsmAnalyzer::analyzeStrictAssertCorrect(*object); std::unique_ptr controlFlow = SSAControlFlowGraphBuilder::build( info, *m_dialect, From c8fa1cd8a2ff1d01b8f9121571f87a722df953bd Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Thu, 31 Oct 2024 17:18:29 +0100 Subject: [PATCH 0601/1022] Yul Semantics: containsMSize only on object --- libyul/YulStack.cpp | 4 ++-- libyul/optimiser/Semantics.cpp | 7 ++++--- libyul/optimiser/Semantics.h | 2 +- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/libyul/YulStack.cpp b/libyul/YulStack.cpp index 877e447c78db..a7bf415a5aa4 100644 --- a/libyul/YulStack.cpp +++ b/libyul/YulStack.cpp @@ -94,7 +94,7 @@ void YulStack::optimize() { if ( !m_optimiserSettings.runYulOptimiser && - yul::MSizeFinder::containsMSize(languageToDialect(m_language, m_evmVersion, m_eofVersion), *m_parserResult) + yul::MSizeFinder::containsMSize(*m_parserResult) ) return; @@ -317,7 +317,7 @@ YulStack::assembleEVMWithDeployed(std::optional _deployName) // it with the minimal steps required to avoid "stack too deep". bool optimize = m_optimiserSettings.optimizeStackAllocation || ( !m_optimiserSettings.runYulOptimiser && - !yul::MSizeFinder::containsMSize(languageToDialect(m_language, m_evmVersion, m_eofVersion), *m_parserResult) + !yul::MSizeFinder::containsMSize(*m_parserResult) ); try { diff --git a/libyul/optimiser/Semantics.cpp b/libyul/optimiser/Semantics.cpp index 5b5ad0eee197..1698ac5eef7a 100644 --- a/libyul/optimiser/Semantics.cpp +++ b/libyul/optimiser/Semantics.cpp @@ -93,14 +93,15 @@ bool MSizeFinder::containsMSize(Dialect const& _dialect, Block const& _ast) return finder.m_msizeFound; } -bool MSizeFinder::containsMSize(Dialect const& _dialect, Object const& _object) +bool MSizeFinder::containsMSize(Object const& _object) { - if (containsMSize(_dialect, _object.code()->root())) + yulAssert(_object.dialect()); + if (containsMSize(*_object.dialect(), _object.code()->root())) return true; for (std::shared_ptr const& node: _object.subObjects) if (auto const* object = dynamic_cast(node.get())) - if (containsMSize(_dialect, *object)) + if (containsMSize(*object)) return true; return false; diff --git a/libyul/optimiser/Semantics.h b/libyul/optimiser/Semantics.h index 1d0018897c00..e97fbd0c31a5 100644 --- a/libyul/optimiser/Semantics.h +++ b/libyul/optimiser/Semantics.h @@ -149,7 +149,7 @@ class MSizeFinder: public ASTWalker { public: static bool containsMSize(Dialect const& _dialect, Block const& _ast); - static bool containsMSize(Dialect const& _dialect, Object const& _object); + static bool containsMSize(Object const& _object); using ASTWalker::operator(); void operator()(FunctionCall const& _funCall) override; From 5168861695fab4986f9a1450e61c50897e6baf0f Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Thu, 31 Oct 2024 17:25:55 +0100 Subject: [PATCH 0602/1022] Run Yul stack compressor only on object --- libyul/optimiser/StackCompressor.cpp | 15 +++++++-------- libyul/optimiser/StackCompressor.h | 1 - libyul/optimiser/Suite.cpp | 2 -- test/libyul/YulOptimizerTestCommon.cpp | 2 +- test/tools/yulopti.cpp | 2 +- 5 files changed, 9 insertions(+), 13 deletions(-) diff --git a/libyul/optimiser/StackCompressor.cpp b/libyul/optimiser/StackCompressor.cpp index 686fb6695e89..a421a2d024e2 100644 --- a/libyul/optimiser/StackCompressor.cpp +++ b/libyul/optimiser/StackCompressor.cpp @@ -237,7 +237,6 @@ void eliminateVariablesOptimizedCodegen( } std::tuple StackCompressor::run( - Dialect const& _dialect, Object const& _object, bool _optimizeStackAllocation, size_t _maxIterations) @@ -250,7 +249,7 @@ std::tuple StackCompressor::run( ); bool usesOptimizedCodeGenerator = false; bool simulateFunctionsWithJumps = true; - if (auto evmDialect = dynamic_cast(&_dialect)) + if (auto evmDialect = dynamic_cast(_object.dialect())) { usesOptimizedCodeGenerator = _optimizeStackAllocation && @@ -258,18 +257,18 @@ std::tuple StackCompressor::run( evmDialect->providesObjectAccess(); simulateFunctionsWithJumps = !evmDialect->eofVersion().has_value(); } - bool allowMSizeOptimization = !MSizeFinder::containsMSize(_dialect, _object.code()->root()); + bool allowMSizeOptimization = !MSizeFinder::containsMSize(*_object.dialect(), _object.code()->root()); Block astRoot = std::get(ASTCopier{}(_object.code()->root())); if (usesOptimizedCodeGenerator) { yul::AsmAnalysisInfo analysisInfo = yul::AsmAnalyzer::analyzeStrictAssertCorrect( - _dialect, + *_object.dialect(), astRoot, _object.summarizeStructure() ); - std::unique_ptr cfg = ControlFlowGraphBuilder::build(analysisInfo, _dialect, astRoot); + std::unique_ptr cfg = ControlFlowGraphBuilder::build(analysisInfo, *_object.dialect(), astRoot); eliminateVariablesOptimizedCodegen( - _dialect, + *_object.dialect(), astRoot, StackLayoutGenerator::reportStackTooDeep(*cfg, simulateFunctionsWithJumps), allowMSizeOptimization @@ -281,11 +280,11 @@ std::tuple StackCompressor::run( { Object object(_object); object.setCode(std::make_shared(*_object.dialect(), std::get(ASTCopier{}(astRoot)))); - std::map stackSurplus = CompilabilityChecker(_dialect, object, _optimizeStackAllocation).stackDeficit; + std::map stackSurplus = CompilabilityChecker(*object.dialect(), object, _optimizeStackAllocation).stackDeficit; if (stackSurplus.empty()) return std::make_tuple(true, std::move(astRoot)); eliminateVariables( - _dialect, + *object.dialect(), astRoot, stackSurplus, allowMSizeOptimization diff --git a/libyul/optimiser/StackCompressor.h b/libyul/optimiser/StackCompressor.h index 70c020b9cee3..b0b086a7e2b0 100644 --- a/libyul/optimiser/StackCompressor.h +++ b/libyul/optimiser/StackCompressor.h @@ -47,7 +47,6 @@ class StackCompressor /// Try to remove local variables until the AST is compilable. /// @returns tuple with true if it was successful as first element, second element is the modified AST. static std::tuple run( - Dialect const& _dialect, Object const& _object, bool _optimizeStackAllocation, size_t _maxIterations diff --git a/libyul/optimiser/Suite.cpp b/libyul/optimiser/Suite.cpp index a9c5b0f2a05b..805dd9291017 100644 --- a/libyul/optimiser/Suite.cpp +++ b/libyul/optimiser/Suite.cpp @@ -140,7 +140,6 @@ void OptimiserSuite::run( PROFILER_PROBE("StackCompressor", probe); _object.setCode(std::make_shared(_dialect, std::move(astRoot))); astRoot = std::get<1>(StackCompressor::run( - _dialect, _object, _optimizeStackAllocation, stackCompressorMaxIterations @@ -167,7 +166,6 @@ void OptimiserSuite::run( PROFILER_PROBE("StackCompressor", probe); _object.setCode(std::make_shared(_dialect, std::move(astRoot))); astRoot = std::get<1>(StackCompressor::run( - _dialect, _object, _optimizeStackAllocation, stackCompressorMaxIterations diff --git a/test/libyul/YulOptimizerTestCommon.cpp b/test/libyul/YulOptimizerTestCommon.cpp index 9b8d2073cdcd..d75fbbe1598e 100644 --- a/test/libyul/YulOptimizerTestCommon.cpp +++ b/test/libyul/YulOptimizerTestCommon.cpp @@ -411,7 +411,7 @@ YulOptimizerTestCommon::YulOptimizerTestCommon( { Object object(*m_optimizedObject); object.setCode(std::make_shared(*m_dialect, std::get(ASTCopier{}(block)))); - block = std::get<1>(StackCompressor::run(*m_dialect, object, true, maxIterations)); + block = std::get<1>(StackCompressor::run(object, true, maxIterations)); } BlockFlattener::run(*m_context, block); return block; diff --git a/test/tools/yulopti.cpp b/test/tools/yulopti.cpp index 5b634de36232..b164bfb4f3d1 100644 --- a/test/tools/yulopti.cpp +++ b/test/tools/yulopti.cpp @@ -219,7 +219,7 @@ class YulOpti { Object obj; obj.setCode(std::make_shared(m_dialect, std::get(ASTCopier{}(*m_astRoot)))); - *m_astRoot = std::get<1>(StackCompressor::run(m_dialect, obj, true, 16)); + *m_astRoot = std::get<1>(StackCompressor::run(obj, true, 16)); break; } default: From a16833718d920354985ba621d1e95470071acccc Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Thu, 31 Oct 2024 17:29:16 +0100 Subject: [PATCH 0603/1022] Remove dialect from yul optimization suite run arguments --- libsolidity/codegen/CompilerContext.cpp | 1 - libyul/ObjectOptimizer.cpp | 1 - libyul/optimiser/Suite.cpp | 21 +++++++++++---------- libyul/optimiser/Suite.h | 1 - test/libyul/YulOptimizerTestCommon.cpp | 1 - 5 files changed, 11 insertions(+), 14 deletions(-) diff --git a/libsolidity/codegen/CompilerContext.cpp b/libsolidity/codegen/CompilerContext.cpp index 3cf713a942fe..4d53b9c234b9 100644 --- a/libsolidity/codegen/CompilerContext.cpp +++ b/libsolidity/codegen/CompilerContext.cpp @@ -544,7 +544,6 @@ void CompilerContext::optimizeYul(yul::Object& _object, OptimiserSettings const& bool const isCreation = runtimeContext() != nullptr; yul::GasMeter meter(*evmDialect, isCreation, _optimiserSettings.expectedExecutionsPerDeployment); yul::OptimiserSuite::run( - *evmDialect, &meter, _object, _optimiserSettings.optimizeStackAllocation, diff --git a/libyul/ObjectOptimizer.cpp b/libyul/ObjectOptimizer.cpp index 992c41b4d921..181cbaa8fe4e 100644 --- a/libyul/ObjectOptimizer.cpp +++ b/libyul/ObjectOptimizer.cpp @@ -90,7 +90,6 @@ void ObjectOptimizer::optimize(Object& _object, Settings const& _settings, bool } OptimiserSuite::run( - dialect, meter.get(), _object, _settings.optimizeStackAllocation, diff --git a/libyul/optimiser/Suite.cpp b/libyul/optimiser/Suite.cpp index 805dd9291017..766f96821b18 100644 --- a/libyul/optimiser/Suite.cpp +++ b/libyul/optimiser/Suite.cpp @@ -89,7 +89,6 @@ using namespace solidity::yul; using namespace std::string_literals; void OptimiserSuite::run( - Dialect const& _dialect, GasMeter const* _meter, Object& _object, bool _optimizeStackAllocation, @@ -99,7 +98,9 @@ void OptimiserSuite::run( std::set const& _externallyUsedIdentifiers ) { - EVMDialect const* evmDialect = dynamic_cast(&_dialect); + yulAssert(_object.dialect()); + auto const& dialect = *_object.dialect(); + EVMDialect const* evmDialect = dynamic_cast(_object.dialect()); bool usesOptimizedCodeGenerator = _optimizeStackAllocation && evmDialect && @@ -111,14 +112,14 @@ void OptimiserSuite::run( { PROFILER_PROBE("Disambiguator", probe); astRoot = std::get(Disambiguator( - _dialect, + dialect, *_object.analysisInfo, reservedIdentifiers )(_object.code()->root())); } - NameDispenser dispenser{_dialect, astRoot, reservedIdentifiers}; - OptimiserStepContext context{_dialect, dispenser, reservedIdentifiers, _expectedExecutionsPerDeployment}; + NameDispenser dispenser{dialect, astRoot, reservedIdentifiers}; + OptimiserStepContext context{dialect, dispenser, reservedIdentifiers, _expectedExecutionsPerDeployment}; OptimiserSuite suite(context, Debug::None); @@ -138,7 +139,7 @@ void OptimiserSuite::run( if (!usesOptimizedCodeGenerator) { PROFILER_PROBE("StackCompressor", probe); - _object.setCode(std::make_shared(_dialect, std::move(astRoot))); + _object.setCode(std::make_shared(dialect, std::move(astRoot))); astRoot = std::get<1>(StackCompressor::run( _object, _optimizeStackAllocation, @@ -164,7 +165,7 @@ void OptimiserSuite::run( { { PROFILER_PROBE("StackCompressor", probe); - _object.setCode(std::make_shared(_dialect, std::move(astRoot))); + _object.setCode(std::make_shared(dialect, std::move(astRoot))); astRoot = std::get<1>(StackCompressor::run( _object, _optimizeStackAllocation, @@ -174,14 +175,14 @@ void OptimiserSuite::run( if (evmDialect->providesObjectAccess()) { PROFILER_PROBE("StackLimitEvader", probe); - _object.setCode(std::make_shared(_dialect, std::move(astRoot))); + _object.setCode(std::make_shared(dialect, std::move(astRoot))); astRoot = StackLimitEvader::run(suite.m_context, _object); } } else if (evmDialect->providesObjectAccess() && _optimizeStackAllocation) { PROFILER_PROBE("StackLimitEvader", probe); - _object.setCode(std::make_shared(_dialect, std::move(astRoot))); + _object.setCode(std::make_shared(dialect, std::move(astRoot))); astRoot = StackLimitEvader::run(suite.m_context, _object); } } @@ -196,7 +197,7 @@ void OptimiserSuite::run( VarNameCleaner::run(suite.m_context, astRoot); } - _object.setCode(std::make_shared(_dialect, std::move(astRoot))); + _object.setCode(std::make_shared(dialect, std::move(astRoot))); _object.analysisInfo = std::make_shared(AsmAnalyzer::analyzeStrictAssertCorrect(_object)); } diff --git a/libyul/optimiser/Suite.h b/libyul/optimiser/Suite.h index e4eac31df505..bd3e1aa054e3 100644 --- a/libyul/optimiser/Suite.h +++ b/libyul/optimiser/Suite.h @@ -63,7 +63,6 @@ class OptimiserSuite /// The value nullopt for `_expectedExecutionsPerDeployment` represents creation code. static void run( - Dialect const& _dialect, GasMeter const* _meter, Object& _object, bool _optimizeStackAllocation, diff --git a/test/libyul/YulOptimizerTestCommon.cpp b/test/libyul/YulOptimizerTestCommon.cpp index d75fbbe1598e..a7452d0537fe 100644 --- a/test/libyul/YulOptimizerTestCommon.cpp +++ b/test/libyul/YulOptimizerTestCommon.cpp @@ -419,7 +419,6 @@ YulOptimizerTestCommon::YulOptimizerTestCommon( {"fullSuite", [&]() { GasMeter meter(dynamic_cast(*m_dialect), false, 200); OptimiserSuite::run( - *m_dialect, &meter, *m_optimizedObject, true, From 96e63ab08f6744aba273d590a5245d8e6979827a Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Thu, 31 Oct 2024 17:32:12 +0100 Subject: [PATCH 0604/1022] Remove dialect from yul compilability checker run arguments --- libyul/CompilabilityChecker.cpp | 3 +-- libyul/CompilabilityChecker.h | 1 - libyul/optimiser/StackCompressor.cpp | 2 +- libyul/optimiser/StackLimitEvader.cpp | 1 - test/libyul/CompilabilityChecker.cpp | 6 +----- test/libyul/YulOptimizerTestCommon.cpp | 1 - test/tools/ossfuzz/StackReuseCodegenFuzzer.cpp | 1 - 7 files changed, 3 insertions(+), 12 deletions(-) diff --git a/libyul/CompilabilityChecker.cpp b/libyul/CompilabilityChecker.cpp index 9cc6bd864320..cc46ecb77000 100644 --- a/libyul/CompilabilityChecker.cpp +++ b/libyul/CompilabilityChecker.cpp @@ -31,13 +31,12 @@ using namespace solidity::yul; using namespace solidity::util; CompilabilityChecker::CompilabilityChecker( - Dialect const& _dialect, Object const& _object, bool _optimizeStackAllocation ) { yulAssert(_object.hasCode()); - if (auto const* evmDialect = dynamic_cast(&_dialect)) + if (auto const* evmDialect = dynamic_cast(_object.dialect())) { NoOutputEVMDialect noOutputDialect(*evmDialect); diff --git a/libyul/CompilabilityChecker.h b/libyul/CompilabilityChecker.h index 160aeca8c783..1b7bf65a5b1b 100644 --- a/libyul/CompilabilityChecker.h +++ b/libyul/CompilabilityChecker.h @@ -45,7 +45,6 @@ namespace solidity::yul struct CompilabilityChecker { CompilabilityChecker( - Dialect const& _dialect, Object const& _object, bool _optimizeStackAllocation ); diff --git a/libyul/optimiser/StackCompressor.cpp b/libyul/optimiser/StackCompressor.cpp index a421a2d024e2..04b931a248e8 100644 --- a/libyul/optimiser/StackCompressor.cpp +++ b/libyul/optimiser/StackCompressor.cpp @@ -280,7 +280,7 @@ std::tuple StackCompressor::run( { Object object(_object); object.setCode(std::make_shared(*_object.dialect(), std::get(ASTCopier{}(astRoot)))); - std::map stackSurplus = CompilabilityChecker(*object.dialect(), object, _optimizeStackAllocation).stackDeficit; + std::map stackSurplus = CompilabilityChecker(object, _optimizeStackAllocation).stackDeficit; if (stackSurplus.empty()) return std::make_tuple(true, std::move(astRoot)); eliminateVariables( diff --git a/libyul/optimiser/StackLimitEvader.cpp b/libyul/optimiser/StackLimitEvader.cpp index 02c6de1594e3..2dc32d78759a 100644 --- a/libyul/optimiser/StackLimitEvader.cpp +++ b/libyul/optimiser/StackLimitEvader.cpp @@ -143,7 +143,6 @@ Block StackLimitEvader::run( else { run(_context, astRoot, CompilabilityChecker{ - _context.dialect, _object, true, }.unreachableVariables); diff --git a/test/libyul/CompilabilityChecker.cpp b/test/libyul/CompilabilityChecker.cpp index daa8f61aa81b..1956db84c6b7 100644 --- a/test/libyul/CompilabilityChecker.cpp +++ b/test/libyul/CompilabilityChecker.cpp @@ -34,16 +34,12 @@ namespace { std::string check(std::string const& _input) { - auto const& dialect = EVMDialect::strictAssemblyForEVM( - solidity::test::CommonOptions::get().evmVersion(), - solidity::test::CommonOptions::get().eofVersion() - ); Object obj; auto parsingResult = yul::test::parse(_input); obj.setCode(parsingResult.first, parsingResult.second); BOOST_REQUIRE(obj.hasCode()); BOOST_REQUIRE(obj.dialect()); - auto functions = CompilabilityChecker(dialect, obj, true).stackDeficit; + auto functions = CompilabilityChecker(obj, true).stackDeficit; std::string out; for (auto const& function: functions) out += function.first.str() + ": " + std::to_string(function.second) + " "; diff --git a/test/libyul/YulOptimizerTestCommon.cpp b/test/libyul/YulOptimizerTestCommon.cpp index a7452d0537fe..351d705cc517 100644 --- a/test/libyul/YulOptimizerTestCommon.cpp +++ b/test/libyul/YulOptimizerTestCommon.cpp @@ -434,7 +434,6 @@ YulOptimizerTestCommon::YulOptimizerTestCommon( Object object(*m_optimizedObject); object.setCode(std::make_shared(*m_dialect, std::get(ASTCopier{}(block)))); auto const unreachables = CompilabilityChecker{ - *m_dialect, object, true }.unreachableVariables; diff --git a/test/tools/ossfuzz/StackReuseCodegenFuzzer.cpp b/test/tools/ossfuzz/StackReuseCodegenFuzzer.cpp index 6f603e335d46..de2fdd28632a 100644 --- a/test/tools/ossfuzz/StackReuseCodegenFuzzer.cpp +++ b/test/tools/ossfuzz/StackReuseCodegenFuzzer.cpp @@ -56,7 +56,6 @@ bool recursiveFunctionExists(Dialect const& _dialect, yul::Object& _object) { auto recursiveFunctions = CallGraphGenerator::callGraph(_object.code()->root()).recursiveFunctions(); for(auto&& [function, variables]: CompilabilityChecker{ - _dialect, _object, true }.unreachableVariables From 6cec259deea1686e704a707386911e6920685d36 Mon Sep 17 00:00:00 2001 From: Martin Blicha Date: Wed, 30 Oct 2024 17:41:36 +0100 Subject: [PATCH 0605/1022] Run docker container as current user, not as root --- scripts/ci/build_emscripten.sh | 3 ++- scripts/ci/build_ossfuzz.sh | 2 +- scripts/ci/docker_upgrade.sh | 11 +++-------- 3 files changed, 6 insertions(+), 10 deletions(-) diff --git a/scripts/ci/build_emscripten.sh b/scripts/ci/build_emscripten.sh index 04e16293fd96..e4d25f195fb7 100755 --- a/scripts/ci/build_emscripten.sh +++ b/scripts/ci/build_emscripten.sh @@ -37,12 +37,13 @@ set -ev SCRIPT_DIR="$(realpath "$(dirname "$0")/..")" # shellcheck source=scripts/common.sh source "${SCRIPT_DIR}/common.sh" +ROOT_DIR="${SCRIPT_DIR}/.." function build() { local build_dir="$1" local prerelease_source="${2:-ci}" - cd /root/project + cd "${ROOT_DIR}" # shellcheck disable=SC2166 if [[ "$CIRCLE_BRANCH" = release || -n "$CIRCLE_TAG" || -n "$FORCE_RELEASE" || "$(git tag --points-at HEAD 2>/dev/null)" == v* ]] diff --git a/scripts/ci/build_ossfuzz.sh b/scripts/ci/build_ossfuzz.sh index 1240b6877f1a..c44f9bababf3 100755 --- a/scripts/ci/build_ossfuzz.sh +++ b/scripts/ci/build_ossfuzz.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash set -ex -ROOTDIR="/root/project" +ROOTDIR="$(realpath "$(dirname "$0")/../..")" BUILDDIR="${ROOTDIR}/build" mkdir -p "${BUILDDIR}" && mkdir -p "$BUILDDIR/deps" diff --git a/scripts/ci/docker_upgrade.sh b/scripts/ci/docker_upgrade.sh index a6b59e157e90..c2077239a5b6 100755 --- a/scripts/ci/docker_upgrade.sh +++ b/scripts/ci/docker_upgrade.sh @@ -51,17 +51,12 @@ docker build "scripts/docker/${IMAGE_NAME}" --file "scripts/docker/${IMAGE_NAME} echo "-- test_docker @ '${PWD}'" -# NOTE: Since /root/project/ is a dir from outside the container and the owner of the files is different, -# git show in the script refuses to work. It must be marked as safe to use first. -# See https://github.blog/2022-04-12-git-security-vulnerability-announced/ docker run \ --rm \ - --volume "${PWD}:/root/project" \ + --volume "${PWD}:/project" \ + -u "$(id -u "${USER}"):$(id -g "${USER}")" \ "${IMAGE_NAME}" \ - bash -c " - git config --global --add safe.directory /root/project && - /root/project/scripts/ci/${IMAGE_NAME}_test_${IMAGE_VARIANT}.sh - " + bash -c "/project/scripts/ci/${IMAGE_NAME}_test_${IMAGE_VARIANT}.sh" echo "-- push_docker" From 75ad2ea34db5582263ad0453dc233db21c462a9f Mon Sep 17 00:00:00 2001 From: Martin Blicha Date: Thu, 24 Oct 2024 15:03:03 +0200 Subject: [PATCH 0606/1022] Docker: Update Z3 and cvc5 versions --- .../buildpack-deps/Dockerfile.emscripten | 18 +++++------- .../buildpack-deps/Dockerfile.ubuntu2004 | 29 +++++++++++-------- .../buildpack-deps/Dockerfile.ubuntu2404 | 27 ++++++++++------- .../Dockerfile.ubuntu2404.clang | 29 +++++++++++-------- 4 files changed, 58 insertions(+), 45 deletions(-) diff --git a/scripts/docker/buildpack-deps/Dockerfile.emscripten b/scripts/docker/buildpack-deps/Dockerfile.emscripten index 478d8d947cf5..8bfb9c51a0dc 100644 --- a/scripts/docker/buildpack-deps/Dockerfile.emscripten +++ b/scripts/docker/buildpack-deps/Dockerfile.emscripten @@ -33,7 +33,7 @@ # Using $(em-config CACHE)/sysroot/usr seems to work, though, and still has cmake find the # dependencies automatically. FROM emscripten/emsdk:3.1.19 AS base -LABEL version="18" +LABEL version="19" ADD emscripten.jam /usr/src RUN set -ex && \ @@ -49,7 +49,7 @@ RUN set -ex && \ # Install Z3 RUN set -ex && \ cd /usr/src && \ - git clone https://github.com/Z3Prover/z3.git -b z3-4.12.1 --depth 1 && \ + git clone https://github.com/Z3Prover/z3.git -b z3-4.13.3 --depth 1 && \ cd z3 && \ mkdir build && \ cd build && \ @@ -86,11 +86,9 @@ RUN set -ex && \ # CVC5 RUN set -ex; \ - cvc5_version="1.1.2"; \ - wget "https://github.com/cvc5/cvc5/releases/download/cvc5-${cvc5_version}/cvc5-Linux-static.zip" -O /opt/cvc5.zip; \ - test "$(sha256sum /opt/cvc5.zip)" = "cf291aef67da8eaa8d425a51f67f3f72f36db8b1040655dc799b64e3d69e6086 /opt/cvc5.zip"; \ - unzip /opt/cvc5.zip -x "cvc5-Linux-static/lib/cmake/*" -d /opt; \ - mv /opt/cvc5-Linux-static/bin/* /usr/bin; \ - mv /opt/cvc5-Linux-static/include/* /usr/include; \ - mv /opt/cvc5-Linux-static/lib/* /usr/lib; \ - rm -rf /opt/cvc5-Linux-static /opt/cvc5.zip; + cvc5_version="1.2.0"; \ + cvc5_archive_name="cvc5-Linux-x86_64-static"; \ + wget "https://github.com/cvc5/cvc5/releases/download/cvc5-${cvc5_version}/${cvc5_archive_name}.zip" -O /opt/cvc5.zip; \ + test "$(sha256sum /opt/cvc5.zip)" = "d18f174ff9a11923c32c3f871f844ed16bd77a28f51050b8e7c8d821c98a1c2e /opt/cvc5.zip"; \ + unzip -j /opt/cvc5.zip "${cvc5_archive_name}/bin/cvc5" -d /usr/bin; \ + rm -f /opt/cvc5.zip; diff --git a/scripts/docker/buildpack-deps/Dockerfile.ubuntu2004 b/scripts/docker/buildpack-deps/Dockerfile.ubuntu2004 index 723192e2d0c4..7592f55ec55b 100644 --- a/scripts/docker/buildpack-deps/Dockerfile.ubuntu2004 +++ b/scripts/docker/buildpack-deps/Dockerfile.ubuntu2004 @@ -22,7 +22,7 @@ # (c) 2016-2019 solidity contributors. #------------------------------------------------------------------------------ FROM buildpack-deps:focal AS base -LABEL version="25" +LABEL version="26" ARG DEBIAN_FRONTEND=noninteractive @@ -39,15 +39,13 @@ RUN set -ex; \ libboost-program-options-dev \ libboost-system-dev \ libboost-test-dev \ - libz3-static-dev \ lsof \ ninja-build \ python3-pip \ python3-sphinx \ software-properties-common \ sudo \ - unzip \ - z3-static; \ + unzip; \ pip3 install \ codecov \ colorama \ @@ -76,14 +74,21 @@ RUN set -ex; \ # CVC5 RUN set -ex; \ - cvc5_version="1.1.2"; \ - wget "https://github.com/cvc5/cvc5/releases/download/cvc5-${cvc5_version}/cvc5-Linux-static.zip" -O /opt/cvc5.zip; \ - test "$(sha256sum /opt/cvc5.zip)" = "cf291aef67da8eaa8d425a51f67f3f72f36db8b1040655dc799b64e3d69e6086 /opt/cvc5.zip"; \ - unzip /opt/cvc5.zip -x "cvc5-Linux-static/lib/cmake/*" -d /opt; \ - mv /opt/cvc5-Linux-static/bin/* /usr/bin; \ - mv /opt/cvc5-Linux-static/include/* /usr/include; \ - mv /opt/cvc5-Linux-static/lib/* /usr/lib; \ - rm -rf /opt/cvc5-Linux-static /opt/cvc5.zip; + cvc5_version="1.2.0"; \ + cvc5_archive_name="cvc5-Linux-x86_64-static"; \ + wget "https://github.com/cvc5/cvc5/releases/download/cvc5-${cvc5_version}/${cvc5_archive_name}.zip" -O /opt/cvc5.zip; \ + test "$(sha256sum /opt/cvc5.zip)" = "d18f174ff9a11923c32c3f871f844ed16bd77a28f51050b8e7c8d821c98a1c2e /opt/cvc5.zip"; \ + unzip -j /opt/cvc5.zip "${cvc5_archive_name}/bin/cvc5" -d /usr/bin; \ + rm -f /opt/cvc5.zip; + +# Z3 +RUN set -ex; \ + z3_version="4.13.3"; \ + z3_archive_name="z3-${z3_version}-x64-glibc-2.35"; \ + wget "https://github.com/Z3Prover/z3/releases/download/z3-${z3_version}/${z3_archive_name}.zip" -O /opt/z3.zip; \ + test "$(sha256sum /opt/z3.zip)" = "32c7377026733c9d7b33c21cd77a68f50ba682367207b031a6bfd80140a8722f /opt/z3.zip"; \ + unzip -j /opt/z3.zip "${z3_archive_name}/bin/z3" -d /usr/bin; \ + rm -f /opt/z3.zip; FROM base AS libraries diff --git a/scripts/docker/buildpack-deps/Dockerfile.ubuntu2404 b/scripts/docker/buildpack-deps/Dockerfile.ubuntu2404 index c7ad4594aab8..eb5439f595be 100644 --- a/scripts/docker/buildpack-deps/Dockerfile.ubuntu2404 +++ b/scripts/docker/buildpack-deps/Dockerfile.ubuntu2404 @@ -22,7 +22,7 @@ # (c) 2016-2024 solidity contributors. #------------------------------------------------------------------------------ FROM buildpack-deps:noble AS base -LABEL version="1" +LABEL version="2" ARG DEBIAN_FRONTEND=noninteractive @@ -44,7 +44,6 @@ RUN set -ex; \ libboost-system-dev \ libboost-test-dev \ libcln-dev \ - libz3-static-dev \ locales-all \ lsof \ ninja-build \ @@ -53,7 +52,6 @@ RUN set -ex; \ software-properties-common \ sudo \ unzip \ - z3-static \ zip; \ pip3 install \ codecov \ @@ -79,14 +77,21 @@ RUN set -ex; \ # CVC5 RUN set -ex; \ - cvc5_version="1.1.2"; \ - wget "https://github.com/cvc5/cvc5/releases/download/cvc5-${cvc5_version}/cvc5-Linux-static.zip" -O /opt/cvc5.zip; \ - test "$(sha256sum /opt/cvc5.zip)" = "cf291aef67da8eaa8d425a51f67f3f72f36db8b1040655dc799b64e3d69e6086 /opt/cvc5.zip"; \ - unzip /opt/cvc5.zip -x "cvc5-Linux-static/lib/cmake/*" -d /opt; \ - mv /opt/cvc5-Linux-static/bin/* /usr/bin; \ - mv /opt/cvc5-Linux-static/include/* /usr/include; \ - mv /opt/cvc5-Linux-static/lib/* /usr/lib; \ - rm -rf /opt/cvc5-Linux-static /opt/cvc5.zip; + cvc5_version="1.2.0"; \ + cvc5_archive_name="cvc5-Linux-x86_64-static"; \ + wget "https://github.com/cvc5/cvc5/releases/download/cvc5-${cvc5_version}/${cvc5_archive_name}.zip" -O /opt/cvc5.zip; \ + test "$(sha256sum /opt/cvc5.zip)" = "d18f174ff9a11923c32c3f871f844ed16bd77a28f51050b8e7c8d821c98a1c2e /opt/cvc5.zip"; \ + unzip -j /opt/cvc5.zip "${cvc5_archive_name}/bin/cvc5" -d /usr/bin; \ + rm -f /opt/cvc5.zip; + +# Z3 +RUN set -ex; \ + z3_version="4.13.3"; \ + z3_archive_name="z3-${z3_version}-x64-glibc-2.35"; \ + wget "https://github.com/Z3Prover/z3/releases/download/z3-${z3_version}/${z3_archive_name}.zip" -O /opt/z3.zip; \ + test "$(sha256sum /opt/z3.zip)" = "32c7377026733c9d7b33c21cd77a68f50ba682367207b031a6bfd80140a8722f /opt/z3.zip"; \ + unzip -j /opt/z3.zip "${z3_archive_name}/bin/z3" -d /usr/bin; \ + rm -f /opt/z3.zip; FROM base AS libraries diff --git a/scripts/docker/buildpack-deps/Dockerfile.ubuntu2404.clang b/scripts/docker/buildpack-deps/Dockerfile.ubuntu2404.clang index 21092e312a7c..3b1e3e614d4e 100644 --- a/scripts/docker/buildpack-deps/Dockerfile.ubuntu2404.clang +++ b/scripts/docker/buildpack-deps/Dockerfile.ubuntu2404.clang @@ -22,7 +22,7 @@ # (c) 2016-2024 solidity contributors. #------------------------------------------------------------------------------ FROM buildpack-deps:noble AS base -LABEL version="2" +LABEL version="3" ARG DEBIAN_FRONTEND=noninteractive @@ -46,13 +46,11 @@ RUN set -ex; \ libboost-test-dev \ libclang-rt-dev \ libcln-dev \ - libz3-static-dev \ lsof \ ninja-build \ python3-pip \ software-properties-common \ - sudo \ - z3-static; \ + sudo; \ pip3 install \ codecov \ colorama \ @@ -78,14 +76,21 @@ RUN set -ex; \ # CVC5 RUN set -ex; \ - cvc5_version="1.1.2"; \ - wget "https://github.com/cvc5/cvc5/releases/download/cvc5-${cvc5_version}/cvc5-Linux-static.zip" -O /opt/cvc5.zip; \ - test "$(sha256sum /opt/cvc5.zip)" = "cf291aef67da8eaa8d425a51f67f3f72f36db8b1040655dc799b64e3d69e6086 /opt/cvc5.zip"; \ - unzip /opt/cvc5.zip -x "cvc5-Linux-static/lib/cmake/*" -d /opt; \ - mv /opt/cvc5-Linux-static/bin/* /usr/bin; \ - mv /opt/cvc5-Linux-static/lib/* /usr/lib; \ - mv /opt/cvc5-Linux-static/include/* /usr/include; \ - rm -rf /opt/cvc5-Linux-static /opt/cvc5.zip; + cvc5_version="1.2.0"; \ + cvc5_archive_name="cvc5-Linux-x86_64-static"; \ + wget "https://github.com/cvc5/cvc5/releases/download/cvc5-${cvc5_version}/${cvc5_archive_name}.zip" -O /opt/cvc5.zip; \ + test "$(sha256sum /opt/cvc5.zip)" = "d18f174ff9a11923c32c3f871f844ed16bd77a28f51050b8e7c8d821c98a1c2e /opt/cvc5.zip"; \ + unzip -j /opt/cvc5.zip "${cvc5_archive_name}/bin/cvc5" -d /usr/bin; \ + rm -f /opt/cvc5.zip; + +# Z3 +RUN set -ex; \ + z3_version="4.13.3"; \ + z3_archive_name="z3-${z3_version}-x64-glibc-2.35"; \ + wget "https://github.com/Z3Prover/z3/releases/download/z3-${z3_version}/${z3_archive_name}.zip" -O /opt/z3.zip; \ + test "$(sha256sum /opt/z3.zip)" = "32c7377026733c9d7b33c21cd77a68f50ba682367207b031a6bfd80140a8722f /opt/z3.zip"; \ + unzip -j /opt/z3.zip "${z3_archive_name}/bin/z3" -d /usr/bin; \ + rm -f /opt/z3.zip; FROM base AS libraries From 966fba572d57107d9a4eda263eeecad81168699a Mon Sep 17 00:00:00 2001 From: r0qs Date: Tue, 3 Dec 2024 14:35:41 +0700 Subject: [PATCH 0607/1022] Yul SSACFG JSON export fix: Export Yul SSA CFG of optimized IR --- libsolidity/interface/CompilerStack.cpp | 6 +- .../standard_yul_cfg_json_export/output.json | 4146 +++++------------ test/cmdlineTests/yul_cfg_json_export/output | 4146 +++++------------ 3 files changed, 2083 insertions(+), 6215 deletions(-) diff --git a/libsolidity/interface/CompilerStack.cpp b/libsolidity/interface/CompilerStack.cpp index f24fae3cd476..b90a30242727 100644 --- a/libsolidity/interface/CompilerStack.cpp +++ b/libsolidity/interface/CompilerStack.cpp @@ -999,10 +999,10 @@ std::optional CompilerStack::yulCFGJson(std::string const& _contractName) // keep it around when compiling a large project containing many contracts. Contract const& currentContract = contract(_contractName); yulAssert(currentContract.contract); - yulAssert(currentContract.yulIR.has_value() == currentContract.contract->canBeDeployed()); - if (!currentContract.yulIR) + yulAssert(currentContract.yulIROptimized.has_value() == currentContract.contract->canBeDeployed()); + if (!currentContract.yulIROptimized) return std::nullopt; - return loadGeneratedIR(*currentContract.yulIR).cfgJson(); + return loadGeneratedIR(*currentContract.yulIROptimized).cfgJson(); } std::optional const& CompilerStack::yulIROptimized(std::string const& _contractName) const diff --git a/test/cmdlineTests/standard_yul_cfg_json_export/output.json b/test/cmdlineTests/standard_yul_cfg_json_export/output.json index 8d3fc5b7e057..c224164c52ec 100644 --- a/test/cmdlineTests/standard_yul_cfg_json_export/output.json +++ b/test/cmdlineTests/standard_yul_cfg_json_export/output.json @@ -18,7 +18,7 @@ "instructions": [ { "builtinArgs": [ - "128" + "0x80" ], "in": [], "op": "memoryguard", @@ -50,18 +50,6 @@ }, "id": "Block2", "instructions": [ - { - "in": [], - "op": "constructor_C_19", - "out": [] - }, - { - "in": [], - "op": "allocate_unbounded", - "out": [ - "v3" - ] - }, { "builtinArgs": [ "C_19_deployed" @@ -86,25 +74,15 @@ "in": [ "v4", "v5", - "v3" + "v0" ], "op": "codecopy", "out": [] }, - { - "builtinArgs": [ - "C_19_deployed" - ], - "in": [], - "op": "datasize", - "out": [ - "v6" - ] - }, { "in": [ - "v6", - "v3" + "v4", + "v0" ], "op": "return", "out": [] @@ -119,109 +97,18 @@ "id": "Block1", "instructions": [ { - "in": [], - "op": "revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb", + "in": [ + "0x00", + "0x00" + ], + "op": "revert", "out": [] } ], - "type": "FunctionCall" + "type": "BuiltinCall" } ], - "functions": { - "allocate_unbounded": { - "arguments": [], - "blocks": [ - { - "exit": { - "returnValues": [ - "v2" - ], - "type": "FunctionReturn" - }, - "id": "Block0", - "instructions": [ - { - "in": [ - "0x40" - ], - "op": "mload", - "out": [ - "v2" - ] - } - ], - "type": "BuiltinCall" - } - ], - "entry": "Block0", - "numReturns": 1, - "type": "Function" - }, - "constructor_C_19": { - "arguments": [], - "blocks": [ - { - "exit": { - "returnValues": [], - "type": "FunctionReturn" - }, - "id": "Block0", - "instructions": [ - { - "in": [], - "op": "constructor_I_7", - "out": [] - } - ], - "type": "FunctionCall" - } - ], - "entry": "Block0", - "numReturns": 0, - "type": "Function" - }, - "constructor_I_7": { - "arguments": [], - "blocks": [ - { - "exit": { - "returnValues": [], - "type": "FunctionReturn" - }, - "id": "Block0", - "instructions": [] - } - ], - "entry": "Block0", - "numReturns": 0, - "type": "Function" - }, - "revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb": { - "arguments": [], - "blocks": [ - { - "exit": { - "type": "Terminated" - }, - "id": "Block0", - "instructions": [ - { - "in": [ - "0x00", - "0x00" - ], - "op": "revert", - "out": [] - } - ], - "type": "BuiltinCall" - } - ], - "entry": "Block0", - "numReturns": 0, - "type": "Function" - } - } + "functions": {} }, "subObjects": { "C_19_deployed": { @@ -239,7 +126,7 @@ "instructions": [ { "builtinArgs": [ - "128" + "0x80" ], "in": [], "op": "memoryguard", @@ -291,19 +178,22 @@ "id": "Block2", "instructions": [ { - "in": [], - "op": "revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74", + "in": [ + "0x00", + "0x00" + ], + "op": "revert", "out": [] } ], - "type": "FunctionCall" + "type": "BuiltinCall" }, { "exit": { - "cond": "v9", + "cond": "v11", "targets": [ - "Block5", - "Block4" + "Block4", + "Block3" ], "type": "ConditionalJump" }, @@ -320,21 +210,22 @@ }, { "in": [ - "v7" + "v7", + "0xe0" ], - "op": "shift_right_224_unsigned", + "op": "shr", "out": [ - "v8" + "v9" ] }, { "in": [ - "0x26121ff0", - "v8" + "v9", + "0x26121ff0" ], "op": "eq", "out": [ - "v9" + "v11" ] } ], @@ -343,604 +234,145 @@ { "exit": { "targets": [ - "Block3" + "Block2" ], "type": "Jump" }, - "id": "Block5", + "id": "Block4", "instructions": [] }, { "exit": { - "type": "Terminated" + "cond": "v12", + "targets": [ + "Block6", + "Block5" + ], + "type": "ConditionalJump" }, - "id": "Block4", + "id": "Block3", "instructions": [ { "in": [], - "op": "external_fun_f_18", - "out": [] + "op": "callvalue", + "out": [ + "v12" + ] } ], - "type": "FunctionCall" + "type": "BuiltinCall" }, { "exit": { + "cond": "v17", "targets": [ - "Block2" + "Block9", + "Block8" ], - "type": "Jump" + "type": "ConditionalJump" }, - "id": "Block3", - "instructions": [] - } - ], - "functions": { - "abi_decode_tuple_": { - "arguments": [ - "v0", - "v1" - ], - "blocks": [ + "id": "Block6", + "instructions": [ { - "exit": { - "cond": "v4", - "targets": [ - "Block2", - "Block1" - ], - "type": "ConditionalJump" - }, - "id": "Block0", - "instructions": [ - { - "in": [ - "v0", - "v1" - ], - "op": "sub", - "out": [ - "v3" - ] - }, - { - "in": [ - "0x00", - "v3" - ], - "op": "slt", - "out": [ - "v4" - ] - } + "in": [ + "0x03" ], - "type": "BuiltinCall" + "op": "not", + "out": [ + "v14" + ] }, { - "exit": { - "returnValues": [], - "type": "FunctionReturn" - }, - "id": "Block2", - "instructions": [] + "in": [], + "op": "calldatasize", + "out": [ + "v15" + ] }, { - "exit": { - "type": "Terminated" - }, - "id": "Block1", - "instructions": [ - { - "in": [], - "op": "revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b", - "out": [] - } + "in": [ + "v14", + "v15" + ], + "op": "add", + "out": [ + "v16" + ] + }, + { + "in": [ + "0x00", + "v16" ], - "type": "FunctionCall" + "op": "slt", + "out": [ + "v17" + ] } ], - "entry": "Block0", - "numReturns": 0, - "type": "Function" + "type": "BuiltinCall" }, - "abi_encode_t_uint256_to_t_uint256_fromStack": { - "arguments": [ - "v0", - "v1" - ], - "blocks": [ + { + "exit": { + "type": "Terminated" + }, + "id": "Block5", + "instructions": [ { - "exit": { - "returnValues": [], - "type": "FunctionReturn" - }, - "id": "Block0", - "instructions": [ - { - "in": [ - "v0" - ], - "op": "cleanup_t_uint256", - "out": [ - "v2" - ] - }, - { - "in": [ - "v2", - "v1" - ], - "op": "mstore", - "out": [] - } + "in": [ + "0x00", + "0x00" ], - "type": "BuiltinCall" + "op": "revert", + "out": [] } ], - "entry": "Block0", - "numReturns": 0, - "type": "Function" + "type": "BuiltinCall" }, - "abi_encode_tuple_t_uint256__to_t_uint256__fromStack": { - "arguments": [ - "v0", - "v1" - ], - "blocks": [ + { + "exit": { + "type": "Terminated" + }, + "id": "Block9", + "instructions": [ { - "exit": { - "returnValues": [ - "v4" - ], - "type": "FunctionReturn" - }, - "id": "Block0", - "instructions": [ - { - "in": [ - "0x20", - "v0" - ], - "op": "add", - "out": [ - "v4" - ] - }, - { - "in": [ - "0x00", - "v0" - ], - "op": "add", - "out": [ - "v5" - ] - }, - { - "in": [ - "v5", - "v1" - ], - "op": "abi_encode_t_uint256_to_t_uint256_fromStack", - "out": [] - } + "in": [ + "0x2a", + "v0" ], - "type": "FunctionCall" + "op": "mstore", + "out": [] + }, + { + "in": [ + "0x20", + "v0" + ], + "op": "return", + "out": [] } ], - "entry": "Block0", - "numReturns": 1, - "type": "Function" - }, - "allocate_unbounded": { - "arguments": [], - "blocks": [ - { - "exit": { - "returnValues": [ - "v2" - ], - "type": "FunctionReturn" - }, - "id": "Block0", - "instructions": [ - { - "in": [ - "0x40" - ], - "op": "mload", - "out": [ - "v2" - ] - } - ], - "type": "BuiltinCall" - } - ], - "entry": "Block0", - "numReturns": 1, - "type": "Function" - }, - "cleanup_t_rational_42_by_1": { - "arguments": [ - "v0" - ], - "blocks": [ - { - "exit": { - "returnValues": [ - "v0" - ], - "type": "FunctionReturn" - }, - "id": "Block0", - "instructions": [] - } - ], - "entry": "Block0", - "numReturns": 1, - "type": "Function" - }, - "cleanup_t_uint256": { - "arguments": [ - "v0" - ], - "blocks": [ - { - "exit": { - "returnValues": [ - "v0" - ], - "type": "FunctionReturn" - }, - "id": "Block0", - "instructions": [] - } - ], - "entry": "Block0", - "numReturns": 1, - "type": "Function" - }, - "convert_t_rational_42_by_1_to_t_uint256": { - "arguments": [ - "v0" - ], - "blocks": [ - { - "exit": { - "returnValues": [ - "v4" - ], - "type": "FunctionReturn" - }, - "id": "Block0", - "instructions": [ - { - "in": [ - "v0" - ], - "op": "cleanup_t_rational_42_by_1", - "out": [ - "v2" - ] - }, - { - "in": [ - "v2" - ], - "op": "identity", - "out": [ - "v3" - ] - }, - { - "in": [ - "v3" - ], - "op": "cleanup_t_uint256", - "out": [ - "v4" - ] - } - ], - "type": "FunctionCall" - } - ], - "entry": "Block0", - "numReturns": 1, - "type": "Function" - }, - "external_fun_f_18": { - "arguments": [], - "blocks": [ - { - "exit": { - "cond": "v0", - "targets": [ - "Block2", - "Block1" - ], - "type": "ConditionalJump" - }, - "id": "Block0", - "instructions": [ - { - "in": [], - "op": "callvalue", - "out": [ - "v0" - ] - } - ], - "type": "BuiltinCall" - }, - { - "exit": { - "type": "Terminated" - }, - "id": "Block2", - "instructions": [ - { - "in": [], - "op": "calldatasize", - "out": [ - "v1" - ] - }, - { - "in": [ - "v1", - "0x04" - ], - "op": "abi_decode_tuple_", - "out": [] - }, - { - "in": [], - "op": "fun_f_18", - "out": [ - "v3" - ] - }, - { - "in": [], - "op": "allocate_unbounded", - "out": [ - "v4" - ] - }, - { - "in": [ - "v3", - "v4" - ], - "op": "abi_encode_tuple_t_uint256__to_t_uint256__fromStack", - "out": [ - "v5" - ] - }, - { - "in": [ - "v4", - "v5" - ], - "op": "sub", - "out": [ - "v6" - ] - }, - { - "in": [ - "v6", - "v4" - ], - "op": "return", - "out": [] - } - ], - "type": "BuiltinCall" - }, - { - "exit": { - "type": "Terminated" - }, - "id": "Block1", - "instructions": [ - { - "in": [], - "op": "revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb", - "out": [] - } - ], - "type": "FunctionCall" - } - ], - "entry": "Block0", - "numReturns": 0, - "type": "Function" - }, - "fun_f_18": { - "arguments": [], - "blocks": [ - { - "exit": { - "returnValues": [ - "v3" - ], - "type": "FunctionReturn" - }, - "id": "Block0", - "instructions": [ - { - "in": [], - "op": "zero_value_for_split_t_uint256", - "out": [ - "v1" - ] - }, - { - "in": [ - "0x2a" - ], - "op": "convert_t_rational_42_by_1_to_t_uint256", - "out": [ - "v3" - ] - } - ], - "type": "FunctionCall" - } - ], - "entry": "Block0", - "numReturns": 1, - "type": "Function" - }, - "identity": { - "arguments": [ - "v0" - ], - "blocks": [ - { - "exit": { - "returnValues": [ - "v0" - ], - "type": "FunctionReturn" - }, - "id": "Block0", - "instructions": [] - } - ], - "entry": "Block0", - "numReturns": 1, - "type": "Function" - }, - "revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74": { - "arguments": [], - "blocks": [ - { - "exit": { - "type": "Terminated" - }, - "id": "Block0", - "instructions": [ - { - "in": [ - "0x00", - "0x00" - ], - "op": "revert", - "out": [] - } - ], - "type": "BuiltinCall" - } - ], - "entry": "Block0", - "numReturns": 0, - "type": "Function" - }, - "revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb": { - "arguments": [], - "blocks": [ - { - "exit": { - "type": "Terminated" - }, - "id": "Block0", - "instructions": [ - { - "in": [ - "0x00", - "0x00" - ], - "op": "revert", - "out": [] - } - ], - "type": "BuiltinCall" - } - ], - "entry": "Block0", - "numReturns": 0, - "type": "Function" - }, - "revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b": { - "arguments": [], - "blocks": [ - { - "exit": { - "type": "Terminated" - }, - "id": "Block0", - "instructions": [ - { - "in": [ - "0x00", - "0x00" - ], - "op": "revert", - "out": [] - } - ], - "type": "BuiltinCall" - } - ], - "entry": "Block0", - "numReturns": 0, - "type": "Function" - }, - "shift_right_224_unsigned": { - "arguments": [ - "v0" - ], - "blocks": [ - { - "exit": { - "returnValues": [ - "v3" - ], - "type": "FunctionReturn" - }, - "id": "Block0", - "instructions": [ - { - "in": [ - "v0", - "0xe0" - ], - "op": "shr", - "out": [ - "v3" - ] - } - ], - "type": "BuiltinCall" - } - ], - "entry": "Block0", - "numReturns": 1, - "type": "Function" + "type": "BuiltinCall" }, - "zero_value_for_split_t_uint256": { - "arguments": [], - "blocks": [ + { + "exit": { + "type": "Terminated" + }, + "id": "Block8", + "instructions": [ { - "exit": { - "returnValues": [ - "0x00" - ], - "type": "FunctionReturn" - }, - "id": "Block0", - "instructions": [] + "in": [ + "0x00", + "0x00" + ], + "op": "revert", + "out": [] } ], - "entry": "Block0", - "numReturns": 1, - "type": "Function" + "type": "BuiltinCall" } - } + ], + "functions": {} }, "subObjects": {}, "type": "subObject" @@ -965,7 +397,7 @@ "instructions": [ { "builtinArgs": [ - "128" + "0x80" ], "in": [], "op": "memoryguard", @@ -997,18 +429,6 @@ }, "id": "Block2", "instructions": [ - { - "in": [], - "op": "constructor_D_38", - "out": [] - }, - { - "in": [], - "op": "allocate_unbounded", - "out": [ - "v3" - ] - }, { "builtinArgs": [ "D_38_deployed" @@ -1033,25 +453,15 @@ "in": [ "v4", "v5", - "v3" + "v0" ], "op": "codecopy", "out": [] }, - { - "builtinArgs": [ - "D_38_deployed" - ], - "in": [], - "op": "datasize", - "out": [ - "v6" - ] - }, { "in": [ - "v6", - "v3" + "v4", + "v0" ], "op": "return", "out": [] @@ -1066,86 +476,18 @@ "id": "Block1", "instructions": [ { - "in": [], - "op": "revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb", + "in": [ + "0x00", + "0x00" + ], + "op": "revert", "out": [] } ], - "type": "FunctionCall" + "type": "BuiltinCall" } ], - "functions": { - "allocate_unbounded": { - "arguments": [], - "blocks": [ - { - "exit": { - "returnValues": [ - "v2" - ], - "type": "FunctionReturn" - }, - "id": "Block0", - "instructions": [ - { - "in": [ - "0x40" - ], - "op": "mload", - "out": [ - "v2" - ] - } - ], - "type": "BuiltinCall" - } - ], - "entry": "Block0", - "numReturns": 1, - "type": "Function" - }, - "constructor_D_38": { - "arguments": [], - "blocks": [ - { - "exit": { - "returnValues": [], - "type": "FunctionReturn" - }, - "id": "Block0", - "instructions": [] - } - ], - "entry": "Block0", - "numReturns": 0, - "type": "Function" - }, - "revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb": { - "arguments": [], - "blocks": [ - { - "exit": { - "type": "Terminated" - }, - "id": "Block0", - "instructions": [ - { - "in": [ - "0x00", - "0x00" - ], - "op": "revert", - "out": [] - } - ], - "type": "BuiltinCall" - } - ], - "entry": "Block0", - "numReturns": 0, - "type": "Function" - } - } + "functions": {} }, "subObjects": { "D_38_deployed": { @@ -1153,1787 +495,947 @@ { "exit": { "cond": "v5", - "targets": [ - "Block2", - "Block1" - ], - "type": "ConditionalJump" - }, - "id": "Block0", - "instructions": [ - { - "builtinArgs": [ - "128" - ], - "in": [], - "op": "memoryguard", - "out": [ - "v0" - ] - }, - { - "in": [ - "v0", - "0x40" - ], - "op": "mstore", - "out": [] - }, - { - "in": [], - "op": "calldatasize", - "out": [ - "v3" - ] - }, - { - "in": [ - "0x04", - "v3" - ], - "op": "lt", - "out": [ - "v4" - ] - }, - { - "in": [ - "v4" - ], - "op": "iszero", - "out": [ - "v5" - ] - } - ], - "type": "BuiltinCall" - }, - { - "exit": { - "type": "Terminated" - }, - "id": "Block2", - "instructions": [ - { - "in": [], - "op": "revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74", - "out": [] - } - ], - "type": "FunctionCall" - }, - { - "exit": { - "cond": "v9", - "targets": [ - "Block5", - "Block4" - ], - "type": "ConditionalJump" - }, - "id": "Block1", - "instructions": [ - { - "in": [ - "0x00" - ], - "op": "calldataload", - "out": [ - "v7" - ] - }, - { - "in": [ - "v7" - ], - "op": "shift_right_224_unsigned", - "out": [ - "v8" - ] - }, - { - "in": [ - "0x26121ff0", - "v8" - ], - "op": "eq", - "out": [ - "v9" - ] - } - ], - "type": "BuiltinCall" - }, - { - "exit": { - "targets": [ - "Block3" - ], - "type": "Jump" - }, - "id": "Block5", - "instructions": [] - }, - { - "exit": { - "type": "Terminated" - }, - "id": "Block4", - "instructions": [ - { - "in": [], - "op": "external_fun_f_37", - "out": [] - } - ], - "type": "FunctionCall" - }, - { - "exit": { - "targets": [ - "Block2" - ], - "type": "Jump" - }, - "id": "Block3", - "instructions": [] - } - ], - "functions": { - "abi_decode_t_uint256_fromMemory": { - "arguments": [ - "v0", - "v1" - ], - "blocks": [ - { - "exit": { - "returnValues": [ - "v3" - ], - "type": "FunctionReturn" - }, - "id": "Block0", - "instructions": [ - { - "in": [ - "v0" - ], - "op": "mload", - "out": [ - "v3" - ] - }, - { - "in": [ - "v3" - ], - "op": "validator_revert_t_uint256", - "out": [] - } - ], - "type": "FunctionCall" - } - ], - "entry": "Block0", - "numReturns": 1, - "type": "Function" - }, - "abi_decode_tuple_": { - "arguments": [ - "v0", - "v1" - ], - "blocks": [ + "targets": [ + "Block2", + "Block1" + ], + "type": "ConditionalJump" + }, + "id": "Block0", + "instructions": [ { - "exit": { - "cond": "v4", - "targets": [ - "Block2", - "Block1" - ], - "type": "ConditionalJump" - }, - "id": "Block0", - "instructions": [ - { - "in": [ - "v0", - "v1" - ], - "op": "sub", - "out": [ - "v3" - ] - }, - { - "in": [ - "0x00", - "v3" - ], - "op": "slt", - "out": [ - "v4" - ] - } + "builtinArgs": [ + "0x80" ], - "type": "BuiltinCall" - }, - { - "exit": { - "returnValues": [], - "type": "FunctionReturn" - }, - "id": "Block2", - "instructions": [] + "in": [], + "op": "memoryguard", + "out": [ + "v0" + ] }, { - "exit": { - "type": "Terminated" - }, - "id": "Block1", - "instructions": [ - { - "in": [], - "op": "revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b", - "out": [] - } + "in": [ + "v0", + "0x40" ], - "type": "FunctionCall" - } - ], - "entry": "Block0", - "numReturns": 0, - "type": "Function" - }, - "abi_decode_tuple_t_uint256_fromMemory": { - "arguments": [ - "v0", - "v1" - ], - "blocks": [ + "op": "mstore", + "out": [] + }, { - "exit": { - "cond": "v5", - "targets": [ - "Block2", - "Block1" - ], - "type": "ConditionalJump" - }, - "id": "Block0", - "instructions": [ - { - "in": [ - "v0", - "v1" - ], - "op": "sub", - "out": [ - "v4" - ] - }, - { - "in": [ - "0x20", - "v4" - ], - "op": "slt", - "out": [ - "v5" - ] - } - ], - "type": "BuiltinCall" + "in": [], + "op": "calldatasize", + "out": [ + "v3" + ] }, { - "exit": { - "returnValues": [ - "v12" - ], - "type": "FunctionReturn" - }, - "id": "Block2", - "instructions": [ - { - "in": [ - "0x00", - "v0" - ], - "op": "add", - "out": [ - "v11" - ] - }, - { - "in": [ - "v1", - "v11" - ], - "op": "abi_decode_t_uint256_fromMemory", - "out": [ - "v12" - ] - } + "in": [ + "0x04", + "v3" ], - "type": "FunctionCall" + "op": "lt", + "out": [ + "v4" + ] }, { - "exit": { - "type": "Terminated" - }, - "id": "Block1", - "instructions": [ - { - "in": [], - "op": "revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b", - "out": [] - } + "in": [ + "v4" ], - "type": "FunctionCall" + "op": "iszero", + "out": [ + "v5" + ] } ], - "entry": "Block0", - "numReturns": 1, - "type": "Function" + "type": "BuiltinCall" }, - "abi_encode_t_uint256_to_t_uint256_fromStack": { - "arguments": [ - "v0", - "v1" - ], - "blocks": [ + { + "exit": { + "type": "Terminated" + }, + "id": "Block2", + "instructions": [ { - "exit": { - "returnValues": [], - "type": "FunctionReturn" - }, - "id": "Block0", - "instructions": [ - { - "in": [ - "v0" - ], - "op": "cleanup_t_uint256", - "out": [ - "v2" - ] - }, - { - "in": [ - "v2", - "v1" - ], - "op": "mstore", - "out": [] - } + "in": [ + "0x00", + "0x00" ], - "type": "BuiltinCall" + "op": "revert", + "out": [] } ], - "entry": "Block0", - "numReturns": 0, - "type": "Function" + "type": "BuiltinCall" }, - "abi_encode_tuple__to__fromStack": { - "arguments": [ - "v0" - ], - "blocks": [ + { + "exit": { + "cond": "v11", + "targets": [ + "Block4", + "Block3" + ], + "type": "ConditionalJump" + }, + "id": "Block1", + "instructions": [ { - "exit": { - "returnValues": [ - "v2" - ], - "type": "FunctionReturn" - }, - "id": "Block0", - "instructions": [ - { - "in": [ - "0x00", - "v0" - ], - "op": "add", - "out": [ - "v2" - ] - } + "in": [ + "0x00" ], - "type": "BuiltinCall" - } - ], - "entry": "Block0", - "numReturns": 1, - "type": "Function" - }, - "abi_encode_tuple_t_uint256__to_t_uint256__fromStack": { - "arguments": [ - "v0", - "v1" - ], - "blocks": [ + "op": "calldataload", + "out": [ + "v7" + ] + }, { - "exit": { - "returnValues": [ - "v4" - ], - "type": "FunctionReturn" - }, - "id": "Block0", - "instructions": [ - { - "in": [ - "0x20", - "v0" - ], - "op": "add", - "out": [ - "v4" - ] - }, - { - "in": [ - "0x00", - "v0" - ], - "op": "add", - "out": [ - "v5" - ] - }, - { - "in": [ - "v5", - "v1" - ], - "op": "abi_encode_t_uint256_to_t_uint256_fromStack", - "out": [] - } + "in": [ + "v7", + "0xe0" + ], + "op": "shr", + "out": [ + "v9" + ] + }, + { + "in": [ + "v9", + "0x26121ff0" ], - "type": "FunctionCall" + "op": "eq", + "out": [ + "v11" + ] } ], - "entry": "Block0", - "numReturns": 1, - "type": "Function" + "type": "BuiltinCall" }, - "allocate_unbounded": { - "arguments": [], - "blocks": [ + { + "exit": { + "targets": [ + "Block2" + ], + "type": "Jump" + }, + "id": "Block4", + "instructions": [] + }, + { + "exit": { + "cond": "v12", + "targets": [ + "Block6", + "Block5" + ], + "type": "ConditionalJump" + }, + "id": "Block3", + "instructions": [ { - "exit": { - "returnValues": [ - "v2" - ], - "type": "FunctionReturn" - }, - "id": "Block0", - "instructions": [ - { - "in": [ - "0x40" - ], - "op": "mload", - "out": [ - "v2" - ] - } - ], - "type": "BuiltinCall" + "in": [], + "op": "callvalue", + "out": [ + "v12" + ] } ], - "entry": "Block0", - "numReturns": 1, - "type": "Function" + "type": "BuiltinCall" }, - "cleanup_t_uint160": { - "arguments": [ - "v0" - ], - "blocks": [ + { + "exit": { + "cond": "v17", + "targets": [ + "Block9", + "Block8" + ], + "type": "ConditionalJump" + }, + "id": "Block6", + "instructions": [ { - "exit": { - "returnValues": [ - "v3" - ], - "type": "FunctionReturn" - }, - "id": "Block0", - "instructions": [ - { - "in": [ - "0xffffffffffffffffffffffffffffffffffffffff", - "v0" - ], - "op": "and", - "out": [ - "v3" - ] - } + "in": [ + "0x03" ], - "type": "BuiltinCall" - } - ], - "entry": "Block0", - "numReturns": 1, - "type": "Function" - }, - "cleanup_t_uint256": { - "arguments": [ - "v0" - ], - "blocks": [ + "op": "not", + "out": [ + "v14" + ] + }, { - "exit": { - "returnValues": [ - "v0" - ], - "type": "FunctionReturn" - }, - "id": "Block0", - "instructions": [] - } - ], - "entry": "Block0", - "numReturns": 1, - "type": "Function" - }, - "convert_t_contract$_C_$19_to_t_address": { - "arguments": [ - "v0" - ], - "blocks": [ + "in": [], + "op": "calldatasize", + "out": [ + "v15" + ] + }, { - "exit": { - "returnValues": [ - "v2" - ], - "type": "FunctionReturn" - }, - "id": "Block0", - "instructions": [ - { - "in": [ - "v0" - ], - "op": "convert_t_uint160_to_t_address", - "out": [ - "v2" - ] - } + "in": [ + "v14", + "v15" ], - "type": "FunctionCall" - } - ], - "entry": "Block0", - "numReturns": 1, - "type": "Function" - }, - "convert_t_uint160_to_t_address": { - "arguments": [ - "v0" - ], - "blocks": [ + "op": "add", + "out": [ + "v16" + ] + }, { - "exit": { - "returnValues": [ - "v2" - ], - "type": "FunctionReturn" - }, - "id": "Block0", - "instructions": [ - { - "in": [ - "v0" - ], - "op": "convert_t_uint160_to_t_uint160", - "out": [ - "v2" - ] - } + "in": [ + "0x00", + "v16" ], - "type": "FunctionCall" + "op": "slt", + "out": [ + "v17" + ] } ], - "entry": "Block0", - "numReturns": 1, - "type": "Function" + "type": "BuiltinCall" }, - "convert_t_uint160_to_t_uint160": { - "arguments": [ - "v0" - ], - "blocks": [ + { + "exit": { + "type": "Terminated" + }, + "id": "Block5", + "instructions": [ { - "exit": { - "returnValues": [ - "v4" - ], - "type": "FunctionReturn" - }, - "id": "Block0", - "instructions": [ - { - "in": [ - "v0" - ], - "op": "cleanup_t_uint160", - "out": [ - "v2" - ] - }, - { - "in": [ - "v2" - ], - "op": "identity", - "out": [ - "v3" - ] - }, - { - "in": [ - "v3" - ], - "op": "cleanup_t_uint160", - "out": [ - "v4" - ] - } + "in": [ + "0x00", + "0x00" ], - "type": "FunctionCall" + "op": "revert", + "out": [] } ], - "entry": "Block0", - "numReturns": 1, - "type": "Function" + "type": "BuiltinCall" }, - "external_fun_f_37": { - "arguments": [], - "blocks": [ + { + "exit": { + "cond": "v28", + "targets": [ + "Block12", + "Block11" + ], + "type": "ConditionalJump" + }, + "id": "Block9", + "instructions": [ { - "exit": { - "cond": "v0", - "targets": [ - "Block2", - "Block1" - ], - "type": "ConditionalJump" - }, - "id": "Block0", - "instructions": [ - { - "in": [], - "op": "callvalue", - "out": [ - "v0" - ] - } + "builtinArgs": [ + "C_19" ], - "type": "BuiltinCall" + "in": [], + "op": "datasize", + "out": [ + "v18" + ] }, { - "exit": { - "type": "Terminated" - }, - "id": "Block2", - "instructions": [ - { - "in": [], - "op": "calldatasize", - "out": [ - "v1" - ] - }, - { - "in": [ - "v1", - "0x04" - ], - "op": "abi_decode_tuple_", - "out": [] - }, - { - "in": [], - "op": "fun_f_37", - "out": [ - "v3" - ] - }, - { - "in": [], - "op": "allocate_unbounded", - "out": [ - "v4" - ] - }, - { - "in": [ - "v3", - "v4" - ], - "op": "abi_encode_tuple_t_uint256__to_t_uint256__fromStack", - "out": [ - "v5" - ] - }, - { - "in": [ - "v4", - "v5" - ], - "op": "sub", - "out": [ - "v6" - ] - }, - { - "in": [ - "v6", - "v4" - ], - "op": "return", - "out": [] - } + "in": [ + "v18", + "v0" + ], + "op": "add", + "out": [ + "v24" + ] + }, + { + "in": [ + "v0", + "v24" ], - "type": "BuiltinCall" + "op": "lt", + "out": [ + "v25" + ] }, { - "exit": { - "type": "Terminated" - }, - "id": "Block1", - "instructions": [ - { - "in": [], - "op": "revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb", - "out": [] - } + "in": [ + "0xffffffffffffffff", + "v24" ], - "type": "FunctionCall" + "op": "gt", + "out": [ + "v27" + ] + }, + { + "in": [ + "v25", + "v27" + ], + "op": "or", + "out": [ + "v28" + ] } ], - "entry": "Block0", - "numReturns": 0, - "type": "Function" + "type": "BuiltinCall" }, - "finalize_allocation": { - "arguments": [ - "v0", - "v1" + { + "exit": { + "type": "Terminated" + }, + "id": "Block8", + "instructions": [ + { + "in": [ + "0x00", + "0x00" + ], + "op": "revert", + "out": [] + } ], - "blocks": [ + "type": "BuiltinCall" + }, + { + "exit": { + "cond": "v42", + "targets": [ + "Block15", + "Block14" + ], + "type": "ConditionalJump" + }, + "id": "Block12", + "instructions": [ { - "exit": { - "cond": "v7", - "targets": [ - "Block2", - "Block1" - ], - "type": "ConditionalJump" - }, - "id": "Block0", - "instructions": [ - { - "in": [ - "v1" - ], - "op": "round_up_to_mul_of_32", - "out": [ - "v2" - ] - }, - { - "in": [ - "v2", - "v0" - ], - "op": "add", - "out": [ - "v3" - ] - }, - { - "in": [ - "v0", - "v3" - ], - "op": "lt", - "out": [ - "v4" - ] - }, - { - "in": [ - "0xffffffffffffffff", - "v3" - ], - "op": "gt", - "out": [ - "v6" - ] - }, - { - "in": [ - "v4", - "v6" - ], - "op": "or", - "out": [ - "v7" - ] - } + "builtinArgs": [ + "C_19" ], - "type": "BuiltinCall" + "in": [], + "op": "dataoffset", + "out": [ + "v35" + ] }, { - "exit": { - "returnValues": [], - "type": "FunctionReturn" - }, - "id": "Block2", - "instructions": [ - { - "in": [ - "v3", - "0x40" - ], - "op": "mstore", - "out": [] - } + "in": [ + "v18", + "v35", + "v0" ], - "type": "BuiltinCall" + "op": "datacopy", + "out": [] }, { - "exit": { - "type": "Terminated" - }, - "id": "Block1", - "instructions": [ - { - "in": [], - "op": "panic_error_0x41", - "out": [] - } + "in": [ + "v0", + "v24" ], - "type": "FunctionCall" - } - ], - "entry": "Block0", - "numReturns": 0, - "type": "Function" - }, - "fun_f_37": { - "arguments": [], - "blocks": [ + "op": "sub", + "out": [ + "v40" + ] + }, { - "exit": { - "cond": "v8", - "targets": [ - "Block2", - "Block1" - ], - "type": "ConditionalJump" - }, - "id": "Block0", - "instructions": [ - { - "in": [], - "op": "zero_value_for_split_t_uint256", - "out": [ - "v1" - ] - }, - { - "in": [], - "op": "allocate_unbounded", - "out": [ - "v2" - ] - }, - { - "builtinArgs": [ - "C_19" - ], - "in": [], - "op": "datasize", - "out": [ - "v3" - ] - }, - { - "in": [ - "v3", - "v2" - ], - "op": "add", - "out": [ - "v4" - ] - }, - { - "in": [ - "v2", - "v4" - ], - "op": "lt", - "out": [ - "v5" - ] - }, - { - "in": [ - "0xffffffffffffffff", - "v4" - ], - "op": "gt", - "out": [ - "v7" - ] - }, - { - "in": [ - "v5", - "v7" - ], - "op": "or", - "out": [ - "v8" - ] - } + "in": [ + "v40", + "v0", + "0x00" ], - "type": "BuiltinCall" + "op": "create", + "out": [ + "v41" + ] }, { - "exit": { - "cond": "v19", - "targets": [ - "Block5", - "Block4" - ], - "type": "ConditionalJump" - }, - "id": "Block2", - "instructions": [ - { - "builtinArgs": [ - "C_19" - ], - "in": [], - "op": "datasize", - "out": [ - "v9" - ] - }, - { - "builtinArgs": [ - "C_19" - ], - "in": [], - "op": "dataoffset", - "out": [ - "v10" - ] - }, - { - "in": [ - "v9", - "v10", - "v2" - ], - "op": "datacopy", - "out": [] - }, - { - "in": [ - "v4" - ], - "op": "abi_encode_tuple__to__fromStack", - "out": [ - "v16" - ] - }, - { - "in": [ - "v2", - "v16" - ], - "op": "sub", - "out": [ - "v17" - ] - }, - { - "in": [ - "v17", - "v2", - "0x00" - ], - "op": "create", - "out": [ - "v18" - ] - }, - { - "in": [ - "v18" - ], - "op": "iszero", - "out": [ - "v19" - ] - } + "in": [ + "v41" ], - "type": "BuiltinCall" + "op": "iszero", + "out": [ + "v42" + ] + } + ], + "type": "BuiltinCall" + }, + { + "exit": { + "type": "Terminated" + }, + "id": "Block11", + "instructions": [ + { + "in": [ + "0x4e487b71", + "0xe0" + ], + "op": "shl", + "out": [ + "v30" + ] }, { - "exit": { - "type": "Terminated" - }, - "id": "Block1", - "instructions": [ - { - "in": [], - "op": "panic_error_0x41", - "out": [] - } + "in": [ + "v30", + "0x00" ], - "type": "FunctionCall" + "op": "mstore", + "out": [] }, { - "exit": { - "cond": "v33", - "targets": [ - "Block8", - "Block7" - ], - "type": "ConditionalJump" - }, - "id": "Block5", - "instructions": [ - { - "in": [ - "v18" - ], - "op": "convert_t_contract$_C_$19_to_t_address", - "out": [ - "v22" - ] - }, - { - "in": [], - "op": "allocate_unbounded", - "out": [ - "v24" - ] - }, - { - "in": [ - "0x26121ff0" - ], - "op": "shift_left_224", - "out": [ - "v25" - ] - }, - { - "in": [ - "v25", - "v24" - ], - "op": "mstore", - "out": [] - }, - { - "in": [ - "0x04", - "v24" - ], - "op": "add", - "out": [ - "v27" - ] - }, - { - "in": [ - "v27" - ], - "op": "abi_encode_tuple__to__fromStack", - "out": [ - "v28" - ] - }, - { - "in": [ - "v24", - "v28" - ], - "op": "sub", - "out": [ - "v30" - ] - }, - { - "in": [], - "op": "gas", - "out": [ - "v31" - ] - }, - { - "in": [ - "0x20", - "v24", - "v30", - "v24", - "v22", - "v31" - ], - "op": "staticcall", - "out": [ - "v32" - ] - }, - { - "in": [ - "v32" - ], - "op": "iszero", - "out": [ - "v33" - ] - } + "in": [ + "0x41", + "0x04" ], - "type": "BuiltinCall" + "op": "mstore", + "out": [] }, { - "exit": { - "type": "Terminated" - }, - "id": "Block4", - "instructions": [ - { - "in": [], - "op": "revert_forward_1", - "out": [] - } + "in": [ + "0x24", + "0x00" + ], + "op": "revert", + "out": [] + } + ], + "type": "BuiltinCall" + }, + { + "exit": { + "cond": "v60", + "targets": [ + "Block18", + "Block17" + ], + "type": "ConditionalJump" + }, + "id": "Block15", + "instructions": [ + { + "in": [ + "0x40" ], - "type": "FunctionCall" + "op": "mload", + "out": [ + "v46" + ] }, { - "exit": { - "cond": "v32", - "targets": [ - "Block11", - "Block10" - ], - "type": "ConditionalJump" - }, - "id": "Block8", - "instructions": [] + "in": [ + "0x026121ff", + "0xe4" + ], + "op": "shl", + "out": [ + "v49" + ] }, { - "exit": { - "type": "Terminated" - }, - "id": "Block7", - "instructions": [ - { - "in": [], - "op": "revert_forward_1", - "out": [] - } + "in": [ + "v49", + "v46" ], - "type": "FunctionCall" + "op": "mstore", + "out": [] }, { - "entries": [ - "Block8", - "Block13" + "in": [ + "0x01", + "0xa0" ], - "exit": { - "returnValues": [ - "v45" - ], - "type": "FunctionReturn" - }, - "id": "Block11", - "instructions": [ - { - "in": [ - "0x00", - "v44" - ], - "op": "PhiFunction", - "out": [ - "v45" - ] - } + "op": "shl", + "out": [ + "v53" ] }, { - "exit": { - "cond": "v37", - "targets": [ - "Block13", - "Block12" - ], - "type": "ConditionalJump" - }, - "id": "Block10", - "instructions": [ - { - "in": [], - "op": "returndatasize", - "out": [ - "v36" - ] - }, - { - "in": [ - "v36", - "0x20" - ], - "op": "gt", - "out": [ - "v37" - ] - } + "in": [ + "0x01", + "v53" ], - "type": "BuiltinCall" + "op": "sub", + "out": [ + "v54" + ] }, { - "entries": [ - "Block10", - "Block12" + "in": [ + "v54", + "v41" ], - "exit": { - "targets": [ - "Block11" - ], - "type": "Jump" - }, - "id": "Block13", - "instructions": [ - { - "in": [ - "0x20", - "v38" - ], - "op": "PhiFunction", - "out": [ - "v39" - ] - }, - { - "in": [ - "v39", - "v24" - ], - "op": "finalize_allocation", - "out": [] - }, - { - "in": [ - "v39", - "v24" - ], - "op": "add", - "out": [ - "v43" - ] - }, - { - "in": [ - "v43", - "v24" - ], - "op": "abi_decode_tuple_t_uint256_fromMemory", - "out": [ - "v44" - ] - } + "op": "and", + "out": [ + "v57" + ] + }, + { + "in": [], + "op": "gas", + "out": [ + "v58" + ] + }, + { + "in": [ + "0x20", + "v46", + "0x04", + "v46", + "v57", + "v58" + ], + "op": "staticcall", + "out": [ + "v59" + ] + }, + { + "in": [ + "v59" + ], + "op": "iszero", + "out": [ + "v60" + ] + } + ], + "type": "BuiltinCall" + }, + { + "exit": { + "type": "Terminated" + }, + "id": "Block14", + "instructions": [ + { + "in": [ + "0x40" + ], + "op": "mload", + "out": [ + "v43" + ] + }, + { + "in": [], + "op": "returndatasize", + "out": [ + "v44" + ] + }, + { + "in": [ + "v44", + "0x00", + "v43" ], - "type": "FunctionCall" + "op": "returndatacopy", + "out": [] }, { - "exit": { - "targets": [ - "Block13" - ], - "type": "Jump" - }, - "id": "Block12", - "instructions": [ - { - "in": [], - "op": "returndatasize", - "out": [ - "v38" - ] - } + "in": [], + "op": "returndatasize", + "out": [ + "v45" + ] + }, + { + "in": [ + "v45", + "v43" ], - "type": "BuiltinCall" + "op": "revert", + "out": [] } ], - "entry": "Block0", - "numReturns": 1, - "type": "Function" + "type": "BuiltinCall" }, - "identity": { - "arguments": [ - "v0" - ], - "blocks": [ - { - "exit": { - "returnValues": [ - "v0" - ], - "type": "FunctionReturn" - }, - "id": "Block0", - "instructions": [] - } - ], - "entry": "Block0", - "numReturns": 1, - "type": "Function" + { + "exit": { + "cond": "v59", + "targets": [ + "Block21", + "Block20" + ], + "type": "ConditionalJump" + }, + "id": "Block18", + "instructions": [] }, - "panic_error_0x41": { - "arguments": [], - "blocks": [ + { + "exit": { + "type": "Terminated" + }, + "id": "Block17", + "instructions": [ { - "exit": { - "type": "Terminated" - }, - "id": "Block0", - "instructions": [ - { - "in": [ - "0x4e487b7100000000000000000000000000000000000000000000000000000000", - "0x00" - ], - "op": "mstore", - "out": [] - }, - { - "in": [ - "0x41", - "0x04" - ], - "op": "mstore", - "out": [] - }, - { - "in": [ - "0x24", - "0x00" - ], - "op": "revert", - "out": [] - } + "in": [ + "0x40" ], - "type": "BuiltinCall" - } - ], - "entry": "Block0", - "numReturns": 0, - "type": "Function" - }, - "revert_error_0cc013b6b3b6beabea4e3a74a6d380f0df81852ca99887912475e1f66b2a2c20": { - "arguments": [], - "blocks": [ + "op": "mload", + "out": [ + "v61" + ] + }, { - "exit": { - "type": "Terminated" - }, - "id": "Block0", - "instructions": [ - { - "in": [ - "0x00", - "0x00" - ], - "op": "revert", - "out": [] - } + "in": [], + "op": "returndatasize", + "out": [ + "v62" + ] + }, + { + "in": [ + "v62", + "0x00", + "v61" ], - "type": "BuiltinCall" - } - ], - "entry": "Block0", - "numReturns": 0, - "type": "Function" - }, - "revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74": { - "arguments": [], - "blocks": [ + "op": "returndatacopy", + "out": [] + }, { - "exit": { - "type": "Terminated" - }, - "id": "Block0", - "instructions": [ - { - "in": [ - "0x00", - "0x00" - ], - "op": "revert", - "out": [] - } + "in": [], + "op": "returndatasize", + "out": [ + "v63" + ] + }, + { + "in": [ + "v63", + "v61" ], - "type": "BuiltinCall" + "op": "revert", + "out": [] } ], - "entry": "Block0", - "numReturns": 0, - "type": "Function" + "type": "BuiltinCall" }, - "revert_error_c1322bf8034eace5e0b5c7295db60986aa89aae5e0ea0873e4689e076861a5db": { - "arguments": [], - "blocks": [ + { + "entries": [ + "Block18", + "Block28" + ], + "exit": { + "type": "Terminated" + }, + "id": "Block21", + "instructions": [ { - "exit": { - "type": "Terminated" - }, - "id": "Block0", - "instructions": [ - { - "in": [ - "0x00", - "0x00" - ], - "op": "revert", - "out": [] - } + "in": [ + "0x00", + "v93" ], - "type": "BuiltinCall" - } - ], - "entry": "Block0", - "numReturns": 0, - "type": "Function" - }, - "revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb": { - "arguments": [], - "blocks": [ + "op": "PhiFunction", + "out": [ + "v95" + ] + }, { - "exit": { - "type": "Terminated" - }, - "id": "Block0", - "instructions": [ - { - "in": [ - "0x00", - "0x00" - ], - "op": "revert", - "out": [] - } + "in": [ + "0x40" ], - "type": "BuiltinCall" - } - ], - "entry": "Block0", - "numReturns": 0, - "type": "Function" - }, - "revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b": { - "arguments": [], - "blocks": [ + "op": "mload", + "out": [ + "v94" + ] + }, { - "exit": { - "type": "Terminated" - }, - "id": "Block0", - "instructions": [ - { - "in": [ - "0x00", - "0x00" - ], - "op": "revert", - "out": [] - } + "in": [ + "v95", + "v94" ], - "type": "BuiltinCall" + "op": "mstore", + "out": [] + }, + { + "in": [ + "0x20", + "v94" + ], + "op": "return", + "out": [] } ], - "entry": "Block0", - "numReturns": 0, - "type": "Function" + "type": "BuiltinCall" }, - "revert_forward_1": { - "arguments": [], - "blocks": [ - { - "exit": { - "type": "Terminated" - }, - "id": "Block0", - "instructions": [ - { - "in": [], - "op": "allocate_unbounded", - "out": [ - "v0" - ] - }, - { - "in": [], - "op": "returndatasize", - "out": [ - "v1" - ] - }, - { - "in": [ - "v1", - "0x00", - "v0" - ], - "op": "returndatacopy", - "out": [] - }, - { - "in": [], - "op": "returndatasize", - "out": [ - "v3" - ] - }, - { - "in": [ - "v3", - "v0" - ], - "op": "revert", - "out": [] - } + { + "exit": { + "cond": "v67", + "targets": [ + "Block23", + "Block22" + ], + "type": "ConditionalJump" + }, + "id": "Block20", + "instructions": [ + { + "in": [], + "op": "returndatasize", + "out": [ + "v66" + ] + }, + { + "in": [ + "v66", + "0x20" ], - "type": "BuiltinCall" + "op": "gt", + "out": [ + "v67" + ] } ], - "entry": "Block0", - "numReturns": 0, - "type": "Function" + "type": "BuiltinCall" }, - "round_up_to_mul_of_32": { - "arguments": [ - "v0" + { + "entries": [ + "Block20", + "Block22" ], - "blocks": [ + "exit": { + "cond": "v80", + "targets": [ + "Block25", + "Block24" + ], + "type": "ConditionalJump" + }, + "id": "Block23", + "instructions": [ { - "exit": { - "returnValues": [ - "v5" - ], - "type": "FunctionReturn" - }, - "id": "Block0", - "instructions": [ - { - "in": [ - "0x1f" - ], - "op": "not", - "out": [ - "v3" - ] - }, - { - "in": [ - "0x1f", - "v0" - ], - "op": "add", - "out": [ - "v4" - ] - }, - { - "in": [ - "v3", - "v4" - ], - "op": "and", - "out": [ - "v5" - ] - } + "in": [ + "0x20", + "v68" ], - "type": "BuiltinCall" + "op": "PhiFunction", + "out": [ + "v71" + ] + }, + { + "in": [ + "0x1f" + ], + "op": "not", + "out": [ + "v70" + ] + }, + { + "in": [ + "0x1f", + "v71" + ], + "op": "add", + "out": [ + "v72" + ] + }, + { + "in": [ + "v70", + "v72" + ], + "op": "and", + "out": [ + "v73" + ] + }, + { + "in": [ + "v73", + "v46" + ], + "op": "add", + "out": [ + "v77" + ] + }, + { + "in": [ + "v46", + "v77" + ], + "op": "lt", + "out": [ + "v78" + ] + }, + { + "in": [ + "0xffffffffffffffff", + "v77" + ], + "op": "gt", + "out": [ + "v79" + ] + }, + { + "in": [ + "v78", + "v79" + ], + "op": "or", + "out": [ + "v80" + ] } ], - "entry": "Block0", - "numReturns": 1, - "type": "Function" + "type": "BuiltinCall" }, - "shift_left_224": { - "arguments": [ - "v0" - ], - "blocks": [ + { + "exit": { + "targets": [ + "Block23" + ], + "type": "Jump" + }, + "id": "Block22", + "instructions": [ { - "exit": { - "returnValues": [ - "v3" - ], - "type": "FunctionReturn" - }, - "id": "Block0", - "instructions": [ - { - "in": [ - "v0", - "0xe0" - ], - "op": "shl", - "out": [ - "v3" - ] - } - ], - "type": "BuiltinCall" + "in": [], + "op": "returndatasize", + "out": [ + "v68" + ] } ], - "entry": "Block0", - "numReturns": 1, - "type": "Function" + "type": "BuiltinCall" }, - "shift_right_224_unsigned": { - "arguments": [ - "v0" - ], - "blocks": [ + { + "exit": { + "cond": "v90", + "targets": [ + "Block28", + "Block27" + ], + "type": "ConditionalJump" + }, + "id": "Block25", + "instructions": [ { - "exit": { - "returnValues": [ - "v3" - ], - "type": "FunctionReturn" - }, - "id": "Block0", - "instructions": [ - { - "in": [ - "v0", - "0xe0" - ], - "op": "shr", - "out": [ - "v3" - ] - } + "in": [ + "v77", + "0x40" ], - "type": "BuiltinCall" + "op": "mstore", + "out": [] + }, + { + "in": [ + "v71", + "v46" + ], + "op": "add", + "out": [ + "v88" + ] + }, + { + "in": [ + "v46", + "v88" + ], + "op": "sub", + "out": [ + "v89" + ] + }, + { + "in": [ + "0x20", + "v89" + ], + "op": "slt", + "out": [ + "v90" + ] } ], - "entry": "Block0", - "numReturns": 1, - "type": "Function" + "type": "BuiltinCall" }, - "validator_revert_t_uint256": { - "arguments": [ - "v0" - ], - "blocks": [ + { + "exit": { + "type": "Terminated" + }, + "id": "Block24", + "instructions": [ { - "exit": { - "cond": "v3", - "targets": [ - "Block2", - "Block1" - ], - "type": "ConditionalJump" - }, - "id": "Block0", - "instructions": [ - { - "in": [ - "v0" - ], - "op": "cleanup_t_uint256", - "out": [ - "v1" - ] - }, - { - "in": [ - "v1", - "v0" - ], - "op": "eq", - "out": [ - "v2" - ] - }, - { - "in": [ - "v2" - ], - "op": "iszero", - "out": [ - "v3" - ] - } + "in": [ + "0x4e487b71", + "0xe0" ], - "type": "BuiltinCall" + "op": "shl", + "out": [ + "v81" + ] }, { - "exit": { - "returnValues": [], - "type": "FunctionReturn" - }, - "id": "Block2", - "instructions": [] + "in": [ + "v81", + "0x00" + ], + "op": "mstore", + "out": [] }, { - "exit": { - "type": "Terminated" - }, - "id": "Block1", - "instructions": [ - { - "in": [ - "0x00", - "0x00" - ], - "op": "revert", - "out": [] - } + "in": [ + "0x41", + "0x04" + ], + "op": "mstore", + "out": [] + }, + { + "in": [ + "0x24", + "0x00" + ], + "op": "revert", + "out": [] + } + ], + "type": "BuiltinCall" + }, + { + "exit": { + "targets": [ + "Block21" + ], + "type": "Jump" + }, + "id": "Block28", + "instructions": [ + { + "in": [ + "v46" ], - "type": "BuiltinCall" + "op": "mload", + "out": [ + "v93" + ] } ], - "entry": "Block0", - "numReturns": 0, - "type": "Function" + "type": "BuiltinCall" }, - "zero_value_for_split_t_uint256": { - "arguments": [], - "blocks": [ + { + "exit": { + "type": "Terminated" + }, + "id": "Block27", + "instructions": [ { - "exit": { - "returnValues": [ - "0x00" - ], - "type": "FunctionReturn" - }, - "id": "Block0", - "instructions": [] + "in": [ + "0x00", + "0x00" + ], + "op": "revert", + "out": [] } ], - "entry": "Block0", - "numReturns": 1, - "type": "Function" + "type": "BuiltinCall" } - } + ], + "functions": {} }, "subObjects": { "C_19": { @@ -2951,7 +1453,7 @@ "instructions": [ { "builtinArgs": [ - "128" + "0x80" ], "in": [], "op": "memoryguard", @@ -2983,18 +1485,6 @@ }, "id": "Block2", "instructions": [ - { - "in": [], - "op": "constructor_C_19", - "out": [] - }, - { - "in": [], - "op": "allocate_unbounded", - "out": [ - "v3" - ] - }, { "builtinArgs": [ "C_19_deployed" @@ -3019,25 +1509,15 @@ "in": [ "v4", "v5", - "v3" + "v0" ], "op": "codecopy", "out": [] }, - { - "builtinArgs": [ - "C_19_deployed" - ], - "in": [], - "op": "datasize", - "out": [ - "v6" - ] - }, { "in": [ - "v6", - "v3" + "v4", + "v0" ], "op": "return", "out": [] @@ -3052,109 +1532,18 @@ "id": "Block1", "instructions": [ { - "in": [], - "op": "revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb", + "in": [ + "0x00", + "0x00" + ], + "op": "revert", "out": [] } ], - "type": "FunctionCall" + "type": "BuiltinCall" } ], - "functions": { - "allocate_unbounded": { - "arguments": [], - "blocks": [ - { - "exit": { - "returnValues": [ - "v2" - ], - "type": "FunctionReturn" - }, - "id": "Block0", - "instructions": [ - { - "in": [ - "0x40" - ], - "op": "mload", - "out": [ - "v2" - ] - } - ], - "type": "BuiltinCall" - } - ], - "entry": "Block0", - "numReturns": 1, - "type": "Function" - }, - "constructor_C_19": { - "arguments": [], - "blocks": [ - { - "exit": { - "returnValues": [], - "type": "FunctionReturn" - }, - "id": "Block0", - "instructions": [ - { - "in": [], - "op": "constructor_I_7", - "out": [] - } - ], - "type": "FunctionCall" - } - ], - "entry": "Block0", - "numReturns": 0, - "type": "Function" - }, - "constructor_I_7": { - "arguments": [], - "blocks": [ - { - "exit": { - "returnValues": [], - "type": "FunctionReturn" - }, - "id": "Block0", - "instructions": [] - } - ], - "entry": "Block0", - "numReturns": 0, - "type": "Function" - }, - "revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb": { - "arguments": [], - "blocks": [ - { - "exit": { - "type": "Terminated" - }, - "id": "Block0", - "instructions": [ - { - "in": [ - "0x00", - "0x00" - ], - "op": "revert", - "out": [] - } - ], - "type": "BuiltinCall" - } - ], - "entry": "Block0", - "numReturns": 0, - "type": "Function" - } - } + "functions": {} }, "subObjects": { "C_19_deployed": { @@ -3172,7 +1561,7 @@ "instructions": [ { "builtinArgs": [ - "128" + "0x80" ], "in": [], "op": "memoryguard", @@ -3224,19 +1613,22 @@ "id": "Block2", "instructions": [ { - "in": [], - "op": "revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74", + "in": [ + "0x00", + "0x00" + ], + "op": "revert", "out": [] } ], - "type": "FunctionCall" + "type": "BuiltinCall" }, { "exit": { - "cond": "v9", + "cond": "v11", "targets": [ - "Block5", - "Block4" + "Block4", + "Block3" ], "type": "ConditionalJump" }, @@ -3253,21 +1645,22 @@ }, { "in": [ - "v7" + "v7", + "0xe0" ], - "op": "shift_right_224_unsigned", + "op": "shr", "out": [ - "v8" + "v9" ] }, { "in": [ - "0x26121ff0", - "v8" + "v9", + "0x26121ff0" ], "op": "eq", "out": [ - "v9" + "v11" ] } ], @@ -3276,604 +1669,145 @@ { "exit": { "targets": [ - "Block3" + "Block2" ], "type": "Jump" }, - "id": "Block5", + "id": "Block4", "instructions": [] }, { "exit": { - "type": "Terminated" + "cond": "v12", + "targets": [ + "Block6", + "Block5" + ], + "type": "ConditionalJump" }, - "id": "Block4", + "id": "Block3", "instructions": [ { "in": [], - "op": "external_fun_f_18", - "out": [] + "op": "callvalue", + "out": [ + "v12" + ] } ], - "type": "FunctionCall" + "type": "BuiltinCall" }, { "exit": { + "cond": "v17", "targets": [ - "Block2" + "Block9", + "Block8" ], - "type": "Jump" + "type": "ConditionalJump" }, - "id": "Block3", - "instructions": [] - } - ], - "functions": { - "abi_decode_tuple_": { - "arguments": [ - "v0", - "v1" - ], - "blocks": [ + "id": "Block6", + "instructions": [ { - "exit": { - "cond": "v4", - "targets": [ - "Block2", - "Block1" - ], - "type": "ConditionalJump" - }, - "id": "Block0", - "instructions": [ - { - "in": [ - "v0", - "v1" - ], - "op": "sub", - "out": [ - "v3" - ] - }, - { - "in": [ - "0x00", - "v3" - ], - "op": "slt", - "out": [ - "v4" - ] - } + "in": [ + "0x03" ], - "type": "BuiltinCall" - }, - { - "exit": { - "returnValues": [], - "type": "FunctionReturn" - }, - "id": "Block2", - "instructions": [] + "op": "not", + "out": [ + "v14" + ] }, { - "exit": { - "type": "Terminated" - }, - "id": "Block1", - "instructions": [ - { - "in": [], - "op": "revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b", - "out": [] - } - ], - "type": "FunctionCall" - } - ], - "entry": "Block0", - "numReturns": 0, - "type": "Function" - }, - "abi_encode_t_uint256_to_t_uint256_fromStack": { - "arguments": [ - "v0", - "v1" - ], - "blocks": [ - { - "exit": { - "returnValues": [], - "type": "FunctionReturn" - }, - "id": "Block0", - "instructions": [ - { - "in": [ - "v0" - ], - "op": "cleanup_t_uint256", - "out": [ - "v2" - ] - }, - { - "in": [ - "v2", - "v1" - ], - "op": "mstore", - "out": [] - } - ], - "type": "BuiltinCall" - } - ], - "entry": "Block0", - "numReturns": 0, - "type": "Function" - }, - "abi_encode_tuple_t_uint256__to_t_uint256__fromStack": { - "arguments": [ - "v0", - "v1" - ], - "blocks": [ - { - "exit": { - "returnValues": [ - "v4" - ], - "type": "FunctionReturn" - }, - "id": "Block0", - "instructions": [ - { - "in": [ - "0x20", - "v0" - ], - "op": "add", - "out": [ - "v4" - ] - }, - { - "in": [ - "0x00", - "v0" - ], - "op": "add", - "out": [ - "v5" - ] - }, - { - "in": [ - "v5", - "v1" - ], - "op": "abi_encode_t_uint256_to_t_uint256_fromStack", - "out": [] - } - ], - "type": "FunctionCall" - } - ], - "entry": "Block0", - "numReturns": 1, - "type": "Function" - }, - "allocate_unbounded": { - "arguments": [], - "blocks": [ - { - "exit": { - "returnValues": [ - "v2" - ], - "type": "FunctionReturn" - }, - "id": "Block0", - "instructions": [ - { - "in": [ - "0x40" - ], - "op": "mload", - "out": [ - "v2" - ] - } - ], - "type": "BuiltinCall" - } - ], - "entry": "Block0", - "numReturns": 1, - "type": "Function" - }, - "cleanup_t_rational_42_by_1": { - "arguments": [ - "v0" - ], - "blocks": [ - { - "exit": { - "returnValues": [ - "v0" - ], - "type": "FunctionReturn" - }, - "id": "Block0", - "instructions": [] - } - ], - "entry": "Block0", - "numReturns": 1, - "type": "Function" - }, - "cleanup_t_uint256": { - "arguments": [ - "v0" - ], - "blocks": [ - { - "exit": { - "returnValues": [ - "v0" - ], - "type": "FunctionReturn" - }, - "id": "Block0", - "instructions": [] - } - ], - "entry": "Block0", - "numReturns": 1, - "type": "Function" - }, - "convert_t_rational_42_by_1_to_t_uint256": { - "arguments": [ - "v0" - ], - "blocks": [ - { - "exit": { - "returnValues": [ - "v4" - ], - "type": "FunctionReturn" - }, - "id": "Block0", - "instructions": [ - { - "in": [ - "v0" - ], - "op": "cleanup_t_rational_42_by_1", - "out": [ - "v2" - ] - }, - { - "in": [ - "v2" - ], - "op": "identity", - "out": [ - "v3" - ] - }, - { - "in": [ - "v3" - ], - "op": "cleanup_t_uint256", - "out": [ - "v4" - ] - } - ], - "type": "FunctionCall" - } - ], - "entry": "Block0", - "numReturns": 1, - "type": "Function" - }, - "external_fun_f_18": { - "arguments": [], - "blocks": [ - { - "exit": { - "cond": "v0", - "targets": [ - "Block2", - "Block1" - ], - "type": "ConditionalJump" - }, - "id": "Block0", - "instructions": [ - { - "in": [], - "op": "callvalue", - "out": [ - "v0" - ] - } - ], - "type": "BuiltinCall" + "in": [], + "op": "calldatasize", + "out": [ + "v15" + ] }, { - "exit": { - "type": "Terminated" - }, - "id": "Block2", - "instructions": [ - { - "in": [], - "op": "calldatasize", - "out": [ - "v1" - ] - }, - { - "in": [ - "v1", - "0x04" - ], - "op": "abi_decode_tuple_", - "out": [] - }, - { - "in": [], - "op": "fun_f_18", - "out": [ - "v3" - ] - }, - { - "in": [], - "op": "allocate_unbounded", - "out": [ - "v4" - ] - }, - { - "in": [ - "v3", - "v4" - ], - "op": "abi_encode_tuple_t_uint256__to_t_uint256__fromStack", - "out": [ - "v5" - ] - }, - { - "in": [ - "v4", - "v5" - ], - "op": "sub", - "out": [ - "v6" - ] - }, - { - "in": [ - "v6", - "v4" - ], - "op": "return", - "out": [] - } + "in": [ + "v14", + "v15" ], - "type": "BuiltinCall" + "op": "add", + "out": [ + "v16" + ] }, { - "exit": { - "type": "Terminated" - }, - "id": "Block1", - "instructions": [ - { - "in": [], - "op": "revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb", - "out": [] - } - ], - "type": "FunctionCall" - } - ], - "entry": "Block0", - "numReturns": 0, - "type": "Function" - }, - "fun_f_18": { - "arguments": [], - "blocks": [ - { - "exit": { - "returnValues": [ - "v3" - ], - "type": "FunctionReturn" - }, - "id": "Block0", - "instructions": [ - { - "in": [], - "op": "zero_value_for_split_t_uint256", - "out": [ - "v1" - ] - }, - { - "in": [ - "0x2a" - ], - "op": "convert_t_rational_42_by_1_to_t_uint256", - "out": [ - "v3" - ] - } + "in": [ + "0x00", + "v16" ], - "type": "FunctionCall" - } - ], - "entry": "Block0", - "numReturns": 1, - "type": "Function" - }, - "identity": { - "arguments": [ - "v0" - ], - "blocks": [ - { - "exit": { - "returnValues": [ - "v0" - ], - "type": "FunctionReturn" - }, - "id": "Block0", - "instructions": [] + "op": "slt", + "out": [ + "v17" + ] } ], - "entry": "Block0", - "numReturns": 1, - "type": "Function" + "type": "BuiltinCall" }, - "revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74": { - "arguments": [], - "blocks": [ + { + "exit": { + "type": "Terminated" + }, + "id": "Block5", + "instructions": [ { - "exit": { - "type": "Terminated" - }, - "id": "Block0", - "instructions": [ - { - "in": [ - "0x00", - "0x00" - ], - "op": "revert", - "out": [] - } + "in": [ + "0x00", + "0x00" ], - "type": "BuiltinCall" + "op": "revert", + "out": [] } ], - "entry": "Block0", - "numReturns": 0, - "type": "Function" + "type": "BuiltinCall" }, - "revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb": { - "arguments": [], - "blocks": [ + { + "exit": { + "type": "Terminated" + }, + "id": "Block9", + "instructions": [ { - "exit": { - "type": "Terminated" - }, - "id": "Block0", - "instructions": [ - { - "in": [ - "0x00", - "0x00" - ], - "op": "revert", - "out": [] - } + "in": [ + "0x2a", + "v0" ], - "type": "BuiltinCall" - } - ], - "entry": "Block0", - "numReturns": 0, - "type": "Function" - }, - "revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b": { - "arguments": [], - "blocks": [ + "op": "mstore", + "out": [] + }, { - "exit": { - "type": "Terminated" - }, - "id": "Block0", - "instructions": [ - { - "in": [ - "0x00", - "0x00" - ], - "op": "revert", - "out": [] - } + "in": [ + "0x20", + "v0" ], - "type": "BuiltinCall" + "op": "return", + "out": [] } ], - "entry": "Block0", - "numReturns": 0, - "type": "Function" + "type": "BuiltinCall" }, - "shift_right_224_unsigned": { - "arguments": [ - "v0" - ], - "blocks": [ + { + "exit": { + "type": "Terminated" + }, + "id": "Block8", + "instructions": [ { - "exit": { - "returnValues": [ - "v3" - ], - "type": "FunctionReturn" - }, - "id": "Block0", - "instructions": [ - { - "in": [ - "v0", - "0xe0" - ], - "op": "shr", - "out": [ - "v3" - ] - } + "in": [ + "0x00", + "0x00" ], - "type": "BuiltinCall" - } - ], - "entry": "Block0", - "numReturns": 1, - "type": "Function" - }, - "zero_value_for_split_t_uint256": { - "arguments": [], - "blocks": [ - { - "exit": { - "returnValues": [ - "0x00" - ], - "type": "FunctionReturn" - }, - "id": "Block0", - "instructions": [] + "op": "revert", + "out": [] } ], - "entry": "Block0", - "numReturns": 1, - "type": "Function" + "type": "BuiltinCall" } - } + ], + "functions": {} }, "subObjects": {}, "type": "subObject" diff --git a/test/cmdlineTests/yul_cfg_json_export/output b/test/cmdlineTests/yul_cfg_json_export/output index d8f2025b3ed3..8339d02c735f 100644 --- a/test/cmdlineTests/yul_cfg_json_export/output +++ b/test/cmdlineTests/yul_cfg_json_export/output @@ -17,7 +17,7 @@ Yul Control Flow Graph: "instructions": [ { "builtinArgs": [ - "128" + "0x80" ], "in": [], "op": "memoryguard", @@ -49,18 +49,6 @@ Yul Control Flow Graph: }, "id": "Block2", "instructions": [ - { - "in": [], - "op": "constructor_C_19", - "out": [] - }, - { - "in": [], - "op": "allocate_unbounded", - "out": [ - "v3" - ] - }, { "builtinArgs": [ "C_19_deployed" @@ -85,25 +73,15 @@ Yul Control Flow Graph: "in": [ "v4", "v5", - "v3" + "v0" ], "op": "codecopy", "out": [] }, - { - "builtinArgs": [ - "C_19_deployed" - ], - "in": [], - "op": "datasize", - "out": [ - "v6" - ] - }, { "in": [ - "v6", - "v3" + "v4", + "v0" ], "op": "return", "out": [] @@ -118,109 +96,18 @@ Yul Control Flow Graph: "id": "Block1", "instructions": [ { - "in": [], - "op": "revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb", + "in": [ + "0x00", + "0x00" + ], + "op": "revert", "out": [] } ], - "type": "FunctionCall" + "type": "BuiltinCall" } ], - "functions": { - "allocate_unbounded": { - "arguments": [], - "blocks": [ - { - "exit": { - "returnValues": [ - "v2" - ], - "type": "FunctionReturn" - }, - "id": "Block0", - "instructions": [ - { - "in": [ - "0x40" - ], - "op": "mload", - "out": [ - "v2" - ] - } - ], - "type": "BuiltinCall" - } - ], - "entry": "Block0", - "numReturns": 1, - "type": "Function" - }, - "constructor_C_19": { - "arguments": [], - "blocks": [ - { - "exit": { - "returnValues": [], - "type": "FunctionReturn" - }, - "id": "Block0", - "instructions": [ - { - "in": [], - "op": "constructor_I_7", - "out": [] - } - ], - "type": "FunctionCall" - } - ], - "entry": "Block0", - "numReturns": 0, - "type": "Function" - }, - "constructor_I_7": { - "arguments": [], - "blocks": [ - { - "exit": { - "returnValues": [], - "type": "FunctionReturn" - }, - "id": "Block0", - "instructions": [] - } - ], - "entry": "Block0", - "numReturns": 0, - "type": "Function" - }, - "revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb": { - "arguments": [], - "blocks": [ - { - "exit": { - "type": "Terminated" - }, - "id": "Block0", - "instructions": [ - { - "in": [ - "0x00", - "0x00" - ], - "op": "revert", - "out": [] - } - ], - "type": "BuiltinCall" - } - ], - "entry": "Block0", - "numReturns": 0, - "type": "Function" - } - } + "functions": {} }, "subObjects": { "C_19_deployed": { @@ -238,7 +125,7 @@ Yul Control Flow Graph: "instructions": [ { "builtinArgs": [ - "128" + "0x80" ], "in": [], "op": "memoryguard", @@ -290,19 +177,22 @@ Yul Control Flow Graph: "id": "Block2", "instructions": [ { - "in": [], - "op": "revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74", + "in": [ + "0x00", + "0x00" + ], + "op": "revert", "out": [] } ], - "type": "FunctionCall" + "type": "BuiltinCall" }, { "exit": { - "cond": "v9", + "cond": "v11", "targets": [ - "Block5", - "Block4" + "Block4", + "Block3" ], "type": "ConditionalJump" }, @@ -319,21 +209,22 @@ Yul Control Flow Graph: }, { "in": [ - "v7" + "v7", + "0xe0" ], - "op": "shift_right_224_unsigned", + "op": "shr", "out": [ - "v8" + "v9" ] }, { "in": [ - "0x26121ff0", - "v8" + "v9", + "0x26121ff0" ], "op": "eq", "out": [ - "v9" + "v11" ] } ], @@ -342,604 +233,145 @@ Yul Control Flow Graph: { "exit": { "targets": [ - "Block3" + "Block2" ], "type": "Jump" }, - "id": "Block5", + "id": "Block4", "instructions": [] }, { "exit": { - "type": "Terminated" + "cond": "v12", + "targets": [ + "Block6", + "Block5" + ], + "type": "ConditionalJump" }, - "id": "Block4", + "id": "Block3", "instructions": [ { "in": [], - "op": "external_fun_f_18", - "out": [] + "op": "callvalue", + "out": [ + "v12" + ] } ], - "type": "FunctionCall" + "type": "BuiltinCall" }, { "exit": { + "cond": "v17", "targets": [ - "Block2" + "Block9", + "Block8" ], - "type": "Jump" + "type": "ConditionalJump" }, - "id": "Block3", - "instructions": [] - } - ], - "functions": { - "abi_decode_tuple_": { - "arguments": [ - "v0", - "v1" - ], - "blocks": [ + "id": "Block6", + "instructions": [ { - "exit": { - "cond": "v4", - "targets": [ - "Block2", - "Block1" - ], - "type": "ConditionalJump" - }, - "id": "Block0", - "instructions": [ - { - "in": [ - "v0", - "v1" - ], - "op": "sub", - "out": [ - "v3" - ] - }, - { - "in": [ - "0x00", - "v3" - ], - "op": "slt", - "out": [ - "v4" - ] - } + "in": [ + "0x03" ], - "type": "BuiltinCall" + "op": "not", + "out": [ + "v14" + ] }, { - "exit": { - "returnValues": [], - "type": "FunctionReturn" - }, - "id": "Block2", - "instructions": [] + "in": [], + "op": "calldatasize", + "out": [ + "v15" + ] }, { - "exit": { - "type": "Terminated" - }, - "id": "Block1", - "instructions": [ - { - "in": [], - "op": "revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b", - "out": [] - } + "in": [ + "v14", + "v15" + ], + "op": "add", + "out": [ + "v16" + ] + }, + { + "in": [ + "0x00", + "v16" ], - "type": "FunctionCall" + "op": "slt", + "out": [ + "v17" + ] } ], - "entry": "Block0", - "numReturns": 0, - "type": "Function" + "type": "BuiltinCall" }, - "abi_encode_t_uint256_to_t_uint256_fromStack": { - "arguments": [ - "v0", - "v1" - ], - "blocks": [ + { + "exit": { + "type": "Terminated" + }, + "id": "Block5", + "instructions": [ { - "exit": { - "returnValues": [], - "type": "FunctionReturn" - }, - "id": "Block0", - "instructions": [ - { - "in": [ - "v0" - ], - "op": "cleanup_t_uint256", - "out": [ - "v2" - ] - }, - { - "in": [ - "v2", - "v1" - ], - "op": "mstore", - "out": [] - } + "in": [ + "0x00", + "0x00" ], - "type": "BuiltinCall" + "op": "revert", + "out": [] } ], - "entry": "Block0", - "numReturns": 0, - "type": "Function" + "type": "BuiltinCall" }, - "abi_encode_tuple_t_uint256__to_t_uint256__fromStack": { - "arguments": [ - "v0", - "v1" - ], - "blocks": [ + { + "exit": { + "type": "Terminated" + }, + "id": "Block9", + "instructions": [ { - "exit": { - "returnValues": [ - "v4" - ], - "type": "FunctionReturn" - }, - "id": "Block0", - "instructions": [ - { - "in": [ - "0x20", - "v0" - ], - "op": "add", - "out": [ - "v4" - ] - }, - { - "in": [ - "0x00", - "v0" - ], - "op": "add", - "out": [ - "v5" - ] - }, - { - "in": [ - "v5", - "v1" - ], - "op": "abi_encode_t_uint256_to_t_uint256_fromStack", - "out": [] - } + "in": [ + "0x2a", + "v0" ], - "type": "FunctionCall" + "op": "mstore", + "out": [] + }, + { + "in": [ + "0x20", + "v0" + ], + "op": "return", + "out": [] } ], - "entry": "Block0", - "numReturns": 1, - "type": "Function" - }, - "allocate_unbounded": { - "arguments": [], - "blocks": [ - { - "exit": { - "returnValues": [ - "v2" - ], - "type": "FunctionReturn" - }, - "id": "Block0", - "instructions": [ - { - "in": [ - "0x40" - ], - "op": "mload", - "out": [ - "v2" - ] - } - ], - "type": "BuiltinCall" - } - ], - "entry": "Block0", - "numReturns": 1, - "type": "Function" - }, - "cleanup_t_rational_42_by_1": { - "arguments": [ - "v0" - ], - "blocks": [ - { - "exit": { - "returnValues": [ - "v0" - ], - "type": "FunctionReturn" - }, - "id": "Block0", - "instructions": [] - } - ], - "entry": "Block0", - "numReturns": 1, - "type": "Function" - }, - "cleanup_t_uint256": { - "arguments": [ - "v0" - ], - "blocks": [ - { - "exit": { - "returnValues": [ - "v0" - ], - "type": "FunctionReturn" - }, - "id": "Block0", - "instructions": [] - } - ], - "entry": "Block0", - "numReturns": 1, - "type": "Function" - }, - "convert_t_rational_42_by_1_to_t_uint256": { - "arguments": [ - "v0" - ], - "blocks": [ - { - "exit": { - "returnValues": [ - "v4" - ], - "type": "FunctionReturn" - }, - "id": "Block0", - "instructions": [ - { - "in": [ - "v0" - ], - "op": "cleanup_t_rational_42_by_1", - "out": [ - "v2" - ] - }, - { - "in": [ - "v2" - ], - "op": "identity", - "out": [ - "v3" - ] - }, - { - "in": [ - "v3" - ], - "op": "cleanup_t_uint256", - "out": [ - "v4" - ] - } - ], - "type": "FunctionCall" - } - ], - "entry": "Block0", - "numReturns": 1, - "type": "Function" - }, - "external_fun_f_18": { - "arguments": [], - "blocks": [ - { - "exit": { - "cond": "v0", - "targets": [ - "Block2", - "Block1" - ], - "type": "ConditionalJump" - }, - "id": "Block0", - "instructions": [ - { - "in": [], - "op": "callvalue", - "out": [ - "v0" - ] - } - ], - "type": "BuiltinCall" - }, - { - "exit": { - "type": "Terminated" - }, - "id": "Block2", - "instructions": [ - { - "in": [], - "op": "calldatasize", - "out": [ - "v1" - ] - }, - { - "in": [ - "v1", - "0x04" - ], - "op": "abi_decode_tuple_", - "out": [] - }, - { - "in": [], - "op": "fun_f_18", - "out": [ - "v3" - ] - }, - { - "in": [], - "op": "allocate_unbounded", - "out": [ - "v4" - ] - }, - { - "in": [ - "v3", - "v4" - ], - "op": "abi_encode_tuple_t_uint256__to_t_uint256__fromStack", - "out": [ - "v5" - ] - }, - { - "in": [ - "v4", - "v5" - ], - "op": "sub", - "out": [ - "v6" - ] - }, - { - "in": [ - "v6", - "v4" - ], - "op": "return", - "out": [] - } - ], - "type": "BuiltinCall" - }, - { - "exit": { - "type": "Terminated" - }, - "id": "Block1", - "instructions": [ - { - "in": [], - "op": "revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb", - "out": [] - } - ], - "type": "FunctionCall" - } - ], - "entry": "Block0", - "numReturns": 0, - "type": "Function" - }, - "fun_f_18": { - "arguments": [], - "blocks": [ - { - "exit": { - "returnValues": [ - "v3" - ], - "type": "FunctionReturn" - }, - "id": "Block0", - "instructions": [ - { - "in": [], - "op": "zero_value_for_split_t_uint256", - "out": [ - "v1" - ] - }, - { - "in": [ - "0x2a" - ], - "op": "convert_t_rational_42_by_1_to_t_uint256", - "out": [ - "v3" - ] - } - ], - "type": "FunctionCall" - } - ], - "entry": "Block0", - "numReturns": 1, - "type": "Function" - }, - "identity": { - "arguments": [ - "v0" - ], - "blocks": [ - { - "exit": { - "returnValues": [ - "v0" - ], - "type": "FunctionReturn" - }, - "id": "Block0", - "instructions": [] - } - ], - "entry": "Block0", - "numReturns": 1, - "type": "Function" - }, - "revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74": { - "arguments": [], - "blocks": [ - { - "exit": { - "type": "Terminated" - }, - "id": "Block0", - "instructions": [ - { - "in": [ - "0x00", - "0x00" - ], - "op": "revert", - "out": [] - } - ], - "type": "BuiltinCall" - } - ], - "entry": "Block0", - "numReturns": 0, - "type": "Function" - }, - "revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb": { - "arguments": [], - "blocks": [ - { - "exit": { - "type": "Terminated" - }, - "id": "Block0", - "instructions": [ - { - "in": [ - "0x00", - "0x00" - ], - "op": "revert", - "out": [] - } - ], - "type": "BuiltinCall" - } - ], - "entry": "Block0", - "numReturns": 0, - "type": "Function" - }, - "revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b": { - "arguments": [], - "blocks": [ - { - "exit": { - "type": "Terminated" - }, - "id": "Block0", - "instructions": [ - { - "in": [ - "0x00", - "0x00" - ], - "op": "revert", - "out": [] - } - ], - "type": "BuiltinCall" - } - ], - "entry": "Block0", - "numReturns": 0, - "type": "Function" - }, - "shift_right_224_unsigned": { - "arguments": [ - "v0" - ], - "blocks": [ - { - "exit": { - "returnValues": [ - "v3" - ], - "type": "FunctionReturn" - }, - "id": "Block0", - "instructions": [ - { - "in": [ - "v0", - "0xe0" - ], - "op": "shr", - "out": [ - "v3" - ] - } - ], - "type": "BuiltinCall" - } - ], - "entry": "Block0", - "numReturns": 1, - "type": "Function" + "type": "BuiltinCall" }, - "zero_value_for_split_t_uint256": { - "arguments": [], - "blocks": [ + { + "exit": { + "type": "Terminated" + }, + "id": "Block8", + "instructions": [ { - "exit": { - "returnValues": [ - "0x00" - ], - "type": "FunctionReturn" - }, - "id": "Block0", - "instructions": [] + "in": [ + "0x00", + "0x00" + ], + "op": "revert", + "out": [] } ], - "entry": "Block0", - "numReturns": 1, - "type": "Function" + "type": "BuiltinCall" } - } + ], + "functions": {} }, "subObjects": {}, "type": "subObject" @@ -965,7 +397,7 @@ Yul Control Flow Graph: "instructions": [ { "builtinArgs": [ - "128" + "0x80" ], "in": [], "op": "memoryguard", @@ -997,18 +429,6 @@ Yul Control Flow Graph: }, "id": "Block2", "instructions": [ - { - "in": [], - "op": "constructor_D_38", - "out": [] - }, - { - "in": [], - "op": "allocate_unbounded", - "out": [ - "v3" - ] - }, { "builtinArgs": [ "D_38_deployed" @@ -1033,25 +453,15 @@ Yul Control Flow Graph: "in": [ "v4", "v5", - "v3" + "v0" ], "op": "codecopy", "out": [] }, - { - "builtinArgs": [ - "D_38_deployed" - ], - "in": [], - "op": "datasize", - "out": [ - "v6" - ] - }, { "in": [ - "v6", - "v3" + "v4", + "v0" ], "op": "return", "out": [] @@ -1066,86 +476,18 @@ Yul Control Flow Graph: "id": "Block1", "instructions": [ { - "in": [], - "op": "revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb", + "in": [ + "0x00", + "0x00" + ], + "op": "revert", "out": [] } ], - "type": "FunctionCall" + "type": "BuiltinCall" } ], - "functions": { - "allocate_unbounded": { - "arguments": [], - "blocks": [ - { - "exit": { - "returnValues": [ - "v2" - ], - "type": "FunctionReturn" - }, - "id": "Block0", - "instructions": [ - { - "in": [ - "0x40" - ], - "op": "mload", - "out": [ - "v2" - ] - } - ], - "type": "BuiltinCall" - } - ], - "entry": "Block0", - "numReturns": 1, - "type": "Function" - }, - "constructor_D_38": { - "arguments": [], - "blocks": [ - { - "exit": { - "returnValues": [], - "type": "FunctionReturn" - }, - "id": "Block0", - "instructions": [] - } - ], - "entry": "Block0", - "numReturns": 0, - "type": "Function" - }, - "revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb": { - "arguments": [], - "blocks": [ - { - "exit": { - "type": "Terminated" - }, - "id": "Block0", - "instructions": [ - { - "in": [ - "0x00", - "0x00" - ], - "op": "revert", - "out": [] - } - ], - "type": "BuiltinCall" - } - ], - "entry": "Block0", - "numReturns": 0, - "type": "Function" - } - } + "functions": {} }, "subObjects": { "D_38_deployed": { @@ -1153,1787 +495,947 @@ Yul Control Flow Graph: { "exit": { "cond": "v5", - "targets": [ - "Block2", - "Block1" - ], - "type": "ConditionalJump" - }, - "id": "Block0", - "instructions": [ - { - "builtinArgs": [ - "128" - ], - "in": [], - "op": "memoryguard", - "out": [ - "v0" - ] - }, - { - "in": [ - "v0", - "0x40" - ], - "op": "mstore", - "out": [] - }, - { - "in": [], - "op": "calldatasize", - "out": [ - "v3" - ] - }, - { - "in": [ - "0x04", - "v3" - ], - "op": "lt", - "out": [ - "v4" - ] - }, - { - "in": [ - "v4" - ], - "op": "iszero", - "out": [ - "v5" - ] - } - ], - "type": "BuiltinCall" - }, - { - "exit": { - "type": "Terminated" - }, - "id": "Block2", - "instructions": [ - { - "in": [], - "op": "revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74", - "out": [] - } - ], - "type": "FunctionCall" - }, - { - "exit": { - "cond": "v9", - "targets": [ - "Block5", - "Block4" - ], - "type": "ConditionalJump" - }, - "id": "Block1", - "instructions": [ - { - "in": [ - "0x00" - ], - "op": "calldataload", - "out": [ - "v7" - ] - }, - { - "in": [ - "v7" - ], - "op": "shift_right_224_unsigned", - "out": [ - "v8" - ] - }, - { - "in": [ - "0x26121ff0", - "v8" - ], - "op": "eq", - "out": [ - "v9" - ] - } - ], - "type": "BuiltinCall" - }, - { - "exit": { - "targets": [ - "Block3" - ], - "type": "Jump" - }, - "id": "Block5", - "instructions": [] - }, - { - "exit": { - "type": "Terminated" - }, - "id": "Block4", - "instructions": [ - { - "in": [], - "op": "external_fun_f_37", - "out": [] - } - ], - "type": "FunctionCall" - }, - { - "exit": { - "targets": [ - "Block2" - ], - "type": "Jump" - }, - "id": "Block3", - "instructions": [] - } - ], - "functions": { - "abi_decode_t_uint256_fromMemory": { - "arguments": [ - "v0", - "v1" - ], - "blocks": [ - { - "exit": { - "returnValues": [ - "v3" - ], - "type": "FunctionReturn" - }, - "id": "Block0", - "instructions": [ - { - "in": [ - "v0" - ], - "op": "mload", - "out": [ - "v3" - ] - }, - { - "in": [ - "v3" - ], - "op": "validator_revert_t_uint256", - "out": [] - } - ], - "type": "FunctionCall" - } - ], - "entry": "Block0", - "numReturns": 1, - "type": "Function" - }, - "abi_decode_tuple_": { - "arguments": [ - "v0", - "v1" - ], - "blocks": [ + "targets": [ + "Block2", + "Block1" + ], + "type": "ConditionalJump" + }, + "id": "Block0", + "instructions": [ { - "exit": { - "cond": "v4", - "targets": [ - "Block2", - "Block1" - ], - "type": "ConditionalJump" - }, - "id": "Block0", - "instructions": [ - { - "in": [ - "v0", - "v1" - ], - "op": "sub", - "out": [ - "v3" - ] - }, - { - "in": [ - "0x00", - "v3" - ], - "op": "slt", - "out": [ - "v4" - ] - } + "builtinArgs": [ + "0x80" ], - "type": "BuiltinCall" - }, - { - "exit": { - "returnValues": [], - "type": "FunctionReturn" - }, - "id": "Block2", - "instructions": [] + "in": [], + "op": "memoryguard", + "out": [ + "v0" + ] }, { - "exit": { - "type": "Terminated" - }, - "id": "Block1", - "instructions": [ - { - "in": [], - "op": "revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b", - "out": [] - } + "in": [ + "v0", + "0x40" ], - "type": "FunctionCall" - } - ], - "entry": "Block0", - "numReturns": 0, - "type": "Function" - }, - "abi_decode_tuple_t_uint256_fromMemory": { - "arguments": [ - "v0", - "v1" - ], - "blocks": [ + "op": "mstore", + "out": [] + }, { - "exit": { - "cond": "v5", - "targets": [ - "Block2", - "Block1" - ], - "type": "ConditionalJump" - }, - "id": "Block0", - "instructions": [ - { - "in": [ - "v0", - "v1" - ], - "op": "sub", - "out": [ - "v4" - ] - }, - { - "in": [ - "0x20", - "v4" - ], - "op": "slt", - "out": [ - "v5" - ] - } - ], - "type": "BuiltinCall" + "in": [], + "op": "calldatasize", + "out": [ + "v3" + ] }, { - "exit": { - "returnValues": [ - "v12" - ], - "type": "FunctionReturn" - }, - "id": "Block2", - "instructions": [ - { - "in": [ - "0x00", - "v0" - ], - "op": "add", - "out": [ - "v11" - ] - }, - { - "in": [ - "v1", - "v11" - ], - "op": "abi_decode_t_uint256_fromMemory", - "out": [ - "v12" - ] - } + "in": [ + "0x04", + "v3" ], - "type": "FunctionCall" + "op": "lt", + "out": [ + "v4" + ] }, { - "exit": { - "type": "Terminated" - }, - "id": "Block1", - "instructions": [ - { - "in": [], - "op": "revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b", - "out": [] - } + "in": [ + "v4" ], - "type": "FunctionCall" + "op": "iszero", + "out": [ + "v5" + ] } ], - "entry": "Block0", - "numReturns": 1, - "type": "Function" + "type": "BuiltinCall" }, - "abi_encode_t_uint256_to_t_uint256_fromStack": { - "arguments": [ - "v0", - "v1" - ], - "blocks": [ + { + "exit": { + "type": "Terminated" + }, + "id": "Block2", + "instructions": [ { - "exit": { - "returnValues": [], - "type": "FunctionReturn" - }, - "id": "Block0", - "instructions": [ - { - "in": [ - "v0" - ], - "op": "cleanup_t_uint256", - "out": [ - "v2" - ] - }, - { - "in": [ - "v2", - "v1" - ], - "op": "mstore", - "out": [] - } + "in": [ + "0x00", + "0x00" ], - "type": "BuiltinCall" + "op": "revert", + "out": [] } ], - "entry": "Block0", - "numReturns": 0, - "type": "Function" + "type": "BuiltinCall" }, - "abi_encode_tuple__to__fromStack": { - "arguments": [ - "v0" - ], - "blocks": [ + { + "exit": { + "cond": "v11", + "targets": [ + "Block4", + "Block3" + ], + "type": "ConditionalJump" + }, + "id": "Block1", + "instructions": [ { - "exit": { - "returnValues": [ - "v2" - ], - "type": "FunctionReturn" - }, - "id": "Block0", - "instructions": [ - { - "in": [ - "0x00", - "v0" - ], - "op": "add", - "out": [ - "v2" - ] - } + "in": [ + "0x00" ], - "type": "BuiltinCall" - } - ], - "entry": "Block0", - "numReturns": 1, - "type": "Function" - }, - "abi_encode_tuple_t_uint256__to_t_uint256__fromStack": { - "arguments": [ - "v0", - "v1" - ], - "blocks": [ + "op": "calldataload", + "out": [ + "v7" + ] + }, { - "exit": { - "returnValues": [ - "v4" - ], - "type": "FunctionReturn" - }, - "id": "Block0", - "instructions": [ - { - "in": [ - "0x20", - "v0" - ], - "op": "add", - "out": [ - "v4" - ] - }, - { - "in": [ - "0x00", - "v0" - ], - "op": "add", - "out": [ - "v5" - ] - }, - { - "in": [ - "v5", - "v1" - ], - "op": "abi_encode_t_uint256_to_t_uint256_fromStack", - "out": [] - } + "in": [ + "v7", + "0xe0" + ], + "op": "shr", + "out": [ + "v9" + ] + }, + { + "in": [ + "v9", + "0x26121ff0" ], - "type": "FunctionCall" + "op": "eq", + "out": [ + "v11" + ] } ], - "entry": "Block0", - "numReturns": 1, - "type": "Function" + "type": "BuiltinCall" }, - "allocate_unbounded": { - "arguments": [], - "blocks": [ + { + "exit": { + "targets": [ + "Block2" + ], + "type": "Jump" + }, + "id": "Block4", + "instructions": [] + }, + { + "exit": { + "cond": "v12", + "targets": [ + "Block6", + "Block5" + ], + "type": "ConditionalJump" + }, + "id": "Block3", + "instructions": [ { - "exit": { - "returnValues": [ - "v2" - ], - "type": "FunctionReturn" - }, - "id": "Block0", - "instructions": [ - { - "in": [ - "0x40" - ], - "op": "mload", - "out": [ - "v2" - ] - } - ], - "type": "BuiltinCall" + "in": [], + "op": "callvalue", + "out": [ + "v12" + ] } ], - "entry": "Block0", - "numReturns": 1, - "type": "Function" + "type": "BuiltinCall" }, - "cleanup_t_uint160": { - "arguments": [ - "v0" - ], - "blocks": [ + { + "exit": { + "cond": "v17", + "targets": [ + "Block9", + "Block8" + ], + "type": "ConditionalJump" + }, + "id": "Block6", + "instructions": [ { - "exit": { - "returnValues": [ - "v3" - ], - "type": "FunctionReturn" - }, - "id": "Block0", - "instructions": [ - { - "in": [ - "0xffffffffffffffffffffffffffffffffffffffff", - "v0" - ], - "op": "and", - "out": [ - "v3" - ] - } + "in": [ + "0x03" ], - "type": "BuiltinCall" - } - ], - "entry": "Block0", - "numReturns": 1, - "type": "Function" - }, - "cleanup_t_uint256": { - "arguments": [ - "v0" - ], - "blocks": [ + "op": "not", + "out": [ + "v14" + ] + }, { - "exit": { - "returnValues": [ - "v0" - ], - "type": "FunctionReturn" - }, - "id": "Block0", - "instructions": [] - } - ], - "entry": "Block0", - "numReturns": 1, - "type": "Function" - }, - "convert_t_contract$_C_$19_to_t_address": { - "arguments": [ - "v0" - ], - "blocks": [ + "in": [], + "op": "calldatasize", + "out": [ + "v15" + ] + }, { - "exit": { - "returnValues": [ - "v2" - ], - "type": "FunctionReturn" - }, - "id": "Block0", - "instructions": [ - { - "in": [ - "v0" - ], - "op": "convert_t_uint160_to_t_address", - "out": [ - "v2" - ] - } + "in": [ + "v14", + "v15" ], - "type": "FunctionCall" - } - ], - "entry": "Block0", - "numReturns": 1, - "type": "Function" - }, - "convert_t_uint160_to_t_address": { - "arguments": [ - "v0" - ], - "blocks": [ + "op": "add", + "out": [ + "v16" + ] + }, { - "exit": { - "returnValues": [ - "v2" - ], - "type": "FunctionReturn" - }, - "id": "Block0", - "instructions": [ - { - "in": [ - "v0" - ], - "op": "convert_t_uint160_to_t_uint160", - "out": [ - "v2" - ] - } + "in": [ + "0x00", + "v16" ], - "type": "FunctionCall" + "op": "slt", + "out": [ + "v17" + ] } ], - "entry": "Block0", - "numReturns": 1, - "type": "Function" + "type": "BuiltinCall" }, - "convert_t_uint160_to_t_uint160": { - "arguments": [ - "v0" - ], - "blocks": [ + { + "exit": { + "type": "Terminated" + }, + "id": "Block5", + "instructions": [ { - "exit": { - "returnValues": [ - "v4" - ], - "type": "FunctionReturn" - }, - "id": "Block0", - "instructions": [ - { - "in": [ - "v0" - ], - "op": "cleanup_t_uint160", - "out": [ - "v2" - ] - }, - { - "in": [ - "v2" - ], - "op": "identity", - "out": [ - "v3" - ] - }, - { - "in": [ - "v3" - ], - "op": "cleanup_t_uint160", - "out": [ - "v4" - ] - } + "in": [ + "0x00", + "0x00" ], - "type": "FunctionCall" + "op": "revert", + "out": [] } ], - "entry": "Block0", - "numReturns": 1, - "type": "Function" + "type": "BuiltinCall" }, - "external_fun_f_37": { - "arguments": [], - "blocks": [ + { + "exit": { + "cond": "v28", + "targets": [ + "Block12", + "Block11" + ], + "type": "ConditionalJump" + }, + "id": "Block9", + "instructions": [ { - "exit": { - "cond": "v0", - "targets": [ - "Block2", - "Block1" - ], - "type": "ConditionalJump" - }, - "id": "Block0", - "instructions": [ - { - "in": [], - "op": "callvalue", - "out": [ - "v0" - ] - } + "builtinArgs": [ + "C_19" ], - "type": "BuiltinCall" + "in": [], + "op": "datasize", + "out": [ + "v18" + ] }, { - "exit": { - "type": "Terminated" - }, - "id": "Block2", - "instructions": [ - { - "in": [], - "op": "calldatasize", - "out": [ - "v1" - ] - }, - { - "in": [ - "v1", - "0x04" - ], - "op": "abi_decode_tuple_", - "out": [] - }, - { - "in": [], - "op": "fun_f_37", - "out": [ - "v3" - ] - }, - { - "in": [], - "op": "allocate_unbounded", - "out": [ - "v4" - ] - }, - { - "in": [ - "v3", - "v4" - ], - "op": "abi_encode_tuple_t_uint256__to_t_uint256__fromStack", - "out": [ - "v5" - ] - }, - { - "in": [ - "v4", - "v5" - ], - "op": "sub", - "out": [ - "v6" - ] - }, - { - "in": [ - "v6", - "v4" - ], - "op": "return", - "out": [] - } + "in": [ + "v18", + "v0" + ], + "op": "add", + "out": [ + "v24" + ] + }, + { + "in": [ + "v0", + "v24" ], - "type": "BuiltinCall" + "op": "lt", + "out": [ + "v25" + ] }, { - "exit": { - "type": "Terminated" - }, - "id": "Block1", - "instructions": [ - { - "in": [], - "op": "revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb", - "out": [] - } + "in": [ + "0xffffffffffffffff", + "v24" ], - "type": "FunctionCall" + "op": "gt", + "out": [ + "v27" + ] + }, + { + "in": [ + "v25", + "v27" + ], + "op": "or", + "out": [ + "v28" + ] } ], - "entry": "Block0", - "numReturns": 0, - "type": "Function" + "type": "BuiltinCall" }, - "finalize_allocation": { - "arguments": [ - "v0", - "v1" + { + "exit": { + "type": "Terminated" + }, + "id": "Block8", + "instructions": [ + { + "in": [ + "0x00", + "0x00" + ], + "op": "revert", + "out": [] + } ], - "blocks": [ + "type": "BuiltinCall" + }, + { + "exit": { + "cond": "v42", + "targets": [ + "Block15", + "Block14" + ], + "type": "ConditionalJump" + }, + "id": "Block12", + "instructions": [ { - "exit": { - "cond": "v7", - "targets": [ - "Block2", - "Block1" - ], - "type": "ConditionalJump" - }, - "id": "Block0", - "instructions": [ - { - "in": [ - "v1" - ], - "op": "round_up_to_mul_of_32", - "out": [ - "v2" - ] - }, - { - "in": [ - "v2", - "v0" - ], - "op": "add", - "out": [ - "v3" - ] - }, - { - "in": [ - "v0", - "v3" - ], - "op": "lt", - "out": [ - "v4" - ] - }, - { - "in": [ - "0xffffffffffffffff", - "v3" - ], - "op": "gt", - "out": [ - "v6" - ] - }, - { - "in": [ - "v4", - "v6" - ], - "op": "or", - "out": [ - "v7" - ] - } + "builtinArgs": [ + "C_19" ], - "type": "BuiltinCall" + "in": [], + "op": "dataoffset", + "out": [ + "v35" + ] }, { - "exit": { - "returnValues": [], - "type": "FunctionReturn" - }, - "id": "Block2", - "instructions": [ - { - "in": [ - "v3", - "0x40" - ], - "op": "mstore", - "out": [] - } + "in": [ + "v18", + "v35", + "v0" ], - "type": "BuiltinCall" + "op": "datacopy", + "out": [] }, { - "exit": { - "type": "Terminated" - }, - "id": "Block1", - "instructions": [ - { - "in": [], - "op": "panic_error_0x41", - "out": [] - } + "in": [ + "v0", + "v24" ], - "type": "FunctionCall" - } - ], - "entry": "Block0", - "numReturns": 0, - "type": "Function" - }, - "fun_f_37": { - "arguments": [], - "blocks": [ + "op": "sub", + "out": [ + "v40" + ] + }, { - "exit": { - "cond": "v8", - "targets": [ - "Block2", - "Block1" - ], - "type": "ConditionalJump" - }, - "id": "Block0", - "instructions": [ - { - "in": [], - "op": "zero_value_for_split_t_uint256", - "out": [ - "v1" - ] - }, - { - "in": [], - "op": "allocate_unbounded", - "out": [ - "v2" - ] - }, - { - "builtinArgs": [ - "C_19" - ], - "in": [], - "op": "datasize", - "out": [ - "v3" - ] - }, - { - "in": [ - "v3", - "v2" - ], - "op": "add", - "out": [ - "v4" - ] - }, - { - "in": [ - "v2", - "v4" - ], - "op": "lt", - "out": [ - "v5" - ] - }, - { - "in": [ - "0xffffffffffffffff", - "v4" - ], - "op": "gt", - "out": [ - "v7" - ] - }, - { - "in": [ - "v5", - "v7" - ], - "op": "or", - "out": [ - "v8" - ] - } + "in": [ + "v40", + "v0", + "0x00" ], - "type": "BuiltinCall" + "op": "create", + "out": [ + "v41" + ] }, { - "exit": { - "cond": "v19", - "targets": [ - "Block5", - "Block4" - ], - "type": "ConditionalJump" - }, - "id": "Block2", - "instructions": [ - { - "builtinArgs": [ - "C_19" - ], - "in": [], - "op": "datasize", - "out": [ - "v9" - ] - }, - { - "builtinArgs": [ - "C_19" - ], - "in": [], - "op": "dataoffset", - "out": [ - "v10" - ] - }, - { - "in": [ - "v9", - "v10", - "v2" - ], - "op": "datacopy", - "out": [] - }, - { - "in": [ - "v4" - ], - "op": "abi_encode_tuple__to__fromStack", - "out": [ - "v16" - ] - }, - { - "in": [ - "v2", - "v16" - ], - "op": "sub", - "out": [ - "v17" - ] - }, - { - "in": [ - "v17", - "v2", - "0x00" - ], - "op": "create", - "out": [ - "v18" - ] - }, - { - "in": [ - "v18" - ], - "op": "iszero", - "out": [ - "v19" - ] - } + "in": [ + "v41" ], - "type": "BuiltinCall" + "op": "iszero", + "out": [ + "v42" + ] + } + ], + "type": "BuiltinCall" + }, + { + "exit": { + "type": "Terminated" + }, + "id": "Block11", + "instructions": [ + { + "in": [ + "0x4e487b71", + "0xe0" + ], + "op": "shl", + "out": [ + "v30" + ] }, { - "exit": { - "type": "Terminated" - }, - "id": "Block1", - "instructions": [ - { - "in": [], - "op": "panic_error_0x41", - "out": [] - } + "in": [ + "v30", + "0x00" ], - "type": "FunctionCall" + "op": "mstore", + "out": [] }, { - "exit": { - "cond": "v33", - "targets": [ - "Block8", - "Block7" - ], - "type": "ConditionalJump" - }, - "id": "Block5", - "instructions": [ - { - "in": [ - "v18" - ], - "op": "convert_t_contract$_C_$19_to_t_address", - "out": [ - "v22" - ] - }, - { - "in": [], - "op": "allocate_unbounded", - "out": [ - "v24" - ] - }, - { - "in": [ - "0x26121ff0" - ], - "op": "shift_left_224", - "out": [ - "v25" - ] - }, - { - "in": [ - "v25", - "v24" - ], - "op": "mstore", - "out": [] - }, - { - "in": [ - "0x04", - "v24" - ], - "op": "add", - "out": [ - "v27" - ] - }, - { - "in": [ - "v27" - ], - "op": "abi_encode_tuple__to__fromStack", - "out": [ - "v28" - ] - }, - { - "in": [ - "v24", - "v28" - ], - "op": "sub", - "out": [ - "v30" - ] - }, - { - "in": [], - "op": "gas", - "out": [ - "v31" - ] - }, - { - "in": [ - "0x20", - "v24", - "v30", - "v24", - "v22", - "v31" - ], - "op": "staticcall", - "out": [ - "v32" - ] - }, - { - "in": [ - "v32" - ], - "op": "iszero", - "out": [ - "v33" - ] - } + "in": [ + "0x41", + "0x04" ], - "type": "BuiltinCall" + "op": "mstore", + "out": [] }, { - "exit": { - "type": "Terminated" - }, - "id": "Block4", - "instructions": [ - { - "in": [], - "op": "revert_forward_1", - "out": [] - } + "in": [ + "0x24", + "0x00" + ], + "op": "revert", + "out": [] + } + ], + "type": "BuiltinCall" + }, + { + "exit": { + "cond": "v60", + "targets": [ + "Block18", + "Block17" + ], + "type": "ConditionalJump" + }, + "id": "Block15", + "instructions": [ + { + "in": [ + "0x40" ], - "type": "FunctionCall" + "op": "mload", + "out": [ + "v46" + ] }, { - "exit": { - "cond": "v32", - "targets": [ - "Block11", - "Block10" - ], - "type": "ConditionalJump" - }, - "id": "Block8", - "instructions": [] + "in": [ + "0x026121ff", + "0xe4" + ], + "op": "shl", + "out": [ + "v49" + ] }, { - "exit": { - "type": "Terminated" - }, - "id": "Block7", - "instructions": [ - { - "in": [], - "op": "revert_forward_1", - "out": [] - } + "in": [ + "v49", + "v46" ], - "type": "FunctionCall" + "op": "mstore", + "out": [] }, { - "entries": [ - "Block8", - "Block13" + "in": [ + "0x01", + "0xa0" ], - "exit": { - "returnValues": [ - "v45" - ], - "type": "FunctionReturn" - }, - "id": "Block11", - "instructions": [ - { - "in": [ - "0x00", - "v44" - ], - "op": "PhiFunction", - "out": [ - "v45" - ] - } + "op": "shl", + "out": [ + "v53" ] }, { - "exit": { - "cond": "v37", - "targets": [ - "Block13", - "Block12" - ], - "type": "ConditionalJump" - }, - "id": "Block10", - "instructions": [ - { - "in": [], - "op": "returndatasize", - "out": [ - "v36" - ] - }, - { - "in": [ - "v36", - "0x20" - ], - "op": "gt", - "out": [ - "v37" - ] - } + "in": [ + "0x01", + "v53" ], - "type": "BuiltinCall" + "op": "sub", + "out": [ + "v54" + ] }, { - "entries": [ - "Block10", - "Block12" + "in": [ + "v54", + "v41" ], - "exit": { - "targets": [ - "Block11" - ], - "type": "Jump" - }, - "id": "Block13", - "instructions": [ - { - "in": [ - "0x20", - "v38" - ], - "op": "PhiFunction", - "out": [ - "v39" - ] - }, - { - "in": [ - "v39", - "v24" - ], - "op": "finalize_allocation", - "out": [] - }, - { - "in": [ - "v39", - "v24" - ], - "op": "add", - "out": [ - "v43" - ] - }, - { - "in": [ - "v43", - "v24" - ], - "op": "abi_decode_tuple_t_uint256_fromMemory", - "out": [ - "v44" - ] - } + "op": "and", + "out": [ + "v57" + ] + }, + { + "in": [], + "op": "gas", + "out": [ + "v58" + ] + }, + { + "in": [ + "0x20", + "v46", + "0x04", + "v46", + "v57", + "v58" + ], + "op": "staticcall", + "out": [ + "v59" + ] + }, + { + "in": [ + "v59" + ], + "op": "iszero", + "out": [ + "v60" + ] + } + ], + "type": "BuiltinCall" + }, + { + "exit": { + "type": "Terminated" + }, + "id": "Block14", + "instructions": [ + { + "in": [ + "0x40" + ], + "op": "mload", + "out": [ + "v43" + ] + }, + { + "in": [], + "op": "returndatasize", + "out": [ + "v44" + ] + }, + { + "in": [ + "v44", + "0x00", + "v43" ], - "type": "FunctionCall" + "op": "returndatacopy", + "out": [] }, { - "exit": { - "targets": [ - "Block13" - ], - "type": "Jump" - }, - "id": "Block12", - "instructions": [ - { - "in": [], - "op": "returndatasize", - "out": [ - "v38" - ] - } + "in": [], + "op": "returndatasize", + "out": [ + "v45" + ] + }, + { + "in": [ + "v45", + "v43" ], - "type": "BuiltinCall" + "op": "revert", + "out": [] } ], - "entry": "Block0", - "numReturns": 1, - "type": "Function" + "type": "BuiltinCall" }, - "identity": { - "arguments": [ - "v0" - ], - "blocks": [ - { - "exit": { - "returnValues": [ - "v0" - ], - "type": "FunctionReturn" - }, - "id": "Block0", - "instructions": [] - } - ], - "entry": "Block0", - "numReturns": 1, - "type": "Function" + { + "exit": { + "cond": "v59", + "targets": [ + "Block21", + "Block20" + ], + "type": "ConditionalJump" + }, + "id": "Block18", + "instructions": [] }, - "panic_error_0x41": { - "arguments": [], - "blocks": [ + { + "exit": { + "type": "Terminated" + }, + "id": "Block17", + "instructions": [ { - "exit": { - "type": "Terminated" - }, - "id": "Block0", - "instructions": [ - { - "in": [ - "0x4e487b7100000000000000000000000000000000000000000000000000000000", - "0x00" - ], - "op": "mstore", - "out": [] - }, - { - "in": [ - "0x41", - "0x04" - ], - "op": "mstore", - "out": [] - }, - { - "in": [ - "0x24", - "0x00" - ], - "op": "revert", - "out": [] - } + "in": [ + "0x40" ], - "type": "BuiltinCall" - } - ], - "entry": "Block0", - "numReturns": 0, - "type": "Function" - }, - "revert_error_0cc013b6b3b6beabea4e3a74a6d380f0df81852ca99887912475e1f66b2a2c20": { - "arguments": [], - "blocks": [ + "op": "mload", + "out": [ + "v61" + ] + }, { - "exit": { - "type": "Terminated" - }, - "id": "Block0", - "instructions": [ - { - "in": [ - "0x00", - "0x00" - ], - "op": "revert", - "out": [] - } + "in": [], + "op": "returndatasize", + "out": [ + "v62" + ] + }, + { + "in": [ + "v62", + "0x00", + "v61" ], - "type": "BuiltinCall" - } - ], - "entry": "Block0", - "numReturns": 0, - "type": "Function" - }, - "revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74": { - "arguments": [], - "blocks": [ + "op": "returndatacopy", + "out": [] + }, { - "exit": { - "type": "Terminated" - }, - "id": "Block0", - "instructions": [ - { - "in": [ - "0x00", - "0x00" - ], - "op": "revert", - "out": [] - } + "in": [], + "op": "returndatasize", + "out": [ + "v63" + ] + }, + { + "in": [ + "v63", + "v61" ], - "type": "BuiltinCall" + "op": "revert", + "out": [] } ], - "entry": "Block0", - "numReturns": 0, - "type": "Function" + "type": "BuiltinCall" }, - "revert_error_c1322bf8034eace5e0b5c7295db60986aa89aae5e0ea0873e4689e076861a5db": { - "arguments": [], - "blocks": [ + { + "entries": [ + "Block18", + "Block28" + ], + "exit": { + "type": "Terminated" + }, + "id": "Block21", + "instructions": [ { - "exit": { - "type": "Terminated" - }, - "id": "Block0", - "instructions": [ - { - "in": [ - "0x00", - "0x00" - ], - "op": "revert", - "out": [] - } + "in": [ + "0x00", + "v93" ], - "type": "BuiltinCall" - } - ], - "entry": "Block0", - "numReturns": 0, - "type": "Function" - }, - "revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb": { - "arguments": [], - "blocks": [ + "op": "PhiFunction", + "out": [ + "v95" + ] + }, { - "exit": { - "type": "Terminated" - }, - "id": "Block0", - "instructions": [ - { - "in": [ - "0x00", - "0x00" - ], - "op": "revert", - "out": [] - } + "in": [ + "0x40" ], - "type": "BuiltinCall" - } - ], - "entry": "Block0", - "numReturns": 0, - "type": "Function" - }, - "revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b": { - "arguments": [], - "blocks": [ + "op": "mload", + "out": [ + "v94" + ] + }, { - "exit": { - "type": "Terminated" - }, - "id": "Block0", - "instructions": [ - { - "in": [ - "0x00", - "0x00" - ], - "op": "revert", - "out": [] - } + "in": [ + "v95", + "v94" ], - "type": "BuiltinCall" + "op": "mstore", + "out": [] + }, + { + "in": [ + "0x20", + "v94" + ], + "op": "return", + "out": [] } ], - "entry": "Block0", - "numReturns": 0, - "type": "Function" + "type": "BuiltinCall" }, - "revert_forward_1": { - "arguments": [], - "blocks": [ - { - "exit": { - "type": "Terminated" - }, - "id": "Block0", - "instructions": [ - { - "in": [], - "op": "allocate_unbounded", - "out": [ - "v0" - ] - }, - { - "in": [], - "op": "returndatasize", - "out": [ - "v1" - ] - }, - { - "in": [ - "v1", - "0x00", - "v0" - ], - "op": "returndatacopy", - "out": [] - }, - { - "in": [], - "op": "returndatasize", - "out": [ - "v3" - ] - }, - { - "in": [ - "v3", - "v0" - ], - "op": "revert", - "out": [] - } + { + "exit": { + "cond": "v67", + "targets": [ + "Block23", + "Block22" + ], + "type": "ConditionalJump" + }, + "id": "Block20", + "instructions": [ + { + "in": [], + "op": "returndatasize", + "out": [ + "v66" + ] + }, + { + "in": [ + "v66", + "0x20" ], - "type": "BuiltinCall" + "op": "gt", + "out": [ + "v67" + ] } ], - "entry": "Block0", - "numReturns": 0, - "type": "Function" + "type": "BuiltinCall" }, - "round_up_to_mul_of_32": { - "arguments": [ - "v0" + { + "entries": [ + "Block20", + "Block22" ], - "blocks": [ + "exit": { + "cond": "v80", + "targets": [ + "Block25", + "Block24" + ], + "type": "ConditionalJump" + }, + "id": "Block23", + "instructions": [ { - "exit": { - "returnValues": [ - "v5" - ], - "type": "FunctionReturn" - }, - "id": "Block0", - "instructions": [ - { - "in": [ - "0x1f" - ], - "op": "not", - "out": [ - "v3" - ] - }, - { - "in": [ - "0x1f", - "v0" - ], - "op": "add", - "out": [ - "v4" - ] - }, - { - "in": [ - "v3", - "v4" - ], - "op": "and", - "out": [ - "v5" - ] - } + "in": [ + "0x20", + "v68" ], - "type": "BuiltinCall" + "op": "PhiFunction", + "out": [ + "v71" + ] + }, + { + "in": [ + "0x1f" + ], + "op": "not", + "out": [ + "v70" + ] + }, + { + "in": [ + "0x1f", + "v71" + ], + "op": "add", + "out": [ + "v72" + ] + }, + { + "in": [ + "v70", + "v72" + ], + "op": "and", + "out": [ + "v73" + ] + }, + { + "in": [ + "v73", + "v46" + ], + "op": "add", + "out": [ + "v77" + ] + }, + { + "in": [ + "v46", + "v77" + ], + "op": "lt", + "out": [ + "v78" + ] + }, + { + "in": [ + "0xffffffffffffffff", + "v77" + ], + "op": "gt", + "out": [ + "v79" + ] + }, + { + "in": [ + "v78", + "v79" + ], + "op": "or", + "out": [ + "v80" + ] } ], - "entry": "Block0", - "numReturns": 1, - "type": "Function" + "type": "BuiltinCall" }, - "shift_left_224": { - "arguments": [ - "v0" - ], - "blocks": [ + { + "exit": { + "targets": [ + "Block23" + ], + "type": "Jump" + }, + "id": "Block22", + "instructions": [ { - "exit": { - "returnValues": [ - "v3" - ], - "type": "FunctionReturn" - }, - "id": "Block0", - "instructions": [ - { - "in": [ - "v0", - "0xe0" - ], - "op": "shl", - "out": [ - "v3" - ] - } - ], - "type": "BuiltinCall" + "in": [], + "op": "returndatasize", + "out": [ + "v68" + ] } ], - "entry": "Block0", - "numReturns": 1, - "type": "Function" + "type": "BuiltinCall" }, - "shift_right_224_unsigned": { - "arguments": [ - "v0" - ], - "blocks": [ + { + "exit": { + "cond": "v90", + "targets": [ + "Block28", + "Block27" + ], + "type": "ConditionalJump" + }, + "id": "Block25", + "instructions": [ { - "exit": { - "returnValues": [ - "v3" - ], - "type": "FunctionReturn" - }, - "id": "Block0", - "instructions": [ - { - "in": [ - "v0", - "0xe0" - ], - "op": "shr", - "out": [ - "v3" - ] - } + "in": [ + "v77", + "0x40" ], - "type": "BuiltinCall" + "op": "mstore", + "out": [] + }, + { + "in": [ + "v71", + "v46" + ], + "op": "add", + "out": [ + "v88" + ] + }, + { + "in": [ + "v46", + "v88" + ], + "op": "sub", + "out": [ + "v89" + ] + }, + { + "in": [ + "0x20", + "v89" + ], + "op": "slt", + "out": [ + "v90" + ] } ], - "entry": "Block0", - "numReturns": 1, - "type": "Function" + "type": "BuiltinCall" }, - "validator_revert_t_uint256": { - "arguments": [ - "v0" - ], - "blocks": [ + { + "exit": { + "type": "Terminated" + }, + "id": "Block24", + "instructions": [ { - "exit": { - "cond": "v3", - "targets": [ - "Block2", - "Block1" - ], - "type": "ConditionalJump" - }, - "id": "Block0", - "instructions": [ - { - "in": [ - "v0" - ], - "op": "cleanup_t_uint256", - "out": [ - "v1" - ] - }, - { - "in": [ - "v1", - "v0" - ], - "op": "eq", - "out": [ - "v2" - ] - }, - { - "in": [ - "v2" - ], - "op": "iszero", - "out": [ - "v3" - ] - } + "in": [ + "0x4e487b71", + "0xe0" ], - "type": "BuiltinCall" + "op": "shl", + "out": [ + "v81" + ] }, { - "exit": { - "returnValues": [], - "type": "FunctionReturn" - }, - "id": "Block2", - "instructions": [] + "in": [ + "v81", + "0x00" + ], + "op": "mstore", + "out": [] }, { - "exit": { - "type": "Terminated" - }, - "id": "Block1", - "instructions": [ - { - "in": [ - "0x00", - "0x00" - ], - "op": "revert", - "out": [] - } + "in": [ + "0x41", + "0x04" + ], + "op": "mstore", + "out": [] + }, + { + "in": [ + "0x24", + "0x00" + ], + "op": "revert", + "out": [] + } + ], + "type": "BuiltinCall" + }, + { + "exit": { + "targets": [ + "Block21" + ], + "type": "Jump" + }, + "id": "Block28", + "instructions": [ + { + "in": [ + "v46" ], - "type": "BuiltinCall" + "op": "mload", + "out": [ + "v93" + ] } ], - "entry": "Block0", - "numReturns": 0, - "type": "Function" + "type": "BuiltinCall" }, - "zero_value_for_split_t_uint256": { - "arguments": [], - "blocks": [ + { + "exit": { + "type": "Terminated" + }, + "id": "Block27", + "instructions": [ { - "exit": { - "returnValues": [ - "0x00" - ], - "type": "FunctionReturn" - }, - "id": "Block0", - "instructions": [] + "in": [ + "0x00", + "0x00" + ], + "op": "revert", + "out": [] } ], - "entry": "Block0", - "numReturns": 1, - "type": "Function" + "type": "BuiltinCall" } - } + ], + "functions": {} }, "subObjects": { "C_19": { @@ -2951,7 +1453,7 @@ Yul Control Flow Graph: "instructions": [ { "builtinArgs": [ - "128" + "0x80" ], "in": [], "op": "memoryguard", @@ -2983,18 +1485,6 @@ Yul Control Flow Graph: }, "id": "Block2", "instructions": [ - { - "in": [], - "op": "constructor_C_19", - "out": [] - }, - { - "in": [], - "op": "allocate_unbounded", - "out": [ - "v3" - ] - }, { "builtinArgs": [ "C_19_deployed" @@ -3019,25 +1509,15 @@ Yul Control Flow Graph: "in": [ "v4", "v5", - "v3" + "v0" ], "op": "codecopy", "out": [] }, - { - "builtinArgs": [ - "C_19_deployed" - ], - "in": [], - "op": "datasize", - "out": [ - "v6" - ] - }, { "in": [ - "v6", - "v3" + "v4", + "v0" ], "op": "return", "out": [] @@ -3052,109 +1532,18 @@ Yul Control Flow Graph: "id": "Block1", "instructions": [ { - "in": [], - "op": "revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb", + "in": [ + "0x00", + "0x00" + ], + "op": "revert", "out": [] } ], - "type": "FunctionCall" + "type": "BuiltinCall" } ], - "functions": { - "allocate_unbounded": { - "arguments": [], - "blocks": [ - { - "exit": { - "returnValues": [ - "v2" - ], - "type": "FunctionReturn" - }, - "id": "Block0", - "instructions": [ - { - "in": [ - "0x40" - ], - "op": "mload", - "out": [ - "v2" - ] - } - ], - "type": "BuiltinCall" - } - ], - "entry": "Block0", - "numReturns": 1, - "type": "Function" - }, - "constructor_C_19": { - "arguments": [], - "blocks": [ - { - "exit": { - "returnValues": [], - "type": "FunctionReturn" - }, - "id": "Block0", - "instructions": [ - { - "in": [], - "op": "constructor_I_7", - "out": [] - } - ], - "type": "FunctionCall" - } - ], - "entry": "Block0", - "numReturns": 0, - "type": "Function" - }, - "constructor_I_7": { - "arguments": [], - "blocks": [ - { - "exit": { - "returnValues": [], - "type": "FunctionReturn" - }, - "id": "Block0", - "instructions": [] - } - ], - "entry": "Block0", - "numReturns": 0, - "type": "Function" - }, - "revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb": { - "arguments": [], - "blocks": [ - { - "exit": { - "type": "Terminated" - }, - "id": "Block0", - "instructions": [ - { - "in": [ - "0x00", - "0x00" - ], - "op": "revert", - "out": [] - } - ], - "type": "BuiltinCall" - } - ], - "entry": "Block0", - "numReturns": 0, - "type": "Function" - } - } + "functions": {} }, "subObjects": { "C_19_deployed": { @@ -3172,7 +1561,7 @@ Yul Control Flow Graph: "instructions": [ { "builtinArgs": [ - "128" + "0x80" ], "in": [], "op": "memoryguard", @@ -3224,19 +1613,22 @@ Yul Control Flow Graph: "id": "Block2", "instructions": [ { - "in": [], - "op": "revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74", + "in": [ + "0x00", + "0x00" + ], + "op": "revert", "out": [] } ], - "type": "FunctionCall" + "type": "BuiltinCall" }, { "exit": { - "cond": "v9", + "cond": "v11", "targets": [ - "Block5", - "Block4" + "Block4", + "Block3" ], "type": "ConditionalJump" }, @@ -3253,21 +1645,22 @@ Yul Control Flow Graph: }, { "in": [ - "v7" + "v7", + "0xe0" ], - "op": "shift_right_224_unsigned", + "op": "shr", "out": [ - "v8" + "v9" ] }, { "in": [ - "0x26121ff0", - "v8" + "v9", + "0x26121ff0" ], "op": "eq", "out": [ - "v9" + "v11" ] } ], @@ -3276,604 +1669,145 @@ Yul Control Flow Graph: { "exit": { "targets": [ - "Block3" + "Block2" ], "type": "Jump" }, - "id": "Block5", + "id": "Block4", "instructions": [] }, { "exit": { - "type": "Terminated" + "cond": "v12", + "targets": [ + "Block6", + "Block5" + ], + "type": "ConditionalJump" }, - "id": "Block4", + "id": "Block3", "instructions": [ { "in": [], - "op": "external_fun_f_18", - "out": [] + "op": "callvalue", + "out": [ + "v12" + ] } ], - "type": "FunctionCall" + "type": "BuiltinCall" }, { "exit": { + "cond": "v17", "targets": [ - "Block2" + "Block9", + "Block8" ], - "type": "Jump" + "type": "ConditionalJump" }, - "id": "Block3", - "instructions": [] - } - ], - "functions": { - "abi_decode_tuple_": { - "arguments": [ - "v0", - "v1" - ], - "blocks": [ + "id": "Block6", + "instructions": [ { - "exit": { - "cond": "v4", - "targets": [ - "Block2", - "Block1" - ], - "type": "ConditionalJump" - }, - "id": "Block0", - "instructions": [ - { - "in": [ - "v0", - "v1" - ], - "op": "sub", - "out": [ - "v3" - ] - }, - { - "in": [ - "0x00", - "v3" - ], - "op": "slt", - "out": [ - "v4" - ] - } + "in": [ + "0x03" ], - "type": "BuiltinCall" - }, - { - "exit": { - "returnValues": [], - "type": "FunctionReturn" - }, - "id": "Block2", - "instructions": [] + "op": "not", + "out": [ + "v14" + ] }, { - "exit": { - "type": "Terminated" - }, - "id": "Block1", - "instructions": [ - { - "in": [], - "op": "revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b", - "out": [] - } - ], - "type": "FunctionCall" - } - ], - "entry": "Block0", - "numReturns": 0, - "type": "Function" - }, - "abi_encode_t_uint256_to_t_uint256_fromStack": { - "arguments": [ - "v0", - "v1" - ], - "blocks": [ - { - "exit": { - "returnValues": [], - "type": "FunctionReturn" - }, - "id": "Block0", - "instructions": [ - { - "in": [ - "v0" - ], - "op": "cleanup_t_uint256", - "out": [ - "v2" - ] - }, - { - "in": [ - "v2", - "v1" - ], - "op": "mstore", - "out": [] - } - ], - "type": "BuiltinCall" - } - ], - "entry": "Block0", - "numReturns": 0, - "type": "Function" - }, - "abi_encode_tuple_t_uint256__to_t_uint256__fromStack": { - "arguments": [ - "v0", - "v1" - ], - "blocks": [ - { - "exit": { - "returnValues": [ - "v4" - ], - "type": "FunctionReturn" - }, - "id": "Block0", - "instructions": [ - { - "in": [ - "0x20", - "v0" - ], - "op": "add", - "out": [ - "v4" - ] - }, - { - "in": [ - "0x00", - "v0" - ], - "op": "add", - "out": [ - "v5" - ] - }, - { - "in": [ - "v5", - "v1" - ], - "op": "abi_encode_t_uint256_to_t_uint256_fromStack", - "out": [] - } - ], - "type": "FunctionCall" - } - ], - "entry": "Block0", - "numReturns": 1, - "type": "Function" - }, - "allocate_unbounded": { - "arguments": [], - "blocks": [ - { - "exit": { - "returnValues": [ - "v2" - ], - "type": "FunctionReturn" - }, - "id": "Block0", - "instructions": [ - { - "in": [ - "0x40" - ], - "op": "mload", - "out": [ - "v2" - ] - } - ], - "type": "BuiltinCall" - } - ], - "entry": "Block0", - "numReturns": 1, - "type": "Function" - }, - "cleanup_t_rational_42_by_1": { - "arguments": [ - "v0" - ], - "blocks": [ - { - "exit": { - "returnValues": [ - "v0" - ], - "type": "FunctionReturn" - }, - "id": "Block0", - "instructions": [] - } - ], - "entry": "Block0", - "numReturns": 1, - "type": "Function" - }, - "cleanup_t_uint256": { - "arguments": [ - "v0" - ], - "blocks": [ - { - "exit": { - "returnValues": [ - "v0" - ], - "type": "FunctionReturn" - }, - "id": "Block0", - "instructions": [] - } - ], - "entry": "Block0", - "numReturns": 1, - "type": "Function" - }, - "convert_t_rational_42_by_1_to_t_uint256": { - "arguments": [ - "v0" - ], - "blocks": [ - { - "exit": { - "returnValues": [ - "v4" - ], - "type": "FunctionReturn" - }, - "id": "Block0", - "instructions": [ - { - "in": [ - "v0" - ], - "op": "cleanup_t_rational_42_by_1", - "out": [ - "v2" - ] - }, - { - "in": [ - "v2" - ], - "op": "identity", - "out": [ - "v3" - ] - }, - { - "in": [ - "v3" - ], - "op": "cleanup_t_uint256", - "out": [ - "v4" - ] - } - ], - "type": "FunctionCall" - } - ], - "entry": "Block0", - "numReturns": 1, - "type": "Function" - }, - "external_fun_f_18": { - "arguments": [], - "blocks": [ - { - "exit": { - "cond": "v0", - "targets": [ - "Block2", - "Block1" - ], - "type": "ConditionalJump" - }, - "id": "Block0", - "instructions": [ - { - "in": [], - "op": "callvalue", - "out": [ - "v0" - ] - } - ], - "type": "BuiltinCall" + "in": [], + "op": "calldatasize", + "out": [ + "v15" + ] }, { - "exit": { - "type": "Terminated" - }, - "id": "Block2", - "instructions": [ - { - "in": [], - "op": "calldatasize", - "out": [ - "v1" - ] - }, - { - "in": [ - "v1", - "0x04" - ], - "op": "abi_decode_tuple_", - "out": [] - }, - { - "in": [], - "op": "fun_f_18", - "out": [ - "v3" - ] - }, - { - "in": [], - "op": "allocate_unbounded", - "out": [ - "v4" - ] - }, - { - "in": [ - "v3", - "v4" - ], - "op": "abi_encode_tuple_t_uint256__to_t_uint256__fromStack", - "out": [ - "v5" - ] - }, - { - "in": [ - "v4", - "v5" - ], - "op": "sub", - "out": [ - "v6" - ] - }, - { - "in": [ - "v6", - "v4" - ], - "op": "return", - "out": [] - } + "in": [ + "v14", + "v15" ], - "type": "BuiltinCall" + "op": "add", + "out": [ + "v16" + ] }, { - "exit": { - "type": "Terminated" - }, - "id": "Block1", - "instructions": [ - { - "in": [], - "op": "revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb", - "out": [] - } - ], - "type": "FunctionCall" - } - ], - "entry": "Block0", - "numReturns": 0, - "type": "Function" - }, - "fun_f_18": { - "arguments": [], - "blocks": [ - { - "exit": { - "returnValues": [ - "v3" - ], - "type": "FunctionReturn" - }, - "id": "Block0", - "instructions": [ - { - "in": [], - "op": "zero_value_for_split_t_uint256", - "out": [ - "v1" - ] - }, - { - "in": [ - "0x2a" - ], - "op": "convert_t_rational_42_by_1_to_t_uint256", - "out": [ - "v3" - ] - } + "in": [ + "0x00", + "v16" ], - "type": "FunctionCall" - } - ], - "entry": "Block0", - "numReturns": 1, - "type": "Function" - }, - "identity": { - "arguments": [ - "v0" - ], - "blocks": [ - { - "exit": { - "returnValues": [ - "v0" - ], - "type": "FunctionReturn" - }, - "id": "Block0", - "instructions": [] + "op": "slt", + "out": [ + "v17" + ] } ], - "entry": "Block0", - "numReturns": 1, - "type": "Function" + "type": "BuiltinCall" }, - "revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74": { - "arguments": [], - "blocks": [ + { + "exit": { + "type": "Terminated" + }, + "id": "Block5", + "instructions": [ { - "exit": { - "type": "Terminated" - }, - "id": "Block0", - "instructions": [ - { - "in": [ - "0x00", - "0x00" - ], - "op": "revert", - "out": [] - } + "in": [ + "0x00", + "0x00" ], - "type": "BuiltinCall" + "op": "revert", + "out": [] } ], - "entry": "Block0", - "numReturns": 0, - "type": "Function" + "type": "BuiltinCall" }, - "revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb": { - "arguments": [], - "blocks": [ + { + "exit": { + "type": "Terminated" + }, + "id": "Block9", + "instructions": [ { - "exit": { - "type": "Terminated" - }, - "id": "Block0", - "instructions": [ - { - "in": [ - "0x00", - "0x00" - ], - "op": "revert", - "out": [] - } + "in": [ + "0x2a", + "v0" ], - "type": "BuiltinCall" - } - ], - "entry": "Block0", - "numReturns": 0, - "type": "Function" - }, - "revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b": { - "arguments": [], - "blocks": [ + "op": "mstore", + "out": [] + }, { - "exit": { - "type": "Terminated" - }, - "id": "Block0", - "instructions": [ - { - "in": [ - "0x00", - "0x00" - ], - "op": "revert", - "out": [] - } + "in": [ + "0x20", + "v0" ], - "type": "BuiltinCall" + "op": "return", + "out": [] } ], - "entry": "Block0", - "numReturns": 0, - "type": "Function" + "type": "BuiltinCall" }, - "shift_right_224_unsigned": { - "arguments": [ - "v0" - ], - "blocks": [ + { + "exit": { + "type": "Terminated" + }, + "id": "Block8", + "instructions": [ { - "exit": { - "returnValues": [ - "v3" - ], - "type": "FunctionReturn" - }, - "id": "Block0", - "instructions": [ - { - "in": [ - "v0", - "0xe0" - ], - "op": "shr", - "out": [ - "v3" - ] - } + "in": [ + "0x00", + "0x00" ], - "type": "BuiltinCall" - } - ], - "entry": "Block0", - "numReturns": 1, - "type": "Function" - }, - "zero_value_for_split_t_uint256": { - "arguments": [], - "blocks": [ - { - "exit": { - "returnValues": [ - "0x00" - ], - "type": "FunctionReturn" - }, - "id": "Block0", - "instructions": [] + "op": "revert", + "out": [] } ], - "entry": "Block0", - "numReturns": 1, - "type": "Function" + "type": "BuiltinCall" } - } + ], + "functions": {} }, "subObjects": {}, "type": "subObject" From 8da621c41d67d8ee5a74157f28efa670a7370746 Mon Sep 17 00:00:00 2001 From: r0qs Date: Wed, 4 Dec 2024 12:26:00 +0700 Subject: [PATCH 0608/1022] Export liveness information of Yul SSA CFG (#15608) Export SSA CFG liveness data --- libyul/YulControlFlowGraphExporter.cpp | 33 +- libyul/YulControlFlowGraphExporter.h | 9 +- libyul/YulStack.cpp | 3 +- .../standard_yul_cfg_json_export/output.json | 314 +++++++++++++++++- .../strict_asm_yul_cfg_json_export/output | 70 +++- test/cmdlineTests/yul_cfg_json_export/output | 314 +++++++++++++++++- 6 files changed, 721 insertions(+), 22 deletions(-) diff --git a/libyul/YulControlFlowGraphExporter.cpp b/libyul/YulControlFlowGraphExporter.cpp index 17737533fd16..65c0805f984a 100644 --- a/libyul/YulControlFlowGraphExporter.cpp +++ b/libyul/YulControlFlowGraphExporter.cpp @@ -31,7 +31,7 @@ using namespace solidity::langutil; using namespace solidity::util; using namespace solidity::yul; -YulControlFlowGraphExporter::YulControlFlowGraphExporter(ControlFlow const& _controlFlow): m_controlFlow(_controlFlow) +YulControlFlowGraphExporter::YulControlFlowGraphExporter(ControlFlow const& _controlFlow, ControlFlowLiveness const* _liveness): m_controlFlow(_controlFlow), m_liveness(_liveness) { } @@ -58,18 +58,22 @@ std::string YulControlFlowGraphExporter::varToString(SSACFG const& _cfg, SSACFG: Json YulControlFlowGraphExporter::run() { + if (m_liveness) + yulAssert(&m_liveness->controlFlow.get() == &m_controlFlow); + Json yulObjectJson = Json::object(); - yulObjectJson["blocks"] = exportBlock(*m_controlFlow.mainGraph, SSACFG::BlockId{0}); + yulObjectJson["blocks"] = exportBlock(*m_controlFlow.mainGraph, SSACFG::BlockId{0}, m_liveness ? m_liveness->mainLiveness.get() : nullptr); Json functionsJson = Json::object(); + size_t index = 0; for (auto const& [function, functionGraph]: m_controlFlow.functionGraphMapping) - functionsJson[function->name.str()] = exportFunction(*functionGraph); + functionsJson[function->name.str()] = exportFunction(*functionGraph, m_liveness ? m_liveness->functionLiveness[index++].get() : nullptr); yulObjectJson["functions"] = functionsJson; return yulObjectJson; } -Json YulControlFlowGraphExporter::exportFunction(SSACFG const& _cfg) +Json YulControlFlowGraphExporter::exportFunction(SSACFG const& _cfg, SSACFGLiveness const* _liveness) { Json functionJson = Json::object(); functionJson["type"] = "Function"; @@ -77,18 +81,18 @@ Json YulControlFlowGraphExporter::exportFunction(SSACFG const& _cfg) static auto constexpr argsTransform = [](auto const& _arg) { return fmt::format("v{}", std::get<1>(_arg).value); }; functionJson["arguments"] = _cfg.arguments | ranges::views::transform(argsTransform) | ranges::to; functionJson["numReturns"] = _cfg.returns.size(); - functionJson["blocks"] = exportBlock(_cfg, _cfg.entry); + functionJson["blocks"] = exportBlock(_cfg, _cfg.entry, _liveness); return functionJson; } -Json YulControlFlowGraphExporter::exportBlock(SSACFG const& _cfg, SSACFG::BlockId _entryId) +Json YulControlFlowGraphExporter::exportBlock(SSACFG const& _cfg, SSACFG::BlockId _entryId, SSACFGLiveness const* _liveness) { Json blocksJson = Json::array(); util::BreadthFirstSearch bfs{{{_entryId}}}; bfs.run([&](SSACFG::BlockId _blockId, auto _addChild) { auto const& block = _cfg.block(_blockId); // Convert current block to JSON - Json blockJson = toJson(_cfg, _blockId); + Json blockJson = toJson(_cfg, _blockId, _liveness); Json exitBlockJson = Json::object(); std::visit(util::GenericVisitor{ @@ -128,12 +132,25 @@ Json YulControlFlowGraphExporter::exportBlock(SSACFG const& _cfg, SSACFG::BlockI return blocksJson; } -Json YulControlFlowGraphExporter::toJson(SSACFG const& _cfg, SSACFG::BlockId _blockId) +Json YulControlFlowGraphExporter::toJson(SSACFG const& _cfg, SSACFG::BlockId _blockId, SSACFGLiveness const* _liveness) { + auto const valueToString = [&](SSACFG::ValueId const& valueId) { return varToString(_cfg, valueId); }; + Json blockJson = Json::object(); auto const& block = _cfg.block(_blockId); blockJson["id"] = "Block" + std::to_string(_blockId.value); + if (_liveness) + { + Json livenessJson = Json::object(); + livenessJson["in"] = _liveness->liveIn(_blockId) + | ranges::views::transform(valueToString) + | ranges::to(); + livenessJson["out"] = _liveness->liveOut(_blockId) + | ranges::views::transform(valueToString) + | ranges::to(); + blockJson["liveness"] = livenessJson; + } blockJson["instructions"] = Json::array(); if (!block.phis.empty()) { diff --git a/libyul/YulControlFlowGraphExporter.h b/libyul/YulControlFlowGraphExporter.h index 37520e194b21..91f9d040e404 100644 --- a/libyul/YulControlFlowGraphExporter.h +++ b/libyul/YulControlFlowGraphExporter.h @@ -28,15 +28,16 @@ using namespace yul; class YulControlFlowGraphExporter { public: - YulControlFlowGraphExporter(ControlFlow const& _controlFlow); + YulControlFlowGraphExporter(ControlFlow const& _controlFlow, ControlFlowLiveness const* _liveness=nullptr); Json run(); - Json exportBlock(SSACFG const& _cfg, SSACFG::BlockId _blockId); - Json exportFunction(SSACFG const& _cfg); + Json exportBlock(SSACFG const& _cfg, SSACFG::BlockId _blockId, SSACFGLiveness const* _liveness); + Json exportFunction(SSACFG const& _cfg, SSACFGLiveness const* _liveness); std::string varToString(SSACFG const& _cfg, SSACFG::ValueId _var); private: ControlFlow const& m_controlFlow; - Json toJson(SSACFG const& _cfg, SSACFG::BlockId _blockId); + ControlFlowLiveness const* m_liveness; + Json toJson(SSACFG const& _cfg, SSACFG::BlockId _blockId, SSACFGLiveness const* _liveness); Json toJson(Json& _ret, SSACFG const& _cfg, SSACFG::Operation const& _operation); Json toJson(SSACFG const& _cfg, std::vector const& _values); }; diff --git a/libyul/YulStack.cpp b/libyul/YulStack.cpp index a7bf415a5aa4..22c1fcb7dcc4 100644 --- a/libyul/YulStack.cpp +++ b/libyul/YulStack.cpp @@ -389,7 +389,8 @@ Json YulStack::cfgJson() const languageToDialect(m_language, m_evmVersion, m_eofVersion), _object.code()->root() ); - YulControlFlowGraphExporter exporter(*controlFlow); + std::unique_ptr liveness = std::make_unique(*controlFlow); + YulControlFlowGraphExporter exporter(*controlFlow, liveness.get()); return exporter.run(); }; diff --git a/test/cmdlineTests/standard_yul_cfg_json_export/output.json b/test/cmdlineTests/standard_yul_cfg_json_export/output.json index c224164c52ec..fc47f4f7b937 100644 --- a/test/cmdlineTests/standard_yul_cfg_json_export/output.json +++ b/test/cmdlineTests/standard_yul_cfg_json_export/output.json @@ -42,6 +42,12 @@ ] } ], + "liveness": { + "in": [], + "out": [ + "v0" + ] + }, "type": "BuiltinCall" }, { @@ -88,6 +94,12 @@ "out": [] } ], + "liveness": { + "in": [ + "v0" + ], + "out": [] + }, "type": "BuiltinCall" }, { @@ -105,6 +117,10 @@ "out": [] } ], + "liveness": { + "in": [], + "out": [] + }, "type": "BuiltinCall" } ], @@ -169,6 +185,12 @@ ] } ], + "liveness": { + "in": [], + "out": [ + "v0" + ] + }, "type": "BuiltinCall" }, { @@ -186,6 +208,10 @@ "out": [] } ], + "liveness": { + "in": [], + "out": [] + }, "type": "BuiltinCall" }, { @@ -229,6 +255,14 @@ ] } ], + "liveness": { + "in": [ + "v0" + ], + "out": [ + "v0" + ] + }, "type": "BuiltinCall" }, { @@ -239,7 +273,11 @@ "type": "Jump" }, "id": "Block4", - "instructions": [] + "instructions": [], + "liveness": { + "in": [], + "out": [] + } }, { "exit": { @@ -260,6 +298,14 @@ ] } ], + "liveness": { + "in": [ + "v0" + ], + "out": [ + "v0" + ] + }, "type": "BuiltinCall" }, { @@ -310,6 +356,14 @@ ] } ], + "liveness": { + "in": [ + "v0" + ], + "out": [ + "v0" + ] + }, "type": "BuiltinCall" }, { @@ -327,6 +381,10 @@ "out": [] } ], + "liveness": { + "in": [], + "out": [] + }, "type": "BuiltinCall" }, { @@ -352,6 +410,12 @@ "out": [] } ], + "liveness": { + "in": [ + "v0" + ], + "out": [] + }, "type": "BuiltinCall" }, { @@ -369,6 +433,10 @@ "out": [] } ], + "liveness": { + "in": [], + "out": [] + }, "type": "BuiltinCall" } ], @@ -421,6 +489,12 @@ ] } ], + "liveness": { + "in": [], + "out": [ + "v0" + ] + }, "type": "BuiltinCall" }, { @@ -467,6 +541,12 @@ "out": [] } ], + "liveness": { + "in": [ + "v0" + ], + "out": [] + }, "type": "BuiltinCall" }, { @@ -484,6 +564,10 @@ "out": [] } ], + "liveness": { + "in": [], + "out": [] + }, "type": "BuiltinCall" } ], @@ -548,6 +632,12 @@ ] } ], + "liveness": { + "in": [], + "out": [ + "v0" + ] + }, "type": "BuiltinCall" }, { @@ -565,6 +655,10 @@ "out": [] } ], + "liveness": { + "in": [], + "out": [] + }, "type": "BuiltinCall" }, { @@ -608,6 +702,14 @@ ] } ], + "liveness": { + "in": [ + "v0" + ], + "out": [ + "v0" + ] + }, "type": "BuiltinCall" }, { @@ -618,7 +720,11 @@ "type": "Jump" }, "id": "Block4", - "instructions": [] + "instructions": [], + "liveness": { + "in": [], + "out": [] + } }, { "exit": { @@ -639,6 +745,14 @@ ] } ], + "liveness": { + "in": [ + "v0" + ], + "out": [ + "v0" + ] + }, "type": "BuiltinCall" }, { @@ -689,6 +803,14 @@ ] } ], + "liveness": { + "in": [ + "v0" + ], + "out": [ + "v0" + ] + }, "type": "BuiltinCall" }, { @@ -706,6 +828,10 @@ "out": [] } ], + "liveness": { + "in": [], + "out": [] + }, "type": "BuiltinCall" }, { @@ -770,6 +896,16 @@ ] } ], + "liveness": { + "in": [ + "v0" + ], + "out": [ + "v0", + "v18", + "v24" + ] + }, "type": "BuiltinCall" }, { @@ -787,6 +923,10 @@ "out": [] } ], + "liveness": { + "in": [], + "out": [] + }, "type": "BuiltinCall" }, { @@ -850,6 +990,16 @@ ] } ], + "liveness": { + "in": [ + "v0", + "v18", + "v24" + ], + "out": [ + "v41" + ] + }, "type": "BuiltinCall" }, { @@ -893,6 +1043,10 @@ "out": [] } ], + "liveness": { + "in": [], + "out": [] + }, "type": "BuiltinCall" }, { @@ -994,6 +1148,14 @@ ] } ], + "liveness": { + "in": [ + "v41" + ], + "out": [ + "v46" + ] + }, "type": "BuiltinCall" }, { @@ -1043,6 +1205,10 @@ "out": [] } ], + "liveness": { + "in": [], + "out": [] + }, "type": "BuiltinCall" }, { @@ -1055,7 +1221,15 @@ "type": "ConditionalJump" }, "id": "Block18", - "instructions": [] + "instructions": [], + "liveness": { + "in": [ + "v46" + ], + "out": [ + "v46" + ] + } }, { "exit": { @@ -1104,6 +1278,10 @@ "out": [] } ], + "liveness": { + "in": [], + "out": [] + }, "type": "BuiltinCall" }, { @@ -1152,6 +1330,12 @@ "out": [] } ], + "liveness": { + "in": [ + "v95" + ], + "out": [] + }, "type": "BuiltinCall" }, { @@ -1183,6 +1367,14 @@ ] } ], + "liveness": { + "in": [ + "v46" + ], + "out": [ + "v46" + ] + }, "type": "BuiltinCall" }, { @@ -1280,6 +1472,17 @@ ] } ], + "liveness": { + "in": [ + "v46", + "v71" + ], + "out": [ + "v46", + "v71", + "v77" + ] + }, "type": "BuiltinCall" }, { @@ -1299,6 +1502,15 @@ ] } ], + "liveness": { + "in": [ + "v46" + ], + "out": [ + "v46", + "v68" + ] + }, "type": "BuiltinCall" }, { @@ -1351,6 +1563,16 @@ ] } ], + "liveness": { + "in": [ + "v46", + "v71", + "v77" + ], + "out": [ + "v46" + ] + }, "type": "BuiltinCall" }, { @@ -1394,6 +1616,10 @@ "out": [] } ], + "liveness": { + "in": [], + "out": [] + }, "type": "BuiltinCall" }, { @@ -1415,6 +1641,14 @@ ] } ], + "liveness": { + "in": [ + "v46" + ], + "out": [ + "v93" + ] + }, "type": "BuiltinCall" }, { @@ -1432,6 +1666,10 @@ "out": [] } ], + "liveness": { + "in": [], + "out": [] + }, "type": "BuiltinCall" } ], @@ -1477,6 +1715,12 @@ ] } ], + "liveness": { + "in": [], + "out": [ + "v0" + ] + }, "type": "BuiltinCall" }, { @@ -1523,6 +1767,12 @@ "out": [] } ], + "liveness": { + "in": [ + "v0" + ], + "out": [] + }, "type": "BuiltinCall" }, { @@ -1540,6 +1790,10 @@ "out": [] } ], + "liveness": { + "in": [], + "out": [] + }, "type": "BuiltinCall" } ], @@ -1604,6 +1858,12 @@ ] } ], + "liveness": { + "in": [], + "out": [ + "v0" + ] + }, "type": "BuiltinCall" }, { @@ -1621,6 +1881,10 @@ "out": [] } ], + "liveness": { + "in": [], + "out": [] + }, "type": "BuiltinCall" }, { @@ -1664,6 +1928,14 @@ ] } ], + "liveness": { + "in": [ + "v0" + ], + "out": [ + "v0" + ] + }, "type": "BuiltinCall" }, { @@ -1674,7 +1946,11 @@ "type": "Jump" }, "id": "Block4", - "instructions": [] + "instructions": [], + "liveness": { + "in": [], + "out": [] + } }, { "exit": { @@ -1695,6 +1971,14 @@ ] } ], + "liveness": { + "in": [ + "v0" + ], + "out": [ + "v0" + ] + }, "type": "BuiltinCall" }, { @@ -1745,6 +2029,14 @@ ] } ], + "liveness": { + "in": [ + "v0" + ], + "out": [ + "v0" + ] + }, "type": "BuiltinCall" }, { @@ -1762,6 +2054,10 @@ "out": [] } ], + "liveness": { + "in": [], + "out": [] + }, "type": "BuiltinCall" }, { @@ -1787,6 +2083,12 @@ "out": [] } ], + "liveness": { + "in": [ + "v0" + ], + "out": [] + }, "type": "BuiltinCall" }, { @@ -1804,6 +2106,10 @@ "out": [] } ], + "liveness": { + "in": [], + "out": [] + }, "type": "BuiltinCall" } ], diff --git a/test/cmdlineTests/strict_asm_yul_cfg_json_export/output b/test/cmdlineTests/strict_asm_yul_cfg_json_export/output index 18fa4288c5a2..ac154fc16246 100644 --- a/test/cmdlineTests/strict_asm_yul_cfg_json_export/output +++ b/test/cmdlineTests/strict_asm_yul_cfg_json_export/output @@ -42,6 +42,12 @@ Yul Control Flow Graph: ] } ], + "liveness": { + "in": [], + "out": [ + "v0" + ] + }, "type": "BuiltinCall" }, { @@ -88,6 +94,12 @@ Yul Control Flow Graph: "out": [] } ], + "liveness": { + "in": [ + "v0" + ], + "out": [] + }, "type": "BuiltinCall" }, { @@ -105,6 +117,10 @@ Yul Control Flow Graph: "out": [] } ], + "liveness": { + "in": [], + "out": [] + }, "type": "BuiltinCall" } ], @@ -169,6 +185,12 @@ Yul Control Flow Graph: ] } ], + "liveness": { + "in": [], + "out": [ + "v0" + ] + }, "type": "BuiltinCall" }, { @@ -186,6 +208,10 @@ Yul Control Flow Graph: "out": [] } ], + "liveness": { + "in": [], + "out": [] + }, "type": "BuiltinCall" }, { @@ -229,6 +255,14 @@ Yul Control Flow Graph: ] } ], + "liveness": { + "in": [ + "v0" + ], + "out": [ + "v0" + ] + }, "type": "BuiltinCall" }, { @@ -239,7 +273,11 @@ Yul Control Flow Graph: "type": "Jump" }, "id": "Block4", - "instructions": [] + "instructions": [], + "liveness": { + "in": [], + "out": [] + } }, { "exit": { @@ -260,6 +298,14 @@ Yul Control Flow Graph: ] } ], + "liveness": { + "in": [ + "v0" + ], + "out": [ + "v0" + ] + }, "type": "BuiltinCall" }, { @@ -310,6 +356,14 @@ Yul Control Flow Graph: ] } ], + "liveness": { + "in": [ + "v0" + ], + "out": [ + "v0" + ] + }, "type": "BuiltinCall" }, { @@ -327,6 +381,10 @@ Yul Control Flow Graph: "out": [] } ], + "liveness": { + "in": [], + "out": [] + }, "type": "BuiltinCall" }, { @@ -352,6 +410,12 @@ Yul Control Flow Graph: "out": [] } ], + "liveness": { + "in": [ + "v0" + ], + "out": [] + }, "type": "BuiltinCall" }, { @@ -369,6 +433,10 @@ Yul Control Flow Graph: "out": [] } ], + "liveness": { + "in": [], + "out": [] + }, "type": "BuiltinCall" } ], diff --git a/test/cmdlineTests/yul_cfg_json_export/output b/test/cmdlineTests/yul_cfg_json_export/output index 8339d02c735f..6848d7db9ddb 100644 --- a/test/cmdlineTests/yul_cfg_json_export/output +++ b/test/cmdlineTests/yul_cfg_json_export/output @@ -41,6 +41,12 @@ Yul Control Flow Graph: ] } ], + "liveness": { + "in": [], + "out": [ + "v0" + ] + }, "type": "BuiltinCall" }, { @@ -87,6 +93,12 @@ Yul Control Flow Graph: "out": [] } ], + "liveness": { + "in": [ + "v0" + ], + "out": [] + }, "type": "BuiltinCall" }, { @@ -104,6 +116,10 @@ Yul Control Flow Graph: "out": [] } ], + "liveness": { + "in": [], + "out": [] + }, "type": "BuiltinCall" } ], @@ -168,6 +184,12 @@ Yul Control Flow Graph: ] } ], + "liveness": { + "in": [], + "out": [ + "v0" + ] + }, "type": "BuiltinCall" }, { @@ -185,6 +207,10 @@ Yul Control Flow Graph: "out": [] } ], + "liveness": { + "in": [], + "out": [] + }, "type": "BuiltinCall" }, { @@ -228,6 +254,14 @@ Yul Control Flow Graph: ] } ], + "liveness": { + "in": [ + "v0" + ], + "out": [ + "v0" + ] + }, "type": "BuiltinCall" }, { @@ -238,7 +272,11 @@ Yul Control Flow Graph: "type": "Jump" }, "id": "Block4", - "instructions": [] + "instructions": [], + "liveness": { + "in": [], + "out": [] + } }, { "exit": { @@ -259,6 +297,14 @@ Yul Control Flow Graph: ] } ], + "liveness": { + "in": [ + "v0" + ], + "out": [ + "v0" + ] + }, "type": "BuiltinCall" }, { @@ -309,6 +355,14 @@ Yul Control Flow Graph: ] } ], + "liveness": { + "in": [ + "v0" + ], + "out": [ + "v0" + ] + }, "type": "BuiltinCall" }, { @@ -326,6 +380,10 @@ Yul Control Flow Graph: "out": [] } ], + "liveness": { + "in": [], + "out": [] + }, "type": "BuiltinCall" }, { @@ -351,6 +409,12 @@ Yul Control Flow Graph: "out": [] } ], + "liveness": { + "in": [ + "v0" + ], + "out": [] + }, "type": "BuiltinCall" }, { @@ -368,6 +432,10 @@ Yul Control Flow Graph: "out": [] } ], + "liveness": { + "in": [], + "out": [] + }, "type": "BuiltinCall" } ], @@ -421,6 +489,12 @@ Yul Control Flow Graph: ] } ], + "liveness": { + "in": [], + "out": [ + "v0" + ] + }, "type": "BuiltinCall" }, { @@ -467,6 +541,12 @@ Yul Control Flow Graph: "out": [] } ], + "liveness": { + "in": [ + "v0" + ], + "out": [] + }, "type": "BuiltinCall" }, { @@ -484,6 +564,10 @@ Yul Control Flow Graph: "out": [] } ], + "liveness": { + "in": [], + "out": [] + }, "type": "BuiltinCall" } ], @@ -548,6 +632,12 @@ Yul Control Flow Graph: ] } ], + "liveness": { + "in": [], + "out": [ + "v0" + ] + }, "type": "BuiltinCall" }, { @@ -565,6 +655,10 @@ Yul Control Flow Graph: "out": [] } ], + "liveness": { + "in": [], + "out": [] + }, "type": "BuiltinCall" }, { @@ -608,6 +702,14 @@ Yul Control Flow Graph: ] } ], + "liveness": { + "in": [ + "v0" + ], + "out": [ + "v0" + ] + }, "type": "BuiltinCall" }, { @@ -618,7 +720,11 @@ Yul Control Flow Graph: "type": "Jump" }, "id": "Block4", - "instructions": [] + "instructions": [], + "liveness": { + "in": [], + "out": [] + } }, { "exit": { @@ -639,6 +745,14 @@ Yul Control Flow Graph: ] } ], + "liveness": { + "in": [ + "v0" + ], + "out": [ + "v0" + ] + }, "type": "BuiltinCall" }, { @@ -689,6 +803,14 @@ Yul Control Flow Graph: ] } ], + "liveness": { + "in": [ + "v0" + ], + "out": [ + "v0" + ] + }, "type": "BuiltinCall" }, { @@ -706,6 +828,10 @@ Yul Control Flow Graph: "out": [] } ], + "liveness": { + "in": [], + "out": [] + }, "type": "BuiltinCall" }, { @@ -770,6 +896,16 @@ Yul Control Flow Graph: ] } ], + "liveness": { + "in": [ + "v0" + ], + "out": [ + "v0", + "v18", + "v24" + ] + }, "type": "BuiltinCall" }, { @@ -787,6 +923,10 @@ Yul Control Flow Graph: "out": [] } ], + "liveness": { + "in": [], + "out": [] + }, "type": "BuiltinCall" }, { @@ -850,6 +990,16 @@ Yul Control Flow Graph: ] } ], + "liveness": { + "in": [ + "v0", + "v18", + "v24" + ], + "out": [ + "v41" + ] + }, "type": "BuiltinCall" }, { @@ -893,6 +1043,10 @@ Yul Control Flow Graph: "out": [] } ], + "liveness": { + "in": [], + "out": [] + }, "type": "BuiltinCall" }, { @@ -994,6 +1148,14 @@ Yul Control Flow Graph: ] } ], + "liveness": { + "in": [ + "v41" + ], + "out": [ + "v46" + ] + }, "type": "BuiltinCall" }, { @@ -1043,6 +1205,10 @@ Yul Control Flow Graph: "out": [] } ], + "liveness": { + "in": [], + "out": [] + }, "type": "BuiltinCall" }, { @@ -1055,7 +1221,15 @@ Yul Control Flow Graph: "type": "ConditionalJump" }, "id": "Block18", - "instructions": [] + "instructions": [], + "liveness": { + "in": [ + "v46" + ], + "out": [ + "v46" + ] + } }, { "exit": { @@ -1104,6 +1278,10 @@ Yul Control Flow Graph: "out": [] } ], + "liveness": { + "in": [], + "out": [] + }, "type": "BuiltinCall" }, { @@ -1152,6 +1330,12 @@ Yul Control Flow Graph: "out": [] } ], + "liveness": { + "in": [ + "v95" + ], + "out": [] + }, "type": "BuiltinCall" }, { @@ -1183,6 +1367,14 @@ Yul Control Flow Graph: ] } ], + "liveness": { + "in": [ + "v46" + ], + "out": [ + "v46" + ] + }, "type": "BuiltinCall" }, { @@ -1280,6 +1472,17 @@ Yul Control Flow Graph: ] } ], + "liveness": { + "in": [ + "v46", + "v71" + ], + "out": [ + "v46", + "v71", + "v77" + ] + }, "type": "BuiltinCall" }, { @@ -1299,6 +1502,15 @@ Yul Control Flow Graph: ] } ], + "liveness": { + "in": [ + "v46" + ], + "out": [ + "v46", + "v68" + ] + }, "type": "BuiltinCall" }, { @@ -1351,6 +1563,16 @@ Yul Control Flow Graph: ] } ], + "liveness": { + "in": [ + "v46", + "v71", + "v77" + ], + "out": [ + "v46" + ] + }, "type": "BuiltinCall" }, { @@ -1394,6 +1616,10 @@ Yul Control Flow Graph: "out": [] } ], + "liveness": { + "in": [], + "out": [] + }, "type": "BuiltinCall" }, { @@ -1415,6 +1641,14 @@ Yul Control Flow Graph: ] } ], + "liveness": { + "in": [ + "v46" + ], + "out": [ + "v93" + ] + }, "type": "BuiltinCall" }, { @@ -1432,6 +1666,10 @@ Yul Control Flow Graph: "out": [] } ], + "liveness": { + "in": [], + "out": [] + }, "type": "BuiltinCall" } ], @@ -1477,6 +1715,12 @@ Yul Control Flow Graph: ] } ], + "liveness": { + "in": [], + "out": [ + "v0" + ] + }, "type": "BuiltinCall" }, { @@ -1523,6 +1767,12 @@ Yul Control Flow Graph: "out": [] } ], + "liveness": { + "in": [ + "v0" + ], + "out": [] + }, "type": "BuiltinCall" }, { @@ -1540,6 +1790,10 @@ Yul Control Flow Graph: "out": [] } ], + "liveness": { + "in": [], + "out": [] + }, "type": "BuiltinCall" } ], @@ -1604,6 +1858,12 @@ Yul Control Flow Graph: ] } ], + "liveness": { + "in": [], + "out": [ + "v0" + ] + }, "type": "BuiltinCall" }, { @@ -1621,6 +1881,10 @@ Yul Control Flow Graph: "out": [] } ], + "liveness": { + "in": [], + "out": [] + }, "type": "BuiltinCall" }, { @@ -1664,6 +1928,14 @@ Yul Control Flow Graph: ] } ], + "liveness": { + "in": [ + "v0" + ], + "out": [ + "v0" + ] + }, "type": "BuiltinCall" }, { @@ -1674,7 +1946,11 @@ Yul Control Flow Graph: "type": "Jump" }, "id": "Block4", - "instructions": [] + "instructions": [], + "liveness": { + "in": [], + "out": [] + } }, { "exit": { @@ -1695,6 +1971,14 @@ Yul Control Flow Graph: ] } ], + "liveness": { + "in": [ + "v0" + ], + "out": [ + "v0" + ] + }, "type": "BuiltinCall" }, { @@ -1745,6 +2029,14 @@ Yul Control Flow Graph: ] } ], + "liveness": { + "in": [ + "v0" + ], + "out": [ + "v0" + ] + }, "type": "BuiltinCall" }, { @@ -1762,6 +2054,10 @@ Yul Control Flow Graph: "out": [] } ], + "liveness": { + "in": [], + "out": [] + }, "type": "BuiltinCall" }, { @@ -1787,6 +2083,12 @@ Yul Control Flow Graph: "out": [] } ], + "liveness": { + "in": [ + "v0" + ], + "out": [] + }, "type": "BuiltinCall" }, { @@ -1804,6 +2106,10 @@ Yul Control Flow Graph: "out": [] } ], + "liveness": { + "in": [], + "out": [] + }, "type": "BuiltinCall" } ], From ca54a7695da56b973dcf7198393a44fe4712a0c2 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Fri, 18 Oct 2024 15:39:29 +0200 Subject: [PATCH 0609/1022] Yul: Add utilities to resolve function name strings and builtin functions from an AST FunctionName --- libyul/Utilities.cpp | 32 ++++++++++++++++++++++++++++++++ libyul/Utilities.h | 10 ++++++++++ 2 files changed, 42 insertions(+) diff --git a/libyul/Utilities.cpp b/libyul/Utilities.cpp index 4bbfb42437b0..dd32d6a604d1 100644 --- a/libyul/Utilities.cpp +++ b/libyul/Utilities.cpp @@ -21,11 +21,15 @@ #include +#include + #include +#include #include #include #include +#include #include @@ -237,3 +241,31 @@ bool SwitchCaseCompareByLiteralValue::operator()(Case const* _lhs, Case const* _ yulAssert(_lhs && _rhs, ""); return Less{}(_lhs->value.get(), _rhs->value.get()); } + +std::string_view yul::resolveFunctionName(FunctionName const& _functionName, Dialect const& _dialect) +{ + GenericVisitor visitor{ + [&](Identifier const& _identifier) -> std::string const& { return _identifier.name.str(); }, + [&](BuiltinName const& _builtin) -> std::string const& { return _dialect.builtin(_builtin.handle).name; } + }; + return std::visit(visitor, _functionName); +} + +BuiltinFunction const* yul::resolveBuiltinFunction(FunctionName const& _functionName, Dialect const& _dialect) +{ + GenericVisitor visitor{ + [&](Identifier const&) -> BuiltinFunction const* { return nullptr; }, + [&](BuiltinName const& _builtin) -> BuiltinFunction const* { return &_dialect.builtin(_builtin.handle); } + }; + return std::visit(visitor, _functionName); +} + +BuiltinFunctionForEVM const* yul::resolveBuiltinFunctionForEVM(FunctionName const& _functionName, EVMDialect const& _dialect) +{ + GenericVisitor visitor{ + [&](Identifier const&) -> BuiltinFunctionForEVM const* { return nullptr; }, + [&](BuiltinName const& _builtin) -> BuiltinFunctionForEVM const* { return &_dialect.builtin(_builtin.handle); } + }; + return std::visit(visitor, _functionName); +} + diff --git a/libyul/Utilities.h b/libyul/Utilities.h index 434c5e9c5a3a..2341ee62a6c5 100644 --- a/libyul/Utilities.h +++ b/libyul/Utilities.h @@ -30,6 +30,11 @@ namespace solidity::yul { +struct Dialect; +class EVMDialect; +struct BuiltinFunction; +struct BuiltinFunctionForEVM; + std::string reindent(std::string const& _code); LiteralValue valueOfNumberLiteral(std::string_view _literal); @@ -83,4 +88,9 @@ struct SwitchCaseCompareByLiteralValue bool operator()(Case const* _lhsCase, Case const* _rhsCase) const; }; +std::string_view resolveFunctionName(FunctionName const& _functionName, Dialect const& _dialect); + +BuiltinFunction const* resolveBuiltinFunction(FunctionName const& _functionName, Dialect const& _dialect); +BuiltinFunctionForEVM const* resolveBuiltinFunctionForEVM(FunctionName const& _functionName, EVMDialect const& _dialect); + } From 144a3a9a15335282f35ede74c563f1a182f1dcdc Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Fri, 18 Oct 2024 16:10:10 +0200 Subject: [PATCH 0610/1022] Yul EVM dialect: Add auxiliary builtin handles --- libyul/backends/evm/EVMDialect.cpp | 9 +++++++++ libyul/backends/evm/EVMDialect.h | 14 ++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/libyul/backends/evm/EVMDialect.cpp b/libyul/backends/evm/EVMDialect.cpp index 4d160b03049e..161f92336b4c 100644 --- a/libyul/backends/evm/EVMDialect.cpp +++ b/libyul/backends/evm/EVMDialect.cpp @@ -475,6 +475,15 @@ EVMDialect::EVMDialect(langutil::EVMVersion _evmVersion, std::optional m_storageStoreFunction = findBuiltin("sstore"); m_storageLoadFunction = findBuiltin("sload"); m_hashFunction = findBuiltin("keccak256"); + + m_discardFunction = findBuiltin("pop"); + m_equalityFunction = findBuiltin("eq"); + m_booleanNegationFunction = findBuiltin("iszero"); + m_memoryStoreFunction = findBuiltin("mstore"); + m_memoryLoadFunction = findBuiltin("mload"); + m_storageStoreFunction = findBuiltin("sstore"); + m_storageLoadFunction = findBuiltin("sload"); + m_hashFunction = findBuiltin("keccak256"); } std::optional EVMDialect::findBuiltin(std::string_view _name) const diff --git a/libyul/backends/evm/EVMDialect.h b/libyul/backends/evm/EVMDialect.h index 58944bdc701f..5d5ea90a99be 100644 --- a/libyul/backends/evm/EVMDialect.h +++ b/libyul/backends/evm/EVMDialect.h @@ -68,6 +68,18 @@ struct BuiltinFunctionForEVM: public BuiltinFunction class EVMDialect: public Dialect { public: + /// Handles to (depending on dialect, potentially existing) builtins, which are not accessible via the + /// `...FunctionHandle` functions of `Dialect` and of which it is statically known, that they are needed in, + /// e.g., certain optimization steps. + struct AuxiliaryBuiltinHandles + { + std::optional add; + std::optional exp; + std::optional mul; + std::optional not_; + std::optional shl; + std::optional sub; + }; /// Constructor, should only be used internally. Use the factory functions below. EVMDialect(langutil::EVMVersion _evmVersion, std::optional _eofVersion, bool _objectAccess); @@ -85,6 +97,7 @@ class EVMDialect: public Dialect std::optional storageStoreFunctionHandle() const override { return m_storageStoreFunction; } std::optional storageLoadFunctionHandle() const override { return m_storageLoadFunction; } std::optional hashFunctionHandle() const override { return m_hashFunction; } + AuxiliaryBuiltinHandles const& auxiliaryBuiltinHandles() const { return m_auxiliaryBuiltinHandles; } static EVMDialect const& strictAssemblyForEVM(langutil::EVMVersion _evmVersion, std::optional _eofVersion); static EVMDialect const& strictAssemblyForEVMObjects(langutil::EVMVersion _evmVersion, std::optional _eofVersion); @@ -123,6 +136,7 @@ class EVMDialect: public Dialect std::optional m_storageStoreFunction; std::optional m_storageLoadFunction; std::optional m_hashFunction; + AuxiliaryBuiltinHandles m_auxiliaryBuiltinHandles; }; } From 7c3ed2b65f88d972014816884ccfa4ba9f4bac04 Mon Sep 17 00:00:00 2001 From: DaniPopes <57450786+DaniPopes@users.noreply.github.com> Date: Thu, 5 Dec 2024 19:24:35 +0100 Subject: [PATCH 0611/1022] Remove request about deleting issue template notes These notes are already commented out so there is no reason to request deleting it. --- .github/ISSUE_TEMPLATE/bug_report.md | 2 -- .github/ISSUE_TEMPLATE/feature_request.md | 2 -- 2 files changed, 4 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 30c09039ef79..ef411e08a49a 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -16,8 +16,6 @@ assignees: '' - [Stack Overflow](https://ethereum.stackexchange.com/) - Ensure the issue isn't already reported. - The issue should be reproducible with the latest solidity version; however, this isn't a hard requirement and being reproducible with an older version is sufficient. - -*Delete the above section and the instructions in the sections below before submitting* --> ## Description diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md index 7ec729b1c7a3..328ff76e22c0 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -18,8 +18,6 @@ assignees: '' - Ensure the issue isn't already reported (check `feature` and `language design` labels). - If you feel uncertain about your feature request, perhaps it's better to open a language design or feedback forum thread via the issue selector, or by going to the forum directly. - [Solidity forum](https://forum.soliditylang.org/) - -*Delete the above section and the instructions in the sections below before submitting* --> ## Abstract From 4edb59d322daabecb6e1b07214ff0c2bb879eacb Mon Sep 17 00:00:00 2001 From: rodiazet Date: Fri, 6 Dec 2024 14:51:32 +0100 Subject: [PATCH 0612/1022] eof: Implement stack height calculation --- libevmasm/Assembly.cpp | 91 ++++++++++++++++++- .../strict_asm_eof_container_prague/output | 2 +- .../strict_asm_eof_dataloadn_prague/output | 2 +- .../objectCompiler/eof/256_subcontainers.yul | 4 +- .../eof/creation_with_immutables.yul | 4 +- test/libyul/objectCompiler/eof/dataloadn.yul | 4 +- test/libyul/objectCompiler/eof/functions.yul | 4 +- .../eof/prune_unreferenced_container.yul | 4 +- test/libyul/objectCompiler/eof/rjumps.yul | 4 +- 9 files changed, 103 insertions(+), 16 deletions(-) diff --git a/libevmasm/Assembly.cpp b/libevmasm/Assembly.cpp index 29b8c8a4057c..e5c62958f6e6 100644 --- a/libevmasm/Assembly.cpp +++ b/libevmasm/Assembly.cpp @@ -46,6 +46,7 @@ #include #include #include +#include using namespace solidity; using namespace solidity::evmasm; @@ -971,6 +972,93 @@ void appendBigEndianUint16(bytes& _dest, ValueT _value) assertThrow(_value <= 0xFFFF, AssemblyException, ""); appendBigEndian(_dest, 2, static_cast(_value)); } + +// Calculates maximum stack height for given code section. According to EIP5450 https://eips.ethereum.org/EIPS/eip-5450 +uint16_t calculateMaxStackHeight(Assembly::CodeSection const& _section) +{ + static auto constexpr UNVISITED = std::numeric_limits::max(); + + AssemblyItems const& items = _section.items; + solAssert(!items.empty()); + uint16_t overallMaxHeight = _section.inputs; + std::stack worklist; + std::vector maxStackHeights(items.size(), UNVISITED); + + // Init first item stack height to number of inputs to the code section + // maxStackHeights stores stack height for an item before the item execution + maxStackHeights[0] = _section.inputs; + // Push first item index to the worklist + worklist.push(0u); + while (!worklist.empty()) + { + size_t idx = worklist.top(); + worklist.pop(); + AssemblyItem const& item = items[idx]; + size_t stackHeightChange = item.deposit(); + size_t currentMaxHeight = maxStackHeights[idx]; + solAssert(currentMaxHeight != UNVISITED); + + std::vector successors; + + // Add next instruction to successors for non-control-flow-changing instructions + if ( + !(item.hasInstruction() && SemanticInformation::terminatesControlFlow(item.instruction())) && + item.type() != RelativeJump && + item.type() != RetF && + item.type() != JumpF + ) + { + solAssert(idx < items.size() - 1, "No terminating instruction."); + successors.emplace_back(idx + 1); + } + + // Add jumps destinations to successors + // TODO: Remember to add RJUMPV when it is supported. + if (item.type() == RelativeJump || item.type() == ConditionalRelativeJump) + { + auto const tagIt = std::find(items.begin(), items.end(), item.tag()); + solAssert(tagIt != items.end(), "Tag not found."); + successors.emplace_back(static_cast(std::distance(items.begin(), tagIt))); + // If backward jump the successor must be already visited. + solAssert(idx <= successors.back() || maxStackHeights[successors.back()] != UNVISITED); + } + + solRequire( + currentMaxHeight + stackHeightChange <= std::numeric_limits::max(), + AssemblyException, + "Stack overflow in EOF function." + ); + overallMaxHeight = std::max(overallMaxHeight, static_cast(currentMaxHeight + stackHeightChange)); + currentMaxHeight += stackHeightChange; + + // Set stack height for all instruction successors + for (size_t successor: successors) + { + solAssert(successor < maxStackHeights.size()); + // Set stack height for newly visited + if (maxStackHeights[successor] == UNVISITED) + { + maxStackHeights[successor] = currentMaxHeight; + worklist.push(successor); + } + else + { + solAssert(successor < maxStackHeights.size()); + // For backward jump successor stack height must be equal + if (successor < idx) + solAssert(maxStackHeights[successor] == currentMaxHeight, "Stack height mismatch."); + + // If successor stack height is smaller update it and recalculate + if (currentMaxHeight > maxStackHeights[successor]) + { + maxStackHeights[successor] = currentMaxHeight; + worklist.push(successor); + } + } + } + } + return overallMaxHeight; +} } std::tuple, size_t> Assembly::createEOFHeader(std::set const& _referencedSubIds) const @@ -1015,8 +1103,7 @@ std::tuple, size_t> Assembly::createEOFHeader(std::se { retBytecode.push_back(codeSection.inputs); retBytecode.push_back(codeSection.outputs); - // TODO: Add stack height calculation - appendBigEndianUint16(retBytecode, 0xFFFFu); + appendBigEndianUint16(retBytecode, calculateMaxStackHeight(codeSection)); } return {retBytecode, codeSectionSizePositions, dataSectionSizePosition}; diff --git a/test/cmdlineTests/strict_asm_eof_container_prague/output b/test/cmdlineTests/strict_asm_eof_container_prague/output index 26d37caf4625..5d134f277865 100644 --- a/test/cmdlineTests/strict_asm_eof_container_prague/output +++ b/test/cmdlineTests/strict_asm_eof_container_prague/output @@ -48,7 +48,7 @@ object "object" { Binary representation: -ef0001010004020001001503000200370037040000000080ffff5f808080ec005f525f808080ec0160205260405ff3ef00010100040200010004030001001b040000000080ffff5f80ee00ef00010100040200010008040000000080ffff60015f5260205ffdef00010100040200010004030001001b040000000080ffff5f80ee00ef00010100040200010008040000000080ffff60205f5260205ffd +ef000101000402000100150300020037003704000000008000045f808080ec005f525f808080ec0160205260405ff3ef00010100040200010004030001001b04000000008000025f80ee00ef00010100040200010008040000000080000260015f5260205ffdef00010100040200010004030001001b04000000008000025f80ee00ef00010100040200010008040000000080000260205f5260205ffd Text representation: 0x00 diff --git a/test/cmdlineTests/strict_asm_eof_dataloadn_prague/output b/test/cmdlineTests/strict_asm_eof_dataloadn_prague/output index 1c06caa5e36d..5d2115f95af6 100644 --- a/test/cmdlineTests/strict_asm_eof_dataloadn_prague/output +++ b/test/cmdlineTests/strict_asm_eof_dataloadn_prague/output @@ -14,7 +14,7 @@ object "a" { Binary representation: -ef0001010004020001000904002d000080ffffd1000d5f5260205ff348656c6c6f2c20576f726c6421 +ef0001010004020001000904002d0000800002d1000d5f5260205ff348656c6c6f2c20576f726c6421 Text representation: auxdataloadn{0} diff --git a/test/libyul/objectCompiler/eof/256_subcontainers.yul b/test/libyul/objectCompiler/eof/256_subcontainers.yul index 46df86355091..fac0f7b5df29 100644 --- a/test/libyul/objectCompiler/eof/256_subcontainers.yul +++ b/test/libyul/objectCompiler/eof/256_subcontainers.yul @@ -4107,6 +4107,6 @@ object "a" { // /* "source":24612:24619 */ // stop // } -// Bytecode: ef000101000402000107010301000014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014040000000080ffff5f808080ec00505f808080ec01505f808080ec02505f808080ec03505f808080ec04505f808080ec05505f808080ec06505f808080ec07505f808080ec08505f808080ec09505f808080ec0a505f808080ec0b505f808080ec0c505f808080ec0d505f808080ec0e505f808080ec0f505f808080ec10505f808080ec11505f808080ec12505f808080ec13505f808080ec14505f808080ec15505f808080ec16505f808080ec17505f808080ec18505f808080ec19505f808080ec1a505f808080ec1b505f808080ec1c505f808080ec1d505f808080ec1e505f808080ec1f505f808080ec20505f808080ec21505f808080ec22505f808080ec23505f808080ec24505f808080ec25505f808080ec26505f808080ec27505f808080ec28505f808080ec29505f808080ec2a505f808080ec2b505f808080ec2c505f808080ec2d505f808080ec2e505f808080ec2f505f808080ec30505f808080ec31505f808080ec32505f808080ec33505f808080ec34505f808080ec35505f808080ec36505f808080ec37505f808080ec38505f808080ec39505f808080ec3a505f808080ec3b505f808080ec3c505f808080ec3d505f808080ec3e505f808080ec3f505f808080ec40505f808080ec41505f808080ec42505f808080ec43505f808080ec44505f808080ec45505f808080ec46505f808080ec47505f808080ec48505f808080ec49505f808080ec4a505f808080ec4b505f808080ec4c505f808080ec4d505f808080ec4e505f808080ec4f505f808080ec50505f808080ec51505f808080ec52505f808080ec53505f808080ec54505f808080ec55505f808080ec56505f808080ec57505f808080ec58505f808080ec59505f808080ec5a505f808080ec5b505f808080ec5c505f808080ec5d505f808080ec5e505f808080ec5f505f808080ec60505f808080ec61505f808080ec62505f808080ec63505f808080ec64505f808080ec65505f808080ec66505f808080ec67505f808080ec68505f808080ec69505f808080ec6a505f808080ec6b505f808080ec6c505f808080ec6d505f808080ec6e505f808080ec6f505f808080ec70505f808080ec71505f808080ec72505f808080ec73505f808080ec74505f808080ec75505f808080ec76505f808080ec77505f808080ec78505f808080ec79505f808080ec7a505f808080ec7b505f808080ec7c505f808080ec7d505f808080ec7e505f808080ec7f505f808080ec80505f808080ec81505f808080ec82505f808080ec83505f808080ec84505f808080ec85505f808080ec86505f808080ec87505f808080ec88505f808080ec89505f808080ec8a505f808080ec8b505f808080ec8c505f808080ec8d505f808080ec8e505f808080ec8f505f808080ec90505f808080ec91505f808080ec92505f808080ec93505f808080ec94505f808080ec95505f808080ec96505f808080ec97505f808080ec98505f808080ec99505f808080ec9a505f808080ec9b505f808080ec9c505f808080ec9d505f808080ec9e505f808080ec9f505f808080eca0505f808080eca1505f808080eca2505f808080eca3505f808080eca4505f808080eca5505f808080eca6505f808080eca7505f808080eca8505f808080eca9505f808080ecaa505f808080ecab505f808080ecac505f808080ecad505f808080ecae505f808080ecaf505f808080ecb0505f808080ecb1505f808080ecb2505f808080ecb3505f808080ecb4505f808080ecb5505f808080ecb6505f808080ecb7505f808080ecb8505f808080ecb9505f808080ecba505f808080ecbb505f808080ecbc505f808080ecbd505f808080ecbe505f808080ecbf505f808080ecc0505f808080ecc1505f808080ecc2505f808080ecc3505f808080ecc4505f808080ecc5505f808080ecc6505f808080ecc7505f808080ecc8505f808080ecc9505f808080ecca505f808080eccb505f808080eccc505f808080eccd505f808080ecce505f808080eccf505f808080ecd0505f808080ecd1505f808080ecd2505f808080ecd3505f808080ecd4505f808080ecd5505f808080ecd6505f808080ecd7505f808080ecd8505f808080ecd9505f808080ecda505f808080ecdb505f808080ecdc505f808080ecdd505f808080ecde505f808080ecdf505f808080ece0505f808080ece1505f808080ece2505f808080ece3505f808080ece4505f808080ece5505f808080ece6505f808080ece7505f808080ece8505f808080ece9505f808080ecea505f808080eceb505f808080ecec505f808080eced505f808080ecee505f808080ecef505f808080ecf0505f808080ecf1505f808080ecf2505f808080ecf3505f808080ecf4505f808080ecf5505f808080ecf6505f808080ecf7505f808080ecf8505f808080ecf9505f808080ecfa505f808080ecfb505f808080ecfc505f808080ecfd505f808080ecfe505f808080ecff5000ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00ef00010100040200010001040000000080ffff00 -// Opcodes: 0xEF STOP ADD ADD STOP DIV MUL STOP ADD SMOD ADD SUB ADD STOP STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x0 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x1 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x2 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x3 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x4 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x5 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x6 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x7 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x8 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x9 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xA POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xB POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xC POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xD POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xE POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xF POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x10 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x11 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x12 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x13 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x14 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x15 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x16 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x17 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x18 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x19 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x1A POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x1B POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x1C POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x1D POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x1E POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x1F POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x20 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x21 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x22 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x23 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x24 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x25 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x26 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x27 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x28 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x29 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x2A POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x2B POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x2C POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x2D POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x2E POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x2F POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x30 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x31 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x32 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x33 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x34 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x35 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x36 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x37 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x38 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x39 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x3A POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x3B POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x3C POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x3D POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x3E POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x3F POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x40 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x41 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x42 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x43 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x44 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x45 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x46 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x47 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x48 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x49 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x4A POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x4B POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x4C POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x4D POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x4E POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x4F POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x50 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x51 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x52 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x53 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x54 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x55 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x56 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x57 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x58 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x59 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x5A POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x5B POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x5C POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x5D POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x5E POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x5F POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x60 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x61 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x62 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x63 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x64 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x65 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x66 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x67 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x68 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x69 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x6A POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x6B POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x6C POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x6D POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x6E POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x6F POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x70 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x71 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x72 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x73 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x74 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x75 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x76 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x77 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x78 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x79 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x7A POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x7B POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x7C POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x7D POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x7E POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x7F POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x80 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x81 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x82 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x83 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x84 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x85 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x86 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x87 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x88 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x89 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x8A POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x8B POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x8C POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x8D POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x8E POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x8F POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x90 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x91 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x92 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x93 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x94 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x95 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x96 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x97 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x98 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x99 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x9A POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x9B POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x9C POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x9D POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x9E POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x9F POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xA0 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xA1 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xA2 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xA3 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xA4 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xA5 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xA6 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xA7 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xA8 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xA9 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xAA POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xAB POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xAC POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xAD POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xAE POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xAF POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xB0 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xB1 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xB2 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xB3 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xB4 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xB5 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xB6 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xB7 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xB8 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xB9 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xBA POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xBB POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xBC POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xBD POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xBE POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xBF POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xC0 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xC1 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xC2 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xC3 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xC4 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xC5 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xC6 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xC7 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xC8 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xC9 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xCA POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xCB POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xCC POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xCD POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xCE POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xCF POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xD0 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xD1 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xD2 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xD3 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xD4 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xD5 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xD6 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xD7 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xD8 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xD9 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xDA POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xDB POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xDC POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xDD POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xDE POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xDF POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xE0 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xE1 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xE2 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xE3 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xE4 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xE5 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xE6 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xE7 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xE8 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xE9 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xEA POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xEB POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xEC POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xED POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xEE POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xEF POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xF0 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xF1 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xF2 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xF3 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xF4 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xF5 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xF6 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xF7 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xF8 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xF9 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xFA POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xFB POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xFC POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xFD POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xFE POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xFF POP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP +// Bytecode: ef00010100040200010701030100001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001404000000008000045f808080ec00505f808080ec01505f808080ec02505f808080ec03505f808080ec04505f808080ec05505f808080ec06505f808080ec07505f808080ec08505f808080ec09505f808080ec0a505f808080ec0b505f808080ec0c505f808080ec0d505f808080ec0e505f808080ec0f505f808080ec10505f808080ec11505f808080ec12505f808080ec13505f808080ec14505f808080ec15505f808080ec16505f808080ec17505f808080ec18505f808080ec19505f808080ec1a505f808080ec1b505f808080ec1c505f808080ec1d505f808080ec1e505f808080ec1f505f808080ec20505f808080ec21505f808080ec22505f808080ec23505f808080ec24505f808080ec25505f808080ec26505f808080ec27505f808080ec28505f808080ec29505f808080ec2a505f808080ec2b505f808080ec2c505f808080ec2d505f808080ec2e505f808080ec2f505f808080ec30505f808080ec31505f808080ec32505f808080ec33505f808080ec34505f808080ec35505f808080ec36505f808080ec37505f808080ec38505f808080ec39505f808080ec3a505f808080ec3b505f808080ec3c505f808080ec3d505f808080ec3e505f808080ec3f505f808080ec40505f808080ec41505f808080ec42505f808080ec43505f808080ec44505f808080ec45505f808080ec46505f808080ec47505f808080ec48505f808080ec49505f808080ec4a505f808080ec4b505f808080ec4c505f808080ec4d505f808080ec4e505f808080ec4f505f808080ec50505f808080ec51505f808080ec52505f808080ec53505f808080ec54505f808080ec55505f808080ec56505f808080ec57505f808080ec58505f808080ec59505f808080ec5a505f808080ec5b505f808080ec5c505f808080ec5d505f808080ec5e505f808080ec5f505f808080ec60505f808080ec61505f808080ec62505f808080ec63505f808080ec64505f808080ec65505f808080ec66505f808080ec67505f808080ec68505f808080ec69505f808080ec6a505f808080ec6b505f808080ec6c505f808080ec6d505f808080ec6e505f808080ec6f505f808080ec70505f808080ec71505f808080ec72505f808080ec73505f808080ec74505f808080ec75505f808080ec76505f808080ec77505f808080ec78505f808080ec79505f808080ec7a505f808080ec7b505f808080ec7c505f808080ec7d505f808080ec7e505f808080ec7f505f808080ec80505f808080ec81505f808080ec82505f808080ec83505f808080ec84505f808080ec85505f808080ec86505f808080ec87505f808080ec88505f808080ec89505f808080ec8a505f808080ec8b505f808080ec8c505f808080ec8d505f808080ec8e505f808080ec8f505f808080ec90505f808080ec91505f808080ec92505f808080ec93505f808080ec94505f808080ec95505f808080ec96505f808080ec97505f808080ec98505f808080ec99505f808080ec9a505f808080ec9b505f808080ec9c505f808080ec9d505f808080ec9e505f808080ec9f505f808080eca0505f808080eca1505f808080eca2505f808080eca3505f808080eca4505f808080eca5505f808080eca6505f808080eca7505f808080eca8505f808080eca9505f808080ecaa505f808080ecab505f808080ecac505f808080ecad505f808080ecae505f808080ecaf505f808080ecb0505f808080ecb1505f808080ecb2505f808080ecb3505f808080ecb4505f808080ecb5505f808080ecb6505f808080ecb7505f808080ecb8505f808080ecb9505f808080ecba505f808080ecbb505f808080ecbc505f808080ecbd505f808080ecbe505f808080ecbf505f808080ecc0505f808080ecc1505f808080ecc2505f808080ecc3505f808080ecc4505f808080ecc5505f808080ecc6505f808080ecc7505f808080ecc8505f808080ecc9505f808080ecca505f808080eccb505f808080eccc505f808080eccd505f808080ecce505f808080eccf505f808080ecd0505f808080ecd1505f808080ecd2505f808080ecd3505f808080ecd4505f808080ecd5505f808080ecd6505f808080ecd7505f808080ecd8505f808080ecd9505f808080ecda505f808080ecdb505f808080ecdc505f808080ecdd505f808080ecde505f808080ecdf505f808080ece0505f808080ece1505f808080ece2505f808080ece3505f808080ece4505f808080ece5505f808080ece6505f808080ece7505f808080ece8505f808080ece9505f808080ecea505f808080eceb505f808080ecec505f808080eced505f808080ecee505f808080ecef505f808080ecf0505f808080ecf1505f808080ecf2505f808080ecf3505f808080ecf4505f808080ecf5505f808080ecf6505f808080ecf7505f808080ecf8505f808080ecf9505f808080ecfa505f808080ecfb505f808080ecfc505f808080ecfd505f808080ecfe505f808080ecff5000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000 +// Opcodes: 0xEF STOP ADD ADD STOP DIV MUL STOP ADD SMOD ADD SUB ADD STOP STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ DIV STOP STOP STOP STOP DUP1 STOP DIV PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x0 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x1 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x2 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x3 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x4 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x5 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x6 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x7 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x8 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x9 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xA POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xB POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xC POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xD POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xE POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xF POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x10 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x11 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x12 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x13 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x14 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x15 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x16 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x17 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x18 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x19 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x1A POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x1B POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x1C POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x1D POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x1E POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x1F POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x20 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x21 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x22 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x23 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x24 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x25 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x26 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x27 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x28 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x29 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x2A POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x2B POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x2C POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x2D POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x2E POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x2F POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x30 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x31 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x32 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x33 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x34 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x35 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x36 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x37 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x38 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x39 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x3A POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x3B POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x3C POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x3D POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x3E POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x3F POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x40 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x41 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x42 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x43 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x44 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x45 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x46 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x47 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x48 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x49 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x4A POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x4B POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x4C POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x4D POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x4E POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x4F POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x50 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x51 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x52 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x53 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x54 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x55 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x56 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x57 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x58 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x59 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x5A POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x5B POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x5C POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x5D POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x5E POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x5F POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x60 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x61 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x62 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x63 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x64 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x65 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x66 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x67 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x68 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x69 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x6A POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x6B POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x6C POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x6D POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x6E POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x6F POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x70 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x71 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x72 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x73 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x74 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x75 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x76 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x77 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x78 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x79 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x7A POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x7B POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x7C POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x7D POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x7E POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x7F POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x80 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x81 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x82 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x83 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x84 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x85 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x86 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x87 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x88 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x89 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x8A POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x8B POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x8C POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x8D POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x8E POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x8F POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x90 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x91 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x92 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x93 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x94 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x95 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x96 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x97 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x98 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x99 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x9A POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x9B POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x9C POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x9D POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x9E POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x9F POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xA0 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xA1 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xA2 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xA3 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xA4 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xA5 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xA6 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xA7 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xA8 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xA9 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xAA POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xAB POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xAC POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xAD POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xAE POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xAF POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xB0 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xB1 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xB2 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xB3 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xB4 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xB5 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xB6 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xB7 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xB8 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xB9 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xBA POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xBB POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xBC POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xBD POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xBE POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xBF POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xC0 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xC1 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xC2 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xC3 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xC4 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xC5 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xC6 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xC7 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xC8 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xC9 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xCA POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xCB POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xCC POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xCD POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xCE POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xCF POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xD0 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xD1 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xD2 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xD3 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xD4 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xD5 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xD6 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xD7 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xD8 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xD9 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xDA POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xDB POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xDC POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xDD POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xDE POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xDF POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xE0 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xE1 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xE2 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xE3 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xE4 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xE5 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xE6 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xE7 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xE8 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xE9 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xEA POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xEB POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xEC POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xED POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xEE POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xEF POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xF0 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xF1 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xF2 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xF3 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xF4 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xF5 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xF6 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xF7 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xF8 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xF9 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xFA POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xFB POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xFC POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xFD POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xFE POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xFF POP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP // SourceMappings: 78:1:0:-:0;50:30;;;;46:35;126:1;98:30;;;;94:35;174:1;146:30;;;;142:35;222:1;194:30;;;;190:35;270:1;242:30;;;;238:35;318:1;290:30;;;;286:35;366:1;338:30;;;;334:35;414:1;386:30;;;;382:35;462:1;434:30;;;;430:35;510:1;482:30;;;;478:35;558:1;530:30;;;;526:35;606:1;578:30;;;;574:35;654:1;626:30;;;;622:35;702:1;674:30;;;;670:35;750:1;722:30;;;;718:35;798:1;770:30;;;;766:35;846:1;818:30;;;;814:35;894:1;866:30;;;;862:35;942:1;914:30;;;;910:35;990:1;962:30;;;;958:35;1038:1;1010:30;;;;1006:35;1086:1;1058:30;;;;1054:35;1134:1;1106:30;;;;1102:35;1182:1;1154:30;;;;1150:35;1230:1;1202:30;;;;1198:35;1278:1;1250:30;;;;1246:35;1326:1;1298:30;;;;1294:35;1374:1;1346:30;;;;1342:35;1422:1;1394:30;;;;1390:35;1470:1;1442:30;;;;1438:35;1518:1;1490:30;;;;1486:35;1566:1;1538:30;;;;1534:35;1614:1;1586:30;;;;1582:35;1662:1;1634:30;;;;1630:35;1710:1;1682:30;;;;1678:35;1758:1;1730:30;;;;1726:35;1806:1;1778:30;;;;1774:35;1854:1;1826:30;;;;1822:35;1902:1;1874:30;;;;1870:35;1950:1;1922:30;;;;1918:35;1998:1;1970:30;;;;1966:35;2046:1;2018:30;;;;2014:35;2094:1;2066:30;;;;2062:35;2142:1;2114:30;;;;2110:35;2190:1;2162:30;;;;2158:35;2238:1;2210:30;;;;2206:35;2286:1;2258:30;;;;2254:35;2334:1;2306:30;;;;2302:35;2382:1;2354:30;;;;2350:35;2430:1;2402:30;;;;2398:35;2478:1;2450:30;;;;2446:35;2526:1;2498:30;;;;2494:35;2574:1;2546:30;;;;2542:35;2622:1;2594:30;;;;2590:35;2670:1;2642:30;;;;2638:35;2718:1;2690:30;;;;2686:35;2766:1;2738:30;;;;2734:35;2814:1;2786:30;;;;2782:35;2862:1;2834:30;;;;2830:35;2910:1;2882:30;;;;2878:35;2958:1;2930:30;;;;2926:35;3006:1;2978:30;;;;2974:35;3054:1;3026:30;;;;3022:35;3102:1;3074:30;;;;3070:35;3150:1;3122:30;;;;3118:35;3198:1;3170:30;;;;3166:35;3246:1;3218:30;;;;3214:35;3294:1;3266:30;;;;3262:35;3342:1;3314:30;;;;3310:35;3390:1;3362:30;;;;3358:35;3438:1;3410:30;;;;3406:35;3486:1;3458:30;;;;3454:35;3534:1;3506:30;;;;3502:35;3582:1;3554:30;;;;3550:35;3630:1;3602:30;;;;3598:35;3678:1;3650:30;;;;3646:35;3726:1;3698:30;;;;3694:35;3774:1;3746:30;;;;3742:35;3822:1;3794:30;;;;3790:35;3870:1;3842:30;;;;3838:35;3918:1;3890:30;;;;3886:35;3966:1;3938:30;;;;3934:35;4014:1;3986:30;;;;3982:35;4062:1;4034:30;;;;4030:35;4110:1;4082:30;;;;4078:35;4158:1;4130:30;;;;4126:35;4206:1;4178:30;;;;4174:35;4254:1;4226:30;;;;4222:35;4302:1;4274:30;;;;4270:35;4350:1;4322:30;;;;4318:35;4398:1;4370:30;;;;4366:35;4446:1;4418:30;;;;4414:35;4494:1;4466:30;;;;4462:35;4542:1;4514:30;;;;4510:35;4590:1;4562:30;;;;4558:35;4638:1;4610:30;;;;4606:35;4686:1;4658:30;;;;4654:35;4734:1;4706:30;;;;4702:35;4782:1;4754:30;;;;4750:35;4830:1;4802:30;;;;4798:35;4878:1;4850:30;;;;4846:35;4926:1;4898:30;;;;4894:35;4974:1;4946:30;;;;4942:35;5022:1;4994:30;;;;4990:35;5070:1;5042:30;;;;5038:35;5118:1;5090:30;;;;5086:35;5166:1;5138:30;;;;5134:35;5214:1;5186:30;;;;5182:35;5262:1;5234:30;;;;5230:35;5310:1;5282:30;;;;5278:35;5358:1;5330:30;;;;5326:35;5406:1;5378:30;;;;5374:35;5454:1;5426:30;;;;5422:35;5502:1;5474:30;;;;5470:35;5550:1;5522:30;;;;5518:35;5598:1;5570:30;;;;5566:35;5646:1;5618:30;;;;5614:35;5694:1;5666:30;;;;5662:35;5742:1;5714:30;;;;5710:35;5790:1;5762:30;;;;5758:35;5838:1;5810:30;;;;5806:35;5886:1;5858:30;;;;5854:35;5934:1;5906:30;;;;5902:35;5982:1;5954:30;;;;5950:35;6030:1;6002:30;;;;5998:35;6078:1;6050:30;;;;6046:35;6126:1;6098:30;;;;6094:35;6174:1;6146:30;;;;6142:35;6222:1;6194:30;;;;6190:35;6270:1;6242:30;;;;6238:35;6318:1;6290:30;;;;6286:35;6366:1;6338:30;;;;6334:35;6414:1;6386:30;;;;6382:35;6462:1;6434:30;;;;6430:35;6510:1;6482:30;;;;6478:35;6558:1;6530:30;;;;6526:35;6606:1;6578:30;;;;6574:35;6654:1;6626:30;;;;6622:35;6702:1;6674:30;;;;6670:35;6750:1;6722:30;;;;6718:35;6798:1;6770:30;;;;6766:35;6846:1;6818:30;;;;6814:35;6894:1;6866:30;;;;6862:35;6942:1;6914:30;;;;6910:35;6990:1;6962:30;;;;6958:35;7038:1;7010:30;;;;7006:35;7086:1;7058:30;;;;7054:35;7134:1;7106:30;;;;7102:35;7182:1;7154:30;;;;7150:35;7230:1;7202:30;;;;7198:35;7278:1;7250:30;;;;7246:35;7326:1;7298:30;;;;7294:35;7374:1;7346:30;;;;7342:35;7422:1;7394:30;;;;7390:35;7470:1;7442:30;;;;7438:35;7518:1;7490:30;;;;7486:35;7566:1;7538:30;;;;7534:35;7614:1;7586:30;;;;7582:35;7662:1;7634:30;;;;7630:35;7710:1;7682:30;;;;7678:35;7758:1;7730:30;;;;7726:35;7806:1;7778:30;;;;7774:35;7854:1;7826:30;;;;7822:35;7902:1;7874:30;;;;7870:35;7950:1;7922:30;;;;7918:35;7998:1;7970:30;;;;7966:35;8046:1;8018:30;;;;8014:35;8094:1;8066:30;;;;8062:35;8142:1;8114:30;;;;8110:35;8190:1;8162:30;;;;8158:35;8238:1;8210:30;;;;8206:35;8286:1;8258:30;;;;8254:35;8334:1;8306:30;;;;8302:35;8382:1;8354:30;;;;8350:35;8430:1;8402:30;;;;8398:35;8478:1;8450:30;;;;8446:35;8526:1;8498:30;;;;8494:35;8574:1;8546:30;;;;8542:35;8622:1;8594:30;;;;8590:35;8670:1;8642:30;;;;8638:35;8718:1;8690:30;;;;8686:35;8766:1;8738:30;;;;8734:35;8814:1;8786:30;;;;8782:35;8862:1;8834:30;;;;8830:35;8910:1;8882:30;;;;8878:35;8958:1;8930:30;;;;8926:35;9006:1;8978:30;;;;8974:35;9054:1;9026:30;;;;9022:35;9102:1;9074:30;;;;9070:35;9150:1;9122:30;;;;9118:35;9198:1;9170:30;;;;9166:35;9246:1;9218:30;;;;9214:35;9294:1;9266:30;;;;9262:35;9342:1;9314:30;;;;9310:35;9390:1;9362:30;;;;9358:35;9438:1;9410:30;;;;9406:35;9486:1;9458:30;;;;9454:35;9534:1;9506:30;;;;9502:35;9582:1;9554:30;;;;9550:35;9630:1;9602:30;;;;9598:35;9678:1;9650:30;;;;9646:35;9726:1;9698:30;;;;9694:35;9774:1;9746:30;;;;9742:35;9822:1;9794:30;;;;9790:35;9870:1;9842:30;;;;9838:35;9918:1;9890:30;;;;9886:35;9966:1;9938:30;;;;9934:35;10014:1;9986:30;;;;9982:35;10062:1;10034:30;;;;10030:35;10110:1;10082:30;;;;10078:35;10158:1;10130:30;;;;10126:35;10206:1;10178:30;;;;10174:35;10254:1;10226:30;;;;10222:35;10302:1;10274:30;;;;10270:35;10350:1;10322:30;;;;10318:35;10398:1;10370:30;;;;10366:35;10446:1;10418:30;;;;10414:35;10494:1;10466:30;;;;10462:35;10542:1;10514:30;;;;10510:35;10590:1;10562:30;;;;10558:35;10638:1;10610:30;;;;10606:35;10686:1;10658:30;;;;10654:35;10734:1;10706:30;;;;10702:35;10782:1;10754:30;;;;10750:35;10830:1;10802:30;;;;10798:35;10878:1;10850:30;;;;10846:35;10926:1;10898:30;;;;10894:35;10974:1;10946:30;;;;10942:35;11022:1;10994:30;;;;10990:35;11070:1;11042:30;;;;11038:35;11118:1;11090:30;;;;11086:35;11166:1;11138:30;;;;11134:35;11214:1;11186:30;;;;11182:35;11262:1;11234:30;;;;11230:35;11310:1;11282:30;;;;11278:35;11358:1;11330:30;;;;11326:35;11406:1;11378:30;;;;11374:35;11454:1;11426:30;;;;11422:35;11502:1;11474:30;;;;11470:35;11550:1;11522:30;;;;11518:35;11598:1;11570:30;;;;11566:35;11646:1;11618:30;;;;11614:35;11694:1;11666:30;;;;11662:35;11742:1;11714:30;;;;11710:35;11790:1;11762:30;;;;11758:35;11838:1;11810:30;;;;11806:35;11886:1;11858:30;;;;11854:35;11934:1;11906:30;;;;11902:35;11982:1;11954:30;;;;11950:35;12030:1;12002:30;;;;11998:35;12078:1;12050:30;;;;12046:35;12126:1;12098:30;;;;12094:35;12174:1;12146:30;;;;12142:35;12222:1;12194:30;;;;12190:35;12270:1;12242:30;;;;12238:35;12318:1;12290:30;;;;12286:35;22:12315 diff --git a/test/libyul/objectCompiler/eof/creation_with_immutables.yul b/test/libyul/objectCompiler/eof/creation_with_immutables.yul index 63558294f120..aaffee722f8a 100644 --- a/test/libyul/objectCompiler/eof/creation_with_immutables.yul +++ b/test/libyul/objectCompiler/eof/creation_with_immutables.yul @@ -95,6 +95,6 @@ object "a" { // return // } // } -// Bytecode: ef0001010004020001000c030001008704000d000080ffff5f808080ec005f5260205ff3ef0001010004020001004c0300010023040000000080ffff7f11223344556677889900112233445566778899001122334455667788990011225f527f112233445566778899001122334455667788990011223344556677889900112260205260405fee00ef00010100040200010010040040000080ffffd10000d10020905f5260205260405ff348656c6c6f2c20576f726c6421 -// Opcodes: 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP 0xC SUB STOP ADD STOP DUP8 DIV STOP 0xD STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x0 PUSH0 MSTORE PUSH1 0x20 PUSH0 RETURN 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP 0x4C SUB STOP ADD STOP 0x23 DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT PUSH32 0x1122334455667788990011223344556677889900112233445566778899001122 PUSH0 MSTORE PUSH32 0x1122334455667788990011223344556677889900112233445566778899001122 PUSH1 0x20 MSTORE PUSH1 0x40 PUSH0 RETURNCONTRACT 0x0 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP LT DIV STOP BLOCKHASH STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT DATALOADN 0x0 DATALOADN 0x20 SWAP1 PUSH0 MSTORE PUSH1 0x20 MSTORE PUSH1 0x40 PUSH0 RETURN BASEFEE PUSH6 0x6C6C6F2C2057 PUSH16 0x726C6421000000000000000000000000 +// Bytecode: ef0001010004020001000c030001008704000d00008000045f808080ec005f5260205ff3ef0001010004020001004c030001002304000000008000027f11223344556677889900112233445566778899001122334455667788990011225f527f112233445566778899001122334455667788990011223344556677889900112260205260405fee00ef000101000402000100100400400000800003d10000d10020905f5260205260405ff348656c6c6f2c20576f726c6421 +// Opcodes: 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP 0xC SUB STOP ADD STOP DUP8 DIV STOP 0xD STOP STOP DUP1 STOP DIV PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x0 PUSH0 MSTORE PUSH1 0x20 PUSH0 RETURN 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP 0x4C SUB STOP ADD STOP 0x23 DIV STOP STOP STOP STOP DUP1 STOP MUL PUSH32 0x1122334455667788990011223344556677889900112233445566778899001122 PUSH0 MSTORE PUSH32 0x1122334455667788990011223344556677889900112233445566778899001122 PUSH1 0x20 MSTORE PUSH1 0x40 PUSH0 RETURNCONTRACT 0x0 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP LT DIV STOP BLOCKHASH STOP STOP DUP1 STOP SUB DATALOADN 0x0 DATALOADN 0x20 SWAP1 PUSH0 MSTORE PUSH1 0x20 MSTORE PUSH1 0x40 PUSH0 RETURN BASEFEE PUSH6 0x6C6C6F2C2057 PUSH16 0x726C6421000000000000000000000000 // SourceMappings: 80:1:0:-:0;56:26;;;;53:1;46:37;106:2;103:1;96:13 diff --git a/test/libyul/objectCompiler/eof/dataloadn.yul b/test/libyul/objectCompiler/eof/dataloadn.yul index b38222917af0..06ebdaa3ce38 100644 --- a/test/libyul/objectCompiler/eof/dataloadn.yul +++ b/test/libyul/objectCompiler/eof/dataloadn.yul @@ -27,6 +27,6 @@ object "a" { // return // stop // data_acaf3289d7b601cbd114fb36c4d29c85bbfd5e133f14cb355c3fd8d99367964f 48656c6c6f2c20576f726c6421 -// Bytecode: ef0001010004020001000904002d000080ffffd1000d5f5260205ff348656c6c6f2c20576f726c6421 -// Opcodes: 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP MULMOD DIV STOP 0x2D STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT DATALOADN 0xD PUSH0 MSTORE PUSH1 0x20 PUSH0 RETURN BASEFEE PUSH6 0x6C6C6F2C2057 PUSH16 0x726C6421000000000000000000000000 +// Bytecode: ef0001010004020001000904002d0000800002d1000d5f5260205ff348656c6c6f2c20576f726c6421 +// Opcodes: 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP MULMOD DIV STOP 0x2D STOP STOP DUP1 STOP MUL DATALOADN 0xD PUSH0 MSTORE PUSH1 0x20 PUSH0 RETURN BASEFEE PUSH6 0x6C6C6F2C2057 PUSH16 0x726C6421000000000000000000000000 // SourceMappings: 56:15:0:-:0;53:1;46:26;95:2;92:1;85:13 diff --git a/test/libyul/objectCompiler/eof/functions.yul b/test/libyul/objectCompiler/eof/functions.yul index 72167f72ab04..65361efa3b5e 100644 --- a/test/libyul/objectCompiler/eof/functions.yul +++ b/test/libyul/objectCompiler/eof/functions.yul @@ -79,6 +79,6 @@ object "a" { // dup1 // revert // } -// Bytecode: ef000101000c020003001400090003040000000080ffff0101ffff0080ffff5f35e300015f52602035e1000460205ff3e50002e100036063e46005e45f80fd -// Opcodes: 0xEF STOP ADD ADD STOP 0xC MUL STOP SUB STOP EQ STOP MULMOD STOP SUB DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT ADD ADD SELFDESTRUCT SELFDESTRUCT STOP DUP1 SELFDESTRUCT SELFDESTRUCT PUSH0 CALLDATALOAD CALLF 0x1 PUSH0 MSTORE PUSH1 0x20 CALLDATALOAD RJUMPI 0x4 PUSH1 0x20 PUSH0 RETURN JUMPF 0x2 RJUMPI 0x3 PUSH1 0x63 RETF PUSH1 0x5 RETF PUSH0 DUP1 REVERT +// Bytecode: ef000101000c020003001400090003040000000080000201010001008000025f35e300015f52602035e1000460205ff3e50002e100036063e46005e45f80fd +// Opcodes: 0xEF STOP ADD ADD STOP 0xC MUL STOP SUB STOP EQ STOP MULMOD STOP SUB DIV STOP STOP STOP STOP DUP1 STOP MUL ADD ADD STOP ADD STOP DUP1 STOP MUL PUSH0 CALLDATALOAD CALLF 0x1 PUSH0 MSTORE PUSH1 0x20 CALLDATALOAD RJUMPI 0x4 PUSH1 0x20 PUSH0 RETURN JUMPF 0x2 RJUMPI 0x3 PUSH1 0x63 RETF PUSH1 0x5 RETF PUSH0 DUP1 REVERT // SourceMappings: 74:1:0:-:0;61:15;56:21::i;53:1::-;46:32;107:2;94:16;91:37;22:364;151:2;148:1;141:13;111:17;113:13::i217:77:0:-:0;203:121;312:2;173:151::o;234:60::-;257:1;275:5::o376:1:0:-:0;366:12; diff --git a/test/libyul/objectCompiler/eof/prune_unreferenced_container.yul b/test/libyul/objectCompiler/eof/prune_unreferenced_container.yul index 2225fe6ebbd2..0c9f9a382497 100644 --- a/test/libyul/objectCompiler/eof/prune_unreferenced_container.yul +++ b/test/libyul/objectCompiler/eof/prune_unreferenced_container.yul @@ -76,6 +76,6 @@ object "a" { // /* "source":421:649 */ // stop // } -// Bytecode: ef0001010004020001000c030001005b040000000080ffff5f808080ec005f5260205ff3ef00010100040200010048040000000080ffff7f11223344556677889900112233445566778899001122334455667788990011225f527f112233445566778899001122334455667788990011223344556677889900112260205200 -// Opcodes: 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP 0xC SUB STOP ADD STOP JUMPDEST DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x0 PUSH0 MSTORE PUSH1 0x20 PUSH0 RETURN 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP BASEFEE DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT PUSH32 0x1122334455667788990011223344556677889900112233445566778899001122 PUSH0 MSTORE PUSH32 0x1122334455667788990011223344556677889900112233445566778899001122 PUSH1 0x20 MSTORE STOP +// Bytecode: ef0001010004020001000c030001005b04000000008000045f808080ec005f5260205ff3ef0001010004020001004804000000008000027f11223344556677889900112233445566778899001122334455667788990011225f527f112233445566778899001122334455667788990011223344556677889900112260205200 +// Opcodes: 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP 0xC SUB STOP ADD STOP JUMPDEST DIV STOP STOP STOP STOP DUP1 STOP DIV PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x0 PUSH0 MSTORE PUSH1 0x20 PUSH0 RETURN 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP BASEFEE DIV STOP STOP STOP STOP DUP1 STOP MUL PUSH32 0x1122334455667788990011223344556677889900112233445566778899001122 PUSH0 MSTORE PUSH32 0x1122334455667788990011223344556677889900112233445566778899001122 PUSH1 0x20 MSTORE STOP // SourceMappings: 80:1:0:-:0;56:26;;;;53:1;46:37;106:2;103:1;96:13 diff --git a/test/libyul/objectCompiler/eof/rjumps.yul b/test/libyul/objectCompiler/eof/rjumps.yul index b13f3c3625e5..d5f2f6c2117b 100644 --- a/test/libyul/objectCompiler/eof/rjumps.yul +++ b/test/libyul/objectCompiler/eof/rjumps.yul @@ -35,6 +35,6 @@ object "a" { // mstore // /* "source":54:70 */ // rjump{tag_2} -// Bytecode: ef00010100040200010010040000000080ffff6001e1000460205ff360015f52e0fff5 -// Opcodes: 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP LT DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT PUSH1 0x1 RJUMPI 0x4 PUSH1 0x20 PUSH0 RETURN PUSH1 0x1 PUSH0 MSTORE RJUMP 0xFFF5 +// Bytecode: ef0001010004020001001004000000008000026001e1000460205ff360015f52e0fff5 +// Opcodes: 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP LT DIV STOP STOP STOP STOP DUP1 STOP MUL PUSH1 0x1 RJUMPI 0x4 PUSH1 0x20 PUSH0 RETURN PUSH1 0x1 PUSH0 MSTORE RJUMP 0xFFF5 // SourceMappings: 49:4:0:-:0;46:24;22:90;93:2;90:1;83:13;54:16;66:1;63;56:12;54:16 From b292de4f13ceaa100eeed6824d91c053842314dc Mon Sep 17 00:00:00 2001 From: rodiazet Date: Fri, 6 Dec 2024 15:36:22 +0100 Subject: [PATCH 0613/1022] eof: Fix legacy `staticcall` error for EOF. Add test. --- libyul/AsmAnalysis.cpp | 1 + .../yulSyntaxTests/eof/legacy_calls_in_eof.yul | 17 +++++++++++++++++ 2 files changed, 18 insertions(+) create mode 100644 test/libyul/yulSyntaxTests/eof/legacy_calls_in_eof.yul diff --git a/libyul/AsmAnalysis.cpp b/libyul/AsmAnalysis.cpp index b00982faf882..f1664ad685c8 100644 --- a/libyul/AsmAnalysis.cpp +++ b/libyul/AsmAnalysis.cpp @@ -776,6 +776,7 @@ bool AsmAnalyzer::validateInstructions(evmasm::Instruction _instr, SourceLocatio _instr == evmasm::Instruction::CALL || _instr == evmasm::Instruction::CALLCODE || _instr == evmasm::Instruction::DELEGATECALL || + _instr == evmasm::Instruction::STATICCALL || _instr == evmasm::Instruction::SELFDESTRUCT || _instr == evmasm::Instruction::JUMP || _instr == evmasm::Instruction::JUMPI || diff --git a/test/libyul/yulSyntaxTests/eof/legacy_calls_in_eof.yul b/test/libyul/yulSyntaxTests/eof/legacy_calls_in_eof.yul new file mode 100644 index 000000000000..4ed95e6c3f5a --- /dev/null +++ b/test/libyul/yulSyntaxTests/eof/legacy_calls_in_eof.yul @@ -0,0 +1,17 @@ +object "a" { + code { + pop(call(address(), 0, 0, 10)) + pop(staticcall(address(), 0, 0)) + pop(delegatecall(address(), 0, 0)) + } +} + +// ==== +// bytecodeFormat: >=EOFv1 +// ---- +// TypeError 9132: (36-40): The "call" instruction is only available in legacy bytecode VMs (you are currently compiling to EOF). +// TypeError 3950: (36-61): Expected expression to evaluate to one value, but got 0 values instead. +// TypeError 9132: (75-85): The "staticcall" instruction is only available in legacy bytecode VMs (you are currently compiling to EOF). +// TypeError 3950: (75-102): Expected expression to evaluate to one value, but got 0 values instead. +// TypeError 9132: (116-128): The "delegatecall" instruction is only available in legacy bytecode VMs (you are currently compiling to EOF). +// TypeError 3950: (116-145): Expected expression to evaluate to one value, but got 0 values instead. From c5ab3b81400573c25f47402d515de52db9b26963 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Fri, 18 Oct 2024 16:16:30 +0200 Subject: [PATCH 0614/1022] Yul: Add builtin AST element --- libsolidity/analysis/ControlFlowBuilder.cpp | 10 +- libsolidity/analysis/ViewPureChecker.cpp | 9 +- libsolidity/ast/ASTJsonImporter.cpp | 4 +- libyul/AST.h | 11 +- libyul/ASTForward.h | 9 ++ libyul/AsmAnalysis.cpp | 48 +++--- libyul/AsmAnalysis.h | 2 +- libyul/AsmJsonConverter.cpp | 14 +- libyul/AsmJsonConverter.h | 5 +- libyul/AsmJsonImporter.cpp | 13 +- libyul/AsmParser.cpp | 144 +++++++++++------- libyul/AsmParser.h | 4 +- libyul/AsmPrinter.cpp | 8 +- libyul/AsmPrinter.h | 5 +- libyul/ControlFlowSideEffectsCollector.cpp | 5 +- libyul/FunctionReferenceResolver.cpp | 14 +- libyul/Utilities.cpp | 9 ++ libyul/Utilities.h | 1 + libyul/backends/evm/ConstantOptimiser.cpp | 45 +++--- libyul/backends/evm/ConstantOptimiser.h | 4 +- .../backends/evm/ControlFlowGraphBuilder.cpp | 14 +- libyul/backends/evm/EVMCodeTransform.cpp | 10 +- libyul/backends/evm/EVMDialect.cpp | 14 +- libyul/backends/evm/EVMMetrics.cpp | 6 +- libyul/backends/evm/EVMObjectCompiler.cpp | 4 +- .../evm/OptimizedEVMCodeTransform.cpp | 17 ++- .../backends/evm/OptimizedEVMCodeTransform.h | 4 +- .../evm/SSAControlFlowGraphBuilder.cpp | 23 +-- libyul/backends/evm/StackHelpers.h | 11 +- libyul/optimiser/ASTCopier.cpp | 10 ++ libyul/optimiser/ASTCopier.h | 1 + libyul/optimiser/BlockHasher.cpp | 29 +++- libyul/optimiser/BlockHasher.h | 1 + libyul/optimiser/CallGraphGenerator.cpp | 20 ++- libyul/optimiser/CallGraphGenerator.h | 7 +- libyul/optimiser/CircularReferencesPruner.cpp | 4 +- .../CommonSubexpressionEliminator.cpp | 7 +- .../optimiser/CommonSubexpressionEliminator.h | 2 +- libyul/optimiser/ControlFlowSimplifier.cpp | 13 +- libyul/optimiser/DataFlowAnalyzer.cpp | 31 ++-- libyul/optimiser/DataFlowAnalyzer.h | 8 +- libyul/optimiser/EqualStoreEliminator.h | 2 +- .../optimiser/EquivalentFunctionCombiner.cpp | 11 +- libyul/optimiser/ExpressionInliner.cpp | 6 +- libyul/optimiser/ExpressionSimplifier.cpp | 9 +- libyul/optimiser/ExpressionSplitter.cpp | 5 +- libyul/optimiser/ForLoopConditionIntoBody.cpp | 2 +- .../optimiser/ForLoopConditionOutOfBody.cpp | 9 +- libyul/optimiser/FullInliner.cpp | 31 ++-- libyul/optimiser/FullInliner.h | 4 +- libyul/optimiser/FunctionCallFinder.cpp | 23 +-- libyul/optimiser/FunctionCallFinder.h | 8 +- libyul/optimiser/FunctionSpecializer.cpp | 13 +- libyul/optimiser/FunctionSpecializer.h | 14 +- .../InlinableExpressionFunctionFinder.cpp | 10 +- .../InlinableExpressionFunctionFinder.h | 6 +- libyul/optimiser/KnowledgeBase.cpp | 15 +- libyul/optimiser/KnowledgeBase.h | 11 +- libyul/optimiser/LoadResolver.cpp | 12 +- libyul/optimiser/LoadResolver.h | 2 +- libyul/optimiser/LoopInvariantCodeMotion.cpp | 2 +- libyul/optimiser/LoopInvariantCodeMotion.h | 4 +- libyul/optimiser/Metrics.cpp | 2 +- libyul/optimiser/NameCollector.cpp | 9 +- libyul/optimiser/NameCollector.h | 8 +- libyul/optimiser/NameDisplacer.cpp | 3 +- libyul/optimiser/NameSimplifier.cpp | 7 +- libyul/optimiser/OptimizerUtilities.cpp | 9 +- libyul/optimiser/OptimizerUtilities.h | 2 +- libyul/optimiser/Semantics.cpp | 54 ++++--- libyul/optimiser/Semantics.h | 14 +- libyul/optimiser/SimplificationRules.cpp | 20 ++- libyul/optimiser/SimplificationRules.h | 7 +- libyul/optimiser/StackLimitEvader.cpp | 28 ++-- libyul/optimiser/StackToMemoryMover.cpp | 11 +- libyul/optimiser/SyntacticalEquality.cpp | 9 ++ libyul/optimiser/SyntacticalEquality.h | 1 + libyul/optimiser/UnusedAssignEliminator.cpp | 10 +- libyul/optimiser/UnusedPruner.cpp | 10 +- libyul/optimiser/UnusedPruner.h | 11 +- libyul/optimiser/UnusedStoreEliminator.cpp | 34 +++-- libyul/optimiser/UnusedStoreEliminator.h | 4 +- test/libsolidity/MemoryGuardTest.cpp | 6 +- test/libyul/ControlFlowGraphTest.cpp | 14 +- test/libyul/FunctionSideEffects.cpp | 11 +- test/libyul/KnowledgeBaseTest.cpp | 2 +- test/libyul/StackLayoutGeneratorTest.cpp | 21 +-- test/libyul/StackShufflingTest.cpp | 20 ++- test/tools/yulInterpreter/Interpreter.cpp | 25 ++- 89 files changed, 710 insertions(+), 441 deletions(-) diff --git a/libsolidity/analysis/ControlFlowBuilder.cpp b/libsolidity/analysis/ControlFlowBuilder.cpp index a42cec172d49..11d8e84c6601 100644 --- a/libsolidity/analysis/ControlFlowBuilder.cpp +++ b/libsolidity/analysis/ControlFlowBuilder.cpp @@ -19,6 +19,7 @@ #include #include #include +#include #include using namespace solidity::langutil; @@ -582,14 +583,13 @@ void ControlFlowBuilder::operator()(yul::FunctionCall const& _functionCall) solAssert(m_currentNode && m_inlineAssembly, ""); yul::ASTWalker::operator()(_functionCall); - if (auto const& builtinHandle = m_inlineAssembly->dialect().findBuiltin(_functionCall.functionName.name.str())) + if (auto const* builtinFunction = resolveBuiltinFunction(_functionCall.functionName, m_inlineAssembly->dialect())) { - auto const& builtinFunction = m_inlineAssembly->dialect().builtin(*builtinHandle); - if (builtinFunction.controlFlowSideEffects.canTerminate) + if (builtinFunction->controlFlowSideEffects.canTerminate) connect(m_currentNode, m_transactionReturnNode); - if (builtinFunction.controlFlowSideEffects.canRevert) + if (builtinFunction->controlFlowSideEffects.canRevert) connect(m_currentNode, m_revertNode); - if (!builtinFunction.controlFlowSideEffects.canContinue) + if (!builtinFunction->controlFlowSideEffects.canContinue) m_currentNode = newLabel(); } } diff --git a/libsolidity/analysis/ViewPureChecker.cpp b/libsolidity/analysis/ViewPureChecker.cpp index 6a3a902edffe..cbd538551106 100644 --- a/libsolidity/analysis/ViewPureChecker.cpp +++ b/libsolidity/analysis/ViewPureChecker.cpp @@ -18,8 +18,9 @@ #include #include -#include #include +#include +#include #include #include @@ -66,9 +67,9 @@ class AssemblyViewPureChecker void operator()(yul::FunctionCall const& _funCall) { if (yul::EVMDialect const* dialect = dynamic_cast(&m_dialect)) - if (std::optional builtinHandle = dialect->findBuiltin(_funCall.functionName.name.str())) - if (auto const& instruction = dialect->builtin(*builtinHandle).instruction) - checkInstruction(nativeLocationOf(_funCall), *instruction); + if (yul::BuiltinFunctionForEVM const* builtin = resolveBuiltinFunctionForEVM(_funCall.functionName, *dialect)) + if (builtin->instruction) + checkInstruction(nativeLocationOf(_funCall), *builtin->instruction); for (auto const& arg: _funCall.arguments) std::visit(*this, arg); diff --git a/libsolidity/ast/ASTJsonImporter.cpp b/libsolidity/ast/ASTJsonImporter.cpp index 5d59308ae3d9..344bfb39d2a6 100644 --- a/libsolidity/ast/ASTJsonImporter.cpp +++ b/libsolidity/ast/ASTJsonImporter.cpp @@ -742,7 +742,9 @@ ASTPointer ASTJsonImporter::createInlineAssembly(Json const& _no flags->emplace_back(std::make_shared(flag.get())); } } - std::shared_ptr operations = std::make_shared(yul::AsmJsonImporter(dialect, m_sourceNames).createAST(member(_node, "AST"))); + std::shared_ptr operations = std::make_shared( + yul::AsmJsonImporter(dialect, m_sourceNames).createAST(member(_node, "AST")) + ); return createASTNode( _node, nullOrASTString(_node, "documentation"), diff --git a/libyul/AST.h b/libyul/AST.h index be734fa6b906..b19499b9a7d1 100644 --- a/libyul/AST.h +++ b/libyul/AST.h @@ -24,6 +24,7 @@ #pragma once #include +#include #include #include @@ -71,6 +72,9 @@ class LiteralValue { struct Literal { langutil::DebugData::ConstPtr debugData; LiteralKind kind; LiteralValue value; }; /// External / internal identifier or label reference struct Identifier { langutil::DebugData::ConstPtr debugData; YulName name; }; +/// AST Node representing a reference to one of the built-in functions (as defined by the dialect). +/// In the source it's an actual name, while in the AST we only store a handle that can be used to find the the function in the Dialect +struct BuiltinName { langutil::DebugData::ConstPtr debugData; BuiltinHandle handle; }; /// Assignment ("x := mload(20:u256)", expects push-1-expression on the right hand /// side and requires x to occupy exactly one stack slot. /// @@ -78,7 +82,7 @@ struct Identifier { langutil::DebugData::ConstPtr debugData; YulName name; }; /// a single stack slot and expects a single expression on the right hand returning /// the same amount of items as the number of variables. struct Assignment { langutil::DebugData::ConstPtr debugData; std::vector variableNames; std::unique_ptr value; }; -struct FunctionCall { langutil::DebugData::ConstPtr debugData; Identifier functionName; std::vector arguments; }; +struct FunctionCall { langutil::DebugData::ConstPtr debugData; FunctionName functionName; std::vector arguments; }; /// Statement that contains only a single expression struct ExpressionStatement { langutil::DebugData::ConstPtr debugData; Expression expression; }; /// Block-scope variable declaration ("let x:u256 := mload(20:u256)"), non-hoisted @@ -114,6 +118,11 @@ class AST Block m_root; }; +bool constexpr isBuiltinFunctionCall(FunctionCall const& _functionCall) noexcept +{ + return std::holds_alternative(_functionCall.functionName); +} + /// Extracts the IR source location from a Yul node. template inline langutil::SourceLocation nativeLocationOf(T const& _node) diff --git a/libyul/ASTForward.h b/libyul/ASTForward.h index 8aba4f248c07..868fc84b2827 100644 --- a/libyul/ASTForward.h +++ b/libyul/ASTForward.h @@ -28,6 +28,9 @@ namespace solidity::yul { +class YulString; +using YulName = YulString; + enum class LiteralKind; class LiteralValue; struct Literal; @@ -46,11 +49,17 @@ struct Continue; struct Leave; struct ExpressionStatement; struct Block; +struct BuiltinName; +struct BuiltinHandle; class AST; struct NameWithDebugData; using Expression = std::variant; +using FunctionName = std::variant; +/// Type that can refer to both user-defined functions and built-ins. +/// Technically the AST allows these names to overlap, but this is not possible to represent in the source. +using FunctionHandle = std::variant; using Statement = std::variant; } diff --git a/libyul/AsmAnalysis.cpp b/libyul/AsmAnalysis.cpp index b00982faf882..7d395a208a99 100644 --- a/libyul/AsmAnalysis.cpp +++ b/libyul/AsmAnalysis.cpp @@ -313,15 +313,14 @@ void AsmAnalyzer::operator()(FunctionDefinition const& _funDef) size_t AsmAnalyzer::operator()(FunctionCall const& _funCall) { - yulAssert(!_funCall.functionName.name.empty(), ""); auto watcher = m_errorReporter.errorWatcher(); std::optional numParameters; std::optional numReturns; std::vector> const* literalArguments = nullptr; - if (std::optional handle = m_dialect.findBuiltin(_funCall.functionName.name.str())) + if (BuiltinFunction const* builtin = resolveBuiltinFunction(_funCall.functionName, m_dialect)) { - if (_funCall.functionName.name == "selfdestruct"_yulname) + if (builtin->name == "selfdestruct") m_errorReporter.warning( 1699_error, nativeLocationOf(_funCall.functionName), @@ -334,7 +333,7 @@ size_t AsmAnalyzer::operator()(FunctionCall const& _funCall) ); else if ( m_evmVersion.supportsTransientStorage() && - _funCall.functionName.name == "tstore"_yulname && + builtin->name == "tstore" && !m_errorReporter.hasError({2394}) ) m_errorReporter.warning( @@ -347,16 +346,15 @@ size_t AsmAnalyzer::operator()(FunctionCall const& _funCall) "The use of transient storage for reentrancy guards that are cleared at the end of the call is safe." ); - BuiltinFunction const& f = m_dialect.builtin(*handle); - numParameters = f.numParameters; - numReturns = f.numReturns; - if (!f.literalArguments.empty()) - literalArguments = &f.literalArguments; + numParameters = builtin->numParameters; + numReturns = builtin->numReturns; + if (!builtin->literalArguments.empty()) + literalArguments = &builtin->literalArguments; validateInstructions(_funCall); - m_sideEffects += f.sideEffects; + m_sideEffects += builtin->sideEffects; } - else if (m_currentScope->lookup(_funCall.functionName.name, GenericVisitor{ + else if (m_currentScope->lookup(YulName{std::string(resolveFunctionName(_funCall.functionName, m_dialect))}, GenericVisitor{ [&](Scope::Variable const&) { m_errorReporter.typeError( @@ -372,10 +370,11 @@ size_t AsmAnalyzer::operator()(FunctionCall const& _funCall) } })) { + yulAssert(std::holds_alternative(_funCall.functionName)); if (m_resolver) // We found a local reference, make sure there is no external reference. m_resolver( - _funCall.functionName, + std::get(_funCall.functionName), yul::IdentifierContext::NonExternal, m_currentScope->insideFunction() ); @@ -386,7 +385,7 @@ size_t AsmAnalyzer::operator()(FunctionCall const& _funCall) m_errorReporter.declarationError( 4619_error, nativeLocationOf(_funCall.functionName), - "Function \"" + _funCall.functionName.name.str() + "\" not found." + fmt::format("Function \"{}\" not found.", resolveFunctionName(_funCall.functionName, m_dialect)) ); yulAssert(!watcher.ok(), "Expected a reported error."); } @@ -395,10 +394,12 @@ size_t AsmAnalyzer::operator()(FunctionCall const& _funCall) m_errorReporter.typeError( 7000_error, nativeLocationOf(_funCall.functionName), - "Function \"" + _funCall.functionName.name.str() + "\" expects " + - std::to_string(*numParameters) + - " arguments but got " + - std::to_string(_funCall.arguments.size()) + "." + fmt::format( + "Function \"{}\" expects {} arguments but got {}.", + resolveFunctionName(_funCall.functionName, m_dialect), + *numParameters, + _funCall.arguments.size() + ) ); for (size_t i = _funCall.arguments.size(); i > 0; i--) @@ -424,7 +425,7 @@ size_t AsmAnalyzer::operator()(FunctionCall const& _funCall) ); else if (*literalArgumentKind == LiteralKind::String) { - std::string functionName = _funCall.functionName.name.str(); + std::string_view functionName = resolveFunctionName(_funCall.functionName, m_dialect); if (functionName == "datasize" || functionName == "dataoffset") { auto const& argumentAsLiteral = std::get(arg); @@ -455,7 +456,7 @@ size_t AsmAnalyzer::operator()(FunctionCall const& _funCall) m_errorReporter.typeError( 2186_error, nativeLocationOf(arg), - "Name required but path given as \"" + functionName + "\" argument." + fmt::format("Name required but path given as \"{}\" argument.", functionName) ); if (!m_objectStructure.topLevelSubObjectNames().count(formattedLiteral)) @@ -480,7 +481,7 @@ size_t AsmAnalyzer::operator()(FunctionCall const& _funCall) } else if (*literalArgumentKind == LiteralKind::Number) { - std::string functionName = _funCall.functionName.name.str(); + std::string_view functionName = resolveFunctionName(_funCall.functionName, m_dialect); if (functionName == "auxdataloadn") { auto const& argumentAsLiteral = std::get(arg); @@ -686,7 +687,7 @@ void AsmAnalyzer::expectValidIdentifier(YulName _identifier, SourceLocation cons ); } -bool AsmAnalyzer::validateInstructions(std::string const& _instructionIdentifier, langutil::SourceLocation const& _location) +bool AsmAnalyzer::validateInstructions(std::string_view _instructionIdentifier, langutil::SourceLocation const& _location) { // NOTE: This function uses the default EVM version instead of the currently selected one. auto const& defaultEVMDialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); @@ -813,7 +814,10 @@ bool AsmAnalyzer::validateInstructions(evmasm::Instruction _instr, SourceLocatio bool AsmAnalyzer::validateInstructions(FunctionCall const& _functionCall) { - return validateInstructions(_functionCall.functionName.name.str(), nativeLocationOf(_functionCall.functionName)); + return validateInstructions( + resolveFunctionName(_functionCall.functionName, m_dialect), + nativeLocationOf(_functionCall.functionName) + ); } void AsmAnalyzer::validateObjectStructure(langutil::SourceLocation _astRootLocation) diff --git a/libyul/AsmAnalysis.h b/libyul/AsmAnalysis.h index 6235b530d16d..e8c02fbec132 100644 --- a/libyul/AsmAnalysis.h +++ b/libyul/AsmAnalysis.h @@ -118,7 +118,7 @@ class AsmAnalyzer void expectValidIdentifier(YulName _identifier, langutil::SourceLocation const& _location); bool validateInstructions(evmasm::Instruction _instr, langutil::SourceLocation const& _location); - bool validateInstructions(std::string const& _instrIdentifier, langutil::SourceLocation const& _location); + bool validateInstructions(std::string_view _instrIdentifier, langutil::SourceLocation const& _location); bool validateInstructions(FunctionCall const& _functionCall); void validateObjectStructure(langutil::SourceLocation _astRootLocation); diff --git a/libyul/AsmJsonConverter.cpp b/libyul/AsmJsonConverter.cpp index 226ac52a5ac8..fd36dd26022c 100644 --- a/libyul/AsmJsonConverter.cpp +++ b/libyul/AsmJsonConverter.cpp @@ -20,8 +20,10 @@ * Converts inline assembly AST to JSON format */ -#include #include + +#include +#include #include #include #include @@ -83,6 +85,14 @@ Json AsmJsonConverter::operator()(Identifier const& _node) const return ret; } +Json AsmJsonConverter::operator()(BuiltinName const& _node) const +{ + // represents BuiltinName also with YulIdentifier node type to avoid a breaking change in the JSON interface + Json ret = createAstNode(originLocationOf(_node), nativeLocationOf(_node), "YulIdentifier"); + ret["name"] = m_dialect.builtin(_node.handle).name; + return ret; +} + Json AsmJsonConverter::operator()(Assignment const& _node) const { yulAssert(_node.variableNames.size() >= 1, "Invalid assignment syntax"); @@ -96,7 +106,7 @@ Json AsmJsonConverter::operator()(Assignment const& _node) const Json AsmJsonConverter::operator()(FunctionCall const& _node) const { Json ret = createAstNode(originLocationOf(_node), nativeLocationOf(_node), "YulFunctionCall"); - ret["functionName"] = (*this)(_node.functionName); + ret["functionName"] = std::visit(*this, _node.functionName); ret["arguments"] = vectorOfVariantsToJson(_node.arguments); return ret; } diff --git a/libyul/AsmJsonConverter.h b/libyul/AsmJsonConverter.h index 75e3400b7d3e..458142e29346 100644 --- a/libyul/AsmJsonConverter.h +++ b/libyul/AsmJsonConverter.h @@ -43,12 +43,14 @@ class AsmJsonConverter: public boost::static_visitor public: /// Create a converter to JSON for any block of inline assembly /// @a _sourceIndex to be used to abbreviate source name in the source locations - explicit AsmJsonConverter(Dialect const&, std::optional _sourceIndex): m_sourceIndex(_sourceIndex) {} + AsmJsonConverter(Dialect const& _dialect, std::optional _sourceIndex): + m_dialect(_dialect), m_sourceIndex(_sourceIndex) {} Json operator()(Block const& _node) const; Json operator()(NameWithDebugData const& _node) const; Json operator()(Literal const& _node) const; Json operator()(Identifier const& _node) const; + Json operator()(BuiltinName const& _node) const; Json operator()(Assignment const& _node) const; Json operator()(VariableDeclaration const& _node) const; Json operator()(FunctionDefinition const& _node) const; @@ -68,6 +70,7 @@ class AsmJsonConverter: public boost::static_visitor template Json vectorOfVariantsToJson(std::vector const& vec) const; + Dialect const& m_dialect; std::optional const m_sourceIndex; }; diff --git a/libyul/AsmJsonImporter.cpp b/libyul/AsmJsonImporter.cpp index 692169fd29c6..a937be62fb7a 100644 --- a/libyul/AsmJsonImporter.cpp +++ b/libyul/AsmJsonImporter.cpp @@ -23,7 +23,9 @@ */ #include + #include +#include #include #include @@ -255,7 +257,16 @@ FunctionCall AsmJsonImporter::createFunctionCall(Json const& _node) for (auto const& var: member(_node, "arguments")) functionCall.arguments.emplace_back(createExpression(var)); - functionCall.functionName = createIdentifier(member(_node, "functionName")); + auto const functionNameNode = member(_node, "functionName"); + auto const name = member(functionNameNode, "name").get(); + if (std::optional builtinHandle = m_dialect.findBuiltin(name)) + { + auto builtin = createAsmNode(functionNameNode); + builtin.handle = *builtinHandle; + functionCall.functionName = builtin; + } + else + functionCall.functionName = createIdentifier(functionNameNode); return functionCall; } diff --git a/libyul/AsmParser.cpp b/libyul/AsmParser.cpp index baef6a3c52ad..66ac22a08e72 100644 --- a/libyul/AsmParser.cpp +++ b/libyul/AsmParser.cpp @@ -405,7 +405,7 @@ Statement Parser::parseStatement() // Options left: // Expression/FunctionCall // Assignment - std::variant elementary(parseLiteralOrIdentifier()); + std::variant elementary(parseLiteralOrIdentifier()); switch (currentToken()) { @@ -420,35 +420,47 @@ Statement Parser::parseStatement() Assignment assignment; assignment.debugData = debugDataOf(elementary); - while (true) + bool foundListEnd = false; + do { - if (!std::holds_alternative(elementary)) - { - auto const token = currentToken() == Token::Comma ? "," : ":="; - - fatalParserError( - 2856_error, - std::string("Variable name must precede \"") + - token + - "\"" + - (currentToken() == Token::Comma ? " in multiple assignment." : " in assignment.") - ); - } - - auto const& identifier = std::get(elementary); - - if (m_dialect.findBuiltin(identifier.name.str())) - fatalParserError(6272_error, "Cannot assign to builtin function \"" + identifier.name.str() + "\"."); - - assignment.variableNames.emplace_back(identifier); - - if (currentToken() != Token::Comma) - break; - - expectToken(Token::Comma); - - elementary = parseLiteralOrIdentifier(); - } + std::visit(GenericVisitor{ + [&](Literal const&) + { + auto const token = currentToken() == Token::Comma ? "," : ":="; + + fatalParserError( + 2856_error, + std::string("Variable name must precede \"") + + token + + "\"" + + (currentToken() == Token::Comma ? " in multiple assignment." : " in assignment.") + ); + }, + [&](BuiltinName const& _builtin) + { + fatalParserError( + 6272_error, + fmt::format( + "Cannot assign to builtin function \"{}\".", + m_dialect.builtin(_builtin.handle).name + ) + ); + }, + [&](Identifier const& _identifier) + { + assignment.variableNames.emplace_back(_identifier); + + if (currentToken() != Token::Comma) + foundListEnd = true; + else + { + expectToken(Token::Comma); + elementary = parseLiteralOrIdentifier(); + } + } + }, elementary); + + } while (!foundListEnd); expectToken(Token::AssemblyAssign); @@ -475,7 +487,7 @@ Case Parser::parseCase() else if (currentToken() == Token::Case) { advance(); - std::variant literal = parseLiteralOrIdentifier(); + std::variant literal = parseLiteralOrIdentifier(); if (!std::holds_alternative(literal)) fatalParserError(4805_error, "Literal expected."); _case.value = std::make_unique(std::get(std::move(literal))); @@ -514,20 +526,25 @@ Expression Parser::parseExpression(bool _unlimitedLiteralArgument) { RecursionGuard recursionGuard(*this); - std::variant operation = parseLiteralOrIdentifier(_unlimitedLiteralArgument); + std::variant operation = parseLiteralOrIdentifier(_unlimitedLiteralArgument); return visit(GenericVisitor{ [&](Identifier& _identifier) -> Expression { if (currentToken() == Token::LParen) return parseCall(std::move(operation)); - if (m_dialect.findBuiltin(_identifier.name.str())) - fatalParserError( - 7104_error, - nativeLocationOf(_identifier), - "Builtin function \"" + _identifier.name.str() + "\" must be called." - ); return std::move(_identifier); }, + [&](BuiltinName& _builtin) -> Expression + { + if (currentToken() == Token::LParen) + return parseCall(std::move(operation)); + fatalParserError( + 7104_error, + nativeLocationOf(_builtin), + "Builtin function \"" + m_dialect.builtin(_builtin.handle).name + "\" must be called." + ); + unreachable(); + }, [&](Literal& _literal) -> Expression { return std::move(_literal); @@ -535,16 +552,20 @@ Expression Parser::parseExpression(bool _unlimitedLiteralArgument) }, operation); } -std::variant Parser::parseLiteralOrIdentifier(bool _unlimitedLiteralArgument) +std::variant Parser::parseLiteralOrIdentifier(bool _unlimitedLiteralArgument) { RecursionGuard recursionGuard(*this); switch (currentToken()) { case Token::Identifier: { - Identifier identifier{createDebugData(), YulName{currentLiteral()}}; + std::variant literalOrIdentifier; + if (std::optional const builtinHandle = m_dialect.findBuiltin(currentLiteral())) + literalOrIdentifier = BuiltinName{createDebugData(), *builtinHandle}; + else + literalOrIdentifier = Identifier{createDebugData(), YulName{currentLiteral()}}; advance(); - return identifier; + return literalOrIdentifier; } case Token::StringLiteral: case Token::HexStringLiteral: @@ -671,36 +692,45 @@ FunctionDefinition Parser::parseFunctionDefinition() return funDef; } -FunctionCall Parser::parseCall(std::variant&& _initialOp) +FunctionCall Parser::parseCall(std::variant&& _initialOp) { RecursionGuard recursionGuard(*this); - if (!std::holds_alternative(_initialOp)) - fatalParserError(9980_error, "Function name expected."); - - FunctionCall ret; - ret.functionName = std::move(std::get(_initialOp)); - ret.debugData = ret.functionName.debugData; - auto const isUnlimitedLiteralArgument = [handle=m_dialect.findBuiltin(ret.functionName.name.str()), this](size_t const index) { - if (!handle) - return false; - auto const& function = m_dialect.builtin(*handle); - return index < function.literalArguments.size() && function.literalArgument(index).has_value(); - }; + std::function isUnlimitedLiteralArgument = [](size_t) -> bool { return false; }; + FunctionCall functionCall; + std::visit(GenericVisitor{ + [&](Literal const&) { fatalParserError(9980_error, "Function name expected."); }, + [&](Identifier const& _identifier) + { + functionCall.debugData = _identifier.debugData; + functionCall.functionName = _identifier; + }, + [&](BuiltinName const& _builtin) + { + isUnlimitedLiteralArgument = [builtinFunction=m_dialect.builtin(_builtin.handle)](size_t _index) { + if (_index < builtinFunction.literalArguments.size()) + return builtinFunction.literalArgument(_index).has_value(); + return false; + }; + functionCall.debugData = _builtin.debugData; + functionCall.functionName = _builtin; + } + }, _initialOp); + size_t argumentIndex {0}; expectToken(Token::LParen); if (currentToken() != Token::RParen) { - ret.arguments.emplace_back(parseExpression(isUnlimitedLiteralArgument(argumentIndex++))); + functionCall.arguments.emplace_back(parseExpression(isUnlimitedLiteralArgument(argumentIndex++))); while (currentToken() != Token::RParen) { expectToken(Token::Comma); - ret.arguments.emplace_back(parseExpression(isUnlimitedLiteralArgument(argumentIndex++))); + functionCall.arguments.emplace_back(parseExpression(isUnlimitedLiteralArgument(argumentIndex++))); } } - updateLocationEndFrom(ret.debugData, currentLocation()); + updateLocationEndFrom(functionCall.debugData, currentLocation()); expectToken(Token::RParen); - return ret; + return functionCall; } NameWithDebugData Parser::parseNameWithDebugData() diff --git a/libyul/AsmParser.h b/libyul/AsmParser.h index d4616a2a9508..b546e179fd96 100644 --- a/libyul/AsmParser.h +++ b/libyul/AsmParser.h @@ -141,10 +141,10 @@ class Parser: public langutil::ParserBase Expression parseExpression(bool _unlimitedLiteralArgument = false); /// Parses an elementary operation, i.e. a literal, identifier, instruction or /// builtin function call (only the name). - std::variant parseLiteralOrIdentifier(bool _unlimitedLiteralArgument = false); + std::variant parseLiteralOrIdentifier(bool _unlimitedLiteralArgument = false); VariableDeclaration parseVariableDeclaration(); FunctionDefinition parseFunctionDefinition(); - FunctionCall parseCall(std::variant&& _initialOp); + FunctionCall parseCall(std::variant&& _index); NameWithDebugData parseNameWithDebugData(); YulName expectAsmIdentifier(); void raiseUnsupportedTypesError(langutil::SourceLocation const& _location) const; diff --git a/libyul/AsmPrinter.cpp b/libyul/AsmPrinter.cpp index 5ba19014995b..a3f7b4ca2b23 100644 --- a/libyul/AsmPrinter.cpp +++ b/libyul/AsmPrinter.cpp @@ -23,6 +23,7 @@ #include #include +#include #include #include @@ -77,6 +78,11 @@ std::string AsmPrinter::operator()(Identifier const& _identifier) return formatDebugData(_identifier) + _identifier.name.str(); } +std::string AsmPrinter::operator()(BuiltinName const& _builtin) +{ + return formatDebugData(_builtin) + m_dialect.builtin(_builtin.handle).name; +} + std::string AsmPrinter::operator()(ExpressionStatement const& _statement) { std::string const locationComment = formatDebugData(_statement); @@ -145,7 +151,7 @@ std::string AsmPrinter::operator()(FunctionDefinition const& _functionDefinition std::string AsmPrinter::operator()(FunctionCall const& _functionCall) { std::string const locationComment = formatDebugData(_functionCall); - std::string const functionName = (*this)(_functionCall.functionName); + std::string const functionName = std::visit(*this, _functionCall.functionName); return locationComment + functionName + "(" + diff --git a/libyul/AsmPrinter.h b/libyul/AsmPrinter.h index 6b63c863883e..d889d83f80ec 100644 --- a/libyul/AsmPrinter.h +++ b/libyul/AsmPrinter.h @@ -54,11 +54,12 @@ class AsmPrinter ); explicit AsmPrinter( - Dialect const&, + Dialect const& _dialect, std::optional>> const& _sourceIndexToName = {}, langutil::DebugInfoSelection const& _debugInfoSelection = langutil::DebugInfoSelection::Default(), langutil::CharStreamProvider const* _soliditySourceProvider = nullptr ): + m_dialect(_dialect), m_debugInfoSelection(_debugInfoSelection), m_soliditySourceProvider(_soliditySourceProvider) { @@ -69,6 +70,7 @@ class AsmPrinter std::string operator()(Literal const& _literal); std::string operator()(Identifier const& _identifier); + std::string operator()(BuiltinName const& _builtin); std::string operator()(ExpressionStatement const& _expr); std::string operator()(Assignment const& _assignment); std::string operator()(VariableDeclaration const& _variableDeclaration); @@ -99,6 +101,7 @@ class AsmPrinter return formatDebugData(_node.debugData, !isExpression); } + Dialect const& m_dialect; std::map m_nameToSourceIndex; langutil::SourceLocation m_lastLocation = {}; langutil::DebugInfoSelection m_debugInfoSelection = {}; diff --git a/libyul/ControlFlowSideEffectsCollector.cpp b/libyul/ControlFlowSideEffectsCollector.cpp index 2694eef1c385..28089b029fca 100644 --- a/libyul/ControlFlowSideEffectsCollector.cpp +++ b/libyul/ControlFlowSideEffectsCollector.cpp @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -271,8 +272,8 @@ ControlFlowNode const* ControlFlowSideEffectsCollector::nextProcessableNode(Func ControlFlowSideEffects const& ControlFlowSideEffectsCollector::sideEffects(FunctionCall const& _call) const { - if (std::optional builtinHandle = m_dialect.findBuiltin(_call.functionName.name.str())) - return m_dialect.builtin(*builtinHandle).controlFlowSideEffects; + if (BuiltinFunction const* builtin = resolveBuiltinFunction(_call.functionName, m_dialect)) + return builtin->controlFlowSideEffects; else return m_functionSideEffects.at(m_functionReferences.at(&_call)); } diff --git a/libyul/FunctionReferenceResolver.cpp b/libyul/FunctionReferenceResolver.cpp index 99e83c2130e7..bf3f536a49a8 100644 --- a/libyul/FunctionReferenceResolver.cpp +++ b/libyul/FunctionReferenceResolver.cpp @@ -34,15 +34,17 @@ FunctionReferenceResolver::FunctionReferenceResolver(Block const& _ast) void FunctionReferenceResolver::operator()(FunctionCall const& _functionCall) { - for (auto&& scope: m_scopes | ranges::views::reverse) - if (FunctionDefinition const** function = util::valueOrNullptr(scope, _functionCall.functionName.name)) + if (!isBuiltinFunctionCall(_functionCall)) + for (auto&& scope: m_scopes | ranges::views::reverse) { - m_functionReferences[&_functionCall] = *function; - break; + yulAssert(std::holds_alternative(_functionCall.functionName)); + if (FunctionDefinition const** function = util::valueOrNullptr(scope, std::get(_functionCall.functionName).name)) + { + m_functionReferences[&_functionCall] = *function; + break; + } } - // If we did not find anything, it was a builtin call. - ASTWalker::operator()(_functionCall); } diff --git a/libyul/Utilities.cpp b/libyul/Utilities.cpp index dd32d6a604d1..e7caf1b2dff4 100644 --- a/libyul/Utilities.cpp +++ b/libyul/Utilities.cpp @@ -269,3 +269,12 @@ BuiltinFunctionForEVM const* yul::resolveBuiltinFunctionForEVM(FunctionName cons return std::visit(visitor, _functionName); } +FunctionHandle yul::functionNameToHandle(FunctionName const& _functionName) +{ + GenericVisitor visitor{ + [&](Identifier const& _identifier) -> FunctionHandle { return _identifier.name; }, + [&](BuiltinName const& _builtin) -> FunctionHandle { return _builtin.handle; } + }; + return std::visit(visitor, _functionName); +} + diff --git a/libyul/Utilities.h b/libyul/Utilities.h index 2341ee62a6c5..a4a558a855b9 100644 --- a/libyul/Utilities.h +++ b/libyul/Utilities.h @@ -92,5 +92,6 @@ std::string_view resolveFunctionName(FunctionName const& _functionName, Dialect BuiltinFunction const* resolveBuiltinFunction(FunctionName const& _functionName, Dialect const& _dialect); BuiltinFunctionForEVM const* resolveBuiltinFunctionForEVM(FunctionName const& _functionName, EVMDialect const& _dialect); +FunctionHandle functionNameToHandle(FunctionName const& _functionName); } diff --git a/libyul/backends/evm/ConstantOptimiser.cpp b/libyul/backends/evm/ConstantOptimiser.cpp index 0ea8f4e5a9fc..d7aed27c339f 100644 --- a/libyul/backends/evm/ConstantOptimiser.cpp +++ b/libyul/backends/evm/ConstantOptimiser.cpp @@ -74,11 +74,10 @@ struct MiniEVMInterpreter u256 operator()(FunctionCall const& _funCall) { - std::optional funHandle = m_dialect.findBuiltin(_funCall.functionName.name.str()); - yulAssert(funHandle, "Expected builtin function."); - BuiltinFunctionForEVM const& fun = m_dialect.builtin(*funHandle); - yulAssert(fun.instruction, "Expected EVM instruction."); - return eval(*fun.instruction, _funCall.arguments); + BuiltinFunctionForEVM const* builtin = resolveBuiltinFunctionForEVM(_funCall.functionName, m_dialect); + yulAssert(builtin, "Expected builtin function."); + yulAssert(builtin->instruction, "Expected EVM instruction."); + return eval(*builtin->instruction, _funCall.arguments); } u256 operator()(Literal const& _literal) { @@ -126,11 +125,20 @@ Representation const& RepresentationFinder::findRepresentation(u256 const& _valu if (m_cache.count(_value)) return m_cache.at(_value); + yulAssert(m_dialect.auxiliaryBuiltinHandles().not_); + yulAssert(m_dialect.auxiliaryBuiltinHandles().shl); + yulAssert(m_dialect.auxiliaryBuiltinHandles().exp); + yulAssert(m_dialect.auxiliaryBuiltinHandles().mul); + yulAssert(m_dialect.auxiliaryBuiltinHandles().add); + yulAssert(m_dialect.auxiliaryBuiltinHandles().sub); + + auto const& auxHandles = m_dialect.auxiliaryBuiltinHandles(); + Representation routine = represent(_value); if (numberEncodingSize(~_value) < numberEncodingSize(_value)) // Negated is shorter to represent - routine = min(std::move(routine), represent("not"_yulname, findRepresentation(~_value))); + routine = min(std::move(routine), represent(*auxHandles.not_, findRepresentation(~_value))); // Decompose value into a * 2**k + b where abs(b) << 2**k for (unsigned bits = 255; bits > 8 && m_maxSteps > 0; --bits) @@ -153,21 +161,21 @@ Representation const& RepresentationFinder::findRepresentation(u256 const& _valu continue; Representation newRoutine; if (m_dialect.evmVersion().hasBitwiseShifting()) - newRoutine = represent("shl"_yulname, represent(bits), findRepresentation(upperPart)); + newRoutine = represent(*auxHandles.shl, represent(bits), findRepresentation(upperPart)); else { - newRoutine = represent("exp"_yulname, represent(2), represent(bits)); + newRoutine = represent(*auxHandles.exp, represent(2), represent(bits)); if (upperPart != 1) - newRoutine = represent("mul"_yulname, findRepresentation(upperPart), newRoutine); + newRoutine = represent(*auxHandles.mul, findRepresentation(upperPart), newRoutine); } if (newRoutine.cost >= routine.cost) continue; if (lowerPart > 0) - newRoutine = represent("add"_yulname, newRoutine, findRepresentation(u256(abs(lowerPart)))); + newRoutine = represent(*auxHandles.add, newRoutine, findRepresentation(u256(abs(lowerPart)))); else if (lowerPart < 0) - newRoutine = represent("sub"_yulname, newRoutine, findRepresentation(u256(abs(lowerPart)))); + newRoutine = represent(*auxHandles.sub, newRoutine, findRepresentation(u256(abs(lowerPart)))); if (m_maxSteps > 0) m_maxSteps--; @@ -186,24 +194,22 @@ Representation RepresentationFinder::represent(u256 const& _value) const } Representation RepresentationFinder::represent( - YulName _instruction, + BuiltinHandle const& _instruction, Representation const& _argument ) const { Representation repr; repr.expression = std::make_unique(FunctionCall{ m_debugData, - Identifier{m_debugData, _instruction}, + BuiltinName{m_debugData, _instruction}, {ASTCopier{}.translate(*_argument.expression)} }); - repr.cost = _argument.cost + m_meter.instructionCosts( - *m_dialect.builtin(*m_dialect.findBuiltin(_instruction.str())).instruction - ); + repr.cost = _argument.cost + m_meter.instructionCosts(*m_dialect.builtin(_instruction).instruction); return repr; } Representation RepresentationFinder::represent( - YulName _instruction, + BuiltinHandle const& _instruction, Representation const& _arg1, Representation const& _arg2 ) const @@ -211,11 +217,10 @@ Representation RepresentationFinder::represent( Representation repr; repr.expression = std::make_unique(FunctionCall{ m_debugData, - Identifier{m_debugData, _instruction}, + BuiltinName{m_debugData, _instruction}, {ASTCopier{}.translate(*_arg1.expression), ASTCopier{}.translate(*_arg2.expression)} }); - repr.cost = m_meter.instructionCosts( - *m_dialect.builtin(*m_dialect.findBuiltin(_instruction.str())).instruction) + _arg1.cost + _arg2.cost; + repr.cost = m_meter.instructionCosts(*m_dialect.builtin(_instruction).instruction) + _arg1.cost + _arg2.cost; return repr; } diff --git a/libyul/backends/evm/ConstantOptimiser.h b/libyul/backends/evm/ConstantOptimiser.h index 35d7dfa43254..5e4b2002b0d0 100644 --- a/libyul/backends/evm/ConstantOptimiser.h +++ b/libyul/backends/evm/ConstantOptimiser.h @@ -93,8 +93,8 @@ class RepresentationFinder Representation const& findRepresentation(u256 const& _value); Representation represent(u256 const& _value) const; - Representation represent(YulName _instruction, Representation const& _arg) const; - Representation represent(YulName _instruction, Representation const& _arg1, Representation const& _arg2) const; + Representation represent(BuiltinHandle const& _instruction, Representation const& _arg) const; + Representation represent(BuiltinHandle const& _instruction, Representation const& _arg1, Representation const& _arg2) const; Representation min(Representation _a, Representation _b); diff --git a/libyul/backends/evm/ControlFlowGraphBuilder.cpp b/libyul/backends/evm/ControlFlowGraphBuilder.cpp index e92515e988ad..990456732bb9 100644 --- a/libyul/backends/evm/ControlFlowGraphBuilder.cpp +++ b/libyul/backends/evm/ControlFlowGraphBuilder.cpp @@ -524,29 +524,29 @@ Stack const& ControlFlowGraphBuilder::visitFunctionCall(FunctionCall const& _cal Stack const* output = nullptr; bool canContinue = true; - if (std::optional const& builtinHandle = m_dialect.findBuiltin(_call.functionName.name.str())) + if (BuiltinFunction const* builtin = resolveBuiltinFunction(_call.functionName, m_dialect)) { - auto const& builtin = m_dialect.builtin(*builtinHandle); Stack inputs; for (auto&& [idx, arg]: _call.arguments | ranges::views::enumerate | ranges::views::reverse) - if (!builtin.literalArgument(idx).has_value()) + if (!builtin->literalArgument(idx).has_value()) inputs.emplace_back(std::visit(*this, arg)); - CFG::BuiltinCall builtinCall{_call.debugData, builtin, _call, inputs.size()}; + CFG::BuiltinCall builtinCall{_call.debugData, *builtin, _call, inputs.size()}; output = &m_currentBlock->operations.emplace_back(CFG::Operation{ // input std::move(inputs), // output - ranges::views::iota(0u, builtin.numReturns) | ranges::views::transform([&](size_t _i) { + ranges::views::iota(0u, builtin->numReturns) | ranges::views::transform([&](size_t _i) { return TemporarySlot{_call, _i}; }) | ranges::to, // operation std::move(builtinCall) }).output; - canContinue = builtin.controlFlowSideEffects.canContinue; + canContinue = builtin->controlFlowSideEffects.canContinue; } else { - Scope::Function const& function = lookupFunction(_call.functionName.name); + yulAssert(std::holds_alternative(_call.functionName)); + Scope::Function const& function = lookupFunction(std::get(_call.functionName).name); canContinue = m_graph.functionInfo.at(&function).canContinue; Stack inputs; // For EOF (m_simulateFunctionsWithJumps == false) we do not have to put return label on stack. diff --git a/libyul/backends/evm/EVMCodeTransform.cpp b/libyul/backends/evm/EVMCodeTransform.cpp index e354649e75d6..f77e4e047d7a 100644 --- a/libyul/backends/evm/EVMCodeTransform.cpp +++ b/libyul/backends/evm/EVMCodeTransform.cpp @@ -230,22 +230,22 @@ void CodeTransform::operator()(FunctionCall const& _call) yulAssert(m_scope, ""); m_assembly.setSourceLocation(originLocationOf(_call)); - if (std::optional builtinHandle = m_dialect.findBuiltin(_call.functionName.name.str())) + if (BuiltinFunctionForEVM const* builtin = resolveBuiltinFunctionForEVM(_call.functionName, m_dialect)) { - BuiltinFunctionForEVM const& builtin = m_dialect.builtin(*builtinHandle); for (auto&& [i, arg]: _call.arguments | ranges::views::enumerate | ranges::views::reverse) - if (!builtin.literalArgument(i)) + if (!builtin->literalArgument(i)) visitExpression(arg); m_assembly.setSourceLocation(originLocationOf(_call)); - builtin.generateCode(_call, m_assembly, m_builtinContext); + builtin->generateCode(_call, m_assembly, m_builtinContext); } else { + yulAssert(std::holds_alternative(_call.functionName)); AbstractAssembly::LabelID returnLabel = m_assembly.newLabelId(); m_assembly.appendLabelReference(returnLabel); Scope::Function* function = nullptr; - yulAssert(m_scope->lookup(_call.functionName.name, GenericVisitor{ + yulAssert(m_scope->lookup(std::get(_call.functionName).name, GenericVisitor{ [](Scope::Variable&) { yulAssert(false, "Expected function name."); }, [&](Scope::Function& _function) { function = &_function; } }), "Function name not found."); diff --git a/libyul/backends/evm/EVMDialect.cpp b/libyul/backends/evm/EVMDialect.cpp index 161f92336b4c..c73a9a79483f 100644 --- a/libyul/backends/evm/EVMDialect.cpp +++ b/libyul/backends/evm/EVMDialect.cpp @@ -476,14 +476,12 @@ EVMDialect::EVMDialect(langutil::EVMVersion _evmVersion, std::optional m_storageLoadFunction = findBuiltin("sload"); m_hashFunction = findBuiltin("keccak256"); - m_discardFunction = findBuiltin("pop"); - m_equalityFunction = findBuiltin("eq"); - m_booleanNegationFunction = findBuiltin("iszero"); - m_memoryStoreFunction = findBuiltin("mstore"); - m_memoryLoadFunction = findBuiltin("mload"); - m_storageStoreFunction = findBuiltin("sstore"); - m_storageLoadFunction = findBuiltin("sload"); - m_hashFunction = findBuiltin("keccak256"); + m_auxiliaryBuiltinHandles.add = EVMDialect::findBuiltin("add"); + m_auxiliaryBuiltinHandles.exp = EVMDialect::findBuiltin("exp"); + m_auxiliaryBuiltinHandles.mul = EVMDialect::findBuiltin("mul"); + m_auxiliaryBuiltinHandles.not_ = EVMDialect::findBuiltin("not"); + m_auxiliaryBuiltinHandles.shl = EVMDialect::findBuiltin("shl"); + m_auxiliaryBuiltinHandles.sub = EVMDialect::findBuiltin("sub"); } std::optional EVMDialect::findBuiltin(std::string_view _name) const diff --git a/libyul/backends/evm/EVMMetrics.cpp b/libyul/backends/evm/EVMMetrics.cpp index 64ff94cf6102..57593fdc26da 100644 --- a/libyul/backends/evm/EVMMetrics.cpp +++ b/libyul/backends/evm/EVMMetrics.cpp @@ -76,10 +76,10 @@ std::pair GasMeterVisitor::instructionCosts( void GasMeterVisitor::operator()(FunctionCall const& _funCall) { ASTWalker::operator()(_funCall); - if (std::optional handle = m_dialect.findBuiltin(_funCall.functionName.name.str())) - if (std::optional const& instruction = m_dialect.builtin(*handle).instruction) + if (BuiltinFunctionForEVM const* builtin = resolveBuiltinFunctionForEVM(_funCall.functionName, m_dialect)) + if (builtin->instruction) { - instructionCostsInternal(*instruction); + instructionCostsInternal(*builtin->instruction); return; } yulAssert(false, "Functions not implemented."); diff --git a/libyul/backends/evm/EVMObjectCompiler.cpp b/libyul/backends/evm/EVMObjectCompiler.cpp index a7ac67c3a6c3..de1174acee00 100644 --- a/libyul/backends/evm/EVMObjectCompiler.cpp +++ b/libyul/backends/evm/EVMObjectCompiler.cpp @@ -90,9 +90,11 @@ void EVMObjectCompiler::run(Object const& _object, bool _optimize) ); if (!stackErrors.empty()) { + yulAssert(_object.dialect()); std::vector memoryGuardCalls = findFunctionCalls( _object.code()->root(), - "memoryguard"_yulname + "memoryguard", + *_object.dialect() ); auto stackError = stackErrors.front(); std::string msg = stackError.comment() ? *stackError.comment() : ""; diff --git a/libyul/backends/evm/OptimizedEVMCodeTransform.cpp b/libyul/backends/evm/OptimizedEVMCodeTransform.cpp index 89a75019ec31..3a1b78e1eb31 100644 --- a/libyul/backends/evm/OptimizedEVMCodeTransform.cpp +++ b/libyul/backends/evm/OptimizedEVMCodeTransform.cpp @@ -73,7 +73,8 @@ std::vector OptimizedEVMCodeTransform::run( _useNamedLabelsForFunctions, *dfg, stackLayout, - !_dialect.eofVersion().has_value() + !_dialect.eofVersion().has_value(), + _dialect ); // Create initial entry layout. optimizedCodeTransform.createStackLayout(debugDataOf(*dfg->entry), stackLayout.blockInfos.at(dfg->entry).entryLayout); @@ -202,12 +203,14 @@ OptimizedEVMCodeTransform::OptimizedEVMCodeTransform( UseNamedLabels _useNamedLabelsForFunctions, CFG const& _dfg, StackLayout const& _stackLayout, - bool _simulateFunctionsWithJumps + bool _simulateFunctionsWithJumps, + EVMDialect const& _dialect ): m_assembly(_assembly), m_builtinContext(_builtinContext), m_dfg(_dfg), m_stackLayout(_stackLayout), + m_dialect(_dialect), m_functionLabels(!_simulateFunctionsWithJumps ? decltype(m_functionLabels)() : [&](){ std::map functionLabels; std::set assignedFunctionNames; @@ -294,9 +297,9 @@ void OptimizedEVMCodeTransform::createStackLayout(langutil::DebugData::ConstPtr YulName varNameDeep = slotVariableName(deepSlot); YulName varNameTop = slotVariableName(m_stack.back()); std::string msg = - "Cannot swap " + (varNameDeep.empty() ? "Slot " + stackSlotToString(deepSlot) : "Variable " + varNameDeep.str()) + - " with " + (varNameTop.empty() ? "Slot " + stackSlotToString(m_stack.back()) : "Variable " + varNameTop.str()) + - ": too deep in the stack by " + std::to_string(deficit) + " slots in " + stackToString(m_stack); + "Cannot swap " + (varNameDeep.empty() ? "Slot " + stackSlotToString(deepSlot, m_dialect) : "Variable " + varNameDeep.str()) + + " with " + (varNameTop.empty() ? "Slot " + stackSlotToString(m_stack.back(), m_dialect) : "Variable " + varNameTop.str()) + + ": too deep in the stack by " + std::to_string(deficit) + " slots in " + stackToString(m_stack, m_dialect); m_stackErrors.emplace_back(StackTooDeepError( m_currentFunctionInfo ? m_currentFunctionInfo->function.name : YulName{}, varNameDeep.empty() ? varNameTop : varNameDeep, @@ -324,8 +327,8 @@ void OptimizedEVMCodeTransform::createStackLayout(langutil::DebugData::ConstPtr int deficit = static_cast(*depth - 15); YulName varName = slotVariableName(_slot); std::string msg = - (varName.empty() ? "Slot " + stackSlotToString(_slot) : "Variable " + varName.str()) - + " is " + std::to_string(*depth - 15) + " too deep in the stack " + stackToString(m_stack); + (varName.empty() ? "Slot " + stackSlotToString(_slot, m_dialect) : "Variable " + varName.str()) + + " is " + std::to_string(*depth - 15) + " too deep in the stack " + stackToString(m_stack, m_dialect); m_stackErrors.emplace_back(StackTooDeepError( m_currentFunctionInfo ? m_currentFunctionInfo->function.name : YulName{}, varName, diff --git a/libyul/backends/evm/OptimizedEVMCodeTransform.h b/libyul/backends/evm/OptimizedEVMCodeTransform.h index 2c072bcca2f6..88ecc2967763 100644 --- a/libyul/backends/evm/OptimizedEVMCodeTransform.h +++ b/libyul/backends/evm/OptimizedEVMCodeTransform.h @@ -69,7 +69,8 @@ class OptimizedEVMCodeTransform UseNamedLabels _useNamedLabelsForFunctions, CFG const& _dfg, StackLayout const& _stackLayout, - bool _simulateFunctionsWithJumps + bool _simulateFunctionsWithJumps, + EVMDialect const& _dialect ); /// Assert that it is valid to transition from @a _currentStack to @a _desiredStack. @@ -102,6 +103,7 @@ class OptimizedEVMCodeTransform BuiltinContext& m_builtinContext; CFG const& m_dfg; StackLayout const& m_stackLayout; + EVMDialect const& m_dialect; Stack m_stack; std::map m_returnLabels; std::map m_blockLabels; diff --git a/libyul/backends/evm/SSAControlFlowGraphBuilder.cpp b/libyul/backends/evm/SSAControlFlowGraphBuilder.cpp index e7b3c9e6d73e..b47248dd58bc 100644 --- a/libyul/backends/evm/SSAControlFlowGraphBuilder.cpp +++ b/libyul/backends/evm/SSAControlFlowGraphBuilder.cpp @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -342,19 +343,21 @@ void SSAControlFlowGraphBuilder::operator()(Switch const& _switch) } else { + std::optional equalityBuiltinHandle = m_dialect.equalityFunctionHandle(); + yulAssert(equalityBuiltinHandle); + auto makeValueCompare = [&](Case const& _case) { FunctionCall const& ghostCall = m_graph.ghostCalls.emplace_back(FunctionCall{ debugDataOf(_case), - Identifier{{}, "eq"_yulname}, + BuiltinName{{}, *equalityBuiltinHandle}, {*_case.value /* skip second argument */ } }); auto outputValue = m_graph.newVariable(m_currentBlock); - std::optional builtinHandle = m_dialect.findBuiltin(ghostCall.functionName.name.str()); currentBlock().operations.emplace_back(SSACFG::Operation{ {outputValue}, SSACFG::BuiltinCall{ debugDataOf(_case), - m_dialect.builtin(*builtinHandle), + m_dialect.builtin(*equalityBuiltinHandle), ghostCall }, {m_graph.newLiteral(debugDataOf(_case), _case.value->value.value()), expression} @@ -547,21 +550,21 @@ std::vector SSAControlFlowGraphBuilder::visitFunctionCall(Funct { bool canContinue = true; SSACFG::Operation operation = [&](){ - if (std::optional const& builtinHandle = m_dialect.findBuiltin(_call.functionName.name.str())) + if (BuiltinFunction const* builtin = resolveBuiltinFunction(_call.functionName, m_dialect)) { - auto const& builtinFunction = m_dialect.builtin(*builtinHandle); - SSACFG::Operation result{{}, SSACFG::BuiltinCall{_call.debugData, builtinFunction, _call}, {}}; + SSACFG::Operation result{{}, SSACFG::BuiltinCall{_call.debugData, *builtin, _call}, {}}; for (auto&& [idx, arg]: _call.arguments | ranges::views::enumerate | ranges::views::reverse) - if (!builtinFunction.literalArgument(idx).has_value()) + if (!builtin->literalArgument(idx).has_value()) result.inputs.emplace_back(std::visit(*this, arg)); - for (size_t i = 0; i < builtinFunction.numReturns; ++i) + for (size_t i = 0; i < builtin->numReturns; ++i) result.outputs.emplace_back(m_graph.newVariable(m_currentBlock)); - canContinue = builtinFunction.controlFlowSideEffects.canContinue; + canContinue = builtin->controlFlowSideEffects.canContinue; return result; } else { - Scope::Function const& function = lookupFunction(_call.functionName.name); + YulName const functionName{std::string(resolveFunctionName(_call.functionName, m_dialect))}; + Scope::Function const& function = lookupFunction(functionName); auto const* definition = findFunctionDefinition(&function); yulAssert(definition); canContinue = m_sideEffects.functionSideEffects().at(definition).canContinue; diff --git a/libyul/backends/evm/StackHelpers.h b/libyul/backends/evm/StackHelpers.h index dae4352a02c4..0fd238c4052d 100644 --- a/libyul/backends/evm/StackHelpers.h +++ b/libyul/backends/evm/StackHelpers.h @@ -20,6 +20,7 @@ #include #include +#include #include @@ -33,23 +34,23 @@ namespace solidity::yul { -inline std::string stackSlotToString(StackSlot const& _slot) +inline std::string stackSlotToString(StackSlot const& _slot, Dialect const& _dialect) { return std::visit(util::GenericVisitor{ - [](FunctionCallReturnLabelSlot const& _ret) -> std::string { return "RET[" + _ret.call.get().functionName.name.str() + "]"; }, + [&](FunctionCallReturnLabelSlot const& _ret) -> std::string { return "RET[" + std::string(resolveFunctionName(_ret.call.get().functionName, _dialect)) + "]"; }, [](FunctionReturnLabelSlot const&) -> std::string { return "RET"; }, [](VariableSlot const& _var) { return _var.variable.get().name.str(); }, [](LiteralSlot const& _lit) { return toCompactHexWithPrefix(_lit.value); }, - [](TemporarySlot const& _tmp) -> std::string { return "TMP[" + _tmp.call.get().functionName.name.str() + ", " + std::to_string(_tmp.index) + "]"; }, + [&](TemporarySlot const& _tmp) -> std::string { return "TMP[" + std::string(resolveFunctionName(_tmp.call.get().functionName, _dialect)) + ", " + std::to_string(_tmp.index) + "]"; }, [](JunkSlot const&) -> std::string { return "JUNK"; } }, _slot); } -inline std::string stackToString(Stack const& _stack) +inline std::string stackToString(Stack const& _stack, Dialect const& _dialect) { std::string result("[ "); for (auto const& slot: _stack) - result += stackSlotToString(slot) + ' '; + result += stackSlotToString(slot, _dialect) + ' '; result += ']'; return result; } diff --git a/libyul/optimiser/ASTCopier.cpp b/libyul/optimiser/ASTCopier.cpp index 269c7adeedff..9e85651ad346 100644 --- a/libyul/optimiser/ASTCopier.cpp +++ b/libyul/optimiser/ASTCopier.cpp @@ -24,6 +24,7 @@ #include #include +#include using namespace solidity; using namespace solidity::yul; @@ -153,6 +154,15 @@ Case ASTCopier::translate(Case const& _case) return Case{_case.debugData, translate(_case.value), translate(_case.body)}; } +FunctionName ASTCopier::translate(FunctionName const& _functionName) +{ + GenericVisitor visitor{ + [&](Identifier const& _identifier) -> FunctionName { return translate(_identifier); }, + [](BuiltinName const& _builtin) -> FunctionName { return _builtin; } + }; + return std::visit(visitor, _functionName); +} + Identifier ASTCopier::translate(Identifier const& _identifier) { return Identifier{_identifier.debugData, translateIdentifier(_identifier.name)}; diff --git a/libyul/optimiser/ASTCopier.h b/libyul/optimiser/ASTCopier.h index 04b1c96cd2e1..e1c3a16aa3ea 100644 --- a/libyul/optimiser/ASTCopier.h +++ b/libyul/optimiser/ASTCopier.h @@ -100,6 +100,7 @@ class ASTCopier: public ExpressionCopier, public StatementCopier Case translate(Case const& _case); virtual Identifier translate(Identifier const& _identifier); Literal translate(Literal const& _literal); + FunctionName translate(FunctionName const& _functionName); NameWithDebugData translate(NameWithDebugData const& _typedName); virtual void enterScope(Block const&) { } diff --git a/libyul/optimiser/BlockHasher.cpp b/libyul/optimiser/BlockHasher.cpp index 5470558ce93a..2cc7a6648392 100644 --- a/libyul/optimiser/BlockHasher.cpp +++ b/libyul/optimiser/BlockHasher.cpp @@ -23,6 +23,8 @@ #include #include +#include + using namespace solidity; using namespace solidity::yul; using namespace solidity::util; @@ -51,6 +53,25 @@ void ASTHasherBase::hashLiteral(solidity::yul::Literal const& _literal) hash8(_literal.value.unlimited()); } +void ASTHasherBase::hashFunctionCall(FunctionCall const& _funCall) +{ + hash64(compileTimeLiteralHash("FunctionCall")); + GenericVisitor visitor{ + [&](BuiltinName const& _builtin) + { + hash64(compileTimeLiteralHash("Builtin")); + hash64(_builtin.handle.id); + }, + [&](Identifier const& _identifier) + { + hash64(compileTimeLiteralHash("UserDefined")); + hash64(_identifier.name.hash()); + hash64(_funCall.arguments.size()); + } + }; + std::visit(visitor, _funCall.functionName); +} + std::map BlockHasher::run(Block const& _block) { std::map result; @@ -85,9 +106,7 @@ void BlockHasher::operator()(Identifier const& _identifier) void BlockHasher::operator()(FunctionCall const& _funCall) { - hash64(compileTimeLiteralHash("FunctionCall")); - hash64(_funCall.functionName.name.hash()); - hash64(_funCall.arguments.size()); + hashFunctionCall(_funCall); ASTWalker::operator()(_funCall); } @@ -218,8 +237,6 @@ void ExpressionHasher::operator()(Identifier const& _identifier) void ExpressionHasher::operator()(FunctionCall const& _funCall) { - hash64(compileTimeLiteralHash("FunctionCall")); - hash64(_funCall.functionName.name.hash()); - hash64(_funCall.arguments.size()); + hashFunctionCall(_funCall); ASTWalker::operator()(_funCall); } diff --git a/libyul/optimiser/BlockHasher.h b/libyul/optimiser/BlockHasher.h index 427161b3c784..12c1c5e72b19 100644 --- a/libyul/optimiser/BlockHasher.h +++ b/libyul/optimiser/BlockHasher.h @@ -62,6 +62,7 @@ class ASTHasherBase: public HasherBase { protected: void hashLiteral(solidity::yul::Literal const& _literal); + void hashFunctionCall(FunctionCall const& _functionCall); }; /** diff --git a/libyul/optimiser/CallGraphGenerator.cpp b/libyul/optimiser/CallGraphGenerator.cpp index f457f55838d3..9b69835dc4f1 100644 --- a/libyul/optimiser/CallGraphGenerator.cpp +++ b/libyul/optimiser/CallGraphGenerator.cpp @@ -23,6 +23,8 @@ #include #include +#include + #include using namespace solidity; @@ -35,11 +37,11 @@ namespace struct CallGraphCycleFinder { CallGraph const& callGraph; - std::set containedInCycle{}; - std::set visited{}; - std::vector currentPath{}; + std::set containedInCycle{}; + std::set visited{}; + std::vector currentPath{}; - void visit(YulName _function) + void visit(FunctionHandle const& _function) { if (visited.count(_function)) return; @@ -61,7 +63,7 @@ struct CallGraphCycleFinder }; } -std::set CallGraph::recursiveFunctions() const +std::set CallGraph::recursiveFunctions() const { CallGraphCycleFinder cycleFinder{*this}; // Visiting the root only is not enough, since there may be disconnected recursive functions. @@ -80,8 +82,12 @@ CallGraph CallGraphGenerator::callGraph(Block const& _ast) void CallGraphGenerator::operator()(FunctionCall const& _functionCall) { auto& functionCalls = m_callGraph.functionCalls[m_currentFunction]; - if (!util::contains(functionCalls, _functionCall.functionName.name)) - functionCalls.emplace_back(_functionCall.functionName.name); + FunctionHandle identifier = std::visit(GenericVisitor{ + [](BuiltinName const& _builtin) -> FunctionHandle { return _builtin.handle; }, + [](Identifier const& _identifier) -> FunctionHandle { return _identifier.name; }, + }, _functionCall.functionName); + if (!util::contains(functionCalls, identifier)) + functionCalls.emplace_back(identifier); ASTWalker::operator()(_functionCall); } diff --git a/libyul/optimiser/CallGraphGenerator.h b/libyul/optimiser/CallGraphGenerator.h index 23e9a2511588..722cbba4a796 100644 --- a/libyul/optimiser/CallGraphGenerator.h +++ b/libyul/optimiser/CallGraphGenerator.h @@ -22,9 +22,9 @@ #pragma once #include +#include #include -#include #include namespace solidity::yul @@ -32,12 +32,13 @@ namespace solidity::yul struct CallGraph { - std::map> functionCalls; + /// Map function definition name -> function name + std::map> functionCalls; std::set functionsWithLoops; /// @returns the set of functions contained in cycles in the call graph, i.e. /// functions that are part of a (mutual) recursion. /// Note that this does not include functions that merely call recursive functions. - std::set recursiveFunctions() const; + std::set recursiveFunctions() const; }; /** diff --git a/libyul/optimiser/CircularReferencesPruner.cpp b/libyul/optimiser/CircularReferencesPruner.cpp index a34f3f4e2aa3..d238f8da2148 100644 --- a/libyul/optimiser/CircularReferencesPruner.cpp +++ b/libyul/optimiser/CircularReferencesPruner.cpp @@ -57,7 +57,7 @@ std::set CircularReferencesPruner::functionsCalledFromOutermostContext( [&_callGraph](YulName _function, auto&& _addChild) { if (_callGraph.functionCalls.count(_function)) for (auto const& callee: _callGraph.functionCalls.at(_function)) - if (_callGraph.functionCalls.count(callee)) - _addChild(callee); + if (std::holds_alternative(callee) && _callGraph.functionCalls.count(std::get(callee))) + _addChild(std::get(callee)); }).visited; } diff --git a/libyul/optimiser/CommonSubexpressionEliminator.cpp b/libyul/optimiser/CommonSubexpressionEliminator.cpp index f74568421a4f..87a14d259070 100644 --- a/libyul/optimiser/CommonSubexpressionEliminator.cpp +++ b/libyul/optimiser/CommonSubexpressionEliminator.cpp @@ -46,7 +46,7 @@ void CommonSubexpressionEliminator::run(OptimiserStepContext& _context, Block& _ CommonSubexpressionEliminator::CommonSubexpressionEliminator( Dialect const& _dialect, - std::map _functionSideEffects + std::map _functionSideEffects ): DataFlowAnalyzer(_dialect, MemoryAndStorage::Ignore, std::move(_functionSideEffects)) { @@ -72,14 +72,13 @@ void CommonSubexpressionEliminator::visit(Expression& _e) { FunctionCall& funCall = std::get(_e); - if (std::optional builtinHandle = m_dialect.findBuiltin(funCall.functionName.name.str())) + if (BuiltinFunction const* builtin = resolveBuiltinFunction(funCall.functionName, m_dialect)) { - BuiltinFunction const& builtin = m_dialect.builtin(*builtinHandle); for (size_t i = funCall.arguments.size(); i > 0; i--) // We should not modify function arguments that have to be literals // Note that replacing the function call entirely is fine, // if the function call is movable. - if (!builtin.literalArgument(i - 1)) + if (!builtin->literalArgument(i - 1)) visit(funCall.arguments[i - 1]); descend = false; diff --git a/libyul/optimiser/CommonSubexpressionEliminator.h b/libyul/optimiser/CommonSubexpressionEliminator.h index d7dc42596ca4..35f8168eba73 100644 --- a/libyul/optimiser/CommonSubexpressionEliminator.h +++ b/libyul/optimiser/CommonSubexpressionEliminator.h @@ -53,7 +53,7 @@ class CommonSubexpressionEliminator: public DataFlowAnalyzer private: CommonSubexpressionEliminator( Dialect const& _dialect, - std::map _functionSideEffects + std::map _functionSideEffects ); protected: diff --git a/libyul/optimiser/ControlFlowSimplifier.cpp b/libyul/optimiser/ControlFlowSimplifier.cpp index a9a8282a680e..53afb5e77785 100644 --- a/libyul/optimiser/ControlFlowSimplifier.cpp +++ b/libyul/optimiser/ControlFlowSimplifier.cpp @@ -37,13 +37,13 @@ namespace ExpressionStatement makeDiscardCall( langutil::DebugData::ConstPtr const& _debugData, - BuiltinFunction const& _discardFunction, + BuiltinHandle const& _discardFunction, Expression&& _expression ) { return {_debugData, FunctionCall{ _debugData, - Identifier{_debugData, YulName{_discardFunction.name}}, + BuiltinName{_debugData, _discardFunction}, {std::move(_expression)} }}; } @@ -141,7 +141,7 @@ void ControlFlowSimplifier::simplify(std::vector& _statements) OptionalStatements s = std::vector{}; s->emplace_back(makeDiscardCall( _ifStmt.debugData, - m_dialect.builtin(*m_dialect.discardFunctionHandle()), + *m_dialect.discardFunctionHandle(), std::move(*_ifStmt.condition) )); return s; @@ -184,7 +184,7 @@ OptionalStatements ControlFlowSimplifier::reduceNoCaseSwitch(Switch& _switchStmt return make_vector(makeDiscardCall( debugDataOf(*_switchStmt.expression), - m_dialect.builtin(*discardFunctionHandle), + *discardFunctionHandle, std::move(*_switchStmt.expression) )); } @@ -199,11 +199,12 @@ OptionalStatements ControlFlowSimplifier::reduceSingleCaseSwitch(Switch& _switch { if (!m_dialect.equalityFunctionHandle()) return {}; + BuiltinName const builtinName{debugData, *m_dialect.equalityFunctionHandle()}; return make_vector(If{ std::move(_switchStmt.debugData), std::make_unique(FunctionCall{ debugData, - Identifier{debugData, YulName{m_dialect.builtin(*m_dialect.equalityFunctionHandle()).name}}, + builtinName, {std::move(*switchCase.value), std::move(*_switchStmt.expression)} }), std::move(switchCase.body) @@ -217,7 +218,7 @@ OptionalStatements ControlFlowSimplifier::reduceSingleCaseSwitch(Switch& _switch return make_vector( makeDiscardCall( debugData, - m_dialect.builtin(*m_dialect.discardFunctionHandle()), + *m_dialect.discardFunctionHandle(), std::move(*_switchStmt.expression) ), std::move(switchCase.body) diff --git a/libyul/optimiser/DataFlowAnalyzer.cpp b/libyul/optimiser/DataFlowAnalyzer.cpp index 8b3282888865..ac08fb0be196 100644 --- a/libyul/optimiser/DataFlowAnalyzer.cpp +++ b/libyul/optimiser/DataFlowAnalyzer.cpp @@ -45,23 +45,19 @@ using namespace solidity::yul; DataFlowAnalyzer::DataFlowAnalyzer( Dialect const& _dialect, MemoryAndStorage _analyzeStores, - std::map _functionSideEffects + std::map _functionSideEffects ): m_dialect(_dialect), m_functionSideEffects(std::move(_functionSideEffects)), - m_knowledgeBase([this](YulName _var) { return variableValue(_var); }), + m_knowledgeBase([this](YulName _var) { return variableValue(_var); }, _dialect), m_analyzeStores(_analyzeStores == MemoryAndStorage::Analyze) { if (m_analyzeStores) { - if (auto const& builtinHandle = _dialect.memoryStoreFunctionHandle()) - m_storeFunctionName[static_cast(StoreLoadLocation::Memory)] = YulName{_dialect.builtin(*builtinHandle).name}; - if (auto const& builtinHandle = _dialect.memoryLoadFunctionHandle()) - m_loadFunctionName[static_cast(StoreLoadLocation::Memory)] = YulName{_dialect.builtin(*builtinHandle).name}; - if (auto const& builtinHandle = _dialect.storageStoreFunctionHandle()) - m_storeFunctionName[static_cast(StoreLoadLocation::Storage)] = YulName{_dialect.builtin(*builtinHandle).name}; - if (auto const& builtinHandle = _dialect.storageLoadFunctionHandle()) - m_loadFunctionName[static_cast(StoreLoadLocation::Storage)] = YulName{_dialect.builtin(*builtinHandle).name}; + m_storeFunctionName[static_cast(StoreLoadLocation::Memory)] = _dialect.memoryStoreFunctionHandle(); + m_loadFunctionName[static_cast(StoreLoadLocation::Memory)] = _dialect.memoryLoadFunctionHandle(); + m_storeFunctionName[static_cast(StoreLoadLocation::Storage)] = _dialect.storageStoreFunctionHandle(); + m_loadFunctionName[static_cast(StoreLoadLocation::Storage)] = _dialect.storageLoadFunctionHandle(); } } @@ -424,7 +420,10 @@ std::optional> DataFlowAnalyzer::isSimpleStore( ) const { if (FunctionCall const* funCall = std::get_if(&_statement.expression)) - if (funCall->functionName.name == m_storeFunctionName[static_cast(_location)]) + if ( + std::holds_alternative(funCall->functionName) && + std::get(funCall->functionName).handle == m_storeFunctionName[static_cast(_location)] + ) if (Identifier const* key = std::get_if(&funCall->arguments.front())) if (Identifier const* value = std::get_if(&funCall->arguments.back())) return std::make_pair(key->name, value->name); @@ -437,7 +436,10 @@ std::optional DataFlowAnalyzer::isSimpleLoad( ) const { if (FunctionCall const* funCall = std::get_if(&_expression)) - if (funCall->functionName.name == m_loadFunctionName[static_cast(_location)]) + if ( + std::holds_alternative(funCall->functionName) && + std::get(funCall->functionName).handle == m_loadFunctionName[static_cast(_location)] + ) if (Identifier const* key = std::get_if(&funCall->arguments.front())) return key->name; return {}; @@ -446,7 +448,10 @@ std::optional DataFlowAnalyzer::isSimpleLoad( std::optional> DataFlowAnalyzer::isKeccak(Expression const& _expression) const { if (FunctionCall const* funCall = std::get_if(&_expression)) - if (funCall->functionName.name.str() == m_dialect.builtin(*m_dialect.hashFunctionHandle()).name) + if ( + std::holds_alternative(funCall->functionName) && + std::get(funCall->functionName).handle == m_dialect.hashFunctionHandle() + ) if (Identifier const* start = std::get_if(&funCall->arguments.at(0))) if (Identifier const* length = std::get_if(&funCall->arguments.at(1))) return std::make_pair(start->name, length->name); diff --git a/libyul/optimiser/DataFlowAnalyzer.h b/libyul/optimiser/DataFlowAnalyzer.h index 5a4b199caefd..7d0f78b534c2 100644 --- a/libyul/optimiser/DataFlowAnalyzer.h +++ b/libyul/optimiser/DataFlowAnalyzer.h @@ -89,7 +89,7 @@ class DataFlowAnalyzer: public ASTModifier explicit DataFlowAnalyzer( Dialect const& _dialect, MemoryAndStorage _analyzeStores, - std::map _functionSideEffects = {} + std::map _functionSideEffects = {} ); using ASTModifier::operator(); @@ -165,7 +165,7 @@ class DataFlowAnalyzer: public ASTModifier Dialect const& m_dialect; /// Side-effects of user-defined functions. Worst-case side-effects are assumed /// if this is not provided or the function is not found. - std::map m_functionSideEffects; + std::map m_functionSideEffects; private: struct Environment @@ -203,8 +203,8 @@ class DataFlowAnalyzer: public ASTModifier /// If true, analyzes memory and storage content via mload/mstore and sload/sstore. bool m_analyzeStores = true; - YulName m_storeFunctionName[static_cast(StoreLoadLocation::Last) + 1]; - YulName m_loadFunctionName[static_cast(StoreLoadLocation::Last) + 1]; + std::optional m_storeFunctionName[static_cast(StoreLoadLocation::Last) + 1]; + std::optional m_loadFunctionName[static_cast(StoreLoadLocation::Last) + 1]; /// Current nesting depth of loops. size_t m_loopDepth{0}; diff --git a/libyul/optimiser/EqualStoreEliminator.h b/libyul/optimiser/EqualStoreEliminator.h index a0b54c590ff5..87f8cae161a6 100644 --- a/libyul/optimiser/EqualStoreEliminator.h +++ b/libyul/optimiser/EqualStoreEliminator.h @@ -45,7 +45,7 @@ class EqualStoreEliminator: public DataFlowAnalyzer private: EqualStoreEliminator( Dialect const& _dialect, - std::map _functionSideEffects + std::map _functionSideEffects ): DataFlowAnalyzer(_dialect, MemoryAndStorage::Analyze, std::move(_functionSideEffects)) {} diff --git a/libyul/optimiser/EquivalentFunctionCombiner.cpp b/libyul/optimiser/EquivalentFunctionCombiner.cpp index 10d15126e645..bbbf039d56ed 100644 --- a/libyul/optimiser/EquivalentFunctionCombiner.cpp +++ b/libyul/optimiser/EquivalentFunctionCombiner.cpp @@ -33,8 +33,13 @@ void EquivalentFunctionCombiner::run(OptimiserStepContext&, Block& _ast) void EquivalentFunctionCombiner::operator()(FunctionCall& _funCall) { - auto it = m_duplicates.find(_funCall.functionName.name); - if (it != m_duplicates.end()) - _funCall.functionName.name = it->second->name; + if (!isBuiltinFunctionCall(_funCall)) + { + auto* identifier = std::get_if(&_funCall.functionName); + yulAssert(identifier); + auto it = m_duplicates.find(identifier->name); + if (it != m_duplicates.end()) + identifier->name = it->second->name; + } ASTModifier::operator()(_funCall); } diff --git a/libyul/optimiser/ExpressionInliner.cpp b/libyul/optimiser/ExpressionInliner.cpp index ab4bbcfa43a8..1dbd5ca98004 100644 --- a/libyul/optimiser/ExpressionInliner.cpp +++ b/libyul/optimiser/ExpressionInliner.cpp @@ -29,6 +29,7 @@ #include #include +#include using namespace solidity; using namespace solidity::yul; @@ -52,9 +53,10 @@ void ExpressionInliner::visit(Expression& _expression) if (std::holds_alternative(_expression)) { FunctionCall& funCall = std::get(_expression); - if (!m_inlinableFunctions.count(funCall.functionName.name)) + YulString const functionName{std::string(resolveFunctionName(funCall.functionName, m_dialect))}; + if (!m_inlinableFunctions.count(functionName)) return; - FunctionDefinition const& fun = *m_inlinableFunctions.at(funCall.functionName.name); + FunctionDefinition const& fun = *m_inlinableFunctions.at(functionName); std::map substitutions; for (size_t i = 0; i < funCall.arguments.size(); i++) diff --git a/libyul/optimiser/ExpressionSimplifier.cpp b/libyul/optimiser/ExpressionSimplifier.cpp index 598d2e90037d..4aa7be1bb556 100644 --- a/libyul/optimiser/ExpressionSimplifier.cpp +++ b/libyul/optimiser/ExpressionSimplifier.cpp @@ -21,6 +21,7 @@ #include +#include #include #include #include @@ -46,10 +47,14 @@ void ExpressionSimplifier::visit(Expression& _expression) m_dialect, [this](YulName _var) { return variableValue(_var); } )) - _expression = match->action().toExpression(debugDataOf(_expression), evmVersionFromDialect(m_dialect)); + { + auto const* evmDialect = dynamic_cast(&m_dialect); + yulAssert(evmDialect); + _expression = match->action().toExpression(debugDataOf(_expression), *evmDialect); + } if (auto* functionCall = std::get_if(&_expression)) - if (std::optional instruction = toEVMInstruction(m_dialect, functionCall->functionName.name)) + if (std::optional instruction = toEVMInstruction(m_dialect, functionCall->functionName)) for (auto op: evmasm::SemanticInformation::readWriteOperations(*instruction)) if (op.startParameter && op.lengthParameter) { diff --git a/libyul/optimiser/ExpressionSplitter.cpp b/libyul/optimiser/ExpressionSplitter.cpp index 71a0963d5542..1bdaa552ba16 100644 --- a/libyul/optimiser/ExpressionSplitter.cpp +++ b/libyul/optimiser/ExpressionSplitter.cpp @@ -26,6 +26,7 @@ #include #include +#include #include @@ -41,10 +42,10 @@ void ExpressionSplitter::run(OptimiserStepContext& _context, Block& _ast) void ExpressionSplitter::operator()(FunctionCall& _funCall) { - std::optional builtinHandle = m_dialect.findBuiltin(_funCall.functionName.name.str()); + BuiltinFunction const* builtin = resolveBuiltinFunction(_funCall.functionName, m_dialect); for (size_t i = _funCall.arguments.size(); i > 0; i--) - if (!builtinHandle || !m_dialect.builtin(*builtinHandle).literalArgument(i - 1)) + if (!builtin || !builtin->literalArgument(i - 1)) outlineExpression(_funCall.arguments[i - 1]); } diff --git a/libyul/optimiser/ForLoopConditionIntoBody.cpp b/libyul/optimiser/ForLoopConditionIntoBody.cpp index 7ee9a9b8c5d5..6324085e65c2 100644 --- a/libyul/optimiser/ForLoopConditionIntoBody.cpp +++ b/libyul/optimiser/ForLoopConditionIntoBody.cpp @@ -47,7 +47,7 @@ void ForLoopConditionIntoBody::operator()(ForLoop& _forLoop) std::make_unique( FunctionCall { debugData, - {debugData, YulName{m_dialect.builtin(*m_dialect.booleanNegationFunctionHandle()).name}}, + BuiltinName{debugData, *m_dialect.booleanNegationFunctionHandle()}, util::make_vector(std::move(*_forLoop.condition)) } ), diff --git a/libyul/optimiser/ForLoopConditionOutOfBody.cpp b/libyul/optimiser/ForLoopConditionOutOfBody.cpp index d082bb78d676..111f26fec5f3 100644 --- a/libyul/optimiser/ForLoopConditionOutOfBody.cpp +++ b/libyul/optimiser/ForLoopConditionOutOfBody.cpp @@ -53,18 +53,21 @@ void ForLoopConditionOutOfBody::operator()(ForLoop& _forLoop) if (!SideEffectsCollector(m_dialect, *firstStatement.condition).movable()) return; - YulName const iszero{m_dialect.builtin(*m_dialect.booleanNegationFunctionHandle()).name}; + std::optional iszero = m_dialect.booleanNegationFunctionHandle(); + yulAssert(iszero.has_value()); + auto const& isZeroHandle = *iszero; langutil::DebugData::ConstPtr debugData = debugDataOf(*firstStatement.condition); if ( std::holds_alternative(*firstStatement.condition) && - std::get(*firstStatement.condition).functionName.name == iszero + std::holds_alternative(std::get(*firstStatement.condition).functionName) && + std::get(std::get(*firstStatement.condition).functionName).handle == isZeroHandle ) _forLoop.condition = std::make_unique(std::move(std::get(*firstStatement.condition).arguments.front())); else _forLoop.condition = std::make_unique(FunctionCall{ debugData, - Identifier{debugData, iszero}, + BuiltinName{debugData, isZeroHandle}, util::make_vector( std::move(*firstStatement.condition) ) diff --git a/libyul/optimiser/FullInliner.cpp b/libyul/optimiser/FullInliner.cpp index 328ef83b8e7b..4b390f4f271a 100644 --- a/libyul/optimiser/FullInliner.cpp +++ b/libyul/optimiser/FullInliner.cpp @@ -67,7 +67,7 @@ FullInliner::FullInliner(Block& _ast, NameDispenser& _dispenser, Dialect const& // Store size of global statements. m_functionSizes[YulName{}] = CodeSize::codeSize(_ast); - std::map references = ReferencesCounter::countReferences(m_ast); + std::map references = ReferencesCounter::countReferences(m_ast); for (auto& statement: m_ast.statements) { if (!std::holds_alternative(statement)) @@ -83,7 +83,7 @@ FullInliner::FullInliner(Block& _ast, NameDispenser& _dispenser, Dialect const& } // Check for memory guard. - std::vector memoryGuardCalls = findFunctionCalls(_ast, "memoryguard"_yulname); + std::vector memoryGuardCalls = findFunctionCalls(_ast, "memoryguard", m_dialect); // We will perform less aggressive inlining, if no ``memoryguard`` call is found. if (!memoryGuardCalls.empty()) m_hasMemoryGuard = true; @@ -101,7 +101,7 @@ void FullInliner::run(Pass _pass) // function name) order. // We use stable_sort below to keep the inlining order of two functions // with the same depth. - std::map depths = callDepths(); + std::map depths = callDepths(); std::vector functions; for (auto& statement: m_ast.statements) if (std::holds_alternative(statement)) @@ -123,7 +123,7 @@ void FullInliner::run(Pass _pass) handleBlock({}, std::get(statement)); } -std::map FullInliner::callDepths() const +std::map FullInliner::callDepths() const { CallGraph cg = CallGraphGenerator::callGraph(m_ast); cg.functionCalls.erase(""_yulname); @@ -131,17 +131,17 @@ std::map FullInliner::callDepths() const // Remove calls to builtin functions. for (auto& call: cg.functionCalls) for (auto it = call.second.begin(); it != call.second.end();) - if (m_dialect.findBuiltin(it->str())) + if (std::holds_alternative(*it)) it = call.second.erase(it); else ++it; - std::map depths; + std::map depths; size_t currentDepth = 0; while (true) { - std::vector removed; + std::vector removed; for (auto it = cg.functionCalls.begin(); it != cg.functionCalls.end();) { auto const& [fun, callees] = *it; @@ -156,7 +156,7 @@ std::map FullInliner::callDepths() const } for (auto& call: cg.functionCalls) - for (YulName toBeRemoved: removed) + for (FunctionHandle toBeRemoved: removed) ranges::actions::remove(call.second, toBeRemoved); currentDepth++; @@ -174,15 +174,19 @@ std::map FullInliner::callDepths() const bool FullInliner::shallInline(FunctionCall const& _funCall, YulName _callSite) { + if (isBuiltinFunctionCall(_funCall)) + return false; + yulAssert(std::holds_alternative(_funCall.functionName)); + auto const& functionName = std::get(_funCall.functionName).name; // No recursive inlining - if (_funCall.functionName.name == _callSite) + if (functionName == _callSite) return false; - FunctionDefinition* calledFunction = function(_funCall.functionName.name); + FunctionDefinition* calledFunction = function(functionName); if (!calledFunction) return false; - if (m_noInlineFunctions.count(_funCall.functionName.name) || recursive(*calledFunction)) + if (m_noInlineFunctions.count(functionName) || recursive(*calledFunction)) return false; // No inlining of calls where argument expressions may have side-effects. @@ -251,7 +255,7 @@ void FullInliner::handleBlock(YulName _currentFunctionName, Block& _block) bool FullInliner::recursive(FunctionDefinition const& _fun) const { - std::map references = ReferencesCounter::countReferences(_fun); + std::map references = ReferencesCounter::countReferences(_fun); return references[_fun.name] > 0; } @@ -291,7 +295,8 @@ std::vector InlineModifier::performInline(Statement& _statement, Func std::vector newStatements; std::map variableReplacements; - FunctionDefinition* function = m_driver.function(_funCall.functionName.name); + yulAssert(std::holds_alternative(_funCall.functionName)); + FunctionDefinition* function = m_driver.function(std::get(_funCall.functionName).name); assertThrow(!!function, OptimizerException, "Attempt to inline invalid function."); m_driver.tentativelyUpdateCodeSize(function->name, m_currentFunction); diff --git a/libyul/optimiser/FullInliner.h b/libyul/optimiser/FullInliner.h index e939070238e5..4620194a4e51 100644 --- a/libyul/optimiser/FullInliner.h +++ b/libyul/optimiser/FullInliner.h @@ -98,7 +98,7 @@ class FullInliner: public ASTModifier /// @returns a map containing the maximum depths of a call chain starting at each /// function. For recursive functions, the value is one larger than for all others. - std::map callDepths() const; + std::map callDepths() const; void updateCodeSize(FunctionDefinition const& _fun); void handleBlock(YulName _currentFunctionName, Block& _block); @@ -114,7 +114,7 @@ class FullInliner: public ASTModifier /// True, if the code contains a ``memoryguard`` and we can expect to be able to move variables to memory later. bool m_hasMemoryGuard = false; /// Set of recursive functions. - std::set m_recursiveFunctions; + std::set m_recursiveFunctions; /// Names of functions to always inline. std::set m_singleUse; /// Variables that are constants (used for inlining heuristic) diff --git a/libyul/optimiser/FunctionCallFinder.cpp b/libyul/optimiser/FunctionCallFinder.cpp index aaf8b9f68232..4c85d77f5246 100644 --- a/libyul/optimiser/FunctionCallFinder.cpp +++ b/libyul/optimiser/FunctionCallFinder.cpp @@ -19,6 +19,8 @@ #include #include +#include +#include using namespace solidity; using namespace solidity::yul; @@ -30,32 +32,35 @@ class MaybeConstFunctionCallFinder: Base { public: using MaybeConstBlock = std::conditional_t, Block const, Block>; - static std::vector run(MaybeConstBlock& _block, YulName const _functionName) + static std::vector run(MaybeConstBlock& _block, std::string_view const _functionName, Dialect const& _dialect) { - MaybeConstFunctionCallFinder functionCallFinder(_functionName); + MaybeConstFunctionCallFinder functionCallFinder(_functionName, _dialect); functionCallFinder(_block); return functionCallFinder.m_calls; } private: - explicit MaybeConstFunctionCallFinder(YulName const _functionName): m_functionName(_functionName), m_calls() {} + explicit MaybeConstFunctionCallFinder(std::string_view const _functionName, Dialect const& _dialect): + m_dialect(_dialect), m_functionName(_functionName), m_calls() {} + using Base::operator(); void operator()(ResultType& _functionCall) override { Base::operator()(_functionCall); - if (_functionCall.functionName.name == m_functionName) + if (resolveFunctionName(_functionCall.functionName, m_dialect) == m_functionName) m_calls.emplace_back(&_functionCall); } - YulName m_functionName; + Dialect const& m_dialect; + std::string_view m_functionName; std::vector m_calls; }; } -std::vector solidity::yul::findFunctionCalls(Block& _block, YulName _functionName) +std::vector solidity::yul::findFunctionCalls(Block& _block, std::string_view const _functionName, Dialect const& _dialect) { - return MaybeConstFunctionCallFinder::run(_block, _functionName); + return MaybeConstFunctionCallFinder::run(_block, _functionName, _dialect); } -std::vector solidity::yul::findFunctionCalls(Block const& _block, YulName _functionName) +std::vector solidity::yul::findFunctionCalls(Block const& _block, std::string_view const _functionName, Dialect const& _dialect) { - return MaybeConstFunctionCallFinder::run(_block, _functionName); + return MaybeConstFunctionCallFinder::run(_block, _functionName, _dialect); } diff --git a/libyul/optimiser/FunctionCallFinder.h b/libyul/optimiser/FunctionCallFinder.h index 41a19fe99fc7..067aee2a399c 100644 --- a/libyul/optimiser/FunctionCallFinder.h +++ b/libyul/optimiser/FunctionCallFinder.h @@ -21,25 +21,27 @@ #pragma once #include -#include +#include #include namespace solidity::yul { +struct Dialect; + /** * Finds all calls to a function of a given name using an ASTModifier. * * Prerequisite: Disambiguator */ -std::vector findFunctionCalls(Block& _block, YulName _functionName); +std::vector findFunctionCalls(Block& _block, std::string_view _functionName, Dialect const& _dialect); /** * Finds all calls to a function of a given name using an ASTWalker. * * Prerequisite: Disambiguator */ -std::vector findFunctionCalls(Block const& _block, YulName _functionName); +std::vector findFunctionCalls(Block const& _block, std::string_view _functionName, Dialect const& _dialect); } diff --git a/libyul/optimiser/FunctionSpecializer.cpp b/libyul/optimiser/FunctionSpecializer.cpp index bab02a2e1813..cbbf14e8f84a 100644 --- a/libyul/optimiser/FunctionSpecializer.cpp +++ b/libyul/optimiser/FunctionSpecializer.cpp @@ -55,21 +55,23 @@ void FunctionSpecializer::operator()(FunctionCall& _f) // TODO When backtracking is implemented, the restriction of recursive functions can be lifted. if ( - m_dialect.findBuiltin(_f.functionName.name.str()) || - m_recursiveFunctions.count(_f.functionName.name) + isBuiltinFunctionCall(_f) || + (std::holds_alternative(_f.functionName) && m_recursiveFunctions.count(std::get(_f.functionName).name)) ) return; + yulAssert(std::holds_alternative(_f.functionName)); + auto& identifier = std::get(_f.functionName); LiteralArguments arguments = specializableArguments(_f); if (ranges::any_of(arguments, [](auto& _a) { return _a.has_value(); })) { - YulName oldName = std::move(_f.functionName.name); + YulName oldName = std::move(identifier.name); auto newName = m_nameDispenser.newName(oldName); m_oldToNewMap[oldName].emplace_back(std::make_pair(newName, arguments)); - _f.functionName.name = newName; + identifier.name = newName; _f.arguments = util::filter( _f.arguments, applyMap(arguments, [](auto& _a) { return !_a; }) @@ -128,8 +130,7 @@ void FunctionSpecializer::run(OptimiserStepContext& _context, Block& _ast) { FunctionSpecializer f{ CallGraphGenerator::callGraph(_ast).recursiveFunctions(), - _context.dispenser, - _context.dialect + _context.dispenser }; f(_ast); diff --git a/libyul/optimiser/FunctionSpecializer.h b/libyul/optimiser/FunctionSpecializer.h index 784ec4311e0f..4df59b354c45 100644 --- a/libyul/optimiser/FunctionSpecializer.h +++ b/libyul/optimiser/FunctionSpecializer.h @@ -22,8 +22,7 @@ #include #include -#include -#include +#include #include #include @@ -67,13 +66,11 @@ class FunctionSpecializer: public ASTModifier private: explicit FunctionSpecializer( - std::set _recursiveFunctions, - NameDispenser& _nameDispenser, - Dialect const& _dialect + std::set _recursiveFunctions, + NameDispenser& _nameDispenser ): m_recursiveFunctions(std::move(_recursiveFunctions)), - m_nameDispenser(_nameDispenser), - m_dialect(_dialect) + m_nameDispenser(_nameDispenser) {} /// Returns a vector of Expressions, where the index `i` is an expression if the function's /// `i`-th argument can be specialized, nullopt otherwise. @@ -104,10 +101,9 @@ class FunctionSpecializer: public ASTModifier /// Note that at least one of the argument will have a literal value. std::map>> m_oldToNewMap; /// We skip specializing recursive functions. Need backtracking to properly deal with them. - std::set const m_recursiveFunctions; + std::set const m_recursiveFunctions; NameDispenser& m_nameDispenser; - Dialect const& m_dialect; }; } diff --git a/libyul/optimiser/InlinableExpressionFunctionFinder.cpp b/libyul/optimiser/InlinableExpressionFunctionFinder.cpp index d719302dcbc2..6061fa3e9725 100644 --- a/libyul/optimiser/InlinableExpressionFunctionFinder.cpp +++ b/libyul/optimiser/InlinableExpressionFunctionFinder.cpp @@ -29,13 +29,13 @@ using namespace solidity::yul; void InlinableExpressionFunctionFinder::operator()(Identifier const& _identifier) { - checkAllowed(_identifier.name); + checkAllowed(_identifier); ASTWalker::operator()(_identifier); } void InlinableExpressionFunctionFinder::operator()(FunctionCall const& _funCall) { - checkAllowed(_funCall.functionName.name); + checkAllowed(_funCall.functionName); ASTWalker::operator()(_funCall); } @@ -67,3 +67,9 @@ void InlinableExpressionFunctionFinder::operator()(FunctionDefinition const& _fu } ASTWalker::operator()(_function.body); } +void InlinableExpressionFunctionFinder::checkAllowed(FunctionName const& _name) +{ + // disallowed function names can only ever be user-defined `yul::Identifier`s, not builtins + if (std::holds_alternative(_name) && m_disallowedIdentifiers.count(std::get(_name).name) != 0) + m_foundDisallowedIdentifier = true; +} diff --git a/libyul/optimiser/InlinableExpressionFunctionFinder.h b/libyul/optimiser/InlinableExpressionFunctionFinder.h index e7210da69a0a..c6897c173529 100644 --- a/libyul/optimiser/InlinableExpressionFunctionFinder.h +++ b/libyul/optimiser/InlinableExpressionFunctionFinder.h @@ -53,11 +53,7 @@ class InlinableExpressionFunctionFinder: public ASTWalker void operator()(FunctionDefinition const& _function) override; private: - void checkAllowed(YulName _name) - { - if (m_disallowedIdentifiers.count(_name)) - m_foundDisallowedIdentifier = true; - } + void checkAllowed(FunctionName const& _name); bool m_foundDisallowedIdentifier = false; std::set m_disallowedIdentifiers; diff --git a/libyul/optimiser/KnowledgeBase.cpp b/libyul/optimiser/KnowledgeBase.cpp index 731f4b3b8195..ceaa8f06b359 100644 --- a/libyul/optimiser/KnowledgeBase.cpp +++ b/libyul/optimiser/KnowledgeBase.cpp @@ -32,9 +32,11 @@ using namespace solidity; using namespace solidity::yul; -KnowledgeBase::KnowledgeBase(std::map const& _ssaValues): +KnowledgeBase::KnowledgeBase(std::map const& _ssaValues, Dialect const& _dialect): m_valuesAreSSA(true), - m_variableValues([_ssaValues](YulName _var) { return util::valueOrNullptr(_ssaValues, _var); }) + m_variableValues([_ssaValues](YulName _var) { return util::valueOrNullptr(_ssaValues, _var); }), + m_addBuiltinHandle(_dialect.findBuiltin("add")), + m_subBuiltinHandle(_dialect.findBuiltin("sub")) {} bool KnowledgeBase::knownToBeDifferent(YulName _a, YulName _b) @@ -116,9 +118,12 @@ std::optional KnowledgeBase::explore(Expression c return VariableOffset{YulName{}, literal->value.value()}; else if (Identifier const* identifier = std::get_if(&_value)) return explore(identifier->name); - else if (FunctionCall const* f = std::get_if(&_value)) + else if ( + FunctionCall const* f = std::get_if(&_value); + f && isBuiltinFunctionCall(*f) + ) { - if (f->functionName.name == "add"_yulname) + if (std::get(f->functionName).handle == m_addBuiltinHandle) { if (std::optional a = explore(f->arguments[0])) if (std::optional b = explore(f->arguments[1])) @@ -132,7 +137,7 @@ std::optional KnowledgeBase::explore(Expression c return VariableOffset{a->reference, offset}; } } - else if (f->functionName.name == "sub"_yulname) + else if (std::get(f->functionName).handle == m_subBuiltinHandle) if (std::optional a = explore(f->arguments[0])) if (std::optional b = explore(f->arguments[1])) { diff --git a/libyul/optimiser/KnowledgeBase.h b/libyul/optimiser/KnowledgeBase.h index 46ea7b96af66..78daadbc4ee4 100644 --- a/libyul/optimiser/KnowledgeBase.h +++ b/libyul/optimiser/KnowledgeBase.h @@ -22,6 +22,7 @@ #pragma once #include +#include #include #include @@ -62,11 +63,13 @@ class KnowledgeBase public: /// Constructor for arbitrary value callback that allows for variable values /// to change in between calls to functions of this class. - explicit KnowledgeBase(std::function _variableValues): - m_variableValues(std::move(_variableValues)) + explicit KnowledgeBase(std::function _variableValues, Dialect const& _dialect): + m_variableValues(std::move(_variableValues)), + m_addBuiltinHandle(_dialect.findBuiltin("add")), + m_subBuiltinHandle(_dialect.findBuiltin("sub")) {} /// Constructor to use if source code is in SSA form and values are constant. - explicit KnowledgeBase(std::map const& _ssaValues); + explicit KnowledgeBase(std::map const& _ssaValues, Dialect const& _dialect); bool knownToBeDifferent(YulName _a, YulName _b); std::optional differenceIfKnownConstant(YulName _a, YulName _b); @@ -115,6 +118,8 @@ class KnowledgeBase bool m_valuesAreSSA = false; /// Callback to retrieve the current value of a variable. std::function m_variableValues; + std::optional m_addBuiltinHandle; + std::optional m_subBuiltinHandle; /// Offsets for each variable to one representative per group. /// The empty string is the representative of the constant value zero. diff --git a/libyul/optimiser/LoadResolver.cpp b/libyul/optimiser/LoadResolver.cpp index d6961b6f8ca3..36163c6c5f21 100644 --- a/libyul/optimiser/LoadResolver.cpp +++ b/libyul/optimiser/LoadResolver.cpp @@ -56,13 +56,17 @@ void LoadResolver::visit(Expression& _e) { DataFlowAnalyzer::visit(_e); - if (FunctionCall const* funCall = std::get_if(&_e)) + if ( + FunctionCall const* funCall = std::get_if(&_e); + funCall && std::holds_alternative(funCall->functionName) + ) { - if (funCall->functionName.name == m_loadFunctionName[static_cast(StoreLoadLocation::Memory)]) + auto const& builtinHandle = std::get(funCall->functionName).handle; + if (builtinHandle == m_loadFunctionName[static_cast(StoreLoadLocation::Memory)]) tryResolve(_e, StoreLoadLocation::Memory, funCall->arguments); - else if (funCall->functionName.name == m_loadFunctionName[static_cast(StoreLoadLocation::Storage)]) + else if (builtinHandle == m_loadFunctionName[static_cast(StoreLoadLocation::Storage)]) tryResolve(_e, StoreLoadLocation::Storage, funCall->arguments); - else if (!m_containsMSize && funCall->functionName.name.str() == m_dialect.builtin(*m_dialect.hashFunctionHandle()).name) + else if (!m_containsMSize && builtinHandle == m_dialect.hashFunctionHandle()) { Identifier const* start = std::get_if(&funCall->arguments.at(0)); Identifier const* length = std::get_if(&funCall->arguments.at(1)); diff --git a/libyul/optimiser/LoadResolver.h b/libyul/optimiser/LoadResolver.h index b4a496303373..d878076929a6 100644 --- a/libyul/optimiser/LoadResolver.h +++ b/libyul/optimiser/LoadResolver.h @@ -49,7 +49,7 @@ class LoadResolver: public DataFlowAnalyzer private: LoadResolver( Dialect const& _dialect, - std::map _functionSideEffects, + std::map _functionSideEffects, bool _containsMSize, std::optional _expectedExecutionsPerDeployment ): diff --git a/libyul/optimiser/LoopInvariantCodeMotion.cpp b/libyul/optimiser/LoopInvariantCodeMotion.cpp index 2a196a68f956..f2e7d040802e 100644 --- a/libyul/optimiser/LoopInvariantCodeMotion.cpp +++ b/libyul/optimiser/LoopInvariantCodeMotion.cpp @@ -32,7 +32,7 @@ using namespace solidity::yul; void LoopInvariantCodeMotion::run(OptimiserStepContext& _context, Block& _ast) { - std::map functionSideEffects = + std::map functionSideEffects = SideEffectsPropagator::sideEffects(_context.dialect, CallGraphGenerator::callGraph(_ast)); bool containsMSize = MSizeFinder::containsMSize(_context.dialect, _ast); std::set ssaVars = SSAValueTracker::ssaVariables(_ast); diff --git a/libyul/optimiser/LoopInvariantCodeMotion.h b/libyul/optimiser/LoopInvariantCodeMotion.h index c85b87a01c32..d03a91eeeba9 100644 --- a/libyul/optimiser/LoopInvariantCodeMotion.h +++ b/libyul/optimiser/LoopInvariantCodeMotion.h @@ -49,7 +49,7 @@ class LoopInvariantCodeMotion: public ASTModifier explicit LoopInvariantCodeMotion( Dialect const& _dialect, std::set const& _ssaVariables, - std::map const& _functionSideEffects, + std::map const& _functionSideEffects, bool _containsMSize ): m_containsMSize(_containsMSize), @@ -69,7 +69,7 @@ class LoopInvariantCodeMotion: public ASTModifier bool m_containsMSize = true; Dialect const& m_dialect; std::set const& m_ssaVariables; - std::map const& m_functionSideEffects; + std::map const& m_functionSideEffects; }; } diff --git a/libyul/optimiser/Metrics.cpp b/libyul/optimiser/Metrics.cpp index 546c465b5c43..04bfe9a7a06d 100644 --- a/libyul/optimiser/Metrics.cpp +++ b/libyul/optimiser/Metrics.cpp @@ -137,7 +137,7 @@ void CodeCost::operator()(FunctionCall const& _funCall) { ASTWalker::operator()(_funCall); - if (auto instruction = toEVMInstruction(m_dialect, _funCall.functionName.name)) + if (auto instruction = toEVMInstruction(m_dialect, _funCall.functionName)) { addInstructionCost(*instruction); return; diff --git a/libyul/optimiser/NameCollector.cpp b/libyul/optimiser/NameCollector.cpp index d6db837f8485..cde9b64f67d1 100644 --- a/libyul/optimiser/NameCollector.cpp +++ b/libyul/optimiser/NameCollector.cpp @@ -22,6 +22,7 @@ #include #include +#include using namespace solidity; using namespace solidity::yul; @@ -55,25 +56,25 @@ void ReferencesCounter::operator()(Identifier const& _identifier) void ReferencesCounter::operator()(FunctionCall const& _funCall) { - ++m_references[_funCall.functionName.name]; + ++m_references[functionNameToHandle(_funCall.functionName)]; ASTWalker::operator()(_funCall); } -std::map ReferencesCounter::countReferences(Block const& _block) +std::map ReferencesCounter::countReferences(Block const& _block) { ReferencesCounter counter; counter(_block); return std::move(counter.m_references); } -std::map ReferencesCounter::countReferences(FunctionDefinition const& _function) +std::map ReferencesCounter::countReferences(FunctionDefinition const& _function) { ReferencesCounter counter; counter(_function); return std::move(counter.m_references); } -std::map ReferencesCounter::countReferences(Expression const& _expression) +std::map ReferencesCounter::countReferences(Expression const& _expression) { ReferencesCounter counter; counter.visit(_expression); diff --git a/libyul/optimiser/NameCollector.h b/libyul/optimiser/NameCollector.h index 0fc2e311ca50..2adc73ced8e3 100644 --- a/libyul/optimiser/NameCollector.h +++ b/libyul/optimiser/NameCollector.h @@ -76,12 +76,12 @@ class ReferencesCounter: public ASTWalker void operator()(Identifier const& _identifier) override; void operator()(FunctionCall const& _funCall) override; - static std::map countReferences(Block const& _block); - static std::map countReferences(FunctionDefinition const& _function); - static std::map countReferences(Expression const& _expression); + static std::map countReferences(Block const& _block); + static std::map countReferences(FunctionDefinition const& _function); + static std::map countReferences(Expression const& _expression); private: - std::map m_references; + std::map m_references; }; /** diff --git a/libyul/optimiser/NameDisplacer.cpp b/libyul/optimiser/NameDisplacer.cpp index c68d52f9a7bb..7430c26c3046 100644 --- a/libyul/optimiser/NameDisplacer.cpp +++ b/libyul/optimiser/NameDisplacer.cpp @@ -54,7 +54,8 @@ void NameDisplacer::operator()(FunctionDefinition& _function) void NameDisplacer::operator()(FunctionCall& _funCall) { - checkAndReplace(_funCall.functionName.name); + if (std::holds_alternative(_funCall.functionName)) + checkAndReplace(std::get(_funCall.functionName).name); ASTModifier::operator()(_funCall); } diff --git a/libyul/optimiser/NameSimplifier.cpp b/libyul/optimiser/NameSimplifier.cpp index 6f3f1760a852..0572a9003523 100644 --- a/libyul/optimiser/NameSimplifier.cpp +++ b/libyul/optimiser/NameSimplifier.cpp @@ -67,8 +67,11 @@ void NameSimplifier::operator()(Identifier& _identifier) void NameSimplifier::operator()(FunctionCall& _funCall) { // The visitor on its own does not visit the function name. - if (!m_context.dialect.findBuiltin(_funCall.functionName.name.str())) - (*this)(_funCall.functionName); + if (!isBuiltinFunctionCall(_funCall)) + { + yulAssert(std::holds_alternative(_funCall.functionName)); + (*this)(std::get(_funCall.functionName)); + } ASTModifier::operator()(_funCall); } diff --git a/libyul/optimiser/OptimizerUtilities.cpp b/libyul/optimiser/OptimizerUtilities.cpp index 001ff147d4b5..8fc225bee0a4 100644 --- a/libyul/optimiser/OptimizerUtilities.cpp +++ b/libyul/optimiser/OptimizerUtilities.cpp @@ -23,8 +23,9 @@ #include -#include #include +#include +#include #include #include @@ -60,11 +61,11 @@ bool yul::isRestrictedIdentifier(Dialect const& _dialect, YulName const& _identi return _identifier.empty() || hasLeadingOrTrailingDot(_identifier.str()) || TokenTraits::isYulKeyword(_identifier.str()) || _dialect.reservedIdentifier(_identifier.str()); } -std::optional yul::toEVMInstruction(Dialect const& _dialect, YulName const& _name) +std::optional yul::toEVMInstruction(Dialect const& _dialect, FunctionName const& _name) { if (auto const* dialect = dynamic_cast(&_dialect)) - if (std::optional const builtinHandle = dialect->findBuiltin(_name.str())) - return dialect->builtin(*builtinHandle).instruction; + if (BuiltinFunctionForEVM const* builtin = resolveBuiltinFunctionForEVM(_name, *dialect)) + return builtin->instruction; return std::nullopt; } diff --git a/libyul/optimiser/OptimizerUtilities.h b/libyul/optimiser/OptimizerUtilities.h index 911a1be0a812..430834d8304b 100644 --- a/libyul/optimiser/OptimizerUtilities.h +++ b/libyul/optimiser/OptimizerUtilities.h @@ -48,7 +48,7 @@ void removeEmptyBlocks(Block& _block); bool isRestrictedIdentifier(Dialect const& _dialect, YulName const& _identifier); /// Helper function that returns the instruction, if the `_name` is a BuiltinFunction -std::optional toEVMInstruction(Dialect const& _dialect, YulName const& _name); +std::optional toEVMInstruction(Dialect const& _dialect, FunctionName const& _name); /// Helper function that returns the EVM version from a dialect. /// It returns the default EVM version if dialect is not an EVMDialect. diff --git a/libyul/optimiser/Semantics.cpp b/libyul/optimiser/Semantics.cpp index 1698ac5eef7a..a505126ae9f1 100644 --- a/libyul/optimiser/Semantics.cpp +++ b/libyul/optimiser/Semantics.cpp @@ -25,6 +25,7 @@ #include #include #include +#include #include @@ -40,7 +41,7 @@ using namespace solidity::yul; SideEffectsCollector::SideEffectsCollector( Dialect const& _dialect, Expression const& _expression, - std::map const* _functionSideEffects + std::map const* _functionSideEffects ): SideEffectsCollector(_dialect, _functionSideEffects) { @@ -56,7 +57,7 @@ SideEffectsCollector::SideEffectsCollector(Dialect const& _dialect, Statement co SideEffectsCollector::SideEffectsCollector( Dialect const& _dialect, Block const& _ast, - std::map const* _functionSideEffects + std::map const* _functionSideEffects ): SideEffectsCollector(_dialect, _functionSideEffects) { @@ -66,7 +67,7 @@ SideEffectsCollector::SideEffectsCollector( SideEffectsCollector::SideEffectsCollector( Dialect const& _dialect, ForLoop const& _ast, - std::map const* _functionSideEffects + std::map const* _functionSideEffects ): SideEffectsCollector(_dialect, _functionSideEffects) { @@ -77,11 +78,11 @@ void SideEffectsCollector::operator()(FunctionCall const& _functionCall) { ASTWalker::operator()(_functionCall); - YulName functionName = _functionCall.functionName.name; - if (std::optional builtinHandle = m_dialect.findBuiltin(functionName.str())) - m_sideEffects += m_dialect.builtin(*builtinHandle).sideEffects; - else if (m_functionSideEffects && m_functionSideEffects->count(functionName)) - m_sideEffects += m_functionSideEffects->at(functionName); + FunctionHandle functionHandle = functionNameToHandle(_functionCall.functionName); + if (BuiltinFunction const* builtin = resolveBuiltinFunction(_functionCall.functionName, m_dialect)) + m_sideEffects += builtin->sideEffects; + else if (m_functionSideEffects && m_functionSideEffects->count(functionHandle)) + m_sideEffects += m_functionSideEffects->at(functionHandle); else m_sideEffects += SideEffects::worst(); } @@ -111,12 +112,12 @@ void MSizeFinder::operator()(FunctionCall const& _functionCall) { ASTWalker::operator()(_functionCall); - if (std::optional builtinHandle = m_dialect.findBuiltin(_functionCall.functionName.name.str())) - if (m_dialect.builtin(*builtinHandle).isMSize) + if (BuiltinFunction const* builtin = resolveBuiltinFunction(_functionCall.functionName, m_dialect)) + if (builtin->isMSize) m_msizeFound = true; } -std::map SideEffectsPropagator::sideEffects( +std::map SideEffectsPropagator::sideEffects( Dialect const& _dialect, CallGraph const& _directCallGraph ) @@ -127,8 +128,16 @@ std::map SideEffectsPropagator::sideEffects( // In the future, we should refine that, because the property // is actually a bit different from "not movable". - std::map ret; - for (auto const& function: _directCallGraph.functionsWithLoops + _directCallGraph.recursiveFunctions()) + std::map ret; + for (auto const& function: _directCallGraph.functionsWithLoops) + { + ret[function].movable = false; + ret[function].canBeRemoved = false; + ret[function].canBeRemovedIfNoMSize = false; + ret[function].cannotLoop = false; + } + + for (auto const& function: _directCallGraph.recursiveFunctions()) { ret[function].movable = false; ret[function].canBeRemoved = false; @@ -138,20 +147,20 @@ std::map SideEffectsPropagator::sideEffects( for (auto const& call: _directCallGraph.functionCalls) { - YulName funName = call.first; + FunctionHandle funName = call.first; SideEffects sideEffects; - auto _visit = [&, visited = std::set{}](YulName _function, auto&& _recurse) mutable { + auto _visit = [&, visited = std::set{}](FunctionHandle _function, auto&& _recurse) mutable { if (!visited.insert(_function).second) return; if (sideEffects == SideEffects::worst()) return; - if (std::optional builtinHandle = _dialect.findBuiltin(_function.str())) + if (BuiltinHandle const* builtinHandle = std::get_if(&_function)) sideEffects += _dialect.builtin(*builtinHandle).sideEffects; else { if (ret.count(_function)) sideEffects += ret[_function]; - for (YulName callee: _directCallGraph.functionCalls.at(_function)) + for (FunctionHandle const& callee: _directCallGraph.functionCalls.at(_function)) _recurse(callee, _recurse); } }; @@ -228,10 +237,13 @@ bool TerminationFinder::containsNonContinuingFunctionCall(Expression const& _exp if (containsNonContinuingFunctionCall(arg)) return true; - if (std::optional const builtinHandle = m_dialect.findBuiltin(functionCall->functionName.name.str())) - return !m_dialect.builtin(*builtinHandle).controlFlowSideEffects.canContinue; - else if (m_functionSideEffects && m_functionSideEffects->count(functionCall->functionName.name)) - return !m_functionSideEffects->at(functionCall->functionName.name).canContinue; + if (BuiltinFunction const* builtin = resolveBuiltinFunction(functionCall->functionName, m_dialect)) + return !builtin->controlFlowSideEffects.canContinue; + + yulAssert(std::holds_alternative(functionCall->functionName)); + auto const& name = std::get(functionCall->functionName).name; + if (m_functionSideEffects && m_functionSideEffects->count(name)) + return !m_functionSideEffects->at(name).canContinue; } return false; } diff --git a/libyul/optimiser/Semantics.h b/libyul/optimiser/Semantics.h index e97fbd0c31a5..9fdeb78d031e 100644 --- a/libyul/optimiser/Semantics.h +++ b/libyul/optimiser/Semantics.h @@ -42,23 +42,23 @@ class SideEffectsCollector: public ASTWalker public: explicit SideEffectsCollector( Dialect const& _dialect, - std::map const* _functionSideEffects = nullptr + std::map const* _functionSideEffects = nullptr ): m_dialect(_dialect), m_functionSideEffects(_functionSideEffects) {} SideEffectsCollector( Dialect const& _dialect, Expression const& _expression, - std::map const* _functionSideEffects = nullptr + std::map const* _functionSideEffects = nullptr ); SideEffectsCollector(Dialect const& _dialect, Statement const& _statement); SideEffectsCollector( Dialect const& _dialect, Block const& _ast, - std::map const* _functionSideEffects = nullptr + std::map const* _functionSideEffects = nullptr ); SideEffectsCollector( Dialect const& _dialect, ForLoop const& _ast, - std::map const* _functionSideEffects = nullptr + std::map const* _functionSideEffects = nullptr ); using ASTWalker::operator(); @@ -117,7 +117,7 @@ class SideEffectsCollector: public ASTWalker private: Dialect const& m_dialect; - std::map const* m_functionSideEffects = nullptr; + std::map const* m_functionSideEffects = nullptr; SideEffects m_sideEffects; }; @@ -130,7 +130,7 @@ class SideEffectsCollector: public ASTWalker class SideEffectsPropagator { public: - static std::map sideEffects( + static std::map sideEffects( Dialect const& _dialect, CallGraph const& _directCallGraph ); @@ -195,7 +195,7 @@ class MovableChecker: public SideEffectsCollector public: explicit MovableChecker( Dialect const& _dialect, - std::map const* _functionSideEffects = nullptr + std::map const* _functionSideEffects = nullptr ): SideEffectsCollector(_dialect, _functionSideEffects) {} MovableChecker(Dialect const& _dialect, Expression const& _expression); diff --git a/libyul/optimiser/SimplificationRules.cpp b/libyul/optimiser/SimplificationRules.cpp index 0fcd35bda1ed..8a7549cc125a 100644 --- a/libyul/optimiser/SimplificationRules.cpp +++ b/libyul/optimiser/SimplificationRules.cpp @@ -79,9 +79,9 @@ std::optional const*>> { if (std::holds_alternative(_expr)) if (auto const* dialect = dynamic_cast(&_dialect)) - if (std::optional const builtinHandle = dialect->findBuiltin(std::get(_expr).functionName.name.str())) - if (auto const& instruction = dialect->builtin(*builtinHandle).instruction) - return std::make_pair(*instruction, &std::get(_expr).arguments); + if (auto const* builtin = resolveBuiltinFunctionForEVM(std::get(_expr).functionName, *dialect)) + if (builtin->instruction) + return std::make_pair(*builtin->instruction, &std::get(_expr).arguments); return {}; } @@ -234,7 +234,7 @@ evmasm::Instruction Pattern::instruction() const return m_instruction; } -Expression Pattern::toExpression(langutil::DebugData::ConstPtr const& _debugData, langutil::EVMVersion _evmVersion) const +Expression Pattern::toExpression(langutil::DebugData::ConstPtr const& _debugData, EVMDialect const& _dialect) const { if (matchGroup()) return ASTCopier().translate(matchGroupValue()); @@ -247,12 +247,18 @@ Expression Pattern::toExpression(langutil::DebugData::ConstPtr const& _debugData { std::vector arguments; for (auto const& arg: m_arguments) - arguments.emplace_back(arg.toExpression(_debugData, _evmVersion)); + arguments.emplace_back(arg.toExpression(_debugData, _dialect)); - std::string name = util::toLower(instructionInfo(m_instruction, _evmVersion).name); + if (!m_instructionBuiltinHandle) + { + std::string name = util::toLower(instructionInfo(m_instruction, _dialect.evmVersion()).name); + std::optional handle = _dialect.findBuiltin(name); + yulAssert(handle); + m_instructionBuiltinHandle = *handle; + } return FunctionCall{_debugData, - Identifier{_debugData, YulName{name}}, + BuiltinName{_debugData, *m_instructionBuiltinHandle}, std::move(arguments) }; } diff --git a/libyul/optimiser/SimplificationRules.h b/libyul/optimiser/SimplificationRules.h index 9362ee8557ec..2d48464ca62f 100644 --- a/libyul/optimiser/SimplificationRules.h +++ b/libyul/optimiser/SimplificationRules.h @@ -24,6 +24,7 @@ #include #include +#include #include #include @@ -38,8 +39,9 @@ namespace solidity::yul { -struct Dialect; struct AssignedValue; +struct Dialect; +class EVMDialect; class Pattern; using DebugData = langutil::DebugData; @@ -133,13 +135,14 @@ class Pattern /// Turns this pattern into an actual expression. Should only be called /// for patterns resulting from an action, i.e. with match groups assigned. - Expression toExpression(langutil::DebugData::ConstPtr const& _debugData, langutil::EVMVersion _evmVersion) const; + Expression toExpression(langutil::DebugData::ConstPtr const& _debugData, EVMDialect const& _dialect) const; private: Expression const& matchGroupValue() const; PatternKind m_kind = PatternKind::Any; evmasm::Instruction m_instruction; ///< Only valid if m_kind is Operation + std::optional mutable m_instructionBuiltinHandle; ///< Builtin handle cache for instructions std::shared_ptr m_data; ///< Only valid if m_kind is Constant std::vector m_arguments; unsigned m_matchGroup = 0; diff --git a/libyul/optimiser/StackLimitEvader.cpp b/libyul/optimiser/StackLimitEvader.cpp index 2dc32d78759a..766cd4928447 100644 --- a/libyul/optimiser/StackLimitEvader.cpp +++ b/libyul/optimiser/StackLimitEvader.cpp @@ -57,7 +57,7 @@ namespace */ struct MemoryOffsetAllocator { - uint64_t run(YulName _function = YulName{}) + uint64_t run(FunctionHandle _function = YulName{}) { if (slotsRequiredForFunction.count(_function)) return slotsRequiredForFunction[_function]; @@ -65,14 +65,17 @@ struct MemoryOffsetAllocator // Assign to zero early to guard against recursive calls. slotsRequiredForFunction[_function] = 0; + if (!std::holds_alternative(_function)) + return 0; + uint64_t requiredSlots = 0; - if (callGraph.count(_function)) - for (YulName child: callGraph.at(_function)) + if (callGraph.count(std::get(_function))) + for (FunctionHandle const& child: callGraph.at(std::get(_function))) requiredSlots = std::max(run(child), requiredSlots); - if (auto const* unreachables = util::valueOrNullptr(unreachableVariables, _function)) + if (auto const* unreachables = util::valueOrNullptr(unreachableVariables, std::get(_function))) { - if (FunctionDefinition const* functionDefinition = util::valueOrDefault(functionDefinitions, _function, nullptr, util::allow_copy)) + if (FunctionDefinition const* functionDefinition = util::valueOrDefault(functionDefinitions, std::get(_function), nullptr, util::allow_copy)) if ( size_t totalArgCount = functionDefinition->returnVariables.size() + functionDefinition->parameters.size(); totalArgCount > 16 @@ -99,14 +102,14 @@ struct MemoryOffsetAllocator /// An empty variable name means that the function has too many arguments or return variables. std::map> const& unreachableVariables; /// The graph of immediate function calls of all functions. - std::map> const& callGraph; + std::map> const& callGraph; /// Maps the name of each user-defined function to its definition. std::map const& functionDefinitions; /// Maps variable names to the memory slot the respective variable is assigned. std::map slotAllocations{}; /// Maps function names to the number of memory slots the respective function requires. - std::map slotsRequiredForFunction{}; + std::map slotsRequiredForFunction{}; }; u256 literalArgumentValue(FunctionCall const& _call) @@ -181,7 +184,7 @@ void StackLimitEvader::run( "StackLimitEvader can only be run on objects using the EVMDialect with object access." ); - std::vector memoryGuardCalls = findFunctionCalls(_astRoot, "memoryguard"_yulname); + std::vector memoryGuardCalls = findFunctionCalls(_astRoot, "memoryguard", *evmDialect); // Do not optimise, if no ``memoryguard`` call is found. if (memoryGuardCalls.empty()) return; @@ -197,9 +200,12 @@ void StackLimitEvader::run( CallGraph callGraph = CallGraphGenerator::callGraph(_astRoot); // We cannot move variables in recursive functions to fixed memory offsets. - for (YulName function: callGraph.recursiveFunctions()) - if (_unreachableVariables.count(function)) + for (FunctionHandle function: callGraph.recursiveFunctions()) + { + yulAssert(std::holds_alternative(function), "Builtins are not recursive."); + if (_unreachableVariables.count(std::get(function))) return; + } std::map functionDefinitions = allFunctionDefinitions(_astRoot); @@ -210,7 +216,7 @@ void StackLimitEvader::run( StackToMemoryMover::run(_context, reservedMemory, memoryOffsetAllocator.slotAllocations, requiredSlots, _astRoot); reservedMemory += 32 * requiredSlots; - for (FunctionCall* memoryGuardCall: findFunctionCalls(_astRoot, "memoryguard"_yulname)) + for (FunctionCall* memoryGuardCall: findFunctionCalls(_astRoot, "memoryguard", *evmDialect)) { Literal* literal = std::get_if(&memoryGuardCall->arguments.front()); yulAssert(literal && literal->kind == LiteralKind::Number, ""); diff --git a/libyul/optimiser/StackToMemoryMover.cpp b/libyul/optimiser/StackToMemoryMover.cpp index e75472f068f5..15df64b3f252 100644 --- a/libyul/optimiser/StackToMemoryMover.cpp +++ b/libyul/optimiser/StackToMemoryMover.cpp @@ -47,7 +47,7 @@ std::vector generateMemoryStore( std::vector result; result.emplace_back(ExpressionStatement{_debugData, FunctionCall{ _debugData, - Identifier{_debugData, YulName{_dialect.builtin(*memoryStoreFunctionHandle).name}}, + BuiltinName{_debugData, *memoryStoreFunctionHandle}, { Literal{_debugData, LiteralKind::Number, _mpos}, std::move(_value) @@ -62,7 +62,7 @@ FunctionCall generateMemoryLoad(Dialect const& _dialect, langutil::DebugData::Co yulAssert(memoryLoadHandle); return FunctionCall{ _debugData, - Identifier{_debugData, YulName{_dialect.builtin(*memoryLoadHandle).name}}, { + BuiltinName{_debugData, *memoryLoadHandle}, { Literal{ _debugData, LiteralKind::Number, @@ -223,13 +223,16 @@ void StackToMemoryMover::operator()(Block& _block) { FunctionCall const* functionCall = std::get_if(_stmt.value.get()); yulAssert(functionCall, ""); - if (m_context.dialect.findBuiltin(functionCall->functionName.name.str())) + if (isBuiltinFunctionCall(*functionCall)) rhsMemorySlots = std::vector>(_lhsVars.size(), std::nullopt); else + { + yulAssert(std::holds_alternative(functionCall->functionName)); rhsMemorySlots = - m_functionReturnVariables.at(functionCall->functionName.name) | + m_functionReturnVariables.at(std::get(functionCall->functionName).name) | ranges::views::transform(m_memoryOffsetTracker) | ranges::to>>; + } } else rhsMemorySlots = std::vector>(_lhsVars.size(), std::nullopt); diff --git a/libyul/optimiser/SyntacticalEquality.cpp b/libyul/optimiser/SyntacticalEquality.cpp index 73b4d5083c54..e233b57e9e2d 100644 --- a/libyul/optimiser/SyntacticalEquality.cpp +++ b/libyul/optimiser/SyntacticalEquality.cpp @@ -25,6 +25,7 @@ #include #include +#include using namespace solidity; using namespace solidity::yul; @@ -54,6 +55,14 @@ bool SyntacticallyEqual::expressionEqual(FunctionCall const& _lhs, FunctionCall }); } +bool SyntacticallyEqual::expressionEqual(FunctionName const& _lhs, FunctionName const& _rhs) +{ + return std::visit(util::GenericVisitor{ + [&](BuiltinName const& _builtin) { return std::holds_alternative(_rhs) && _builtin.handle == std::get(_rhs).handle; }, + [&](Identifier const& _identifier) { return std::holds_alternative(_rhs) && expressionEqual(_identifier, std::get(_rhs)); }, + }, _lhs); +} + bool SyntacticallyEqual::expressionEqual(Identifier const& _lhs, Identifier const& _rhs) { auto lhsIt = m_identifiersLHS.find(_lhs.name); diff --git a/libyul/optimiser/SyntacticalEquality.h b/libyul/optimiser/SyntacticalEquality.h index 1fd888f7af8c..0db52c9690df 100644 --- a/libyul/optimiser/SyntacticalEquality.h +++ b/libyul/optimiser/SyntacticalEquality.h @@ -48,6 +48,7 @@ class SyntacticallyEqual bool expressionEqual(FunctionCall const& _lhs, FunctionCall const& _rhs); bool expressionEqual(Identifier const& _lhs, Identifier const& _rhs); + bool expressionEqual(FunctionName const& _lhs, FunctionName const& _rhs); bool expressionEqual(Literal const& _lhs, Literal const& _rhs); bool statementEqual(ExpressionStatement const& _lhs, ExpressionStatement const& _rhs); diff --git a/libyul/optimiser/UnusedAssignEliminator.cpp b/libyul/optimiser/UnusedAssignEliminator.cpp index eb639f8a6c3f..6de2ebf4cacd 100644 --- a/libyul/optimiser/UnusedAssignEliminator.cpp +++ b/libyul/optimiser/UnusedAssignEliminator.cpp @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -79,10 +80,13 @@ void UnusedAssignEliminator::operator()(FunctionCall const& _functionCall) UnusedStoreBase::operator()(_functionCall); ControlFlowSideEffects sideEffects; - if (std::optional const builtinHandle = m_dialect.findBuiltin(_functionCall.functionName.name.str())) - sideEffects = m_dialect.builtin(*builtinHandle).controlFlowSideEffects; + if (BuiltinFunction const* builtin = resolveBuiltinFunction(_functionCall.functionName, m_dialect)) + sideEffects = builtin->controlFlowSideEffects; else - sideEffects = m_controlFlowSideEffects.at(_functionCall.functionName.name); + { + yulAssert(std::holds_alternative(_functionCall.functionName)); + sideEffects = m_controlFlowSideEffects.at(std::get(_functionCall.functionName).name); + } if (!sideEffects.canContinue) // We do not return from the current function, so it is OK to also diff --git a/libyul/optimiser/UnusedPruner.cpp b/libyul/optimiser/UnusedPruner.cpp index 9f6b88412f9c..91568f4d65be 100644 --- a/libyul/optimiser/UnusedPruner.cpp +++ b/libyul/optimiser/UnusedPruner.cpp @@ -43,7 +43,7 @@ UnusedPruner::UnusedPruner( Dialect const& _dialect, Block& _ast, bool _allowMSizeOptimization, - std::map const* _functionSideEffects, + std::map const* _functionSideEffects, std::set const& _externallyUsedFunctions ): m_dialect(_dialect), @@ -94,7 +94,7 @@ void UnusedPruner::operator()(Block& _block) else if (varDecl.variables.size() == 1 && m_dialect.discardFunctionHandle()) statement = ExpressionStatement{varDecl.debugData, FunctionCall{ varDecl.debugData, - {varDecl.debugData, YulName{m_dialect.builtin(*m_dialect.discardFunctionHandle()).name}}, + BuiltinName{varDecl.debugData, *m_dialect.discardFunctionHandle()}, {*std::move(varDecl.value)} }}; } @@ -121,7 +121,7 @@ void UnusedPruner::runUntilStabilised( Dialect const& _dialect, Block& _ast, bool _allowMSizeOptimization, - std::map const* _functionSideEffects, + std::map const* _functionSideEffects, std::set const& _externallyUsedFunctions ) { @@ -146,7 +146,7 @@ void UnusedPruner::runUntilStabilisedOnFullAST( std::set const& _externallyUsedFunctions ) { - std::map functionSideEffects = + std::map functionSideEffects = SideEffectsPropagator::sideEffects(_dialect, CallGraphGenerator::callGraph(_ast)); bool allowMSizeOptimization = !MSizeFinder::containsMSize(_dialect, _ast); runUntilStabilised(_dialect, _ast, allowMSizeOptimization, &functionSideEffects, _externallyUsedFunctions); @@ -157,7 +157,7 @@ bool UnusedPruner::used(YulName _name) const return m_references.count(_name) && m_references.at(_name) > 0; } -void UnusedPruner::subtractReferences(std::map const& _subtrahend) +void UnusedPruner::subtractReferences(std::map const& _subtrahend) { for (auto const& ref: _subtrahend) { diff --git a/libyul/optimiser/UnusedPruner.h b/libyul/optimiser/UnusedPruner.h index 040e7ce43b39..37d26bbb0c85 100644 --- a/libyul/optimiser/UnusedPruner.h +++ b/libyul/optimiser/UnusedPruner.h @@ -52,7 +52,6 @@ class UnusedPruner: public ASTModifier static constexpr char const* name{"UnusedPruner"}; static void run(OptimiserStepContext& _context, Block& _ast); - using ASTModifier::operator(); void operator()(Block& _block) override; @@ -64,7 +63,7 @@ class UnusedPruner: public ASTModifier Dialect const& _dialect, Block& _ast, bool _allowMSizeOptimization, - std::map const* _functionSideEffects = nullptr, + std::map const* _functionSideEffects = nullptr, std::set const& _externallyUsedFunctions = {} ); @@ -83,18 +82,18 @@ class UnusedPruner: public ASTModifier Dialect const& _dialect, Block& _ast, bool _allowMSizeOptimization, - std::map const* _functionSideEffects = nullptr, + std::map const* _functionSideEffects = nullptr, std::set const& _externallyUsedFunctions = {} ); bool used(YulName _name) const; - void subtractReferences(std::map const& _subtrahend); + void subtractReferences(std::map const& _subtrahend); Dialect const& m_dialect; bool m_allowMSizeOptimization = false; - std::map const* m_functionSideEffects = nullptr; + std::map const* m_functionSideEffects = nullptr; bool m_shouldRunAgain = false; - std::map m_references; + std::map m_references; }; } diff --git a/libyul/optimiser/UnusedStoreEliminator.cpp b/libyul/optimiser/UnusedStoreEliminator.cpp index 7c68d577bb74..6f2f1ee938f8 100644 --- a/libyul/optimiser/UnusedStoreEliminator.cpp +++ b/libyul/optimiser/UnusedStoreEliminator.cpp @@ -30,6 +30,7 @@ #include #include #include +#include #include @@ -45,7 +46,7 @@ using namespace solidity::yul; void UnusedStoreEliminator::run(OptimiserStepContext& _context, Block& _ast) { - std::map functionSideEffects = SideEffectsPropagator::sideEffects( + std::map functionSideEffects = SideEffectsPropagator::sideEffects( _context.dialect, CallGraphGenerator::callGraph(_ast) ); @@ -81,7 +82,7 @@ void UnusedStoreEliminator::run(OptimiserStepContext& _context, Block& _ast) UnusedStoreEliminator::UnusedStoreEliminator( Dialect const& _dialect, - std::map const& _functionSideEffects, + std::map const& _functionSideEffects, std::map _controlFlowSideEffects, std::map const& _ssaValues, bool _ignoreMemory @@ -89,9 +90,9 @@ UnusedStoreEliminator::UnusedStoreEliminator( UnusedStoreBase(_dialect), m_ignoreMemory(_ignoreMemory), m_functionSideEffects(_functionSideEffects), - m_controlFlowSideEffects(_controlFlowSideEffects), + m_controlFlowSideEffects(std::move(_controlFlowSideEffects)), m_ssaValues(_ssaValues), - m_knowledgeBase(_ssaValues) + m_knowledgeBase(_ssaValues, _dialect) {} void UnusedStoreEliminator::operator()(FunctionCall const& _functionCall) @@ -102,10 +103,13 @@ void UnusedStoreEliminator::operator()(FunctionCall const& _functionCall) applyOperation(op); ControlFlowSideEffects sideEffects; - if (std::optional const builtinHandle = m_dialect.findBuiltin(_functionCall.functionName.name.str())) - sideEffects = m_dialect.builtin(*builtinHandle).controlFlowSideEffects; + if (auto builtin = resolveBuiltinFunction(_functionCall.functionName, m_dialect)) + sideEffects = builtin->controlFlowSideEffects; else - sideEffects = m_controlFlowSideEffects.at(_functionCall.functionName.name); + { + yulAssert(std::holds_alternative(_functionCall.functionName)); + sideEffects = m_controlFlowSideEffects.at(std::get(_functionCall.functionName).name); + } if (sideEffects.canTerminate) markActiveAsUsed(Location::Storage); @@ -141,7 +145,7 @@ void UnusedStoreEliminator::visit(Statement const& _statement) FunctionCall const* funCall = std::get_if(&exprStatement->expression); yulAssert(funCall); - std::optional instruction = toEVMInstruction(m_dialect, funCall->functionName.name); + std::optional instruction = toEVMInstruction(m_dialect, funCall->functionName); if (!instruction) return; @@ -189,7 +193,7 @@ void UnusedStoreEliminator::visit(Statement const& _statement) if ( m_knowledgeBase.knownToBeZero(*startOffset) && lengthCall && - toEVMInstruction(m_dialect, lengthCall->functionName.name) == Instruction::RETURNDATASIZE + toEVMInstruction(m_dialect, lengthCall->functionName) == Instruction::RETURNDATASIZE ) allowReturndatacopyToBeRemoved = true; } @@ -216,14 +220,16 @@ std::vector UnusedStoreEliminator::operationsF { using evmasm::Instruction; - YulName functionName = _functionCall.functionName.name; SideEffects sideEffects; - if (std::optional const builtinHandle = m_dialect.findBuiltin(functionName.str())) - sideEffects = m_dialect.builtin(*builtinHandle).sideEffects; + if (BuiltinFunction const* f = resolveBuiltinFunction(_functionCall.functionName, m_dialect)) + sideEffects = f->sideEffects; else - sideEffects = m_functionSideEffects.at(functionName); + { + yulAssert(std::holds_alternative(_functionCall.functionName)); + sideEffects = m_functionSideEffects.at(std::get(_functionCall.functionName).name); + } - std::optional instruction = toEVMInstruction(m_dialect, functionName); + std::optional instruction = toEVMInstruction(m_dialect, _functionCall.functionName); if (!instruction) { std::vector result; diff --git a/libyul/optimiser/UnusedStoreEliminator.h b/libyul/optimiser/UnusedStoreEliminator.h index f749a229ca11..6da33a9866c6 100644 --- a/libyul/optimiser/UnusedStoreEliminator.h +++ b/libyul/optimiser/UnusedStoreEliminator.h @@ -62,7 +62,7 @@ class UnusedStoreEliminator: public UnusedStoreBase explicit UnusedStoreEliminator( Dialect const& _dialect, - std::map const& _functionSideEffects, + std::map const& _functionSideEffects, std::map _controlFlowSideEffects, std::map const& _ssaValues, bool _ignoreMemory @@ -122,7 +122,7 @@ class UnusedStoreEliminator: public UnusedStoreBase std::optional identifierNameIfSSA(Expression const& _expression) const; bool const m_ignoreMemory; - std::map const& m_functionSideEffects; + std::map const& m_functionSideEffects; std::map m_controlFlowSideEffects; std::map const& m_ssaValues; diff --git a/test/libsolidity/MemoryGuardTest.cpp b/test/libsolidity/MemoryGuardTest.cpp index a98c7a323015..b797564b7234 100644 --- a/test/libsolidity/MemoryGuardTest.cpp +++ b/test/libsolidity/MemoryGuardTest.cpp @@ -59,12 +59,13 @@ TestCase::TestResult MemoryGuardTest::run(std::ostream& _stream, std::string con m_obtainedResult.clear(); for (std::string contractName: compiler().contractNames()) { + auto const& dialect = EVMDialect::strictAssemblyForEVMObjects(CommonOptions::get().evmVersion(), CommonOptions::get().eofVersion()); ErrorList errors; std::optional const& ir = compiler().yulIR(contractName); solAssert(ir); auto [object, analysisInfo] = yul::test::parse( *ir, - EVMDialect::strictAssemblyForEVMObjects(CommonOptions::get().evmVersion(), CommonOptions::get().eofVersion()), + dialect, errors ); @@ -78,7 +79,8 @@ TestCase::TestResult MemoryGuardTest::run(std::ostream& _stream, std::string con auto handleObject = [&](std::string const& _kind, Object const& _object) { m_obtainedResult += contractName + "(" + _kind + ") " + (findFunctionCalls( _object.code()->root(), - "memoryguard"_yulname + "memoryguard", + dialect ).empty() ? "false" : "true") + "\n"; }; handleObject("creation", *object); diff --git a/test/libyul/ControlFlowGraphTest.cpp b/test/libyul/ControlFlowGraphTest.cpp index 0aaaea58105c..bd0bf0a802d2 100644 --- a/test/libyul/ControlFlowGraphTest.cpp +++ b/test/libyul/ControlFlowGraphTest.cpp @@ -64,8 +64,9 @@ static std::string variableSlotToString(VariableSlot const& _slot) class ControlFlowGraphPrinter { public: - ControlFlowGraphPrinter(std::ostream& _stream): - m_stream(_stream) + ControlFlowGraphPrinter(std::ostream& _stream, Dialect const& _dialect): + m_stream(_stream), + m_dialect(_dialect) { } void operator()(CFG::BasicBlock const& _block, bool _isMainEntry = true) @@ -133,7 +134,7 @@ class ControlFlowGraphPrinter m_stream << _call.function.get().name.str() << ": "; }, [&](CFG::BuiltinCall const& _call) { - m_stream << _call.functionCall.get().functionName.name.str() << ": "; + m_stream << _call.builtin.get().name << ": "; }, [&](CFG::Assignment const& _assignment) { m_stream << "Assignment("; @@ -141,7 +142,7 @@ class ControlFlowGraphPrinter m_stream << "): "; } }, operation.operation); - m_stream << stackToString(operation.input) << " => " << stackToString(operation.output) << "\\l\\\n"; + m_stream << stackToString(operation.input, m_dialect) << " => " << stackToString(operation.output, m_dialect) << "\\l\\\n"; } m_stream << "\"];\n"; std::visit(util::GenericVisitor{ @@ -163,7 +164,7 @@ class ControlFlowGraphPrinter { m_stream << "Block" << getBlockId(_block) << " -> Block" << getBlockId(_block) << "Exit;\n"; m_stream << "Block" << getBlockId(_block) << "Exit [label=\"{ "; - m_stream << stackSlotToString(_conditionalJump.condition); + m_stream << stackSlotToString(_conditionalJump.condition, m_dialect); m_stream << "| { <0> Zero | <1> NonZero }}\" shape=Mrecord];\n"; m_stream << "Block" << getBlockId(_block); m_stream << "Exit:0 -> Block" << getBlockId(*_conditionalJump.zero) << ";\n"; @@ -192,6 +193,7 @@ class ControlFlowGraphPrinter return id; } std::ostream& m_stream; + Dialect const& m_dialect; std::map m_blockIds; size_t m_blockCount = 0; std::list m_blocksToPrint; @@ -212,7 +214,7 @@ TestCase::TestResult ControlFlowGraphTest::run(std::ostream& _stream, std::strin std::unique_ptr cfg = ControlFlowGraphBuilder::build(*analysisInfo, *m_dialect, object->code()->root()); output << "digraph CFG {\nnodesep=0.7;\nnode[shape=box];\n\n"; - ControlFlowGraphPrinter printer{output}; + ControlFlowGraphPrinter printer{output, *m_dialect}; printer(*cfg->entry); for (auto function: cfg->functions) printer(cfg->functionInfo.at(function)); diff --git a/test/libyul/FunctionSideEffects.cpp b/test/libyul/FunctionSideEffects.cpp index 46a7c99fea51..204150ad837e 100644 --- a/test/libyul/FunctionSideEffects.cpp +++ b/test/libyul/FunctionSideEffects.cpp @@ -29,6 +29,7 @@ #include #include +#include #include @@ -92,14 +93,20 @@ TestCase::TestResult FunctionSideEffects::run(std::ostream& _stream, std::string if (!obj.hasCode()) BOOST_THROW_EXCEPTION(std::runtime_error("Parsing input failed.")); - std::map functionSideEffects = SideEffectsPropagator::sideEffects( + std::map functionSideEffects = SideEffectsPropagator::sideEffects( dialect, CallGraphGenerator::callGraph(obj.code()->root()) ); std::map functionSideEffectsStr; for (auto const& fun: functionSideEffects) - functionSideEffectsStr[fun.first.str()] = toString(fun.second); + { + auto const& functionNameStr = std::visit(GenericVisitor{ + [](YulName const& _name) { return _name.str(); }, + [&](BuiltinHandle const& _builtin) { return dialect.builtin(_builtin).name; } + }, fun.first); + functionSideEffectsStr[functionNameStr] = toString(fun.second); + } m_obtainedResult.clear(); for (auto const& fun: functionSideEffectsStr) diff --git a/test/libyul/KnowledgeBaseTest.cpp b/test/libyul/KnowledgeBaseTest.cpp index 0e7d411a3d3d..eefeb90109bc 100644 --- a/test/libyul/KnowledgeBaseTest.cpp +++ b/test/libyul/KnowledgeBaseTest.cpp @@ -60,7 +60,7 @@ class KnowledgeBaseTest m_values[name].value = expression; m_object->setCode(std::make_shared(m_dialect, std::move(astRoot))); - return KnowledgeBase([this](YulName _var) { return util::valueOrNullptr(m_values, _var); }); + return KnowledgeBase([this](YulName _var) { return util::valueOrNullptr(m_values, _var); }, m_dialect); } EVMDialect m_dialect{solidity::test::CommonOptions::get().evmVersion(), diff --git a/test/libyul/StackLayoutGeneratorTest.cpp b/test/libyul/StackLayoutGeneratorTest.cpp index 49af089ef82f..b41f7f21e820 100644 --- a/test/libyul/StackLayoutGeneratorTest.cpp +++ b/test/libyul/StackLayoutGeneratorTest.cpp @@ -69,8 +69,8 @@ static std::string variableSlotToString(VariableSlot const& _slot) class StackLayoutPrinter { public: - StackLayoutPrinter(std::ostream& _stream, StackLayout const& _stackLayout): - m_stream(_stream), m_stackLayout(_stackLayout) + StackLayoutPrinter(std::ostream& _stream, StackLayout const& _stackLayout, Dialect const& _dialect): + m_stream(_stream), m_stackLayout(_stackLayout), m_dialect(_dialect) { } void operator()(CFG::BasicBlock const& _block, bool _isMainEntry = true) @@ -104,7 +104,7 @@ class StackLayoutPrinter m_stream << "\\l\\\n"; Stack functionEntryStack = {FunctionReturnLabelSlot{_info.function}}; functionEntryStack += _info.parameters | ranges::views::reverse; - m_stream << stackToString(functionEntryStack) << "\"];\n"; + m_stream << stackToString(functionEntryStack, m_dialect) << "\"];\n"; m_stream << "FunctionEntry_" << _info.function.name.str() << " -> Block" << getBlockId(*_info.entry) << ";\n"; (*this)(*_info.entry, false); } @@ -135,17 +135,17 @@ class StackLayoutPrinter }, entry->exit); auto const& blockInfo = m_stackLayout.blockInfos.at(&_block); - m_stream << stackToString(blockInfo.entryLayout) << "\\l\\\n"; + m_stream << stackToString(blockInfo.entryLayout, m_dialect) << "\\l\\\n"; for (auto const& operation: _block.operations) { auto entryLayout = m_stackLayout.operationEntryLayout.at(&operation); - m_stream << stackToString(m_stackLayout.operationEntryLayout.at(&operation)) << "\\l\\\n"; + m_stream << stackToString(m_stackLayout.operationEntryLayout.at(&operation), m_dialect) << "\\l\\\n"; std::visit(util::GenericVisitor{ [&](CFG::FunctionCall const& _call) { m_stream << _call.function.get().name.str(); }, [&](CFG::BuiltinCall const& _call) { - m_stream << _call.functionCall.get().functionName.name.str(); + m_stream << _call.builtin.get().name; }, [&](CFG::Assignment const& _assignment) { @@ -159,9 +159,9 @@ class StackLayoutPrinter for (size_t i = 0; i < operation.input.size(); ++i) entryLayout.pop_back(); entryLayout += operation.output; - m_stream << stackToString(entryLayout) << "\\l\\\n"; + m_stream << stackToString(entryLayout, m_dialect) << "\\l\\\n"; } - m_stream << stackToString(blockInfo.exitLayout) << "\\l\\\n"; + m_stream << stackToString(blockInfo.exitLayout, m_dialect) << "\\l\\\n"; m_stream << "\"];\n"; std::visit(util::GenericVisitor{ [&](CFG::BasicBlock::MainExit const&) @@ -182,7 +182,7 @@ class StackLayoutPrinter { m_stream << "Block" << getBlockId(_block) << " -> Block" << getBlockId(_block) << "Exit;\n"; m_stream << "Block" << getBlockId(_block) << "Exit [label=\"{ "; - m_stream << stackSlotToString(_conditionalJump.condition); + m_stream << stackSlotToString(_conditionalJump.condition, m_dialect); m_stream << "| { <0> Zero | <1> NonZero }}\" shape=Mrecord];\n"; m_stream << "Block" << getBlockId(_block); m_stream << "Exit:0 -> Block" << getBlockId(*_conditionalJump.zero) << ";\n"; @@ -212,6 +212,7 @@ class StackLayoutPrinter } std::ostream& m_stream; StackLayout const& m_stackLayout; + Dialect const& m_dialect; std::map m_blockIds; size_t m_blockCount = 0; std::list m_blocksToPrint; @@ -238,7 +239,7 @@ TestCase::TestResult StackLayoutGeneratorTest::run(std::ostream& _stream, std::s StackLayout stackLayout = StackLayoutGenerator::run(*cfg, simulateFunctionsWithJumps); output << "digraph CFG {\nnodesep=0.7;\nnode[shape=box];\n\n"; - StackLayoutPrinter printer{output, stackLayout}; + StackLayoutPrinter printer{output, stackLayout, *m_dialect}; printer(*cfg->entry); for (auto function: cfg->functions) printer(cfg->functionInfo.at(function)); diff --git a/test/libyul/StackShufflingTest.cpp b/test/libyul/StackShufflingTest.cpp index 40fdcc5b15f4..baf8e0c8e543 100644 --- a/test/libyul/StackShufflingTest.cpp +++ b/test/libyul/StackShufflingTest.cpp @@ -17,9 +17,13 @@ #include +#include + +#include +#include + #include #include -#include using namespace solidity::util; using namespace solidity::langutil; @@ -137,6 +141,10 @@ StackShufflingTest::StackShufflingTest(std::string const& _filename): TestCase::TestResult StackShufflingTest::run(std::ostream& _stream, std::string const& _linePrefix, bool _formatted) { + auto const& dialect = EVMDialect::strictAssemblyForEVMObjects( + solidity::test::CommonOptions::get().evmVersion(), + solidity::test::CommonOptions::get().eofVersion() + ); if (!parse(m_source)) { AnsiColorized(_stream, _formatted, {formatting::BOLD, formatting::RED}) << _linePrefix << "Error parsing source." << std::endl; @@ -149,14 +157,14 @@ TestCase::TestResult StackShufflingTest::run(std::ostream& _stream, std::string m_targetStack, [&](unsigned _swapDepth) // swap { - output << stackToString(m_sourceStack) << std::endl; + output << stackToString(m_sourceStack, dialect) << std::endl; output << "SWAP" << _swapDepth << std::endl; }, [&](StackSlot const& _slot) // dupOrPush { - output << stackToString(m_sourceStack) << std::endl; + output << stackToString(m_sourceStack, dialect) << std::endl; if (canBeFreelyGenerated(_slot)) - output << "PUSH " << stackSlotToString(_slot) << std::endl; + output << "PUSH " << stackSlotToString(_slot, dialect) << std::endl; else { if (auto depth = util::findOffset(m_sourceStack | ranges::views::reverse, _slot)) @@ -166,12 +174,12 @@ TestCase::TestResult StackShufflingTest::run(std::ostream& _stream, std::string } }, [&](){ // pop - output << stackToString(m_sourceStack) << std::endl; + output << stackToString(m_sourceStack, dialect) << std::endl; output << "POP" << std::endl; } ); - output << stackToString(m_sourceStack) << std::endl; + output << stackToString(m_sourceStack, dialect) << std::endl; m_obtainedResult = output.str(); return checkResult(_stream, _linePrefix, _formatted); diff --git a/test/tools/yulInterpreter/Interpreter.cpp b/test/tools/yulInterpreter/Interpreter.cpp index 433ff3f072e3..2709d1b468aa 100644 --- a/test/tools/yulInterpreter/Interpreter.cpp +++ b/test/tools/yulInterpreter/Interpreter.cpp @@ -309,42 +309,39 @@ void ExpressionEvaluator::operator()(Identifier const& _identifier) void ExpressionEvaluator::operator()(FunctionCall const& _funCall) { std::vector> const* literalArguments = nullptr; - if (std::optional builtinHandle = m_dialect.findBuiltin(_funCall.functionName.name.str())) - if ( - auto const& args = m_dialect.builtin(*builtinHandle).literalArguments; - !args.empty() - ) - literalArguments = &args; + if (BuiltinFunction const* builtin = resolveBuiltinFunction(_funCall.functionName, m_dialect)) + if (!builtin->literalArguments.empty()) + literalArguments = &builtin->literalArguments; evaluateArgs(_funCall.arguments, literalArguments); if (EVMDialect const* dialect = dynamic_cast(&m_dialect)) { - if (std::optional builtinHandle = dialect->findBuiltin(_funCall.functionName.name.str())) + if (BuiltinFunctionForEVM const* fun = resolveBuiltinFunctionForEVM(_funCall.functionName, *dialect)) { - auto const& fun = dialect->builtin(*builtinHandle); EVMInstructionInterpreter interpreter(dialect->evmVersion(), m_state, m_disableMemoryTrace); - u256 const value = interpreter.evalBuiltin(fun, _funCall.arguments, values()); + u256 const value = interpreter.evalBuiltin(*fun, _funCall.arguments, values()); if ( !m_disableExternalCalls && - fun.instruction && - evmasm::isCallInstruction(*fun.instruction) + fun->instruction && + evmasm::isCallInstruction(*fun->instruction) ) - runExternalCall(*fun.instruction); + runExternalCall(*fun->instruction); setValue(value); return; } } + yulAssert(!isBuiltinFunctionCall(_funCall)); Scope* scope = &m_scope; for (; scope; scope = scope->parent) - if (scope->names.count(_funCall.functionName.name)) + if (scope->names.count(std::get(_funCall.functionName).name)) break; yulAssert(scope, ""); - FunctionDefinition const* fun = scope->names.at(_funCall.functionName.name); + FunctionDefinition const* fun = scope->names.at(std::get(_funCall.functionName).name); yulAssert(fun, "Function not found."); yulAssert(m_values.size() == fun->parameters.size(), ""); std::map variables; From 1380016cc3e20797b2e663e34e7aa2dcb980572c Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Tue, 22 Oct 2024 14:34:46 +0200 Subject: [PATCH 0615/1022] Add Yul tests to test erroneous assignment to builtins and numbers --- test/libyul/yulSyntaxTests/assignment_to_builtin.yul | 6 ++++++ test/libyul/yulSyntaxTests/assignment_to_number.yul | 6 ++++++ 2 files changed, 12 insertions(+) create mode 100644 test/libyul/yulSyntaxTests/assignment_to_builtin.yul create mode 100644 test/libyul/yulSyntaxTests/assignment_to_number.yul diff --git a/test/libyul/yulSyntaxTests/assignment_to_builtin.yul b/test/libyul/yulSyntaxTests/assignment_to_builtin.yul new file mode 100644 index 000000000000..80f84c1349c5 --- /dev/null +++ b/test/libyul/yulSyntaxTests/assignment_to_builtin.yul @@ -0,0 +1,6 @@ +{ + function f() -> x {} + add := f() +} +// ---- +// ParserError 6272: (35-37): Cannot assign to builtin function "add". diff --git a/test/libyul/yulSyntaxTests/assignment_to_number.yul b/test/libyul/yulSyntaxTests/assignment_to_number.yul new file mode 100644 index 000000000000..3c4517fdde0c --- /dev/null +++ b/test/libyul/yulSyntaxTests/assignment_to_number.yul @@ -0,0 +1,6 @@ +{ + function f() -> x {} + let 123 := f() +} +// ---- +// ParserError 2314: (35-38): Expected identifier but got 'Number' From 804c4848657b0cacbb20afb8610d2e0a62b403eb Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Fri, 6 Dec 2024 07:04:09 +0100 Subject: [PATCH 0616/1022] Yul BlockHasher: Do not hash number of arguments for function calls. --- libyul/optimiser/BlockHasher.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/libyul/optimiser/BlockHasher.cpp b/libyul/optimiser/BlockHasher.cpp index 2cc7a6648392..6e8e8ed62f57 100644 --- a/libyul/optimiser/BlockHasher.cpp +++ b/libyul/optimiser/BlockHasher.cpp @@ -66,7 +66,6 @@ void ASTHasherBase::hashFunctionCall(FunctionCall const& _funCall) { hash64(compileTimeLiteralHash("UserDefined")); hash64(_identifier.name.hash()); - hash64(_funCall.arguments.size()); } }; std::visit(visitor, _funCall.functionName); From 8994d85fb7f86804436c81a64f6ee998a6f01fac Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Fri, 6 Dec 2024 08:13:57 +0100 Subject: [PATCH 0617/1022] YulString accepts string_view --- libyul/AsmAnalysis.cpp | 2 +- libyul/YulString.h | 7 ++++--- libyul/backends/evm/SSAControlFlowGraphBuilder.cpp | 2 +- libyul/optimiser/ExpressionInliner.cpp | 2 +- 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/libyul/AsmAnalysis.cpp b/libyul/AsmAnalysis.cpp index 7d395a208a99..ddd7ad1539aa 100644 --- a/libyul/AsmAnalysis.cpp +++ b/libyul/AsmAnalysis.cpp @@ -354,7 +354,7 @@ size_t AsmAnalyzer::operator()(FunctionCall const& _funCall) validateInstructions(_funCall); m_sideEffects += builtin->sideEffects; } - else if (m_currentScope->lookup(YulName{std::string(resolveFunctionName(_funCall.functionName, m_dialect))}, GenericVisitor{ + else if (m_currentScope->lookup(YulName{resolveFunctionName(_funCall.functionName, m_dialect)}, GenericVisitor{ [&](Scope::Variable const&) { m_errorReporter.typeError( diff --git a/libyul/YulString.h b/libyul/YulString.h index bd9438e5abc9..d6c13f0d3751 100644 --- a/libyul/YulString.h +++ b/libyul/YulString.h @@ -27,6 +27,7 @@ #include #include #include +#include #include namespace solidity::yul @@ -51,7 +52,7 @@ class YulStringRepository return inst; } - Handle stringToHandle(std::string const& _string) + Handle stringToHandle(std::string_view const _string) { if (_string.empty()) return { 0, emptyHash() }; @@ -68,7 +69,7 @@ class YulStringRepository } std::string const& idToString(size_t _id) const { return *m_strings.at(_id); } - static std::uint64_t hash(std::string const& v) + static std::uint64_t hash(std::string_view const v) { // FNV hash - can be replaced by a better one, e.g. xxhash64 std::uint64_t hash = emptyHash(); @@ -126,7 +127,7 @@ class YulString { public: YulString() = default; - explicit YulString(std::string const& _s): m_handle(YulStringRepository::instance().stringToHandle(_s)) {} + explicit YulString(std::string_view const _s): m_handle(YulStringRepository::instance().stringToHandle(_s)) {} YulString(YulString const&) = default; YulString(YulString&&) = default; YulString& operator=(YulString const&) = default; diff --git a/libyul/backends/evm/SSAControlFlowGraphBuilder.cpp b/libyul/backends/evm/SSAControlFlowGraphBuilder.cpp index b47248dd58bc..4597c56a5917 100644 --- a/libyul/backends/evm/SSAControlFlowGraphBuilder.cpp +++ b/libyul/backends/evm/SSAControlFlowGraphBuilder.cpp @@ -563,7 +563,7 @@ std::vector SSAControlFlowGraphBuilder::visitFunctionCall(Funct } else { - YulName const functionName{std::string(resolveFunctionName(_call.functionName, m_dialect))}; + YulName const functionName{resolveFunctionName(_call.functionName, m_dialect)}; Scope::Function const& function = lookupFunction(functionName); auto const* definition = findFunctionDefinition(&function); yulAssert(definition); diff --git a/libyul/optimiser/ExpressionInliner.cpp b/libyul/optimiser/ExpressionInliner.cpp index 1dbd5ca98004..0d59dab2d2e7 100644 --- a/libyul/optimiser/ExpressionInliner.cpp +++ b/libyul/optimiser/ExpressionInliner.cpp @@ -53,7 +53,7 @@ void ExpressionInliner::visit(Expression& _expression) if (std::holds_alternative(_expression)) { FunctionCall& funCall = std::get(_expression); - YulString const functionName{std::string(resolveFunctionName(funCall.functionName, m_dialect))}; + YulString const functionName{resolveFunctionName(funCall.functionName, m_dialect)}; if (!m_inlinableFunctions.count(functionName)) return; FunctionDefinition const& fun = *m_inlinableFunctions.at(functionName); From a9f0b3d2aec443c95294fc6c8640e77bc77b377b Mon Sep 17 00:00:00 2001 From: rodiazet Date: Mon, 9 Dec 2024 15:04:16 +0100 Subject: [PATCH 0618/1022] eof: eof: Fix legacy `create2` and `extcodehash` error for EOF --- libyul/AsmAnalysis.cpp | 2 ++ test/libyul/yulSyntaxTests/eof/create2_in_eof.yul | 11 +++++++++++ test/libyul/yulSyntaxTests/eof/extcodehash_in_eof.yul | 11 +++++++++++ 3 files changed, 24 insertions(+) create mode 100644 test/libyul/yulSyntaxTests/eof/create2_in_eof.yul create mode 100644 test/libyul/yulSyntaxTests/eof/extcodehash_in_eof.yul diff --git a/libyul/AsmAnalysis.cpp b/libyul/AsmAnalysis.cpp index 9d816061c209..55f5af4cf3ab 100644 --- a/libyul/AsmAnalysis.cpp +++ b/libyul/AsmAnalysis.cpp @@ -783,10 +783,12 @@ bool AsmAnalyzer::validateInstructions(evmasm::Instruction _instr, SourceLocatio _instr == evmasm::Instruction::JUMPI || _instr == evmasm::Instruction::PC || _instr == evmasm::Instruction::CREATE || + _instr == evmasm::Instruction::CREATE2 || _instr == evmasm::Instruction::CODESIZE || _instr == evmasm::Instruction::CODECOPY || _instr == evmasm::Instruction::EXTCODESIZE || _instr == evmasm::Instruction::EXTCODECOPY || + _instr == evmasm::Instruction::EXTCODEHASH || _instr == evmasm::Instruction::GAS )) { diff --git a/test/libyul/yulSyntaxTests/eof/create2_in_eof.yul b/test/libyul/yulSyntaxTests/eof/create2_in_eof.yul new file mode 100644 index 000000000000..77c10694749b --- /dev/null +++ b/test/libyul/yulSyntaxTests/eof/create2_in_eof.yul @@ -0,0 +1,11 @@ +object "a" { + code { + pop(create2(0, 0, 0, 0)) + } +} + +// ==== +// bytecodeFormat: >=EOFv1 +// ---- +// TypeError 9132: (36-43): The "create2" instruction is only available in legacy bytecode VMs (you are currently compiling to EOF). +// TypeError 3950: (36-55): Expected expression to evaluate to one value, but got 0 values instead. diff --git a/test/libyul/yulSyntaxTests/eof/extcodehash_in_eof.yul b/test/libyul/yulSyntaxTests/eof/extcodehash_in_eof.yul new file mode 100644 index 000000000000..79bfb4499386 --- /dev/null +++ b/test/libyul/yulSyntaxTests/eof/extcodehash_in_eof.yul @@ -0,0 +1,11 @@ +object "a" { + code { + pop(extcodehash(0)) + } +} + +// ==== +// bytecodeFormat: >=EOFv1 +// ---- +// TypeError 9132: (36-47): The "extcodehash" instruction is only available in legacy bytecode VMs (you are currently compiling to EOF). +// TypeError 3950: (36-50): Expected expression to evaluate to one value, but got 0 values instead. From becce9242634da8d909a123586ecad1d4f9042be Mon Sep 17 00:00:00 2001 From: r0qs Date: Mon, 9 Dec 2024 17:32:17 +0100 Subject: [PATCH 0619/1022] Disable the stale action for issues. --- .github/workflows/stale.yml | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index d982c43f2b59..0b344728220c 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -1,4 +1,4 @@ -name: Check stale issues and pull requests +name: Check stale pull requests on: workflow_dispatch: @@ -6,12 +6,12 @@ on: - cron: '0 12 * * *' permissions: - issues: write pull-requests: write env: - BEFORE_ISSUE_STALE: 90 - BEFORE_ISSUE_CLOSE: 7 + # NOTE: We set the parameters below to -1, so issues will never be marked as stale or closed automatically. + BEFORE_ISSUE_STALE: -1 + BEFORE_ISSUE_CLOSE: -1 BEFORE_PR_STALE: 14 BEFORE_PR_CLOSE: 7 @@ -24,17 +24,7 @@ jobs: debug-only: false days-before-issue-stale: ${{ env.BEFORE_ISSUE_STALE }} days-before-issue-close: ${{ env.BEFORE_ISSUE_CLOSE }} - stale-issue-message: | - This issue has been marked as stale due to inactivity for the last ${{ env.BEFORE_ISSUE_STALE }} days. - It will be automatically closed in ${{ env.BEFORE_ISSUE_CLOSE }} days. - close-issue-message: | - Hi everyone! This issue has been automatically closed due to inactivity. - If you think this issue is still relevant in the latest Solidity version and you have something to [contribute](https://docs.soliditylang.org/en/latest/contributing.html), feel free to reopen. - However, unless the issue is a concrete proposal that can be implemented, we recommend starting a language discussion on the [forum](https://forum.soliditylang.org) instead. ascending: true - stale-issue-label: stale - close-issue-label: 'closed due inactivity' - exempt-issue-labels: 'bug :bug:,epic,roadmap,selected for development,must have,must have eventually,smt' stale-pr-message: | This pull request is stale because it has been open for ${{ env.BEFORE_PR_STALE }} days with no activity. It will be closed in ${{ env.BEFORE_PR_CLOSE }} days unless the `stale` label is removed. From 5efaa669208d26d847e2ac5f57a5195a3c487891 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Fri, 6 Dec 2024 07:42:31 +0100 Subject: [PATCH 0620/1022] Yul: Make Dialect into a class. --- libsolidity/ast/AST.h | 2 +- libsolidity/ast/ASTAnnotations.h | 2 +- libyul/AST.h | 2 +- libyul/AsmJsonConverter.h | 2 +- libyul/AsmJsonImporter.h | 2 +- libyul/AsmPrinter.h | 2 +- libyul/ControlFlowSideEffectsCollector.h | 2 +- libyul/Dialect.h | 3 ++- libyul/Object.h | 2 +- libyul/Utilities.h | 2 +- libyul/backends/evm/ConstantOptimiser.h | 2 +- libyul/optimiser/CommonSubexpressionEliminator.h | 2 +- libyul/optimiser/ControlFlowSimplifier.h | 2 +- libyul/optimiser/DataFlowAnalyzer.h | 2 +- libyul/optimiser/DeadCodeEliminator.h | 2 +- libyul/optimiser/Disambiguator.h | 2 +- libyul/optimiser/ExpressionInliner.h | 2 +- libyul/optimiser/ExpressionSimplifier.h | 2 +- libyul/optimiser/ExpressionSplitter.h | 2 +- libyul/optimiser/FunctionCallFinder.h | 2 +- libyul/optimiser/KnowledgeBase.h | 2 +- libyul/optimiser/Metrics.h | 2 +- libyul/optimiser/NameDispenser.h | 2 +- libyul/optimiser/NameDisplacer.h | 2 +- libyul/optimiser/NameSimplifier.h | 2 +- libyul/optimiser/OptimiserStep.h | 2 +- libyul/optimiser/Semantics.h | 2 +- libyul/optimiser/SimplificationRules.h | 2 +- libyul/optimiser/StackCompressor.h | 2 +- libyul/optimiser/Suite.h | 2 +- libyul/optimiser/UnusedAssignEliminator.h | 2 +- libyul/optimiser/UnusedPruner.h | 2 +- libyul/optimiser/UnusedStoreBase.h | 2 +- libyul/optimiser/UnusedStoreEliminator.h | 2 +- libyul/optimiser/VarNameCleaner.h | 2 +- test/libyul/Common.h | 2 +- test/libyul/ControlFlowGraphTest.h | 2 +- test/libyul/SSAControlFlowGraphTest.h | 2 +- test/libyul/StackLayoutGeneratorTest.h | 2 +- test/libyul/YulOptimizerTest.h | 2 +- test/libyul/YulOptimizerTestCommon.h | 2 +- test/tools/yulInterpreter/Interpreter.h | 2 +- tools/yulPhaser/Program.h | 2 +- 43 files changed, 44 insertions(+), 43 deletions(-) diff --git a/libsolidity/ast/AST.h b/libsolidity/ast/AST.h index 0e2df8a900fc..fa2ce20948c2 100644 --- a/libsolidity/ast/AST.h +++ b/libsolidity/ast/AST.h @@ -49,7 +49,7 @@ namespace solidity::yul { // Forward-declaration to class AST; -struct Dialect; +class Dialect; } namespace solidity::frontend diff --git a/libsolidity/ast/ASTAnnotations.h b/libsolidity/ast/ASTAnnotations.h index 81b3b8374697..f017481be5aa 100644 --- a/libsolidity/ast/ASTAnnotations.h +++ b/libsolidity/ast/ASTAnnotations.h @@ -39,7 +39,7 @@ namespace solidity::yul { struct AsmAnalysisInfo; struct Identifier; -struct Dialect; +class Dialect; } namespace solidity::frontend diff --git a/libyul/AST.h b/libyul/AST.h index b19499b9a7d1..6a49db68e7aa 100644 --- a/libyul/AST.h +++ b/libyul/AST.h @@ -37,7 +37,7 @@ namespace solidity::yul { -struct Dialect; +class Dialect; struct NameWithDebugData { langutil::DebugData::ConstPtr debugData; YulName name; }; using NameWithDebugDataList = std::vector; diff --git a/libyul/AsmJsonConverter.h b/libyul/AsmJsonConverter.h index 458142e29346..6705197f943f 100644 --- a/libyul/AsmJsonConverter.h +++ b/libyul/AsmJsonConverter.h @@ -33,7 +33,7 @@ namespace solidity::yul { -struct Dialect; +class Dialect; /** * Converter of the yul AST into JSON format diff --git a/libyul/AsmJsonImporter.h b/libyul/AsmJsonImporter.h index 2d7ff472c5e9..830e44b3acb1 100644 --- a/libyul/AsmJsonImporter.h +++ b/libyul/AsmJsonImporter.h @@ -32,7 +32,7 @@ namespace solidity::yul { -struct Dialect; +class Dialect; /** * Component that imports an AST from json format to the internal format diff --git a/libyul/AsmPrinter.h b/libyul/AsmPrinter.h index d889d83f80ec..60a7f9a0f289 100644 --- a/libyul/AsmPrinter.h +++ b/libyul/AsmPrinter.h @@ -37,7 +37,7 @@ namespace solidity::yul { -struct Dialect; +class Dialect; /** * Converts a parsed Yul AST into readable string representation. diff --git a/libyul/ControlFlowSideEffectsCollector.h b/libyul/ControlFlowSideEffectsCollector.h index 5a1c76297012..2ef7a4bfa003 100644 --- a/libyul/ControlFlowSideEffectsCollector.h +++ b/libyul/ControlFlowSideEffectsCollector.h @@ -29,7 +29,7 @@ namespace solidity::yul { -struct Dialect; +class Dialect; struct ControlFlowNode { diff --git a/libyul/Dialect.h b/libyul/Dialect.h index 62d18bdf0ec8..2afd4a579288 100644 --- a/libyul/Dialect.h +++ b/libyul/Dialect.h @@ -57,8 +57,9 @@ struct BuiltinFunction } }; -struct Dialect +class Dialect { +public: /// Noncopiable. Dialect(Dialect const&) = delete; Dialect& operator=(Dialect const&) = delete; diff --git a/libyul/Object.h b/libyul/Object.h index 295c4a87c786..c865b906ed37 100644 --- a/libyul/Object.h +++ b/libyul/Object.h @@ -36,7 +36,7 @@ namespace solidity::yul { -struct Dialect; +class Dialect; struct AsmAnalysisInfo; using SourceNameMap = std::map>; diff --git a/libyul/Utilities.h b/libyul/Utilities.h index a4a558a855b9..64b5f456ac1f 100644 --- a/libyul/Utilities.h +++ b/libyul/Utilities.h @@ -30,7 +30,7 @@ namespace solidity::yul { -struct Dialect; +class Dialect; class EVMDialect; struct BuiltinFunction; struct BuiltinFunctionForEVM; diff --git a/libyul/backends/evm/ConstantOptimiser.h b/libyul/backends/evm/ConstantOptimiser.h index 5e4b2002b0d0..9c25450bf96f 100644 --- a/libyul/backends/evm/ConstantOptimiser.h +++ b/libyul/backends/evm/ConstantOptimiser.h @@ -37,7 +37,7 @@ namespace solidity::yul { -struct Dialect; +class Dialect; class GasMeter; /** diff --git a/libyul/optimiser/CommonSubexpressionEliminator.h b/libyul/optimiser/CommonSubexpressionEliminator.h index 35f8168eba73..713c35f0229c 100644 --- a/libyul/optimiser/CommonSubexpressionEliminator.h +++ b/libyul/optimiser/CommonSubexpressionEliminator.h @@ -32,7 +32,7 @@ namespace solidity::yul { -struct Dialect; +class Dialect; struct SideEffects; /** diff --git a/libyul/optimiser/ControlFlowSimplifier.h b/libyul/optimiser/ControlFlowSimplifier.h index 86ebf296c290..829138471752 100644 --- a/libyul/optimiser/ControlFlowSimplifier.h +++ b/libyul/optimiser/ControlFlowSimplifier.h @@ -22,7 +22,7 @@ namespace solidity::yul { -struct Dialect; +class Dialect; struct OptimiserStepContext; /** diff --git a/libyul/optimiser/DataFlowAnalyzer.h b/libyul/optimiser/DataFlowAnalyzer.h index 7d0f78b534c2..5b1cf25ffe1f 100644 --- a/libyul/optimiser/DataFlowAnalyzer.h +++ b/libyul/optimiser/DataFlowAnalyzer.h @@ -37,7 +37,7 @@ namespace solidity::yul { -struct Dialect; +class Dialect; struct SideEffects; class KnowledgeBase; diff --git a/libyul/optimiser/DeadCodeEliminator.h b/libyul/optimiser/DeadCodeEliminator.h index f252536c599e..701af3ad1561 100644 --- a/libyul/optimiser/DeadCodeEliminator.h +++ b/libyul/optimiser/DeadCodeEliminator.h @@ -30,7 +30,7 @@ namespace solidity::yul { -struct Dialect; +class Dialect; struct OptimiserStepContext; /** diff --git a/libyul/optimiser/Disambiguator.h b/libyul/optimiser/Disambiguator.h index 08d8d158f699..36d178b086c1 100644 --- a/libyul/optimiser/Disambiguator.h +++ b/libyul/optimiser/Disambiguator.h @@ -31,7 +31,7 @@ namespace solidity::yul { -struct Dialect; +class Dialect; /** * Creates a copy of a Yul AST replacing all identifiers by unique names. diff --git a/libyul/optimiser/ExpressionInliner.h b/libyul/optimiser/ExpressionInliner.h index 08ff08648428..f8cf70d56e13 100644 --- a/libyul/optimiser/ExpressionInliner.h +++ b/libyul/optimiser/ExpressionInliner.h @@ -29,7 +29,7 @@ namespace solidity::yul { -struct Dialect; +class Dialect; struct OptimiserStepContext; /** diff --git a/libyul/optimiser/ExpressionSimplifier.h b/libyul/optimiser/ExpressionSimplifier.h index 662c8c389936..b004c9b5211a 100644 --- a/libyul/optimiser/ExpressionSimplifier.h +++ b/libyul/optimiser/ExpressionSimplifier.h @@ -27,7 +27,7 @@ namespace solidity::yul { -struct Dialect; +class Dialect; struct OptimiserStepContext; /** diff --git a/libyul/optimiser/ExpressionSplitter.h b/libyul/optimiser/ExpressionSplitter.h index 0b223e9859b2..2581b23de1e2 100644 --- a/libyul/optimiser/ExpressionSplitter.h +++ b/libyul/optimiser/ExpressionSplitter.h @@ -31,7 +31,7 @@ namespace solidity::yul { -struct Dialect; +class Dialect; struct OptimiserStepContext; /** diff --git a/libyul/optimiser/FunctionCallFinder.h b/libyul/optimiser/FunctionCallFinder.h index 067aee2a399c..1c21a0115985 100644 --- a/libyul/optimiser/FunctionCallFinder.h +++ b/libyul/optimiser/FunctionCallFinder.h @@ -28,7 +28,7 @@ namespace solidity::yul { -struct Dialect; +class Dialect; /** * Finds all calls to a function of a given name using an ASTModifier. diff --git a/libyul/optimiser/KnowledgeBase.h b/libyul/optimiser/KnowledgeBase.h index 78daadbc4ee4..0852f8902592 100644 --- a/libyul/optimiser/KnowledgeBase.h +++ b/libyul/optimiser/KnowledgeBase.h @@ -34,7 +34,7 @@ namespace solidity::yul { -struct Dialect; +class Dialect; struct AssignedValue; /** diff --git a/libyul/optimiser/Metrics.h b/libyul/optimiser/Metrics.h index 53ff25325996..cdcc28822d94 100644 --- a/libyul/optimiser/Metrics.h +++ b/libyul/optimiser/Metrics.h @@ -27,7 +27,7 @@ namespace solidity::yul { -struct Dialect; +class Dialect; class EVMDialect; /** diff --git a/libyul/optimiser/NameDispenser.h b/libyul/optimiser/NameDispenser.h index 3da50359a764..ec936d39af1b 100644 --- a/libyul/optimiser/NameDispenser.h +++ b/libyul/optimiser/NameDispenser.h @@ -28,7 +28,7 @@ namespace solidity::yul { -struct Dialect; +class Dialect; /** * Optimizer component that can be used to generate new names that diff --git a/libyul/optimiser/NameDisplacer.h b/libyul/optimiser/NameDisplacer.h index 3312e203d7ae..cfe297d4d7a4 100644 --- a/libyul/optimiser/NameDisplacer.h +++ b/libyul/optimiser/NameDisplacer.h @@ -29,7 +29,7 @@ namespace solidity::yul { -struct Dialect; +class Dialect; /** * Optimiser component that renames identifiers to free up certain names. diff --git a/libyul/optimiser/NameSimplifier.h b/libyul/optimiser/NameSimplifier.h index 0ff5077cc694..f3426d60f8f8 100644 --- a/libyul/optimiser/NameSimplifier.h +++ b/libyul/optimiser/NameSimplifier.h @@ -30,7 +30,7 @@ namespace solidity::yul { -struct Dialect; +class Dialect; /** * Pass to "simplify" all identifier names. diff --git a/libyul/optimiser/OptimiserStep.h b/libyul/optimiser/OptimiserStep.h index 89bfcef814d0..7425a1906532 100644 --- a/libyul/optimiser/OptimiserStep.h +++ b/libyul/optimiser/OptimiserStep.h @@ -27,7 +27,7 @@ namespace solidity::yul { -struct Dialect; +class Dialect; struct Block; class NameDispenser; diff --git a/libyul/optimiser/Semantics.h b/libyul/optimiser/Semantics.h index 9fdeb78d031e..9d3c724af2d7 100644 --- a/libyul/optimiser/Semantics.h +++ b/libyul/optimiser/Semantics.h @@ -31,7 +31,7 @@ namespace solidity::yul { -struct Dialect; +class Dialect; /** * Specific AST walker that determines side-effect free-ness and movability of code. diff --git a/libyul/optimiser/SimplificationRules.h b/libyul/optimiser/SimplificationRules.h index 2d48464ca62f..f4b584b99ca4 100644 --- a/libyul/optimiser/SimplificationRules.h +++ b/libyul/optimiser/SimplificationRules.h @@ -40,7 +40,7 @@ namespace solidity::yul { struct AssignedValue; -struct Dialect; +class Dialect; class EVMDialect; class Pattern; diff --git a/libyul/optimiser/StackCompressor.h b/libyul/optimiser/StackCompressor.h index b0b086a7e2b0..d5590006c855 100644 --- a/libyul/optimiser/StackCompressor.h +++ b/libyul/optimiser/StackCompressor.h @@ -29,7 +29,7 @@ namespace solidity::yul { -struct Dialect; +class Dialect; class Object; struct FunctionDefinition; diff --git a/libyul/optimiser/Suite.h b/libyul/optimiser/Suite.h index bd3e1aa054e3..b0c3314089b7 100644 --- a/libyul/optimiser/Suite.h +++ b/libyul/optimiser/Suite.h @@ -36,7 +36,7 @@ namespace solidity::yul { struct AsmAnalysisInfo; -struct Dialect; +class Dialect; class GasMeter; class Object; diff --git a/libyul/optimiser/UnusedAssignEliminator.h b/libyul/optimiser/UnusedAssignEliminator.h index ea2116f0352a..73628c929671 100644 --- a/libyul/optimiser/UnusedAssignEliminator.h +++ b/libyul/optimiser/UnusedAssignEliminator.h @@ -33,7 +33,7 @@ namespace solidity::yul { -struct Dialect; +class Dialect; /** * Optimiser component that removes assignments to variables that are not used diff --git a/libyul/optimiser/UnusedPruner.h b/libyul/optimiser/UnusedPruner.h index 37d26bbb0c85..cd9a7e341d7f 100644 --- a/libyul/optimiser/UnusedPruner.h +++ b/libyul/optimiser/UnusedPruner.h @@ -30,7 +30,7 @@ namespace solidity::yul { -struct Dialect; +class Dialect; struct SideEffects; /** diff --git a/libyul/optimiser/UnusedStoreBase.h b/libyul/optimiser/UnusedStoreBase.h index e5c11c491462..2c51224c0f39 100644 --- a/libyul/optimiser/UnusedStoreBase.h +++ b/libyul/optimiser/UnusedStoreBase.h @@ -31,7 +31,7 @@ namespace solidity::yul { -struct Dialect; +class Dialect; /** * Base class for both UnusedAssignEliminator and UnusedStoreEliminator. diff --git a/libyul/optimiser/UnusedStoreEliminator.h b/libyul/optimiser/UnusedStoreEliminator.h index 6da33a9866c6..45d363dfc9fc 100644 --- a/libyul/optimiser/UnusedStoreEliminator.h +++ b/libyul/optimiser/UnusedStoreEliminator.h @@ -36,7 +36,7 @@ namespace solidity::yul { -struct Dialect; +class Dialect; struct AssignedValue; /** diff --git a/libyul/optimiser/VarNameCleaner.h b/libyul/optimiser/VarNameCleaner.h index 7f8bb842e9e1..47f3aca48db9 100644 --- a/libyul/optimiser/VarNameCleaner.h +++ b/libyul/optimiser/VarNameCleaner.h @@ -31,7 +31,7 @@ namespace solidity::yul { -struct Dialect; +class Dialect; /** * Pass to normalize identifier suffixes. diff --git a/test/libyul/Common.h b/test/libyul/Common.h index 54c61f875a79..e36e81052cc9 100644 --- a/test/libyul/Common.h +++ b/test/libyul/Common.h @@ -38,7 +38,7 @@ namespace solidity::yul struct AsmAnalysisInfo; struct Block; class Object; -struct Dialect; +class Dialect; class AST; } diff --git a/test/libyul/ControlFlowGraphTest.h b/test/libyul/ControlFlowGraphTest.h index e9de50a610c3..953a27b22004 100644 --- a/test/libyul/ControlFlowGraphTest.h +++ b/test/libyul/ControlFlowGraphTest.h @@ -22,7 +22,7 @@ namespace solidity::yul { -struct Dialect; +class Dialect; namespace test { diff --git a/test/libyul/SSAControlFlowGraphTest.h b/test/libyul/SSAControlFlowGraphTest.h index 09c10448695c..13ca2027ab98 100644 --- a/test/libyul/SSAControlFlowGraphTest.h +++ b/test/libyul/SSAControlFlowGraphTest.h @@ -24,7 +24,7 @@ namespace solidity::yul { -struct Dialect; +class Dialect; namespace test { diff --git a/test/libyul/StackLayoutGeneratorTest.h b/test/libyul/StackLayoutGeneratorTest.h index 6116b1df7347..e1c6dc7f912f 100644 --- a/test/libyul/StackLayoutGeneratorTest.h +++ b/test/libyul/StackLayoutGeneratorTest.h @@ -22,7 +22,7 @@ namespace solidity::yul { -struct Dialect; +class Dialect; namespace test { diff --git a/test/libyul/YulOptimizerTest.h b/test/libyul/YulOptimizerTest.h index 2412812888b0..207a4b8ce09e 100644 --- a/test/libyul/YulOptimizerTest.h +++ b/test/libyul/YulOptimizerTest.h @@ -30,7 +30,7 @@ namespace solidity::yul { struct AsmAnalysisInfo; class Object; -struct Dialect; +class Dialect; } namespace solidity::yul::test diff --git a/test/libyul/YulOptimizerTestCommon.h b/test/libyul/YulOptimizerTestCommon.h index b214b80c01c4..bc513e7481b4 100644 --- a/test/libyul/YulOptimizerTestCommon.h +++ b/test/libyul/YulOptimizerTestCommon.h @@ -30,7 +30,7 @@ namespace solidity::yul { struct AsmAnalysisInfo; class Object; -struct Dialect; +class Dialect; class AST; } diff --git a/test/tools/yulInterpreter/Interpreter.h b/test/tools/yulInterpreter/Interpreter.h index 356a190709a7..427a30d9ea08 100644 --- a/test/tools/yulInterpreter/Interpreter.h +++ b/test/tools/yulInterpreter/Interpreter.h @@ -35,7 +35,7 @@ namespace solidity::yul { -struct Dialect; +class Dialect; } namespace solidity::yul::test diff --git a/tools/yulPhaser/Program.h b/tools/yulPhaser/Program.h index be4bf582d665..7ac7f3aad157 100644 --- a/tools/yulPhaser/Program.h +++ b/tools/yulPhaser/Program.h @@ -43,7 +43,7 @@ namespace solidity::yul { struct AsmAnalysisInfo; -struct Dialect; +class Dialect; struct CodeWeights; } From b1ce8a26fee9af9c4396d8531b238f5bcba98d40 Mon Sep 17 00:00:00 2001 From: rodiazet Date: Mon, 9 Dec 2024 11:53:09 +0100 Subject: [PATCH 0621/1022] eof: Fix `library` argument setting in `deployCode` --- libsolidity/codegen/ir/IRGenerator.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/libsolidity/codegen/ir/IRGenerator.cpp b/libsolidity/codegen/ir/IRGenerator.cpp index 48b646d3536c..688ab258a94d 100644 --- a/libsolidity/codegen/ir/IRGenerator.cpp +++ b/libsolidity/codegen/ir/IRGenerator.cpp @@ -1015,6 +1015,7 @@ std::string IRGenerator::deployCode(ContractDefinition const& _contract) if (eof) { + t("library", _contract.isLibrary()); t("auxDataStart", std::to_string(CompilerUtils::generalPurposeMemoryStart)); solAssert(m_context.reservedMemorySize() <= 0xFFFF, "Reserved memory size exceeded maximum allowed EOF data section size."); t("auxDataSize", std::to_string(m_context.reservedMemorySize())); From a26b2812aa231e63be1573b07d2a38f64c8878e1 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Fri, 6 Dec 2024 08:36:50 +0100 Subject: [PATCH 0622/1022] Add test::CommonOptions::evmDialect method --- test/Common.cpp | 16 ++++++++++++++-- test/Common.h | 6 ++++++ test/libsolidity/MemoryGuardTest.cpp | 2 +- test/libyul/ControlFlowSideEffectsTest.cpp | 8 +++----- test/libyul/EVMCodeTransformTest.cpp | 6 +++--- test/libyul/FunctionSideEffects.cpp | 8 +++----- test/libyul/StackShufflingTest.cpp | 6 ++---- test/libyul/YulInterpreterTest.cpp | 10 +++++----- 8 files changed, 37 insertions(+), 25 deletions(-) diff --git a/test/Common.cpp b/test/Common.cpp index bab95c457b6a..43f73d4d71d4 100644 --- a/test/Common.cpp +++ b/test/Common.cpp @@ -16,19 +16,25 @@ */ // SPDX-License-Identifier: GPL-3.0 -#include -#include #include + #include #include +#include + #include #include + #include #include #include + #include +#include +#include + namespace fs = boost::filesystem; namespace po = boost::program_options; @@ -260,6 +266,12 @@ langutil::EVMVersion CommonOptions::evmVersion() const return langutil::EVMVersion(); } +yul::EVMDialect const& CommonOptions::evmDialect() const +{ + return yul::EVMDialect::strictAssemblyForEVMObjects(evmVersion(), eofVersion()); +} + + CommonOptions const& CommonOptions::get() { if (!m_singleton) diff --git a/test/Common.h b/test/Common.h index 409d6f6960e1..c3d21d258295 100644 --- a/test/Common.h +++ b/test/Common.h @@ -29,6 +29,11 @@ #include #include +namespace solidity::yul +{ +class EVMDialect; +} + namespace solidity::test { @@ -66,6 +71,7 @@ struct CommonOptions langutil::EVMVersion evmVersion() const; std::optional eofVersion() const { return m_eofVersion; } + yul::EVMDialect const& evmDialect() const; virtual void addOptions(); // @returns true if the program should continue, false if it should exit immediately without diff --git a/test/libsolidity/MemoryGuardTest.cpp b/test/libsolidity/MemoryGuardTest.cpp index b797564b7234..9826f4b19468 100644 --- a/test/libsolidity/MemoryGuardTest.cpp +++ b/test/libsolidity/MemoryGuardTest.cpp @@ -59,7 +59,7 @@ TestCase::TestResult MemoryGuardTest::run(std::ostream& _stream, std::string con m_obtainedResult.clear(); for (std::string contractName: compiler().contractNames()) { - auto const& dialect = EVMDialect::strictAssemblyForEVMObjects(CommonOptions::get().evmVersion(), CommonOptions::get().eofVersion()); + auto const& dialect = CommonOptions::get().evmDialect(); ErrorList errors; std::optional const& ir = compiler().yulIR(contractName); solAssert(ir); diff --git a/test/libyul/ControlFlowSideEffectsTest.cpp b/test/libyul/ControlFlowSideEffectsTest.cpp index 3dc576c8ed20..50c546e36c5d 100644 --- a/test/libyul/ControlFlowSideEffectsTest.cpp +++ b/test/libyul/ControlFlowSideEffectsTest.cpp @@ -28,6 +28,7 @@ #include using namespace solidity; +using namespace solidity::test; using namespace solidity::yul; using namespace solidity::yul::test; using namespace solidity::frontend::test; @@ -56,12 +57,9 @@ ControlFlowSideEffectsTest::ControlFlowSideEffectsTest(std::string const& _filen TestCase::TestResult ControlFlowSideEffectsTest::run(std::ostream& _stream, std::string const& _linePrefix, bool _formatted) { - auto const& dialect = EVMDialect::strictAssemblyForEVMObjects( - solidity::test::CommonOptions::get().evmVersion(), - solidity::test::CommonOptions::get().eofVersion() - ); + auto const& dialect = CommonOptions::get().evmDialect(); Object obj; - auto parsingResult = yul::test::parse(m_source); + auto parsingResult = parse(m_source); obj.setCode(parsingResult.first, parsingResult.second); if (!obj.hasCode()) BOOST_THROW_EXCEPTION(std::runtime_error("Parsing input failed.")); diff --git a/test/libyul/EVMCodeTransformTest.cpp b/test/libyul/EVMCodeTransformTest.cpp index 75d86136e9e0..da2eaad0eca0 100644 --- a/test/libyul/EVMCodeTransformTest.cpp +++ b/test/libyul/EVMCodeTransformTest.cpp @@ -32,6 +32,7 @@ #include using namespace solidity; +using namespace solidity::test; using namespace solidity::util; using namespace solidity::langutil; using namespace solidity::yul; @@ -67,13 +68,12 @@ TestCase::TestResult EVMCodeTransformTest::run(std::ostream& _stream, std::strin return TestResult::FatalError; } - evmasm::Assembly assembly{solidity::test::CommonOptions::get().evmVersion(), false, std::nullopt, {}}; + evmasm::Assembly assembly{CommonOptions::get().evmVersion(), false, std::nullopt, {}}; EthAssemblyAdapter adapter(assembly); EVMObjectCompiler::compile( *stack.parserResult(), adapter, - EVMDialect::strictAssemblyForEVMObjects(solidity::test::CommonOptions::get().evmVersion(), - solidity::test::CommonOptions::get().eofVersion()), + CommonOptions::get().evmDialect(), m_stackOpt, std::nullopt ); diff --git a/test/libyul/FunctionSideEffects.cpp b/test/libyul/FunctionSideEffects.cpp index 204150ad837e..d19d87844fcf 100644 --- a/test/libyul/FunctionSideEffects.cpp +++ b/test/libyul/FunctionSideEffects.cpp @@ -35,6 +35,7 @@ using namespace solidity; +using namespace solidity::test; using namespace solidity::util; using namespace solidity::langutil; using namespace solidity::yul; @@ -83,12 +84,9 @@ FunctionSideEffects::FunctionSideEffects(std::string const& _filename): TestCase::TestResult FunctionSideEffects::run(std::ostream& _stream, std::string const& _linePrefix, bool _formatted) { - auto const& dialect = EVMDialect::strictAssemblyForEVMObjects( - solidity::test::CommonOptions::get().evmVersion(), - solidity::test::CommonOptions::get().eofVersion() - ); + auto const& dialect = CommonOptions::get().evmDialect(); Object obj; - auto parsingResult = yul::test::parse(m_source); + auto parsingResult = parse(m_source); obj.setCode(parsingResult.first, parsingResult.second); if (!obj.hasCode()) BOOST_THROW_EXCEPTION(std::runtime_error("Parsing input failed.")); diff --git a/test/libyul/StackShufflingTest.cpp b/test/libyul/StackShufflingTest.cpp index baf8e0c8e543..258bc9204aa5 100644 --- a/test/libyul/StackShufflingTest.cpp +++ b/test/libyul/StackShufflingTest.cpp @@ -25,6 +25,7 @@ #include #include +using namespace solidity::test; using namespace solidity::util; using namespace solidity::langutil; using namespace solidity::yul; @@ -141,10 +142,7 @@ StackShufflingTest::StackShufflingTest(std::string const& _filename): TestCase::TestResult StackShufflingTest::run(std::ostream& _stream, std::string const& _linePrefix, bool _formatted) { - auto const& dialect = EVMDialect::strictAssemblyForEVMObjects( - solidity::test::CommonOptions::get().evmVersion(), - solidity::test::CommonOptions::get().eofVersion() - ); + auto const& dialect = CommonOptions::get().evmDialect(); if (!parse(m_source)) { AnsiColorized(_stream, _formatted, {formatting::BOLD, formatting::RED}) << _linePrefix << "Error parsing source." << std::endl; diff --git a/test/libyul/YulInterpreterTest.cpp b/test/libyul/YulInterpreterTest.cpp index 484a7a241d81..25b348dfb2d9 100644 --- a/test/libyul/YulInterpreterTest.cpp +++ b/test/libyul/YulInterpreterTest.cpp @@ -39,6 +39,7 @@ #include using namespace solidity; +using namespace solidity::test; using namespace solidity::util; using namespace solidity::langutil; using namespace solidity::yul; @@ -67,10 +68,10 @@ TestCase::TestResult YulInterpreterTest::run(std::ostream& _stream, std::string bool YulInterpreterTest::parse(std::ostream& _stream, std::string const& _linePrefix, bool const _formatted) { YulStack stack( - solidity::test::CommonOptions::get().evmVersion(), - solidity::test::CommonOptions::get().eofVersion(), + CommonOptions::get().evmVersion(), + CommonOptions::get().eofVersion(), YulStack::Language::StrictAssembly, - solidity::frontend::OptimiserSettings::none(), + OptimiserSettings::none(), DebugInfoSelection::All() ); if (stack.parseAndAnalyze("", m_source)) @@ -98,8 +99,7 @@ std::string YulInterpreterTest::interpret() { Interpreter::run( state, - EVMDialect::strictAssemblyForEVMObjects(solidity::test::CommonOptions::get().evmVersion(), - solidity::test::CommonOptions::get().eofVersion()), + CommonOptions::get().evmDialect(), m_ast->root(), /*disableExternalCalls=*/ !m_simulateExternalCallsToSelf, /*disableMemoryTracing=*/ false From 2ae6807f49d180d2493637d59ca8e723eca2b3d8 Mon Sep 17 00:00:00 2001 From: rodiazet Date: Mon, 9 Dec 2024 11:23:43 +0100 Subject: [PATCH 0623/1022] eof: Introduce new instruction set for `ext*call` --- libevmasm/Instruction.cpp | 6 +++ libevmasm/Instruction.h | 6 +++ libevmasm/SemanticInformation.cpp | 38 +++++++++++++++++++ liblangutil/EVMVersion.cpp | 3 ++ libyul/AsmAnalysis.cpp | 15 ++++++++ libyul/backends/evm/EVMDialect.cpp | 15 +++++++- .../EVMInstructionInterpreter.cpp | 3 ++ 7 files changed, 85 insertions(+), 1 deletion(-) diff --git a/libevmasm/Instruction.cpp b/libevmasm/Instruction.cpp index 82ed73cc994e..649a6c863486 100644 --- a/libevmasm/Instruction.cpp +++ b/libevmasm/Instruction.cpp @@ -182,6 +182,9 @@ std::map const solidity::evmasm::c_instructions = { "STATICCALL", Instruction::STATICCALL }, { "RETURN", Instruction::RETURN }, { "DELEGATECALL", Instruction::DELEGATECALL }, + { "EXTCALL", Instruction::EXTCALL }, + { "EXTSTATICCALL", Instruction::EXTSTATICCALL }, + { "EXTDELEGATECALL", Instruction::EXTDELEGATECALL }, { "CREATE2", Instruction::CREATE2 }, { "REVERT", Instruction::REVERT }, { "INVALID", Instruction::INVALID }, @@ -344,6 +347,9 @@ static std::map const c_instructionInfo = {Instruction::RETURN, {"RETURN", 0, 2, 0, true, Tier::Zero}}, {Instruction::DELEGATECALL, {"DELEGATECALL", 0, 6, 1, true, Tier::Special}}, {Instruction::STATICCALL, {"STATICCALL", 0, 6, 1, true, Tier::Special}}, + {Instruction::EXTCALL, {"EXTCALL", 0, 4, 1, true, Tier::Special}}, + {Instruction::EXTDELEGATECALL,{"EXTDELEGATECALL", 0, 3, 1, true, Tier::Special}}, + {Instruction::EXTSTATICCALL, {"EXTSTATICCALL", 0, 3, 1, true, Tier::Special}}, {Instruction::CREATE2, {"CREATE2", 0, 4, 1, true, Tier::Special}}, {Instruction::REVERT, {"REVERT", 0, 2, 0, true, Tier::Zero}}, {Instruction::INVALID, {"INVALID", 0, 0, 0, true, Tier::Zero}}, diff --git a/libevmasm/Instruction.h b/libevmasm/Instruction.h index 351a6981c070..a1b9af364a0d 100644 --- a/libevmasm/Instruction.h +++ b/libevmasm/Instruction.h @@ -198,7 +198,10 @@ enum class Instruction: uint8_t RETURN, ///< halt execution returning output data DELEGATECALL, ///< like CALLCODE but keeps caller's value and sender CREATE2 = 0xf5, ///< create new account with associated code at address `sha3(0xff + sender + salt + init code) % 2**160` + EXTCALL = 0xf8, ///< EOF message-call into an account + EXTDELEGATECALL = 0xf9, ///< EOF delegate call STATICCALL = 0xfa, ///< like CALL but disallow state modifications + EXTSTATICCALL = 0xfb, ///< like EXTCALL but disallow state modifications REVERT = 0xfd, ///< halt execution, revert state and return output data INVALID = 0xfe, ///< invalid instruction for expressing runtime errors (e.g., division-by-zero) @@ -214,6 +217,9 @@ constexpr bool isCallInstruction(Instruction _inst) noexcept case Instruction::CALLCODE: case Instruction::DELEGATECALL: case Instruction::STATICCALL: + case Instruction::EXTCALL: + case Instruction::EXTSTATICCALL: + case Instruction::EXTDELEGATECALL: return true; default: return false; diff --git a/libevmasm/SemanticInformation.cpp b/libevmasm/SemanticInformation.cpp index c27945b82e51..a9672efa53b0 100644 --- a/libevmasm/SemanticInformation.cpp +++ b/libevmasm/SemanticInformation.cpp @@ -169,6 +169,26 @@ std::vector SemanticInformation::readWriteOperat }); return operations; } + case Instruction::EXTCALL: + case Instruction::EXTSTATICCALL: + case Instruction::EXTDELEGATECALL: + { + size_t paramCount = static_cast(instructionInfo(_instruction, langutil::EVMVersion()).args); + size_t const memoryStartParam = _instruction == Instruction::EXTCALL ? paramCount - 3 : paramCount - 2; + size_t const memoryLengthParam = _instruction == Instruction::EXTCALL ? paramCount - 2 : paramCount - 1; + std::vector operations{ + Operation{Location::Memory, Effect::Read, memoryStartParam, memoryLengthParam, {}}, + Operation{Location::Storage, Effect::Read, {}, {}, {}}, + Operation{Location::TransientStorage, Effect::Read, {}, {}, {}} + }; + if (_instruction == Instruction::EXTDELEGATECALL) + { + operations.emplace_back(Operation{Location::Storage, Effect::Write, {}, {}, {}}); + operations.emplace_back(Operation{Location::TransientStorage, Effect::Write, {}, {}, {}}); + } + + return operations; + } case Instruction::CREATE: case Instruction::CREATE2: return std::vector{ @@ -380,6 +400,9 @@ bool SemanticInformation::isDeterministic(AssemblyItem const& _item) case Instruction::CALLCODE: case Instruction::DELEGATECALL: case Instruction::STATICCALL: + case Instruction::EXTCALL: + case Instruction::EXTDELEGATECALL: + case Instruction::EXTSTATICCALL: case Instruction::CREATE: case Instruction::CREATE2: case Instruction::GAS: @@ -475,6 +498,9 @@ SemanticInformation::Effect SemanticInformation::memory(Instruction _instruction case Instruction::LOG4: case Instruction::EOFCREATE: case Instruction::RETURNCONTRACT: + case Instruction::EXTCALL: + case Instruction::EXTDELEGATECALL: + case Instruction::EXTSTATICCALL: return SemanticInformation::Read; default: @@ -514,10 +540,13 @@ SemanticInformation::Effect SemanticInformation::storage(Instruction _instructio case Instruction::SSTORE: case Instruction::EOFCREATE: case Instruction::RETURNCONTRACT: + case Instruction::EXTCALL: + case Instruction::EXTDELEGATECALL: return SemanticInformation::Write; case Instruction::SLOAD: case Instruction::STATICCALL: + case Instruction::EXTSTATICCALL: return SemanticInformation::Read; default: @@ -537,10 +566,13 @@ SemanticInformation::Effect SemanticInformation::transientStorage(Instruction _i case Instruction::TSTORE: case Instruction::EOFCREATE: case Instruction::RETURNCONTRACT: + case Instruction::EXTCALL: + case Instruction::EXTDELEGATECALL: return SemanticInformation::Write; case Instruction::TLOAD: case Instruction::STATICCALL: + case Instruction::EXTSTATICCALL: return SemanticInformation::Read; default: @@ -559,7 +591,10 @@ SemanticInformation::Effect SemanticInformation::otherState(Instruction _instruc case Instruction::CREATE2: case Instruction::EOFCREATE: case Instruction::RETURNCONTRACT: + case Instruction::EXTCALL: + case Instruction::EXTDELEGATECALL: case Instruction::SELFDESTRUCT: + case Instruction::EXTSTATICCALL: case Instruction::STATICCALL: // because it can affect returndatasize // Strictly speaking, log0, .., log4 writes to the state, but the EVM cannot read it, so they // are just marked as having 'other side effects.' @@ -606,6 +641,7 @@ bool SemanticInformation::invalidInPureFunctions(Instruction _instruction) case Instruction::NUMBER: case Instruction::PREVRANDAO: case Instruction::GASLIMIT: + case Instruction::EXTSTATICCALL: case Instruction::STATICCALL: case Instruction::SLOAD: case Instruction::TLOAD: @@ -635,6 +671,8 @@ bool SemanticInformation::invalidInViewFunctions(Instruction _instruction) case Instruction::CALL: case Instruction::CALLCODE: case Instruction::DELEGATECALL: + case Instruction::EXTCALL: + case Instruction::EXTDELEGATECALL: // According to EOF spec https://eips.ethereum.org/EIPS/eip-7620#eofcreate case Instruction::EOFCREATE: // According to EOF spec https://eips.ethereum.org/EIPS/eip-7620#returncontract diff --git a/liblangutil/EVMVersion.cpp b/liblangutil/EVMVersion.cpp index 26364f2af2a2..6f7ac91397d9 100644 --- a/liblangutil/EVMVersion.cpp +++ b/liblangutil/EVMVersion.cpp @@ -85,6 +85,9 @@ bool EVMVersion::hasOpcode(Instruction _opcode, std::optional _eofVersi case Instruction::CALLF: case Instruction::JUMPF: case Instruction::RETF: + case Instruction::EXTCALL: + case Instruction::EXTSTATICCALL: + case Instruction::EXTDELEGATECALL: return _eofVersion.has_value(); default: return true; diff --git a/libyul/AsmAnalysis.cpp b/libyul/AsmAnalysis.cpp index 55f5af4cf3ab..fd826eaecd18 100644 --- a/libyul/AsmAnalysis.cpp +++ b/libyul/AsmAnalysis.cpp @@ -773,6 +773,21 @@ bool AsmAnalyzer::validateInstructions(evmasm::Instruction _instr, SourceLocatio "PC instruction is a low-level EVM feature. " "Because of that PC is disallowed in strict assembly." ); + else if (!m_eofVersion.has_value() && ( + _instr == evmasm::Instruction::EXTCALL || + _instr == evmasm::Instruction::EXTDELEGATECALL || + _instr == evmasm::Instruction::EXTSTATICCALL + )) + { + m_errorReporter.typeError( + 4328_error, + _location, + fmt::format( + "The \"{}\" instruction is only available on EOF.", + fmt::arg("instruction", boost::to_lower_copy(instructionInfo(_instr, m_evmVersion).name)) + ) + ); + } else if (m_eofVersion.has_value() && ( _instr == evmasm::Instruction::CALL || _instr == evmasm::Instruction::CALLCODE || diff --git a/libyul/backends/evm/EVMDialect.cpp b/libyul/backends/evm/EVMDialect.cpp index c73a9a79483f..bb7a96953034 100644 --- a/libyul/backends/evm/EVMDialect.cpp +++ b/libyul/backends/evm/EVMDialect.cpp @@ -153,6 +153,18 @@ std::set> createReservedIdentifiers(langutil::EVMVersio (_instr == evmasm::Instruction::TSTORE || _instr == evmasm::Instruction::TLOAD); }; + auto eofIdentifiersException = [&](evmasm::Instruction _instr) -> bool + { + solAssert(!_eofVersion.has_value() || _evmVersion >= langutil::EVMVersion::prague()); + return + !_eofVersion.has_value() && + ( + _instr == evmasm::Instruction::EXTCALL || + _instr == evmasm::Instruction::EXTSTATICCALL || + _instr == evmasm::Instruction::EXTDELEGATECALL + ); + }; + std::set> reserved; for (auto const& instr: evmasm::c_instructions) { @@ -163,7 +175,8 @@ std::set> createReservedIdentifiers(langutil::EVMVersio !blobHashException(instr.second) && !blobBaseFeeException(instr.second) && !mcopyException(instr.second) && - !transientStorageException(instr.second) + !transientStorageException(instr.second) && + !eofIdentifiersException(instr.second) ) reserved.emplace(name); } diff --git a/test/tools/yulInterpreter/EVMInstructionInterpreter.cpp b/test/tools/yulInterpreter/EVMInstructionInterpreter.cpp index 92ac56d6919f..94a6c3b1ee3f 100644 --- a/test/tools/yulInterpreter/EVMInstructionInterpreter.cpp +++ b/test/tools/yulInterpreter/EVMInstructionInterpreter.cpp @@ -495,6 +495,9 @@ u256 EVMInstructionInterpreter::eval( case Instruction::RETURNCONTRACT: case Instruction::RJUMP: case Instruction::RJUMPI: + case Instruction::EXTCALL: + case Instruction::EXTSTATICCALL: + case Instruction::EXTDELEGATECALL: solUnimplemented("EOF not yet supported by Yul interpreter."); } From f495f676ac6749e219f40eca594f1c2f6f63a799 Mon Sep 17 00:00:00 2001 From: rodiazet Date: Mon, 9 Dec 2024 11:23:43 +0100 Subject: [PATCH 0624/1022] eof: Use EOF `ext*call` in yul generator for statements. --- .../codegen/ir/IRGeneratorForStatements.cpp | 72 ++++++++++++++----- 1 file changed, 55 insertions(+), 17 deletions(-) diff --git a/libsolidity/codegen/ir/IRGeneratorForStatements.cpp b/libsolidity/codegen/ir/IRGeneratorForStatements.cpp index 9b2e0ea7723e..babe43357fbb 100644 --- a/libsolidity/codegen/ir/IRGeneratorForStatements.cpp +++ b/libsolidity/codegen/ir/IRGeneratorForStatements.cpp @@ -1622,11 +1622,16 @@ void IRGeneratorForStatements::endVisit(FunctionCall const& _functionCall) Whiskers templ(R"( let := 0 if iszero() { := } - let := call(,
, , 0, 0, 0, 0) + + let := iszero(extcall(
, 0, 0, )) + + let := call(,
, , 0, 0, 0, 0) + if iszero() { () } )"); + templ("eof", m_context.eofVersion().has_value()); templ("gas", m_context.newYulVariable()); templ("callStipend", toString(evmasm::GasCosts::callStipend)); templ("address", address); @@ -1669,17 +1674,30 @@ void IRGeneratorForStatements::endVisit(FunctionCall const& _functionCall) mstore(0, 0) - let := (,
, 0, , sub(, ), 0, 32) + + // EOF always uses extstaticcall + let := iszero(extstaticcall(
, , sub(, ))) + + let := (,
, 0, , sub(, ), 0, 32) + if iszero() { () } + + if eq(returndatasize(), 32) { returndatacopy(0, 0, 32) } + let := (mload(0)) )"); - templ("call", m_context.evmVersion().hasStaticCall() ? "staticcall" : "call"); - templ("isCall", !m_context.evmVersion().hasStaticCall()); + auto const eof = m_context.eofVersion().has_value(); + if (!eof) + { + templ("call", m_context.evmVersion().hasStaticCall() ? "staticcall" : "call"); + templ("isCall", !m_context.evmVersion().hasStaticCall()); + } templ("shl", m_utils.shiftLeftFunction(offset * 8)); templ("allocateUnbounded", m_utils.allocateUnboundedFunction()); templ("pos", m_context.newYulVariable()); templ("end", m_context.newYulVariable()); templ("isECRecover", FunctionType::Kind::ECRecover == functionType->kind()); + templ("eof", eof); if (FunctionType::Kind::ECRecover == functionType->kind()) templ("encodeArgs", m_context.abiFunctions().tupleEncoder(argumentTypes, parameterTypes)); else @@ -2630,7 +2648,6 @@ void IRGeneratorForStatements::appendExternalFunctionCall( argumentStrings += IRVariable(*arg).stackSlots(); } - if (!m_context.evmVersion().canOverchargeGasForCall()) { // Touch the end of the output area so that we do not pay for memory resize during the call @@ -2642,7 +2659,7 @@ void IRGeneratorForStatements::appendExternalFunctionCall( } // NOTE: When the expected size of returndata is static, we pass that in to the call opcode and it gets copied automatically. - // When it's dynamic, we get zero from estimatedReturnSize() instead and then we need an explicit returndatacopy(). + // When it's dynamic, we get zero from estimatedReturnSize() instead and then we need an explicit returndatacopy(). Whiskers templ(R"( if iszero(extcodesize(
)) { () } @@ -2652,7 +2669,11 @@ void IRGeneratorForStatements::appendExternalFunctionCall( mstore(, ()) let := (add(, 4) ) - let := (,
, , , sub(, ), , ) + + let := iszero((
, , sub(, ) , )) + + let := (,
, , , sub(, ), , ) + if iszero() { () } @@ -2667,6 +2688,9 @@ void IRGeneratorForStatements::appendExternalFunctionCall( if gt(, returndatasize()) { := returndatasize() } + + returndatacopy(, 0, ) + @@ -2678,6 +2702,9 @@ void IRGeneratorForStatements::appendExternalFunctionCall( } )"); templ("revertNoCode", m_utils.revertReasonIfDebugFunction("Target contract does not contain code")); + auto const eof = m_context.eofVersion().has_value(); + solAssert(!eof || !funType.gasSet()); + templ("eof", eof); // 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. @@ -2685,9 +2712,12 @@ void IRGeneratorForStatements::appendExternalFunctionCall( for (auto const& t: returnInfo.returnTypes) encodedHeadSize += t->decodingType()->calldataHeadSize(); bool const checkExtcodesize = - encodedHeadSize == 0 || - !m_context.evmVersion().supportsReturndata() || - m_context.revertStrings() >= RevertStrings::Debug; + !eof && + ( + encodedHeadSize == 0 || + !m_context.evmVersion().supportsReturndata() || + m_context.revertStrings() >= RevertStrings::Debug + ); templ("checkExtcodesize", checkExtcodesize); templ("pos", m_context.newYulVariable()); @@ -2748,11 +2778,11 @@ void IRGeneratorForStatements::appendExternalFunctionCall( } // Order is important here, STATICCALL might overlap with DELEGATECALL. if (isDelegateCall) - templ("call", "delegatecall"); + templ("call", eof ? "extdelegatecall" : "delegatecall"); else if (useStaticCall) - templ("call", "staticcall"); + templ("call", eof ? "extstaticcall" : "staticcall"); else - templ("call", "call"); + templ("call", eof ? "extcall" : "call"); templ("forwardingRevert", m_utils.forwardingRevertFunction()); @@ -2791,13 +2821,20 @@ void IRGeneratorForStatements::appendBareCall( let := mload() - let := (,
, , , , 0, 0) + + let := iszero((
, , , )) + + let := (,
, , , , 0, 0) + + let := () )"); templ("allocateUnbounded", m_utils.allocateUnboundedFunction()); templ("pos", m_context.newYulVariable()); templ("length", m_context.newYulVariable()); + auto const eof = m_context.eofVersion().has_value(); + templ("eof", eof); templ("arg", IRVariable(*_arguments.front()).commaSeparatedList()); Type const& argType = type(*_arguments.front()); @@ -2819,18 +2856,19 @@ void IRGeneratorForStatements::appendBareCall( if (funKind == FunctionType::Kind::BareCall) { templ("value", funType.valueSet() ? IRVariable(_functionCall.expression()).part("value").name() : "0"); - templ("call", "call"); + templ("call", eof ? "extcall" : "call"); } else { solAssert(!funType.valueSet(), "Value set for delegatecall or staticcall."); templ("value", ""); if (funKind == FunctionType::Kind::BareStaticCall) - templ("call", "staticcall"); + templ("call", eof ? "extstaticcall" : "staticcall"); else - templ("call", "delegatecall"); + templ("call", eof ? "extdelegatecall" : "delegatecall"); } + solAssert(!eof || !funType.gasSet()); if (funType.gasSet()) templ("gas", IRVariable(_functionCall.expression()).part("gas").name()); else if (m_context.evmVersion().canOverchargeGasForCall()) From 6520bfd55639c2ab76e922aa1d51813fa0f0f552 Mon Sep 17 00:00:00 2001 From: rodiazet Date: Mon, 9 Dec 2024 11:23:43 +0100 Subject: [PATCH 0625/1022] eof: Add unit tests in `yulSyntaxTests` and `objectCompiler` --- test/libyul/objectCompiler/eof/extcall.yul | 52 +++++++++++++++++++ .../eof/eof_identifiers_in_legacy.yul | 10 ++++ .../eof/extcall_function_in_eof.yul | 11 ++++ test/libyul/yulSyntaxTests/eof/extcalls.yul | 11 ++++ .../eof/extcalls_invalid_in_legacy.yul | 17 ++++++ .../eof/extdelegatecall_function_in_eof.yul | 11 ++++ .../eof/extstaticcall_function_in_eof.yul | 11 ++++ 7 files changed, 123 insertions(+) create mode 100644 test/libyul/objectCompiler/eof/extcall.yul create mode 100644 test/libyul/yulSyntaxTests/eof/eof_identifiers_in_legacy.yul create mode 100644 test/libyul/yulSyntaxTests/eof/extcall_function_in_eof.yul create mode 100644 test/libyul/yulSyntaxTests/eof/extcalls.yul create mode 100644 test/libyul/yulSyntaxTests/eof/extcalls_invalid_in_legacy.yul create mode 100644 test/libyul/yulSyntaxTests/eof/extdelegatecall_function_in_eof.yul create mode 100644 test/libyul/yulSyntaxTests/eof/extstaticcall_function_in_eof.yul diff --git a/test/libyul/objectCompiler/eof/extcall.yul b/test/libyul/objectCompiler/eof/extcall.yul new file mode 100644 index 000000000000..d0322b1a9e2e --- /dev/null +++ b/test/libyul/objectCompiler/eof/extcall.yul @@ -0,0 +1,52 @@ +object "a" { + code { + sstore(0, extcall(address(), 0, 0, 10)) + sstore(1, extdelegatecall(address(), 0, 0)) + sstore(2, extstaticcall(address(), 0, 0)) + } +} + +// ==== +// bytecodeFormat: >=EOFv1 +// ---- +// Assembly: +// /* "source":81:83 */ +// 0x0a +// /* "source":78:79 */ +// 0x00 +// /* "source":64:73 */ +// dup1 +// address +// /* "source":56:84 */ +// extcall +// /* "source":53:54 */ +// 0x00 +// /* "source":46:85 */ +// sstore +// /* "source":138:139 */ +// 0x00 +// /* "source":124:133 */ +// dup1 +// address +// /* "source":108:140 */ +// extdelegatecall +// /* "source":105:106 */ +// 0x01 +// /* "source":98:141 */ +// sstore +// /* "source":192:193 */ +// 0x00 +// /* "source":178:187 */ +// dup1 +// address +// /* "source":164:194 */ +// extstaticcall +// /* "source":161:162 */ +// 0x02 +// /* "source":154:195 */ +// sstore +// /* "source":22:211 */ +// stop +// Bytecode: ef000101000402000100170400000000800004600a5f8030f85f555f8030f96001555f8030fb60025500 +// Opcodes: 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP OR DIV STOP STOP STOP STOP DUP1 STOP DIV PUSH1 0xA PUSH0 DUP1 ADDRESS EXTCALL PUSH0 SSTORE PUSH0 DUP1 ADDRESS EXTDELEGATECALL PUSH1 0x1 SSTORE PUSH0 DUP1 ADDRESS EXTSTATICCALL PUSH1 0x2 SSTORE STOP +// SourceMappings: 81:2:0:-:0;78:1;64:9;;56:28;53:1;46:39;138:1;124:9;;108:32;105:1;98:43;192:1;178:9;;164:30;161:1;154:41;22:189 diff --git a/test/libyul/yulSyntaxTests/eof/eof_identifiers_in_legacy.yul b/test/libyul/yulSyntaxTests/eof/eof_identifiers_in_legacy.yul new file mode 100644 index 000000000000..d9d7fde15997 --- /dev/null +++ b/test/libyul/yulSyntaxTests/eof/eof_identifiers_in_legacy.yul @@ -0,0 +1,10 @@ +object "a" { + code { + function extcall() {} + function extstaticcall() {} + function extdelegatecall() {} + } +} + +// ==== +// bytecodeFormat: legacy \ No newline at end of file diff --git a/test/libyul/yulSyntaxTests/eof/extcall_function_in_eof.yul b/test/libyul/yulSyntaxTests/eof/extcall_function_in_eof.yul new file mode 100644 index 000000000000..1e503ca94a65 --- /dev/null +++ b/test/libyul/yulSyntaxTests/eof/extcall_function_in_eof.yul @@ -0,0 +1,11 @@ +object "a" { + code { + function extcall() {} + } +} + +// ==== +// bytecodeFormat: >=EOFv1 +// ---- +// ParserError 5568: (41-48): Cannot use builtin function name "extcall" as identifier name. +// ParserError 8143: (41-48): Expected keyword "data" or "object" or "}". diff --git a/test/libyul/yulSyntaxTests/eof/extcalls.yul b/test/libyul/yulSyntaxTests/eof/extcalls.yul new file mode 100644 index 000000000000..a8352c254d8e --- /dev/null +++ b/test/libyul/yulSyntaxTests/eof/extcalls.yul @@ -0,0 +1,11 @@ +object "a" { + code { + pop(extcall(address(), 0, 0, 0)) + pop(extdelegatecall(address(), 0, 0)) + pop(extstaticcall(address(), 0, 0)) + } +} + +// ==== +// bytecodeFormat: >=EOFv1 +// ---- diff --git a/test/libyul/yulSyntaxTests/eof/extcalls_invalid_in_legacy.yul b/test/libyul/yulSyntaxTests/eof/extcalls_invalid_in_legacy.yul new file mode 100644 index 000000000000..6aec96aa2e3c --- /dev/null +++ b/test/libyul/yulSyntaxTests/eof/extcalls_invalid_in_legacy.yul @@ -0,0 +1,17 @@ +object "a" { + code { + pop(extcall(address(), 0, 0, 0)) + pop(extdelegatecall(address(), 0, 0)) + pop(extstaticcall(address(), 0, 0)) + } +} + +// ==== +// bytecodeFormat: legacy +// ---- +// TypeError 4328: (36-43): The "extcall" instruction is only available on EOF. +// TypeError 3950: (36-63): Expected expression to evaluate to one value, but got 0 values instead. +// TypeError 4328: (77-92): The "extdelegatecall" instruction is only available on EOF. +// TypeError 3950: (77-109): Expected expression to evaluate to one value, but got 0 values instead. +// TypeError 4328: (123-136): The "extstaticcall" instruction is only available on EOF. +// TypeError 3950: (123-153): Expected expression to evaluate to one value, but got 0 values instead. diff --git a/test/libyul/yulSyntaxTests/eof/extdelegatecall_function_in_eof.yul b/test/libyul/yulSyntaxTests/eof/extdelegatecall_function_in_eof.yul new file mode 100644 index 000000000000..0515c8d265b4 --- /dev/null +++ b/test/libyul/yulSyntaxTests/eof/extdelegatecall_function_in_eof.yul @@ -0,0 +1,11 @@ +object "a" { + code { + function extdelegatecall() {} + } +} + +// ==== +// bytecodeFormat: >=EOFv1 +// ---- +// ParserError 5568: (41-56): Cannot use builtin function name "extdelegatecall" as identifier name. +// ParserError 8143: (41-56): Expected keyword "data" or "object" or "}". diff --git a/test/libyul/yulSyntaxTests/eof/extstaticcall_function_in_eof.yul b/test/libyul/yulSyntaxTests/eof/extstaticcall_function_in_eof.yul new file mode 100644 index 000000000000..fbfb5074b6fd --- /dev/null +++ b/test/libyul/yulSyntaxTests/eof/extstaticcall_function_in_eof.yul @@ -0,0 +1,11 @@ +object "a" { + code { + function extstaticcall() {} + } +} + +// ==== +// bytecodeFormat: >=EOFv1 +// ---- +// ParserError 5568: (41-54): Cannot use builtin function name "extstaticcall" as identifier name. +// ParserError 8143: (41-54): Expected keyword "data" or "object" or "}". From 6263f56071e16d2edce233e7ff349d6ae7303e32 Mon Sep 17 00:00:00 2001 From: rodiazet Date: Mon, 9 Dec 2024 11:50:59 +0100 Subject: [PATCH 0626/1022] eof: Enable one semantic test to sanity check. --- test/libsolidity/semanticTests/ecrecover/ecrecover.sol | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/libsolidity/semanticTests/ecrecover/ecrecover.sol b/test/libsolidity/semanticTests/ecrecover/ecrecover.sol index 1beb451de8b0..41b0bf86590a 100644 --- a/test/libsolidity/semanticTests/ecrecover/ecrecover.sol +++ b/test/libsolidity/semanticTests/ecrecover/ecrecover.sol @@ -3,6 +3,8 @@ contract test { return ecrecover(h, v, r, s); } } +// ==== +// bytecodeFormat: legacy,>=EOFv1 // ---- // a(bytes32,uint8,bytes32,bytes32): // 0x18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c, From 4f6ebd2605ea12489ef395df7805c2b8e3ff0856 Mon Sep 17 00:00:00 2001 From: RiceChuan Date: Tue, 10 Dec 2024 16:58:37 +0800 Subject: [PATCH 0627/1022] =?UTF-8?q?style=EF=BC=9A=20SETTINGS=5FPRESETS?= =?UTF-8?q?=20is=20not=20declared=20using=20const.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: RiceChuan --- scripts/bytecodecompare/prepare_report.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/bytecodecompare/prepare_report.js b/scripts/bytecodecompare/prepare_report.js index 821b5cb750eb..96bd3c1eebfa 100755 --- a/scripts/bytecodecompare/prepare_report.js +++ b/scripts/bytecodecompare/prepare_report.js @@ -4,7 +4,7 @@ const fs = require('fs') const compiler = require('solc') -SETTINGS_PRESETS = { +const SETTINGS_PRESETS = { 'legacy-optimize': {optimize: true, viaIR: false}, 'legacy-no-optimize': {optimize: false, viaIR: false}, 'via-ir-optimize': {optimize: true, viaIR: true}, From 34657855cab27408ac6ee7f283a7ac175510ebc6 Mon Sep 17 00:00:00 2001 From: rodiazet Date: Tue, 10 Dec 2024 12:35:56 +0100 Subject: [PATCH 0628/1022] eof: Comment unnecessary `solAssert` --- libevmasm/Assembly.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libevmasm/Assembly.cpp b/libevmasm/Assembly.cpp index e5c62958f6e6..12bb3cccc13c 100644 --- a/libevmasm/Assembly.cpp +++ b/libevmasm/Assembly.cpp @@ -1019,8 +1019,9 @@ uint16_t calculateMaxStackHeight(Assembly::CodeSection const& _section) auto const tagIt = std::find(items.begin(), items.end(), item.tag()); solAssert(tagIt != items.end(), "Tag not found."); successors.emplace_back(static_cast(std::distance(items.begin(), tagIt))); + // TODO: This assert fails until the code is not topologically sorted. Uncomment when sorting introduced. // If backward jump the successor must be already visited. - solAssert(idx <= successors.back() || maxStackHeights[successors.back()] != UNVISITED); + // solAssert(idx <= successors.back() || maxStackHeights[successors.back()] != UNVISITED); } solRequire( From 3a290debd12f8d385abaa1e7affb86aa1cc26dc9 Mon Sep 17 00:00:00 2001 From: rodiazet Date: Tue, 10 Dec 2024 16:44:58 +0100 Subject: [PATCH 0629/1022] eof: Disallow `gas` option for external function call. --- libsolidity/analysis/TypeChecker.cpp | 6 ++++++ libsolidity/analysis/TypeChecker.h | 4 +++- libsolidity/interface/CompilerStack.cpp | 2 +- test/libsolidity/Assembly.cpp | 6 +++++- test/libsolidity/SolidityExpressionCompiler.cpp | 6 +++++- .../eof/external_call_with_gas_option.sol | 12 ++++++++++++ 6 files changed, 32 insertions(+), 4 deletions(-) create mode 100644 test/libsolidity/syntaxTests/functionCalls/eof/external_call_with_gas_option.sol diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp index 993541472637..4264bf71d46f 100644 --- a/libsolidity/analysis/TypeChecker.cpp +++ b/libsolidity/analysis/TypeChecker.cpp @@ -2967,6 +2967,12 @@ bool TypeChecker::visit(FunctionCallOptions const& _functionCallOptions) _functionCallOptions.location(), "Function call option \"gas\" cannot be used with \"new\"." ); + else if (m_eofVersion.has_value()) + m_errorReporter.typeError( + 3765_error, + _functionCallOptions.location(), + "Function call option \"gas\" cannot be used when compiling to EOF." + ); else { expectType(*_functionCallOptions.options()[i], *TypeProvider::uint256()); diff --git a/libsolidity/analysis/TypeChecker.h b/libsolidity/analysis/TypeChecker.h index b3bd8b91fb09..a517a750c323 100644 --- a/libsolidity/analysis/TypeChecker.h +++ b/libsolidity/analysis/TypeChecker.h @@ -47,8 +47,9 @@ class TypeChecker: private ASTConstVisitor { public: /// @param _errorReporter provides the error logging functionality. - TypeChecker(langutil::EVMVersion _evmVersion, langutil::ErrorReporter& _errorReporter): + TypeChecker(langutil::EVMVersion _evmVersion, std::optional _eofVersion, langutil::ErrorReporter& _errorReporter): m_evmVersion(_evmVersion), + m_eofVersion(_eofVersion), m_errorReporter(_errorReporter) {} @@ -192,6 +193,7 @@ class TypeChecker: private ASTConstVisitor ContractDefinition const* m_currentContract = nullptr; langutil::EVMVersion m_evmVersion; + std::optional m_eofVersion; langutil::ErrorReporter& m_errorReporter; }; diff --git a/libsolidity/interface/CompilerStack.cpp b/libsolidity/interface/CompilerStack.cpp index b90a30242727..fa84364681cd 100644 --- a/libsolidity/interface/CompilerStack.cpp +++ b/libsolidity/interface/CompilerStack.cpp @@ -557,7 +557,7 @@ bool CompilerStack::analyzeLegacy(bool _noErrorsSoFar) // // Note: this does not resolve overloaded functions. In order to do that, types of arguments are needed, // which is only done one step later. - TypeChecker typeChecker(m_evmVersion, m_errorReporter); + TypeChecker typeChecker(m_evmVersion, m_eofVersion, m_errorReporter); for (Source const* source: m_sourceOrder) if (source->ast && !typeChecker.checkTypeRequirements(*source->ast)) noErrors = false; diff --git a/test/libsolidity/Assembly.cpp b/test/libsolidity/Assembly.cpp index bf1e5caf7c04..0999e30ed30b 100644 --- a/test/libsolidity/Assembly.cpp +++ b/test/libsolidity/Assembly.cpp @@ -81,7 +81,11 @@ evmasm::AssemblyItems compileContract(std::shared_ptr _sourceCode) if (Error::containsErrors(errorReporter.errors())) return AssemblyItems(); } - TypeChecker checker(solidity::test::CommonOptions::get().evmVersion(), errorReporter); + TypeChecker checker( + solidity::test::CommonOptions::get().evmVersion(), + solidity::test::CommonOptions::get().eofVersion(), + errorReporter + ); BOOST_REQUIRE_NO_THROW(checker.checkTypeRequirements(*sourceUnit)); if (Error::containsErrors(errorReporter.errors())) return AssemblyItems(); diff --git a/test/libsolidity/SolidityExpressionCompiler.cpp b/test/libsolidity/SolidityExpressionCompiler.cpp index 20983b650990..3df712a43a76 100644 --- a/test/libsolidity/SolidityExpressionCompiler.cpp +++ b/test/libsolidity/SolidityExpressionCompiler.cpp @@ -133,7 +133,11 @@ bytes compileFirstExpression( DeclarationTypeChecker declarationTypeChecker(errorReporter, solidity::test::CommonOptions::get().evmVersion()); for (ASTPointer const& node: sourceUnit->nodes()) BOOST_REQUIRE(declarationTypeChecker.check(*node)); - TypeChecker typeChecker(solidity::test::CommonOptions::get().evmVersion(), errorReporter); + TypeChecker typeChecker( + solidity::test::CommonOptions::get().evmVersion(), + solidity::test::CommonOptions::get().eofVersion(), + errorReporter + ); BOOST_REQUIRE(typeChecker.checkTypeRequirements(*sourceUnit)); for (ASTPointer const& node: sourceUnit->nodes()) if (ContractDefinition* contract = dynamic_cast(node.get())) diff --git a/test/libsolidity/syntaxTests/functionCalls/eof/external_call_with_gas_option.sol b/test/libsolidity/syntaxTests/functionCalls/eof/external_call_with_gas_option.sol new file mode 100644 index 000000000000..9443bac0605f --- /dev/null +++ b/test/libsolidity/syntaxTests/functionCalls/eof/external_call_with_gas_option.sol @@ -0,0 +1,12 @@ +contract C { + function g(bool x) public pure { + require(x); + } + function f(bool x) public returns (uint) { + this.g{gas: 8000}(x); + } +} +// ==== +// bytecodeFormat: >=EOFv1 +// ---- +// TypeError 3765: (131-148): Function call option "gas" cannot be used when compiling to EOF. From e8cfe0b304872291d63da69c20d73540a2a18739 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Fri, 6 Dec 2024 21:57:57 +0100 Subject: [PATCH 0630/1022] StandardCompiler: Fix evm.* outputs being evaluated even when not requested in Standard JSON --- Changelog.md | 1 + libsolidity/interface/StandardCompiler.cpp | 218 +++++++++++---------- 2 files changed, 115 insertions(+), 104 deletions(-) diff --git a/Changelog.md b/Changelog.md index 4c2885c9a8b8..29b5870bc8fa 100644 --- a/Changelog.md +++ b/Changelog.md @@ -9,6 +9,7 @@ Compiler Features: Bugfixes: * General: Fix internal compiler error when requesting IR AST outputs for interfaces and abstract contracts. +* Standard JSON Interface: Fix ``generatedSources`` and ``sourceMap`` being generated internally even when not requested. ### 0.8.28 (2024-10-09) diff --git a/libsolidity/interface/StandardCompiler.cpp b/libsolidity/interface/StandardCompiler.cpp index 351a17b897d6..56f955f4013d 100644 --- a/libsolidity/interface/StandardCompiler.cpp +++ b/libsolidity/interface/StandardCompiler.cpp @@ -374,33 +374,6 @@ Json formatImmutableReferences(std::map const& _artifactRequested -) -{ - Json output; - if (_artifactRequested("object")) - output["object"] = _object.toHex(); - if (_artifactRequested("opcodes")) - output["opcodes"] = evmasm::disassemble(_object.bytecode, _evmVersion); - if (_artifactRequested("sourceMap")) - output["sourceMap"] = _sourceMap ? *_sourceMap : ""; - if (_artifactRequested("functionDebugData")) - output["functionDebugData"] = StandardCompiler::formatFunctionDebugData(_object.functionDebugData); - if (_artifactRequested("linkReferences")) - output["linkReferences"] = formatLinkReferences(_object.linkReferences); - if (_runtimeObject && _artifactRequested("immutableReferences")) - output["immutableReferences"] = formatImmutableReferences(_object.immutableReferences); - if (_artifactRequested("generatedSources")) - output["generatedSources"] = std::move(_generatedSources); - return output; -} - std::optional checkKeys(Json const& _input, std::set const& _keys, std::string const& _name) { if (!_input.empty() && !_input.is_object()) @@ -1246,22 +1219,26 @@ Json StandardCompiler::importEVMAssembly(StandardCompiler::InputsAndSettings _in evmObjectComponents("bytecode"), wildcardMatchesExperimental )) - evmData["bytecode"] = collectEVMObject( - _inputsAndSettings.evmVersion, - stack.object(sourceName), - stack.sourceMapping(sourceName), - {}, - false, // _runtimeObject - [&](std::string const& _element) { - return isArtifactRequested( - _inputsAndSettings.outputSelection, - sourceName, - "", - "evm.bytecode." + _element, - wildcardMatchesExperimental - ); - } - ); + { + auto const evmCreationArtifactRequested = [&](std::string const& _element) { + return isArtifactRequested(_inputsAndSettings.outputSelection, sourceName, "", "evm.bytecode." + _element, wildcardMatchesExperimental); + }; + + Json creationJSON; + if (evmCreationArtifactRequested("object")) + creationJSON["object"] = stack.object(sourceName).toHex(); + if (evmCreationArtifactRequested("opcodes")) + creationJSON["opcodes"] = evmasm::disassemble(stack.object(sourceName).bytecode, _inputsAndSettings.evmVersion); + if (evmCreationArtifactRequested("sourceMap")) + creationJSON["sourceMap"] = stack.sourceMapping(sourceName) ? *stack.sourceMapping(sourceName) : ""; + if (evmCreationArtifactRequested("functionDebugData")) + creationJSON["functionDebugData"] = formatFunctionDebugData(stack.object(sourceName).functionDebugData); + if (evmCreationArtifactRequested("linkReferences")) + creationJSON["linkReferences"] = formatLinkReferences(stack.object(sourceName).linkReferences); + if (evmCreationArtifactRequested("generatedSources")) + creationJSON["generatedSources"] = {}; + evmData["bytecode"] = creationJSON; + } if (isArtifactRequested( _inputsAndSettings.outputSelection, @@ -1270,22 +1247,28 @@ Json StandardCompiler::importEVMAssembly(StandardCompiler::InputsAndSettings _in evmObjectComponents("deployedBytecode"), wildcardMatchesExperimental )) - evmData["deployedBytecode"] = collectEVMObject( - _inputsAndSettings.evmVersion, - stack.runtimeObject(sourceName), - stack.runtimeSourceMapping(sourceName), - {}, - true, // _runtimeObject - [&](std::string const& _element) { - return isArtifactRequested( - _inputsAndSettings.outputSelection, - sourceName, - "", - "evm.deployedBytecode." + _element, - wildcardMatchesExperimental - ); - } - ); + { + auto const evmDeployedArtifactRequested = [&](std::string const& _element) { + return isArtifactRequested(_inputsAndSettings.outputSelection, sourceName, "", "evm.deployedBytecode." + _element, wildcardMatchesExperimental); + }; + + Json deployedJSON; + if (evmDeployedArtifactRequested("object")) + deployedJSON["object"] = stack.runtimeObject(sourceName).toHex(); + if (evmDeployedArtifactRequested("opcodes")) + deployedJSON["opcodes"] = evmasm::disassemble(stack.runtimeObject(sourceName).bytecode, _inputsAndSettings.evmVersion); + if (evmDeployedArtifactRequested("sourceMap")) + deployedJSON["sourceMap"] = stack.runtimeSourceMapping(sourceName) ? *stack.runtimeSourceMapping(sourceName) : ""; + if (evmDeployedArtifactRequested("functionDebugData")) + deployedJSON["functionDebugData"] = formatFunctionDebugData(stack.runtimeObject(sourceName).functionDebugData); + if (evmDeployedArtifactRequested("linkReferences")) + deployedJSON["linkReferences"] = formatLinkReferences(stack.runtimeObject(sourceName).linkReferences); + if (evmDeployedArtifactRequested("immutableReferences")) + deployedJSON["immutableReferences"] = formatImmutableReferences(stack.runtimeObject(sourceName).immutableReferences); + if (evmDeployedArtifactRequested("generatedSources")) + deployedJSON["generatedSources"] = {}; + evmData["deployedBytecode"] = deployedJSON; + } Json contractData; if (!evmData.empty()) @@ -1506,20 +1489,26 @@ Json StandardCompiler::compileSolidity(StandardCompiler::InputsAndSettings _inpu evmObjectComponents("bytecode"), wildcardMatchesExperimental )) - evmData["bytecode"] = collectEVMObject( - _inputsAndSettings.evmVersion, - compilerStack.object(contractName), - compilerStack.sourceMapping(contractName), - compilerStack.generatedSources(contractName), - false, - [&](std::string const& _element) { return isArtifactRequested( - _inputsAndSettings.outputSelection, - file, - name, - "evm.bytecode." + _element, - wildcardMatchesExperimental - ); } - ); + { + auto const evmCreationArtifactRequested = [&](std::string const& _element) { + return isArtifactRequested(_inputsAndSettings.outputSelection, file, name, "evm.bytecode." + _element, wildcardMatchesExperimental); + }; + + Json creationJSON; + if (evmCreationArtifactRequested("object")) + creationJSON["object"] = compilerStack.object(contractName).toHex(); + if (evmCreationArtifactRequested("opcodes")) + creationJSON["opcodes"] = evmasm::disassemble(compilerStack.object(contractName).bytecode, _inputsAndSettings.evmVersion); + if (evmCreationArtifactRequested("sourceMap")) + creationJSON["sourceMap"] = compilerStack.sourceMapping(contractName) ? *compilerStack.sourceMapping(contractName) : ""; + if (evmCreationArtifactRequested("functionDebugData")) + creationJSON["functionDebugData"] = formatFunctionDebugData(compilerStack.object(contractName).functionDebugData); + if (evmCreationArtifactRequested("linkReferences")) + creationJSON["linkReferences"] = formatLinkReferences(compilerStack.object(contractName).linkReferences); + if (evmCreationArtifactRequested("generatedSources")) + creationJSON["generatedSources"] = compilerStack.generatedSources(contractName, /* _runtime */ false); + evmData["bytecode"] = creationJSON; + } if (compilationSuccess && isArtifactRequested( _inputsAndSettings.outputSelection, @@ -1528,20 +1517,28 @@ Json StandardCompiler::compileSolidity(StandardCompiler::InputsAndSettings _inpu evmObjectComponents("deployedBytecode"), wildcardMatchesExperimental )) - evmData["deployedBytecode"] = collectEVMObject( - _inputsAndSettings.evmVersion, - compilerStack.runtimeObject(contractName), - compilerStack.runtimeSourceMapping(contractName), - compilerStack.generatedSources(contractName, true), - true, - [&](std::string const& _element) { return isArtifactRequested( - _inputsAndSettings.outputSelection, - file, - name, - "evm.deployedBytecode." + _element, - wildcardMatchesExperimental - ); } - ); + { + auto const evmDeployedArtifactRequested = [&](std::string const& _element) { + return isArtifactRequested(_inputsAndSettings.outputSelection, file, name, "evm.deployedBytecode." + _element, wildcardMatchesExperimental); + }; + + Json deployedJSON; + if (evmDeployedArtifactRequested("object")) + deployedJSON["object"] = compilerStack.runtimeObject(contractName).toHex(); + if (evmDeployedArtifactRequested("opcodes")) + deployedJSON["opcodes"] = evmasm::disassemble(compilerStack.runtimeObject(contractName).bytecode, _inputsAndSettings.evmVersion); + if (evmDeployedArtifactRequested("sourceMap")) + deployedJSON["sourceMap"] = compilerStack.runtimeSourceMapping(contractName) ? *compilerStack.runtimeSourceMapping(contractName) : ""; + if (evmDeployedArtifactRequested("functionDebugData")) + deployedJSON["functionDebugData"] = formatFunctionDebugData(compilerStack.runtimeObject(contractName).functionDebugData); + if (evmDeployedArtifactRequested("linkReferences")) + deployedJSON["linkReferences"] = formatLinkReferences(compilerStack.runtimeObject(contractName).linkReferences); + if (evmDeployedArtifactRequested("immutableReferences")) + deployedJSON["immutableReferences"] = formatImmutableReferences(compilerStack.runtimeObject(contractName).immutableReferences); + if (evmDeployedArtifactRequested("generatedSources")) + deployedJSON["generatedSources"] = compilerStack.generatedSources(contractName, /* _runtime */ true); + evmData["deployedBytecode"] = deployedJSON; + } if (!evmData.empty()) contractData["evm"] = evmData; @@ -1668,23 +1665,36 @@ Json StandardCompiler::compileYul(InputsAndSettings _inputsAndSettings) wildcardMatchesExperimental )) { - MachineAssemblyObject const& o = isDeployed ? deployedObject : object; - if (o.bytecode) - output["contracts"][sourceName][contractName]["evm"][kind] = - collectEVMObject( - _inputsAndSettings.evmVersion, - *o.bytecode, - o.sourceMappings.get(), - Json::array(), - isDeployed, - [&, kind = kind](std::string const& _element) { return isArtifactRequested( - _inputsAndSettings.outputSelection, - sourceName, - contractName, - "evm." + kind + "." + _element, - wildcardMatchesExperimental - ); } - ); + auto const evmArtifactRequested = [&](std::string const& _kind, std::string const& _element) { + return isArtifactRequested( + _inputsAndSettings.outputSelection, + sourceName, + contractName, + "evm." + _kind + "." + _element, + wildcardMatchesExperimental + ); + }; + + MachineAssemblyObject const& selectedObject = isDeployed ? deployedObject : object; + if (selectedObject.bytecode) + { + Json bytecodeJSON; + if (evmArtifactRequested(kind, "object")) + bytecodeJSON["object"] = selectedObject.bytecode->toHex(); + if (evmArtifactRequested(kind, "opcodes")) + bytecodeJSON["opcodes"] = evmasm::disassemble(selectedObject.bytecode->bytecode, _inputsAndSettings.evmVersion); + if (evmArtifactRequested(kind, "sourceMap")) + bytecodeJSON["sourceMap"] = selectedObject.sourceMappings ? *selectedObject.sourceMappings : ""; + if (evmArtifactRequested(kind, "functionDebugData")) + bytecodeJSON["functionDebugData"] = formatFunctionDebugData(selectedObject.bytecode->functionDebugData); + if (evmArtifactRequested(kind, "linkReferences")) + bytecodeJSON["linkReferences"] = formatLinkReferences(selectedObject.bytecode->linkReferences); + if (isDeployed && evmArtifactRequested(kind, "immutableReferences")) + bytecodeJSON["immutableReferences"] = formatImmutableReferences(selectedObject.bytecode->immutableReferences); + if (evmArtifactRequested(kind, "generatedSources")) + bytecodeJSON["generatedSources"] = Json::array(); + output["contracts"][sourceName][contractName]["evm"][kind] = bytecodeJSON; + } } if (isArtifactRequested(_inputsAndSettings.outputSelection, sourceName, contractName, "irOptimized", wildcardMatchesExperimental)) From 11d8fddeeff896d5d13eb873b8dac90c3c659988 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Fri, 6 Dec 2024 22:27:47 +0100 Subject: [PATCH 0631/1022] StandardCompiler: Don't include empty generatedSources key for Yul compilation and assembly import --- libsolidity/interface/StandardCompiler.cpp | 6 ------ test/cmdlineTests/standard_yul/output.json | 1 - .../standard_yul_immutable_references/output.json | 2 -- test/cmdlineTests/standard_yul_object/output.json | 1 - test/cmdlineTests/standard_yul_object_name/output.json | 2 -- test/cmdlineTests/standard_yul_optimiserSteps/output.json | 1 - test/cmdlineTests/standard_yul_optimized/output.json | 1 - test/cmdlineTests/standard_yul_output_warning/output.json | 1 - 8 files changed, 15 deletions(-) diff --git a/libsolidity/interface/StandardCompiler.cpp b/libsolidity/interface/StandardCompiler.cpp index 56f955f4013d..b5279c624a9e 100644 --- a/libsolidity/interface/StandardCompiler.cpp +++ b/libsolidity/interface/StandardCompiler.cpp @@ -1235,8 +1235,6 @@ Json StandardCompiler::importEVMAssembly(StandardCompiler::InputsAndSettings _in creationJSON["functionDebugData"] = formatFunctionDebugData(stack.object(sourceName).functionDebugData); if (evmCreationArtifactRequested("linkReferences")) creationJSON["linkReferences"] = formatLinkReferences(stack.object(sourceName).linkReferences); - if (evmCreationArtifactRequested("generatedSources")) - creationJSON["generatedSources"] = {}; evmData["bytecode"] = creationJSON; } @@ -1265,8 +1263,6 @@ Json StandardCompiler::importEVMAssembly(StandardCompiler::InputsAndSettings _in deployedJSON["linkReferences"] = formatLinkReferences(stack.runtimeObject(sourceName).linkReferences); if (evmDeployedArtifactRequested("immutableReferences")) deployedJSON["immutableReferences"] = formatImmutableReferences(stack.runtimeObject(sourceName).immutableReferences); - if (evmDeployedArtifactRequested("generatedSources")) - deployedJSON["generatedSources"] = {}; evmData["deployedBytecode"] = deployedJSON; } @@ -1691,8 +1687,6 @@ Json StandardCompiler::compileYul(InputsAndSettings _inputsAndSettings) bytecodeJSON["linkReferences"] = formatLinkReferences(selectedObject.bytecode->linkReferences); if (isDeployed && evmArtifactRequested(kind, "immutableReferences")) bytecodeJSON["immutableReferences"] = formatImmutableReferences(selectedObject.bytecode->immutableReferences); - if (evmArtifactRequested(kind, "generatedSources")) - bytecodeJSON["generatedSources"] = Json::array(); output["contracts"][sourceName][contractName]["evm"][kind] = bytecodeJSON; } } diff --git a/test/cmdlineTests/standard_yul/output.json b/test/cmdlineTests/standard_yul/output.json index 30fe1dd7ecb7..a72904ee6c31 100644 --- a/test/cmdlineTests/standard_yul/output.json +++ b/test/cmdlineTests/standard_yul/output.json @@ -18,7 +18,6 @@ ", "bytecode": { "functionDebugData": {}, - "generatedSources": [], "linkReferences": {}, "object": "", "opcodes":"", diff --git a/test/cmdlineTests/standard_yul_immutable_references/output.json b/test/cmdlineTests/standard_yul_immutable_references/output.json index 7bfbb076a389..3f82bcbaab54 100644 --- a/test/cmdlineTests/standard_yul_immutable_references/output.json +++ b/test/cmdlineTests/standard_yul_immutable_references/output.json @@ -5,7 +5,6 @@ "evm": { "bytecode": { "functionDebugData": {}, - "generatedSources": [], "linkReferences": {}, "object": "", "opcodes":"", @@ -13,7 +12,6 @@ }, "deployedBytecode": { "functionDebugData": {}, - "generatedSources": [], "immutableReferences": { "test": [ { diff --git a/test/cmdlineTests/standard_yul_object/output.json b/test/cmdlineTests/standard_yul_object/output.json index 3181da426000..c1bb2eb3eb6d 100644 --- a/test/cmdlineTests/standard_yul_object/output.json +++ b/test/cmdlineTests/standard_yul_object/output.json @@ -19,7 +19,6 @@ data_4e03657aea45a94fc7d47ba826c8d667c0d1e6e33a64a036ec44f58fa12d6c45 616263 ", "bytecode": { "functionDebugData": {}, - "generatedSources": [], "linkReferences": {}, "object": "", "opcodes":"", diff --git a/test/cmdlineTests/standard_yul_object_name/output.json b/test/cmdlineTests/standard_yul_object_name/output.json index 1512900e1c85..2b6dc1f73e85 100644 --- a/test/cmdlineTests/standard_yul_object_name/output.json +++ b/test/cmdlineTests/standard_yul_object_name/output.json @@ -27,7 +27,6 @@ sub_0: assembly { ", "bytecode": { "functionDebugData": {}, - "generatedSources": [], "linkReferences": {}, "object": "", "opcodes":"", @@ -35,7 +34,6 @@ sub_0: assembly { }, "deployedBytecode": { "functionDebugData": {}, - "generatedSources": [], "immutableReferences": {}, "linkReferences": {}, "object": "", diff --git a/test/cmdlineTests/standard_yul_optimiserSteps/output.json b/test/cmdlineTests/standard_yul_optimiserSteps/output.json index 2a654d20a9cb..621a029076e2 100644 --- a/test/cmdlineTests/standard_yul_optimiserSteps/output.json +++ b/test/cmdlineTests/standard_yul_optimiserSteps/output.json @@ -15,7 +15,6 @@ ", "bytecode": { "functionDebugData": {}, - "generatedSources": [], "linkReferences": {}, "object": "", "opcodes":"", diff --git a/test/cmdlineTests/standard_yul_optimized/output.json b/test/cmdlineTests/standard_yul_optimized/output.json index 513f8148a0f9..ad0e9f40aa1f 100644 --- a/test/cmdlineTests/standard_yul_optimized/output.json +++ b/test/cmdlineTests/standard_yul_optimized/output.json @@ -15,7 +15,6 @@ ", "bytecode": { "functionDebugData": {}, - "generatedSources": [], "linkReferences": {}, "object": "", "opcodes":"", diff --git a/test/cmdlineTests/standard_yul_output_warning/output.json b/test/cmdlineTests/standard_yul_output_warning/output.json index 3234be1817fd..514280afcc80 100644 --- a/test/cmdlineTests/standard_yul_output_warning/output.json +++ b/test/cmdlineTests/standard_yul_output_warning/output.json @@ -19,7 +19,6 @@ ", "bytecode": { "functionDebugData": {}, - "generatedSources": [], "linkReferences": {}, "object": "", "opcodes":"", From 8616387d5c999b088e654d49cfe20420f6c89cf0 Mon Sep 17 00:00:00 2001 From: rodiazet Date: Tue, 10 Dec 2024 14:41:54 +0100 Subject: [PATCH 0632/1022] eof: Add new (EOF) message kind to EVMHost. Separate arguments in sendMessage --- test/EVMHost.cpp | 18 +++++++++++++----- test/ExecutionFramework.cpp | 18 +++++++++++++----- test/ExecutionFramework.h | 8 ++++---- test/contracts/AuctionRegistrar.cpp | 2 +- test/contracts/Wallet.cpp | 2 +- test/libsolidity/GasMeter.cpp | 2 +- test/libsolidity/SolidityEndToEndTest.cpp | 4 ++-- test/libsolidity/SolidityExecutionFramework.h | 2 +- 8 files changed, 36 insertions(+), 20 deletions(-) diff --git a/test/EVMHost.cpp b/test/EVMHost.cpp index 5626f8d436e7..7d0125eecff0 100644 --- a/test/EVMHost.cpp +++ b/test/EVMHost.cpp @@ -332,13 +332,17 @@ evmc::Result EVMHost::call(evmc_message const& _message) noexcept code = evmc::bytes(message.input_data, message.input_data + message.input_size); } - else if (message.kind == EVMC_CREATE2) + else if (message.kind == EVMC_CREATE2 || message.kind == EVMC_EOFCREATE) { h160 createAddress(keccak256( bytes{0xff} + bytes(std::begin(message.sender.bytes), std::end(message.sender.bytes)) + bytes(std::begin(message.create2_salt.bytes), std::end(message.create2_salt.bytes)) + - keccak256(bytes(message.input_data, message.input_data + message.input_size)).asBytes() + keccak256( + message.kind == EVMC_CREATE2 ? + bytes(message.input_data, message.input_data + message.input_size) : + bytes(message.code, message.code + message.code_size) + ).asBytes() ), h160::AlignRight); message.recipient = convertToEVMC(createAddress); @@ -353,13 +357,16 @@ evmc::Result EVMHost::call(evmc_message const& _message) noexcept return result; } - code = evmc::bytes(message.input_data, message.input_data + message.input_size); + if (message.kind == EVMC_CREATE2) + code = evmc::bytes(message.input_data, message.input_data + message.input_size); + else // EOFCREATE + code = evmc::bytes(message.code, message.code + message.code_size); } else code = accounts[message.code_address].code; auto& destination = accounts[message.recipient]; - if (message.kind == EVMC_CREATE || message.kind == EVMC_CREATE2) + if (message.kind == EVMC_CREATE || message.kind == EVMC_CREATE2 || message.kind == EVMC_EOFCREATE) // Mark account as created if it is a CREATE or CREATE2 call // TODO: Should we roll changes back on failure like we do for `accounts`? m_newlyCreatedAccounts.emplace(message.recipient); @@ -396,7 +403,7 @@ evmc::Result EVMHost::call(evmc_message const& _message) noexcept } evmc::Result result = m_vm.execute(*this, m_evmRevision, message, code.data(), code.size()); - if (message.kind == EVMC_CREATE || message.kind == EVMC_CREATE2) + if (message.kind == EVMC_CREATE || message.kind == EVMC_CREATE2 || message.kind == EVMC_EOFCREATE) { int64_t codeDepositGas = static_cast(evmasm::GasCosts::createDataGas * result.output_size); result.gas_left -= codeDepositGas; @@ -409,6 +416,7 @@ evmc::Result EVMHost::call(evmc_message const& _message) noexcept } else { + // TODO: Add proper codehash calculation for EOF. m_totalCodeDepositGas += codeDepositGas; result.create_address = message.recipient; destination.code = evmc::bytes(result.output_data, result.output_data + result.output_size); diff --git a/test/ExecutionFramework.cpp b/test/ExecutionFramework.cpp index 0081ba4a9d27..582cf1edab6e 100644 --- a/test/ExecutionFramework.cpp +++ b/test/ExecutionFramework.cpp @@ -145,10 +145,13 @@ u256 ExecutionFramework::blockNumber() const return m_evmcHost->tx_context.block_number; } -void ExecutionFramework::sendMessage(bytes const& _data, bool _isCreation, u256 const& _value) +void ExecutionFramework::sendMessage(bytes const& _bytecode, bytes const& _arguments, bool _isCreation, u256 const& _value) { + auto const eof = _bytecode.size() > 1 && _bytecode[0] == 0xef && _bytecode[1] == 0x00; m_evmcHost->newBlock(); + auto const data = _bytecode + _arguments; + if (m_showMessages) { if (_isCreation) @@ -157,17 +160,22 @@ void ExecutionFramework::sendMessage(bytes const& _data, bool _isCreation, u256 std::cout << "CALL " << m_sender.hex() << " -> " << m_contractAddress.hex() << ":" << std::endl; if (_value > 0) std::cout << " value: " << _value << std::endl; - std::cout << " in: " << util::toHex(_data) << std::endl; + std::cout << " in: " << util::toHex(data) << std::endl; } evmc_message message{}; - message.input_data = _data.data(); - message.input_size = _data.size(); + message.input_data = eof ? _arguments.data() : data.data(); + message.input_size = eof ? _arguments.size() : data.size(); + if (eof) + { + message.code = _bytecode.data(); + message.code_size = _bytecode.size(); + } message.sender = EVMHost::convertToEVMC(m_sender); message.value = EVMHost::convertToEVMC(_value); if (_isCreation) { - message.kind = EVMC_CREATE; + message.kind = eof ? EVMC_EOFCREATE : EVMC_CREATE; message.recipient = {}; message.code_address = {}; } diff --git a/test/ExecutionFramework.h b/test/ExecutionFramework.h index 5d66ea10d042..44812e230ab0 100644 --- a/test/ExecutionFramework.h +++ b/test/ExecutionFramework.h @@ -90,7 +90,7 @@ class ExecutionFramework bytes const& callFallbackWithValue(u256 const& _value) { - sendMessage(bytes(), false, _value); + sendMessage(bytes(), bytes(), false, _value); return m_output; } @@ -101,13 +101,13 @@ class ExecutionFramework bytes const& callLowLevel(bytes const& _data, u256 const& _value) { - sendMessage(_data, false, _value); + sendMessage(_data, bytes(), false, _value); return m_output; } bytes const& callContractFunctionWithValueNoEncoding(std::string _sig, u256 const& _value, bytes const& _arguments) { - sendMessage(util::selectorFromSignatureH32(_sig).asBytes() + _arguments, false, _value); + sendMessage(util::selectorFromSignatureH32(_sig).asBytes(), _arguments, false, _value); return m_output; } @@ -277,7 +277,7 @@ class ExecutionFramework void selectVM(evmc_capabilities _cap = evmc_capabilities::EVMC_CAPABILITY_EVM1); void reset(); - void sendMessage(bytes const& _data, bool _isCreation, u256 const& _value = 0); + void sendMessage(bytes const& _bytecode, bytes const& _argument, bool _isCreation, u256 const& _value = 0); void sendEther(util::h160 const& _to, u256 const& _value); size_t currentTimestamp(); size_t blockTimestamp(u256 _number); diff --git a/test/contracts/AuctionRegistrar.cpp b/test/contracts/AuctionRegistrar.cpp index 8d0b1ccb640d..c686963df317 100644 --- a/test/contracts/AuctionRegistrar.cpp +++ b/test/contracts/AuctionRegistrar.cpp @@ -225,7 +225,7 @@ class AuctionRegistrarTestFramework: public SolidityExecutionFramework return compileContract(registrarCode, "GlobalRegistrar"); }); - sendMessage(compiled, true); + sendMessage(compiled, bytes(), true); BOOST_REQUIRE(m_transactionSuccessful); BOOST_REQUIRE(!m_output.empty()); } diff --git a/test/contracts/Wallet.cpp b/test/contracts/Wallet.cpp index db9119deebeb..6e8670e14e0a 100644 --- a/test/contracts/Wallet.cpp +++ b/test/contracts/Wallet.cpp @@ -454,7 +454,7 @@ class WalletTestFramework: public SolidityExecutionFramework }); bytes args = encodeArgs(u256(0x60), _required, _dailyLimit, u256(_owners.size()), _owners); - sendMessage(compiled + args, true, _value); + sendMessage(compiled, args, true, _value); BOOST_REQUIRE(m_transactionSuccessful); BOOST_REQUIRE(!m_output.empty()); } diff --git a/test/libsolidity/GasMeter.cpp b/test/libsolidity/GasMeter.cpp index 1afebac5c5c8..9012ad083c02 100644 --- a/test/libsolidity/GasMeter.cpp +++ b/test/libsolidity/GasMeter.cpp @@ -76,7 +76,7 @@ class GasMeterTestFramework: public SolidityExecutionFramework util::FixedHash<4> hash = util::selectorFromSignatureH32(_sig); for (bytes const& arguments: _argumentVariants) { - sendMessage(hash.asBytes() + arguments, false, 0); + sendMessage(hash.asBytes(), arguments, false, 0); BOOST_CHECK(m_transactionSuccessful); gasUsed = std::max(gasUsed, m_gasUsed); gas = std::max(gas, gasForTransaction(hash.asBytes() + arguments, false)); diff --git a/test/libsolidity/SolidityEndToEndTest.cpp b/test/libsolidity/SolidityEndToEndTest.cpp index e321a5298603..76699c2e3b6c 100644 --- a/test/libsolidity/SolidityEndToEndTest.cpp +++ b/test/libsolidity/SolidityEndToEndTest.cpp @@ -1374,7 +1374,7 @@ BOOST_AUTO_TEST_CASE(bytes_from_calldata_to_memory) ALSO_VIA_YUL( compileAndRun(sourceCode); bytes calldata1 = util::selectorFromSignatureH32("f()").asBytes() + bytes(61, 0x22) + bytes(12, 0x12); - sendMessage(calldata1, false); + sendMessage(calldata1, bytes(), false); BOOST_CHECK(m_transactionSuccessful); BOOST_CHECK(m_output == encodeArgs(util::keccak256(bytes{'a', 'b', 'c'} + calldata1))); ); @@ -1474,7 +1474,7 @@ BOOST_AUTO_TEST_CASE(copy_from_calldata_removes_bytes_data) compileAndRun(sourceCode); ABI_CHECK(callContractFunction("set()", 1, 2, 3, 4, 5), encodeArgs(true)); BOOST_CHECK(!storageEmpty(m_contractAddress)); - sendMessage(bytes(), false); + sendMessage(bytes(), bytes(), false); BOOST_CHECK(m_transactionSuccessful); BOOST_CHECK(m_output.empty()); BOOST_CHECK(storageEmpty(m_contractAddress)); diff --git a/test/libsolidity/SolidityExecutionFramework.h b/test/libsolidity/SolidityExecutionFramework.h index f91ba758f08b..4caa4aa1e1a4 100644 --- a/test/libsolidity/SolidityExecutionFramework.h +++ b/test/libsolidity/SolidityExecutionFramework.h @@ -62,7 +62,7 @@ class SolidityExecutionFramework: public solidity::test::ExecutionFramework ) override { bytes bytecode = multiSourceCompileContract(_sourceCode, _sourceName, _contractName, _libraryAddresses); - sendMessage(bytecode + _arguments, true, _value); + sendMessage(bytecode, _arguments, true, _value); return m_output; } From 0f7729df486a9c51eb51db507b9fbf0431fae4e6 Mon Sep 17 00:00:00 2001 From: rodiazet Date: Tue, 10 Dec 2024 14:41:54 +0100 Subject: [PATCH 0633/1022] eof: Enable EOF validation in `EVMHost` --- test/EVMHost.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/test/EVMHost.cpp b/test/EVMHost.cpp index 7d0125eecff0..fdaf3f35be1d 100644 --- a/test/EVMHost.cpp +++ b/test/EVMHost.cpp @@ -58,6 +58,7 @@ evmc::VM& EVMHost::getVM(std::string const& _path) std::cerr << ":" << std::endl << errorMsg; std::cerr << std::endl; } + vms[_path]->set_option("validate_eof", "1"); } if (vms.count(_path) > 0) From db7dacf3ddb4f786f66368b1db64d1ce14b5a710 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Tue, 10 Dec 2024 08:46:01 +0100 Subject: [PATCH 0634/1022] Constant Optimizer: Do not assert for shl builtin It is guarded by dialect.evmVersion().hasBitwiseShifting(). --- libyul/backends/evm/ConstantOptimiser.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/libyul/backends/evm/ConstantOptimiser.cpp b/libyul/backends/evm/ConstantOptimiser.cpp index d7aed27c339f..aa744415bf9d 100644 --- a/libyul/backends/evm/ConstantOptimiser.cpp +++ b/libyul/backends/evm/ConstantOptimiser.cpp @@ -126,7 +126,6 @@ Representation const& RepresentationFinder::findRepresentation(u256 const& _valu return m_cache.at(_value); yulAssert(m_dialect.auxiliaryBuiltinHandles().not_); - yulAssert(m_dialect.auxiliaryBuiltinHandles().shl); yulAssert(m_dialect.auxiliaryBuiltinHandles().exp); yulAssert(m_dialect.auxiliaryBuiltinHandles().mul); yulAssert(m_dialect.auxiliaryBuiltinHandles().add); From b976807ea9b2300d0d4ee261c88a23e3efdc949e Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Tue, 10 Dec 2024 09:59:18 +0100 Subject: [PATCH 0635/1022] EVMCodeTransformTest: use defaulted evm dialect --- test/libyul/EVMCodeTransformTest.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/libyul/EVMCodeTransformTest.cpp b/test/libyul/EVMCodeTransformTest.cpp index da2eaad0eca0..3b3432f8ed26 100644 --- a/test/libyul/EVMCodeTransformTest.cpp +++ b/test/libyul/EVMCodeTransformTest.cpp @@ -53,6 +53,8 @@ TestCase::TestResult EVMCodeTransformTest::run(std::ostream& _stream, std::strin solidity::frontend::OptimiserSettings settings = solidity::frontend::OptimiserSettings::none(); settings.runYulOptimiser = false; settings.optimizeStackAllocation = m_stackOpt; + // Restrict to a single EVM/EOF version combination (the default one) as code generation + // can be different from version to version. YulStack stack( EVMVersion{}, std::nullopt, @@ -73,7 +75,7 @@ TestCase::TestResult EVMCodeTransformTest::run(std::ostream& _stream, std::strin EVMObjectCompiler::compile( *stack.parserResult(), adapter, - CommonOptions::get().evmDialect(), + *dynamic_cast(stack.parserResult()->dialect()), m_stackOpt, std::nullopt ); From 58e71b274ca64b443df57815ed1b4bb60466a98e Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Wed, 11 Dec 2024 08:37:09 +0100 Subject: [PATCH 0636/1022] EVMObjectCompiler: Take dialect from object --- libyul/YulStack.cpp | 14 +------------- libyul/backends/evm/EVMObjectCompiler.cpp | 22 ++++++++++++---------- libyul/backends/evm/EVMObjectCompiler.h | 10 ++-------- test/libyul/EVMCodeTransformTest.cpp | 4 +--- 4 files changed, 16 insertions(+), 34 deletions(-) diff --git a/libyul/YulStack.cpp b/libyul/YulStack.cpp index 22c1fcb7dcc4..4517853a31e3 100644 --- a/libyul/YulStack.cpp +++ b/libyul/YulStack.cpp @@ -192,19 +192,7 @@ bool YulStack::analyzeParsed(Object& _object) void YulStack::compileEVM(AbstractAssembly& _assembly, bool _optimize) const { - EVMDialect const* dialect = nullptr; - switch (m_language) - { - case Language::Assembly: - case Language::StrictAssembly: - dialect = &EVMDialect::strictAssemblyForEVMObjects(m_evmVersion, m_eofVersion); - break; - default: - yulAssert(false, "Invalid language."); - break; - } - - EVMObjectCompiler::compile(*m_parserResult, _assembly, *dialect, _optimize, m_eofVersion); + EVMObjectCompiler::compile(*m_parserResult, _assembly, _optimize); } void YulStack::reparse() diff --git a/libyul/backends/evm/EVMObjectCompiler.cpp b/libyul/backends/evm/EVMObjectCompiler.cpp index de1174acee00..fb61e70f6489 100644 --- a/libyul/backends/evm/EVMObjectCompiler.cpp +++ b/libyul/backends/evm/EVMObjectCompiler.cpp @@ -37,17 +37,19 @@ using namespace solidity::yul; void EVMObjectCompiler::compile( Object const& _object, AbstractAssembly& _assembly, - EVMDialect const& _dialect, - bool _optimize, - std::optional _eofVersion + bool _optimize ) { - EVMObjectCompiler compiler(_assembly, _dialect, _eofVersion); + EVMObjectCompiler compiler(_assembly); compiler.run(_object, _optimize); } void EVMObjectCompiler::run(Object const& _object, bool _optimize) { + yulAssert(_object.dialect()); + auto const* evmDialect = dynamic_cast(_object.dialect()); + yulAssert(evmDialect); + BuiltinContext context; context.currentObject = &_object; @@ -59,7 +61,7 @@ void EVMObjectCompiler::run(Object const& _object, bool _optimize) auto subAssemblyAndID = m_assembly.createSubAssembly(isCreation, subObject->name); context.subIDs[subObject->name] = subAssemblyAndID.second; subObject->subId = subAssemblyAndID.second; - compile(*subObject, *subAssemblyAndID.first, m_dialect, _optimize, m_eofVersion); + compile(*subObject, *subAssemblyAndID.first, _optimize); } else { @@ -73,18 +75,18 @@ void EVMObjectCompiler::run(Object const& _object, bool _optimize) yulAssert(_object.analysisInfo, "No analysis info."); yulAssert(_object.hasCode(), "No code."); - if (m_eofVersion.has_value()) + if (evmDialect->eofVersion().has_value()) yulAssert( - _optimize && (m_dialect.evmVersion() >= langutil::EVMVersion::prague()), + _optimize && (evmDialect->evmVersion() >= langutil::EVMVersion::prague()), "Experimental EOF support is only available for optimized via-IR compilation and the most recent EVM version." ); - if (_optimize && m_dialect.evmVersion().canOverchargeGasForCall()) + if (_optimize && evmDialect->evmVersion().canOverchargeGasForCall()) { auto stackErrors = OptimizedEVMCodeTransform::run( m_assembly, *_object.analysisInfo, _object.code()->root(), - m_dialect, + *evmDialect, context, OptimizedEVMCodeTransform::UseNamedLabels::ForFirstFunctionOfEachName ); @@ -116,7 +118,7 @@ void EVMObjectCompiler::run(Object const& _object, bool _optimize) m_assembly, *_object.analysisInfo, _object.code()->root(), - m_dialect, + *evmDialect, context, _optimize, {}, diff --git a/libyul/backends/evm/EVMObjectCompiler.h b/libyul/backends/evm/EVMObjectCompiler.h index 5154bd37fe1c..cca346ae7845 100644 --- a/libyul/backends/evm/EVMObjectCompiler.h +++ b/libyul/backends/evm/EVMObjectCompiler.h @@ -36,20 +36,14 @@ class EVMObjectCompiler static void compile( Object const& _object, AbstractAssembly& _assembly, - EVMDialect const& _dialect, - bool _optimize, - std::optional _eofVersion + bool _optimize ); private: - EVMObjectCompiler(AbstractAssembly& _assembly, EVMDialect const& _dialect, std::optional _eofVersion): - m_assembly(_assembly), m_dialect(_dialect), m_eofVersion(_eofVersion) - {} + EVMObjectCompiler(AbstractAssembly& _assembly): m_assembly(_assembly) {} void run(Object const& _object, bool _optimize); AbstractAssembly& m_assembly; - EVMDialect const& m_dialect; - std::optional m_eofVersion; }; } diff --git a/test/libyul/EVMCodeTransformTest.cpp b/test/libyul/EVMCodeTransformTest.cpp index 3b3432f8ed26..1ba74a6e24da 100644 --- a/test/libyul/EVMCodeTransformTest.cpp +++ b/test/libyul/EVMCodeTransformTest.cpp @@ -75,9 +75,7 @@ TestCase::TestResult EVMCodeTransformTest::run(std::ostream& _stream, std::strin EVMObjectCompiler::compile( *stack.parserResult(), adapter, - *dynamic_cast(stack.parserResult()->dialect()), - m_stackOpt, - std::nullopt + m_stackOpt ); std::ostringstream output; From 394dd929f3bc6208c73cef98af918d696d418679 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Wed, 11 Dec 2024 09:07:30 +0100 Subject: [PATCH 0637/1022] EVMCodeTransformTest: Only run for the current EVM version --- test/libyul/EVMCodeTransformTest.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/test/libyul/EVMCodeTransformTest.cpp b/test/libyul/EVMCodeTransformTest.cpp index 1ba74a6e24da..288c35570fe8 100644 --- a/test/libyul/EVMCodeTransformTest.cpp +++ b/test/libyul/EVMCodeTransformTest.cpp @@ -46,6 +46,7 @@ EVMCodeTransformTest::EVMCodeTransformTest(std::string const& _filename): m_source = m_reader.source(); m_stackOpt = m_reader.boolSetting("stackOptimization", false); m_expectation = m_reader.simpleExpectations(); + m_shouldRun = CommonOptions::get().evmDialect().evmVersion() == EVMVersion{}; } TestCase::TestResult EVMCodeTransformTest::run(std::ostream& _stream, std::string const& _linePrefix, bool const _formatted) From 7e1486dba24929451fefe6ee5152fd2bd7e61b8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Fri, 6 Dec 2024 23:17:23 +0100 Subject: [PATCH 0638/1022] Fix unimplemented errors during Solidity and Yul parsing being treated as success --- libsolidity/interface/CompilerStack.cpp | 1 + libyul/YulStack.cpp | 1 + 2 files changed, 2 insertions(+) diff --git a/libsolidity/interface/CompilerStack.cpp b/libsolidity/interface/CompilerStack.cpp index fa84364681cd..dbfa4febe578 100644 --- a/libsolidity/interface/CompilerStack.cpp +++ b/libsolidity/interface/CompilerStack.cpp @@ -419,6 +419,7 @@ bool CompilerStack::parse() catch (UnimplementedFeatureError const& _error) { reportUnimplementedFeatureError(_error); + return false; } return true; diff --git a/libyul/YulStack.cpp b/libyul/YulStack.cpp index 4517853a31e3..97c67d3b58ad 100644 --- a/libyul/YulStack.cpp +++ b/libyul/YulStack.cpp @@ -62,6 +62,7 @@ bool YulStack::parse(std::string const& _sourceName, std::string const& _source) catch (UnimplementedFeatureError const& _error) { reportUnimplementedFeatureError(_error); + return false; } if (!m_errorReporter.hasErrors()) From 95c6e84f0ffc498b62009b3999881b75f37efd77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Fri, 29 Nov 2024 20:37:54 +0100 Subject: [PATCH 0639/1022] Don't ignore errors reported at optimization and assembling steps in Yul compilation --- libsolidity/interface/CompilerStack.cpp | 38 +++++++++++++-- libsolidity/interface/CompilerStack.h | 1 + libsolidity/interface/StandardCompiler.cpp | 56 +++++++++++----------- libyul/YulStack.cpp | 15 ++++-- solc/CommandLineInterface.cpp | 38 ++++++++------- test/libyul/ObjectCompilerTest.cpp | 16 ++++--- 6 files changed, 108 insertions(+), 56 deletions(-) diff --git a/libsolidity/interface/CompilerStack.cpp b/libsolidity/interface/CompilerStack.cpp index dbfa4febe578..6a50b04c5d28 100644 --- a/libsolidity/interface/CompilerStack.cpp +++ b/libsolidity/interface/CompilerStack.cpp @@ -784,14 +784,17 @@ bool CompilerStack::compile(State _stopAfter) // but CodeGenerationError is one case where someone decided to just throw Error. solAssert(_error.type() == Error::Type::CodeGenerationError); m_errorReporter.error(_error.errorId(), _error.type(), SourceLocation(), _error.what()); - return false; } catch (UnimplementedFeatureError const& _error) { reportUnimplementedFeatureError(_error); - return false; } + + if (m_errorReporter.hasErrors()) + return false; } + + solAssert(!m_errorReporter.hasErrors()); m_stackState = CompilationSuccessful; this->link(); return true; @@ -1611,6 +1614,14 @@ void CompilerStack::generateEVMFromIR(ContractDefinition const& _contract) std::string deployedName = IRNames::deployedObject(_contract); solAssert(!deployedName.empty(), ""); tie(compiledContract.evmAssembly, compiledContract.evmRuntimeAssembly) = stack.assembleEVMWithDeployed(deployedName); + + if (stack.hasErrors()) + { + for (std::shared_ptr const& error: stack.errors()) + reportIRPostAnalysisError(error.get()); + return; + } + assembleYul(_contract, compiledContract.evmAssembly, compiledContract.evmRuntimeAssembly); } @@ -2005,6 +2016,27 @@ experimental::Analysis const& CompilerStack::experimentalAnalysis() const void CompilerStack::reportUnimplementedFeatureError(UnimplementedFeatureError const& _error) { - solAssert(_error.comment(), "Unimplemented feature errors must include a message for the user"); + solAssert(_error.comment(), "Errors must include a message for the user."); + m_errorReporter.unimplementedFeatureError(1834_error, _error.sourceLocation(), *_error.comment()); } + +void CompilerStack::reportIRPostAnalysisError(Error const* _error) +{ + solAssert(_error); + solAssert(_error->comment(), "Errors must include a message for the user."); + solAssert(!_error->secondarySourceLocation()); + + // Do not report Yul warnings and infos. These are only reported in pure Yul compilation. + if (!Error::isError(_error->severity())) + return; + + m_errorReporter.error( + _error->errorId(), + _error->type(), + // Ignore the original location. It's likely missing, but even if not, it points at Yul source. + // CompilerStack can only point at locations in Solidity sources. + SourceLocation{}, + *_error->comment() + ); +} diff --git a/libsolidity/interface/CompilerStack.h b/libsolidity/interface/CompilerStack.h index 009103a498f8..81a039403b9b 100644 --- a/libsolidity/interface/CompilerStack.h +++ b/libsolidity/interface/CompilerStack.h @@ -579,6 +579,7 @@ class CompilerStack: public langutil::CharStreamProvider, public evmasm::Abstrac ) const; void reportUnimplementedFeatureError(langutil::UnimplementedFeatureError const& _error); + void reportIRPostAnalysisError(langutil::Error const* _error); ReadCallback::Callback m_readFile; OptimiserSettings m_optimiserSettings; diff --git a/libsolidity/interface/StandardCompiler.cpp b/libsolidity/interface/StandardCompiler.cpp index b5279c624a9e..9357310c07e4 100644 --- a/libsolidity/interface/StandardCompiler.cpp +++ b/libsolidity/interface/StandardCompiler.cpp @@ -1609,9 +1609,35 @@ Json StandardCompiler::compileYul(InputsAndSettings _inputsAndSettings) std::string const& sourceName = _inputsAndSettings.sources.begin()->first; std::string const& sourceContents = _inputsAndSettings.sources.begin()->second; - // Inconsistent state - stop here to receive error reports from users - if (!stack.parseAndAnalyze(sourceName, sourceContents) && !stack.hasErrors()) - solAssert(false, "No error reported, but parsing/analysis failed."); + std::string contractName; + bool const wildcardMatchesExperimental = true; + MachineAssemblyObject object; + MachineAssemblyObject deployedObject; + + bool successful = stack.parseAndAnalyze(sourceName, sourceContents); + if (!successful) + // Inconsistent state - stop here to receive error reports from users + solAssert(stack.hasErrors(), "No error reported, but parsing/analysis failed."); + else + { + contractName = stack.parserResult()->name; + if (isArtifactRequested(_inputsAndSettings.outputSelection, sourceName, contractName, "ir", wildcardMatchesExperimental)) + output["contracts"][sourceName][contractName]["ir"] = stack.print(); + + if (isArtifactRequested(_inputsAndSettings.outputSelection, sourceName, contractName, "ast", wildcardMatchesExperimental)) + { + Json sourceResult; + sourceResult["id"] = 0; + sourceResult["ast"] = stack.astJson(); + output["sources"][sourceName] = sourceResult; + } + stack.optimize(); + std::tie(object, deployedObject) = stack.assembleWithDeployed(); + if (object.bytecode) + object.bytecode->link(_inputsAndSettings.libraries); + if (deployedObject.bytecode) + deployedObject.bytecode->link(_inputsAndSettings.libraries); + } for (auto const& error: stack.errors()) { @@ -1628,30 +1654,6 @@ Json StandardCompiler::compileYul(InputsAndSettings _inputsAndSettings) if (stack.hasErrors()) return output; - std::string contractName = stack.parserResult()->name; - - bool const wildcardMatchesExperimental = true; - if (isArtifactRequested(_inputsAndSettings.outputSelection, sourceName, contractName, "ir", wildcardMatchesExperimental)) - output["contracts"][sourceName][contractName]["ir"] = stack.print(); - - if (isArtifactRequested(_inputsAndSettings.outputSelection, sourceName, contractName, "ast", wildcardMatchesExperimental)) - { - Json sourceResult; - sourceResult["id"] = 0; - sourceResult["ast"] = stack.astJson(); - output["sources"][sourceName] = sourceResult; - } - stack.optimize(); - - MachineAssemblyObject object; - MachineAssemblyObject deployedObject; - std::tie(object, deployedObject) = stack.assembleWithDeployed(); - - if (object.bytecode) - object.bytecode->link(_inputsAndSettings.libraries); - if (deployedObject.bytecode) - deployedObject.bytecode->link(_inputsAndSettings.libraries); - for (auto&& [kind, isDeployed]: {make_pair("bytecode"s, false), make_pair("deployedBytecode"s, true)}) if (isArtifactRequested( _inputsAndSettings.outputSelection, diff --git a/libyul/YulStack.cpp b/libyul/YulStack.cpp index 97c67d3b58ad..caa1bef87953 100644 --- a/libyul/YulStack.cpp +++ b/libyul/YulStack.cpp @@ -249,9 +249,14 @@ MachineAssemblyObject YulStack::assemble(Machine _machine) std::pair YulStack::assembleWithDeployed(std::optional _deployName) { + yulAssert(m_charStream); + auto [creationAssembly, deployedAssembly] = assembleEVMWithDeployed(_deployName); - yulAssert(creationAssembly, ""); - yulAssert(m_charStream, ""); + if (!creationAssembly) + { + yulAssert(!deployedAssembly); + return {MachineAssemblyObject{}, MachineAssemblyObject{}}; + } MachineAssemblyObject creationObject; MachineAssemblyObject deployedObject; @@ -285,6 +290,7 @@ YulStack::assembleWithDeployed(std::optional _deployName) catch (UnimplementedFeatureError const& _error) { reportUnimplementedFeatureError(_error); + return {MachineAssemblyObject{}, MachineAssemblyObject{}}; } return {std::move(creationObject), std::move(deployedObject)}; @@ -341,9 +347,10 @@ YulStack::assembleEVMWithDeployed(std::optional _deployName) catch (UnimplementedFeatureError const& _error) { reportUnimplementedFeatureError(_error); + return {nullptr, nullptr}; } - return {std::make_shared(assembly), {}}; + return {std::make_shared(assembly), nullptr}; } std::string YulStack::print() const @@ -415,6 +422,6 @@ std::shared_ptr YulStack::parserResult() const void YulStack::reportUnimplementedFeatureError(UnimplementedFeatureError const& _error) { - solAssert(_error.comment(), "Unimplemented feature errors must include a message for the user"); + yulAssert(_error.comment(), "Errors must include a message for the user."); m_errorReporter.unimplementedFeatureError(1920_error, _error.sourceLocation(), *_error.comment()); } diff --git a/solc/CommandLineInterface.cpp b/solc/CommandLineInterface.cpp index 4816ee531c07..f2bb4af107bb 100644 --- a/solc/CommandLineInterface.cpp +++ b/solc/CommandLineInterface.cpp @@ -1232,9 +1232,10 @@ void CommandLineInterface::assembleYul(yul::YulStack::Language _language, yul::Y bool successful = true; std::map yulStacks; - for (auto const& src: m_fileReader.sourceUnits()) + std::map objects; + for (auto const& [sourceUnitName, yulSource]: m_fileReader.sourceUnits()) { - auto& stack = yulStacks[src.first] = yul::YulStack( + auto& stack = yulStacks[sourceUnitName] = yul::YulStack( m_options.output.evmVersion, m_options.output.eofVersion, _language, @@ -1244,20 +1245,28 @@ void CommandLineInterface::assembleYul(yul::YulStack::Language _language, yul::Y DebugInfoSelection::Default() ); - if (!stack.parseAndAnalyze(src.first, src.second)) - successful = false; + successful = successful && stack.parseAndAnalyze(sourceUnitName, yulSource); + if (!successful) + solAssert(stack.hasErrors(), "No error reported, but parsing/analysis failed."); else - stack.optimize(); - - if (successful && m_options.compiler.outputs.asmJson) { - std::shared_ptr result = stack.parserResult(); - if (result && !result->hasContiguousSourceIndices()) + if ( + m_options.compiler.outputs.asmJson && + stack.parserResult() && + !stack.parserResult()->hasContiguousSourceIndices() + ) solThrow( CommandLineExecutionError, "Generating the assembly JSON output was not possible. " "Source indices provided in the @use-src annotation in the Yul input do not start at 0 or are not contiguous." ); + + stack.optimize(); + + yul::MachineAssemblyObject object = stack.assemble(_targetMachine); + if (object.bytecode) + object.bytecode->link(m_options.linker.libraries); + objects.insert({sourceUnitName, std::move(object)}); } } @@ -1281,13 +1290,14 @@ void CommandLineInterface::assembleYul(yul::YulStack::Language _language, yul::Y solThrow(CommandLineExecutionError, ""); } - for (auto const& src: m_fileReader.sourceUnits()) + for (auto const& [sourceUnitName, yulSource]: m_fileReader.sourceUnits()) { solAssert(_targetMachine == yul::YulStack::Machine::EVM); std::string machine = "EVM"; - sout() << std::endl << "======= " << src.first << " (" << machine << ") =======" << std::endl; + sout() << std::endl << "======= " << sourceUnitName << " (" << machine << ") =======" << std::endl; - yul::YulStack& stack = yulStacks[src.first]; + yul::YulStack const& stack = yulStacks[sourceUnitName]; + yul::MachineAssemblyObject const& object = objects[sourceUnitName]; if (m_options.compiler.outputs.irOptimized) { @@ -1297,10 +1307,6 @@ void CommandLineInterface::assembleYul(yul::YulStack::Language _language, yul::Y sout() << stack.print() << std::endl; } - yul::MachineAssemblyObject object; - object = stack.assemble(_targetMachine); - object.bytecode->link(m_options.linker.libraries); - if (m_options.compiler.outputs.binary) { sout() << std::endl << "Binary representation:" << std::endl; diff --git a/test/libyul/ObjectCompilerTest.cpp b/test/libyul/ObjectCompilerTest.cpp index 126c3ad6f691..d507aa333b06 100644 --- a/test/libyul/ObjectCompilerTest.cpp +++ b/test/libyul/ObjectCompilerTest.cpp @@ -71,18 +71,22 @@ TestCase::TestResult ObjectCompilerTest::run(std::ostream& _stream, std::string OptimiserSettings::preset(m_optimisationPreset), DebugInfoSelection::All() ); - if (!stack.parseAndAnalyze("source", m_source)) + bool successful = stack.parseAndAnalyze("source", m_source); + MachineAssemblyObject obj; + if (successful) + { + stack.optimize(); + obj = stack.assemble(YulStack::Machine::EVM); + } + if (stack.hasErrors()) { AnsiColorized(_stream, _formatted, {formatting::BOLD, formatting::RED}) << _linePrefix << "Error parsing source." << std::endl; SourceReferenceFormatter{_stream, stack, true, false} .printErrorInformation(stack.errors()); return TestResult::FatalError; } - stack.optimize(); - - MachineAssemblyObject obj = stack.assemble(YulStack::Machine::EVM); - solAssert(obj.bytecode, ""); - solAssert(obj.sourceMappings, ""); + solAssert(obj.bytecode); + solAssert(obj.sourceMappings); m_obtainedResult = "Assembly:\n" + obj.assembly->assemblyString(stack.debugInfoSelection()); if (obj.bytecode->bytecode.empty()) From 65130cdee2e2a68285c75a7910e5a0cb573f2eb2 Mon Sep 17 00:00:00 2001 From: rodiazet Date: Tue, 10 Dec 2024 12:21:54 +0100 Subject: [PATCH 0640/1022] eof: Fix immutables for EOF. Pass `m_immutablesVariables` and `m_libraryAddressOffset` to `Deployed` context of IRGenerationContext for EOF --- libsolidity/codegen/ir/IRGenerationContext.cpp | 10 +++++++++- libsolidity/codegen/ir/IRGenerationContext.h | 15 ++++++++++++++- libsolidity/codegen/ir/IRGenerator.cpp | 14 ++++++++++++++ test/libsolidity/semanticTests/immutable/stub.sol | 2 ++ 4 files changed, 39 insertions(+), 2 deletions(-) diff --git a/libsolidity/codegen/ir/IRGenerationContext.cpp b/libsolidity/codegen/ir/IRGenerationContext.cpp index fd47fec10184..89ce999492fc 100644 --- a/libsolidity/codegen/ir/IRGenerationContext.cpp +++ b/libsolidity/codegen/ir/IRGenerationContext.cpp @@ -87,6 +87,7 @@ void IRGenerationContext::resetLocalVariables() void IRGenerationContext::registerImmutableVariable(VariableDeclaration const& _variable) { + solAssert(m_executionContext != ExecutionContext::Deployed); solAssert(_variable.immutable(), "Attempted to register a non-immutable variable as immutable."); solUnimplementedAssert( _variable.annotation().type->isValueType(), @@ -122,6 +123,7 @@ size_t IRGenerationContext::reservedMemorySize() const void IRGenerationContext::registerLibraryAddressImmutable() { + solAssert(m_executionContext != ExecutionContext::Deployed); solAssert(m_reservedMemory.has_value(), "Reserved memory has already been reset."); solAssert(!m_libraryAddressImmutableOffset.has_value()); m_libraryAddressImmutableOffset = CompilerUtils::generalPurposeMemoryStart + *m_reservedMemory; @@ -156,7 +158,13 @@ size_t IRGenerationContext::reservedMemory() immutableVariablesSize += var->type()->sizeOnStack() * 32; } - solAssert(immutableVariablesSize == reservedMemory); + // In Creation context check that only immutable variables or library address are stored in the reserved memory. + // In Deployed context (for EOF) m_immutableVariables contains offsets in EOF data section. + solAssert( + (m_executionContext == ExecutionContext::Creation && + reservedMemory == immutableVariablesSize + (m_libraryAddressImmutableOffset.has_value() ? 32 : 0)) || + (m_executionContext == ExecutionContext::Deployed && reservedMemory == 0) + ); m_reservedMemory = std::nullopt; return reservedMemory; diff --git a/libsolidity/codegen/ir/IRGenerationContext.h b/libsolidity/codegen/ir/IRGenerationContext.h index 01220e87b86d..1a995734d28d 100644 --- a/libsolidity/codegen/ir/IRGenerationContext.h +++ b/libsolidity/codegen/ir/IRGenerationContext.h @@ -165,6 +165,19 @@ class IRGenerationContext langutil::DebugInfoSelection debugInfoSelection() const { return m_debugInfoSelection; } langutil::CharStreamProvider const* soliditySourceProvider() const { return m_soliditySourceProvider; } + std::map const& immutableVariables() const { return m_immutableVariables; } + void setImmutableVariables(std::map _immutableVariables) + { + solAssert(m_eofVersion.has_value()); + solAssert(m_executionContext == ExecutionContext::Deployed); + m_immutableVariables = std::move(_immutableVariables); + } + void setLibraryAddressImmutableOffset(size_t _libraryAddressImmutableOffset) + { + solAssert(m_eofVersion.has_value()); + solAssert(m_executionContext == ExecutionContext::Deployed); + m_libraryAddressImmutableOffset = _libraryAddressImmutableOffset; + } private: langutil::EVMVersion m_evmVersion; @@ -176,7 +189,7 @@ class IRGenerationContext ContractDefinition const* m_mostDerivedContract = nullptr; std::map m_localVariables; /// Memory offsets reserved for the values of immutable variables during contract creation. - /// This map is empty in the runtime context. + /// This map is empty in the legacy runtime context and may be not empty in EOF runtime context. std::map m_immutableVariables; std::optional m_libraryAddressImmutableOffset; /// Total amount of reserved memory. Reserved memory is used to store diff --git a/libsolidity/codegen/ir/IRGenerator.cpp b/libsolidity/codegen/ir/IRGenerator.cpp index 688ab258a94d..e8bb7a87436f 100644 --- a/libsolidity/codegen/ir/IRGenerator.cpp +++ b/libsolidity/codegen/ir/IRGenerator.cpp @@ -197,8 +197,21 @@ std::string IRGenerator::generate( t("memoryInitCreation", memoryInit(!creationInvolvesMemoryUnsafeAssembly)); t("useSrcMapCreation", formatUseSrcMap(m_context)); + auto const immutableVariables = m_context.immutableVariables(); + auto const libraryAddressImmutableOffset = (_contract.isLibrary() && eof) ? + m_context.libraryAddressImmutableOffset() : 0; + resetContext(_contract, ExecutionContext::Deployed); + // When generating to EOF we have to initialize these two members, because they store offsets in EOF data section + // which is used during deployed container generation + if (m_eofVersion.has_value()) + { + m_context.setImmutableVariables(std::move(immutableVariables)); + if (_contract.isLibrary()) + m_context.setLibraryAddressImmutableOffset(libraryAddressImmutableOffset); + } + // NOTE: Function pointers can be passed from creation code via storage variables. We need to // get all the functions they could point to into the dispatch functions even if they're never // referenced by name in the deployed code. @@ -1153,6 +1166,7 @@ void IRGenerator::resetContext(ContractDefinition const& _contract, ExecutionCon m_context.debugInfoSelection(), m_context.soliditySourceProvider() ); + m_context = std::move(newContext); m_context.setMostDerivedContract(_contract); diff --git a/test/libsolidity/semanticTests/immutable/stub.sol b/test/libsolidity/semanticTests/immutable/stub.sol index 092edfab4fa8..c528b1aa7c0e 100644 --- a/test/libsolidity/semanticTests/immutable/stub.sol +++ b/test/libsolidity/semanticTests/immutable/stub.sol @@ -9,5 +9,7 @@ contract C { return (x+x,y); } } +// ==== +// bytecodeFormat: legacy,>=EOFv1 // ---- // f() -> 84, 23 From b3bf85e44799440018c174787e71e6be56dc4994 Mon Sep 17 00:00:00 2001 From: rodiazet Date: Wed, 11 Dec 2024 15:33:27 +0100 Subject: [PATCH 0641/1022] eof: Enable `ext*call`s unavailability test for EOF and legacy bytecode format. --- test/libyul/yulSyntaxTests/eof/callf_jumpf_retf.yul | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/libyul/yulSyntaxTests/eof/callf_jumpf_retf.yul b/test/libyul/yulSyntaxTests/eof/callf_jumpf_retf.yul index 2dcd04ca62a2..1d8ae6ddc588 100644 --- a/test/libyul/yulSyntaxTests/eof/callf_jumpf_retf.yul +++ b/test/libyul/yulSyntaxTests/eof/callf_jumpf_retf.yul @@ -5,6 +5,8 @@ object "a" { retf() } } +// ==== +// bytecodeFormat: legacy,>=EOFv1 // ---- // DeclarationError 4619: (32-37): Function "callf" not found. // DeclarationError 4619: (48-53): Function "jumpf" not found. From 72715f1b2cc7de8f30b012df5ae1a3a5f38ea0e0 Mon Sep 17 00:00:00 2001 From: rodiazet Date: Tue, 10 Dec 2024 12:15:03 +0100 Subject: [PATCH 0642/1022] eof: Fix subassembly references in parent object --- libevmasm/Assembly.cpp | 11 ++++++++++- .../semanticTests/libraries/library_address.sol | 1 + 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/libevmasm/Assembly.cpp b/libevmasm/Assembly.cpp index 12bb3cccc13c..1fe4fa7d97b8 100644 --- a/libevmasm/Assembly.cpp +++ b/libevmasm/Assembly.cpp @@ -1657,7 +1657,16 @@ LinkerObject const& Assembly::assembleEOF() const } for (auto i: referencedSubIds) - ret.bytecode += m_subs[i]->assemble().bytecode; + { + size_t const subAssemblyPostionInParentObject = ret.bytecode.size(); + auto const& subAssemblyLinkerObject = m_subs[i]->assemble(); + // Append subassembly bytecode to the parent assembly result bytecode + ret.bytecode += subAssemblyLinkerObject.bytecode; + // Add subassembly link references to parent linker object. + // Offset accordingly to subassembly position in parent object bytecode + for (auto const& [subAssemblyLinkRefPosition, linkRef]: subAssemblyLinkerObject.linkReferences) + ret.linkReferences[subAssemblyPostionInParentObject + subAssemblyLinkRefPosition] = linkRef; + } // TODO: Fill functionDebugData for EOF. It probably should be handled for new code section in the loop above. solRequire(m_namedTags.empty(), AssemblyException, "Named tags must be empty in EOF context."); diff --git a/test/libsolidity/semanticTests/libraries/library_address.sol b/test/libsolidity/semanticTests/libraries/library_address.sol index 6ca064445012..af3a45a97304 100644 --- a/test/libsolidity/semanticTests/libraries/library_address.sol +++ b/test/libsolidity/semanticTests/libraries/library_address.sol @@ -36,6 +36,7 @@ contract C { } // ==== // EVMVersion: >=byzantium +// bytecodeFormat: legacy,>=EOFv1 // ---- // library: L // addr() -> false From e6bca7308b3ec86abbcf1e837aca2b5d2b169a90 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Thu, 12 Dec 2024 10:54:36 +0100 Subject: [PATCH 0643/1022] Yul CFG Builder: Fix ghost call function name --- libyul/backends/evm/ControlFlowGraphBuilder.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libyul/backends/evm/ControlFlowGraphBuilder.cpp b/libyul/backends/evm/ControlFlowGraphBuilder.cpp index 990456732bb9..cce5c98557e2 100644 --- a/libyul/backends/evm/ControlFlowGraphBuilder.cpp +++ b/libyul/backends/evm/ControlFlowGraphBuilder.cpp @@ -364,7 +364,7 @@ void ControlFlowGraphBuilder::operator()(Switch const& _switch) auto makeValueCompare = [&](Case const& _case) { yul::FunctionCall const& ghostCall = m_graph.ghostCalls.emplace_back(yul::FunctionCall{ debugDataOf(_case), - yul::Identifier{{}, "eq"_yulname}, + BuiltinName{{}, *equalityBuiltinHandle}, {*_case.value, Identifier{{}, ghostVariableName}} }); BuiltinFunction const& equalityBuiltin = m_dialect.builtin(*equalityBuiltinHandle); From 834e9ada0bc80d8ea3f8e07cba294c3622c360d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Wed, 4 Dec 2024 04:04:55 +0100 Subject: [PATCH 0644/1022] Failing tests testing proper handling of CodeGenerationError in Yul --- .../standard_yul_code_generation_error/args | 1 + .../standard_yul_code_generation_error/in.yul | 9 +++++++++ .../standard_yul_code_generation_error/input.json | 6 ++++++ .../standard_yul_code_generation_error/output.json | 13 +++++++++++++ .../strict_asm_code_generation_error/args | 1 + .../strict_asm_code_generation_error/err | 1 + .../strict_asm_code_generation_error/exit | 1 + .../strict_asm_code_generation_error/input.yul | 9 +++++++++ 8 files changed, 41 insertions(+) create mode 100644 test/cmdlineTests/standard_yul_code_generation_error/args create mode 100644 test/cmdlineTests/standard_yul_code_generation_error/in.yul create mode 100644 test/cmdlineTests/standard_yul_code_generation_error/input.json create mode 100644 test/cmdlineTests/standard_yul_code_generation_error/output.json create mode 100644 test/cmdlineTests/strict_asm_code_generation_error/args create mode 100644 test/cmdlineTests/strict_asm_code_generation_error/err create mode 100644 test/cmdlineTests/strict_asm_code_generation_error/exit create mode 100644 test/cmdlineTests/strict_asm_code_generation_error/input.yul diff --git a/test/cmdlineTests/standard_yul_code_generation_error/args b/test/cmdlineTests/standard_yul_code_generation_error/args new file mode 100644 index 000000000000..18532c5a6d3f --- /dev/null +++ b/test/cmdlineTests/standard_yul_code_generation_error/args @@ -0,0 +1 @@ +--allow-paths . diff --git a/test/cmdlineTests/standard_yul_code_generation_error/in.yul b/test/cmdlineTests/standard_yul_code_generation_error/in.yul new file mode 100644 index 000000000000..2bf18f0c6d4d --- /dev/null +++ b/test/cmdlineTests/standard_yul_code_generation_error/in.yul @@ -0,0 +1,9 @@ +object "C" { + code {} + + object "C_deployed" { + code { + sstore(0, loadimmutable("1")) + } + } +} diff --git a/test/cmdlineTests/standard_yul_code_generation_error/input.json b/test/cmdlineTests/standard_yul_code_generation_error/input.json new file mode 100644 index 000000000000..905eef6c758a --- /dev/null +++ b/test/cmdlineTests/standard_yul_code_generation_error/input.json @@ -0,0 +1,6 @@ +{ + "language": "Yul", + "sources": { + "C": {"urls": ["standard_yul_code_generation_error/in.yul"]} + } +} diff --git a/test/cmdlineTests/standard_yul_code_generation_error/output.json b/test/cmdlineTests/standard_yul_code_generation_error/output.json new file mode 100644 index 000000000000..9bd38bbacf31 --- /dev/null +++ b/test/cmdlineTests/standard_yul_code_generation_error/output.json @@ -0,0 +1,13 @@ +{ + "errors": [ + { + "component": "general", + "formattedMessage": "CodeGenerationError: Some immutables were read from but never assigned, possibly because of optimization. + +", + "message": "Some immutables were read from but never assigned, possibly because of optimization.", + "severity": "error", + "type": "CodeGenerationError" + } + ] +} diff --git a/test/cmdlineTests/strict_asm_code_generation_error/args b/test/cmdlineTests/strict_asm_code_generation_error/args new file mode 100644 index 000000000000..47be2b30ed16 --- /dev/null +++ b/test/cmdlineTests/strict_asm_code_generation_error/args @@ -0,0 +1 @@ +--strict-assembly --bin diff --git a/test/cmdlineTests/strict_asm_code_generation_error/err b/test/cmdlineTests/strict_asm_code_generation_error/err new file mode 100644 index 000000000000..31af508c7b40 --- /dev/null +++ b/test/cmdlineTests/strict_asm_code_generation_error/err @@ -0,0 +1 @@ +Error: Some immutables were read from but never assigned, possibly because of optimization. diff --git a/test/cmdlineTests/strict_asm_code_generation_error/exit b/test/cmdlineTests/strict_asm_code_generation_error/exit new file mode 100644 index 000000000000..d00491fd7e5b --- /dev/null +++ b/test/cmdlineTests/strict_asm_code_generation_error/exit @@ -0,0 +1 @@ +1 diff --git a/test/cmdlineTests/strict_asm_code_generation_error/input.yul b/test/cmdlineTests/strict_asm_code_generation_error/input.yul new file mode 100644 index 000000000000..2bf18f0c6d4d --- /dev/null +++ b/test/cmdlineTests/strict_asm_code_generation_error/input.yul @@ -0,0 +1,9 @@ +object "C" { + code {} + + object "C_deployed" { + code { + sstore(0, loadimmutable("1")) + } + } +} From 47545d3c3ac66547e279fdff0b08e4abdf92b65e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Fri, 29 Nov 2024 20:07:26 +0100 Subject: [PATCH 0645/1022] Accept throwing as the standard mechanism for reporting errors during code generation --- Changelog.md | 1 + liblangutil/ErrorReporter.cpp | 17 +++++++++++++++++ liblangutil/ErrorReporter.h | 3 +++ libsolidity/interface/CompilerStack.cpp | 6 +----- libyul/YulStack.cpp | 10 ++++++++++ libyul/YulStack.h | 2 ++ 6 files changed, 34 insertions(+), 5 deletions(-) diff --git a/Changelog.md b/Changelog.md index 29b5870bc8fa..9aaa1ca8b022 100644 --- a/Changelog.md +++ b/Changelog.md @@ -10,6 +10,7 @@ Compiler Features: Bugfixes: * General: Fix internal compiler error when requesting IR AST outputs for interfaces and abstract contracts. * Standard JSON Interface: Fix ``generatedSources`` and ``sourceMap`` being generated internally even when not requested. +* Yul: Fix internal compiler error when a code generation error should be reported instead. ### 0.8.28 (2024-10-09) diff --git a/liblangutil/ErrorReporter.cpp b/liblangutil/ErrorReporter.cpp index ddb6b70d1253..8c8bb7ab05b8 100644 --- a/liblangutil/ErrorReporter.cpp +++ b/liblangutil/ErrorReporter.cpp @@ -273,6 +273,23 @@ void ErrorReporter::unimplementedFeatureError(ErrorId _error, SourceLocation con ); } +void ErrorReporter::codeGenerationError(ErrorId _error, SourceLocation const& _location, std::string const& _description) +{ + error(_error, Error::Type::CodeGenerationError, _location, _description); +} + +void ErrorReporter::codeGenerationError(Error const& _error) +{ + solAssert(_error.type() == Error::Type::CodeGenerationError); + solAssert(_error.comment(), "Errors must include a message for the user."); + solUnimplementedAssert(!_error.secondarySourceLocation(), "Secondary locations not supported yet."); + codeGenerationError( + _error.errorId(), + _error.sourceLocation() ? *_error.sourceLocation() : SourceLocation{}, + *_error.comment() + ); +} + void ErrorReporter::info( ErrorId _error, SourceLocation const& _location, diff --git a/liblangutil/ErrorReporter.h b/liblangutil/ErrorReporter.h index 989cc4d5e3a0..55e4d56216b7 100644 --- a/liblangutil/ErrorReporter.h +++ b/liblangutil/ErrorReporter.h @@ -120,6 +120,9 @@ class ErrorReporter void unimplementedFeatureError(ErrorId _error, SourceLocation const& _location, std::string const& _description); + void codeGenerationError(ErrorId _error, SourceLocation const& _location, std::string const& _description); + void codeGenerationError(Error const& _error); + ErrorList const& errors() const; void clear(); diff --git a/libsolidity/interface/CompilerStack.cpp b/libsolidity/interface/CompilerStack.cpp index 6a50b04c5d28..9649b79c842a 100644 --- a/libsolidity/interface/CompilerStack.cpp +++ b/libsolidity/interface/CompilerStack.cpp @@ -779,11 +779,7 @@ bool CompilerStack::compile(State _stopAfter) } catch (Error const& _error) { - // Since codegen has no access to the error reporter, the only way for it to - // report an error is to throw. In most cases it uses dedicated exceptions, - // but CodeGenerationError is one case where someone decided to just throw Error. - solAssert(_error.type() == Error::Type::CodeGenerationError); - m_errorReporter.error(_error.errorId(), _error.type(), SourceLocation(), _error.what()); + m_errorReporter.codeGenerationError(_error); } catch (UnimplementedFeatureError const& _error) { diff --git a/libyul/YulStack.cpp b/libyul/YulStack.cpp index caa1bef87953..dfab4b6878c0 100644 --- a/libyul/YulStack.cpp +++ b/libyul/YulStack.cpp @@ -287,6 +287,11 @@ YulStack::assembleWithDeployed(std::optional _deployName) ); } } + catch (Error const& _error) + { + m_errorReporter.codeGenerationError(_error); + return {MachineAssemblyObject{}, MachineAssemblyObject{}}; + } catch (UnimplementedFeatureError const& _error) { reportUnimplementedFeatureError(_error); @@ -344,6 +349,11 @@ YulStack::assembleEVMWithDeployed(std::optional _deployName) return {std::make_shared(assembly), std::make_shared(runtimeAssembly)}; } } + catch (Error const& _error) + { + m_errorReporter.codeGenerationError(_error); + return {nullptr, nullptr}; + } catch (UnimplementedFeatureError const& _error) { reportUnimplementedFeatureError(_error); diff --git a/libyul/YulStack.h b/libyul/YulStack.h index de391f591044..f9837e553ed4 100644 --- a/libyul/YulStack.h +++ b/libyul/YulStack.h @@ -25,6 +25,8 @@ #include #include #include +#include + #include #include From 287c05cd1b697114b7696ed7d4cda3a29d39d649 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Mon, 16 Dec 2024 09:22:11 +0100 Subject: [PATCH 0646/1022] Testing: Add "current" evm version setting to tests --- test/TestCase.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/test/TestCase.cpp b/test/TestCase.cpp index 942153d3cd6c..9505a2caafe5 100644 --- a/test/TestCase.cpp +++ b/test/TestCase.cpp @@ -114,7 +114,11 @@ void EVMVersionRestrictedTestCase::processEVMVersionSetting() break; versionString = versionString.substr(versionBegin); - std::optional version = langutil::EVMVersion::fromString(versionString); + std::optional version; + if (versionString == "current") + version = std::make_optional(); + else + version = langutil::EVMVersion::fromString(versionString); if (!version) BOOST_THROW_EXCEPTION(std::runtime_error{"Invalid EVM version: \"" + versionString + "\""}); From 20644423ed80d8dc35aafd7182eae24b10283860 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Thu, 12 Dec 2024 08:58:25 +0100 Subject: [PATCH 0647/1022] EVMCodeTransformTest: Restrict to current version --- test/libyul/EVMCodeTransformTest.cpp | 5 ++--- test/libyul/evmCodeTransform/after_terminating_function.yul | 1 + test/libyul/evmCodeTransform/early_push_on_deep_swap.yul | 1 + test/libyul/evmCodeTransform/literal_loop.yul | 1 + test/libyul/evmCodeTransform/nonempty_initial_layout.yul | 1 + test/libyul/evmCodeTransform/pops_in_reverting_branch.yul | 1 + test/libyul/evmCodeTransform/stackReuse/for_1.yul | 1 + test/libyul/evmCodeTransform/stackReuse/for_2.yul | 1 + .../evmCodeTransform/stackReuse/function_argument_reuse.yul | 1 + test/libyul/evmCodeTransform/stackReuse/function_call.yul | 1 + .../evmCodeTransform/stackReuse/function_many_arguments.yul | 1 + test/libyul/evmCodeTransform/stackReuse/function_params.yul | 1 + .../stackReuse/function_params_and_retparams.yul | 1 + .../stackReuse/function_params_and_retparams_partly_used.yul | 1 + .../libyul/evmCodeTransform/stackReuse/function_retparam.yul | 1 + .../evmCodeTransform/stackReuse/function_retparam_block.yul | 1 + .../stackReuse/function_retparam_declaration.yul | 1 + .../evmCodeTransform/stackReuse/function_retparam_for.yul | 1 + .../evmCodeTransform/stackReuse/function_retparam_if.yul | 1 + .../evmCodeTransform/stackReuse/function_retparam_leave.yul | 1 + .../evmCodeTransform/stackReuse/function_retparam_read.yul | 1 + .../stackReuse/function_retparam_unassigned.yul | 1 + .../stackReuse/function_retparam_unassigned_multiple.yul | 1 + test/libyul/evmCodeTransform/stackReuse/function_trivial.yul | 1 + .../stackReuse/function_with_body_embedded.yul | 1 + .../evmCodeTransform/stackReuse/functions_multi_return.yul | 1 + test/libyul/evmCodeTransform/stackReuse/if.yul | 1 + .../evmCodeTransform/stackReuse/last_use_in_nested_block.yul | 1 + .../stackReuse/multi_reuse_same_variable_name.yul | 1 + .../evmCodeTransform/stackReuse/multi_reuse_single_slot.yul | 1 + .../stackReuse/multi_reuse_single_slot_nested.yul | 1 + .../stackReuse/reuse_on_decl_assign_not_same_scope.yul | 1 + .../stackReuse/reuse_on_decl_assign_to_last_used.yul | 1 + .../stackReuse/reuse_on_decl_assign_to_last_used_expr.yul | 1 + .../stackReuse/reuse_on_decl_assign_to_not_last_used.yul | 1 + test/libyul/evmCodeTransform/stackReuse/reuse_slots.yul | 1 + .../evmCodeTransform/stackReuse/reuse_slots_function.yul | 1 + .../stackReuse/reuse_slots_function_with_gaps.yul | 1 + .../evmCodeTransform/stackReuse/reuse_too_deep_slot.yul | 1 + test/libyul/evmCodeTransform/stackReuse/single_var.yul | 1 + .../evmCodeTransform/stackReuse/single_var_assigned.yul | 1 + .../stackReuse/single_var_assigned_plus_code.yul | 1 + .../stackReuse/single_var_assigned_plus_code_and_reused.yul | 1 + test/libyul/evmCodeTransform/stackReuse/smoke.yul | 1 + test/libyul/evmCodeTransform/stackReuse/switch.yul | 1 + test/libyul/evmCodeTransform/stub.yul | 1 + test/libyul/evmCodeTransform/unassigned_return_variable.yul | 1 + 47 files changed, 48 insertions(+), 3 deletions(-) diff --git a/test/libyul/EVMCodeTransformTest.cpp b/test/libyul/EVMCodeTransformTest.cpp index 288c35570fe8..3d80281c7d91 100644 --- a/test/libyul/EVMCodeTransformTest.cpp +++ b/test/libyul/EVMCodeTransformTest.cpp @@ -46,7 +46,6 @@ EVMCodeTransformTest::EVMCodeTransformTest(std::string const& _filename): m_source = m_reader.source(); m_stackOpt = m_reader.boolSetting("stackOptimization", false); m_expectation = m_reader.simpleExpectations(); - m_shouldRun = CommonOptions::get().evmDialect().evmVersion() == EVMVersion{}; } TestCase::TestResult EVMCodeTransformTest::run(std::ostream& _stream, std::string const& _linePrefix, bool const _formatted) @@ -57,8 +56,8 @@ TestCase::TestResult EVMCodeTransformTest::run(std::ostream& _stream, std::strin // Restrict to a single EVM/EOF version combination (the default one) as code generation // can be different from version to version. YulStack stack( - EVMVersion{}, - std::nullopt, + CommonOptions::get().evmVersion(), + CommonOptions::get().eofVersion(), YulStack::Language::StrictAssembly, settings, DebugInfoSelection::All() diff --git a/test/libyul/evmCodeTransform/after_terminating_function.yul b/test/libyul/evmCodeTransform/after_terminating_function.yul index ee32b4431579..7baa751c3c0f 100644 --- a/test/libyul/evmCodeTransform/after_terminating_function.yul +++ b/test/libyul/evmCodeTransform/after_terminating_function.yul @@ -5,6 +5,7 @@ } // ==== // stackOptimization: true +// EVMVersion: =current // ---- // /* "":17:18 */ // 0x02 diff --git a/test/libyul/evmCodeTransform/early_push_on_deep_swap.yul b/test/libyul/evmCodeTransform/early_push_on_deep_swap.yul index 5e119cc73f8f..3d9d55e7822b 100644 --- a/test/libyul/evmCodeTransform/early_push_on_deep_swap.yul +++ b/test/libyul/evmCodeTransform/early_push_on_deep_swap.yul @@ -3,6 +3,7 @@ } // ==== // stackOptimization: true +// EVMVersion: =current // ---- // /* "":1027:1092 */ // 0x0100000000000000000000000000000000000000000000000000000000000001 diff --git a/test/libyul/evmCodeTransform/literal_loop.yul b/test/libyul/evmCodeTransform/literal_loop.yul index d743836cbcdb..060d0f428f64 100644 --- a/test/libyul/evmCodeTransform/literal_loop.yul +++ b/test/libyul/evmCodeTransform/literal_loop.yul @@ -14,6 +14,7 @@ object "main" { } // ==== // stackOptimization: true +// EVMVersion: =current // ---- // /* "":62:82 */ // dataSize(sub_0) diff --git a/test/libyul/evmCodeTransform/nonempty_initial_layout.yul b/test/libyul/evmCodeTransform/nonempty_initial_layout.yul index eb1a787c061f..df22777245e6 100644 --- a/test/libyul/evmCodeTransform/nonempty_initial_layout.yul +++ b/test/libyul/evmCodeTransform/nonempty_initial_layout.yul @@ -3,6 +3,7 @@ } // ==== // stackOptimization: true +// EVMVersion: =current // ---- // /* "":9:69 */ // 0x2000000000000000000000000000000000000000000000000000000000 diff --git a/test/libyul/evmCodeTransform/pops_in_reverting_branch.yul b/test/libyul/evmCodeTransform/pops_in_reverting_branch.yul index 78bf0a168268..5c1f027a47eb 100644 --- a/test/libyul/evmCodeTransform/pops_in_reverting_branch.yul +++ b/test/libyul/evmCodeTransform/pops_in_reverting_branch.yul @@ -10,6 +10,7 @@ object "main" { } // ==== // stackOptimization: true +// EVMVersion: =current // ---- // /* "":51:52 */ // 0x00 diff --git a/test/libyul/evmCodeTransform/stackReuse/for_1.yul b/test/libyul/evmCodeTransform/stackReuse/for_1.yul index b02710598fd5..92ecf2314055 100644 --- a/test/libyul/evmCodeTransform/stackReuse/for_1.yul +++ b/test/libyul/evmCodeTransform/stackReuse/for_1.yul @@ -1,6 +1,7 @@ { for { let z := 0 } 1 { } { let x := 3 } let t := 2 } // ==== // stackOptimization: true +// EVMVersion: =current // ---- // /* "":17:18 */ // 0x00 diff --git a/test/libyul/evmCodeTransform/stackReuse/for_2.yul b/test/libyul/evmCodeTransform/stackReuse/for_2.yul index 37d372fb9949..20403c5121c1 100644 --- a/test/libyul/evmCodeTransform/stackReuse/for_2.yul +++ b/test/libyul/evmCodeTransform/stackReuse/for_2.yul @@ -1,6 +1,7 @@ { for { let z := 0 } 1 { } { z := 8 let x := 3 } let t := 2 } // ==== // stackOptimization: true +// EVMVersion: =current // ---- // /* "":17:18 */ // 0x00 diff --git a/test/libyul/evmCodeTransform/stackReuse/function_argument_reuse.yul b/test/libyul/evmCodeTransform/stackReuse/function_argument_reuse.yul index 96637da89fc1..c5fea43e809c 100644 --- a/test/libyul/evmCodeTransform/stackReuse/function_argument_reuse.yul +++ b/test/libyul/evmCodeTransform/stackReuse/function_argument_reuse.yul @@ -3,6 +3,7 @@ } // ==== // stackOptimization: true +// EVMVersion: =current // ---- // /* "":0:88 */ // stop diff --git a/test/libyul/evmCodeTransform/stackReuse/function_call.yul b/test/libyul/evmCodeTransform/stackReuse/function_call.yul index 507b354413b6..669d62bb89bb 100644 --- a/test/libyul/evmCodeTransform/stackReuse/function_call.yul +++ b/test/libyul/evmCodeTransform/stackReuse/function_call.yul @@ -5,6 +5,7 @@ } // ==== // stackOptimization: true +// EVMVersion: =current // ---- // /* "":15:22 */ // tag_2 diff --git a/test/libyul/evmCodeTransform/stackReuse/function_many_arguments.yul b/test/libyul/evmCodeTransform/stackReuse/function_many_arguments.yul index 17ccdd3caf39..f92aa29548cf 100644 --- a/test/libyul/evmCodeTransform/stackReuse/function_many_arguments.yul +++ b/test/libyul/evmCodeTransform/stackReuse/function_many_arguments.yul @@ -24,6 +24,7 @@ } // ==== // stackOptimization: true +// EVMVersion: =current // ---- // /* "":0:662 */ // stop diff --git a/test/libyul/evmCodeTransform/stackReuse/function_params.yul b/test/libyul/evmCodeTransform/stackReuse/function_params.yul index e8d9bb30cc1b..4f667cf17124 100644 --- a/test/libyul/evmCodeTransform/stackReuse/function_params.yul +++ b/test/libyul/evmCodeTransform/stackReuse/function_params.yul @@ -3,6 +3,7 @@ } // ==== // stackOptimization: true +// EVMVersion: =current // ---- // /* "":0:28 */ // stop diff --git a/test/libyul/evmCodeTransform/stackReuse/function_params_and_retparams.yul b/test/libyul/evmCodeTransform/stackReuse/function_params_and_retparams.yul index 1d157663a56d..78e78880818f 100644 --- a/test/libyul/evmCodeTransform/stackReuse/function_params_and_retparams.yul +++ b/test/libyul/evmCodeTransform/stackReuse/function_params_and_retparams.yul @@ -7,6 +7,7 @@ } // ==== // stackOptimization: true +// EVMVersion: =current // ---- // /* "":210:252 */ // stop 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 d0fc0506f88c..401b6927fdbf 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 @@ -3,6 +3,7 @@ } // ==== // stackOptimization: true +// EVMVersion: =current // ---- // /* "":0:80 */ // stop diff --git a/test/libyul/evmCodeTransform/stackReuse/function_retparam.yul b/test/libyul/evmCodeTransform/stackReuse/function_retparam.yul index bee0d3f635d9..6dc0cacff95a 100644 --- a/test/libyul/evmCodeTransform/stackReuse/function_retparam.yul +++ b/test/libyul/evmCodeTransform/stackReuse/function_retparam.yul @@ -3,6 +3,7 @@ } // ==== // stackOptimization: true +// EVMVersion: =current // ---- // /* "":0:32 */ // stop diff --git a/test/libyul/evmCodeTransform/stackReuse/function_retparam_block.yul b/test/libyul/evmCodeTransform/stackReuse/function_retparam_block.yul index 5a9e7704e68a..2fad31cc7b02 100644 --- a/test/libyul/evmCodeTransform/stackReuse/function_retparam_block.yul +++ b/test/libyul/evmCodeTransform/stackReuse/function_retparam_block.yul @@ -3,6 +3,7 @@ } // ==== // stackOptimization: true +// EVMVersion: =current // ---- // /* "":0:65 */ // stop diff --git a/test/libyul/evmCodeTransform/stackReuse/function_retparam_declaration.yul b/test/libyul/evmCodeTransform/stackReuse/function_retparam_declaration.yul index 97bffac381a1..8683163931b8 100644 --- a/test/libyul/evmCodeTransform/stackReuse/function_retparam_declaration.yul +++ b/test/libyul/evmCodeTransform/stackReuse/function_retparam_declaration.yul @@ -3,6 +3,7 @@ } // ==== // stackOptimization: true +// EVMVersion: =current // ---- // /* "":0:65 */ // stop diff --git a/test/libyul/evmCodeTransform/stackReuse/function_retparam_for.yul b/test/libyul/evmCodeTransform/stackReuse/function_retparam_for.yul index c18fb7c37e50..698f508307ec 100644 --- a/test/libyul/evmCodeTransform/stackReuse/function_retparam_for.yul +++ b/test/libyul/evmCodeTransform/stackReuse/function_retparam_for.yul @@ -3,6 +3,7 @@ } // ==== // stackOptimization: true +// EVMVersion: =current // ---- // /* "":0:78 */ // stop diff --git a/test/libyul/evmCodeTransform/stackReuse/function_retparam_if.yul b/test/libyul/evmCodeTransform/stackReuse/function_retparam_if.yul index 08dda5a3bc28..e7c752a15589 100644 --- a/test/libyul/evmCodeTransform/stackReuse/function_retparam_if.yul +++ b/test/libyul/evmCodeTransform/stackReuse/function_retparam_if.yul @@ -3,6 +3,7 @@ } // ==== // stackOptimization: true +// EVMVersion: =current // ---- // /* "":0:70 */ // stop diff --git a/test/libyul/evmCodeTransform/stackReuse/function_retparam_leave.yul b/test/libyul/evmCodeTransform/stackReuse/function_retparam_leave.yul index 9ac0c00bf8f2..b043977f77c9 100644 --- a/test/libyul/evmCodeTransform/stackReuse/function_retparam_leave.yul +++ b/test/libyul/evmCodeTransform/stackReuse/function_retparam_leave.yul @@ -3,6 +3,7 @@ } // ==== // stackOptimization: true +// EVMVersion: =current // ---- // /* "":0:67 */ // stop diff --git a/test/libyul/evmCodeTransform/stackReuse/function_retparam_read.yul b/test/libyul/evmCodeTransform/stackReuse/function_retparam_read.yul index fcc8278e6719..4266f1499c52 100644 --- a/test/libyul/evmCodeTransform/stackReuse/function_retparam_read.yul +++ b/test/libyul/evmCodeTransform/stackReuse/function_retparam_read.yul @@ -3,6 +3,7 @@ } // ==== // stackOptimization: true +// EVMVersion: =current // ---- // /* "":0:74 */ // stop diff --git a/test/libyul/evmCodeTransform/stackReuse/function_retparam_unassigned.yul b/test/libyul/evmCodeTransform/stackReuse/function_retparam_unassigned.yul index 1cc19a464105..e83d68dd0fbe 100644 --- a/test/libyul/evmCodeTransform/stackReuse/function_retparam_unassigned.yul +++ b/test/libyul/evmCodeTransform/stackReuse/function_retparam_unassigned.yul @@ -3,6 +3,7 @@ } // ==== // stackOptimization: true +// EVMVersion: =current // ---- // /* "":0:46 */ // stop diff --git a/test/libyul/evmCodeTransform/stackReuse/function_retparam_unassigned_multiple.yul b/test/libyul/evmCodeTransform/stackReuse/function_retparam_unassigned_multiple.yul index e44e3b43729b..bef2538670bf 100644 --- a/test/libyul/evmCodeTransform/stackReuse/function_retparam_unassigned_multiple.yul +++ b/test/libyul/evmCodeTransform/stackReuse/function_retparam_unassigned_multiple.yul @@ -3,6 +3,7 @@ } // ==== // stackOptimization: true +// EVMVersion: =current // ---- // /* "":0:52 */ // stop diff --git a/test/libyul/evmCodeTransform/stackReuse/function_trivial.yul b/test/libyul/evmCodeTransform/stackReuse/function_trivial.yul index 3d6286efdb07..e9f44f11d7ab 100644 --- a/test/libyul/evmCodeTransform/stackReuse/function_trivial.yul +++ b/test/libyul/evmCodeTransform/stackReuse/function_trivial.yul @@ -3,6 +3,7 @@ } // ==== // stackOptimization: true +// EVMVersion: =current // ---- // /* "":0:22 */ // stop diff --git a/test/libyul/evmCodeTransform/stackReuse/function_with_body_embedded.yul b/test/libyul/evmCodeTransform/stackReuse/function_with_body_embedded.yul index f8480bc91ea8..077a2e428d37 100644 --- a/test/libyul/evmCodeTransform/stackReuse/function_with_body_embedded.yul +++ b/test/libyul/evmCodeTransform/stackReuse/function_with_body_embedded.yul @@ -8,6 +8,7 @@ } // ==== // stackOptimization: true +// EVMVersion: =current // ---- // /* "":15:16 */ // 0x03 diff --git a/test/libyul/evmCodeTransform/stackReuse/functions_multi_return.yul b/test/libyul/evmCodeTransform/stackReuse/functions_multi_return.yul index 1ce02483dcbf..e834b7aa8ef6 100644 --- a/test/libyul/evmCodeTransform/stackReuse/functions_multi_return.yul +++ b/test/libyul/evmCodeTransform/stackReuse/functions_multi_return.yul @@ -9,6 +9,7 @@ } // ==== // stackOptimization: true +// EVMVersion: =current // ---- // /* "":74:81 */ // tag_3 diff --git a/test/libyul/evmCodeTransform/stackReuse/if.yul b/test/libyul/evmCodeTransform/stackReuse/if.yul index cee19ab93fdc..23ab75b59bc8 100644 --- a/test/libyul/evmCodeTransform/stackReuse/if.yul +++ b/test/libyul/evmCodeTransform/stackReuse/if.yul @@ -2,6 +2,7 @@ { let z := mload(0) if z { let x := z } let t := 3 } // ==== // stackOptimization: true +// EVMVersion: =current // ---- // /* "":72:73 */ // 0x00 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 49ffb3971be3..ed0a297bb649 100644 --- a/test/libyul/evmCodeTransform/stackReuse/last_use_in_nested_block.yul +++ b/test/libyul/evmCodeTransform/stackReuse/last_use_in_nested_block.yul @@ -1,6 +1,7 @@ { let z := 0 { pop(z) } let x := 1 } // ==== // stackOptimization: true +// EVMVersion: =current // ---- // /* "":11:12 */ // 0x00 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 3404dc53628c..eee735565a68 100644 --- a/test/libyul/evmCodeTransform/stackReuse/multi_reuse_same_variable_name.yul +++ b/test/libyul/evmCodeTransform/stackReuse/multi_reuse_same_variable_name.yul @@ -1,6 +1,7 @@ { let z := mload(0) { let x := 1 x := 6 z := x } { let x := 2 z := x x := 4 } } // ==== // stackOptimization: true +// EVMVersion: =current // ---- // /* "":17:18 */ // 0x00 diff --git a/test/libyul/evmCodeTransform/stackReuse/multi_reuse_single_slot.yul b/test/libyul/evmCodeTransform/stackReuse/multi_reuse_single_slot.yul index a80e66c10efa..dde7e1269471 100644 --- a/test/libyul/evmCodeTransform/stackReuse/multi_reuse_single_slot.yul +++ b/test/libyul/evmCodeTransform/stackReuse/multi_reuse_single_slot.yul @@ -1,6 +1,7 @@ { let x := 1 x := 6 let y := 2 y := 4 } // ==== // stackOptimization: true +// EVMVersion: =current // ---- // /* "":11:12 */ // 0x01 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 db8783502340..fdf2f695bd90 100644 --- a/test/libyul/evmCodeTransform/stackReuse/multi_reuse_single_slot_nested.yul +++ b/test/libyul/evmCodeTransform/stackReuse/multi_reuse_single_slot_nested.yul @@ -1,6 +1,7 @@ { let x := 1 x := 6 { let y := 2 y := 4 } } // ==== // stackOptimization: true +// EVMVersion: =current // ---- // /* "":11:12 */ // 0x01 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 9be91989d00a..4d0531a4dcfb 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 @@ -7,6 +7,7 @@ } // ==== // stackOptimization: true +// EVMVersion: =current // ---- // /* "":15:16 */ // 0x05 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 11e77c62694e..a7ef081e2601 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 @@ -5,6 +5,7 @@ } // ==== // stackOptimization: true +// EVMVersion: =current // ---- // /* "":15:16 */ // 0x05 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 214020ccdc37..adaa154614fb 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 @@ -5,6 +5,7 @@ } // ==== // stackOptimization: true +// EVMVersion: =current // ---- // /* "":37:38 */ // 0x02 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 e3002f34d942..3d10ecd42018 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 @@ -5,6 +5,7 @@ } // ==== // stackOptimization: true +// EVMVersion: =current // ---- // /* "":15:16 */ // 0x05 diff --git a/test/libyul/evmCodeTransform/stackReuse/reuse_slots.yul b/test/libyul/evmCodeTransform/stackReuse/reuse_slots.yul index 13decd3231ae..b9bbeeb385fe 100644 --- a/test/libyul/evmCodeTransform/stackReuse/reuse_slots.yul +++ b/test/libyul/evmCodeTransform/stackReuse/reuse_slots.yul @@ -1,6 +1,7 @@ { let a, b, c, d let x := 2 let y := 3 mstore(x, a) mstore(y, c) } // ==== // stackOptimization: true +// EVMVersion: =current // ---- // /* "":2:16 */ // 0x00 diff --git a/test/libyul/evmCodeTransform/stackReuse/reuse_slots_function.yul b/test/libyul/evmCodeTransform/stackReuse/reuse_slots_function.yul index 13e3065ccc97..1af5c6454acc 100644 --- a/test/libyul/evmCodeTransform/stackReuse/reuse_slots_function.yul +++ b/test/libyul/evmCodeTransform/stackReuse/reuse_slots_function.yul @@ -4,6 +4,7 @@ } // ==== // stackOptimization: true +// EVMVersion: =current // ---- // /* "":58:61 */ // tag_2 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 f1cde362aef4..329d354ce6e6 100644 --- a/test/libyul/evmCodeTransform/stackReuse/reuse_slots_function_with_gaps.yul +++ b/test/libyul/evmCodeTransform/stackReuse/reuse_slots_function_with_gaps.yul @@ -8,6 +8,7 @@ } // ==== // stackOptimization: true +// EVMVersion: =current // ---- // /* "":106:107 */ // 0x05 diff --git a/test/libyul/evmCodeTransform/stackReuse/reuse_too_deep_slot.yul b/test/libyul/evmCodeTransform/stackReuse/reuse_too_deep_slot.yul index 2adfe7892bce..a2f2a1b476df 100644 --- a/test/libyul/evmCodeTransform/stackReuse/reuse_too_deep_slot.yul +++ b/test/libyul/evmCodeTransform/stackReuse/reuse_too_deep_slot.yul @@ -32,6 +32,7 @@ } // ==== // stackOptimization: true +// EVMVersion: =current // ---- // /* "":15:16 */ // 0x07 diff --git a/test/libyul/evmCodeTransform/stackReuse/single_var.yul b/test/libyul/evmCodeTransform/stackReuse/single_var.yul index 09a0d6feeb9e..d42e5928a155 100644 --- a/test/libyul/evmCodeTransform/stackReuse/single_var.yul +++ b/test/libyul/evmCodeTransform/stackReuse/single_var.yul @@ -1,6 +1,7 @@ { let x } // ==== // stackOptimization: true +// EVMVersion: =current // ---- // /* "":2:7 */ // 0x00 diff --git a/test/libyul/evmCodeTransform/stackReuse/single_var_assigned.yul b/test/libyul/evmCodeTransform/stackReuse/single_var_assigned.yul index ed497467d57e..3d6b68000188 100644 --- a/test/libyul/evmCodeTransform/stackReuse/single_var_assigned.yul +++ b/test/libyul/evmCodeTransform/stackReuse/single_var_assigned.yul @@ -1,6 +1,7 @@ { let x := 1 } // ==== // stackOptimization: true +// EVMVersion: =current // ---- // /* "":11:12 */ // 0x01 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 bec4c834ff58..707c8a30655b 100644 --- a/test/libyul/evmCodeTransform/stackReuse/single_var_assigned_plus_code.yul +++ b/test/libyul/evmCodeTransform/stackReuse/single_var_assigned_plus_code.yul @@ -1,6 +1,7 @@ { let x := 1 mstore(3, 4) } // ==== // stackOptimization: true +// EVMVersion: =current // ---- // /* "":11:12 */ // 0x01 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 b9a814700abd..8f3e28390fdb 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 @@ -1,6 +1,7 @@ { let x := 1 mstore(3, 4) pop(mload(x)) } // ==== // stackOptimization: true +// EVMVersion: =current // ---- // /* "":11:12 */ // 0x01 diff --git a/test/libyul/evmCodeTransform/stackReuse/smoke.yul b/test/libyul/evmCodeTransform/stackReuse/smoke.yul index aa46f7a4a538..32b3704fd99a 100644 --- a/test/libyul/evmCodeTransform/stackReuse/smoke.yul +++ b/test/libyul/evmCodeTransform/stackReuse/smoke.yul @@ -1,6 +1,7 @@ {} // ==== // stackOptimization: true +// EVMVersion: =current // ---- // /* "":0:2 */ // stop diff --git a/test/libyul/evmCodeTransform/stackReuse/switch.yul b/test/libyul/evmCodeTransform/stackReuse/switch.yul index f72d80fad0b5..a7fb935a49f0 100644 --- a/test/libyul/evmCodeTransform/stackReuse/switch.yul +++ b/test/libyul/evmCodeTransform/stackReuse/switch.yul @@ -1,6 +1,7 @@ { let z := 0 switch z case 0 { let x := 2 let y := 3 } default { z := 3 } let t := 9 } // ==== // stackOptimization: true +// EVMVersion: =current // ---- // /* "":11:12 */ // 0x00 diff --git a/test/libyul/evmCodeTransform/stub.yul b/test/libyul/evmCodeTransform/stub.yul index ef7cd668c1c1..f8541dd3f1f7 100644 --- a/test/libyul/evmCodeTransform/stub.yul +++ b/test/libyul/evmCodeTransform/stub.yul @@ -19,6 +19,7 @@ } // ==== // stackOptimization: true +// EVMVersion: =current // ---- // /* "":14:21 */ // tag_2 diff --git a/test/libyul/evmCodeTransform/unassigned_return_variable.yul b/test/libyul/evmCodeTransform/unassigned_return_variable.yul index 666fefe1aa64..2c28d52a3062 100644 --- a/test/libyul/evmCodeTransform/unassigned_return_variable.yul +++ b/test/libyul/evmCodeTransform/unassigned_return_variable.yul @@ -6,6 +6,7 @@ } // ==== // stackOptimization: true +// EVMVersion: =current // ---- // /* "":0:111 */ // stop From 3c0545cfbb0bbb65a4408641cd6cfa8d541a15d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Wed, 4 Dec 2024 00:41:11 +0100 Subject: [PATCH 0648/1022] YulOptimizerTestCommon: Get Dialect from Object --- test/libyul/YulOptimizerTest.cpp | 2 +- test/libyul/YulOptimizerTestCommon.cpp | 33 ++++++++++---------- test/libyul/YulOptimizerTestCommon.h | 7 +---- test/tools/ossfuzz/yulProtoFuzzer.cpp | 5 +-- test/tools/ossfuzz/yulProto_diff_ossfuzz.cpp | 5 +-- 5 files changed, 21 insertions(+), 31 deletions(-) diff --git a/test/libyul/YulOptimizerTest.cpp b/test/libyul/YulOptimizerTest.cpp index dc05810bc672..03f05ffa2ae9 100644 --- a/test/libyul/YulOptimizerTest.cpp +++ b/test/libyul/YulOptimizerTest.cpp @@ -74,7 +74,7 @@ TestCase::TestResult YulOptimizerTest::run(std::ostream& _stream, std::string co soltestAssert(m_dialect, "Dialect not set."); m_object->analysisInfo = m_analysisInfo; - YulOptimizerTestCommon tester(m_object, *m_dialect); + YulOptimizerTestCommon tester(m_object); tester.setStep(m_optimizerStep); if (!tester.runStep()) diff --git a/test/libyul/YulOptimizerTestCommon.cpp b/test/libyul/YulOptimizerTestCommon.cpp index 351d705cc517..19b2176c10f5 100644 --- a/test/libyul/YulOptimizerTestCommon.cpp +++ b/test/libyul/YulOptimizerTestCommon.cpp @@ -18,6 +18,8 @@ #include +#include + #include #include #include @@ -73,11 +75,12 @@ using namespace solidity::yul; using namespace solidity::yul::test; using namespace solidity::frontend; -YulOptimizerTestCommon::YulOptimizerTestCommon( - std::shared_ptr _obj, - Dialect const& _dialect -): m_dialect(&_dialect), m_object(_obj), m_optimizedObject(std::make_shared(*_obj)) +YulOptimizerTestCommon::YulOptimizerTestCommon(std::shared_ptr _obj): + m_object(_obj), + m_optimizedObject(std::make_shared(*_obj)) { + soltestAssert(m_object && m_optimizedObject); + if ( std::any_of( m_object->subObjects.begin(), @@ -85,7 +88,7 @@ YulOptimizerTestCommon::YulOptimizerTestCommon( [](auto const& subObject) { return dynamic_cast(subObject.get()) == nullptr;} ) ) - solUnimplementedAssert(false, "The current implementation of YulOptimizerTests ignores subobjects that are not Data."); + solUnimplemented("The current implementation of YulOptimizerTests ignores subobjects that are not Data."); m_namedSteps = { {"disambiguator", [&]() { return disambiguate(); }}, @@ -108,8 +111,8 @@ YulOptimizerTestCommon::YulOptimizerTestCommon( {"constantOptimiser", [&]() { auto block = std::get(ASTCopier{}(m_object->code()->root())); updateContext(block); - GasMeter meter(dynamic_cast(*m_dialect), false, 200); - ConstantOptimiser{dynamic_cast(*m_dialect), meter}(block); + GasMeter meter(dynamic_cast(*m_object->dialect()), false, 200); + ConstantOptimiser{dynamic_cast(*m_object->dialect()), meter}(block); return block; }}, {"varDeclInitializer", [&]() { @@ -410,14 +413,14 @@ YulOptimizerTestCommon::YulOptimizerTestCommon( size_t maxIterations = 16; { Object object(*m_optimizedObject); - object.setCode(std::make_shared(*m_dialect, std::get(ASTCopier{}(block)))); + object.setCode(std::make_shared(*m_object->dialect(), std::get(ASTCopier{}(block)))); block = std::get<1>(StackCompressor::run(object, true, maxIterations)); } BlockFlattener::run(*m_context, block); return block; }}, {"fullSuite", [&]() { - GasMeter meter(dynamic_cast(*m_dialect), false, 200); + GasMeter meter(dynamic_cast(*m_object->dialect()), false, 200); OptimiserSuite::run( &meter, *m_optimizedObject, @@ -432,7 +435,7 @@ YulOptimizerTestCommon::YulOptimizerTestCommon( auto block = disambiguate(); updateContext(block); Object object(*m_optimizedObject); - object.setCode(std::make_shared(*m_dialect, std::get(ASTCopier{}(block)))); + object.setCode(std::make_shared(*m_object->dialect(), std::get(ASTCopier{}(block)))); auto const unreachables = CompilabilityChecker{ object, true @@ -493,12 +496,10 @@ void YulOptimizerTestCommon::setStep(std::string const& _optimizerStep) bool YulOptimizerTestCommon::runStep() { - yulAssert(m_dialect, "Dialect not set."); - if (m_namedSteps.count(m_optimizerStep)) { auto block = m_namedSteps[m_optimizerStep](); - m_optimizedObject->setCode(std::make_shared(*m_dialect, std::move(block))); + m_optimizedObject->setCode(std::make_shared(*m_object->dialect(), std::move(block))); } else return false; @@ -542,15 +543,15 @@ Block const* YulOptimizerTestCommon::run() Block YulOptimizerTestCommon::disambiguate() { - auto block = std::get(Disambiguator(*m_dialect, *m_object->analysisInfo)(m_object->code()->root())); + auto block = std::get(Disambiguator(*m_object->dialect(), *m_object->analysisInfo)(m_object->code()->root())); return block; } void YulOptimizerTestCommon::updateContext(Block const& _block) { - m_nameDispenser = std::make_unique(*m_dialect, _block, m_reservedIdentifiers); + m_nameDispenser = std::make_unique(*m_object->dialect(), _block, m_reservedIdentifiers); m_context = std::make_unique(OptimiserStepContext{ - *m_dialect, + *m_object->dialect(), *m_nameDispenser, m_reservedIdentifiers, frontend::OptimiserSettings::standard().expectedExecutionsPerDeployment diff --git a/test/libyul/YulOptimizerTestCommon.h b/test/libyul/YulOptimizerTestCommon.h index bc513e7481b4..df5c84039b0f 100644 --- a/test/libyul/YulOptimizerTestCommon.h +++ b/test/libyul/YulOptimizerTestCommon.h @@ -30,7 +30,6 @@ namespace solidity::yul { struct AsmAnalysisInfo; class Object; -class Dialect; class AST; } @@ -39,10 +38,7 @@ namespace solidity::yul::test class YulOptimizerTestCommon { public: - explicit YulOptimizerTestCommon( - std::shared_ptr _obj, - Dialect const& _dialect - ); + explicit YulOptimizerTestCommon(std::shared_ptr _obj); /// Sets optimiser step to be run to @param /// _optimiserStep. void setStep(std::string const& _optimizerStep); @@ -65,7 +61,6 @@ class YulOptimizerTestCommon std::string m_optimizerStep; - Dialect const* m_dialect = nullptr; std::set m_reservedIdentifiers; std::unique_ptr m_nameDispenser; std::unique_ptr m_context; diff --git a/test/tools/ossfuzz/yulProtoFuzzer.cpp b/test/tools/ossfuzz/yulProtoFuzzer.cpp index 4e9387f6f51e..2f372c3254c1 100644 --- a/test/tools/ossfuzz/yulProtoFuzzer.cpp +++ b/test/tools/ossfuzz/yulProtoFuzzer.cpp @@ -80,10 +80,7 @@ DEFINE_PROTO_FUZZER(Program const& _input) // TODO: Add EOF support // Optimize - YulOptimizerTestCommon optimizerTest( - stack.parserResult(), - EVMDialect::strictAssemblyForEVMObjects(version, std::nullopt) - ); + YulOptimizerTestCommon optimizerTest(stack.parserResult()); optimizerTest.setStep(optimizerTest.randomOptimiserStep(_input.step())); auto const* astRoot = optimizerTest.run(); yulAssert(astRoot != nullptr, "Optimiser error."); diff --git a/test/tools/ossfuzz/yulProto_diff_ossfuzz.cpp b/test/tools/ossfuzz/yulProto_diff_ossfuzz.cpp index eff96f831eaf..d15043972693 100644 --- a/test/tools/ossfuzz/yulProto_diff_ossfuzz.cpp +++ b/test/tools/ossfuzz/yulProto_diff_ossfuzz.cpp @@ -99,10 +99,7 @@ DEFINE_PROTO_FUZZER(Program const& _input) return; // TODO: Add EOF support - YulOptimizerTestCommon optimizerTest( - stack.parserResult(), - EVMDialect::strictAssemblyForEVMObjects(version, std::nullopt) - ); + YulOptimizerTestCommon optimizerTest(stack.parserResult()); optimizerTest.setStep(optimizerTest.randomOptimiserStep(_input.step())); auto const* astRoot = optimizerTest.run(); yulAssert(astRoot != nullptr, "Optimiser error."); From 46b0616aaed98fa7ddef3c396d7d5fa81d075f56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Wed, 4 Dec 2024 01:13:29 +0100 Subject: [PATCH 0649/1022] Unify Yul code parsing across different test suites --- libyul/YulStack.cpp | 7 ++ libyul/YulStack.h | 3 + test/libsolidity/MemoryGuardTest.cpp | 29 +++--- test/libyul/Common.cpp | 102 +++++++++++---------- test/libyul/Common.h | 21 ++++- test/libyul/CompilabilityChecker.cpp | 15 +-- test/libyul/ControlFlowGraphTest.cpp | 24 ++--- test/libyul/ControlFlowGraphTest.h | 10 +- test/libyul/ControlFlowSideEffectsTest.cpp | 24 +++-- test/libyul/EVMCodeTransformTest.cpp | 19 ++-- test/libyul/FunctionSideEffects.cpp | 23 ++--- test/libyul/FunctionSideEffects.h | 1 - test/libyul/KnowledgeBaseTest.cpp | 26 +++--- test/libyul/Metrics.cpp | 10 +- test/libyul/ObjectCompilerTest.cpp | 30 ++---- test/libyul/ObjectCompilerTest.h | 1 - test/libyul/ObjectParser.cpp | 41 ++------- test/libyul/SSAControlFlowGraphTest.cpp | 25 ++--- test/libyul/SSAControlFlowGraphTest.h | 10 +- test/libyul/StackLayoutGeneratorTest.cpp | 28 +++--- test/libyul/StackLayoutGeneratorTest.h | 10 +- test/libyul/SyntaxTest.cpp | 34 +++---- test/libyul/SyntaxTest.h | 4 - test/libyul/YulInterpreterTest.cpp | 45 +++------ test/libyul/YulInterpreterTest.h | 8 +- test/libyul/YulOptimizerTest.cpp | 34 +++---- test/libyul/YulOptimizerTest.h | 10 +- 27 files changed, 259 insertions(+), 335 deletions(-) diff --git a/libyul/YulStack.cpp b/libyul/YulStack.cpp index dfab4b6878c0..791b7103ded8 100644 --- a/libyul/YulStack.cpp +++ b/libyul/YulStack.cpp @@ -430,6 +430,13 @@ std::shared_ptr YulStack::parserResult() const return m_parserResult; } +Dialect const& YulStack::dialect() const +{ + yulAssert(m_stackState >= AnalysisSuccessful); + yulAssert(m_parserResult && m_parserResult->dialect()); + return *m_parserResult->dialect(); +} + void YulStack::reportUnimplementedFeatureError(UnimplementedFeatureError const& _error) { yulAssert(_error.comment(), "Errors must include a message for the user."); diff --git a/libyul/YulStack.h b/libyul/YulStack.h index f9837e553ed4..94688fddcaaf 100644 --- a/libyul/YulStack.h +++ b/libyul/YulStack.h @@ -139,6 +139,7 @@ class YulStack: public langutil::CharStreamProvider /// @returns the errors generated during parsing, analysis (and potentially assembly). langutil::ErrorList const& errors() const { return m_errors; } bool hasErrors() const { return m_errorReporter.hasErrors(); } + bool hasErrorsWarningsOrInfos() const { return m_errorReporter.hasErrorsWarningsOrInfos(); } /// Pretty-print the input after having parsed it. std::string print() const; @@ -150,6 +151,8 @@ class YulStack: public langutil::CharStreamProvider /// Return the parsed and analyzed object. std::shared_ptr parserResult() const; + Dialect const& dialect() const; + langutil::DebugInfoSelection debugInfoSelection() const { return m_debugInfoSelection; } private: diff --git a/test/libsolidity/MemoryGuardTest.cpp b/test/libsolidity/MemoryGuardTest.cpp index 9826f4b19468..0f4230d5adec 100644 --- a/test/libsolidity/MemoryGuardTest.cpp +++ b/test/libsolidity/MemoryGuardTest.cpp @@ -20,13 +20,17 @@ #include #include + #include + #include #include + #include -#include #include #include +#include + #include #include #include @@ -38,6 +42,7 @@ using namespace solidity::langutil; using namespace solidity::frontend; using namespace solidity::frontend::test; using namespace solidity::test; +using namespace solidity::yul::test; using namespace yul; void MemoryGuardTest::setupCompiler(CompilerStack& _compiler) @@ -59,20 +64,14 @@ TestCase::TestResult MemoryGuardTest::run(std::ostream& _stream, std::string con m_obtainedResult.clear(); for (std::string contractName: compiler().contractNames()) { - auto const& dialect = CommonOptions::get().evmDialect(); ErrorList errors; std::optional const& ir = compiler().yulIR(contractName); - solAssert(ir); - auto [object, analysisInfo] = yul::test::parse( - *ir, - dialect, - errors - ); + soltestAssert(ir); - if (!object || !analysisInfo || Error::containsErrors(errors)) + YulStack yulStack = parseYul(*ir); + if (yulStack.hasErrors()) { - AnsiColorized(_stream, _formatted, {formatting::BOLD, formatting::RED}) << _linePrefix << "Error parsing IR:" << std::endl; - printPrefixed(_stream, formatErrors(filterErrors(errors), _formatted), _linePrefix); + printYulErrors(yulStack, _stream, _linePrefix, _formatted); return TestResult::FatalError; } @@ -80,14 +79,14 @@ TestCase::TestResult MemoryGuardTest::run(std::ostream& _stream, std::string con m_obtainedResult += contractName + "(" + _kind + ") " + (findFunctionCalls( _object.code()->root(), "memoryguard", - dialect + yulStack.dialect() ).empty() ? "false" : "true") + "\n"; }; - handleObject("creation", *object); - size_t deployedIndex = object->subIndexByName.at( + handleObject("creation", *yulStack.parserResult()); + size_t deployedIndex = yulStack.parserResult()->subIndexByName.at( IRNames::deployedObject(compiler().contractDefinition(contractName)) ); - handleObject("runtime", dynamic_cast(*object->subObjects[deployedIndex])); + handleObject("runtime", dynamic_cast(*yulStack.parserResult()->subObjects[deployedIndex])); } return checkResult(_stream, _linePrefix, _formatted); } diff --git a/test/libyul/Common.cpp b/test/libyul/Common.cpp index 32f60c8ebe6f..e64558bd48a9 100644 --- a/test/libyul/Common.cpp +++ b/test/libyul/Common.cpp @@ -21,6 +21,8 @@ #include +#include + #include #include @@ -30,76 +32,69 @@ #include #include +#include + #include #include #include +#include #include #include using namespace solidity; +using namespace solidity::frontend; using namespace solidity::yul; using namespace solidity::langutil; +using namespace solidity::util; +using namespace solidity::test; -namespace -{ -Dialect const& defaultDialect() -{ - return yul::EVMDialect::strictAssemblyForEVM( - solidity::test::CommonOptions::get().evmVersion(), - solidity::test::CommonOptions::get().eofVersion() - ); -} -} - -std::pair, std::shared_ptr> yul::test::parse(std::string const& _source) +YulStack yul::test::parseYul( + std::string const& _source, + std::string _sourceUnitName, + std::optional _optimiserSettings +) { - YulStack stack( - solidity::test::CommonOptions::get().evmVersion(), - solidity::test::CommonOptions::get().eofVersion(), + YulStack yulStack( + CommonOptions::get().evmVersion(), + CommonOptions::get().eofVersion(), YulStack::Language::StrictAssembly, - solidity::test::CommonOptions::get().optimize ? - solidity::frontend::OptimiserSettings::standard() : - solidity::frontend::OptimiserSettings::minimal(), + _optimiserSettings.has_value() ? + *_optimiserSettings : + (CommonOptions::get().optimize ? OptimiserSettings::standard() : OptimiserSettings::minimal()), DebugInfoSelection::All() ); - if (!stack.parseAndAnalyze("", _source) || Error::hasErrorsWarningsOrInfos(stack.errors())) - BOOST_FAIL("Invalid source."); - return std::make_pair(stack.parserResult()->code(), stack.parserResult()->analysisInfo); -} - -std::pair, std::shared_ptr> yul::test::parse( - std::string const& _source, - Dialect const& _dialect, - ErrorList& _errors -) -{ - ErrorReporter errorReporter(_errors); - CharStream stream(_source, ""); - std::shared_ptr scanner = std::make_shared(stream); - std::shared_ptr parserResult = yul::ObjectParser(errorReporter, _dialect).parse(scanner, false); - if (!parserResult) - return {}; - if (!parserResult->hasCode() || errorReporter.hasErrors()) - return {}; - std::shared_ptr analysisInfo = std::make_shared(); - AsmAnalyzer analyzer(*analysisInfo, errorReporter, _dialect, {}, parserResult->summarizeStructure()); - // TODO this should be done recursively. - if (!analyzer.analyze(parserResult->code()->root()) || errorReporter.hasErrors()) - return {}; - return {std::move(parserResult), std::move(analysisInfo)}; + bool successful = yulStack.parseAndAnalyze(_sourceUnitName, _source); + if (!successful) + soltestAssert(yulStack.hasErrors()); + else + { + soltestAssert(!yulStack.hasErrors()); + soltestAssert(yulStack.parserResult()); + soltestAssert(yulStack.parserResult()->code()); + soltestAssert(yulStack.parserResult()->analysisInfo); + } + return yulStack; } yul::Block yul::test::disambiguate(std::string const& _source) { - auto result = parse(_source); - return std::get(Disambiguator(defaultDialect(), *result.second, {})(result.first->root())); + YulStack yulStack = parseYul(_source); + soltestAssert(!yulStack.hasErrorsWarningsOrInfos()); + return std::get(Disambiguator( + yulStack.dialect(), + *yulStack.parserResult()->analysisInfo, + {} + )(yulStack.parserResult()->code()->root())); } std::string yul::test::format(std::string const& _source) { - return AsmPrinter::format(*parse(_source).first); + YulStack yulStack = parseYul(_source); + solUnimplementedAssert(yulStack.parserResult()->subObjects.empty(), "Subobjects not supported."); + soltestAssert(!yulStack.hasErrorsWarningsOrInfos()); + return AsmPrinter::format(*yulStack.parserResult()->code()); } namespace @@ -134,3 +129,18 @@ yul::Dialect const& yul::test::dialect(std::string const& _name, langutil::EVMVe return validDialects.at(_name)(_evmVersion, _eofVersion); } + +void yul::test::printYulErrors( + YulStack const& _yulStack, + std::ostream& _stream, + std::string const& _linePrefix, + bool const _formatted +) +{ + AnsiColorized(_stream, _formatted, {formatting::BOLD, formatting::RED}) + << _linePrefix + << "Error parsing source." + << std::endl; + SourceReferenceFormatter formatter{_stream, _yulStack, true, false}; + formatter.printErrorInformation(_yulStack.errors()); +} diff --git a/test/libyul/Common.h b/test/libyul/Common.h index e36e81052cc9..de402c29a9da 100644 --- a/test/libyul/Common.h +++ b/test/libyul/Common.h @@ -21,11 +21,14 @@ #pragma once +#include + #include #include #include #include +#include namespace solidity::langutil { @@ -40,20 +43,28 @@ struct Block; class Object; class Dialect; class AST; +class YulStack; } namespace solidity::yul::test { -std::pair, std::shared_ptr> -parse(std::string const& _source); - -std::pair, std::shared_ptr> -parse(std::string const& _source, Dialect const& _dialect, langutil::ErrorList& _errors); +yul::YulStack parseYul( + std::string const& _source, + std::string _sourceUnitName = "", + std::optional _optimiserSettings = std::nullopt +); Block disambiguate(std::string const& _source); std::string format(std::string const& _source); solidity::yul::Dialect const& dialect(std::string const& _name, langutil::EVMVersion _evmVersion, std::optional _eofVersion); +void printYulErrors( + yul::YulStack const& _yulStack, + std::ostream& _stream, + std::string const& _linePrefix, + bool const _formatted +); + } diff --git a/test/libyul/CompilabilityChecker.cpp b/test/libyul/CompilabilityChecker.cpp index 1956db84c6b7..a030af487eb1 100644 --- a/test/libyul/CompilabilityChecker.cpp +++ b/test/libyul/CompilabilityChecker.cpp @@ -20,10 +20,12 @@ #include +#include + #include -#include #include +#include #include @@ -34,12 +36,11 @@ namespace { std::string check(std::string const& _input) { - Object obj; - auto parsingResult = yul::test::parse(_input); - obj.setCode(parsingResult.first, parsingResult.second); - BOOST_REQUIRE(obj.hasCode()); - BOOST_REQUIRE(obj.dialect()); - auto functions = CompilabilityChecker(obj, true).stackDeficit; + YulStack yulStack = parseYul(_input); + solUnimplementedAssert(yulStack.parserResult()->subObjects.empty(), "Tests with subobjects not supported."); + soltestAssert(!yulStack.hasErrorsWarningsOrInfos()); + + auto functions = CompilabilityChecker(*yulStack.parserResult(), true).stackDeficit; std::string out; for (auto const& function: functions) out += function.first.str() + ": " + std::to_string(function.second) + " "; diff --git a/test/libyul/ControlFlowGraphTest.cpp b/test/libyul/ControlFlowGraphTest.cpp index bd0bf0a802d2..c0ab37956e4c 100644 --- a/test/libyul/ControlFlowGraphTest.cpp +++ b/test/libyul/ControlFlowGraphTest.cpp @@ -24,8 +24,8 @@ #include #include #include +#include -#include #include #ifdef ISOLTEST @@ -45,11 +45,7 @@ ControlFlowGraphTest::ControlFlowGraphTest(std::string const& _filename): { m_source = m_reader.source(); auto dialectName = m_reader.stringSetting("dialect", "evm"); - m_dialect = &dialect( - dialectName, - solidity::test::CommonOptions::get().evmVersion(), - solidity::test::CommonOptions::get().eofVersion() - ); + soltestAssert(dialectName == "evm"); // We only have one dialect now m_expectation = m_reader.simpleExpectations(); } @@ -201,20 +197,24 @@ class ControlFlowGraphPrinter TestCase::TestResult ControlFlowGraphTest::run(std::ostream& _stream, std::string const& _linePrefix, bool const _formatted) { - ErrorList errors; - auto [object, analysisInfo] = parse(m_source, *m_dialect, errors); - if (!object || !analysisInfo || Error::containsErrors(errors)) + YulStack yulStack = parseYul(m_source); + solUnimplementedAssert(yulStack.parserResult()->subObjects.empty(), "Tests with subobjects not supported."); + if (yulStack.hasErrors()) { - AnsiColorized(_stream, _formatted, {formatting::BOLD, formatting::RED}) << _linePrefix << "Error parsing source." << std::endl; + printYulErrors(yulStack, _stream, _linePrefix, _formatted); return TestResult::FatalError; } std::ostringstream output; - std::unique_ptr cfg = ControlFlowGraphBuilder::build(*analysisInfo, *m_dialect, object->code()->root()); + std::unique_ptr cfg = ControlFlowGraphBuilder::build( + *yulStack.parserResult()->analysisInfo, + yulStack.dialect(), + yulStack.parserResult()->code()->root() + ); output << "digraph CFG {\nnodesep=0.7;\nnode[shape=box];\n\n"; - ControlFlowGraphPrinter printer{output, *m_dialect}; + ControlFlowGraphPrinter printer{output, yulStack.dialect()}; printer(*cfg->entry); for (auto function: cfg->functions) printer(cfg->functionInfo.at(function)); diff --git a/test/libyul/ControlFlowGraphTest.h b/test/libyul/ControlFlowGraphTest.h index 953a27b22004..f6c8ddfce5db 100644 --- a/test/libyul/ControlFlowGraphTest.h +++ b/test/libyul/ControlFlowGraphTest.h @@ -20,11 +20,7 @@ #include -namespace solidity::yul -{ -class Dialect; - -namespace test +namespace solidity::yul::test { class ControlFlowGraphTest: public frontend::test::EVMVersionRestrictedTestCase @@ -36,8 +32,6 @@ class ControlFlowGraphTest: public frontend::test::EVMVersionRestrictedTestCase } explicit ControlFlowGraphTest(std::string const& _filename); TestResult run(std::ostream& _stream, std::string const& _linePrefix = "", bool const _formatted = false) override; -private: - Dialect const* m_dialect = nullptr; }; -} + } diff --git a/test/libyul/ControlFlowSideEffectsTest.cpp b/test/libyul/ControlFlowSideEffectsTest.cpp index 50c546e36c5d..2249ba110cb1 100644 --- a/test/libyul/ControlFlowSideEffectsTest.cpp +++ b/test/libyul/ControlFlowSideEffectsTest.cpp @@ -25,13 +25,15 @@ #include #include #include -#include +#include using namespace solidity; using namespace solidity::test; using namespace solidity::yul; using namespace solidity::yul::test; using namespace solidity::frontend::test; +using namespace solidity::util; +using namespace solidity::langutil; namespace { @@ -57,19 +59,21 @@ ControlFlowSideEffectsTest::ControlFlowSideEffectsTest(std::string const& _filen TestCase::TestResult ControlFlowSideEffectsTest::run(std::ostream& _stream, std::string const& _linePrefix, bool _formatted) { - auto const& dialect = CommonOptions::get().evmDialect(); - Object obj; - auto parsingResult = parse(m_source); - obj.setCode(parsingResult.first, parsingResult.second); - if (!obj.hasCode()) - BOOST_THROW_EXCEPTION(std::runtime_error("Parsing input failed.")); + YulStack yulStack = parseYul(m_source); + solUnimplementedAssert(yulStack.parserResult()->subObjects.empty(), "Tests with subobjects not supported."); + + if (yulStack.hasErrors()) + { + printYulErrors(yulStack, _stream, _linePrefix, _formatted); + return TestResult::FatalError; + } ControlFlowSideEffectsCollector sideEffects( - dialect, - obj.code()->root() + yulStack.dialect(), + yulStack.parserResult()->code()->root() ); m_obtainedResult.clear(); - forEach(obj.code()->root(), [&](FunctionDefinition const& _fun) { + forEach(yulStack.parserResult()->code()->root(), [&](FunctionDefinition const& _fun) { std::string effectStr = toString(sideEffects.functionSideEffects().at(&_fun)); m_obtainedResult += _fun.name.str() + (effectStr.empty() ? ":" : ": " + effectStr) + "\n"; }); diff --git a/test/libyul/EVMCodeTransformTest.cpp b/test/libyul/EVMCodeTransformTest.cpp index 3d80281c7d91..624a44c3e538 100644 --- a/test/libyul/EVMCodeTransformTest.cpp +++ b/test/libyul/EVMCodeTransformTest.cpp @@ -27,9 +27,7 @@ #include -#include - -#include +#include using namespace solidity; using namespace solidity::test; @@ -55,32 +53,29 @@ TestCase::TestResult EVMCodeTransformTest::run(std::ostream& _stream, std::strin settings.optimizeStackAllocation = m_stackOpt; // Restrict to a single EVM/EOF version combination (the default one) as code generation // can be different from version to version. - YulStack stack( + YulStack yulStack( CommonOptions::get().evmVersion(), CommonOptions::get().eofVersion(), YulStack::Language::StrictAssembly, settings, DebugInfoSelection::All() ); - if (!stack.parseAndAnalyze("", m_source)) + yulStack.parseAndAnalyze("", m_source); + if (yulStack.hasErrors()) { - AnsiColorized(_stream, _formatted, {formatting::BOLD, formatting::RED}) << _linePrefix << "Error parsing source." << std::endl; - SourceReferenceFormatter{_stream, stack, true, false} - .printErrorInformation(stack.errors()); + printYulErrors(yulStack, _stream, _linePrefix, _formatted); return TestResult::FatalError; } evmasm::Assembly assembly{CommonOptions::get().evmVersion(), false, std::nullopt, {}}; EthAssemblyAdapter adapter(assembly); EVMObjectCompiler::compile( - *stack.parserResult(), + *yulStack.parserResult(), adapter, m_stackOpt ); - std::ostringstream output; - output << assembly; - m_obtainedResult = output.str(); + m_obtainedResult = toString(assembly); return checkResult(_stream, _linePrefix, _formatted); } diff --git a/test/libyul/FunctionSideEffects.cpp b/test/libyul/FunctionSideEffects.cpp index d19d87844fcf..4dab4ace2d49 100644 --- a/test/libyul/FunctionSideEffects.cpp +++ b/test/libyul/FunctionSideEffects.cpp @@ -20,12 +20,11 @@ #include #include -#include - #include #include #include #include +#include #include #include @@ -84,16 +83,18 @@ FunctionSideEffects::FunctionSideEffects(std::string const& _filename): TestCase::TestResult FunctionSideEffects::run(std::ostream& _stream, std::string const& _linePrefix, bool _formatted) { - auto const& dialect = CommonOptions::get().evmDialect(); - Object obj; - auto parsingResult = parse(m_source); - obj.setCode(parsingResult.first, parsingResult.second); - if (!obj.hasCode()) - BOOST_THROW_EXCEPTION(std::runtime_error("Parsing input failed.")); + YulStack yulStack = parseYul(m_source); + solUnimplementedAssert(yulStack.parserResult()->subObjects.empty(), "Tests with subobjects not supported."); + + if (yulStack.hasErrors()) + { + printYulErrors(yulStack, _stream, _linePrefix, _formatted); + return TestResult::FatalError; + } std::map functionSideEffects = SideEffectsPropagator::sideEffects( - dialect, - CallGraphGenerator::callGraph(obj.code()->root()) + yulStack.dialect(), + CallGraphGenerator::callGraph(yulStack.parserResult()->code()->root()) ); std::map functionSideEffectsStr; @@ -101,7 +102,7 @@ TestCase::TestResult FunctionSideEffects::run(std::ostream& _stream, std::string { auto const& functionNameStr = std::visit(GenericVisitor{ [](YulName const& _name) { return _name.str(); }, - [&](BuiltinHandle const& _builtin) { return dialect.builtin(_builtin).name; } + [&](BuiltinHandle const& _builtin) { return yulStack.dialect().builtin(_builtin).name; } }, fun.first); functionSideEffectsStr[functionNameStr] = toString(fun.second); } diff --git a/test/libyul/FunctionSideEffects.h b/test/libyul/FunctionSideEffects.h index ac0653733f03..3490c854a0b5 100644 --- a/test/libyul/FunctionSideEffects.h +++ b/test/libyul/FunctionSideEffects.h @@ -18,7 +18,6 @@ #pragma once -#include #include #include diff --git a/test/libyul/KnowledgeBaseTest.cpp b/test/libyul/KnowledgeBaseTest.cpp index eefeb90109bc..6e75442f0621 100644 --- a/test/libyul/KnowledgeBaseTest.cpp +++ b/test/libyul/KnowledgeBaseTest.cpp @@ -20,9 +20,12 @@ #include +#include + #include #include +#include #include #include #include @@ -30,8 +33,6 @@ #include #include -#include - #include using namespace solidity::langutil; @@ -44,27 +45,28 @@ class KnowledgeBaseTest protected: KnowledgeBase constructKnowledgeBase(std::string const& _source) { - ErrorList errorList; - std::shared_ptr analysisInfo; - std::tie(m_object, analysisInfo) = yul::test::parse(_source, m_dialect, errorList); - BOOST_REQUIRE(m_object && errorList.empty() && m_object->hasCode()); + YulStack yulStack = parseYul(_source); + solUnimplementedAssert(yulStack.parserResult()->subObjects.empty(), "Tests with subobjects not supported."); + soltestAssert(!yulStack.hasErrors()); + m_object = yulStack.parserResult(); auto astRoot = std::get(yul::ASTCopier{}(m_object->code()->root())); - NameDispenser dispenser(m_dialect, astRoot); + NameDispenser dispenser(*m_object->dialect(), astRoot); std::set reserved; - OptimiserStepContext context{m_dialect, dispenser, reserved, 0}; + OptimiserStepContext context{*m_object->dialect(), dispenser, reserved, 0}; CommonSubexpressionEliminator::run(context, astRoot); m_ssaValues(astRoot); for (auto const& [name, expression]: m_ssaValues.values()) m_values[name].value = expression; - m_object->setCode(std::make_shared(m_dialect, std::move(astRoot))); - return KnowledgeBase([this](YulName _var) { return util::valueOrNullptr(m_values, _var); }, m_dialect); + m_object->setCode(std::make_shared(*m_object->dialect(), std::move(astRoot))); + return KnowledgeBase( + [this](YulName _var) { return util::valueOrNullptr(m_values, _var); }, + *m_object->dialect() + ); } - EVMDialect m_dialect{solidity::test::CommonOptions::get().evmVersion(), - solidity::test::CommonOptions::get().eofVersion(), true}; std::shared_ptr m_object; SSAValueTracker m_ssaValues; std::map m_values; diff --git a/test/libyul/Metrics.cpp b/test/libyul/Metrics.cpp index 5c7b5fc34de0..9e74cd150e49 100644 --- a/test/libyul/Metrics.cpp +++ b/test/libyul/Metrics.cpp @@ -20,11 +20,14 @@ #include +#include + #include #include #include #include +#include #include @@ -38,9 +41,10 @@ namespace size_t codeSize(std::string const& _source, CodeWeights const _weights = {}) { - std::shared_ptr ast = parse(_source).first; - BOOST_REQUIRE(ast); - return CodeSize::codeSize(ast->root(), _weights); + YulStack yulStack = parseYul(_source); + solUnimplementedAssert(yulStack.parserResult()->subObjects.empty(), "Tests with subobjects not supported."); + soltestAssert(!yulStack.hasErrors()); + return CodeSize::codeSize(yulStack.parserResult()->code()->root(), _weights); } } diff --git a/test/libyul/ObjectCompilerTest.cpp b/test/libyul/ObjectCompilerTest.cpp index d507aa333b06..f7d331d94acb 100644 --- a/test/libyul/ObjectCompilerTest.cpp +++ b/test/libyul/ObjectCompilerTest.cpp @@ -21,8 +21,7 @@ #include #include - -#include +#include #include @@ -31,11 +30,10 @@ #include #include -#include #include -#include +#include using namespace solidity; using namespace solidity::util; @@ -64,31 +62,23 @@ ObjectCompilerTest::ObjectCompilerTest(std::string const& _filename): TestCase::TestResult ObjectCompilerTest::run(std::ostream& _stream, std::string const& _linePrefix, bool const _formatted) { - YulStack stack( - solidity::test::CommonOptions::get().evmVersion(), - solidity::test::CommonOptions::get().eofVersion(), - YulStack::Language::StrictAssembly, - OptimiserSettings::preset(m_optimisationPreset), - DebugInfoSelection::All() - ); - bool successful = stack.parseAndAnalyze("source", m_source); + YulStack yulStack = parseYul(m_source, "source", OptimiserSettings::preset(m_optimisationPreset)); MachineAssemblyObject obj; - if (successful) + if (!yulStack.hasErrors()) { - stack.optimize(); - obj = stack.assemble(YulStack::Machine::EVM); + yulStack.optimize(); + obj = yulStack.assemble(YulStack::Machine::EVM); } - if (stack.hasErrors()) + if (yulStack.hasErrors()) { - AnsiColorized(_stream, _formatted, {formatting::BOLD, formatting::RED}) << _linePrefix << "Error parsing source." << std::endl; - SourceReferenceFormatter{_stream, stack, true, false} - .printErrorInformation(stack.errors()); + printYulErrors(yulStack, _stream, _linePrefix, _formatted); return TestResult::FatalError; } + solAssert(obj.bytecode); solAssert(obj.sourceMappings); - m_obtainedResult = "Assembly:\n" + obj.assembly->assemblyString(stack.debugInfoSelection()); + m_obtainedResult = "Assembly:\n" + obj.assembly->assemblyString(yulStack.debugInfoSelection()); if (obj.bytecode->bytecode.empty()) m_obtainedResult += "-- empty bytecode --\n"; else diff --git a/test/libyul/ObjectCompilerTest.h b/test/libyul/ObjectCompilerTest.h index 3310d80b8e26..604ad0346c27 100644 --- a/test/libyul/ObjectCompilerTest.h +++ b/test/libyul/ObjectCompilerTest.h @@ -51,7 +51,6 @@ class ObjectCompilerTest: public solidity::frontend::test::EVMVersionRestrictedT TestResult run(std::ostream& _stream, std::string const& _linePrefix = "", bool const _formatted = false) override; private: - bool parse(std::ostream& _stream, std::string const& _linePrefix, bool const _formatted); void disambiguate(); frontend::OptimisationPreset m_optimisationPreset; diff --git a/test/libyul/ObjectParser.cpp b/test/libyul/ObjectParser.cpp index 9a891be915d7..23d8aaa57f8e 100644 --- a/test/libyul/ObjectParser.cpp +++ b/test/libyul/ObjectParser.cpp @@ -22,6 +22,7 @@ #include #include +#include #include #include @@ -53,42 +54,14 @@ namespace solidity::yul::test namespace { -std::pair parse(std::string const& _source) -{ - YulStack asmStack( - solidity::test::CommonOptions::get().evmVersion(), - solidity::test::CommonOptions::get().eofVersion(), - YulStack::Language::StrictAssembly, - solidity::frontend::OptimiserSettings::none(), - DebugInfoSelection::All() - ); - bool success = asmStack.parseAndAnalyze("source", _source); - return {success, asmStack.errors()}; -} - std::optional parseAndReturnFirstError(std::string const& _source, bool _allowWarningsAndInfos = true) { - bool success; - ErrorList errors; - tie(success, errors) = parse(_source); - if (!success) - { - BOOST_REQUIRE_EQUAL(errors.size(), 1); - return *errors.front(); - } - else - { - // If success is true, there might still be an error in the assembly stage. - if (_allowWarningsAndInfos && !Error::containsErrors(errors)) - return {}; - else if (!errors.empty()) - { - if (!_allowWarningsAndInfos) - BOOST_CHECK_EQUAL(errors.size(), 1); - return *errors.front(); - } - } - return {}; + YulStack yulStack = parseYul(_source, "source", OptimiserSettings::none()); + if (!yulStack.hasErrorsWarningsOrInfos() || (!yulStack.hasErrors() && _allowWarningsAndInfos)) + return {}; + + BOOST_REQUIRE_EQUAL(yulStack.errors().size(), 1); + return *yulStack.errors().front(); } bool successParse(std::string const& _source, bool _allowWarningsAndInfos = true) diff --git a/test/libyul/SSAControlFlowGraphTest.cpp b/test/libyul/SSAControlFlowGraphTest.cpp index ad825cdf5073..c23a2ca5faf9 100644 --- a/test/libyul/SSAControlFlowGraphTest.cpp +++ b/test/libyul/SSAControlFlowGraphTest.cpp @@ -25,8 +25,7 @@ #include #include - -#include +#include #ifdef ISOLTEST #include @@ -48,29 +47,25 @@ SSAControlFlowGraphTest::SSAControlFlowGraphTest(std::string const& _filename): { m_source = m_reader.source(); auto dialectName = m_reader.stringSetting("dialect", "evm"); - m_dialect = &dialect( - dialectName, - solidity::test::CommonOptions::get().evmVersion(), - solidity::test::CommonOptions::get().eofVersion() - ); + soltestAssert(dialectName == "evm"); // We only have one dialect now m_expectation = m_reader.simpleExpectations(); } TestCase::TestResult SSAControlFlowGraphTest::run(std::ostream& _stream, std::string const& _linePrefix, bool const _formatted) { - ErrorList errors; - auto [object, analysisInfo] = parse(m_source, *m_dialect, errors); - if (!object || !analysisInfo || Error::containsErrors(errors)) + YulStack yulStack = parseYul(m_source); + solUnimplementedAssert(yulStack.parserResult()->subObjects.empty(), "Tests with subobjects not supported."); + + if (yulStack.hasErrors()) { - AnsiColorized(_stream, _formatted, {formatting::BOLD, formatting::RED}) << _linePrefix << "Error parsing source." << std::endl; + printYulErrors(yulStack, _stream, _linePrefix, _formatted); return TestResult::FatalError; } - auto info = AsmAnalyzer::analyzeStrictAssertCorrect(*object); std::unique_ptr controlFlow = SSAControlFlowGraphBuilder::build( - info, - *m_dialect, - object->code()->root() + *yulStack.parserResult()->analysisInfo, + yulStack.dialect(), + yulStack.parserResult()->code()->root() ); ControlFlowLiveness liveness(*controlFlow); m_obtainedResult = controlFlow->toDot(&liveness); diff --git a/test/libyul/SSAControlFlowGraphTest.h b/test/libyul/SSAControlFlowGraphTest.h index 13ca2027ab98..51dd3c86d1a0 100644 --- a/test/libyul/SSAControlFlowGraphTest.h +++ b/test/libyul/SSAControlFlowGraphTest.h @@ -22,11 +22,7 @@ #include -namespace solidity::yul -{ -class Dialect; - -namespace test +namespace solidity::yul::test { class SSAControlFlowGraphTest: public solidity::frontend::test::TestCase @@ -35,8 +31,6 @@ class SSAControlFlowGraphTest: public solidity::frontend::test::TestCase static std::unique_ptr create(Config const& _config); explicit SSAControlFlowGraphTest(std::string const& _filename); TestResult run(std::ostream& _stream, std::string const& _linePrefix = "", bool const _formatted = false) override; -private: - Dialect const* m_dialect = nullptr; }; -} + } diff --git a/test/libyul/StackLayoutGeneratorTest.cpp b/test/libyul/StackLayoutGeneratorTest.cpp index b41f7f21e820..0db063740006 100644 --- a/test/libyul/StackLayoutGeneratorTest.cpp +++ b/test/libyul/StackLayoutGeneratorTest.cpp @@ -26,9 +26,8 @@ #include #include #include -#include +#include -#include #include #include @@ -50,11 +49,7 @@ StackLayoutGeneratorTest::StackLayoutGeneratorTest(std::string const& _filename) { m_source = m_reader.source(); auto dialectName = m_reader.stringSetting("dialect", "evm"); - m_dialect = &dialect( - dialectName, - solidity::test::CommonOptions::get().evmVersion(), - solidity::test::CommonOptions::get().eofVersion() - ); + soltestAssert(dialectName == "evm"); // We only have one dialect now m_expectation = m_reader.simpleExpectations(); } @@ -220,26 +215,31 @@ class StackLayoutPrinter TestCase::TestResult StackLayoutGeneratorTest::run(std::ostream& _stream, std::string const& _linePrefix, bool const _formatted) { - ErrorList errors; - auto [object, analysisInfo] = parse(m_source, *m_dialect, errors); - if (!object || !analysisInfo || Error::containsErrors(errors)) + YulStack yulStack = parseYul(m_source); + solUnimplementedAssert(yulStack.parserResult()->subObjects.empty(), "Tests with subobjects not supported."); + + if (yulStack.hasErrors()) { - AnsiColorized(_stream, _formatted, {formatting::BOLD, formatting::RED}) << _linePrefix << "Error parsing source." << std::endl; + printYulErrors(yulStack, _stream, _linePrefix, _formatted); return TestResult::FatalError; } std::ostringstream output; - std::unique_ptr cfg = ControlFlowGraphBuilder::build(*analysisInfo, *m_dialect, object->code()->root()); + std::unique_ptr cfg = ControlFlowGraphBuilder::build( + *yulStack.parserResult()->analysisInfo, + yulStack.dialect(), + yulStack.parserResult()->code()->root() + ); bool simulateFunctionsWithJumps = true; - if (auto const* evmDialect = dynamic_cast(m_dialect)) + if (auto const* evmDialect = dynamic_cast(&yulStack.dialect())) simulateFunctionsWithJumps = !evmDialect->eofVersion().has_value(); StackLayout stackLayout = StackLayoutGenerator::run(*cfg, simulateFunctionsWithJumps); output << "digraph CFG {\nnodesep=0.7;\nnode[shape=box];\n\n"; - StackLayoutPrinter printer{output, stackLayout, *m_dialect}; + StackLayoutPrinter printer{output, stackLayout, yulStack.dialect()}; printer(*cfg->entry); for (auto function: cfg->functions) printer(cfg->functionInfo.at(function)); diff --git a/test/libyul/StackLayoutGeneratorTest.h b/test/libyul/StackLayoutGeneratorTest.h index e1c6dc7f912f..c7259a02a963 100644 --- a/test/libyul/StackLayoutGeneratorTest.h +++ b/test/libyul/StackLayoutGeneratorTest.h @@ -20,11 +20,7 @@ #include -namespace solidity::yul -{ -class Dialect; - -namespace test +namespace solidity::yul::test { class StackLayoutGeneratorTest: public frontend::test::EVMVersionRestrictedTestCase @@ -36,8 +32,6 @@ class StackLayoutGeneratorTest: public frontend::test::EVMVersionRestrictedTestC } explicit StackLayoutGeneratorTest(std::string const& _filename); TestResult run(std::ostream& _stream, std::string const& _linePrefix = "", bool const _formatted = false) override; -private: - Dialect const* m_dialect = nullptr; }; -} + } diff --git a/test/libyul/SyntaxTest.cpp b/test/libyul/SyntaxTest.cpp index aa37e85afdd8..70f54b86ac71 100644 --- a/test/libyul/SyntaxTest.cpp +++ b/test/libyul/SyntaxTest.cpp @@ -16,39 +16,32 @@ */ // SPDX-License-Identifier: GPL-3.0 -#include -#include - -#include -#include +#include #include -#include #include #include #include +#include + using namespace solidity; using namespace solidity::util; using namespace solidity::langutil; +using namespace solidity::test; using namespace solidity::yul::test; +using namespace solidity::frontend; using namespace solidity::frontend::test; void SyntaxTest::parseAndAnalyze() { - if (m_sources.sources.size() != 1) - BOOST_THROW_EXCEPTION(std::runtime_error{"Expected only one source for yul test."}); - - std::string const& name = m_sources.sources.begin()->first; - std::string const& source = m_sources.sources.begin()->second; + solUnimplementedAssert(m_sources.sources.size() == 1, "Multi-source Yul tests are not supported."); + auto const& [sourceUnitName, source] = *m_sources.sources.begin(); - ErrorList errorList{}; - soltestAssert(m_dialect, ""); - // Silently ignoring the results. - yul::test::parse(source, *m_dialect, errorList); - for (auto const& error: errorList) + YulStack yulStack = parseYul(source); + for (auto const& error: yulStack.errors()) { int locationStart = -1; int locationEnd = -1; @@ -63,21 +56,16 @@ void SyntaxTest::parseAndAnalyze() error->type(), error->errorId(), errorMessage(*error), - name, + sourceUnitName, locationStart, locationEnd }); } - } SyntaxTest::SyntaxTest(std::string const& _filename, langutil::EVMVersion _evmVersion): CommonSyntaxTest(_filename, _evmVersion) { std::string dialectName = m_reader.stringSetting("dialect", "evm"); - m_dialect = &dialect( - dialectName, - solidity::test::CommonOptions::get().evmVersion(), - solidity::test::CommonOptions::get().eofVersion() - ); + soltestAssert(dialectName == "evm"); // We only have one dialect now } diff --git a/test/libyul/SyntaxTest.h b/test/libyul/SyntaxTest.h index 27e59ee61439..9aab3298e1c5 100644 --- a/test/libyul/SyntaxTest.h +++ b/test/libyul/SyntaxTest.h @@ -19,7 +19,6 @@ #pragma once #include -#include namespace solidity::yul::test { @@ -37,9 +36,6 @@ class SyntaxTest: public solidity::test::CommonSyntaxTest ~SyntaxTest() override {} protected: void parseAndAnalyze() override; - -private: - Dialect const* m_dialect = nullptr; }; } diff --git a/test/libyul/YulInterpreterTest.cpp b/test/libyul/YulInterpreterTest.cpp index 25b348dfb2d9..d97211b9761d 100644 --- a/test/libyul/YulInterpreterTest.cpp +++ b/test/libyul/YulInterpreterTest.cpp @@ -18,20 +18,18 @@ #include +#include + #include #include -#include #include #include #include #include #include -#include - -#include #include #include @@ -57,40 +55,23 @@ YulInterpreterTest::YulInterpreterTest(std::string const& _filename): TestCase::TestResult YulInterpreterTest::run(std::ostream& _stream, std::string const& _linePrefix, bool const _formatted) { - if (!parse(_stream, _linePrefix, _formatted)) + YulStack yulStack = parseYul(m_source, "", solidity::frontend::OptimiserSettings::none()); + + if (yulStack.hasErrors()) + { + printYulErrors(yulStack, _stream, _linePrefix, _formatted); return TestResult::FatalError; + } - m_obtainedResult = interpret(); + m_obtainedResult = interpret(yulStack.parserResult()); return checkResult(_stream, _linePrefix, _formatted); } -bool YulInterpreterTest::parse(std::ostream& _stream, std::string const& _linePrefix, bool const _formatted) +std::string YulInterpreterTest::interpret(std::shared_ptr const& _object) { - YulStack stack( - CommonOptions::get().evmVersion(), - CommonOptions::get().eofVersion(), - YulStack::Language::StrictAssembly, - OptimiserSettings::none(), - DebugInfoSelection::All() - ); - if (stack.parseAndAnalyze("", m_source)) - { - m_ast = stack.parserResult()->code(); - m_analysisInfo = stack.parserResult()->analysisInfo; - return true; - } - else - { - AnsiColorized(_stream, _formatted, {formatting::BOLD, formatting::RED}) << _linePrefix << "Error parsing source." << std::endl; - SourceReferenceFormatter{_stream, stack, true, false} - .printErrorInformation(stack.errors()); - return false; - } -} + solAssert(_object && _object->hasCode()); -std::string YulInterpreterTest::interpret() -{ InterpreterState state; state.maxTraceSize = 32; state.maxSteps = 512; @@ -99,8 +80,8 @@ std::string YulInterpreterTest::interpret() { Interpreter::run( state, - CommonOptions::get().evmDialect(), - m_ast->root(), + *_object->dialect(), + _object->code()->root(), /*disableExternalCalls=*/ !m_simulateExternalCallsToSelf, /*disableMemoryTracing=*/ false ); diff --git a/test/libyul/YulInterpreterTest.h b/test/libyul/YulInterpreterTest.h index d591591332ce..b4a21b69a277 100644 --- a/test/libyul/YulInterpreterTest.h +++ b/test/libyul/YulInterpreterTest.h @@ -22,8 +22,7 @@ namespace solidity::yul { -struct AsmAnalysisInfo; -class AST; +class Object; } namespace solidity::yul::test @@ -42,11 +41,8 @@ class YulInterpreterTest: public solidity::frontend::test::EVMVersionRestrictedT TestResult run(std::ostream& _stream, std::string const& _linePrefix = "", bool const _formatted = false) override; private: - bool parse(std::ostream& _stream, std::string const& _linePrefix, bool const _formatted); - std::string interpret(); + std::string interpret(std::shared_ptr const& _object); - std::shared_ptr m_ast; - std::shared_ptr m_analysisInfo; bool m_simulateExternalCallsToSelf = false; }; diff --git a/test/libyul/YulOptimizerTest.cpp b/test/libyul/YulOptimizerTest.cpp index 03f05ffa2ae9..1048fb468854 100644 --- a/test/libyul/YulOptimizerTest.cpp +++ b/test/libyul/YulOptimizerTest.cpp @@ -26,6 +26,7 @@ #include #include #include +#include #include #include @@ -56,24 +57,17 @@ YulOptimizerTest::YulOptimizerTest(std::string const& _filename): m_source = m_reader.source(); auto dialectName = m_reader.stringSetting("dialect", "evm"); - m_dialect = &dialect( - dialectName, - solidity::test::CommonOptions::get().evmVersion(), - solidity::test::CommonOptions::get().eofVersion() - ); + soltestAssert(dialectName == "evm"); // We only have one dialect now m_expectation = m_reader.simpleExpectations(); } TestCase::TestResult YulOptimizerTest::run(std::ostream& _stream, std::string const& _linePrefix, bool const _formatted) { - std::tie(m_object, m_analysisInfo) = parse(_stream, _linePrefix, _formatted, m_source); + m_object = parse(_stream, _linePrefix, _formatted, m_source); if (!m_object) return TestResult::FatalError; - soltestAssert(m_dialect, "Dialect not set."); - - m_object->analysisInfo = m_analysisInfo; YulOptimizerTestCommon tester(m_object); tester.setStep(m_optimizerStep); @@ -91,7 +85,7 @@ TestCase::TestResult YulOptimizerTest::run(std::ostream& _stream, std::string co printedOptimizedObject = optimizedObject->toString(); // Re-parse new code for compilability - if (!std::get<0>(parse(_stream, _linePrefix, _formatted, printedOptimizedObject))) + if (!parse(_stream, _linePrefix, _formatted, printedOptimizedObject)) { util::AnsiColorized(_stream, _formatted, {util::formatting::BOLD, util::formatting::CYAN}) << _linePrefix << "Result after the optimiser:" << std::endl; @@ -104,25 +98,19 @@ TestCase::TestResult YulOptimizerTest::run(std::ostream& _stream, std::string co return checkResult(_stream, _linePrefix, _formatted); } -std::pair, std::shared_ptr> YulOptimizerTest::parse( +std::shared_ptr YulOptimizerTest::parse( std::ostream& _stream, std::string const& _linePrefix, bool const _formatted, std::string const& _source ) { - ErrorList errors; - soltestAssert(m_dialect, ""); - std::shared_ptr object; - std::shared_ptr analysisInfo; - std::tie(object, analysisInfo) = yul::test::parse(_source, *m_dialect, errors); - if (!object || !analysisInfo || Error::containsErrors(errors)) + YulStack yulStack = parseYul(_source); + if (yulStack.hasErrors()) { - AnsiColorized(_stream, _formatted, {formatting::BOLD, formatting::RED}) << _linePrefix << "Error parsing source." << std::endl; - CharStream charStream(_source, ""); - SourceReferenceFormatter{_stream, SingletonCharStreamProvider(charStream), true, false} - .printErrorInformation(errors); - return {}; + printYulErrors(yulStack, _stream, _linePrefix, _formatted); + return nullptr; } - return {std::move(object), std::move(analysisInfo)}; + + return yulStack.parserResult(); } diff --git a/test/libyul/YulOptimizerTest.h b/test/libyul/YulOptimizerTest.h index 207a4b8ce09e..02fd6a0b2700 100644 --- a/test/libyul/YulOptimizerTest.h +++ b/test/libyul/YulOptimizerTest.h @@ -48,16 +48,16 @@ class YulOptimizerTest: public solidity::frontend::test::EVMVersionRestrictedTes TestResult run(std::ostream& _stream, std::string const& _linePrefix = "", bool const _formatted = false) override; private: - std::pair, std::shared_ptr> parse( - std::ostream& _stream, std::string const& _linePrefix, bool const _formatted, std::string const& _source + std::shared_ptr parse( + std::ostream& _stream, + std::string const& _linePrefix, + bool const _formatted, + std::string const& _source ); std::string m_optimizerStep; - Dialect const* m_dialect = nullptr; - std::shared_ptr m_object; - std::shared_ptr m_analysisInfo; }; } From 2ccf0df6162224f2910fde333ecb8f9ecb2bcaf8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Sat, 7 Dec 2024 02:38:29 +0100 Subject: [PATCH 0650/1022] CompilerStack: Use location of the current contract as default location in post-analysis errors --- Changelog.md | 1 + libsolidity/interface/CompilerStack.cpp | 43 ++++++++++++++++--- libsolidity/interface/CompilerStack.h | 8 +++- libyul/YulStack.cpp | 3 ++ .../output.json | 9 ++++ .../operators/shifts/shr_unused.sol | 2 +- .../array/nested_calldata_storage.sol | 2 +- .../array/nested_calldata_storage2.sol | 2 +- .../constants/mod_div_rational.sol | 2 +- .../builtin/builtin_type_definition.sol | 2 +- .../syntaxTests/immutable/no_assignments.sol | 2 +- .../inline_array_fixed_types.sol | 2 +- .../inline_arrays/inline_array_rationals.sol | 2 +- .../303_fixed_type_int_conversion.sol | 2 +- ...304_fixed_type_rational_int_conversion.sol | 2 +- ...ixed_type_rational_fraction_conversion.sol | 2 +- .../307_rational_unary_minus_operation.sol | 2 +- .../312_leading_zero_rationals_convert.sol | 2 +- .../314_fixed_type_zero_handling.sol | 2 +- ..._fixed_type_valid_explicit_conversions.sol | 2 +- .../323_mapping_with_fixed_literal.sol | 2 +- .../324_fixed_points_inside_structs.sol | 2 +- ...8_rational_to_fixed_literal_expression.sol | 2 +- .../343_integer_and_fixed_interaction.sol | 2 +- .../declaring_fixed_and_ufixed_variables.sol | 2 +- .../lexer_numbers_with_underscores_fixed.sol | 2 +- ...ional_number_literal_to_fixed_implicit.sol | 2 +- 27 files changed, 77 insertions(+), 31 deletions(-) diff --git a/Changelog.md b/Changelog.md index 9aaa1ca8b022..731640653d5a 100644 --- a/Changelog.md +++ b/Changelog.md @@ -4,6 +4,7 @@ Language Features: Compiler Features: + * Error Reporting: Errors reported during code generation now point at the location of the contract when more fine-grained location is not available. * SMTChecker: Z3 is now a runtime dependency, not a build dependency (except for emscripten build). diff --git a/libsolidity/interface/CompilerStack.cpp b/libsolidity/interface/CompilerStack.cpp index 9649b79c842a..9d76ced02330 100644 --- a/libsolidity/interface/CompilerStack.cpp +++ b/libsolidity/interface/CompilerStack.cpp @@ -779,11 +779,11 @@ bool CompilerStack::compile(State _stopAfter) } catch (Error const& _error) { - m_errorReporter.codeGenerationError(_error); + reportCodeGenerationError(_error, contract); } catch (UnimplementedFeatureError const& _error) { - reportUnimplementedFeatureError(_error); + reportUnimplementedFeatureError(_error, contract); } if (m_errorReporter.hasErrors()) @@ -1614,7 +1614,7 @@ void CompilerStack::generateEVMFromIR(ContractDefinition const& _contract) if (stack.hasErrors()) { for (std::shared_ptr const& error: stack.errors()) - reportIRPostAnalysisError(error.get()); + reportIRPostAnalysisError(error.get(), compiledContract.contract); return; } @@ -2010,18 +2010,47 @@ experimental::Analysis const& CompilerStack::experimentalAnalysis() const return *m_experimentalAnalysis; } -void CompilerStack::reportUnimplementedFeatureError(UnimplementedFeatureError const& _error) +void CompilerStack::reportUnimplementedFeatureError( + UnimplementedFeatureError const& _error, + ContractDefinition const* _contractDefinition +) { solAssert(_error.comment(), "Errors must include a message for the user."); + if (_error.sourceLocation().sourceName) + solAssert(m_sources.count(*_error.sourceLocation().sourceName) != 0); + + m_errorReporter.unimplementedFeatureError( + 1834_error, + (_error.sourceLocation().sourceName || !_contractDefinition) ? + _error.sourceLocation() : + _contractDefinition->location(), + *_error.comment() + ); +} - m_errorReporter.unimplementedFeatureError(1834_error, _error.sourceLocation(), *_error.comment()); +void CompilerStack::reportCodeGenerationError(Error const& _error, ContractDefinition const* _contractDefinition) +{ + solAssert(_error.type() == Error::Type::CodeGenerationError); + solAssert(_error.comment(), "Errors must include a message for the user."); + if (_error.sourceLocation() && _error.sourceLocation()->sourceName) + solAssert(m_sources.count(*_error.sourceLocation()->sourceName) != 0); + solAssert(_contractDefinition); + + m_errorReporter.codeGenerationError( + _error.errorId(), + (_error.sourceLocation() && _error.sourceLocation()->sourceName) ? + *_error.sourceLocation() : + _contractDefinition->location(), + *_error.comment() + ); } -void CompilerStack::reportIRPostAnalysisError(Error const* _error) +void CompilerStack::reportIRPostAnalysisError(Error const* _error, ContractDefinition const* _contractDefinition) { solAssert(_error); solAssert(_error->comment(), "Errors must include a message for the user."); solAssert(!_error->secondarySourceLocation()); + solAssert(_contractDefinition); // Do not report Yul warnings and infos. These are only reported in pure Yul compilation. if (!Error::isError(_error->severity())) @@ -2032,7 +2061,7 @@ void CompilerStack::reportIRPostAnalysisError(Error const* _error) _error->type(), // Ignore the original location. It's likely missing, but even if not, it points at Yul source. // CompilerStack can only point at locations in Solidity sources. - SourceLocation{}, + _contractDefinition->location(), *_error->comment() ); } diff --git a/libsolidity/interface/CompilerStack.h b/libsolidity/interface/CompilerStack.h index 81a039403b9b..f36eedde0611 100644 --- a/libsolidity/interface/CompilerStack.h +++ b/libsolidity/interface/CompilerStack.h @@ -578,8 +578,12 @@ class CompilerStack: public langutil::CharStreamProvider, public evmasm::Abstrac FunctionDefinition const& _function ) const; - void reportUnimplementedFeatureError(langutil::UnimplementedFeatureError const& _error); - void reportIRPostAnalysisError(langutil::Error const* _error); + void reportUnimplementedFeatureError( + langutil::UnimplementedFeatureError const& _error, + ContractDefinition const* _contractDefinition = nullptr + ); + void reportCodeGenerationError(langutil::Error const& _error, ContractDefinition const* _contractDefinition); + void reportIRPostAnalysisError(langutil::Error const* _error, ContractDefinition const* _contractDefinition); ReadCallback::Callback m_readFile; OptimiserSettings m_optimiserSettings; diff --git a/libyul/YulStack.cpp b/libyul/YulStack.cpp index 791b7103ded8..03e22c8d1a80 100644 --- a/libyul/YulStack.cpp +++ b/libyul/YulStack.cpp @@ -439,6 +439,9 @@ Dialect const& YulStack::dialect() const void YulStack::reportUnimplementedFeatureError(UnimplementedFeatureError const& _error) { + yulAssert(m_charStream); yulAssert(_error.comment(), "Errors must include a message for the user."); + if (_error.sourceLocation().sourceName) + yulAssert(*_error.sourceLocation().sourceName == m_charStream->name()); m_errorReporter.unimplementedFeatureError(1920_error, _error.sourceLocation(), *_error.comment()); } diff --git a/test/cmdlineTests/standard_outputs_on_compilation_error/output.json b/test/cmdlineTests/standard_outputs_on_compilation_error/output.json index e0f4e37e6ae0..0fa7fcff3cda 100644 --- a/test/cmdlineTests/standard_outputs_on_compilation_error/output.json +++ b/test/cmdlineTests/standard_outputs_on_compilation_error/output.json @@ -54,10 +54,19 @@ "component": "general", "errorCode": "1284", "formattedMessage": "CodeGenerationError: Some immutables were read from but never assigned, possibly because of optimization. + --> C:4:1: + | +4 | contract C { + | ^ (Relevant source part starts here and spans across multiple lines). ", "message": "Some immutables were read from but never assigned, possibly because of optimization.", "severity": "error", + "sourceLocation": { + "end": 320, + "file": "C", + "start": 56 + }, "type": "CodeGenerationError" } ], diff --git a/test/libsolidity/smtCheckerTests/operators/shifts/shr_unused.sol b/test/libsolidity/smtCheckerTests/operators/shifts/shr_unused.sol index 50438175895e..2134068db614 100644 --- a/test/libsolidity/smtCheckerTests/operators/shifts/shr_unused.sol +++ b/test/libsolidity/smtCheckerTests/operators/shifts/shr_unused.sol @@ -8,4 +8,4 @@ contract C { // SMTEngine: all // ---- // Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. -// UnimplementedFeatureError 1834: Not yet implemented - FixedPointType. +// UnimplementedFeatureError 1834: (0-80): Not yet implemented - FixedPointType. diff --git a/test/libsolidity/syntaxTests/array/nested_calldata_storage.sol b/test/libsolidity/syntaxTests/array/nested_calldata_storage.sol index 18bf550c066b..9aa5fce1211a 100644 --- a/test/libsolidity/syntaxTests/array/nested_calldata_storage.sol +++ b/test/libsolidity/syntaxTests/array/nested_calldata_storage.sol @@ -6,4 +6,4 @@ contract C { } // ---- -// UnimplementedFeatureError 1834: Copying nested calldata dynamic arrays to storage is not implemented in the old code generator. +// UnimplementedFeatureError 1834: (35-127): Copying nested calldata dynamic arrays to storage is not implemented in the old code generator. diff --git a/test/libsolidity/syntaxTests/array/nested_calldata_storage2.sol b/test/libsolidity/syntaxTests/array/nested_calldata_storage2.sol index 9f5bb8eab5b1..f1125b4d232b 100644 --- a/test/libsolidity/syntaxTests/array/nested_calldata_storage2.sol +++ b/test/libsolidity/syntaxTests/array/nested_calldata_storage2.sol @@ -6,4 +6,4 @@ contract C { } // ---- -// UnimplementedFeatureError 1834: Copying nested calldata dynamic arrays to storage is not implemented in the old code generator. +// UnimplementedFeatureError 1834: (35-125): Copying nested calldata dynamic arrays to storage is not implemented in the old code generator. diff --git a/test/libsolidity/syntaxTests/constants/mod_div_rational.sol b/test/libsolidity/syntaxTests/constants/mod_div_rational.sol index 5c127eb4a253..68d3bfc7ae03 100644 --- a/test/libsolidity/syntaxTests/constants/mod_div_rational.sol +++ b/test/libsolidity/syntaxTests/constants/mod_div_rational.sol @@ -5,4 +5,4 @@ contract C { fixed a4 = 0 / -0.123; } // ---- -// UnimplementedFeatureError 1834: Not yet implemented - FixedPointType. +// UnimplementedFeatureError 1834: (0-150): Not yet implemented - FixedPointType. diff --git a/test/libsolidity/syntaxTests/experimental/builtin/builtin_type_definition.sol b/test/libsolidity/syntaxTests/experimental/builtin/builtin_type_definition.sol index ed7db1ec6c8b..858b9132dd32 100644 --- a/test/libsolidity/syntaxTests/experimental/builtin/builtin_type_definition.sol +++ b/test/libsolidity/syntaxTests/experimental/builtin/builtin_type_definition.sol @@ -89,4 +89,4 @@ contract C { // Info 4164: (563-574): Inferred type: (bool, word) -> word // Info 4164: (563-567): Inferred type: (?bm:type, ?bn:type) // Info 4164: (575-576): Inferred type: (bool, word) -// UnimplementedFeatureError 1834: No support for calling functions pointers yet. +// UnimplementedFeatureError 1834: (267-586): No support for calling functions pointers yet. diff --git a/test/libsolidity/syntaxTests/immutable/no_assignments.sol b/test/libsolidity/syntaxTests/immutable/no_assignments.sol index 7357d174a8d5..7d7948671419 100644 --- a/test/libsolidity/syntaxTests/immutable/no_assignments.sol +++ b/test/libsolidity/syntaxTests/immutable/no_assignments.sol @@ -10,4 +10,4 @@ contract C { // ==== // optimize-yul: true // ---- -// CodeGenerationError 1284: Some immutables were read from but never assigned, possibly because of optimization. +// CodeGenerationError 1284: (0-168): Some immutables were read from but never assigned, possibly because of optimization. diff --git a/test/libsolidity/syntaxTests/inline_arrays/inline_array_fixed_types.sol b/test/libsolidity/syntaxTests/inline_arrays/inline_array_fixed_types.sol index 604f9b029800..8e51bd1886c1 100644 --- a/test/libsolidity/syntaxTests/inline_arrays/inline_array_fixed_types.sol +++ b/test/libsolidity/syntaxTests/inline_arrays/inline_array_fixed_types.sol @@ -6,4 +6,4 @@ contract test { // ---- // Warning 2072: (50-67): Unused local variable. // Warning 2018: (20-119): Function state mutability can be restricted to pure -// UnimplementedFeatureError 1834: Not yet implemented - FixedPointType. +// UnimplementedFeatureError 1834: (0-121): Not yet implemented - FixedPointType. diff --git a/test/libsolidity/syntaxTests/inline_arrays/inline_array_rationals.sol b/test/libsolidity/syntaxTests/inline_arrays/inline_array_rationals.sol index 63df5c044916..0382672fe38e 100644 --- a/test/libsolidity/syntaxTests/inline_arrays/inline_array_rationals.sol +++ b/test/libsolidity/syntaxTests/inline_arrays/inline_array_rationals.sol @@ -6,4 +6,4 @@ contract test { // ---- // Warning 2072: (50-73): Unused local variable. // Warning 2018: (20-118): Function state mutability can be restricted to pure -// UnimplementedFeatureError 1834: Not yet implemented - FixedPointType. +// UnimplementedFeatureError 1834: (0-120): Not yet implemented - FixedPointType. diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/303_fixed_type_int_conversion.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/303_fixed_type_int_conversion.sol index 58c74b9ad0b8..88a407fef98d 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/303_fixed_type_int_conversion.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/303_fixed_type_int_conversion.sol @@ -9,4 +9,4 @@ contract test { } // ---- // Warning 2018: (20-147): Function state mutability can be restricted to pure -// UnimplementedFeatureError 1834: Not yet implemented - FixedPointType. +// UnimplementedFeatureError 1834: (0-149): Not yet implemented - FixedPointType. diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/304_fixed_type_rational_int_conversion.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/304_fixed_type_rational_int_conversion.sol index 404cbc4bce0d..0e3cb3b6cb47 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/304_fixed_type_rational_int_conversion.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/304_fixed_type_rational_int_conversion.sol @@ -7,4 +7,4 @@ contract test { } // ---- // Warning 2018: (20-104): Function state mutability can be restricted to pure -// UnimplementedFeatureError 1834: Not yet implemented - FixedPointType. +// UnimplementedFeatureError 1834: (0-106): Not yet implemented - FixedPointType. diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/305_fixed_type_rational_fraction_conversion.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/305_fixed_type_rational_fraction_conversion.sol index b113c6bcce52..ada627037e49 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/305_fixed_type_rational_fraction_conversion.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/305_fixed_type_rational_fraction_conversion.sol @@ -7,4 +7,4 @@ contract test { } // ---- // Warning 2018: (20-108): Function state mutability can be restricted to pure -// UnimplementedFeatureError 1834: Not yet implemented - FixedPointType. +// UnimplementedFeatureError 1834: (0-110): Not yet implemented - FixedPointType. diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/307_rational_unary_minus_operation.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/307_rational_unary_minus_operation.sol index e80024a98ad8..adb9fbe699ce 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/307_rational_unary_minus_operation.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/307_rational_unary_minus_operation.sol @@ -6,4 +6,4 @@ contract test { } } // ---- -// UnimplementedFeatureError 1834: Not yet implemented - FixedPointType. +// UnimplementedFeatureError 1834: (0-126): Not yet implemented - FixedPointType. diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/312_leading_zero_rationals_convert.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/312_leading_zero_rationals_convert.sol index 20be0208c11f..e763fa18be20 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/312_leading_zero_rationals_convert.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/312_leading_zero_rationals_convert.sol @@ -8,4 +8,4 @@ contract A { } } // ---- -// UnimplementedFeatureError 1834: Not yet implemented - FixedPointType. +// UnimplementedFeatureError 1834: (0-289): Not yet implemented - FixedPointType. diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/314_fixed_type_zero_handling.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/314_fixed_type_zero_handling.sol index 7415ed6e85f0..b9205f01b1d9 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/314_fixed_type_zero_handling.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/314_fixed_type_zero_handling.sol @@ -6,4 +6,4 @@ contract test { } // ---- // Warning 2018: (20-104): Function state mutability can be restricted to pure -// UnimplementedFeatureError 1834: Not yet implemented - FixedPointType. +// UnimplementedFeatureError 1834: (0-106): Not yet implemented - FixedPointType. diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/317_fixed_type_valid_explicit_conversions.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/317_fixed_type_valid_explicit_conversions.sol index fa32ec7dd86a..1282c24daf89 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/317_fixed_type_valid_explicit_conversions.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/317_fixed_type_valid_explicit_conversions.sol @@ -7,4 +7,4 @@ contract test { } // ---- // Warning 2018: (20-182): Function state mutability can be restricted to pure -// UnimplementedFeatureError 1834: Not yet implemented - FixedPointType. +// UnimplementedFeatureError 1834: (0-184): Not yet implemented - FixedPointType. diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/323_mapping_with_fixed_literal.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/323_mapping_with_fixed_literal.sol index cb730221dfcd..3ee670cd585c 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/323_mapping_with_fixed_literal.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/323_mapping_with_fixed_literal.sol @@ -5,4 +5,4 @@ contract test { } } // ---- -// UnimplementedFeatureError 1834: Not yet implemented - FixedPointType. +// UnimplementedFeatureError 1834: (0-130): Not yet implemented - FixedPointType. diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/324_fixed_points_inside_structs.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/324_fixed_points_inside_structs.sol index 9bc6243029d1..ba467a67b131 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/324_fixed_points_inside_structs.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/324_fixed_points_inside_structs.sol @@ -6,4 +6,4 @@ contract test { myStruct a = myStruct(3.125, 3); } // ---- -// UnimplementedFeatureError 1834: Not yet implemented - FixedPointType. +// UnimplementedFeatureError 1834: (0-115): Not yet implemented - FixedPointType. diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/328_rational_to_fixed_literal_expression.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/328_rational_to_fixed_literal_expression.sol index 8391734aec0f..b5162bcd9720 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/328_rational_to_fixed_literal_expression.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/328_rational_to_fixed_literal_expression.sol @@ -13,4 +13,4 @@ contract test { // ---- // Warning 2519: (238-252): This declaration shadows an existing declaration. // Warning 2018: (20-339): Function state mutability can be restricted to pure -// UnimplementedFeatureError 1834: Not yet implemented - FixedPointType. +// UnimplementedFeatureError 1834: (0-341): Not yet implemented - FixedPointType. diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/343_integer_and_fixed_interaction.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/343_integer_and_fixed_interaction.sol index 15ca25931efd..3ebd54d4541a 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/343_integer_and_fixed_interaction.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/343_integer_and_fixed_interaction.sol @@ -6,4 +6,4 @@ contract test { // ---- // Warning 2072: (50-58): Unused local variable. // Warning 2018: (20-89): Function state mutability can be restricted to pure -// UnimplementedFeatureError 1834: Not yet implemented - FixedPointType. +// UnimplementedFeatureError 1834: (0-91): Not yet implemented - FixedPointType. diff --git a/test/libsolidity/syntaxTests/parsing/declaring_fixed_and_ufixed_variables.sol b/test/libsolidity/syntaxTests/parsing/declaring_fixed_and_ufixed_variables.sol index ea41bbf3ec7a..2518a4b57e47 100644 --- a/test/libsolidity/syntaxTests/parsing/declaring_fixed_and_ufixed_variables.sol +++ b/test/libsolidity/syntaxTests/parsing/declaring_fixed_and_ufixed_variables.sol @@ -11,4 +11,4 @@ contract A { // Warning 2072: (93-104): Unused local variable. // Warning 2072: (114-121): Unused local variable. // Warning 2018: (41-128): Function state mutability can be restricted to pure -// UnimplementedFeatureError 1834: Fixed point types not implemented. +// UnimplementedFeatureError 1834: (0-130): Fixed point types not implemented. diff --git a/test/libsolidity/syntaxTests/parsing/lexer_numbers_with_underscores_fixed.sol b/test/libsolidity/syntaxTests/parsing/lexer_numbers_with_underscores_fixed.sol index 9932c4c3d48b..9346264edbcd 100644 --- a/test/libsolidity/syntaxTests/parsing/lexer_numbers_with_underscores_fixed.sol +++ b/test/libsolidity/syntaxTests/parsing/lexer_numbers_with_underscores_fixed.sol @@ -7,4 +7,4 @@ contract C { } } // ---- -// UnimplementedFeatureError 1834: Not yet implemented - FixedPointType. +// UnimplementedFeatureError 1834: (0-109): Not yet implemented - FixedPointType. diff --git a/test/libsolidity/syntaxTests/types/rational_number_literal_to_fixed_implicit.sol b/test/libsolidity/syntaxTests/types/rational_number_literal_to_fixed_implicit.sol index a93555fd7120..e62728770d90 100644 --- a/test/libsolidity/syntaxTests/types/rational_number_literal_to_fixed_implicit.sol +++ b/test/libsolidity/syntaxTests/types/rational_number_literal_to_fixed_implicit.sol @@ -13,4 +13,4 @@ contract C { } } // ---- -// UnimplementedFeatureError 1834: Not yet implemented - FixedPointType. +// UnimplementedFeatureError 1834: (0-317): Not yet implemented - FixedPointType. From 682d2c617177fe082544b5a93f6520ee6aa2b537 Mon Sep 17 00:00:00 2001 From: rodiazet Date: Mon, 2 Dec 2024 11:37:23 +0100 Subject: [PATCH 0651/1022] Prune unreferenced functions from CFG --- .../backends/evm/ControlFlowGraphBuilder.cpp | 27 ++++++++++++-- ...une_unreachable_function_non_returning.yul | 29 +++++++++++++++ .../prune_unreachable_function_recursion.yul | 26 ++++++++++++++ .../eof/prune_unreferenced_function.yul | 33 +++++++++++++++++ ...une_unreachable_function_non_returning.yul | 29 +++++++++++++++ .../prune_unreachable_function_recursion.yul | 27 ++++++++++++++ .../prune_unreferenced_function.yul | 35 +++++++++++++++++++ 7 files changed, 203 insertions(+), 3 deletions(-) create mode 100644 test/libyul/objectCompiler/eof/prune_unreachable_function_non_returning.yul create mode 100644 test/libyul/objectCompiler/eof/prune_unreachable_function_recursion.yul create mode 100644 test/libyul/objectCompiler/eof/prune_unreferenced_function.yul create mode 100644 test/libyul/objectCompiler/prune_unreachable_function_non_returning.yul create mode 100644 test/libyul/objectCompiler/prune_unreachable_function_recursion.yul create mode 100644 test/libyul/objectCompiler/prune_unreferenced_function.yul diff --git a/libyul/backends/evm/ControlFlowGraphBuilder.cpp b/libyul/backends/evm/ControlFlowGraphBuilder.cpp index cce5c98557e2..3986d54a0a36 100644 --- a/libyul/backends/evm/ControlFlowGraphBuilder.cpp +++ b/libyul/backends/evm/ControlFlowGraphBuilder.cpp @@ -52,12 +52,23 @@ namespace /// Removes edges to blocks that are not reachable. void cleanUnreachable(CFG& _cfg) { + // If operation is a function call it adds the callee entry as child + auto const addFunctionsEntries = [&_cfg](CFG::BasicBlock* _node, auto&& _addChild) + { + for (auto const& operation: _node->operations) + { + if (auto const* functionCall = std::get_if(&operation.operation)) + { + auto const functionInfo = _cfg.functionInfo.at(&(functionCall->function.get())); + _addChild(functionInfo.entry); + } + } + }; + // Determine which blocks are reachable from the entry. util::BreadthFirstSearch reachabilityCheck{{_cfg.entry}}; - for (auto const& functionInfo: _cfg.functionInfo | ranges::views::values) - reachabilityCheck.verticesToTraverse.emplace_back(functionInfo.entry); - reachabilityCheck.run([&](CFG::BasicBlock* _node, auto&& _addChild) { + addFunctionsEntries(_node, _addChild); visit(util::GenericVisitor{ [&](CFG::BasicBlock::Jump const& _jump) { _addChild(_jump.target); @@ -77,6 +88,16 @@ void cleanUnreachable(CFG& _cfg) cxx20::erase_if(node->entries, [&](CFG::BasicBlock* entry) -> bool { return !reachabilityCheck.visited.count(entry); }); + + // Remove functions which are never referenced. + _cfg.functions.erase(std::remove_if(_cfg.functions.begin(), _cfg.functions.end(), [&](auto const& item) { + return !reachabilityCheck.visited.count(_cfg.functionInfo.at(item).entry); + }), _cfg.functions.end()); + + // Remove functionInfos which are never referenced. + cxx20::erase_if(_cfg.functionInfo, [&](auto const& entry) -> bool { + return !reachabilityCheck.visited.count(entry.second.entry); + }); } /// Sets the ``recursive`` member to ``true`` for all recursive function calls. diff --git a/test/libyul/objectCompiler/eof/prune_unreachable_function_non_returning.yul b/test/libyul/objectCompiler/eof/prune_unreachable_function_non_returning.yul new file mode 100644 index 000000000000..c1ed84ca4249 --- /dev/null +++ b/test/libyul/objectCompiler/eof/prune_unreachable_function_non_returning.yul @@ -0,0 +1,29 @@ +object "Contract" { + code { + f() + g() + + function f() { revert(0, 0) } + function g() { mstore(0, 2) } + } +} + +// ==== +// EVMVersion: >=shanghai +// bytecodeFormat: >=EOFv1 +// optimizationPreset: none +// ---- +// Assembly: +// /* "source":53:56 */ +// jumpf{code_section_1} +// +// code_section_1: assembly { +// /* "source":124:125 */ +// 0x00 +// /* "source":114:126 */ +// dup1 +// revert +// } +// Bytecode: ef000101000802000200030003040000000080ffff0080ffffe500015f80fd +// Opcodes: 0xEF STOP ADD ADD STOP ADDMOD MUL STOP MUL STOP SUB STOP SUB DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP DUP1 SELFDESTRUCT SELFDESTRUCT JUMPF 0x1 PUSH0 DUP1 REVERT +// SourceMappings: 53:3:0:i:0124:1:0:-:0;114:12; diff --git a/test/libyul/objectCompiler/eof/prune_unreachable_function_recursion.yul b/test/libyul/objectCompiler/eof/prune_unreachable_function_recursion.yul new file mode 100644 index 000000000000..f3869c9ad48c --- /dev/null +++ b/test/libyul/objectCompiler/eof/prune_unreachable_function_recursion.yul @@ -0,0 +1,26 @@ +object "Contract" { + code { + f() + g() + + function f() { f() } + function g() { mstore(0, 2) } + } +} + +// ==== +// EVMVersion: >=shanghai +// bytecodeFormat: >=EOFv1 +// optimizationPreset: none +// ---- +// Assembly: +// /* "source":53:56 */ +// jumpf{code_section_1} +// +// code_section_1: assembly { +// /* "source":114:117 */ +// jumpf{code_section_1} +// } +// Bytecode: ef000101000802000200030003040000000080ffff0080ffffe50001e50001 +// Opcodes: 0xEF STOP ADD ADD STOP ADDMOD MUL STOP MUL STOP SUB STOP SUB DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP DUP1 SELFDESTRUCT SELFDESTRUCT JUMPF 0x1 JUMPF 0x1 +// SourceMappings: 53:3:0:i:0114:3:0:i:0 diff --git a/test/libyul/objectCompiler/eof/prune_unreferenced_function.yul b/test/libyul/objectCompiler/eof/prune_unreferenced_function.yul new file mode 100644 index 000000000000..610c9a4580cd --- /dev/null +++ b/test/libyul/objectCompiler/eof/prune_unreferenced_function.yul @@ -0,0 +1,33 @@ +object "Contract" { + code { + g() + + function f() { mstore(0, 3) } + function g() { mstore(0, 2) } + } +} + +// ==== +// EVMVersion: >=shanghai +// bytecodeFormat: >=EOFv1 +// optimizationPreset: none +// ---- +// Assembly: +// /* "source":41:44 */ +// callf{code_section_1} +// /* "source":29:98 */ +// stop +// +// code_section_1: assembly { +// /* "source":88:89 */ +// 0x02 +// /* "source":85:86 */ +// 0x00 +// /* "source":78:90 */ +// mstore +// /* "source":55:92 */ +// retf +// } +// Bytecode: ef000101000802000200040005040000000080ffff0000ffffe300010060025f52e4 +// Opcodes: 0xEF STOP ADD ADD STOP ADDMOD MUL STOP MUL STOP DIV STOP SDIV DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP STOP SELFDESTRUCT SELFDESTRUCT CALLF 0x1 STOP PUSH1 0x2 PUSH0 MSTORE RETF +// SourceMappings: 41:3:0:i:0;29:69::-88:1:0:-:0;85;78:12;55:37::o diff --git a/test/libyul/objectCompiler/prune_unreachable_function_non_returning.yul b/test/libyul/objectCompiler/prune_unreachable_function_non_returning.yul new file mode 100644 index 000000000000..9c0a0acdc779 --- /dev/null +++ b/test/libyul/objectCompiler/prune_unreachable_function_non_returning.yul @@ -0,0 +1,29 @@ +object "Contract" { + code { + f() + g() + + function f() { revert(0, 0) } + function g() { mstore(0, 2) } + } +} + +// ==== +// EVMVersion: >=shanghai +// bytecodeFormat: legacy +// optimizationPreset: none +// ---- +// Assembly: +// /* "source":53:56 */ +// tag_1 +// jump // in +// /* "source":91:128 */ +// tag_1: +// /* "source":124:125 */ +// 0x00 +// /* "source":114:126 */ +// dup1 +// revert +// Bytecode: 6003565b5f80fd +// Opcodes: PUSH1 0x3 JUMP JUMPDEST PUSH0 DUP1 REVERT +// SourceMappings: 53:3:0:-:0;:::i;91:37::-;124:1;114:12; diff --git a/test/libyul/objectCompiler/prune_unreachable_function_recursion.yul b/test/libyul/objectCompiler/prune_unreachable_function_recursion.yul new file mode 100644 index 000000000000..1000cfd31f44 --- /dev/null +++ b/test/libyul/objectCompiler/prune_unreachable_function_recursion.yul @@ -0,0 +1,27 @@ +object "Contract" { + code { + f() + g() + + function f() { f() } + function g() { mstore(0, 2) } + } +} + +// ==== +// EVMVersion: >=shanghai +// bytecodeFormat: legacy +// optimizationPreset: none +// ---- +// Assembly: +// /* "source":53:56 */ +// tag_1 +// jump // in +// /* "source":91:119 */ +// tag_1: +// /* "source":114:117 */ +// tag_1 +// jump // in +// Bytecode: 6003565b600356 +// Opcodes: PUSH1 0x3 JUMP JUMPDEST PUSH1 0x3 JUMP +// SourceMappings: 53:3:0:-:0;:::i;91:28::-;114:3;:::i diff --git a/test/libyul/objectCompiler/prune_unreferenced_function.yul b/test/libyul/objectCompiler/prune_unreferenced_function.yul new file mode 100644 index 000000000000..88010bd72555 --- /dev/null +++ b/test/libyul/objectCompiler/prune_unreferenced_function.yul @@ -0,0 +1,35 @@ +object "Contract" { + code { + g() + + function f() { mstore(0, 3) } + function g() { mstore(0, 2) } + } +} + +// ==== +// EVMVersion: >=shanghai +// bytecodeFormat: legacy +// optimizationPreset: none +// ---- +// Assembly: +// /* "source":41:44 */ +// tag_2 +// tag_1 +// jump // in +// tag_2: +// /* "source":29:98 */ +// stop +// /* "source":55:92 */ +// tag_1: +// /* "source":88:89 */ +// 0x02 +// /* "source":85:86 */ +// 0x00 +// /* "source":78:90 */ +// mstore +// /* "source":55:92 */ +// jump // out +// Bytecode: 60056007565b005b60025f5256 +// Opcodes: PUSH1 0x5 PUSH1 0x7 JUMP JUMPDEST STOP JUMPDEST PUSH1 0x2 PUSH0 MSTORE JUMP +// SourceMappings: 41:3:0:-:0;;:::i;:::-;29:69;55:37;88:1;85;78:12;55:37::o From bbb6a116e3c2732c7e5201d02387928a9fa983aa Mon Sep 17 00:00:00 2001 From: rodiazet Date: Mon, 16 Dec 2024 12:20:48 +0100 Subject: [PATCH 0652/1022] Update tests expectations --- .../stackReuse/function_argument_reuse.yul | 15 ++++++++- ...ction_argument_reuse_without_retparams.yul | 23 +++++++++---- .../stackReuse/function_many_arguments.yul | 33 ++++++++++++++++++- .../stackReuse/function_params.yul | 13 +++++++- .../function_params_and_retparams.yul | 15 ++++++++- ...ction_params_and_retparams_partly_used.yul | 15 ++++++++- .../stackReuse/function_retparam.yul | 9 ++++- .../stackReuse/function_retparam_block.yul | 11 ++++++- .../function_retparam_declaration.yul | 11 ++++++- .../stackReuse/function_retparam_for.yul | 11 ++++++- .../stackReuse/function_retparam_if.yul | 19 ++++++++--- .../stackReuse/function_retparam_leave.yul | 11 ++++++- .../stackReuse/function_retparam_read.yul | 11 ++++++- .../function_retparam_unassigned.yul | 11 ++++++- .../function_retparam_unassigned_multiple.yul | 9 ++++- .../stackReuse/function_trivial.yul | 13 ++++++-- .../function_with_body_embedded.yul | 16 ++++++++- .../unassigned_return_variable.yul | 10 ++++-- ...une_unreachable_function_non_returning.yul | 4 +-- .../prune_unreachable_function_recursion.yul | 5 ++- .../eof/prune_unreferenced_function.yul | 4 +-- .../leading_and_trailing_dots.yul | 20 ++--------- test/libyul/yulControlFlowGraph/function.yul | 26 +++++---------- test/libyul/yulStackLayout/function.yul | 31 ++++++----------- 24 files changed, 254 insertions(+), 92 deletions(-) diff --git a/test/libyul/evmCodeTransform/stackReuse/function_argument_reuse.yul b/test/libyul/evmCodeTransform/stackReuse/function_argument_reuse.yul index 96637da89fc1..515765ad268b 100644 --- a/test/libyul/evmCodeTransform/stackReuse/function_argument_reuse.yul +++ b/test/libyul/evmCodeTransform/stackReuse/function_argument_reuse.yul @@ -1,10 +1,23 @@ { function f(a, b, c) -> x { pop(address()) sstore(a, c) pop(callvalue()) x := b } + pop(f(0, 0, 0)) } // ==== // stackOptimization: true // ---- -// /* "":0:88 */ +// /* "":95:105 */ +// tag_2 +// /* "":103:104 */ +// 0x00 +// /* "":95:105 */ +// dup1 +// dup1 +// tag_1 +// jump // in +// tag_2: +// /* "":91:106 */ +// pop +// /* "":0:108 */ // stop // /* "":6:86 */ // tag_1: 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 b5cc611879ec..09ce0b84a2b2 100644 --- a/test/libyul/evmCodeTransform/stackReuse/function_argument_reuse_without_retparams.yul +++ b/test/libyul/evmCodeTransform/stackReuse/function_argument_reuse_without_retparams.yul @@ -3,12 +3,23 @@ mstore(0x80, x) if calldataload(0) { sstore(y, y) } } + + f(0, 0) } // ==== -// stackOptimization: true // EVMVersion: >=shanghai +// stackOptimization: true // ---- -// /* "":0:88 */ +// /* "":90:97 */ +// tag_2 +// /* "":95:96 */ +// 0x00 +// /* "":90:97 */ +// dup1 +// tag_1 +// jump // in +// tag_2: +// /* "":0:99 */ // stop // /* "":4:86 */ // tag_1: @@ -21,18 +32,18 @@ // /* "":50:65 */ // calldataload // /* "":47:82 */ -// tag_2 +// tag_3 // jumpi // /* "":21:86 */ -// tag_3: +// tag_4: // /* "":4:86 */ // pop // jump // out // /* "":66:82 */ -// tag_2: +// tag_3: // /* "":68:80 */ // dup1 // sstore // /* "":66:82 */ // 0x00 -// jump(tag_3) +// jump(tag_4) diff --git a/test/libyul/evmCodeTransform/stackReuse/function_many_arguments.yul b/test/libyul/evmCodeTransform/stackReuse/function_many_arguments.yul index 17ccdd3caf39..e78cda9cba17 100644 --- a/test/libyul/evmCodeTransform/stackReuse/function_many_arguments.yul +++ b/test/libyul/evmCodeTransform/stackReuse/function_many_arguments.yul @@ -21,11 +21,42 @@ mstore(0x0340, a19) x := a20 } + + pop(f(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)) } // ==== // stackOptimization: true // ---- -// /* "":0:662 */ +// /* "":670:731 */ +// tag_2 +// /* "":729:730 */ +// 0x00 +// /* "":670:731 */ +// dup1 +// dup1 +// dup1 +// dup1 +// dup1 +// dup1 +// dup1 +// dup1 +// dup1 +// dup1 +// dup1 +// dup1 +// dup1 +// dup1 +// dup1 +// dup1 +// dup1 +// dup1 +// dup1 +// tag_1 +// jump // in +// tag_2: +// /* "":666:732 */ +// pop +// /* "":0:734 */ // stop // /* "":6:660 */ // tag_1: diff --git a/test/libyul/evmCodeTransform/stackReuse/function_params.yul b/test/libyul/evmCodeTransform/stackReuse/function_params.yul index e8d9bb30cc1b..dda389524edd 100644 --- a/test/libyul/evmCodeTransform/stackReuse/function_params.yul +++ b/test/libyul/evmCodeTransform/stackReuse/function_params.yul @@ -1,10 +1,21 @@ { function f(a, b) { } + + f(0, 0) } // ==== // stackOptimization: true // ---- -// /* "":0:28 */ +// /* "":32:39 */ +// tag_2 +// /* "":37:38 */ +// 0x00 +// /* "":32:39 */ +// dup1 +// tag_1 +// jump // in +// tag_2: +// /* "":0:41 */ // stop // /* "":6:26 */ // tag_1: diff --git a/test/libyul/evmCodeTransform/stackReuse/function_params_and_retparams.yul b/test/libyul/evmCodeTransform/stackReuse/function_params_and_retparams.yul index 1d157663a56d..bf6ed9f14b6e 100644 --- a/test/libyul/evmCodeTransform/stackReuse/function_params_and_retparams.yul +++ b/test/libyul/evmCodeTransform/stackReuse/function_params_and_retparams.yul @@ -4,11 +4,24 @@ // can be reused. { function f(a, b, c, d) -> x, y { } + + let x, y := f(0, 0, 0, 0) } // ==== // stackOptimization: true // ---- -// /* "":210:252 */ +// /* "":268:281 */ +// tag_2 +// /* "":279:280 */ +// 0x00 +// /* "":268:281 */ +// dup1 +// dup1 +// dup1 +// tag_1 +// jump // in +// tag_2: +// /* "":210:283 */ // stop // /* "":216:250 */ // tag_1: 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 d0fc0506f88c..cf38dc0b4a04 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 @@ -1,10 +1,23 @@ { function f(a, b, c, d) -> x, y { b := 3 let s := 9 y := 2 mstore(s, y) } + + let x, y := f(0, 0, 0, 0) } // ==== // stackOptimization: true // ---- -// /* "":0:80 */ +// /* "":97:110 */ +// tag_2 +// /* "":108:109 */ +// 0x00 +// /* "":97:110 */ +// dup1 +// dup1 +// dup1 +// tag_1 +// jump // in +// tag_2: +// /* "":0:112 */ // stop // /* "":6:78 */ // tag_1: diff --git a/test/libyul/evmCodeTransform/stackReuse/function_retparam.yul b/test/libyul/evmCodeTransform/stackReuse/function_retparam.yul index bee0d3f635d9..eb912cbe2c00 100644 --- a/test/libyul/evmCodeTransform/stackReuse/function_retparam.yul +++ b/test/libyul/evmCodeTransform/stackReuse/function_retparam.yul @@ -1,10 +1,17 @@ { function f() -> x, y { } + + let x, y := f() } // ==== // stackOptimization: true // ---- -// /* "":0:32 */ +// /* "":49:52 */ +// tag_2 +// tag_1 +// jump // in +// tag_2: +// /* "":0:54 */ // stop // /* "":6:30 */ // tag_1: diff --git a/test/libyul/evmCodeTransform/stackReuse/function_retparam_block.yul b/test/libyul/evmCodeTransform/stackReuse/function_retparam_block.yul index 5a9e7704e68a..42186ca69dde 100644 --- a/test/libyul/evmCodeTransform/stackReuse/function_retparam_block.yul +++ b/test/libyul/evmCodeTransform/stackReuse/function_retparam_block.yul @@ -1,10 +1,19 @@ { function f() -> x { pop(address()) { pop(callvalue()) } } + + pop(f()) } // ==== // stackOptimization: true // ---- -// /* "":0:65 */ +// /* "":74:77 */ +// tag_2 +// tag_1 +// jump // in +// tag_2: +// /* "":70:78 */ +// pop +// /* "":0:80 */ // stop // /* "":6:63 */ // tag_1: diff --git a/test/libyul/evmCodeTransform/stackReuse/function_retparam_declaration.yul b/test/libyul/evmCodeTransform/stackReuse/function_retparam_declaration.yul index 97bffac381a1..402555e2d6ed 100644 --- a/test/libyul/evmCodeTransform/stackReuse/function_retparam_declaration.yul +++ b/test/libyul/evmCodeTransform/stackReuse/function_retparam_declaration.yul @@ -1,10 +1,19 @@ { function f() -> x { pop(address()) let y := callvalue() } + + pop(f()) } // ==== // stackOptimization: true // ---- -// /* "":0:65 */ +// /* "":74:77 */ +// tag_2 +// tag_1 +// jump // in +// tag_2: +// /* "":70:78 */ +// pop +// /* "":0:80 */ // stop // /* "":6:63 */ // tag_1: diff --git a/test/libyul/evmCodeTransform/stackReuse/function_retparam_for.yul b/test/libyul/evmCodeTransform/stackReuse/function_retparam_for.yul index c18fb7c37e50..583173222628 100644 --- a/test/libyul/evmCodeTransform/stackReuse/function_retparam_for.yul +++ b/test/libyul/evmCodeTransform/stackReuse/function_retparam_for.yul @@ -1,10 +1,19 @@ { function f() -> x { pop(address()) for { pop(callvalue()) } 0 {} { } } + + pop(f()) } // ==== // stackOptimization: true // ---- -// /* "":0:78 */ +// /* "":86:89 */ +// tag_2 +// tag_1 +// jump // in +// tag_2: +// /* "":82:90 */ +// pop +// /* "":0:92 */ // stop // /* "":6:76 */ // tag_1: diff --git a/test/libyul/evmCodeTransform/stackReuse/function_retparam_if.yul b/test/libyul/evmCodeTransform/stackReuse/function_retparam_if.yul index 08dda5a3bc28..6a53eab99108 100644 --- a/test/libyul/evmCodeTransform/stackReuse/function_retparam_if.yul +++ b/test/libyul/evmCodeTransform/stackReuse/function_retparam_if.yul @@ -1,10 +1,19 @@ { function f() -> x { pop(address()) if 1 { pop(callvalue()) } } + + pop(f()) } // ==== // stackOptimization: true // ---- -// /* "":0:70 */ +// /* "":78:81 */ +// tag_2 +// tag_1 +// jump // in +// tag_2: +// /* "":74:82 */ +// pop +// /* "":0:84 */ // stop // /* "":6:68 */ // tag_1: @@ -19,17 +28,17 @@ // /* "":26:40 */ // pop // /* "":41:66 */ -// tag_2 +// tag_3 // jumpi // /* "":24:68 */ -// tag_3: +// tag_4: // /* "":6:68 */ // jump // out // /* "":46:66 */ -// tag_2: +// tag_3: // /* "":52:63 */ // callvalue // /* "":48:64 */ // pop // /* "":46:66 */ -// jump(tag_3) +// jump(tag_4) diff --git a/test/libyul/evmCodeTransform/stackReuse/function_retparam_leave.yul b/test/libyul/evmCodeTransform/stackReuse/function_retparam_leave.yul index 9ac0c00bf8f2..ecaf79f76f0e 100644 --- a/test/libyul/evmCodeTransform/stackReuse/function_retparam_leave.yul +++ b/test/libyul/evmCodeTransform/stackReuse/function_retparam_leave.yul @@ -1,10 +1,19 @@ { function f() -> x { pop(address()) leave pop(callvalue()) } + + pop(f()) } // ==== // stackOptimization: true // ---- -// /* "":0:67 */ +// /* "":75:78 */ +// tag_2 +// tag_1 +// jump // in +// tag_2: +// /* "":71:79 */ +// pop +// /* "":0:81 */ // stop // /* "":6:65 */ // tag_1: diff --git a/test/libyul/evmCodeTransform/stackReuse/function_retparam_read.yul b/test/libyul/evmCodeTransform/stackReuse/function_retparam_read.yul index fcc8278e6719..4fe4dcd4e5be 100644 --- a/test/libyul/evmCodeTransform/stackReuse/function_retparam_read.yul +++ b/test/libyul/evmCodeTransform/stackReuse/function_retparam_read.yul @@ -1,10 +1,19 @@ { function f() -> x { pop(address()) sstore(0, x) pop(callvalue()) } + + pop(f()) } // ==== // stackOptimization: true // ---- -// /* "":0:74 */ +// /* "":82:85 */ +// tag_2 +// tag_1 +// jump // in +// tag_2: +// /* "":78:86 */ +// pop +// /* "":0:88 */ // stop // /* "":6:72 */ // tag_1: diff --git a/test/libyul/evmCodeTransform/stackReuse/function_retparam_unassigned.yul b/test/libyul/evmCodeTransform/stackReuse/function_retparam_unassigned.yul index 1cc19a464105..977f8c9d638d 100644 --- a/test/libyul/evmCodeTransform/stackReuse/function_retparam_unassigned.yul +++ b/test/libyul/evmCodeTransform/stackReuse/function_retparam_unassigned.yul @@ -1,10 +1,19 @@ { function f() -> x { pop(callvalue()) } + + pop(f()) } // ==== // stackOptimization: true // ---- -// /* "":0:46 */ +// /* "":54:57 */ +// tag_2 +// tag_1 +// jump // in +// tag_2: +// /* "":50:58 */ +// pop +// /* "":0:60 */ // stop // /* "":6:44 */ // tag_1: diff --git a/test/libyul/evmCodeTransform/stackReuse/function_retparam_unassigned_multiple.yul b/test/libyul/evmCodeTransform/stackReuse/function_retparam_unassigned_multiple.yul index e44e3b43729b..7d3d9605703d 100644 --- a/test/libyul/evmCodeTransform/stackReuse/function_retparam_unassigned_multiple.yul +++ b/test/libyul/evmCodeTransform/stackReuse/function_retparam_unassigned_multiple.yul @@ -1,10 +1,17 @@ { function f() -> x, y, z { pop(callvalue()) } + + let x, y, z := f() } // ==== // stackOptimization: true // ---- -// /* "":0:52 */ +// /* "":71:74 */ +// tag_2 +// tag_1 +// jump // in +// tag_2: +// /* "":0:76 */ // stop // /* "":6:50 */ // tag_1: diff --git a/test/libyul/evmCodeTransform/stackReuse/function_trivial.yul b/test/libyul/evmCodeTransform/stackReuse/function_trivial.yul index 3d6286efdb07..ad5098af7f6d 100644 --- a/test/libyul/evmCodeTransform/stackReuse/function_trivial.yul +++ b/test/libyul/evmCodeTransform/stackReuse/function_trivial.yul @@ -1,11 +1,18 @@ { - function f() { } + function f() { } + + f() } // ==== // stackOptimization: true // ---- -// /* "":0:22 */ +// /* "":28:31 */ +// tag_2 +// tag_1 +// jump // in +// tag_2: +// /* "":0:33 */ // stop -// /* "":4:20 */ +// /* "":6:22 */ // 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 f8480bc91ea8..20651dd49e48 100644 --- a/test/libyul/evmCodeTransform/stackReuse/function_with_body_embedded.yul +++ b/test/libyul/evmCodeTransform/stackReuse/function_with_body_embedded.yul @@ -5,6 +5,8 @@ let x := a a := 3 t := a } b := 7 + + pop(f(0, 0)) } // ==== // stackOptimization: true @@ -15,7 +17,19 @@ // pop // /* "":182:183 */ // 0x07 -// /* "":0:185 */ +// /* "":193:200 */ +// pop +// tag_2 +// /* "":198:199 */ +// 0x00 +// /* "":193:200 */ +// dup1 +// tag_1 +// jump // in +// tag_2: +// /* "":189:201 */ +// pop +// /* "":0:203 */ // stop // /* "":21:172 */ // tag_1: diff --git a/test/libyul/evmCodeTransform/unassigned_return_variable.yul b/test/libyul/evmCodeTransform/unassigned_return_variable.yul index 666fefe1aa64..e0ff7eddf5f9 100644 --- a/test/libyul/evmCodeTransform/unassigned_return_variable.yul +++ b/test/libyul/evmCodeTransform/unassigned_return_variable.yul @@ -3,12 +3,18 @@ function g(b,s) -> y { y := g(b, g(y, s)) } + + pop(g(0,0)) } // ==== // stackOptimization: true // ---- -// /* "":0:111 */ -// stop +// /* "":121:122 */ +// 0x00 +// /* "":117:123 */ +// dup1 +// tag_1 +// jump // in // /* "":60:109 */ // tag_1: // pop diff --git a/test/libyul/objectCompiler/eof/prune_unreachable_function_non_returning.yul b/test/libyul/objectCompiler/eof/prune_unreachable_function_non_returning.yul index c1ed84ca4249..f4792619f185 100644 --- a/test/libyul/objectCompiler/eof/prune_unreachable_function_non_returning.yul +++ b/test/libyul/objectCompiler/eof/prune_unreachable_function_non_returning.yul @@ -24,6 +24,6 @@ object "Contract" { // dup1 // revert // } -// Bytecode: ef000101000802000200030003040000000080ffff0080ffffe500015f80fd -// Opcodes: 0xEF STOP ADD ADD STOP ADDMOD MUL STOP MUL STOP SUB STOP SUB DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP DUP1 SELFDESTRUCT SELFDESTRUCT JUMPF 0x1 PUSH0 DUP1 REVERT +// Bytecode: ef000101000802000200030003040000000080000000800002e500015f80fd +// Opcodes: 0xEF STOP ADD ADD STOP ADDMOD MUL STOP MUL STOP SUB STOP SUB DIV STOP STOP STOP STOP DUP1 STOP STOP STOP DUP1 STOP MUL JUMPF 0x1 PUSH0 DUP1 REVERT // SourceMappings: 53:3:0:i:0124:1:0:-:0;114:12; diff --git a/test/libyul/objectCompiler/eof/prune_unreachable_function_recursion.yul b/test/libyul/objectCompiler/eof/prune_unreachable_function_recursion.yul index f3869c9ad48c..0276b4cad5e9 100644 --- a/test/libyul/objectCompiler/eof/prune_unreachable_function_recursion.yul +++ b/test/libyul/objectCompiler/eof/prune_unreachable_function_recursion.yul @@ -9,7 +9,6 @@ object "Contract" { } // ==== -// EVMVersion: >=shanghai // bytecodeFormat: >=EOFv1 // optimizationPreset: none // ---- @@ -21,6 +20,6 @@ object "Contract" { // /* "source":114:117 */ // jumpf{code_section_1} // } -// Bytecode: ef000101000802000200030003040000000080ffff0080ffffe50001e50001 -// Opcodes: 0xEF STOP ADD ADD STOP ADDMOD MUL STOP MUL STOP SUB STOP SUB DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP DUP1 SELFDESTRUCT SELFDESTRUCT JUMPF 0x1 JUMPF 0x1 +// Bytecode: ef000101000802000200030003040000000080000000800000e50001e50001 +// Opcodes: 0xEF STOP ADD ADD STOP ADDMOD MUL STOP MUL STOP SUB STOP SUB DIV STOP STOP STOP STOP DUP1 STOP STOP STOP DUP1 STOP STOP JUMPF 0x1 JUMPF 0x1 // SourceMappings: 53:3:0:i:0114:3:0:i:0 diff --git a/test/libyul/objectCompiler/eof/prune_unreferenced_function.yul b/test/libyul/objectCompiler/eof/prune_unreferenced_function.yul index 610c9a4580cd..8cbb294cda49 100644 --- a/test/libyul/objectCompiler/eof/prune_unreferenced_function.yul +++ b/test/libyul/objectCompiler/eof/prune_unreferenced_function.yul @@ -28,6 +28,6 @@ object "Contract" { // /* "source":55:92 */ // retf // } -// Bytecode: ef000101000802000200040005040000000080ffff0000ffffe300010060025f52e4 -// Opcodes: 0xEF STOP ADD ADD STOP ADDMOD MUL STOP MUL STOP DIV STOP SDIV DIV STOP STOP STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT STOP STOP SELFDESTRUCT SELFDESTRUCT CALLF 0x1 STOP PUSH1 0x2 PUSH0 MSTORE RETF +// Bytecode: ef000101000802000200040005040000000080000000000002e300010060025f52e4 +// Opcodes: 0xEF STOP ADD ADD STOP ADDMOD MUL STOP MUL STOP DIV STOP SDIV DIV STOP STOP STOP STOP DUP1 STOP STOP STOP STOP STOP MUL CALLF 0x1 STOP PUSH1 0x2 PUSH0 MSTORE RETF // SourceMappings: 41:3:0:i:0;29:69::-88:1:0:-:0;85;78:12;55:37::o diff --git a/test/libyul/objectCompiler/leading_and_trailing_dots.yul b/test/libyul/objectCompiler/leading_and_trailing_dots.yul index 9d32cadc0cd7..ddacd8b45dde 100644 --- a/test/libyul/objectCompiler/leading_and_trailing_dots.yul +++ b/test/libyul/objectCompiler/leading_and_trailing_dots.yul @@ -25,20 +25,6 @@ // /* "source":134:138 */ // tag_1 // jump // in -// /* "source":149:181 */ -// tag_2: -// /* "source":177:178 */ -// 0x00 -// /* "source":175:179 */ -// tag_2 -// jump // in -// /* "source":190:222 */ -// tag_3: -// /* "source":218:219 */ -// 0x00 -// /* "source":216:220 */ -// tag_3 -// jump // in -// Bytecode: 60025b5f6002565b5f6007565b5f600c56 -// Opcodes: PUSH1 0x2 JUMPDEST PUSH0 PUSH1 0x2 JUMP JUMPDEST PUSH0 PUSH1 0x7 JUMP JUMPDEST PUSH0 PUSH1 0xC JUMP -// SourceMappings: 53:1:0:-:0;108:32;136:1;134:4;:::i;149:32::-;177:1;175:4;:::i;190:32::-;218:1;216:4;:::i +// Bytecode: 60025b5f600256 +// Opcodes: PUSH1 0x2 JUMPDEST PUSH0 PUSH1 0x2 JUMP +// SourceMappings: 53:1:0:-:0;108:32;136:1;134:4;:::i diff --git a/test/libyul/yulControlFlowGraph/function.yul b/test/libyul/yulControlFlowGraph/function.yul index 90c4b380e48c..f65c7505cb9d 100644 --- a/test/libyul/yulControlFlowGraph/function.yul +++ b/test/libyul/yulControlFlowGraph/function.yul @@ -44,30 +44,22 @@ // Block1Exit [label="FunctionReturn[f]"]; // Block1 -> Block1Exit; // -// FunctionEntry_g_2 [label="function g()"]; -// FunctionEntry_g_2 -> Block2; +// FunctionEntry_h_2 [label="function h(x)"]; +// FunctionEntry_h_2 -> Block2; // Block2 [label="\ -// sstore: [ 0x0101 0x01 ] => [ ]\l\ -// "]; -// Block2Exit [label="FunctionReturn[g]"]; -// Block2 -> Block2Exit; -// -// FunctionEntry_h_3 [label="function h(x)"]; -// FunctionEntry_h_3 -> Block3; -// Block3 [label="\ // f: [ RET[f] 0x00 x ] => [ TMP[f, 0] ]\l\ // h: [ TMP[f, 0] ] => [ ]\l\ // "]; -// Block3Exit [label="Terminated"]; -// Block3 -> Block3Exit; +// Block2Exit [label="Terminated"]; +// Block2 -> Block2Exit; // -// FunctionEntry_i_4 [label="function i() -> v, w"]; -// FunctionEntry_i_4 -> Block4; -// Block4 [label="\ +// FunctionEntry_i_3 [label="function i() -> v, w"]; +// FunctionEntry_i_3 -> Block3; +// Block3 [label="\ // Assignment(v): [ 0x0202 ] => [ v ]\l\ // Assignment(w): [ 0x0303 ] => [ w ]\l\ // "]; -// Block4Exit [label="FunctionReturn[i]"]; -// Block4 -> Block4Exit; +// Block3Exit [label="FunctionReturn[i]"]; +// Block3 -> Block3Exit; // // } diff --git a/test/libyul/yulStackLayout/function.yul b/test/libyul/yulStackLayout/function.yul index ccf97422f44f..e01a8dcb3610 100644 --- a/test/libyul/yulStackLayout/function.yul +++ b/test/libyul/yulStackLayout/function.yul @@ -17,6 +17,8 @@ let x, y := i() h(x) h(y) + // This calla of g() is unreachable too as the one in h() but we wanna cover both cases. + g() } // ---- // digraph CFG { @@ -63,23 +65,10 @@ // Block1Exit [label="FunctionReturn[f]"]; // Block1 -> Block1Exit; // -// FunctionEntry_g [label="function g()\l\ -// [ RET ]"]; -// FunctionEntry_g -> Block2; -// Block2 [label="\ -// [ RET ]\l\ -// [ RET 0x0101 0x01 ]\l\ -// sstore\l\ -// [ RET ]\l\ -// [ RET ]\l\ -// "]; -// Block2Exit [label="FunctionReturn[g]"]; -// Block2 -> Block2Exit; -// // FunctionEntry_h [label="function h(x)\l\ // [ RET x ]"]; -// FunctionEntry_h -> Block3; -// Block3 [label="\ +// FunctionEntry_h -> Block2; +// Block2 [label="\ // [ RET[f] 0x00 x ]\l\ // [ RET[f] 0x00 x ]\l\ // f\l\ @@ -89,13 +78,13 @@ // [ ]\l\ // [ ]\l\ // "]; -// Block3Exit [label="Terminated"]; -// Block3 -> Block3Exit; +// Block2Exit [label="Terminated"]; +// Block2 -> Block2Exit; // // FunctionEntry_i [label="function i() -> v, w\l\ // [ RET ]"]; -// FunctionEntry_i -> Block4; -// Block4 [label="\ +// FunctionEntry_i -> Block3; +// Block3 [label="\ // [ RET ]\l\ // [ RET 0x0202 ]\l\ // Assignment(v)\l\ @@ -105,7 +94,7 @@ // [ v RET w ]\l\ // [ v w RET ]\l\ // "]; -// Block4Exit [label="FunctionReturn[i]"]; -// Block4 -> Block4Exit; +// Block3Exit [label="FunctionReturn[i]"]; +// Block3 -> Block3Exit; // // } From 8d98c6d8ad440a932b8e299ee6bebb028f9f2693 Mon Sep 17 00:00:00 2001 From: rodiazet Date: Wed, 18 Dec 2024 17:05:12 +0100 Subject: [PATCH 0653/1022] eof: Support `bytecodeFormat` flag by `FunctionSideEffects` tests --- test/libyul/FunctionSideEffects.cpp | 2 +- test/libyul/FunctionSideEffects.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test/libyul/FunctionSideEffects.cpp b/test/libyul/FunctionSideEffects.cpp index 4dab4ace2d49..cb24ed764c32 100644 --- a/test/libyul/FunctionSideEffects.cpp +++ b/test/libyul/FunctionSideEffects.cpp @@ -75,7 +75,7 @@ std::string toString(SideEffects const& _sideEffects) } FunctionSideEffects::FunctionSideEffects(std::string const& _filename): - TestCase(_filename) + EVMVersionRestrictedTestCase(_filename) { m_source = m_reader.source(); m_expectation = m_reader.simpleExpectations(); diff --git a/test/libyul/FunctionSideEffects.h b/test/libyul/FunctionSideEffects.h index 3490c854a0b5..9a7b77c14968 100644 --- a/test/libyul/FunctionSideEffects.h +++ b/test/libyul/FunctionSideEffects.h @@ -28,7 +28,7 @@ namespace solidity::yul::test { -class FunctionSideEffects: public solidity::frontend::test::TestCase +class FunctionSideEffects: public solidity::frontend::test::EVMVersionRestrictedTestCase { public: static std::unique_ptr create(Config const& _config) From 535e2a97053d420bd3f62dc0938b2de26593e3d9 Mon Sep 17 00:00:00 2001 From: rodiazet Date: Wed, 18 Dec 2024 17:05:12 +0100 Subject: [PATCH 0654/1022] eof: Update `functionSideEffects` tests --- test/libyul/functionSideEffects/otherImmovables.yul | 2 ++ test/libyul/functionSideEffects/state.yul | 2 ++ test/libyul/functionSideEffects/storage.yul | 2 ++ 3 files changed, 6 insertions(+) diff --git a/test/libyul/functionSideEffects/otherImmovables.yul b/test/libyul/functionSideEffects/otherImmovables.yul index bb02dba1d8ac..01dfd877cdee 100644 --- a/test/libyul/functionSideEffects/otherImmovables.yul +++ b/test/libyul/functionSideEffects/otherImmovables.yul @@ -4,6 +4,8 @@ function g() { stop() } function h() { invalid() } } +// ==== +// bytecodeFormat: legacy // ---- // : movable, movable apart from effects, can be removed, can be removed if no msize // a: can be removed, can be removed if no msize diff --git a/test/libyul/functionSideEffects/state.yul b/test/libyul/functionSideEffects/state.yul index e605ff1e514a..c8b467094132 100644 --- a/test/libyul/functionSideEffects/state.yul +++ b/test/libyul/functionSideEffects/state.yul @@ -3,6 +3,8 @@ function f() { a() } function g() { sstore(0, 1) } } +// ==== +// bytecodeFormat: legacy // ---- // : movable, movable apart from effects, can be removed, can be removed if no msize // a: writes other state, writes storage, writes memory diff --git a/test/libyul/functionSideEffects/storage.yul b/test/libyul/functionSideEffects/storage.yul index 038c368a29d9..3d1e2d836d37 100644 --- a/test/libyul/functionSideEffects/storage.yul +++ b/test/libyul/functionSideEffects/storage.yul @@ -4,6 +4,8 @@ function g() { pop(callcode(100, 0x010, 10, 0x00, 32, 0x0100, 32))} function h() { pop(sload(0))} } +// ==== +// bytecodeFormat: legacy // ---- // : movable, movable apart from effects, can be removed, can be removed if no msize // a: writes storage From 8b31ce84a60979767aadd36ba9a5a6d5cc5891f2 Mon Sep 17 00:00:00 2001 From: rodiazet Date: Wed, 18 Dec 2024 17:05:12 +0100 Subject: [PATCH 0655/1022] eof: Re-enable excluded earlier tests. --- .circleci/soltest.sh | 3 --- 1 file changed, 3 deletions(-) diff --git a/.circleci/soltest.sh b/.circleci/soltest.sh index 9631a72568c9..940ff1122aa9 100755 --- a/.circleci/soltest.sh +++ b/.circleci/soltest.sh @@ -56,9 +56,6 @@ EOF_EXCLUDES=( --run_test='!SolidityInlineAssembly/Analysis/large_constant' --run_test='!SolidityInlineAssembly/Analysis/staticcall' --run_test='!ViewPureChecker/assembly_staticcall' - --run_test='!functionSideEffects/otherImmovables' - --run_test='!functionSideEffects/state' - --run_test='!functionSideEffects/storage' --run_test='!gasTests/abiv2' --run_test='!gasTests/abiv2_optimised' --run_test='!gasTests/data_storage' From f2d41d39ac504731448f618c1a3a892cbc41d478 Mon Sep 17 00:00:00 2001 From: rodiazet Date: Fri, 13 Dec 2024 12:15:32 +0100 Subject: [PATCH 0656/1022] Adjust `copyConstructorArgumentsToMemoryFunction` function to make it supports EOF --- libsolidity/codegen/ABIFunctions.h | 3 +- libsolidity/codegen/Compiler.h | 11 +++++-- libsolidity/codegen/CompilerContext.h | 5 +-- libsolidity/codegen/YulUtilFunctions.cpp | 33 ++++++++++++------- libsolidity/codegen/YulUtilFunctions.h | 3 ++ .../codegen/ir/IRGenerationContext.cpp | 4 +-- libsolidity/codegen/ir/IRGenerator.cpp | 7 ++-- libsolidity/codegen/ir/IRGenerator.h | 2 +- .../codegen/ir/IRGeneratorForStatements.cpp | 4 +-- libsolidity/interface/CompilerStack.cpp | 7 +++- .../output.json | 2 ++ test/libsolidity/Assembly.cpp | 1 + .../SolidityExpressionCompiler.cpp | 1 + .../base_constructor_arguments.sol | 2 ++ 14 files changed, 60 insertions(+), 25 deletions(-) diff --git a/libsolidity/codegen/ABIFunctions.h b/libsolidity/codegen/ABIFunctions.h index b7f7f8ae5735..d357447ac3e8 100644 --- a/libsolidity/codegen/ABIFunctions.h +++ b/libsolidity/codegen/ABIFunctions.h @@ -56,13 +56,14 @@ class ABIFunctions public: explicit ABIFunctions( langutil::EVMVersion _evmVersion, + std::optional _eofVersion, RevertStrings _revertStrings, MultiUseYulFunctionCollector& _functionCollector ): m_evmVersion(_evmVersion), m_revertStrings(_revertStrings), m_functionCollector(_functionCollector), - m_utils(_evmVersion, m_revertStrings, m_functionCollector) + m_utils(_evmVersion, _eofVersion, m_revertStrings, m_functionCollector) {} /// @returns name of an assembly function to ABI-encode values of @a _givenTypes diff --git a/libsolidity/codegen/Compiler.h b/libsolidity/codegen/Compiler.h index 1267c1a2d92c..bc801ff5782b 100644 --- a/libsolidity/codegen/Compiler.h +++ b/libsolidity/codegen/Compiler.h @@ -37,10 +37,15 @@ namespace solidity::frontend class Compiler { public: - Compiler(langutil::EVMVersion _evmVersion, RevertStrings _revertStrings, OptimiserSettings _optimiserSettings): + Compiler( + langutil::EVMVersion _evmVersion, + std::optional _eofVersion, + RevertStrings _revertStrings, + OptimiserSettings _optimiserSettings + ): m_optimiserSettings(std::move(_optimiserSettings)), - m_runtimeContext(_evmVersion, _revertStrings), - m_context(_evmVersion, _revertStrings, &m_runtimeContext) + m_runtimeContext(_evmVersion, _eofVersion, _revertStrings), + m_context(_evmVersion, _eofVersion, _revertStrings, &m_runtimeContext) { } /// Compiles a contract. diff --git a/libsolidity/codegen/CompilerContext.h b/libsolidity/codegen/CompilerContext.h index 2805b8daf8d0..17559fbf4182 100644 --- a/libsolidity/codegen/CompilerContext.h +++ b/libsolidity/codegen/CompilerContext.h @@ -62,6 +62,7 @@ class CompilerContext public: explicit CompilerContext( langutil::EVMVersion _evmVersion, + std::optional _eofVersion, RevertStrings _revertStrings, CompilerContext* _runtimeContext = nullptr ): @@ -70,8 +71,8 @@ class CompilerContext m_revertStrings(_revertStrings), m_reservedMemory{0}, m_runtimeContext(_runtimeContext), - m_abiFunctions(m_evmVersion, m_revertStrings, m_yulFunctionCollector), - m_yulUtilFunctions(m_evmVersion, m_revertStrings, m_yulFunctionCollector) + m_abiFunctions(m_evmVersion, _eofVersion, m_revertStrings, m_yulFunctionCollector), + m_yulUtilFunctions(m_evmVersion, _eofVersion, m_revertStrings, m_yulFunctionCollector) { if (m_runtimeContext) m_runtimeSub = size_t(m_asm->newSub(m_runtimeContext->m_asm).data()); diff --git a/libsolidity/codegen/YulUtilFunctions.cpp b/libsolidity/codegen/YulUtilFunctions.cpp index c908c7ae0936..ffeaa790e1e8 100644 --- a/libsolidity/codegen/YulUtilFunctions.cpp +++ b/libsolidity/codegen/YulUtilFunctions.cpp @@ -285,7 +285,7 @@ std::string YulUtilFunctions::revertWithError( errorArgumentTypes.push_back(arg->annotation().type); } templ("argumentVars", joinHumanReadablePrefixed(errorArgumentVars)); - templ("encode", ABIFunctions(m_evmVersion, m_revertStrings, m_functionCollector).tupleEncoder(errorArgumentTypes, _parameterTypes)); + templ("encode", ABIFunctions(m_evmVersion, m_eofVersion, m_revertStrings, m_functionCollector).tupleEncoder(errorArgumentTypes, _parameterTypes)); return templ.render(); } @@ -2592,7 +2592,7 @@ std::string YulUtilFunctions::copyArrayFromStorageToMemoryFunction(ArrayType con if (_from.baseType()->isValueType()) { solAssert(*_from.baseType() == *_to.baseType(), ""); - ABIFunctions abi(m_evmVersion, m_revertStrings, m_functionCollector); + ABIFunctions abi(m_evmVersion, m_eofVersion, m_revertStrings, m_functionCollector); return Whiskers(R"( function (slot) -> memPtr { memPtr := () @@ -2697,7 +2697,7 @@ std::string YulUtilFunctions::bytesOrStringConcatFunction( templ("finalizeAllocation", finalizeAllocationFunction()); templ( "encodePacked", - ABIFunctions{m_evmVersion, m_revertStrings, m_functionCollector}.tupleEncoderPacked( + ABIFunctions{m_evmVersion, m_eofVersion, m_revertStrings, m_functionCollector}.tupleEncoderPacked( _argumentTypes, targetTypes ) @@ -3578,7 +3578,7 @@ std::string YulUtilFunctions::conversionFunction(Type const& _from, Type const& )") ( "abiDecode", - ABIFunctions(m_evmVersion, m_revertStrings, m_functionCollector).abiDecodingFunctionStruct( + ABIFunctions(m_evmVersion, m_eofVersion, m_revertStrings, m_functionCollector).abiDecodingFunctionStruct( toStructType, false ) @@ -3907,6 +3907,7 @@ std::string YulUtilFunctions::arrayConversionFunction(ArrayType const& _from, Ar _from.dataStoredIn(DataLocation::CallData) ? ABIFunctions( m_evmVersion, + m_eofVersion, m_revertStrings, m_functionCollector ).abiDecodingFunctionArrayAvailableLength(_to, false) : @@ -4105,7 +4106,10 @@ std::string YulUtilFunctions::packedHashFunction( templ("variables", suffixedVariableNameList("var_", 1, 1 + sizeOnStack)); templ("comma", sizeOnStack > 0 ? "," : ""); templ("allocateUnbounded", allocateUnboundedFunction()); - templ("packedEncode", ABIFunctions(m_evmVersion, m_revertStrings, m_functionCollector).tupleEncoderPacked(_givenTypes, _targetTypes)); + templ( + "packedEncode", + ABIFunctions(m_evmVersion, m_eofVersion, m_revertStrings, m_functionCollector).tupleEncoderPacked(_givenTypes, _targetTypes) + ); return templ.render(); }); } @@ -4726,15 +4730,21 @@ std::string YulUtilFunctions::copyConstructorArgumentsToMemoryFunction( return m_functionCollector.createFunction(functionName, [&]() { std::string returnParams = suffixedVariableNameList("ret_param_",0, CompilerUtils::sizeOnStack(_contract.constructor()->parameters())); - ABIFunctions abiFunctions(m_evmVersion, m_revertStrings, m_functionCollector); + ABIFunctions abiFunctions(m_evmVersion, m_eofVersion, m_revertStrings, m_functionCollector); return util::Whiskers(R"( function () -> { - let programSize := datasize("") - let argSize := sub(codesize(), programSize) - - let memoryDataOffset := (argSize) - codecopy(memoryDataOffset, programSize, argSize) + + let argSize := calldatasize() + let memoryDataOffset := (argSize) + calldatacopy(memoryDataOffset, 0, argSize) + + let programSize := datasize("") + let argSize := sub(codesize(), programSize) + + let memoryDataOffset := (argSize) + codecopy(memoryDataOffset, programSize, argSize) + := (memoryDataOffset, add(memoryDataOffset, argSize)) } @@ -4744,6 +4754,7 @@ std::string YulUtilFunctions::copyConstructorArgumentsToMemoryFunction( ("object", _creationObjectName) ("allocate", allocationFunction()) ("abiDecode", abiFunctions.tupleDecoder(FunctionType(*_contract.constructor()).parameterTypes(), true)) + ("eof", m_eofVersion.has_value()) .render(); }); } diff --git a/libsolidity/codegen/YulUtilFunctions.h b/libsolidity/codegen/YulUtilFunctions.h index 6c06cdcc94e6..5ea99d603083 100644 --- a/libsolidity/codegen/YulUtilFunctions.h +++ b/libsolidity/codegen/YulUtilFunctions.h @@ -52,10 +52,12 @@ class YulUtilFunctions public: explicit YulUtilFunctions( langutil::EVMVersion _evmVersion, + std::optional _eofVersion, RevertStrings _revertStrings, MultiUseYulFunctionCollector& _functionCollector ): m_evmVersion(_evmVersion), + m_eofVersion(_eofVersion), m_revertStrings(_revertStrings), m_functionCollector(_functionCollector) {} @@ -640,6 +642,7 @@ class YulUtilFunctions std::string longByteArrayStorageIndexAccessNoCheckFunction(); langutil::EVMVersion m_evmVersion; + std::optional m_eofVersion; RevertStrings m_revertStrings; MultiUseYulFunctionCollector& m_functionCollector; }; diff --git a/libsolidity/codegen/ir/IRGenerationContext.cpp b/libsolidity/codegen/ir/IRGenerationContext.cpp index 89ce999492fc..f33461b632a7 100644 --- a/libsolidity/codegen/ir/IRGenerationContext.cpp +++ b/libsolidity/codegen/ir/IRGenerationContext.cpp @@ -224,10 +224,10 @@ void IRGenerationContext::internalFunctionCalledThroughDispatch(YulArity const& YulUtilFunctions IRGenerationContext::utils() { - return YulUtilFunctions(m_evmVersion, m_revertStrings, m_functions); + return YulUtilFunctions(m_evmVersion, m_eofVersion, m_revertStrings, m_functions); } ABIFunctions IRGenerationContext::abiFunctions() { - return ABIFunctions(m_evmVersion, m_revertStrings, m_functions); + return ABIFunctions(m_evmVersion, m_eofVersion, m_revertStrings, m_functions); } diff --git a/libsolidity/codegen/ir/IRGenerator.cpp b/libsolidity/codegen/ir/IRGenerator.cpp index e8bb7a87436f..ae2a12c71c32 100644 --- a/libsolidity/codegen/ir/IRGenerator.cpp +++ b/libsolidity/codegen/ir/IRGenerator.cpp @@ -177,7 +177,10 @@ std::string IRGenerator::generate( constructorParams.emplace_back(m_context.newYulVariable()); t( "copyConstructorArguments", - m_utils.copyConstructorArgumentsToMemoryFunction(_contract, IRNames::creationObject(_contract)) + m_utils.copyConstructorArgumentsToMemoryFunction( + _contract, + IRNames::creationObject(_contract) + ) ); } t("constructorParams", joinHumanReadable(constructorParams)); @@ -768,7 +771,7 @@ std::string IRGenerator::generateExternalFunction(ContractDefinition const& _con unsigned paramVars = std::make_shared(_functionType.parameterTypes())->sizeOnStack(); unsigned retVars = std::make_shared(_functionType.returnParameterTypes())->sizeOnStack(); - ABIFunctions abiFunctions(m_evmVersion, m_context.revertStrings(), m_context.functionCollector()); + ABIFunctions abiFunctions(m_evmVersion, m_eofVersion, m_context.revertStrings(), m_context.functionCollector()); t("abiDecode", abiFunctions.tupleDecoder(_functionType.parameterTypes())); t("params", suffixedVariableNameList("param_", 0, paramVars)); t("retParams", suffixedVariableNameList("ret_", 0, retVars)); diff --git a/libsolidity/codegen/ir/IRGenerator.h b/libsolidity/codegen/ir/IRGenerator.h index ed29a8bb3971..60d5d25cd026 100644 --- a/libsolidity/codegen/ir/IRGenerator.h +++ b/libsolidity/codegen/ir/IRGenerator.h @@ -66,7 +66,7 @@ class IRGenerator _debugInfoSelection, _soliditySourceProvider ), - m_utils(_evmVersion, m_context.revertStrings(), m_context.functionCollector()), + m_utils(_evmVersion, _eofVersion, m_context.revertStrings(), m_context.functionCollector()), m_optimiserSettings(_optimiserSettings) {} diff --git a/libsolidity/codegen/ir/IRGeneratorForStatements.cpp b/libsolidity/codegen/ir/IRGeneratorForStatements.cpp index babe43357fbb..3ae151593d33 100644 --- a/libsolidity/codegen/ir/IRGeneratorForStatements.cpp +++ b/libsolidity/codegen/ir/IRGeneratorForStatements.cpp @@ -1072,7 +1072,7 @@ void IRGeneratorForStatements::endVisit(FunctionCall const& _functionCall) { auto const& event = dynamic_cast(functionType->declaration()); TypePointers paramTypes = functionType->parameterTypes(); - ABIFunctions abi(m_context.evmVersion(), m_context.revertStrings(), m_context.functionCollector()); + ABIFunctions abi(m_context.evmVersion(), m_context.eofVersion(), m_context.revertStrings(), m_context.functionCollector()); std::vector indexedArgs; std::vector nonIndexedArgs; @@ -2843,7 +2843,7 @@ void IRGeneratorForStatements::appendBareCall( else { templ("needsEncoding", true); - ABIFunctions abi(m_context.evmVersion(), m_context.revertStrings(), m_context.functionCollector()); + ABIFunctions abi(m_context.evmVersion(), m_context.eofVersion(), m_context.revertStrings(), m_context.functionCollector()); templ("encode", abi.tupleEncoderPacked({&argType}, {TypeProvider::bytesMemory()})); } diff --git a/libsolidity/interface/CompilerStack.cpp b/libsolidity/interface/CompilerStack.cpp index 9d76ced02330..2a859ea24517 100644 --- a/libsolidity/interface/CompilerStack.cpp +++ b/libsolidity/interface/CompilerStack.cpp @@ -1502,7 +1502,12 @@ void CompilerStack::compileContract( Contract& compiledContract = m_contracts.at(_contract.fullyQualifiedName()); - std::shared_ptr compiler = std::make_shared(m_evmVersion, m_revertStrings, m_optimiserSettings); + std::shared_ptr compiler = std::make_shared( + m_evmVersion, + m_eofVersion, + m_revertStrings, + m_optimiserSettings + ); solAssert(!m_viaIR, ""); bytes cborEncodedMetadata = createCBORMetadata(compiledContract, /* _forIR */ false); 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 5ff4e7a190fc..16220fd619b0 100644 --- a/test/cmdlineTests/standard_debug_info_in_yul_location/output.json +++ b/test/cmdlineTests/standard_debug_info_in_yul_location/output.json @@ -84,6 +84,7 @@ object \"C_54\" { } function copy_arguments_for_constructor_20_object_C_54() -> ret_param_0 { + let programSize := datasize(\"C_54\") let argSize := sub(codesize(), programSize) @@ -850,6 +851,7 @@ object \"D_72\" { } function copy_arguments_for_constructor_71_object_D_72() -> ret_param_0 { + let programSize := datasize(\"D_72\") let argSize := sub(codesize(), programSize) diff --git a/test/libsolidity/Assembly.cpp b/test/libsolidity/Assembly.cpp index 0999e30ed30b..bf9c6b16afb9 100644 --- a/test/libsolidity/Assembly.cpp +++ b/test/libsolidity/Assembly.cpp @@ -94,6 +94,7 @@ evmasm::AssemblyItems compileContract(std::shared_ptr _sourceCode) { Compiler compiler( solidity::test::CommonOptions::get().evmVersion(), + solidity::test::CommonOptions::get().eofVersion(), RevertStrings::Default, solidity::test::CommonOptions::get().optimize ? OptimiserSettings::standard() : OptimiserSettings::minimal() ); diff --git a/test/libsolidity/SolidityExpressionCompiler.cpp b/test/libsolidity/SolidityExpressionCompiler.cpp index 3df712a43a76..b6d40eed029a 100644 --- a/test/libsolidity/SolidityExpressionCompiler.cpp +++ b/test/libsolidity/SolidityExpressionCompiler.cpp @@ -147,6 +147,7 @@ bytes compileFirstExpression( CompilerContext context( solidity::test::CommonOptions::get().evmVersion(), + solidity::test::CommonOptions::get().eofVersion(), RevertStrings::Default ); context.resetVisitedNodes(contract); diff --git a/test/libsolidity/semanticTests/constructor/base_constructor_arguments.sol b/test/libsolidity/semanticTests/constructor/base_constructor_arguments.sol index 55daf6d3d547..ee1ed30195e5 100644 --- a/test/libsolidity/semanticTests/constructor/base_constructor_arguments.sol +++ b/test/libsolidity/semanticTests/constructor/base_constructor_arguments.sol @@ -19,5 +19,7 @@ contract Derived is Base { return m_a; } } +// ==== +// bytecodeFormat: legacy,>=EOFv1 // ---- // getA() -> 49 From b1d31432cc57a0d1ee67ccd8b525690c0967cb8e Mon Sep 17 00:00:00 2001 From: rodiazet Date: Fri, 13 Dec 2024 12:15:53 +0100 Subject: [PATCH 0657/1022] eof: Enable semantic tests. --- .../semanticTests/constructor/arrays_in_constructors.sol | 2 ++ .../semanticTests/constructor/bytes_in_constructors_packer.sol | 2 ++ .../constructor/bytes_in_constructors_unpacker.sol | 2 ++ .../constructor/constructor_arguments_external.sol | 2 ++ .../constructor/constructor_arguments_internal.sol | 2 ++ .../semanticTests/constructor/constructor_function_argument.sol | 2 ++ .../semanticTests/constructor/constructor_function_complex.sol | 2 ++ .../constructor/constructor_static_array_argument.sol | 2 ++ .../constructor/evm_exceptions_in_constructor_call_fail.sol | 2 ++ .../constructor/function_usage_in_constructor_arguments.sol | 2 ++ .../constructor/functions_called_by_constructor.sol | 2 ++ .../functions_called_by_constructor_through_dispatch.sol | 2 ++ .../inline_member_init_inheritence_without_constructor.sol | 2 ++ .../semanticTests/constructor/order_of_evaluation.sol | 2 ++ .../semanticTests/constructor/payable_constructor.sol | 2 ++ .../semanticTests/constructor/store_function_in_constructor.sol | 2 ++ .../constructor/store_function_in_constructor_packed.sol | 2 ++ .../store_internal_unused_function_in_constructor.sol | 2 ++ .../store_internal_unused_library_function_in_constructor.sol | 2 ++ .../constructor/transient_state_variable_initialization.sol | 1 + 20 files changed, 39 insertions(+) diff --git a/test/libsolidity/semanticTests/constructor/arrays_in_constructors.sol b/test/libsolidity/semanticTests/constructor/arrays_in_constructors.sol index 8fe8d36f9bb8..aeeb1a0c1aa4 100644 --- a/test/libsolidity/semanticTests/constructor/arrays_in_constructors.sol +++ b/test/libsolidity/semanticTests/constructor/arrays_in_constructors.sol @@ -22,6 +22,8 @@ contract Creator { ch = c.part(x); } } +// ==== +// bytecodeFormat: legacy,>=EOFv1 // ---- // f(uint256,address[]): 7, 0x40, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 -> 7, 8 // gas irOptimized: 327784 diff --git a/test/libsolidity/semanticTests/constructor/bytes_in_constructors_packer.sol b/test/libsolidity/semanticTests/constructor/bytes_in_constructors_packer.sol index 69896ebf1584..55abe4804c56 100644 --- a/test/libsolidity/semanticTests/constructor/bytes_in_constructors_packer.sol +++ b/test/libsolidity/semanticTests/constructor/bytes_in_constructors_packer.sol @@ -22,6 +22,8 @@ contract Creator { ch = c.part(x); } } +// ==== +// bytecodeFormat: legacy,>=EOFv1 // ---- // f(uint256,bytes): 7, 0x40, 78, "abcdefghijklmnopqrstuvwxyzabcdef", "ghijklmnopqrstuvwxyzabcdefghijkl", "mnopqrstuvwxyz" -> 7, "h" // gas irOptimized: 169292 diff --git a/test/libsolidity/semanticTests/constructor/bytes_in_constructors_unpacker.sol b/test/libsolidity/semanticTests/constructor/bytes_in_constructors_unpacker.sol index 036d6ca629a3..13db633b9b06 100644 --- a/test/libsolidity/semanticTests/constructor/bytes_in_constructors_unpacker.sol +++ b/test/libsolidity/semanticTests/constructor/bytes_in_constructors_unpacker.sol @@ -6,6 +6,8 @@ contract Test { m_s = s; } } +// ==== +// bytecodeFormat: legacy,>=EOFv1 // ---- // constructor(): 7, 0x40, 78, "abcdefghijklmnopqrstuvwxyzabcdef", "ghijklmnopqrstuvwxyzabcdefghijkl", "mnopqrstuvwxyz" -> // gas irOptimized: 181465 diff --git a/test/libsolidity/semanticTests/constructor/constructor_arguments_external.sol b/test/libsolidity/semanticTests/constructor/constructor_arguments_external.sol index 7d068338b091..e59cb4214a23 100644 --- a/test/libsolidity/semanticTests/constructor/constructor_arguments_external.sol +++ b/test/libsolidity/semanticTests/constructor/constructor_arguments_external.sol @@ -15,6 +15,8 @@ contract Main { return flag; } } +// ==== +// bytecodeFormat: legacy,>=EOFv1 // ---- // constructor(): "abc", true // gas irOptimized: 80174 diff --git a/test/libsolidity/semanticTests/constructor/constructor_arguments_internal.sol b/test/libsolidity/semanticTests/constructor/constructor_arguments_internal.sol index bf3f0c0c9b74..a811d12c89f6 100644 --- a/test/libsolidity/semanticTests/constructor/constructor_arguments_internal.sol +++ b/test/libsolidity/semanticTests/constructor/constructor_arguments_internal.sol @@ -32,6 +32,8 @@ contract Main { return h.getName(); } } +// ==== +// bytecodeFormat: legacy,>=EOFv1 // ---- // getFlag() -> true // getName() -> "abc" diff --git a/test/libsolidity/semanticTests/constructor/constructor_function_argument.sol b/test/libsolidity/semanticTests/constructor/constructor_function_argument.sol index 159f2943d432..76e5193d9720 100644 --- a/test/libsolidity/semanticTests/constructor/constructor_function_argument.sol +++ b/test/libsolidity/semanticTests/constructor/constructor_function_argument.sol @@ -3,5 +3,7 @@ contract D { constructor(function() external returns (uint)) { } } +// ==== +// bytecodeFormat: legacy,>=EOFv1 // ---- // constructor(): 0xfdd67305928fcac8d213d1e47bfa6165cd0b87b946644cd0000000000000000 -> diff --git a/test/libsolidity/semanticTests/constructor/constructor_function_complex.sol b/test/libsolidity/semanticTests/constructor/constructor_function_complex.sol index 13abe72c5cce..10a4ee06dbb5 100644 --- a/test/libsolidity/semanticTests/constructor/constructor_function_complex.sol +++ b/test/libsolidity/semanticTests/constructor/constructor_function_complex.sol @@ -15,6 +15,8 @@ contract C { return 16; } } +// ==== +// bytecodeFormat: legacy,>=EOFv1 // ---- // f() -> 16 // gas legacy: 78477 diff --git a/test/libsolidity/semanticTests/constructor/constructor_static_array_argument.sol b/test/libsolidity/semanticTests/constructor/constructor_static_array_argument.sol index 5947b257363f..ed4eb6e4d15f 100644 --- a/test/libsolidity/semanticTests/constructor/constructor_static_array_argument.sol +++ b/test/libsolidity/semanticTests/constructor/constructor_static_array_argument.sol @@ -7,6 +7,8 @@ contract C { b = _b; } } +// ==== +// bytecodeFormat: legacy,>=EOFv1 // ---- // constructor(): 1, 2, 3, 4 -> // gas irOptimized: 148129 diff --git a/test/libsolidity/semanticTests/constructor/evm_exceptions_in_constructor_call_fail.sol b/test/libsolidity/semanticTests/constructor/evm_exceptions_in_constructor_call_fail.sol index 43d1fdab848f..d45c65524902 100644 --- a/test/libsolidity/semanticTests/constructor/evm_exceptions_in_constructor_call_fail.sol +++ b/test/libsolidity/semanticTests/constructor/evm_exceptions_in_constructor_call_fail.sol @@ -13,6 +13,8 @@ contract B { ++test; } } +// ==== +// bytecodeFormat: legacy,>=EOFv1 // ---- // testIt() -> // test() -> 2 diff --git a/test/libsolidity/semanticTests/constructor/function_usage_in_constructor_arguments.sol b/test/libsolidity/semanticTests/constructor/function_usage_in_constructor_arguments.sol index c04f039188c4..a736cab912fa 100644 --- a/test/libsolidity/semanticTests/constructor/function_usage_in_constructor_arguments.sol +++ b/test/libsolidity/semanticTests/constructor/function_usage_in_constructor_arguments.sol @@ -19,5 +19,7 @@ contract Derived is Base { return m_a; } } +// ==== +// bytecodeFormat: legacy,>=EOFv1 // ---- // getA() -> 2 diff --git a/test/libsolidity/semanticTests/constructor/functions_called_by_constructor.sol b/test/libsolidity/semanticTests/constructor/functions_called_by_constructor.sol index b968a07a161d..d70508b7645d 100644 --- a/test/libsolidity/semanticTests/constructor/functions_called_by_constructor.sol +++ b/test/libsolidity/semanticTests/constructor/functions_called_by_constructor.sol @@ -14,5 +14,7 @@ contract Test { name = _name; } } +// ==== +// bytecodeFormat: legacy,>=EOFv1 // ---- // getName() -> "abc" diff --git a/test/libsolidity/semanticTests/constructor/functions_called_by_constructor_through_dispatch.sol b/test/libsolidity/semanticTests/constructor/functions_called_by_constructor_through_dispatch.sol index 0a1250a8ba62..ef7b5dcf8cad 100644 --- a/test/libsolidity/semanticTests/constructor/functions_called_by_constructor_through_dispatch.sol +++ b/test/libsolidity/semanticTests/constructor/functions_called_by_constructor_through_dispatch.sol @@ -24,5 +24,7 @@ contract Test { name = _shiftOperator(name, _bytes); } } +// ==== +// bytecodeFormat: legacy,>=EOFv1 // ---- // getName() -> "def\x00\x00\x00" diff --git a/test/libsolidity/semanticTests/constructor/inline_member_init_inheritence_without_constructor.sol b/test/libsolidity/semanticTests/constructor/inline_member_init_inheritence_without_constructor.sol index 320349cda9ed..13c80b7b6273 100644 --- a/test/libsolidity/semanticTests/constructor/inline_member_init_inheritence_without_constructor.sol +++ b/test/libsolidity/semanticTests/constructor/inline_member_init_inheritence_without_constructor.sol @@ -14,6 +14,8 @@ contract Derived is Base { return m_derived; } } +// ==== +// bytecodeFormat: legacy,>=EOFv1 // ---- // getBMember() -> 5 // getDMember() -> 6 diff --git a/test/libsolidity/semanticTests/constructor/order_of_evaluation.sol b/test/libsolidity/semanticTests/constructor/order_of_evaluation.sol index 2416f124ec37..14bb7cf07c6c 100644 --- a/test/libsolidity/semanticTests/constructor/order_of_evaluation.sol +++ b/test/libsolidity/semanticTests/constructor/order_of_evaluation.sol @@ -18,5 +18,7 @@ contract X is D, C, B, A { function g() public view returns (uint[] memory) { return x; } constructor() A(f(1)) C(f(2)) B(f(3)) D(f(4)) {} } +// ==== +// bytecodeFormat: legacy,>=EOFv1 // ---- // g() -> 0x20, 4, 1, 3, 2, 4 diff --git a/test/libsolidity/semanticTests/constructor/payable_constructor.sol b/test/libsolidity/semanticTests/constructor/payable_constructor.sol index 09fe0a1cc32d..1020f697dd06 100644 --- a/test/libsolidity/semanticTests/constructor/payable_constructor.sol +++ b/test/libsolidity/semanticTests/constructor/payable_constructor.sol @@ -1,5 +1,7 @@ contract C { constructor() payable {} } +// ==== +// bytecodeFormat: legacy,>=EOFv1 // ---- // constructor(), 27 wei -> diff --git a/test/libsolidity/semanticTests/constructor/store_function_in_constructor.sol b/test/libsolidity/semanticTests/constructor/store_function_in_constructor.sol index dee3af35415f..7bc2982b78f1 100644 --- a/test/libsolidity/semanticTests/constructor/store_function_in_constructor.sol +++ b/test/libsolidity/semanticTests/constructor/store_function_in_constructor.sol @@ -15,6 +15,8 @@ contract C { return x(_arg); } } +// ==== +// bytecodeFormat: legacy,>=EOFv1 // ---- // use(uint256): 3 -> 6 // result_in_constructor() -> 4 diff --git a/test/libsolidity/semanticTests/constructor/store_function_in_constructor_packed.sol b/test/libsolidity/semanticTests/constructor/store_function_in_constructor_packed.sol index 07b12ad96cb7..b0a20f14310d 100644 --- a/test/libsolidity/semanticTests/constructor/store_function_in_constructor_packed.sol +++ b/test/libsolidity/semanticTests/constructor/store_function_in_constructor_packed.sol @@ -16,6 +16,8 @@ contract C { return x(_arg); } } +// ==== +// bytecodeFormat: legacy,>=EOFv1 // ---- // use(uint16): 3 -> 0xfff9 // result_in_constructor() -> 0xfffb diff --git a/test/libsolidity/semanticTests/constructor/store_internal_unused_function_in_constructor.sol b/test/libsolidity/semanticTests/constructor/store_internal_unused_function_in_constructor.sol index cc9d8ca6a134..905e1d3492d0 100644 --- a/test/libsolidity/semanticTests/constructor/store_internal_unused_function_in_constructor.sol +++ b/test/libsolidity/semanticTests/constructor/store_internal_unused_function_in_constructor.sol @@ -13,5 +13,7 @@ contract C { return x(); } } +// ==== +// bytecodeFormat: legacy,>=EOFv1 // ---- // t() -> 7 diff --git a/test/libsolidity/semanticTests/constructor/store_internal_unused_library_function_in_constructor.sol b/test/libsolidity/semanticTests/constructor/store_internal_unused_library_function_in_constructor.sol index 5845e9b56e15..b7d9bb5f454b 100644 --- a/test/libsolidity/semanticTests/constructor/store_internal_unused_library_function_in_constructor.sol +++ b/test/libsolidity/semanticTests/constructor/store_internal_unused_library_function_in_constructor.sol @@ -16,5 +16,7 @@ contract C { return x(); } } +// ==== +// bytecodeFormat: legacy,>=EOFv1 // ---- // t() -> 7 diff --git a/test/libsolidity/semanticTests/constructor/transient_state_variable_initialization.sol b/test/libsolidity/semanticTests/constructor/transient_state_variable_initialization.sol index 3260fa30ff23..46a9090c24d8 100644 --- a/test/libsolidity/semanticTests/constructor/transient_state_variable_initialization.sol +++ b/test/libsolidity/semanticTests/constructor/transient_state_variable_initialization.sol @@ -14,5 +14,6 @@ contract C { // ==== // EVMVersion: >=cancun +// bytecodeFormat: legacy,>=EOFv1 // ---- // f() -> 100 From be16078d747b14b67616e4a64fe2df54949b97f7 Mon Sep 17 00:00:00 2001 From: rodiazet Date: Wed, 18 Dec 2024 16:15:29 +0100 Subject: [PATCH 0658/1022] eof: Make `GasTest` inherits from `EVMVersionRestricted` --- test/libsolidity/GasTest.cpp | 6 +----- test/libsolidity/GasTest.h | 2 +- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/test/libsolidity/GasTest.cpp b/test/libsolidity/GasTest.cpp index 14722535e446..39b0e6681abe 100644 --- a/test/libsolidity/GasTest.cpp +++ b/test/libsolidity/GasTest.cpp @@ -37,7 +37,7 @@ using namespace solidity; using namespace boost::unit_test; GasTest::GasTest(std::string const& _filename): - TestCase(_filename) + EVMVersionRestrictedTestCase(_filename) { m_source = m_reader.source(); m_optimise = m_reader.boolSetting("optimize", false); @@ -114,10 +114,6 @@ void GasTest::setupCompiler(CompilerStack& _compiler) } settings.expectedExecutionsPerDeployment = m_optimiseRuns; _compiler.setOptimiserSettings(settings); - - // Intentionally ignoring EVM version specified on the command line. - // Gas expectations are only valid for the default version. - _compiler.setEVMVersion(EVMVersion{}); } TestCase::TestResult GasTest::run(std::ostream& _stream, std::string const& _linePrefix, bool _formatted) diff --git a/test/libsolidity/GasTest.h b/test/libsolidity/GasTest.h index 1337ae3f6f07..998411abf863 100644 --- a/test/libsolidity/GasTest.h +++ b/test/libsolidity/GasTest.h @@ -32,7 +32,7 @@ namespace solidity::frontend::test { -class GasTest: AnalysisFramework, public TestCase +class GasTest: AnalysisFramework, public EVMVersionRestrictedTestCase { public: static std::unique_ptr create(Config const& _config) From da7e1bc2f7125d1c9b03e3ff5894374aeac22a9e Mon Sep 17 00:00:00 2001 From: rodiazet Date: Wed, 18 Dec 2024 16:50:16 +0100 Subject: [PATCH 0659/1022] eof: Enable disabled earlier `gasTests` in `soltest.sh` --- .circleci/soltest.sh | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/.circleci/soltest.sh b/.circleci/soltest.sh index 940ff1122aa9..71c2a952adac 100755 --- a/.circleci/soltest.sh +++ b/.circleci/soltest.sh @@ -56,18 +56,6 @@ EOF_EXCLUDES=( --run_test='!SolidityInlineAssembly/Analysis/large_constant' --run_test='!SolidityInlineAssembly/Analysis/staticcall' --run_test='!ViewPureChecker/assembly_staticcall' - --run_test='!gasTests/abiv2' - --run_test='!gasTests/abiv2_optimised' - --run_test='!gasTests/data_storage' - --run_test='!gasTests/dispatch_large' - --run_test='!gasTests/dispatch_large_optimised' - --run_test='!gasTests/dispatch_medium' - --run_test='!gasTests/dispatch_medium_optimised' - --run_test='!gasTests/dispatch_small' - --run_test='!gasTests/dispatch_small_optimised' - --run_test='!gasTests/exp' - --run_test='!gasTests/exp_optimized' - --run_test='!gasTests/storage_costs' --run_test='!yulStackLayout/literal_loop' ) From 586d31473d8d4fdbf41392f345a5ffd80ffff738 Mon Sep 17 00:00:00 2001 From: rodiazet Date: Wed, 18 Dec 2024 21:32:16 +0100 Subject: [PATCH 0660/1022] eof: Update `gasTests` tests --- test/libsolidity/gasTests/abiv2.sol | 3 +++ test/libsolidity/gasTests/abiv2_optimised.sol | 2 ++ test/libsolidity/gasTests/data_storage.sol | 3 +++ test/libsolidity/gasTests/dispatch_large.sol | 3 +++ test/libsolidity/gasTests/dispatch_large_optimised.sol | 2 ++ test/libsolidity/gasTests/dispatch_medium.sol | 3 +++ test/libsolidity/gasTests/dispatch_medium_optimised.sol | 3 +++ test/libsolidity/gasTests/dispatch_small.sol | 3 +++ test/libsolidity/gasTests/dispatch_small_optimised.sol | 2 ++ test/libsolidity/gasTests/exp.sol | 2 ++ test/libsolidity/gasTests/exp_optimized.sol | 2 ++ test/libsolidity/gasTests/storage_costs.sol | 2 ++ 12 files changed, 30 insertions(+) diff --git a/test/libsolidity/gasTests/abiv2.sol b/test/libsolidity/gasTests/abiv2.sol index 6fa822fade47..95c30ac645db 100644 --- a/test/libsolidity/gasTests/abiv2.sol +++ b/test/libsolidity/gasTests/abiv2.sol @@ -12,6 +12,9 @@ contract C { function f7(uint[31] memory, string[20] memory, C, address) public returns (bytes[] memory, uint16[] memory) {} function f8(uint[32] memory, string[] memory, uint32, address) public returns (uint[] memory, uint16[] memory) {} } +// ==== +// EVMVersion: =current +// bytecodeFormat: legacy // ---- // creation: // codeDepositCost: 1208000 diff --git a/test/libsolidity/gasTests/abiv2_optimised.sol b/test/libsolidity/gasTests/abiv2_optimised.sol index 2989c1acd8f9..e23a7bff2562 100644 --- a/test/libsolidity/gasTests/abiv2_optimised.sol +++ b/test/libsolidity/gasTests/abiv2_optimised.sol @@ -13,6 +13,8 @@ contract C { function f8(uint[32] memory, string[] memory, uint32, address) public returns (uint[] memory, uint16[] memory) {} } // ==== +// EVMVersion: =current +// bytecodeFormat: legacy // optimize: true // optimize-yul: true // ---- diff --git a/test/libsolidity/gasTests/data_storage.sol b/test/libsolidity/gasTests/data_storage.sol index 0d24ef505273..d9cacf5caf44 100644 --- a/test/libsolidity/gasTests/data_storage.sol +++ b/test/libsolidity/gasTests/data_storage.sol @@ -11,6 +11,9 @@ contract C { require(false, "12345678901234567890123456789012123456789012345678901234567890123"); } } +// ==== +// EVMVersion: =current +// bytecodeFormat: legacy // ---- // creation: // codeDepositCost: 377800 diff --git a/test/libsolidity/gasTests/dispatch_large.sol b/test/libsolidity/gasTests/dispatch_large.sol index e1cce4acd764..2b7822f5f855 100644 --- a/test/libsolidity/gasTests/dispatch_large.sol +++ b/test/libsolidity/gasTests/dispatch_large.sol @@ -22,6 +22,9 @@ contract Large { function g9(uint x) public payable returns (uint) { b[uint8(msg.data[8])] = x; } function g0(uint x) public payable returns (uint) { require(x > 10); } } +// ==== +// EVMVersion: =current +// bytecodeFormat: legacy // ---- // creation: // codeDepositCost: 618400 diff --git a/test/libsolidity/gasTests/dispatch_large_optimised.sol b/test/libsolidity/gasTests/dispatch_large_optimised.sol index 83e55c1a9c1e..5ab62e892285 100644 --- a/test/libsolidity/gasTests/dispatch_large_optimised.sol +++ b/test/libsolidity/gasTests/dispatch_large_optimised.sol @@ -23,6 +23,8 @@ contract Large { function g0(uint x) public payable returns (uint) { require(x > 10); } } // ==== +// EVMVersion: =current +// bytecodeFormat: legacy // optimize: true // optimize-runs: 2 // ---- diff --git a/test/libsolidity/gasTests/dispatch_medium.sol b/test/libsolidity/gasTests/dispatch_medium.sol index 6bf8f89394fa..aedbec0b081f 100644 --- a/test/libsolidity/gasTests/dispatch_medium.sol +++ b/test/libsolidity/gasTests/dispatch_medium.sol @@ -9,6 +9,9 @@ contract Medium { function g9(uint x) public payable returns (uint) { b[uint8(msg.data[8])] = x; } function g0(uint x) public payable returns (uint) { require(x > 10); } } +// ==== +// EVMVersion: =current +// bytecodeFormat: legacy // ---- // creation: // codeDepositCost: 259600 diff --git a/test/libsolidity/gasTests/dispatch_medium_optimised.sol b/test/libsolidity/gasTests/dispatch_medium_optimised.sol index e921fcf125ba..2ea33955e9c8 100644 --- a/test/libsolidity/gasTests/dispatch_medium_optimised.sol +++ b/test/libsolidity/gasTests/dispatch_medium_optimised.sol @@ -10,6 +10,9 @@ contract Medium { function g0(uint x) public payable returns (uint) { require(x > 10); } } // ==== +// EVMVersion: =current +// bytecodeFormat: legacy +// ==== // optimize: true // optimize-runs: 2 // ---- diff --git a/test/libsolidity/gasTests/dispatch_small.sol b/test/libsolidity/gasTests/dispatch_small.sol index d2c391582ed5..d198fd9927f1 100644 --- a/test/libsolidity/gasTests/dispatch_small.sol +++ b/test/libsolidity/gasTests/dispatch_small.sol @@ -4,6 +4,9 @@ contract Small { function f1(uint x) public returns (uint) { a = x; b[uint8(msg.data[0])] = x; } fallback () external payable {} } +// ==== +// EVMVersion: =current +// bytecodeFormat: legacy // ---- // creation: // codeDepositCost: 103800 diff --git a/test/libsolidity/gasTests/dispatch_small_optimised.sol b/test/libsolidity/gasTests/dispatch_small_optimised.sol index e20e1d982427..b59bdafc2780 100644 --- a/test/libsolidity/gasTests/dispatch_small_optimised.sol +++ b/test/libsolidity/gasTests/dispatch_small_optimised.sol @@ -5,8 +5,10 @@ contract Small { fallback () external payable {} } // ==== +// EVMVersion: =current // optimize: true // optimize-runs: 2 +// bytecodeFormat: legacy // ---- // creation: // codeDepositCost: 58200 diff --git a/test/libsolidity/gasTests/exp.sol b/test/libsolidity/gasTests/exp.sol index 6ad4dd3bee43..40ef138136cd 100644 --- a/test/libsolidity/gasTests/exp.sol +++ b/test/libsolidity/gasTests/exp.sol @@ -15,6 +15,8 @@ contract C { } } // ==== +// EVMVersion: =current +// bytecodeFormat: legacy // optimize: false // optimize-yul: false // ---- diff --git a/test/libsolidity/gasTests/exp_optimized.sol b/test/libsolidity/gasTests/exp_optimized.sol index 982fcd28feb9..fae9a24fd757 100644 --- a/test/libsolidity/gasTests/exp_optimized.sol +++ b/test/libsolidity/gasTests/exp_optimized.sol @@ -15,6 +15,8 @@ contract C { } } // ==== +// EVMVersion: =current +// bytecodeFormat: legacy // optimize: true // optimize-yul: true // ---- diff --git a/test/libsolidity/gasTests/storage_costs.sol b/test/libsolidity/gasTests/storage_costs.sol index afb442ed7f97..871c15eab388 100644 --- a/test/libsolidity/gasTests/storage_costs.sol +++ b/test/libsolidity/gasTests/storage_costs.sol @@ -11,8 +11,10 @@ contract C { } } // ==== +// EVMVersion: =current // optimize: true // optimize-yul: true +// bytecodeFormat: legacy // ---- // creation: // codeDepositCost: 25600 From 969950c637752cac0dffa50f781334a5d14a343d Mon Sep 17 00:00:00 2001 From: rodiazet Date: Fri, 13 Dec 2024 14:22:23 +0100 Subject: [PATCH 0661/1022] eof: Fix assembly stack height for non-returning function --- libevmasm/Assembly.cpp | 27 ++++++++++--------- libevmasm/Assembly.h | 7 +++-- libevmasm/AssemblyItem.cpp | 2 +- libevmasm/AssemblyItem.h | 8 +++--- libyul/backends/evm/AbstractAssembly.h | 3 ++- libyul/backends/evm/EthAssemblyAdapter.cpp | 4 +-- libyul/backends/evm/EthAssemblyAdapter.h | 2 +- libyul/backends/evm/NoOutputAssembly.cpp | 12 ++++----- libyul/backends/evm/NoOutputAssembly.h | 2 +- .../evm/OptimizedEVMCodeTransform.cpp | 10 +++---- .../inline_assembly_in_modifiers.sol | 2 ++ 11 files changed, 41 insertions(+), 38 deletions(-) diff --git a/libevmasm/Assembly.cpp b/libevmasm/Assembly.cpp index 1fe4fa7d97b8..001865b2c4c0 100644 --- a/libevmasm/Assembly.cpp +++ b/libevmasm/Assembly.cpp @@ -708,10 +708,10 @@ AssemblyItem Assembly::newFunctionCall(uint16_t _functionID) const solAssert(_functionID < m_codeSections.size(), "Call to undeclared function."); solAssert(_functionID > 0, "Cannot call section 0"); auto const& section = m_codeSections.at(_functionID); - if (section.outputs != 0x80) - return AssemblyItem::functionCall(_functionID, section.inputs, section.outputs); - else + if (section.nonReturning) return AssemblyItem::jumpToFunction(_functionID, section.inputs, section.outputs); + else + return AssemblyItem::functionCall(_functionID, section.inputs, section.outputs); } AssemblyItem Assembly::newFunctionReturn() const @@ -720,14 +720,14 @@ AssemblyItem Assembly::newFunctionReturn() const return AssemblyItem::functionReturn(); } -uint16_t Assembly::createFunction(uint8_t _args, uint8_t _rets) +uint16_t Assembly::createFunction(uint8_t _args, uint8_t _rets, bool _nonReturning) { size_t functionID = m_codeSections.size(); solRequire(functionID < 1024, AssemblyException, "Too many functions for EOF"); solAssert(m_currentCodeSection == 0, "Functions need to be declared from the main block."); - solAssert(_rets <= 0x80, "Too many function returns."); - solAssert(_args <= 127, "Too many function inputs."); - m_codeSections.emplace_back(CodeSection{_args, _rets, {}}); + solRequire(_rets <= 127, AssemblyException, "Too many function returns."); + solRequire(_args <= 127, AssemblyException, "Too many function inputs."); + m_codeSections.emplace_back(CodeSection{_args, _rets, _nonReturning, {}}); return static_cast(functionID); } @@ -1103,7 +1103,8 @@ std::tuple, size_t> Assembly::createEOFHeader(std::se for (auto const& codeSection: m_codeSections) { retBytecode.push_back(codeSection.inputs); - retBytecode.push_back(codeSection.outputs); + // According to EOF spec function output num equals 0x80 means non-returning function + retBytecode.push_back(codeSection.nonReturning ? 0x80 : codeSection.outputs); appendBigEndianUint16(retBytecode, calculateMaxStackHeight(codeSection)); } @@ -1522,7 +1523,8 @@ LinkerObject const& Assembly::assembleEOF() const solRequire(!m_codeSections.empty(), AssemblyException, "Expected at least one code section."); solRequire( - m_codeSections.front().inputs == 0 && m_codeSections.front().outputs == 0x80, AssemblyException, + m_codeSections.front().inputs == 0 && m_codeSections.front().outputs == 0 && m_codeSections.front().nonReturning, + AssemblyException, "Expected the first code section to have zero inputs and be non-returning." ); @@ -1624,12 +1626,11 @@ LinkerObject const& Assembly::assembleEOF() const size_t const index = static_cast(item.data()); solAssert(index < m_codeSections.size()); solAssert(item.functionSignature().argsNum <= 127); - solAssert(item.type() == JumpF || item.functionSignature().retsNum <= 127); - solAssert(item.type() == CallF || item.functionSignature().retsNum <= 128); + solAssert(item.functionSignature().retsNum <= 127); solAssert(m_codeSections[index].inputs == item.functionSignature().argsNum); solAssert(m_codeSections[index].outputs == item.functionSignature().retsNum); - // If CallF the function can continue. - solAssert(item.type() == JumpF || item.functionSignature().canContinue()); + // If CallF the function cannot be non-returning. + solAssert(item.type() == JumpF || !m_codeSections[index].nonReturning); appendBigEndianUint16(ret.bytecode, item.data()); break; } diff --git a/libevmasm/Assembly.h b/libevmasm/Assembly.h index db567a917b10..92dfb0a44008 100644 --- a/libevmasm/Assembly.h +++ b/libevmasm/Assembly.h @@ -61,7 +61,7 @@ class Assembly m_name(std::move(_name)) { // Code section number 0 has to be non-returning. - m_codeSections.emplace_back(CodeSection{0, 0x80, {}}); + m_codeSections.emplace_back(CodeSection{0, 0, true, {}}); } std::optional eofVersion() const { return m_eofVersion; } @@ -72,7 +72,7 @@ class Assembly AssemblyItem newFunctionCall(uint16_t _functionID) const; AssemblyItem newFunctionReturn() const; - uint16_t createFunction(uint8_t _args, uint8_t _rets); + uint16_t createFunction(uint8_t _args, uint8_t _rets, bool _nonReturning); void beginFunction(uint16_t _functionID); void endFunction(); @@ -221,7 +221,10 @@ class Assembly struct CodeSection { uint8_t inputs = 0; + // Number of outputs needs to be set properly even for non-returning function. + // It matters in case of stack height calculation of the function call instruction. uint8_t outputs = 0; + bool nonReturning = false; AssemblyItems items{}; }; diff --git a/libevmasm/AssemblyItem.cpp b/libevmasm/AssemblyItem.cpp index ea670eb0a2b3..424b9eedaa39 100644 --- a/libevmasm/AssemblyItem.cpp +++ b/libevmasm/AssemblyItem.cpp @@ -249,7 +249,7 @@ size_t AssemblyItem::returnValues() const return 1; case JumpF: case CallF: - return functionSignature().canContinue() ? functionSignature().retsNum : 0; + return functionSignature().retsNum; case AssignImmutable: case UndefinedItem: break; diff --git a/libevmasm/AssemblyItem.h b/libevmasm/AssemblyItem.h index 28b2fb537545..babf2b7b7051 100644 --- a/libevmasm/AssemblyItem.h +++ b/libevmasm/AssemblyItem.h @@ -120,7 +120,7 @@ class AssemblyItem static AssemblyItem jumpToFunction(uint16_t _functionID, uint8_t _args, uint8_t _rets, langutil::DebugData::ConstPtr _debugData = langutil::DebugData::create()) { AssemblyItem result(JumpF, Instruction::JUMPF, _functionID, _debugData); - solAssert(_args <= 127 && _rets <= 128); + solAssert(_args <= 127 && _rets <= 127); result.m_functionSignature = {_args, _rets}; return result; } @@ -292,12 +292,10 @@ class AssemblyItem struct FunctionSignature { - /// Number of EOF function arguments. must be less than 127 + /// Number of EOF function arguments. must be less than 128 uint8_t argsNum; - /// Number of EOF function return values. Must be less than 128. 128(0x80) means that it's non-returning. + /// Number of EOF function return values. Must be less than 128. uint8_t retsNum; - - bool canContinue() const { return retsNum != 0x80;} }; FunctionSignature const& functionSignature() const diff --git a/libyul/backends/evm/AbstractAssembly.h b/libyul/backends/evm/AbstractAssembly.h index 6fe234782e10..7a3e6b7422be 100644 --- a/libyul/backends/evm/AbstractAssembly.h +++ b/libyul/backends/evm/AbstractAssembly.h @@ -105,7 +105,8 @@ class AbstractAssembly /// Registers a new function with given signature and returns its ID. /// The function is initially empty and its body must be filled with instructions. - virtual FunctionID registerFunction(uint8_t _args, uint8_t _rets) = 0; + /// `_rets` even for non-returning function matters in case of stack height calculation. + virtual FunctionID registerFunction(uint8_t _args, uint8_t _rets, bool _nonReturning) = 0; /// Selects a function as a target for newly appended instructions. /// May only be called after the main code section is already filled and /// must not be called when another function is already selected. diff --git a/libyul/backends/evm/EthAssemblyAdapter.cpp b/libyul/backends/evm/EthAssemblyAdapter.cpp index d9cf47f4dabe..b608859e2ba8 100644 --- a/libyul/backends/evm/EthAssemblyAdapter.cpp +++ b/libyul/backends/evm/EthAssemblyAdapter.cpp @@ -145,9 +145,9 @@ std::pair, AbstractAssembly::SubID> EthAssembl return {std::make_shared(*assembly), static_cast(sub.data())}; } -AbstractAssembly::FunctionID EthAssemblyAdapter::registerFunction(uint8_t _args, uint8_t _rets) +AbstractAssembly::FunctionID EthAssemblyAdapter::registerFunction(uint8_t _args, uint8_t _rets, bool _nonReturning) { - return m_assembly.createFunction(_args, _rets); + return m_assembly.createFunction(_args, _rets, _nonReturning); } void EthAssemblyAdapter::beginFunction(AbstractAssembly::FunctionID _functionID) diff --git a/libyul/backends/evm/EthAssemblyAdapter.h b/libyul/backends/evm/EthAssemblyAdapter.h index 29a6fba7bef1..93e7c816abf4 100644 --- a/libyul/backends/evm/EthAssemblyAdapter.h +++ b/libyul/backends/evm/EthAssemblyAdapter.h @@ -56,7 +56,7 @@ class EthAssemblyAdapter: public AbstractAssembly void appendJumpToIf(LabelID _labelId, JumpType _jumpType) override; void appendAssemblySize() override; std::pair, SubID> createSubAssembly(bool _creation, std::string _name = {}) override; - AbstractAssembly::FunctionID registerFunction(uint8_t _args, uint8_t _rets) override; + AbstractAssembly::FunctionID registerFunction(uint8_t _args, uint8_t _rets, bool _nonReturning) override; void beginFunction(AbstractAssembly::FunctionID _functionID) override; void endFunction() override; void appendFunctionCall(FunctionID _functionID) override; diff --git a/libyul/backends/evm/NoOutputAssembly.cpp b/libyul/backends/evm/NoOutputAssembly.cpp index c9d6c6292fb5..840372fcaf83 100644 --- a/libyul/backends/evm/NoOutputAssembly.cpp +++ b/libyul/backends/evm/NoOutputAssembly.cpp @@ -120,11 +120,11 @@ std::pair, AbstractAssembly::SubID> NoOutputAs return {}; } -AbstractAssembly::FunctionID NoOutputAssembly::registerFunction(uint8_t _args, uint8_t _rets) +AbstractAssembly::FunctionID NoOutputAssembly::registerFunction(uint8_t _args, uint8_t _rets, bool) { yulAssert(m_context.numFunctions <= std::numeric_limits::max()); AbstractAssembly::FunctionID id = static_cast(m_context.numFunctions++); - m_context.functionSignatures[id] = std::make_pair(_args, _rets); + m_context.functionSignatures[id] = {_args, _rets}; return id; } @@ -139,8 +139,8 @@ void NoOutputAssembly::beginFunction(FunctionID _functionID) void NoOutputAssembly::endFunction() { yulAssert(m_currentFunctionID != 0, "End function without begin function."); - auto const rets = m_context.functionSignatures.at(m_currentFunctionID).second; - yulAssert(rets == 0x80 || m_stackHeight == rets, "Stack height mismatch at function end."); + auto const [_, rets] = m_context.functionSignatures.at(m_currentFunctionID); + yulAssert(m_stackHeight == rets, "Stack height mismatch at function end."); m_currentFunctionID = 0; } @@ -153,8 +153,8 @@ void NoOutputAssembly::appendFunctionCall(FunctionID _functionID) void NoOutputAssembly::appendFunctionReturn() { yulAssert(m_currentFunctionID != 0, "End function without begin function."); - auto const rets = m_context.functionSignatures.at(m_currentFunctionID).second; - yulAssert(rets == 0x80 || m_stackHeight == rets, "Stack height mismatch at function end."); + auto const [_, rets] = m_context.functionSignatures.at(m_currentFunctionID); + yulAssert(m_stackHeight == rets, "Stack height mismatch at function end."); } void NoOutputAssembly::appendDataOffset(std::vector const&) diff --git a/libyul/backends/evm/NoOutputAssembly.h b/libyul/backends/evm/NoOutputAssembly.h index 2669a277c4a4..64832b083df9 100644 --- a/libyul/backends/evm/NoOutputAssembly.h +++ b/libyul/backends/evm/NoOutputAssembly.h @@ -73,7 +73,7 @@ class NoOutputAssembly: public AbstractAssembly void appendAssemblySize() override; std::pair, SubID> createSubAssembly(bool _creation, std::string _name = "") override; - FunctionID registerFunction(uint8_t _args, uint8_t _rets) override; + FunctionID registerFunction(uint8_t _args, uint8_t _rets, bool _nonReturning) override; void beginFunction(FunctionID) override; void endFunction() override; void appendFunctionCall(FunctionID _functionID) override; diff --git a/libyul/backends/evm/OptimizedEVMCodeTransform.cpp b/libyul/backends/evm/OptimizedEVMCodeTransform.cpp index 3a1b78e1eb31..139df8af6098 100644 --- a/libyul/backends/evm/OptimizedEVMCodeTransform.cpp +++ b/libyul/backends/evm/OptimizedEVMCodeTransform.cpp @@ -56,12 +56,12 @@ std::vector OptimizedEVMCodeTransform::run( for (Scope::Function const* function: dfg->functions) { auto const& info = dfg->functionInfo.at(function); - yulAssert(info.parameters.size() <= 0x7f); - yulAssert(info.returnVariables.size() <= 0x7f); - // According to EOF spec function output num equals 0x80 means non-returning function + yulAssert(info.parameters.size() <= std::numeric_limits::max()); + yulAssert(info.returnVariables.size() <= std::numeric_limits::max()); auto functionID = _assembly.registerFunction( static_cast(info.parameters.size()), - static_cast(info.canContinue ? info.returnVariables.size() : 0x80) + static_cast(info.returnVariables.size()), + !info.canContinue ); _builtinContext.functionIDs[function] = functionID; } @@ -128,8 +128,6 @@ void OptimizedEVMCodeTransform::operator()(CFG::FunctionCall const& _call) for (size_t i = 0; i < _call.function.get().numArguments + (useReturnLabel ? 1 : 0); ++i) m_stack.pop_back(); // Push return values to m_stack. - if (!m_simulateFunctionsWithJumps) - yulAssert(_call.function.get().numReturns < 0x80, "Num of function output >= 128"); for (size_t index: ranges::views::iota(0u, _call.function.get().numReturns)) m_stack.emplace_back(TemporarySlot{_call.functionCall, index}); yulAssert(m_assembly.stackHeight() == static_cast(m_stack.size()), ""); diff --git a/test/libsolidity/semanticTests/inlineAssembly/inline_assembly_in_modifiers.sol b/test/libsolidity/semanticTests/inlineAssembly/inline_assembly_in_modifiers.sol index e050d2b52220..bed3add8a6fe 100644 --- a/test/libsolidity/semanticTests/inlineAssembly/inline_assembly_in_modifiers.sol +++ b/test/libsolidity/semanticTests/inlineAssembly/inline_assembly_in_modifiers.sol @@ -27,6 +27,8 @@ contract C { return true; } } +// ==== +// bytecodeFormat: legacy,>=EOFv1 // ---- // f() -> true // g() -> FAILURE From e45133c77a6706e9aee829d56e17096d03ddaba6 Mon Sep 17 00:00:00 2001 From: rodiazet Date: Fri, 13 Dec 2024 14:23:08 +0100 Subject: [PATCH 0662/1022] eof: Add `solAssert` checking that stack height does not go negative. --- libyul/backends/evm/NoOutputAssembly.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/libyul/backends/evm/NoOutputAssembly.cpp b/libyul/backends/evm/NoOutputAssembly.cpp index 840372fcaf83..322191984fd4 100644 --- a/libyul/backends/evm/NoOutputAssembly.cpp +++ b/libyul/backends/evm/NoOutputAssembly.cpp @@ -148,6 +148,7 @@ void NoOutputAssembly::appendFunctionCall(FunctionID _functionID) { auto [args, rets] = m_context.functionSignatures.at(_functionID); m_stackHeight += static_cast(rets) - static_cast(args); + solAssert(m_stackHeight >= 0); } void NoOutputAssembly::appendFunctionReturn() From 81f410fae40f1874539c73e91456df8e516e315a Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Thu, 19 Dec 2024 10:13:00 +0100 Subject: [PATCH 0663/1022] SSACFG liveness: add conditional jump values to live set --- libyul/backends/evm/SSACFGLiveness.cpp | 22 +++++- .../standard_yul_cfg_json_export/output.json | 70 +++++++++++++------ .../strict_asm_yul_cfg_json_export/output | 15 ++-- test/cmdlineTests/yul_cfg_json_export/output | 70 +++++++++++++------ .../libyul/yulSSAControlFlowGraph/complex.yul | 14 ++-- .../yulSSAControlFlowGraph/complex2.yul | 14 ++-- .../yulSSAControlFlowGraph/nested_for.yul | 10 +-- .../nested_function.yul | 4 +- test/libyul/yulSSAControlFlowGraph/switch.yul | 4 +- 9 files changed, 146 insertions(+), 77 deletions(-) diff --git a/libyul/backends/evm/SSACFGLiveness.cpp b/libyul/backends/evm/SSACFGLiveness.cpp index 4537c8c5d8fc..6ecd559ca806 100644 --- a/libyul/backends/evm/SSACFGLiveness.cpp +++ b/libyul/backends/evm/SSACFGLiveness.cpp @@ -18,6 +18,8 @@ #include +#include + #include #include #include @@ -87,9 +89,23 @@ void SSACFGLiveness::runDagDfs() if (!m_topologicalSort.backEdge(blockId, _successor)) live += m_liveIns[_successor.value] - m_cfg.block(_successor).phis; }); - if (std::holds_alternative(block.exit)) - live += std::get(block.exit).returnValues - | ranges::views::filter(literalsFilter(m_cfg)); + util::GenericVisitor exitVisitor { + [](SSACFG::BasicBlock::MainExit const&) {}, + [&](SSACFG::BasicBlock::FunctionReturn const& _functionReturn) { + live += _functionReturn.returnValues | ranges::views::filter(literalsFilter(m_cfg)); + }, + [&](SSACFG::BasicBlock::JumpTable const& _jt) { + if (literalsFilter(m_cfg)(_jt.value)) + live.emplace(_jt.value); + }, + [](SSACFG::BasicBlock::Jump const&) {}, + [&](SSACFG::BasicBlock::ConditionalJump const& _conditionalJump) { + if (literalsFilter(m_cfg)(_conditionalJump.condition)) + live.emplace(_conditionalJump.condition); + }, + [](SSACFG::BasicBlock::Terminated const&) {} + }; + std::visit(exitVisitor, block.exit); // clean out unreachables live = live | ranges::views::filter([&](auto const& valueId) { return !std::holds_alternative(m_cfg.valueInfo(valueId)); }) | ranges::to; diff --git a/test/cmdlineTests/standard_yul_cfg_json_export/output.json b/test/cmdlineTests/standard_yul_cfg_json_export/output.json index fc47f4f7b937..bb13b3e91503 100644 --- a/test/cmdlineTests/standard_yul_cfg_json_export/output.json +++ b/test/cmdlineTests/standard_yul_cfg_json_export/output.json @@ -45,7 +45,8 @@ "liveness": { "in": [], "out": [ - "v0" + "v0", + "v2" ] }, "type": "BuiltinCall" @@ -188,7 +189,8 @@ "liveness": { "in": [], "out": [ - "v0" + "v0", + "v5" ] }, "type": "BuiltinCall" @@ -260,7 +262,8 @@ "v0" ], "out": [ - "v0" + "v0", + "v11" ] }, "type": "BuiltinCall" @@ -303,7 +306,8 @@ "v0" ], "out": [ - "v0" + "v0", + "v12" ] }, "type": "BuiltinCall" @@ -361,7 +365,8 @@ "v0" ], "out": [ - "v0" + "v0", + "v17" ] }, "type": "BuiltinCall" @@ -492,7 +497,8 @@ "liveness": { "in": [], "out": [ - "v0" + "v0", + "v2" ] }, "type": "BuiltinCall" @@ -635,7 +641,8 @@ "liveness": { "in": [], "out": [ - "v0" + "v0", + "v5" ] }, "type": "BuiltinCall" @@ -707,7 +714,8 @@ "v0" ], "out": [ - "v0" + "v0", + "v11" ] }, "type": "BuiltinCall" @@ -750,7 +758,8 @@ "v0" ], "out": [ - "v0" + "v0", + "v12" ] }, "type": "BuiltinCall" @@ -808,7 +817,8 @@ "v0" ], "out": [ - "v0" + "v0", + "v17" ] }, "type": "BuiltinCall" @@ -903,7 +913,8 @@ "out": [ "v0", "v18", - "v24" + "v24", + "v28" ] }, "type": "BuiltinCall" @@ -997,7 +1008,8 @@ "v24" ], "out": [ - "v41" + "v41", + "v42" ] }, "type": "BuiltinCall" @@ -1153,7 +1165,9 @@ "v41" ], "out": [ - "v46" + "v46", + "v59", + "v60" ] }, "type": "BuiltinCall" @@ -1224,10 +1238,12 @@ "instructions": [], "liveness": { "in": [ - "v46" + "v46", + "v59" ], "out": [ - "v46" + "v46", + "v59" ] } }, @@ -1372,7 +1388,8 @@ "v46" ], "out": [ - "v46" + "v46", + "v67" ] }, "type": "BuiltinCall" @@ -1480,7 +1497,8 @@ "out": [ "v46", "v71", - "v77" + "v77", + "v80" ] }, "type": "BuiltinCall" @@ -1570,7 +1588,8 @@ "v77" ], "out": [ - "v46" + "v46", + "v90" ] }, "type": "BuiltinCall" @@ -1718,7 +1737,8 @@ "liveness": { "in": [], "out": [ - "v0" + "v0", + "v2" ] }, "type": "BuiltinCall" @@ -1861,7 +1881,8 @@ "liveness": { "in": [], "out": [ - "v0" + "v0", + "v5" ] }, "type": "BuiltinCall" @@ -1933,7 +1954,8 @@ "v0" ], "out": [ - "v0" + "v0", + "v11" ] }, "type": "BuiltinCall" @@ -1976,7 +1998,8 @@ "v0" ], "out": [ - "v0" + "v0", + "v12" ] }, "type": "BuiltinCall" @@ -2034,7 +2057,8 @@ "v0" ], "out": [ - "v0" + "v0", + "v17" ] }, "type": "BuiltinCall" diff --git a/test/cmdlineTests/strict_asm_yul_cfg_json_export/output b/test/cmdlineTests/strict_asm_yul_cfg_json_export/output index ac154fc16246..a65c164d631d 100644 --- a/test/cmdlineTests/strict_asm_yul_cfg_json_export/output +++ b/test/cmdlineTests/strict_asm_yul_cfg_json_export/output @@ -45,7 +45,8 @@ Yul Control Flow Graph: "liveness": { "in": [], "out": [ - "v0" + "v0", + "v2" ] }, "type": "BuiltinCall" @@ -188,7 +189,8 @@ Yul Control Flow Graph: "liveness": { "in": [], "out": [ - "v0" + "v0", + "v5" ] }, "type": "BuiltinCall" @@ -260,7 +262,8 @@ Yul Control Flow Graph: "v0" ], "out": [ - "v0" + "v0", + "v11" ] }, "type": "BuiltinCall" @@ -303,7 +306,8 @@ Yul Control Flow Graph: "v0" ], "out": [ - "v0" + "v0", + "v12" ] }, "type": "BuiltinCall" @@ -361,7 +365,8 @@ Yul Control Flow Graph: "v0" ], "out": [ - "v0" + "v0", + "v17" ] }, "type": "BuiltinCall" diff --git a/test/cmdlineTests/yul_cfg_json_export/output b/test/cmdlineTests/yul_cfg_json_export/output index 6848d7db9ddb..f6f2ec6d8f42 100644 --- a/test/cmdlineTests/yul_cfg_json_export/output +++ b/test/cmdlineTests/yul_cfg_json_export/output @@ -44,7 +44,8 @@ Yul Control Flow Graph: "liveness": { "in": [], "out": [ - "v0" + "v0", + "v2" ] }, "type": "BuiltinCall" @@ -187,7 +188,8 @@ Yul Control Flow Graph: "liveness": { "in": [], "out": [ - "v0" + "v0", + "v5" ] }, "type": "BuiltinCall" @@ -259,7 +261,8 @@ Yul Control Flow Graph: "v0" ], "out": [ - "v0" + "v0", + "v11" ] }, "type": "BuiltinCall" @@ -302,7 +305,8 @@ Yul Control Flow Graph: "v0" ], "out": [ - "v0" + "v0", + "v12" ] }, "type": "BuiltinCall" @@ -360,7 +364,8 @@ Yul Control Flow Graph: "v0" ], "out": [ - "v0" + "v0", + "v17" ] }, "type": "BuiltinCall" @@ -492,7 +497,8 @@ Yul Control Flow Graph: "liveness": { "in": [], "out": [ - "v0" + "v0", + "v2" ] }, "type": "BuiltinCall" @@ -635,7 +641,8 @@ Yul Control Flow Graph: "liveness": { "in": [], "out": [ - "v0" + "v0", + "v5" ] }, "type": "BuiltinCall" @@ -707,7 +714,8 @@ Yul Control Flow Graph: "v0" ], "out": [ - "v0" + "v0", + "v11" ] }, "type": "BuiltinCall" @@ -750,7 +758,8 @@ Yul Control Flow Graph: "v0" ], "out": [ - "v0" + "v0", + "v12" ] }, "type": "BuiltinCall" @@ -808,7 +817,8 @@ Yul Control Flow Graph: "v0" ], "out": [ - "v0" + "v0", + "v17" ] }, "type": "BuiltinCall" @@ -903,7 +913,8 @@ Yul Control Flow Graph: "out": [ "v0", "v18", - "v24" + "v24", + "v28" ] }, "type": "BuiltinCall" @@ -997,7 +1008,8 @@ Yul Control Flow Graph: "v24" ], "out": [ - "v41" + "v41", + "v42" ] }, "type": "BuiltinCall" @@ -1153,7 +1165,9 @@ Yul Control Flow Graph: "v41" ], "out": [ - "v46" + "v46", + "v59", + "v60" ] }, "type": "BuiltinCall" @@ -1224,10 +1238,12 @@ Yul Control Flow Graph: "instructions": [], "liveness": { "in": [ - "v46" + "v46", + "v59" ], "out": [ - "v46" + "v46", + "v59" ] } }, @@ -1372,7 +1388,8 @@ Yul Control Flow Graph: "v46" ], "out": [ - "v46" + "v46", + "v67" ] }, "type": "BuiltinCall" @@ -1480,7 +1497,8 @@ Yul Control Flow Graph: "out": [ "v46", "v71", - "v77" + "v77", + "v80" ] }, "type": "BuiltinCall" @@ -1570,7 +1588,8 @@ Yul Control Flow Graph: "v77" ], "out": [ - "v46" + "v46", + "v90" ] }, "type": "BuiltinCall" @@ -1718,7 +1737,8 @@ Yul Control Flow Graph: "liveness": { "in": [], "out": [ - "v0" + "v0", + "v2" ] }, "type": "BuiltinCall" @@ -1861,7 +1881,8 @@ Yul Control Flow Graph: "liveness": { "in": [], "out": [ - "v0" + "v0", + "v5" ] }, "type": "BuiltinCall" @@ -1933,7 +1954,8 @@ Yul Control Flow Graph: "v0" ], "out": [ - "v0" + "v0", + "v11" ] }, "type": "BuiltinCall" @@ -1976,7 +1998,8 @@ Yul Control Flow Graph: "v0" ], "out": [ - "v0" + "v0", + "v12" ] }, "type": "BuiltinCall" @@ -2034,7 +2057,8 @@ Yul Control Flow Graph: "v0" ], "out": [ - "v0" + "v0", + "v17" ] }, "type": "BuiltinCall" diff --git a/test/libyul/yulSSAControlFlowGraph/complex.yul b/test/libyul/yulSSAControlFlowGraph/complex.yul index 6fb0453c186b..3f7f329a48d5 100644 --- a/test/libyul/yulSSAControlFlowGraph/complex.yul +++ b/test/libyul/yulSSAControlFlowGraph/complex.yul @@ -69,7 +69,7 @@ // Block1_0Exit -> Block1_1 [style="solid"]; // Block1_1 [label="\ // Block 1; (1, max 17)\nLiveIn: v0,v1,v5\l\ -// LiveOut: v0,v1,v5\l\nv5 := φ(\l\ +// LiveOut: v0,v1,v5,v6\l\nv5 := φ(\l\ // Block 0 => 42,\l\ // Block 21 => v43\l\ // )\l\ @@ -81,7 +81,7 @@ // Block1_1Exit:1 -> Block1_2 [style="solid"]; // Block1_2 [label="\ // Block 2; (2, max 17)\nLiveIn: v0,v1,v5\l\ -// LiveOut: v0,v1,v5,v7\l\nv7 := mload(v5)\l\ +// LiveOut: v0,v1,v5,v7,v8\l\nv7 := mload(v5)\l\ // v8 := eq(0, v7)\l\ // "]; // Block1_2 -> Block1_2Exit; @@ -103,7 +103,7 @@ // Block1_6Exit -> Block1_4 [style="solid"]; // Block1_7 [label="\ // Block 7; (5, max 17)\nLiveIn: v0,v1,v5,v7\l\ -// LiveOut: v0,v1,v5,v7\l\nv13 := eq(1, v7)\l\ +// LiveOut: v0,v1,v5,v7,v13\l\nv13 := eq(1, v7)\l\ // "]; // Block1_7 -> Block1_7Exit; // Block1_7Exit [label="{ If v13 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; @@ -117,7 +117,7 @@ // Block1_9 -> Block1_9Exit; // Block1_10 [label="\ // Block 10; (7, max 17)\nLiveIn: v0,v1,v5,v7\l\ -// LiveOut: v0,v1,v5,v7\l\nv20 := eq(2, v7)\l\ +// LiveOut: v0,v1,v5,v7,v20\l\nv20 := eq(2, v7)\l\ // "]; // Block1_10 -> Block1_10Exit; // Block1_10Exit [label="{ If v20 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; @@ -132,7 +132,7 @@ // Block1_12 -> Block1_12Exit; // Block1_13 [label="\ // Block 13; (9, max 17)\nLiveIn: v0,v1,v5,v7\l\ -// LiveOut: v0,v1,v5\l\nv25 := eq(3, v7)\l\ +// LiveOut: v0,v1,v5,v25\l\nv25 := eq(3, v7)\l\ // "]; // Block1_13 -> Block1_13Exit; // Block1_13Exit [label="{ If v25 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; @@ -147,7 +147,7 @@ // Block1_15Exit -> Block1_5 [style="solid"]; // Block1_16 [label="\ // Block 16; (15, max 17)\nLiveIn: v0,v1,v5\l\ -// LiveOut: v0,v1,v5\l\nv29 := mload(v1)\l\ +// LiveOut: v0,v1,v5,v29\l\nv29 := mload(v1)\l\ // "]; // Block1_16 -> Block1_16Exit; // Block1_16Exit [label="{ If v29 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; @@ -175,7 +175,7 @@ // Block1_18Exit -> Block1_5 [style="solid"]; // Block1_3 [label="\ // Block 3; (12, max 14)\nLiveIn: v0,v1,v5\l\ -// LiveOut: v0,v1,v43\l\nv43 := add(1, v5)\l\ +// LiveOut: v0,v1,v43,v44\l\nv43 := add(1, v5)\l\ // v44 := calldataload(v43)\l\ // "]; // Block1_3 -> Block1_3Exit; diff --git a/test/libyul/yulSSAControlFlowGraph/complex2.yul b/test/libyul/yulSSAControlFlowGraph/complex2.yul index c3ea8b94f8aa..6d801124cda3 100644 --- a/test/libyul/yulSSAControlFlowGraph/complex2.yul +++ b/test/libyul/yulSSAControlFlowGraph/complex2.yul @@ -85,7 +85,7 @@ // Block1_0Exit -> Block1_1 [style="solid"]; // Block1_1 [label="\ // Block 1; (1, max 17)\nLiveIn: v0,v1,v5\l\ -// LiveOut: v0,v1,v5\l\nv5 := φ(\l\ +// LiveOut: v0,v1,v5,v6\l\nv5 := φ(\l\ // Block 0 => 42,\l\ // Block 21 => v43\l\ // )\l\ @@ -97,7 +97,7 @@ // Block1_1Exit:1 -> Block1_2 [style="solid"]; // Block1_2 [label="\ // Block 2; (2, max 17)\nLiveIn: v0,v1,v5\l\ -// LiveOut: v0,v1,v5,v7\l\nv7 := mload(v5)\l\ +// LiveOut: v0,v1,v5,v7,v8\l\nv7 := mload(v5)\l\ // v8 := eq(0, v7)\l\ // "]; // Block1_2 -> Block1_2Exit; @@ -119,7 +119,7 @@ // Block1_6Exit -> Block1_4 [style="solid"]; // Block1_7 [label="\ // Block 7; (5, max 17)\nLiveIn: v0,v1,v5,v7\l\ -// LiveOut: v0,v1,v5,v7\l\nv13 := eq(1, v7)\l\ +// LiveOut: v0,v1,v5,v7,v13\l\nv13 := eq(1, v7)\l\ // "]; // Block1_7 -> Block1_7Exit; // Block1_7Exit [label="{ If v13 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; @@ -133,7 +133,7 @@ // Block1_9 -> Block1_9Exit; // Block1_10 [label="\ // Block 10; (7, max 17)\nLiveIn: v0,v1,v5,v7\l\ -// LiveOut: v0,v1,v5,v7\l\nv20 := eq(2, v7)\l\ +// LiveOut: v0,v1,v5,v7,v20\l\nv20 := eq(2, v7)\l\ // "]; // Block1_10 -> Block1_10Exit; // Block1_10Exit [label="{ If v20 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; @@ -148,7 +148,7 @@ // Block1_12 -> Block1_12Exit; // Block1_13 [label="\ // Block 13; (9, max 17)\nLiveIn: v0,v1,v5,v7\l\ -// LiveOut: v0,v1,v5\l\nv25 := eq(3, v7)\l\ +// LiveOut: v0,v1,v5,v25\l\nv25 := eq(3, v7)\l\ // "]; // Block1_13 -> Block1_13Exit; // Block1_13Exit [label="{ If v25 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; @@ -163,7 +163,7 @@ // Block1_15Exit -> Block1_5 [style="solid"]; // Block1_16 [label="\ // Block 16; (15, max 17)\nLiveIn: v0,v1,v5\l\ -// LiveOut: v0,v1,v5\l\nv29 := mload(v1)\l\ +// LiveOut: v0,v1,v5,v29\l\nv29 := mload(v1)\l\ // "]; // Block1_16 -> Block1_16Exit; // Block1_16Exit [label="{ If v29 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; @@ -191,7 +191,7 @@ // Block1_18Exit -> Block1_5 [style="solid"]; // Block1_3 [label="\ // Block 3; (12, max 14)\nLiveIn: v0,v1,v5\l\ -// LiveOut: v0,v1,v43\l\nv43 := add(1, v5)\l\ +// LiveOut: v0,v1,v43,v44\l\nv43 := add(1, v5)\l\ // v44 := calldataload(v43)\l\ // "]; // Block1_3 -> Block1_3Exit; diff --git a/test/libyul/yulSSAControlFlowGraph/nested_for.yul b/test/libyul/yulSSAControlFlowGraph/nested_for.yul index b088e3b55ed8..f816df462b91 100644 --- a/test/libyul/yulSSAControlFlowGraph/nested_for.yul +++ b/test/libyul/yulSSAControlFlowGraph/nested_for.yul @@ -33,7 +33,7 @@ // Block0_0Exit -> Block0_1 [style="solid"]; // Block0_1 [label="\ // Block 1; (1, max 24)\nLiveIn: v2\l\ -// LiveOut: v2\l\nv2 := φ(\l\ +// LiveOut: v2,v3\l\nv2 := φ(\l\ // Block 0 => 0,\l\ // Block 3 => v36\l\ // )\l\ @@ -56,7 +56,7 @@ // Block0_4 -> Block0_4Exit; // Block0_5 [label="\ // Block 5; (3, max 23)\nLiveIn: v2,v4\l\ -// LiveOut: v2,v4\l\nv4 := φ(\l\ +// LiveOut: v2,v4,v5\l\nv4 := φ(\l\ // Block 2 => 0,\l\ // Block 7 => v35\l\ // )\l\ @@ -80,7 +80,7 @@ // Block0_8Exit -> Block0_3 [style="solid"]; // Block0_9 [label="\ // Block 9; (5, max 21)\nLiveIn: v2,v4,v6\l\ -// LiveOut: v2,v4,v6\l\nv6 := φ(\l\ +// LiveOut: v2,v4,v6,v7\l\nv6 := φ(\l\ // Block 6 => 0,\l\ // Block 11 => v31\l\ // )\l\ @@ -132,7 +132,7 @@ // Block0_7Exit -> Block0_5 [style="dashed"]; // Block0_15 [label="\ // Block 15; (8, max 19)\nLiveIn: v2,v4,v6,v8\l\ -// LiveOut: v2,v4,v6,v8\l\nv8 := φ(\l\ +// LiveOut: v2,v4,v6,v8,v9\l\nv8 := φ(\l\ // Block 13 => 0,\l\ // Block 17 => v16\l\ // )\l\ @@ -171,7 +171,7 @@ // Block0_18Exit -> Block0_14 [style="solid"]; // Block0_21 [label="\ // Block 21; (14, max 19)\nLiveIn: v2,v4,v6,v19\l\ -// LiveOut: v2,v4,v6,v19\l\nv19 := φ(\l\ +// LiveOut: v2,v4,v6,v19,v20\l\nv19 := φ(\l\ // Block 19 => 0,\l\ // Block 23 => v26\l\ // )\l\ diff --git a/test/libyul/yulSSAControlFlowGraph/nested_function.yul b/test/libyul/yulSSAControlFlowGraph/nested_function.yul index acda15ce81a5..1263d4782db8 100644 --- a/test/libyul/yulSSAControlFlowGraph/nested_function.yul +++ b/test/libyul/yulSSAControlFlowGraph/nested_function.yul @@ -103,7 +103,7 @@ // FunctionEntry_cycle1_0 -> Block7_0; // Block7_0 [label="\ // Block 0; (0, max 2)\nLiveIn: \l\ -// LiveOut: \l\nv2 := mload(3)\l\ +// LiveOut: v2\l\nv2 := mload(3)\l\ // "]; // Block7_0 -> Block7_0Exit; // Block7_0Exit [label="{ If v2 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; @@ -130,7 +130,7 @@ // FunctionEntry_cycle2_0 -> Block8_0; // Block8_0 [label="\ // Block 0; (0, max 2)\nLiveIn: \l\ -// LiveOut: \l\nv2 := mload(4)\l\ +// LiveOut: v2\l\nv2 := mload(4)\l\ // "]; // Block8_0 -> Block8_0Exit; // Block8_0Exit [label="{ If v2 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; diff --git a/test/libyul/yulSSAControlFlowGraph/switch.yul b/test/libyul/yulSSAControlFlowGraph/switch.yul index 10573b012298..91b3daeeeded 100644 --- a/test/libyul/yulSSAControlFlowGraph/switch.yul +++ b/test/libyul/yulSSAControlFlowGraph/switch.yul @@ -23,7 +23,7 @@ // Entry0 -> Block0_0; // Block0_0 [label="\ // Block 0; (0, max 5)\nLiveIn: \l\ -// LiveOut: v3\l\nv1 := calldataload(3)\l\ +// LiveOut: v3,v4\l\nv1 := calldataload(3)\l\ // v3 := sload(0)\l\ // v4 := eq(0, v3)\l\ // "]; @@ -40,7 +40,7 @@ // Block0_2Exit -> Block0_1 [style="solid"]; // Block0_3 [label="\ // Block 3; (3, max 5)\nLiveIn: v3\l\ -// LiveOut: \l\nv7 := eq(1, v3)\l\ +// LiveOut: v7\l\nv7 := eq(1, v3)\l\ // "]; // Block0_3 -> Block0_3Exit; // Block0_3Exit [label="{ If v7 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; From d2e468cb735f1c35f1a28d4cf6e560028892479e Mon Sep 17 00:00:00 2001 From: DaniPopes <57450786+DaniPopes@users.noreply.github.com> Date: Thu, 19 Dec 2024 16:51:50 +0200 Subject: [PATCH 0664/1022] Remove unused expression annotation Remove the unused lValueOfOrdinaryAssignment expression annotation. --- libsolidity/analysis/TypeChecker.cpp | 15 ++++----------- libsolidity/analysis/TypeChecker.h | 2 +- libsolidity/ast/ASTAnnotations.h | 4 ---- 3 files changed, 5 insertions(+), 16 deletions(-) diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp index 4264bf71d46f..b461fa283026 100644 --- a/libsolidity/analysis/TypeChecker.cpp +++ b/libsolidity/analysis/TypeChecker.cpp @@ -1454,10 +1454,7 @@ void TypeChecker::checkExpressionAssignment(Type const& _type, Expression const& bool TypeChecker::visit(Assignment const& _assignment) { - requireLValue( - _assignment.leftHandSide(), - _assignment.assignmentOperator() == Token::Assign - ); + requireLValue(_assignment.leftHandSide()); Type const* t = type(_assignment.leftHandSide()); _assignment.annotation().type = t; _assignment.annotation().isPure = false; @@ -1518,10 +1515,7 @@ bool TypeChecker::visit(TupleExpression const& _tuple) for (auto const& component: components) if (component) { - requireLValue( - *component, - _tuple.annotation().lValueOfOrdinaryAssignment - ); + requireLValue(*component); types.push_back(type(*component)); } else @@ -1614,7 +1608,7 @@ bool TypeChecker::visit(UnaryOperation const& _operation) Token op = _operation.getOperator(); bool const modifying = (op == Token::Inc || op == Token::Dec || op == Token::Delete); if (modifying) - requireLValue(_operation.subExpression(), false); + requireLValue(_operation.subExpression()); else _operation.subExpression().accept(*this); Type const* operandType = type(_operation.subExpression()); @@ -4137,10 +4131,9 @@ bool TypeChecker::expectType(Expression const& _expression, Type const& _expecte return true; } -void TypeChecker::requireLValue(Expression const& _expression, bool _ordinaryAssignment) +void TypeChecker::requireLValue(Expression const& _expression) { _expression.annotation().willBeWrittenTo = true; - _expression.annotation().lValueOfOrdinaryAssignment = _ordinaryAssignment; _expression.accept(*this); if (*_expression.annotation().isLValue) diff --git a/libsolidity/analysis/TypeChecker.h b/libsolidity/analysis/TypeChecker.h index a517a750c323..e4bc12705314 100644 --- a/libsolidity/analysis/TypeChecker.h +++ b/libsolidity/analysis/TypeChecker.h @@ -175,7 +175,7 @@ class TypeChecker: private ASTConstVisitor /// convertible to @a _expectedType. bool expectType(Expression const& _expression, Type const& _expectedType); /// Runs type checks on @a _expression to infer its type and then checks that it is an LValue. - void requireLValue(Expression const& _expression, bool _ordinaryAssignment); + void requireLValue(Expression const& _expression); bool useABICoderV2() const; diff --git a/libsolidity/ast/ASTAnnotations.h b/libsolidity/ast/ASTAnnotations.h index f017481be5aa..3f817b180fd9 100644 --- a/libsolidity/ast/ASTAnnotations.h +++ b/libsolidity/ast/ASTAnnotations.h @@ -279,10 +279,6 @@ struct ExpressionAnnotation: ASTAnnotation util::SetOnce isLValue; /// Whether the expression is used in a context where the LValue is actually required. bool willBeWrittenTo = false; - /// Whether the expression is an lvalue that is only assigned. - /// Would be false for --, ++, delete, +=, -=, .... - /// Only relevant if isLvalue == true - bool lValueOfOrdinaryAssignment = false; /// Types and - if given - names of arguments if the expr. is a function /// that is called, used for overload resolution From 749f64c807af480b6d4e6859493381cabd1b2077 Mon Sep 17 00:00:00 2001 From: rodiazet Date: Mon, 16 Dec 2024 19:59:01 +0100 Subject: [PATCH 0665/1022] eof: Add EOF enabled predicate to BOOST tests. --- test/Common.cpp | 7 +++++++ test/Common.h | 4 ++++ 2 files changed, 11 insertions(+) diff --git a/test/Common.cpp b/test/Common.cpp index 43f73d4d71d4..30738dcfc6dd 100644 --- a/test/Common.cpp +++ b/test/Common.cpp @@ -302,6 +302,13 @@ bool isValidSemanticTestPath(boost::filesystem::path const& _testPath) return true; } +boost::unit_test::precondition::predicate_t nonEOF() +{ + return [](boost::unit_test::test_unit_id) { + return !solidity::test::CommonOptions::get().eofVersion().has_value(); + }; +} + boost::unit_test::precondition::predicate_t minEVMVersionCheck(langutil::EVMVersion _minEVMVersion) { return [_minEVMVersion](boost::unit_test::test_unit_id) { diff --git a/test/Common.h b/test/Common.h index c3d21d258295..866f6945a645 100644 --- a/test/Common.h +++ b/test/Common.h @@ -112,6 +112,10 @@ bool isValidSemanticTestPath(boost::filesystem::path const& _testPath); /// @return A predicate (function) that can be passed into @a boost::unit_test::precondition(). boost::unit_test::precondition::predicate_t minEVMVersionCheck(langutil::EVMVersion _minEVMVersion); +/// Helper that can be used to skip tests when the EOF is not supported by the test case. +/// @return A predicate (function) that can be passed into @a boost::unit_test::precondition(). +boost::unit_test::precondition::predicate_t nonEOF(); + bool loadVMs(CommonOptions const& _options); /** From 53c6abc7fcf2b0cef8a75baace1369d375eca3bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Wed, 4 Dec 2024 01:31:06 +0100 Subject: [PATCH 0666/1022] Fix typos in a couple of Yul test names --- .../{long_obect_name.yul => long_object_name.yul} | 0 .../{call_intruction_in_eof.yul => call_instruction_in_eof.yul} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename test/libyul/yulInterpreterTests/{long_obect_name.yul => long_object_name.yul} (100%) rename test/libyul/yulSyntaxTests/eof/{call_intruction_in_eof.yul => call_instruction_in_eof.yul} (100%) diff --git a/test/libyul/yulInterpreterTests/long_obect_name.yul b/test/libyul/yulInterpreterTests/long_object_name.yul similarity index 100% rename from test/libyul/yulInterpreterTests/long_obect_name.yul rename to test/libyul/yulInterpreterTests/long_object_name.yul diff --git a/test/libyul/yulSyntaxTests/eof/call_intruction_in_eof.yul b/test/libyul/yulSyntaxTests/eof/call_instruction_in_eof.yul similarity index 100% rename from test/libyul/yulSyntaxTests/eof/call_intruction_in_eof.yul rename to test/libyul/yulSyntaxTests/eof/call_instruction_in_eof.yul From 715573aa379ab1a268fc8fedbc7861d15fccd095 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Wed, 4 Dec 2024 03:42:34 +0100 Subject: [PATCH 0667/1022] More accurate unimplemented message for assembly import on EOF --- libevmasm/Assembly.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libevmasm/Assembly.cpp b/libevmasm/Assembly.cpp index 001865b2c4c0..17c4ee10e741 100644 --- a/libevmasm/Assembly.cpp +++ b/libevmasm/Assembly.cpp @@ -90,7 +90,7 @@ void Assembly::importAssemblyItemsFromJSON(Json const& _code, std::vector const& _sourceIndice Json root; root[".code"] = Json::array(); Json& code = root[".code"]; - // TODO: support EOF + // TODO: support EOF solUnimplementedAssert(!m_eofVersion.has_value(), "Assembly output for EOF is not yet implemented."); solAssert(m_codeSections.size() == 1); for (AssemblyItem const& item: m_codeSections.front().items) From bb9d694a6a6ef18947d17bd914af800b60c7e652 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Thu, 19 Dec 2024 16:33:40 +0100 Subject: [PATCH 0668/1022] Assembly: Fix check for the maximum size of the EOF data section --- libevmasm/Assembly.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/libevmasm/Assembly.cpp b/libevmasm/Assembly.cpp index 17c4ee10e741..430124e2adad 100644 --- a/libevmasm/Assembly.cpp +++ b/libevmasm/Assembly.cpp @@ -1683,8 +1683,12 @@ LinkerObject const& Assembly::assembleEOF() const // DATALOADN loads 32 bytes from EOF data section zero padded if reading out of data bounds. // In our case we do not allow DATALOADN with offsets which reads out of data bounds. auto const staticAuxDataSize = maxAuxDataLoadNOffset.has_value() ? (*maxAuxDataLoadNOffset + 32u) : 0u; - solRequire(preDeployDataSectionSize + staticAuxDataSize < std::numeric_limits::max(), AssemblyException, - "Invalid DATALOADN offset."); + auto const preDeployAndStaticAuxDataSize = preDeployDataSectionSize + staticAuxDataSize; + solRequire( + preDeployAndStaticAuxDataSize <= std::numeric_limits::max(), + AssemblyException, + "Invalid DATALOADN offset." + ); // If some data was already added to data section we need to update data section refs accordingly if (preDeployDataSectionSize > 0) @@ -1695,8 +1699,6 @@ LinkerObject const& Assembly::assembleEOF() const setBigEndianUint16(ret.bytecode, refPosition, staticAuxDataOffset + preDeployDataSectionSize); } - auto const preDeployAndStaticAuxDataSize = preDeployDataSectionSize + staticAuxDataSize; - setBigEndianUint16(ret.bytecode, dataSectionSizePosition, preDeployAndStaticAuxDataSize); return ret; From b639134f3a87e2b3701889cae7ead1ff48ca41a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Sat, 30 Nov 2024 04:00:48 +0100 Subject: [PATCH 0669/1022] Assemble Yul in syntax tests so that CodeGenerationErrors can be tested --- test/libyul/SyntaxTest.cpp | 6 ++++++ .../loadimmutable_without_setimmutable.yul | 11 +++++++++++ 2 files changed, 17 insertions(+) create mode 100644 test/libyul/yulSyntaxTests/loadimmutable_without_setimmutable.yul diff --git a/test/libyul/SyntaxTest.cpp b/test/libyul/SyntaxTest.cpp index 70f54b86ac71..88046c02f8a1 100644 --- a/test/libyul/SyntaxTest.cpp +++ b/test/libyul/SyntaxTest.cpp @@ -41,6 +41,12 @@ void SyntaxTest::parseAndAnalyze() auto const& [sourceUnitName, source] = *m_sources.sources.begin(); YulStack yulStack = parseYul(source); + if (!yulStack.hasErrors()) + { + // Assemble the object so that we can test CodeGenerationErrors too. + yulStack.optimize(); + yulStack.assemble(YulStack::Machine::EVM); + } for (auto const& error: yulStack.errors()) { int locationStart = -1; diff --git a/test/libyul/yulSyntaxTests/loadimmutable_without_setimmutable.yul b/test/libyul/yulSyntaxTests/loadimmutable_without_setimmutable.yul new file mode 100644 index 000000000000..8695e938d7fb --- /dev/null +++ b/test/libyul/yulSyntaxTests/loadimmutable_without_setimmutable.yul @@ -0,0 +1,11 @@ +object "C" { + code {} + + object "C_deployed" { + code { + sstore(0, loadimmutable("1")) + } + } +} +// ---- +// CodeGenerationError 1284: Some immutables were read from but never assigned, possibly because of optimization. From ba19d3ff3309ff4e1af740758438169a9eb92076 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Sat, 30 Nov 2024 03:21:24 +0100 Subject: [PATCH 0670/1022] Throw CodeGenerationError in two cases where we can't generate bytecode due to EOF limits --- libevmasm/Assembly.cpp | 20 +- .../auxdataloadn_in_eof_offset_too_high.yul | 13 + .../eof/too_large_code_section.yul | 1880 +++++++++++++++++ 3 files changed, 1908 insertions(+), 5 deletions(-) create mode 100644 test/libyul/yulSyntaxTests/eof/auxdataloadn_in_eof_offset_too_high.yul create mode 100644 test/libyul/yulSyntaxTests/eof/too_large_code_section.yul diff --git a/libevmasm/Assembly.cpp b/libevmasm/Assembly.cpp index 430124e2adad..1cd3e11faf8f 100644 --- a/libevmasm/Assembly.cpp +++ b/libevmasm/Assembly.cpp @@ -1642,6 +1642,14 @@ LinkerObject const& Assembly::assembleEOF() const } } + if (ret.bytecode.size() - sectionStart > std::numeric_limits::max()) + // TODO: Include source location. Note that origin locations we have in debug data are + // not usable for error reporting when compiling pure Yul because they point at the optimized source. + throw Error( + 2202_error, + Error::Type::CodeGenerationError, + "Code section too large for EOF." + ); setBigEndianUint16(ret.bytecode, codeSectionSizePositions[codeSectionIndex], ret.bytecode.size() - sectionStart); } @@ -1684,11 +1692,13 @@ LinkerObject const& Assembly::assembleEOF() const // In our case we do not allow DATALOADN with offsets which reads out of data bounds. auto const staticAuxDataSize = maxAuxDataLoadNOffset.has_value() ? (*maxAuxDataLoadNOffset + 32u) : 0u; auto const preDeployAndStaticAuxDataSize = preDeployDataSectionSize + staticAuxDataSize; - solRequire( - preDeployAndStaticAuxDataSize <= std::numeric_limits::max(), - AssemblyException, - "Invalid DATALOADN offset." - ); + + if (preDeployAndStaticAuxDataSize > std::numeric_limits::max()) + throw Error( + 3965_error, + Error::Type::CodeGenerationError, + "The highest accessed data offset exceeds the maximum possible size of the static auxdata section." + ); // If some data was already added to data section we need to update data section refs accordingly if (preDeployDataSectionSize > 0) diff --git a/test/libyul/yulSyntaxTests/eof/auxdataloadn_in_eof_offset_too_high.yul b/test/libyul/yulSyntaxTests/eof/auxdataloadn_in_eof_offset_too_high.yul new file mode 100644 index 000000000000..1d163c232ca6 --- /dev/null +++ b/test/libyul/yulSyntaxTests/eof/auxdataloadn_in_eof_offset_too_high.yul @@ -0,0 +1,13 @@ +object "a" { + code { + { + mstore(0, auxdataloadn(0xffe0)) + return(0, 32) + } + } + data "data1" hex"48656c6c6f2c20576f726c6421" +} +// ==== +// bytecodeFormat: >=EOFv1 +// ---- +// CodeGenerationError 3965: The highest accessed data offset exceeds the maximum possible size of the static auxdata section. diff --git a/test/libyul/yulSyntaxTests/eof/too_large_code_section.yul b/test/libyul/yulSyntaxTests/eof/too_large_code_section.yul new file mode 100644 index 000000000000..ce69a69a51c5 --- /dev/null +++ b/test/libyul/yulSyntaxTests/eof/too_large_code_section.yul @@ -0,0 +1,1880 @@ +{ + sstore("112233445566778899aabbccddee0000", "112233445566778899aabbccddee0000") + sstore("112233445566778899aabbccddee0001", "112233445566778899aabbccddee0001") + sstore("112233445566778899aabbccddee0002", "112233445566778899aabbccddee0002") + sstore("112233445566778899aabbccddee0003", "112233445566778899aabbccddee0003") + sstore("112233445566778899aabbccddee0004", "112233445566778899aabbccddee0004") + sstore("112233445566778899aabbccddee0005", "112233445566778899aabbccddee0005") + sstore("112233445566778899aabbccddee0006", "112233445566778899aabbccddee0006") + sstore("112233445566778899aabbccddee0007", "112233445566778899aabbccddee0007") + sstore("112233445566778899aabbccddee0008", "112233445566778899aabbccddee0008") + sstore("112233445566778899aabbccddee0009", "112233445566778899aabbccddee0009") + sstore("112233445566778899aabbccddee000a", "112233445566778899aabbccddee000a") + sstore("112233445566778899aabbccddee000b", "112233445566778899aabbccddee000b") + sstore("112233445566778899aabbccddee000c", "112233445566778899aabbccddee000c") + sstore("112233445566778899aabbccddee000d", "112233445566778899aabbccddee000d") + sstore("112233445566778899aabbccddee000e", "112233445566778899aabbccddee000e") + sstore("112233445566778899aabbccddee000f", "112233445566778899aabbccddee000f") + sstore("112233445566778899aabbccddee0010", "112233445566778899aabbccddee0010") + sstore("112233445566778899aabbccddee0011", "112233445566778899aabbccddee0011") + sstore("112233445566778899aabbccddee0012", "112233445566778899aabbccddee0012") + sstore("112233445566778899aabbccddee0013", "112233445566778899aabbccddee0013") + sstore("112233445566778899aabbccddee0014", "112233445566778899aabbccddee0014") + sstore("112233445566778899aabbccddee0015", "112233445566778899aabbccddee0015") + sstore("112233445566778899aabbccddee0016", "112233445566778899aabbccddee0016") + sstore("112233445566778899aabbccddee0017", "112233445566778899aabbccddee0017") + sstore("112233445566778899aabbccddee0018", "112233445566778899aabbccddee0018") + sstore("112233445566778899aabbccddee0019", "112233445566778899aabbccddee0019") + sstore("112233445566778899aabbccddee001a", "112233445566778899aabbccddee001a") + sstore("112233445566778899aabbccddee001b", "112233445566778899aabbccddee001b") + sstore("112233445566778899aabbccddee001c", "112233445566778899aabbccddee001c") + sstore("112233445566778899aabbccddee001d", "112233445566778899aabbccddee001d") + sstore("112233445566778899aabbccddee001e", "112233445566778899aabbccddee001e") + sstore("112233445566778899aabbccddee001f", "112233445566778899aabbccddee001f") + sstore("112233445566778899aabbccddee0020", "112233445566778899aabbccddee0020") + sstore("112233445566778899aabbccddee0021", "112233445566778899aabbccddee0021") + sstore("112233445566778899aabbccddee0022", "112233445566778899aabbccddee0022") + sstore("112233445566778899aabbccddee0023", "112233445566778899aabbccddee0023") + sstore("112233445566778899aabbccddee0024", "112233445566778899aabbccddee0024") + sstore("112233445566778899aabbccddee0025", "112233445566778899aabbccddee0025") + sstore("112233445566778899aabbccddee0026", "112233445566778899aabbccddee0026") + sstore("112233445566778899aabbccddee0027", "112233445566778899aabbccddee0027") + sstore("112233445566778899aabbccddee0028", "112233445566778899aabbccddee0028") + sstore("112233445566778899aabbccddee0029", "112233445566778899aabbccddee0029") + sstore("112233445566778899aabbccddee002a", "112233445566778899aabbccddee002a") + sstore("112233445566778899aabbccddee002b", "112233445566778899aabbccddee002b") + sstore("112233445566778899aabbccddee002c", "112233445566778899aabbccddee002c") + sstore("112233445566778899aabbccddee002d", "112233445566778899aabbccddee002d") + sstore("112233445566778899aabbccddee002e", "112233445566778899aabbccddee002e") + sstore("112233445566778899aabbccddee002f", "112233445566778899aabbccddee002f") + sstore("112233445566778899aabbccddee0030", "112233445566778899aabbccddee0030") + sstore("112233445566778899aabbccddee0031", "112233445566778899aabbccddee0031") + sstore("112233445566778899aabbccddee0032", "112233445566778899aabbccddee0032") + sstore("112233445566778899aabbccddee0033", "112233445566778899aabbccddee0033") + sstore("112233445566778899aabbccddee0034", "112233445566778899aabbccddee0034") + sstore("112233445566778899aabbccddee0035", "112233445566778899aabbccddee0035") + sstore("112233445566778899aabbccddee0036", "112233445566778899aabbccddee0036") + sstore("112233445566778899aabbccddee0037", "112233445566778899aabbccddee0037") + sstore("112233445566778899aabbccddee0038", "112233445566778899aabbccddee0038") + sstore("112233445566778899aabbccddee0039", "112233445566778899aabbccddee0039") + sstore("112233445566778899aabbccddee003a", "112233445566778899aabbccddee003a") + sstore("112233445566778899aabbccddee003b", "112233445566778899aabbccddee003b") + sstore("112233445566778899aabbccddee003c", "112233445566778899aabbccddee003c") + sstore("112233445566778899aabbccddee003d", "112233445566778899aabbccddee003d") + sstore("112233445566778899aabbccddee003e", "112233445566778899aabbccddee003e") + sstore("112233445566778899aabbccddee003f", "112233445566778899aabbccddee003f") + sstore("112233445566778899aabbccddee0040", "112233445566778899aabbccddee0040") + sstore("112233445566778899aabbccddee0041", "112233445566778899aabbccddee0041") + sstore("112233445566778899aabbccddee0042", "112233445566778899aabbccddee0042") + sstore("112233445566778899aabbccddee0043", "112233445566778899aabbccddee0043") + sstore("112233445566778899aabbccddee0044", "112233445566778899aabbccddee0044") + sstore("112233445566778899aabbccddee0045", "112233445566778899aabbccddee0045") + sstore("112233445566778899aabbccddee0046", "112233445566778899aabbccddee0046") + sstore("112233445566778899aabbccddee0047", "112233445566778899aabbccddee0047") + sstore("112233445566778899aabbccddee0048", "112233445566778899aabbccddee0048") + sstore("112233445566778899aabbccddee0049", "112233445566778899aabbccddee0049") + sstore("112233445566778899aabbccddee004a", "112233445566778899aabbccddee004a") + sstore("112233445566778899aabbccddee004b", "112233445566778899aabbccddee004b") + sstore("112233445566778899aabbccddee004c", "112233445566778899aabbccddee004c") + sstore("112233445566778899aabbccddee004d", "112233445566778899aabbccddee004d") + sstore("112233445566778899aabbccddee004e", "112233445566778899aabbccddee004e") + sstore("112233445566778899aabbccddee004f", "112233445566778899aabbccddee004f") + sstore("112233445566778899aabbccddee0050", "112233445566778899aabbccddee0050") + sstore("112233445566778899aabbccddee0051", "112233445566778899aabbccddee0051") + sstore("112233445566778899aabbccddee0052", "112233445566778899aabbccddee0052") + sstore("112233445566778899aabbccddee0053", "112233445566778899aabbccddee0053") + sstore("112233445566778899aabbccddee0054", "112233445566778899aabbccddee0054") + sstore("112233445566778899aabbccddee0055", "112233445566778899aabbccddee0055") + sstore("112233445566778899aabbccddee0056", "112233445566778899aabbccddee0056") + sstore("112233445566778899aabbccddee0057", "112233445566778899aabbccddee0057") + sstore("112233445566778899aabbccddee0058", "112233445566778899aabbccddee0058") + sstore("112233445566778899aabbccddee0059", "112233445566778899aabbccddee0059") + sstore("112233445566778899aabbccddee005a", "112233445566778899aabbccddee005a") + sstore("112233445566778899aabbccddee005b", "112233445566778899aabbccddee005b") + sstore("112233445566778899aabbccddee005c", "112233445566778899aabbccddee005c") + sstore("112233445566778899aabbccddee005d", "112233445566778899aabbccddee005d") + sstore("112233445566778899aabbccddee005e", "112233445566778899aabbccddee005e") + sstore("112233445566778899aabbccddee005f", "112233445566778899aabbccddee005f") + sstore("112233445566778899aabbccddee0060", "112233445566778899aabbccddee0060") + sstore("112233445566778899aabbccddee0061", "112233445566778899aabbccddee0061") + sstore("112233445566778899aabbccddee0062", "112233445566778899aabbccddee0062") + sstore("112233445566778899aabbccddee0063", "112233445566778899aabbccddee0063") + sstore("112233445566778899aabbccddee0064", "112233445566778899aabbccddee0064") + sstore("112233445566778899aabbccddee0065", "112233445566778899aabbccddee0065") + sstore("112233445566778899aabbccddee0066", "112233445566778899aabbccddee0066") + sstore("112233445566778899aabbccddee0067", "112233445566778899aabbccddee0067") + sstore("112233445566778899aabbccddee0068", "112233445566778899aabbccddee0068") + sstore("112233445566778899aabbccddee0069", "112233445566778899aabbccddee0069") + sstore("112233445566778899aabbccddee006a", "112233445566778899aabbccddee006a") + sstore("112233445566778899aabbccddee006b", "112233445566778899aabbccddee006b") + sstore("112233445566778899aabbccddee006c", "112233445566778899aabbccddee006c") + sstore("112233445566778899aabbccddee006d", "112233445566778899aabbccddee006d") + sstore("112233445566778899aabbccddee006e", "112233445566778899aabbccddee006e") + sstore("112233445566778899aabbccddee006f", "112233445566778899aabbccddee006f") + sstore("112233445566778899aabbccddee0070", "112233445566778899aabbccddee0070") + sstore("112233445566778899aabbccddee0071", "112233445566778899aabbccddee0071") + sstore("112233445566778899aabbccddee0072", "112233445566778899aabbccddee0072") + sstore("112233445566778899aabbccddee0073", "112233445566778899aabbccddee0073") + sstore("112233445566778899aabbccddee0074", "112233445566778899aabbccddee0074") + sstore("112233445566778899aabbccddee0075", "112233445566778899aabbccddee0075") + sstore("112233445566778899aabbccddee0076", "112233445566778899aabbccddee0076") + sstore("112233445566778899aabbccddee0077", "112233445566778899aabbccddee0077") + sstore("112233445566778899aabbccddee0078", "112233445566778899aabbccddee0078") + sstore("112233445566778899aabbccddee0079", "112233445566778899aabbccddee0079") + sstore("112233445566778899aabbccddee007a", "112233445566778899aabbccddee007a") + sstore("112233445566778899aabbccddee007b", "112233445566778899aabbccddee007b") + sstore("112233445566778899aabbccddee007c", "112233445566778899aabbccddee007c") + sstore("112233445566778899aabbccddee007d", "112233445566778899aabbccddee007d") + sstore("112233445566778899aabbccddee007e", "112233445566778899aabbccddee007e") + sstore("112233445566778899aabbccddee007f", "112233445566778899aabbccddee007f") + sstore("112233445566778899aabbccddee0080", "112233445566778899aabbccddee0080") + sstore("112233445566778899aabbccddee0081", "112233445566778899aabbccddee0081") + sstore("112233445566778899aabbccddee0082", "112233445566778899aabbccddee0082") + sstore("112233445566778899aabbccddee0083", "112233445566778899aabbccddee0083") + sstore("112233445566778899aabbccddee0084", "112233445566778899aabbccddee0084") + sstore("112233445566778899aabbccddee0085", "112233445566778899aabbccddee0085") + sstore("112233445566778899aabbccddee0086", "112233445566778899aabbccddee0086") + sstore("112233445566778899aabbccddee0087", "112233445566778899aabbccddee0087") + sstore("112233445566778899aabbccddee0088", "112233445566778899aabbccddee0088") + sstore("112233445566778899aabbccddee0089", "112233445566778899aabbccddee0089") + sstore("112233445566778899aabbccddee008a", "112233445566778899aabbccddee008a") + sstore("112233445566778899aabbccddee008b", "112233445566778899aabbccddee008b") + sstore("112233445566778899aabbccddee008c", "112233445566778899aabbccddee008c") + sstore("112233445566778899aabbccddee008d", "112233445566778899aabbccddee008d") + sstore("112233445566778899aabbccddee008e", "112233445566778899aabbccddee008e") + sstore("112233445566778899aabbccddee008f", "112233445566778899aabbccddee008f") + sstore("112233445566778899aabbccddee0090", "112233445566778899aabbccddee0090") + sstore("112233445566778899aabbccddee0091", "112233445566778899aabbccddee0091") + sstore("112233445566778899aabbccddee0092", "112233445566778899aabbccddee0092") + sstore("112233445566778899aabbccddee0093", "112233445566778899aabbccddee0093") + sstore("112233445566778899aabbccddee0094", "112233445566778899aabbccddee0094") + sstore("112233445566778899aabbccddee0095", "112233445566778899aabbccddee0095") + sstore("112233445566778899aabbccddee0096", "112233445566778899aabbccddee0096") + sstore("112233445566778899aabbccddee0097", "112233445566778899aabbccddee0097") + sstore("112233445566778899aabbccddee0098", "112233445566778899aabbccddee0098") + sstore("112233445566778899aabbccddee0099", "112233445566778899aabbccddee0099") + sstore("112233445566778899aabbccddee009a", "112233445566778899aabbccddee009a") + sstore("112233445566778899aabbccddee009b", "112233445566778899aabbccddee009b") + sstore("112233445566778899aabbccddee009c", "112233445566778899aabbccddee009c") + sstore("112233445566778899aabbccddee009d", "112233445566778899aabbccddee009d") + sstore("112233445566778899aabbccddee009e", "112233445566778899aabbccddee009e") + sstore("112233445566778899aabbccddee009f", "112233445566778899aabbccddee009f") + sstore("112233445566778899aabbccddee00a0", "112233445566778899aabbccddee00a0") + sstore("112233445566778899aabbccddee00a1", "112233445566778899aabbccddee00a1") + sstore("112233445566778899aabbccddee00a2", "112233445566778899aabbccddee00a2") + sstore("112233445566778899aabbccddee00a3", "112233445566778899aabbccddee00a3") + sstore("112233445566778899aabbccddee00a4", "112233445566778899aabbccddee00a4") + sstore("112233445566778899aabbccddee00a5", "112233445566778899aabbccddee00a5") + sstore("112233445566778899aabbccddee00a6", "112233445566778899aabbccddee00a6") + sstore("112233445566778899aabbccddee00a7", "112233445566778899aabbccddee00a7") + sstore("112233445566778899aabbccddee00a8", "112233445566778899aabbccddee00a8") + sstore("112233445566778899aabbccddee00a9", "112233445566778899aabbccddee00a9") + sstore("112233445566778899aabbccddee00aa", "112233445566778899aabbccddee00aa") + sstore("112233445566778899aabbccddee00ab", "112233445566778899aabbccddee00ab") + sstore("112233445566778899aabbccddee00ac", "112233445566778899aabbccddee00ac") + sstore("112233445566778899aabbccddee00ad", "112233445566778899aabbccddee00ad") + sstore("112233445566778899aabbccddee00ae", "112233445566778899aabbccddee00ae") + sstore("112233445566778899aabbccddee00af", "112233445566778899aabbccddee00af") + sstore("112233445566778899aabbccddee00b0", "112233445566778899aabbccddee00b0") + sstore("112233445566778899aabbccddee00b1", "112233445566778899aabbccddee00b1") + sstore("112233445566778899aabbccddee00b2", "112233445566778899aabbccddee00b2") + sstore("112233445566778899aabbccddee00b3", "112233445566778899aabbccddee00b3") + sstore("112233445566778899aabbccddee00b4", "112233445566778899aabbccddee00b4") + sstore("112233445566778899aabbccddee00b5", "112233445566778899aabbccddee00b5") + sstore("112233445566778899aabbccddee00b6", "112233445566778899aabbccddee00b6") + sstore("112233445566778899aabbccddee00b7", "112233445566778899aabbccddee00b7") + sstore("112233445566778899aabbccddee00b8", "112233445566778899aabbccddee00b8") + sstore("112233445566778899aabbccddee00b9", "112233445566778899aabbccddee00b9") + sstore("112233445566778899aabbccddee00ba", "112233445566778899aabbccddee00ba") + sstore("112233445566778899aabbccddee00bb", "112233445566778899aabbccddee00bb") + sstore("112233445566778899aabbccddee00bc", "112233445566778899aabbccddee00bc") + sstore("112233445566778899aabbccddee00bd", "112233445566778899aabbccddee00bd") + sstore("112233445566778899aabbccddee00be", "112233445566778899aabbccddee00be") + sstore("112233445566778899aabbccddee00bf", "112233445566778899aabbccddee00bf") + sstore("112233445566778899aabbccddee00c0", "112233445566778899aabbccddee00c0") + sstore("112233445566778899aabbccddee00c1", "112233445566778899aabbccddee00c1") + sstore("112233445566778899aabbccddee00c2", "112233445566778899aabbccddee00c2") + sstore("112233445566778899aabbccddee00c3", "112233445566778899aabbccddee00c3") + sstore("112233445566778899aabbccddee00c4", "112233445566778899aabbccddee00c4") + sstore("112233445566778899aabbccddee00c5", "112233445566778899aabbccddee00c5") + sstore("112233445566778899aabbccddee00c6", "112233445566778899aabbccddee00c6") + sstore("112233445566778899aabbccddee00c7", "112233445566778899aabbccddee00c7") + sstore("112233445566778899aabbccddee00c8", "112233445566778899aabbccddee00c8") + sstore("112233445566778899aabbccddee00c9", "112233445566778899aabbccddee00c9") + sstore("112233445566778899aabbccddee00ca", "112233445566778899aabbccddee00ca") + sstore("112233445566778899aabbccddee00cb", "112233445566778899aabbccddee00cb") + sstore("112233445566778899aabbccddee00cc", "112233445566778899aabbccddee00cc") + sstore("112233445566778899aabbccddee00cd", "112233445566778899aabbccddee00cd") + sstore("112233445566778899aabbccddee00ce", "112233445566778899aabbccddee00ce") + sstore("112233445566778899aabbccddee00cf", "112233445566778899aabbccddee00cf") + sstore("112233445566778899aabbccddee00d0", "112233445566778899aabbccddee00d0") + sstore("112233445566778899aabbccddee00d1", "112233445566778899aabbccddee00d1") + sstore("112233445566778899aabbccddee00d2", "112233445566778899aabbccddee00d2") + sstore("112233445566778899aabbccddee00d3", "112233445566778899aabbccddee00d3") + sstore("112233445566778899aabbccddee00d4", "112233445566778899aabbccddee00d4") + sstore("112233445566778899aabbccddee00d5", "112233445566778899aabbccddee00d5") + sstore("112233445566778899aabbccddee00d6", "112233445566778899aabbccddee00d6") + sstore("112233445566778899aabbccddee00d7", "112233445566778899aabbccddee00d7") + sstore("112233445566778899aabbccddee00d8", "112233445566778899aabbccddee00d8") + sstore("112233445566778899aabbccddee00d9", "112233445566778899aabbccddee00d9") + sstore("112233445566778899aabbccddee00da", "112233445566778899aabbccddee00da") + sstore("112233445566778899aabbccddee00db", "112233445566778899aabbccddee00db") + sstore("112233445566778899aabbccddee00dc", "112233445566778899aabbccddee00dc") + sstore("112233445566778899aabbccddee00dd", "112233445566778899aabbccddee00dd") + sstore("112233445566778899aabbccddee00de", "112233445566778899aabbccddee00de") + sstore("112233445566778899aabbccddee00df", "112233445566778899aabbccddee00df") + sstore("112233445566778899aabbccddee00e0", "112233445566778899aabbccddee00e0") + sstore("112233445566778899aabbccddee00e1", "112233445566778899aabbccddee00e1") + sstore("112233445566778899aabbccddee00e2", "112233445566778899aabbccddee00e2") + sstore("112233445566778899aabbccddee00e3", "112233445566778899aabbccddee00e3") + sstore("112233445566778899aabbccddee00e4", "112233445566778899aabbccddee00e4") + sstore("112233445566778899aabbccddee00e5", "112233445566778899aabbccddee00e5") + sstore("112233445566778899aabbccddee00e6", "112233445566778899aabbccddee00e6") + sstore("112233445566778899aabbccddee00e7", "112233445566778899aabbccddee00e7") + sstore("112233445566778899aabbccddee00e8", "112233445566778899aabbccddee00e8") + sstore("112233445566778899aabbccddee00e9", "112233445566778899aabbccddee00e9") + sstore("112233445566778899aabbccddee00ea", "112233445566778899aabbccddee00ea") + sstore("112233445566778899aabbccddee00eb", "112233445566778899aabbccddee00eb") + sstore("112233445566778899aabbccddee00ec", "112233445566778899aabbccddee00ec") + sstore("112233445566778899aabbccddee00ed", "112233445566778899aabbccddee00ed") + sstore("112233445566778899aabbccddee00ee", "112233445566778899aabbccddee00ee") + sstore("112233445566778899aabbccddee00ef", "112233445566778899aabbccddee00ef") + sstore("112233445566778899aabbccddee00f0", "112233445566778899aabbccddee00f0") + sstore("112233445566778899aabbccddee00f1", "112233445566778899aabbccddee00f1") + sstore("112233445566778899aabbccddee00f2", "112233445566778899aabbccddee00f2") + sstore("112233445566778899aabbccddee00f3", "112233445566778899aabbccddee00f3") + sstore("112233445566778899aabbccddee00f4", "112233445566778899aabbccddee00f4") + sstore("112233445566778899aabbccddee00f5", "112233445566778899aabbccddee00f5") + sstore("112233445566778899aabbccddee00f6", "112233445566778899aabbccddee00f6") + sstore("112233445566778899aabbccddee00f7", "112233445566778899aabbccddee00f7") + sstore("112233445566778899aabbccddee00f8", "112233445566778899aabbccddee00f8") + sstore("112233445566778899aabbccddee00f9", "112233445566778899aabbccddee00f9") + sstore("112233445566778899aabbccddee00fa", "112233445566778899aabbccddee00fa") + sstore("112233445566778899aabbccddee00fb", "112233445566778899aabbccddee00fb") + sstore("112233445566778899aabbccddee00fc", "112233445566778899aabbccddee00fc") + sstore("112233445566778899aabbccddee00fd", "112233445566778899aabbccddee00fd") + sstore("112233445566778899aabbccddee00fe", "112233445566778899aabbccddee00fe") + sstore("112233445566778899aabbccddee00ff", "112233445566778899aabbccddee00ff") + sstore("112233445566778899aabbccddee0100", "112233445566778899aabbccddee0100") + sstore("112233445566778899aabbccddee0101", "112233445566778899aabbccddee0101") + sstore("112233445566778899aabbccddee0102", "112233445566778899aabbccddee0102") + sstore("112233445566778899aabbccddee0103", "112233445566778899aabbccddee0103") + sstore("112233445566778899aabbccddee0104", "112233445566778899aabbccddee0104") + sstore("112233445566778899aabbccddee0105", "112233445566778899aabbccddee0105") + sstore("112233445566778899aabbccddee0106", "112233445566778899aabbccddee0106") + sstore("112233445566778899aabbccddee0107", "112233445566778899aabbccddee0107") + sstore("112233445566778899aabbccddee0108", "112233445566778899aabbccddee0108") + sstore("112233445566778899aabbccddee0109", "112233445566778899aabbccddee0109") + sstore("112233445566778899aabbccddee010a", "112233445566778899aabbccddee010a") + sstore("112233445566778899aabbccddee010b", "112233445566778899aabbccddee010b") + sstore("112233445566778899aabbccddee010c", "112233445566778899aabbccddee010c") + sstore("112233445566778899aabbccddee010d", "112233445566778899aabbccddee010d") + sstore("112233445566778899aabbccddee010e", "112233445566778899aabbccddee010e") + sstore("112233445566778899aabbccddee010f", "112233445566778899aabbccddee010f") + sstore("112233445566778899aabbccddee0110", "112233445566778899aabbccddee0110") + sstore("112233445566778899aabbccddee0111", "112233445566778899aabbccddee0111") + sstore("112233445566778899aabbccddee0112", "112233445566778899aabbccddee0112") + sstore("112233445566778899aabbccddee0113", "112233445566778899aabbccddee0113") + sstore("112233445566778899aabbccddee0114", "112233445566778899aabbccddee0114") + sstore("112233445566778899aabbccddee0115", "112233445566778899aabbccddee0115") + sstore("112233445566778899aabbccddee0116", "112233445566778899aabbccddee0116") + sstore("112233445566778899aabbccddee0117", "112233445566778899aabbccddee0117") + sstore("112233445566778899aabbccddee0118", "112233445566778899aabbccddee0118") + sstore("112233445566778899aabbccddee0119", "112233445566778899aabbccddee0119") + sstore("112233445566778899aabbccddee011a", "112233445566778899aabbccddee011a") + sstore("112233445566778899aabbccddee011b", "112233445566778899aabbccddee011b") + sstore("112233445566778899aabbccddee011c", "112233445566778899aabbccddee011c") + sstore("112233445566778899aabbccddee011d", "112233445566778899aabbccddee011d") + sstore("112233445566778899aabbccddee011e", "112233445566778899aabbccddee011e") + sstore("112233445566778899aabbccddee011f", "112233445566778899aabbccddee011f") + sstore("112233445566778899aabbccddee0120", "112233445566778899aabbccddee0120") + sstore("112233445566778899aabbccddee0121", "112233445566778899aabbccddee0121") + sstore("112233445566778899aabbccddee0122", "112233445566778899aabbccddee0122") + sstore("112233445566778899aabbccddee0123", "112233445566778899aabbccddee0123") + sstore("112233445566778899aabbccddee0124", "112233445566778899aabbccddee0124") + sstore("112233445566778899aabbccddee0125", "112233445566778899aabbccddee0125") + sstore("112233445566778899aabbccddee0126", "112233445566778899aabbccddee0126") + sstore("112233445566778899aabbccddee0127", "112233445566778899aabbccddee0127") + sstore("112233445566778899aabbccddee0128", "112233445566778899aabbccddee0128") + sstore("112233445566778899aabbccddee0129", "112233445566778899aabbccddee0129") + sstore("112233445566778899aabbccddee012a", "112233445566778899aabbccddee012a") + sstore("112233445566778899aabbccddee012b", "112233445566778899aabbccddee012b") + sstore("112233445566778899aabbccddee012c", "112233445566778899aabbccddee012c") + sstore("112233445566778899aabbccddee012d", "112233445566778899aabbccddee012d") + sstore("112233445566778899aabbccddee012e", "112233445566778899aabbccddee012e") + sstore("112233445566778899aabbccddee012f", "112233445566778899aabbccddee012f") + sstore("112233445566778899aabbccddee0130", "112233445566778899aabbccddee0130") + sstore("112233445566778899aabbccddee0131", "112233445566778899aabbccddee0131") + sstore("112233445566778899aabbccddee0132", "112233445566778899aabbccddee0132") + sstore("112233445566778899aabbccddee0133", "112233445566778899aabbccddee0133") + sstore("112233445566778899aabbccddee0134", "112233445566778899aabbccddee0134") + sstore("112233445566778899aabbccddee0135", "112233445566778899aabbccddee0135") + sstore("112233445566778899aabbccddee0136", "112233445566778899aabbccddee0136") + sstore("112233445566778899aabbccddee0137", "112233445566778899aabbccddee0137") + sstore("112233445566778899aabbccddee0138", "112233445566778899aabbccddee0138") + sstore("112233445566778899aabbccddee0139", "112233445566778899aabbccddee0139") + sstore("112233445566778899aabbccddee013a", "112233445566778899aabbccddee013a") + sstore("112233445566778899aabbccddee013b", "112233445566778899aabbccddee013b") + sstore("112233445566778899aabbccddee013c", "112233445566778899aabbccddee013c") + sstore("112233445566778899aabbccddee013d", "112233445566778899aabbccddee013d") + sstore("112233445566778899aabbccddee013e", "112233445566778899aabbccddee013e") + sstore("112233445566778899aabbccddee013f", "112233445566778899aabbccddee013f") + sstore("112233445566778899aabbccddee0140", "112233445566778899aabbccddee0140") + sstore("112233445566778899aabbccddee0141", "112233445566778899aabbccddee0141") + sstore("112233445566778899aabbccddee0142", "112233445566778899aabbccddee0142") + sstore("112233445566778899aabbccddee0143", "112233445566778899aabbccddee0143") + sstore("112233445566778899aabbccddee0144", "112233445566778899aabbccddee0144") + sstore("112233445566778899aabbccddee0145", "112233445566778899aabbccddee0145") + sstore("112233445566778899aabbccddee0146", "112233445566778899aabbccddee0146") + sstore("112233445566778899aabbccddee0147", "112233445566778899aabbccddee0147") + sstore("112233445566778899aabbccddee0148", "112233445566778899aabbccddee0148") + sstore("112233445566778899aabbccddee0149", "112233445566778899aabbccddee0149") + sstore("112233445566778899aabbccddee014a", "112233445566778899aabbccddee014a") + sstore("112233445566778899aabbccddee014b", "112233445566778899aabbccddee014b") + sstore("112233445566778899aabbccddee014c", "112233445566778899aabbccddee014c") + sstore("112233445566778899aabbccddee014d", "112233445566778899aabbccddee014d") + sstore("112233445566778899aabbccddee014e", "112233445566778899aabbccddee014e") + sstore("112233445566778899aabbccddee014f", "112233445566778899aabbccddee014f") + sstore("112233445566778899aabbccddee0150", "112233445566778899aabbccddee0150") + sstore("112233445566778899aabbccddee0151", "112233445566778899aabbccddee0151") + sstore("112233445566778899aabbccddee0152", "112233445566778899aabbccddee0152") + sstore("112233445566778899aabbccddee0153", "112233445566778899aabbccddee0153") + sstore("112233445566778899aabbccddee0154", "112233445566778899aabbccddee0154") + sstore("112233445566778899aabbccddee0155", "112233445566778899aabbccddee0155") + sstore("112233445566778899aabbccddee0156", "112233445566778899aabbccddee0156") + sstore("112233445566778899aabbccddee0157", "112233445566778899aabbccddee0157") + sstore("112233445566778899aabbccddee0158", "112233445566778899aabbccddee0158") + sstore("112233445566778899aabbccddee0159", "112233445566778899aabbccddee0159") + sstore("112233445566778899aabbccddee015a", "112233445566778899aabbccddee015a") + sstore("112233445566778899aabbccddee015b", "112233445566778899aabbccddee015b") + sstore("112233445566778899aabbccddee015c", "112233445566778899aabbccddee015c") + sstore("112233445566778899aabbccddee015d", "112233445566778899aabbccddee015d") + sstore("112233445566778899aabbccddee015e", "112233445566778899aabbccddee015e") + sstore("112233445566778899aabbccddee015f", "112233445566778899aabbccddee015f") + sstore("112233445566778899aabbccddee0160", "112233445566778899aabbccddee0160") + sstore("112233445566778899aabbccddee0161", "112233445566778899aabbccddee0161") + sstore("112233445566778899aabbccddee0162", "112233445566778899aabbccddee0162") + sstore("112233445566778899aabbccddee0163", "112233445566778899aabbccddee0163") + sstore("112233445566778899aabbccddee0164", "112233445566778899aabbccddee0164") + sstore("112233445566778899aabbccddee0165", "112233445566778899aabbccddee0165") + sstore("112233445566778899aabbccddee0166", "112233445566778899aabbccddee0166") + sstore("112233445566778899aabbccddee0167", "112233445566778899aabbccddee0167") + sstore("112233445566778899aabbccddee0168", "112233445566778899aabbccddee0168") + sstore("112233445566778899aabbccddee0169", "112233445566778899aabbccddee0169") + sstore("112233445566778899aabbccddee016a", "112233445566778899aabbccddee016a") + sstore("112233445566778899aabbccddee016b", "112233445566778899aabbccddee016b") + sstore("112233445566778899aabbccddee016c", "112233445566778899aabbccddee016c") + sstore("112233445566778899aabbccddee016d", "112233445566778899aabbccddee016d") + sstore("112233445566778899aabbccddee016e", "112233445566778899aabbccddee016e") + sstore("112233445566778899aabbccddee016f", "112233445566778899aabbccddee016f") + sstore("112233445566778899aabbccddee0170", "112233445566778899aabbccddee0170") + sstore("112233445566778899aabbccddee0171", "112233445566778899aabbccddee0171") + sstore("112233445566778899aabbccddee0172", "112233445566778899aabbccddee0172") + sstore("112233445566778899aabbccddee0173", "112233445566778899aabbccddee0173") + sstore("112233445566778899aabbccddee0174", "112233445566778899aabbccddee0174") + sstore("112233445566778899aabbccddee0175", "112233445566778899aabbccddee0175") + sstore("112233445566778899aabbccddee0176", "112233445566778899aabbccddee0176") + sstore("112233445566778899aabbccddee0177", "112233445566778899aabbccddee0177") + sstore("112233445566778899aabbccddee0178", "112233445566778899aabbccddee0178") + sstore("112233445566778899aabbccddee0179", "112233445566778899aabbccddee0179") + sstore("112233445566778899aabbccddee017a", "112233445566778899aabbccddee017a") + sstore("112233445566778899aabbccddee017b", "112233445566778899aabbccddee017b") + sstore("112233445566778899aabbccddee017c", "112233445566778899aabbccddee017c") + sstore("112233445566778899aabbccddee017d", "112233445566778899aabbccddee017d") + sstore("112233445566778899aabbccddee017e", "112233445566778899aabbccddee017e") + sstore("112233445566778899aabbccddee017f", "112233445566778899aabbccddee017f") + sstore("112233445566778899aabbccddee0180", "112233445566778899aabbccddee0180") + sstore("112233445566778899aabbccddee0181", "112233445566778899aabbccddee0181") + sstore("112233445566778899aabbccddee0182", "112233445566778899aabbccddee0182") + sstore("112233445566778899aabbccddee0183", "112233445566778899aabbccddee0183") + sstore("112233445566778899aabbccddee0184", "112233445566778899aabbccddee0184") + sstore("112233445566778899aabbccddee0185", "112233445566778899aabbccddee0185") + sstore("112233445566778899aabbccddee0186", "112233445566778899aabbccddee0186") + sstore("112233445566778899aabbccddee0187", "112233445566778899aabbccddee0187") + sstore("112233445566778899aabbccddee0188", "112233445566778899aabbccddee0188") + sstore("112233445566778899aabbccddee0189", "112233445566778899aabbccddee0189") + sstore("112233445566778899aabbccddee018a", "112233445566778899aabbccddee018a") + sstore("112233445566778899aabbccddee018b", "112233445566778899aabbccddee018b") + sstore("112233445566778899aabbccddee018c", "112233445566778899aabbccddee018c") + sstore("112233445566778899aabbccddee018d", "112233445566778899aabbccddee018d") + sstore("112233445566778899aabbccddee018e", "112233445566778899aabbccddee018e") + sstore("112233445566778899aabbccddee018f", "112233445566778899aabbccddee018f") + sstore("112233445566778899aabbccddee0190", "112233445566778899aabbccddee0190") + sstore("112233445566778899aabbccddee0191", "112233445566778899aabbccddee0191") + sstore("112233445566778899aabbccddee0192", "112233445566778899aabbccddee0192") + sstore("112233445566778899aabbccddee0193", "112233445566778899aabbccddee0193") + sstore("112233445566778899aabbccddee0194", "112233445566778899aabbccddee0194") + sstore("112233445566778899aabbccddee0195", "112233445566778899aabbccddee0195") + sstore("112233445566778899aabbccddee0196", "112233445566778899aabbccddee0196") + sstore("112233445566778899aabbccddee0197", "112233445566778899aabbccddee0197") + sstore("112233445566778899aabbccddee0198", "112233445566778899aabbccddee0198") + sstore("112233445566778899aabbccddee0199", "112233445566778899aabbccddee0199") + sstore("112233445566778899aabbccddee019a", "112233445566778899aabbccddee019a") + sstore("112233445566778899aabbccddee019b", "112233445566778899aabbccddee019b") + sstore("112233445566778899aabbccddee019c", "112233445566778899aabbccddee019c") + sstore("112233445566778899aabbccddee019d", "112233445566778899aabbccddee019d") + sstore("112233445566778899aabbccddee019e", "112233445566778899aabbccddee019e") + sstore("112233445566778899aabbccddee019f", "112233445566778899aabbccddee019f") + sstore("112233445566778899aabbccddee01a0", "112233445566778899aabbccddee01a0") + sstore("112233445566778899aabbccddee01a1", "112233445566778899aabbccddee01a1") + sstore("112233445566778899aabbccddee01a2", "112233445566778899aabbccddee01a2") + sstore("112233445566778899aabbccddee01a3", "112233445566778899aabbccddee01a3") + sstore("112233445566778899aabbccddee01a4", "112233445566778899aabbccddee01a4") + sstore("112233445566778899aabbccddee01a5", "112233445566778899aabbccddee01a5") + sstore("112233445566778899aabbccddee01a6", "112233445566778899aabbccddee01a6") + sstore("112233445566778899aabbccddee01a7", "112233445566778899aabbccddee01a7") + sstore("112233445566778899aabbccddee01a8", "112233445566778899aabbccddee01a8") + sstore("112233445566778899aabbccddee01a9", "112233445566778899aabbccddee01a9") + sstore("112233445566778899aabbccddee01aa", "112233445566778899aabbccddee01aa") + sstore("112233445566778899aabbccddee01ab", "112233445566778899aabbccddee01ab") + sstore("112233445566778899aabbccddee01ac", "112233445566778899aabbccddee01ac") + sstore("112233445566778899aabbccddee01ad", "112233445566778899aabbccddee01ad") + sstore("112233445566778899aabbccddee01ae", "112233445566778899aabbccddee01ae") + sstore("112233445566778899aabbccddee01af", "112233445566778899aabbccddee01af") + sstore("112233445566778899aabbccddee01b0", "112233445566778899aabbccddee01b0") + sstore("112233445566778899aabbccddee01b1", "112233445566778899aabbccddee01b1") + sstore("112233445566778899aabbccddee01b2", "112233445566778899aabbccddee01b2") + sstore("112233445566778899aabbccddee01b3", "112233445566778899aabbccddee01b3") + sstore("112233445566778899aabbccddee01b4", "112233445566778899aabbccddee01b4") + sstore("112233445566778899aabbccddee01b5", "112233445566778899aabbccddee01b5") + sstore("112233445566778899aabbccddee01b6", "112233445566778899aabbccddee01b6") + sstore("112233445566778899aabbccddee01b7", "112233445566778899aabbccddee01b7") + sstore("112233445566778899aabbccddee01b8", "112233445566778899aabbccddee01b8") + sstore("112233445566778899aabbccddee01b9", "112233445566778899aabbccddee01b9") + sstore("112233445566778899aabbccddee01ba", "112233445566778899aabbccddee01ba") + sstore("112233445566778899aabbccddee01bb", "112233445566778899aabbccddee01bb") + sstore("112233445566778899aabbccddee01bc", "112233445566778899aabbccddee01bc") + sstore("112233445566778899aabbccddee01bd", "112233445566778899aabbccddee01bd") + sstore("112233445566778899aabbccddee01be", "112233445566778899aabbccddee01be") + sstore("112233445566778899aabbccddee01bf", "112233445566778899aabbccddee01bf") + sstore("112233445566778899aabbccddee01c0", "112233445566778899aabbccddee01c0") + sstore("112233445566778899aabbccddee01c1", "112233445566778899aabbccddee01c1") + sstore("112233445566778899aabbccddee01c2", "112233445566778899aabbccddee01c2") + sstore("112233445566778899aabbccddee01c3", "112233445566778899aabbccddee01c3") + sstore("112233445566778899aabbccddee01c4", "112233445566778899aabbccddee01c4") + sstore("112233445566778899aabbccddee01c5", "112233445566778899aabbccddee01c5") + sstore("112233445566778899aabbccddee01c6", "112233445566778899aabbccddee01c6") + sstore("112233445566778899aabbccddee01c7", "112233445566778899aabbccddee01c7") + sstore("112233445566778899aabbccddee01c8", "112233445566778899aabbccddee01c8") + sstore("112233445566778899aabbccddee01c9", "112233445566778899aabbccddee01c9") + sstore("112233445566778899aabbccddee01ca", "112233445566778899aabbccddee01ca") + sstore("112233445566778899aabbccddee01cb", "112233445566778899aabbccddee01cb") + sstore("112233445566778899aabbccddee01cc", "112233445566778899aabbccddee01cc") + sstore("112233445566778899aabbccddee01cd", "112233445566778899aabbccddee01cd") + sstore("112233445566778899aabbccddee01ce", "112233445566778899aabbccddee01ce") + sstore("112233445566778899aabbccddee01cf", "112233445566778899aabbccddee01cf") + sstore("112233445566778899aabbccddee01d0", "112233445566778899aabbccddee01d0") + sstore("112233445566778899aabbccddee01d1", "112233445566778899aabbccddee01d1") + sstore("112233445566778899aabbccddee01d2", "112233445566778899aabbccddee01d2") + sstore("112233445566778899aabbccddee01d3", "112233445566778899aabbccddee01d3") + sstore("112233445566778899aabbccddee01d4", "112233445566778899aabbccddee01d4") + sstore("112233445566778899aabbccddee01d5", "112233445566778899aabbccddee01d5") + sstore("112233445566778899aabbccddee01d6", "112233445566778899aabbccddee01d6") + sstore("112233445566778899aabbccddee01d7", "112233445566778899aabbccddee01d7") + sstore("112233445566778899aabbccddee01d8", "112233445566778899aabbccddee01d8") + sstore("112233445566778899aabbccddee01d9", "112233445566778899aabbccddee01d9") + sstore("112233445566778899aabbccddee01da", "112233445566778899aabbccddee01da") + sstore("112233445566778899aabbccddee01db", "112233445566778899aabbccddee01db") + sstore("112233445566778899aabbccddee01dc", "112233445566778899aabbccddee01dc") + sstore("112233445566778899aabbccddee01dd", "112233445566778899aabbccddee01dd") + sstore("112233445566778899aabbccddee01de", "112233445566778899aabbccddee01de") + sstore("112233445566778899aabbccddee01df", "112233445566778899aabbccddee01df") + sstore("112233445566778899aabbccddee01e0", "112233445566778899aabbccddee01e0") + sstore("112233445566778899aabbccddee01e1", "112233445566778899aabbccddee01e1") + sstore("112233445566778899aabbccddee01e2", "112233445566778899aabbccddee01e2") + sstore("112233445566778899aabbccddee01e3", "112233445566778899aabbccddee01e3") + sstore("112233445566778899aabbccddee01e4", "112233445566778899aabbccddee01e4") + sstore("112233445566778899aabbccddee01e5", "112233445566778899aabbccddee01e5") + sstore("112233445566778899aabbccddee01e6", "112233445566778899aabbccddee01e6") + sstore("112233445566778899aabbccddee01e7", "112233445566778899aabbccddee01e7") + sstore("112233445566778899aabbccddee01e8", "112233445566778899aabbccddee01e8") + sstore("112233445566778899aabbccddee01e9", "112233445566778899aabbccddee01e9") + sstore("112233445566778899aabbccddee01ea", "112233445566778899aabbccddee01ea") + sstore("112233445566778899aabbccddee01eb", "112233445566778899aabbccddee01eb") + sstore("112233445566778899aabbccddee01ec", "112233445566778899aabbccddee01ec") + sstore("112233445566778899aabbccddee01ed", "112233445566778899aabbccddee01ed") + sstore("112233445566778899aabbccddee01ee", "112233445566778899aabbccddee01ee") + sstore("112233445566778899aabbccddee01ef", "112233445566778899aabbccddee01ef") + sstore("112233445566778899aabbccddee01f0", "112233445566778899aabbccddee01f0") + sstore("112233445566778899aabbccddee01f1", "112233445566778899aabbccddee01f1") + sstore("112233445566778899aabbccddee01f2", "112233445566778899aabbccddee01f2") + sstore("112233445566778899aabbccddee01f3", "112233445566778899aabbccddee01f3") + sstore("112233445566778899aabbccddee01f4", "112233445566778899aabbccddee01f4") + sstore("112233445566778899aabbccddee01f5", "112233445566778899aabbccddee01f5") + sstore("112233445566778899aabbccddee01f6", "112233445566778899aabbccddee01f6") + sstore("112233445566778899aabbccddee01f7", "112233445566778899aabbccddee01f7") + sstore("112233445566778899aabbccddee01f8", "112233445566778899aabbccddee01f8") + sstore("112233445566778899aabbccddee01f9", "112233445566778899aabbccddee01f9") + sstore("112233445566778899aabbccddee01fa", "112233445566778899aabbccddee01fa") + sstore("112233445566778899aabbccddee01fb", "112233445566778899aabbccddee01fb") + sstore("112233445566778899aabbccddee01fc", "112233445566778899aabbccddee01fc") + sstore("112233445566778899aabbccddee01fd", "112233445566778899aabbccddee01fd") + sstore("112233445566778899aabbccddee01fe", "112233445566778899aabbccddee01fe") + sstore("112233445566778899aabbccddee01ff", "112233445566778899aabbccddee01ff") + sstore("112233445566778899aabbccddee0200", "112233445566778899aabbccddee0200") + sstore("112233445566778899aabbccddee0201", "112233445566778899aabbccddee0201") + sstore("112233445566778899aabbccddee0202", "112233445566778899aabbccddee0202") + sstore("112233445566778899aabbccddee0203", "112233445566778899aabbccddee0203") + sstore("112233445566778899aabbccddee0204", "112233445566778899aabbccddee0204") + sstore("112233445566778899aabbccddee0205", "112233445566778899aabbccddee0205") + sstore("112233445566778899aabbccddee0206", "112233445566778899aabbccddee0206") + sstore("112233445566778899aabbccddee0207", "112233445566778899aabbccddee0207") + sstore("112233445566778899aabbccddee0208", "112233445566778899aabbccddee0208") + sstore("112233445566778899aabbccddee0209", "112233445566778899aabbccddee0209") + sstore("112233445566778899aabbccddee020a", "112233445566778899aabbccddee020a") + sstore("112233445566778899aabbccddee020b", "112233445566778899aabbccddee020b") + sstore("112233445566778899aabbccddee020c", "112233445566778899aabbccddee020c") + sstore("112233445566778899aabbccddee020d", "112233445566778899aabbccddee020d") + sstore("112233445566778899aabbccddee020e", "112233445566778899aabbccddee020e") + sstore("112233445566778899aabbccddee020f", "112233445566778899aabbccddee020f") + sstore("112233445566778899aabbccddee0210", "112233445566778899aabbccddee0210") + sstore("112233445566778899aabbccddee0211", "112233445566778899aabbccddee0211") + sstore("112233445566778899aabbccddee0212", "112233445566778899aabbccddee0212") + sstore("112233445566778899aabbccddee0213", "112233445566778899aabbccddee0213") + sstore("112233445566778899aabbccddee0214", "112233445566778899aabbccddee0214") + sstore("112233445566778899aabbccddee0215", "112233445566778899aabbccddee0215") + sstore("112233445566778899aabbccddee0216", "112233445566778899aabbccddee0216") + sstore("112233445566778899aabbccddee0217", "112233445566778899aabbccddee0217") + sstore("112233445566778899aabbccddee0218", "112233445566778899aabbccddee0218") + sstore("112233445566778899aabbccddee0219", "112233445566778899aabbccddee0219") + sstore("112233445566778899aabbccddee021a", "112233445566778899aabbccddee021a") + sstore("112233445566778899aabbccddee021b", "112233445566778899aabbccddee021b") + sstore("112233445566778899aabbccddee021c", "112233445566778899aabbccddee021c") + sstore("112233445566778899aabbccddee021d", "112233445566778899aabbccddee021d") + sstore("112233445566778899aabbccddee021e", "112233445566778899aabbccddee021e") + sstore("112233445566778899aabbccddee021f", "112233445566778899aabbccddee021f") + sstore("112233445566778899aabbccddee0220", "112233445566778899aabbccddee0220") + sstore("112233445566778899aabbccddee0221", "112233445566778899aabbccddee0221") + sstore("112233445566778899aabbccddee0222", "112233445566778899aabbccddee0222") + sstore("112233445566778899aabbccddee0223", "112233445566778899aabbccddee0223") + sstore("112233445566778899aabbccddee0224", "112233445566778899aabbccddee0224") + sstore("112233445566778899aabbccddee0225", "112233445566778899aabbccddee0225") + sstore("112233445566778899aabbccddee0226", "112233445566778899aabbccddee0226") + sstore("112233445566778899aabbccddee0227", "112233445566778899aabbccddee0227") + sstore("112233445566778899aabbccddee0228", "112233445566778899aabbccddee0228") + sstore("112233445566778899aabbccddee0229", "112233445566778899aabbccddee0229") + sstore("112233445566778899aabbccddee022a", "112233445566778899aabbccddee022a") + sstore("112233445566778899aabbccddee022b", "112233445566778899aabbccddee022b") + sstore("112233445566778899aabbccddee022c", "112233445566778899aabbccddee022c") + sstore("112233445566778899aabbccddee022d", "112233445566778899aabbccddee022d") + sstore("112233445566778899aabbccddee022e", "112233445566778899aabbccddee022e") + sstore("112233445566778899aabbccddee022f", "112233445566778899aabbccddee022f") + sstore("112233445566778899aabbccddee0230", "112233445566778899aabbccddee0230") + sstore("112233445566778899aabbccddee0231", "112233445566778899aabbccddee0231") + sstore("112233445566778899aabbccddee0232", "112233445566778899aabbccddee0232") + sstore("112233445566778899aabbccddee0233", "112233445566778899aabbccddee0233") + sstore("112233445566778899aabbccddee0234", "112233445566778899aabbccddee0234") + sstore("112233445566778899aabbccddee0235", "112233445566778899aabbccddee0235") + sstore("112233445566778899aabbccddee0236", "112233445566778899aabbccddee0236") + sstore("112233445566778899aabbccddee0237", "112233445566778899aabbccddee0237") + sstore("112233445566778899aabbccddee0238", "112233445566778899aabbccddee0238") + sstore("112233445566778899aabbccddee0239", "112233445566778899aabbccddee0239") + sstore("112233445566778899aabbccddee023a", "112233445566778899aabbccddee023a") + sstore("112233445566778899aabbccddee023b", "112233445566778899aabbccddee023b") + sstore("112233445566778899aabbccddee023c", "112233445566778899aabbccddee023c") + sstore("112233445566778899aabbccddee023d", "112233445566778899aabbccddee023d") + sstore("112233445566778899aabbccddee023e", "112233445566778899aabbccddee023e") + sstore("112233445566778899aabbccddee023f", "112233445566778899aabbccddee023f") + sstore("112233445566778899aabbccddee0240", "112233445566778899aabbccddee0240") + sstore("112233445566778899aabbccddee0241", "112233445566778899aabbccddee0241") + sstore("112233445566778899aabbccddee0242", "112233445566778899aabbccddee0242") + sstore("112233445566778899aabbccddee0243", "112233445566778899aabbccddee0243") + sstore("112233445566778899aabbccddee0244", "112233445566778899aabbccddee0244") + sstore("112233445566778899aabbccddee0245", "112233445566778899aabbccddee0245") + sstore("112233445566778899aabbccddee0246", "112233445566778899aabbccddee0246") + sstore("112233445566778899aabbccddee0247", "112233445566778899aabbccddee0247") + sstore("112233445566778899aabbccddee0248", "112233445566778899aabbccddee0248") + sstore("112233445566778899aabbccddee0249", "112233445566778899aabbccddee0249") + sstore("112233445566778899aabbccddee024a", "112233445566778899aabbccddee024a") + sstore("112233445566778899aabbccddee024b", "112233445566778899aabbccddee024b") + sstore("112233445566778899aabbccddee024c", "112233445566778899aabbccddee024c") + sstore("112233445566778899aabbccddee024d", "112233445566778899aabbccddee024d") + sstore("112233445566778899aabbccddee024e", "112233445566778899aabbccddee024e") + sstore("112233445566778899aabbccddee024f", "112233445566778899aabbccddee024f") + sstore("112233445566778899aabbccddee0250", "112233445566778899aabbccddee0250") + sstore("112233445566778899aabbccddee0251", "112233445566778899aabbccddee0251") + sstore("112233445566778899aabbccddee0252", "112233445566778899aabbccddee0252") + sstore("112233445566778899aabbccddee0253", "112233445566778899aabbccddee0253") + sstore("112233445566778899aabbccddee0254", "112233445566778899aabbccddee0254") + sstore("112233445566778899aabbccddee0255", "112233445566778899aabbccddee0255") + sstore("112233445566778899aabbccddee0256", "112233445566778899aabbccddee0256") + sstore("112233445566778899aabbccddee0257", "112233445566778899aabbccddee0257") + sstore("112233445566778899aabbccddee0258", "112233445566778899aabbccddee0258") + sstore("112233445566778899aabbccddee0259", "112233445566778899aabbccddee0259") + sstore("112233445566778899aabbccddee025a", "112233445566778899aabbccddee025a") + sstore("112233445566778899aabbccddee025b", "112233445566778899aabbccddee025b") + sstore("112233445566778899aabbccddee025c", "112233445566778899aabbccddee025c") + sstore("112233445566778899aabbccddee025d", "112233445566778899aabbccddee025d") + sstore("112233445566778899aabbccddee025e", "112233445566778899aabbccddee025e") + sstore("112233445566778899aabbccddee025f", "112233445566778899aabbccddee025f") + sstore("112233445566778899aabbccddee0260", "112233445566778899aabbccddee0260") + sstore("112233445566778899aabbccddee0261", "112233445566778899aabbccddee0261") + sstore("112233445566778899aabbccddee0262", "112233445566778899aabbccddee0262") + sstore("112233445566778899aabbccddee0263", "112233445566778899aabbccddee0263") + sstore("112233445566778899aabbccddee0264", "112233445566778899aabbccddee0264") + sstore("112233445566778899aabbccddee0265", "112233445566778899aabbccddee0265") + sstore("112233445566778899aabbccddee0266", "112233445566778899aabbccddee0266") + sstore("112233445566778899aabbccddee0267", "112233445566778899aabbccddee0267") + sstore("112233445566778899aabbccddee0268", "112233445566778899aabbccddee0268") + sstore("112233445566778899aabbccddee0269", "112233445566778899aabbccddee0269") + sstore("112233445566778899aabbccddee026a", "112233445566778899aabbccddee026a") + sstore("112233445566778899aabbccddee026b", "112233445566778899aabbccddee026b") + sstore("112233445566778899aabbccddee026c", "112233445566778899aabbccddee026c") + sstore("112233445566778899aabbccddee026d", "112233445566778899aabbccddee026d") + sstore("112233445566778899aabbccddee026e", "112233445566778899aabbccddee026e") + sstore("112233445566778899aabbccddee026f", "112233445566778899aabbccddee026f") + sstore("112233445566778899aabbccddee0270", "112233445566778899aabbccddee0270") + sstore("112233445566778899aabbccddee0271", "112233445566778899aabbccddee0271") + sstore("112233445566778899aabbccddee0272", "112233445566778899aabbccddee0272") + sstore("112233445566778899aabbccddee0273", "112233445566778899aabbccddee0273") + sstore("112233445566778899aabbccddee0274", "112233445566778899aabbccddee0274") + sstore("112233445566778899aabbccddee0275", "112233445566778899aabbccddee0275") + sstore("112233445566778899aabbccddee0276", "112233445566778899aabbccddee0276") + sstore("112233445566778899aabbccddee0277", "112233445566778899aabbccddee0277") + sstore("112233445566778899aabbccddee0278", "112233445566778899aabbccddee0278") + sstore("112233445566778899aabbccddee0279", "112233445566778899aabbccddee0279") + sstore("112233445566778899aabbccddee027a", "112233445566778899aabbccddee027a") + sstore("112233445566778899aabbccddee027b", "112233445566778899aabbccddee027b") + sstore("112233445566778899aabbccddee027c", "112233445566778899aabbccddee027c") + sstore("112233445566778899aabbccddee027d", "112233445566778899aabbccddee027d") + sstore("112233445566778899aabbccddee027e", "112233445566778899aabbccddee027e") + sstore("112233445566778899aabbccddee027f", "112233445566778899aabbccddee027f") + sstore("112233445566778899aabbccddee0280", "112233445566778899aabbccddee0280") + sstore("112233445566778899aabbccddee0281", "112233445566778899aabbccddee0281") + sstore("112233445566778899aabbccddee0282", "112233445566778899aabbccddee0282") + sstore("112233445566778899aabbccddee0283", "112233445566778899aabbccddee0283") + sstore("112233445566778899aabbccddee0284", "112233445566778899aabbccddee0284") + sstore("112233445566778899aabbccddee0285", "112233445566778899aabbccddee0285") + sstore("112233445566778899aabbccddee0286", "112233445566778899aabbccddee0286") + sstore("112233445566778899aabbccddee0287", "112233445566778899aabbccddee0287") + sstore("112233445566778899aabbccddee0288", "112233445566778899aabbccddee0288") + sstore("112233445566778899aabbccddee0289", "112233445566778899aabbccddee0289") + sstore("112233445566778899aabbccddee028a", "112233445566778899aabbccddee028a") + sstore("112233445566778899aabbccddee028b", "112233445566778899aabbccddee028b") + sstore("112233445566778899aabbccddee028c", "112233445566778899aabbccddee028c") + sstore("112233445566778899aabbccddee028d", "112233445566778899aabbccddee028d") + sstore("112233445566778899aabbccddee028e", "112233445566778899aabbccddee028e") + sstore("112233445566778899aabbccddee028f", "112233445566778899aabbccddee028f") + sstore("112233445566778899aabbccddee0290", "112233445566778899aabbccddee0290") + sstore("112233445566778899aabbccddee0291", "112233445566778899aabbccddee0291") + sstore("112233445566778899aabbccddee0292", "112233445566778899aabbccddee0292") + sstore("112233445566778899aabbccddee0293", "112233445566778899aabbccddee0293") + sstore("112233445566778899aabbccddee0294", "112233445566778899aabbccddee0294") + sstore("112233445566778899aabbccddee0295", "112233445566778899aabbccddee0295") + sstore("112233445566778899aabbccddee0296", "112233445566778899aabbccddee0296") + sstore("112233445566778899aabbccddee0297", "112233445566778899aabbccddee0297") + sstore("112233445566778899aabbccddee0298", "112233445566778899aabbccddee0298") + sstore("112233445566778899aabbccddee0299", "112233445566778899aabbccddee0299") + sstore("112233445566778899aabbccddee029a", "112233445566778899aabbccddee029a") + sstore("112233445566778899aabbccddee029b", "112233445566778899aabbccddee029b") + sstore("112233445566778899aabbccddee029c", "112233445566778899aabbccddee029c") + sstore("112233445566778899aabbccddee029d", "112233445566778899aabbccddee029d") + sstore("112233445566778899aabbccddee029e", "112233445566778899aabbccddee029e") + sstore("112233445566778899aabbccddee029f", "112233445566778899aabbccddee029f") + sstore("112233445566778899aabbccddee02a0", "112233445566778899aabbccddee02a0") + sstore("112233445566778899aabbccddee02a1", "112233445566778899aabbccddee02a1") + sstore("112233445566778899aabbccddee02a2", "112233445566778899aabbccddee02a2") + sstore("112233445566778899aabbccddee02a3", "112233445566778899aabbccddee02a3") + sstore("112233445566778899aabbccddee02a4", "112233445566778899aabbccddee02a4") + sstore("112233445566778899aabbccddee02a5", "112233445566778899aabbccddee02a5") + sstore("112233445566778899aabbccddee02a6", "112233445566778899aabbccddee02a6") + sstore("112233445566778899aabbccddee02a7", "112233445566778899aabbccddee02a7") + sstore("112233445566778899aabbccddee02a8", "112233445566778899aabbccddee02a8") + sstore("112233445566778899aabbccddee02a9", "112233445566778899aabbccddee02a9") + sstore("112233445566778899aabbccddee02aa", "112233445566778899aabbccddee02aa") + sstore("112233445566778899aabbccddee02ab", "112233445566778899aabbccddee02ab") + sstore("112233445566778899aabbccddee02ac", "112233445566778899aabbccddee02ac") + sstore("112233445566778899aabbccddee02ad", "112233445566778899aabbccddee02ad") + sstore("112233445566778899aabbccddee02ae", "112233445566778899aabbccddee02ae") + sstore("112233445566778899aabbccddee02af", "112233445566778899aabbccddee02af") + sstore("112233445566778899aabbccddee02b0", "112233445566778899aabbccddee02b0") + sstore("112233445566778899aabbccddee02b1", "112233445566778899aabbccddee02b1") + sstore("112233445566778899aabbccddee02b2", "112233445566778899aabbccddee02b2") + sstore("112233445566778899aabbccddee02b3", "112233445566778899aabbccddee02b3") + sstore("112233445566778899aabbccddee02b4", "112233445566778899aabbccddee02b4") + sstore("112233445566778899aabbccddee02b5", "112233445566778899aabbccddee02b5") + sstore("112233445566778899aabbccddee02b6", "112233445566778899aabbccddee02b6") + sstore("112233445566778899aabbccddee02b7", "112233445566778899aabbccddee02b7") + sstore("112233445566778899aabbccddee02b8", "112233445566778899aabbccddee02b8") + sstore("112233445566778899aabbccddee02b9", "112233445566778899aabbccddee02b9") + sstore("112233445566778899aabbccddee02ba", "112233445566778899aabbccddee02ba") + sstore("112233445566778899aabbccddee02bb", "112233445566778899aabbccddee02bb") + sstore("112233445566778899aabbccddee02bc", "112233445566778899aabbccddee02bc") + sstore("112233445566778899aabbccddee02bd", "112233445566778899aabbccddee02bd") + sstore("112233445566778899aabbccddee02be", "112233445566778899aabbccddee02be") + sstore("112233445566778899aabbccddee02bf", "112233445566778899aabbccddee02bf") + sstore("112233445566778899aabbccddee02c0", "112233445566778899aabbccddee02c0") + sstore("112233445566778899aabbccddee02c1", "112233445566778899aabbccddee02c1") + sstore("112233445566778899aabbccddee02c2", "112233445566778899aabbccddee02c2") + sstore("112233445566778899aabbccddee02c3", "112233445566778899aabbccddee02c3") + sstore("112233445566778899aabbccddee02c4", "112233445566778899aabbccddee02c4") + sstore("112233445566778899aabbccddee02c5", "112233445566778899aabbccddee02c5") + sstore("112233445566778899aabbccddee02c6", "112233445566778899aabbccddee02c6") + sstore("112233445566778899aabbccddee02c7", "112233445566778899aabbccddee02c7") + sstore("112233445566778899aabbccddee02c8", "112233445566778899aabbccddee02c8") + sstore("112233445566778899aabbccddee02c9", "112233445566778899aabbccddee02c9") + sstore("112233445566778899aabbccddee02ca", "112233445566778899aabbccddee02ca") + sstore("112233445566778899aabbccddee02cb", "112233445566778899aabbccddee02cb") + sstore("112233445566778899aabbccddee02cc", "112233445566778899aabbccddee02cc") + sstore("112233445566778899aabbccddee02cd", "112233445566778899aabbccddee02cd") + sstore("112233445566778899aabbccddee02ce", "112233445566778899aabbccddee02ce") + sstore("112233445566778899aabbccddee02cf", "112233445566778899aabbccddee02cf") + sstore("112233445566778899aabbccddee02d0", "112233445566778899aabbccddee02d0") + sstore("112233445566778899aabbccddee02d1", "112233445566778899aabbccddee02d1") + sstore("112233445566778899aabbccddee02d2", "112233445566778899aabbccddee02d2") + sstore("112233445566778899aabbccddee02d3", "112233445566778899aabbccddee02d3") + sstore("112233445566778899aabbccddee02d4", "112233445566778899aabbccddee02d4") + sstore("112233445566778899aabbccddee02d5", "112233445566778899aabbccddee02d5") + sstore("112233445566778899aabbccddee02d6", "112233445566778899aabbccddee02d6") + sstore("112233445566778899aabbccddee02d7", "112233445566778899aabbccddee02d7") + sstore("112233445566778899aabbccddee02d8", "112233445566778899aabbccddee02d8") + sstore("112233445566778899aabbccddee02d9", "112233445566778899aabbccddee02d9") + sstore("112233445566778899aabbccddee02da", "112233445566778899aabbccddee02da") + sstore("112233445566778899aabbccddee02db", "112233445566778899aabbccddee02db") + sstore("112233445566778899aabbccddee02dc", "112233445566778899aabbccddee02dc") + sstore("112233445566778899aabbccddee02dd", "112233445566778899aabbccddee02dd") + sstore("112233445566778899aabbccddee02de", "112233445566778899aabbccddee02de") + sstore("112233445566778899aabbccddee02df", "112233445566778899aabbccddee02df") + sstore("112233445566778899aabbccddee02e0", "112233445566778899aabbccddee02e0") + sstore("112233445566778899aabbccddee02e1", "112233445566778899aabbccddee02e1") + sstore("112233445566778899aabbccddee02e2", "112233445566778899aabbccddee02e2") + sstore("112233445566778899aabbccddee02e3", "112233445566778899aabbccddee02e3") + sstore("112233445566778899aabbccddee02e4", "112233445566778899aabbccddee02e4") + sstore("112233445566778899aabbccddee02e5", "112233445566778899aabbccddee02e5") + sstore("112233445566778899aabbccddee02e6", "112233445566778899aabbccddee02e6") + sstore("112233445566778899aabbccddee02e7", "112233445566778899aabbccddee02e7") + sstore("112233445566778899aabbccddee02e8", "112233445566778899aabbccddee02e8") + sstore("112233445566778899aabbccddee02e9", "112233445566778899aabbccddee02e9") + sstore("112233445566778899aabbccddee02ea", "112233445566778899aabbccddee02ea") + sstore("112233445566778899aabbccddee02eb", "112233445566778899aabbccddee02eb") + sstore("112233445566778899aabbccddee02ec", "112233445566778899aabbccddee02ec") + sstore("112233445566778899aabbccddee02ed", "112233445566778899aabbccddee02ed") + sstore("112233445566778899aabbccddee02ee", "112233445566778899aabbccddee02ee") + sstore("112233445566778899aabbccddee02ef", "112233445566778899aabbccddee02ef") + sstore("112233445566778899aabbccddee02f0", "112233445566778899aabbccddee02f0") + sstore("112233445566778899aabbccddee02f1", "112233445566778899aabbccddee02f1") + sstore("112233445566778899aabbccddee02f2", "112233445566778899aabbccddee02f2") + sstore("112233445566778899aabbccddee02f3", "112233445566778899aabbccddee02f3") + sstore("112233445566778899aabbccddee02f4", "112233445566778899aabbccddee02f4") + sstore("112233445566778899aabbccddee02f5", "112233445566778899aabbccddee02f5") + sstore("112233445566778899aabbccddee02f6", "112233445566778899aabbccddee02f6") + sstore("112233445566778899aabbccddee02f7", "112233445566778899aabbccddee02f7") + sstore("112233445566778899aabbccddee02f8", "112233445566778899aabbccddee02f8") + sstore("112233445566778899aabbccddee02f9", "112233445566778899aabbccddee02f9") + sstore("112233445566778899aabbccddee02fa", "112233445566778899aabbccddee02fa") + sstore("112233445566778899aabbccddee02fb", "112233445566778899aabbccddee02fb") + sstore("112233445566778899aabbccddee02fc", "112233445566778899aabbccddee02fc") + sstore("112233445566778899aabbccddee02fd", "112233445566778899aabbccddee02fd") + sstore("112233445566778899aabbccddee02fe", "112233445566778899aabbccddee02fe") + sstore("112233445566778899aabbccddee02ff", "112233445566778899aabbccddee02ff") + sstore("112233445566778899aabbccddee0300", "112233445566778899aabbccddee0300") + sstore("112233445566778899aabbccddee0301", "112233445566778899aabbccddee0301") + sstore("112233445566778899aabbccddee0302", "112233445566778899aabbccddee0302") + sstore("112233445566778899aabbccddee0303", "112233445566778899aabbccddee0303") + sstore("112233445566778899aabbccddee0304", "112233445566778899aabbccddee0304") + sstore("112233445566778899aabbccddee0305", "112233445566778899aabbccddee0305") + sstore("112233445566778899aabbccddee0306", "112233445566778899aabbccddee0306") + sstore("112233445566778899aabbccddee0307", "112233445566778899aabbccddee0307") + sstore("112233445566778899aabbccddee0308", "112233445566778899aabbccddee0308") + sstore("112233445566778899aabbccddee0309", "112233445566778899aabbccddee0309") + sstore("112233445566778899aabbccddee030a", "112233445566778899aabbccddee030a") + sstore("112233445566778899aabbccddee030b", "112233445566778899aabbccddee030b") + sstore("112233445566778899aabbccddee030c", "112233445566778899aabbccddee030c") + sstore("112233445566778899aabbccddee030d", "112233445566778899aabbccddee030d") + sstore("112233445566778899aabbccddee030e", "112233445566778899aabbccddee030e") + sstore("112233445566778899aabbccddee030f", "112233445566778899aabbccddee030f") + sstore("112233445566778899aabbccddee0310", "112233445566778899aabbccddee0310") + sstore("112233445566778899aabbccddee0311", "112233445566778899aabbccddee0311") + sstore("112233445566778899aabbccddee0312", "112233445566778899aabbccddee0312") + sstore("112233445566778899aabbccddee0313", "112233445566778899aabbccddee0313") + sstore("112233445566778899aabbccddee0314", "112233445566778899aabbccddee0314") + sstore("112233445566778899aabbccddee0315", "112233445566778899aabbccddee0315") + sstore("112233445566778899aabbccddee0316", "112233445566778899aabbccddee0316") + sstore("112233445566778899aabbccddee0317", "112233445566778899aabbccddee0317") + sstore("112233445566778899aabbccddee0318", "112233445566778899aabbccddee0318") + sstore("112233445566778899aabbccddee0319", "112233445566778899aabbccddee0319") + sstore("112233445566778899aabbccddee031a", "112233445566778899aabbccddee031a") + sstore("112233445566778899aabbccddee031b", "112233445566778899aabbccddee031b") + sstore("112233445566778899aabbccddee031c", "112233445566778899aabbccddee031c") + sstore("112233445566778899aabbccddee031d", "112233445566778899aabbccddee031d") + sstore("112233445566778899aabbccddee031e", "112233445566778899aabbccddee031e") + sstore("112233445566778899aabbccddee031f", "112233445566778899aabbccddee031f") + sstore("112233445566778899aabbccddee0320", "112233445566778899aabbccddee0320") + sstore("112233445566778899aabbccddee0321", "112233445566778899aabbccddee0321") + sstore("112233445566778899aabbccddee0322", "112233445566778899aabbccddee0322") + sstore("112233445566778899aabbccddee0323", "112233445566778899aabbccddee0323") + sstore("112233445566778899aabbccddee0324", "112233445566778899aabbccddee0324") + sstore("112233445566778899aabbccddee0325", "112233445566778899aabbccddee0325") + sstore("112233445566778899aabbccddee0326", "112233445566778899aabbccddee0326") + sstore("112233445566778899aabbccddee0327", "112233445566778899aabbccddee0327") + sstore("112233445566778899aabbccddee0328", "112233445566778899aabbccddee0328") + sstore("112233445566778899aabbccddee0329", "112233445566778899aabbccddee0329") + sstore("112233445566778899aabbccddee032a", "112233445566778899aabbccddee032a") + sstore("112233445566778899aabbccddee032b", "112233445566778899aabbccddee032b") + sstore("112233445566778899aabbccddee032c", "112233445566778899aabbccddee032c") + sstore("112233445566778899aabbccddee032d", "112233445566778899aabbccddee032d") + sstore("112233445566778899aabbccddee032e", "112233445566778899aabbccddee032e") + sstore("112233445566778899aabbccddee032f", "112233445566778899aabbccddee032f") + sstore("112233445566778899aabbccddee0330", "112233445566778899aabbccddee0330") + sstore("112233445566778899aabbccddee0331", "112233445566778899aabbccddee0331") + sstore("112233445566778899aabbccddee0332", "112233445566778899aabbccddee0332") + sstore("112233445566778899aabbccddee0333", "112233445566778899aabbccddee0333") + sstore("112233445566778899aabbccddee0334", "112233445566778899aabbccddee0334") + sstore("112233445566778899aabbccddee0335", "112233445566778899aabbccddee0335") + sstore("112233445566778899aabbccddee0336", "112233445566778899aabbccddee0336") + sstore("112233445566778899aabbccddee0337", "112233445566778899aabbccddee0337") + sstore("112233445566778899aabbccddee0338", "112233445566778899aabbccddee0338") + sstore("112233445566778899aabbccddee0339", "112233445566778899aabbccddee0339") + sstore("112233445566778899aabbccddee033a", "112233445566778899aabbccddee033a") + sstore("112233445566778899aabbccddee033b", "112233445566778899aabbccddee033b") + sstore("112233445566778899aabbccddee033c", "112233445566778899aabbccddee033c") + sstore("112233445566778899aabbccddee033d", "112233445566778899aabbccddee033d") + sstore("112233445566778899aabbccddee033e", "112233445566778899aabbccddee033e") + sstore("112233445566778899aabbccddee033f", "112233445566778899aabbccddee033f") + sstore("112233445566778899aabbccddee0340", "112233445566778899aabbccddee0340") + sstore("112233445566778899aabbccddee0341", "112233445566778899aabbccddee0341") + sstore("112233445566778899aabbccddee0342", "112233445566778899aabbccddee0342") + sstore("112233445566778899aabbccddee0343", "112233445566778899aabbccddee0343") + sstore("112233445566778899aabbccddee0344", "112233445566778899aabbccddee0344") + sstore("112233445566778899aabbccddee0345", "112233445566778899aabbccddee0345") + sstore("112233445566778899aabbccddee0346", "112233445566778899aabbccddee0346") + sstore("112233445566778899aabbccddee0347", "112233445566778899aabbccddee0347") + sstore("112233445566778899aabbccddee0348", "112233445566778899aabbccddee0348") + sstore("112233445566778899aabbccddee0349", "112233445566778899aabbccddee0349") + sstore("112233445566778899aabbccddee034a", "112233445566778899aabbccddee034a") + sstore("112233445566778899aabbccddee034b", "112233445566778899aabbccddee034b") + sstore("112233445566778899aabbccddee034c", "112233445566778899aabbccddee034c") + sstore("112233445566778899aabbccddee034d", "112233445566778899aabbccddee034d") + sstore("112233445566778899aabbccddee034e", "112233445566778899aabbccddee034e") + sstore("112233445566778899aabbccddee034f", "112233445566778899aabbccddee034f") + sstore("112233445566778899aabbccddee0350", "112233445566778899aabbccddee0350") + sstore("112233445566778899aabbccddee0351", "112233445566778899aabbccddee0351") + sstore("112233445566778899aabbccddee0352", "112233445566778899aabbccddee0352") + sstore("112233445566778899aabbccddee0353", "112233445566778899aabbccddee0353") + sstore("112233445566778899aabbccddee0354", "112233445566778899aabbccddee0354") + sstore("112233445566778899aabbccddee0355", "112233445566778899aabbccddee0355") + sstore("112233445566778899aabbccddee0356", "112233445566778899aabbccddee0356") + sstore("112233445566778899aabbccddee0357", "112233445566778899aabbccddee0357") + sstore("112233445566778899aabbccddee0358", "112233445566778899aabbccddee0358") + sstore("112233445566778899aabbccddee0359", "112233445566778899aabbccddee0359") + sstore("112233445566778899aabbccddee035a", "112233445566778899aabbccddee035a") + sstore("112233445566778899aabbccddee035b", "112233445566778899aabbccddee035b") + sstore("112233445566778899aabbccddee035c", "112233445566778899aabbccddee035c") + sstore("112233445566778899aabbccddee035d", "112233445566778899aabbccddee035d") + sstore("112233445566778899aabbccddee035e", "112233445566778899aabbccddee035e") + sstore("112233445566778899aabbccddee035f", "112233445566778899aabbccddee035f") + sstore("112233445566778899aabbccddee0360", "112233445566778899aabbccddee0360") + sstore("112233445566778899aabbccddee0361", "112233445566778899aabbccddee0361") + sstore("112233445566778899aabbccddee0362", "112233445566778899aabbccddee0362") + sstore("112233445566778899aabbccddee0363", "112233445566778899aabbccddee0363") + sstore("112233445566778899aabbccddee0364", "112233445566778899aabbccddee0364") + sstore("112233445566778899aabbccddee0365", "112233445566778899aabbccddee0365") + sstore("112233445566778899aabbccddee0366", "112233445566778899aabbccddee0366") + sstore("112233445566778899aabbccddee0367", "112233445566778899aabbccddee0367") + sstore("112233445566778899aabbccddee0368", "112233445566778899aabbccddee0368") + sstore("112233445566778899aabbccddee0369", "112233445566778899aabbccddee0369") + sstore("112233445566778899aabbccddee036a", "112233445566778899aabbccddee036a") + sstore("112233445566778899aabbccddee036b", "112233445566778899aabbccddee036b") + sstore("112233445566778899aabbccddee036c", "112233445566778899aabbccddee036c") + sstore("112233445566778899aabbccddee036d", "112233445566778899aabbccddee036d") + sstore("112233445566778899aabbccddee036e", "112233445566778899aabbccddee036e") + sstore("112233445566778899aabbccddee036f", "112233445566778899aabbccddee036f") + sstore("112233445566778899aabbccddee0370", "112233445566778899aabbccddee0370") + sstore("112233445566778899aabbccddee0371", "112233445566778899aabbccddee0371") + sstore("112233445566778899aabbccddee0372", "112233445566778899aabbccddee0372") + sstore("112233445566778899aabbccddee0373", "112233445566778899aabbccddee0373") + sstore("112233445566778899aabbccddee0374", "112233445566778899aabbccddee0374") + sstore("112233445566778899aabbccddee0375", "112233445566778899aabbccddee0375") + sstore("112233445566778899aabbccddee0376", "112233445566778899aabbccddee0376") + sstore("112233445566778899aabbccddee0377", "112233445566778899aabbccddee0377") + sstore("112233445566778899aabbccddee0378", "112233445566778899aabbccddee0378") + sstore("112233445566778899aabbccddee0379", "112233445566778899aabbccddee0379") + sstore("112233445566778899aabbccddee037a", "112233445566778899aabbccddee037a") + sstore("112233445566778899aabbccddee037b", "112233445566778899aabbccddee037b") + sstore("112233445566778899aabbccddee037c", "112233445566778899aabbccddee037c") + sstore("112233445566778899aabbccddee037d", "112233445566778899aabbccddee037d") + sstore("112233445566778899aabbccddee037e", "112233445566778899aabbccddee037e") + sstore("112233445566778899aabbccddee037f", "112233445566778899aabbccddee037f") + sstore("112233445566778899aabbccddee0380", "112233445566778899aabbccddee0380") + sstore("112233445566778899aabbccddee0381", "112233445566778899aabbccddee0381") + sstore("112233445566778899aabbccddee0382", "112233445566778899aabbccddee0382") + sstore("112233445566778899aabbccddee0383", "112233445566778899aabbccddee0383") + sstore("112233445566778899aabbccddee0384", "112233445566778899aabbccddee0384") + sstore("112233445566778899aabbccddee0385", "112233445566778899aabbccddee0385") + sstore("112233445566778899aabbccddee0386", "112233445566778899aabbccddee0386") + sstore("112233445566778899aabbccddee0387", "112233445566778899aabbccddee0387") + sstore("112233445566778899aabbccddee0388", "112233445566778899aabbccddee0388") + sstore("112233445566778899aabbccddee0389", "112233445566778899aabbccddee0389") + sstore("112233445566778899aabbccddee038a", "112233445566778899aabbccddee038a") + sstore("112233445566778899aabbccddee038b", "112233445566778899aabbccddee038b") + sstore("112233445566778899aabbccddee038c", "112233445566778899aabbccddee038c") + sstore("112233445566778899aabbccddee038d", "112233445566778899aabbccddee038d") + sstore("112233445566778899aabbccddee038e", "112233445566778899aabbccddee038e") + sstore("112233445566778899aabbccddee038f", "112233445566778899aabbccddee038f") + sstore("112233445566778899aabbccddee0390", "112233445566778899aabbccddee0390") + sstore("112233445566778899aabbccddee0391", "112233445566778899aabbccddee0391") + sstore("112233445566778899aabbccddee0392", "112233445566778899aabbccddee0392") + sstore("112233445566778899aabbccddee0393", "112233445566778899aabbccddee0393") + sstore("112233445566778899aabbccddee0394", "112233445566778899aabbccddee0394") + sstore("112233445566778899aabbccddee0395", "112233445566778899aabbccddee0395") + sstore("112233445566778899aabbccddee0396", "112233445566778899aabbccddee0396") + sstore("112233445566778899aabbccddee0397", "112233445566778899aabbccddee0397") + sstore("112233445566778899aabbccddee0398", "112233445566778899aabbccddee0398") + sstore("112233445566778899aabbccddee0399", "112233445566778899aabbccddee0399") + sstore("112233445566778899aabbccddee039a", "112233445566778899aabbccddee039a") + sstore("112233445566778899aabbccddee039b", "112233445566778899aabbccddee039b") + sstore("112233445566778899aabbccddee039c", "112233445566778899aabbccddee039c") + sstore("112233445566778899aabbccddee039d", "112233445566778899aabbccddee039d") + sstore("112233445566778899aabbccddee039e", "112233445566778899aabbccddee039e") + sstore("112233445566778899aabbccddee039f", "112233445566778899aabbccddee039f") + sstore("112233445566778899aabbccddee03a0", "112233445566778899aabbccddee03a0") + sstore("112233445566778899aabbccddee03a1", "112233445566778899aabbccddee03a1") + sstore("112233445566778899aabbccddee03a2", "112233445566778899aabbccddee03a2") + sstore("112233445566778899aabbccddee03a3", "112233445566778899aabbccddee03a3") + sstore("112233445566778899aabbccddee03a4", "112233445566778899aabbccddee03a4") + sstore("112233445566778899aabbccddee03a5", "112233445566778899aabbccddee03a5") + sstore("112233445566778899aabbccddee03a6", "112233445566778899aabbccddee03a6") + sstore("112233445566778899aabbccddee03a7", "112233445566778899aabbccddee03a7") + sstore("112233445566778899aabbccddee03a8", "112233445566778899aabbccddee03a8") + sstore("112233445566778899aabbccddee03a9", "112233445566778899aabbccddee03a9") + sstore("112233445566778899aabbccddee03aa", "112233445566778899aabbccddee03aa") + sstore("112233445566778899aabbccddee03ab", "112233445566778899aabbccddee03ab") + sstore("112233445566778899aabbccddee03ac", "112233445566778899aabbccddee03ac") + sstore("112233445566778899aabbccddee03ad", "112233445566778899aabbccddee03ad") + sstore("112233445566778899aabbccddee03ae", "112233445566778899aabbccddee03ae") + sstore("112233445566778899aabbccddee03af", "112233445566778899aabbccddee03af") + sstore("112233445566778899aabbccddee03b0", "112233445566778899aabbccddee03b0") + sstore("112233445566778899aabbccddee03b1", "112233445566778899aabbccddee03b1") + sstore("112233445566778899aabbccddee03b2", "112233445566778899aabbccddee03b2") + sstore("112233445566778899aabbccddee03b3", "112233445566778899aabbccddee03b3") + sstore("112233445566778899aabbccddee03b4", "112233445566778899aabbccddee03b4") + sstore("112233445566778899aabbccddee03b5", "112233445566778899aabbccddee03b5") + sstore("112233445566778899aabbccddee03b6", "112233445566778899aabbccddee03b6") + sstore("112233445566778899aabbccddee03b7", "112233445566778899aabbccddee03b7") + sstore("112233445566778899aabbccddee03b8", "112233445566778899aabbccddee03b8") + sstore("112233445566778899aabbccddee03b9", "112233445566778899aabbccddee03b9") + sstore("112233445566778899aabbccddee03ba", "112233445566778899aabbccddee03ba") + sstore("112233445566778899aabbccddee03bb", "112233445566778899aabbccddee03bb") + sstore("112233445566778899aabbccddee03bc", "112233445566778899aabbccddee03bc") + sstore("112233445566778899aabbccddee03bd", "112233445566778899aabbccddee03bd") + sstore("112233445566778899aabbccddee03be", "112233445566778899aabbccddee03be") + sstore("112233445566778899aabbccddee03bf", "112233445566778899aabbccddee03bf") + sstore("112233445566778899aabbccddee03c0", "112233445566778899aabbccddee03c0") + sstore("112233445566778899aabbccddee03c1", "112233445566778899aabbccddee03c1") + sstore("112233445566778899aabbccddee03c2", "112233445566778899aabbccddee03c2") + sstore("112233445566778899aabbccddee03c3", "112233445566778899aabbccddee03c3") + sstore("112233445566778899aabbccddee03c4", "112233445566778899aabbccddee03c4") + sstore("112233445566778899aabbccddee03c5", "112233445566778899aabbccddee03c5") + sstore("112233445566778899aabbccddee03c6", "112233445566778899aabbccddee03c6") + sstore("112233445566778899aabbccddee03c7", "112233445566778899aabbccddee03c7") + sstore("112233445566778899aabbccddee03c8", "112233445566778899aabbccddee03c8") + sstore("112233445566778899aabbccddee03c9", "112233445566778899aabbccddee03c9") + sstore("112233445566778899aabbccddee03ca", "112233445566778899aabbccddee03ca") + sstore("112233445566778899aabbccddee03cb", "112233445566778899aabbccddee03cb") + sstore("112233445566778899aabbccddee03cc", "112233445566778899aabbccddee03cc") + sstore("112233445566778899aabbccddee03cd", "112233445566778899aabbccddee03cd") + sstore("112233445566778899aabbccddee03ce", "112233445566778899aabbccddee03ce") + sstore("112233445566778899aabbccddee03cf", "112233445566778899aabbccddee03cf") + sstore("112233445566778899aabbccddee03d0", "112233445566778899aabbccddee03d0") + sstore("112233445566778899aabbccddee03d1", "112233445566778899aabbccddee03d1") + sstore("112233445566778899aabbccddee03d2", "112233445566778899aabbccddee03d2") + sstore("112233445566778899aabbccddee03d3", "112233445566778899aabbccddee03d3") + sstore("112233445566778899aabbccddee03d4", "112233445566778899aabbccddee03d4") + sstore("112233445566778899aabbccddee03d5", "112233445566778899aabbccddee03d5") + sstore("112233445566778899aabbccddee03d6", "112233445566778899aabbccddee03d6") + sstore("112233445566778899aabbccddee03d7", "112233445566778899aabbccddee03d7") + sstore("112233445566778899aabbccddee03d8", "112233445566778899aabbccddee03d8") + sstore("112233445566778899aabbccddee03d9", "112233445566778899aabbccddee03d9") + sstore("112233445566778899aabbccddee03da", "112233445566778899aabbccddee03da") + sstore("112233445566778899aabbccddee03db", "112233445566778899aabbccddee03db") + sstore("112233445566778899aabbccddee03dc", "112233445566778899aabbccddee03dc") + sstore("112233445566778899aabbccddee03dd", "112233445566778899aabbccddee03dd") + sstore("112233445566778899aabbccddee03de", "112233445566778899aabbccddee03de") + sstore("112233445566778899aabbccddee03df", "112233445566778899aabbccddee03df") + sstore("112233445566778899aabbccddee03e0", "112233445566778899aabbccddee03e0") + sstore("112233445566778899aabbccddee03e1", "112233445566778899aabbccddee03e1") + sstore("112233445566778899aabbccddee03e2", "112233445566778899aabbccddee03e2") + sstore("112233445566778899aabbccddee03e3", "112233445566778899aabbccddee03e3") + sstore("112233445566778899aabbccddee03e4", "112233445566778899aabbccddee03e4") + sstore("112233445566778899aabbccddee03e5", "112233445566778899aabbccddee03e5") + sstore("112233445566778899aabbccddee03e6", "112233445566778899aabbccddee03e6") + sstore("112233445566778899aabbccddee03e7", "112233445566778899aabbccddee03e7") + sstore("112233445566778899aabbccddee03e8", "112233445566778899aabbccddee03e8") + sstore("112233445566778899aabbccddee03e9", "112233445566778899aabbccddee03e9") + sstore("112233445566778899aabbccddee03ea", "112233445566778899aabbccddee03ea") + sstore("112233445566778899aabbccddee03eb", "112233445566778899aabbccddee03eb") + sstore("112233445566778899aabbccddee03ec", "112233445566778899aabbccddee03ec") + sstore("112233445566778899aabbccddee03ed", "112233445566778899aabbccddee03ed") + sstore("112233445566778899aabbccddee03ee", "112233445566778899aabbccddee03ee") + sstore("112233445566778899aabbccddee03ef", "112233445566778899aabbccddee03ef") + sstore("112233445566778899aabbccddee03f0", "112233445566778899aabbccddee03f0") + sstore("112233445566778899aabbccddee03f1", "112233445566778899aabbccddee03f1") + sstore("112233445566778899aabbccddee03f2", "112233445566778899aabbccddee03f2") + sstore("112233445566778899aabbccddee03f3", "112233445566778899aabbccddee03f3") + sstore("112233445566778899aabbccddee03f4", "112233445566778899aabbccddee03f4") + sstore("112233445566778899aabbccddee03f5", "112233445566778899aabbccddee03f5") + sstore("112233445566778899aabbccddee03f6", "112233445566778899aabbccddee03f6") + sstore("112233445566778899aabbccddee03f7", "112233445566778899aabbccddee03f7") + sstore("112233445566778899aabbccddee03f8", "112233445566778899aabbccddee03f8") + sstore("112233445566778899aabbccddee03f9", "112233445566778899aabbccddee03f9") + sstore("112233445566778899aabbccddee03fa", "112233445566778899aabbccddee03fa") + sstore("112233445566778899aabbccddee03fb", "112233445566778899aabbccddee03fb") + sstore("112233445566778899aabbccddee03fc", "112233445566778899aabbccddee03fc") + sstore("112233445566778899aabbccddee03fd", "112233445566778899aabbccddee03fd") + sstore("112233445566778899aabbccddee03fe", "112233445566778899aabbccddee03fe") + sstore("112233445566778899aabbccddee03ff", "112233445566778899aabbccddee03ff") + sstore("112233445566778899aabbccddee0400", "112233445566778899aabbccddee0400") + sstore("112233445566778899aabbccddee0401", "112233445566778899aabbccddee0401") + sstore("112233445566778899aabbccddee0402", "112233445566778899aabbccddee0402") + sstore("112233445566778899aabbccddee0403", "112233445566778899aabbccddee0403") + sstore("112233445566778899aabbccddee0404", "112233445566778899aabbccddee0404") + sstore("112233445566778899aabbccddee0405", "112233445566778899aabbccddee0405") + sstore("112233445566778899aabbccddee0406", "112233445566778899aabbccddee0406") + sstore("112233445566778899aabbccddee0407", "112233445566778899aabbccddee0407") + sstore("112233445566778899aabbccddee0408", "112233445566778899aabbccddee0408") + sstore("112233445566778899aabbccddee0409", "112233445566778899aabbccddee0409") + sstore("112233445566778899aabbccddee040a", "112233445566778899aabbccddee040a") + sstore("112233445566778899aabbccddee040b", "112233445566778899aabbccddee040b") + sstore("112233445566778899aabbccddee040c", "112233445566778899aabbccddee040c") + sstore("112233445566778899aabbccddee040d", "112233445566778899aabbccddee040d") + sstore("112233445566778899aabbccddee040e", "112233445566778899aabbccddee040e") + sstore("112233445566778899aabbccddee040f", "112233445566778899aabbccddee040f") + sstore("112233445566778899aabbccddee0410", "112233445566778899aabbccddee0410") + sstore("112233445566778899aabbccddee0411", "112233445566778899aabbccddee0411") + sstore("112233445566778899aabbccddee0412", "112233445566778899aabbccddee0412") + sstore("112233445566778899aabbccddee0413", "112233445566778899aabbccddee0413") + sstore("112233445566778899aabbccddee0414", "112233445566778899aabbccddee0414") + sstore("112233445566778899aabbccddee0415", "112233445566778899aabbccddee0415") + sstore("112233445566778899aabbccddee0416", "112233445566778899aabbccddee0416") + sstore("112233445566778899aabbccddee0417", "112233445566778899aabbccddee0417") + sstore("112233445566778899aabbccddee0418", "112233445566778899aabbccddee0418") + sstore("112233445566778899aabbccddee0419", "112233445566778899aabbccddee0419") + sstore("112233445566778899aabbccddee041a", "112233445566778899aabbccddee041a") + sstore("112233445566778899aabbccddee041b", "112233445566778899aabbccddee041b") + sstore("112233445566778899aabbccddee041c", "112233445566778899aabbccddee041c") + sstore("112233445566778899aabbccddee041d", "112233445566778899aabbccddee041d") + sstore("112233445566778899aabbccddee041e", "112233445566778899aabbccddee041e") + sstore("112233445566778899aabbccddee041f", "112233445566778899aabbccddee041f") + sstore("112233445566778899aabbccddee0420", "112233445566778899aabbccddee0420") + sstore("112233445566778899aabbccddee0421", "112233445566778899aabbccddee0421") + sstore("112233445566778899aabbccddee0422", "112233445566778899aabbccddee0422") + sstore("112233445566778899aabbccddee0423", "112233445566778899aabbccddee0423") + sstore("112233445566778899aabbccddee0424", "112233445566778899aabbccddee0424") + sstore("112233445566778899aabbccddee0425", "112233445566778899aabbccddee0425") + sstore("112233445566778899aabbccddee0426", "112233445566778899aabbccddee0426") + sstore("112233445566778899aabbccddee0427", "112233445566778899aabbccddee0427") + sstore("112233445566778899aabbccddee0428", "112233445566778899aabbccddee0428") + sstore("112233445566778899aabbccddee0429", "112233445566778899aabbccddee0429") + sstore("112233445566778899aabbccddee042a", "112233445566778899aabbccddee042a") + sstore("112233445566778899aabbccddee042b", "112233445566778899aabbccddee042b") + sstore("112233445566778899aabbccddee042c", "112233445566778899aabbccddee042c") + sstore("112233445566778899aabbccddee042d", "112233445566778899aabbccddee042d") + sstore("112233445566778899aabbccddee042e", "112233445566778899aabbccddee042e") + sstore("112233445566778899aabbccddee042f", "112233445566778899aabbccddee042f") + sstore("112233445566778899aabbccddee0430", "112233445566778899aabbccddee0430") + sstore("112233445566778899aabbccddee0431", "112233445566778899aabbccddee0431") + sstore("112233445566778899aabbccddee0432", "112233445566778899aabbccddee0432") + sstore("112233445566778899aabbccddee0433", "112233445566778899aabbccddee0433") + sstore("112233445566778899aabbccddee0434", "112233445566778899aabbccddee0434") + sstore("112233445566778899aabbccddee0435", "112233445566778899aabbccddee0435") + sstore("112233445566778899aabbccddee0436", "112233445566778899aabbccddee0436") + sstore("112233445566778899aabbccddee0437", "112233445566778899aabbccddee0437") + sstore("112233445566778899aabbccddee0438", "112233445566778899aabbccddee0438") + sstore("112233445566778899aabbccddee0439", "112233445566778899aabbccddee0439") + sstore("112233445566778899aabbccddee043a", "112233445566778899aabbccddee043a") + sstore("112233445566778899aabbccddee043b", "112233445566778899aabbccddee043b") + sstore("112233445566778899aabbccddee043c", "112233445566778899aabbccddee043c") + sstore("112233445566778899aabbccddee043d", "112233445566778899aabbccddee043d") + sstore("112233445566778899aabbccddee043e", "112233445566778899aabbccddee043e") + sstore("112233445566778899aabbccddee043f", "112233445566778899aabbccddee043f") + sstore("112233445566778899aabbccddee0440", "112233445566778899aabbccddee0440") + sstore("112233445566778899aabbccddee0441", "112233445566778899aabbccddee0441") + sstore("112233445566778899aabbccddee0442", "112233445566778899aabbccddee0442") + sstore("112233445566778899aabbccddee0443", "112233445566778899aabbccddee0443") + sstore("112233445566778899aabbccddee0444", "112233445566778899aabbccddee0444") + sstore("112233445566778899aabbccddee0445", "112233445566778899aabbccddee0445") + sstore("112233445566778899aabbccddee0446", "112233445566778899aabbccddee0446") + sstore("112233445566778899aabbccddee0447", "112233445566778899aabbccddee0447") + sstore("112233445566778899aabbccddee0448", "112233445566778899aabbccddee0448") + sstore("112233445566778899aabbccddee0449", "112233445566778899aabbccddee0449") + sstore("112233445566778899aabbccddee044a", "112233445566778899aabbccddee044a") + sstore("112233445566778899aabbccddee044b", "112233445566778899aabbccddee044b") + sstore("112233445566778899aabbccddee044c", "112233445566778899aabbccddee044c") + sstore("112233445566778899aabbccddee044d", "112233445566778899aabbccddee044d") + sstore("112233445566778899aabbccddee044e", "112233445566778899aabbccddee044e") + sstore("112233445566778899aabbccddee044f", "112233445566778899aabbccddee044f") + sstore("112233445566778899aabbccddee0450", "112233445566778899aabbccddee0450") + sstore("112233445566778899aabbccddee0451", "112233445566778899aabbccddee0451") + sstore("112233445566778899aabbccddee0452", "112233445566778899aabbccddee0452") + sstore("112233445566778899aabbccddee0453", "112233445566778899aabbccddee0453") + sstore("112233445566778899aabbccddee0454", "112233445566778899aabbccddee0454") + sstore("112233445566778899aabbccddee0455", "112233445566778899aabbccddee0455") + sstore("112233445566778899aabbccddee0456", "112233445566778899aabbccddee0456") + sstore("112233445566778899aabbccddee0457", "112233445566778899aabbccddee0457") + sstore("112233445566778899aabbccddee0458", "112233445566778899aabbccddee0458") + sstore("112233445566778899aabbccddee0459", "112233445566778899aabbccddee0459") + sstore("112233445566778899aabbccddee045a", "112233445566778899aabbccddee045a") + sstore("112233445566778899aabbccddee045b", "112233445566778899aabbccddee045b") + sstore("112233445566778899aabbccddee045c", "112233445566778899aabbccddee045c") + sstore("112233445566778899aabbccddee045d", "112233445566778899aabbccddee045d") + sstore("112233445566778899aabbccddee045e", "112233445566778899aabbccddee045e") + sstore("112233445566778899aabbccddee045f", "112233445566778899aabbccddee045f") + sstore("112233445566778899aabbccddee0460", "112233445566778899aabbccddee0460") + sstore("112233445566778899aabbccddee0461", "112233445566778899aabbccddee0461") + sstore("112233445566778899aabbccddee0462", "112233445566778899aabbccddee0462") + sstore("112233445566778899aabbccddee0463", "112233445566778899aabbccddee0463") + sstore("112233445566778899aabbccddee0464", "112233445566778899aabbccddee0464") + sstore("112233445566778899aabbccddee0465", "112233445566778899aabbccddee0465") + sstore("112233445566778899aabbccddee0466", "112233445566778899aabbccddee0466") + sstore("112233445566778899aabbccddee0467", "112233445566778899aabbccddee0467") + sstore("112233445566778899aabbccddee0468", "112233445566778899aabbccddee0468") + sstore("112233445566778899aabbccddee0469", "112233445566778899aabbccddee0469") + sstore("112233445566778899aabbccddee046a", "112233445566778899aabbccddee046a") + sstore("112233445566778899aabbccddee046b", "112233445566778899aabbccddee046b") + sstore("112233445566778899aabbccddee046c", "112233445566778899aabbccddee046c") + sstore("112233445566778899aabbccddee046d", "112233445566778899aabbccddee046d") + sstore("112233445566778899aabbccddee046e", "112233445566778899aabbccddee046e") + sstore("112233445566778899aabbccddee046f", "112233445566778899aabbccddee046f") + sstore("112233445566778899aabbccddee0470", "112233445566778899aabbccddee0470") + sstore("112233445566778899aabbccddee0471", "112233445566778899aabbccddee0471") + sstore("112233445566778899aabbccddee0472", "112233445566778899aabbccddee0472") + sstore("112233445566778899aabbccddee0473", "112233445566778899aabbccddee0473") + sstore("112233445566778899aabbccddee0474", "112233445566778899aabbccddee0474") + sstore("112233445566778899aabbccddee0475", "112233445566778899aabbccddee0475") + sstore("112233445566778899aabbccddee0476", "112233445566778899aabbccddee0476") + sstore("112233445566778899aabbccddee0477", "112233445566778899aabbccddee0477") + sstore("112233445566778899aabbccddee0478", "112233445566778899aabbccddee0478") + sstore("112233445566778899aabbccddee0479", "112233445566778899aabbccddee0479") + sstore("112233445566778899aabbccddee047a", "112233445566778899aabbccddee047a") + sstore("112233445566778899aabbccddee047b", "112233445566778899aabbccddee047b") + sstore("112233445566778899aabbccddee047c", "112233445566778899aabbccddee047c") + sstore("112233445566778899aabbccddee047d", "112233445566778899aabbccddee047d") + sstore("112233445566778899aabbccddee047e", "112233445566778899aabbccddee047e") + sstore("112233445566778899aabbccddee047f", "112233445566778899aabbccddee047f") + sstore("112233445566778899aabbccddee0480", "112233445566778899aabbccddee0480") + sstore("112233445566778899aabbccddee0481", "112233445566778899aabbccddee0481") + sstore("112233445566778899aabbccddee0482", "112233445566778899aabbccddee0482") + sstore("112233445566778899aabbccddee0483", "112233445566778899aabbccddee0483") + sstore("112233445566778899aabbccddee0484", "112233445566778899aabbccddee0484") + sstore("112233445566778899aabbccddee0485", "112233445566778899aabbccddee0485") + sstore("112233445566778899aabbccddee0486", "112233445566778899aabbccddee0486") + sstore("112233445566778899aabbccddee0487", "112233445566778899aabbccddee0487") + sstore("112233445566778899aabbccddee0488", "112233445566778899aabbccddee0488") + sstore("112233445566778899aabbccddee0489", "112233445566778899aabbccddee0489") + sstore("112233445566778899aabbccddee048a", "112233445566778899aabbccddee048a") + sstore("112233445566778899aabbccddee048b", "112233445566778899aabbccddee048b") + sstore("112233445566778899aabbccddee048c", "112233445566778899aabbccddee048c") + sstore("112233445566778899aabbccddee048d", "112233445566778899aabbccddee048d") + sstore("112233445566778899aabbccddee048e", "112233445566778899aabbccddee048e") + sstore("112233445566778899aabbccddee048f", "112233445566778899aabbccddee048f") + sstore("112233445566778899aabbccddee0490", "112233445566778899aabbccddee0490") + sstore("112233445566778899aabbccddee0491", "112233445566778899aabbccddee0491") + sstore("112233445566778899aabbccddee0492", "112233445566778899aabbccddee0492") + sstore("112233445566778899aabbccddee0493", "112233445566778899aabbccddee0493") + sstore("112233445566778899aabbccddee0494", "112233445566778899aabbccddee0494") + sstore("112233445566778899aabbccddee0495", "112233445566778899aabbccddee0495") + sstore("112233445566778899aabbccddee0496", "112233445566778899aabbccddee0496") + sstore("112233445566778899aabbccddee0497", "112233445566778899aabbccddee0497") + sstore("112233445566778899aabbccddee0498", "112233445566778899aabbccddee0498") + sstore("112233445566778899aabbccddee0499", "112233445566778899aabbccddee0499") + sstore("112233445566778899aabbccddee049a", "112233445566778899aabbccddee049a") + sstore("112233445566778899aabbccddee049b", "112233445566778899aabbccddee049b") + sstore("112233445566778899aabbccddee049c", "112233445566778899aabbccddee049c") + sstore("112233445566778899aabbccddee049d", "112233445566778899aabbccddee049d") + sstore("112233445566778899aabbccddee049e", "112233445566778899aabbccddee049e") + sstore("112233445566778899aabbccddee049f", "112233445566778899aabbccddee049f") + sstore("112233445566778899aabbccddee04a0", "112233445566778899aabbccddee04a0") + sstore("112233445566778899aabbccddee04a1", "112233445566778899aabbccddee04a1") + sstore("112233445566778899aabbccddee04a2", "112233445566778899aabbccddee04a2") + sstore("112233445566778899aabbccddee04a3", "112233445566778899aabbccddee04a3") + sstore("112233445566778899aabbccddee04a4", "112233445566778899aabbccddee04a4") + sstore("112233445566778899aabbccddee04a5", "112233445566778899aabbccddee04a5") + sstore("112233445566778899aabbccddee04a6", "112233445566778899aabbccddee04a6") + sstore("112233445566778899aabbccddee04a7", "112233445566778899aabbccddee04a7") + sstore("112233445566778899aabbccddee04a8", "112233445566778899aabbccddee04a8") + sstore("112233445566778899aabbccddee04a9", "112233445566778899aabbccddee04a9") + sstore("112233445566778899aabbccddee04aa", "112233445566778899aabbccddee04aa") + sstore("112233445566778899aabbccddee04ab", "112233445566778899aabbccddee04ab") + sstore("112233445566778899aabbccddee04ac", "112233445566778899aabbccddee04ac") + sstore("112233445566778899aabbccddee04ad", "112233445566778899aabbccddee04ad") + sstore("112233445566778899aabbccddee04ae", "112233445566778899aabbccddee04ae") + sstore("112233445566778899aabbccddee04af", "112233445566778899aabbccddee04af") + sstore("112233445566778899aabbccddee04b0", "112233445566778899aabbccddee04b0") + sstore("112233445566778899aabbccddee04b1", "112233445566778899aabbccddee04b1") + sstore("112233445566778899aabbccddee04b2", "112233445566778899aabbccddee04b2") + sstore("112233445566778899aabbccddee04b3", "112233445566778899aabbccddee04b3") + sstore("112233445566778899aabbccddee04b4", "112233445566778899aabbccddee04b4") + sstore("112233445566778899aabbccddee04b5", "112233445566778899aabbccddee04b5") + sstore("112233445566778899aabbccddee04b6", "112233445566778899aabbccddee04b6") + sstore("112233445566778899aabbccddee04b7", "112233445566778899aabbccddee04b7") + sstore("112233445566778899aabbccddee04b8", "112233445566778899aabbccddee04b8") + sstore("112233445566778899aabbccddee04b9", "112233445566778899aabbccddee04b9") + sstore("112233445566778899aabbccddee04ba", "112233445566778899aabbccddee04ba") + sstore("112233445566778899aabbccddee04bb", "112233445566778899aabbccddee04bb") + sstore("112233445566778899aabbccddee04bc", "112233445566778899aabbccddee04bc") + sstore("112233445566778899aabbccddee04bd", "112233445566778899aabbccddee04bd") + sstore("112233445566778899aabbccddee04be", "112233445566778899aabbccddee04be") + sstore("112233445566778899aabbccddee04bf", "112233445566778899aabbccddee04bf") + sstore("112233445566778899aabbccddee04c0", "112233445566778899aabbccddee04c0") + sstore("112233445566778899aabbccddee04c1", "112233445566778899aabbccddee04c1") + sstore("112233445566778899aabbccddee04c2", "112233445566778899aabbccddee04c2") + sstore("112233445566778899aabbccddee04c3", "112233445566778899aabbccddee04c3") + sstore("112233445566778899aabbccddee04c4", "112233445566778899aabbccddee04c4") + sstore("112233445566778899aabbccddee04c5", "112233445566778899aabbccddee04c5") + sstore("112233445566778899aabbccddee04c6", "112233445566778899aabbccddee04c6") + sstore("112233445566778899aabbccddee04c7", "112233445566778899aabbccddee04c7") + sstore("112233445566778899aabbccddee04c8", "112233445566778899aabbccddee04c8") + sstore("112233445566778899aabbccddee04c9", "112233445566778899aabbccddee04c9") + sstore("112233445566778899aabbccddee04ca", "112233445566778899aabbccddee04ca") + sstore("112233445566778899aabbccddee04cb", "112233445566778899aabbccddee04cb") + sstore("112233445566778899aabbccddee04cc", "112233445566778899aabbccddee04cc") + sstore("112233445566778899aabbccddee04cd", "112233445566778899aabbccddee04cd") + sstore("112233445566778899aabbccddee04ce", "112233445566778899aabbccddee04ce") + sstore("112233445566778899aabbccddee04cf", "112233445566778899aabbccddee04cf") + sstore("112233445566778899aabbccddee04d0", "112233445566778899aabbccddee04d0") + sstore("112233445566778899aabbccddee04d1", "112233445566778899aabbccddee04d1") + sstore("112233445566778899aabbccddee04d2", "112233445566778899aabbccddee04d2") + sstore("112233445566778899aabbccddee04d3", "112233445566778899aabbccddee04d3") + sstore("112233445566778899aabbccddee04d4", "112233445566778899aabbccddee04d4") + sstore("112233445566778899aabbccddee04d5", "112233445566778899aabbccddee04d5") + sstore("112233445566778899aabbccddee04d6", "112233445566778899aabbccddee04d6") + sstore("112233445566778899aabbccddee04d7", "112233445566778899aabbccddee04d7") + sstore("112233445566778899aabbccddee04d8", "112233445566778899aabbccddee04d8") + sstore("112233445566778899aabbccddee04d9", "112233445566778899aabbccddee04d9") + sstore("112233445566778899aabbccddee04da", "112233445566778899aabbccddee04da") + sstore("112233445566778899aabbccddee04db", "112233445566778899aabbccddee04db") + sstore("112233445566778899aabbccddee04dc", "112233445566778899aabbccddee04dc") + sstore("112233445566778899aabbccddee04dd", "112233445566778899aabbccddee04dd") + sstore("112233445566778899aabbccddee04de", "112233445566778899aabbccddee04de") + sstore("112233445566778899aabbccddee04df", "112233445566778899aabbccddee04df") + sstore("112233445566778899aabbccddee04e0", "112233445566778899aabbccddee04e0") + sstore("112233445566778899aabbccddee04e1", "112233445566778899aabbccddee04e1") + sstore("112233445566778899aabbccddee04e2", "112233445566778899aabbccddee04e2") + sstore("112233445566778899aabbccddee04e3", "112233445566778899aabbccddee04e3") + sstore("112233445566778899aabbccddee04e4", "112233445566778899aabbccddee04e4") + sstore("112233445566778899aabbccddee04e5", "112233445566778899aabbccddee04e5") + sstore("112233445566778899aabbccddee04e6", "112233445566778899aabbccddee04e6") + sstore("112233445566778899aabbccddee04e7", "112233445566778899aabbccddee04e7") + sstore("112233445566778899aabbccddee04e8", "112233445566778899aabbccddee04e8") + sstore("112233445566778899aabbccddee04e9", "112233445566778899aabbccddee04e9") + sstore("112233445566778899aabbccddee04ea", "112233445566778899aabbccddee04ea") + sstore("112233445566778899aabbccddee04eb", "112233445566778899aabbccddee04eb") + sstore("112233445566778899aabbccddee04ec", "112233445566778899aabbccddee04ec") + sstore("112233445566778899aabbccddee04ed", "112233445566778899aabbccddee04ed") + sstore("112233445566778899aabbccddee04ee", "112233445566778899aabbccddee04ee") + sstore("112233445566778899aabbccddee04ef", "112233445566778899aabbccddee04ef") + sstore("112233445566778899aabbccddee04f0", "112233445566778899aabbccddee04f0") + sstore("112233445566778899aabbccddee04f1", "112233445566778899aabbccddee04f1") + sstore("112233445566778899aabbccddee04f2", "112233445566778899aabbccddee04f2") + sstore("112233445566778899aabbccddee04f3", "112233445566778899aabbccddee04f3") + sstore("112233445566778899aabbccddee04f4", "112233445566778899aabbccddee04f4") + sstore("112233445566778899aabbccddee04f5", "112233445566778899aabbccddee04f5") + sstore("112233445566778899aabbccddee04f6", "112233445566778899aabbccddee04f6") + sstore("112233445566778899aabbccddee04f7", "112233445566778899aabbccddee04f7") + sstore("112233445566778899aabbccddee04f8", "112233445566778899aabbccddee04f8") + sstore("112233445566778899aabbccddee04f9", "112233445566778899aabbccddee04f9") + sstore("112233445566778899aabbccddee04fa", "112233445566778899aabbccddee04fa") + sstore("112233445566778899aabbccddee04fb", "112233445566778899aabbccddee04fb") + sstore("112233445566778899aabbccddee04fc", "112233445566778899aabbccddee04fc") + sstore("112233445566778899aabbccddee04fd", "112233445566778899aabbccddee04fd") + sstore("112233445566778899aabbccddee04fe", "112233445566778899aabbccddee04fe") + sstore("112233445566778899aabbccddee04ff", "112233445566778899aabbccddee04ff") + sstore("112233445566778899aabbccddee0500", "112233445566778899aabbccddee0500") + sstore("112233445566778899aabbccddee0501", "112233445566778899aabbccddee0501") + sstore("112233445566778899aabbccddee0502", "112233445566778899aabbccddee0502") + sstore("112233445566778899aabbccddee0503", "112233445566778899aabbccddee0503") + sstore("112233445566778899aabbccddee0504", "112233445566778899aabbccddee0504") + sstore("112233445566778899aabbccddee0505", "112233445566778899aabbccddee0505") + sstore("112233445566778899aabbccddee0506", "112233445566778899aabbccddee0506") + sstore("112233445566778899aabbccddee0507", "112233445566778899aabbccddee0507") + sstore("112233445566778899aabbccddee0508", "112233445566778899aabbccddee0508") + sstore("112233445566778899aabbccddee0509", "112233445566778899aabbccddee0509") + sstore("112233445566778899aabbccddee050a", "112233445566778899aabbccddee050a") + sstore("112233445566778899aabbccddee050b", "112233445566778899aabbccddee050b") + sstore("112233445566778899aabbccddee050c", "112233445566778899aabbccddee050c") + sstore("112233445566778899aabbccddee050d", "112233445566778899aabbccddee050d") + sstore("112233445566778899aabbccddee050e", "112233445566778899aabbccddee050e") + sstore("112233445566778899aabbccddee050f", "112233445566778899aabbccddee050f") + sstore("112233445566778899aabbccddee0510", "112233445566778899aabbccddee0510") + sstore("112233445566778899aabbccddee0511", "112233445566778899aabbccddee0511") + sstore("112233445566778899aabbccddee0512", "112233445566778899aabbccddee0512") + sstore("112233445566778899aabbccddee0513", "112233445566778899aabbccddee0513") + sstore("112233445566778899aabbccddee0514", "112233445566778899aabbccddee0514") + sstore("112233445566778899aabbccddee0515", "112233445566778899aabbccddee0515") + sstore("112233445566778899aabbccddee0516", "112233445566778899aabbccddee0516") + sstore("112233445566778899aabbccddee0517", "112233445566778899aabbccddee0517") + sstore("112233445566778899aabbccddee0518", "112233445566778899aabbccddee0518") + sstore("112233445566778899aabbccddee0519", "112233445566778899aabbccddee0519") + sstore("112233445566778899aabbccddee051a", "112233445566778899aabbccddee051a") + sstore("112233445566778899aabbccddee051b", "112233445566778899aabbccddee051b") + sstore("112233445566778899aabbccddee051c", "112233445566778899aabbccddee051c") + sstore("112233445566778899aabbccddee051d", "112233445566778899aabbccddee051d") + sstore("112233445566778899aabbccddee051e", "112233445566778899aabbccddee051e") + sstore("112233445566778899aabbccddee051f", "112233445566778899aabbccddee051f") + sstore("112233445566778899aabbccddee0520", "112233445566778899aabbccddee0520") + sstore("112233445566778899aabbccddee0521", "112233445566778899aabbccddee0521") + sstore("112233445566778899aabbccddee0522", "112233445566778899aabbccddee0522") + sstore("112233445566778899aabbccddee0523", "112233445566778899aabbccddee0523") + sstore("112233445566778899aabbccddee0524", "112233445566778899aabbccddee0524") + sstore("112233445566778899aabbccddee0525", "112233445566778899aabbccddee0525") + sstore("112233445566778899aabbccddee0526", "112233445566778899aabbccddee0526") + sstore("112233445566778899aabbccddee0527", "112233445566778899aabbccddee0527") + sstore("112233445566778899aabbccddee0528", "112233445566778899aabbccddee0528") + sstore("112233445566778899aabbccddee0529", "112233445566778899aabbccddee0529") + sstore("112233445566778899aabbccddee052a", "112233445566778899aabbccddee052a") + sstore("112233445566778899aabbccddee052b", "112233445566778899aabbccddee052b") + sstore("112233445566778899aabbccddee052c", "112233445566778899aabbccddee052c") + sstore("112233445566778899aabbccddee052d", "112233445566778899aabbccddee052d") + sstore("112233445566778899aabbccddee052e", "112233445566778899aabbccddee052e") + sstore("112233445566778899aabbccddee052f", "112233445566778899aabbccddee052f") + sstore("112233445566778899aabbccddee0530", "112233445566778899aabbccddee0530") + sstore("112233445566778899aabbccddee0531", "112233445566778899aabbccddee0531") + sstore("112233445566778899aabbccddee0532", "112233445566778899aabbccddee0532") + sstore("112233445566778899aabbccddee0533", "112233445566778899aabbccddee0533") + sstore("112233445566778899aabbccddee0534", "112233445566778899aabbccddee0534") + sstore("112233445566778899aabbccddee0535", "112233445566778899aabbccddee0535") + sstore("112233445566778899aabbccddee0536", "112233445566778899aabbccddee0536") + sstore("112233445566778899aabbccddee0537", "112233445566778899aabbccddee0537") + sstore("112233445566778899aabbccddee0538", "112233445566778899aabbccddee0538") + sstore("112233445566778899aabbccddee0539", "112233445566778899aabbccddee0539") + sstore("112233445566778899aabbccddee053a", "112233445566778899aabbccddee053a") + sstore("112233445566778899aabbccddee053b", "112233445566778899aabbccddee053b") + sstore("112233445566778899aabbccddee053c", "112233445566778899aabbccddee053c") + sstore("112233445566778899aabbccddee053d", "112233445566778899aabbccddee053d") + sstore("112233445566778899aabbccddee053e", "112233445566778899aabbccddee053e") + sstore("112233445566778899aabbccddee053f", "112233445566778899aabbccddee053f") + sstore("112233445566778899aabbccddee0540", "112233445566778899aabbccddee0540") + sstore("112233445566778899aabbccddee0541", "112233445566778899aabbccddee0541") + sstore("112233445566778899aabbccddee0542", "112233445566778899aabbccddee0542") + sstore("112233445566778899aabbccddee0543", "112233445566778899aabbccddee0543") + sstore("112233445566778899aabbccddee0544", "112233445566778899aabbccddee0544") + sstore("112233445566778899aabbccddee0545", "112233445566778899aabbccddee0545") + sstore("112233445566778899aabbccddee0546", "112233445566778899aabbccddee0546") + sstore("112233445566778899aabbccddee0547", "112233445566778899aabbccddee0547") + sstore("112233445566778899aabbccddee0548", "112233445566778899aabbccddee0548") + sstore("112233445566778899aabbccddee0549", "112233445566778899aabbccddee0549") + sstore("112233445566778899aabbccddee054a", "112233445566778899aabbccddee054a") + sstore("112233445566778899aabbccddee054b", "112233445566778899aabbccddee054b") + sstore("112233445566778899aabbccddee054c", "112233445566778899aabbccddee054c") + sstore("112233445566778899aabbccddee054d", "112233445566778899aabbccddee054d") + sstore("112233445566778899aabbccddee054e", "112233445566778899aabbccddee054e") + sstore("112233445566778899aabbccddee054f", "112233445566778899aabbccddee054f") + sstore("112233445566778899aabbccddee0550", "112233445566778899aabbccddee0550") + sstore("112233445566778899aabbccddee0551", "112233445566778899aabbccddee0551") + sstore("112233445566778899aabbccddee0552", "112233445566778899aabbccddee0552") + sstore("112233445566778899aabbccddee0553", "112233445566778899aabbccddee0553") + sstore("112233445566778899aabbccddee0554", "112233445566778899aabbccddee0554") + sstore("112233445566778899aabbccddee0555", "112233445566778899aabbccddee0555") + sstore("112233445566778899aabbccddee0556", "112233445566778899aabbccddee0556") + sstore("112233445566778899aabbccddee0557", "112233445566778899aabbccddee0557") + sstore("112233445566778899aabbccddee0558", "112233445566778899aabbccddee0558") + sstore("112233445566778899aabbccddee0559", "112233445566778899aabbccddee0559") + sstore("112233445566778899aabbccddee055a", "112233445566778899aabbccddee055a") + sstore("112233445566778899aabbccddee055b", "112233445566778899aabbccddee055b") + sstore("112233445566778899aabbccddee055c", "112233445566778899aabbccddee055c") + sstore("112233445566778899aabbccddee055d", "112233445566778899aabbccddee055d") + sstore("112233445566778899aabbccddee055e", "112233445566778899aabbccddee055e") + sstore("112233445566778899aabbccddee055f", "112233445566778899aabbccddee055f") + sstore("112233445566778899aabbccddee0560", "112233445566778899aabbccddee0560") + sstore("112233445566778899aabbccddee0561", "112233445566778899aabbccddee0561") + sstore("112233445566778899aabbccddee0562", "112233445566778899aabbccddee0562") + sstore("112233445566778899aabbccddee0563", "112233445566778899aabbccddee0563") + sstore("112233445566778899aabbccddee0564", "112233445566778899aabbccddee0564") + sstore("112233445566778899aabbccddee0565", "112233445566778899aabbccddee0565") + sstore("112233445566778899aabbccddee0566", "112233445566778899aabbccddee0566") + sstore("112233445566778899aabbccddee0567", "112233445566778899aabbccddee0567") + sstore("112233445566778899aabbccddee0568", "112233445566778899aabbccddee0568") + sstore("112233445566778899aabbccddee0569", "112233445566778899aabbccddee0569") + sstore("112233445566778899aabbccddee056a", "112233445566778899aabbccddee056a") + sstore("112233445566778899aabbccddee056b", "112233445566778899aabbccddee056b") + sstore("112233445566778899aabbccddee056c", "112233445566778899aabbccddee056c") + sstore("112233445566778899aabbccddee056d", "112233445566778899aabbccddee056d") + sstore("112233445566778899aabbccddee056e", "112233445566778899aabbccddee056e") + sstore("112233445566778899aabbccddee056f", "112233445566778899aabbccddee056f") + sstore("112233445566778899aabbccddee0570", "112233445566778899aabbccddee0570") + sstore("112233445566778899aabbccddee0571", "112233445566778899aabbccddee0571") + sstore("112233445566778899aabbccddee0572", "112233445566778899aabbccddee0572") + sstore("112233445566778899aabbccddee0573", "112233445566778899aabbccddee0573") + sstore("112233445566778899aabbccddee0574", "112233445566778899aabbccddee0574") + sstore("112233445566778899aabbccddee0575", "112233445566778899aabbccddee0575") + sstore("112233445566778899aabbccddee0576", "112233445566778899aabbccddee0576") + sstore("112233445566778899aabbccddee0577", "112233445566778899aabbccddee0577") + sstore("112233445566778899aabbccddee0578", "112233445566778899aabbccddee0578") + sstore("112233445566778899aabbccddee0579", "112233445566778899aabbccddee0579") + sstore("112233445566778899aabbccddee057a", "112233445566778899aabbccddee057a") + sstore("112233445566778899aabbccddee057b", "112233445566778899aabbccddee057b") + sstore("112233445566778899aabbccddee057c", "112233445566778899aabbccddee057c") + sstore("112233445566778899aabbccddee057d", "112233445566778899aabbccddee057d") + sstore("112233445566778899aabbccddee057e", "112233445566778899aabbccddee057e") + sstore("112233445566778899aabbccddee057f", "112233445566778899aabbccddee057f") + sstore("112233445566778899aabbccddee0580", "112233445566778899aabbccddee0580") + sstore("112233445566778899aabbccddee0581", "112233445566778899aabbccddee0581") + sstore("112233445566778899aabbccddee0582", "112233445566778899aabbccddee0582") + sstore("112233445566778899aabbccddee0583", "112233445566778899aabbccddee0583") + sstore("112233445566778899aabbccddee0584", "112233445566778899aabbccddee0584") + sstore("112233445566778899aabbccddee0585", "112233445566778899aabbccddee0585") + sstore("112233445566778899aabbccddee0586", "112233445566778899aabbccddee0586") + sstore("112233445566778899aabbccddee0587", "112233445566778899aabbccddee0587") + sstore("112233445566778899aabbccddee0588", "112233445566778899aabbccddee0588") + sstore("112233445566778899aabbccddee0589", "112233445566778899aabbccddee0589") + sstore("112233445566778899aabbccddee058a", "112233445566778899aabbccddee058a") + sstore("112233445566778899aabbccddee058b", "112233445566778899aabbccddee058b") + sstore("112233445566778899aabbccddee058c", "112233445566778899aabbccddee058c") + sstore("112233445566778899aabbccddee058d", "112233445566778899aabbccddee058d") + sstore("112233445566778899aabbccddee058e", "112233445566778899aabbccddee058e") + sstore("112233445566778899aabbccddee058f", "112233445566778899aabbccddee058f") + sstore("112233445566778899aabbccddee0590", "112233445566778899aabbccddee0590") + sstore("112233445566778899aabbccddee0591", "112233445566778899aabbccddee0591") + sstore("112233445566778899aabbccddee0592", "112233445566778899aabbccddee0592") + sstore("112233445566778899aabbccddee0593", "112233445566778899aabbccddee0593") + sstore("112233445566778899aabbccddee0594", "112233445566778899aabbccddee0594") + sstore("112233445566778899aabbccddee0595", "112233445566778899aabbccddee0595") + sstore("112233445566778899aabbccddee0596", "112233445566778899aabbccddee0596") + sstore("112233445566778899aabbccddee0597", "112233445566778899aabbccddee0597") + sstore("112233445566778899aabbccddee0598", "112233445566778899aabbccddee0598") + sstore("112233445566778899aabbccddee0599", "112233445566778899aabbccddee0599") + sstore("112233445566778899aabbccddee059a", "112233445566778899aabbccddee059a") + sstore("112233445566778899aabbccddee059b", "112233445566778899aabbccddee059b") + sstore("112233445566778899aabbccddee059c", "112233445566778899aabbccddee059c") + sstore("112233445566778899aabbccddee059d", "112233445566778899aabbccddee059d") + sstore("112233445566778899aabbccddee059e", "112233445566778899aabbccddee059e") + sstore("112233445566778899aabbccddee059f", "112233445566778899aabbccddee059f") + sstore("112233445566778899aabbccddee05a0", "112233445566778899aabbccddee05a0") + sstore("112233445566778899aabbccddee05a1", "112233445566778899aabbccddee05a1") + sstore("112233445566778899aabbccddee05a2", "112233445566778899aabbccddee05a2") + sstore("112233445566778899aabbccddee05a3", "112233445566778899aabbccddee05a3") + sstore("112233445566778899aabbccddee05a4", "112233445566778899aabbccddee05a4") + sstore("112233445566778899aabbccddee05a5", "112233445566778899aabbccddee05a5") + sstore("112233445566778899aabbccddee05a6", "112233445566778899aabbccddee05a6") + sstore("112233445566778899aabbccddee05a7", "112233445566778899aabbccddee05a7") + sstore("112233445566778899aabbccddee05a8", "112233445566778899aabbccddee05a8") + sstore("112233445566778899aabbccddee05a9", "112233445566778899aabbccddee05a9") + sstore("112233445566778899aabbccddee05aa", "112233445566778899aabbccddee05aa") + sstore("112233445566778899aabbccddee05ab", "112233445566778899aabbccddee05ab") + sstore("112233445566778899aabbccddee05ac", "112233445566778899aabbccddee05ac") + sstore("112233445566778899aabbccddee05ad", "112233445566778899aabbccddee05ad") + sstore("112233445566778899aabbccddee05ae", "112233445566778899aabbccddee05ae") + sstore("112233445566778899aabbccddee05af", "112233445566778899aabbccddee05af") + sstore("112233445566778899aabbccddee05b0", "112233445566778899aabbccddee05b0") + sstore("112233445566778899aabbccddee05b1", "112233445566778899aabbccddee05b1") + sstore("112233445566778899aabbccddee05b2", "112233445566778899aabbccddee05b2") + sstore("112233445566778899aabbccddee05b3", "112233445566778899aabbccddee05b3") + sstore("112233445566778899aabbccddee05b4", "112233445566778899aabbccddee05b4") + sstore("112233445566778899aabbccddee05b5", "112233445566778899aabbccddee05b5") + sstore("112233445566778899aabbccddee05b6", "112233445566778899aabbccddee05b6") + sstore("112233445566778899aabbccddee05b7", "112233445566778899aabbccddee05b7") + sstore("112233445566778899aabbccddee05b8", "112233445566778899aabbccddee05b8") + sstore("112233445566778899aabbccddee05b9", "112233445566778899aabbccddee05b9") + sstore("112233445566778899aabbccddee05ba", "112233445566778899aabbccddee05ba") + sstore("112233445566778899aabbccddee05bb", "112233445566778899aabbccddee05bb") + sstore("112233445566778899aabbccddee05bc", "112233445566778899aabbccddee05bc") + sstore("112233445566778899aabbccddee05bd", "112233445566778899aabbccddee05bd") + sstore("112233445566778899aabbccddee05be", "112233445566778899aabbccddee05be") + sstore("112233445566778899aabbccddee05bf", "112233445566778899aabbccddee05bf") + sstore("112233445566778899aabbccddee05c0", "112233445566778899aabbccddee05c0") + sstore("112233445566778899aabbccddee05c1", "112233445566778899aabbccddee05c1") + sstore("112233445566778899aabbccddee05c2", "112233445566778899aabbccddee05c2") + sstore("112233445566778899aabbccddee05c3", "112233445566778899aabbccddee05c3") + sstore("112233445566778899aabbccddee05c4", "112233445566778899aabbccddee05c4") + sstore("112233445566778899aabbccddee05c5", "112233445566778899aabbccddee05c5") + sstore("112233445566778899aabbccddee05c6", "112233445566778899aabbccddee05c6") + sstore("112233445566778899aabbccddee05c7", "112233445566778899aabbccddee05c7") + sstore("112233445566778899aabbccddee05c8", "112233445566778899aabbccddee05c8") + sstore("112233445566778899aabbccddee05c9", "112233445566778899aabbccddee05c9") + sstore("112233445566778899aabbccddee05ca", "112233445566778899aabbccddee05ca") + sstore("112233445566778899aabbccddee05cb", "112233445566778899aabbccddee05cb") + sstore("112233445566778899aabbccddee05cc", "112233445566778899aabbccddee05cc") + sstore("112233445566778899aabbccddee05cd", "112233445566778899aabbccddee05cd") + sstore("112233445566778899aabbccddee05ce", "112233445566778899aabbccddee05ce") + sstore("112233445566778899aabbccddee05cf", "112233445566778899aabbccddee05cf") + sstore("112233445566778899aabbccddee05d0", "112233445566778899aabbccddee05d0") + sstore("112233445566778899aabbccddee05d1", "112233445566778899aabbccddee05d1") + sstore("112233445566778899aabbccddee05d2", "112233445566778899aabbccddee05d2") + sstore("112233445566778899aabbccddee05d3", "112233445566778899aabbccddee05d3") + sstore("112233445566778899aabbccddee05d4", "112233445566778899aabbccddee05d4") + sstore("112233445566778899aabbccddee05d5", "112233445566778899aabbccddee05d5") + sstore("112233445566778899aabbccddee05d6", "112233445566778899aabbccddee05d6") + sstore("112233445566778899aabbccddee05d7", "112233445566778899aabbccddee05d7") + sstore("112233445566778899aabbccddee05d8", "112233445566778899aabbccddee05d8") + sstore("112233445566778899aabbccddee05d9", "112233445566778899aabbccddee05d9") + sstore("112233445566778899aabbccddee05da", "112233445566778899aabbccddee05da") + sstore("112233445566778899aabbccddee05db", "112233445566778899aabbccddee05db") + sstore("112233445566778899aabbccddee05dc", "112233445566778899aabbccddee05dc") + sstore("112233445566778899aabbccddee05dd", "112233445566778899aabbccddee05dd") + sstore("112233445566778899aabbccddee05de", "112233445566778899aabbccddee05de") + sstore("112233445566778899aabbccddee05df", "112233445566778899aabbccddee05df") + sstore("112233445566778899aabbccddee05e0", "112233445566778899aabbccddee05e0") + sstore("112233445566778899aabbccddee05e1", "112233445566778899aabbccddee05e1") + sstore("112233445566778899aabbccddee05e2", "112233445566778899aabbccddee05e2") + sstore("112233445566778899aabbccddee05e3", "112233445566778899aabbccddee05e3") + sstore("112233445566778899aabbccddee05e4", "112233445566778899aabbccddee05e4") + sstore("112233445566778899aabbccddee05e5", "112233445566778899aabbccddee05e5") + sstore("112233445566778899aabbccddee05e6", "112233445566778899aabbccddee05e6") + sstore("112233445566778899aabbccddee05e7", "112233445566778899aabbccddee05e7") + sstore("112233445566778899aabbccddee05e8", "112233445566778899aabbccddee05e8") + sstore("112233445566778899aabbccddee05e9", "112233445566778899aabbccddee05e9") + sstore("112233445566778899aabbccddee05ea", "112233445566778899aabbccddee05ea") + sstore("112233445566778899aabbccddee05eb", "112233445566778899aabbccddee05eb") + sstore("112233445566778899aabbccddee05ec", "112233445566778899aabbccddee05ec") + sstore("112233445566778899aabbccddee05ed", "112233445566778899aabbccddee05ed") + sstore("112233445566778899aabbccddee05ee", "112233445566778899aabbccddee05ee") + sstore("112233445566778899aabbccddee05ef", "112233445566778899aabbccddee05ef") + sstore("112233445566778899aabbccddee05f0", "112233445566778899aabbccddee05f0") + sstore("112233445566778899aabbccddee05f1", "112233445566778899aabbccddee05f1") + sstore("112233445566778899aabbccddee05f2", "112233445566778899aabbccddee05f2") + sstore("112233445566778899aabbccddee05f3", "112233445566778899aabbccddee05f3") + sstore("112233445566778899aabbccddee05f4", "112233445566778899aabbccddee05f4") + sstore("112233445566778899aabbccddee05f5", "112233445566778899aabbccddee05f5") + sstore("112233445566778899aabbccddee05f6", "112233445566778899aabbccddee05f6") + sstore("112233445566778899aabbccddee05f7", "112233445566778899aabbccddee05f7") + sstore("112233445566778899aabbccddee05f8", "112233445566778899aabbccddee05f8") + sstore("112233445566778899aabbccddee05f9", "112233445566778899aabbccddee05f9") + sstore("112233445566778899aabbccddee05fa", "112233445566778899aabbccddee05fa") + sstore("112233445566778899aabbccddee05fb", "112233445566778899aabbccddee05fb") + sstore("112233445566778899aabbccddee05fc", "112233445566778899aabbccddee05fc") + sstore("112233445566778899aabbccddee05fd", "112233445566778899aabbccddee05fd") + sstore("112233445566778899aabbccddee05fe", "112233445566778899aabbccddee05fe") + sstore("112233445566778899aabbccddee05ff", "112233445566778899aabbccddee05ff") + sstore("112233445566778899aabbccddee0600", "112233445566778899aabbccddee0600") + sstore("112233445566778899aabbccddee0601", "112233445566778899aabbccddee0601") + sstore("112233445566778899aabbccddee0602", "112233445566778899aabbccddee0602") + sstore("112233445566778899aabbccddee0603", "112233445566778899aabbccddee0603") + sstore("112233445566778899aabbccddee0604", "112233445566778899aabbccddee0604") + sstore("112233445566778899aabbccddee0605", "112233445566778899aabbccddee0605") + sstore("112233445566778899aabbccddee0606", "112233445566778899aabbccddee0606") + sstore("112233445566778899aabbccddee0607", "112233445566778899aabbccddee0607") + sstore("112233445566778899aabbccddee0608", "112233445566778899aabbccddee0608") + sstore("112233445566778899aabbccddee0609", "112233445566778899aabbccddee0609") + sstore("112233445566778899aabbccddee060a", "112233445566778899aabbccddee060a") + sstore("112233445566778899aabbccddee060b", "112233445566778899aabbccddee060b") + sstore("112233445566778899aabbccddee060c", "112233445566778899aabbccddee060c") + sstore("112233445566778899aabbccddee060d", "112233445566778899aabbccddee060d") + sstore("112233445566778899aabbccddee060e", "112233445566778899aabbccddee060e") + sstore("112233445566778899aabbccddee060f", "112233445566778899aabbccddee060f") + sstore("112233445566778899aabbccddee0610", "112233445566778899aabbccddee0610") + sstore("112233445566778899aabbccddee0611", "112233445566778899aabbccddee0611") + sstore("112233445566778899aabbccddee0612", "112233445566778899aabbccddee0612") + sstore("112233445566778899aabbccddee0613", "112233445566778899aabbccddee0613") + sstore("112233445566778899aabbccddee0614", "112233445566778899aabbccddee0614") + sstore("112233445566778899aabbccddee0615", "112233445566778899aabbccddee0615") + sstore("112233445566778899aabbccddee0616", "112233445566778899aabbccddee0616") + sstore("112233445566778899aabbccddee0617", "112233445566778899aabbccddee0617") + sstore("112233445566778899aabbccddee0618", "112233445566778899aabbccddee0618") + sstore("112233445566778899aabbccddee0619", "112233445566778899aabbccddee0619") + sstore("112233445566778899aabbccddee061a", "112233445566778899aabbccddee061a") + sstore("112233445566778899aabbccddee061b", "112233445566778899aabbccddee061b") + sstore("112233445566778899aabbccddee061c", "112233445566778899aabbccddee061c") + sstore("112233445566778899aabbccddee061d", "112233445566778899aabbccddee061d") + sstore("112233445566778899aabbccddee061e", "112233445566778899aabbccddee061e") + sstore("112233445566778899aabbccddee061f", "112233445566778899aabbccddee061f") + sstore("112233445566778899aabbccddee0620", "112233445566778899aabbccddee0620") + sstore("112233445566778899aabbccddee0621", "112233445566778899aabbccddee0621") + sstore("112233445566778899aabbccddee0622", "112233445566778899aabbccddee0622") + sstore("112233445566778899aabbccddee0623", "112233445566778899aabbccddee0623") + sstore("112233445566778899aabbccddee0624", "112233445566778899aabbccddee0624") + sstore("112233445566778899aabbccddee0625", "112233445566778899aabbccddee0625") + sstore("112233445566778899aabbccddee0626", "112233445566778899aabbccddee0626") + sstore("112233445566778899aabbccddee0627", "112233445566778899aabbccddee0627") + sstore("112233445566778899aabbccddee0628", "112233445566778899aabbccddee0628") + sstore("112233445566778899aabbccddee0629", "112233445566778899aabbccddee0629") + sstore("112233445566778899aabbccddee062a", "112233445566778899aabbccddee062a") + sstore("112233445566778899aabbccddee062b", "112233445566778899aabbccddee062b") + sstore("112233445566778899aabbccddee062c", "112233445566778899aabbccddee062c") + sstore("112233445566778899aabbccddee062d", "112233445566778899aabbccddee062d") + sstore("112233445566778899aabbccddee062e", "112233445566778899aabbccddee062e") + sstore("112233445566778899aabbccddee062f", "112233445566778899aabbccddee062f") + sstore("112233445566778899aabbccddee0630", "112233445566778899aabbccddee0630") + sstore("112233445566778899aabbccddee0631", "112233445566778899aabbccddee0631") + sstore("112233445566778899aabbccddee0632", "112233445566778899aabbccddee0632") + sstore("112233445566778899aabbccddee0633", "112233445566778899aabbccddee0633") + sstore("112233445566778899aabbccddee0634", "112233445566778899aabbccddee0634") + sstore("112233445566778899aabbccddee0635", "112233445566778899aabbccddee0635") + sstore("112233445566778899aabbccddee0636", "112233445566778899aabbccddee0636") + sstore("112233445566778899aabbccddee0637", "112233445566778899aabbccddee0637") + sstore("112233445566778899aabbccddee0638", "112233445566778899aabbccddee0638") + sstore("112233445566778899aabbccddee0639", "112233445566778899aabbccddee0639") + sstore("112233445566778899aabbccddee063a", "112233445566778899aabbccddee063a") + sstore("112233445566778899aabbccddee063b", "112233445566778899aabbccddee063b") + sstore("112233445566778899aabbccddee063c", "112233445566778899aabbccddee063c") + sstore("112233445566778899aabbccddee063d", "112233445566778899aabbccddee063d") + sstore("112233445566778899aabbccddee063e", "112233445566778899aabbccddee063e") + sstore("112233445566778899aabbccddee063f", "112233445566778899aabbccddee063f") + sstore("112233445566778899aabbccddee0640", "112233445566778899aabbccddee0640") + sstore("112233445566778899aabbccddee0641", "112233445566778899aabbccddee0641") + sstore("112233445566778899aabbccddee0642", "112233445566778899aabbccddee0642") + sstore("112233445566778899aabbccddee0643", "112233445566778899aabbccddee0643") + sstore("112233445566778899aabbccddee0644", "112233445566778899aabbccddee0644") + sstore("112233445566778899aabbccddee0645", "112233445566778899aabbccddee0645") + sstore("112233445566778899aabbccddee0646", "112233445566778899aabbccddee0646") + sstore("112233445566778899aabbccddee0647", "112233445566778899aabbccddee0647") + sstore("112233445566778899aabbccddee0648", "112233445566778899aabbccddee0648") + sstore("112233445566778899aabbccddee0649", "112233445566778899aabbccddee0649") + sstore("112233445566778899aabbccddee064a", "112233445566778899aabbccddee064a") + sstore("112233445566778899aabbccddee064b", "112233445566778899aabbccddee064b") + sstore("112233445566778899aabbccddee064c", "112233445566778899aabbccddee064c") + sstore("112233445566778899aabbccddee064d", "112233445566778899aabbccddee064d") + sstore("112233445566778899aabbccddee064e", "112233445566778899aabbccddee064e") + sstore("112233445566778899aabbccddee064f", "112233445566778899aabbccddee064f") + sstore("112233445566778899aabbccddee0650", "112233445566778899aabbccddee0650") + sstore("112233445566778899aabbccddee0651", "112233445566778899aabbccddee0651") + sstore("112233445566778899aabbccddee0652", "112233445566778899aabbccddee0652") + sstore("112233445566778899aabbccddee0653", "112233445566778899aabbccddee0653") + sstore("112233445566778899aabbccddee0654", "112233445566778899aabbccddee0654") + sstore("112233445566778899aabbccddee0655", "112233445566778899aabbccddee0655") + sstore("112233445566778899aabbccddee0656", "112233445566778899aabbccddee0656") + sstore("112233445566778899aabbccddee0657", "112233445566778899aabbccddee0657") + sstore("112233445566778899aabbccddee0658", "112233445566778899aabbccddee0658") + sstore("112233445566778899aabbccddee0659", "112233445566778899aabbccddee0659") + sstore("112233445566778899aabbccddee065a", "112233445566778899aabbccddee065a") + sstore("112233445566778899aabbccddee065b", "112233445566778899aabbccddee065b") + sstore("112233445566778899aabbccddee065c", "112233445566778899aabbccddee065c") + sstore("112233445566778899aabbccddee065d", "112233445566778899aabbccddee065d") + sstore("112233445566778899aabbccddee065e", "112233445566778899aabbccddee065e") + sstore("112233445566778899aabbccddee065f", "112233445566778899aabbccddee065f") + sstore("112233445566778899aabbccddee0660", "112233445566778899aabbccddee0660") + sstore("112233445566778899aabbccddee0661", "112233445566778899aabbccddee0661") + sstore("112233445566778899aabbccddee0662", "112233445566778899aabbccddee0662") + sstore("112233445566778899aabbccddee0663", "112233445566778899aabbccddee0663") + sstore("112233445566778899aabbccddee0664", "112233445566778899aabbccddee0664") + sstore("112233445566778899aabbccddee0665", "112233445566778899aabbccddee0665") + sstore("112233445566778899aabbccddee0666", "112233445566778899aabbccddee0666") + sstore("112233445566778899aabbccddee0667", "112233445566778899aabbccddee0667") + sstore("112233445566778899aabbccddee0668", "112233445566778899aabbccddee0668") + sstore("112233445566778899aabbccddee0669", "112233445566778899aabbccddee0669") + sstore("112233445566778899aabbccddee066a", "112233445566778899aabbccddee066a") + sstore("112233445566778899aabbccddee066b", "112233445566778899aabbccddee066b") + sstore("112233445566778899aabbccddee066c", "112233445566778899aabbccddee066c") + sstore("112233445566778899aabbccddee066d", "112233445566778899aabbccddee066d") + sstore("112233445566778899aabbccddee066e", "112233445566778899aabbccddee066e") + sstore("112233445566778899aabbccddee066f", "112233445566778899aabbccddee066f") + sstore("112233445566778899aabbccddee0670", "112233445566778899aabbccddee0670") + sstore("112233445566778899aabbccddee0671", "112233445566778899aabbccddee0671") + sstore("112233445566778899aabbccddee0672", "112233445566778899aabbccddee0672") + sstore("112233445566778899aabbccddee0673", "112233445566778899aabbccddee0673") + sstore("112233445566778899aabbccddee0674", "112233445566778899aabbccddee0674") + sstore("112233445566778899aabbccddee0675", "112233445566778899aabbccddee0675") + sstore("112233445566778899aabbccddee0676", "112233445566778899aabbccddee0676") + sstore("112233445566778899aabbccddee0677", "112233445566778899aabbccddee0677") + sstore("112233445566778899aabbccddee0678", "112233445566778899aabbccddee0678") + sstore("112233445566778899aabbccddee0679", "112233445566778899aabbccddee0679") + sstore("112233445566778899aabbccddee067a", "112233445566778899aabbccddee067a") + sstore("112233445566778899aabbccddee067b", "112233445566778899aabbccddee067b") + sstore("112233445566778899aabbccddee067c", "112233445566778899aabbccddee067c") + sstore("112233445566778899aabbccddee067d", "112233445566778899aabbccddee067d") + sstore("112233445566778899aabbccddee067e", "112233445566778899aabbccddee067e") + sstore("112233445566778899aabbccddee067f", "112233445566778899aabbccddee067f") + sstore("112233445566778899aabbccddee0680", "112233445566778899aabbccddee0680") + sstore("112233445566778899aabbccddee0681", "112233445566778899aabbccddee0681") + sstore("112233445566778899aabbccddee0682", "112233445566778899aabbccddee0682") + sstore("112233445566778899aabbccddee0683", "112233445566778899aabbccddee0683") + sstore("112233445566778899aabbccddee0684", "112233445566778899aabbccddee0684") + sstore("112233445566778899aabbccddee0685", "112233445566778899aabbccddee0685") + sstore("112233445566778899aabbccddee0686", "112233445566778899aabbccddee0686") + sstore("112233445566778899aabbccddee0687", "112233445566778899aabbccddee0687") + sstore("112233445566778899aabbccddee0688", "112233445566778899aabbccddee0688") + sstore("112233445566778899aabbccddee0689", "112233445566778899aabbccddee0689") + sstore("112233445566778899aabbccddee068a", "112233445566778899aabbccddee068a") + sstore("112233445566778899aabbccddee068b", "112233445566778899aabbccddee068b") + sstore("112233445566778899aabbccddee068c", "112233445566778899aabbccddee068c") + sstore("112233445566778899aabbccddee068d", "112233445566778899aabbccddee068d") + sstore("112233445566778899aabbccddee068e", "112233445566778899aabbccddee068e") + sstore("112233445566778899aabbccddee068f", "112233445566778899aabbccddee068f") + sstore("112233445566778899aabbccddee0690", "112233445566778899aabbccddee0690") + sstore("112233445566778899aabbccddee0691", "112233445566778899aabbccddee0691") + sstore("112233445566778899aabbccddee0692", "112233445566778899aabbccddee0692") + sstore("112233445566778899aabbccddee0693", "112233445566778899aabbccddee0693") + sstore("112233445566778899aabbccddee0694", "112233445566778899aabbccddee0694") + sstore("112233445566778899aabbccddee0695", "112233445566778899aabbccddee0695") + sstore("112233445566778899aabbccddee0696", "112233445566778899aabbccddee0696") + sstore("112233445566778899aabbccddee0697", "112233445566778899aabbccddee0697") + sstore("112233445566778899aabbccddee0698", "112233445566778899aabbccddee0698") + sstore("112233445566778899aabbccddee0699", "112233445566778899aabbccddee0699") + sstore("112233445566778899aabbccddee069a", "112233445566778899aabbccddee069a") + sstore("112233445566778899aabbccddee069b", "112233445566778899aabbccddee069b") + sstore("112233445566778899aabbccddee069c", "112233445566778899aabbccddee069c") + sstore("112233445566778899aabbccddee069d", "112233445566778899aabbccddee069d") + sstore("112233445566778899aabbccddee069e", "112233445566778899aabbccddee069e") + sstore("112233445566778899aabbccddee069f", "112233445566778899aabbccddee069f") + sstore("112233445566778899aabbccddee06a0", "112233445566778899aabbccddee06a0") + sstore("112233445566778899aabbccddee06a1", "112233445566778899aabbccddee06a1") + sstore("112233445566778899aabbccddee06a2", "112233445566778899aabbccddee06a2") + sstore("112233445566778899aabbccddee06a3", "112233445566778899aabbccddee06a3") + sstore("112233445566778899aabbccddee06a4", "112233445566778899aabbccddee06a4") + sstore("112233445566778899aabbccddee06a5", "112233445566778899aabbccddee06a5") + sstore("112233445566778899aabbccddee06a6", "112233445566778899aabbccddee06a6") + sstore("112233445566778899aabbccddee06a7", "112233445566778899aabbccddee06a7") + sstore("112233445566778899aabbccddee06a8", "112233445566778899aabbccddee06a8") + sstore("112233445566778899aabbccddee06a9", "112233445566778899aabbccddee06a9") + sstore("112233445566778899aabbccddee06aa", "112233445566778899aabbccddee06aa") + sstore("112233445566778899aabbccddee06ab", "112233445566778899aabbccddee06ab") + sstore("112233445566778899aabbccddee06ac", "112233445566778899aabbccddee06ac") + sstore("112233445566778899aabbccddee06ad", "112233445566778899aabbccddee06ad") + sstore("112233445566778899aabbccddee06ae", "112233445566778899aabbccddee06ae") + sstore("112233445566778899aabbccddee06af", "112233445566778899aabbccddee06af") + sstore("112233445566778899aabbccddee06b0", "112233445566778899aabbccddee06b0") + sstore("112233445566778899aabbccddee06b1", "112233445566778899aabbccddee06b1") + sstore("112233445566778899aabbccddee06b2", "112233445566778899aabbccddee06b2") + sstore("112233445566778899aabbccddee06b3", "112233445566778899aabbccddee06b3") + sstore("112233445566778899aabbccddee06b4", "112233445566778899aabbccddee06b4") + sstore("112233445566778899aabbccddee06b5", "112233445566778899aabbccddee06b5") + sstore("112233445566778899aabbccddee06b6", "112233445566778899aabbccddee06b6") + sstore("112233445566778899aabbccddee06b7", "112233445566778899aabbccddee06b7") + sstore("112233445566778899aabbccddee06b8", "112233445566778899aabbccddee06b8") + sstore("112233445566778899aabbccddee06b9", "112233445566778899aabbccddee06b9") + sstore("112233445566778899aabbccddee06ba", "112233445566778899aabbccddee06ba") + sstore("112233445566778899aabbccddee06bb", "112233445566778899aabbccddee06bb") + sstore("112233445566778899aabbccddee06bc", "112233445566778899aabbccddee06bc") + sstore("112233445566778899aabbccddee06bd", "112233445566778899aabbccddee06bd") + sstore("112233445566778899aabbccddee06be", "112233445566778899aabbccddee06be") + sstore("112233445566778899aabbccddee06bf", "112233445566778899aabbccddee06bf") + sstore("112233445566778899aabbccddee06c0", "112233445566778899aabbccddee06c0") + sstore("112233445566778899aabbccddee06c1", "112233445566778899aabbccddee06c1") + sstore("112233445566778899aabbccddee06c2", "112233445566778899aabbccddee06c2") + sstore("112233445566778899aabbccddee06c3", "112233445566778899aabbccddee06c3") + sstore("112233445566778899aabbccddee06c4", "112233445566778899aabbccddee06c4") + sstore("112233445566778899aabbccddee06c5", "112233445566778899aabbccddee06c5") + sstore("112233445566778899aabbccddee06c6", "112233445566778899aabbccddee06c6") + sstore("112233445566778899aabbccddee06c7", "112233445566778899aabbccddee06c7") + sstore("112233445566778899aabbccddee06c8", "112233445566778899aabbccddee06c8") + sstore("112233445566778899aabbccddee06c9", "112233445566778899aabbccddee06c9") + sstore("112233445566778899aabbccddee06ca", "112233445566778899aabbccddee06ca") + sstore("112233445566778899aabbccddee06cb", "112233445566778899aabbccddee06cb") + sstore("112233445566778899aabbccddee06cc", "112233445566778899aabbccddee06cc") + sstore("112233445566778899aabbccddee06cd", "112233445566778899aabbccddee06cd") + sstore("112233445566778899aabbccddee06ce", "112233445566778899aabbccddee06ce") + sstore("112233445566778899aabbccddee06cf", "112233445566778899aabbccddee06cf") + sstore("112233445566778899aabbccddee06d0", "112233445566778899aabbccddee06d0") + sstore("112233445566778899aabbccddee06d1", "112233445566778899aabbccddee06d1") + sstore("112233445566778899aabbccddee06d2", "112233445566778899aabbccddee06d2") + sstore("112233445566778899aabbccddee06d3", "112233445566778899aabbccddee06d3") + sstore("112233445566778899aabbccddee06d4", "112233445566778899aabbccddee06d4") + sstore("112233445566778899aabbccddee06d5", "112233445566778899aabbccddee06d5") + sstore("112233445566778899aabbccddee06d6", "112233445566778899aabbccddee06d6") + sstore("112233445566778899aabbccddee06d7", "112233445566778899aabbccddee06d7") + sstore("112233445566778899aabbccddee06d8", "112233445566778899aabbccddee06d8") + sstore("112233445566778899aabbccddee06d9", "112233445566778899aabbccddee06d9") + sstore("112233445566778899aabbccddee06da", "112233445566778899aabbccddee06da") + sstore("112233445566778899aabbccddee06db", "112233445566778899aabbccddee06db") + sstore("112233445566778899aabbccddee06dc", "112233445566778899aabbccddee06dc") + sstore("112233445566778899aabbccddee06dd", "112233445566778899aabbccddee06dd") + sstore("112233445566778899aabbccddee06de", "112233445566778899aabbccddee06de") + sstore("112233445566778899aabbccddee06df", "112233445566778899aabbccddee06df") + sstore("112233445566778899aabbccddee06e0", "112233445566778899aabbccddee06e0") + sstore("112233445566778899aabbccddee06e1", "112233445566778899aabbccddee06e1") + sstore("112233445566778899aabbccddee06e2", "112233445566778899aabbccddee06e2") + sstore("112233445566778899aabbccddee06e3", "112233445566778899aabbccddee06e3") + sstore("112233445566778899aabbccddee06e4", "112233445566778899aabbccddee06e4") + sstore("112233445566778899aabbccddee06e5", "112233445566778899aabbccddee06e5") + sstore("112233445566778899aabbccddee06e6", "112233445566778899aabbccddee06e6") + sstore("112233445566778899aabbccddee06e7", "112233445566778899aabbccddee06e7") + sstore("112233445566778899aabbccddee06e8", "112233445566778899aabbccddee06e8") + sstore("112233445566778899aabbccddee06e9", "112233445566778899aabbccddee06e9") + sstore("112233445566778899aabbccddee06ea", "112233445566778899aabbccddee06ea") + sstore("112233445566778899aabbccddee06eb", "112233445566778899aabbccddee06eb") + sstore("112233445566778899aabbccddee06ec", "112233445566778899aabbccddee06ec") + sstore("112233445566778899aabbccddee06ed", "112233445566778899aabbccddee06ed") + sstore("112233445566778899aabbccddee06ee", "112233445566778899aabbccddee06ee") + sstore("112233445566778899aabbccddee06ef", "112233445566778899aabbccddee06ef") + sstore("112233445566778899aabbccddee06f0", "112233445566778899aabbccddee06f0") + sstore("112233445566778899aabbccddee06f1", "112233445566778899aabbccddee06f1") + sstore("112233445566778899aabbccddee06f2", "112233445566778899aabbccddee06f2") + sstore("112233445566778899aabbccddee06f3", "112233445566778899aabbccddee06f3") + sstore("112233445566778899aabbccddee06f4", "112233445566778899aabbccddee06f4") + sstore("112233445566778899aabbccddee06f5", "112233445566778899aabbccddee06f5") + sstore("112233445566778899aabbccddee06f6", "112233445566778899aabbccddee06f6") + sstore("112233445566778899aabbccddee06f7", "112233445566778899aabbccddee06f7") + sstore("112233445566778899aabbccddee06f8", "112233445566778899aabbccddee06f8") + sstore("112233445566778899aabbccddee06f9", "112233445566778899aabbccddee06f9") + sstore("112233445566778899aabbccddee06fa", "112233445566778899aabbccddee06fa") + sstore("112233445566778899aabbccddee06fb", "112233445566778899aabbccddee06fb") + sstore("112233445566778899aabbccddee06fc", "112233445566778899aabbccddee06fc") + sstore("112233445566778899aabbccddee06fd", "112233445566778899aabbccddee06fd") + sstore("112233445566778899aabbccddee06fe", "112233445566778899aabbccddee06fe") + sstore("112233445566778899aabbccddee06ff", "112233445566778899aabbccddee06ff") + sstore("112233445566778899aabbccddee0700", "112233445566778899aabbccddee0700") + sstore("112233445566778899aabbccddee0701", "112233445566778899aabbccddee0701") + sstore("112233445566778899aabbccddee0702", "112233445566778899aabbccddee0702") + sstore("112233445566778899aabbccddee0703", "112233445566778899aabbccddee0703") + sstore("112233445566778899aabbccddee0704", "112233445566778899aabbccddee0704") + sstore("112233445566778899aabbccddee0705", "112233445566778899aabbccddee0705") + sstore("112233445566778899aabbccddee0706", "112233445566778899aabbccddee0706") + sstore("112233445566778899aabbccddee0707", "112233445566778899aabbccddee0707") + sstore("112233445566778899aabbccddee0708", "112233445566778899aabbccddee0708") + sstore("112233445566778899aabbccddee0709", "112233445566778899aabbccddee0709") + sstore("112233445566778899aabbccddee070a", "112233445566778899aabbccddee070a") + sstore("112233445566778899aabbccddee070b", "112233445566778899aabbccddee070b") + sstore("112233445566778899aabbccddee070c", "112233445566778899aabbccddee070c") + sstore("112233445566778899aabbccddee070d", "112233445566778899aabbccddee070d") + sstore("112233445566778899aabbccddee070e", "112233445566778899aabbccddee070e") + sstore("112233445566778899aabbccddee070f", "112233445566778899aabbccddee070f") + sstore("112233445566778899aabbccddee0710", "112233445566778899aabbccddee0710") + sstore("112233445566778899aabbccddee0711", "112233445566778899aabbccddee0711") + sstore("112233445566778899aabbccddee0712", "112233445566778899aabbccddee0712") + sstore("112233445566778899aabbccddee0713", "112233445566778899aabbccddee0713") + sstore("112233445566778899aabbccddee0714", "112233445566778899aabbccddee0714") + sstore("112233445566778899aabbccddee0715", "112233445566778899aabbccddee0715") + sstore("112233445566778899aabbccddee0716", "112233445566778899aabbccddee0716") + sstore("112233445566778899aabbccddee0717", "112233445566778899aabbccddee0717") + sstore("112233445566778899aabbccddee0718", "112233445566778899aabbccddee0718") + sstore("112233445566778899aabbccddee0719", "112233445566778899aabbccddee0719") + sstore("112233445566778899aabbccddee071a", "112233445566778899aabbccddee071a") + sstore("112233445566778899aabbccddee071b", "112233445566778899aabbccddee071b") + sstore("112233445566778899aabbccddee071c", "112233445566778899aabbccddee071c") + sstore("112233445566778899aabbccddee071d", "112233445566778899aabbccddee071d") + sstore("112233445566778899aabbccddee071e", "112233445566778899aabbccddee071e") + sstore("112233445566778899aabbccddee071f", "112233445566778899aabbccddee071f") + sstore("112233445566778899aabbccddee0720", "112233445566778899aabbccddee0720") + sstore("112233445566778899aabbccddee0721", "112233445566778899aabbccddee0721") + sstore("112233445566778899aabbccddee0722", "112233445566778899aabbccddee0722") + sstore("112233445566778899aabbccddee0723", "112233445566778899aabbccddee0723") + sstore("112233445566778899aabbccddee0724", "112233445566778899aabbccddee0724") + sstore("112233445566778899aabbccddee0725", "112233445566778899aabbccddee0725") + sstore("112233445566778899aabbccddee0726", "112233445566778899aabbccddee0726") + sstore("112233445566778899aabbccddee0727", "112233445566778899aabbccddee0727") + sstore("112233445566778899aabbccddee0728", "112233445566778899aabbccddee0728") + sstore("112233445566778899aabbccddee0729", "112233445566778899aabbccddee0729") + sstore("112233445566778899aabbccddee072a", "112233445566778899aabbccddee072a") + sstore("112233445566778899aabbccddee072b", "112233445566778899aabbccddee072b") + sstore("112233445566778899aabbccddee072c", "112233445566778899aabbccddee072c") + sstore("112233445566778899aabbccddee072d", "112233445566778899aabbccddee072d") + sstore("112233445566778899aabbccddee072e", "112233445566778899aabbccddee072e") + sstore("112233445566778899aabbccddee072f", "112233445566778899aabbccddee072f") + sstore("112233445566778899aabbccddee0730", "112233445566778899aabbccddee0730") + sstore("112233445566778899aabbccddee0731", "112233445566778899aabbccddee0731") + sstore("112233445566778899aabbccddee0732", "112233445566778899aabbccddee0732") + sstore("112233445566778899aabbccddee0733", "112233445566778899aabbccddee0733") + sstore("112233445566778899aabbccddee0734", "112233445566778899aabbccddee0734") + sstore("112233445566778899aabbccddee0735", "112233445566778899aabbccddee0735") + sstore("112233445566778899aabbccddee0736", "112233445566778899aabbccddee0736") + sstore("112233445566778899aabbccddee0737", "112233445566778899aabbccddee0737") + sstore("112233445566778899aabbccddee0738", "112233445566778899aabbccddee0738") + sstore("112233445566778899aabbccddee0739", "112233445566778899aabbccddee0739") + sstore("112233445566778899aabbccddee073a", "112233445566778899aabbccddee073a") + sstore("112233445566778899aabbccddee073b", "112233445566778899aabbccddee073b") + sstore("112233445566778899aabbccddee073c", "112233445566778899aabbccddee073c") + sstore("112233445566778899aabbccddee073d", "112233445566778899aabbccddee073d") + sstore("112233445566778899aabbccddee073e", "112233445566778899aabbccddee073e") + sstore("112233445566778899aabbccddee073f", "112233445566778899aabbccddee073f") + sstore("112233445566778899aabbccddee0740", "112233445566778899aabbccddee0740") + sstore("112233445566778899aabbccddee0741", "112233445566778899aabbccddee0741") + sstore("112233445566778899aabbccddee0742", "112233445566778899aabbccddee0742") + sstore("112233445566778899aabbccddee0743", "112233445566778899aabbccddee0743") + sstore("112233445566778899aabbccddee0744", "112233445566778899aabbccddee0744") + sstore("112233445566778899aabbccddee0745", "112233445566778899aabbccddee0745") + sstore("112233445566778899aabbccddee0746", "112233445566778899aabbccddee0746") + sstore("112233445566778899aabbccddee0747", "112233445566778899aabbccddee0747") + sstore("112233445566778899aabbccddee0748", "112233445566778899aabbccddee0748") + sstore("112233445566778899aabbccddee0749", "112233445566778899aabbccddee0749") + sstore("112233445566778899aabbccddee074a", "112233445566778899aabbccddee074a") + sstore("112233445566778899aabbccddee074b", "112233445566778899aabbccddee074b") + sstore("112233445566778899aabbccddee074c", "112233445566778899aabbccddee074c") + sstore("112233445566778899aabbccddee074d", "112233445566778899aabbccddee074d") + sstore("112233445566778899aabbccddee074e", "112233445566778899aabbccddee074e") + sstore("112233445566778899aabbccddee074f", "112233445566778899aabbccddee074f") + sstore("112233445566778899aabbccddee0750", "112233445566778899aabbccddee0750") + return(0, 32) +} +// ==== +// bytecodeFormat: >=EOFv1 +// ---- +// CodeGenerationError 2202: Code section too large for EOF. From 43b84f0f11012454f609242a89d342c8ea7b9b3a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Wed, 4 Dec 2024 03:25:52 +0100 Subject: [PATCH 0671/1022] Replace several unnecessary EOF validations with assertions --- libevmasm/Assembly.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libevmasm/Assembly.cpp b/libevmasm/Assembly.cpp index 1cd3e11faf8f..19201545e524 100644 --- a/libevmasm/Assembly.cpp +++ b/libevmasm/Assembly.cpp @@ -1521,10 +1521,9 @@ LinkerObject const& Assembly::assembleEOF() const auto const subIdsReplacements = findReferencedContainers(); auto const referencedSubIds = keys(subIdsReplacements); - solRequire(!m_codeSections.empty(), AssemblyException, "Expected at least one code section."); - solRequire( + solAssert(!m_codeSections.empty(), "Expected at least one code section."); + solAssert( m_codeSections.front().inputs == 0 && m_codeSections.front().outputs == 0 && m_codeSections.front().nonReturning, - AssemblyException, "Expected the first code section to have zero inputs and be non-returning." ); @@ -1660,7 +1659,8 @@ LinkerObject const& Assembly::assembleEOF() const solAssert(tagPos != std::numeric_limits::max(), "Reference to tag without position."); ptrdiff_t const relativeJumpOffset = static_cast(tagPos) - (static_cast(refPos) + 2); - solRequire(-0x8000 <= relativeJumpOffset && relativeJumpOffset <= 0x7FFF, AssemblyException, "Relative jump too far"); + // This cannot happen in practice because we'll run into section size limit first. + solAssert(-0x8000 <= relativeJumpOffset && relativeJumpOffset <= 0x7FFF, "Relative jump too far"); solAssert(relativeJumpOffset < -2 || 0 <= relativeJumpOffset, "Relative jump offset into immediate argument."); setBigEndianUint16(ret.bytecode, refPos, static_cast(static_cast(relativeJumpOffset))); } From b5fed832739adbd12cdaacd915f340b461238427 Mon Sep 17 00:00:00 2001 From: rodiazet Date: Mon, 16 Dec 2024 19:59:01 +0100 Subject: [PATCH 0672/1022] eof: Disable C++ tests which won't work for EOF. --- test/libevmasm/Assembler.cpp | 9 ++++++--- test/libevmasm/Optimiser.cpp | 8 +++++--- test/libsolidity/InlineAssembly.cpp | 8 +++++--- test/libsolidity/SolidityCompiler.cpp | 4 +++- test/libsolidity/ViewPureChecker.cpp | 3 ++- 5 files changed, 21 insertions(+), 11 deletions(-) diff --git a/test/libevmasm/Assembler.cpp b/test/libevmasm/Assembler.cpp index b1222b49d1ae..3a6383002dc3 100644 --- a/test/libevmasm/Assembler.cpp +++ b/test/libevmasm/Assembler.cpp @@ -37,6 +37,7 @@ using namespace solidity::langutil; using namespace solidity::evmasm; +using namespace solidity::test; using namespace std::string_literals; namespace solidity::frontend::test @@ -54,7 +55,7 @@ namespace BOOST_AUTO_TEST_SUITE(Assembler) -BOOST_AUTO_TEST_CASE(all_assembly_items) +BOOST_AUTO_TEST_CASE(all_assembly_items, *boost::unit_test::precondition(nonEOF())) { std::map indices = { { "root.asm", 0 }, @@ -216,7 +217,8 @@ BOOST_AUTO_TEST_CASE(all_assembly_items) BOOST_CHECK_EQUAL(util::jsonCompactPrint(_assembly.assemblyJSON(indices)), util::jsonCompactPrint(jsonValue)); } -BOOST_AUTO_TEST_CASE(immutables_and_its_source_maps) +// TODO: Implement EOF counterpart +BOOST_AUTO_TEST_CASE(immutables_and_its_source_maps, *boost::unit_test::precondition(nonEOF())) { EVMVersion evmVersion = solidity::test::CommonOptions::get().evmVersion(); // Tests for 1, 2, 3 number of immutables. @@ -301,7 +303,8 @@ BOOST_AUTO_TEST_CASE(immutables_and_its_source_maps) } } -BOOST_AUTO_TEST_CASE(immutable) +// TODO: Implement EOF counterpart +BOOST_AUTO_TEST_CASE(immutable, *boost::unit_test::precondition(nonEOF())) { std::map indices = { { "root.asm", 0 }, diff --git a/test/libevmasm/Optimiser.cpp b/test/libevmasm/Optimiser.cpp index 8ed413cfe199..a8e9afeaf2de 100644 --- a/test/libevmasm/Optimiser.cpp +++ b/test/libevmasm/Optimiser.cpp @@ -41,6 +41,7 @@ using namespace solidity::langutil; using namespace solidity::evmasm; +using namespace solidity::test; namespace solidity::frontend::test { @@ -1329,13 +1330,14 @@ BOOST_AUTO_TEST_CASE(jumpdest_removal) ); } -BOOST_AUTO_TEST_CASE(jumpdest_removal_subassemblies) +BOOST_AUTO_TEST_CASE(jumpdest_removal_subassemblies, *boost::unit_test::precondition(nonEOF())) { // This tests that tags from subassemblies are not removed // if they are referenced by a super-assembly. Furthermore, // tag unifications (due to block deduplication) is also // visible at the super-assembly. + solAssert(!solidity::test::CommonOptions::get().eofVersion().has_value()); Assembly::OptimiserSettings settings; settings.runInliner = false; settings.runJumpdestRemover = true; @@ -1346,8 +1348,8 @@ BOOST_AUTO_TEST_CASE(jumpdest_removal_subassemblies) settings.evmVersion = solidity::test::CommonOptions::get().evmVersion(); settings.expectedExecutionsPerDeployment = OptimiserSettings{}.expectedExecutionsPerDeployment; - Assembly main{settings.evmVersion, false, solidity::test::CommonOptions::get().eofVersion(), {}}; - AssemblyPointer sub = std::make_shared(settings.evmVersion, true, solidity::test::CommonOptions::get().eofVersion(), std::string{}); + Assembly main{settings.evmVersion, false, std::nullopt, {}}; + AssemblyPointer sub = std::make_shared(settings.evmVersion, true, std::nullopt, std::string{}); sub->append(u256(1)); auto t1 = sub->newTag(); diff --git a/test/libsolidity/InlineAssembly.cpp b/test/libsolidity/InlineAssembly.cpp index b3993e39f3df..fb08c667ce54 100644 --- a/test/libsolidity/InlineAssembly.cpp +++ b/test/libsolidity/InlineAssembly.cpp @@ -44,6 +44,7 @@ using namespace solidity::langutil; using namespace solidity::yul; +using namespace solidity::test; namespace solidity::frontend::test { @@ -294,7 +295,8 @@ BOOST_AUTO_TEST_CASE(designated_invalid_instruction) BOOST_CHECK(successAssemble("{ invalid() }")); } -BOOST_AUTO_TEST_CASE(inline_assembly_shadowed_instruction_declaration) +// TODO: Implement EOF counterpart +BOOST_AUTO_TEST_CASE(inline_assembly_shadowed_instruction_declaration, *boost::unit_test::precondition(nonEOF())) { CHECK_ASSEMBLE_ERROR("{ let gas := 1 }", ParserError, "Cannot use builtin"); } @@ -333,14 +335,14 @@ BOOST_AUTO_TEST_CASE(returndatacopy) BOOST_CHECK(successAssemble("{ returndatacopy(0, 32, 64) }")); } -BOOST_AUTO_TEST_CASE(staticcall) +BOOST_AUTO_TEST_CASE(staticcall, *boost::unit_test::precondition(nonEOF())) { if (!solidity::test::CommonOptions::get().evmVersion().hasStaticCall()) return; BOOST_CHECK(successAssemble("{ pop(staticcall(10000, 0x123, 64, 0x10, 128, 0x10)) }")); } -BOOST_AUTO_TEST_CASE(create2) +BOOST_AUTO_TEST_CASE(create2, *boost::unit_test::precondition(nonEOF())) { if (!solidity::test::CommonOptions::get().evmVersion().hasCreate2()) return; diff --git a/test/libsolidity/SolidityCompiler.cpp b/test/libsolidity/SolidityCompiler.cpp index 7cb95a99d0bc..79d838349af9 100644 --- a/test/libsolidity/SolidityCompiler.cpp +++ b/test/libsolidity/SolidityCompiler.cpp @@ -24,6 +24,7 @@ #include +using namespace solidity::test; namespace solidity::frontend::test { @@ -42,7 +43,8 @@ class SolidityCompilerFixture: protected AnalysisFramework BOOST_FIXTURE_TEST_SUITE(SolidityCompiler, SolidityCompilerFixture) -BOOST_AUTO_TEST_CASE(does_not_include_creation_time_only_internal_functions) +// TODO: Implement EOF counterpart +BOOST_AUTO_TEST_CASE(does_not_include_creation_time_only_internal_functions, *boost::unit_test::precondition(nonEOF())) { char const* sourceCode = R"( contract C { diff --git a/test/libsolidity/ViewPureChecker.cpp b/test/libsolidity/ViewPureChecker.cpp index 3d0e024da83b..ac220283a8e6 100644 --- a/test/libsolidity/ViewPureChecker.cpp +++ b/test/libsolidity/ViewPureChecker.cpp @@ -28,6 +28,7 @@ #include using namespace solidity::langutil; +using namespace solidity::test; namespace solidity::frontend::test { @@ -133,7 +134,7 @@ BOOST_AUTO_TEST_CASE(address_staticcall) } -BOOST_AUTO_TEST_CASE(assembly_staticcall) +BOOST_AUTO_TEST_CASE(assembly_staticcall, *boost::unit_test::precondition(nonEOF())) { std::string text = R"( contract C { From 10a1d516f8cd3a3c4d659a0a98f33cd6e2bc6797 Mon Sep 17 00:00:00 2001 From: rodiazet Date: Thu, 19 Dec 2024 10:10:21 +0100 Subject: [PATCH 0673/1022] eof: Re-enable test disabled in `soltest.sh` --- .circleci/soltest.sh | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/.circleci/soltest.sh b/.circleci/soltest.sh index 71c2a952adac..318192de4443 100755 --- a/.circleci/soltest.sh +++ b/.circleci/soltest.sh @@ -45,17 +45,6 @@ IFS=" " read -r -a SOLTEST_FLAGS <<< "$SOLTEST_FLAGS" # TODO: [EOF] These won't pass on EOF yet. Reenable them when the implementation is complete. EOF_EXCLUDES=( - --run_test='!Assembler/all_assembly_items' - --run_test='!Assembler/immutable' - --run_test='!Assembler/immutables_and_its_source_maps' - --run_test='!Optimiser/jumpdest_removal_subassemblies' - --run_test='!Optimiser/jumpdest_removal_subassemblies/*' - --run_test='!SolidityCompiler/does_not_include_creation_time_only_internal_functions' - --run_test='!SolidityInlineAssembly/Analysis/create2' - --run_test='!SolidityInlineAssembly/Analysis/inline_assembly_shadowed_instruction_declaration' - --run_test='!SolidityInlineAssembly/Analysis/large_constant' - --run_test='!SolidityInlineAssembly/Analysis/staticcall' - --run_test='!ViewPureChecker/assembly_staticcall' --run_test='!yulStackLayout/literal_loop' ) From cb4899a0def8b135b5056a1f7b48f8ea926103af Mon Sep 17 00:00:00 2001 From: rodiazet Date: Thu, 19 Dec 2024 21:46:41 +0100 Subject: [PATCH 0674/1022] eof: Disable `smtCheckeTests` when compiling to EOF. --- test/libsolidity/SMTCheckerTest.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/libsolidity/SMTCheckerTest.cpp b/test/libsolidity/SMTCheckerTest.cpp index c25025ccf77c..96a9538f1b4e 100644 --- a/test/libsolidity/SMTCheckerTest.cpp +++ b/test/libsolidity/SMTCheckerTest.cpp @@ -136,6 +136,10 @@ SMTCheckerTest::SMTCheckerTest(std::string const& _filename): auto const& bmcLoopIterations = m_reader.sizetSetting("BMCLoopIterations", 1); m_modelCheckerSettings.bmcLoopIterations = std::optional{bmcLoopIterations}; + + // TODO: Enable EOF testing when EOF gets stable and smtCheckerTest starts using IR. + if (CommonOptions::get().eofVersion().has_value()) + m_shouldRun = false; } void SMTCheckerTest::setupCompiler(CompilerStack& _compiler) From f7b86bb4c550eff9bb6309c06bc5eaf0f0fc2b1d Mon Sep 17 00:00:00 2001 From: Gaetan Lepage Date: Tue, 31 Dec 2024 13:50:00 +0100 Subject: [PATCH 0675/1022] Fix build with GCC 14 --- test/yulPhaser/Chromosome.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/yulPhaser/Chromosome.cpp b/test/yulPhaser/Chromosome.cpp index da109086a916..881f70007374 100644 --- a/test/yulPhaser/Chromosome.cpp +++ b/test/yulPhaser/Chromosome.cpp @@ -85,8 +85,8 @@ BOOST_AUTO_TEST_CASE(makeRandom_should_use_every_possible_step_with_the_same_pro const double expectedValue = double(stepIndices.size() - 1) / 2.0; const double variance = double(stepIndices.size() * stepIndices.size() - 1) / 12.0; - BOOST_TEST(abs(mean(samples) - expectedValue) < expectedValue * relativeTolerance); - BOOST_TEST(abs(meanSquaredError(samples, expectedValue) - variance) < variance * relativeTolerance); + BOOST_TEST(fabs(mean(samples) - expectedValue) < expectedValue * relativeTolerance); + BOOST_TEST(fabs(meanSquaredError(samples, expectedValue) - variance) < variance * relativeTolerance); } BOOST_AUTO_TEST_CASE(constructor_should_store_genes) @@ -159,8 +159,8 @@ BOOST_AUTO_TEST_CASE(randomOptimisationStep_should_return_each_step_with_same_pr const double expectedValue = double(stepIndices.size() - 1) / 2.0; const double variance = double(stepIndices.size() * stepIndices.size() - 1) / 12.0; - BOOST_TEST(abs(mean(samples) - expectedValue) < expectedValue * relativeTolerance); - BOOST_TEST(abs(meanSquaredError(samples, expectedValue) - variance) < variance * relativeTolerance); + BOOST_TEST(fabs(mean(samples) - expectedValue) < expectedValue * relativeTolerance); + BOOST_TEST(fabs(meanSquaredError(samples, expectedValue) - variance) < variance * relativeTolerance); } BOOST_AUTO_TEST_CASE(stepsToGenes_should_translate_optimisation_step_names_to_abbreviations) From ac4d267f8154677f66af4d33f98f233699db1fb7 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Mon, 6 Jan 2025 10:38:14 +0100 Subject: [PATCH 0676/1022] Adapts to new Boost download location --- .circleci/osx_install_dependencies.sh | 2 +- scripts/docker/buildpack-deps/Dockerfile.emscripten | 4 ++-- scripts/docker/buildpack-deps/Dockerfile.ubuntu.clang.ossfuzz | 4 ++-- scripts/install_deps.ps1 | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.circleci/osx_install_dependencies.sh b/.circleci/osx_install_dependencies.sh index c606913e4e93..f618bd9d3e70 100755 --- a/.circleci/osx_install_dependencies.sh +++ b/.circleci/osx_install_dependencies.sh @@ -66,7 +66,7 @@ then boost_version="1.84.0" boost_package="boost_${boost_version//./_}.tar.bz2" boost_dir="boost_${boost_version//./_}" - wget "https://boostorg.jfrog.io/artifactory/main/release/$boost_version/source/$boost_package" + wget "https://archives.boost.io/release/$boost_version/source/$boost_package" tar xf "$boost_package" rm "$boost_package" cd "$boost_dir" diff --git a/scripts/docker/buildpack-deps/Dockerfile.emscripten b/scripts/docker/buildpack-deps/Dockerfile.emscripten index 8bfb9c51a0dc..d8eb9a903f52 100644 --- a/scripts/docker/buildpack-deps/Dockerfile.emscripten +++ b/scripts/docker/buildpack-deps/Dockerfile.emscripten @@ -33,7 +33,7 @@ # Using $(em-config CACHE)/sysroot/usr seems to work, though, and still has cmake find the # dependencies automatically. FROM emscripten/emsdk:3.1.19 AS base -LABEL version="19" +LABEL version="20" ADD emscripten.jam /usr/src RUN set -ex && \ @@ -70,7 +70,7 @@ RUN set -ex && \ # Install Boost RUN set -ex && \ cd /usr/src && \ - wget -q 'https://boostorg.jfrog.io/artifactory/main/release/1.75.0/source/boost_1_75_0.tar.bz2' -O boost.tar.bz2 && \ + wget -q 'https://archives.boost.io/release/1.75.0/source/boost_1_75_0.tar.bz2' -O boost.tar.bz2 && \ test "$(sha256sum boost.tar.bz2)" = "953db31e016db7bb207f11432bef7df100516eeb746843fa0486a222e3fd49cb boost.tar.bz2" && \ tar -xf boost.tar.bz2 && \ rm boost.tar.bz2 && \ diff --git a/scripts/docker/buildpack-deps/Dockerfile.ubuntu.clang.ossfuzz b/scripts/docker/buildpack-deps/Dockerfile.ubuntu.clang.ossfuzz index aae11521e50d..743d924d793e 100644 --- a/scripts/docker/buildpack-deps/Dockerfile.ubuntu.clang.ossfuzz +++ b/scripts/docker/buildpack-deps/Dockerfile.ubuntu.clang.ossfuzz @@ -22,7 +22,7 @@ # (c) 2016-2021 solidity contributors. #------------------------------------------------------------------------------ FROM gcr.io/oss-fuzz-base/base-clang:latest as base -LABEL version="7" +LABEL version="8" ARG DEBIAN_FRONTEND=noninteractive @@ -73,7 +73,7 @@ FROM base AS libraries # Boost RUN set -ex; \ cd /usr/src; \ - wget -q 'https://boostorg.jfrog.io/artifactory/main/release/1.74.0/source/boost_1_74_0.tar.bz2' -O boost.tar.bz2; \ + wget -q 'https://archives.boost.io/release/1.74.0/source/boost_1_74_0.tar.bz2' -O boost.tar.bz2; \ test "$(sha256sum boost.tar.bz2)" = "83bfc1507731a0906e387fc28b7ef5417d591429e51e788417fe9ff025e116b1 boost.tar.bz2" && \ tar -xf boost.tar.bz2; \ rm boost.tar.bz2; \ diff --git a/scripts/install_deps.ps1 b/scripts/install_deps.ps1 index 26a9e116f054..ad4f5bdadccc 100644 --- a/scripts/install_deps.ps1 +++ b/scripts/install_deps.ps1 @@ -16,7 +16,7 @@ if ( -not (Test-Path "$PSScriptRoot\..\deps\boost") ) { # FIXME: The default user agent results in Artifactory treating Invoke-WebRequest as a browser # and serving it a page that requires JavaScript. - Invoke-WebRequest -URI "https://boostorg.jfrog.io/artifactory/main/release/1.83.0/source/boost_1_83_0.zip" -OutFile boost.zip -UserAgent "" + Invoke-WebRequest -URI "https://archives.boost.io/release/1.83.0/source/boost_1_83_0.zip" -OutFile boost.zip -UserAgent "" if ((Get-FileHash boost.zip).Hash -ne "c86bd9d9eef795b4b0d3802279419fde5221922805b073b9bd822edecb1ca28e") { throw 'Downloaded Boost source package has wrong checksum.' } From 6af8becb47b131ae894fb66502fbe02922b0af35 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Mon, 6 Jan 2025 13:55:51 +0100 Subject: [PATCH 0677/1022] Update emscripten docker image version --- .circleci/config.yml | 4 ++-- scripts/build_emscripten.sh | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 542118f6deef..18dc57ebdbec 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -26,8 +26,8 @@ parameters: emscripten-docker-image: type: string # NOTE: Please remember to update the `scripts/build_emscripten.sh` whenever the hash of this image changes. - # solbuildpackpusher/solidity-buildpack-deps:emscripten-19 - default: "solbuildpackpusher/solidity-buildpack-deps@sha256:170b159c82ce70e639500551394460f01798c18a5e17b45ea91277b0cf8eae37" + # solbuildpackpusher/solidity-buildpack-deps:emscripten-20 + default: "solbuildpackpusher/solidity-buildpack-deps@sha256:98f963ed799a0d206ef8e7b5475f847e0dea53b7fdea9618bbc6106a62730bd2" evm-version: type: string default: cancun diff --git a/scripts/build_emscripten.sh b/scripts/build_emscripten.sh index a53393f1d34c..93556a557e09 100755 --- a/scripts/build_emscripten.sh +++ b/scripts/build_emscripten.sh @@ -33,9 +33,9 @@ if (( $# != 0 )); then params="$(printf "%q " "${@}")" fi -# solbuildpackpusher/solidity-buildpack-deps:emscripten-19 +# solbuildpackpusher/solidity-buildpack-deps:emscripten-20` # NOTE: Without `safe.directory` git would assume it's not safe to operate on /root/project since it's owned by a different user. # See https://github.blog/2022-04-12-git-security-vulnerability-announced/ docker run -v "$(pwd):/root/project" -w /root/project \ - solbuildpackpusher/solidity-buildpack-deps@sha256:170b159c82ce70e639500551394460f01798c18a5e17b45ea91277b0cf8eae37 \ + solbuildpackpusher/solidity-buildpack-deps@sha256:98f963ed799a0d206ef8e7b5475f847e0dea53b7fdea9618bbc6106a62730bd2 \ /bin/bash -c "git config --global --add safe.directory /root/project && ./scripts/ci/build_emscripten.sh ${params}" From 969c9ca39de8049988b1441ec35b09be48269668 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Mon, 6 Jan 2025 11:21:28 +0100 Subject: [PATCH 0678/1022] SSACFG liveness: Adds exit liveness info to livein --- libyul/backends/evm/SSACFGLiveness.cpp | 52 ++++++++------- .../standard_yul_cfg_json_export/output.json | 66 +++++++------------ .../strict_asm_yul_cfg_json_export/output | 15 ++--- test/cmdlineTests/yul_cfg_json_export/output | 66 +++++++------------ .../libyul/yulSSAControlFlowGraph/complex.yul | 14 ++-- .../yulSSAControlFlowGraph/complex2.yul | 14 ++-- .../yulSSAControlFlowGraph/nested_for.yul | 10 +-- .../nested_function.yul | 4 +- test/libyul/yulSSAControlFlowGraph/switch.yul | 4 +- 9 files changed, 102 insertions(+), 143 deletions(-) diff --git a/libyul/backends/evm/SSACFGLiveness.cpp b/libyul/backends/evm/SSACFGLiveness.cpp index 6ecd559ca806..aecaed6ffa18 100644 --- a/libyul/backends/evm/SSACFGLiveness.cpp +++ b/libyul/backends/evm/SSACFGLiveness.cpp @@ -89,23 +89,10 @@ void SSACFGLiveness::runDagDfs() if (!m_topologicalSort.backEdge(blockId, _successor)) live += m_liveIns[_successor.value] - m_cfg.block(_successor).phis; }); - util::GenericVisitor exitVisitor { - [](SSACFG::BasicBlock::MainExit const&) {}, - [&](SSACFG::BasicBlock::FunctionReturn const& _functionReturn) { - live += _functionReturn.returnValues | ranges::views::filter(literalsFilter(m_cfg)); - }, - [&](SSACFG::BasicBlock::JumpTable const& _jt) { - if (literalsFilter(m_cfg)(_jt.value)) - live.emplace(_jt.value); - }, - [](SSACFG::BasicBlock::Jump const&) {}, - [&](SSACFG::BasicBlock::ConditionalJump const& _conditionalJump) { - if (literalsFilter(m_cfg)(_conditionalJump.condition)) - live.emplace(_conditionalJump.condition); - }, - [](SSACFG::BasicBlock::Terminated const&) {} - }; - std::visit(exitVisitor, block.exit); + + if (std::holds_alternative(block.exit)) + live += std::get(block.exit).returnValues + | ranges::views::filter(literalsFilter(m_cfg)); // clean out unreachables live = live | ranges::views::filter([&](auto const& valueId) { return !std::holds_alternative(m_cfg.valueInfo(valueId)); }) | ranges::to; @@ -114,12 +101,33 @@ void SSACFGLiveness::runDagDfs() m_liveOuts[blockId.value] = live; // for each program point p in B, backwards, do: - for (auto const& op: block.operations | ranges::views::reverse) { - // remove variables defined at p from live - live -= op.outputs | ranges::views::filter(literalsFilter(m_cfg)) | ranges::to; - // add uses at p to live - live += op.inputs | ranges::views::filter(literalsFilter(m_cfg)) | ranges::to; + // add value ids to the live set that are used in exit blocks + util::GenericVisitor exitVisitor { + [](SSACFG::BasicBlock::MainExit const&) {}, + [&](SSACFG::BasicBlock::FunctionReturn const& _functionReturn) { + live += _functionReturn.returnValues | ranges::views::filter(literalsFilter(m_cfg)); + }, + [&](SSACFG::BasicBlock::JumpTable const& _jt) { + if (literalsFilter(m_cfg)(_jt.value)) + live.emplace(_jt.value); + }, + [](SSACFG::BasicBlock::Jump const&) {}, + [&](SSACFG::BasicBlock::ConditionalJump const& _conditionalJump) { + if (literalsFilter(m_cfg)(_conditionalJump.condition)) + live.emplace(_conditionalJump.condition); + }, + [](SSACFG::BasicBlock::Terminated const&) {} + }; + std::visit(exitVisitor, block.exit); + + for (auto const& op: block.operations | ranges::views::reverse) + { + // remove variables defined at p from live + live -= op.outputs | ranges::views::filter(literalsFilter(m_cfg)) | ranges::to; + // add uses at p to live + live += op.inputs | ranges::views::filter(literalsFilter(m_cfg)) | ranges::to; + } } // livein(b) <- live \cup PhiDefs(B) diff --git a/test/cmdlineTests/standard_yul_cfg_json_export/output.json b/test/cmdlineTests/standard_yul_cfg_json_export/output.json index bb13b3e91503..81c0e49e5930 100644 --- a/test/cmdlineTests/standard_yul_cfg_json_export/output.json +++ b/test/cmdlineTests/standard_yul_cfg_json_export/output.json @@ -45,8 +45,7 @@ "liveness": { "in": [], "out": [ - "v0", - "v2" + "v0" ] }, "type": "BuiltinCall" @@ -189,8 +188,7 @@ "liveness": { "in": [], "out": [ - "v0", - "v5" + "v0" ] }, "type": "BuiltinCall" @@ -262,8 +260,7 @@ "v0" ], "out": [ - "v0", - "v11" + "v0" ] }, "type": "BuiltinCall" @@ -306,8 +303,7 @@ "v0" ], "out": [ - "v0", - "v12" + "v0" ] }, "type": "BuiltinCall" @@ -365,8 +361,7 @@ "v0" ], "out": [ - "v0", - "v17" + "v0" ] }, "type": "BuiltinCall" @@ -497,8 +492,7 @@ "liveness": { "in": [], "out": [ - "v0", - "v2" + "v0" ] }, "type": "BuiltinCall" @@ -641,8 +635,7 @@ "liveness": { "in": [], "out": [ - "v0", - "v5" + "v0" ] }, "type": "BuiltinCall" @@ -714,8 +707,7 @@ "v0" ], "out": [ - "v0", - "v11" + "v0" ] }, "type": "BuiltinCall" @@ -758,8 +750,7 @@ "v0" ], "out": [ - "v0", - "v12" + "v0" ] }, "type": "BuiltinCall" @@ -817,8 +808,7 @@ "v0" ], "out": [ - "v0", - "v17" + "v0" ] }, "type": "BuiltinCall" @@ -913,8 +903,7 @@ "out": [ "v0", "v18", - "v24", - "v28" + "v24" ] }, "type": "BuiltinCall" @@ -1008,8 +997,7 @@ "v24" ], "out": [ - "v41", - "v42" + "v41" ] }, "type": "BuiltinCall" @@ -1166,8 +1154,7 @@ ], "out": [ "v46", - "v59", - "v60" + "v59" ] }, "type": "BuiltinCall" @@ -1242,8 +1229,7 @@ "v59" ], "out": [ - "v46", - "v59" + "v46" ] } }, @@ -1388,8 +1374,7 @@ "v46" ], "out": [ - "v46", - "v67" + "v46" ] }, "type": "BuiltinCall" @@ -1497,8 +1482,7 @@ "out": [ "v46", "v71", - "v77", - "v80" + "v77" ] }, "type": "BuiltinCall" @@ -1588,8 +1572,7 @@ "v77" ], "out": [ - "v46", - "v90" + "v46" ] }, "type": "BuiltinCall" @@ -1737,8 +1720,7 @@ "liveness": { "in": [], "out": [ - "v0", - "v2" + "v0" ] }, "type": "BuiltinCall" @@ -1881,8 +1863,7 @@ "liveness": { "in": [], "out": [ - "v0", - "v5" + "v0" ] }, "type": "BuiltinCall" @@ -1954,8 +1935,7 @@ "v0" ], "out": [ - "v0", - "v11" + "v0" ] }, "type": "BuiltinCall" @@ -1998,8 +1978,7 @@ "v0" ], "out": [ - "v0", - "v12" + "v0" ] }, "type": "BuiltinCall" @@ -2057,8 +2036,7 @@ "v0" ], "out": [ - "v0", - "v17" + "v0" ] }, "type": "BuiltinCall" diff --git a/test/cmdlineTests/strict_asm_yul_cfg_json_export/output b/test/cmdlineTests/strict_asm_yul_cfg_json_export/output index a65c164d631d..ac154fc16246 100644 --- a/test/cmdlineTests/strict_asm_yul_cfg_json_export/output +++ b/test/cmdlineTests/strict_asm_yul_cfg_json_export/output @@ -45,8 +45,7 @@ Yul Control Flow Graph: "liveness": { "in": [], "out": [ - "v0", - "v2" + "v0" ] }, "type": "BuiltinCall" @@ -189,8 +188,7 @@ Yul Control Flow Graph: "liveness": { "in": [], "out": [ - "v0", - "v5" + "v0" ] }, "type": "BuiltinCall" @@ -262,8 +260,7 @@ Yul Control Flow Graph: "v0" ], "out": [ - "v0", - "v11" + "v0" ] }, "type": "BuiltinCall" @@ -306,8 +303,7 @@ Yul Control Flow Graph: "v0" ], "out": [ - "v0", - "v12" + "v0" ] }, "type": "BuiltinCall" @@ -365,8 +361,7 @@ Yul Control Flow Graph: "v0" ], "out": [ - "v0", - "v17" + "v0" ] }, "type": "BuiltinCall" diff --git a/test/cmdlineTests/yul_cfg_json_export/output b/test/cmdlineTests/yul_cfg_json_export/output index f6f2ec6d8f42..dd4dece740a0 100644 --- a/test/cmdlineTests/yul_cfg_json_export/output +++ b/test/cmdlineTests/yul_cfg_json_export/output @@ -44,8 +44,7 @@ Yul Control Flow Graph: "liveness": { "in": [], "out": [ - "v0", - "v2" + "v0" ] }, "type": "BuiltinCall" @@ -188,8 +187,7 @@ Yul Control Flow Graph: "liveness": { "in": [], "out": [ - "v0", - "v5" + "v0" ] }, "type": "BuiltinCall" @@ -261,8 +259,7 @@ Yul Control Flow Graph: "v0" ], "out": [ - "v0", - "v11" + "v0" ] }, "type": "BuiltinCall" @@ -305,8 +302,7 @@ Yul Control Flow Graph: "v0" ], "out": [ - "v0", - "v12" + "v0" ] }, "type": "BuiltinCall" @@ -364,8 +360,7 @@ Yul Control Flow Graph: "v0" ], "out": [ - "v0", - "v17" + "v0" ] }, "type": "BuiltinCall" @@ -497,8 +492,7 @@ Yul Control Flow Graph: "liveness": { "in": [], "out": [ - "v0", - "v2" + "v0" ] }, "type": "BuiltinCall" @@ -641,8 +635,7 @@ Yul Control Flow Graph: "liveness": { "in": [], "out": [ - "v0", - "v5" + "v0" ] }, "type": "BuiltinCall" @@ -714,8 +707,7 @@ Yul Control Flow Graph: "v0" ], "out": [ - "v0", - "v11" + "v0" ] }, "type": "BuiltinCall" @@ -758,8 +750,7 @@ Yul Control Flow Graph: "v0" ], "out": [ - "v0", - "v12" + "v0" ] }, "type": "BuiltinCall" @@ -817,8 +808,7 @@ Yul Control Flow Graph: "v0" ], "out": [ - "v0", - "v17" + "v0" ] }, "type": "BuiltinCall" @@ -913,8 +903,7 @@ Yul Control Flow Graph: "out": [ "v0", "v18", - "v24", - "v28" + "v24" ] }, "type": "BuiltinCall" @@ -1008,8 +997,7 @@ Yul Control Flow Graph: "v24" ], "out": [ - "v41", - "v42" + "v41" ] }, "type": "BuiltinCall" @@ -1166,8 +1154,7 @@ Yul Control Flow Graph: ], "out": [ "v46", - "v59", - "v60" + "v59" ] }, "type": "BuiltinCall" @@ -1242,8 +1229,7 @@ Yul Control Flow Graph: "v59" ], "out": [ - "v46", - "v59" + "v46" ] } }, @@ -1388,8 +1374,7 @@ Yul Control Flow Graph: "v46" ], "out": [ - "v46", - "v67" + "v46" ] }, "type": "BuiltinCall" @@ -1497,8 +1482,7 @@ Yul Control Flow Graph: "out": [ "v46", "v71", - "v77", - "v80" + "v77" ] }, "type": "BuiltinCall" @@ -1588,8 +1572,7 @@ Yul Control Flow Graph: "v77" ], "out": [ - "v46", - "v90" + "v46" ] }, "type": "BuiltinCall" @@ -1737,8 +1720,7 @@ Yul Control Flow Graph: "liveness": { "in": [], "out": [ - "v0", - "v2" + "v0" ] }, "type": "BuiltinCall" @@ -1881,8 +1863,7 @@ Yul Control Flow Graph: "liveness": { "in": [], "out": [ - "v0", - "v5" + "v0" ] }, "type": "BuiltinCall" @@ -1954,8 +1935,7 @@ Yul Control Flow Graph: "v0" ], "out": [ - "v0", - "v11" + "v0" ] }, "type": "BuiltinCall" @@ -1998,8 +1978,7 @@ Yul Control Flow Graph: "v0" ], "out": [ - "v0", - "v12" + "v0" ] }, "type": "BuiltinCall" @@ -2057,8 +2036,7 @@ Yul Control Flow Graph: "v0" ], "out": [ - "v0", - "v17" + "v0" ] }, "type": "BuiltinCall" diff --git a/test/libyul/yulSSAControlFlowGraph/complex.yul b/test/libyul/yulSSAControlFlowGraph/complex.yul index 3f7f329a48d5..6fb0453c186b 100644 --- a/test/libyul/yulSSAControlFlowGraph/complex.yul +++ b/test/libyul/yulSSAControlFlowGraph/complex.yul @@ -69,7 +69,7 @@ // Block1_0Exit -> Block1_1 [style="solid"]; // Block1_1 [label="\ // Block 1; (1, max 17)\nLiveIn: v0,v1,v5\l\ -// LiveOut: v0,v1,v5,v6\l\nv5 := φ(\l\ +// LiveOut: v0,v1,v5\l\nv5 := φ(\l\ // Block 0 => 42,\l\ // Block 21 => v43\l\ // )\l\ @@ -81,7 +81,7 @@ // Block1_1Exit:1 -> Block1_2 [style="solid"]; // Block1_2 [label="\ // Block 2; (2, max 17)\nLiveIn: v0,v1,v5\l\ -// LiveOut: v0,v1,v5,v7,v8\l\nv7 := mload(v5)\l\ +// LiveOut: v0,v1,v5,v7\l\nv7 := mload(v5)\l\ // v8 := eq(0, v7)\l\ // "]; // Block1_2 -> Block1_2Exit; @@ -103,7 +103,7 @@ // Block1_6Exit -> Block1_4 [style="solid"]; // Block1_7 [label="\ // Block 7; (5, max 17)\nLiveIn: v0,v1,v5,v7\l\ -// LiveOut: v0,v1,v5,v7,v13\l\nv13 := eq(1, v7)\l\ +// LiveOut: v0,v1,v5,v7\l\nv13 := eq(1, v7)\l\ // "]; // Block1_7 -> Block1_7Exit; // Block1_7Exit [label="{ If v13 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; @@ -117,7 +117,7 @@ // Block1_9 -> Block1_9Exit; // Block1_10 [label="\ // Block 10; (7, max 17)\nLiveIn: v0,v1,v5,v7\l\ -// LiveOut: v0,v1,v5,v7,v20\l\nv20 := eq(2, v7)\l\ +// LiveOut: v0,v1,v5,v7\l\nv20 := eq(2, v7)\l\ // "]; // Block1_10 -> Block1_10Exit; // Block1_10Exit [label="{ If v20 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; @@ -132,7 +132,7 @@ // Block1_12 -> Block1_12Exit; // Block1_13 [label="\ // Block 13; (9, max 17)\nLiveIn: v0,v1,v5,v7\l\ -// LiveOut: v0,v1,v5,v25\l\nv25 := eq(3, v7)\l\ +// LiveOut: v0,v1,v5\l\nv25 := eq(3, v7)\l\ // "]; // Block1_13 -> Block1_13Exit; // Block1_13Exit [label="{ If v25 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; @@ -147,7 +147,7 @@ // Block1_15Exit -> Block1_5 [style="solid"]; // Block1_16 [label="\ // Block 16; (15, max 17)\nLiveIn: v0,v1,v5\l\ -// LiveOut: v0,v1,v5,v29\l\nv29 := mload(v1)\l\ +// LiveOut: v0,v1,v5\l\nv29 := mload(v1)\l\ // "]; // Block1_16 -> Block1_16Exit; // Block1_16Exit [label="{ If v29 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; @@ -175,7 +175,7 @@ // Block1_18Exit -> Block1_5 [style="solid"]; // Block1_3 [label="\ // Block 3; (12, max 14)\nLiveIn: v0,v1,v5\l\ -// LiveOut: v0,v1,v43,v44\l\nv43 := add(1, v5)\l\ +// LiveOut: v0,v1,v43\l\nv43 := add(1, v5)\l\ // v44 := calldataload(v43)\l\ // "]; // Block1_3 -> Block1_3Exit; diff --git a/test/libyul/yulSSAControlFlowGraph/complex2.yul b/test/libyul/yulSSAControlFlowGraph/complex2.yul index 6d801124cda3..c3ea8b94f8aa 100644 --- a/test/libyul/yulSSAControlFlowGraph/complex2.yul +++ b/test/libyul/yulSSAControlFlowGraph/complex2.yul @@ -85,7 +85,7 @@ // Block1_0Exit -> Block1_1 [style="solid"]; // Block1_1 [label="\ // Block 1; (1, max 17)\nLiveIn: v0,v1,v5\l\ -// LiveOut: v0,v1,v5,v6\l\nv5 := φ(\l\ +// LiveOut: v0,v1,v5\l\nv5 := φ(\l\ // Block 0 => 42,\l\ // Block 21 => v43\l\ // )\l\ @@ -97,7 +97,7 @@ // Block1_1Exit:1 -> Block1_2 [style="solid"]; // Block1_2 [label="\ // Block 2; (2, max 17)\nLiveIn: v0,v1,v5\l\ -// LiveOut: v0,v1,v5,v7,v8\l\nv7 := mload(v5)\l\ +// LiveOut: v0,v1,v5,v7\l\nv7 := mload(v5)\l\ // v8 := eq(0, v7)\l\ // "]; // Block1_2 -> Block1_2Exit; @@ -119,7 +119,7 @@ // Block1_6Exit -> Block1_4 [style="solid"]; // Block1_7 [label="\ // Block 7; (5, max 17)\nLiveIn: v0,v1,v5,v7\l\ -// LiveOut: v0,v1,v5,v7,v13\l\nv13 := eq(1, v7)\l\ +// LiveOut: v0,v1,v5,v7\l\nv13 := eq(1, v7)\l\ // "]; // Block1_7 -> Block1_7Exit; // Block1_7Exit [label="{ If v13 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; @@ -133,7 +133,7 @@ // Block1_9 -> Block1_9Exit; // Block1_10 [label="\ // Block 10; (7, max 17)\nLiveIn: v0,v1,v5,v7\l\ -// LiveOut: v0,v1,v5,v7,v20\l\nv20 := eq(2, v7)\l\ +// LiveOut: v0,v1,v5,v7\l\nv20 := eq(2, v7)\l\ // "]; // Block1_10 -> Block1_10Exit; // Block1_10Exit [label="{ If v20 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; @@ -148,7 +148,7 @@ // Block1_12 -> Block1_12Exit; // Block1_13 [label="\ // Block 13; (9, max 17)\nLiveIn: v0,v1,v5,v7\l\ -// LiveOut: v0,v1,v5,v25\l\nv25 := eq(3, v7)\l\ +// LiveOut: v0,v1,v5\l\nv25 := eq(3, v7)\l\ // "]; // Block1_13 -> Block1_13Exit; // Block1_13Exit [label="{ If v25 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; @@ -163,7 +163,7 @@ // Block1_15Exit -> Block1_5 [style="solid"]; // Block1_16 [label="\ // Block 16; (15, max 17)\nLiveIn: v0,v1,v5\l\ -// LiveOut: v0,v1,v5,v29\l\nv29 := mload(v1)\l\ +// LiveOut: v0,v1,v5\l\nv29 := mload(v1)\l\ // "]; // Block1_16 -> Block1_16Exit; // Block1_16Exit [label="{ If v29 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; @@ -191,7 +191,7 @@ // Block1_18Exit -> Block1_5 [style="solid"]; // Block1_3 [label="\ // Block 3; (12, max 14)\nLiveIn: v0,v1,v5\l\ -// LiveOut: v0,v1,v43,v44\l\nv43 := add(1, v5)\l\ +// LiveOut: v0,v1,v43\l\nv43 := add(1, v5)\l\ // v44 := calldataload(v43)\l\ // "]; // Block1_3 -> Block1_3Exit; diff --git a/test/libyul/yulSSAControlFlowGraph/nested_for.yul b/test/libyul/yulSSAControlFlowGraph/nested_for.yul index f816df462b91..b088e3b55ed8 100644 --- a/test/libyul/yulSSAControlFlowGraph/nested_for.yul +++ b/test/libyul/yulSSAControlFlowGraph/nested_for.yul @@ -33,7 +33,7 @@ // Block0_0Exit -> Block0_1 [style="solid"]; // Block0_1 [label="\ // Block 1; (1, max 24)\nLiveIn: v2\l\ -// LiveOut: v2,v3\l\nv2 := φ(\l\ +// LiveOut: v2\l\nv2 := φ(\l\ // Block 0 => 0,\l\ // Block 3 => v36\l\ // )\l\ @@ -56,7 +56,7 @@ // Block0_4 -> Block0_4Exit; // Block0_5 [label="\ // Block 5; (3, max 23)\nLiveIn: v2,v4\l\ -// LiveOut: v2,v4,v5\l\nv4 := φ(\l\ +// LiveOut: v2,v4\l\nv4 := φ(\l\ // Block 2 => 0,\l\ // Block 7 => v35\l\ // )\l\ @@ -80,7 +80,7 @@ // Block0_8Exit -> Block0_3 [style="solid"]; // Block0_9 [label="\ // Block 9; (5, max 21)\nLiveIn: v2,v4,v6\l\ -// LiveOut: v2,v4,v6,v7\l\nv6 := φ(\l\ +// LiveOut: v2,v4,v6\l\nv6 := φ(\l\ // Block 6 => 0,\l\ // Block 11 => v31\l\ // )\l\ @@ -132,7 +132,7 @@ // Block0_7Exit -> Block0_5 [style="dashed"]; // Block0_15 [label="\ // Block 15; (8, max 19)\nLiveIn: v2,v4,v6,v8\l\ -// LiveOut: v2,v4,v6,v8,v9\l\nv8 := φ(\l\ +// LiveOut: v2,v4,v6,v8\l\nv8 := φ(\l\ // Block 13 => 0,\l\ // Block 17 => v16\l\ // )\l\ @@ -171,7 +171,7 @@ // Block0_18Exit -> Block0_14 [style="solid"]; // Block0_21 [label="\ // Block 21; (14, max 19)\nLiveIn: v2,v4,v6,v19\l\ -// LiveOut: v2,v4,v6,v19,v20\l\nv19 := φ(\l\ +// LiveOut: v2,v4,v6,v19\l\nv19 := φ(\l\ // Block 19 => 0,\l\ // Block 23 => v26\l\ // )\l\ diff --git a/test/libyul/yulSSAControlFlowGraph/nested_function.yul b/test/libyul/yulSSAControlFlowGraph/nested_function.yul index 1263d4782db8..acda15ce81a5 100644 --- a/test/libyul/yulSSAControlFlowGraph/nested_function.yul +++ b/test/libyul/yulSSAControlFlowGraph/nested_function.yul @@ -103,7 +103,7 @@ // FunctionEntry_cycle1_0 -> Block7_0; // Block7_0 [label="\ // Block 0; (0, max 2)\nLiveIn: \l\ -// LiveOut: v2\l\nv2 := mload(3)\l\ +// LiveOut: \l\nv2 := mload(3)\l\ // "]; // Block7_0 -> Block7_0Exit; // Block7_0Exit [label="{ If v2 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; @@ -130,7 +130,7 @@ // FunctionEntry_cycle2_0 -> Block8_0; // Block8_0 [label="\ // Block 0; (0, max 2)\nLiveIn: \l\ -// LiveOut: v2\l\nv2 := mload(4)\l\ +// LiveOut: \l\nv2 := mload(4)\l\ // "]; // Block8_0 -> Block8_0Exit; // Block8_0Exit [label="{ If v2 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; diff --git a/test/libyul/yulSSAControlFlowGraph/switch.yul b/test/libyul/yulSSAControlFlowGraph/switch.yul index 91b3daeeeded..10573b012298 100644 --- a/test/libyul/yulSSAControlFlowGraph/switch.yul +++ b/test/libyul/yulSSAControlFlowGraph/switch.yul @@ -23,7 +23,7 @@ // Entry0 -> Block0_0; // Block0_0 [label="\ // Block 0; (0, max 5)\nLiveIn: \l\ -// LiveOut: v3,v4\l\nv1 := calldataload(3)\l\ +// LiveOut: v3\l\nv1 := calldataload(3)\l\ // v3 := sload(0)\l\ // v4 := eq(0, v3)\l\ // "]; @@ -40,7 +40,7 @@ // Block0_2Exit -> Block0_1 [style="solid"]; // Block0_3 [label="\ // Block 3; (3, max 5)\nLiveIn: v3\l\ -// LiveOut: v7\l\nv7 := eq(1, v3)\l\ +// LiveOut: \l\nv7 := eq(1, v3)\l\ // "]; // Block0_3 -> Block0_3Exit; // Block0_3Exit [label="{ If v7 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; From 9e9c29a1e920f956814132fd608861bf589aa75e Mon Sep 17 00:00:00 2001 From: r0qs Date: Wed, 8 Jan 2025 14:58:22 +0100 Subject: [PATCH 0679/1022] SSA CFG Exporter: fix subobjects placement in json exporter --- libyul/YulStack.cpp | 5 +- .../standard_yul_cfg_json_export/output.json | 3220 ++++++++--------- .../strict_asm_yul_cfg_json_export/output | 548 +-- test/cmdlineTests/yul_cfg_json_export/output | 3220 ++++++++--------- 4 files changed, 3497 insertions(+), 3496 deletions(-) diff --git a/libyul/YulStack.cpp b/libyul/YulStack.cpp index 03e22c8d1a80..aa8a328204d2 100644 --- a/libyul/YulStack.cpp +++ b/libyul/YulStack.cpp @@ -409,7 +409,7 @@ Json YulStack::cfgJson() const subObjectsJson[subObject->name] = exportCFGFromObject(*subObject); subObjectsJson["type"] = "subObject"; if (!subObject->subObjects.empty()) - subObjectsJson["subObjects"] = exportCFGFromSubObjects(subObject->subObjects); + subObjectsJson[subObject->name]["subObjects"] = exportCFGFromSubObjects(subObject->subObjects); } return subObjectsJson; }; @@ -418,7 +418,8 @@ Json YulStack::cfgJson() const Json jsonObject = Json::object(); jsonObject[object.name] = exportCFGFromObject(object); jsonObject["type"] = "Object"; - jsonObject["subObjects"] = exportCFGFromSubObjects(object.subObjects); + if (!object.subObjects.empty()) + jsonObject[object.name]["subObjects"] = exportCFGFromSubObjects(object.subObjects); return jsonObject; } diff --git a/test/cmdlineTests/standard_yul_cfg_json_export/output.json b/test/cmdlineTests/standard_yul_cfg_json_export/output.json index 81c0e49e5930..303d51bbbbf4 100644 --- a/test/cmdlineTests/standard_yul_cfg_json_export/output.json +++ b/test/cmdlineTests/standard_yul_cfg_json_export/output.json @@ -124,326 +124,326 @@ "type": "BuiltinCall" } ], - "functions": {} - }, - "subObjects": { - "C_19_deployed": { - "blocks": [ - { - "exit": { - "cond": "v5", - "targets": [ - "Block2", - "Block1" - ], - "type": "ConditionalJump" - }, - "id": "Block0", - "instructions": [ - { - "builtinArgs": [ - "0x80" + "functions": {}, + "subObjects": { + "C_19_deployed": { + "blocks": [ + { + "exit": { + "cond": "v5", + "targets": [ + "Block2", + "Block1" ], + "type": "ConditionalJump" + }, + "id": "Block0", + "instructions": [ + { + "builtinArgs": [ + "0x80" + ], + "in": [], + "op": "memoryguard", + "out": [ + "v0" + ] + }, + { + "in": [ + "v0", + "0x40" + ], + "op": "mstore", + "out": [] + }, + { + "in": [], + "op": "calldatasize", + "out": [ + "v3" + ] + }, + { + "in": [ + "0x04", + "v3" + ], + "op": "lt", + "out": [ + "v4" + ] + }, + { + "in": [ + "v4" + ], + "op": "iszero", + "out": [ + "v5" + ] + } + ], + "liveness": { "in": [], - "op": "memoryguard", "out": [ "v0" ] }, - { - "in": [ - "v0", - "0x40" - ], - "op": "mstore", - "out": [] + "type": "BuiltinCall" + }, + { + "exit": { + "type": "Terminated" }, - { + "id": "Block2", + "instructions": [ + { + "in": [ + "0x00", + "0x00" + ], + "op": "revert", + "out": [] + } + ], + "liveness": { "in": [], - "op": "calldatasize", - "out": [ - "v3" - ] + "out": [] }, - { - "in": [ - "0x04", - "v3" + "type": "BuiltinCall" + }, + { + "exit": { + "cond": "v11", + "targets": [ + "Block4", + "Block3" ], - "op": "lt", - "out": [ - "v4" - ] + "type": "ConditionalJump" }, - { + "id": "Block1", + "instructions": [ + { + "in": [ + "0x00" + ], + "op": "calldataload", + "out": [ + "v7" + ] + }, + { + "in": [ + "v7", + "0xe0" + ], + "op": "shr", + "out": [ + "v9" + ] + }, + { + "in": [ + "v9", + "0x26121ff0" + ], + "op": "eq", + "out": [ + "v11" + ] + } + ], + "liveness": { "in": [ - "v4" + "v0" ], - "op": "iszero", "out": [ - "v5" + "v0" ] - } - ], - "liveness": { - "in": [], - "out": [ - "v0" - ] - }, - "type": "BuiltinCall" - }, - { - "exit": { - "type": "Terminated" + }, + "type": "BuiltinCall" }, - "id": "Block2", - "instructions": [ - { - "in": [ - "0x00", - "0x00" + { + "exit": { + "targets": [ + "Block2" ], - "op": "revert", + "type": "Jump" + }, + "id": "Block4", + "instructions": [], + "liveness": { + "in": [], "out": [] } - ], - "liveness": { - "in": [], - "out": [] }, - "type": "BuiltinCall" - }, - { - "exit": { - "cond": "v11", - "targets": [ - "Block4", - "Block3" + { + "exit": { + "cond": "v12", + "targets": [ + "Block6", + "Block5" + ], + "type": "ConditionalJump" + }, + "id": "Block3", + "instructions": [ + { + "in": [], + "op": "callvalue", + "out": [ + "v12" + ] + } ], - "type": "ConditionalJump" - }, - "id": "Block1", - "instructions": [ - { + "liveness": { "in": [ - "0x00" + "v0" ], - "op": "calldataload", "out": [ - "v7" + "v0" ] }, - { - "in": [ - "v7", - "0xe0" + "type": "BuiltinCall" + }, + { + "exit": { + "cond": "v17", + "targets": [ + "Block9", + "Block8" ], - "op": "shr", - "out": [ - "v9" - ] + "type": "ConditionalJump" }, - { + "id": "Block6", + "instructions": [ + { + "in": [ + "0x03" + ], + "op": "not", + "out": [ + "v14" + ] + }, + { + "in": [], + "op": "calldatasize", + "out": [ + "v15" + ] + }, + { + "in": [ + "v14", + "v15" + ], + "op": "add", + "out": [ + "v16" + ] + }, + { + "in": [ + "0x00", + "v16" + ], + "op": "slt", + "out": [ + "v17" + ] + } + ], + "liveness": { "in": [ - "v9", - "0x26121ff0" + "v0" ], - "op": "eq", "out": [ - "v11" + "v0" ] - } - ], - "liveness": { - "in": [ - "v0" - ], - "out": [ - "v0" - ] - }, - "type": "BuiltinCall" - }, - { - "exit": { - "targets": [ - "Block2" - ], - "type": "Jump" + }, + "type": "BuiltinCall" }, - "id": "Block4", - "instructions": [], - "liveness": { - "in": [], - "out": [] - } - }, - { - "exit": { - "cond": "v12", - "targets": [ - "Block6", - "Block5" + { + "exit": { + "type": "Terminated" + }, + "id": "Block5", + "instructions": [ + { + "in": [ + "0x00", + "0x00" + ], + "op": "revert", + "out": [] + } ], - "type": "ConditionalJump" - }, - "id": "Block3", - "instructions": [ - { + "liveness": { "in": [], - "op": "callvalue", - "out": [ - "v12" - ] - } - ], - "liveness": { - "in": [ - "v0" - ], - "out": [ - "v0" - ] + "out": [] + }, + "type": "BuiltinCall" }, - "type": "BuiltinCall" - }, - { - "exit": { - "cond": "v17", - "targets": [ - "Block9", - "Block8" + { + "exit": { + "type": "Terminated" + }, + "id": "Block9", + "instructions": [ + { + "in": [ + "0x2a", + "v0" + ], + "op": "mstore", + "out": [] + }, + { + "in": [ + "0x20", + "v0" + ], + "op": "return", + "out": [] + } ], - "type": "ConditionalJump" - }, - "id": "Block6", - "instructions": [ - { + "liveness": { "in": [ - "0x03" + "v0" ], - "op": "not", - "out": [ - "v14" - ] - }, - { - "in": [], - "op": "calldatasize", - "out": [ - "v15" - ] - }, - { - "in": [ - "v14", - "v15" - ], - "op": "add", - "out": [ - "v16" - ] - }, - { - "in": [ - "0x00", - "v16" - ], - "op": "slt", - "out": [ - "v17" - ] - } - ], - "liveness": { - "in": [ - "v0" - ], - "out": [ - "v0" - ] - }, - "type": "BuiltinCall" - }, - { - "exit": { - "type": "Terminated" - }, - "id": "Block5", - "instructions": [ - { - "in": [ - "0x00", - "0x00" - ], - "op": "revert", "out": [] - } - ], - "liveness": { - "in": [], - "out": [] - }, - "type": "BuiltinCall" - }, - { - "exit": { - "type": "Terminated" + }, + "type": "BuiltinCall" }, - "id": "Block9", - "instructions": [ - { - "in": [ - "0x2a", - "v0" - ], - "op": "mstore", - "out": [] + { + "exit": { + "type": "Terminated" }, - { - "in": [ - "0x20", - "v0" - ], - "op": "return", - "out": [] - } - ], - "liveness": { - "in": [ - "v0" + "id": "Block8", + "instructions": [ + { + "in": [ + "0x00", + "0x00" + ], + "op": "revert", + "out": [] + } ], - "out": [] - }, - "type": "BuiltinCall" - }, - { - "exit": { - "type": "Terminated" - }, - "id": "Block8", - "instructions": [ - { - "in": [ - "0x00", - "0x00" - ], - "op": "revert", + "liveness": { + "in": [], "out": [] - } - ], - "liveness": { - "in": [], - "out": [] - }, - "type": "BuiltinCall" - } - ], - "functions": {} - }, - "subObjects": {}, - "type": "subObject" + }, + "type": "BuiltinCall" + } + ], + "functions": {}, + "subObjects": {} + }, + "type": "subObject" + } }, "type": "Object" } @@ -571,1156 +571,1007 @@ "type": "BuiltinCall" } ], - "functions": {} - }, - "subObjects": { - "D_38_deployed": { - "blocks": [ - { - "exit": { - "cond": "v5", - "targets": [ - "Block2", - "Block1" - ], - "type": "ConditionalJump" - }, - "id": "Block0", - "instructions": [ - { - "builtinArgs": [ - "0x80" + "functions": {}, + "subObjects": { + "D_38_deployed": { + "blocks": [ + { + "exit": { + "cond": "v5", + "targets": [ + "Block2", + "Block1" ], + "type": "ConditionalJump" + }, + "id": "Block0", + "instructions": [ + { + "builtinArgs": [ + "0x80" + ], + "in": [], + "op": "memoryguard", + "out": [ + "v0" + ] + }, + { + "in": [ + "v0", + "0x40" + ], + "op": "mstore", + "out": [] + }, + { + "in": [], + "op": "calldatasize", + "out": [ + "v3" + ] + }, + { + "in": [ + "0x04", + "v3" + ], + "op": "lt", + "out": [ + "v4" + ] + }, + { + "in": [ + "v4" + ], + "op": "iszero", + "out": [ + "v5" + ] + } + ], + "liveness": { "in": [], - "op": "memoryguard", "out": [ "v0" ] }, - { - "in": [ - "v0", - "0x40" - ], - "op": "mstore", - "out": [] + "type": "BuiltinCall" + }, + { + "exit": { + "type": "Terminated" }, - { + "id": "Block2", + "instructions": [ + { + "in": [ + "0x00", + "0x00" + ], + "op": "revert", + "out": [] + } + ], + "liveness": { "in": [], - "op": "calldatasize", - "out": [ - "v3" - ] + "out": [] }, - { - "in": [ - "0x04", - "v3" + "type": "BuiltinCall" + }, + { + "exit": { + "cond": "v11", + "targets": [ + "Block4", + "Block3" ], - "op": "lt", - "out": [ - "v4" - ] + "type": "ConditionalJump" }, - { + "id": "Block1", + "instructions": [ + { + "in": [ + "0x00" + ], + "op": "calldataload", + "out": [ + "v7" + ] + }, + { + "in": [ + "v7", + "0xe0" + ], + "op": "shr", + "out": [ + "v9" + ] + }, + { + "in": [ + "v9", + "0x26121ff0" + ], + "op": "eq", + "out": [ + "v11" + ] + } + ], + "liveness": { "in": [ - "v4" + "v0" ], - "op": "iszero", "out": [ - "v5" + "v0" ] - } - ], - "liveness": { - "in": [], - "out": [ - "v0" - ] - }, - "type": "BuiltinCall" - }, - { - "exit": { - "type": "Terminated" + }, + "type": "BuiltinCall" }, - "id": "Block2", - "instructions": [ - { - "in": [ - "0x00", - "0x00" + { + "exit": { + "targets": [ + "Block2" ], - "op": "revert", + "type": "Jump" + }, + "id": "Block4", + "instructions": [], + "liveness": { + "in": [], "out": [] } - ], - "liveness": { - "in": [], - "out": [] - }, - "type": "BuiltinCall" - }, - { - "exit": { - "cond": "v11", - "targets": [ - "Block4", - "Block3" - ], - "type": "ConditionalJump" }, - "id": "Block1", - "instructions": [ - { - "in": [ - "0x00" + { + "exit": { + "cond": "v12", + "targets": [ + "Block6", + "Block5" ], - "op": "calldataload", - "out": [ - "v7" - ] + "type": "ConditionalJump" }, - { + "id": "Block3", + "instructions": [ + { + "in": [], + "op": "callvalue", + "out": [ + "v12" + ] + } + ], + "liveness": { "in": [ - "v7", - "0xe0" + "v0" ], - "op": "shr", "out": [ - "v9" + "v0" ] }, - { - "in": [ - "v9", - "0x26121ff0" - ], - "op": "eq", - "out": [ - "v11" - ] - } - ], - "liveness": { - "in": [ - "v0" - ], - "out": [ - "v0" - ] - }, - "type": "BuiltinCall" - }, - { - "exit": { - "targets": [ - "Block2" - ], - "type": "Jump" - }, - "id": "Block4", - "instructions": [], - "liveness": { - "in": [], - "out": [] - } - }, - { - "exit": { - "cond": "v12", - "targets": [ - "Block6", - "Block5" - ], - "type": "ConditionalJump" + "type": "BuiltinCall" }, - "id": "Block3", - "instructions": [ - { - "in": [], - "op": "callvalue", - "out": [ - "v12" - ] - } - ], - "liveness": { - "in": [ - "v0" - ], - "out": [ - "v0" - ] - }, - "type": "BuiltinCall" - }, - { - "exit": { - "cond": "v17", - "targets": [ - "Block9", - "Block8" - ], - "type": "ConditionalJump" - }, - "id": "Block6", - "instructions": [ - { - "in": [ - "0x03" + { + "exit": { + "cond": "v17", + "targets": [ + "Block9", + "Block8" ], - "op": "not", - "out": [ - "v14" - ] - }, - { - "in": [], - "op": "calldatasize", - "out": [ - "v15" - ] + "type": "ConditionalJump" }, - { + "id": "Block6", + "instructions": [ + { + "in": [ + "0x03" + ], + "op": "not", + "out": [ + "v14" + ] + }, + { + "in": [], + "op": "calldatasize", + "out": [ + "v15" + ] + }, + { + "in": [ + "v14", + "v15" + ], + "op": "add", + "out": [ + "v16" + ] + }, + { + "in": [ + "0x00", + "v16" + ], + "op": "slt", + "out": [ + "v17" + ] + } + ], + "liveness": { "in": [ - "v14", - "v15" + "v0" ], - "op": "add", "out": [ - "v16" + "v0" ] }, - { - "in": [ - "0x00", - "v16" - ], - "op": "slt", - "out": [ - "v17" - ] - } - ], - "liveness": { - "in": [ - "v0" - ], - "out": [ - "v0" - ] - }, - "type": "BuiltinCall" - }, - { - "exit": { - "type": "Terminated" - }, - "id": "Block5", - "instructions": [ - { - "in": [ - "0x00", - "0x00" - ], - "op": "revert", - "out": [] - } - ], - "liveness": { - "in": [], - "out": [] + "type": "BuiltinCall" }, - "type": "BuiltinCall" - }, - { - "exit": { - "cond": "v28", - "targets": [ - "Block12", - "Block11" + { + "exit": { + "type": "Terminated" + }, + "id": "Block5", + "instructions": [ + { + "in": [ + "0x00", + "0x00" + ], + "op": "revert", + "out": [] + } ], - "type": "ConditionalJump" + "liveness": { + "in": [], + "out": [] + }, + "type": "BuiltinCall" }, - "id": "Block9", - "instructions": [ - { - "builtinArgs": [ - "C_19" + { + "exit": { + "cond": "v28", + "targets": [ + "Block12", + "Block11" ], - "in": [], - "op": "datasize", - "out": [ - "v18" - ] + "type": "ConditionalJump" }, - { + "id": "Block9", + "instructions": [ + { + "builtinArgs": [ + "C_19" + ], + "in": [], + "op": "datasize", + "out": [ + "v18" + ] + }, + { + "in": [ + "v18", + "v0" + ], + "op": "add", + "out": [ + "v24" + ] + }, + { + "in": [ + "v0", + "v24" + ], + "op": "lt", + "out": [ + "v25" + ] + }, + { + "in": [ + "0xffffffffffffffff", + "v24" + ], + "op": "gt", + "out": [ + "v27" + ] + }, + { + "in": [ + "v25", + "v27" + ], + "op": "or", + "out": [ + "v28" + ] + } + ], + "liveness": { "in": [ - "v18", "v0" ], - "op": "add", "out": [ - "v24" - ] - }, - { - "in": [ "v0", + "v18", "v24" - ], - "op": "lt", - "out": [ - "v25" - ] - }, - { - "in": [ - "0xffffffffffffffff", - "v24" - ], - "op": "gt", - "out": [ - "v27" ] }, - { - "in": [ - "v25", - "v27" - ], - "op": "or", - "out": [ - "v28" - ] - } - ], - "liveness": { - "in": [ - "v0" - ], - "out": [ - "v0", - "v18", - "v24" - ] - }, - "type": "BuiltinCall" - }, - { - "exit": { - "type": "Terminated" - }, - "id": "Block8", - "instructions": [ - { - "in": [ - "0x00", - "0x00" - ], - "op": "revert", - "out": [] - } - ], - "liveness": { - "in": [], - "out": [] + "type": "BuiltinCall" }, - "type": "BuiltinCall" - }, - { - "exit": { - "cond": "v42", - "targets": [ - "Block15", - "Block14" + { + "exit": { + "type": "Terminated" + }, + "id": "Block8", + "instructions": [ + { + "in": [ + "0x00", + "0x00" + ], + "op": "revert", + "out": [] + } ], - "type": "ConditionalJump" - }, - "id": "Block12", - "instructions": [ - { - "builtinArgs": [ - "C_19" - ], + "liveness": { "in": [], - "op": "dataoffset", - "out": [ - "v35" - ] - }, - { - "in": [ - "v18", - "v35", - "v0" - ], - "op": "datacopy", "out": [] }, - { - "in": [ - "v0", - "v24" + "type": "BuiltinCall" + }, + { + "exit": { + "cond": "v42", + "targets": [ + "Block15", + "Block14" ], - "op": "sub", - "out": [ - "v40" - ] + "type": "ConditionalJump" }, - { + "id": "Block12", + "instructions": [ + { + "builtinArgs": [ + "C_19" + ], + "in": [], + "op": "dataoffset", + "out": [ + "v35" + ] + }, + { + "in": [ + "v18", + "v35", + "v0" + ], + "op": "datacopy", + "out": [] + }, + { + "in": [ + "v0", + "v24" + ], + "op": "sub", + "out": [ + "v40" + ] + }, + { + "in": [ + "v40", + "v0", + "0x00" + ], + "op": "create", + "out": [ + "v41" + ] + }, + { + "in": [ + "v41" + ], + "op": "iszero", + "out": [ + "v42" + ] + } + ], + "liveness": { "in": [ - "v40", "v0", - "0x00" + "v18", + "v24" ], - "op": "create", "out": [ "v41" ] }, - { - "in": [ - "v41" - ], - "op": "iszero", - "out": [ - "v42" - ] - } - ], - "liveness": { - "in": [ - "v0", - "v18", - "v24" - ], - "out": [ - "v41" - ] - }, - "type": "BuiltinCall" - }, - { - "exit": { - "type": "Terminated" + "type": "BuiltinCall" }, - "id": "Block11", - "instructions": [ - { - "in": [ - "0x4e487b71", - "0xe0" - ], - "op": "shl", - "out": [ - "v30" - ] - }, - { - "in": [ - "v30", - "0x00" - ], - "op": "mstore", - "out": [] - }, - { - "in": [ - "0x41", - "0x04" - ], - "op": "mstore", - "out": [] + { + "exit": { + "type": "Terminated" }, - { - "in": [ - "0x24", - "0x00" - ], - "op": "revert", - "out": [] - } - ], - "liveness": { - "in": [], - "out": [] - }, - "type": "BuiltinCall" - }, - { - "exit": { - "cond": "v60", - "targets": [ - "Block18", - "Block17" + "id": "Block11", + "instructions": [ + { + "in": [ + "0x4e487b71", + "0xe0" + ], + "op": "shl", + "out": [ + "v30" + ] + }, + { + "in": [ + "v30", + "0x00" + ], + "op": "mstore", + "out": [] + }, + { + "in": [ + "0x41", + "0x04" + ], + "op": "mstore", + "out": [] + }, + { + "in": [ + "0x24", + "0x00" + ], + "op": "revert", + "out": [] + } ], - "type": "ConditionalJump" - }, - "id": "Block15", - "instructions": [ - { - "in": [ - "0x40" - ], - "op": "mload", - "out": [ - "v46" - ] - }, - { - "in": [ - "0x026121ff", - "0xe4" - ], - "op": "shl", - "out": [ - "v49" - ] - }, - { - "in": [ - "v49", - "v46" - ], - "op": "mstore", + "liveness": { + "in": [], "out": [] }, - { - "in": [ - "0x01", - "0xa0" - ], - "op": "shl", - "out": [ - "v53" - ] - }, - { - "in": [ - "0x01", - "v53" + "type": "BuiltinCall" + }, + { + "exit": { + "cond": "v60", + "targets": [ + "Block18", + "Block17" ], - "op": "sub", - "out": [ - "v54" - ] + "type": "ConditionalJump" }, - { + "id": "Block15", + "instructions": [ + { + "in": [ + "0x40" + ], + "op": "mload", + "out": [ + "v46" + ] + }, + { + "in": [ + "0x026121ff", + "0xe4" + ], + "op": "shl", + "out": [ + "v49" + ] + }, + { + "in": [ + "v49", + "v46" + ], + "op": "mstore", + "out": [] + }, + { + "in": [ + "0x01", + "0xa0" + ], + "op": "shl", + "out": [ + "v53" + ] + }, + { + "in": [ + "0x01", + "v53" + ], + "op": "sub", + "out": [ + "v54" + ] + }, + { + "in": [ + "v54", + "v41" + ], + "op": "and", + "out": [ + "v57" + ] + }, + { + "in": [], + "op": "gas", + "out": [ + "v58" + ] + }, + { + "in": [ + "0x20", + "v46", + "0x04", + "v46", + "v57", + "v58" + ], + "op": "staticcall", + "out": [ + "v59" + ] + }, + { + "in": [ + "v59" + ], + "op": "iszero", + "out": [ + "v60" + ] + } + ], + "liveness": { "in": [ - "v54", "v41" ], - "op": "and", - "out": [ - "v57" - ] - }, - { - "in": [], - "op": "gas", "out": [ - "v58" - ] - }, - { - "in": [ - "0x20", "v46", - "0x04", - "v46", - "v57", - "v58" - ], - "op": "staticcall", - "out": [ - "v59" - ] - }, - { - "in": [ "v59" - ], - "op": "iszero", - "out": [ - "v60" - ] - } - ], - "liveness": { - "in": [ - "v41" - ], - "out": [ - "v46", - "v59" - ] - }, - "type": "BuiltinCall" - }, - { - "exit": { - "type": "Terminated" - }, - "id": "Block14", - "instructions": [ - { - "in": [ - "0x40" - ], - "op": "mload", - "out": [ - "v43" - ] - }, - { - "in": [], - "op": "returndatasize", - "out": [ - "v44" - ] - }, - { - "in": [ - "v44", - "0x00", - "v43" - ], - "op": "returndatacopy", - "out": [] - }, - { - "in": [], - "op": "returndatasize", - "out": [ - "v45" - ] - }, - { - "in": [ - "v45", - "v43" - ], - "op": "revert", - "out": [] - } - ], - "liveness": { - "in": [], - "out": [] - }, - "type": "BuiltinCall" - }, - { - "exit": { - "cond": "v59", - "targets": [ - "Block21", - "Block20" - ], - "type": "ConditionalJump" - }, - "id": "Block18", - "instructions": [], - "liveness": { - "in": [ - "v46", - "v59" - ], - "out": [ - "v46" - ] - } - }, - { - "exit": { - "type": "Terminated" - }, - "id": "Block17", - "instructions": [ - { - "in": [ - "0x40" - ], - "op": "mload", - "out": [ - "v61" - ] - }, - { - "in": [], - "op": "returndatasize", - "out": [ - "v62" - ] - }, - { - "in": [ - "v62", - "0x00", - "v61" - ], - "op": "returndatacopy", - "out": [] - }, - { - "in": [], - "op": "returndatasize", - "out": [ - "v63" - ] - }, - { - "in": [ - "v63", - "v61" - ], - "op": "revert", - "out": [] - } - ], - "liveness": { - "in": [], - "out": [] - }, - "type": "BuiltinCall" - }, - { - "entries": [ - "Block18", - "Block28" - ], - "exit": { - "type": "Terminated" - }, - "id": "Block21", - "instructions": [ - { - "in": [ - "0x00", - "v93" - ], - "op": "PhiFunction", - "out": [ - "v95" ] }, - { - "in": [ - "0x40" - ], - "op": "mload", - "out": [ - "v94" - ] - }, - { - "in": [ - "v95", - "v94" - ], - "op": "mstore", - "out": [] - }, - { - "in": [ - "0x20", - "v94" - ], - "op": "return", - "out": [] - } - ], - "liveness": { - "in": [ - "v95" - ], - "out": [] - }, - "type": "BuiltinCall" - }, - { - "exit": { - "cond": "v67", - "targets": [ - "Block23", - "Block22" - ], - "type": "ConditionalJump" - }, - "id": "Block20", - "instructions": [ - { - "in": [], - "op": "returndatasize", - "out": [ - "v66" - ] - }, - { - "in": [ - "v66", - "0x20" - ], - "op": "gt", - "out": [ - "v67" - ] - } - ], - "liveness": { - "in": [ - "v46" - ], - "out": [ - "v46" - ] - }, - "type": "BuiltinCall" - }, - { - "entries": [ - "Block20", - "Block22" - ], - "exit": { - "cond": "v80", - "targets": [ - "Block25", - "Block24" - ], - "type": "ConditionalJump" + "type": "BuiltinCall" }, - "id": "Block23", - "instructions": [ - { - "in": [ - "0x20", - "v68" - ], - "op": "PhiFunction", - "out": [ - "v71" - ] - }, - { - "in": [ - "0x1f" - ], - "op": "not", - "out": [ - "v70" - ] - }, - { - "in": [ - "0x1f", - "v71" - ], - "op": "add", - "out": [ - "v72" - ] + { + "exit": { + "type": "Terminated" }, - { - "in": [ - "v70", - "v72" - ], - "op": "and", - "out": [ - "v73" - ] + "id": "Block14", + "instructions": [ + { + "in": [ + "0x40" + ], + "op": "mload", + "out": [ + "v43" + ] + }, + { + "in": [], + "op": "returndatasize", + "out": [ + "v44" + ] + }, + { + "in": [ + "v44", + "0x00", + "v43" + ], + "op": "returndatacopy", + "out": [] + }, + { + "in": [], + "op": "returndatasize", + "out": [ + "v45" + ] + }, + { + "in": [ + "v45", + "v43" + ], + "op": "revert", + "out": [] + } + ], + "liveness": { + "in": [], + "out": [] }, - { - "in": [ - "v73", - "v46" + "type": "BuiltinCall" + }, + { + "exit": { + "cond": "v59", + "targets": [ + "Block21", + "Block20" ], - "op": "add", - "out": [ - "v77" - ] + "type": "ConditionalJump" }, - { + "id": "Block18", + "instructions": [], + "liveness": { "in": [ "v46", - "v77" - ], - "op": "lt", - "out": [ - "v78" - ] - }, - { - "in": [ - "0xffffffffffffffff", - "v77" - ], - "op": "gt", - "out": [ - "v79" - ] - }, - { - "in": [ - "v78", - "v79" + "v59" ], - "op": "or", "out": [ - "v80" + "v46" ] } - ], - "liveness": { - "in": [ - "v46", - "v71" - ], - "out": [ - "v46", - "v71", - "v77" - ] }, - "type": "BuiltinCall" - }, - { - "exit": { - "targets": [ - "Block23" + { + "exit": { + "type": "Terminated" + }, + "id": "Block17", + "instructions": [ + { + "in": [ + "0x40" + ], + "op": "mload", + "out": [ + "v61" + ] + }, + { + "in": [], + "op": "returndatasize", + "out": [ + "v62" + ] + }, + { + "in": [ + "v62", + "0x00", + "v61" + ], + "op": "returndatacopy", + "out": [] + }, + { + "in": [], + "op": "returndatasize", + "out": [ + "v63" + ] + }, + { + "in": [ + "v63", + "v61" + ], + "op": "revert", + "out": [] + } ], - "type": "Jump" - }, - "id": "Block22", - "instructions": [ - { + "liveness": { "in": [], - "op": "returndatasize", - "out": [ - "v68" - ] - } - ], - "liveness": { - "in": [ - "v46" - ], - "out": [ - "v46", - "v68" - ] + "out": [] + }, + "type": "BuiltinCall" }, - "type": "BuiltinCall" - }, - { - "exit": { - "cond": "v90", - "targets": [ - "Block28", - "Block27" + { + "entries": [ + "Block18", + "Block28" ], - "type": "ConditionalJump" - }, - "id": "Block25", - "instructions": [ - { + "exit": { + "type": "Terminated" + }, + "id": "Block21", + "instructions": [ + { + "in": [ + "0x00", + "v93" + ], + "op": "PhiFunction", + "out": [ + "v95" + ] + }, + { + "in": [ + "0x40" + ], + "op": "mload", + "out": [ + "v94" + ] + }, + { + "in": [ + "v95", + "v94" + ], + "op": "mstore", + "out": [] + }, + { + "in": [ + "0x20", + "v94" + ], + "op": "return", + "out": [] + } + ], + "liveness": { "in": [ - "v77", - "0x40" + "v95" ], - "op": "mstore", "out": [] }, - { - "in": [ - "v71", - "v46" + "type": "BuiltinCall" + }, + { + "exit": { + "cond": "v67", + "targets": [ + "Block23", + "Block22" ], - "op": "add", - "out": [ - "v88" - ] + "type": "ConditionalJump" }, - { + "id": "Block20", + "instructions": [ + { + "in": [], + "op": "returndatasize", + "out": [ + "v66" + ] + }, + { + "in": [ + "v66", + "0x20" + ], + "op": "gt", + "out": [ + "v67" + ] + } + ], + "liveness": { "in": [ - "v46", - "v88" + "v46" ], - "op": "sub", "out": [ - "v89" + "v46" ] }, - { - "in": [ - "0x20", - "v89" + "type": "BuiltinCall" + }, + { + "entries": [ + "Block20", + "Block22" + ], + "exit": { + "cond": "v80", + "targets": [ + "Block25", + "Block24" ], - "op": "slt", - "out": [ - "v90" - ] - } - ], - "liveness": { - "in": [ - "v46", - "v71", - "v77" + "type": "ConditionalJump" + }, + "id": "Block23", + "instructions": [ + { + "in": [ + "0x20", + "v68" + ], + "op": "PhiFunction", + "out": [ + "v71" + ] + }, + { + "in": [ + "0x1f" + ], + "op": "not", + "out": [ + "v70" + ] + }, + { + "in": [ + "0x1f", + "v71" + ], + "op": "add", + "out": [ + "v72" + ] + }, + { + "in": [ + "v70", + "v72" + ], + "op": "and", + "out": [ + "v73" + ] + }, + { + "in": [ + "v73", + "v46" + ], + "op": "add", + "out": [ + "v77" + ] + }, + { + "in": [ + "v46", + "v77" + ], + "op": "lt", + "out": [ + "v78" + ] + }, + { + "in": [ + "0xffffffffffffffff", + "v77" + ], + "op": "gt", + "out": [ + "v79" + ] + }, + { + "in": [ + "v78", + "v79" + ], + "op": "or", + "out": [ + "v80" + ] + } ], - "out": [ - "v46" - ] - }, - "type": "BuiltinCall" - }, - { - "exit": { - "type": "Terminated" - }, - "id": "Block24", - "instructions": [ - { + "liveness": { "in": [ - "0x4e487b71", - "0xe0" + "v46", + "v71" ], - "op": "shl", "out": [ - "v81" + "v46", + "v71", + "v77" ] }, - { - "in": [ - "v81", - "0x00" - ], - "op": "mstore", - "out": [] - }, - { - "in": [ - "0x41", - "0x04" - ], - "op": "mstore", - "out": [] - }, - { - "in": [ - "0x24", - "0x00" - ], - "op": "revert", - "out": [] - } - ], - "liveness": { - "in": [], - "out": [] + "type": "BuiltinCall" }, - "type": "BuiltinCall" - }, - { - "exit": { - "targets": [ - "Block21" + { + "exit": { + "targets": [ + "Block23" + ], + "type": "Jump" + }, + "id": "Block22", + "instructions": [ + { + "in": [], + "op": "returndatasize", + "out": [ + "v68" + ] + } ], - "type": "Jump" - }, - "id": "Block28", - "instructions": [ - { + "liveness": { "in": [ "v46" ], - "op": "mload", "out": [ - "v93" + "v46", + "v68" ] - } - ], - "liveness": { - "in": [ - "v46" - ], - "out": [ - "v93" - ] - }, - "type": "BuiltinCall" - }, - { - "exit": { - "type": "Terminated" - }, - "id": "Block27", - "instructions": [ - { - "in": [ - "0x00", - "0x00" - ], - "op": "revert", - "out": [] - } - ], - "liveness": { - "in": [], - "out": [] + }, + "type": "BuiltinCall" }, - "type": "BuiltinCall" - } - ], - "functions": {} - }, - "subObjects": { - "C_19": { - "blocks": [ { "exit": { - "cond": "v2", + "cond": "v90", "targets": [ - "Block2", - "Block1" + "Block28", + "Block27" ], "type": "ConditionalJump" }, - "id": "Block0", + "id": "Block25", "instructions": [ { - "builtinArgs": [ - "0x80" + "in": [ + "v77", + "0x40" ], - "in": [], - "op": "memoryguard", + "op": "mstore", + "out": [] + }, + { + "in": [ + "v71", + "v46" + ], + "op": "add", "out": [ - "v0" + "v88" ] }, { "in": [ - "v0", - "0x40" + "v46", + "v88" ], - "op": "mstore", - "out": [] + "op": "sub", + "out": [ + "v89" + ] }, { - "in": [], - "op": "callvalue", + "in": [ + "0x20", + "v89" + ], + "op": "slt", "out": [ - "v2" + "v90" ] } ], "liveness": { - "in": [], + "in": [ + "v46", + "v71", + "v77" + ], "out": [ - "v0" + "v46" ] }, "type": "BuiltinCall" @@ -1729,51 +1580,75 @@ "exit": { "type": "Terminated" }, - "id": "Block2", + "id": "Block24", "instructions": [ { - "builtinArgs": [ - "C_19_deployed" + "in": [ + "0x4e487b71", + "0xe0" ], - "in": [], - "op": "datasize", + "op": "shl", "out": [ - "v4" + "v81" ] }, { - "builtinArgs": [ - "C_19_deployed" + "in": [ + "v81", + "0x00" ], - "in": [], - "op": "dataoffset", - "out": [ - "v5" - ] + "op": "mstore", + "out": [] }, { "in": [ - "v4", - "v5", - "v0" + "0x41", + "0x04" ], - "op": "codecopy", + "op": "mstore", "out": [] }, { "in": [ - "v4", - "v0" + "0x24", + "0x00" ], - "op": "return", + "op": "revert", "out": [] } ], + "liveness": { + "in": [], + "out": [] + }, + "type": "BuiltinCall" + }, + { + "exit": { + "targets": [ + "Block21" + ], + "type": "Jump" + }, + "id": "Block28", + "instructions": [ + { + "in": [ + "v46" + ], + "op": "mload", + "out": [ + "v93" + ] + } + ], "liveness": { "in": [ - "v0" + "v46" ], - "out": [] + "out": [ + "v93" + ] }, "type": "BuiltinCall" }, @@ -1781,7 +1656,7 @@ "exit": { "type": "Terminated" }, - "id": "Block1", + "id": "Block27", "instructions": [ { "in": [ @@ -1799,330 +1674,455 @@ "type": "BuiltinCall" } ], - "functions": {} - }, - "subObjects": { - "C_19_deployed": { - "blocks": [ - { - "exit": { - "cond": "v5", - "targets": [ - "Block2", - "Block1" - ], - "type": "ConditionalJump" - }, - "id": "Block0", - "instructions": [ - { - "builtinArgs": [ - "0x80" - ], - "in": [], - "op": "memoryguard", - "out": [ - "v0" - ] - }, - { - "in": [ - "v0", - "0x40" + "functions": {}, + "subObjects": { + "C_19": { + "blocks": [ + { + "exit": { + "cond": "v2", + "targets": [ + "Block2", + "Block1" ], - "op": "mstore", - "out": [] + "type": "ConditionalJump" }, - { + "id": "Block0", + "instructions": [ + { + "builtinArgs": [ + "0x80" + ], + "in": [], + "op": "memoryguard", + "out": [ + "v0" + ] + }, + { + "in": [ + "v0", + "0x40" + ], + "op": "mstore", + "out": [] + }, + { + "in": [], + "op": "callvalue", + "out": [ + "v2" + ] + } + ], + "liveness": { "in": [], - "op": "calldatasize", "out": [ - "v3" - ] - }, - { - "in": [ - "0x04", - "v3" - ], - "op": "lt", - "out": [ - "v4" + "v0" ] }, - { - "in": [ - "v4" - ], - "op": "iszero", - "out": [ - "v5" - ] - } - ], - "liveness": { - "in": [], - "out": [ - "v0" - ] - }, - "type": "BuiltinCall" - }, - { - "exit": { - "type": "Terminated" - }, - "id": "Block2", - "instructions": [ - { - "in": [ - "0x00", - "0x00" - ], - "op": "revert", - "out": [] - } - ], - "liveness": { - "in": [], - "out": [] + "type": "BuiltinCall" }, - "type": "BuiltinCall" - }, - { - "exit": { - "cond": "v11", - "targets": [ - "Block4", - "Block3" - ], - "type": "ConditionalJump" - }, - "id": "Block1", - "instructions": [ - { - "in": [ - "0x00" - ], - "op": "calldataload", - "out": [ - "v7" - ] - }, - { - "in": [ - "v7", - "0xe0" - ], - "op": "shr", - "out": [ - "v9" - ] + { + "exit": { + "type": "Terminated" }, - { - "in": [ - "v9", - "0x26121ff0" - ], - "op": "eq", - "out": [ - "v11" - ] - } - ], - "liveness": { - "in": [ - "v0" - ], - "out": [ - "v0" - ] - }, - "type": "BuiltinCall" - }, - { - "exit": { - "targets": [ - "Block2" + "id": "Block2", + "instructions": [ + { + "builtinArgs": [ + "C_19_deployed" + ], + "in": [], + "op": "datasize", + "out": [ + "v4" + ] + }, + { + "builtinArgs": [ + "C_19_deployed" + ], + "in": [], + "op": "dataoffset", + "out": [ + "v5" + ] + }, + { + "in": [ + "v4", + "v5", + "v0" + ], + "op": "codecopy", + "out": [] + }, + { + "in": [ + "v4", + "v0" + ], + "op": "return", + "out": [] + } ], - "type": "Jump" - }, - "id": "Block4", - "instructions": [], - "liveness": { - "in": [], - "out": [] - } - }, - { - "exit": { - "cond": "v12", - "targets": [ - "Block6", - "Block5" - ], - "type": "ConditionalJump" - }, - "id": "Block3", - "instructions": [ - { - "in": [], - "op": "callvalue", - "out": [ - "v12" - ] - } - ], - "liveness": { - "in": [ - "v0" - ], - "out": [ - "v0" - ] - }, - "type": "BuiltinCall" - }, - { - "exit": { - "cond": "v17", - "targets": [ - "Block9", - "Block8" - ], - "type": "ConditionalJump" - }, - "id": "Block6", - "instructions": [ - { + "liveness": { "in": [ - "0x03" + "v0" ], - "op": "not", - "out": [ - "v14" - ] - }, - { - "in": [], - "op": "calldatasize", - "out": [ - "v15" - ] + "out": [] }, - { - "in": [ - "v14", - "v15" - ], - "op": "add", - "out": [ - "v16" - ] + "type": "BuiltinCall" + }, + { + "exit": { + "type": "Terminated" }, - { - "in": [ - "0x00", - "v16" - ], - "op": "slt", - "out": [ - "v17" - ] - } - ], - "liveness": { - "in": [ - "v0" + "id": "Block1", + "instructions": [ + { + "in": [ + "0x00", + "0x00" + ], + "op": "revert", + "out": [] + } ], - "out": [ - "v0" - ] - }, - "type": "BuiltinCall" - }, - { - "exit": { - "type": "Terminated" - }, - "id": "Block5", - "instructions": [ - { - "in": [ - "0x00", - "0x00" - ], - "op": "revert", - "out": [] - } - ], - "liveness": { - "in": [], - "out": [] - }, - "type": "BuiltinCall" - }, - { - "exit": { - "type": "Terminated" - }, - "id": "Block9", - "instructions": [ - { - "in": [ - "0x2a", - "v0" - ], - "op": "mstore", + "liveness": { + "in": [], "out": [] }, - { - "in": [ - "0x20", - "v0" - ], - "op": "return", - "out": [] - } - ], - "liveness": { - "in": [ - "v0" + "type": "BuiltinCall" + } + ], + "functions": {}, + "subObjects": { + "C_19_deployed": { + "blocks": [ + { + "exit": { + "cond": "v5", + "targets": [ + "Block2", + "Block1" + ], + "type": "ConditionalJump" + }, + "id": "Block0", + "instructions": [ + { + "builtinArgs": [ + "0x80" + ], + "in": [], + "op": "memoryguard", + "out": [ + "v0" + ] + }, + { + "in": [ + "v0", + "0x40" + ], + "op": "mstore", + "out": [] + }, + { + "in": [], + "op": "calldatasize", + "out": [ + "v3" + ] + }, + { + "in": [ + "0x04", + "v3" + ], + "op": "lt", + "out": [ + "v4" + ] + }, + { + "in": [ + "v4" + ], + "op": "iszero", + "out": [ + "v5" + ] + } + ], + "liveness": { + "in": [], + "out": [ + "v0" + ] + }, + "type": "BuiltinCall" + }, + { + "exit": { + "type": "Terminated" + }, + "id": "Block2", + "instructions": [ + { + "in": [ + "0x00", + "0x00" + ], + "op": "revert", + "out": [] + } + ], + "liveness": { + "in": [], + "out": [] + }, + "type": "BuiltinCall" + }, + { + "exit": { + "cond": "v11", + "targets": [ + "Block4", + "Block3" + ], + "type": "ConditionalJump" + }, + "id": "Block1", + "instructions": [ + { + "in": [ + "0x00" + ], + "op": "calldataload", + "out": [ + "v7" + ] + }, + { + "in": [ + "v7", + "0xe0" + ], + "op": "shr", + "out": [ + "v9" + ] + }, + { + "in": [ + "v9", + "0x26121ff0" + ], + "op": "eq", + "out": [ + "v11" + ] + } + ], + "liveness": { + "in": [ + "v0" + ], + "out": [ + "v0" + ] + }, + "type": "BuiltinCall" + }, + { + "exit": { + "targets": [ + "Block2" + ], + "type": "Jump" + }, + "id": "Block4", + "instructions": [], + "liveness": { + "in": [], + "out": [] + } + }, + { + "exit": { + "cond": "v12", + "targets": [ + "Block6", + "Block5" + ], + "type": "ConditionalJump" + }, + "id": "Block3", + "instructions": [ + { + "in": [], + "op": "callvalue", + "out": [ + "v12" + ] + } + ], + "liveness": { + "in": [ + "v0" + ], + "out": [ + "v0" + ] + }, + "type": "BuiltinCall" + }, + { + "exit": { + "cond": "v17", + "targets": [ + "Block9", + "Block8" + ], + "type": "ConditionalJump" + }, + "id": "Block6", + "instructions": [ + { + "in": [ + "0x03" + ], + "op": "not", + "out": [ + "v14" + ] + }, + { + "in": [], + "op": "calldatasize", + "out": [ + "v15" + ] + }, + { + "in": [ + "v14", + "v15" + ], + "op": "add", + "out": [ + "v16" + ] + }, + { + "in": [ + "0x00", + "v16" + ], + "op": "slt", + "out": [ + "v17" + ] + } + ], + "liveness": { + "in": [ + "v0" + ], + "out": [ + "v0" + ] + }, + "type": "BuiltinCall" + }, + { + "exit": { + "type": "Terminated" + }, + "id": "Block5", + "instructions": [ + { + "in": [ + "0x00", + "0x00" + ], + "op": "revert", + "out": [] + } + ], + "liveness": { + "in": [], + "out": [] + }, + "type": "BuiltinCall" + }, + { + "exit": { + "type": "Terminated" + }, + "id": "Block9", + "instructions": [ + { + "in": [ + "0x2a", + "v0" + ], + "op": "mstore", + "out": [] + }, + { + "in": [ + "0x20", + "v0" + ], + "op": "return", + "out": [] + } + ], + "liveness": { + "in": [ + "v0" + ], + "out": [] + }, + "type": "BuiltinCall" + }, + { + "exit": { + "type": "Terminated" + }, + "id": "Block8", + "instructions": [ + { + "in": [ + "0x00", + "0x00" + ], + "op": "revert", + "out": [] + } + ], + "liveness": { + "in": [], + "out": [] + }, + "type": "BuiltinCall" + } ], - "out": [] - }, - "type": "BuiltinCall" - }, - { - "exit": { - "type": "Terminated" - }, - "id": "Block8", - "instructions": [ - { - "in": [ - "0x00", - "0x00" - ], - "op": "revert", - "out": [] - } - ], - "liveness": { - "in": [], - "out": [] + "functions": {}, + "subObjects": {} }, - "type": "BuiltinCall" + "type": "subObject" } - ], - "functions": {} - }, - "subObjects": {}, - "type": "subObject" + }, + "type": "subObject" + } }, "type": "subObject" - }, - "type": "subObject" + } }, "type": "Object" } diff --git a/test/cmdlineTests/strict_asm_yul_cfg_json_export/output b/test/cmdlineTests/strict_asm_yul_cfg_json_export/output index ac154fc16246..c79692c3c035 100644 --- a/test/cmdlineTests/strict_asm_yul_cfg_json_export/output +++ b/test/cmdlineTests/strict_asm_yul_cfg_json_export/output @@ -124,325 +124,325 @@ Yul Control Flow Graph: "type": "BuiltinCall" } ], - "functions": {} - }, - "subObjects": { - "C_19_deployed": { - "blocks": [ - { - "exit": { - "cond": "v5", - "targets": [ - "Block2", - "Block1" - ], - "type": "ConditionalJump" - }, - "id": "Block0", - "instructions": [ - { - "builtinArgs": [ - "0x80" + "functions": {}, + "subObjects": { + "C_19_deployed": { + "blocks": [ + { + "exit": { + "cond": "v5", + "targets": [ + "Block2", + "Block1" ], + "type": "ConditionalJump" + }, + "id": "Block0", + "instructions": [ + { + "builtinArgs": [ + "0x80" + ], + "in": [], + "op": "memoryguard", + "out": [ + "v0" + ] + }, + { + "in": [ + "v0", + "0x40" + ], + "op": "mstore", + "out": [] + }, + { + "in": [], + "op": "calldatasize", + "out": [ + "v3" + ] + }, + { + "in": [ + "0x04", + "v3" + ], + "op": "lt", + "out": [ + "v4" + ] + }, + { + "in": [ + "v4" + ], + "op": "iszero", + "out": [ + "v5" + ] + } + ], + "liveness": { "in": [], - "op": "memoryguard", "out": [ "v0" ] }, - { - "in": [ - "v0", - "0x40" - ], - "op": "mstore", - "out": [] + "type": "BuiltinCall" + }, + { + "exit": { + "type": "Terminated" }, - { + "id": "Block2", + "instructions": [ + { + "in": [ + "0x00", + "0x00" + ], + "op": "revert", + "out": [] + } + ], + "liveness": { "in": [], - "op": "calldatasize", - "out": [ - "v3" - ] + "out": [] }, - { - "in": [ - "0x04", - "v3" + "type": "BuiltinCall" + }, + { + "exit": { + "cond": "v11", + "targets": [ + "Block4", + "Block3" ], - "op": "lt", - "out": [ - "v4" - ] + "type": "ConditionalJump" }, - { + "id": "Block1", + "instructions": [ + { + "in": [ + "0x00" + ], + "op": "calldataload", + "out": [ + "v7" + ] + }, + { + "in": [ + "v7", + "0xe0" + ], + "op": "shr", + "out": [ + "v9" + ] + }, + { + "in": [ + "v9", + "0x26121ff0" + ], + "op": "eq", + "out": [ + "v11" + ] + } + ], + "liveness": { "in": [ - "v4" + "v0" ], - "op": "iszero", "out": [ - "v5" + "v0" ] - } - ], - "liveness": { - "in": [], - "out": [ - "v0" - ] - }, - "type": "BuiltinCall" - }, - { - "exit": { - "type": "Terminated" + }, + "type": "BuiltinCall" }, - "id": "Block2", - "instructions": [ - { - "in": [ - "0x00", - "0x00" + { + "exit": { + "targets": [ + "Block2" ], - "op": "revert", + "type": "Jump" + }, + "id": "Block4", + "instructions": [], + "liveness": { + "in": [], "out": [] } - ], - "liveness": { - "in": [], - "out": [] }, - "type": "BuiltinCall" - }, - { - "exit": { - "cond": "v11", - "targets": [ - "Block4", - "Block3" - ], - "type": "ConditionalJump" - }, - "id": "Block1", - "instructions": [ - { - "in": [ - "0x00" + { + "exit": { + "cond": "v12", + "targets": [ + "Block6", + "Block5" ], - "op": "calldataload", - "out": [ - "v7" - ] + "type": "ConditionalJump" }, - { + "id": "Block3", + "instructions": [ + { + "in": [], + "op": "callvalue", + "out": [ + "v12" + ] + } + ], + "liveness": { "in": [ - "v7", - "0xe0" + "v0" ], - "op": "shr", "out": [ - "v9" + "v0" ] }, - { - "in": [ - "v9", - "0x26121ff0" - ], - "op": "eq", - "out": [ - "v11" - ] - } - ], - "liveness": { - "in": [ - "v0" - ], - "out": [ - "v0" - ] - }, - "type": "BuiltinCall" - }, - { - "exit": { - "targets": [ - "Block2" - ], - "type": "Jump" + "type": "BuiltinCall" }, - "id": "Block4", - "instructions": [], - "liveness": { - "in": [], - "out": [] - } - }, - { - "exit": { - "cond": "v12", - "targets": [ - "Block6", - "Block5" - ], - "type": "ConditionalJump" - }, - "id": "Block3", - "instructions": [ - { - "in": [], - "op": "callvalue", - "out": [ - "v12" - ] - } - ], - "liveness": { - "in": [ - "v0" - ], - "out": [ - "v0" - ] - }, - "type": "BuiltinCall" - }, - { - "exit": { - "cond": "v17", - "targets": [ - "Block9", - "Block8" - ], - "type": "ConditionalJump" - }, - "id": "Block6", - "instructions": [ - { - "in": [ - "0x03" + { + "exit": { + "cond": "v17", + "targets": [ + "Block9", + "Block8" ], - "op": "not", - "out": [ - "v14" - ] + "type": "ConditionalJump" }, - { - "in": [], - "op": "calldatasize", - "out": [ - "v15" - ] - }, - { + "id": "Block6", + "instructions": [ + { + "in": [ + "0x03" + ], + "op": "not", + "out": [ + "v14" + ] + }, + { + "in": [], + "op": "calldatasize", + "out": [ + "v15" + ] + }, + { + "in": [ + "v14", + "v15" + ], + "op": "add", + "out": [ + "v16" + ] + }, + { + "in": [ + "0x00", + "v16" + ], + "op": "slt", + "out": [ + "v17" + ] + } + ], + "liveness": { "in": [ - "v14", - "v15" + "v0" ], - "op": "add", "out": [ - "v16" + "v0" ] }, - { - "in": [ - "0x00", - "v16" - ], - "op": "slt", - "out": [ - "v17" - ] - } - ], - "liveness": { - "in": [ - "v0" - ], - "out": [ - "v0" - ] + "type": "BuiltinCall" }, - "type": "BuiltinCall" - }, - { - "exit": { - "type": "Terminated" - }, - "id": "Block5", - "instructions": [ - { - "in": [ - "0x00", - "0x00" - ], - "op": "revert", + { + "exit": { + "type": "Terminated" + }, + "id": "Block5", + "instructions": [ + { + "in": [ + "0x00", + "0x00" + ], + "op": "revert", + "out": [] + } + ], + "liveness": { + "in": [], "out": [] - } - ], - "liveness": { - "in": [], - "out": [] - }, - "type": "BuiltinCall" - }, - { - "exit": { - "type": "Terminated" + }, + "type": "BuiltinCall" }, - "id": "Block9", - "instructions": [ - { - "in": [ - "0x2a", - "v0" - ], - "op": "mstore", - "out": [] + { + "exit": { + "type": "Terminated" }, - { + "id": "Block9", + "instructions": [ + { + "in": [ + "0x2a", + "v0" + ], + "op": "mstore", + "out": [] + }, + { + "in": [ + "0x20", + "v0" + ], + "op": "return", + "out": [] + } + ], + "liveness": { "in": [ - "0x20", "v0" ], - "op": "return", "out": [] - } - ], - "liveness": { - "in": [ - "v0" - ], - "out": [] - }, - "type": "BuiltinCall" - }, - { - "exit": { - "type": "Terminated" + }, + "type": "BuiltinCall" }, - "id": "Block8", - "instructions": [ - { - "in": [ - "0x00", - "0x00" - ], - "op": "revert", + { + "exit": { + "type": "Terminated" + }, + "id": "Block8", + "instructions": [ + { + "in": [ + "0x00", + "0x00" + ], + "op": "revert", + "out": [] + } + ], + "liveness": { + "in": [], "out": [] - } - ], - "liveness": { - "in": [], - "out": [] - }, - "type": "BuiltinCall" - } - ], - "functions": {} - }, - "type": "subObject" + }, + "type": "BuiltinCall" + } + ], + "functions": {} + }, + "type": "subObject" + } }, "type": "Object" } diff --git a/test/cmdlineTests/yul_cfg_json_export/output b/test/cmdlineTests/yul_cfg_json_export/output index dd4dece740a0..0508769d7cb0 100644 --- a/test/cmdlineTests/yul_cfg_json_export/output +++ b/test/cmdlineTests/yul_cfg_json_export/output @@ -123,326 +123,326 @@ Yul Control Flow Graph: "type": "BuiltinCall" } ], - "functions": {} - }, - "subObjects": { - "C_19_deployed": { - "blocks": [ - { - "exit": { - "cond": "v5", - "targets": [ - "Block2", - "Block1" - ], - "type": "ConditionalJump" - }, - "id": "Block0", - "instructions": [ - { - "builtinArgs": [ - "0x80" + "functions": {}, + "subObjects": { + "C_19_deployed": { + "blocks": [ + { + "exit": { + "cond": "v5", + "targets": [ + "Block2", + "Block1" ], + "type": "ConditionalJump" + }, + "id": "Block0", + "instructions": [ + { + "builtinArgs": [ + "0x80" + ], + "in": [], + "op": "memoryguard", + "out": [ + "v0" + ] + }, + { + "in": [ + "v0", + "0x40" + ], + "op": "mstore", + "out": [] + }, + { + "in": [], + "op": "calldatasize", + "out": [ + "v3" + ] + }, + { + "in": [ + "0x04", + "v3" + ], + "op": "lt", + "out": [ + "v4" + ] + }, + { + "in": [ + "v4" + ], + "op": "iszero", + "out": [ + "v5" + ] + } + ], + "liveness": { "in": [], - "op": "memoryguard", "out": [ "v0" ] }, - { - "in": [ - "v0", - "0x40" - ], - "op": "mstore", - "out": [] + "type": "BuiltinCall" + }, + { + "exit": { + "type": "Terminated" }, - { + "id": "Block2", + "instructions": [ + { + "in": [ + "0x00", + "0x00" + ], + "op": "revert", + "out": [] + } + ], + "liveness": { "in": [], - "op": "calldatasize", - "out": [ - "v3" - ] + "out": [] }, - { - "in": [ - "0x04", - "v3" + "type": "BuiltinCall" + }, + { + "exit": { + "cond": "v11", + "targets": [ + "Block4", + "Block3" ], - "op": "lt", - "out": [ - "v4" - ] + "type": "ConditionalJump" }, - { + "id": "Block1", + "instructions": [ + { + "in": [ + "0x00" + ], + "op": "calldataload", + "out": [ + "v7" + ] + }, + { + "in": [ + "v7", + "0xe0" + ], + "op": "shr", + "out": [ + "v9" + ] + }, + { + "in": [ + "v9", + "0x26121ff0" + ], + "op": "eq", + "out": [ + "v11" + ] + } + ], + "liveness": { "in": [ - "v4" + "v0" ], - "op": "iszero", "out": [ - "v5" + "v0" ] - } - ], - "liveness": { - "in": [], - "out": [ - "v0" - ] - }, - "type": "BuiltinCall" - }, - { - "exit": { - "type": "Terminated" + }, + "type": "BuiltinCall" }, - "id": "Block2", - "instructions": [ - { - "in": [ - "0x00", - "0x00" + { + "exit": { + "targets": [ + "Block2" ], - "op": "revert", + "type": "Jump" + }, + "id": "Block4", + "instructions": [], + "liveness": { + "in": [], "out": [] } - ], - "liveness": { - "in": [], - "out": [] }, - "type": "BuiltinCall" - }, - { - "exit": { - "cond": "v11", - "targets": [ - "Block4", - "Block3" + { + "exit": { + "cond": "v12", + "targets": [ + "Block6", + "Block5" + ], + "type": "ConditionalJump" + }, + "id": "Block3", + "instructions": [ + { + "in": [], + "op": "callvalue", + "out": [ + "v12" + ] + } ], - "type": "ConditionalJump" - }, - "id": "Block1", - "instructions": [ - { + "liveness": { "in": [ - "0x00" + "v0" ], - "op": "calldataload", "out": [ - "v7" + "v0" ] }, - { - "in": [ - "v7", - "0xe0" + "type": "BuiltinCall" + }, + { + "exit": { + "cond": "v17", + "targets": [ + "Block9", + "Block8" ], - "op": "shr", - "out": [ - "v9" - ] + "type": "ConditionalJump" }, - { + "id": "Block6", + "instructions": [ + { + "in": [ + "0x03" + ], + "op": "not", + "out": [ + "v14" + ] + }, + { + "in": [], + "op": "calldatasize", + "out": [ + "v15" + ] + }, + { + "in": [ + "v14", + "v15" + ], + "op": "add", + "out": [ + "v16" + ] + }, + { + "in": [ + "0x00", + "v16" + ], + "op": "slt", + "out": [ + "v17" + ] + } + ], + "liveness": { "in": [ - "v9", - "0x26121ff0" + "v0" ], - "op": "eq", "out": [ - "v11" + "v0" ] - } - ], - "liveness": { - "in": [ - "v0" - ], - "out": [ - "v0" - ] - }, - "type": "BuiltinCall" - }, - { - "exit": { - "targets": [ - "Block2" - ], - "type": "Jump" + }, + "type": "BuiltinCall" }, - "id": "Block4", - "instructions": [], - "liveness": { - "in": [], - "out": [] - } - }, - { - "exit": { - "cond": "v12", - "targets": [ - "Block6", - "Block5" + { + "exit": { + "type": "Terminated" + }, + "id": "Block5", + "instructions": [ + { + "in": [ + "0x00", + "0x00" + ], + "op": "revert", + "out": [] + } ], - "type": "ConditionalJump" - }, - "id": "Block3", - "instructions": [ - { + "liveness": { "in": [], - "op": "callvalue", - "out": [ - "v12" - ] - } - ], - "liveness": { - "in": [ - "v0" - ], - "out": [ - "v0" - ] + "out": [] + }, + "type": "BuiltinCall" }, - "type": "BuiltinCall" - }, - { - "exit": { - "cond": "v17", - "targets": [ - "Block9", - "Block8" + { + "exit": { + "type": "Terminated" + }, + "id": "Block9", + "instructions": [ + { + "in": [ + "0x2a", + "v0" + ], + "op": "mstore", + "out": [] + }, + { + "in": [ + "0x20", + "v0" + ], + "op": "return", + "out": [] + } ], - "type": "ConditionalJump" - }, - "id": "Block6", - "instructions": [ - { + "liveness": { "in": [ - "0x03" + "v0" ], - "op": "not", - "out": [ - "v14" - ] - }, - { - "in": [], - "op": "calldatasize", - "out": [ - "v15" - ] - }, - { - "in": [ - "v14", - "v15" - ], - "op": "add", - "out": [ - "v16" - ] - }, - { - "in": [ - "0x00", - "v16" - ], - "op": "slt", - "out": [ - "v17" - ] - } - ], - "liveness": { - "in": [ - "v0" - ], - "out": [ - "v0" - ] - }, - "type": "BuiltinCall" - }, - { - "exit": { - "type": "Terminated" - }, - "id": "Block5", - "instructions": [ - { - "in": [ - "0x00", - "0x00" - ], - "op": "revert", "out": [] - } - ], - "liveness": { - "in": [], - "out": [] - }, - "type": "BuiltinCall" - }, - { - "exit": { - "type": "Terminated" + }, + "type": "BuiltinCall" }, - "id": "Block9", - "instructions": [ - { - "in": [ - "0x2a", - "v0" - ], - "op": "mstore", - "out": [] + { + "exit": { + "type": "Terminated" }, - { - "in": [ - "0x20", - "v0" - ], - "op": "return", - "out": [] - } - ], - "liveness": { - "in": [ - "v0" + "id": "Block8", + "instructions": [ + { + "in": [ + "0x00", + "0x00" + ], + "op": "revert", + "out": [] + } ], - "out": [] - }, - "type": "BuiltinCall" - }, - { - "exit": { - "type": "Terminated" - }, - "id": "Block8", - "instructions": [ - { - "in": [ - "0x00", - "0x00" - ], - "op": "revert", + "liveness": { + "in": [], "out": [] - } - ], - "liveness": { - "in": [], - "out": [] - }, - "type": "BuiltinCall" - } - ], - "functions": {} - }, - "subObjects": {}, - "type": "subObject" + }, + "type": "BuiltinCall" + } + ], + "functions": {}, + "subObjects": {} + }, + "type": "subObject" + } }, "type": "Object" } @@ -571,1156 +571,1007 @@ Yul Control Flow Graph: "type": "BuiltinCall" } ], - "functions": {} - }, - "subObjects": { - "D_38_deployed": { - "blocks": [ - { - "exit": { - "cond": "v5", - "targets": [ - "Block2", - "Block1" - ], - "type": "ConditionalJump" - }, - "id": "Block0", - "instructions": [ - { - "builtinArgs": [ - "0x80" + "functions": {}, + "subObjects": { + "D_38_deployed": { + "blocks": [ + { + "exit": { + "cond": "v5", + "targets": [ + "Block2", + "Block1" ], + "type": "ConditionalJump" + }, + "id": "Block0", + "instructions": [ + { + "builtinArgs": [ + "0x80" + ], + "in": [], + "op": "memoryguard", + "out": [ + "v0" + ] + }, + { + "in": [ + "v0", + "0x40" + ], + "op": "mstore", + "out": [] + }, + { + "in": [], + "op": "calldatasize", + "out": [ + "v3" + ] + }, + { + "in": [ + "0x04", + "v3" + ], + "op": "lt", + "out": [ + "v4" + ] + }, + { + "in": [ + "v4" + ], + "op": "iszero", + "out": [ + "v5" + ] + } + ], + "liveness": { "in": [], - "op": "memoryguard", "out": [ "v0" ] }, - { - "in": [ - "v0", - "0x40" - ], - "op": "mstore", - "out": [] + "type": "BuiltinCall" + }, + { + "exit": { + "type": "Terminated" }, - { + "id": "Block2", + "instructions": [ + { + "in": [ + "0x00", + "0x00" + ], + "op": "revert", + "out": [] + } + ], + "liveness": { "in": [], - "op": "calldatasize", - "out": [ - "v3" - ] + "out": [] }, - { - "in": [ - "0x04", - "v3" + "type": "BuiltinCall" + }, + { + "exit": { + "cond": "v11", + "targets": [ + "Block4", + "Block3" ], - "op": "lt", - "out": [ - "v4" - ] + "type": "ConditionalJump" }, - { + "id": "Block1", + "instructions": [ + { + "in": [ + "0x00" + ], + "op": "calldataload", + "out": [ + "v7" + ] + }, + { + "in": [ + "v7", + "0xe0" + ], + "op": "shr", + "out": [ + "v9" + ] + }, + { + "in": [ + "v9", + "0x26121ff0" + ], + "op": "eq", + "out": [ + "v11" + ] + } + ], + "liveness": { "in": [ - "v4" + "v0" ], - "op": "iszero", "out": [ - "v5" + "v0" ] - } - ], - "liveness": { - "in": [], - "out": [ - "v0" - ] - }, - "type": "BuiltinCall" - }, - { - "exit": { - "type": "Terminated" + }, + "type": "BuiltinCall" }, - "id": "Block2", - "instructions": [ - { - "in": [ - "0x00", - "0x00" + { + "exit": { + "targets": [ + "Block2" ], - "op": "revert", + "type": "Jump" + }, + "id": "Block4", + "instructions": [], + "liveness": { + "in": [], "out": [] } - ], - "liveness": { - "in": [], - "out": [] - }, - "type": "BuiltinCall" - }, - { - "exit": { - "cond": "v11", - "targets": [ - "Block4", - "Block3" - ], - "type": "ConditionalJump" }, - "id": "Block1", - "instructions": [ - { - "in": [ - "0x00" + { + "exit": { + "cond": "v12", + "targets": [ + "Block6", + "Block5" ], - "op": "calldataload", - "out": [ - "v7" - ] + "type": "ConditionalJump" }, - { + "id": "Block3", + "instructions": [ + { + "in": [], + "op": "callvalue", + "out": [ + "v12" + ] + } + ], + "liveness": { "in": [ - "v7", - "0xe0" + "v0" ], - "op": "shr", "out": [ - "v9" + "v0" ] }, - { - "in": [ - "v9", - "0x26121ff0" - ], - "op": "eq", - "out": [ - "v11" - ] - } - ], - "liveness": { - "in": [ - "v0" - ], - "out": [ - "v0" - ] - }, - "type": "BuiltinCall" - }, - { - "exit": { - "targets": [ - "Block2" - ], - "type": "Jump" - }, - "id": "Block4", - "instructions": [], - "liveness": { - "in": [], - "out": [] - } - }, - { - "exit": { - "cond": "v12", - "targets": [ - "Block6", - "Block5" - ], - "type": "ConditionalJump" + "type": "BuiltinCall" }, - "id": "Block3", - "instructions": [ - { - "in": [], - "op": "callvalue", - "out": [ - "v12" - ] - } - ], - "liveness": { - "in": [ - "v0" - ], - "out": [ - "v0" - ] - }, - "type": "BuiltinCall" - }, - { - "exit": { - "cond": "v17", - "targets": [ - "Block9", - "Block8" - ], - "type": "ConditionalJump" - }, - "id": "Block6", - "instructions": [ - { - "in": [ - "0x03" + { + "exit": { + "cond": "v17", + "targets": [ + "Block9", + "Block8" ], - "op": "not", - "out": [ - "v14" - ] - }, - { - "in": [], - "op": "calldatasize", - "out": [ - "v15" - ] + "type": "ConditionalJump" }, - { + "id": "Block6", + "instructions": [ + { + "in": [ + "0x03" + ], + "op": "not", + "out": [ + "v14" + ] + }, + { + "in": [], + "op": "calldatasize", + "out": [ + "v15" + ] + }, + { + "in": [ + "v14", + "v15" + ], + "op": "add", + "out": [ + "v16" + ] + }, + { + "in": [ + "0x00", + "v16" + ], + "op": "slt", + "out": [ + "v17" + ] + } + ], + "liveness": { "in": [ - "v14", - "v15" + "v0" ], - "op": "add", "out": [ - "v16" + "v0" ] }, - { - "in": [ - "0x00", - "v16" - ], - "op": "slt", - "out": [ - "v17" - ] - } - ], - "liveness": { - "in": [ - "v0" - ], - "out": [ - "v0" - ] - }, - "type": "BuiltinCall" - }, - { - "exit": { - "type": "Terminated" - }, - "id": "Block5", - "instructions": [ - { - "in": [ - "0x00", - "0x00" - ], - "op": "revert", - "out": [] - } - ], - "liveness": { - "in": [], - "out": [] + "type": "BuiltinCall" }, - "type": "BuiltinCall" - }, - { - "exit": { - "cond": "v28", - "targets": [ - "Block12", - "Block11" + { + "exit": { + "type": "Terminated" + }, + "id": "Block5", + "instructions": [ + { + "in": [ + "0x00", + "0x00" + ], + "op": "revert", + "out": [] + } ], - "type": "ConditionalJump" + "liveness": { + "in": [], + "out": [] + }, + "type": "BuiltinCall" }, - "id": "Block9", - "instructions": [ - { - "builtinArgs": [ - "C_19" + { + "exit": { + "cond": "v28", + "targets": [ + "Block12", + "Block11" ], - "in": [], - "op": "datasize", - "out": [ - "v18" - ] + "type": "ConditionalJump" }, - { + "id": "Block9", + "instructions": [ + { + "builtinArgs": [ + "C_19" + ], + "in": [], + "op": "datasize", + "out": [ + "v18" + ] + }, + { + "in": [ + "v18", + "v0" + ], + "op": "add", + "out": [ + "v24" + ] + }, + { + "in": [ + "v0", + "v24" + ], + "op": "lt", + "out": [ + "v25" + ] + }, + { + "in": [ + "0xffffffffffffffff", + "v24" + ], + "op": "gt", + "out": [ + "v27" + ] + }, + { + "in": [ + "v25", + "v27" + ], + "op": "or", + "out": [ + "v28" + ] + } + ], + "liveness": { "in": [ - "v18", "v0" ], - "op": "add", "out": [ - "v24" - ] - }, - { - "in": [ "v0", + "v18", "v24" - ], - "op": "lt", - "out": [ - "v25" - ] - }, - { - "in": [ - "0xffffffffffffffff", - "v24" - ], - "op": "gt", - "out": [ - "v27" ] }, - { - "in": [ - "v25", - "v27" - ], - "op": "or", - "out": [ - "v28" - ] - } - ], - "liveness": { - "in": [ - "v0" - ], - "out": [ - "v0", - "v18", - "v24" - ] - }, - "type": "BuiltinCall" - }, - { - "exit": { - "type": "Terminated" - }, - "id": "Block8", - "instructions": [ - { - "in": [ - "0x00", - "0x00" - ], - "op": "revert", - "out": [] - } - ], - "liveness": { - "in": [], - "out": [] + "type": "BuiltinCall" }, - "type": "BuiltinCall" - }, - { - "exit": { - "cond": "v42", - "targets": [ - "Block15", - "Block14" + { + "exit": { + "type": "Terminated" + }, + "id": "Block8", + "instructions": [ + { + "in": [ + "0x00", + "0x00" + ], + "op": "revert", + "out": [] + } ], - "type": "ConditionalJump" - }, - "id": "Block12", - "instructions": [ - { - "builtinArgs": [ - "C_19" - ], + "liveness": { "in": [], - "op": "dataoffset", - "out": [ - "v35" - ] - }, - { - "in": [ - "v18", - "v35", - "v0" - ], - "op": "datacopy", "out": [] }, - { - "in": [ - "v0", - "v24" + "type": "BuiltinCall" + }, + { + "exit": { + "cond": "v42", + "targets": [ + "Block15", + "Block14" ], - "op": "sub", - "out": [ - "v40" - ] + "type": "ConditionalJump" }, - { + "id": "Block12", + "instructions": [ + { + "builtinArgs": [ + "C_19" + ], + "in": [], + "op": "dataoffset", + "out": [ + "v35" + ] + }, + { + "in": [ + "v18", + "v35", + "v0" + ], + "op": "datacopy", + "out": [] + }, + { + "in": [ + "v0", + "v24" + ], + "op": "sub", + "out": [ + "v40" + ] + }, + { + "in": [ + "v40", + "v0", + "0x00" + ], + "op": "create", + "out": [ + "v41" + ] + }, + { + "in": [ + "v41" + ], + "op": "iszero", + "out": [ + "v42" + ] + } + ], + "liveness": { "in": [ - "v40", "v0", - "0x00" + "v18", + "v24" ], - "op": "create", "out": [ "v41" ] }, - { - "in": [ - "v41" - ], - "op": "iszero", - "out": [ - "v42" - ] - } - ], - "liveness": { - "in": [ - "v0", - "v18", - "v24" - ], - "out": [ - "v41" - ] - }, - "type": "BuiltinCall" - }, - { - "exit": { - "type": "Terminated" + "type": "BuiltinCall" }, - "id": "Block11", - "instructions": [ - { - "in": [ - "0x4e487b71", - "0xe0" - ], - "op": "shl", - "out": [ - "v30" - ] - }, - { - "in": [ - "v30", - "0x00" - ], - "op": "mstore", - "out": [] - }, - { - "in": [ - "0x41", - "0x04" - ], - "op": "mstore", - "out": [] + { + "exit": { + "type": "Terminated" }, - { - "in": [ - "0x24", - "0x00" - ], - "op": "revert", - "out": [] - } - ], - "liveness": { - "in": [], - "out": [] - }, - "type": "BuiltinCall" - }, - { - "exit": { - "cond": "v60", - "targets": [ - "Block18", - "Block17" + "id": "Block11", + "instructions": [ + { + "in": [ + "0x4e487b71", + "0xe0" + ], + "op": "shl", + "out": [ + "v30" + ] + }, + { + "in": [ + "v30", + "0x00" + ], + "op": "mstore", + "out": [] + }, + { + "in": [ + "0x41", + "0x04" + ], + "op": "mstore", + "out": [] + }, + { + "in": [ + "0x24", + "0x00" + ], + "op": "revert", + "out": [] + } ], - "type": "ConditionalJump" - }, - "id": "Block15", - "instructions": [ - { - "in": [ - "0x40" - ], - "op": "mload", - "out": [ - "v46" - ] - }, - { - "in": [ - "0x026121ff", - "0xe4" - ], - "op": "shl", - "out": [ - "v49" - ] - }, - { - "in": [ - "v49", - "v46" - ], - "op": "mstore", + "liveness": { + "in": [], "out": [] }, - { - "in": [ - "0x01", - "0xa0" - ], - "op": "shl", - "out": [ - "v53" - ] - }, - { - "in": [ - "0x01", - "v53" + "type": "BuiltinCall" + }, + { + "exit": { + "cond": "v60", + "targets": [ + "Block18", + "Block17" ], - "op": "sub", - "out": [ - "v54" - ] + "type": "ConditionalJump" }, - { + "id": "Block15", + "instructions": [ + { + "in": [ + "0x40" + ], + "op": "mload", + "out": [ + "v46" + ] + }, + { + "in": [ + "0x026121ff", + "0xe4" + ], + "op": "shl", + "out": [ + "v49" + ] + }, + { + "in": [ + "v49", + "v46" + ], + "op": "mstore", + "out": [] + }, + { + "in": [ + "0x01", + "0xa0" + ], + "op": "shl", + "out": [ + "v53" + ] + }, + { + "in": [ + "0x01", + "v53" + ], + "op": "sub", + "out": [ + "v54" + ] + }, + { + "in": [ + "v54", + "v41" + ], + "op": "and", + "out": [ + "v57" + ] + }, + { + "in": [], + "op": "gas", + "out": [ + "v58" + ] + }, + { + "in": [ + "0x20", + "v46", + "0x04", + "v46", + "v57", + "v58" + ], + "op": "staticcall", + "out": [ + "v59" + ] + }, + { + "in": [ + "v59" + ], + "op": "iszero", + "out": [ + "v60" + ] + } + ], + "liveness": { "in": [ - "v54", "v41" ], - "op": "and", - "out": [ - "v57" - ] - }, - { - "in": [], - "op": "gas", "out": [ - "v58" - ] - }, - { - "in": [ - "0x20", "v46", - "0x04", - "v46", - "v57", - "v58" - ], - "op": "staticcall", - "out": [ - "v59" - ] - }, - { - "in": [ "v59" - ], - "op": "iszero", - "out": [ - "v60" - ] - } - ], - "liveness": { - "in": [ - "v41" - ], - "out": [ - "v46", - "v59" - ] - }, - "type": "BuiltinCall" - }, - { - "exit": { - "type": "Terminated" - }, - "id": "Block14", - "instructions": [ - { - "in": [ - "0x40" - ], - "op": "mload", - "out": [ - "v43" - ] - }, - { - "in": [], - "op": "returndatasize", - "out": [ - "v44" - ] - }, - { - "in": [ - "v44", - "0x00", - "v43" - ], - "op": "returndatacopy", - "out": [] - }, - { - "in": [], - "op": "returndatasize", - "out": [ - "v45" - ] - }, - { - "in": [ - "v45", - "v43" - ], - "op": "revert", - "out": [] - } - ], - "liveness": { - "in": [], - "out": [] - }, - "type": "BuiltinCall" - }, - { - "exit": { - "cond": "v59", - "targets": [ - "Block21", - "Block20" - ], - "type": "ConditionalJump" - }, - "id": "Block18", - "instructions": [], - "liveness": { - "in": [ - "v46", - "v59" - ], - "out": [ - "v46" - ] - } - }, - { - "exit": { - "type": "Terminated" - }, - "id": "Block17", - "instructions": [ - { - "in": [ - "0x40" - ], - "op": "mload", - "out": [ - "v61" - ] - }, - { - "in": [], - "op": "returndatasize", - "out": [ - "v62" - ] - }, - { - "in": [ - "v62", - "0x00", - "v61" - ], - "op": "returndatacopy", - "out": [] - }, - { - "in": [], - "op": "returndatasize", - "out": [ - "v63" - ] - }, - { - "in": [ - "v63", - "v61" - ], - "op": "revert", - "out": [] - } - ], - "liveness": { - "in": [], - "out": [] - }, - "type": "BuiltinCall" - }, - { - "entries": [ - "Block18", - "Block28" - ], - "exit": { - "type": "Terminated" - }, - "id": "Block21", - "instructions": [ - { - "in": [ - "0x00", - "v93" - ], - "op": "PhiFunction", - "out": [ - "v95" ] }, - { - "in": [ - "0x40" - ], - "op": "mload", - "out": [ - "v94" - ] - }, - { - "in": [ - "v95", - "v94" - ], - "op": "mstore", - "out": [] - }, - { - "in": [ - "0x20", - "v94" - ], - "op": "return", - "out": [] - } - ], - "liveness": { - "in": [ - "v95" - ], - "out": [] - }, - "type": "BuiltinCall" - }, - { - "exit": { - "cond": "v67", - "targets": [ - "Block23", - "Block22" - ], - "type": "ConditionalJump" - }, - "id": "Block20", - "instructions": [ - { - "in": [], - "op": "returndatasize", - "out": [ - "v66" - ] - }, - { - "in": [ - "v66", - "0x20" - ], - "op": "gt", - "out": [ - "v67" - ] - } - ], - "liveness": { - "in": [ - "v46" - ], - "out": [ - "v46" - ] - }, - "type": "BuiltinCall" - }, - { - "entries": [ - "Block20", - "Block22" - ], - "exit": { - "cond": "v80", - "targets": [ - "Block25", - "Block24" - ], - "type": "ConditionalJump" + "type": "BuiltinCall" }, - "id": "Block23", - "instructions": [ - { - "in": [ - "0x20", - "v68" - ], - "op": "PhiFunction", - "out": [ - "v71" - ] - }, - { - "in": [ - "0x1f" - ], - "op": "not", - "out": [ - "v70" - ] - }, - { - "in": [ - "0x1f", - "v71" - ], - "op": "add", - "out": [ - "v72" - ] + { + "exit": { + "type": "Terminated" }, - { - "in": [ - "v70", - "v72" - ], - "op": "and", - "out": [ - "v73" - ] + "id": "Block14", + "instructions": [ + { + "in": [ + "0x40" + ], + "op": "mload", + "out": [ + "v43" + ] + }, + { + "in": [], + "op": "returndatasize", + "out": [ + "v44" + ] + }, + { + "in": [ + "v44", + "0x00", + "v43" + ], + "op": "returndatacopy", + "out": [] + }, + { + "in": [], + "op": "returndatasize", + "out": [ + "v45" + ] + }, + { + "in": [ + "v45", + "v43" + ], + "op": "revert", + "out": [] + } + ], + "liveness": { + "in": [], + "out": [] }, - { - "in": [ - "v73", - "v46" + "type": "BuiltinCall" + }, + { + "exit": { + "cond": "v59", + "targets": [ + "Block21", + "Block20" ], - "op": "add", - "out": [ - "v77" - ] + "type": "ConditionalJump" }, - { + "id": "Block18", + "instructions": [], + "liveness": { "in": [ "v46", - "v77" - ], - "op": "lt", - "out": [ - "v78" - ] - }, - { - "in": [ - "0xffffffffffffffff", - "v77" - ], - "op": "gt", - "out": [ - "v79" - ] - }, - { - "in": [ - "v78", - "v79" + "v59" ], - "op": "or", "out": [ - "v80" + "v46" ] } - ], - "liveness": { - "in": [ - "v46", - "v71" - ], - "out": [ - "v46", - "v71", - "v77" - ] }, - "type": "BuiltinCall" - }, - { - "exit": { - "targets": [ - "Block23" + { + "exit": { + "type": "Terminated" + }, + "id": "Block17", + "instructions": [ + { + "in": [ + "0x40" + ], + "op": "mload", + "out": [ + "v61" + ] + }, + { + "in": [], + "op": "returndatasize", + "out": [ + "v62" + ] + }, + { + "in": [ + "v62", + "0x00", + "v61" + ], + "op": "returndatacopy", + "out": [] + }, + { + "in": [], + "op": "returndatasize", + "out": [ + "v63" + ] + }, + { + "in": [ + "v63", + "v61" + ], + "op": "revert", + "out": [] + } ], - "type": "Jump" - }, - "id": "Block22", - "instructions": [ - { + "liveness": { "in": [], - "op": "returndatasize", - "out": [ - "v68" - ] - } - ], - "liveness": { - "in": [ - "v46" - ], - "out": [ - "v46", - "v68" - ] + "out": [] + }, + "type": "BuiltinCall" }, - "type": "BuiltinCall" - }, - { - "exit": { - "cond": "v90", - "targets": [ - "Block28", - "Block27" + { + "entries": [ + "Block18", + "Block28" ], - "type": "ConditionalJump" - }, - "id": "Block25", - "instructions": [ - { + "exit": { + "type": "Terminated" + }, + "id": "Block21", + "instructions": [ + { + "in": [ + "0x00", + "v93" + ], + "op": "PhiFunction", + "out": [ + "v95" + ] + }, + { + "in": [ + "0x40" + ], + "op": "mload", + "out": [ + "v94" + ] + }, + { + "in": [ + "v95", + "v94" + ], + "op": "mstore", + "out": [] + }, + { + "in": [ + "0x20", + "v94" + ], + "op": "return", + "out": [] + } + ], + "liveness": { "in": [ - "v77", - "0x40" + "v95" ], - "op": "mstore", "out": [] }, - { - "in": [ - "v71", - "v46" + "type": "BuiltinCall" + }, + { + "exit": { + "cond": "v67", + "targets": [ + "Block23", + "Block22" ], - "op": "add", - "out": [ - "v88" - ] + "type": "ConditionalJump" }, - { + "id": "Block20", + "instructions": [ + { + "in": [], + "op": "returndatasize", + "out": [ + "v66" + ] + }, + { + "in": [ + "v66", + "0x20" + ], + "op": "gt", + "out": [ + "v67" + ] + } + ], + "liveness": { "in": [ - "v46", - "v88" + "v46" ], - "op": "sub", "out": [ - "v89" + "v46" ] }, - { - "in": [ - "0x20", - "v89" + "type": "BuiltinCall" + }, + { + "entries": [ + "Block20", + "Block22" + ], + "exit": { + "cond": "v80", + "targets": [ + "Block25", + "Block24" ], - "op": "slt", - "out": [ - "v90" - ] - } - ], - "liveness": { - "in": [ - "v46", - "v71", - "v77" + "type": "ConditionalJump" + }, + "id": "Block23", + "instructions": [ + { + "in": [ + "0x20", + "v68" + ], + "op": "PhiFunction", + "out": [ + "v71" + ] + }, + { + "in": [ + "0x1f" + ], + "op": "not", + "out": [ + "v70" + ] + }, + { + "in": [ + "0x1f", + "v71" + ], + "op": "add", + "out": [ + "v72" + ] + }, + { + "in": [ + "v70", + "v72" + ], + "op": "and", + "out": [ + "v73" + ] + }, + { + "in": [ + "v73", + "v46" + ], + "op": "add", + "out": [ + "v77" + ] + }, + { + "in": [ + "v46", + "v77" + ], + "op": "lt", + "out": [ + "v78" + ] + }, + { + "in": [ + "0xffffffffffffffff", + "v77" + ], + "op": "gt", + "out": [ + "v79" + ] + }, + { + "in": [ + "v78", + "v79" + ], + "op": "or", + "out": [ + "v80" + ] + } ], - "out": [ - "v46" - ] - }, - "type": "BuiltinCall" - }, - { - "exit": { - "type": "Terminated" - }, - "id": "Block24", - "instructions": [ - { + "liveness": { "in": [ - "0x4e487b71", - "0xe0" + "v46", + "v71" ], - "op": "shl", "out": [ - "v81" + "v46", + "v71", + "v77" ] }, - { - "in": [ - "v81", - "0x00" - ], - "op": "mstore", - "out": [] - }, - { - "in": [ - "0x41", - "0x04" - ], - "op": "mstore", - "out": [] - }, - { - "in": [ - "0x24", - "0x00" - ], - "op": "revert", - "out": [] - } - ], - "liveness": { - "in": [], - "out": [] + "type": "BuiltinCall" }, - "type": "BuiltinCall" - }, - { - "exit": { - "targets": [ - "Block21" + { + "exit": { + "targets": [ + "Block23" + ], + "type": "Jump" + }, + "id": "Block22", + "instructions": [ + { + "in": [], + "op": "returndatasize", + "out": [ + "v68" + ] + } ], - "type": "Jump" - }, - "id": "Block28", - "instructions": [ - { + "liveness": { "in": [ "v46" ], - "op": "mload", "out": [ - "v93" + "v46", + "v68" ] - } - ], - "liveness": { - "in": [ - "v46" - ], - "out": [ - "v93" - ] - }, - "type": "BuiltinCall" - }, - { - "exit": { - "type": "Terminated" - }, - "id": "Block27", - "instructions": [ - { - "in": [ - "0x00", - "0x00" - ], - "op": "revert", - "out": [] - } - ], - "liveness": { - "in": [], - "out": [] + }, + "type": "BuiltinCall" }, - "type": "BuiltinCall" - } - ], - "functions": {} - }, - "subObjects": { - "C_19": { - "blocks": [ { "exit": { - "cond": "v2", + "cond": "v90", "targets": [ - "Block2", - "Block1" + "Block28", + "Block27" ], "type": "ConditionalJump" }, - "id": "Block0", + "id": "Block25", "instructions": [ { - "builtinArgs": [ - "0x80" + "in": [ + "v77", + "0x40" ], - "in": [], - "op": "memoryguard", + "op": "mstore", + "out": [] + }, + { + "in": [ + "v71", + "v46" + ], + "op": "add", "out": [ - "v0" + "v88" ] }, { "in": [ - "v0", - "0x40" + "v46", + "v88" ], - "op": "mstore", - "out": [] + "op": "sub", + "out": [ + "v89" + ] }, { - "in": [], - "op": "callvalue", + "in": [ + "0x20", + "v89" + ], + "op": "slt", "out": [ - "v2" + "v90" ] } ], "liveness": { - "in": [], + "in": [ + "v46", + "v71", + "v77" + ], "out": [ - "v0" + "v46" ] }, "type": "BuiltinCall" @@ -1729,51 +1580,75 @@ Yul Control Flow Graph: "exit": { "type": "Terminated" }, - "id": "Block2", + "id": "Block24", "instructions": [ { - "builtinArgs": [ - "C_19_deployed" + "in": [ + "0x4e487b71", + "0xe0" ], - "in": [], - "op": "datasize", + "op": "shl", "out": [ - "v4" + "v81" ] }, { - "builtinArgs": [ - "C_19_deployed" + "in": [ + "v81", + "0x00" ], - "in": [], - "op": "dataoffset", - "out": [ - "v5" - ] + "op": "mstore", + "out": [] }, { "in": [ - "v4", - "v5", - "v0" + "0x41", + "0x04" ], - "op": "codecopy", + "op": "mstore", "out": [] }, { "in": [ - "v4", - "v0" + "0x24", + "0x00" ], - "op": "return", + "op": "revert", "out": [] } ], + "liveness": { + "in": [], + "out": [] + }, + "type": "BuiltinCall" + }, + { + "exit": { + "targets": [ + "Block21" + ], + "type": "Jump" + }, + "id": "Block28", + "instructions": [ + { + "in": [ + "v46" + ], + "op": "mload", + "out": [ + "v93" + ] + } + ], "liveness": { "in": [ - "v0" + "v46" ], - "out": [] + "out": [ + "v93" + ] }, "type": "BuiltinCall" }, @@ -1781,7 +1656,7 @@ Yul Control Flow Graph: "exit": { "type": "Terminated" }, - "id": "Block1", + "id": "Block27", "instructions": [ { "in": [ @@ -1799,330 +1674,455 @@ Yul Control Flow Graph: "type": "BuiltinCall" } ], - "functions": {} - }, - "subObjects": { - "C_19_deployed": { - "blocks": [ - { - "exit": { - "cond": "v5", - "targets": [ - "Block2", - "Block1" - ], - "type": "ConditionalJump" - }, - "id": "Block0", - "instructions": [ - { - "builtinArgs": [ - "0x80" - ], - "in": [], - "op": "memoryguard", - "out": [ - "v0" - ] - }, - { - "in": [ - "v0", - "0x40" + "functions": {}, + "subObjects": { + "C_19": { + "blocks": [ + { + "exit": { + "cond": "v2", + "targets": [ + "Block2", + "Block1" ], - "op": "mstore", - "out": [] + "type": "ConditionalJump" }, - { + "id": "Block0", + "instructions": [ + { + "builtinArgs": [ + "0x80" + ], + "in": [], + "op": "memoryguard", + "out": [ + "v0" + ] + }, + { + "in": [ + "v0", + "0x40" + ], + "op": "mstore", + "out": [] + }, + { + "in": [], + "op": "callvalue", + "out": [ + "v2" + ] + } + ], + "liveness": { "in": [], - "op": "calldatasize", "out": [ - "v3" - ] - }, - { - "in": [ - "0x04", - "v3" - ], - "op": "lt", - "out": [ - "v4" + "v0" ] }, - { - "in": [ - "v4" - ], - "op": "iszero", - "out": [ - "v5" - ] - } - ], - "liveness": { - "in": [], - "out": [ - "v0" - ] - }, - "type": "BuiltinCall" - }, - { - "exit": { - "type": "Terminated" - }, - "id": "Block2", - "instructions": [ - { - "in": [ - "0x00", - "0x00" - ], - "op": "revert", - "out": [] - } - ], - "liveness": { - "in": [], - "out": [] + "type": "BuiltinCall" }, - "type": "BuiltinCall" - }, - { - "exit": { - "cond": "v11", - "targets": [ - "Block4", - "Block3" - ], - "type": "ConditionalJump" - }, - "id": "Block1", - "instructions": [ - { - "in": [ - "0x00" - ], - "op": "calldataload", - "out": [ - "v7" - ] - }, - { - "in": [ - "v7", - "0xe0" - ], - "op": "shr", - "out": [ - "v9" - ] + { + "exit": { + "type": "Terminated" }, - { - "in": [ - "v9", - "0x26121ff0" - ], - "op": "eq", - "out": [ - "v11" - ] - } - ], - "liveness": { - "in": [ - "v0" - ], - "out": [ - "v0" - ] - }, - "type": "BuiltinCall" - }, - { - "exit": { - "targets": [ - "Block2" + "id": "Block2", + "instructions": [ + { + "builtinArgs": [ + "C_19_deployed" + ], + "in": [], + "op": "datasize", + "out": [ + "v4" + ] + }, + { + "builtinArgs": [ + "C_19_deployed" + ], + "in": [], + "op": "dataoffset", + "out": [ + "v5" + ] + }, + { + "in": [ + "v4", + "v5", + "v0" + ], + "op": "codecopy", + "out": [] + }, + { + "in": [ + "v4", + "v0" + ], + "op": "return", + "out": [] + } ], - "type": "Jump" - }, - "id": "Block4", - "instructions": [], - "liveness": { - "in": [], - "out": [] - } - }, - { - "exit": { - "cond": "v12", - "targets": [ - "Block6", - "Block5" - ], - "type": "ConditionalJump" - }, - "id": "Block3", - "instructions": [ - { - "in": [], - "op": "callvalue", - "out": [ - "v12" - ] - } - ], - "liveness": { - "in": [ - "v0" - ], - "out": [ - "v0" - ] - }, - "type": "BuiltinCall" - }, - { - "exit": { - "cond": "v17", - "targets": [ - "Block9", - "Block8" - ], - "type": "ConditionalJump" - }, - "id": "Block6", - "instructions": [ - { + "liveness": { "in": [ - "0x03" + "v0" ], - "op": "not", - "out": [ - "v14" - ] - }, - { - "in": [], - "op": "calldatasize", - "out": [ - "v15" - ] + "out": [] }, - { - "in": [ - "v14", - "v15" - ], - "op": "add", - "out": [ - "v16" - ] + "type": "BuiltinCall" + }, + { + "exit": { + "type": "Terminated" }, - { - "in": [ - "0x00", - "v16" - ], - "op": "slt", - "out": [ - "v17" - ] - } - ], - "liveness": { - "in": [ - "v0" + "id": "Block1", + "instructions": [ + { + "in": [ + "0x00", + "0x00" + ], + "op": "revert", + "out": [] + } ], - "out": [ - "v0" - ] - }, - "type": "BuiltinCall" - }, - { - "exit": { - "type": "Terminated" - }, - "id": "Block5", - "instructions": [ - { - "in": [ - "0x00", - "0x00" - ], - "op": "revert", - "out": [] - } - ], - "liveness": { - "in": [], - "out": [] - }, - "type": "BuiltinCall" - }, - { - "exit": { - "type": "Terminated" - }, - "id": "Block9", - "instructions": [ - { - "in": [ - "0x2a", - "v0" - ], - "op": "mstore", + "liveness": { + "in": [], "out": [] }, - { - "in": [ - "0x20", - "v0" - ], - "op": "return", - "out": [] - } - ], - "liveness": { - "in": [ - "v0" + "type": "BuiltinCall" + } + ], + "functions": {}, + "subObjects": { + "C_19_deployed": { + "blocks": [ + { + "exit": { + "cond": "v5", + "targets": [ + "Block2", + "Block1" + ], + "type": "ConditionalJump" + }, + "id": "Block0", + "instructions": [ + { + "builtinArgs": [ + "0x80" + ], + "in": [], + "op": "memoryguard", + "out": [ + "v0" + ] + }, + { + "in": [ + "v0", + "0x40" + ], + "op": "mstore", + "out": [] + }, + { + "in": [], + "op": "calldatasize", + "out": [ + "v3" + ] + }, + { + "in": [ + "0x04", + "v3" + ], + "op": "lt", + "out": [ + "v4" + ] + }, + { + "in": [ + "v4" + ], + "op": "iszero", + "out": [ + "v5" + ] + } + ], + "liveness": { + "in": [], + "out": [ + "v0" + ] + }, + "type": "BuiltinCall" + }, + { + "exit": { + "type": "Terminated" + }, + "id": "Block2", + "instructions": [ + { + "in": [ + "0x00", + "0x00" + ], + "op": "revert", + "out": [] + } + ], + "liveness": { + "in": [], + "out": [] + }, + "type": "BuiltinCall" + }, + { + "exit": { + "cond": "v11", + "targets": [ + "Block4", + "Block3" + ], + "type": "ConditionalJump" + }, + "id": "Block1", + "instructions": [ + { + "in": [ + "0x00" + ], + "op": "calldataload", + "out": [ + "v7" + ] + }, + { + "in": [ + "v7", + "0xe0" + ], + "op": "shr", + "out": [ + "v9" + ] + }, + { + "in": [ + "v9", + "0x26121ff0" + ], + "op": "eq", + "out": [ + "v11" + ] + } + ], + "liveness": { + "in": [ + "v0" + ], + "out": [ + "v0" + ] + }, + "type": "BuiltinCall" + }, + { + "exit": { + "targets": [ + "Block2" + ], + "type": "Jump" + }, + "id": "Block4", + "instructions": [], + "liveness": { + "in": [], + "out": [] + } + }, + { + "exit": { + "cond": "v12", + "targets": [ + "Block6", + "Block5" + ], + "type": "ConditionalJump" + }, + "id": "Block3", + "instructions": [ + { + "in": [], + "op": "callvalue", + "out": [ + "v12" + ] + } + ], + "liveness": { + "in": [ + "v0" + ], + "out": [ + "v0" + ] + }, + "type": "BuiltinCall" + }, + { + "exit": { + "cond": "v17", + "targets": [ + "Block9", + "Block8" + ], + "type": "ConditionalJump" + }, + "id": "Block6", + "instructions": [ + { + "in": [ + "0x03" + ], + "op": "not", + "out": [ + "v14" + ] + }, + { + "in": [], + "op": "calldatasize", + "out": [ + "v15" + ] + }, + { + "in": [ + "v14", + "v15" + ], + "op": "add", + "out": [ + "v16" + ] + }, + { + "in": [ + "0x00", + "v16" + ], + "op": "slt", + "out": [ + "v17" + ] + } + ], + "liveness": { + "in": [ + "v0" + ], + "out": [ + "v0" + ] + }, + "type": "BuiltinCall" + }, + { + "exit": { + "type": "Terminated" + }, + "id": "Block5", + "instructions": [ + { + "in": [ + "0x00", + "0x00" + ], + "op": "revert", + "out": [] + } + ], + "liveness": { + "in": [], + "out": [] + }, + "type": "BuiltinCall" + }, + { + "exit": { + "type": "Terminated" + }, + "id": "Block9", + "instructions": [ + { + "in": [ + "0x2a", + "v0" + ], + "op": "mstore", + "out": [] + }, + { + "in": [ + "0x20", + "v0" + ], + "op": "return", + "out": [] + } + ], + "liveness": { + "in": [ + "v0" + ], + "out": [] + }, + "type": "BuiltinCall" + }, + { + "exit": { + "type": "Terminated" + }, + "id": "Block8", + "instructions": [ + { + "in": [ + "0x00", + "0x00" + ], + "op": "revert", + "out": [] + } + ], + "liveness": { + "in": [], + "out": [] + }, + "type": "BuiltinCall" + } ], - "out": [] - }, - "type": "BuiltinCall" - }, - { - "exit": { - "type": "Terminated" - }, - "id": "Block8", - "instructions": [ - { - "in": [ - "0x00", - "0x00" - ], - "op": "revert", - "out": [] - } - ], - "liveness": { - "in": [], - "out": [] + "functions": {}, + "subObjects": {} }, - "type": "BuiltinCall" + "type": "subObject" } - ], - "functions": {} - }, - "subObjects": {}, - "type": "subObject" + }, + "type": "subObject" + } }, "type": "subObject" - }, - "type": "subObject" + } }, "type": "Object" } From 18c4a778fd3a3d2e90e1edc03f80ff37a2668bac Mon Sep 17 00:00:00 2001 From: Alexander Arlt Date: Wed, 8 Jan 2025 16:09:25 +0100 Subject: [PATCH 0680/1022] Remove unnecessary virtual specifier. --- libevmasm/EVMAssemblyStack.h | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/libevmasm/EVMAssemblyStack.h b/libevmasm/EVMAssemblyStack.h index cf959de79c1a..55c9fd684ecc 100644 --- a/libevmasm/EVMAssemblyStack.h +++ b/libevmasm/EVMAssemblyStack.h @@ -50,25 +50,25 @@ class EVMAssemblyStack: public AbstractAssemblyStack std::string const& name() const { return m_name; } - virtual LinkerObject const& object(std::string const& _contractName) const override; - virtual LinkerObject const& runtimeObject(std::string const& _contractName) const override; + LinkerObject const& object(std::string const& _contractName) const override; + LinkerObject const& runtimeObject(std::string const& _contractName) const override; std::shared_ptr const& evmAssembly() const { return m_evmAssembly; } std::shared_ptr const& evmRuntimeAssembly() const { return m_evmRuntimeAssembly; } - virtual std::string const* sourceMapping(std::string const& _contractName) const override; - virtual std::string const* runtimeSourceMapping(std::string const& _contractName) const override; + std::string const* sourceMapping(std::string const& _contractName) const override; + std::string const* runtimeSourceMapping(std::string const& _contractName) const override; - virtual Json assemblyJSON(std::string const& _contractName) const override; - virtual std::string assemblyString(std::string const& _contractName, StringMap const& _sourceCodes) const override; + Json assemblyJSON(std::string const& _contractName) const override; + std::string assemblyString(std::string const& _contractName, StringMap const& _sourceCodes) const override; - virtual std::string const filesystemFriendlyName(std::string const& _contractName) const override; + std::string const filesystemFriendlyName(std::string const& _contractName) const override; - virtual std::vector contractNames() const override { return {m_name}; } - virtual std::vector sourceNames() const override; + std::vector contractNames() const override { return {m_name}; } + std::vector sourceNames() const override; std::map sourceIndices() const; - virtual bool compilationSuccessful() const override { return m_evmAssembly != nullptr; } + bool compilationSuccessful() const override { return m_evmAssembly != nullptr; } void selectDebugInfo(langutil::DebugInfoSelection _debugInfoSelection) { From d17a4dd777d4d12724455fe92897047fb4b93243 Mon Sep 17 00:00:00 2001 From: santamasa <0xstarker@gmail.com> Date: Wed, 8 Jan 2025 21:10:43 +0300 Subject: [PATCH 0681/1022] docs: typo fix Update CODE_OF_CONDUCT.md --- CODE_OF_CONDUCT.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index 273eac6020ed..898042b7f8c3 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -3,7 +3,7 @@ ## Our Pledge In the interest of fostering an open and welcoming environment, we as -contributors and maintainers pledge to making participation in our project and +contributors and maintainers pledge to make participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socioeconomic status, nationality, personal From d90acc1c77ca9746dcc80ce63d76dd7e4e6c52aa Mon Sep 17 00:00:00 2001 From: DaniPopes <57450786+DaniPopes@users.noreply.github.com> Date: Mon, 6 Jan 2025 00:52:48 +0100 Subject: [PATCH 0682/1022] Reduce some file system paths' lengths --- .../input.json | 27 ---------------- .../output.json | 32 ------------------- 2 files changed, 59 deletions(-) delete mode 100644 test/cmdlineTests/standard_model_checker_show_unsupported_false_all_engines/standard_model_checker_show_unsupported_false_all_enginesstandard_model_checker_show_unsupported_false_bmc/input.json delete mode 100644 test/cmdlineTests/standard_model_checker_show_unsupported_false_all_engines/standard_model_checker_show_unsupported_false_all_enginesstandard_model_checker_show_unsupported_false_bmc/output.json diff --git a/test/cmdlineTests/standard_model_checker_show_unsupported_false_all_engines/standard_model_checker_show_unsupported_false_all_enginesstandard_model_checker_show_unsupported_false_bmc/input.json b/test/cmdlineTests/standard_model_checker_show_unsupported_false_all_engines/standard_model_checker_show_unsupported_false_all_enginesstandard_model_checker_show_unsupported_false_bmc/input.json deleted file mode 100644 index e3a42c295f8c..000000000000 --- a/test/cmdlineTests/standard_model_checker_show_unsupported_false_all_engines/standard_model_checker_show_unsupported_false_all_enginesstandard_model_checker_show_unsupported_false_bmc/input.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "language": "Solidity", - "sources": - { - "A": - { - "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\n\ncontract test { - struct S { - uint x; - } - S s; - function f(bool b) public { - s.x |= b ? 1 : 2; - assert(s.x > 0); - } - }" - } - }, - "settings": - { - "modelChecker": - { - "engine": "all", - "showUnsupported": false - } - } -} diff --git a/test/cmdlineTests/standard_model_checker_show_unsupported_false_all_engines/standard_model_checker_show_unsupported_false_all_enginesstandard_model_checker_show_unsupported_false_bmc/output.json b/test/cmdlineTests/standard_model_checker_show_unsupported_false_all_engines/standard_model_checker_show_unsupported_false_all_enginesstandard_model_checker_show_unsupported_false_bmc/output.json deleted file mode 100644 index fb599d21d2e4..000000000000 --- a/test/cmdlineTests/standard_model_checker_show_unsupported_false_all_engines/standard_model_checker_show_unsupported_false_all_enginesstandard_model_checker_show_unsupported_false_bmc/output.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "errors": - [ - { - "component": "general", - "errorCode": "5840", - "formattedMessage": "Warning: CHC: 1 verification condition(s) could not be proved. Enable the model checker option \"show unproved\" to see all of them. Consider choosing a specific contract to be verified in order to reduce the solving problems. Consider increasing the timeout per query. - -", - "message": "CHC: 1 verification condition(s) could not be proved. Enable the model checker option \"show unproved\" to see all of them. Consider choosing a specific contract to be verified in order to reduce the solving problems. Consider increasing the timeout per query.", - "severity": "warning", - "type": "Warning" - }, - { - "component": "general", - "errorCode": "2788", - "formattedMessage": "Warning: BMC: 1 verification condition(s) could not be proved. Enable the model checker option \"show unproved\" to see all of them. Consider choosing a specific contract to be verified in order to reduce the solving problems. Consider increasing the timeout per query. - -", - "message": "BMC: 1 verification condition(s) could not be proved. Enable the model checker option \"show unproved\" to see all of them. Consider choosing a specific contract to be verified in order to reduce the solving problems. Consider increasing the timeout per query.", - "severity": "warning", - "type": "Warning" - } - ], - "sources": - { - "A": - { - "id": 0 - } - } -} From eabc97a252bd27014208e6e23cbfbd9de737b89c Mon Sep 17 00:00:00 2001 From: Marco Date: Fri, 3 Jan 2025 15:45:35 +0100 Subject: [PATCH 0683/1022] typo assembly.rst --- docs/assembly.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/assembly.rst b/docs/assembly.rst index 09e158e489c6..c1af2907aed8 100644 --- a/docs/assembly.rst +++ b/docs/assembly.rst @@ -209,7 +209,7 @@ Local Solidity variables are available for assignments, for example: ``assembly { signextend(, x) }`` -Since Solidity 0.6.0, the name of a inline assembly variable may not +Since Solidity 0.6.0, the name of an inline assembly variable may not shadow any declaration visible in the scope of the inline assembly block (including variable, contract and function declarations). From 0191fd99792cf2e389fb909cdda0b3a307330b02 Mon Sep 17 00:00:00 2001 From: Marco Date: Fri, 3 Jan 2025 15:46:24 +0100 Subject: [PATCH 0684/1022] typo circular_reference_internal_function.sol --- .../bytecodeReferences/circular_reference_internal_function.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/libsolidity/syntaxTests/bytecodeReferences/circular_reference_internal_function.sol b/test/libsolidity/syntaxTests/bytecodeReferences/circular_reference_internal_function.sol index 0b06b2b7ae12..f25690aadc57 100644 --- a/test/libsolidity/syntaxTests/bytecodeReferences/circular_reference_internal_function.sol +++ b/test/libsolidity/syntaxTests/bytecodeReferences/circular_reference_internal_function.sol @@ -1,6 +1,6 @@ contract C { - // Internal uncalled function should not cause an cyclic dep. error + // Internal uncalled function should not cause a cyclic dep. error function foo() internal { new D(); } function callFoo() virtual public { foo(); } } From 94bfae1a941606bd3f90f1c2bf8dcae45dbc904a Mon Sep 17 00:00:00 2001 From: "gmh5225.eth" <13917777+gmh5225@users.noreply.github.com> Date: Tue, 24 Dec 2024 22:34:07 +0800 Subject: [PATCH 0685/1022] fix compilation error on MSVC --- liblangutil/EVMVersion.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/liblangutil/EVMVersion.cpp b/liblangutil/EVMVersion.cpp index 6f7ac91397d9..832b6ebaaf6b 100644 --- a/liblangutil/EVMVersion.cpp +++ b/liblangutil/EVMVersion.cpp @@ -19,8 +19,9 @@ * EVM versioning. */ -#include #include +#include + using namespace solidity; using namespace solidity::evmasm; @@ -29,7 +30,7 @@ using namespace solidity::langutil; bool EVMVersion::hasOpcode(Instruction _opcode, std::optional _eofVersion) const { // EOF version can be only defined since prague - assert(!_eofVersion.has_value() || this->m_version >= prague()); + assert(!_eofVersion.has_value() || static_cast(m_version) >= static_cast(prague().m_version)); switch (_opcode) { From 9446ea1a12385226b26d3ee5229d66e8de9eda92 Mon Sep 17 00:00:00 2001 From: gmh5225 <2315157@qq.com> Date: Sat, 28 Dec 2024 02:55:00 +0800 Subject: [PATCH 0686/1022] Fix MSVC compilation error on EVMVersion comparison --- liblangutil/EVMVersion.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/liblangutil/EVMVersion.cpp b/liblangutil/EVMVersion.cpp index 832b6ebaaf6b..ac087b8fcc47 100644 --- a/liblangutil/EVMVersion.cpp +++ b/liblangutil/EVMVersion.cpp @@ -19,9 +19,8 @@ * EVM versioning. */ -#include #include - +#include using namespace solidity; using namespace solidity::evmasm; @@ -30,7 +29,7 @@ using namespace solidity::langutil; bool EVMVersion::hasOpcode(Instruction _opcode, std::optional _eofVersion) const { // EOF version can be only defined since prague - assert(!_eofVersion.has_value() || static_cast(m_version) >= static_cast(prague().m_version)); + assert(!_eofVersion.has_value() || *this >= prague()); switch (_opcode) { From 4f5adf4444db7763134e0bed37d78c056cf6f059 Mon Sep 17 00:00:00 2001 From: "gmh5225.eth" <13917777+gmh5225@users.noreply.github.com> Date: Tue, 24 Dec 2024 20:05:36 +0800 Subject: [PATCH 0687/1022] fix correct Boost compilation flags --- docs/installing-solidity.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/installing-solidity.rst b/docs/installing-solidity.rst index 0d63d48212f9..57499b812166 100644 --- a/docs/installing-solidity.rst +++ b/docs/installing-solidity.rst @@ -505,7 +505,7 @@ And for Windows: cmake -G "Visual Studio 16 2019" .. In case you want to use the version of boost installed by ``scripts\install_deps.ps1``, you will -additionally need to pass ``-DBoost_DIR="deps\boost\lib\cmake\Boost-*"`` and ``-DCMAKE_MSVC_RUNTIME_LIBRARY=MultiThreaded`` +additionally need to pass ``-DBoost_ROOT="deps/boost" -DBoost_INCLUDE_DIR="deps/boost/include"`` and ``-DCMAKE_MSVC_RUNTIME_LIBRARY=MultiThreaded`` as arguments to the call to ``cmake``. This should result in the creation of **solidity.sln** in that build directory. From 225ccac729ddcd7bc5ce1e9b3d66511a9d627920 Mon Sep 17 00:00:00 2001 From: Martin Blicha Date: Thu, 9 Jan 2025 16:54:00 +0100 Subject: [PATCH 0688/1022] SMTChecker: Fix error when initializing fixed-sized-bytes array When encoding initialization of an array of fixed-sized bytes, we need to make sure the elements of the inlined array have the right SMT sort. Because of implict conversion from string literals to fixed-sized bytes, we need to pass the information about the desired type when encoding the individual elements. --- Changelog.md | 7 ++++--- libsolidity/formal/SMTEncoder.cpp | 8 +++++--- .../fixed_bytes_array_from_strig_inline_array.sol | 14 ++++++++++++++ 3 files changed, 23 insertions(+), 6 deletions(-) create mode 100644 test/libsolidity/smtCheckerTests/typecast/fixed_bytes_array_from_strig_inline_array.sol diff --git a/Changelog.md b/Changelog.md index 731640653d5a..521ee8793e88 100644 --- a/Changelog.md +++ b/Changelog.md @@ -9,9 +9,10 @@ Compiler Features: Bugfixes: -* General: Fix internal compiler error when requesting IR AST outputs for interfaces and abstract contracts. -* Standard JSON Interface: Fix ``generatedSources`` and ``sourceMap`` being generated internally even when not requested. -* Yul: Fix internal compiler error when a code generation error should be reported instead. + * General: Fix internal compiler error when requesting IR AST outputs for interfaces and abstract contracts. + * SMTChecker: Fix SMT logic error when initializing a fixed-sized-bytes array using string literals. + * Standard JSON Interface: Fix ``generatedSources`` and ``sourceMap`` being generated internally even when not requested. + * Yul: Fix internal compiler error when a code generation error should be reported instead. ### 0.8.28 (2024-10-09) diff --git a/libsolidity/formal/SMTEncoder.cpp b/libsolidity/formal/SMTEncoder.cpp index 7e338d9f80b9..01627007f03e 100644 --- a/libsolidity/formal/SMTEncoder.cpp +++ b/libsolidity/formal/SMTEncoder.cpp @@ -428,9 +428,11 @@ void SMTEncoder::endVisit(TupleExpression const& _tuple) { // Add constraints for the length and values as it is known. auto symbArray = std::dynamic_pointer_cast(m_context.expression(_tuple)); - solAssert(symbArray, ""); - - addArrayLiteralAssertions(*symbArray, applyMap(_tuple.components(), [&](auto const& c) { return expr(*c); })); + smtAssert(symbArray, "Inline array must be represented with SymbolicArrayVariable"); + auto originalType = symbArray->originalType(); + auto arrayType = dynamic_cast(originalType); + smtAssert(arrayType, "Type of inline array must be ArrayType"); + addArrayLiteralAssertions(*symbArray, applyMap(_tuple.components(), [&](auto const& c) { return expr(*c, arrayType->baseType()); })); } else { diff --git a/test/libsolidity/smtCheckerTests/typecast/fixed_bytes_array_from_strig_inline_array.sol b/test/libsolidity/smtCheckerTests/typecast/fixed_bytes_array_from_strig_inline_array.sol new file mode 100644 index 000000000000..c92fe2a7e356 --- /dev/null +++ b/test/libsolidity/smtCheckerTests/typecast/fixed_bytes_array_from_strig_inline_array.sol @@ -0,0 +1,14 @@ +contract D { + function test() public pure { + bytes7[2] memory dummyBytes = [bytes7("A"), "B"]; + assert(uint56(dummyBytes[0]) == 0x41000000000000); + assert(uint56(dummyBytes[1]) == 0x42000000000000); + assert(uint56(dummyBytes[1]) == 0x41000000000000); // Should fail + } +} +// ==== +// SMTEngine: chc +// SMTTargets: assert +// ---- +// Warning 6328: (231-280): CHC: Assertion violation happens here.\nCounterexample:\n\ndummyBytes = [0x41000000000000, 0x42000000000000]\n\nTransaction trace:\nD.constructor()\nD.test() +// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. From 32c546f899b1b72fca058d6b50fbb1a8d0f41af6 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Thu, 9 Jan 2025 12:52:32 +0100 Subject: [PATCH 0689/1022] Yul control flow: Add toDot method to liveness --- libyul/backends/evm/ControlFlow.cpp | 5 +++++ libyul/backends/evm/ControlFlow.h | 2 ++ 2 files changed, 7 insertions(+) diff --git a/libyul/backends/evm/ControlFlow.cpp b/libyul/backends/evm/ControlFlow.cpp index 3ec123a8ed7c..863fa30f6c7d 100644 --- a/libyul/backends/evm/ControlFlow.cpp +++ b/libyul/backends/evm/ControlFlow.cpp @@ -26,3 +26,8 @@ ControlFlowLiveness::ControlFlowLiveness(ControlFlow const& _controlFlow): mainLiveness(std::make_unique(*_controlFlow.mainGraph)), functionLiveness(_controlFlow.functionGraphs | ranges::views::transform([](auto const& _cfg) { return std::make_unique(*_cfg); }) | ranges::to) { } + +std::string ControlFlowLiveness::toDot() const +{ + return controlFlow.get().toDot(this); +} diff --git a/libyul/backends/evm/ControlFlow.h b/libyul/backends/evm/ControlFlow.h index 6438f330c386..394ce00c58c4 100644 --- a/libyul/backends/evm/ControlFlow.h +++ b/libyul/backends/evm/ControlFlow.h @@ -34,6 +34,8 @@ struct ControlFlowLiveness{ std::reference_wrapper controlFlow; std::unique_ptr mainLiveness; std::vector> functionLiveness; + + std::string toDot() const; }; struct ControlFlow From fce849d558f2cf9bd24518e3efb6c9b7f1bdfc48 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Thu, 9 Jan 2025 12:53:27 +0100 Subject: [PATCH 0690/1022] SSA CFG to dot: Replaces reserved dollar characters in function names --- libyul/backends/evm/SSAControlFlowGraph.cpp | 31 +++++++++++++++++---- 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/libyul/backends/evm/SSAControlFlowGraph.cpp b/libyul/backends/evm/SSAControlFlowGraph.cpp index 8e52e78e7983..733f4967d806 100644 --- a/libyul/backends/evm/SSAControlFlowGraph.cpp +++ b/libyul/backends/evm/SSAControlFlowGraph.cpp @@ -77,6 +77,25 @@ class SSACFGPrinter ); } + static std::string escape(std::string_view const str) + { + using namespace std::literals; + static constexpr auto replacements = std::array{std::make_tuple('$', "_d_")}; + std::stringstream ss; + for (auto const c: str) + { + auto const it = std::find_if(replacements.begin(), replacements.end(), [c](auto const& replacement) + { + return std::get<0>(replacement) == c; + }); + if (it != replacements.end()) + ss << std::get<1>(*it); + else + ss << c; + } + return ss.str(); + } + std::string formatBlockHandle(SSACFG::BlockId const& _id) const { return fmt::format("Block{}_{}", m_functionIndex, _id.value); @@ -157,7 +176,7 @@ class SSACFGPrinter ); m_result << fmt::format( "{}({})\\l\\\n", - label, + escape(label), fmt::join(operation.inputs | ranges::views::transform(valueToString), ", ") ); } @@ -247,15 +266,15 @@ class SSACFGPrinter void printFunction(Scope::Function const& _fun) { - static auto constexpr returnsTransform = [](auto const& functionReturnValue) { return functionReturnValue.get().name.str(); }; + static auto constexpr returnsTransform = [](auto const& functionReturnValue) { return escape(functionReturnValue.get().name.str()); }; static auto constexpr argsTransform = [](auto const& arg) { return fmt::format("v{}", std::get<1>(arg).value); }; - m_result << "FunctionEntry_" << _fun.name.str() << "_" << m_cfg.entry.value << " [label=\""; + m_result << "FunctionEntry_" << escape(_fun.name.str()) << "_" << m_cfg.entry.value << " [label=\""; if (!m_cfg.returns.empty()) - m_result << fmt::format("function {0}:\n {1} := {0}({2})", _fun.name.str(), fmt::join(m_cfg.returns | ranges::views::transform(returnsTransform), ", "), fmt::join(m_cfg.arguments | ranges::views::transform(argsTransform), ", ")); + m_result << fmt::format("function {0}:\n {1} := {0}({2})", escape(_fun.name.str()), fmt::join(m_cfg.returns | ranges::views::transform(returnsTransform), ", "), fmt::join(m_cfg.arguments | ranges::views::transform(argsTransform), ", ")); else - m_result << fmt::format("function {0}:\n {0}({1})", _fun.name.str(), fmt::join(m_cfg.arguments | ranges::views::transform(argsTransform), ", ")); + m_result << fmt::format("function {0}:\n {0}({1})", escape(_fun.name.str()), fmt::join(m_cfg.arguments | ranges::views::transform(argsTransform), ", ")); m_result << "\"];\n"; - m_result << "FunctionEntry_" << _fun.name.str() << "_" << m_cfg.entry.value << " -> Block" << m_functionIndex << "_" << m_cfg.entry.value << ";\n"; + m_result << "FunctionEntry_" << escape(_fun.name.str()) << "_" << m_cfg.entry.value << " -> Block" << m_functionIndex << "_" << m_cfg.entry.value << ";\n"; printBlock(m_cfg.entry); } From 74314fc77e295659d3772265e7b40166ba9991c6 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Thu, 9 Jan 2025 14:12:56 +0100 Subject: [PATCH 0691/1022] Liveness: Add block exit values to live set for op-wise sets --- libyul/backends/evm/SSACFGLiveness.cpp | 53 ++++++++++++----------- libyul/backends/evm/SSACFGLiveness.h | 1 + libyul/backends/evm/SSAControlFlowGraph.h | 14 +++++- 3 files changed, 42 insertions(+), 26 deletions(-) diff --git a/libyul/backends/evm/SSACFGLiveness.cpp b/libyul/backends/evm/SSACFGLiveness.cpp index aecaed6ffa18..a0bfeb5bb143 100644 --- a/libyul/backends/evm/SSACFGLiveness.cpp +++ b/libyul/backends/evm/SSACFGLiveness.cpp @@ -37,6 +37,29 @@ constexpr auto literalsFilter(SSACFG const& _cfg) } } +std::set SSACFGLiveness::blockExitValues(SSACFG::BlockId const& _blockId) const +{ + std::set result; + util::GenericVisitor exitVisitor { + [](SSACFG::BasicBlock::MainExit const&) {}, + [&](SSACFG::BasicBlock::FunctionReturn const& _functionReturn) { + result += _functionReturn.returnValues | ranges::views::filter(literalsFilter(m_cfg)); + }, + [&](SSACFG::BasicBlock::JumpTable const& _jt) { + if (literalsFilter(m_cfg)(_jt.value)) + result.emplace(_jt.value); + }, + [](SSACFG::BasicBlock::Jump const&) {}, + [&](SSACFG::BasicBlock::ConditionalJump const& _conditionalJump) { + if (literalsFilter(m_cfg)(_conditionalJump.condition)) + result.emplace(_conditionalJump.condition); + }, + [](SSACFG::BasicBlock::Terminated const&) {} + }; + std::visit(exitVisitor, m_cfg.block(_blockId).exit); + return result; +} + SSACFGLiveness::SSACFGLiveness(SSACFG const& _cfg): m_cfg(_cfg), m_topologicalSort(_cfg), @@ -70,12 +93,7 @@ void SSACFGLiveness::runDagDfs() { auto const& info = m_cfg.valueInfo(phi); yulAssert(std::holds_alternative(info), "value info of phi wasn't PhiValue"); - auto const& entries = m_cfg.block(std::get(info).block).entries; - // this is getting the argument index of the phi function corresponding to the path going - // through "blockId", ie, the currently handled block - auto const it = entries.find(blockId); - yulAssert(it != entries.end()); - auto const argIndex = static_cast(std::distance(entries.begin(), it)); + auto const argIndex = m_cfg.phiArgumentIndex(blockId, _successor); yulAssert(argIndex < std::get(info).arguments.size()); auto const arg = std::get(info).arguments.at(argIndex); if (!std::holds_alternative(m_cfg.valueInfo(arg))) @@ -103,23 +121,7 @@ void SSACFGLiveness::runDagDfs() // for each program point p in B, backwards, do: { // add value ids to the live set that are used in exit blocks - util::GenericVisitor exitVisitor { - [](SSACFG::BasicBlock::MainExit const&) {}, - [&](SSACFG::BasicBlock::FunctionReturn const& _functionReturn) { - live += _functionReturn.returnValues | ranges::views::filter(literalsFilter(m_cfg)); - }, - [&](SSACFG::BasicBlock::JumpTable const& _jt) { - if (literalsFilter(m_cfg)(_jt.value)) - live.emplace(_jt.value); - }, - [](SSACFG::BasicBlock::Jump const&) {}, - [&](SSACFG::BasicBlock::ConditionalJump const& _conditionalJump) { - if (literalsFilter(m_cfg)(_conditionalJump.condition)) - live.emplace(_conditionalJump.condition); - }, - [](SSACFG::BasicBlock::Terminated const&) {} - }; - std::visit(exitVisitor, block.exit); + live += blockExitValues(blockId); for (auto const& op: block.operations | ranges::views::reverse) { @@ -163,12 +165,13 @@ void SSACFGLiveness::fillOperationsLiveOut() { for (size_t blockIdValue = 0; blockIdValue < m_cfg.numBlocks(); ++blockIdValue) { - auto const& operations = m_cfg.block(SSACFG::BlockId{blockIdValue}).operations; + SSACFG::BlockId const blockId{blockIdValue}; + auto const& operations = m_cfg.block(blockId).operations; auto& liveOuts = m_operationLiveOuts[blockIdValue]; liveOuts.resize(operations.size()); if (!operations.empty()) { - auto live = m_liveOuts[blockIdValue]; + auto live = m_liveOuts[blockIdValue] + blockExitValues(blockId); auto rit = liveOuts.rbegin(); for (auto const& op: operations | ranges::views::reverse) { diff --git a/libyul/backends/evm/SSACFGLiveness.h b/libyul/backends/evm/SSACFGLiveness.h index b0b9ccb7a3dc..6ec0d16884d6 100644 --- a/libyul/backends/evm/SSACFGLiveness.h +++ b/libyul/backends/evm/SSACFGLiveness.h @@ -47,6 +47,7 @@ class SSACFGLiveness void runDagDfs(); void runLoopTreeDfs(size_t _loopHeader); void fillOperationsLiveOut(); + std::set blockExitValues(SSACFG::BlockId const& _blockId) const; SSACFG const& m_cfg; ForwardSSACFGTopologicalSort m_topologicalSort; diff --git a/libyul/backends/evm/SSAControlFlowGraph.h b/libyul/backends/evm/SSAControlFlowGraph.h index 00f12fc71de6..9397e0e207c1 100644 --- a/libyul/backends/evm/SSAControlFlowGraph.h +++ b/libyul/backends/evm/SSAControlFlowGraph.h @@ -76,7 +76,7 @@ class SSACFG langutil::DebugData::ConstPtr debugData; std::reference_wrapper function; std::reference_wrapper call; - bool const canContinue = true; + bool canContinue; }; struct Operation { @@ -162,6 +162,10 @@ class SSACFG }; struct UnreachableValue {}; using ValueInfo = std::variant; + bool isLiteralValue(ValueId const _var) const + { + return std::holds_alternative(valueInfo(_var)); + } ValueInfo& valueInfo(ValueId const _var) { return m_valueInfos.at(_var.value); @@ -208,6 +212,14 @@ class SSACFG return it->second; } + size_t phiArgumentIndex(BlockId const _source, BlockId const _target) const + { + auto const& targetBlock = block(_target); + auto idx = util::findOffset(targetBlock.entries, _source); + yulAssert(idx, fmt::format("Target block {} not found as entry in one of the exits of the current block {}.", _target.value, _source.value)); + return *idx; + } + std::string toDot( bool _includeDiGraphDefinition=true, std::optional _functionIndex=std::nullopt, From f0010d54fdff0aa4d032050273d4570b609b0c60 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Thu, 9 Jan 2025 14:13:13 +0100 Subject: [PATCH 0692/1022] Liveness: Only perform topological sort on nodes reachable from root --- libyul/backends/evm/SSACFGTopologicalSort.cpp | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/libyul/backends/evm/SSACFGTopologicalSort.cpp b/libyul/backends/evm/SSACFGTopologicalSort.cpp index 5e3e0c0ec61b..881e48ea1b32 100644 --- a/libyul/backends/evm/SSACFGTopologicalSort.cpp +++ b/libyul/backends/evm/SSACFGTopologicalSort.cpp @@ -28,11 +28,7 @@ ForwardSSACFGTopologicalSort::ForwardSSACFGTopologicalSort(SSACFG const& _cfg): yulAssert(m_cfg.entry.value == 0); m_preOrder.reserve(m_cfg.numBlocks()); m_postOrder.reserve(m_cfg.numBlocks()); - for (size_t id = 0; id < m_cfg.numBlocks(); ++id) - { - if (!m_explored[id]) - dfs(id); - } + dfs(0); for (auto const& [v1, v2]: m_potentialBackEdges) if (ancestor(v2, v1)) From a3c07eb5d50a7e1b80292e781ab060c33331db2b Mon Sep 17 00:00:00 2001 From: piguagua Date: Wed, 15 Jan 2025 16:08:42 +0800 Subject: [PATCH 0693/1022] chore: remove redundant word Signed-off-by: piguagua --- libyul/AST.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libyul/AST.h b/libyul/AST.h index 6a49db68e7aa..d5988ee05386 100644 --- a/libyul/AST.h +++ b/libyul/AST.h @@ -73,7 +73,7 @@ struct Literal { langutil::DebugData::ConstPtr debugData; LiteralKind kind; Lite /// External / internal identifier or label reference struct Identifier { langutil::DebugData::ConstPtr debugData; YulName name; }; /// AST Node representing a reference to one of the built-in functions (as defined by the dialect). -/// In the source it's an actual name, while in the AST we only store a handle that can be used to find the the function in the Dialect +/// In the source it's an actual name, while in the AST we only store a handle that can be used to find the function in the Dialect struct BuiltinName { langutil::DebugData::ConstPtr debugData; BuiltinHandle handle; }; /// Assignment ("x := mload(20:u256)", expects push-1-expression on the right hand /// side and requires x to occupy exactly one stack slot. From 019d9af824ca7de5225fbd83d533d0ab8c99b973 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Wed, 15 Jan 2025 16:02:56 +0100 Subject: [PATCH 0694/1022] Ask about compilation pipeline in bug template for github issues --- .github/ISSUE_TEMPLATE/bug_report.md | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index ef411e08a49a..a53f931ca3e6 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -25,6 +25,7 @@ assignees: '' ## Environment - Compiler version: +- Compilation pipeline (legacy, IR, EOF): - Target EVM version (as per compiler settings): - Framework/IDE (e.g. Truffle or Remix): - EVM execution environment / backend / blockchain client: From 124caf8a93fb09c99f635268f7f4592f93713447 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Wed, 15 Jan 2025 16:03:11 +0100 Subject: [PATCH 0695/1022] Update framework examples in bug template for github issues --- .github/ISSUE_TEMPLATE/bug_report.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index a53f931ca3e6..b4f42fd52381 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -27,7 +27,7 @@ assignees: '' - Compiler version: - Compilation pipeline (legacy, IR, EOF): - Target EVM version (as per compiler settings): -- Framework/IDE (e.g. Truffle or Remix): +- Framework/IDE (e.g. Foundry, Hardhat, Remix): - EVM execution environment / backend / blockchain client: - Operating system: From fcc44851dd1c61e07ad07336719c2d96a84bf0e3 Mon Sep 17 00:00:00 2001 From: chloefeal <188809157+chloefeal@users.noreply.github.com> Date: Thu, 16 Jan 2025 23:32:27 +0800 Subject: [PATCH 0696/1022] Update Changelog.md Signed-off-by: chloefeal <188809157+chloefeal@users.noreply.github.com> --- Changelog.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Changelog.md b/Changelog.md index 521ee8793e88..cc094ff11cf5 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1440,7 +1440,7 @@ Language Features: * Introduce ``virtual`` and ``override`` keywords. * Modify ``push(element)`` for dynamic storage arrays such that it does not return the new length anymore. * Yul: Introduce ``leave`` statement that exits the current function. - * JSON AST: Add the function selector of each externally-visible FunctonDefinition to the AST JSON export. + * JSON AST: Add the function selector of each externally-visible FunctionDefinition to the AST JSON export. Compiler Features: * Allow revert strings to be stripped from the binary using the ``--revert-strings`` option or the ``settings.debug.revertStrings`` setting. From ac0f8f0a866a200eb2302a5f6bc871360f762f8c Mon Sep 17 00:00:00 2001 From: chloefeal <188809157+chloefeal@users.noreply.github.com> Date: Thu, 16 Jan 2025 23:32:41 +0800 Subject: [PATCH 0697/1022] Update test/libsolidity/util/ContractABIUtils.h Signed-off-by: chloefeal <188809157+chloefeal@users.noreply.github.com> --- test/libsolidity/util/ContractABIUtils.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/libsolidity/util/ContractABIUtils.h b/test/libsolidity/util/ContractABIUtils.h index 3f0b1b04e283..ec41956ae32e 100644 --- a/test/libsolidity/util/ContractABIUtils.h +++ b/test/libsolidity/util/ContractABIUtils.h @@ -72,7 +72,7 @@ class ContractABIUtils /// Calculates the encoding size of given _parameters based /// on the size of their types. - static size_t encodingSize(ParameterList const& _paremeters); + static size_t encodingSize(ParameterList const& _parameters); private: /// Parses and translates a single type and returns a list of From ded4c981a574c2342785342e12a24fa580809838 Mon Sep 17 00:00:00 2001 From: Martin Blicha Date: Fri, 10 Jan 2025 11:05:48 +0100 Subject: [PATCH 0698/1022] SMTChecker: Fix parsing of array select and store expressions --- Changelog.md | 1 + libsmtutil/CHCSmtLib2Interface.cpp | 10 +++++++++ .../invariants/array_access_2.sol | 22 +++++++++++++++++++ 3 files changed, 33 insertions(+) create mode 100644 test/libsolidity/smtCheckerTests/invariants/array_access_2.sol diff --git a/Changelog.md b/Changelog.md index 521ee8793e88..e31cc636b4d2 100644 --- a/Changelog.md +++ b/Changelog.md @@ -11,6 +11,7 @@ Compiler Features: Bugfixes: * General: Fix internal compiler error when requesting IR AST outputs for interfaces and abstract contracts. * SMTChecker: Fix SMT logic error when initializing a fixed-sized-bytes array using string literals. + * SMTChecker: Fix SMT logic error when translating invariants involving array store and select operations. * Standard JSON Interface: Fix ``generatedSources`` and ``sourceMap`` being generated internally even when not requested. * Yul: Fix internal compiler error when a code generation error should be reported instead. diff --git a/libsmtutil/CHCSmtLib2Interface.cpp b/libsmtutil/CHCSmtLib2Interface.cpp index 0bd74a410300..f9bb3b8f60b7 100644 --- a/libsmtutil/CHCSmtLib2Interface.cpp +++ b/libsmtutil/CHCSmtLib2Interface.cpp @@ -355,6 +355,16 @@ smtutil::Expression CHCSmtLib2Interface::ScopedParser::toSMTUtilExpression(SMTLi auto accessor = maybeTupleAccessor.value(); return smtutil::Expression("dt_accessor_" + accessor.first, std::move(arguments), accessor.second); } + if (op == "select") + { + smtSolverInteractionRequire(arguments.size() == 2, "Select has two arguments: array and index"); + return smtutil::Expression::select(arguments[0], arguments[1]); + } + if (op == "store") + { + smtSolverInteractionRequire(arguments.size() == 3, "Store has three arguments: array, index and element"); + return smtutil::Expression::store(arguments[0], arguments[1], arguments[2]); + } else { std::set boolOperators{"and", "or", "not", "=", "<", ">", "<=", ">=", "=>"}; diff --git a/test/libsolidity/smtCheckerTests/invariants/array_access_2.sol b/test/libsolidity/smtCheckerTests/invariants/array_access_2.sol new file mode 100644 index 000000000000..891662f65af1 --- /dev/null +++ b/test/libsolidity/smtCheckerTests/invariants/array_access_2.sol @@ -0,0 +1,22 @@ +contract C { + constructor() { + int8 v; + (v *= v); + } +} + +contract D { + bool[2] internal a; + + function f() internal view { + do {} while(!(a[1])); + } +} +// ==== +// SMTEngine: chc +// SMTIgnoreInv: no +// SMTSolvers: z3 +// SMTTargets: overflow +// ---- +// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. +// Info 1180: Contract invariant(s) for :D:\n(true || true)\nReentrancy property(ies) for :C:\n(( = 0) && (x!5 = x!4))\nReentrancy property(ies) for :D:\n(( = 0) && (x!6 = x!4) && (a' = a))\n = 0 -> no errors\n = 1 -> Overflow at v *= v\n From cdac6a2ac46b4cd43da42f636dcb5ea136a317a9 Mon Sep 17 00:00:00 2001 From: Alexander Arlt Date: Fri, 17 Jan 2025 13:25:35 +0100 Subject: [PATCH 0699/1022] [libyul] Fix false-negative maybe-uninitialized warning on gcc. --- libyul/optimiser/ForLoopConditionIntoBody.cpp | 5 +++-- libyul/optimiser/UnusedPruner.cpp | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/libyul/optimiser/ForLoopConditionIntoBody.cpp b/libyul/optimiser/ForLoopConditionIntoBody.cpp index 6324085e65c2..b3c78129aa47 100644 --- a/libyul/optimiser/ForLoopConditionIntoBody.cpp +++ b/libyul/optimiser/ForLoopConditionIntoBody.cpp @@ -32,8 +32,9 @@ void ForLoopConditionIntoBody::run(OptimiserStepContext& _context, Block& _ast) void ForLoopConditionIntoBody::operator()(ForLoop& _forLoop) { + std::optional booleanNegationFunctionHandle = m_dialect.booleanNegationFunctionHandle(); if ( - m_dialect.booleanNegationFunctionHandle() && + booleanNegationFunctionHandle && !std::holds_alternative(*_forLoop.condition) && !std::holds_alternative(*_forLoop.condition) ) @@ -47,7 +48,7 @@ void ForLoopConditionIntoBody::operator()(ForLoop& _forLoop) std::make_unique( FunctionCall { debugData, - BuiltinName{debugData, *m_dialect.booleanNegationFunctionHandle()}, + BuiltinName{debugData, *booleanNegationFunctionHandle}, util::make_vector(std::move(*_forLoop.condition)) } ), diff --git a/libyul/optimiser/UnusedPruner.cpp b/libyul/optimiser/UnusedPruner.cpp index 91568f4d65be..5d50e4599bfd 100644 --- a/libyul/optimiser/UnusedPruner.cpp +++ b/libyul/optimiser/UnusedPruner.cpp @@ -81,6 +81,7 @@ void UnusedPruner::operator()(Block& _block) [&](NameWithDebugData const& _typedName) { return used(_typedName.name); } )) { + std::optional discardFunctionHandle = m_dialect.discardFunctionHandle(); if (!varDecl.value) statement = Block{std::move(varDecl.debugData), {}}; else if ( @@ -91,10 +92,10 @@ void UnusedPruner::operator()(Block& _block) subtractReferences(ReferencesCounter::countReferences(*varDecl.value)); statement = Block{std::move(varDecl.debugData), {}}; } - else if (varDecl.variables.size() == 1 && m_dialect.discardFunctionHandle()) + else if (varDecl.variables.size() == 1 && discardFunctionHandle) statement = ExpressionStatement{varDecl.debugData, FunctionCall{ varDecl.debugData, - BuiltinName{varDecl.debugData, *m_dialect.discardFunctionHandle()}, + BuiltinName{varDecl.debugData, *discardFunctionHandle}, {*std::move(varDecl.value)} }}; } From 78e267817fc6f3cc85f3702b12e9c1fb28cb06ca Mon Sep 17 00:00:00 2001 From: ericlehong <193237094+ericlehong@users.noreply.github.com> Date: Fri, 17 Jan 2025 23:47:10 +0800 Subject: [PATCH 0700/1022] Update libevmasm/Assembly.cpp Signed-off-by: ericlehong <193237094+ericlehong@users.noreply.github.com> --- libevmasm/Assembly.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libevmasm/Assembly.cpp b/libevmasm/Assembly.cpp index 19201545e524..22bff5415333 100644 --- a/libevmasm/Assembly.cpp +++ b/libevmasm/Assembly.cpp @@ -1667,14 +1667,14 @@ LinkerObject const& Assembly::assembleEOF() const for (auto i: referencedSubIds) { - size_t const subAssemblyPostionInParentObject = ret.bytecode.size(); + size_t const subAssemblyPositionInParentObject = ret.bytecode.size(); auto const& subAssemblyLinkerObject = m_subs[i]->assemble(); // Append subassembly bytecode to the parent assembly result bytecode ret.bytecode += subAssemblyLinkerObject.bytecode; // Add subassembly link references to parent linker object. // Offset accordingly to subassembly position in parent object bytecode for (auto const& [subAssemblyLinkRefPosition, linkRef]: subAssemblyLinkerObject.linkReferences) - ret.linkReferences[subAssemblyPostionInParentObject + subAssemblyLinkRefPosition] = linkRef; + ret.linkReferences[subAssemblyPositionInParentObject + subAssemblyLinkRefPosition] = linkRef; } // TODO: Fill functionDebugData for EOF. It probably should be handled for new code section in the loop above. From 76df9809d10d5fb558a2407cf2965dcfa06b46f7 Mon Sep 17 00:00:00 2001 From: dxsullivan <193140725+dxsullivan@users.noreply.github.com> Date: Sat, 18 Jan 2025 09:13:27 +0800 Subject: [PATCH 0701/1022] Fix function name enumerateOptmisationSteps --- test/yulPhaser/Chromosome.cpp | 4 ++-- test/yulPhaser/Population.cpp | 2 +- test/yulPhaser/TestHelpers.cpp | 2 +- test/yulPhaser/TestHelpers.h | 2 +- test/yulPhaser/TestHelpersTest.cpp | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/test/yulPhaser/Chromosome.cpp b/test/yulPhaser/Chromosome.cpp index 881f70007374..5503de1bfe34 100644 --- a/test/yulPhaser/Chromosome.cpp +++ b/test/yulPhaser/Chromosome.cpp @@ -75,7 +75,7 @@ BOOST_AUTO_TEST_CASE(makeRandom_should_use_every_possible_step_with_the_same_pro constexpr int samplesPerStep = 500; constexpr double relativeTolerance = 0.02; - std::map stepIndices = enumerateOptmisationSteps(); + std::map stepIndices = enumerateOptimisationSteps(); auto chromosome = Chromosome::makeRandom(stepIndices.size() * samplesPerStep); std::vector samples; @@ -151,7 +151,7 @@ BOOST_AUTO_TEST_CASE(randomOptimisationStep_should_return_each_step_with_same_pr constexpr int samplesPerStep = 500; constexpr double relativeTolerance = 0.02; - std::map stepIndices = enumerateOptmisationSteps(); + std::map stepIndices = enumerateOptimisationSteps(); std::vector samples; for (size_t i = 0; i <= stepIndices.size() * samplesPerStep; ++i) samples.push_back(stepIndices.at(Chromosome::randomOptimisationStep())); diff --git a/test/yulPhaser/Population.cpp b/test/yulPhaser/Population.cpp index aed014592c1b..dedaa766f912 100644 --- a/test/yulPhaser/Population.cpp +++ b/test/yulPhaser/Population.cpp @@ -185,7 +185,7 @@ BOOST_FIXTURE_TEST_CASE(makeRandom_should_return_population_with_random_chromoso constexpr int chromosomeLength = 30; constexpr double relativeTolerance = 0.01; - std::map stepIndices = enumerateOptmisationSteps(); + std::map stepIndices = enumerateOptimisationSteps(); auto population = Population::makeRandom(m_fitnessMetric, populationSize, chromosomeLength, chromosomeLength); std::vector samples; diff --git a/test/yulPhaser/TestHelpers.cpp b/test/yulPhaser/TestHelpers.cpp index d75b63b4ac8b..baf7fb222f1c 100644 --- a/test/yulPhaser/TestHelpers.cpp +++ b/test/yulPhaser/TestHelpers.cpp @@ -53,7 +53,7 @@ std::vector phaser::test::chromosomeLengths(Population const& _populatio return lengths; } -std::map phaser::test::enumerateOptmisationSteps() +std::map phaser::test::enumerateOptimisationSteps() { std::map stepIndices; size_t i = 0; diff --git a/test/yulPhaser/TestHelpers.h b/test/yulPhaser/TestHelpers.h index f9d0afa4cf59..adfea7946d50 100644 --- a/test/yulPhaser/TestHelpers.h +++ b/test/yulPhaser/TestHelpers.h @@ -105,7 +105,7 @@ size_t countDifferences(Chromosome const& _chromosome1, Chromosome const& _chrom /// Assigns indices from 0 to N to all optimisation steps available in the OptimiserSuite. /// This is a convenience helper to make it easier to test their distribution with tools made for /// integers. -std::map enumerateOptmisationSteps(); +std::map enumerateOptimisationSteps(); // STRING UTILITIES diff --git a/test/yulPhaser/TestHelpersTest.cpp b/test/yulPhaser/TestHelpersTest.cpp index 23be74230cca..08a12f9d2cab 100644 --- a/test/yulPhaser/TestHelpersTest.cpp +++ b/test/yulPhaser/TestHelpersTest.cpp @@ -99,7 +99,7 @@ BOOST_AUTO_TEST_CASE(countDifferences_should_count_missing_characters_as_differe BOOST_AUTO_TEST_CASE(enumerateOptimisationSteps_should_assing_indices_to_all_available_optimisation_steps) { std::map stepsAndAbbreviations = OptimiserSuite::stepNameToAbbreviationMap(); - std::map stepsAndIndices = enumerateOptmisationSteps(); + std::map stepsAndIndices = enumerateOptimisationSteps(); BOOST_TEST(stepsAndIndices.size() == stepsAndAbbreviations.size()); std::set stepsSoFar; From d750b9dfce17def575a1177845525e26e96a5c67 Mon Sep 17 00:00:00 2001 From: Skylar Ray <137945430+sky-coderay@users.noreply.github.com> Date: Mon, 20 Jan 2025 14:34:00 +0200 Subject: [PATCH 0702/1022] Fix the name of `RETURNCONTRACT` instruction in EOF assembly output (#15729) * Fix RETURNCONTRACT instruction in AssemblyItem.cpp --------- Co-authored-by: r0qs --- libevmasm/AssemblyItem.cpp | 2 +- test/cmdlineTests/strict_asm_eof_container_prague/output | 4 ++-- test/libyul/objectCompiler/eof/creation_with_immutables.yul | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/libevmasm/AssemblyItem.cpp b/libevmasm/AssemblyItem.cpp index 424b9eedaa39..3bc7ef7049a6 100644 --- a/libevmasm/AssemblyItem.cpp +++ b/libevmasm/AssemblyItem.cpp @@ -393,7 +393,7 @@ std::string AssemblyItem::toAssemblyText(Assembly const& _assembly) const text = "eofcreate{" + std::to_string(static_cast(data())) + "}"; break; case ReturnContract: - text = "returcontract{" + std::to_string(static_cast(data())) + "}"; + text = "returncontract{" + std::to_string(static_cast(data())) + "}"; break; case RelativeJump: text = "rjump{" + std::string("tag_") + std::to_string(relativeJumpTagID()) + "}"; diff --git a/test/cmdlineTests/strict_asm_eof_container_prague/output b/test/cmdlineTests/strict_asm_eof_container_prague/output index 5d134f277865..d38adba184c0 100644 --- a/test/cmdlineTests/strict_asm_eof_container_prague/output +++ b/test/cmdlineTests/strict_asm_eof_container_prague/output @@ -73,7 +73,7 @@ stop sub_0: assembly { 0x00 dup1 - returcontract{0} + returncontract{0} stop sub_0: assembly { @@ -89,7 +89,7 @@ sub_0: assembly { sub_1: assembly { 0x00 dup1 - returcontract{0} + returncontract{0} stop sub_0: assembly { diff --git a/test/libyul/objectCompiler/eof/creation_with_immutables.yul b/test/libyul/objectCompiler/eof/creation_with_immutables.yul index aaffee722f8a..3d5ef85bc9a5 100644 --- a/test/libyul/objectCompiler/eof/creation_with_immutables.yul +++ b/test/libyul/objectCompiler/eof/creation_with_immutables.yul @@ -69,7 +69,7 @@ object "a" { // /* "source":397:398 */ // 0x00 // /* "source":377:403 */ -// returcontract{0} +// returncontract{0} // stop // // sub_0: assembly { From 53899156aa3dacc43fca67b49f594fe169966e1c Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Mon, 20 Jan 2025 11:52:49 +0100 Subject: [PATCH 0703/1022] ParserBase: avoid copying around currentLiteral --- liblangutil/ParserBase.cpp | 2 +- liblangutil/ParserBase.h | 3 ++- libsolutil/CommonData.h | 2 +- libyul/AsmParser.cpp | 4 ++-- libyul/AsmParser.h | 2 +- libyul/ObjectParser.cpp | 2 +- 6 files changed, 8 insertions(+), 7 deletions(-) diff --git a/liblangutil/ParserBase.cpp b/liblangutil/ParserBase.cpp index fde0f27ecc5a..00a38727daa1 100644 --- a/liblangutil/ParserBase.cpp +++ b/liblangutil/ParserBase.cpp @@ -43,7 +43,7 @@ Token ParserBase::peekNextToken() const return m_scanner->peekNextToken(); } -std::string ParserBase::currentLiteral() const +std::string_view ParserBase::currentLiteral() const { return m_scanner->currentLiteral(); } diff --git a/liblangutil/ParserBase.h b/liblangutil/ParserBase.h index 88fc76a9c307..cd84da2234f7 100644 --- a/liblangutil/ParserBase.h +++ b/liblangutil/ParserBase.h @@ -71,7 +71,8 @@ class ParserBase Token currentToken() const; Token peekNextToken() const; std::string tokenName(Token _token); - std::string currentLiteral() const; + /// Points to the current literal. The string view invalidates when the parser advances. + std::string_view currentLiteral() const; virtual Token advance(); ///@} diff --git a/libsolutil/CommonData.h b/libsolutil/CommonData.h index 1a5451ef5191..b663ede77bb5 100644 --- a/libsolutil/CommonData.h +++ b/libsolutil/CommonData.h @@ -470,7 +470,7 @@ inline std::string asString(bytesConstRef _b) } /// Converts a string to a byte array containing the string's (byte) data. -inline bytes asBytes(std::string const& _b) +inline bytes asBytes(std::string_view const _b) { return bytes((uint8_t const*)_b.data(), (uint8_t const*)(_b.data() + _b.size())); } diff --git a/libyul/AsmParser.cpp b/libyul/AsmParser.cpp index 66ac22a08e72..8377b8178d3d 100644 --- a/libyul/AsmParser.cpp +++ b/libyul/AsmParser.cpp @@ -779,7 +779,7 @@ void Parser::checkBreakContinuePosition(std::string const& _which) } } -bool Parser::isValidNumberLiteral(std::string const& _literal) +bool Parser::isValidNumberLiteral(std::string_view const _literal) { try { @@ -793,7 +793,7 @@ bool Parser::isValidNumberLiteral(std::string const& _literal) if (boost::starts_with(_literal, "0x")) return true; else - return _literal.find_first_not_of("0123456789") == std::string::npos; + return _literal.find_first_not_of("0123456789") == std::string_view::npos; } void Parser::raiseUnsupportedTypesError(SourceLocation const& _location) const diff --git a/libyul/AsmParser.h b/libyul/AsmParser.h index b546e179fd96..75c1cba873f9 100644 --- a/libyul/AsmParser.h +++ b/libyul/AsmParser.h @@ -152,7 +152,7 @@ class Parser: public langutil::ParserBase /// Reports an error if we are currently not inside the body part of a for loop. void checkBreakContinuePosition(std::string const& _which); - static bool isValidNumberLiteral(std::string const& _literal); + static bool isValidNumberLiteral(std::string_view _literal); private: Dialect const& m_dialect; diff --git a/libyul/ObjectParser.cpp b/libyul/ObjectParser.cpp index 123dedcb483d..954ade311f84 100644 --- a/libyul/ObjectParser.cpp +++ b/libyul/ObjectParser.cpp @@ -198,7 +198,7 @@ void ObjectParser::parseData(Object& _containingObject) std::string ObjectParser::parseUniqueName(Object const* _containingObject) { expectToken(Token::StringLiteral, false); - auto const name = currentLiteral(); + std::string const name{currentLiteral()}; if (name.empty()) parserError(3287_error, "Object name cannot be empty."); else if (_containingObject && _containingObject->name == name) From 20e30f50da4b0ea013e1bf3db8b3a2cd84effaa8 Mon Sep 17 00:00:00 2001 From: r0qs Date: Mon, 13 Jan 2025 23:52:46 +0100 Subject: [PATCH 0704/1022] Replace base-clang by ossfuzz base-builder --- .../Dockerfile.ubuntu.clang.ossfuzz | 26 ++++++++----------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/scripts/docker/buildpack-deps/Dockerfile.ubuntu.clang.ossfuzz b/scripts/docker/buildpack-deps/Dockerfile.ubuntu.clang.ossfuzz index 743d924d793e..f02cce06a99a 100644 --- a/scripts/docker/buildpack-deps/Dockerfile.ubuntu.clang.ossfuzz +++ b/scripts/docker/buildpack-deps/Dockerfile.ubuntu.clang.ossfuzz @@ -21,8 +21,10 @@ # # (c) 2016-2021 solidity contributors. #------------------------------------------------------------------------------ -FROM gcr.io/oss-fuzz-base/base-clang:latest as base -LABEL version="8" +# FIXME: Workaround for Boost 1.83.0 build failure when using Clang 18 (default since https://github.com/google/oss-fuzz/pull/11714) +# See: https://github.com/google/oss-fuzz/blob/5a9322260c4c66e7eb3e5d922b9fee6621ffd8da/projects/solidity/Dockerfile#L17C1-L18C139 +FROM gcr.io/oss-fuzz-base/base-builder@sha256:19782f7fe8092843368894dbc471ce9b30dd6a2813946071a36e8b05f5b1e27e AS base +LABEL version="9" ARG DEBIAN_FRONTEND=noninteractive @@ -44,6 +46,7 @@ RUN apt-get update; \ openjdk-8-jdk \ pkg-config \ python3-pip \ + python3-dev \ software-properties-common \ sudo \ texinfo \ @@ -59,32 +62,25 @@ RUN apt-get update; \ pygments-lexer-solidity \ pylint \ requests \ - tabulate \ - z3-solver; - -# Install cmake 3.21.2 (minimum requirement is cmake 3.10) -RUN wget https://github.com/Kitware/CMake/releases/download/v3.21.2/cmake-3.21.2-Linux-x86_64.sh; \ - test "$(sha256sum cmake-3.21.2-Linux-x86_64.sh)" = "3310362c6fe4d4b2dc00823835f3d4a7171bbd73deb7d059738494761f1c908c cmake-3.21.2-Linux-x86_64.sh"; \ - chmod +x cmake-3.21.2-Linux-x86_64.sh; \ - ./cmake-3.21.2-Linux-x86_64.sh --skip-license --prefix="/usr" + tabulate; FROM base AS libraries # Boost RUN set -ex; \ cd /usr/src; \ - wget -q 'https://archives.boost.io/release/1.74.0/source/boost_1_74_0.tar.bz2' -O boost.tar.bz2; \ - test "$(sha256sum boost.tar.bz2)" = "83bfc1507731a0906e387fc28b7ef5417d591429e51e788417fe9ff025e116b1 boost.tar.bz2" && \ + wget -q 'https://archives.boost.io/release/1.83.0/source/boost_1_83_0.tar.bz2' -O boost.tar.bz2; \ + test "$(sha256sum boost.tar.bz2)" = "6478edfe2f3305127cffe8caf73ea0176c53769f4bf1585be237eb30798c3b8e boost.tar.bz2" && \ tar -xf boost.tar.bz2; \ rm boost.tar.bz2; \ - cd boost_1_74_0; \ - CXXFLAGS="-stdlib=libc++ -pthread" LDFLAGS="-stdlib=libc++" ./bootstrap.sh --with-toolset=clang --prefix=/usr; \ + cd boost_1_83_0; \ + CXXFLAGS="-std=c++17 -stdlib=libc++ -pthread" LDFLAGS="-stdlib=libc++" ./bootstrap.sh --with-toolset=clang --prefix=/usr; \ ./b2 toolset=clang cxxflags="-stdlib=libc++ -pthread" linkflags="-stdlib=libc++ -pthread" headers; \ ./b2 toolset=clang cxxflags="-stdlib=libc++ -pthread" linkflags="-stdlib=libc++ -pthread" \ link=static variant=release runtime-link=static \ system filesystem unit_test_framework program_options \ install -j $(($(nproc)/2)); \ - rm -rf /usr/src/boost_1_74_0 + rm -rf /usr/src/boost_1_83_0 # Z3 RUN set -ex; \ From aee707e2bf33c54a26efd9f1b61b892ab65e48bf Mon Sep 17 00:00:00 2001 From: r0qs Date: Fri, 17 Jan 2025 14:30:15 +0100 Subject: [PATCH 0705/1022] Bump Z3 and CVC5 --- .../Dockerfile.ubuntu.clang.ossfuzz | 32 ++++++++----------- 1 file changed, 13 insertions(+), 19 deletions(-) diff --git a/scripts/docker/buildpack-deps/Dockerfile.ubuntu.clang.ossfuzz b/scripts/docker/buildpack-deps/Dockerfile.ubuntu.clang.ossfuzz index f02cce06a99a..7e70bcc22b17 100644 --- a/scripts/docker/buildpack-deps/Dockerfile.ubuntu.clang.ossfuzz +++ b/scripts/docker/buildpack-deps/Dockerfile.ubuntu.clang.ossfuzz @@ -84,21 +84,17 @@ RUN set -ex; \ # Z3 RUN set -ex; \ - git clone --depth 1 -b z3-4.12.1 https://github.com/Z3Prover/z3.git \ - /usr/src/z3; \ - cd /usr/src/z3; \ - mkdir build; \ - cd build; \ - LDFLAGS=$CXXFLAGS cmake -DZ3_BUILD_LIBZ3_SHARED=OFF -DCMAKE_INSTALL_PREFIX=/usr \ - -DCMAKE_BUILD_TYPE=Release ..; \ - make libz3 -j; \ - make install; \ - rm -rf /usr/src/z3 + z3_version="4.13.3"; \ + z3_archive_name="z3-${z3_version}-x64-glibc-2.35"; \ + wget "https://github.com/Z3Prover/z3/releases/download/z3-${z3_version}/${z3_archive_name}.zip" -O /opt/z3.zip; \ + test "$(sha256sum /opt/z3.zip)" = "32c7377026733c9d7b33c21cd77a68f50ba682367207b031a6bfd80140a8722f /opt/z3.zip"; \ + unzip -j /opt/z3.zip "${z3_archive_name}/bin/z3" -d /usr/bin; \ + rm -f /opt/z3.zip; # Eldarica RUN set -ex; \ apt-get update; \ - apt-get install -qy unzip openjdk-11-jre; \ + apt-get install -qqy openjdk-11-jre; \ eldarica_version="2.1"; \ wget "https://github.com/uuverifiers/eldarica/releases/download/v${eldarica_version}/eldarica-bin-${eldarica_version}.zip" -O /opt/eld_binaries.zip; \ test "$(sha256sum /opt/eld_binaries.zip)" = "0ac43f45c0925383c9d2077f62bbb515fd792375f3b2b101b30c9e81dcd7785c /opt/eld_binaries.zip"; \ @@ -107,14 +103,12 @@ RUN set -ex; \ # CVC5 RUN set -ex; \ - cvc5_version="1.1.2"; \ - wget "https://github.com/cvc5/cvc5/releases/download/cvc5-${cvc5_version}/cvc5-Linux-static.zip" -O /opt/cvc5.zip; \ - test "$(sha256sum /opt/cvc5.zip)" = "cf291aef67da8eaa8d425a51f67f3f72f36db8b1040655dc799b64e3d69e6086 /opt/cvc5.zip"; \ - unzip /opt/cvc5.zip -x "cvc5-Linux-static/lib/cmake/*" -d /opt; \ - mv /opt/cvc5-Linux-static/bin/* /usr/bin; \ - mv /opt/cvc5-Linux-static/include/* /usr/include; \ - mv /opt/cvc5-Linux-static/lib/* /usr/lib; \ - rm -rf /opt/cvc5-Linux-static /opt/cvc5.zip; + cvc5_version="1.2.0"; \ + cvc5_archive_name="cvc5-Linux-x86_64-static"; \ + wget "https://github.com/cvc5/cvc5/releases/download/cvc5-${cvc5_version}/${cvc5_archive_name}.zip" -O /opt/cvc5.zip; \ + test "$(sha256sum /opt/cvc5.zip)" = "d18f174ff9a11923c32c3f871f844ed16bd77a28f51050b8e7c8d821c98a1c2e /opt/cvc5.zip"; \ + unzip -j /opt/cvc5.zip "${cvc5_archive_name}/bin/cvc5" -d /usr/bin; \ + rm -f /opt/cvc5.zip; # OSSFUZZ: libprotobuf-mutator RUN set -ex; \ From 89e9000a37f893919e3e0cf6640bbff258179343 Mon Sep 17 00:00:00 2001 From: r0qs Date: Mon, 20 Jan 2025 13:11:38 +0100 Subject: [PATCH 0706/1022] Convert spaces to tabs --- .../Dockerfile.ubuntu.clang.ossfuzz | 89 +++++++++---------- 1 file changed, 44 insertions(+), 45 deletions(-) diff --git a/scripts/docker/buildpack-deps/Dockerfile.ubuntu.clang.ossfuzz b/scripts/docker/buildpack-deps/Dockerfile.ubuntu.clang.ossfuzz index 7e70bcc22b17..1dbf48e9b45f 100644 --- a/scripts/docker/buildpack-deps/Dockerfile.ubuntu.clang.ossfuzz +++ b/scripts/docker/buildpack-deps/Dockerfile.ubuntu.clang.ossfuzz @@ -68,19 +68,19 @@ FROM base AS libraries # Boost RUN set -ex; \ - cd /usr/src; \ - wget -q 'https://archives.boost.io/release/1.83.0/source/boost_1_83_0.tar.bz2' -O boost.tar.bz2; \ - test "$(sha256sum boost.tar.bz2)" = "6478edfe2f3305127cffe8caf73ea0176c53769f4bf1585be237eb30798c3b8e boost.tar.bz2" && \ - tar -xf boost.tar.bz2; \ - rm boost.tar.bz2; \ - cd boost_1_83_0; \ - CXXFLAGS="-std=c++17 -stdlib=libc++ -pthread" LDFLAGS="-stdlib=libc++" ./bootstrap.sh --with-toolset=clang --prefix=/usr; \ - ./b2 toolset=clang cxxflags="-stdlib=libc++ -pthread" linkflags="-stdlib=libc++ -pthread" headers; \ - ./b2 toolset=clang cxxflags="-stdlib=libc++ -pthread" linkflags="-stdlib=libc++ -pthread" \ - link=static variant=release runtime-link=static \ - system filesystem unit_test_framework program_options \ - install -j $(($(nproc)/2)); \ - rm -rf /usr/src/boost_1_83_0 + cd /usr/src; \ + wget -q 'https://archives.boost.io/release/1.83.0/source/boost_1_83_0.tar.bz2' -O boost.tar.bz2; \ + test "$(sha256sum boost.tar.bz2)" = "6478edfe2f3305127cffe8caf73ea0176c53769f4bf1585be237eb30798c3b8e boost.tar.bz2" && \ + tar -xf boost.tar.bz2; \ + rm boost.tar.bz2; \ + cd boost_1_83_0; \ + CXXFLAGS="-std=c++17 -stdlib=libc++ -pthread" LDFLAGS="-stdlib=libc++" ./bootstrap.sh --with-toolset=clang --prefix=/usr; \ + ./b2 toolset=clang cxxflags="-stdlib=libc++ -pthread" linkflags="-stdlib=libc++ -pthread" headers; \ + ./b2 toolset=clang cxxflags="-stdlib=libc++ -pthread" linkflags="-stdlib=libc++ -pthread" \ + link=static variant=release runtime-link=static \ + system filesystem unit_test_framework program_options \ + install -j $(($(nproc)/2)); \ + rm -rf /usr/src/boost_1_83_0 # Z3 RUN set -ex; \ @@ -112,15 +112,14 @@ RUN set -ex; \ # OSSFUZZ: libprotobuf-mutator RUN set -ex; \ - git clone https://github.com/google/libprotobuf-mutator.git \ - /usr/src/libprotobuf-mutator; \ + git clone https://github.com/google/libprotobuf-mutator.git /usr/src/libprotobuf-mutator; \ cd /usr/src/libprotobuf-mutator; \ git checkout 3521f47a2828da9ace403e4ecc4aece1a84feb36; \ mkdir build; \ cd build; \ cmake .. -GNinja -DLIB_PROTO_MUTATOR_DOWNLOAD_PROTOBUF=ON \ - -DLIB_PROTO_MUTATOR_TESTING=OFF -DCMAKE_BUILD_TYPE=Release \ - -DCMAKE_INSTALL_PREFIX="/usr"; \ + -DLIB_PROTO_MUTATOR_TESTING=OFF -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_INSTALL_PREFIX="/usr"; \ ninja; \ cp -vpr external.protobuf/bin/* /usr/bin/; \ cp -vpr external.protobuf/include/* /usr/include/; \ @@ -142,37 +141,37 @@ RUN set -ex; \ # gmp RUN set -ex; \ - # Replace system installed libgmp static library - # with sanitized version. Do not perform apt - # remove because it removes mlton as well that - # we need for building libabicoder - cd /usr/src/; \ - git clone --depth 1 --branch gmp-6.2.1 https://github.com/gmp-mirror/gmp-6.2 gmp/; \ - rm -r gmp/.git/; \ - test \ - "$(tar --create gmp/ --sort=name --mtime=1970-01-01Z --owner=0 --group=0 --numeric-owner | sha256sum)" = \ - "d606ff6a4ce98692f9920031e85ea8fcf4a65ce1426f6f0048b8794aefed174b -"; \ - # NOTE: This removes also libgmp.so, which git depends on - rm -f /usr/lib/x86_64-linux-gnu/libgmp.*; \ - rm -f /usr/include/x86_64-linux-gnu/gmp.h; \ - cd gmp/; \ - autoreconf -i; \ - ./configure --prefix=/usr --enable-static=yes --enable-maintainer-mode; \ - make -j; \ - make check; \ - make install; \ - rm -rf /usr/src/gmp/ + # Replace system installed libgmp static library + # with sanitized version. Do not perform apt + # remove because it removes mlton as well that + # we need for building libabicoder + cd /usr/src/; \ + git clone --depth 1 --branch gmp-6.2.1 https://github.com/gmp-mirror/gmp-6.2 gmp/; \ + rm -r gmp/.git/; \ + test \ + "$(tar --create gmp/ --sort=name --mtime=1970-01-01Z --owner=0 --group=0 --numeric-owner | sha256sum)" = \ + "d606ff6a4ce98692f9920031e85ea8fcf4a65ce1426f6f0048b8794aefed174b -"; \ + # NOTE: This removes also libgmp.so, which git depends on + rm -f /usr/lib/x86_64-linux-gnu/libgmp.*; \ + rm -f /usr/include/x86_64-linux-gnu/gmp.h; \ + cd gmp/; \ + autoreconf -i; \ + ./configure --prefix=/usr --enable-static=yes --enable-maintainer-mode; \ + make -j; \ + make check; \ + make install; \ + rm -rf /usr/src/gmp/ # libabicoder RUN set -ex; \ - cd /usr/src; \ - git clone https://github.com/ekpyron/Yul-Isabelle; \ - cd Yul-Isabelle; \ - cd libabicoder; \ - CXX=clang++ CXXFLAGS="-stdlib=libc++ -pthread" make; \ - cp libabicoder.a /usr/lib; \ - cp abicoder.hpp /usr/include; \ - rm -rf /usr/src/Yul-Isabelle + cd /usr/src; \ + git clone https://github.com/ekpyron/Yul-Isabelle; \ + cd Yul-Isabelle; \ + cd libabicoder; \ + CXX=clang++ CXXFLAGS="-stdlib=libc++ -pthread" make; \ + cp libabicoder.a /usr/lib; \ + cp abicoder.hpp /usr/include; \ + rm -rf /usr/src/Yul-Isabelle FROM base COPY --from=libraries /usr/lib /usr/lib From ed71f949c5888a70d5b827b29cbe579c6fa4c4bf Mon Sep 17 00:00:00 2001 From: r0qs Date: Tue, 14 Jan 2025 18:55:38 +0100 Subject: [PATCH 0707/1022] Bump ossfuzz image --- .circleci/config.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 18dc57ebdbec..c24604c84e90 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -21,8 +21,8 @@ parameters: default: "solbuildpackpusher/solidity-buildpack-deps@sha256:534c4eea1ba370a85cf3c106b4a30b43152ba4f695fab5e18577009a5e272146" ubuntu-clang-ossfuzz-docker-image: type: string - # solbuildpackpusher/solidity-buildpack-deps:ubuntu.clang.ossfuzz-6 - default: "solbuildpackpusher/solidity-buildpack-deps@sha256:8883fa2845bbc1e0922af60439313666e4ba325f67a117e17d78cca3ea6589b3" + # solbuildpackpusher/solidity-buildpack-deps:ubuntu.clang.ossfuzz-9 + default: "solbuildpackpusher/solidity-buildpack-deps@sha256:c95b24958c92821f1d409b97fcc4930576603063f088a98e780283ee7ec5b575" emscripten-docker-image: type: string # NOTE: Please remember to update the `scripts/build_emscripten.sh` whenever the hash of this image changes. From b683c8e8e12beccfdf7a357cb4cd3009504c4dca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Wed, 22 Jan 2025 00:15:53 +0100 Subject: [PATCH 0708/1022] Fix spelling mistakes and silence false-positives newly reported by codespell --- scripts/codespell_ignored_lines.txt | 1 + test/libsolidity/util/SoltestTypes.h | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/codespell_ignored_lines.txt b/scripts/codespell_ignored_lines.txt index 7ad83795cae7..fe99c9f24651 100644 --- a/scripts/codespell_ignored_lines.txt +++ b/scripts/codespell_ignored_lines.txt @@ -19,3 +19,4 @@ docker run --rm -v "${OUTPUTDIR}":/tmp/output -v "${SCRIPTDIR}":/tmp/scripts:ro templ("assignEnd", "end := tail"); templ("assignEnd", ""); self.assertIn('401 Client Error: Unauthorized', str(manager.exception)) + a = abd; diff --git a/test/libsolidity/util/SoltestTypes.h b/test/libsolidity/util/SoltestTypes.h index 791cea011610..4db9bc43b257 100644 --- a/test/libsolidity/util/SoltestTypes.h +++ b/test/libsolidity/util/SoltestTypes.h @@ -32,7 +32,7 @@ namespace solidity::frontend::test T(Invalid, "invalid", 0) \ T(EOS, "EOS", 0) \ T(Whitespace, "_", 0) \ - /* punctuations */ \ + /* punctuation */ \ T(LParen, "(", 0) \ T(RParen, ")", 0) \ T(LBrack, "[", 0) \ From 1682f7f8b12562663263e12951100b1561b08ada Mon Sep 17 00:00:00 2001 From: Martin Blicha Date: Tue, 21 Jan 2025 17:45:21 +0100 Subject: [PATCH 0709/1022] SMTChecker: Fix encoding of arguments of cryptographic functions For example, the function ecrecover expect an argument of type fixed bytes, but due to implicit conversion, you can also pass a string literal. We previously did not take this into account in the encoding into SMT, which could let to SMT expressions having wrong sorts. --- Changelog.md | 1 + libsolidity/formal/SMTEncoder.cpp | 10 +++++----- .../crypto/crypto_functions_same_string_literal.sol | 12 +++++++++--- 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/Changelog.md b/Changelog.md index b0539c403a3d..03a3f7e9b426 100644 --- a/Changelog.md +++ b/Changelog.md @@ -12,6 +12,7 @@ Bugfixes: * General: Fix internal compiler error when requesting IR AST outputs for interfaces and abstract contracts. * SMTChecker: Fix SMT logic error when initializing a fixed-sized-bytes array using string literals. * SMTChecker: Fix SMT logic error when translating invariants involving array store and select operations. + * SMTChecker: Fix wrong encoding of string literals as arguments of ``ecrecover`` precompile. * Standard JSON Interface: Fix ``generatedSources`` and ``sourceMap`` being generated internally even when not requested. * Yul: Fix internal compiler error when a code generation error should be reported instead. diff --git a/libsolidity/formal/SMTEncoder.cpp b/libsolidity/formal/SMTEncoder.cpp index 01627007f03e..6db9420b802b 100644 --- a/libsolidity/formal/SMTEncoder.cpp +++ b/libsolidity/formal/SMTEncoder.cpp @@ -851,7 +851,7 @@ void SMTEncoder::visitCryptoFunction(FunctionCall const& _funCall) { auto const& funType = dynamic_cast(*_funCall.expression().annotation().type); auto kind = funType.kind(); - auto arg0 = expr(*_funCall.arguments().at(0)); + auto arg0 = expr(*_funCall.arguments().at(0), TypeProvider::bytesStorage()); std::optional result; if (kind == FunctionType::Kind::KECCAK256) result = smtutil::Expression::select(state().cryptoFunction("keccak256"), arg0); @@ -862,10 +862,10 @@ void SMTEncoder::visitCryptoFunction(FunctionCall const& _funCall) else if (kind == FunctionType::Kind::ECRecover) { auto e = state().cryptoFunction("ecrecover"); - auto arg0 = expr(*_funCall.arguments().at(0)); - auto arg1 = expr(*_funCall.arguments().at(1)); - auto arg2 = expr(*_funCall.arguments().at(2)); - auto arg3 = expr(*_funCall.arguments().at(3)); + auto arg0 = expr(*_funCall.arguments().at(0), TypeProvider::fixedBytes(32)); + auto arg1 = expr(*_funCall.arguments().at(1), TypeProvider::uint(8)); + auto arg2 = expr(*_funCall.arguments().at(2), TypeProvider::fixedBytes(32)); + auto arg3 = expr(*_funCall.arguments().at(3), TypeProvider::fixedBytes(32)); auto inputSort = dynamic_cast(*e.sort).domain; auto ecrecoverInput = smtutil::Expression::tuple_constructor( smtutil::Expression(std::make_shared(inputSort), ""), diff --git a/test/libsolidity/smtCheckerTests/crypto/crypto_functions_same_string_literal.sol b/test/libsolidity/smtCheckerTests/crypto/crypto_functions_same_string_literal.sol index 9e5123ab5bd5..67e7899db3f2 100644 --- a/test/libsolidity/smtCheckerTests/crypto/crypto_functions_same_string_literal.sol +++ b/test/libsolidity/smtCheckerTests/crypto/crypto_functions_same_string_literal.sol @@ -5,19 +5,25 @@ contract C { assert(k1 == k2); } - function c2() public pure { + function c2() public pure { bytes32 s1 = sha256("10"); bytes32 s2 = sha256("10"); assert(s1 == s2); } - function c3() public pure { + function c3() public pure { bytes32 r1 = ripemd160("100"); bytes32 r2 = ripemd160("100"); assert(r1 == r2); } + + function c4() public pure { + address e1 = ecrecover("a", 1, hex"bb", unicode"c"); + address e2 = ecrecover("a", 1, hex"bb", unicode"c"); + assert(e1 == e2); + } } // ==== // SMTEngine: chc // ---- -// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. +// Info 1391: CHC: 4 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. From 444103c81957186aeb0410c02cbc81555391b25d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Wed, 15 Jan 2025 16:16:20 +0100 Subject: [PATCH 0710/1022] Split function type documentation into smaller sections --- docs/types/value-types.rst | 36 ++++++++++++++++++++++-------------- 1 file changed, 22 insertions(+), 14 deletions(-) diff --git a/docs/types/value-types.rst b/docs/types/value-types.rst index 9b5ee447e6d6..b91635a19ab1 100644 --- a/docs/types/value-types.rst +++ b/docs/types/value-types.rst @@ -728,7 +728,7 @@ that has the same data representation as the input, whereas ``toUFixed256x18`` r Function Types -------------- -Function types are the types of functions. Variables of function type +Function types are the types of functions. Variables of a function type can be assigned from functions and function parameters of function type can be used to pass functions to and return functions from function calls. Function types come in two flavours - *internal* and *external* functions: @@ -743,6 +743,20 @@ contract internally. External functions consist of an address and a function signature and they can be passed via and returned from external function calls. +Note that public functions of the current contract can be used both as an +internal and as an external function. To use ``f`` as an internal function, +just use ``f``, if you want to use its external form, use ``this.f``. + +If a function type variable is not initialised, calling it results +in a :ref:`Panic error`. The same happens if you call a function after using ``delete`` +on it. + +.. note:: + Lambda or inline functions are planned but not yet supported. + +Declaration syntax +^^^^^^^^^^^^^^^^^^ + Function types are notated as follows: .. code-block:: solidity @@ -759,7 +773,8 @@ omitted. Note that this only applies to function types. Visibility has to be specified explicitly for functions defined in contracts, they do not have a default. -Conversions: +Conversions +^^^^^^^^^^^ A function type ``A`` is implicitly convertible to a function type ``B`` if and only if their parameter types are identical, their return types are identical, @@ -788,18 +803,10 @@ Which makes it possible to assign a ``payable`` function pointer to a ``non-paya function pointer ensuring both types behave the same way, i.e, both cannot be used to send ether. -If a function type variable is not initialised, calling it results -in a :ref:`Panic error`. The same happens if you call a function after using ``delete`` -on it. - If external function types are used outside of the context of Solidity, they are treated as the ``function`` type, which encodes the address followed by the function identifier together in a single ``bytes24`` type. -Note that public functions of the current contract can be used both as an -internal and as an external function. To use ``f`` as an internal function, -just use ``f``, if you want to use its external form, use ``this.f``. - A function of an internal type can be assigned to a variable of an internal function type regardless of where it is defined. This includes private, internal and public functions of both contracts and libraries as well as free @@ -828,7 +835,8 @@ Libraries are excluded because they require a ``delegatecall`` and use :ref:`a d convention for their selectors `. Functions declared in interfaces do not have definitions so pointing at them does not make sense either. -Members: +Members +^^^^^^^ External (or public) functions have the following members: @@ -843,6 +851,9 @@ External (or public) functions have the following members: respectively. See :ref:`External Function Calls ` for more information. +Examples +^^^^^^^^ + Example that shows how to use the members: .. code-block:: solidity @@ -966,6 +977,3 @@ Another example that uses external function types: exchangeRate = response; } } - -.. note:: - Lambda or inline functions are planned but not yet supported. From 3357ca7b89e0ee715da6fe9585d1944b59b80406 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Wed, 15 Jan 2025 18:29:12 +0100 Subject: [PATCH 0711/1022] Document function type stability across code changes --- docs/control-structures.rst | 2 ++ docs/introduction-to-smart-contracts.rst | 1 + docs/ir-breaking-changes.rst | 2 ++ docs/security-considerations.rst | 10 ++++++ docs/types/value-types.rst | 43 ++++++++++++++++++++++++ 5 files changed, 58 insertions(+) diff --git a/docs/control-structures.rst b/docs/control-structures.rst index 238d261152c5..1d21a6e2668e 100644 --- a/docs/control-structures.rst +++ b/docs/control-structures.rst @@ -239,6 +239,8 @@ to limit the amount of gas. If the creation fails (due to out-of-stack, not enough balance or other problems), an exception is thrown. +.. _salted-contract-creations: + Salted contract creations / create2 ----------------------------------- diff --git a/docs/introduction-to-smart-contracts.rst b/docs/introduction-to-smart-contracts.rst index 45857c3f891c..994cb85d479f 100644 --- a/docs/introduction-to-smart-contracts.rst +++ b/docs/introduction-to-smart-contracts.rst @@ -537,6 +537,7 @@ operations, loops should be preferred over recursive calls. Furthermore, only 63/64th of the gas can be forwarded in a message call, which causes a depth limit of a little less than 1000 in practice. +.. _delegatecall: .. index:: delegatecall, library Delegatecall and Libraries diff --git a/docs/ir-breaking-changes.rst b/docs/ir-breaking-changes.rst index 4917cfc7158d..e76b779aa474 100644 --- a/docs/ir-breaking-changes.rst +++ b/docs/ir-breaking-changes.rst @@ -258,6 +258,8 @@ hiding new and different behavior in existing code. Internals ========= +.. _internal-function-pointers-in-ir: + Internal function pointers -------------------------- diff --git a/docs/security-considerations.rst b/docs/security-considerations.rst index 92d601043dd7..2b8f7f835133 100644 --- a/docs/security-considerations.rst +++ b/docs/security-considerations.rst @@ -371,6 +371,16 @@ If your ``mapping`` information must be deleted, consider using a library simila `iterable mapping `_, allowing you to traverse the keys and delete their values in the appropriate ``mapping``. +Internal Function Pointers in Upgradeable Contracts +=================================================== + +Updating the code of your contract may :ref:`invalidate the values of variables of internal function +types`. +Consider such values ephemeral and avoid storing them in state variables. +If you do, you must ensure that they never persist across code updates and are never used by +other contracts having access to the same storage space as a result of a delegatecall or account +abstraction. + Minor Details ============= diff --git a/docs/types/value-types.rst b/docs/types/value-types.rst index b91635a19ab1..6155e093b90e 100644 --- a/docs/types/value-types.rst +++ b/docs/types/value-types.rst @@ -851,6 +851,49 @@ External (or public) functions have the following members: respectively. See :ref:`External Function Calls ` for more information. +.. _function-type-value-stability-across-contract-updates: + +Value stability across contract updates +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +An important aspect to consider when using values of function types is whether the value will +remain valid if the underlying code changes. + +The state of the blockchain is not completely immutable and there are multiple ways to place +different code under the same address: + +- Directly deploying different code using :ref:`salted contract creation`. +- Delegating to a different contract via :ref:`DELEGATECALL` + (upgradeable code behind a proxy contract is a common example of this). +- Account abstraction as defined by `EIP-7702 `_. + +External function types can be considered as stable as contract's ABI, which makes them very portable. +Their ABI representation always consists of a contract address and a function selector and it is +perfectly safe to store them long-term or pass them between contracts. +While it is possible for the referenced function to change or disappear, a direct external call +would be affected the same way, so there is no additional risk in such use. + +In case of internal functions, however, the value is an identifier that is strongly tied to +contract's bytecode. +The actual representation of the identifier is an implementation detail and may change between +compiler versions or even :ref:`between different backends`. +Values assigned under a given representation are deterministic (i.e. guaranteed to remain the same +as long as the source code is the same) but are easily affected by changes such as adding, removing +or reordering of functions. +The compiler is also free to remove internal functions that are never used, which may affect other identifiers. +Some representations, e.g. one where identifiers are simply jump targets, may be affected by +virtually any change, even one completely unrelated to internal functions. + +To counter this, the language limits the use of internal function types outside of the context in +which they are valid. +This is why internal function types cannot be used as parameters of external functions (or in any +other way that is exposed in contract's ABI). +However, there are still situations where it is up to the user to decide whether their use is safe or not. +For example long-term storage of such values in state variables is discouraged, but may be safe if +the contract code is never going to be updated. +It is also always possible to side-step any safeguards by using inline assembly. +Such use always needs careful consideration. + Examples ^^^^^^^^ From 4b1bf339b2c8da77fb7c1d638c1f6a9db7768877 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Wed, 15 Jan 2025 18:29:57 +0100 Subject: [PATCH 0712/1022] Document the fact that in IR codegen only explicitly referenced functions are added to internal dispatch --- docs/ir-breaking-changes.rst | 6 ++++++ docs/types/value-types.rst | 7 +++++++ 2 files changed, 13 insertions(+) diff --git a/docs/ir-breaking-changes.rst b/docs/ir-breaking-changes.rst index e76b779aa474..30c1c611165c 100644 --- a/docs/ir-breaking-changes.rst +++ b/docs/ir-breaking-changes.rst @@ -278,6 +278,12 @@ The ID ``0`` is reserved for uninitialized function pointers which then cause a In the old code generator, internal function pointers are initialized with a special function that always causes a panic. This causes a storage write at construction time for internal function pointers in storage. +.. note:: + The compiler is free to omit internal functions that are never explicitly referenced by name. + As a consequence, assigning to a function type variable in inline assembly does not guarantee + that the assigned value will be included in the internal dispatch. + The function must also be explicitly referenced elsewhere in the code. + Cleanup ------- diff --git a/docs/types/value-types.rst b/docs/types/value-types.rst index 6155e093b90e..38d22aebdc2d 100644 --- a/docs/types/value-types.rst +++ b/docs/types/value-types.rst @@ -894,6 +894,13 @@ the contract code is never going to be updated. It is also always possible to side-step any safeguards by using inline assembly. Such use always needs careful consideration. +.. note:: + The removal of unused internal functions only takes into account explicit references to + such functions by name. + Implicit references, such as assigning a new value to a function type variable in inline assembly + may still lead to the removal of the function if it is not also referenced explicitly elsewhere + in the source. + Examples ^^^^^^^^ From 314c27b57c31c405c76cea35b626560293940e03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Tue, 14 Jan 2025 17:31:40 +0100 Subject: [PATCH 0713/1022] Tests for Yul names clashing with builtins and reserved identifiers --- .../clash_with_non_reserved_pure_yul_builtin.sol | 10 ++++++++++ .../clash_with_reserved_builtin.sol | 12 ++++++++++++ .../clash_with_reserved_non_builtin.sol | 15 +++++++++++++++ .../clash_with_reserved_pure_yul_builtin.sol | 15 +++++++++++++++ .../invalid/builtin_name_as_type.yul | 8 ++++++++ .../clash_with_non_reserved_pure_yul_builtin.yul | 8 ++++++++ .../invalid/clash_with_reserved_builtin.yul | 8 ++++++++ .../invalid/clash_with_reserved_non_builtin.yul | 11 +++++++++++ .../clash_with_reserved_pure_yul_builtin.yul | 8 ++++++++ .../invalid/reserved_identifier_as_type.yul | 10 ++++++++++ 10 files changed, 105 insertions(+) create mode 100644 test/libsolidity/syntaxTests/inlineAssembly/clash_with_non_reserved_pure_yul_builtin.sol create mode 100644 test/libsolidity/syntaxTests/inlineAssembly/clash_with_reserved_builtin.sol create mode 100644 test/libsolidity/syntaxTests/inlineAssembly/clash_with_reserved_non_builtin.sol create mode 100644 test/libsolidity/syntaxTests/inlineAssembly/clash_with_reserved_pure_yul_builtin.sol create mode 100644 test/libyul/yulSyntaxTests/invalid/builtin_name_as_type.yul create mode 100644 test/libyul/yulSyntaxTests/invalid/clash_with_non_reserved_pure_yul_builtin.yul create mode 100644 test/libyul/yulSyntaxTests/invalid/clash_with_reserved_builtin.yul create mode 100644 test/libyul/yulSyntaxTests/invalid/clash_with_reserved_non_builtin.yul create mode 100644 test/libyul/yulSyntaxTests/invalid/clash_with_reserved_pure_yul_builtin.yul create mode 100644 test/libyul/yulSyntaxTests/invalid/reserved_identifier_as_type.yul diff --git a/test/libsolidity/syntaxTests/inlineAssembly/clash_with_non_reserved_pure_yul_builtin.sol b/test/libsolidity/syntaxTests/inlineAssembly/clash_with_non_reserved_pure_yul_builtin.sol new file mode 100644 index 000000000000..9b6ee266c3ed --- /dev/null +++ b/test/libsolidity/syntaxTests/inlineAssembly/clash_with_non_reserved_pure_yul_builtin.sol @@ -0,0 +1,10 @@ +contract C { + function f() public pure { + // NOTE: memoryguard is a builtin but only in pure Yul, not inline assembly. + // NOTE: memoryguard is not a reserved identifier. + assembly { function memoryguard() {} } + assembly { function f(memoryguard) {} } + assembly { function f() -> memoryguard {} } + assembly { let memoryguard } + } +} diff --git a/test/libsolidity/syntaxTests/inlineAssembly/clash_with_reserved_builtin.sol b/test/libsolidity/syntaxTests/inlineAssembly/clash_with_reserved_builtin.sol new file mode 100644 index 000000000000..7a1f6d5e957e --- /dev/null +++ b/test/libsolidity/syntaxTests/inlineAssembly/clash_with_reserved_builtin.sol @@ -0,0 +1,12 @@ +contract C { + function f() public view { + assembly { + // NOTE: All EVM instruction names are reserved identifiers in Yul. + // NOTE: We do provide builtins corresponding to these instructions. + function add(mstore) -> sstore {} + let coinbase + } + } +} +// ---- +// ParserError 5568: (245-248): Cannot use builtin function name "add" as identifier name. diff --git a/test/libsolidity/syntaxTests/inlineAssembly/clash_with_reserved_non_builtin.sol b/test/libsolidity/syntaxTests/inlineAssembly/clash_with_reserved_non_builtin.sol new file mode 100644 index 000000000000..52f3a4320e96 --- /dev/null +++ b/test/libsolidity/syntaxTests/inlineAssembly/clash_with_reserved_non_builtin.sol @@ -0,0 +1,15 @@ +contract C { + function f() public pure { + assembly { + // NOTE: All EVM instruction names are reserved identifiers in Yul. + // NOTE: We don't provide builtins corresponding to these instructions. + function dup1(dup2) -> dup3 {} + let dup4 + } + } +} +// ---- +// DeclarationError 5017: (239-269): The identifier "dup1" is reserved and can not be used. +// DeclarationError 5017: (253-257): The identifier "dup2" is reserved and can not be used. +// DeclarationError 5017: (262-266): The identifier "dup3" is reserved and can not be used. +// DeclarationError 5017: (286-290): The identifier "dup4" is reserved and can not be used. diff --git a/test/libsolidity/syntaxTests/inlineAssembly/clash_with_reserved_pure_yul_builtin.sol b/test/libsolidity/syntaxTests/inlineAssembly/clash_with_reserved_pure_yul_builtin.sol new file mode 100644 index 000000000000..45b9df386aa3 --- /dev/null +++ b/test/libsolidity/syntaxTests/inlineAssembly/clash_with_reserved_pure_yul_builtin.sol @@ -0,0 +1,15 @@ +contract C { + function f() public view { + assembly { + // NOTE: These are builtins but only in pure Yul, not inline assembly. + // NOTE: Names of these builtins are also reserved identifiers. + function loadimmutable(setimmutable) -> datasize {} + let dataoffset + } + } +} +// ---- +// DeclarationError 5017: (234-285): The identifier "loadimmutable" is reserved and can not be used. +// DeclarationError 5017: (257-269): The identifier "setimmutable" is reserved and can not be used. +// DeclarationError 5017: (274-282): The identifier "datasize" is reserved and can not be used. +// DeclarationError 5017: (302-312): The identifier "dataoffset" is reserved and can not be used. diff --git a/test/libyul/yulSyntaxTests/invalid/builtin_name_as_type.yul b/test/libyul/yulSyntaxTests/invalid/builtin_name_as_type.yul new file mode 100644 index 000000000000..c15247fcd164 --- /dev/null +++ b/test/libyul/yulSyntaxTests/invalid/builtin_name_as_type.yul @@ -0,0 +1,8 @@ +{ + let x: datacopy + x := true: loadimmutable + + function f(y: linkersymbol) {} +} +// ---- +// ParserError 5568: (13-21): Cannot use builtin function name "datacopy" as identifier name. diff --git a/test/libyul/yulSyntaxTests/invalid/clash_with_non_reserved_pure_yul_builtin.yul b/test/libyul/yulSyntaxTests/invalid/clash_with_non_reserved_pure_yul_builtin.yul new file mode 100644 index 000000000000..daaed0aa3e74 --- /dev/null +++ b/test/libyul/yulSyntaxTests/invalid/clash_with_non_reserved_pure_yul_builtin.yul @@ -0,0 +1,8 @@ +{ + { function memoryguard() {} } + { function f(memoryguard) {} } + { function f() -> memoryguard {} } + { let memoryguard } +} +// ---- +// ParserError 5568: (17-28): Cannot use builtin function name "memoryguard" as identifier name. diff --git a/test/libyul/yulSyntaxTests/invalid/clash_with_reserved_builtin.yul b/test/libyul/yulSyntaxTests/invalid/clash_with_reserved_builtin.yul new file mode 100644 index 000000000000..52f76c30cd4c --- /dev/null +++ b/test/libyul/yulSyntaxTests/invalid/clash_with_reserved_builtin.yul @@ -0,0 +1,8 @@ +{ + // NOTE: All EVM instruction names are reserved identifiers in Yul. + // NOTE: We do provide builtins corresponding to these instructions. + function add(mstore) -> sstore {} + let coinbase +} +// ---- +// ParserError 5568: (160-163): Cannot use builtin function name "add" as identifier name. diff --git a/test/libyul/yulSyntaxTests/invalid/clash_with_reserved_non_builtin.yul b/test/libyul/yulSyntaxTests/invalid/clash_with_reserved_non_builtin.yul new file mode 100644 index 000000000000..bf7ad840cd05 --- /dev/null +++ b/test/libyul/yulSyntaxTests/invalid/clash_with_reserved_non_builtin.yul @@ -0,0 +1,11 @@ +{ + // NOTE: All EVM instruction names are reserved identifiers in Yul. + // NOTE: We don't provide builtins corresponding to these instructions. + function dup1(dup2) -> dup3 {} + let dup4 +} +// ---- +// DeclarationError 5017: (154-184): The identifier "dup1" is reserved and can not be used. +// DeclarationError 5017: (168-172): The identifier "dup2" is reserved and can not be used. +// DeclarationError 5017: (177-181): The identifier "dup3" is reserved and can not be used. +// DeclarationError 5017: (193-197): The identifier "dup4" is reserved and can not be used. diff --git a/test/libyul/yulSyntaxTests/invalid/clash_with_reserved_pure_yul_builtin.yul b/test/libyul/yulSyntaxTests/invalid/clash_with_reserved_pure_yul_builtin.yul new file mode 100644 index 000000000000..0bc282fe3635 --- /dev/null +++ b/test/libyul/yulSyntaxTests/invalid/clash_with_reserved_pure_yul_builtin.yul @@ -0,0 +1,8 @@ +{ + // NOTE: These are builtins but only in pure Yul, not inline assembly. + // NOTE: Names of these builtins are also reserved identifiers. + function loadimmutable(setimmutable) -> datasize {} + let dataoffset +} +// ---- +// ParserError 5568: (158-171): Cannot use builtin function name "loadimmutable" as identifier name. diff --git a/test/libyul/yulSyntaxTests/invalid/reserved_identifier_as_type.yul b/test/libyul/yulSyntaxTests/invalid/reserved_identifier_as_type.yul new file mode 100644 index 000000000000..df46d16b5a69 --- /dev/null +++ b/test/libyul/yulSyntaxTests/invalid/reserved_identifier_as_type.yul @@ -0,0 +1,10 @@ +{ + let x: jump + x := true: dup12 + + function f(y: jumpi) {} +} +// ---- +// ParserError 5473: (10-17): Types are not supported in untyped Yul. +// ParserError 5473: (27-38): Types are not supported in untyped Yul. +// ParserError 5473: (55-63): Types are not supported in untyped Yul. From edb6783e43f710cda94b26186c77047add14ca72 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Tue, 14 Jan 2025 17:18:06 +0100 Subject: [PATCH 0714/1022] Make name clash with a Yul builtin a non-fatal error --- Changelog.md | 1 + libyul/AsmParser.cpp | 8 +++++++- .../inlineAssembly/basefee_reserved_london.sol | 1 + .../inlineAssembly/blobbasefee_reserved_cancun.sol | 1 + .../inlineAssembly/clash_with_reserved_builtin.sol | 3 +++ .../difficulty_disallowed_function_pre_paris.sol | 1 + .../syntaxTests/inlineAssembly/mcopy_reserved_cancun.sol | 1 + .../prevrandao_disallowed_function_post_paris.sol | 1 + .../syntaxTests/inlineAssembly/tload_reserved_cancun.sol | 1 + .../syntaxTests/inlineAssembly/tstore_reserved_cancun.sol | 1 + test/libyul/yulSyntaxTests/blobhash.yul | 1 + .../libyul/yulSyntaxTests/eof/extcall_function_in_eof.yul | 1 - .../eof/extdelegatecall_function_in_eof.yul | 1 - .../yulSyntaxTests/eof/extstaticcall_function_in_eof.yul | 1 - .../yulSyntaxTests/invalid/builtin_name_as_type.yul | 5 +++++ .../invalid/clash_with_non_reserved_pure_yul_builtin.yul | 3 +++ .../invalid/clash_with_reserved_builtin.yul | 3 +++ .../invalid/clash_with_reserved_pure_yul_builtin.yul | 3 +++ test/libyul/yulSyntaxTests/mcopy_as_identifier.yul | 1 + 19 files changed, 34 insertions(+), 4 deletions(-) diff --git a/Changelog.md b/Changelog.md index 03a3f7e9b426..c00adf0fd977 100644 --- a/Changelog.md +++ b/Changelog.md @@ -6,6 +6,7 @@ Language Features: Compiler Features: * Error Reporting: Errors reported during code generation now point at the location of the contract when more fine-grained location is not available. * SMTChecker: Z3 is now a runtime dependency, not a build dependency (except for emscripten build). + * Yul Parser: Make name clash with a builtin a non-fatal error. Bugfixes: diff --git a/libyul/AsmParser.cpp b/libyul/AsmParser.cpp index 66ac22a08e72..8d8e91e5ce4d 100644 --- a/libyul/AsmParser.cpp +++ b/libyul/AsmParser.cpp @@ -755,7 +755,13 @@ YulName Parser::expectAsmIdentifier() { YulName name{currentLiteral()}; if (currentToken() == Token::Identifier && m_dialect.findBuiltin(name.str())) - fatalParserError(5568_error, "Cannot use builtin function name \"" + name.str() + "\" as identifier name."); + // Non-fatal. We'll continue and wrongly parse it as an identifier. May lead to some spurious + // errors after this point, but likely also much more useful ones. + m_errorReporter.parserError( + 5568_error, + currentLocation(), + "Cannot use builtin function name \"" + name.str() + "\" as identifier name." + ); // NOTE: We keep the expectation here to ensure the correct source location for the error above. expectToken(Token::Identifier); return name; diff --git a/test/libsolidity/syntaxTests/inlineAssembly/basefee_reserved_london.sol b/test/libsolidity/syntaxTests/inlineAssembly/basefee_reserved_london.sol index 00ecaf01a426..1235dd547c18 100644 --- a/test/libsolidity/syntaxTests/inlineAssembly/basefee_reserved_london.sol +++ b/test/libsolidity/syntaxTests/inlineAssembly/basefee_reserved_london.sol @@ -10,3 +10,4 @@ contract C { // EVMVersion: =london // ---- // ParserError 5568: (98-105): Cannot use builtin function name "basefee" as identifier name. +// ParserError 7104: (137-144): Builtin function "basefee" must be called. diff --git a/test/libsolidity/syntaxTests/inlineAssembly/blobbasefee_reserved_cancun.sol b/test/libsolidity/syntaxTests/inlineAssembly/blobbasefee_reserved_cancun.sol index 0bab7e36c74e..4e81c4865407 100644 --- a/test/libsolidity/syntaxTests/inlineAssembly/blobbasefee_reserved_cancun.sol +++ b/test/libsolidity/syntaxTests/inlineAssembly/blobbasefee_reserved_cancun.sol @@ -10,3 +10,4 @@ contract C { // EVMVersion: >=cancun // ---- // ParserError 5568: (98-109): Cannot use builtin function name "blobbasefee" as identifier name. +// ParserError 7104: (141-152): Builtin function "blobbasefee" must be called. diff --git a/test/libsolidity/syntaxTests/inlineAssembly/clash_with_reserved_builtin.sol b/test/libsolidity/syntaxTests/inlineAssembly/clash_with_reserved_builtin.sol index 7a1f6d5e957e..9dbf877d6bc2 100644 --- a/test/libsolidity/syntaxTests/inlineAssembly/clash_with_reserved_builtin.sol +++ b/test/libsolidity/syntaxTests/inlineAssembly/clash_with_reserved_builtin.sol @@ -10,3 +10,6 @@ contract C { } // ---- // ParserError 5568: (245-248): Cannot use builtin function name "add" as identifier name. +// ParserError 5568: (249-255): Cannot use builtin function name "mstore" as identifier name. +// ParserError 5568: (260-266): Cannot use builtin function name "sstore" as identifier name. +// ParserError 5568: (286-294): Cannot use builtin function name "coinbase" as identifier name. diff --git a/test/libsolidity/syntaxTests/inlineAssembly/difficulty_disallowed_function_pre_paris.sol b/test/libsolidity/syntaxTests/inlineAssembly/difficulty_disallowed_function_pre_paris.sol index a177e8f63099..d55935aad27a 100644 --- a/test/libsolidity/syntaxTests/inlineAssembly/difficulty_disallowed_function_pre_paris.sol +++ b/test/libsolidity/syntaxTests/inlineAssembly/difficulty_disallowed_function_pre_paris.sol @@ -19,3 +19,4 @@ contract C { // EVMVersion: =cancun // ---- // ParserError 5568: (101-106): Cannot use builtin function name "mcopy" as identifier name. +// ParserError 7104: (134-139): Builtin function "mcopy" must be called. diff --git a/test/libsolidity/syntaxTests/inlineAssembly/prevrandao_disallowed_function_post_paris.sol b/test/libsolidity/syntaxTests/inlineAssembly/prevrandao_disallowed_function_post_paris.sol index 6c284a005956..7924f52e2340 100644 --- a/test/libsolidity/syntaxTests/inlineAssembly/prevrandao_disallowed_function_post_paris.sol +++ b/test/libsolidity/syntaxTests/inlineAssembly/prevrandao_disallowed_function_post_paris.sol @@ -19,3 +19,4 @@ contract C { // EVMVersion: >=paris // ---- // ParserError 5568: (101-111): Cannot use builtin function name "prevrandao" as identifier name. +// ParserError 7104: (143-153): Builtin function "prevrandao" must be called. diff --git a/test/libsolidity/syntaxTests/inlineAssembly/tload_reserved_cancun.sol b/test/libsolidity/syntaxTests/inlineAssembly/tload_reserved_cancun.sol index 77c988577620..b8c09fd59c1a 100644 --- a/test/libsolidity/syntaxTests/inlineAssembly/tload_reserved_cancun.sol +++ b/test/libsolidity/syntaxTests/inlineAssembly/tload_reserved_cancun.sol @@ -10,3 +10,4 @@ contract C { // EVMVersion: >=cancun // ---- // ParserError 5568: (98-103): Cannot use builtin function name "tload" as identifier name. +// ParserError 7104: (135-140): Builtin function "tload" must be called. diff --git a/test/libsolidity/syntaxTests/inlineAssembly/tstore_reserved_cancun.sol b/test/libsolidity/syntaxTests/inlineAssembly/tstore_reserved_cancun.sol index 9f08d985aa38..9944c84f54c2 100644 --- a/test/libsolidity/syntaxTests/inlineAssembly/tstore_reserved_cancun.sol +++ b/test/libsolidity/syntaxTests/inlineAssembly/tstore_reserved_cancun.sol @@ -10,3 +10,4 @@ contract C { // EVMVersion: >=cancun // ---- // ParserError 5568: (98-104): Cannot use builtin function name "tstore" as identifier name. +// ParserError 7104: (136-142): Builtin function "tstore" must be called. diff --git a/test/libyul/yulSyntaxTests/blobhash.yul b/test/libyul/yulSyntaxTests/blobhash.yul index 6337f22c1b29..272ec13d7bb0 100644 --- a/test/libyul/yulSyntaxTests/blobhash.yul +++ b/test/libyul/yulSyntaxTests/blobhash.yul @@ -13,3 +13,4 @@ // EVMVersion: >=cancun // ---- // ParserError 5568: (20-28): Cannot use builtin function name "blobhash" as identifier name. +// ParserError 5568: (64-72): Cannot use builtin function name "blobhash" as identifier name. diff --git a/test/libyul/yulSyntaxTests/eof/extcall_function_in_eof.yul b/test/libyul/yulSyntaxTests/eof/extcall_function_in_eof.yul index 1e503ca94a65..021c98dd3c6f 100644 --- a/test/libyul/yulSyntaxTests/eof/extcall_function_in_eof.yul +++ b/test/libyul/yulSyntaxTests/eof/extcall_function_in_eof.yul @@ -8,4 +8,3 @@ object "a" { // bytecodeFormat: >=EOFv1 // ---- // ParserError 5568: (41-48): Cannot use builtin function name "extcall" as identifier name. -// ParserError 8143: (41-48): Expected keyword "data" or "object" or "}". diff --git a/test/libyul/yulSyntaxTests/eof/extdelegatecall_function_in_eof.yul b/test/libyul/yulSyntaxTests/eof/extdelegatecall_function_in_eof.yul index 0515c8d265b4..e352f1b3a650 100644 --- a/test/libyul/yulSyntaxTests/eof/extdelegatecall_function_in_eof.yul +++ b/test/libyul/yulSyntaxTests/eof/extdelegatecall_function_in_eof.yul @@ -8,4 +8,3 @@ object "a" { // bytecodeFormat: >=EOFv1 // ---- // ParserError 5568: (41-56): Cannot use builtin function name "extdelegatecall" as identifier name. -// ParserError 8143: (41-56): Expected keyword "data" or "object" or "}". diff --git a/test/libyul/yulSyntaxTests/eof/extstaticcall_function_in_eof.yul b/test/libyul/yulSyntaxTests/eof/extstaticcall_function_in_eof.yul index fbfb5074b6fd..0db2313a034a 100644 --- a/test/libyul/yulSyntaxTests/eof/extstaticcall_function_in_eof.yul +++ b/test/libyul/yulSyntaxTests/eof/extstaticcall_function_in_eof.yul @@ -8,4 +8,3 @@ object "a" { // bytecodeFormat: >=EOFv1 // ---- // ParserError 5568: (41-54): Cannot use builtin function name "extstaticcall" as identifier name. -// ParserError 8143: (41-54): Expected keyword "data" or "object" or "}". diff --git a/test/libyul/yulSyntaxTests/invalid/builtin_name_as_type.yul b/test/libyul/yulSyntaxTests/invalid/builtin_name_as_type.yul index c15247fcd164..b9b3346f48c2 100644 --- a/test/libyul/yulSyntaxTests/invalid/builtin_name_as_type.yul +++ b/test/libyul/yulSyntaxTests/invalid/builtin_name_as_type.yul @@ -6,3 +6,8 @@ } // ---- // ParserError 5568: (13-21): Cannot use builtin function name "datacopy" as identifier name. +// ParserError 5473: (10-21): Types are not supported in untyped Yul. +// ParserError 5568: (37-50): Cannot use builtin function name "loadimmutable" as identifier name. +// ParserError 5473: (31-50): Types are not supported in untyped Yul. +// ParserError 5568: (70-82): Cannot use builtin function name "linkersymbol" as identifier name. +// ParserError 5473: (67-82): Types are not supported in untyped Yul. diff --git a/test/libyul/yulSyntaxTests/invalid/clash_with_non_reserved_pure_yul_builtin.yul b/test/libyul/yulSyntaxTests/invalid/clash_with_non_reserved_pure_yul_builtin.yul index daaed0aa3e74..6f582442322b 100644 --- a/test/libyul/yulSyntaxTests/invalid/clash_with_non_reserved_pure_yul_builtin.yul +++ b/test/libyul/yulSyntaxTests/invalid/clash_with_non_reserved_pure_yul_builtin.yul @@ -6,3 +6,6 @@ } // ---- // ParserError 5568: (17-28): Cannot use builtin function name "memoryguard" as identifier name. +// ParserError 5568: (53-64): Cannot use builtin function name "memoryguard" as identifier name. +// ParserError 5568: (93-104): Cannot use builtin function name "memoryguard" as identifier name. +// ParserError 5568: (120-131): Cannot use builtin function name "memoryguard" as identifier name. diff --git a/test/libyul/yulSyntaxTests/invalid/clash_with_reserved_builtin.yul b/test/libyul/yulSyntaxTests/invalid/clash_with_reserved_builtin.yul index 52f76c30cd4c..f146f06aeb76 100644 --- a/test/libyul/yulSyntaxTests/invalid/clash_with_reserved_builtin.yul +++ b/test/libyul/yulSyntaxTests/invalid/clash_with_reserved_builtin.yul @@ -6,3 +6,6 @@ } // ---- // ParserError 5568: (160-163): Cannot use builtin function name "add" as identifier name. +// ParserError 5568: (164-170): Cannot use builtin function name "mstore" as identifier name. +// ParserError 5568: (175-181): Cannot use builtin function name "sstore" as identifier name. +// ParserError 5568: (193-201): Cannot use builtin function name "coinbase" as identifier name. diff --git a/test/libyul/yulSyntaxTests/invalid/clash_with_reserved_pure_yul_builtin.yul b/test/libyul/yulSyntaxTests/invalid/clash_with_reserved_pure_yul_builtin.yul index 0bc282fe3635..035efbacc46a 100644 --- a/test/libyul/yulSyntaxTests/invalid/clash_with_reserved_pure_yul_builtin.yul +++ b/test/libyul/yulSyntaxTests/invalid/clash_with_reserved_pure_yul_builtin.yul @@ -6,3 +6,6 @@ } // ---- // ParserError 5568: (158-171): Cannot use builtin function name "loadimmutable" as identifier name. +// ParserError 5568: (172-184): Cannot use builtin function name "setimmutable" as identifier name. +// ParserError 5568: (189-197): Cannot use builtin function name "datasize" as identifier name. +// ParserError 5568: (209-219): Cannot use builtin function name "dataoffset" as identifier name. diff --git a/test/libyul/yulSyntaxTests/mcopy_as_identifier.yul b/test/libyul/yulSyntaxTests/mcopy_as_identifier.yul index e48c27d06d81..be00e0a3584f 100644 --- a/test/libyul/yulSyntaxTests/mcopy_as_identifier.yul +++ b/test/libyul/yulSyntaxTests/mcopy_as_identifier.yul @@ -12,3 +12,4 @@ // EVMVersion: >=cancun // ---- // ParserError 5568: (20-25): Cannot use builtin function name "mcopy" as identifier name. +// ParserError 5568: (61-66): Cannot use builtin function name "mcopy" as identifier name. From 09db0cc5f9b3365e977b9b44288f36eeffe4e6df Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Wed, 22 Jan 2025 16:41:32 +0100 Subject: [PATCH 0715/1022] Add Ubuntu 22.04 image --- .github/workflows/buildpack-deps.yml | 3 +- scripts/ci/buildpack-deps_test_ubuntu2204.sh | 1 + .../buildpack-deps/Dockerfile.ubuntu2204 | 108 ++++++++++++++++++ 3 files changed, 111 insertions(+), 1 deletion(-) create mode 120000 scripts/ci/buildpack-deps_test_ubuntu2204.sh create mode 100644 scripts/docker/buildpack-deps/Dockerfile.ubuntu2204 diff --git a/.github/workflows/buildpack-deps.yml b/.github/workflows/buildpack-deps.yml index fe6da11e16da..ad2e58270018 100644 --- a/.github/workflows/buildpack-deps.yml +++ b/.github/workflows/buildpack-deps.yml @@ -7,6 +7,7 @@ on: - 'scripts/docker/buildpack-deps/Dockerfile.emscripten' - 'scripts/docker/buildpack-deps/Dockerfile.ubuntu.clang.ossfuzz' - 'scripts/docker/buildpack-deps/Dockerfile.ubuntu2004' + - 'scripts/docker/buildpack-deps/Dockerfile.ubuntu2204' - 'scripts/docker/buildpack-deps/Dockerfile.ubuntu2404' - 'scripts/docker/buildpack-deps/Dockerfile.ubuntu2404.clang' @@ -23,7 +24,7 @@ jobs: strategy: fail-fast: false matrix: - image_variant: [emscripten, ubuntu.clang.ossfuzz, ubuntu2004, ubuntu2404, ubuntu2404.clang] + image_variant: [emscripten, ubuntu.clang.ossfuzz, ubuntu2004, ubuntu2204, ubuntu2404, ubuntu2404.clang] steps: - uses: actions/checkout@v4 diff --git a/scripts/ci/buildpack-deps_test_ubuntu2204.sh b/scripts/ci/buildpack-deps_test_ubuntu2204.sh new file mode 120000 index 000000000000..c07a74de4fb4 --- /dev/null +++ b/scripts/ci/buildpack-deps_test_ubuntu2204.sh @@ -0,0 +1 @@ +build.sh \ No newline at end of file diff --git a/scripts/docker/buildpack-deps/Dockerfile.ubuntu2204 b/scripts/docker/buildpack-deps/Dockerfile.ubuntu2204 new file mode 100644 index 000000000000..9b365a374a07 --- /dev/null +++ b/scripts/docker/buildpack-deps/Dockerfile.ubuntu2204 @@ -0,0 +1,108 @@ +# vim:syntax=dockerfile +#------------------------------------------------------------------------------ +# Dockerfile for building and testing Solidity Compiler on CI +# Target: Ubuntu 22.04 (Jammy Jellyfish) +# URL: https://hub.docker.com/r/ethereum/solidity-buildpack-deps +# +# 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-2025 solidity contributors. +#------------------------------------------------------------------------------ +FROM buildpack-deps:jammy AS base +LABEL version="1" + +ARG DEBIAN_FRONTEND=noninteractive + +RUN set -ex; \ + dist=$(grep DISTRIB_CODENAME /etc/lsb-release | cut -d= -f2); \ + echo "deb http://ppa.launchpad.net/ethereum/cpp-build-deps/ubuntu $dist main" >> /etc/apt/sources.list ; \ + apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 1c52189c923f6ca9 ; \ + apt-get update; \ + apt-get install -qqy --no-install-recommends \ + build-essential \ + cmake \ + jq \ + clang \ + libboost-filesystem-dev \ + libboost-program-options-dev \ + libboost-system-dev \ + libboost-test-dev \ + libcln-dev \ + locales-all \ + lsof \ + ninja-build \ + python3-pip \ + python3-sphinx \ + software-properties-common \ + sudo \ + unzip \ + zip; \ + pip3 install \ + codecov \ + colorama \ + deepdiff \ + parsec \ + pygments-lexer-solidity \ + pylint \ + requests \ + tabulate \ + z3-solver; + +# Eldarica +RUN set -ex; \ + apt-get update; \ + apt-get install -qqy \ + openjdk-11-jre; \ + eldarica_version="2.1"; \ + wget "https://github.com/uuverifiers/eldarica/releases/download/v${eldarica_version}/eldarica-bin-${eldarica_version}.zip" -O /opt/eld_binaries.zip; \ + test "$(sha256sum /opt/eld_binaries.zip)" = "0ac43f45c0925383c9d2077f62bbb515fd792375f3b2b101b30c9e81dcd7785c /opt/eld_binaries.zip"; \ + unzip /opt/eld_binaries.zip -d /opt; \ + rm -f /opt/eld_binaries.zip; + +# CVC5 +RUN set -ex; \ + cvc5_version="1.2.0"; \ + cvc5_archive_name="cvc5-Linux-x86_64-static"; \ + wget "https://github.com/cvc5/cvc5/releases/download/cvc5-${cvc5_version}/${cvc5_archive_name}.zip" -O /opt/cvc5.zip; \ + test "$(sha256sum /opt/cvc5.zip)" = "d18f174ff9a11923c32c3f871f844ed16bd77a28f51050b8e7c8d821c98a1c2e /opt/cvc5.zip"; \ + unzip -j /opt/cvc5.zip "${cvc5_archive_name}/bin/cvc5" -d /usr/bin; \ + rm -f /opt/cvc5.zip; + +# Z3 +RUN set -ex; \ + z3_version="4.13.3"; \ + z3_archive_name="z3-${z3_version}-x64-glibc-2.35"; \ + wget "https://github.com/Z3Prover/z3/releases/download/z3-${z3_version}/${z3_archive_name}.zip" -O /opt/z3.zip; \ + test "$(sha256sum /opt/z3.zip)" = "32c7377026733c9d7b33c21cd77a68f50ba682367207b031a6bfd80140a8722f /opt/z3.zip"; \ + unzip -j /opt/z3.zip "${z3_archive_name}/bin/z3" -d /usr/bin; \ + rm -f /opt/z3.zip; + +FROM base AS libraries + +# EVMONE +RUN set -ex; \ + wget -O /usr/src/evmone.tar.gz https://github.com/ethereum/evmone/releases/download/v0.12.0/evmone-0.12.0-linux-x86_64.tar.gz; \ + test "$(sha256sum /usr/src/evmone.tar.gz)" = "1c7b5eba0c8c3b3b2a7a05101e2d01a13a2f84b323989a29be66285dba4136ce /usr/src/evmone.tar.gz"; \ + cd /usr; \ + tar -xf /usr/src/evmone.tar.gz; \ + rm -rf /usr/src/evmone.tar.gz + +FROM base +COPY --from=libraries /usr/lib /usr/lib +COPY --from=libraries /usr/bin /usr/bin +COPY --from=libraries /usr/include /usr/include +COPY --from=libraries /opt/eldarica /opt/eldarica +ENV PATH="$PATH:/opt/eldarica" From 0ea9a40b82cd7ecad8f5d0fa44aa6f3d0206be9f Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Wed, 22 Jan 2025 18:14:17 +0100 Subject: [PATCH 0716/1022] ci: add build jobs that run on ubuntu 2204 --- .circleci/config.yml | 59 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index c24604c84e90..be04d2a6f997 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -11,6 +11,10 @@ parameters: type: string # solbuildpackpusher/solidity-buildpack-deps:ubuntu2004-26 default: "solbuildpackpusher/solidity-buildpack-deps@sha256:1f387a77be889f65a2a25986a5c5eccc88cec23fabe6aeaf351790751145c81e" + ubuntu-2204-docker-image: + type: string + # solbuildpackpusher/solidity-buildpack-deps:ubuntu2204-1 + default: "solbuildpackpusher/solidity-buildpack-deps@sha256:d61b0a4a49ac106e6747c1e8037882f1d421b537dba6c96c0a400ca105d85d4d" ubuntu-2404-docker-image: type: string # solbuildpackpusher/solidity-buildpack-deps:ubuntu2404-2 @@ -551,6 +555,42 @@ defaults: MAKEFLAGS: -j 10 CPUs: 10 + - base_ubuntu2204: &base_ubuntu2204 + docker: + - image: << pipeline.parameters.ubuntu-2204-docker-image >> + environment: &base_ubuntu2204_env + TERM: xterm + CC: gcc + CXX: g++ + MAKEFLAGS: -j 3 + CPUs: 3 + + - base_ubuntu2204_large: &base_ubuntu2204_large + <<: *base_ubuntu2204 + resource_class: large + environment: &base_ubuntu2204_large_env + <<: *base_ubuntu2204_env + MAKEFLAGS: -j 5 + CPUs: 5 + + - base_ubuntu2204_clang: &base_ubuntu2204_clang + docker: + - image: << pipeline.parameters.ubuntu-2204-docker-image >> + environment: &base_ubuntu2204_clang_env + TERM: xterm + CC: clang + CXX: clang++ + MAKEFLAGS: -j 3 + CPUs: 3 + + - base_ubuntu2204_clang_large: &base_ubuntu2204_clang_large + <<: *base_ubuntu2204_clang + resource_class: large + environment: &base_ubuntu2204_clang_large_env + <<: *base_ubuntu2204_clang_env + MAKEFLAGS: -j 5 + CPUs: 5 + - base_ubuntu2404: &base_ubuntu2404 docker: - image: << pipeline.parameters.ubuntu-2404-docker-image >> @@ -1068,6 +1108,23 @@ jobs: - run_build - matrix_notify_failure_unless_pr + b_ubu_2204: + <<: *base_ubuntu2204_large + steps: + - checkout + - run_build + - matrix_notify_failure_unless_pr + + b_ubu_2204_clang: + <<: *base_ubuntu2204_clang_large + environment: + <<: *base_ubuntu2204_clang_large_env + MAKEFLAGS: -j 10 + steps: + - checkout + - run_build + - matrix_notify_failure_unless_pr + b_ubu_ossfuzz: &b_ubu_ossfuzz <<: *base_ubuntu_clang_large steps: @@ -1818,6 +1875,8 @@ workflows: - b_docs: *requires_nothing - b_ubu_cxx20: *requires_nothing - b_ubu_ossfuzz: *requires_nothing + - b_ubu_2204: *requires_nothing + - b_ubu_2204_clang: *requires_nothing # OS/X build and tests - b_osx: *requires_nothing From f499283a94a5fc8063b6586532c7cb2dd3972557 Mon Sep 17 00:00:00 2001 From: planetBoy <140164174+Guayaba221@users.noreply.github.com> Date: Wed, 22 Jan 2025 19:45:43 +0100 Subject: [PATCH 0717/1022] Update buildinfo.cmake --- cmake/scripts/buildinfo.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/scripts/buildinfo.cmake b/cmake/scripts/buildinfo.cmake index 3fb6beb2b787..a4e40e87b6b3 100644 --- a/cmake/scripts/buildinfo.cmake +++ b/cmake/scripts/buildinfo.cmake @@ -61,7 +61,7 @@ if (SOL_COMMIT_HASH AND SOL_LOCAL_CHANGES) endif() set(SOL_VERSION_COMMIT "commit.${SOL_COMMIT_HASH}") -set(SOl_VERSION_PLATFORM ETH_BUILD_PLATFORM) +set(SOL_VERSION_PLATFORM ETH_BUILD_PLATFORM) set(SOL_VERSION_BUILDINFO "commit.${SOL_COMMIT_HASH}.${ETH_BUILD_PLATFORM}") set(TMPFILE "${ETH_DST_DIR}/BuildInfo.h.tmp") From 887947bccc1e289f017f754fe41417dca8a897a8 Mon Sep 17 00:00:00 2001 From: rodiazet Date: Thu, 23 Jan 2025 11:53:12 +0100 Subject: [PATCH 0718/1022] eof: Fix error message wording. --- libyul/AsmAnalysis.cpp | 2 +- .../eof/extcalls_invalid_in_legacy.yul | 23 ++++++++----------- 2 files changed, 11 insertions(+), 14 deletions(-) diff --git a/libyul/AsmAnalysis.cpp b/libyul/AsmAnalysis.cpp index fd826eaecd18..2d0eeae2bb02 100644 --- a/libyul/AsmAnalysis.cpp +++ b/libyul/AsmAnalysis.cpp @@ -783,7 +783,7 @@ bool AsmAnalyzer::validateInstructions(evmasm::Instruction _instr, SourceLocatio 4328_error, _location, fmt::format( - "The \"{}\" instruction is only available on EOF.", + "The \"{}\" instruction is only available in EOF.", fmt::arg("instruction", boost::to_lower_copy(instructionInfo(_instr, m_evmVersion).name)) ) ); diff --git a/test/libyul/yulSyntaxTests/eof/extcalls_invalid_in_legacy.yul b/test/libyul/yulSyntaxTests/eof/extcalls_invalid_in_legacy.yul index 6aec96aa2e3c..1a67818025d4 100644 --- a/test/libyul/yulSyntaxTests/eof/extcalls_invalid_in_legacy.yul +++ b/test/libyul/yulSyntaxTests/eof/extcalls_invalid_in_legacy.yul @@ -1,17 +1,14 @@ -object "a" { - code { - pop(extcall(address(), 0, 0, 0)) - pop(extdelegatecall(address(), 0, 0)) - pop(extstaticcall(address(), 0, 0)) - } +{ + pop(extcall(address(), 0, 0, 0)) + pop(extdelegatecall(address(), 0, 0)) + pop(extstaticcall(address(), 0, 0)) } - // ==== // bytecodeFormat: legacy // ---- -// TypeError 4328: (36-43): The "extcall" instruction is only available on EOF. -// TypeError 3950: (36-63): Expected expression to evaluate to one value, but got 0 values instead. -// TypeError 4328: (77-92): The "extdelegatecall" instruction is only available on EOF. -// TypeError 3950: (77-109): Expected expression to evaluate to one value, but got 0 values instead. -// TypeError 4328: (123-136): The "extstaticcall" instruction is only available on EOF. -// TypeError 3950: (123-153): Expected expression to evaluate to one value, but got 0 values instead. +// TypeError 4328: (10-17): The "extcall" instruction is only available in EOF. +// TypeError 3950: (10-37): Expected expression to evaluate to one value, but got 0 values instead. +// TypeError 4328: (47-62): The "extdelegatecall" instruction is only available in EOF. +// TypeError 3950: (47-79): Expected expression to evaluate to one value, but got 0 values instead. +// TypeError 4328: (89-102): The "extstaticcall" instruction is only available in EOF. +// TypeError 3950: (89-119): Expected expression to evaluate to one value, but got 0 values instead. From b202600e4cfca885ed7adb13f2d1e3631122286b Mon Sep 17 00:00:00 2001 From: rodiazet Date: Thu, 23 Jan 2025 11:53:12 +0100 Subject: [PATCH 0719/1022] eof: Fix unintentionally reserved EOF identifiers in legacy --- libyul/backends/evm/EVMDialect.cpp | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/libyul/backends/evm/EVMDialect.cpp b/libyul/backends/evm/EVMDialect.cpp index bb7a96953034..74599eb1c449 100644 --- a/libyul/backends/evm/EVMDialect.cpp +++ b/libyul/backends/evm/EVMDialect.cpp @@ -155,14 +155,13 @@ std::set> createReservedIdentifiers(langutil::EVMVersio auto eofIdentifiersException = [&](evmasm::Instruction _instr) -> bool { - solAssert(!_eofVersion.has_value() || _evmVersion >= langutil::EVMVersion::prague()); - return - !_eofVersion.has_value() && - ( - _instr == evmasm::Instruction::EXTCALL || - _instr == evmasm::Instruction::EXTSTATICCALL || - _instr == evmasm::Instruction::EXTDELEGATECALL - ); + solAssert(!_eofVersion.has_value() || (*_eofVersion == 1 && _evmVersion == langutil::EVMVersion::prague())); + if (_eofVersion.has_value()) + // For EOF every instruction is reserved identifier. + return false; + else + return langutil::EVMVersion::prague().hasOpcode(_instr, 1) && + !langutil::EVMVersion::prague().hasOpcode(_instr, std::nullopt); }; std::set> reserved; From 4436907ea8baa265a99d0ec025d6b25851c1ae1a Mon Sep 17 00:00:00 2001 From: rodiazet Date: Thu, 23 Jan 2025 11:53:12 +0100 Subject: [PATCH 0720/1022] eof: Add better message when EOF builtin used in legcy --- libyul/AsmAnalysis.cpp | 33 +++++++++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 4 deletions(-) diff --git a/libyul/AsmAnalysis.cpp b/libyul/AsmAnalysis.cpp index 2d0eeae2bb02..69f2e765e0b9 100644 --- a/libyul/AsmAnalysis.cpp +++ b/libyul/AsmAnalysis.cpp @@ -695,11 +695,28 @@ bool AsmAnalyzer::validateInstructions(std::string_view _instructionIdentifier, if (builtinHandle && defaultEVMDialect.builtin(*builtinHandle).instruction.has_value()) return validateInstructions(*defaultEVMDialect.builtin(*builtinHandle).instruction, _location); + solAssert(!m_eofVersion.has_value() || (*m_eofVersion == 1 && m_evmVersion == langutil::EVMVersion::prague())); // TODO: Change `prague()` to `EVMVersion{}` once EOF gets deployed auto const& eofDialect = EVMDialect::strictAssemblyForEVM(EVMVersion::prague(), 1); auto const eofBuiltinHandle = eofDialect.findBuiltin(_instructionIdentifier); - if (eofBuiltinHandle && eofDialect.builtin(*eofBuiltinHandle).instruction.has_value()) - return validateInstructions(*eofDialect.builtin(*eofBuiltinHandle).instruction, _location); + if (eofBuiltinHandle) + { + auto const builtin = eofDialect.builtin(*eofBuiltinHandle); + if (builtin.instruction.has_value()) + return validateInstructions(*builtin.instruction, _location); + else if (!m_eofVersion.has_value()) + { + m_errorReporter.declarationError( + 7223_error, + _location, + fmt::format( + "Builtin function \"{}\" is only available in EOF.", + fmt::arg("function", _instructionIdentifier) + ) + ); + return true; + } + } return false; } @@ -716,8 +733,16 @@ bool AsmAnalyzer::validateInstructions(evmasm::Instruction _instr, SourceLocatio yulAssert( _instr != evmasm::Instruction::JUMP && _instr != evmasm::Instruction::JUMPI && - _instr != evmasm::Instruction::JUMPDEST, - ""); + _instr != evmasm::Instruction::JUMPDEST && + _instr != evmasm::Instruction::DATALOADN && + _instr != evmasm::Instruction::EOFCREATE && + _instr != evmasm::Instruction::RETURNCONTRACT && + _instr != evmasm::Instruction::RJUMP && + _instr != evmasm::Instruction::RJUMPI && + _instr != evmasm::Instruction::CALLF && + _instr != evmasm::Instruction::JUMPF && + _instr != evmasm::Instruction::RETF + ); auto errorForVM = [&](ErrorId _errorId, std::string const& vmKindMessage) { m_errorReporter.typeError( From 9032d580e65b42d6053a25d7b8e555fea37bfd9c Mon Sep 17 00:00:00 2001 From: rodiazet Date: Thu, 23 Jan 2025 11:53:12 +0100 Subject: [PATCH 0721/1022] eof: Add tests --- .../eof/auxdataloadn_in_legacy.yul | 4 +-- .../eof/eof_identifiers_in_legacy.yul | 10 ------- .../eof_identifiers_not_defined_in_legacy.yul | 29 +++++++++++++++++++ ...eof_identifiers_not_reserved_in_legacy.yul | 16 ++++++++++ .../eof/eof_names_reserved_in_eof.yul | 17 +++++++++++ ...of_opcodes_identifiers_reserved_in_eof.yul | 17 +++++++++++ 6 files changed, 81 insertions(+), 12 deletions(-) delete mode 100644 test/libyul/yulSyntaxTests/eof/eof_identifiers_in_legacy.yul create mode 100644 test/libyul/yulSyntaxTests/eof/eof_identifiers_not_defined_in_legacy.yul create mode 100644 test/libyul/yulSyntaxTests/eof/eof_identifiers_not_reserved_in_legacy.yul create mode 100644 test/libyul/yulSyntaxTests/eof/eof_names_reserved_in_eof.yul create mode 100644 test/libyul/yulSyntaxTests/eof/eof_opcodes_identifiers_reserved_in_eof.yul diff --git a/test/libyul/yulSyntaxTests/eof/auxdataloadn_in_legacy.yul b/test/libyul/yulSyntaxTests/eof/auxdataloadn_in_legacy.yul index 0fe3221f1a52..47986059e283 100644 --- a/test/libyul/yulSyntaxTests/eof/auxdataloadn_in_legacy.yul +++ b/test/libyul/yulSyntaxTests/eof/auxdataloadn_in_legacy.yul @@ -11,5 +11,5 @@ object "a" { // EVMVersion: >=prague // bytecodeFormat: legacy // ---- -// DeclarationError 4619: (42-54): Function "auxdataloadn" not found. -// TypeError 3950: (42-57): Expected expression to evaluate to one value, but got 0 values instead. \ No newline at end of file +// DeclarationError 7223: (42-54): Builtin function "auxdataloadn" is only available in EOF. +// TypeError 3950: (42-57): Expected expression to evaluate to one value, but got 0 values instead. diff --git a/test/libyul/yulSyntaxTests/eof/eof_identifiers_in_legacy.yul b/test/libyul/yulSyntaxTests/eof/eof_identifiers_in_legacy.yul deleted file mode 100644 index d9d7fde15997..000000000000 --- a/test/libyul/yulSyntaxTests/eof/eof_identifiers_in_legacy.yul +++ /dev/null @@ -1,10 +0,0 @@ -object "a" { - code { - function extcall() {} - function extstaticcall() {} - function extdelegatecall() {} - } -} - -// ==== -// bytecodeFormat: legacy \ No newline at end of file diff --git a/test/libyul/yulSyntaxTests/eof/eof_identifiers_not_defined_in_legacy.yul b/test/libyul/yulSyntaxTests/eof/eof_identifiers_not_defined_in_legacy.yul new file mode 100644 index 000000000000..ab55fb21d786 --- /dev/null +++ b/test/libyul/yulSyntaxTests/eof/eof_identifiers_not_defined_in_legacy.yul @@ -0,0 +1,29 @@ +{ + auxdataloadn(0) + dataloadn(0) + eofcreate("name", 0, 0, 0, 0) + returncontract("name", 0, 0) + rjump() + rjumpi() + callf(0) + jumpf(0) + retf() + extcall(0, 1, 2, 3) + extstaticcall(0, 1, 2) + extdelegatecall(0, 1, 2) +} +// ==== +// bytecodeFormat: legacy +// ---- +// DeclarationError 7223: (6-18): Builtin function "auxdataloadn" is only available in EOF. +// DeclarationError 4619: (26-35): Function "dataloadn" not found. +// DeclarationError 7223: (43-52): Builtin function "eofcreate" is only available in EOF. +// DeclarationError 4619: (77-91): Function "returncontract" not found. +// DeclarationError 4619: (110-115): Function "rjump" not found. +// DeclarationError 4619: (122-128): Function "rjumpi" not found. +// DeclarationError 4619: (135-140): Function "callf" not found. +// DeclarationError 4619: (148-153): Function "jumpf" not found. +// DeclarationError 4619: (161-165): Function "retf" not found. +// TypeError 4328: (172-179): The "extcall" instruction is only available in EOF. +// TypeError 4328: (196-209): The "extstaticcall" instruction is only available in EOF. +// TypeError 4328: (223-238): The "extdelegatecall" instruction is only available in EOF. diff --git a/test/libyul/yulSyntaxTests/eof/eof_identifiers_not_reserved_in_legacy.yul b/test/libyul/yulSyntaxTests/eof/eof_identifiers_not_reserved_in_legacy.yul new file mode 100644 index 000000000000..3cb737d4bf10 --- /dev/null +++ b/test/libyul/yulSyntaxTests/eof/eof_identifiers_not_reserved_in_legacy.yul @@ -0,0 +1,16 @@ +{ + function auxdataloadn() {} + function dataloadn() {} + function eofcreate() {} + function returncontract() {} + function rjump() {} + function rjumpi() {} + function callf() {} + function jumpf() {} + function retf() {} + function extcall() {} + function extstaticcall() {} + function extdelegatecall() {} +} +// ==== +// bytecodeFormat: legacy \ No newline at end of file diff --git a/test/libyul/yulSyntaxTests/eof/eof_names_reserved_in_eof.yul b/test/libyul/yulSyntaxTests/eof/eof_names_reserved_in_eof.yul new file mode 100644 index 000000000000..063f8f4a835a --- /dev/null +++ b/test/libyul/yulSyntaxTests/eof/eof_names_reserved_in_eof.yul @@ -0,0 +1,17 @@ +{ + function auxdataloadn() {} + function eofcreate() {} + function returncontract() {} + function extcall() {} + function extdelegatecall() {} + function extstaticcall() {} +} +// ==== +// bytecodeFormat: >=EOFv1 +// ---- +// ParserError 5568: (15-27): Cannot use builtin function name "auxdataloadn" as identifier name. +// ParserError 5568: (46-55): Cannot use builtin function name "eofcreate" as identifier name. +// ParserError 5568: (74-88): Cannot use builtin function name "returncontract" as identifier name. +// ParserError 5568: (107-114): Cannot use builtin function name "extcall" as identifier name. +// ParserError 5568: (133-148): Cannot use builtin function name "extdelegatecall" as identifier name. +// ParserError 5568: (167-180): Cannot use builtin function name "extstaticcall" as identifier name. diff --git a/test/libyul/yulSyntaxTests/eof/eof_opcodes_identifiers_reserved_in_eof.yul b/test/libyul/yulSyntaxTests/eof/eof_opcodes_identifiers_reserved_in_eof.yul new file mode 100644 index 000000000000..17ca120e6e5f --- /dev/null +++ b/test/libyul/yulSyntaxTests/eof/eof_opcodes_identifiers_reserved_in_eof.yul @@ -0,0 +1,17 @@ +{ + function dataloadn() {} + function rjump() {} + function rjumpi() {} + function callf() {} + function jumpf() {} + function retf() {} +} +// ==== +// bytecodeFormat: >=EOFv1 +// ---- +// DeclarationError 5017: (6-29): The identifier "dataloadn" is reserved and can not be used. +// DeclarationError 5017: (34-53): The identifier "rjump" is reserved and can not be used. +// DeclarationError 5017: (58-78): The identifier "rjumpi" is reserved and can not be used. +// DeclarationError 5017: (83-102): The identifier "callf" is reserved and can not be used. +// DeclarationError 5017: (107-126): The identifier "jumpf" is reserved and can not be used. +// DeclarationError 5017: (131-149): The identifier "retf" is reserved and can not be used. From e78424420505dc832cc6c3e0c4f9ebc7d71e3efa Mon Sep 17 00:00:00 2001 From: leopardracer <136604165+leopardracer@users.noreply.github.com> Date: Thu, 23 Jan 2025 17:43:44 +0100 Subject: [PATCH 0722/1022] fix: typos in `libsolidity/analysis/` (#15756) * Update NameAndTypeResolver.cpp * Update ControlFlowAnalyzer.cpp --- libsolidity/analysis/ControlFlowAnalyzer.cpp | 4 ++-- libsolidity/analysis/NameAndTypeResolver.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/libsolidity/analysis/ControlFlowAnalyzer.cpp b/libsolidity/analysis/ControlFlowAnalyzer.cpp index 7ae1aa76e2b9..8c9c6ba5c4fa 100644 --- a/libsolidity/analysis/ControlFlowAnalyzer.cpp +++ b/libsolidity/analysis/ControlFlowAnalyzer.cpp @@ -74,12 +74,12 @@ void ControlFlowAnalyzer::checkUninitializedAccess(CFGNode const* _entry, CFGNod bool propagateFrom(NodeInfo const& _entryNode) { size_t previousUnassignedVariablesAtEntry = unassignedVariablesAtEntry.size(); - size_t previousUninitializedVariableAccessess = uninitializedVariableAccesses.size(); + size_t previousUninitializedVariableAccesses = uninitializedVariableAccesses.size(); unassignedVariablesAtEntry += _entryNode.unassignedVariablesAtExit; uninitializedVariableAccesses += _entryNode.uninitializedVariableAccesses; return unassignedVariablesAtEntry.size() > previousUnassignedVariablesAtEntry || - uninitializedVariableAccesses.size() > previousUninitializedVariableAccessess + uninitializedVariableAccesses.size() > previousUninitializedVariableAccesses ; } }; diff --git a/libsolidity/analysis/NameAndTypeResolver.cpp b/libsolidity/analysis/NameAndTypeResolver.cpp index 32ef6d476b22..766f1bf121f5 100644 --- a/libsolidity/analysis/NameAndTypeResolver.cpp +++ b/libsolidity/analysis/NameAndTypeResolver.cpp @@ -716,7 +716,7 @@ void DeclarationRegistrationHelper::registerDeclaration(Declaration& _declaratio ); // NOTE: We're registering the function outside of its scope(). This will only affect - // name lookups. An more general alternative would be to modify Scoper to simply assign it + // name lookups. A more general alternative would be to modify Scoper to simply assign it // that scope in the first place, but this would complicate the AST traversal here, which // currently assumes that scopes follow ScopeOpener nesting. registerDeclaration(*m_scopes.at(quantifier->scope()), _declaration, nullptr, nullptr, false /* inactive */, m_errorReporter); From b59eafa9cc7709cea4fb612bb3943c1a5922d424 Mon Sep 17 00:00:00 2001 From: "fuder.eth" <139509124+vtjl10@users.noreply.github.com> Date: Thu, 23 Jan 2025 12:58:59 +0100 Subject: [PATCH 0723/1022] Update SymbolicTypes.cpp --- libsolidity/formal/SymbolicTypes.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libsolidity/formal/SymbolicTypes.cpp b/libsolidity/formal/SymbolicTypes.cpp index f8e1ebbdc805..72739bccfb91 100644 --- a/libsolidity/formal/SymbolicTypes.cpp +++ b/libsolidity/formal/SymbolicTypes.cpp @@ -126,15 +126,15 @@ SortPointer smtSort(frontend::Type const& _type) tupleName = tupleSort->name; else if (isContract(*baseType)) // use a common sort for contracts so inheriting contracts do not cause conflicting SMT types - // solc handles types mismtach + // solc handles types mismatch tupleName = "contract"; else if (isFunction(*baseType)) // use a common sort for functions so pure and view modifier do not cause conflicting SMT types - // solc handles types mismtach + // solc handles types mismatch tupleName = "function"; else if (isAddress(*baseType)) // use a common sort for address and address payable so it does not cause conflicting SMT types - // solc handles types mismtach + // solc handles types mismatch tupleName = "address"; else if ( baseType->category() == frontend::Type::Category::Integer || From 6854a62972c95170aad922b07789fedf95b306a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Thu, 23 Jan 2025 20:01:43 +0100 Subject: [PATCH 0724/1022] Fix semantic and syntax test dirs not following the same naming convention --- .../abi_decode_calldata.sol | 0 .../abi_decode_simple.sol | 0 .../abi_decode_simple_storage.sol | 0 .../abi_encode_call.sol | 0 .../abi_encode_call_declaration.sol | 0 .../abi_encode_call_is_consistent.sol | 0 .../abi_encode_call_memory.sol | 0 .../abi_encode_call_special_args.sol | 0 .../abi_encode_call_uint_bytes.sol | 0 .../abi_encode_empty_string_v1.sol | 0 .../abi_encode_with_selector.sol | 0 .../abi_encode_with_selectorv2.sol | 0 .../abi_encode_with_signature.sol | 0 .../abi_encode_with_signaturev2.sol | 0 .../contract_array.sol | 0 .../contract_array_v2.sol | 0 .../offset_overflow_in_array_decoding.sol | 0 .../offset_overflow_in_array_decoding_2.sol | 0 .../offset_overflow_in_array_decoding_3.sol | 0 .../array_2d_zeroed_memory_index_access.sol | 0 .../array_array_static.sol | 0 ...c_return_param_zeroed_memory_index_access.sol | 0 .../array_static_zeroed_memory_index_access.sol | 0 .../array_zeroed_memory_index_access.sol | 0 .../a.sol | 0 .../c.sol | 0 .../d.sol | 0 .../D/d.sol | 0 .../c.sol | 0 .../dir/B/b.sol | 0 .../dir/G/g.sol | 0 .../dir/a.sol | 0 .../dir/contract.sol | 2 +- .../h.sol | 0 .../b.sol | 0 .../dir/a.sol | 0 .../dir/contract.sol | 0 .../dot_a.sol | 0 .../dot_dot_b.sol | 0 .../externalSource/non_normalized_paths.sol | 8 ++++---- .../externalSource/relative_imports.sol | 16 ++++++++-------- .../source_name_starting_with_dots.sol | 12 ++++++------ .../prediction_example.sol | 0 .../salted_create.sol | 0 .../salted_create_with_value.sol | 0 .../ancestor.sol | 0 .../base.sol | 0 .../base_multi.sol | 0 .../base_multi_no_constructor.sol | 0 .../base_multi_no_constructor_modifier_style.sol | 0 .../fallback_overrides_receive.sol | 0 .../fallback_with_override.sol | 0 .../fallback_with_override_intermediate.sol | 0 .../fallback_without_override.sol | 0 .../fallback_without_override_intermediate.sol | 0 .../receive_overrides_fallback.sol | 0 .../receive_parameter.sol | 0 .../receive_return_parameter.sol | 0 .../receive_unimplemented.sol | 0 .../receive_with_override.sol | 0 .../receive_with_override_intermediate.sol | 0 .../receive_without_override.sol | 0 .../receive_without_override_intermediate.sol | 0 .../abstract_needed.sol | 0 .../diamond_needed.sol | 0 .../regular_optional.sol | 0 .../dynamic_inline_array.sol | 0 ...claration_and_passing_implicit_conversion.sol | 0 ...n_and_passing_implicit_conversion_strings.sol | 0 ...ne_array_declaration_const_int_conversion.sol | 0 ...array_declaration_const_string_conversion.sol | 0 .../inline_array_declaration_no_type.sol | 0 .../inline_array_declaration_no_type_strings.sol | 0 .../inline_array_fixed_types.sol | 0 .../inline_array_of_mapping_type.sol | 0 .../inline_array_rationals.sol | 0 .../invalid_types_in_inline_array.sol | 0 .../lvalues_as_inline_array.sol | 0 .../unnamed_type_tuple_in_inline_array.sol | 0 .../unnamed_types_in_inline_array_1.sol | 0 .../unnamed_types_in_inline_array_2.sol | 0 .../unnamed_types_in_inline_array_3.sol | 0 .../function_definition_expression.sol | 0 .../function_parameter_return_types_fail.sol | 0 .../function_parameter_return_types_success.sol | 0 .../function_state_mutability_fail.sol | 0 .../function_state_mutability_success.sol | 0 .../selector/function_selector_pure.sol | 0 .../local_variable_selector_not_pure.sol | 0 .../state_variable_selector_contract_name.sol | 0 .../state_variable_selector_not_pure.sol | 0 .../selector/state_variable_selector_super.sol | 0 92 files changed, 19 insertions(+), 19 deletions(-) rename test/libsolidity/semanticTests/{abiencodedecode => abiEncodeDecode}/abi_decode_calldata.sol (100%) rename test/libsolidity/semanticTests/{abiencodedecode => abiEncodeDecode}/abi_decode_simple.sol (100%) rename test/libsolidity/semanticTests/{abiencodedecode => abiEncodeDecode}/abi_decode_simple_storage.sol (100%) rename test/libsolidity/semanticTests/{abiencodedecode => abiEncodeDecode}/abi_encode_call.sol (100%) rename test/libsolidity/semanticTests/{abiencodedecode => abiEncodeDecode}/abi_encode_call_declaration.sol (100%) rename test/libsolidity/semanticTests/{abiencodedecode => abiEncodeDecode}/abi_encode_call_is_consistent.sol (100%) rename test/libsolidity/semanticTests/{abiencodedecode => abiEncodeDecode}/abi_encode_call_memory.sol (100%) rename test/libsolidity/semanticTests/{abiencodedecode => abiEncodeDecode}/abi_encode_call_special_args.sol (100%) rename test/libsolidity/semanticTests/{abiencodedecode => abiEncodeDecode}/abi_encode_call_uint_bytes.sol (100%) rename test/libsolidity/semanticTests/{abiencodedecode => abiEncodeDecode}/abi_encode_empty_string_v1.sol (100%) rename test/libsolidity/semanticTests/{abiencodedecode => abiEncodeDecode}/abi_encode_with_selector.sol (100%) rename test/libsolidity/semanticTests/{abiencodedecode => abiEncodeDecode}/abi_encode_with_selectorv2.sol (100%) rename test/libsolidity/semanticTests/{abiencodedecode => abiEncodeDecode}/abi_encode_with_signature.sol (100%) rename test/libsolidity/semanticTests/{abiencodedecode => abiEncodeDecode}/abi_encode_with_signaturev2.sol (100%) rename test/libsolidity/semanticTests/{abiencodedecode => abiEncodeDecode}/contract_array.sol (100%) rename test/libsolidity/semanticTests/{abiencodedecode => abiEncodeDecode}/contract_array_v2.sol (100%) rename test/libsolidity/semanticTests/{abiencodedecode => abiEncodeDecode}/offset_overflow_in_array_decoding.sol (100%) rename test/libsolidity/semanticTests/{abiencodedecode => abiEncodeDecode}/offset_overflow_in_array_decoding_2.sol (100%) rename test/libsolidity/semanticTests/{abiencodedecode => abiEncodeDecode}/offset_overflow_in_array_decoding_3.sol (100%) rename test/libsolidity/semanticTests/array/{array_memory_allocation => arrayMemoryAllocation}/array_2d_zeroed_memory_index_access.sol (100%) rename test/libsolidity/semanticTests/array/{array_memory_allocation => arrayMemoryAllocation}/array_array_static.sol (100%) rename test/libsolidity/semanticTests/array/{array_memory_allocation => arrayMemoryAllocation}/array_static_return_param_zeroed_memory_index_access.sol (100%) rename test/libsolidity/semanticTests/array/{array_memory_allocation => arrayMemoryAllocation}/array_static_zeroed_memory_index_access.sol (100%) rename test/libsolidity/semanticTests/array/{array_memory_allocation => arrayMemoryAllocation}/array_zeroed_memory_index_access.sol (100%) rename test/libsolidity/semanticTests/externalSource/{_non_normalized_paths => _nonNormalizedPaths}/a.sol (100%) rename test/libsolidity/semanticTests/externalSource/{_non_normalized_paths => _nonNormalizedPaths}/c.sol (100%) rename test/libsolidity/semanticTests/externalSource/{_non_normalized_paths => _nonNormalizedPaths}/d.sol (100%) rename test/libsolidity/semanticTests/externalSource/{_relative_imports => _relativeImports}/D/d.sol (100%) rename test/libsolidity/semanticTests/externalSource/{_relative_imports => _relativeImports}/c.sol (100%) rename test/libsolidity/semanticTests/externalSource/{_relative_imports => _relativeImports}/dir/B/b.sol (100%) rename test/libsolidity/semanticTests/externalSource/{_relative_imports => _relativeImports}/dir/G/g.sol (100%) rename test/libsolidity/semanticTests/externalSource/{_relative_imports => _relativeImports}/dir/a.sol (100%) rename test/libsolidity/semanticTests/externalSource/{_relative_imports => _relativeImports}/dir/contract.sol (76%) rename test/libsolidity/semanticTests/externalSource/{_relative_imports => _relativeImports}/h.sol (100%) rename test/libsolidity/semanticTests/externalSource/{_source_name_starting_with_dots => _sourceNameStartingWithDots}/b.sol (100%) rename test/libsolidity/semanticTests/externalSource/{_source_name_starting_with_dots => _sourceNameStartingWithDots}/dir/a.sol (100%) rename test/libsolidity/semanticTests/externalSource/{_source_name_starting_with_dots => _sourceNameStartingWithDots}/dir/contract.sol (100%) rename test/libsolidity/semanticTests/externalSource/{_source_name_starting_with_dots => _sourceNameStartingWithDots}/dot_a.sol (100%) rename test/libsolidity/semanticTests/externalSource/{_source_name_starting_with_dots => _sourceNameStartingWithDots}/dot_dot_b.sol (100%) rename test/libsolidity/semanticTests/{salted_create => saltedCreate}/prediction_example.sol (100%) rename test/libsolidity/semanticTests/{salted_create => saltedCreate}/salted_create.sol (100%) rename test/libsolidity/semanticTests/{salted_create => saltedCreate}/salted_create_with_value.sol (100%) rename test/libsolidity/syntaxTests/inheritance/{duplicated_constructor_call => duplicatedConstructorCall}/ancestor.sol (100%) rename test/libsolidity/syntaxTests/inheritance/{duplicated_constructor_call => duplicatedConstructorCall}/base.sol (100%) rename test/libsolidity/syntaxTests/inheritance/{duplicated_constructor_call => duplicatedConstructorCall}/base_multi.sol (100%) rename test/libsolidity/syntaxTests/inheritance/{duplicated_constructor_call => duplicatedConstructorCall}/base_multi_no_constructor.sol (100%) rename test/libsolidity/syntaxTests/inheritance/{duplicated_constructor_call => duplicatedConstructorCall}/base_multi_no_constructor_modifier_style.sol (100%) rename test/libsolidity/syntaxTests/inheritance/{fallback_receive => fallbackReceive}/fallback_overrides_receive.sol (100%) rename test/libsolidity/syntaxTests/inheritance/{fallback_receive => fallbackReceive}/fallback_with_override.sol (100%) rename test/libsolidity/syntaxTests/inheritance/{fallback_receive => fallbackReceive}/fallback_with_override_intermediate.sol (100%) rename test/libsolidity/syntaxTests/inheritance/{fallback_receive => fallbackReceive}/fallback_without_override.sol (100%) rename test/libsolidity/syntaxTests/inheritance/{fallback_receive => fallbackReceive}/fallback_without_override_intermediate.sol (100%) rename test/libsolidity/syntaxTests/inheritance/{fallback_receive => fallbackReceive}/receive_overrides_fallback.sol (100%) rename test/libsolidity/syntaxTests/inheritance/{fallback_receive => fallbackReceive}/receive_parameter.sol (100%) rename test/libsolidity/syntaxTests/inheritance/{fallback_receive => fallbackReceive}/receive_return_parameter.sol (100%) rename test/libsolidity/syntaxTests/inheritance/{fallback_receive => fallbackReceive}/receive_unimplemented.sol (100%) rename test/libsolidity/syntaxTests/inheritance/{fallback_receive => fallbackReceive}/receive_with_override.sol (100%) rename test/libsolidity/syntaxTests/inheritance/{fallback_receive => fallbackReceive}/receive_with_override_intermediate.sol (100%) rename test/libsolidity/syntaxTests/inheritance/{fallback_receive => fallbackReceive}/receive_without_override.sol (100%) rename test/libsolidity/syntaxTests/inheritance/{fallback_receive => fallbackReceive}/receive_without_override_intermediate.sol (100%) rename test/libsolidity/syntaxTests/inheritance/override/{interface_exception => interfaceException}/abstract_needed.sol (100%) rename test/libsolidity/syntaxTests/inheritance/override/{interface_exception => interfaceException}/diamond_needed.sol (100%) rename test/libsolidity/syntaxTests/inheritance/override/{interface_exception => interfaceException}/regular_optional.sol (100%) rename test/libsolidity/syntaxTests/{inline_arrays => inlineArrays}/dynamic_inline_array.sol (100%) rename test/libsolidity/syntaxTests/{inline_arrays => inlineArrays}/inline_array_declaration_and_passing_implicit_conversion.sol (100%) rename test/libsolidity/syntaxTests/{inline_arrays => inlineArrays}/inline_array_declaration_and_passing_implicit_conversion_strings.sol (100%) rename test/libsolidity/syntaxTests/{inline_arrays => inlineArrays}/inline_array_declaration_const_int_conversion.sol (100%) rename test/libsolidity/syntaxTests/{inline_arrays => inlineArrays}/inline_array_declaration_const_string_conversion.sol (100%) rename test/libsolidity/syntaxTests/{inline_arrays => inlineArrays}/inline_array_declaration_no_type.sol (100%) rename test/libsolidity/syntaxTests/{inline_arrays => inlineArrays}/inline_array_declaration_no_type_strings.sol (100%) rename test/libsolidity/syntaxTests/{inline_arrays => inlineArrays}/inline_array_fixed_types.sol (100%) rename test/libsolidity/syntaxTests/{inline_arrays => inlineArrays}/inline_array_of_mapping_type.sol (100%) rename test/libsolidity/syntaxTests/{inline_arrays => inlineArrays}/inline_array_rationals.sol (100%) rename test/libsolidity/syntaxTests/{inline_arrays => inlineArrays}/invalid_types_in_inline_array.sol (100%) rename test/libsolidity/syntaxTests/{inline_arrays => inlineArrays}/lvalues_as_inline_array.sol (100%) rename test/libsolidity/syntaxTests/{inline_arrays => inlineArrays}/unnamed_type_tuple_in_inline_array.sol (100%) rename test/libsolidity/syntaxTests/{inline_arrays => inlineArrays}/unnamed_types_in_inline_array_1.sol (100%) rename test/libsolidity/syntaxTests/{inline_arrays => inlineArrays}/unnamed_types_in_inline_array_2.sol (100%) rename test/libsolidity/syntaxTests/{inline_arrays => inlineArrays}/unnamed_types_in_inline_array_3.sol (100%) rename test/libsolidity/syntaxTests/types/{function_types => functionTypes}/function_definition_expression.sol (100%) rename test/libsolidity/syntaxTests/types/{function_types => functionTypes}/function_parameter_return_types_fail.sol (100%) rename test/libsolidity/syntaxTests/types/{function_types => functionTypes}/function_parameter_return_types_success.sol (100%) rename test/libsolidity/syntaxTests/types/{function_types => functionTypes}/function_state_mutability_fail.sol (100%) rename test/libsolidity/syntaxTests/types/{function_types => functionTypes}/function_state_mutability_success.sol (100%) rename test/libsolidity/syntaxTests/types/{function_types => functionTypes}/selector/function_selector_pure.sol (100%) rename test/libsolidity/syntaxTests/types/{function_types => functionTypes}/selector/local_variable_selector_not_pure.sol (100%) rename test/libsolidity/syntaxTests/types/{function_types => functionTypes}/selector/state_variable_selector_contract_name.sol (100%) rename test/libsolidity/syntaxTests/types/{function_types => functionTypes}/selector/state_variable_selector_not_pure.sol (100%) rename test/libsolidity/syntaxTests/types/{function_types => functionTypes}/selector/state_variable_selector_super.sol (100%) diff --git a/test/libsolidity/semanticTests/abiencodedecode/abi_decode_calldata.sol b/test/libsolidity/semanticTests/abiEncodeDecode/abi_decode_calldata.sol similarity index 100% rename from test/libsolidity/semanticTests/abiencodedecode/abi_decode_calldata.sol rename to test/libsolidity/semanticTests/abiEncodeDecode/abi_decode_calldata.sol diff --git a/test/libsolidity/semanticTests/abiencodedecode/abi_decode_simple.sol b/test/libsolidity/semanticTests/abiEncodeDecode/abi_decode_simple.sol similarity index 100% rename from test/libsolidity/semanticTests/abiencodedecode/abi_decode_simple.sol rename to test/libsolidity/semanticTests/abiEncodeDecode/abi_decode_simple.sol diff --git a/test/libsolidity/semanticTests/abiencodedecode/abi_decode_simple_storage.sol b/test/libsolidity/semanticTests/abiEncodeDecode/abi_decode_simple_storage.sol similarity index 100% rename from test/libsolidity/semanticTests/abiencodedecode/abi_decode_simple_storage.sol rename to test/libsolidity/semanticTests/abiEncodeDecode/abi_decode_simple_storage.sol diff --git a/test/libsolidity/semanticTests/abiencodedecode/abi_encode_call.sol b/test/libsolidity/semanticTests/abiEncodeDecode/abi_encode_call.sol similarity index 100% rename from test/libsolidity/semanticTests/abiencodedecode/abi_encode_call.sol rename to test/libsolidity/semanticTests/abiEncodeDecode/abi_encode_call.sol diff --git a/test/libsolidity/semanticTests/abiencodedecode/abi_encode_call_declaration.sol b/test/libsolidity/semanticTests/abiEncodeDecode/abi_encode_call_declaration.sol similarity index 100% rename from test/libsolidity/semanticTests/abiencodedecode/abi_encode_call_declaration.sol rename to test/libsolidity/semanticTests/abiEncodeDecode/abi_encode_call_declaration.sol diff --git a/test/libsolidity/semanticTests/abiencodedecode/abi_encode_call_is_consistent.sol b/test/libsolidity/semanticTests/abiEncodeDecode/abi_encode_call_is_consistent.sol similarity index 100% rename from test/libsolidity/semanticTests/abiencodedecode/abi_encode_call_is_consistent.sol rename to test/libsolidity/semanticTests/abiEncodeDecode/abi_encode_call_is_consistent.sol diff --git a/test/libsolidity/semanticTests/abiencodedecode/abi_encode_call_memory.sol b/test/libsolidity/semanticTests/abiEncodeDecode/abi_encode_call_memory.sol similarity index 100% rename from test/libsolidity/semanticTests/abiencodedecode/abi_encode_call_memory.sol rename to test/libsolidity/semanticTests/abiEncodeDecode/abi_encode_call_memory.sol diff --git a/test/libsolidity/semanticTests/abiencodedecode/abi_encode_call_special_args.sol b/test/libsolidity/semanticTests/abiEncodeDecode/abi_encode_call_special_args.sol similarity index 100% rename from test/libsolidity/semanticTests/abiencodedecode/abi_encode_call_special_args.sol rename to test/libsolidity/semanticTests/abiEncodeDecode/abi_encode_call_special_args.sol diff --git a/test/libsolidity/semanticTests/abiencodedecode/abi_encode_call_uint_bytes.sol b/test/libsolidity/semanticTests/abiEncodeDecode/abi_encode_call_uint_bytes.sol similarity index 100% rename from test/libsolidity/semanticTests/abiencodedecode/abi_encode_call_uint_bytes.sol rename to test/libsolidity/semanticTests/abiEncodeDecode/abi_encode_call_uint_bytes.sol diff --git a/test/libsolidity/semanticTests/abiencodedecode/abi_encode_empty_string_v1.sol b/test/libsolidity/semanticTests/abiEncodeDecode/abi_encode_empty_string_v1.sol similarity index 100% rename from test/libsolidity/semanticTests/abiencodedecode/abi_encode_empty_string_v1.sol rename to test/libsolidity/semanticTests/abiEncodeDecode/abi_encode_empty_string_v1.sol diff --git a/test/libsolidity/semanticTests/abiencodedecode/abi_encode_with_selector.sol b/test/libsolidity/semanticTests/abiEncodeDecode/abi_encode_with_selector.sol similarity index 100% rename from test/libsolidity/semanticTests/abiencodedecode/abi_encode_with_selector.sol rename to test/libsolidity/semanticTests/abiEncodeDecode/abi_encode_with_selector.sol diff --git a/test/libsolidity/semanticTests/abiencodedecode/abi_encode_with_selectorv2.sol b/test/libsolidity/semanticTests/abiEncodeDecode/abi_encode_with_selectorv2.sol similarity index 100% rename from test/libsolidity/semanticTests/abiencodedecode/abi_encode_with_selectorv2.sol rename to test/libsolidity/semanticTests/abiEncodeDecode/abi_encode_with_selectorv2.sol diff --git a/test/libsolidity/semanticTests/abiencodedecode/abi_encode_with_signature.sol b/test/libsolidity/semanticTests/abiEncodeDecode/abi_encode_with_signature.sol similarity index 100% rename from test/libsolidity/semanticTests/abiencodedecode/abi_encode_with_signature.sol rename to test/libsolidity/semanticTests/abiEncodeDecode/abi_encode_with_signature.sol diff --git a/test/libsolidity/semanticTests/abiencodedecode/abi_encode_with_signaturev2.sol b/test/libsolidity/semanticTests/abiEncodeDecode/abi_encode_with_signaturev2.sol similarity index 100% rename from test/libsolidity/semanticTests/abiencodedecode/abi_encode_with_signaturev2.sol rename to test/libsolidity/semanticTests/abiEncodeDecode/abi_encode_with_signaturev2.sol diff --git a/test/libsolidity/semanticTests/abiencodedecode/contract_array.sol b/test/libsolidity/semanticTests/abiEncodeDecode/contract_array.sol similarity index 100% rename from test/libsolidity/semanticTests/abiencodedecode/contract_array.sol rename to test/libsolidity/semanticTests/abiEncodeDecode/contract_array.sol diff --git a/test/libsolidity/semanticTests/abiencodedecode/contract_array_v2.sol b/test/libsolidity/semanticTests/abiEncodeDecode/contract_array_v2.sol similarity index 100% rename from test/libsolidity/semanticTests/abiencodedecode/contract_array_v2.sol rename to test/libsolidity/semanticTests/abiEncodeDecode/contract_array_v2.sol diff --git a/test/libsolidity/semanticTests/abiencodedecode/offset_overflow_in_array_decoding.sol b/test/libsolidity/semanticTests/abiEncodeDecode/offset_overflow_in_array_decoding.sol similarity index 100% rename from test/libsolidity/semanticTests/abiencodedecode/offset_overflow_in_array_decoding.sol rename to test/libsolidity/semanticTests/abiEncodeDecode/offset_overflow_in_array_decoding.sol diff --git a/test/libsolidity/semanticTests/abiencodedecode/offset_overflow_in_array_decoding_2.sol b/test/libsolidity/semanticTests/abiEncodeDecode/offset_overflow_in_array_decoding_2.sol similarity index 100% rename from test/libsolidity/semanticTests/abiencodedecode/offset_overflow_in_array_decoding_2.sol rename to test/libsolidity/semanticTests/abiEncodeDecode/offset_overflow_in_array_decoding_2.sol diff --git a/test/libsolidity/semanticTests/abiencodedecode/offset_overflow_in_array_decoding_3.sol b/test/libsolidity/semanticTests/abiEncodeDecode/offset_overflow_in_array_decoding_3.sol similarity index 100% rename from test/libsolidity/semanticTests/abiencodedecode/offset_overflow_in_array_decoding_3.sol rename to test/libsolidity/semanticTests/abiEncodeDecode/offset_overflow_in_array_decoding_3.sol diff --git a/test/libsolidity/semanticTests/array/array_memory_allocation/array_2d_zeroed_memory_index_access.sol b/test/libsolidity/semanticTests/array/arrayMemoryAllocation/array_2d_zeroed_memory_index_access.sol similarity index 100% rename from test/libsolidity/semanticTests/array/array_memory_allocation/array_2d_zeroed_memory_index_access.sol rename to test/libsolidity/semanticTests/array/arrayMemoryAllocation/array_2d_zeroed_memory_index_access.sol diff --git a/test/libsolidity/semanticTests/array/array_memory_allocation/array_array_static.sol b/test/libsolidity/semanticTests/array/arrayMemoryAllocation/array_array_static.sol similarity index 100% rename from test/libsolidity/semanticTests/array/array_memory_allocation/array_array_static.sol rename to test/libsolidity/semanticTests/array/arrayMemoryAllocation/array_array_static.sol diff --git a/test/libsolidity/semanticTests/array/array_memory_allocation/array_static_return_param_zeroed_memory_index_access.sol b/test/libsolidity/semanticTests/array/arrayMemoryAllocation/array_static_return_param_zeroed_memory_index_access.sol similarity index 100% rename from test/libsolidity/semanticTests/array/array_memory_allocation/array_static_return_param_zeroed_memory_index_access.sol rename to test/libsolidity/semanticTests/array/arrayMemoryAllocation/array_static_return_param_zeroed_memory_index_access.sol diff --git a/test/libsolidity/semanticTests/array/array_memory_allocation/array_static_zeroed_memory_index_access.sol b/test/libsolidity/semanticTests/array/arrayMemoryAllocation/array_static_zeroed_memory_index_access.sol similarity index 100% rename from test/libsolidity/semanticTests/array/array_memory_allocation/array_static_zeroed_memory_index_access.sol rename to test/libsolidity/semanticTests/array/arrayMemoryAllocation/array_static_zeroed_memory_index_access.sol diff --git a/test/libsolidity/semanticTests/array/array_memory_allocation/array_zeroed_memory_index_access.sol b/test/libsolidity/semanticTests/array/arrayMemoryAllocation/array_zeroed_memory_index_access.sol similarity index 100% rename from test/libsolidity/semanticTests/array/array_memory_allocation/array_zeroed_memory_index_access.sol rename to test/libsolidity/semanticTests/array/arrayMemoryAllocation/array_zeroed_memory_index_access.sol diff --git a/test/libsolidity/semanticTests/externalSource/_non_normalized_paths/a.sol b/test/libsolidity/semanticTests/externalSource/_nonNormalizedPaths/a.sol similarity index 100% rename from test/libsolidity/semanticTests/externalSource/_non_normalized_paths/a.sol rename to test/libsolidity/semanticTests/externalSource/_nonNormalizedPaths/a.sol diff --git a/test/libsolidity/semanticTests/externalSource/_non_normalized_paths/c.sol b/test/libsolidity/semanticTests/externalSource/_nonNormalizedPaths/c.sol similarity index 100% rename from test/libsolidity/semanticTests/externalSource/_non_normalized_paths/c.sol rename to test/libsolidity/semanticTests/externalSource/_nonNormalizedPaths/c.sol diff --git a/test/libsolidity/semanticTests/externalSource/_non_normalized_paths/d.sol b/test/libsolidity/semanticTests/externalSource/_nonNormalizedPaths/d.sol similarity index 100% rename from test/libsolidity/semanticTests/externalSource/_non_normalized_paths/d.sol rename to test/libsolidity/semanticTests/externalSource/_nonNormalizedPaths/d.sol diff --git a/test/libsolidity/semanticTests/externalSource/_relative_imports/D/d.sol b/test/libsolidity/semanticTests/externalSource/_relativeImports/D/d.sol similarity index 100% rename from test/libsolidity/semanticTests/externalSource/_relative_imports/D/d.sol rename to test/libsolidity/semanticTests/externalSource/_relativeImports/D/d.sol diff --git a/test/libsolidity/semanticTests/externalSource/_relative_imports/c.sol b/test/libsolidity/semanticTests/externalSource/_relativeImports/c.sol similarity index 100% rename from test/libsolidity/semanticTests/externalSource/_relative_imports/c.sol rename to test/libsolidity/semanticTests/externalSource/_relativeImports/c.sol diff --git a/test/libsolidity/semanticTests/externalSource/_relative_imports/dir/B/b.sol b/test/libsolidity/semanticTests/externalSource/_relativeImports/dir/B/b.sol similarity index 100% rename from test/libsolidity/semanticTests/externalSource/_relative_imports/dir/B/b.sol rename to test/libsolidity/semanticTests/externalSource/_relativeImports/dir/B/b.sol diff --git a/test/libsolidity/semanticTests/externalSource/_relative_imports/dir/G/g.sol b/test/libsolidity/semanticTests/externalSource/_relativeImports/dir/G/g.sol similarity index 100% rename from test/libsolidity/semanticTests/externalSource/_relative_imports/dir/G/g.sol rename to test/libsolidity/semanticTests/externalSource/_relativeImports/dir/G/g.sol diff --git a/test/libsolidity/semanticTests/externalSource/_relative_imports/dir/a.sol b/test/libsolidity/semanticTests/externalSource/_relativeImports/dir/a.sol similarity index 100% rename from test/libsolidity/semanticTests/externalSource/_relative_imports/dir/a.sol rename to test/libsolidity/semanticTests/externalSource/_relativeImports/dir/a.sol diff --git a/test/libsolidity/semanticTests/externalSource/_relative_imports/dir/contract.sol b/test/libsolidity/semanticTests/externalSource/_relativeImports/dir/contract.sol similarity index 76% rename from test/libsolidity/semanticTests/externalSource/_relative_imports/dir/contract.sol rename to test/libsolidity/semanticTests/externalSource/_relativeImports/dir/contract.sol index aab81b975c5b..e41d935a233d 100644 --- a/test/libsolidity/semanticTests/externalSource/_relative_imports/dir/contract.sol +++ b/test/libsolidity/semanticTests/externalSource/_relativeImports/dir/contract.sol @@ -3,6 +3,6 @@ import {B} from "./B/b.sol"; import {C} from "../c.sol"; import {D} from "../D/d.sol"; import {G} from "./E/../F/../G/./g.sol"; -import {H} from "../../../../_relative_imports/h.sol"; +import {H} from "../../../../_relativeImports/h.sol"; contract Contract { } diff --git a/test/libsolidity/semanticTests/externalSource/_relative_imports/h.sol b/test/libsolidity/semanticTests/externalSource/_relativeImports/h.sol similarity index 100% rename from test/libsolidity/semanticTests/externalSource/_relative_imports/h.sol rename to test/libsolidity/semanticTests/externalSource/_relativeImports/h.sol diff --git a/test/libsolidity/semanticTests/externalSource/_source_name_starting_with_dots/b.sol b/test/libsolidity/semanticTests/externalSource/_sourceNameStartingWithDots/b.sol similarity index 100% rename from test/libsolidity/semanticTests/externalSource/_source_name_starting_with_dots/b.sol rename to test/libsolidity/semanticTests/externalSource/_sourceNameStartingWithDots/b.sol diff --git a/test/libsolidity/semanticTests/externalSource/_source_name_starting_with_dots/dir/a.sol b/test/libsolidity/semanticTests/externalSource/_sourceNameStartingWithDots/dir/a.sol similarity index 100% rename from test/libsolidity/semanticTests/externalSource/_source_name_starting_with_dots/dir/a.sol rename to test/libsolidity/semanticTests/externalSource/_sourceNameStartingWithDots/dir/a.sol diff --git a/test/libsolidity/semanticTests/externalSource/_source_name_starting_with_dots/dir/contract.sol b/test/libsolidity/semanticTests/externalSource/_sourceNameStartingWithDots/dir/contract.sol similarity index 100% rename from test/libsolidity/semanticTests/externalSource/_source_name_starting_with_dots/dir/contract.sol rename to test/libsolidity/semanticTests/externalSource/_sourceNameStartingWithDots/dir/contract.sol diff --git a/test/libsolidity/semanticTests/externalSource/_source_name_starting_with_dots/dot_a.sol b/test/libsolidity/semanticTests/externalSource/_sourceNameStartingWithDots/dot_a.sol similarity index 100% rename from test/libsolidity/semanticTests/externalSource/_source_name_starting_with_dots/dot_a.sol rename to test/libsolidity/semanticTests/externalSource/_sourceNameStartingWithDots/dot_a.sol diff --git a/test/libsolidity/semanticTests/externalSource/_source_name_starting_with_dots/dot_dot_b.sol b/test/libsolidity/semanticTests/externalSource/_sourceNameStartingWithDots/dot_dot_b.sol similarity index 100% rename from test/libsolidity/semanticTests/externalSource/_source_name_starting_with_dots/dot_dot_b.sol rename to test/libsolidity/semanticTests/externalSource/_sourceNameStartingWithDots/dot_dot_b.sol diff --git a/test/libsolidity/semanticTests/externalSource/non_normalized_paths.sol b/test/libsolidity/semanticTests/externalSource/non_normalized_paths.sol index 7316cc7d57fd..84ad75514f99 100644 --- a/test/libsolidity/semanticTests/externalSource/non_normalized_paths.sol +++ b/test/libsolidity/semanticTests/externalSource/non_normalized_paths.sol @@ -1,7 +1,7 @@ -==== ExternalSource: _non_normalized_paths//a.sol ==== -==== ExternalSource: C/////c.sol=_non_normalized_paths/c.sol ==== -==== ExternalSource: C/../////D/d.sol=_non_normalized_paths///d.sol ==== -import {A} from "_non_normalized_paths//a.sol"; +==== ExternalSource: _nonNormalizedPaths//a.sol ==== +==== ExternalSource: C/////c.sol=_nonNormalizedPaths/c.sol ==== +==== ExternalSource: C/../////D/d.sol=_nonNormalizedPaths///d.sol ==== +import {A} from "_nonNormalizedPaths//a.sol"; import {C} from "C/////c.sol"; import {D} from "C/../////D/d.sol"; contract Contract { diff --git a/test/libsolidity/semanticTests/externalSource/relative_imports.sol b/test/libsolidity/semanticTests/externalSource/relative_imports.sol index 9a37896bb568..e8e4022294fc 100644 --- a/test/libsolidity/semanticTests/externalSource/relative_imports.sol +++ b/test/libsolidity/semanticTests/externalSource/relative_imports.sol @@ -1,11 +1,11 @@ -==== ExternalSource: _relative_imports/dir/contract.sol ==== -==== ExternalSource: _relative_imports/dir/a.sol ==== -==== ExternalSource: _relative_imports/dir/B/b.sol ==== -==== ExternalSource: _relative_imports/c.sol ==== -==== ExternalSource: _relative_imports/D/d.sol ==== -==== ExternalSource: _relative_imports/dir/G/g.sol ==== -==== ExternalSource: _relative_imports/h.sol ==== -import {A, B, C, D, G, H, Contract} from "_relative_imports/dir/contract.sol"; +==== ExternalSource: _relativeImports/dir/contract.sol ==== +==== ExternalSource: _relativeImports/dir/a.sol ==== +==== ExternalSource: _relativeImports/dir/B/b.sol ==== +==== ExternalSource: _relativeImports/c.sol ==== +==== ExternalSource: _relativeImports/D/d.sol ==== +==== ExternalSource: _relativeImports/dir/G/g.sol ==== +==== ExternalSource: _relativeImports/h.sol ==== +import {A, B, C, D, G, H, Contract} from "_relativeImports/dir/contract.sol"; contract CC { } // ---- diff --git a/test/libsolidity/semanticTests/externalSource/source_name_starting_with_dots.sol b/test/libsolidity/semanticTests/externalSource/source_name_starting_with_dots.sol index b671c94f9f9d..bb325b39110f 100644 --- a/test/libsolidity/semanticTests/externalSource/source_name_starting_with_dots.sol +++ b/test/libsolidity/semanticTests/externalSource/source_name_starting_with_dots.sol @@ -1,9 +1,9 @@ -==== ExternalSource: ./a.sol=_source_name_starting_with_dots/dot_a.sol ==== -==== ExternalSource: ../b.sol=_source_name_starting_with_dots/dot_dot_b.sol ==== -==== ExternalSource: _source_name_starting_with_dots/dir/a.sol ==== -==== ExternalSource: _source_name_starting_with_dots/b.sol ==== -==== ExternalSource: _source_name_starting_with_dots/dir/contract.sol ==== -import {A, B} from "_source_name_starting_with_dots/dir/contract.sol"; +==== ExternalSource: ./a.sol=_sourceNameStartingWithDots/dot_a.sol ==== +==== ExternalSource: ../b.sol=_sourceNameStartingWithDots/dot_dot_b.sol ==== +==== ExternalSource: _sourceNameStartingWithDots/dir/a.sol ==== +==== ExternalSource: _sourceNameStartingWithDots/b.sol ==== +==== ExternalSource: _sourceNameStartingWithDots/dir/contract.sol ==== +import {A, B} from "_sourceNameStartingWithDots/dir/contract.sol"; contract Contract { } // ---- diff --git a/test/libsolidity/semanticTests/salted_create/prediction_example.sol b/test/libsolidity/semanticTests/saltedCreate/prediction_example.sol similarity index 100% rename from test/libsolidity/semanticTests/salted_create/prediction_example.sol rename to test/libsolidity/semanticTests/saltedCreate/prediction_example.sol diff --git a/test/libsolidity/semanticTests/salted_create/salted_create.sol b/test/libsolidity/semanticTests/saltedCreate/salted_create.sol similarity index 100% rename from test/libsolidity/semanticTests/salted_create/salted_create.sol rename to test/libsolidity/semanticTests/saltedCreate/salted_create.sol diff --git a/test/libsolidity/semanticTests/salted_create/salted_create_with_value.sol b/test/libsolidity/semanticTests/saltedCreate/salted_create_with_value.sol similarity index 100% rename from test/libsolidity/semanticTests/salted_create/salted_create_with_value.sol rename to test/libsolidity/semanticTests/saltedCreate/salted_create_with_value.sol diff --git a/test/libsolidity/syntaxTests/inheritance/duplicated_constructor_call/ancestor.sol b/test/libsolidity/syntaxTests/inheritance/duplicatedConstructorCall/ancestor.sol similarity index 100% rename from test/libsolidity/syntaxTests/inheritance/duplicated_constructor_call/ancestor.sol rename to test/libsolidity/syntaxTests/inheritance/duplicatedConstructorCall/ancestor.sol diff --git a/test/libsolidity/syntaxTests/inheritance/duplicated_constructor_call/base.sol b/test/libsolidity/syntaxTests/inheritance/duplicatedConstructorCall/base.sol similarity index 100% rename from test/libsolidity/syntaxTests/inheritance/duplicated_constructor_call/base.sol rename to test/libsolidity/syntaxTests/inheritance/duplicatedConstructorCall/base.sol diff --git a/test/libsolidity/syntaxTests/inheritance/duplicated_constructor_call/base_multi.sol b/test/libsolidity/syntaxTests/inheritance/duplicatedConstructorCall/base_multi.sol similarity index 100% rename from test/libsolidity/syntaxTests/inheritance/duplicated_constructor_call/base_multi.sol rename to test/libsolidity/syntaxTests/inheritance/duplicatedConstructorCall/base_multi.sol diff --git a/test/libsolidity/syntaxTests/inheritance/duplicated_constructor_call/base_multi_no_constructor.sol b/test/libsolidity/syntaxTests/inheritance/duplicatedConstructorCall/base_multi_no_constructor.sol similarity index 100% rename from test/libsolidity/syntaxTests/inheritance/duplicated_constructor_call/base_multi_no_constructor.sol rename to test/libsolidity/syntaxTests/inheritance/duplicatedConstructorCall/base_multi_no_constructor.sol diff --git a/test/libsolidity/syntaxTests/inheritance/duplicated_constructor_call/base_multi_no_constructor_modifier_style.sol b/test/libsolidity/syntaxTests/inheritance/duplicatedConstructorCall/base_multi_no_constructor_modifier_style.sol similarity index 100% rename from test/libsolidity/syntaxTests/inheritance/duplicated_constructor_call/base_multi_no_constructor_modifier_style.sol rename to test/libsolidity/syntaxTests/inheritance/duplicatedConstructorCall/base_multi_no_constructor_modifier_style.sol diff --git a/test/libsolidity/syntaxTests/inheritance/fallback_receive/fallback_overrides_receive.sol b/test/libsolidity/syntaxTests/inheritance/fallbackReceive/fallback_overrides_receive.sol similarity index 100% rename from test/libsolidity/syntaxTests/inheritance/fallback_receive/fallback_overrides_receive.sol rename to test/libsolidity/syntaxTests/inheritance/fallbackReceive/fallback_overrides_receive.sol diff --git a/test/libsolidity/syntaxTests/inheritance/fallback_receive/fallback_with_override.sol b/test/libsolidity/syntaxTests/inheritance/fallbackReceive/fallback_with_override.sol similarity index 100% rename from test/libsolidity/syntaxTests/inheritance/fallback_receive/fallback_with_override.sol rename to test/libsolidity/syntaxTests/inheritance/fallbackReceive/fallback_with_override.sol diff --git a/test/libsolidity/syntaxTests/inheritance/fallback_receive/fallback_with_override_intermediate.sol b/test/libsolidity/syntaxTests/inheritance/fallbackReceive/fallback_with_override_intermediate.sol similarity index 100% rename from test/libsolidity/syntaxTests/inheritance/fallback_receive/fallback_with_override_intermediate.sol rename to test/libsolidity/syntaxTests/inheritance/fallbackReceive/fallback_with_override_intermediate.sol diff --git a/test/libsolidity/syntaxTests/inheritance/fallback_receive/fallback_without_override.sol b/test/libsolidity/syntaxTests/inheritance/fallbackReceive/fallback_without_override.sol similarity index 100% rename from test/libsolidity/syntaxTests/inheritance/fallback_receive/fallback_without_override.sol rename to test/libsolidity/syntaxTests/inheritance/fallbackReceive/fallback_without_override.sol diff --git a/test/libsolidity/syntaxTests/inheritance/fallback_receive/fallback_without_override_intermediate.sol b/test/libsolidity/syntaxTests/inheritance/fallbackReceive/fallback_without_override_intermediate.sol similarity index 100% rename from test/libsolidity/syntaxTests/inheritance/fallback_receive/fallback_without_override_intermediate.sol rename to test/libsolidity/syntaxTests/inheritance/fallbackReceive/fallback_without_override_intermediate.sol diff --git a/test/libsolidity/syntaxTests/inheritance/fallback_receive/receive_overrides_fallback.sol b/test/libsolidity/syntaxTests/inheritance/fallbackReceive/receive_overrides_fallback.sol similarity index 100% rename from test/libsolidity/syntaxTests/inheritance/fallback_receive/receive_overrides_fallback.sol rename to test/libsolidity/syntaxTests/inheritance/fallbackReceive/receive_overrides_fallback.sol diff --git a/test/libsolidity/syntaxTests/inheritance/fallback_receive/receive_parameter.sol b/test/libsolidity/syntaxTests/inheritance/fallbackReceive/receive_parameter.sol similarity index 100% rename from test/libsolidity/syntaxTests/inheritance/fallback_receive/receive_parameter.sol rename to test/libsolidity/syntaxTests/inheritance/fallbackReceive/receive_parameter.sol diff --git a/test/libsolidity/syntaxTests/inheritance/fallback_receive/receive_return_parameter.sol b/test/libsolidity/syntaxTests/inheritance/fallbackReceive/receive_return_parameter.sol similarity index 100% rename from test/libsolidity/syntaxTests/inheritance/fallback_receive/receive_return_parameter.sol rename to test/libsolidity/syntaxTests/inheritance/fallbackReceive/receive_return_parameter.sol diff --git a/test/libsolidity/syntaxTests/inheritance/fallback_receive/receive_unimplemented.sol b/test/libsolidity/syntaxTests/inheritance/fallbackReceive/receive_unimplemented.sol similarity index 100% rename from test/libsolidity/syntaxTests/inheritance/fallback_receive/receive_unimplemented.sol rename to test/libsolidity/syntaxTests/inheritance/fallbackReceive/receive_unimplemented.sol diff --git a/test/libsolidity/syntaxTests/inheritance/fallback_receive/receive_with_override.sol b/test/libsolidity/syntaxTests/inheritance/fallbackReceive/receive_with_override.sol similarity index 100% rename from test/libsolidity/syntaxTests/inheritance/fallback_receive/receive_with_override.sol rename to test/libsolidity/syntaxTests/inheritance/fallbackReceive/receive_with_override.sol diff --git a/test/libsolidity/syntaxTests/inheritance/fallback_receive/receive_with_override_intermediate.sol b/test/libsolidity/syntaxTests/inheritance/fallbackReceive/receive_with_override_intermediate.sol similarity index 100% rename from test/libsolidity/syntaxTests/inheritance/fallback_receive/receive_with_override_intermediate.sol rename to test/libsolidity/syntaxTests/inheritance/fallbackReceive/receive_with_override_intermediate.sol diff --git a/test/libsolidity/syntaxTests/inheritance/fallback_receive/receive_without_override.sol b/test/libsolidity/syntaxTests/inheritance/fallbackReceive/receive_without_override.sol similarity index 100% rename from test/libsolidity/syntaxTests/inheritance/fallback_receive/receive_without_override.sol rename to test/libsolidity/syntaxTests/inheritance/fallbackReceive/receive_without_override.sol diff --git a/test/libsolidity/syntaxTests/inheritance/fallback_receive/receive_without_override_intermediate.sol b/test/libsolidity/syntaxTests/inheritance/fallbackReceive/receive_without_override_intermediate.sol similarity index 100% rename from test/libsolidity/syntaxTests/inheritance/fallback_receive/receive_without_override_intermediate.sol rename to test/libsolidity/syntaxTests/inheritance/fallbackReceive/receive_without_override_intermediate.sol diff --git a/test/libsolidity/syntaxTests/inheritance/override/interface_exception/abstract_needed.sol b/test/libsolidity/syntaxTests/inheritance/override/interfaceException/abstract_needed.sol similarity index 100% rename from test/libsolidity/syntaxTests/inheritance/override/interface_exception/abstract_needed.sol rename to test/libsolidity/syntaxTests/inheritance/override/interfaceException/abstract_needed.sol diff --git a/test/libsolidity/syntaxTests/inheritance/override/interface_exception/diamond_needed.sol b/test/libsolidity/syntaxTests/inheritance/override/interfaceException/diamond_needed.sol similarity index 100% rename from test/libsolidity/syntaxTests/inheritance/override/interface_exception/diamond_needed.sol rename to test/libsolidity/syntaxTests/inheritance/override/interfaceException/diamond_needed.sol diff --git a/test/libsolidity/syntaxTests/inheritance/override/interface_exception/regular_optional.sol b/test/libsolidity/syntaxTests/inheritance/override/interfaceException/regular_optional.sol similarity index 100% rename from test/libsolidity/syntaxTests/inheritance/override/interface_exception/regular_optional.sol rename to test/libsolidity/syntaxTests/inheritance/override/interfaceException/regular_optional.sol diff --git a/test/libsolidity/syntaxTests/inline_arrays/dynamic_inline_array.sol b/test/libsolidity/syntaxTests/inlineArrays/dynamic_inline_array.sol similarity index 100% rename from test/libsolidity/syntaxTests/inline_arrays/dynamic_inline_array.sol rename to test/libsolidity/syntaxTests/inlineArrays/dynamic_inline_array.sol diff --git a/test/libsolidity/syntaxTests/inline_arrays/inline_array_declaration_and_passing_implicit_conversion.sol b/test/libsolidity/syntaxTests/inlineArrays/inline_array_declaration_and_passing_implicit_conversion.sol similarity index 100% rename from test/libsolidity/syntaxTests/inline_arrays/inline_array_declaration_and_passing_implicit_conversion.sol rename to test/libsolidity/syntaxTests/inlineArrays/inline_array_declaration_and_passing_implicit_conversion.sol diff --git a/test/libsolidity/syntaxTests/inline_arrays/inline_array_declaration_and_passing_implicit_conversion_strings.sol b/test/libsolidity/syntaxTests/inlineArrays/inline_array_declaration_and_passing_implicit_conversion_strings.sol similarity index 100% rename from test/libsolidity/syntaxTests/inline_arrays/inline_array_declaration_and_passing_implicit_conversion_strings.sol rename to test/libsolidity/syntaxTests/inlineArrays/inline_array_declaration_and_passing_implicit_conversion_strings.sol diff --git a/test/libsolidity/syntaxTests/inline_arrays/inline_array_declaration_const_int_conversion.sol b/test/libsolidity/syntaxTests/inlineArrays/inline_array_declaration_const_int_conversion.sol similarity index 100% rename from test/libsolidity/syntaxTests/inline_arrays/inline_array_declaration_const_int_conversion.sol rename to test/libsolidity/syntaxTests/inlineArrays/inline_array_declaration_const_int_conversion.sol diff --git a/test/libsolidity/syntaxTests/inline_arrays/inline_array_declaration_const_string_conversion.sol b/test/libsolidity/syntaxTests/inlineArrays/inline_array_declaration_const_string_conversion.sol similarity index 100% rename from test/libsolidity/syntaxTests/inline_arrays/inline_array_declaration_const_string_conversion.sol rename to test/libsolidity/syntaxTests/inlineArrays/inline_array_declaration_const_string_conversion.sol diff --git a/test/libsolidity/syntaxTests/inline_arrays/inline_array_declaration_no_type.sol b/test/libsolidity/syntaxTests/inlineArrays/inline_array_declaration_no_type.sol similarity index 100% rename from test/libsolidity/syntaxTests/inline_arrays/inline_array_declaration_no_type.sol rename to test/libsolidity/syntaxTests/inlineArrays/inline_array_declaration_no_type.sol diff --git a/test/libsolidity/syntaxTests/inline_arrays/inline_array_declaration_no_type_strings.sol b/test/libsolidity/syntaxTests/inlineArrays/inline_array_declaration_no_type_strings.sol similarity index 100% rename from test/libsolidity/syntaxTests/inline_arrays/inline_array_declaration_no_type_strings.sol rename to test/libsolidity/syntaxTests/inlineArrays/inline_array_declaration_no_type_strings.sol diff --git a/test/libsolidity/syntaxTests/inline_arrays/inline_array_fixed_types.sol b/test/libsolidity/syntaxTests/inlineArrays/inline_array_fixed_types.sol similarity index 100% rename from test/libsolidity/syntaxTests/inline_arrays/inline_array_fixed_types.sol rename to test/libsolidity/syntaxTests/inlineArrays/inline_array_fixed_types.sol diff --git a/test/libsolidity/syntaxTests/inline_arrays/inline_array_of_mapping_type.sol b/test/libsolidity/syntaxTests/inlineArrays/inline_array_of_mapping_type.sol similarity index 100% rename from test/libsolidity/syntaxTests/inline_arrays/inline_array_of_mapping_type.sol rename to test/libsolidity/syntaxTests/inlineArrays/inline_array_of_mapping_type.sol diff --git a/test/libsolidity/syntaxTests/inline_arrays/inline_array_rationals.sol b/test/libsolidity/syntaxTests/inlineArrays/inline_array_rationals.sol similarity index 100% rename from test/libsolidity/syntaxTests/inline_arrays/inline_array_rationals.sol rename to test/libsolidity/syntaxTests/inlineArrays/inline_array_rationals.sol diff --git a/test/libsolidity/syntaxTests/inline_arrays/invalid_types_in_inline_array.sol b/test/libsolidity/syntaxTests/inlineArrays/invalid_types_in_inline_array.sol similarity index 100% rename from test/libsolidity/syntaxTests/inline_arrays/invalid_types_in_inline_array.sol rename to test/libsolidity/syntaxTests/inlineArrays/invalid_types_in_inline_array.sol diff --git a/test/libsolidity/syntaxTests/inline_arrays/lvalues_as_inline_array.sol b/test/libsolidity/syntaxTests/inlineArrays/lvalues_as_inline_array.sol similarity index 100% rename from test/libsolidity/syntaxTests/inline_arrays/lvalues_as_inline_array.sol rename to test/libsolidity/syntaxTests/inlineArrays/lvalues_as_inline_array.sol diff --git a/test/libsolidity/syntaxTests/inline_arrays/unnamed_type_tuple_in_inline_array.sol b/test/libsolidity/syntaxTests/inlineArrays/unnamed_type_tuple_in_inline_array.sol similarity index 100% rename from test/libsolidity/syntaxTests/inline_arrays/unnamed_type_tuple_in_inline_array.sol rename to test/libsolidity/syntaxTests/inlineArrays/unnamed_type_tuple_in_inline_array.sol diff --git a/test/libsolidity/syntaxTests/inline_arrays/unnamed_types_in_inline_array_1.sol b/test/libsolidity/syntaxTests/inlineArrays/unnamed_types_in_inline_array_1.sol similarity index 100% rename from test/libsolidity/syntaxTests/inline_arrays/unnamed_types_in_inline_array_1.sol rename to test/libsolidity/syntaxTests/inlineArrays/unnamed_types_in_inline_array_1.sol diff --git a/test/libsolidity/syntaxTests/inline_arrays/unnamed_types_in_inline_array_2.sol b/test/libsolidity/syntaxTests/inlineArrays/unnamed_types_in_inline_array_2.sol similarity index 100% rename from test/libsolidity/syntaxTests/inline_arrays/unnamed_types_in_inline_array_2.sol rename to test/libsolidity/syntaxTests/inlineArrays/unnamed_types_in_inline_array_2.sol diff --git a/test/libsolidity/syntaxTests/inline_arrays/unnamed_types_in_inline_array_3.sol b/test/libsolidity/syntaxTests/inlineArrays/unnamed_types_in_inline_array_3.sol similarity index 100% rename from test/libsolidity/syntaxTests/inline_arrays/unnamed_types_in_inline_array_3.sol rename to test/libsolidity/syntaxTests/inlineArrays/unnamed_types_in_inline_array_3.sol diff --git a/test/libsolidity/syntaxTests/types/function_types/function_definition_expression.sol b/test/libsolidity/syntaxTests/types/functionTypes/function_definition_expression.sol similarity index 100% rename from test/libsolidity/syntaxTests/types/function_types/function_definition_expression.sol rename to test/libsolidity/syntaxTests/types/functionTypes/function_definition_expression.sol diff --git a/test/libsolidity/syntaxTests/types/function_types/function_parameter_return_types_fail.sol b/test/libsolidity/syntaxTests/types/functionTypes/function_parameter_return_types_fail.sol similarity index 100% rename from test/libsolidity/syntaxTests/types/function_types/function_parameter_return_types_fail.sol rename to test/libsolidity/syntaxTests/types/functionTypes/function_parameter_return_types_fail.sol diff --git a/test/libsolidity/syntaxTests/types/function_types/function_parameter_return_types_success.sol b/test/libsolidity/syntaxTests/types/functionTypes/function_parameter_return_types_success.sol similarity index 100% rename from test/libsolidity/syntaxTests/types/function_types/function_parameter_return_types_success.sol rename to test/libsolidity/syntaxTests/types/functionTypes/function_parameter_return_types_success.sol diff --git a/test/libsolidity/syntaxTests/types/function_types/function_state_mutability_fail.sol b/test/libsolidity/syntaxTests/types/functionTypes/function_state_mutability_fail.sol similarity index 100% rename from test/libsolidity/syntaxTests/types/function_types/function_state_mutability_fail.sol rename to test/libsolidity/syntaxTests/types/functionTypes/function_state_mutability_fail.sol diff --git a/test/libsolidity/syntaxTests/types/function_types/function_state_mutability_success.sol b/test/libsolidity/syntaxTests/types/functionTypes/function_state_mutability_success.sol similarity index 100% rename from test/libsolidity/syntaxTests/types/function_types/function_state_mutability_success.sol rename to test/libsolidity/syntaxTests/types/functionTypes/function_state_mutability_success.sol diff --git a/test/libsolidity/syntaxTests/types/function_types/selector/function_selector_pure.sol b/test/libsolidity/syntaxTests/types/functionTypes/selector/function_selector_pure.sol similarity index 100% rename from test/libsolidity/syntaxTests/types/function_types/selector/function_selector_pure.sol rename to test/libsolidity/syntaxTests/types/functionTypes/selector/function_selector_pure.sol diff --git a/test/libsolidity/syntaxTests/types/function_types/selector/local_variable_selector_not_pure.sol b/test/libsolidity/syntaxTests/types/functionTypes/selector/local_variable_selector_not_pure.sol similarity index 100% rename from test/libsolidity/syntaxTests/types/function_types/selector/local_variable_selector_not_pure.sol rename to test/libsolidity/syntaxTests/types/functionTypes/selector/local_variable_selector_not_pure.sol diff --git a/test/libsolidity/syntaxTests/types/function_types/selector/state_variable_selector_contract_name.sol b/test/libsolidity/syntaxTests/types/functionTypes/selector/state_variable_selector_contract_name.sol similarity index 100% rename from test/libsolidity/syntaxTests/types/function_types/selector/state_variable_selector_contract_name.sol rename to test/libsolidity/syntaxTests/types/functionTypes/selector/state_variable_selector_contract_name.sol diff --git a/test/libsolidity/syntaxTests/types/function_types/selector/state_variable_selector_not_pure.sol b/test/libsolidity/syntaxTests/types/functionTypes/selector/state_variable_selector_not_pure.sol similarity index 100% rename from test/libsolidity/syntaxTests/types/function_types/selector/state_variable_selector_not_pure.sol rename to test/libsolidity/syntaxTests/types/functionTypes/selector/state_variable_selector_not_pure.sol diff --git a/test/libsolidity/syntaxTests/types/function_types/selector/state_variable_selector_super.sol b/test/libsolidity/syntaxTests/types/functionTypes/selector/state_variable_selector_super.sol similarity index 100% rename from test/libsolidity/syntaxTests/types/function_types/selector/state_variable_selector_super.sol rename to test/libsolidity/syntaxTests/types/functionTypes/selector/state_variable_selector_super.sol From 11b770f725d13b7bc9e43f7c43e4ff96e54ba7d4 Mon Sep 17 00:00:00 2001 From: kilavvy <140459108+kilavvy@users.noreply.github.com> Date: Fri, 24 Jan 2025 03:51:41 +0100 Subject: [PATCH 0725/1022] fix typo in `distinguishingProperty` variable name (#15763) * Update FilesystemUtils.cpp * Update OverrideChecker.cpp --- libsolidity/analysis/OverrideChecker.cpp | 4 ++-- test/FilesystemUtils.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/libsolidity/analysis/OverrideChecker.cpp b/libsolidity/analysis/OverrideChecker.cpp index f2a99340deee..f51aa2b6e5e0 100644 --- a/libsolidity/analysis/OverrideChecker.cpp +++ b/libsolidity/analysis/OverrideChecker.cpp @@ -801,7 +801,7 @@ void OverrideChecker::checkAmbiguousOverridesInternal(std::set _b std::string callableName = _baseCallables.begin()->astNodeName(); if (_baseCallables.begin()->isVariable()) callableName = "function"; - std::string distinguishigProperty = _baseCallables.begin()->distinguishingProperty(); + std::string distinguishingProperty = _baseCallables.begin()->distinguishingProperty(); bool foundVariable = false; for (auto const& base: _baseCallables) @@ -811,7 +811,7 @@ void OverrideChecker::checkAmbiguousOverridesInternal(std::set _b std::string message = "Derived contract must override " + callableName + " \"" + _baseCallables.begin()->name() + - "\". Two or more base classes define " + callableName + " with same " + distinguishigProperty + "."; + "\". Two or more base classes define " + callableName + " with same " + distinguishingProperty + "."; if (foundVariable) message += diff --git a/test/FilesystemUtils.cpp b/test/FilesystemUtils.cpp index 2d917485d631..edd9a0d6d11d 100644 --- a/test/FilesystemUtils.cpp +++ b/test/FilesystemUtils.cpp @@ -44,12 +44,12 @@ void solidity::test::createFilesWithParentDirs(std::set void solidity::test::createFileWithContent(boost::filesystem::path const& _path, std::string const& _content) { if (boost::filesystem::is_regular_file(_path)) - BOOST_THROW_EXCEPTION(std::runtime_error("File already exists: \"" + _path.string() + "\".")); \ + BOOST_THROW_EXCEPTION(std::runtime_error("File already exists: \"" + _path.string() + "\".")); // Use binary mode to avoid line ending conversion on Windows. std::ofstream newFile(_path.string(), std::ofstream::binary); if (newFile.fail() || !boost::filesystem::is_regular_file(_path)) - BOOST_THROW_EXCEPTION(std::runtime_error("Failed to create a file: \"" + _path.string() + "\".")); \ + BOOST_THROW_EXCEPTION(std::runtime_error("Failed to create a file: \"" + _path.string() + "\".")); newFile << _content; } From 2d7dc289cd36ba82a7d8d52226be5cea1e7a69a7 Mon Sep 17 00:00:00 2001 From: Maxim Evtush <154841002+maximevtush@users.noreply.github.com> Date: Fri, 24 Jan 2025 04:29:15 +0100 Subject: [PATCH 0726/1022] fix typo in `ExpressionNestingLimitReached` enum value (#15767) * Update yulFuzzerCommon.cpp * Update yulFuzzerCommon.h --- test/tools/ossfuzz/yulFuzzerCommon.cpp | 4 ++-- test/tools/ossfuzz/yulFuzzerCommon.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/test/tools/ossfuzz/yulFuzzerCommon.cpp b/test/tools/ossfuzz/yulFuzzerCommon.cpp index 033dfc044d12..b95df8f2138c 100644 --- a/test/tools/ossfuzz/yulFuzzerCommon.cpp +++ b/test/tools/ossfuzz/yulFuzzerCommon.cpp @@ -64,7 +64,7 @@ yulFuzzerUtil::TerminationReason yulFuzzerUtil::interpret( } catch (ExpressionNestingLimitReached const&) { - reason = TerminationReason::ExpresionNestingLimitReached; + reason = TerminationReason::ExpressionNestingLimitReached; } catch (ExplicitlyTerminated const&) { @@ -83,5 +83,5 @@ bool yulFuzzerUtil::resourceLimitsExceeded(TerminationReason _reason) return _reason == yulFuzzerUtil::TerminationReason::StepLimitReached || _reason == yulFuzzerUtil::TerminationReason::TraceLimitReached || - _reason == yulFuzzerUtil::TerminationReason::ExpresionNestingLimitReached; + _reason == yulFuzzerUtil::TerminationReason::ExpressionNestingLimitReached; } diff --git a/test/tools/ossfuzz/yulFuzzerCommon.h b/test/tools/ossfuzz/yulFuzzerCommon.h index 6575db11face..afcb0f2d3c9e 100644 --- a/test/tools/ossfuzz/yulFuzzerCommon.h +++ b/test/tools/ossfuzz/yulFuzzerCommon.h @@ -28,7 +28,7 @@ struct yulFuzzerUtil ExplicitlyTerminated, StepLimitReached, TraceLimitReached, - ExpresionNestingLimitReached, + ExpressionNestingLimitReached, None }; From 9cb47312cfcfe0b766d1f46d0da8108d3ce115e8 Mon Sep 17 00:00:00 2001 From: FT <140458077+zeevick10@users.noreply.github.com> Date: Fri, 24 Jan 2025 12:31:24 +0100 Subject: [PATCH 0727/1022] Update StackCompressor.cpp --- libyul/optimiser/StackCompressor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libyul/optimiser/StackCompressor.cpp b/libyul/optimiser/StackCompressor.cpp index 04b931a248e8..ae91716e5385 100644 --- a/libyul/optimiser/StackCompressor.cpp +++ b/libyul/optimiser/StackCompressor.cpp @@ -15,7 +15,7 @@ along with solidity. If not, see . */ /** - * Optimisation stage that aggressively rematerializes certain variables ina a function to free + * Optimisation stage that aggressively rematerializes certain variables in a function to free * space on the stack until it is compilable. */ From 39c14916c25d89f8eab377c84f98ef2a46f1893f Mon Sep 17 00:00:00 2001 From: FT <140458077+zeevick10@users.noreply.github.com> Date: Fri, 24 Jan 2025 12:31:39 +0100 Subject: [PATCH 0728/1022] Update StackCompressor.h --- libyul/optimiser/StackCompressor.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libyul/optimiser/StackCompressor.h b/libyul/optimiser/StackCompressor.h index d5590006c855..728acb813001 100644 --- a/libyul/optimiser/StackCompressor.h +++ b/libyul/optimiser/StackCompressor.h @@ -16,7 +16,7 @@ */ // SPDX-License-Identifier: GPL-3.0 /** - * Optimisation stage that aggressively rematerializes certain variables ina a function to free + * Optimisation stage that aggressively rematerializes certain variables in a function to free * space on the stack until it is compilable. */ From 01ba4a45d98068392cfe1263d0ce729e578a0260 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Thu, 23 Jan 2025 19:30:43 +0100 Subject: [PATCH 0729/1022] Semantic tests: merge asmForLoop/ with inlineAssembly/ --- .../{asmForLoop => inlineAssembly}/for_loop_break.sol | 0 .../{asmForLoop => inlineAssembly}/for_loop_continue.sol | 0 .../{asmForLoop => inlineAssembly}/for_loop_nested.sol | 0 3 files changed, 0 insertions(+), 0 deletions(-) rename test/libsolidity/semanticTests/{asmForLoop => inlineAssembly}/for_loop_break.sol (100%) rename test/libsolidity/semanticTests/{asmForLoop => inlineAssembly}/for_loop_continue.sol (100%) rename test/libsolidity/semanticTests/{asmForLoop => inlineAssembly}/for_loop_nested.sol (100%) diff --git a/test/libsolidity/semanticTests/asmForLoop/for_loop_break.sol b/test/libsolidity/semanticTests/inlineAssembly/for_loop_break.sol similarity index 100% rename from test/libsolidity/semanticTests/asmForLoop/for_loop_break.sol rename to test/libsolidity/semanticTests/inlineAssembly/for_loop_break.sol diff --git a/test/libsolidity/semanticTests/asmForLoop/for_loop_continue.sol b/test/libsolidity/semanticTests/inlineAssembly/for_loop_continue.sol similarity index 100% rename from test/libsolidity/semanticTests/asmForLoop/for_loop_continue.sol rename to test/libsolidity/semanticTests/inlineAssembly/for_loop_continue.sol diff --git a/test/libsolidity/semanticTests/asmForLoop/for_loop_nested.sol b/test/libsolidity/semanticTests/inlineAssembly/for_loop_nested.sol similarity index 100% rename from test/libsolidity/semanticTests/asmForLoop/for_loop_nested.sol rename to test/libsolidity/semanticTests/inlineAssembly/for_loop_nested.sol From ea905bd1087005a2c9a55379bcf7e47cc2fa5f0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Thu, 23 Jan 2025 19:30:08 +0100 Subject: [PATCH 0730/1022] Move loose semantic and syntax tests tests to the right subdirectories --- .../{ => cleanup}/byte_array_to_storage_cleanup.sol | 0 .../semanticTests/{ => cleanup}/dirty_calldata_bytes.sol | 0 .../{ => cleanup}/dirty_calldata_dynamic_array.sol | 0 .../state_variable_initialization.sol} | 0 .../{ => events}/emit_three_identical_events.sol | 0 .../{ => events}/emit_two_identical_events.sol | 0 .../constructor_inheritance_init_order.sol | 0 .../constructor_inheritance_init_order_2.sol | 0 .../constructor_inheritance_init_order_3_legacy.sol | 0 .../constructor_inheritance_init_order_3_viaIR.sol | 0 .../{ => inheritance}/constructor_with_params.sol | 0 .../constructor_with_params_diamond_inheritance.sol | 0 .../constructor_with_params_inheritance.sol | 0 .../constructor_with_params_inheritance_2.sol | 0 .../interface_inheritance_conversions.sol | 0 .../{ => inheritance}/state_variables_init_order.sol | 0 .../{ => inheritance}/state_variables_init_order_2.sol | 0 .../{ => inheritance}/state_variables_init_order_3.sol | 0 .../{ => isoltestTesting}/empty_contract.sol | 0 .../{ => isoltestTesting}/isoltestFormatting.sol | 0 .../{ => optimizer}/unused_store_storage_removal_bug.sol | 0 .../{ => scoping}/c99_scoping_activation.sol | 0 .../semanticTests/{ => statements}/empty_for_loop.sol | 0 .../{ => abiEncoder}/tight_packing_literals.sol | 0 .../{ => abiEncoder}/tight_packing_literals_fine.sol | 0 .../syntaxTests/{ => comments}/multiline_comments.sol | 0 .../syntaxTests/{ => constructor}/constructor_this.sol | 0 .../{ => globalFunctions}/deprecated_functions.sol | 0 .../cycle_checker_function_type.sol | 0 .../missing_functions_duplicate_bug.sol | 0 .../{ => isoltestTesting}/stopAfterAnalysisError.sol | 0 .../stopAfterParsingAnalysisErrorNotShowing.sol | 0 .../{ => isoltestTesting}/stopAfterParsingError.sol | 0 .../{ => literalOperations}/literal_comparisons.sol | 0 .../{ => literals}/upper_case_hex_literals.sol | 0 test/libsolidity/syntaxTests/{ => operators}/negation.sol | 0 .../{ => operators}/signed_rational_modulus.sol | 0 test/libsolidity/syntaxTests/{ => parsing}/unexpected.sol | 0 .../{ => scoping}/double_stateVariable_declaration.sol | 0 .../{ => scoping}/double_variable_declaration.sol | 0 .../syntaxTests/{ => scoping}/duplicate_contract.sol | 0 .../syntaxTests/{ => scoping}/missing_state_variable.sol | 0 .../{ => sizeLimits}/more_than_256_declarationerrors.sol | 0 .../{ => sizeLimits}/more_than_256_importerrors.sol | 0 .../{ => sizeLimits}/more_than_256_syntaxerrors.sol | 0 test/libsolidity/syntaxTests/{ => smoke}/smoke_test.sol | 0 .../syntaxTests/{ => structs}/empty_struct.sol | 0 .../{ => super}/unimplemented_super_function.sol | 0 .../{ => super}/unimplemented_super_function_derived.sol | 0 test/scripts/test_bytecodecompare_prepare_report.py | 8 ++++---- 50 files changed, 4 insertions(+), 4 deletions(-) rename test/libsolidity/semanticTests/{ => cleanup}/byte_array_to_storage_cleanup.sol (100%) rename test/libsolidity/semanticTests/{ => cleanup}/dirty_calldata_bytes.sol (100%) rename test/libsolidity/semanticTests/{ => cleanup}/dirty_calldata_dynamic_array.sol (100%) rename test/libsolidity/semanticTests/{state_var_initialization.sol => constructor/state_variable_initialization.sol} (100%) rename test/libsolidity/semanticTests/{ => events}/emit_three_identical_events.sol (100%) rename test/libsolidity/semanticTests/{ => events}/emit_two_identical_events.sol (100%) rename test/libsolidity/semanticTests/{ => inheritance}/constructor_inheritance_init_order.sol (100%) rename test/libsolidity/semanticTests/{ => inheritance}/constructor_inheritance_init_order_2.sol (100%) rename test/libsolidity/semanticTests/{ => inheritance}/constructor_inheritance_init_order_3_legacy.sol (100%) rename test/libsolidity/semanticTests/{ => inheritance}/constructor_inheritance_init_order_3_viaIR.sol (100%) rename test/libsolidity/semanticTests/{ => inheritance}/constructor_with_params.sol (100%) rename test/libsolidity/semanticTests/{ => inheritance}/constructor_with_params_diamond_inheritance.sol (100%) rename test/libsolidity/semanticTests/{ => inheritance}/constructor_with_params_inheritance.sol (100%) rename test/libsolidity/semanticTests/{ => inheritance}/constructor_with_params_inheritance_2.sol (100%) rename test/libsolidity/semanticTests/{ => inheritance}/interface_inheritance_conversions.sol (100%) rename test/libsolidity/semanticTests/{ => inheritance}/state_variables_init_order.sol (100%) rename test/libsolidity/semanticTests/{ => inheritance}/state_variables_init_order_2.sol (100%) rename test/libsolidity/semanticTests/{ => inheritance}/state_variables_init_order_3.sol (100%) rename test/libsolidity/semanticTests/{ => isoltestTesting}/empty_contract.sol (100%) rename test/libsolidity/semanticTests/{ => isoltestTesting}/isoltestFormatting.sol (100%) rename test/libsolidity/semanticTests/{ => optimizer}/unused_store_storage_removal_bug.sol (100%) rename test/libsolidity/semanticTests/{ => scoping}/c99_scoping_activation.sol (100%) rename test/libsolidity/semanticTests/{ => statements}/empty_for_loop.sol (100%) rename test/libsolidity/syntaxTests/{ => abiEncoder}/tight_packing_literals.sol (100%) rename test/libsolidity/syntaxTests/{ => abiEncoder}/tight_packing_literals_fine.sol (100%) rename test/libsolidity/syntaxTests/{ => comments}/multiline_comments.sol (100%) rename test/libsolidity/syntaxTests/{ => constructor}/constructor_this.sol (100%) rename test/libsolidity/syntaxTests/{ => globalFunctions}/deprecated_functions.sol (100%) rename test/libsolidity/syntaxTests/{ => iceRegressionTests}/cycle_checker_function_type.sol (100%) rename test/libsolidity/syntaxTests/{ => iceRegressionTests}/missing_functions_duplicate_bug.sol (100%) rename test/libsolidity/syntaxTests/{ => isoltestTesting}/stopAfterAnalysisError.sol (100%) rename test/libsolidity/syntaxTests/{ => isoltestTesting}/stopAfterParsingAnalysisErrorNotShowing.sol (100%) rename test/libsolidity/syntaxTests/{ => isoltestTesting}/stopAfterParsingError.sol (100%) rename test/libsolidity/syntaxTests/{ => literalOperations}/literal_comparisons.sol (100%) rename test/libsolidity/syntaxTests/{ => literals}/upper_case_hex_literals.sol (100%) rename test/libsolidity/syntaxTests/{ => operators}/negation.sol (100%) rename test/libsolidity/syntaxTests/{ => operators}/signed_rational_modulus.sol (100%) rename test/libsolidity/syntaxTests/{ => parsing}/unexpected.sol (100%) rename test/libsolidity/syntaxTests/{ => scoping}/double_stateVariable_declaration.sol (100%) rename test/libsolidity/syntaxTests/{ => scoping}/double_variable_declaration.sol (100%) rename test/libsolidity/syntaxTests/{ => scoping}/duplicate_contract.sol (100%) rename test/libsolidity/syntaxTests/{ => scoping}/missing_state_variable.sol (100%) rename test/libsolidity/syntaxTests/{ => sizeLimits}/more_than_256_declarationerrors.sol (100%) rename test/libsolidity/syntaxTests/{ => sizeLimits}/more_than_256_importerrors.sol (100%) rename test/libsolidity/syntaxTests/{ => sizeLimits}/more_than_256_syntaxerrors.sol (100%) rename test/libsolidity/syntaxTests/{ => smoke}/smoke_test.sol (100%) rename test/libsolidity/syntaxTests/{ => structs}/empty_struct.sol (100%) rename test/libsolidity/syntaxTests/{ => super}/unimplemented_super_function.sol (100%) rename test/libsolidity/syntaxTests/{ => super}/unimplemented_super_function_derived.sol (100%) diff --git a/test/libsolidity/semanticTests/byte_array_to_storage_cleanup.sol b/test/libsolidity/semanticTests/cleanup/byte_array_to_storage_cleanup.sol similarity index 100% rename from test/libsolidity/semanticTests/byte_array_to_storage_cleanup.sol rename to test/libsolidity/semanticTests/cleanup/byte_array_to_storage_cleanup.sol diff --git a/test/libsolidity/semanticTests/dirty_calldata_bytes.sol b/test/libsolidity/semanticTests/cleanup/dirty_calldata_bytes.sol similarity index 100% rename from test/libsolidity/semanticTests/dirty_calldata_bytes.sol rename to test/libsolidity/semanticTests/cleanup/dirty_calldata_bytes.sol diff --git a/test/libsolidity/semanticTests/dirty_calldata_dynamic_array.sol b/test/libsolidity/semanticTests/cleanup/dirty_calldata_dynamic_array.sol similarity index 100% rename from test/libsolidity/semanticTests/dirty_calldata_dynamic_array.sol rename to test/libsolidity/semanticTests/cleanup/dirty_calldata_dynamic_array.sol diff --git a/test/libsolidity/semanticTests/state_var_initialization.sol b/test/libsolidity/semanticTests/constructor/state_variable_initialization.sol similarity index 100% rename from test/libsolidity/semanticTests/state_var_initialization.sol rename to test/libsolidity/semanticTests/constructor/state_variable_initialization.sol diff --git a/test/libsolidity/semanticTests/emit_three_identical_events.sol b/test/libsolidity/semanticTests/events/emit_three_identical_events.sol similarity index 100% rename from test/libsolidity/semanticTests/emit_three_identical_events.sol rename to test/libsolidity/semanticTests/events/emit_three_identical_events.sol diff --git a/test/libsolidity/semanticTests/emit_two_identical_events.sol b/test/libsolidity/semanticTests/events/emit_two_identical_events.sol similarity index 100% rename from test/libsolidity/semanticTests/emit_two_identical_events.sol rename to test/libsolidity/semanticTests/events/emit_two_identical_events.sol diff --git a/test/libsolidity/semanticTests/constructor_inheritance_init_order.sol b/test/libsolidity/semanticTests/inheritance/constructor_inheritance_init_order.sol similarity index 100% rename from test/libsolidity/semanticTests/constructor_inheritance_init_order.sol rename to test/libsolidity/semanticTests/inheritance/constructor_inheritance_init_order.sol diff --git a/test/libsolidity/semanticTests/constructor_inheritance_init_order_2.sol b/test/libsolidity/semanticTests/inheritance/constructor_inheritance_init_order_2.sol similarity index 100% rename from test/libsolidity/semanticTests/constructor_inheritance_init_order_2.sol rename to test/libsolidity/semanticTests/inheritance/constructor_inheritance_init_order_2.sol diff --git a/test/libsolidity/semanticTests/constructor_inheritance_init_order_3_legacy.sol b/test/libsolidity/semanticTests/inheritance/constructor_inheritance_init_order_3_legacy.sol similarity index 100% rename from test/libsolidity/semanticTests/constructor_inheritance_init_order_3_legacy.sol rename to test/libsolidity/semanticTests/inheritance/constructor_inheritance_init_order_3_legacy.sol diff --git a/test/libsolidity/semanticTests/constructor_inheritance_init_order_3_viaIR.sol b/test/libsolidity/semanticTests/inheritance/constructor_inheritance_init_order_3_viaIR.sol similarity index 100% rename from test/libsolidity/semanticTests/constructor_inheritance_init_order_3_viaIR.sol rename to test/libsolidity/semanticTests/inheritance/constructor_inheritance_init_order_3_viaIR.sol diff --git a/test/libsolidity/semanticTests/constructor_with_params.sol b/test/libsolidity/semanticTests/inheritance/constructor_with_params.sol similarity index 100% rename from test/libsolidity/semanticTests/constructor_with_params.sol rename to test/libsolidity/semanticTests/inheritance/constructor_with_params.sol diff --git a/test/libsolidity/semanticTests/constructor_with_params_diamond_inheritance.sol b/test/libsolidity/semanticTests/inheritance/constructor_with_params_diamond_inheritance.sol similarity index 100% rename from test/libsolidity/semanticTests/constructor_with_params_diamond_inheritance.sol rename to test/libsolidity/semanticTests/inheritance/constructor_with_params_diamond_inheritance.sol diff --git a/test/libsolidity/semanticTests/constructor_with_params_inheritance.sol b/test/libsolidity/semanticTests/inheritance/constructor_with_params_inheritance.sol similarity index 100% rename from test/libsolidity/semanticTests/constructor_with_params_inheritance.sol rename to test/libsolidity/semanticTests/inheritance/constructor_with_params_inheritance.sol diff --git a/test/libsolidity/semanticTests/constructor_with_params_inheritance_2.sol b/test/libsolidity/semanticTests/inheritance/constructor_with_params_inheritance_2.sol similarity index 100% rename from test/libsolidity/semanticTests/constructor_with_params_inheritance_2.sol rename to test/libsolidity/semanticTests/inheritance/constructor_with_params_inheritance_2.sol diff --git a/test/libsolidity/semanticTests/interface_inheritance_conversions.sol b/test/libsolidity/semanticTests/inheritance/interface_inheritance_conversions.sol similarity index 100% rename from test/libsolidity/semanticTests/interface_inheritance_conversions.sol rename to test/libsolidity/semanticTests/inheritance/interface_inheritance_conversions.sol diff --git a/test/libsolidity/semanticTests/state_variables_init_order.sol b/test/libsolidity/semanticTests/inheritance/state_variables_init_order.sol similarity index 100% rename from test/libsolidity/semanticTests/state_variables_init_order.sol rename to test/libsolidity/semanticTests/inheritance/state_variables_init_order.sol diff --git a/test/libsolidity/semanticTests/state_variables_init_order_2.sol b/test/libsolidity/semanticTests/inheritance/state_variables_init_order_2.sol similarity index 100% rename from test/libsolidity/semanticTests/state_variables_init_order_2.sol rename to test/libsolidity/semanticTests/inheritance/state_variables_init_order_2.sol diff --git a/test/libsolidity/semanticTests/state_variables_init_order_3.sol b/test/libsolidity/semanticTests/inheritance/state_variables_init_order_3.sol similarity index 100% rename from test/libsolidity/semanticTests/state_variables_init_order_3.sol rename to test/libsolidity/semanticTests/inheritance/state_variables_init_order_3.sol diff --git a/test/libsolidity/semanticTests/empty_contract.sol b/test/libsolidity/semanticTests/isoltestTesting/empty_contract.sol similarity index 100% rename from test/libsolidity/semanticTests/empty_contract.sol rename to test/libsolidity/semanticTests/isoltestTesting/empty_contract.sol diff --git a/test/libsolidity/semanticTests/isoltestFormatting.sol b/test/libsolidity/semanticTests/isoltestTesting/isoltestFormatting.sol similarity index 100% rename from test/libsolidity/semanticTests/isoltestFormatting.sol rename to test/libsolidity/semanticTests/isoltestTesting/isoltestFormatting.sol diff --git a/test/libsolidity/semanticTests/unused_store_storage_removal_bug.sol b/test/libsolidity/semanticTests/optimizer/unused_store_storage_removal_bug.sol similarity index 100% rename from test/libsolidity/semanticTests/unused_store_storage_removal_bug.sol rename to test/libsolidity/semanticTests/optimizer/unused_store_storage_removal_bug.sol diff --git a/test/libsolidity/semanticTests/c99_scoping_activation.sol b/test/libsolidity/semanticTests/scoping/c99_scoping_activation.sol similarity index 100% rename from test/libsolidity/semanticTests/c99_scoping_activation.sol rename to test/libsolidity/semanticTests/scoping/c99_scoping_activation.sol diff --git a/test/libsolidity/semanticTests/empty_for_loop.sol b/test/libsolidity/semanticTests/statements/empty_for_loop.sol similarity index 100% rename from test/libsolidity/semanticTests/empty_for_loop.sol rename to test/libsolidity/semanticTests/statements/empty_for_loop.sol diff --git a/test/libsolidity/syntaxTests/tight_packing_literals.sol b/test/libsolidity/syntaxTests/abiEncoder/tight_packing_literals.sol similarity index 100% rename from test/libsolidity/syntaxTests/tight_packing_literals.sol rename to test/libsolidity/syntaxTests/abiEncoder/tight_packing_literals.sol diff --git a/test/libsolidity/syntaxTests/tight_packing_literals_fine.sol b/test/libsolidity/syntaxTests/abiEncoder/tight_packing_literals_fine.sol similarity index 100% rename from test/libsolidity/syntaxTests/tight_packing_literals_fine.sol rename to test/libsolidity/syntaxTests/abiEncoder/tight_packing_literals_fine.sol diff --git a/test/libsolidity/syntaxTests/multiline_comments.sol b/test/libsolidity/syntaxTests/comments/multiline_comments.sol similarity index 100% rename from test/libsolidity/syntaxTests/multiline_comments.sol rename to test/libsolidity/syntaxTests/comments/multiline_comments.sol diff --git a/test/libsolidity/syntaxTests/constructor_this.sol b/test/libsolidity/syntaxTests/constructor/constructor_this.sol similarity index 100% rename from test/libsolidity/syntaxTests/constructor_this.sol rename to test/libsolidity/syntaxTests/constructor/constructor_this.sol diff --git a/test/libsolidity/syntaxTests/deprecated_functions.sol b/test/libsolidity/syntaxTests/globalFunctions/deprecated_functions.sol similarity index 100% rename from test/libsolidity/syntaxTests/deprecated_functions.sol rename to test/libsolidity/syntaxTests/globalFunctions/deprecated_functions.sol diff --git a/test/libsolidity/syntaxTests/cycle_checker_function_type.sol b/test/libsolidity/syntaxTests/iceRegressionTests/cycle_checker_function_type.sol similarity index 100% rename from test/libsolidity/syntaxTests/cycle_checker_function_type.sol rename to test/libsolidity/syntaxTests/iceRegressionTests/cycle_checker_function_type.sol diff --git a/test/libsolidity/syntaxTests/missing_functions_duplicate_bug.sol b/test/libsolidity/syntaxTests/iceRegressionTests/missing_functions_duplicate_bug.sol similarity index 100% rename from test/libsolidity/syntaxTests/missing_functions_duplicate_bug.sol rename to test/libsolidity/syntaxTests/iceRegressionTests/missing_functions_duplicate_bug.sol diff --git a/test/libsolidity/syntaxTests/stopAfterAnalysisError.sol b/test/libsolidity/syntaxTests/isoltestTesting/stopAfterAnalysisError.sol similarity index 100% rename from test/libsolidity/syntaxTests/stopAfterAnalysisError.sol rename to test/libsolidity/syntaxTests/isoltestTesting/stopAfterAnalysisError.sol diff --git a/test/libsolidity/syntaxTests/stopAfterParsingAnalysisErrorNotShowing.sol b/test/libsolidity/syntaxTests/isoltestTesting/stopAfterParsingAnalysisErrorNotShowing.sol similarity index 100% rename from test/libsolidity/syntaxTests/stopAfterParsingAnalysisErrorNotShowing.sol rename to test/libsolidity/syntaxTests/isoltestTesting/stopAfterParsingAnalysisErrorNotShowing.sol diff --git a/test/libsolidity/syntaxTests/stopAfterParsingError.sol b/test/libsolidity/syntaxTests/isoltestTesting/stopAfterParsingError.sol similarity index 100% rename from test/libsolidity/syntaxTests/stopAfterParsingError.sol rename to test/libsolidity/syntaxTests/isoltestTesting/stopAfterParsingError.sol diff --git a/test/libsolidity/syntaxTests/literal_comparisons.sol b/test/libsolidity/syntaxTests/literalOperations/literal_comparisons.sol similarity index 100% rename from test/libsolidity/syntaxTests/literal_comparisons.sol rename to test/libsolidity/syntaxTests/literalOperations/literal_comparisons.sol diff --git a/test/libsolidity/syntaxTests/upper_case_hex_literals.sol b/test/libsolidity/syntaxTests/literals/upper_case_hex_literals.sol similarity index 100% rename from test/libsolidity/syntaxTests/upper_case_hex_literals.sol rename to test/libsolidity/syntaxTests/literals/upper_case_hex_literals.sol diff --git a/test/libsolidity/syntaxTests/negation.sol b/test/libsolidity/syntaxTests/operators/negation.sol similarity index 100% rename from test/libsolidity/syntaxTests/negation.sol rename to test/libsolidity/syntaxTests/operators/negation.sol diff --git a/test/libsolidity/syntaxTests/signed_rational_modulus.sol b/test/libsolidity/syntaxTests/operators/signed_rational_modulus.sol similarity index 100% rename from test/libsolidity/syntaxTests/signed_rational_modulus.sol rename to test/libsolidity/syntaxTests/operators/signed_rational_modulus.sol diff --git a/test/libsolidity/syntaxTests/unexpected.sol b/test/libsolidity/syntaxTests/parsing/unexpected.sol similarity index 100% rename from test/libsolidity/syntaxTests/unexpected.sol rename to test/libsolidity/syntaxTests/parsing/unexpected.sol diff --git a/test/libsolidity/syntaxTests/double_stateVariable_declaration.sol b/test/libsolidity/syntaxTests/scoping/double_stateVariable_declaration.sol similarity index 100% rename from test/libsolidity/syntaxTests/double_stateVariable_declaration.sol rename to test/libsolidity/syntaxTests/scoping/double_stateVariable_declaration.sol diff --git a/test/libsolidity/syntaxTests/double_variable_declaration.sol b/test/libsolidity/syntaxTests/scoping/double_variable_declaration.sol similarity index 100% rename from test/libsolidity/syntaxTests/double_variable_declaration.sol rename to test/libsolidity/syntaxTests/scoping/double_variable_declaration.sol diff --git a/test/libsolidity/syntaxTests/duplicate_contract.sol b/test/libsolidity/syntaxTests/scoping/duplicate_contract.sol similarity index 100% rename from test/libsolidity/syntaxTests/duplicate_contract.sol rename to test/libsolidity/syntaxTests/scoping/duplicate_contract.sol diff --git a/test/libsolidity/syntaxTests/missing_state_variable.sol b/test/libsolidity/syntaxTests/scoping/missing_state_variable.sol similarity index 100% rename from test/libsolidity/syntaxTests/missing_state_variable.sol rename to test/libsolidity/syntaxTests/scoping/missing_state_variable.sol diff --git a/test/libsolidity/syntaxTests/more_than_256_declarationerrors.sol b/test/libsolidity/syntaxTests/sizeLimits/more_than_256_declarationerrors.sol similarity index 100% rename from test/libsolidity/syntaxTests/more_than_256_declarationerrors.sol rename to test/libsolidity/syntaxTests/sizeLimits/more_than_256_declarationerrors.sol diff --git a/test/libsolidity/syntaxTests/more_than_256_importerrors.sol b/test/libsolidity/syntaxTests/sizeLimits/more_than_256_importerrors.sol similarity index 100% rename from test/libsolidity/syntaxTests/more_than_256_importerrors.sol rename to test/libsolidity/syntaxTests/sizeLimits/more_than_256_importerrors.sol diff --git a/test/libsolidity/syntaxTests/more_than_256_syntaxerrors.sol b/test/libsolidity/syntaxTests/sizeLimits/more_than_256_syntaxerrors.sol similarity index 100% rename from test/libsolidity/syntaxTests/more_than_256_syntaxerrors.sol rename to test/libsolidity/syntaxTests/sizeLimits/more_than_256_syntaxerrors.sol diff --git a/test/libsolidity/syntaxTests/smoke_test.sol b/test/libsolidity/syntaxTests/smoke/smoke_test.sol similarity index 100% rename from test/libsolidity/syntaxTests/smoke_test.sol rename to test/libsolidity/syntaxTests/smoke/smoke_test.sol diff --git a/test/libsolidity/syntaxTests/empty_struct.sol b/test/libsolidity/syntaxTests/structs/empty_struct.sol similarity index 100% rename from test/libsolidity/syntaxTests/empty_struct.sol rename to test/libsolidity/syntaxTests/structs/empty_struct.sol diff --git a/test/libsolidity/syntaxTests/unimplemented_super_function.sol b/test/libsolidity/syntaxTests/super/unimplemented_super_function.sol similarity index 100% rename from test/libsolidity/syntaxTests/unimplemented_super_function.sol rename to test/libsolidity/syntaxTests/super/unimplemented_super_function.sol diff --git a/test/libsolidity/syntaxTests/unimplemented_super_function_derived.sol b/test/libsolidity/syntaxTests/super/unimplemented_super_function_derived.sol similarity index 100% rename from test/libsolidity/syntaxTests/unimplemented_super_function_derived.sol rename to test/libsolidity/syntaxTests/super/unimplemented_super_function_derived.sol diff --git a/test/scripts/test_bytecodecompare_prepare_report.py b/test/scripts/test_bytecodecompare_prepare_report.py index 28a89ec315cb..e1987c60c17c 100644 --- a/test/scripts/test_bytecodecompare_prepare_report.py +++ b/test/scripts/test_bytecodecompare_prepare_report.py @@ -24,7 +24,7 @@ SMT_CONTRACT_WITH_MIXED_NEWLINES_SOL_PATH = FIXTURE_DIR / 'smt_contract_with_mixed_newlines.sol' SMT_CONTRACT_WITH_MIXED_NEWLINES_SOL_CODE = load_fixture(SMT_CONTRACT_WITH_MIXED_NEWLINES_SOL_PATH) -SYNTAX_SMOKE_TEST_SOL_PATH = LIBSOLIDITY_TEST_DIR / 'syntaxTests/smoke_test.sol' +SYNTAX_SMOKE_TEST_SOL_PATH = LIBSOLIDITY_TEST_DIR / 'syntaxTests/smoke/smoke_test.sol' SYNTAX_SMOKE_TEST_SOL_CODE = load_libsolidity_test_case(SYNTAX_SMOKE_TEST_SOL_PATH) LIBRARY_INHERITED2_SOL_JSON_OUTPUT = load_fixture('library_inherited2_sol_json_output.json') @@ -58,19 +58,19 @@ def test_format_report(self): contract_reports=[ ContractReport( contract_name='A', - file_name=Path('syntaxTests/smoke_test.sol'), + file_name=Path('syntaxTests/smoke/smoke_test.sol'), bytecode=None, metadata=None, ), ContractReport( contract_name='B', - file_name=Path('syntaxTests/smoke_test.sol'), + file_name=Path('syntaxTests/smoke/smoke_test.sol'), bytecode=None, metadata='{"language":"Solidity"}', ), ContractReport( contract_name='Lib', - file_name=Path('syntaxTests/smoke_test.sol'), + file_name=Path('syntaxTests/smoke/smoke_test.sol'), bytecode='60566050600b828282398051', metadata=None, ), From 640dd41db40cfa43c5d7209e242352ea75774e49 Mon Sep 17 00:00:00 2001 From: XxAlex74xX <30472093+XxAlex74xX@users.noreply.github.com> Date: Mon, 27 Jan 2025 09:37:09 +0100 Subject: [PATCH 0731/1022] Update natspec-format.rst --- docs/natspec-format.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/natspec-format.rst b/docs/natspec-format.rst index f1910648378f..2f0d1d6b40d9 100644 --- a/docs/natspec-format.rst +++ b/docs/natspec-format.rst @@ -209,7 +209,7 @@ JSON file as output for the ``Tree`` contract: "age(uint256)" : { "notice" : "Calculate tree age in years, rounded up, for live trees" - } + }, "leaves()" : { "notice" : "Returns the amount of leaves the tree has." From 57342666ca9b03499d8299b3ff269494647b6787 Mon Sep 17 00:00:00 2001 From: Martin Blicha Date: Fri, 10 Jan 2025 21:20:56 +0100 Subject: [PATCH 0732/1022] SMTChecker: Fix crash in BMC engine regarding state variables Previously, analyzing a call to a getter to a contract then has not been analyzed yet with BMC would result in a crash because BMC would not know about the state variable being accessed. To fix this, we let BMC know about all state variables in all contracts during initialization. --- Changelog.md | 1 + libsolidity/formal/BMC.cpp | 4 +++- libsolidity/formal/SMTEncoder.cpp | 8 +++++++ libsolidity/formal/SMTEncoder.h | 3 +++ .../cross_contract_getter_call.sol | 22 +++++++++++++++++++ 5 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 test/libsolidity/smtCheckerTests/bmc_coverage/cross_contract_getter_call.sol diff --git a/Changelog.md b/Changelog.md index c00adf0fd977..35f9b83bedda 100644 --- a/Changelog.md +++ b/Changelog.md @@ -11,6 +11,7 @@ Compiler Features: Bugfixes: * General: Fix internal compiler error when requesting IR AST outputs for interfaces and abstract contracts. + * SMTChecker: Fix SMT logic error when analyzing cross-contract getter call with BMC. * SMTChecker: Fix SMT logic error when initializing a fixed-sized-bytes array using string literals. * SMTChecker: Fix SMT logic error when translating invariants involving array store and select operations. * SMTChecker: Fix wrong encoding of string literals as arguments of ``ecrecover`` precompile. diff --git a/libsolidity/formal/BMC.cpp b/libsolidity/formal/BMC.cpp index 679309766c36..d7bad10e7b35 100644 --- a/libsolidity/formal/BMC.cpp +++ b/libsolidity/formal/BMC.cpp @@ -93,7 +93,9 @@ void BMC::analyze(SourceUnit const& _source, std::map const& _sources) +{ + for (auto const& source: _sources) + for (auto const& node: source->nodes()) + if (auto contract = dynamic_cast(node.get())) + createStateVariables(*contract); +} + smt::SymbolicState& SMTEncoder::state() { return m_context.state(); diff --git a/libsolidity/formal/SMTEncoder.h b/libsolidity/formal/SMTEncoder.h index 3248f1390f64..f01f6802c337 100644 --- a/libsolidity/formal/SMTEncoder.h +++ b/libsolidity/formal/SMTEncoder.h @@ -439,6 +439,9 @@ class SMTEncoder: public ASTConstVisitor /// Create symbolic variables for the free constants in all @param _sources. void createFreeConstants(std::set const& _sources); + /// Create symbolic variables for all state variables for all contracts in all @param _sources. + void createStateVariables(std::set const& _sources); + /// @returns a note to be added to warnings. std::string extraComment(); diff --git a/test/libsolidity/smtCheckerTests/bmc_coverage/cross_contract_getter_call.sol b/test/libsolidity/smtCheckerTests/bmc_coverage/cross_contract_getter_call.sol new file mode 100644 index 000000000000..f36647ed2b04 --- /dev/null +++ b/test/libsolidity/smtCheckerTests/bmc_coverage/cross_contract_getter_call.sol @@ -0,0 +1,22 @@ +contract C { + D internal d; + constructor() { + d = new D(); + } + function invokeAndCheck() public { + d.set(); + assert(d.n() <= 1); + } +} + +contract D { + uint public n; + function set() external { + n = 1; + } +} +// ==== +// SMTEngine: bmc +// ---- +// Warning 8729: (51-58): Contract deployment is only supported in the trusted mode for external calls with the CHC engine. +// Warning 4661: (112-130): BMC: Assertion violation happens here. From 5d27b0f94ba5d7240aeb2bf8413f6f847afb45a9 Mon Sep 17 00:00:00 2001 From: rodiazet Date: Tue, 7 Jan 2025 16:39:19 +0100 Subject: [PATCH 0733/1022] eof: Assert against legacy identifiers/members availability in EOF context. --- .../codegen/ir/IRGeneratorForStatements.cpp | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/libsolidity/codegen/ir/IRGeneratorForStatements.cpp b/libsolidity/codegen/ir/IRGeneratorForStatements.cpp index 3ae151593d33..c716c43a6070 100644 --- a/libsolidity/codegen/ir/IRGeneratorForStatements.cpp +++ b/libsolidity/codegen/ir/IRGeneratorForStatements.cpp @@ -1529,6 +1529,15 @@ void IRGeneratorForStatements::endVisit(FunctionCall const& _functionCall) case FunctionType::Kind::BlockHash: case FunctionType::Kind::BlobHash: { + solAssert( + !m_context.eofVersion().has_value() || functionType->kind() != FunctionType::Kind::GasLeft, + "EOF does not support gasleft." + ); + solAssert( + !m_context.eofVersion().has_value() || functionType->kind() != FunctionType::Kind::Selfdestruct, + "EOF does not support selfdestruct." + ); + static std::map functions = { {FunctionType::Kind::GasLeft, "gas"}, {FunctionType::Kind::Selfdestruct, "selfdestruct"}, @@ -1845,6 +1854,7 @@ void IRGeneratorForStatements::endVisit(MemberAccess const& _memberAccess) ")\n"; else if (member == "code") { + solAssert(!m_context.eofVersion().has_value(), "EOF does not support address.code."); std::string externalCodeFunction = m_utils.externalCodeFunction(); define(_memberAccess) << externalCodeFunction << @@ -1853,10 +1863,13 @@ void IRGeneratorForStatements::endVisit(MemberAccess const& _memberAccess) ")\n"; } else if (member == "codehash") + { + solAssert(!m_context.eofVersion().has_value(), "EOF does not support address.codehash."); define(_memberAccess) << "extcodehash(" << expressionAsType(_memberAccess.expression(), *TypeProvider::address()) << ")\n"; + } else if (std::set{"send", "transfer"}.count(member)) { solAssert(dynamic_cast(*_memberAccess.expression().annotation().type).stateMutability() == StateMutability::Payable); @@ -1973,6 +1986,7 @@ void IRGeneratorForStatements::endVisit(MemberAccess const& _memberAccess) solAssert(false, "Blockhash has been removed."); else if (member == "creationCode" || member == "runtimeCode") { + solAssert(!m_context.eofVersion().has_value(), "EOF does not support \"" + member + "\"."); Type const* arg = dynamic_cast(*_memberAccess.expression().annotation().type).typeArgument(); auto const& contractType = dynamic_cast(*arg); solAssert(!contractType.isSuper()); From 1832fbd732f387b6e0be72bf96f0bd082acb9515 Mon Sep 17 00:00:00 2001 From: Alexander Arlt Date: Mon, 22 Jul 2024 19:15:14 +0200 Subject: [PATCH 0734/1022] Enable ethdebug debug info and output selection. --- libevmasm/AbstractAssemblyStack.h | 4 + libevmasm/Assembly.cpp | 2 +- libevmasm/EVMAssemblyStack.cpp | 19 + libevmasm/EVMAssemblyStack.h | 6 + liblangutil/DebugInfoSelection.cpp | 12 +- liblangutil/DebugInfoSelection.h | 15 +- libsolidity/codegen/ir/IRGenerator.cpp | 3 +- libsolidity/interface/CompilerStack.cpp | 33 ++ libsolidity/interface/CompilerStack.h | 17 + libsolidity/interface/StandardCompiler.cpp | 88 ++- libyul/YulStack.cpp | 14 +- libyul/YulStack.h | 4 + solc/CommandLineInterface.cpp | 64 +++ solc/CommandLineInterface.h | 2 + solc/CommandLineParser.cpp | 84 ++- solc/CommandLineParser.h | 4 + test/cmdlineTests/ethdebug/args | 1 + test/cmdlineTests/ethdebug/input.sol | 7 + test/cmdlineTests/ethdebug/output | 42 ++ .../ethdebug_and_ethdebug_runtime/args | 1 + .../ethdebug_and_ethdebug_runtime/input.sol | 7 + .../ethdebug_and_ethdebug_runtime/output | 44 ++ test/cmdlineTests/ethdebug_runtime/args | 1 + test/cmdlineTests/ethdebug_runtime/input.sol | 7 + test/cmdlineTests/ethdebug_runtime/output | 42 ++ .../input.json | 24 + .../output.json | 214 ++++++++ .../input.json | 24 + .../output.json | 226 ++++++++ .../input.json | 24 + .../output.json | 214 ++++++++ .../standard_yul_ethdebug_bytecode/args | 1 + .../standard_yul_ethdebug_bytecode/in.yul | 17 + .../standard_yul_ethdebug_bytecode/input.json | 14 + .../output.json | 31 ++ .../args | 1 + .../in.yul | 17 + .../input.json | 11 + .../output.json | 11 + test/cmdlineTests/yul_ethdebug/args | 1 + test/cmdlineTests/yul_ethdebug/input.yul | 18 + test/cmdlineTests/yul_ethdebug/output | 18 + test/cmdlineTests/yul_ethdebug_runtime/args | 1 + test/cmdlineTests/yul_ethdebug_runtime/err | 1 + test/cmdlineTests/yul_ethdebug_runtime/exit | 1 + .../yul_ethdebug_runtime/input.yul | 18 + test/libsolidity/StandardCompiler.cpp | 511 ++++++++++++++++++ test/libyul/Common.cpp | 2 +- test/libyul/EVMCodeTransformTest.cpp | 2 +- test/libyul/ObjectParser.cpp | 2 +- test/solc/CommandLineInterface.cpp | 350 ++++++++++++ test/solc/CommandLineParser.cpp | 43 ++ .../ossfuzz/strictasm_assembly_ossfuzz.cpp | 2 +- test/tools/ossfuzz/strictasm_diff_ossfuzz.cpp | 2 +- test/tools/ossfuzz/strictasm_opt_ossfuzz.cpp | 2 +- 55 files changed, 2308 insertions(+), 18 deletions(-) create mode 100644 test/cmdlineTests/ethdebug/args create mode 100644 test/cmdlineTests/ethdebug/input.sol create mode 100644 test/cmdlineTests/ethdebug/output create mode 100644 test/cmdlineTests/ethdebug_and_ethdebug_runtime/args create mode 100644 test/cmdlineTests/ethdebug_and_ethdebug_runtime/input.sol create mode 100644 test/cmdlineTests/ethdebug_and_ethdebug_runtime/output create mode 100644 test/cmdlineTests/ethdebug_runtime/args create mode 100644 test/cmdlineTests/ethdebug_runtime/input.sol create mode 100644 test/cmdlineTests/ethdebug_runtime/output create mode 100644 test/cmdlineTests/standard_output_selection_ethdebug_bytecode/input.json create mode 100644 test/cmdlineTests/standard_output_selection_ethdebug_bytecode/output.json create mode 100644 test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode/input.json create mode 100644 test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode/output.json create mode 100644 test/cmdlineTests/standard_output_selection_ethdebug_deployedbytecode/input.json create mode 100644 test/cmdlineTests/standard_output_selection_ethdebug_deployedbytecode/output.json create mode 100644 test/cmdlineTests/standard_yul_ethdebug_bytecode/args create mode 100644 test/cmdlineTests/standard_yul_ethdebug_bytecode/in.yul create mode 100644 test/cmdlineTests/standard_yul_ethdebug_bytecode/input.json create mode 100644 test/cmdlineTests/standard_yul_ethdebug_bytecode/output.json create mode 100644 test/cmdlineTests/standard_yul_ethdebug_deployed_bytecode/args create mode 100644 test/cmdlineTests/standard_yul_ethdebug_deployed_bytecode/in.yul create mode 100644 test/cmdlineTests/standard_yul_ethdebug_deployed_bytecode/input.json create mode 100644 test/cmdlineTests/standard_yul_ethdebug_deployed_bytecode/output.json create mode 100644 test/cmdlineTests/yul_ethdebug/args create mode 100644 test/cmdlineTests/yul_ethdebug/input.yul create mode 100644 test/cmdlineTests/yul_ethdebug/output create mode 100644 test/cmdlineTests/yul_ethdebug_runtime/args create mode 100644 test/cmdlineTests/yul_ethdebug_runtime/err create mode 100644 test/cmdlineTests/yul_ethdebug_runtime/exit create mode 100644 test/cmdlineTests/yul_ethdebug_runtime/input.yul diff --git a/libevmasm/AbstractAssemblyStack.h b/libevmasm/AbstractAssemblyStack.h index 278edf5c273b..c4eb804eea41 100644 --- a/libevmasm/AbstractAssemblyStack.h +++ b/libevmasm/AbstractAssemblyStack.h @@ -40,6 +40,10 @@ class AbstractAssemblyStack virtual std::string const* sourceMapping(std::string const& _contractName) const = 0; virtual std::string const* runtimeSourceMapping(std::string const& _contractName) const = 0; + virtual Json ethdebug(std::string const& _contractName) const = 0; + virtual Json ethdebugRuntime(std::string const& _contractName) const = 0; + virtual Json ethdebug() const = 0; + virtual Json assemblyJSON(std::string const& _contractName) const = 0; virtual std::string assemblyString(std::string const& _contractName, StringMap const& _sourceCodes) const = 0; diff --git a/libevmasm/Assembly.cpp b/libevmasm/Assembly.cpp index 22bff5415333..ac9f14b15498 100644 --- a/libevmasm/Assembly.cpp +++ b/libevmasm/Assembly.cpp @@ -444,7 +444,7 @@ std::string Assembly::assemblyString( { std::ostringstream tmp; assemblyStream(tmp, _debugInfoSelection, "", _sourceCodes); - return tmp.str(); + return (_debugInfoSelection.ethdebug ? "/// ethdebug: enabled\n" : "") + tmp.str(); } Json Assembly::assemblyJSON(std::map const& _sourceIndices, bool _includeSourceList) const diff --git a/libevmasm/EVMAssemblyStack.cpp b/libevmasm/EVMAssemblyStack.cpp index df4517fc522b..f8b8b4b54d0e 100644 --- a/libevmasm/EVMAssemblyStack.cpp +++ b/libevmasm/EVMAssemblyStack.cpp @@ -103,6 +103,25 @@ std::string const* EVMAssemblyStack::runtimeSourceMapping(std::string const& _co return &m_runtimeSourceMapping; } +Json EVMAssemblyStack::ethdebug(std::string const& _contractName) const +{ + solAssert(_contractName == m_name); + solAssert(m_ethdebug != nullptr); + return *m_ethdebug; +} + +Json EVMAssemblyStack::ethdebugRuntime(std::string const& _contractName) const +{ + solAssert(_contractName == m_name); + solAssert(m_ethdebugRuntime != nullptr); + return *m_ethdebugRuntime; +} + +Json EVMAssemblyStack::ethdebug() const +{ + return {}; +} + Json EVMAssemblyStack::assemblyJSON(std::string const& _contractName) const { solAssert(_contractName == m_name); diff --git a/libevmasm/EVMAssemblyStack.h b/libevmasm/EVMAssemblyStack.h index 55c9fd684ecc..e3888afadc3e 100644 --- a/libevmasm/EVMAssemblyStack.h +++ b/libevmasm/EVMAssemblyStack.h @@ -59,6 +59,10 @@ class EVMAssemblyStack: public AbstractAssemblyStack std::string const* sourceMapping(std::string const& _contractName) const override; std::string const* runtimeSourceMapping(std::string const& _contractName) const override; + Json ethdebug(std::string const& _contractName) const override; + Json ethdebugRuntime(std::string const& _contractName) const override; + Json ethdebug() const override; + Json assemblyJSON(std::string const& _contractName) const override; std::string assemblyString(std::string const& _contractName, StringMap const& _sourceCodes) const override; @@ -87,6 +91,8 @@ class EVMAssemblyStack: public AbstractAssemblyStack langutil::DebugInfoSelection m_debugInfoSelection = langutil::DebugInfoSelection::Default(); std::string m_sourceMapping; std::string m_runtimeSourceMapping; + std::unique_ptr m_ethdebug; + std::unique_ptr m_ethdebugRuntime; }; } // namespace solidity::evmasm diff --git a/liblangutil/DebugInfoSelection.cpp b/liblangutil/DebugInfoSelection.cpp index ad0b615c1c1e..dfd623646e3a 100644 --- a/liblangutil/DebugInfoSelection.cpp +++ b/liblangutil/DebugInfoSelection.cpp @@ -49,6 +49,14 @@ DebugInfoSelection const DebugInfoSelection::Only(bool DebugInfoSelection::* _me return result; } +DebugInfoSelection const DebugInfoSelection::AllExcept(std::vector const& _members) noexcept +{ + DebugInfoSelection result = All(); + for (bool DebugInfoSelection::* member: _members) + result.*member = false; + return result; +} + std::optional DebugInfoSelection::fromString(std::string_view _input) { // TODO: Make more stuff constexpr and make it a static_assert(). @@ -56,7 +64,7 @@ std::optional DebugInfoSelection::fromString(std::string_vie solAssert(componentMap().count("none") == 0, ""); if (_input == "all") - return All(); + return AllExceptExperimental(); if (_input == "none") return None(); @@ -74,7 +82,7 @@ std::optional DebugInfoSelection::fromComponents( for (auto const& component: _componentNames) { if (component == "*") - return (_acceptWildcards ? std::make_optional(DebugInfoSelection::All()) : std::nullopt); + return (_acceptWildcards ? std::make_optional(AllExceptExperimental()) : std::nullopt); if (!selection.enable(component)) return std::nullopt; diff --git a/liblangutil/DebugInfoSelection.h b/liblangutil/DebugInfoSelection.h index 3a9432de6d02..daf4b950f2e9 100644 --- a/liblangutil/DebugInfoSelection.h +++ b/liblangutil/DebugInfoSelection.h @@ -42,7 +42,9 @@ struct DebugInfoSelection static DebugInfoSelection const All(bool _value = true) noexcept; static DebugInfoSelection const None() noexcept { return All(false); } static DebugInfoSelection const Only(bool DebugInfoSelection::* _member) noexcept; - static DebugInfoSelection const Default() noexcept { return All(); } + static DebugInfoSelection const Default() noexcept { return AllExceptExperimental(); } + static DebugInfoSelection const AllExcept(std::vector const& _members) noexcept; + static DebugInfoSelection const AllExceptExperimental() noexcept { return AllExcept({&DebugInfoSelection::ethdebug}); } static std::optional fromString(std::string_view _input); static std::optional fromComponents( @@ -72,13 +74,24 @@ struct DebugInfoSelection {"location", &DebugInfoSelection::location}, {"snippet", &DebugInfoSelection::snippet}, {"ast-id", &DebugInfoSelection::astID}, + {"ethdebug", &DebugInfoSelection::ethdebug}, }; return components; } + std::vector selectedNames() const + { + std::vector result; + for (auto const& component: componentMap()) + if (this->*(component.second)) + result.push_back(component.first); + return result; + } + bool location = false; ///< Include source location. E.g. `@src 3:50:100` bool snippet = false; ///< Include source code snippet next to location. E.g. `@src 3:50:100 "contract C {..."` bool astID = false; ///< Include ID of the Solidity AST node. E.g. `@ast-id 15` + bool ethdebug = false; ///< Include ethdebug related debug information. }; std::ostream& operator<<(std::ostream& _stream, DebugInfoSelection const& _selection); diff --git a/libsolidity/codegen/ir/IRGenerator.cpp b/libsolidity/codegen/ir/IRGenerator.cpp index ae2a12c71c32..dd6503ca1fbf 100644 --- a/libsolidity/codegen/ir/IRGenerator.cpp +++ b/libsolidity/codegen/ir/IRGenerator.cpp @@ -120,7 +120,7 @@ std::string IRGenerator::generate( ); }; - Whiskers t(R"( + Whiskers t(R"(/// ethdebug: enabled /// @use-src object "" { code { @@ -164,6 +164,7 @@ std::string IRGenerator::generate( for (VariableDeclaration const* var: ContractType(_contract).immutableVariables()) m_context.registerImmutableVariable(*var); + t("isEthdebugEnabled", m_context.debugInfoSelection().ethdebug); t("CreationObject", IRNames::creationObject(_contract)); t("sourceLocationCommentCreation", dispenseLocationComment(_contract)); t("library", _contract.isLibrary()); diff --git a/libsolidity/interface/CompilerStack.cpp b/libsolidity/interface/CompilerStack.cpp index 2a859ea24517..1791ad45a9d5 100644 --- a/libsolidity/interface/CompilerStack.cpp +++ b/libsolidity/interface/CompilerStack.cpp @@ -1181,6 +1181,39 @@ Json CompilerStack::interfaceSymbols(std::string const& _contractName) const return interfaceSymbols; } +Json CompilerStack::ethdebug() const +{ + solAssert(m_stackState >= AnalysisSuccessful, "Analysis was not successful."); + solAssert(!m_contracts.empty()); + Json result = Json::object(); + result["sources"] = sourceNames(); + return result; +} + +Json CompilerStack::ethdebug(std::string const& _contractName) const +{ + return ethdebug(contract(_contractName), /* runtime */ false); +} + +Json CompilerStack::ethdebugRuntime(std::string const& _contractName) const +{ + return ethdebug(contract(_contractName), /* runtime */ true); +} + +Json CompilerStack::ethdebug(Contract const& _contract, bool _runtime) const +{ + solAssert(m_stackState >= AnalysisSuccessful, "Analysis was not successful."); + solAssert(_contract.contract); + solUnimplementedAssert(!isExperimentalSolidity()); + if (_runtime) + { + Json result = Json::object(); + return result; + } + Json result = Json::object(); + return result; +} + bytes CompilerStack::cborMetadata(std::string const& _contractName, bool _forIR) const { solAssert(m_stackState >= AnalysisSuccessful, "Analysis was not successful."); diff --git a/libsolidity/interface/CompilerStack.h b/libsolidity/interface/CompilerStack.h index f36eedde0611..2731787a4b88 100644 --- a/libsolidity/interface/CompilerStack.h +++ b/libsolidity/interface/CompilerStack.h @@ -391,6 +391,18 @@ class CompilerStack: public langutil::CharStreamProvider, public evmasm::Abstrac /// @returns a JSON object with the three members ``methods``, ``events``, ``errors``. Each is a map, mapping identifiers (hashes) to function names. Json interfaceSymbols(std::string const& _contractName) const; + /// @returns a JSON representing the ethdebug data of the specified contract. + /// Prerequisite: Successful call to parse or compile. + Json ethdebug(std::string const& _contractName) const override; + + /// @returns a JSON representing the ethdebug data of the specified contract. + /// Prerequisite: Successful call to parse or compile. + Json ethdebugRuntime(std::string const& _contractName) const override; + + /// @returns a JSON representing the top-level ethdebug data (types, etc.). + /// Prerequisite: Successful call to parse or compile. + Json ethdebug() const override; + /// @returns the Contract Metadata matching the pipeline selected using the viaIR setting. std::string const& metadata(std::string const& _contractName) const { return metadata(contract(_contractName)); } @@ -571,6 +583,11 @@ class CompilerStack: public langutil::CharStreamProvider, public evmasm::Abstrac /// This will generate the metadata and store it in the Contract object if it is not present yet. std::string const& metadata(Contract const& _contract) const; + /// @returns the Contract ethdebug data. + /// This will generate the JSON object and store it in the Contract object if it is not present yet. + /// Prerequisite: Successful call to parse or compile. + Json ethdebug(Contract const& _contract, bool _runtime) const; + /// @returns the offset of the entry point of the given function into the list of assembly items /// or zero if it is not found or does not exist. size_t functionEntryPoint( diff --git a/libsolidity/interface/StandardCompiler.cpp b/libsolidity/interface/StandardCompiler.cpp index 9357310c07e4..bcdb2901d053 100644 --- a/libsolidity/interface/StandardCompiler.cpp +++ b/libsolidity/interface/StandardCompiler.cpp @@ -165,7 +165,7 @@ bool hashMatchesContent(std::string const& _hash, std::string const& _content) bool isArtifactRequested(Json const& _outputSelection, std::string const& _artifact, bool _wildcardMatchesExperimental) { - static std::set experimental{"ir", "irAst", "irOptimized", "irOptimizedAst", "yulCFGJson"}; + static std::set experimental{"ir", "irAst", "irOptimized", "irOptimizedAst", "yulCFGJson", "ethdebug"}; for (auto const& selectedArtifactJson: _outputSelection) { std::string const& selectedArtifact = selectedArtifactJson.get(); @@ -173,12 +173,20 @@ bool isArtifactRequested(Json const& _outputSelection, std::string const& _artif _artifact == selectedArtifact || boost::algorithm::starts_with(_artifact, selectedArtifact + ".") ) + { + if (_artifact.find("ethdebug") != std::string::npos) + // only accept exact matches for ethdebug, e.g. evm.bytecode.ethdebug + return selectedArtifact == _artifact; return true; + } else if (selectedArtifact == "*") { // TODO: yulCFGJson is only experimental now, so it should not be matched by "*". if (_artifact == "yulCFGJson") return false; + // TODO: everything ethdebug related is only experimental for now, so it should not be matched by "*". + if (_artifact.find("ethdebug") != std::string::npos) + return false; // "ir", "irOptimized" can only be matched by "*" if activated. if (experimental.count(_artifact) == 0 || _wildcardMatchesExperimental) return true; @@ -237,7 +245,7 @@ bool isArtifactRequested(Json const& _outputSelection, std::string const& _file, std::vector evmObjectComponents(std::string const& _objectKind) { solAssert(_objectKind == "bytecode" || _objectKind == "deployedBytecode", ""); - std::vector components{"", ".object", ".opcodes", ".sourceMap", ".functionDebugData", ".generatedSources", ".linkReferences"}; + std::vector components{"", ".object", ".opcodes", ".sourceMap", ".functionDebugData", ".generatedSources", ".linkReferences", ".ethdebug"}; if (_objectKind == "deployedBytecode") components.push_back(".immutableReferences"); return util::applyMap(components, [&](auto const& _s) { return "evm." + _objectKind + _s; }); @@ -253,7 +261,7 @@ bool isBinaryRequested(Json const& _outputSelection) static std::vector const outputsThatRequireBinaries = std::vector{ "*", "ir", "irAst", "irOptimized", "irOptimizedAst", "yulCFGJson", - "evm.gasEstimates", "evm.legacyAssembly", "evm.assembly" + "evm.gasEstimates", "evm.legacyAssembly", "evm.assembly", "ethdebug" } + evmObjectComponents("bytecode") + evmObjectComponents("deployedBytecode"); for (auto const& fileRequests: _outputSelection) @@ -283,6 +291,21 @@ bool isEvmBytecodeRequested(Json const& _outputSelection) return false; } +/// @returns true if ethdebug was requested. +bool isEthdebugRequested(Json const& _outputSelection) +{ + if (!_outputSelection.is_object()) + return false; + + for (auto const& fileRequests: _outputSelection) + for (auto const& requests: fileRequests) + for (auto const& request: requests) + if (request == "evm.bytecode.ethdebug" || request == "evm.deployedBytecode.ethdebug") + return true; + + return false; +} + /// @returns The set of selected contracts, along with their compiler pipeline configuration, based /// on outputs requested in the JSON. Translates wildcards to the ones understood by CompilerStack. /// Note that as an exception, '*' does not yet match "ir", "irAst", "irOptimized" or "irOptimizedAst". @@ -1152,6 +1175,35 @@ std::variant StandardCompiler::parseI ret.modelCheckerSettings.timeout = modelCheckerSettings["timeout"].get(); } + if ((ret.debugInfoSelection.has_value() && ret.debugInfoSelection->ethdebug) || isEthdebugRequested(ret.outputSelection)) + { + if (ret.language != "Solidity" && ret.language != "Yul") + return formatFatalError(Error::Type::FatalError, "'settings.debug.debugInfo' 'ethdebug' is only supported for languages 'Solidity' and 'Yul'."); + } + + if (isEthdebugRequested(ret.outputSelection)) + { + if (ret.language == "Solidity" && !ret.viaIR) + return formatFatalError(Error::Type::FatalError, "'evm.bytecode.ethdebug' or 'evm.deployedBytecode.ethdebug' can only be selected as output, if 'viaIR' was set."); + + if (!ret.debugInfoSelection.has_value()) + { + ret.debugInfoSelection = DebugInfoSelection::Default(); + ret.debugInfoSelection->enable("ethdebug"); + } + else + { + if (!ret.debugInfoSelection->ethdebug && ret.language == "Solidity") + return formatFatalError(Error::Type::FatalError, "'ethdebug' needs to be enabled in 'settings.debug.debugInfo', if 'evm.bytecode.ethdebug' or 'evm.deployedBytecode.ethdebug' was selected as output."); + } + } + + if ( + ret.debugInfoSelection.has_value() && ret.debugInfoSelection->ethdebug && ret.language == "Solidity" && + !pipelineConfig(ret.outputSelection)[""][""].irCodegen && !isEthdebugRequested(ret.outputSelection) + ) + return formatFatalError(Error::Type::FatalError, "'settings.debug.debugInfo' can only include 'ethdebug', if output 'ir', 'irOptimized', 'evm.bytecode.ethdebug', or 'evm.deployedBytecode.ethdebug' was selected."); + return {std::move(ret)}; } @@ -1235,6 +1287,8 @@ Json StandardCompiler::importEVMAssembly(StandardCompiler::InputsAndSettings _in creationJSON["functionDebugData"] = formatFunctionDebugData(stack.object(sourceName).functionDebugData); if (evmCreationArtifactRequested("linkReferences")) creationJSON["linkReferences"] = formatLinkReferences(stack.object(sourceName).linkReferences); + if (evmCreationArtifactRequested("ethdebug")) + creationJSON["ethdebug"] = stack.ethdebug(sourceName); evmData["bytecode"] = creationJSON; } @@ -1263,6 +1317,8 @@ Json StandardCompiler::importEVMAssembly(StandardCompiler::InputsAndSettings _in deployedJSON["linkReferences"] = formatLinkReferences(stack.runtimeObject(sourceName).linkReferences); if (evmDeployedArtifactRequested("immutableReferences")) deployedJSON["immutableReferences"] = formatImmutableReferences(stack.runtimeObject(sourceName).immutableReferences); + if (evmDeployedArtifactRequested("ethdebug")) + deployedJSON["ethdebug"] = stack.ethdebugRuntime(sourceName); evmData["deployedBytecode"] = deployedJSON; } @@ -1503,6 +1559,8 @@ Json StandardCompiler::compileSolidity(StandardCompiler::InputsAndSettings _inpu creationJSON["linkReferences"] = formatLinkReferences(compilerStack.object(contractName).linkReferences); if (evmCreationArtifactRequested("generatedSources")) creationJSON["generatedSources"] = compilerStack.generatedSources(contractName, /* _runtime */ false); + if (evmCreationArtifactRequested("ethdebug")) + creationJSON["ethdebug"] = compilerStack.ethdebug(contractName); evmData["bytecode"] = creationJSON; } @@ -1533,6 +1591,8 @@ Json StandardCompiler::compileSolidity(StandardCompiler::InputsAndSettings _inpu deployedJSON["immutableReferences"] = formatImmutableReferences(compilerStack.runtimeObject(contractName).immutableReferences); if (evmDeployedArtifactRequested("generatedSources")) deployedJSON["generatedSources"] = compilerStack.generatedSources(contractName, /* _runtime */ true); + if (evmDeployedArtifactRequested("ethdebug")) + deployedJSON["ethdebug"] = compilerStack.ethdebugRuntime(contractName); evmData["deployedBytecode"] = deployedJSON; } @@ -1546,6 +1606,10 @@ Json StandardCompiler::compileSolidity(StandardCompiler::InputsAndSettings _inpu contractsOutput[file][name] = contractData; } } + + if (isEthdebugRequested(_inputsAndSettings.outputSelection)) + output["ethdebug"] = compilerStack.ethdebug(); + if (!contractsOutput.empty()) output["contracts"] = contractsOutput; @@ -1597,6 +1661,19 @@ Json StandardCompiler::compileYul(InputsAndSettings _inputsAndSettings) return output; } + for (auto const& fileRequests: _inputsAndSettings.outputSelection) + for (auto const& requests: fileRequests) + for (auto const& request: requests) + if (request == "evm.deployedBytecode.ethdebug") + { + output["errors"].emplace_back(formatError( + Error::Type::JSONError, + "general", + "\"evm.deployedBytecode.ethdebug\" cannot be used for Yul." + )); + return output; + } + YulStack stack( _inputsAndSettings.evmVersion, _inputsAndSettings.eofVersion, @@ -1687,6 +1764,8 @@ Json StandardCompiler::compileYul(InputsAndSettings _inputsAndSettings) bytecodeJSON["functionDebugData"] = formatFunctionDebugData(selectedObject.bytecode->functionDebugData); if (evmArtifactRequested(kind, "linkReferences")) bytecodeJSON["linkReferences"] = formatLinkReferences(selectedObject.bytecode->linkReferences); + if (evmArtifactRequested(kind, "ethdebug")) + bytecodeJSON["ethdebug"] = selectedObject.ethdebug; if (isDeployed && evmArtifactRequested(kind, "immutableReferences")) bytecodeJSON["immutableReferences"] = formatImmutableReferences(selectedObject.bytecode->immutableReferences); output["contracts"][sourceName][contractName]["evm"][kind] = bytecodeJSON; @@ -1700,6 +1779,9 @@ Json StandardCompiler::compileYul(InputsAndSettings _inputsAndSettings) if (isArtifactRequested(_inputsAndSettings.outputSelection, sourceName, contractName, "yulCFGJson", wildcardMatchesExperimental)) output["contracts"][sourceName][contractName]["yulCFGJson"] = stack.cfgJson(); + if (isEthdebugRequested(_inputsAndSettings.outputSelection)) + output["ethdebug"] = stack.ethdebug(); + return output; } diff --git a/libyul/YulStack.cpp b/libyul/YulStack.cpp index aa8a328204d2..f58705e9cb9d 100644 --- a/libyul/YulStack.cpp +++ b/libyul/YulStack.cpp @@ -273,6 +273,7 @@ YulStack::assembleWithDeployed(std::optional _deployName) {{m_charStream->name(), 0}} ); } + creationObject.ethdebug["not yet implemented @ MachineAssemblyObject::ethdebug"] = true; if (deployedAssembly) { @@ -368,7 +369,7 @@ std::string YulStack::print() const yulAssert(m_stackState >= Parsed); yulAssert(m_parserResult, ""); yulAssert(m_parserResult->hasCode(), ""); - return m_parserResult->toString( + return (m_debugInfoSelection.ethdebug ? "/// ethdebug: enabled\n" : "") + m_parserResult->toString( m_debugInfoSelection, m_soliditySourceProvider ) + "\n"; @@ -382,6 +383,17 @@ Json YulStack::astJson() const return m_parserResult->toJson(); } +Json YulStack::ethdebug() const +{ + yulAssert(m_parserResult, ""); + yulAssert(m_parserResult->hasCode(), ""); + yulAssert(m_parserResult->analysisInfo, ""); + + Json result = Json::object(); + result["sources"] = Json::array({m_charStream->name()}); + return result; +} + Json YulStack::cfgJson() const { yulAssert(m_parserResult, ""); diff --git a/libyul/YulStack.h b/libyul/YulStack.h index 94688fddcaaf..b745f1b80538 100644 --- a/libyul/YulStack.h +++ b/libyul/YulStack.h @@ -60,6 +60,7 @@ struct MachineAssemblyObject std::shared_ptr bytecode; std::shared_ptr assembly; std::unique_ptr sourceMappings; + Json ethdebug = Json::object(); }; /* @@ -148,6 +149,9 @@ class YulStack: public langutil::CharStreamProvider // return the JSON representation of the YuL CFG (experimental) Json cfgJson() const; + /// @returns a JSON representing the top-level ethdebug data (types, etc.). + Json ethdebug() const; + /// Return the parsed and analyzed object. std::shared_ptr parserResult() const; diff --git a/solc/CommandLineInterface.cpp b/solc/CommandLineInterface.cpp index f2bb4af107bb..d97e56638947 100644 --- a/solc/CommandLineInterface.cpp +++ b/solc/CommandLineInterface.cpp @@ -151,6 +151,8 @@ static bool needsHumanTargetedStdout(CommandLineOptions const& _options) _options.compiler.outputs.yulCFGJson || _options.compiler.outputs.binary || _options.compiler.outputs.binaryRuntime || + _options.compiler.outputs.ethdebug || + _options.compiler.outputs.ethdebugRuntime || _options.compiler.outputs.metadata || _options.compiler.outputs.natspecUser || _options.compiler.outputs.natspecDev || @@ -551,6 +553,44 @@ void CommandLineInterface::handleGasEstimation(std::string const& _contract) } } +void CommandLineInterface::handleEthdebug() +{ + if (m_options.compiler.outputs.ethdebug || m_options.compiler.outputs.ethdebugRuntime) + { + std::string ethdebug{jsonPrint(removeNullMembers(m_compiler->ethdebug()), m_options.formatting.json)}; + if (!m_options.output.dir.empty()) + createFile("ethdebug.json", ethdebug); + else + sout() << "======= Debug Data (ethdebug/format/info/resources) =======" << std::endl << ethdebug << std::endl; + } +} + +void CommandLineInterface::handleEthdebug(std::string const& _contract) +{ + solAssert(CompilerInputModes.count(m_options.input.mode) == 1); + + if (!(m_options.compiler.outputs.ethdebug || m_options.compiler.outputs.ethdebugRuntime)) + return; + + if (m_options.compiler.outputs.ethdebug) + { + std::string ethdebug{jsonPrint(removeNullMembers(m_compiler->ethdebug(_contract)), m_options.formatting.json)}; + if (!m_options.output.dir.empty()) + createFile(m_compiler->filesystemFriendlyName(_contract) + "_ethdebug.json", ethdebug); + else + sout() << "Debug Data (ethdebug/format/program):" << std::endl << ethdebug << std::endl; + } + + if (m_options.compiler.outputs.ethdebugRuntime) + { + std::string ethdebugRuntime{jsonPrint(removeNullMembers(m_compiler->ethdebugRuntime(_contract)), m_options.formatting.json)}; + if (!m_options.output.dir.empty()) + createFile(m_compiler->filesystemFriendlyName(_contract) + "_ethdebug-runtime.json", ethdebugRuntime); + else + sout() << "Debug Data of the runtime part (ethdebug/format/program):" << std::endl << ethdebugRuntime << std::endl; + } +} + void CommandLineInterface::readInputFiles() { solAssert(!m_standardJsonInput.has_value()); @@ -912,6 +952,8 @@ void CommandLineInterface::compile() m_options.compiler.outputs.opcodes || m_options.compiler.outputs.binary || m_options.compiler.outputs.binaryRuntime || + m_options.compiler.outputs.ethdebug || + m_options.compiler.outputs.ethdebugRuntime || (m_options.compiler.combinedJsonRequests && ( m_options.compiler.combinedJsonRequests->binary || m_options.compiler.combinedJsonRequests->binaryRuntime || @@ -1290,6 +1332,17 @@ void CommandLineInterface::assembleYul(yul::YulStack::Language _language, yul::Y solThrow(CommandLineExecutionError, ""); } + if (m_options.compiler.outputs.ethdebug) + { + Json ethdebugObject = Json::object(); + ethdebugObject["sources"] = m_fileReader.sourceUnits() | ranges::views::keys; + sout() << "======= Debug Data (ethdebug/format/info/resources) =======" << std::endl; + sout() << util::jsonPrint( + ethdebugObject, + m_options.formatting.json + ) << std::endl; + } + for (auto const& [sourceUnitName, yulSource]: m_fileReader.sourceUnits()) { solAssert(_targetMachine == yul::YulStack::Machine::EVM); @@ -1345,6 +1398,14 @@ void CommandLineInterface::assembleYul(yul::YulStack::Language _language, yul::Y m_options.formatting.json ) << std::endl; } + if (m_options.compiler.outputs.ethdebug) + { + sout() << std::endl << "Debug Data (ethdebug/format/program):" << std::endl; + sout() << util::jsonPrint( + object.ethdebug, + m_options.formatting.json + ) << std::endl; + } } } @@ -1357,6 +1418,8 @@ void CommandLineInterface::outputCompilationResults() // do we need AST output? handleAst(); + handleEthdebug(); + CompilerOutputs astOutputSelection; astOutputSelection.astCompactJson = true; if (m_options.compiler.outputs != CompilerOutputs() && m_options.compiler.outputs != astOutputSelection) @@ -1388,6 +1451,7 @@ void CommandLineInterface::outputCompilationResults() handleTransientStorageLayout(contract); handleNatspec(true, contract); handleNatspec(false, contract); + handleEthdebug(contract); } // end of contracts iteration } diff --git a/solc/CommandLineInterface.h b/solc/CommandLineInterface.h index ce30a4d71db7..b8a10c372db2 100644 --- a/solc/CommandLineInterface.h +++ b/solc/CommandLineInterface.h @@ -101,6 +101,7 @@ class CommandLineInterface void handleCombinedJSON(); void handleAst(); + void handleEthdebug(); void handleEVMAssembly(std::string const& _contract); void handleBinary(std::string const& _contract); void handleOpcode(std::string const& _contract); @@ -117,6 +118,7 @@ class CommandLineInterface void handleGasEstimation(std::string const& _contract); void handleStorageLayout(std::string const& _contract); void handleTransientStorageLayout(std::string const& _contract); + void handleEthdebug(std::string const& _contract); /// Tries to read @ m_sourceCodes as a JSONs holding ASTs /// such that they can be imported into the compiler (importASTs()) diff --git a/solc/CommandLineParser.cpp b/solc/CommandLineParser.cpp index 5929144049a2..f62abb3c6043 100644 --- a/solc/CommandLineParser.cpp +++ b/solc/CommandLineParser.cpp @@ -474,6 +474,7 @@ void CommandLineParser::parseOutputSelection() CompilerOutputs::componentName(&CompilerOutputs::astCompactJson), CompilerOutputs::componentName(&CompilerOutputs::asmJson), CompilerOutputs::componentName(&CompilerOutputs::yulCFGJson), + CompilerOutputs::componentName(&CompilerOutputs::ethdebug), }; static std::set const evmAssemblyJsonImportModeOutputs = { CompilerOutputs::componentName(&CompilerOutputs::asm_), @@ -651,7 +652,7 @@ General Information)").c_str(), po::value()->default_value(util::toString(DebugInfoSelection::Default())), ("Debug info components to be included in the produced EVM assembly and Yul code. " "Value can be all, none or a comma-separated list containing one or more of the " - "following components: " + util::joinHumanReadable(DebugInfoSelection::componentMap() | ranges::views::keys) + ".").c_str() + "following components: " + util::joinHumanReadable(DebugInfoSelection::Default().selectedNames()) + ".").c_str() ) ( g_strStopAfter.c_str(), @@ -773,9 +774,23 @@ General Information)").c_str(), (CompilerOutputs::componentName(&CompilerOutputs::transientStorageLayout).c_str(), "Slots, offsets and types of the contract's state variables located in transient storage.") ; if (!_forHelp) // Note: We intentionally keep this undocumented for now. + { outputComponents.add_options() - (CompilerOutputs::componentName(&CompilerOutputs::yulCFGJson).c_str(), "Control Flow Graph (CFG) of Yul code in JSON format.") - ; + ( + CompilerOutputs::componentName(&CompilerOutputs::yulCFGJson).c_str(), + "Control Flow Graph (CFG) of Yul code in JSON format." + ); + outputComponents.add_options() + ( + CompilerOutputs::componentName(&CompilerOutputs::ethdebug).c_str(), + "Ethdebug output of all contracts." + ); + outputComponents.add_options() + ( + CompilerOutputs::componentName(&CompilerOutputs::ethdebugRuntime).c_str(), + "Ethdebug output of the runtime part of all contracts." + ); + } desc.add(outputComponents); po::options_description extraOutput("Extra Output"); @@ -1321,6 +1336,14 @@ void CommandLineParser::processArgs() CommandLineValidationError, "Optimizer can only be used for strict assembly. Use --" + g_strStrictAssembly + "." ); + + if (m_options.compiler.outputs.ethdebug || m_options.compiler.outputs.ethdebugRuntime) + if (!m_options.output.debugInfoSelection.has_value()) + { + m_options.output.debugInfoSelection = DebugInfoSelection::Default(); + m_options.output.debugInfoSelection->enable("ethdebug"); + } + return; } else if (countEnabledOptions({g_strYulDialect, g_strMachine}) >= 1) @@ -1460,6 +1483,61 @@ void CommandLineParser::processArgs() m_options.input.mode == InputMode::CompilerWithASTImport || m_options.input.mode == InputMode::EVMAssemblerJSON ); + + bool incompatibleEthdebugOutputs = + m_options.compiler.outputs.asmJson || m_options.compiler.outputs.irAstJson || m_options.compiler.outputs.irOptimizedAstJson; + + bool incompatibleEthdebugInputs = m_options.input.mode != InputMode::Compiler; + + static std::string enableEthdebugMessage = + "--" + CompilerOutputs::componentName(&CompilerOutputs::ethdebug) + " / --" + CompilerOutputs::componentName(&CompilerOutputs::ethdebugRuntime); + + static std::string enableIrMessage = + "--" + CompilerOutputs::componentName(&CompilerOutputs::ir) + " / --" + CompilerOutputs::componentName(&CompilerOutputs::irOptimized); + + if (m_options.compiler.outputs.ethdebug || m_options.compiler.outputs.ethdebugRuntime) + { + if (!m_options.output.viaIR) + solThrow( + CommandLineValidationError, + enableEthdebugMessage + " output can only be selected, if --via-ir was specified." + ); + + if (incompatibleEthdebugOutputs) + solThrow( + CommandLineValidationError, + enableEthdebugMessage + " output can only be used with " + enableIrMessage + "." + ); + + if (!m_options.output.debugInfoSelection.has_value()) + { + m_options.output.debugInfoSelection = DebugInfoSelection::Default(); + m_options.output.debugInfoSelection->enable("ethdebug"); + } + else + { + if (!m_options.output.debugInfoSelection->ethdebug) + solThrow( + CommandLineValidationError, + "--debug-info must contain ethdebug, when compiling with " + enableEthdebugMessage + "." + ); + } + } + + if ( + m_options.output.debugInfoSelection.has_value() && m_options.output.debugInfoSelection->ethdebug && + (!(m_options.compiler.outputs.ir || m_options.compiler.outputs.irOptimized || m_options.compiler.outputs.ethdebug || m_options.compiler.outputs.ethdebugRuntime) || incompatibleEthdebugOutputs) + ) + solThrow( + CommandLineValidationError, + "--debug-info ethdebug can only be used with " + enableIrMessage + " and/or " + enableEthdebugMessage + "." + ); + + if (m_options.output.debugInfoSelection.has_value() && m_options.output.debugInfoSelection->ethdebug && incompatibleEthdebugInputs) + solThrow( + CommandLineValidationError, + "Invalid input mode for --debug-info ethdebug / --ethdebug / --ethdebug-runtime." + ); } void CommandLineParser::parseCombinedJsonOption() diff --git a/solc/CommandLineParser.h b/solc/CommandLineParser.h index 3d187694e2e0..d8141cb4fcf0 100644 --- a/solc/CommandLineParser.h +++ b/solc/CommandLineParser.h @@ -88,6 +88,8 @@ struct CompilerOutputs {"storage-layout", &CompilerOutputs::storageLayout}, {"transient-storage-layout", &CompilerOutputs::transientStorageLayout}, {"yul-cfg-json", &CompilerOutputs::yulCFGJson}, + {"ethdebug", &CompilerOutputs::ethdebug}, + {"ethdebug-runtime", &CompilerOutputs::ethdebugRuntime}, }; return components; } @@ -110,6 +112,8 @@ struct CompilerOutputs bool metadata = false; bool storageLayout = false; bool transientStorageLayout = false; + bool ethdebug = false; + bool ethdebugRuntime = false; }; struct CombinedJsonRequests diff --git a/test/cmdlineTests/ethdebug/args b/test/cmdlineTests/ethdebug/args new file mode 100644 index 000000000000..6edc3b560136 --- /dev/null +++ b/test/cmdlineTests/ethdebug/args @@ -0,0 +1 @@ +--ethdebug --via-ir --optimize --ir-optimized \ No newline at end of file diff --git a/test/cmdlineTests/ethdebug/input.sol b/test/cmdlineTests/ethdebug/input.sol new file mode 100644 index 000000000000..25b9640ca565 --- /dev/null +++ b/test/cmdlineTests/ethdebug/input.sol @@ -0,0 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0 +pragma solidity >=0.0; + +contract C { + function f() public {} +} + diff --git a/test/cmdlineTests/ethdebug/output b/test/cmdlineTests/ethdebug/output new file mode 100644 index 000000000000..41f243d9c488 --- /dev/null +++ b/test/cmdlineTests/ethdebug/output @@ -0,0 +1,42 @@ +======= Debug Data (ethdebug/format/info/resources) ======= +{"sources":["ethdebug/input.sol"]} + +======= ethdebug/input.sol:C ======= +Optimized IR: +/// ethdebug: enabled +/// @use-src 0:"ethdebug/input.sol" +object "C_6" { + code { + { + /// @src 0:60:101 "contract C {..." + let _1 := memoryguard(0x80) + mstore(64, _1) + if callvalue() { revert(0, 0) } + let _2 := datasize("C_6_deployed") + codecopy(_1, dataoffset("C_6_deployed"), _2) + return(_1, _2) + } + } + /// @use-src 0:"ethdebug/input.sol" + object "C_6_deployed" { + code { + { + /// @src 0:60:101 "contract C {..." + if iszero(lt(calldatasize(), 4)) + { + if eq(0x26121ff0, shr(224, calldataload(0))) + { + if callvalue() { revert(0, 0) } + if slt(add(calldatasize(), not(3)), 0) { revert(0, 0) } + return(0, 0) + } + } + revert(0, 0) + } + } + data ".metadata" hex"" + } +} + +Debug Data (ethdebug/format/program): +{} diff --git a/test/cmdlineTests/ethdebug_and_ethdebug_runtime/args b/test/cmdlineTests/ethdebug_and_ethdebug_runtime/args new file mode 100644 index 000000000000..809fb09884d8 --- /dev/null +++ b/test/cmdlineTests/ethdebug_and_ethdebug_runtime/args @@ -0,0 +1 @@ +--ethdebug-runtime --ethdebug --via-ir --optimize --ir-optimized \ No newline at end of file diff --git a/test/cmdlineTests/ethdebug_and_ethdebug_runtime/input.sol b/test/cmdlineTests/ethdebug_and_ethdebug_runtime/input.sol new file mode 100644 index 000000000000..25b9640ca565 --- /dev/null +++ b/test/cmdlineTests/ethdebug_and_ethdebug_runtime/input.sol @@ -0,0 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0 +pragma solidity >=0.0; + +contract C { + function f() public {} +} + diff --git a/test/cmdlineTests/ethdebug_and_ethdebug_runtime/output b/test/cmdlineTests/ethdebug_and_ethdebug_runtime/output new file mode 100644 index 000000000000..3566824b9b03 --- /dev/null +++ b/test/cmdlineTests/ethdebug_and_ethdebug_runtime/output @@ -0,0 +1,44 @@ +======= Debug Data (ethdebug/format/info/resources) ======= +{"sources":["ethdebug_and_ethdebug_runtime/input.sol"]} + +======= ethdebug_and_ethdebug_runtime/input.sol:C ======= +Optimized IR: +/// ethdebug: enabled +/// @use-src 0:"ethdebug_and_ethdebug_runtime/input.sol" +object "C_6" { + code { + { + /// @src 0:60:101 "contract C {..." + let _1 := memoryguard(0x80) + mstore(64, _1) + if callvalue() { revert(0, 0) } + let _2 := datasize("C_6_deployed") + codecopy(_1, dataoffset("C_6_deployed"), _2) + return(_1, _2) + } + } + /// @use-src 0:"ethdebug_and_ethdebug_runtime/input.sol" + object "C_6_deployed" { + code { + { + /// @src 0:60:101 "contract C {..." + if iszero(lt(calldatasize(), 4)) + { + if eq(0x26121ff0, shr(224, calldataload(0))) + { + if callvalue() { revert(0, 0) } + if slt(add(calldatasize(), not(3)), 0) { revert(0, 0) } + return(0, 0) + } + } + revert(0, 0) + } + } + data ".metadata" hex"" + } +} + +Debug Data (ethdebug/format/program): +{} +Debug Data of the runtime part (ethdebug/format/program): +{} diff --git a/test/cmdlineTests/ethdebug_runtime/args b/test/cmdlineTests/ethdebug_runtime/args new file mode 100644 index 000000000000..dfc6038785a5 --- /dev/null +++ b/test/cmdlineTests/ethdebug_runtime/args @@ -0,0 +1 @@ +--ethdebug-runtime --via-ir --optimize --ir-optimized \ No newline at end of file diff --git a/test/cmdlineTests/ethdebug_runtime/input.sol b/test/cmdlineTests/ethdebug_runtime/input.sol new file mode 100644 index 000000000000..25b9640ca565 --- /dev/null +++ b/test/cmdlineTests/ethdebug_runtime/input.sol @@ -0,0 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0 +pragma solidity >=0.0; + +contract C { + function f() public {} +} + diff --git a/test/cmdlineTests/ethdebug_runtime/output b/test/cmdlineTests/ethdebug_runtime/output new file mode 100644 index 000000000000..8af39f64ef3c --- /dev/null +++ b/test/cmdlineTests/ethdebug_runtime/output @@ -0,0 +1,42 @@ +======= Debug Data (ethdebug/format/info/resources) ======= +{"sources":["ethdebug_runtime/input.sol"]} + +======= ethdebug_runtime/input.sol:C ======= +Optimized IR: +/// ethdebug: enabled +/// @use-src 0:"ethdebug_runtime/input.sol" +object "C_6" { + code { + { + /// @src 0:60:101 "contract C {..." + let _1 := memoryguard(0x80) + mstore(64, _1) + if callvalue() { revert(0, 0) } + let _2 := datasize("C_6_deployed") + codecopy(_1, dataoffset("C_6_deployed"), _2) + return(_1, _2) + } + } + /// @use-src 0:"ethdebug_runtime/input.sol" + object "C_6_deployed" { + code { + { + /// @src 0:60:101 "contract C {..." + if iszero(lt(calldatasize(), 4)) + { + if eq(0x26121ff0, shr(224, calldataload(0))) + { + if callvalue() { revert(0, 0) } + if slt(add(calldatasize(), not(3)), 0) { revert(0, 0) } + return(0, 0) + } + } + revert(0, 0) + } + } + data ".metadata" hex"" + } +} + +Debug Data of the runtime part (ethdebug/format/program): +{} diff --git a/test/cmdlineTests/standard_output_selection_ethdebug_bytecode/input.json b/test/cmdlineTests/standard_output_selection_ethdebug_bytecode/input.json new file mode 100644 index 000000000000..e7173abed3e1 --- /dev/null +++ b/test/cmdlineTests/standard_output_selection_ethdebug_bytecode/input.json @@ -0,0 +1,24 @@ +{ + "language": "Solidity", + "sources": { + "a.sol": { + "content": "//SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract A1 { function a(uint x) public pure { assert(x > 0); } } contract A2 { function a(uint x) public pure { assert(x > 0); } }" + }, + "b.sol": { + "content": "//SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract A1 { function b(uint x) public pure { assert(x > 0); } } contract B2 { function b(uint x) public pure { assert(x > 0); } }" + } + }, + "settings": { + "viaIR": true, + "optimizer": { + "enabled": true + }, + "outputSelection": { + "*": { + "*": [ + "evm.bytecode.ethdebug", "irOptimized" + ] + } + } + } +} diff --git a/test/cmdlineTests/standard_output_selection_ethdebug_bytecode/output.json b/test/cmdlineTests/standard_output_selection_ethdebug_bytecode/output.json new file mode 100644 index 000000000000..da701aec60f5 --- /dev/null +++ b/test/cmdlineTests/standard_output_selection_ethdebug_bytecode/output.json @@ -0,0 +1,214 @@ +{ + "contracts": { + "a.sol": { + "A1": { + "evm": { + "bytecode": { + "ethdebug": {} + } + }, + "irOptimized": "/// ethdebug: enabled +/// @use-src 0:\"a.sol\" +object \"A1_14\" { + code { + { + /// @src 0:58:123 \"contract A1 { function a(uint x) public pure { assert(x > 0); } }\" + let _1 := memoryguard(0x80) + mstore(64, _1) + if callvalue() { revert(0, 0) } + let _2 := datasize(\"A1_14_deployed\") + codecopy(_1, dataoffset(\"A1_14_deployed\"), _2) + return(_1, _2) + } + } + /// @use-src 0:\"a.sol\" + object \"A1_14_deployed\" { + code { + { + /// @src 0:58:123 \"contract A1 { function a(uint x) public pure { assert(x > 0); } }\" + if iszero(lt(calldatasize(), 4)) + { + if eq(0xf0fdf834, shr(224, calldataload(0))) + { + if callvalue() { revert(0, 0) } + if slt(add(calldatasize(), not(3)), 32) { revert(0, 0) } + if /** @src 0:112:117 \"x > 0\" */ iszero(/** @src 0:58:123 \"contract A1 { function a(uint x) public pure { assert(x > 0); } }\" */ calldataload(4)) + { + mstore(0, shl(224, 0x4e487b71)) + mstore(4, 1) + revert(0, 0x24) + } + return(0, 0) + } + } + revert(0, 0) + } + } + data \".metadata\" hex\"\" + } +} +" + }, + "A2": { + "evm": { + "bytecode": { + "ethdebug": {} + } + }, + "irOptimized": "/// ethdebug: enabled +/// @use-src 0:\"a.sol\" +object \"A2_27\" { + code { + { + /// @src 0:124:189 \"contract A2 { function a(uint x) public pure { assert(x > 0); } }\" + let _1 := memoryguard(0x80) + mstore(64, _1) + if callvalue() { revert(0, 0) } + let _2 := datasize(\"A2_27_deployed\") + codecopy(_1, dataoffset(\"A2_27_deployed\"), _2) + return(_1, _2) + } + } + /// @use-src 0:\"a.sol\" + object \"A2_27_deployed\" { + code { + { + /// @src 0:124:189 \"contract A2 { function a(uint x) public pure { assert(x > 0); } }\" + if iszero(lt(calldatasize(), 4)) + { + if eq(0xf0fdf834, shr(224, calldataload(0))) + { + if callvalue() { revert(0, 0) } + if slt(add(calldatasize(), not(3)), 32) { revert(0, 0) } + if /** @src 0:178:183 \"x > 0\" */ iszero(/** @src 0:124:189 \"contract A2 { function a(uint x) public pure { assert(x > 0); } }\" */ calldataload(4)) + { + mstore(0, shl(224, 0x4e487b71)) + mstore(4, 1) + revert(0, 0x24) + } + return(0, 0) + } + } + revert(0, 0) + } + } + data \".metadata\" hex\"\" + } +} +" + } + }, + "b.sol": { + "A1": { + "evm": { + "bytecode": { + "ethdebug": {} + } + }, + "irOptimized": "/// ethdebug: enabled +/// @use-src 1:\"b.sol\" +object \"A1_42\" { + code { + { + /// @src 1:58:123 \"contract A1 { function b(uint x) public pure { assert(x > 0); } }\" + let _1 := memoryguard(0x80) + mstore(64, _1) + if callvalue() { revert(0, 0) } + let _2 := datasize(\"A1_42_deployed\") + codecopy(_1, dataoffset(\"A1_42_deployed\"), _2) + return(_1, _2) + } + } + /// @use-src 1:\"b.sol\" + object \"A1_42_deployed\" { + code { + { + /// @src 1:58:123 \"contract A1 { function b(uint x) public pure { assert(x > 0); } }\" + if iszero(lt(calldatasize(), 4)) + { + if eq(0xcd580ff3, shr(224, calldataload(0))) + { + if callvalue() { revert(0, 0) } + if slt(add(calldatasize(), not(3)), 32) { revert(0, 0) } + if /** @src 1:112:117 \"x > 0\" */ iszero(/** @src 1:58:123 \"contract A1 { function b(uint x) public pure { assert(x > 0); } }\" */ calldataload(4)) + { + mstore(0, shl(224, 0x4e487b71)) + mstore(4, 1) + revert(0, 0x24) + } + return(0, 0) + } + } + revert(0, 0) + } + } + data \".metadata\" hex\"\" + } +} +" + }, + "B2": { + "evm": { + "bytecode": { + "ethdebug": {} + } + }, + "irOptimized": "/// ethdebug: enabled +/// @use-src 1:\"b.sol\" +object \"B2_55\" { + code { + { + /// @src 1:124:189 \"contract B2 { function b(uint x) public pure { assert(x > 0); } }\" + let _1 := memoryguard(0x80) + mstore(64, _1) + if callvalue() { revert(0, 0) } + let _2 := datasize(\"B2_55_deployed\") + codecopy(_1, dataoffset(\"B2_55_deployed\"), _2) + return(_1, _2) + } + } + /// @use-src 1:\"b.sol\" + object \"B2_55_deployed\" { + code { + { + /// @src 1:124:189 \"contract B2 { function b(uint x) public pure { assert(x > 0); } }\" + if iszero(lt(calldatasize(), 4)) + { + if eq(0xcd580ff3, shr(224, calldataload(0))) + { + if callvalue() { revert(0, 0) } + if slt(add(calldatasize(), not(3)), 32) { revert(0, 0) } + if /** @src 1:178:183 \"x > 0\" */ iszero(/** @src 1:124:189 \"contract B2 { function b(uint x) public pure { assert(x > 0); } }\" */ calldataload(4)) + { + mstore(0, shl(224, 0x4e487b71)) + mstore(4, 1) + revert(0, 0x24) + } + return(0, 0) + } + } + revert(0, 0) + } + } + data \".metadata\" hex\"\" + } +} +" + } + } + }, + "ethdebug": { + "sources": [ + "a.sol", + "b.sol" + ] + }, + "sources": { + "a.sol": { + "id": 0 + }, + "b.sol": { + "id": 1 + } + } +} diff --git a/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode/input.json b/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode/input.json new file mode 100644 index 000000000000..e45f27f3caa8 --- /dev/null +++ b/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode/input.json @@ -0,0 +1,24 @@ +{ + "language": "Solidity", + "sources": { + "a.sol": { + "content": "//SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract A1 { function a(uint x) public pure { assert(x > 0); } } contract A2 { function a(uint x) public pure { assert(x > 0); } }" + }, + "b.sol": { + "content": "//SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract A1 { function b(uint x) public pure { assert(x > 0); } } contract B2 { function b(uint x) public pure { assert(x > 0); } }" + } + }, + "settings": { + "viaIR": true, + "optimizer": { + "enabled": true + }, + "outputSelection": { + "*": { + "*": [ + "evm.bytecode.ethdebug", "evm.deployedBytecode.ethdebug", "irOptimized" + ] + } + } + } +} diff --git a/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode/output.json b/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode/output.json new file mode 100644 index 000000000000..4e41e41c385b --- /dev/null +++ b/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode/output.json @@ -0,0 +1,226 @@ +{ + "contracts": { + "a.sol": { + "A1": { + "evm": { + "bytecode": { + "ethdebug": {} + }, + "deployedBytecode": { + "ethdebug": {} + } + }, + "irOptimized": "/// ethdebug: enabled +/// @use-src 0:\"a.sol\" +object \"A1_14\" { + code { + { + /// @src 0:58:123 \"contract A1 { function a(uint x) public pure { assert(x > 0); } }\" + let _1 := memoryguard(0x80) + mstore(64, _1) + if callvalue() { revert(0, 0) } + let _2 := datasize(\"A1_14_deployed\") + codecopy(_1, dataoffset(\"A1_14_deployed\"), _2) + return(_1, _2) + } + } + /// @use-src 0:\"a.sol\" + object \"A1_14_deployed\" { + code { + { + /// @src 0:58:123 \"contract A1 { function a(uint x) public pure { assert(x > 0); } }\" + if iszero(lt(calldatasize(), 4)) + { + if eq(0xf0fdf834, shr(224, calldataload(0))) + { + if callvalue() { revert(0, 0) } + if slt(add(calldatasize(), not(3)), 32) { revert(0, 0) } + if /** @src 0:112:117 \"x > 0\" */ iszero(/** @src 0:58:123 \"contract A1 { function a(uint x) public pure { assert(x > 0); } }\" */ calldataload(4)) + { + mstore(0, shl(224, 0x4e487b71)) + mstore(4, 1) + revert(0, 0x24) + } + return(0, 0) + } + } + revert(0, 0) + } + } + data \".metadata\" hex\"\" + } +} +" + }, + "A2": { + "evm": { + "bytecode": { + "ethdebug": {} + }, + "deployedBytecode": { + "ethdebug": {} + } + }, + "irOptimized": "/// ethdebug: enabled +/// @use-src 0:\"a.sol\" +object \"A2_27\" { + code { + { + /// @src 0:124:189 \"contract A2 { function a(uint x) public pure { assert(x > 0); } }\" + let _1 := memoryguard(0x80) + mstore(64, _1) + if callvalue() { revert(0, 0) } + let _2 := datasize(\"A2_27_deployed\") + codecopy(_1, dataoffset(\"A2_27_deployed\"), _2) + return(_1, _2) + } + } + /// @use-src 0:\"a.sol\" + object \"A2_27_deployed\" { + code { + { + /// @src 0:124:189 \"contract A2 { function a(uint x) public pure { assert(x > 0); } }\" + if iszero(lt(calldatasize(), 4)) + { + if eq(0xf0fdf834, shr(224, calldataload(0))) + { + if callvalue() { revert(0, 0) } + if slt(add(calldatasize(), not(3)), 32) { revert(0, 0) } + if /** @src 0:178:183 \"x > 0\" */ iszero(/** @src 0:124:189 \"contract A2 { function a(uint x) public pure { assert(x > 0); } }\" */ calldataload(4)) + { + mstore(0, shl(224, 0x4e487b71)) + mstore(4, 1) + revert(0, 0x24) + } + return(0, 0) + } + } + revert(0, 0) + } + } + data \".metadata\" hex\"\" + } +} +" + } + }, + "b.sol": { + "A1": { + "evm": { + "bytecode": { + "ethdebug": {} + }, + "deployedBytecode": { + "ethdebug": {} + } + }, + "irOptimized": "/// ethdebug: enabled +/// @use-src 1:\"b.sol\" +object \"A1_42\" { + code { + { + /// @src 1:58:123 \"contract A1 { function b(uint x) public pure { assert(x > 0); } }\" + let _1 := memoryguard(0x80) + mstore(64, _1) + if callvalue() { revert(0, 0) } + let _2 := datasize(\"A1_42_deployed\") + codecopy(_1, dataoffset(\"A1_42_deployed\"), _2) + return(_1, _2) + } + } + /// @use-src 1:\"b.sol\" + object \"A1_42_deployed\" { + code { + { + /// @src 1:58:123 \"contract A1 { function b(uint x) public pure { assert(x > 0); } }\" + if iszero(lt(calldatasize(), 4)) + { + if eq(0xcd580ff3, shr(224, calldataload(0))) + { + if callvalue() { revert(0, 0) } + if slt(add(calldatasize(), not(3)), 32) { revert(0, 0) } + if /** @src 1:112:117 \"x > 0\" */ iszero(/** @src 1:58:123 \"contract A1 { function b(uint x) public pure { assert(x > 0); } }\" */ calldataload(4)) + { + mstore(0, shl(224, 0x4e487b71)) + mstore(4, 1) + revert(0, 0x24) + } + return(0, 0) + } + } + revert(0, 0) + } + } + data \".metadata\" hex\"\" + } +} +" + }, + "B2": { + "evm": { + "bytecode": { + "ethdebug": {} + }, + "deployedBytecode": { + "ethdebug": {} + } + }, + "irOptimized": "/// ethdebug: enabled +/// @use-src 1:\"b.sol\" +object \"B2_55\" { + code { + { + /// @src 1:124:189 \"contract B2 { function b(uint x) public pure { assert(x > 0); } }\" + let _1 := memoryguard(0x80) + mstore(64, _1) + if callvalue() { revert(0, 0) } + let _2 := datasize(\"B2_55_deployed\") + codecopy(_1, dataoffset(\"B2_55_deployed\"), _2) + return(_1, _2) + } + } + /// @use-src 1:\"b.sol\" + object \"B2_55_deployed\" { + code { + { + /// @src 1:124:189 \"contract B2 { function b(uint x) public pure { assert(x > 0); } }\" + if iszero(lt(calldatasize(), 4)) + { + if eq(0xcd580ff3, shr(224, calldataload(0))) + { + if callvalue() { revert(0, 0) } + if slt(add(calldatasize(), not(3)), 32) { revert(0, 0) } + if /** @src 1:178:183 \"x > 0\" */ iszero(/** @src 1:124:189 \"contract B2 { function b(uint x) public pure { assert(x > 0); } }\" */ calldataload(4)) + { + mstore(0, shl(224, 0x4e487b71)) + mstore(4, 1) + revert(0, 0x24) + } + return(0, 0) + } + } + revert(0, 0) + } + } + data \".metadata\" hex\"\" + } +} +" + } + } + }, + "ethdebug": { + "sources": [ + "a.sol", + "b.sol" + ] + }, + "sources": { + "a.sol": { + "id": 0 + }, + "b.sol": { + "id": 1 + } + } +} diff --git a/test/cmdlineTests/standard_output_selection_ethdebug_deployedbytecode/input.json b/test/cmdlineTests/standard_output_selection_ethdebug_deployedbytecode/input.json new file mode 100644 index 000000000000..9e104dc177cc --- /dev/null +++ b/test/cmdlineTests/standard_output_selection_ethdebug_deployedbytecode/input.json @@ -0,0 +1,24 @@ +{ + "language": "Solidity", + "sources": { + "a.sol": { + "content": "//SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract A1 { function a(uint x) public pure { assert(x > 0); } } contract A2 { function a(uint x) public pure { assert(x > 0); } }" + }, + "b.sol": { + "content": "//SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract A1 { function b(uint x) public pure { assert(x > 0); } } contract B2 { function b(uint x) public pure { assert(x > 0); } }" + } + }, + "settings": { + "viaIR": true, + "optimizer": { + "enabled": true + }, + "outputSelection": { + "*": { + "*": [ + "evm.deployedBytecode.ethdebug", "irOptimized" + ] + } + } + } +} diff --git a/test/cmdlineTests/standard_output_selection_ethdebug_deployedbytecode/output.json b/test/cmdlineTests/standard_output_selection_ethdebug_deployedbytecode/output.json new file mode 100644 index 000000000000..3ad7350a9fe8 --- /dev/null +++ b/test/cmdlineTests/standard_output_selection_ethdebug_deployedbytecode/output.json @@ -0,0 +1,214 @@ +{ + "contracts": { + "a.sol": { + "A1": { + "evm": { + "deployedBytecode": { + "ethdebug": {} + } + }, + "irOptimized": "/// ethdebug: enabled +/// @use-src 0:\"a.sol\" +object \"A1_14\" { + code { + { + /// @src 0:58:123 \"contract A1 { function a(uint x) public pure { assert(x > 0); } }\" + let _1 := memoryguard(0x80) + mstore(64, _1) + if callvalue() { revert(0, 0) } + let _2 := datasize(\"A1_14_deployed\") + codecopy(_1, dataoffset(\"A1_14_deployed\"), _2) + return(_1, _2) + } + } + /// @use-src 0:\"a.sol\" + object \"A1_14_deployed\" { + code { + { + /// @src 0:58:123 \"contract A1 { function a(uint x) public pure { assert(x > 0); } }\" + if iszero(lt(calldatasize(), 4)) + { + if eq(0xf0fdf834, shr(224, calldataload(0))) + { + if callvalue() { revert(0, 0) } + if slt(add(calldatasize(), not(3)), 32) { revert(0, 0) } + if /** @src 0:112:117 \"x > 0\" */ iszero(/** @src 0:58:123 \"contract A1 { function a(uint x) public pure { assert(x > 0); } }\" */ calldataload(4)) + { + mstore(0, shl(224, 0x4e487b71)) + mstore(4, 1) + revert(0, 0x24) + } + return(0, 0) + } + } + revert(0, 0) + } + } + data \".metadata\" hex\"\" + } +} +" + }, + "A2": { + "evm": { + "deployedBytecode": { + "ethdebug": {} + } + }, + "irOptimized": "/// ethdebug: enabled +/// @use-src 0:\"a.sol\" +object \"A2_27\" { + code { + { + /// @src 0:124:189 \"contract A2 { function a(uint x) public pure { assert(x > 0); } }\" + let _1 := memoryguard(0x80) + mstore(64, _1) + if callvalue() { revert(0, 0) } + let _2 := datasize(\"A2_27_deployed\") + codecopy(_1, dataoffset(\"A2_27_deployed\"), _2) + return(_1, _2) + } + } + /// @use-src 0:\"a.sol\" + object \"A2_27_deployed\" { + code { + { + /// @src 0:124:189 \"contract A2 { function a(uint x) public pure { assert(x > 0); } }\" + if iszero(lt(calldatasize(), 4)) + { + if eq(0xf0fdf834, shr(224, calldataload(0))) + { + if callvalue() { revert(0, 0) } + if slt(add(calldatasize(), not(3)), 32) { revert(0, 0) } + if /** @src 0:178:183 \"x > 0\" */ iszero(/** @src 0:124:189 \"contract A2 { function a(uint x) public pure { assert(x > 0); } }\" */ calldataload(4)) + { + mstore(0, shl(224, 0x4e487b71)) + mstore(4, 1) + revert(0, 0x24) + } + return(0, 0) + } + } + revert(0, 0) + } + } + data \".metadata\" hex\"\" + } +} +" + } + }, + "b.sol": { + "A1": { + "evm": { + "deployedBytecode": { + "ethdebug": {} + } + }, + "irOptimized": "/// ethdebug: enabled +/// @use-src 1:\"b.sol\" +object \"A1_42\" { + code { + { + /// @src 1:58:123 \"contract A1 { function b(uint x) public pure { assert(x > 0); } }\" + let _1 := memoryguard(0x80) + mstore(64, _1) + if callvalue() { revert(0, 0) } + let _2 := datasize(\"A1_42_deployed\") + codecopy(_1, dataoffset(\"A1_42_deployed\"), _2) + return(_1, _2) + } + } + /// @use-src 1:\"b.sol\" + object \"A1_42_deployed\" { + code { + { + /// @src 1:58:123 \"contract A1 { function b(uint x) public pure { assert(x > 0); } }\" + if iszero(lt(calldatasize(), 4)) + { + if eq(0xcd580ff3, shr(224, calldataload(0))) + { + if callvalue() { revert(0, 0) } + if slt(add(calldatasize(), not(3)), 32) { revert(0, 0) } + if /** @src 1:112:117 \"x > 0\" */ iszero(/** @src 1:58:123 \"contract A1 { function b(uint x) public pure { assert(x > 0); } }\" */ calldataload(4)) + { + mstore(0, shl(224, 0x4e487b71)) + mstore(4, 1) + revert(0, 0x24) + } + return(0, 0) + } + } + revert(0, 0) + } + } + data \".metadata\" hex\"\" + } +} +" + }, + "B2": { + "evm": { + "deployedBytecode": { + "ethdebug": {} + } + }, + "irOptimized": "/// ethdebug: enabled +/// @use-src 1:\"b.sol\" +object \"B2_55\" { + code { + { + /// @src 1:124:189 \"contract B2 { function b(uint x) public pure { assert(x > 0); } }\" + let _1 := memoryguard(0x80) + mstore(64, _1) + if callvalue() { revert(0, 0) } + let _2 := datasize(\"B2_55_deployed\") + codecopy(_1, dataoffset(\"B2_55_deployed\"), _2) + return(_1, _2) + } + } + /// @use-src 1:\"b.sol\" + object \"B2_55_deployed\" { + code { + { + /// @src 1:124:189 \"contract B2 { function b(uint x) public pure { assert(x > 0); } }\" + if iszero(lt(calldatasize(), 4)) + { + if eq(0xcd580ff3, shr(224, calldataload(0))) + { + if callvalue() { revert(0, 0) } + if slt(add(calldatasize(), not(3)), 32) { revert(0, 0) } + if /** @src 1:178:183 \"x > 0\" */ iszero(/** @src 1:124:189 \"contract B2 { function b(uint x) public pure { assert(x > 0); } }\" */ calldataload(4)) + { + mstore(0, shl(224, 0x4e487b71)) + mstore(4, 1) + revert(0, 0x24) + } + return(0, 0) + } + } + revert(0, 0) + } + } + data \".metadata\" hex\"\" + } +} +" + } + } + }, + "ethdebug": { + "sources": [ + "a.sol", + "b.sol" + ] + }, + "sources": { + "a.sol": { + "id": 0 + }, + "b.sol": { + "id": 1 + } + } +} diff --git a/test/cmdlineTests/standard_yul_ethdebug_bytecode/args b/test/cmdlineTests/standard_yul_ethdebug_bytecode/args new file mode 100644 index 000000000000..18532c5a6d3f --- /dev/null +++ b/test/cmdlineTests/standard_yul_ethdebug_bytecode/args @@ -0,0 +1 @@ +--allow-paths . diff --git a/test/cmdlineTests/standard_yul_ethdebug_bytecode/in.yul b/test/cmdlineTests/standard_yul_ethdebug_bytecode/in.yul new file mode 100644 index 000000000000..920aef8e9dc2 --- /dev/null +++ b/test/cmdlineTests/standard_yul_ethdebug_bytecode/in.yul @@ -0,0 +1,17 @@ +/// @use-src 0:"input.sol" +object "C_6_deployed" { + code { + /// @src 0:60:101 "contract C {..." + mstore(64, 128) + + // f() + fun_f_5() + + /// @src 0:77:99 "function f() public {}" + function fun_f_5() { + sstore(0, 42) + } + /// @src 0:60:101 "contract C {..." + } +} + diff --git a/test/cmdlineTests/standard_yul_ethdebug_bytecode/input.json b/test/cmdlineTests/standard_yul_ethdebug_bytecode/input.json new file mode 100644 index 000000000000..86761f23659c --- /dev/null +++ b/test/cmdlineTests/standard_yul_ethdebug_bytecode/input.json @@ -0,0 +1,14 @@ +{ + "language": "Yul", + "sources": { + "C": {"urls": ["standard_yul_debug_info_print_all/in.yul"]} + }, + "settings": { + "optimizer": { + "enabled": true + }, + "outputSelection": { + "*": {"*": ["evm.bytecode.ethdebug", "irOptimized"]} + } + } +} diff --git a/test/cmdlineTests/standard_yul_ethdebug_bytecode/output.json b/test/cmdlineTests/standard_yul_ethdebug_bytecode/output.json new file mode 100644 index 000000000000..0e93c5b77f30 --- /dev/null +++ b/test/cmdlineTests/standard_yul_ethdebug_bytecode/output.json @@ -0,0 +1,31 @@ +{ + "contracts": { + "C": { + "C_6_deployed": { + "evm": { + "bytecode": { + "ethdebug": { + "not yet implemented @ MachineAssemblyObject::ethdebug": true + } + } + }, + "irOptimized": "/// ethdebug: enabled +/// @use-src 0:\"input.sol\" +object \"C_6_deployed\" { + code { + { + /// @src 0:77:99 + sstore(0, 42) + } + } +} +" + } + } + }, + "ethdebug": { + "sources": [ + "C" + ] + } +} diff --git a/test/cmdlineTests/standard_yul_ethdebug_deployed_bytecode/args b/test/cmdlineTests/standard_yul_ethdebug_deployed_bytecode/args new file mode 100644 index 000000000000..18532c5a6d3f --- /dev/null +++ b/test/cmdlineTests/standard_yul_ethdebug_deployed_bytecode/args @@ -0,0 +1 @@ +--allow-paths . diff --git a/test/cmdlineTests/standard_yul_ethdebug_deployed_bytecode/in.yul b/test/cmdlineTests/standard_yul_ethdebug_deployed_bytecode/in.yul new file mode 100644 index 000000000000..920aef8e9dc2 --- /dev/null +++ b/test/cmdlineTests/standard_yul_ethdebug_deployed_bytecode/in.yul @@ -0,0 +1,17 @@ +/// @use-src 0:"input.sol" +object "C_6_deployed" { + code { + /// @src 0:60:101 "contract C {..." + mstore(64, 128) + + // f() + fun_f_5() + + /// @src 0:77:99 "function f() public {}" + function fun_f_5() { + sstore(0, 42) + } + /// @src 0:60:101 "contract C {..." + } +} + diff --git a/test/cmdlineTests/standard_yul_ethdebug_deployed_bytecode/input.json b/test/cmdlineTests/standard_yul_ethdebug_deployed_bytecode/input.json new file mode 100644 index 000000000000..e132c654f042 --- /dev/null +++ b/test/cmdlineTests/standard_yul_ethdebug_deployed_bytecode/input.json @@ -0,0 +1,11 @@ +{ + "language": "Yul", + "sources": { + "C": {"urls": ["standard_yul_debug_info_print_all/in.yul"]} + }, + "settings": { + "outputSelection": { + "*": {"*": ["evm.deployedBytecode.ethdebug"]} + } + } +} diff --git a/test/cmdlineTests/standard_yul_ethdebug_deployed_bytecode/output.json b/test/cmdlineTests/standard_yul_ethdebug_deployed_bytecode/output.json new file mode 100644 index 000000000000..1380c31d7c10 --- /dev/null +++ b/test/cmdlineTests/standard_yul_ethdebug_deployed_bytecode/output.json @@ -0,0 +1,11 @@ +{ + "errors": [ + { + "component": "general", + "formattedMessage": "\"evm.deployedBytecode.ethdebug\" cannot be used for Yul.", + "message": "\"evm.deployedBytecode.ethdebug\" cannot be used for Yul.", + "severity": "error", + "type": "JSONError" + } + ] +} diff --git a/test/cmdlineTests/yul_ethdebug/args b/test/cmdlineTests/yul_ethdebug/args new file mode 100644 index 000000000000..715f3fb4848b --- /dev/null +++ b/test/cmdlineTests/yul_ethdebug/args @@ -0,0 +1 @@ +--ethdebug --strict-assembly --optimize --ir-optimized \ No newline at end of file diff --git a/test/cmdlineTests/yul_ethdebug/input.yul b/test/cmdlineTests/yul_ethdebug/input.yul new file mode 100644 index 000000000000..acd0b45f5335 --- /dev/null +++ b/test/cmdlineTests/yul_ethdebug/input.yul @@ -0,0 +1,18 @@ +object "object" { + code { + let a + let b + { + function z() -> y + { y := calldataload(0) } + a := z() + } + { + function z() -> y + { y := calldataload(0x20) } + b := z() + } + sstore(a, b) + } +} + diff --git a/test/cmdlineTests/yul_ethdebug/output b/test/cmdlineTests/yul_ethdebug/output new file mode 100644 index 000000000000..702fe057d532 --- /dev/null +++ b/test/cmdlineTests/yul_ethdebug/output @@ -0,0 +1,18 @@ +======= Debug Data (ethdebug/format/info/resources) ======= +{"sources":["yul_ethdebug/input.yul"]} + +======= yul_ethdebug/input.yul (EVM) ======= + +Pretty printed source: +/// ethdebug: enabled +object "object" { + code { + { + sstore(calldataload(0), calldataload(0x20)) + } + } +} + + +Debug Data (ethdebug/format/program): +{"not yet implemented @ MachineAssemblyObject::ethdebug":true} diff --git a/test/cmdlineTests/yul_ethdebug_runtime/args b/test/cmdlineTests/yul_ethdebug_runtime/args new file mode 100644 index 000000000000..3bedf2d9e437 --- /dev/null +++ b/test/cmdlineTests/yul_ethdebug_runtime/args @@ -0,0 +1 @@ +--ethdebug-runtime --strict-assembly \ No newline at end of file diff --git a/test/cmdlineTests/yul_ethdebug_runtime/err b/test/cmdlineTests/yul_ethdebug_runtime/err new file mode 100644 index 000000000000..ed5894632c43 --- /dev/null +++ b/test/cmdlineTests/yul_ethdebug_runtime/err @@ -0,0 +1 @@ +Error: The following outputs are not supported in assembler mode: --ethdebug-runtime. diff --git a/test/cmdlineTests/yul_ethdebug_runtime/exit b/test/cmdlineTests/yul_ethdebug_runtime/exit new file mode 100644 index 000000000000..d00491fd7e5b --- /dev/null +++ b/test/cmdlineTests/yul_ethdebug_runtime/exit @@ -0,0 +1 @@ +1 diff --git a/test/cmdlineTests/yul_ethdebug_runtime/input.yul b/test/cmdlineTests/yul_ethdebug_runtime/input.yul new file mode 100644 index 000000000000..acd0b45f5335 --- /dev/null +++ b/test/cmdlineTests/yul_ethdebug_runtime/input.yul @@ -0,0 +1,18 @@ +object "object" { + code { + let a + let b + { + function z() -> y + { y := calldataload(0) } + a := z() + } + { + function z() -> y + { y := calldataload(0x20) } + b := z() + } + sstore(a, b) + } +} + diff --git a/test/libsolidity/StandardCompiler.cpp b/test/libsolidity/StandardCompiler.cpp index 4cb0b3c93068..80cba338202d 100644 --- a/test/libsolidity/StandardCompiler.cpp +++ b/test/libsolidity/StandardCompiler.cpp @@ -33,6 +33,7 @@ #include #include +#include using namespace solidity::evmasm; using namespace std::string_literals; @@ -152,6 +153,147 @@ Json compile(std::string _input) return ret; } +Json createLanguageAndSourcesSection(std::string const& _language, std::map const& _sources, bool _contentNode = true) +{ + Json result = Json::object(); + result["language"] = _language; + result["sources"] = Json::object(); + for (auto const& source: _sources) + { + result["sources"][source.first] = Json::object(); + if (_contentNode) + result["sources"][source.first]["content"] = source.second; + else + result["sources"][source.first] = source.second; + } + return result; +} + +class Code +{ +public: + virtual ~Code() = default; + explicit Code(std::map _code = {}) : m_code(std::move(_code)) {} + [[nodiscard]] virtual Json json() const = 0; +protected: + std::map m_code; +}; + +class SolidityCode: public Code +{ +public: + explicit SolidityCode(std::map _code = { + {"fileA", "pragma solidity >=0.0; contract C { function f() public pure {} }"} + }) : Code(std::move(_code)) {} + [[nodiscard]] Json json() const override + { + return createLanguageAndSourcesSection("Solidity", m_code); + } +}; + +class YulCode: public Code +{ +public: + explicit YulCode(std::map _code = { + {"fileA", "{}"} + }) : Code(std::move(_code)) {} + [[nodiscard]] Json json() const override + { + return createLanguageAndSourcesSection("Yul", m_code); + } +}; + +class EvmAssemblyCode: public Code +{ +public: + explicit EvmAssemblyCode(std::map _code = { + {"fileA", Json::parse(R"( + { + "assemblyJson": { + ".code": [ + { + "begin": 36, + "end": 51, + "name": "PUSH", + "source": 0, + "value": "0" + } + ], + "sourceList": [ + "" + ] + } + } + )")} + }) : Code(std::move(_code)) {} + [[nodiscard]] Json json() const override + { + return createLanguageAndSourcesSection("EVMAssembly", m_code, false); + } +}; + +class SolidityAstCode: public Code +{ +public: + explicit SolidityAstCode(std::map _code = { + {"fileA", Json::parse(R"( + { + "ast": { + "absolutePath": "empty_contract.sol", + "exportedSymbols": { + "test": [ + 1 + ] + }, + "id": 2, + "nodeType": "SourceUnit", + "nodes": [ + { + "abstract": false, + "baseContracts": [], + "canonicalName": "test", + "contractDependencies": [], + "contractKind": "contract", + "fullyImplemented": true, + "id": 1, + "linearizedBaseContracts": [ + 1 + ], + "name": "test", + "nameLocation": "9:4:0", + "nodeType": "ContractDefinition", + "nodes": [], + "scope": 2, + "src": "0:17:0", + "usedErrors": [] + } + ], + "src": "0:124:0" + }, + "id": 0 + } + )")} + }) : Code(std::move(_code)) {} + [[nodiscard]] Json json() const override + { + return createLanguageAndSourcesSection("SolidityAST", m_code); + } +}; + +Json generateStandardJson(bool _viaIr, Json const& _debugInfoSelection, Json const& _outputSelection, Code const& _code = SolidityCode(), bool _advancedOutputSelection = false) +{ + Json result = _code.json(); + result["settings"] = Json::object(); + result["settings"]["viaIR"] = _viaIr; + if (!_debugInfoSelection.empty()) + result["settings"]["debug"]["debugInfo"] = _debugInfoSelection; + if (_advancedOutputSelection) + result["settings"]["outputSelection"] = _outputSelection; + else + result["settings"]["outputSelection"]["*"]["*"] = _outputSelection; + return result; +} + } // end anonymous namespace BOOST_AUTO_TEST_SUITE(StandardCompiler) @@ -1782,6 +1924,375 @@ BOOST_AUTO_TEST_CASE(source_location_of_bare_block) BOOST_REQUIRE(sourceMap.find(sourceRef) != std::string::npos); } +BOOST_AUTO_TEST_CASE(ethdebug_excluded_from_wildcards) +{ + frontend::StandardCompiler compiler; + // excluded from output selection wildcard + Json result = compiler.compile(generateStandardJson(true, {}, Json::array({"*"}))); + BOOST_REQUIRE(result.dump().find("ethdebug") == std::string::npos); + // excluded from debug info selection wildcard + result = compiler.compile(generateStandardJson(true, {"*"}, Json::array({"ir"}))); + BOOST_REQUIRE(result.dump().find("ethdebug") == std::string::npos); + // excluded from both - just in case ;) + result = compiler.compile(generateStandardJson(true, {"*"}, Json::array({"*"}))); + BOOST_REQUIRE(result.dump().find("ethdebug") == std::string::npos); +} + +BOOST_AUTO_TEST_CASE(ethdebug_debug_info_ethdebug) +{ + static std::vector>>> tests{ + { + generateStandardJson(false, Json::array({"ethdebug"}), Json::array({"*"})), + "'settings.debug.debugInfo' can only include 'ethdebug', if output 'ir', 'irOptimized', 'evm.bytecode.ethdebug', or 'evm.deployedBytecode.ethdebug' was selected.", + std::nullopt, + }, + { + generateStandardJson(true, Json::array({"ethdebug"}), Json::array({"*"})), + "'settings.debug.debugInfo' can only include 'ethdebug', if output 'ir', 'irOptimized', 'evm.bytecode.ethdebug', or 'evm.deployedBytecode.ethdebug' was selected.", + std::nullopt, + }, + { + generateStandardJson(false, Json::array({"ethdebug"}), Json::array({"evm.bytecode.ethdebug"})), + "'evm.bytecode.ethdebug' or 'evm.deployedBytecode.ethdebug' can only be selected as output, if 'viaIR' was set.", + std::nullopt, + }, + { + generateStandardJson(false, Json::array({"ethdebug"}), Json::array({"evm.deployedBytecode.ethdebug"})), + "'evm.bytecode.ethdebug' or 'evm.deployedBytecode.ethdebug' can only be selected as output, if 'viaIR' was set.", + std::nullopt, + }, + { + generateStandardJson(false, Json::array({"ethdebug"}), Json::array({"evm.bytecode.ethdebug", "evm.deployedBytecode.ethdebug"})), + "'evm.bytecode.ethdebug' or 'evm.deployedBytecode.ethdebug' can only be selected as output, if 'viaIR' was set.", + std::nullopt, + }, + { + generateStandardJson(false, Json::array({"ethdebug"}), Json::array({"ir"})), + {}, + [](const Json& result) + { + return result.dump().find("/// ethdebug: enabled") != std::string::npos; + } + }, + { + generateStandardJson(false, Json::array({"ethdebug"}), Json::array({"irOptimized"})), + {}, + [](const Json& result) + { + return result.dump().find("/// ethdebug: enabled") != std::string::npos; + } + }, + { + generateStandardJson(true, {}, Json::array({"ir", "evm.bytecode.ethdebug"})), + {}, + [](const Json& result) + { + return result.dump().find("/// ethdebug: enabled") != std::string::npos; + } + }, + { + generateStandardJson(true, {}, Json::array({"ir", "evm.deployedBytecode.ethdebug"})), + {}, + [](const Json& result) + { + return result.dump().find("/// ethdebug: enabled") != std::string::npos; + } + }, + { + generateStandardJson(true, {}, Json::array({"ir", "evm.bytecode.ethdebug", "evm.deployedBytecode.ethdebug"})), + {}, + [](const Json& result) + { + return result.dump().find("/// ethdebug: enabled") != std::string::npos; + } + }, + { + generateStandardJson(true, {}, Json::array({"irOptimized", "evm.bytecode.ethdebug"})), + {}, + [](const Json& result) + { + return result.dump().find("/// ethdebug: enabled") != std::string::npos; + } + }, + { + generateStandardJson(true, {}, Json::array({"irOptimized", "evm.deployedBytecode.ethdebug"})), + {}, + [](const Json& result) + { + return result.dump().find("/// ethdebug: enabled") != std::string::npos; + } + }, + { + generateStandardJson(true, {}, Json::array({"irOptimized", "evm.bytecode.ethdebug", "evm.deployedBytecode.ethdebug"})), + {}, + [](const Json& result) + { + return result.dump().find("/// ethdebug: enabled") != std::string::npos; + } + }, + { + generateStandardJson(true, Json::array({"ethdebug"}), Json::array({"ir"}), YulCode()), + {}, + [](const Json& result) + { + return result.dump().find("/// ethdebug: enabled") != std::string::npos; + } + }, + { + generateStandardJson(true, Json::array({"ethdebug"}), Json::array({"irOptimized"}), YulCode()), + {}, + [](const Json& result) + { + return result.dump().find("/// ethdebug: enabled") != std::string::npos; + } + }, + { + generateStandardJson(true, Json::array({"ethdebugs"}), Json::array({"irOptimized"}), YulCode()), + "Invalid value in settings.debug.debugInfo.", + {} + }, + { + generateStandardJson( + true, Json::array({"ethdebug"}), { + {"fileA", {{"contractA", Json::array({"evm.deployedBytecode.bin"})}}}, + {"fileB", {{"contractB", Json::array({"evm.bytecode.bin"})}}} + }, + SolidityCode({ + {"fileA", "pragma solidity >=0.0; contract contractA { function f() public pure {} }"}, + {"fileB", "pragma solidity >=0.0; contract contractB { function f() public pure {} }"} + }), true + ), + "'settings.debug.debugInfo' can only include 'ethdebug', if output 'ir', 'irOptimized', 'evm.bytecode.ethdebug', or 'evm.deployedBytecode.ethdebug' was selected.", + std::nullopt, + }, + { + generateStandardJson(true, Json::array({"ethdebug"}), Json::array({"*"}), EvmAssemblyCode()), + "'settings.debug.debugInfo' 'ethdebug' is only supported for languages 'Solidity' and 'Yul'.", + std::nullopt, + }, + { + generateStandardJson(true, Json::array({"ethdebug"}), Json::array({"*"}), SolidityAstCode()), + "'settings.debug.debugInfo' 'ethdebug' is only supported for languages 'Solidity' and 'Yul'.", + std::nullopt, + }, + }; + frontend::StandardCompiler compiler; + for (auto const& test: tests) + { + Json result = compiler.compile(std::get<0>(test)); + BOOST_REQUIRE(!std::get<1>(test).empty() ? result.contains("errors") : result.contains("contracts")); + if (!std::get<1>(test).empty()) + for (auto const& e: result["errors"]) + BOOST_REQUIRE(e["message"] == std::get<1>(test)); + if (std::get<2>(test).has_value()) + BOOST_REQUIRE((*std::get<2>(test))(result)); + } +} + +BOOST_AUTO_TEST_CASE(ethdebug_ethdebug_output) +{ + static std::vector>>> tests{ + { + generateStandardJson(false, Json::array({"ethdebug"}), Json::array({"evm.bytecode.ethdebug"})), + "'evm.bytecode.ethdebug' or 'evm.deployedBytecode.ethdebug' can only be selected as output, if 'viaIR' was set.", + std::nullopt + }, + { + generateStandardJson(false, {}, Json::array({"evm.bytecode.ethdebug"})), + "'evm.bytecode.ethdebug' or 'evm.deployedBytecode.ethdebug' can only be selected as output, if 'viaIR' was set.", + std::nullopt + }, + { + generateStandardJson(false, Json::array({"ethdebug"}), Json::array({"evm.deployedBytecode.ethdebug"})), + "'evm.bytecode.ethdebug' or 'evm.deployedBytecode.ethdebug' can only be selected as output, if 'viaIR' was set.", + std::nullopt + }, + { + generateStandardJson(false, {}, Json::array({"evm.deployedBytecode.ethdebug"})), + "'evm.bytecode.ethdebug' or 'evm.deployedBytecode.ethdebug' can only be selected as output, if 'viaIR' was set.", + std::nullopt + }, + { + generateStandardJson(false, Json::array({"ethdebug"}), Json::array({"evm.bytecode.ethdebug", "evm.deployedBytecode.ethdebug"})), + "'evm.bytecode.ethdebug' or 'evm.deployedBytecode.ethdebug' can only be selected as output, if 'viaIR' was set.", + std::nullopt + }, + { + generateStandardJson(false, {}, Json::array({"evm.bytecode.ethdebug", "evm.deployedBytecode.ethdebug"})), + "'evm.bytecode.ethdebug' or 'evm.deployedBytecode.ethdebug' can only be selected as output, if 'viaIR' was set.", + std::nullopt + }, + { + generateStandardJson(true, Json::array({"location"}), Json::array({"evm.bytecode.ethdebug"})), + "'ethdebug' needs to be enabled in 'settings.debug.debugInfo', if 'evm.bytecode.ethdebug' or 'evm.deployedBytecode.ethdebug' was selected as output.", + std::nullopt + }, + { + generateStandardJson(true, Json::array({"location"}), Json::array({"evm.deployedBytecode.ethdebug"})), + "'ethdebug' needs to be enabled in 'settings.debug.debugInfo', if 'evm.bytecode.ethdebug' or 'evm.deployedBytecode.ethdebug' was selected as output.", + std::nullopt + }, + { + generateStandardJson(true, Json::array({"location"}), Json::array({"evm.bytecode.ethdebug", "evm.deployedBytecode.ethdebug"})), + "'ethdebug' needs to be enabled in 'settings.debug.debugInfo', if 'evm.bytecode.ethdebug' or 'evm.deployedBytecode.ethdebug' was selected as output.", + std::nullopt + }, + { + generateStandardJson(true, Json::array({"ethdebug"}), Json::array({"evm.bytecode.ethdebug"})), + {}, + [](const Json& result) + { + return result.contains("ethdebug") && result["contracts"]["fileA"]["C"]["evm"]["bytecode"].contains("ethdebug"); + } + }, + { + generateStandardJson(true, Json::array({"ethdebug"}), Json::array({"evm.deployedBytecode.ethdebug"})), + {}, + [](const Json& result) + { + return result.contains("ethdebug") && result["contracts"]["fileA"]["C"]["evm"]["deployedBytecode"].contains("ethdebug"); + } + }, + { + generateStandardJson(true, Json::array({"ethdebug"}), Json::array({"evm.bytecode.ethdebug", "evm.deployedBytecode.ethdebug"})), + {}, + [](const Json& result) + { + return result.contains("ethdebug") && result["contracts"]["fileA"]["C"]["evm"]["deployedBytecode"].contains("ethdebug") && + result["contracts"]["fileA"]["C"]["evm"]["bytecode"].contains("ethdebug"); + } + }, + { + generateStandardJson(true, {}, Json::array({"evm.bytecode.ethdebug"})), + {}, + [](const Json& result) + { + return result.contains("ethdebug") && result["contracts"]["fileA"]["C"]["evm"]["bytecode"].contains("ethdebug"); + } + }, + { + generateStandardJson(true, {}, Json::array({"evm.deployedBytecode.ethdebug"})), + {}, + [](const Json& result) + { + return result.contains("ethdebug") && result["contracts"]["fileA"]["C"]["evm"]["deployedBytecode"].contains("ethdebug"); + } + }, + { + generateStandardJson(true, {}, Json::array({"evm.bytecode.ethdebug", "evm.deployedBytecode.ethdebug"})), + {}, + [](const Json& result) + { + return result.contains("ethdebug") && result["contracts"]["fileA"]["C"]["evm"]["deployedBytecode"].contains("ethdebug") && + result["contracts"]["fileA"]["C"]["evm"]["bytecode"].contains("ethdebug"); + } + }, + { + generateStandardJson(true, {}, Json::array({"evm.bytecode.ethdebug", "ir"})), + {}, + [](const Json& result) + { + return result.dump().find("/// ethdebug: enabled") != std::string::npos && result.contains("ethdebug") && result["contracts"]["fileA"]["C"]["evm"]["bytecode"].contains("ethdebug"); + } + }, + { + generateStandardJson(true, {}, Json::array({"evm.deployedBytecode.ethdebug", "ir"})), + {}, + [](const Json& result) + { + return result.dump().find("/// ethdebug: enabled") != std::string::npos && result.contains("ethdebug") && result["contracts"]["fileA"]["C"]["evm"]["deployedBytecode"].contains("ethdebug"); + } + }, + { + generateStandardJson(true, {}, Json::array({"evm.bytecode.ethdebugs"})), + {}, + [](const Json& result) + { + return !result.contains("ethdebug"); + } + }, + { + generateStandardJson(true, {}, Json::array({"evm.deployedBytecode.ethdebugs"})), + {}, + [](const Json& result) + { + return !result.contains("ethdebug"); + } + }, + { + generateStandardJson(true, {}, Json::array({"evm.bytecode.ethdebug", "evm.deployedBytecode.ethdebug", "ir"})), + {}, + [](const Json& result) + { + return result.dump().find("/// ethdebug: enabled") != std::string::npos && result.contains("ethdebug") && result["contracts"]["fileA"]["C"]["evm"]["deployedBytecode"].contains("ethdebug") && + result["contracts"]["fileA"]["C"]["evm"]["bytecode"].contains("ethdebug"); + } + }, + { + generateStandardJson(true, {}, Json::array({"evm.bytecode.ethdebug", "ir"}), YulCode()), + {}, + [](const Json& result) + { + return result.dump().find("/// ethdebug: enabled") != std::string::npos && result["contracts"]["fileA"]["object"]["evm"]["bytecode"].contains("ethdebug"); + } + }, + { + generateStandardJson(true, {}, Json::array({"evm.deployedBytecode.ethdebug", "ir"}), YulCode()), + {"\"evm.deployedBytecode.ethdebug\" cannot be used for Yul."}, + std::nullopt + }, + { + generateStandardJson(true, {}, Json::array({"evm.bytecode.ethdebug", "evm.deployedBytecode.ethdebug", "ir"}), YulCode()), + {"\"evm.deployedBytecode.ethdebug\" cannot be used for Yul."}, + std::nullopt + }, + { + generateStandardJson(true, {}, Json::array({"evm.bytecode"})), + {}, + [](const Json& result) + { + return result.dump().find("ethdebug") == std::string::npos; + } + }, + { + generateStandardJson(true, {}, Json::array({"evm.deployedBytecode"})), + {}, + [](const Json& result) + { + return result.dump().find("ethdebug") == std::string::npos; + } + }, + { + generateStandardJson( + true, {}, { + {"fileA", {{"contractA", Json::array({"evm.deployedBytecode.ethdebug"})}}}, + {"fileB", {{"contractB", Json::array({"evm.bytecode.ethdebug"})}}} + }, + SolidityCode({ + {"fileA", "pragma solidity >=0.0; contract contractA { function f() public pure {} }"}, + {"fileB", "pragma solidity >=0.0; contract contractB { function f() public pure {} }"} + }), true + ), + {}, + [](const Json& result) + { + return result["contracts"]["fileA"]["contractA"]["evm"]["deployedBytecode"].contains("ethdebug") && + result["contracts"]["fileB"]["contractB"]["evm"]["bytecode"].contains("ethdebug") && result.contains("ethdebug"); + } + } + }; + frontend::StandardCompiler compiler; + for (auto const& test: tests) + { + Json result = compiler.compile(std::get<0>(test)); + if (!std::get<1>(test).empty()) + for (auto const& e: result["errors"]) + BOOST_REQUIRE(e["message"] == std::get<1>(test)); + if (std::get<2>(test).has_value()) + BOOST_REQUIRE((*std::get<2>(test))(result)); + } +} + BOOST_AUTO_TEST_SUITE_END() } // end namespaces diff --git a/test/libyul/Common.cpp b/test/libyul/Common.cpp index e64558bd48a9..a9f4c59a74ac 100644 --- a/test/libyul/Common.cpp +++ b/test/libyul/Common.cpp @@ -63,7 +63,7 @@ YulStack yul::test::parseYul( _optimiserSettings.has_value() ? *_optimiserSettings : (CommonOptions::get().optimize ? OptimiserSettings::standard() : OptimiserSettings::minimal()), - DebugInfoSelection::All() + DebugInfoSelection::AllExceptExperimental() ); bool successful = yulStack.parseAndAnalyze(_sourceUnitName, _source); if (!successful) diff --git a/test/libyul/EVMCodeTransformTest.cpp b/test/libyul/EVMCodeTransformTest.cpp index 624a44c3e538..4fff5a22e70d 100644 --- a/test/libyul/EVMCodeTransformTest.cpp +++ b/test/libyul/EVMCodeTransformTest.cpp @@ -58,7 +58,7 @@ TestCase::TestResult EVMCodeTransformTest::run(std::ostream& _stream, std::strin CommonOptions::get().eofVersion(), YulStack::Language::StrictAssembly, settings, - DebugInfoSelection::All() + DebugInfoSelection::AllExceptExperimental() ); yulStack.parseAndAnalyze("", m_source); if (yulStack.hasErrors()) diff --git a/test/libyul/ObjectParser.cpp b/test/libyul/ObjectParser.cpp index 23d8aaa57f8e..446348fa0ba3 100644 --- a/test/libyul/ObjectParser.cpp +++ b/test/libyul/ObjectParser.cpp @@ -151,7 +151,7 @@ BOOST_AUTO_TEST_CASE(to_string) solidity::test::CommonOptions::get().eofVersion(), YulStack::Language::StrictAssembly, solidity::frontend::OptimiserSettings::none(), - DebugInfoSelection::All() + DebugInfoSelection::AllExceptExperimental() ); BOOST_REQUIRE(asmStack.parseAndAnalyze("source", code)); BOOST_CHECK_EQUAL(asmStack.print(), expectation); diff --git a/test/solc/CommandLineInterface.cpp b/test/solc/CommandLineInterface.cpp index 6d19df01b3f8..8dfcedac8548 100644 --- a/test/solc/CommandLineInterface.cpp +++ b/test/solc/CommandLineInterface.cpp @@ -1412,6 +1412,356 @@ BOOST_AUTO_TEST_CASE(cli_include_paths_ambiguous_import) BOOST_REQUIRE(!result.success); } +BOOST_AUTO_TEST_CASE(cli_ethdebug_no_ethdebug_in_help) +{ + OptionsReaderAndMessages result = runCLI({"solc", "--help"}); + BOOST_REQUIRE(result.stdoutContent.find("ethdebug") == std::string::npos); + // just in case + BOOST_REQUIRE(result.stderrContent.find("ethdebug") == std::string::npos); +} + +BOOST_AUTO_TEST_CASE(cli_ethdebug_incompatible_outputs) +{ + TemporaryDirectory tempDir(TEST_CASE_NAME); + createFilesWithParentDirs({tempDir.path() / "input.sol"}); + static std::vector, std::string>> tests{ + { + {"solc", "--ethdebug", "--asm-json", tempDir.path().string() + "/input.sol"}, + "Error: --ethdebug / --ethdebug-runtime output can only be selected, if --via-ir was specified.\n" + }, + { + {"solc", "--via-ir", "--ethdebug", "--asm-json", tempDir.path().string() + "/input.sol"}, + "Error: --ethdebug / --ethdebug-runtime output can only be used with --ir / --ir-optimized.\n" + }, + { + {"solc", "--via-ir", "--ethdebug", "--ir-ast-json", tempDir.path().string() + "/input.sol"}, + "Error: --ethdebug / --ethdebug-runtime output can only be used with --ir / --ir-optimized.\n" + }, + { + {"solc", "--via-ir", "--ethdebug", "--ir-optimized-ast-json", tempDir.path().string() + "/input.sol"}, + "Error: --ethdebug / --ethdebug-runtime output can only be used with --ir / --ir-optimized.\n" + }, + { + {"solc", "--ethdebug", "--import-asm-json", tempDir.path().string() + "/input.json"}, + "Error: Option --ethdebug is not supported with --import-asm-json.\n" + }, + { + {"solc", "--via-ir", "--ethdebug", "--asm-json", tempDir.path().string() + "/input.sol"}, + "Error: --ethdebug / --ethdebug-runtime output can only be used with --ir / --ir-optimized.\n" + }, + { + {"solc", "--ethdebug-runtime", "--asm-json", tempDir.path().string() + "/input.sol"}, + "Error: --ethdebug / --ethdebug-runtime output can only be selected, if --via-ir was specified.\n" + }, + { + {"solc", "--via-ir", "--ethdebug-runtime", "--asm-json", tempDir.path().string() + "/input.sol"}, + "Error: --ethdebug / --ethdebug-runtime output can only be used with --ir / --ir-optimized.\n" + }, + { + {"solc", "--via-ir", "--ethdebug-runtime", "--ir-ast-json", tempDir.path().string() + "/input.sol"}, + "Error: --ethdebug / --ethdebug-runtime output can only be used with --ir / --ir-optimized.\n" + }, + { + {"solc", "--via-ir", "--ethdebug-runtime", "--ir-optimized-ast-json", tempDir.path().string() + "/input.sol"}, + "Error: --ethdebug / --ethdebug-runtime output can only be used with --ir / --ir-optimized.\n" + }, + { + {"solc", "--ethdebug-runtime", "--import-asm-json", tempDir.path().string() + "/input.json"}, + "Error: Option --ethdebug-runtime is not supported with --import-asm-json.\n" + }, + { + {"solc", "--via-ir", "--ethdebug-runtime", "--asm-json", tempDir.path().string() + "/input.sol"}, + "Error: --ethdebug / --ethdebug-runtime output can only be used with --ir / --ir-optimized.\n" + }, + { + {"solc", "--debug-info", "ethdebug", "--asm-json", tempDir.path().string() + "/input.sol"}, + "Error: --debug-info ethdebug can only be used with --ir / --ir-optimized and/or --ethdebug / --ethdebug-runtime.\n" + }, + { + {"solc", "--debug-info", "ethdebug", "--asm-json", tempDir.path().string() + "/input.sol"}, + "Error: --debug-info ethdebug can only be used with --ir / --ir-optimized and/or --ethdebug / --ethdebug-runtime.\n" + }, + { + {"solc", "--debug-info", "ethdebug", "--ir-ast-json", tempDir.path().string() + "/input.sol"}, + "Error: --debug-info ethdebug can only be used with --ir / --ir-optimized and/or --ethdebug / --ethdebug-runtime.\n" + }, + { + {"solc", "--debug-info", "ethdebug", "--ir-optimized-ast-json", tempDir.path().string() + "/input.sol"}, + "Error: --debug-info ethdebug can only be used with --ir / --ir-optimized and/or --ethdebug / --ethdebug-runtime.\n" + }, + { + {"solc", "--debug-info", "ethdebug", "--import-asm-json", tempDir.path().string() + "/input.json"}, + "Error: Option --debug-info is not supported with --import-asm-json.\n" + }, + { + {"solc", "--debug-info", "ethdebug", "--import-asm-json", tempDir.path().string() + "/input.json"}, + "Error: Option --debug-info is not supported with --import-asm-json.\n" + }, + { + {"solc", "--debug-info", "ethdebug", "--asm-json", tempDir.path().string() + "/input.json"}, + "Error: --debug-info ethdebug can only be used with --ir / --ir-optimized and/or --ethdebug / --ethdebug-runtime.\n" + } + }; + for (auto const& test: tests) + { + OptionsReaderAndMessages result = runCLI(test.first, ""); + BOOST_REQUIRE(!result.success); + BOOST_CHECK_EQUAL(result.stderrContent, test.second); + } +} + +BOOST_AUTO_TEST_CASE(cli_ethdebug_incompatible_input_modes) +{ + TemporaryDirectory tempDir(TEST_CASE_NAME); + createFilesWithParentDirs({tempDir.path() / "input.json"}); + static std::vector, std::string>> tests{ + { + {"solc", "--ethdebug", "--import-asm-json", tempDir.path().string() + "/input.json"}, + "Error: Option --ethdebug is not supported with --import-asm-json.\n" + }, + { + {"solc", "--ethdebug", "--via-ir", "--import-asm-json", tempDir.path().string() + "/input.json"}, + "Error: The following options are not supported in the current input mode: --via-ir\n" + }, + { + {"solc", "--ethdebug", "--import-asm-json", tempDir.path().string() + "/input.json"}, + "Error: Option --ethdebug is not supported with --import-asm-json.\n" + }, + { + {"solc", "--debug-info", "ethdebug", "--import-asm-json", tempDir.path().string() + "/input.json"}, + "Error: Option --debug-info is not supported with --import-asm-json.\n" + }, + { + {"solc", "--ethdebug", "--import-ast", tempDir.path().string() + "/input.json"}, + "Error: --ethdebug / --ethdebug-runtime output can only be selected, if --via-ir was specified.\n" + }, + { + {"solc", "--ethdebug", "--via-ir", "--import-ast", tempDir.path().string() + "/input.json"}, + "Error: Invalid input mode for --debug-info ethdebug / --ethdebug / --ethdebug-runtime.\n" + }, + { + {"solc", "--debug-info", "ethdebug", "--ir", "--import-ast", tempDir.path().string() + "/input.json"}, + "Error: Invalid input mode for --debug-info ethdebug / --ethdebug / --ethdebug-runtime.\n" + } + }; + for (auto const& test: tests) + { + OptionsReaderAndMessages result = runCLI(test.first, ""); + BOOST_REQUIRE(!result.success); + BOOST_CHECK_EQUAL(result.stderrContent, test.second); + } +} + +BOOST_AUTO_TEST_CASE(cli_ethdebug_debug_info_ethdebug) +{ + TemporaryDirectory tempDir(TEST_CASE_NAME); + createFilesWithParentDirs({tempDir.path() / "input.sol"}, "pragma solidity >=0.0; contract C { function f() public pure {} }"); + createFilesWithParentDirs({tempDir.path() / "input.yul"}, "{}"); + static std::vector, std::vector, std::vector>> tests{ + { + {"solc", "--debug-info", "ethdebug", tempDir.path().string() + "/input.sol"}, + {"Error: --debug-info ethdebug can only be used with --ir / --ir-optimized and/or --ethdebug / --ethdebug-runtime.\n"}, + {}, + }, + { + {"solc", "--debug-info", "ethdebug", "--ir", tempDir.path().string() + "/input.sol"}, + {}, + {"/// ethdebug: enabled"}, + }, + { + {"solc", "--debug-info", "ethdebug", "--ir-optimized", tempDir.path().string() + "/input.sol"}, + {}, + {"/// ethdebug: enabled"}, + }, + { + {"solc", "--debug-info", "ethdebug", "--ethdebug", tempDir.path().string() + "/input.sol"}, + {"Error: --ethdebug / --ethdebug-runtime output can only be selected, if --via-ir was specified.\n"}, + {}, + }, + { + {"solc", "--debug-info", "ethdebug", "--ethdebug", "--via-ir", tempDir.path().string() + "/input.sol"}, + {}, + {"======= Debug Data (ethdebug/format/info/resources) =======", "Debug Data (ethdebug/format/program):"}, + }, + { + {"solc", "--debug-info", "ethdebug", "--ethdebug-runtime", "--via-ir", tempDir.path().string() + "/input.sol"}, + {}, + {"======= Debug Data (ethdebug/format/info/resources) =======", "Debug Data of the runtime part (ethdebug/format/program):"}, + }, + { + {"solc", "--debug-info", "ethdebug", "--strict-assembly", tempDir.path().string() + "/input.yul"}, + {}, + {"/// ethdebug: enabled", "Pretty printed source", "Binary representation", "Text representation"}, + }, + { + {"solc", "--ethdebug", "--strict-assembly", tempDir.path().string() + "/input.yul"}, + {}, + {"======= Debug Data (ethdebug/format/info/resources) =======", "Debug Data (ethdebug/format/program):"}, + }, + { + {"solc", "--ethdebug-runtime", "--strict-assembly", tempDir.path().string() + "/input.yul"}, + {"Error: The following outputs are not supported in assembler mode: --ethdebug-runtime.\n"}, + {}, + }, + { + {"solc", "--ethdebug", "--ethdebug-runtime", "--strict-assembly", tempDir.path().string() + "/input.yul"}, + {"Error: The following outputs are not supported in assembler mode: --ethdebug-runtime.\n"}, + {}, + }, + { + {"solc", "--debug-info", "ethdebug", "--ethdebug", tempDir.path().string() + "/input.sol"}, + {"Error: --ethdebug / --ethdebug-runtime output can only be selected, if --via-ir was specified.\n"}, + {}, + }, + { + {"solc", "--debug-info", "ethdebug", "--ethdebug-runtime", tempDir.path().string() + "/input.sol"}, + {"Error: --ethdebug / --ethdebug-runtime output can only be selected, if --via-ir was specified.\n"}, + {}, + }, + { + {"solc", "--debug-info", "ethdebug", "--ethdebug", "--ethdebug-runtime", tempDir.path().string() + "/input.sol"}, + {"Error: --ethdebug / --ethdebug-runtime output can only be selected, if --via-ir was specified.\n"}, + {}, + }, + { + {"solc", "--debug-info", "ethdebug", "--ethdebug", "--ethdebug-runtime", "--via-ir", tempDir.path().string() + "/input.sol"}, + {}, + {"======= Debug Data (ethdebug/format/info/resources) =======", "Debug Data (ethdebug/format/program):", "Debug Data of the runtime part (ethdebug/format/program):"}, + }, + { + {"solc", "--debug-info", "location", "--ethdebug", "--via-ir", tempDir.path().string() + "/input.sol"}, + {"Error: --debug-info must contain ethdebug, when compiling with --ethdebug / --ethdebug-runtime.\n"}, + {}, + }, + { + {"solc", "--debug-info", "location", "--ethdebug-runtime", "--via-ir", tempDir.path().string() + "/input.sol"}, + {"Error: --debug-info must contain ethdebug, when compiling with --ethdebug / --ethdebug-runtime.\n"}, + {}, + }, + { + {"solc", "--debug-info", "location", "--ethdebug", "--ethdebug-runtime", "--via-ir", tempDir.path().string() + "/input.sol"}, + {"Error: --debug-info must contain ethdebug, when compiling with --ethdebug / --ethdebug-runtime.\n"}, + {}, + }, + { + {"solc", "--debug-info", "all", "--ethdebug", "--via-ir", tempDir.path().string() + "/input.sol"}, + {"Error: --debug-info must contain ethdebug, when compiling with --ethdebug / --ethdebug-runtime.\n"}, + {}, + }, + { + {"solc", "--debug-info", "all", "--ethdebug-runtime", "--via-ir", tempDir.path().string() + "/input.sol"}, + {"Error: --debug-info must contain ethdebug, when compiling with --ethdebug / --ethdebug-runtime.\n"}, + {}, + }, + { + {"solc", "--debug-info", "all", "--ethdebug", "--ethdebug-runtime", "--via-ir", tempDir.path().string() + "/input.sol"}, + {"Error: --debug-info must contain ethdebug, when compiling with --ethdebug / --ethdebug-runtime.\n"}, + {}, + }, + }; + for (auto const& test: tests) + { + OptionsReaderAndMessages result{runCLI(std::get<0>(test), "")}; + BOOST_REQUIRE(!std::get<1>(test).empty() ? !result.success : result.success); + for (auto const& error : std::get<1>(test)) + BOOST_REQUIRE(result.stderrContent == error); + for (auto const& output : std::get<2>(test)) + BOOST_REQUIRE(result.stdoutContent.find(output) != std::string::npos); + } +} + +BOOST_AUTO_TEST_CASE(cli_ethdebug_ethdebug_output) +{ + TemporaryDirectory tempDir(TEST_CASE_NAME); + createFilesWithParentDirs({tempDir.path() / "input.sol"}, "pragma solidity >=0.0; contract C { function f() public pure {} }"); + static std::vector, std::vector, std::vector>> tests{ + { + {"solc", "--ethdebug", tempDir.path().string() + "/input.sol"}, + {"Error: --ethdebug / --ethdebug-runtime output can only be selected, if --via-ir was specified.\n"}, + {}, + }, + { + {"solc", "--ethdebug", "--ethdebug-runtime", tempDir.path().string() + "/input.sol"}, + {"Error: --ethdebug / --ethdebug-runtime output can only be selected, if --via-ir was specified.\n"}, + {}, + }, + { + {"solc", "--ethdebug-runtime", tempDir.path().string() + "/input.sol"}, + {"Error: --ethdebug / --ethdebug-runtime output can only be selected, if --via-ir was specified.\n"}, + {}, + }, + { + {"solc", "--ethdebug", "--via-ir", tempDir.path().string() + "/input.sol"}, + {}, + {"======= Debug Data (ethdebug/format/info/resources) =======", "Debug Data (ethdebug/format/program)"}, + }, + { + {"solc", "--ethdebug-runtime", "--via-ir", tempDir.path().string() + "/input.sol"}, + {}, + {"======= Debug Data (ethdebug/format/info/resources) =======", "Debug Data of the runtime part (ethdebug/format/program)"}, + }, + { + {"solc", "--ethdebug", "--ethdebug-runtime", "--via-ir", tempDir.path().string() + "/input.sol"}, + {}, + {"======= Debug Data (ethdebug/format/info/resources) =======", "Debug Data (ethdebug/format/program)", "Debug Data of the runtime part (ethdebug/format/program)"}, + }, + { + {"solc", "--ethdebug", "--via-ir", "--ir", tempDir.path().string() + "/input.sol"}, + {}, + {"======= Debug Data (ethdebug/format/info/resources) =======", "Debug Data (ethdebug/format/program)", "/// ethdebug: enabled"}, + }, + { + {"solc", "--ethdebug-runtime", "--via-ir", "--ir", tempDir.path().string() + "/input.sol"}, + {}, + {"======= Debug Data (ethdebug/format/info/resources) =======", "Debug Data of the runtime part (ethdebug/format/program)", "/// ethdebug: enabled"}, + }, + { + {"solc", "--ethdebug", "--ethdebug-runtime", "--via-ir", "--ir", tempDir.path().string() + "/input.sol"}, + {}, + {"======= Debug Data (ethdebug/format/info/resources) =======", "Debug Data (ethdebug/format/program)", "Debug Data of the runtime part (ethdebug/format/program)", "/// ethdebug: enabled"}, + }, + { + {"solc", "--ethdebug", "--via-ir", "--ir-optimized", tempDir.path().string() + "/input.sol"}, + {}, + {"======= Debug Data (ethdebug/format/info/resources) =======", "Debug Data (ethdebug/format/program)", "/// ethdebug: enabled"}, + }, + { + {"solc", "--ethdebug-runtime", "--via-ir", "--ir-optimized", tempDir.path().string() + "/input.sol"}, + {}, + {"======= Debug Data (ethdebug/format/info/resources) =======", "Debug Data of the runtime part (ethdebug/format/program)", "/// ethdebug: enabled"}, + }, + { + {"solc", "--ethdebug", "--ethdebug-runtime", "--via-ir", "--ir-optimized", tempDir.path().string() + "/input.sol"}, + {}, + {"======= Debug Data (ethdebug/format/info/resources) =======", "Debug Data (ethdebug/format/program)", "Debug Data of the runtime part (ethdebug/format/program)", "/// ethdebug: enabled"}, + }, + { + {"solc", "--ethdebug", "--via-ir", "--ir-optimized", "--optimize", tempDir.path().string() + "/input.sol"}, + {}, + {"======= Debug Data (ethdebug/format/info/resources) =======", "Debug Data (ethdebug/format/program)", "/// ethdebug: enabled"}, + }, + { + {"solc", "--ethdebug-runtime", "--via-ir", "--ir-optimized", "--optimize", tempDir.path().string() + "/input.sol"}, + {}, + {"======= Debug Data (ethdebug/format/info/resources) =======", "Debug Data of the runtime part (ethdebug/format/program)", "/// ethdebug: enabled"}, + }, + { + {"solc", "--ethdebug", "--ethdebug-runtime", "--via-ir", "--ir-optimized", "--optimize", tempDir.path().string() + "/input.sol"}, + {}, + {"======= Debug Data (ethdebug/format/info/resources) =======", "Debug Data (ethdebug/format/program)", "Debug Data of the runtime part (ethdebug/format/program)", "/// ethdebug: enabled"}, + }, + }; + for (auto const& test: tests) + { + OptionsReaderAndMessages result{runCLI(std::get<0>(test), "")}; + BOOST_REQUIRE(!std::get<1>(test).empty() ? !result.success : result.success); + for (auto const& error : std::get<1>(test)) + BOOST_REQUIRE(result.stderrContent == error); + for (auto const& output : std::get<2>(test)) + BOOST_REQUIRE(result.stdoutContent.find(output) != std::string::npos); + } +} + BOOST_AUTO_TEST_SUITE_END() } // namespace solidity::frontend::test diff --git a/test/solc/CommandLineParser.cpp b/test/solc/CommandLineParser.cpp index 227b1b9213d8..be3e25d3302c 100644 --- a/test/solc/CommandLineParser.cpp +++ b/test/solc/CommandLineParser.cpp @@ -628,6 +628,49 @@ BOOST_AUTO_TEST_CASE(invalid_optimizer_sequence_without_optimize) } } +BOOST_AUTO_TEST_CASE(ethdebug) +{ + CommandLineOptions commandLineOptions = parseCommandLine({"solc", "contract.sol", "--debug-info", "ethdebug", "--ethdebug", "--via-ir"}); + BOOST_CHECK_EQUAL(commandLineOptions.compiler.outputs.ethdebug, true); + BOOST_CHECK_EQUAL(commandLineOptions.compiler.outputs.ethdebugRuntime, false); + BOOST_CHECK_EQUAL(commandLineOptions.output.debugInfoSelection.has_value(), true); + BOOST_CHECK_EQUAL(commandLineOptions.output.debugInfoSelection->ethdebug, true); + commandLineOptions = parseCommandLine({"solc", "contract.sol", "--debug-info", "ethdebug", "--ethdebug-runtime", "--via-ir"}); + BOOST_CHECK_EQUAL(commandLineOptions.compiler.outputs.ethdebug, false); + BOOST_CHECK_EQUAL(commandLineOptions.compiler.outputs.ethdebugRuntime, true); + BOOST_CHECK_EQUAL(commandLineOptions.output.debugInfoSelection.has_value(), true); + BOOST_CHECK_EQUAL(commandLineOptions.output.debugInfoSelection->ethdebug, true); + commandLineOptions = parseCommandLine({"solc", "contract.sol", "--ethdebug", "--via-ir"}); + BOOST_CHECK_EQUAL(commandLineOptions.compiler.outputs.ethdebug, true); + BOOST_CHECK_EQUAL(commandLineOptions.compiler.outputs.ethdebugRuntime, false); + // debug-info "ethdebug" selected implicitly, + // if compiled with --ethdebug or --ethdebug-runtime and no debug-info was selected. + BOOST_CHECK_EQUAL(commandLineOptions.output.debugInfoSelection.has_value(), true); + BOOST_CHECK_EQUAL(commandLineOptions.output.debugInfoSelection->ethdebug, true); + commandLineOptions = parseCommandLine({"solc", "contract.sol", "--ethdebug-runtime", "--via-ir"}); + BOOST_CHECK_EQUAL(commandLineOptions.compiler.outputs.ethdebug, false); + BOOST_CHECK_EQUAL(commandLineOptions.compiler.outputs.ethdebugRuntime, true); + BOOST_CHECK_EQUAL(commandLineOptions.output.debugInfoSelection.has_value(), true); + BOOST_CHECK_EQUAL(commandLineOptions.output.debugInfoSelection->ethdebug, true); + commandLineOptions = parseCommandLine({"solc", "contract.sol", "--ethdebug", "--ethdebug-runtime", "--via-ir"}); + BOOST_CHECK_EQUAL(commandLineOptions.compiler.outputs.ethdebug, true); + BOOST_CHECK_EQUAL(commandLineOptions.compiler.outputs.ethdebugRuntime, true); + BOOST_CHECK_EQUAL(commandLineOptions.output.debugInfoSelection.has_value(), true); + BOOST_CHECK_EQUAL(commandLineOptions.output.debugInfoSelection->ethdebug, true); + commandLineOptions = parseCommandLine({"solc", "contract.sol", "--debug-info", "ethdebug", "--ir"}); + BOOST_CHECK_EQUAL(commandLineOptions.compiler.outputs.ethdebug, false); + BOOST_CHECK_EQUAL(commandLineOptions.compiler.outputs.ethdebugRuntime, false); + BOOST_CHECK_EQUAL(commandLineOptions.compiler.outputs.ir, true); + BOOST_CHECK_EQUAL(commandLineOptions.output.debugInfoSelection.has_value(), true); + BOOST_CHECK_EQUAL(commandLineOptions.output.debugInfoSelection->ethdebug, true); + commandLineOptions = parseCommandLine({"solc", "contract.sol", "--debug-info", "ethdebug", "--ir-optimized"}); + BOOST_CHECK_EQUAL(commandLineOptions.compiler.outputs.ethdebug, false); + BOOST_CHECK_EQUAL(commandLineOptions.compiler.outputs.ethdebugRuntime, false); + BOOST_CHECK_EQUAL(commandLineOptions.compiler.outputs.irOptimized, true); + BOOST_CHECK_EQUAL(commandLineOptions.output.debugInfoSelection.has_value(), true); + BOOST_CHECK_EQUAL(commandLineOptions.output.debugInfoSelection->ethdebug, true); +} + BOOST_AUTO_TEST_SUITE_END() } // namespace solidity::frontend::test diff --git a/test/tools/ossfuzz/strictasm_assembly_ossfuzz.cpp b/test/tools/ossfuzz/strictasm_assembly_ossfuzz.cpp index 595aecdca3f4..5a9192bc3a05 100644 --- a/test/tools/ossfuzz/strictasm_assembly_ossfuzz.cpp +++ b/test/tools/ossfuzz/strictasm_assembly_ossfuzz.cpp @@ -41,7 +41,7 @@ extern "C" int LLVMFuzzerTestOneInput(uint8_t const* _data, size_t _size) std::nullopt, YulStack::Language::StrictAssembly, solidity::frontend::OptimiserSettings::minimal(), - langutil::DebugInfoSelection::All() + langutil::DebugInfoSelection::AllExceptExperimental() ); if (!stack.parseAndAnalyze("source", input)) diff --git a/test/tools/ossfuzz/strictasm_diff_ossfuzz.cpp b/test/tools/ossfuzz/strictasm_diff_ossfuzz.cpp index ffeb14702183..a4515b30957a 100644 --- a/test/tools/ossfuzz/strictasm_diff_ossfuzz.cpp +++ b/test/tools/ossfuzz/strictasm_diff_ossfuzz.cpp @@ -65,7 +65,7 @@ extern "C" int LLVMFuzzerTestOneInput(uint8_t const* _data, size_t _size) std::nullopt, YulStack::Language::StrictAssembly, solidity::frontend::OptimiserSettings::full(), - DebugInfoSelection::All() + DebugInfoSelection::AllExceptExperimental() ); try { diff --git a/test/tools/ossfuzz/strictasm_opt_ossfuzz.cpp b/test/tools/ossfuzz/strictasm_opt_ossfuzz.cpp index 7553c81c0f44..4543804926ee 100644 --- a/test/tools/ossfuzz/strictasm_opt_ossfuzz.cpp +++ b/test/tools/ossfuzz/strictasm_opt_ossfuzz.cpp @@ -42,7 +42,7 @@ extern "C" int LLVMFuzzerTestOneInput(uint8_t const* _data, size_t _size) std::nullopt, YulStack::Language::StrictAssembly, solidity::frontend::OptimiserSettings::full(), - DebugInfoSelection::All() + DebugInfoSelection::AllExceptExperimental() ); if (!stack.parseAndAnalyze("source", input)) From 7ea985d54daa79ca623623b719eb4aa9d26f0411 Mon Sep 17 00:00:00 2001 From: Alexander Arlt Date: Thu, 16 Jan 2025 15:24:13 +0100 Subject: [PATCH 0735/1022] Error when ethdebug is used with optimization. --- libsolidity/interface/StandardCompiler.cpp | 3 + solc/CommandLineParser.cpp | 15 +- test/cmdlineTests/ethdebug/args | 2 +- test/cmdlineTests/ethdebug/output | 111 ++- .../ethdebug_and_ethdebug_runtime/args | 2 +- .../ethdebug_and_ethdebug_runtime/output | 111 ++- .../ethdebug_enabled_optimization/args | 1 + .../ethdebug_enabled_optimization/err | 1 + .../ethdebug_enabled_optimization/exit | 1 + .../ethdebug_enabled_optimization/input.sol | 7 + test/cmdlineTests/ethdebug_runtime/args | 2 +- test/cmdlineTests/ethdebug_runtime/output | 111 ++- .../input.json | 4 +- .../output.json | 692 +++++++++++++++--- .../input.json | 4 +- .../output.json | 692 +++++++++++++++--- .../input.json | 24 + .../output.json | 11 + .../input.json | 4 +- .../output.json | 692 +++++++++++++++--- .../input.json | 21 + .../output.json | 11 + .../input.json | 24 + .../output.json | 11 + .../standard_yul_ethdebug_bytecode/input.json | 5 +- .../output.json | 12 +- .../standard_yul_ethdebug_irOptimized/args | 1 + .../standard_yul_ethdebug_irOptimized/in.yul | 17 + .../input.json | 11 + .../output.json | 11 + .../standard_yul_ethdebug_optimize/args | 1 + .../standard_yul_ethdebug_optimize/in.yul | 17 + .../standard_yul_ethdebug_optimize/input.json | 14 + .../output.json | 11 + test/libsolidity/StandardCompiler.cpp | 17 +- test/solc/CommandLineInterface.cpp | 55 +- test/solc/CommandLineParser.cpp | 6 - 37 files changed, 2362 insertions(+), 373 deletions(-) create mode 100644 test/cmdlineTests/ethdebug_enabled_optimization/args create mode 100644 test/cmdlineTests/ethdebug_enabled_optimization/err create mode 100644 test/cmdlineTests/ethdebug_enabled_optimization/exit create mode 100644 test/cmdlineTests/ethdebug_enabled_optimization/input.sol create mode 100644 test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_optimizer/input.json create mode 100644 test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_optimizer/output.json create mode 100644 test/cmdlineTests/standard_output_selection_ethdebug_irOptimized/input.json create mode 100644 test/cmdlineTests/standard_output_selection_ethdebug_irOptimized/output.json create mode 100644 test/cmdlineTests/standard_output_selection_ethdebug_optimize/input.json create mode 100644 test/cmdlineTests/standard_output_selection_ethdebug_optimize/output.json create mode 100644 test/cmdlineTests/standard_yul_ethdebug_irOptimized/args create mode 100644 test/cmdlineTests/standard_yul_ethdebug_irOptimized/in.yul create mode 100644 test/cmdlineTests/standard_yul_ethdebug_irOptimized/input.json create mode 100644 test/cmdlineTests/standard_yul_ethdebug_irOptimized/output.json create mode 100644 test/cmdlineTests/standard_yul_ethdebug_optimize/args create mode 100644 test/cmdlineTests/standard_yul_ethdebug_optimize/in.yul create mode 100644 test/cmdlineTests/standard_yul_ethdebug_optimize/input.json create mode 100644 test/cmdlineTests/standard_yul_ethdebug_optimize/output.json diff --git a/libsolidity/interface/StandardCompiler.cpp b/libsolidity/interface/StandardCompiler.cpp index bcdb2901d053..520f4d5f1c8f 100644 --- a/libsolidity/interface/StandardCompiler.cpp +++ b/libsolidity/interface/StandardCompiler.cpp @@ -1204,6 +1204,9 @@ std::variant StandardCompiler::parseI ) return formatFatalError(Error::Type::FatalError, "'settings.debug.debugInfo' can only include 'ethdebug', if output 'ir', 'irOptimized', 'evm.bytecode.ethdebug', or 'evm.deployedBytecode.ethdebug' was selected."); + if (isEthdebugRequested(ret.outputSelection) && (ret.optimiserSettings.runYulOptimiser || isArtifactRequested(ret.outputSelection, "*", "*", "irOptimized", false))) + return formatFatalError(Error::Type::FatalError, "Optimization is not yet supported with ethdebug."); + return {std::move(ret)}; } diff --git a/solc/CommandLineParser.cpp b/solc/CommandLineParser.cpp index f62abb3c6043..56be4195dcc8 100644 --- a/solc/CommandLineParser.cpp +++ b/solc/CommandLineParser.cpp @@ -1485,15 +1485,18 @@ void CommandLineParser::processArgs() ); bool incompatibleEthdebugOutputs = - m_options.compiler.outputs.asmJson || m_options.compiler.outputs.irAstJson || m_options.compiler.outputs.irOptimizedAstJson; + m_options.compiler.outputs.asmJson || m_options.compiler.outputs.irAstJson || m_options.compiler.outputs.irOptimizedAstJson || + m_options.compiler.outputs.irOptimized || m_options.optimizer.optimizeYul || m_options.optimizer.optimizeEvmasm; bool incompatibleEthdebugInputs = m_options.input.mode != InputMode::Compiler; static std::string enableEthdebugMessage = "--" + CompilerOutputs::componentName(&CompilerOutputs::ethdebug) + " / --" + CompilerOutputs::componentName(&CompilerOutputs::ethdebugRuntime); - static std::string enableIrMessage = - "--" + CompilerOutputs::componentName(&CompilerOutputs::ir) + " / --" + CompilerOutputs::componentName(&CompilerOutputs::irOptimized); + static std::string incompatibleEthdebugOptimizerMessage = + "--" + g_strOptimize + " / --" + CompilerOutputs::componentName(&CompilerOutputs::irOptimized); + + static std::string enableIrMessage = "--" + CompilerOutputs::componentName(&CompilerOutputs::ir); if (m_options.compiler.outputs.ethdebug || m_options.compiler.outputs.ethdebugRuntime) { @@ -1506,7 +1509,7 @@ void CommandLineParser::processArgs() if (incompatibleEthdebugOutputs) solThrow( CommandLineValidationError, - enableEthdebugMessage + " output can only be used with " + enableIrMessage + "." + enableEthdebugMessage + " output can only be used with " + enableIrMessage + ". Optimization is not yet supported with ethdebug, e.g. no support for " + incompatibleEthdebugOptimizerMessage + " yet." ); if (!m_options.output.debugInfoSelection.has_value()) @@ -1526,11 +1529,11 @@ void CommandLineParser::processArgs() if ( m_options.output.debugInfoSelection.has_value() && m_options.output.debugInfoSelection->ethdebug && - (!(m_options.compiler.outputs.ir || m_options.compiler.outputs.irOptimized || m_options.compiler.outputs.ethdebug || m_options.compiler.outputs.ethdebugRuntime) || incompatibleEthdebugOutputs) + (!(m_options.compiler.outputs.ir || m_options.compiler.outputs.ethdebug || m_options.compiler.outputs.ethdebugRuntime) || incompatibleEthdebugOutputs) ) solThrow( CommandLineValidationError, - "--debug-info ethdebug can only be used with " + enableIrMessage + " and/or " + enableEthdebugMessage + "." + "--debug-info ethdebug can only be used with " + enableIrMessage + " and/or " + enableEthdebugMessage + ". Optimization is not yet supported with ethdebug, e.g. no support for " + incompatibleEthdebugOptimizerMessage + " yet." ); if (m_options.output.debugInfoSelection.has_value() && m_options.output.debugInfoSelection->ethdebug && incompatibleEthdebugInputs) diff --git a/test/cmdlineTests/ethdebug/args b/test/cmdlineTests/ethdebug/args index 6edc3b560136..ac83894b301f 100644 --- a/test/cmdlineTests/ethdebug/args +++ b/test/cmdlineTests/ethdebug/args @@ -1 +1 @@ ---ethdebug --via-ir --optimize --ir-optimized \ No newline at end of file +--ethdebug --via-ir --ir \ No newline at end of file diff --git a/test/cmdlineTests/ethdebug/output b/test/cmdlineTests/ethdebug/output index 41f243d9c488..375c5cf900af 100644 --- a/test/cmdlineTests/ethdebug/output +++ b/test/cmdlineTests/ethdebug/output @@ -2,41 +2,120 @@ {"sources":["ethdebug/input.sol"]} ======= ethdebug/input.sol:C ======= -Optimized IR: +IR: /// ethdebug: enabled /// @use-src 0:"ethdebug/input.sol" object "C_6" { code { - { + /// @src 0:60:101 "contract C {..." + mstore(64, memoryguard(128)) + if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } + + constructor_C_6() + + let _1 := allocate_unbounded() + codecopy(_1, dataoffset("C_6_deployed"), datasize("C_6_deployed")) + + return(_1, datasize("C_6_deployed")) + + function allocate_unbounded() -> memPtr { + memPtr := mload(64) + } + + function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() { + revert(0, 0) + } + + /// @src 0:60:101 "contract C {..." + function constructor_C_6() { + /// @src 0:60:101 "contract C {..." - let _1 := memoryguard(0x80) - mstore(64, _1) - if callvalue() { revert(0, 0) } - let _2 := datasize("C_6_deployed") - codecopy(_1, dataoffset("C_6_deployed"), _2) - return(_1, _2) + } + /// @src 0:60:101 "contract C {..." + } /// @use-src 0:"ethdebug/input.sol" object "C_6_deployed" { code { + /// @src 0:60:101 "contract C {..." + mstore(64, memoryguard(128)) + + if iszero(lt(calldatasize(), 4)) { - /// @src 0:60:101 "contract C {..." - if iszero(lt(calldatasize(), 4)) + let selector := shift_right_224_unsigned(calldataload(0)) + switch selector + + case 0x26121ff0 { - if eq(0x26121ff0, shr(224, calldataload(0))) - { - if callvalue() { revert(0, 0) } - if slt(add(calldatasize(), not(3)), 0) { revert(0, 0) } - return(0, 0) - } + // f() + + external_fun_f_5() } + + default {} + } + + revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() + + function shift_right_224_unsigned(value) -> newValue { + newValue := + + shr(224, value) + + } + + function allocate_unbounded() -> memPtr { + memPtr := mload(64) + } + + function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() { revert(0, 0) } + + function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() { + revert(0, 0) + } + + function abi_decode_tuple_(headStart, dataEnd) { + if slt(sub(dataEnd, headStart), 0) { revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() } + + } + + function abi_encode_tuple__to__fromStack(headStart ) -> tail { + tail := add(headStart, 0) + + } + + function external_fun_f_5() { + + if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } + abi_decode_tuple_(4, calldatasize()) + fun_f_5() + let memPos := allocate_unbounded() + let memEnd := abi_encode_tuple__to__fromStack(memPos ) + return(memPos, sub(memEnd, memPos)) + + } + + function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() { + revert(0, 0) + } + + /// @ast-id 5 + /// @src 0:77:99 "function f() public {}" + function fun_f_5() { + + } + /// @src 0:60:101 "contract C {..." + } + data ".metadata" hex"" } + } + Debug Data (ethdebug/format/program): {} diff --git a/test/cmdlineTests/ethdebug_and_ethdebug_runtime/args b/test/cmdlineTests/ethdebug_and_ethdebug_runtime/args index 809fb09884d8..18053bcdac95 100644 --- a/test/cmdlineTests/ethdebug_and_ethdebug_runtime/args +++ b/test/cmdlineTests/ethdebug_and_ethdebug_runtime/args @@ -1 +1 @@ ---ethdebug-runtime --ethdebug --via-ir --optimize --ir-optimized \ No newline at end of file +--ethdebug-runtime --ethdebug --via-ir --ir \ No newline at end of file diff --git a/test/cmdlineTests/ethdebug_and_ethdebug_runtime/output b/test/cmdlineTests/ethdebug_and_ethdebug_runtime/output index 3566824b9b03..000f29c4df1a 100644 --- a/test/cmdlineTests/ethdebug_and_ethdebug_runtime/output +++ b/test/cmdlineTests/ethdebug_and_ethdebug_runtime/output @@ -2,42 +2,121 @@ {"sources":["ethdebug_and_ethdebug_runtime/input.sol"]} ======= ethdebug_and_ethdebug_runtime/input.sol:C ======= -Optimized IR: +IR: /// ethdebug: enabled /// @use-src 0:"ethdebug_and_ethdebug_runtime/input.sol" object "C_6" { code { - { + /// @src 0:60:101 "contract C {..." + mstore(64, memoryguard(128)) + if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } + + constructor_C_6() + + let _1 := allocate_unbounded() + codecopy(_1, dataoffset("C_6_deployed"), datasize("C_6_deployed")) + + return(_1, datasize("C_6_deployed")) + + function allocate_unbounded() -> memPtr { + memPtr := mload(64) + } + + function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() { + revert(0, 0) + } + + /// @src 0:60:101 "contract C {..." + function constructor_C_6() { + /// @src 0:60:101 "contract C {..." - let _1 := memoryguard(0x80) - mstore(64, _1) - if callvalue() { revert(0, 0) } - let _2 := datasize("C_6_deployed") - codecopy(_1, dataoffset("C_6_deployed"), _2) - return(_1, _2) + } + /// @src 0:60:101 "contract C {..." + } /// @use-src 0:"ethdebug_and_ethdebug_runtime/input.sol" object "C_6_deployed" { code { + /// @src 0:60:101 "contract C {..." + mstore(64, memoryguard(128)) + + if iszero(lt(calldatasize(), 4)) { - /// @src 0:60:101 "contract C {..." - if iszero(lt(calldatasize(), 4)) + let selector := shift_right_224_unsigned(calldataload(0)) + switch selector + + case 0x26121ff0 { - if eq(0x26121ff0, shr(224, calldataload(0))) - { - if callvalue() { revert(0, 0) } - if slt(add(calldatasize(), not(3)), 0) { revert(0, 0) } - return(0, 0) - } + // f() + + external_fun_f_5() } + + default {} + } + + revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() + + function shift_right_224_unsigned(value) -> newValue { + newValue := + + shr(224, value) + + } + + function allocate_unbounded() -> memPtr { + memPtr := mload(64) + } + + function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() { revert(0, 0) } + + function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() { + revert(0, 0) + } + + function abi_decode_tuple_(headStart, dataEnd) { + if slt(sub(dataEnd, headStart), 0) { revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() } + + } + + function abi_encode_tuple__to__fromStack(headStart ) -> tail { + tail := add(headStart, 0) + + } + + function external_fun_f_5() { + + if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } + abi_decode_tuple_(4, calldatasize()) + fun_f_5() + let memPos := allocate_unbounded() + let memEnd := abi_encode_tuple__to__fromStack(memPos ) + return(memPos, sub(memEnd, memPos)) + + } + + function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() { + revert(0, 0) + } + + /// @ast-id 5 + /// @src 0:77:99 "function f() public {}" + function fun_f_5() { + + } + /// @src 0:60:101 "contract C {..." + } + data ".metadata" hex"" } + } + Debug Data (ethdebug/format/program): {} Debug Data of the runtime part (ethdebug/format/program): diff --git a/test/cmdlineTests/ethdebug_enabled_optimization/args b/test/cmdlineTests/ethdebug_enabled_optimization/args new file mode 100644 index 000000000000..6edc3b560136 --- /dev/null +++ b/test/cmdlineTests/ethdebug_enabled_optimization/args @@ -0,0 +1 @@ +--ethdebug --via-ir --optimize --ir-optimized \ No newline at end of file diff --git a/test/cmdlineTests/ethdebug_enabled_optimization/err b/test/cmdlineTests/ethdebug_enabled_optimization/err new file mode 100644 index 000000000000..082f6feee994 --- /dev/null +++ b/test/cmdlineTests/ethdebug_enabled_optimization/err @@ -0,0 +1 @@ +Error: --ethdebug / --ethdebug-runtime output can only be used with --ir. Optimization is not yet supported with ethdebug, e.g. no support for --optimize / --ir-optimized yet. diff --git a/test/cmdlineTests/ethdebug_enabled_optimization/exit b/test/cmdlineTests/ethdebug_enabled_optimization/exit new file mode 100644 index 000000000000..d00491fd7e5b --- /dev/null +++ b/test/cmdlineTests/ethdebug_enabled_optimization/exit @@ -0,0 +1 @@ +1 diff --git a/test/cmdlineTests/ethdebug_enabled_optimization/input.sol b/test/cmdlineTests/ethdebug_enabled_optimization/input.sol new file mode 100644 index 000000000000..25b9640ca565 --- /dev/null +++ b/test/cmdlineTests/ethdebug_enabled_optimization/input.sol @@ -0,0 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0 +pragma solidity >=0.0; + +contract C { + function f() public {} +} + diff --git a/test/cmdlineTests/ethdebug_runtime/args b/test/cmdlineTests/ethdebug_runtime/args index dfc6038785a5..a2193034c8db 100644 --- a/test/cmdlineTests/ethdebug_runtime/args +++ b/test/cmdlineTests/ethdebug_runtime/args @@ -1 +1 @@ ---ethdebug-runtime --via-ir --optimize --ir-optimized \ No newline at end of file +--ethdebug-runtime --via-ir --ir \ No newline at end of file diff --git a/test/cmdlineTests/ethdebug_runtime/output b/test/cmdlineTests/ethdebug_runtime/output index 8af39f64ef3c..8670e379d4e3 100644 --- a/test/cmdlineTests/ethdebug_runtime/output +++ b/test/cmdlineTests/ethdebug_runtime/output @@ -2,41 +2,120 @@ {"sources":["ethdebug_runtime/input.sol"]} ======= ethdebug_runtime/input.sol:C ======= -Optimized IR: +IR: /// ethdebug: enabled /// @use-src 0:"ethdebug_runtime/input.sol" object "C_6" { code { - { + /// @src 0:60:101 "contract C {..." + mstore(64, memoryguard(128)) + if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } + + constructor_C_6() + + let _1 := allocate_unbounded() + codecopy(_1, dataoffset("C_6_deployed"), datasize("C_6_deployed")) + + return(_1, datasize("C_6_deployed")) + + function allocate_unbounded() -> memPtr { + memPtr := mload(64) + } + + function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() { + revert(0, 0) + } + + /// @src 0:60:101 "contract C {..." + function constructor_C_6() { + /// @src 0:60:101 "contract C {..." - let _1 := memoryguard(0x80) - mstore(64, _1) - if callvalue() { revert(0, 0) } - let _2 := datasize("C_6_deployed") - codecopy(_1, dataoffset("C_6_deployed"), _2) - return(_1, _2) + } + /// @src 0:60:101 "contract C {..." + } /// @use-src 0:"ethdebug_runtime/input.sol" object "C_6_deployed" { code { + /// @src 0:60:101 "contract C {..." + mstore(64, memoryguard(128)) + + if iszero(lt(calldatasize(), 4)) { - /// @src 0:60:101 "contract C {..." - if iszero(lt(calldatasize(), 4)) + let selector := shift_right_224_unsigned(calldataload(0)) + switch selector + + case 0x26121ff0 { - if eq(0x26121ff0, shr(224, calldataload(0))) - { - if callvalue() { revert(0, 0) } - if slt(add(calldatasize(), not(3)), 0) { revert(0, 0) } - return(0, 0) - } + // f() + + external_fun_f_5() } + + default {} + } + + revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() + + function shift_right_224_unsigned(value) -> newValue { + newValue := + + shr(224, value) + + } + + function allocate_unbounded() -> memPtr { + memPtr := mload(64) + } + + function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() { revert(0, 0) } + + function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() { + revert(0, 0) + } + + function abi_decode_tuple_(headStart, dataEnd) { + if slt(sub(dataEnd, headStart), 0) { revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() } + + } + + function abi_encode_tuple__to__fromStack(headStart ) -> tail { + tail := add(headStart, 0) + + } + + function external_fun_f_5() { + + if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } + abi_decode_tuple_(4, calldatasize()) + fun_f_5() + let memPos := allocate_unbounded() + let memEnd := abi_encode_tuple__to__fromStack(memPos ) + return(memPos, sub(memEnd, memPos)) + + } + + function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() { + revert(0, 0) + } + + /// @ast-id 5 + /// @src 0:77:99 "function f() public {}" + function fun_f_5() { + + } + /// @src 0:60:101 "contract C {..." + } + data ".metadata" hex"" } + } + Debug Data of the runtime part (ethdebug/format/program): {} diff --git a/test/cmdlineTests/standard_output_selection_ethdebug_bytecode/input.json b/test/cmdlineTests/standard_output_selection_ethdebug_bytecode/input.json index e7173abed3e1..6ac2691c2085 100644 --- a/test/cmdlineTests/standard_output_selection_ethdebug_bytecode/input.json +++ b/test/cmdlineTests/standard_output_selection_ethdebug_bytecode/input.json @@ -11,12 +11,12 @@ "settings": { "viaIR": true, "optimizer": { - "enabled": true + "enabled": false }, "outputSelection": { "*": { "*": [ - "evm.bytecode.ethdebug", "irOptimized" + "evm.bytecode.ethdebug", "ir" ] } } diff --git a/test/cmdlineTests/standard_output_selection_ethdebug_bytecode/output.json b/test/cmdlineTests/standard_output_selection_ethdebug_bytecode/output.json index da701aec60f5..fabb25ee6720 100644 --- a/test/cmdlineTests/standard_output_selection_ethdebug_bytecode/output.json +++ b/test/cmdlineTests/standard_output_selection_ethdebug_bytecode/output.json @@ -7,46 +7,175 @@ "ethdebug": {} } }, - "irOptimized": "/// ethdebug: enabled + "ir": "/// ethdebug: enabled /// @use-src 0:\"a.sol\" object \"A1_14\" { code { - { + /// @src 0:58:123 \"contract A1 { function a(uint x) public pure { assert(x > 0); } }\" + mstore(64, memoryguard(128)) + if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } + + constructor_A1_14() + + let _1 := allocate_unbounded() + codecopy(_1, dataoffset(\"A1_14_deployed\"), datasize(\"A1_14_deployed\")) + + return(_1, datasize(\"A1_14_deployed\")) + + function allocate_unbounded() -> memPtr { + memPtr := mload(64) + } + + function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() { + revert(0, 0) + } + + /// @src 0:58:123 \"contract A1 { function a(uint x) public pure { assert(x > 0); } }\" + function constructor_A1_14() { + /// @src 0:58:123 \"contract A1 { function a(uint x) public pure { assert(x > 0); } }\" - let _1 := memoryguard(0x80) - mstore(64, _1) - if callvalue() { revert(0, 0) } - let _2 := datasize(\"A1_14_deployed\") - codecopy(_1, dataoffset(\"A1_14_deployed\"), _2) - return(_1, _2) + } + /// @src 0:58:123 \"contract A1 { function a(uint x) public pure { assert(x > 0); } }\" + } /// @use-src 0:\"a.sol\" object \"A1_14_deployed\" { code { + /// @src 0:58:123 \"contract A1 { function a(uint x) public pure { assert(x > 0); } }\" + mstore(64, memoryguard(128)) + + if iszero(lt(calldatasize(), 4)) { - /// @src 0:58:123 \"contract A1 { function a(uint x) public pure { assert(x > 0); } }\" - if iszero(lt(calldatasize(), 4)) + let selector := shift_right_224_unsigned(calldataload(0)) + switch selector + + case 0xf0fdf834 { - if eq(0xf0fdf834, shr(224, calldataload(0))) - { - if callvalue() { revert(0, 0) } - if slt(add(calldatasize(), not(3)), 32) { revert(0, 0) } - if /** @src 0:112:117 \"x > 0\" */ iszero(/** @src 0:58:123 \"contract A1 { function a(uint x) public pure { assert(x > 0); } }\" */ calldataload(4)) - { - mstore(0, shl(224, 0x4e487b71)) - mstore(4, 1) - revert(0, 0x24) - } - return(0, 0) - } + // a(uint256) + + external_fun_a_13() + } + + default {} + } + + revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() + + function shift_right_224_unsigned(value) -> newValue { + newValue := + + shr(224, value) + + } + + function allocate_unbounded() -> memPtr { + memPtr := mload(64) + } + + function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() { + revert(0, 0) + } + + function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() { + revert(0, 0) + } + + function revert_error_c1322bf8034eace5e0b5c7295db60986aa89aae5e0ea0873e4689e076861a5db() { + revert(0, 0) + } + + function cleanup_t_uint256(value) -> cleaned { + cleaned := value + } + + function validator_revert_t_uint256(value) { + if iszero(eq(value, cleanup_t_uint256(value))) { revert(0, 0) } + } + + function abi_decode_t_uint256(offset, end) -> value { + value := calldataload(offset) + validator_revert_t_uint256(value) + } + + function abi_decode_tuple_t_uint256(headStart, dataEnd) -> value0 { + if slt(sub(dataEnd, headStart), 32) { revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() } + + { + + let offset := 0 + + value0 := abi_decode_t_uint256(add(headStart, offset), dataEnd) } + + } + + function abi_encode_tuple__to__fromStack(headStart ) -> tail { + tail := add(headStart, 0) + + } + + function external_fun_a_13() { + + if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } + let param_0 := abi_decode_tuple_t_uint256(4, calldatasize()) + fun_a_13(param_0) + let memPos := allocate_unbounded() + let memEnd := abi_encode_tuple__to__fromStack(memPos ) + return(memPos, sub(memEnd, memPos)) + + } + + function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() { revert(0, 0) } + + function cleanup_t_rational_0_by_1(value) -> cleaned { + cleaned := value + } + + function identity(value) -> ret { + ret := value + } + + function convert_t_rational_0_by_1_to_t_uint256(value) -> converted { + converted := cleanup_t_uint256(identity(cleanup_t_rational_0_by_1(value))) + } + + function panic_error_0x01() { + mstore(0, 35408467139433450592217433187231851964531694900788300625387963629091585785856) + mstore(4, 0x01) + revert(0, 0x24) + } + + function assert_helper(condition) { + if iszero(condition) { panic_error_0x01() } + } + + /// @ast-id 13 + /// @src 0:72:121 \"function a(uint x) public pure { assert(x > 0); }\" + function fun_a_13(var_x_3) { + + /// @src 0:112:113 \"x\" + let _1 := var_x_3 + let expr_7 := _1 + /// @src 0:116:117 \"0\" + let expr_8 := 0x00 + /// @src 0:112:117 \"x > 0\" + let expr_9 := gt(cleanup_t_uint256(expr_7), convert_t_rational_0_by_1_to_t_uint256(expr_8)) + /// @src 0:105:118 \"assert(x > 0)\" + assert_helper(expr_9) + + } + /// @src 0:58:123 \"contract A1 { function a(uint x) public pure { assert(x > 0); } }\" + } + data \".metadata\" hex\"\" } + } + " }, "A2": { @@ -55,46 +184,175 @@ object \"A1_14\" { "ethdebug": {} } }, - "irOptimized": "/// ethdebug: enabled + "ir": "/// ethdebug: enabled /// @use-src 0:\"a.sol\" object \"A2_27\" { code { - { + /// @src 0:124:189 \"contract A2 { function a(uint x) public pure { assert(x > 0); } }\" + mstore(64, memoryguard(128)) + if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } + + constructor_A2_27() + + let _1 := allocate_unbounded() + codecopy(_1, dataoffset(\"A2_27_deployed\"), datasize(\"A2_27_deployed\")) + + return(_1, datasize(\"A2_27_deployed\")) + + function allocate_unbounded() -> memPtr { + memPtr := mload(64) + } + + function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() { + revert(0, 0) + } + + /// @src 0:124:189 \"contract A2 { function a(uint x) public pure { assert(x > 0); } }\" + function constructor_A2_27() { + /// @src 0:124:189 \"contract A2 { function a(uint x) public pure { assert(x > 0); } }\" - let _1 := memoryguard(0x80) - mstore(64, _1) - if callvalue() { revert(0, 0) } - let _2 := datasize(\"A2_27_deployed\") - codecopy(_1, dataoffset(\"A2_27_deployed\"), _2) - return(_1, _2) + } + /// @src 0:124:189 \"contract A2 { function a(uint x) public pure { assert(x > 0); } }\" + } /// @use-src 0:\"a.sol\" object \"A2_27_deployed\" { code { + /// @src 0:124:189 \"contract A2 { function a(uint x) public pure { assert(x > 0); } }\" + mstore(64, memoryguard(128)) + + if iszero(lt(calldatasize(), 4)) { - /// @src 0:124:189 \"contract A2 { function a(uint x) public pure { assert(x > 0); } }\" - if iszero(lt(calldatasize(), 4)) + let selector := shift_right_224_unsigned(calldataload(0)) + switch selector + + case 0xf0fdf834 { - if eq(0xf0fdf834, shr(224, calldataload(0))) - { - if callvalue() { revert(0, 0) } - if slt(add(calldatasize(), not(3)), 32) { revert(0, 0) } - if /** @src 0:178:183 \"x > 0\" */ iszero(/** @src 0:124:189 \"contract A2 { function a(uint x) public pure { assert(x > 0); } }\" */ calldataload(4)) - { - mstore(0, shl(224, 0x4e487b71)) - mstore(4, 1) - revert(0, 0x24) - } - return(0, 0) - } + // a(uint256) + + external_fun_a_26() + } + + default {} + } + + revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() + + function shift_right_224_unsigned(value) -> newValue { + newValue := + + shr(224, value) + + } + + function allocate_unbounded() -> memPtr { + memPtr := mload(64) + } + + function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() { + revert(0, 0) + } + + function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() { + revert(0, 0) + } + + function revert_error_c1322bf8034eace5e0b5c7295db60986aa89aae5e0ea0873e4689e076861a5db() { + revert(0, 0) + } + + function cleanup_t_uint256(value) -> cleaned { + cleaned := value + } + + function validator_revert_t_uint256(value) { + if iszero(eq(value, cleanup_t_uint256(value))) { revert(0, 0) } + } + + function abi_decode_t_uint256(offset, end) -> value { + value := calldataload(offset) + validator_revert_t_uint256(value) + } + + function abi_decode_tuple_t_uint256(headStart, dataEnd) -> value0 { + if slt(sub(dataEnd, headStart), 32) { revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() } + + { + + let offset := 0 + + value0 := abi_decode_t_uint256(add(headStart, offset), dataEnd) } + + } + + function abi_encode_tuple__to__fromStack(headStart ) -> tail { + tail := add(headStart, 0) + + } + + function external_fun_a_26() { + + if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } + let param_0 := abi_decode_tuple_t_uint256(4, calldatasize()) + fun_a_26(param_0) + let memPos := allocate_unbounded() + let memEnd := abi_encode_tuple__to__fromStack(memPos ) + return(memPos, sub(memEnd, memPos)) + + } + + function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() { revert(0, 0) } + + function cleanup_t_rational_0_by_1(value) -> cleaned { + cleaned := value + } + + function identity(value) -> ret { + ret := value + } + + function convert_t_rational_0_by_1_to_t_uint256(value) -> converted { + converted := cleanup_t_uint256(identity(cleanup_t_rational_0_by_1(value))) + } + + function panic_error_0x01() { + mstore(0, 35408467139433450592217433187231851964531694900788300625387963629091585785856) + mstore(4, 0x01) + revert(0, 0x24) + } + + function assert_helper(condition) { + if iszero(condition) { panic_error_0x01() } + } + + /// @ast-id 26 + /// @src 0:138:187 \"function a(uint x) public pure { assert(x > 0); }\" + function fun_a_26(var_x_16) { + + /// @src 0:178:179 \"x\" + let _1 := var_x_16 + let expr_20 := _1 + /// @src 0:182:183 \"0\" + let expr_21 := 0x00 + /// @src 0:178:183 \"x > 0\" + let expr_22 := gt(cleanup_t_uint256(expr_20), convert_t_rational_0_by_1_to_t_uint256(expr_21)) + /// @src 0:171:184 \"assert(x > 0)\" + assert_helper(expr_22) + + } + /// @src 0:124:189 \"contract A2 { function a(uint x) public pure { assert(x > 0); } }\" + } + data \".metadata\" hex\"\" } + } + " } }, @@ -105,46 +363,175 @@ object \"A2_27\" { "ethdebug": {} } }, - "irOptimized": "/// ethdebug: enabled + "ir": "/// ethdebug: enabled /// @use-src 1:\"b.sol\" object \"A1_42\" { code { - { + /// @src 1:58:123 \"contract A1 { function b(uint x) public pure { assert(x > 0); } }\" + mstore(64, memoryguard(128)) + if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } + + constructor_A1_42() + + let _1 := allocate_unbounded() + codecopy(_1, dataoffset(\"A1_42_deployed\"), datasize(\"A1_42_deployed\")) + + return(_1, datasize(\"A1_42_deployed\")) + + function allocate_unbounded() -> memPtr { + memPtr := mload(64) + } + + function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() { + revert(0, 0) + } + + /// @src 1:58:123 \"contract A1 { function b(uint x) public pure { assert(x > 0); } }\" + function constructor_A1_42() { + /// @src 1:58:123 \"contract A1 { function b(uint x) public pure { assert(x > 0); } }\" - let _1 := memoryguard(0x80) - mstore(64, _1) - if callvalue() { revert(0, 0) } - let _2 := datasize(\"A1_42_deployed\") - codecopy(_1, dataoffset(\"A1_42_deployed\"), _2) - return(_1, _2) + } + /// @src 1:58:123 \"contract A1 { function b(uint x) public pure { assert(x > 0); } }\" + } /// @use-src 1:\"b.sol\" object \"A1_42_deployed\" { code { + /// @src 1:58:123 \"contract A1 { function b(uint x) public pure { assert(x > 0); } }\" + mstore(64, memoryguard(128)) + + if iszero(lt(calldatasize(), 4)) { - /// @src 1:58:123 \"contract A1 { function b(uint x) public pure { assert(x > 0); } }\" - if iszero(lt(calldatasize(), 4)) + let selector := shift_right_224_unsigned(calldataload(0)) + switch selector + + case 0xcd580ff3 { - if eq(0xcd580ff3, shr(224, calldataload(0))) - { - if callvalue() { revert(0, 0) } - if slt(add(calldatasize(), not(3)), 32) { revert(0, 0) } - if /** @src 1:112:117 \"x > 0\" */ iszero(/** @src 1:58:123 \"contract A1 { function b(uint x) public pure { assert(x > 0); } }\" */ calldataload(4)) - { - mstore(0, shl(224, 0x4e487b71)) - mstore(4, 1) - revert(0, 0x24) - } - return(0, 0) - } + // b(uint256) + + external_fun_b_41() + } + + default {} + } + + revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() + + function shift_right_224_unsigned(value) -> newValue { + newValue := + + shr(224, value) + + } + + function allocate_unbounded() -> memPtr { + memPtr := mload(64) + } + + function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() { + revert(0, 0) + } + + function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() { + revert(0, 0) + } + + function revert_error_c1322bf8034eace5e0b5c7295db60986aa89aae5e0ea0873e4689e076861a5db() { + revert(0, 0) + } + + function cleanup_t_uint256(value) -> cleaned { + cleaned := value + } + + function validator_revert_t_uint256(value) { + if iszero(eq(value, cleanup_t_uint256(value))) { revert(0, 0) } + } + + function abi_decode_t_uint256(offset, end) -> value { + value := calldataload(offset) + validator_revert_t_uint256(value) + } + + function abi_decode_tuple_t_uint256(headStart, dataEnd) -> value0 { + if slt(sub(dataEnd, headStart), 32) { revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() } + + { + + let offset := 0 + + value0 := abi_decode_t_uint256(add(headStart, offset), dataEnd) } + + } + + function abi_encode_tuple__to__fromStack(headStart ) -> tail { + tail := add(headStart, 0) + + } + + function external_fun_b_41() { + + if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } + let param_0 := abi_decode_tuple_t_uint256(4, calldatasize()) + fun_b_41(param_0) + let memPos := allocate_unbounded() + let memEnd := abi_encode_tuple__to__fromStack(memPos ) + return(memPos, sub(memEnd, memPos)) + + } + + function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() { revert(0, 0) } + + function cleanup_t_rational_0_by_1(value) -> cleaned { + cleaned := value + } + + function identity(value) -> ret { + ret := value + } + + function convert_t_rational_0_by_1_to_t_uint256(value) -> converted { + converted := cleanup_t_uint256(identity(cleanup_t_rational_0_by_1(value))) + } + + function panic_error_0x01() { + mstore(0, 35408467139433450592217433187231851964531694900788300625387963629091585785856) + mstore(4, 0x01) + revert(0, 0x24) + } + + function assert_helper(condition) { + if iszero(condition) { panic_error_0x01() } + } + + /// @ast-id 41 + /// @src 1:72:121 \"function b(uint x) public pure { assert(x > 0); }\" + function fun_b_41(var_x_31) { + + /// @src 1:112:113 \"x\" + let _1 := var_x_31 + let expr_35 := _1 + /// @src 1:116:117 \"0\" + let expr_36 := 0x00 + /// @src 1:112:117 \"x > 0\" + let expr_37 := gt(cleanup_t_uint256(expr_35), convert_t_rational_0_by_1_to_t_uint256(expr_36)) + /// @src 1:105:118 \"assert(x > 0)\" + assert_helper(expr_37) + + } + /// @src 1:58:123 \"contract A1 { function b(uint x) public pure { assert(x > 0); } }\" + } + data \".metadata\" hex\"\" } + } + " }, "B2": { @@ -153,46 +540,175 @@ object \"A1_42\" { "ethdebug": {} } }, - "irOptimized": "/// ethdebug: enabled + "ir": "/// ethdebug: enabled /// @use-src 1:\"b.sol\" object \"B2_55\" { code { - { + /// @src 1:124:189 \"contract B2 { function b(uint x) public pure { assert(x > 0); } }\" + mstore(64, memoryguard(128)) + if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } + + constructor_B2_55() + + let _1 := allocate_unbounded() + codecopy(_1, dataoffset(\"B2_55_deployed\"), datasize(\"B2_55_deployed\")) + + return(_1, datasize(\"B2_55_deployed\")) + + function allocate_unbounded() -> memPtr { + memPtr := mload(64) + } + + function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() { + revert(0, 0) + } + + /// @src 1:124:189 \"contract B2 { function b(uint x) public pure { assert(x > 0); } }\" + function constructor_B2_55() { + /// @src 1:124:189 \"contract B2 { function b(uint x) public pure { assert(x > 0); } }\" - let _1 := memoryguard(0x80) - mstore(64, _1) - if callvalue() { revert(0, 0) } - let _2 := datasize(\"B2_55_deployed\") - codecopy(_1, dataoffset(\"B2_55_deployed\"), _2) - return(_1, _2) + } + /// @src 1:124:189 \"contract B2 { function b(uint x) public pure { assert(x > 0); } }\" + } /// @use-src 1:\"b.sol\" object \"B2_55_deployed\" { code { + /// @src 1:124:189 \"contract B2 { function b(uint x) public pure { assert(x > 0); } }\" + mstore(64, memoryguard(128)) + + if iszero(lt(calldatasize(), 4)) { - /// @src 1:124:189 \"contract B2 { function b(uint x) public pure { assert(x > 0); } }\" - if iszero(lt(calldatasize(), 4)) + let selector := shift_right_224_unsigned(calldataload(0)) + switch selector + + case 0xcd580ff3 { - if eq(0xcd580ff3, shr(224, calldataload(0))) - { - if callvalue() { revert(0, 0) } - if slt(add(calldatasize(), not(3)), 32) { revert(0, 0) } - if /** @src 1:178:183 \"x > 0\" */ iszero(/** @src 1:124:189 \"contract B2 { function b(uint x) public pure { assert(x > 0); } }\" */ calldataload(4)) - { - mstore(0, shl(224, 0x4e487b71)) - mstore(4, 1) - revert(0, 0x24) - } - return(0, 0) - } + // b(uint256) + + external_fun_b_54() + } + + default {} + } + + revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() + + function shift_right_224_unsigned(value) -> newValue { + newValue := + + shr(224, value) + + } + + function allocate_unbounded() -> memPtr { + memPtr := mload(64) + } + + function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() { + revert(0, 0) + } + + function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() { + revert(0, 0) + } + + function revert_error_c1322bf8034eace5e0b5c7295db60986aa89aae5e0ea0873e4689e076861a5db() { + revert(0, 0) + } + + function cleanup_t_uint256(value) -> cleaned { + cleaned := value + } + + function validator_revert_t_uint256(value) { + if iszero(eq(value, cleanup_t_uint256(value))) { revert(0, 0) } + } + + function abi_decode_t_uint256(offset, end) -> value { + value := calldataload(offset) + validator_revert_t_uint256(value) + } + + function abi_decode_tuple_t_uint256(headStart, dataEnd) -> value0 { + if slt(sub(dataEnd, headStart), 32) { revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() } + + { + + let offset := 0 + + value0 := abi_decode_t_uint256(add(headStart, offset), dataEnd) } + + } + + function abi_encode_tuple__to__fromStack(headStart ) -> tail { + tail := add(headStart, 0) + + } + + function external_fun_b_54() { + + if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } + let param_0 := abi_decode_tuple_t_uint256(4, calldatasize()) + fun_b_54(param_0) + let memPos := allocate_unbounded() + let memEnd := abi_encode_tuple__to__fromStack(memPos ) + return(memPos, sub(memEnd, memPos)) + + } + + function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() { revert(0, 0) } + + function cleanup_t_rational_0_by_1(value) -> cleaned { + cleaned := value + } + + function identity(value) -> ret { + ret := value + } + + function convert_t_rational_0_by_1_to_t_uint256(value) -> converted { + converted := cleanup_t_uint256(identity(cleanup_t_rational_0_by_1(value))) + } + + function panic_error_0x01() { + mstore(0, 35408467139433450592217433187231851964531694900788300625387963629091585785856) + mstore(4, 0x01) + revert(0, 0x24) + } + + function assert_helper(condition) { + if iszero(condition) { panic_error_0x01() } + } + + /// @ast-id 54 + /// @src 1:138:187 \"function b(uint x) public pure { assert(x > 0); }\" + function fun_b_54(var_x_44) { + + /// @src 1:178:179 \"x\" + let _1 := var_x_44 + let expr_48 := _1 + /// @src 1:182:183 \"0\" + let expr_49 := 0x00 + /// @src 1:178:183 \"x > 0\" + let expr_50 := gt(cleanup_t_uint256(expr_48), convert_t_rational_0_by_1_to_t_uint256(expr_49)) + /// @src 1:171:184 \"assert(x > 0)\" + assert_helper(expr_50) + + } + /// @src 1:124:189 \"contract B2 { function b(uint x) public pure { assert(x > 0); } }\" + } + data \".metadata\" hex\"\" } + } + " } } diff --git a/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode/input.json b/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode/input.json index e45f27f3caa8..bb93f57a8256 100644 --- a/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode/input.json +++ b/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode/input.json @@ -11,12 +11,12 @@ "settings": { "viaIR": true, "optimizer": { - "enabled": true + "enabled": false }, "outputSelection": { "*": { "*": [ - "evm.bytecode.ethdebug", "evm.deployedBytecode.ethdebug", "irOptimized" + "evm.bytecode.ethdebug", "evm.deployedBytecode.ethdebug", "ir" ] } } diff --git a/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode/output.json b/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode/output.json index 4e41e41c385b..f8fb2ce274d0 100644 --- a/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode/output.json +++ b/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode/output.json @@ -10,46 +10,175 @@ "ethdebug": {} } }, - "irOptimized": "/// ethdebug: enabled + "ir": "/// ethdebug: enabled /// @use-src 0:\"a.sol\" object \"A1_14\" { code { - { + /// @src 0:58:123 \"contract A1 { function a(uint x) public pure { assert(x > 0); } }\" + mstore(64, memoryguard(128)) + if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } + + constructor_A1_14() + + let _1 := allocate_unbounded() + codecopy(_1, dataoffset(\"A1_14_deployed\"), datasize(\"A1_14_deployed\")) + + return(_1, datasize(\"A1_14_deployed\")) + + function allocate_unbounded() -> memPtr { + memPtr := mload(64) + } + + function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() { + revert(0, 0) + } + + /// @src 0:58:123 \"contract A1 { function a(uint x) public pure { assert(x > 0); } }\" + function constructor_A1_14() { + /// @src 0:58:123 \"contract A1 { function a(uint x) public pure { assert(x > 0); } }\" - let _1 := memoryguard(0x80) - mstore(64, _1) - if callvalue() { revert(0, 0) } - let _2 := datasize(\"A1_14_deployed\") - codecopy(_1, dataoffset(\"A1_14_deployed\"), _2) - return(_1, _2) + } + /// @src 0:58:123 \"contract A1 { function a(uint x) public pure { assert(x > 0); } }\" + } /// @use-src 0:\"a.sol\" object \"A1_14_deployed\" { code { + /// @src 0:58:123 \"contract A1 { function a(uint x) public pure { assert(x > 0); } }\" + mstore(64, memoryguard(128)) + + if iszero(lt(calldatasize(), 4)) { - /// @src 0:58:123 \"contract A1 { function a(uint x) public pure { assert(x > 0); } }\" - if iszero(lt(calldatasize(), 4)) + let selector := shift_right_224_unsigned(calldataload(0)) + switch selector + + case 0xf0fdf834 { - if eq(0xf0fdf834, shr(224, calldataload(0))) - { - if callvalue() { revert(0, 0) } - if slt(add(calldatasize(), not(3)), 32) { revert(0, 0) } - if /** @src 0:112:117 \"x > 0\" */ iszero(/** @src 0:58:123 \"contract A1 { function a(uint x) public pure { assert(x > 0); } }\" */ calldataload(4)) - { - mstore(0, shl(224, 0x4e487b71)) - mstore(4, 1) - revert(0, 0x24) - } - return(0, 0) - } + // a(uint256) + + external_fun_a_13() + } + + default {} + } + + revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() + + function shift_right_224_unsigned(value) -> newValue { + newValue := + + shr(224, value) + + } + + function allocate_unbounded() -> memPtr { + memPtr := mload(64) + } + + function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() { + revert(0, 0) + } + + function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() { + revert(0, 0) + } + + function revert_error_c1322bf8034eace5e0b5c7295db60986aa89aae5e0ea0873e4689e076861a5db() { + revert(0, 0) + } + + function cleanup_t_uint256(value) -> cleaned { + cleaned := value + } + + function validator_revert_t_uint256(value) { + if iszero(eq(value, cleanup_t_uint256(value))) { revert(0, 0) } + } + + function abi_decode_t_uint256(offset, end) -> value { + value := calldataload(offset) + validator_revert_t_uint256(value) + } + + function abi_decode_tuple_t_uint256(headStart, dataEnd) -> value0 { + if slt(sub(dataEnd, headStart), 32) { revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() } + + { + + let offset := 0 + + value0 := abi_decode_t_uint256(add(headStart, offset), dataEnd) } + + } + + function abi_encode_tuple__to__fromStack(headStart ) -> tail { + tail := add(headStart, 0) + + } + + function external_fun_a_13() { + + if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } + let param_0 := abi_decode_tuple_t_uint256(4, calldatasize()) + fun_a_13(param_0) + let memPos := allocate_unbounded() + let memEnd := abi_encode_tuple__to__fromStack(memPos ) + return(memPos, sub(memEnd, memPos)) + + } + + function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() { revert(0, 0) } + + function cleanup_t_rational_0_by_1(value) -> cleaned { + cleaned := value + } + + function identity(value) -> ret { + ret := value + } + + function convert_t_rational_0_by_1_to_t_uint256(value) -> converted { + converted := cleanup_t_uint256(identity(cleanup_t_rational_0_by_1(value))) + } + + function panic_error_0x01() { + mstore(0, 35408467139433450592217433187231851964531694900788300625387963629091585785856) + mstore(4, 0x01) + revert(0, 0x24) + } + + function assert_helper(condition) { + if iszero(condition) { panic_error_0x01() } + } + + /// @ast-id 13 + /// @src 0:72:121 \"function a(uint x) public pure { assert(x > 0); }\" + function fun_a_13(var_x_3) { + + /// @src 0:112:113 \"x\" + let _1 := var_x_3 + let expr_7 := _1 + /// @src 0:116:117 \"0\" + let expr_8 := 0x00 + /// @src 0:112:117 \"x > 0\" + let expr_9 := gt(cleanup_t_uint256(expr_7), convert_t_rational_0_by_1_to_t_uint256(expr_8)) + /// @src 0:105:118 \"assert(x > 0)\" + assert_helper(expr_9) + + } + /// @src 0:58:123 \"contract A1 { function a(uint x) public pure { assert(x > 0); } }\" + } + data \".metadata\" hex\"\" } + } + " }, "A2": { @@ -61,46 +190,175 @@ object \"A1_14\" { "ethdebug": {} } }, - "irOptimized": "/// ethdebug: enabled + "ir": "/// ethdebug: enabled /// @use-src 0:\"a.sol\" object \"A2_27\" { code { - { + /// @src 0:124:189 \"contract A2 { function a(uint x) public pure { assert(x > 0); } }\" + mstore(64, memoryguard(128)) + if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } + + constructor_A2_27() + + let _1 := allocate_unbounded() + codecopy(_1, dataoffset(\"A2_27_deployed\"), datasize(\"A2_27_deployed\")) + + return(_1, datasize(\"A2_27_deployed\")) + + function allocate_unbounded() -> memPtr { + memPtr := mload(64) + } + + function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() { + revert(0, 0) + } + + /// @src 0:124:189 \"contract A2 { function a(uint x) public pure { assert(x > 0); } }\" + function constructor_A2_27() { + /// @src 0:124:189 \"contract A2 { function a(uint x) public pure { assert(x > 0); } }\" - let _1 := memoryguard(0x80) - mstore(64, _1) - if callvalue() { revert(0, 0) } - let _2 := datasize(\"A2_27_deployed\") - codecopy(_1, dataoffset(\"A2_27_deployed\"), _2) - return(_1, _2) + } + /// @src 0:124:189 \"contract A2 { function a(uint x) public pure { assert(x > 0); } }\" + } /// @use-src 0:\"a.sol\" object \"A2_27_deployed\" { code { + /// @src 0:124:189 \"contract A2 { function a(uint x) public pure { assert(x > 0); } }\" + mstore(64, memoryguard(128)) + + if iszero(lt(calldatasize(), 4)) { - /// @src 0:124:189 \"contract A2 { function a(uint x) public pure { assert(x > 0); } }\" - if iszero(lt(calldatasize(), 4)) + let selector := shift_right_224_unsigned(calldataload(0)) + switch selector + + case 0xf0fdf834 { - if eq(0xf0fdf834, shr(224, calldataload(0))) - { - if callvalue() { revert(0, 0) } - if slt(add(calldatasize(), not(3)), 32) { revert(0, 0) } - if /** @src 0:178:183 \"x > 0\" */ iszero(/** @src 0:124:189 \"contract A2 { function a(uint x) public pure { assert(x > 0); } }\" */ calldataload(4)) - { - mstore(0, shl(224, 0x4e487b71)) - mstore(4, 1) - revert(0, 0x24) - } - return(0, 0) - } + // a(uint256) + + external_fun_a_26() + } + + default {} + } + + revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() + + function shift_right_224_unsigned(value) -> newValue { + newValue := + + shr(224, value) + + } + + function allocate_unbounded() -> memPtr { + memPtr := mload(64) + } + + function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() { + revert(0, 0) + } + + function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() { + revert(0, 0) + } + + function revert_error_c1322bf8034eace5e0b5c7295db60986aa89aae5e0ea0873e4689e076861a5db() { + revert(0, 0) + } + + function cleanup_t_uint256(value) -> cleaned { + cleaned := value + } + + function validator_revert_t_uint256(value) { + if iszero(eq(value, cleanup_t_uint256(value))) { revert(0, 0) } + } + + function abi_decode_t_uint256(offset, end) -> value { + value := calldataload(offset) + validator_revert_t_uint256(value) + } + + function abi_decode_tuple_t_uint256(headStart, dataEnd) -> value0 { + if slt(sub(dataEnd, headStart), 32) { revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() } + + { + + let offset := 0 + + value0 := abi_decode_t_uint256(add(headStart, offset), dataEnd) } + + } + + function abi_encode_tuple__to__fromStack(headStart ) -> tail { + tail := add(headStart, 0) + + } + + function external_fun_a_26() { + + if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } + let param_0 := abi_decode_tuple_t_uint256(4, calldatasize()) + fun_a_26(param_0) + let memPos := allocate_unbounded() + let memEnd := abi_encode_tuple__to__fromStack(memPos ) + return(memPos, sub(memEnd, memPos)) + + } + + function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() { revert(0, 0) } + + function cleanup_t_rational_0_by_1(value) -> cleaned { + cleaned := value + } + + function identity(value) -> ret { + ret := value + } + + function convert_t_rational_0_by_1_to_t_uint256(value) -> converted { + converted := cleanup_t_uint256(identity(cleanup_t_rational_0_by_1(value))) + } + + function panic_error_0x01() { + mstore(0, 35408467139433450592217433187231851964531694900788300625387963629091585785856) + mstore(4, 0x01) + revert(0, 0x24) + } + + function assert_helper(condition) { + if iszero(condition) { panic_error_0x01() } + } + + /// @ast-id 26 + /// @src 0:138:187 \"function a(uint x) public pure { assert(x > 0); }\" + function fun_a_26(var_x_16) { + + /// @src 0:178:179 \"x\" + let _1 := var_x_16 + let expr_20 := _1 + /// @src 0:182:183 \"0\" + let expr_21 := 0x00 + /// @src 0:178:183 \"x > 0\" + let expr_22 := gt(cleanup_t_uint256(expr_20), convert_t_rational_0_by_1_to_t_uint256(expr_21)) + /// @src 0:171:184 \"assert(x > 0)\" + assert_helper(expr_22) + + } + /// @src 0:124:189 \"contract A2 { function a(uint x) public pure { assert(x > 0); } }\" + } + data \".metadata\" hex\"\" } + } + " } }, @@ -114,46 +372,175 @@ object \"A2_27\" { "ethdebug": {} } }, - "irOptimized": "/// ethdebug: enabled + "ir": "/// ethdebug: enabled /// @use-src 1:\"b.sol\" object \"A1_42\" { code { - { + /// @src 1:58:123 \"contract A1 { function b(uint x) public pure { assert(x > 0); } }\" + mstore(64, memoryguard(128)) + if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } + + constructor_A1_42() + + let _1 := allocate_unbounded() + codecopy(_1, dataoffset(\"A1_42_deployed\"), datasize(\"A1_42_deployed\")) + + return(_1, datasize(\"A1_42_deployed\")) + + function allocate_unbounded() -> memPtr { + memPtr := mload(64) + } + + function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() { + revert(0, 0) + } + + /// @src 1:58:123 \"contract A1 { function b(uint x) public pure { assert(x > 0); } }\" + function constructor_A1_42() { + /// @src 1:58:123 \"contract A1 { function b(uint x) public pure { assert(x > 0); } }\" - let _1 := memoryguard(0x80) - mstore(64, _1) - if callvalue() { revert(0, 0) } - let _2 := datasize(\"A1_42_deployed\") - codecopy(_1, dataoffset(\"A1_42_deployed\"), _2) - return(_1, _2) + } + /// @src 1:58:123 \"contract A1 { function b(uint x) public pure { assert(x > 0); } }\" + } /// @use-src 1:\"b.sol\" object \"A1_42_deployed\" { code { + /// @src 1:58:123 \"contract A1 { function b(uint x) public pure { assert(x > 0); } }\" + mstore(64, memoryguard(128)) + + if iszero(lt(calldatasize(), 4)) { - /// @src 1:58:123 \"contract A1 { function b(uint x) public pure { assert(x > 0); } }\" - if iszero(lt(calldatasize(), 4)) + let selector := shift_right_224_unsigned(calldataload(0)) + switch selector + + case 0xcd580ff3 { - if eq(0xcd580ff3, shr(224, calldataload(0))) - { - if callvalue() { revert(0, 0) } - if slt(add(calldatasize(), not(3)), 32) { revert(0, 0) } - if /** @src 1:112:117 \"x > 0\" */ iszero(/** @src 1:58:123 \"contract A1 { function b(uint x) public pure { assert(x > 0); } }\" */ calldataload(4)) - { - mstore(0, shl(224, 0x4e487b71)) - mstore(4, 1) - revert(0, 0x24) - } - return(0, 0) - } + // b(uint256) + + external_fun_b_41() + } + + default {} + } + + revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() + + function shift_right_224_unsigned(value) -> newValue { + newValue := + + shr(224, value) + + } + + function allocate_unbounded() -> memPtr { + memPtr := mload(64) + } + + function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() { + revert(0, 0) + } + + function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() { + revert(0, 0) + } + + function revert_error_c1322bf8034eace5e0b5c7295db60986aa89aae5e0ea0873e4689e076861a5db() { + revert(0, 0) + } + + function cleanup_t_uint256(value) -> cleaned { + cleaned := value + } + + function validator_revert_t_uint256(value) { + if iszero(eq(value, cleanup_t_uint256(value))) { revert(0, 0) } + } + + function abi_decode_t_uint256(offset, end) -> value { + value := calldataload(offset) + validator_revert_t_uint256(value) + } + + function abi_decode_tuple_t_uint256(headStart, dataEnd) -> value0 { + if slt(sub(dataEnd, headStart), 32) { revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() } + + { + + let offset := 0 + + value0 := abi_decode_t_uint256(add(headStart, offset), dataEnd) } + + } + + function abi_encode_tuple__to__fromStack(headStart ) -> tail { + tail := add(headStart, 0) + + } + + function external_fun_b_41() { + + if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } + let param_0 := abi_decode_tuple_t_uint256(4, calldatasize()) + fun_b_41(param_0) + let memPos := allocate_unbounded() + let memEnd := abi_encode_tuple__to__fromStack(memPos ) + return(memPos, sub(memEnd, memPos)) + + } + + function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() { revert(0, 0) } + + function cleanup_t_rational_0_by_1(value) -> cleaned { + cleaned := value + } + + function identity(value) -> ret { + ret := value + } + + function convert_t_rational_0_by_1_to_t_uint256(value) -> converted { + converted := cleanup_t_uint256(identity(cleanup_t_rational_0_by_1(value))) + } + + function panic_error_0x01() { + mstore(0, 35408467139433450592217433187231851964531694900788300625387963629091585785856) + mstore(4, 0x01) + revert(0, 0x24) + } + + function assert_helper(condition) { + if iszero(condition) { panic_error_0x01() } + } + + /// @ast-id 41 + /// @src 1:72:121 \"function b(uint x) public pure { assert(x > 0); }\" + function fun_b_41(var_x_31) { + + /// @src 1:112:113 \"x\" + let _1 := var_x_31 + let expr_35 := _1 + /// @src 1:116:117 \"0\" + let expr_36 := 0x00 + /// @src 1:112:117 \"x > 0\" + let expr_37 := gt(cleanup_t_uint256(expr_35), convert_t_rational_0_by_1_to_t_uint256(expr_36)) + /// @src 1:105:118 \"assert(x > 0)\" + assert_helper(expr_37) + + } + /// @src 1:58:123 \"contract A1 { function b(uint x) public pure { assert(x > 0); } }\" + } + data \".metadata\" hex\"\" } + } + " }, "B2": { @@ -165,46 +552,175 @@ object \"A1_42\" { "ethdebug": {} } }, - "irOptimized": "/// ethdebug: enabled + "ir": "/// ethdebug: enabled /// @use-src 1:\"b.sol\" object \"B2_55\" { code { - { + /// @src 1:124:189 \"contract B2 { function b(uint x) public pure { assert(x > 0); } }\" + mstore(64, memoryguard(128)) + if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } + + constructor_B2_55() + + let _1 := allocate_unbounded() + codecopy(_1, dataoffset(\"B2_55_deployed\"), datasize(\"B2_55_deployed\")) + + return(_1, datasize(\"B2_55_deployed\")) + + function allocate_unbounded() -> memPtr { + memPtr := mload(64) + } + + function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() { + revert(0, 0) + } + + /// @src 1:124:189 \"contract B2 { function b(uint x) public pure { assert(x > 0); } }\" + function constructor_B2_55() { + /// @src 1:124:189 \"contract B2 { function b(uint x) public pure { assert(x > 0); } }\" - let _1 := memoryguard(0x80) - mstore(64, _1) - if callvalue() { revert(0, 0) } - let _2 := datasize(\"B2_55_deployed\") - codecopy(_1, dataoffset(\"B2_55_deployed\"), _2) - return(_1, _2) + } + /// @src 1:124:189 \"contract B2 { function b(uint x) public pure { assert(x > 0); } }\" + } /// @use-src 1:\"b.sol\" object \"B2_55_deployed\" { code { + /// @src 1:124:189 \"contract B2 { function b(uint x) public pure { assert(x > 0); } }\" + mstore(64, memoryguard(128)) + + if iszero(lt(calldatasize(), 4)) { - /// @src 1:124:189 \"contract B2 { function b(uint x) public pure { assert(x > 0); } }\" - if iszero(lt(calldatasize(), 4)) + let selector := shift_right_224_unsigned(calldataload(0)) + switch selector + + case 0xcd580ff3 { - if eq(0xcd580ff3, shr(224, calldataload(0))) - { - if callvalue() { revert(0, 0) } - if slt(add(calldatasize(), not(3)), 32) { revert(0, 0) } - if /** @src 1:178:183 \"x > 0\" */ iszero(/** @src 1:124:189 \"contract B2 { function b(uint x) public pure { assert(x > 0); } }\" */ calldataload(4)) - { - mstore(0, shl(224, 0x4e487b71)) - mstore(4, 1) - revert(0, 0x24) - } - return(0, 0) - } + // b(uint256) + + external_fun_b_54() + } + + default {} + } + + revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() + + function shift_right_224_unsigned(value) -> newValue { + newValue := + + shr(224, value) + + } + + function allocate_unbounded() -> memPtr { + memPtr := mload(64) + } + + function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() { + revert(0, 0) + } + + function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() { + revert(0, 0) + } + + function revert_error_c1322bf8034eace5e0b5c7295db60986aa89aae5e0ea0873e4689e076861a5db() { + revert(0, 0) + } + + function cleanup_t_uint256(value) -> cleaned { + cleaned := value + } + + function validator_revert_t_uint256(value) { + if iszero(eq(value, cleanup_t_uint256(value))) { revert(0, 0) } + } + + function abi_decode_t_uint256(offset, end) -> value { + value := calldataload(offset) + validator_revert_t_uint256(value) + } + + function abi_decode_tuple_t_uint256(headStart, dataEnd) -> value0 { + if slt(sub(dataEnd, headStart), 32) { revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() } + + { + + let offset := 0 + + value0 := abi_decode_t_uint256(add(headStart, offset), dataEnd) } + + } + + function abi_encode_tuple__to__fromStack(headStart ) -> tail { + tail := add(headStart, 0) + + } + + function external_fun_b_54() { + + if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } + let param_0 := abi_decode_tuple_t_uint256(4, calldatasize()) + fun_b_54(param_0) + let memPos := allocate_unbounded() + let memEnd := abi_encode_tuple__to__fromStack(memPos ) + return(memPos, sub(memEnd, memPos)) + + } + + function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() { revert(0, 0) } + + function cleanup_t_rational_0_by_1(value) -> cleaned { + cleaned := value + } + + function identity(value) -> ret { + ret := value + } + + function convert_t_rational_0_by_1_to_t_uint256(value) -> converted { + converted := cleanup_t_uint256(identity(cleanup_t_rational_0_by_1(value))) + } + + function panic_error_0x01() { + mstore(0, 35408467139433450592217433187231851964531694900788300625387963629091585785856) + mstore(4, 0x01) + revert(0, 0x24) + } + + function assert_helper(condition) { + if iszero(condition) { panic_error_0x01() } + } + + /// @ast-id 54 + /// @src 1:138:187 \"function b(uint x) public pure { assert(x > 0); }\" + function fun_b_54(var_x_44) { + + /// @src 1:178:179 \"x\" + let _1 := var_x_44 + let expr_48 := _1 + /// @src 1:182:183 \"0\" + let expr_49 := 0x00 + /// @src 1:178:183 \"x > 0\" + let expr_50 := gt(cleanup_t_uint256(expr_48), convert_t_rational_0_by_1_to_t_uint256(expr_49)) + /// @src 1:171:184 \"assert(x > 0)\" + assert_helper(expr_50) + + } + /// @src 1:124:189 \"contract B2 { function b(uint x) public pure { assert(x > 0); } }\" + } + data \".metadata\" hex\"\" } + } + " } } diff --git a/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_optimizer/input.json b/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_optimizer/input.json new file mode 100644 index 000000000000..e45f27f3caa8 --- /dev/null +++ b/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_optimizer/input.json @@ -0,0 +1,24 @@ +{ + "language": "Solidity", + "sources": { + "a.sol": { + "content": "//SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract A1 { function a(uint x) public pure { assert(x > 0); } } contract A2 { function a(uint x) public pure { assert(x > 0); } }" + }, + "b.sol": { + "content": "//SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract A1 { function b(uint x) public pure { assert(x > 0); } } contract B2 { function b(uint x) public pure { assert(x > 0); } }" + } + }, + "settings": { + "viaIR": true, + "optimizer": { + "enabled": true + }, + "outputSelection": { + "*": { + "*": [ + "evm.bytecode.ethdebug", "evm.deployedBytecode.ethdebug", "irOptimized" + ] + } + } + } +} diff --git a/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_optimizer/output.json b/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_optimizer/output.json new file mode 100644 index 000000000000..3ed2f577c7aa --- /dev/null +++ b/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_optimizer/output.json @@ -0,0 +1,11 @@ +{ + "errors": [ + { + "component": "general", + "formattedMessage": "Optimization is not yet supported with ethdebug.", + "message": "Optimization is not yet supported with ethdebug.", + "severity": "error", + "type": "FatalError" + } + ] +} diff --git a/test/cmdlineTests/standard_output_selection_ethdebug_deployedbytecode/input.json b/test/cmdlineTests/standard_output_selection_ethdebug_deployedbytecode/input.json index 9e104dc177cc..f8e3ee312e6b 100644 --- a/test/cmdlineTests/standard_output_selection_ethdebug_deployedbytecode/input.json +++ b/test/cmdlineTests/standard_output_selection_ethdebug_deployedbytecode/input.json @@ -11,12 +11,12 @@ "settings": { "viaIR": true, "optimizer": { - "enabled": true + "enabled": false }, "outputSelection": { "*": { "*": [ - "evm.deployedBytecode.ethdebug", "irOptimized" + "evm.deployedBytecode.ethdebug", "ir" ] } } diff --git a/test/cmdlineTests/standard_output_selection_ethdebug_deployedbytecode/output.json b/test/cmdlineTests/standard_output_selection_ethdebug_deployedbytecode/output.json index 3ad7350a9fe8..4c7b4ed67197 100644 --- a/test/cmdlineTests/standard_output_selection_ethdebug_deployedbytecode/output.json +++ b/test/cmdlineTests/standard_output_selection_ethdebug_deployedbytecode/output.json @@ -7,46 +7,175 @@ "ethdebug": {} } }, - "irOptimized": "/// ethdebug: enabled + "ir": "/// ethdebug: enabled /// @use-src 0:\"a.sol\" object \"A1_14\" { code { - { + /// @src 0:58:123 \"contract A1 { function a(uint x) public pure { assert(x > 0); } }\" + mstore(64, memoryguard(128)) + if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } + + constructor_A1_14() + + let _1 := allocate_unbounded() + codecopy(_1, dataoffset(\"A1_14_deployed\"), datasize(\"A1_14_deployed\")) + + return(_1, datasize(\"A1_14_deployed\")) + + function allocate_unbounded() -> memPtr { + memPtr := mload(64) + } + + function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() { + revert(0, 0) + } + + /// @src 0:58:123 \"contract A1 { function a(uint x) public pure { assert(x > 0); } }\" + function constructor_A1_14() { + /// @src 0:58:123 \"contract A1 { function a(uint x) public pure { assert(x > 0); } }\" - let _1 := memoryguard(0x80) - mstore(64, _1) - if callvalue() { revert(0, 0) } - let _2 := datasize(\"A1_14_deployed\") - codecopy(_1, dataoffset(\"A1_14_deployed\"), _2) - return(_1, _2) + } + /// @src 0:58:123 \"contract A1 { function a(uint x) public pure { assert(x > 0); } }\" + } /// @use-src 0:\"a.sol\" object \"A1_14_deployed\" { code { + /// @src 0:58:123 \"contract A1 { function a(uint x) public pure { assert(x > 0); } }\" + mstore(64, memoryguard(128)) + + if iszero(lt(calldatasize(), 4)) { - /// @src 0:58:123 \"contract A1 { function a(uint x) public pure { assert(x > 0); } }\" - if iszero(lt(calldatasize(), 4)) + let selector := shift_right_224_unsigned(calldataload(0)) + switch selector + + case 0xf0fdf834 { - if eq(0xf0fdf834, shr(224, calldataload(0))) - { - if callvalue() { revert(0, 0) } - if slt(add(calldatasize(), not(3)), 32) { revert(0, 0) } - if /** @src 0:112:117 \"x > 0\" */ iszero(/** @src 0:58:123 \"contract A1 { function a(uint x) public pure { assert(x > 0); } }\" */ calldataload(4)) - { - mstore(0, shl(224, 0x4e487b71)) - mstore(4, 1) - revert(0, 0x24) - } - return(0, 0) - } + // a(uint256) + + external_fun_a_13() + } + + default {} + } + + revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() + + function shift_right_224_unsigned(value) -> newValue { + newValue := + + shr(224, value) + + } + + function allocate_unbounded() -> memPtr { + memPtr := mload(64) + } + + function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() { + revert(0, 0) + } + + function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() { + revert(0, 0) + } + + function revert_error_c1322bf8034eace5e0b5c7295db60986aa89aae5e0ea0873e4689e076861a5db() { + revert(0, 0) + } + + function cleanup_t_uint256(value) -> cleaned { + cleaned := value + } + + function validator_revert_t_uint256(value) { + if iszero(eq(value, cleanup_t_uint256(value))) { revert(0, 0) } + } + + function abi_decode_t_uint256(offset, end) -> value { + value := calldataload(offset) + validator_revert_t_uint256(value) + } + + function abi_decode_tuple_t_uint256(headStart, dataEnd) -> value0 { + if slt(sub(dataEnd, headStart), 32) { revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() } + + { + + let offset := 0 + + value0 := abi_decode_t_uint256(add(headStart, offset), dataEnd) } + + } + + function abi_encode_tuple__to__fromStack(headStart ) -> tail { + tail := add(headStart, 0) + + } + + function external_fun_a_13() { + + if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } + let param_0 := abi_decode_tuple_t_uint256(4, calldatasize()) + fun_a_13(param_0) + let memPos := allocate_unbounded() + let memEnd := abi_encode_tuple__to__fromStack(memPos ) + return(memPos, sub(memEnd, memPos)) + + } + + function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() { revert(0, 0) } + + function cleanup_t_rational_0_by_1(value) -> cleaned { + cleaned := value + } + + function identity(value) -> ret { + ret := value + } + + function convert_t_rational_0_by_1_to_t_uint256(value) -> converted { + converted := cleanup_t_uint256(identity(cleanup_t_rational_0_by_1(value))) + } + + function panic_error_0x01() { + mstore(0, 35408467139433450592217433187231851964531694900788300625387963629091585785856) + mstore(4, 0x01) + revert(0, 0x24) + } + + function assert_helper(condition) { + if iszero(condition) { panic_error_0x01() } + } + + /// @ast-id 13 + /// @src 0:72:121 \"function a(uint x) public pure { assert(x > 0); }\" + function fun_a_13(var_x_3) { + + /// @src 0:112:113 \"x\" + let _1 := var_x_3 + let expr_7 := _1 + /// @src 0:116:117 \"0\" + let expr_8 := 0x00 + /// @src 0:112:117 \"x > 0\" + let expr_9 := gt(cleanup_t_uint256(expr_7), convert_t_rational_0_by_1_to_t_uint256(expr_8)) + /// @src 0:105:118 \"assert(x > 0)\" + assert_helper(expr_9) + + } + /// @src 0:58:123 \"contract A1 { function a(uint x) public pure { assert(x > 0); } }\" + } + data \".metadata\" hex\"\" } + } + " }, "A2": { @@ -55,46 +184,175 @@ object \"A1_14\" { "ethdebug": {} } }, - "irOptimized": "/// ethdebug: enabled + "ir": "/// ethdebug: enabled /// @use-src 0:\"a.sol\" object \"A2_27\" { code { - { + /// @src 0:124:189 \"contract A2 { function a(uint x) public pure { assert(x > 0); } }\" + mstore(64, memoryguard(128)) + if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } + + constructor_A2_27() + + let _1 := allocate_unbounded() + codecopy(_1, dataoffset(\"A2_27_deployed\"), datasize(\"A2_27_deployed\")) + + return(_1, datasize(\"A2_27_deployed\")) + + function allocate_unbounded() -> memPtr { + memPtr := mload(64) + } + + function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() { + revert(0, 0) + } + + /// @src 0:124:189 \"contract A2 { function a(uint x) public pure { assert(x > 0); } }\" + function constructor_A2_27() { + /// @src 0:124:189 \"contract A2 { function a(uint x) public pure { assert(x > 0); } }\" - let _1 := memoryguard(0x80) - mstore(64, _1) - if callvalue() { revert(0, 0) } - let _2 := datasize(\"A2_27_deployed\") - codecopy(_1, dataoffset(\"A2_27_deployed\"), _2) - return(_1, _2) + } + /// @src 0:124:189 \"contract A2 { function a(uint x) public pure { assert(x > 0); } }\" + } /// @use-src 0:\"a.sol\" object \"A2_27_deployed\" { code { + /// @src 0:124:189 \"contract A2 { function a(uint x) public pure { assert(x > 0); } }\" + mstore(64, memoryguard(128)) + + if iszero(lt(calldatasize(), 4)) { - /// @src 0:124:189 \"contract A2 { function a(uint x) public pure { assert(x > 0); } }\" - if iszero(lt(calldatasize(), 4)) + let selector := shift_right_224_unsigned(calldataload(0)) + switch selector + + case 0xf0fdf834 { - if eq(0xf0fdf834, shr(224, calldataload(0))) - { - if callvalue() { revert(0, 0) } - if slt(add(calldatasize(), not(3)), 32) { revert(0, 0) } - if /** @src 0:178:183 \"x > 0\" */ iszero(/** @src 0:124:189 \"contract A2 { function a(uint x) public pure { assert(x > 0); } }\" */ calldataload(4)) - { - mstore(0, shl(224, 0x4e487b71)) - mstore(4, 1) - revert(0, 0x24) - } - return(0, 0) - } + // a(uint256) + + external_fun_a_26() + } + + default {} + } + + revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() + + function shift_right_224_unsigned(value) -> newValue { + newValue := + + shr(224, value) + + } + + function allocate_unbounded() -> memPtr { + memPtr := mload(64) + } + + function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() { + revert(0, 0) + } + + function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() { + revert(0, 0) + } + + function revert_error_c1322bf8034eace5e0b5c7295db60986aa89aae5e0ea0873e4689e076861a5db() { + revert(0, 0) + } + + function cleanup_t_uint256(value) -> cleaned { + cleaned := value + } + + function validator_revert_t_uint256(value) { + if iszero(eq(value, cleanup_t_uint256(value))) { revert(0, 0) } + } + + function abi_decode_t_uint256(offset, end) -> value { + value := calldataload(offset) + validator_revert_t_uint256(value) + } + + function abi_decode_tuple_t_uint256(headStart, dataEnd) -> value0 { + if slt(sub(dataEnd, headStart), 32) { revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() } + + { + + let offset := 0 + + value0 := abi_decode_t_uint256(add(headStart, offset), dataEnd) } + + } + + function abi_encode_tuple__to__fromStack(headStart ) -> tail { + tail := add(headStart, 0) + + } + + function external_fun_a_26() { + + if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } + let param_0 := abi_decode_tuple_t_uint256(4, calldatasize()) + fun_a_26(param_0) + let memPos := allocate_unbounded() + let memEnd := abi_encode_tuple__to__fromStack(memPos ) + return(memPos, sub(memEnd, memPos)) + + } + + function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() { revert(0, 0) } + + function cleanup_t_rational_0_by_1(value) -> cleaned { + cleaned := value + } + + function identity(value) -> ret { + ret := value + } + + function convert_t_rational_0_by_1_to_t_uint256(value) -> converted { + converted := cleanup_t_uint256(identity(cleanup_t_rational_0_by_1(value))) + } + + function panic_error_0x01() { + mstore(0, 35408467139433450592217433187231851964531694900788300625387963629091585785856) + mstore(4, 0x01) + revert(0, 0x24) + } + + function assert_helper(condition) { + if iszero(condition) { panic_error_0x01() } + } + + /// @ast-id 26 + /// @src 0:138:187 \"function a(uint x) public pure { assert(x > 0); }\" + function fun_a_26(var_x_16) { + + /// @src 0:178:179 \"x\" + let _1 := var_x_16 + let expr_20 := _1 + /// @src 0:182:183 \"0\" + let expr_21 := 0x00 + /// @src 0:178:183 \"x > 0\" + let expr_22 := gt(cleanup_t_uint256(expr_20), convert_t_rational_0_by_1_to_t_uint256(expr_21)) + /// @src 0:171:184 \"assert(x > 0)\" + assert_helper(expr_22) + + } + /// @src 0:124:189 \"contract A2 { function a(uint x) public pure { assert(x > 0); } }\" + } + data \".metadata\" hex\"\" } + } + " } }, @@ -105,46 +363,175 @@ object \"A2_27\" { "ethdebug": {} } }, - "irOptimized": "/// ethdebug: enabled + "ir": "/// ethdebug: enabled /// @use-src 1:\"b.sol\" object \"A1_42\" { code { - { + /// @src 1:58:123 \"contract A1 { function b(uint x) public pure { assert(x > 0); } }\" + mstore(64, memoryguard(128)) + if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } + + constructor_A1_42() + + let _1 := allocate_unbounded() + codecopy(_1, dataoffset(\"A1_42_deployed\"), datasize(\"A1_42_deployed\")) + + return(_1, datasize(\"A1_42_deployed\")) + + function allocate_unbounded() -> memPtr { + memPtr := mload(64) + } + + function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() { + revert(0, 0) + } + + /// @src 1:58:123 \"contract A1 { function b(uint x) public pure { assert(x > 0); } }\" + function constructor_A1_42() { + /// @src 1:58:123 \"contract A1 { function b(uint x) public pure { assert(x > 0); } }\" - let _1 := memoryguard(0x80) - mstore(64, _1) - if callvalue() { revert(0, 0) } - let _2 := datasize(\"A1_42_deployed\") - codecopy(_1, dataoffset(\"A1_42_deployed\"), _2) - return(_1, _2) + } + /// @src 1:58:123 \"contract A1 { function b(uint x) public pure { assert(x > 0); } }\" + } /// @use-src 1:\"b.sol\" object \"A1_42_deployed\" { code { + /// @src 1:58:123 \"contract A1 { function b(uint x) public pure { assert(x > 0); } }\" + mstore(64, memoryguard(128)) + + if iszero(lt(calldatasize(), 4)) { - /// @src 1:58:123 \"contract A1 { function b(uint x) public pure { assert(x > 0); } }\" - if iszero(lt(calldatasize(), 4)) + let selector := shift_right_224_unsigned(calldataload(0)) + switch selector + + case 0xcd580ff3 { - if eq(0xcd580ff3, shr(224, calldataload(0))) - { - if callvalue() { revert(0, 0) } - if slt(add(calldatasize(), not(3)), 32) { revert(0, 0) } - if /** @src 1:112:117 \"x > 0\" */ iszero(/** @src 1:58:123 \"contract A1 { function b(uint x) public pure { assert(x > 0); } }\" */ calldataload(4)) - { - mstore(0, shl(224, 0x4e487b71)) - mstore(4, 1) - revert(0, 0x24) - } - return(0, 0) - } + // b(uint256) + + external_fun_b_41() + } + + default {} + } + + revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() + + function shift_right_224_unsigned(value) -> newValue { + newValue := + + shr(224, value) + + } + + function allocate_unbounded() -> memPtr { + memPtr := mload(64) + } + + function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() { + revert(0, 0) + } + + function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() { + revert(0, 0) + } + + function revert_error_c1322bf8034eace5e0b5c7295db60986aa89aae5e0ea0873e4689e076861a5db() { + revert(0, 0) + } + + function cleanup_t_uint256(value) -> cleaned { + cleaned := value + } + + function validator_revert_t_uint256(value) { + if iszero(eq(value, cleanup_t_uint256(value))) { revert(0, 0) } + } + + function abi_decode_t_uint256(offset, end) -> value { + value := calldataload(offset) + validator_revert_t_uint256(value) + } + + function abi_decode_tuple_t_uint256(headStart, dataEnd) -> value0 { + if slt(sub(dataEnd, headStart), 32) { revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() } + + { + + let offset := 0 + + value0 := abi_decode_t_uint256(add(headStart, offset), dataEnd) } + + } + + function abi_encode_tuple__to__fromStack(headStart ) -> tail { + tail := add(headStart, 0) + + } + + function external_fun_b_41() { + + if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } + let param_0 := abi_decode_tuple_t_uint256(4, calldatasize()) + fun_b_41(param_0) + let memPos := allocate_unbounded() + let memEnd := abi_encode_tuple__to__fromStack(memPos ) + return(memPos, sub(memEnd, memPos)) + + } + + function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() { revert(0, 0) } + + function cleanup_t_rational_0_by_1(value) -> cleaned { + cleaned := value + } + + function identity(value) -> ret { + ret := value + } + + function convert_t_rational_0_by_1_to_t_uint256(value) -> converted { + converted := cleanup_t_uint256(identity(cleanup_t_rational_0_by_1(value))) + } + + function panic_error_0x01() { + mstore(0, 35408467139433450592217433187231851964531694900788300625387963629091585785856) + mstore(4, 0x01) + revert(0, 0x24) + } + + function assert_helper(condition) { + if iszero(condition) { panic_error_0x01() } + } + + /// @ast-id 41 + /// @src 1:72:121 \"function b(uint x) public pure { assert(x > 0); }\" + function fun_b_41(var_x_31) { + + /// @src 1:112:113 \"x\" + let _1 := var_x_31 + let expr_35 := _1 + /// @src 1:116:117 \"0\" + let expr_36 := 0x00 + /// @src 1:112:117 \"x > 0\" + let expr_37 := gt(cleanup_t_uint256(expr_35), convert_t_rational_0_by_1_to_t_uint256(expr_36)) + /// @src 1:105:118 \"assert(x > 0)\" + assert_helper(expr_37) + + } + /// @src 1:58:123 \"contract A1 { function b(uint x) public pure { assert(x > 0); } }\" + } + data \".metadata\" hex\"\" } + } + " }, "B2": { @@ -153,46 +540,175 @@ object \"A1_42\" { "ethdebug": {} } }, - "irOptimized": "/// ethdebug: enabled + "ir": "/// ethdebug: enabled /// @use-src 1:\"b.sol\" object \"B2_55\" { code { - { + /// @src 1:124:189 \"contract B2 { function b(uint x) public pure { assert(x > 0); } }\" + mstore(64, memoryguard(128)) + if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } + + constructor_B2_55() + + let _1 := allocate_unbounded() + codecopy(_1, dataoffset(\"B2_55_deployed\"), datasize(\"B2_55_deployed\")) + + return(_1, datasize(\"B2_55_deployed\")) + + function allocate_unbounded() -> memPtr { + memPtr := mload(64) + } + + function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() { + revert(0, 0) + } + + /// @src 1:124:189 \"contract B2 { function b(uint x) public pure { assert(x > 0); } }\" + function constructor_B2_55() { + /// @src 1:124:189 \"contract B2 { function b(uint x) public pure { assert(x > 0); } }\" - let _1 := memoryguard(0x80) - mstore(64, _1) - if callvalue() { revert(0, 0) } - let _2 := datasize(\"B2_55_deployed\") - codecopy(_1, dataoffset(\"B2_55_deployed\"), _2) - return(_1, _2) + } + /// @src 1:124:189 \"contract B2 { function b(uint x) public pure { assert(x > 0); } }\" + } /// @use-src 1:\"b.sol\" object \"B2_55_deployed\" { code { + /// @src 1:124:189 \"contract B2 { function b(uint x) public pure { assert(x > 0); } }\" + mstore(64, memoryguard(128)) + + if iszero(lt(calldatasize(), 4)) { - /// @src 1:124:189 \"contract B2 { function b(uint x) public pure { assert(x > 0); } }\" - if iszero(lt(calldatasize(), 4)) + let selector := shift_right_224_unsigned(calldataload(0)) + switch selector + + case 0xcd580ff3 { - if eq(0xcd580ff3, shr(224, calldataload(0))) - { - if callvalue() { revert(0, 0) } - if slt(add(calldatasize(), not(3)), 32) { revert(0, 0) } - if /** @src 1:178:183 \"x > 0\" */ iszero(/** @src 1:124:189 \"contract B2 { function b(uint x) public pure { assert(x > 0); } }\" */ calldataload(4)) - { - mstore(0, shl(224, 0x4e487b71)) - mstore(4, 1) - revert(0, 0x24) - } - return(0, 0) - } + // b(uint256) + + external_fun_b_54() + } + + default {} + } + + revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() + + function shift_right_224_unsigned(value) -> newValue { + newValue := + + shr(224, value) + + } + + function allocate_unbounded() -> memPtr { + memPtr := mload(64) + } + + function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() { + revert(0, 0) + } + + function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() { + revert(0, 0) + } + + function revert_error_c1322bf8034eace5e0b5c7295db60986aa89aae5e0ea0873e4689e076861a5db() { + revert(0, 0) + } + + function cleanup_t_uint256(value) -> cleaned { + cleaned := value + } + + function validator_revert_t_uint256(value) { + if iszero(eq(value, cleanup_t_uint256(value))) { revert(0, 0) } + } + + function abi_decode_t_uint256(offset, end) -> value { + value := calldataload(offset) + validator_revert_t_uint256(value) + } + + function abi_decode_tuple_t_uint256(headStart, dataEnd) -> value0 { + if slt(sub(dataEnd, headStart), 32) { revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() } + + { + + let offset := 0 + + value0 := abi_decode_t_uint256(add(headStart, offset), dataEnd) } + + } + + function abi_encode_tuple__to__fromStack(headStart ) -> tail { + tail := add(headStart, 0) + + } + + function external_fun_b_54() { + + if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } + let param_0 := abi_decode_tuple_t_uint256(4, calldatasize()) + fun_b_54(param_0) + let memPos := allocate_unbounded() + let memEnd := abi_encode_tuple__to__fromStack(memPos ) + return(memPos, sub(memEnd, memPos)) + + } + + function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() { revert(0, 0) } + + function cleanup_t_rational_0_by_1(value) -> cleaned { + cleaned := value + } + + function identity(value) -> ret { + ret := value + } + + function convert_t_rational_0_by_1_to_t_uint256(value) -> converted { + converted := cleanup_t_uint256(identity(cleanup_t_rational_0_by_1(value))) + } + + function panic_error_0x01() { + mstore(0, 35408467139433450592217433187231851964531694900788300625387963629091585785856) + mstore(4, 0x01) + revert(0, 0x24) + } + + function assert_helper(condition) { + if iszero(condition) { panic_error_0x01() } + } + + /// @ast-id 54 + /// @src 1:138:187 \"function b(uint x) public pure { assert(x > 0); }\" + function fun_b_54(var_x_44) { + + /// @src 1:178:179 \"x\" + let _1 := var_x_44 + let expr_48 := _1 + /// @src 1:182:183 \"0\" + let expr_49 := 0x00 + /// @src 1:178:183 \"x > 0\" + let expr_50 := gt(cleanup_t_uint256(expr_48), convert_t_rational_0_by_1_to_t_uint256(expr_49)) + /// @src 1:171:184 \"assert(x > 0)\" + assert_helper(expr_50) + + } + /// @src 1:124:189 \"contract B2 { function b(uint x) public pure { assert(x > 0); } }\" + } + data \".metadata\" hex\"\" } + } + " } } diff --git a/test/cmdlineTests/standard_output_selection_ethdebug_irOptimized/input.json b/test/cmdlineTests/standard_output_selection_ethdebug_irOptimized/input.json new file mode 100644 index 000000000000..ab13b27ea6ea --- /dev/null +++ b/test/cmdlineTests/standard_output_selection_ethdebug_irOptimized/input.json @@ -0,0 +1,21 @@ +{ + "language": "Solidity", + "sources": { + "a.sol": { + "content": "//SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract A1 { function a(uint x) public pure { assert(x > 0); } } contract A2 { function a(uint x) public pure { assert(x > 0); } }" + }, + "b.sol": { + "content": "//SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract A1 { function b(uint x) public pure { assert(x > 0); } } contract B2 { function b(uint x) public pure { assert(x > 0); } }" + } + }, + "settings": { + "viaIR": true, + "outputSelection": { + "*": { + "*": [ + "evm.bytecode.ethdebug", "irOptimized" + ] + } + } + } +} diff --git a/test/cmdlineTests/standard_output_selection_ethdebug_irOptimized/output.json b/test/cmdlineTests/standard_output_selection_ethdebug_irOptimized/output.json new file mode 100644 index 000000000000..3ed2f577c7aa --- /dev/null +++ b/test/cmdlineTests/standard_output_selection_ethdebug_irOptimized/output.json @@ -0,0 +1,11 @@ +{ + "errors": [ + { + "component": "general", + "formattedMessage": "Optimization is not yet supported with ethdebug.", + "message": "Optimization is not yet supported with ethdebug.", + "severity": "error", + "type": "FatalError" + } + ] +} diff --git a/test/cmdlineTests/standard_output_selection_ethdebug_optimize/input.json b/test/cmdlineTests/standard_output_selection_ethdebug_optimize/input.json new file mode 100644 index 000000000000..a8a5cff05d0b --- /dev/null +++ b/test/cmdlineTests/standard_output_selection_ethdebug_optimize/input.json @@ -0,0 +1,24 @@ +{ + "language": "Solidity", + "sources": { + "a.sol": { + "content": "//SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract A1 { function a(uint x) public pure { assert(x > 0); } } contract A2 { function a(uint x) public pure { assert(x > 0); } }" + }, + "b.sol": { + "content": "//SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract A1 { function b(uint x) public pure { assert(x > 0); } } contract B2 { function b(uint x) public pure { assert(x > 0); } }" + } + }, + "settings": { + "viaIR": true, + "optimizer": { + "enabled": true + }, + "outputSelection": { + "*": { + "*": [ + "evm.bytecode.ethdebug", "ir" + ] + } + } + } +} diff --git a/test/cmdlineTests/standard_output_selection_ethdebug_optimize/output.json b/test/cmdlineTests/standard_output_selection_ethdebug_optimize/output.json new file mode 100644 index 000000000000..3ed2f577c7aa --- /dev/null +++ b/test/cmdlineTests/standard_output_selection_ethdebug_optimize/output.json @@ -0,0 +1,11 @@ +{ + "errors": [ + { + "component": "general", + "formattedMessage": "Optimization is not yet supported with ethdebug.", + "message": "Optimization is not yet supported with ethdebug.", + "severity": "error", + "type": "FatalError" + } + ] +} diff --git a/test/cmdlineTests/standard_yul_ethdebug_bytecode/input.json b/test/cmdlineTests/standard_yul_ethdebug_bytecode/input.json index 86761f23659c..f3346fdd10e3 100644 --- a/test/cmdlineTests/standard_yul_ethdebug_bytecode/input.json +++ b/test/cmdlineTests/standard_yul_ethdebug_bytecode/input.json @@ -4,11 +4,8 @@ "C": {"urls": ["standard_yul_debug_info_print_all/in.yul"]} }, "settings": { - "optimizer": { - "enabled": true - }, "outputSelection": { - "*": {"*": ["evm.bytecode.ethdebug", "irOptimized"]} + "*": {"*": ["evm.bytecode.ethdebug", "ir"]} } } } diff --git a/test/cmdlineTests/standard_yul_ethdebug_bytecode/output.json b/test/cmdlineTests/standard_yul_ethdebug_bytecode/output.json index 0e93c5b77f30..c9ab1d8f5e73 100644 --- a/test/cmdlineTests/standard_yul_ethdebug_bytecode/output.json +++ b/test/cmdlineTests/standard_yul_ethdebug_bytecode/output.json @@ -9,14 +9,16 @@ } } }, - "irOptimized": "/// ethdebug: enabled + "ir": "/// ethdebug: enabled /// @use-src 0:\"input.sol\" object \"C_6_deployed\" { code { - { - /// @src 0:77:99 - sstore(0, 42) - } + /// @src 0:60:101 + mstore(64, 128) + fun_f_5() + /// @src 0:77:99 + function fun_f_5() + { sstore(0, 42) } } } " diff --git a/test/cmdlineTests/standard_yul_ethdebug_irOptimized/args b/test/cmdlineTests/standard_yul_ethdebug_irOptimized/args new file mode 100644 index 000000000000..18532c5a6d3f --- /dev/null +++ b/test/cmdlineTests/standard_yul_ethdebug_irOptimized/args @@ -0,0 +1 @@ +--allow-paths . diff --git a/test/cmdlineTests/standard_yul_ethdebug_irOptimized/in.yul b/test/cmdlineTests/standard_yul_ethdebug_irOptimized/in.yul new file mode 100644 index 000000000000..920aef8e9dc2 --- /dev/null +++ b/test/cmdlineTests/standard_yul_ethdebug_irOptimized/in.yul @@ -0,0 +1,17 @@ +/// @use-src 0:"input.sol" +object "C_6_deployed" { + code { + /// @src 0:60:101 "contract C {..." + mstore(64, 128) + + // f() + fun_f_5() + + /// @src 0:77:99 "function f() public {}" + function fun_f_5() { + sstore(0, 42) + } + /// @src 0:60:101 "contract C {..." + } +} + diff --git a/test/cmdlineTests/standard_yul_ethdebug_irOptimized/input.json b/test/cmdlineTests/standard_yul_ethdebug_irOptimized/input.json new file mode 100644 index 000000000000..89994857f418 --- /dev/null +++ b/test/cmdlineTests/standard_yul_ethdebug_irOptimized/input.json @@ -0,0 +1,11 @@ +{ + "language": "Yul", + "sources": { + "C": {"urls": ["standard_yul_debug_info_print_all/in.yul"]} + }, + "settings": { + "outputSelection": { + "*": {"*": ["evm.bytecode.ethdebug", "irOptimized"]} + } + } +} diff --git a/test/cmdlineTests/standard_yul_ethdebug_irOptimized/output.json b/test/cmdlineTests/standard_yul_ethdebug_irOptimized/output.json new file mode 100644 index 000000000000..3ed2f577c7aa --- /dev/null +++ b/test/cmdlineTests/standard_yul_ethdebug_irOptimized/output.json @@ -0,0 +1,11 @@ +{ + "errors": [ + { + "component": "general", + "formattedMessage": "Optimization is not yet supported with ethdebug.", + "message": "Optimization is not yet supported with ethdebug.", + "severity": "error", + "type": "FatalError" + } + ] +} diff --git a/test/cmdlineTests/standard_yul_ethdebug_optimize/args b/test/cmdlineTests/standard_yul_ethdebug_optimize/args new file mode 100644 index 000000000000..18532c5a6d3f --- /dev/null +++ b/test/cmdlineTests/standard_yul_ethdebug_optimize/args @@ -0,0 +1 @@ +--allow-paths . diff --git a/test/cmdlineTests/standard_yul_ethdebug_optimize/in.yul b/test/cmdlineTests/standard_yul_ethdebug_optimize/in.yul new file mode 100644 index 000000000000..920aef8e9dc2 --- /dev/null +++ b/test/cmdlineTests/standard_yul_ethdebug_optimize/in.yul @@ -0,0 +1,17 @@ +/// @use-src 0:"input.sol" +object "C_6_deployed" { + code { + /// @src 0:60:101 "contract C {..." + mstore(64, 128) + + // f() + fun_f_5() + + /// @src 0:77:99 "function f() public {}" + function fun_f_5() { + sstore(0, 42) + } + /// @src 0:60:101 "contract C {..." + } +} + diff --git a/test/cmdlineTests/standard_yul_ethdebug_optimize/input.json b/test/cmdlineTests/standard_yul_ethdebug_optimize/input.json new file mode 100644 index 000000000000..fb232f23a1fb --- /dev/null +++ b/test/cmdlineTests/standard_yul_ethdebug_optimize/input.json @@ -0,0 +1,14 @@ +{ + "language": "Yul", + "sources": { + "C": {"urls": ["standard_yul_debug_info_print_all/in.yul"]} + }, + "settings": { + "optimizer": { + "enabled": true + }, + "outputSelection": { + "*": {"*": ["evm.bytecode.ethdebug", "ir"]} + } + } +} diff --git a/test/cmdlineTests/standard_yul_ethdebug_optimize/output.json b/test/cmdlineTests/standard_yul_ethdebug_optimize/output.json new file mode 100644 index 000000000000..3ed2f577c7aa --- /dev/null +++ b/test/cmdlineTests/standard_yul_ethdebug_optimize/output.json @@ -0,0 +1,11 @@ +{ + "errors": [ + { + "component": "general", + "formattedMessage": "Optimization is not yet supported with ethdebug.", + "message": "Optimization is not yet supported with ethdebug.", + "severity": "error", + "type": "FatalError" + } + ] +} diff --git a/test/libsolidity/StandardCompiler.cpp b/test/libsolidity/StandardCompiler.cpp index 80cba338202d..3161eba2a868 100644 --- a/test/libsolidity/StandardCompiler.cpp +++ b/test/libsolidity/StandardCompiler.cpp @@ -1975,7 +1975,7 @@ BOOST_AUTO_TEST_CASE(ethdebug_debug_info_ethdebug) } }, { - generateStandardJson(false, Json::array({"ethdebug"}), Json::array({"irOptimized"})), + generateStandardJson(false, Json::array({"ethdebug"}), Json::array({"ir"})), {}, [](const Json& result) { @@ -2007,7 +2007,7 @@ BOOST_AUTO_TEST_CASE(ethdebug_debug_info_ethdebug) } }, { - generateStandardJson(true, {}, Json::array({"irOptimized", "evm.bytecode.ethdebug"})), + generateStandardJson(true, {}, Json::array({"ir", "evm.bytecode.ethdebug"})), {}, [](const Json& result) { @@ -2015,7 +2015,7 @@ BOOST_AUTO_TEST_CASE(ethdebug_debug_info_ethdebug) } }, { - generateStandardJson(true, {}, Json::array({"irOptimized", "evm.deployedBytecode.ethdebug"})), + generateStandardJson(true, {}, Json::array({"ir", "evm.deployedBytecode.ethdebug"})), {}, [](const Json& result) { @@ -2023,7 +2023,7 @@ BOOST_AUTO_TEST_CASE(ethdebug_debug_info_ethdebug) } }, { - generateStandardJson(true, {}, Json::array({"irOptimized", "evm.bytecode.ethdebug", "evm.deployedBytecode.ethdebug"})), + generateStandardJson(true, {}, Json::array({"ir", "evm.bytecode.ethdebug", "evm.deployedBytecode.ethdebug"})), {}, [](const Json& result) { @@ -2040,14 +2040,11 @@ BOOST_AUTO_TEST_CASE(ethdebug_debug_info_ethdebug) }, { generateStandardJson(true, Json::array({"ethdebug"}), Json::array({"irOptimized"}), YulCode()), - {}, - [](const Json& result) - { - return result.dump().find("/// ethdebug: enabled") != std::string::npos; - } + "Optimization is not yet supported with ethdebug.", + {} }, { - generateStandardJson(true, Json::array({"ethdebugs"}), Json::array({"irOptimized"}), YulCode()), + generateStandardJson(true, Json::array({"ethdebugs"}), Json::array({"ir"}), YulCode()), "Invalid value in settings.debug.debugInfo.", {} }, diff --git a/test/solc/CommandLineInterface.cpp b/test/solc/CommandLineInterface.cpp index 8dfcedac8548..17166268a656 100644 --- a/test/solc/CommandLineInterface.cpp +++ b/test/solc/CommandLineInterface.cpp @@ -1431,15 +1431,23 @@ BOOST_AUTO_TEST_CASE(cli_ethdebug_incompatible_outputs) }, { {"solc", "--via-ir", "--ethdebug", "--asm-json", tempDir.path().string() + "/input.sol"}, - "Error: --ethdebug / --ethdebug-runtime output can only be used with --ir / --ir-optimized.\n" + "Error: --ethdebug / --ethdebug-runtime output can only be used with --ir. Optimization is not yet supported with ethdebug, e.g. no support for --optimize / --ir-optimized yet.\n" + }, + { + {"solc", "--via-ir", "--ethdebug", "--optimize", tempDir.path().string() + "/input.sol"}, + "Error: --ethdebug / --ethdebug-runtime output can only be used with --ir. Optimization is not yet supported with ethdebug, e.g. no support for --optimize / --ir-optimized yet.\n" + }, + { + {"solc", "--via-ir", "--ethdebug", "--ir-optimized", tempDir.path().string() + "/input.sol"}, + "Error: --ethdebug / --ethdebug-runtime output can only be used with --ir. Optimization is not yet supported with ethdebug, e.g. no support for --optimize / --ir-optimized yet.\n" }, { {"solc", "--via-ir", "--ethdebug", "--ir-ast-json", tempDir.path().string() + "/input.sol"}, - "Error: --ethdebug / --ethdebug-runtime output can only be used with --ir / --ir-optimized.\n" + "Error: --ethdebug / --ethdebug-runtime output can only be used with --ir. Optimization is not yet supported with ethdebug, e.g. no support for --optimize / --ir-optimized yet.\n" }, { {"solc", "--via-ir", "--ethdebug", "--ir-optimized-ast-json", tempDir.path().string() + "/input.sol"}, - "Error: --ethdebug / --ethdebug-runtime output can only be used with --ir / --ir-optimized.\n" + "Error: --ethdebug / --ethdebug-runtime output can only be used with --ir. Optimization is not yet supported with ethdebug, e.g. no support for --optimize / --ir-optimized yet.\n" }, { {"solc", "--ethdebug", "--import-asm-json", tempDir.path().string() + "/input.json"}, @@ -1447,7 +1455,7 @@ BOOST_AUTO_TEST_CASE(cli_ethdebug_incompatible_outputs) }, { {"solc", "--via-ir", "--ethdebug", "--asm-json", tempDir.path().string() + "/input.sol"}, - "Error: --ethdebug / --ethdebug-runtime output can only be used with --ir / --ir-optimized.\n" + "Error: --ethdebug / --ethdebug-runtime output can only be used with --ir. Optimization is not yet supported with ethdebug, e.g. no support for --optimize / --ir-optimized yet.\n" }, { {"solc", "--ethdebug-runtime", "--asm-json", tempDir.path().string() + "/input.sol"}, @@ -1455,15 +1463,15 @@ BOOST_AUTO_TEST_CASE(cli_ethdebug_incompatible_outputs) }, { {"solc", "--via-ir", "--ethdebug-runtime", "--asm-json", tempDir.path().string() + "/input.sol"}, - "Error: --ethdebug / --ethdebug-runtime output can only be used with --ir / --ir-optimized.\n" + "Error: --ethdebug / --ethdebug-runtime output can only be used with --ir. Optimization is not yet supported with ethdebug, e.g. no support for --optimize / --ir-optimized yet.\n" }, { {"solc", "--via-ir", "--ethdebug-runtime", "--ir-ast-json", tempDir.path().string() + "/input.sol"}, - "Error: --ethdebug / --ethdebug-runtime output can only be used with --ir / --ir-optimized.\n" + "Error: --ethdebug / --ethdebug-runtime output can only be used with --ir. Optimization is not yet supported with ethdebug, e.g. no support for --optimize / --ir-optimized yet.\n" }, { {"solc", "--via-ir", "--ethdebug-runtime", "--ir-optimized-ast-json", tempDir.path().string() + "/input.sol"}, - "Error: --ethdebug / --ethdebug-runtime output can only be used with --ir / --ir-optimized.\n" + "Error: --ethdebug / --ethdebug-runtime output can only be used with --ir. Optimization is not yet supported with ethdebug, e.g. no support for --optimize / --ir-optimized yet.\n" }, { {"solc", "--ethdebug-runtime", "--import-asm-json", tempDir.path().string() + "/input.json"}, @@ -1471,23 +1479,23 @@ BOOST_AUTO_TEST_CASE(cli_ethdebug_incompatible_outputs) }, { {"solc", "--via-ir", "--ethdebug-runtime", "--asm-json", tempDir.path().string() + "/input.sol"}, - "Error: --ethdebug / --ethdebug-runtime output can only be used with --ir / --ir-optimized.\n" + "Error: --ethdebug / --ethdebug-runtime output can only be used with --ir. Optimization is not yet supported with ethdebug, e.g. no support for --optimize / --ir-optimized yet.\n" }, { {"solc", "--debug-info", "ethdebug", "--asm-json", tempDir.path().string() + "/input.sol"}, - "Error: --debug-info ethdebug can only be used with --ir / --ir-optimized and/or --ethdebug / --ethdebug-runtime.\n" + "Error: --debug-info ethdebug can only be used with --ir and/or --ethdebug / --ethdebug-runtime. Optimization is not yet supported with ethdebug, e.g. no support for --optimize / --ir-optimized yet.\n" }, { {"solc", "--debug-info", "ethdebug", "--asm-json", tempDir.path().string() + "/input.sol"}, - "Error: --debug-info ethdebug can only be used with --ir / --ir-optimized and/or --ethdebug / --ethdebug-runtime.\n" + "Error: --debug-info ethdebug can only be used with --ir and/or --ethdebug / --ethdebug-runtime. Optimization is not yet supported with ethdebug, e.g. no support for --optimize / --ir-optimized yet.\n" }, { {"solc", "--debug-info", "ethdebug", "--ir-ast-json", tempDir.path().string() + "/input.sol"}, - "Error: --debug-info ethdebug can only be used with --ir / --ir-optimized and/or --ethdebug / --ethdebug-runtime.\n" + "Error: --debug-info ethdebug can only be used with --ir and/or --ethdebug / --ethdebug-runtime. Optimization is not yet supported with ethdebug, e.g. no support for --optimize / --ir-optimized yet.\n" }, { {"solc", "--debug-info", "ethdebug", "--ir-optimized-ast-json", tempDir.path().string() + "/input.sol"}, - "Error: --debug-info ethdebug can only be used with --ir / --ir-optimized and/or --ethdebug / --ethdebug-runtime.\n" + "Error: --debug-info ethdebug can only be used with --ir and/or --ethdebug / --ethdebug-runtime. Optimization is not yet supported with ethdebug, e.g. no support for --optimize / --ir-optimized yet.\n" }, { {"solc", "--debug-info", "ethdebug", "--import-asm-json", tempDir.path().string() + "/input.json"}, @@ -1499,7 +1507,7 @@ BOOST_AUTO_TEST_CASE(cli_ethdebug_incompatible_outputs) }, { {"solc", "--debug-info", "ethdebug", "--asm-json", tempDir.path().string() + "/input.json"}, - "Error: --debug-info ethdebug can only be used with --ir / --ir-optimized and/or --ethdebug / --ethdebug-runtime.\n" + "Error: --debug-info ethdebug can only be used with --ir and/or --ethdebug / --ethdebug-runtime. Optimization is not yet supported with ethdebug, e.g. no support for --optimize / --ir-optimized yet.\n" } }; for (auto const& test: tests) @@ -1560,7 +1568,7 @@ BOOST_AUTO_TEST_CASE(cli_ethdebug_debug_info_ethdebug) static std::vector, std::vector, std::vector>> tests{ { {"solc", "--debug-info", "ethdebug", tempDir.path().string() + "/input.sol"}, - {"Error: --debug-info ethdebug can only be used with --ir / --ir-optimized and/or --ethdebug / --ethdebug-runtime.\n"}, + {"Error: --debug-info ethdebug can only be used with --ir and/or --ethdebug / --ethdebug-runtime. Optimization is not yet supported with ethdebug, e.g. no support for --optimize / --ir-optimized yet.\n"}, {}, }, { @@ -1570,8 +1578,13 @@ BOOST_AUTO_TEST_CASE(cli_ethdebug_debug_info_ethdebug) }, { {"solc", "--debug-info", "ethdebug", "--ir-optimized", tempDir.path().string() + "/input.sol"}, + {"Error: --debug-info ethdebug can only be used with --ir and/or --ethdebug / --ethdebug-runtime. Optimization is not yet supported with ethdebug, e.g. no support for --optimize / --ir-optimized yet.\n"}, + {}, + }, + { + {"solc", "--debug-info", "ethdebug", "--optimize", tempDir.path().string() + "/input.sol"}, + {"Error: --debug-info ethdebug can only be used with --ir and/or --ethdebug / --ethdebug-runtime. Optimization is not yet supported with ethdebug, e.g. no support for --optimize / --ir-optimized yet.\n"}, {}, - {"/// ethdebug: enabled"}, }, { {"solc", "--debug-info", "ethdebug", "--ethdebug", tempDir.path().string() + "/input.sol"}, @@ -1722,33 +1735,33 @@ BOOST_AUTO_TEST_CASE(cli_ethdebug_ethdebug_output) }, { {"solc", "--ethdebug", "--via-ir", "--ir-optimized", tempDir.path().string() + "/input.sol"}, + {"Error: --ethdebug / --ethdebug-runtime output can only be used with --ir. Optimization is not yet supported with ethdebug, e.g. no support for --optimize / --ir-optimized yet.\n"}, {}, - {"======= Debug Data (ethdebug/format/info/resources) =======", "Debug Data (ethdebug/format/program)", "/// ethdebug: enabled"}, }, { {"solc", "--ethdebug-runtime", "--via-ir", "--ir-optimized", tempDir.path().string() + "/input.sol"}, + {"Error: --ethdebug / --ethdebug-runtime output can only be used with --ir. Optimization is not yet supported with ethdebug, e.g. no support for --optimize / --ir-optimized yet.\n"}, {}, - {"======= Debug Data (ethdebug/format/info/resources) =======", "Debug Data of the runtime part (ethdebug/format/program)", "/// ethdebug: enabled"}, }, { {"solc", "--ethdebug", "--ethdebug-runtime", "--via-ir", "--ir-optimized", tempDir.path().string() + "/input.sol"}, + {"Error: --ethdebug / --ethdebug-runtime output can only be used with --ir. Optimization is not yet supported with ethdebug, e.g. no support for --optimize / --ir-optimized yet.\n"}, {}, - {"======= Debug Data (ethdebug/format/info/resources) =======", "Debug Data (ethdebug/format/program)", "Debug Data of the runtime part (ethdebug/format/program)", "/// ethdebug: enabled"}, }, { {"solc", "--ethdebug", "--via-ir", "--ir-optimized", "--optimize", tempDir.path().string() + "/input.sol"}, + {"Error: --ethdebug / --ethdebug-runtime output can only be used with --ir. Optimization is not yet supported with ethdebug, e.g. no support for --optimize / --ir-optimized yet.\n"}, {}, - {"======= Debug Data (ethdebug/format/info/resources) =======", "Debug Data (ethdebug/format/program)", "/// ethdebug: enabled"}, }, { {"solc", "--ethdebug-runtime", "--via-ir", "--ir-optimized", "--optimize", tempDir.path().string() + "/input.sol"}, + {"Error: --ethdebug / --ethdebug-runtime output can only be used with --ir. Optimization is not yet supported with ethdebug, e.g. no support for --optimize / --ir-optimized yet.\n"}, {}, - {"======= Debug Data (ethdebug/format/info/resources) =======", "Debug Data of the runtime part (ethdebug/format/program)", "/// ethdebug: enabled"}, }, { {"solc", "--ethdebug", "--ethdebug-runtime", "--via-ir", "--ir-optimized", "--optimize", tempDir.path().string() + "/input.sol"}, + {"Error: --ethdebug / --ethdebug-runtime output can only be used with --ir. Optimization is not yet supported with ethdebug, e.g. no support for --optimize / --ir-optimized yet.\n"}, {}, - {"======= Debug Data (ethdebug/format/info/resources) =======", "Debug Data (ethdebug/format/program)", "Debug Data of the runtime part (ethdebug/format/program)", "/// ethdebug: enabled"}, }, }; for (auto const& test: tests) diff --git a/test/solc/CommandLineParser.cpp b/test/solc/CommandLineParser.cpp index be3e25d3302c..85eeaebe31a8 100644 --- a/test/solc/CommandLineParser.cpp +++ b/test/solc/CommandLineParser.cpp @@ -663,12 +663,6 @@ BOOST_AUTO_TEST_CASE(ethdebug) BOOST_CHECK_EQUAL(commandLineOptions.compiler.outputs.ir, true); BOOST_CHECK_EQUAL(commandLineOptions.output.debugInfoSelection.has_value(), true); BOOST_CHECK_EQUAL(commandLineOptions.output.debugInfoSelection->ethdebug, true); - commandLineOptions = parseCommandLine({"solc", "contract.sol", "--debug-info", "ethdebug", "--ir-optimized"}); - BOOST_CHECK_EQUAL(commandLineOptions.compiler.outputs.ethdebug, false); - BOOST_CHECK_EQUAL(commandLineOptions.compiler.outputs.ethdebugRuntime, false); - BOOST_CHECK_EQUAL(commandLineOptions.compiler.outputs.irOptimized, true); - BOOST_CHECK_EQUAL(commandLineOptions.output.debugInfoSelection.has_value(), true); - BOOST_CHECK_EQUAL(commandLineOptions.output.debugInfoSelection->ethdebug, true); } BOOST_AUTO_TEST_SUITE_END() From 3bb6a0138ea7320eb5f72b8056c17951a51833ed Mon Sep 17 00:00:00 2001 From: rodiazet Date: Tue, 28 Jan 2025 11:06:29 +0100 Subject: [PATCH 0736/1022] eof: Fix condition when generating custom error for builtins available in EOF but not in legacy --- libyul/AsmAnalysis.cpp | 7 ++++--- .../eof/eof_identifiers_not_defined_in_legacy.yul | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/libyul/AsmAnalysis.cpp b/libyul/AsmAnalysis.cpp index 69f2e765e0b9..b6dcbb08e2dc 100644 --- a/libyul/AsmAnalysis.cpp +++ b/libyul/AsmAnalysis.cpp @@ -690,21 +690,22 @@ void AsmAnalyzer::expectValidIdentifier(YulName _identifier, SourceLocation cons bool AsmAnalyzer::validateInstructions(std::string_view _instructionIdentifier, langutil::SourceLocation const& _location) { // NOTE: This function uses the default EVM version instead of the currently selected one. - auto const& defaultEVMDialect = EVMDialect::strictAssemblyForEVM(EVMVersion{}, std::nullopt); + auto const& defaultEVMDialect = EVMDialect::strictAssemblyForEVMObjects(EVMVersion{}, std::nullopt); auto const builtinHandle = defaultEVMDialect.findBuiltin(_instructionIdentifier); if (builtinHandle && defaultEVMDialect.builtin(*builtinHandle).instruction.has_value()) return validateInstructions(*defaultEVMDialect.builtin(*builtinHandle).instruction, _location); solAssert(!m_eofVersion.has_value() || (*m_eofVersion == 1 && m_evmVersion == langutil::EVMVersion::prague())); // TODO: Change `prague()` to `EVMVersion{}` once EOF gets deployed - auto const& eofDialect = EVMDialect::strictAssemblyForEVM(EVMVersion::prague(), 1); + auto const& eofDialect = EVMDialect::strictAssemblyForEVMObjects(EVMVersion::prague(), 1); auto const eofBuiltinHandle = eofDialect.findBuiltin(_instructionIdentifier); if (eofBuiltinHandle) { auto const builtin = eofDialect.builtin(*eofBuiltinHandle); if (builtin.instruction.has_value()) return validateInstructions(*builtin.instruction, _location); - else if (!m_eofVersion.has_value()) + // If builtin is available in EOF but not available in legacy (and we build to legacy) generate custom error. + else if (!m_eofVersion.has_value() && !builtinHandle) { m_errorReporter.declarationError( 7223_error, diff --git a/test/libyul/yulSyntaxTests/eof/eof_identifiers_not_defined_in_legacy.yul b/test/libyul/yulSyntaxTests/eof/eof_identifiers_not_defined_in_legacy.yul index ab55fb21d786..0b786893ec06 100644 --- a/test/libyul/yulSyntaxTests/eof/eof_identifiers_not_defined_in_legacy.yul +++ b/test/libyul/yulSyntaxTests/eof/eof_identifiers_not_defined_in_legacy.yul @@ -18,7 +18,7 @@ // DeclarationError 7223: (6-18): Builtin function "auxdataloadn" is only available in EOF. // DeclarationError 4619: (26-35): Function "dataloadn" not found. // DeclarationError 7223: (43-52): Builtin function "eofcreate" is only available in EOF. -// DeclarationError 4619: (77-91): Function "returncontract" not found. +// DeclarationError 7223: (77-91): Builtin function "returncontract" is only available in EOF. // DeclarationError 4619: (110-115): Function "rjump" not found. // DeclarationError 4619: (122-128): Function "rjumpi" not found. // DeclarationError 4619: (135-140): Function "callf" not found. From 677c84a84c240245bf895381baa23ce10a4ba1ba Mon Sep 17 00:00:00 2001 From: rodiazet Date: Fri, 24 Jan 2025 11:22:31 +0100 Subject: [PATCH 0737/1022] eof: Disallow EOF builtins in inline assembly. --- libyul/backends/evm/EVMDialect.cpp | 86 ++++++++++--------- .../invalid/eof/eof_builtins_disallowed.sol | 15 ++++ ...builtins_disallowed_in_inline_assembly.sol | 16 ++++ 3 files changed, 75 insertions(+), 42 deletions(-) create mode 100644 test/libsolidity/syntaxTests/inlineAssembly/invalid/eof/eof_builtins_disallowed.sol create mode 100644 test/libsolidity/syntaxTests/inlineAssembly/invalid/eof/eof_builtins_disallowed_in_inline_assembly.sol diff --git a/libyul/backends/evm/EVMDialect.cpp b/libyul/backends/evm/EVMDialect.cpp index 74599eb1c449..611e95c39d72 100644 --- a/libyul/backends/evm/EVMDialect.cpp +++ b/libyul/backends/evm/EVMDialect.cpp @@ -381,50 +381,51 @@ std::vector> createBuiltins(langutil::EVMVe } else // EOF context { - builtins.emplace_back(createFunction( - "auxdataloadn", - 1, - 1, - EVMDialect::sideEffectsOfInstruction(evmasm::Instruction::DATALOADN), - ControlFlowSideEffects::fromInstruction(evmasm::Instruction::DATALOADN), - {LiteralKind::Number}, - []( - FunctionCall const& _call, - AbstractAssembly& _assembly, - BuiltinContext& - ) { - yulAssert(_call.arguments.size() == 1); - Literal const* literal = std::get_if(&_call.arguments.front()); - yulAssert(literal, ""); - yulAssert(literal->value.value() <= std::numeric_limits::max()); - _assembly.appendAuxDataLoadN(static_cast(literal->value.value())); - } - )); - - builtins.emplace_back(createFunction( - "eofcreate", - 5, - 1, - EVMDialect::sideEffectsOfInstruction(evmasm::Instruction::EOFCREATE), - ControlFlowSideEffects::fromInstruction(evmasm::Instruction::EOFCREATE), - {LiteralKind::String, std::nullopt, std::nullopt, std::nullopt, std::nullopt}, - []( - FunctionCall const& _call, - AbstractAssembly& _assembly, - BuiltinContext& context - ) { - yulAssert(_call.arguments.size() == 5); - Literal const* literal = std::get_if(&_call.arguments.front()); - auto const formattedLiteral = formatLiteral(*literal); - yulAssert(!util::contains(formattedLiteral, '.')); - auto const* containerID = valueOrNullptr(context.subIDs, formattedLiteral); - yulAssert(containerID != nullptr); - yulAssert(*containerID <= std::numeric_limits::max()); - _assembly.appendEOFCreate(static_cast(*containerID)); - } + if (_objectAccess) + { + builtins.emplace_back(createFunction( + "auxdataloadn", + 1, + 1, + EVMDialect::sideEffectsOfInstruction(evmasm::Instruction::DATALOADN), + ControlFlowSideEffects::fromInstruction(evmasm::Instruction::DATALOADN), + {LiteralKind::Number}, + []( + FunctionCall const& _call, + AbstractAssembly& _assembly, + BuiltinContext& + ) { + yulAssert(_call.arguments.size() == 1); + Literal const* literal = std::get_if(&_call.arguments.front()); + yulAssert(literal, ""); + yulAssert(literal->value.value() <= std::numeric_limits::max()); + _assembly.appendAuxDataLoadN(static_cast(literal->value.value())); + } )); - if (_objectAccess) + builtins.emplace_back(createFunction( + "eofcreate", + 5, + 1, + EVMDialect::sideEffectsOfInstruction(evmasm::Instruction::EOFCREATE), + ControlFlowSideEffects::fromInstruction(evmasm::Instruction::EOFCREATE), + {LiteralKind::String, std::nullopt, std::nullopt, std::nullopt, std::nullopt}, + []( + FunctionCall const& _call, + AbstractAssembly& _assembly, + BuiltinContext& context + ) { + yulAssert(_call.arguments.size() == 5); + Literal const* literal = std::get_if(&_call.arguments.front()); + auto const formattedLiteral = formatLiteral(*literal); + yulAssert(!util::contains(formattedLiteral, '.')); + auto const* containerID = valueOrNullptr(context.subIDs, formattedLiteral); + yulAssert(containerID != nullptr); + yulAssert(*containerID <= std::numeric_limits::max()); + _assembly.appendEOFCreate(static_cast(*containerID)); + } + )); + builtins.emplace_back(createFunction( "returncontract", 3, @@ -448,6 +449,7 @@ std::vector> createBuiltins(langutil::EVMVe _assembly.appendReturnContract(static_cast(*containerID)); } )); + } } yulAssert( ranges::all_of(builtins, [](std::optional const& _builtinFunction){ diff --git a/test/libsolidity/syntaxTests/inlineAssembly/invalid/eof/eof_builtins_disallowed.sol b/test/libsolidity/syntaxTests/inlineAssembly/invalid/eof/eof_builtins_disallowed.sol new file mode 100644 index 000000000000..617aeff98929 --- /dev/null +++ b/test/libsolidity/syntaxTests/inlineAssembly/invalid/eof/eof_builtins_disallowed.sol @@ -0,0 +1,15 @@ +contract C { + function f() view public { + assembly { + eofcreate("a", 0, 0, 0, 0) + returncontract("a", 0) + auxdataloadn(0) + } + } +} +// ==== +// bytecodeFormat: legacy +// ---- +// DeclarationError 7223: (75-84): Builtin function "eofcreate" is only available in EOF. +// DeclarationError 7223: (114-128): Builtin function "returncontract" is only available in EOF. +// DeclarationError 7223: (149-161): Builtin function "auxdataloadn" is only available in EOF. diff --git a/test/libsolidity/syntaxTests/inlineAssembly/invalid/eof/eof_builtins_disallowed_in_inline_assembly.sol b/test/libsolidity/syntaxTests/inlineAssembly/invalid/eof/eof_builtins_disallowed_in_inline_assembly.sol new file mode 100644 index 000000000000..a2a6540efde5 --- /dev/null +++ b/test/libsolidity/syntaxTests/inlineAssembly/invalid/eof/eof_builtins_disallowed_in_inline_assembly.sol @@ -0,0 +1,16 @@ +// TODO: They should be available in some way in the context of inline assembly. For now it's disallowed them. +contract C { + function f() view public { + assembly { + eofcreate("a", 0, 0, 0, 0) + returncontract("a", 0) + auxdataloadn(0) + } + } +} +// ==== +// bytecodeFormat: >=EOFv1 +// ---- +// DeclarationError 4619: (186-195): Function "eofcreate" not found. +// DeclarationError 4619: (225-239): Function "returncontract" not found. +// DeclarationError 4619: (260-272): Function "auxdataloadn" not found. From 233a5081835a04939ccf85dfb5286c0b53d23c66 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Wed, 22 Jan 2025 09:36:54 +0100 Subject: [PATCH 0738/1022] Enable c++20 in CMake --- Changelog.md | 4 ++++ cmake/EthCompilerSettings.cmake | 12 ++++++------ cmake/EthToolchains.cmake | 4 ++-- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/Changelog.md b/Changelog.md index c00adf0fd977..f37cfcef0722 100644 --- a/Changelog.md +++ b/Changelog.md @@ -18,6 +18,10 @@ Bugfixes: * Yul: Fix internal compiler error when a code generation error should be reported instead. +Build system: + * Switch from C++17 to C++20 as the target standard. + + ### 0.8.28 (2024-10-09) Language Features: diff --git a/cmake/EthCompilerSettings.cmake b/cmake/EthCompilerSettings.cmake index ccbd8a6c4e93..f3db974ae273 100644 --- a/cmake/EthCompilerSettings.cmake +++ b/cmake/EthCompilerSettings.cmake @@ -89,9 +89,9 @@ if (("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU") OR ("${CMAKE_CXX_COMPILER_ID}" MA # Additional GCC-specific compiler settings. if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU") - # Check that we've got GCC 8.0 or newer. - if (NOT (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 8.0)) - message(FATAL_ERROR "${PROJECT_NAME} requires g++ 8.0 or greater.") + # Check that we've got GCC 11.0 or newer. + if (NOT (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 11.0)) + message(FATAL_ERROR "${PROJECT_NAME} requires g++ 11.0 or greater.") endif () # Use fancy colors in the compiler diagnostics @@ -99,9 +99,9 @@ if (("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU") OR ("${CMAKE_CXX_COMPILER_ID}" MA # Additional Clang-specific compiler settings. elseif ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") - # Check that we've got clang 7.0 or newer. - if (NOT (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 7.0)) - message(FATAL_ERROR "${PROJECT_NAME} requires clang++ 7.0 or greater.") + # Check that we've got clang 14.0 or newer. + if (NOT (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 14.0)) + message(FATAL_ERROR "${PROJECT_NAME} requires clang++ 14.0 or greater.") endif () if ("${CMAKE_SYSTEM_NAME}" MATCHES "Darwin") diff --git a/cmake/EthToolchains.cmake b/cmake/EthToolchains.cmake index c2306bd75d11..1d5dc62f3ae5 100644 --- a/cmake/EthToolchains.cmake +++ b/cmake/EthToolchains.cmake @@ -1,6 +1,6 @@ -# Require C++17. +# Require C++20. if (NOT DEFINED CMAKE_CXX_STANDARD) - set(CMAKE_CXX_STANDARD 17) # This requires at least CMake 3.8 to accept this C++17 flag. + set(CMAKE_CXX_STANDARD 20) # This requires at least CMake 3.12 to accept this C++20 flag. endif () set(CMAKE_CXX_STANDARD_REQUIRED TRUE) set(CMAKE_CXX_EXTENSIONS OFF) From 90f07403f9fb9afa454a72f2d2cef7236fdd5f4e Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Wed, 22 Jan 2025 09:37:42 +0100 Subject: [PATCH 0739/1022] docs: Update minimum compiler versions to gcc11 and clang14 --- docs/installing-solidity.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/installing-solidity.rst b/docs/installing-solidity.rst index 57499b812166..129d1d3a82e3 100644 --- a/docs/installing-solidity.rst +++ b/docs/installing-solidity.rst @@ -372,8 +372,8 @@ Minimum Compiler Versions The following C++ compilers and their minimum versions can build the Solidity codebase: -- `GCC `_, version 8+ -- `Clang `_, version 7+ +- `GCC `_, version 11+ +- `Clang `_, version 14+ - `MSVC `_, version 2019+ Prerequisites - macOS From 044d34e102c7c2d4a9fc42568da13086430b4b73 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Wed, 22 Jan 2025 09:38:18 +0100 Subject: [PATCH 0740/1022] ci: remove cxx20 job --- .circleci/config.yml | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index be04d2a6f997..da4be0e35ec7 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1093,21 +1093,6 @@ jobs: - solc/solc-static-linux - matrix_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. - b_ubu_cxx20: - <<: *base_ubuntu2404_large - environment: - <<: *base_ubuntu2404_large_env - CMAKE_BUILD_TYPE: Debug - # gold is more memory-efficient than the default, allows us to stay with the "large" resource class without OOM errors - CMAKE_OPTIONS: -DCMAKE_CXX_STANDARD=20 -DCMAKE_CXX_FLAGS=-fuse-ld=gold - MAKEFLAGS: -j 6 - steps: - - checkout - - run_build - - matrix_notify_failure_unless_pr - b_ubu_2204: <<: *base_ubuntu2204_large steps: @@ -1873,7 +1858,6 @@ workflows: # build-only - b_docs: *requires_nothing - - b_ubu_cxx20: *requires_nothing - b_ubu_ossfuzz: *requires_nothing - b_ubu_2204: *requires_nothing - b_ubu_2204_clang: *requires_nothing From e97e99366f24029a57f0280a9330bd2bfe776983 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Wed, 22 Jan 2025 09:43:15 +0100 Subject: [PATCH 0741/1022] fix various compiler warnings and errors due to version bump and cxx20 --- cmake/EthCompilerSettings.cmake | 8 ++++ libevmasm/ConstantOptimiser.cpp | 22 +++++++++++ libevmasm/ConstantOptimiser.h | 19 ++-------- libevmasm/PeepholeOptimiser.cpp | 6 +++ libevmasm/PeepholeOptimiser.h | 6 +-- libsolidity/ast/Types.cpp | 38 ++++++++++++++----- libsolidity/ast/Types.h | 4 ++ libsolidity/experimental/ast/TypeSystem.cpp | 3 +- .../experimental/ast/TypeSystemHelper.cpp | 2 +- libsolidity/interface/GasEstimator.cpp | 2 +- libyul/optimiser/ExpressionSplitter.cpp | 7 ++++ libyul/optimiser/ExpressionSplitter.h | 8 ++-- libyul/optimiser/FunctionHoister.cpp | 3 ++ libyul/optimiser/FunctionHoister.h | 3 +- solc/CommandLineInterface.cpp | 1 - solc/CommandLineParser.cpp | 3 -- test/EVMHost.cpp | 12 ++++++ test/tools/ossfuzz/CMakeLists.txt | 28 ++++++++------ .../tools/ossfuzz/StackReuseCodegenFuzzer.cpp | 2 +- 19 files changed, 121 insertions(+), 56 deletions(-) diff --git a/cmake/EthCompilerSettings.cmake b/cmake/EthCompilerSettings.cmake index f3db974ae273..cc8435ed3c30 100644 --- a/cmake/EthCompilerSettings.cmake +++ b/cmake/EthCompilerSettings.cmake @@ -94,6 +94,12 @@ if (("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU") OR ("${CMAKE_CXX_COMPILER_ID}" MA message(FATAL_ERROR "${PROJECT_NAME} requires g++ 11.0 or greater.") endif () + # GCC 12 emits warnings for string concatenations with operator+ under O3 + # See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105651 + if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 12.0 AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 13.0) + add_compile_options(-Wno-error=restrict) + endif () + # Use fancy colors in the compiler diagnostics add_compile_options(-fdiagnostics-color) @@ -104,6 +110,8 @@ if (("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU") OR ("${CMAKE_CXX_COMPILER_ID}" MA message(FATAL_ERROR "${PROJECT_NAME} requires clang++ 14.0 or greater.") endif () + # use std::invoke_result, superseding std::result_of which has been removed in c++20 + add_compile_definitions(BOOST_ASIO_HAS_STD_INVOKE_RESULT) if ("${CMAKE_SYSTEM_NAME}" MATCHES "Darwin") # Set stack size to 32MB - by default Apple's clang defines a stack size of 8MB. # Normally 16MB is enough to run all tests, but it will exceed the stack, if -DSANITIZE=address is used. diff --git a/libevmasm/ConstantOptimiser.cpp b/libevmasm/ConstantOptimiser.cpp index 6fdb42bd76d0..7cf00fc9ed41 100644 --- a/libevmasm/ConstantOptimiser.cpp +++ b/libevmasm/ConstantOptimiser.cpp @@ -140,6 +140,11 @@ bigint LiteralMethod::gasNeeded() const ); } +AssemblyItems LiteralMethod::execute(Assembly&) const +{ + return {}; +} + bigint CodeCopyMethod::gasNeeded() const { return combineGas( @@ -226,6 +231,23 @@ AssemblyItems CodeCopyMethod::copyRoutine(AssemblyItem* _pushData) const } } +ComputeMethod::ComputeMethod(Params const& _params, u256 const& _value): + ConstantOptimisationMethod(_params, _value) +{ + m_routine = findRepresentation(m_value); + assertThrow( + checkRepresentation(m_value, m_routine), + OptimizerException, + "Invalid constant expression created." + ); +} +ComputeMethod::~ComputeMethod() = default; + +AssemblyItems ComputeMethod::execute(Assembly&) const +{ + return m_routine; +} + AssemblyItems ComputeMethod::findRepresentation(u256 const& _value) { if (_value < 0x10000) diff --git a/libevmasm/ConstantOptimiser.h b/libevmasm/ConstantOptimiser.h index 7a929939efe6..4952d7985d43 100644 --- a/libevmasm/ConstantOptimiser.h +++ b/libevmasm/ConstantOptimiser.h @@ -108,7 +108,7 @@ class LiteralMethod: public ConstantOptimisationMethod explicit LiteralMethod(Params const& _params, u256 const& _value): ConstantOptimisationMethod(_params, _value) {} bigint gasNeeded() const override; - AssemblyItems execute(Assembly&) const override { return AssemblyItems{}; } + AssemblyItems execute(Assembly&) const override; }; /** @@ -132,22 +132,11 @@ class CodeCopyMethod: public ConstantOptimisationMethod class ComputeMethod: public ConstantOptimisationMethod { public: - explicit ComputeMethod(Params const& _params, u256 const& _value): - ConstantOptimisationMethod(_params, _value) - { - m_routine = findRepresentation(m_value); - assertThrow( - checkRepresentation(m_value, m_routine), - OptimizerException, - "Invalid constant expression created." - ); - } + ComputeMethod(Params const& _params, u256 const& _value); + ~ComputeMethod() override; bigint gasNeeded() const override { return gasNeeded(m_routine); } - AssemblyItems execute(Assembly&) const override - { - return m_routine; - } + AssemblyItems execute(Assembly&) const override; protected: /// Tries to recursively find a way to compute @a _value. diff --git a/libevmasm/PeepholeOptimiser.cpp b/libevmasm/PeepholeOptimiser.cpp index 64650eaeea9f..3129efb4d734 100644 --- a/libevmasm/PeepholeOptimiser.cpp +++ b/libevmasm/PeepholeOptimiser.cpp @@ -709,6 +709,12 @@ size_t numberOfPops(AssemblyItems const& _items) } +PeepholeOptimiser::PeepholeOptimiser(AssemblyItems& _items, langutil::EVMVersion const _evmVersion): + m_items(_items), + m_evmVersion(_evmVersion) +{ +} + bool PeepholeOptimiser::optimise() { // Avoid referencing immutables too early by using approx. counting in bytesRequired() diff --git a/libevmasm/PeepholeOptimiser.h b/libevmasm/PeepholeOptimiser.h index 8e3161b212aa..2a1b9ae5ba44 100644 --- a/libevmasm/PeepholeOptimiser.h +++ b/libevmasm/PeepholeOptimiser.h @@ -43,11 +43,7 @@ class PeepholeOptimisationMethod class PeepholeOptimiser { public: - explicit PeepholeOptimiser(AssemblyItems& _items, langutil::EVMVersion const _evmVersion): - m_items(_items), - m_evmVersion(_evmVersion) - { - } + explicit PeepholeOptimiser(AssemblyItems& _items, langutil::EVMVersion _evmVersion); virtual ~PeepholeOptimiser() = default; bool optimise(); diff --git a/libsolidity/ast/Types.cpp b/libsolidity/ast/Types.cpp index 95f249516142..c77a6d0b6b50 100644 --- a/libsolidity/ast/Types.cpp +++ b/libsolidity/ast/Types.cpp @@ -661,8 +661,12 @@ bool IntegerType::operator==(Type const& _other) const { if (_other.category() != category()) return false; - IntegerType const& other = dynamic_cast(_other); - return other.m_bits == m_bits && other.m_modifier == m_modifier; + return *this == dynamic_cast(_other); +} + +bool IntegerType::operator==(IntegerType const& _other) const +{ + return _other.m_bits == m_bits && _other.m_modifier == m_modifier; } std::string IntegerType::toString(bool) const @@ -1699,17 +1703,21 @@ bool ArrayType::operator==(Type const& _other) const { if (_other.category() != category()) return false; - ArrayType const& other = dynamic_cast(_other); + return *this == dynamic_cast(_other); +} + +bool ArrayType::operator==(ArrayType const& _other) const +{ if ( - !equals(other) || - other.isByteArray() != isByteArray() || - other.isString() != isString() || - other.isDynamicallySized() != isDynamicallySized() + !equals(_other) || + _other.isByteArray() != isByteArray() || + _other.isString() != isString() || + _other.isDynamicallySized() != isDynamicallySized() ) return false; - if (*other.baseType() != *baseType()) + if (*_other.baseType() != *baseType()) return false; - return isDynamicallySized() || length() == other.length(); + return isDynamicallySized() || length() == _other.length(); } BoolResult ArrayType::validForLocation(DataLocation _loc) const @@ -2704,7 +2712,12 @@ bool UserDefinedValueType::operator==(Type const& _other) const if (_other.category() != category()) return false; UserDefinedValueType const& other = dynamic_cast(_other); - return other.definition() == definition(); + return *this == other; +} + +bool UserDefinedValueType::operator==(UserDefinedValueType const& _other) const +{ + return _other.definition() == definition(); } std::string UserDefinedValueType::toString(bool /* _withoutDataLocation */) const @@ -4058,6 +4071,11 @@ bool ModifierType::operator==(Type const& _other) const { if (_other.category() != category()) return false; + return *this == dynamic_cast(_other); +} + +bool ModifierType::operator==(ModifierType const& _other) const +{ ModifierType const& other = dynamic_cast(_other); if (m_parameterTypes.size() != other.m_parameterTypes.size()) diff --git a/libsolidity/ast/Types.h b/libsolidity/ast/Types.h index c642362029d9..aa14cf6b938e 100644 --- a/libsolidity/ast/Types.h +++ b/libsolidity/ast/Types.h @@ -495,6 +495,7 @@ class IntegerType: public Type TypeResult unaryOperatorResult(Token _operator) const override; TypeResult binaryOperatorResult(Token _operator, Type const* _other) const override; + bool operator==(IntegerType const& _other) const; bool operator==(Type const& _other) const override; unsigned calldataEncodedSize(bool _padded = true) const override { return _padded ? 32 : m_bits / 8; } @@ -854,6 +855,7 @@ class ArrayType: public ReferenceType BoolResult isImplicitlyConvertibleTo(Type const& _convertTo) const override; BoolResult isExplicitlyConvertibleTo(Type const& _convertTo) const override; std::string richIdentifier() const override; + bool operator==(ArrayType const& _other) const; bool operator==(Type const& _other) const override; unsigned calldataEncodedSize(bool) const override; unsigned calldataEncodedTailSize() const override; @@ -1148,6 +1150,7 @@ class UserDefinedValueType: public Type Declaration const* typeDefinition() const override; std::string richIdentifier() const override; + bool operator==(UserDefinedValueType const& _other) const; bool operator==(Type const& _other) const override; unsigned calldataEncodedSize(bool _padded) const override { return underlyingType().calldataEncodedSize(_padded); } @@ -1625,6 +1628,7 @@ class ModifierType: public Type bool hasSimpleZeroValueInMemory() const override { solAssert(false, ""); } std::string richIdentifier() const override; bool operator==(Type const& _other) const override; + bool operator==(ModifierType const& _other) const; std::string toString(bool _withoutDataLocation) const override; protected: std::vector> makeStackItems() const override { return {}; } diff --git a/libsolidity/experimental/ast/TypeSystem.cpp b/libsolidity/experimental/ast/TypeSystem.cpp index 059054dcdbce..5198743ed67f 100644 --- a/libsolidity/experimental/ast/TypeSystem.cpp +++ b/libsolidity/experimental/ast/TypeSystem.cpp @@ -24,7 +24,8 @@ #include -#include +#include + #include #include #include diff --git a/libsolidity/experimental/ast/TypeSystemHelper.cpp b/libsolidity/experimental/ast/TypeSystemHelper.cpp index 9ad18e1608bc..b01bc0529414 100644 --- a/libsolidity/experimental/ast/TypeSystemHelper.cpp +++ b/libsolidity/experimental/ast/TypeSystemHelper.cpp @@ -26,7 +26,7 @@ #include #include -#include +#include #include #include #include diff --git a/libsolidity/interface/GasEstimator.cpp b/libsolidity/interface/GasEstimator.cpp index fd3fbbc02c45..4313fad7fd66 100644 --- a/libsolidity/interface/GasEstimator.cpp +++ b/libsolidity/interface/GasEstimator.cpp @@ -109,7 +109,7 @@ std::set GasEstimator::finestNodesAtLocation( { std::map locations; std::set nodes; - SimpleASTVisitor visitor(std::function(), [&](ASTNode const& _n) + SimpleASTVisitor visitor([](ASTNode const&) { return false; }, [&](ASTNode const& _n) { if (!locations.count(_n.location())) { diff --git a/libyul/optimiser/ExpressionSplitter.cpp b/libyul/optimiser/ExpressionSplitter.cpp index 1bdaa552ba16..649bd85834d2 100644 --- a/libyul/optimiser/ExpressionSplitter.cpp +++ b/libyul/optimiser/ExpressionSplitter.cpp @@ -35,6 +35,13 @@ using namespace solidity::yul; using namespace solidity::util; using namespace solidity::langutil; +ExpressionSplitter::ExpressionSplitter(Dialect const& _dialect, NameDispenser& _nameDispenser): + m_dialect(_dialect), + m_nameDispenser(_nameDispenser) +{} + +ExpressionSplitter::~ExpressionSplitter() = default; + void ExpressionSplitter::run(OptimiserStepContext& _context, Block& _ast) { ExpressionSplitter{_context.dialect, _context.dispenser}(_ast); diff --git a/libyul/optimiser/ExpressionSplitter.h b/libyul/optimiser/ExpressionSplitter.h index 2581b23de1e2..739916317765 100644 --- a/libyul/optimiser/ExpressionSplitter.h +++ b/libyul/optimiser/ExpressionSplitter.h @@ -68,13 +68,11 @@ class ExpressionSplitter: public ASTModifier void operator()(Block& _block) override; private: - explicit ExpressionSplitter( + ExpressionSplitter( Dialect const& _dialect, NameDispenser& _nameDispenser - ): - m_dialect(_dialect), - m_nameDispenser(_nameDispenser) - { } + ); + ~ExpressionSplitter() override; /// Replaces the expression by a variable if it is a function call or functional /// instruction. The declaration of the variable is appended to m_statementsToPrefix. diff --git a/libyul/optimiser/FunctionHoister.cpp b/libyul/optimiser/FunctionHoister.cpp index 32df3b121a61..356056a99abd 100644 --- a/libyul/optimiser/FunctionHoister.cpp +++ b/libyul/optimiser/FunctionHoister.cpp @@ -30,6 +30,9 @@ using namespace solidity; using namespace solidity::yul; +FunctionHoister::FunctionHoister() = default; +FunctionHoister::~FunctionHoister() = default; + void FunctionHoister::operator()(Block& _block) { bool topLevel = m_isTopLevel; diff --git a/libyul/optimiser/FunctionHoister.h b/libyul/optimiser/FunctionHoister.h index 04d7f64e3d73..8242c9f4792f 100644 --- a/libyul/optimiser/FunctionHoister.h +++ b/libyul/optimiser/FunctionHoister.h @@ -46,7 +46,8 @@ class FunctionHoister: public ASTModifier void operator()(Block& _block) override; private: - FunctionHoister() = default; + FunctionHoister(); + ~FunctionHoister() override; bool m_isTopLevel = true; std::vector m_functions; diff --git a/solc/CommandLineInterface.cpp b/solc/CommandLineInterface.cpp index f2bb4af107bb..784967c52ef7 100644 --- a/solc/CommandLineInterface.cpp +++ b/solc/CommandLineInterface.cpp @@ -118,7 +118,6 @@ std::ostream& CommandLineInterface::serr(bool _markAsUsed) static std::string const g_stdinFileName = ""; static std::string const g_strAbi = "abi"; static std::string const g_strAsm = "asm"; -static std::string const g_strAst = "ast"; static std::string const g_strBinary = "bin"; static std::string const g_strBinaryRuntime = "bin-runtime"; static std::string const g_strContracts = "contracts"; diff --git a/solc/CommandLineParser.cpp b/solc/CommandLineParser.cpp index 5929144049a2..c888d9a53a63 100644 --- a/solc/CommandLineParser.cpp +++ b/solc/CommandLineParser.cpp @@ -91,7 +91,6 @@ static std::string const g_strOutputDir = "output-dir"; static std::string const g_strOverwrite = "overwrite"; static std::string const g_strRevertStrings = "revert-strings"; static std::string const g_strStopAfter = "stop-after"; -static std::string const g_strParsing = "parsing"; /// Possible arguments to for --revert-strings static std::set const g_revertStringsArgs @@ -102,8 +101,6 @@ static std::set const g_revertStringsArgs revertStringsToString(RevertStrings::VerboseDebug) }; -static std::string const g_strSources = "sources"; -static std::string const g_strSourceList = "sourceList"; static std::string const g_strStandardJSON = "standard-json"; static std::string const g_strStrictAssembly = "strict-assembly"; static std::string const g_strSwarm = "swarm"; diff --git a/test/EVMHost.cpp b/test/EVMHost.cpp index fdaf3f35be1d..5370542c7e0b 100644 --- a/test/EVMHost.cpp +++ b/test/EVMHost.cpp @@ -20,8 +20,20 @@ * for testing purposes. */ +// Weird issue when compiling with O3 on gcc 12 and later due to usage of vector (aka bytes) as std::map key +// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98465 +// also clang doesn't know stringop-overread +#if defined(__GNUC__) && !defined(__clang__) // GCC-specific pragma +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wstringop-overread" +#endif + #include +#if defined(__GNUC__) && !defined(__clang__) // GCC-specific pragma +#pragma GCC diagnostic pop +#endif + #include #include diff --git a/test/tools/ossfuzz/CMakeLists.txt b/test/tools/ossfuzz/CMakeLists.txt index 9449eddbad55..da18968928ea 100644 --- a/test/tools/ossfuzz/CMakeLists.txt +++ b/test/tools/ossfuzz/CMakeLists.txt @@ -74,7 +74,16 @@ if (OSSFUZZ) # are auto-generated by the protobuf compiler because the compiler # does not generate warning-free C++ bindings with regard to # upstream Clang builds that are used by ossfuzz. - target_compile_options(yul_proto_ossfuzz PUBLIC ${COMPILE_OPTIONS} -Wno-sign-conversion -Wno-suggest-destructor-override -Wno-inconsistent-missing-destructor-override -Wno-shorten-64-to-32) + set( + SILENCE_PROTOBUF_AUTOGENERATED_WARNINGS + -Wno-sign-conversion + -Wno-suggest-destructor-override + -Wno-inconsistent-missing-destructor-override + -Wno-shorten-64-to-32 + -Wno-deprecated + ) + + target_compile_options(yul_proto_ossfuzz PUBLIC ${COMPILE_OPTIONS} ${SILENCE_PROTOBUF_AUTOGENERATED_WARNINGS}) add_executable( yul_proto_diff_ossfuzz @@ -92,7 +101,7 @@ if (OSSFUZZ) protobuf.a ) set_target_properties(yul_proto_diff_ossfuzz PROPERTIES LINK_FLAGS ${LIB_FUZZING_ENGINE}) - target_compile_options(yul_proto_diff_ossfuzz PUBLIC ${COMPILE_OPTIONS} -Wno-sign-conversion -Wno-suggest-destructor-override -Wno-inconsistent-missing-destructor-override -Wno-shorten-64-to-32) + target_compile_options(yul_proto_diff_ossfuzz PUBLIC ${COMPILE_OPTIONS} ${SILENCE_PROTOBUF_AUTOGENERATED_WARNINGS}) add_executable(yul_proto_diff_custom_mutate_ossfuzz yulProto_diff_ossfuzz.cpp @@ -110,7 +119,7 @@ if (OSSFUZZ) protobuf.a ) set_target_properties(yul_proto_diff_custom_mutate_ossfuzz PROPERTIES LINK_FLAGS ${LIB_FUZZING_ENGINE}) - target_compile_options(yul_proto_diff_custom_mutate_ossfuzz PUBLIC ${COMPILE_OPTIONS} -Wno-sign-conversion -Wno-suggest-destructor-override -Wno-inconsistent-missing-destructor-override -Wno-shorten-64-to-32) + target_compile_options(yul_proto_diff_custom_mutate_ossfuzz PUBLIC ${COMPILE_OPTIONS} ${SILENCE_PROTOBUF_AUTOGENERATED_WARNINGS}) add_executable(stack_reuse_codegen_ossfuzz StackReuseCodegenFuzzer.cpp @@ -130,12 +139,7 @@ if (OSSFUZZ) set_target_properties(stack_reuse_codegen_ossfuzz PROPERTIES LINK_FLAGS ${LIB_FUZZING_ENGINE}) target_compile_options(stack_reuse_codegen_ossfuzz PUBLIC ${COMPILE_OPTIONS} - -Wno-sign-conversion - -Wno-inconsistent-missing-destructor-override - -Wno-unused-parameter - -Wno-zero-length-array - -Wno-suggest-destructor-override - -Wno-shorten-64-to-32 + ${SILENCE_PROTOBUF_AUTOGENERATED_WARNINGS} ) add_executable(abiv2_proto_ossfuzz @@ -156,7 +160,7 @@ if (OSSFUZZ) protobuf.a ) set_target_properties(abiv2_proto_ossfuzz PROPERTIES LINK_FLAGS ${LIB_FUZZING_ENGINE}) - target_compile_options(abiv2_proto_ossfuzz PUBLIC ${COMPILE_OPTIONS} -Wno-sign-conversion -Wno-suggest-destructor-override -Wno-inconsistent-missing-destructor-override -Wno-shorten-64-to-32) + target_compile_options(abiv2_proto_ossfuzz PUBLIC ${COMPILE_OPTIONS} ${SILENCE_PROTOBUF_AUTOGENERATED_WARNINGS}) add_executable(abiv2_isabelle_ossfuzz AbiV2IsabelleFuzzer.cpp @@ -178,7 +182,7 @@ if (OSSFUZZ) gmp.a ) set_target_properties(abiv2_isabelle_ossfuzz PROPERTIES LINK_FLAGS ${LIB_FUZZING_ENGINE}) - target_compile_options(abiv2_isabelle_ossfuzz PUBLIC ${COMPILE_OPTIONS} -Wno-sign-conversion -Wno-suggest-destructor-override -Wno-inconsistent-missing-destructor-override -Wno-shorten-64-to-32) + target_compile_options(abiv2_isabelle_ossfuzz PUBLIC ${COMPILE_OPTIONS} ${SILENCE_PROTOBUF_AUTOGENERATED_WARNINGS}) add_executable(sol_proto_ossfuzz solProtoFuzzer.cpp @@ -198,7 +202,7 @@ if (OSSFUZZ) protobuf.a ) set_target_properties(sol_proto_ossfuzz PROPERTIES LINK_FLAGS ${LIB_FUZZING_ENGINE}) - target_compile_options(sol_proto_ossfuzz PUBLIC ${COMPILE_OPTIONS} -Wno-sign-conversion -Wno-suggest-destructor-override -Wno-inconsistent-missing-destructor-override -Wno-shorten-64-to-32) + target_compile_options(sol_proto_ossfuzz PUBLIC ${COMPILE_OPTIONS} ${SILENCE_PROTOBUF_AUTOGENERATED_WARNINGS}) else() add_library(solc_ossfuzz solc_ossfuzz.cpp diff --git a/test/tools/ossfuzz/StackReuseCodegenFuzzer.cpp b/test/tools/ossfuzz/StackReuseCodegenFuzzer.cpp index de2fdd28632a..71a4ff54a9f4 100644 --- a/test/tools/ossfuzz/StackReuseCodegenFuzzer.cpp +++ b/test/tools/ossfuzz/StackReuseCodegenFuzzer.cpp @@ -52,7 +52,7 @@ static evmc::VM evmone = evmc::VM{evmc_create_evmone()}; namespace { /// @returns true if there are recursive functions, false otherwise. -bool recursiveFunctionExists(Dialect const& _dialect, yul::Object& _object) +bool recursiveFunctionExists(Dialect const& /*_dialect*/, yul::Object& _object) { auto recursiveFunctions = CallGraphGenerator::callGraph(_object.code()->root()).recursiveFunctions(); for(auto&& [function, variables]: CompilabilityChecker{ From eceea82223dce3cffb1cf9f4640d6851b3d41969 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Wed, 22 Jan 2025 09:43:59 +0100 Subject: [PATCH 0742/1022] ci: switch static to fully static build and bump to ubu 2024 --- .circleci/config.yml | 6 +++--- Changelog.md | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index da4be0e35ec7..164694e4505e 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1073,10 +1073,10 @@ jobs: # to avoid glibc incompatibilities. # See: https://github.com/ethereum/solidity/issues/13954 # On large runs 2x faster than on medium. 3x on xlarge. - <<: *base_ubuntu2004_xlarge + <<: *base_ubuntu2404_xlarge environment: - <<: *base_ubuntu2004_xlarge_env - CMAKE_OPTIONS: -DCMAKE_BUILD_TYPE=Release -DSOLC_STATIC_STDLIBS=ON + <<: *base_ubuntu2404_xlarge_env + CMAKE_OPTIONS: -DCMAKE_BUILD_TYPE=Release -DSOLC_LINK_STATIC=ON steps: - checkout - run_build diff --git a/Changelog.md b/Changelog.md index f37cfcef0722..b942f068fa77 100644 --- a/Changelog.md +++ b/Changelog.md @@ -19,9 +19,9 @@ Bugfixes: Build system: + * Linux release builds are fully static again and no longer depend on ``glibc``. * Switch from C++17 to C++20 as the target standard. - ### 0.8.28 (2024-10-09) Language Features: From 5833ea3c49275d5af2f0916192e5aa9a9bd0b9cd Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Thu, 23 Jan 2025 09:01:27 +0100 Subject: [PATCH 0743/1022] drop ubuntu focal support --- ReleaseChecklist.md | 3 ++- scripts/deps-ppa/static_z3.sh | 2 +- scripts/release_ppa.sh | 4 ++-- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/ReleaseChecklist.md b/ReleaseChecklist.md index a70afe0cb503..758ef79ddaa4 100644 --- a/ReleaseChecklist.md +++ b/ReleaseChecklist.md @@ -94,7 +94,8 @@ At least a day before the release: **SERIOUSLY: DO NOT PROCEED EARLIER!!!** - [ ] *After* the package with the static build is *published*, use it to create packages for older Ubuntu versions. Copy the static package to the [``~ethereum/ethereum`` PPA](https://launchpad.net/~ethereum/+archive/ubuntu/ethereum) - for the destination series ``Trusty``, ``Xenial`` and ``Bionic`` while selecting ``Copy existing binaries``. + for the destination series ``Trusty``, ``Xenial``, ``Bionic``, and ``Focal`` + while selecting ``Copy existing binaries``. ### Release solc-js - [ ] Wait until solc-bin was properly deployed. You can test this via remix - a test run through remix is advisable anyway. diff --git a/scripts/deps-ppa/static_z3.sh b/scripts/deps-ppa/static_z3.sh index 9e273188cf62..140c40c6abb3 100755 --- a/scripts/deps-ppa/static_z3.sh +++ b/scripts/deps-ppa/static_z3.sh @@ -41,7 +41,7 @@ sourcePPAConfig # Sanity check checkDputEntries "\[cpp-build-deps\]" -DISTRIBUTIONS="focal jammy noble oracular" +DISTRIBUTIONS="jammy noble oracular" for distribution in $DISTRIBUTIONS do diff --git a/scripts/release_ppa.sh b/scripts/release_ppa.sh index 773c43cc9968..cf8df3d6c47d 100755 --- a/scripts/release_ppa.sh +++ b/scripts/release_ppa.sh @@ -66,9 +66,9 @@ sourcePPAConfig packagename=solc # This needs to be a still active release -static_build_distribution=focal +static_build_distribution=noble -DISTRIBUTIONS="focal jammy noble oracular" +DISTRIBUTIONS="jammy noble oracular" if is_release then From e4b82f9c4432155907db3f06acb150f0f597f8e1 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Thu, 23 Jan 2025 09:06:20 +0100 Subject: [PATCH 0744/1022] drop ubuntu ubuntu 20.04 docker image --- .github/workflows/buildpack-deps.yml | 1 - .../buildpack-deps/Dockerfile.ubuntu2004 | 108 ------------------ 2 files changed, 109 deletions(-) delete mode 100644 scripts/docker/buildpack-deps/Dockerfile.ubuntu2004 diff --git a/.github/workflows/buildpack-deps.yml b/.github/workflows/buildpack-deps.yml index ad2e58270018..00d08372d676 100644 --- a/.github/workflows/buildpack-deps.yml +++ b/.github/workflows/buildpack-deps.yml @@ -6,7 +6,6 @@ on: paths: - 'scripts/docker/buildpack-deps/Dockerfile.emscripten' - 'scripts/docker/buildpack-deps/Dockerfile.ubuntu.clang.ossfuzz' - - 'scripts/docker/buildpack-deps/Dockerfile.ubuntu2004' - 'scripts/docker/buildpack-deps/Dockerfile.ubuntu2204' - 'scripts/docker/buildpack-deps/Dockerfile.ubuntu2404' - 'scripts/docker/buildpack-deps/Dockerfile.ubuntu2404.clang' diff --git a/scripts/docker/buildpack-deps/Dockerfile.ubuntu2004 b/scripts/docker/buildpack-deps/Dockerfile.ubuntu2004 deleted file mode 100644 index 7592f55ec55b..000000000000 --- a/scripts/docker/buildpack-deps/Dockerfile.ubuntu2004 +++ /dev/null @@ -1,108 +0,0 @@ -# vim:syntax=dockerfile -#------------------------------------------------------------------------------ -# Dockerfile for building and testing Solidity Compiler on CI -# Target: Ubuntu 19.04 (Disco Dingo) -# URL: https://hub.docker.com/r/ethereum/solidity-buildpack-deps -# -# 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-2019 solidity contributors. -#------------------------------------------------------------------------------ -FROM buildpack-deps:focal AS base -LABEL version="26" - -ARG DEBIAN_FRONTEND=noninteractive - -RUN set -ex; \ - dist=$(grep DISTRIB_CODENAME /etc/lsb-release | cut -d= -f2); \ - echo "deb http://ppa.launchpad.net/ethereum/cpp-build-deps/ubuntu $dist main" >> /etc/apt/sources.list ; \ - apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 1c52189c923f6ca9 ; \ - apt-get update; \ - apt-get install -qqy --no-install-recommends \ - build-essential \ - cmake \ - jq \ - libboost-filesystem-dev \ - libboost-program-options-dev \ - libboost-system-dev \ - libboost-test-dev \ - lsof \ - ninja-build \ - python3-pip \ - python3-sphinx \ - software-properties-common \ - sudo \ - unzip; \ - pip3 install \ - codecov \ - colorama \ - deepdiff \ - parsec \ - pygments-lexer-solidity \ - pylint \ - requests \ - tabulate \ - z3-solver; - -# TODO: we could eliminate duplication by using a Dockerfile extension like: -# https://github.com/edrevo/dockerfile-plus?tab=readme-ov-file#dockerfile -# or mult-stage builds, then we could define a base image which would be included/used by all the other Dockerfiles. -# Or we could move the common parts to a shell script, copying and calling it from the Dockerfiles. -# Eldarica -RUN set -ex; \ - apt-get update; \ - apt-get install -qqy \ - openjdk-11-jre; \ - eldarica_version="2.1"; \ - wget "https://github.com/uuverifiers/eldarica/releases/download/v${eldarica_version}/eldarica-bin-${eldarica_version}.zip" -O /opt/eld_binaries.zip; \ - test "$(sha256sum /opt/eld_binaries.zip)" = "0ac43f45c0925383c9d2077f62bbb515fd792375f3b2b101b30c9e81dcd7785c /opt/eld_binaries.zip"; \ - unzip /opt/eld_binaries.zip -d /opt; \ - rm -f /opt/eld_binaries.zip; - -# CVC5 -RUN set -ex; \ - cvc5_version="1.2.0"; \ - cvc5_archive_name="cvc5-Linux-x86_64-static"; \ - wget "https://github.com/cvc5/cvc5/releases/download/cvc5-${cvc5_version}/${cvc5_archive_name}.zip" -O /opt/cvc5.zip; \ - test "$(sha256sum /opt/cvc5.zip)" = "d18f174ff9a11923c32c3f871f844ed16bd77a28f51050b8e7c8d821c98a1c2e /opt/cvc5.zip"; \ - unzip -j /opt/cvc5.zip "${cvc5_archive_name}/bin/cvc5" -d /usr/bin; \ - rm -f /opt/cvc5.zip; - -# Z3 -RUN set -ex; \ - z3_version="4.13.3"; \ - z3_archive_name="z3-${z3_version}-x64-glibc-2.35"; \ - wget "https://github.com/Z3Prover/z3/releases/download/z3-${z3_version}/${z3_archive_name}.zip" -O /opt/z3.zip; \ - test "$(sha256sum /opt/z3.zip)" = "32c7377026733c9d7b33c21cd77a68f50ba682367207b031a6bfd80140a8722f /opt/z3.zip"; \ - unzip -j /opt/z3.zip "${z3_archive_name}/bin/z3" -d /usr/bin; \ - rm -f /opt/z3.zip; - -FROM base AS libraries - -# EVMONE -RUN set -ex; \ - wget -O /usr/src/evmone.tar.gz https://github.com/ethereum/evmone/releases/download/v0.12.0/evmone-0.12.0-linux-x86_64.tar.gz; \ - test "$(sha256sum /usr/src/evmone.tar.gz)" = "1c7b5eba0c8c3b3b2a7a05101e2d01a13a2f84b323989a29be66285dba4136ce /usr/src/evmone.tar.gz"; \ - cd /usr; \ - tar -xf /usr/src/evmone.tar.gz; \ - rm -rf /usr/src/evmone.tar.gz - -FROM base -COPY --from=libraries /usr/lib /usr/lib -COPY --from=libraries /usr/bin /usr/bin -COPY --from=libraries /usr/include /usr/include -COPY --from=libraries /opt/eldarica /opt/eldarica -ENV PATH="$PATH:/opt/eldarica" From bc0b9c1966355b140e6464ed7d2b3bdc9a39d111 Mon Sep 17 00:00:00 2001 From: rodiazet Date: Thu, 23 Jan 2025 12:17:49 +0100 Subject: [PATCH 0745/1022] eof: Update `yulSyntaxTests` tests for EOF --- test/libyul/yulSyntaxTests/builtin_function_literal.yul | 2 ++ test/libyul/yulSyntaxTests/datacopy_shadowing.yul | 2 ++ test/libyul/yulSyntaxTests/dataoffset_shadowing.yul | 2 ++ test/libyul/yulSyntaxTests/datasize_shadowing.yul | 2 ++ .../yulSyntaxTests/eof/builtin_function_literal.yul | 9 +++++++++ test/libyul/yulSyntaxTests/eof/datacopy_shadowing.yul | 7 +++++++ test/libyul/yulSyntaxTests/eof/dataoffset_shadowing.yul | 7 +++++++ test/libyul/yulSyntaxTests/eof/datasize_shadowing.yul | 7 +++++++ .../yulSyntaxTests/eof/loadimmutable_shadowing.yul | 8 ++++++++ ...iltin_with_literal_argument_into_literal_argument.yul | 8 ++++++++ test/libyul/yulSyntaxTests/eof/selfdestruct.yul | 7 +++++++ .../libyul/yulSyntaxTests/eof/setimmutable_shadowing.yul | 8 ++++++++ test/libyul/yulSyntaxTests/hex_switch_case.yul | 2 +- test/libyul/yulSyntaxTests/hex_switch_case_long.yul | 4 ++-- test/libyul/yulSyntaxTests/invalid/pc_disallowed.yul | 2 ++ test/libyul/yulSyntaxTests/loadimmutable.yul | 1 + test/libyul/yulSyntaxTests/loadimmutable_bad_literal.yul | 1 + test/libyul/yulSyntaxTests/loadimmutable_shadowing.yul | 1 + .../loadimmutable_without_setimmutable.yul | 2 ++ test/libyul/yulSyntaxTests/metadata_access.yul | 2 ++ test/libyul/yulSyntaxTests/metadata_access_2.yul | 2 ++ test/libyul/yulSyntaxTests/metadata_access_subobject.yul | 2 ++ test/libyul/yulSyntaxTests/objects/data.yul | 2 ++ test/libyul/yulSyntaxTests/objects/data_access.yul | 2 ++ test/libyul/yulSyntaxTests/objects/datacopy.yul | 2 ++ .../yulSyntaxTests/objects/dataoffset_nonliteral.yul | 2 ++ .../yulSyntaxTests/objects/dataoffset_nonstring.yul | 2 ++ .../yulSyntaxTests/objects/dataoffset_notfound.yul | 2 ++ .../yulSyntaxTests/objects/datasize_nonliteral.yul | 2 ++ .../libyul/yulSyntaxTests/objects/datasize_nonstring.yul | 2 ++ test/libyul/yulSyntaxTests/objects/datasize_notfound.yul | 2 ++ test/libyul/yulSyntaxTests/objects/subobject_access.yul | 2 ++ .../libyul/yulSyntaxTests/opcode_for_function_args_1.yul | 4 ++-- .../libyul/yulSyntaxTests/opcode_for_function_args_2.yul | 4 ++-- test/libyul/yulSyntaxTests/opcode_for_functions.yul | 4 ++-- ...iltin_with_literal_argument_into_literal_argument.yul | 1 + test/libyul/yulSyntaxTests/selfdestruct.yul | 2 ++ test/libyul/yulSyntaxTests/setimmutable.yul | 1 + test/libyul/yulSyntaxTests/setimmutable_bad_literal.yul | 1 + test/libyul/yulSyntaxTests/setimmutable_shadowing.yul | 1 + test/libyul/yulSyntaxTests/simple_functions.yul | 2 +- .../libyul/yulSyntaxTests/string_literal_switch_case.yul | 2 +- .../yulSyntaxTests/string_literal_too_long_immutable.yul | 1 + 43 files changed, 120 insertions(+), 11 deletions(-) create mode 100644 test/libyul/yulSyntaxTests/eof/builtin_function_literal.yul create mode 100644 test/libyul/yulSyntaxTests/eof/datacopy_shadowing.yul create mode 100644 test/libyul/yulSyntaxTests/eof/dataoffset_shadowing.yul create mode 100644 test/libyul/yulSyntaxTests/eof/datasize_shadowing.yul create mode 100644 test/libyul/yulSyntaxTests/eof/loadimmutable_shadowing.yul create mode 100644 test/libyul/yulSyntaxTests/eof/passing_builtin_with_literal_argument_into_literal_argument.yul create mode 100644 test/libyul/yulSyntaxTests/eof/selfdestruct.yul create mode 100644 test/libyul/yulSyntaxTests/eof/setimmutable_shadowing.yul diff --git a/test/libyul/yulSyntaxTests/builtin_function_literal.yul b/test/libyul/yulSyntaxTests/builtin_function_literal.yul index 22f7216146a6..c975648ae2df 100644 --- a/test/libyul/yulSyntaxTests/builtin_function_literal.yul +++ b/test/libyul/yulSyntaxTests/builtin_function_literal.yul @@ -1,6 +1,8 @@ { datasize(x,1) } +// ==== +// bytecodeFormat: legacy // ---- // TypeError 7000: (4-12): Function "datasize" expects 1 arguments but got 2. // TypeError 9114: (4-12): Function expects direct literals as arguments. diff --git a/test/libyul/yulSyntaxTests/datacopy_shadowing.yul b/test/libyul/yulSyntaxTests/datacopy_shadowing.yul index 3f14f47226a9..7466af6c3863 100644 --- a/test/libyul/yulSyntaxTests/datacopy_shadowing.yul +++ b/test/libyul/yulSyntaxTests/datacopy_shadowing.yul @@ -1,5 +1,7 @@ { function datacopy(a, b, c) {} } +// ==== +// bytecodeFormat: legacy // ---- // ParserError 5568: (15-23): Cannot use builtin function name "datacopy" as identifier name. diff --git a/test/libyul/yulSyntaxTests/dataoffset_shadowing.yul b/test/libyul/yulSyntaxTests/dataoffset_shadowing.yul index fb32fb61c17a..db02e90e4881 100644 --- a/test/libyul/yulSyntaxTests/dataoffset_shadowing.yul +++ b/test/libyul/yulSyntaxTests/dataoffset_shadowing.yul @@ -1,5 +1,7 @@ { function dataoffset(a) -> b {} } +// ==== +// bytecodeFormat: legacy // ---- // ParserError 5568: (15-25): Cannot use builtin function name "dataoffset" as identifier name. diff --git a/test/libyul/yulSyntaxTests/datasize_shadowing.yul b/test/libyul/yulSyntaxTests/datasize_shadowing.yul index 379401754cac..79e500949e8b 100644 --- a/test/libyul/yulSyntaxTests/datasize_shadowing.yul +++ b/test/libyul/yulSyntaxTests/datasize_shadowing.yul @@ -1,5 +1,7 @@ { function datasize(a) -> b {} } +// ==== +// bytecodeFormat: legacy // ---- // ParserError 5568: (15-23): Cannot use builtin function name "datasize" as identifier name. diff --git a/test/libyul/yulSyntaxTests/eof/builtin_function_literal.yul b/test/libyul/yulSyntaxTests/eof/builtin_function_literal.yul new file mode 100644 index 000000000000..d70f5a7bf006 --- /dev/null +++ b/test/libyul/yulSyntaxTests/eof/builtin_function_literal.yul @@ -0,0 +1,9 @@ +{ + auxdataloadn(x,1) +} +// ==== +// bytecodeFormat: >=EOFv1 +// ---- +// TypeError 7000: (6-18): Function "auxdataloadn" expects 1 arguments but got 2. +// TypeError 9114: (6-18): Function expects direct literals as arguments. +// DeclarationError 8198: (19-20): Identifier "x" not found. diff --git a/test/libyul/yulSyntaxTests/eof/datacopy_shadowing.yul b/test/libyul/yulSyntaxTests/eof/datacopy_shadowing.yul new file mode 100644 index 000000000000..b44c2ba0d19f --- /dev/null +++ b/test/libyul/yulSyntaxTests/eof/datacopy_shadowing.yul @@ -0,0 +1,7 @@ +{ + function datacopy(a, b, c) {} +} +// ==== +// bytecodeFormat: >=EOFv1 +// ---- +// DeclarationError 5017: (6-35): The identifier "datacopy" is reserved and can not be used. diff --git a/test/libyul/yulSyntaxTests/eof/dataoffset_shadowing.yul b/test/libyul/yulSyntaxTests/eof/dataoffset_shadowing.yul new file mode 100644 index 000000000000..7c525bcc45e5 --- /dev/null +++ b/test/libyul/yulSyntaxTests/eof/dataoffset_shadowing.yul @@ -0,0 +1,7 @@ +{ + function dataoffset(a) -> b {} +} +// ==== +// bytecodeFormat: >=EOFv1 +// ---- +// DeclarationError 5017: (6-36): The identifier "dataoffset" is reserved and can not be used. diff --git a/test/libyul/yulSyntaxTests/eof/datasize_shadowing.yul b/test/libyul/yulSyntaxTests/eof/datasize_shadowing.yul new file mode 100644 index 000000000000..57345184256c --- /dev/null +++ b/test/libyul/yulSyntaxTests/eof/datasize_shadowing.yul @@ -0,0 +1,7 @@ +{ + function datasize(a) -> b {} +} +// ==== +// bytecodeFormat: >=EOFv1 +// ---- +// DeclarationError 5017: (6-34): The identifier "datasize" is reserved and can not be used. diff --git a/test/libyul/yulSyntaxTests/eof/loadimmutable_shadowing.yul b/test/libyul/yulSyntaxTests/eof/loadimmutable_shadowing.yul new file mode 100644 index 000000000000..a9fc2606752f --- /dev/null +++ b/test/libyul/yulSyntaxTests/eof/loadimmutable_shadowing.yul @@ -0,0 +1,8 @@ +{ + function loadimmutable(a) {} +} +// ==== +// bytecodeFormat: >=EOFv1 +// dialect: evm +// ---- +// DeclarationError 5017: (6-34): The identifier "loadimmutable" is reserved and can not be used. diff --git a/test/libyul/yulSyntaxTests/eof/passing_builtin_with_literal_argument_into_literal_argument.yul b/test/libyul/yulSyntaxTests/eof/passing_builtin_with_literal_argument_into_literal_argument.yul new file mode 100644 index 000000000000..d46c1671b6bf --- /dev/null +++ b/test/libyul/yulSyntaxTests/eof/passing_builtin_with_literal_argument_into_literal_argument.yul @@ -0,0 +1,8 @@ +{ + auxdataloadn(auxdataloadn(0)) +} +// ==== +// bytecodeFormat: >=EOFv1 +// dialect: evm +// ---- +// TypeError 9114: (6-18): Function expects direct literals as arguments. diff --git a/test/libyul/yulSyntaxTests/eof/selfdestruct.yul b/test/libyul/yulSyntaxTests/eof/selfdestruct.yul new file mode 100644 index 000000000000..7920511eb0c4 --- /dev/null +++ b/test/libyul/yulSyntaxTests/eof/selfdestruct.yul @@ -0,0 +1,7 @@ +{ + selfdestruct(0x02) +} +// ==== +// bytecodeFormat: >=EOFv1 +// ---- +// TypeError 9132: (3-15): The "selfdestruct" instruction is only available in legacy bytecode VMs (you are currently compiling to EOF). diff --git a/test/libyul/yulSyntaxTests/eof/setimmutable_shadowing.yul b/test/libyul/yulSyntaxTests/eof/setimmutable_shadowing.yul new file mode 100644 index 000000000000..83d9a33f6821 --- /dev/null +++ b/test/libyul/yulSyntaxTests/eof/setimmutable_shadowing.yul @@ -0,0 +1,8 @@ +{ + function setimmutable(a, b) {} +} +// ==== +// bytecodeFormat: >=EOFv1 +// dialect: evm +// ---- +// DeclarationError 5017: (6-36): The identifier "setimmutable" is reserved and can not be used. diff --git a/test/libyul/yulSyntaxTests/hex_switch_case.yul b/test/libyul/yulSyntaxTests/hex_switch_case.yul index e0d00539a4a8..ec1e3edde9a0 100644 --- a/test/libyul/yulSyntaxTests/hex_switch_case.yul +++ b/test/libyul/yulSyntaxTests/hex_switch_case.yul @@ -1,5 +1,5 @@ { - switch codesize() + switch calldataload(0) case hex"00" {} case hex"1122" {} } diff --git a/test/libyul/yulSyntaxTests/hex_switch_case_long.yul b/test/libyul/yulSyntaxTests/hex_switch_case_long.yul index abdbc6ec15f6..93035730b1d1 100644 --- a/test/libyul/yulSyntaxTests/hex_switch_case_long.yul +++ b/test/libyul/yulSyntaxTests/hex_switch_case_long.yul @@ -1,7 +1,7 @@ { - switch codesize() + switch calldataload(0) case hex"00" {} case hex"112233445566778899001122334455667788990011223344556677889900112233445566778899001122334455667788990011223344556677889900" {} } // ---- -// TypeError 3069: (53-178): String literal too long (60 > 32) +// TypeError 3069: (58-183): String literal too long (60 > 32) diff --git a/test/libyul/yulSyntaxTests/invalid/pc_disallowed.yul b/test/libyul/yulSyntaxTests/invalid/pc_disallowed.yul index d5b3847b1743..6a5587c972ae 100644 --- a/test/libyul/yulSyntaxTests/invalid/pc_disallowed.yul +++ b/test/libyul/yulSyntaxTests/invalid/pc_disallowed.yul @@ -1,5 +1,7 @@ { pop(pc()) } +// ==== +// bytecodeFormat: legacy // ---- // SyntaxError 2450: (10-12): PC instruction is a low-level EVM feature. Because of that PC is disallowed in strict assembly. diff --git a/test/libyul/yulSyntaxTests/loadimmutable.yul b/test/libyul/yulSyntaxTests/loadimmutable.yul index 6aea058b5d57..7c40a65034d5 100644 --- a/test/libyul/yulSyntaxTests/loadimmutable.yul +++ b/test/libyul/yulSyntaxTests/loadimmutable.yul @@ -3,4 +3,5 @@ } // ==== // dialect: evm +// bytecodeFormat: legacy // ---- diff --git a/test/libyul/yulSyntaxTests/loadimmutable_bad_literal.yul b/test/libyul/yulSyntaxTests/loadimmutable_bad_literal.yul index 2aadd2f208f0..ea1d7186f29f 100644 --- a/test/libyul/yulSyntaxTests/loadimmutable_bad_literal.yul +++ b/test/libyul/yulSyntaxTests/loadimmutable_bad_literal.yul @@ -5,6 +5,7 @@ } // ==== // dialect: evm +// bytecodeFormat: legacy // ---- // TypeError 5859: (24-25): Function expects string literal. // TypeError 5859: (50-54): Function expects string literal. diff --git a/test/libyul/yulSyntaxTests/loadimmutable_shadowing.yul b/test/libyul/yulSyntaxTests/loadimmutable_shadowing.yul index 8711d0b17757..8156bd4fba49 100644 --- a/test/libyul/yulSyntaxTests/loadimmutable_shadowing.yul +++ b/test/libyul/yulSyntaxTests/loadimmutable_shadowing.yul @@ -3,5 +3,6 @@ } // ==== // dialect: evm +// bytecodeFormat: legacy // ---- // ParserError 5568: (15-28): Cannot use builtin function name "loadimmutable" as identifier name. diff --git a/test/libyul/yulSyntaxTests/loadimmutable_without_setimmutable.yul b/test/libyul/yulSyntaxTests/loadimmutable_without_setimmutable.yul index 8695e938d7fb..42ca7eb2f8d4 100644 --- a/test/libyul/yulSyntaxTests/loadimmutable_without_setimmutable.yul +++ b/test/libyul/yulSyntaxTests/loadimmutable_without_setimmutable.yul @@ -7,5 +7,7 @@ object "C" { } } } +// ==== +// bytecodeFormat: legacy // ---- // CodeGenerationError 1284: Some immutables were read from but never assigned, possibly because of optimization. diff --git a/test/libyul/yulSyntaxTests/metadata_access.yul b/test/libyul/yulSyntaxTests/metadata_access.yul index 63aeb4760296..52bf786cda73 100644 --- a/test/libyul/yulSyntaxTests/metadata_access.yul +++ b/test/libyul/yulSyntaxTests/metadata_access.yul @@ -21,6 +21,8 @@ object "A" { data ".metadata" "Hello, World!" data ".other" "Hello, World2!" } +// ==== +// bytecodeFormat: legacy // ---- // TypeError 3517: (41-49): Unknown data object ".other". // TypeError 3517: (69-77): Unknown data object ".other". diff --git a/test/libyul/yulSyntaxTests/metadata_access_2.yul b/test/libyul/yulSyntaxTests/metadata_access_2.yul index a4b013e854ff..204409d3e97f 100644 --- a/test/libyul/yulSyntaxTests/metadata_access_2.yul +++ b/test/libyul/yulSyntaxTests/metadata_access_2.yul @@ -9,5 +9,7 @@ object "A" { data "1" "XYZ" data ".mightbereservedinthefuture" "TRS" } +// ==== +// bytecodeFormat: legacy // ---- // TypeError 3517: (90-119): Unknown data object ".mightbereservedinthefuture". diff --git a/test/libyul/yulSyntaxTests/metadata_access_subobject.yul b/test/libyul/yulSyntaxTests/metadata_access_subobject.yul index 216b56ac649c..c52ab9e1a66c 100644 --- a/test/libyul/yulSyntaxTests/metadata_access_subobject.yul +++ b/test/libyul/yulSyntaxTests/metadata_access_subobject.yul @@ -8,5 +8,7 @@ object "A" { data "x" "ABC" } } +// ==== +// bytecodeFormat: legacy // ---- // TypeError 3517: (41-54): Unknown data object ".metadata.x". diff --git a/test/libyul/yulSyntaxTests/objects/data.yul b/test/libyul/yulSyntaxTests/objects/data.yul index 47d7b59c7f0a..744a88c64578 100644 --- a/test/libyul/yulSyntaxTests/objects/data.yul +++ b/test/libyul/yulSyntaxTests/objects/data.yul @@ -6,4 +6,6 @@ object "A" { data "2" hex"0011" data "3" "hello world this is longer than 32 bytes and should still work" } +// ==== +// bytecodeFormat: legacy // ---- diff --git a/test/libyul/yulSyntaxTests/objects/data_access.yul b/test/libyul/yulSyntaxTests/objects/data_access.yul index e9455fafab33..681cb5028056 100644 --- a/test/libyul/yulSyntaxTests/objects/data_access.yul +++ b/test/libyul/yulSyntaxTests/objects/data_access.yul @@ -6,4 +6,6 @@ object "A" { data "B" hex"00" } +// ==== +// bytecodeFormat: legacy // ---- diff --git a/test/libyul/yulSyntaxTests/objects/datacopy.yul b/test/libyul/yulSyntaxTests/objects/datacopy.yul index 6e36025fcbd1..1afb88e2739b 100644 --- a/test/libyul/yulSyntaxTests/objects/datacopy.yul +++ b/test/libyul/yulSyntaxTests/objects/datacopy.yul @@ -6,4 +6,6 @@ let s := "" datacopy(x, "11", s) } +// ==== +// bytecodeFormat: legacy // ---- diff --git a/test/libyul/yulSyntaxTests/objects/dataoffset_nonliteral.yul b/test/libyul/yulSyntaxTests/objects/dataoffset_nonliteral.yul index d53e26281eae..ba80b462efd0 100644 --- a/test/libyul/yulSyntaxTests/objects/dataoffset_nonliteral.yul +++ b/test/libyul/yulSyntaxTests/objects/dataoffset_nonliteral.yul @@ -6,5 +6,7 @@ object "A" { data "B" hex"00" } +// ==== +// bytecodeFormat: legacy // ---- // TypeError 9114: (47-57): Function expects direct literals as arguments. diff --git a/test/libyul/yulSyntaxTests/objects/dataoffset_nonstring.yul b/test/libyul/yulSyntaxTests/objects/dataoffset_nonstring.yul index 93a981d924e0..1ac18c19c5bb 100644 --- a/test/libyul/yulSyntaxTests/objects/dataoffset_nonstring.yul +++ b/test/libyul/yulSyntaxTests/objects/dataoffset_nonstring.yul @@ -3,5 +3,7 @@ object "A" { pop(dataoffset(0)) } } +// ==== +// bytecodeFormat: legacy // ---- // TypeError 5859: (41-42): Function expects string literal. diff --git a/test/libyul/yulSyntaxTests/objects/dataoffset_notfound.yul b/test/libyul/yulSyntaxTests/objects/dataoffset_notfound.yul index 14df40201418..3ee03d66e63d 100644 --- a/test/libyul/yulSyntaxTests/objects/dataoffset_notfound.yul +++ b/test/libyul/yulSyntaxTests/objects/dataoffset_notfound.yul @@ -4,5 +4,7 @@ object "A" { } data "B" "" } +// ==== +// bytecodeFormat: legacy // ---- // TypeError 3517: (41-44): Unknown data object "C". diff --git a/test/libyul/yulSyntaxTests/objects/datasize_nonliteral.yul b/test/libyul/yulSyntaxTests/objects/datasize_nonliteral.yul index 837408b9a00b..a5179f3e45e2 100644 --- a/test/libyul/yulSyntaxTests/objects/datasize_nonliteral.yul +++ b/test/libyul/yulSyntaxTests/objects/datasize_nonliteral.yul @@ -6,5 +6,7 @@ object "A" { data "B" hex"00" } +// ==== +// bytecodeFormat: legacy // ---- // TypeError 9114: (47-55): Function expects direct literals as arguments. diff --git a/test/libyul/yulSyntaxTests/objects/datasize_nonstring.yul b/test/libyul/yulSyntaxTests/objects/datasize_nonstring.yul index 19042a2df738..c8697d06b3dc 100644 --- a/test/libyul/yulSyntaxTests/objects/datasize_nonstring.yul +++ b/test/libyul/yulSyntaxTests/objects/datasize_nonstring.yul @@ -3,5 +3,7 @@ object "A" { pop(datasize(0)) } } +// ==== +// bytecodeFormat: legacy // ---- // TypeError 5859: (39-40): Function expects string literal. diff --git a/test/libyul/yulSyntaxTests/objects/datasize_notfound.yul b/test/libyul/yulSyntaxTests/objects/datasize_notfound.yul index 48a2c268e205..4fe607a0b8da 100644 --- a/test/libyul/yulSyntaxTests/objects/datasize_notfound.yul +++ b/test/libyul/yulSyntaxTests/objects/datasize_notfound.yul @@ -4,5 +4,7 @@ object "A" { } data "B" "" } +// ==== +// bytecodeFormat: legacy // ---- // TypeError 3517: (39-42): Unknown data object "C". diff --git a/test/libyul/yulSyntaxTests/objects/subobject_access.yul b/test/libyul/yulSyntaxTests/objects/subobject_access.yul index 59426a0aa631..11fd37d9c6f0 100644 --- a/test/libyul/yulSyntaxTests/objects/subobject_access.yul +++ b/test/libyul/yulSyntaxTests/objects/subobject_access.yul @@ -8,4 +8,6 @@ object "A" { code {} } } +// ==== +// bytecodeFormat: legacy // ---- diff --git a/test/libyul/yulSyntaxTests/opcode_for_function_args_1.yul b/test/libyul/yulSyntaxTests/opcode_for_function_args_1.yul index 00c357bb44aa..dfe4ed903274 100644 --- a/test/libyul/yulSyntaxTests/opcode_for_function_args_1.yul +++ b/test/libyul/yulSyntaxTests/opcode_for_function_args_1.yul @@ -1,5 +1,5 @@ { - function f(gas) {} + function f(mload) {} } // ---- -// ParserError 5568: (14-17): Cannot use builtin function name "gas" as identifier name. +// ParserError 5568: (14-19): Cannot use builtin function name "mload" as identifier name. diff --git a/test/libyul/yulSyntaxTests/opcode_for_function_args_2.yul b/test/libyul/yulSyntaxTests/opcode_for_function_args_2.yul index 989cfce9e007..9fdb7727787b 100644 --- a/test/libyul/yulSyntaxTests/opcode_for_function_args_2.yul +++ b/test/libyul/yulSyntaxTests/opcode_for_function_args_2.yul @@ -1,5 +1,5 @@ { - function f() -> gas {} + function f() -> mload {} } // ---- -// ParserError 5568: (19-22): Cannot use builtin function name "gas" as identifier name. +// ParserError 5568: (19-24): Cannot use builtin function name "mload" as identifier name. diff --git a/test/libyul/yulSyntaxTests/opcode_for_functions.yul b/test/libyul/yulSyntaxTests/opcode_for_functions.yul index 0efc7cbccedd..8dea8893d337 100644 --- a/test/libyul/yulSyntaxTests/opcode_for_functions.yul +++ b/test/libyul/yulSyntaxTests/opcode_for_functions.yul @@ -1,5 +1,5 @@ { - function gas() {} + function mload() {} } // ---- -// ParserError 5568: (12-15): Cannot use builtin function name "gas" as identifier name. +// ParserError 5568: (12-17): Cannot use builtin function name "mload" as identifier name. diff --git a/test/libyul/yulSyntaxTests/passing_builtin_with_literal_argument_into_literal_argument.yul b/test/libyul/yulSyntaxTests/passing_builtin_with_literal_argument_into_literal_argument.yul index 433d36683dfe..d1e6d50e9e80 100644 --- a/test/libyul/yulSyntaxTests/passing_builtin_with_literal_argument_into_literal_argument.yul +++ b/test/libyul/yulSyntaxTests/passing_builtin_with_literal_argument_into_literal_argument.yul @@ -3,5 +3,6 @@ } // ==== // dialect: evm +// bytecodeFormat: legacy // ---- // TypeError 9114: (6-18): Function expects direct literals as arguments. diff --git a/test/libyul/yulSyntaxTests/selfdestruct.yul b/test/libyul/yulSyntaxTests/selfdestruct.yul index faecf92c3805..181e9806ddaa 100644 --- a/test/libyul/yulSyntaxTests/selfdestruct.yul +++ b/test/libyul/yulSyntaxTests/selfdestruct.yul @@ -1,5 +1,7 @@ { selfdestruct(0x02) } +// ==== +// bytecodeFormat: legacy // ---- // Warning 1699: (3-15): "selfdestruct" has been deprecated. Note that, starting from the Cancun hard fork, the underlying opcode no longer deletes the code and data associated with an account and only transfers its Ether to the beneficiary, unless executed in the same transaction in which the contract was created (see EIP-6780). Any use in newly deployed contracts is strongly discouraged even if the new behavior is taken into account. Future changes to the EVM might further reduce the functionality of the opcode. diff --git a/test/libyul/yulSyntaxTests/setimmutable.yul b/test/libyul/yulSyntaxTests/setimmutable.yul index e1d6a74919c9..88e38b1338a4 100644 --- a/test/libyul/yulSyntaxTests/setimmutable.yul +++ b/test/libyul/yulSyntaxTests/setimmutable.yul @@ -3,4 +3,5 @@ } // ==== // dialect: evm +// bytecodeFormat: legacy // ---- diff --git a/test/libyul/yulSyntaxTests/setimmutable_bad_literal.yul b/test/libyul/yulSyntaxTests/setimmutable_bad_literal.yul index 9e4bc8032c78..175ab15aa59e 100644 --- a/test/libyul/yulSyntaxTests/setimmutable_bad_literal.yul +++ b/test/libyul/yulSyntaxTests/setimmutable_bad_literal.yul @@ -5,6 +5,7 @@ } // ==== // dialect: evm +// bytecodeFormat: legacy // ---- // TypeError 5859: (22-23): Function expects string literal. // TypeError 5859: (89-93): Function expects string literal. diff --git a/test/libyul/yulSyntaxTests/setimmutable_shadowing.yul b/test/libyul/yulSyntaxTests/setimmutable_shadowing.yul index b76a5de9b729..fbcfeb15ff98 100644 --- a/test/libyul/yulSyntaxTests/setimmutable_shadowing.yul +++ b/test/libyul/yulSyntaxTests/setimmutable_shadowing.yul @@ -3,5 +3,6 @@ } // ==== // dialect: evm +// bytecodeFormat: legacy // ---- // ParserError 5568: (15-27): Cannot use builtin function name "setimmutable" as identifier name. diff --git a/test/libyul/yulSyntaxTests/simple_functions.yul b/test/libyul/yulSyntaxTests/simple_functions.yul index 5b63885f2b5f..8d97e4ac0e39 100644 --- a/test/libyul/yulSyntaxTests/simple_functions.yul +++ b/test/libyul/yulSyntaxTests/simple_functions.yul @@ -2,7 +2,7 @@ function a() {} function f() { mstore(0, 1) } function g() { sstore(0, 1) } - function h() { let x := msize() } + function h() { let x := balance(0x0) } function i() { let z := mload(0) } } // ==== diff --git a/test/libyul/yulSyntaxTests/string_literal_switch_case.yul b/test/libyul/yulSyntaxTests/string_literal_switch_case.yul index 6f0d72229947..b69b56c662cd 100644 --- a/test/libyul/yulSyntaxTests/string_literal_switch_case.yul +++ b/test/libyul/yulSyntaxTests/string_literal_switch_case.yul @@ -1,5 +1,5 @@ { - switch codesize() + switch calldataload(0) case "1" {} case "2" {} } diff --git a/test/libyul/yulSyntaxTests/string_literal_too_long_immutable.yul b/test/libyul/yulSyntaxTests/string_literal_too_long_immutable.yul index 98707451e600..d81f69a082ee 100644 --- a/test/libyul/yulSyntaxTests/string_literal_too_long_immutable.yul +++ b/test/libyul/yulSyntaxTests/string_literal_too_long_immutable.yul @@ -7,4 +7,5 @@ } // ==== // dialect: evm +// bytecodeFormat: legacy // ---- From c64cb1ffcf7061cdd7fa21a4f53632ad5a147b9d Mon Sep 17 00:00:00 2001 From: r0qs Date: Tue, 28 Jan 2025 23:27:27 +0100 Subject: [PATCH 0746/1022] Fix foundry version for prb-math --- .circleci/config.yml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 164694e4505e..8e1e85794210 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -834,6 +834,8 @@ defaults: binary_type: native image: cimg/rust:1.74.0-node resource_class: medium + # TODO: Use nightly Foundry builds after https://github.com/PaulRBerg/prb-math/issues/248 is fixed + foundry_version: "v0.3.0" - job_native_test_ext_elementfi: &job_native_test_ext_elementfi <<: *requires_b_ubu_static @@ -1461,6 +1463,9 @@ jobs: python2: type: boolean default: false + foundry_version: + type: string + default: "nightly" docker: - image: << parameters.image >> resource_class: << parameters.resource_class >> @@ -1474,7 +1479,8 @@ jobs: - checkout - attach_workspace: at: /tmp/workspace - - install_foundry + - install_foundry: + version: << parameters.foundry_version >> - run: name: Ensure pnpm is installed if npm is present command: | From 89b20de21d9e30b2953e2eb40311d0486eeed42f Mon Sep 17 00:00:00 2001 From: Skyge <1506186404li@gmail.com> Date: Wed, 29 Jan 2025 15:27:19 +0800 Subject: [PATCH 0747/1022] Update versions flyout menu location. --- docs/index.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/index.rst b/docs/index.rst index f1608890d757..a60dc1b84d46 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -29,7 +29,7 @@ read our :doc:`contributors guide ` for more details. .. Hint:: You can download this documentation as PDF, HTML or Epub - by clicking on the versions flyout menu in the bottom-left corner and selecting the preferred download format. + by clicking on the versions flyout menu in the bottom-right corner and selecting the preferred download format. Getting Started From 9851010d2ed143f5382b1b2b6e57e3e33f2d5001 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Fri, 24 Jan 2025 01:42:46 +0100 Subject: [PATCH 0748/1022] Remove obsolete semantic tests for the old-style .value() syntax - The ones in `functionCall` were testing multiple applications of `.value()`, which is no longer possible with the `{value: ...}` syntax. - The ones in `various` became identical when the `.value()` syntax was deprecated. --- .../functionCall/gas_and_value_basic.sol | 2 - .../gas_and_value_brace_syntax.sol | 48 ------------------- .../semanticTests/various/value_complex.sol | 28 ----------- .../semanticTests/various/value_insane.sol | 27 ----------- 4 files changed, 105 deletions(-) delete mode 100644 test/libsolidity/semanticTests/functionCall/gas_and_value_brace_syntax.sol delete mode 100644 test/libsolidity/semanticTests/various/value_complex.sol delete mode 100644 test/libsolidity/semanticTests/various/value_insane.sol diff --git a/test/libsolidity/semanticTests/functionCall/gas_and_value_basic.sol b/test/libsolidity/semanticTests/functionCall/gas_and_value_basic.sol index e6187d06e2df..e7bf053eb2c6 100644 --- a/test/libsolidity/semanticTests/functionCall/gas_and_value_basic.sol +++ b/test/libsolidity/semanticTests/functionCall/gas_and_value_basic.sol @@ -13,8 +13,6 @@ contract helper { return flag; } } - - contract test { helper h; diff --git a/test/libsolidity/semanticTests/functionCall/gas_and_value_brace_syntax.sol b/test/libsolidity/semanticTests/functionCall/gas_and_value_brace_syntax.sol deleted file mode 100644 index 41079af03955..000000000000 --- a/test/libsolidity/semanticTests/functionCall/gas_and_value_brace_syntax.sol +++ /dev/null @@ -1,48 +0,0 @@ -contract helper { - bool flag; - - function getBalance() payable public returns(uint256 myBalance) { - return address(this).balance; - } - - function setFlag() public { - flag = true; - } - - function getFlag() public returns(bool fl) { - return flag; - } -} -contract test { - helper h; - constructor() payable { - h = new helper(); - } - - function sendAmount(uint amount) public payable returns(uint256 bal) { - return h.getBalance{value: amount}(); - } - - function outOfGas() public returns(bool ret) { - h.setFlag { - gas: 2 - }(); // should fail due to OOG - return true; - } - - function checkState() public returns(bool flagAfter, uint myBal) { - flagAfter = h.getFlag(); - myBal = address(this).balance; - } -} -// ---- -// constructor(), 20 wei -> -// gas irOptimized: 120218 -// gas irOptimized code: 132000 -// gas legacy: 130583 -// gas legacy code: 261200 -// gas legacyOptimized: 121069 -// gas legacyOptimized code: 147000 -// sendAmount(uint256): 5 -> 5 -// outOfGas() -> FAILURE # call to helper should not succeed but amount should be transferred anyway # -// checkState() -> false, 15 diff --git a/test/libsolidity/semanticTests/various/value_complex.sol b/test/libsolidity/semanticTests/various/value_complex.sol deleted file mode 100644 index 4639d34c7071..000000000000 --- a/test/libsolidity/semanticTests/various/value_complex.sol +++ /dev/null @@ -1,28 +0,0 @@ -contract helper { - function getBalance() public payable returns (uint256 myBalance) { - return address(this).balance; - } -} - - -contract test { - helper h; - - constructor() payable { - h = new helper(); - } - - function sendAmount(uint256 amount) public payable returns (uint256 bal) { - uint256 someStackElement = 20; - return h.getBalance{value: amount + 3, gas: 1000}(); - } -} -// ---- -// constructor(), 20 wei -> -// gas irOptimized: 114463 -// gas irOptimized code: 58800 -// gas legacy: 120091 -// gas legacy code: 132400 -// gas legacyOptimized: 114536 -// gas legacyOptimized code: 65800 -// sendAmount(uint256): 5 -> 8 diff --git a/test/libsolidity/semanticTests/various/value_insane.sol b/test/libsolidity/semanticTests/various/value_insane.sol deleted file mode 100644 index bc6a803de92f..000000000000 --- a/test/libsolidity/semanticTests/various/value_insane.sol +++ /dev/null @@ -1,27 +0,0 @@ -contract helper { - function getBalance() public payable returns (uint256 myBalance) { - return address(this).balance; - } -} - - -contract test { - helper h; - - constructor() payable { - h = new helper(); - } - - function sendAmount(uint256 amount) public returns (uint256 bal) { - return h.getBalance{value: amount + 3, gas: 1000}(); - } -} -// ---- -// constructor(), 20 wei -> -// gas irOptimized: 114527 -// gas irOptimized code: 59600 -// gas legacy: 120199 -// gas legacy code: 133600 -// gas legacyOptimized: 114568 -// gas legacyOptimized code: 66200 -// sendAmount(uint256): 5 -> 8 From 3b1d78d3e3d5a873b78e24184f746166b5f32389 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Thu, 23 Jan 2025 19:15:32 +0100 Subject: [PATCH 0749/1022] Adjust semantic tests where possible to make them run unchanged on both EOF and legacy --- .../keccak256_packed_complex_types.sol | 4 +- .../constructor/no_callvalue_check.sol | 12 ++--- .../errors/errors_by_parameter_type.sol | 8 +-- ...quire_error_function_pointer_parameter.sol | 4 +- .../events/event_indexed_function.sol | 4 +- .../events/event_indexed_function2.sol | 8 +-- .../semanticTests/externalContracts/snark.sol | 52 +++++++++---------- .../functionCall/failed_create.sol | 32 ++++++------ .../functionTypes/address_member.sol | 10 ++-- .../function_external_delete_storage.sol | 38 +++++++------- .../immutable/multi_creation.sol | 12 ++--- .../address_overload_resolution.sol | 8 +-- .../interface_inheritance_conversions.sol | 13 ++--- .../inheritance/member_notation_ctor.sol | 6 +-- .../external_function_pointer_address.sol | 8 +-- .../transient_storage_low_level_calls.sol | 12 ++--- .../balance_other_contract.sol | 27 ++-------- .../operator_making_pure_external_call.sol | 12 ++--- .../operator_making_view_external_call.sol | 12 ++--- .../semanticTests/tryCatch/assert.sol | 5 +- .../tryCatch/assert_pre_byzantium.sol | 18 +++++++ .../semanticTests/tryCatch/create.sol | 12 ++--- .../{super_trivial.sol => require.sol} | 2 +- ...{trivial.sol => require_pre_byzantium.sol} | 2 + .../tryCatch/return_function.sol | 4 +- .../various/many_subassemblies.sol | 28 +++++----- .../viaYul/conversion/function_cast.sol | 11 ++-- .../semanticTests/viaYul/function_address.sol | 15 +++--- 28 files changed, 187 insertions(+), 192 deletions(-) create mode 100644 test/libsolidity/semanticTests/tryCatch/assert_pre_byzantium.sol rename test/libsolidity/semanticTests/tryCatch/{super_trivial.sol => require.sol} (87%) rename test/libsolidity/semanticTests/tryCatch/{trivial.sol => require_pre_byzantium.sol} (91%) diff --git a/test/libsolidity/semanticTests/builtinFunctions/keccak256_packed_complex_types.sol b/test/libsolidity/semanticTests/builtinFunctions/keccak256_packed_complex_types.sol index ea6d781898f0..fbecf750ab4f 100644 --- a/test/libsolidity/semanticTests/builtinFunctions/keccak256_packed_complex_types.sol +++ b/test/libsolidity/semanticTests/builtinFunctions/keccak256_packed_complex_types.sol @@ -7,8 +7,8 @@ contract C { x[2] = y[2] = uint120(type(uint).max - 3); hash1 = keccak256(abi.encodePacked(x)); hash2 = keccak256(abi.encodePacked(y)); - hash3 = keccak256(abi.encodePacked(this.f)); + hash3 = keccak256(abi.encodePacked(C(address(0x1234)))); } } // ---- -// f() -> 0xba4f20407251e4607cd66b90bfea19ec6971699c03e4a4f3ea737d5818ac27ae, 0xba4f20407251e4607cd66b90bfea19ec6971699c03e4a4f3ea737d5818ac27ae, 0x0e9229fb1d2cd02cee4b6c9f25497777014a8766e3479666d1c619066d2887ec +// f() -> 0xba4f20407251e4607cd66b90bfea19ec6971699c03e4a4f3ea737d5818ac27ae, 0xba4f20407251e4607cd66b90bfea19ec6971699c03e4a4f3ea737d5818ac27ae, 0xe7490fade3a8e31113ecb6c0d2635e28a6f5ca8359a57afe914827f41ddf0848 diff --git a/test/libsolidity/semanticTests/constructor/no_callvalue_check.sol b/test/libsolidity/semanticTests/constructor/no_callvalue_check.sol index 583f1ca37b3f..f21d473413f1 100644 --- a/test/libsolidity/semanticTests/constructor/no_callvalue_check.sol +++ b/test/libsolidity/semanticTests/constructor/no_callvalue_check.sol @@ -9,17 +9,17 @@ contract B3 { constructor() payable {} } contract C { function f() public payable returns (bool) { // Make sure none of these revert. - new B1{value: 10}(); - new B2{value: 10}(); - new B3{value: 10}(); + new B1{value: 10, salt: hex"00"}(); + new B2{value: 10, salt: hex"01"}(); + new B3{value: 10, salt: hex"02"}(); return true; } } // ---- // f(), 2000 ether -> true -// gas irOptimized: 117623 +// gas irOptimized: 117688 // gas irOptimized code: 1800 -// gas legacy: 117821 +// gas legacy: 117889 // gas legacy code: 4800 -// gas legacyOptimized: 117690 +// gas legacyOptimized: 117761 // gas legacyOptimized code: 4800 diff --git a/test/libsolidity/semanticTests/errors/errors_by_parameter_type.sol b/test/libsolidity/semanticTests/errors/errors_by_parameter_type.sol index bc70b5bef757..906fd0597d53 100644 --- a/test/libsolidity/semanticTests/errors/errors_by_parameter_type.sol +++ b/test/libsolidity/semanticTests/errors/errors_by_parameter_type.sol @@ -27,10 +27,10 @@ contract C { require(false, E3(S(1, true, "string literal"))); } function e() external view { - require(false, E4(address(this))); + require(false, E4(address(0x1234))); } function f() external view { - require(false, E5(this.a)); + require(false, E5(C(address(0x1234)).a)); } } @@ -41,5 +41,5 @@ contract C { // b() -> FAILURE, hex"47e26897", hex"0000000000000000000000000000000000000000000000000000000000000001" // c() -> FAILURE, hex"8f372c34", hex"0000000000000000000000000000000000000000000000000000000000000020", hex"000000000000000000000000000000000000000000000000000000000000000e", hex"737472696e67206c69746572616c000000000000000000000000000000000000" // d() -> FAILURE, hex"5717173e", hex"0000000000000000000000000000000000000000000000000000000000000020", hex"0000000000000000000000000000000000000000000000000000000000000001", hex"0000000000000000000000000000000000000000000000000000000000000001", hex"0000000000000000000000000000000000000000000000000000000000000060", hex"000000000000000000000000000000000000000000000000000000000000000e", hex"737472696e67206c69746572616c000000000000000000000000000000000000" -// e() -> FAILURE, hex"7efef9ea", hex"000000000000000000000000c06afe3a8444fc0004668591e8306bfb9968e79e" -// f() -> FAILURE, hex"0c3f12eb", hex"c06afe3a8444fc0004668591e8306bfb9968e79e0dbe671f0000000000000000" +// e() -> FAILURE, hex"7efef9ea", hex"0000000000000000000000000000000000000000000000000000000000001234" +// f() -> FAILURE, hex"0c3f12eb", hex"00000000000000000000000000000000000012340dbe671f0000000000000000" diff --git a/test/libsolidity/semanticTests/errors/require_error_function_pointer_parameter.sol b/test/libsolidity/semanticTests/errors/require_error_function_pointer_parameter.sol index 3af19ca64fbf..7a82d4f81e35 100644 --- a/test/libsolidity/semanticTests/errors/require_error_function_pointer_parameter.sol +++ b/test/libsolidity/semanticTests/errors/require_error_function_pointer_parameter.sol @@ -10,9 +10,9 @@ contract C function f() external view { // more than one stack slot - require(false, CustomError(this.e)); + require(false, CustomError(C(address(0x1234)).e)); } } // ---- -// f() -> FAILURE, hex"271b1dfa", hex"c06afe3a8444fc0004668591e8306bfb9968e79ef37cdc8e0000000000000000" +// f() -> FAILURE, hex"271b1dfa", hex"0000000000000000000000000000000000001234f37cdc8e0000000000000000" diff --git a/test/libsolidity/semanticTests/events/event_indexed_function.sol b/test/libsolidity/semanticTests/events/event_indexed_function.sol index ea7574159500..29b19dbe711d 100644 --- a/test/libsolidity/semanticTests/events/event_indexed_function.sol +++ b/test/libsolidity/semanticTests/events/event_indexed_function.sol @@ -1,9 +1,9 @@ contract C { event Test(function() external indexed); function f() public { - emit Test(this.f); + emit Test(C(address(0x1234)).f); } } // ---- // f() -> -// ~ emit Test(function): #0xc06afe3a8444fc0004668591e8306bfb9968e79e26121ff00000000000000000 +// ~ emit Test(function): #0x123426121ff00000000000000000 diff --git a/test/libsolidity/semanticTests/events/event_indexed_function2.sol b/test/libsolidity/semanticTests/events/event_indexed_function2.sol index d4c47e868a1f..9587f8c37778 100644 --- a/test/libsolidity/semanticTests/events/event_indexed_function2.sol +++ b/test/libsolidity/semanticTests/events/event_indexed_function2.sol @@ -2,14 +2,14 @@ contract C { event TestA(function() external indexed); event TestB(function(uint256) external indexed); function f1() public { - emit TestA(this.f1); + emit TestA(C(address(0x1234)).f1); } function f2(uint256 a) public { - emit TestB(this.f2); + emit TestB(C(address(0x1234)).f2); } } // ---- // f1() -> -// ~ emit TestA(function): #0xc06afe3a8444fc0004668591e8306bfb9968e79ec27fc3050000000000000000 +// ~ emit TestA(function): #0x1234c27fc3050000000000000000 // f2(uint256): 1 -> -// ~ emit TestB(function): #0xc06afe3a8444fc0004668591e8306bfb9968e79ebf3724af0000000000000000 +// ~ emit TestB(function): #0x1234bf3724af0000000000000000 diff --git a/test/libsolidity/semanticTests/externalContracts/snark.sol b/test/libsolidity/semanticTests/externalContracts/snark.sol index 906279d17935..2b1fe023e075 100644 --- a/test/libsolidity/semanticTests/externalContracts/snark.sol +++ b/test/libsolidity/semanticTests/externalContracts/snark.sol @@ -1,3 +1,5 @@ +pragma abicoder v2; + library Pairing { struct G1Point { uint X; @@ -35,34 +37,26 @@ library Pairing { /// @return r the sum of two points of G1 function add(G1Point memory p1, G1Point memory p2) internal returns (G1Point memory r) { - uint[4] memory input; + uint[6] memory input; input[0] = p1.X; input[1] = p1.Y; input[2] = p2.X; input[3] = p2.Y; - bool success; - assembly { - success := call(sub(gas(), 2000), 6, 0, input, 0xc0, r, 0x60) - // Use "invalid" to make gas estimation work - switch success case 0 { invalid() } - } + (bool success, bytes memory encodedResult) = address(6).call(abi.encode(input)); require(success); + r = abi.decode(encodedResult, (G1Point)); } /// @return r the product of a point on G1 and a scalar, i.e. /// p == p.mul(1) and p.add(p) == p.mul(2) for all points p. function mul(G1Point memory p, uint s) internal returns (G1Point memory r) { - uint[3] memory input; + uint[4] memory input; input[0] = p.X; input[1] = p.Y; input[2] = s; - bool success; - assembly { - success := call(sub(gas(), 2000), 7, 0, input, 0x80, r, 0x60) - // Use "invalid" to make gas estimation work - switch success case 0 { invalid() } - } + (bool success, bytes memory encodedResult) = address(7).call(abi.encode(input)); require(success); + r = abi.decode(encodedResult, (G1Point)); } /// @return the result of computing the pairing check @@ -83,15 +77,19 @@ library Pairing { input[i * 6 + 4] = p2[i].Y[0]; input[i * 6 + 5] = p2[i].Y[1]; } - uint[1] memory out; - bool success; - assembly { - success := call(sub(gas(), 2000), 8, 0, add(input, 0x20), mul(inputSize, 0x20), out, 0x20) - // Use "invalid" to make gas estimation work - switch success case 0 { invalid() } + + bytes memory encodedInput = new bytes(inputSize * 32); + for (uint i = 0; i < inputSize; i++) + { + uint offset = (i + 1) * 32; + uint item = input[i]; + assembly ("memory-safe") { + mstore(add(encodedInput, offset), item) + } } + (bool success, bytes memory encodedResult) = address(8).call(encodedInput); require(success); - return out[0] != 0; + return abi.decode(encodedResult, (bool)); } function pairingProd2(G1Point memory a1, G2Point memory a2, G1Point memory b1, G2Point memory b2) internal returns (bool) { G1Point[] memory p1 = new G1Point[](2); @@ -294,11 +292,11 @@ contract Test { // f() -> true // g() -> true // pair() -> true -// gas irOptimized: 270409 -// gas legacy: 275219 -// gas legacyOptimized: 266862 +// gas irOptimized: 275319 +// gas legacy: 293854 +// gas legacyOptimized: 276409 // verifyTx() -> true // ~ emit Verified(string): 0x20, 0x16, "Successfully verified." -// gas irOptimized: 785720 -// gas legacy: 801903 -// gas legacyOptimized: 770941 +// gas irOptimized: 821446 +// gas legacy: 914211 +// gas legacyOptimized: 820319 diff --git a/test/libsolidity/semanticTests/functionCall/failed_create.sol b/test/libsolidity/semanticTests/functionCall/failed_create.sol index 657b4b5cfff6..bb6289768445 100644 --- a/test/libsolidity/semanticTests/functionCall/failed_create.sol +++ b/test/libsolidity/semanticTests/functionCall/failed_create.sol @@ -2,35 +2,35 @@ contract D { constructor() payable {} } contract C { uint public x; constructor() payable {} - function f(uint amount) public returns (D) { + function f(uint amount) public { x++; - return (new D){value: amount}(); + (new D){value: amount, salt: bytes32(x)}(); } - function stack(uint depth) public payable returns (address) { + function stack(uint depth) public payable { if (depth > 0) - return this.stack(depth - 1); + this.stack(depth - 1); else - return address(f(0)); + f(0); } } // ==== // EVMVersion: >=byzantium // ---- // constructor(), 20 wei -// gas irOptimized: 61548 -// gas irOptimized code: 104600 -// gas legacy: 70147 -// gas legacy code: 215400 -// gas legacyOptimized: 61715 -// gas legacyOptimized code: 106800 -// f(uint256): 20 -> 0x137aa4dfc0911524504fcd4d98501f179bc13b4a +// gas irOptimized: 59688 +// gas irOptimized code: 81800 +// gas legacy: 64468 +// gas legacy code: 145400 +// gas legacyOptimized: 60443 +// gas legacyOptimized code: 91200 +// f(uint256): 20 -> // x() -> 1 // f(uint256): 20 -> FAILURE // x() -> 1 // stack(uint256): 1023 -> FAILURE -// gas irOptimized: 252410 -// gas legacy: 476845 -// gas legacyOptimized: 299061 +// gas irOptimized: 298110 +// gas legacy: 527207 +// gas legacyOptimized: 353607 // x() -> 1 -// stack(uint256): 10 -> 0x87948bd7ebbe13a00bfd930c93e4828ab18e3908 +// stack(uint256): 10 -> // x() -> 2 diff --git a/test/libsolidity/semanticTests/functionTypes/address_member.sol b/test/libsolidity/semanticTests/functionTypes/address_member.sol index a5f56f3dc688..214752a1f45c 100644 --- a/test/libsolidity/semanticTests/functionTypes/address_member.sol +++ b/test/libsolidity/semanticTests/functionTypes/address_member.sol @@ -1,10 +1,10 @@ contract C { function f() public view returns (address a1, address a2) { - a1 = this.f.address; - this.f.address; - [this.f.address][0]; - a2 = [this.f.address][0]; + a1 = C(address(0x1234)).f.address; + C(address(0x1234)).f.address; + [C(address(0x1234)).f.address][0]; + a2 = [C(address(0x1234)).f.address][0]; } } // ---- -// f() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e, 0xc06afe3a8444fc0004668591e8306bfb9968e79e +// f() -> 0x1234, 0x1234 diff --git a/test/libsolidity/semanticTests/functionTypes/function_external_delete_storage.sol b/test/libsolidity/semanticTests/functionTypes/function_external_delete_storage.sol index d5e105e5f536..1d8d1897c8f6 100644 --- a/test/libsolidity/semanticTests/functionTypes/function_external_delete_storage.sol +++ b/test/libsolidity/semanticTests/functionTypes/function_external_delete_storage.sol @@ -1,17 +1,19 @@ contract C { function() external public x; - uint public y = 0; - function increment() public { - ++y; - } + function f() public {} function set() external { - x = this.increment; + x = this.f; + } + + function isF() external returns (bool) { + return x == this.f; } - function incrementIndirectly() public { - x(); + function isZero() external returns (bool) { + function() external zero; + return x == zero; } function deleteFunction() public { @@ -20,18 +22,14 @@ contract C { } } // ---- -// x() -> 0 -// y() -> 0 -// increment() -> -// y() -> 1 +// isF() -> false +// isZero() -> true +// deleteFunction() -> +// isF() -> false +// isZero() -> true // set() -> -// x() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79ed09de08a0000000000000000 -// increment() -> -// y() -> 2 -// incrementIndirectly() -> -// y() -> 3 +// isF() -> true +// isZero() -> false // deleteFunction() -> -// increment() -> -// y() -> 4 -// incrementIndirectly() -> FAILURE -// y() -> 4 +// isF() -> false +// isZero() -> true diff --git a/test/libsolidity/semanticTests/immutable/multi_creation.sol b/test/libsolidity/semanticTests/immutable/multi_creation.sol index aa8a1ad8a860..1036b7f83a52 100644 --- a/test/libsolidity/semanticTests/immutable/multi_creation.sol +++ b/test/libsolidity/semanticTests/immutable/multi_creation.sol @@ -18,20 +18,20 @@ contract C { uint public y; constructor() { a = 3; - x = (new A()).f(); - y = (new B()).f(); + x = (new A{salt: hex"00"}()).f(); + y = (new B{salt: hex"00"}()).f(); } function f() public returns (uint256, uint, uint) { - return (a, (new A()).f(), (new B()).f()); + return (a, (new A{salt: hex"01"}()).f(), (new B{salt: hex"01"}()).f()); } } // ---- // f() -> 3, 7, 5 -// gas irOptimized: 86796 +// gas irOptimized: 86892 // gas irOptimized code: 37200 -// gas legacy: 87727 +// gas legacy: 87839 // gas legacy code: 60800 -// gas legacyOptimized: 86770 +// gas legacyOptimized: 86870 // gas legacyOptimized code: 37200 // 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 0865ed2876ad..c4d416d9a18c 100644 --- a/test/libsolidity/semanticTests/inheritance/address_overload_resolution.sol +++ b/test/libsolidity/semanticTests/inheritance/address_overload_resolution.sol @@ -11,19 +11,19 @@ contract C { contract D { function f() public returns (uint256) { - return (new C()).balance(); + return (new C{salt: hex"00"}()).balance(); } function g() public returns (uint256) { - return (new C()).transfer(5); + return (new C{salt: hex"01"}()).transfer(5); } } // ---- // f() -> 1 // gas irOptimized: 77051 -// gas legacy: 54480 +// gas legacy: 54553 // gas legacy code: 57800 // g() -> 5 // gas irOptimized: 77106 -// gas legacy: 55016 +// gas legacy: 55090 // gas legacy code: 57800 diff --git a/test/libsolidity/semanticTests/inheritance/interface_inheritance_conversions.sol b/test/libsolidity/semanticTests/inheritance/interface_inheritance_conversions.sol index 62e1e4fba6dc..2448b3e03bc2 100644 --- a/test/libsolidity/semanticTests/inheritance/interface_inheritance_conversions.sol +++ b/test/libsolidity/semanticTests/inheritance/interface_inheritance_conversions.sol @@ -10,26 +10,21 @@ interface SubB is Parent { function subBFun() external returns (uint256); } -contract Impl is SubA, SubB { +contract C is SubA, SubB { function parentFun() override external returns (uint256) { return 1; } function subAFun() override external returns (uint256) { return 2; } function subBFun() override external returns (uint256) { return 3; } -} -contract C { function convertParent() public returns (uint256) { - Parent p = new Impl(); - return p.parentFun(); + return this.parentFun(); } function convertSubA() public returns (uint256, uint256) { - SubA sa = new Impl(); - return (sa.parentFun(), sa.subAFun()); + return (this.parentFun(), this.subAFun()); } function convertSubB() public returns (uint256, uint256) { - SubB sb = new Impl(); - return (sb.parentFun(), sb.subBFun()); + return (this.parentFun(), this.subBFun()); } } // ---- diff --git a/test/libsolidity/semanticTests/inheritance/member_notation_ctor.sol b/test/libsolidity/semanticTests/inheritance/member_notation_ctor.sol index b9697c5ae1d7..517d3c148aaa 100644 --- a/test/libsolidity/semanticTests/inheritance/member_notation_ctor.sol +++ b/test/libsolidity/semanticTests/inheritance/member_notation_ctor.sol @@ -13,14 +13,14 @@ contract D is M.C { contract A { function g(int p) public returns (int) { - D d = new D(p); + D d = new D{salt: bytes32(uint256(p))}(p); return d.getX(); } } // ---- // g(int256): -1 -> -1 -// gas legacy: 77876 +// gas legacy: 77955 // gas legacy code: 24200 // g(int256): 10 -> 10 -// gas legacy: 77504 +// gas legacy: 77583 // gas legacy code: 24200 diff --git a/test/libsolidity/semanticTests/inlineAssembly/external_function_pointer_address.sol b/test/libsolidity/semanticTests/inlineAssembly/external_function_pointer_address.sol index ae891df5dc4f..dd60679ae95b 100644 --- a/test/libsolidity/semanticTests/inlineAssembly/external_function_pointer_address.sol +++ b/test/libsolidity/semanticTests/inlineAssembly/external_function_pointer_address.sol @@ -2,16 +2,16 @@ contract C { function testFunction() external {} function testYul() public returns (address adr) { - function() external fp = this.testFunction; + function() external fp = C(address(0x1234)).testFunction; assembly { adr := fp.address } } function testSol() public returns (address) { - return this.testFunction.address; + return C(address(0x1234)).testFunction.address; } } // ---- -// testYul() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e -// testSol() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e +// testYul() -> 0x1234 +// testSol() -> 0x1234 diff --git a/test/libsolidity/semanticTests/inlineAssembly/transient_storage_low_level_calls.sol b/test/libsolidity/semanticTests/inlineAssembly/transient_storage_low_level_calls.sol index e43fc475740a..d3714e7dfca5 100644 --- a/test/libsolidity/semanticTests/inlineAssembly/transient_storage_low_level_calls.sol +++ b/test/libsolidity/semanticTests/inlineAssembly/transient_storage_low_level_calls.sol @@ -27,7 +27,7 @@ contract C { function testDelegateCall() external returns (bool) { this.set(5); - D d = new D(); + D d = new D{salt: hex"00"}(); // Caller contract is the owner of the transient storage (bool success, ) = address(d).delegatecall(abi.encodeCall(d.addOne, ())); require(success); @@ -37,7 +37,7 @@ contract C { function testCall() external returns (bool) { this.set(5); - D d = new D(); + D d = new D{salt: hex"01"}(); // Callee/Target contract is the owner of the transient storage (bool success, ) = address(d).call(abi.encodeCall(d.addOne, ())); require(success); @@ -47,7 +47,7 @@ contract C { function tloadAllowedStaticCall() external returns (bool) { this.set(5); - D d = new D(); + D d = new D{salt: hex"02"}(); (bool success, bytes memory result) = address(d).staticcall(abi.encodeCall(d.get, ())); require(success); require(abi.decode(result, (uint)) == 0); @@ -55,7 +55,7 @@ contract C { } function tstoreNotAllowedStaticCall() external returns (bool) { - D d = new D(); + D d = new D{salt: hex"03"}(); (bool success, ) = address(d).staticcall(abi.encodeCall(d.addOne, ())); require(!success); return true; @@ -68,9 +68,9 @@ contract C { // testCall() -> true // tloadAllowedStaticCall() -> true // tstoreNotAllowedStaticCall() -> true -// gas irOptimized: 98419720 +// gas irOptimized: 98419721 // gas irOptimized code: 19000 -// gas legacy: 98409086 +// gas legacy: 98409087 // gas legacy code: 30000 // gas legacyOptimized: 98420962 // gas legacyOptimized code: 17800 diff --git a/test/libsolidity/semanticTests/isoltestTesting/balance_other_contract.sol b/test/libsolidity/semanticTests/isoltestTesting/balance_other_contract.sol index 1240a8251427..92d358294a1d 100644 --- a/test/libsolidity/semanticTests/isoltestTesting/balance_other_contract.sol +++ b/test/libsolidity/semanticTests/isoltestTesting/balance_other_contract.sol @@ -1,30 +1,9 @@ -contract Other { +contract C { constructor() payable { - } - function getAddress() public returns (address) { - return address(this); - } -} -contract ClientReceipt { - Other other; - constructor() payable { - other = new Other{value:500}(); - } - function getAddress() public returns (address) { - return other.getAddress(); + payable(address(0x1234)).transfer(500); } } // ---- // constructor(), 2000 wei -> -// gas irOptimized: 114353 -// gas irOptimized code: 58800 -// gas legacy: 118617 -// gas legacy code: 111400 -// gas legacyOptimized: 114067 -// gas legacyOptimized code: 59800 // balance -> 1500 -// gas irOptimized: 191881 -// gas legacy: 235167 -// gas legacyOptimized: 180756 -// getAddress() -> 0x137aa4dfc0911524504fcd4d98501f179bc13b4a -// balance: 0x137aa4dfc0911524504fcd4d98501f179bc13b4a -> 500 +// balance: 0x0000000000000000000000000000000000001234 -> 500 diff --git a/test/libsolidity/semanticTests/operators/userDefined/operator_making_pure_external_call.sol b/test/libsolidity/semanticTests/operators/userDefined/operator_making_pure_external_call.sol index ec41099eecbb..56b1159c202c 100644 --- a/test/libsolidity/semanticTests/operators/userDefined/operator_making_pure_external_call.sol +++ b/test/libsolidity/semanticTests/operators/userDefined/operator_making_pure_external_call.sol @@ -39,13 +39,13 @@ function loadAdder() pure returns (IAdder adder) { contract C { function testMul(Int32 x, Int32 y) public returns (Int32) { - storeAdder(new Adder()); + storeAdder(new Adder{salt: hex"00"}()); return x + y; } function testInc(Int32 x) public returns (Int32) { - storeAdder(new Adder()); + storeAdder(new Adder{salt: hex"01"}()); return -x; } @@ -53,13 +53,13 @@ contract C { // ---- // testMul(int32,int32): 42, 10 -> 420 // gas irOptimized: 102563 -// gas legacy: 56978 +// gas legacy: 57117 // gas legacy code: 127000 -// gas legacyOptimized: 55161 +// gas legacyOptimized: 55246 // gas legacyOptimized code: 68400 // testInc(int32): 42 -> 43 // gas irOptimized: 102386 -// gas legacy: 56238 +// gas legacy: 56378 // gas legacy code: 127000 -// gas legacyOptimized: 54851 +// gas legacyOptimized: 54943 // gas legacyOptimized code: 68400 diff --git a/test/libsolidity/semanticTests/operators/userDefined/operator_making_view_external_call.sol b/test/libsolidity/semanticTests/operators/userDefined/operator_making_view_external_call.sol index 7e70eb091bf6..106605c063f0 100644 --- a/test/libsolidity/semanticTests/operators/userDefined/operator_making_view_external_call.sol +++ b/test/libsolidity/semanticTests/operators/userDefined/operator_making_view_external_call.sol @@ -45,13 +45,13 @@ function loadAdder() pure returns (IAdderPure adder) { contract C { function testMul(Int32 x, Int32 y) public returns (Int32) { - storeAdder(new Adder()); + storeAdder(new Adder{salt: hex"00"}()); return x + y; } function testInc(Int32 x) public returns (Int32) { - storeAdder(new Adder()); + storeAdder(new Adder{salt: hex"01"}()); return -x; } @@ -59,13 +59,13 @@ contract C { // ---- // testMul(int32,int32): 42, 10 -> 420 // gas irOptimized: 102563 -// gas legacy: 56978 +// gas legacy: 57117 // gas legacy code: 127000 -// gas legacyOptimized: 55161 +// gas legacyOptimized: 55246 // gas legacyOptimized code: 68400 // testInc(int32): 42 -> 43 // gas irOptimized: 102386 -// gas legacy: 56238 +// gas legacy: 56378 // gas legacy code: 127000 -// gas legacyOptimized: 54851 +// gas legacyOptimized: 54943 // gas legacyOptimized code: 68400 diff --git a/test/libsolidity/semanticTests/tryCatch/assert.sol b/test/libsolidity/semanticTests/tryCatch/assert.sol index 8b6a7b99692e..335ef26bfba6 100644 --- a/test/libsolidity/semanticTests/tryCatch/assert.sol +++ b/test/libsolidity/semanticTests/tryCatch/assert.sol @@ -3,14 +3,15 @@ contract C { assert(x); } function f(bool x) public returns (uint) { - // Set the gas to make this work on pre-byzantium VMs - try this.g{gas: 8000}(x) { + try this.g(x) { return 1; } catch { return 2; } } } +// ==== +// EVMVersion: >=byzantium // ---- // f(bool): true -> 1 // f(bool): false -> 2 diff --git a/test/libsolidity/semanticTests/tryCatch/assert_pre_byzantium.sol b/test/libsolidity/semanticTests/tryCatch/assert_pre_byzantium.sol new file mode 100644 index 000000000000..a683f531fc0e --- /dev/null +++ b/test/libsolidity/semanticTests/tryCatch/assert_pre_byzantium.sol @@ -0,0 +1,18 @@ +contract C { + function g(bool x) public pure { + assert(x); + } + function f(bool x) public returns (uint) { + // Set the gas to make this work on pre-byzantium VMs + try this.g{gas: 8000}(x) { + return 1; + } catch { + return 2; + } + } +} +// ==== +// EVMVersion: 1 +// f(bool): false -> 2 diff --git a/test/libsolidity/semanticTests/tryCatch/create.sol b/test/libsolidity/semanticTests/tryCatch/create.sol index 43d0f22f6506..4ad40d531872 100644 --- a/test/libsolidity/semanticTests/tryCatch/create.sol +++ b/test/libsolidity/semanticTests/tryCatch/create.sol @@ -6,19 +6,19 @@ contract Succeeds { } contract C { - function f() public returns (Reverts x, uint, string memory txt) { + function f() public returns (bool created, string memory txt) { uint i = 3; try new Reverts(i) returns (Reverts r) { - x = r; + created = (address(r) != address(0)); txt = "success"; } catch Error(string memory s) { txt = s; } } - function g() public returns (Succeeds x, uint, string memory txt) { + function g() public returns (bool created, string memory txt) { uint i = 8; try new Succeeds(i) returns (Succeeds r) { - x = r; + created = (address(r) != address(0)); txt = "success"; } catch Error(string memory s) { txt = s; @@ -28,5 +28,5 @@ contract C { // ==== // EVMVersion: >=byzantium // ---- -// f() -> 0, 0, 96, 13, "test message." -// g() -> 0x137aa4dfc0911524504fcd4d98501f179bc13b4a, 0, 96, 7, "success" +// f() -> false, 0x40, 13, "test message." +// g() -> true, 0x40, 7, "success" diff --git a/test/libsolidity/semanticTests/tryCatch/super_trivial.sol b/test/libsolidity/semanticTests/tryCatch/require.sol similarity index 87% rename from test/libsolidity/semanticTests/tryCatch/super_trivial.sol rename to test/libsolidity/semanticTests/tryCatch/require.sol index 98fbcddb21b5..730243208e55 100644 --- a/test/libsolidity/semanticTests/tryCatch/super_trivial.sol +++ b/test/libsolidity/semanticTests/tryCatch/require.sol @@ -1,5 +1,5 @@ contract C { - function g(bool x) external pure { + function g(bool x) public pure { require(x); } function f(bool x) public returns (uint) { diff --git a/test/libsolidity/semanticTests/tryCatch/trivial.sol b/test/libsolidity/semanticTests/tryCatch/require_pre_byzantium.sol similarity index 91% rename from test/libsolidity/semanticTests/tryCatch/trivial.sol rename to test/libsolidity/semanticTests/tryCatch/require_pre_byzantium.sol index d43477e994ab..eb9251ec7048 100644 --- a/test/libsolidity/semanticTests/tryCatch/trivial.sol +++ b/test/libsolidity/semanticTests/tryCatch/require_pre_byzantium.sol @@ -11,6 +11,8 @@ contract C { } } } +// ==== +// EVMVersion: 1 // f(bool): false -> 2 diff --git a/test/libsolidity/semanticTests/tryCatch/return_function.sol b/test/libsolidity/semanticTests/tryCatch/return_function.sol index 6aac30fe4617..396633655e10 100644 --- a/test/libsolidity/semanticTests/tryCatch/return_function.sol +++ b/test/libsolidity/semanticTests/tryCatch/return_function.sol @@ -1,7 +1,7 @@ contract C { function g() public returns (uint a, function() external h, uint b) { a = 1; - h = this.fun; + h = C(address(0x1234)).fun; b = 9; } function f() public returns (uint, function() external, uint) { @@ -14,4 +14,4 @@ contract C { function fun() public pure {} } // ---- -// f() -> 0x1, 0xc06afe3a8444fc0004668591e8306bfb9968e79e946644cd0000000000000000, 9 +// f() -> 0x1, 0x1234946644cd0000000000000000, 9 diff --git a/test/libsolidity/semanticTests/various/many_subassemblies.sol b/test/libsolidity/semanticTests/various/many_subassemblies.sol index b270c7006694..b448d0101fac 100644 --- a/test/libsolidity/semanticTests/various/many_subassemblies.sol +++ b/test/libsolidity/semanticTests/various/many_subassemblies.sol @@ -15,24 +15,24 @@ contract D { // This is primarily meant to test assembly import via --import-asm-json. // The exported JSON will fail the reimport unless the subassembly indices are parsed // correctly - as hex numbers. - new C0(); - new C1(); - new C2(); - new C3(); - new C4(); - new C5(); - new C6(); - new C7(); - new C8(); - new C9(); - new C10(); + new C0{salt: hex"00"}(); + new C1{salt: hex"01"}(); + new C2{salt: hex"02"}(); + new C3{salt: hex"03"}(); + new C4{salt: hex"04"}(); + new C5{salt: hex"05"}(); + new C6{salt: hex"06"}(); + new C7{salt: hex"07"}(); + new C8{salt: hex"08"}(); + new C9{salt: hex"09"}(); + new C10{salt: hex"0a"}(); } } // ---- // run() -> -// gas irOptimized: 374934 +// gas irOptimized: 375192 // gas irOptimized code: 6600 -// gas legacy: 375119 +// gas legacy: 375404 // gas legacy code: 17600 -// gas legacyOptimized: 375119 +// gas legacyOptimized: 375464 // gas legacyOptimized code: 17600 diff --git a/test/libsolidity/semanticTests/viaYul/conversion/function_cast.sol b/test/libsolidity/semanticTests/viaYul/conversion/function_cast.sol index 843376baa553..7aaaa648f659 100644 --- a/test/libsolidity/semanticTests/viaYul/conversion/function_cast.sol +++ b/test/libsolidity/semanticTests/viaYul/conversion/function_cast.sol @@ -9,13 +9,14 @@ contract C { return this.g()(x) + 1; } function t() external view returns ( - function(uint) external returns (uint) a, - function(uint) external view returns (uint) b) { - a = this.f; - b = this.f; + function(uint) external returns (uint) a, + function(uint) external view returns (uint) b + ) { + a = C(address(0x1234)).f; + b = C(address(0x1234)).f; } } // ---- // f(uint256): 2 -> 4 // h(uint256): 2 -> 5 -// t() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79eb3de648b0000000000000000, 0xc06afe3a8444fc0004668591e8306bfb9968e79eb3de648b0000000000000000 +// t() -> 0x1234b3de648b0000000000000000, 0x1234b3de648b0000000000000000 diff --git a/test/libsolidity/semanticTests/viaYul/function_address.sol b/test/libsolidity/semanticTests/viaYul/function_address.sol index 0c1c58dd821d..a781db753e30 100644 --- a/test/libsolidity/semanticTests/viaYul/function_address.sol +++ b/test/libsolidity/semanticTests/viaYul/function_address.sol @@ -1,15 +1,18 @@ contract C { function f() external returns (address) { - return this.f.address; + return C(address(0x1234)).f.address; } - function g() external returns (bool) { - return this.f.address == address(this); + function g() external returns (bool, bool) { + return ( + this.f.address == address(this), + C(address(0x1234)).f.address == address(0x1234) + ); } function h(function() external a) public returns (address) { - return a.address; + return a.address; } } // ---- -// f() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e -// g() -> true +// f() -> 0x1234 +// g() -> true, true // h(function): left(0x1122334400112233445566778899AABBCCDDEEFF42424242) -> 0x1122334400112233445566778899AABBCCDDEEFF From f580dfbc38b7a8bcd0a50ebb106cb343e28746e0 Mon Sep 17 00:00:00 2001 From: rodiazet Date: Wed, 29 Jan 2025 22:44:32 +0100 Subject: [PATCH 0750/1022] eof: Add test which checks that setting an EOF version results in the experimental flag being set. --- test/libsolidity/Metadata.cpp | 42 +++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/test/libsolidity/Metadata.cpp b/test/libsolidity/Metadata.cpp index ed490b9a839b..e6cdef036819 100644 --- a/test/libsolidity/Metadata.cpp +++ b/test/libsolidity/Metadata.cpp @@ -225,6 +225,48 @@ BOOST_AUTO_TEST_CASE(metadata_stamp_experimental) } } +BOOST_AUTO_TEST_CASE(metadata_eof_experimental) +{ + // Check that setting an EOF version results in the experimental flag being set. + char const* sourceCode = R"( + pragma solidity >=0.0; + contract test { + function g(function(uint) external returns (uint) x) public {} + } + )"; + for (auto metadataFormat: std::set{ + CompilerStack::MetadataFormat::NoMetadata, + CompilerStack::MetadataFormat::WithReleaseVersionTag, + CompilerStack::MetadataFormat::WithPrereleaseVersionTag + }) + { + CompilerStack compilerStack; + compilerStack.setMetadataFormat(metadataFormat); + compilerStack.setSources({{"", sourceCode}}); + compilerStack.setEVMVersion(solidity::test::CommonOptions::get().evmVersion()); + compilerStack.setViaIR(true); + compilerStack.setEOFVersion(solidity::test::CommonOptions::get().eofVersion()); + compilerStack.setOptimiserSettings(solidity::test::CommonOptions::get().optimize); + BOOST_REQUIRE_MESSAGE(compilerStack.compile(), "Compiling contract failed"); + bytes const& bytecode = compilerStack.runtimeObject("test").bytecode; + std::string const& metadata = compilerStack.metadata("test"); + BOOST_CHECK(solidity::test::isValidMetadata(metadata)); + + auto const cborMetadata = requireParsedCBORMetadata(bytecode, metadataFormat); + + if ( + metadataFormat == CompilerStack::MetadataFormat::NoMetadata || + !solidity::test::CommonOptions::get().eofVersion().has_value() + ) + BOOST_CHECK(cborMetadata.count("experimental") == 0); + else + { + BOOST_CHECK(cborMetadata.count("experimental") == 1); + BOOST_CHECK(cborMetadata.at("experimental") == "true"); + } + } +} + BOOST_AUTO_TEST_CASE(metadata_relevant_sources) { CompilerStack compilerStack; From 509cd4770270ec0a1e056b440a33d131fb88fa9a Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Thu, 30 Jan 2025 09:34:41 +0100 Subject: [PATCH 0751/1022] Use clang in alpine docker container --- scripts/Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/Dockerfile b/scripts/Dockerfile index 3a1c6a5a7cf9..6df9337ec862 100644 --- a/scripts/Dockerfile +++ b/scripts/Dockerfile @@ -6,7 +6,7 @@ MAINTAINER chriseth WORKDIR /solidity # Build dependencies -RUN apk update && apk add boost-dev boost-static build-base cmake git +RUN apk update && apk add boost-dev boost-static build-base cmake git clang #Copy working directory on travis to the image COPY / $WORKDIR @@ -17,7 +17,7 @@ ARG BUILD_CONCURRENCY="0" #Install dependencies, eliminate annoying warnings RUN sed -i -E -e 's/include /include /' /usr/include/boost/asio/detail/socket_types.hpp -RUN cmake -DCMAKE_BUILD_TYPE=Release -DTESTS=0 -DSOLC_LINK_STATIC=1 +RUN cmake -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_BUILD_TYPE=Release -DTESTS=0 -DSOLC_LINK_STATIC=1 RUN make solc \ -j$(awk "BEGIN { \ if (${BUILD_CONCURRENCY} != 0) { \ From a669f791834252fe2231f8f6b43ec389b9bae5e1 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Thu, 30 Jan 2025 09:40:14 +0100 Subject: [PATCH 0752/1022] Use two jobs for b_ubu_asan compilation --- .circleci/config.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index 8e1e85794210..0c4e65954f5f 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1040,6 +1040,8 @@ jobs: # See: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105562#c27 CMAKE_OPTIONS: -DSANITIZE=address -DPEDANTIC=OFF CMAKE_BUILD_TYPE: Release + # Set the number of jobs to two instead of the default three, so that we do not run out of memory + MAKEFLAGS: -j 2 steps: - build From 46cbf39b8cd76ef613040f0542a3dec93e922047 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Thu, 30 Jan 2025 12:13:24 +0100 Subject: [PATCH 0753/1022] Restrict tests using salted instantiation to >=constantinople --- .../semanticTests/constructor/no_callvalue_check.sol | 2 ++ test/libsolidity/semanticTests/functionCall/failed_create.sol | 2 +- test/libsolidity/semanticTests/immutable/multi_creation.sol | 2 ++ .../semanticTests/inheritance/address_overload_resolution.sol | 2 ++ .../semanticTests/inheritance/member_notation_ctor.sol | 2 ++ .../userDefined/operator_making_pure_external_call.sol | 2 ++ .../userDefined/operator_making_view_external_call.sol | 2 ++ test/libsolidity/semanticTests/various/many_subassemblies.sol | 2 ++ 8 files changed, 15 insertions(+), 1 deletion(-) diff --git a/test/libsolidity/semanticTests/constructor/no_callvalue_check.sol b/test/libsolidity/semanticTests/constructor/no_callvalue_check.sol index f21d473413f1..a46b6a6a8e8d 100644 --- a/test/libsolidity/semanticTests/constructor/no_callvalue_check.sol +++ b/test/libsolidity/semanticTests/constructor/no_callvalue_check.sol @@ -15,6 +15,8 @@ contract C { return true; } } +// ==== +// EVMVersion: >=constantinople // ---- // f(), 2000 ether -> true // gas irOptimized: 117688 diff --git a/test/libsolidity/semanticTests/functionCall/failed_create.sol b/test/libsolidity/semanticTests/functionCall/failed_create.sol index bb6289768445..87bd12d58b75 100644 --- a/test/libsolidity/semanticTests/functionCall/failed_create.sol +++ b/test/libsolidity/semanticTests/functionCall/failed_create.sol @@ -14,7 +14,7 @@ contract C { } } // ==== -// EVMVersion: >=byzantium +// EVMVersion: >=constantinople // ---- // constructor(), 20 wei // gas irOptimized: 59688 diff --git a/test/libsolidity/semanticTests/immutable/multi_creation.sol b/test/libsolidity/semanticTests/immutable/multi_creation.sol index 1036b7f83a52..515dd41bb1b1 100644 --- a/test/libsolidity/semanticTests/immutable/multi_creation.sol +++ b/test/libsolidity/semanticTests/immutable/multi_creation.sol @@ -25,6 +25,8 @@ contract C { return (a, (new A{salt: hex"01"}()).f(), (new B{salt: hex"01"}()).f()); } } +// ==== +// EVMVersion: >=constantinople // ---- // f() -> 3, 7, 5 // gas irOptimized: 86892 diff --git a/test/libsolidity/semanticTests/inheritance/address_overload_resolution.sol b/test/libsolidity/semanticTests/inheritance/address_overload_resolution.sol index c4d416d9a18c..90a3f9ec8c1f 100644 --- a/test/libsolidity/semanticTests/inheritance/address_overload_resolution.sol +++ b/test/libsolidity/semanticTests/inheritance/address_overload_resolution.sol @@ -18,6 +18,8 @@ contract D { return (new C{salt: hex"01"}()).transfer(5); } } +// ==== +// EVMVersion: >=constantinople // ---- // f() -> 1 // gas irOptimized: 77051 diff --git a/test/libsolidity/semanticTests/inheritance/member_notation_ctor.sol b/test/libsolidity/semanticTests/inheritance/member_notation_ctor.sol index 517d3c148aaa..cbedca48c8c4 100644 --- a/test/libsolidity/semanticTests/inheritance/member_notation_ctor.sol +++ b/test/libsolidity/semanticTests/inheritance/member_notation_ctor.sol @@ -17,6 +17,8 @@ contract A { return d.getX(); } } +// ==== +// EVMVersion: >=constantinople // ---- // g(int256): -1 -> -1 // gas legacy: 77955 diff --git a/test/libsolidity/semanticTests/operators/userDefined/operator_making_pure_external_call.sol b/test/libsolidity/semanticTests/operators/userDefined/operator_making_pure_external_call.sol index 56b1159c202c..364e589e55c1 100644 --- a/test/libsolidity/semanticTests/operators/userDefined/operator_making_pure_external_call.sol +++ b/test/libsolidity/semanticTests/operators/userDefined/operator_making_pure_external_call.sol @@ -50,6 +50,8 @@ contract C { return -x; } } +// ==== +// EVMVersion: >=constantinople // ---- // testMul(int32,int32): 42, 10 -> 420 // gas irOptimized: 102563 diff --git a/test/libsolidity/semanticTests/operators/userDefined/operator_making_view_external_call.sol b/test/libsolidity/semanticTests/operators/userDefined/operator_making_view_external_call.sol index 106605c063f0..54048113c323 100644 --- a/test/libsolidity/semanticTests/operators/userDefined/operator_making_view_external_call.sol +++ b/test/libsolidity/semanticTests/operators/userDefined/operator_making_view_external_call.sol @@ -56,6 +56,8 @@ contract C { return -x; } } +// ==== +// EVMVersion: >=constantinople // ---- // testMul(int32,int32): 42, 10 -> 420 // gas irOptimized: 102563 diff --git a/test/libsolidity/semanticTests/various/many_subassemblies.sol b/test/libsolidity/semanticTests/various/many_subassemblies.sol index b448d0101fac..a320a2aa3eca 100644 --- a/test/libsolidity/semanticTests/various/many_subassemblies.sol +++ b/test/libsolidity/semanticTests/various/many_subassemblies.sol @@ -28,6 +28,8 @@ contract D { new C10{salt: hex"0a"}(); } } +// ==== +// EVMVersion: >=constantinople // ---- // run() -> // gas irOptimized: 375192 From eb7d79496539fa26ab6586972c538c289ef4c78c Mon Sep 17 00:00:00 2001 From: rodiazet Date: Thu, 12 Dec 2024 12:19:33 +0100 Subject: [PATCH 0754/1022] eof: Enable yul in `SyntaxTest` by default when compiling to EOF --- test/libsolidity/SyntaxTest.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/libsolidity/SyntaxTest.cpp b/test/libsolidity/SyntaxTest.cpp index 41c1d0568be6..4fd3df7cfc6f 100644 --- a/test/libsolidity/SyntaxTest.cpp +++ b/test/libsolidity/SyntaxTest.cpp @@ -48,7 +48,9 @@ SyntaxTest::SyntaxTest( { static std::set const compileViaYulAllowedValues{"true", "false"}; - m_compileViaYul = m_reader.stringSetting("compileViaYul", "false"); + auto const eofEnabled = solidity::test::CommonOptions::get().eofVersion().has_value(); + + m_compileViaYul = m_reader.stringSetting("compileViaYul", eofEnabled ? "true" : "false"); if (!util::contains(compileViaYulAllowedValues, m_compileViaYul)) BOOST_THROW_EXCEPTION(std::runtime_error("Invalid compileViaYul value: " + m_compileViaYul + ".")); m_optimiseYul = m_reader.boolSetting("optimize-yul", true); From 3e8008ec50f7046a7d9221c8cd59c0a7fc0344dc Mon Sep 17 00:00:00 2001 From: rodiazet Date: Mon, 27 Jan 2025 17:58:49 +0100 Subject: [PATCH 0755/1022] eof: Update syntax tests. --- .../array/nested_calldata_storage.sol | 13 +++ .../array/nested_calldata_storage2.sol | 13 +++ ...sing_public_state_variable_via_v1_type.sol | 2 + ...rary_function_accepting_storage_struct.sol | 2 + ...rary_function_accepting_storage_struct.sol | 2 + .../abiEncoder/v1_call_to_v2_modifier.sol | 2 + .../v1_constructor_with_v2_modifier.sol | 2 + ...ance_from_contract_calling_v2_function.sol | 2 + ...itance_from_contract_defining_v2_event.sol | 2 + ...itance_from_contract_emitting_v2_event.sol | 2 + .../v1_modifier_overriding_v2_modifier.sol | 2 + .../abiEncoder/v1_v2_v1_modifier_mix.sol | 2 + .../array/nested_calldata_storage.sol | 2 + .../array/nested_calldata_storage2.sol | 2 + .../bytecodeReferences/library_non_called.sol | 2 + .../constants/mod_div_rational.sol | 4 +- .../constructor/nonabiv2_type_abstract.sol | 2 + .../builtin/builtin_type_definition.sol | 1 + .../import_and_call_stdlib_function.sol | 1 + .../functionCalls/calloptions_duplicated.sol | 2 + .../calloptions_on_delegatecall.sol | 2 + .../calloptions_on_staticcall.sol | 1 + .../functionCalls/calloptions_repeated.sol | 1 + .../eof/calloptions_on_delegatecall.sol | 11 +++ .../eof/calloptions_on_staticcall.sol | 12 +++ .../eof/lowlevel_call_options.sol | 9 ++ .../functionCalls/lowlevel_call_options.sol | 2 + .../functionTypes/call_gas_on_function.sol | 3 +- ...r_external_functions_with_call_options.sol | 12 +++ ...xternal_functions_with_extra_gas_slots.sol | 12 --- .../eof/call_gas_on_function.sol | 10 +++ ...ns_with_variable_number_of_stack_slots.sol | 7 +- .../syntaxTests/immutable/creationCode.sol | 2 + .../syntaxTests/immutable/no_assignments.sol | 4 +- .../inlineArrays/inline_array_fixed_types.sol | 4 +- .../inlineArrays/inline_array_rationals.sol | 4 +- .../assignment_from_library.sol | 2 + .../create2_as_variable_post_istanbul.sol | 1 + .../inlineAssembly/evm_byzantium.sol | 1 + .../inlineAssembly/evm_constantinople.sol | 1 + ...dehash_as_variable_post_constantinople.sol | 1 + .../inlineAssembly/hex_switch_case.sol | 3 +- .../inlineAssembly/invalid/pc_disallowed.sol | 2 + .../string_literal_switch_case.sol | 3 +- .../use_msize_without_optimizer.sol | 1 + .../syntaxTests/metaTypes/codeAccess.sol | 2 + .../metaTypes/codeAccessAbstractCreation.sol | 2 + .../metaTypes/codeAccessAbstractRuntime.sol | 2 + .../syntaxTests/metaTypes/codeAccessBase.sol | 2 + .../metaTypes/codeAccessCyclic.sol | 2 + .../metaTypes/codeAccessIsConstant.sol | 2 + .../metaTypes/codeAccessLibrary.sol | 2 + .../metaTypes/codeAccess_super.sol | 2 + .../syntaxTests/metaTypes/codeIsNoLValue.sol | 2 + .../metaTypes/runtimeCodeWarningAssembly.sol | 2 + .../metaTypes/type_runtimecode.sol | 2 + ...e_runtimecode_from_ternary_expression_.sol | 2 + .../303_fixed_type_int_conversion.sol | 4 +- ...304_fixed_type_rational_int_conversion.sol | 4 +- ...ixed_type_rational_fraction_conversion.sol | 4 +- .../307_rational_unary_minus_operation.sol | 4 +- .../312_leading_zero_rationals_convert.sol | 4 +- .../314_fixed_type_zero_handling.sol | 4 +- ..._fixed_type_valid_explicit_conversions.sol | 4 +- .../323_mapping_with_fixed_literal.sol | 4 +- .../324_fixed_points_inside_structs.sol | 4 +- ...8_rational_to_fixed_literal_expression.sol | 4 +- .../343_integer_and_fixed_interaction.sol | 4 +- .../nameAndTypeResolution/497_gasleft.sol | 2 + .../lexer_numbers_with_underscores_fixed.sol | 4 +- .../sizeLimits/bytecode_too_large.sol | 1 + .../bytecode_too_large_abiencoder_v1.sol | 1 + .../functionCallOptions_err.sol | 2 + ...nspecified_encoding_internal_functions.sol | 12 +-- .../types/address/address_members.sol | 2 + .../address/address_payable_selfdestruct.sol | 2 + .../syntaxTests/types/address/codehash.sol | 1 + .../types/address/eof/address_members.sol | 9 ++ ...ional_number_literal_to_fixed_implicit.sol | 4 +- .../address_constantinople.sol | 1 + .../syntaxTests/viewPureChecker/assembly.sol | 2 + .../assembly_constantinople.sol | 1 + .../viewPureChecker/builtin_functions.sol | 2 + .../call_options_without_call.sol | 9 ++ .../viewPureChecker/eof/assembly.sol | 29 +++++++ .../viewPureChecker/eof/builtin_functions.sol | 22 +++++ .../inline_assembly_instructions_allowed.sol | 86 +++++++++++++++++++ ...ine_assembly_instructions_allowed_pure.sol | 85 ++++++++++++++++++ ...ine_assembly_instructions_allowed_view.sol | 85 ++++++++++++++++++ ...nline_assembly_instructions_disallowed.sol | 28 ++++++ ..._assembly_instructions_disallowed_pure.sol | 71 +++++++++++++++ ..._assembly_instructions_disallowed_view.sol | 28 ++++++ .../gas_value_without_call.sol | 2 + .../gas_with_call_nonpayable.sol | 2 + .../inline_assembly_instructions_allowed.sol | 1 + ...ine_assembly_instructions_allowed_pure.sol | 1 + ...ine_assembly_instructions_allowed_view.sol | 1 + ...nline_assembly_instructions_disallowed.sol | 2 + ..._assembly_instructions_disallowed_pure.sol | 2 + ...instructions_disallowed_pure_byzantium.sol | 1 + ...uctions_disallowed_pure_constantinople.sol | 1 + ..._assembly_instructions_disallowed_view.sol | 1 + .../viewPureChecker/staticcall_gas_view.sol | 1 + 103 files changed, 701 insertions(+), 44 deletions(-) create mode 100644 test/libsolidity/semanticTests/array/nested_calldata_storage.sol create mode 100644 test/libsolidity/semanticTests/array/nested_calldata_storage2.sol create mode 100644 test/libsolidity/syntaxTests/functionCalls/eof/calloptions_on_delegatecall.sol create mode 100644 test/libsolidity/syntaxTests/functionCalls/eof/calloptions_on_staticcall.sol create mode 100644 test/libsolidity/syntaxTests/functionCalls/eof/lowlevel_call_options.sol create mode 100644 test/libsolidity/syntaxTests/functionTypes/comparison_operator_for_external_functions_with_call_options.sol delete mode 100644 test/libsolidity/syntaxTests/functionTypes/comparison_operator_for_external_functions_with_extra_gas_slots.sol create mode 100644 test/libsolidity/syntaxTests/functionTypes/eof/call_gas_on_function.sol create mode 100644 test/libsolidity/syntaxTests/types/address/eof/address_members.sol create mode 100644 test/libsolidity/syntaxTests/viewPureChecker/call_options_without_call.sol create mode 100644 test/libsolidity/syntaxTests/viewPureChecker/eof/assembly.sol create mode 100644 test/libsolidity/syntaxTests/viewPureChecker/eof/builtin_functions.sol create mode 100644 test/libsolidity/syntaxTests/viewPureChecker/eof/inline_assembly_instructions_allowed.sol create mode 100644 test/libsolidity/syntaxTests/viewPureChecker/eof/inline_assembly_instructions_allowed_pure.sol create mode 100644 test/libsolidity/syntaxTests/viewPureChecker/eof/inline_assembly_instructions_allowed_view.sol create mode 100644 test/libsolidity/syntaxTests/viewPureChecker/eof/inline_assembly_instructions_disallowed.sol create mode 100644 test/libsolidity/syntaxTests/viewPureChecker/eof/inline_assembly_instructions_disallowed_pure.sol create mode 100644 test/libsolidity/syntaxTests/viewPureChecker/eof/inline_assembly_instructions_disallowed_view.sol diff --git a/test/libsolidity/semanticTests/array/nested_calldata_storage.sol b/test/libsolidity/semanticTests/array/nested_calldata_storage.sol new file mode 100644 index 000000000000..7cc9753bec8f --- /dev/null +++ b/test/libsolidity/semanticTests/array/nested_calldata_storage.sol @@ -0,0 +1,13 @@ +pragma abicoder v2; + +contract C { + uint[][2] public tmp_i; + function i(uint[][2] calldata s) external { tmp_i = s; } +} +// ==== +// compileViaYul: true +// ---- +// i(uint256[][2]): 0x20, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 +// gas irOptimized: 223100 +// tmp_i(uint256,uint256): 0, 0 -> 0x0A01 +// tmp_i(uint256,uint256): 1, 0 -> 0x0B01 diff --git a/test/libsolidity/semanticTests/array/nested_calldata_storage2.sol b/test/libsolidity/semanticTests/array/nested_calldata_storage2.sol new file mode 100644 index 000000000000..f8db31b54cc8 --- /dev/null +++ b/test/libsolidity/semanticTests/array/nested_calldata_storage2.sol @@ -0,0 +1,13 @@ +pragma abicoder v2; + +contract C { + uint[][] public tmp_i; + function i(uint[][] calldata s) external { tmp_i = s; } +} +// ==== +// compileViaYul: true +// ---- +// i(uint256[][]): 0x20, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 +// gas irOptimized: 245506 +// tmp_i(uint256,uint256): 0, 0 -> 0x0A01 +// tmp_i(uint256,uint256): 1, 0 -> 0x0B01 diff --git a/test/libsolidity/syntaxTests/abiEncoder/v1_accessing_public_state_variable_via_v1_type.sol b/test/libsolidity/syntaxTests/abiEncoder/v1_accessing_public_state_variable_via_v1_type.sol index f324d2c33e30..036a2597616c 100644 --- a/test/libsolidity/syntaxTests/abiEncoder/v1_accessing_public_state_variable_via_v1_type.sol +++ b/test/libsolidity/syntaxTests/abiEncoder/v1_accessing_public_state_variable_via_v1_type.sol @@ -13,4 +13,6 @@ contract D { return a + b; } } +// ==== +// bytecodeFormat: legacy // ---- diff --git a/test/libsolidity/syntaxTests/abiEncoder/v1_call_to_v1_library_function_accepting_storage_struct.sol b/test/libsolidity/syntaxTests/abiEncoder/v1_call_to_v1_library_function_accepting_storage_struct.sol index b21b7cfaff5e..03fb9bae673b 100644 --- a/test/libsolidity/syntaxTests/abiEncoder/v1_call_to_v1_library_function_accepting_storage_struct.sol +++ b/test/libsolidity/syntaxTests/abiEncoder/v1_call_to_v1_library_function_accepting_storage_struct.sol @@ -19,4 +19,6 @@ contract Test { L.set(item); } } +// ==== +// bytecodeFormat: legacy // ---- diff --git a/test/libsolidity/syntaxTests/abiEncoder/v1_call_to_v2_library_function_accepting_storage_struct.sol b/test/libsolidity/syntaxTests/abiEncoder/v1_call_to_v2_library_function_accepting_storage_struct.sol index 41bc072a5949..01d9658ce2cf 100644 --- a/test/libsolidity/syntaxTests/abiEncoder/v1_call_to_v2_library_function_accepting_storage_struct.sol +++ b/test/libsolidity/syntaxTests/abiEncoder/v1_call_to_v2_library_function_accepting_storage_struct.sol @@ -19,4 +19,6 @@ contract Test { L.get(item); } } +// ==== +// bytecodeFormat: legacy // ---- diff --git a/test/libsolidity/syntaxTests/abiEncoder/v1_call_to_v2_modifier.sol b/test/libsolidity/syntaxTests/abiEncoder/v1_call_to_v2_modifier.sol index 78d7b0512414..ef066593c4bc 100644 --- a/test/libsolidity/syntaxTests/abiEncoder/v1_call_to_v2_modifier.sol +++ b/test/libsolidity/syntaxTests/abiEncoder/v1_call_to_v2_modifier.sol @@ -25,4 +25,6 @@ contract C is B { validate() {} } +// ==== +// bytecodeFormat: legacy // ---- diff --git a/test/libsolidity/syntaxTests/abiEncoder/v1_constructor_with_v2_modifier.sol b/test/libsolidity/syntaxTests/abiEncoder/v1_constructor_with_v2_modifier.sol index 1ac5d713b104..b937d1e2d1a2 100644 --- a/test/libsolidity/syntaxTests/abiEncoder/v1_constructor_with_v2_modifier.sol +++ b/test/libsolidity/syntaxTests/abiEncoder/v1_constructor_with_v2_modifier.sol @@ -32,4 +32,6 @@ import "B"; contract D is C { constructor() validate B() validate C() validate {} } +// ==== +// bytecodeFormat: legacy // ---- diff --git a/test/libsolidity/syntaxTests/abiEncoder/v1_inheritance_from_contract_calling_v2_function.sol b/test/libsolidity/syntaxTests/abiEncoder/v1_inheritance_from_contract_calling_v2_function.sol index 073a125be984..9743d5318ca0 100644 --- a/test/libsolidity/syntaxTests/abiEncoder/v1_inheritance_from_contract_calling_v2_function.sol +++ b/test/libsolidity/syntaxTests/abiEncoder/v1_inheritance_from_contract_calling_v2_function.sol @@ -23,4 +23,6 @@ pragma abicoder v1; import "A"; contract C is B {} +// ==== +// bytecodeFormat: legacy // ---- diff --git a/test/libsolidity/syntaxTests/abiEncoder/v1_inheritance_from_contract_defining_v2_event.sol b/test/libsolidity/syntaxTests/abiEncoder/v1_inheritance_from_contract_defining_v2_event.sol index 963ed33c70e6..e4492a4ef742 100644 --- a/test/libsolidity/syntaxTests/abiEncoder/v1_inheritance_from_contract_defining_v2_event.sol +++ b/test/libsolidity/syntaxTests/abiEncoder/v1_inheritance_from_contract_defining_v2_event.sol @@ -13,4 +13,6 @@ pragma abicoder v1; import "A"; contract D is C {} +// ==== +// bytecodeFormat: legacy // ---- diff --git a/test/libsolidity/syntaxTests/abiEncoder/v1_inheritance_from_contract_emitting_v2_event.sol b/test/libsolidity/syntaxTests/abiEncoder/v1_inheritance_from_contract_emitting_v2_event.sol index 8aa2f8552c2b..5ae4cb0ed836 100644 --- a/test/libsolidity/syntaxTests/abiEncoder/v1_inheritance_from_contract_emitting_v2_event.sol +++ b/test/libsolidity/syntaxTests/abiEncoder/v1_inheritance_from_contract_emitting_v2_event.sol @@ -19,4 +19,6 @@ pragma abicoder v1; import "A"; contract D is C {} +// ==== +// bytecodeFormat: legacy // ---- diff --git a/test/libsolidity/syntaxTests/abiEncoder/v1_modifier_overriding_v2_modifier.sol b/test/libsolidity/syntaxTests/abiEncoder/v1_modifier_overriding_v2_modifier.sol index dd102cf51378..9a809b50a2fe 100644 --- a/test/libsolidity/syntaxTests/abiEncoder/v1_modifier_overriding_v2_modifier.sol +++ b/test/libsolidity/syntaxTests/abiEncoder/v1_modifier_overriding_v2_modifier.sol @@ -27,4 +27,6 @@ contract C is B { _; } } +// ==== +// bytecodeFormat: legacy // ---- diff --git a/test/libsolidity/syntaxTests/abiEncoder/v1_v2_v1_modifier_mix.sol b/test/libsolidity/syntaxTests/abiEncoder/v1_v2_v1_modifier_mix.sol index e5df9cc82237..6665c42efd49 100644 --- a/test/libsolidity/syntaxTests/abiEncoder/v1_v2_v1_modifier_mix.sol +++ b/test/libsolidity/syntaxTests/abiEncoder/v1_v2_v1_modifier_mix.sol @@ -52,4 +52,6 @@ struct Data { contract X { function get() public view returns (Data memory) {} } +// ==== +// bytecodeFormat: legacy // ---- diff --git a/test/libsolidity/syntaxTests/array/nested_calldata_storage.sol b/test/libsolidity/syntaxTests/array/nested_calldata_storage.sol index 9aa5fce1211a..e9ef53842c81 100644 --- a/test/libsolidity/syntaxTests/array/nested_calldata_storage.sol +++ b/test/libsolidity/syntaxTests/array/nested_calldata_storage.sol @@ -5,5 +5,7 @@ contract C { function i(uint[][2] calldata s) external { tmp_i = s; } } +// ==== +// compileViaYul: false // ---- // UnimplementedFeatureError 1834: (35-127): Copying nested calldata dynamic arrays to storage is not implemented in the old code generator. diff --git a/test/libsolidity/syntaxTests/array/nested_calldata_storage2.sol b/test/libsolidity/syntaxTests/array/nested_calldata_storage2.sol index f1125b4d232b..5db87f0d4edb 100644 --- a/test/libsolidity/syntaxTests/array/nested_calldata_storage2.sol +++ b/test/libsolidity/syntaxTests/array/nested_calldata_storage2.sol @@ -5,5 +5,7 @@ contract C { function i(uint[][] calldata s) external { tmp_i = s; } } +// ==== +// compileViaYul: false // ---- // UnimplementedFeatureError 1834: (35-125): Copying nested calldata dynamic arrays to storage is not implemented in the old code generator. diff --git a/test/libsolidity/syntaxTests/bytecodeReferences/library_non_called.sol b/test/libsolidity/syntaxTests/bytecodeReferences/library_non_called.sol index b7392ff3ee74..1374c3110d35 100644 --- a/test/libsolidity/syntaxTests/bytecodeReferences/library_non_called.sol +++ b/test/libsolidity/syntaxTests/bytecodeReferences/library_non_called.sol @@ -7,5 +7,7 @@ library L2 { contract A { function f() public pure { type(L2).creationCode; } } +// ==== +// bytecodeFormat: legacy // ---- // Warning 6133: (157-178): Statement has no effect. diff --git a/test/libsolidity/syntaxTests/constants/mod_div_rational.sol b/test/libsolidity/syntaxTests/constants/mod_div_rational.sol index 68d3bfc7ae03..b7a4b4518473 100644 --- a/test/libsolidity/syntaxTests/constants/mod_div_rational.sol +++ b/test/libsolidity/syntaxTests/constants/mod_div_rational.sol @@ -4,5 +4,7 @@ contract C { fixed a3 = 0 / 0.123; fixed a4 = 0 / -0.123; } +// ==== +// compileViaYul: true // ---- -// UnimplementedFeatureError 1834: (0-150): Not yet implemented - FixedPointType. +// UnimplementedFeatureError 1834: (28-53): Fixed point types not implemented. diff --git a/test/libsolidity/syntaxTests/constructor/nonabiv2_type_abstract.sol b/test/libsolidity/syntaxTests/constructor/nonabiv2_type_abstract.sol index 2ca22790c128..ca52859ff928 100644 --- a/test/libsolidity/syntaxTests/constructor/nonabiv2_type_abstract.sol +++ b/test/libsolidity/syntaxTests/constructor/nonabiv2_type_abstract.sol @@ -2,4 +2,6 @@ pragma abicoder v1; abstract contract C { constructor(uint[][][] memory t) {} } +// ==== +// bytecodeFormat: legacy // ---- diff --git a/test/libsolidity/syntaxTests/experimental/builtin/builtin_type_definition.sol b/test/libsolidity/syntaxTests/experimental/builtin/builtin_type_definition.sol index 858b9132dd32..74a659cd8b83 100644 --- a/test/libsolidity/syntaxTests/experimental/builtin/builtin_type_definition.sol +++ b/test/libsolidity/syntaxTests/experimental/builtin/builtin_type_definition.sol @@ -32,6 +32,7 @@ contract C { // ==== // EVMVersion: >=constantinople // compileViaYul: true +// bytecodeFormat: legacy // ---- // Warning 2264: (0-29): Experimental features are turned on. Do not use experimental features on live deployments. // Info 4164: (31-61): Inferred type: void diff --git a/test/libsolidity/syntaxTests/experimental/inference/import_and_call_stdlib_function.sol b/test/libsolidity/syntaxTests/experimental/inference/import_and_call_stdlib_function.sol index fc75e85947eb..72af2133f206 100644 --- a/test/libsolidity/syntaxTests/experimental/inference/import_and_call_stdlib_function.sol +++ b/test/libsolidity/syntaxTests/experimental/inference/import_and_call_stdlib_function.sol @@ -13,6 +13,7 @@ contract C // ==== // EVMVersion: >=constantinople // compileViaYul: true +// bytecodeFormat: legacy // ---- // Warning 2264: (std.stub:63-92): Experimental features are turned on. Do not use experimental features on live deployments. // Warning 2264: (0-29): Experimental features are turned on. Do not use experimental features on live deployments. diff --git a/test/libsolidity/syntaxTests/functionCalls/calloptions_duplicated.sol b/test/libsolidity/syntaxTests/functionCalls/calloptions_duplicated.sol index 3b162a7f220a..417eea14d609 100644 --- a/test/libsolidity/syntaxTests/functionCalls/calloptions_duplicated.sol +++ b/test/libsolidity/syntaxTests/functionCalls/calloptions_duplicated.sol @@ -8,6 +8,8 @@ contract C { } } // ==== +// bytecodeFormat: legacy +// ==== // EVMVersion: >=constantinople // ---- // TypeError 9886: (78-101): Duplicate option "gas". diff --git a/test/libsolidity/syntaxTests/functionCalls/calloptions_on_delegatecall.sol b/test/libsolidity/syntaxTests/functionCalls/calloptions_on_delegatecall.sol index d719fdcd9bb7..858b9a1d2e89 100644 --- a/test/libsolidity/syntaxTests/functionCalls/calloptions_on_delegatecall.sol +++ b/test/libsolidity/syntaxTests/functionCalls/calloptions_on_delegatecall.sol @@ -3,6 +3,8 @@ contract C { address(10).delegatecall{value: 7, gas: 3}(""); } } +// ==== +// bytecodeFormat: legacy // ---- // TypeError 6189: (56-98): Cannot set option "value" for delegatecall. // Warning 9302: (56-102): Return value of low-level calls not used. diff --git a/test/libsolidity/syntaxTests/functionCalls/calloptions_on_staticcall.sol b/test/libsolidity/syntaxTests/functionCalls/calloptions_on_staticcall.sol index e128f03f1f21..c525542c7e0b 100644 --- a/test/libsolidity/syntaxTests/functionCalls/calloptions_on_staticcall.sol +++ b/test/libsolidity/syntaxTests/functionCalls/calloptions_on_staticcall.sol @@ -5,6 +5,7 @@ contract C { } // ==== // EVMVersion: >=byzantium +// bytecodeFormat: legacy // ---- // TypeError 2842: (56-96): Cannot set option "value" for staticcall. // Warning 9302: (56-100): Return value of low-level calls not used. diff --git a/test/libsolidity/syntaxTests/functionCalls/calloptions_repeated.sol b/test/libsolidity/syntaxTests/functionCalls/calloptions_repeated.sol index 4356efcf95d5..0961881a1257 100644 --- a/test/libsolidity/syntaxTests/functionCalls/calloptions_repeated.sol +++ b/test/libsolidity/syntaxTests/functionCalls/calloptions_repeated.sol @@ -10,6 +10,7 @@ contract C { } // ==== // EVMVersion: >=constantinople +// bytecodeFormat: legacy // ---- // TypeError 1645: (78-110): Function call options have already been set, you have to combine them into a single {...}-option. // TypeError 1645: (120-154): Function call options have already been set, you have to combine them into a single {...}-option. diff --git a/test/libsolidity/syntaxTests/functionCalls/eof/calloptions_on_delegatecall.sol b/test/libsolidity/syntaxTests/functionCalls/eof/calloptions_on_delegatecall.sol new file mode 100644 index 000000000000..fdbb79b96970 --- /dev/null +++ b/test/libsolidity/syntaxTests/functionCalls/eof/calloptions_on_delegatecall.sol @@ -0,0 +1,11 @@ +contract C { + function foo() pure internal { + address(10).delegatecall{value: 7, gas: 3}(""); + } +} +// ==== +// bytecodeFormat: >=EOFv1 +// ---- +// TypeError 6189: (56-98): Cannot set option "value" for delegatecall. +// TypeError 3765: (56-98): Function call option "gas" cannot be used when compiling to EOF. +// Warning 9302: (56-102): Return value of low-level calls not used. diff --git a/test/libsolidity/syntaxTests/functionCalls/eof/calloptions_on_staticcall.sol b/test/libsolidity/syntaxTests/functionCalls/eof/calloptions_on_staticcall.sol new file mode 100644 index 000000000000..f63837dcf26a --- /dev/null +++ b/test/libsolidity/syntaxTests/functionCalls/eof/calloptions_on_staticcall.sol @@ -0,0 +1,12 @@ +contract C { + function foo() pure internal { + address(10).staticcall{value: 7, gas: 3}(""); + } +} +// ==== +// EVMVersion: >=prague +// bytecodeFormat: >=EOFv1 +// ---- +// TypeError 2842: (56-96): Cannot set option "value" for staticcall. +// TypeError 3765: (56-96): Function call option "gas" cannot be used when compiling to EOF. +// Warning 9302: (56-100): Return value of low-level calls not used. diff --git a/test/libsolidity/syntaxTests/functionCalls/eof/lowlevel_call_options.sol b/test/libsolidity/syntaxTests/functionCalls/eof/lowlevel_call_options.sol new file mode 100644 index 000000000000..4bc515d7c54c --- /dev/null +++ b/test/libsolidity/syntaxTests/functionCalls/eof/lowlevel_call_options.sol @@ -0,0 +1,9 @@ +contract C { + function foo() internal { + (bool success, ) = address(10).call{value: 7}(""); + success; + } +} +// ==== +// bytecodeFormat: >=EOFv1 +// ---- diff --git a/test/libsolidity/syntaxTests/functionCalls/lowlevel_call_options.sol b/test/libsolidity/syntaxTests/functionCalls/lowlevel_call_options.sol index da5c17a20ac0..c5ec6de71380 100644 --- a/test/libsolidity/syntaxTests/functionCalls/lowlevel_call_options.sol +++ b/test/libsolidity/syntaxTests/functionCalls/lowlevel_call_options.sol @@ -4,4 +4,6 @@ contract C { success; } } +// ==== +// bytecodeFormat: legacy // ---- diff --git a/test/libsolidity/syntaxTests/functionTypes/call_gas_on_function.sol b/test/libsolidity/syntaxTests/functionTypes/call_gas_on_function.sol index 6b926e2ddecb..e92d1cfb0489 100644 --- a/test/libsolidity/syntaxTests/functionTypes/call_gas_on_function.sol +++ b/test/libsolidity/syntaxTests/functionTypes/call_gas_on_function.sol @@ -4,5 +4,6 @@ contract C { x{gas: 2}(1); } } - +// ==== +// bytecodeFormat: legacy // ---- diff --git a/test/libsolidity/syntaxTests/functionTypes/comparison_operator_for_external_functions_with_call_options.sol b/test/libsolidity/syntaxTests/functionTypes/comparison_operator_for_external_functions_with_call_options.sol new file mode 100644 index 000000000000..da84e6ada8f1 --- /dev/null +++ b/test/libsolidity/syntaxTests/functionTypes/comparison_operator_for_external_functions_with_call_options.sol @@ -0,0 +1,12 @@ +contract C { + function external_test_function() payable external {} + function comparison_operator_for_external_function_with_extra_slots() external returns (bool) { + return ( + (this.external_test_function{value: 4} == this.external_test_function) && + (this.external_test_function{value: 4} == this.external_test_function{value: 4}) + ); + } +} +// ---- +// TypeError 2271: (201-269): Built-in binary operator == cannot be applied to types function () payable external and function () payable external. +// TypeError 2271: (287-365): Built-in binary operator == cannot be applied to types function () payable external and function () payable external. diff --git a/test/libsolidity/syntaxTests/functionTypes/comparison_operator_for_external_functions_with_extra_gas_slots.sol b/test/libsolidity/syntaxTests/functionTypes/comparison_operator_for_external_functions_with_extra_gas_slots.sol deleted file mode 100644 index 12cbe2939bc3..000000000000 --- a/test/libsolidity/syntaxTests/functionTypes/comparison_operator_for_external_functions_with_extra_gas_slots.sol +++ /dev/null @@ -1,12 +0,0 @@ -contract C { - function external_test_function() external {} - function comparison_operator_for_external_function_with_extra_slots() external returns (bool) { - return ( - (this.external_test_function{gas: 4} == this.external_test_function) && - (this.external_test_function{gas: 4} == this.external_test_function{gas: 4}) - ); - } -} -// ---- -// TypeError 2271: (193-259): Built-in binary operator == cannot be applied to types function () external and function () external. -// TypeError 2271: (277-351): Built-in binary operator == cannot be applied to types function () external and function () external. diff --git a/test/libsolidity/syntaxTests/functionTypes/eof/call_gas_on_function.sol b/test/libsolidity/syntaxTests/functionTypes/eof/call_gas_on_function.sol new file mode 100644 index 000000000000..c4f00843d597 --- /dev/null +++ b/test/libsolidity/syntaxTests/functionTypes/eof/call_gas_on_function.sol @@ -0,0 +1,10 @@ +contract C { + function (uint) external returns (uint) x; + function f() public { + x{gas: 2}(1); + } +} +// ==== +// bytecodeFormat: >=EOFv1 +// ---- +// TypeError 3765: (94-103): Function call option "gas" cannot be used when compiling to EOF. diff --git a/test/libsolidity/syntaxTests/functionTypes/external_functions_with_variable_number_of_stack_slots.sol b/test/libsolidity/syntaxTests/functionTypes/external_functions_with_variable_number_of_stack_slots.sol index 8593bdbf4fed..a6d8d7c1d31c 100644 --- a/test/libsolidity/syntaxTests/functionTypes/external_functions_with_variable_number_of_stack_slots.sol +++ b/test/libsolidity/syntaxTests/functionTypes/external_functions_with_variable_number_of_stack_slots.sol @@ -1,8 +1,7 @@ contract C { - function f (address) external returns (bool) { - this.f{gas: 42}.address; + function f (address) payable external returns (bool) { + this.f{value: 42}.address; } } // ---- -// Warning 6321: (56-60): Unnamed return variable can remain unassigned. Add an explicit return with value to all non-reverting code paths or name the variable. -// Warning 2018: (17-102): Function state mutability can be restricted to view +// Warning 6321: (64-68): Unnamed return variable can remain unassigned. Add an explicit return with value to all non-reverting code paths or name the variable. diff --git a/test/libsolidity/syntaxTests/immutable/creationCode.sol b/test/libsolidity/syntaxTests/immutable/creationCode.sol index 0a2282695cda..32fb4edea8bb 100644 --- a/test/libsolidity/syntaxTests/immutable/creationCode.sol +++ b/test/libsolidity/syntaxTests/immutable/creationCode.sol @@ -7,4 +7,6 @@ contract Test { return type(A).creationCode; } } +// ==== +// bytecodeFormat: legacy // ---- diff --git a/test/libsolidity/syntaxTests/immutable/no_assignments.sol b/test/libsolidity/syntaxTests/immutable/no_assignments.sol index 7d7948671419..92bcac8cfb7d 100644 --- a/test/libsolidity/syntaxTests/immutable/no_assignments.sol +++ b/test/libsolidity/syntaxTests/immutable/no_assignments.sol @@ -1,3 +1,4 @@ +// TODO: This test case should work the same way for EOF but EOF immutables support is not in its final state yet. contract C { uint immutable x; constructor() { @@ -8,6 +9,7 @@ contract C { function f() external view returns(uint) { return x; } } // ==== +// bytecodeFormat: legacy // optimize-yul: true // ---- -// CodeGenerationError 1284: (0-168): Some immutables were read from but never assigned, possibly because of optimization. +// CodeGenerationError 1284: (115-283): Some immutables were read from but never assigned, possibly because of optimization. diff --git a/test/libsolidity/syntaxTests/inlineArrays/inline_array_fixed_types.sol b/test/libsolidity/syntaxTests/inlineArrays/inline_array_fixed_types.sol index 8e51bd1886c1..7c67a647a3e2 100644 --- a/test/libsolidity/syntaxTests/inlineArrays/inline_array_fixed_types.sol +++ b/test/libsolidity/syntaxTests/inlineArrays/inline_array_fixed_types.sol @@ -3,7 +3,9 @@ contract test { fixed[3] memory a = [fixed(3.5), fixed(-4.25), fixed(967.125)]; } } +// ==== +// compileViaYul: true // ---- // Warning 2072: (50-67): Unused local variable. // Warning 2018: (20-119): Function state mutability can be restricted to pure -// UnimplementedFeatureError 1834: (0-121): Not yet implemented - FixedPointType. +// UnimplementedFeatureError 1834: (71-81): Fixed point types not implemented. diff --git a/test/libsolidity/syntaxTests/inlineArrays/inline_array_rationals.sol b/test/libsolidity/syntaxTests/inlineArrays/inline_array_rationals.sol index 0382672fe38e..20e9de7649ca 100644 --- a/test/libsolidity/syntaxTests/inlineArrays/inline_array_rationals.sol +++ b/test/libsolidity/syntaxTests/inlineArrays/inline_array_rationals.sol @@ -3,7 +3,9 @@ contract test { ufixed128x3[4] memory a = [ufixed128x3(3.5), 4.125, 2.5, 4.0]; } } +// ==== +// compileViaYul: true // ---- // Warning 2072: (50-73): Unused local variable. // Warning 2018: (20-118): Function state mutability can be restricted to pure -// UnimplementedFeatureError 1834: (0-120): Not yet implemented - FixedPointType. +// UnimplementedFeatureError 1834: (77-93): Fixed point types not implemented. diff --git a/test/libsolidity/syntaxTests/inlineAssembly/assignment_from_library.sol b/test/libsolidity/syntaxTests/inlineAssembly/assignment_from_library.sol index 522ca801d975..801bdd7eea18 100644 --- a/test/libsolidity/syntaxTests/inlineAssembly/assignment_from_library.sol +++ b/test/libsolidity/syntaxTests/inlineAssembly/assignment_from_library.sol @@ -8,4 +8,6 @@ contract C { } } } +// ==== +// compileViaYul: false // ---- diff --git a/test/libsolidity/syntaxTests/inlineAssembly/create2_as_variable_post_istanbul.sol b/test/libsolidity/syntaxTests/inlineAssembly/create2_as_variable_post_istanbul.sol index 96a384c54d20..0468ef093f52 100644 --- a/test/libsolidity/syntaxTests/inlineAssembly/create2_as_variable_post_istanbul.sol +++ b/test/libsolidity/syntaxTests/inlineAssembly/create2_as_variable_post_istanbul.sol @@ -6,4 +6,5 @@ contract c { } // ==== // EVMVersion: >=constantinople +// bytecodeFormat: legacy // ---- diff --git a/test/libsolidity/syntaxTests/inlineAssembly/evm_byzantium.sol b/test/libsolidity/syntaxTests/inlineAssembly/evm_byzantium.sol index b08172ebe469..e019026f633b 100644 --- a/test/libsolidity/syntaxTests/inlineAssembly/evm_byzantium.sol +++ b/test/libsolidity/syntaxTests/inlineAssembly/evm_byzantium.sol @@ -13,4 +13,5 @@ contract C { } // ==== // EVMVersion: >=byzantium +// bytecodeFormat: legacy // ---- diff --git a/test/libsolidity/syntaxTests/inlineAssembly/evm_constantinople.sol b/test/libsolidity/syntaxTests/inlineAssembly/evm_constantinople.sol index 2aff4351ae8b..ddfa80d7fc7e 100644 --- a/test/libsolidity/syntaxTests/inlineAssembly/evm_constantinople.sol +++ b/test/libsolidity/syntaxTests/inlineAssembly/evm_constantinople.sol @@ -19,4 +19,5 @@ contract C { } // ==== // EVMVersion: >=constantinople +// bytecodeFormat: legacy // ---- diff --git a/test/libsolidity/syntaxTests/inlineAssembly/extcodehash_as_variable_post_constantinople.sol b/test/libsolidity/syntaxTests/inlineAssembly/extcodehash_as_variable_post_constantinople.sol index 8b34ab906d4a..8ee7f644be0e 100644 --- a/test/libsolidity/syntaxTests/inlineAssembly/extcodehash_as_variable_post_constantinople.sol +++ b/test/libsolidity/syntaxTests/inlineAssembly/extcodehash_as_variable_post_constantinople.sol @@ -7,4 +7,5 @@ contract c { } // ==== // EVMVersion: >=constantinople +// bytecodeFormat: legacy // ---- diff --git a/test/libsolidity/syntaxTests/inlineAssembly/hex_switch_case.sol b/test/libsolidity/syntaxTests/inlineAssembly/hex_switch_case.sol index 038e8c4ff99e..915048905dbc 100644 --- a/test/libsolidity/syntaxTests/inlineAssembly/hex_switch_case.sol +++ b/test/libsolidity/syntaxTests/inlineAssembly/hex_switch_case.sol @@ -1,10 +1,9 @@ contract C { function f() public pure { assembly { - switch codesize() + switch calldataload(0) case hex"00" {} case hex"1122" {} } } } -// ---- diff --git a/test/libsolidity/syntaxTests/inlineAssembly/invalid/pc_disallowed.sol b/test/libsolidity/syntaxTests/inlineAssembly/invalid/pc_disallowed.sol index 816bb1c0d5f4..1178e9a2b907 100644 --- a/test/libsolidity/syntaxTests/inlineAssembly/invalid/pc_disallowed.sol +++ b/test/libsolidity/syntaxTests/inlineAssembly/invalid/pc_disallowed.sol @@ -5,5 +5,7 @@ contract C { } } } +// ==== +// bytecodeFormat: legacy // ---- // SyntaxError 2450: (61-63): PC instruction is a low-level EVM feature. Because of that PC is disallowed in strict assembly. diff --git a/test/libsolidity/syntaxTests/inlineAssembly/string_literal_switch_case.sol b/test/libsolidity/syntaxTests/inlineAssembly/string_literal_switch_case.sol index 0a63987e143e..d612d10d0abb 100644 --- a/test/libsolidity/syntaxTests/inlineAssembly/string_literal_switch_case.sol +++ b/test/libsolidity/syntaxTests/inlineAssembly/string_literal_switch_case.sol @@ -1,10 +1,9 @@ contract C { function f() public pure { assembly { - switch codesize() + switch calldataload(0) case "1" {} case "2" {} } } } -// ---- diff --git a/test/libsolidity/syntaxTests/inlineAssembly/use_msize_without_optimizer.sol b/test/libsolidity/syntaxTests/inlineAssembly/use_msize_without_optimizer.sol index 8cdf96641ada..d356fe299ae9 100644 --- a/test/libsolidity/syntaxTests/inlineAssembly/use_msize_without_optimizer.sol +++ b/test/libsolidity/syntaxTests/inlineAssembly/use_msize_without_optimizer.sol @@ -7,4 +7,5 @@ contract C { } // ==== // optimize-yul: false +// bytecodeFormat: legacy // ---- diff --git a/test/libsolidity/syntaxTests/metaTypes/codeAccess.sol b/test/libsolidity/syntaxTests/metaTypes/codeAccess.sol index e90443e14ef5..6136665e34bd 100644 --- a/test/libsolidity/syntaxTests/metaTypes/codeAccess.sol +++ b/test/libsolidity/syntaxTests/metaTypes/codeAccess.sol @@ -9,4 +9,6 @@ contract Test { contract Other { function f(uint) public pure returns (uint) {} } +// ==== +// bytecodeFormat: legacy // ---- diff --git a/test/libsolidity/syntaxTests/metaTypes/codeAccessAbstractCreation.sol b/test/libsolidity/syntaxTests/metaTypes/codeAccessAbstractCreation.sol index 2f5c356c08d0..22f81cfb0241 100644 --- a/test/libsolidity/syntaxTests/metaTypes/codeAccessAbstractCreation.sol +++ b/test/libsolidity/syntaxTests/metaTypes/codeAccessAbstractCreation.sol @@ -6,5 +6,7 @@ contract Test { abstract contract Other { function f(uint) public returns (uint); } +// ==== +// bytecodeFormat: legacy // ---- // TypeError 9582: (97-121): Member "creationCode" not found or not visible after argument-dependent lookup in type(contract Other). diff --git a/test/libsolidity/syntaxTests/metaTypes/codeAccessAbstractRuntime.sol b/test/libsolidity/syntaxTests/metaTypes/codeAccessAbstractRuntime.sol index 538a26e78941..8019dabb2176 100644 --- a/test/libsolidity/syntaxTests/metaTypes/codeAccessAbstractRuntime.sol +++ b/test/libsolidity/syntaxTests/metaTypes/codeAccessAbstractRuntime.sol @@ -6,5 +6,7 @@ contract Test { abstract contract Other { function f(uint) public returns (uint); } +// ==== +// bytecodeFormat: legacy // ---- // TypeError 9582: (91-114): Member "runtimeCode" not found or not visible after argument-dependent lookup in type(contract Other). diff --git a/test/libsolidity/syntaxTests/metaTypes/codeAccessBase.sol b/test/libsolidity/syntaxTests/metaTypes/codeAccessBase.sol index c202046cc4d0..c4b3efedd77d 100644 --- a/test/libsolidity/syntaxTests/metaTypes/codeAccessBase.sol +++ b/test/libsolidity/syntaxTests/metaTypes/codeAccessBase.sol @@ -21,6 +21,8 @@ contract Test4 is Base { return type(Base).runtimeCode; } } +// ==== +// bytecodeFormat: legacy // ---- // TypeError 7813: (166-190): Circular reference to contract bytecode either via "new" or "type(...).creationCode" / "type(...).runtimeCode". // TypeError 7813: (300-323): Circular reference to contract bytecode either via "new" or "type(...).creationCode" / "type(...).runtimeCode". diff --git a/test/libsolidity/syntaxTests/metaTypes/codeAccessCyclic.sol b/test/libsolidity/syntaxTests/metaTypes/codeAccessCyclic.sol index 57e3263e3249..4a5a760f792b 100644 --- a/test/libsolidity/syntaxTests/metaTypes/codeAccessCyclic.sol +++ b/test/libsolidity/syntaxTests/metaTypes/codeAccessCyclic.sol @@ -8,6 +8,8 @@ contract B { type(A).runtimeCode; } } +// ==== +// bytecodeFormat: legacy // ---- // TypeError 7813: (52-71): Circular reference to contract bytecode either via "new" or "type(...).creationCode" / "type(...).runtimeCode". // TypeError 7813: (133-152): Circular reference to contract bytecode either via "new" or "type(...).creationCode" / "type(...).runtimeCode". diff --git a/test/libsolidity/syntaxTests/metaTypes/codeAccessIsConstant.sol b/test/libsolidity/syntaxTests/metaTypes/codeAccessIsConstant.sol index cda5d5c349f7..96303396e032 100644 --- a/test/libsolidity/syntaxTests/metaTypes/codeAccessIsConstant.sol +++ b/test/libsolidity/syntaxTests/metaTypes/codeAccessIsConstant.sol @@ -4,4 +4,6 @@ contract Test { } contract B { function f() public pure {} } +// ==== +// bytecodeFormat: legacy // ---- diff --git a/test/libsolidity/syntaxTests/metaTypes/codeAccessLibrary.sol b/test/libsolidity/syntaxTests/metaTypes/codeAccessLibrary.sol index f746dc35d1de..8c707006891b 100644 --- a/test/libsolidity/syntaxTests/metaTypes/codeAccessLibrary.sol +++ b/test/libsolidity/syntaxTests/metaTypes/codeAccessLibrary.sol @@ -9,4 +9,6 @@ contract Test { contract Library { function f(uint) public pure returns (uint) {} } +// ==== +// bytecodeFormat: legacy // ---- diff --git a/test/libsolidity/syntaxTests/metaTypes/codeAccess_super.sol b/test/libsolidity/syntaxTests/metaTypes/codeAccess_super.sol index 7d057e132b17..a8fef765eea1 100644 --- a/test/libsolidity/syntaxTests/metaTypes/codeAccess_super.sol +++ b/test/libsolidity/syntaxTests/metaTypes/codeAccess_super.sol @@ -9,5 +9,7 @@ contract SuperTest is Other { return type(super).runtimeCode; } } +// ==== +// bytecodeFormat: legacy // ---- // TypeError 4259: (177-182): Invalid type for argument in the function call. An enum type, contract type or an integer type is required, but type(contract super SuperTest) provided. diff --git a/test/libsolidity/syntaxTests/metaTypes/codeIsNoLValue.sol b/test/libsolidity/syntaxTests/metaTypes/codeIsNoLValue.sol index c9cade179f55..2a51276414d9 100644 --- a/test/libsolidity/syntaxTests/metaTypes/codeIsNoLValue.sol +++ b/test/libsolidity/syntaxTests/metaTypes/codeIsNoLValue.sol @@ -5,6 +5,8 @@ contract Test { } } contract C {} +// ==== +// bytecodeFormat: legacy // ---- // TypeError 4247: (55-75): Expression has to be an lvalue. // TypeError 4247: (100-119): Expression has to be an lvalue. diff --git a/test/libsolidity/syntaxTests/metaTypes/runtimeCodeWarningAssembly.sol b/test/libsolidity/syntaxTests/metaTypes/runtimeCodeWarningAssembly.sol index 40eaee040cbe..8e6fcf64e34a 100644 --- a/test/libsolidity/syntaxTests/metaTypes/runtimeCodeWarningAssembly.sol +++ b/test/libsolidity/syntaxTests/metaTypes/runtimeCodeWarningAssembly.sol @@ -12,6 +12,8 @@ contract C { contract D is C { constructor() {} } +// ==== +// bytecodeFormat: legacy // ---- // Warning 6417: (77-96): The constructor of the contract (or its base) uses inline assembly. Because of that, it might be that the deployed bytecode is different from type(...).runtimeCode. // Warning 6417: (118-137): The constructor of the contract (or its base) uses inline assembly. Because of that, it might be that the deployed bytecode is different from type(...).runtimeCode. diff --git a/test/libsolidity/syntaxTests/metaTypes/type_runtimecode.sol b/test/libsolidity/syntaxTests/metaTypes/type_runtimecode.sol index 6b054b4dacfb..d110b2c8ec37 100644 --- a/test/libsolidity/syntaxTests/metaTypes/type_runtimecode.sol +++ b/test/libsolidity/syntaxTests/metaTypes/type_runtimecode.sol @@ -6,4 +6,6 @@ contract C { return type(A).runtimeCode; } } +// ==== +// bytecodeFormat: legacy // ---- diff --git a/test/libsolidity/syntaxTests/metaTypes/type_runtimecode_from_ternary_expression_.sol b/test/libsolidity/syntaxTests/metaTypes/type_runtimecode_from_ternary_expression_.sol index 8fcf65480e12..f802b9a00508 100644 --- a/test/libsolidity/syntaxTests/metaTypes/type_runtimecode_from_ternary_expression_.sol +++ b/test/libsolidity/syntaxTests/metaTypes/type_runtimecode_from_ternary_expression_.sol @@ -9,6 +9,8 @@ contract C { return (getA ? type(A) : type(B)).runtimeCode; } } +// ==== +// bytecodeFormat: legacy // ---- // TypeError 9717: (126-133): Invalid mobile type in true expression. // TypeError 3703: (136-143): Invalid mobile type in false expression. diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/303_fixed_type_int_conversion.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/303_fixed_type_int_conversion.sol index 88a407fef98d..41bb9e046ce0 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/303_fixed_type_int_conversion.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/303_fixed_type_int_conversion.sol @@ -7,6 +7,8 @@ contract test { c; d; } } +// ==== +// compileViaYul: true // ---- // Warning 2018: (20-147): Function state mutability can be restricted to pure -// UnimplementedFeatureError 1834: (0-149): Not yet implemented - FixedPointType. +// UnimplementedFeatureError 1834: (93-104): Fixed point types not implemented. diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/304_fixed_type_rational_int_conversion.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/304_fixed_type_rational_int_conversion.sol index 0e3cb3b6cb47..2809575b6c44 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/304_fixed_type_rational_int_conversion.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/304_fixed_type_rational_int_conversion.sol @@ -5,6 +5,8 @@ contract test { c; d; } } +// ==== +// compileViaYul: true // ---- // Warning 2018: (20-104): Function state mutability can be restricted to pure -// UnimplementedFeatureError 1834: (0-106): Not yet implemented - FixedPointType. +// UnimplementedFeatureError 1834: (50-61): Fixed point types not implemented. diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/305_fixed_type_rational_fraction_conversion.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/305_fixed_type_rational_fraction_conversion.sol index ada627037e49..0a13eedcc372 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/305_fixed_type_rational_fraction_conversion.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/305_fixed_type_rational_fraction_conversion.sol @@ -5,6 +5,8 @@ contract test { a; d; } } +// ==== +// compileViaYul: true // ---- // Warning 2018: (20-108): Function state mutability can be restricted to pure -// UnimplementedFeatureError 1834: (0-110): Not yet implemented - FixedPointType. +// UnimplementedFeatureError 1834: (50-63): Fixed point types not implemented. diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/307_rational_unary_minus_operation.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/307_rational_unary_minus_operation.sol index adb9fbe699ce..d0d11105bd1c 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/307_rational_unary_minus_operation.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/307_rational_unary_minus_operation.sol @@ -5,5 +5,7 @@ contract test { a; b; } } +// ==== +// compileViaYul: true // ---- -// UnimplementedFeatureError 1834: (0-126): Not yet implemented - FixedPointType. +// UnimplementedFeatureError 1834: (55-74): Fixed point types not implemented. diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/312_leading_zero_rationals_convert.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/312_leading_zero_rationals_convert.sol index e763fa18be20..c1586595b154 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/312_leading_zero_rationals_convert.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/312_leading_zero_rationals_convert.sol @@ -7,5 +7,7 @@ contract A { a; b; c; d; } } +// ==== +// compileViaYul: true // ---- -// UnimplementedFeatureError 1834: (0-289): Not yet implemented - FixedPointType. +// UnimplementedFeatureError 1834: (52-70): Fixed point types not implemented. diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/314_fixed_type_zero_handling.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/314_fixed_type_zero_handling.sol index b9205f01b1d9..07c4017e0d5f 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/314_fixed_type_zero_handling.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/314_fixed_type_zero_handling.sol @@ -4,6 +4,8 @@ contract test { ufixed32x1 b = 0; b; } } +// ==== +// compileViaYul: true // ---- // Warning 2018: (20-104): Function state mutability can be restricted to pure -// UnimplementedFeatureError 1834: (0-106): Not yet implemented - FixedPointType. +// UnimplementedFeatureError 1834: (50-65): Fixed point types not implemented. diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/317_fixed_type_valid_explicit_conversions.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/317_fixed_type_valid_explicit_conversions.sol index 1282c24daf89..84e5b764027c 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/317_fixed_type_valid_explicit_conversions.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/317_fixed_type_valid_explicit_conversions.sol @@ -5,6 +5,8 @@ contract test { ufixed8x1 c = ufixed8x1(1/3); c; } } +// ==== +// compileViaYul: true // ---- // Warning 2018: (20-182): Function state mutability can be restricted to pure -// UnimplementedFeatureError 1834: (0-184): Not yet implemented - FixedPointType. +// UnimplementedFeatureError 1834: (67-84): Fixed point types not implemented. diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/323_mapping_with_fixed_literal.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/323_mapping_with_fixed_literal.sol index 3ee670cd585c..9a714f6b9d6d 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/323_mapping_with_fixed_literal.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/323_mapping_with_fixed_literal.sol @@ -4,5 +4,7 @@ contract test { fixedString[0.5] = "Half"; } } +// ==== +// compileViaYul: true // ---- -// UnimplementedFeatureError 1834: (0-130): Not yet implemented - FixedPointType. +// UnimplementedFeatureError 1834: (96-112): Fixed point types not implemented. diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/324_fixed_points_inside_structs.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/324_fixed_points_inside_structs.sol index ba467a67b131..f0ec56875d7c 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/324_fixed_points_inside_structs.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/324_fixed_points_inside_structs.sol @@ -5,5 +5,7 @@ contract test { } myStruct a = myStruct(3.125, 3); } +// ==== +// compileViaYul: true // ---- -// UnimplementedFeatureError 1834: (0-115): Not yet implemented - FixedPointType. +// UnimplementedFeatureError 1834: (94-112): Fixed point types not implemented. diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/328_rational_to_fixed_literal_expression.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/328_rational_to_fixed_literal_expression.sol index b5162bcd9720..7293e0f42528 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/328_rational_to_fixed_literal_expression.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/328_rational_to_fixed_literal_expression.sol @@ -10,7 +10,9 @@ contract test { a; b; c; d; e; f; g; } } +// ==== +// compileViaYul: true // ---- // Warning 2519: (238-252): This declaration shadows an existing declaration. // Warning 2018: (20-339): Function state mutability can be restricted to pure -// UnimplementedFeatureError 1834: (0-341): Not yet implemented - FixedPointType. +// UnimplementedFeatureError 1834: (50-72): Fixed point types not implemented. diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/343_integer_and_fixed_interaction.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/343_integer_and_fixed_interaction.sol index 3ebd54d4541a..27133cf1d923 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/343_integer_and_fixed_interaction.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/343_integer_and_fixed_interaction.sol @@ -3,7 +3,9 @@ contract test { ufixed a = uint64(1) + ufixed(2); } } +// ==== +// compileViaYul: true // ---- // Warning 2072: (50-58): Unused local variable. // Warning 2018: (20-89): Function state mutability can be restricted to pure -// UnimplementedFeatureError 1834: (0-91): Not yet implemented - FixedPointType. +// UnimplementedFeatureError 1834: (73-82): Fixed point types not implemented. diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/497_gasleft.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/497_gasleft.sol index 3d5acac99be3..7a5254a1a127 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/497_gasleft.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/497_gasleft.sol @@ -1,4 +1,6 @@ contract C { function f() public view returns (uint256 val) { return gasleft(); } } +// ==== +// bytecodeFormat: legacy // ---- diff --git a/test/libsolidity/syntaxTests/parsing/lexer_numbers_with_underscores_fixed.sol b/test/libsolidity/syntaxTests/parsing/lexer_numbers_with_underscores_fixed.sol index 9346264edbcd..2e1c746baf4e 100644 --- a/test/libsolidity/syntaxTests/parsing/lexer_numbers_with_underscores_fixed.sol +++ b/test/libsolidity/syntaxTests/parsing/lexer_numbers_with_underscores_fixed.sol @@ -6,5 +6,7 @@ contract C { f1; f2; } } +// ==== +// compileViaYul: true // ---- -// UnimplementedFeatureError 1834: (0-109): Not yet implemented - FixedPointType. +// UnimplementedFeatureError 1834: (46-64): Fixed point types not implemented. diff --git a/test/libsolidity/syntaxTests/sizeLimits/bytecode_too_large.sol b/test/libsolidity/syntaxTests/sizeLimits/bytecode_too_large.sol index f22b9755d652..5ac74bba7cb7 100644 --- a/test/libsolidity/syntaxTests/sizeLimits/bytecode_too_large.sol +++ b/test/libsolidity/syntaxTests/sizeLimits/bytecode_too_large.sol @@ -8,5 +8,6 @@ contract test { } // ==== // EVMVersion: >=cancun +// bytecodeFormat: legacy // ---- // Warning 5574: (21-27154): Contract code size is 27164 bytes and exceeds 24576 bytes (a limit introduced in Spurious Dragon). This contract may not be deployable on Mainnet. Consider enabling the optimizer (with a low "runs" value!), turning off revert strings, or using libraries. diff --git a/test/libsolidity/syntaxTests/sizeLimits/bytecode_too_large_abiencoder_v1.sol b/test/libsolidity/syntaxTests/sizeLimits/bytecode_too_large_abiencoder_v1.sol index a0c7267d0d20..f3091ebf5351 100644 --- a/test/libsolidity/syntaxTests/sizeLimits/bytecode_too_large_abiencoder_v1.sol +++ b/test/libsolidity/syntaxTests/sizeLimits/bytecode_too_large_abiencoder_v1.sol @@ -8,5 +8,6 @@ contract test { } // ==== // EVMVersion: >=shanghai +// bytecodeFormat: legacy // ---- // Warning 5574: (21-27154): Contract code size is 27205 bytes and exceeds 24576 bytes (a limit introduced in Spurious Dragon). This contract may not be deployable on Mainnet. Consider enabling the optimizer (with a low "runs" value!), turning off revert strings, or using libraries. diff --git a/test/libsolidity/syntaxTests/specialFunctions/functionCallOptions_err.sol b/test/libsolidity/syntaxTests/specialFunctions/functionCallOptions_err.sol index 071859e53fb7..8e5ebcdeb97a 100644 --- a/test/libsolidity/syntaxTests/specialFunctions/functionCallOptions_err.sol +++ b/test/libsolidity/syntaxTests/specialFunctions/functionCallOptions_err.sol @@ -5,6 +5,8 @@ contract C { abi.encode(this.f{value: 2, gas: 1}); } } +// ==== +// bytecodeFormat: legacy // ---- // TypeError 2056: (60-76): This type cannot be encoded. // TypeError 2056: (92-106): This type cannot be encoded. diff --git a/test/libsolidity/syntaxTests/specialFunctions/types_with_unspecified_encoding_internal_functions.sol b/test/libsolidity/syntaxTests/specialFunctions/types_with_unspecified_encoding_internal_functions.sol index 6ecb4e4ff869..a69dcfa924b8 100644 --- a/test/libsolidity/syntaxTests/specialFunctions/types_with_unspecified_encoding_internal_functions.sol +++ b/test/libsolidity/syntaxTests/specialFunctions/types_with_unspecified_encoding_internal_functions.sol @@ -1,11 +1,11 @@ contract C { - function f() public pure { - bytes32 h = keccak256(abi.encodePacked(keccak256, f, this.f{gas: 2}, blockhash)); + function f() payable public { + bytes32 h = keccak256(abi.encodePacked(keccak256, f, this.f{value: 2}, blockhash)); h; } } // ---- -// TypeError 2056: (91-100): This type cannot be encoded. -// TypeError 2056: (102-103): This type cannot be encoded. -// TypeError 2056: (105-119): This type cannot be encoded. -// TypeError 2056: (121-130): This type cannot be encoded. +// TypeError 2056: (94-103): This type cannot be encoded. +// TypeError 2056: (105-106): This type cannot be encoded. +// TypeError 2056: (108-124): This type cannot be encoded. +// TypeError 2056: (126-135): This type cannot be encoded. diff --git a/test/libsolidity/syntaxTests/types/address/address_members.sol b/test/libsolidity/syntaxTests/types/address/address_members.sol index 144361b9409a..9299b65d523c 100644 --- a/test/libsolidity/syntaxTests/types/address/address_members.sol +++ b/test/libsolidity/syntaxTests/types/address/address_members.sol @@ -5,4 +5,6 @@ contract C { function i() public view returns (uint) { return f().code.length; } function j() public view returns (uint) { return h().length; } } +// ==== +// bytecodeFormat: legacy // ---- diff --git a/test/libsolidity/syntaxTests/types/address/address_payable_selfdestruct.sol b/test/libsolidity/syntaxTests/types/address/address_payable_selfdestruct.sol index 754ff2c67488..449b628d4491 100644 --- a/test/libsolidity/syntaxTests/types/address/address_payable_selfdestruct.sol +++ b/test/libsolidity/syntaxTests/types/address/address_payable_selfdestruct.sol @@ -3,5 +3,7 @@ contract C { selfdestruct(a); } } +// ==== +// bytecodeFormat: legacy // ---- // Warning 5159: (64-76): "selfdestruct" has been deprecated. Note that, starting from the Cancun hard fork, the underlying opcode no longer deletes the code and data associated with an account and only transfers its Ether to the beneficiary, unless executed in the same transaction in which the contract was created (see EIP-6780). Any use in newly deployed contracts is strongly discouraged even if the new behavior is taken into account. Future changes to the EVM might further reduce the functionality of the opcode. diff --git a/test/libsolidity/syntaxTests/types/address/codehash.sol b/test/libsolidity/syntaxTests/types/address/codehash.sol index cf7eaabec976..00956d97e848 100644 --- a/test/libsolidity/syntaxTests/types/address/codehash.sol +++ b/test/libsolidity/syntaxTests/types/address/codehash.sol @@ -5,4 +5,5 @@ contract C { } // ==== // EVMVersion: >=constantinople +// bytecodeFormat: legacy // ---- diff --git a/test/libsolidity/syntaxTests/types/address/eof/address_members.sol b/test/libsolidity/syntaxTests/types/address/eof/address_members.sol new file mode 100644 index 000000000000..a1b21de2cea0 --- /dev/null +++ b/test/libsolidity/syntaxTests/types/address/eof/address_members.sol @@ -0,0 +1,9 @@ +contract C { + function f() public view returns (address) { return address(this); } + function g() public view returns (uint) { return f().balance; } + function h() public pure returns (bytes memory) { return msg.data; } + function j() public pure returns (uint) { return h().length; } +} +// ==== +// bytecodeFormat: >=EOFv1 +// ---- diff --git a/test/libsolidity/syntaxTests/types/rational_number_literal_to_fixed_implicit.sol b/test/libsolidity/syntaxTests/types/rational_number_literal_to_fixed_implicit.sol index e62728770d90..f76fa84308a9 100644 --- a/test/libsolidity/syntaxTests/types/rational_number_literal_to_fixed_implicit.sol +++ b/test/libsolidity/syntaxTests/types/rational_number_literal_to_fixed_implicit.sol @@ -12,5 +12,7 @@ contract C { a; b; c; } } +// ==== +// compileViaYul: true // ---- -// UnimplementedFeatureError 1834: (0-317): Not yet implemented - FixedPointType. +// UnimplementedFeatureError 1834: (66-84): Fixed point types not implemented. diff --git a/test/libsolidity/syntaxTests/viewPureChecker/address_constantinople.sol b/test/libsolidity/syntaxTests/viewPureChecker/address_constantinople.sol index 4387ca60a75b..e8ee980bf5ac 100644 --- a/test/libsolidity/syntaxTests/viewPureChecker/address_constantinople.sol +++ b/test/libsolidity/syntaxTests/viewPureChecker/address_constantinople.sol @@ -8,4 +8,5 @@ contract C { } // ==== // EVMVersion: >=constantinople +// bytecodeFormat: legacy // ---- diff --git a/test/libsolidity/syntaxTests/viewPureChecker/assembly.sol b/test/libsolidity/syntaxTests/viewPureChecker/assembly.sol index cc8ac5e8341b..9097a166c118 100644 --- a/test/libsolidity/syntaxTests/viewPureChecker/assembly.sol +++ b/test/libsolidity/syntaxTests/viewPureChecker/assembly.sol @@ -27,4 +27,6 @@ contract C { assembly { pop(extcodesize(0)) } } } +// ==== +// bytecodeFormat: legacy // ---- diff --git a/test/libsolidity/syntaxTests/viewPureChecker/assembly_constantinople.sol b/test/libsolidity/syntaxTests/viewPureChecker/assembly_constantinople.sol index ed0b20d53793..16f57b2e8091 100644 --- a/test/libsolidity/syntaxTests/viewPureChecker/assembly_constantinople.sol +++ b/test/libsolidity/syntaxTests/viewPureChecker/assembly_constantinople.sol @@ -5,4 +5,5 @@ contract C { } // ==== // EVMVersion: >=constantinople +// bytecodeFormat: legacy // ---- diff --git a/test/libsolidity/syntaxTests/viewPureChecker/builtin_functions.sol b/test/libsolidity/syntaxTests/viewPureChecker/builtin_functions.sol index 4d1710a3a160..8f275321382a 100644 --- a/test/libsolidity/syntaxTests/viewPureChecker/builtin_functions.sol +++ b/test/libsolidity/syntaxTests/viewPureChecker/builtin_functions.sol @@ -18,5 +18,7 @@ contract C { } receive() payable external {} } +// ==== +// bytecodeFormat: legacy // ---- // Warning 5159: (122-134): "selfdestruct" has been deprecated. Note that, starting from the Cancun hard fork, the underlying opcode no longer deletes the code and data associated with an account and only transfers its Ether to the beneficiary, unless executed in the same transaction in which the contract was created (see EIP-6780). Any use in newly deployed contracts is strongly discouraged even if the new behavior is taken into account. Future changes to the EVM might further reduce the functionality of the opcode. diff --git a/test/libsolidity/syntaxTests/viewPureChecker/call_options_without_call.sol b/test/libsolidity/syntaxTests/viewPureChecker/call_options_without_call.sol new file mode 100644 index 000000000000..ea4d20297bb9 --- /dev/null +++ b/test/libsolidity/syntaxTests/viewPureChecker/call_options_without_call.sol @@ -0,0 +1,9 @@ +contract C { + function f() external payable {} + function g(address a) external pure { + a.call{value: 42}; + } + function h() external view { + this.f{value: 42}; + } +} diff --git a/test/libsolidity/syntaxTests/viewPureChecker/eof/assembly.sol b/test/libsolidity/syntaxTests/viewPureChecker/eof/assembly.sol new file mode 100644 index 000000000000..fad9b7c1fa27 --- /dev/null +++ b/test/libsolidity/syntaxTests/viewPureChecker/eof/assembly.sol @@ -0,0 +1,29 @@ +contract C { + struct S { uint x; } + S s; + function e() pure public { + assembly { mstore(keccak256(0, 20), mul(s.slot, 2)) } + } + function f() pure public { + uint x; + assembly { x := 7 } + } + function g() view public { + assembly { for {} 1 { pop(sload(0)) } { } pop(calldataload(0)) } + } + function h() view public { + assembly { function g() { pop(blockhash(20)) } } + } + function i() public { + assembly { pop(extcall(0, 1, 2, 3)) } + } + function k() public view { + assembly { pop(balance(0)) } + } + function l() public pure { + assembly { pop(calldataload(0)) } + } +} +// ==== +// bytecodeFormat: >=EOFv1 +// ---- diff --git a/test/libsolidity/syntaxTests/viewPureChecker/eof/builtin_functions.sol b/test/libsolidity/syntaxTests/viewPureChecker/eof/builtin_functions.sol new file mode 100644 index 000000000000..91ea709fe2a6 --- /dev/null +++ b/test/libsolidity/syntaxTests/viewPureChecker/eof/builtin_functions.sol @@ -0,0 +1,22 @@ +contract C { + function f() public { + payable(this).transfer(1); + require(payable(this).send(2)); + (bool success,) = address(this).delegatecall(""); + require(success); + (success,) = address(this).call(""); + require(success); + } + function g() pure public { + bytes32 x = keccak256("abc"); + bytes32 y = sha256("abc"); + address z = ecrecover(bytes32(uint256(1)), uint8(2), bytes32(uint256(3)), bytes32(uint256(4))); + require(true); + assert(true); + x; y; z; + } + receive() payable external {} +} +// ==== +// bytecodeFormat: >=EOFv1 +// ---- diff --git a/test/libsolidity/syntaxTests/viewPureChecker/eof/inline_assembly_instructions_allowed.sol b/test/libsolidity/syntaxTests/viewPureChecker/eof/inline_assembly_instructions_allowed.sol new file mode 100644 index 000000000000..81d0f4e565b5 --- /dev/null +++ b/test/libsolidity/syntaxTests/viewPureChecker/eof/inline_assembly_instructions_allowed.sol @@ -0,0 +1,86 @@ +contract C { + function f() public { + assembly { + stop() + pop(add(0, 1)) + pop(sub(0, 1)) + pop(mul(0, 1)) + pop(div(0, 1)) + pop(sdiv(0, 1)) + pop(mod(0, 1)) + pop(smod(0, 1)) + pop(exp(0, 1)) + pop(not(0)) + pop(lt(0, 1)) + pop(gt(0, 1)) + pop(slt(0, 1)) + pop(sgt(0, 1)) + pop(eq(0, 1)) + pop(iszero(0)) + pop(and(0, 1)) + pop(or(0, 1)) + pop(xor(0, 1)) + pop(byte(0, 1)) + pop(shl(0, 1)) + pop(shr(0, 1)) + pop(sar(0, 1)) + pop(addmod(0, 1, 2)) + pop(mulmod(0, 1, 2)) + pop(signextend(0, 1)) + pop(keccak256(0, 1)) + pop(0) + pop(mload(0)) + mstore(0, 1) + mstore8(0, 1) + pop(sload(0)) + sstore(0, 1) + pop(address()) + pop(balance(0)) + pop(selfbalance()) + pop(caller()) + pop(callvalue()) + pop(calldataload(0)) + pop(calldatasize()) + calldatacopy(0, 1, 2) + pop(returndatasize()) + returndatacopy(0, 1, 2) + pop(extcall(0, 1, 2, 3)) + pop(extdelegatecall(0, 1, 2)) + pop(extstaticcall(0, 1, 2)) + return(0, 1) + revert(0, 1) + invalid() + log0(0, 1) + log1(0, 1, 2) + log2(0, 1, 2, 3) + log3(0, 1, 2, 3, 4) + log4(0, 1, 2, 3, 4, 5) + pop(chainid()) + pop(basefee()) + pop(origin()) + pop(gasprice()) + pop(blockhash(0)) + pop(coinbase()) + pop(timestamp()) + pop(number()) + pop(prevrandao()) + + mcopy(1, 2, 3) + pop(blobhash(0)) + pop(blobbasefee()) + pop(tload(0)) + tstore(0, 0) + + // NOTE: msize() is allowed only with optimizer disabled + //pop(msize()) + } + } +} +// ==== +// bytecodeFormat: >=EOFv1 +// ---- +// Warning 2394: (1970-1976): Transient storage as defined by EIP-1153 can break the composability of smart contracts: Since transient storage is cleared only at the end of the transaction and not at the end of the outermost call frame to the contract within a transaction, your contract may unintentionally misbehave when invoked multiple times in a complex transaction. To avoid this, be sure to clear all transient storage at the end of any call to your contract. The use of transient storage for reentrancy guards that are cleared at the end of the call is safe. +// Warning 5740: (89-1400): Unreachable code. +// Warning 5740: (1413-1425): Unreachable code. +// Warning 5740: (1438-1447): Unreachable code. +// Warning 5740: (1460-1982): Unreachable code. diff --git a/test/libsolidity/syntaxTests/viewPureChecker/eof/inline_assembly_instructions_allowed_pure.sol b/test/libsolidity/syntaxTests/viewPureChecker/eof/inline_assembly_instructions_allowed_pure.sol new file mode 100644 index 000000000000..f3da4722ff7d --- /dev/null +++ b/test/libsolidity/syntaxTests/viewPureChecker/eof/inline_assembly_instructions_allowed_pure.sol @@ -0,0 +1,85 @@ +contract C { + function f() public pure { + assembly { + stop() + pop(add(0, 1)) + pop(sub(0, 1)) + pop(mul(0, 1)) + pop(div(0, 1)) + pop(sdiv(0, 1)) + pop(mod(0, 1)) + pop(smod(0, 1)) + pop(exp(0, 1)) + pop(not(0)) + pop(lt(0, 1)) + pop(gt(0, 1)) + pop(slt(0, 1)) + pop(sgt(0, 1)) + pop(eq(0, 1)) + pop(iszero(0)) + pop(and(0, 1)) + pop(or(0, 1)) + pop(xor(0, 1)) + pop(byte(0, 1)) + pop(shl(0, 1)) + pop(shr(0, 1)) + pop(sar(0, 1)) + pop(addmod(0, 1, 2)) + pop(mulmod(0, 1, 2)) + pop(signextend(0, 1)) + pop(keccak256(0, 1)) + pop(0) + pop(mload(0)) + mstore(0, 1) + mstore8(0, 1) + //pop(sload(0)) + //sstore(0, 1) + //pop(address()) + //pop(balance(0)) + //pop(selfbalance()) + //pop(caller()) + //pop(callvalue()) + pop(calldataload(0)) + pop(calldatasize()) + calldatacopy(0, 1, 2) + pop(returndatasize()) + returndatacopy(0, 1, 2) + //pop(extcall(0, 1, 2, 3)) + //pop(extdelegatecall(0, 1, 2)) + //pop(extstaticcall(0, 1, 2)) + return(0, 1) + revert(0, 1) + invalid() + //log0(0, 1) + //log1(0, 1, 2) + //log2(0, 1, 2, 3) + //log3(0, 1, 2, 3, 4) + //log4(0, 1, 2, 3, 4, 5) + //pop(chainid()) + //pop(basefee()) + //pop(origin()) + //pop(gasprice()) + //pop(blockhash(0)) + //pop(coinbase()) + //pop(timestamp()) + //pop(number()) + //pop(prevrandao()) + //pop(gaslimit()) + mcopy(1, 2, 3) + //pop(blobhash(0)) + //pop(blobbasefee()) + //pop(tload(0)) + //tstore(0, 1) + + // NOTE: msize() is allowed only with optimizer disabled + //pop(msize()) + } + } +} +// ==== +// bytecodeFormat: >=EOFv1 +// ---- +// Warning 5740: (94-1425): Unreachable code. +// Warning 5740: (1438-1450): Unreachable code. +// Warning 5740: (1463-1472): Unreachable code. +// Warning 5740: (1939-1953): Unreachable code. diff --git a/test/libsolidity/syntaxTests/viewPureChecker/eof/inline_assembly_instructions_allowed_view.sol b/test/libsolidity/syntaxTests/viewPureChecker/eof/inline_assembly_instructions_allowed_view.sol new file mode 100644 index 000000000000..d1a5be03601e --- /dev/null +++ b/test/libsolidity/syntaxTests/viewPureChecker/eof/inline_assembly_instructions_allowed_view.sol @@ -0,0 +1,85 @@ +contract C { + function f() public view { + assembly { + stop() + pop(add(0, 1)) + pop(sub(0, 1)) + pop(mul(0, 1)) + pop(div(0, 1)) + pop(sdiv(0, 1)) + pop(mod(0, 1)) + pop(smod(0, 1)) + pop(exp(0, 1)) + pop(not(0)) + pop(lt(0, 1)) + pop(gt(0, 1)) + pop(slt(0, 1)) + pop(sgt(0, 1)) + pop(eq(0, 1)) + pop(iszero(0)) + pop(and(0, 1)) + pop(or(0, 1)) + pop(xor(0, 1)) + pop(byte(0, 1)) + pop(shl(0, 1)) + pop(shr(0, 1)) + pop(sar(0, 1)) + pop(addmod(0, 1, 2)) + pop(mulmod(0, 1, 2)) + pop(signextend(0, 1)) + pop(keccak256(0, 1)) + pop(0) + pop(mload(0)) + mstore(0, 1) + mstore8(0, 1) + pop(sload(0)) + //sstore(0, 1) + pop(address()) + pop(balance(0)) + pop(selfbalance()) + pop(caller()) + pop(callvalue()) + pop(calldataload(0)) + pop(calldatasize()) + calldatacopy(0, 1, 2) + pop(returndatasize()) + returndatacopy(0, 1, 2) + //pop(extcall(0, 1, 2, 3)) + //pop(extdelegatecall(0, 1, 2)) + pop(extstaticcall(0, 1, 2)) + return(0, 1) + revert(0, 1) + invalid() + //log0(0, 1) + //log1(0, 1, 2) + //log2(0, 1, 2, 3) + //log3(0, 1, 2, 3, 4) + //log4(0, 1, 2, 3, 4, 5) + pop(chainid()) + pop(basefee()) + pop(origin()) + pop(gasprice()) + pop(blockhash(0)) + pop(coinbase()) + pop(timestamp()) + pop(number()) + pop(prevrandao()) + pop(gaslimit()) + mcopy(1, 2, 3) + pop(blobhash(0)) + pop(blobbasefee()) + pop(tload(0)) + //tstore(0, 1) + + // NOTE: msize() is allowed only with optimizer disabled + //pop(msize()) + } + } +} +// ==== +// bytecodeFormat: >=EOFv1 +// ---- +// Warning 5740: (94-1411): Unreachable code. +// Warning 5740: (1424-1436): Unreachable code. +// Warning 5740: (1449-1458): Unreachable code. +// Warning 5740: (1626-2005): Unreachable code. diff --git a/test/libsolidity/syntaxTests/viewPureChecker/eof/inline_assembly_instructions_disallowed.sol b/test/libsolidity/syntaxTests/viewPureChecker/eof/inline_assembly_instructions_disallowed.sol new file mode 100644 index 000000000000..e65ea26bd97e --- /dev/null +++ b/test/libsolidity/syntaxTests/viewPureChecker/eof/inline_assembly_instructions_disallowed.sol @@ -0,0 +1,28 @@ +// TODO: eofcreate, returncontract and auxdataloadn are for now disallowed in inline assembly. They need proper design on language level +contract C { + function f() public { + assembly { + linkersymbol("x") + memoryguard(0) + verbatim_1i_1o(hex"600202", 0) + + pop(eofcreate("a", 0, 0, 0, 0)) + returncontract("a", 0, 0, 0) + pop(auxdataloadn(0)) + + pop(msize()) + } + } +} +// ==== +// bytecodeFormat: >=EOFv1 +// ---- +// SyntaxError 6553: (184-449): The msize instruction cannot be used when the Yul optimizer is activated because it can change its semantics. Either disable the Yul optimizer or do not use the instruction. +// DeclarationError 4619: (207-219): Function "linkersymbol" not found. +// DeclarationError 4619: (237-248): Function "memoryguard" not found. +// DeclarationError 4619: (264-278): Function "verbatim_1i_1o" not found. +// DeclarationError 4619: (312-321): Function "eofcreate" not found. +// TypeError 3950: (312-338): Expected expression to evaluate to one value, but got 0 values instead. +// DeclarationError 4619: (352-366): Function "returncontract" not found. +// DeclarationError 4619: (397-409): Function "auxdataloadn" not found. +// TypeError 3950: (397-412): Expected expression to evaluate to one value, but got 0 values instead. diff --git a/test/libsolidity/syntaxTests/viewPureChecker/eof/inline_assembly_instructions_disallowed_pure.sol b/test/libsolidity/syntaxTests/viewPureChecker/eof/inline_assembly_instructions_disallowed_pure.sol new file mode 100644 index 000000000000..19342ec194c4 --- /dev/null +++ b/test/libsolidity/syntaxTests/viewPureChecker/eof/inline_assembly_instructions_disallowed_pure.sol @@ -0,0 +1,71 @@ +contract C { + function f() public pure { + assembly { + pop(sload(0)) + sstore(0, 1) + pop(address()) + pop(balance(0)) + pop(caller()) + pop(callvalue()) + pop(extcall(0, 1, 2, 3)) + pop(extstaticcall(0, 1, 2)) + pop(extdelegatecall(0, 1, 2)) + log0(0, 1) + log1(0, 1, 2) + log2(0, 1, 2, 3) + log3(0, 1, 2, 3, 4) + log4(0, 1, 2, 3, 4, 5) + pop(origin()) + pop(gasprice()) + pop(blockhash(0)) + pop(coinbase()) + pop(timestamp()) + pop(number()) + pop(gaslimit()) + pop(blobhash(0)) + pop(blobbasefee()) + pop(tload(0)) + tstore(0, 0) + pop(selfbalance()) + pop(chainid()) + pop(basefee()) + pop(prevrandao()) + + // This one is disallowed too but the error suppresses other errors. + //pop(msize()) + } + } +} +// ==== +// bytecodeFormat: >=EOFv1 +// ---- +// Warning 2394: (781-787): Transient storage as defined by EIP-1153 can break the composability of smart contracts: Since transient storage is cleared only at the end of the transaction and not at the end of the outermost call frame to the contract within a transaction, your contract may unintentionally misbehave when invoked multiple times in a complex transaction. To avoid this, be sure to clear all transient storage at the end of any call to your contract. The use of transient storage for reentrancy guards that are cleared at the end of the call is safe. +// TypeError 2527: (79-87): Function declared as pure, but this expression (potentially) reads from the environment or state and thus requires "view". +// TypeError 8961: (101-113): Function cannot be declared as pure because this expression (potentially) modifies the state. +// TypeError 2527: (130-139): Function declared as pure, but this expression (potentially) reads from the environment or state and thus requires "view". +// TypeError 2527: (157-167): Function declared as pure, but this expression (potentially) reads from the environment or state and thus requires "view". +// TypeError 2527: (185-193): Function declared as pure, but this expression (potentially) reads from the environment or state and thus requires "view". +// TypeError 2527: (211-222): Function declared as pure, but this expression (potentially) reads from the environment or state and thus requires "view". +// TypeError 8961: (240-259): Function cannot be declared as pure because this expression (potentially) modifies the state. +// TypeError 2527: (277-299): Function declared as pure, but this expression (potentially) reads from the environment or state and thus requires "view". +// TypeError 8961: (317-341): Function cannot be declared as pure because this expression (potentially) modifies the state. +// TypeError 8961: (355-365): Function cannot be declared as pure because this expression (potentially) modifies the state. +// TypeError 8961: (378-391): Function cannot be declared as pure because this expression (potentially) modifies the state. +// TypeError 8961: (404-420): Function cannot be declared as pure because this expression (potentially) modifies the state. +// TypeError 8961: (433-452): Function cannot be declared as pure because this expression (potentially) modifies the state. +// TypeError 8961: (465-487): Function cannot be declared as pure because this expression (potentially) modifies the state. +// TypeError 2527: (504-512): Function declared as pure, but this expression (potentially) reads from the environment or state and thus requires "view". +// TypeError 2527: (530-540): Function declared as pure, but this expression (potentially) reads from the environment or state and thus requires "view". +// TypeError 2527: (558-570): Function declared as pure, but this expression (potentially) reads from the environment or state and thus requires "view". +// TypeError 2527: (588-598): Function declared as pure, but this expression (potentially) reads from the environment or state and thus requires "view". +// TypeError 2527: (616-627): Function declared as pure, but this expression (potentially) reads from the environment or state and thus requires "view". +// TypeError 2527: (645-653): Function declared as pure, but this expression (potentially) reads from the environment or state and thus requires "view". +// TypeError 2527: (671-681): Function declared as pure, but this expression (potentially) reads from the environment or state and thus requires "view". +// TypeError 2527: (699-710): Function declared as pure, but this expression (potentially) reads from the environment or state and thus requires "view". +// TypeError 2527: (728-741): Function declared as pure, but this expression (potentially) reads from the environment or state and thus requires "view". +// TypeError 2527: (759-767): Function declared as pure, but this expression (potentially) reads from the environment or state and thus requires "view". +// TypeError 8961: (781-793): Function cannot be declared as pure because this expression (potentially) modifies the state. +// TypeError 2527: (810-823): Function declared as pure, but this expression (potentially) reads from the environment or state and thus requires "view". +// TypeError 2527: (841-850): Function declared as pure, but this expression (potentially) reads from the environment or state and thus requires "view". +// TypeError 2527: (868-877): Function declared as pure, but this expression (potentially) reads from the environment or state and thus requires "view". +// TypeError 2527: (895-907): Function declared as pure, but this expression (potentially) reads from the environment or state and thus requires "view". diff --git a/test/libsolidity/syntaxTests/viewPureChecker/eof/inline_assembly_instructions_disallowed_view.sol b/test/libsolidity/syntaxTests/viewPureChecker/eof/inline_assembly_instructions_disallowed_view.sol new file mode 100644 index 000000000000..f8e9bc3ef136 --- /dev/null +++ b/test/libsolidity/syntaxTests/viewPureChecker/eof/inline_assembly_instructions_disallowed_view.sol @@ -0,0 +1,28 @@ +contract C { + function f() public view { + assembly { + sstore(0, 1) + pop(extcall(0, 1, 2, 3)) + pop(extdelegatecall(0, 1, 2)) + log0(0, 1) + log1(0, 1, 2) + log2(0, 1, 2, 3) + log3(0, 1, 2, 3, 4) + log4(0, 1, 2, 3, 4, 5) + + // This one is disallowed too but the error suppresses other errors. + //pop(msize()) + } + } +} +// ==== +// bytecodeFormat: >=EOFv1 +// ---- +// TypeError 8961: (75-87): Function cannot be declared as view because this expression (potentially) modifies the state. +// TypeError 8961: (104-123): Function cannot be declared as view because this expression (potentially) modifies the state. +// TypeError 8961: (141-165): Function cannot be declared as view because this expression (potentially) modifies the state. +// TypeError 8961: (179-189): Function cannot be declared as view because this expression (potentially) modifies the state. +// TypeError 8961: (202-215): Function cannot be declared as view because this expression (potentially) modifies the state. +// TypeError 8961: (228-244): Function cannot be declared as view because this expression (potentially) modifies the state. +// TypeError 8961: (257-276): Function cannot be declared as view because this expression (potentially) modifies the state. +// TypeError 8961: (289-311): Function cannot be declared as view because this expression (potentially) modifies the state. diff --git a/test/libsolidity/syntaxTests/viewPureChecker/gas_value_without_call.sol b/test/libsolidity/syntaxTests/viewPureChecker/gas_value_without_call.sol index 41120bf08111..f0bfba70ce31 100644 --- a/test/libsolidity/syntaxTests/viewPureChecker/gas_value_without_call.sol +++ b/test/libsolidity/syntaxTests/viewPureChecker/gas_value_without_call.sol @@ -11,4 +11,6 @@ contract C { this.f{gas: 42}; } } +// ==== +// bytecodeFormat: legacy // ---- diff --git a/test/libsolidity/syntaxTests/viewPureChecker/gas_with_call_nonpayable.sol b/test/libsolidity/syntaxTests/viewPureChecker/gas_with_call_nonpayable.sol index 65030cb30729..77956ffac02a 100644 --- a/test/libsolidity/syntaxTests/viewPureChecker/gas_with_call_nonpayable.sol +++ b/test/libsolidity/syntaxTests/viewPureChecker/gas_with_call_nonpayable.sol @@ -7,6 +7,8 @@ contract C { this.h{gas: 42}(); } } +// ==== +// bytecodeFormat: legacy // ---- // TypeError 8961: (90-109): Function cannot be declared as view because this expression (potentially) modifies the state. // TypeError 8961: (180-197): Function cannot be declared as view because this expression (potentially) modifies the state. diff --git a/test/libsolidity/syntaxTests/viewPureChecker/inline_assembly_instructions_allowed.sol b/test/libsolidity/syntaxTests/viewPureChecker/inline_assembly_instructions_allowed.sol index 886d6de0ce2f..680a8f85f2f7 100644 --- a/test/libsolidity/syntaxTests/viewPureChecker/inline_assembly_instructions_allowed.sol +++ b/test/libsolidity/syntaxTests/viewPureChecker/inline_assembly_instructions_allowed.sol @@ -84,6 +84,7 @@ contract C { } // ==== // EVMVersion: >=paris +// bytecodeFormat: legacy // ---- // Warning 1699: (1754-1766): "selfdestruct" has been deprecated. Note that, starting from the Cancun hard fork, the underlying opcode no longer deletes the code and data associated with an account and only transfers its Ether to the beneficiary, unless executed in the same transaction in which the contract was created (see EIP-6780). Any use in newly deployed contracts is strongly discouraged even if the new behavior is taken into account. Future changes to the EVM might further reduce the functionality of the opcode. // Warning 5740: (89-1716): Unreachable code. diff --git a/test/libsolidity/syntaxTests/viewPureChecker/inline_assembly_instructions_allowed_pure.sol b/test/libsolidity/syntaxTests/viewPureChecker/inline_assembly_instructions_allowed_pure.sol index 16c75d6f7291..5268f7a98e0b 100644 --- a/test/libsolidity/syntaxTests/viewPureChecker/inline_assembly_instructions_allowed_pure.sol +++ b/test/libsolidity/syntaxTests/viewPureChecker/inline_assembly_instructions_allowed_pure.sol @@ -83,6 +83,7 @@ contract C { } // ==== // EVMVersion: >=london +// bytecodeFormat: legacy // ---- // Warning 5740: (94-1755): Unreachable code. // Warning 5740: (1768-1780): Unreachable code. diff --git a/test/libsolidity/syntaxTests/viewPureChecker/inline_assembly_instructions_allowed_view.sol b/test/libsolidity/syntaxTests/viewPureChecker/inline_assembly_instructions_allowed_view.sol index 0bb92c1fd2fa..e2fa70102dfa 100644 --- a/test/libsolidity/syntaxTests/viewPureChecker/inline_assembly_instructions_allowed_view.sol +++ b/test/libsolidity/syntaxTests/viewPureChecker/inline_assembly_instructions_allowed_view.sol @@ -84,6 +84,7 @@ contract C { } // ==== // EVMVersion: >=paris +// bytecodeFormat: legacy // ---- // Warning 5740: (94-1733): Unreachable code. // Warning 5740: (1746-1758): Unreachable code. diff --git a/test/libsolidity/syntaxTests/viewPureChecker/inline_assembly_instructions_disallowed.sol b/test/libsolidity/syntaxTests/viewPureChecker/inline_assembly_instructions_disallowed.sol index 992a51ad2a28..ff557e6865f7 100644 --- a/test/libsolidity/syntaxTests/viewPureChecker/inline_assembly_instructions_disallowed.sol +++ b/test/libsolidity/syntaxTests/viewPureChecker/inline_assembly_instructions_disallowed.sol @@ -15,6 +15,8 @@ contract C { } } } +// ==== +// bytecodeFormat: legacy // ---- // SyntaxError 6553: (47-362): The msize instruction cannot be used when the Yul optimizer is activated because it can change its semantics. Either disable the Yul optimizer or do not use the instruction. // DeclarationError 4619: (70-78): Function "datasize" not found. diff --git a/test/libsolidity/syntaxTests/viewPureChecker/inline_assembly_instructions_disallowed_pure.sol b/test/libsolidity/syntaxTests/viewPureChecker/inline_assembly_instructions_disallowed_pure.sol index 665a17eebf63..91be09f58f22 100644 --- a/test/libsolidity/syntaxTests/viewPureChecker/inline_assembly_instructions_disallowed_pure.sol +++ b/test/libsolidity/syntaxTests/viewPureChecker/inline_assembly_instructions_disallowed_pure.sol @@ -34,6 +34,8 @@ contract C { } } } +// ==== +// bytecodeFormat: legacy // ---- // Warning 1699: (498-510): "selfdestruct" has been deprecated. Note that, starting from the Cancun hard fork, the underlying opcode no longer deletes the code and data associated with an account and only transfers its Ether to the beneficiary, unless executed in the same transaction in which the contract was created (see EIP-6780). Any use in newly deployed contracts is strongly discouraged even if the new behavior is taken into account. Future changes to the EVM might further reduce the functionality of the opcode. // Warning 5740: (526-853): Unreachable code. diff --git a/test/libsolidity/syntaxTests/viewPureChecker/inline_assembly_instructions_disallowed_pure_byzantium.sol b/test/libsolidity/syntaxTests/viewPureChecker/inline_assembly_instructions_disallowed_pure_byzantium.sol index f0320d8b0835..ded86c88a9a3 100644 --- a/test/libsolidity/syntaxTests/viewPureChecker/inline_assembly_instructions_disallowed_pure_byzantium.sol +++ b/test/libsolidity/syntaxTests/viewPureChecker/inline_assembly_instructions_disallowed_pure_byzantium.sol @@ -7,5 +7,6 @@ contract C { } // ==== // EVMVersion: >=byzantium +// bytecodeFormat: legacy // ---- // TypeError 2527: (79-107): Function declared as pure, but this expression (potentially) reads from the environment or state and thus requires "view". diff --git a/test/libsolidity/syntaxTests/viewPureChecker/inline_assembly_instructions_disallowed_pure_constantinople.sol b/test/libsolidity/syntaxTests/viewPureChecker/inline_assembly_instructions_disallowed_pure_constantinople.sol index 30210efc32fa..47826724e8e6 100644 --- a/test/libsolidity/syntaxTests/viewPureChecker/inline_assembly_instructions_disallowed_pure_constantinople.sol +++ b/test/libsolidity/syntaxTests/viewPureChecker/inline_assembly_instructions_disallowed_pure_constantinople.sol @@ -8,6 +8,7 @@ contract C { } // ==== // EVMVersion: >=constantinople +// bytecodeFormat: legacy // ---- // TypeError 2527: (79-93): Function declared as pure, but this expression (potentially) reads from the environment or state and thus requires "view". // TypeError 8961: (111-130): Function cannot be declared as pure because this expression (potentially) modifies the state. diff --git a/test/libsolidity/syntaxTests/viewPureChecker/inline_assembly_instructions_disallowed_view.sol b/test/libsolidity/syntaxTests/viewPureChecker/inline_assembly_instructions_disallowed_view.sol index b2f241ff08c5..e2bf4c5d1f4b 100644 --- a/test/libsolidity/syntaxTests/viewPureChecker/inline_assembly_instructions_disallowed_view.sol +++ b/test/libsolidity/syntaxTests/viewPureChecker/inline_assembly_instructions_disallowed_view.sol @@ -22,6 +22,7 @@ contract C { } // ==== // EVMVersion: >=london +// bytecodeFormat: legacy // ---- // Warning 1699: (308-320): "selfdestruct" has been deprecated. Note that, starting from the Cancun hard fork, the underlying opcode no longer deletes the code and data associated with an account and only transfers its Ether to the beneficiary, unless executed in the same transaction in which the contract was created (see EIP-6780). Any use in newly deployed contracts is strongly discouraged even if the new behavior is taken into account. Future changes to the EVM might further reduce the functionality of the opcode. // Warning 5740: (336-468): Unreachable code. diff --git a/test/libsolidity/syntaxTests/viewPureChecker/staticcall_gas_view.sol b/test/libsolidity/syntaxTests/viewPureChecker/staticcall_gas_view.sol index f49327a92114..832f60f97b56 100644 --- a/test/libsolidity/syntaxTests/viewPureChecker/staticcall_gas_view.sol +++ b/test/libsolidity/syntaxTests/viewPureChecker/staticcall_gas_view.sol @@ -8,4 +8,5 @@ contract C { } // ==== // EVMVersion: >=byzantium +// bytecodeFormat: legacy // ---- From 52a2557a8ccdade9022ba6566652ab0fc65b75ba Mon Sep 17 00:00:00 2001 From: rodiazet Date: Thu, 30 Jan 2025 15:16:54 +0100 Subject: [PATCH 0756/1022] eof: Make "jump too far" error testable. Add tests. --- libevmasm/Assembly.cpp | 9 ++++++++- .../sizeLimits/eof/bytecode_too_large.sol | 14 ++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 test/libsolidity/syntaxTests/sizeLimits/eof/bytecode_too_large.sol diff --git a/libevmasm/Assembly.cpp b/libevmasm/Assembly.cpp index ac9f14b15498..91beb9a7f3f2 100644 --- a/libevmasm/Assembly.cpp +++ b/libevmasm/Assembly.cpp @@ -1660,7 +1660,14 @@ LinkerObject const& Assembly::assembleEOF() const ptrdiff_t const relativeJumpOffset = static_cast(tagPos) - (static_cast(refPos) + 2); // This cannot happen in practice because we'll run into section size limit first. - solAssert(-0x8000 <= relativeJumpOffset && relativeJumpOffset <= 0x7FFF, "Relative jump too far"); + if (!(-0x8000 <= relativeJumpOffset && relativeJumpOffset <= 0x7FFF)) + // TODO: Include source location. Note that origin locations we have in debug data are + // not usable for error reporting when compiling pure Yul because they point at the optimized source. + throw Error( + 2703_error, + Error::Type::CodeGenerationError, + "Relative jump too far" + ); solAssert(relativeJumpOffset < -2 || 0 <= relativeJumpOffset, "Relative jump offset into immediate argument."); setBigEndianUint16(ret.bytecode, refPos, static_cast(static_cast(relativeJumpOffset))); } diff --git a/test/libsolidity/syntaxTests/sizeLimits/eof/bytecode_too_large.sol b/test/libsolidity/syntaxTests/sizeLimits/eof/bytecode_too_large.sol new file mode 100644 index 000000000000..e7c369577ce8 --- /dev/null +++ b/test/libsolidity/syntaxTests/sizeLimits/eof/bytecode_too_large.sol @@ -0,0 +1,14 @@ +// TODO: Change to proper error when all optimizations implemented for EOF +pragma abicoder v2; + +contract test { + function f() public pure returns (string memory ret) { + // 27000 bytes long data + ret = "........................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................"; + } +} +// ==== +// EVMVersion: >=cancun +// bytecodeFormat: >=EOFv1 +// ---- +// CodeGenerationError 2703: (96-27229): Relative jump too far From aa3fe8556d8b11dcbf7f9020e61e6fc3224a6b53 Mon Sep 17 00:00:00 2001 From: r0qs Date: Thu, 30 Jan 2025 17:03:50 +0100 Subject: [PATCH 0757/1022] Fix wrong comment about blobhash behavior --- .../inlineAssembly/blobhash_index_exceeding_blob_count.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/libsolidity/semanticTests/inlineAssembly/blobhash_index_exceeding_blob_count.sol b/test/libsolidity/semanticTests/inlineAssembly/blobhash_index_exceeding_blob_count.sol index 7063978c5c1b..50a2ea7081d4 100644 --- a/test/libsolidity/semanticTests/inlineAssembly/blobhash_index_exceeding_blob_count.sol +++ b/test/libsolidity/semanticTests/inlineAssembly/blobhash_index_exceeding_blob_count.sol @@ -1,7 +1,7 @@ contract C { function f() public view returns (bytes32 ret) { assembly { - // EIP-4844 specifies that if `index < len(tx.blob_versioned_hashes)`, `blobhash(index)` should return 0. + // EIP-4844 specifies that if `index >= len(tx.blob_versioned_hashes)`, `blobhash(index)` should return 0. // Thus, as we injected only two blob hashes in the transaction context in EVMHost, // the return value of the function below MUST be zero. ret := blobhash(2) From 89fb22463b30fe15dd2014c824a822b53df96f6f Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Thu, 30 Jan 2025 16:07:32 +0100 Subject: [PATCH 0758/1022] Bump resource class for t_ems_ext_edr from small to medium --- .circleci/config.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 0c4e65954f5f..0f75e76cd40b 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1397,11 +1397,12 @@ jobs: - matrix_notify_failure_unless_pr t_ems_ext_edr: - <<: *base_node_small + # Runs out of memory on the small instance + <<: *base_ubuntu2404 docker: - image: cimg/rust:1.79.0-node environment: - <<: *base_node_small_env + <<: *base_ubuntu2404_env EDR_TESTS_SOLC_PATH: /tmp/workspace/soljson.js steps: - checkout From 7add03e281df8d960eabaf5420c6b8220e1ab7a5 Mon Sep 17 00:00:00 2001 From: Martin Blicha Date: Mon, 27 Jan 2025 17:40:18 +0100 Subject: [PATCH 0759/1022] SMTChecker: Put all information regarding transaction data in one place --- libsolidity/formal/Predicate.cpp | 17 +-------- libsolidity/formal/SymbolicState.h | 22 +----------- libsolidity/formal/SymbolicTypes.cpp | 35 +++++++++++++++++++ libsolidity/formal/SymbolicTypes.h | 2 ++ .../special/tx_data_immutable.sol | 12 ++++--- 5 files changed, 47 insertions(+), 41 deletions(-) diff --git a/libsolidity/formal/Predicate.cpp b/libsolidity/formal/Predicate.cpp index 5cac3a6a9230..fe7c03fe1238 100644 --- a/libsolidity/formal/Predicate.cpp +++ b/libsolidity/formal/Predicate.cpp @@ -489,22 +489,7 @@ std::map Predicate::expressionSubstitution(smtutil::Ex std::map> Predicate::readTxVars(smtutil::Expression const& _tx) const { - std::map const txVars{ - {"block.basefee", TypeProvider::uint256()}, - {"block.chainid", TypeProvider::uint256()}, - {"block.coinbase", TypeProvider::address()}, - {"block.prevrandao", TypeProvider::uint256()}, - {"block.gaslimit", TypeProvider::uint256()}, - {"block.number", TypeProvider::uint256()}, - {"block.timestamp", TypeProvider::uint256()}, - {"blockhash", TypeProvider::array(DataLocation::Memory, TypeProvider::uint256())}, - {"msg.data", TypeProvider::array(DataLocation::CallData)}, - {"msg.sender", TypeProvider::address()}, - {"msg.sig", TypeProvider::fixedBytes(4)}, - {"msg.value", TypeProvider::uint256()}, - {"tx.gasprice", TypeProvider::uint256()}, - {"tx.origin", TypeProvider::address()} - }; + std::map const txVars = transactionMemberTypes(); std::map> vars; for (auto&& [i, v]: txVars | ranges::views::enumerate) vars.emplace(v.first, expressionToString(_tx.arguments.at(i), v.second)); diff --git a/libsolidity/formal/SymbolicState.h b/libsolidity/formal/SymbolicState.h index ac018df1acf8..20bfb3f00cf2 100644 --- a/libsolidity/formal/SymbolicState.h +++ b/libsolidity/formal/SymbolicState.h @@ -236,27 +236,7 @@ class SymbolicState /// and the element is a tuple containing the state variables of that contract. std::unique_ptr m_state; - BlockchainVariable m_tx{ - "tx", - { - {"block.basefee", smtutil::SortProvider::uintSort}, - {"block.chainid", smtutil::SortProvider::uintSort}, - {"block.coinbase", smt::smtSort(*TypeProvider::address())}, - {"block.prevrandao", smtutil::SortProvider::uintSort}, - {"block.gaslimit", smtutil::SortProvider::uintSort}, - {"block.number", smtutil::SortProvider::uintSort}, - {"block.timestamp", smtutil::SortProvider::uintSort}, - {"blockhash", std::make_shared(smtutil::SortProvider::uintSort, smtutil::SortProvider::uintSort)}, - // TODO gasleft - {"msg.data", smt::smtSort(*TypeProvider::bytesMemory())}, - {"msg.sender", smt::smtSort(*TypeProvider::address())}, - {"msg.sig", smtutil::SortProvider::uintSort}, - {"msg.value", smtutil::SortProvider::uintSort}, - {"tx.gasprice", smtutil::SortProvider::uintSort}, - {"tx.origin", smt::smtSort(*TypeProvider::address())} - }, - m_context - }; + BlockchainVariable m_tx{"tx", transactionMemberSorts(), m_context}; BlockchainVariable m_crypto{ "crypto", diff --git a/libsolidity/formal/SymbolicTypes.cpp b/libsolidity/formal/SymbolicTypes.cpp index 72739bccfb91..0428ffaa2cc0 100644 --- a/libsolidity/formal/SymbolicTypes.cpp +++ b/libsolidity/formal/SymbolicTypes.cpp @@ -667,4 +667,39 @@ smtutil::Expression assignMember(smtutil::Expression const _tuple, std::map transactionMemberTypes() +{ + // TODO: gasleft + return { + {"block.basefee", TypeProvider::uint256()}, + {"block.chainid", TypeProvider::uint256()}, + {"block.coinbase", TypeProvider::address()}, + {"block.prevrandao", TypeProvider::uint256()}, + {"block.gaslimit", TypeProvider::uint256()}, + {"block.number", TypeProvider::uint256()}, + {"block.timestamp", TypeProvider::uint256()}, + {"blockhash", TypeProvider::array(DataLocation::Memory, TypeProvider::uint256())}, + {"msg.data", TypeProvider::bytesCalldata()}, + {"msg.sender", TypeProvider::address()}, + {"msg.sig", TypeProvider::fixedBytes(4)}, + {"msg.value", TypeProvider::uint256()}, + {"tx.gasprice", TypeProvider::uint256()}, + {"tx.origin", TypeProvider::address()} + }; +} + +std::map transactionMemberSorts() +{ + // NOTE: `blockhash` needs proper `ArraySort`, `smtSort` wraps array types into array+length pair + auto toSort = [&](auto const& entry) -> SortPointer + { + if (entry.first == "blockhash") + return std::make_shared(SortProvider::uintSort, SortProvider::uintSort); + return smtSort(*entry.second); + }; + auto types = transactionMemberTypes(); + return types + | ranges::views::transform([&](auto const& entry) { return std::make_pair(entry.first, toSort(entry)); }) + | ranges::to>(); +} } diff --git a/libsolidity/formal/SymbolicTypes.h b/libsolidity/formal/SymbolicTypes.h index 747e27b7e372..d38dcc04514a 100644 --- a/libsolidity/formal/SymbolicTypes.h +++ b/libsolidity/formal/SymbolicTypes.h @@ -86,4 +86,6 @@ std::optional symbolicTypeConversion(frontend::Type const* smtutil::Expression member(smtutil::Expression const& _tuple, std::string const& _member); smtutil::Expression assignMember(smtutil::Expression const _tuple, std::map const& _values); +std::map transactionMemberTypes(); +std::map transactionMemberSorts(); } diff --git a/test/libsolidity/smtCheckerTests/special/tx_data_immutable.sol b/test/libsolidity/smtCheckerTests/special/tx_data_immutable.sol index c66ce565393a..21a924b1fa78 100644 --- a/test/libsolidity/smtCheckerTests/special/tx_data_immutable.sol +++ b/test/libsolidity/smtCheckerTests/special/tx_data_immutable.sol @@ -1,5 +1,6 @@ contract C { bytes32 bhash; + uint bfee; address coin; uint dif; uint prevrandao; @@ -15,6 +16,7 @@ contract C { function f() public payable { bhash = blockhash(12); + bfee = block.basefee; coin = block.coinbase; dif = block.difficulty; prevrandao = block.prevrandao; @@ -31,6 +33,7 @@ contract C { fi(); assert(bhash == blockhash(12)); + assert(bfee == block.basefee); assert(coin == block.coinbase); assert(dif == block.difficulty); assert(prevrandao == block.prevrandao); @@ -47,6 +50,7 @@ contract C { function fi() internal view { assert(bhash == blockhash(12)); + assert(bfee == block.basefee); assert(coin == block.coinbase); assert(dif == block.difficulty); assert(prevrandao == block.prevrandao); @@ -64,7 +68,7 @@ contract C { // ==== // SMTEngine: all // ---- -// Warning 8417: (293-309): Since the VM version paris, "difficulty" was replaced by "prevrandao", which now returns a random number based on the beacon chain. -// Warning 8417: (645-661): Since the VM version paris, "difficulty" was replaced by "prevrandao", which now returns a random number based on the beacon chain. -// Warning 8417: (1127-1143): Since the VM version paris, "difficulty" was replaced by "prevrandao", which now returns a random number based on the beacon chain. -// Info 1391: CHC: 26 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. +// Warning 8417: (329-345): Since the VM version paris, "difficulty" was replaced by "prevrandao", which now returns a random number based on the beacon chain. +// Warning 8417: (714-730): Since the VM version paris, "difficulty" was replaced by "prevrandao", which now returns a random number based on the beacon chain. +// Warning 8417: (1229-1245): Since the VM version paris, "difficulty" was replaced by "prevrandao", which now returns a random number based on the beacon chain. +// Info 1391: CHC: 28 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. From c02be83df79ace9e037b268b53c8cded41e5876a Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Fri, 31 Jan 2025 08:17:25 +0100 Subject: [PATCH 0760/1022] Remove cxx20 header containing reference implementation of erase_if --- libsolutil/CMakeLists.txt | 1 - libsolutil/cxx20.h | 64 ------------------- .../backends/evm/ControlFlowGraphBuilder.cpp | 5 +- .../evm/OptimizedEVMCodeTransform.cpp | 1 - .../evm/SSAControlFlowGraphBuilder.cpp | 3 +- libyul/backends/evm/StackLayoutGenerator.cpp | 4 +- libyul/optimiser/DataFlowAnalyzer.cpp | 21 +++--- 7 files changed, 14 insertions(+), 85 deletions(-) delete mode 100644 libsolutil/cxx20.h diff --git a/libsolutil/CMakeLists.txt b/libsolutil/CMakeLists.txt index aac943517e02..1ec12051a619 100644 --- a/libsolutil/CMakeLists.txt +++ b/libsolutil/CMakeLists.txt @@ -7,7 +7,6 @@ set(sources CommonData.h CommonIO.cpp CommonIO.h - cxx20.h DisjointSet.cpp DisjointSet.h DominatorFinder.h diff --git a/libsolutil/cxx20.h b/libsolutil/cxx20.h deleted file mode 100644 index a21a73e681af..000000000000 --- a/libsolutil/cxx20.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - This file is part of solidity. - - solidity is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - solidity is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with solidity. If not, see . -*/ -// SPDX-License-Identifier: GPL-3.0 -#pragma once - -#include - -// Contains polyfills of STL functions and algorithms that will become available in C++20. -namespace solidity::cxx20 -{ - -// Taken from https://en.cppreference.com/w/cpp/container/map/erase_if. -template -typename std::map::size_type erase_if(std::map& _c, Pred _pred) -{ - auto old_size = _c.size(); - for (auto i = _c.begin(), last = _c.end(); i != last;) - if (_pred(*i)) - i = _c.erase(i); - else - ++i; - return old_size - _c.size(); -} - -// Taken from https://en.cppreference.com/w/cpp/container/unordered_map/erase_if. -template -typename std::unordered_map::size_type -erase_if(std::unordered_map& _c, Pred _pred) -{ - auto old_size = _c.size(); - for (auto i = _c.begin(), last = _c.end(); i != last;) - if (_pred(*i)) - i = _c.erase(i); - else - ++i; - return old_size - _c.size(); -} - -// Taken from https://en.cppreference.com/w/cpp/container/vector/erase2 -template -constexpr typename std::vector::size_type -erase_if(std::vector& c, Pred pred) -{ - auto it = std::remove_if(c.begin(), c.end(), pred); - auto r = std::distance(it, c.end()); - c.erase(it, c.end()); - return static_cast::size_type>(r); -} - -} diff --git a/libyul/backends/evm/ControlFlowGraphBuilder.cpp b/libyul/backends/evm/ControlFlowGraphBuilder.cpp index 3986d54a0a36..d9456e4c32d0 100644 --- a/libyul/backends/evm/ControlFlowGraphBuilder.cpp +++ b/libyul/backends/evm/ControlFlowGraphBuilder.cpp @@ -26,7 +26,6 @@ #include #include -#include #include #include @@ -85,7 +84,7 @@ void cleanUnreachable(CFG& _cfg) // Remove all entries from unreachable nodes from the graph. for (CFG::BasicBlock* node: reachabilityCheck.visited) - cxx20::erase_if(node->entries, [&](CFG::BasicBlock* entry) -> bool { + std::erase_if(node->entries, [&](CFG::BasicBlock* entry) -> bool { return !reachabilityCheck.visited.count(entry); }); @@ -95,7 +94,7 @@ void cleanUnreachable(CFG& _cfg) }), _cfg.functions.end()); // Remove functionInfos which are never referenced. - cxx20::erase_if(_cfg.functionInfo, [&](auto const& entry) -> bool { + std::erase_if(_cfg.functionInfo, [&](auto const& entry) -> bool { return !reachabilityCheck.visited.count(entry.second.entry); }); } diff --git a/libyul/backends/evm/OptimizedEVMCodeTransform.cpp b/libyul/backends/evm/OptimizedEVMCodeTransform.cpp index 139df8af6098..bd5c55a3cd73 100644 --- a/libyul/backends/evm/OptimizedEVMCodeTransform.cpp +++ b/libyul/backends/evm/OptimizedEVMCodeTransform.cpp @@ -26,7 +26,6 @@ #include #include -#include #include #include diff --git a/libyul/backends/evm/SSAControlFlowGraphBuilder.cpp b/libyul/backends/evm/SSAControlFlowGraphBuilder.cpp index 4597c56a5917..bf8cfd92a802 100644 --- a/libyul/backends/evm/SSAControlFlowGraphBuilder.cpp +++ b/libyul/backends/evm/SSAControlFlowGraphBuilder.cpp @@ -29,7 +29,6 @@ #include #include #include -#include #include #include @@ -197,7 +196,7 @@ void SSAControlFlowGraphBuilder::cleanUnreachable() it = block.entries.erase(it); for (auto phi: block.phis) if (auto* phiInfo = std::get_if(&m_graph.valueInfo(phi))) - cxx20::erase_if(phiInfo->arguments, [&](SSACFG::ValueId _arg) { + std::erase_if(phiInfo->arguments, [&](SSACFG::ValueId _arg) { if (isUnreachableValue(_arg)) { maybeTrivialPhi.insert(phi); diff --git a/libyul/backends/evm/StackLayoutGenerator.cpp b/libyul/backends/evm/StackLayoutGenerator.cpp index 3d1d5f7b0d76..ecaa4198bd52 100644 --- a/libyul/backends/evm/StackLayoutGenerator.cpp +++ b/libyul/backends/evm/StackLayoutGenerator.cpp @@ -26,8 +26,6 @@ #include #include -#include -#include #include #include @@ -577,7 +575,7 @@ Stack StackLayoutGenerator::combineStack(Stack const& _stack1, Stack const& _sta for (auto slot: stack2Tail) if (!util::contains(candidate, slot)) candidate.emplace_back(slot); - cxx20::erase_if(candidate, [](StackSlot const& slot) { + std::erase_if(candidate, [](StackSlot const& slot) { return std::holds_alternative(slot) || std::holds_alternative(slot); }); diff --git a/libyul/optimiser/DataFlowAnalyzer.cpp b/libyul/optimiser/DataFlowAnalyzer.cpp index ac08fb0be196..b11282bb176b 100644 --- a/libyul/optimiser/DataFlowAnalyzer.cpp +++ b/libyul/optimiser/DataFlowAnalyzer.cpp @@ -32,7 +32,6 @@ #include #include -#include #include @@ -68,7 +67,7 @@ void DataFlowAnalyzer::operator()(ExpressionStatement& _statement) if (auto vars = isSimpleStore(StoreLoadLocation::Storage, _statement)) { ASTModifier::operator()(_statement); - cxx20::erase_if(m_state.environment.storage, mapTuple([&](auto&& key, auto&& value) { + std::erase_if(m_state.environment.storage, mapTuple([&](auto&& key, auto&& value) { return !m_knowledgeBase.knownToBeDifferent(vars->first, key) && vars->second != value; @@ -79,7 +78,7 @@ void DataFlowAnalyzer::operator()(ExpressionStatement& _statement) else if (auto vars = isSimpleStore(StoreLoadLocation::Memory, _statement)) { ASTModifier::operator()(_statement); - cxx20::erase_if(m_state.environment.memory, mapTuple([&](auto&& key, auto&& /* value */) { + std::erase_if(m_state.environment.memory, mapTuple([&](auto&& key, auto&& /* value */) { return !m_knowledgeBase.knownToBeDifferentByAtLeast32(vars->first, key); })); // TODO erase keccak knowledge, but in a more clever way @@ -272,14 +271,14 @@ void DataFlowAnalyzer::handleAssignment(std::set const& _variables, Exp // assignment to slot denoted by "name" m_state.environment.storage.erase(name); // assignment to slot contents denoted by "name" - cxx20::erase_if(m_state.environment.storage, mapTuple([&name](auto&& /* key */, auto&& value) { return value == name; })); + std::erase_if(m_state.environment.storage, mapTuple([&name](auto&& /* key */, auto&& value) { return value == name; })); // assignment to slot denoted by "name" m_state.environment.memory.erase(name); // assignment to slot contents denoted by "name" - cxx20::erase_if(m_state.environment.keccak, [&name](auto&& _item) { + std::erase_if(m_state.environment.keccak, [&name](auto&& _item) { return _item.first.first == name || _item.first.second == name || _item.second == name; }); - cxx20::erase_if(m_state.environment.memory, mapTuple([&name](auto&& /* key */, auto&& value) { return value == name; })); + std::erase_if(m_state.environment.memory, mapTuple([&name](auto&& /* key */, auto&& value) { return value == name; })); } } @@ -337,9 +336,9 @@ void DataFlowAnalyzer::clearValues(std::set _variables) auto eraseCondition = mapTuple([&_variables](auto&& key, auto&& value) { return _variables.count(key) || _variables.count(value); }); - cxx20::erase_if(m_state.environment.storage, eraseCondition); - cxx20::erase_if(m_state.environment.memory, eraseCondition); - cxx20::erase_if(m_state.environment.keccak, [&_variables](auto&& _item) { + std::erase_if(m_state.environment.storage, eraseCondition); + std::erase_if(m_state.environment.memory, eraseCondition); + std::erase_if(m_state.environment.keccak, [&_variables](auto&& _item) { return _variables.count(_item.first.first) || _variables.count(_item.first.second) || @@ -464,7 +463,7 @@ void DataFlowAnalyzer::joinKnowledge(Environment const& _olderEnvironment) return; joinKnowledgeHelper(m_state.environment.storage, _olderEnvironment.storage); joinKnowledgeHelper(m_state.environment.memory, _olderEnvironment.memory); - cxx20::erase_if(m_state.environment.keccak, mapTuple([&_olderEnvironment](auto&& key, auto&& currentValue) { + std::erase_if(m_state.environment.keccak, mapTuple([&_olderEnvironment](auto&& key, auto&& currentValue) { YulName const* oldValue = valueOrNullptr(_olderEnvironment.keccak, key); return !oldValue || *oldValue != currentValue; })); @@ -479,7 +478,7 @@ void DataFlowAnalyzer::joinKnowledgeHelper( // This also works for memory because _older is an "older version" // of m_state.environment.memory and thus any overlapping write would have cleared the keys // that are not known to be different inside m_state.environment.memory already. - cxx20::erase_if(_this, mapTuple([&_older](auto&& key, auto&& currentValue){ + std::erase_if(_this, mapTuple([&_older](auto&& key, auto&& currentValue){ YulName const* oldValue = valueOrNullptr(_older, key); return !oldValue || *oldValue != currentValue; })); From 8fe3961654c5031c418ec2df4fb0ef45373c9386 Mon Sep 17 00:00:00 2001 From: Martin Blicha Date: Mon, 27 Jan 2025 23:18:40 +0100 Subject: [PATCH 0761/1022] SMTChecker: Add support for block.blobbasefee and blobhash() We overapproximate the behaviour here in the same way as for `block.basefee` and `blockhash`. For the first we only add the basic domain constraints and the second is modelled as an uninterpreted function. We also model the fact that the number of blobs in transaction is limited by returning 0 from blobhash() if the argument is greater or equal to the limit. The current limit is 6, but it will soon be increased to 9 in pectra update. Since we overapproximate the behaviour anyway, we can use the pectra limit immediately. --- Changelog.md | 1 + docs/smtchecker.rst | 6 +- libsolidity/formal/BMC.cpp | 1 + libsolidity/formal/CHC.cpp | 1 + libsolidity/formal/SMTEncoder.cpp | 15 ++++ libsolidity/formal/SMTEncoder.h | 1 + libsolidity/formal/SymbolicState.cpp | 6 ++ libsolidity/formal/SymbolicState.h | 3 + libsolidity/formal/SymbolicTypes.cpp | 6 +- scripts/error_codes.py | 1 + .../model_checker_print_query_all/err | 10 +-- .../model_checker_print_query_bmc/err | 4 +- .../model_checker_print_query_chc/err | 6 +- .../err | 2 +- .../err | 2 +- .../err | 7 +- .../model_checker_show_unproved_true_bmc/err | 7 +- .../output.json | 86 +++++++++---------- .../output.json | 14 +-- .../output.json | 20 ++--- .../output.json | 10 +-- .../output.json | 10 +-- .../output.json | 10 +-- .../output.json | 25 ++---- .../output.json | 25 ++---- .../output.json | 14 +-- .../compound_bitwise_or_uint_3.sol | 2 +- .../external_calls/external_safe.sol | 5 +- .../operators/compound_bitwise_or_uint_3.sol | 2 +- ...rator_matches_equivalent_function_call.sol | 4 +- .../special/blobhash_beyond_limit.sol | 11 +++ .../special/tx_data_immutable.sol | 24 ++++-- .../special/tx_data_immutable_fail.sol | 86 +++++++++++-------- .../types/fixed_bytes_access_3.sol | 4 +- 34 files changed, 229 insertions(+), 202 deletions(-) create mode 100644 test/libsolidity/smtCheckerTests/special/blobhash_beyond_limit.sol diff --git a/Changelog.md b/Changelog.md index 6caef22b1557..cceec2a73de0 100644 --- a/Changelog.md +++ b/Changelog.md @@ -5,6 +5,7 @@ Language Features: Compiler Features: * Error Reporting: Errors reported during code generation now point at the location of the contract when more fine-grained location is not available. + * SMTChecker: Support `block.blobbasefee` and `blobhash`. * SMTChecker: Z3 is now a runtime dependency, not a build dependency (except for emscripten build). * Yul Parser: Make name clash with a builtin a non-fatal error. diff --git a/docs/smtchecker.rst b/docs/smtchecker.rst index 7db996fafc88..5de941bf2706 100644 --- a/docs/smtchecker.rst +++ b/docs/smtchecker.rst @@ -931,9 +931,9 @@ the arguments. +-----------------------------------+--------------------------------------+ |``addmod``, ``mulmod`` |Supported precisely. | +-----------------------------------+--------------------------------------+ -|``gasleft``, ``blockhash``, |Abstracted with UF. | -|``keccak256``, ``ecrecover`` | | -|``ripemd160`` | | +|``gasleft``, ``blobhash``, |Abstracted with UF. | +|``blockhash``, ``keccak256``, | | +|``ecrecover``, ``ripemd160`` | | +-----------------------------------+--------------------------------------+ |pure functions without |Abstracted with UF | |implementation (external or | | diff --git a/libsolidity/formal/BMC.cpp b/libsolidity/formal/BMC.cpp index d7bad10e7b35..86c7eb7a89f8 100644 --- a/libsolidity/formal/BMC.cpp +++ b/libsolidity/formal/BMC.cpp @@ -664,6 +664,7 @@ void BMC::endVisit(FunctionCall const& _funCall) case FunctionType::Kind::ECRecover: case FunctionType::Kind::SHA256: case FunctionType::Kind::RIPEMD160: + case FunctionType::Kind::BlobHash: case FunctionType::Kind::BlockHash: case FunctionType::Kind::AddMod: case FunctionType::Kind::MulMod: diff --git a/libsolidity/formal/CHC.cpp b/libsolidity/formal/CHC.cpp index 9f23aff6fb67..bd0b3f4022d9 100644 --- a/libsolidity/formal/CHC.cpp +++ b/libsolidity/formal/CHC.cpp @@ -641,6 +641,7 @@ void CHC::endVisit(FunctionCall const& _funCall) case FunctionType::Kind::ECRecover: case FunctionType::Kind::SHA256: case FunctionType::Kind::RIPEMD160: + case FunctionType::Kind::BlobHash: case FunctionType::Kind::BlockHash: case FunctionType::Kind::AddMod: case FunctionType::Kind::MulMod: diff --git a/libsolidity/formal/SMTEncoder.cpp b/libsolidity/formal/SMTEncoder.cpp index d7b23156383e..2fecb734a630 100644 --- a/libsolidity/formal/SMTEncoder.cpp +++ b/libsolidity/formal/SMTEncoder.cpp @@ -679,6 +679,9 @@ void SMTEncoder::endVisit(FunctionCall const& _funCall) case FunctionType::Kind::BlockHash: defineExpr(_funCall, state().blockhash(expr(*_funCall.arguments().at(0)))); break; + case FunctionType::Kind::BlobHash: + visitBlobHash(_funCall); + break; case FunctionType::Kind::AddMod: case FunctionType::Kind::MulMod: visitAddMulMod(_funCall); @@ -893,6 +896,18 @@ void SMTEncoder::visitGasLeft(FunctionCall const& _funCall) m_context.addAssertion(symbolicVar->currentValue() <= symbolicVar->valueAtIndex(index - 1)); } +void SMTEncoder::visitBlobHash(FunctionCall const& _funCall) +{ + constexpr unsigned BLOB_TRANSACTION_LIMIT = 9; // Since pectra + auto indexExpr = expr(*_funCall.arguments().at(0)); + auto valueExpr = smtutil::Expression::ite( + indexExpr >= BLOB_TRANSACTION_LIMIT, + smtutil::Expression(u256(0)), + state().blobhash(indexExpr) + ); + defineExpr(_funCall, std::move(valueExpr)); +} + void SMTEncoder::visitAddMulMod(FunctionCall const& _funCall) { auto const& funType = dynamic_cast(*_funCall.expression().annotation().type); diff --git a/libsolidity/formal/SMTEncoder.h b/libsolidity/formal/SMTEncoder.h index f01f6802c337..d79ae8f82aaa 100644 --- a/libsolidity/formal/SMTEncoder.h +++ b/libsolidity/formal/SMTEncoder.h @@ -229,6 +229,7 @@ class SMTEncoder: public ASTConstVisitor void visitBytesConcat(FunctionCall const& _funCall); void visitCryptoFunction(FunctionCall const& _funCall); void visitGasLeft(FunctionCall const& _funCall); + void visitBlobHash(FunctionCall const& _funCall); virtual void visitAddMulMod(FunctionCall const& _funCall); void visitWrapUnwrap(FunctionCall const& _funCall); void visitObjectCreation(FunctionCall const& _funCall); diff --git a/libsolidity/formal/SymbolicState.cpp b/libsolidity/formal/SymbolicState.cpp index bf835b801d21..492e0055b008 100644 --- a/libsolidity/formal/SymbolicState.cpp +++ b/libsolidity/formal/SymbolicState.cpp @@ -96,6 +96,11 @@ smtutil::Expression SymbolicState::balance(smtutil::Expression _address) const return smtutil::Expression::select(balances(), std::move(_address)); } +smtutil::Expression SymbolicState::blobhash(smtutil::Expression _blobIndex) const +{ + return smtutil::Expression::select(m_tx.member("blobhash"), std::move(_blobIndex)); +} + smtutil::Expression SymbolicState::blockhash(smtutil::Expression _blockNumber) const { return smtutil::Expression::select(m_tx.member("blockhash"), std::move(_blockNumber)); @@ -222,6 +227,7 @@ smtutil::Expression SymbolicState::txTypeConstraints() const return evmParisConstraints() && smt::symbolicUnknownConstraints(m_tx.member("block.basefee"), TypeProvider::uint256()) && + smt::symbolicUnknownConstraints(m_tx.member("block.blobbasefee"), TypeProvider::uint256()) && smt::symbolicUnknownConstraints(m_tx.member("block.chainid"), TypeProvider::uint256()) && smt::symbolicUnknownConstraints(m_tx.member("block.coinbase"), TypeProvider::address()) && smt::symbolicUnknownConstraints(m_tx.member("block.prevrandao"), TypeProvider::uint256()) && diff --git a/libsolidity/formal/SymbolicState.h b/libsolidity/formal/SymbolicState.h index 20bfb3f00cf2..ca40e695d521 100644 --- a/libsolidity/formal/SymbolicState.h +++ b/libsolidity/formal/SymbolicState.h @@ -65,8 +65,10 @@ class BlockchainVariable * - array of address => bool representing whether an address is used by a contract * - storage of contracts * - block and transaction properties, represented as a tuple of: + * - blobhash * - blockhash * - block basefee + * - block blobbasefee * - block chainid * - block coinbase * - block gaslimit @@ -148,6 +150,7 @@ class SymbolicState smtutil::Expression txFunctionConstraints(FunctionDefinition const& _function) const; smtutil::Expression txTypeConstraints() const; smtutil::Expression txNonPayableConstraint() const; + smtutil::Expression blobhash(smtutil::Expression _blobIndex) const; smtutil::Expression blockhash(smtutil::Expression _blockNumber) const; smtutil::Expression evmParisConstraints() const; //@} diff --git a/libsolidity/formal/SymbolicTypes.cpp b/libsolidity/formal/SymbolicTypes.cpp index 0428ffaa2cc0..738a48f706c3 100644 --- a/libsolidity/formal/SymbolicTypes.cpp +++ b/libsolidity/formal/SymbolicTypes.cpp @@ -672,12 +672,14 @@ std::map transactionMemberTypes() // TODO: gasleft return { {"block.basefee", TypeProvider::uint256()}, + {"block.blobbasefee", TypeProvider::uint256()}, {"block.chainid", TypeProvider::uint256()}, {"block.coinbase", TypeProvider::address()}, {"block.prevrandao", TypeProvider::uint256()}, {"block.gaslimit", TypeProvider::uint256()}, {"block.number", TypeProvider::uint256()}, {"block.timestamp", TypeProvider::uint256()}, + {"blobhash", TypeProvider::array(DataLocation::Memory, TypeProvider::uint256())}, {"blockhash", TypeProvider::array(DataLocation::Memory, TypeProvider::uint256())}, {"msg.data", TypeProvider::bytesCalldata()}, {"msg.sender", TypeProvider::address()}, @@ -690,10 +692,10 @@ std::map transactionMemberTypes() std::map transactionMemberSorts() { - // NOTE: `blockhash` needs proper `ArraySort`, `smtSort` wraps array types into array+length pair + // NOTE: `blockhash` and `blobhash` need proper `ArraySort`, `smtSort()` wraps array types into array+length pair auto toSort = [&](auto const& entry) -> SortPointer { - if (entry.first == "blockhash") + if (entry.first == "blockhash" || entry.first == "blobhash") return std::make_shared(SortProvider::uintSort, SortProvider::uintSort); return smtSort(*entry.second); }; diff --git a/scripts/error_codes.py b/scripts/error_codes.py index 813d08330e31..50021d986478 100755 --- a/scripts/error_codes.py +++ b/scripts/error_codes.py @@ -205,6 +205,7 @@ def examine_id_coverage(top_dir, source_id_to_file_names, new_ids_only=False): "7053", # Unimplemented feature error (parsing stage), currently has no tests "2339", # SMTChecker, covered by CL tests "6240", # SMTChecker, covered by CL tests + "2788", # SMTChecker: BMC: verification condition(s) could not be proved "1733", # AsmAnalysis: expecting bool expression (everything is implicitly bool without types in Yul) "9547", # AsmAnalysis: assigning incompatible types in Yul (whitelisted as there are currently no types) } diff --git a/test/cmdlineTests/model_checker_print_query_all/err b/test/cmdlineTests/model_checker_print_query_all/err index 76dff6664b80..92a3b7f7b50f 100644 --- a/test/cmdlineTests/model_checker_print_query_all/err +++ b/test/cmdlineTests/model_checker_print_query_all/err @@ -8,7 +8,7 @@ Info: CHC: Requested query: (declare-datatypes ((|state_type| 0)) (((|state_type| (|balances| (Array Int Int)))))) (declare-fun |interface_0_C_16| (Int |abi_type| |crypto_type| |state_type|) Bool) (declare-fun |nondet_interface_1_C_16| (Int Int |abi_type| |crypto_type| |state_type| |state_type|) Bool) -(declare-datatypes ((|tx_type| 0)) (((|tx_type| (|block.basefee| Int) (|block.chainid| Int) (|block.coinbase| Int) (|block.gaslimit| Int) (|block.number| Int) (|block.prevrandao| Int) (|block.timestamp| Int) (|blockhash| (Array Int Int)) (|msg.data| |bytes_tuple|) (|msg.sender| Int) (|msg.sig| Int) (|msg.value| Int) (|tx.gasprice| Int) (|tx.origin| Int))))) +(declare-datatypes ((|tx_type| 0)) (((|tx_type| (|blobhash| (Array Int Int)) (|block.basefee| Int) (|block.blobbasefee| Int) (|block.chainid| Int) (|block.coinbase| Int) (|block.gaslimit| Int) (|block.number| Int) (|block.prevrandao| Int) (|block.timestamp| Int) (|blockhash| (Array Int Int)) (|msg.data| |bytes_tuple|) (|msg.sender| Int) (|msg.sig| Int) (|msg.value| Int) (|tx.gasprice| Int) (|tx.origin| Int))))) (declare-fun |summary_constructor_2_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool) (assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (this_0 Int)) (=> (= error_0 0) (nondet_interface_1_C_16 error_0 this_0 abi_0 crypto_0 state_0 state_0))) @@ -45,7 +45,7 @@ Info: CHC: Requested query: (block_9_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1)) ) (assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_1 Int)) -(=> (and (and (block_9_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (summary_3_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_2 state_3) (and (= state_2 (|state_type| (store (|balances| state_1) this_0 (+ (select (|balances| state_1) this_0) funds_2_0)))) (and (and (>= (+ (select (|balances| state_1) this_0) funds_2_0) 0) (<= (+ (select (|balances| state_1) this_0) funds_2_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935)) (and (>= funds_2_0 (|msg.value| tx_0)) (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (and (and (and (and (and (= (|msg.value| tx_0) 0) (= (|msg.sig| tx_0) 638722032)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 0) 38)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 1) 18)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 2) 31)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 3) 240)) (>= (|bytes_tuple_accessor_length| (|msg.data| tx_0)) 4))) (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true))))))) true) (summary_4_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_3))) +(=> (and (and (block_9_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (summary_3_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_2 state_3) (and (= state_2 (|state_type| (store (|balances| state_1) this_0 (+ (select (|balances| state_1) this_0) funds_2_0)))) (and (and (>= (+ (select (|balances| state_1) this_0) funds_2_0) 0) (<= (+ (select (|balances| state_1) this_0) funds_2_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935)) (and (>= funds_2_0 (|msg.value| tx_0)) (and (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.blobbasefee| tx_0) 0) (<= (|block.blobbasefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (and (and (and (and (and (= (|msg.value| tx_0) 0) (= (|msg.sig| tx_0) 638722032)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 0) 38)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 1) 18)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 2) 31)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 3) 240)) (>= (|bytes_tuple_accessor_length| (|msg.data| tx_0)) 4))) (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true))))))) true) (summary_4_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_3))) ) (assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|)) (=> (and (and (interface_0_C_16 this_0 abi_0 crypto_0 state_0) true) (and (summary_4_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (= error_0 0))) (interface_0_C_16 this_0 abi_0 crypto_0 state_1))) @@ -73,7 +73,7 @@ Info: CHC: Requested query: (=> (and (and (implicit_constructor_entry_13_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (and (= error_1 0) (and (contract_initializer_10_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2) true))) true) (summary_constructor_2_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_2))) ) (assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|)) -(=> (and (and (summary_constructor_2_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (= (|msg.value| tx_0) 0)) (= error_0 0))) (interface_0_C_16 this_0 abi_0 crypto_0 state_1))) +(=> (and (and (summary_constructor_2_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) (and (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.blobbasefee| tx_0) 0) (<= (|block.blobbasefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (= (|msg.value| tx_0) 0)) (= error_0 0))) (interface_0_C_16 this_0 abi_0 crypto_0 state_1))) ) (declare-fun |error_target_3| () Bool) (assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|)) @@ -96,7 +96,7 @@ Info: BMC: Requested query: (declare-fun |error_0| () Int) (declare-fun |this_0| () Int) (declare-datatypes ((|bytes_tuple| 0)) (((|bytes_tuple| (|bytes_tuple_accessor_array| (Array Int Int)) (|bytes_tuple_accessor_length| Int))))) -(declare-datatypes ((|tx_type| 0)) (((|tx_type| (|block.basefee| Int) (|block.chainid| Int) (|block.coinbase| Int) (|block.gaslimit| Int) (|block.number| Int) (|block.prevrandao| Int) (|block.timestamp| Int) (|blockhash| (Array Int Int)) (|msg.data| |bytes_tuple|) (|msg.sender| Int) (|msg.sig| Int) (|msg.value| Int) (|tx.gasprice| Int) (|tx.origin| Int))))) +(declare-datatypes ((|tx_type| 0)) (((|tx_type| (|blobhash| (Array Int Int)) (|block.basefee| Int) (|block.blobbasefee| Int) (|block.chainid| Int) (|block.coinbase| Int) (|block.gaslimit| Int) (|block.number| Int) (|block.prevrandao| Int) (|block.timestamp| Int) (|blockhash| (Array Int Int)) (|msg.data| |bytes_tuple|) (|msg.sender| Int) (|msg.sig| Int) (|msg.value| Int) (|tx.gasprice| Int) (|tx.origin| Int))))) (declare-fun |tx_0| () |tx_type|) (declare-datatypes ((|ecrecover_input_type| 0)) (((|ecrecover_input_type| (|hash| Int) (|v| Int) (|r| Int) (|s| Int))))) (declare-datatypes ((|crypto_type| 0)) (((|crypto_type| (|ecrecover| (Array |ecrecover_input_type| Int)) (|keccak256| (Array |bytes_tuple| Int)) (|ripemd160| (Array |bytes_tuple| Int)) (|sha256| (Array |bytes_tuple| Int)))))) @@ -112,7 +112,7 @@ Info: BMC: Requested query: (declare-fun |expr_9_0| () Int) (declare-fun |expr_10_0| () Int) (declare-fun |expr_11_1| () Bool) -(assert (and (and (and true true) (and (= expr_11_1 (= expr_9_0 expr_10_0)) (and (=> (and true true) true) (and (= expr_10_0 0) (and (=> (and true true) (and (>= expr_9_0 0) (<= expr_9_0 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (= expr_9_0 x_5_1) (and (ite (and true true) (= x_5_1 expr_6_0) (= x_5_1 x_5_0)) (and (=> (and true true) true) (and (= expr_6_0 0) (and (= x_5_0 0) (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (and (and (and (and (and (= (|msg.value| tx_0) 0) (= (|msg.sig| tx_0) 638722032)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 0) 38)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 1) 18)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 2) 31)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 3) 240)) (>= (|bytes_tuple_accessor_length| (|msg.data| tx_0)) 4))) true))))))))))) (not expr_11_1))) +(assert (and (and (and true true) (and (= expr_11_1 (= expr_9_0 expr_10_0)) (and (=> (and true true) true) (and (= expr_10_0 0) (and (=> (and true true) (and (>= expr_9_0 0) (<= expr_9_0 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (= expr_9_0 x_5_1) (and (ite (and true true) (= x_5_1 expr_6_0) (= x_5_1 x_5_0)) (and (=> (and true true) true) (and (= expr_6_0 0) (and (= x_5_0 0) (and (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.blobbasefee| tx_0) 0) (<= (|block.blobbasefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (and (and (and (and (and (= (|msg.value| tx_0) 0) (= (|msg.sig| tx_0) 638722032)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 0) 38)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 1) 18)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 2) 31)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 3) 240)) (>= (|bytes_tuple_accessor_length| (|msg.data| tx_0)) 4))) true))))))))))) (not expr_11_1))) (declare-const |EVALEXPR_0| Int) (assert (= |EVALEXPR_0| x_5_1)) (check-sat) diff --git a/test/cmdlineTests/model_checker_print_query_bmc/err b/test/cmdlineTests/model_checker_print_query_bmc/err index 6fb8440b7b8b..efbc2a3aef9b 100644 --- a/test/cmdlineTests/model_checker_print_query_bmc/err +++ b/test/cmdlineTests/model_checker_print_query_bmc/err @@ -4,7 +4,7 @@ Info: BMC: Requested query: (declare-fun |error_0| () Int) (declare-fun |this_0| () Int) (declare-datatypes ((|bytes_tuple| 0)) (((|bytes_tuple| (|bytes_tuple_accessor_array| (Array Int Int)) (|bytes_tuple_accessor_length| Int))))) -(declare-datatypes ((|tx_type| 0)) (((|tx_type| (|block.basefee| Int) (|block.chainid| Int) (|block.coinbase| Int) (|block.gaslimit| Int) (|block.number| Int) (|block.prevrandao| Int) (|block.timestamp| Int) (|blockhash| (Array Int Int)) (|msg.data| |bytes_tuple|) (|msg.sender| Int) (|msg.sig| Int) (|msg.value| Int) (|tx.gasprice| Int) (|tx.origin| Int))))) +(declare-datatypes ((|tx_type| 0)) (((|tx_type| (|blobhash| (Array Int Int)) (|block.basefee| Int) (|block.blobbasefee| Int) (|block.chainid| Int) (|block.coinbase| Int) (|block.gaslimit| Int) (|block.number| Int) (|block.prevrandao| Int) (|block.timestamp| Int) (|blockhash| (Array Int Int)) (|msg.data| |bytes_tuple|) (|msg.sender| Int) (|msg.sig| Int) (|msg.value| Int) (|tx.gasprice| Int) (|tx.origin| Int))))) (declare-fun |tx_0| () |tx_type|) (declare-datatypes ((|ecrecover_input_type| 0)) (((|ecrecover_input_type| (|hash| Int) (|v| Int) (|r| Int) (|s| Int))))) (declare-datatypes ((|crypto_type| 0)) (((|crypto_type| (|ecrecover| (Array |ecrecover_input_type| Int)) (|keccak256| (Array |bytes_tuple| Int)) (|ripemd160| (Array |bytes_tuple| Int)) (|sha256| (Array |bytes_tuple| Int)))))) @@ -19,7 +19,7 @@ Info: BMC: Requested query: (declare-fun |expr_9_0| () Int) (declare-fun |expr_10_0| () Int) (declare-fun |expr_11_1| () Bool) -(assert (and (and (and true true) (and (= expr_11_1 (= expr_9_0 expr_10_0)) (and (=> (and true true) true) (and (= expr_10_0 0) (and (=> (and true true) (and (>= expr_9_0 0) (<= expr_9_0 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (= expr_9_0 x_5_1) (and (ite (and true true) (= x_5_1 expr_6_0) (= x_5_1 x_5_0)) (and (=> (and true true) true) (and (= expr_6_0 0) (and (= x_5_0 0) (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (and (and (and (and (and (= (|msg.value| tx_0) 0) (= (|msg.sig| tx_0) 638722032)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 0) 38)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 1) 18)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 2) 31)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 3) 240)) (>= (|bytes_tuple_accessor_length| (|msg.data| tx_0)) 4))) true))))))))))) (not expr_11_1))) +(assert (and (and (and true true) (and (= expr_11_1 (= expr_9_0 expr_10_0)) (and (=> (and true true) true) (and (= expr_10_0 0) (and (=> (and true true) (and (>= expr_9_0 0) (<= expr_9_0 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (= expr_9_0 x_5_1) (and (ite (and true true) (= x_5_1 expr_6_0) (= x_5_1 x_5_0)) (and (=> (and true true) true) (and (= expr_6_0 0) (and (= x_5_0 0) (and (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.blobbasefee| tx_0) 0) (<= (|block.blobbasefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (and (and (and (and (and (= (|msg.value| tx_0) 0) (= (|msg.sig| tx_0) 638722032)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 0) 38)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 1) 18)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 2) 31)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 3) 240)) (>= (|bytes_tuple_accessor_length| (|msg.data| tx_0)) 4))) true))))))))))) (not expr_11_1))) (declare-const |EVALEXPR_0| Int) (assert (= |EVALEXPR_0| x_5_1)) (check-sat) diff --git a/test/cmdlineTests/model_checker_print_query_chc/err b/test/cmdlineTests/model_checker_print_query_chc/err index 28368f546205..9c18265be4e6 100644 --- a/test/cmdlineTests/model_checker_print_query_chc/err +++ b/test/cmdlineTests/model_checker_print_query_chc/err @@ -8,7 +8,7 @@ Info: CHC: Requested query: (declare-datatypes ((|state_type| 0)) (((|state_type| (|balances| (Array Int Int)))))) (declare-fun |interface_0_C_16| (Int |abi_type| |crypto_type| |state_type|) Bool) (declare-fun |nondet_interface_1_C_16| (Int Int |abi_type| |crypto_type| |state_type| |state_type|) Bool) -(declare-datatypes ((|tx_type| 0)) (((|tx_type| (|block.basefee| Int) (|block.chainid| Int) (|block.coinbase| Int) (|block.gaslimit| Int) (|block.number| Int) (|block.prevrandao| Int) (|block.timestamp| Int) (|blockhash| (Array Int Int)) (|msg.data| |bytes_tuple|) (|msg.sender| Int) (|msg.sig| Int) (|msg.value| Int) (|tx.gasprice| Int) (|tx.origin| Int))))) +(declare-datatypes ((|tx_type| 0)) (((|tx_type| (|blobhash| (Array Int Int)) (|block.basefee| Int) (|block.blobbasefee| Int) (|block.chainid| Int) (|block.coinbase| Int) (|block.gaslimit| Int) (|block.number| Int) (|block.prevrandao| Int) (|block.timestamp| Int) (|blockhash| (Array Int Int)) (|msg.data| |bytes_tuple|) (|msg.sender| Int) (|msg.sig| Int) (|msg.value| Int) (|tx.gasprice| Int) (|tx.origin| Int))))) (declare-fun |summary_constructor_2_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool) (assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (this_0 Int)) (=> (= error_0 0) (nondet_interface_1_C_16 error_0 this_0 abi_0 crypto_0 state_0 state_0))) @@ -45,7 +45,7 @@ Info: CHC: Requested query: (block_9_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1)) ) (assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_1 Int)) -(=> (and (and (block_9_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (summary_3_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_2 state_3) (and (= state_2 (|state_type| (store (|balances| state_1) this_0 (+ (select (|balances| state_1) this_0) funds_2_0)))) (and (and (>= (+ (select (|balances| state_1) this_0) funds_2_0) 0) (<= (+ (select (|balances| state_1) this_0) funds_2_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935)) (and (>= funds_2_0 (|msg.value| tx_0)) (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (and (and (and (and (and (= (|msg.value| tx_0) 0) (= (|msg.sig| tx_0) 638722032)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 0) 38)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 1) 18)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 2) 31)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 3) 240)) (>= (|bytes_tuple_accessor_length| (|msg.data| tx_0)) 4))) (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true))))))) true) (summary_4_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_3))) +(=> (and (and (block_9_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (summary_3_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_2 state_3) (and (= state_2 (|state_type| (store (|balances| state_1) this_0 (+ (select (|balances| state_1) this_0) funds_2_0)))) (and (and (>= (+ (select (|balances| state_1) this_0) funds_2_0) 0) (<= (+ (select (|balances| state_1) this_0) funds_2_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935)) (and (>= funds_2_0 (|msg.value| tx_0)) (and (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.blobbasefee| tx_0) 0) (<= (|block.blobbasefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (and (and (and (and (and (= (|msg.value| tx_0) 0) (= (|msg.sig| tx_0) 638722032)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 0) 38)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 1) 18)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 2) 31)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 3) 240)) (>= (|bytes_tuple_accessor_length| (|msg.data| tx_0)) 4))) (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true))))))) true) (summary_4_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_3))) ) (assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|)) (=> (and (and (interface_0_C_16 this_0 abi_0 crypto_0 state_0) true) (and (summary_4_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (= error_0 0))) (interface_0_C_16 this_0 abi_0 crypto_0 state_1))) @@ -73,7 +73,7 @@ Info: CHC: Requested query: (=> (and (and (implicit_constructor_entry_13_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (and (= error_1 0) (and (contract_initializer_10_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2) true))) true) (summary_constructor_2_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_2))) ) (assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|)) -(=> (and (and (summary_constructor_2_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (= (|msg.value| tx_0) 0)) (= error_0 0))) (interface_0_C_16 this_0 abi_0 crypto_0 state_1))) +(=> (and (and (summary_constructor_2_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) (and (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.blobbasefee| tx_0) 0) (<= (|block.blobbasefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (= (|msg.value| tx_0) 0)) (= error_0 0))) (interface_0_C_16 this_0 abi_0 crypto_0 state_1))) ) (declare-fun |error_target_3| () Bool) (assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|)) diff --git a/test/cmdlineTests/model_checker_show_unproved_default_all_engines/err b/test/cmdlineTests/model_checker_show_unproved_default_all_engines/err index 45c38ef3594a..486cd2c65899 100644 --- a/test/cmdlineTests/model_checker_show_unproved_default_all_engines/err +++ b/test/cmdlineTests/model_checker_show_unproved_default_all_engines/err @@ -1,3 +1,3 @@ Warning: CHC: 1 verification condition(s) could not be proved. Enable the model checker option "show unproved" to see all of them. Consider choosing a specific contract to be verified in order to reduce the solving problems. Consider increasing the timeout per query. -Warning: BMC: 1 verification condition(s) could not be proved. Enable the model checker option "show unproved" to see all of them. Consider choosing a specific contract to be verified in order to reduce the solving problems. Consider increasing the timeout per query. +Info: BMC: 1 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/cmdlineTests/model_checker_show_unproved_default_bmc/err b/test/cmdlineTests/model_checker_show_unproved_default_bmc/err index f8d0af2f4f72..21041fee1976 100644 --- a/test/cmdlineTests/model_checker_show_unproved_default_bmc/err +++ b/test/cmdlineTests/model_checker_show_unproved_default_bmc/err @@ -1 +1 @@ -Warning: BMC: 1 verification condition(s) could not be proved. Enable the model checker option "show unproved" to see all of them. Consider choosing a specific contract to be verified in order to reduce the solving problems. Consider increasing the timeout per query. +Info: BMC: 1 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/cmdlineTests/model_checker_show_unproved_true_all_engines/err b/test/cmdlineTests/model_checker_show_unproved_true_all_engines/err index 83864075dd74..7a338f614952 100644 --- a/test/cmdlineTests/model_checker_show_unproved_true_all_engines/err +++ b/test/cmdlineTests/model_checker_show_unproved_true_all_engines/err @@ -4,9 +4,4 @@ Warning: CHC: Assertion violation might happen here. 10 | assert(s.x > 0); | ^^^^^^^^^^^^^^^ -Warning: BMC: Assertion violation might happen here. - --> model_checker_show_unproved_true_all_engines/input.sol:10:9: - | -10 | assert(s.x > 0); - | ^^^^^^^^^^^^^^^ -Note: +Info: BMC: 1 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/cmdlineTests/model_checker_show_unproved_true_bmc/err b/test/cmdlineTests/model_checker_show_unproved_true_bmc/err index 84ada7873b07..21041fee1976 100644 --- a/test/cmdlineTests/model_checker_show_unproved_true_bmc/err +++ b/test/cmdlineTests/model_checker_show_unproved_true_bmc/err @@ -1,6 +1 @@ -Warning: BMC: Assertion violation might happen here. - --> model_checker_show_unproved_true_bmc/input.sol:10:9: - | -10 | assert(s.x > 0); - | ^^^^^^^^^^^^^^^ -Note: +Info: BMC: 1 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/cmdlineTests/standard_model_checker_print_query_all/output.json b/test/cmdlineTests/standard_model_checker_print_query_all/output.json index a800fb34d7b6..1108d790786a 100644 --- a/test/cmdlineTests/standard_model_checker_print_query_all/output.json +++ b/test/cmdlineTests/standard_model_checker_print_query_all/output.json @@ -1,36 +1,7 @@ { "auxiliaryInputRequested": { "smtlib2queries": { - "0x54683263097e1c4f5e0e75b68e4ebe3e4f7042f899198181df911c8196a1725b": "(set-option :produce-models true) -(set-option :timeout 1000) -(set-logic ALL) -(declare-fun |x_5_3| () Int) -(declare-fun |error_0| () Int) -(declare-fun |this_0| () Int) -(declare-datatypes ((|bytes_tuple| 0)) (((|bytes_tuple| (|bytes_tuple_accessor_array| (Array Int Int)) (|bytes_tuple_accessor_length| Int))))) -(declare-datatypes ((|tx_type| 0)) (((|tx_type| (|block.basefee| Int) (|block.chainid| Int) (|block.coinbase| Int) (|block.gaslimit| Int) (|block.number| Int) (|block.prevrandao| Int) (|block.timestamp| Int) (|blockhash| (Array Int Int)) (|msg.data| |bytes_tuple|) (|msg.sender| Int) (|msg.sig| Int) (|msg.value| Int) (|tx.gasprice| Int) (|tx.origin| Int))))) -(declare-fun |tx_0| () |tx_type|) -(declare-datatypes ((|ecrecover_input_type| 0)) (((|ecrecover_input_type| (|hash| Int) (|v| Int) (|r| Int) (|s| Int))))) -(declare-datatypes ((|crypto_type| 0)) (((|crypto_type| (|ecrecover| (Array |ecrecover_input_type| Int)) (|keccak256| (Array |bytes_tuple| Int)) (|ripemd160| (Array |bytes_tuple| Int)) (|sha256| (Array |bytes_tuple| Int)))))) -(declare-fun |crypto_0| () |crypto_type|) -(declare-datatypes ((|abi_type| 0)) (((|abi_type|)))) -(declare-fun |abi_0| () |abi_type|) -(declare-datatypes ((|state_type| 0)) (((|state_type| (|balances| (Array Int Int)))))) -(declare-fun |state_0| () |state_type|) -(declare-fun |x_5_4| () Int) -(declare-fun |x_5_0| () Int) -(declare-fun |expr_6_0| () Int) -(declare-fun |x_5_1| () Int) -(declare-fun |expr_9_0| () Int) -(declare-fun |expr_10_0| () Int) -(declare-fun |expr_11_1| () Bool) -(assert (and (and (and true true) (and (= expr_11_1 (= expr_9_0 expr_10_0)) (and (=> (and true true) true) (and (= expr_10_0 0) (and (=> (and true true) (and (>= expr_9_0 0) (<= expr_9_0 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (= expr_9_0 x_5_1) (and (ite (and true true) (= x_5_1 expr_6_0) (= x_5_1 x_5_0)) (and (=> (and true true) true) (and (= expr_6_0 0) (and (= x_5_0 0) (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (and (and (and (and (and (= (|msg.value| tx_0) 0) (= (|msg.sig| tx_0) 638722032)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 0) 38)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 1) 18)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 2) 31)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 3) 240)) (>= (|bytes_tuple_accessor_length| (|msg.data| tx_0)) 4))) true))))))))))) (not expr_11_1))) -(declare-const |EVALEXPR_0| Int) -(assert (= |EVALEXPR_0| x_5_1)) -(check-sat) -(get-value (|EVALEXPR_0| )) -", - "0x9cfcd53712a0be144c8e7983b3635498ead1af2624885fb89762eae8c43233e5": "(set-option :timeout 1000) + "0x89dce9b2e59f1b2d3445ec646e15e2609ff358edb66afa7227538979017e0f7b": "(set-option :timeout 1000) (set-logic HORN) (declare-datatypes ((|abi_type| 0)) (((|abi_type|)))) (declare-datatypes ((|ecrecover_input_type| 0)) (((|ecrecover_input_type| (|hash| Int) (|v| Int) (|r| Int) (|s| Int))))) @@ -39,7 +10,7 @@ (declare-datatypes ((|state_type| 0)) (((|state_type| (|balances| (Array Int Int)))))) (declare-fun |interface_0_C_16| (Int |abi_type| |crypto_type| |state_type|) Bool) (declare-fun |nondet_interface_1_C_16| (Int Int |abi_type| |crypto_type| |state_type| |state_type|) Bool) -(declare-datatypes ((|tx_type| 0)) (((|tx_type| (|block.basefee| Int) (|block.chainid| Int) (|block.coinbase| Int) (|block.gaslimit| Int) (|block.number| Int) (|block.prevrandao| Int) (|block.timestamp| Int) (|blockhash| (Array Int Int)) (|msg.data| |bytes_tuple|) (|msg.sender| Int) (|msg.sig| Int) (|msg.value| Int) (|tx.gasprice| Int) (|tx.origin| Int))))) +(declare-datatypes ((|tx_type| 0)) (((|tx_type| (|blobhash| (Array Int Int)) (|block.basefee| Int) (|block.blobbasefee| Int) (|block.chainid| Int) (|block.coinbase| Int) (|block.gaslimit| Int) (|block.number| Int) (|block.prevrandao| Int) (|block.timestamp| Int) (|blockhash| (Array Int Int)) (|msg.data| |bytes_tuple|) (|msg.sender| Int) (|msg.sig| Int) (|msg.value| Int) (|tx.gasprice| Int) (|tx.origin| Int))))) (declare-fun |summary_constructor_2_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool) (assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (this_0 Int)) (=> (= error_0 0) (nondet_interface_1_C_16 error_0 this_0 abi_0 crypto_0 state_0 state_0))) @@ -76,7 +47,7 @@ (block_9_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1)) ) (assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_1 Int)) -(=> (and (and (block_9_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (summary_3_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_2 state_3) (and (= state_2 (|state_type| (store (|balances| state_1) this_0 (+ (select (|balances| state_1) this_0) funds_2_0)))) (and (and (>= (+ (select (|balances| state_1) this_0) funds_2_0) 0) (<= (+ (select (|balances| state_1) this_0) funds_2_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935)) (and (>= funds_2_0 (|msg.value| tx_0)) (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (and (and (and (and (and (= (|msg.value| tx_0) 0) (= (|msg.sig| tx_0) 638722032)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 0) 38)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 1) 18)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 2) 31)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 3) 240)) (>= (|bytes_tuple_accessor_length| (|msg.data| tx_0)) 4))) (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true))))))) true) (summary_4_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_3))) +(=> (and (and (block_9_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (summary_3_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_2 state_3) (and (= state_2 (|state_type| (store (|balances| state_1) this_0 (+ (select (|balances| state_1) this_0) funds_2_0)))) (and (and (>= (+ (select (|balances| state_1) this_0) funds_2_0) 0) (<= (+ (select (|balances| state_1) this_0) funds_2_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935)) (and (>= funds_2_0 (|msg.value| tx_0)) (and (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.blobbasefee| tx_0) 0) (<= (|block.blobbasefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (and (and (and (and (and (= (|msg.value| tx_0) 0) (= (|msg.sig| tx_0) 638722032)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 0) 38)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 1) 18)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 2) 31)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 3) 240)) (>= (|bytes_tuple_accessor_length| (|msg.data| tx_0)) 4))) (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true))))))) true) (summary_4_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_3))) ) (assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|)) (=> (and (and (interface_0_C_16 this_0 abi_0 crypto_0 state_0) true) (and (summary_4_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (= error_0 0))) (interface_0_C_16 this_0 abi_0 crypto_0 state_1))) @@ -104,7 +75,7 @@ (=> (and (and (implicit_constructor_entry_13_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (and (= error_1 0) (and (contract_initializer_10_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2) true))) true) (summary_constructor_2_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_2))) ) (assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|)) -(=> (and (and (summary_constructor_2_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (= (|msg.value| tx_0) 0)) (= error_0 0))) (interface_0_C_16 this_0 abi_0 crypto_0 state_1))) +(=> (and (and (summary_constructor_2_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) (and (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.blobbasefee| tx_0) 0) (<= (|block.blobbasefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (= (|msg.value| tx_0) 0)) (= error_0 0))) (interface_0_C_16 this_0 abi_0 crypto_0 state_1))) ) (declare-fun |error_target_3| () Bool) (assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|)) @@ -113,6 +84,35 @@ (forall ((UNUSED Bool)) (=> error_target_3 false))) (check-sat) +", + "0xca8e4027f5350278d291f782ff3ec7a7f618e8a729beb4173e7dad3f008af497": "(set-option :produce-models true) +(set-option :timeout 1000) +(set-logic ALL) +(declare-fun |x_5_3| () Int) +(declare-fun |error_0| () Int) +(declare-fun |this_0| () Int) +(declare-datatypes ((|bytes_tuple| 0)) (((|bytes_tuple| (|bytes_tuple_accessor_array| (Array Int Int)) (|bytes_tuple_accessor_length| Int))))) +(declare-datatypes ((|tx_type| 0)) (((|tx_type| (|blobhash| (Array Int Int)) (|block.basefee| Int) (|block.blobbasefee| Int) (|block.chainid| Int) (|block.coinbase| Int) (|block.gaslimit| Int) (|block.number| Int) (|block.prevrandao| Int) (|block.timestamp| Int) (|blockhash| (Array Int Int)) (|msg.data| |bytes_tuple|) (|msg.sender| Int) (|msg.sig| Int) (|msg.value| Int) (|tx.gasprice| Int) (|tx.origin| Int))))) +(declare-fun |tx_0| () |tx_type|) +(declare-datatypes ((|ecrecover_input_type| 0)) (((|ecrecover_input_type| (|hash| Int) (|v| Int) (|r| Int) (|s| Int))))) +(declare-datatypes ((|crypto_type| 0)) (((|crypto_type| (|ecrecover| (Array |ecrecover_input_type| Int)) (|keccak256| (Array |bytes_tuple| Int)) (|ripemd160| (Array |bytes_tuple| Int)) (|sha256| (Array |bytes_tuple| Int)))))) +(declare-fun |crypto_0| () |crypto_type|) +(declare-datatypes ((|abi_type| 0)) (((|abi_type|)))) +(declare-fun |abi_0| () |abi_type|) +(declare-datatypes ((|state_type| 0)) (((|state_type| (|balances| (Array Int Int)))))) +(declare-fun |state_0| () |state_type|) +(declare-fun |x_5_4| () Int) +(declare-fun |x_5_0| () Int) +(declare-fun |expr_6_0| () Int) +(declare-fun |x_5_1| () Int) +(declare-fun |expr_9_0| () Int) +(declare-fun |expr_10_0| () Int) +(declare-fun |expr_11_1| () Bool) +(assert (and (and (and true true) (and (= expr_11_1 (= expr_9_0 expr_10_0)) (and (=> (and true true) true) (and (= expr_10_0 0) (and (=> (and true true) (and (>= expr_9_0 0) (<= expr_9_0 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (= expr_9_0 x_5_1) (and (ite (and true true) (= x_5_1 expr_6_0) (= x_5_1 x_5_0)) (and (=> (and true true) true) (and (= expr_6_0 0) (and (= x_5_0 0) (and (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.blobbasefee| tx_0) 0) (<= (|block.blobbasefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (and (and (and (and (and (= (|msg.value| tx_0) 0) (= (|msg.sig| tx_0) 638722032)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 0) 38)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 1) 18)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 2) 31)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 3) 240)) (>= (|bytes_tuple_accessor_length| (|msg.data| tx_0)) 4))) true))))))))))) (not expr_11_1))) +(declare-const |EVALEXPR_0| Int) +(assert (= |EVALEXPR_0| x_5_1)) +(check-sat) +(get-value (|EVALEXPR_0| )) " } }, @@ -130,7 +130,7 @@ (declare-datatypes ((|state_type| 0)) (((|state_type| (|balances| (Array Int Int)))))) (declare-fun |interface_0_C_16| (Int |abi_type| |crypto_type| |state_type|) Bool) (declare-fun |nondet_interface_1_C_16| (Int Int |abi_type| |crypto_type| |state_type| |state_type|) Bool) -(declare-datatypes ((|tx_type| 0)) (((|tx_type| (|block.basefee| Int) (|block.chainid| Int) (|block.coinbase| Int) (|block.gaslimit| Int) (|block.number| Int) (|block.prevrandao| Int) (|block.timestamp| Int) (|blockhash| (Array Int Int)) (|msg.data| |bytes_tuple|) (|msg.sender| Int) (|msg.sig| Int) (|msg.value| Int) (|tx.gasprice| Int) (|tx.origin| Int))))) +(declare-datatypes ((|tx_type| 0)) (((|tx_type| (|blobhash| (Array Int Int)) (|block.basefee| Int) (|block.blobbasefee| Int) (|block.chainid| Int) (|block.coinbase| Int) (|block.gaslimit| Int) (|block.number| Int) (|block.prevrandao| Int) (|block.timestamp| Int) (|blockhash| (Array Int Int)) (|msg.data| |bytes_tuple|) (|msg.sender| Int) (|msg.sig| Int) (|msg.value| Int) (|tx.gasprice| Int) (|tx.origin| Int))))) (declare-fun |summary_constructor_2_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool) (assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (this_0 Int)) (=> (= error_0 0) (nondet_interface_1_C_16 error_0 this_0 abi_0 crypto_0 state_0 state_0))) @@ -167,7 +167,7 @@ (block_9_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1)) ) (assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_1 Int)) -(=> (and (and (block_9_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (summary_3_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_2 state_3) (and (= state_2 (|state_type| (store (|balances| state_1) this_0 (+ (select (|balances| state_1) this_0) funds_2_0)))) (and (and (>= (+ (select (|balances| state_1) this_0) funds_2_0) 0) (<= (+ (select (|balances| state_1) this_0) funds_2_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935)) (and (>= funds_2_0 (|msg.value| tx_0)) (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (and (and (and (and (and (= (|msg.value| tx_0) 0) (= (|msg.sig| tx_0) 638722032)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 0) 38)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 1) 18)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 2) 31)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 3) 240)) (>= (|bytes_tuple_accessor_length| (|msg.data| tx_0)) 4))) (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true))))))) true) (summary_4_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_3))) +(=> (and (and (block_9_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (summary_3_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_2 state_3) (and (= state_2 (|state_type| (store (|balances| state_1) this_0 (+ (select (|balances| state_1) this_0) funds_2_0)))) (and (and (>= (+ (select (|balances| state_1) this_0) funds_2_0) 0) (<= (+ (select (|balances| state_1) this_0) funds_2_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935)) (and (>= funds_2_0 (|msg.value| tx_0)) (and (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.blobbasefee| tx_0) 0) (<= (|block.blobbasefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (and (and (and (and (and (= (|msg.value| tx_0) 0) (= (|msg.sig| tx_0) 638722032)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 0) 38)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 1) 18)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 2) 31)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 3) 240)) (>= (|bytes_tuple_accessor_length| (|msg.data| tx_0)) 4))) (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true))))))) true) (summary_4_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_3))) ) (assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|)) (=> (and (and (interface_0_C_16 this_0 abi_0 crypto_0 state_0) true) (and (summary_4_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (= error_0 0))) (interface_0_C_16 this_0 abi_0 crypto_0 state_1))) @@ -195,7 +195,7 @@ (=> (and (and (implicit_constructor_entry_13_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (and (= error_1 0) (and (contract_initializer_10_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2) true))) true) (summary_constructor_2_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_2))) ) (assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|)) -(=> (and (and (summary_constructor_2_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (= (|msg.value| tx_0) 0)) (= error_0 0))) (interface_0_C_16 this_0 abi_0 crypto_0 state_1))) +(=> (and (and (summary_constructor_2_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) (and (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.blobbasefee| tx_0) 0) (<= (|block.blobbasefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (= (|msg.value| tx_0) 0)) (= error_0 0))) (interface_0_C_16 this_0 abi_0 crypto_0 state_1))) ) (declare-fun |error_target_3| () Bool) (assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|)) @@ -217,7 +217,7 @@ (declare-datatypes ((|state_type| 0)) (((|state_type| (|balances| (Array Int Int)))))) (declare-fun |interface_0_C_16| (Int |abi_type| |crypto_type| |state_type|) Bool) (declare-fun |nondet_interface_1_C_16| (Int Int |abi_type| |crypto_type| |state_type| |state_type|) Bool) -(declare-datatypes ((|tx_type| 0)) (((|tx_type| (|block.basefee| Int) (|block.chainid| Int) (|block.coinbase| Int) (|block.gaslimit| Int) (|block.number| Int) (|block.prevrandao| Int) (|block.timestamp| Int) (|blockhash| (Array Int Int)) (|msg.data| |bytes_tuple|) (|msg.sender| Int) (|msg.sig| Int) (|msg.value| Int) (|tx.gasprice| Int) (|tx.origin| Int))))) +(declare-datatypes ((|tx_type| 0)) (((|tx_type| (|blobhash| (Array Int Int)) (|block.basefee| Int) (|block.blobbasefee| Int) (|block.chainid| Int) (|block.coinbase| Int) (|block.gaslimit| Int) (|block.number| Int) (|block.prevrandao| Int) (|block.timestamp| Int) (|blockhash| (Array Int Int)) (|msg.data| |bytes_tuple|) (|msg.sender| Int) (|msg.sig| Int) (|msg.value| Int) (|tx.gasprice| Int) (|tx.origin| Int))))) (declare-fun |summary_constructor_2_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool) (assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (this_0 Int)) (=> (= error_0 0) (nondet_interface_1_C_16 error_0 this_0 abi_0 crypto_0 state_0 state_0))) @@ -254,7 +254,7 @@ (block_9_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1)) ) (assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_1 Int)) -(=> (and (and (block_9_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (summary_3_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_2 state_3) (and (= state_2 (|state_type| (store (|balances| state_1) this_0 (+ (select (|balances| state_1) this_0) funds_2_0)))) (and (and (>= (+ (select (|balances| state_1) this_0) funds_2_0) 0) (<= (+ (select (|balances| state_1) this_0) funds_2_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935)) (and (>= funds_2_0 (|msg.value| tx_0)) (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (and (and (and (and (and (= (|msg.value| tx_0) 0) (= (|msg.sig| tx_0) 638722032)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 0) 38)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 1) 18)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 2) 31)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 3) 240)) (>= (|bytes_tuple_accessor_length| (|msg.data| tx_0)) 4))) (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true))))))) true) (summary_4_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_3))) +(=> (and (and (block_9_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (summary_3_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_2 state_3) (and (= state_2 (|state_type| (store (|balances| state_1) this_0 (+ (select (|balances| state_1) this_0) funds_2_0)))) (and (and (>= (+ (select (|balances| state_1) this_0) funds_2_0) 0) (<= (+ (select (|balances| state_1) this_0) funds_2_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935)) (and (>= funds_2_0 (|msg.value| tx_0)) (and (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.blobbasefee| tx_0) 0) (<= (|block.blobbasefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (and (and (and (and (and (= (|msg.value| tx_0) 0) (= (|msg.sig| tx_0) 638722032)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 0) 38)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 1) 18)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 2) 31)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 3) 240)) (>= (|bytes_tuple_accessor_length| (|msg.data| tx_0)) 4))) (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true))))))) true) (summary_4_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_3))) ) (assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|)) (=> (and (and (interface_0_C_16 this_0 abi_0 crypto_0 state_0) true) (and (summary_4_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (= error_0 0))) (interface_0_C_16 this_0 abi_0 crypto_0 state_1))) @@ -282,7 +282,7 @@ (=> (and (and (implicit_constructor_entry_13_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (and (= error_1 0) (and (contract_initializer_10_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2) true))) true) (summary_constructor_2_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_2))) ) (assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|)) -(=> (and (and (summary_constructor_2_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (= (|msg.value| tx_0) 0)) (= error_0 0))) (interface_0_C_16 this_0 abi_0 crypto_0 state_1))) +(=> (and (and (summary_constructor_2_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) (and (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.blobbasefee| tx_0) 0) (<= (|block.blobbasefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (= (|msg.value| tx_0) 0)) (= error_0 0))) (interface_0_C_16 this_0 abi_0 crypto_0 state_1))) ) (declare-fun |error_target_3| () Bool) (assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|)) @@ -326,7 +326,7 @@ (declare-fun |error_0| () Int) (declare-fun |this_0| () Int) (declare-datatypes ((|bytes_tuple| 0)) (((|bytes_tuple| (|bytes_tuple_accessor_array| (Array Int Int)) (|bytes_tuple_accessor_length| Int))))) -(declare-datatypes ((|tx_type| 0)) (((|tx_type| (|block.basefee| Int) (|block.chainid| Int) (|block.coinbase| Int) (|block.gaslimit| Int) (|block.number| Int) (|block.prevrandao| Int) (|block.timestamp| Int) (|blockhash| (Array Int Int)) (|msg.data| |bytes_tuple|) (|msg.sender| Int) (|msg.sig| Int) (|msg.value| Int) (|tx.gasprice| Int) (|tx.origin| Int))))) +(declare-datatypes ((|tx_type| 0)) (((|tx_type| (|blobhash| (Array Int Int)) (|block.basefee| Int) (|block.blobbasefee| Int) (|block.chainid| Int) (|block.coinbase| Int) (|block.gaslimit| Int) (|block.number| Int) (|block.prevrandao| Int) (|block.timestamp| Int) (|blockhash| (Array Int Int)) (|msg.data| |bytes_tuple|) (|msg.sender| Int) (|msg.sig| Int) (|msg.value| Int) (|tx.gasprice| Int) (|tx.origin| Int))))) (declare-fun |tx_0| () |tx_type|) (declare-datatypes ((|ecrecover_input_type| 0)) (((|ecrecover_input_type| (|hash| Int) (|v| Int) (|r| Int) (|s| Int))))) (declare-datatypes ((|crypto_type| 0)) (((|crypto_type| (|ecrecover| (Array |ecrecover_input_type| Int)) (|keccak256| (Array |bytes_tuple| Int)) (|ripemd160| (Array |bytes_tuple| Int)) (|sha256| (Array |bytes_tuple| Int)))))) @@ -342,7 +342,7 @@ (declare-fun |expr_9_0| () Int) (declare-fun |expr_10_0| () Int) (declare-fun |expr_11_1| () Bool) -(assert (and (and (and true true) (and (= expr_11_1 (= expr_9_0 expr_10_0)) (and (=> (and true true) true) (and (= expr_10_0 0) (and (=> (and true true) (and (>= expr_9_0 0) (<= expr_9_0 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (= expr_9_0 x_5_1) (and (ite (and true true) (= x_5_1 expr_6_0) (= x_5_1 x_5_0)) (and (=> (and true true) true) (and (= expr_6_0 0) (and (= x_5_0 0) (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (and (and (and (and (and (= (|msg.value| tx_0) 0) (= (|msg.sig| tx_0) 638722032)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 0) 38)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 1) 18)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 2) 31)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 3) 240)) (>= (|bytes_tuple_accessor_length| (|msg.data| tx_0)) 4))) true))))))))))) (not expr_11_1))) +(assert (and (and (and true true) (and (= expr_11_1 (= expr_9_0 expr_10_0)) (and (=> (and true true) true) (and (= expr_10_0 0) (and (=> (and true true) (and (>= expr_9_0 0) (<= expr_9_0 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (= expr_9_0 x_5_1) (and (ite (and true true) (= x_5_1 expr_6_0) (= x_5_1 x_5_0)) (and (=> (and true true) true) (and (= expr_6_0 0) (and (= x_5_0 0) (and (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.blobbasefee| tx_0) 0) (<= (|block.blobbasefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (and (and (and (and (and (= (|msg.value| tx_0) 0) (= (|msg.sig| tx_0) 638722032)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 0) 38)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 1) 18)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 2) 31)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 3) 240)) (>= (|bytes_tuple_accessor_length| (|msg.data| tx_0)) 4))) true))))))))))) (not expr_11_1))) (declare-const |EVALEXPR_0| Int) (assert (= |EVALEXPR_0| x_5_1)) (check-sat) @@ -358,7 +358,7 @@ (declare-fun |error_0| () Int) (declare-fun |this_0| () Int) (declare-datatypes ((|bytes_tuple| 0)) (((|bytes_tuple| (|bytes_tuple_accessor_array| (Array Int Int)) (|bytes_tuple_accessor_length| Int))))) -(declare-datatypes ((|tx_type| 0)) (((|tx_type| (|block.basefee| Int) (|block.chainid| Int) (|block.coinbase| Int) (|block.gaslimit| Int) (|block.number| Int) (|block.prevrandao| Int) (|block.timestamp| Int) (|blockhash| (Array Int Int)) (|msg.data| |bytes_tuple|) (|msg.sender| Int) (|msg.sig| Int) (|msg.value| Int) (|tx.gasprice| Int) (|tx.origin| Int))))) +(declare-datatypes ((|tx_type| 0)) (((|tx_type| (|blobhash| (Array Int Int)) (|block.basefee| Int) (|block.blobbasefee| Int) (|block.chainid| Int) (|block.coinbase| Int) (|block.gaslimit| Int) (|block.number| Int) (|block.prevrandao| Int) (|block.timestamp| Int) (|blockhash| (Array Int Int)) (|msg.data| |bytes_tuple|) (|msg.sender| Int) (|msg.sig| Int) (|msg.value| Int) (|tx.gasprice| Int) (|tx.origin| Int))))) (declare-fun |tx_0| () |tx_type|) (declare-datatypes ((|ecrecover_input_type| 0)) (((|ecrecover_input_type| (|hash| Int) (|v| Int) (|r| Int) (|s| Int))))) (declare-datatypes ((|crypto_type| 0)) (((|crypto_type| (|ecrecover| (Array |ecrecover_input_type| Int)) (|keccak256| (Array |bytes_tuple| Int)) (|ripemd160| (Array |bytes_tuple| Int)) (|sha256| (Array |bytes_tuple| Int)))))) @@ -374,7 +374,7 @@ (declare-fun |expr_9_0| () Int) (declare-fun |expr_10_0| () Int) (declare-fun |expr_11_1| () Bool) -(assert (and (and (and true true) (and (= expr_11_1 (= expr_9_0 expr_10_0)) (and (=> (and true true) true) (and (= expr_10_0 0) (and (=> (and true true) (and (>= expr_9_0 0) (<= expr_9_0 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (= expr_9_0 x_5_1) (and (ite (and true true) (= x_5_1 expr_6_0) (= x_5_1 x_5_0)) (and (=> (and true true) true) (and (= expr_6_0 0) (and (= x_5_0 0) (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (and (and (and (and (and (= (|msg.value| tx_0) 0) (= (|msg.sig| tx_0) 638722032)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 0) 38)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 1) 18)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 2) 31)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 3) 240)) (>= (|bytes_tuple_accessor_length| (|msg.data| tx_0)) 4))) true))))))))))) (not expr_11_1))) +(assert (and (and (and true true) (and (= expr_11_1 (= expr_9_0 expr_10_0)) (and (=> (and true true) true) (and (= expr_10_0 0) (and (=> (and true true) (and (>= expr_9_0 0) (<= expr_9_0 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (= expr_9_0 x_5_1) (and (ite (and true true) (= x_5_1 expr_6_0) (= x_5_1 x_5_0)) (and (=> (and true true) true) (and (= expr_6_0 0) (and (= x_5_0 0) (and (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.blobbasefee| tx_0) 0) (<= (|block.blobbasefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (and (and (and (and (and (= (|msg.value| tx_0) 0) (= (|msg.sig| tx_0) 638722032)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 0) 38)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 1) 18)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 2) 31)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 3) 240)) (>= (|bytes_tuple_accessor_length| (|msg.data| tx_0)) 4))) true))))))))))) (not expr_11_1))) (declare-const |EVALEXPR_0| Int) (assert (= |EVALEXPR_0| x_5_1)) (check-sat) diff --git a/test/cmdlineTests/standard_model_checker_print_query_bmc/output.json b/test/cmdlineTests/standard_model_checker_print_query_bmc/output.json index cee9d4b9bf9c..a0be6110b5f3 100644 --- a/test/cmdlineTests/standard_model_checker_print_query_bmc/output.json +++ b/test/cmdlineTests/standard_model_checker_print_query_bmc/output.json @@ -1,12 +1,12 @@ { "auxiliaryInputRequested": { "smtlib2queries": { - "0x2bd3d35071b94d7536d10aad691cee810d94841cca10218c3be21255e258aeb7": "(set-option :produce-models true) + "0x41ee12cade46d5e1c28896216d2b220d2d28b47c925b0191941303216c8635dd": "(set-option :produce-models true) (set-logic ALL) (declare-fun |error_0| () Int) (declare-fun |this_0| () Int) (declare-datatypes ((|bytes_tuple| 0)) (((|bytes_tuple| (|bytes_tuple_accessor_array| (Array Int Int)) (|bytes_tuple_accessor_length| Int))))) -(declare-datatypes ((|tx_type| 0)) (((|tx_type| (|block.basefee| Int) (|block.chainid| Int) (|block.coinbase| Int) (|block.gaslimit| Int) (|block.number| Int) (|block.prevrandao| Int) (|block.timestamp| Int) (|blockhash| (Array Int Int)) (|msg.data| |bytes_tuple|) (|msg.sender| Int) (|msg.sig| Int) (|msg.value| Int) (|tx.gasprice| Int) (|tx.origin| Int))))) +(declare-datatypes ((|tx_type| 0)) (((|tx_type| (|blobhash| (Array Int Int)) (|block.basefee| Int) (|block.blobbasefee| Int) (|block.chainid| Int) (|block.coinbase| Int) (|block.gaslimit| Int) (|block.number| Int) (|block.prevrandao| Int) (|block.timestamp| Int) (|blockhash| (Array Int Int)) (|msg.data| |bytes_tuple|) (|msg.sender| Int) (|msg.sig| Int) (|msg.value| Int) (|tx.gasprice| Int) (|tx.origin| Int))))) (declare-fun |tx_0| () |tx_type|) (declare-datatypes ((|ecrecover_input_type| 0)) (((|ecrecover_input_type| (|hash| Int) (|v| Int) (|r| Int) (|s| Int))))) (declare-datatypes ((|crypto_type| 0)) (((|crypto_type| (|ecrecover| (Array |ecrecover_input_type| Int)) (|keccak256| (Array |bytes_tuple| Int)) (|ripemd160| (Array |bytes_tuple| Int)) (|sha256| (Array |bytes_tuple| Int)))))) @@ -21,7 +21,7 @@ (declare-fun |expr_9_0| () Int) (declare-fun |expr_10_0| () Int) (declare-fun |expr_11_1| () Bool) -(assert (and (and (and true true) (and (= expr_11_1 (= expr_9_0 expr_10_0)) (and (=> (and true true) true) (and (= expr_10_0 0) (and (=> (and true true) (and (>= expr_9_0 0) (<= expr_9_0 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (= expr_9_0 x_5_1) (and (ite (and true true) (= x_5_1 expr_6_0) (= x_5_1 x_5_0)) (and (=> (and true true) true) (and (= expr_6_0 0) (and (= x_5_0 0) (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (and (and (and (and (and (= (|msg.value| tx_0) 0) (= (|msg.sig| tx_0) 638722032)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 0) 38)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 1) 18)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 2) 31)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 3) 240)) (>= (|bytes_tuple_accessor_length| (|msg.data| tx_0)) 4))) true))))))))))) (not expr_11_1))) +(assert (and (and (and true true) (and (= expr_11_1 (= expr_9_0 expr_10_0)) (and (=> (and true true) true) (and (= expr_10_0 0) (and (=> (and true true) (and (>= expr_9_0 0) (<= expr_9_0 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (= expr_9_0 x_5_1) (and (ite (and true true) (= x_5_1 expr_6_0) (= x_5_1 x_5_0)) (and (=> (and true true) true) (and (= expr_6_0 0) (and (= x_5_0 0) (and (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.blobbasefee| tx_0) 0) (<= (|block.blobbasefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (and (and (and (and (and (= (|msg.value| tx_0) 0) (= (|msg.sig| tx_0) 638722032)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 0) 38)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 1) 18)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 2) 31)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 3) 240)) (>= (|bytes_tuple_accessor_length| (|msg.data| tx_0)) 4))) true))))))))))) (not expr_11_1))) (declare-const |EVALEXPR_0| Int) (assert (= |EVALEXPR_0| x_5_1)) (check-sat) @@ -39,7 +39,7 @@ (declare-fun |error_0| () Int) (declare-fun |this_0| () Int) (declare-datatypes ((|bytes_tuple| 0)) (((|bytes_tuple| (|bytes_tuple_accessor_array| (Array Int Int)) (|bytes_tuple_accessor_length| Int))))) -(declare-datatypes ((|tx_type| 0)) (((|tx_type| (|block.basefee| Int) (|block.chainid| Int) (|block.coinbase| Int) (|block.gaslimit| Int) (|block.number| Int) (|block.prevrandao| Int) (|block.timestamp| Int) (|blockhash| (Array Int Int)) (|msg.data| |bytes_tuple|) (|msg.sender| Int) (|msg.sig| Int) (|msg.value| Int) (|tx.gasprice| Int) (|tx.origin| Int))))) +(declare-datatypes ((|tx_type| 0)) (((|tx_type| (|blobhash| (Array Int Int)) (|block.basefee| Int) (|block.blobbasefee| Int) (|block.chainid| Int) (|block.coinbase| Int) (|block.gaslimit| Int) (|block.number| Int) (|block.prevrandao| Int) (|block.timestamp| Int) (|blockhash| (Array Int Int)) (|msg.data| |bytes_tuple|) (|msg.sender| Int) (|msg.sig| Int) (|msg.value| Int) (|tx.gasprice| Int) (|tx.origin| Int))))) (declare-fun |tx_0| () |tx_type|) (declare-datatypes ((|ecrecover_input_type| 0)) (((|ecrecover_input_type| (|hash| Int) (|v| Int) (|r| Int) (|s| Int))))) (declare-datatypes ((|crypto_type| 0)) (((|crypto_type| (|ecrecover| (Array |ecrecover_input_type| Int)) (|keccak256| (Array |bytes_tuple| Int)) (|ripemd160| (Array |bytes_tuple| Int)) (|sha256| (Array |bytes_tuple| Int)))))) @@ -54,7 +54,7 @@ (declare-fun |expr_9_0| () Int) (declare-fun |expr_10_0| () Int) (declare-fun |expr_11_1| () Bool) -(assert (and (and (and true true) (and (= expr_11_1 (= expr_9_0 expr_10_0)) (and (=> (and true true) true) (and (= expr_10_0 0) (and (=> (and true true) (and (>= expr_9_0 0) (<= expr_9_0 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (= expr_9_0 x_5_1) (and (ite (and true true) (= x_5_1 expr_6_0) (= x_5_1 x_5_0)) (and (=> (and true true) true) (and (= expr_6_0 0) (and (= x_5_0 0) (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (and (and (and (and (and (= (|msg.value| tx_0) 0) (= (|msg.sig| tx_0) 638722032)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 0) 38)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 1) 18)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 2) 31)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 3) 240)) (>= (|bytes_tuple_accessor_length| (|msg.data| tx_0)) 4))) true))))))))))) (not expr_11_1))) +(assert (and (and (and true true) (and (= expr_11_1 (= expr_9_0 expr_10_0)) (and (=> (and true true) true) (and (= expr_10_0 0) (and (=> (and true true) (and (>= expr_9_0 0) (<= expr_9_0 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (= expr_9_0 x_5_1) (and (ite (and true true) (= x_5_1 expr_6_0) (= x_5_1 x_5_0)) (and (=> (and true true) true) (and (= expr_6_0 0) (and (= x_5_0 0) (and (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.blobbasefee| tx_0) 0) (<= (|block.blobbasefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (and (and (and (and (and (= (|msg.value| tx_0) 0) (= (|msg.sig| tx_0) 638722032)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 0) 38)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 1) 18)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 2) 31)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 3) 240)) (>= (|bytes_tuple_accessor_length| (|msg.data| tx_0)) 4))) true))))))))))) (not expr_11_1))) (declare-const |EVALEXPR_0| Int) (assert (= |EVALEXPR_0| x_5_1)) (check-sat) @@ -68,7 +68,7 @@ (declare-fun |error_0| () Int) (declare-fun |this_0| () Int) (declare-datatypes ((|bytes_tuple| 0)) (((|bytes_tuple| (|bytes_tuple_accessor_array| (Array Int Int)) (|bytes_tuple_accessor_length| Int))))) -(declare-datatypes ((|tx_type| 0)) (((|tx_type| (|block.basefee| Int) (|block.chainid| Int) (|block.coinbase| Int) (|block.gaslimit| Int) (|block.number| Int) (|block.prevrandao| Int) (|block.timestamp| Int) (|blockhash| (Array Int Int)) (|msg.data| |bytes_tuple|) (|msg.sender| Int) (|msg.sig| Int) (|msg.value| Int) (|tx.gasprice| Int) (|tx.origin| Int))))) +(declare-datatypes ((|tx_type| 0)) (((|tx_type| (|blobhash| (Array Int Int)) (|block.basefee| Int) (|block.blobbasefee| Int) (|block.chainid| Int) (|block.coinbase| Int) (|block.gaslimit| Int) (|block.number| Int) (|block.prevrandao| Int) (|block.timestamp| Int) (|blockhash| (Array Int Int)) (|msg.data| |bytes_tuple|) (|msg.sender| Int) (|msg.sig| Int) (|msg.value| Int) (|tx.gasprice| Int) (|tx.origin| Int))))) (declare-fun |tx_0| () |tx_type|) (declare-datatypes ((|ecrecover_input_type| 0)) (((|ecrecover_input_type| (|hash| Int) (|v| Int) (|r| Int) (|s| Int))))) (declare-datatypes ((|crypto_type| 0)) (((|crypto_type| (|ecrecover| (Array |ecrecover_input_type| Int)) (|keccak256| (Array |bytes_tuple| Int)) (|ripemd160| (Array |bytes_tuple| Int)) (|sha256| (Array |bytes_tuple| Int)))))) @@ -83,7 +83,7 @@ (declare-fun |expr_9_0| () Int) (declare-fun |expr_10_0| () Int) (declare-fun |expr_11_1| () Bool) -(assert (and (and (and true true) (and (= expr_11_1 (= expr_9_0 expr_10_0)) (and (=> (and true true) true) (and (= expr_10_0 0) (and (=> (and true true) (and (>= expr_9_0 0) (<= expr_9_0 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (= expr_9_0 x_5_1) (and (ite (and true true) (= x_5_1 expr_6_0) (= x_5_1 x_5_0)) (and (=> (and true true) true) (and (= expr_6_0 0) (and (= x_5_0 0) (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (and (and (and (and (and (= (|msg.value| tx_0) 0) (= (|msg.sig| tx_0) 638722032)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 0) 38)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 1) 18)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 2) 31)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 3) 240)) (>= (|bytes_tuple_accessor_length| (|msg.data| tx_0)) 4))) true))))))))))) (not expr_11_1))) +(assert (and (and (and true true) (and (= expr_11_1 (= expr_9_0 expr_10_0)) (and (=> (and true true) true) (and (= expr_10_0 0) (and (=> (and true true) (and (>= expr_9_0 0) (<= expr_9_0 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (= expr_9_0 x_5_1) (and (ite (and true true) (= x_5_1 expr_6_0) (= x_5_1 x_5_0)) (and (=> (and true true) true) (and (= expr_6_0 0) (and (= x_5_0 0) (and (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.blobbasefee| tx_0) 0) (<= (|block.blobbasefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (and (and (and (and (and (= (|msg.value| tx_0) 0) (= (|msg.sig| tx_0) 638722032)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 0) 38)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 1) 18)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 2) 31)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 3) 240)) (>= (|bytes_tuple_accessor_length| (|msg.data| tx_0)) 4))) true))))))))))) (not expr_11_1))) (declare-const |EVALEXPR_0| Int) (assert (= |EVALEXPR_0| x_5_1)) (check-sat) diff --git a/test/cmdlineTests/standard_model_checker_print_query_chc/output.json b/test/cmdlineTests/standard_model_checker_print_query_chc/output.json index 9553a3cfb662..be0d9fa9e912 100644 --- a/test/cmdlineTests/standard_model_checker_print_query_chc/output.json +++ b/test/cmdlineTests/standard_model_checker_print_query_chc/output.json @@ -1,7 +1,7 @@ { "auxiliaryInputRequested": { "smtlib2queries": { - "0x9cfcd53712a0be144c8e7983b3635498ead1af2624885fb89762eae8c43233e5": "(set-option :timeout 1000) + "0x89dce9b2e59f1b2d3445ec646e15e2609ff358edb66afa7227538979017e0f7b": "(set-option :timeout 1000) (set-logic HORN) (declare-datatypes ((|abi_type| 0)) (((|abi_type|)))) (declare-datatypes ((|ecrecover_input_type| 0)) (((|ecrecover_input_type| (|hash| Int) (|v| Int) (|r| Int) (|s| Int))))) @@ -10,7 +10,7 @@ (declare-datatypes ((|state_type| 0)) (((|state_type| (|balances| (Array Int Int)))))) (declare-fun |interface_0_C_16| (Int |abi_type| |crypto_type| |state_type|) Bool) (declare-fun |nondet_interface_1_C_16| (Int Int |abi_type| |crypto_type| |state_type| |state_type|) Bool) -(declare-datatypes ((|tx_type| 0)) (((|tx_type| (|block.basefee| Int) (|block.chainid| Int) (|block.coinbase| Int) (|block.gaslimit| Int) (|block.number| Int) (|block.prevrandao| Int) (|block.timestamp| Int) (|blockhash| (Array Int Int)) (|msg.data| |bytes_tuple|) (|msg.sender| Int) (|msg.sig| Int) (|msg.value| Int) (|tx.gasprice| Int) (|tx.origin| Int))))) +(declare-datatypes ((|tx_type| 0)) (((|tx_type| (|blobhash| (Array Int Int)) (|block.basefee| Int) (|block.blobbasefee| Int) (|block.chainid| Int) (|block.coinbase| Int) (|block.gaslimit| Int) (|block.number| Int) (|block.prevrandao| Int) (|block.timestamp| Int) (|blockhash| (Array Int Int)) (|msg.data| |bytes_tuple|) (|msg.sender| Int) (|msg.sig| Int) (|msg.value| Int) (|tx.gasprice| Int) (|tx.origin| Int))))) (declare-fun |summary_constructor_2_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool) (assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (this_0 Int)) (=> (= error_0 0) (nondet_interface_1_C_16 error_0 this_0 abi_0 crypto_0 state_0 state_0))) @@ -47,7 +47,7 @@ (block_9_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1)) ) (assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_1 Int)) -(=> (and (and (block_9_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (summary_3_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_2 state_3) (and (= state_2 (|state_type| (store (|balances| state_1) this_0 (+ (select (|balances| state_1) this_0) funds_2_0)))) (and (and (>= (+ (select (|balances| state_1) this_0) funds_2_0) 0) (<= (+ (select (|balances| state_1) this_0) funds_2_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935)) (and (>= funds_2_0 (|msg.value| tx_0)) (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (and (and (and (and (and (= (|msg.value| tx_0) 0) (= (|msg.sig| tx_0) 638722032)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 0) 38)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 1) 18)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 2) 31)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 3) 240)) (>= (|bytes_tuple_accessor_length| (|msg.data| tx_0)) 4))) (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true))))))) true) (summary_4_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_3))) +(=> (and (and (block_9_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (summary_3_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_2 state_3) (and (= state_2 (|state_type| (store (|balances| state_1) this_0 (+ (select (|balances| state_1) this_0) funds_2_0)))) (and (and (>= (+ (select (|balances| state_1) this_0) funds_2_0) 0) (<= (+ (select (|balances| state_1) this_0) funds_2_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935)) (and (>= funds_2_0 (|msg.value| tx_0)) (and (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.blobbasefee| tx_0) 0) (<= (|block.blobbasefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (and (and (and (and (and (= (|msg.value| tx_0) 0) (= (|msg.sig| tx_0) 638722032)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 0) 38)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 1) 18)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 2) 31)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 3) 240)) (>= (|bytes_tuple_accessor_length| (|msg.data| tx_0)) 4))) (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true))))))) true) (summary_4_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_3))) ) (assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|)) (=> (and (and (interface_0_C_16 this_0 abi_0 crypto_0 state_0) true) (and (summary_4_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (= error_0 0))) (interface_0_C_16 this_0 abi_0 crypto_0 state_1))) @@ -75,7 +75,7 @@ (=> (and (and (implicit_constructor_entry_13_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (and (= error_1 0) (and (contract_initializer_10_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2) true))) true) (summary_constructor_2_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_2))) ) (assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|)) -(=> (and (and (summary_constructor_2_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (= (|msg.value| tx_0) 0)) (= error_0 0))) (interface_0_C_16 this_0 abi_0 crypto_0 state_1))) +(=> (and (and (summary_constructor_2_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) (and (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.blobbasefee| tx_0) 0) (<= (|block.blobbasefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (= (|msg.value| tx_0) 0)) (= error_0 0))) (interface_0_C_16 this_0 abi_0 crypto_0 state_1))) ) (declare-fun |error_target_3| () Bool) (assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|)) @@ -101,7 +101,7 @@ (declare-datatypes ((|state_type| 0)) (((|state_type| (|balances| (Array Int Int)))))) (declare-fun |interface_0_C_16| (Int |abi_type| |crypto_type| |state_type|) Bool) (declare-fun |nondet_interface_1_C_16| (Int Int |abi_type| |crypto_type| |state_type| |state_type|) Bool) -(declare-datatypes ((|tx_type| 0)) (((|tx_type| (|block.basefee| Int) (|block.chainid| Int) (|block.coinbase| Int) (|block.gaslimit| Int) (|block.number| Int) (|block.prevrandao| Int) (|block.timestamp| Int) (|blockhash| (Array Int Int)) (|msg.data| |bytes_tuple|) (|msg.sender| Int) (|msg.sig| Int) (|msg.value| Int) (|tx.gasprice| Int) (|tx.origin| Int))))) +(declare-datatypes ((|tx_type| 0)) (((|tx_type| (|blobhash| (Array Int Int)) (|block.basefee| Int) (|block.blobbasefee| Int) (|block.chainid| Int) (|block.coinbase| Int) (|block.gaslimit| Int) (|block.number| Int) (|block.prevrandao| Int) (|block.timestamp| Int) (|blockhash| (Array Int Int)) (|msg.data| |bytes_tuple|) (|msg.sender| Int) (|msg.sig| Int) (|msg.value| Int) (|tx.gasprice| Int) (|tx.origin| Int))))) (declare-fun |summary_constructor_2_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool) (assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (this_0 Int)) (=> (= error_0 0) (nondet_interface_1_C_16 error_0 this_0 abi_0 crypto_0 state_0 state_0))) @@ -138,7 +138,7 @@ (block_9_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1)) ) (assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_1 Int)) -(=> (and (and (block_9_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (summary_3_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_2 state_3) (and (= state_2 (|state_type| (store (|balances| state_1) this_0 (+ (select (|balances| state_1) this_0) funds_2_0)))) (and (and (>= (+ (select (|balances| state_1) this_0) funds_2_0) 0) (<= (+ (select (|balances| state_1) this_0) funds_2_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935)) (and (>= funds_2_0 (|msg.value| tx_0)) (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (and (and (and (and (and (= (|msg.value| tx_0) 0) (= (|msg.sig| tx_0) 638722032)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 0) 38)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 1) 18)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 2) 31)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 3) 240)) (>= (|bytes_tuple_accessor_length| (|msg.data| tx_0)) 4))) (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true))))))) true) (summary_4_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_3))) +(=> (and (and (block_9_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (summary_3_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_2 state_3) (and (= state_2 (|state_type| (store (|balances| state_1) this_0 (+ (select (|balances| state_1) this_0) funds_2_0)))) (and (and (>= (+ (select (|balances| state_1) this_0) funds_2_0) 0) (<= (+ (select (|balances| state_1) this_0) funds_2_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935)) (and (>= funds_2_0 (|msg.value| tx_0)) (and (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.blobbasefee| tx_0) 0) (<= (|block.blobbasefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (and (and (and (and (and (= (|msg.value| tx_0) 0) (= (|msg.sig| tx_0) 638722032)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 0) 38)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 1) 18)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 2) 31)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 3) 240)) (>= (|bytes_tuple_accessor_length| (|msg.data| tx_0)) 4))) (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true))))))) true) (summary_4_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_3))) ) (assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|)) (=> (and (and (interface_0_C_16 this_0 abi_0 crypto_0 state_0) true) (and (summary_4_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (= error_0 0))) (interface_0_C_16 this_0 abi_0 crypto_0 state_1))) @@ -166,7 +166,7 @@ (=> (and (and (implicit_constructor_entry_13_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (and (= error_1 0) (and (contract_initializer_10_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2) true))) true) (summary_constructor_2_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_2))) ) (assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|)) -(=> (and (and (summary_constructor_2_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (= (|msg.value| tx_0) 0)) (= error_0 0))) (interface_0_C_16 this_0 abi_0 crypto_0 state_1))) +(=> (and (and (summary_constructor_2_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) (and (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.blobbasefee| tx_0) 0) (<= (|block.blobbasefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (= (|msg.value| tx_0) 0)) (= error_0 0))) (interface_0_C_16 this_0 abi_0 crypto_0 state_1))) ) (declare-fun |error_target_3| () Bool) (assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|)) @@ -188,7 +188,7 @@ (declare-datatypes ((|state_type| 0)) (((|state_type| (|balances| (Array Int Int)))))) (declare-fun |interface_0_C_16| (Int |abi_type| |crypto_type| |state_type|) Bool) (declare-fun |nondet_interface_1_C_16| (Int Int |abi_type| |crypto_type| |state_type| |state_type|) Bool) -(declare-datatypes ((|tx_type| 0)) (((|tx_type| (|block.basefee| Int) (|block.chainid| Int) (|block.coinbase| Int) (|block.gaslimit| Int) (|block.number| Int) (|block.prevrandao| Int) (|block.timestamp| Int) (|blockhash| (Array Int Int)) (|msg.data| |bytes_tuple|) (|msg.sender| Int) (|msg.sig| Int) (|msg.value| Int) (|tx.gasprice| Int) (|tx.origin| Int))))) +(declare-datatypes ((|tx_type| 0)) (((|tx_type| (|blobhash| (Array Int Int)) (|block.basefee| Int) (|block.blobbasefee| Int) (|block.chainid| Int) (|block.coinbase| Int) (|block.gaslimit| Int) (|block.number| Int) (|block.prevrandao| Int) (|block.timestamp| Int) (|blockhash| (Array Int Int)) (|msg.data| |bytes_tuple|) (|msg.sender| Int) (|msg.sig| Int) (|msg.value| Int) (|tx.gasprice| Int) (|tx.origin| Int))))) (declare-fun |summary_constructor_2_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool) (assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (this_0 Int)) (=> (= error_0 0) (nondet_interface_1_C_16 error_0 this_0 abi_0 crypto_0 state_0 state_0))) @@ -225,7 +225,7 @@ (block_9_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1)) ) (assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_1 Int)) -(=> (and (and (block_9_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (summary_3_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_2 state_3) (and (= state_2 (|state_type| (store (|balances| state_1) this_0 (+ (select (|balances| state_1) this_0) funds_2_0)))) (and (and (>= (+ (select (|balances| state_1) this_0) funds_2_0) 0) (<= (+ (select (|balances| state_1) this_0) funds_2_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935)) (and (>= funds_2_0 (|msg.value| tx_0)) (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (and (and (and (and (and (= (|msg.value| tx_0) 0) (= (|msg.sig| tx_0) 638722032)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 0) 38)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 1) 18)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 2) 31)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 3) 240)) (>= (|bytes_tuple_accessor_length| (|msg.data| tx_0)) 4))) (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true))))))) true) (summary_4_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_3))) +(=> (and (and (block_9_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (summary_3_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_2 state_3) (and (= state_2 (|state_type| (store (|balances| state_1) this_0 (+ (select (|balances| state_1) this_0) funds_2_0)))) (and (and (>= (+ (select (|balances| state_1) this_0) funds_2_0) 0) (<= (+ (select (|balances| state_1) this_0) funds_2_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935)) (and (>= funds_2_0 (|msg.value| tx_0)) (and (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.blobbasefee| tx_0) 0) (<= (|block.blobbasefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (and (and (and (and (and (= (|msg.value| tx_0) 0) (= (|msg.sig| tx_0) 638722032)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 0) 38)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 1) 18)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 2) 31)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 3) 240)) (>= (|bytes_tuple_accessor_length| (|msg.data| tx_0)) 4))) (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true))))))) true) (summary_4_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_3))) ) (assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|)) (=> (and (and (interface_0_C_16 this_0 abi_0 crypto_0 state_0) true) (and (summary_4_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (= error_0 0))) (interface_0_C_16 this_0 abi_0 crypto_0 state_1))) @@ -253,7 +253,7 @@ (=> (and (and (implicit_constructor_entry_13_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (and (= error_1 0) (and (contract_initializer_10_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2) true))) true) (summary_constructor_2_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_2))) ) (assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|)) -(=> (and (and (summary_constructor_2_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (= (|msg.value| tx_0) 0)) (= error_0 0))) (interface_0_C_16 this_0 abi_0 crypto_0 state_1))) +(=> (and (and (summary_constructor_2_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) (and (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.blobbasefee| tx_0) 0) (<= (|block.blobbasefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (= (|msg.value| tx_0) 0)) (= error_0 0))) (interface_0_C_16 this_0 abi_0 crypto_0 state_1))) ) (declare-fun |error_target_3| () Bool) (assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|)) diff --git a/test/cmdlineTests/standard_model_checker_show_unproved_default_all_engines/output.json b/test/cmdlineTests/standard_model_checker_show_unproved_default_all_engines/output.json index da3b3dcad888..de2c2aca05b7 100644 --- a/test/cmdlineTests/standard_model_checker_show_unproved_default_all_engines/output.json +++ b/test/cmdlineTests/standard_model_checker_show_unproved_default_all_engines/output.json @@ -12,13 +12,13 @@ }, { "component": "general", - "errorCode": "2788", - "formattedMessage": "Warning: BMC: 1 verification condition(s) could not be proved. Enable the model checker option \"show unproved\" to see all of them. Consider choosing a specific contract to be verified in order to reduce the solving problems. Consider increasing the timeout per query. + "errorCode": "6002", + "formattedMessage": "Info: BMC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them. ", - "message": "BMC: 1 verification condition(s) could not be proved. Enable the model checker option \"show unproved\" to see all of them. Consider choosing a specific contract to be verified in order to reduce the solving problems. Consider increasing the timeout per query.", - "severity": "warning", - "type": "Warning" + "message": "BMC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.", + "severity": "info", + "type": "Info" } ], "sources": { diff --git a/test/cmdlineTests/standard_model_checker_show_unproved_false_all_engines/output.json b/test/cmdlineTests/standard_model_checker_show_unproved_false_all_engines/output.json index da3b3dcad888..de2c2aca05b7 100644 --- a/test/cmdlineTests/standard_model_checker_show_unproved_false_all_engines/output.json +++ b/test/cmdlineTests/standard_model_checker_show_unproved_false_all_engines/output.json @@ -12,13 +12,13 @@ }, { "component": "general", - "errorCode": "2788", - "formattedMessage": "Warning: BMC: 1 verification condition(s) could not be proved. Enable the model checker option \"show unproved\" to see all of them. Consider choosing a specific contract to be verified in order to reduce the solving problems. Consider increasing the timeout per query. + "errorCode": "6002", + "formattedMessage": "Info: BMC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them. ", - "message": "BMC: 1 verification condition(s) could not be proved. Enable the model checker option \"show unproved\" to see all of them. Consider choosing a specific contract to be verified in order to reduce the solving problems. Consider increasing the timeout per query.", - "severity": "warning", - "type": "Warning" + "message": "BMC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.", + "severity": "info", + "type": "Info" } ], "sources": { diff --git a/test/cmdlineTests/standard_model_checker_show_unproved_false_bmc/output.json b/test/cmdlineTests/standard_model_checker_show_unproved_false_bmc/output.json index 67f8df731994..0f1ce4e39454 100644 --- a/test/cmdlineTests/standard_model_checker_show_unproved_false_bmc/output.json +++ b/test/cmdlineTests/standard_model_checker_show_unproved_false_bmc/output.json @@ -2,13 +2,13 @@ "errors": [ { "component": "general", - "errorCode": "2788", - "formattedMessage": "Warning: BMC: 1 verification condition(s) could not be proved. Enable the model checker option \"show unproved\" to see all of them. Consider choosing a specific contract to be verified in order to reduce the solving problems. Consider increasing the timeout per query. + "errorCode": "6002", + "formattedMessage": "Info: BMC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them. ", - "message": "BMC: 1 verification condition(s) could not be proved. Enable the model checker option \"show unproved\" to see all of them. Consider choosing a specific contract to be verified in order to reduce the solving problems. Consider increasing the timeout per query.", - "severity": "warning", - "type": "Warning" + "message": "BMC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.", + "severity": "info", + "type": "Info" } ], "sources": { diff --git a/test/cmdlineTests/standard_model_checker_show_unproved_true_all_engines/output.json b/test/cmdlineTests/standard_model_checker_show_unproved_true_all_engines/output.json index b6153de5ebe5..22c2a48193c1 100644 --- a/test/cmdlineTests/standard_model_checker_show_unproved_true_all_engines/output.json +++ b/test/cmdlineTests/standard_model_checker_show_unproved_true_all_engines/output.json @@ -21,28 +21,13 @@ }, { "component": "general", - "errorCode": "7812", - "formattedMessage": "Warning: BMC: Assertion violation might happen here. - --> A:11:7: - | -11 | \t\t\t\t\t\tassert(s.x > 0); - | \t\t\t\t\t\t^^^^^^^^^^^^^^^ -Note: + "errorCode": "6002", + "formattedMessage": "Info: BMC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them. ", - "message": "BMC: Assertion violation might happen here.", - "secondarySourceLocations": [ - { - "message": "" - } - ], - "severity": "warning", - "sourceLocation": { - "end": 201, - "file": "A", - "start": 186 - }, - "type": "Warning" + "message": "BMC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.", + "severity": "info", + "type": "Info" } ], "sources": { diff --git a/test/cmdlineTests/standard_model_checker_show_unproved_true_bmc/output.json b/test/cmdlineTests/standard_model_checker_show_unproved_true_bmc/output.json index 6c3b57c79553..0f1ce4e39454 100644 --- a/test/cmdlineTests/standard_model_checker_show_unproved_true_bmc/output.json +++ b/test/cmdlineTests/standard_model_checker_show_unproved_true_bmc/output.json @@ -2,28 +2,13 @@ "errors": [ { "component": "general", - "errorCode": "7812", - "formattedMessage": "Warning: BMC: Assertion violation might happen here. - --> A:11:7: - | -11 | \t\t\t\t\t\tassert(s.x > 0); - | \t\t\t\t\t\t^^^^^^^^^^^^^^^ -Note: + "errorCode": "6002", + "formattedMessage": "Info: BMC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them. ", - "message": "BMC: Assertion violation might happen here.", - "secondarySourceLocations": [ - { - "message": "" - } - ], - "severity": "warning", - "sourceLocation": { - "end": 201, - "file": "A", - "start": 186 - }, - "type": "Warning" + "message": "BMC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.", + "severity": "info", + "type": "Info" } ], "sources": { diff --git a/test/cmdlineTests/standard_model_checker_solvers_smtlib2/output.json b/test/cmdlineTests/standard_model_checker_solvers_smtlib2/output.json index a3f4cc03d784..79037e2236bd 100644 --- a/test/cmdlineTests/standard_model_checker_solvers_smtlib2/output.json +++ b/test/cmdlineTests/standard_model_checker_solvers_smtlib2/output.json @@ -1,13 +1,13 @@ { "auxiliaryInputRequested": { "smtlib2queries": { - "0x51b9801f3e8e35f2ff5f4538b0636fae81aa84a482cbb486ae4db63bede5ecb5": "(set-option :produce-models true) + "0x1b1a2b4161df2f2869bdcd6ee320ef4c54aded9ae9c0441dd2dd4248f5616d97": "(set-option :produce-models true) (set-logic ALL) (declare-fun |x_3_3| () Int) (declare-fun |error_0| () Int) (declare-fun |this_0| () Int) (declare-datatypes ((|bytes_tuple| 0)) (((|bytes_tuple| (|bytes_tuple_accessor_array| (Array Int Int)) (|bytes_tuple_accessor_length| Int))))) -(declare-datatypes ((|tx_type| 0)) (((|tx_type| (|block.basefee| Int) (|block.chainid| Int) (|block.coinbase| Int) (|block.gaslimit| Int) (|block.number| Int) (|block.prevrandao| Int) (|block.timestamp| Int) (|blockhash| (Array Int Int)) (|msg.data| |bytes_tuple|) (|msg.sender| Int) (|msg.sig| Int) (|msg.value| Int) (|tx.gasprice| Int) (|tx.origin| Int))))) +(declare-datatypes ((|tx_type| 0)) (((|tx_type| (|blobhash| (Array Int Int)) (|block.basefee| Int) (|block.blobbasefee| Int) (|block.chainid| Int) (|block.coinbase| Int) (|block.gaslimit| Int) (|block.number| Int) (|block.prevrandao| Int) (|block.timestamp| Int) (|blockhash| (Array Int Int)) (|msg.data| |bytes_tuple|) (|msg.sender| Int) (|msg.sig| Int) (|msg.value| Int) (|tx.gasprice| Int) (|tx.origin| Int))))) (declare-fun |tx_0| () |tx_type|) (declare-datatypes ((|ecrecover_input_type| 0)) (((|ecrecover_input_type| (|hash| Int) (|v| Int) (|r| Int) (|s| Int))))) (declare-datatypes ((|crypto_type| 0)) (((|crypto_type| (|ecrecover| (Array |ecrecover_input_type| Int)) (|keccak256| (Array |bytes_tuple| Int)) (|ripemd160| (Array |bytes_tuple| Int)) (|sha256| (Array |bytes_tuple| Int)))))) @@ -21,13 +21,13 @@ (declare-fun |expr_7_0| () Int) (declare-fun |expr_8_0| () Int) (declare-fun |expr_9_1| () Bool) -(assert (and (and (and true true) (and (= expr_9_1 (> expr_7_0 expr_8_0)) (and (=> (and true true) true) (and (= expr_8_0 0) (and (=> (and true true) (and (>= expr_7_0 0) (<= expr_7_0 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (= expr_7_0 x_3_0) (and (and (>= x_3_0 0) (<= x_3_0 115792089237316195423570985008687907853269984665640564039457584007913129639935)) (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (and (and (and (and (and (= (|msg.value| tx_0) 0) (= (|msg.sig| tx_0) 3017696395)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 0) 179)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 1) 222)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 2) 100)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 3) 139)) (>= (|bytes_tuple_accessor_length| (|msg.data| tx_0)) 4))) true)))))))) (not expr_9_1))) +(assert (and (and (and true true) (and (= expr_9_1 (> expr_7_0 expr_8_0)) (and (=> (and true true) true) (and (= expr_8_0 0) (and (=> (and true true) (and (>= expr_7_0 0) (<= expr_7_0 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (= expr_7_0 x_3_0) (and (and (>= x_3_0 0) (<= x_3_0 115792089237316195423570985008687907853269984665640564039457584007913129639935)) (and (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.blobbasefee| tx_0) 0) (<= (|block.blobbasefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (and (and (and (and (and (= (|msg.value| tx_0) 0) (= (|msg.sig| tx_0) 3017696395)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 0) 179)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 1) 222)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 2) 100)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 3) 139)) (>= (|bytes_tuple_accessor_length| (|msg.data| tx_0)) 4))) true)))))))) (not expr_9_1))) (declare-const |EVALEXPR_0| Int) (assert (= |EVALEXPR_0| x_3_0)) (check-sat) (get-value (|EVALEXPR_0| )) ", - "0xdb239809dcdaa42e35abca69790cb7e11b105f839e37faa8841f0dd9736688d7": "(set-logic HORN) + "0xd2654693bf2b4f42bfe922319928772b52430787451450fda29da1ebea716f19": "(set-logic HORN) (declare-datatypes ((|abi_type| 0)) (((|abi_type|)))) (declare-datatypes ((|ecrecover_input_type| 0)) (((|ecrecover_input_type| (|hash| Int) (|v| Int) (|r| Int) (|s| Int))))) (declare-datatypes ((|bytes_tuple| 0)) (((|bytes_tuple| (|bytes_tuple_accessor_array| (Array Int Int)) (|bytes_tuple_accessor_length| Int))))) @@ -35,7 +35,7 @@ (declare-datatypes ((|state_type| 0)) (((|state_type| (|balances| (Array Int Int)))))) (declare-fun |interface_0_C_14| (Int |abi_type| |crypto_type| |state_type|) Bool) (declare-fun |nondet_interface_1_C_14| (Int Int |abi_type| |crypto_type| |state_type| |state_type|) Bool) -(declare-datatypes ((|tx_type| 0)) (((|tx_type| (|block.basefee| Int) (|block.chainid| Int) (|block.coinbase| Int) (|block.gaslimit| Int) (|block.number| Int) (|block.prevrandao| Int) (|block.timestamp| Int) (|blockhash| (Array Int Int)) (|msg.data| |bytes_tuple|) (|msg.sender| Int) (|msg.sig| Int) (|msg.value| Int) (|tx.gasprice| Int) (|tx.origin| Int))))) +(declare-datatypes ((|tx_type| 0)) (((|tx_type| (|blobhash| (Array Int Int)) (|block.basefee| Int) (|block.blobbasefee| Int) (|block.chainid| Int) (|block.coinbase| Int) (|block.gaslimit| Int) (|block.number| Int) (|block.prevrandao| Int) (|block.timestamp| Int) (|blockhash| (Array Int Int)) (|msg.data| |bytes_tuple|) (|msg.sender| Int) (|msg.sig| Int) (|msg.value| Int) (|tx.gasprice| Int) (|tx.origin| Int))))) (declare-fun |summary_constructor_2_C_14| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool) (assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (this_0 Int)) (=> (= error_0 0) (nondet_interface_1_C_14 error_0 this_0 abi_0 crypto_0 state_0 state_0))) @@ -72,7 +72,7 @@ (block_9_function_f__13_14 error_0 this_0 abi_0 crypto_0 tx_0 state_0 x_3_0 state_1 x_3_1)) ) (assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_3_0 Int) (x_3_1 Int) (x_3_2 Int)) -(=> (and (and (block_9_function_f__13_14 error_0 this_0 abi_0 crypto_0 tx_0 state_0 x_3_0 state_1 x_3_1) (and (summary_3_function_f__13_14 error_1 this_0 abi_0 crypto_0 tx_0 state_2 x_3_1 state_3 x_3_2) (and (= state_2 (|state_type| (store (|balances| state_1) this_0 (+ (select (|balances| state_1) this_0) funds_2_0)))) (and (and (>= (+ (select (|balances| state_1) this_0) funds_2_0) 0) (<= (+ (select (|balances| state_1) this_0) funds_2_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935)) (and (>= funds_2_0 (|msg.value| tx_0)) (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (and (and (and (and (and (= (|msg.value| tx_0) 0) (= (|msg.sig| tx_0) 3017696395)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 0) 179)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 1) 222)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 2) 100)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 3) 139)) (>= (|bytes_tuple_accessor_length| (|msg.data| tx_0)) 4))) (and (and (and (and (= state_1 state_0) (= error_0 0)) true) (and true (= x_3_1 x_3_0))) true))))))) true) (summary_4_function_f__13_14 error_1 this_0 abi_0 crypto_0 tx_0 state_0 x_3_0 state_3 x_3_2))) +(=> (and (and (block_9_function_f__13_14 error_0 this_0 abi_0 crypto_0 tx_0 state_0 x_3_0 state_1 x_3_1) (and (summary_3_function_f__13_14 error_1 this_0 abi_0 crypto_0 tx_0 state_2 x_3_1 state_3 x_3_2) (and (= state_2 (|state_type| (store (|balances| state_1) this_0 (+ (select (|balances| state_1) this_0) funds_2_0)))) (and (and (>= (+ (select (|balances| state_1) this_0) funds_2_0) 0) (<= (+ (select (|balances| state_1) this_0) funds_2_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935)) (and (>= funds_2_0 (|msg.value| tx_0)) (and (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.blobbasefee| tx_0) 0) (<= (|block.blobbasefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (and (and (and (and (and (= (|msg.value| tx_0) 0) (= (|msg.sig| tx_0) 3017696395)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 0) 179)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 1) 222)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 2) 100)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 3) 139)) (>= (|bytes_tuple_accessor_length| (|msg.data| tx_0)) 4))) (and (and (and (and (= state_1 state_0) (= error_0 0)) true) (and true (= x_3_1 x_3_0))) true))))))) true) (summary_4_function_f__13_14 error_1 this_0 abi_0 crypto_0 tx_0 state_0 x_3_0 state_3 x_3_2))) ) (assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_3_0 Int) (x_3_1 Int)) (=> (and (and (interface_0_C_14 this_0 abi_0 crypto_0 state_0) true) (and (summary_4_function_f__13_14 error_0 this_0 abi_0 crypto_0 tx_0 state_0 x_3_0 state_1 x_3_1) (= error_0 0))) (interface_0_C_14 this_0 abi_0 crypto_0 state_1))) @@ -100,7 +100,7 @@ (=> (and (and (implicit_constructor_entry_13_C_14 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (and (= error_1 0) (and (contract_initializer_10_C_14 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2) true))) true) (summary_constructor_2_C_14 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_2))) ) (assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|)) -(=> (and (and (summary_constructor_2_C_14 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (= (|msg.value| tx_0) 0)) (= error_0 0))) (interface_0_C_14 this_0 abi_0 crypto_0 state_1))) +(=> (and (and (summary_constructor_2_C_14 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) (and (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.blobbasefee| tx_0) 0) (<= (|block.blobbasefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (= (|msg.value| tx_0) 0)) (= error_0 0))) (interface_0_C_14 this_0 abi_0 crypto_0 state_1))) ) (declare-fun |error_target_3| () Bool) (assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_3_0 Int) (x_3_1 Int)) diff --git a/test/libsolidity/smtCheckerTests/bmc_coverage/compound_bitwise_or_uint_3.sol b/test/libsolidity/smtCheckerTests/bmc_coverage/compound_bitwise_or_uint_3.sol index 02d538d7d64c..9562653806df 100644 --- a/test/libsolidity/smtCheckerTests/bmc_coverage/compound_bitwise_or_uint_3.sol +++ b/test/libsolidity/smtCheckerTests/bmc_coverage/compound_bitwise_or_uint_3.sol @@ -12,4 +12,4 @@ contract C { // SMTEngine: bmc // SMTShowUnproved: no // ---- -// Warning 2788: BMC: 1 verification condition(s) could not be proved. Enable the model checker option "show unproved" to see all of them. Consider choosing a specific contract to be verified in order to reduce the solving problems. Consider increasing the timeout per query. +// Info 6002: BMC: 1 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/external_calls/external_safe.sol b/test/libsolidity/smtCheckerTests/external_calls/external_safe.sol index a28e4852b0f2..8afc574a8b9e 100644 --- a/test/libsolidity/smtCheckerTests/external_calls/external_safe.sol +++ b/test/libsolidity/smtCheckerTests/external_calls/external_safe.sol @@ -6,17 +6,16 @@ contract C { uint x; D d; function f() public { - if (x < 5) + if (x < 4) ++x; } function g() public { d.d(); - assert(x < 6); + assert(x < 5); } } // ==== // SMTEngine: all // SMTTargets: assert -// SMTIgnoreOS: linux // ---- // Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/operators/compound_bitwise_or_uint_3.sol b/test/libsolidity/smtCheckerTests/operators/compound_bitwise_or_uint_3.sol index 2650b08975bd..ff246b362c54 100644 --- a/test/libsolidity/smtCheckerTests/operators/compound_bitwise_or_uint_3.sol +++ b/test/libsolidity/smtCheckerTests/operators/compound_bitwise_or_uint_3.sol @@ -12,4 +12,4 @@ contract C { // SMTEngine: all // ---- // Warning 6328: (125-140): CHC: Assertion violation might happen here. -// Warning 7812: (125-140): BMC: Assertion violation might happen here. +// Info 6002: BMC: 1 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/operators/userDefined/user_defined_operator_matches_equivalent_function_call.sol b/test/libsolidity/smtCheckerTests/operators/userDefined/user_defined_operator_matches_equivalent_function_call.sol index 30f6a0ba9781..76ad6db55384 100644 --- a/test/libsolidity/smtCheckerTests/operators/userDefined/user_defined_operator_matches_equivalent_function_call.sol +++ b/test/libsolidity/smtCheckerTests/operators/userDefined/user_defined_operator_matches_equivalent_function_call.sol @@ -53,10 +53,10 @@ contract C { } // ==== // SMTEngine: all -// SMTIgnoreOS: macos // SMTTargets: assert // ---- // Warning 6328: (2209-2235): CHC: Assertion violation might happen here. // Warning 6328: (2245-2271): CHC: Assertion violation might happen here. // Info 1391: CHC: 14 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. -// Info 6002: BMC: 2 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. +// Warning 7812: (2245-2271): BMC: Assertion violation might happen here. +// Info 6002: BMC: 1 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/special/blobhash_beyond_limit.sol b/test/libsolidity/smtCheckerTests/special/blobhash_beyond_limit.sol new file mode 100644 index 000000000000..b68a9aa4b464 --- /dev/null +++ b/test/libsolidity/smtCheckerTests/special/blobhash_beyond_limit.sol @@ -0,0 +1,11 @@ +contract C { + function f(uint index) public view { + uint limit = 9; // Since PECTRA + require(index >= limit); + assert(blobhash(index) == 0); + } +} +// ==== +// SMTEngine: all +// ---- +// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/special/tx_data_immutable.sol b/test/libsolidity/smtCheckerTests/special/tx_data_immutable.sol index 21a924b1fa78..e2e7e9ebd290 100644 --- a/test/libsolidity/smtCheckerTests/special/tx_data_immutable.sol +++ b/test/libsolidity/smtCheckerTests/special/tx_data_immutable.sol @@ -1,6 +1,8 @@ contract C { - bytes32 bhash; + bytes32 blob_hash; + bytes32 block_hash; uint bfee; + uint blobfee; address coin; uint dif; uint prevrandao; @@ -15,8 +17,10 @@ contract C { address origin; function f() public payable { - bhash = blockhash(12); + blob_hash = blobhash(1); + block_hash = blockhash(12); bfee = block.basefee; + blobfee = block.blobbasefee; coin = block.coinbase; dif = block.difficulty; prevrandao = block.prevrandao; @@ -32,8 +36,10 @@ contract C { fi(); - assert(bhash == blockhash(12)); + assert(blob_hash == blobhash(1)); + assert(block_hash == blockhash(12)); assert(bfee == block.basefee); + assert(blobfee == block.blobbasefee); assert(coin == block.coinbase); assert(dif == block.difficulty); assert(prevrandao == block.prevrandao); @@ -49,8 +55,10 @@ contract C { } function fi() internal view { - assert(bhash == blockhash(12)); + assert(blob_hash == blobhash(1)); + assert(block_hash == blockhash(12)); assert(bfee == block.basefee); + assert(blobfee == block.blobbasefee); assert(coin == block.coinbase); assert(dif == block.difficulty); assert(prevrandao == block.prevrandao); @@ -68,7 +76,7 @@ contract C { // ==== // SMTEngine: all // ---- -// Warning 8417: (329-345): Since the VM version paris, "difficulty" was replaced by "prevrandao", which now returns a random number based on the beacon chain. -// Warning 8417: (714-730): Since the VM version paris, "difficulty" was replaced by "prevrandao", which now returns a random number based on the beacon chain. -// Warning 8417: (1229-1245): Since the VM version paris, "difficulty" was replaced by "prevrandao", which now returns a random number based on the beacon chain. -// Info 1391: CHC: 28 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. +// Warning 8417: (432-448): Since the VM version paris, "difficulty" was replaced by "prevrandao", which now returns a random number based on the beacon chain. +// Warning 8417: (898-914): Since the VM version paris, "difficulty" was replaced by "prevrandao", which now returns a random number based on the beacon chain. +// Warning 8417: (1494-1510): Since the VM version paris, "difficulty" was replaced by "prevrandao", which now returns a random number based on the beacon chain. +// Info 1391: CHC: 32 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/special/tx_data_immutable_fail.sol b/test/libsolidity/smtCheckerTests/special/tx_data_immutable_fail.sol index 2b16f2d1aab7..be8436e82673 100644 --- a/test/libsolidity/smtCheckerTests/special/tx_data_immutable_fail.sol +++ b/test/libsolidity/smtCheckerTests/special/tx_data_immutable_fail.sol @@ -1,5 +1,8 @@ contract C { - bytes32 bhash; + bytes32 blob_hash; + bytes32 block_hash; + uint bfee; + uint blobfee; address coin; uint dif; uint prevrandao; @@ -14,7 +17,10 @@ contract C { address origin; function f() public payable { - bhash = blockhash(12); + blob_hash = blobhash(1); + block_hash = blockhash(12); + bfee = block.basefee; + blobfee = block.blobbasefee; coin = block.coinbase; dif = block.difficulty; prevrandao = block.prevrandao; @@ -30,8 +36,11 @@ contract C { fi(); - assert(bhash == blockhash(122)); - assert(coin != block.coinbase); + assert(blob_hash == blobhash(2)); + assert(block_hash == blockhash(122)); + assert(bfee != block.basefee); + assert(blobfee != block.blobbasefee); + assert(coin != block.coinbase); assert(dif != block.difficulty); assert(prevrandao != block.prevrandao); assert(glimit != block.gaslimit); @@ -46,7 +55,10 @@ contract C { } function fi() internal view { - assert(bhash == blockhash(122)); + assert(blob_hash == blobhash(2)); + assert(block_hash == blockhash(122)); + assert(bfee != block.basefee); + assert(blobfee != block.blobbasefee); assert(coin != block.coinbase); assert(dif != block.difficulty); assert(prevrandao != block.prevrandao); @@ -65,32 +77,38 @@ contract C { // SMTEngine: all // SMTIgnoreCex: yes // ---- -// Warning 8417: (293-309): Since the VM version paris, "difficulty" was replaced by "prevrandao", which now returns a random number based on the beacon chain. -// Warning 8417: (646-662): Since the VM version paris, "difficulty" was replaced by "prevrandao", which now returns a random number based on the beacon chain. -// Warning 8417: (1129-1145): Since the VM version paris, "difficulty" was replaced by "prevrandao", which now returns a random number based on the beacon chain. -// Warning 6328: (563-594): CHC: Assertion violation happens here. -// Warning 6328: (598-628): CHC: Assertion violation happens here. -// Warning 6328: (632-663): CHC: Assertion violation happens here. -// Warning 6328: (667-705): CHC: Assertion violation happens here. -// Warning 6328: (709-741): CHC: Assertion violation happens here. -// Warning 6328: (745-775): CHC: Assertion violation happens here. -// Warning 6328: (779-812): CHC: Assertion violation happens here. -// Warning 6328: (816-855): CHC: Assertion violation happens here. -// Warning 6328: (859-887): CHC: Assertion violation happens here. -// Warning 6328: (891-913): CHC: Assertion violation happens here. -// Warning 6328: (917-943): CHC: Assertion violation happens here. -// Warning 6328: (947-976): CHC: Assertion violation happens here. -// Warning 6328: (980-1007): CHC: Assertion violation happens here. -// Warning 6328: (1046-1077): CHC: Assertion violation happens here. -// Warning 6328: (1081-1111): CHC: Assertion violation happens here. -// Warning 6328: (1115-1146): CHC: Assertion violation happens here. -// Warning 6328: (1150-1188): CHC: Assertion violation happens here. -// Warning 6328: (1192-1224): CHC: Assertion violation happens here. -// Warning 6328: (1228-1258): CHC: Assertion violation happens here. -// Warning 6328: (1262-1295): CHC: Assertion violation happens here. -// Warning 6328: (1299-1338): CHC: Assertion violation happens here. -// Warning 6328: (1342-1370): CHC: Assertion violation happens here. -// Warning 6328: (1374-1396): CHC: Assertion violation happens here. -// Warning 6328: (1400-1426): CHC: Assertion violation happens here. -// Warning 6328: (1430-1459): CHC: Assertion violation happens here. -// Warning 6328: (1463-1490): CHC: Assertion violation happens here. +// Warning 8417: (474-490): Since the VM version paris, "difficulty" was replaced by "prevrandao", which now returns a random number based on the beacon chain. +// Warning 8417: (969-985): Since the VM version paris, "difficulty" was replaced by "prevrandao", which now returns a random number based on the beacon chain. +// Warning 8417: (1580-1596): Since the VM version paris, "difficulty" was replaced by "prevrandao", which now returns a random number based on the beacon chain. +// Warning 6328: (744-776): CHC: Assertion violation happens here.\nCounterexample:\nblob_hash = 0x0, block_hash = 0x0986, bfee = 0, blobfee = 0, coin = 0x0, dif = 18446744073709551617, prevrandao = 18446744073709551617, glimit = 0, number = 0, tstamp = 0, mdata = [0x26, 0x12, 0x1f, 0xf0], sender = 0x0, sig = 0x26121ff0, value = 0, gprice = 0, origin = 0x0\n\nTransaction trace:\nC.constructor()\nState: blob_hash = 0x0, block_hash = 0x0, bfee = 0, blobfee = 0, coin = 0x0, dif = 0, prevrandao = 0, glimit = 0, number = 0, tstamp = 0, mdata = [], sender = 0x0, sig = 0x0, value = 0, gprice = 0, origin = 0x0\nC.f(){ block.basefee: 0, block.blobbasefee: 0, block.coinbase: 0x0, block.gaslimit: 0, block.number: 0, block.prevrandao: 18446744073709551617, block.timestamp: 0, msg.data: [0x26, 0x12, 0x1f, 0xf0], msg.sender: 0x0, msg.sig: 0x26121ff0, msg.value: 0, tx.gasprice: 0, tx.origin: 0x0 }\n C.fi() -- internal call +// Warning 6328: (780-816): CHC: Assertion violation happens here.\nCounterexample:\nblob_hash = 0x0, block_hash = 0x0, bfee = 0, blobfee = 0, coin = 0x0, dif = 18446744073709551617, prevrandao = 18446744073709551617, glimit = 0, number = 0, tstamp = 0, mdata = [0x26, 0x12, 0x1f, 0xf0], sender = 0x0, sig = 0x26121ff0, value = 0, gprice = 0, origin = 0x0\n\nTransaction trace:\nC.constructor()\nState: blob_hash = 0x0, block_hash = 0x0, bfee = 0, blobfee = 0, coin = 0x0, dif = 0, prevrandao = 0, glimit = 0, number = 0, tstamp = 0, mdata = [], sender = 0x0, sig = 0x0, value = 0, gprice = 0, origin = 0x0\nC.f(){ block.basefee: 0, block.blobbasefee: 0, block.coinbase: 0x0, block.gaslimit: 0, block.number: 0, block.prevrandao: 18446744073709551617, block.timestamp: 0, msg.data: [0x26, 0x12, 0x1f, 0xf0], msg.sender: 0x0, msg.sig: 0x26121ff0, msg.value: 0, tx.gasprice: 0, tx.origin: 0x0 }\n C.fi() -- internal call +// Warning 6328: (820-849): CHC: Assertion violation happens here.\nCounterexample:\nblob_hash = 0x2e16, block_hash = 0x2298, bfee = 0, blobfee = 0, coin = 0x0, dif = 18446744073709551617, prevrandao = 18446744073709551617, glimit = 0, number = 0, tstamp = 0, mdata = [0x26, 0x12, 0x1f, 0xf0], sender = 0x0, sig = 0x26121ff0, value = 0, gprice = 0, origin = 0x0\n\nTransaction trace:\nC.constructor()\nState: blob_hash = 0x0, block_hash = 0x0, bfee = 0, blobfee = 0, coin = 0x0, dif = 0, prevrandao = 0, glimit = 0, number = 0, tstamp = 0, mdata = [], sender = 0x0, sig = 0x0, value = 0, gprice = 0, origin = 0x0\nC.f(){ block.basefee: 0, block.blobbasefee: 0, block.coinbase: 0x0, block.gaslimit: 0, block.number: 0, block.prevrandao: 18446744073709551617, block.timestamp: 0, msg.data: [0x26, 0x12, 0x1f, 0xf0], msg.sender: 0x0, msg.sig: 0x26121ff0, msg.value: 0, tx.gasprice: 0, tx.origin: 0x0 }\n C.fi() -- internal call +// Warning 6328: (867-903): CHC: Assertion violation happens here.\nCounterexample:\nblob_hash = 0x0, block_hash = 0x0, bfee = 0, blobfee = 0, coin = 0x0, dif = 18446744073709551617, prevrandao = 18446744073709551617, glimit = 0, number = 0, tstamp = 0, mdata = [0x26, 0x12, 0x1f, 0xf0], sender = 0x0, sig = 0x26121ff0, value = 0, gprice = 0, origin = 0x0\n\nTransaction trace:\nC.constructor()\nState: blob_hash = 0x0, block_hash = 0x0, bfee = 0, blobfee = 0, coin = 0x0, dif = 0, prevrandao = 0, glimit = 0, number = 0, tstamp = 0, mdata = [], sender = 0x0, sig = 0x0, value = 0, gprice = 0, origin = 0x0\nC.f(){ block.basefee: 0, block.blobbasefee: 0, block.coinbase: 0x0, block.gaslimit: 0, block.number: 0, block.prevrandao: 18446744073709551617, block.timestamp: 0, msg.data: [0x26, 0x12, 0x1f, 0xf0], msg.sender: 0x0, msg.sig: 0x26121ff0, msg.value: 0, tx.gasprice: 0, tx.origin: 0x0 }\n C.fi() -- internal call +// Warning 6328: (921-951): CHC: Assertion violation happens here.\nCounterexample:\nblob_hash = 0x0, block_hash = 0x0, bfee = 0, blobfee = 0, coin = 0x0, dif = 18446744073709551617, prevrandao = 18446744073709551617, glimit = 0, number = 0, tstamp = 0, mdata = [0x26, 0x12, 0x1f, 0xf0], sender = 0x0, sig = 0x26121ff0, value = 0, gprice = 0, origin = 0x0\n\nTransaction trace:\nC.constructor()\nState: blob_hash = 0x0, block_hash = 0x0, bfee = 0, blobfee = 0, coin = 0x0, dif = 0, prevrandao = 0, glimit = 0, number = 0, tstamp = 0, mdata = [], sender = 0x0, sig = 0x0, value = 0, gprice = 0, origin = 0x0\nC.f(){ block.basefee: 0, block.blobbasefee: 0, block.coinbase: 0x0, block.gaslimit: 0, block.number: 0, block.prevrandao: 18446744073709551617, block.timestamp: 0, msg.data: [0x26, 0x12, 0x1f, 0xf0], msg.sender: 0x0, msg.sig: 0x26121ff0, msg.value: 0, tx.gasprice: 0, tx.origin: 0x0 }\n C.fi() -- internal call +// Warning 6328: (955-986): CHC: Assertion violation happens here.\nCounterexample:\nblob_hash = 0x2298, block_hash = 0x0986, bfee = 0, blobfee = 0, coin = 0x0, dif = 18446744073709551617, prevrandao = 18446744073709551617, glimit = 0, number = 0, tstamp = 0, mdata = [0x26, 0x12, 0x1f, 0xf0], sender = 0x0, sig = 0x26121ff0, value = 0, gprice = 0, origin = 0x0\n\nTransaction trace:\nC.constructor()\nState: blob_hash = 0x0, block_hash = 0x0, bfee = 0, blobfee = 0, coin = 0x0, dif = 0, prevrandao = 0, glimit = 0, number = 0, tstamp = 0, mdata = [], sender = 0x0, sig = 0x0, value = 0, gprice = 0, origin = 0x0\nC.f(){ block.basefee: 0, block.blobbasefee: 0, block.coinbase: 0x0, block.gaslimit: 0, block.number: 0, block.prevrandao: 18446744073709551617, block.timestamp: 0, msg.data: [0x26, 0x12, 0x1f, 0xf0], msg.sender: 0x0, msg.sig: 0x26121ff0, msg.value: 0, tx.gasprice: 0, tx.origin: 0x0 }\n C.fi() -- internal call +// Warning 6328: (990-1028): CHC: Assertion violation happens here.\nCounterexample:\nblob_hash = 0x0, block_hash = 0x0986, bfee = 0, blobfee = 0, coin = 0x0, dif = 18446744073709551617, prevrandao = 18446744073709551617, glimit = 0, number = 0, tstamp = 0, mdata = [0x26, 0x12, 0x1f, 0xf0], sender = 0x0, sig = 0x26121ff0, value = 0, gprice = 0, origin = 0x0\n\nTransaction trace:\nC.constructor()\nState: blob_hash = 0x0, block_hash = 0x0, bfee = 0, blobfee = 0, coin = 0x0, dif = 0, prevrandao = 0, glimit = 0, number = 0, tstamp = 0, mdata = [], sender = 0x0, sig = 0x0, value = 0, gprice = 0, origin = 0x0\nC.f(){ block.basefee: 0, block.blobbasefee: 0, block.coinbase: 0x0, block.gaslimit: 0, block.number: 0, block.prevrandao: 18446744073709551617, block.timestamp: 0, msg.data: [0x26, 0x12, 0x1f, 0xf0], msg.sender: 0x0, msg.sig: 0x26121ff0, msg.value: 0, tx.gasprice: 0, tx.origin: 0x0 }\n C.fi() -- internal call +// Warning 6328: (1032-1064): CHC: Assertion violation happens here.\nCounterexample:\nblob_hash = 0x0, block_hash = 0x0986, bfee = 0, blobfee = 0, coin = 0x0, dif = 18446744073709551617, prevrandao = 18446744073709551617, glimit = 0, number = 0, tstamp = 0, mdata = [0x26, 0x12, 0x1f, 0xf0], sender = 0x0, sig = 0x26121ff0, value = 0, gprice = 0, origin = 0x0\n\nTransaction trace:\nC.constructor()\nState: blob_hash = 0x0, block_hash = 0x0, bfee = 0, blobfee = 0, coin = 0x0, dif = 0, prevrandao = 0, glimit = 0, number = 0, tstamp = 0, mdata = [], sender = 0x0, sig = 0x0, value = 0, gprice = 0, origin = 0x0\nC.f(){ block.basefee: 0, block.blobbasefee: 0, block.coinbase: 0x0, block.gaslimit: 0, block.number: 0, block.prevrandao: 18446744073709551617, block.timestamp: 0, msg.data: [0x26, 0x12, 0x1f, 0xf0], msg.sender: 0x0, msg.sig: 0x26121ff0, msg.value: 0, tx.gasprice: 0, tx.origin: 0x0 }\n C.fi() -- internal call +// Warning 6328: (1068-1098): CHC: Assertion violation happens here.\nCounterexample:\nblob_hash = 0x2298, block_hash = 0x0986, bfee = 0, blobfee = 0, coin = 0x0, dif = 18446744073709551617, prevrandao = 18446744073709551617, glimit = 0, number = 0, tstamp = 0, mdata = [0x26, 0x12, 0x1f, 0xf0], sender = 0x0, sig = 0x26121ff0, value = 0, gprice = 0, origin = 0x0\n\nTransaction trace:\nC.constructor()\nState: blob_hash = 0x0, block_hash = 0x0, bfee = 0, blobfee = 0, coin = 0x0, dif = 0, prevrandao = 0, glimit = 0, number = 0, tstamp = 0, mdata = [], sender = 0x0, sig = 0x0, value = 0, gprice = 0, origin = 0x0\nC.f(){ block.basefee: 0, block.blobbasefee: 0, block.coinbase: 0x0, block.gaslimit: 0, block.number: 0, block.prevrandao: 18446744073709551617, block.timestamp: 0, msg.data: [0x26, 0x12, 0x1f, 0xf0], msg.sender: 0x0, msg.sig: 0x26121ff0, msg.value: 0, tx.gasprice: 0, tx.origin: 0x0 }\n C.fi() -- internal call +// Warning 6328: (1102-1135): CHC: Assertion violation happens here.\nCounterexample:\nblob_hash = 0x2298, block_hash = 0x0986, bfee = 0, blobfee = 0, coin = 0x0, dif = 18446744073709551617, prevrandao = 18446744073709551617, glimit = 0, number = 0, tstamp = 0, mdata = [0x26, 0x12, 0x1f, 0xf0], sender = 0x0, sig = 0x26121ff0, value = 0, gprice = 0, origin = 0x0\n\nTransaction trace:\nC.constructor()\nState: blob_hash = 0x0, block_hash = 0x0, bfee = 0, blobfee = 0, coin = 0x0, dif = 0, prevrandao = 0, glimit = 0, number = 0, tstamp = 0, mdata = [], sender = 0x0, sig = 0x0, value = 0, gprice = 0, origin = 0x0\nC.f(){ block.basefee: 0, block.blobbasefee: 0, block.coinbase: 0x0, block.gaslimit: 0, block.number: 0, block.prevrandao: 18446744073709551617, block.timestamp: 0, msg.data: [0x26, 0x12, 0x1f, 0xf0], msg.sender: 0x0, msg.sig: 0x26121ff0, msg.value: 0, tx.gasprice: 0, tx.origin: 0x0 }\n C.fi() -- internal call +// Warning 6328: (1139-1178): CHC: Assertion violation happens here.\nCounterexample:\nblob_hash = 0x2298, block_hash = 0x0986, bfee = 0, blobfee = 0, coin = 0x0, dif = 18446744073709551617, prevrandao = 18446744073709551617, glimit = 0, number = 0, tstamp = 0, mdata = [0x26, 0x12, 0x1f, 0xf0], sender = 0x0, sig = 0x26121ff0, value = 0, gprice = 0, origin = 0x0\n\nTransaction trace:\nC.constructor()\nState: blob_hash = 0x0, block_hash = 0x0, bfee = 0, blobfee = 0, coin = 0x0, dif = 0, prevrandao = 0, glimit = 0, number = 0, tstamp = 0, mdata = [], sender = 0x0, sig = 0x0, value = 0, gprice = 0, origin = 0x0\nC.f(){ block.basefee: 0, block.blobbasefee: 0, block.coinbase: 0x0, block.gaslimit: 0, block.number: 0, block.prevrandao: 18446744073709551617, block.timestamp: 0, msg.data: [0x26, 0x12, 0x1f, 0xf0], msg.sender: 0x0, msg.sig: 0x26121ff0, msg.value: 0, tx.gasprice: 0, tx.origin: 0x0 }\n C.fi() -- internal call +// Warning 6328: (1182-1210): CHC: Assertion violation happens here.\nCounterexample:\nblob_hash = 0x0, block_hash = 0x0, bfee = 0, blobfee = 0, coin = 0x0, dif = 18446744073709551617, prevrandao = 18446744073709551617, glimit = 0, number = 0, tstamp = 0, mdata = [0x26, 0x12, 0x1f, 0xf0], sender = 0x0, sig = 0x26121ff0, value = 0, gprice = 0, origin = 0x0\n\nTransaction trace:\nC.constructor()\nState: blob_hash = 0x0, block_hash = 0x0, bfee = 0, blobfee = 0, coin = 0x0, dif = 0, prevrandao = 0, glimit = 0, number = 0, tstamp = 0, mdata = [], sender = 0x0, sig = 0x0, value = 0, gprice = 0, origin = 0x0\nC.f(){ block.basefee: 0, block.blobbasefee: 0, block.coinbase: 0x0, block.gaslimit: 0, block.number: 0, block.prevrandao: 18446744073709551617, block.timestamp: 0, msg.data: [0x26, 0x12, 0x1f, 0xf0], msg.sender: 0x0, msg.sig: 0x26121ff0, msg.value: 0, tx.gasprice: 0, tx.origin: 0x0 }\n C.fi() -- internal call +// Warning 6328: (1214-1236): CHC: Assertion violation happens here.\nCounterexample:\nblob_hash = 0x0, block_hash = 0x0, bfee = 0, blobfee = 0, coin = 0x0, dif = 18446744073709551617, prevrandao = 18446744073709551617, glimit = 0, number = 0, tstamp = 0, mdata = [0x26, 0x12, 0x1f, 0xf0], sender = 0x0, sig = 0x26121ff0, value = 0, gprice = 0, origin = 0x0\n\nTransaction trace:\nC.constructor()\nState: blob_hash = 0x0, block_hash = 0x0, bfee = 0, blobfee = 0, coin = 0x0, dif = 0, prevrandao = 0, glimit = 0, number = 0, tstamp = 0, mdata = [], sender = 0x0, sig = 0x0, value = 0, gprice = 0, origin = 0x0\nC.f(){ block.basefee: 0, block.blobbasefee: 0, block.coinbase: 0x0, block.gaslimit: 0, block.number: 0, block.prevrandao: 18446744073709551617, block.timestamp: 0, msg.data: [0x26, 0x12, 0x1f, 0xf0], msg.sender: 0x0, msg.sig: 0x26121ff0, msg.value: 0, tx.gasprice: 0, tx.origin: 0x0 }\n C.fi() -- internal call +// Warning 6328: (1240-1266): CHC: Assertion violation happens here.\nCounterexample:\nblob_hash = 0x0, block_hash = 0x0986, bfee = 0, blobfee = 0, coin = 0x0, dif = 18446744073709551617, prevrandao = 18446744073709551617, glimit = 0, number = 0, tstamp = 0, mdata = [0x26, 0x12, 0x1f, 0xf0], sender = 0x0, sig = 0x26121ff0, value = 0, gprice = 0, origin = 0x0\n\nTransaction trace:\nC.constructor()\nState: blob_hash = 0x0, block_hash = 0x0, bfee = 0, blobfee = 0, coin = 0x0, dif = 0, prevrandao = 0, glimit = 0, number = 0, tstamp = 0, mdata = [], sender = 0x0, sig = 0x0, value = 0, gprice = 0, origin = 0x0\nC.f(){ block.basefee: 0, block.blobbasefee: 0, block.coinbase: 0x0, block.gaslimit: 0, block.number: 0, block.prevrandao: 18446744073709551617, block.timestamp: 0, msg.data: [0x26, 0x12, 0x1f, 0xf0], msg.sender: 0x0, msg.sig: 0x26121ff0, msg.value: 0, tx.gasprice: 0, tx.origin: 0x0 }\n C.fi() -- internal call +// Warning 6328: (1270-1299): CHC: Assertion violation happens here.\nCounterexample:\nblob_hash = 0x2298, block_hash = 0x0, bfee = 0, blobfee = 0, coin = 0x0, dif = 18446744073709551617, prevrandao = 18446744073709551617, glimit = 0, number = 0, tstamp = 0, mdata = [0x26, 0x12, 0x1f, 0xf0], sender = 0x0, sig = 0x26121ff0, value = 0, gprice = 0, origin = 0x0\n\nTransaction trace:\nC.constructor()\nState: blob_hash = 0x0, block_hash = 0x0, bfee = 0, blobfee = 0, coin = 0x0, dif = 0, prevrandao = 0, glimit = 0, number = 0, tstamp = 0, mdata = [], sender = 0x0, sig = 0x0, value = 0, gprice = 0, origin = 0x0\nC.f(){ block.basefee: 0, block.blobbasefee: 0, block.coinbase: 0x0, block.gaslimit: 0, block.number: 0, block.prevrandao: 18446744073709551617, block.timestamp: 0, msg.data: [0x26, 0x12, 0x1f, 0xf0], msg.sender: 0x0, msg.sig: 0x26121ff0, msg.value: 0, tx.gasprice: 0, tx.origin: 0x0 }\n C.fi() -- internal call +// Warning 6328: (1303-1330): CHC: Assertion violation happens here.\nCounterexample:\nblob_hash = 0x0, block_hash = 0x0, bfee = 0, blobfee = 0, coin = 0x0, dif = 18446744073709551617, prevrandao = 18446744073709551617, glimit = 0, number = 0, tstamp = 0, mdata = [0x26, 0x12, 0x1f, 0xf0], sender = 0x0, sig = 0x26121ff0, value = 0, gprice = 0, origin = 0x0\n\nTransaction trace:\nC.constructor()\nState: blob_hash = 0x0, block_hash = 0x0, bfee = 0, blobfee = 0, coin = 0x0, dif = 0, prevrandao = 0, glimit = 0, number = 0, tstamp = 0, mdata = [], sender = 0x0, sig = 0x0, value = 0, gprice = 0, origin = 0x0\nC.f(){ block.basefee: 0, block.blobbasefee: 0, block.coinbase: 0x0, block.gaslimit: 0, block.number: 0, block.prevrandao: 18446744073709551617, block.timestamp: 0, msg.data: [0x26, 0x12, 0x1f, 0xf0], msg.sender: 0x0, msg.sig: 0x26121ff0, msg.value: 0, tx.gasprice: 0, tx.origin: 0x0 }\n C.fi() -- internal call +// Warning 6328: (1369-1401): CHC: Assertion violation happens here.\nCounterexample:\nblob_hash = 0x0, block_hash = 0x0, bfee = 0, blobfee = 0, coin = 0x0, dif = 18446744073709551617, prevrandao = 18446744073709551617, glimit = 0, number = 0, tstamp = 0, mdata = [0x26, 0x12, 0x1f, 0xf0], sender = 0x0, sig = 0x26121ff0, value = 0, gprice = 0, origin = 0x0\n\nTransaction trace:\nC.constructor()\nState: blob_hash = 0x0, block_hash = 0x0, bfee = 0, blobfee = 0, coin = 0x0, dif = 0, prevrandao = 0, glimit = 0, number = 0, tstamp = 0, mdata = [], sender = 0x0, sig = 0x0, value = 0, gprice = 0, origin = 0x0\nC.f(){ block.basefee: 0, block.blobbasefee: 0, block.coinbase: 0x0, block.gaslimit: 0, block.number: 0, block.prevrandao: 18446744073709551617, block.timestamp: 0, msg.data: [0x26, 0x12, 0x1f, 0xf0], msg.sender: 0x0, msg.sig: 0x26121ff0, msg.value: 0, tx.gasprice: 0, tx.origin: 0x0 }\n C.fi() -- internal call +// Warning 6328: (1405-1441): CHC: Assertion violation happens here.\nCounterexample:\nblob_hash = 0x0986, block_hash = 0x2298, bfee = 0, blobfee = 0, coin = 0x0, dif = 18446744073709551617, prevrandao = 18446744073709551617, glimit = 0, number = 0, tstamp = 0, mdata = [0x26, 0x12, 0x1f, 0xf0], sender = 0x0, sig = 0x26121ff0, value = 0, gprice = 0, origin = 0x0\n\nTransaction trace:\nC.constructor()\nState: blob_hash = 0x0, block_hash = 0x0, bfee = 0, blobfee = 0, coin = 0x0, dif = 0, prevrandao = 0, glimit = 0, number = 0, tstamp = 0, mdata = [], sender = 0x0, sig = 0x0, value = 0, gprice = 0, origin = 0x0\nC.f(){ block.basefee: 0, block.blobbasefee: 0, block.coinbase: 0x0, block.gaslimit: 0, block.number: 0, block.prevrandao: 18446744073709551617, block.timestamp: 0, msg.data: [0x26, 0x12, 0x1f, 0xf0], msg.sender: 0x0, msg.sig: 0x26121ff0, msg.value: 0, tx.gasprice: 0, tx.origin: 0x0 }\n C.fi() -- internal call +// Warning 6328: (1445-1474): CHC: Assertion violation happens here.\nCounterexample:\nblob_hash = 0x0, block_hash = 0x0, bfee = 0, blobfee = 0, coin = 0x0, dif = 18446744073709551617, prevrandao = 18446744073709551617, glimit = 0, number = 0, tstamp = 0, mdata = [0x26, 0x12, 0x1f, 0xf0], sender = 0x0, sig = 0x26121ff0, value = 0, gprice = 0, origin = 0x0\n\nTransaction trace:\nC.constructor()\nState: blob_hash = 0x0, block_hash = 0x0, bfee = 0, blobfee = 0, coin = 0x0, dif = 0, prevrandao = 0, glimit = 0, number = 0, tstamp = 0, mdata = [], sender = 0x0, sig = 0x0, value = 0, gprice = 0, origin = 0x0\nC.f(){ block.basefee: 0, block.blobbasefee: 0, block.coinbase: 0x0, block.gaslimit: 0, block.number: 0, block.prevrandao: 18446744073709551617, block.timestamp: 0, msg.data: [0x26, 0x12, 0x1f, 0xf0], msg.sender: 0x0, msg.sig: 0x26121ff0, msg.value: 0, tx.gasprice: 0, tx.origin: 0x0 }\n C.fi() -- internal call +// Warning 6328: (1492-1528): CHC: Assertion violation happens here.\nCounterexample:\nblob_hash = 0x0, block_hash = 0x2298, bfee = 0, blobfee = 0, coin = 0x0, dif = 18446744073709551617, prevrandao = 18446744073709551617, glimit = 0, number = 0, tstamp = 0, mdata = [0x26, 0x12, 0x1f, 0xf0], sender = 0x0, sig = 0x26121ff0, value = 0, gprice = 0, origin = 0x0\n\nTransaction trace:\nC.constructor()\nState: blob_hash = 0x0, block_hash = 0x0, bfee = 0, blobfee = 0, coin = 0x0, dif = 0, prevrandao = 0, glimit = 0, number = 0, tstamp = 0, mdata = [], sender = 0x0, sig = 0x0, value = 0, gprice = 0, origin = 0x0\nC.f(){ block.basefee: 0, block.blobbasefee: 0, block.coinbase: 0x0, block.gaslimit: 0, block.number: 0, block.prevrandao: 18446744073709551617, block.timestamp: 0, msg.data: [0x26, 0x12, 0x1f, 0xf0], msg.sender: 0x0, msg.sig: 0x26121ff0, msg.value: 0, tx.gasprice: 0, tx.origin: 0x0 }\n C.fi() -- internal call +// Warning 6328: (1532-1562): CHC: Assertion violation happens here.\nCounterexample:\nblob_hash = 0x2298, block_hash = 0x0986, bfee = 0, blobfee = 0, coin = 0x0, dif = 18446744073709551617, prevrandao = 18446744073709551617, glimit = 0, number = 0, tstamp = 0, mdata = [0x26, 0x12, 0x1f, 0xf0], sender = 0x0, sig = 0x26121ff0, value = 0, gprice = 0, origin = 0x0\n\nTransaction trace:\nC.constructor()\nState: blob_hash = 0x0, block_hash = 0x0, bfee = 0, blobfee = 0, coin = 0x0, dif = 0, prevrandao = 0, glimit = 0, number = 0, tstamp = 0, mdata = [], sender = 0x0, sig = 0x0, value = 0, gprice = 0, origin = 0x0\nC.f(){ block.basefee: 0, block.blobbasefee: 0, block.coinbase: 0x0, block.gaslimit: 0, block.number: 0, block.prevrandao: 18446744073709551617, block.timestamp: 0, msg.data: [0x26, 0x12, 0x1f, 0xf0], msg.sender: 0x0, msg.sig: 0x26121ff0, msg.value: 0, tx.gasprice: 0, tx.origin: 0x0 }\n C.fi() -- internal call +// Warning 6328: (1566-1597): CHC: Assertion violation happens here.\nCounterexample:\nblob_hash = 0x0986, block_hash = 0x2298, bfee = 0, blobfee = 0, coin = 0x0, dif = 18446744073709551617, prevrandao = 18446744073709551617, glimit = 0, number = 0, tstamp = 0, mdata = [0x26, 0x12, 0x1f, 0xf0], sender = 0x0, sig = 0x26121ff0, value = 0, gprice = 0, origin = 0x0\n\nTransaction trace:\nC.constructor()\nState: blob_hash = 0x0, block_hash = 0x0, bfee = 0, blobfee = 0, coin = 0x0, dif = 0, prevrandao = 0, glimit = 0, number = 0, tstamp = 0, mdata = [], sender = 0x0, sig = 0x0, value = 0, gprice = 0, origin = 0x0\nC.f(){ block.basefee: 0, block.blobbasefee: 0, block.coinbase: 0x0, block.gaslimit: 0, block.number: 0, block.prevrandao: 18446744073709551617, block.timestamp: 0, msg.data: [0x26, 0x12, 0x1f, 0xf0], msg.sender: 0x0, msg.sig: 0x26121ff0, msg.value: 0, tx.gasprice: 0, tx.origin: 0x0 }\n C.fi() -- internal call +// Warning 6328: (1601-1639): CHC: Assertion violation happens here.\nCounterexample:\nblob_hash = 0x2298, block_hash = 0x0, bfee = 0, blobfee = 0, coin = 0x0, dif = 18446744073709551617, prevrandao = 18446744073709551617, glimit = 0, number = 0, tstamp = 0, mdata = [0x26, 0x12, 0x1f, 0xf0], sender = 0x0, sig = 0x26121ff0, value = 0, gprice = 0, origin = 0x0\n\nTransaction trace:\nC.constructor()\nState: blob_hash = 0x0, block_hash = 0x0, bfee = 0, blobfee = 0, coin = 0x0, dif = 0, prevrandao = 0, glimit = 0, number = 0, tstamp = 0, mdata = [], sender = 0x0, sig = 0x0, value = 0, gprice = 0, origin = 0x0\nC.f(){ block.basefee: 0, block.blobbasefee: 0, block.coinbase: 0x0, block.gaslimit: 0, block.number: 0, block.prevrandao: 18446744073709551617, block.timestamp: 0, msg.data: [0x26, 0x12, 0x1f, 0xf0], msg.sender: 0x0, msg.sig: 0x26121ff0, msg.value: 0, tx.gasprice: 0, tx.origin: 0x0 }\n C.fi() -- internal call +// Warning 6328: (1643-1675): CHC: Assertion violation happens here.\nCounterexample:\nblob_hash = 0x0, block_hash = 0x0, bfee = 0, blobfee = 0, coin = 0x0, dif = 18446744073709551617, prevrandao = 18446744073709551617, glimit = 0, number = 0, tstamp = 0, mdata = [0x26, 0x12, 0x1f, 0xf0], sender = 0x0, sig = 0x26121ff0, value = 0, gprice = 0, origin = 0x0\n\nTransaction trace:\nC.constructor()\nState: blob_hash = 0x0, block_hash = 0x0, bfee = 0, blobfee = 0, coin = 0x0, dif = 0, prevrandao = 0, glimit = 0, number = 0, tstamp = 0, mdata = [], sender = 0x0, sig = 0x0, value = 0, gprice = 0, origin = 0x0\nC.f(){ block.basefee: 0, block.blobbasefee: 0, block.coinbase: 0x0, block.gaslimit: 0, block.number: 0, block.prevrandao: 18446744073709551617, block.timestamp: 0, msg.data: [0x26, 0x12, 0x1f, 0xf0], msg.sender: 0x0, msg.sig: 0x26121ff0, msg.value: 0, tx.gasprice: 0, tx.origin: 0x0 }\n C.fi() -- internal call +// Warning 6328: (1679-1709): CHC: Assertion violation happens here.\nCounterexample:\nblob_hash = 0x0, block_hash = 0x2298, bfee = 0, blobfee = 0, coin = 0x0, dif = 18446744073709551617, prevrandao = 18446744073709551617, glimit = 0, number = 0, tstamp = 0, mdata = [0x26, 0x12, 0x1f, 0xf0], sender = 0x0, sig = 0x26121ff0, value = 0, gprice = 0, origin = 0x0\n\nTransaction trace:\nC.constructor()\nState: blob_hash = 0x0, block_hash = 0x0, bfee = 0, blobfee = 0, coin = 0x0, dif = 0, prevrandao = 0, glimit = 0, number = 0, tstamp = 0, mdata = [], sender = 0x0, sig = 0x0, value = 0, gprice = 0, origin = 0x0\nC.f(){ block.basefee: 0, block.blobbasefee: 0, block.coinbase: 0x0, block.gaslimit: 0, block.number: 0, block.prevrandao: 18446744073709551617, block.timestamp: 0, msg.data: [0x26, 0x12, 0x1f, 0xf0], msg.sender: 0x0, msg.sig: 0x26121ff0, msg.value: 0, tx.gasprice: 0, tx.origin: 0x0 }\n C.fi() -- internal call +// Warning 6328: (1713-1746): CHC: Assertion violation happens here.\nCounterexample:\nblob_hash = 0x0, block_hash = 0x0986, bfee = 0, blobfee = 0, coin = 0x0, dif = 18446744073709551617, prevrandao = 18446744073709551617, glimit = 0, number = 0, tstamp = 0, mdata = [0x26, 0x12, 0x1f, 0xf0], sender = 0x0, sig = 0x26121ff0, value = 0, gprice = 0, origin = 0x0\n\nTransaction trace:\nC.constructor()\nState: blob_hash = 0x0, block_hash = 0x0, bfee = 0, blobfee = 0, coin = 0x0, dif = 0, prevrandao = 0, glimit = 0, number = 0, tstamp = 0, mdata = [], sender = 0x0, sig = 0x0, value = 0, gprice = 0, origin = 0x0\nC.f(){ block.basefee: 0, block.blobbasefee: 0, block.coinbase: 0x0, block.gaslimit: 0, block.number: 0, block.prevrandao: 18446744073709551617, block.timestamp: 0, msg.data: [0x26, 0x12, 0x1f, 0xf0], msg.sender: 0x0, msg.sig: 0x26121ff0, msg.value: 0, tx.gasprice: 0, tx.origin: 0x0 }\n C.fi() -- internal call +// Warning 6328: (1750-1789): CHC: Assertion violation happens here.\nCounterexample:\nblob_hash = 0x0986, block_hash = 0x2298, bfee = 0, blobfee = 0, coin = 0x0, dif = 18446744073709551617, prevrandao = 18446744073709551617, glimit = 0, number = 0, tstamp = 0, mdata = [0x26, 0x12, 0x1f, 0xf0], sender = 0x0, sig = 0x26121ff0, value = 0, gprice = 0, origin = 0x0\n\nTransaction trace:\nC.constructor()\nState: blob_hash = 0x0, block_hash = 0x0, bfee = 0, blobfee = 0, coin = 0x0, dif = 0, prevrandao = 0, glimit = 0, number = 0, tstamp = 0, mdata = [], sender = 0x0, sig = 0x0, value = 0, gprice = 0, origin = 0x0\nC.f(){ block.basefee: 0, block.blobbasefee: 0, block.coinbase: 0x0, block.gaslimit: 0, block.number: 0, block.prevrandao: 18446744073709551617, block.timestamp: 0, msg.data: [0x26, 0x12, 0x1f, 0xf0], msg.sender: 0x0, msg.sig: 0x26121ff0, msg.value: 0, tx.gasprice: 0, tx.origin: 0x0 }\n C.fi() -- internal call +// Warning 6328: (1793-1821): CHC: Assertion violation happens here.\nCounterexample:\nblob_hash = 0x2298, block_hash = 0x0986, bfee = 0, blobfee = 0, coin = 0x0, dif = 18446744073709551617, prevrandao = 18446744073709551617, glimit = 0, number = 0, tstamp = 0, mdata = [0x26, 0x12, 0x1f, 0xf0], sender = 0x0, sig = 0x26121ff0, value = 0, gprice = 0, origin = 0x0\n\nTransaction trace:\nC.constructor()\nState: blob_hash = 0x0, block_hash = 0x0, bfee = 0, blobfee = 0, coin = 0x0, dif = 0, prevrandao = 0, glimit = 0, number = 0, tstamp = 0, mdata = [], sender = 0x0, sig = 0x0, value = 0, gprice = 0, origin = 0x0\nC.f(){ block.basefee: 0, block.blobbasefee: 0, block.coinbase: 0x0, block.gaslimit: 0, block.number: 0, block.prevrandao: 18446744073709551617, block.timestamp: 0, msg.data: [0x26, 0x12, 0x1f, 0xf0], msg.sender: 0x0, msg.sig: 0x26121ff0, msg.value: 0, tx.gasprice: 0, tx.origin: 0x0 }\n C.fi() -- internal call +// Warning 6328: (1825-1847): CHC: Assertion violation happens here.\nCounterexample:\nblob_hash = 0x0, block_hash = 0x0, bfee = 0, blobfee = 0, coin = 0x0, dif = 18446744073709551617, prevrandao = 18446744073709551617, glimit = 0, number = 0, tstamp = 0, mdata = [0x26, 0x12, 0x1f, 0xf0], sender = 0x0, sig = 0x26121ff0, value = 0, gprice = 0, origin = 0x0\n\nTransaction trace:\nC.constructor()\nState: blob_hash = 0x0, block_hash = 0x0, bfee = 0, blobfee = 0, coin = 0x0, dif = 0, prevrandao = 0, glimit = 0, number = 0, tstamp = 0, mdata = [], sender = 0x0, sig = 0x0, value = 0, gprice = 0, origin = 0x0\nC.f(){ block.basefee: 0, block.blobbasefee: 0, block.coinbase: 0x0, block.gaslimit: 0, block.number: 0, block.prevrandao: 18446744073709551617, block.timestamp: 0, msg.data: [0x26, 0x12, 0x1f, 0xf0], msg.sender: 0x0, msg.sig: 0x26121ff0, msg.value: 0, tx.gasprice: 0, tx.origin: 0x0 }\n C.fi() -- internal call +// Warning 6328: (1851-1877): CHC: Assertion violation happens here.\nCounterexample:\nblob_hash = 0x0986, block_hash = 0x2298, bfee = 0, blobfee = 0, coin = 0x0, dif = 18446744073709551617, prevrandao = 18446744073709551617, glimit = 0, number = 0, tstamp = 0, mdata = [0x26, 0x12, 0x1f, 0xf0], sender = 0x0, sig = 0x26121ff0, value = 0, gprice = 0, origin = 0x0\n\nTransaction trace:\nC.constructor()\nState: blob_hash = 0x0, block_hash = 0x0, bfee = 0, blobfee = 0, coin = 0x0, dif = 0, prevrandao = 0, glimit = 0, number = 0, tstamp = 0, mdata = [], sender = 0x0, sig = 0x0, value = 0, gprice = 0, origin = 0x0\nC.f(){ block.basefee: 0, block.blobbasefee: 0, block.coinbase: 0x0, block.gaslimit: 0, block.number: 0, block.prevrandao: 18446744073709551617, block.timestamp: 0, msg.data: [0x26, 0x12, 0x1f, 0xf0], msg.sender: 0x0, msg.sig: 0x26121ff0, msg.value: 0, tx.gasprice: 0, tx.origin: 0x0 }\n C.fi() -- internal call +// Warning 6328: (1881-1910): CHC: Assertion violation happens here.\nCounterexample:\nblob_hash = 0x0, block_hash = 0x0986, bfee = 0, blobfee = 0, coin = 0x0, dif = 18446744073709551617, prevrandao = 18446744073709551617, glimit = 0, number = 0, tstamp = 0, mdata = [0x26, 0x12, 0x1f, 0xf0], sender = 0x0, sig = 0x26121ff0, value = 0, gprice = 0, origin = 0x0\n\nTransaction trace:\nC.constructor()\nState: blob_hash = 0x0, block_hash = 0x0, bfee = 0, blobfee = 0, coin = 0x0, dif = 0, prevrandao = 0, glimit = 0, number = 0, tstamp = 0, mdata = [], sender = 0x0, sig = 0x0, value = 0, gprice = 0, origin = 0x0\nC.f(){ block.basefee: 0, block.blobbasefee: 0, block.coinbase: 0x0, block.gaslimit: 0, block.number: 0, block.prevrandao: 18446744073709551617, block.timestamp: 0, msg.data: [0x26, 0x12, 0x1f, 0xf0], msg.sender: 0x0, msg.sig: 0x26121ff0, msg.value: 0, tx.gasprice: 0, tx.origin: 0x0 }\n C.fi() -- internal call +// Warning 6328: (1914-1941): CHC: Assertion violation happens here.\nCounterexample:\nblob_hash = 0x0, block_hash = 0x0, bfee = 0, blobfee = 0, coin = 0x0, dif = 18446744073709551617, prevrandao = 18446744073709551617, glimit = 0, number = 0, tstamp = 0, mdata = [0x26, 0x12, 0x1f, 0xf0], sender = 0x0, sig = 0x26121ff0, value = 0, gprice = 0, origin = 0x0\n\nTransaction trace:\nC.constructor()\nState: blob_hash = 0x0, block_hash = 0x0, bfee = 0, blobfee = 0, coin = 0x0, dif = 0, prevrandao = 0, glimit = 0, number = 0, tstamp = 0, mdata = [], sender = 0x0, sig = 0x0, value = 0, gprice = 0, origin = 0x0\nC.f(){ block.basefee: 0, block.blobbasefee: 0, block.coinbase: 0x0, block.gaslimit: 0, block.number: 0, block.prevrandao: 18446744073709551617, block.timestamp: 0, msg.data: [0x26, 0x12, 0x1f, 0xf0], msg.sender: 0x0, msg.sig: 0x26121ff0, msg.value: 0, tx.gasprice: 0, tx.origin: 0x0 }\n C.fi() -- internal call diff --git a/test/libsolidity/smtCheckerTests/types/fixed_bytes_access_3.sol b/test/libsolidity/smtCheckerTests/types/fixed_bytes_access_3.sol index 54f3233531fa..bb4ef03428e7 100644 --- a/test/libsolidity/smtCheckerTests/types/fixed_bytes_access_3.sol +++ b/test/libsolidity/smtCheckerTests/types/fixed_bytes_access_3.sol @@ -30,7 +30,7 @@ contract C { } // ==== // SMTEngine: all +// SMTIgnoreOS: macos // ---- -// Warning 6368: (374-381): CHC: Out of bounds access might happen here. // Warning 6368: (456-462): CHC: Out of bounds access happens here. -// Info 1391: CHC: 12 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. +// Info 1391: CHC: 13 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. From 85074cc17b108362d62d8a6eef3d972afb308ee3 Mon Sep 17 00:00:00 2001 From: Rudko Hanna <162179706+Pistasha@users.noreply.github.com> Date: Fri, 31 Jan 2025 16:51:05 +0200 Subject: [PATCH 0762/1022] fix: correct code comments and references in ArrayUtils, CHC, EncodingContext, and LSP tests (#15801) * Update ArrayUtils.cpp * Update CHC.cpp * Update EncodingContext.h * Update goto_definition_imports.sol * Update goto_definition_imports.sol --- libsolidity/codegen/ArrayUtils.cpp | 2 +- libsolidity/formal/CHC.cpp | 2 +- libsolidity/formal/EncodingContext.h | 2 +- test/libsolidity/lsp/goto/goto_definition_imports.sol | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/libsolidity/codegen/ArrayUtils.cpp b/libsolidity/codegen/ArrayUtils.cpp index 5dd94aebc4f0..455cfe0842ed 100644 --- a/libsolidity/codegen/ArrayUtils.cpp +++ b/libsolidity/codegen/ArrayUtils.cpp @@ -710,7 +710,7 @@ void ArrayUtils::resizeDynamicArray(ArrayType const& _typeIn) const CompilerUtils(_context).computeHashStatic(); _context << Instruction::SSTORE; // stack: ref new_length current_length - // Store new length: Compule 2*length + 1 and store it. + // Store new length: Compute 2*length + 1 and store it. _context << Instruction::DUP2 << Instruction::DUP1 << Instruction::ADD; _context << u256(1) << Instruction::ADD; // stack: ref new_length current_length 2*new_length+1 diff --git a/libsolidity/formal/CHC.cpp b/libsolidity/formal/CHC.cpp index 9f23aff6fb67..222a0995b267 100644 --- a/libsolidity/formal/CHC.cpp +++ b/libsolidity/formal/CHC.cpp @@ -1336,7 +1336,7 @@ void CHC::clearIndices(ContractDefinition const* _contract, FunctionDefinition c void CHC::setCurrentBlock(Predicate const& _block) { - if (m_context.solverStackHeigh() > 0) + if (m_context.solverStackHeight() > 0) m_context.popSolver(); solAssert(m_currentContract, ""); clearIndices(m_currentContract, m_currentFunction); diff --git a/libsolidity/formal/EncodingContext.h b/libsolidity/formal/EncodingContext.h index 35e54ed76bc9..5387184ee0c9 100644 --- a/libsolidity/formal/EncodingContext.h +++ b/libsolidity/formal/EncodingContext.h @@ -142,7 +142,7 @@ class EncodingContext void pushSolver(); void popSolver(); void addAssertion(smtutil::Expression const& _e); - size_t solverStackHeigh() { return m_assertions.size(); } const + size_t solverStackHeight() { return m_assertions.size(); } const smtutil::SolverInterface* solver() { solAssert(m_solver, ""); diff --git a/test/libsolidity/lsp/goto/goto_definition_imports.sol b/test/libsolidity/lsp/goto/goto_definition_imports.sol index dd0267d710b0..f58bd002c385 100644 --- a/test/libsolidity/lsp/goto/goto_definition_imports.sol +++ b/test/libsolidity/lsp/goto/goto_definition_imports.sol @@ -2,7 +2,7 @@ pragma solidity >=0.8.0; import {Weather as Wetter} from "./lib.sol"; -// ^ @wheatherImportCursor +// ^ @weatherImportCursor import "./lib.sol" as That; // ^^^^ @ThatImport @@ -25,7 +25,7 @@ contract C // ---- // lib: @diagnostics 2072 // -> textDocument/definition { -// "position": @wheatherImportCursor +// "position": @weatherImportCursor // } // <- [ // { From d62ff26a68ea56a2d496ba6d65a5116d3f26f1f2 Mon Sep 17 00:00:00 2001 From: rodiazet Date: Fri, 31 Jan 2025 15:53:36 +0100 Subject: [PATCH 0763/1022] tests: Add `outputs` setting to `ObjectCompilerTest` --- test/libyul/ObjectCompilerTest.cpp | 33 ++++++++++++++++++++++-------- test/libyul/ObjectCompilerTest.h | 1 + 2 files changed, 25 insertions(+), 9 deletions(-) diff --git a/test/libyul/ObjectCompilerTest.cpp b/test/libyul/ObjectCompilerTest.cpp index f7d331d94acb..b7e475c91b1b 100644 --- a/test/libyul/ObjectCompilerTest.cpp +++ b/test/libyul/ObjectCompilerTest.cpp @@ -57,6 +57,13 @@ ObjectCompilerTest::ObjectCompilerTest(std::string const& _filename): }, "minimal" ); + + constexpr std::array allowedOutputs = {"Assembly", "Bytecode", "Opcodes", "SourceMappings"}; + boost::split(m_outputSetting, m_reader.stringSetting("outputs", "Assembly,Bytecode,Opcodes,SourceMappings"), boost::is_any_of(",")); + for (auto const& output: m_outputSetting) + if (std::find(allowedOutputs.begin(), allowedOutputs.end(), output) == allowedOutputs.end()) + BOOST_THROW_EXCEPTION(std::runtime_error{"Invalid output type: \"" + output + "\""}); + m_expectation = m_reader.simpleExpectations(); } @@ -78,18 +85,26 @@ TestCase::TestResult ObjectCompilerTest::run(std::ostream& _stream, std::string solAssert(obj.bytecode); solAssert(obj.sourceMappings); - m_obtainedResult = "Assembly:\n" + obj.assembly->assemblyString(yulStack.debugInfoSelection()); + if (std::find(m_outputSetting.begin(), m_outputSetting.end(), "Assembly") != m_outputSetting.end()) + m_obtainedResult = "Assembly:\n" + obj.assembly->assemblyString(yulStack.debugInfoSelection()); if (obj.bytecode->bytecode.empty()) m_obtainedResult += "-- empty bytecode --\n"; else - m_obtainedResult += - "Bytecode: " + - util::toHex(obj.bytecode->bytecode) + - "\nOpcodes: " + - boost::trim_copy(evmasm::disassemble(obj.bytecode->bytecode, solidity::test::CommonOptions::get().evmVersion())) + - "\nSourceMappings:" + - (obj.sourceMappings->empty() ? "" : " " + *obj.sourceMappings) + - "\n"; + { + if (std::find(m_outputSetting.begin(), m_outputSetting.end(), "Bytecode") != m_outputSetting.end()) + m_obtainedResult += "Bytecode: " + util::toHex(obj.bytecode->bytecode); + if (std::find(m_outputSetting.begin(), m_outputSetting.end(), "Opcodes") != m_outputSetting.end()) + { + m_obtainedResult += (!m_obtainedResult.empty() && m_obtainedResult.back() != '\n') ? "\n" : ""; + m_obtainedResult += "Opcodes: " + + boost::trim_copy(evmasm::disassemble(obj.bytecode->bytecode, solidity::test::CommonOptions::get().evmVersion())); + } + if (std::find(m_outputSetting.begin(), m_outputSetting.end(), "SourceMappings") != m_outputSetting.end()) + { + m_obtainedResult += (!m_obtainedResult.empty() && m_obtainedResult.back() != '\n') ? "\n" : ""; + m_obtainedResult += "SourceMappings:" + (obj.sourceMappings->empty() ? "" : " " + *obj.sourceMappings) + "\n"; + } + } return checkResult(_stream, _linePrefix, _formatted); } diff --git a/test/libyul/ObjectCompilerTest.h b/test/libyul/ObjectCompilerTest.h index 604ad0346c27..7a7941a69f95 100644 --- a/test/libyul/ObjectCompilerTest.h +++ b/test/libyul/ObjectCompilerTest.h @@ -54,6 +54,7 @@ class ObjectCompilerTest: public solidity::frontend::test::EVMVersionRestrictedT void disambiguate(); frontend::OptimisationPreset m_optimisationPreset; + std::vector m_outputSetting; }; } From c2f14258d86c8cdfad08c2737c47807e90571d93 Mon Sep 17 00:00:00 2001 From: rodiazet Date: Fri, 31 Jan 2025 16:14:45 +0100 Subject: [PATCH 0764/1022] eof: Update `semanticTests` tests for EOF --- .../constructor/callvalue_check.sol | 2 + .../deployedCodeExclusion/bound_function.sol | 3 ++ .../library_function.sol | 3 ++ .../deployedCodeExclusion/module_function.sol | 3 ++ .../static_base_function.sol | 3 ++ .../subassembly_deduplication.sol | 3 ++ .../deployedCodeExclusion/super_function.sol | 3 ++ .../virtual_function.sol | 3 ++ .../events/event_emit_from_other_contract.sol | 4 ++ .../semanticTests/experimental/stub.sol | 1 + .../semanticTests/experimental/type_class.sol | 1 + .../freeFunctions/free_runtimecode.sol | 2 + .../functionCall/call_options_overload.sol | 2 + .../calling_nonexisting_contract_throws.sol | 2 + .../eof/call_options_overload.sol | 16 ++++++++ .../eof/calling_nonexisting_contract.sol | 25 ++++++++++++ .../external_call_at_construction_time.sol | 24 ++++++++++++ .../eof/external_call_to_nonexisting.sol | 39 +++++++++++++++++++ .../external_call_at_construction_time.sol | 1 + .../external_call_to_nonexisting.sol | 2 + ...ernal_call_to_nonexisting_debugstrings.sol | 1 + .../functionCall/gas_and_value_basic.sol | 2 + ...eck_on_adding_gas_variable_to_function.sol | 2 + .../transient_storage_selfdestruct.sol | 1 + .../called_contract_has_code.sol | 1 + .../reverts/eof/revert_return_area.sol | 19 +++++++++ .../reverts/revert_return_area.sol | 1 + .../eof/salted_create_with_value.sol | 23 +++++++++++ .../saltedCreate/prediction_example.sol | 1 + .../saltedCreate/salted_create_with_value.sol | 1 + .../semanticTests/shanghai/evmone_support.sol | 1 + .../semanticTests/state/gasleft.sol | 2 + .../semanticTests/various/address_code.sol | 2 + .../various/address_code_complex.sol | 2 + .../various/code_access_content.sol | 2 + .../various/code_access_create.sol | 3 ++ .../various/code_access_padding.sol | 2 + .../various/code_access_runtime.sol | 1 + .../semanticTests/various/code_length.sol | 2 + .../various/code_length_contract_member.sol | 2 + .../semanticTests/various/codehash.sol | 1 + .../various/codehash_assembly.sol | 1 + .../semanticTests/various/create_calldata.sol | 2 + .../semanticTests/various/create_random.sol | 1 + .../various/eof/create_calldata.sol | 21 ++++++++++ .../various/gasleft_decrease.sol | 2 + .../various/selfdestruct_post_cancun.sol | 1 + ...uct_post_cancun_multiple_beneficiaries.sol | 1 + .../selfdestruct_post_cancun_redeploy.sol | 1 + 49 files changed, 244 insertions(+) create mode 100644 test/libsolidity/semanticTests/functionCall/eof/call_options_overload.sol create mode 100644 test/libsolidity/semanticTests/functionCall/eof/calling_nonexisting_contract.sol create mode 100644 test/libsolidity/semanticTests/functionCall/eof/external_call_at_construction_time.sol create mode 100644 test/libsolidity/semanticTests/functionCall/eof/external_call_to_nonexisting.sol create mode 100644 test/libsolidity/semanticTests/reverts/eof/revert_return_area.sol create mode 100644 test/libsolidity/semanticTests/saltedCreate/eof/salted_create_with_value.sol create mode 100644 test/libsolidity/semanticTests/various/eof/create_calldata.sol diff --git a/test/libsolidity/semanticTests/constructor/callvalue_check.sol b/test/libsolidity/semanticTests/constructor/callvalue_check.sol index f45fbed925ad..10086886a622 100644 --- a/test/libsolidity/semanticTests/constructor/callvalue_check.sol +++ b/test/libsolidity/semanticTests/constructor/callvalue_check.sol @@ -11,6 +11,7 @@ contract B4 { constructor() {} } contract C { function createWithValue(bytes memory c, uint256 value) public payable returns (bool) { uint256 y = 0; + // TODO: This test is hard to recreate for EOF as for now eofcreate is disallowed in inline assembly. assembly { y := create(value, add(c, 0x20), mload(c)) } return y != 0; } @@ -29,6 +30,7 @@ contract C { } // ==== // EVMVersion: >homestead +// bytecodeFormat: legacy // ---- // f(uint256), 2000 ether: 0 -> true // f(uint256), 2000 ether: 100 -> false diff --git a/test/libsolidity/semanticTests/deployedCodeExclusion/bound_function.sol b/test/libsolidity/semanticTests/deployedCodeExclusion/bound_function.sol index 64b80422c352..69a4bd65b1d9 100644 --- a/test/libsolidity/semanticTests/deployedCodeExclusion/bound_function.sol +++ b/test/libsolidity/semanticTests/deployedCodeExclusion/bound_function.sol @@ -1,3 +1,4 @@ +// TODO: Recreate this test for EOF when subassembly deduplication will be supported for EOF too. function longdata(S memory) pure returns (bytes memory) { return "xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID" @@ -36,5 +37,7 @@ contract C { return x < data.length; } } +// ==== +// bytecodeFormat: legacy // ---- // test() -> true diff --git a/test/libsolidity/semanticTests/deployedCodeExclusion/library_function.sol b/test/libsolidity/semanticTests/deployedCodeExclusion/library_function.sol index 931109199649..28843b25d19d 100644 --- a/test/libsolidity/semanticTests/deployedCodeExclusion/library_function.sol +++ b/test/libsolidity/semanticTests/deployedCodeExclusion/library_function.sol @@ -1,3 +1,4 @@ +// TODO: Recreate this test for EOF when subassembly deduplication will be supported for EOF too. library L { function longdata() pure internal returns (bytes memory) { return @@ -30,5 +31,7 @@ contract C { return x < data.length; } } +// ==== +// bytecodeFormat: legacy // ---- // test() -> true diff --git a/test/libsolidity/semanticTests/deployedCodeExclusion/module_function.sol b/test/libsolidity/semanticTests/deployedCodeExclusion/module_function.sol index 018d410557b0..8e075654f313 100644 --- a/test/libsolidity/semanticTests/deployedCodeExclusion/module_function.sol +++ b/test/libsolidity/semanticTests/deployedCodeExclusion/module_function.sol @@ -1,3 +1,4 @@ +// TODO: Recreate this test for EOF when subassembly deduplication will be supported for EOF too. ==== Source: mod.sol ==== function longdata() pure returns (bytes memory) { return @@ -32,5 +33,7 @@ contract C { return x < data.length; } } +// ==== +// bytecodeFormat: legacy // ---- // test() -> true diff --git a/test/libsolidity/semanticTests/deployedCodeExclusion/static_base_function.sol b/test/libsolidity/semanticTests/deployedCodeExclusion/static_base_function.sol index 0f9b023b08d9..255e99e82489 100644 --- a/test/libsolidity/semanticTests/deployedCodeExclusion/static_base_function.sol +++ b/test/libsolidity/semanticTests/deployedCodeExclusion/static_base_function.sol @@ -1,3 +1,4 @@ +// TODO: Recreate this test for EOF when subassembly deduplication will be supported for EOF too. abstract contract S { function longdata() internal pure returns (bytes memory) { return @@ -31,5 +32,7 @@ contract C is S { return x < data.length; } } +// ==== +// bytecodeFormat: legacy // ---- // test() -> true diff --git a/test/libsolidity/semanticTests/deployedCodeExclusion/subassembly_deduplication.sol b/test/libsolidity/semanticTests/deployedCodeExclusion/subassembly_deduplication.sol index b6ae85b838d8..4425475695a1 100644 --- a/test/libsolidity/semanticTests/deployedCodeExclusion/subassembly_deduplication.sol +++ b/test/libsolidity/semanticTests/deployedCodeExclusion/subassembly_deduplication.sol @@ -1,3 +1,4 @@ +// TODO: Recreate this test for EOF when subassembly deduplication will be supported for EOF too. contract A { function longdata() pure external returns (bytes memory) { return @@ -37,5 +38,7 @@ contract C { x < 2 * type(A).creationCode.length; } } +// ==== +// bytecodeFormat: legacy // ---- // test() -> true diff --git a/test/libsolidity/semanticTests/deployedCodeExclusion/super_function.sol b/test/libsolidity/semanticTests/deployedCodeExclusion/super_function.sol index 9accc54a2b05..17aabdf83832 100644 --- a/test/libsolidity/semanticTests/deployedCodeExclusion/super_function.sol +++ b/test/libsolidity/semanticTests/deployedCodeExclusion/super_function.sol @@ -1,3 +1,4 @@ +// TODO: Recreate this test for EOF when subassembly deduplication will be supported for EOF too. abstract contract S { function longdata() internal pure returns (bytes memory) { return @@ -31,5 +32,7 @@ contract C is S { return x < data.length; } } +// ==== +// bytecodeFormat: legacy // ---- // test() -> true diff --git a/test/libsolidity/semanticTests/deployedCodeExclusion/virtual_function.sol b/test/libsolidity/semanticTests/deployedCodeExclusion/virtual_function.sol index 866fe9dfc452..322de3c84435 100644 --- a/test/libsolidity/semanticTests/deployedCodeExclusion/virtual_function.sol +++ b/test/libsolidity/semanticTests/deployedCodeExclusion/virtual_function.sol @@ -1,3 +1,4 @@ +// TODO: Recreate this test for EOF when subassembly deduplication will be supported for EOF too. abstract contract S { function longdata() internal virtual pure returns (bytes memory); } @@ -35,5 +36,7 @@ contract C is X { return x < data.length; } } +// ==== +// bytecodeFormat: legacy // ---- // test() -> true diff --git a/test/libsolidity/semanticTests/events/event_emit_from_other_contract.sol b/test/libsolidity/semanticTests/events/event_emit_from_other_contract.sol index 61e1bbdd6c0e..e6d800d9b229 100644 --- a/test/libsolidity/semanticTests/events/event_emit_from_other_contract.sol +++ b/test/libsolidity/semanticTests/events/event_emit_from_other_contract.sol @@ -1,3 +1,5 @@ +// TODO: Implement this test for EOF. Now it's not possible because deployed contract address depends on contract bytecode. +// This means that the address changes when optimisations are applied. contract D { event Deposit(address indexed _from, bytes32 indexed _id, uint _value); function deposit(bytes32 _id) public payable { @@ -13,6 +15,8 @@ contract C { d.deposit(_id); } } +// ==== +// bytecodeFormat: legacy // ---- // constructor() -> // gas irOptimized: 113970 diff --git a/test/libsolidity/semanticTests/experimental/stub.sol b/test/libsolidity/semanticTests/experimental/stub.sol index 6e7a750fe980..d2d0999bfb76 100644 --- a/test/libsolidity/semanticTests/experimental/stub.sol +++ b/test/libsolidity/semanticTests/experimental/stub.sol @@ -92,6 +92,7 @@ contract C { // EVMVersion: >=constantinople // ==== // compileViaYul: true +// bytecodeFormat: legacy // ---- // (): 0 -> 0 // (): 1 -> 544 diff --git a/test/libsolidity/semanticTests/experimental/type_class.sol b/test/libsolidity/semanticTests/experimental/type_class.sol index 69fa568dfd96..7331c0dbd73c 100644 --- a/test/libsolidity/semanticTests/experimental/type_class.sol +++ b/test/libsolidity/semanticTests/experimental/type_class.sol @@ -63,5 +63,6 @@ contract C { // ==== // EVMVersion: >=constantinople // compileViaYul: true +// bytecodeFormat: legacy // ---- // () -> 1, 0 diff --git a/test/libsolidity/semanticTests/freeFunctions/free_runtimecode.sol b/test/libsolidity/semanticTests/freeFunctions/free_runtimecode.sol index 7a05ff5d0270..e414b8205ba7 100644 --- a/test/libsolidity/semanticTests/freeFunctions/free_runtimecode.sol +++ b/test/libsolidity/semanticTests/freeFunctions/free_runtimecode.sol @@ -11,5 +11,7 @@ contract D { return test(); } } +// ==== +// bytecodeFormat: legacy // ---- // f() -> true diff --git a/test/libsolidity/semanticTests/functionCall/call_options_overload.sol b/test/libsolidity/semanticTests/functionCall/call_options_overload.sol index b9eb6ca42892..61e979f17536 100644 --- a/test/libsolidity/semanticTests/functionCall/call_options_overload.sol +++ b/test/libsolidity/semanticTests/functionCall/call_options_overload.sol @@ -10,6 +10,8 @@ contract C { function bal() external returns (uint) { return address(this).balance; } receive() external payable {} } +// ==== +// bytecodeFormat: legacy // ---- // (), 1 ether // call() -> 1, 2, 2, 2 diff --git a/test/libsolidity/semanticTests/functionCall/calling_nonexisting_contract_throws.sol b/test/libsolidity/semanticTests/functionCall/calling_nonexisting_contract_throws.sol index 229618384d1e..36dfc844d934 100644 --- a/test/libsolidity/semanticTests/functionCall/calling_nonexisting_contract_throws.sol +++ b/test/libsolidity/semanticTests/functionCall/calling_nonexisting_contract_throws.sol @@ -21,6 +21,8 @@ contract C { return 7; } } +// ==== +// bytecodeFormat: legacy // ---- // f() -> FAILURE // g() -> FAILURE diff --git a/test/libsolidity/semanticTests/functionCall/eof/call_options_overload.sol b/test/libsolidity/semanticTests/functionCall/eof/call_options_overload.sol new file mode 100644 index 000000000000..1ddc06c1dd2c --- /dev/null +++ b/test/libsolidity/semanticTests/functionCall/eof/call_options_overload.sol @@ -0,0 +1,16 @@ +contract C { + function f(uint x) external payable returns (uint) { return 1; } + function f(uint x, uint y) external payable returns (uint) { return 2; } + function call() public payable returns (uint x, uint y) { + x = this.f{value: 10}(2); + y = this.f{value: 10}(2, 3); + } + function bal() external returns (uint) { return address(this).balance; } + receive() external payable {} +} +// ==== +// bytecodeFormat: >=EOFv1 +// ---- +// (), 1 ether +// call() -> 1, 2 +// bal() -> 1000000000000000000 diff --git a/test/libsolidity/semanticTests/functionCall/eof/calling_nonexisting_contract.sol b/test/libsolidity/semanticTests/functionCall/eof/calling_nonexisting_contract.sol new file mode 100644 index 000000000000..10b39634d5de --- /dev/null +++ b/test/libsolidity/semanticTests/functionCall/eof/calling_nonexisting_contract.sol @@ -0,0 +1,25 @@ +abstract contract D { + function g() public virtual; +} + + +contract C { + D d = D(address(0x1212)); + + function f() public returns (uint256) { + // This call throws on legacy bytecode because of calling nonexisting contract. Legacy checks that there is + // a non-empty code under under an address. EOF doesn't do it because non-observability assumption + d.g(); + return 7; + } + + function h() public returns (uint256) { + address(d).call(""); // this does not throw (low-level) + return 7; + } +} +// ==== +// bytecodeFormat: >=EOFv1 +// ---- +// f() -> 7 +// h() -> 7 diff --git a/test/libsolidity/semanticTests/functionCall/eof/external_call_at_construction_time.sol b/test/libsolidity/semanticTests/functionCall/eof/external_call_at_construction_time.sol new file mode 100644 index 000000000000..6235562c990f --- /dev/null +++ b/test/libsolidity/semanticTests/functionCall/eof/external_call_at_construction_time.sol @@ -0,0 +1,24 @@ +// 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; + } +} +// ==== +// bytecodeFormat: >=EOFv1 +// ---- +// f(uint256): 0 -> 1 +// f(uint256): 1 -> FAILURE +// f(uint256): 2 -> 3 diff --git a/test/libsolidity/semanticTests/functionCall/eof/external_call_to_nonexisting.sol b/test/libsolidity/semanticTests/functionCall/eof/external_call_to_nonexisting.sol new file mode 100644 index 000000000000..bc39e963344b --- /dev/null +++ b/test/libsolidity/semanticTests/functionCall/eof/external_call_to_nonexisting.sol @@ -0,0 +1,39 @@ +// 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; + } +} +// ==== +// bytecodeFormat: >=EOFv1 +// ---- +// constructor(), 1 ether -> +// gas irOptimized: 88853 +// gas irOptimized code: 164400 +// gas legacy: 102721 +// gas legacy code: 334400 +// gas legacyOptimized: 91499 +// gas legacyOptimized code: 196400 +// f(uint256): 0 -> 1 +// f(uint256): 1 -> 2 +// f(uint256): 2 -> 3 +// f(uint256): 3 -> 4 +// f(uint256): 4 -> FAILURE +// f(uint256): 5 -> FAILURE +// f(uint256): 6 -> 7 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 6f7f020fe678..c5fa0538e6e7 100644 --- a/test/libsolidity/semanticTests/functionCall/external_call_at_construction_time.sol +++ b/test/libsolidity/semanticTests/functionCall/external_call_at_construction_time.sol @@ -18,6 +18,7 @@ contract C { } // ==== // EVMVersion: >=byzantium +// bytecodeFormat: legacy // ---- // f(uint256): 0 -> FAILURE // f(uint256): 1 -> FAILURE diff --git a/test/libsolidity/semanticTests/functionCall/external_call_to_nonexisting.sol b/test/libsolidity/semanticTests/functionCall/external_call_to_nonexisting.sol index 472921c1d25c..0031059c021a 100644 --- a/test/libsolidity/semanticTests/functionCall/external_call_to_nonexisting.sol +++ b/test/libsolidity/semanticTests/functionCall/external_call_to_nonexisting.sol @@ -20,6 +20,8 @@ contract C { return 1 + c; } } +// ==== +// bytecodeFormat: legacy // ---- // constructor(), 1 ether -> // gas irOptimized: 88853 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 d1b6e8e866ae..a8eafb38ea1a 100644 --- a/test/libsolidity/semanticTests/functionCall/external_call_to_nonexisting_debugstrings.sol +++ b/test/libsolidity/semanticTests/functionCall/external_call_to_nonexisting_debugstrings.sol @@ -23,6 +23,7 @@ contract C { // ==== // EVMVersion: >=byzantium // revertStrings: debug +// bytecodeFormat: legacy // ---- // constructor(), 1 ether -> // gas irOptimized: 98698 diff --git a/test/libsolidity/semanticTests/functionCall/gas_and_value_basic.sol b/test/libsolidity/semanticTests/functionCall/gas_and_value_basic.sol index e7bf053eb2c6..7415accabcd2 100644 --- a/test/libsolidity/semanticTests/functionCall/gas_and_value_basic.sol +++ b/test/libsolidity/semanticTests/functionCall/gas_and_value_basic.sol @@ -34,6 +34,8 @@ contract test { myBal = address(this).balance; } } +// ==== +// bytecodeFormat: legacy // ---- // constructor(), 20 wei -> // gas irOptimized: 120218 diff --git a/test/libsolidity/semanticTests/functionTypes/stack_height_check_on_adding_gas_variable_to_function.sol b/test/libsolidity/semanticTests/functionTypes/stack_height_check_on_adding_gas_variable_to_function.sol index f811988fec9a..1ca391e81095 100644 --- a/test/libsolidity/semanticTests/functionTypes/stack_height_check_on_adding_gas_variable_to_function.sol +++ b/test/libsolidity/semanticTests/functionTypes/stack_height_check_on_adding_gas_variable_to_function.sol @@ -19,5 +19,7 @@ contract C { return true; } } +// ==== +// bytecodeFormat: legacy // ---- // test_function() -> true diff --git a/test/libsolidity/semanticTests/inlineAssembly/transient_storage_selfdestruct.sol b/test/libsolidity/semanticTests/inlineAssembly/transient_storage_selfdestruct.sol index c2066ef8be1e..26bb09edca7a 100644 --- a/test/libsolidity/semanticTests/inlineAssembly/transient_storage_selfdestruct.sol +++ b/test/libsolidity/semanticTests/inlineAssembly/transient_storage_selfdestruct.sol @@ -38,6 +38,7 @@ contract D { } // ==== // EVMVersion: >=cancun +// bytecodeFormat: legacy // ---- // constructor() -> // gas irOptimized: 127596 diff --git a/test/libsolidity/semanticTests/revertStrings/called_contract_has_code.sol b/test/libsolidity/semanticTests/revertStrings/called_contract_has_code.sol index 110b1e50c724..d9a6549252f1 100644 --- a/test/libsolidity/semanticTests/revertStrings/called_contract_has_code.sol +++ b/test/libsolidity/semanticTests/revertStrings/called_contract_has_code.sol @@ -8,5 +8,6 @@ contract C { // ==== // EVMVersion: >=byzantium // revertStrings: debug +// bytecodeFormat: legacy // ---- // g() -> FAILURE, hex"08c379a0", 0x20, 37, "Target contract does not contain", " code" diff --git a/test/libsolidity/semanticTests/reverts/eof/revert_return_area.sol b/test/libsolidity/semanticTests/reverts/eof/revert_return_area.sol new file mode 100644 index 000000000000..8cec1ca1d66c --- /dev/null +++ b/test/libsolidity/semanticTests/reverts/eof/revert_return_area.sol @@ -0,0 +1,19 @@ +contract C { + fallback() external { + revert("abc"); + } + + function f() public returns (uint s, uint r) { + address x = address(this); + assembly { + mstore(0, 7) + s := extcall(x, 0, 0, 0) + returndatacopy(0, 0, 32) + r := mload(0) + } + } +} +// ==== +// bytecodeFormat: >=EOFv1 +// ---- +// f() -> 0x01, 0x08c379a000000000000000000000000000000000000000000000000000000000 diff --git a/test/libsolidity/semanticTests/reverts/revert_return_area.sol b/test/libsolidity/semanticTests/reverts/revert_return_area.sol index 8ab4ca22722c..5f276f91c948 100644 --- a/test/libsolidity/semanticTests/reverts/revert_return_area.sol +++ b/test/libsolidity/semanticTests/reverts/revert_return_area.sol @@ -14,5 +14,6 @@ contract C { } // ==== // EVMVersion: >=byzantium +// bytecodeFormat: legacy // ---- // f() -> 0x00, 0x08c379a000000000000000000000000000000000000000000000000000000000 diff --git a/test/libsolidity/semanticTests/saltedCreate/eof/salted_create_with_value.sol b/test/libsolidity/semanticTests/saltedCreate/eof/salted_create_with_value.sol new file mode 100644 index 000000000000..e6c6f6eb0772 --- /dev/null +++ b/test/libsolidity/semanticTests/saltedCreate/eof/salted_create_with_value.sol @@ -0,0 +1,23 @@ +contract B +{ + uint x; + function getBalance() public view returns (uint) { + return address(this).balance * 1000 + x; + } + constructor(uint _x) payable { + x = _x; + } +} + +contract A { + function f() public payable returns (uint, uint, uint) { + B x = new B{salt: "abc1", value: 3}(7); + B y = new B{value: 3, salt: "abc2"}(8); + B z = new B{salt: "abc3", value: 3}(9); + return (x.getBalance(), y.getBalance(), z.getBalance()); + } +} +// ==== +// bytecodeFormat: >=EOFv1 +// ---- +// f(), 10 ether -> 3007, 3008, 3009 diff --git a/test/libsolidity/semanticTests/saltedCreate/prediction_example.sol b/test/libsolidity/semanticTests/saltedCreate/prediction_example.sol index 7d0e3c8b0dbc..f1f62db03230 100644 --- a/test/libsolidity/semanticTests/saltedCreate/prediction_example.sol +++ b/test/libsolidity/semanticTests/saltedCreate/prediction_example.sol @@ -24,6 +24,7 @@ contract C { // ==== // EVMVersion: >=constantinople // compileViaYul: also +// bytecodeFormat: legacy // ---- // createDSalted(bytes32,uint256): 42, 64 -> // gas legacy: 78573 diff --git a/test/libsolidity/semanticTests/saltedCreate/salted_create_with_value.sol b/test/libsolidity/semanticTests/saltedCreate/salted_create_with_value.sol index 25d1935770d1..c810000e5b3c 100644 --- a/test/libsolidity/semanticTests/saltedCreate/salted_create_with_value.sol +++ b/test/libsolidity/semanticTests/saltedCreate/salted_create_with_value.sol @@ -19,6 +19,7 @@ contract A { } // ==== // EVMVersion: >=constantinople +// bytecodeFormat: legacy // ---- // f(), 10 ether -> 3007, 3008, 3009 // gas irOptimized: 187022 diff --git a/test/libsolidity/semanticTests/shanghai/evmone_support.sol b/test/libsolidity/semanticTests/shanghai/evmone_support.sol index 359dc516ffcd..4f3c0ee1ba6a 100644 --- a/test/libsolidity/semanticTests/shanghai/evmone_support.sol +++ b/test/libsolidity/semanticTests/shanghai/evmone_support.sol @@ -26,6 +26,7 @@ contract Test { // ==== // compileViaYul: also // EVMVersion: >=shanghai +// bytecodeFormat: legacy // ---- // bytecode() -> 0x20, 4, 0x60205ff300000000000000000000000000000000000000000000000000000000 // isPush0Supported() -> true diff --git a/test/libsolidity/semanticTests/state/gasleft.sol b/test/libsolidity/semanticTests/state/gasleft.sol index 6ce623ce81ea..2d4a37b48d8b 100644 --- a/test/libsolidity/semanticTests/state/gasleft.sol +++ b/test/libsolidity/semanticTests/state/gasleft.sol @@ -3,6 +3,8 @@ contract C { return gasleft() > 0; } } +// ==== +// bytecodeFormat: legacy // ---- // f() -> true // f() -> true diff --git a/test/libsolidity/semanticTests/various/address_code.sol b/test/libsolidity/semanticTests/various/address_code.sol index 549512eb3e44..4d810f970987 100644 --- a/test/libsolidity/semanticTests/various/address_code.sol +++ b/test/libsolidity/semanticTests/various/address_code.sol @@ -12,6 +12,8 @@ contract C { function g() public view returns (uint) { return address(0).code.length; } function h() public view returns (uint) { return address(1).code.length; } } +// ==== +// bytecodeFormat: legacy // ---- // constructor() -> // gas irOptimized: 70760 diff --git a/test/libsolidity/semanticTests/various/address_code_complex.sol b/test/libsolidity/semanticTests/various/address_code_complex.sol index f2d21c9069b3..d228d99d1767 100644 --- a/test/libsolidity/semanticTests/various/address_code_complex.sol +++ b/test/libsolidity/semanticTests/various/address_code_complex.sol @@ -12,6 +12,8 @@ contract C { function f() public returns (bytes memory) { return address(new A()).code; } function g() public returns (uint) { return address(new A()).code.length; } } +// ==== +// bytecodeFormat: legacy // ---- // f() -> 0x20, 0x20, 0x48aa5566000000 // g() -> 0x20 diff --git a/test/libsolidity/semanticTests/various/code_access_content.sol b/test/libsolidity/semanticTests/various/code_access_content.sol index 22ceff337f89..b8b13b3c677f 100644 --- a/test/libsolidity/semanticTests/various/code_access_content.sol +++ b/test/libsolidity/semanticTests/various/code_access_content.sol @@ -36,6 +36,8 @@ contract C { return true; } } +// ==== +// bytecodeFormat: legacy // ---- // testRuntime() -> true // gas legacy: 76575 diff --git a/test/libsolidity/semanticTests/various/code_access_create.sol b/test/libsolidity/semanticTests/various/code_access_create.sol index f5f0b8644423..e3a6e03728e9 100644 --- a/test/libsolidity/semanticTests/various/code_access_create.sol +++ b/test/libsolidity/semanticTests/various/code_access_create.sol @@ -1,3 +1,4 @@ +// TODO: Recreate this test when eofcreate will be allowed in inline assembly. contract D { uint256 x; @@ -21,6 +22,8 @@ contract C { return d.f(); } } +// ==== +// bytecodeFormat: legacy // ---- // test() -> 7 // gas legacy: 76647 diff --git a/test/libsolidity/semanticTests/various/code_access_padding.sol b/test/libsolidity/semanticTests/various/code_access_padding.sol index 831d4bde4ab4..6c07fb4e089e 100644 --- a/test/libsolidity/semanticTests/various/code_access_padding.sol +++ b/test/libsolidity/semanticTests/various/code_access_padding.sol @@ -14,5 +14,7 @@ contract C { } } } +// ==== +// bytecodeFormat: legacy // ---- // diff() -> 0 # This checks that the allocation function pads to multiples of 32 bytes # diff --git a/test/libsolidity/semanticTests/various/code_access_runtime.sol b/test/libsolidity/semanticTests/various/code_access_runtime.sol index 10d7c1852e95..0c848fc592eb 100644 --- a/test/libsolidity/semanticTests/various/code_access_runtime.sol +++ b/test/libsolidity/semanticTests/various/code_access_runtime.sol @@ -21,6 +21,7 @@ contract C { } // ==== // EVMVersion: >=constantinople +// bytecodeFormat: legacy // ---- // test() -> 42 // gas legacy: 76034 diff --git a/test/libsolidity/semanticTests/various/code_length.sol b/test/libsolidity/semanticTests/various/code_length.sol index 844a0f65706f..08065b302c99 100644 --- a/test/libsolidity/semanticTests/various/code_length.sol +++ b/test/libsolidity/semanticTests/various/code_length.sol @@ -57,6 +57,8 @@ contract C { } } +// ==== +// bytecodeFormat: legacy // ---- // constructor() // gas legacy: 66989 diff --git a/test/libsolidity/semanticTests/various/code_length_contract_member.sol b/test/libsolidity/semanticTests/various/code_length_contract_member.sol index ff883139a46e..79e940080f02 100644 --- a/test/libsolidity/semanticTests/various/code_length_contract_member.sol +++ b/test/libsolidity/semanticTests/various/code_length_contract_member.sol @@ -11,5 +11,7 @@ contract C { return (s.code.length, s.another.length, address(this).code.length > 50); } } +// ==== +// bytecodeFormat: legacy // ---- // f() -> 0x20, 0x20, true diff --git a/test/libsolidity/semanticTests/various/codehash.sol b/test/libsolidity/semanticTests/various/codehash.sol index fa7dab9dab9f..465e2ee31b51 100644 --- a/test/libsolidity/semanticTests/various/codehash.sol +++ b/test/libsolidity/semanticTests/various/codehash.sol @@ -13,6 +13,7 @@ contract C { } // ==== // EVMVersion: >=constantinople +// bytecodeFormat: legacy // ---- // f() -> 0x0 // g() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 diff --git a/test/libsolidity/semanticTests/various/codehash_assembly.sol b/test/libsolidity/semanticTests/various/codehash_assembly.sol index fe2210fa107a..81c2286d5e44 100644 --- a/test/libsolidity/semanticTests/various/codehash_assembly.sol +++ b/test/libsolidity/semanticTests/various/codehash_assembly.sol @@ -17,6 +17,7 @@ contract C { } // ==== // EVMVersion: >=constantinople +// bytecodeFormat: legacy // ---- // f() -> 0 // g() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 diff --git a/test/libsolidity/semanticTests/various/create_calldata.sol b/test/libsolidity/semanticTests/various/create_calldata.sol index a5f61d2ddd67..7e3e326228a7 100644 --- a/test/libsolidity/semanticTests/various/create_calldata.sol +++ b/test/libsolidity/semanticTests/various/create_calldata.sol @@ -6,6 +6,8 @@ contract C { assert(msg.data.length == 0); } } +// ==== +// bytecodeFormat: legacy // ---- // constructor(): 42 -> // gas irOptimized: 68239 diff --git a/test/libsolidity/semanticTests/various/create_random.sol b/test/libsolidity/semanticTests/various/create_random.sol index 676ec32a89ae..b053deb442ed 100644 --- a/test/libsolidity/semanticTests/various/create_random.sol +++ b/test/libsolidity/semanticTests/various/create_random.sol @@ -33,6 +33,7 @@ contract C { } // ==== // EVMVersion: >=constantinople +// bytecodeFormat: legacy // ---- // addr() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e // testRunner() -> 0x137aa4dfc0911524504fcd4d98501f179bc13b4a, 0x2c1c30623ddd93e0b765a6caaca0c859eeb0644d diff --git a/test/libsolidity/semanticTests/various/eof/create_calldata.sol b/test/libsolidity/semanticTests/various/eof/create_calldata.sol new file mode 100644 index 000000000000..ae1fc39ec6c8 --- /dev/null +++ b/test/libsolidity/semanticTests/various/eof/create_calldata.sol @@ -0,0 +1,21 @@ +contract C { + bytes public s; + constructor(uint256 x, bytes memory b) { + // On EOF msg.data contains constructor arguments, while on legacy it's empty + // (arguments are appended to the code). + s = msg.data; + assert(msg.data.length == 288); + uint y; + bytes memory d; + (y, d) = abi.decode(msg.data, (uint256, bytes)); + assert(x == y); + assert(b.length == d.length); + for (uint i = 0; i < b.length; ++i) + assert(b[i] == d[i]); + } +} +// ==== +// bytecodeFormat: >=EOFv1 +// ---- +// constructor(): 42, 0x20, 0xc0, 1, 2, 3, 4, 5, 6 -> +// s() -> 0x20, 0x0120, 42, 0x20, 0xc0, 1, 2, 3, 4, 5, 6 diff --git a/test/libsolidity/semanticTests/various/gasleft_decrease.sol b/test/libsolidity/semanticTests/various/gasleft_decrease.sol index ab7302743f64..ea891edc4e5f 100644 --- a/test/libsolidity/semanticTests/various/gasleft_decrease.sol +++ b/test/libsolidity/semanticTests/various/gasleft_decrease.sol @@ -14,6 +14,8 @@ contract C { return true; } } +// ==== +// bytecodeFormat: legacy // ---- // f() -> true // g() -> true diff --git a/test/libsolidity/semanticTests/various/selfdestruct_post_cancun.sol b/test/libsolidity/semanticTests/various/selfdestruct_post_cancun.sol index 4cb5c8c713bf..bf70caee5b54 100644 --- a/test/libsolidity/semanticTests/various/selfdestruct_post_cancun.sol +++ b/test/libsolidity/semanticTests/various/selfdestruct_post_cancun.sol @@ -62,6 +62,7 @@ contract D { } // ==== // EVMVersion: >=cancun +// bytecodeFormat: legacy // ---- // constructor(), 1 ether -> // gas irOptimized: 67028 diff --git a/test/libsolidity/semanticTests/various/selfdestruct_post_cancun_multiple_beneficiaries.sol b/test/libsolidity/semanticTests/various/selfdestruct_post_cancun_multiple_beneficiaries.sol index a582649196c3..7629fabc1ce2 100644 --- a/test/libsolidity/semanticTests/various/selfdestruct_post_cancun_multiple_beneficiaries.sol +++ b/test/libsolidity/semanticTests/various/selfdestruct_post_cancun_multiple_beneficiaries.sol @@ -33,6 +33,7 @@ contract D { } // ==== // EVMVersion: >=cancun +// bytecodeFormat: legacy // ---- // constructor(), 2 ether -> // gas irOptimized: 108104 diff --git a/test/libsolidity/semanticTests/various/selfdestruct_post_cancun_redeploy.sol b/test/libsolidity/semanticTests/various/selfdestruct_post_cancun_redeploy.sol index dd550d31a0cf..c9f50046c07d 100644 --- a/test/libsolidity/semanticTests/various/selfdestruct_post_cancun_redeploy.sol +++ b/test/libsolidity/semanticTests/various/selfdestruct_post_cancun_redeploy.sol @@ -80,6 +80,7 @@ contract D { // ==== // EVMVersion: >=cancun +// bytecodeFormat: legacy // ---- // constructor(), 1 ether -> // gas irOptimized: 132974 From 1a1988b2d08eb9e25a9c69d2e58ee910de10fa8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Mon, 27 Jan 2025 16:14:46 +0100 Subject: [PATCH 0765/1022] EVMHost: Wrap long hard-coded input/output of ecMul --- test/EVMHost.cpp | 135 +++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 112 insertions(+), 23 deletions(-) diff --git a/test/EVMHost.cpp b/test/EVMHost.cpp index 5370542c7e0b..f18140dac93b 100644 --- a/test/EVMHost.cpp +++ b/test/EVMHost.cpp @@ -927,79 +927,167 @@ evmc::Result EVMHost::precompileALTBN128G1Mul(evmc_message const& _message) noex static std::map const inputOutput{ { - fromHex("0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000"), + fromHex( + "0000000000000000000000000000000000000000000000000000000000000001" + "0000000000000000000000000000000000000000000000000000000000000002" + "0000000000000000000000000000000000000000000000000000000000000002" + "0000000000000000000000000000000000000000000000000000000000000000" + ), { - fromHex("030644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd315ed738c0e0a7c92e7845f96b2ae9c0a68a6a449e3538fc7ff3ebf7a5a18a2c4"), + fromHex( + "030644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd3" + "15ed738c0e0a7c92e7845f96b2ae9c0a68a6a449e3538fc7ff3ebf7a5a18a2c4" + ), gas_cost } }, { - fromHex("0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000000000000000000000000"), + fromHex( + "0000000000000000000000000000000000000000000000000000000000000001" + "0000000000000000000000000000000000000000000000000000000000000002" + "0000000000000000000000000000000000000000000000000000000000000005" + "0000000000000000000000000000000000000000000000000000000000000000" + ), { - fromHex("17c139df0efee0f766bc0204762b774362e4ded88953a39ce849a8a7fa163fa901e0559bacb160664764a357af8a9fe70baa9258e0b959273ffc5718c6d4cc7c"), + fromHex( + "17c139df0efee0f766bc0204762b774362e4ded88953a39ce849a8a7fa163fa9" + "01e0559bacb160664764a357af8a9fe70baa9258e0b959273ffc5718c6d4cc7c" + ), gas_cost } }, { - fromHex("09b54f111d3b2d1b2fe1ae9669b3db3d7bf93b70f00647e65c849275de6dc7fe18b2e77c63a3e400d6d1f1fbc6e1a1167bbca603d34d03edea231eb0ab7b14b4030f7b0c405c888aff922307ea2cd1c70f64664bab76899500341f4260a209290000000000000000000000000000000000000000000000000000000000000000"), + fromHex( + "09b54f111d3b2d1b2fe1ae9669b3db3d7bf93b70f00647e65c849275de6dc7fe" + "18b2e77c63a3e400d6d1f1fbc6e1a1167bbca603d34d03edea231eb0ab7b14b4" + "030f7b0c405c888aff922307ea2cd1c70f64664bab76899500341f4260a20929" + "0000000000000000000000000000000000000000000000000000000000000000" + ), { - fromHex("16a1d378d1a98cf5383cdc512011234287ca43b6a078d1842d5c58c5b1f475cc1309377a7026d08ca1529eab74381a7e0d3a4b79d80bacec207cd52fc8e3769c"), + fromHex( + "16a1d378d1a98cf5383cdc512011234287ca43b6a078d1842d5c58c5b1f475cc" + "1309377a7026d08ca1529eab74381a7e0d3a4b79d80bacec207cd52fc8e3769c" + ), gas_cost } }, { - fromHex("0a6de0e2240aa253f46ce0da883b61976e3588146e01c9d8976548c145fe6e4a04fbaa3a4aed4bb77f30ebb07a3ec1c7d77a7f2edd75636babfeff97b1ea686e1551dcd4965285ef049512d2d30cbfc1a91acd5baad4a6e19e22e93176197f170000000000000000000000000000000000000000000000000000000000000000"), + fromHex( + "0a6de0e2240aa253f46ce0da883b61976e3588146e01c9d8976548c145fe6e4a" + "04fbaa3a4aed4bb77f30ebb07a3ec1c7d77a7f2edd75636babfeff97b1ea686e" + "1551dcd4965285ef049512d2d30cbfc1a91acd5baad4a6e19e22e93176197f17" + "0000000000000000000000000000000000000000000000000000000000000000" + ), { - fromHex("28d3c57516712e7843a5b3cfa7d7274a037943f5bd57c227620ad207728e42832795fa9df21d4b8b329a45bae120f1fd9df9049ecacaa9dd1eca18bc6a55cd2f"), + fromHex( + "28d3c57516712e7843a5b3cfa7d7274a037943f5bd57c227620ad207728e4283" + "2795fa9df21d4b8b329a45bae120f1fd9df9049ecacaa9dd1eca18bc6a55cd2f" + ), gas_cost } }, { - fromHex("0c54b42137b67cc268cbb53ac62b00ecead23984092b494a88befe58445a244a18e3723d37fae9262d58b548a0575f59d9c3266db7afb4d5739555837f6b8b3e0c692b41f1acc961f6ea83bae2c3a1a55c54f766c63ba76989f52c149c17b5e70000000000000000000000000000000000000000000000000000000000000000"), + fromHex( + "0c54b42137b67cc268cbb53ac62b00ecead23984092b494a88befe58445a244a" + "18e3723d37fae9262d58b548a0575f59d9c3266db7afb4d5739555837f6b8b3e" + "0c692b41f1acc961f6ea83bae2c3a1a55c54f766c63ba76989f52c149c17b5e7" + "0000000000000000000000000000000000000000000000000000000000000000" + ), { - fromHex("258f1faa356e470cca19c928afa5ceed6215c756912af5725b8db5777cc8f3b6175ced8a58d0c132c2b95ba14c16dde93e7f7789214116ff69da6f44daa966e6"), + fromHex( + "258f1faa356e470cca19c928afa5ceed6215c756912af5725b8db5777cc8f3b6" + "175ced8a58d0c132c2b95ba14c16dde93e7f7789214116ff69da6f44daa966e6" + ), gas_cost } }, { - fromHex("0f103f14a584d4203c27c26155b2c955f8dfa816980b24ba824e1972d6486a5d0c4165133b9f5be17c804203af781bcf168da7386620479f9b885ecbcd27b17b0ea71d0abb524cac7cfff5323e1d0b14ab705842426c978f96753ccce258ed930000000000000000000000000000000000000000000000000000000000000000"), + fromHex( + "0f103f14a584d4203c27c26155b2c955f8dfa816980b24ba824e1972d6486a5d" + "0c4165133b9f5be17c804203af781bcf168da7386620479f9b885ecbcd27b17b" + "0ea71d0abb524cac7cfff5323e1d0b14ab705842426c978f96753ccce258ed93" + "0000000000000000000000000000000000000000000000000000000000000000" + ), { - fromHex("2a49621e12910cd90f3e731083d454255bf1c533d6e15b8699156778d0f27f5d2590ee31824548d159aa2d22296bf149d564c0872f41b89b7dc5c6e6e3cd1c4d"), + fromHex( + "2a49621e12910cd90f3e731083d454255bf1c533d6e15b8699156778d0f27f5d" + "2590ee31824548d159aa2d22296bf149d564c0872f41b89b7dc5c6e6e3cd1c4d" + ), gas_cost } }, { - fromHex("111e2e2a5f8828f80ddad08f9f74db56dac1cc16c1cb278036f79a84cf7a116f1d7d62e192b219b9808faa906c5ced871788f6339e8d91b83ac1343e20a16b3000000000000000000000000000000000000000e40800000000000000008cdcbc0000000000000000000000000000000000000000000000000000000000000000"), + fromHex( + "111e2e2a5f8828f80ddad08f9f74db56dac1cc16c1cb278036f79a84cf7a116f" + "1d7d62e192b219b9808faa906c5ced871788f6339e8d91b83ac1343e20a16b30" + "00000000000000000000000000000000000000e40800000000000000008cdcbc" + "0000000000000000000000000000000000000000000000000000000000000000" + ), { - fromHex("25ff95a3abccf32adc6a4c3c8caddca67723d8ada802e9b9f612e3ddb40b20050d82b09bb4ec927bbf182bdc402790429322b7e2f285f2aad8ea135cbf7143d8"), + fromHex( + "25ff95a3abccf32adc6a4c3c8caddca67723d8ada802e9b9f612e3ddb40b2005" + "0d82b09bb4ec927bbf182bdc402790429322b7e2f285f2aad8ea135cbf7143d8" + ), gas_cost } }, { - fromHex("17d5d09b4146424bff7e6fb01487c477bbfcd0cdbbc92d5d6457aae0b6717cc502b5636903efbf46db9235bbe74045d21c138897fda32e079040db1a16c1a7a11887420878c0c8e37605291c626585eabbec8d8b97a848fe8d58a37b004583510000000000000000000000000000000000000000000000000000000000000000"), + fromHex( + "17d5d09b4146424bff7e6fb01487c477bbfcd0cdbbc92d5d6457aae0b6717cc5" + "02b5636903efbf46db9235bbe74045d21c138897fda32e079040db1a16c1a7a1" + "1887420878c0c8e37605291c626585eabbec8d8b97a848fe8d58a37b00458351" + "0000000000000000000000000000000000000000000000000000000000000000" + ), { - fromHex("2364294faf6b89fedeede9986aa777c4f6c2f5c4a4559ee93dfec9b7b94ef80b05aeae62655ea23865ae6661ae371a55c12098703d0f2301f4223e708c92efc6"), + fromHex( + "2364294faf6b89fedeede9986aa777c4f6c2f5c4a4559ee93dfec9b7b94ef80b" + "05aeae62655ea23865ae6661ae371a55c12098703d0f2301f4223e708c92efc6" + ), gas_cost } }, { - fromHex("1c36e713d4d54e3a9644dffca1fc524be4868f66572516025a61ca542539d43f042dcc4525b82dfb242b09cb21909d5c22643dcdbe98c4d082cc2877e96b24db016086cc934d5cab679c6991a4efcedbab26d7e4fb23b6a1ad4e6b5c2fb59ce50000000000000000000000000000000000000000000000000000000000000000"), + fromHex( + "1c36e713d4d54e3a9644dffca1fc524be4868f66572516025a61ca542539d43f" + "042dcc4525b82dfb242b09cb21909d5c22643dcdbe98c4d082cc2877e96b24db" + "016086cc934d5cab679c6991a4efcedbab26d7e4fb23b6a1ad4e6b5c2fb59ce5" + "0000000000000000000000000000000000000000000000000000000000000000" + ), { - fromHex("1644e84fef7b7fdc98254f0654580173307a3bc44db990581e7ab55a22446dcf28c2916b7e875692b195831945805438fcd30d2693d8a80cf8c88ec6ef4c315d"), + fromHex( + "1644e84fef7b7fdc98254f0654580173307a3bc44db990581e7ab55a22446dcf" + "28c2916b7e875692b195831945805438fcd30d2693d8a80cf8c88ec6ef4c315d" + ), gas_cost } }, { - fromHex("1e39e9f0f91fa7ff8047ffd90de08785777fe61c0e3434e728fce4cf35047ddc2e0b64d75ebfa86d7f8f8e08abbe2e7ae6e0a1c0b34d028f19fa56e9450527cb1eec35a0e955cad4bee5846ae0f1d0b742d8636b278450c534e38e06a60509f90000000000000000000000000000000000000000000000000000000000000000"), + fromHex( + "1e39e9f0f91fa7ff8047ffd90de08785777fe61c0e3434e728fce4cf35047ddc" + "2e0b64d75ebfa86d7f8f8e08abbe2e7ae6e0a1c0b34d028f19fa56e9450527cb" + "1eec35a0e955cad4bee5846ae0f1d0b742d8636b278450c534e38e06a60509f9" + "0000000000000000000000000000000000000000000000000000000000000000" + ), { - fromHex("1385281136ff5b2c326807ff0a824b6ca4f21fcc7c8764e9801bc4ad497d501202254594be8473dcf018a2aa66ea301e38fc865823acf75a9901721d1fc6bf4c"), + fromHex( + "1385281136ff5b2c326807ff0a824b6ca4f21fcc7c8764e9801bc4ad497d5012" + "02254594be8473dcf018a2aa66ea301e38fc865823acf75a9901721d1fc6bf4c" + ), gas_cost } }, { - fromHex("232063b584fb76c8d07995bee3a38fa7565405f3549c6a918ddaa90ab971e7f82ac9b135a81d96425c92d02296322ad56ffb16299633233e4880f95aafa7fda70689c3dc4311426ee11707866b2cbdf9751dacd07245bf99d2113d3f5a8cac470000000000000000000000000000000000000000000000000000000000000000"), + fromHex( + "232063b584fb76c8d07995bee3a38fa7565405f3549c6a918ddaa90ab971e7f8" + "2ac9b135a81d96425c92d02296322ad56ffb16299633233e4880f95aafa7fda7" + "0689c3dc4311426ee11707866b2cbdf9751dacd07245bf99d2113d3f5a8cac47" + "0000000000000000000000000000000000000000000000000000000000000000" + ), { - fromHex("2174f0221490cd9c15b0387f3251ec3d49517a51c37a8076eac12afb4a95a7071d1c3fcd3161e2a417b4df0955f02db1fffa9005210fb30c5aa3755307e9d1f5"), + fromHex( + "2174f0221490cd9c15b0387f3251ec3d49517a51c37a8076eac12afb4a95a707" + "1d1c3fcd3161e2a417b4df0955f02db1fffa9005210fb30c5aa3755307e9d1f5" + ), gas_cost } } @@ -1184,7 +1272,8 @@ evmc::Result EVMHost::precompileBlake2f(evmc_message const&) noexcept evmc::Result EVMHost::precompileGeneric( evmc_message const& _message, - std::map const& _inOut) noexcept + std::map const& _inOut +) noexcept { bytes input(_message.input_data, _message.input_data + _message.input_size); if (_inOut.count(input)) From 8834c4ee2f97c0511498d6bd83483fa3b3f91701 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Mon, 27 Jan 2025 16:22:05 +0100 Subject: [PATCH 0766/1022] EVMHost: Remove extra zeros from hard-coded ecAdd/ecMull inputs --- test/EVMHost.cpp | 41 ------------------- .../semanticTests/externalContracts/snark.sol | 16 ++++---- 2 files changed, 8 insertions(+), 49 deletions(-) diff --git a/test/EVMHost.cpp b/test/EVMHost.cpp index f18140dac93b..38752dde64fa 100644 --- a/test/EVMHost.cpp +++ b/test/EVMHost.cpp @@ -664,8 +664,6 @@ evmc::Result EVMHost::precompileALTBN128G1Add(evmc_message const& _message) noex "0000000000000000000000000000000000000000000000000000000000000000" "1385281136ff5b2c326807ff0a824b6ca4f21fcc7c8764e9801bc4ad497d5012" "02254594be8473dcf018a2aa66ea301e38fc865823acf75a9901721d1fc6bf4c" - "0000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000" ), { fromHex( @@ -681,8 +679,6 @@ evmc::Result EVMHost::precompileALTBN128G1Add(evmc_message const& _message) noex "0000000000000000000000000000000000000000000000000000000000000002" "0000000000000000000000000000000000000000000000000000000000000001" "0000000000000000000000000000000000000000000000000000000000000002" - "0000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000" ), { fromHex( @@ -698,8 +694,6 @@ evmc::Result EVMHost::precompileALTBN128G1Add(evmc_message const& _message) noex "0000000000000000000000000000000000000000000000000000000000000002" "0000000000000000000000000000000000000000000000000000000000000001" "30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd45" - "0000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000" ), { fromHex( @@ -715,8 +709,6 @@ evmc::Result EVMHost::precompileALTBN128G1Add(evmc_message const& _message) noex "09f5528bdb0ef9354837a0f4b4c9da973bd5b805d359976f719ab0b74e0a7368" "28d3c57516712e7843a5b3cfa7d7274a037943f5bd57c227620ad207728e4283" "2795fa9df21d4b8b329a45bae120f1fd9df9049ecacaa9dd1eca18bc6a55cd2f" - "0000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000" ), { fromHex( @@ -732,8 +724,6 @@ evmc::Result EVMHost::precompileALTBN128G1Add(evmc_message const& _message) noex "02254594be8473dcf018a2aa66ea301e38fc865823acf75a9901721d1fc6bf4c" "1644e84fef7b7fdc98254f0654580173307a3bc44db990581e7ab55a22446dcf" "28c2916b7e875692b195831945805438fcd30d2693d8a80cf8c88ec6ef4c315d" - "0000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000" ), { fromHex( @@ -749,8 +739,6 @@ evmc::Result EVMHost::precompileALTBN128G1Add(evmc_message const& _message) noex "16dabf21b3f25b9665269d98dc17b1da6118251dc0b403ae50e96dfe91239375" "25ff95a3abccf32adc6a4c3c8caddca67723d8ada802e9b9f612e3ddb40b2005" "0d82b09bb4ec927bbf182bdc402790429322b7e2f285f2aad8ea135cbf7143d8" - "0000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000" ), { fromHex( @@ -766,8 +754,6 @@ evmc::Result EVMHost::precompileALTBN128G1Add(evmc_message const& _message) noex "1b5ed0e9e8f3ff35589ea81a45cf63887d4a92c099a3be1d97b26f0db96323dd" "16a1d378d1a98cf5383cdc512011234287ca43b6a078d1842d5c58c5b1f475cc" "1309377a7026d08ca1529eab74381a7e0d3a4b79d80bacec207cd52fc8e3769c" - "0000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000" ), { fromHex( @@ -783,8 +769,6 @@ evmc::Result EVMHost::precompileALTBN128G1Add(evmc_message const& _message) noex "3034dd2920f673e204fee2811c678745fc819b55d3e9d294e45c9b03a76aef41" "0f25929bcb43d5a57391564615c9e70a992b10eafa4db109709649cf48c50dd2" "16da2f5cb6be7a0aa72c440c53c9bbdfec6c36c7d515536431b3a865468acbba" - "0000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000" ), { fromHex( @@ -800,8 +784,6 @@ evmc::Result EVMHost::precompileALTBN128G1Add(evmc_message const& _message) noex "1d1f2259c715327bedb42c095af6c0267e4e1be836b4e04b3f0502552f93cca9" "2364294faf6b89fedeede9986aa777c4f6c2f5c4a4559ee93dfec9b7b94ef80b" "05aeae62655ea23865ae6661ae371a55c12098703d0f2301f4223e708c92efc6" - "0000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000" ), { fromHex( @@ -817,8 +799,6 @@ evmc::Result EVMHost::precompileALTBN128G1Add(evmc_message const& _message) noex "0185fbba22de9e698262925665735dbc4d6e8288bc3fc39fae10ca58e16e77f7" "258f1faa356e470cca19c928afa5ceed6215c756912af5725b8db5777cc8f3b6" "175ced8a58d0c132c2b95ba14c16dde93e7f7789214116ff69da6f44daa966e6" - "0000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000" ), { fromHex( @@ -834,8 +814,6 @@ evmc::Result EVMHost::precompileALTBN128G1Add(evmc_message const& _message) noex "27c440dbd5053253a3a692f9bf89b9b6e9612127cf97db1e11ffa9679acc933b" "1496064626ba8bffeb7805f0d16143a65649bb0850333ea512c03fcdaf31e254" "07b4f210ab542533f1ee5633ae4406cd16c63494b537ce3f1cf4afff6f76a48f" - "0000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000" ), { fromHex( @@ -851,8 +829,6 @@ evmc::Result EVMHost::precompileALTBN128G1Add(evmc_message const& _message) noex "27c440dbd5053253a3a692f9bf89b9b6e9612127cf97db1e11ffa9679acc933b" "1c76476f4def4bb94541d57ebba1193381ffa7aa76ada664dd31c16024c43f59" "3034dd2920f673e204fee2811c678745fc819b55d3e9d294e45c9b03a76aef41" - "0000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000" ), { fromHex( @@ -868,8 +844,6 @@ evmc::Result EVMHost::precompileALTBN128G1Add(evmc_message const& _message) noex "26dd3d225c9a71476db0cf834232eba84020f3073c6d20c519963e0b98f235e1" "2174f0221490cd9c15b0387f3251ec3d49517a51c37a8076eac12afb4a95a707" "1d1c3fcd3161e2a417b4df0955f02db1fffa9005210fb30c5aa3755307e9d1f5" - "0000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000" ), { fromHex( @@ -885,8 +859,6 @@ evmc::Result EVMHost::precompileALTBN128G1Add(evmc_message const& _message) noex "13cf106acf943c2a331de21c7d5e3351354e7412f2dba2918483a6593a6828d4" "2a49621e12910cd90f3e731083d454255bf1c533d6e15b8699156778d0f27f5d" "2590ee31824548d159aa2d22296bf149d564c0872f41b89b7dc5c6e6e3cd1c4d" - "0000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000" ), { fromHex( @@ -902,8 +874,6 @@ evmc::Result EVMHost::precompileALTBN128G1Add(evmc_message const& _message) noex "2c7cdf62c2498486fd52646e577a06723ce97737b3c958262d78c4a413661e8a" "0aee46a7ea6e80a3675026dfa84019deee2a2dedb1bbe11d7fe124cb3efb4b5a" "044747b6e9176e13ede3a4dfd0d33ccca6321b9acd23bf3683a60adc0366ebaf" - "0000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000" ), { fromHex( @@ -931,7 +901,6 @@ evmc::Result EVMHost::precompileALTBN128G1Mul(evmc_message const& _message) noex "0000000000000000000000000000000000000000000000000000000000000001" "0000000000000000000000000000000000000000000000000000000000000002" "0000000000000000000000000000000000000000000000000000000000000002" - "0000000000000000000000000000000000000000000000000000000000000000" ), { fromHex( @@ -946,7 +915,6 @@ evmc::Result EVMHost::precompileALTBN128G1Mul(evmc_message const& _message) noex "0000000000000000000000000000000000000000000000000000000000000001" "0000000000000000000000000000000000000000000000000000000000000002" "0000000000000000000000000000000000000000000000000000000000000005" - "0000000000000000000000000000000000000000000000000000000000000000" ), { fromHex( @@ -961,7 +929,6 @@ evmc::Result EVMHost::precompileALTBN128G1Mul(evmc_message const& _message) noex "09b54f111d3b2d1b2fe1ae9669b3db3d7bf93b70f00647e65c849275de6dc7fe" "18b2e77c63a3e400d6d1f1fbc6e1a1167bbca603d34d03edea231eb0ab7b14b4" "030f7b0c405c888aff922307ea2cd1c70f64664bab76899500341f4260a20929" - "0000000000000000000000000000000000000000000000000000000000000000" ), { fromHex( @@ -976,7 +943,6 @@ evmc::Result EVMHost::precompileALTBN128G1Mul(evmc_message const& _message) noex "0a6de0e2240aa253f46ce0da883b61976e3588146e01c9d8976548c145fe6e4a" "04fbaa3a4aed4bb77f30ebb07a3ec1c7d77a7f2edd75636babfeff97b1ea686e" "1551dcd4965285ef049512d2d30cbfc1a91acd5baad4a6e19e22e93176197f17" - "0000000000000000000000000000000000000000000000000000000000000000" ), { fromHex( @@ -991,7 +957,6 @@ evmc::Result EVMHost::precompileALTBN128G1Mul(evmc_message const& _message) noex "0c54b42137b67cc268cbb53ac62b00ecead23984092b494a88befe58445a244a" "18e3723d37fae9262d58b548a0575f59d9c3266db7afb4d5739555837f6b8b3e" "0c692b41f1acc961f6ea83bae2c3a1a55c54f766c63ba76989f52c149c17b5e7" - "0000000000000000000000000000000000000000000000000000000000000000" ), { fromHex( @@ -1006,7 +971,6 @@ evmc::Result EVMHost::precompileALTBN128G1Mul(evmc_message const& _message) noex "0f103f14a584d4203c27c26155b2c955f8dfa816980b24ba824e1972d6486a5d" "0c4165133b9f5be17c804203af781bcf168da7386620479f9b885ecbcd27b17b" "0ea71d0abb524cac7cfff5323e1d0b14ab705842426c978f96753ccce258ed93" - "0000000000000000000000000000000000000000000000000000000000000000" ), { fromHex( @@ -1021,7 +985,6 @@ evmc::Result EVMHost::precompileALTBN128G1Mul(evmc_message const& _message) noex "111e2e2a5f8828f80ddad08f9f74db56dac1cc16c1cb278036f79a84cf7a116f" "1d7d62e192b219b9808faa906c5ced871788f6339e8d91b83ac1343e20a16b30" "00000000000000000000000000000000000000e40800000000000000008cdcbc" - "0000000000000000000000000000000000000000000000000000000000000000" ), { fromHex( @@ -1036,7 +999,6 @@ evmc::Result EVMHost::precompileALTBN128G1Mul(evmc_message const& _message) noex "17d5d09b4146424bff7e6fb01487c477bbfcd0cdbbc92d5d6457aae0b6717cc5" "02b5636903efbf46db9235bbe74045d21c138897fda32e079040db1a16c1a7a1" "1887420878c0c8e37605291c626585eabbec8d8b97a848fe8d58a37b00458351" - "0000000000000000000000000000000000000000000000000000000000000000" ), { fromHex( @@ -1051,7 +1013,6 @@ evmc::Result EVMHost::precompileALTBN128G1Mul(evmc_message const& _message) noex "1c36e713d4d54e3a9644dffca1fc524be4868f66572516025a61ca542539d43f" "042dcc4525b82dfb242b09cb21909d5c22643dcdbe98c4d082cc2877e96b24db" "016086cc934d5cab679c6991a4efcedbab26d7e4fb23b6a1ad4e6b5c2fb59ce5" - "0000000000000000000000000000000000000000000000000000000000000000" ), { fromHex( @@ -1066,7 +1027,6 @@ evmc::Result EVMHost::precompileALTBN128G1Mul(evmc_message const& _message) noex "1e39e9f0f91fa7ff8047ffd90de08785777fe61c0e3434e728fce4cf35047ddc" "2e0b64d75ebfa86d7f8f8e08abbe2e7ae6e0a1c0b34d028f19fa56e9450527cb" "1eec35a0e955cad4bee5846ae0f1d0b742d8636b278450c534e38e06a60509f9" - "0000000000000000000000000000000000000000000000000000000000000000" ), { fromHex( @@ -1081,7 +1041,6 @@ evmc::Result EVMHost::precompileALTBN128G1Mul(evmc_message const& _message) noex "232063b584fb76c8d07995bee3a38fa7565405f3549c6a918ddaa90ab971e7f8" "2ac9b135a81d96425c92d02296322ad56ffb16299633233e4880f95aafa7fda7" "0689c3dc4311426ee11707866b2cbdf9751dacd07245bf99d2113d3f5a8cac47" - "0000000000000000000000000000000000000000000000000000000000000000" ), { fromHex( diff --git a/test/libsolidity/semanticTests/externalContracts/snark.sol b/test/libsolidity/semanticTests/externalContracts/snark.sol index 2b1fe023e075..c073993e1d37 100644 --- a/test/libsolidity/semanticTests/externalContracts/snark.sol +++ b/test/libsolidity/semanticTests/externalContracts/snark.sol @@ -37,7 +37,7 @@ library Pairing { /// @return r the sum of two points of G1 function add(G1Point memory p1, G1Point memory p2) internal returns (G1Point memory r) { - uint[6] memory input; + uint[4] memory input; input[0] = p1.X; input[1] = p1.Y; input[2] = p2.X; @@ -50,7 +50,7 @@ library Pairing { /// @return r the product of a point on G1 and a scalar, i.e. /// p == p.mul(1) and p.add(p) == p.mul(2) for all points p. function mul(G1Point memory p, uint s) internal returns (G1Point memory r) { - uint[4] memory input; + uint[3] memory input; input[0] = p.X; input[1] = p.Y; input[2] = s; @@ -292,11 +292,11 @@ contract Test { // f() -> true // g() -> true // pair() -> true -// gas irOptimized: 275319 -// gas legacy: 293854 -// gas legacyOptimized: 276409 +// gas irOptimized: 275229 +// gas legacy: 293579 +// gas legacyOptimized: 276313 // verifyTx() -> true // ~ emit Verified(string): 0x20, 0x16, "Successfully verified." -// gas irOptimized: 821446 -// gas legacy: 914211 -// gas legacyOptimized: 820319 +// gas irOptimized: 818076 +// gas legacy: 904397 +// gas legacyOptimized: 816770 From 87c0b6b46f1dbb391b67d50989e3d28b4bba011d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Tue, 28 Jan 2025 16:41:40 +0100 Subject: [PATCH 0767/1022] EVMHost: Ignore trailing input in ecRecover, ecAdd and ecMul precompiles - Our mock implementation only worked for the exact hard-coded inputs we had and failed if there were any trailing bytes. Real precompiles would ignore those bytes. --- test/EVMHost.cpp | 24 +++++++++++--- test/EVMHost.h | 12 ++++++- .../precompiles_ignoring_trailing_input.sol | 32 +++++++++++++++++++ 3 files changed, 62 insertions(+), 6 deletions(-) create mode 100644 test/libsolidity/semanticTests/isoltestTesting/precompiles_ignoring_trailing_input.sol diff --git a/test/EVMHost.cpp b/test/EVMHost.cpp index 38752dde64fa..a3d1d427d7ae 100644 --- a/test/EVMHost.cpp +++ b/test/EVMHost.cpp @@ -507,7 +507,7 @@ evmc::Result EVMHost::precompileECRecover(evmc_message const& _message) noexcept } } }; - evmc::Result result = precompileGeneric(_message, inputOutput); + evmc::Result result = precompileGeneric(_message, inputOutput, true /* _ignoresTrailingInput */); // ECRecover will return success with empty response in case of failure if (result.status_code != EVMC_SUCCESS && result.status_code != EVMC_OUT_OF_GAS) return resultWithGas(_message.gas, gas_cost, {}); @@ -884,7 +884,7 @@ evmc::Result EVMHost::precompileALTBN128G1Add(evmc_message const& _message) noex } } }; - return precompileGeneric(_message, inputOutput); + return precompileGeneric(_message, inputOutput, true /* _ignoresTrailingInput */); } template @@ -1051,7 +1051,7 @@ evmc::Result EVMHost::precompileALTBN128G1Mul(evmc_message const& _message) noex } } }; - return precompileGeneric(_message, inputOutput); + return precompileGeneric(_message, inputOutput, true /* _ignoresTrailingInput */); } template @@ -1220,6 +1220,7 @@ evmc::Result EVMHost::precompileALTBN128PairingProduct(evmc_message const& _mess } } }; + return precompileGeneric(_message, inputOutput); } @@ -1231,10 +1232,23 @@ evmc::Result EVMHost::precompileBlake2f(evmc_message const&) noexcept evmc::Result EVMHost::precompileGeneric( evmc_message const& _message, - std::map const& _inOut + std::map const& _inOut, + bool _ignoresTrailingInput ) noexcept { - bytes input(_message.input_data, _message.input_data + _message.input_size); + size_t meaningfulInputSize = _message.input_size; + if (_ignoresTrailingInput && !_inOut.empty()) + { + // _ignoresTrailingInput only implemented for the case where all inputs have same size. + // Simpler to implement and it's all we need for now. + for (auto const& [input, output]: _inOut) + solAssert(input.size() == _inOut.begin()->first.size()); + + // If there is more input that expected, precompiles tend to simply ignore it. + meaningfulInputSize = std::min(_message.input_size, _inOut.begin()->first.size()); + } + + bytes input(_message.input_data, _message.input_data + meaningfulInputSize); if (_inOut.count(input)) { auto const& ret = _inOut.at(input); diff --git a/test/EVMHost.h b/test/EVMHost.h index 121adbc15945..522eb7b72fed 100644 --- a/test/EVMHost.h +++ b/test/EVMHost.h @@ -124,7 +124,17 @@ class EVMHost: public evmc::MockedHost template static evmc::Result precompileALTBN128PairingProduct(evmc_message const& _message) noexcept; static evmc::Result precompileBlake2f(evmc_message const& _message) noexcept; - static evmc::Result precompileGeneric(evmc_message const& _message, std::map const& _inOut) noexcept; + /// Generic implementation of a precompile for testing, with hard-coded answers for hard-coded inputs. + /// @param _message EVM message to handle. + /// @param _inOut Hard-coded inputs and corresponding outputs to be returned. + /// @param _ignoresTrailingInput Enable if the precompile only cares about the initial part of + /// its input and works exactly the same, regardless of what's in the remaining part. The message will + /// be considered a match for a test input even if it's longer. + static evmc::Result precompileGeneric( + evmc_message const& _message, + std::map const& _inOut, + bool _ignoresTrailingInput = false + ) noexcept; /// @returns a result object with gas usage and result data taken from @a _data. /// The outcome will be a failure if the limit < required. /// @note The return value is only valid as long as @a _data is alive! diff --git a/test/libsolidity/semanticTests/isoltestTesting/precompiles_ignoring_trailing_input.sol b/test/libsolidity/semanticTests/isoltestTesting/precompiles_ignoring_trailing_input.sol new file mode 100644 index 000000000000..920c6b06ef32 --- /dev/null +++ b/test/libsolidity/semanticTests/isoltestTesting/precompiles_ignoring_trailing_input.sol @@ -0,0 +1,32 @@ +contract C { + function ecRecover(uint[4] memory input) public returns (bytes memory) { + (bool success, bytes memory encodedOutput) = address(1).call(abi.encode(input)); + require(success); + return encodedOutput; + } + + function ecAdd(uint[4] memory input) public returns (bytes memory) { + (bool success, bytes memory encodedOutput) = address(6).call(abi.encode(input)); + require(success); + return encodedOutput; + } + + function ecMul(uint[3] memory input) public returns (bytes memory) { + (bool success, bytes memory encodedOutput) = address(7).call(abi.encode(input)); + require(success); + return encodedOutput; + } +} +// ---- +// ecRecover(uint256[4]): 0x18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c, 0x000000000000000000000000000000000000000000000000000000000000001c, 0x73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f, 0xeeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549 -> 0x20, 0x20, 966588469268559010541288244128342317224451555083 +// ecRecover(uint256[4]): 0x18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c, 0x000000000000000000000000000000000000000000000000000000000000001c, 0x73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f, 0xeeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549, 0x01, 0x02, 0x03 -> 0x20, 0x20, 966588469268559010541288244128342317224451555083 + +// ecAdd(uint256[4]): 0x01, 0x02, 0x01, 0x02 -> 0x20, 0x40, 1368015179489954701390400359078579693043519447331113978918064868415326638035, 9918110051302171585080402603319702774565515993150576347155970296011118125764 +// ecAdd(uint256[4]): 0x01, 0x02, 0x01, 0x02, 0x01 -> 0x20, 0x40, 1368015179489954701390400359078579693043519447331113978918064868415326638035, 9918110051302171585080402603319702774565515993150576347155970296011118125764 +// ecAdd(uint256[4]): 0x01, 0x02, 0x01, 0x02, 0x01, 0x02 -> 0x20, 0x40, 1368015179489954701390400359078579693043519447331113978918064868415326638035, 9918110051302171585080402603319702774565515993150576347155970296011118125764 +// ecAdd(uint256[4]): 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x03 -> 0x20, 0x40, 1368015179489954701390400359078579693043519447331113978918064868415326638035, 9918110051302171585080402603319702774565515993150576347155970296011118125764 + +// ecMul(uint256[3]): 0x01, 0x02, 0x02 -> 0x20, 0x40, 1368015179489954701390400359078579693043519447331113978918064868415326638035, 9918110051302171585080402603319702774565515993150576347155970296011118125764 +// ecMul(uint256[3]): 0x01, 0x02, 0x02, 0x01 -> 0x20, 0x40, 1368015179489954701390400359078579693043519447331113978918064868415326638035, 9918110051302171585080402603319702774565515993150576347155970296011118125764 +// ecMul(uint256[3]): 0x01, 0x02, 0x02, 0x01, 0x02 -> 0x20, 0x40, 1368015179489954701390400359078579693043519447331113978918064868415326638035, 9918110051302171585080402603319702774565515993150576347155970296011118125764 +// ecMul(uint256[3]): 0x01, 0x02, 0x02, 0x01, 0x02, 0x03 -> 0x20, 0x40, 1368015179489954701390400359078579693043519447331113978918064868415326638035, 9918110051302171585080402603319702774565515993150576347155970296011118125764 From 349e7fc86c8ffd84fdc2765e9d7f9d71ccca192f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Tue, 28 Jan 2025 16:38:42 +0100 Subject: [PATCH 0768/1022] EVMHost: Report unexpected precompile input as a test error rather than a revert - Currently it looks as if EVM reverted, but we should make it clear that we simply don't have a hard-coded value matching the input - Some tests were relying on this behavior - they need specific hard-coded outputs. --- test/EVMHost.cpp | 31 ++++++++++++++++++- .../failing_ecrecover_invalid_input.sol | 4 +-- .../bare_call_no_returndatacopy.sol | 3 +- 3 files changed, 34 insertions(+), 4 deletions(-) diff --git a/test/EVMHost.cpp b/test/EVMHost.cpp index a3d1d427d7ae..897f01c68ac3 100644 --- a/test/EVMHost.cpp +++ b/test/EVMHost.cpp @@ -505,6 +505,30 @@ evmc::Result EVMHost::precompileECRecover(evmc_message const& _message) noexcept fromHex("0000000000000000000000008743523d96a1b2cbe0c6909653a56da18ed484af"), gas_cost } + }, + { + fromHex( + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + "0000000000000000000000000000000000000000000000000000000000000001" + "0000000000000000000000000000000000000000000000000000000000000002" + "0000000000000000000000000000000000000000000000000000000000000003" + ), + { + fromHex(""), + gas_cost + } + }, + { + fromHex( + "77e5189111eb6557e8a637b27ef8fbb15bc61d61c2f00cc48878f3a296e5e0ca" + "0000000000000000000000000000000000000000000000000000000000000000" + "6944c77849b18048f6abe0db8084b0d0d0689cdddb53d2671c36967b58691ad4" + "ef4f06ba4f78319baafd0424365777241af4dfd3da840471b4b4b087b7750d0d" + ), + { + fromHex(""), + gas_cost + } } }; evmc::Result result = precompileGeneric(_message, inputOutput, true /* _ignoresTrailingInput */); @@ -1255,7 +1279,12 @@ evmc::Result EVMHost::precompileGeneric( return resultWithGas(_message.gas, ret.gas_used, ret.output); } else - return resultWithFailure(); + // FIXME: We're in a noexcept function; this will result in terminate() and then abort(). + // Still better than nothing - can't be mistaken for revert and Boost will report test name. + solThrow( + Exception, + "Test output for a precompile not defined for input: " + toHex(input, HexPrefix::Add) + ); } evmc::Result EVMHost::resultWithFailure() noexcept diff --git a/test/libsolidity/semanticTests/ecrecover/failing_ecrecover_invalid_input.sol b/test/libsolidity/semanticTests/ecrecover/failing_ecrecover_invalid_input.sol index 55621bdcdae6..ee3f4c6bec51 100644 --- a/test/libsolidity/semanticTests/ecrecover/failing_ecrecover_invalid_input.sol +++ b/test/libsolidity/semanticTests/ecrecover/failing_ecrecover_invalid_input.sol @@ -1,7 +1,7 @@ contract C { // ecrecover should return zero for malformed input - // (v should be 27 or 28, not 1) - // Note that the precompile does not return zero but returns nothing. + // (v should be 27 or 28, not 1) + // Note that the precompile does not return zero but returns nothing. function f() public returns (address) { return ecrecover(bytes32(type(uint256).max), 1, bytes32(uint(2)), bytes32(uint(3))); } diff --git a/test/libsolidity/semanticTests/functionCall/bare_call_no_returndatacopy.sol b/test/libsolidity/semanticTests/functionCall/bare_call_no_returndatacopy.sol index 17b6f74c8739..3b3afab3bf07 100644 --- a/test/libsolidity/semanticTests/functionCall/bare_call_no_returndatacopy.sol +++ b/test/libsolidity/semanticTests/functionCall/bare_call_no_returndatacopy.sol @@ -1,6 +1,7 @@ contract C { function f() public returns (bool) { - (bool success, ) = address(1).call(""); + // Random address, no contract deployed to it. + (bool success, ) = address(0xffff).call(""); return success; } } From caa37d30afe0efe402e9b0f89fda54796c138567 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Thu, 30 Jan 2025 18:54:56 +0100 Subject: [PATCH 0769/1022] isoltest: Remove duplicate warning about not enforcing gas expectations --- test/soltest.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/test/soltest.cpp b/test/soltest.cpp index 8e7a3ddcd4a9..9bc60d1181f8 100644 --- a/test/soltest.cpp +++ b/test/soltest.cpp @@ -230,9 +230,6 @@ test_suite* init_unit_test_suite(int /*argc*/, char* /*argv*/[]) if (solidity::test::CommonOptions::get().disableSemanticTests) std::cout << std::endl << "--- SKIPPING ALL SEMANTICS TESTS ---" << std::endl << std::endl; - if (!solidity::test::CommonOptions::get().enforceGasTest) - std::cout << std::endl << "WARNING :: Gas Cost Expectations are not being enforced" << std::endl << std::endl; - Batcher batcher(CommonOptions::get().selectedBatch, CommonOptions::get().batches); if (CommonOptions::get().batches > 1) std::cout << "Batch " << CommonOptions::get().selectedBatch << " out of " << CommonOptions::get().batches << std::endl; From eb56b4bfe6fe9996342b27d4fc6a4001725d4446 Mon Sep 17 00:00:00 2001 From: Martin Blicha Date: Fri, 31 Jan 2025 20:12:15 +0100 Subject: [PATCH 0770/1022] SMTChecker: Remove code left over after switch to SMT-LIB interface This is the last occurence of the HAVE_Z3 macro in the codebase. --- libsolidity/formal/BMC.cpp | 11 ----------- scripts/error_codes.py | 1 - 2 files changed, 12 deletions(-) diff --git a/libsolidity/formal/BMC.cpp b/libsolidity/formal/BMC.cpp index 86c7eb7a89f8..5fb2f5a9fd75 100644 --- a/libsolidity/formal/BMC.cpp +++ b/libsolidity/formal/BMC.cpp @@ -58,17 +58,6 @@ BMC::BMC( if (_settings.solvers.z3 ) solvers.emplace_back(std::make_unique(_smtCallback, _settings.timeout)); m_interface = std::make_unique(std::move(solvers), _settings.timeout); -#if defined (HAVE_Z3) - if (m_settings.solvers.z3) - if (!_smtlib2Responses.empty()) - m_errorReporter.warning( - 5622_error, - "SMT-LIB2 query responses were given in the auxiliary input, " - "but this Solidity binary uses an SMT solver Z3 directly." - "These responses will be ignored." - "Consider disabling Z3 at compilation time in order to use SMT-LIB2 responses." - ); -#endif } void BMC::analyze(SourceUnit const& _source, std::map, smt::EncodingContext::IdCompare> _solvedTargets) diff --git a/scripts/error_codes.py b/scripts/error_codes.py index 50021d986478..d99d60c6e284 100755 --- a/scripts/error_codes.py +++ b/scripts/error_codes.py @@ -246,7 +246,6 @@ def examine_id_coverage(top_dir, source_id_to_file_names, new_ids_only=False): "4802", "4902", "5272", - "5622", "5798", "5840", "7128", From 8fc863d3bb47f0df760cff3e825f21c00216a9c8 Mon Sep 17 00:00:00 2001 From: rodiazet Date: Sat, 1 Feb 2025 10:14:26 +0100 Subject: [PATCH 0771/1022] eof: `objectCompiler` tests updating --- test/libyul/objectCompiler/data.yul | 2 + test/libyul/objectCompiler/datacopy.yul | 1 + .../libyul/objectCompiler/dataoffset_code.yul | 1 + .../libyul/objectCompiler/dataoffset_data.yul | 1 + .../libyul/objectCompiler/dataoffset_self.yul | 1 + test/libyul/objectCompiler/datasize_code.yul | 1 + test/libyul/objectCompiler/datasize_data.yul | 1 + test/libyul/objectCompiler/datasize_self.yul | 1 + .../eof/leading_and_trailing_dots.yul | 30 +++++ .../objectCompiler/eof/long_object_name.yul | 33 +++++ test/libyul/objectCompiler/eof/simple.yul | 19 +++ test/libyul/objectCompiler/eof/smoke.yul | 12 ++ test/libyul/objectCompiler/eof/subObject.yul | 29 +++++ .../objectCompiler/eof/subSubObject.yul | 49 ++++++++ .../objectCompiler/eof/verbatim_bug.yul | 118 ++++++++++++++++++ .../libyul/objectCompiler/function_series.yul | 1 + ...identical_subobjects_creation_deployed.yul | 4 +- .../identical_subobjects_full_debug_info.yul | 4 +- .../identical_subobjects_no_debug_info.yul | 4 +- ...dentical_subobjects_partial_debug_info.yul | 4 +- ...bobjects_partial_debug_info_no_use_src.yul | 4 +- ...cal_subobjects_with_subject_references.yul | 5 +- ..._long_name_does_not_end_up_in_bytecode.yul | 1 + test/libyul/objectCompiler/jump_tags.yul | 1 + .../leading_and_trailing_dots.yul | 5 +- test/libyul/objectCompiler/linkersymbol.yul | 29 ++--- .../objectCompiler/long_object_name.yul | 5 +- test/libyul/objectCompiler/manySubObjects.yul | 5 +- test/libyul/objectCompiler/metadata.yul | 1 + test/libyul/objectCompiler/namedObject.yul | 4 +- .../libyul/objectCompiler/namedObjectCode.yul | 4 +- .../objectCompiler/nested_optimizer.yul | 4 +- test/libyul/objectCompiler/simple.yul | 1 + .../objectCompiler/simple_optimizer.yul | 4 +- test/libyul/objectCompiler/smoke.yul | 1 + .../libyul/objectCompiler/sourceLocations.yul | 1 + test/libyul/objectCompiler/subObject.yul | 1 + .../libyul/objectCompiler/subObjectAccess.yul | 1 + test/libyul/objectCompiler/subSubObject.yul | 1 + test/libyul/objectCompiler/verbatim_bug.yul | 5 +- 40 files changed, 339 insertions(+), 60 deletions(-) create mode 100644 test/libyul/objectCompiler/eof/leading_and_trailing_dots.yul create mode 100644 test/libyul/objectCompiler/eof/long_object_name.yul create mode 100644 test/libyul/objectCompiler/eof/simple.yul create mode 100644 test/libyul/objectCompiler/eof/smoke.yul create mode 100644 test/libyul/objectCompiler/eof/subObject.yul create mode 100644 test/libyul/objectCompiler/eof/subSubObject.yul create mode 100644 test/libyul/objectCompiler/eof/verbatim_bug.yul diff --git a/test/libyul/objectCompiler/data.yul b/test/libyul/objectCompiler/data.yul index 4447a0b8e97f..53eb24ce1915 100644 --- a/test/libyul/objectCompiler/data.yul +++ b/test/libyul/objectCompiler/data.yul @@ -1,10 +1,12 @@ object "a" { code {} // Unreferenced data is not added to the assembled bytecode. + // TODO: This is not implemented for EOF. Should work for legacy and EOF when implemented. data "str" "Hello, World!" } // ==== // EVMVersion: >=constantinople +// bytecodeFormat: legacy // ---- // Assembly: // /* "source":22:29 */ diff --git a/test/libyul/objectCompiler/datacopy.yul b/test/libyul/objectCompiler/datacopy.yul index 46a0ec0f7a6d..ea00b4478461 100644 --- a/test/libyul/objectCompiler/datacopy.yul +++ b/test/libyul/objectCompiler/datacopy.yul @@ -13,6 +13,7 @@ object "a" { } // ==== // EVMVersion: >=shanghai +// bytecodeFormat: legacy // ---- // Assembly: // /* "source":77:92 */ diff --git a/test/libyul/objectCompiler/dataoffset_code.yul b/test/libyul/objectCompiler/dataoffset_code.yul index 1171303af291..2a1aa04a14dd 100644 --- a/test/libyul/objectCompiler/dataoffset_code.yul +++ b/test/libyul/objectCompiler/dataoffset_code.yul @@ -7,6 +7,7 @@ object "a" { } // ==== // EVMVersion: >=shanghai +// bytecodeFormat: legacy // ---- // Assembly: // /* "source":44:61 */ diff --git a/test/libyul/objectCompiler/dataoffset_data.yul b/test/libyul/objectCompiler/dataoffset_data.yul index 381cb999f0ed..9490986819e0 100644 --- a/test/libyul/objectCompiler/dataoffset_data.yul +++ b/test/libyul/objectCompiler/dataoffset_data.yul @@ -4,6 +4,7 @@ object "a" { } // ==== // EVMVersion: >=shanghai +// bytecodeFormat: legacy // ---- // Assembly: // /* "source":56:75 */ diff --git a/test/libyul/objectCompiler/dataoffset_self.yul b/test/libyul/objectCompiler/dataoffset_self.yul index b6a0552cb7b1..9f82f5568023 100644 --- a/test/libyul/objectCompiler/dataoffset_self.yul +++ b/test/libyul/objectCompiler/dataoffset_self.yul @@ -4,6 +4,7 @@ object "a" { } // ==== // EVMVersion: >=shanghai +// bytecodeFormat: legacy // ---- // Assembly: // /* "source":44:59 */ diff --git a/test/libyul/objectCompiler/datasize_code.yul b/test/libyul/objectCompiler/datasize_code.yul index 7bf365031b5b..db2fee4d8392 100644 --- a/test/libyul/objectCompiler/datasize_code.yul +++ b/test/libyul/objectCompiler/datasize_code.yul @@ -7,6 +7,7 @@ object "a" { } // ==== // EVMVersion: >=shanghai +// bytecodeFormat: legacy // ---- // Assembly: // /* "source":44:59 */ diff --git a/test/libyul/objectCompiler/datasize_data.yul b/test/libyul/objectCompiler/datasize_data.yul index f0ae32b1b661..52afde6fcad0 100644 --- a/test/libyul/objectCompiler/datasize_data.yul +++ b/test/libyul/objectCompiler/datasize_data.yul @@ -4,6 +4,7 @@ object "a" { } // ==== // EVMVersion: >=shanghai +// bytecodeFormat: legacy // ---- // Assembly: // /* "source":44:61 */ diff --git a/test/libyul/objectCompiler/datasize_self.yul b/test/libyul/objectCompiler/datasize_self.yul index fb5b7fb89489..93512f1da5ac 100644 --- a/test/libyul/objectCompiler/datasize_self.yul +++ b/test/libyul/objectCompiler/datasize_self.yul @@ -4,6 +4,7 @@ object "a" { } // ==== // EVMVersion: >=shanghai +// bytecodeFormat: legacy // ---- // Assembly: // /* "source":36:49 */ diff --git a/test/libyul/objectCompiler/eof/leading_and_trailing_dots.yul b/test/libyul/objectCompiler/eof/leading_and_trailing_dots.yul new file mode 100644 index 000000000000..f62e24233db1 --- /dev/null +++ b/test/libyul/objectCompiler/eof/leading_and_trailing_dots.yul @@ -0,0 +1,30 @@ +{ + function e(_._) { + e(0) + } + e(2) + function f(n._) { + f(0) + } + f(2) + function g(_.n) { + g(0) + } + g(2) +} +// ==== +// bytecodeFormat: >=EOFv1 +// outputs: Assembly +// ---- +// Assembly: +// /* "source":53:54 */ +// 0x02 +// /* "source":51:55 */ +// jumpf{code_section_1} +// +// code_section_1: assembly { +// /* "source":136:137 */ +// 0x00 +// /* "source":134:138 */ +// jumpf{code_section_1} +// } diff --git a/test/libyul/objectCompiler/eof/long_object_name.yul b/test/libyul/objectCompiler/eof/long_object_name.yul new file mode 100644 index 000000000000..680a268885d9 --- /dev/null +++ b/test/libyul/objectCompiler/eof/long_object_name.yul @@ -0,0 +1,33 @@ +object "t" { + code { + sstore(0, eofcreate("name_that_is_longer_than_32_bytes_name_that_is_longer_than_32_bytes_name_that_is_longer_than_32_bytes", 0, 0, 0, 0)) + } + object "name_that_is_longer_than_32_bytes_name_that_is_longer_than_32_bytes_name_that_is_longer_than_32_bytes" { + code {} + } +} +// ==== +// bytecodeFormat: >=EOFv1 +// optimizationPreset: full +// outputs: Assembly +// ---- +// Assembly: +// /* "source":180:181 */ +// 0x00 +// /* "source":56:182 */ +// dup1 +// dup1 +// dup1 +// eofcreate{0} +// /* "source":53:54 */ +// 0x00 +// /* "source":46:183 */ +// sstore +// /* "source":22:199 */ +// stop +// stop +// +// sub_0: assembly { +// /* "source":330:337 */ +// stop +// } diff --git a/test/libyul/objectCompiler/eof/simple.yul b/test/libyul/objectCompiler/eof/simple.yul new file mode 100644 index 000000000000..cfb95fbecfb1 --- /dev/null +++ b/test/libyul/objectCompiler/eof/simple.yul @@ -0,0 +1,19 @@ +{ + sstore(0, 1) +} +// ==== +// EVMVersion: >=shanghai +// bytecodeFormat: >=EOFv1 +// ---- +// Assembly: +// /* "source":41:42 */ +// 0x01 +// /* "source":38:39 */ +// 0x00 +// /* "source":31:43 */ +// sstore +// /* "source":27:47 */ +// stop +// Bytecode: ef00010100040200010005040000000080000260015f5500 +// Opcodes: 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP SDIV DIV STOP STOP STOP STOP DUP1 STOP MUL PUSH1 0x1 PUSH0 SSTORE STOP +// SourceMappings: 41:1:0:-:0;38;31:12;27:20 diff --git a/test/libyul/objectCompiler/eof/smoke.yul b/test/libyul/objectCompiler/eof/smoke.yul new file mode 100644 index 000000000000..eecfac9a8741 --- /dev/null +++ b/test/libyul/objectCompiler/eof/smoke.yul @@ -0,0 +1,12 @@ +{ +} +// ==== +// EVMVersion: >=constantinople +// bytecodeFormat: >=EOFv1 +// ---- +// Assembly: +// /* "source":27:34 */ +// stop +// Bytecode: ef00010100040200010001040000000080000000 +// Opcodes: 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP +// SourceMappings: 27:7:0:-:0 diff --git a/test/libyul/objectCompiler/eof/subObject.yul b/test/libyul/objectCompiler/eof/subObject.yul new file mode 100644 index 000000000000..2f1771d79008 --- /dev/null +++ b/test/libyul/objectCompiler/eof/subObject.yul @@ -0,0 +1,29 @@ +object "a" { + code {} + // Unreferenced data is not added to the assembled bytecode. + // TODO: This is not implemented for EOF. Uncomment line below when implemented. + // data "str" "Hello, World!" + // Unreferenced object is not added to the assembled bytecode. + object "sub" { code { sstore(0, 1) } } +} +// ==== +// bytecodeFormat: >=EOFv1 +// ---- +// Assembly: +// /* "source":22:29 */ +// stop +// stop +// +// sub_0: assembly { +// /* "source":76:77 */ +// 0x01 +// /* "source":73:74 */ +// 0x00 +// /* "source":66:78 */ +// sstore +// /* "source":62:82 */ +// stop +// } +// Bytecode: ef00010100040200010001040000000080000000 +// Opcodes: 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP +// SourceMappings: 22:7:0:-:0 diff --git a/test/libyul/objectCompiler/eof/subSubObject.yul b/test/libyul/objectCompiler/eof/subSubObject.yul new file mode 100644 index 000000000000..39dd209bfd90 --- /dev/null +++ b/test/libyul/objectCompiler/eof/subSubObject.yul @@ -0,0 +1,49 @@ +object "a" { + code {} + // Unreferenced data is not added to the assembled bytecode. + // TODO: This is not implemented for EOF. Uncomment line below when implemented. + // data "str" "Hello, World!" + // Unreferenced object is not added to the assembled bytecode. + object "sub" { + code { sstore(0, 1) } + object "subsub" { + code { sstore(2, 3) } + data "str" hex"123456" + } + } +} +// ==== +// bytecodeFormat: >=EOFv1 +// ---- +// Assembly: +// /* "source":22:29 */ +// stop +// stop +// +// sub_0: assembly { +// /* "source":76:77 */ +// 0x01 +// /* "source":73:74 */ +// 0x00 +// /* "source":66:78 */ +// sstore +// /* "source":62:82 */ +// stop +// stop +// +// sub_0: assembly { +// /* "source":140:141 */ +// 0x03 +// /* "source":137:138 */ +// 0x02 +// /* "source":130:142 */ +// sstore +// /* "source":126:146 */ +// stop +// stop +// data_6adf031833174bbe4c85eafe59ddb54e6584648c2c962c6f94791ab49caa0ad4 123456 +// } +// } +// Bytecode: ef00010100040200010001040000000080000000 +// Opcodes: 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP +// SourceMappings: 22:7:0:-:0 diff --git a/test/libyul/objectCompiler/eof/verbatim_bug.yul b/test/libyul/objectCompiler/eof/verbatim_bug.yul new file mode 100644 index 000000000000..704702a53519 --- /dev/null +++ b/test/libyul/objectCompiler/eof/verbatim_bug.yul @@ -0,0 +1,118 @@ +object "a" { + code { + let dummy := 0xAABBCCDDEEFF + let input := sload(0) + let output + + switch input + case 0x00 { + // Note that due to a bug the following disappeared from the assembly output. + output := verbatim_1i_1o(hex"506000", dummy) + } + case 0x01 { + output := 1 + } + case 0x02 { + output := verbatim_1i_1o(hex"506002", dummy) + } + case 0x03 { + output := 3 + } + + sstore(0, output) + } +} +// ==== +// EVMVersion: >=shanghai +// bytecodeFormat: >=EOFv1 +// optimizationPreset: full +// outputs: Assembly +// ---- +// Assembly: +// /* "source":65:66 */ +// 0x00 +// /* "source":59:67 */ +// sload +// /* "source":94:95 */ +// 0x00 +// /* "source":108:406 */ +// swap1 +// /* "source":133:225 */ +// dup1 +// /* "source":138:142 */ +// 0x00 +// /* "source":133:225 */ +// eq +// rjumpi{tag_1} +// /* "source":108:406 */ +// tag_2: +// /* "source":238:263 */ +// dup1 +// /* "source":243:247 */ +// 0x01 +// /* "source":238:263 */ +// eq +// rjumpi{tag_3} +// /* "source":108:406 */ +// tag_4: +// /* "source":276:368 */ +// dup1 +// /* "source":281:285 */ +// 0x02 +// /* "source":276:368 */ +// eq +// rjumpi{tag_5} +// /* "source":108:406 */ +// tag_6: +// /* "source":386:390 */ +// 0x03 +// /* "source":381:406 */ +// eq +// rjumpi{tag_7} +// /* "source":108:406 */ +// tag_8: +// /* "source":426:427 */ +// 0x00 +// /* "source":419:436 */ +// sstore +// /* "source":108:406 */ +// stop +// /* "source":391:406 */ +// tag_7: +// /* "source":393:404 */ +// pop +// /* "source":403:404 */ +// 0x03 +// /* "source":391:406 */ +// rjump{tag_8} +// /* "source":286:368 */ +// tag_5: +// /* "source":314:354 */ +// pop +// pop +// /* "source":339:353 */ +// 0xaabbccddeeff +// /* "source":314:354 */ +// verbatimbytecode_506002 +// /* "source":286:368 */ +// rjump{tag_8} +// /* "source":248:263 */ +// tag_3: +// /* "source":250:261 */ +// pop +// pop +// /* "source":260:261 */ +// 0x01 +// /* "source":248:263 */ +// rjump{tag_8} +// /* "source":143:225 */ +// tag_1: +// /* "source":171:211 */ +// pop +// pop +// /* "source":196:210 */ +// 0xaabbccddeeff +// /* "source":171:211 */ +// verbatimbytecode_506000 +// /* "source":143:225 */ +// rjump{tag_8} diff --git a/test/libyul/objectCompiler/function_series.yul b/test/libyul/objectCompiler/function_series.yul index 8750f164991a..fd5a5d6c05f6 100644 --- a/test/libyul/objectCompiler/function_series.yul +++ b/test/libyul/objectCompiler/function_series.yul @@ -13,6 +13,7 @@ object "Contract" { // ==== // EVMVersion: >=shanghai // optimizationPreset: none +// bytecodeFormat: legacy // ---- // Assembly: // /* "source":33:48 */ diff --git a/test/libyul/objectCompiler/identical_subobjects_creation_deployed.yul b/test/libyul/objectCompiler/identical_subobjects_creation_deployed.yul index 01270ef44316..4a29c1498d0e 100644 --- a/test/libyul/objectCompiler/identical_subobjects_creation_deployed.yul +++ b/test/libyul/objectCompiler/identical_subobjects_creation_deployed.yul @@ -66,6 +66,7 @@ object "A" { // ==== // EVMVersion: >=constantinople // optimizationPreset: full +// outputs: Assembly // ---- // Assembly: // sstore(calldataload(sub(shl(0xff, 0x01), shl(0x7f, 0x01))), calldataload(0x01)) @@ -103,6 +104,3 @@ object "A" { // sstore(calldataload(sub(shl(0xff, 0x01), shl(0x7f, 0x01))), calldataload(0x01)) // stop // } -// Bytecode: 6001356001607f1b600160ff1b03355500fe -// Opcodes: PUSH1 0x1 CALLDATALOAD PUSH1 0x1 PUSH1 0x7F SHL PUSH1 0x1 PUSH1 0xFF SHL SUB CALLDATALOAD SSTORE STOP INVALID -// SourceMappings: :::-:0;;;;;;;;;;; diff --git a/test/libyul/objectCompiler/identical_subobjects_full_debug_info.yul b/test/libyul/objectCompiler/identical_subobjects_full_debug_info.yul index 88ec2c3542c7..9bd6413c9d3b 100644 --- a/test/libyul/objectCompiler/identical_subobjects_full_debug_info.yul +++ b/test/libyul/objectCompiler/identical_subobjects_full_debug_info.yul @@ -66,6 +66,7 @@ object "A" { // ==== // EVMVersion: >=shanghai // optimizationPreset: full +// outputs: Assembly // ---- // Assembly: // /* "A.sol":10:20 */ @@ -110,6 +111,3 @@ object "A" { // sstore(calldataload(0x00), calldataload(0x01)) // stop // } -// Bytecode: 6001355f355500fe -// Opcodes: PUSH1 0x1 CALLDATALOAD PUSH0 CALLDATALOAD SSTORE STOP INVALID -// SourceMappings: 10:10::-:0;-1:-1;10:10;-1:-1;10:10;-1:-1 diff --git a/test/libyul/objectCompiler/identical_subobjects_no_debug_info.yul b/test/libyul/objectCompiler/identical_subobjects_no_debug_info.yul index 309d995469a9..0248d61f7bc4 100644 --- a/test/libyul/objectCompiler/identical_subobjects_no_debug_info.yul +++ b/test/libyul/objectCompiler/identical_subobjects_no_debug_info.yul @@ -52,6 +52,7 @@ object "A" { // ==== // EVMVersion: >=shanghai // optimizationPreset: full +// outputs: Assembly // ---- // Assembly: // /* "source":83:84 */ @@ -159,6 +160,3 @@ object "A" { // /* "source":938:1034 */ // stop // } -// Bytecode: 6001355f355500fe -// Opcodes: PUSH1 0x1 CALLDATALOAD PUSH0 CALLDATALOAD SSTORE STOP INVALID -// SourceMappings: 83:1:0:-:0;70:15;66:1;53:15;46:40;22:80 diff --git a/test/libyul/objectCompiler/identical_subobjects_partial_debug_info.yul b/test/libyul/objectCompiler/identical_subobjects_partial_debug_info.yul index 82c2fd766e2c..10fcc202ea78 100644 --- a/test/libyul/objectCompiler/identical_subobjects_partial_debug_info.yul +++ b/test/libyul/objectCompiler/identical_subobjects_partial_debug_info.yul @@ -71,6 +71,7 @@ object "A" { // ==== // EVMVersion: >=shanghai // optimizationPreset: full +// outputs: Assembly // ---- // Assembly: // /* "A.sol":10:20 */ @@ -147,6 +148,3 @@ object "A" { // /* "source":1674:1770 */ // stop // } -// Bytecode: 6001355f355500fe -// Opcodes: PUSH1 0x1 CALLDATALOAD PUSH0 CALLDATALOAD SSTORE STOP INVALID -// SourceMappings: 10:10::-:0;-1:-1;10:10;-1:-1;10:10;-1:-1 diff --git a/test/libyul/objectCompiler/identical_subobjects_partial_debug_info_no_use_src.yul b/test/libyul/objectCompiler/identical_subobjects_partial_debug_info_no_use_src.yul index 230535525007..533abbdd87c0 100644 --- a/test/libyul/objectCompiler/identical_subobjects_partial_debug_info_no_use_src.yul +++ b/test/libyul/objectCompiler/identical_subobjects_partial_debug_info_no_use_src.yul @@ -58,6 +58,7 @@ object "A" { // ==== // EVMVersion: >=shanghai // optimizationPreset: full +// outputs: Assembly // ---- // Assembly: // /* "source":83:84 */ @@ -165,6 +166,3 @@ object "A" { // /* "source":938:1034 */ // stop // } -// Bytecode: 6001355f355500fe -// Opcodes: PUSH1 0x1 CALLDATALOAD PUSH0 CALLDATALOAD SSTORE STOP INVALID -// SourceMappings: 83:1:0:-:0;70:15;66:1;53:15;46:40;22:80 diff --git a/test/libyul/objectCompiler/identical_subobjects_with_subject_references.yul b/test/libyul/objectCompiler/identical_subobjects_with_subject_references.yul index 74f613cdfffa..c1bd855ad52b 100644 --- a/test/libyul/objectCompiler/identical_subobjects_with_subject_references.yul +++ b/test/libyul/objectCompiler/identical_subobjects_with_subject_references.yul @@ -96,7 +96,9 @@ object "A" { } // ==== // EVMVersion: >=shanghai +// bytecodeFormat: legacy // optimizationPreset: full +// outputs: Assembly // ---- // Assembly: // sstore(calldataload(0x00), calldataload(dataOffset(sub_0))) @@ -162,6 +164,3 @@ object "A" { // stop // data_257dd53638d790f0311f866044a2856def338f9a4d22fce0bdeed5b2d53851a9 307862626262 // } -// Bytecode: 6008355f355500fe6008355f355500fe6008355f355500fe6008355f355500fe6008355f355500fe30786262 -// Opcodes: PUSH1 0x8 CALLDATALOAD PUSH0 CALLDATALOAD SSTORE STOP INVALID PUSH1 0x8 CALLDATALOAD PUSH0 CALLDATALOAD SSTORE STOP INVALID PUSH1 0x8 CALLDATALOAD PUSH0 CALLDATALOAD SSTORE STOP INVALID PUSH1 0x8 CALLDATALOAD PUSH0 CALLDATALOAD SSTORE STOP INVALID PUSH1 0x8 CALLDATALOAD PUSH0 CALLDATALOAD SSTORE STOP INVALID ADDRESS PUSH25 0x62620000000000000000000000000000000000000000000000 -// SourceMappings: :::-:0;;;;; diff --git a/test/libyul/objectCompiler/immutable_long_name_does_not_end_up_in_bytecode.yul b/test/libyul/objectCompiler/immutable_long_name_does_not_end_up_in_bytecode.yul index 18d31087f9c5..e77506c30fbd 100644 --- a/test/libyul/objectCompiler/immutable_long_name_does_not_end_up_in_bytecode.yul +++ b/test/libyul/objectCompiler/immutable_long_name_does_not_end_up_in_bytecode.yul @@ -9,6 +9,7 @@ object "a" { } // ==== // EVMVersion: >=shanghai +// bytecodeFormat: legacy // ---- // Assembly: // /* "source":143:185 */ diff --git a/test/libyul/objectCompiler/jump_tags.yul b/test/libyul/objectCompiler/jump_tags.yul index 0d1f1ff791ab..9261c7765653 100644 --- a/test/libyul/objectCompiler/jump_tags.yul +++ b/test/libyul/objectCompiler/jump_tags.yul @@ -12,6 +12,7 @@ object "Contract" { // ==== // optimizationPreset: none +// bytecodeFormat: legacy // ---- // Assembly: // /* "source":33:54 */ diff --git a/test/libyul/objectCompiler/leading_and_trailing_dots.yul b/test/libyul/objectCompiler/leading_and_trailing_dots.yul index ddacd8b45dde..08dd970211ba 100644 --- a/test/libyul/objectCompiler/leading_and_trailing_dots.yul +++ b/test/libyul/objectCompiler/leading_and_trailing_dots.yul @@ -14,6 +14,8 @@ } // ==== // EVMVersion: >=shanghai +// bytecodeFormat: legacy +// outputs: Assembly // ---- // Assembly: // /* "source":53:54 */ @@ -25,6 +27,3 @@ // /* "source":134:138 */ // tag_1 // jump // in -// Bytecode: 60025b5f600256 -// Opcodes: PUSH1 0x2 JUMPDEST PUSH0 PUSH1 0x2 JUMP -// SourceMappings: 53:1:0:-:0;108:32;136:1;134:4;:::i diff --git a/test/libyul/objectCompiler/linkersymbol.yul b/test/libyul/objectCompiler/linkersymbol.yul index ba0319108b27..cab45afa745f 100644 --- a/test/libyul/objectCompiler/linkersymbol.yul +++ b/test/libyul/objectCompiler/linkersymbol.yul @@ -2,22 +2,15 @@ object "a" { code { let addr := linkersymbol("contract/test.sol:L") mstore(128, shl(227, 0x18530aaf)) - let success := call(gas(), addr, 0, 128, 4, 128, 0) + sstore(0, balance(addr)) } } // ==== // EVMVersion: >=shanghai +// outputs: Assembly // ---- // Assembly: -// /* "source":190:191 */ -// 0x00 -// /* "source":185:188 */ -// 0x80 -// /* "source":182:183 */ -// 0x04 // /* "source":58:93 */ -// dup2 -// dup4 // linkerSymbol("f919ba91ac99f96129544b80b9516b27a80e376b9dc693819d0b18b7e0395612") // /* "source":127:137 */ // 0x18530aaf @@ -25,15 +18,15 @@ object "a" { // 0xe3 // /* "source":118:138 */ // shl +// /* "source":113:116 */ +// 0x80 // /* "source":106:139 */ -// dup4 // mstore -// /* "source":161:166 */ -// gas -// /* "source":156:192 */ -// call -// /* "source":152:193 */ +// /* "source":162:175 */ +// balance +// /* "source":159:160 */ +// 0x00 +// /* "source":152:176 */ +// sstore +// /* "source":22:192 */ // stop -// Bytecode: 5f6080600481837300000000000000000000000000000000000000006318530aaf60e31b83525af100 -// Opcodes: PUSH0 PUSH1 0x80 PUSH1 0x4 DUP2 DUP4 PUSH20 0x0 PUSH4 0x18530AAF PUSH1 0xE3 SHL DUP4 MSTORE GAS CALL STOP -// SourceMappings: 190:1:0:-:0;185:3;182:1;58:35;;;127:10;122:3;118:20;106:33;;161:5;156:36;152:41 diff --git a/test/libyul/objectCompiler/long_object_name.yul b/test/libyul/objectCompiler/long_object_name.yul index 805beb42495d..a1f1c7a63aea 100644 --- a/test/libyul/objectCompiler/long_object_name.yul +++ b/test/libyul/objectCompiler/long_object_name.yul @@ -9,6 +9,8 @@ object "t" { // ==== // EVMVersion: >=shanghai // optimizationPreset: full +// outputs: Assembly +// bytecodeFormat: legacy // ---- // Assembly: // /* "source":56:169 */ @@ -25,6 +27,3 @@ object "t" { // /* "source":317:324 */ // stop // } -// Bytecode: 60015f5500fe -// Opcodes: PUSH1 0x1 PUSH0 SSTORE STOP INVALID -// SourceMappings: 56:113:0:-:0;53:1;46:124;22:164 diff --git a/test/libyul/objectCompiler/manySubObjects.yul b/test/libyul/objectCompiler/manySubObjects.yul index 1a087f9c9430..c4879f2107ad 100644 --- a/test/libyul/objectCompiler/manySubObjects.yul +++ b/test/libyul/objectCompiler/manySubObjects.yul @@ -136,6 +136,8 @@ object "root" { } // ==== // EVMVersion: >=shanghai +// outputs: Assembly +// bytecodeFormat: legacy // ---- // Assembly: // /* "source":59:75 */ @@ -472,6 +474,3 @@ object "root" { // stop // } // } -// Bytecode: 61005c5f55600b600155600660025560066003556006600455600660055560066006556006600755600660085560066009556006600a556006600b556006600c556006600d556006600e556006600f556006601055600c60115500fe -// Opcodes: PUSH2 0x5C PUSH0 SSTORE PUSH1 0xB PUSH1 0x1 SSTORE PUSH1 0x6 PUSH1 0x2 SSTORE PUSH1 0x6 PUSH1 0x3 SSTORE PUSH1 0x6 PUSH1 0x4 SSTORE PUSH1 0x6 PUSH1 0x5 SSTORE PUSH1 0x6 PUSH1 0x6 SSTORE PUSH1 0x6 PUSH1 0x7 SSTORE PUSH1 0x6 PUSH1 0x8 SSTORE PUSH1 0x6 PUSH1 0x9 SSTORE PUSH1 0x6 PUSH1 0xA SSTORE PUSH1 0x6 PUSH1 0xB SSTORE PUSH1 0x6 PUSH1 0xC SSTORE PUSH1 0x6 PUSH1 0xD SSTORE PUSH1 0x6 PUSH1 0xE SSTORE PUSH1 0x6 PUSH1 0xF SSTORE PUSH1 0x6 PUSH1 0x10 SSTORE PUSH1 0xC PUSH1 0x11 SSTORE STOP INVALID -// SourceMappings: 59:16:0:-:0;56:1;49:27;99:13;96:1;89:24;136:13;133:1;126:24;173:13;170:1;163:24;210:13;207:1;200:24;247:13;244:1;237:24;284:13;281:1;274:24;321:13;318:1;311:24;358:13;355:1;348:24;395:13;392:1;385:24;433:13;429:2;422:25;471:13;467:2;460:25;509:13;505:2;498:25;547:13;543:2;536:25;585:13;581:2;574:25;623:13;619:2;612:25;661:13;657:2;650:25;699:14;695:2;688:26;25:705 diff --git a/test/libyul/objectCompiler/metadata.yul b/test/libyul/objectCompiler/metadata.yul index dbd802e3384d..3787710e644c 100644 --- a/test/libyul/objectCompiler/metadata.yul +++ b/test/libyul/objectCompiler/metadata.yul @@ -21,6 +21,7 @@ object "A" { } // ==== // EVMVersion: >=shanghai +// bytecodeFormat: legacy // ---- // Assembly: // /* "source":55:68 */ diff --git a/test/libyul/objectCompiler/namedObject.yul b/test/libyul/objectCompiler/namedObject.yul index 66727585dbcb..d236f9ba0efd 100644 --- a/test/libyul/objectCompiler/namedObject.yul +++ b/test/libyul/objectCompiler/namedObject.yul @@ -3,10 +3,8 @@ object "a" { } // ==== // EVMVersion: >=constantinople +// outputs: Assembly // ---- // Assembly: // /* "source":22:29 */ // stop -// Bytecode: 00 -// Opcodes: STOP -// SourceMappings: 22:7:0:-:0 diff --git a/test/libyul/objectCompiler/namedObjectCode.yul b/test/libyul/objectCompiler/namedObjectCode.yul index efb41524b5cc..e5d16be3e442 100644 --- a/test/libyul/objectCompiler/namedObjectCode.yul +++ b/test/libyul/objectCompiler/namedObjectCode.yul @@ -3,6 +3,7 @@ object "a" { } // ==== // EVMVersion: >=shanghai +// outputs: Assembly // ---- // Assembly: // /* "source":36:37 */ @@ -13,6 +14,3 @@ object "a" { // sstore // /* "source":22:42 */ // stop -// Bytecode: 60015f5500 -// Opcodes: PUSH1 0x1 PUSH0 SSTORE STOP -// SourceMappings: 36:1:0:-:0;33;26:12;22:20 diff --git a/test/libyul/objectCompiler/nested_optimizer.yul b/test/libyul/objectCompiler/nested_optimizer.yul index 0275e1665ae5..38b78e6dcae6 100644 --- a/test/libyul/objectCompiler/nested_optimizer.yul +++ b/test/libyul/objectCompiler/nested_optimizer.yul @@ -17,6 +17,7 @@ object "a" { // ==== // EVMVersion: >=shanghai // optimizationPreset: full +// outputs: Assembly // ---- // Assembly: // /* "source":58:59 */ @@ -41,6 +42,3 @@ object "a" { // /* "source":101:155 */ // stop // } -// Bytecode: 5f80355500fe -// Opcodes: PUSH0 DUP1 CALLDATALOAD SSTORE STOP INVALID -// SourceMappings: 58:1:0:-:0;41:15;;34:26;22:46 diff --git a/test/libyul/objectCompiler/simple.yul b/test/libyul/objectCompiler/simple.yul index f7f945abf58a..3af2c0f6a05d 100644 --- a/test/libyul/objectCompiler/simple.yul +++ b/test/libyul/objectCompiler/simple.yul @@ -3,6 +3,7 @@ } // ==== // EVMVersion: >=shanghai +// bytecodeFormat: legacy // ---- // Assembly: // /* "source":41:42 */ diff --git a/test/libyul/objectCompiler/simple_optimizer.yul b/test/libyul/objectCompiler/simple_optimizer.yul index 7348b2e20cd4..db386a1f1318 100644 --- a/test/libyul/objectCompiler/simple_optimizer.yul +++ b/test/libyul/objectCompiler/simple_optimizer.yul @@ -7,6 +7,7 @@ // ==== // EVMVersion: >=shanghai // optimizationPreset: full +// outputs: Assembly // ---- // Assembly: // /* "source":63:64 */ @@ -18,6 +19,3 @@ // sstore // /* "source":27:73 */ // stop -// Bytecode: 5f80355500 -// Opcodes: PUSH0 DUP1 CALLDATALOAD SSTORE STOP -// SourceMappings: 63:1:0:-:0;46:15;;39:26;27:46 diff --git a/test/libyul/objectCompiler/smoke.yul b/test/libyul/objectCompiler/smoke.yul index 2ca3d62f004a..06736baa8710 100644 --- a/test/libyul/objectCompiler/smoke.yul +++ b/test/libyul/objectCompiler/smoke.yul @@ -2,6 +2,7 @@ } // ==== // EVMVersion: >=constantinople +// bytecodeFormat: legacy // ---- // Assembly: // /* "source":27:34 */ diff --git a/test/libyul/objectCompiler/sourceLocations.yul b/test/libyul/objectCompiler/sourceLocations.yul index a1e55ade4ae1..756260259b2c 100644 --- a/test/libyul/objectCompiler/sourceLocations.yul +++ b/test/libyul/objectCompiler/sourceLocations.yul @@ -30,6 +30,7 @@ object "a" { } // ==== // EVMVersion: >=shanghai +// bytecodeFormat: legacy // ---- // Assembly: // /* "abc.sol":0:2 */ diff --git a/test/libyul/objectCompiler/subObject.yul b/test/libyul/objectCompiler/subObject.yul index f394054d74f0..c10cbaac1407 100644 --- a/test/libyul/objectCompiler/subObject.yul +++ b/test/libyul/objectCompiler/subObject.yul @@ -6,6 +6,7 @@ object "a" { } // ==== // EVMVersion: >=constantinople +// bytecodeFormat: legacy // ---- // Assembly: // /* "source":22:29 */ diff --git a/test/libyul/objectCompiler/subObjectAccess.yul b/test/libyul/objectCompiler/subObjectAccess.yul index 047eae408730..1ef30838f9a8 100644 --- a/test/libyul/objectCompiler/subObjectAccess.yul +++ b/test/libyul/objectCompiler/subObjectAccess.yul @@ -67,6 +67,7 @@ object "A" { } // ==== // EVMVersion: >=shanghai +// bytecodeFormat: legacy // ---- // Assembly: // /* "source":57:72 */ diff --git a/test/libyul/objectCompiler/subSubObject.yul b/test/libyul/objectCompiler/subSubObject.yul index a7274ce639db..2aa89592be5a 100644 --- a/test/libyul/objectCompiler/subSubObject.yul +++ b/test/libyul/objectCompiler/subSubObject.yul @@ -12,6 +12,7 @@ object "a" { } // ==== // EVMVersion: >=constantinople +// bytecodeFormat: legacy // ---- // Assembly: // /* "source":22:29 */ diff --git a/test/libyul/objectCompiler/verbatim_bug.yul b/test/libyul/objectCompiler/verbatim_bug.yul index 3858b5984dba..892ec13fae32 100644 --- a/test/libyul/objectCompiler/verbatim_bug.yul +++ b/test/libyul/objectCompiler/verbatim_bug.yul @@ -24,7 +24,9 @@ object "a" { } // ==== // EVMVersion: >=shanghai +// bytecodeFormat: legacy // optimizationPreset: full +// outputs: Assembly // ---- // Assembly: // /* "source":65:66 */ @@ -120,6 +122,3 @@ object "a" { // sstore // /* "source":108:406 */ // stop -// Bytecode: 5f80548015603e578060011460365780600214602657600314601f575f55005b5060035f55005b505065aabbccddeeff5060025f55005b505060015f55005b505065aabbccddeeff5060005f5500 -// Opcodes: PUSH0 DUP1 SLOAD DUP1 ISZERO PUSH1 0x3E JUMPI DUP1 PUSH1 0x1 EQ PUSH1 0x36 JUMPI DUP1 PUSH1 0x2 EQ PUSH1 0x26 JUMPI PUSH1 0x3 EQ PUSH1 0x1F JUMPI PUSH0 SSTORE STOP JUMPDEST POP PUSH1 0x3 PUSH0 SSTORE STOP JUMPDEST POP POP PUSH6 0xAABBCCDDEEFF POP PUSH1 0x2 PUSH0 SSTORE STOP JUMPDEST POP POP PUSH1 0x1 PUSH0 SSTORE STOP JUMPDEST POP POP PUSH6 0xAABBCCDDEEFF POP PUSH1 0x0 PUSH0 SSTORE STOP -// SourceMappings: 65:1:0:-:0;59:8;;133:92;;;;238:25;243:4;238:25;;;276:92;281:4;276:92;;;386:4;381:25;;;426:1;419:17;108:298;391:15;393:11;403:1;426;419:17;108:298;286:82;314:40;;339:14;314:40;426:1;419:17;108:298;248:15;250:11;;260:1;426;419:17;108:298;143:82;171:40;;196:14;171:40;426:1;419:17;108:298 From dbcc90d90e78fcd15d25fb3e17412f22a745296d Mon Sep 17 00:00:00 2001 From: irreduciblen <197363205+irreduciblen@users.noreply.github.com> Date: Sat, 1 Feb 2025 16:48:45 +0800 Subject: [PATCH 0772/1022] Fix libsolidity/ast/AST.h --- libsolidity/ast/AST.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libsolidity/ast/AST.h b/libsolidity/ast/AST.h index fa2ce20948c2..5cf4880075a2 100644 --- a/libsolidity/ast/AST.h +++ b/libsolidity/ast/AST.h @@ -2054,7 +2054,7 @@ class Assignment: public Expression ): Expression(_id, _location), m_leftHandSide(std::move(_leftHandSide)), - m_assigmentOperator(_assignmentOperator), + m_assignmentOperator(_assignmentOperator), m_rightHandSide(std::move(_rightHandSide)) { solAssert(TokenTraits::isAssignmentOp(_assignmentOperator), ""); @@ -2063,12 +2063,12 @@ class Assignment: public Expression void accept(ASTConstVisitor& _visitor) const override; Expression const& leftHandSide() const { return *m_leftHandSide; } - Token assignmentOperator() const { return m_assigmentOperator; } + Token assignmentOperator() const { return m_assignmentOperator; } Expression const& rightHandSide() const { return *m_rightHandSide; } private: ASTPointer m_leftHandSide; - Token m_assigmentOperator; + Token m_assignmentOperator; ASTPointer m_rightHandSide; }; From 0cab9c6374031773e8a35b079ad67b04183e898e Mon Sep 17 00:00:00 2001 From: imilygathia <197356964+imilygathia@users.noreply.github.com> Date: Sat, 1 Feb 2025 15:13:28 +0800 Subject: [PATCH 0773/1022] tests: fix test case's name --- test/yulPhaser/TestHelpersTest.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/yulPhaser/TestHelpersTest.cpp b/test/yulPhaser/TestHelpersTest.cpp index 08a12f9d2cab..d4f698561a34 100644 --- a/test/yulPhaser/TestHelpersTest.cpp +++ b/test/yulPhaser/TestHelpersTest.cpp @@ -96,7 +96,7 @@ BOOST_AUTO_TEST_CASE(countDifferences_should_count_missing_characters_as_differe BOOST_TEST(countDifferences(Chromosome("aa"), Chromosome("cccc")) == 4); } -BOOST_AUTO_TEST_CASE(enumerateOptimisationSteps_should_assing_indices_to_all_available_optimisation_steps) +BOOST_AUTO_TEST_CASE(enumerateOptimisationSteps_should_assign_indices_to_all_available_optimisation_steps) { std::map stepsAndAbbreviations = OptimiserSuite::stepNameToAbbreviationMap(); std::map stepsAndIndices = enumerateOptimisationSteps(); From 2d47ea8d914d5397b5bd15a30e9dc1170b337603 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Sat, 1 Feb 2025 19:08:01 +0100 Subject: [PATCH 0774/1022] Restrict the test for trailing input in precompiles to >= byzantium EVMs --- .../isoltestTesting/precompiles_ignoring_trailing_input.sol | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/libsolidity/semanticTests/isoltestTesting/precompiles_ignoring_trailing_input.sol b/test/libsolidity/semanticTests/isoltestTesting/precompiles_ignoring_trailing_input.sol index 920c6b06ef32..ef6abb9a9140 100644 --- a/test/libsolidity/semanticTests/isoltestTesting/precompiles_ignoring_trailing_input.sol +++ b/test/libsolidity/semanticTests/isoltestTesting/precompiles_ignoring_trailing_input.sol @@ -17,6 +17,8 @@ contract C { return encodedOutput; } } +// ==== +// EVMVersion: >=byzantium // ---- // ecRecover(uint256[4]): 0x18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c, 0x000000000000000000000000000000000000000000000000000000000000001c, 0x73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f, 0xeeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549 -> 0x20, 0x20, 966588469268559010541288244128342317224451555083 // ecRecover(uint256[4]): 0x18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c, 0x000000000000000000000000000000000000000000000000000000000000001c, 0x73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f, 0xeeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549, 0x01, 0x02, 0x03 -> 0x20, 0x20, 966588469268559010541288244128342317224451555083 From d7af663f70b718dc3ace0065f9973f1afcdf402f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Sat, 1 Feb 2025 19:08:35 +0100 Subject: [PATCH 0775/1022] Make tests for reserved Yul builtins compatible with EOF --- .../invalid/builtin_name_as_type.yul | 16 ++++++++-------- .../clash_with_reserved_pure_yul_builtin.yul | 2 ++ .../clash_with_reserved_pure_yul_builtin_eof.yul | 13 +++++++++++++ 3 files changed, 23 insertions(+), 8 deletions(-) create mode 100644 test/libyul/yulSyntaxTests/invalid/clash_with_reserved_pure_yul_builtin_eof.yul diff --git a/test/libyul/yulSyntaxTests/invalid/builtin_name_as_type.yul b/test/libyul/yulSyntaxTests/invalid/builtin_name_as_type.yul index b9b3346f48c2..2e4252af412d 100644 --- a/test/libyul/yulSyntaxTests/invalid/builtin_name_as_type.yul +++ b/test/libyul/yulSyntaxTests/invalid/builtin_name_as_type.yul @@ -1,13 +1,13 @@ { - let x: datacopy - x := true: loadimmutable + let x: memoryguard + x := true: linkersymbol function f(y: linkersymbol) {} } // ---- -// ParserError 5568: (13-21): Cannot use builtin function name "datacopy" as identifier name. -// ParserError 5473: (10-21): Types are not supported in untyped Yul. -// ParserError 5568: (37-50): Cannot use builtin function name "loadimmutable" as identifier name. -// ParserError 5473: (31-50): Types are not supported in untyped Yul. -// ParserError 5568: (70-82): Cannot use builtin function name "linkersymbol" as identifier name. -// ParserError 5473: (67-82): Types are not supported in untyped Yul. +// ParserError 5568: (13-24): Cannot use builtin function name "memoryguard" as identifier name. +// ParserError 5473: (10-24): Types are not supported in untyped Yul. +// ParserError 5568: (40-52): Cannot use builtin function name "linkersymbol" as identifier name. +// ParserError 5473: (34-52): Types are not supported in untyped Yul. +// ParserError 5568: (72-84): Cannot use builtin function name "linkersymbol" as identifier name. +// ParserError 5473: (69-84): Types are not supported in untyped Yul. diff --git a/test/libyul/yulSyntaxTests/invalid/clash_with_reserved_pure_yul_builtin.yul b/test/libyul/yulSyntaxTests/invalid/clash_with_reserved_pure_yul_builtin.yul index 035efbacc46a..66698c63377b 100644 --- a/test/libyul/yulSyntaxTests/invalid/clash_with_reserved_pure_yul_builtin.yul +++ b/test/libyul/yulSyntaxTests/invalid/clash_with_reserved_pure_yul_builtin.yul @@ -4,6 +4,8 @@ function loadimmutable(setimmutable) -> datasize {} let dataoffset } +// ==== +// bytecodeFormat: legacy // ---- // ParserError 5568: (158-171): Cannot use builtin function name "loadimmutable" as identifier name. // ParserError 5568: (172-184): Cannot use builtin function name "setimmutable" as identifier name. diff --git a/test/libyul/yulSyntaxTests/invalid/clash_with_reserved_pure_yul_builtin_eof.yul b/test/libyul/yulSyntaxTests/invalid/clash_with_reserved_pure_yul_builtin_eof.yul new file mode 100644 index 000000000000..0466cc9b62d8 --- /dev/null +++ b/test/libyul/yulSyntaxTests/invalid/clash_with_reserved_pure_yul_builtin_eof.yul @@ -0,0 +1,13 @@ +{ + // NOTE: These are builtins but only in pure Yul, not inline assembly. + // NOTE: Names of these builtins are also reserved identifiers. + function auxdataloadn(eofcreate) -> returncontract {} + let eofcreate +} +// ==== +// bytecodeFormat: >=EOFv1 +// ---- +// ParserError 5568: (158-170): Cannot use builtin function name "auxdataloadn" as identifier name. +// ParserError 5568: (171-180): Cannot use builtin function name "eofcreate" as identifier name. +// ParserError 5568: (185-199): Cannot use builtin function name "returncontract" as identifier name. +// ParserError 5568: (211-220): Cannot use builtin function name "eofcreate" as identifier name. From 7f9cf570727d27979aa14850cc2e5cdbfcd6f15f Mon Sep 17 00:00:00 2001 From: rodiazet Date: Mon, 3 Feb 2025 12:59:37 +0100 Subject: [PATCH 0776/1022] eof: Pass proper EOF flag to `Assembly` used by `EVMCodeTransformTest` --- test/libyul/EVMCodeTransformTest.cpp | 2 +- ...ction_argument_reuse_without_retparams.yul | 45 +++++++++++++++++++ ...ction_argument_reuse_without_retparams.yul | 1 + 3 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 test/libyul/evmCodeTransform/stackReuse/eof/function_argument_reuse_without_retparams.yul diff --git a/test/libyul/EVMCodeTransformTest.cpp b/test/libyul/EVMCodeTransformTest.cpp index 4fff5a22e70d..96699b109c52 100644 --- a/test/libyul/EVMCodeTransformTest.cpp +++ b/test/libyul/EVMCodeTransformTest.cpp @@ -67,7 +67,7 @@ TestCase::TestResult EVMCodeTransformTest::run(std::ostream& _stream, std::strin return TestResult::FatalError; } - evmasm::Assembly assembly{CommonOptions::get().evmVersion(), false, std::nullopt, {}}; + evmasm::Assembly assembly{CommonOptions::get().evmVersion(), false, CommonOptions::get().eofVersion(), {}}; EthAssemblyAdapter adapter(assembly); EVMObjectCompiler::compile( *yulStack.parserResult(), diff --git a/test/libyul/evmCodeTransform/stackReuse/eof/function_argument_reuse_without_retparams.yul b/test/libyul/evmCodeTransform/stackReuse/eof/function_argument_reuse_without_retparams.yul new file mode 100644 index 000000000000..77423e88c067 --- /dev/null +++ b/test/libyul/evmCodeTransform/stackReuse/eof/function_argument_reuse_without_retparams.yul @@ -0,0 +1,45 @@ +{ + function f(x, y) { + mstore(0x80, x) + if calldataload(0) { sstore(y, y) } + } + + f(0, 0) +} +// ==== +// bytecodeFormat: >=EOFv1 +// stackOptimization: true +// ---- +// /* "":95:96 */ +// 0x00 +// /* "":90:97 */ +// dup1 +// callf{code_section_1} +// /* "":0:99 */ +// stop +// +// code_section_1: assembly { +// /* "":34:38 */ +// 0x80 +// /* "":27:42 */ +// mstore +// /* "":63:64 */ +// 0x00 +// /* "":50:65 */ +// calldataload +// /* "":47:82 */ +// rjumpi{tag_1} +// /* "":21:86 */ +// tag_2: +// /* "":4:86 */ +// pop +// retf +// /* "":66:82 */ +// tag_1: +// /* "":68:80 */ +// dup1 +// sstore +// /* "":66:82 */ +// 0x00 +// rjump{tag_2} +// } 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 09ce0b84a2b2..c7a82c412f6f 100644 --- a/test/libyul/evmCodeTransform/stackReuse/function_argument_reuse_without_retparams.yul +++ b/test/libyul/evmCodeTransform/stackReuse/function_argument_reuse_without_retparams.yul @@ -8,6 +8,7 @@ } // ==== // EVMVersion: >=shanghai +// bytecodeFormat: legacy // stackOptimization: true // ---- // /* "":90:97 */ From 402031c4cf4b47ca329e7c1897361b48e337cb44 Mon Sep 17 00:00:00 2001 From: rodiazet Date: Fri, 13 Dec 2024 13:06:19 +0100 Subject: [PATCH 0777/1022] eof: Update `yulOptimizerTests` tests. --- .../branches_for.yul | 10 ++-- .../long_literals_as_builtin_args.yul | 2 + .../non_movable_instr2.yul | 2 + .../object_access.yul | 2 + .../commonSubexpressionEliminator/trivial.yul | 6 +- .../string_as_hex_and_hex_as_string.yul | 2 + .../equalStoreEliminator/branching.yul | 7 +-- .../equalStoreEliminator/functionbody.yul | 12 ++-- .../equalStoreEliminator/verbatim.yul | 4 +- .../constant_representation_datasize.yul | 2 + .../expressionSimplifier/create2_and_mask.yul | 1 + .../expressionSimplifier/create_and_mask.yul | 2 + .../large_byte_access.yul | 2 + .../pop_byte_shr_call.yul | 1 + .../side_effects_in_for_condition.yul | 1 + .../expressionSimplifier/zero_length_read.yul | 5 -- .../zero_length_read_call.yul | 15 +++++ .../zero_length_read_codecopy.yul | 13 +++++ .../expressionSplitter/object_access.yul | 2 + ...d_removes_non_constant_and_not_movable.yul | 2 + .../scoped_var_ref_in_function_call.yul | 2 + .../yulOptimizerTests/fullSuite/aztec.yul | 2 + .../fullSuite/create2_and_mask.yul | 1 + .../fullSuite/create_and_mask.yul | 1 + .../fullSuite/extcodelength.yul | 1 + .../fullSuite/stack_compressor_msize.yul | 4 +- .../unusedFunctionParameterPruner.yul | 4 +- .../unusedFunctionParameterPruner_return.yul | 2 + .../loadResolver/extstaticcall.yul | 29 ++++++++++ .../loadResolver/keccak_crash.yul | 2 + ....yul => memory_with_call_invalidation.yul} | 18 +----- .../memory_with_extcall_invalidation.yul | 22 ++++++++ ...memory_with_function_call_invalidation.yul | 17 ++++++ .../memory_with_mstore_invalidation.yul | 19 +++++++ .../loadResolver/staticcall.yul | 1 + .../loadResolver/zero_length_reads.yul | 1 + .../loadResolver/zero_length_reads_eof.yul | 39 +++++++++++++ .../loopInvariantCodeMotion/complex_move.yul | 4 +- .../loopInvariantCodeMotion/create_sload.yul | 2 + .../move_state_function.yul | 4 +- .../loopInvariantCodeMotion/no_move_gas.yul | 15 +++++ .../no_move_immovables.yul | 20 +++---- .../no_move_memory.yul | 4 +- .../no_move_memory_msize.yul | 4 +- .../loopInvariantCodeMotion/no_move_state.yul | 2 + .../no_move_state_function.yul | 4 +- .../no_move_state_loop.yul | 4 +- .../no_move_state_recursive_function.yul | 4 +- .../no_move_staticall_returndatasize.yul | 2 + .../no_move_storage.yul | 55 ++++--------------- .../no_move_storage_in_body.yul | 24 ++++++++ .../no_move_storage_in_post.yul | 24 ++++++++ .../loopInvariantCodeMotion/simple_state.yul | 4 +- .../rematerialiser/reassign.yul | 4 +- .../rematerialiser/update_asignment_remat.yul | 4 +- .../call_does_not_need_to_write.yul | 2 + .../unusedStoreEliminator/create.yul | 2 + .../create_inside_function.yul | 2 + 58 files changed, 325 insertions(+), 123 deletions(-) create mode 100644 test/libyul/yulOptimizerTests/expressionSimplifier/zero_length_read_call.yul create mode 100644 test/libyul/yulOptimizerTests/expressionSimplifier/zero_length_read_codecopy.yul create mode 100644 test/libyul/yulOptimizerTests/loadResolver/extstaticcall.yul rename test/libyul/yulOptimizerTests/loadResolver/{memory_with_different_kinds_of_invalidation.yul => memory_with_call_invalidation.yul} (54%) create mode 100644 test/libyul/yulOptimizerTests/loadResolver/memory_with_extcall_invalidation.yul create mode 100644 test/libyul/yulOptimizerTests/loadResolver/memory_with_function_call_invalidation.yul create mode 100644 test/libyul/yulOptimizerTests/loadResolver/memory_with_mstore_invalidation.yul create mode 100644 test/libyul/yulOptimizerTests/loadResolver/zero_length_reads_eof.yul create mode 100644 test/libyul/yulOptimizerTests/loopInvariantCodeMotion/no_move_gas.yul create mode 100644 test/libyul/yulOptimizerTests/loopInvariantCodeMotion/no_move_storage_in_body.yul create mode 100644 test/libyul/yulOptimizerTests/loopInvariantCodeMotion/no_move_storage_in_post.yul diff --git a/test/libyul/yulOptimizerTests/commonSubexpressionEliminator/branches_for.yul b/test/libyul/yulOptimizerTests/commonSubexpressionEliminator/branches_for.yul index ac4ed1b0545e..9c569811e795 100644 --- a/test/libyul/yulOptimizerTests/commonSubexpressionEliminator/branches_for.yul +++ b/test/libyul/yulOptimizerTests/commonSubexpressionEliminator/branches_for.yul @@ -1,17 +1,17 @@ { let a := 1 - let b := codesize() - for { } lt(1, codesize()) { mstore(1, codesize()) a := add(a, codesize()) } { - mstore(1, codesize()) + let b := calldataload(0) + for { } lt(1, calldataload(0)) { mstore(1, calldataload(0)) a := add(a, calldataload(0)) } { + mstore(1, calldataload(0)) } - mstore(1, codesize()) + mstore(1, calldataload(0)) } // ---- // step: commonSubexpressionEliminator // // { // let a := 1 -// let b := codesize() +// let b := calldataload(0) // for { } // lt(1, b) // { diff --git a/test/libyul/yulOptimizerTests/commonSubexpressionEliminator/long_literals_as_builtin_args.yul b/test/libyul/yulOptimizerTests/commonSubexpressionEliminator/long_literals_as_builtin_args.yul index f480bec9e1ae..e4ad176e846f 100644 --- a/test/libyul/yulOptimizerTests/commonSubexpressionEliminator/long_literals_as_builtin_args.yul +++ b/test/libyul/yulOptimizerTests/commonSubexpressionEliminator/long_literals_as_builtin_args.yul @@ -10,6 +10,8 @@ object "AccessControlDefaultAdminRules4233_14" { data "AccessControlDefaultAdminRules4233_14_deployed" "AccessControlDefaultAdminRules4233_14_deployed" } +// ==== +// bytecodeFormat: legacy // ---- // step: commonSubexpressionEliminator // diff --git a/test/libyul/yulOptimizerTests/commonSubexpressionEliminator/non_movable_instr2.yul b/test/libyul/yulOptimizerTests/commonSubexpressionEliminator/non_movable_instr2.yul index ed8916e63723..210b697f46a4 100644 --- a/test/libyul/yulOptimizerTests/commonSubexpressionEliminator/non_movable_instr2.yul +++ b/test/libyul/yulOptimizerTests/commonSubexpressionEliminator/non_movable_instr2.yul @@ -2,6 +2,8 @@ let a := gas() let b := gas() } +// ==== +// bytecodeFormat: legacy // ---- // step: commonSubexpressionEliminator // diff --git a/test/libyul/yulOptimizerTests/commonSubexpressionEliminator/object_access.yul b/test/libyul/yulOptimizerTests/commonSubexpressionEliminator/object_access.yul index c8c4e4e1388a..98645c653739 100644 --- a/test/libyul/yulOptimizerTests/commonSubexpressionEliminator/object_access.yul +++ b/test/libyul/yulOptimizerTests/commonSubexpressionEliminator/object_access.yul @@ -14,6 +14,8 @@ object "main" { } data "abc" "Hello, World!" } +// ==== +// bytecodeFormat: legacy // ---- // step: commonSubexpressionEliminator // diff --git a/test/libyul/yulOptimizerTests/commonSubexpressionEliminator/trivial.yul b/test/libyul/yulOptimizerTests/commonSubexpressionEliminator/trivial.yul index c64fc93f9833..ad0168027011 100644 --- a/test/libyul/yulOptimizerTests/commonSubexpressionEliminator/trivial.yul +++ b/test/libyul/yulOptimizerTests/commonSubexpressionEliminator/trivial.yul @@ -1,11 +1,11 @@ { - let a := mul(1, codesize()) - let b := mul(1, codesize()) + let a := mul(1, calldataload(0)) + let b := mul(1, calldataload(0)) } // ---- // step: commonSubexpressionEliminator // // { -// let a := mul(1, codesize()) +// let a := mul(1, calldataload(0)) // let b := a // } diff --git a/test/libyul/yulOptimizerTests/disambiguator/string_as_hex_and_hex_as_string.yul b/test/libyul/yulOptimizerTests/disambiguator/string_as_hex_and_hex_as_string.yul index f0db2af1b220..e2612756e7a5 100644 --- a/test/libyul/yulOptimizerTests/disambiguator/string_as_hex_and_hex_as_string.yul +++ b/test/libyul/yulOptimizerTests/disambiguator/string_as_hex_and_hex_as_string.yul @@ -4,6 +4,8 @@ object "A" { } data 'abc' "1234" } +// ==== +// bytecodeFormat: legacy // ---- // step: disambiguator // diff --git a/test/libyul/yulOptimizerTests/equalStoreEliminator/branching.yul b/test/libyul/yulOptimizerTests/equalStoreEliminator/branching.yul index 63f0d38e43fe..2f382cab0726 100644 --- a/test/libyul/yulOptimizerTests/equalStoreEliminator/branching.yul +++ b/test/libyul/yulOptimizerTests/equalStoreEliminator/branching.yul @@ -4,7 +4,7 @@ sstore(a, b) if calldataload(32) { sstore(a, b) - pop(staticcall(0, 0, 0, 0, 0, 0)) + pop(sload(a)) sstore(a, b) } sstore(a, b) @@ -18,8 +18,5 @@ // let a := calldataload(0) // let b := 20 // sstore(a, b) -// if calldataload(32) -// { -// pop(staticcall(0, 0, 0, 0, 0, 0)) -// } +// if calldataload(32) { pop(sload(a)) } // } diff --git a/test/libyul/yulOptimizerTests/equalStoreEliminator/functionbody.yul b/test/libyul/yulOptimizerTests/equalStoreEliminator/functionbody.yul index 68839721cd76..cc376652ee7b 100644 --- a/test/libyul/yulOptimizerTests/equalStoreEliminator/functionbody.yul +++ b/test/libyul/yulOptimizerTests/equalStoreEliminator/functionbody.yul @@ -10,7 +10,7 @@ } function g() { - pop(staticcall(0, 0, 0, 0, 0, 0)) + pop(sload(calldataload(0))) } function h(a_, b_) { @@ -21,7 +21,7 @@ } function i() { - pop(delegatecall(0, 0, 0, 0, 0, 0)) + sstore(calldataload(64), 42) } @@ -40,9 +40,7 @@ // g() // } // function g() -// { -// pop(staticcall(0, 0, 0, 0, 0, 0)) -// } +// { pop(sload(calldataload(0))) } // function h(a_, b_) // { // sstore(a_, b_) @@ -50,7 +48,5 @@ // sstore(a_, b_) // } // function i() -// { -// pop(delegatecall(0, 0, 0, 0, 0, 0)) -// } +// { sstore(calldataload(64), 42) } // } diff --git a/test/libyul/yulOptimizerTests/equalStoreEliminator/verbatim.yul b/test/libyul/yulOptimizerTests/equalStoreEliminator/verbatim.yul index fcaddd12134d..112d704e2711 100644 --- a/test/libyul/yulOptimizerTests/equalStoreEliminator/verbatim.yul +++ b/test/libyul/yulOptimizerTests/equalStoreEliminator/verbatim.yul @@ -4,7 +4,7 @@ sstore(a, b) if calldataload(32) { sstore(a, b) - pop(staticcall(0, 0, 0, 0, 0, 0)) + pop(sload(a)) verbatim_0i_0o("xyz") } sstore(a, b) @@ -20,7 +20,7 @@ // sstore(a, b) // if calldataload(32) // { -// pop(staticcall(0, 0, 0, 0, 0, 0)) +// pop(sload(a)) // verbatim_0i_0o("xyz") // } // sstore(a, b) diff --git a/test/libyul/yulOptimizerTests/equivalentFunctionCombiner/constant_representation_datasize.yul b/test/libyul/yulOptimizerTests/equivalentFunctionCombiner/constant_representation_datasize.yul index 301f50c6ea27..4d3be77e8239 100644 --- a/test/libyul/yulOptimizerTests/equivalentFunctionCombiner/constant_representation_datasize.yul +++ b/test/libyul/yulOptimizerTests/equivalentFunctionCombiner/constant_representation_datasize.yul @@ -26,6 +26,8 @@ object "test" data 'A' "A" } +// ==== +// bytecodeFormat: legacy // ---- // step: equivalentFunctionCombiner // diff --git a/test/libyul/yulOptimizerTests/expressionSimplifier/create2_and_mask.yul b/test/libyul/yulOptimizerTests/expressionSimplifier/create2_and_mask.yul index a431c57a6c6c..e635ad5d4824 100644 --- a/test/libyul/yulOptimizerTests/expressionSimplifier/create2_and_mask.yul +++ b/test/libyul/yulOptimizerTests/expressionSimplifier/create2_and_mask.yul @@ -8,6 +8,7 @@ } // ==== // EVMVersion: >=constantinople +// bytecodeFormat: legacy // ---- // step: expressionSimplifier // diff --git a/test/libyul/yulOptimizerTests/expressionSimplifier/create_and_mask.yul b/test/libyul/yulOptimizerTests/expressionSimplifier/create_and_mask.yul index 3710cbebdf48..1f10c90adb7c 100644 --- a/test/libyul/yulOptimizerTests/expressionSimplifier/create_and_mask.yul +++ b/test/libyul/yulOptimizerTests/expressionSimplifier/create_and_mask.yul @@ -7,6 +7,8 @@ let b := and(0xffffffffffffffffffffffffffffffffffffffff, create(0, 0, 0x20)) sstore(a, b) } +// ==== +// bytecodeFormat: legacy // ---- // step: expressionSimplifier // diff --git a/test/libyul/yulOptimizerTests/expressionSimplifier/large_byte_access.yul b/test/libyul/yulOptimizerTests/expressionSimplifier/large_byte_access.yul index 19d65dca4152..c73fea65c6e0 100644 --- a/test/libyul/yulOptimizerTests/expressionSimplifier/large_byte_access.yul +++ b/test/libyul/yulOptimizerTests/expressionSimplifier/large_byte_access.yul @@ -9,6 +9,8 @@ sstore(9, c) sstore(10, d) } +// ==== +// bytecodeFormat: legacy // ---- // step: expressionSimplifier // diff --git a/test/libyul/yulOptimizerTests/expressionSimplifier/pop_byte_shr_call.yul b/test/libyul/yulOptimizerTests/expressionSimplifier/pop_byte_shr_call.yul index abd1b1743d32..d1e00802ffab 100644 --- a/test/libyul/yulOptimizerTests/expressionSimplifier/pop_byte_shr_call.yul +++ b/test/libyul/yulOptimizerTests/expressionSimplifier/pop_byte_shr_call.yul @@ -3,6 +3,7 @@ } // ==== // EVMVersion: >=constantinople +// bytecodeFormat: legacy // ---- // step: expressionSimplifier // diff --git a/test/libyul/yulOptimizerTests/expressionSimplifier/side_effects_in_for_condition.yul b/test/libyul/yulOptimizerTests/expressionSimplifier/side_effects_in_for_condition.yul index 9c3a5c8ba29e..6dc67840697d 100644 --- a/test/libyul/yulOptimizerTests/expressionSimplifier/side_effects_in_for_condition.yul +++ b/test/libyul/yulOptimizerTests/expressionSimplifier/side_effects_in_for_condition.yul @@ -5,6 +5,7 @@ } // ==== // EVMVersion: >byzantium +// bytecodeFormat: legacy // ---- // step: expressionSimplifier // diff --git a/test/libyul/yulOptimizerTests/expressionSimplifier/zero_length_read.yul b/test/libyul/yulOptimizerTests/expressionSimplifier/zero_length_read.yul index ee7464932d3a..3bc52009e5cc 100644 --- a/test/libyul/yulOptimizerTests/expressionSimplifier/zero_length_read.yul +++ b/test/libyul/yulOptimizerTests/expressionSimplifier/zero_length_read.yul @@ -1,9 +1,7 @@ { revert(calldataload(0), 0) - revert(call(0,0,0,0,0,0,0), 0) calldatacopy(calldataload(1), calldataload(2), 0) return(calldataload(3), 0) - codecopy(calldataload(4), calldataload(5), sub(42,42)) } // ---- // step: expressionSimplifier @@ -12,10 +10,7 @@ // { // let _1 := 0 // revert(0, _1) -// pop(call(_1, _1, _1, _1, _1, _1, _1)) -// revert(0, _1) // calldatacopy(0, calldataload(2), _1) // return(0, _1) -// codecopy(0, calldataload(5), 0) // } // } diff --git a/test/libyul/yulOptimizerTests/expressionSimplifier/zero_length_read_call.yul b/test/libyul/yulOptimizerTests/expressionSimplifier/zero_length_read_call.yul new file mode 100644 index 000000000000..4764c6d5795d --- /dev/null +++ b/test/libyul/yulOptimizerTests/expressionSimplifier/zero_length_read_call.yul @@ -0,0 +1,15 @@ +{ + revert(call(0,0,0,0,0,0,0), 0) +} +// ==== +// bytecodeFormat: legacy +// ---- +// step: expressionSimplifier +// +// { +// { +// let _1 := 0 +// pop(call(_1, _1, _1, _1, _1, _1, _1)) +// revert(0, _1) +// } +// } diff --git a/test/libyul/yulOptimizerTests/expressionSimplifier/zero_length_read_codecopy.yul b/test/libyul/yulOptimizerTests/expressionSimplifier/zero_length_read_codecopy.yul new file mode 100644 index 000000000000..e3f1085e065c --- /dev/null +++ b/test/libyul/yulOptimizerTests/expressionSimplifier/zero_length_read_codecopy.yul @@ -0,0 +1,13 @@ +{ + codecopy(calldataload(4), calldataload(5), sub(42,42)) +} +// ==== +// bytecodeFormat: legacy +// ---- +// step: expressionSimplifier +// +// { +// { +// codecopy(0, calldataload(5), 0) +// } +// } diff --git a/test/libyul/yulOptimizerTests/expressionSplitter/object_access.yul b/test/libyul/yulOptimizerTests/expressionSplitter/object_access.yul index bcd6d0f7bba5..b362f1568c4a 100644 --- a/test/libyul/yulOptimizerTests/expressionSplitter/object_access.yul +++ b/test/libyul/yulOptimizerTests/expressionSplitter/object_access.yul @@ -9,6 +9,8 @@ object "main" { } data "abc" "Hello, World!" } +// ==== +// bytecodeFormat: legacy // ---- // step: expressionSplitter // diff --git a/test/libyul/yulOptimizerTests/fullSimplify/not_applied_removes_non_constant_and_not_movable.yul b/test/libyul/yulOptimizerTests/fullSimplify/not_applied_removes_non_constant_and_not_movable.yul index 0e366e6d4090..af609eb60b61 100644 --- a/test/libyul/yulOptimizerTests/fullSimplify/not_applied_removes_non_constant_and_not_movable.yul +++ b/test/libyul/yulOptimizerTests/fullSimplify/not_applied_removes_non_constant_and_not_movable.yul @@ -3,6 +3,8 @@ let a := div(create(0, 0, 0), 0) mstore(0, a) } +// ==== +// bytecodeFormat: legacy // ---- // step: fullSimplify // diff --git a/test/libyul/yulOptimizerTests/fullSimplify/scoped_var_ref_in_function_call.yul b/test/libyul/yulOptimizerTests/fullSimplify/scoped_var_ref_in_function_call.yul index 38e5ab2108d7..1820f363c52f 100644 --- a/test/libyul/yulOptimizerTests/fullSimplify/scoped_var_ref_in_function_call.yul +++ b/test/libyul/yulOptimizerTests/fullSimplify/scoped_var_ref_in_function_call.yul @@ -6,6 +6,8 @@ } f(call(2, 0, 1, mod(x, 8), 1, 1, 1)) } +// ==== +// bytecodeFormat: legacy // ---- // step: fullSimplify // diff --git a/test/libyul/yulOptimizerTests/fullSuite/aztec.yul b/test/libyul/yulOptimizerTests/fullSuite/aztec.yul index 8b26a7ba3723..94d4b14fffcf 100644 --- a/test/libyul/yulOptimizerTests/fullSuite/aztec.yul +++ b/test/libyul/yulOptimizerTests/fullSuite/aztec.yul @@ -1,3 +1,4 @@ +// TODO: Add EOF version of this contract and compare with legacy to see which optimizations are missed. /** * @title Library to validate AZTEC zero-knowledge proofs * @author Zachary Williamson, AZTEC @@ -230,6 +231,7 @@ } // ==== // EVMVersion: >=istanbul +// bytecodeFormat: legacy // ---- // step: fullSuite // diff --git a/test/libyul/yulOptimizerTests/fullSuite/create2_and_mask.yul b/test/libyul/yulOptimizerTests/fullSuite/create2_and_mask.yul index 6ebca20f5bbb..f0c54556a423 100644 --- a/test/libyul/yulOptimizerTests/fullSuite/create2_and_mask.yul +++ b/test/libyul/yulOptimizerTests/fullSuite/create2_and_mask.yul @@ -8,6 +8,7 @@ } // ==== // EVMVersion: >=shanghai +// bytecodeFormat: legacy // ---- // step: fullSuite // diff --git a/test/libyul/yulOptimizerTests/fullSuite/create_and_mask.yul b/test/libyul/yulOptimizerTests/fullSuite/create_and_mask.yul index 078616bb3b7e..984d9a458d8c 100644 --- a/test/libyul/yulOptimizerTests/fullSuite/create_and_mask.yul +++ b/test/libyul/yulOptimizerTests/fullSuite/create_and_mask.yul @@ -8,6 +8,7 @@ } // ==== // EVMVersion: >=istanbul +// bytecodeFormat: legacy // ---- // step: fullSuite // diff --git a/test/libyul/yulOptimizerTests/fullSuite/extcodelength.yul b/test/libyul/yulOptimizerTests/fullSuite/extcodelength.yul index dd6cdc0e44c4..772ec67cfec8 100644 --- a/test/libyul/yulOptimizerTests/fullSuite/extcodelength.yul +++ b/test/libyul/yulOptimizerTests/fullSuite/extcodelength.yul @@ -18,6 +18,7 @@ } // ==== // EVMVersion: >byzantium +// bytecodeFormat: legacy // ---- // step: fullSuite // diff --git a/test/libyul/yulOptimizerTests/fullSuite/stack_compressor_msize.yul b/test/libyul/yulOptimizerTests/fullSuite/stack_compressor_msize.yul index 5fbe8d22e615..c7eb0a405b80 100644 --- a/test/libyul/yulOptimizerTests/fullSuite/stack_compressor_msize.yul +++ b/test/libyul/yulOptimizerTests/fullSuite/stack_compressor_msize.yul @@ -22,7 +22,7 @@ function foo_singlereturn_1(in_1, in_2) -> out { - extcodecopy(1,msize(),1,1) + mstore8(msize(), 42) } a := foo_singlereturn_0() @@ -60,5 +60,5 @@ // default { out := gcd(_b, mod(_a, _b)) } // } // function foo_singlereturn() -// { extcodecopy(1, msize(), 1, 1) } +// { mstore8(msize(), 42) } // } diff --git a/test/libyul/yulOptimizerTests/fullSuite/unusedFunctionParameterPruner.yul b/test/libyul/yulOptimizerTests/fullSuite/unusedFunctionParameterPruner.yul index 6f82ab27a6d8..9d893a7d3c5c 100644 --- a/test/libyul/yulOptimizerTests/fullSuite/unusedFunctionParameterPruner.yul +++ b/test/libyul/yulOptimizerTests/fullSuite/unusedFunctionParameterPruner.yul @@ -9,7 +9,7 @@ out1 := mload(32) out1 := sload(out1) out2 := add(out1, 1) - extcodecopy(out1, out2, 1, b) + calldatacopy(out2, out1, b) // to prevent foo from getting inlined if iszero(out1) { leave } } @@ -27,7 +27,7 @@ // { // out1 := sload(mload(32)) // out2 := add(out1, 1) -// extcodecopy(out1, out2, 1, b) +// calldatacopy(out2, out1, b) // if iszero(out1) { leave } // } // } diff --git a/test/libyul/yulOptimizerTests/fullSuite/unusedFunctionParameterPruner_return.yul b/test/libyul/yulOptimizerTests/fullSuite/unusedFunctionParameterPruner_return.yul index b066d998bafe..f95e6f30dcc3 100644 --- a/test/libyul/yulOptimizerTests/fullSuite/unusedFunctionParameterPruner_return.yul +++ b/test/libyul/yulOptimizerTests/fullSuite/unusedFunctionParameterPruner_return.yul @@ -16,6 +16,8 @@ if iszero(out1) { leave } } } +// ==== +// bytecodeFormat: legacy // ---- // step: fullSuite // diff --git a/test/libyul/yulOptimizerTests/loadResolver/extstaticcall.yul b/test/libyul/yulOptimizerTests/loadResolver/extstaticcall.yul new file mode 100644 index 000000000000..b7b4de23b017 --- /dev/null +++ b/test/libyul/yulOptimizerTests/loadResolver/extstaticcall.yul @@ -0,0 +1,29 @@ +{ + let a := 0 + let b := 1 + let c := 2 + sstore(a, b) + mstore(900, 7) + let d := extstaticcall(10, 0, 200) + sstore(add(a, 1), mload(900)) + // Main test objective: replace this sload. + mstore(0, sload(a)) +} +// ==== +// EVMVersion: >=byzantium +// bytecodeFormat: >=EOFv1 +// ---- +// step: loadResolver +// +// { +// { +// let a := 0 +// let b := 1 +// sstore(a, b) +// let _1 := 7 +// mstore(900, _1) +// pop(extstaticcall(10, a, 200)) +// sstore(1, _1) +// mstore(a, b) +// } +// } diff --git a/test/libyul/yulOptimizerTests/loadResolver/keccak_crash.yul b/test/libyul/yulOptimizerTests/loadResolver/keccak_crash.yul index 18c818d15ec6..c67a0f875545 100644 --- a/test/libyul/yulOptimizerTests/loadResolver/keccak_crash.yul +++ b/test/libyul/yulOptimizerTests/loadResolver/keccak_crash.yul @@ -2,6 +2,8 @@ { for {} addmod(keccak256(0x0,create(0x0, 0x0, 0x0)), 0x0, 0x0) {} {} } +// ==== +// bytecodeFormat: legacy // ---- // step: loadResolver // diff --git a/test/libyul/yulOptimizerTests/loadResolver/memory_with_different_kinds_of_invalidation.yul b/test/libyul/yulOptimizerTests/loadResolver/memory_with_call_invalidation.yul similarity index 54% rename from test/libyul/yulOptimizerTests/loadResolver/memory_with_different_kinds_of_invalidation.yul rename to test/libyul/yulOptimizerTests/loadResolver/memory_with_call_invalidation.yul index 840f19005b06..88d0ba64db73 100644 --- a/test/libyul/yulOptimizerTests/loadResolver/memory_with_different_kinds_of_invalidation.yul +++ b/test/libyul/yulOptimizerTests/loadResolver/memory_with_call_invalidation.yul @@ -3,17 +3,9 @@ sstore(0, mload(2)) pop(call(0, 0, 0, 0, 0, 0, 0)) sstore(0, mload(2)) - - mstore(2, 10) - mstore8(calldataload(0), 4) - sstore(0, mload(2)) - - mstore(2, 10) - g() - sstore(0, mload(2)) - - function g() {} } +// ==== +// bytecodeFormat: legacy // ---- // step: loadResolver // @@ -27,11 +19,5 @@ // sstore(_5, _4) // pop(call(_5, _5, _5, _5, _5, _5, _5)) // sstore(_5, mload(_2)) -// let _17 := 10 -// mstore(_2, _17) -// mstore8(calldataload(_5), 4) -// sstore(_5, mload(_2)) -// mstore(_2, _17) -// sstore(_5, _17) // } // } diff --git a/test/libyul/yulOptimizerTests/loadResolver/memory_with_extcall_invalidation.yul b/test/libyul/yulOptimizerTests/loadResolver/memory_with_extcall_invalidation.yul new file mode 100644 index 000000000000..55c131677f5a --- /dev/null +++ b/test/libyul/yulOptimizerTests/loadResolver/memory_with_extcall_invalidation.yul @@ -0,0 +1,22 @@ +{ + mstore(2, 9) + sstore(0, mload(2)) + pop(extcall(0, 0, 0, 0)) + sstore(0, mload(2)) +} +// ==== +// bytecodeFormat: >=EOFv1 +// ---- +// step: loadResolver +// +// { +// { +// let _1 := 9 +// mstore(2, _1) +// let _4 := _1 +// let _5 := 0 +// sstore(_5, _4) +// pop(extcall(_5, _5, _5, _5)) +// sstore(_5, _1) +// } +// } diff --git a/test/libyul/yulOptimizerTests/loadResolver/memory_with_function_call_invalidation.yul b/test/libyul/yulOptimizerTests/loadResolver/memory_with_function_call_invalidation.yul new file mode 100644 index 000000000000..7181d553ada7 --- /dev/null +++ b/test/libyul/yulOptimizerTests/loadResolver/memory_with_function_call_invalidation.yul @@ -0,0 +1,17 @@ +{ + mstore(2, 10) + g() + sstore(0, mload(2)) + + function g() {} +} +// ---- +// step: loadResolver +// +// { +// { +// let _1 := 10 +// mstore(2, _1) +// sstore(0, _1) +// } +// } diff --git a/test/libyul/yulOptimizerTests/loadResolver/memory_with_mstore_invalidation.yul b/test/libyul/yulOptimizerTests/loadResolver/memory_with_mstore_invalidation.yul new file mode 100644 index 000000000000..3179ef3916ea --- /dev/null +++ b/test/libyul/yulOptimizerTests/loadResolver/memory_with_mstore_invalidation.yul @@ -0,0 +1,19 @@ +{ + mstore(2, 10) + mstore8(calldataload(0), 4) + sstore(0, mload(2)) +} +// ---- +// step: loadResolver +// +// { +// { +// let _1 := 10 +// let _2 := 2 +// mstore(_2, _1) +// let _3 := 4 +// let _4 := 0 +// mstore8(calldataload(_4), _3) +// sstore(_4, mload(_2)) +// } +// } diff --git a/test/libyul/yulOptimizerTests/loadResolver/staticcall.yul b/test/libyul/yulOptimizerTests/loadResolver/staticcall.yul index 2a72eee3e215..ede5dc3e8273 100644 --- a/test/libyul/yulOptimizerTests/loadResolver/staticcall.yul +++ b/test/libyul/yulOptimizerTests/loadResolver/staticcall.yul @@ -11,6 +11,7 @@ } // ==== // EVMVersion: >=byzantium +// bytecodeFormat: legacy // ---- // step: loadResolver // diff --git a/test/libyul/yulOptimizerTests/loadResolver/zero_length_reads.yul b/test/libyul/yulOptimizerTests/loadResolver/zero_length_reads.yul index 418221a93824..8035d17729bd 100644 --- a/test/libyul/yulOptimizerTests/loadResolver/zero_length_reads.yul +++ b/test/libyul/yulOptimizerTests/loadResolver/zero_length_reads.yul @@ -18,6 +18,7 @@ } // ==== // EVMVersion: >=constantinople +// bytecodeFormat: legacy // ---- // step: loadResolver // diff --git a/test/libyul/yulOptimizerTests/loadResolver/zero_length_reads_eof.yul b/test/libyul/yulOptimizerTests/loadResolver/zero_length_reads_eof.yul new file mode 100644 index 000000000000..42e6d11c7b2f --- /dev/null +++ b/test/libyul/yulOptimizerTests/loadResolver/zero_length_reads_eof.yul @@ -0,0 +1,39 @@ +{ + // TODO: The current implementation of YulOptimizerTests ignores subobjects that are not Data. It's impossbile to test + // eofcreate and returncontract now. + returndatacopy(1, 1, 0) + calldatacopy(1, 1, 0) + log0(1, 0) + log1(1, 0, 1) + log2(1, 0, 1, 1) + log3(1, 0, 1, 1, 1) + log4(1, 0, 1, 1, 1, 1) + //pop(eofcreate("a", 1, 1, 1, 0)) + //returncontract("b", 1, 0) + pop(extcall(1, 1, 1, 0)) + pop(extdelegatecall(1, 1, 0)) + pop(extstaticcall(1, 1, 0)) + return(1, 0) +} +// ==== +// bytecodeFormat: >=EOFv1 +// ---- +// step: loadResolver +// +// { +// { +// let _1 := 0 +// let _2 := 1 +// returndatacopy(0, _2, _1) +// calldatacopy(0, _2, _1) +// log0(0, _1) +// log1(0, _1, _2) +// log2(0, _1, _2, _2) +// log3(0, _1, _2, _2, _2) +// log4(0, _1, _2, _2, _2, _2) +// pop(extcall(_2, _2, _2, _1)) +// pop(extdelegatecall(_2, 0, _1)) +// pop(extstaticcall(_2, 0, _1)) +// return(0, _1) +// } +// } diff --git a/test/libyul/yulOptimizerTests/loopInvariantCodeMotion/complex_move.yul b/test/libyul/yulOptimizerTests/loopInvariantCodeMotion/complex_move.yul index 3c11ca65f0db..cfa38e05ab08 100644 --- a/test/libyul/yulOptimizerTests/loopInvariantCodeMotion/complex_move.yul +++ b/test/libyul/yulOptimizerTests/loopInvariantCodeMotion/complex_move.yul @@ -2,7 +2,7 @@ let b := 1 for { let a := 1 } iszero(eq(a, 10)) { a := add(a, 1) } { let inv := add(b, 42) - let x := extcodesize(keccak256(mul(mload(inv), 3), 32)) + let x := balance(keccak256(mul(mload(inv), 3), 32)) a := add(x, 1) sstore(a, inv) } @@ -14,7 +14,7 @@ // let b := 1 // let a := 1 // let inv := add(b, 42) -// let x := extcodesize(keccak256(mul(mload(inv), 3), 32)) +// let x := balance(keccak256(mul(mload(inv), 3), 32)) // for { } iszero(eq(a, 10)) { a := add(a, 1) } // { // a := add(x, 1) diff --git a/test/libyul/yulOptimizerTests/loopInvariantCodeMotion/create_sload.yul b/test/libyul/yulOptimizerTests/loopInvariantCodeMotion/create_sload.yul index 41289503791a..fa6619d05e30 100644 --- a/test/libyul/yulOptimizerTests/loopInvariantCodeMotion/create_sload.yul +++ b/test/libyul/yulOptimizerTests/loopInvariantCodeMotion/create_sload.yul @@ -11,6 +11,8 @@ let z := f() } } +// ==== +// bytecodeFormat: legacy // ---- // step: loopInvariantCodeMotion // diff --git a/test/libyul/yulOptimizerTests/loopInvariantCodeMotion/move_state_function.yul b/test/libyul/yulOptimizerTests/loopInvariantCodeMotion/move_state_function.yul index 1d1a1491558f..a6ccbb39f83c 100644 --- a/test/libyul/yulOptimizerTests/loopInvariantCodeMotion/move_state_function.yul +++ b/test/libyul/yulOptimizerTests/loopInvariantCodeMotion/move_state_function.yul @@ -4,7 +4,7 @@ let b := 1 for { let a := 1 } iszero(eq(a, 10)) { a := add(a, 1) } { - let t := extcodesize(f()) + let t := balance(f()) let q := g() } } @@ -14,7 +14,7 @@ // { // let b := 1 // let a := 1 -// let t := extcodesize(f()) +// let t := balance(f()) // let q := g() // for { } iszero(eq(a, 10)) { a := add(a, 1) } // { } diff --git a/test/libyul/yulOptimizerTests/loopInvariantCodeMotion/no_move_gas.yul b/test/libyul/yulOptimizerTests/loopInvariantCodeMotion/no_move_gas.yul new file mode 100644 index 000000000000..ae69ae3f7a45 --- /dev/null +++ b/test/libyul/yulOptimizerTests/loopInvariantCodeMotion/no_move_gas.yul @@ -0,0 +1,15 @@ +{ + for { let a := 1 } iszero(eq(a, 10)) { a := add(a, 1) } { + let c := gas() + } +} +// ==== +// bytecodeFormat: legacy +// ---- +// step: loopInvariantCodeMotion +// +// { +// let a := 1 +// for { } iszero(eq(a, 10)) { a := add(a, 1) } +// { let c := gas() } +// } diff --git a/test/libyul/yulOptimizerTests/loopInvariantCodeMotion/no_move_immovables.yul b/test/libyul/yulOptimizerTests/loopInvariantCodeMotion/no_move_immovables.yul index 8881fdc84887..0c7d68fc7641 100644 --- a/test/libyul/yulOptimizerTests/loopInvariantCodeMotion/no_move_immovables.yul +++ b/test/libyul/yulOptimizerTests/loopInvariantCodeMotion/no_move_immovables.yul @@ -1,24 +1,20 @@ { - let a := 1 - function f() -> x {invalid()} - function g() -> y {return(0, 0)} - for { let i := 1 } iszero(eq(i, 10)) { a := add(i, 1) } { - let b := f() - let c := gas() - let d := g() - let e := sload(g()) - } + function f() -> x {invalid()} + function g() -> y {return(0, 0)} + for { let a := 1 } iszero(eq(a, 10)) { a := add(a, 1) } { + let b := f() + let d := g() + let e := sload(g()) + } } // ---- // step: loopInvariantCodeMotion // // { // let a := 1 -// let i := 1 -// for { } iszero(eq(i, 10)) { a := add(i, 1) } +// for { } iszero(eq(a, 10)) { a := add(a, 1) } // { // let b := f() -// let c := gas() // let d := g() // let e := sload(g()) // } diff --git a/test/libyul/yulOptimizerTests/loopInvariantCodeMotion/no_move_memory.yul b/test/libyul/yulOptimizerTests/loopInvariantCodeMotion/no_move_memory.yul index 942a3c5802cb..486921ae6304 100644 --- a/test/libyul/yulOptimizerTests/loopInvariantCodeMotion/no_move_memory.yul +++ b/test/libyul/yulOptimizerTests/loopInvariantCodeMotion/no_move_memory.yul @@ -9,7 +9,7 @@ for { let a := 1 } iszero(eq(a, 10)) { a := add(a, 1) } { let inv := add(b, 42) // mload prevents moving of extcodesize - let x := extcodesize(mload(mul(inv, 3))) + let x := balance(mload(mul(inv, 3))) a := add(x, 1) mstore(a, inv) } @@ -31,7 +31,7 @@ // let inv_2 := add(b, 42) // for { } iszero(eq(a_1, 10)) { a_1 := add(a_1, 1) } // { -// let x_3 := extcodesize(mload(mul(inv_2, 3))) +// let x_3 := balance(mload(mul(inv_2, 3))) // a_1 := add(x_3, 1) // mstore(a_1, inv_2) // } diff --git a/test/libyul/yulOptimizerTests/loopInvariantCodeMotion/no_move_memory_msize.yul b/test/libyul/yulOptimizerTests/loopInvariantCodeMotion/no_move_memory_msize.yul index 2033a9be91a4..95f968d89195 100644 --- a/test/libyul/yulOptimizerTests/loopInvariantCodeMotion/no_move_memory_msize.yul +++ b/test/libyul/yulOptimizerTests/loopInvariantCodeMotion/no_move_memory_msize.yul @@ -8,7 +8,7 @@ } for { let a := 1 } iszero(eq(a, 10)) { a := add(a, 1) } { let inv := add(b, 42) - let x := extcodesize(mload(mul(inv, 3))) + let x := balance(mload(mul(inv, 3))) a := add(x, 1) } } @@ -29,7 +29,7 @@ // let inv_2 := add(b, 42) // for { } iszero(eq(a_1, 10)) { a_1 := add(a_1, 1) } // { -// let x_3 := extcodesize(mload(mul(inv_2, 3))) +// let x_3 := balance(mload(mul(inv_2, 3))) // a_1 := add(x_3, 1) // } // } diff --git a/test/libyul/yulOptimizerTests/loopInvariantCodeMotion/no_move_state.yul b/test/libyul/yulOptimizerTests/loopInvariantCodeMotion/no_move_state.yul index fa6c985b4f8a..c2ea86bc82f0 100644 --- a/test/libyul/yulOptimizerTests/loopInvariantCodeMotion/no_move_state.yul +++ b/test/libyul/yulOptimizerTests/loopInvariantCodeMotion/no_move_state.yul @@ -25,6 +25,8 @@ } } +// ==== +// bytecodeFormat: legacy // ---- // step: loopInvariantCodeMotion // diff --git a/test/libyul/yulOptimizerTests/loopInvariantCodeMotion/no_move_state_function.yul b/test/libyul/yulOptimizerTests/loopInvariantCodeMotion/no_move_state_function.yul index d3dce8d781b6..c50d1b6c21d4 100644 --- a/test/libyul/yulOptimizerTests/loopInvariantCodeMotion/no_move_state_function.yul +++ b/test/libyul/yulOptimizerTests/loopInvariantCodeMotion/no_move_state_function.yul @@ -7,7 +7,7 @@ let b := 1 for { let a := 1 } iszero(eq(a, 10)) { a := add(a, 1) } { - let t := extcodesize(f()) + let t := balance(f()) let q := sload(g()) } } @@ -19,7 +19,7 @@ // let a := 1 // for { } iszero(eq(a, 10)) { a := add(a, 1) } // { -// let t := extcodesize(f()) +// let t := balance(f()) // let q := sload(g()) // } // function f() -> x diff --git a/test/libyul/yulOptimizerTests/loopInvariantCodeMotion/no_move_state_loop.yul b/test/libyul/yulOptimizerTests/loopInvariantCodeMotion/no_move_state_loop.yul index 8de9147d8aed..9745dbe4760f 100644 --- a/test/libyul/yulOptimizerTests/loopInvariantCodeMotion/no_move_state_loop.yul +++ b/test/libyul/yulOptimizerTests/loopInvariantCodeMotion/no_move_state_loop.yul @@ -4,7 +4,7 @@ let b := 1 for { let a := 1 } iszero(eq(a, 10)) { a := add(a, 1) } { - let t := extcodesize(f()) + let t := balance(f()) let q := g() } } @@ -16,7 +16,7 @@ // let a := 1 // for { } iszero(eq(a, 10)) { a := add(a, 1) } // { -// let t := extcodesize(f()) +// let t := balance(f()) // let q := g() // } // function f() -> x diff --git a/test/libyul/yulOptimizerTests/loopInvariantCodeMotion/no_move_state_recursive_function.yul b/test/libyul/yulOptimizerTests/loopInvariantCodeMotion/no_move_state_recursive_function.yul index 1eb0ccd6dd96..b8d4044c50d2 100644 --- a/test/libyul/yulOptimizerTests/loopInvariantCodeMotion/no_move_state_recursive_function.yul +++ b/test/libyul/yulOptimizerTests/loopInvariantCodeMotion/no_move_state_recursive_function.yul @@ -4,7 +4,7 @@ let b := 1 for { let a := 1 } iszero(eq(a, 10)) { a := add(a, 1) } { - let t := extcodesize(f()) + let t := balance(f()) let q := sload(g()) } } @@ -16,7 +16,7 @@ // let a := 1 // for { } iszero(eq(a, 10)) { a := add(a, 1) } // { -// let t := extcodesize(f()) +// let t := balance(f()) // let q := sload(g()) // } // function f() -> x diff --git a/test/libyul/yulOptimizerTests/loopInvariantCodeMotion/no_move_staticall_returndatasize.yul b/test/libyul/yulOptimizerTests/loopInvariantCodeMotion/no_move_staticall_returndatasize.yul index ae20f4904f88..a5f2125a0300 100644 --- a/test/libyul/yulOptimizerTests/loopInvariantCodeMotion/no_move_staticall_returndatasize.yul +++ b/test/libyul/yulOptimizerTests/loopInvariantCodeMotion/no_move_staticall_returndatasize.yul @@ -10,6 +10,8 @@ } } // ==== +// bytecodeFormat: legacy +// ==== // EVMVersion: >=byzantium // ---- // step: loopInvariantCodeMotion diff --git a/test/libyul/yulOptimizerTests/loopInvariantCodeMotion/no_move_storage.yul b/test/libyul/yulOptimizerTests/loopInvariantCodeMotion/no_move_storage.yul index 0ef2fd78ad40..410f07663dbf 100644 --- a/test/libyul/yulOptimizerTests/loopInvariantCodeMotion/no_move_storage.yul +++ b/test/libyul/yulOptimizerTests/loopInvariantCodeMotion/no_move_storage.yul @@ -1,30 +1,15 @@ { - let b := 1 - // invalidates storage in post - for { let a := 1 } iszero(eq(a, 10)) { sstore(0x00, 0x01)} { - let inv := add(b, 42) - let x := sload(mul(inv, 3)) - a := add(x, 1) - mstore(a, inv) - } - - // invalidates storage in body - for { let a := 1 } iszero(eq(a, 10)) { a := add(a, 1) } { - let inv := add(b, 42) - let x := sload(mul(inv, 3)) - a := add(x, 1) - sstore(a, inv) - } - - // invalidates state in body - for { let a := 1 } iszero(eq(a, 10)) { a := add(a, 1) } { - let inv := add(b, 42) - pop(callcode(100, 0x010, 10, 0x00, 32, 0x0100, 32)) - let x := sload(mul(inv, 3)) - a := add(x, 1) - } - + let b := 1 + // invalidates state in body + for { let a := 1 } iszero(eq(a, 10)) { a := add(a, 1) } { + let inv := add(b, 42) + pop(callcode(100, 0x010, 10, 0x00, 32, 0x0100, 32)) + let x := sload(mul(inv, 3)) + a := add(x, 1) + } } +// ==== +// bytecodeFormat: legacy // ---- // step: loopInvariantCodeMotion // @@ -32,26 +17,10 @@ // let b := 1 // let a := 1 // let inv := add(b, 42) -// for { } iszero(eq(a, 10)) { sstore(0x00, 0x01) } +// for { } iszero(eq(a, 10)) { a := add(a, 1) } // { +// pop(callcode(100, 0x010, 10, 0x00, 32, 0x0100, 32)) // let x := sload(mul(inv, 3)) // a := add(x, 1) -// mstore(a, inv) -// } -// let a_1 := 1 -// let inv_2 := add(b, 42) -// for { } iszero(eq(a_1, 10)) { a_1 := add(a_1, 1) } -// { -// let x_3 := sload(mul(inv_2, 3)) -// a_1 := add(x_3, 1) -// sstore(a_1, inv_2) -// } -// let a_4 := 1 -// let inv_5 := add(b, 42) -// for { } iszero(eq(a_4, 10)) { a_4 := add(a_4, 1) } -// { -// pop(callcode(100, 0x010, 10, 0x00, 32, 0x0100, 32)) -// let x_6 := sload(mul(inv_5, 3)) -// a_4 := add(x_6, 1) // } // } diff --git a/test/libyul/yulOptimizerTests/loopInvariantCodeMotion/no_move_storage_in_body.yul b/test/libyul/yulOptimizerTests/loopInvariantCodeMotion/no_move_storage_in_body.yul new file mode 100644 index 000000000000..66a21130bbb8 --- /dev/null +++ b/test/libyul/yulOptimizerTests/loopInvariantCodeMotion/no_move_storage_in_body.yul @@ -0,0 +1,24 @@ +{ + let b := 1 + // invalidates storage in body + for { let a := 1 } iszero(eq(a, 10)) { a := add(a, 1) } { + let inv := add(b, 42) + let x := sload(mul(inv, 3)) + a := add(x, 1) + sstore(a, inv) + } +} +// ---- +// step: loopInvariantCodeMotion +// +// { +// let b := 1 +// let a := 1 +// let inv := add(b, 42) +// for { } iszero(eq(a, 10)) { a := add(a, 1) } +// { +// let x := sload(mul(inv, 3)) +// a := add(x, 1) +// sstore(a, inv) +// } +// } diff --git a/test/libyul/yulOptimizerTests/loopInvariantCodeMotion/no_move_storage_in_post.yul b/test/libyul/yulOptimizerTests/loopInvariantCodeMotion/no_move_storage_in_post.yul new file mode 100644 index 000000000000..6859f028bd34 --- /dev/null +++ b/test/libyul/yulOptimizerTests/loopInvariantCodeMotion/no_move_storage_in_post.yul @@ -0,0 +1,24 @@ +{ + let b := 1 + // invalidates storage in post + for { let a := 1 } iszero(eq(a, 10)) { sstore(0x00, 0x01)} { + let inv := add(b, 42) + let x := sload(mul(inv, 3)) + a := add(x, 1) + mstore(a, inv) + } +} +// ---- +// step: loopInvariantCodeMotion +// +// { +// let b := 1 +// let a := 1 +// let inv := add(b, 42) +// for { } iszero(eq(a, 10)) { sstore(0x00, 0x01) } +// { +// let x := sload(mul(inv, 3)) +// a := add(x, 1) +// mstore(a, inv) +// } +// } diff --git a/test/libyul/yulOptimizerTests/loopInvariantCodeMotion/simple_state.yul b/test/libyul/yulOptimizerTests/loopInvariantCodeMotion/simple_state.yul index f8b5a3d53725..b087802ef566 100644 --- a/test/libyul/yulOptimizerTests/loopInvariantCodeMotion/simple_state.yul +++ b/test/libyul/yulOptimizerTests/loopInvariantCodeMotion/simple_state.yul @@ -2,7 +2,7 @@ let b := 1 for { let a := 1 } iszero(eq(a, 10)) { a := add(a, 1) } { let inv := add(b, 42) - let x := extcodesize(mul(inv, 3)) + let x := balance(mul(inv, 3)) a := add(x, 1) mstore(a, inv) } @@ -14,7 +14,7 @@ // let b := 1 // let a := 1 // let inv := add(b, 42) -// let x := extcodesize(mul(inv, 3)) +// let x := balance(mul(inv, 3)) // for { } iszero(eq(a, 10)) { a := add(a, 1) } // { // a := add(x, 1) diff --git a/test/libyul/yulOptimizerTests/rematerialiser/reassign.yul b/test/libyul/yulOptimizerTests/rematerialiser/reassign.yul index ef6e12ab6ec2..57886d56380b 100644 --- a/test/libyul/yulOptimizerTests/rematerialiser/reassign.yul +++ b/test/libyul/yulOptimizerTests/rematerialiser/reassign.yul @@ -1,5 +1,5 @@ { - let a := extcodesize(0) + let a := balance(0) let b := a let c := b a := 2 @@ -10,7 +10,7 @@ // step: rematerialiser // // { -// let a := extcodesize(0) +// let a := balance(0) // let b := a // let c := a // a := 2 diff --git a/test/libyul/yulOptimizerTests/rematerialiser/update_asignment_remat.yul b/test/libyul/yulOptimizerTests/rematerialiser/update_asignment_remat.yul index bb5f029803fa..d168b1886c94 100644 --- a/test/libyul/yulOptimizerTests/rematerialiser/update_asignment_remat.yul +++ b/test/libyul/yulOptimizerTests/rematerialiser/update_asignment_remat.yul @@ -1,6 +1,6 @@ // We cannot substitute `a` in `let b := a` { - let a := extcodesize(0) + let a := balance(0) a := mul(a, 2) let b := a } @@ -8,7 +8,7 @@ // step: rematerialiser // // { -// let a := extcodesize(0) +// let a := balance(0) // a := mul(a, 2) // let b := a // } diff --git a/test/libyul/yulOptimizerTests/unusedStoreEliminator/call_does_not_need_to_write.yul b/test/libyul/yulOptimizerTests/unusedStoreEliminator/call_does_not_need_to_write.yul index eeff779f85e0..2a65462e86bf 100644 --- a/test/libyul/yulOptimizerTests/unusedStoreEliminator/call_does_not_need_to_write.yul +++ b/test/libyul/yulOptimizerTests/unusedStoreEliminator/call_does_not_need_to_write.yul @@ -12,6 +12,8 @@ sstore(0, mload(0)) } +// ==== +// bytecodeFormat: legacy // ---- // step: unusedStoreEliminator // diff --git a/test/libyul/yulOptimizerTests/unusedStoreEliminator/create.yul b/test/libyul/yulOptimizerTests/unusedStoreEliminator/create.yul index c3183d9ec83b..dc339466f864 100644 --- a/test/libyul/yulOptimizerTests/unusedStoreEliminator/create.yul +++ b/test/libyul/yulOptimizerTests/unusedStoreEliminator/create.yul @@ -4,6 +4,8 @@ pop(create(0, 0, 0)) sstore(x, 20) } +// ==== +// bytecodeFormat: legacy // ---- // step: unusedStoreEliminator // diff --git a/test/libyul/yulOptimizerTests/unusedStoreEliminator/create_inside_function.yul b/test/libyul/yulOptimizerTests/unusedStoreEliminator/create_inside_function.yul index 782c68663b08..788e7be21ddd 100644 --- a/test/libyul/yulOptimizerTests/unusedStoreEliminator/create_inside_function.yul +++ b/test/libyul/yulOptimizerTests/unusedStoreEliminator/create_inside_function.yul @@ -7,6 +7,8 @@ f() sstore(x, 20) } +// ==== +// bytecodeFormat: legacy // ---- // step: unusedStoreEliminator // From ea58f7eb553d4ec0306fa856a02138cbee6b808c Mon Sep 17 00:00:00 2001 From: rodiazet Date: Fri, 13 Dec 2024 15:23:58 +0100 Subject: [PATCH 0778/1022] eof: Update `yulControlFlowGraph` tests --- .../yulControlFlowGraph/ambiguous_names.yul | 2 + test/libyul/yulControlFlowGraph/complex.yul | 2 + .../yulControlFlowGraph/eof/function.yul | 67 +++++++++++++++++++ test/libyul/yulControlFlowGraph/function.yul | 2 + test/libyul/yulControlFlowGraph/leave.yul | 2 + 5 files changed, 75 insertions(+) create mode 100644 test/libyul/yulControlFlowGraph/eof/function.yul diff --git a/test/libyul/yulControlFlowGraph/ambiguous_names.yul b/test/libyul/yulControlFlowGraph/ambiguous_names.yul index fabeda45b80f..e7aaeadbba3d 100644 --- a/test/libyul/yulControlFlowGraph/ambiguous_names.yul +++ b/test/libyul/yulControlFlowGraph/ambiguous_names.yul @@ -14,6 +14,8 @@ function b() {} } } +// ==== +// bytecodeFormat: legacy // ---- // digraph CFG { // nodesep=0.7; diff --git a/test/libyul/yulControlFlowGraph/complex.yul b/test/libyul/yulControlFlowGraph/complex.yul index 4001a93092e1..718ea6770979 100644 --- a/test/libyul/yulControlFlowGraph/complex.yul +++ b/test/libyul/yulControlFlowGraph/complex.yul @@ -43,6 +43,8 @@ } pop(f(1,2)) } +// ==== +// bytecodeFormat: legacy // ---- // digraph CFG { // nodesep=0.7; diff --git a/test/libyul/yulControlFlowGraph/eof/function.yul b/test/libyul/yulControlFlowGraph/eof/function.yul new file mode 100644 index 000000000000..5f5ef934bd94 --- /dev/null +++ b/test/libyul/yulControlFlowGraph/eof/function.yul @@ -0,0 +1,67 @@ +{ + function f(a, b) -> r { + let x := add(a,b) + r := sub(x,a) + } + function g() { + sstore(0x01, 0x0101) + } + function h(x) { + h(f(x, 0)) + g() + } + function i() -> v, w { + v := 0x0202 + w := 0x0303 + } + let x, y := i() + h(x) + h(y) +} +// ==== +// bytecodeFormat: >=EOFv1 +// ---- +// digraph CFG { +// nodesep=0.7; +// node[shape=box]; +// +// Entry [label="Entry"]; +// Entry -> Block0; +// Block0 [label="\ +// i: [ ] => [ TMP[i, 0] TMP[i, 1] ]\l\ +// Assignment(x, y): [ TMP[i, 0] TMP[i, 1] ] => [ x y ]\l\ +// h: [ x ] => [ ]\l\ +// "]; +// Block0Exit [label="Terminated"]; +// Block0 -> Block0Exit; +// +// FunctionEntry_f_1 [label="function f(a, b) -> r"]; +// FunctionEntry_f_1 -> Block1; +// Block1 [label="\ +// add: [ b a ] => [ TMP[add, 0] ]\l\ +// Assignment(x): [ TMP[add, 0] ] => [ x ]\l\ +// sub: [ a x ] => [ TMP[sub, 0] ]\l\ +// Assignment(r): [ TMP[sub, 0] ] => [ r ]\l\ +// "]; +// Block1Exit [label="FunctionReturn[f]"]; +// Block1 -> Block1Exit; +// +// FunctionEntry_h_2 [label="function h(x)"]; +// FunctionEntry_h_2 -> Block2; +// Block2 [label="\ +// f: [ 0x00 x ] => [ TMP[f, 0] ]\l\ +// h: [ TMP[f, 0] ] => [ ]\l\ +// "]; +// Block2Exit [label="Terminated"]; +// Block2 -> Block2Exit; +// +// FunctionEntry_i_3 [label="function i() -> v, w"]; +// FunctionEntry_i_3 -> Block3; +// Block3 [label="\ +// Assignment(v): [ 0x0202 ] => [ v ]\l\ +// Assignment(w): [ 0x0303 ] => [ w ]\l\ +// "]; +// Block3Exit [label="FunctionReturn[i]"]; +// Block3 -> Block3Exit; +// +// } diff --git a/test/libyul/yulControlFlowGraph/function.yul b/test/libyul/yulControlFlowGraph/function.yul index f65c7505cb9d..0e3691a426cd 100644 --- a/test/libyul/yulControlFlowGraph/function.yul +++ b/test/libyul/yulControlFlowGraph/function.yul @@ -18,6 +18,8 @@ h(x) h(y) } +// ==== +// bytecodeFormat: legacy // ---- // digraph CFG { // nodesep=0.7; diff --git a/test/libyul/yulControlFlowGraph/leave.yul b/test/libyul/yulControlFlowGraph/leave.yul index 4d0a63af4805..d6f475513b4d 100644 --- a/test/libyul/yulControlFlowGraph/leave.yul +++ b/test/libyul/yulControlFlowGraph/leave.yul @@ -11,6 +11,8 @@ pop(f(0,1)) } +// ==== +// bytecodeFormat: legacy // ---- // digraph CFG { // nodesep=0.7; From 2c323da8b9e29c7301086ccf7bcb06c52d883cc3 Mon Sep 17 00:00:00 2001 From: rodiazet Date: Mon, 16 Dec 2024 10:44:02 +0100 Subject: [PATCH 0779/1022] eof: Update `yulStackLayout` tests --- test/libyul/yulStackLayout/complex.yul | 2 + test/libyul/yulStackLayout/eof/function.yul | 102 ++++++++++++++++++++ test/libyul/yulStackLayout/function.yul | 4 +- test/libyul/yulStackLayout/literal_loop.yul | 2 + 4 files changed, 109 insertions(+), 1 deletion(-) create mode 100644 test/libyul/yulStackLayout/eof/function.yul diff --git a/test/libyul/yulStackLayout/complex.yul b/test/libyul/yulStackLayout/complex.yul index 604dca1f46e2..66390f7d4741 100644 --- a/test/libyul/yulStackLayout/complex.yul +++ b/test/libyul/yulStackLayout/complex.yul @@ -48,6 +48,8 @@ } pop(f(1,2)) } +// ==== +// bytecodeFormat: legacy // ---- // digraph CFG { // nodesep=0.7; diff --git a/test/libyul/yulStackLayout/eof/function.yul b/test/libyul/yulStackLayout/eof/function.yul new file mode 100644 index 000000000000..a196e46e887d --- /dev/null +++ b/test/libyul/yulStackLayout/eof/function.yul @@ -0,0 +1,102 @@ +{ + function f(a, b) -> r { + let x := add(a,b) + r := sub(x,a) + } + function g() { + sstore(0x01, 0x0101) + } + function h(x) { + h(f(x, 0)) + g() + } + function i() -> v, w { + v := 0x0202 + w := 0x0303 + } + let x, y := i() + h(x) + h(y) + // This call of g() is unreachable too as the one in h() but we wanna cover both cases. + g() +} +// ==== +// bytecodeFormat: >=EOFv1 +// ---- +// digraph CFG { +// nodesep=0.7; +// node[shape=box]; +// +// Entry [label="Entry"]; +// Entry -> Block0; +// Block0 [label="\ +// [ ]\l\ +// [ ]\l\ +// i\l\ +// [ TMP[i, 0] TMP[i, 1] ]\l\ +// [ TMP[i, 0] TMP[i, 1] ]\l\ +// Assignment(x, y)\l\ +// [ x y ]\l\ +// [ x ]\l\ +// h\l\ +// [ ]\l\ +// [ ]\l\ +// "]; +// Block0Exit [label="Terminated"]; +// Block0 -> Block0Exit; +// +// FunctionEntry_f [label="function f(a, b) -> r\l\ +// [ RET b a ]"]; +// FunctionEntry_f -> Block1; +// Block1 [label="\ +// [ a b ]\l\ +// [ a b a ]\l\ +// add\l\ +// [ a TMP[add, 0] ]\l\ +// [ a TMP[add, 0] ]\l\ +// Assignment(x)\l\ +// [ a x ]\l\ +// [ a x ]\l\ +// sub\l\ +// [ TMP[sub, 0] ]\l\ +// [ TMP[sub, 0] ]\l\ +// Assignment(r)\l\ +// [ r ]\l\ +// [ r ]\l\ +// "]; +// Block1Exit [label="FunctionReturn[f]"]; +// Block1 -> Block1Exit; +// +// FunctionEntry_h [label="function h(x)\l\ +// [ RET x ]"]; +// FunctionEntry_h -> Block2; +// Block2 [label="\ +// [ 0x00 x ]\l\ +// [ 0x00 x ]\l\ +// f\l\ +// [ TMP[f, 0] ]\l\ +// [ TMP[f, 0] ]\l\ +// h\l\ +// [ ]\l\ +// [ ]\l\ +// "]; +// Block2Exit [label="Terminated"]; +// Block2 -> Block2Exit; +// +// FunctionEntry_i [label="function i() -> v, w\l\ +// [ RET ]"]; +// FunctionEntry_i -> Block3; +// Block3 [label="\ +// [ ]\l\ +// [ 0x0202 ]\l\ +// Assignment(v)\l\ +// [ v ]\l\ +// [ v 0x0303 ]\l\ +// Assignment(w)\l\ +// [ v w ]\l\ +// [ v w ]\l\ +// "]; +// Block3Exit [label="FunctionReturn[i]"]; +// Block3 -> Block3Exit; +// +// } diff --git a/test/libyul/yulStackLayout/function.yul b/test/libyul/yulStackLayout/function.yul index e01a8dcb3610..13f83505d48e 100644 --- a/test/libyul/yulStackLayout/function.yul +++ b/test/libyul/yulStackLayout/function.yul @@ -17,9 +17,11 @@ let x, y := i() h(x) h(y) - // This calla of g() is unreachable too as the one in h() but we wanna cover both cases. + // This call of g() is unreachable too as the one in h() but we wanna cover both cases. g() } +// ==== +// bytecodeFormat: legacy // ---- // digraph CFG { // nodesep=0.7; diff --git a/test/libyul/yulStackLayout/literal_loop.yul b/test/libyul/yulStackLayout/literal_loop.yul index 841c4106262d..fee5f7b5673a 100644 --- a/test/libyul/yulStackLayout/literal_loop.yul +++ b/test/libyul/yulStackLayout/literal_loop.yul @@ -4,6 +4,8 @@ {} {} } +// ==== +// bytecodeFormat: legacy // ---- // digraph CFG { // nodesep=0.7; From c9466e557963237a581ec954331c74d5c1898df9 Mon Sep 17 00:00:00 2001 From: rodiazet Date: Mon, 16 Dec 2024 11:17:03 +0100 Subject: [PATCH 0780/1022] eof: Update `yulInterpreterTests` tests --- test/libyul/yulInterpreterTests/and_create.yul | 2 ++ test/libyul/yulInterpreterTests/and_create2.yul | 1 + test/libyul/yulInterpreterTests/create2.yul | 1 + test/libyul/yulInterpreterTests/datacopy.yul | 2 ++ test/libyul/yulInterpreterTests/dataoffset.yul | 2 ++ test/libyul/yulInterpreterTests/datasize.yul | 2 ++ test/libyul/yulInterpreterTests/external_call_to_self.yul | 1 + test/libyul/yulInterpreterTests/external_call_unexecuted.yul | 2 ++ .../libyul/yulInterpreterTests/external_callcode_unexecuted.yul | 2 ++ .../yulInterpreterTests/external_delegatecall_unexecuted.yul | 2 ++ .../yulInterpreterTests/external_staticcall_unexecuted.yul | 1 + test/libyul/yulInterpreterTests/long_object_name.yul | 2 ++ test/libyul/yulInterpreterTests/pop_byte_shr_call.yul | 1 + test/libyul/yulInterpreterTests/side_effect_free.yul | 1 + test/libyul/yulInterpreterTests/zero_length_reads.yul | 1 + .../libyul/yulInterpreterTests/zero_length_reads_and_revert.yul | 1 + 16 files changed, 24 insertions(+) diff --git a/test/libyul/yulInterpreterTests/and_create.yul b/test/libyul/yulInterpreterTests/and_create.yul index da962c3c0b04..5d8cd6cfde8d 100644 --- a/test/libyul/yulInterpreterTests/and_create.yul +++ b/test/libyul/yulInterpreterTests/and_create.yul @@ -4,6 +4,8 @@ let b := and(u160max, create(0, u160max, 0)) mstore(0, eq(a, b)) } +// ==== +// bytecodeFormat: legacy // ---- // Trace: // CREATE(0, 0, 0) diff --git a/test/libyul/yulInterpreterTests/and_create2.yul b/test/libyul/yulInterpreterTests/and_create2.yul index 0b83d818f087..c076c1203e11 100644 --- a/test/libyul/yulInterpreterTests/and_create2.yul +++ b/test/libyul/yulInterpreterTests/and_create2.yul @@ -6,6 +6,7 @@ } // ==== // EVMVersion: >=constantinople +// bytecodeFormat: legacy // ---- // Trace: // CREATE2(0, 0, 0, 0) diff --git a/test/libyul/yulInterpreterTests/create2.yul b/test/libyul/yulInterpreterTests/create2.yul index b7484f5db8de..ad6eb5383796 100644 --- a/test/libyul/yulInterpreterTests/create2.yul +++ b/test/libyul/yulInterpreterTests/create2.yul @@ -5,6 +5,7 @@ } // ==== // EVMVersion: >=constantinople +// bytecodeFormat: legacy // ---- // Trace: // CREATE2(0, 0, 32, 32) diff --git a/test/libyul/yulInterpreterTests/datacopy.yul b/test/libyul/yulInterpreterTests/datacopy.yul index ce5b6ce5c53a..61a3259a7c96 100644 --- a/test/libyul/yulInterpreterTests/datacopy.yul +++ b/test/libyul/yulInterpreterTests/datacopy.yul @@ -8,6 +8,8 @@ object "main" } object "sub" { code { sstore(0, 1) } } } +// ==== +// bytecodeFormat: legacy // ---- // Trace: // Memory dump: diff --git a/test/libyul/yulInterpreterTests/dataoffset.yul b/test/libyul/yulInterpreterTests/dataoffset.yul index f5a9aeb12f34..366ceb4bd273 100644 --- a/test/libyul/yulInterpreterTests/dataoffset.yul +++ b/test/libyul/yulInterpreterTests/dataoffset.yul @@ -6,6 +6,8 @@ object "main" } object "sub" { code { sstore(0, 1) } } } +// ==== +// bytecodeFormat: legacy // ---- // Trace: // Memory dump: diff --git a/test/libyul/yulInterpreterTests/datasize.yul b/test/libyul/yulInterpreterTests/datasize.yul index ff80edee7c94..f03d7083699f 100644 --- a/test/libyul/yulInterpreterTests/datasize.yul +++ b/test/libyul/yulInterpreterTests/datasize.yul @@ -6,6 +6,8 @@ object "main" } object "sub" { code { sstore(0, 1) } } } +// ==== +// bytecodeFormat: legacy // ---- // Trace: // Memory dump: diff --git a/test/libyul/yulInterpreterTests/external_call_to_self.yul b/test/libyul/yulInterpreterTests/external_call_to_self.yul index 3f5c887b4aeb..b2d69086a54f 100644 --- a/test/libyul/yulInterpreterTests/external_call_to_self.yul +++ b/test/libyul/yulInterpreterTests/external_call_to_self.yul @@ -11,6 +11,7 @@ } // ==== // simulateExternalCall: true +// bytecodeFormat: legacy // ---- // Trace: // CALL(153, 0x11111111, 0, 64, 32, 256, 32) diff --git a/test/libyul/yulInterpreterTests/external_call_unexecuted.yul b/test/libyul/yulInterpreterTests/external_call_unexecuted.yul index 0a5458b47e2f..93bb9ec03d7b 100644 --- a/test/libyul/yulInterpreterTests/external_call_unexecuted.yul +++ b/test/libyul/yulInterpreterTests/external_call_unexecuted.yul @@ -2,6 +2,8 @@ let x := call(gas(), 0x45, 0x5, 0, 0x20, 0x30, 0x20) sstore(0x64, x) } +// ==== +// bytecodeFormat: legacy // ---- // Trace: // CALL(153, 69, 5, 0, 32, 48, 32) diff --git a/test/libyul/yulInterpreterTests/external_callcode_unexecuted.yul b/test/libyul/yulInterpreterTests/external_callcode_unexecuted.yul index 5245d7443a93..5d0da5c0633e 100644 --- a/test/libyul/yulInterpreterTests/external_callcode_unexecuted.yul +++ b/test/libyul/yulInterpreterTests/external_callcode_unexecuted.yul @@ -2,6 +2,8 @@ let x := callcode(gas(), 0x45, 0x5, 0, 0x20, 0x30, 0x20) sstore(100, x) } +// ==== +// bytecodeFormat: legacy // ---- // Trace: // CALLCODE(153, 69, 5, 0, 32, 48, 32) diff --git a/test/libyul/yulInterpreterTests/external_delegatecall_unexecuted.yul b/test/libyul/yulInterpreterTests/external_delegatecall_unexecuted.yul index a827181fca2c..3e84df570931 100644 --- a/test/libyul/yulInterpreterTests/external_delegatecall_unexecuted.yul +++ b/test/libyul/yulInterpreterTests/external_delegatecall_unexecuted.yul @@ -2,6 +2,8 @@ let x := delegatecall(gas(), 0x45, 0, 0x20, 0x30, 0x20) sstore(100, x) } +// ==== +// bytecodeFormat: legacy // ---- // Trace: // DELEGATECALL(153, 69, 0, 32, 48, 32) diff --git a/test/libyul/yulInterpreterTests/external_staticcall_unexecuted.yul b/test/libyul/yulInterpreterTests/external_staticcall_unexecuted.yul index 66ea146a06ab..664692bad565 100644 --- a/test/libyul/yulInterpreterTests/external_staticcall_unexecuted.yul +++ b/test/libyul/yulInterpreterTests/external_staticcall_unexecuted.yul @@ -4,6 +4,7 @@ } // ==== // EVMVersion: >=byzantium +// bytecodeFormat: legacy // ---- // Trace: // STATICCALL(153, 69, 0, 32, 48, 32) diff --git a/test/libyul/yulInterpreterTests/long_object_name.yul b/test/libyul/yulInterpreterTests/long_object_name.yul index ede304029997..69b7acbb2bf9 100644 --- a/test/libyul/yulInterpreterTests/long_object_name.yul +++ b/test/libyul/yulInterpreterTests/long_object_name.yul @@ -13,6 +13,8 @@ object "t" { } } } +// ==== +// bytecodeFormat: legacy // ---- // Trace: // Memory dump: diff --git a/test/libyul/yulInterpreterTests/pop_byte_shr_call.yul b/test/libyul/yulInterpreterTests/pop_byte_shr_call.yul index ec9ca2fe6437..4386711a1c26 100644 --- a/test/libyul/yulInterpreterTests/pop_byte_shr_call.yul +++ b/test/libyul/yulInterpreterTests/pop_byte_shr_call.yul @@ -3,6 +3,7 @@ } // ==== // EVMVersion: >=constantinople +// bytecodeFormat: legacy // ---- // Trace: // CALL(0, 0, 0, 0, 0, 0, 0) diff --git a/test/libyul/yulInterpreterTests/side_effect_free.yul b/test/libyul/yulInterpreterTests/side_effect_free.yul index adedd299f579..d68d57364b2b 100644 --- a/test/libyul/yulInterpreterTests/side_effect_free.yul +++ b/test/libyul/yulInterpreterTests/side_effect_free.yul @@ -14,6 +14,7 @@ } // ==== // EVMVersion: >=constantinople +// bytecodeFormat: legacy // ---- // Trace: // Memory dump: diff --git a/test/libyul/yulInterpreterTests/zero_length_reads.yul b/test/libyul/yulInterpreterTests/zero_length_reads.yul index 661db49ffbb6..68cae1b92129 100644 --- a/test/libyul/yulInterpreterTests/zero_length_reads.yul +++ b/test/libyul/yulInterpreterTests/zero_length_reads.yul @@ -18,6 +18,7 @@ } // ==== // EVMVersion: >=constantinople +// bytecodeFormat: legacy // ---- // Trace: // RETURNDATACOPY(0, 1, 0) diff --git a/test/libyul/yulInterpreterTests/zero_length_reads_and_revert.yul b/test/libyul/yulInterpreterTests/zero_length_reads_and_revert.yul index 0d0f92420e30..c9143d7918f5 100644 --- a/test/libyul/yulInterpreterTests/zero_length_reads_and_revert.yul +++ b/test/libyul/yulInterpreterTests/zero_length_reads_and_revert.yul @@ -18,6 +18,7 @@ } // ==== // EVMVersion: >=constantinople +// bytecodeFormat: legacy // ---- // Trace: // RETURNDATACOPY(0, 1, 0) From 6ea1dce9e86f2d78a532636366aff5f5e10c09bd Mon Sep 17 00:00:00 2001 From: Martin Blicha Date: Fri, 31 Jan 2025 22:06:59 +0100 Subject: [PATCH 0781/1022] SMTChecker: Fix parsing bv2int expression from solver's response --- libsmtutil/CHCSmtLib2Interface.cpp | 5 +++++ .../solver_response_involves_bv2int.sol | 16 ++++++++++++++++ 2 files changed, 21 insertions(+) create mode 100644 test/libsolidity/smtCheckerTests/invariants/solver_response_involves_bv2int.sol diff --git a/libsmtutil/CHCSmtLib2Interface.cpp b/libsmtutil/CHCSmtLib2Interface.cpp index f9bb3b8f60b7..6b0534296f29 100644 --- a/libsmtutil/CHCSmtLib2Interface.cpp +++ b/libsmtutil/CHCSmtLib2Interface.cpp @@ -365,6 +365,11 @@ smtutil::Expression CHCSmtLib2Interface::ScopedParser::toSMTUtilExpression(SMTLi smtSolverInteractionRequire(arguments.size() == 3, "Store has three arguments: array, index and element"); return smtutil::Expression::store(arguments[0], arguments[1], arguments[2]); } + if (op == "bv2int") + { + smtSolverInteractionRequire(arguments.size() == 1, "bv2int has one argument"); + return smtutil::Expression::bv2int(arguments[0]); + } else { std::set boolOperators{"and", "or", "not", "=", "<", ">", "<=", ">=", "=>"}; diff --git a/test/libsolidity/smtCheckerTests/invariants/solver_response_involves_bv2int.sol b/test/libsolidity/smtCheckerTests/invariants/solver_response_involves_bv2int.sol new file mode 100644 index 000000000000..54609b86a23c --- /dev/null +++ b/test/libsolidity/smtCheckerTests/invariants/solver_response_involves_bv2int.sol @@ -0,0 +1,16 @@ +// Taken from issue #15770 +contract c { + function f(uint len) public pure returns (bytes memory) { + bytes memory x = new bytes(len); + for (uint i = 0; i < len; i++) { + x[i] = bytes1(uint8(i)); + } + return x; + } +} +// ==== +// SMTEngine: chc +// SMTIgnoreInv: no +// SMTSolvers: z3 +// ---- +// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. From b14c7efe3f0f091d324b1271d225337dd298d2d8 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Sun, 26 Jan 2025 08:37:25 +0100 Subject: [PATCH 0782/1022] StringUtils: Compatibility of joinHumanReadable with string_view --- libsolutil/StringUtils.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/libsolutil/StringUtils.h b/libsolutil/StringUtils.h index 77ffe6735401..763f1ea64f41 100644 --- a/libsolutil/StringUtils.h +++ b/libsolutil/StringUtils.h @@ -67,24 +67,24 @@ std::string joinHumanReadable { auto const itEnd = end(_list); - std::string result; + std::stringstream result; for (auto it = begin(_list); it != itEnd; ) { - std::string element = *it; + auto const& element = *it; bool first = (it == begin(_list)); ++it; if (!first) { if (it == itEnd && !_lastSeparator.empty()) - result += _lastSeparator; // last iteration + result << _lastSeparator; // last iteration else - result += _separator; + result << _separator; } - result += std::move(element); + result << element; } - return result; + return result.str(); } /// Joins collection of strings just like joinHumanReadable, but prepends the separator From 78ec8dd6f93bf5a5b4ca7582f9d491a4f66c3610 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Mon, 3 Feb 2025 11:46:27 +0100 Subject: [PATCH 0783/1022] Token: Use string view for isYulKeyword --- liblangutil/Token.cpp | 6 +++--- liblangutil/Token.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/liblangutil/Token.cpp b/liblangutil/Token.cpp index 8a860791fa45..1c5ae6f4e707 100644 --- a/liblangutil/Token.cpp +++ b/liblangutil/Token.cpp @@ -134,20 +134,20 @@ std::string friendlyName(Token tok) } -static Token keywordByName(std::string const& _name) +static Token keywordByName(std::string_view const _name) { // The following macros are used inside TOKEN_LIST and cause non-keyword tokens to be ignored // and keywords to be put inside the keywords variable. #define KEYWORD(name, string, precedence) {string, Token::name}, #define TOKEN(name, string, precedence) - static std::map const keywords({TOKEN_LIST(TOKEN, KEYWORD)}); + static std::map> const keywords({TOKEN_LIST(TOKEN, KEYWORD)}); #undef KEYWORD #undef TOKEN auto it = keywords.find(_name); return it == keywords.end() ? Token::Identifier : it->second; } -bool isYulKeyword(std::string const& _literal) +bool isYulKeyword(std::string_view const _literal) { return _literal == "leave" || isYulKeyword(keywordByName(_literal)); } diff --git a/liblangutil/Token.h b/liblangutil/Token.h index d9438271ca6a..bfbc89bb4839 100644 --- a/liblangutil/Token.h +++ b/liblangutil/Token.h @@ -377,7 +377,7 @@ namespace TokenTraits return _token > Token::NonExperimentalEnd && _token < Token::ExperimentalEnd; } - bool isYulKeyword(std::string const& _literal); + bool isYulKeyword(std::string_view _literal); Token AssignmentToBinaryOp(Token op); From 40aad416cfe76095d9b216093996cdcaaa6b7f17 Mon Sep 17 00:00:00 2001 From: rodiazet Date: Mon, 3 Feb 2025 11:54:12 +0100 Subject: [PATCH 0784/1022] Enable default test running for EOF --- test/TestCase.cpp | 2 +- test/libsolidity/SemanticTest.cpp | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/test/TestCase.cpp b/test/TestCase.cpp index 9505a2caafe5..104bd1bdeefb 100644 --- a/test/TestCase.cpp +++ b/test/TestCase.cpp @@ -150,7 +150,7 @@ void EVMVersionRestrictedTestCase::processBytecodeFormatSetting() // EOF only available since Prague solAssert(!eofVersion.has_value() ||solidity::test::CommonOptions::get().evmVersion() >= langutil::EVMVersion::prague()); - std::string bytecodeFormatString = m_reader.stringSetting("bytecodeFormat", "legacy"); + std::string bytecodeFormatString = m_reader.stringSetting("bytecodeFormat", "legacy,>=EOFv1"); if (bytecodeFormatString == "legacy,>=EOFv1" || bytecodeFormatString == ">=EOFv1,legacy") return; diff --git a/test/libsolidity/SemanticTest.cpp b/test/libsolidity/SemanticTest.cpp index b0bdb95cb9c4..0c3f2f3bcbdd 100644 --- a/test/libsolidity/SemanticTest.cpp +++ b/test/libsolidity/SemanticTest.cpp @@ -91,7 +91,9 @@ SemanticTest::SemanticTest( if (m_runWithABIEncoderV1Only && !solidity::test::CommonOptions::get().useABIEncoderV1) m_shouldRun = false; - std::string compileViaYul = m_reader.stringSetting("compileViaYul", "also"); + auto const eofEnabled = solidity::test::CommonOptions::get().eofVersion().has_value(); + std::string compileViaYul = m_reader.stringSetting("compileViaYul", eofEnabled ? "true" : "also"); + if (m_runWithABIEncoderV1Only && compileViaYul != "false") BOOST_THROW_EXCEPTION(std::runtime_error( "ABIEncoderV1Only tests cannot be run via yul, " From 055561815b35c77ef71cc143027431f03566115d Mon Sep 17 00:00:00 2001 From: rodiazet Date: Mon, 3 Feb 2025 11:54:12 +0100 Subject: [PATCH 0785/1022] Omit running semantic and syntax tests when compileViaYul is false and EFO enabled. --- test/libsolidity/SemanticTest.cpp | 3 +++ test/libsolidity/SyntaxTest.cpp | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/test/libsolidity/SemanticTest.cpp b/test/libsolidity/SemanticTest.cpp index 0c3f2f3bcbdd..1b66dd60fffb 100644 --- a/test/libsolidity/SemanticTest.cpp +++ b/test/libsolidity/SemanticTest.cpp @@ -94,6 +94,9 @@ SemanticTest::SemanticTest( auto const eofEnabled = solidity::test::CommonOptions::get().eofVersion().has_value(); std::string compileViaYul = m_reader.stringSetting("compileViaYul", eofEnabled ? "true" : "also"); + if (compileViaYul == "false" && eofEnabled) + m_shouldRun = false; + if (m_runWithABIEncoderV1Only && compileViaYul != "false") BOOST_THROW_EXCEPTION(std::runtime_error( "ABIEncoderV1Only tests cannot be run via yul, " diff --git a/test/libsolidity/SyntaxTest.cpp b/test/libsolidity/SyntaxTest.cpp index 4fd3df7cfc6f..8944710542a5 100644 --- a/test/libsolidity/SyntaxTest.cpp +++ b/test/libsolidity/SyntaxTest.cpp @@ -53,6 +53,10 @@ SyntaxTest::SyntaxTest( m_compileViaYul = m_reader.stringSetting("compileViaYul", eofEnabled ? "true" : "false"); if (!util::contains(compileViaYulAllowedValues, m_compileViaYul)) BOOST_THROW_EXCEPTION(std::runtime_error("Invalid compileViaYul value: " + m_compileViaYul + ".")); + + if (m_compileViaYul == "false" && eofEnabled) + m_shouldRun = false; + m_optimiseYul = m_reader.boolSetting("optimize-yul", true); static std::map const pipelineStages = { From 934716b68529dbea6dc09d066d6cc8806c4e1811 Mon Sep 17 00:00:00 2001 From: Martin Blicha Date: Mon, 3 Feb 2025 14:46:48 +0100 Subject: [PATCH 0786/1022] SMTChecker: Fix crash on external function call wrapped in 1-tuple The function call needs to be unwrapped from within nested parentheses to get the proper call expression. --- Changelog.md | 1 + libsolidity/formal/SMTEncoder.cpp | 2 +- .../external_call_extra_parentheses_1.sol | 9 +++++++++ .../external_call_extra_parentheses_2.sol | 12 ++++++++++++ 4 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 test/libsolidity/smtCheckerTests/external_calls/external_call_extra_parentheses_1.sol create mode 100644 test/libsolidity/smtCheckerTests/external_calls/external_call_extra_parentheses_2.sol diff --git a/Changelog.md b/Changelog.md index cceec2a73de0..cde5636cfea1 100644 --- a/Changelog.md +++ b/Changelog.md @@ -13,6 +13,7 @@ Compiler Features: Bugfixes: * General: Fix internal compiler error when requesting IR AST outputs for interfaces and abstract contracts. * SMTChecker: Fix SMT logic error when analyzing cross-contract getter call with BMC. + * SMTChecker: Fix SMT logic error when external call has extra effectless parentheses. * SMTChecker: Fix SMT logic error when initializing a fixed-sized-bytes array using string literals. * SMTChecker: Fix SMT logic error when translating invariants involving array store and select operations. * SMTChecker: Fix wrong encoding of string literals as arguments of ``ecrecover`` precompile. diff --git a/libsolidity/formal/SMTEncoder.cpp b/libsolidity/formal/SMTEncoder.cpp index 2fecb734a630..08fd4a256e38 100644 --- a/libsolidity/formal/SMTEncoder.cpp +++ b/libsolidity/formal/SMTEncoder.cpp @@ -2771,7 +2771,7 @@ TypePointers SMTEncoder::replaceUserTypes(TypePointers const& _types) std::pair SMTEncoder::functionCallExpression(FunctionCall const& _funCall) { - Expression const* callExpr = &_funCall.expression(); + Expression const* callExpr = innermostTuple(_funCall.expression()); auto const* callOptions = dynamic_cast(callExpr); if (callOptions) callExpr = &callOptions->expression(); diff --git a/test/libsolidity/smtCheckerTests/external_calls/external_call_extra_parentheses_1.sol b/test/libsolidity/smtCheckerTests/external_calls/external_call_extra_parentheses_1.sol new file mode 100644 index 000000000000..a071d0f150cc --- /dev/null +++ b/test/libsolidity/smtCheckerTests/external_calls/external_call_extra_parentheses_1.sol @@ -0,0 +1,9 @@ +contract C { + function f() external {} + function g() public { + (this.f)(); + } +} +// ==== +// SMTEngine: chc +// ---- diff --git a/test/libsolidity/smtCheckerTests/external_calls/external_call_extra_parentheses_2.sol b/test/libsolidity/smtCheckerTests/external_calls/external_call_extra_parentheses_2.sol new file mode 100644 index 000000000000..bbff78aa73f3 --- /dev/null +++ b/test/libsolidity/smtCheckerTests/external_calls/external_call_extra_parentheses_2.sol @@ -0,0 +1,12 @@ +contract D { + function f() external {} +} + +contract C { + function g(D d) public { + ((d.f))(); + } +} +// ==== +// SMTEngine: chc +// ---- From 4c3b26ddc35971081c460f69cd09cef6c4211b7e Mon Sep 17 00:00:00 2001 From: Martin Blicha Date: Mon, 3 Feb 2025 14:52:21 +0100 Subject: [PATCH 0787/1022] SMTChecker: Small cleanup of handling function calls A redundant lambda has been removed. The same function is actually defined as a member of SMTEncoder An error message has been improved. --- libsolidity/formal/CHC.cpp | 11 ----------- libsolidity/formal/SMTEncoder.cpp | 2 +- 2 files changed, 1 insertion(+), 12 deletions(-) diff --git a/libsolidity/formal/CHC.cpp b/libsolidity/formal/CHC.cpp index dd901bc38314..d5a1fa580993 100644 --- a/libsolidity/formal/CHC.cpp +++ b/libsolidity/formal/CHC.cpp @@ -927,17 +927,6 @@ void CHC::internalFunctionCall(FunctionCall const& _funCall) Expression const* calledExpr = &_funCall.expression(); auto funType = dynamic_cast(calledExpr->annotation().type); - auto contractAddressValue = [this](FunctionCall const& _f) { - auto [callExpr, callOptions] = functionCallExpression(_f); - - FunctionType const& funType = dynamic_cast(*callExpr->annotation().type); - if (funType.kind() == FunctionType::Kind::Internal) - return state().thisAddress(); - if (MemberAccess const* callBase = dynamic_cast(callExpr)) - return expr(callBase->expression()); - solAssert(false, "Unreachable!"); - }; - std::vector arguments; for (auto& arg: _funCall.sortedArguments()) arguments.push_back(&(*arg)); diff --git a/libsolidity/formal/SMTEncoder.cpp b/libsolidity/formal/SMTEncoder.cpp index 08fd4a256e38..c1a4d61ee145 100644 --- a/libsolidity/formal/SMTEncoder.cpp +++ b/libsolidity/formal/SMTEncoder.cpp @@ -2869,7 +2869,7 @@ smtutil::Expression SMTEncoder::contractAddressValue(FunctionCall const& _f) auto [funExpr, funOptions] = functionCallExpression(_f); if (MemberAccess const* callBase = dynamic_cast(funExpr)) return expr(callBase->expression()); - solAssert(false, "Unreachable!"); + smtAssert(false, "Unexpected function call type encountered while getting contract address!"); } VariableDeclaration const* SMTEncoder::publicGetter(Expression const& _expr) const { From f9adfa326092cb3814d3392f120a70ab90ec7841 Mon Sep 17 00:00:00 2001 From: Martin Blicha Date: Tue, 4 Feb 2025 21:24:32 +0100 Subject: [PATCH 0788/1022] SMTChecker: Make innermostTuple return reference Instead of returning a pointer, to indicate that the method always returns a valid value (and does not need a check for null pointer), we can return a reference. As part of the refactoring, we can actually eliminate one usage of this method. --- libsolidity/formal/Predicate.cpp | 29 +++++-------- libsolidity/formal/SMTEncoder.cpp | 72 +++++++++++++++---------------- libsolidity/formal/SMTEncoder.h | 2 +- 3 files changed, 48 insertions(+), 55 deletions(-) diff --git a/libsolidity/formal/Predicate.cpp b/libsolidity/formal/Predicate.cpp index fe7c03fe1238..4b7ca8edb324 100644 --- a/libsolidity/formal/Predicate.cpp +++ b/libsolidity/formal/Predicate.cpp @@ -247,24 +247,17 @@ std::string Predicate::formatSummaryCall( { bool visit(MemberAccess const& _memberAccess) { - Expression const* memberExpr = SMTEncoder::innermostTuple(_memberAccess.expression()); - - Type const* exprType = memberExpr->annotation().type; - solAssert(exprType, ""); - if (exprType->category() == Type::Category::Magic) - if (auto const* identifier = dynamic_cast(memberExpr)) - { - ASTString const& name = identifier->name(); - auto memberName = _memberAccess.memberName(); - - // TODO remove this for 0.9.0 - if (name == "block" && memberName == "difficulty") - memberName = "prevrandao"; - - if (name == "block" || name == "msg" || name == "tx") - txVars.insert(name + "." + memberName); - } - + if (auto magicType = dynamic_cast(_memberAccess.expression().annotation().type)) + { + auto memberName = _memberAccess.memberName(); + auto magicKind = magicType->kind(); + // TODO remove this for 0.9.0 + if (magicKind == MagicType::Kind::Block && memberName == "difficulty") + memberName = "prevrandao"; + + if (magicKind == MagicType::Kind::Block || magicKind == MagicType::Kind::Message || magicKind == MagicType::Kind::Transaction) + txVars.insert(magicType->toString(true) + "." + memberName); + } return true; } diff --git a/libsolidity/formal/SMTEncoder.cpp b/libsolidity/formal/SMTEncoder.cpp index c1a4d61ee145..7c826ab36b21 100644 --- a/libsolidity/formal/SMTEncoder.cpp +++ b/libsolidity/formal/SMTEncoder.cpp @@ -465,22 +465,22 @@ void SMTEncoder::endVisit(UnaryOperation const& _op) if (*_op.annotation().userDefinedFunction) return; - auto const* subExpr = innermostTuple(_op.subExpression()); + auto const& subExpr = innermostTuple(_op.subExpression()); auto type = _op.annotation().type; switch (_op.getOperator()) { case Token::Not: // ! { solAssert(smt::isBool(*type), ""); - defineExpr(_op, !expr(*subExpr)); + defineExpr(_op, !expr(subExpr)); break; } case Token::Inc: // ++ (pre- or postfix) case Token::Dec: // -- (pre- or postfix) { solAssert(smt::isInteger(*type) || smt::isFixedPoint(*type), ""); - solAssert(subExpr->annotation().willBeWrittenTo, ""); - auto innerValue = expr(*subExpr); + solAssert(subExpr.annotation().willBeWrittenTo, ""); + auto innerValue = expr(subExpr); auto newValue = arithmeticOperation( _op.getOperator() == Token::Inc ? Token::Add : Token::Sub, innerValue, @@ -489,34 +489,34 @@ void SMTEncoder::endVisit(UnaryOperation const& _op) _op ).first; defineExpr(_op, _op.isPrefixOperation() ? newValue : innerValue); - assignment(*subExpr, newValue); + assignment(subExpr, newValue); break; } case Token::Sub: // - { - defineExpr(_op, 0 - expr(*subExpr)); + defineExpr(_op, 0 - expr(subExpr)); break; } case Token::Delete: { - if (auto decl = identifierToVariable(*subExpr)) + if (auto decl = identifierToVariable(subExpr)) { m_context.newValue(*decl); m_context.setZeroValue(*decl); } else { - solAssert(m_context.knownExpression(*subExpr), ""); - auto const& symbVar = m_context.expression(*subExpr); + solAssert(m_context.knownExpression(subExpr), ""); + auto const& symbVar = m_context.expression(subExpr); symbVar->increaseIndex(); m_context.setZeroValue(*symbVar); if ( - dynamic_cast(subExpr) || - dynamic_cast(subExpr) + dynamic_cast(&subExpr) || + dynamic_cast(&subExpr) ) - indexOrMemberAssignment(*subExpr, symbVar->currentValue()); + indexOrMemberAssignment(subExpr, symbVar->currentValue()); // Empty push added a zero value anyway, so no need to delete extra. - else if (!isEmptyPush(*subExpr)) + else if (!isEmptyPush(subExpr)) solAssert(false, ""); } break; @@ -1398,14 +1398,14 @@ bool SMTEncoder::visit(MemberAccess const& _memberAccess) return true; } - Expression const* memberExpr = innermostTuple(_memberAccess.expression()); + Expression const& memberExpr = innermostTuple(_memberAccess.expression()); - auto const& exprType = memberExpr->annotation().type; + auto const& exprType = memberExpr.annotation().type; solAssert(exprType, ""); if (exprType->category() == Type::Category::Magic) { - if (auto const* identifier = dynamic_cast(memberExpr)) + if (auto const* identifier = dynamic_cast(&memberExpr)) { auto const& name = identifier->name(); solAssert(name == "block" || name == "msg" || name == "tx", ""); @@ -1458,14 +1458,14 @@ bool SMTEncoder::visit(MemberAccess const& _memberAccess) } else if (smt::isNonRecursiveStruct(*exprType)) { - memberExpr->accept(*this); - auto const& symbStruct = std::dynamic_pointer_cast(m_context.expression(*memberExpr)); + memberExpr.accept(*this); + auto const& symbStruct = std::dynamic_pointer_cast(m_context.expression(memberExpr)); defineExpr(_memberAccess, symbStruct->member(_memberAccess.memberName())); return false; } else if (exprType->category() == Type::Category::TypeType) { - auto const* decl = expressionToDeclaration(*memberExpr); + auto const* decl = expressionToDeclaration(memberExpr); if (dynamic_cast(decl)) { auto enumType = dynamic_cast(accessType); @@ -1488,10 +1488,10 @@ bool SMTEncoder::visit(MemberAccess const& _memberAccess) } else if (exprType->category() == Type::Category::Address) { - memberExpr->accept(*this); + memberExpr.accept(*this); if (_memberAccess.memberName() == "balance") { - defineExpr(_memberAccess, state().balance(expr(*memberExpr))); + defineExpr(_memberAccess, state().balance(expr(memberExpr))); setSymbolicUnknownValue(*m_context.expression(_memberAccess), m_context); m_uninterpretedTerms.insert(&_memberAccess); return false; @@ -1499,10 +1499,10 @@ bool SMTEncoder::visit(MemberAccess const& _memberAccess) } else if (exprType->category() == Type::Category::Array) { - memberExpr->accept(*this); + memberExpr.accept(*this); if (_memberAccess.memberName() == "length") { - auto symbArray = std::dynamic_pointer_cast(m_context.expression(*memberExpr)); + auto symbArray = std::dynamic_pointer_cast(m_context.expression(memberExpr)); solAssert(symbArray, ""); defineExpr(_memberAccess, symbArray->length()); m_uninterpretedTerms.insert(&_memberAccess); @@ -2174,16 +2174,16 @@ void SMTEncoder::assignment( void SMTEncoder::tupleAssignment(Expression const& _left, Expression const& _right) { - auto lTuple = dynamic_cast(innermostTuple(_left)); + auto lTuple = dynamic_cast(&innermostTuple(_left)); solAssert(lTuple, ""); - Expression const* right = innermostTuple(_right); + Expression const& right = innermostTuple(_right); auto const& lComponents = lTuple->components(); // If both sides are tuple expressions, we individually and potentially // recursively assign each pair of components. // This is because of potential type conversion. - if (auto rTuple = dynamic_cast(right)) + if (auto rTuple = dynamic_cast(&right)) { auto const& rComponents = rTuple->components(); solAssert(lComponents.size() == rComponents.size(), ""); @@ -2204,13 +2204,13 @@ void SMTEncoder::tupleAssignment(Expression const& _left, Expression const& _rig } else { - auto rType = dynamic_cast(right->annotation().type); + auto rType = dynamic_cast(right.annotation().type); solAssert(rType, ""); auto const& rComponents = rType->components(); solAssert(lComponents.size() == rComponents.size(), ""); - auto symbRight = expr(*right); + auto symbRight = expr(right); solAssert(symbRight.sort->kind == smtutil::Kind::Tuple, ""); for (unsigned i = 0; i < lComponents.size(); ++i) @@ -2737,11 +2737,11 @@ Type const* SMTEncoder::keyType(Type const* _type) solAssert(false, ""); } -Expression const* SMTEncoder::innermostTuple(Expression const& _expr) +Expression const& SMTEncoder::innermostTuple(Expression const& _expr) { auto const* tuple = dynamic_cast(&_expr); if (!tuple || tuple->isInlineArray()) - return &_expr; + return _expr; Expression const* expr = tuple; while (tuple && !tuple->isInlineArray() && tuple->components().size() == 1) @@ -2750,7 +2750,7 @@ Expression const* SMTEncoder::innermostTuple(Expression const& _expr) tuple = dynamic_cast(expr); } solAssert(expr, ""); - return expr; + return *expr; } Type const* SMTEncoder::underlyingType(Type const* _type) @@ -2771,7 +2771,7 @@ TypePointers SMTEncoder::replaceUserTypes(TypePointers const& _types) std::pair SMTEncoder::functionCallExpression(FunctionCall const& _funCall) { - Expression const* callExpr = innermostTuple(_funCall.expression()); + Expression const* callExpr = &innermostTuple(_funCall.expression()); auto const* callOptions = dynamic_cast(callExpr); if (callOptions) callExpr = &callOptions->expression(); @@ -2783,7 +2783,7 @@ Expression const* SMTEncoder::cleanExpression(Expression const& _expr) { auto const* expr = &_expr; if (auto const* tuple = dynamic_cast(expr)) - return cleanExpression(*innermostTuple(*tuple)); + return cleanExpression(innermostTuple(*tuple)); if (auto const* functionCall = dynamic_cast(expr)) if (*functionCall->annotation().kind == FunctionCallKind::TypeConversion) { @@ -2918,7 +2918,7 @@ FunctionDefinition const* SMTEncoder::functionCallToDefinition( if (TupleExpression const* fun = dynamic_cast(calledExpr)) { solAssert(fun->components().size() == 1, ""); - calledExpr = innermostTuple(*calledExpr); + calledExpr = &innermostTuple(*calledExpr); } auto resolveVirtual = [&](auto const* _ref) -> FunctionDefinition const* { @@ -3220,8 +3220,8 @@ std::vector SMTEncoder::symbolicArguments( unsigned firstParam = 0; if (_boundArgumentCall) { - Expression const* calledExpr = innermostTuple(*_boundArgumentCall.value()); - auto const& attachedFunction = dynamic_cast(calledExpr); + Expression const& calledExpr = innermostTuple(*_boundArgumentCall.value()); + auto const& attachedFunction = dynamic_cast(&calledExpr); solAssert(attachedFunction, ""); args.push_back(expr(attachedFunction->expression(), _funParameters.front()->type())); firstParam = 1; diff --git a/libsolidity/formal/SMTEncoder.h b/libsolidity/formal/SMTEncoder.h index d79ae8f82aaa..c6c549151058 100644 --- a/libsolidity/formal/SMTEncoder.h +++ b/libsolidity/formal/SMTEncoder.h @@ -71,7 +71,7 @@ class SMTEncoder: public ASTConstVisitor /// @returns the innermost element in a chain of 1-tuples if applicable, /// otherwise _expr. - static Expression const* innermostTuple(Expression const& _expr); + static Expression const& innermostTuple(Expression const& _expr); /// @returns the underlying type if _type is UserDefinedValueType, /// and _type otherwise. From bbb0caaaf9a570351e03064e402d959125a6b6b2 Mon Sep 17 00:00:00 2001 From: Martin Blicha Date: Tue, 4 Feb 2025 13:06:27 +0100 Subject: [PATCH 0789/1022] SMTChecker: Fix internal error involving string to bytes conversion This happened when analyzing deployment of a contract and the type conversion was necessary for the constructor argument. --- Changelog.md | 1 + libsolidity/formal/CHC.cpp | 2 +- ...fixed_bytes_constructor_for_deployment.sol | 21 +++++++++++++++++++ 3 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 test/libsolidity/smtCheckerTests/typecast/string_literal_to_fixed_bytes_constructor_for_deployment.sol diff --git a/Changelog.md b/Changelog.md index cde5636cfea1..be3209702455 100644 --- a/Changelog.md +++ b/Changelog.md @@ -13,6 +13,7 @@ Compiler Features: Bugfixes: * General: Fix internal compiler error when requesting IR AST outputs for interfaces and abstract contracts. * SMTChecker: Fix SMT logic error when analyzing cross-contract getter call with BMC. + * SMTChecker: Fix SMT logic error when contract deployment involves string literal to fixed bytes conversion. * SMTChecker: Fix SMT logic error when external call has extra effectless parentheses. * SMTChecker: Fix SMT logic error when initializing a fixed-sized-bytes array using string literals. * SMTChecker: Fix SMT logic error when translating invariants involving array store and select operations. diff --git a/libsolidity/formal/CHC.cpp b/libsolidity/formal/CHC.cpp index d5a1fa580993..bd3b0d9888fe 100644 --- a/libsolidity/formal/CHC.cpp +++ b/libsolidity/formal/CHC.cpp @@ -854,7 +854,7 @@ void CHC::visitDeployment(FunctionCall const& _funCall) auto const& params = constructor->parameters(); solAssert(args.size() == params.size(), ""); for (auto [arg, param]: ranges::zip_view(args, params)) - m_context.addAssertion(expr(*arg) == m_context.variable(*param)->currentValue()); + m_context.addAssertion(expr(*arg, param->type()) == m_context.variable(*param)->currentValue()); } for (auto var: stateVariablesIncludingInheritedAndPrivate(*contract)) m_context.variable(*var)->increaseIndex(); diff --git a/test/libsolidity/smtCheckerTests/typecast/string_literal_to_fixed_bytes_constructor_for_deployment.sol b/test/libsolidity/smtCheckerTests/typecast/string_literal_to_fixed_bytes_constructor_for_deployment.sol new file mode 100644 index 000000000000..5226f886d959 --- /dev/null +++ b/test/libsolidity/smtCheckerTests/typecast/string_literal_to_fixed_bytes_constructor_for_deployment.sol @@ -0,0 +1,21 @@ +contract A { + bytes3 public a; + + constructor(bytes3 _a) payable { + a = _a; + } +} + +contract B { + A a; + + constructor() payable { + a = (new A){value: 10}("abc"); + assert(a.a() == 0x616263); + } +} +// ==== +// SMTEngine: chc +// SMTExtCalls: trusted +// ---- +// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. From 455da960987d47b95cc137b42d75bb4c889a689b Mon Sep 17 00:00:00 2001 From: r0qs Date: Wed, 22 Jan 2025 21:44:34 +0100 Subject: [PATCH 0790/1022] Bump evmone to v0.13.0 in buildpack-deps --- .../docker/buildpack-deps/Dockerfile.ubuntu.clang.ossfuzz | 4 ++-- scripts/docker/buildpack-deps/Dockerfile.ubuntu2204 | 6 +++--- scripts/docker/buildpack-deps/Dockerfile.ubuntu2404 | 6 +++--- scripts/docker/buildpack-deps/Dockerfile.ubuntu2404.clang | 6 +++--- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/scripts/docker/buildpack-deps/Dockerfile.ubuntu.clang.ossfuzz b/scripts/docker/buildpack-deps/Dockerfile.ubuntu.clang.ossfuzz index 1dbf48e9b45f..b5cd64a235e0 100644 --- a/scripts/docker/buildpack-deps/Dockerfile.ubuntu.clang.ossfuzz +++ b/scripts/docker/buildpack-deps/Dockerfile.ubuntu.clang.ossfuzz @@ -24,7 +24,7 @@ # FIXME: Workaround for Boost 1.83.0 build failure when using Clang 18 (default since https://github.com/google/oss-fuzz/pull/11714) # See: https://github.com/google/oss-fuzz/blob/5a9322260c4c66e7eb3e5d922b9fee6621ffd8da/projects/solidity/Dockerfile#L17C1-L18C139 FROM gcr.io/oss-fuzz-base/base-builder@sha256:19782f7fe8092843368894dbc471ce9b30dd6a2813946071a36e8b05f5b1e27e AS base -LABEL version="9" +LABEL version="10" ARG DEBIAN_FRONTEND=noninteractive @@ -130,7 +130,7 @@ RUN set -ex; \ # EVMONE RUN set -ex; \ cd /usr/src; \ - git clone --branch="v0.11.0" --recurse-submodules https://github.com/ethereum/evmone.git; \ + git clone --branch="v0.13.0" --recurse-submodules https://github.com/ethereum/evmone.git; \ cd evmone; \ mkdir build; \ cd build; \ diff --git a/scripts/docker/buildpack-deps/Dockerfile.ubuntu2204 b/scripts/docker/buildpack-deps/Dockerfile.ubuntu2204 index 9b365a374a07..f66c1d8fd07f 100644 --- a/scripts/docker/buildpack-deps/Dockerfile.ubuntu2204 +++ b/scripts/docker/buildpack-deps/Dockerfile.ubuntu2204 @@ -22,7 +22,7 @@ # (c) 2016-2025 solidity contributors. #------------------------------------------------------------------------------ FROM buildpack-deps:jammy AS base -LABEL version="1" +LABEL version="2" ARG DEBIAN_FRONTEND=noninteractive @@ -94,8 +94,8 @@ FROM base AS libraries # EVMONE RUN set -ex; \ - wget -O /usr/src/evmone.tar.gz https://github.com/ethereum/evmone/releases/download/v0.12.0/evmone-0.12.0-linux-x86_64.tar.gz; \ - test "$(sha256sum /usr/src/evmone.tar.gz)" = "1c7b5eba0c8c3b3b2a7a05101e2d01a13a2f84b323989a29be66285dba4136ce /usr/src/evmone.tar.gz"; \ + wget -O /usr/src/evmone.tar.gz https://github.com/ethereum/evmone/releases/download/v0.13.0/evmone-0.13.0-linux-x86_64.tar.gz; \ + test "$(sha256sum /usr/src/evmone.tar.gz)" = "94efc7fa27ff94018003ad95a62c20b17a45f027d434eb642c8e345e8d4d3cad /usr/src/evmone.tar.gz"; \ cd /usr; \ tar -xf /usr/src/evmone.tar.gz; \ rm -rf /usr/src/evmone.tar.gz diff --git a/scripts/docker/buildpack-deps/Dockerfile.ubuntu2404 b/scripts/docker/buildpack-deps/Dockerfile.ubuntu2404 index eb5439f595be..fc372c709ae2 100644 --- a/scripts/docker/buildpack-deps/Dockerfile.ubuntu2404 +++ b/scripts/docker/buildpack-deps/Dockerfile.ubuntu2404 @@ -22,7 +22,7 @@ # (c) 2016-2024 solidity contributors. #------------------------------------------------------------------------------ FROM buildpack-deps:noble AS base -LABEL version="2" +LABEL version="3" ARG DEBIAN_FRONTEND=noninteractive @@ -97,8 +97,8 @@ FROM base AS libraries # EVMONE RUN set -ex; \ - wget -O /usr/src/evmone.tar.gz https://github.com/ethereum/evmone/releases/download/v0.12.0/evmone-0.12.0-linux-x86_64.tar.gz; \ - test "$(sha256sum /usr/src/evmone.tar.gz)" = "1c7b5eba0c8c3b3b2a7a05101e2d01a13a2f84b323989a29be66285dba4136ce /usr/src/evmone.tar.gz"; \ + wget -O /usr/src/evmone.tar.gz https://github.com/ethereum/evmone/releases/download/v0.13.0/evmone-0.13.0-linux-x86_64.tar.gz; \ + test "$(sha256sum /usr/src/evmone.tar.gz)" = "94efc7fa27ff94018003ad95a62c20b17a45f027d434eb642c8e345e8d4d3cad /usr/src/evmone.tar.gz"; \ cd /usr; \ tar -xf /usr/src/evmone.tar.gz; \ rm -rf /usr/src/evmone.tar.gz diff --git a/scripts/docker/buildpack-deps/Dockerfile.ubuntu2404.clang b/scripts/docker/buildpack-deps/Dockerfile.ubuntu2404.clang index 3b1e3e614d4e..91a31c26300a 100644 --- a/scripts/docker/buildpack-deps/Dockerfile.ubuntu2404.clang +++ b/scripts/docker/buildpack-deps/Dockerfile.ubuntu2404.clang @@ -22,7 +22,7 @@ # (c) 2016-2024 solidity contributors. #------------------------------------------------------------------------------ FROM buildpack-deps:noble AS base -LABEL version="3" +LABEL version="4" ARG DEBIAN_FRONTEND=noninteractive @@ -99,8 +99,8 @@ ENV CXX clang++ # EVMONE RUN set -ex; \ - wget -O /usr/src/evmone.tar.gz https://github.com/ethereum/evmone/releases/download/v0.12.0/evmone-0.12.0-linux-x86_64.tar.gz; \ - test "$(sha256sum /usr/src/evmone.tar.gz)" = "1c7b5eba0c8c3b3b2a7a05101e2d01a13a2f84b323989a29be66285dba4136ce /usr/src/evmone.tar.gz"; \ + wget -O /usr/src/evmone.tar.gz https://github.com/ethereum/evmone/releases/download/v0.13.0/evmone-0.13.0-linux-x86_64.tar.gz; \ + test "$(sha256sum /usr/src/evmone.tar.gz)" = "94efc7fa27ff94018003ad95a62c20b17a45f027d434eb642c8e345e8d4d3cad /usr/src/evmone.tar.gz"; \ cd /usr; \ tar -xf /usr/src/evmone.tar.gz; \ rm -rf /usr/src/evmone.tar.gz From 6135aa167c431ddec6f08d531182daf868f87a95 Mon Sep 17 00:00:00 2001 From: r0qs Date: Tue, 4 Feb 2025 11:40:25 +0100 Subject: [PATCH 0791/1022] Fix ossfuzz build and force use of libc++ --- .../Dockerfile.ubuntu.clang.ossfuzz | 31 ++++++++++++++----- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/scripts/docker/buildpack-deps/Dockerfile.ubuntu.clang.ossfuzz b/scripts/docker/buildpack-deps/Dockerfile.ubuntu.clang.ossfuzz index b5cd64a235e0..bf228d6176fb 100644 --- a/scripts/docker/buildpack-deps/Dockerfile.ubuntu.clang.ossfuzz +++ b/scripts/docker/buildpack-deps/Dockerfile.ubuntu.clang.ossfuzz @@ -21,9 +21,7 @@ # # (c) 2016-2021 solidity contributors. #------------------------------------------------------------------------------ -# FIXME: Workaround for Boost 1.83.0 build failure when using Clang 18 (default since https://github.com/google/oss-fuzz/pull/11714) -# See: https://github.com/google/oss-fuzz/blob/5a9322260c4c66e7eb3e5d922b9fee6621ffd8da/projects/solidity/Dockerfile#L17C1-L18C139 -FROM gcr.io/oss-fuzz-base/base-builder@sha256:19782f7fe8092843368894dbc471ce9b30dd6a2813946071a36e8b05f5b1e27e AS base +FROM gcr.io/oss-fuzz-base/base-builder AS base LABEL version="10" ARG DEBIAN_FRONTEND=noninteractive @@ -37,6 +35,8 @@ RUN apt-get update; \ git \ jq \ libbz2-dev \ + libc++-18-dev \ + libc++abi-18-dev \ liblzma-dev \ libtool \ lsof \ @@ -64,6 +64,10 @@ RUN apt-get update; \ requests \ tabulate; +# Ensure that the expected version of Clang is installed, as the base image may update it in the future: +# https://github.com/google/oss-fuzz/blob/5e96edbdf285045cc82dbca5600cbe994a3b1a74/infra/base-images/base-clang/checkout_build_install_llvm.sh#L57 +RUN test "$(clang -dumpversion | cut -d. -f1)" = "18" || (echo "Error: Clang 18 not found!" && exit 1) + FROM base AS libraries # Boost @@ -74,9 +78,16 @@ RUN set -ex; \ tar -xf boost.tar.bz2; \ rm boost.tar.bz2; \ cd boost_1_83_0; \ - CXXFLAGS="-std=c++17 -stdlib=libc++ -pthread" LDFLAGS="-stdlib=libc++" ./bootstrap.sh --with-toolset=clang --prefix=/usr; \ - ./b2 toolset=clang cxxflags="-stdlib=libc++ -pthread" linkflags="-stdlib=libc++ -pthread" headers; \ - ./b2 toolset=clang cxxflags="-stdlib=libc++ -pthread" linkflags="-stdlib=libc++ -pthread" \ + export CXXFLAGS="-std=c++20 -nostdinc++ -I/usr/lib/llvm-18/include/c++/v1 -pthread"; \ + export LDFLAGS="-stdlib=libc++ -L/usr/lib/llvm-18/lib"; \ + ./bootstrap.sh --with-toolset=clang --prefix=/usr; \ + ./b2 toolset=clang \ + cxxflags="${CXXFLAGS}" \ + linkflags="${LDFLAGS}" \ + headers; \ + ./b2 toolset=clang \ + cxxflags="${CXXFLAGS}" \ + linkflags="${LDFLAGS}" \ link=static variant=release runtime-link=static \ system filesystem unit_test_framework program_options \ install -j $(($(nproc)/2)); \ @@ -111,10 +122,12 @@ RUN set -ex; \ rm -f /opt/cvc5.zip; # OSSFUZZ: libprotobuf-mutator +# Use commit prior to libprotobuf upgrade that broke solidity build +# See https://github.com/google/oss-fuzz/issues/10237 RUN set -ex; \ git clone https://github.com/google/libprotobuf-mutator.git /usr/src/libprotobuf-mutator; \ cd /usr/src/libprotobuf-mutator; \ - git checkout 3521f47a2828da9ace403e4ecc4aece1a84feb36; \ + git reset --hard 212a7be1eb08e7f9c79732d2aab9b2097085d936; \ mkdir build; \ cd build; \ cmake .. -GNinja -DLIB_PROTO_MUTATOR_DOWNLOAD_PROTOBUF=ON \ @@ -134,7 +147,9 @@ RUN set -ex; \ cd evmone; \ mkdir build; \ cd build; \ - CXX=clang++ cmake -G Ninja -DBUILD_SHARED_LIBS=OFF -DCMAKE_INSTALL_PREFIX="/usr" ..; \ + CXX=clang++ cmake .. -G Ninja \ + -DCMAKE_CXX_STANDARD=20 -DCMAKE_CXX_FLAGS="-stdlib=libc++" \ + -DBUILD_SHARED_LIBS=OFF -DCMAKE_INSTALL_PREFIX="/usr"; \ ninja; \ ninja install/strip; \ rm -rf /usr/src/evmone From cdd02d5b182a2092ccb2a9fb8c40c678f7f4399e Mon Sep 17 00:00:00 2001 From: r0qs Date: Tue, 4 Feb 2025 13:13:48 +0100 Subject: [PATCH 0792/1022] Disable ccache --- scripts/ci/build_ossfuzz.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/ci/build_ossfuzz.sh b/scripts/ci/build_ossfuzz.sh index c44f9bababf3..64d992994ed6 100755 --- a/scripts/ci/build_ossfuzz.sh +++ b/scripts/ci/build_ossfuzz.sh @@ -18,7 +18,7 @@ function generate_protobuf_bindings function build_fuzzers { cd "${BUILDDIR}" - cmake .. -DCMAKE_BUILD_TYPE="${CMAKE_BUILD_TYPE:-Release}" \ + cmake .. -DCMAKE_BUILD_TYPE="${CMAKE_BUILD_TYPE:-Release}" -DCCACHE=OFF \ -DCMAKE_TOOLCHAIN_FILE="${ROOTDIR}"/cmake/toolchains/libfuzzer.cmake make ossfuzz ossfuzz_proto ossfuzz_abiv2 -j 4 } From 719fc8b083e2d124182cd2a628065fa102461f7c Mon Sep 17 00:00:00 2001 From: r0qs Date: Tue, 4 Feb 2025 13:22:29 +0100 Subject: [PATCH 0793/1022] Remove unused symlink for dropped Ubuntu 20.04 image --- scripts/ci/buildpack-deps_test_ubuntu2004.sh | 1 - 1 file changed, 1 deletion(-) delete mode 120000 scripts/ci/buildpack-deps_test_ubuntu2004.sh diff --git a/scripts/ci/buildpack-deps_test_ubuntu2004.sh b/scripts/ci/buildpack-deps_test_ubuntu2004.sh deleted file mode 120000 index feb6a5927fc0..000000000000 --- a/scripts/ci/buildpack-deps_test_ubuntu2004.sh +++ /dev/null @@ -1 +0,0 @@ -./build.sh \ No newline at end of file From 7c15253100721e67e2e4da3f96ae1353311044db Mon Sep 17 00:00:00 2001 From: r0qs Date: Wed, 22 Jan 2025 21:45:40 +0100 Subject: [PATCH 0794/1022] Bump evmone to v0.13.0 in CI --- .circleci/config.yml | 16 ++++++++-------- .circleci/osx_install_dependencies.sh | 4 ++-- scripts/install_evmone.ps1 | 2 +- test/Common.h | 6 +++--- ...operator_matches_equivalent_function_call.sol | 4 +--- 5 files changed, 15 insertions(+), 17 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 0f75e76cd40b..d26ef3bd41a6 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -13,20 +13,20 @@ parameters: default: "solbuildpackpusher/solidity-buildpack-deps@sha256:1f387a77be889f65a2a25986a5c5eccc88cec23fabe6aeaf351790751145c81e" ubuntu-2204-docker-image: type: string - # solbuildpackpusher/solidity-buildpack-deps:ubuntu2204-1 - default: "solbuildpackpusher/solidity-buildpack-deps@sha256:d61b0a4a49ac106e6747c1e8037882f1d421b537dba6c96c0a400ca105d85d4d" + # solbuildpackpusher/solidity-buildpack-deps:ubuntu2204-2 + default: "solbuildpackpusher/solidity-buildpack-deps@sha256:877fcc2589779f8245770711d10db92eda97d338dae76b6a9f27dde1a41b3aa0" ubuntu-2404-docker-image: type: string - # solbuildpackpusher/solidity-buildpack-deps:ubuntu2404-2 - default: "solbuildpackpusher/solidity-buildpack-deps@sha256:92efa8581887e5389b29d3a150112a8433a04ebf5fddf2c65ed6794b4cdf1fe3" + # solbuildpackpusher/solidity-buildpack-deps:ubuntu2404-3 + default: "solbuildpackpusher/solidity-buildpack-deps@sha256:ef6a91d7f1434c67fb9e05c6136d80f71c0ad9198479e1a88e3437680993cda4" ubuntu-2404-clang-docker-image: type: string - # solbuildpackpusher/solidity-buildpack-deps:ubuntu2404.clang-3 - default: "solbuildpackpusher/solidity-buildpack-deps@sha256:534c4eea1ba370a85cf3c106b4a30b43152ba4f695fab5e18577009a5e272146" + # solbuildpackpusher/solidity-buildpack-deps:ubuntu2404.clang-4 + default: "solbuildpackpusher/solidity-buildpack-deps@sha256:97fb2d1bc002b3624161f539a1d29543c0e6c6f4d9a61f611b9b60e99e18f377" ubuntu-clang-ossfuzz-docker-image: type: string - # solbuildpackpusher/solidity-buildpack-deps:ubuntu.clang.ossfuzz-9 - default: "solbuildpackpusher/solidity-buildpack-deps@sha256:c95b24958c92821f1d409b97fcc4930576603063f088a98e780283ee7ec5b575" + # solbuildpackpusher/solidity-buildpack-deps:ubuntu.clang.ossfuzz-10 + default: "solbuildpackpusher/solidity-buildpack-deps@sha256:bd55d9a3b13c88608709ec442188c414d30f4c49f23dc2ce8b76bf8c90603fc7" emscripten-docker-image: type: string # NOTE: Please remember to update the `scripts/build_emscripten.sh` whenever the hash of this image changes. diff --git a/.circleci/osx_install_dependencies.sh b/.circleci/osx_install_dependencies.sh index f618bd9d3e70..e7a0b9ddfda2 100755 --- a/.circleci/osx_install_dependencies.sh +++ b/.circleci/osx_install_dependencies.sh @@ -110,10 +110,10 @@ then rm -rf "$z3_dir" # evmone - evmone_version="0.12.0" + evmone_version="0.13.0" evmone_package="evmone-${evmone_version}-darwin-arm64.tar.gz" wget "https://github.com/ethereum/evmone/releases/download/v${evmone_version}/${evmone_package}" - validate_checksum "$evmone_package" e164e0d2b985cc1cca07b501538b2e804bf872d1d8d531f9241d518a886234a6 + validate_checksum "$evmone_package" 49fe6cc35e0e13c48ca2f29a6b85a47f7b25dcd427e14254000d3bc29cddf2a6 sudo tar xzpf "$evmone_package" -C /usr/local rm "$evmone_package" fi diff --git a/scripts/install_evmone.ps1 b/scripts/install_evmone.ps1 index 7295afa01ee3..53fc7b6eee9e 100644 --- a/scripts/install_evmone.ps1 +++ b/scripts/install_evmone.ps1 @@ -3,6 +3,6 @@ $ErrorActionPreference = "Stop" # Needed for Invoke-WebRequest to work via CI. $progressPreference = "silentlyContinue" -Invoke-WebRequest -URI "https://github.com/ethereum/evmone/releases/download/v0.12.0/evmone-0.12.0-windows-amd64.zip" -OutFile "evmone.zip" +Invoke-WebRequest -URI "https://github.com/ethereum/evmone/releases/download/v0.13.0/evmone-0.13.0-windows-amd64.zip" -OutFile "evmone.zip" tar -xf evmone.zip "bin/evmone.dll" mv bin/evmone.dll deps/ diff --git a/test/Common.h b/test/Common.h index 866f6945a645..27c2081346fc 100644 --- a/test/Common.h +++ b/test/Common.h @@ -39,13 +39,13 @@ namespace solidity::test #ifdef _WIN32 static constexpr auto evmoneFilename = "evmone.dll"; -static constexpr auto evmoneDownloadLink = "https://github.com/ethereum/evmone/releases/download/v0.12.0/evmone-0.12.0-windows-amd64.zip"; +static constexpr auto evmoneDownloadLink = "https://github.com/ethereum/evmone/releases/download/v0.13.0/evmone-0.13.0-windows-amd64.zip"; #elif defined(__APPLE__) static constexpr auto evmoneFilename = "libevmone.dylib"; -static constexpr auto evmoneDownloadLink = "https://github.com/ethereum/evmone/releases/download/v0.12.0/evmone-0.12.0-darwin-arm64.tar.gz"; +static constexpr auto evmoneDownloadLink = "https://github.com/ethereum/evmone/releases/download/v0.13.0/evmone-0.13.0-darwin-arm64.tar.gz"; #else static constexpr auto evmoneFilename = "libevmone.so"; -static constexpr auto evmoneDownloadLink = "https://github.com/ethereum/evmone/releases/download/v0.12.0/evmone-0.12.0-linux-x86_64.tar.gz"; +static constexpr auto evmoneDownloadLink = "https://github.com/ethereum/evmone/releases/download/v0.13.0/evmone-0.13.0-linux-x86_64.tar.gz"; #endif struct ConfigException: public util::Exception {}; diff --git a/test/libsolidity/smtCheckerTests/operators/userDefined/user_defined_operator_matches_equivalent_function_call.sol b/test/libsolidity/smtCheckerTests/operators/userDefined/user_defined_operator_matches_equivalent_function_call.sol index 76ad6db55384..76078a582198 100644 --- a/test/libsolidity/smtCheckerTests/operators/userDefined/user_defined_operator_matches_equivalent_function_call.sol +++ b/test/libsolidity/smtCheckerTests/operators/userDefined/user_defined_operator_matches_equivalent_function_call.sol @@ -52,11 +52,9 @@ contract C { } } // ==== -// SMTEngine: all +// SMTEngine: chc // SMTTargets: assert // ---- // Warning 6328: (2209-2235): CHC: Assertion violation might happen here. // Warning 6328: (2245-2271): CHC: Assertion violation might happen here. // Info 1391: CHC: 14 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. -// Warning 7812: (2245-2271): BMC: Assertion violation might happen here. -// Info 6002: BMC: 1 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. From 6b4ee52513d66f0da68b688ede59c24816dd0b6a Mon Sep 17 00:00:00 2001 From: r0qs Date: Mon, 3 Feb 2025 21:12:54 +0100 Subject: [PATCH 0795/1022] Introduces EVM version Osaka --- .circleci/soltest_all.sh | 2 +- Changelog.md | 1 + docs/using-the-compiler.rst | 3 ++- liblangutil/EVMVersion.h | 8 ++++++-- scripts/tests.sh | 2 +- test/EVMHost.cpp | 2 ++ test/tools/ossfuzz/protoToYul.cpp | 2 ++ test/tools/ossfuzz/yulProto.proto | 1 + 8 files changed, 16 insertions(+), 5 deletions(-) diff --git a/.circleci/soltest_all.sh b/.circleci/soltest_all.sh index 1c7882448ca1..1e765c6f9e32 100755 --- a/.circleci/soltest_all.sh +++ b/.circleci/soltest_all.sh @@ -31,7 +31,7 @@ REPODIR="$(realpath "$(dirname "$0")"/..)" # shellcheck source=scripts/common.sh source "${REPODIR}/scripts/common.sh" -DEFAULT_EVM_VALUES=(constantinople petersburg istanbul berlin london paris shanghai cancun prague) +DEFAULT_EVM_VALUES=(constantinople petersburg istanbul berlin london paris shanghai cancun prague osaka) EVMS_WITH_EOF=(prague) # Deserialize the EVM_VALUES array if it was provided as argument or diff --git a/Changelog.md b/Changelog.md index be3209702455..0bf7cb988081 100644 --- a/Changelog.md +++ b/Changelog.md @@ -5,6 +5,7 @@ Language Features: Compiler Features: * Error Reporting: Errors reported during code generation now point at the location of the contract when more fine-grained location is not available. + * EVM: Support for the EVM version "Osaka". * SMTChecker: Support `block.blobbasefee` and `blobhash`. * SMTChecker: Z3 is now a runtime dependency, not a build dependency (except for emscripten build). * Yul Parser: Make name clash with a builtin a non-fatal error. diff --git a/docs/using-the-compiler.rst b/docs/using-the-compiler.rst index 48151a637713..a5d5b08ccd0b 100644 --- a/docs/using-the-compiler.rst +++ b/docs/using-the-compiler.rst @@ -182,6 +182,7 @@ at each version. Backward compatibility is not guaranteed between each version. - Opcode ``mcopy`` is available in assembly (see `EIP-5656 `_). - Opcodes ``tstore`` and ``tload`` are available in assembly (see `EIP-1153 `_). - ``prague`` (**experimental**) +- ``osaka`` (**experimental**) .. index:: ! standard JSON, ! --standard-json .. _compiler-api: @@ -349,7 +350,7 @@ Input Description // Version of the EVM to compile for. // Affects type checking and code generation. Can be homestead, // tangerineWhistle, spuriousDragon, byzantium, constantinople, - // petersburg, istanbul, berlin, london, paris, shanghai, cancun (default) or prague (experimental). + // petersburg, istanbul, berlin, london, paris, shanghai, cancun (default), prague (experimental) or osaka (experimental). "evmVersion": "cancun", // Optional: Change compilation pipeline to go through the Yul intermediate representation. // This is false by default. diff --git a/liblangutil/EVMVersion.h b/liblangutil/EVMVersion.h index 2201f3c9dd1e..6566f3a4acf8 100644 --- a/liblangutil/EVMVersion.h +++ b/liblangutil/EVMVersion.h @@ -64,6 +64,7 @@ class EVMVersion: static EVMVersion shanghai() { return {Version::Shanghai}; } static EVMVersion cancun() { return {Version::Cancun}; } static EVMVersion prague() { return {Version::Prague}; } + static EVMVersion osaka() { return {Version::Osaka}; } static std::vector allVersions() { return { @@ -80,6 +81,7 @@ class EVMVersion: shanghai(), cancun(), prague(), + osaka(), }; } @@ -92,7 +94,7 @@ class EVMVersion: } bool isExperimental() const { - return m_version == Version::Prague; + return *this > EVMVersion{}; } bool operator==(EVMVersion const& _other) const { return m_version == _other.m_version; } @@ -115,6 +117,7 @@ class EVMVersion: case Version::Shanghai: return "shanghai"; case Version::Cancun: return "cancun"; case Version::Prague: return "prague"; + case Version::Osaka: return "osaka"; } util::unreachable(); } @@ -155,7 +158,8 @@ class EVMVersion: Paris, Shanghai, Cancun, - Prague + Prague, + Osaka, }; EVMVersion(Version _version): m_version(_version) {} diff --git a/scripts/tests.sh b/scripts/tests.sh index dfbc0477342d..3d2849369eca 100755 --- a/scripts/tests.sh +++ b/scripts/tests.sh @@ -105,7 +105,7 @@ EVM_VERSIONS="homestead byzantium" if [ -z "$CI" ] then - EVM_VERSIONS+=" constantinople petersburg istanbul berlin london paris shanghai cancun prague" + EVM_VERSIONS+=" constantinople petersburg istanbul berlin london paris shanghai cancun prague osaka" fi # And then run the Solidity unit-tests in the matrix combination of optimizer / no optimizer diff --git a/test/EVMHost.cpp b/test/EVMHost.cpp index 897f01c68ac3..7df39bf71ee8 100644 --- a/test/EVMHost.cpp +++ b/test/EVMHost.cpp @@ -134,6 +134,8 @@ EVMHost::EVMHost(langutil::EVMVersion _evmVersion, evmc::VM& _vm): m_evmRevision = EVMC_CANCUN; else if (_evmVersion == langutil::EVMVersion::prague()) m_evmRevision = EVMC_PRAGUE; + else if (_evmVersion == langutil::EVMVersion::osaka()) + m_evmRevision = EVMC_OSAKA; else assertThrow(false, Exception, "Unsupported EVM version"); diff --git a/test/tools/ossfuzz/protoToYul.cpp b/test/tools/ossfuzz/protoToYul.cpp index 5a57b779dc87..cc5f68e71ecf 100644 --- a/test/tools/ossfuzz/protoToYul.cpp +++ b/test/tools/ossfuzz/protoToYul.cpp @@ -121,6 +121,8 @@ EVMVersion ProtoConverter::evmVersionMapping(Program_Version const& _ver) return EVMVersion::cancun(); case Program::PRAGUE: return EVMVersion::prague(); + case Program::OSAKA: + return EVMVersion::osaka(); } } diff --git a/test/tools/ossfuzz/yulProto.proto b/test/tools/ossfuzz/yulProto.proto index 15ac01396bcc..a22aacb0df03 100644 --- a/test/tools/ossfuzz/yulProto.proto +++ b/test/tools/ossfuzz/yulProto.proto @@ -407,6 +407,7 @@ message Program { SHANGHAI = 10; CANCUN = 11; PRAGUE = 12; + OSAKA = 13; } oneof program_oneof { Block block = 1; From 462fd19f9c11dc554e3b2052aaa8a1803ac0c482 Mon Sep 17 00:00:00 2001 From: r0qs Date: Mon, 3 Feb 2025 21:16:08 +0100 Subject: [PATCH 0796/1022] Move EOF support to Osaka Rename tests --- .circleci/soltest_all.sh | 2 +- liblangutil/EVMVersion.cpp | 4 ++-- liblangutil/EVMVersion.h | 3 +++ libyul/AsmAnalysis.cpp | 5 ++--- libyul/backends/evm/EVMDialect.cpp | 7 +++---- libyul/backends/evm/EVMObjectCompiler.cpp | 8 ++++---- test/Common.cpp | 2 +- test/TestCase.cpp | 5 ++--- test/cmdlineTests/strict_asm_eof_container_osaka/args | 1 + .../input.yul | 0 .../output | 2 +- test/cmdlineTests/strict_asm_eof_container_prague/args | 1 - test/cmdlineTests/strict_asm_eof_dataloadn_osaka/args | 1 + .../input.yul | 0 .../output | 2 +- test/cmdlineTests/strict_asm_eof_dataloadn_prague/args | 1 - .../functionCalls/eof/calloptions_on_staticcall.sol | 1 - .../objectCompiler/eof/creation_with_immutables.yul | 1 - test/libyul/objectCompiler/eof/dataloadn.yul | 1 - .../objectCompiler/eof/prune_unreferenced_container.yul | 1 - test/libyul/objectCompiler/eof/rjumps.yul | 1 - .../eof/auxdataloadn_in_eof_invalid_literal_type.yul | 1 - test/libyul/yulSyntaxTests/eof/auxdataloadn_in_legacy.yul | 1 - 23 files changed, 22 insertions(+), 29 deletions(-) create mode 100644 test/cmdlineTests/strict_asm_eof_container_osaka/args rename test/cmdlineTests/{strict_asm_eof_container_prague => strict_asm_eof_container_osaka}/input.yul (100%) rename test/cmdlineTests/{strict_asm_eof_container_prague => strict_asm_eof_container_osaka}/output (96%) delete mode 100644 test/cmdlineTests/strict_asm_eof_container_prague/args create mode 100644 test/cmdlineTests/strict_asm_eof_dataloadn_osaka/args rename test/cmdlineTests/{strict_asm_eof_dataloadn_prague => strict_asm_eof_dataloadn_osaka}/input.yul (100%) rename test/cmdlineTests/{strict_asm_eof_dataloadn_prague => strict_asm_eof_dataloadn_osaka}/output (88%) delete mode 100644 test/cmdlineTests/strict_asm_eof_dataloadn_prague/args diff --git a/.circleci/soltest_all.sh b/.circleci/soltest_all.sh index 1e765c6f9e32..216b1ee3815a 100755 --- a/.circleci/soltest_all.sh +++ b/.circleci/soltest_all.sh @@ -32,7 +32,7 @@ REPODIR="$(realpath "$(dirname "$0")"/..)" source "${REPODIR}/scripts/common.sh" DEFAULT_EVM_VALUES=(constantinople petersburg istanbul berlin london paris shanghai cancun prague osaka) -EVMS_WITH_EOF=(prague) +EVMS_WITH_EOF=(osaka) # Deserialize the EVM_VALUES array if it was provided as argument or # set EVM_VALUES to the default values. diff --git a/liblangutil/EVMVersion.cpp b/liblangutil/EVMVersion.cpp index ac087b8fcc47..30df93796522 100644 --- a/liblangutil/EVMVersion.cpp +++ b/liblangutil/EVMVersion.cpp @@ -28,8 +28,8 @@ using namespace solidity::langutil; bool EVMVersion::hasOpcode(Instruction _opcode, std::optional _eofVersion) const { - // EOF version can be only defined since prague - assert(!_eofVersion.has_value() || *this >= prague()); + // EOF version can be only defined since osaka + assert(!_eofVersion.has_value() || *this >= EVMVersion::firstWithEOF()); switch (_opcode) { diff --git a/liblangutil/EVMVersion.h b/liblangutil/EVMVersion.h index 6566f3a4acf8..a159f2e4bb2f 100644 --- a/liblangutil/EVMVersion.h +++ b/liblangutil/EVMVersion.h @@ -93,6 +93,8 @@ class EVMVersion: return std::nullopt; } + static EVMVersion firstWithEOF() { return {Version::Osaka}; } + bool isExperimental() const { return *this > EVMVersion{}; } @@ -137,6 +139,7 @@ class EVMVersion: bool hasBlobHash() const { return *this >= cancun(); } bool hasMcopy() const { return *this >= cancun(); } bool supportsTransientStorage() const { return *this >= cancun(); } + bool supportsEOF() const { return *this >= firstWithEOF(); } bool hasOpcode(evmasm::Instruction _opcode, std::optional _eofVersion) const; diff --git a/libyul/AsmAnalysis.cpp b/libyul/AsmAnalysis.cpp index b6dcbb08e2dc..7c82d788f35f 100644 --- a/libyul/AsmAnalysis.cpp +++ b/libyul/AsmAnalysis.cpp @@ -695,9 +695,8 @@ bool AsmAnalyzer::validateInstructions(std::string_view _instructionIdentifier, if (builtinHandle && defaultEVMDialect.builtin(*builtinHandle).instruction.has_value()) return validateInstructions(*defaultEVMDialect.builtin(*builtinHandle).instruction, _location); - solAssert(!m_eofVersion.has_value() || (*m_eofVersion == 1 && m_evmVersion == langutil::EVMVersion::prague())); - // TODO: Change `prague()` to `EVMVersion{}` once EOF gets deployed - auto const& eofDialect = EVMDialect::strictAssemblyForEVMObjects(EVMVersion::prague(), 1); + solAssert(!m_eofVersion.has_value() || *m_eofVersion == 1); + auto const& eofDialect = EVMDialect::strictAssemblyForEVMObjects(EVMVersion::firstWithEOF(), 1); auto const eofBuiltinHandle = eofDialect.findBuiltin(_instructionIdentifier); if (eofBuiltinHandle) { diff --git a/libyul/backends/evm/EVMDialect.cpp b/libyul/backends/evm/EVMDialect.cpp index 611e95c39d72..4fa78f0233a4 100644 --- a/libyul/backends/evm/EVMDialect.cpp +++ b/libyul/backends/evm/EVMDialect.cpp @@ -155,13 +155,12 @@ std::set> createReservedIdentifiers(langutil::EVMVersio auto eofIdentifiersException = [&](evmasm::Instruction _instr) -> bool { - solAssert(!_eofVersion.has_value() || (*_eofVersion == 1 && _evmVersion == langutil::EVMVersion::prague())); + solAssert(!_eofVersion.has_value() || (*_eofVersion == 1 && _evmVersion.supportsEOF())); if (_eofVersion.has_value()) // For EOF every instruction is reserved identifier. return false; - else - return langutil::EVMVersion::prague().hasOpcode(_instr, 1) && - !langutil::EVMVersion::prague().hasOpcode(_instr, std::nullopt); + return langutil::EVMVersion::firstWithEOF().hasOpcode(_instr, 1) && + !langutil::EVMVersion::firstWithEOF().hasOpcode(_instr, std::nullopt); }; std::set> reserved; diff --git a/libyul/backends/evm/EVMObjectCompiler.cpp b/libyul/backends/evm/EVMObjectCompiler.cpp index fb61e70f6489..30f06bc97385 100644 --- a/libyul/backends/evm/EVMObjectCompiler.cpp +++ b/libyul/backends/evm/EVMObjectCompiler.cpp @@ -76,10 +76,10 @@ void EVMObjectCompiler::run(Object const& _object, bool _optimize) yulAssert(_object.analysisInfo, "No analysis info."); yulAssert(_object.hasCode(), "No code."); if (evmDialect->eofVersion().has_value()) - yulAssert( - _optimize && (evmDialect->evmVersion() >= langutil::EVMVersion::prague()), - "Experimental EOF support is only available for optimized via-IR compilation and the most recent EVM version." - ); + { + solUnimplementedAssert(_optimize, "EOF supported only for optimized compilation via IR."); + yulAssert(evmDialect->evmVersion().supportsEOF()); + } if (_optimize && evmDialect->evmVersion().canOverchargeGasForCall()) { auto stackErrors = OptimizedEVMCodeTransform::run( diff --git a/test/Common.cpp b/test/Common.cpp index 30738dcfc6dd..bb25d203b71e 100644 --- a/test/Common.cpp +++ b/test/Common.cpp @@ -162,7 +162,7 @@ void CommonOptions::validate() const std::cout << std::endl << "DO NOT COMMIT THE UPDATED EXPECTATIONS." << std::endl << std::endl; } - assertThrow(!eofVersion().has_value() || evmVersion() >= langutil::EVMVersion::prague(), ConfigException, "EOF is unavailable before Prague fork."); + assertThrow(!eofVersion().has_value() || evmVersion().supportsEOF(), ConfigException, "EOF is unavailable before Osaka fork."); } bool CommonOptions::parse(int argc, char const* const* argv) diff --git a/test/TestCase.cpp b/test/TestCase.cpp index 104bd1bdeefb..da47c26fde90 100644 --- a/test/TestCase.cpp +++ b/test/TestCase.cpp @@ -146,9 +146,8 @@ void EVMVersionRestrictedTestCase::processEVMVersionSetting() void EVMVersionRestrictedTestCase::processBytecodeFormatSetting() { std::optional eofVersion = solidity::test::CommonOptions::get().eofVersion(); - // TODO: Update if EOF moved to Osaka - // EOF only available since Prague - solAssert(!eofVersion.has_value() ||solidity::test::CommonOptions::get().evmVersion() >= langutil::EVMVersion::prague()); + // EOF only available since Osaka + solAssert(!eofVersion.has_value() || solidity::test::CommonOptions::get().evmVersion().supportsEOF()); std::string bytecodeFormatString = m_reader.stringSetting("bytecodeFormat", "legacy,>=EOFv1"); if (bytecodeFormatString == "legacy,>=EOFv1" || bytecodeFormatString == ">=EOFv1,legacy") diff --git a/test/cmdlineTests/strict_asm_eof_container_osaka/args b/test/cmdlineTests/strict_asm_eof_container_osaka/args new file mode 100644 index 000000000000..60abde356339 --- /dev/null +++ b/test/cmdlineTests/strict_asm_eof_container_osaka/args @@ -0,0 +1 @@ + --strict-assembly --experimental-eof-version 1 --evm-version osaka --asm --ir-optimized --bin --debug-info none diff --git a/test/cmdlineTests/strict_asm_eof_container_prague/input.yul b/test/cmdlineTests/strict_asm_eof_container_osaka/input.yul similarity index 100% rename from test/cmdlineTests/strict_asm_eof_container_prague/input.yul rename to test/cmdlineTests/strict_asm_eof_container_osaka/input.yul diff --git a/test/cmdlineTests/strict_asm_eof_container_prague/output b/test/cmdlineTests/strict_asm_eof_container_osaka/output similarity index 96% rename from test/cmdlineTests/strict_asm_eof_container_prague/output rename to test/cmdlineTests/strict_asm_eof_container_osaka/output index d38adba184c0..81f01798a766 100644 --- a/test/cmdlineTests/strict_asm_eof_container_prague/output +++ b/test/cmdlineTests/strict_asm_eof_container_osaka/output @@ -1,5 +1,5 @@ -======= strict_asm_eof_container_prague/input.yul (EVM) ======= +======= strict_asm_eof_container_osaka/input.yul (EVM) ======= Pretty printed source: object "object" { diff --git a/test/cmdlineTests/strict_asm_eof_container_prague/args b/test/cmdlineTests/strict_asm_eof_container_prague/args deleted file mode 100644 index 0078e6e68e36..000000000000 --- a/test/cmdlineTests/strict_asm_eof_container_prague/args +++ /dev/null @@ -1 +0,0 @@ - --strict-assembly --experimental-eof-version 1 --evm-version prague --asm --ir-optimized --bin --debug-info none diff --git a/test/cmdlineTests/strict_asm_eof_dataloadn_osaka/args b/test/cmdlineTests/strict_asm_eof_dataloadn_osaka/args new file mode 100644 index 000000000000..60abde356339 --- /dev/null +++ b/test/cmdlineTests/strict_asm_eof_dataloadn_osaka/args @@ -0,0 +1 @@ + --strict-assembly --experimental-eof-version 1 --evm-version osaka --asm --ir-optimized --bin --debug-info none diff --git a/test/cmdlineTests/strict_asm_eof_dataloadn_prague/input.yul b/test/cmdlineTests/strict_asm_eof_dataloadn_osaka/input.yul similarity index 100% rename from test/cmdlineTests/strict_asm_eof_dataloadn_prague/input.yul rename to test/cmdlineTests/strict_asm_eof_dataloadn_osaka/input.yul diff --git a/test/cmdlineTests/strict_asm_eof_dataloadn_prague/output b/test/cmdlineTests/strict_asm_eof_dataloadn_osaka/output similarity index 88% rename from test/cmdlineTests/strict_asm_eof_dataloadn_prague/output rename to test/cmdlineTests/strict_asm_eof_dataloadn_osaka/output index 5d2115f95af6..677c49b88a1b 100644 --- a/test/cmdlineTests/strict_asm_eof_dataloadn_prague/output +++ b/test/cmdlineTests/strict_asm_eof_dataloadn_osaka/output @@ -1,5 +1,5 @@ -======= strict_asm_eof_dataloadn_prague/input.yul (EVM) ======= +======= strict_asm_eof_dataloadn_osaka/input.yul (EVM) ======= Pretty printed source: object "a" { diff --git a/test/cmdlineTests/strict_asm_eof_dataloadn_prague/args b/test/cmdlineTests/strict_asm_eof_dataloadn_prague/args deleted file mode 100644 index 0078e6e68e36..000000000000 --- a/test/cmdlineTests/strict_asm_eof_dataloadn_prague/args +++ /dev/null @@ -1 +0,0 @@ - --strict-assembly --experimental-eof-version 1 --evm-version prague --asm --ir-optimized --bin --debug-info none diff --git a/test/libsolidity/syntaxTests/functionCalls/eof/calloptions_on_staticcall.sol b/test/libsolidity/syntaxTests/functionCalls/eof/calloptions_on_staticcall.sol index f63837dcf26a..d43fb5969d72 100644 --- a/test/libsolidity/syntaxTests/functionCalls/eof/calloptions_on_staticcall.sol +++ b/test/libsolidity/syntaxTests/functionCalls/eof/calloptions_on_staticcall.sol @@ -4,7 +4,6 @@ contract C { } } // ==== -// EVMVersion: >=prague // bytecodeFormat: >=EOFv1 // ---- // TypeError 2842: (56-96): Cannot set option "value" for staticcall. diff --git a/test/libyul/objectCompiler/eof/creation_with_immutables.yul b/test/libyul/objectCompiler/eof/creation_with_immutables.yul index 3d5ef85bc9a5..c11cceae85ad 100644 --- a/test/libyul/objectCompiler/eof/creation_with_immutables.yul +++ b/test/libyul/objectCompiler/eof/creation_with_immutables.yul @@ -27,7 +27,6 @@ object "a" { } // ==== -// EVMVersion: >=prague // bytecodeFormat: >=EOFv1 // ---- // Assembly: diff --git a/test/libyul/objectCompiler/eof/dataloadn.yul b/test/libyul/objectCompiler/eof/dataloadn.yul index 06ebdaa3ce38..7fda77b9a666 100644 --- a/test/libyul/objectCompiler/eof/dataloadn.yul +++ b/test/libyul/objectCompiler/eof/dataloadn.yul @@ -9,7 +9,6 @@ object "a" { } // ==== -// EVMVersion: >=prague // bytecodeFormat: >=EOFv1 // ---- // Assembly: diff --git a/test/libyul/objectCompiler/eof/prune_unreferenced_container.yul b/test/libyul/objectCompiler/eof/prune_unreferenced_container.yul index 0c9f9a382497..35f503c708fa 100644 --- a/test/libyul/objectCompiler/eof/prune_unreferenced_container.yul +++ b/test/libyul/objectCompiler/eof/prune_unreferenced_container.yul @@ -20,7 +20,6 @@ object "a" { } // ==== -// EVMVersion: >=prague // bytecodeFormat: >=EOFv1 // ---- // Assembly: diff --git a/test/libyul/objectCompiler/eof/rjumps.yul b/test/libyul/objectCompiler/eof/rjumps.yul index d5f2f6c2117b..49665784e9a2 100644 --- a/test/libyul/objectCompiler/eof/rjumps.yul +++ b/test/libyul/objectCompiler/eof/rjumps.yul @@ -9,7 +9,6 @@ object "a" { } // ==== -// EVMVersion: >=prague // bytecodeFormat: >=EOFv1 // ---- // Assembly: diff --git a/test/libyul/yulSyntaxTests/eof/auxdataloadn_in_eof_invalid_literal_type.yul b/test/libyul/yulSyntaxTests/eof/auxdataloadn_in_eof_invalid_literal_type.yul index 08de0df183af..3622a39648e1 100644 --- a/test/libyul/yulSyntaxTests/eof/auxdataloadn_in_eof_invalid_literal_type.yul +++ b/test/libyul/yulSyntaxTests/eof/auxdataloadn_in_eof_invalid_literal_type.yul @@ -8,7 +8,6 @@ object "a" { } // ==== -// EVMVersion: >=prague // bytecodeFormat: >=EOFv1 // ---- // TypeError 5859: (55-58): Function expects number literal. \ No newline at end of file diff --git a/test/libyul/yulSyntaxTests/eof/auxdataloadn_in_legacy.yul b/test/libyul/yulSyntaxTests/eof/auxdataloadn_in_legacy.yul index 47986059e283..f6af43217faf 100644 --- a/test/libyul/yulSyntaxTests/eof/auxdataloadn_in_legacy.yul +++ b/test/libyul/yulSyntaxTests/eof/auxdataloadn_in_legacy.yul @@ -8,7 +8,6 @@ object "a" { } // ==== -// EVMVersion: >=prague // bytecodeFormat: legacy // ---- // DeclarationError 7223: (42-54): Builtin function "auxdataloadn" is only available in EOF. From ac4fb25f5eddaaf83de1633543f47b4d8d86eccf Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Tue, 11 Feb 2025 13:50:15 +0100 Subject: [PATCH 0797/1022] Yul optimizer utilities use string_view to determine if an identifier is restricted --- libyul/optimiser/NameDispenser.cpp | 2 +- libyul/optimiser/OptimizerUtilities.cpp | 4 ++-- libyul/optimiser/OptimizerUtilities.h | 4 ++-- libyul/optimiser/VarNameCleaner.cpp | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/libyul/optimiser/NameDispenser.cpp b/libyul/optimiser/NameDispenser.cpp index c2b6b9847f3c..3493c36682df 100644 --- a/libyul/optimiser/NameDispenser.cpp +++ b/libyul/optimiser/NameDispenser.cpp @@ -58,7 +58,7 @@ YulName NameDispenser::newName(YulName _nameHint) bool NameDispenser::illegalName(YulName _name) { - return isRestrictedIdentifier(m_dialect, _name) || m_usedNames.count(_name); + return isRestrictedIdentifier(m_dialect, _name.str()) || m_usedNames.contains(_name); } void NameDispenser::reset(Block const& _ast) diff --git a/libyul/optimiser/OptimizerUtilities.cpp b/libyul/optimiser/OptimizerUtilities.cpp index 8fc225bee0a4..3001d43f8e85 100644 --- a/libyul/optimiser/OptimizerUtilities.cpp +++ b/libyul/optimiser/OptimizerUtilities.cpp @@ -56,9 +56,9 @@ void yul::removeEmptyBlocks(Block& _block) ranges::actions::remove_if(_block.statements, isEmptyBlock); } -bool yul::isRestrictedIdentifier(Dialect const& _dialect, YulName const& _identifier) +bool yul::isRestrictedIdentifier(Dialect const& _dialect, std::string_view const _identifier) { - return _identifier.empty() || hasLeadingOrTrailingDot(_identifier.str()) || TokenTraits::isYulKeyword(_identifier.str()) || _dialect.reservedIdentifier(_identifier.str()); + return _identifier.empty() || hasLeadingOrTrailingDot(_identifier) || TokenTraits::isYulKeyword(_identifier) || _dialect.reservedIdentifier(_identifier); } std::optional yul::toEVMInstruction(Dialect const& _dialect, FunctionName const& _name) diff --git a/libyul/optimiser/OptimizerUtilities.h b/libyul/optimiser/OptimizerUtilities.h index 430834d8304b..d302b4aebba8 100644 --- a/libyul/optimiser/OptimizerUtilities.h +++ b/libyul/optimiser/OptimizerUtilities.h @@ -24,11 +24,11 @@ #include #include #include -#include #include #include #include +#include namespace solidity::evmasm { @@ -45,7 +45,7 @@ void removeEmptyBlocks(Block& _block); /// Returns true if a given literal can not be used as an identifier. /// This includes Yul keywords and builtins of the given dialect. -bool isRestrictedIdentifier(Dialect const& _dialect, YulName const& _identifier); +bool isRestrictedIdentifier(Dialect const& _dialect, std::string_view _identifier); /// Helper function that returns the instruction, if the `_name` is a BuiltinFunction std::optional toEVMInstruction(Dialect const& _dialect, FunctionName const& _name); diff --git a/libyul/optimiser/VarNameCleaner.cpp b/libyul/optimiser/VarNameCleaner.cpp index b3a34d283e7e..8d34ce85e408 100644 --- a/libyul/optimiser/VarNameCleaner.cpp +++ b/libyul/optimiser/VarNameCleaner.cpp @@ -111,7 +111,7 @@ YulName VarNameCleaner::findCleanName(YulName const& _name) const bool VarNameCleaner::isUsedName(YulName const& _name) const { - return isRestrictedIdentifier(m_dialect, _name) || m_usedNames.count(_name); + return isRestrictedIdentifier(m_dialect, _name.str()) || m_usedNames.contains(_name); } YulName VarNameCleaner::stripSuffix(YulName const& _name) const From b0485e44b629035d68fe9bab14e502a95c89b4ec Mon Sep 17 00:00:00 2001 From: Martin Blicha Date: Wed, 12 Feb 2025 13:13:51 +0100 Subject: [PATCH 0798/1022] SMTChecker: Fix reporting same target both as safe and unsafe The same verification target can be analyzed in the context of different contracts. If the target is safe in the context of one contract, but can be violated in the context of another contract, model checker may report it both safe and unsafe (depending on the order of the analyzed contract). Note that if one violation of a target has been detected, the same target if ignored later. However, if it was first shown safe, that information would be kept and displayed to the user. The proposed fix checks if an unsafe target has previously been shown safe, and if so, this information is deleted. --- Changelog.md | 1 + libsolidity/formal/CHC.cpp | 8 +++++++- .../free_function_multiple_contracts.sol | 20 +++++++++++++++++++ ...call_with_assertion_inheritance_1_fail.sol | 8 ++++---- .../functions/library_constant.sol | 6 +++--- .../imports/import_library_2.sol | 3 +-- .../base_contract_assertion_fail_1.sol | 1 - .../base_contract_assertion_fail_2.sol | 1 - .../base_contract_assertion_fail_3.sol | 2 +- .../base_contract_assertion_fail_4.sol | 2 +- .../base_contract_assertion_fail_5.sol | 2 +- .../base_contract_assertion_fail_7.sol | 2 +- .../base_contract_assertion_fail_9.sol | 1 - ...tor_state_variable_init_diamond_middle.sol | 6 +++--- .../modifiers/modifier_overriding_4.sol | 8 ++++---- .../modifiers/modifier_two_invocations_2.sol | 4 ++-- .../assignment_chain_tuple_contract_3.sol | 2 +- .../special/msg_value_inheritance_2.sol | 5 ++--- .../special/msg_value_inheritance_3.sol | 4 ++-- 19 files changed, 54 insertions(+), 32 deletions(-) create mode 100644 test/libsolidity/smtCheckerTests/functions/free_function_multiple_contracts.sol diff --git a/Changelog.md b/Changelog.md index 0bf7cb988081..5886dca26016 100644 --- a/Changelog.md +++ b/Changelog.md @@ -13,6 +13,7 @@ Compiler Features: Bugfixes: * General: Fix internal compiler error when requesting IR AST outputs for interfaces and abstract contracts. + * SMTChecker: Fix reporting on targets that are safe in the context of one contract but unsafe in the context of another contract. * SMTChecker: Fix SMT logic error when analyzing cross-contract getter call with BMC. * SMTChecker: Fix SMT logic error when contract deployment involves string literal to fixed bytes conversion. * SMTChecker: Fix SMT logic error when external call has extra effectless parentheses. diff --git a/libsolidity/formal/CHC.cpp b/libsolidity/formal/CHC.cpp index bd3b0d9888fe..3a5da1e587cc 100644 --- a/libsolidity/formal/CHC.cpp +++ b/libsolidity/formal/CHC.cpp @@ -2169,7 +2169,13 @@ void CHC::checkAndReportTarget( } else if (result == CheckResult::SATISFIABLE) { - solAssert(!_satMsg.empty(), ""); + solAssert(!_satMsg.empty()); + if (auto it = m_safeTargets.find(_target.errorNode); it != m_safeTargets.end()) + { + std::erase_if(it->second, [&](auto const& target) { return target.type == _target.type; }); + if (it->second.empty()) + m_safeTargets.erase(it); + } auto cex = generateCounterexample(model, error().name); if (cex) m_unsafeTargets[_target.errorNode][_target.type] = { diff --git a/test/libsolidity/smtCheckerTests/functions/free_function_multiple_contracts.sol b/test/libsolidity/smtCheckerTests/functions/free_function_multiple_contracts.sol new file mode 100644 index 000000000000..49ca28f5c8d0 --- /dev/null +++ b/test/libsolidity/smtCheckerTests/functions/free_function_multiple_contracts.sol @@ -0,0 +1,20 @@ +function check(uint x) pure { + assert(x > 0); +} + +contract C { + function a() public pure { + check(1); + } +} + +contract D { + function b(uint x) public pure { + check(x); + } +} +// ==== +// SMTEngine: chc +// SMTIgnoreCex: no +// ---- +// Warning 6328: (31-44): CHC: Assertion violation happens here.\nCounterexample:\n\nx = 0\n\nTransaction trace:\nD.constructor()\nD.b(0)\n check(0) -- internal call diff --git a/test/libsolidity/smtCheckerTests/functions/internal_call_with_assertion_inheritance_1_fail.sol b/test/libsolidity/smtCheckerTests/functions/internal_call_with_assertion_inheritance_1_fail.sol index 9f2fca60cefb..10a07e13648a 100644 --- a/test/libsolidity/smtCheckerTests/functions/internal_call_with_assertion_inheritance_1_fail.sol +++ b/test/libsolidity/smtCheckerTests/functions/internal_call_with_assertion_inheritance_1_fail.sol @@ -17,7 +17,7 @@ contract C is A { // ==== // SMTEngine: all // ---- -// Warning 6328: (49-63): CHC: Assertion violation happens here. -// Warning 6328: (115-129): CHC: Assertion violation happens here. -// Warning 6328: (147-161): CHC: Assertion violation happens here. -// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. +// Warning 6328: (49-63): CHC: Assertion violation happens here.\nCounterexample:\nx = 1\n\nTransaction trace:\nC.constructor() +// Warning 6328: (115-129): CHC: Assertion violation happens here.\nCounterexample:\nx = 0\n\nTransaction trace:\nC.constructor() +// Warning 6328: (147-161): CHC: Assertion violation happens here.\nCounterexample:\nx = 0\n\nTransaction trace:\nC.constructor() +// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/functions/library_constant.sol b/test/libsolidity/smtCheckerTests/functions/library_constant.sol index 53349f0b6c30..22fccbe70d6c 100644 --- a/test/libsolidity/smtCheckerTests/functions/library_constant.sol +++ b/test/libsolidity/smtCheckerTests/functions/library_constant.sol @@ -19,6 +19,6 @@ contract C { // ==== // SMTEngine: all // ---- -// Warning 6328: (103-122): CHC: Assertion violation happens here. -// Warning 4984: (196-201): CHC: Overflow (resulting value larger than 2**256 - 1) happens here. -// Info 1391: CHC: 4 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. +// Warning 6328: (103-122): CHC: Assertion violation happens here.\nCounterexample:\nTON = 1000\n\nTransaction trace:\nl1.constructor()\nState: TON = 1000\nl1.f1() +// Warning 4984: (196-201): CHC: Overflow (resulting value larger than 2**256 - 1) happens here.\nCounterexample:\n\nx = 115792089237316195423570985008687907853269984665640564039457584007913129639935\n\nTransaction trace:\nC.constructor()\nC.f(115792089237316195423570985008687907853269984665640564039457584007913129639935)\n l1.f2(115792089237316195423570985008687907853269984665640564039457584007913129639935, 1) -- internal call +// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/imports/import_library_2.sol b/test/libsolidity/smtCheckerTests/imports/import_library_2.sol index a1c3160ea23a..1046e6a49b11 100644 --- a/test/libsolidity/smtCheckerTests/imports/import_library_2.sol +++ b/test/libsolidity/smtCheckerTests/imports/import_library_2.sol @@ -25,5 +25,4 @@ contract ERC20 { // ==== // SMTEngine: all // ---- -// Warning 3944: (ERC20.sol:157-162): CHC: Underflow (resulting value less than 0) happens here. -// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. +// Warning 3944: (ERC20.sol:157-162): CHC: Underflow (resulting value less than 0) happens here.\nCounterexample:\n\namount = 1\n\nTransaction trace:\nERC20.constructor()\nERC20.transferFrom(1){ msg.sender: 0x2e15 }\n SafeMath.sub(0, 1) -- internal call 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 6ecfed7914a6..d8838195f544 100644 --- a/test/libsolidity/smtCheckerTests/inheritance/base_contract_assertion_fail_1.sol +++ b/test/libsolidity/smtCheckerTests/inheritance/base_contract_assertion_fail_1.sol @@ -17,4 +17,3 @@ contract C is B { // SMTIgnoreCex: no // ---- // 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 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/inheritance/base_contract_assertion_fail_2.sol b/test/libsolidity/smtCheckerTests/inheritance/base_contract_assertion_fail_2.sol index 85e2677f782a..026ad07ab674 100644 --- a/test/libsolidity/smtCheckerTests/inheritance/base_contract_assertion_fail_2.sol +++ b/test/libsolidity/smtCheckerTests/inheritance/base_contract_assertion_fail_2.sol @@ -24,4 +24,3 @@ contract C is B { // SMTIgnoreCex: no // ---- // Warning 6328: (54-68): CHC: Assertion violation happens here.\nCounterexample:\ny = 0, z = 0, w = 0, a = 0, b = 0, x = 1\n\nTransaction trace:\nC.constructor()\nState: y = 0, z = 0, w = 0, a = 0, b = 0, x = 0\nC.g()\n A.f() -- internal call -// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/inheritance/base_contract_assertion_fail_3.sol b/test/libsolidity/smtCheckerTests/inheritance/base_contract_assertion_fail_3.sol index f1481197f11f..cc5115052c6e 100644 --- a/test/libsolidity/smtCheckerTests/inheritance/base_contract_assertion_fail_3.sol +++ b/test/libsolidity/smtCheckerTests/inheritance/base_contract_assertion_fail_3.sol @@ -30,4 +30,4 @@ contract C is B { // SMTIgnoreCex: no // ---- // Warning 6328: (64-78): CHC: Assertion violation happens here.\nCounterexample:\nx = 2\n\nTransaction trace:\nC.constructor()\nState: x = 0\nC.g()\n B.f() -- internal call\n A.f() -- internal call\n C.v() -- internal call -// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. +// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/inheritance/base_contract_assertion_fail_4.sol b/test/libsolidity/smtCheckerTests/inheritance/base_contract_assertion_fail_4.sol index 04b7ea7480e9..adfcb5e2301a 100644 --- a/test/libsolidity/smtCheckerTests/inheritance/base_contract_assertion_fail_4.sol +++ b/test/libsolidity/smtCheckerTests/inheritance/base_contract_assertion_fail_4.sol @@ -37,4 +37,4 @@ contract C is B, A1 { // SMTIgnoreCex: no // ---- // Warning 6328: (64-78): CHC: Assertion violation happens here.\nCounterexample:\nx = 2\n\nTransaction trace:\nC.constructor()\nState: x = 0\nC.g()\n C.f() -- internal call\n A1.f() -- internal call\n B.f() -- internal call\n A.f() -- internal call\n C.v() -- internal call -// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. +// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/inheritance/base_contract_assertion_fail_5.sol b/test/libsolidity/smtCheckerTests/inheritance/base_contract_assertion_fail_5.sol index e386c4b445b3..89bc75398604 100644 --- a/test/libsolidity/smtCheckerTests/inheritance/base_contract_assertion_fail_5.sol +++ b/test/libsolidity/smtCheckerTests/inheritance/base_contract_assertion_fail_5.sol @@ -31,4 +31,4 @@ contract C is B { // SMTIgnoreCex: no // ---- // Warning 6328: (97-111): CHC: Assertion violation happens here.\nCounterexample:\nx = 0\n\nTransaction trace:\nC.constructor()\nState: x = 0\nC.g()\n B.f() -- internal call\n A.f() -- internal call\n C.v() -- internal call\n A.v() -- internal call -// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. +// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/inheritance/base_contract_assertion_fail_7.sol b/test/libsolidity/smtCheckerTests/inheritance/base_contract_assertion_fail_7.sol index 45cf7fe186ad..9c2981bf10b1 100644 --- a/test/libsolidity/smtCheckerTests/inheritance/base_contract_assertion_fail_7.sol +++ b/test/libsolidity/smtCheckerTests/inheritance/base_contract_assertion_fail_7.sol @@ -24,4 +24,4 @@ contract C is A { // SMTIgnoreCex: no // ---- // Warning 6328: (56-70): CHC: Assertion violation happens here.\nCounterexample:\nx = 2\n\nTransaction trace:\nC.constructor()\nState: x = 0\nC.g()\n A.f() -- internal call\n C.v() -- internal call -// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. +// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/inheritance/base_contract_assertion_fail_9.sol b/test/libsolidity/smtCheckerTests/inheritance/base_contract_assertion_fail_9.sol index 9972c7e3ff26..36b22040a2a5 100644 --- a/test/libsolidity/smtCheckerTests/inheritance/base_contract_assertion_fail_9.sol +++ b/test/libsolidity/smtCheckerTests/inheritance/base_contract_assertion_fail_9.sol @@ -31,4 +31,3 @@ contract C is B { // ---- // Warning 6328: (62-76): CHC: Assertion violation happens here.\nCounterexample:\nx = 2\n\nTransaction trace:\nC.constructor()\nState: x = 0\nB.f()\n A.f() -- internal call\n C.v() -- internal call // Warning 6328: (131-145): CHC: Assertion violation happens here.\nCounterexample:\nx = 0\n\nTransaction trace:\nA.constructor()\nState: x = 0\nA.f()\n A.v() -- internal call -// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/inheritance/constructor_state_variable_init_diamond_middle.sol b/test/libsolidity/smtCheckerTests/inheritance/constructor_state_variable_init_diamond_middle.sol index 8590b0bcfa86..e80e398fe924 100644 --- a/test/libsolidity/smtCheckerTests/inheritance/constructor_state_variable_init_diamond_middle.sol +++ b/test/libsolidity/smtCheckerTests/inheritance/constructor_state_variable_init_diamond_middle.sol @@ -25,6 +25,6 @@ contract D is B, C { // ==== // SMTEngine: all // ---- -// Warning 6328: (134-148): CHC: Assertion violation happens here. -// Warning 6328: (223-237): CHC: Assertion violation happens here. -// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. +// Warning 6328: (134-148): CHC: Assertion violation happens here.\nCounterexample:\nx = 2\n\nTransaction trace:\nD.constructor() +// Warning 6328: (223-237): CHC: Assertion violation happens here.\nCounterexample:\nx = 3\n\nTransaction trace:\nD.constructor() +// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/modifiers/modifier_overriding_4.sol b/test/libsolidity/smtCheckerTests/modifiers/modifier_overriding_4.sol index 652dd811f3d4..d0e82665ccfc 100644 --- a/test/libsolidity/smtCheckerTests/modifiers/modifier_overriding_4.sol +++ b/test/libsolidity/smtCheckerTests/modifiers/modifier_overriding_4.sol @@ -36,7 +36,7 @@ contract D is B,C { // ==== // SMTEngine: all // ---- -// Warning 6328: (160-174): CHC: Assertion violation happens here. -// Warning 6328: (193-207): CHC: Assertion violation happens here. -// Warning 6328: (226-240): CHC: Assertion violation happens here. -// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. +// Warning 6328: (160-174): CHC: Assertion violation happens here.\nCounterexample:\nx = 1\n\nTransaction trace:\nB.constructor()\nState: x = 0\nA.f() +// Warning 6328: (193-207): CHC: Assertion violation happens here.\nCounterexample:\nx = 2\n\nTransaction trace:\nC.constructor()\nState: x = 0\nA.f() +// Warning 6328: (226-240): CHC: Assertion violation happens here.\nCounterexample:\nx = 3\n\nTransaction trace:\nD.constructor()\nState: x = 0\nA.f() +// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/modifiers/modifier_two_invocations_2.sol b/test/libsolidity/smtCheckerTests/modifiers/modifier_two_invocations_2.sol index d6bc51ffd5c3..a41c918571a9 100644 --- a/test/libsolidity/smtCheckerTests/modifiers/modifier_two_invocations_2.sol +++ b/test/libsolidity/smtCheckerTests/modifiers/modifier_two_invocations_2.sol @@ -16,5 +16,5 @@ contract C // ==== // SMTEngine: all // ---- -// Warning 6328: (76-90): CHC: Assertion violation happens here. -// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. +// Warning 6328: (76-90): CHC: Assertion violation happens here.\nCounterexample:\nx = 3\n\nTransaction trace:\nC.constructor()\nState: x = 0\nC.f() +// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/operators/assignment_chain_tuple_contract_3.sol b/test/libsolidity/smtCheckerTests/operators/assignment_chain_tuple_contract_3.sol index e53436a0f66c..1f0fd5829e84 100644 --- a/test/libsolidity/smtCheckerTests/operators/assignment_chain_tuple_contract_3.sol +++ b/test/libsolidity/smtCheckerTests/operators/assignment_chain_tuple_contract_3.sol @@ -23,4 +23,4 @@ contract D is C { // ---- // Warning 6328: (95-109): CHC: Assertion violation happens here.\nCounterexample:\ny = 3, x = 3\n\nTransaction trace:\nD.constructor()\nState: y = 3, x = 3\nC.f() // Warning 6328: (180-194): CHC: Assertion violation happens here.\nCounterexample:\nx = 2\n\nTransaction trace:\nC.constructor()\nState: x = 2\nC.g() -// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. +// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/special/msg_value_inheritance_2.sol b/test/libsolidity/smtCheckerTests/special/msg_value_inheritance_2.sol index 942607bd8a6f..f6c182c1e91c 100644 --- a/test/libsolidity/smtCheckerTests/special/msg_value_inheritance_2.sol +++ b/test/libsolidity/smtCheckerTests/special/msg_value_inheritance_2.sol @@ -14,6 +14,5 @@ contract C is A { // ==== // SMTEngine: all // ---- -// Warning 6328: (60-74): CHC: Assertion violation happens here. -// Warning 6328: (240-254): CHC: Assertion violation happens here. -// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. +// Warning 6328: (60-74): CHC: Assertion violation happens here.\nCounterexample:\nv = 0, x = 115792089237316195423570985008687907853269984665640564039457584007913129637498\n\nTransaction trace:\nC.constructor(){ msg.value: 115792089237316195423570985008687907853269984665640564039457584007913129637498 } +// Warning 6328: (240-254): CHC: Assertion violation happens here.\nCounterexample:\nv = 115792089237316195423570985008687907853269984665640564039457584007913129637498, x = 115792089237316195423570985008687907853269984665640564039457584007913129637498\n\nTransaction trace:\nC.constructor(){ msg.value: 115792089237316195423570985008687907853269984665640564039457584007913129637498 } diff --git a/test/libsolidity/smtCheckerTests/special/msg_value_inheritance_3.sol b/test/libsolidity/smtCheckerTests/special/msg_value_inheritance_3.sol index fc8d6e08f300..4a659978f9f4 100644 --- a/test/libsolidity/smtCheckerTests/special/msg_value_inheritance_3.sol +++ b/test/libsolidity/smtCheckerTests/special/msg_value_inheritance_3.sol @@ -18,5 +18,5 @@ contract C is A, B { // ==== // SMTEngine: all // ---- -// Warning 6328: (60-74): CHC: Assertion violation happens here. -// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. +// Warning 6328: (60-74): CHC: Assertion violation happens here.\nCounterexample:\nx = 115792089237316195423570985008687907853269984665640564039457584007913129637498\n\nTransaction trace:\nC.constructor(){ msg.value: 115792089237316195423570985008687907853269984665640564039457584007913129637498 } +// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. From 780fee18a8bbd8002a138fa7b8a3611bbb10ded5 Mon Sep 17 00:00:00 2001 From: Martin Blicha Date: Wed, 12 Feb 2025 22:10:22 +0100 Subject: [PATCH 0799/1022] Testing: Fix unused variable warning in SMTCheckerTests --- test/libsolidity/SMTCheckerTest.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/libsolidity/SMTCheckerTest.cpp b/test/libsolidity/SMTCheckerTest.cpp index 96a9538f1b4e..d8843e0d3a1e 100644 --- a/test/libsolidity/SMTCheckerTest.cpp +++ b/test/libsolidity/SMTCheckerTest.cpp @@ -131,6 +131,10 @@ SMTCheckerTest::SMTCheckerTest(std::string const& _filename): #elif __linux__ if (os == "linux") m_shouldRun = false; +#else + // On other operating systems this setting is ignored (as we don't test other operating systems in CI), + // but we need to prevent an unused-variable warning. + (void)os; #endif } From 3b965999240510d84d57e7eb12fdad2393ac4d4e Mon Sep 17 00:00:00 2001 From: Martin Blicha Date: Fri, 31 Jan 2025 21:21:05 +0100 Subject: [PATCH 0800/1022] SMTChecker: Allow printing queries for all solvers Since SMTChecker now uses SMT-LIB to represent the queries and pass them to the solvers, we do not have to restrict this option to the "smtlib2" solver. It can be used with any solver. The query will be logged and then passed to the solver as usual. --- Changelog.md | 1 + libsolidity/formal/BMC.cpp | 5 +- libsolidity/formal/CHC.cpp | 5 +- libsolidity/interface/StandardCompiler.cpp | 3 - solc/CommandLineParser.cpp | 4 - .../model_checker_print_query_all/err | 4 - .../model_checker_print_query_bmc/err | 2 - .../model_checker_print_query_chc/err | 2 - .../args | 1 - .../err | 1 - .../exit | 1 - .../input.sol | 9 -- .../args | 1 - .../err | 1 - .../exit | 1 - .../input.sol | 9 -- .../args | 1 - .../err | 1 - .../exit | 1 - .../input.sol | 9 -- .../output.json | 137 ------------------ .../output.json | 40 ----- .../output.json | 98 ------------- .../input.json | 25 ---- .../output.json | 11 -- .../input.json | 26 ---- .../output.json | 11 -- 27 files changed, 6 insertions(+), 404 deletions(-) delete mode 100644 test/cmdlineTests/model_checker_print_query_no_smtlib2_solver_bmc/args delete mode 100644 test/cmdlineTests/model_checker_print_query_no_smtlib2_solver_bmc/err delete mode 100644 test/cmdlineTests/model_checker_print_query_no_smtlib2_solver_bmc/exit delete mode 100644 test/cmdlineTests/model_checker_print_query_no_smtlib2_solver_bmc/input.sol delete mode 100644 test/cmdlineTests/model_checker_print_query_no_smtlib2_solver_chc/args delete mode 100644 test/cmdlineTests/model_checker_print_query_no_smtlib2_solver_chc/err delete mode 100644 test/cmdlineTests/model_checker_print_query_no_smtlib2_solver_chc/exit delete mode 100644 test/cmdlineTests/model_checker_print_query_no_smtlib2_solver_chc/input.sol delete mode 100644 test/cmdlineTests/model_checker_print_query_superflous_solver/args delete mode 100644 test/cmdlineTests/model_checker_print_query_superflous_solver/err delete mode 100644 test/cmdlineTests/model_checker_print_query_superflous_solver/exit delete mode 100644 test/cmdlineTests/model_checker_print_query_superflous_solver/input.sol delete mode 100644 test/cmdlineTests/standard_model_checker_print_query_no_smtlib2_solver/input.json delete mode 100644 test/cmdlineTests/standard_model_checker_print_query_no_smtlib2_solver/output.json delete mode 100644 test/cmdlineTests/standard_model_checker_print_query_superflous_solver/input.json delete mode 100644 test/cmdlineTests/standard_model_checker_print_query_superflous_solver/output.json diff --git a/Changelog.md b/Changelog.md index 5886dca26016..c37993488a36 100644 --- a/Changelog.md +++ b/Changelog.md @@ -7,6 +7,7 @@ Compiler Features: * Error Reporting: Errors reported during code generation now point at the location of the contract when more fine-grained location is not available. * EVM: Support for the EVM version "Osaka". * SMTChecker: Support `block.blobbasefee` and `blobhash`. + * SMTChecker: The option `--model-checker-print-query` no longer requires `--model-checker-solvers smtlib2`. * SMTChecker: Z3 is now a runtime dependency, not a build dependency (except for emscripten build). * Yul Parser: Make name clash with a builtin a non-fatal error. diff --git a/libsolidity/formal/BMC.cpp b/libsolidity/formal/BMC.cpp index 5fb2f5a9fd75..c29c21e5cc3f 100644 --- a/libsolidity/formal/BMC.cpp +++ b/libsolidity/formal/BMC.cpp @@ -49,7 +49,6 @@ BMC::BMC( ): SMTEncoder(_context, _settings, _errorReporter, _unsupportedErrorReporter, _provedSafeReporter, _charStreamProvider) { - solAssert(!_settings.printQuery || _settings.solvers == SMTSolverChoice::SMTLIB2(), "Only SMTLib2 solver can be enabled to print queries"); std::vector> solvers; if (_settings.solvers.smtlib2) solvers.emplace_back(std::make_unique(_smtlib2Responses, _smtCallback, _settings.timeout)); @@ -1262,8 +1261,10 @@ BMC::checkSatisfiableAndGenerateModel(std::vector const& _e 6240_error, "BMC: Requested query:\n" + smtlibCode ); + result = CheckResult::UNKNOWN; } - tie(result, values) = m_interface->check(_expressionsToEvaluate); + else + tie(result, values) = m_interface->check(_expressionsToEvaluate); } catch (smtutil::SolverError const& _e) { diff --git a/libsolidity/formal/CHC.cpp b/libsolidity/formal/CHC.cpp index 3a5da1e587cc..c313ae54e1ae 100644 --- a/libsolidity/formal/CHC.cpp +++ b/libsolidity/formal/CHC.cpp @@ -64,9 +64,7 @@ CHC::CHC( SMTEncoder(_context, _settings, _errorReporter, _unsupportedErrorReporter, _provedSafeReporter, _charStreamProvider), m_smtlib2Responses(_smtlib2Responses), m_smtCallback(_smtCallback) -{ - solAssert(!_settings.printQuery || _settings.solvers == smtutil::SMTSolverChoice::SMTLIB2(), "Only SMTLib2 solver can be enabled to print queries"); -} +{} void CHC::analyze(SourceUnit const& _source) { @@ -1897,6 +1895,7 @@ CHCSolverInterface::QueryResult CHC::query(smtutil::Expression const& _query, la 2339_error, "CHC: Requested query:\n" + smtLibCode ); + return {.answer = CheckResult::UNKNOWN, .invariant = smtutil::Expression(true), .cex = {}}; } auto result = m_interface->query(_query); switch (result.answer) diff --git a/libsolidity/interface/StandardCompiler.cpp b/libsolidity/interface/StandardCompiler.cpp index 520f4d5f1c8f..cf110079b026 100644 --- a/libsolidity/interface/StandardCompiler.cpp +++ b/libsolidity/interface/StandardCompiler.cpp @@ -1141,9 +1141,6 @@ std::variant StandardCompiler::parseI if (!printQuery.is_boolean()) return formatFatalError(Error::Type::JSONError, "settings.modelChecker.printQuery must be a Boolean value."); - if (!(ret.modelCheckerSettings.solvers == smtutil::SMTSolverChoice::SMTLIB2())) - return formatFatalError(Error::Type::JSONError, "Only SMTLib2 solver can be enabled to print queries"); - ret.modelCheckerSettings.printQuery = printQuery.get(); } diff --git a/solc/CommandLineParser.cpp b/solc/CommandLineParser.cpp index b02b1ed8c702..e5b096c2a023 100644 --- a/solc/CommandLineParser.cpp +++ b/solc/CommandLineParser.cpp @@ -1435,11 +1435,7 @@ void CommandLineParser::processArgs() } if (m_args.count(g_strModelCheckerPrintQuery)) - { - if (!(m_options.modelChecker.settings.solvers == smtutil::SMTSolverChoice::SMTLIB2())) - solThrow(CommandLineValidationError, "Only SMTLib2 solver can be enabled to print queries"); m_options.modelChecker.settings.printQuery = true; - } if (m_args.count(g_strModelCheckerTargets)) { diff --git a/test/cmdlineTests/model_checker_print_query_all/err b/test/cmdlineTests/model_checker_print_query_all/err index 92a3b7f7b50f..e696c6ed3836 100644 --- a/test/cmdlineTests/model_checker_print_query_all/err +++ b/test/cmdlineTests/model_checker_print_query_all/err @@ -86,8 +86,6 @@ Info: CHC: Requested query: Warning: CHC: 1 verification condition(s) could not be proved. Enable the model checker option "show unproved" to see all of them. Consider choosing a specific contract to be verified in order to reduce the solving problems. Consider increasing the timeout per query. -Warning: CHC analysis was not possible. No Horn solver was available. None of the installed solvers was enabled. - Info: BMC: Requested query: (set-option :produce-models true) (set-option :timeout 1000) @@ -120,5 +118,3 @@ Info: BMC: Requested query: Warning: BMC: 1 verification condition(s) could not be proved. Enable the model checker option "show unproved" to see all of them. Consider choosing a specific contract to be verified in order to reduce the solving problems. Consider increasing the timeout per query. - -Warning: BMC analysis was not possible. No SMT solver (Z3 or cvc5) was available. None of the installed solvers was enabled. diff --git a/test/cmdlineTests/model_checker_print_query_bmc/err b/test/cmdlineTests/model_checker_print_query_bmc/err index efbc2a3aef9b..4713ac13e3ca 100644 --- a/test/cmdlineTests/model_checker_print_query_bmc/err +++ b/test/cmdlineTests/model_checker_print_query_bmc/err @@ -27,5 +27,3 @@ Info: BMC: Requested query: Warning: BMC: 1 verification condition(s) could not be proved. Enable the model checker option "show unproved" to see all of them. Consider choosing a specific contract to be verified in order to reduce the solving problems. Consider increasing the timeout per query. - -Warning: BMC analysis was not possible. No SMT solver (Z3 or cvc5) was available. None of the installed solvers was enabled. diff --git a/test/cmdlineTests/model_checker_print_query_chc/err b/test/cmdlineTests/model_checker_print_query_chc/err index 9c18265be4e6..a55ad5cea7d1 100644 --- a/test/cmdlineTests/model_checker_print_query_chc/err +++ b/test/cmdlineTests/model_checker_print_query_chc/err @@ -85,5 +85,3 @@ Info: CHC: Requested query: Warning: CHC: 1 verification condition(s) could not be proved. Enable the model checker option "show unproved" to see all of them. Consider choosing a specific contract to be verified in order to reduce the solving problems. Consider increasing the timeout per query. - -Warning: CHC analysis was not possible. No Horn solver was available. None of the installed solvers was enabled. diff --git a/test/cmdlineTests/model_checker_print_query_no_smtlib2_solver_bmc/args b/test/cmdlineTests/model_checker_print_query_no_smtlib2_solver_bmc/args deleted file mode 100644 index 12b7c324584b..000000000000 --- a/test/cmdlineTests/model_checker_print_query_no_smtlib2_solver_bmc/args +++ /dev/null @@ -1 +0,0 @@ ---model-checker-engine bmc --model-checker-print-query --model-checker-solvers z3 diff --git a/test/cmdlineTests/model_checker_print_query_no_smtlib2_solver_bmc/err b/test/cmdlineTests/model_checker_print_query_no_smtlib2_solver_bmc/err deleted file mode 100644 index 1e2296446199..000000000000 --- a/test/cmdlineTests/model_checker_print_query_no_smtlib2_solver_bmc/err +++ /dev/null @@ -1 +0,0 @@ -Error: Only SMTLib2 solver can be enabled to print queries diff --git a/test/cmdlineTests/model_checker_print_query_no_smtlib2_solver_bmc/exit b/test/cmdlineTests/model_checker_print_query_no_smtlib2_solver_bmc/exit deleted file mode 100644 index d00491fd7e5b..000000000000 --- a/test/cmdlineTests/model_checker_print_query_no_smtlib2_solver_bmc/exit +++ /dev/null @@ -1 +0,0 @@ -1 diff --git a/test/cmdlineTests/model_checker_print_query_no_smtlib2_solver_bmc/input.sol b/test/cmdlineTests/model_checker_print_query_no_smtlib2_solver_bmc/input.sol deleted file mode 100644 index eb4cd572ae22..000000000000 --- a/test/cmdlineTests/model_checker_print_query_no_smtlib2_solver_bmc/input.sol +++ /dev/null @@ -1,9 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0 -pragma solidity >=0.0; -contract C -{ - function f() public pure { - uint x = 0; - assert(x == 0); - } -} diff --git a/test/cmdlineTests/model_checker_print_query_no_smtlib2_solver_chc/args b/test/cmdlineTests/model_checker_print_query_no_smtlib2_solver_chc/args deleted file mode 100644 index e3a8c32d4716..000000000000 --- a/test/cmdlineTests/model_checker_print_query_no_smtlib2_solver_chc/args +++ /dev/null @@ -1 +0,0 @@ ---model-checker-engine chc --model-checker-print-query --model-checker-solvers z3 diff --git a/test/cmdlineTests/model_checker_print_query_no_smtlib2_solver_chc/err b/test/cmdlineTests/model_checker_print_query_no_smtlib2_solver_chc/err deleted file mode 100644 index 1e2296446199..000000000000 --- a/test/cmdlineTests/model_checker_print_query_no_smtlib2_solver_chc/err +++ /dev/null @@ -1 +0,0 @@ -Error: Only SMTLib2 solver can be enabled to print queries diff --git a/test/cmdlineTests/model_checker_print_query_no_smtlib2_solver_chc/exit b/test/cmdlineTests/model_checker_print_query_no_smtlib2_solver_chc/exit deleted file mode 100644 index d00491fd7e5b..000000000000 --- a/test/cmdlineTests/model_checker_print_query_no_smtlib2_solver_chc/exit +++ /dev/null @@ -1 +0,0 @@ -1 diff --git a/test/cmdlineTests/model_checker_print_query_no_smtlib2_solver_chc/input.sol b/test/cmdlineTests/model_checker_print_query_no_smtlib2_solver_chc/input.sol deleted file mode 100644 index eb4cd572ae22..000000000000 --- a/test/cmdlineTests/model_checker_print_query_no_smtlib2_solver_chc/input.sol +++ /dev/null @@ -1,9 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0 -pragma solidity >=0.0; -contract C -{ - function f() public pure { - uint x = 0; - assert(x == 0); - } -} diff --git a/test/cmdlineTests/model_checker_print_query_superflous_solver/args b/test/cmdlineTests/model_checker_print_query_superflous_solver/args deleted file mode 100644 index 64e5d88728ea..000000000000 --- a/test/cmdlineTests/model_checker_print_query_superflous_solver/args +++ /dev/null @@ -1 +0,0 @@ ---model-checker-engine bmc --model-checker-print-query --model-checker-solvers z3,smtlib2 diff --git a/test/cmdlineTests/model_checker_print_query_superflous_solver/err b/test/cmdlineTests/model_checker_print_query_superflous_solver/err deleted file mode 100644 index 1e2296446199..000000000000 --- a/test/cmdlineTests/model_checker_print_query_superflous_solver/err +++ /dev/null @@ -1 +0,0 @@ -Error: Only SMTLib2 solver can be enabled to print queries diff --git a/test/cmdlineTests/model_checker_print_query_superflous_solver/exit b/test/cmdlineTests/model_checker_print_query_superflous_solver/exit deleted file mode 100644 index d00491fd7e5b..000000000000 --- a/test/cmdlineTests/model_checker_print_query_superflous_solver/exit +++ /dev/null @@ -1 +0,0 @@ -1 diff --git a/test/cmdlineTests/model_checker_print_query_superflous_solver/input.sol b/test/cmdlineTests/model_checker_print_query_superflous_solver/input.sol deleted file mode 100644 index eb4cd572ae22..000000000000 --- a/test/cmdlineTests/model_checker_print_query_superflous_solver/input.sol +++ /dev/null @@ -1,9 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0 -pragma solidity >=0.0; -contract C -{ - function f() public pure { - uint x = 0; - assert(x == 0); - } -} diff --git a/test/cmdlineTests/standard_model_checker_print_query_all/output.json b/test/cmdlineTests/standard_model_checker_print_query_all/output.json index 1108d790786a..85c4e142c383 100644 --- a/test/cmdlineTests/standard_model_checker_print_query_all/output.json +++ b/test/cmdlineTests/standard_model_checker_print_query_all/output.json @@ -1,121 +1,4 @@ { - "auxiliaryInputRequested": { - "smtlib2queries": { - "0x89dce9b2e59f1b2d3445ec646e15e2609ff358edb66afa7227538979017e0f7b": "(set-option :timeout 1000) -(set-logic HORN) -(declare-datatypes ((|abi_type| 0)) (((|abi_type|)))) -(declare-datatypes ((|ecrecover_input_type| 0)) (((|ecrecover_input_type| (|hash| Int) (|v| Int) (|r| Int) (|s| Int))))) -(declare-datatypes ((|bytes_tuple| 0)) (((|bytes_tuple| (|bytes_tuple_accessor_array| (Array Int Int)) (|bytes_tuple_accessor_length| Int))))) -(declare-datatypes ((|crypto_type| 0)) (((|crypto_type| (|ecrecover| (Array |ecrecover_input_type| Int)) (|keccak256| (Array |bytes_tuple| Int)) (|ripemd160| (Array |bytes_tuple| Int)) (|sha256| (Array |bytes_tuple| Int)))))) -(declare-datatypes ((|state_type| 0)) (((|state_type| (|balances| (Array Int Int)))))) -(declare-fun |interface_0_C_16| (Int |abi_type| |crypto_type| |state_type|) Bool) -(declare-fun |nondet_interface_1_C_16| (Int Int |abi_type| |crypto_type| |state_type| |state_type|) Bool) -(declare-datatypes ((|tx_type| 0)) (((|tx_type| (|blobhash| (Array Int Int)) (|block.basefee| Int) (|block.blobbasefee| Int) (|block.chainid| Int) (|block.coinbase| Int) (|block.gaslimit| Int) (|block.number| Int) (|block.prevrandao| Int) (|block.timestamp| Int) (|blockhash| (Array Int Int)) (|msg.data| |bytes_tuple|) (|msg.sender| Int) (|msg.sig| Int) (|msg.value| Int) (|tx.gasprice| Int) (|tx.origin| Int))))) -(declare-fun |summary_constructor_2_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool) -(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (this_0 Int)) -(=> (= error_0 0) (nondet_interface_1_C_16 error_0 this_0 abi_0 crypto_0 state_0 state_0))) -) -(declare-fun |summary_3_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool) -(declare-fun |summary_4_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool) -(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|)) -(=> (and (and (nondet_interface_1_C_16 error_0 this_0 abi_0 crypto_0 state_0 state_1) true) (and (= error_0 0) (summary_4_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2))) (nondet_interface_1_C_16 error_1 this_0 abi_0 crypto_0 state_0 state_2))) -) -(declare-fun |block_5_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int) Bool) -(declare-fun |block_6_f_14_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int) Bool) -(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_1 Int)) -(block_5_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1)) -) -(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_1 Int)) -(=> (and (and (block_5_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true)) true) (block_6_f_14_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1))) -) -(declare-fun |block_7_return_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int) Bool) -(declare-fun |block_8_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int) Bool) -(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (block_6_f_14_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (= expr_11_1 (= expr_9_0 expr_10_0)) (and (=> true true) (and (= expr_10_0 0) (and (=> true (and (>= expr_9_0 0) (<= expr_9_0 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (= expr_9_0 x_5_2) (and (= x_5_2 expr_6_0) (and (=> true true) (and (= expr_6_0 0) (and (= x_5_1 0) true)))))))))) (and (and true (not expr_11_1)) (= error_1 1))) (block_8_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_2))) -) -(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_1 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_2 Int)) -(=> (block_8_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_2) (summary_3_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1))) -) -(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (block_6_f_14_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (= error_1 error_0) (and (= expr_11_1 (= expr_9_0 expr_10_0)) (and (=> true true) (and (= expr_10_0 0) (and (=> true (and (>= expr_9_0 0) (<= expr_9_0 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (= expr_9_0 x_5_2) (and (= x_5_2 expr_6_0) (and (=> true true) (and (= expr_6_0 0) (and (= x_5_1 0) true))))))))))) true) (block_7_return_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_2))) -) -(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_1 Int)) -(=> (and (and (block_7_return_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) true) true) (summary_3_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1))) -) -(declare-fun |block_9_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int) Bool) -(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_1 Int)) -(block_9_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1)) -) -(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_1 Int)) -(=> (and (and (block_9_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (summary_3_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_2 state_3) (and (= state_2 (|state_type| (store (|balances| state_1) this_0 (+ (select (|balances| state_1) this_0) funds_2_0)))) (and (and (>= (+ (select (|balances| state_1) this_0) funds_2_0) 0) (<= (+ (select (|balances| state_1) this_0) funds_2_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935)) (and (>= funds_2_0 (|msg.value| tx_0)) (and (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.blobbasefee| tx_0) 0) (<= (|block.blobbasefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (and (and (and (and (and (= (|msg.value| tx_0) 0) (= (|msg.sig| tx_0) 638722032)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 0) 38)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 1) 18)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 2) 31)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 3) 240)) (>= (|bytes_tuple_accessor_length| (|msg.data| tx_0)) 4))) (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true))))))) true) (summary_4_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_3))) -) -(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|)) -(=> (and (and (interface_0_C_16 this_0 abi_0 crypto_0 state_0) true) (and (summary_4_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (= error_0 0))) (interface_0_C_16 this_0 abi_0 crypto_0 state_1))) -) -(declare-fun |contract_initializer_10_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool) -(declare-fun |contract_initializer_entry_11_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool) -(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|)) -(=> (and (and (= state_1 state_0) (= error_0 0)) true) (contract_initializer_entry_11_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1))) -) -(declare-fun |contract_initializer_after_init_12_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool) -(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|)) -(=> (and (and (contract_initializer_entry_11_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) true) (contract_initializer_after_init_12_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1))) -) -(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|)) -(=> (and (and (contract_initializer_after_init_12_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) true) (contract_initializer_10_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1))) -) -(declare-fun |implicit_constructor_entry_13_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool) -(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|)) -(=> (and (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true) (>= (select (|balances| state_1) this_0) (|msg.value| tx_0))) (implicit_constructor_entry_13_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1))) -) -(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|)) -(=> (and (and (implicit_constructor_entry_13_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (and (contract_initializer_10_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2) true)) (> error_1 0)) (summary_constructor_2_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_2))) -) -(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|)) -(=> (and (and (implicit_constructor_entry_13_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (and (= error_1 0) (and (contract_initializer_10_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2) true))) true) (summary_constructor_2_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_2))) -) -(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|)) -(=> (and (and (summary_constructor_2_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) (and (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.blobbasefee| tx_0) 0) (<= (|block.blobbasefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (= (|msg.value| tx_0) 0)) (= error_0 0))) (interface_0_C_16 this_0 abi_0 crypto_0 state_1))) -) -(declare-fun |error_target_3| () Bool) -(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|)) -(=> (and (and (interface_0_C_16 this_0 abi_0 crypto_0 state_0) true) (and (summary_4_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (= error_0 1))) error_target_3)) -)(assert -(forall ((UNUSED Bool)) -(=> error_target_3 false))) -(check-sat) -", - "0xca8e4027f5350278d291f782ff3ec7a7f618e8a729beb4173e7dad3f008af497": "(set-option :produce-models true) -(set-option :timeout 1000) -(set-logic ALL) -(declare-fun |x_5_3| () Int) -(declare-fun |error_0| () Int) -(declare-fun |this_0| () Int) -(declare-datatypes ((|bytes_tuple| 0)) (((|bytes_tuple| (|bytes_tuple_accessor_array| (Array Int Int)) (|bytes_tuple_accessor_length| Int))))) -(declare-datatypes ((|tx_type| 0)) (((|tx_type| (|blobhash| (Array Int Int)) (|block.basefee| Int) (|block.blobbasefee| Int) (|block.chainid| Int) (|block.coinbase| Int) (|block.gaslimit| Int) (|block.number| Int) (|block.prevrandao| Int) (|block.timestamp| Int) (|blockhash| (Array Int Int)) (|msg.data| |bytes_tuple|) (|msg.sender| Int) (|msg.sig| Int) (|msg.value| Int) (|tx.gasprice| Int) (|tx.origin| Int))))) -(declare-fun |tx_0| () |tx_type|) -(declare-datatypes ((|ecrecover_input_type| 0)) (((|ecrecover_input_type| (|hash| Int) (|v| Int) (|r| Int) (|s| Int))))) -(declare-datatypes ((|crypto_type| 0)) (((|crypto_type| (|ecrecover| (Array |ecrecover_input_type| Int)) (|keccak256| (Array |bytes_tuple| Int)) (|ripemd160| (Array |bytes_tuple| Int)) (|sha256| (Array |bytes_tuple| Int)))))) -(declare-fun |crypto_0| () |crypto_type|) -(declare-datatypes ((|abi_type| 0)) (((|abi_type|)))) -(declare-fun |abi_0| () |abi_type|) -(declare-datatypes ((|state_type| 0)) (((|state_type| (|balances| (Array Int Int)))))) -(declare-fun |state_0| () |state_type|) -(declare-fun |x_5_4| () Int) -(declare-fun |x_5_0| () Int) -(declare-fun |expr_6_0| () Int) -(declare-fun |x_5_1| () Int) -(declare-fun |expr_9_0| () Int) -(declare-fun |expr_10_0| () Int) -(declare-fun |expr_11_1| () Bool) -(assert (and (and (and true true) (and (= expr_11_1 (= expr_9_0 expr_10_0)) (and (=> (and true true) true) (and (= expr_10_0 0) (and (=> (and true true) (and (>= expr_9_0 0) (<= expr_9_0 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (= expr_9_0 x_5_1) (and (ite (and true true) (= x_5_1 expr_6_0) (= x_5_1 x_5_0)) (and (=> (and true true) true) (and (= expr_6_0 0) (and (= x_5_0 0) (and (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.blobbasefee| tx_0) 0) (<= (|block.blobbasefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (and (and (and (and (and (= (|msg.value| tx_0) 0) (= (|msg.sig| tx_0) 638722032)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 0) 38)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 1) 18)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 2) 31)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 3) 240)) (>= (|bytes_tuple_accessor_length| (|msg.data| tx_0)) 4))) true))))))))))) (not expr_11_1))) -(declare-const |EVALEXPR_0| Int) -(assert (= |EVALEXPR_0| x_5_1)) -(check-sat) -(get-value (|EVALEXPR_0| )) -" - } - }, "errors": [ { "component": "general", @@ -305,16 +188,6 @@ "severity": "warning", "type": "Warning" }, - { - "component": "general", - "errorCode": "3996", - "formattedMessage": "Warning: CHC analysis was not possible. No Horn solver was available. None of the installed solvers was enabled. - -", - "message": "CHC analysis was not possible. No Horn solver was available. None of the installed solvers was enabled.", - "severity": "warning", - "type": "Warning" - }, { "component": "general", "errorCode": "6240", @@ -392,16 +265,6 @@ "message": "BMC: 1 verification condition(s) could not be proved. Enable the model checker option \"show unproved\" to see all of them. Consider choosing a specific contract to be verified in order to reduce the solving problems. Consider increasing the timeout per query.", "severity": "warning", "type": "Warning" - }, - { - "component": "general", - "errorCode": "8084", - "formattedMessage": "Warning: BMC analysis was not possible. No SMT solver (Z3 or cvc5) was available. None of the installed solvers was enabled. - -", - "message": "BMC analysis was not possible. No SMT solver (Z3 or cvc5) was available. None of the installed solvers was enabled.", - "severity": "warning", - "type": "Warning" } ], "sources": { diff --git a/test/cmdlineTests/standard_model_checker_print_query_bmc/output.json b/test/cmdlineTests/standard_model_checker_print_query_bmc/output.json index a0be6110b5f3..21fdedc40918 100644 --- a/test/cmdlineTests/standard_model_checker_print_query_bmc/output.json +++ b/test/cmdlineTests/standard_model_checker_print_query_bmc/output.json @@ -1,34 +1,4 @@ { - "auxiliaryInputRequested": { - "smtlib2queries": { - "0x41ee12cade46d5e1c28896216d2b220d2d28b47c925b0191941303216c8635dd": "(set-option :produce-models true) -(set-logic ALL) -(declare-fun |error_0| () Int) -(declare-fun |this_0| () Int) -(declare-datatypes ((|bytes_tuple| 0)) (((|bytes_tuple| (|bytes_tuple_accessor_array| (Array Int Int)) (|bytes_tuple_accessor_length| Int))))) -(declare-datatypes ((|tx_type| 0)) (((|tx_type| (|blobhash| (Array Int Int)) (|block.basefee| Int) (|block.blobbasefee| Int) (|block.chainid| Int) (|block.coinbase| Int) (|block.gaslimit| Int) (|block.number| Int) (|block.prevrandao| Int) (|block.timestamp| Int) (|blockhash| (Array Int Int)) (|msg.data| |bytes_tuple|) (|msg.sender| Int) (|msg.sig| Int) (|msg.value| Int) (|tx.gasprice| Int) (|tx.origin| Int))))) -(declare-fun |tx_0| () |tx_type|) -(declare-datatypes ((|ecrecover_input_type| 0)) (((|ecrecover_input_type| (|hash| Int) (|v| Int) (|r| Int) (|s| Int))))) -(declare-datatypes ((|crypto_type| 0)) (((|crypto_type| (|ecrecover| (Array |ecrecover_input_type| Int)) (|keccak256| (Array |bytes_tuple| Int)) (|ripemd160| (Array |bytes_tuple| Int)) (|sha256| (Array |bytes_tuple| Int)))))) -(declare-fun |crypto_0| () |crypto_type|) -(declare-datatypes ((|abi_type| 0)) (((|abi_type|)))) -(declare-fun |abi_0| () |abi_type|) -(declare-datatypes ((|state_type| 0)) (((|state_type| (|balances| (Array Int Int)))))) -(declare-fun |state_0| () |state_type|) -(declare-fun |x_5_0| () Int) -(declare-fun |expr_6_0| () Int) -(declare-fun |x_5_1| () Int) -(declare-fun |expr_9_0| () Int) -(declare-fun |expr_10_0| () Int) -(declare-fun |expr_11_1| () Bool) -(assert (and (and (and true true) (and (= expr_11_1 (= expr_9_0 expr_10_0)) (and (=> (and true true) true) (and (= expr_10_0 0) (and (=> (and true true) (and (>= expr_9_0 0) (<= expr_9_0 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (= expr_9_0 x_5_1) (and (ite (and true true) (= x_5_1 expr_6_0) (= x_5_1 x_5_0)) (and (=> (and true true) true) (and (= expr_6_0 0) (and (= x_5_0 0) (and (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.blobbasefee| tx_0) 0) (<= (|block.blobbasefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (and (and (and (and (and (= (|msg.value| tx_0) 0) (= (|msg.sig| tx_0) 638722032)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 0) 38)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 1) 18)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 2) 31)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 3) 240)) (>= (|bytes_tuple_accessor_length| (|msg.data| tx_0)) 4))) true))))))))))) (not expr_11_1))) -(declare-const |EVALEXPR_0| Int) -(assert (= |EVALEXPR_0| x_5_1)) -(check-sat) -(get-value (|EVALEXPR_0| )) -" - } - }, "errors": [ { "component": "general", @@ -101,16 +71,6 @@ "message": "BMC: 1 verification condition(s) could not be proved. Enable the model checker option \"show unproved\" to see all of them. Consider choosing a specific contract to be verified in order to reduce the solving problems. Consider increasing the timeout per query.", "severity": "warning", "type": "Warning" - }, - { - "component": "general", - "errorCode": "8084", - "formattedMessage": "Warning: BMC analysis was not possible. No SMT solver (Z3 or cvc5) was available. None of the installed solvers was enabled. - -", - "message": "BMC analysis was not possible. No SMT solver (Z3 or cvc5) was available. None of the installed solvers was enabled.", - "severity": "warning", - "type": "Warning" } ], "sources": { diff --git a/test/cmdlineTests/standard_model_checker_print_query_chc/output.json b/test/cmdlineTests/standard_model_checker_print_query_chc/output.json index be0d9fa9e912..57c81ec50a47 100644 --- a/test/cmdlineTests/standard_model_checker_print_query_chc/output.json +++ b/test/cmdlineTests/standard_model_checker_print_query_chc/output.json @@ -1,92 +1,4 @@ { - "auxiliaryInputRequested": { - "smtlib2queries": { - "0x89dce9b2e59f1b2d3445ec646e15e2609ff358edb66afa7227538979017e0f7b": "(set-option :timeout 1000) -(set-logic HORN) -(declare-datatypes ((|abi_type| 0)) (((|abi_type|)))) -(declare-datatypes ((|ecrecover_input_type| 0)) (((|ecrecover_input_type| (|hash| Int) (|v| Int) (|r| Int) (|s| Int))))) -(declare-datatypes ((|bytes_tuple| 0)) (((|bytes_tuple| (|bytes_tuple_accessor_array| (Array Int Int)) (|bytes_tuple_accessor_length| Int))))) -(declare-datatypes ((|crypto_type| 0)) (((|crypto_type| (|ecrecover| (Array |ecrecover_input_type| Int)) (|keccak256| (Array |bytes_tuple| Int)) (|ripemd160| (Array |bytes_tuple| Int)) (|sha256| (Array |bytes_tuple| Int)))))) -(declare-datatypes ((|state_type| 0)) (((|state_type| (|balances| (Array Int Int)))))) -(declare-fun |interface_0_C_16| (Int |abi_type| |crypto_type| |state_type|) Bool) -(declare-fun |nondet_interface_1_C_16| (Int Int |abi_type| |crypto_type| |state_type| |state_type|) Bool) -(declare-datatypes ((|tx_type| 0)) (((|tx_type| (|blobhash| (Array Int Int)) (|block.basefee| Int) (|block.blobbasefee| Int) (|block.chainid| Int) (|block.coinbase| Int) (|block.gaslimit| Int) (|block.number| Int) (|block.prevrandao| Int) (|block.timestamp| Int) (|blockhash| (Array Int Int)) (|msg.data| |bytes_tuple|) (|msg.sender| Int) (|msg.sig| Int) (|msg.value| Int) (|tx.gasprice| Int) (|tx.origin| Int))))) -(declare-fun |summary_constructor_2_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool) -(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (this_0 Int)) -(=> (= error_0 0) (nondet_interface_1_C_16 error_0 this_0 abi_0 crypto_0 state_0 state_0))) -) -(declare-fun |summary_3_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool) -(declare-fun |summary_4_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool) -(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|)) -(=> (and (and (nondet_interface_1_C_16 error_0 this_0 abi_0 crypto_0 state_0 state_1) true) (and (= error_0 0) (summary_4_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2))) (nondet_interface_1_C_16 error_1 this_0 abi_0 crypto_0 state_0 state_2))) -) -(declare-fun |block_5_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int) Bool) -(declare-fun |block_6_f_14_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int) Bool) -(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_1 Int)) -(block_5_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1)) -) -(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_1 Int)) -(=> (and (and (block_5_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true)) true) (block_6_f_14_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1))) -) -(declare-fun |block_7_return_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int) Bool) -(declare-fun |block_8_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int) Bool) -(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (block_6_f_14_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (= expr_11_1 (= expr_9_0 expr_10_0)) (and (=> true true) (and (= expr_10_0 0) (and (=> true (and (>= expr_9_0 0) (<= expr_9_0 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (= expr_9_0 x_5_2) (and (= x_5_2 expr_6_0) (and (=> true true) (and (= expr_6_0 0) (and (= x_5_1 0) true)))))))))) (and (and true (not expr_11_1)) (= error_1 1))) (block_8_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_2))) -) -(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_1 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_2 Int)) -(=> (block_8_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_2) (summary_3_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1))) -) -(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_1 Int) (x_5_2 Int)) -(=> (and (and (block_6_f_14_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (= error_1 error_0) (and (= expr_11_1 (= expr_9_0 expr_10_0)) (and (=> true true) (and (= expr_10_0 0) (and (=> true (and (>= expr_9_0 0) (<= expr_9_0 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (= expr_9_0 x_5_2) (and (= x_5_2 expr_6_0) (and (=> true true) (and (= expr_6_0 0) (and (= x_5_1 0) true))))))))))) true) (block_7_return_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_2))) -) -(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_1 Int)) -(=> (and (and (block_7_return_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) true) true) (summary_3_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1))) -) -(declare-fun |block_9_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int) Bool) -(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_1 Int)) -(block_9_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1)) -) -(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_1 Int)) -(=> (and (and (block_9_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (summary_3_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_2 state_3) (and (= state_2 (|state_type| (store (|balances| state_1) this_0 (+ (select (|balances| state_1) this_0) funds_2_0)))) (and (and (>= (+ (select (|balances| state_1) this_0) funds_2_0) 0) (<= (+ (select (|balances| state_1) this_0) funds_2_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935)) (and (>= funds_2_0 (|msg.value| tx_0)) (and (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.blobbasefee| tx_0) 0) (<= (|block.blobbasefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (and (and (and (and (and (= (|msg.value| tx_0) 0) (= (|msg.sig| tx_0) 638722032)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 0) 38)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 1) 18)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 2) 31)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 3) 240)) (>= (|bytes_tuple_accessor_length| (|msg.data| tx_0)) 4))) (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true))))))) true) (summary_4_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_3))) -) -(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|)) -(=> (and (and (interface_0_C_16 this_0 abi_0 crypto_0 state_0) true) (and (summary_4_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (= error_0 0))) (interface_0_C_16 this_0 abi_0 crypto_0 state_1))) -) -(declare-fun |contract_initializer_10_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool) -(declare-fun |contract_initializer_entry_11_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool) -(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|)) -(=> (and (and (= state_1 state_0) (= error_0 0)) true) (contract_initializer_entry_11_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1))) -) -(declare-fun |contract_initializer_after_init_12_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool) -(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|)) -(=> (and (and (contract_initializer_entry_11_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) true) (contract_initializer_after_init_12_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1))) -) -(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|)) -(=> (and (and (contract_initializer_after_init_12_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) true) (contract_initializer_10_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1))) -) -(declare-fun |implicit_constructor_entry_13_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool) -(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|)) -(=> (and (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true) (>= (select (|balances| state_1) this_0) (|msg.value| tx_0))) (implicit_constructor_entry_13_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1))) -) -(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|)) -(=> (and (and (implicit_constructor_entry_13_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (and (contract_initializer_10_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2) true)) (> error_1 0)) (summary_constructor_2_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_2))) -) -(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|)) -(=> (and (and (implicit_constructor_entry_13_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (and (= error_1 0) (and (contract_initializer_10_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2) true))) true) (summary_constructor_2_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_2))) -) -(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|)) -(=> (and (and (summary_constructor_2_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) (and (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.blobbasefee| tx_0) 0) (<= (|block.blobbasefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (= (|msg.value| tx_0) 0)) (= error_0 0))) (interface_0_C_16 this_0 abi_0 crypto_0 state_1))) -) -(declare-fun |error_target_3| () Bool) -(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|)) -(=> (and (and (interface_0_C_16 this_0 abi_0 crypto_0 state_0) true) (and (summary_4_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (= error_0 1))) error_target_3)) -)(assert -(forall ((UNUSED Bool)) -(=> error_target_3 false))) -(check-sat) -" - } - }, "errors": [ { "component": "general", @@ -275,16 +187,6 @@ "message": "CHC: 1 verification condition(s) could not be proved. Enable the model checker option \"show unproved\" to see all of them. Consider choosing a specific contract to be verified in order to reduce the solving problems. Consider increasing the timeout per query.", "severity": "warning", "type": "Warning" - }, - { - "component": "general", - "errorCode": "3996", - "formattedMessage": "Warning: CHC analysis was not possible. No Horn solver was available. None of the installed solvers was enabled. - -", - "message": "CHC analysis was not possible. No Horn solver was available. None of the installed solvers was enabled.", - "severity": "warning", - "type": "Warning" } ], "sources": { diff --git a/test/cmdlineTests/standard_model_checker_print_query_no_smtlib2_solver/input.json b/test/cmdlineTests/standard_model_checker_print_query_no_smtlib2_solver/input.json deleted file mode 100644 index 0159c256e6ed..000000000000 --- a/test/cmdlineTests/standard_model_checker_print_query_no_smtlib2_solver/input.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "language": "Solidity", - "sources": - { - "A": - { - "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\n - contract C - { - function f() public pure { - uint x = 0; - assert(x == 0); - } - }" - } - }, - "settings": - { - "modelChecker": - { - "engine": "all", - "printQuery": true - } - } -} diff --git a/test/cmdlineTests/standard_model_checker_print_query_no_smtlib2_solver/output.json b/test/cmdlineTests/standard_model_checker_print_query_no_smtlib2_solver/output.json deleted file mode 100644 index d675499f91db..000000000000 --- a/test/cmdlineTests/standard_model_checker_print_query_no_smtlib2_solver/output.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "errors": [ - { - "component": "general", - "formattedMessage": "Only SMTLib2 solver can be enabled to print queries", - "message": "Only SMTLib2 solver can be enabled to print queries", - "severity": "error", - "type": "JSONError" - } - ] -} diff --git a/test/cmdlineTests/standard_model_checker_print_query_superflous_solver/input.json b/test/cmdlineTests/standard_model_checker_print_query_superflous_solver/input.json deleted file mode 100644 index 9ebda00174b4..000000000000 --- a/test/cmdlineTests/standard_model_checker_print_query_superflous_solver/input.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "language": "Solidity", - "sources": - { - "A": - { - "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\n - contract C - { - function f() public pure { - uint x = 0; - assert(x == 0); - } - }" - } - }, - "settings": - { - "modelChecker": - { - "engine": "all", - "printQuery": true, - "solvers": ["smtlib2", "z3"] - } - } -} diff --git a/test/cmdlineTests/standard_model_checker_print_query_superflous_solver/output.json b/test/cmdlineTests/standard_model_checker_print_query_superflous_solver/output.json deleted file mode 100644 index d675499f91db..000000000000 --- a/test/cmdlineTests/standard_model_checker_print_query_superflous_solver/output.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "errors": [ - { - "component": "general", - "formattedMessage": "Only SMTLib2 solver can be enabled to print queries", - "message": "Only SMTLib2 solver can be enabled to print queries", - "severity": "error", - "type": "JSONError" - } - ] -} From 7b22b9c25751a216b821f6a418ef51b8aa7f9a67 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Thu, 6 Feb 2025 11:33:38 +0100 Subject: [PATCH 0801/1022] CLI: Allows to run the asm optimizer on imported asm --- Changelog.md | 1 + docs/using-the-compiler.rst | 9 +++++++-- libevmasm/EVMAssemblyStack.cpp | 1 + libevmasm/EVMAssemblyStack.h | 13 +++++++++++-- libsolidity/interface/StandardCompiler.cpp | 19 +++++++++++++++---- libsolidity/interface/StandardCompiler.h | 2 +- solc/CommandLineInterface.cpp | 9 ++++++++- solc/CommandLineParser.cpp | 11 +++++++++-- 8 files changed, 53 insertions(+), 12 deletions(-) diff --git a/Changelog.md b/Changelog.md index 5886dca26016..0145ace66622 100644 --- a/Changelog.md +++ b/Changelog.md @@ -6,6 +6,7 @@ Language Features: Compiler Features: * Error Reporting: Errors reported during code generation now point at the location of the contract when more fine-grained location is not available. * EVM: Support for the EVM version "Osaka". + * EVM Assembly Import: Allow enabling opcode-based optimizer. * SMTChecker: Support `block.blobbasefee` and `blobhash`. * SMTChecker: Z3 is now a runtime dependency, not a build dependency (except for emscripten build). * Yul Parser: Make name clash with a builtin a non-fatal error. diff --git a/docs/using-the-compiler.rst b/docs/using-the-compiler.rst index a5d5b08ccd0b..8893f6c50ba2 100644 --- a/docs/using-the-compiler.rst +++ b/docs/using-the-compiler.rst @@ -289,6 +289,9 @@ Input Description // enabled an can only be explicitly disabled via 'details'. // WARNING: Before version 0.8.6 omitting this setting was not equivalent to setting // it to false and would result in all components being disabled instead. + // WARNING: Enabling optimizations for EVMAssembly input is allowed but not necessary under normal + // circumstances. It forces the opcode-based optimizer to run again and can produce bytecode that + // is not reproducible from metadata. "enabled": true, // Optimize for how many times you intend to run the code. Optional. Default: 200. // Lower values will optimize more for initial deployment cost, higher @@ -300,12 +303,14 @@ Input Description // all values are provided explicitly. "details": { // Peephole optimizer (opcode-based). Optional. Default: true. - // NOTE: Always runs (even with optimization disabled) unless explicitly turned off here. + // Default for EVMAssembly input: false when optimization is not enabled. + // NOTE: Always runs (even with optimization disabled) except for EVMAssembly input or when explicitly turned off here. "peephole": true, // Inliner (opcode-based). Optional. Default: true when optimization is enabled. "inliner": false, // Unused JUMPDEST remover (opcode-based). Optional. Default: true. - // NOTE: Always runs (even with optimization disabled) unless explicitly turned off here. + // Default for EVMAssembly input: false when optimization is not enabled. + // NOTE: Always runs (even with optimization disabled) except for EVMAssembly input or when explicitly turned off here. "jumpdestRemover": true, // Literal reordering (codegen-based). Optional. Default: true when optimization is enabled. // Moves literals to the right of commutative binary operators during code generation, helping exploit associativity. diff --git a/libevmasm/EVMAssemblyStack.cpp b/libevmasm/EVMAssemblyStack.cpp index f8b8b4b54d0e..7cb05bf8bf00 100644 --- a/libevmasm/EVMAssemblyStack.cpp +++ b/libevmasm/EVMAssemblyStack.cpp @@ -55,6 +55,7 @@ void EVMAssemblyStack::assemble() solAssert(m_evmAssembly->isCreation()); solAssert(!m_evmRuntimeAssembly); + m_evmAssembly->optimise(m_optimiserSettings); m_object = m_evmAssembly->assemble(); // TODO: Check for EOF solAssert(m_evmAssembly->codeSections().size() == 1); diff --git a/libevmasm/EVMAssemblyStack.h b/libevmasm/EVMAssemblyStack.h index e3888afadc3e..2fe63c11c2ec 100644 --- a/libevmasm/EVMAssemblyStack.h +++ b/libevmasm/EVMAssemblyStack.h @@ -26,6 +26,7 @@ #include #include +#include namespace solidity::evmasm { @@ -33,8 +34,15 @@ namespace solidity::evmasm class EVMAssemblyStack: public AbstractAssemblyStack { public: - explicit EVMAssemblyStack(langutil::EVMVersion _evmVersion, std::optional _eofVersion): - m_evmVersion(_evmVersion), m_eofVersion(_eofVersion) {} + explicit EVMAssemblyStack( + langutil::EVMVersion _evmVersion, + std::optional _eofVersion, + Assembly::OptimiserSettings _optimiserSettings + ): + m_evmVersion(_evmVersion), + m_eofVersion(_eofVersion), + m_optimiserSettings(std::move(_optimiserSettings)) + {} /// Runs parsing and analysis steps. /// Multiple calls overwrite the previous state. @@ -82,6 +90,7 @@ class EVMAssemblyStack: public AbstractAssemblyStack private: langutil::EVMVersion m_evmVersion; std::optional m_eofVersion; + Assembly::OptimiserSettings m_optimiserSettings; std::string m_name; std::shared_ptr m_evmAssembly; std::shared_ptr m_evmRuntimeAssembly; diff --git a/libsolidity/interface/StandardCompiler.cpp b/libsolidity/interface/StandardCompiler.cpp index 520f4d5f1c8f..fb0ea4514cdc 100644 --- a/libsolidity/interface/StandardCompiler.cpp +++ b/libsolidity/interface/StandardCompiler.cpp @@ -564,12 +564,12 @@ std::optional checkOutputSelection(Json const& _outputSelection) /// Validates the optimizer settings and returns them in a parsed object. /// On error returns the json-formatted error message. -std::variant parseOptimizerSettings(Json const& _jsonInput) +std::variant parseOptimizerSettings(std::string_view const _language, Json const& _jsonInput) { if (auto result = checkOptimizerKeys(_jsonInput)) return *result; - OptimiserSettings settings = OptimiserSettings::minimal(); + OptimiserSettings settings = _language == "EVMAssembly" ? OptimiserSettings::none() : OptimiserSettings::minimal(); if (_jsonInput.contains("enabled")) { @@ -907,12 +907,16 @@ std::variant StandardCompiler::parseI if (settings.contains("optimizer")) { - auto optimiserSettings = parseOptimizerSettings(settings["optimizer"]); + auto optimiserSettings = parseOptimizerSettings(ret.language, settings["optimizer"]); if (std::holds_alternative(optimiserSettings)) return std::get(std::move(optimiserSettings)); // was an error else ret.optimiserSettings = std::get(std::move(optimiserSettings)); } + else if (ret.language == "EVMAssembly") + ret.optimiserSettings = OptimiserSettings::none(); + else + ret.optimiserSettings = OptimiserSettings::minimal(); Json const& jsonLibraries = settings.value("libraries", Json::object()); if (!jsonLibraries.is_object()) @@ -1236,7 +1240,14 @@ Json StandardCompiler::importEVMAssembly(StandardCompiler::InputsAndSettings _in if (!isBinaryRequested(_inputsAndSettings.outputSelection)) return Json::object(); - evmasm::EVMAssemblyStack stack(_inputsAndSettings.evmVersion, _inputsAndSettings.eofVersion); + evmasm::EVMAssemblyStack stack( + _inputsAndSettings.evmVersion, + _inputsAndSettings.eofVersion, + evmasm::Assembly::OptimiserSettings::translateSettings( + _inputsAndSettings.optimiserSettings, + _inputsAndSettings.evmVersion + ) + ); std::string const& sourceName = _inputsAndSettings.jsonSources.begin()->first; // result of structured binding can only be used within lambda from C++20 on. Json const& sourceJson = _inputsAndSettings.jsonSources.begin()->second; try diff --git a/libsolidity/interface/StandardCompiler.h b/libsolidity/interface/StandardCompiler.h index 590d96b9c191..665e8b487158 100644 --- a/libsolidity/interface/StandardCompiler.h +++ b/libsolidity/interface/StandardCompiler.h @@ -80,7 +80,7 @@ class StandardCompiler std::optional eofVersion; std::vector remappings; RevertStrings revertStrings = RevertStrings::Default; - OptimiserSettings optimiserSettings = OptimiserSettings::minimal(); + OptimiserSettings optimiserSettings; std::optional debugInfoSelection; std::map libraries; bool metadataLiteralSources = false; diff --git a/solc/CommandLineInterface.cpp b/solc/CommandLineInterface.cpp index 2e553c688973..92acad4bdbd9 100644 --- a/solc/CommandLineInterface.cpp +++ b/solc/CommandLineInterface.cpp @@ -889,7 +889,14 @@ void CommandLineInterface::assembleFromEVMAssemblyJSON() solAssert(m_fileReader.sourceUnits().size() == 1); auto&& [sourceUnitName, source] = *m_fileReader.sourceUnits().begin(); - auto evmAssemblyStack = std::make_unique(m_options.output.evmVersion, m_options.output.eofVersion); + auto evmAssemblyStack = std::make_unique( + m_options.output.evmVersion, + m_options.output.eofVersion, + evmasm::Assembly::OptimiserSettings::translateSettings( + m_options.optimiserSettings(), + m_options.output.evmVersion + ) + ); try { evmAssemblyStack->parseAndAnalyze(sourceUnitName, source); diff --git a/solc/CommandLineParser.cpp b/solc/CommandLineParser.cpp index b02b1ed8c702..52d158ccd5f8 100644 --- a/solc/CommandLineParser.cpp +++ b/solc/CommandLineParser.cpp @@ -264,7 +264,10 @@ OptimiserSettings CommandLineOptions::optimiserSettings() const if (optimizer.optimizeEvmasm) settings = OptimiserSettings::standard(); else - settings = OptimiserSettings::minimal(); + if (input.mode == InputMode::EVMAssemblerJSON) + settings = OptimiserSettings::none(); + else + settings = OptimiserSettings::minimal(); settings.runYulOptimiser = optimizer.optimizeYul; if (optimizer.optimizeYul) @@ -687,7 +690,10 @@ General Information)").c_str(), ) ( g_strImportEvmAssemblerJson.c_str(), - "Import EVM assembly from JSON. Assumes input is in the format used by --asm-json." + ("Import EVM assembly in JSON format produced by --asm-json. " + "WARNING: --asm-json output is already optimized according to settings stored in metadata. " + "Using --" + g_strOptimize + " in this mode is allowed, but not necessary under normal circumstances. " + "It forces the optimizer to run again and can produce bytecode that is not reproducible from metadata.").c_str() ) ( g_strLSP.c_str(), @@ -1082,6 +1088,7 @@ void CommandLineParser::processArgs() g_strCombinedJson, g_strInputFile, g_strJsonIndent, + g_strOptimize, g_strPrettyJson, "srcmap", "srcmap-runtime", From 34f131e342654ac538ded90c1216e30e98883042 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Wed, 12 Feb 2025 10:38:02 +0100 Subject: [PATCH 0802/1022] Adds tests that check imported asm with and without optimize behavior --- .../import_asm_json_no_optimize/args | 1 + .../import_asm_json_no_optimize/output | 19 +++++++++ .../import_asm_json_no_optimize/stdin | 23 +++++++++++ .../import_asm_json_optimize/args | 1 + .../import_asm_json_optimize/exit | 1 + .../import_asm_json_optimize/output | 2 + .../import_asm_json_optimize/stdin | 23 +++++++++++ .../args | 1 - .../err | 1 - .../exit | 1 - .../stdin | 6 --- .../input.json | 37 +++++++++++++++++ .../output.json | 29 ++++++++++++++ .../input.json | 40 +++++++++++++++++++ .../output.json | 12 ++++++ 15 files changed, 188 insertions(+), 9 deletions(-) create mode 100644 test/cmdlineTests/import_asm_json_no_optimize/args create mode 100644 test/cmdlineTests/import_asm_json_no_optimize/output create mode 100644 test/cmdlineTests/import_asm_json_no_optimize/stdin create mode 100644 test/cmdlineTests/import_asm_json_optimize/args create mode 100644 test/cmdlineTests/import_asm_json_optimize/exit create mode 100644 test/cmdlineTests/import_asm_json_optimize/output create mode 100644 test/cmdlineTests/import_asm_json_optimize/stdin delete mode 100644 test/cmdlineTests/import_asm_json_optimize_not_supported/args delete mode 100644 test/cmdlineTests/import_asm_json_optimize_not_supported/err delete mode 100644 test/cmdlineTests/import_asm_json_optimize_not_supported/exit delete mode 100644 test/cmdlineTests/import_asm_json_optimize_not_supported/stdin create mode 100644 test/cmdlineTests/import_asm_json_standard_json_no_optimize/input.json create mode 100644 test/cmdlineTests/import_asm_json_standard_json_no_optimize/output.json create mode 100644 test/cmdlineTests/import_asm_json_standard_json_optimize/input.json create mode 100644 test/cmdlineTests/import_asm_json_standard_json_optimize/output.json diff --git a/test/cmdlineTests/import_asm_json_no_optimize/args b/test/cmdlineTests/import_asm_json_no_optimize/args new file mode 100644 index 000000000000..0af885908f1e --- /dev/null +++ b/test/cmdlineTests/import_asm_json_no_optimize/args @@ -0,0 +1 @@ +--import-asm-json - --asm diff --git a/test/cmdlineTests/import_asm_json_no_optimize/output b/test/cmdlineTests/import_asm_json_no_optimize/output new file mode 100644 index 000000000000..03aa23879874 --- /dev/null +++ b/test/cmdlineTests/import_asm_json_no_optimize/output @@ -0,0 +1,19 @@ +EVM assembly: + 0x00 + 0x00 + 0x00 + 0x00 + 0x00 + 0x00 + 0x00 + 0x00 + 0x00 + pop(0x00) + pop + pop + pop + pop + pop + pop + pop + revert diff --git a/test/cmdlineTests/import_asm_json_no_optimize/stdin b/test/cmdlineTests/import_asm_json_no_optimize/stdin new file mode 100644 index 000000000000..c7017646aefd --- /dev/null +++ b/test/cmdlineTests/import_asm_json_no_optimize/stdin @@ -0,0 +1,23 @@ +{ + ".code": [ + { "name": "PUSH", "value": "0" }, + { "name": "PUSH", "value": "0" }, + { "name": "PUSH", "value": "0" }, + { "name": "PUSH", "value": "0" }, + { "name": "PUSH", "value": "0" }, + { "name": "PUSH", "value": "0" }, + { "name": "PUSH", "value": "0" }, + { "name": "PUSH", "value": "0" }, + { "name": "PUSH", "value": "0" }, + { "name": "PUSH", "value": "0" }, + { "name": "POP" }, + { "name": "POP" }, + { "name": "POP" }, + { "name": "POP" }, + { "name": "POP" }, + { "name": "POP" }, + { "name": "POP" }, + { "name": "POP" }, + { "name": "REVERT" } + ] +} diff --git a/test/cmdlineTests/import_asm_json_optimize/args b/test/cmdlineTests/import_asm_json_optimize/args new file mode 100644 index 000000000000..b9370e6e4f11 --- /dev/null +++ b/test/cmdlineTests/import_asm_json_optimize/args @@ -0,0 +1 @@ +--optimize --import-asm-json - --asm diff --git a/test/cmdlineTests/import_asm_json_optimize/exit b/test/cmdlineTests/import_asm_json_optimize/exit new file mode 100644 index 000000000000..573541ac9702 --- /dev/null +++ b/test/cmdlineTests/import_asm_json_optimize/exit @@ -0,0 +1 @@ +0 diff --git a/test/cmdlineTests/import_asm_json_optimize/output b/test/cmdlineTests/import_asm_json_optimize/output new file mode 100644 index 000000000000..25337fe77938 --- /dev/null +++ b/test/cmdlineTests/import_asm_json_optimize/output @@ -0,0 +1,2 @@ +EVM assembly: + revert(0x00, 0x00) diff --git a/test/cmdlineTests/import_asm_json_optimize/stdin b/test/cmdlineTests/import_asm_json_optimize/stdin new file mode 100644 index 000000000000..c7017646aefd --- /dev/null +++ b/test/cmdlineTests/import_asm_json_optimize/stdin @@ -0,0 +1,23 @@ +{ + ".code": [ + { "name": "PUSH", "value": "0" }, + { "name": "PUSH", "value": "0" }, + { "name": "PUSH", "value": "0" }, + { "name": "PUSH", "value": "0" }, + { "name": "PUSH", "value": "0" }, + { "name": "PUSH", "value": "0" }, + { "name": "PUSH", "value": "0" }, + { "name": "PUSH", "value": "0" }, + { "name": "PUSH", "value": "0" }, + { "name": "PUSH", "value": "0" }, + { "name": "POP" }, + { "name": "POP" }, + { "name": "POP" }, + { "name": "POP" }, + { "name": "POP" }, + { "name": "POP" }, + { "name": "POP" }, + { "name": "POP" }, + { "name": "REVERT" } + ] +} diff --git a/test/cmdlineTests/import_asm_json_optimize_not_supported/args b/test/cmdlineTests/import_asm_json_optimize_not_supported/args deleted file mode 100644 index f649e9740882..000000000000 --- a/test/cmdlineTests/import_asm_json_optimize_not_supported/args +++ /dev/null @@ -1 +0,0 @@ ---optimize --import-asm-json - --opcodes --asm diff --git a/test/cmdlineTests/import_asm_json_optimize_not_supported/err b/test/cmdlineTests/import_asm_json_optimize_not_supported/err deleted file mode 100644 index 8f42dca78694..000000000000 --- a/test/cmdlineTests/import_asm_json_optimize_not_supported/err +++ /dev/null @@ -1 +0,0 @@ -Error: Option --optimize is not supported with --import-asm-json. diff --git a/test/cmdlineTests/import_asm_json_optimize_not_supported/exit b/test/cmdlineTests/import_asm_json_optimize_not_supported/exit deleted file mode 100644 index d00491fd7e5b..000000000000 --- a/test/cmdlineTests/import_asm_json_optimize_not_supported/exit +++ /dev/null @@ -1 +0,0 @@ -1 diff --git a/test/cmdlineTests/import_asm_json_optimize_not_supported/stdin b/test/cmdlineTests/import_asm_json_optimize_not_supported/stdin deleted file mode 100644 index f6cc546647c3..000000000000 --- a/test/cmdlineTests/import_asm_json_optimize_not_supported/stdin +++ /dev/null @@ -1,6 +0,0 @@ -{ - ".code": [ - {"name": "DIFFICULTY"}, - {"name": "PREVRANDAO"} - ] -} diff --git a/test/cmdlineTests/import_asm_json_standard_json_no_optimize/input.json b/test/cmdlineTests/import_asm_json_standard_json_no_optimize/input.json new file mode 100644 index 000000000000..d2ba25938f7d --- /dev/null +++ b/test/cmdlineTests/import_asm_json_standard_json_no_optimize/input.json @@ -0,0 +1,37 @@ +{ + "language": "EVMAssembly", + "sources": { + "A": { + "assemblyJson": { + ".code": [ + { "name": "PUSH", "value": "0" }, + { "name": "PUSH", "value": "0" }, + { "name": "PUSH", "value": "0" }, + { "name": "PUSH", "value": "0" }, + { "name": "PUSH", "value": "0" }, + { "name": "PUSH", "value": "0" }, + { "name": "PUSH", "value": "0" }, + { "name": "PUSH", "value": "0" }, + { "name": "PUSH", "value": "0" }, + { "name": "PUSH", "value": "0" }, + { "name": "POP" }, + { "name": "POP" }, + { "name": "POP" }, + { "name": "POP" }, + { "name": "POP" }, + { "name": "POP" }, + { "name": "POP" }, + { "name": "POP" }, + { "name": "REVERT" } + ] + } + } + }, + "settings": { + "outputSelection": { + "*": { + "": ["evm.assembly"] + } + } + } +} diff --git a/test/cmdlineTests/import_asm_json_standard_json_no_optimize/output.json b/test/cmdlineTests/import_asm_json_standard_json_no_optimize/output.json new file mode 100644 index 000000000000..5dc5942bf7c0 --- /dev/null +++ b/test/cmdlineTests/import_asm_json_standard_json_no_optimize/output.json @@ -0,0 +1,29 @@ +{ + "contracts": { + "A": { + "": { + "evm": { + "assembly": " 0x00 + 0x00 + 0x00 + 0x00 + 0x00 + 0x00 + 0x00 + 0x00 + 0x00 + pop(0x00) + pop + pop + pop + pop + pop + pop + pop + revert +" + } + } + } + } +} diff --git a/test/cmdlineTests/import_asm_json_standard_json_optimize/input.json b/test/cmdlineTests/import_asm_json_standard_json_optimize/input.json new file mode 100644 index 000000000000..d1d45825952d --- /dev/null +++ b/test/cmdlineTests/import_asm_json_standard_json_optimize/input.json @@ -0,0 +1,40 @@ +{ + "language": "EVMAssembly", + "sources": { + "A": { + "assemblyJson": { + ".code": [ + { "name": "PUSH", "value": "0" }, + { "name": "PUSH", "value": "0" }, + { "name": "PUSH", "value": "0" }, + { "name": "PUSH", "value": "0" }, + { "name": "PUSH", "value": "0" }, + { "name": "PUSH", "value": "0" }, + { "name": "PUSH", "value": "0" }, + { "name": "PUSH", "value": "0" }, + { "name": "PUSH", "value": "0" }, + { "name": "PUSH", "value": "0" }, + { "name": "POP" }, + { "name": "POP" }, + { "name": "POP" }, + { "name": "POP" }, + { "name": "POP" }, + { "name": "POP" }, + { "name": "POP" }, + { "name": "POP" }, + { "name": "REVERT" } + ] + } + } + }, + "settings": { + "outputSelection": { + "*": { + "": ["evm.assembly"] + } + }, + "optimizer": { + "enabled": true + } + } +} diff --git a/test/cmdlineTests/import_asm_json_standard_json_optimize/output.json b/test/cmdlineTests/import_asm_json_standard_json_optimize/output.json new file mode 100644 index 000000000000..606862e0af8a --- /dev/null +++ b/test/cmdlineTests/import_asm_json_standard_json_optimize/output.json @@ -0,0 +1,12 @@ +{ + "contracts": { + "A": { + "": { + "evm": { + "assembly": " revert(0x00, 0x00) +" + } + } + } + } +} From 41f374b76dd289ba52c01327ec57caa7fdfd3298 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Thu, 13 Feb 2025 09:40:34 +0100 Subject: [PATCH 0803/1022] Remove evm version from Assembly::OptimiserSettings --- libevmasm/Assembly.cpp | 11 +++++------ libevmasm/Assembly.h | 3 +-- libsolidity/codegen/CompilerContext.h | 2 +- libsolidity/interface/StandardCompiler.cpp | 3 +-- libyul/YulStack.cpp | 2 +- solc/CommandLineInterface.cpp | 3 +-- test/libevmasm/Optimiser.cpp | 6 +++--- 7 files changed, 13 insertions(+), 17 deletions(-) diff --git a/libevmasm/Assembly.cpp b/libevmasm/Assembly.cpp index 91beb9a7f3f2..21cabcbc53b1 100644 --- a/libevmasm/Assembly.cpp +++ b/libevmasm/Assembly.cpp @@ -819,8 +819,8 @@ std::map const& Assembly::optimiseInternal( _tagsReferencedFromOutside, _settings.expectedExecutionsPerDeployment, isCreation(), - _settings.evmVersion} - .optimise(); + m_evmVersion + }.optimise(); } // TODO: verify this for EOF. if (_settings.runJumpdestRemover && !m_eofVersion.has_value()) @@ -935,7 +935,7 @@ std::map const& Assembly::optimiseInternal( ConstantOptimisationMethod::optimiseConstants( isCreation(), isCreation() ? 1 : _settings.expectedExecutionsPerDeployment, - _settings.evmVersion, + m_evmVersion, *this ); @@ -1769,10 +1769,10 @@ Assembly const* Assembly::subAssemblyById(size_t _subId) const return currentAssembly; } -Assembly::OptimiserSettings Assembly::OptimiserSettings::translateSettings(frontend::OptimiserSettings const& _settings, langutil::EVMVersion const& _evmVersion) +Assembly::OptimiserSettings Assembly::OptimiserSettings::translateSettings(frontend::OptimiserSettings const& _settings) { // Constructing it this way so that we notice changes in the fields. - evmasm::Assembly::OptimiserSettings asmSettings{false, false, false, false, false, false, _evmVersion, 0}; + OptimiserSettings asmSettings{false, false, false, false, false, false, 0}; asmSettings.runInliner = _settings.runInliner; asmSettings.runJumpdestRemover = _settings.runJumpdestRemover; asmSettings.runPeephole = _settings.runPeephole; @@ -1780,6 +1780,5 @@ Assembly::OptimiserSettings Assembly::OptimiserSettings::translateSettings(front asmSettings.runCSE = _settings.runCSE; asmSettings.runConstantOptimiser = _settings.runConstantOptimiser; asmSettings.expectedExecutionsPerDeployment = _settings.expectedExecutionsPerDeployment; - asmSettings.evmVersion = _evmVersion; return asmSettings; } diff --git a/libevmasm/Assembly.h b/libevmasm/Assembly.h index 92dfb0a44008..6f30fa635176 100644 --- a/libevmasm/Assembly.h +++ b/libevmasm/Assembly.h @@ -166,12 +166,11 @@ class Assembly bool runDeduplicate = false; bool runCSE = false; bool runConstantOptimiser = false; - langutil::EVMVersion evmVersion; /// This specifies an estimate on how often each opcode in this assembly will be executed, /// i.e. use a small value to optimise for size and a large value to optimise for runtime gas usage. size_t expectedExecutionsPerDeployment = frontend::OptimiserSettings{}.expectedExecutionsPerDeployment; - static OptimiserSettings translateSettings(frontend::OptimiserSettings const& _settings, langutil::EVMVersion const& _evmVersion); + static OptimiserSettings translateSettings(frontend::OptimiserSettings const& _settings); }; /// Modify and return the current assembly such that creation and execution gas usage diff --git a/libsolidity/codegen/CompilerContext.h b/libsolidity/codegen/CompilerContext.h index 17559fbf4182..5f50bbefdc92 100644 --- a/libsolidity/codegen/CompilerContext.h +++ b/libsolidity/codegen/CompilerContext.h @@ -284,7 +284,7 @@ class CompilerContext void appendToAuxiliaryData(bytes const& _data) { m_asm->appendToAuxiliaryData(_data); } /// Run optimisation step. - void optimise(OptimiserSettings const& _settings) { m_asm->optimise(evmasm::Assembly::OptimiserSettings::translateSettings(_settings, m_evmVersion)); } + void optimise(OptimiserSettings const& _settings) { m_asm->optimise(evmasm::Assembly::OptimiserSettings::translateSettings(_settings)); } /// @returns the runtime context if in creation mode and runtime context is set, nullptr otherwise. CompilerContext* runtimeContext() const { return m_runtimeContext; } diff --git a/libsolidity/interface/StandardCompiler.cpp b/libsolidity/interface/StandardCompiler.cpp index fb0ea4514cdc..1671267d70e2 100644 --- a/libsolidity/interface/StandardCompiler.cpp +++ b/libsolidity/interface/StandardCompiler.cpp @@ -1244,8 +1244,7 @@ Json StandardCompiler::importEVMAssembly(StandardCompiler::InputsAndSettings _in _inputsAndSettings.evmVersion, _inputsAndSettings.eofVersion, evmasm::Assembly::OptimiserSettings::translateSettings( - _inputsAndSettings.optimiserSettings, - _inputsAndSettings.evmVersion + _inputsAndSettings.optimiserSettings ) ); std::string const& sourceName = _inputsAndSettings.jsonSources.begin()->first; // result of structured binding can only be used within lambda from C++20 on. diff --git a/libyul/YulStack.cpp b/libyul/YulStack.cpp index f58705e9cb9d..1ad24998ffb5 100644 --- a/libyul/YulStack.cpp +++ b/libyul/YulStack.cpp @@ -324,7 +324,7 @@ YulStack::assembleEVMWithDeployed(std::optional _deployName) { compileEVM(adapter, optimize); - assembly.optimise(evmasm::Assembly::OptimiserSettings::translateSettings(m_optimiserSettings, m_evmVersion)); + assembly.optimise(evmasm::Assembly::OptimiserSettings::translateSettings(m_optimiserSettings)); std::optional subIndex; diff --git a/solc/CommandLineInterface.cpp b/solc/CommandLineInterface.cpp index 92acad4bdbd9..4fd730096e85 100644 --- a/solc/CommandLineInterface.cpp +++ b/solc/CommandLineInterface.cpp @@ -893,8 +893,7 @@ void CommandLineInterface::assembleFromEVMAssemblyJSON() m_options.output.evmVersion, m_options.output.eofVersion, evmasm::Assembly::OptimiserSettings::translateSettings( - m_options.optimiserSettings(), - m_options.output.evmVersion + m_options.optimiserSettings() ) ); try diff --git a/test/libevmasm/Optimiser.cpp b/test/libevmasm/Optimiser.cpp index a8e9afeaf2de..f4b7034de544 100644 --- a/test/libevmasm/Optimiser.cpp +++ b/test/libevmasm/Optimiser.cpp @@ -1345,11 +1345,11 @@ BOOST_AUTO_TEST_CASE(jumpdest_removal_subassemblies, *boost::unit_test::precondi settings.runDeduplicate = true; settings.runCSE = true; settings.runConstantOptimiser = true; - settings.evmVersion = solidity::test::CommonOptions::get().evmVersion(); settings.expectedExecutionsPerDeployment = OptimiserSettings{}.expectedExecutionsPerDeployment; - Assembly main{settings.evmVersion, false, std::nullopt, {}}; - AssemblyPointer sub = std::make_shared(settings.evmVersion, true, std::nullopt, std::string{}); + auto const evmVersion = CommonOptions::get().evmVersion(); + Assembly main{evmVersion, false, std::nullopt, {}}; + AssemblyPointer sub = std::make_shared(evmVersion, true, std::nullopt, std::string{}); sub->append(u256(1)); auto t1 = sub->newTag(); From 20569e4c61f80600801255836c6c163c37b8663e Mon Sep 17 00:00:00 2001 From: rodiazet Date: Fri, 14 Feb 2025 09:15:34 +0100 Subject: [PATCH 0804/1022] eof: Add EOF initial support changelog entry. --- Changelog.md | 1 + docs/using-the-compiler.rst | 1 + 2 files changed, 2 insertions(+) diff --git a/Changelog.md b/Changelog.md index 0145ace66622..75bd75eae178 100644 --- a/Changelog.md +++ b/Changelog.md @@ -7,6 +7,7 @@ Compiler Features: * Error Reporting: Errors reported during code generation now point at the location of the contract when more fine-grained location is not available. * EVM: Support for the EVM version "Osaka". * EVM Assembly Import: Allow enabling opcode-based optimizer. + * General: The experimental EOF backend implements a subset of EOF sufficient to compile arbitrary high-level Solidity syntax via IR with optimization enabled. * SMTChecker: Support `block.blobbasefee` and `blobhash`. * SMTChecker: Z3 is now a runtime dependency, not a build dependency (except for emscripten build). * Yul Parser: Make name clash with a builtin a non-fatal error. diff --git a/docs/using-the-compiler.rst b/docs/using-the-compiler.rst index 8893f6c50ba2..97db1d7ceb0a 100644 --- a/docs/using-the-compiler.rst +++ b/docs/using-the-compiler.rst @@ -183,6 +183,7 @@ at each version. Backward compatibility is not guaranteed between each version. - Opcodes ``tstore`` and ``tload`` are available in assembly (see `EIP-1153 `_). - ``prague`` (**experimental**) - ``osaka`` (**experimental**) + - Experimental compilation to EOF is available starting from this version. (`EIP-7692 `_) .. index:: ! standard JSON, ! --standard-json .. _compiler-api: From 2f11f6539b791f09387d024fe68d3f4aee181b58 Mon Sep 17 00:00:00 2001 From: Maxim Evtush <154841002+maximevtush@users.noreply.github.com> Date: Fri, 14 Feb 2025 14:09:45 +0100 Subject: [PATCH 0805/1022] fix: typos in a few syntax test file names (#15858) * fix typo public_var_parallel_funciton.sol to public_var_parallel_function.sol * gix typo: invalid_variable_mutablity.sol -> invalid_variable_mutability.sol * fix typo: recursive_function_paramter_err.sol -> recursive_function_parameter_err.sol --- ...var_parallel_funciton.sol => public_var_parallel_function.sol} | 0 ...lid_variable_mutablity.sol => invalid_variable_mutability.sol} | 0 ...tion_paramter_err.sol => recursive_function_parameter_err.sol} | 0 3 files changed, 0 insertions(+), 0 deletions(-) rename test/libsolidity/syntaxTests/inheritance/override/{public_var_parallel_funciton.sol => public_var_parallel_function.sol} (100%) rename test/libsolidity/syntaxTests/parsing/{invalid_variable_mutablity.sol => invalid_variable_mutability.sol} (100%) rename test/libsolidity/syntaxTests/userDefinedValueType/{recursive_function_paramter_err.sol => recursive_function_parameter_err.sol} (100%) diff --git a/test/libsolidity/syntaxTests/inheritance/override/public_var_parallel_funciton.sol b/test/libsolidity/syntaxTests/inheritance/override/public_var_parallel_function.sol similarity index 100% rename from test/libsolidity/syntaxTests/inheritance/override/public_var_parallel_funciton.sol rename to test/libsolidity/syntaxTests/inheritance/override/public_var_parallel_function.sol diff --git a/test/libsolidity/syntaxTests/parsing/invalid_variable_mutablity.sol b/test/libsolidity/syntaxTests/parsing/invalid_variable_mutability.sol similarity index 100% rename from test/libsolidity/syntaxTests/parsing/invalid_variable_mutablity.sol rename to test/libsolidity/syntaxTests/parsing/invalid_variable_mutability.sol diff --git a/test/libsolidity/syntaxTests/userDefinedValueType/recursive_function_paramter_err.sol b/test/libsolidity/syntaxTests/userDefinedValueType/recursive_function_parameter_err.sol similarity index 100% rename from test/libsolidity/syntaxTests/userDefinedValueType/recursive_function_paramter_err.sol rename to test/libsolidity/syntaxTests/userDefinedValueType/recursive_function_parameter_err.sol From 868154c56e82d1a8bdd1fc40331e32da7e8d4992 Mon Sep 17 00:00:00 2001 From: kilavvy <140459108+kilavvy@users.noreply.github.com> Date: Fri, 14 Feb 2025 23:42:33 +0100 Subject: [PATCH 0806/1022] fix: typos in a few syntax and natspec test file names (#15864) * typo fix * fix typo * typo fix --- ..._param_description.sol => dev_multiline_param_description.sol} | 0 ...stract_contructor_param.sol => abstract_constructor_param.sol} | 0 ...mory.sol => mapping_struct_recursive_data_location_memory.sol} | 0 3 files changed, 0 insertions(+), 0 deletions(-) rename test/libsolidity/natspecJSON/{dev_mutiline_param_description.sol => dev_multiline_param_description.sol} (100%) rename test/libsolidity/syntaxTests/types/mapping/{abstract_contructor_param.sol => abstract_constructor_param.sol} (100%) rename test/libsolidity/syntaxTests/types/mapping/{mapping_struct_recusrive_data_location_memory.sol => mapping_struct_recursive_data_location_memory.sol} (100%) diff --git a/test/libsolidity/natspecJSON/dev_mutiline_param_description.sol b/test/libsolidity/natspecJSON/dev_multiline_param_description.sol similarity index 100% rename from test/libsolidity/natspecJSON/dev_mutiline_param_description.sol rename to test/libsolidity/natspecJSON/dev_multiline_param_description.sol diff --git a/test/libsolidity/syntaxTests/types/mapping/abstract_contructor_param.sol b/test/libsolidity/syntaxTests/types/mapping/abstract_constructor_param.sol similarity index 100% rename from test/libsolidity/syntaxTests/types/mapping/abstract_contructor_param.sol rename to test/libsolidity/syntaxTests/types/mapping/abstract_constructor_param.sol diff --git a/test/libsolidity/syntaxTests/types/mapping/mapping_struct_recusrive_data_location_memory.sol b/test/libsolidity/syntaxTests/types/mapping/mapping_struct_recursive_data_location_memory.sol similarity index 100% rename from test/libsolidity/syntaxTests/types/mapping/mapping_struct_recusrive_data_location_memory.sol rename to test/libsolidity/syntaxTests/types/mapping/mapping_struct_recursive_data_location_memory.sol From 80eb5279eaf771ca3828255163706610660311dc Mon Sep 17 00:00:00 2001 From: Fallengirl <155266340+Fallengirl@users.noreply.github.com> Date: Sat, 15 Feb 2025 14:04:36 +0100 Subject: [PATCH 0807/1022] Fix spelling errors in a few code comments in libsolidity and SMTChecker (#15866) * Update CompilerContext.h * Update BMC.cpp * Update SMTEncoder.h --- libsolidity/codegen/CompilerContext.h | 2 +- libsolidity/formal/BMC.cpp | 2 +- libsolidity/formal/SMTEncoder.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/libsolidity/codegen/CompilerContext.h b/libsolidity/codegen/CompilerContext.h index 5f50bbefdc92..e8c4e9bc77f7 100644 --- a/libsolidity/codegen/CompilerContext.h +++ b/libsolidity/codegen/CompilerContext.h @@ -367,7 +367,7 @@ class CompilerContext /// modifier is applied twice, the position of the variable needs to be restored /// after the nested modifier is left. std::map> m_localVariables; - /// The contract currently being compiled. Virtual function lookup starts from this contarct. + /// The contract currently being compiled. Virtual function lookup starts from this contract. ContractDefinition const* m_mostDerivedContract = nullptr; /// Whether to use checked arithmetic. Arithmetic m_arithmetic = Arithmetic::Checked; diff --git a/libsolidity/formal/BMC.cpp b/libsolidity/formal/BMC.cpp index 5fb2f5a9fd75..1b6be157942d 100644 --- a/libsolidity/formal/BMC.cpp +++ b/libsolidity/formal/BMC.cpp @@ -459,7 +459,7 @@ bool BMC::visit(ForStatement const& _node) _node.condition()->accept(*this); forCondition = expr(*_node.condition()); } - // asseert that the loop is complete + // assert that the loop is complete m_context.addAssertion(!forCondition || broke || !forConditionOnPreviousIterations); mergeVariables( broke || !forConditionOnPreviousIterations, diff --git a/libsolidity/formal/SMTEncoder.h b/libsolidity/formal/SMTEncoder.h index c6c549151058..f926a0d0fc80 100644 --- a/libsolidity/formal/SMTEncoder.h +++ b/libsolidity/formal/SMTEncoder.h @@ -508,7 +508,7 @@ class SMTEncoder: public ASTConstVisitor ContractDefinition const* m_currentContract = nullptr; /// Stores the free functions and internal library functions. - /// Those need to be encoded repeatedely for every analyzed contract. + /// Those need to be encoded repeatedly for every analyzed contract. std::set m_freeFunctions; /// Stores the context of the encoding. From e94a1f1415b3041b7555437685609e64727ab7d2 Mon Sep 17 00:00:00 2001 From: xiaobei0715 <1505929057@qq.com> Date: Sat, 15 Feb 2025 14:39:10 +0800 Subject: [PATCH 0808/1022] Updating copyright year to 2025 --- docs/conf.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/conf.py b/docs/conf.py index f57a3b5b904c..dc52c96bdfcf 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -114,7 +114,7 @@ def get_github_username_repo(url): # General information about the project. project = 'Solidity' -project_copyright = '2016-2024, The Solidity Authors' +project_copyright = '2016-2025, The Solidity Authors' # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the From 7f3a8e267e9d39c0b8d428736ae5401f1f80081d Mon Sep 17 00:00:00 2001 From: PixelPilot <161360836+PixelPil0t1@users.noreply.github.com> Date: Sun, 16 Feb 2025 15:49:03 +0100 Subject: [PATCH 0809/1022] Grammar and typo fixes in code comments (#15869) * Update emscripten.jam * Update SSATransform.h --- libyul/optimiser/SSATransform.h | 2 +- scripts/docker/buildpack-deps/emscripten.jam | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libyul/optimiser/SSATransform.h b/libyul/optimiser/SSATransform.h index 64181bf208d3..4b46d7169f80 100644 --- a/libyul/optimiser/SSATransform.h +++ b/libyul/optimiser/SSATransform.h @@ -67,7 +67,7 @@ class NameDispenser; * The current value mapping is cleared for a variable a at the end of each block * in which it was assigned. We compensate that by appending a declaration * of the form of "let a_1 := a" right after the location where control flow joins so - * variable references can use the SSA variable. The only exception to this rule are + * variable references can use the SSA variable. The only exception to this rule is * for loop conditions, as we cannot insert a variable declaration there. * * After this stage, UnusedAssignmentEliminator is recommended to remove the unnecessary diff --git a/scripts/docker/buildpack-deps/emscripten.jam b/scripts/docker/buildpack-deps/emscripten.jam index bc8f0fa00eb4..21768524f5d0 100644 --- a/scripts/docker/buildpack-deps/emscripten.jam +++ b/scripts/docker/buildpack-deps/emscripten.jam @@ -25,7 +25,7 @@ # ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER # DEALINGS IN THE SOFTWARE. # -# Boost.Build support for Emscipten. +# Boost.Build support for Emscripten. # # @todo add support for dynamic linking # @todo add support for --js-library, --pre-js, and --post-js options From 76686ecbc67ecfc4577fd33f4ba7fe53fc8c9f57 Mon Sep 17 00:00:00 2001 From: FT <140458077+zeevick10@users.noreply.github.com> Date: Sun, 16 Feb 2025 16:20:14 +0100 Subject: [PATCH 0810/1022] fix: typos in a few test file names (#15867) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix typo: funtion_call.yul to function_call.yul * fix typo: constructer_internal_function_abstract.sol to constructor_internal_function_abstract.sol * fix typo: non_implemented_modifer.sol to non_implemented_modifier.sol --------- Co-authored-by: zeevick10 --- ...on_abstract.sol => constructor_internal_function_abstract.sol} | 0 .../{non_implemented_modifer.sol => non_implemented_modifier.sol} | 0 .../disambiguator/{funtion_call.yul => function_call.yul} | 0 3 files changed, 0 insertions(+), 0 deletions(-) rename test/libsolidity/syntaxTests/constructor/{constructer_internal_function_abstract.sol => constructor_internal_function_abstract.sol} (100%) rename test/libsolidity/syntaxTests/controlFlow/modifiers/{non_implemented_modifer.sol => non_implemented_modifier.sol} (100%) rename test/libyul/yulOptimizerTests/disambiguator/{funtion_call.yul => function_call.yul} (100%) diff --git a/test/libsolidity/syntaxTests/constructor/constructer_internal_function_abstract.sol b/test/libsolidity/syntaxTests/constructor/constructor_internal_function_abstract.sol similarity index 100% rename from test/libsolidity/syntaxTests/constructor/constructer_internal_function_abstract.sol rename to test/libsolidity/syntaxTests/constructor/constructor_internal_function_abstract.sol diff --git a/test/libsolidity/syntaxTests/controlFlow/modifiers/non_implemented_modifer.sol b/test/libsolidity/syntaxTests/controlFlow/modifiers/non_implemented_modifier.sol similarity index 100% rename from test/libsolidity/syntaxTests/controlFlow/modifiers/non_implemented_modifer.sol rename to test/libsolidity/syntaxTests/controlFlow/modifiers/non_implemented_modifier.sol diff --git a/test/libyul/yulOptimizerTests/disambiguator/funtion_call.yul b/test/libyul/yulOptimizerTests/disambiguator/function_call.yul similarity index 100% rename from test/libyul/yulOptimizerTests/disambiguator/funtion_call.yul rename to test/libyul/yulOptimizerTests/disambiguator/function_call.yul From 68c4aa3c943ce1e238e8fc36296928edd6394f1f Mon Sep 17 00:00:00 2001 From: Daniel Kirchner Date: Mon, 10 Feb 2025 19:36:10 +0100 Subject: [PATCH 0811/1022] Add SWAPN/DUPN. --- libevmasm/Assembly.cpp | 22 +++++++++++++-- libevmasm/Assembly.h | 6 +++- libevmasm/AssemblyItem.cpp | 27 +++++++++++++++++- libevmasm/AssemblyItem.h | 18 ++++++++++-- libevmasm/Instruction.cpp | 4 +++ libevmasm/Instruction.h | 26 ++--------------- libevmasm/KnownState.cpp | 4 +-- libevmasm/PeepholeOptimiser.cpp | 2 +- libevmasm/SemanticInformation.cpp | 28 +++++++++++++++++-- libevmasm/SemanticInformation.h | 4 +++ liblangutil/EVMVersion.cpp | 2 ++ libyul/AsmAnalysis.cpp | 4 ++- libyul/backends/evm/AbstractAssembly.h | 7 +++++ libyul/backends/evm/EVMDialect.cpp | 6 ++-- libyul/backends/evm/EthAssemblyAdapter.cpp | 11 ++++++++ libyul/backends/evm/EthAssemblyAdapter.h | 3 ++ libyul/backends/evm/NoOutputAssembly.cpp | 5 ++++ libyul/backends/evm/NoOutputAssembly.h | 2 ++ .../eof_identifiers_not_defined_in_legacy.yul | 4 +++ ...eof_identifiers_not_reserved_in_legacy.yul | 2 ++ ...of_opcodes_identifiers_reserved_in_eof.yul | 4 +++ .../EVMInstructionInterpreter.cpp | 2 ++ 22 files changed, 155 insertions(+), 38 deletions(-) diff --git a/libevmasm/Assembly.cpp b/libevmasm/Assembly.cpp index 21cabcbc53b1..4dcc6a4b092b 100644 --- a/libevmasm/Assembly.cpp +++ b/libevmasm/Assembly.cpp @@ -767,11 +767,21 @@ AssemblyItem Assembly::newImmutableAssignment(std::string const& _identifier) return AssemblyItem{AssignImmutable, h}; } -AssemblyItem Assembly::newAuxDataLoadN(size_t _offset) +AssemblyItem Assembly::newAuxDataLoadN(size_t _offset) const { return AssemblyItem{AuxDataLoadN, _offset}; } +AssemblyItem Assembly::newSwapN(size_t _depth) const +{ + return AssemblyItem::swapN(_depth); +} + +AssemblyItem Assembly::newDupN(size_t _depth) const +{ + return AssemblyItem::dupN(_depth); +} + Assembly& Assembly::optimise(OptimiserSettings const& _settings) { optimiseInternal(_settings, {}); @@ -1558,7 +1568,9 @@ LinkerObject const& Assembly::assembleEOF() const item.instruction() != Instruction::RJUMPI && item.instruction() != Instruction::CALLF && item.instruction() != Instruction::JUMPF && - item.instruction() != Instruction::RETF + item.instruction() != Instruction::RETF && + item.instruction() != Instruction::DUPN && + item.instruction() != Instruction::SWAPN ); solAssert(!(item.instruction() >= Instruction::PUSH0 && item.instruction() <= Instruction::PUSH32)); ret.bytecode += assembleOperation(item); @@ -1636,6 +1648,12 @@ LinkerObject const& Assembly::assembleEOF() const case RetF: ret.bytecode.push_back(static_cast(Instruction::RETF)); break; + case SwapN: + case DupN: + ret.bytecode.push_back(static_cast(item.instruction())); + solAssert(item.data() >= 1 && item.data() <= 256); + ret.bytecode.push_back(static_cast(item.data() - 1)); + break; default: solAssert(false, "Unexpected opcode while assembling."); } diff --git a/libevmasm/Assembly.h b/libevmasm/Assembly.h index 6f30fa635176..30b06dd367fb 100644 --- a/libevmasm/Assembly.h +++ b/libevmasm/Assembly.h @@ -88,7 +88,9 @@ class Assembly AssemblyItem newPushLibraryAddress(std::string const& _identifier); AssemblyItem newPushImmutable(std::string const& _identifier); AssemblyItem newImmutableAssignment(std::string const& _identifier); - AssemblyItem newAuxDataLoadN(size_t offset); + AssemblyItem newAuxDataLoadN(size_t offset) const; + AssemblyItem newSwapN(size_t _depth) const; + AssemblyItem newDupN(size_t _depth) const; AssemblyItem const& append(AssemblyItem _i); AssemblyItem const& append(bytes const& _data) { return append(newData(_data)); } @@ -102,6 +104,8 @@ class Assembly void appendImmutable(std::string const& _identifier) { append(newPushImmutable(_identifier)); } void appendImmutableAssignment(std::string const& _identifier) { append(newImmutableAssignment(_identifier)); } void appendAuxDataLoadN(uint16_t _offset) { append(newAuxDataLoadN(_offset));} + void appendSwapN(size_t _depth) { append(newSwapN(_depth)); } + void appendDupN(size_t _depth) { append(newDupN(_depth)); } void appendVerbatim(bytes _data, size_t _arguments, size_t _returnVariables) { diff --git a/libevmasm/AssemblyItem.cpp b/libevmasm/AssemblyItem.cpp index 3bc7ef7049a6..8a917986f915 100644 --- a/libevmasm/AssemblyItem.cpp +++ b/libevmasm/AssemblyItem.cpp @@ -19,6 +19,7 @@ #include #include +#include #include #include @@ -90,6 +91,9 @@ std::pair AssemblyItem::nameAndData(langutil::EVMVersi case JumpF: case RetF: return {instructionInfo(instruction(), _evmVersion).name, ""}; + case SwapN: + case DupN: + return {instructionInfo(instruction(), _evmVersion).name, util::toString(static_cast(data())) }; case Push: return {"PUSH", toStringInHex(data())}; case PushTag: @@ -192,6 +196,10 @@ size_t AssemblyItem::bytesRequired(size_t _addressLength, langutil::EVMVersion _ return 2; case ReturnContract: return 2; + case SwapN: + return 2; + case DupN: + return 2; case UndefinedItem: solAssert(false); } @@ -203,6 +211,10 @@ size_t AssemblyItem::arguments() const { if (type() == CallF || type() == JumpF) return functionSignature().argsNum; + else if (type() == SwapN) + return static_cast(data()) + 1; + else if (type() == DupN) + return static_cast(data()); else if (hasInstruction()) { solAssert(instruction() != Instruction::CALLF && instruction() != Instruction::JUMPF); @@ -231,6 +243,9 @@ size_t AssemblyItem::returnValues() const // The latest EVMVersion is used here, since the InstructionInfo is assumed to be // the same across all EVM versions except for the instruction name. return static_cast(instructionInfo(instruction(), EVMVersion()).ret); + case SwapN: + case DupN: + return static_cast(data()) + 1; case Push: case PushTag: case PushData: @@ -270,8 +285,10 @@ bool AssemblyItem::canBeFunctional() const case ConditionalRelativeJump: case CallF: case JumpF: + case SwapN: + case DupN: case RetF: - return !isDupInstruction(instruction()) && !isSwapInstruction(instruction()); + return !SemanticInformation::isDupInstruction(*this) && !SemanticInformation::isSwapInstruction(*this); case Push: case PushTag: case PushData: @@ -410,6 +427,12 @@ std::string AssemblyItem::toAssemblyText(Assembly const& _assembly) const case RetF: text = "retf"; break; + case SwapN: + text = "swapn{" + std::to_string(static_cast(data())) + "}"; + break; + case DupN: + text = "dupn{" + std::to_string(static_cast(data())) + "}"; + break; } if (m_jumpType == JumpType::IntoFunction || m_jumpType == JumpType::OutOfFunction) { @@ -435,6 +458,8 @@ std::ostream& solidity::evmasm::operator<<(std::ostream& _out, AssemblyItem cons case CallF: case JumpF: case RetF: + case SwapN: + case DupN: _out << " " << instructionInfo(_item.instruction(), EVMVersion()).name; if (_item.instruction() == Instruction::JUMP || _item.instruction() == Instruction::JUMPI) _out << "\t" << _item.getJumpTypeAsString(); diff --git a/libevmasm/AssemblyItem.h b/libevmasm/AssemblyItem.h index babf2b7b7051..b053c5b27598 100644 --- a/libevmasm/AssemblyItem.h +++ b/libevmasm/AssemblyItem.h @@ -62,7 +62,9 @@ enum AssemblyItemType CallF, ///< Jumps to a returning EOF function, adding a new frame to the return stack. JumpF, ///< Jumps to a returning or non-returning EOF function without changing the return stack. RetF, ///< Returns from an EOF function, removing a frame from the return stack. - VerbatimBytecode ///< Contains data that is inserted into the bytecode code section without modification. + VerbatimBytecode, ///< Contains data that is inserted into the bytecode code section without modification. + SwapN, ///< EOF SWAPN with immediate argument. + DupN, ///< EOF DUPN with immediate argument. }; enum class Precision { Precise , Approximate }; @@ -147,6 +149,16 @@ class AssemblyItem solAssert(_tag.type() == Tag); return AssemblyItem(ConditionalRelativeJump, Instruction::RJUMPI, _tag.data(), _debugData); } + static AssemblyItem swapN(size_t _depth, langutil::DebugData::ConstPtr _debugData = langutil::DebugData::create()) + { + solAssert(_depth >= 1 && _depth <= 256); + return AssemblyItem(SwapN, Instruction::SWAPN, _depth, _debugData); + } + static AssemblyItem dupN(size_t _depth, langutil::DebugData::ConstPtr _debugData = langutil::DebugData::create()) + { + solAssert(_depth >= 1 && _depth <= 256); + return AssemblyItem(DupN, Instruction::DUPN, _depth, _debugData); + } AssemblyItem(AssemblyItem const&) = default; AssemblyItem(AssemblyItem&&) = default; @@ -191,7 +203,9 @@ class AssemblyItem m_type == ConditionalRelativeJump || m_type == CallF || m_type == JumpF || - m_type == RetF; + m_type == RetF || + m_type == SwapN || + m_type == DupN; } /// @returns the instruction of this item (only valid if hasInstruction returns true) Instruction instruction() const diff --git a/libevmasm/Instruction.cpp b/libevmasm/Instruction.cpp index 649a6c863486..dad9804d09a8 100644 --- a/libevmasm/Instruction.cpp +++ b/libevmasm/Instruction.cpp @@ -172,6 +172,8 @@ std::map const solidity::evmasm::c_instructions = { "CALLF", Instruction::CALLF }, { "RETF", Instruction::RETF }, { "JUMPF", Instruction::JUMPF }, + { "DUPN", Instruction::DUPN }, + { "SWAPN", Instruction::SWAPN }, { "RJUMP", Instruction::RJUMP }, { "RJUMPI", Instruction::RJUMPI }, { "EOFCREATE", Instruction::EOFCREATE }, @@ -339,6 +341,8 @@ static std::map const c_instructionInfo = {Instruction::RETF, {"RETF", 0, 0, 0, true, Tier::RetF}}, {Instruction::CALLF, {"CALLF", 2, 0, 0, true, Tier::CallF}}, {Instruction::JUMPF, {"JUMPF", 2, 0, 0, true, Tier::JumpF}}, + {Instruction::SWAPN, {"SWAPN", 1, 0, 0, false, Tier::VeryLow}}, + {Instruction::DUPN, {"DUPN", 1, 0, 0, false, Tier::VeryLow}}, {Instruction::EOFCREATE, {"EOFCREATE", 1, 4, 1, true, Tier::Special}}, {Instruction::RETURNCONTRACT, {"RETURNCONTRACT", 1, 2, 0, true, Tier::Special}}, {Instruction::CREATE, {"CREATE", 0, 3, 1, true, Tier::Special}}, diff --git a/libevmasm/Instruction.h b/libevmasm/Instruction.h index a1b9af364a0d..137144715296 100644 --- a/libevmasm/Instruction.h +++ b/libevmasm/Instruction.h @@ -190,6 +190,8 @@ enum class Instruction: uint8_t CALLF = 0xe3, ///< call function in a EOF code section RETF = 0xe4, ///< return to caller from the code section of EOF container JUMPF = 0xe5, ///< jump to a code section of EOF container without adding a new return stack frame. + DUPN = 0xe6, ///< copies a value at the stack depth given as immediate argument to the top of the stack + SWAPN = 0xe7, ///< swaps the highest value with a value at a stack depth given as immediate argument EOFCREATE = 0xec, ///< create a new account with associated container code. RETURNCONTRACT = 0xee, ///< return container to be deployed with axiliary data filled in. CREATE = 0xf0, ///< create a new account with associated code @@ -232,18 +234,6 @@ inline bool isPushInstruction(Instruction _inst) return Instruction::PUSH0 <= _inst && _inst <= Instruction::PUSH32; } -/// @returns true if the instruction is a DUP -inline bool isDupInstruction(Instruction _inst) -{ - return Instruction::DUP1 <= _inst && _inst <= Instruction::DUP16; -} - -/// @returns true if the instruction is a SWAP -inline bool isSwapInstruction(Instruction _inst) -{ - return Instruction::SWAP1 <= _inst && _inst <= Instruction::SWAP16; -} - /// @returns true if the instruction is a LOG inline bool isLogInstruction(Instruction _inst) { @@ -256,18 +246,6 @@ inline unsigned getPushNumber(Instruction _inst) return static_cast(_inst) - unsigned(Instruction::PUSH0); } -/// @returns the number of DUP Instruction _inst -inline unsigned getDupNumber(Instruction _inst) -{ - return static_cast(_inst) - unsigned(Instruction::DUP1) + 1; -} - -/// @returns the number of SWAP Instruction _inst -inline unsigned getSwapNumber(Instruction _inst) -{ - return static_cast(_inst) - unsigned(Instruction::SWAP1) + 1; -} - /// @returns the number of LOG Instruction _inst inline unsigned getLogNumber(Instruction _inst) { diff --git a/libevmasm/KnownState.cpp b/libevmasm/KnownState.cpp index 66553bc06633..6e1a00465b26 100644 --- a/libevmasm/KnownState.cpp +++ b/libevmasm/KnownState.cpp @@ -137,14 +137,14 @@ KnownState::StoreOperation KnownState::feedItem(AssemblyItem const& _item, bool setStackElement( m_stackHeight + 1, stackElement( - m_stackHeight - static_cast(instruction) + static_cast(Instruction::DUP1), + m_stackHeight - (static_cast(SemanticInformation::getDupNumber(_item)) - 1), _item.debugData() ) ); else if (SemanticInformation::isSwapInstruction(_item)) swapStackElements( m_stackHeight, - m_stackHeight - 1 - static_cast(instruction) + static_cast(Instruction::SWAP1), + m_stackHeight - 1 - (static_cast(SemanticInformation::getSwapNumber(_item)) - 1), _item.debugData() ); else if (instruction != Instruction::POP) diff --git a/libevmasm/PeepholeOptimiser.cpp b/libevmasm/PeepholeOptimiser.cpp index 3129efb4d734..879f5b3272dc 100644 --- a/libevmasm/PeepholeOptimiser.cpp +++ b/libevmasm/PeepholeOptimiser.cpp @@ -290,7 +290,7 @@ struct DupSwap: SimplePeepholeOptimizerMethod if ( SemanticInformation::isDupInstruction(_dupN) && SemanticInformation::isSwapInstruction(_swapN) && - getDupNumber(_dupN.instruction()) == getSwapNumber(_swapN.instruction()) + SemanticInformation::getDupNumber(_dupN) == SemanticInformation::getSwapNumber(_swapN) ) { *_out = _dupN; diff --git a/libevmasm/SemanticInformation.cpp b/libevmasm/SemanticInformation.cpp index a9672efa53b0..662436ff63c8 100644 --- a/libevmasm/SemanticInformation.cpp +++ b/libevmasm/SemanticInformation.cpp @@ -312,16 +312,22 @@ bool SemanticInformation::isCommutativeOperation(AssemblyItem const& _item) bool SemanticInformation::isDupInstruction(AssemblyItem const& _item) { + if (_item.type() == evmasm::DupN) + return true; if (_item.type() != evmasm::Operation) return false; - return evmasm::isDupInstruction(_item.instruction()); + auto inst = _item.instruction(); + return Instruction::DUP1 <= inst && inst <= Instruction::DUP16; } bool SemanticInformation::isSwapInstruction(AssemblyItem const& _item) { + if (_item.type() == evmasm::SwapN) + return true; if (_item.type() != evmasm::Operation) return false; - return evmasm::isSwapInstruction(_item.instruction()); + auto inst = _item.instruction(); + return Instruction::SWAP1 <= inst && inst <= Instruction::SWAP16; } bool SemanticInformation::altersControlFlow(AssemblyItem const& _item) @@ -387,6 +393,24 @@ bool SemanticInformation::reverts(Instruction _instruction) } } +size_t SemanticInformation::getDupNumber(AssemblyItem const& _item) +{ + assertThrow(isDupInstruction(_item), OptimizerException, "Not a DUP instruction."); + if (_item.type() == evmasm::DupN) + return static_cast(_item.data()); + auto inst = _item.instruction(); + return static_cast(inst) - static_cast(Instruction::DUP1) + 1; +} + +size_t SemanticInformation::getSwapNumber(AssemblyItem const& _item) +{ + assertThrow(isSwapInstruction(_item), OptimizerException, "Not a swap instruction."); + if (_item.type() == evmasm::SwapN) + return static_cast(_item.data()); + auto inst = _item.instruction(); + return static_cast(inst) - static_cast(Instruction::SWAP1) + 1; +} + bool SemanticInformation::isDeterministic(AssemblyItem const& _item) { assertThrow(_item.type() != VerbatimBytecode, AssemblyException, ""); diff --git a/libevmasm/SemanticInformation.h b/libevmasm/SemanticInformation.h index 457f60052a6a..8dae6acad6f6 100644 --- a/libevmasm/SemanticInformation.h +++ b/libevmasm/SemanticInformation.h @@ -86,6 +86,10 @@ struct SemanticInformation static bool terminatesControlFlow(AssemblyItem const& _item); static bool terminatesControlFlow(Instruction _instruction); static bool reverts(Instruction _instruction); + /// @returns the 1-based DUP depth a DUP AssembleItem @a _item + static size_t getDupNumber(AssemblyItem const& _item); + /// @returns the 1-based SWAP depth a DUP AssembleItem @a _item + static size_t getSwapNumber(AssemblyItem const& _item); /// @returns false if the value put on the stack by _item depends on anything else than /// the information in the current block header, memory, storage, transient storage or stack. static bool isDeterministic(AssemblyItem const& _item); diff --git a/liblangutil/EVMVersion.cpp b/liblangutil/EVMVersion.cpp index 30df93796522..4fbfe8de41b0 100644 --- a/liblangutil/EVMVersion.cpp +++ b/liblangutil/EVMVersion.cpp @@ -84,6 +84,8 @@ bool EVMVersion::hasOpcode(Instruction _opcode, std::optional _eofVersi case Instruction::RJUMPI: case Instruction::CALLF: case Instruction::JUMPF: + case Instruction::DUPN: + case Instruction::SWAPN: case Instruction::RETF: case Instruction::EXTCALL: case Instruction::EXTSTATICCALL: diff --git a/libyul/AsmAnalysis.cpp b/libyul/AsmAnalysis.cpp index 7c82d788f35f..352f16f769b8 100644 --- a/libyul/AsmAnalysis.cpp +++ b/libyul/AsmAnalysis.cpp @@ -741,7 +741,9 @@ bool AsmAnalyzer::validateInstructions(evmasm::Instruction _instr, SourceLocatio _instr != evmasm::Instruction::RJUMPI && _instr != evmasm::Instruction::CALLF && _instr != evmasm::Instruction::JUMPF && - _instr != evmasm::Instruction::RETF + _instr != evmasm::Instruction::RETF && + _instr != evmasm::Instruction::DUPN && + _instr != evmasm::Instruction::SWAPN ); auto errorForVM = [&](ErrorId _errorId, std::string const& vmKindMessage) { diff --git a/libyul/backends/evm/AbstractAssembly.h b/libyul/backends/evm/AbstractAssembly.h index 7a3e6b7422be..41f480f442a0 100644 --- a/libyul/backends/evm/AbstractAssembly.h +++ b/libyul/backends/evm/AbstractAssembly.h @@ -149,6 +149,13 @@ class AbstractAssembly /// EOF auxiliary data in data section and the auxiliary data are different things. virtual void appendToAuxiliaryData(bytes const& _data) = 0; + /// Appends a SWAPN with 1-based indexing for @arg _depth. I.e. a depth of 1 would be equivalent to emitting SWAP1. + /// @arg _depth ranges from 1 to 256. + virtual void appendSwapN(size_t _depth) = 0; + /// Appends a DUPN with 1-based indexing for @arg _depth. I.e. a depth of 1 would be equivalent to emitting DUP1. + /// @arg _depth ranges from 1 to 256. + virtual void appendDupN(size_t _depth) = 0; + /// Mark this assembly as invalid. Any attempt to request bytecode from it should throw. virtual void markAsInvalid() = 0; diff --git a/libyul/backends/evm/EVMDialect.cpp b/libyul/backends/evm/EVMDialect.cpp index 4fa78f0233a4..d68ef16348b1 100644 --- a/libyul/backends/evm/EVMDialect.cpp +++ b/libyul/backends/evm/EVMDialect.cpp @@ -211,8 +211,8 @@ std::vector> createBuiltins(langutil::EVMVe auto const opcode = instr.second; if ( - !evmasm::isDupInstruction(opcode) && - !evmasm::isSwapInstruction(opcode) && + !(opcode >= evmasm::Instruction::DUP1 && opcode <= evmasm::Instruction::DUP16) && + !(opcode >= evmasm::Instruction::SWAP1 && opcode <= evmasm::Instruction::SWAP16) && !evmasm::isPushInstruction(opcode) && opcode != evmasm::Instruction::JUMP && opcode != evmasm::Instruction::JUMPI && @@ -224,6 +224,8 @@ std::vector> createBuiltins(langutil::EVMVe opcode != evmasm::Instruction::RJUMPI && opcode != evmasm::Instruction::CALLF && opcode != evmasm::Instruction::JUMPF && + opcode != evmasm::Instruction::DUPN && + opcode != evmasm::Instruction::SWAPN && opcode != evmasm::Instruction::RETF && _evmVersion.hasOpcode(opcode, _eofVersion) && !prevRandaoException(name) diff --git a/libyul/backends/evm/EthAssemblyAdapter.cpp b/libyul/backends/evm/EthAssemblyAdapter.cpp index b608859e2ba8..960e663dfa7a 100644 --- a/libyul/backends/evm/EthAssemblyAdapter.cpp +++ b/libyul/backends/evm/EthAssemblyAdapter.cpp @@ -232,6 +232,17 @@ void EthAssemblyAdapter::appendAuxDataLoadN(uint16_t _offset) m_assembly.appendAuxDataLoadN(_offset); } +void EthAssemblyAdapter::appendSwapN(size_t _depth) +{ + m_assembly.appendSwapN(_depth); +} + +void EthAssemblyAdapter::appendDupN(size_t _depth) +{ + m_assembly.appendDupN(_depth); +} + + void EthAssemblyAdapter::markAsInvalid() { m_assembly.markAsInvalid(); diff --git a/libyul/backends/evm/EthAssemblyAdapter.h b/libyul/backends/evm/EthAssemblyAdapter.h index 93e7c816abf4..dd708b8b33de 100644 --- a/libyul/backends/evm/EthAssemblyAdapter.h +++ b/libyul/backends/evm/EthAssemblyAdapter.h @@ -74,6 +74,9 @@ class EthAssemblyAdapter: public AbstractAssembly void appendAuxDataLoadN(uint16_t _offset) override; + void appendSwapN(size_t _depth) override; + void appendDupN(size_t _depth) override; + void markAsInvalid() override; langutil::EVMVersion evmVersion() const override; diff --git a/libyul/backends/evm/NoOutputAssembly.cpp b/libyul/backends/evm/NoOutputAssembly.cpp index 322191984fd4..78025265f342 100644 --- a/libyul/backends/evm/NoOutputAssembly.cpp +++ b/libyul/backends/evm/NoOutputAssembly.cpp @@ -114,6 +114,11 @@ void NoOutputAssembly::appendAssemblySize() appendInstruction(evmasm::Instruction::PUSH1); } +void NoOutputAssembly::appendDupN(size_t) +{ + m_stackHeight++; +} + std::pair, AbstractAssembly::SubID> NoOutputAssembly::createSubAssembly(bool, std::string) { yulAssert(false, "Sub assemblies not implemented."); diff --git a/libyul/backends/evm/NoOutputAssembly.h b/libyul/backends/evm/NoOutputAssembly.h index 64832b083df9..502f90d854f5 100644 --- a/libyul/backends/evm/NoOutputAssembly.h +++ b/libyul/backends/evm/NoOutputAssembly.h @@ -90,6 +90,8 @@ class NoOutputAssembly: public AbstractAssembly void appendAuxDataLoadN(uint16_t) override; void appendEOFCreate(ContainerID) override; void appendReturnContract(ContainerID) override; + void appendSwapN(size_t) override {} + void appendDupN(size_t) override; void markAsInvalid() override {} diff --git a/test/libyul/yulSyntaxTests/eof/eof_identifiers_not_defined_in_legacy.yul b/test/libyul/yulSyntaxTests/eof/eof_identifiers_not_defined_in_legacy.yul index 0b786893ec06..71137488f293 100644 --- a/test/libyul/yulSyntaxTests/eof/eof_identifiers_not_defined_in_legacy.yul +++ b/test/libyul/yulSyntaxTests/eof/eof_identifiers_not_defined_in_legacy.yul @@ -11,6 +11,8 @@ extcall(0, 1, 2, 3) extstaticcall(0, 1, 2) extdelegatecall(0, 1, 2) + swapn() + dupn() } // ==== // bytecodeFormat: legacy @@ -27,3 +29,5 @@ // TypeError 4328: (172-179): The "extcall" instruction is only available in EOF. // TypeError 4328: (196-209): The "extstaticcall" instruction is only available in EOF. // TypeError 4328: (223-238): The "extdelegatecall" instruction is only available in EOF. +// DeclarationError 4619: (252-257): Function "swapn" not found. +// DeclarationError 4619: (264-268): Function "dupn" not found. diff --git a/test/libyul/yulSyntaxTests/eof/eof_identifiers_not_reserved_in_legacy.yul b/test/libyul/yulSyntaxTests/eof/eof_identifiers_not_reserved_in_legacy.yul index 3cb737d4bf10..313e17884ee5 100644 --- a/test/libyul/yulSyntaxTests/eof/eof_identifiers_not_reserved_in_legacy.yul +++ b/test/libyul/yulSyntaxTests/eof/eof_identifiers_not_reserved_in_legacy.yul @@ -11,6 +11,8 @@ function extcall() {} function extstaticcall() {} function extdelegatecall() {} + function swapn() {} + function dupn() {} } // ==== // bytecodeFormat: legacy \ No newline at end of file diff --git a/test/libyul/yulSyntaxTests/eof/eof_opcodes_identifiers_reserved_in_eof.yul b/test/libyul/yulSyntaxTests/eof/eof_opcodes_identifiers_reserved_in_eof.yul index 17ca120e6e5f..6992e4003fb8 100644 --- a/test/libyul/yulSyntaxTests/eof/eof_opcodes_identifiers_reserved_in_eof.yul +++ b/test/libyul/yulSyntaxTests/eof/eof_opcodes_identifiers_reserved_in_eof.yul @@ -5,6 +5,8 @@ function callf() {} function jumpf() {} function retf() {} + function swapn() {} + function dupn() {} } // ==== // bytecodeFormat: >=EOFv1 @@ -15,3 +17,5 @@ // DeclarationError 5017: (83-102): The identifier "callf" is reserved and can not be used. // DeclarationError 5017: (107-126): The identifier "jumpf" is reserved and can not be used. // DeclarationError 5017: (131-149): The identifier "retf" is reserved and can not be used. +// DeclarationError 5017: (154-173): The identifier "swapn" is reserved and can not be used. +// DeclarationError 5017: (178-196): The identifier "dupn" is reserved and can not be used. diff --git a/test/tools/yulInterpreter/EVMInstructionInterpreter.cpp b/test/tools/yulInterpreter/EVMInstructionInterpreter.cpp index 94a6c3b1ee3f..31c2ccc97744 100644 --- a/test/tools/yulInterpreter/EVMInstructionInterpreter.cpp +++ b/test/tools/yulInterpreter/EVMInstructionInterpreter.cpp @@ -486,6 +486,8 @@ u256 EVMInstructionInterpreter::eval( case Instruction::SWAP14: case Instruction::SWAP15: case Instruction::SWAP16: + case Instruction::SWAPN: + case Instruction::DUPN: yulAssert(false, "Impossible in strict assembly."); case Instruction::DATALOADN: case Instruction::CALLF: From 091dde6f483cd61d23945a783ca64f1c9615e77e Mon Sep 17 00:00:00 2001 From: Martin Blicha Date: Fri, 14 Feb 2025 12:51:41 +0100 Subject: [PATCH 0812/1022] ConstantEvaluator: Add `tryEvaluate` method that swallows errors --- libsolidity/analysis/ConstantEvaluator.cpp | 14 ++++++++++++++ libsolidity/analysis/ConstantEvaluator.h | 4 ++++ 2 files changed, 18 insertions(+) diff --git a/libsolidity/analysis/ConstantEvaluator.cpp b/libsolidity/analysis/ConstantEvaluator.cpp index 8e18183a81f9..0d953be93ff4 100644 --- a/libsolidity/analysis/ConstantEvaluator.cpp +++ b/libsolidity/analysis/ConstantEvaluator.cpp @@ -269,6 +269,20 @@ std::optional ConstantEvaluator::evaluate( return ConstantEvaluator{_errorReporter}.evaluate(_expr); } +std::optional ConstantEvaluator::tryEvaluate(Expression const& _expr) +{ + ErrorList errorList; + ErrorReporter errorReporter(errorList); + try + { + return ConstantEvaluator{errorReporter}.evaluate(_expr); + } + catch (FatalError const&) + { + return std::nullopt; + } +} + std::optional ConstantEvaluator::evaluate(ASTNode const& _node) { diff --git a/libsolidity/analysis/ConstantEvaluator.h b/libsolidity/analysis/ConstantEvaluator.h index 5b4b3460446b..297d5f6e80c9 100644 --- a/libsolidity/analysis/ConstantEvaluator.h +++ b/libsolidity/analysis/ConstantEvaluator.h @@ -57,6 +57,10 @@ class ConstantEvaluator: private ASTConstVisitor Expression const& _expr ); + /// Works the same as `evaluate` but swallows any errors that might occur in the evaluation and simply returns + /// `std::nullopt` instead. + static std::optional tryEvaluate(Expression const& _expr); + /// Performs arbitrary-precision evaluation of a binary operator. Returns nullopt on cases like /// division by zero or e.g. bit operators applied to fractional values. static std::optional evaluateBinaryOperator(Token _operator, rational const& _left, rational const& _right); From de36f55772a1bda6bf6e5523053a4f5e1006cc72 Mon Sep 17 00:00:00 2001 From: Martin Blicha Date: Fri, 14 Feb 2025 12:54:38 +0100 Subject: [PATCH 0813/1022] SMTChecker: Ignore errors that might occur during constant evaluation Previously, if a fatal error would occur during constant evaluation in the model checker, it would throw an exception which the model checker would let escape and crash the compiler. We now use the new API that swallows any errors and the model checker can continue, simply treating the expression as not constant. --- Changelog.md | 1 + libsolidity/formal/SMTEncoder.cpp | 9 ++------- .../operators/constant_evaluation_add.sol | 11 +++++++++++ .../operators/constant_evaluation_bitwise_not.sol | 9 +++++++++ .../operators/constant_evaluation_sub.sol | 11 +++++++++++ 5 files changed, 34 insertions(+), 7 deletions(-) create mode 100644 test/libsolidity/smtCheckerTests/operators/constant_evaluation_add.sol create mode 100644 test/libsolidity/smtCheckerTests/operators/constant_evaluation_bitwise_not.sol create mode 100644 test/libsolidity/smtCheckerTests/operators/constant_evaluation_sub.sol diff --git a/Changelog.md b/Changelog.md index f6fc05636291..731f8d57944a 100644 --- a/Changelog.md +++ b/Changelog.md @@ -16,6 +16,7 @@ Compiler Features: Bugfixes: * General: Fix internal compiler error when requesting IR AST outputs for interfaces and abstract contracts. + * SMTChecker: Fix internal compiler error when analyzing overflowing expressions or bitwise negation of unsigned types involving constants. * SMTChecker: Fix reporting on targets that are safe in the context of one contract but unsafe in the context of another contract. * SMTChecker: Fix SMT logic error when analyzing cross-contract getter call with BMC. * SMTChecker: Fix SMT logic error when contract deployment involves string literal to fixed bytes conversion. diff --git a/libsolidity/formal/SMTEncoder.cpp b/libsolidity/formal/SMTEncoder.cpp index 7c826ab36b21..a0b71f5941a9 100644 --- a/libsolidity/formal/SMTEncoder.cpp +++ b/libsolidity/formal/SMTEncoder.cpp @@ -3124,13 +3124,8 @@ RationalNumberType const* SMTEncoder::isConstant(Expression const& _expr) if (auto type = dynamic_cast(_expr.annotation().type)) return type; - // _expr may not be constant evaluable. - // In that case we ignore any warnings emitted by the constant evaluator, - // as it will return nullptr in case of failure. - ErrorList l; - ErrorReporter e(l); - if (auto t = ConstantEvaluator::evaluate(e, _expr)) - return TypeProvider::rationalNumber(t->value); + if (auto typedRational = ConstantEvaluator::tryEvaluate(_expr)) + return TypeProvider::rationalNumber(typedRational->value); return nullptr; } diff --git a/test/libsolidity/smtCheckerTests/operators/constant_evaluation_add.sol b/test/libsolidity/smtCheckerTests/operators/constant_evaluation_add.sol new file mode 100644 index 000000000000..b174b9478810 --- /dev/null +++ b/test/libsolidity/smtCheckerTests/operators/constant_evaluation_add.sol @@ -0,0 +1,11 @@ +contract C { + uint8 constant N = 255; + + function f() public pure returns (uint8) { + return N + 1; + } +} +// ==== +// SMTEngine: chc +// ---- +// Warning 4984: (104-109): CHC: Overflow (resulting value larger than 255) happens here.\nCounterexample:\nN = 255\n = 0\n\nTransaction trace:\nC.constructor()\nState: N = 255\nC.f() diff --git a/test/libsolidity/smtCheckerTests/operators/constant_evaluation_bitwise_not.sol b/test/libsolidity/smtCheckerTests/operators/constant_evaluation_bitwise_not.sol new file mode 100644 index 000000000000..54159b18074d --- /dev/null +++ b/test/libsolidity/smtCheckerTests/operators/constant_evaluation_bitwise_not.sol @@ -0,0 +1,9 @@ +contract C { + uint256 constant largeConstant = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF; + function test() public pure returns (uint256) { + return ~largeConstant; + } +} +// ==== +// SMTEngine: chc +// ---- diff --git a/test/libsolidity/smtCheckerTests/operators/constant_evaluation_sub.sol b/test/libsolidity/smtCheckerTests/operators/constant_evaluation_sub.sol new file mode 100644 index 000000000000..39a9b7cac396 --- /dev/null +++ b/test/libsolidity/smtCheckerTests/operators/constant_evaluation_sub.sol @@ -0,0 +1,11 @@ +contract C { + uint256 public constant B = 1; + + function f() public pure returns (uint256) { + return B - 112; + } +} +// ==== +// SMTEngine: chc +// ---- +// Warning 3944: (113-120): CHC: Underflow (resulting value less than 0) happens here.\nCounterexample:\nB = 1\n = 0\n\nTransaction trace:\nC.constructor()\nState: B = 1\nC.f() From d51fda0d8c3af20987a4f8f0ff7f8560c26f2f2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Fri, 31 Jan 2025 18:01:48 +0100 Subject: [PATCH 0814/1022] installing-solidity.rst: Remove redundant example of usage via docker --- docs/installing-solidity.rst | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/docs/installing-solidity.rst b/docs/installing-solidity.rst index 129d1d3a82e3..912c501dcc13 100644 --- a/docs/installing-solidity.rst +++ b/docs/installing-solidity.rst @@ -83,17 +83,11 @@ and runs it in a new container, passing the ``--help`` argument. docker run ethereum/solc:stable --help -You can specify release build versions in the tag. For example: - -.. code-block:: bash - - docker run ethereum/solc:stable --help - -Note +.. note:: -Specific compiler versions are supported as the Docker image tag such as `ethereum/solc:0.8.23`. We will be passing the -`stable` tag here instead of specific version tag to ensure that users get the latest version by default and avoid the issue of -an out-of-date version. + Specific compiler versions are supported as the Docker image tag such as `ethereum/solc:0.8.23`. + We will be passing the `stable` tag here instead of specific version tag to ensure that users get + the latest version by default and avoid the issue of an out-of-date version. To use the Docker image to compile Solidity files on the host machine, mount a local folder for input and output, and specify the contract to compile. For example: From d23bfb63a593db486db366b0818bec899e8cbdfa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Fri, 31 Jan 2025 18:17:08 +0100 Subject: [PATCH 0815/1022] installing-solidity.rst: Fix single backticks --- docs/installing-solidity.rst | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/installing-solidity.rst b/docs/installing-solidity.rst index 912c501dcc13..261c07266fec 100644 --- a/docs/installing-solidity.rst +++ b/docs/installing-solidity.rst @@ -47,15 +47,15 @@ npm / Node.js ============= Use ``npm`` for a convenient and portable way to install ``solcjs``, a Solidity compiler. The -`solcjs` program has fewer features than the ways to access the compiler described +``solcjs`` program has fewer features than the ways to access the compiler described further down this page. The :ref:`commandline-compiler` documentation assumes you are using the full-featured compiler, ``solc``. The usage of ``solcjs`` is documented inside its own `repository `_. Note: The solc-js project is derived from the C++ -`solc` by using Emscripten, which means that both use the same compiler source code. -`solc-js` can be used in JavaScript projects directly (such as Remix). +``solc`` by using Emscripten, which means that both use the same compiler source code. +``solc-js`` can be used in JavaScript projects directly (such as Remix). Please refer to the solc-js repository for instructions. .. code-block:: bash @@ -85,8 +85,8 @@ and runs it in a new container, passing the ``--help`` argument. .. note:: - Specific compiler versions are supported as the Docker image tag such as `ethereum/solc:0.8.23`. - We will be passing the `stable` tag here instead of specific version tag to ensure that users get + Specific compiler versions are supported as the Docker image tag such as ``ethereum/solc:0.8.23``. + We will be passing the ``stable`` tag here instead of specific version tag to ensure that users get the latest version by default and avoid the issue of an out-of-date version. To use the Docker image to compile Solidity files on the host machine, mount a @@ -212,7 +212,7 @@ out-of-the-box but it is also meant to be friendly to third-party tools: - The content is mirrored to https://binaries.soliditylang.org where it can be easily downloaded over HTTPS without any authentication, rate limiting or the need to use git. -- Content is served with correct `Content-Type` headers and lenient CORS configuration so that it +- Content is served with correct ``Content-Type`` headers and lenient CORS configuration so that it can be directly loaded by tools running in the browser. - Binaries do not require installation or unpacking (exception for older Windows builds bundled with necessary DLLs). From 19002a8f4cb08202334be60b8e4d939e262a86ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Fri, 31 Jan 2025 18:18:23 +0100 Subject: [PATCH 0816/1022] installing-solidity.rst: Use full option names and tweak example commands - Also put example paths in /tmp to avoid new root dirs being created if the example is used verbatim --- docs/installing-solidity.rst | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/docs/installing-solidity.rst b/docs/installing-solidity.rst index 261c07266fec..07d82b9c81d1 100644 --- a/docs/installing-solidity.rst +++ b/docs/installing-solidity.rst @@ -60,7 +60,7 @@ Please refer to the solc-js repository for instructions. .. code-block:: bash - npm install -g solc + npm install --global solc .. note:: @@ -94,7 +94,13 @@ local folder for input and output, and specify the contract to compile. For exam .. code-block:: bash - docker run -v /local/path:/sources ethereum/solc:stable -o /sources/output --abi --bin /sources/Contract.sol + docker run \ + --volume "/tmp/some/local/path/:/sources/" \ + ethereum/solc:stable \ + /sources/Contract.sol \ + --abi \ + --bin \ + --output-dir /sources/output/ You can also use the standard JSON interface (which is recommended when using the compiler with tooling). When using this interface, it is not necessary to mount any directories as long as the JSON input is From 46006c82fdd9fca8c5ac05200cd73a2d1a526975 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Thu, 13 Feb 2025 10:13:12 +0100 Subject: [PATCH 0817/1022] Default comparison operators for frontend optimiser settings --- Changelog.md | 1 + libsolidity/interface/OptimiserSettings.h | 23 ++--------------------- 2 files changed, 3 insertions(+), 21 deletions(-) diff --git a/Changelog.md b/Changelog.md index 731f8d57944a..00b7df77b912 100644 --- a/Changelog.md +++ b/Changelog.md @@ -16,6 +16,7 @@ Compiler Features: Bugfixes: * General: Fix internal compiler error when requesting IR AST outputs for interfaces and abstract contracts. + * Metadata: Fix custom cleanup sequence missing from metadata when other optimizer settings have default values. * SMTChecker: Fix internal compiler error when analyzing overflowing expressions or bitwise negation of unsigned types involving constants. * SMTChecker: Fix reporting on targets that are safe in the context of one contract but unsafe in the context of another contract. * SMTChecker: Fix SMT logic error when analyzing cross-contract getter call with BMC. diff --git a/libsolidity/interface/OptimiserSettings.h b/libsolidity/interface/OptimiserSettings.h index 1f702851c066..d282e139d22a 100644 --- a/libsolidity/interface/OptimiserSettings.h +++ b/libsolidity/interface/OptimiserSettings.h @@ -111,27 +111,8 @@ struct OptimiserSettings util::unreachable(); } - bool operator==(OptimiserSettings const& _other) const - { - return - runOrderLiterals == _other.runOrderLiterals && - runInliner == _other.runInliner && - runJumpdestRemover == _other.runJumpdestRemover && - runPeephole == _other.runPeephole && - runDeduplicate == _other.runDeduplicate && - runCSE == _other.runCSE && - runConstantOptimiser == _other.runConstantOptimiser && - simpleCounterForLoopUncheckedIncrement == _other.simpleCounterForLoopUncheckedIncrement && - optimizeStackAllocation == _other.optimizeStackAllocation && - runYulOptimiser == _other.runYulOptimiser && - yulOptimiserSteps == _other.yulOptimiserSteps && - expectedExecutionsPerDeployment == _other.expectedExecutionsPerDeployment; - } - - bool operator!=(OptimiserSettings const& _other) const - { - return !(*this == _other); - } + bool operator==(OptimiserSettings const& _other) const = default; + bool operator!=(OptimiserSettings const& _other) const = default; /// Move literals to the right of commutative binary operators during code generation. /// This helps exploiting associativity. From cc164838ab46d7af32af90984007053aa6e8da9a Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Thu, 13 Feb 2025 15:11:46 +0100 Subject: [PATCH 0818/1022] Add test that has a custom cleanup sequence but otherwise default optimizer settings --- test/libsolidity/Metadata.cpp | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/test/libsolidity/Metadata.cpp b/test/libsolidity/Metadata.cpp index e6cdef036819..da3822dcddd9 100644 --- a/test/libsolidity/Metadata.cpp +++ b/test/libsolidity/Metadata.cpp @@ -458,16 +458,27 @@ BOOST_AUTO_TEST_CASE(metadata_optimiser_sequence) {"dhfoDgvulfnTUtnIf", "fDn"} }; - auto check = [sourceCode](std::string const& _optimizerSequence, std::string const& _optimizerCleanupSequence) + std::vector settingsToTest; + for (auto const& [optimizerSequence, optimizerCleanupSequence]: sequences) + { + settingsToTest.emplace_back(OptimiserSettings::minimal()); + settingsToTest.back().runYulOptimiser = true; + settingsToTest.back().yulOptimiserSteps = optimizerSequence; + settingsToTest.back().yulOptimiserCleanupSteps = optimizerCleanupSequence; + } + + { + // test that a custom cleanup step sequence does not lead to default standard optimiser settings in metadata + settingsToTest.emplace_back(OptimiserSettings::standard()); + settingsToTest.back().yulOptimiserCleanupSteps = "D"; + } + + auto check = [sourceCode](OptimiserSettings const& _optimizerSettings) { - OptimiserSettings optimizerSettings = OptimiserSettings::minimal(); - optimizerSettings.runYulOptimiser = true; - optimizerSettings.yulOptimiserSteps = _optimizerSequence; - optimizerSettings.yulOptimiserCleanupSteps = _optimizerCleanupSequence; CompilerStack compilerStack; compilerStack.setSources({{"", sourceCode}}); compilerStack.setEVMVersion(solidity::test::CommonOptions::get().evmVersion()); - compilerStack.setOptimiserSettings(optimizerSettings); + compilerStack.setOptimiserSettings(_optimizerSettings); BOOST_REQUIRE_MESSAGE(compilerStack.compile(), "Compiling contract failed"); @@ -480,12 +491,12 @@ BOOST_AUTO_TEST_CASE(metadata_optimiser_sequence) BOOST_CHECK(metadata["settings"]["optimizer"]["details"]["yulDetails"].contains("optimizerSteps")); std::string const metadataOptimizerSteps = metadata["settings"]["optimizer"]["details"]["yulDetails"]["optimizerSteps"].get(); - std::string const expectedMetadataOptimiserSteps = _optimizerSequence + ":" + _optimizerCleanupSequence; + std::string const expectedMetadataOptimiserSteps = _optimizerSettings.yulOptimiserSteps + ":" + _optimizerSettings.yulOptimiserCleanupSteps; BOOST_CHECK_EQUAL(metadataOptimizerSteps, expectedMetadataOptimiserSteps); }; - for (auto const& [sequence, cleanupSequence] : sequences) - check(sequence, cleanupSequence); + for (auto const& optimizerSettings: settingsToTest) + check(optimizerSettings); } BOOST_AUTO_TEST_CASE(metadata_license_missing) From 85fe2a007ea2bf7887cf348623060b4d83cc4f13 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Thu, 20 Feb 2025 13:42:03 +0100 Subject: [PATCH 0819/1022] Use buildx in docker deploy manual --- scripts/docker_deploy_manual.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/docker_deploy_manual.sh b/scripts/docker_deploy_manual.sh index 8753d59c9a2d..1386bcfa177e 100755 --- a/scripts/docker_deploy_manual.sh +++ b/scripts/docker_deploy_manual.sh @@ -47,13 +47,13 @@ function tag_and_push } rm -rf .git -docker build -t "$image":build -f scripts/Dockerfile . --progress plain +docker buildx build -t "$image":build -f scripts/Dockerfile . --progress=plain tmp_container=$(docker create "$image":build sh) # Alpine image mkdir -p upload docker cp "${tmp_container}":/usr/bin/solc upload/solc-static-linux -docker build -t "$image":build-alpine -f scripts/Dockerfile_alpine . --progress plain +docker buildx build -t "$image":build-alpine -f scripts/Dockerfile_alpine . --progress=plain if [ "$branch" = "develop" ] then From df96847da35d3ddfefd02054826d917b838605f1 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Tue, 18 Feb 2025 09:08:17 +0100 Subject: [PATCH 0820/1022] Expands metadata test coverage to more presets and non-default sequence with default cleanup --- test/libsolidity/Metadata.cpp | 60 ++++++++++++++++++++++++----------- 1 file changed, 41 insertions(+), 19 deletions(-) diff --git a/test/libsolidity/Metadata.cpp b/test/libsolidity/Metadata.cpp index da3822dcddd9..3b7d101d5948 100644 --- a/test/libsolidity/Metadata.cpp +++ b/test/libsolidity/Metadata.cpp @@ -443,7 +443,7 @@ BOOST_AUTO_TEST_CASE(metadata_revert_strings) BOOST_AUTO_TEST_CASE(metadata_optimiser_sequence) { - char const* sourceCode = R"( + std::string const sourceCode = R"( pragma solidity >=0.0; contract C { } @@ -455,28 +455,34 @@ BOOST_AUTO_TEST_CASE(metadata_optimiser_sequence) {"", ""}, {"", "fDn"}, {"dhfoDgvulfnTUtnIf", "" }, - {"dhfoDgvulfnTUtnIf", "fDn"} + {"dhfoDgvulfnTUtnIf", "fDn"}, + // test that a custom cleanup step sequence does not lead to default standard optimiser settings in metadata + {OptimiserSettings::DefaultYulOptimiserSteps, "D"}, + // test that a custom optimizer sequence does not lead to default standard optimiser settings in metadata + {"dhfoDgvulfnTUtnIf", OptimiserSettings::DefaultYulOptimiserCleanupSteps} }; std::vector settingsToTest; for (auto const& [optimizerSequence, optimizerCleanupSequence]: sequences) { - settingsToTest.emplace_back(OptimiserSettings::minimal()); - settingsToTest.back().runYulOptimiser = true; - settingsToTest.back().yulOptimiserSteps = optimizerSequence; - settingsToTest.back().yulOptimiserCleanupSteps = optimizerCleanupSequence; - } - - { - // test that a custom cleanup step sequence does not lead to default standard optimiser settings in metadata - settingsToTest.emplace_back(OptimiserSettings::standard()); - settingsToTest.back().yulOptimiserCleanupSteps = "D"; + for (auto const& preset: { + OptimiserSettings::none(), + OptimiserSettings::minimal(), + OptimiserSettings::standard(), + OptimiserSettings::full(), + }) + { + settingsToTest.emplace_back(preset); + settingsToTest.back().runYulOptimiser = true; + settingsToTest.back().yulOptimiserSteps = optimizerSequence; + settingsToTest.back().yulOptimiserCleanupSteps = optimizerCleanupSequence; + } } - auto check = [sourceCode](OptimiserSettings const& _optimizerSettings) + auto generateMetadataJson = [](std::string const& _source, OptimiserSettings const& _optimizerSettings) -> Json { CompilerStack compilerStack; - compilerStack.setSources({{"", sourceCode}}); + compilerStack.setSources({{"", _source}}); compilerStack.setEVMVersion(solidity::test::CommonOptions::get().evmVersion()); compilerStack.setOptimiserSettings(_optimizerSettings); @@ -486,17 +492,33 @@ BOOST_AUTO_TEST_CASE(metadata_optimiser_sequence) Json metadata; BOOST_REQUIRE(util::jsonParseStrict(serialisedMetadata, metadata)); BOOST_CHECK(solidity::test::isValidMetadata(metadata)); - BOOST_CHECK(metadata["settings"]["optimizer"].contains("details")); - BOOST_CHECK(metadata["settings"]["optimizer"]["details"].contains("yulDetails")); - BOOST_CHECK(metadata["settings"]["optimizer"]["details"]["yulDetails"].contains("optimizerSteps")); + return metadata; + }; + + auto checkCustomSettings = [generateMetadataJson, sourceCode](OptimiserSettings const& _optimizerSettings) + { + auto const metadataJson = generateMetadataJson(sourceCode, _optimizerSettings); + BOOST_CHECK(metadataJson["settings"]["optimizer"].contains("details")); + BOOST_CHECK(metadataJson["settings"]["optimizer"]["details"].contains("yulDetails")); + BOOST_CHECK(metadataJson["settings"]["optimizer"]["details"]["yulDetails"].contains("optimizerSteps")); - std::string const metadataOptimizerSteps = metadata["settings"]["optimizer"]["details"]["yulDetails"]["optimizerSteps"].get(); + std::string const metadataOptimizerSteps = metadataJson["settings"]["optimizer"]["details"]["yulDetails"]["optimizerSteps"].get(); std::string const expectedMetadataOptimiserSteps = _optimizerSettings.yulOptimiserSteps + ":" + _optimizerSettings.yulOptimiserCleanupSteps; BOOST_CHECK_EQUAL(metadataOptimizerSteps, expectedMetadataOptimiserSteps); }; for (auto const& optimizerSettings: settingsToTest) - check(optimizerSettings); + checkCustomSettings(optimizerSettings); + + for (auto const& preset: {OptimiserSettings::minimal(), OptimiserSettings::standard(), OptimiserSettings::full()}) + { + auto const metadataJson = generateMetadataJson(sourceCode, preset); + Json expectedOptimizerMetadata = { + {"enabled", preset != OptimiserSettings::minimal()}, + {"runs", preset.expectedExecutionsPerDeployment} + }; + BOOST_CHECK(metadataJson["settings"]["optimizer"] == expectedOptimizerMetadata); + } } BOOST_AUTO_TEST_CASE(metadata_license_missing) From 5c0ba6c25d4e0017ab5d23bd2ed25ad341173821 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Mon, 10 Feb 2025 14:33:33 +0100 Subject: [PATCH 0821/1022] Optimize collection of references in dataflow analyzer clearValues Previously, when clearing values in the data flow analyzer, referencing values were gathered by iterating over all variables and checking if they are contained inside any of the gathered references, reflected in a datastructure of form map(variable -> set). Now, it is just checked, if there is any nonempty intersection between the set of variables to clean and the values of the aforementioned map. The check makes use of sets being sorted. In pathological cases like the chains.sol benchmark, this can bring down the compilation time by approx. 50%. No functional changes, overall behavior stays the same. --- libsolutil/CommonData.h | 23 ++++++++++++++++++ libyul/optimiser/DataFlowAnalyzer.cpp | 35 +++++++++++++++------------ libyul/optimiser/DataFlowAnalyzer.h | 7 +++--- libyul/optimiser/Rematerialiser.cpp | 2 +- 4 files changed, 47 insertions(+), 20 deletions(-) diff --git a/libsolutil/CommonData.h b/libsolutil/CommonData.h index b663ede77bb5..ee3a6eb9551f 100644 --- a/libsolutil/CommonData.h +++ b/libsolutil/CommonData.h @@ -551,6 +551,29 @@ void iterateReplacingWindow(std::vector& _vector, F const& _f, std::index_seq } +/// Checks if two collections possess a non-empty intersection. +/// Assumes that both inputs are sorted in ascending order. +template +requires ( + std::forward_iterator> && + std::forward_iterator> +) +bool hasNonemptyIntersectionSorted(Collection1 const& _collection1, Collection2 const& _collection2) +{ + auto it1 = std::ranges::begin(_collection1); + auto it2 = std::ranges::begin(_collection2); + while (it1 != std::ranges::end(_collection1) && it2 != std::ranges::end(_collection2)) + { + if (*it1 == *it2) + return true; + if (*it1 < *it2) + ++it1; + else + ++it2; + } + return false; +} + /// Function that iterates over the vector @param _vector, /// calling the function @param _f on sequences of @tparam N of its /// elements. If @param _f returns a vector, these elements are replaced by diff --git a/libyul/optimiser/DataFlowAnalyzer.cpp b/libyul/optimiser/DataFlowAnalyzer.cpp index b11282bb176b..2407781354d0 100644 --- a/libyul/optimiser/DataFlowAnalyzer.cpp +++ b/libyul/optimiser/DataFlowAnalyzer.cpp @@ -263,9 +263,10 @@ void DataFlowAnalyzer::handleAssignment(std::set const& _variables, Exp } auto const& referencedVariables = movableChecker.referencedVariables(); + std::vector const referencedVariablesSorted(referencedVariables.begin(), referencedVariables.end()); for (auto const& name: _variables) { - m_state.references[name] = referencedVariables; + m_state.sortedReferences[name] = referencedVariablesSorted; if (!_isDeclaration) { // assignment to slot denoted by "name" @@ -310,12 +311,12 @@ void DataFlowAnalyzer::popScope() for (auto const& name: m_variableScopes.back().variables) { m_state.value.erase(name); - m_state.references.erase(name); + m_state.sortedReferences.erase(name); } m_variableScopes.pop_back(); } -void DataFlowAnalyzer::clearValues(std::set _variables) +void DataFlowAnalyzer::clearValues(std::set const& _variablesToClear) { // All variables that reference variables to be cleared also have to be // cleared, but not recursively, since only the value of the original @@ -333,30 +334,32 @@ void DataFlowAnalyzer::clearValues(std::set _variables) // First clear storage knowledge, because we do not have to clear // storage knowledge of variables whose expression has changed, // since the value is still unchanged. - auto eraseCondition = mapTuple([&_variables](auto&& key, auto&& value) { - return _variables.count(key) || _variables.count(value); + auto eraseCondition = mapTuple([&_variablesToClear](auto&& key, auto&& value) { + return _variablesToClear.count(key) || _variablesToClear.count(value); }); std::erase_if(m_state.environment.storage, eraseCondition); std::erase_if(m_state.environment.memory, eraseCondition); - std::erase_if(m_state.environment.keccak, [&_variables](auto&& _item) { + std::erase_if(m_state.environment.keccak, [&_variablesToClear](auto&& _item) { return - _variables.count(_item.first.first) || - _variables.count(_item.first.second) || - _variables.count(_item.second); + _variablesToClear.count(_item.first.first) || + _variablesToClear.count(_item.first.second) || + _variablesToClear.count(_item.second); }); // Also clear variables that reference variables to be cleared. - std::set referencingVariables; - for (auto const& variableToClear: _variables) - for (auto const& [ref, names]: m_state.references) - if (names.count(variableToClear)) - referencingVariables.emplace(ref); + std::set referencingVariablesToClear; + std::vector const sortedVariablesToClear(_variablesToClear.begin(), _variablesToClear.end()); + for (auto const& [referencingVariable, referencedVariables]: m_state.sortedReferences) + // instead of checking each variable in `referencedVariables`, we check if there is any intersection making use of the + // sortedness of the vectors, which can increase performance by up to 50% in pathological cases + if (hasNonemptyIntersectionSorted(referencedVariables, sortedVariablesToClear)) + referencingVariablesToClear.emplace(referencingVariable); // Clear the value and update the reference relation. - for (auto const& name: _variables + referencingVariables) + for (auto const& name: _variablesToClear + referencingVariablesToClear) { m_state.value.erase(name); - m_state.references.erase(name); + m_state.sortedReferences.erase(name); } } diff --git a/libyul/optimiser/DataFlowAnalyzer.h b/libyul/optimiser/DataFlowAnalyzer.h index 5b1cf25ffe1f..7b731a4eb877 100644 --- a/libyul/optimiser/DataFlowAnalyzer.h +++ b/libyul/optimiser/DataFlowAnalyzer.h @@ -104,7 +104,7 @@ class DataFlowAnalyzer: public ASTModifier /// @returns the current value of the given variable, if known - always movable. AssignedValue const* variableValue(YulName _variable) const { return util::valueOrNullptr(m_state.value, _variable); } - std::set const* references(YulName _variable) const { return util::valueOrNullptr(m_state.references, _variable); } + std::vector const* sortedReferences(YulName _variable) const { return util::valueOrNullptr(m_state.sortedReferences, _variable); } std::map const& allValues() const { return m_state.value; } std::optional storageValue(YulName _key) const; std::optional memoryValue(YulName _key) const; @@ -122,7 +122,7 @@ class DataFlowAnalyzer: public ASTModifier /// Clears information about the values assigned to the given variables, /// for example at points where control flow is merged. - void clearValues(std::set _names); + void clearValues(std::set const& _variablesToClear); virtual void assignValue(YulName _variable, Expression const* _value); @@ -180,7 +180,8 @@ class DataFlowAnalyzer: public ASTModifier /// Current values of variables, always movable. std::map value; /// m_references[a].contains(b) <=> the current expression assigned to a references b - std::unordered_map> references; + /// The mapped vectors _must always_ be sorted + std::unordered_map> sortedReferences; Environment environment; }; diff --git a/libyul/optimiser/Rematerialiser.cpp b/libyul/optimiser/Rematerialiser.cpp index fe33b10a2245..bfcd9d8f630f 100644 --- a/libyul/optimiser/Rematerialiser.cpp +++ b/libyul/optimiser/Rematerialiser.cpp @@ -71,7 +71,7 @@ void Rematerialiser::visit(Expression& _e) ) { assertThrow(m_referenceCounts[name] > 0, OptimizerException, ""); - auto variableReferences = references(name); + auto variableReferences = sortedReferences(name); if (!variableReferences || ranges::all_of(*variableReferences, [&](auto const& ref) { return inScope(ref); })) { // update reference counts From e844a8bfb26f7d850b1bf783228e298ad7595f0c Mon Sep 17 00:00:00 2001 From: Matheus Aguiar Date: Thu, 23 Jan 2025 14:01:11 -0300 Subject: [PATCH 0822/1022] Parse contract layout specification --- Changelog.md | 1 + docs/grammar/SolidityLexer.g4 | 2 + docs/grammar/SolidityParser.g4 | 13 ++- liblangutil/ErrorReporter.cpp | 11 ++ liblangutil/ErrorReporter.h | 1 + libsolidity/analysis/NameAndTypeResolver.cpp | 4 + libsolidity/analysis/TypeChecker.cpp | 3 + libsolidity/ast/AST.cpp | 11 ++ libsolidity/ast/AST.h | 27 ++++- libsolidity/ast/ASTForward.h | 1 + libsolidity/ast/ASTJsonExporter.cpp | 18 ++- libsolidity/ast/ASTJsonExporter.h | 2 + libsolidity/ast/ASTJsonImporter.cpp | 16 ++- libsolidity/ast/ASTJsonImporter.h | 3 +- libsolidity/ast/ASTVisitor.h | 4 + libsolidity/ast/AST_accept.h | 20 ++++ libsolidity/interface/CompilerStack.cpp | 4 +- libsolidity/parsing/Parser.cpp | 76 ++++++++++++- libsolidity/parsing/Parser.h | 2 + .../args | 1 + .../input.sol | 4 + .../output | 103 ++++++++++++++++++ .../args | 1 + .../inheritance_repeated_definition_error/err | 10 ++ .../exit | 1 + .../stdin | 10 ++ .../args | 1 + .../err | 1 + .../exit | 1 + .../stdin | 62 +++++++++++ .../args | 1 + .../err | 5 + .../exit | 1 + .../stdin | 4 + .../args | 1 + .../err | 5 + .../exit | 1 + .../stdin | 4 + .../args | 1 + .../err | 10 ++ .../exit | 1 + .../stdin | 6 + .../args | 1 + .../err | 1 + .../exit | 1 + .../output | 2 + .../stdin | 4 + .../ASTJSON/storage_layout_specifier.json | 88 +++++++++++++++ .../ASTJSON/storage_layout_specifier.sol | 3 + .../functionCalls/empty_call_options.sol | 8 ++ .../duplicated_inheritance_definition.sol | 5 + .../repeated_inheritance_definition.sol | 7 ++ .../abstract_contract.sol | 4 + .../at_before_layout.sol | 3 + .../contract_named_at.sol | 4 + .../contract_named_layout.sol | 4 + ...tract_with_members_named_layout_and_at.sol | 7 ++ .../duplicated_layout_definition.sol | 3 + .../duplicated_layout_keyword.sol | 4 + .../function_declaration_layout_specified.sol | 5 + ..._declaration_layout_with_no_expression.sol | 6 + .../storageLayoutSpecifier/interface.sol | 3 + ...layout_specification_binary_expression.sol | 4 + .../layout_specification_by_function.sol | 7 ++ ...t_specification_constant_in_expression.sol | 5 + .../layout_specification_no_expression.sol | 3 + .../layout_specified_by_empty_braces.sol | 3 + ...ecified_by_function_empty_call_options.sol | 6 + ...pecified_by_function_with_call_options.sol | 7 ++ .../layout_statement_without_at.sol | 4 + .../layout_with_inheritance.sol | 7 ++ .../storageLayoutSpecifier/library.sol | 3 + .../multi_token_expression.sol | 5 + .../storageLayoutSpecifier/natspec.sol | 10 ++ .../repeated_layout_definition.sol | 5 + .../storageLayoutSpecifier/simple_layout.sol | 6 + .../state_variable_layout_specifier.sol | 5 + .../struct_layout_specifier.sol | 3 + 78 files changed, 684 insertions(+), 16 deletions(-) create mode 100644 test/cmdlineTests/ast_compact_json_storage_layout_specifier/args create mode 100644 test/cmdlineTests/ast_compact_json_storage_layout_specifier/input.sol create mode 100644 test/cmdlineTests/ast_compact_json_storage_layout_specifier/output create mode 100644 test/cmdlineTests/inheritance_repeated_definition_error/args create mode 100644 test/cmdlineTests/inheritance_repeated_definition_error/err create mode 100644 test/cmdlineTests/inheritance_repeated_definition_error/exit create mode 100644 test/cmdlineTests/inheritance_repeated_definition_error/stdin create mode 100644 test/cmdlineTests/standard_cli_import_ast_storage_layout_specifier_missing_expression/args create mode 100644 test/cmdlineTests/standard_cli_import_ast_storage_layout_specifier_missing_expression/err create mode 100644 test/cmdlineTests/standard_cli_import_ast_storage_layout_specifier_missing_expression/exit create mode 100644 test/cmdlineTests/standard_cli_import_ast_storage_layout_specifier_missing_expression/stdin create mode 100644 test/cmdlineTests/storage_layout_specifier_codegen_error/args create mode 100644 test/cmdlineTests/storage_layout_specifier_codegen_error/err create mode 100644 test/cmdlineTests/storage_layout_specifier_codegen_error/exit create mode 100644 test/cmdlineTests/storage_layout_specifier_codegen_error/stdin create mode 100644 test/cmdlineTests/storage_layout_specifier_ir_codegen_error/args create mode 100644 test/cmdlineTests/storage_layout_specifier_ir_codegen_error/err create mode 100644 test/cmdlineTests/storage_layout_specifier_ir_codegen_error/exit create mode 100644 test/cmdlineTests/storage_layout_specifier_ir_codegen_error/stdin create mode 100644 test/cmdlineTests/storage_layout_specifier_repeated_definition_error/args create mode 100644 test/cmdlineTests/storage_layout_specifier_repeated_definition_error/err create mode 100644 test/cmdlineTests/storage_layout_specifier_repeated_definition_error/exit create mode 100644 test/cmdlineTests/storage_layout_specifier_repeated_definition_error/stdin create mode 100644 test/cmdlineTests/storage_layout_specifier_storage_layout_output_error/args create mode 100644 test/cmdlineTests/storage_layout_specifier_storage_layout_output_error/err create mode 100644 test/cmdlineTests/storage_layout_specifier_storage_layout_output_error/exit create mode 100644 test/cmdlineTests/storage_layout_specifier_storage_layout_output_error/output create mode 100644 test/cmdlineTests/storage_layout_specifier_storage_layout_output_error/stdin create mode 100644 test/libsolidity/ASTJSON/storage_layout_specifier.json create mode 100644 test/libsolidity/ASTJSON/storage_layout_specifier.sol create mode 100644 test/libsolidity/syntaxTests/functionCalls/empty_call_options.sol create mode 100644 test/libsolidity/syntaxTests/inheritance/duplicated_inheritance_definition.sol create mode 100644 test/libsolidity/syntaxTests/inheritance/repeated_inheritance_definition.sol create mode 100644 test/libsolidity/syntaxTests/storageLayoutSpecifier/abstract_contract.sol create mode 100644 test/libsolidity/syntaxTests/storageLayoutSpecifier/at_before_layout.sol create mode 100644 test/libsolidity/syntaxTests/storageLayoutSpecifier/contract_named_at.sol create mode 100644 test/libsolidity/syntaxTests/storageLayoutSpecifier/contract_named_layout.sol create mode 100644 test/libsolidity/syntaxTests/storageLayoutSpecifier/contract_with_members_named_layout_and_at.sol create mode 100644 test/libsolidity/syntaxTests/storageLayoutSpecifier/duplicated_layout_definition.sol create mode 100644 test/libsolidity/syntaxTests/storageLayoutSpecifier/duplicated_layout_keyword.sol create mode 100644 test/libsolidity/syntaxTests/storageLayoutSpecifier/function_declaration_layout_specified.sol create mode 100644 test/libsolidity/syntaxTests/storageLayoutSpecifier/function_declaration_layout_with_no_expression.sol create mode 100644 test/libsolidity/syntaxTests/storageLayoutSpecifier/interface.sol create mode 100644 test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specification_binary_expression.sol create mode 100644 test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specification_by_function.sol create mode 100644 test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specification_constant_in_expression.sol create mode 100644 test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specification_no_expression.sol create mode 100644 test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_empty_braces.sol create mode 100644 test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_function_empty_call_options.sol create mode 100644 test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_function_with_call_options.sol create mode 100644 test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_statement_without_at.sol create mode 100644 test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_with_inheritance.sol create mode 100644 test/libsolidity/syntaxTests/storageLayoutSpecifier/library.sol create mode 100644 test/libsolidity/syntaxTests/storageLayoutSpecifier/multi_token_expression.sol create mode 100644 test/libsolidity/syntaxTests/storageLayoutSpecifier/natspec.sol create mode 100644 test/libsolidity/syntaxTests/storageLayoutSpecifier/repeated_layout_definition.sol create mode 100644 test/libsolidity/syntaxTests/storageLayoutSpecifier/simple_layout.sol create mode 100644 test/libsolidity/syntaxTests/storageLayoutSpecifier/state_variable_layout_specifier.sol create mode 100644 test/libsolidity/syntaxTests/storageLayoutSpecifier/struct_layout_specifier.sol diff --git a/Changelog.md b/Changelog.md index 00b7df77b912..3eb3abf79f38 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,6 +1,7 @@ ### 0.8.29 (unreleased) Language Features: + * Introduce syntax for specifying contract storage layout base. Compiler Features: diff --git a/docs/grammar/SolidityLexer.g4 b/docs/grammar/SolidityLexer.g4 index f994c331d536..ad3b04098132 100644 --- a/docs/grammar/SolidityLexer.g4 +++ b/docs/grammar/SolidityLexer.g4 @@ -14,6 +14,7 @@ Address: 'address'; Anonymous: 'anonymous'; As: 'as'; Assembly: 'assembly' -> pushMode(AssemblyBlockMode); +At: 'at'; // not a real keyword Bool: 'bool'; Break: 'break'; Bytes: 'bytes'; @@ -54,6 +55,7 @@ Indexed: 'indexed'; Interface: 'interface'; Internal: 'internal'; Is: 'is'; +Layout: 'layout'; // not a real keyword Library: 'library'; Mapping: 'mapping'; Memory: 'memory'; diff --git a/docs/grammar/SolidityParser.g4 b/docs/grammar/SolidityParser.g4 index a344fad54470..5ad422913e98 100644 --- a/docs/grammar/SolidityParser.g4 +++ b/docs/grammar/SolidityParser.g4 @@ -52,9 +52,14 @@ symbolAliases: LBrace aliases+=importAliases (Comma aliases+=importAliases)* RBr /** * Top-level definition of a contract. */ -contractDefinition: +contractDefinition +locals [boolean layoutSet=false, boolean inheritanceSet=false] +: Abstract? Contract name=identifier - inheritanceSpecifierList? + ( + {!$layoutSet}? Layout At expression {$layoutSet = true;} + | {!$inheritanceSet}? inheritanceSpecifierList {$inheritanceSet = true;} + )* LBrace contractBodyElement* RBrace; /** * Top-level definition of an interface. @@ -379,7 +384,7 @@ expression: expression LBrack index=expression? RBrack # IndexAccess | expression LBrack startIndex=expression? Colon endIndex=expression? RBrack # IndexRangeAccess | expression Period (identifier | Address) # MemberAccess - | expression LBrace (namedArgument (Comma namedArgument)*)? RBrace # FunctionCallOptions + | expression LBrace (namedArgument (Comma namedArgument)*) RBrace # FunctionCallOptions | expression callArgumentList # FunctionCall | Payable callArgumentList # PayableConversion | Type LParen typeName RParen # MetaType @@ -420,7 +425,7 @@ inlineArrayExpression: LBrack (expression ( Comma expression)* ) RBrack; /** * Besides regular non-keyword Identifiers, some keywords like 'from' and 'error' can also be used as identifiers. */ -identifier: Identifier | From | Error | Revert | Global | Transient; +identifier: Identifier | From | Error | Revert | Global | Transient | Layout | At; literal: stringLiteral | numberLiteral | booleanLiteral | hexStringLiteral | unicodeStringLiteral; diff --git a/liblangutil/ErrorReporter.cpp b/liblangutil/ErrorReporter.cpp index 8c8bb7ab05b8..10d7f1d116a6 100644 --- a/liblangutil/ErrorReporter.cpp +++ b/liblangutil/ErrorReporter.cpp @@ -190,6 +190,17 @@ void ErrorReporter::parserError(ErrorId _error, SourceLocation const& _location, ); } +void ErrorReporter::parserError(ErrorId _error, SourceLocation const& _location, SecondarySourceLocation const& _secondaryLocation, std::string const& _description) +{ + error( + _error, + Error::Type::ParserError, + _location, + _secondaryLocation, + _description + ); +} + void ErrorReporter::fatalParserError(ErrorId _error, SourceLocation const& _location, std::string const& _description) { fatalError( diff --git a/liblangutil/ErrorReporter.h b/liblangutil/ErrorReporter.h index 55e4d56216b7..dc359c1b05e0 100644 --- a/liblangutil/ErrorReporter.h +++ b/liblangutil/ErrorReporter.h @@ -87,6 +87,7 @@ class ErrorReporter void fatalDeclarationError(ErrorId _error, SourceLocation const& _location, std::string const& _description); void parserError(ErrorId _error, SourceLocation const& _location, std::string const& _description); + void parserError(ErrorId _error, SourceLocation const& _location, SecondarySourceLocation const& _secondaryLocation, std::string const& _description); void fatalParserError(ErrorId _error, SourceLocation const& _location, std::string const& _description); diff --git a/libsolidity/analysis/NameAndTypeResolver.cpp b/libsolidity/analysis/NameAndTypeResolver.cpp index 766f1bf121f5..2fb6a6162405 100644 --- a/libsolidity/analysis/NameAndTypeResolver.cpp +++ b/libsolidity/analysis/NameAndTypeResolver.cpp @@ -299,6 +299,10 @@ bool NameAndTypeResolver::resolveNamesAndTypesInternal(ASTNode& _node, bool _res if (!resolveNamesAndTypesInternal(*baseContract, true)) success = false; + if (StorageLayoutSpecifier* storageLayoutSpecifier = contract->storageLayoutSpecifier()) + if (!resolveNamesAndTypesInternal(*storageLayoutSpecifier, true)) + success = false; + setScope(contract); if (success) diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp index b461fa283026..a0d21744de88 100644 --- a/libsolidity/analysis/TypeChecker.cpp +++ b/libsolidity/analysis/TypeChecker.cpp @@ -86,6 +86,9 @@ bool TypeChecker::visit(ContractDefinition const& _contract) ASTNode::listAccept(_contract.baseContracts(), *this); + if (StorageLayoutSpecifier const* layoutSpecifier = _contract.storageLayoutSpecifier()) + layoutSpecifier->accept(*this); + for (auto const& n: _contract.subNodes()) n->accept(*this); diff --git a/libsolidity/ast/AST.cpp b/libsolidity/ast/AST.cpp index b62ea3e2df8a..cf3bddf403d6 100644 --- a/libsolidity/ast/AST.cpp +++ b/libsolidity/ast/AST.cpp @@ -371,6 +371,17 @@ std::multimap const& ContractDefinition: }); } +StorageLayoutSpecifier::StorageLayoutSpecifier( + int64_t _id, + SourceLocation const& _location, + ASTPointer _baseSlotExpression +): + ASTNode(_id, _location), + m_baseSlotExpression(_baseSlotExpression) +{ + solAssert(m_baseSlotExpression); + solAssert(_location.contains(m_baseSlotExpression->location())); +} TypeNameAnnotation& TypeName::annotation() const { diff --git a/libsolidity/ast/AST.h b/libsolidity/ast/AST.h index 5cf4880075a2..cc5cc932415c 100644 --- a/libsolidity/ast/AST.h +++ b/libsolidity/ast/AST.h @@ -509,14 +509,16 @@ class ContractDefinition: public Declaration, public StructurallyDocumented, pub std::vector> _baseContracts, std::vector> _subNodes, ContractKind _contractKind = ContractKind::Contract, - bool _abstract = false + bool _abstract = false, + ASTPointer _storageLayoutSpecifier = nullptr ): Declaration(_id, _location, _name, std::move(_nameLocation)), StructurallyDocumented(_documentation), m_baseContracts(std::move(_baseContracts)), m_subNodes(std::move(_subNodes)), m_contractKind(_contractKind), - m_abstract(_abstract) + m_abstract(_abstract), + m_storageLayoutSpecifier(_storageLayoutSpecifier) {} void accept(ASTVisitor& _visitor) override; @@ -586,6 +588,9 @@ class ContractDefinition: public Declaration, public StructurallyDocumented, pub bool abstract() const { return m_abstract; } + StorageLayoutSpecifier const* storageLayoutSpecifier() const { return m_storageLayoutSpecifier.get(); } + StorageLayoutSpecifier* storageLayoutSpecifier() { return m_storageLayoutSpecifier.get(); } + ContractDefinition const* superContract(ContractDefinition const& _mostDerivedContract) const; /// @returns the next constructor in the inheritance hierarchy. FunctionDefinition const* nextConstructor(ContractDefinition const& _mostDerivedContract) const; @@ -597,12 +602,30 @@ class ContractDefinition: public Declaration, public StructurallyDocumented, pub std::vector> m_subNodes; ContractKind m_contractKind; bool m_abstract{false}; + ASTPointer m_storageLayoutSpecifier; util::LazyInit, FunctionTypePointer>>> m_interfaceFunctionList[2]; util::LazyInit> m_interfaceEvents; util::LazyInit> m_definedFunctionsByName; }; + +class StorageLayoutSpecifier : public ASTNode +{ +public: + StorageLayoutSpecifier( + int64_t _id, + SourceLocation const& _location, + ASTPointer _baseSlotExpression + ); + void accept(ASTVisitor& _visitor) override; + void accept(ASTConstVisitor& _visitor) const override; + + Expression const& baseSlotExpression() const { solAssert(m_baseSlotExpression); return *m_baseSlotExpression; } +private: + ASTPointer m_baseSlotExpression; +}; + /** * A sequence of identifiers separated by dots used outside the expression context. Inside the expression context, this is a sequence of Identifier and MemberAccess. */ diff --git a/libsolidity/ast/ASTForward.h b/libsolidity/ast/ASTForward.h index b8a3a4ae0057..d0fe7d97afa1 100644 --- a/libsolidity/ast/ASTForward.h +++ b/libsolidity/ast/ASTForward.h @@ -98,6 +98,7 @@ class Identifier; class ElementaryTypeNameExpression; class Literal; class StructuredDocumentation; +class StorageLayoutSpecifier; /// Experimental Solidity nodes /// @{ diff --git a/libsolidity/ast/ASTJsonExporter.cpp b/libsolidity/ast/ASTJsonExporter.cpp index 4e7a5cd508b4..42627b5f7f7c 100644 --- a/libsolidity/ast/ASTJsonExporter.cpp +++ b/libsolidity/ast/ASTJsonExporter.cpp @@ -210,6 +210,13 @@ Json ASTJsonExporter::toJson(ASTNode const& _node) return util::removeNullMembers(std::move(m_currentValue)); } +Json ASTJsonExporter::toJson(ASTNode const* _node) +{ + if (!_node) + return Json(); + return toJson(*_node); +} + bool ASTJsonExporter::visit(SourceUnit const& _node) { std::vector> attributes = { @@ -279,6 +286,14 @@ bool ASTJsonExporter::visit(ImportDirective const& _node) return false; } +bool ASTJsonExporter::visit(StorageLayoutSpecifier const& _node) +{ + setJsonNode(_node, "StorageLayoutSpecifier", { + {"baseSlotExpression", toJson(_node.baseSlotExpression())} + }); + return false; +} + bool ASTJsonExporter::visit(ContractDefinition const& _node) { std::vector> attributes = { @@ -293,7 +308,8 @@ bool ASTJsonExporter::visit(ContractDefinition const& _node) std::make_pair("usedEvents", getContainerIds(_node.interfaceEvents(false))), std::make_pair("usedErrors", getContainerIds(_node.interfaceErrors(false))), std::make_pair("nodes", toJson(_node.subNodes())), - std::make_pair("scope", idOrNull(_node.scope())) + std::make_pair("scope", idOrNull(_node.scope())), + std::make_pair("storageLayout", toJson(_node.storageLayoutSpecifier())) }; addIfSet(attributes, "canonicalName", _node.annotation().canonicalName); diff --git a/libsolidity/ast/ASTJsonExporter.h b/libsolidity/ast/ASTJsonExporter.h index c7933120a974..3174dc1865ea 100644 --- a/libsolidity/ast/ASTJsonExporter.h +++ b/libsolidity/ast/ASTJsonExporter.h @@ -60,6 +60,7 @@ class ASTJsonExporter: public ASTConstVisitor /// Output the json representation of the AST to _stream. void print(std::ostream& _stream, ASTNode const& _node, util::JsonFormat const& _format); Json toJson(ASTNode const& _node); + Json toJson(ASTNode const* _node); template Json toJson(std::vector> const& _nodes) { @@ -126,6 +127,7 @@ class ASTJsonExporter: public ASTConstVisitor bool visit(ElementaryTypeNameExpression const& _node) override; bool visit(Literal const& _node) override; bool visit(StructuredDocumentation const& _node) override; + bool visit(StorageLayoutSpecifier const& _node) override; void endVisit(EventDefinition const&) override; diff --git a/libsolidity/ast/ASTJsonImporter.cpp b/libsolidity/ast/ASTJsonImporter.cpp index 344bfb39d2a6..d6cd7f43896a 100644 --- a/libsolidity/ast/ASTJsonImporter.cpp +++ b/libsolidity/ast/ASTJsonImporter.cpp @@ -37,6 +37,8 @@ #include #include +#include + namespace solidity::frontend { @@ -255,6 +257,8 @@ ASTPointer ASTJsonImporter::convertJsonToASTNode(Json const& _json) return createLiteral(_json); if (nodeType == "StructuredDocumentation") return createDocumentation(_json); + if (nodeType == "StorageLayoutSpecifier") + return createStorageLayoutSpecifier(_json); else astAssert(false, "Unknown type of ASTNode: " + nodeType); @@ -348,7 +352,17 @@ ASTPointer ASTJsonImporter::createContractDefinition(Json co baseContracts, subNodes, contractKind(_node), - memberAsBool(_node, "abstract") + memberAsBool(_node, "abstract"), + nullOrCast(member(_node, "storageLayout")) + ); +} + +ASTPointer ASTJsonImporter::createStorageLayoutSpecifier(Json const& _node) +{ + astAssert(_node.contains("baseSlotExpression"), "Expected field \"baseSlotExpression\" is missing."); + return createASTNode( + _node, + convertJsonToASTNode(_node["baseSlotExpression"]) ); } diff --git a/libsolidity/ast/ASTJsonImporter.h b/libsolidity/ast/ASTJsonImporter.h index e4a7c2da3fe9..7c5dd5be9f99 100644 --- a/libsolidity/ast/ASTJsonImporter.h +++ b/libsolidity/ast/ASTJsonImporter.h @@ -131,10 +131,11 @@ class ASTJsonImporter ASTPointer createElementaryTypeNameExpression(Json const& _node); ASTPointer createLiteral(Json const& _node); ASTPointer createDocumentation(Json const& _node); + ASTPointer createStorageLayoutSpecifier(Json const& _node); ///@} // =============== general helper functions =================== - /// @returns the member of a given JSON object, throws if member does not exist + /// @returns the member of a given JSON object or null if member does not exist Json member(Json const& _node, std::string const& _name); /// @returns the appropriate TokenObject used in parsed Strings (pragma directive or operator) Token scanSingleToken(Json const& _node); diff --git a/libsolidity/ast/ASTVisitor.h b/libsolidity/ast/ASTVisitor.h index f985a449019a..010e99ec3d72 100644 --- a/libsolidity/ast/ASTVisitor.h +++ b/libsolidity/ast/ASTVisitor.h @@ -109,6 +109,7 @@ class ASTVisitor virtual bool visit(ElementaryTypeNameExpression& _node) { return visitNode(_node); } virtual bool visit(Literal& _node) { return visitNode(_node); } virtual bool visit(StructuredDocumentation& _node) { return visitNode(_node); } + virtual bool visit(StorageLayoutSpecifier& _node) { return visitNode(_node); } /// Experimental Solidity nodes /// @{ virtual bool visit(TypeClassDefinition& _node) { return visitNode(_node); } @@ -174,6 +175,7 @@ class ASTVisitor virtual void endVisit(ElementaryTypeNameExpression& _node) { endVisitNode(_node); } virtual void endVisit(Literal& _node) { endVisitNode(_node); } virtual void endVisit(StructuredDocumentation& _node) { endVisitNode(_node); } + virtual void endVisit(StorageLayoutSpecifier& _node) { endVisitNode(_node); } /// Experimental Solidity nodes /// @{ virtual void endVisit(TypeClassDefinition& _node) { endVisitNode(_node); } @@ -261,6 +263,7 @@ class ASTConstVisitor virtual bool visit(ElementaryTypeNameExpression const& _node) { return visitNode(_node); } virtual bool visit(Literal const& _node) { return visitNode(_node); } virtual bool visit(StructuredDocumentation const& _node) { return visitNode(_node); } + virtual bool visit(StorageLayoutSpecifier const& _node) { return visitNode(_node); } /// Experimental Solidity nodes /// @{ virtual bool visit(TypeClassDefinition const& _node) { return visitNode(_node); } @@ -326,6 +329,7 @@ class ASTConstVisitor virtual void endVisit(ElementaryTypeNameExpression const& _node) { endVisitNode(_node); } virtual void endVisit(Literal const& _node) { endVisitNode(_node); } virtual void endVisit(StructuredDocumentation const& _node) { endVisitNode(_node); } + virtual void endVisit(StorageLayoutSpecifier const& _node) { endVisitNode(_node); } /// Experimental Solidity nodes /// @{ virtual void endVisit(TypeClassDefinition const& _node) { endVisitNode(_node); } diff --git a/libsolidity/ast/AST_accept.h b/libsolidity/ast/AST_accept.h index 55ebe2a78c61..1cd771f9d4a8 100644 --- a/libsolidity/ast/AST_accept.h +++ b/libsolidity/ast/AST_accept.h @@ -93,6 +93,8 @@ void ContractDefinition::accept(ASTVisitor& _visitor) if (m_documentation) m_documentation->accept(_visitor); listAccept(m_baseContracts, _visitor); + if (m_storageLayoutSpecifier) + m_storageLayoutSpecifier->accept(_visitor); listAccept(m_subNodes, _visitor); } _visitor.endVisit(*this); @@ -105,6 +107,8 @@ void ContractDefinition::accept(ASTConstVisitor& _visitor) const if (m_documentation) m_documentation->accept(_visitor); listAccept(m_baseContracts, _visitor); + if (m_storageLayoutSpecifier) + m_storageLayoutSpecifier->accept(_visitor); listAccept(m_subNodes, _visitor); } _visitor.endVisit(*this); @@ -1160,6 +1164,22 @@ void ForAllQuantifier::accept(ASTConstVisitor& _visitor) const } _visitor.endVisit(*this); } + +void StorageLayoutSpecifier::accept(ASTVisitor& _visitor) +{ + if (_visitor.visit(*this)) + m_baseSlotExpression->accept(_visitor); + + _visitor.endVisit(*this); +} + +void StorageLayoutSpecifier::accept(ASTConstVisitor& _visitor) const +{ + if (_visitor.visit(*this)) + m_baseSlotExpression->accept(_visitor); + + _visitor.endVisit(*this); +} /// @} } diff --git a/libsolidity/interface/CompilerStack.cpp b/libsolidity/interface/CompilerStack.cpp index 1791ad45a9d5..4e9346ecfebd 100644 --- a/libsolidity/interface/CompilerStack.cpp +++ b/libsolidity/interface/CompilerStack.cpp @@ -1104,6 +1104,7 @@ Json const& CompilerStack::storageLayout(Contract const& _contract) const solAssert(m_stackState >= AnalysisSuccessful, "Analysis was not successful."); solAssert(_contract.contract); solUnimplementedAssert(!isExperimentalSolidity()); + solUnimplementedAssert(!_contract.contract->storageLayoutSpecifier(), "Storage layout not supported for contract with specified layout base."); return _contract.storageLayout.init([&]{ return StorageLayout().generate(*_contract.contract, DataLocation::Storage); }); } @@ -1523,6 +1524,7 @@ void CompilerStack::compileContract( solAssert(!m_viaIR, ""); solUnimplementedAssert(!m_eofVersion.has_value(), "Experimental EOF support is only available for via-IR compilation."); solAssert(m_stackState >= AnalysisSuccessful, ""); + solUnimplementedAssert(!_contract.storageLayoutSpecifier(), "Code generation is not supported for contracts with specified storage layout base."); if (_otherCompilers.count(&_contract)) return; @@ -1558,7 +1560,7 @@ void CompilerStack::compileContract( void CompilerStack::generateIR(ContractDefinition const& _contract, bool _unoptimizedOnly) { solAssert(m_stackState >= AnalysisSuccessful, ""); - + solUnimplementedAssert(!_contract.storageLayoutSpecifier(), "Code generation is not supported for contracts with specified storage layout base."); Contract& compiledContract = m_contracts.at(_contract.fullyQualifiedName()); if (compiledContract.yulIR) { diff --git a/libsolidity/parsing/Parser.cpp b/libsolidity/parsing/Parser.cpp index 13303170d6ad..dce729de408b 100644 --- a/libsolidity/parsing/Parser.cpp +++ b/libsolidity/parsing/Parser.cpp @@ -370,6 +370,31 @@ std::pair Parser::parseContractKind() return std::make_pair(kind, abstract); } +ASTPointer Parser::parseStorageLayoutSpecifier() +{ + RecursionGuard recursionGuard(*this); + ASTNodeFactory nodeFactory(*this); + ASTPointer layoutIdentifier = expectIdentifierToken(); + solAssert(layoutIdentifier && *layoutIdentifier == "layout"); + if ( + m_scanner->currentToken() != Token::Identifier || + m_scanner->currentLiteral() != "at" + ) + m_errorReporter.parserError( + 1994_error, + m_scanner->currentLocation(), + "Expected \'at\' but got " + tokenName(m_scanner->currentToken()) + ); + + advance(); + ASTPointer baseSlotExpression = parseExpression(); + solAssert(baseSlotExpression); + nodeFactory.setEndPositionFromNode(baseSlotExpression); + return nodeFactory.createNode( + baseSlotExpression + ); +} + ASTPointer Parser::parseContractDefinition() { RecursionGuard recursionGuard(*this); @@ -380,16 +405,54 @@ ASTPointer Parser::parseContractDefinition() std::vector> baseContracts; std::vector> subNodes; std::pair contractKind{}; + ASTPointer storageLayoutSpecifier; documentation = parseStructuredDocumentation(); contractKind = parseContractKind(); std::tie(name, nameLocation) = expectIdentifierWithLocation(); - if (m_scanner->currentToken() == Token::Is) - do + while (true) + { + if (m_scanner->currentToken() == Token::Is) { - advance(); - baseContracts.push_back(parseInheritanceSpecifier()); + if (baseContracts.size() != 0) + m_errorReporter.parserError( + 6668_error, + m_scanner->currentLocation(), + SecondarySourceLocation().append("Previous list:", baseContracts[0]->location()), + "More than one inheritance list." + ); + do + { + advance(); + baseContracts.push_back(parseInheritanceSpecifier()); + } + while (m_scanner->currentToken() == Token::Comma); } - while (m_scanner->currentToken() == Token::Comma); + else if ( + m_scanner->currentToken() == Token::Identifier && + m_scanner->currentLiteral() == "layout" && + contractKind.first == ContractKind::Contract + ) + { + if (storageLayoutSpecifier) + m_errorReporter.parserError( + 8714_error, + m_scanner->currentLocation(), + SecondarySourceLocation().append("Previous definition:", storageLayoutSpecifier->location()), + "More than one storage layout definition." + ); + + storageLayoutSpecifier = parseStorageLayoutSpecifier(); + } + else + break; + } + + if (storageLayoutSpecifier && baseContracts.size() > 0) + { + solAssert(!storageLayoutSpecifier->location().intersects(baseContracts[0]->location())); + solAssert(!baseContracts[0]->location().intersects(storageLayoutSpecifier->location())); + } + expectToken(Token::LBrace); while (true) { @@ -443,7 +506,8 @@ ASTPointer Parser::parseContractDefinition() baseContracts, subNodes, contractKind.first, - contractKind.second + contractKind.second, + storageLayoutSpecifier ); } diff --git a/libsolidity/parsing/Parser.h b/libsolidity/parsing/Parser.h index 830df05c27c8..d208c1f8bd79 100644 --- a/libsolidity/parsing/Parser.h +++ b/libsolidity/parsing/Parser.h @@ -171,6 +171,8 @@ class Parser: public langutil::ParserBase FunctionCallArguments parseFunctionCallArguments(); FunctionCallArguments parseNamedArguments(); std::pair, langutil::SourceLocation> expectIdentifierWithLocation(); + + ASTPointer parseStorageLayoutSpecifier(); ///@} ///@{ diff --git a/test/cmdlineTests/ast_compact_json_storage_layout_specifier/args b/test/cmdlineTests/ast_compact_json_storage_layout_specifier/args new file mode 100644 index 000000000000..76497f217954 --- /dev/null +++ b/test/cmdlineTests/ast_compact_json_storage_layout_specifier/args @@ -0,0 +1 @@ +--ast-compact-json --pretty-json --json-indent 4 --allow-paths . diff --git a/test/cmdlineTests/ast_compact_json_storage_layout_specifier/input.sol b/test/cmdlineTests/ast_compact_json_storage_layout_specifier/input.sol new file mode 100644 index 000000000000..e6c5250af0ff --- /dev/null +++ b/test/cmdlineTests/ast_compact_json_storage_layout_specifier/input.sol @@ -0,0 +1,4 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity >=0.0; + +contract C layout at 1234 + 4567 {} diff --git a/test/cmdlineTests/ast_compact_json_storage_layout_specifier/output b/test/cmdlineTests/ast_compact_json_storage_layout_specifier/output new file mode 100644 index 000000000000..4fe5fe193be9 --- /dev/null +++ b/test/cmdlineTests/ast_compact_json_storage_layout_specifier/output @@ -0,0 +1,103 @@ +JSON AST (compact format): + + +======= ast_compact_json_storage_layout_specifier/input.sol ======= +{ + "absolutePath": "ast_compact_json_storage_layout_specifier/input.sol", + "exportedSymbols": { + "C": [ + 6 + ] + }, + "id": 7, + "license": "GPL-3.0", + "nodeType": "SourceUnit", + "nodes": [ + { + "id": 1, + "literals": [ + "solidity", + ">=", + "0.0" + ], + "nodeType": "PragmaDirective", + "src": "36:22:0" + }, + { + "abstract": false, + "baseContracts": [], + "canonicalName": "C", + "contractDependencies": [], + "contractKind": "contract", + "fullyImplemented": true, + "id": 6, + "linearizedBaseContracts": [ + 6 + ], + "name": "C", + "nameLocation": "69:1:0", + "nodeType": "ContractDefinition", + "nodes": [], + "scope": 7, + "src": "60:35:0", + "storageLayout": { + "baseSlotExpression": { + "commonType": { + "typeIdentifier": "t_rational_5801_by_1", + "typeString": "int_const 5801" + }, + "id": 4, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "leftExpression": { + "hexValue": "31323334", + "id": 2, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "81:4:0", + "typeDescriptions": { + "typeIdentifier": "t_rational_1234_by_1", + "typeString": "int_const 1234" + }, + "value": "1234" + }, + "nodeType": "BinaryOperation", + "operator": "+", + "rightExpression": { + "hexValue": "34353637", + "id": 3, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "88:4:0", + "typeDescriptions": { + "typeIdentifier": "t_rational_4567_by_1", + "typeString": "int_const 4567" + }, + "value": "4567" + }, + "src": "81:11:0", + "typeDescriptions": { + "typeIdentifier": "t_rational_5801_by_1", + "typeString": "int_const 5801" + } + }, + "id": 5, + "nodeType": "StorageLayoutSpecifier", + "src": "71:21:0" + }, + "usedErrors": [], + "usedEvents": [] + } + ], + "src": "36:60:0" +} diff --git a/test/cmdlineTests/inheritance_repeated_definition_error/args b/test/cmdlineTests/inheritance_repeated_definition_error/args new file mode 100644 index 000000000000..3cf20d57b0b8 --- /dev/null +++ b/test/cmdlineTests/inheritance_repeated_definition_error/args @@ -0,0 +1 @@ +- \ No newline at end of file diff --git a/test/cmdlineTests/inheritance_repeated_definition_error/err b/test/cmdlineTests/inheritance_repeated_definition_error/err new file mode 100644 index 000000000000..aa73b10f2281 --- /dev/null +++ b/test/cmdlineTests/inheritance_repeated_definition_error/err @@ -0,0 +1,10 @@ +Error: More than one inheritance list. + --> :9:20: + | +9 | contract C is A, B is B { + | ^^ +Note: Previous list: + --> :9:15: + | +9 | contract C is A, B is B { + | ^ diff --git a/test/cmdlineTests/inheritance_repeated_definition_error/exit b/test/cmdlineTests/inheritance_repeated_definition_error/exit new file mode 100644 index 000000000000..d00491fd7e5b --- /dev/null +++ b/test/cmdlineTests/inheritance_repeated_definition_error/exit @@ -0,0 +1 @@ +1 diff --git a/test/cmdlineTests/inheritance_repeated_definition_error/stdin b/test/cmdlineTests/inheritance_repeated_definition_error/stdin new file mode 100644 index 000000000000..8babcc4f2691 --- /dev/null +++ b/test/cmdlineTests/inheritance_repeated_definition_error/stdin @@ -0,0 +1,10 @@ +//SPDX-License-Identifier: GPL-3.0 +pragma solidity >=0.0; +contract A { +} + +contract B { +} + +contract C is A, B is B { +} \ No newline at end of file diff --git a/test/cmdlineTests/standard_cli_import_ast_storage_layout_specifier_missing_expression/args b/test/cmdlineTests/standard_cli_import_ast_storage_layout_specifier_missing_expression/args new file mode 100644 index 000000000000..f0b85640bd48 --- /dev/null +++ b/test/cmdlineTests/standard_cli_import_ast_storage_layout_specifier_missing_expression/args @@ -0,0 +1 @@ +--import-ast - \ No newline at end of file diff --git a/test/cmdlineTests/standard_cli_import_ast_storage_layout_specifier_missing_expression/err b/test/cmdlineTests/standard_cli_import_ast_storage_layout_specifier_missing_expression/err new file mode 100644 index 000000000000..bdb03116e486 --- /dev/null +++ b/test/cmdlineTests/standard_cli_import_ast_storage_layout_specifier_missing_expression/err @@ -0,0 +1 @@ +Error: Failed to import AST: Expected field "baseSlotExpression" is missing. diff --git a/test/cmdlineTests/standard_cli_import_ast_storage_layout_specifier_missing_expression/exit b/test/cmdlineTests/standard_cli_import_ast_storage_layout_specifier_missing_expression/exit new file mode 100644 index 000000000000..d00491fd7e5b --- /dev/null +++ b/test/cmdlineTests/standard_cli_import_ast_storage_layout_specifier_missing_expression/exit @@ -0,0 +1 @@ +1 diff --git a/test/cmdlineTests/standard_cli_import_ast_storage_layout_specifier_missing_expression/stdin b/test/cmdlineTests/standard_cli_import_ast_storage_layout_specifier_missing_expression/stdin new file mode 100644 index 000000000000..88bd25df1283 --- /dev/null +++ b/test/cmdlineTests/standard_cli_import_ast_storage_layout_specifier_missing_expression/stdin @@ -0,0 +1,62 @@ +{ + "language": "SolidityAST", + "sources": { + "A": { + "AST": { + "absolutePath": "A", + "exportedSymbols": { + "C": [ + 4 + ] + }, + "id": 5, + "license": "GPL-3.0", + "nodeType": "SourceUnit", + "nodes": [ + { + "id": 1, + "literals": [ + "solidity", + ">=", + "0.0" + ], + "nodeType": "PragmaDirective", + "src": "36:22:0" + }, + { + "abstract": false, + "baseContracts": [], + "canonicalName": "C", + "contractDependencies": [], + "contractKind": "contract", + "fullyImplemented": true, + "id": 4, + "linearizedBaseContracts": [ + 4 + ], + "name": "C", + "nameLocation": "69:1:0", + "nodeType": "ContractDefinition", + "nodes": [], + "scope": 5, + "src": "60:28:0", + "storageLayout": { + "id": 3, + "nodeType": "StorageLayoutSpecifier", + "src": "71:16:0" + }, + "usedErrors": [], + "usedEvents": [] + } + ], + "src": "36:53:0" + }, + "id": 0 + } + }, + "settings": { + "outputSelection": { + "*": { "*": [] } + } + } +} \ No newline at end of file diff --git a/test/cmdlineTests/storage_layout_specifier_codegen_error/args b/test/cmdlineTests/storage_layout_specifier_codegen_error/args new file mode 100644 index 000000000000..ccc12f642d1c --- /dev/null +++ b/test/cmdlineTests/storage_layout_specifier_codegen_error/args @@ -0,0 +1 @@ +--asm - \ No newline at end of file diff --git a/test/cmdlineTests/storage_layout_specifier_codegen_error/err b/test/cmdlineTests/storage_layout_specifier_codegen_error/err new file mode 100644 index 000000000000..d1012053f398 --- /dev/null +++ b/test/cmdlineTests/storage_layout_specifier_codegen_error/err @@ -0,0 +1,5 @@ +Error: Code generation is not supported for contracts with specified storage layout base. + --> :4:1: + | +4 | contract C layout at 42 {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/test/cmdlineTests/storage_layout_specifier_codegen_error/exit b/test/cmdlineTests/storage_layout_specifier_codegen_error/exit new file mode 100644 index 000000000000..d00491fd7e5b --- /dev/null +++ b/test/cmdlineTests/storage_layout_specifier_codegen_error/exit @@ -0,0 +1 @@ +1 diff --git a/test/cmdlineTests/storage_layout_specifier_codegen_error/stdin b/test/cmdlineTests/storage_layout_specifier_codegen_error/stdin new file mode 100644 index 000000000000..87066c4d4050 --- /dev/null +++ b/test/cmdlineTests/storage_layout_specifier_codegen_error/stdin @@ -0,0 +1,4 @@ +//SPDX-License-Identifier: GPL-3.0 +pragma solidity >=0.0; + +contract C layout at 42 {} \ No newline at end of file diff --git a/test/cmdlineTests/storage_layout_specifier_ir_codegen_error/args b/test/cmdlineTests/storage_layout_specifier_ir_codegen_error/args new file mode 100644 index 000000000000..a84e2a2576ff --- /dev/null +++ b/test/cmdlineTests/storage_layout_specifier_ir_codegen_error/args @@ -0,0 +1 @@ +--ir --asm - \ No newline at end of file diff --git a/test/cmdlineTests/storage_layout_specifier_ir_codegen_error/err b/test/cmdlineTests/storage_layout_specifier_ir_codegen_error/err new file mode 100644 index 000000000000..d1012053f398 --- /dev/null +++ b/test/cmdlineTests/storage_layout_specifier_ir_codegen_error/err @@ -0,0 +1,5 @@ +Error: Code generation is not supported for contracts with specified storage layout base. + --> :4:1: + | +4 | contract C layout at 42 {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/test/cmdlineTests/storage_layout_specifier_ir_codegen_error/exit b/test/cmdlineTests/storage_layout_specifier_ir_codegen_error/exit new file mode 100644 index 000000000000..d00491fd7e5b --- /dev/null +++ b/test/cmdlineTests/storage_layout_specifier_ir_codegen_error/exit @@ -0,0 +1 @@ +1 diff --git a/test/cmdlineTests/storage_layout_specifier_ir_codegen_error/stdin b/test/cmdlineTests/storage_layout_specifier_ir_codegen_error/stdin new file mode 100644 index 000000000000..87066c4d4050 --- /dev/null +++ b/test/cmdlineTests/storage_layout_specifier_ir_codegen_error/stdin @@ -0,0 +1,4 @@ +//SPDX-License-Identifier: GPL-3.0 +pragma solidity >=0.0; + +contract C layout at 42 {} \ No newline at end of file diff --git a/test/cmdlineTests/storage_layout_specifier_repeated_definition_error/args b/test/cmdlineTests/storage_layout_specifier_repeated_definition_error/args new file mode 100644 index 000000000000..3cf20d57b0b8 --- /dev/null +++ b/test/cmdlineTests/storage_layout_specifier_repeated_definition_error/args @@ -0,0 +1 @@ +- \ No newline at end of file diff --git a/test/cmdlineTests/storage_layout_specifier_repeated_definition_error/err b/test/cmdlineTests/storage_layout_specifier_repeated_definition_error/err new file mode 100644 index 000000000000..983a9b92cd9d --- /dev/null +++ b/test/cmdlineTests/storage_layout_specifier_repeated_definition_error/err @@ -0,0 +1,10 @@ +Error: More than one storage layout definition. + --> :5:34: + | +5 | contract C layout at 0x1234 is A layout at 0xABCD { + | ^^^^^^ +Note: Previous definition: + --> :5:12: + | +5 | contract C layout at 0x1234 is A layout at 0xABCD { + | ^^^^^^^^^^^^^^^^ diff --git a/test/cmdlineTests/storage_layout_specifier_repeated_definition_error/exit b/test/cmdlineTests/storage_layout_specifier_repeated_definition_error/exit new file mode 100644 index 000000000000..d00491fd7e5b --- /dev/null +++ b/test/cmdlineTests/storage_layout_specifier_repeated_definition_error/exit @@ -0,0 +1 @@ +1 diff --git a/test/cmdlineTests/storage_layout_specifier_repeated_definition_error/stdin b/test/cmdlineTests/storage_layout_specifier_repeated_definition_error/stdin new file mode 100644 index 000000000000..fc2ea9c9bad1 --- /dev/null +++ b/test/cmdlineTests/storage_layout_specifier_repeated_definition_error/stdin @@ -0,0 +1,6 @@ +//SPDX-License-Identifier: GPL-3.0 +pragma solidity >=0.0; +contract A { +} +contract C layout at 0x1234 is A layout at 0xABCD { +} \ No newline at end of file diff --git a/test/cmdlineTests/storage_layout_specifier_storage_layout_output_error/args b/test/cmdlineTests/storage_layout_specifier_storage_layout_output_error/args new file mode 100644 index 000000000000..93090d6aabb9 --- /dev/null +++ b/test/cmdlineTests/storage_layout_specifier_storage_layout_output_error/args @@ -0,0 +1 @@ +--storage-layout - \ No newline at end of file diff --git a/test/cmdlineTests/storage_layout_specifier_storage_layout_output_error/err b/test/cmdlineTests/storage_layout_specifier_storage_layout_output_error/err new file mode 100644 index 000000000000..58e52d14aa9a --- /dev/null +++ b/test/cmdlineTests/storage_layout_specifier_storage_layout_output_error/err @@ -0,0 +1 @@ +Error: Storage layout not supported for contract with specified layout base. diff --git a/test/cmdlineTests/storage_layout_specifier_storage_layout_output_error/exit b/test/cmdlineTests/storage_layout_specifier_storage_layout_output_error/exit new file mode 100644 index 000000000000..d00491fd7e5b --- /dev/null +++ b/test/cmdlineTests/storage_layout_specifier_storage_layout_output_error/exit @@ -0,0 +1 @@ +1 diff --git a/test/cmdlineTests/storage_layout_specifier_storage_layout_output_error/output b/test/cmdlineTests/storage_layout_specifier_storage_layout_output_error/output new file mode 100644 index 000000000000..c90881588636 --- /dev/null +++ b/test/cmdlineTests/storage_layout_specifier_storage_layout_output_error/output @@ -0,0 +1,2 @@ + +======= :C ======= diff --git a/test/cmdlineTests/storage_layout_specifier_storage_layout_output_error/stdin b/test/cmdlineTests/storage_layout_specifier_storage_layout_output_error/stdin new file mode 100644 index 000000000000..87066c4d4050 --- /dev/null +++ b/test/cmdlineTests/storage_layout_specifier_storage_layout_output_error/stdin @@ -0,0 +1,4 @@ +//SPDX-License-Identifier: GPL-3.0 +pragma solidity >=0.0; + +contract C layout at 42 {} \ No newline at end of file diff --git a/test/libsolidity/ASTJSON/storage_layout_specifier.json b/test/libsolidity/ASTJSON/storage_layout_specifier.json new file mode 100644 index 000000000000..5ffa1abe3f74 --- /dev/null +++ b/test/libsolidity/ASTJSON/storage_layout_specifier.json @@ -0,0 +1,88 @@ +{ + "absolutePath": "a", + "exportedSymbols": { + "C": [ + 5 + ] + }, + "id": 6, + "nodeType": "SourceUnit", + "nodes": [ + { + "abstract": false, + "baseContracts": [], + "canonicalName": "C", + "contractDependencies": [], + "contractKind": "contract", + "fullyImplemented": true, + "id": 5, + "linearizedBaseContracts": [ + 5 + ], + "name": "C", + "nameLocation": "9:1:1", + "nodeType": "ContractDefinition", + "nodes": [], + "scope": 6, + "src": "0:35:1", + "storageLayout": { + "baseSlotExpression": { + "commonType": { + "typeIdentifier": "t_rational_5801_by_1", + "typeString": "int_const 5801" + }, + "id": 3, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "leftExpression": { + "hexValue": "31323334", + "id": 1, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "21:4:1", + "typeDescriptions": { + "typeIdentifier": "t_rational_1234_by_1", + "typeString": "int_const 1234" + }, + "value": "1234" + }, + "nodeType": "BinaryOperation", + "operator": "+", + "rightExpression": { + "hexValue": "34353637", + "id": 2, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "28:4:1", + "typeDescriptions": { + "typeIdentifier": "t_rational_4567_by_1", + "typeString": "int_const 4567" + }, + "value": "4567" + }, + "src": "21:11:1", + "typeDescriptions": { + "typeIdentifier": "t_rational_5801_by_1", + "typeString": "int_const 5801" + } + }, + "id": 4, + "nodeType": "StorageLayoutSpecifier", + "src": "11:21:1" + }, + "usedErrors": [], + "usedEvents": [] + } + ], + "src": "0:36:1" +} diff --git a/test/libsolidity/ASTJSON/storage_layout_specifier.sol b/test/libsolidity/ASTJSON/storage_layout_specifier.sol new file mode 100644 index 000000000000..1031f2db092c --- /dev/null +++ b/test/libsolidity/ASTJSON/storage_layout_specifier.sol @@ -0,0 +1,3 @@ +contract C layout at 1234 + 4567 {} + +// ---- \ No newline at end of file diff --git a/test/libsolidity/syntaxTests/functionCalls/empty_call_options.sol b/test/libsolidity/syntaxTests/functionCalls/empty_call_options.sol new file mode 100644 index 000000000000..6a14c1198c84 --- /dev/null +++ b/test/libsolidity/syntaxTests/functionCalls/empty_call_options.sol @@ -0,0 +1,8 @@ +contract C { + function f() external payable returns (uint) { return 1; } + function g() public { + this.f{}(); + } +} +// ---- +// ParserError 2314: (116-117): Expected ';' but got '{' diff --git a/test/libsolidity/syntaxTests/inheritance/duplicated_inheritance_definition.sol b/test/libsolidity/syntaxTests/inheritance/duplicated_inheritance_definition.sol new file mode 100644 index 000000000000..1701f7723610 --- /dev/null +++ b/test/libsolidity/syntaxTests/inheritance/duplicated_inheritance_definition.sol @@ -0,0 +1,5 @@ +contract A {} +contract B {} +contract C is A, B is B{ } +// ---- +// ParserError 6668: (47-49): More than one inheritance list. diff --git a/test/libsolidity/syntaxTests/inheritance/repeated_inheritance_definition.sol b/test/libsolidity/syntaxTests/inheritance/repeated_inheritance_definition.sol new file mode 100644 index 000000000000..87af62c6753d --- /dev/null +++ b/test/libsolidity/syntaxTests/inheritance/repeated_inheritance_definition.sol @@ -0,0 +1,7 @@ +contract A {} +contract B {} +contract C is A is B is B is A{ } +// ---- +// ParserError 6668: (44-46): More than one inheritance list. +// ParserError 6668: (49-51): More than one inheritance list. +// ParserError 6668: (54-56): More than one inheritance list. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/abstract_contract.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/abstract_contract.sol new file mode 100644 index 000000000000..f362a5d897c5 --- /dev/null +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/abstract_contract.sol @@ -0,0 +1,4 @@ +abstract contract C layout at 42 { } +// ==== +// stopAfter: parsing +// ---- diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/at_before_layout.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/at_before_layout.sol new file mode 100644 index 000000000000..fc6b53c364f5 --- /dev/null +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/at_before_layout.sol @@ -0,0 +1,3 @@ +contract C at layout 0x1234ABC { } +// ---- +// ParserError 2314: (11-13): Expected '{' but got identifier diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/contract_named_at.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/contract_named_at.sol new file mode 100644 index 000000000000..710703520ba7 --- /dev/null +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/contract_named_at.sol @@ -0,0 +1,4 @@ +contract at layout at 0x1234ABC { } +// ==== +// stopAfter: parsing +// ---- diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/contract_named_layout.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/contract_named_layout.sol new file mode 100644 index 000000000000..9b7b1fc0e2cc --- /dev/null +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/contract_named_layout.sol @@ -0,0 +1,4 @@ +contract layout layout at 0x1234ABC { } +// ==== +// stopAfter: parsing +// ---- diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/contract_with_members_named_layout_and_at.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/contract_with_members_named_layout_and_at.sol new file mode 100644 index 000000000000..5daf8c3c47b4 --- /dev/null +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/contract_with_members_named_layout_and_at.sol @@ -0,0 +1,7 @@ +contract C layout at 0x1234 { + uint layout; + function at() public pure { } +} +// ==== +// stopAfter: parsing +// ---- diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/duplicated_layout_definition.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/duplicated_layout_definition.sol new file mode 100644 index 000000000000..4781b87fabe0 --- /dev/null +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/duplicated_layout_definition.sol @@ -0,0 +1,3 @@ +contract C layout at 0x1234 is A, B layout at 0xABC { } +// ---- +// ParserError 8714: (36-42): More than one storage layout definition. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/duplicated_layout_keyword.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/duplicated_layout_keyword.sol new file mode 100644 index 000000000000..416ca0f64670 --- /dev/null +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/duplicated_layout_keyword.sol @@ -0,0 +1,4 @@ +contract C layout layout at 0x1234ABC { } +// ---- +// ParserError 1994: (18-24): Expected 'at' but got identifier +// ParserError 2314: (28-37): Expected '{' but got 'Number' diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/function_declaration_layout_specified.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/function_declaration_layout_specified.sol new file mode 100644 index 000000000000..7f433dabb253 --- /dev/null +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/function_declaration_layout_specified.sol @@ -0,0 +1,5 @@ +contract C { + function f() public pure layout at 32 { } +} +// ---- +// ParserError 2314: (52-54): Expected '{' but got 'Number' diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/function_declaration_layout_with_no_expression.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/function_declaration_layout_with_no_expression.sol new file mode 100644 index 000000000000..c28596af7d3c --- /dev/null +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/function_declaration_layout_with_no_expression.sol @@ -0,0 +1,6 @@ +contract C { + function f() public pure layout at { } +} +// ==== +// stopAfter: parsing +// ---- diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/interface.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/interface.sol new file mode 100644 index 000000000000..2c853e837cfe --- /dev/null +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/interface.sol @@ -0,0 +1,3 @@ +interface I layout at 42 { } +// ---- +// ParserError 2314: (12-18): Expected '{' but got identifier diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specification_binary_expression.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specification_binary_expression.sol new file mode 100644 index 000000000000..2623fcaa7d83 --- /dev/null +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specification_binary_expression.sol @@ -0,0 +1,4 @@ +contract C layout at 0xffff * (0x123 + 0xABC) { } +// ==== +// stopAfter: parsing +// ---- diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specification_by_function.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specification_by_function.sol new file mode 100644 index 000000000000..3d256c9b1af1 --- /dev/null +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specification_by_function.sol @@ -0,0 +1,7 @@ +function f() pure returns (uint256) { + return 128; +} +contract C layout at f() { } +// ==== +// stopAfter: parsing +// ---- diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specification_constant_in_expression.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specification_constant_in_expression.sol new file mode 100644 index 000000000000..3b034da9ef9d --- /dev/null +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specification_constant_in_expression.sol @@ -0,0 +1,5 @@ +uint constant X = 42; +contract C layout at 0xffff * (50 - X) { } +// ==== +// stopAfter: parsing +// ---- diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specification_no_expression.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specification_no_expression.sol new file mode 100644 index 000000000000..5123678b6d8a --- /dev/null +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specification_no_expression.sol @@ -0,0 +1,3 @@ +contract C layout at { } +// ---- +// ParserError 6933: (21-22): Expected primary expression. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_empty_braces.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_empty_braces.sol new file mode 100644 index 000000000000..96a65ff9844a --- /dev/null +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_empty_braces.sol @@ -0,0 +1,3 @@ +contract C layout at { } { } +// ---- +// ParserError 6933: (21-22): Expected primary expression. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_function_empty_call_options.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_function_empty_call_options.sol new file mode 100644 index 000000000000..e0b1f4e5cb61 --- /dev/null +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_function_empty_call_options.sol @@ -0,0 +1,6 @@ +contract A { + function f() external pure returns (uint) {} +} +contract C is A layout at this.f{}() {} +// ---- +// ParserError 7858: (98-99): Expected pragma, import directive or contract/interface/library/struct/enum/constant/function/error definition. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_function_with_call_options.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_function_with_call_options.sol new file mode 100644 index 000000000000..4bc00778cd2f --- /dev/null +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_function_with_call_options.sol @@ -0,0 +1,7 @@ +contract A { + function f() external pure returns (uint) {} +} +contract C is A layout at this.f{value:123}() {} +// ==== +// stopAfter: parsing +// ---- diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_statement_without_at.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_statement_without_at.sol new file mode 100644 index 000000000000..b60654629fa4 --- /dev/null +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_statement_without_at.sol @@ -0,0 +1,4 @@ +contract C layout { } +// ---- +// ParserError 1994: (18-19): Expected 'at' but got '{' +// ParserError 6933: (20-21): Expected primary expression. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_with_inheritance.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_with_inheritance.sol new file mode 100644 index 000000000000..198751482e44 --- /dev/null +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_with_inheritance.sol @@ -0,0 +1,7 @@ +contract A { } +contract B { } +contract C is A, B layout at 0x1234 { } +contract D layout at 0xABCD is A, B { } +// ==== +// stopAfter: parsing +// ---- diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/library.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/library.sol new file mode 100644 index 000000000000..2848a7c7ef1d --- /dev/null +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/library.sol @@ -0,0 +1,3 @@ +library L layout at 42 { } +// ---- +// ParserError 2314: (10-16): Expected '{' but got identifier diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/multi_token_expression.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/multi_token_expression.sol new file mode 100644 index 000000000000..0ecaf0da24e0 --- /dev/null +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/multi_token_expression.sol @@ -0,0 +1,5 @@ +contract C layout at 5 minutes { } +contract D layout at 2 gwei { } +// ==== +// stopAfter: parsing +// ---- diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/natspec.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/natspec.sol new file mode 100644 index 000000000000..d1712a1ff10a --- /dev/null +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/natspec.sol @@ -0,0 +1,10 @@ +contract C layout at + /** + @notice function f should return the value of the base slot for the contract's storage layout + @dev the value returned by f should be in the range of uint256 + */ + f() +{ } +// ==== +// stopAfter: parsing +// ---- \ No newline at end of file diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/repeated_layout_definition.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/repeated_layout_definition.sol new file mode 100644 index 000000000000..7176940306fa --- /dev/null +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/repeated_layout_definition.sol @@ -0,0 +1,5 @@ +contract C layout at 0x1234 layout at 0xABC layout at 0x4321 layout at 0xCBA { } +// ---- +// ParserError 8714: (28-34): More than one storage layout definition. +// ParserError 8714: (44-50): More than one storage layout definition. +// ParserError 8714: (61-67): More than one storage layout definition. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/simple_layout.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/simple_layout.sol new file mode 100644 index 000000000000..03a2f8a07e0e --- /dev/null +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/simple_layout.sol @@ -0,0 +1,6 @@ +contract A layout at 0x1234 {} +contract B layout at 1024 {} +contract C layout at "C" {} +// ==== +// stopAfter: parsing +// ---- diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/state_variable_layout_specifier.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/state_variable_layout_specifier.sol new file mode 100644 index 000000000000..0f7279fcd267 --- /dev/null +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/state_variable_layout_specifier.sol @@ -0,0 +1,5 @@ +contract C { + uint x layout at 0xF; +} +// ---- +// ParserError 2314: (24-30): Expected ';' but got identifier diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/struct_layout_specifier.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/struct_layout_specifier.sol new file mode 100644 index 000000000000..fa05d1276375 --- /dev/null +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/struct_layout_specifier.sol @@ -0,0 +1,3 @@ +struct S layout at 23 { } +// ---- +// ParserError 2314: (9-15): Expected '{' but got identifier From de3a7b509ed7c446fe4de055410fdd230b22a389 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Wed, 19 Feb 2025 10:23:50 +0100 Subject: [PATCH 0823/1022] finds default vendored dependencies via find_package if requested --- CMakeLists.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 729da0d72e23..d95b7213ebe6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -61,6 +61,11 @@ if (NOT IGNORE_VENDORED_DEPENDENCIES) include(fmtlib) include(nlohmann-json) include(range-v3) +else () + message(WARNING "-- Ignoring vendored dependencies. Will use installed versions if found. Versions may differ from the ones the compiler was tested with. Make sure to run the test suite and thoroughly test the resulting binaries before using them in production.") + find_package(fmt REQUIRED) + find_package(nlohmann_json REQUIRED) + find_package(range-v3 REQUIRED) endif() find_package(Threads) From 04cfcf75c2008288a50ee4e9bf426cc6eda0e816 Mon Sep 17 00:00:00 2001 From: Matheus Aguiar Date: Tue, 3 Dec 2024 11:58:46 -0300 Subject: [PATCH 0824/1022] Tweak existing tests --- .../syntaxTests/storageLayoutSpecifier/abstract_contract.sol | 3 +-- .../syntaxTests/storageLayoutSpecifier/contract_named_at.sol | 3 +-- .../storageLayoutSpecifier/contract_named_layout.sol | 3 +-- .../contract_with_members_named_layout_and_at.sol | 3 +-- .../layout_specification_binary_expression.sol | 3 +-- .../layout_specification_by_function.sol | 3 +-- .../layout_specification_constant_in_expression.sol | 3 +-- .../layout_specified_by_function_with_call_options.sol | 5 ++--- .../storageLayoutSpecifier/layout_with_inheritance.sol | 3 +-- .../storageLayoutSpecifier/multi_token_expression.sol | 3 +-- .../syntaxTests/storageLayoutSpecifier/simple_layout.sol | 5 ++--- ...layout_specifier.sol => struct_with_layout_specifier.sol} | 0 12 files changed, 13 insertions(+), 24 deletions(-) rename test/libsolidity/syntaxTests/storageLayoutSpecifier/{struct_layout_specifier.sol => struct_with_layout_specifier.sol} (100%) diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/abstract_contract.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/abstract_contract.sol index f362a5d897c5..dc7a7ce4863e 100644 --- a/test/libsolidity/syntaxTests/storageLayoutSpecifier/abstract_contract.sol +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/abstract_contract.sol @@ -1,4 +1,3 @@ abstract contract C layout at 42 { } -// ==== -// stopAfter: parsing // ---- +// UnimplementedFeatureError 1834: (0-36): Code generation is not supported for contracts with specified storage layout base. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/contract_named_at.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/contract_named_at.sol index 710703520ba7..bbb928cb3715 100644 --- a/test/libsolidity/syntaxTests/storageLayoutSpecifier/contract_named_at.sol +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/contract_named_at.sol @@ -1,4 +1,3 @@ contract at layout at 0x1234ABC { } -// ==== -// stopAfter: parsing // ---- +// UnimplementedFeatureError 1834: (0-35): Code generation is not supported for contracts with specified storage layout base. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/contract_named_layout.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/contract_named_layout.sol index 9b7b1fc0e2cc..5c755d610ccf 100644 --- a/test/libsolidity/syntaxTests/storageLayoutSpecifier/contract_named_layout.sol +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/contract_named_layout.sol @@ -1,4 +1,3 @@ contract layout layout at 0x1234ABC { } -// ==== -// stopAfter: parsing // ---- +// UnimplementedFeatureError 1834: (0-39): Code generation is not supported for contracts with specified storage layout base. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/contract_with_members_named_layout_and_at.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/contract_with_members_named_layout_and_at.sol index 5daf8c3c47b4..9e15ef564985 100644 --- a/test/libsolidity/syntaxTests/storageLayoutSpecifier/contract_with_members_named_layout_and_at.sol +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/contract_with_members_named_layout_and_at.sol @@ -2,6 +2,5 @@ contract C layout at 0x1234 { uint layout; function at() public pure { } } -// ==== -// stopAfter: parsing // ---- +// UnimplementedFeatureError 1834: (0-82): Code generation is not supported for contracts with specified storage layout base. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specification_binary_expression.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specification_binary_expression.sol index 2623fcaa7d83..609178fd0e02 100644 --- a/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specification_binary_expression.sol +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specification_binary_expression.sol @@ -1,4 +1,3 @@ contract C layout at 0xffff * (0x123 + 0xABC) { } -// ==== -// stopAfter: parsing // ---- +// UnimplementedFeatureError 1834: (0-49): Code generation is not supported for contracts with specified storage layout base. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specification_by_function.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specification_by_function.sol index 3d256c9b1af1..e9cd65ffe400 100644 --- a/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specification_by_function.sol +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specification_by_function.sol @@ -2,6 +2,5 @@ function f() pure returns (uint256) { return 128; } contract C layout at f() { } -// ==== -// stopAfter: parsing // ---- +// UnimplementedFeatureError 1834: (56-84): Code generation is not supported for contracts with specified storage layout base. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specification_constant_in_expression.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specification_constant_in_expression.sol index 3b034da9ef9d..471a5a63c225 100644 --- a/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specification_constant_in_expression.sol +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specification_constant_in_expression.sol @@ -1,5 +1,4 @@ uint constant X = 42; contract C layout at 0xffff * (50 - X) { } -// ==== -// stopAfter: parsing // ---- +// UnimplementedFeatureError 1834: (22-64): Code generation is not supported for contracts with specified storage layout base. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_function_with_call_options.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_function_with_call_options.sol index 4bc00778cd2f..aca167f6b95d 100644 --- a/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_function_with_call_options.sol +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_function_with_call_options.sol @@ -1,7 +1,6 @@ contract A { - function f() external pure returns (uint) {} + function f() external payable returns (uint) {} } contract C is A layout at this.f{value:123}() {} -// ==== -// stopAfter: parsing // ---- +// UnimplementedFeatureError 1834: (67-115): Code generation is not supported for contracts with specified storage layout base. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_with_inheritance.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_with_inheritance.sol index 198751482e44..7c8d483e272b 100644 --- a/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_with_inheritance.sol +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_with_inheritance.sol @@ -2,6 +2,5 @@ contract A { } contract B { } contract C is A, B layout at 0x1234 { } contract D layout at 0xABCD is A, B { } -// ==== -// stopAfter: parsing // ---- +// UnimplementedFeatureError 1834: (30-69): Code generation is not supported for contracts with specified storage layout base. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/multi_token_expression.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/multi_token_expression.sol index 0ecaf0da24e0..8e048b29e992 100644 --- a/test/libsolidity/syntaxTests/storageLayoutSpecifier/multi_token_expression.sol +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/multi_token_expression.sol @@ -1,5 +1,4 @@ contract C layout at 5 minutes { } contract D layout at 2 gwei { } -// ==== -// stopAfter: parsing // ---- +// UnimplementedFeatureError 1834: (0-34): Code generation is not supported for contracts with specified storage layout base. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/simple_layout.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/simple_layout.sol index 03a2f8a07e0e..116a6c5e4a3b 100644 --- a/test/libsolidity/syntaxTests/storageLayoutSpecifier/simple_layout.sol +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/simple_layout.sol @@ -1,6 +1,5 @@ contract A layout at 0x1234 {} contract B layout at 1024 {} -contract C layout at "C" {} -// ==== -// stopAfter: parsing +contract C layout at 0 {} // ---- +// UnimplementedFeatureError 1834: (0-30): Code generation is not supported for contracts with specified storage layout base. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/struct_layout_specifier.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/struct_with_layout_specifier.sol similarity index 100% rename from test/libsolidity/syntaxTests/storageLayoutSpecifier/struct_layout_specifier.sol rename to test/libsolidity/syntaxTests/storageLayoutSpecifier/struct_with_layout_specifier.sol From ef61400474f8228a49573b33b17cb6ec3cb78fb9 Mon Sep 17 00:00:00 2001 From: Matheus Aguiar Date: Tue, 3 Dec 2024 11:58:46 -0300 Subject: [PATCH 0825/1022] Add tests --- .../args | 1 + .../stdin | 6 +++++ .../storage_layout_specifier_no_doc.sol | 23 +++++++++++++++++++ .../storageLayoutSpecifier/abi_decode.sol | 3 +++ .../storageLayoutSpecifier/address.sol | 3 +++ .../address_non_constant.sol | 6 +++++ .../storageLayoutSpecifier/array_literal.sol | 3 +++ .../storageLayoutSpecifier/assignment.sol | 4 ++++ .../bitwise_negation_after_cast.sol | 3 +++ .../storageLayoutSpecifier/boolean.sol | 3 +++ .../builtin_functions.sol | 18 +++++++++++++++ .../bytes_length_member.sol | 3 +++ .../constant_divided_by_its_negation.sol | 4 ++++ .../constant_divided_by_zero.sol | 4 ++++ .../constant_from_base_contract.sol | 7 ++++++ .../storageLayoutSpecifier/delete.sol | 4 ++++ .../division_by_zero.sol | 3 +++ .../storageLayoutSpecifier/enum.sol | 5 ++++ .../function_address.sol | 7 ++++++ .../function_defined_in_other_contract.sol | 7 ++++++ .../function_selector.sol | 6 +++++ .../storageLayoutSpecifier/hex_address.sol | 3 +++ .../storageLayoutSpecifier/hex_string.sol | 3 +++ .../hex_string_cast.sol | 3 +++ .../increment_operator.sol | 4 ++++ .../inheriting_from_abstract_contract.sol | 5 ++++ .../inheriting_from_interface.sol | 5 ++++ .../inheriting_from_itself.sol | 3 +++ .../intermediate_operation_out_of_range.sol | 4 ++++ ...already_specified_in_ancestor_contract.sol | 7 ++++++ .../layout_bitwise_negation_literal.sol | 3 +++ .../layout_fractional_number.sol | 7 ++++++ .../layout_specification_bytes.sol | 4 ++++ .../layout_specification_max_value.sol | 3 +++ .../layout_specification_overflow_value.sol | 4 ++++ .../layout_specification_underflow_value.sol | 4 ++++ ...specified_by_attached_library_function.sol | 12 ++++++++++ .../layout_specified_by_bytes_concat.sol | 3 +++ .../layout_specified_by_error.sol | 4 ++++ .../layout_specified_by_event.sol | 4 ++++ ...ayout_specified_by_expression_not_pure.sol | 5 ++++ ...t_specified_by_first_ancestor_contract.sol | 6 +++++ .../layout_specified_by_interface_id.sol | 5 ++++ .../layout_specified_by_kecak256.sol | 3 +++ ...ut_specified_by_last_ancestor_contract.sol | 6 +++++ .../layout_specified_by_module.sol | 9 ++++++++ .../layout_specified_by_other_contract.sol | 4 ++++ .../layout_specified_by_type.sol | 3 +++ .../storageLayoutSpecifier/literal_cast.sol | 3 +++ .../literal_with_underscore.sol | 5 ++++ .../magic_variables.sol | 7 ++++++ .../negative_number.sol | 3 +++ .../storageLayoutSpecifier/precompiles.sol | 4 ++++ .../rational_number_zero_fractional_part.sol | 4 ++++ .../same_ancestor_two_contracts.sol | 5 ++++ .../state_variable_from_base_contract.sol | 7 ++++++ ...ate_variable_getter_from_base_contract.sol | 7 ++++++ .../storageLayoutSpecifier/string.sol | 3 +++ .../struct_defined_in_other_contract.sol | 11 +++++++++ .../ternary_operator.sol | 4 ++++ .../storageLayoutSpecifier/tuple.sol | 3 +++ .../storageLayoutSpecifier/type_uint_max.sol | 3 +++ .../user_defined_operators.sol | 12 ++++++++++ .../user_defined_value_type.sol | 5 ++++ .../user_defined_value_type_unwrap.sol | 5 ++++ .../user_defined_value_type_wrap.sol | 4 ++++ .../value_from_array_literal.sol | 4 ++++ .../value_from_bytes.sol | 4 ++++ 68 files changed, 352 insertions(+) create mode 100644 test/cmdlineTests/storage_layout_already_defined_in_ancestor/args create mode 100644 test/cmdlineTests/storage_layout_already_defined_in_ancestor/stdin create mode 100644 test/libsolidity/natspecJSON/storage_layout_specifier_no_doc.sol create mode 100644 test/libsolidity/syntaxTests/storageLayoutSpecifier/abi_decode.sol create mode 100644 test/libsolidity/syntaxTests/storageLayoutSpecifier/address.sol create mode 100644 test/libsolidity/syntaxTests/storageLayoutSpecifier/address_non_constant.sol create mode 100644 test/libsolidity/syntaxTests/storageLayoutSpecifier/array_literal.sol create mode 100644 test/libsolidity/syntaxTests/storageLayoutSpecifier/assignment.sol create mode 100644 test/libsolidity/syntaxTests/storageLayoutSpecifier/bitwise_negation_after_cast.sol create mode 100644 test/libsolidity/syntaxTests/storageLayoutSpecifier/boolean.sol create mode 100644 test/libsolidity/syntaxTests/storageLayoutSpecifier/builtin_functions.sol create mode 100644 test/libsolidity/syntaxTests/storageLayoutSpecifier/bytes_length_member.sol create mode 100644 test/libsolidity/syntaxTests/storageLayoutSpecifier/constant_divided_by_its_negation.sol create mode 100644 test/libsolidity/syntaxTests/storageLayoutSpecifier/constant_divided_by_zero.sol create mode 100644 test/libsolidity/syntaxTests/storageLayoutSpecifier/constant_from_base_contract.sol create mode 100644 test/libsolidity/syntaxTests/storageLayoutSpecifier/delete.sol create mode 100644 test/libsolidity/syntaxTests/storageLayoutSpecifier/division_by_zero.sol create mode 100644 test/libsolidity/syntaxTests/storageLayoutSpecifier/enum.sol create mode 100644 test/libsolidity/syntaxTests/storageLayoutSpecifier/function_address.sol create mode 100644 test/libsolidity/syntaxTests/storageLayoutSpecifier/function_defined_in_other_contract.sol create mode 100644 test/libsolidity/syntaxTests/storageLayoutSpecifier/function_selector.sol create mode 100644 test/libsolidity/syntaxTests/storageLayoutSpecifier/hex_address.sol create mode 100644 test/libsolidity/syntaxTests/storageLayoutSpecifier/hex_string.sol create mode 100644 test/libsolidity/syntaxTests/storageLayoutSpecifier/hex_string_cast.sol create mode 100644 test/libsolidity/syntaxTests/storageLayoutSpecifier/increment_operator.sol create mode 100644 test/libsolidity/syntaxTests/storageLayoutSpecifier/inheriting_from_abstract_contract.sol create mode 100644 test/libsolidity/syntaxTests/storageLayoutSpecifier/inheriting_from_interface.sol create mode 100644 test/libsolidity/syntaxTests/storageLayoutSpecifier/inheriting_from_itself.sol create mode 100644 test/libsolidity/syntaxTests/storageLayoutSpecifier/intermediate_operation_out_of_range.sol create mode 100644 test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_already_specified_in_ancestor_contract.sol create mode 100644 test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_bitwise_negation_literal.sol create mode 100644 test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_fractional_number.sol create mode 100644 test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specification_bytes.sol create mode 100644 test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specification_max_value.sol create mode 100644 test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specification_overflow_value.sol create mode 100644 test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specification_underflow_value.sol create mode 100644 test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_attached_library_function.sol create mode 100644 test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_bytes_concat.sol create mode 100644 test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_error.sol create mode 100644 test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_event.sol create mode 100644 test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_expression_not_pure.sol create mode 100644 test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_first_ancestor_contract.sol create mode 100644 test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_interface_id.sol create mode 100644 test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_kecak256.sol create mode 100644 test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_last_ancestor_contract.sol create mode 100644 test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_module.sol create mode 100644 test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_other_contract.sol create mode 100644 test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_type.sol create mode 100644 test/libsolidity/syntaxTests/storageLayoutSpecifier/literal_cast.sol create mode 100644 test/libsolidity/syntaxTests/storageLayoutSpecifier/literal_with_underscore.sol create mode 100644 test/libsolidity/syntaxTests/storageLayoutSpecifier/magic_variables.sol create mode 100644 test/libsolidity/syntaxTests/storageLayoutSpecifier/negative_number.sol create mode 100644 test/libsolidity/syntaxTests/storageLayoutSpecifier/precompiles.sol create mode 100644 test/libsolidity/syntaxTests/storageLayoutSpecifier/rational_number_zero_fractional_part.sol create mode 100644 test/libsolidity/syntaxTests/storageLayoutSpecifier/same_ancestor_two_contracts.sol create mode 100644 test/libsolidity/syntaxTests/storageLayoutSpecifier/state_variable_from_base_contract.sol create mode 100644 test/libsolidity/syntaxTests/storageLayoutSpecifier/state_variable_getter_from_base_contract.sol create mode 100644 test/libsolidity/syntaxTests/storageLayoutSpecifier/string.sol create mode 100644 test/libsolidity/syntaxTests/storageLayoutSpecifier/struct_defined_in_other_contract.sol create mode 100644 test/libsolidity/syntaxTests/storageLayoutSpecifier/ternary_operator.sol create mode 100644 test/libsolidity/syntaxTests/storageLayoutSpecifier/tuple.sol create mode 100644 test/libsolidity/syntaxTests/storageLayoutSpecifier/type_uint_max.sol create mode 100644 test/libsolidity/syntaxTests/storageLayoutSpecifier/user_defined_operators.sol create mode 100644 test/libsolidity/syntaxTests/storageLayoutSpecifier/user_defined_value_type.sol create mode 100644 test/libsolidity/syntaxTests/storageLayoutSpecifier/user_defined_value_type_unwrap.sol create mode 100644 test/libsolidity/syntaxTests/storageLayoutSpecifier/user_defined_value_type_wrap.sol create mode 100644 test/libsolidity/syntaxTests/storageLayoutSpecifier/value_from_array_literal.sol create mode 100644 test/libsolidity/syntaxTests/storageLayoutSpecifier/value_from_bytes.sol diff --git a/test/cmdlineTests/storage_layout_already_defined_in_ancestor/args b/test/cmdlineTests/storage_layout_already_defined_in_ancestor/args new file mode 100644 index 000000000000..3cf20d57b0b8 --- /dev/null +++ b/test/cmdlineTests/storage_layout_already_defined_in_ancestor/args @@ -0,0 +1 @@ +- \ No newline at end of file diff --git a/test/cmdlineTests/storage_layout_already_defined_in_ancestor/stdin b/test/cmdlineTests/storage_layout_already_defined_in_ancestor/stdin new file mode 100644 index 000000000000..a340f7530003 --- /dev/null +++ b/test/cmdlineTests/storage_layout_already_defined_in_ancestor/stdin @@ -0,0 +1,6 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity *; + +contract A layout at 0x1234 {} +contract B is A {} +contract C layout at 0x1234 is B {} diff --git a/test/libsolidity/natspecJSON/storage_layout_specifier_no_doc.sol b/test/libsolidity/natspecJSON/storage_layout_specifier_no_doc.sol new file mode 100644 index 000000000000..9bb8f4a06e24 --- /dev/null +++ b/test/libsolidity/natspecJSON/storage_layout_specifier_no_doc.sol @@ -0,0 +1,23 @@ +contract C + /// @notice this changes the base slot of the contract storage + layout at + /// @dev the expression must be in range of uint256 + 0x1234 +{ } +// ==== +// stopAfter: analysis +// ---- +// ---- +// :C devdoc +// { +// "kind": "dev", +// "methods": {}, +// "version": 1 +// } +// +// :C userdoc +// { +// "kind": "user", +// "methods": {}, +// "version": 1 +// } diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/abi_decode.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/abi_decode.sol new file mode 100644 index 000000000000..330f461c2d02 --- /dev/null +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/abi_decode.sol @@ -0,0 +1,3 @@ +contract C layout at abi.decode(abi.encode(42), (uint)) {} +// ---- +// UnimplementedFeatureError 1834: (0-58): Code generation is not supported for contracts with specified storage layout base. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/address.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/address.sol new file mode 100644 index 000000000000..5691c0c9051e --- /dev/null +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/address.sol @@ -0,0 +1,3 @@ +contract C layout at address(0x1234) {} +// ---- +// UnimplementedFeatureError 1834: (0-39): Code generation is not supported for contracts with specified storage layout base. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/address_non_constant.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/address_non_constant.sol new file mode 100644 index 000000000000..2d6d0745ac1a --- /dev/null +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/address_non_constant.sol @@ -0,0 +1,6 @@ +contract A {} + +contract C layout at address(new A()) {} +contract D layout at uint160(address(this)) {} +// ---- +// UnimplementedFeatureError 1834: (15-55): Code generation is not supported for contracts with specified storage layout base. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/array_literal.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/array_literal.sol new file mode 100644 index 000000000000..0f9c73b67bc4 --- /dev/null +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/array_literal.sol @@ -0,0 +1,3 @@ +contract C layout at [1, 2, 3] {} +// ---- +// UnimplementedFeatureError 1834: (0-33): Code generation is not supported for contracts with specified storage layout base. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/assignment.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/assignment.sol new file mode 100644 index 000000000000..2849dea65212 --- /dev/null +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/assignment.sol @@ -0,0 +1,4 @@ +contract C layout at 1 = 2 { } +// ---- +// TypeError 4247: (21-22): Expression has to be an lvalue. +// TypeError 7407: (25-26): Type int_const 2 is not implicitly convertible to expected type int_const 1. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/bitwise_negation_after_cast.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/bitwise_negation_after_cast.sol new file mode 100644 index 000000000000..01e34b707ddd --- /dev/null +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/bitwise_negation_after_cast.sol @@ -0,0 +1,3 @@ +contract C layout at ~uint(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) {} +// ---- +// UnimplementedFeatureError 1834: (0-97): Code generation is not supported for contracts with specified storage layout base. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/boolean.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/boolean.sol new file mode 100644 index 000000000000..cb4112f41bc4 --- /dev/null +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/boolean.sol @@ -0,0 +1,3 @@ +contract C layout at true {} +// ---- +// UnimplementedFeatureError 1834: (0-28): Code generation is not supported for contracts with specified storage layout base. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/builtin_functions.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/builtin_functions.sol new file mode 100644 index 000000000000..631b1c60ba52 --- /dev/null +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/builtin_functions.sol @@ -0,0 +1,18 @@ +contract A layout at block.basefee { } +contract B layout at block.chainid { } +contract C layout at block.number { } +contract D layout at uint160(address(block.coinbase)) { } +contract E layout at block.prevrandao { } +contract F layout at uint(blockhash(0)) { } +contract G layout at msg.value { } +contract H layout at msg.sender { } +contract I layout at msg.data { } +contract J layout at tx.gasprice { } +contract K layout at uint160(tx.origin) { } +contract L layout at address(this).balance { } +contract M layout at uint(address(this).codehash) { } + +// ==== +// EVMVersion: >=paris +// ---- +// UnimplementedFeatureError 1834: (0-38): Code generation is not supported for contracts with specified storage layout base. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/bytes_length_member.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/bytes_length_member.sol new file mode 100644 index 000000000000..b2bb64b199d9 --- /dev/null +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/bytes_length_member.sol @@ -0,0 +1,3 @@ +contract C layout at bytes("ABCD").length {} +// ---- +// UnimplementedFeatureError 1834: (0-44): Code generation is not supported for contracts with specified storage layout base. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/constant_divided_by_its_negation.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/constant_divided_by_its_negation.sol new file mode 100644 index 000000000000..9f8acbeb6a36 --- /dev/null +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/constant_divided_by_its_negation.sol @@ -0,0 +1,4 @@ +uint constant N = 100; +contract C layout at N / ~N {} +// ---- +// TypeError 3667: (48-50): Arithmetic error when computing constant value. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/constant_divided_by_zero.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/constant_divided_by_zero.sol new file mode 100644 index 000000000000..f6e3c3805bd2 --- /dev/null +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/constant_divided_by_zero.sol @@ -0,0 +1,4 @@ +uint constant N = 100; +contract C layout at N / 0 {} +// ---- +// TypeError 1211: (44-49): Division by zero. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/constant_from_base_contract.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/constant_from_base_contract.sol new file mode 100644 index 000000000000..1995cf698f96 --- /dev/null +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/constant_from_base_contract.sol @@ -0,0 +1,7 @@ +contract A { + uint constant x = 10; +} + +contract C is A layout at A.x { } +// ---- +// UnimplementedFeatureError 1834: (42-75): Code generation is not supported for contracts with specified storage layout base. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/delete.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/delete.sol new file mode 100644 index 000000000000..b6926b51ff8f --- /dev/null +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/delete.sol @@ -0,0 +1,4 @@ +contract C layout at delete 2 { } +// ---- +// TypeError 4247: (28-29): Expression has to be an lvalue. +// TypeError 9767: (21-29): Built-in unary operator delete cannot be applied to type int_const 2. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/division_by_zero.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/division_by_zero.sol new file mode 100644 index 000000000000..51ddd9d6c4c7 --- /dev/null +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/division_by_zero.sol @@ -0,0 +1,3 @@ +contract A layout at 1 / 0 {} +// ---- +// TypeError 2271: (21-26): Built-in binary operator / cannot be applied to types int_const 1 and int_const 0. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/enum.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/enum.sol new file mode 100644 index 000000000000..c9eba88e5380 --- /dev/null +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/enum.sol @@ -0,0 +1,5 @@ +enum Color {Red, Green, Blue} + +contract C layout at Color.Red {} +// ---- +// UnimplementedFeatureError 1834: (31-64): Code generation is not supported for contracts with specified storage layout base. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/function_address.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/function_address.sol new file mode 100644 index 000000000000..b6d2b99d96a4 --- /dev/null +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/function_address.sol @@ -0,0 +1,7 @@ +contract A { + function f() public pure {} +} + +contract C is A layout at this.f.address {} +// ---- +// UnimplementedFeatureError 1834: (48-91): Code generation is not supported for contracts with specified storage layout base. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/function_defined_in_other_contract.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/function_defined_in_other_contract.sol new file mode 100644 index 000000000000..1b890790346b --- /dev/null +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/function_defined_in_other_contract.sol @@ -0,0 +1,7 @@ +contract A { + function f() external pure {} +} + +contract C layout at A.f { } +// ---- +// UnimplementedFeatureError 1834: (50-78): Code generation is not supported for contracts with specified storage layout base. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/function_selector.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/function_selector.sol new file mode 100644 index 000000000000..e3b873ca7905 --- /dev/null +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/function_selector.sol @@ -0,0 +1,6 @@ +contract A { + function f() public {} +} +contract C is A layout at uint32(this.f.selector) {} +// ---- +// UnimplementedFeatureError 1834: (42-94): Code generation is not supported for contracts with specified storage layout base. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/hex_address.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/hex_address.sol new file mode 100644 index 000000000000..4a6e9401f420 --- /dev/null +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/hex_address.sol @@ -0,0 +1,3 @@ +contract C layout at 0xdCad3a6d3569DF655070DEd06cb7A1b2Ccd1D3AF {} +// ---- +// UnimplementedFeatureError 1834: (0-66): Code generation is not supported for contracts with specified storage layout base. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/hex_string.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/hex_string.sol new file mode 100644 index 000000000000..38d1085a84af --- /dev/null +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/hex_string.sol @@ -0,0 +1,3 @@ +contract C layout at hex"616263" {} +// ---- +// UnimplementedFeatureError 1834: (0-35): Code generation is not supported for contracts with specified storage layout base. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/hex_string_cast.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/hex_string_cast.sol new file mode 100644 index 000000000000..0318625995b5 --- /dev/null +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/hex_string_cast.sol @@ -0,0 +1,3 @@ +contract at layout at uint40(bytes5(hex"0011223344")) { } +// ---- +// UnimplementedFeatureError 1834: (0-57): Code generation is not supported for contracts with specified storage layout base. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/increment_operator.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/increment_operator.sol new file mode 100644 index 000000000000..b5d0b0651c64 --- /dev/null +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/increment_operator.sol @@ -0,0 +1,4 @@ +contract C layout at ++2 { } +// ---- +// TypeError 4247: (23-24): Expression has to be an lvalue. +// TypeError 9767: (21-24): Built-in unary operator ++ cannot be applied to type int_const 2. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/inheriting_from_abstract_contract.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/inheriting_from_abstract_contract.sol new file mode 100644 index 000000000000..850798c937ed --- /dev/null +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/inheriting_from_abstract_contract.sol @@ -0,0 +1,5 @@ +abstract contract A { } + +contract C layout at 42 is A { } +// ---- +// UnimplementedFeatureError 1834: (25-57): Code generation is not supported for contracts with specified storage layout base. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/inheriting_from_interface.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/inheriting_from_interface.sol new file mode 100644 index 000000000000..541dea056c2a --- /dev/null +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/inheriting_from_interface.sol @@ -0,0 +1,5 @@ +interface I { } + +contract C layout at 42 is I { } +// ---- +// UnimplementedFeatureError 1834: (17-49): Code generation is not supported for contracts with specified storage layout base. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/inheriting_from_itself.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/inheriting_from_itself.sol new file mode 100644 index 000000000000..e0e6625abd7d --- /dev/null +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/inheriting_from_itself.sol @@ -0,0 +1,3 @@ +contract C layout at 42 is C { } +// ---- +// TypeError 2449: (27-28): Definition of base has to precede definition of derived contract diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/intermediate_operation_out_of_range.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/intermediate_operation_out_of_range.sol new file mode 100644 index 000000000000..b7bae489fb5f --- /dev/null +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/intermediate_operation_out_of_range.sol @@ -0,0 +1,4 @@ +contract A layout at (2**256 + 1) * 2 - 2**256 - 3 {} +contract B layout at (2**2 - 2**3) * (2**5 - 2**8) {} +// ---- +// UnimplementedFeatureError 1834: (0-54): Code generation is not supported for contracts with specified storage layout base. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_already_specified_in_ancestor_contract.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_already_specified_in_ancestor_contract.sol new file mode 100644 index 000000000000..8ddfdbfc37e1 --- /dev/null +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_already_specified_in_ancestor_contract.sol @@ -0,0 +1,7 @@ +contract A layout at 0x1234 {} + +contract B is A {} + +contract C is B layout at 0xABCD {} +// ---- +// UnimplementedFeatureError 1834: (0-30): Code generation is not supported for contracts with specified storage layout base. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_bitwise_negation_literal.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_bitwise_negation_literal.sol new file mode 100644 index 000000000000..cd74b20dbc78 --- /dev/null +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_bitwise_negation_literal.sol @@ -0,0 +1,3 @@ +contract C layout at ~0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE {} +// ---- +// UnimplementedFeatureError 1834: (0-91): Code generation is not supported for contracts with specified storage layout base. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_fractional_number.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_fractional_number.sol new file mode 100644 index 000000000000..0e24366b10e5 --- /dev/null +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_fractional_number.sol @@ -0,0 +1,7 @@ +contract A layout at 3/2 {} +contract B layout at 4.2 {} +contract C layout at .1 {} +contract D layout at 42e-10 {} +contract E layout at 1_7e-10 {} +// ---- +// UnimplementedFeatureError 1834: (0-27): Code generation is not supported for contracts with specified storage layout base. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specification_bytes.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specification_bytes.sol new file mode 100644 index 000000000000..65923479d283 --- /dev/null +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specification_bytes.sol @@ -0,0 +1,4 @@ +bytes32 constant b = "bytes"; +contract A layout at b[1] {} +// ---- +// UnimplementedFeatureError 1834: (30-58): Code generation is not supported for contracts with specified storage layout base. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specification_max_value.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specification_max_value.sol new file mode 100644 index 000000000000..67954bdce1d8 --- /dev/null +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specification_max_value.sol @@ -0,0 +1,3 @@ +contract C layout at 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF {} +// ---- +// UnimplementedFeatureError 1834: (0-90): Code generation is not supported for contracts with specified storage layout base. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specification_overflow_value.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specification_overflow_value.sol new file mode 100644 index 000000000000..ece4273bbbc4 --- /dev/null +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specification_overflow_value.sol @@ -0,0 +1,4 @@ +contract A layout at 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + 1 {} +contract B layout at 2**256 {} +// ---- +// UnimplementedFeatureError 1834: (0-94): Code generation is not supported for contracts with specified storage layout base. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specification_underflow_value.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specification_underflow_value.sol new file mode 100644 index 000000000000..953d791cc9ec --- /dev/null +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specification_underflow_value.sol @@ -0,0 +1,4 @@ +contract A layout at 0 - 1 {} +contract B layout at 2**8 - 2**16 {} +// ---- +// UnimplementedFeatureError 1834: (0-29): Code generation is not supported for contracts with specified storage layout base. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_attached_library_function.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_attached_library_function.sol new file mode 100644 index 000000000000..b586a271e177 --- /dev/null +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_attached_library_function.sol @@ -0,0 +1,12 @@ +library L { + function f(uint x) public pure returns (uint) { + return x * 2; + } +} + + +contract C layout at 2.f() { + using L for *; +} +// ---- +// UnimplementedFeatureError 1834: (96-145): Code generation is not supported for contracts with specified storage layout base. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_bytes_concat.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_bytes_concat.sol new file mode 100644 index 000000000000..93271e125b6c --- /dev/null +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_bytes_concat.sol @@ -0,0 +1,3 @@ +contract C layout at uint64(bytes8(bytes.concat("ABCD", "EFGH"))) {} +// ---- +// UnimplementedFeatureError 1834: (0-68): Code generation is not supported for contracts with specified storage layout base. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_error.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_error.sol new file mode 100644 index 000000000000..c73dc480d912 --- /dev/null +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_error.sol @@ -0,0 +1,4 @@ +error MyError(); +contract C layout at MyError() {} +// ---- +// TypeError 7757: (38-47): Errors can only be used with revert statements: "revert MyError(args);", or require functions: "require(condition, MyError(args))". diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_event.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_event.sol new file mode 100644 index 000000000000..7560fb83bbea --- /dev/null +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_event.sol @@ -0,0 +1,4 @@ +event MyEvent(); +contract C layout at MyEvent() {} +// ---- +// TypeError 3132: (38-47): Event invocations have to be prefixed by "emit". diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_expression_not_pure.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_expression_not_pure.sol new file mode 100644 index 000000000000..cbb4e5ed9140 --- /dev/null +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_expression_not_pure.sol @@ -0,0 +1,5 @@ +function f(uint x) returns (uint) { return x + 1; } +contract A layout at f(2) {} +// ---- +// Warning 2018: (0-51): Function state mutability can be restricted to pure +// UnimplementedFeatureError 1834: (52-80): Code generation is not supported for contracts with specified storage layout base. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_first_ancestor_contract.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_first_ancestor_contract.sol new file mode 100644 index 000000000000..0549c9d607ac --- /dev/null +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_first_ancestor_contract.sol @@ -0,0 +1,6 @@ +contract A layout at 42 {} +contract B is A {} +contract C is B {} +contract D is C {} +// ---- +// UnimplementedFeatureError 1834: (0-26): Code generation is not supported for contracts with specified storage layout base. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_interface_id.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_interface_id.sol new file mode 100644 index 000000000000..c8bc2abbcd28 --- /dev/null +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_interface_id.sol @@ -0,0 +1,5 @@ +interface I {} + +contract C layout at uint(bytes32(type(I).interfaceId)) { } +// ---- +// UnimplementedFeatureError 1834: (16-75): Code generation is not supported for contracts with specified storage layout base. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_kecak256.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_kecak256.sol new file mode 100644 index 000000000000..14fb09b104c6 --- /dev/null +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_kecak256.sol @@ -0,0 +1,3 @@ +contract C layout at uint(keccak256(bytes.concat("ABCD"))) {} +// ---- +// UnimplementedFeatureError 1834: (0-61): Code generation is not supported for contracts with specified storage layout base. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_last_ancestor_contract.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_last_ancestor_contract.sol new file mode 100644 index 000000000000..2a783a813dbe --- /dev/null +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_last_ancestor_contract.sol @@ -0,0 +1,6 @@ +contract A {} +contract B is A {} +contract C is B layout at 42 {} +contract D is C {} +// ---- +// UnimplementedFeatureError 1834: (33-64): Code generation is not supported for contracts with specified storage layout base. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_module.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_module.sol new file mode 100644 index 000000000000..57d51d587f47 --- /dev/null +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_module.sol @@ -0,0 +1,9 @@ +==== Source: A ==== +function f() pure {} + +==== Source: B ==== +import "A" as MyModule; + +contract C layout at MyModule {} +// ---- +// UnimplementedFeatureError 1834: (B:25-57): Code generation is not supported for contracts with specified storage layout base. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_other_contract.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_other_contract.sol new file mode 100644 index 000000000000..ee695075e319 --- /dev/null +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_other_contract.sol @@ -0,0 +1,4 @@ +contract A {} +contract C layout at A(address(0x1234)) {} +// ---- +// UnimplementedFeatureError 1834: (14-56): Code generation is not supported for contracts with specified storage layout base. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_type.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_type.sol new file mode 100644 index 000000000000..47ae6f0b431f --- /dev/null +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_type.sol @@ -0,0 +1,3 @@ +contract A layout at uint {} +// ---- +// UnimplementedFeatureError 1834: (0-28): Code generation is not supported for contracts with specified storage layout base. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/literal_cast.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/literal_cast.sol new file mode 100644 index 000000000000..d5bd3825e8aa --- /dev/null +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/literal_cast.sol @@ -0,0 +1,3 @@ +contract at layout at uint(42) { } +// ---- +// UnimplementedFeatureError 1834: (0-34): Code generation is not supported for contracts with specified storage layout base. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/literal_with_underscore.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/literal_with_underscore.sol new file mode 100644 index 000000000000..1c3c715f9da9 --- /dev/null +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/literal_with_underscore.sol @@ -0,0 +1,5 @@ +contract A layout at 42_0e10 {} +contract B layout at 0x1234_ABCD {} +contract C layout at 1234_000 {} +// ---- +// UnimplementedFeatureError 1834: (0-31): Code generation is not supported for contracts with specified storage layout base. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/magic_variables.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/magic_variables.sol new file mode 100644 index 000000000000..44798fdbf3db --- /dev/null +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/magic_variables.sol @@ -0,0 +1,7 @@ +contract A layout at this {} +contract B layout at super {} +contract C layout at msg {} +contract D layout at tx {} +contract E layout at block {} +// ---- +// UnimplementedFeatureError 1834: (0-28): Code generation is not supported for contracts with specified storage layout base. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/negative_number.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/negative_number.sol new file mode 100644 index 000000000000..79d8b395b808 --- /dev/null +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/negative_number.sol @@ -0,0 +1,3 @@ +contract A layout at -1 {} +// ---- +// UnimplementedFeatureError 1834: (0-26): Code generation is not supported for contracts with specified storage layout base. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/precompiles.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/precompiles.sol new file mode 100644 index 000000000000..a7e9ee08977d --- /dev/null +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/precompiles.sol @@ -0,0 +1,4 @@ +contract A layout at addmod(1, 2, 3) {} +contract B layout at mulmod(3, 2, 1) {} +// ---- +// UnimplementedFeatureError 1834: (0-39): Code generation is not supported for contracts with specified storage layout base. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/rational_number_zero_fractional_part.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/rational_number_zero_fractional_part.sol new file mode 100644 index 000000000000..4d5b2da9cd51 --- /dev/null +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/rational_number_zero_fractional_part.sol @@ -0,0 +1,4 @@ +contract A layout at 42.0 {} +contract B layout at 2.5e10 {} +// ---- +// UnimplementedFeatureError 1834: (0-28): Code generation is not supported for contracts with specified storage layout base. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/same_ancestor_two_contracts.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/same_ancestor_two_contracts.sol new file mode 100644 index 000000000000..310f503579a0 --- /dev/null +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/same_ancestor_two_contracts.sol @@ -0,0 +1,5 @@ +contract A {} +contract B is A layout at 64 {} +contract C is A layout at 42 {} +// ---- +// UnimplementedFeatureError 1834: (14-45): Code generation is not supported for contracts with specified storage layout base. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/state_variable_from_base_contract.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/state_variable_from_base_contract.sol new file mode 100644 index 000000000000..67e63924b382 --- /dev/null +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/state_variable_from_base_contract.sol @@ -0,0 +1,7 @@ +contract A { + uint public x = 10; +} + +contract C is A layout at A.x {} +// ---- +// UnimplementedFeatureError 1834: (40-72): Code generation is not supported for contracts with specified storage layout base. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/state_variable_getter_from_base_contract.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/state_variable_getter_from_base_contract.sol new file mode 100644 index 000000000000..11c8f449cabd --- /dev/null +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/state_variable_getter_from_base_contract.sol @@ -0,0 +1,7 @@ +contract A { + uint public x = 10; +} + +contract C is A layout at this.x() {} +// ---- +// UnimplementedFeatureError 1834: (40-77): Code generation is not supported for contracts with specified storage layout base. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/string.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/string.sol new file mode 100644 index 000000000000..7f41e64cbdfd --- /dev/null +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/string.sol @@ -0,0 +1,3 @@ +contract C layout at "MyLayoutBase" {} +// ---- +// UnimplementedFeatureError 1834: (0-38): Code generation is not supported for contracts with specified storage layout base. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/struct_defined_in_other_contract.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/struct_defined_in_other_contract.sol new file mode 100644 index 000000000000..4f74c454551a --- /dev/null +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/struct_defined_in_other_contract.sol @@ -0,0 +1,11 @@ +contract A { + struct SA { + uint x; + uint y; + bytes32 b; + } +} + +contract C is A layout at A.SA { } +// ---- +// UnimplementedFeatureError 1834: (89-123): Code generation is not supported for contracts with specified storage layout base. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/ternary_operator.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/ternary_operator.sol new file mode 100644 index 000000000000..5052d837589d --- /dev/null +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/ternary_operator.sol @@ -0,0 +1,4 @@ +contract A layout at true ? 42 : 94 {} +contract B layout at 255 + (true ? 1 : 0) {} +// ---- +// UnimplementedFeatureError 1834: (0-38): Code generation is not supported for contracts with specified storage layout base. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/tuple.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/tuple.sol new file mode 100644 index 000000000000..0dbc2b371680 --- /dev/null +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/tuple.sol @@ -0,0 +1,3 @@ +contract C layout at (1, 2, 3) {} +// ---- +// UnimplementedFeatureError 1834: (0-33): Code generation is not supported for contracts with specified storage layout base. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/type_uint_max.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/type_uint_max.sol new file mode 100644 index 000000000000..54ebb32c7f7b --- /dev/null +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/type_uint_max.sol @@ -0,0 +1,3 @@ +contract at layout at type(uint).max { } +// ---- +// UnimplementedFeatureError 1834: (0-40): Code generation is not supported for contracts with specified storage layout base. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/user_defined_operators.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/user_defined_operators.sol new file mode 100644 index 000000000000..e044a6aadfdc --- /dev/null +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/user_defined_operators.sol @@ -0,0 +1,12 @@ +type MyUint is uint; + +using {add as +} for MyUint global; +function add(MyUint a, MyUint b) pure returns (MyUint) { + return MyUint.wrap(2); +} + +contract C layout at MyUint.wrap(1) + MyUint.wrap(2) {} +// ---- +// Warning 5667: (71-79): Unused function parameter. Remove or comment out the variable name to silence this warning. +// Warning 5667: (81-89): Unused function parameter. Remove or comment out the variable name to silence this warning. +// UnimplementedFeatureError 1834: (145-200): Code generation is not supported for contracts with specified storage layout base. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/user_defined_value_type.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/user_defined_value_type.sol new file mode 100644 index 000000000000..9287e5a3bef8 --- /dev/null +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/user_defined_value_type.sol @@ -0,0 +1,5 @@ +type MyUint is uint128; +MyUint constant x = MyUint.wrap(42); +contract C layout at x {} +// ---- +// UnimplementedFeatureError 1834: (61-86): Code generation is not supported for contracts with specified storage layout base. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/user_defined_value_type_unwrap.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/user_defined_value_type_unwrap.sol new file mode 100644 index 000000000000..a232939c74fa --- /dev/null +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/user_defined_value_type_unwrap.sol @@ -0,0 +1,5 @@ +type MyUint is uint128; +MyUint constant x = MyUint.wrap(42); +contract C layout at MyUint.unwrap(x) {} +// ---- +// UnimplementedFeatureError 1834: (61-101): Code generation is not supported for contracts with specified storage layout base. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/user_defined_value_type_wrap.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/user_defined_value_type_wrap.sol new file mode 100644 index 000000000000..e057b6940b92 --- /dev/null +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/user_defined_value_type_wrap.sol @@ -0,0 +1,4 @@ +type MyUint is uint128; +contract C layout at MyUint.wrap(42) {} +// ---- +// UnimplementedFeatureError 1834: (24-63): Code generation is not supported for contracts with specified storage layout base. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/value_from_array_literal.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/value_from_array_literal.sol new file mode 100644 index 000000000000..cce2bfbe95cb --- /dev/null +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/value_from_array_literal.sol @@ -0,0 +1,4 @@ +contract A layout at [1, 2, 3][0] {} +contract B layout at 255 + [1, 2, 3][0] {} +// ---- +// UnimplementedFeatureError 1834: (0-36): Code generation is not supported for contracts with specified storage layout base. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/value_from_bytes.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/value_from_bytes.sol new file mode 100644 index 000000000000..73fcdc485f33 --- /dev/null +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/value_from_bytes.sol @@ -0,0 +1,4 @@ +bytes32 constant b = "Solidity"; +contract C layout at uint8(b[1]) {} +// ---- +// UnimplementedFeatureError 1834: (33-68): Code generation is not supported for contracts with specified storage layout base. From 7ef0ef8c19bf7df4341b3e72787d8ac75cf988e6 Mon Sep 17 00:00:00 2001 From: Matheus Aguiar Date: Thu, 6 Feb 2025 17:37:53 -0300 Subject: [PATCH 0826/1022] Type checker support for storage layout specifier --- libsolidity/analysis/ContractLevelChecker.cpp | 31 +++++++++ libsolidity/analysis/ContractLevelChecker.h | 2 + .../analysis/PostTypeContractLevelChecker.cpp | 69 ++++++++++++++++++- .../analysis/PostTypeContractLevelChecker.h | 2 + libsolidity/ast/AST.cpp | 5 ++ libsolidity/ast/AST.h | 2 + libsolidity/ast/ASTAnnotations.h | 7 ++ .../err | 21 ++++++ .../exit | 1 + .../storageLayoutSpecifier/abi_decode.sol | 2 +- .../abstract_contract.sol | 2 +- .../storageLayoutSpecifier/address.sol | 2 +- .../address_non_constant.sol | 3 +- .../storageLayoutSpecifier/array_literal.sol | 2 +- .../bitwise_negation_after_cast.sol | 2 +- .../storageLayoutSpecifier/boolean.sol | 2 +- .../builtin_functions.sol | 14 +++- .../bytes_length_member.sol | 2 +- .../constant_divided_by_its_negation.sol | 2 +- .../constant_divided_by_zero.sol | 2 +- .../constant_from_base_contract.sol | 2 +- .../storageLayoutSpecifier/enum.sol | 2 +- .../function_address.sol | 2 +- .../function_defined_in_other_contract.sol | 2 +- .../function_selector.sol | 2 +- .../storageLayoutSpecifier/hex_address.sol | 2 +- .../storageLayoutSpecifier/hex_string.sol | 2 +- .../hex_string_cast.sol | 2 +- ...already_specified_in_ancestor_contract.sol | 3 +- .../layout_bitwise_negation_literal.sol | 2 +- .../layout_fractional_number.sol | 6 +- .../layout_specification_by_function.sol | 2 +- .../layout_specification_bytes.sol | 2 +- ...t_specification_constant_in_expression.sol | 2 +- .../layout_specification_overflow_value.sol | 3 +- .../layout_specification_underflow_value.sol | 3 +- ...specified_by_attached_library_function.sol | 2 +- .../layout_specified_by_bytes_concat.sol | 2 +- ...ayout_specified_by_expression_not_pure.sol | 3 +- ...t_specified_by_first_ancestor_contract.sol | 4 +- ...pecified_by_function_with_call_options.sol | 2 +- .../layout_specified_by_interface_id.sol | 2 +- .../layout_specified_by_kecak256.sol | 2 +- ...ut_specified_by_last_ancestor_contract.sol | 2 +- .../layout_specified_by_module.sol | 2 +- .../layout_specified_by_other_contract.sol | 2 +- .../layout_specified_by_type.sol | 2 +- .../storageLayoutSpecifier/literal_cast.sol | 2 +- .../magic_variables.sol | 6 +- .../negative_number.sol | 2 +- .../storageLayoutSpecifier/precompiles.sol | 3 +- .../state_variable_from_base_contract.sol | 2 +- ...ate_variable_getter_from_base_contract.sol | 2 +- .../storageLayoutSpecifier/string.sol | 2 +- .../struct_defined_in_other_contract.sol | 2 +- .../ternary_operator.sol | 3 +- .../storageLayoutSpecifier/tuple.sol | 2 +- .../storageLayoutSpecifier/type_uint_max.sol | 2 +- .../user_defined_operators.sol | 4 +- .../user_defined_value_type.sol | 2 +- .../user_defined_value_type_unwrap.sol | 2 +- .../user_defined_value_type_wrap.sol | 2 +- .../value_from_array_literal.sol | 3 +- .../value_from_bytes.sol | 2 +- 64 files changed, 223 insertions(+), 59 deletions(-) create mode 100644 test/cmdlineTests/storage_layout_already_defined_in_ancestor/err create mode 100644 test/cmdlineTests/storage_layout_already_defined_in_ancestor/exit diff --git a/libsolidity/analysis/ContractLevelChecker.cpp b/libsolidity/analysis/ContractLevelChecker.cpp index eaeaf4851710..7996fd71137b 100644 --- a/libsolidity/analysis/ContractLevelChecker.cpp +++ b/libsolidity/analysis/ContractLevelChecker.cpp @@ -97,10 +97,41 @@ bool ContractLevelChecker::check(ContractDefinition const& _contract) checkBaseABICompatibility(_contract); checkPayableFallbackWithoutReceive(_contract); checkStorageSize(_contract); + checkStorageLayoutSpecifier(_contract); return !Error::containsErrors(m_errorReporter.errors()); } +void ContractLevelChecker::checkStorageLayoutSpecifier(ContractDefinition const& _contract) +{ + if (_contract.storageLayoutSpecifier()) + { + solAssert(!_contract.isLibrary() && !_contract.isInterface()); + + if (_contract.abstract()) + m_errorReporter.typeError( + 7587_error, + _contract.storageLayoutSpecifier()->location(), + "Storage layout cannot be specified for abstract contracts." + ); + } + + for (auto const* ancestorContract: _contract.annotation().linearizedBaseContracts | ranges::views::reverse) + { + if (*ancestorContract == _contract) + continue; + if (ancestorContract->storageLayoutSpecifier()) + m_errorReporter.typeError( + 8894_error, + _contract.location(), + SecondarySourceLocation().append( + "Storage layout was already specified here.", + ancestorContract->storageLayoutSpecifier()->location() + ), + "Storage layout can only be specified in the most derived contract." + ); + } +} void ContractLevelChecker::checkDuplicateFunctions(ContractDefinition const& _contract) { /// Checks that two functions with the same name defined in this contract have different diff --git a/libsolidity/analysis/ContractLevelChecker.h b/libsolidity/analysis/ContractLevelChecker.h index 1f5826fdc059..f0e521c60bad 100644 --- a/libsolidity/analysis/ContractLevelChecker.h +++ b/libsolidity/analysis/ContractLevelChecker.h @@ -90,6 +90,8 @@ class ContractLevelChecker void checkPayableFallbackWithoutReceive(ContractDefinition const& _contract); /// Error if the contract requires too much storage void checkStorageSize(ContractDefinition const& _contract); + /// Checks if the storage layout specifier is properly assigned in the inheritance tree and not applied to an abstract contract + void checkStorageLayoutSpecifier(ContractDefinition const& _contract); OverrideChecker m_overrideChecker; langutil::ErrorReporter& m_errorReporter; diff --git a/libsolidity/analysis/PostTypeContractLevelChecker.cpp b/libsolidity/analysis/PostTypeContractLevelChecker.cpp index 6d8dc416aa00..b605401e9e27 100644 --- a/libsolidity/analysis/PostTypeContractLevelChecker.cpp +++ b/libsolidity/analysis/PostTypeContractLevelChecker.cpp @@ -22,13 +22,19 @@ #include +#include #include +#include +#include #include #include +#include + using namespace solidity; using namespace solidity::langutil; using namespace solidity::frontend; +using namespace solidity::util; bool PostTypeContractLevelChecker::check(SourceUnit const& _sourceUnit) { @@ -51,7 +57,7 @@ bool PostTypeContractLevelChecker::check(ContractDefinition const& _contract) for (ErrorDefinition const* error: _contract.interfaceErrors()) { std::string signature = error->functionType(true)->externalSignature(); - uint32_t hash = util::selectorFromSignatureU32(signature); + uint32_t hash = selectorFromSignatureU32(signature); // Fail if there is a different signature for the same hash. if (!errorHashes[hash].empty() && !errorHashes[hash].count(signature)) { @@ -67,5 +73,66 @@ bool PostTypeContractLevelChecker::check(ContractDefinition const& _contract) errorHashes[hash][signature] = error->location(); } + if (auto const* layoutSpecifier = _contract.storageLayoutSpecifier()) + checkStorageLayoutSpecifier(*layoutSpecifier); + return !Error::containsErrors(m_errorReporter.errors()); } + +void PostTypeContractLevelChecker::checkStorageLayoutSpecifier(StorageLayoutSpecifier const& _storageLayoutSpecifier) +{ + Expression const& baseSlotExpression = _storageLayoutSpecifier.baseSlotExpression(); + + if (!*baseSlotExpression.annotation().isPure) + { + // TODO: introduce and handle erc7201 as a builtin function + m_errorReporter.typeError( + 1139_error, + baseSlotExpression.location(), + "The base slot of the storage layout must be a compile-time constant expression." + ); + return; + } + + auto const* baseSlotExpressionType = type(baseSlotExpression); + auto const* rationalType = dynamic_cast(baseSlotExpressionType); + if (!rationalType) + { + m_errorReporter.typeError( + 6396_error, + baseSlotExpression.location(), + "The base slot of the storage layout must evaluate to a rational number." + ); + return; + } + + if (rationalType->isFractional()) + { + m_errorReporter.typeError( + 1763_error, + baseSlotExpression.location(), + "The base slot of the storage layout must evaluate to an integer." + ); + return; + } + solAssert(rationalType->value().denominator() == 1); + + if ( + rationalType->value().numerator() < 0 || + rationalType->value().numerator() > std::numeric_limits::max() + ) + { + m_errorReporter.typeError( + 6753_error, + baseSlotExpression.location(), + fmt::format( + "The base slot of the storage layout evaluates to {}, which is outside the range of type uint256.", + formatNumberReadable(rationalType->value().numerator()) + ) + ); + return; + } + + solAssert(baseSlotExpressionType->isImplicitlyConvertibleTo(*TypeProvider::uint256())); + _storageLayoutSpecifier.annotation().baseSlot = u256(rationalType->value().numerator()); +} diff --git a/libsolidity/analysis/PostTypeContractLevelChecker.h b/libsolidity/analysis/PostTypeContractLevelChecker.h index e12e37184687..889c163562ff 100644 --- a/libsolidity/analysis/PostTypeContractLevelChecker.h +++ b/libsolidity/analysis/PostTypeContractLevelChecker.h @@ -50,6 +50,8 @@ class PostTypeContractLevelChecker /// @returns true iff all checks passed. Note even if all checks passed, errors() can still contain warnings bool check(ContractDefinition const& _contract); + void checkStorageLayoutSpecifier(StorageLayoutSpecifier const& _storageLayoutSpecifier); + langutil::ErrorReporter& m_errorReporter; }; diff --git a/libsolidity/ast/AST.cpp b/libsolidity/ast/AST.cpp index cf3bddf403d6..b59273b18d5d 100644 --- a/libsolidity/ast/AST.cpp +++ b/libsolidity/ast/AST.cpp @@ -383,6 +383,11 @@ StorageLayoutSpecifier::StorageLayoutSpecifier( solAssert(_location.contains(m_baseSlotExpression->location())); } +StorageLayoutSpecifierAnnotation& StorageLayoutSpecifier::annotation() const +{ + return initAnnotation(); +} + TypeNameAnnotation& TypeName::annotation() const { return initAnnotation(); diff --git a/libsolidity/ast/AST.h b/libsolidity/ast/AST.h index cc5cc932415c..0121bef332df 100644 --- a/libsolidity/ast/AST.h +++ b/libsolidity/ast/AST.h @@ -622,6 +622,8 @@ class StorageLayoutSpecifier : public ASTNode void accept(ASTConstVisitor& _visitor) const override; Expression const& baseSlotExpression() const { solAssert(m_baseSlotExpression); return *m_baseSlotExpression; } + StorageLayoutSpecifierAnnotation& annotation() const override; + private: ASTPointer m_baseSlotExpression; }; diff --git a/libsolidity/ast/ASTAnnotations.h b/libsolidity/ast/ASTAnnotations.h index 3f817b180fd9..7adfc7a4aa2e 100644 --- a/libsolidity/ast/ASTAnnotations.h +++ b/libsolidity/ast/ASTAnnotations.h @@ -27,6 +27,7 @@ #include #include +#include #include #include @@ -173,6 +174,12 @@ struct ContractDefinitionAnnotation: TypeDeclarationAnnotation, StructurallyDocu std::map internalFunctionIDs; }; +struct StorageLayoutSpecifierAnnotation: ASTAnnotation +{ + // The evaluated value of the expression specifying the contract storage layout base + util::SetOnce baseSlot; +}; + struct CallableDeclarationAnnotation: DeclarationAnnotation { /// The set of functions/modifiers/events this callable overrides. diff --git a/test/cmdlineTests/storage_layout_already_defined_in_ancestor/err b/test/cmdlineTests/storage_layout_already_defined_in_ancestor/err new file mode 100644 index 000000000000..a5ad279544f2 --- /dev/null +++ b/test/cmdlineTests/storage_layout_already_defined_in_ancestor/err @@ -0,0 +1,21 @@ +Error: Storage layout can only be specified in the most derived contract. + --> :5:1: + | +5 | contract B is A {} + | ^^^^^^^^^^^^^^^^^^ +Note: Storage layout was already specified here. + --> :4:12: + | +4 | contract A layout at 0x1234 {} + | ^^^^^^^^^^^^^^^^ + +Error: Storage layout can only be specified in the most derived contract. + --> :6:1: + | +6 | contract C layout at 0x1234 is B {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Note: Storage layout was already specified here. + --> :4:12: + | +4 | contract A layout at 0x1234 {} + | ^^^^^^^^^^^^^^^^ diff --git a/test/cmdlineTests/storage_layout_already_defined_in_ancestor/exit b/test/cmdlineTests/storage_layout_already_defined_in_ancestor/exit new file mode 100644 index 000000000000..d00491fd7e5b --- /dev/null +++ b/test/cmdlineTests/storage_layout_already_defined_in_ancestor/exit @@ -0,0 +1 @@ +1 diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/abi_decode.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/abi_decode.sol index 330f461c2d02..920e8d252c2b 100644 --- a/test/libsolidity/syntaxTests/storageLayoutSpecifier/abi_decode.sol +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/abi_decode.sol @@ -1,3 +1,3 @@ contract C layout at abi.decode(abi.encode(42), (uint)) {} // ---- -// UnimplementedFeatureError 1834: (0-58): Code generation is not supported for contracts with specified storage layout base. +// TypeError 6396: (21-55): The base slot of the storage layout must evaluate to a rational number. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/abstract_contract.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/abstract_contract.sol index dc7a7ce4863e..3f87f87bb394 100644 --- a/test/libsolidity/syntaxTests/storageLayoutSpecifier/abstract_contract.sol +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/abstract_contract.sol @@ -1,3 +1,3 @@ abstract contract C layout at 42 { } // ---- -// UnimplementedFeatureError 1834: (0-36): Code generation is not supported for contracts with specified storage layout base. +// TypeError 7587: (20-32): Storage layout cannot be specified for abstract contracts. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/address.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/address.sol index 5691c0c9051e..fded26fadd0d 100644 --- a/test/libsolidity/syntaxTests/storageLayoutSpecifier/address.sol +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/address.sol @@ -1,3 +1,3 @@ contract C layout at address(0x1234) {} // ---- -// UnimplementedFeatureError 1834: (0-39): Code generation is not supported for contracts with specified storage layout base. +// TypeError 6396: (21-36): The base slot of the storage layout must evaluate to a rational number. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/address_non_constant.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/address_non_constant.sol index 2d6d0745ac1a..39e3fcec982e 100644 --- a/test/libsolidity/syntaxTests/storageLayoutSpecifier/address_non_constant.sol +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/address_non_constant.sol @@ -3,4 +3,5 @@ contract A {} contract C layout at address(new A()) {} contract D layout at uint160(address(this)) {} // ---- -// UnimplementedFeatureError 1834: (15-55): Code generation is not supported for contracts with specified storage layout base. +// TypeError 1139: (36-52): The base slot of the storage layout must be a compile-time constant expression. +// TypeError 1139: (77-99): The base slot of the storage layout must be a compile-time constant expression. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/array_literal.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/array_literal.sol index 0f9c73b67bc4..af6b9424f607 100644 --- a/test/libsolidity/syntaxTests/storageLayoutSpecifier/array_literal.sol +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/array_literal.sol @@ -1,3 +1,3 @@ contract C layout at [1, 2, 3] {} // ---- -// UnimplementedFeatureError 1834: (0-33): Code generation is not supported for contracts with specified storage layout base. +// TypeError 6396: (21-30): The base slot of the storage layout must evaluate to a rational number. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/bitwise_negation_after_cast.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/bitwise_negation_after_cast.sol index 01e34b707ddd..6ccb2ff7a1c8 100644 --- a/test/libsolidity/syntaxTests/storageLayoutSpecifier/bitwise_negation_after_cast.sol +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/bitwise_negation_after_cast.sol @@ -1,3 +1,3 @@ contract C layout at ~uint(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) {} // ---- -// UnimplementedFeatureError 1834: (0-97): Code generation is not supported for contracts with specified storage layout base. +// TypeError 6396: (21-94): The base slot of the storage layout must evaluate to a rational number. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/boolean.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/boolean.sol index cb4112f41bc4..083977c7ae15 100644 --- a/test/libsolidity/syntaxTests/storageLayoutSpecifier/boolean.sol +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/boolean.sol @@ -1,3 +1,3 @@ contract C layout at true {} // ---- -// UnimplementedFeatureError 1834: (0-28): Code generation is not supported for contracts with specified storage layout base. +// TypeError 6396: (21-25): The base slot of the storage layout must evaluate to a rational number. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/builtin_functions.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/builtin_functions.sol index 631b1c60ba52..7c1bfc1e60d2 100644 --- a/test/libsolidity/syntaxTests/storageLayoutSpecifier/builtin_functions.sol +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/builtin_functions.sol @@ -15,4 +15,16 @@ contract M layout at uint(address(this).codehash) { } // ==== // EVMVersion: >=paris // ---- -// UnimplementedFeatureError 1834: (0-38): Code generation is not supported for contracts with specified storage layout base. +// TypeError 1139: (21-34): The base slot of the storage layout must be a compile-time constant expression. +// TypeError 1139: (60-73): The base slot of the storage layout must be a compile-time constant expression. +// TypeError 1139: (99-111): The base slot of the storage layout must be a compile-time constant expression. +// TypeError 1139: (137-169): The base slot of the storage layout must be a compile-time constant expression. +// TypeError 1139: (195-211): The base slot of the storage layout must be a compile-time constant expression. +// TypeError 1139: (237-255): The base slot of the storage layout must be a compile-time constant expression. +// TypeError 1139: (281-290): The base slot of the storage layout must be a compile-time constant expression. +// TypeError 1139: (316-326): The base slot of the storage layout must be a compile-time constant expression. +// TypeError 1139: (352-360): The base slot of the storage layout must be a compile-time constant expression. +// TypeError 1139: (386-397): The base slot of the storage layout must be a compile-time constant expression. +// TypeError 1139: (423-441): The base slot of the storage layout must be a compile-time constant expression. +// TypeError 1139: (467-488): The base slot of the storage layout must be a compile-time constant expression. +// TypeError 1139: (514-542): The base slot of the storage layout must be a compile-time constant expression. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/bytes_length_member.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/bytes_length_member.sol index b2bb64b199d9..f49e6c2dbda2 100644 --- a/test/libsolidity/syntaxTests/storageLayoutSpecifier/bytes_length_member.sol +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/bytes_length_member.sol @@ -1,3 +1,3 @@ contract C layout at bytes("ABCD").length {} // ---- -// UnimplementedFeatureError 1834: (0-44): Code generation is not supported for contracts with specified storage layout base. +// TypeError 1139: (21-41): The base slot of the storage layout must be a compile-time constant expression. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/constant_divided_by_its_negation.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/constant_divided_by_its_negation.sol index 9f8acbeb6a36..b9cdd9dfaae2 100644 --- a/test/libsolidity/syntaxTests/storageLayoutSpecifier/constant_divided_by_its_negation.sol +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/constant_divided_by_its_negation.sol @@ -1,4 +1,4 @@ uint constant N = 100; contract C layout at N / ~N {} // ---- -// TypeError 3667: (48-50): Arithmetic error when computing constant value. +// TypeError 6396: (44-50): The base slot of the storage layout must evaluate to a rational number. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/constant_divided_by_zero.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/constant_divided_by_zero.sol index f6e3c3805bd2..bb97172d996c 100644 --- a/test/libsolidity/syntaxTests/storageLayoutSpecifier/constant_divided_by_zero.sol +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/constant_divided_by_zero.sol @@ -1,4 +1,4 @@ uint constant N = 100; contract C layout at N / 0 {} // ---- -// TypeError 1211: (44-49): Division by zero. +// TypeError 6396: (44-49): The base slot of the storage layout must evaluate to a rational number. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/constant_from_base_contract.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/constant_from_base_contract.sol index 1995cf698f96..e06deeaaf2dc 100644 --- a/test/libsolidity/syntaxTests/storageLayoutSpecifier/constant_from_base_contract.sol +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/constant_from_base_contract.sol @@ -4,4 +4,4 @@ contract A { contract C is A layout at A.x { } // ---- -// UnimplementedFeatureError 1834: (42-75): Code generation is not supported for contracts with specified storage layout base. +// TypeError 6396: (68-71): The base slot of the storage layout must evaluate to a rational number. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/enum.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/enum.sol index c9eba88e5380..9a264247c8d0 100644 --- a/test/libsolidity/syntaxTests/storageLayoutSpecifier/enum.sol +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/enum.sol @@ -2,4 +2,4 @@ enum Color {Red, Green, Blue} contract C layout at Color.Red {} // ---- -// UnimplementedFeatureError 1834: (31-64): Code generation is not supported for contracts with specified storage layout base. +// TypeError 6396: (52-61): The base slot of the storage layout must evaluate to a rational number. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/function_address.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/function_address.sol index b6d2b99d96a4..a3256f2df237 100644 --- a/test/libsolidity/syntaxTests/storageLayoutSpecifier/function_address.sol +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/function_address.sol @@ -4,4 +4,4 @@ contract A { contract C is A layout at this.f.address {} // ---- -// UnimplementedFeatureError 1834: (48-91): Code generation is not supported for contracts with specified storage layout base. +// TypeError 1139: (74-88): The base slot of the storage layout must be a compile-time constant expression. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/function_defined_in_other_contract.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/function_defined_in_other_contract.sol index 1b890790346b..68b2e2460471 100644 --- a/test/libsolidity/syntaxTests/storageLayoutSpecifier/function_defined_in_other_contract.sol +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/function_defined_in_other_contract.sol @@ -4,4 +4,4 @@ contract A { contract C layout at A.f { } // ---- -// UnimplementedFeatureError 1834: (50-78): Code generation is not supported for contracts with specified storage layout base. +// TypeError 6396: (71-74): The base slot of the storage layout must evaluate to a rational number. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/function_selector.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/function_selector.sol index e3b873ca7905..98c7b6057abe 100644 --- a/test/libsolidity/syntaxTests/storageLayoutSpecifier/function_selector.sol +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/function_selector.sol @@ -3,4 +3,4 @@ contract A { } contract C is A layout at uint32(this.f.selector) {} // ---- -// UnimplementedFeatureError 1834: (42-94): Code generation is not supported for contracts with specified storage layout base. +// TypeError 6396: (68-91): The base slot of the storage layout must evaluate to a rational number. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/hex_address.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/hex_address.sol index 4a6e9401f420..9e63740d89f3 100644 --- a/test/libsolidity/syntaxTests/storageLayoutSpecifier/hex_address.sol +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/hex_address.sol @@ -1,3 +1,3 @@ contract C layout at 0xdCad3a6d3569DF655070DEd06cb7A1b2Ccd1D3AF {} // ---- -// UnimplementedFeatureError 1834: (0-66): Code generation is not supported for contracts with specified storage layout base. +// TypeError 6396: (21-63): The base slot of the storage layout must evaluate to a rational number. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/hex_string.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/hex_string.sol index 38d1085a84af..194f0df0ea9a 100644 --- a/test/libsolidity/syntaxTests/storageLayoutSpecifier/hex_string.sol +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/hex_string.sol @@ -1,3 +1,3 @@ contract C layout at hex"616263" {} // ---- -// UnimplementedFeatureError 1834: (0-35): Code generation is not supported for contracts with specified storage layout base. +// TypeError 6396: (21-32): The base slot of the storage layout must evaluate to a rational number. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/hex_string_cast.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/hex_string_cast.sol index 0318625995b5..a803d005f7dd 100644 --- a/test/libsolidity/syntaxTests/storageLayoutSpecifier/hex_string_cast.sol +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/hex_string_cast.sol @@ -1,3 +1,3 @@ contract at layout at uint40(bytes5(hex"0011223344")) { } // ---- -// UnimplementedFeatureError 1834: (0-57): Code generation is not supported for contracts with specified storage layout base. +// TypeError 6396: (22-53): The base slot of the storage layout must evaluate to a rational number. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_already_specified_in_ancestor_contract.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_already_specified_in_ancestor_contract.sol index 8ddfdbfc37e1..d525d92066a0 100644 --- a/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_already_specified_in_ancestor_contract.sol +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_already_specified_in_ancestor_contract.sol @@ -4,4 +4,5 @@ contract B is A {} contract C is B layout at 0xABCD {} // ---- -// UnimplementedFeatureError 1834: (0-30): Code generation is not supported for contracts with specified storage layout base. +// TypeError 8894: (32-50): Storage layout can only be specified in the most derived contract. +// TypeError 8894: (52-87): Storage layout can only be specified in the most derived contract. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_bitwise_negation_literal.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_bitwise_negation_literal.sol index cd74b20dbc78..a3238257466e 100644 --- a/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_bitwise_negation_literal.sol +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_bitwise_negation_literal.sol @@ -1,3 +1,3 @@ contract C layout at ~0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE {} // ---- -// UnimplementedFeatureError 1834: (0-91): Code generation is not supported for contracts with specified storage layout base. +// TypeError 6753: (21-88): The base slot of the storage layout evaluates to -2**256 + 1, which is outside the range of type uint256. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_fractional_number.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_fractional_number.sol index 0e24366b10e5..1f2e1ecd4eda 100644 --- a/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_fractional_number.sol +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_fractional_number.sol @@ -4,4 +4,8 @@ contract C layout at .1 {} contract D layout at 42e-10 {} contract E layout at 1_7e-10 {} // ---- -// UnimplementedFeatureError 1834: (0-27): Code generation is not supported for contracts with specified storage layout base. +// TypeError 1763: (21-24): The base slot of the storage layout must evaluate to an integer. +// TypeError 1763: (49-52): The base slot of the storage layout must evaluate to an integer. +// TypeError 1763: (77-79): The base slot of the storage layout must evaluate to an integer. +// TypeError 1763: (104-110): The base slot of the storage layout must evaluate to an integer. +// TypeError 1763: (135-142): The base slot of the storage layout must evaluate to an integer. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specification_by_function.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specification_by_function.sol index e9cd65ffe400..f0c6a00985ea 100644 --- a/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specification_by_function.sol +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specification_by_function.sol @@ -3,4 +3,4 @@ function f() pure returns (uint256) { } contract C layout at f() { } // ---- -// UnimplementedFeatureError 1834: (56-84): Code generation is not supported for contracts with specified storage layout base. +// TypeError 1139: (77-80): The base slot of the storage layout must be a compile-time constant expression. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specification_bytes.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specification_bytes.sol index 65923479d283..6f9b39703afa 100644 --- a/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specification_bytes.sol +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specification_bytes.sol @@ -1,4 +1,4 @@ bytes32 constant b = "bytes"; contract A layout at b[1] {} // ---- -// UnimplementedFeatureError 1834: (30-58): Code generation is not supported for contracts with specified storage layout base. +// TypeError 6396: (51-55): The base slot of the storage layout must evaluate to a rational number. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specification_constant_in_expression.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specification_constant_in_expression.sol index 471a5a63c225..8e6d37ad6e1f 100644 --- a/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specification_constant_in_expression.sol +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specification_constant_in_expression.sol @@ -1,4 +1,4 @@ uint constant X = 42; contract C layout at 0xffff * (50 - X) { } // ---- -// UnimplementedFeatureError 1834: (22-64): Code generation is not supported for contracts with specified storage layout base. +// TypeError 6396: (43-60): The base slot of the storage layout must evaluate to a rational number. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specification_overflow_value.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specification_overflow_value.sol index ece4273bbbc4..9901af417570 100644 --- a/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specification_overflow_value.sol +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specification_overflow_value.sol @@ -1,4 +1,5 @@ contract A layout at 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + 1 {} contract B layout at 2**256 {} // ---- -// UnimplementedFeatureError 1834: (0-94): Code generation is not supported for contracts with specified storage layout base. +// TypeError 6753: (21-91): The base slot of the storage layout evaluates to 2**256, which is outside the range of type uint256. +// TypeError 6753: (116-122): The base slot of the storage layout evaluates to 2**256, which is outside the range of type uint256. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specification_underflow_value.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specification_underflow_value.sol index 953d791cc9ec..e1f1b0914a9c 100644 --- a/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specification_underflow_value.sol +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specification_underflow_value.sol @@ -1,4 +1,5 @@ contract A layout at 0 - 1 {} contract B layout at 2**8 - 2**16 {} // ---- -// UnimplementedFeatureError 1834: (0-29): Code generation is not supported for contracts with specified storage layout base. +// TypeError 6753: (21-26): The base slot of the storage layout evaluates to -1, which is outside the range of type uint256. +// TypeError 6753: (51-63): The base slot of the storage layout evaluates to -65280, which is outside the range of type uint256. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_attached_library_function.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_attached_library_function.sol index b586a271e177..6c38d15988d7 100644 --- a/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_attached_library_function.sol +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_attached_library_function.sol @@ -9,4 +9,4 @@ contract C layout at 2.f() { using L for *; } // ---- -// UnimplementedFeatureError 1834: (96-145): Code generation is not supported for contracts with specified storage layout base. +// TypeError 1139: (117-122): The base slot of the storage layout must be a compile-time constant expression. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_bytes_concat.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_bytes_concat.sol index 93271e125b6c..d341a5a764d2 100644 --- a/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_bytes_concat.sol +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_bytes_concat.sol @@ -1,3 +1,3 @@ contract C layout at uint64(bytes8(bytes.concat("ABCD", "EFGH"))) {} // ---- -// UnimplementedFeatureError 1834: (0-68): Code generation is not supported for contracts with specified storage layout base. +// TypeError 1139: (21-65): The base slot of the storage layout must be a compile-time constant expression. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_expression_not_pure.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_expression_not_pure.sol index cbb4e5ed9140..c7a72f727749 100644 --- a/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_expression_not_pure.sol +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_expression_not_pure.sol @@ -1,5 +1,4 @@ function f(uint x) returns (uint) { return x + 1; } contract A layout at f(2) {} // ---- -// Warning 2018: (0-51): Function state mutability can be restricted to pure -// UnimplementedFeatureError 1834: (52-80): Code generation is not supported for contracts with specified storage layout base. +// TypeError 1139: (73-77): The base slot of the storage layout must be a compile-time constant expression. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_first_ancestor_contract.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_first_ancestor_contract.sol index 0549c9d607ac..77b1ed617c08 100644 --- a/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_first_ancestor_contract.sol +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_first_ancestor_contract.sol @@ -3,4 +3,6 @@ contract B is A {} contract C is B {} contract D is C {} // ---- -// UnimplementedFeatureError 1834: (0-26): Code generation is not supported for contracts with specified storage layout base. +// TypeError 8894: (27-45): Storage layout can only be specified in the most derived contract. +// TypeError 8894: (46-64): Storage layout can only be specified in the most derived contract. +// TypeError 8894: (65-83): Storage layout can only be specified in the most derived contract. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_function_with_call_options.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_function_with_call_options.sol index aca167f6b95d..f0b2a2b68b04 100644 --- a/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_function_with_call_options.sol +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_function_with_call_options.sol @@ -3,4 +3,4 @@ contract A { } contract C is A layout at this.f{value:123}() {} // ---- -// UnimplementedFeatureError 1834: (67-115): Code generation is not supported for contracts with specified storage layout base. +// TypeError 1139: (93-112): The base slot of the storage layout must be a compile-time constant expression. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_interface_id.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_interface_id.sol index c8bc2abbcd28..12304ba8a0bd 100644 --- a/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_interface_id.sol +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_interface_id.sol @@ -2,4 +2,4 @@ interface I {} contract C layout at uint(bytes32(type(I).interfaceId)) { } // ---- -// UnimplementedFeatureError 1834: (16-75): Code generation is not supported for contracts with specified storage layout base. +// TypeError 6396: (37-71): The base slot of the storage layout must evaluate to a rational number. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_kecak256.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_kecak256.sol index 14fb09b104c6..539a59c11c07 100644 --- a/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_kecak256.sol +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_kecak256.sol @@ -1,3 +1,3 @@ contract C layout at uint(keccak256(bytes.concat("ABCD"))) {} // ---- -// UnimplementedFeatureError 1834: (0-61): Code generation is not supported for contracts with specified storage layout base. +// TypeError 1139: (21-58): The base slot of the storage layout must be a compile-time constant expression. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_last_ancestor_contract.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_last_ancestor_contract.sol index 2a783a813dbe..0c42f3550a44 100644 --- a/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_last_ancestor_contract.sol +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_last_ancestor_contract.sol @@ -3,4 +3,4 @@ contract B is A {} contract C is B layout at 42 {} contract D is C {} // ---- -// UnimplementedFeatureError 1834: (33-64): Code generation is not supported for contracts with specified storage layout base. +// TypeError 8894: (65-83): Storage layout can only be specified in the most derived contract. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_module.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_module.sol index 57d51d587f47..ee480730434c 100644 --- a/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_module.sol +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_module.sol @@ -6,4 +6,4 @@ import "A" as MyModule; contract C layout at MyModule {} // ---- -// UnimplementedFeatureError 1834: (B:25-57): Code generation is not supported for contracts with specified storage layout base. +// TypeError 6396: (B:46-54): The base slot of the storage layout must evaluate to a rational number. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_other_contract.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_other_contract.sol index ee695075e319..035e43d24ae4 100644 --- a/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_other_contract.sol +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_other_contract.sol @@ -1,4 +1,4 @@ contract A {} contract C layout at A(address(0x1234)) {} // ---- -// UnimplementedFeatureError 1834: (14-56): Code generation is not supported for contracts with specified storage layout base. +// TypeError 6396: (35-53): The base slot of the storage layout must evaluate to a rational number. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_type.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_type.sol index 47ae6f0b431f..4d48e410f881 100644 --- a/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_type.sol +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_type.sol @@ -1,3 +1,3 @@ contract A layout at uint {} // ---- -// UnimplementedFeatureError 1834: (0-28): Code generation is not supported for contracts with specified storage layout base. +// TypeError 6396: (21-25): The base slot of the storage layout must evaluate to a rational number. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/literal_cast.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/literal_cast.sol index d5bd3825e8aa..0f682d779b0b 100644 --- a/test/libsolidity/syntaxTests/storageLayoutSpecifier/literal_cast.sol +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/literal_cast.sol @@ -1,3 +1,3 @@ contract at layout at uint(42) { } // ---- -// UnimplementedFeatureError 1834: (0-34): Code generation is not supported for contracts with specified storage layout base. +// TypeError 6396: (22-30): The base slot of the storage layout must evaluate to a rational number. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/magic_variables.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/magic_variables.sol index 44798fdbf3db..0558e28db9b6 100644 --- a/test/libsolidity/syntaxTests/storageLayoutSpecifier/magic_variables.sol +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/magic_variables.sol @@ -4,4 +4,8 @@ contract C layout at msg {} contract D layout at tx {} contract E layout at block {} // ---- -// UnimplementedFeatureError 1834: (0-28): Code generation is not supported for contracts with specified storage layout base. +// TypeError 1139: (21-25): The base slot of the storage layout must be a compile-time constant expression. +// TypeError 1139: (50-55): The base slot of the storage layout must be a compile-time constant expression. +// TypeError 1139: (80-83): The base slot of the storage layout must be a compile-time constant expression. +// TypeError 1139: (108-110): The base slot of the storage layout must be a compile-time constant expression. +// TypeError 1139: (135-140): The base slot of the storage layout must be a compile-time constant expression. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/negative_number.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/negative_number.sol index 79d8b395b808..9e3111f880c3 100644 --- a/test/libsolidity/syntaxTests/storageLayoutSpecifier/negative_number.sol +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/negative_number.sol @@ -1,3 +1,3 @@ contract A layout at -1 {} // ---- -// UnimplementedFeatureError 1834: (0-26): Code generation is not supported for contracts with specified storage layout base. +// TypeError 6753: (21-23): The base slot of the storage layout evaluates to -1, which is outside the range of type uint256. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/precompiles.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/precompiles.sol index a7e9ee08977d..c87a98eaa919 100644 --- a/test/libsolidity/syntaxTests/storageLayoutSpecifier/precompiles.sol +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/precompiles.sol @@ -1,4 +1,5 @@ contract A layout at addmod(1, 2, 3) {} contract B layout at mulmod(3, 2, 1) {} // ---- -// UnimplementedFeatureError 1834: (0-39): Code generation is not supported for contracts with specified storage layout base. +// TypeError 6396: (21-36): The base slot of the storage layout must evaluate to a rational number. +// TypeError 6396: (61-76): The base slot of the storage layout must evaluate to a rational number. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/state_variable_from_base_contract.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/state_variable_from_base_contract.sol index 67e63924b382..92c0b1147ea4 100644 --- a/test/libsolidity/syntaxTests/storageLayoutSpecifier/state_variable_from_base_contract.sol +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/state_variable_from_base_contract.sol @@ -4,4 +4,4 @@ contract A { contract C is A layout at A.x {} // ---- -// UnimplementedFeatureError 1834: (40-72): Code generation is not supported for contracts with specified storage layout base. +// TypeError 1139: (66-69): The base slot of the storage layout must be a compile-time constant expression. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/state_variable_getter_from_base_contract.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/state_variable_getter_from_base_contract.sol index 11c8f449cabd..70e3e441956e 100644 --- a/test/libsolidity/syntaxTests/storageLayoutSpecifier/state_variable_getter_from_base_contract.sol +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/state_variable_getter_from_base_contract.sol @@ -4,4 +4,4 @@ contract A { contract C is A layout at this.x() {} // ---- -// UnimplementedFeatureError 1834: (40-77): Code generation is not supported for contracts with specified storage layout base. +// TypeError 1139: (66-74): The base slot of the storage layout must be a compile-time constant expression. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/string.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/string.sol index 7f41e64cbdfd..3b8292fe8cbd 100644 --- a/test/libsolidity/syntaxTests/storageLayoutSpecifier/string.sol +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/string.sol @@ -1,3 +1,3 @@ contract C layout at "MyLayoutBase" {} // ---- -// UnimplementedFeatureError 1834: (0-38): Code generation is not supported for contracts with specified storage layout base. +// TypeError 6396: (21-35): The base slot of the storage layout must evaluate to a rational number. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/struct_defined_in_other_contract.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/struct_defined_in_other_contract.sol index 4f74c454551a..bb1bcc0e13ba 100644 --- a/test/libsolidity/syntaxTests/storageLayoutSpecifier/struct_defined_in_other_contract.sol +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/struct_defined_in_other_contract.sol @@ -8,4 +8,4 @@ contract A { contract C is A layout at A.SA { } // ---- -// UnimplementedFeatureError 1834: (89-123): Code generation is not supported for contracts with specified storage layout base. +// TypeError 1139: (115-119): The base slot of the storage layout must be a compile-time constant expression. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/ternary_operator.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/ternary_operator.sol index 5052d837589d..f426104cc2cb 100644 --- a/test/libsolidity/syntaxTests/storageLayoutSpecifier/ternary_operator.sol +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/ternary_operator.sol @@ -1,4 +1,5 @@ contract A layout at true ? 42 : 94 {} contract B layout at 255 + (true ? 1 : 0) {} // ---- -// UnimplementedFeatureError 1834: (0-38): Code generation is not supported for contracts with specified storage layout base. +// TypeError 6396: (21-35): The base slot of the storage layout must evaluate to a rational number. +// TypeError 6396: (60-80): The base slot of the storage layout must evaluate to a rational number. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/tuple.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/tuple.sol index 0dbc2b371680..eb4693e488d1 100644 --- a/test/libsolidity/syntaxTests/storageLayoutSpecifier/tuple.sol +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/tuple.sol @@ -1,3 +1,3 @@ contract C layout at (1, 2, 3) {} // ---- -// UnimplementedFeatureError 1834: (0-33): Code generation is not supported for contracts with specified storage layout base. +// TypeError 6396: (21-30): The base slot of the storage layout must evaluate to a rational number. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/type_uint_max.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/type_uint_max.sol index 54ebb32c7f7b..dd8ee6f9cc27 100644 --- a/test/libsolidity/syntaxTests/storageLayoutSpecifier/type_uint_max.sol +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/type_uint_max.sol @@ -1,3 +1,3 @@ contract at layout at type(uint).max { } // ---- -// UnimplementedFeatureError 1834: (0-40): Code generation is not supported for contracts with specified storage layout base. +// TypeError 6396: (22-36): The base slot of the storage layout must evaluate to a rational number. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/user_defined_operators.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/user_defined_operators.sol index e044a6aadfdc..14259fd3d65d 100644 --- a/test/libsolidity/syntaxTests/storageLayoutSpecifier/user_defined_operators.sol +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/user_defined_operators.sol @@ -7,6 +7,4 @@ function add(MyUint a, MyUint b) pure returns (MyUint) { contract C layout at MyUint.wrap(1) + MyUint.wrap(2) {} // ---- -// Warning 5667: (71-79): Unused function parameter. Remove or comment out the variable name to silence this warning. -// Warning 5667: (81-89): Unused function parameter. Remove or comment out the variable name to silence this warning. -// UnimplementedFeatureError 1834: (145-200): Code generation is not supported for contracts with specified storage layout base. +// TypeError 1139: (166-197): The base slot of the storage layout must be a compile-time constant expression. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/user_defined_value_type.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/user_defined_value_type.sol index 9287e5a3bef8..98036416880a 100644 --- a/test/libsolidity/syntaxTests/storageLayoutSpecifier/user_defined_value_type.sol +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/user_defined_value_type.sol @@ -2,4 +2,4 @@ type MyUint is uint128; MyUint constant x = MyUint.wrap(42); contract C layout at x {} // ---- -// UnimplementedFeatureError 1834: (61-86): Code generation is not supported for contracts with specified storage layout base. +// TypeError 6396: (82-83): The base slot of the storage layout must evaluate to a rational number. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/user_defined_value_type_unwrap.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/user_defined_value_type_unwrap.sol index a232939c74fa..b45ee88dd98d 100644 --- a/test/libsolidity/syntaxTests/storageLayoutSpecifier/user_defined_value_type_unwrap.sol +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/user_defined_value_type_unwrap.sol @@ -2,4 +2,4 @@ type MyUint is uint128; MyUint constant x = MyUint.wrap(42); contract C layout at MyUint.unwrap(x) {} // ---- -// UnimplementedFeatureError 1834: (61-101): Code generation is not supported for contracts with specified storage layout base. +// TypeError 6396: (82-98): The base slot of the storage layout must evaluate to a rational number. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/user_defined_value_type_wrap.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/user_defined_value_type_wrap.sol index e057b6940b92..172fb58ab12c 100644 --- a/test/libsolidity/syntaxTests/storageLayoutSpecifier/user_defined_value_type_wrap.sol +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/user_defined_value_type_wrap.sol @@ -1,4 +1,4 @@ type MyUint is uint128; contract C layout at MyUint.wrap(42) {} // ---- -// UnimplementedFeatureError 1834: (24-63): Code generation is not supported for contracts with specified storage layout base. +// TypeError 6396: (45-60): The base slot of the storage layout must evaluate to a rational number. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/value_from_array_literal.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/value_from_array_literal.sol index cce2bfbe95cb..bb56de728944 100644 --- a/test/libsolidity/syntaxTests/storageLayoutSpecifier/value_from_array_literal.sol +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/value_from_array_literal.sol @@ -1,4 +1,5 @@ contract A layout at [1, 2, 3][0] {} contract B layout at 255 + [1, 2, 3][0] {} // ---- -// UnimplementedFeatureError 1834: (0-36): Code generation is not supported for contracts with specified storage layout base. +// TypeError 6396: (21-33): The base slot of the storage layout must evaluate to a rational number. +// TypeError 6396: (58-76): The base slot of the storage layout must evaluate to a rational number. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/value_from_bytes.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/value_from_bytes.sol index 73fcdc485f33..1f08fa0ec9ee 100644 --- a/test/libsolidity/syntaxTests/storageLayoutSpecifier/value_from_bytes.sol +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/value_from_bytes.sol @@ -1,4 +1,4 @@ bytes32 constant b = "Solidity"; contract C layout at uint8(b[1]) {} // ---- -// UnimplementedFeatureError 1834: (33-68): Code generation is not supported for contracts with specified storage layout base. +// TypeError 6396: (54-65): The base slot of the storage layout must evaluate to a rational number. From bff760504bbe92921f7bdd728b03714a82e1e175 Mon Sep 17 00:00:00 2001 From: Daniel Kirchner Date: Mon, 10 Feb 2025 19:36:10 +0100 Subject: [PATCH 0827/1022] Support for SWAPN/DUPN in EVM Code Transform. --- libevmasm/GasMeter.cpp | 44 +++++-- libevmasm/GasMeter.h | 11 +- libyul/backends/evm/EVMDialect.h | 1 + .../evm/OptimizedEVMCodeTransform.cpp | 46 +++++-- .../backends/evm/OptimizedEVMCodeTransform.h | 4 + libyul/backends/evm/StackHelpers.h | 36 ++++-- libyul/backends/evm/StackLayoutGenerator.cpp | 115 +++++++++++------- libyul/backends/evm/StackLayoutGenerator.h | 27 +++- libyul/optimiser/StackCompressor.cpp | 4 +- libyul/optimiser/StackLimitEvader.cpp | 2 +- test/libyul/StackLayoutGeneratorTest.cpp | 6 +- test/libyul/StackShufflingTest.cpp | 3 +- 12 files changed, 215 insertions(+), 84 deletions(-) diff --git a/libevmasm/GasMeter.cpp b/libevmasm/GasMeter.cpp index 1eff35fb2d66..fde0819dabec 100644 --- a/libevmasm/GasMeter.cpp +++ b/libevmasm/GasMeter.cpp @@ -263,12 +263,11 @@ GasMeter::GasConsumption GasMeter::memoryGas(int _stackPosOffset, int _stackPosS })); } -unsigned GasMeter::runGas(Instruction _instruction, langutil::EVMVersion _evmVersion) +namespace { - if (_instruction == Instruction::JUMPDEST) - return 1; - - switch (instructionInfo(_instruction, _evmVersion).gasPriceTier) +std::optional gasCostForTier(Tier _tier) +{ + switch (_tier) { case Tier::Zero: return GasCosts::tier0Gas; case Tier::Base: return GasCosts::tier1Gas; @@ -286,10 +285,21 @@ unsigned GasMeter::runGas(Instruction _instruction, langutil::EVMVersion _evmVer case Tier::Special: case Tier::Invalid: - assertThrow(false, OptimizerException, "Invalid gas tier for instruction " + instructionInfo(_instruction, _evmVersion).name); + return std::nullopt; } util::unreachable(); } +} + +unsigned GasMeter::runGas(Instruction _instruction, langutil::EVMVersion _evmVersion) +{ + if (_instruction == Instruction::JUMPDEST) + return 1; + + if (auto gasCost = gasCostForTier(instructionInfo(_instruction, _evmVersion).gasPriceTier)) + return *gasCost; + solAssert(false, "Invalid gas tier for instruction " + instructionInfo(_instruction, _evmVersion).name); +} unsigned GasMeter::pushGas(u256 _value, langutil::EVMVersion _evmVersion) { @@ -299,6 +309,24 @@ unsigned GasMeter::pushGas(u256 _value, langutil::EVMVersion _evmVersion) ); } +unsigned GasMeter::swapGas(size_t _depth, langutil::EVMVersion _evmVersion) +{ + if (_depth <= 16) + return runGas(evmasm::swapInstruction(static_cast(_depth)), _evmVersion); + auto gasCost = gasCostForTier(instructionInfo(evmasm::Instruction::SWAPN, _evmVersion).gasPriceTier); + solAssert(gasCost.has_value(), "Expected gas cost for SWAPN to be defined."); + return *gasCost; +} + +unsigned GasMeter::dupGas(size_t _depth, langutil::EVMVersion _evmVersion) +{ + if (_depth <= 16) + return runGas(evmasm::swapInstruction(static_cast(_depth)), _evmVersion); + auto gasCost = gasCostForTier(instructionInfo(evmasm::Instruction::DUPN, _evmVersion).gasPriceTier); + solAssert(gasCost.has_value(), "Expected gas cost for DUPN to be defined."); + return *gasCost; +} + u256 GasMeter::dataGas(bytes const& _data, bool _inCreation, langutil::EVMVersion _evmVersion) { bigint gas = 0; @@ -309,7 +337,7 @@ u256 GasMeter::dataGas(bytes const& _data, bool _inCreation, langutil::EVMVersio } else gas = bigint(GasCosts::createDataGas) * _data.size(); - assertThrow(gas < bigint(u256(-1)), OptimizerException, "Gas cost exceeds 256 bits."); + solAssert(gas < bigint(u256(-1)), "Gas cost exceeds 256 bits."); return u256(gas); } @@ -317,6 +345,6 @@ u256 GasMeter::dataGas(bytes const& _data, bool _inCreation, langutil::EVMVersio u256 GasMeter::dataGas(uint64_t _length, bool _inCreation, langutil::EVMVersion _evmVersion) { bigint gas = bigint(_length) * (_inCreation ? GasCosts::txDataNonZeroGas(_evmVersion) : GasCosts::createDataGas); - assertThrow(gas < bigint(u256(-1)), OptimizerException, "Gas cost exceeds 256 bits."); + solAssert(gas < bigint(u256(-1)), "Gas cost exceeds 256 bits."); return u256(gas); } diff --git a/libevmasm/GasMeter.h b/libevmasm/GasMeter.h index f202b358e5f0..286999e5c753 100644 --- a/libevmasm/GasMeter.h +++ b/libevmasm/GasMeter.h @@ -226,9 +226,18 @@ class GasMeter /// change with EVM versions) static unsigned runGas(Instruction _instruction, langutil::EVMVersion _evmVersion); - /// @returns gas costs for push instructions (may change depending on EVM version) + /// @returns gas costs for the cheapest push instructions for the given @a _value + /// (may change depending on EVM version) static unsigned pushGas(u256 _value, langutil::EVMVersion _evmVersion); + /// @returns gas costs for the cheapest swap instructions for the given @a _depth + /// (may change depending on EVM version) + static unsigned swapGas(size_t _depth, langutil::EVMVersion _evmVersion); + + /// @returns gas costs for the cheapest dup instructions for the given @a _depth + /// (may change depending on EVM version) + static unsigned dupGas(size_t _depth, langutil::EVMVersion _evmVersion); + /// @returns the gas cost of the supplied data, depending whether it is in creation code, or not. /// In case of @a _inCreation, the data is only sent as a transaction and is not stored, whereas /// otherwise code will be stored and have to pay "createDataGas" cost. diff --git a/libyul/backends/evm/EVMDialect.h b/libyul/backends/evm/EVMDialect.h index 5d5ea90a99be..0440daade1ce 100644 --- a/libyul/backends/evm/EVMDialect.h +++ b/libyul/backends/evm/EVMDialect.h @@ -104,6 +104,7 @@ class EVMDialect: public Dialect langutil::EVMVersion evmVersion() const { return m_evmVersion; } std::optional eofVersion() const { return m_eofVersion; } + size_t reachableStackDepth() const { return m_eofVersion.has_value() ? 256 : 16; } bool providesObjectAccess() const { return m_objectAccess; } diff --git a/libyul/backends/evm/OptimizedEVMCodeTransform.cpp b/libyul/backends/evm/OptimizedEVMCodeTransform.cpp index bd5c55a3cd73..07ab758d7502 100644 --- a/libyul/backends/evm/OptimizedEVMCodeTransform.cpp +++ b/libyul/backends/evm/OptimizedEVMCodeTransform.cpp @@ -23,6 +23,7 @@ #include +#include #include #include @@ -48,7 +49,7 @@ std::vector OptimizedEVMCodeTransform::run( ) { std::unique_ptr dfg = ControlFlowGraphBuilder::build(_analysisInfo, _dialect, _block); - StackLayout stackLayout = StackLayoutGenerator::run(*dfg, !_dialect.eofVersion().has_value()); + StackLayout stackLayout = StackLayoutGenerator::run(*dfg, !_dialect.eofVersion().has_value(), _dialect.reachableStackDepth()); if (_dialect.eofVersion().has_value()) { @@ -229,7 +230,8 @@ OptimizedEVMCodeTransform::OptimizedEVMCodeTransform( } return functionLabels; }()), - m_simulateFunctionsWithJumps(_simulateFunctionsWithJumps) + m_simulateFunctionsWithJumps(_simulateFunctionsWithJumps), + m_reachableStackDepth(_dialect.reachableStackDepth()) { } @@ -285,11 +287,11 @@ void OptimizedEVMCodeTransform::createStackLayout(langutil::DebugData::ConstPtr { yulAssert(static_cast(m_stack.size()) == m_assembly.stackHeight(), ""); yulAssert(_i > 0 && _i < m_stack.size(), ""); - if (_i <= 16) - m_assembly.appendInstruction(evmasm::swapInstruction(_i)); + if (_i <= m_reachableStackDepth) + appendSwap(_i); else { - int deficit = static_cast(_i) - 16; + int deficit = static_cast(_i) - static_cast(m_reachableStackDepth); StackSlot const& deepSlot = m_stack.at(m_stack.size() - _i - 1); YulName varNameDeep = slotVariableName(deepSlot); YulName varNameTop = slotVariableName(m_stack.back()); @@ -310,22 +312,21 @@ void OptimizedEVMCodeTransform::createStackLayout(langutil::DebugData::ConstPtr [&](StackSlot const& _slot) { yulAssert(static_cast(m_stack.size()) == m_assembly.stackHeight(), ""); - // Dup the slot, if already on stack and reachable. if (auto depth = util::findOffset(m_stack | ranges::views::reverse, _slot)) { - if (*depth < 16) + if (*depth < m_reachableStackDepth) { - m_assembly.appendInstruction(evmasm::dupInstruction(static_cast(*depth + 1))); + appendDup(*depth + 1); return; } else if (!canBeFreelyGenerated(_slot)) { - int deficit = static_cast(*depth - 15); + int deficit = static_cast(*depth - (m_reachableStackDepth - 1)); YulName varName = slotVariableName(_slot); std::string msg = (varName.empty() ? "Slot " + stackSlotToString(_slot, m_dialect) : "Variable " + varName.str()) - + " is " + std::to_string(*depth - 15) + " too deep in the stack " + stackToString(m_stack, m_dialect); + + " is " + std::to_string(*depth - (m_reachableStackDepth - 1)) + " too deep in the stack " + stackToString(m_stack, m_dialect); m_stackErrors.emplace_back(StackTooDeepError( m_currentFunctionInfo ? m_currentFunctionInfo->function.name : YulName{}, varName, @@ -388,11 +389,34 @@ void OptimizedEVMCodeTransform::createStackLayout(langutil::DebugData::ConstPtr [&]() { m_assembly.appendInstruction(evmasm::Instruction::POP); - } + }, + m_reachableStackDepth ); yulAssert(m_assembly.stackHeight() == static_cast(m_stack.size()), ""); } +void OptimizedEVMCodeTransform::appendSwap(size_t _depth) +{ + if (_depth <= 16) + m_assembly.appendInstruction(evmasm::swapInstruction(static_cast(_depth))); + else + { + yulAssert(_depth <= m_reachableStackDepth); + m_assembly.appendSwapN(_depth); + } +} + +void OptimizedEVMCodeTransform::appendDup(size_t _depth) +{ + if (_depth <= 16) + m_assembly.appendInstruction(evmasm::dupInstruction(static_cast(_depth))); + else + { + yulAssert(_depth <= m_reachableStackDepth); + m_assembly.appendDupN(_depth); + } +} + void OptimizedEVMCodeTransform::operator()(CFG::BasicBlock const& _block) { // Assert that this is the first visit of the block and mark as generated. diff --git a/libyul/backends/evm/OptimizedEVMCodeTransform.h b/libyul/backends/evm/OptimizedEVMCodeTransform.h index 88ecc2967763..2cb251fba8d5 100644 --- a/libyul/backends/evm/OptimizedEVMCodeTransform.h +++ b/libyul/backends/evm/OptimizedEVMCodeTransform.h @@ -87,6 +87,9 @@ class OptimizedEVMCodeTransform /// Sets the source locations to the one in @a _debugData. void createStackLayout(langutil::DebugData::ConstPtr _debugData, Stack _targetStack); + void appendSwap(size_t _depth); + void appendDup(size_t _depth); + /// Generate code for the given block @a _block. /// Expects the current stack layout m_stack to be a stack layout that is compatible with the /// entry layout expected by the block. @@ -116,6 +119,7 @@ class OptimizedEVMCodeTransform std::vector m_stackErrors; /// True if it simulates functions with jumps. False otherwise. True for legacy bytecode bool m_simulateFunctionsWithJumps = true; + size_t const m_reachableStackDepth{}; }; } diff --git a/libyul/backends/evm/StackHelpers.h b/libyul/backends/evm/StackHelpers.h index 0fd238c4052d..c5d63847153a 100644 --- a/libyul/backends/evm/StackHelpers.h +++ b/libyul/backends/evm/StackHelpers.h @@ -56,7 +56,6 @@ inline std::string stackToString(Stack const& _stack, Dialect const& _dialect) } -// Abstraction of stack shuffling operations. Can be defined as actual concept once we switch to C++20. // Used as an interface for the stack shuffler below. // The shuffle operation class is expected to internally keep track of a current stack layout (the "source layout") // that the shuffler is supposed to shuffle to a fixed target stack layout. @@ -65,7 +64,6 @@ inline std::string stackToString(Stack const& _stack, Dialect const& _dialect) // in the interface below. // Based on that information the shuffler decides which is the next optimal operation to perform on the stack // and calls the corresponding entry point in the shuffling operations (swap, pushOrDupTarget or pop). -/* template concept ShuffleOperationConcept = requires(ShuffleOperations ops, size_t sourceOffset, size_t targetOffset, size_t depth) { // Returns true, iff the current slot at sourceOffset in source layout is a suitable slot at targetOffset. @@ -98,11 +96,13 @@ concept ShuffleOperationConcept = requires(ShuffleOperations ops, size_t sourceO { ops.pop() }; // Dups or pushes the slot that is supposed to end up at the given target offset. { ops.pushOrDupTarget(targetOffset) }; + // Maximum reachable depth with swaps and dups. + { ops.reachableStackDepth } -> std::convertible_to; }; -*/ + /// Helper class that can perform shuffling of a source stack layout to a target stack layout via /// abstracted shuffle operations. -template +template class Shuffler { public: @@ -128,10 +128,10 @@ class Shuffler static bool dupDeepSlotIfRequired(ShuffleOperations& _ops) { // Check if the stack is large enough for anything to potentially become unreachable. - if (_ops.sourceSize() < 15) + if (_ops.sourceSize() < (_ops.reachableStackDepth - 1)) return false; // Check whether any deep slot might still be needed later (i.e. we still need to reach it with a DUP or SWAP). - for (size_t sourceOffset: ranges::views::iota(0u, _ops.sourceSize() - 15)) + for (size_t sourceOffset: ranges::views::iota(0u, _ops.sourceSize() - (_ops.reachableStackDepth - 1))) { // This slot needs to be moved. if (!_ops.isCompatible(sourceOffset, sourceOffset)) @@ -256,10 +256,10 @@ class Shuffler ) { // We cannot swap that deep. - if (ops.sourceSize() - offset - 1 > 16) + if (ops.sourceSize() - offset - 1 > ops.reachableStackDepth) { // If there is a reachable slot to be removed, park the current top there. - for (size_t swapDepth: ranges::views::iota(1u, 17u) | ranges::views::reverse) + for (size_t swapDepth: ranges::views::iota(1u, ops.reachableStackDepth + 1u) | ranges::views::reverse) if (ops.sourceMultiplicity(ops.sourceSize() - 1 - swapDepth) < 0) { ops.swap(swapDepth); @@ -327,7 +327,7 @@ class Shuffler yulAssert(ops.sourceMultiplicity(i) == 0 && (ops.targetIsArbitrary(i) || ops.targetMultiplicity(i) == 0), ""); yulAssert(ops.isCompatible(sourceTop, sourceTop), ""); - auto swappableOffsets = ranges::views::iota(size > 17 ? size - 17 : 0u, size); + auto swappableOffsets = ranges::views::iota(size > ops.reachableStackDepth + 1u ? size - (ops.reachableStackDepth + 1u) : 0u, size); // If we find a lower slot that is out of position, but also compatible with the top, swap that up. for (size_t offset: swappableOffsets) @@ -431,7 +431,14 @@ class Multiplicity /// its argument to the stack top. /// @a _pop is a function with signature void() that is called when the top most slot is popped. template -void createStackLayout(Stack& _currentStack, Stack const& _targetStack, Swap _swap, PushOrDup _pushOrDup, Pop _pop) +void createStackLayout( + Stack& _currentStack, + Stack const& _targetStack, + Swap _swap, + PushOrDup _pushOrDup, + Pop _pop, + size_t _reachableStackDepth +) { struct ShuffleOperations { @@ -441,18 +448,21 @@ void createStackLayout(Stack& _currentStack, Stack const& _targetStack, Swap _sw PushOrDup pushOrDupCallback; Pop popCallback; Multiplicity multiplicity; + size_t reachableStackDepth; ShuffleOperations( Stack& _currentStack, Stack const& _targetStack, Swap _swap, PushOrDup _pushOrDup, - Pop _pop + Pop _pop, + size_t _reachableStackDepth ): currentStack(_currentStack), targetStack(_targetStack), swapCallback(_swap), pushOrDupCallback(_pushOrDup), - popCallback(_pop) + popCallback(_pop), + reachableStackDepth(_reachableStackDepth) { for (auto const& slot: currentStack) --multiplicity[slot]; @@ -499,7 +509,7 @@ void createStackLayout(Stack& _currentStack, Stack const& _targetStack, Swap _sw } }; - Shuffler::shuffle(_currentStack, _targetStack, _swap, _pushOrDup, _pop); + Shuffler::shuffle(_currentStack, _targetStack, _swap, _pushOrDup, _pop, _reachableStackDepth); yulAssert(_currentStack.size() == _targetStack.size(), ""); for (auto&& [current, target]: ranges::zip_view(_currentStack, _targetStack)) diff --git a/libyul/backends/evm/StackLayoutGenerator.cpp b/libyul/backends/evm/StackLayoutGenerator.cpp index ecaa4198bd52..6abb1bb9fa1b 100644 --- a/libyul/backends/evm/StackLayoutGenerator.cpp +++ b/libyul/backends/evm/StackLayoutGenerator.cpp @@ -45,28 +45,47 @@ using namespace solidity; using namespace solidity::yul; -StackLayout StackLayoutGenerator::run(CFG const& _cfg, bool _simulateFunctionsWithJumps) +StackLayout StackLayoutGenerator::run(CFG const& _cfg, bool _simulateFunctionsWithJumps, size_t _reachableStackDepth) { StackLayout stackLayout{{}, {}}; - StackLayoutGenerator{stackLayout, nullptr, _simulateFunctionsWithJumps}.processEntryPoint(*_cfg.entry); + StackLayoutGenerator{ + stackLayout, + nullptr, + _simulateFunctionsWithJumps, + _reachableStackDepth + }.processEntryPoint(*_cfg.entry); for (auto& functionInfo: _cfg.functionInfo | ranges::views::values) - StackLayoutGenerator{stackLayout, &functionInfo, _simulateFunctionsWithJumps}.processEntryPoint(*functionInfo.entry, &functionInfo); + StackLayoutGenerator{ + stackLayout, + &functionInfo, + _simulateFunctionsWithJumps, + _reachableStackDepth + }.processEntryPoint(*functionInfo.entry, &functionInfo); return stackLayout; } -std::map> StackLayoutGenerator::reportStackTooDeep(CFG const& _cfg, bool _simulateFunctionsWithJumps) +std::map> StackLayoutGenerator::reportStackTooDeep( + CFG const& _cfg, + bool _simulateFunctionsWithJumps, + size_t _reachableStackDepth +) { std::map> stackTooDeepErrors; - stackTooDeepErrors[YulName{}] = reportStackTooDeep(_cfg, YulName{}, _simulateFunctionsWithJumps); + stackTooDeepErrors[YulName{}] = reportStackTooDeep(_cfg, YulName{}, _simulateFunctionsWithJumps, _reachableStackDepth); for (auto const& function: _cfg.functions) - if (auto errors = reportStackTooDeep(_cfg, function->name, _simulateFunctionsWithJumps); !errors.empty()) + if (auto errors = reportStackTooDeep(_cfg, function->name, _simulateFunctionsWithJumps, _reachableStackDepth); !errors.empty()) stackTooDeepErrors[function->name] = std::move(errors); return stackTooDeepErrors; } -std::vector StackLayoutGenerator::reportStackTooDeep(CFG const& _cfg, YulName _functionName, bool _simulateFunctionsWithJumps) +std::vector StackLayoutGenerator::reportStackTooDeep( + CFG const& _cfg, + YulName _functionName, + bool _simulateFunctionsWithJumps, + size_t _reachableStackDepth +) { StackLayout stackLayout{{}, {}}; CFG::FunctionInfo const* functionInfo = nullptr; @@ -80,23 +99,33 @@ std::vector StackLayoutGenerator::reportStac yulAssert(functionInfo, "Function not found."); } - StackLayoutGenerator generator{stackLayout, functionInfo, _simulateFunctionsWithJumps}; + StackLayoutGenerator generator{stackLayout, functionInfo, _simulateFunctionsWithJumps, _reachableStackDepth}; CFG::BasicBlock const* entry = functionInfo ? functionInfo->entry : _cfg.entry; generator.processEntryPoint(*entry); return generator.reportStackTooDeep(*entry); } -StackLayoutGenerator::StackLayoutGenerator(StackLayout& _layout, CFG::FunctionInfo const* _functionInfo, bool _simulateFunctionsWithJumps): +StackLayoutGenerator::StackLayoutGenerator( + StackLayout& _layout, + CFG::FunctionInfo const* _functionInfo, + bool _simulateFunctionsWithJumps, + size_t _reachableStackDepth +): m_layout(_layout), m_currentFunctionInfo(_functionInfo), - m_simulateFunctionsWithJumps(_simulateFunctionsWithJumps) + m_simulateFunctionsWithJumps(_simulateFunctionsWithJumps), + m_reachableStackDepth(_reachableStackDepth) { } namespace { /// @returns all stack too deep errors that would occur when shuffling @a _source to @a _target. -std::vector findStackTooDeep(Stack const& _source, Stack const& _target) +std::vector findStackTooDeep( + Stack const& _source, + Stack const& _target, + size_t _reachableStackDepth +) { Stack currentStack = _source; std::vector stackTooDeepErrors; @@ -113,9 +142,9 @@ std::vector findStackTooDeep(Stack const& _s _target, [&](unsigned _i) { - if (_i > 16) + if (_i > _reachableStackDepth) stackTooDeepErrors.emplace_back(StackLayoutGenerator::StackTooDeep{ - _i - 16, + _i - _reachableStackDepth, getVariableChoices(currentStack | ranges::views::take_last(_i + 1)) }); }, @@ -125,14 +154,15 @@ std::vector findStackTooDeep(Stack const& _s return; if ( auto depth = util::findOffset(currentStack | ranges::views::reverse, _slot); - depth && *depth >= 16 + depth && *depth >= _reachableStackDepth ) stackTooDeepErrors.emplace_back(StackLayoutGenerator::StackTooDeep{ - *depth - 15, + *depth - (_reachableStackDepth - 1), getVariableChoices(currentStack | ranges::views::take_last(*depth + 1)) }); }, - [&]() {} + [&]() {}, + _reachableStackDepth ); return stackTooDeepErrors; } @@ -142,7 +172,7 @@ std::vector findStackTooDeep(Stack const& _s /// If @a _generateSlotOnTheFly returns true for a slot, this slot should not occur in the ideal stack, but /// rather be generated on the fly during shuffling. template -Stack createIdealLayout(Stack const& _operationOutput, Stack const& _post, Callable _generateSlotOnTheFly) +Stack createIdealLayout(Stack const& _operationOutput, Stack const& _post, Callable _generateSlotOnTheFly, size_t _reachableStackDepth) { struct PreviousSlot { size_t slot; }; @@ -174,11 +204,13 @@ Stack createIdealLayout(Stack const& _operationOutput, Stack const& _post, Calla std::set outputs; Multiplicity multiplicity; Callable generateSlotOnTheFly; + size_t const reachableStackDepth; ShuffleOperations( std::vector>& _layout, Stack const& _post, - Callable _generateSlotOnTheFly - ): layout(_layout), post(_post), generateSlotOnTheFly(_generateSlotOnTheFly) + Callable _generateSlotOnTheFly, + size_t _reachableStackDepth + ): layout(_layout), post(_post), generateSlotOnTheFly(_generateSlotOnTheFly), reachableStackDepth(_reachableStackDepth) { for (auto const& layoutSlot: layout) if (StackSlot const* slot = std::get_if(&layoutSlot)) @@ -241,7 +273,7 @@ Stack createIdealLayout(Stack const& _operationOutput, Stack const& _post, Calla void pop() { layout.pop_back(); } void pushOrDupTarget(size_t _offset) { layout.push_back(post.at(_offset)); } }; - Shuffler::shuffle(layout, _post, _generateSlotOnTheFly); + Shuffler::shuffle(layout, _post, _generateSlotOnTheFly, _reachableStackDepth); // Now we can construct the ideal layout before the operation. // "layout" has shuffled the PreviousSlot{x} to new places using minimal operations to move the operation @@ -280,7 +312,7 @@ Stack StackLayoutGenerator::propagateStackThroughOperation(Stack _exitStack, CFG // Determine the ideal permutation of the slots in _exitLayout that are not operation outputs (and not to be // generated on the fly), s.t. shuffling the `stack + _operation.output` to _exitLayout is cheap. - Stack stack = createIdealLayout(_operation.output, _exitStack, generateSlotOnTheFly); + Stack stack = createIdealLayout(_operation.output, _exitStack, generateSlotOnTheFly, m_reachableStackDepth); // Make sure the resulting previous slots do not overlap with any assignmed variables. if (auto const* assignment = std::get_if(&_operation.operation)) @@ -304,7 +336,7 @@ Stack StackLayoutGenerator::propagateStackThroughOperation(Stack _exitStack, CFG stack.pop_back(); else if (auto offset = util::findOffset(stack | ranges::views::reverse | ranges::views::drop(1), stack.back())) { - if (*offset + 2 < 16) + if (*offset + 2 < m_reachableStackDepth) stack.pop_back(); else break; @@ -322,7 +354,7 @@ Stack StackLayoutGenerator::propagateStackThroughBlock(Stack _exitStack, CFG::Ba for (auto&& [idx, operation]: _block.operations | ranges::views::enumerate | ranges::views::reverse) { Stack newStack = propagateStackThroughOperation(stack, operation, _aggressiveStackCompression); - if (!_aggressiveStackCompression && !findStackTooDeep(newStack, stack).empty()) + if (!_aggressiveStackCompression && !findStackTooDeep(newStack, stack, m_reachableStackDepth).empty()) // If we had stack errors, run again with aggressive stack compression. return propagateStackThroughBlock(std::move(_exitStack), _block, true); stack = std::move(newStack); @@ -443,7 +475,8 @@ std::optional StackLayoutGenerator::getExitLayoutOrStageDependencies( // If the current iteration has already visited both jump targets, start from its entry layout. Stack stack = combineStack( m_layout.blockInfos.at(_conditionalJump.zero).entryLayout, - m_layout.blockInfos.at(_conditionalJump.nonZero).entryLayout + m_layout.blockInfos.at(_conditionalJump.nonZero).entryLayout, + m_reachableStackDepth ); // Additionally, the jump condition has to be at the stack top at exit. stack.emplace_back(_conditionalJump.condition); @@ -546,7 +579,7 @@ void StackLayoutGenerator::stitchConditionalJumps(CFG::BasicBlock const& _block) }); } -Stack StackLayoutGenerator::combineStack(Stack const& _stack1, Stack const& _stack2) +Stack StackLayoutGenerator::combineStack(Stack const& _stack1, Stack const& _stack2, size_t _reachableStackDepth) { // TODO: it would be nicer to replace this by a constructive algorithm. // Currently it uses a reduced version of the Heap Algorithm to partly brute-force, which seems @@ -564,9 +597,9 @@ Stack StackLayoutGenerator::combineStack(Stack const& _stack1, Stack const& _sta Stack stack2Tail = _stack2 | ranges::views::drop(commonPrefix.size()) | ranges::to; if (stack1Tail.empty()) - return commonPrefix + compressStack(stack2Tail); + return commonPrefix + compressStack(stack2Tail, _reachableStackDepth); if (stack2Tail.empty()) - return commonPrefix + compressStack(stack1Tail); + return commonPrefix + compressStack(stack1Tail, _reachableStackDepth); Stack candidate; for (auto slot: stack1Tail) @@ -582,18 +615,18 @@ Stack StackLayoutGenerator::combineStack(Stack const& _stack1, Stack const& _sta auto evaluate = [&](Stack const& _candidate) -> size_t { size_t numOps = 0; Stack testStack = _candidate; - auto swap = [&](unsigned _swapDepth) { ++numOps; if (_swapDepth > 16) numOps += 1000; }; + auto swap = [&](unsigned _swapDepth) { ++numOps; if (_swapDepth > _reachableStackDepth) numOps += 1000; }; auto dupOrPush = [&](StackSlot const& _slot) { if (canBeFreelyGenerated(_slot)) return; auto depth = util::findOffset(ranges::concat_view(commonPrefix, testStack) | ranges::views::reverse, _slot); - if (depth && *depth >= 16) + if (depth && *depth >= _reachableStackDepth) numOps += 1000; }; - createStackLayout(testStack, stack1Tail, swap, dupOrPush, [&](){}); + createStackLayout(testStack, stack1Tail, swap, dupOrPush, [&](){}, _reachableStackDepth); testStack = _candidate; - createStackLayout(testStack, stack2Tail, swap, dupOrPush, [&](){}); + createStackLayout(testStack, stack2Tail, swap, dupOrPush, [&](){}, _reachableStackDepth); return numOps; }; @@ -644,7 +677,7 @@ std::vector StackLayoutGenerator::reportStac { Stack& operationEntry = m_layout.operationEntryLayout.at(&operation); - stackTooDeepErrors += findStackTooDeep(currentStack, operationEntry); + stackTooDeepErrors += findStackTooDeep(currentStack, operationEntry, m_reachableStackDepth); currentStack = operationEntry; for (size_t i = 0; i < operation.input.size(); i++) currentStack.pop_back(); @@ -658,7 +691,7 @@ std::vector StackLayoutGenerator::reportStac [&](CFG::BasicBlock::Jump const& _jump) { Stack const& targetLayout = m_layout.blockInfos.at(_jump.target).entryLayout; - stackTooDeepErrors += findStackTooDeep(currentStack, targetLayout); + stackTooDeepErrors += findStackTooDeep(currentStack, targetLayout, m_reachableStackDepth); if (!_jump.backwards) _addChild(_jump.target); @@ -669,7 +702,7 @@ std::vector StackLayoutGenerator::reportStac m_layout.blockInfos.at(_conditionalJump.zero).entryLayout, m_layout.blockInfos.at(_conditionalJump.nonZero).entryLayout }) - stackTooDeepErrors += findStackTooDeep(currentStack, targetLayout); + stackTooDeepErrors += findStackTooDeep(currentStack, targetLayout, m_reachableStackDepth); _addChild(_conditionalJump.zero); _addChild(_conditionalJump.nonZero); @@ -681,7 +714,7 @@ std::vector StackLayoutGenerator::reportStac return stackTooDeepErrors; } -Stack StackLayoutGenerator::compressStack(Stack _stack) +Stack StackLayoutGenerator::compressStack(Stack _stack, size_t _reachableStackDepth) { std::optional firstDupOffset; do @@ -699,7 +732,7 @@ Stack StackLayoutGenerator::compressStack(Stack _stack) break; } else if (auto dupDepth = util::findOffset(_stack | ranges::views::reverse | ranges::views::drop(depth + 1), slot)) - if (depth + *dupDepth <= 16) + if (depth + *dupDepth <= _reachableStackDepth) { firstDupOffset = _stack.size() - depth - 1; break; @@ -746,10 +779,10 @@ void StackLayoutGenerator::fillInJunk(CFG::BasicBlock const& _block, CFG::Functi size_t opGas = 0; auto swap = [&](unsigned _swapDepth) { - if (_swapDepth > 16) + if (_swapDepth > m_reachableStackDepth) opGas += 1000; else - opGas += evmasm::GasMeter::runGas(evmasm::swapInstruction(_swapDepth), langutil::EVMVersion()); + opGas += evmasm::GasMeter::swapGas(_swapDepth, langutil::EVMVersion{}); }; auto dupOrPush = [&](StackSlot const& _slot) { @@ -759,8 +792,8 @@ void StackLayoutGenerator::fillInJunk(CFG::BasicBlock const& _block, CFG::Functi { if (auto depth = util::findOffset(_source | ranges::views::reverse, _slot)) { - if (*depth < 16) - opGas += evmasm::GasMeter::runGas(evmasm::dupInstruction(static_cast(*depth + 1)), langutil::EVMVersion()); + if (*depth < m_reachableStackDepth) + opGas += evmasm::GasMeter::dupGas(*depth + 1, langutil::EVMVersion{}); else opGas += 1000; } @@ -777,7 +810,7 @@ void StackLayoutGenerator::fillInJunk(CFG::BasicBlock const& _block, CFG::Functi } }; auto pop = [&]() { opGas += evmasm::GasMeter::runGas(evmasm::Instruction::POP,langutil::EVMVersion()); }; - createStackLayout(_source, _target, swap, dupOrPush, pop); + createStackLayout(_source, _target, swap, dupOrPush, pop, m_reachableStackDepth); return opGas; }; /// @returns the number of junk slots to be prepended to @a _targetLayout for an optimal transition from diff --git a/libyul/backends/evm/StackLayoutGenerator.h b/libyul/backends/evm/StackLayoutGenerator.h index 44cbbd43a4b3..9626c7ad1c77 100644 --- a/libyul/backends/evm/StackLayoutGenerator.h +++ b/libyul/backends/evm/StackLayoutGenerator.h @@ -55,18 +55,32 @@ class StackLayoutGenerator std::vector variableChoices; }; - static StackLayout run(CFG const& _cfg, bool _simulateFunctionsWithJumps); + static StackLayout run(CFG const& _cfg, bool _simulateFunctionsWithJumps, size_t _reachableStackDepth); /// @returns a map from function names to the stack too deep errors occurring in that function. /// Requires @a _cfg to be a control flow graph generated from disambiguated Yul. /// The empty string is mapped to the stack too deep errors of the main entry point. - static std::map> reportStackTooDeep(CFG const& _cfg, bool _simulateFunctionsWithJumps); + static std::map> reportStackTooDeep( + CFG const& _cfg, + bool _simulateFunctionsWithJumps, + size_t _reachableStackDepth + ); /// @returns all stack too deep errors in the function named @a _functionName. /// Requires @a _cfg to be a control flow graph generated from disambiguated Yul. /// If @a _functionName is empty, the stack too deep errors of the main entry point are reported instead. - static std::vector reportStackTooDeep(CFG const& _cfg, YulName _functionName, bool _simulateFunctionsWithJumps); + static std::vector reportStackTooDeep( + CFG const& _cfg, + YulName _functionName, + bool _simulateFunctionsWithJumps, + size_t _reachableStackDepth + ); private: - StackLayoutGenerator(StackLayout& _context, CFG::FunctionInfo const* _functionInfo, bool _simulateFunctionsWithJumps); + StackLayoutGenerator( + StackLayout& _context, + CFG::FunctionInfo const* _functionInfo, + bool _simulateFunctionsWithJumps, + size_t _reachableStackDepth + ); /// @returns the optimal entry stack layout, s.t. @a _operation can be applied to it and /// the result can be transformed to @a _exitStack with minimal stack shuffling. @@ -100,7 +114,7 @@ class StackLayoutGenerator /// Calculates the ideal stack layout, s.t. both @a _stack1 and @a _stack2 can be achieved with minimal /// stack shuffling when starting from the returned layout. - static Stack combineStack(Stack const& _stack1, Stack const& _stack2); + static Stack combineStack(Stack const& _stack1, Stack const& _stack2, size_t _reachableStackDepth); /// Walks through the CFG and reports any stack too deep errors that would occur when generating code for it /// without countermeasures. @@ -109,7 +123,7 @@ class StackLayoutGenerator /// @returns a copy of @a _stack stripped of all duplicates and slots that can be freely generated. /// Attempts to create a layout that requires a minimal amount of operations to reconstruct the original /// stack @a _stack. - static Stack compressStack(Stack _stack); + static Stack compressStack(Stack _stack, size_t _reachableStackDepth); //// Fills in junk when entering branches that do not need a clean stack in case the result is cheaper. void fillInJunk(CFG::BasicBlock const& _block, CFG::FunctionInfo const* _functionInfo = nullptr); @@ -118,6 +132,7 @@ class StackLayoutGenerator CFG::FunctionInfo const* m_currentFunctionInfo = nullptr; /// True if it simulates functions with jumps. False otherwise. True for legacy bytecode bool m_simulateFunctionsWithJumps = true; + size_t const m_reachableStackDepth{}; }; } diff --git a/libyul/optimiser/StackCompressor.cpp b/libyul/optimiser/StackCompressor.cpp index ae91716e5385..1dac1a66fe21 100644 --- a/libyul/optimiser/StackCompressor.cpp +++ b/libyul/optimiser/StackCompressor.cpp @@ -249,6 +249,7 @@ std::tuple StackCompressor::run( ); bool usesOptimizedCodeGenerator = false; bool simulateFunctionsWithJumps = true; + size_t reachableStackDepth = 16; if (auto evmDialect = dynamic_cast(_object.dialect())) { usesOptimizedCodeGenerator = @@ -256,6 +257,7 @@ std::tuple StackCompressor::run( evmDialect->evmVersion().canOverchargeGasForCall() && evmDialect->providesObjectAccess(); simulateFunctionsWithJumps = !evmDialect->eofVersion().has_value(); + reachableStackDepth = evmDialect->reachableStackDepth(); } bool allowMSizeOptimization = !MSizeFinder::containsMSize(*_object.dialect(), _object.code()->root()); Block astRoot = std::get(ASTCopier{}(_object.code()->root())); @@ -270,7 +272,7 @@ std::tuple StackCompressor::run( eliminateVariablesOptimizedCodegen( *_object.dialect(), astRoot, - StackLayoutGenerator::reportStackTooDeep(*cfg, simulateFunctionsWithJumps), + StackLayoutGenerator::reportStackTooDeep(*cfg, simulateFunctionsWithJumps, reachableStackDepth), allowMSizeOptimization ); } diff --git a/libyul/optimiser/StackLimitEvader.cpp b/libyul/optimiser/StackLimitEvader.cpp index 766cd4928447..d62b3e93542f 100644 --- a/libyul/optimiser/StackLimitEvader.cpp +++ b/libyul/optimiser/StackLimitEvader.cpp @@ -141,7 +141,7 @@ Block StackLimitEvader::run( _object.summarizeStructure() ); std::unique_ptr cfg = ControlFlowGraphBuilder::build(analysisInfo, *evmDialect, astRoot); - run(_context, astRoot, StackLayoutGenerator::reportStackTooDeep(*cfg, !evmDialect->eofVersion().has_value())); + run(_context, astRoot, StackLayoutGenerator::reportStackTooDeep(*cfg, !evmDialect->eofVersion().has_value(), evmDialect->reachableStackDepth())); } else { diff --git a/test/libyul/StackLayoutGeneratorTest.cpp b/test/libyul/StackLayoutGeneratorTest.cpp index 0db063740006..841872933b9a 100644 --- a/test/libyul/StackLayoutGeneratorTest.cpp +++ b/test/libyul/StackLayoutGeneratorTest.cpp @@ -233,10 +233,14 @@ TestCase::TestResult StackLayoutGeneratorTest::run(std::ostream& _stream, std::s ); bool simulateFunctionsWithJumps = true; + size_t reachableStackDepth = 16; if (auto const* evmDialect = dynamic_cast(&yulStack.dialect())) + { simulateFunctionsWithJumps = !evmDialect->eofVersion().has_value(); + reachableStackDepth = evmDialect->reachableStackDepth(); + } - StackLayout stackLayout = StackLayoutGenerator::run(*cfg, simulateFunctionsWithJumps); + StackLayout stackLayout = StackLayoutGenerator::run(*cfg, simulateFunctionsWithJumps, reachableStackDepth); output << "digraph CFG {\nnodesep=0.7;\nnode[shape=box];\n\n"; StackLayoutPrinter printer{output, stackLayout, yulStack.dialect()}; diff --git a/test/libyul/StackShufflingTest.cpp b/test/libyul/StackShufflingTest.cpp index 258bc9204aa5..a58510a417e9 100644 --- a/test/libyul/StackShufflingTest.cpp +++ b/test/libyul/StackShufflingTest.cpp @@ -174,7 +174,8 @@ TestCase::TestResult StackShufflingTest::run(std::ostream& _stream, std::string [&](){ // pop output << stackToString(m_sourceStack, dialect) << std::endl; output << "POP" << std::endl; - } + }, + 16u // TODO: make it a test setting ); output << stackToString(m_sourceStack, dialect) << std::endl; From 44c0697fce86c5352ca491a498ea7d9fcf8adb32 Mon Sep 17 00:00:00 2001 From: Daniel Kirchner Date: Mon, 17 Feb 2025 18:31:20 +0100 Subject: [PATCH 0828/1022] Test cases for SWAPN, DUPN and related stack shuffling. --- test/libyul/StackLayoutGeneratorTest.cpp | 11 +- test/libyul/StackShufflingTest.cpp | 18 +- test/libyul/StackShufflingTest.h | 2 + test/libyul/evmCodeTransform/eof_dup256.yul | 2595 +++++++++++++++ test/libyul/evmCodeTransform/eof_swap17.yul | 229 ++ test/libyul/evmCodeTransform/eof_swap256.yul | 2839 +++++++++++++++++ .../pop_early_to_avoid_swap17.stack | 12 + test/libyul/yulStackShuffling/swap17.stack | 13 + .../libyul/yulStackShuffling/swap_cycle.stack | 1 + 9 files changed, 5712 insertions(+), 8 deletions(-) create mode 100644 test/libyul/evmCodeTransform/eof_dup256.yul create mode 100644 test/libyul/evmCodeTransform/eof_swap17.yul create mode 100644 test/libyul/evmCodeTransform/eof_swap256.yul create mode 100644 test/libyul/yulStackShuffling/pop_early_to_avoid_swap17.stack create mode 100644 test/libyul/yulStackShuffling/swap17.stack diff --git a/test/libyul/StackLayoutGeneratorTest.cpp b/test/libyul/StackLayoutGeneratorTest.cpp index 841872933b9a..86fd6184e26b 100644 --- a/test/libyul/StackLayoutGeneratorTest.cpp +++ b/test/libyul/StackLayoutGeneratorTest.cpp @@ -232,13 +232,10 @@ TestCase::TestResult StackLayoutGeneratorTest::run(std::ostream& _stream, std::s yulStack.parserResult()->code()->root() ); - bool simulateFunctionsWithJumps = true; - size_t reachableStackDepth = 16; - if (auto const* evmDialect = dynamic_cast(&yulStack.dialect())) - { - simulateFunctionsWithJumps = !evmDialect->eofVersion().has_value(); - reachableStackDepth = evmDialect->reachableStackDepth(); - } + auto const* evmDialect = dynamic_cast(&yulStack.dialect()); + solAssert(evmDialect, "StackLayoutGenerator can only be run on EVM dialects."); + bool simulateFunctionsWithJumps = !evmDialect->eofVersion().has_value(); + size_t reachableStackDepth = evmDialect->reachableStackDepth(); StackLayout stackLayout = StackLayoutGenerator::run(*cfg, simulateFunctionsWithJumps, reachableStackDepth); diff --git a/test/libyul/StackShufflingTest.cpp b/test/libyul/StackShufflingTest.cpp index a58510a417e9..58ea124fb1df 100644 --- a/test/libyul/StackShufflingTest.cpp +++ b/test/libyul/StackShufflingTest.cpp @@ -24,6 +24,7 @@ #include #include +#include using namespace solidity::test; using namespace solidity::util; @@ -136,10 +137,20 @@ bool StackShufflingTest::parse(std::string const& _source) StackShufflingTest::StackShufflingTest(std::string const& _filename): TestCase(_filename) { + processSettings(); m_source = m_reader.source(); m_expectation = m_reader.simpleExpectations(); } +void StackShufflingTest::processSettings() +{ + std::string depthString = m_reader.stringSetting("maximumStackDepth", "16"); + std::optional depth = toUnsignedInt(depthString); + if (!depth.has_value()) + BOOST_THROW_EXCEPTION(std::runtime_error{"Invalid maximum stack depth: \"" + depthString + "\""}); + m_maximumStackDepth = *depth; +} + TestCase::TestResult StackShufflingTest::run(std::ostream& _stream, std::string const& _linePrefix, bool _formatted) { auto const& dialect = CommonOptions::get().evmDialect(); @@ -150,16 +161,19 @@ TestCase::TestResult StackShufflingTest::run(std::ostream& _stream, std::string } std::ostringstream output; + size_t operations = 0; createStackLayout( m_sourceStack, m_targetStack, [&](unsigned _swapDepth) // swap { + ++operations; output << stackToString(m_sourceStack, dialect) << std::endl; output << "SWAP" << _swapDepth << std::endl; }, [&](StackSlot const& _slot) // dupOrPush { + ++operations; output << stackToString(m_sourceStack, dialect) << std::endl; if (canBeFreelyGenerated(_slot)) output << "PUSH " << stackSlotToString(_slot, dialect) << std::endl; @@ -172,13 +186,15 @@ TestCase::TestResult StackShufflingTest::run(std::ostream& _stream, std::string } }, [&](){ // pop + ++operations; output << stackToString(m_sourceStack, dialect) << std::endl; output << "POP" << std::endl; }, - 16u // TODO: make it a test setting + m_maximumStackDepth ); output << stackToString(m_sourceStack, dialect) << std::endl; + output << operations << " operations" << std::endl; m_obtainedResult = output.str(); return checkResult(_stream, _linePrefix, _formatted); diff --git a/test/libyul/StackShufflingTest.h b/test/libyul/StackShufflingTest.h index 2e2dd12ad325..5485ed081805 100644 --- a/test/libyul/StackShufflingTest.h +++ b/test/libyul/StackShufflingTest.h @@ -37,8 +37,10 @@ class StackShufflingTest: public TestCase explicit StackShufflingTest(std::string const& _filename); TestResult run(std::ostream& _stream, std::string const& _linePrefix = "", bool const _formatted = false) override; private: + void processSettings(); bool parse(std::string const& _source); + size_t m_maximumStackDepth{}; Stack m_sourceStack; Stack m_targetStack; std::map m_functions; diff --git a/test/libyul/evmCodeTransform/eof_dup256.yul b/test/libyul/evmCodeTransform/eof_dup256.yul new file mode 100644 index 000000000000..a345c7b6d63d --- /dev/null +++ b/test/libyul/evmCodeTransform/eof_dup256.yul @@ -0,0 +1,2595 @@ +object "main" { + code { + let v0 := calldataload(0) + let v1 := calldataload(1) + let v2 := calldataload(2) + let v3 := calldataload(3) + let v4 := calldataload(4) + let v5 := calldataload(5) + let v6 := calldataload(6) + let v7 := calldataload(7) + let v8 := calldataload(8) + let v9 := calldataload(9) + let v10 := calldataload(10) + let v11 := calldataload(11) + let v12 := calldataload(12) + let v13 := calldataload(13) + let v14 := calldataload(14) + let v15 := calldataload(15) + let v16 := calldataload(16) + let v17 := calldataload(17) + let v18 := calldataload(18) + let v19 := calldataload(19) + let v20 := calldataload(20) + let v21 := calldataload(21) + let v22 := calldataload(22) + let v23 := calldataload(23) + let v24 := calldataload(24) + let v25 := calldataload(25) + let v26 := calldataload(26) + let v27 := calldataload(27) + let v28 := calldataload(28) + let v29 := calldataload(29) + let v30 := calldataload(30) + let v31 := calldataload(31) + let v32 := calldataload(32) + let v33 := calldataload(33) + let v34 := calldataload(34) + let v35 := calldataload(35) + let v36 := calldataload(36) + let v37 := calldataload(37) + let v38 := calldataload(38) + let v39 := calldataload(39) + let v40 := calldataload(40) + let v41 := calldataload(41) + let v42 := calldataload(42) + let v43 := calldataload(43) + let v44 := calldataload(44) + let v45 := calldataload(45) + let v46 := calldataload(46) + let v47 := calldataload(47) + let v48 := calldataload(48) + let v49 := calldataload(49) + let v50 := calldataload(50) + let v51 := calldataload(51) + let v52 := calldataload(52) + let v53 := calldataload(53) + let v54 := calldataload(54) + let v55 := calldataload(55) + let v56 := calldataload(56) + let v57 := calldataload(57) + let v58 := calldataload(58) + let v59 := calldataload(59) + let v60 := calldataload(60) + let v61 := calldataload(61) + let v62 := calldataload(62) + let v63 := calldataload(63) + let v64 := calldataload(64) + let v65 := calldataload(65) + let v66 := calldataload(66) + let v67 := calldataload(67) + let v68 := calldataload(68) + let v69 := calldataload(69) + let v70 := calldataload(70) + let v71 := calldataload(71) + let v72 := calldataload(72) + let v73 := calldataload(73) + let v74 := calldataload(74) + let v75 := calldataload(75) + let v76 := calldataload(76) + let v77 := calldataload(77) + let v78 := calldataload(78) + let v79 := calldataload(79) + let v80 := calldataload(80) + let v81 := calldataload(81) + let v82 := calldataload(82) + let v83 := calldataload(83) + let v84 := calldataload(84) + let v85 := calldataload(85) + let v86 := calldataload(86) + let v87 := calldataload(87) + let v88 := calldataload(88) + let v89 := calldataload(89) + let v90 := calldataload(90) + let v91 := calldataload(91) + let v92 := calldataload(92) + let v93 := calldataload(93) + let v94 := calldataload(94) + let v95 := calldataload(95) + let v96 := calldataload(96) + let v97 := calldataload(97) + let v98 := calldataload(98) + let v99 := calldataload(99) + let v100 := calldataload(100) + let v101 := calldataload(101) + let v102 := calldataload(102) + let v103 := calldataload(103) + let v104 := calldataload(104) + let v105 := calldataload(105) + let v106 := calldataload(106) + let v107 := calldataload(107) + let v108 := calldataload(108) + let v109 := calldataload(109) + let v110 := calldataload(110) + let v111 := calldataload(111) + let v112 := calldataload(112) + let v113 := calldataload(113) + let v114 := calldataload(114) + let v115 := calldataload(115) + let v116 := calldataload(116) + let v117 := calldataload(117) + let v118 := calldataload(118) + let v119 := calldataload(119) + let v120 := calldataload(120) + let v121 := calldataload(121) + let v122 := calldataload(122) + let v123 := calldataload(123) + let v124 := calldataload(124) + let v125 := calldataload(125) + let v126 := calldataload(126) + let v127 := calldataload(127) + let v128 := calldataload(128) + let v129 := calldataload(129) + let v130 := calldataload(130) + let v131 := calldataload(131) + let v132 := calldataload(132) + let v133 := calldataload(133) + let v134 := calldataload(134) + let v135 := calldataload(135) + let v136 := calldataload(136) + let v137 := calldataload(137) + let v138 := calldataload(138) + let v139 := calldataload(139) + let v140 := calldataload(140) + let v141 := calldataload(141) + let v142 := calldataload(142) + let v143 := calldataload(143) + let v144 := calldataload(144) + let v145 := calldataload(145) + let v146 := calldataload(146) + let v147 := calldataload(147) + let v148 := calldataload(148) + let v149 := calldataload(149) + let v150 := calldataload(150) + let v151 := calldataload(151) + let v152 := calldataload(152) + let v153 := calldataload(153) + let v154 := calldataload(154) + let v155 := calldataload(155) + let v156 := calldataload(156) + let v157 := calldataload(157) + let v158 := calldataload(158) + let v159 := calldataload(159) + let v160 := calldataload(160) + let v161 := calldataload(161) + let v162 := calldataload(162) + let v163 := calldataload(163) + let v164 := calldataload(164) + let v165 := calldataload(165) + let v166 := calldataload(166) + let v167 := calldataload(167) + let v168 := calldataload(168) + let v169 := calldataload(169) + let v170 := calldataload(170) + let v171 := calldataload(171) + let v172 := calldataload(172) + let v173 := calldataload(173) + let v174 := calldataload(174) + let v175 := calldataload(175) + let v176 := calldataload(176) + let v177 := calldataload(177) + let v178 := calldataload(178) + let v179 := calldataload(179) + let v180 := calldataload(180) + let v181 := calldataload(181) + let v182 := calldataload(182) + let v183 := calldataload(183) + let v184 := calldataload(184) + let v185 := calldataload(185) + let v186 := calldataload(186) + let v187 := calldataload(187) + let v188 := calldataload(188) + let v189 := calldataload(189) + let v190 := calldataload(190) + let v191 := calldataload(191) + let v192 := calldataload(192) + let v193 := calldataload(193) + let v194 := calldataload(194) + let v195 := calldataload(195) + let v196 := calldataload(196) + let v197 := calldataload(197) + let v198 := calldataload(198) + let v199 := calldataload(199) + let v200 := calldataload(200) + let v201 := calldataload(201) + let v202 := calldataload(202) + let v203 := calldataload(203) + let v204 := calldataload(204) + let v205 := calldataload(205) + let v206 := calldataload(206) + let v207 := calldataload(207) + let v208 := calldataload(208) + let v209 := calldataload(209) + let v210 := calldataload(210) + let v211 := calldataload(211) + let v212 := calldataload(212) + let v213 := calldataload(213) + let v214 := calldataload(214) + let v215 := calldataload(215) + let v216 := calldataload(216) + let v217 := calldataload(217) + let v218 := calldataload(218) + let v219 := calldataload(219) + let v220 := calldataload(220) + let v221 := calldataload(221) + let v222 := calldataload(222) + let v223 := calldataload(223) + let v224 := calldataload(224) + let v225 := calldataload(225) + let v226 := calldataload(226) + let v227 := calldataload(227) + let v228 := calldataload(228) + let v229 := calldataload(229) + let v230 := calldataload(230) + let v231 := calldataload(231) + let v232 := calldataload(232) + let v233 := calldataload(233) + let v234 := calldataload(234) + let v235 := calldataload(235) + let v236 := calldataload(236) + let v237 := calldataload(237) + let v238 := calldataload(238) + let v239 := calldataload(239) + let v240 := calldataload(240) + let v241 := calldataload(241) + let v242 := calldataload(242) + let v243 := calldataload(243) + let v244 := calldataload(244) + let v245 := calldataload(245) + let v246 := calldataload(246) + let v247 := calldataload(247) + let v248 := calldataload(248) + let v249 := calldataload(249) + let v250 := calldataload(250) + let v251 := calldataload(251) + let v252 := calldataload(252) + let v253 := calldataload(253) + let v254 := calldataload(254) + let v255 := calldataload(255) + // The conditional jump splits basic blocks and prevents us from moving the resulting dupn{256} further up. + // At the time of writing, the current code transform would do that and turn it into a less-deep dup otherwise. + if calldataload(256) { revert(0,0) } + sstore(256, v0) + sstore(255, v255) + sstore(254, v254) + sstore(253, v253) + sstore(252, v252) + sstore(251, v251) + sstore(250, v250) + sstore(249, v249) + sstore(248, v248) + sstore(247, v247) + sstore(246, v246) + sstore(245, v245) + sstore(244, v244) + sstore(243, v243) + sstore(242, v242) + sstore(241, v241) + sstore(240, v240) + sstore(239, v239) + sstore(238, v238) + sstore(237, v237) + sstore(236, v236) + sstore(235, v235) + sstore(234, v234) + sstore(233, v233) + sstore(232, v232) + sstore(231, v231) + sstore(230, v230) + sstore(229, v229) + sstore(228, v228) + sstore(227, v227) + sstore(226, v226) + sstore(225, v225) + sstore(224, v224) + sstore(223, v223) + sstore(222, v222) + sstore(221, v221) + sstore(220, v220) + sstore(219, v219) + sstore(218, v218) + sstore(217, v217) + sstore(216, v216) + sstore(215, v215) + sstore(214, v214) + sstore(213, v213) + sstore(212, v212) + sstore(211, v211) + sstore(210, v210) + sstore(209, v209) + sstore(208, v208) + sstore(207, v207) + sstore(206, v206) + sstore(205, v205) + sstore(204, v204) + sstore(203, v203) + sstore(202, v202) + sstore(201, v201) + sstore(200, v200) + sstore(199, v199) + sstore(198, v198) + sstore(197, v197) + sstore(196, v196) + sstore(195, v195) + sstore(194, v194) + sstore(193, v193) + sstore(192, v192) + sstore(191, v191) + sstore(190, v190) + sstore(189, v189) + sstore(188, v188) + sstore(187, v187) + sstore(186, v186) + sstore(185, v185) + sstore(184, v184) + sstore(183, v183) + sstore(182, v182) + sstore(181, v181) + sstore(180, v180) + sstore(179, v179) + sstore(178, v178) + sstore(177, v177) + sstore(176, v176) + sstore(175, v175) + sstore(174, v174) + sstore(173, v173) + sstore(172, v172) + sstore(171, v171) + sstore(170, v170) + sstore(169, v169) + sstore(168, v168) + sstore(167, v167) + sstore(166, v166) + sstore(165, v165) + sstore(164, v164) + sstore(163, v163) + sstore(162, v162) + sstore(161, v161) + sstore(160, v160) + sstore(159, v159) + sstore(158, v158) + sstore(157, v157) + sstore(156, v156) + sstore(155, v155) + sstore(154, v154) + sstore(153, v153) + sstore(152, v152) + sstore(151, v151) + sstore(150, v150) + sstore(149, v149) + sstore(148, v148) + sstore(147, v147) + sstore(146, v146) + sstore(145, v145) + sstore(144, v144) + sstore(143, v143) + sstore(142, v142) + sstore(141, v141) + sstore(140, v140) + sstore(139, v139) + sstore(138, v138) + sstore(137, v137) + sstore(136, v136) + sstore(135, v135) + sstore(134, v134) + sstore(133, v133) + sstore(132, v132) + sstore(131, v131) + sstore(130, v130) + sstore(129, v129) + sstore(128, v128) + sstore(127, v127) + sstore(126, v126) + sstore(125, v125) + sstore(124, v124) + sstore(123, v123) + sstore(122, v122) + sstore(121, v121) + sstore(120, v120) + sstore(119, v119) + sstore(118, v118) + sstore(117, v117) + sstore(116, v116) + sstore(115, v115) + sstore(114, v114) + sstore(113, v113) + sstore(112, v112) + sstore(111, v111) + sstore(110, v110) + sstore(109, v109) + sstore(108, v108) + sstore(107, v107) + sstore(106, v106) + sstore(105, v105) + sstore(104, v104) + sstore(103, v103) + sstore(102, v102) + sstore(101, v101) + sstore(100, v100) + sstore(99, v99) + sstore(98, v98) + sstore(97, v97) + sstore(96, v96) + sstore(95, v95) + sstore(94, v94) + sstore(93, v93) + sstore(92, v92) + sstore(91, v91) + sstore(90, v90) + sstore(89, v89) + sstore(88, v88) + sstore(87, v87) + sstore(86, v86) + sstore(85, v85) + sstore(84, v84) + sstore(83, v83) + sstore(82, v82) + sstore(81, v81) + sstore(80, v80) + sstore(79, v79) + sstore(78, v78) + sstore(77, v77) + sstore(76, v76) + sstore(75, v75) + sstore(74, v74) + sstore(73, v73) + sstore(72, v72) + sstore(71, v71) + sstore(70, v70) + sstore(69, v69) + sstore(68, v68) + sstore(67, v67) + sstore(66, v66) + sstore(65, v65) + sstore(64, v64) + sstore(63, v63) + sstore(62, v62) + sstore(61, v61) + sstore(60, v60) + sstore(59, v59) + sstore(58, v58) + sstore(57, v57) + sstore(56, v56) + sstore(55, v55) + sstore(54, v54) + sstore(53, v53) + sstore(52, v52) + sstore(51, v51) + sstore(50, v50) + sstore(49, v49) + sstore(48, v48) + sstore(47, v47) + sstore(46, v46) + sstore(45, v45) + sstore(44, v44) + sstore(43, v43) + sstore(42, v42) + sstore(41, v41) + sstore(40, v40) + sstore(39, v39) + sstore(38, v38) + sstore(37, v37) + sstore(36, v36) + sstore(35, v35) + sstore(34, v34) + sstore(33, v33) + sstore(32, v32) + sstore(31, v31) + sstore(30, v30) + sstore(29, v29) + sstore(28, v28) + sstore(27, v27) + sstore(26, v26) + sstore(25, v25) + sstore(24, v24) + sstore(23, v23) + sstore(22, v22) + sstore(21, v21) + sstore(20, v20) + sstore(19, v19) + sstore(18, v18) + sstore(17, v17) + sstore(16, v16) + sstore(15, v15) + sstore(14, v14) + sstore(13, v13) + sstore(12, v12) + sstore(11, v11) + sstore(10, v10) + sstore(9, v9) + sstore(8, v8) + sstore(7, v7) + sstore(6, v6) + sstore(5, v5) + sstore(4, v4) + sstore(3, v3) + sstore(2, v2) + sstore(1, v1) + sstore(0, v0) + } +} +// ==== +// bytecodeFormat: >=EOFv1 +// stackOptimization: true +// ---- +// /* "":58:59 */ +// 0x00 +// /* "":45:60 */ +// calldataload +// /* "":92:93 */ +// 0x01 +// /* "":79:94 */ +// calldataload +// /* "":126:127 */ +// 0x02 +// /* "":113:128 */ +// calldataload +// /* "":160:161 */ +// 0x03 +// /* "":147:162 */ +// calldataload +// /* "":194:195 */ +// 0x04 +// /* "":181:196 */ +// calldataload +// /* "":228:229 */ +// 0x05 +// /* "":215:230 */ +// calldataload +// /* "":262:263 */ +// 0x06 +// /* "":249:264 */ +// calldataload +// /* "":296:297 */ +// 0x07 +// /* "":283:298 */ +// calldataload +// /* "":330:331 */ +// 0x08 +// /* "":317:332 */ +// calldataload +// /* "":364:365 */ +// 0x09 +// /* "":351:366 */ +// calldataload +// /* "":399:401 */ +// 0x0a +// /* "":386:402 */ +// calldataload +// /* "":435:437 */ +// 0x0b +// /* "":422:438 */ +// calldataload +// /* "":471:473 */ +// 0x0c +// /* "":458:474 */ +// calldataload +// /* "":507:509 */ +// 0x0d +// /* "":494:510 */ +// calldataload +// /* "":543:545 */ +// 0x0e +// /* "":530:546 */ +// calldataload +// /* "":579:581 */ +// 0x0f +// /* "":566:582 */ +// calldataload +// /* "":615:617 */ +// 0x10 +// /* "":602:618 */ +// calldataload +// /* "":651:653 */ +// 0x11 +// /* "":638:654 */ +// calldataload +// /* "":687:689 */ +// 0x12 +// /* "":674:690 */ +// calldataload +// /* "":723:725 */ +// 0x13 +// /* "":710:726 */ +// calldataload +// /* "":759:761 */ +// 0x14 +// /* "":746:762 */ +// calldataload +// /* "":795:797 */ +// 0x15 +// /* "":782:798 */ +// calldataload +// /* "":831:833 */ +// 0x16 +// /* "":818:834 */ +// calldataload +// /* "":867:869 */ +// 0x17 +// /* "":854:870 */ +// calldataload +// /* "":903:905 */ +// 0x18 +// /* "":890:906 */ +// calldataload +// /* "":939:941 */ +// 0x19 +// /* "":926:942 */ +// calldataload +// /* "":975:977 */ +// 0x1a +// /* "":962:978 */ +// calldataload +// /* "":1011:1013 */ +// 0x1b +// /* "":998:1014 */ +// calldataload +// /* "":1047:1049 */ +// 0x1c +// /* "":1034:1050 */ +// calldataload +// /* "":1083:1085 */ +// 0x1d +// /* "":1070:1086 */ +// calldataload +// /* "":1119:1121 */ +// 0x1e +// /* "":1106:1122 */ +// calldataload +// /* "":1155:1157 */ +// 0x1f +// /* "":1142:1158 */ +// calldataload +// /* "":1191:1193 */ +// 0x20 +// /* "":1178:1194 */ +// calldataload +// /* "":1227:1229 */ +// 0x21 +// /* "":1214:1230 */ +// calldataload +// /* "":1263:1265 */ +// 0x22 +// /* "":1250:1266 */ +// calldataload +// /* "":1299:1301 */ +// 0x23 +// /* "":1286:1302 */ +// calldataload +// /* "":1335:1337 */ +// 0x24 +// /* "":1322:1338 */ +// calldataload +// /* "":1371:1373 */ +// 0x25 +// /* "":1358:1374 */ +// calldataload +// /* "":1407:1409 */ +// 0x26 +// /* "":1394:1410 */ +// calldataload +// /* "":1443:1445 */ +// 0x27 +// /* "":1430:1446 */ +// calldataload +// /* "":1479:1481 */ +// 0x28 +// /* "":1466:1482 */ +// calldataload +// /* "":1515:1517 */ +// 0x29 +// /* "":1502:1518 */ +// calldataload +// /* "":1551:1553 */ +// 0x2a +// /* "":1538:1554 */ +// calldataload +// /* "":1587:1589 */ +// 0x2b +// /* "":1574:1590 */ +// calldataload +// /* "":1623:1625 */ +// 0x2c +// /* "":1610:1626 */ +// calldataload +// /* "":1659:1661 */ +// 0x2d +// /* "":1646:1662 */ +// calldataload +// /* "":1695:1697 */ +// 0x2e +// /* "":1682:1698 */ +// calldataload +// /* "":1731:1733 */ +// 0x2f +// /* "":1718:1734 */ +// calldataload +// /* "":1767:1769 */ +// 0x30 +// /* "":1754:1770 */ +// calldataload +// /* "":1803:1805 */ +// 0x31 +// /* "":1790:1806 */ +// calldataload +// /* "":1839:1841 */ +// 0x32 +// /* "":1826:1842 */ +// calldataload +// /* "":1875:1877 */ +// 0x33 +// /* "":1862:1878 */ +// calldataload +// /* "":1911:1913 */ +// 0x34 +// /* "":1898:1914 */ +// calldataload +// /* "":1947:1949 */ +// 0x35 +// /* "":1934:1950 */ +// calldataload +// /* "":1983:1985 */ +// 0x36 +// /* "":1970:1986 */ +// calldataload +// /* "":2019:2021 */ +// 0x37 +// /* "":2006:2022 */ +// calldataload +// /* "":2055:2057 */ +// 0x38 +// /* "":2042:2058 */ +// calldataload +// /* "":2091:2093 */ +// 0x39 +// /* "":2078:2094 */ +// calldataload +// /* "":2127:2129 */ +// 0x3a +// /* "":2114:2130 */ +// calldataload +// /* "":2163:2165 */ +// 0x3b +// /* "":2150:2166 */ +// calldataload +// /* "":2199:2201 */ +// 0x3c +// /* "":2186:2202 */ +// calldataload +// /* "":2235:2237 */ +// 0x3d +// /* "":2222:2238 */ +// calldataload +// /* "":2271:2273 */ +// 0x3e +// /* "":2258:2274 */ +// calldataload +// /* "":2307:2309 */ +// 0x3f +// /* "":2294:2310 */ +// calldataload +// /* "":2343:2345 */ +// 0x40 +// /* "":2330:2346 */ +// calldataload +// /* "":2379:2381 */ +// 0x41 +// /* "":2366:2382 */ +// calldataload +// /* "":2415:2417 */ +// 0x42 +// /* "":2402:2418 */ +// calldataload +// /* "":2451:2453 */ +// 0x43 +// /* "":2438:2454 */ +// calldataload +// /* "":2487:2489 */ +// 0x44 +// /* "":2474:2490 */ +// calldataload +// /* "":2523:2525 */ +// 0x45 +// /* "":2510:2526 */ +// calldataload +// /* "":2559:2561 */ +// 0x46 +// /* "":2546:2562 */ +// calldataload +// /* "":2595:2597 */ +// 0x47 +// /* "":2582:2598 */ +// calldataload +// /* "":2631:2633 */ +// 0x48 +// /* "":2618:2634 */ +// calldataload +// /* "":2667:2669 */ +// 0x49 +// /* "":2654:2670 */ +// calldataload +// /* "":2703:2705 */ +// 0x4a +// /* "":2690:2706 */ +// calldataload +// /* "":2739:2741 */ +// 0x4b +// /* "":2726:2742 */ +// calldataload +// /* "":2775:2777 */ +// 0x4c +// /* "":2762:2778 */ +// calldataload +// /* "":2811:2813 */ +// 0x4d +// /* "":2798:2814 */ +// calldataload +// /* "":2847:2849 */ +// 0x4e +// /* "":2834:2850 */ +// calldataload +// /* "":2883:2885 */ +// 0x4f +// /* "":2870:2886 */ +// calldataload +// /* "":2919:2921 */ +// 0x50 +// /* "":2906:2922 */ +// calldataload +// /* "":2955:2957 */ +// 0x51 +// /* "":2942:2958 */ +// calldataload +// /* "":2991:2993 */ +// 0x52 +// /* "":2978:2994 */ +// calldataload +// /* "":3027:3029 */ +// 0x53 +// /* "":3014:3030 */ +// calldataload +// /* "":3063:3065 */ +// 0x54 +// /* "":3050:3066 */ +// calldataload +// /* "":3099:3101 */ +// 0x55 +// /* "":3086:3102 */ +// calldataload +// /* "":3135:3137 */ +// 0x56 +// /* "":3122:3138 */ +// calldataload +// /* "":3171:3173 */ +// 0x57 +// /* "":3158:3174 */ +// calldataload +// /* "":3207:3209 */ +// 0x58 +// /* "":3194:3210 */ +// calldataload +// /* "":3243:3245 */ +// 0x59 +// /* "":3230:3246 */ +// calldataload +// /* "":3279:3281 */ +// 0x5a +// /* "":3266:3282 */ +// calldataload +// /* "":3315:3317 */ +// 0x5b +// /* "":3302:3318 */ +// calldataload +// /* "":3351:3353 */ +// 0x5c +// /* "":3338:3354 */ +// calldataload +// /* "":3387:3389 */ +// 0x5d +// /* "":3374:3390 */ +// calldataload +// /* "":3423:3425 */ +// 0x5e +// /* "":3410:3426 */ +// calldataload +// /* "":3459:3461 */ +// 0x5f +// /* "":3446:3462 */ +// calldataload +// /* "":3495:3497 */ +// 0x60 +// /* "":3482:3498 */ +// calldataload +// /* "":3531:3533 */ +// 0x61 +// /* "":3518:3534 */ +// calldataload +// /* "":3567:3569 */ +// 0x62 +// /* "":3554:3570 */ +// calldataload +// /* "":3603:3605 */ +// 0x63 +// /* "":3590:3606 */ +// calldataload +// /* "":3640:3643 */ +// 0x64 +// /* "":3627:3644 */ +// calldataload +// /* "":3678:3681 */ +// 0x65 +// /* "":3665:3682 */ +// calldataload +// /* "":3716:3719 */ +// 0x66 +// /* "":3703:3720 */ +// calldataload +// /* "":3754:3757 */ +// 0x67 +// /* "":3741:3758 */ +// calldataload +// /* "":3792:3795 */ +// 0x68 +// /* "":3779:3796 */ +// calldataload +// /* "":3830:3833 */ +// 0x69 +// /* "":3817:3834 */ +// calldataload +// /* "":3868:3871 */ +// 0x6a +// /* "":3855:3872 */ +// calldataload +// /* "":3906:3909 */ +// 0x6b +// /* "":3893:3910 */ +// calldataload +// /* "":3944:3947 */ +// 0x6c +// /* "":3931:3948 */ +// calldataload +// /* "":3982:3985 */ +// 0x6d +// /* "":3969:3986 */ +// calldataload +// /* "":4020:4023 */ +// 0x6e +// /* "":4007:4024 */ +// calldataload +// /* "":4058:4061 */ +// 0x6f +// /* "":4045:4062 */ +// calldataload +// /* "":4096:4099 */ +// 0x70 +// /* "":4083:4100 */ +// calldataload +// /* "":4134:4137 */ +// 0x71 +// /* "":4121:4138 */ +// calldataload +// /* "":4172:4175 */ +// 0x72 +// /* "":4159:4176 */ +// calldataload +// /* "":4210:4213 */ +// 0x73 +// /* "":4197:4214 */ +// calldataload +// /* "":4248:4251 */ +// 0x74 +// /* "":4235:4252 */ +// calldataload +// /* "":4286:4289 */ +// 0x75 +// /* "":4273:4290 */ +// calldataload +// /* "":4324:4327 */ +// 0x76 +// /* "":4311:4328 */ +// calldataload +// /* "":4362:4365 */ +// 0x77 +// /* "":4349:4366 */ +// calldataload +// /* "":4400:4403 */ +// 0x78 +// /* "":4387:4404 */ +// calldataload +// /* "":4438:4441 */ +// 0x79 +// /* "":4425:4442 */ +// calldataload +// /* "":4476:4479 */ +// 0x7a +// /* "":4463:4480 */ +// calldataload +// /* "":4514:4517 */ +// 0x7b +// /* "":4501:4518 */ +// calldataload +// /* "":4552:4555 */ +// 0x7c +// /* "":4539:4556 */ +// calldataload +// /* "":4590:4593 */ +// 0x7d +// /* "":4577:4594 */ +// calldataload +// /* "":4628:4631 */ +// 0x7e +// /* "":4615:4632 */ +// calldataload +// /* "":4666:4669 */ +// 0x7f +// /* "":4653:4670 */ +// calldataload +// /* "":4704:4707 */ +// 0x80 +// /* "":4691:4708 */ +// calldataload +// /* "":4742:4745 */ +// 0x81 +// /* "":4729:4746 */ +// calldataload +// /* "":4780:4783 */ +// 0x82 +// /* "":4767:4784 */ +// calldataload +// /* "":4818:4821 */ +// 0x83 +// /* "":4805:4822 */ +// calldataload +// /* "":4856:4859 */ +// 0x84 +// /* "":4843:4860 */ +// calldataload +// /* "":4894:4897 */ +// 0x85 +// /* "":4881:4898 */ +// calldataload +// /* "":4932:4935 */ +// 0x86 +// /* "":4919:4936 */ +// calldataload +// /* "":4970:4973 */ +// 0x87 +// /* "":4957:4974 */ +// calldataload +// /* "":5008:5011 */ +// 0x88 +// /* "":4995:5012 */ +// calldataload +// /* "":5046:5049 */ +// 0x89 +// /* "":5033:5050 */ +// calldataload +// /* "":5084:5087 */ +// 0x8a +// /* "":5071:5088 */ +// calldataload +// /* "":5122:5125 */ +// 0x8b +// /* "":5109:5126 */ +// calldataload +// /* "":5160:5163 */ +// 0x8c +// /* "":5147:5164 */ +// calldataload +// /* "":5198:5201 */ +// 0x8d +// /* "":5185:5202 */ +// calldataload +// /* "":5236:5239 */ +// 0x8e +// /* "":5223:5240 */ +// calldataload +// /* "":5274:5277 */ +// 0x8f +// /* "":5261:5278 */ +// calldataload +// /* "":5312:5315 */ +// 0x90 +// /* "":5299:5316 */ +// calldataload +// /* "":5350:5353 */ +// 0x91 +// /* "":5337:5354 */ +// calldataload +// /* "":5388:5391 */ +// 0x92 +// /* "":5375:5392 */ +// calldataload +// /* "":5426:5429 */ +// 0x93 +// /* "":5413:5430 */ +// calldataload +// /* "":5464:5467 */ +// 0x94 +// /* "":5451:5468 */ +// calldataload +// /* "":5502:5505 */ +// 0x95 +// /* "":5489:5506 */ +// calldataload +// /* "":5540:5543 */ +// 0x96 +// /* "":5527:5544 */ +// calldataload +// /* "":5578:5581 */ +// 0x97 +// /* "":5565:5582 */ +// calldataload +// /* "":5616:5619 */ +// 0x98 +// /* "":5603:5620 */ +// calldataload +// /* "":5654:5657 */ +// 0x99 +// /* "":5641:5658 */ +// calldataload +// /* "":5692:5695 */ +// 0x9a +// /* "":5679:5696 */ +// calldataload +// /* "":5730:5733 */ +// 0x9b +// /* "":5717:5734 */ +// calldataload +// /* "":5768:5771 */ +// 0x9c +// /* "":5755:5772 */ +// calldataload +// /* "":5806:5809 */ +// 0x9d +// /* "":5793:5810 */ +// calldataload +// /* "":5844:5847 */ +// 0x9e +// /* "":5831:5848 */ +// calldataload +// /* "":5882:5885 */ +// 0x9f +// /* "":5869:5886 */ +// calldataload +// /* "":5920:5923 */ +// 0xa0 +// /* "":5907:5924 */ +// calldataload +// /* "":5958:5961 */ +// 0xa1 +// /* "":5945:5962 */ +// calldataload +// /* "":5996:5999 */ +// 0xa2 +// /* "":5983:6000 */ +// calldataload +// /* "":6034:6037 */ +// 0xa3 +// /* "":6021:6038 */ +// calldataload +// /* "":6072:6075 */ +// 0xa4 +// /* "":6059:6076 */ +// calldataload +// /* "":6110:6113 */ +// 0xa5 +// /* "":6097:6114 */ +// calldataload +// /* "":6148:6151 */ +// 0xa6 +// /* "":6135:6152 */ +// calldataload +// /* "":6186:6189 */ +// 0xa7 +// /* "":6173:6190 */ +// calldataload +// /* "":6224:6227 */ +// 0xa8 +// /* "":6211:6228 */ +// calldataload +// /* "":6262:6265 */ +// 0xa9 +// /* "":6249:6266 */ +// calldataload +// /* "":6300:6303 */ +// 0xaa +// /* "":6287:6304 */ +// calldataload +// /* "":6338:6341 */ +// 0xab +// /* "":6325:6342 */ +// calldataload +// /* "":6376:6379 */ +// 0xac +// /* "":6363:6380 */ +// calldataload +// /* "":6414:6417 */ +// 0xad +// /* "":6401:6418 */ +// calldataload +// /* "":6452:6455 */ +// 0xae +// /* "":6439:6456 */ +// calldataload +// /* "":6490:6493 */ +// 0xaf +// /* "":6477:6494 */ +// calldataload +// /* "":6528:6531 */ +// 0xb0 +// /* "":6515:6532 */ +// calldataload +// /* "":6566:6569 */ +// 0xb1 +// /* "":6553:6570 */ +// calldataload +// /* "":6604:6607 */ +// 0xb2 +// /* "":6591:6608 */ +// calldataload +// /* "":6642:6645 */ +// 0xb3 +// /* "":6629:6646 */ +// calldataload +// /* "":6680:6683 */ +// 0xb4 +// /* "":6667:6684 */ +// calldataload +// /* "":6718:6721 */ +// 0xb5 +// /* "":6705:6722 */ +// calldataload +// /* "":6756:6759 */ +// 0xb6 +// /* "":6743:6760 */ +// calldataload +// /* "":6794:6797 */ +// 0xb7 +// /* "":6781:6798 */ +// calldataload +// /* "":6832:6835 */ +// 0xb8 +// /* "":6819:6836 */ +// calldataload +// /* "":6870:6873 */ +// 0xb9 +// /* "":6857:6874 */ +// calldataload +// /* "":6908:6911 */ +// 0xba +// /* "":6895:6912 */ +// calldataload +// /* "":6946:6949 */ +// 0xbb +// /* "":6933:6950 */ +// calldataload +// /* "":6984:6987 */ +// 0xbc +// /* "":6971:6988 */ +// calldataload +// /* "":7022:7025 */ +// 0xbd +// /* "":7009:7026 */ +// calldataload +// /* "":7060:7063 */ +// 0xbe +// /* "":7047:7064 */ +// calldataload +// /* "":7098:7101 */ +// 0xbf +// /* "":7085:7102 */ +// calldataload +// /* "":7136:7139 */ +// 0xc0 +// /* "":7123:7140 */ +// calldataload +// /* "":7174:7177 */ +// 0xc1 +// /* "":7161:7178 */ +// calldataload +// /* "":7212:7215 */ +// 0xc2 +// /* "":7199:7216 */ +// calldataload +// /* "":7250:7253 */ +// 0xc3 +// /* "":7237:7254 */ +// calldataload +// /* "":7288:7291 */ +// 0xc4 +// /* "":7275:7292 */ +// calldataload +// /* "":7326:7329 */ +// 0xc5 +// /* "":7313:7330 */ +// calldataload +// /* "":7364:7367 */ +// 0xc6 +// /* "":7351:7368 */ +// calldataload +// /* "":7402:7405 */ +// 0xc7 +// /* "":7389:7406 */ +// calldataload +// /* "":7440:7443 */ +// 0xc8 +// /* "":7427:7444 */ +// calldataload +// /* "":7478:7481 */ +// 0xc9 +// /* "":7465:7482 */ +// calldataload +// /* "":7516:7519 */ +// 0xca +// /* "":7503:7520 */ +// calldataload +// /* "":7554:7557 */ +// 0xcb +// /* "":7541:7558 */ +// calldataload +// /* "":7592:7595 */ +// 0xcc +// /* "":7579:7596 */ +// calldataload +// /* "":7630:7633 */ +// 0xcd +// /* "":7617:7634 */ +// calldataload +// /* "":7668:7671 */ +// 0xce +// /* "":7655:7672 */ +// calldataload +// /* "":7706:7709 */ +// 0xcf +// /* "":7693:7710 */ +// calldataload +// /* "":7744:7747 */ +// 0xd0 +// /* "":7731:7748 */ +// calldataload +// /* "":7782:7785 */ +// 0xd1 +// /* "":7769:7786 */ +// calldataload +// /* "":7820:7823 */ +// 0xd2 +// /* "":7807:7824 */ +// calldataload +// /* "":7858:7861 */ +// 0xd3 +// /* "":7845:7862 */ +// calldataload +// /* "":7896:7899 */ +// 0xd4 +// /* "":7883:7900 */ +// calldataload +// /* "":7934:7937 */ +// 0xd5 +// /* "":7921:7938 */ +// calldataload +// /* "":7972:7975 */ +// 0xd6 +// /* "":7959:7976 */ +// calldataload +// /* "":8010:8013 */ +// 0xd7 +// /* "":7997:8014 */ +// calldataload +// /* "":8048:8051 */ +// 0xd8 +// /* "":8035:8052 */ +// calldataload +// /* "":8086:8089 */ +// 0xd9 +// /* "":8073:8090 */ +// calldataload +// /* "":8124:8127 */ +// 0xda +// /* "":8111:8128 */ +// calldataload +// /* "":8162:8165 */ +// 0xdb +// /* "":8149:8166 */ +// calldataload +// /* "":8200:8203 */ +// 0xdc +// /* "":8187:8204 */ +// calldataload +// /* "":8238:8241 */ +// 0xdd +// /* "":8225:8242 */ +// calldataload +// /* "":8276:8279 */ +// 0xde +// /* "":8263:8280 */ +// calldataload +// /* "":8314:8317 */ +// 0xdf +// /* "":8301:8318 */ +// calldataload +// /* "":8352:8355 */ +// 0xe0 +// /* "":8339:8356 */ +// calldataload +// /* "":8390:8393 */ +// 0xe1 +// /* "":8377:8394 */ +// calldataload +// /* "":8428:8431 */ +// 0xe2 +// /* "":8415:8432 */ +// calldataload +// /* "":8466:8469 */ +// 0xe3 +// /* "":8453:8470 */ +// calldataload +// /* "":8504:8507 */ +// 0xe4 +// /* "":8491:8508 */ +// calldataload +// /* "":8542:8545 */ +// 0xe5 +// /* "":8529:8546 */ +// calldataload +// /* "":8580:8583 */ +// 0xe6 +// /* "":8567:8584 */ +// calldataload +// /* "":8618:8621 */ +// 0xe7 +// /* "":8605:8622 */ +// calldataload +// /* "":8656:8659 */ +// 0xe8 +// /* "":8643:8660 */ +// calldataload +// /* "":8694:8697 */ +// 0xe9 +// /* "":8681:8698 */ +// calldataload +// /* "":8732:8735 */ +// 0xea +// /* "":8719:8736 */ +// calldataload +// /* "":8770:8773 */ +// 0xeb +// /* "":8757:8774 */ +// calldataload +// /* "":8808:8811 */ +// 0xec +// /* "":8795:8812 */ +// calldataload +// /* "":8846:8849 */ +// 0xed +// /* "":8833:8850 */ +// calldataload +// /* "":8884:8887 */ +// 0xee +// /* "":8871:8888 */ +// calldataload +// /* "":8922:8925 */ +// 0xef +// /* "":8909:8926 */ +// calldataload +// /* "":8960:8963 */ +// 0xf0 +// /* "":8947:8964 */ +// calldataload +// /* "":8998:9001 */ +// 0xf1 +// /* "":8985:9002 */ +// calldataload +// /* "":9036:9039 */ +// 0xf2 +// /* "":9023:9040 */ +// calldataload +// /* "":9074:9077 */ +// 0xf3 +// /* "":9061:9078 */ +// calldataload +// /* "":9112:9115 */ +// 0xf4 +// /* "":9099:9116 */ +// calldataload +// /* "":9150:9153 */ +// 0xf5 +// /* "":9137:9154 */ +// calldataload +// /* "":9188:9191 */ +// 0xf6 +// /* "":9175:9192 */ +// calldataload +// /* "":9226:9229 */ +// 0xf7 +// /* "":9213:9230 */ +// calldataload +// /* "":9264:9267 */ +// 0xf8 +// /* "":9251:9268 */ +// calldataload +// /* "":9302:9305 */ +// 0xf9 +// /* "":9289:9306 */ +// calldataload +// /* "":9340:9343 */ +// 0xfa +// /* "":9327:9344 */ +// calldataload +// /* "":9378:9381 */ +// 0xfb +// /* "":9365:9382 */ +// calldataload +// /* "":9416:9419 */ +// 0xfc +// /* "":9403:9420 */ +// calldataload +// /* "":9454:9457 */ +// 0xfd +// /* "":9441:9458 */ +// calldataload +// /* "":9492:9495 */ +// 0xfe +// /* "":9479:9496 */ +// calldataload +// /* "":9530:9533 */ +// 0xff +// /* "":9517:9534 */ +// calldataload +// /* "":9795:9798 */ +// 0x0100 +// /* "":9782:9799 */ +// calldataload +// /* "":9779:9815 */ +// rjumpi{tag_1} +// /* "":25:16281 */ +// tag_2: +// /* "":9824:9839 */ +// dupn{256} +// /* "":9831:9834 */ +// 0x0100 +// /* "":9824:9839 */ +// sstore +// /* "":9855:9858 */ +// 0xff +// /* "":9848:9865 */ +// sstore +// /* "":9881:9884 */ +// 0xfe +// /* "":9874:9891 */ +// sstore +// /* "":9907:9910 */ +// 0xfd +// /* "":9900:9917 */ +// sstore +// /* "":9933:9936 */ +// 0xfc +// /* "":9926:9943 */ +// sstore +// /* "":9959:9962 */ +// 0xfb +// /* "":9952:9969 */ +// sstore +// /* "":9985:9988 */ +// 0xfa +// /* "":9978:9995 */ +// sstore +// /* "":10011:10014 */ +// 0xf9 +// /* "":10004:10021 */ +// sstore +// /* "":10037:10040 */ +// 0xf8 +// /* "":10030:10047 */ +// sstore +// /* "":10063:10066 */ +// 0xf7 +// /* "":10056:10073 */ +// sstore +// /* "":10089:10092 */ +// 0xf6 +// /* "":10082:10099 */ +// sstore +// /* "":10115:10118 */ +// 0xf5 +// /* "":10108:10125 */ +// sstore +// /* "":10141:10144 */ +// 0xf4 +// /* "":10134:10151 */ +// sstore +// /* "":10167:10170 */ +// 0xf3 +// /* "":10160:10177 */ +// sstore +// /* "":10193:10196 */ +// 0xf2 +// /* "":10186:10203 */ +// sstore +// /* "":10219:10222 */ +// 0xf1 +// /* "":10212:10229 */ +// sstore +// /* "":10245:10248 */ +// 0xf0 +// /* "":10238:10255 */ +// sstore +// /* "":10271:10274 */ +// 0xef +// /* "":10264:10281 */ +// sstore +// /* "":10297:10300 */ +// 0xee +// /* "":10290:10307 */ +// sstore +// /* "":10323:10326 */ +// 0xed +// /* "":10316:10333 */ +// sstore +// /* "":10349:10352 */ +// 0xec +// /* "":10342:10359 */ +// sstore +// /* "":10375:10378 */ +// 0xeb +// /* "":10368:10385 */ +// sstore +// /* "":10401:10404 */ +// 0xea +// /* "":10394:10411 */ +// sstore +// /* "":10427:10430 */ +// 0xe9 +// /* "":10420:10437 */ +// sstore +// /* "":10453:10456 */ +// 0xe8 +// /* "":10446:10463 */ +// sstore +// /* "":10479:10482 */ +// 0xe7 +// /* "":10472:10489 */ +// sstore +// /* "":10505:10508 */ +// 0xe6 +// /* "":10498:10515 */ +// sstore +// /* "":10531:10534 */ +// 0xe5 +// /* "":10524:10541 */ +// sstore +// /* "":10557:10560 */ +// 0xe4 +// /* "":10550:10567 */ +// sstore +// /* "":10583:10586 */ +// 0xe3 +// /* "":10576:10593 */ +// sstore +// /* "":10609:10612 */ +// 0xe2 +// /* "":10602:10619 */ +// sstore +// /* "":10635:10638 */ +// 0xe1 +// /* "":10628:10645 */ +// sstore +// /* "":10661:10664 */ +// 0xe0 +// /* "":10654:10671 */ +// sstore +// /* "":10687:10690 */ +// 0xdf +// /* "":10680:10697 */ +// sstore +// /* "":10713:10716 */ +// 0xde +// /* "":10706:10723 */ +// sstore +// /* "":10739:10742 */ +// 0xdd +// /* "":10732:10749 */ +// sstore +// /* "":10765:10768 */ +// 0xdc +// /* "":10758:10775 */ +// sstore +// /* "":10791:10794 */ +// 0xdb +// /* "":10784:10801 */ +// sstore +// /* "":10817:10820 */ +// 0xda +// /* "":10810:10827 */ +// sstore +// /* "":10843:10846 */ +// 0xd9 +// /* "":10836:10853 */ +// sstore +// /* "":10869:10872 */ +// 0xd8 +// /* "":10862:10879 */ +// sstore +// /* "":10895:10898 */ +// 0xd7 +// /* "":10888:10905 */ +// sstore +// /* "":10921:10924 */ +// 0xd6 +// /* "":10914:10931 */ +// sstore +// /* "":10947:10950 */ +// 0xd5 +// /* "":10940:10957 */ +// sstore +// /* "":10973:10976 */ +// 0xd4 +// /* "":10966:10983 */ +// sstore +// /* "":10999:11002 */ +// 0xd3 +// /* "":10992:11009 */ +// sstore +// /* "":11025:11028 */ +// 0xd2 +// /* "":11018:11035 */ +// sstore +// /* "":11051:11054 */ +// 0xd1 +// /* "":11044:11061 */ +// sstore +// /* "":11077:11080 */ +// 0xd0 +// /* "":11070:11087 */ +// sstore +// /* "":11103:11106 */ +// 0xcf +// /* "":11096:11113 */ +// sstore +// /* "":11129:11132 */ +// 0xce +// /* "":11122:11139 */ +// sstore +// /* "":11155:11158 */ +// 0xcd +// /* "":11148:11165 */ +// sstore +// /* "":11181:11184 */ +// 0xcc +// /* "":11174:11191 */ +// sstore +// /* "":11207:11210 */ +// 0xcb +// /* "":11200:11217 */ +// sstore +// /* "":11233:11236 */ +// 0xca +// /* "":11226:11243 */ +// sstore +// /* "":11259:11262 */ +// 0xc9 +// /* "":11252:11269 */ +// sstore +// /* "":11285:11288 */ +// 0xc8 +// /* "":11278:11295 */ +// sstore +// /* "":11311:11314 */ +// 0xc7 +// /* "":11304:11321 */ +// sstore +// /* "":11337:11340 */ +// 0xc6 +// /* "":11330:11347 */ +// sstore +// /* "":11363:11366 */ +// 0xc5 +// /* "":11356:11373 */ +// sstore +// /* "":11389:11392 */ +// 0xc4 +// /* "":11382:11399 */ +// sstore +// /* "":11415:11418 */ +// 0xc3 +// /* "":11408:11425 */ +// sstore +// /* "":11441:11444 */ +// 0xc2 +// /* "":11434:11451 */ +// sstore +// /* "":11467:11470 */ +// 0xc1 +// /* "":11460:11477 */ +// sstore +// /* "":11493:11496 */ +// 0xc0 +// /* "":11486:11503 */ +// sstore +// /* "":11519:11522 */ +// 0xbf +// /* "":11512:11529 */ +// sstore +// /* "":11545:11548 */ +// 0xbe +// /* "":11538:11555 */ +// sstore +// /* "":11571:11574 */ +// 0xbd +// /* "":11564:11581 */ +// sstore +// /* "":11597:11600 */ +// 0xbc +// /* "":11590:11607 */ +// sstore +// /* "":11623:11626 */ +// 0xbb +// /* "":11616:11633 */ +// sstore +// /* "":11649:11652 */ +// 0xba +// /* "":11642:11659 */ +// sstore +// /* "":11675:11678 */ +// 0xb9 +// /* "":11668:11685 */ +// sstore +// /* "":11701:11704 */ +// 0xb8 +// /* "":11694:11711 */ +// sstore +// /* "":11727:11730 */ +// 0xb7 +// /* "":11720:11737 */ +// sstore +// /* "":11753:11756 */ +// 0xb6 +// /* "":11746:11763 */ +// sstore +// /* "":11779:11782 */ +// 0xb5 +// /* "":11772:11789 */ +// sstore +// /* "":11805:11808 */ +// 0xb4 +// /* "":11798:11815 */ +// sstore +// /* "":11831:11834 */ +// 0xb3 +// /* "":11824:11841 */ +// sstore +// /* "":11857:11860 */ +// 0xb2 +// /* "":11850:11867 */ +// sstore +// /* "":11883:11886 */ +// 0xb1 +// /* "":11876:11893 */ +// sstore +// /* "":11909:11912 */ +// 0xb0 +// /* "":11902:11919 */ +// sstore +// /* "":11935:11938 */ +// 0xaf +// /* "":11928:11945 */ +// sstore +// /* "":11961:11964 */ +// 0xae +// /* "":11954:11971 */ +// sstore +// /* "":11987:11990 */ +// 0xad +// /* "":11980:11997 */ +// sstore +// /* "":12013:12016 */ +// 0xac +// /* "":12006:12023 */ +// sstore +// /* "":12039:12042 */ +// 0xab +// /* "":12032:12049 */ +// sstore +// /* "":12065:12068 */ +// 0xaa +// /* "":12058:12075 */ +// sstore +// /* "":12091:12094 */ +// 0xa9 +// /* "":12084:12101 */ +// sstore +// /* "":12117:12120 */ +// 0xa8 +// /* "":12110:12127 */ +// sstore +// /* "":12143:12146 */ +// 0xa7 +// /* "":12136:12153 */ +// sstore +// /* "":12169:12172 */ +// 0xa6 +// /* "":12162:12179 */ +// sstore +// /* "":12195:12198 */ +// 0xa5 +// /* "":12188:12205 */ +// sstore +// /* "":12221:12224 */ +// 0xa4 +// /* "":12214:12231 */ +// sstore +// /* "":12247:12250 */ +// 0xa3 +// /* "":12240:12257 */ +// sstore +// /* "":12273:12276 */ +// 0xa2 +// /* "":12266:12283 */ +// sstore +// /* "":12299:12302 */ +// 0xa1 +// /* "":12292:12309 */ +// sstore +// /* "":12325:12328 */ +// 0xa0 +// /* "":12318:12335 */ +// sstore +// /* "":12351:12354 */ +// 0x9f +// /* "":12344:12361 */ +// sstore +// /* "":12377:12380 */ +// 0x9e +// /* "":12370:12387 */ +// sstore +// /* "":12403:12406 */ +// 0x9d +// /* "":12396:12413 */ +// sstore +// /* "":12429:12432 */ +// 0x9c +// /* "":12422:12439 */ +// sstore +// /* "":12455:12458 */ +// 0x9b +// /* "":12448:12465 */ +// sstore +// /* "":12481:12484 */ +// 0x9a +// /* "":12474:12491 */ +// sstore +// /* "":12507:12510 */ +// 0x99 +// /* "":12500:12517 */ +// sstore +// /* "":12533:12536 */ +// 0x98 +// /* "":12526:12543 */ +// sstore +// /* "":12559:12562 */ +// 0x97 +// /* "":12552:12569 */ +// sstore +// /* "":12585:12588 */ +// 0x96 +// /* "":12578:12595 */ +// sstore +// /* "":12611:12614 */ +// 0x95 +// /* "":12604:12621 */ +// sstore +// /* "":12637:12640 */ +// 0x94 +// /* "":12630:12647 */ +// sstore +// /* "":12663:12666 */ +// 0x93 +// /* "":12656:12673 */ +// sstore +// /* "":12689:12692 */ +// 0x92 +// /* "":12682:12699 */ +// sstore +// /* "":12715:12718 */ +// 0x91 +// /* "":12708:12725 */ +// sstore +// /* "":12741:12744 */ +// 0x90 +// /* "":12734:12751 */ +// sstore +// /* "":12767:12770 */ +// 0x8f +// /* "":12760:12777 */ +// sstore +// /* "":12793:12796 */ +// 0x8e +// /* "":12786:12803 */ +// sstore +// /* "":12819:12822 */ +// 0x8d +// /* "":12812:12829 */ +// sstore +// /* "":12845:12848 */ +// 0x8c +// /* "":12838:12855 */ +// sstore +// /* "":12871:12874 */ +// 0x8b +// /* "":12864:12881 */ +// sstore +// /* "":12897:12900 */ +// 0x8a +// /* "":12890:12907 */ +// sstore +// /* "":12923:12926 */ +// 0x89 +// /* "":12916:12933 */ +// sstore +// /* "":12949:12952 */ +// 0x88 +// /* "":12942:12959 */ +// sstore +// /* "":12975:12978 */ +// 0x87 +// /* "":12968:12985 */ +// sstore +// /* "":13001:13004 */ +// 0x86 +// /* "":12994:13011 */ +// sstore +// /* "":13027:13030 */ +// 0x85 +// /* "":13020:13037 */ +// sstore +// /* "":13053:13056 */ +// 0x84 +// /* "":13046:13063 */ +// sstore +// /* "":13079:13082 */ +// 0x83 +// /* "":13072:13089 */ +// sstore +// /* "":13105:13108 */ +// 0x82 +// /* "":13098:13115 */ +// sstore +// /* "":13131:13134 */ +// 0x81 +// /* "":13124:13141 */ +// sstore +// /* "":13157:13160 */ +// 0x80 +// /* "":13150:13167 */ +// sstore +// /* "":13183:13186 */ +// 0x7f +// /* "":13176:13193 */ +// sstore +// /* "":13209:13212 */ +// 0x7e +// /* "":13202:13219 */ +// sstore +// /* "":13235:13238 */ +// 0x7d +// /* "":13228:13245 */ +// sstore +// /* "":13261:13264 */ +// 0x7c +// /* "":13254:13271 */ +// sstore +// /* "":13287:13290 */ +// 0x7b +// /* "":13280:13297 */ +// sstore +// /* "":13313:13316 */ +// 0x7a +// /* "":13306:13323 */ +// sstore +// /* "":13339:13342 */ +// 0x79 +// /* "":13332:13349 */ +// sstore +// /* "":13365:13368 */ +// 0x78 +// /* "":13358:13375 */ +// sstore +// /* "":13391:13394 */ +// 0x77 +// /* "":13384:13401 */ +// sstore +// /* "":13417:13420 */ +// 0x76 +// /* "":13410:13427 */ +// sstore +// /* "":13443:13446 */ +// 0x75 +// /* "":13436:13453 */ +// sstore +// /* "":13469:13472 */ +// 0x74 +// /* "":13462:13479 */ +// sstore +// /* "":13495:13498 */ +// 0x73 +// /* "":13488:13505 */ +// sstore +// /* "":13521:13524 */ +// 0x72 +// /* "":13514:13531 */ +// sstore +// /* "":13547:13550 */ +// 0x71 +// /* "":13540:13557 */ +// sstore +// /* "":13573:13576 */ +// 0x70 +// /* "":13566:13583 */ +// sstore +// /* "":13599:13602 */ +// 0x6f +// /* "":13592:13609 */ +// sstore +// /* "":13625:13628 */ +// 0x6e +// /* "":13618:13635 */ +// sstore +// /* "":13651:13654 */ +// 0x6d +// /* "":13644:13661 */ +// sstore +// /* "":13677:13680 */ +// 0x6c +// /* "":13670:13687 */ +// sstore +// /* "":13703:13706 */ +// 0x6b +// /* "":13696:13713 */ +// sstore +// /* "":13729:13732 */ +// 0x6a +// /* "":13722:13739 */ +// sstore +// /* "":13755:13758 */ +// 0x69 +// /* "":13748:13765 */ +// sstore +// /* "":13781:13784 */ +// 0x68 +// /* "":13774:13791 */ +// sstore +// /* "":13807:13810 */ +// 0x67 +// /* "":13800:13817 */ +// sstore +// /* "":13833:13836 */ +// 0x66 +// /* "":13826:13843 */ +// sstore +// /* "":13859:13862 */ +// 0x65 +// /* "":13852:13869 */ +// sstore +// /* "":13885:13888 */ +// 0x64 +// /* "":13878:13895 */ +// sstore +// /* "":13911:13913 */ +// 0x63 +// /* "":13904:13919 */ +// sstore +// /* "":13935:13937 */ +// 0x62 +// /* "":13928:13943 */ +// sstore +// /* "":13959:13961 */ +// 0x61 +// /* "":13952:13967 */ +// sstore +// /* "":13983:13985 */ +// 0x60 +// /* "":13976:13991 */ +// sstore +// /* "":14007:14009 */ +// 0x5f +// /* "":14000:14015 */ +// sstore +// /* "":14031:14033 */ +// 0x5e +// /* "":14024:14039 */ +// sstore +// /* "":14055:14057 */ +// 0x5d +// /* "":14048:14063 */ +// sstore +// /* "":14079:14081 */ +// 0x5c +// /* "":14072:14087 */ +// sstore +// /* "":14103:14105 */ +// 0x5b +// /* "":14096:14111 */ +// sstore +// /* "":14127:14129 */ +// 0x5a +// /* "":14120:14135 */ +// sstore +// /* "":14151:14153 */ +// 0x59 +// /* "":14144:14159 */ +// sstore +// /* "":14175:14177 */ +// 0x58 +// /* "":14168:14183 */ +// sstore +// /* "":14199:14201 */ +// 0x57 +// /* "":14192:14207 */ +// sstore +// /* "":14223:14225 */ +// 0x56 +// /* "":14216:14231 */ +// sstore +// /* "":14247:14249 */ +// 0x55 +// /* "":14240:14255 */ +// sstore +// /* "":14271:14273 */ +// 0x54 +// /* "":14264:14279 */ +// sstore +// /* "":14295:14297 */ +// 0x53 +// /* "":14288:14303 */ +// sstore +// /* "":14319:14321 */ +// 0x52 +// /* "":14312:14327 */ +// sstore +// /* "":14343:14345 */ +// 0x51 +// /* "":14336:14351 */ +// sstore +// /* "":14367:14369 */ +// 0x50 +// /* "":14360:14375 */ +// sstore +// /* "":14391:14393 */ +// 0x4f +// /* "":14384:14399 */ +// sstore +// /* "":14415:14417 */ +// 0x4e +// /* "":14408:14423 */ +// sstore +// /* "":14439:14441 */ +// 0x4d +// /* "":14432:14447 */ +// sstore +// /* "":14463:14465 */ +// 0x4c +// /* "":14456:14471 */ +// sstore +// /* "":14487:14489 */ +// 0x4b +// /* "":14480:14495 */ +// sstore +// /* "":14511:14513 */ +// 0x4a +// /* "":14504:14519 */ +// sstore +// /* "":14535:14537 */ +// 0x49 +// /* "":14528:14543 */ +// sstore +// /* "":14559:14561 */ +// 0x48 +// /* "":14552:14567 */ +// sstore +// /* "":14583:14585 */ +// 0x47 +// /* "":14576:14591 */ +// sstore +// /* "":14607:14609 */ +// 0x46 +// /* "":14600:14615 */ +// sstore +// /* "":14631:14633 */ +// 0x45 +// /* "":14624:14639 */ +// sstore +// /* "":14655:14657 */ +// 0x44 +// /* "":14648:14663 */ +// sstore +// /* "":14679:14681 */ +// 0x43 +// /* "":14672:14687 */ +// sstore +// /* "":14703:14705 */ +// 0x42 +// /* "":14696:14711 */ +// sstore +// /* "":14727:14729 */ +// 0x41 +// /* "":14720:14735 */ +// sstore +// /* "":14751:14753 */ +// 0x40 +// /* "":14744:14759 */ +// sstore +// /* "":14775:14777 */ +// 0x3f +// /* "":14768:14783 */ +// sstore +// /* "":14799:14801 */ +// 0x3e +// /* "":14792:14807 */ +// sstore +// /* "":14823:14825 */ +// 0x3d +// /* "":14816:14831 */ +// sstore +// /* "":14847:14849 */ +// 0x3c +// /* "":14840:14855 */ +// sstore +// /* "":14871:14873 */ +// 0x3b +// /* "":14864:14879 */ +// sstore +// /* "":14895:14897 */ +// 0x3a +// /* "":14888:14903 */ +// sstore +// /* "":14919:14921 */ +// 0x39 +// /* "":14912:14927 */ +// sstore +// /* "":14943:14945 */ +// 0x38 +// /* "":14936:14951 */ +// sstore +// /* "":14967:14969 */ +// 0x37 +// /* "":14960:14975 */ +// sstore +// /* "":14991:14993 */ +// 0x36 +// /* "":14984:14999 */ +// sstore +// /* "":15015:15017 */ +// 0x35 +// /* "":15008:15023 */ +// sstore +// /* "":15039:15041 */ +// 0x34 +// /* "":15032:15047 */ +// sstore +// /* "":15063:15065 */ +// 0x33 +// /* "":15056:15071 */ +// sstore +// /* "":15087:15089 */ +// 0x32 +// /* "":15080:15095 */ +// sstore +// /* "":15111:15113 */ +// 0x31 +// /* "":15104:15119 */ +// sstore +// /* "":15135:15137 */ +// 0x30 +// /* "":15128:15143 */ +// sstore +// /* "":15159:15161 */ +// 0x2f +// /* "":15152:15167 */ +// sstore +// /* "":15183:15185 */ +// 0x2e +// /* "":15176:15191 */ +// sstore +// /* "":15207:15209 */ +// 0x2d +// /* "":15200:15215 */ +// sstore +// /* "":15231:15233 */ +// 0x2c +// /* "":15224:15239 */ +// sstore +// /* "":15255:15257 */ +// 0x2b +// /* "":15248:15263 */ +// sstore +// /* "":15279:15281 */ +// 0x2a +// /* "":15272:15287 */ +// sstore +// /* "":15303:15305 */ +// 0x29 +// /* "":15296:15311 */ +// sstore +// /* "":15327:15329 */ +// 0x28 +// /* "":15320:15335 */ +// sstore +// /* "":15351:15353 */ +// 0x27 +// /* "":15344:15359 */ +// sstore +// /* "":15375:15377 */ +// 0x26 +// /* "":15368:15383 */ +// sstore +// /* "":15399:15401 */ +// 0x25 +// /* "":15392:15407 */ +// sstore +// /* "":15423:15425 */ +// 0x24 +// /* "":15416:15431 */ +// sstore +// /* "":15447:15449 */ +// 0x23 +// /* "":15440:15455 */ +// sstore +// /* "":15471:15473 */ +// 0x22 +// /* "":15464:15479 */ +// sstore +// /* "":15495:15497 */ +// 0x21 +// /* "":15488:15503 */ +// sstore +// /* "":15519:15521 */ +// 0x20 +// /* "":15512:15527 */ +// sstore +// /* "":15543:15545 */ +// 0x1f +// /* "":15536:15551 */ +// sstore +// /* "":15567:15569 */ +// 0x1e +// /* "":15560:15575 */ +// sstore +// /* "":15591:15593 */ +// 0x1d +// /* "":15584:15599 */ +// sstore +// /* "":15615:15617 */ +// 0x1c +// /* "":15608:15623 */ +// sstore +// /* "":15639:15641 */ +// 0x1b +// /* "":15632:15647 */ +// sstore +// /* "":15663:15665 */ +// 0x1a +// /* "":15656:15671 */ +// sstore +// /* "":15687:15689 */ +// 0x19 +// /* "":15680:15695 */ +// sstore +// /* "":15711:15713 */ +// 0x18 +// /* "":15704:15719 */ +// sstore +// /* "":15735:15737 */ +// 0x17 +// /* "":15728:15743 */ +// sstore +// /* "":15759:15761 */ +// 0x16 +// /* "":15752:15767 */ +// sstore +// /* "":15783:15785 */ +// 0x15 +// /* "":15776:15791 */ +// sstore +// /* "":15807:15809 */ +// 0x14 +// /* "":15800:15815 */ +// sstore +// /* "":15831:15833 */ +// 0x13 +// /* "":15824:15839 */ +// sstore +// /* "":15855:15857 */ +// 0x12 +// /* "":15848:15863 */ +// sstore +// /* "":15879:15881 */ +// 0x11 +// /* "":15872:15887 */ +// sstore +// /* "":15903:15905 */ +// 0x10 +// /* "":15896:15911 */ +// sstore +// /* "":15927:15929 */ +// 0x0f +// /* "":15920:15935 */ +// sstore +// /* "":15951:15953 */ +// 0x0e +// /* "":15944:15959 */ +// sstore +// /* "":15975:15977 */ +// 0x0d +// /* "":15968:15983 */ +// sstore +// /* "":15999:16001 */ +// 0x0c +// /* "":15992:16007 */ +// sstore +// /* "":16023:16025 */ +// 0x0b +// /* "":16016:16031 */ +// sstore +// /* "":16047:16049 */ +// 0x0a +// /* "":16040:16055 */ +// sstore +// /* "":16071:16072 */ +// 0x09 +// /* "":16064:16077 */ +// sstore +// /* "":16093:16094 */ +// 0x08 +// /* "":16086:16099 */ +// sstore +// /* "":16115:16116 */ +// 0x07 +// /* "":16108:16121 */ +// sstore +// /* "":16137:16138 */ +// 0x06 +// /* "":16130:16143 */ +// sstore +// /* "":16159:16160 */ +// 0x05 +// /* "":16152:16165 */ +// sstore +// /* "":16181:16182 */ +// 0x04 +// /* "":16174:16187 */ +// sstore +// /* "":16203:16204 */ +// 0x03 +// /* "":16196:16209 */ +// sstore +// /* "":16225:16226 */ +// 0x02 +// /* "":16218:16231 */ +// sstore +// /* "":16247:16248 */ +// 0x01 +// /* "":16240:16253 */ +// sstore +// /* "":16269:16270 */ +// 0x00 +// /* "":16262:16275 */ +// sstore +// /* "":25:16281 */ +// stop +// /* "":9800:9815 */ +// tag_1: +// /* "":9811:9812 */ +// 0x00 +// /* "":9802:9813 */ +// dup1 +// revert diff --git a/test/libyul/evmCodeTransform/eof_swap17.yul b/test/libyul/evmCodeTransform/eof_swap17.yul new file mode 100644 index 000000000000..1f9b993cca87 --- /dev/null +++ b/test/libyul/evmCodeTransform/eof_swap17.yul @@ -0,0 +1,229 @@ +object "main" { + code { + // v17 is 17 slots deep in stack - all values in between are still needed - no way to avoid a swapn{17}. + // Running this without EOF, as expected, throws stack-too-deep. + function f(v00, v01, v02, v03, v04, v05, v06, v07, v08, v09, v10, v11, v12, v13, v14, v15, v16, v17) { + sstore(17, v17) + sstore(16, v16) + sstore(15, v15) + sstore(14, v14) + sstore(13, v13) + sstore(12, v12) + sstore(11, v11) + sstore(10, v10) + sstore(9, v09) + sstore(8, v08) + sstore(7, v07) + sstore(6, v06) + sstore(5, v05) + sstore(4, v04) + sstore(3, v03) + sstore(2, v02) + sstore(1, v01) + sstore(0, v00) + } + f( + calldataload(0), + calldataload(1), + calldataload(2), + calldataload(3), + calldataload(4), + calldataload(5), + calldataload(6), + calldataload(7), + calldataload(8), + calldataload(9), + calldataload(10), + calldataload(11), + calldataload(12), + calldataload(13), + calldataload(14), + calldataload(15), + calldataload(16), + calldataload(17) + ) + } +} +// ==== +// bytecodeFormat: >=EOFv1 +// stackOptimization: true +// ---- +// /* "":1361:1363 */ +// 0x11 +// /* "":1348:1364 */ +// calldataload +// /* "":1331:1333 */ +// 0x10 +// /* "":1318:1334 */ +// calldataload +// /* "":1301:1303 */ +// 0x0f +// /* "":1288:1304 */ +// calldataload +// /* "":1271:1273 */ +// 0x0e +// /* "":1258:1274 */ +// calldataload +// /* "":1241:1243 */ +// 0x0d +// /* "":1228:1244 */ +// calldataload +// /* "":1211:1213 */ +// 0x0c +// /* "":1198:1214 */ +// calldataload +// /* "":1181:1183 */ +// 0x0b +// /* "":1168:1184 */ +// calldataload +// /* "":1151:1153 */ +// 0x0a +// /* "":1138:1154 */ +// calldataload +// /* "":1122:1123 */ +// 0x09 +// /* "":1109:1124 */ +// calldataload +// /* "":1093:1094 */ +// 0x08 +// /* "":1080:1095 */ +// calldataload +// /* "":1064:1065 */ +// 0x07 +// /* "":1051:1066 */ +// calldataload +// /* "":1035:1036 */ +// 0x06 +// /* "":1022:1037 */ +// calldataload +// /* "":1006:1007 */ +// 0x05 +// /* "":993:1008 */ +// calldataload +// /* "":977:978 */ +// 0x04 +// /* "":964:979 */ +// calldataload +// /* "":948:949 */ +// 0x03 +// /* "":935:950 */ +// calldataload +// /* "":919:920 */ +// 0x02 +// /* "":906:921 */ +// calldataload +// /* "":890:891 */ +// 0x01 +// /* "":877:892 */ +// calldataload +// /* "":861:862 */ +// 0x00 +// /* "":848:863 */ +// calldataload +// /* "":833:1374 */ +// callf{code_section_1} +// /* "":22:1377 */ +// stop +// +// code_section_1: assembly { +// /* "":218:824 */ +// swapn{17} +// swap16 +// swap1 +// swap16 +// swap15 +// swap2 +// swap15 +// swap14 +// swap3 +// swap14 +// swap13 +// swap4 +// swap13 +// swap12 +// swap5 +// swap12 +// swap11 +// swap6 +// swap11 +// swap10 +// swap7 +// swap10 +// swap9 +// swap8 +// swap9 +// /* "":340:342 */ +// 0x11 +// /* "":333:348 */ +// sstore +// /* "":368:370 */ +// 0x10 +// /* "":361:376 */ +// sstore +// /* "":396:398 */ +// 0x0f +// /* "":389:404 */ +// sstore +// /* "":424:426 */ +// 0x0e +// /* "":417:432 */ +// sstore +// /* "":452:454 */ +// 0x0d +// /* "":445:460 */ +// sstore +// /* "":480:482 */ +// 0x0c +// /* "":473:488 */ +// sstore +// /* "":508:510 */ +// 0x0b +// /* "":501:516 */ +// sstore +// /* "":536:538 */ +// 0x0a +// /* "":529:544 */ +// sstore +// /* "":564:565 */ +// 0x09 +// /* "":557:571 */ +// sstore +// /* "":591:592 */ +// 0x08 +// /* "":584:598 */ +// sstore +// /* "":618:619 */ +// 0x07 +// /* "":611:625 */ +// sstore +// /* "":645:646 */ +// 0x06 +// /* "":638:652 */ +// sstore +// /* "":672:673 */ +// 0x05 +// /* "":665:679 */ +// sstore +// /* "":699:700 */ +// 0x04 +// /* "":692:706 */ +// sstore +// /* "":726:727 */ +// 0x03 +// /* "":719:733 */ +// sstore +// /* "":753:754 */ +// 0x02 +// /* "":746:760 */ +// sstore +// /* "":780:781 */ +// 0x01 +// /* "":773:787 */ +// sstore +// /* "":807:808 */ +// 0x00 +// /* "":800:814 */ +// sstore +// /* "":218:824 */ +// retf +// } diff --git a/test/libyul/evmCodeTransform/eof_swap256.yul b/test/libyul/evmCodeTransform/eof_swap256.yul new file mode 100644 index 000000000000..f718937be02e --- /dev/null +++ b/test/libyul/evmCodeTransform/eof_swap256.yul @@ -0,0 +1,2839 @@ +object "main" { + code { + // Triggers a swapn{256}. Generating one more variable results in a stack-too-deep. + // Note that this relies on not running the optimizer here. With optimizer this code + // can become entirely swap-free. + let v0 := calldataload(0) + let v1 := calldataload(1) + let v2 := calldataload(2) + let v3 := calldataload(3) + let v4 := calldataload(4) + let v5 := calldataload(5) + let v6 := calldataload(6) + let v7 := calldataload(7) + let v8 := calldataload(8) + let v9 := calldataload(9) + let v10 := calldataload(10) + let v11 := calldataload(11) + let v12 := calldataload(12) + let v13 := calldataload(13) + let v14 := calldataload(14) + let v15 := calldataload(15) + let v16 := calldataload(16) + let v17 := calldataload(17) + let v18 := calldataload(18) + let v19 := calldataload(19) + let v20 := calldataload(20) + let v21 := calldataload(21) + let v22 := calldataload(22) + let v23 := calldataload(23) + let v24 := calldataload(24) + let v25 := calldataload(25) + let v26 := calldataload(26) + let v27 := calldataload(27) + let v28 := calldataload(28) + let v29 := calldataload(29) + let v30 := calldataload(30) + let v31 := calldataload(31) + let v32 := calldataload(32) + let v33 := calldataload(33) + let v34 := calldataload(34) + let v35 := calldataload(35) + let v36 := calldataload(36) + let v37 := calldataload(37) + let v38 := calldataload(38) + let v39 := calldataload(39) + let v40 := calldataload(40) + let v41 := calldataload(41) + let v42 := calldataload(42) + let v43 := calldataload(43) + let v44 := calldataload(44) + let v45 := calldataload(45) + let v46 := calldataload(46) + let v47 := calldataload(47) + let v48 := calldataload(48) + let v49 := calldataload(49) + let v50 := calldataload(50) + let v51 := calldataload(51) + let v52 := calldataload(52) + let v53 := calldataload(53) + let v54 := calldataload(54) + let v55 := calldataload(55) + let v56 := calldataload(56) + let v57 := calldataload(57) + let v58 := calldataload(58) + let v59 := calldataload(59) + let v60 := calldataload(60) + let v61 := calldataload(61) + let v62 := calldataload(62) + let v63 := calldataload(63) + let v64 := calldataload(64) + let v65 := calldataload(65) + let v66 := calldataload(66) + let v67 := calldataload(67) + let v68 := calldataload(68) + let v69 := calldataload(69) + let v70 := calldataload(70) + let v71 := calldataload(71) + let v72 := calldataload(72) + let v73 := calldataload(73) + let v74 := calldataload(74) + let v75 := calldataload(75) + let v76 := calldataload(76) + let v77 := calldataload(77) + let v78 := calldataload(78) + let v79 := calldataload(79) + let v80 := calldataload(80) + let v81 := calldataload(81) + let v82 := calldataload(82) + let v83 := calldataload(83) + let v84 := calldataload(84) + let v85 := calldataload(85) + let v86 := calldataload(86) + let v87 := calldataload(87) + let v88 := calldataload(88) + let v89 := calldataload(89) + let v90 := calldataload(90) + let v91 := calldataload(91) + let v92 := calldataload(92) + let v93 := calldataload(93) + let v94 := calldataload(94) + let v95 := calldataload(95) + let v96 := calldataload(96) + let v97 := calldataload(97) + let v98 := calldataload(98) + let v99 := calldataload(99) + let v100 := calldataload(100) + let v101 := calldataload(101) + let v102 := calldataload(102) + let v103 := calldataload(103) + let v104 := calldataload(104) + let v105 := calldataload(105) + let v106 := calldataload(106) + let v107 := calldataload(107) + let v108 := calldataload(108) + let v109 := calldataload(109) + let v110 := calldataload(110) + let v111 := calldataload(111) + let v112 := calldataload(112) + let v113 := calldataload(113) + let v114 := calldataload(114) + let v115 := calldataload(115) + let v116 := calldataload(116) + let v117 := calldataload(117) + let v118 := calldataload(118) + let v119 := calldataload(119) + let v120 := calldataload(120) + let v121 := calldataload(121) + let v122 := calldataload(122) + let v123 := calldataload(123) + let v124 := calldataload(124) + let v125 := calldataload(125) + let v126 := calldataload(126) + let v127 := calldataload(127) + let v128 := calldataload(128) + let v129 := calldataload(129) + let v130 := calldataload(130) + let v131 := calldataload(131) + let v132 := calldataload(132) + let v133 := calldataload(133) + let v134 := calldataload(134) + let v135 := calldataload(135) + let v136 := calldataload(136) + let v137 := calldataload(137) + let v138 := calldataload(138) + let v139 := calldataload(139) + let v140 := calldataload(140) + let v141 := calldataload(141) + let v142 := calldataload(142) + let v143 := calldataload(143) + let v144 := calldataload(144) + let v145 := calldataload(145) + let v146 := calldataload(146) + let v147 := calldataload(147) + let v148 := calldataload(148) + let v149 := calldataload(149) + let v150 := calldataload(150) + let v151 := calldataload(151) + let v152 := calldataload(152) + let v153 := calldataload(153) + let v154 := calldataload(154) + let v155 := calldataload(155) + let v156 := calldataload(156) + let v157 := calldataload(157) + let v158 := calldataload(158) + let v159 := calldataload(159) + let v160 := calldataload(160) + let v161 := calldataload(161) + let v162 := calldataload(162) + let v163 := calldataload(163) + let v164 := calldataload(164) + let v165 := calldataload(165) + let v166 := calldataload(166) + let v167 := calldataload(167) + let v168 := calldataload(168) + let v169 := calldataload(169) + let v170 := calldataload(170) + let v171 := calldataload(171) + let v172 := calldataload(172) + let v173 := calldataload(173) + let v174 := calldataload(174) + let v175 := calldataload(175) + let v176 := calldataload(176) + let v177 := calldataload(177) + let v178 := calldataload(178) + let v179 := calldataload(179) + let v180 := calldataload(180) + let v181 := calldataload(181) + let v182 := calldataload(182) + let v183 := calldataload(183) + let v184 := calldataload(184) + let v185 := calldataload(185) + let v186 := calldataload(186) + let v187 := calldataload(187) + let v188 := calldataload(188) + let v189 := calldataload(189) + let v190 := calldataload(190) + let v191 := calldataload(191) + let v192 := calldataload(192) + let v193 := calldataload(193) + let v194 := calldataload(194) + let v195 := calldataload(195) + let v196 := calldataload(196) + let v197 := calldataload(197) + let v198 := calldataload(198) + let v199 := calldataload(199) + let v200 := calldataload(200) + let v201 := calldataload(201) + let v202 := calldataload(202) + let v203 := calldataload(203) + let v204 := calldataload(204) + let v205 := calldataload(205) + let v206 := calldataload(206) + let v207 := calldataload(207) + let v208 := calldataload(208) + let v209 := calldataload(209) + let v210 := calldataload(210) + let v211 := calldataload(211) + let v212 := calldataload(212) + let v213 := calldataload(213) + let v214 := calldataload(214) + let v215 := calldataload(215) + let v216 := calldataload(216) + let v217 := calldataload(217) + let v218 := calldataload(218) + let v219 := calldataload(219) + let v220 := calldataload(220) + let v221 := calldataload(221) + let v222 := calldataload(222) + let v223 := calldataload(223) + let v224 := calldataload(224) + let v225 := calldataload(225) + let v226 := calldataload(226) + let v227 := calldataload(227) + let v228 := calldataload(228) + let v229 := calldataload(229) + let v230 := calldataload(230) + let v231 := calldataload(231) + let v232 := calldataload(232) + let v233 := calldataload(233) + let v234 := calldataload(234) + let v235 := calldataload(235) + let v236 := calldataload(236) + let v237 := calldataload(237) + let v238 := calldataload(238) + let v239 := calldataload(239) + let v240 := calldataload(240) + let v241 := calldataload(241) + let v242 := calldataload(242) + let v243 := calldataload(243) + let v244 := calldataload(244) + let v245 := calldataload(245) + let v246 := calldataload(246) + let v247 := calldataload(247) + let v248 := calldataload(248) + let v249 := calldataload(249) + let v250 := calldataload(250) + let v251 := calldataload(251) + let v252 := calldataload(252) + let v253 := calldataload(253) + let v254 := calldataload(254) + let v255 := calldataload(255) + let v256 := calldataload(256) + sstore(0, v0) + sstore(1, v1) + sstore(2, v2) + sstore(3, v3) + sstore(4, v4) + sstore(5, v5) + sstore(6, v6) + sstore(7, v7) + sstore(8, v8) + sstore(9, v9) + sstore(10, v10) + sstore(11, v11) + sstore(12, v12) + sstore(13, v13) + sstore(14, v14) + sstore(15, v15) + sstore(16, v16) + sstore(17, v17) + sstore(18, v18) + sstore(19, v19) + sstore(20, v20) + sstore(21, v21) + sstore(22, v22) + sstore(23, v23) + sstore(24, v24) + sstore(25, v25) + sstore(26, v26) + sstore(27, v27) + sstore(28, v28) + sstore(29, v29) + sstore(30, v30) + sstore(31, v31) + sstore(32, v32) + sstore(33, v33) + sstore(34, v34) + sstore(35, v35) + sstore(36, v36) + sstore(37, v37) + sstore(38, v38) + sstore(39, v39) + sstore(40, v40) + sstore(41, v41) + sstore(42, v42) + sstore(43, v43) + sstore(44, v44) + sstore(45, v45) + sstore(46, v46) + sstore(47, v47) + sstore(48, v48) + sstore(49, v49) + sstore(50, v50) + sstore(51, v51) + sstore(52, v52) + sstore(53, v53) + sstore(54, v54) + sstore(55, v55) + sstore(56, v56) + sstore(57, v57) + sstore(58, v58) + sstore(59, v59) + sstore(60, v60) + sstore(61, v61) + sstore(62, v62) + sstore(63, v63) + sstore(64, v64) + sstore(65, v65) + sstore(66, v66) + sstore(67, v67) + sstore(68, v68) + sstore(69, v69) + sstore(70, v70) + sstore(71, v71) + sstore(72, v72) + sstore(73, v73) + sstore(74, v74) + sstore(75, v75) + sstore(76, v76) + sstore(77, v77) + sstore(78, v78) + sstore(79, v79) + sstore(80, v80) + sstore(81, v81) + sstore(82, v82) + sstore(83, v83) + sstore(84, v84) + sstore(85, v85) + sstore(86, v86) + sstore(87, v87) + sstore(88, v88) + sstore(89, v89) + sstore(90, v90) + sstore(91, v91) + sstore(92, v92) + sstore(93, v93) + sstore(94, v94) + sstore(95, v95) + sstore(96, v96) + sstore(97, v97) + sstore(98, v98) + sstore(99, v99) + sstore(100, v100) + sstore(101, v101) + sstore(102, v102) + sstore(103, v103) + sstore(104, v104) + sstore(105, v105) + sstore(106, v106) + sstore(107, v107) + sstore(108, v108) + sstore(109, v109) + sstore(110, v110) + sstore(111, v111) + sstore(112, v112) + sstore(113, v113) + sstore(114, v114) + sstore(115, v115) + sstore(116, v116) + sstore(117, v117) + sstore(118, v118) + sstore(119, v119) + sstore(120, v120) + sstore(121, v121) + sstore(122, v122) + sstore(123, v123) + sstore(124, v124) + sstore(125, v125) + sstore(126, v126) + sstore(127, v127) + sstore(128, v128) + sstore(129, v129) + sstore(130, v130) + sstore(131, v131) + sstore(132, v132) + sstore(133, v133) + sstore(134, v134) + sstore(135, v135) + sstore(136, v136) + sstore(137, v137) + sstore(138, v138) + sstore(139, v139) + sstore(140, v140) + sstore(141, v141) + sstore(142, v142) + sstore(143, v143) + sstore(144, v144) + sstore(145, v145) + sstore(146, v146) + sstore(147, v147) + sstore(148, v148) + sstore(149, v149) + sstore(150, v150) + sstore(151, v151) + sstore(152, v152) + sstore(153, v153) + sstore(154, v154) + sstore(155, v155) + sstore(156, v156) + sstore(157, v157) + sstore(158, v158) + sstore(159, v159) + sstore(160, v160) + sstore(161, v161) + sstore(162, v162) + sstore(163, v163) + sstore(164, v164) + sstore(165, v165) + sstore(166, v166) + sstore(167, v167) + sstore(168, v168) + sstore(169, v169) + sstore(170, v170) + sstore(171, v171) + sstore(172, v172) + sstore(173, v173) + sstore(174, v174) + sstore(175, v175) + sstore(176, v176) + sstore(177, v177) + sstore(178, v178) + sstore(179, v179) + sstore(180, v180) + sstore(181, v181) + sstore(182, v182) + sstore(183, v183) + sstore(184, v184) + sstore(185, v185) + sstore(186, v186) + sstore(187, v187) + sstore(188, v188) + sstore(189, v189) + sstore(190, v190) + sstore(191, v191) + sstore(192, v192) + sstore(193, v193) + sstore(194, v194) + sstore(195, v195) + sstore(196, v196) + sstore(197, v197) + sstore(198, v198) + sstore(199, v199) + sstore(200, v200) + sstore(201, v201) + sstore(202, v202) + sstore(203, v203) + sstore(204, v204) + sstore(205, v205) + sstore(206, v206) + sstore(207, v207) + sstore(208, v208) + sstore(209, v209) + sstore(210, v210) + sstore(211, v211) + sstore(212, v212) + sstore(213, v213) + sstore(214, v214) + sstore(215, v215) + sstore(216, v216) + sstore(217, v217) + sstore(218, v218) + sstore(219, v219) + sstore(220, v220) + sstore(221, v221) + sstore(222, v222) + sstore(223, v223) + sstore(224, v224) + sstore(225, v225) + sstore(226, v226) + sstore(227, v227) + sstore(228, v228) + sstore(229, v229) + sstore(230, v230) + sstore(231, v231) + sstore(232, v232) + sstore(233, v233) + sstore(234, v234) + sstore(235, v235) + sstore(236, v236) + sstore(237, v237) + sstore(238, v238) + sstore(239, v239) + sstore(240, v240) + sstore(241, v241) + sstore(242, v242) + sstore(243, v243) + sstore(244, v244) + sstore(245, v245) + sstore(246, v246) + sstore(247, v247) + sstore(248, v248) + sstore(249, v249) + sstore(250, v250) + sstore(251, v251) + sstore(252, v252) + sstore(253, v253) + sstore(254, v254) + sstore(255, v255) + sstore(256, v256) + } +} +// ==== +// bytecodeFormat: >=EOFv1 +// stackOptimization: true +// ---- +// /* "":285:286 */ +// 0x00 +// /* "":272:287 */ +// calldataload +// /* "":319:320 */ +// 0x01 +// /* "":306:321 */ +// calldataload +// /* "":353:354 */ +// 0x02 +// /* "":340:355 */ +// calldataload +// /* "":387:388 */ +// 0x03 +// /* "":374:389 */ +// calldataload +// /* "":421:422 */ +// 0x04 +// /* "":408:423 */ +// calldataload +// /* "":455:456 */ +// 0x05 +// /* "":442:457 */ +// calldataload +// /* "":489:490 */ +// 0x06 +// /* "":476:491 */ +// calldataload +// /* "":523:524 */ +// 0x07 +// /* "":510:525 */ +// calldataload +// /* "":557:558 */ +// 0x08 +// /* "":544:559 */ +// calldataload +// /* "":591:592 */ +// 0x09 +// /* "":578:593 */ +// calldataload +// /* "":626:628 */ +// 0x0a +// /* "":613:629 */ +// calldataload +// /* "":662:664 */ +// 0x0b +// /* "":649:665 */ +// calldataload +// /* "":698:700 */ +// 0x0c +// /* "":685:701 */ +// calldataload +// /* "":734:736 */ +// 0x0d +// /* "":721:737 */ +// calldataload +// /* "":770:772 */ +// 0x0e +// /* "":757:773 */ +// calldataload +// /* "":806:808 */ +// 0x0f +// /* "":793:809 */ +// calldataload +// /* "":842:844 */ +// 0x10 +// /* "":829:845 */ +// calldataload +// /* "":878:880 */ +// 0x11 +// /* "":865:881 */ +// calldataload +// /* "":914:916 */ +// 0x12 +// /* "":901:917 */ +// calldataload +// /* "":950:952 */ +// 0x13 +// /* "":937:953 */ +// calldataload +// /* "":986:988 */ +// 0x14 +// /* "":973:989 */ +// calldataload +// /* "":1022:1024 */ +// 0x15 +// /* "":1009:1025 */ +// calldataload +// /* "":1058:1060 */ +// 0x16 +// /* "":1045:1061 */ +// calldataload +// /* "":1094:1096 */ +// 0x17 +// /* "":1081:1097 */ +// calldataload +// /* "":1130:1132 */ +// 0x18 +// /* "":1117:1133 */ +// calldataload +// /* "":1166:1168 */ +// 0x19 +// /* "":1153:1169 */ +// calldataload +// /* "":1202:1204 */ +// 0x1a +// /* "":1189:1205 */ +// calldataload +// /* "":1238:1240 */ +// 0x1b +// /* "":1225:1241 */ +// calldataload +// /* "":1274:1276 */ +// 0x1c +// /* "":1261:1277 */ +// calldataload +// /* "":1310:1312 */ +// 0x1d +// /* "":1297:1313 */ +// calldataload +// /* "":1346:1348 */ +// 0x1e +// /* "":1333:1349 */ +// calldataload +// /* "":1382:1384 */ +// 0x1f +// /* "":1369:1385 */ +// calldataload +// /* "":1418:1420 */ +// 0x20 +// /* "":1405:1421 */ +// calldataload +// /* "":1454:1456 */ +// 0x21 +// /* "":1441:1457 */ +// calldataload +// /* "":1490:1492 */ +// 0x22 +// /* "":1477:1493 */ +// calldataload +// /* "":1526:1528 */ +// 0x23 +// /* "":1513:1529 */ +// calldataload +// /* "":1562:1564 */ +// 0x24 +// /* "":1549:1565 */ +// calldataload +// /* "":1598:1600 */ +// 0x25 +// /* "":1585:1601 */ +// calldataload +// /* "":1634:1636 */ +// 0x26 +// /* "":1621:1637 */ +// calldataload +// /* "":1670:1672 */ +// 0x27 +// /* "":1657:1673 */ +// calldataload +// /* "":1706:1708 */ +// 0x28 +// /* "":1693:1709 */ +// calldataload +// /* "":1742:1744 */ +// 0x29 +// /* "":1729:1745 */ +// calldataload +// /* "":1778:1780 */ +// 0x2a +// /* "":1765:1781 */ +// calldataload +// /* "":1814:1816 */ +// 0x2b +// /* "":1801:1817 */ +// calldataload +// /* "":1850:1852 */ +// 0x2c +// /* "":1837:1853 */ +// calldataload +// /* "":1886:1888 */ +// 0x2d +// /* "":1873:1889 */ +// calldataload +// /* "":1922:1924 */ +// 0x2e +// /* "":1909:1925 */ +// calldataload +// /* "":1958:1960 */ +// 0x2f +// /* "":1945:1961 */ +// calldataload +// /* "":1994:1996 */ +// 0x30 +// /* "":1981:1997 */ +// calldataload +// /* "":2030:2032 */ +// 0x31 +// /* "":2017:2033 */ +// calldataload +// /* "":2066:2068 */ +// 0x32 +// /* "":2053:2069 */ +// calldataload +// /* "":2102:2104 */ +// 0x33 +// /* "":2089:2105 */ +// calldataload +// /* "":2138:2140 */ +// 0x34 +// /* "":2125:2141 */ +// calldataload +// /* "":2174:2176 */ +// 0x35 +// /* "":2161:2177 */ +// calldataload +// /* "":2210:2212 */ +// 0x36 +// /* "":2197:2213 */ +// calldataload +// /* "":2246:2248 */ +// 0x37 +// /* "":2233:2249 */ +// calldataload +// /* "":2282:2284 */ +// 0x38 +// /* "":2269:2285 */ +// calldataload +// /* "":2318:2320 */ +// 0x39 +// /* "":2305:2321 */ +// calldataload +// /* "":2354:2356 */ +// 0x3a +// /* "":2341:2357 */ +// calldataload +// /* "":2390:2392 */ +// 0x3b +// /* "":2377:2393 */ +// calldataload +// /* "":2426:2428 */ +// 0x3c +// /* "":2413:2429 */ +// calldataload +// /* "":2462:2464 */ +// 0x3d +// /* "":2449:2465 */ +// calldataload +// /* "":2498:2500 */ +// 0x3e +// /* "":2485:2501 */ +// calldataload +// /* "":2534:2536 */ +// 0x3f +// /* "":2521:2537 */ +// calldataload +// /* "":2570:2572 */ +// 0x40 +// /* "":2557:2573 */ +// calldataload +// /* "":2606:2608 */ +// 0x41 +// /* "":2593:2609 */ +// calldataload +// /* "":2642:2644 */ +// 0x42 +// /* "":2629:2645 */ +// calldataload +// /* "":2678:2680 */ +// 0x43 +// /* "":2665:2681 */ +// calldataload +// /* "":2714:2716 */ +// 0x44 +// /* "":2701:2717 */ +// calldataload +// /* "":2750:2752 */ +// 0x45 +// /* "":2737:2753 */ +// calldataload +// /* "":2786:2788 */ +// 0x46 +// /* "":2773:2789 */ +// calldataload +// /* "":2822:2824 */ +// 0x47 +// /* "":2809:2825 */ +// calldataload +// /* "":2858:2860 */ +// 0x48 +// /* "":2845:2861 */ +// calldataload +// /* "":2894:2896 */ +// 0x49 +// /* "":2881:2897 */ +// calldataload +// /* "":2930:2932 */ +// 0x4a +// /* "":2917:2933 */ +// calldataload +// /* "":2966:2968 */ +// 0x4b +// /* "":2953:2969 */ +// calldataload +// /* "":3002:3004 */ +// 0x4c +// /* "":2989:3005 */ +// calldataload +// /* "":3038:3040 */ +// 0x4d +// /* "":3025:3041 */ +// calldataload +// /* "":3074:3076 */ +// 0x4e +// /* "":3061:3077 */ +// calldataload +// /* "":3110:3112 */ +// 0x4f +// /* "":3097:3113 */ +// calldataload +// /* "":3146:3148 */ +// 0x50 +// /* "":3133:3149 */ +// calldataload +// /* "":3182:3184 */ +// 0x51 +// /* "":3169:3185 */ +// calldataload +// /* "":3218:3220 */ +// 0x52 +// /* "":3205:3221 */ +// calldataload +// /* "":3254:3256 */ +// 0x53 +// /* "":3241:3257 */ +// calldataload +// /* "":3290:3292 */ +// 0x54 +// /* "":3277:3293 */ +// calldataload +// /* "":3326:3328 */ +// 0x55 +// /* "":3313:3329 */ +// calldataload +// /* "":3362:3364 */ +// 0x56 +// /* "":3349:3365 */ +// calldataload +// /* "":3398:3400 */ +// 0x57 +// /* "":3385:3401 */ +// calldataload +// /* "":3434:3436 */ +// 0x58 +// /* "":3421:3437 */ +// calldataload +// /* "":3470:3472 */ +// 0x59 +// /* "":3457:3473 */ +// calldataload +// /* "":3506:3508 */ +// 0x5a +// /* "":3493:3509 */ +// calldataload +// /* "":3542:3544 */ +// 0x5b +// /* "":3529:3545 */ +// calldataload +// /* "":3578:3580 */ +// 0x5c +// /* "":3565:3581 */ +// calldataload +// /* "":3614:3616 */ +// 0x5d +// /* "":3601:3617 */ +// calldataload +// /* "":3650:3652 */ +// 0x5e +// /* "":3637:3653 */ +// calldataload +// /* "":3686:3688 */ +// 0x5f +// /* "":3673:3689 */ +// calldataload +// /* "":3722:3724 */ +// 0x60 +// /* "":3709:3725 */ +// calldataload +// /* "":3758:3760 */ +// 0x61 +// /* "":3745:3761 */ +// calldataload +// /* "":3794:3796 */ +// 0x62 +// /* "":3781:3797 */ +// calldataload +// /* "":3830:3832 */ +// 0x63 +// /* "":3817:3833 */ +// calldataload +// /* "":3867:3870 */ +// 0x64 +// /* "":3854:3871 */ +// calldataload +// /* "":3905:3908 */ +// 0x65 +// /* "":3892:3909 */ +// calldataload +// /* "":3943:3946 */ +// 0x66 +// /* "":3930:3947 */ +// calldataload +// /* "":3981:3984 */ +// 0x67 +// /* "":3968:3985 */ +// calldataload +// /* "":4019:4022 */ +// 0x68 +// /* "":4006:4023 */ +// calldataload +// /* "":4057:4060 */ +// 0x69 +// /* "":4044:4061 */ +// calldataload +// /* "":4095:4098 */ +// 0x6a +// /* "":4082:4099 */ +// calldataload +// /* "":4133:4136 */ +// 0x6b +// /* "":4120:4137 */ +// calldataload +// /* "":4171:4174 */ +// 0x6c +// /* "":4158:4175 */ +// calldataload +// /* "":4209:4212 */ +// 0x6d +// /* "":4196:4213 */ +// calldataload +// /* "":4247:4250 */ +// 0x6e +// /* "":4234:4251 */ +// calldataload +// /* "":4285:4288 */ +// 0x6f +// /* "":4272:4289 */ +// calldataload +// /* "":4323:4326 */ +// 0x70 +// /* "":4310:4327 */ +// calldataload +// /* "":4361:4364 */ +// 0x71 +// /* "":4348:4365 */ +// calldataload +// /* "":4399:4402 */ +// 0x72 +// /* "":4386:4403 */ +// calldataload +// /* "":4437:4440 */ +// 0x73 +// /* "":4424:4441 */ +// calldataload +// /* "":4475:4478 */ +// 0x74 +// /* "":4462:4479 */ +// calldataload +// /* "":4513:4516 */ +// 0x75 +// /* "":4500:4517 */ +// calldataload +// /* "":4551:4554 */ +// 0x76 +// /* "":4538:4555 */ +// calldataload +// /* "":4589:4592 */ +// 0x77 +// /* "":4576:4593 */ +// calldataload +// /* "":4627:4630 */ +// 0x78 +// /* "":4614:4631 */ +// calldataload +// /* "":4665:4668 */ +// 0x79 +// /* "":4652:4669 */ +// calldataload +// /* "":4703:4706 */ +// 0x7a +// /* "":4690:4707 */ +// calldataload +// /* "":4741:4744 */ +// 0x7b +// /* "":4728:4745 */ +// calldataload +// /* "":4779:4782 */ +// 0x7c +// /* "":4766:4783 */ +// calldataload +// /* "":4817:4820 */ +// 0x7d +// /* "":4804:4821 */ +// calldataload +// /* "":4855:4858 */ +// 0x7e +// /* "":4842:4859 */ +// calldataload +// /* "":4893:4896 */ +// 0x7f +// /* "":4880:4897 */ +// calldataload +// /* "":4931:4934 */ +// 0x80 +// /* "":4918:4935 */ +// calldataload +// /* "":4969:4972 */ +// 0x81 +// /* "":4956:4973 */ +// calldataload +// /* "":4994:5011 */ +// swap2 +// /* "":5007:5010 */ +// 0x82 +// /* "":4994:5011 */ +// calldataload +// /* "":5032:5049 */ +// swap4 +// /* "":5045:5048 */ +// 0x83 +// /* "":5032:5049 */ +// calldataload +// /* "":5070:5087 */ +// swap6 +// /* "":5083:5086 */ +// 0x84 +// /* "":5070:5087 */ +// calldataload +// /* "":5108:5125 */ +// swap8 +// /* "":5121:5124 */ +// 0x85 +// /* "":5108:5125 */ +// calldataload +// /* "":5146:5163 */ +// swap10 +// /* "":5159:5162 */ +// 0x86 +// /* "":5146:5163 */ +// calldataload +// /* "":5184:5201 */ +// swap12 +// /* "":5197:5200 */ +// 0x87 +// /* "":5184:5201 */ +// calldataload +// /* "":5222:5239 */ +// swap14 +// /* "":5235:5238 */ +// 0x88 +// /* "":5222:5239 */ +// calldataload +// /* "":5260:5277 */ +// swap16 +// /* "":5273:5276 */ +// 0x89 +// /* "":5260:5277 */ +// calldataload +// /* "":5298:5315 */ +// swapn{18} +// /* "":5311:5314 */ +// 0x8a +// /* "":5298:5315 */ +// calldataload +// /* "":5336:5353 */ +// swapn{20} +// /* "":5349:5352 */ +// 0x8b +// /* "":5336:5353 */ +// calldataload +// /* "":5374:5391 */ +// swapn{22} +// /* "":5387:5390 */ +// 0x8c +// /* "":5374:5391 */ +// calldataload +// /* "":5412:5429 */ +// swapn{24} +// /* "":5425:5428 */ +// 0x8d +// /* "":5412:5429 */ +// calldataload +// /* "":5450:5467 */ +// swapn{26} +// /* "":5463:5466 */ +// 0x8e +// /* "":5450:5467 */ +// calldataload +// /* "":5488:5505 */ +// swapn{28} +// /* "":5501:5504 */ +// 0x8f +// /* "":5488:5505 */ +// calldataload +// /* "":5526:5543 */ +// swapn{30} +// /* "":5539:5542 */ +// 0x90 +// /* "":5526:5543 */ +// calldataload +// /* "":5564:5581 */ +// swapn{32} +// /* "":5577:5580 */ +// 0x91 +// /* "":5564:5581 */ +// calldataload +// /* "":5602:5619 */ +// swapn{34} +// /* "":5615:5618 */ +// 0x92 +// /* "":5602:5619 */ +// calldataload +// /* "":5640:5657 */ +// swapn{36} +// /* "":5653:5656 */ +// 0x93 +// /* "":5640:5657 */ +// calldataload +// /* "":5678:5695 */ +// swapn{38} +// /* "":5691:5694 */ +// 0x94 +// /* "":5678:5695 */ +// calldataload +// /* "":5716:5733 */ +// swapn{40} +// /* "":5729:5732 */ +// 0x95 +// /* "":5716:5733 */ +// calldataload +// /* "":5754:5771 */ +// swapn{42} +// /* "":5767:5770 */ +// 0x96 +// /* "":5754:5771 */ +// calldataload +// /* "":5792:5809 */ +// swapn{44} +// /* "":5805:5808 */ +// 0x97 +// /* "":5792:5809 */ +// calldataload +// /* "":5830:5847 */ +// swapn{46} +// /* "":5843:5846 */ +// 0x98 +// /* "":5830:5847 */ +// calldataload +// /* "":5868:5885 */ +// swapn{48} +// /* "":5881:5884 */ +// 0x99 +// /* "":5868:5885 */ +// calldataload +// /* "":5906:5923 */ +// swapn{50} +// /* "":5919:5922 */ +// 0x9a +// /* "":5906:5923 */ +// calldataload +// /* "":5944:5961 */ +// swapn{52} +// /* "":5957:5960 */ +// 0x9b +// /* "":5944:5961 */ +// calldataload +// /* "":5982:5999 */ +// swapn{54} +// /* "":5995:5998 */ +// 0x9c +// /* "":5982:5999 */ +// calldataload +// /* "":6020:6037 */ +// swapn{56} +// /* "":6033:6036 */ +// 0x9d +// /* "":6020:6037 */ +// calldataload +// /* "":6058:6075 */ +// swapn{58} +// /* "":6071:6074 */ +// 0x9e +// /* "":6058:6075 */ +// calldataload +// /* "":6096:6113 */ +// swapn{60} +// /* "":6109:6112 */ +// 0x9f +// /* "":6096:6113 */ +// calldataload +// /* "":6134:6151 */ +// swapn{62} +// /* "":6147:6150 */ +// 0xa0 +// /* "":6134:6151 */ +// calldataload +// /* "":6172:6189 */ +// swapn{64} +// /* "":6185:6188 */ +// 0xa1 +// /* "":6172:6189 */ +// calldataload +// /* "":6210:6227 */ +// swapn{66} +// /* "":6223:6226 */ +// 0xa2 +// /* "":6210:6227 */ +// calldataload +// /* "":6248:6265 */ +// swapn{68} +// /* "":6261:6264 */ +// 0xa3 +// /* "":6248:6265 */ +// calldataload +// /* "":6286:6303 */ +// swapn{70} +// /* "":6299:6302 */ +// 0xa4 +// /* "":6286:6303 */ +// calldataload +// /* "":6324:6341 */ +// swapn{72} +// /* "":6337:6340 */ +// 0xa5 +// /* "":6324:6341 */ +// calldataload +// /* "":6362:6379 */ +// swapn{74} +// /* "":6375:6378 */ +// 0xa6 +// /* "":6362:6379 */ +// calldataload +// /* "":6400:6417 */ +// swapn{76} +// /* "":6413:6416 */ +// 0xa7 +// /* "":6400:6417 */ +// calldataload +// /* "":6438:6455 */ +// swapn{78} +// /* "":6451:6454 */ +// 0xa8 +// /* "":6438:6455 */ +// calldataload +// /* "":6476:6493 */ +// swapn{80} +// /* "":6489:6492 */ +// 0xa9 +// /* "":6476:6493 */ +// calldataload +// /* "":6514:6531 */ +// swapn{82} +// /* "":6527:6530 */ +// 0xaa +// /* "":6514:6531 */ +// calldataload +// /* "":6552:6569 */ +// swapn{84} +// /* "":6565:6568 */ +// 0xab +// /* "":6552:6569 */ +// calldataload +// /* "":6590:6607 */ +// swapn{86} +// /* "":6603:6606 */ +// 0xac +// /* "":6590:6607 */ +// calldataload +// /* "":6628:6645 */ +// swapn{88} +// /* "":6641:6644 */ +// 0xad +// /* "":6628:6645 */ +// calldataload +// /* "":6666:6683 */ +// swapn{90} +// /* "":6679:6682 */ +// 0xae +// /* "":6666:6683 */ +// calldataload +// /* "":6704:6721 */ +// swapn{92} +// /* "":6717:6720 */ +// 0xaf +// /* "":6704:6721 */ +// calldataload +// /* "":6742:6759 */ +// swapn{94} +// /* "":6755:6758 */ +// 0xb0 +// /* "":6742:6759 */ +// calldataload +// /* "":6780:6797 */ +// swapn{96} +// /* "":6793:6796 */ +// 0xb1 +// /* "":6780:6797 */ +// calldataload +// /* "":6818:6835 */ +// swapn{98} +// /* "":6831:6834 */ +// 0xb2 +// /* "":6818:6835 */ +// calldataload +// /* "":6856:6873 */ +// swapn{100} +// /* "":6869:6872 */ +// 0xb3 +// /* "":6856:6873 */ +// calldataload +// /* "":6894:6911 */ +// swapn{102} +// /* "":6907:6910 */ +// 0xb4 +// /* "":6894:6911 */ +// calldataload +// /* "":6932:6949 */ +// swapn{104} +// /* "":6945:6948 */ +// 0xb5 +// /* "":6932:6949 */ +// calldataload +// /* "":6970:6987 */ +// swapn{106} +// /* "":6983:6986 */ +// 0xb6 +// /* "":6970:6987 */ +// calldataload +// /* "":7008:7025 */ +// swapn{108} +// /* "":7021:7024 */ +// 0xb7 +// /* "":7008:7025 */ +// calldataload +// /* "":7046:7063 */ +// swapn{110} +// /* "":7059:7062 */ +// 0xb8 +// /* "":7046:7063 */ +// calldataload +// /* "":7084:7101 */ +// swapn{112} +// /* "":7097:7100 */ +// 0xb9 +// /* "":7084:7101 */ +// calldataload +// /* "":7122:7139 */ +// swapn{114} +// /* "":7135:7138 */ +// 0xba +// /* "":7122:7139 */ +// calldataload +// /* "":7160:7177 */ +// swapn{116} +// /* "":7173:7176 */ +// 0xbb +// /* "":7160:7177 */ +// calldataload +// /* "":7198:7215 */ +// swapn{118} +// /* "":7211:7214 */ +// 0xbc +// /* "":7198:7215 */ +// calldataload +// /* "":7236:7253 */ +// swapn{120} +// /* "":7249:7252 */ +// 0xbd +// /* "":7236:7253 */ +// calldataload +// /* "":7274:7291 */ +// swapn{122} +// /* "":7287:7290 */ +// 0xbe +// /* "":7274:7291 */ +// calldataload +// /* "":7312:7329 */ +// swapn{124} +// /* "":7325:7328 */ +// 0xbf +// /* "":7312:7329 */ +// calldataload +// /* "":7350:7367 */ +// swapn{126} +// /* "":7363:7366 */ +// 0xc0 +// /* "":7350:7367 */ +// calldataload +// /* "":7388:7405 */ +// swapn{128} +// /* "":7401:7404 */ +// 0xc1 +// /* "":7388:7405 */ +// calldataload +// /* "":7426:7443 */ +// swapn{130} +// /* "":7439:7442 */ +// 0xc2 +// /* "":7426:7443 */ +// calldataload +// /* "":7464:7481 */ +// swapn{132} +// /* "":7477:7480 */ +// 0xc3 +// /* "":7464:7481 */ +// calldataload +// /* "":7502:7519 */ +// swapn{134} +// /* "":7515:7518 */ +// 0xc4 +// /* "":7502:7519 */ +// calldataload +// /* "":7540:7557 */ +// swapn{136} +// /* "":7553:7556 */ +// 0xc5 +// /* "":7540:7557 */ +// calldataload +// /* "":7578:7595 */ +// swapn{138} +// /* "":7591:7594 */ +// 0xc6 +// /* "":7578:7595 */ +// calldataload +// /* "":7616:7633 */ +// swapn{140} +// /* "":7629:7632 */ +// 0xc7 +// /* "":7616:7633 */ +// calldataload +// /* "":7654:7671 */ +// swapn{142} +// /* "":7667:7670 */ +// 0xc8 +// /* "":7654:7671 */ +// calldataload +// /* "":7692:7709 */ +// swapn{144} +// /* "":7705:7708 */ +// 0xc9 +// /* "":7692:7709 */ +// calldataload +// /* "":7730:7747 */ +// swapn{146} +// /* "":7743:7746 */ +// 0xca +// /* "":7730:7747 */ +// calldataload +// /* "":7768:7785 */ +// swapn{148} +// /* "":7781:7784 */ +// 0xcb +// /* "":7768:7785 */ +// calldataload +// /* "":7806:7823 */ +// swapn{150} +// /* "":7819:7822 */ +// 0xcc +// /* "":7806:7823 */ +// calldataload +// /* "":7844:7861 */ +// swapn{152} +// /* "":7857:7860 */ +// 0xcd +// /* "":7844:7861 */ +// calldataload +// /* "":7882:7899 */ +// swapn{154} +// /* "":7895:7898 */ +// 0xce +// /* "":7882:7899 */ +// calldataload +// /* "":7920:7937 */ +// swapn{156} +// /* "":7933:7936 */ +// 0xcf +// /* "":7920:7937 */ +// calldataload +// /* "":7958:7975 */ +// swapn{158} +// /* "":7971:7974 */ +// 0xd0 +// /* "":7958:7975 */ +// calldataload +// /* "":7996:8013 */ +// swapn{160} +// /* "":8009:8012 */ +// 0xd1 +// /* "":7996:8013 */ +// calldataload +// /* "":8034:8051 */ +// swapn{162} +// /* "":8047:8050 */ +// 0xd2 +// /* "":8034:8051 */ +// calldataload +// /* "":8072:8089 */ +// swapn{164} +// /* "":8085:8088 */ +// 0xd3 +// /* "":8072:8089 */ +// calldataload +// /* "":8110:8127 */ +// swapn{166} +// /* "":8123:8126 */ +// 0xd4 +// /* "":8110:8127 */ +// calldataload +// /* "":8148:8165 */ +// swapn{168} +// /* "":8161:8164 */ +// 0xd5 +// /* "":8148:8165 */ +// calldataload +// /* "":8186:8203 */ +// swapn{170} +// /* "":8199:8202 */ +// 0xd6 +// /* "":8186:8203 */ +// calldataload +// /* "":8224:8241 */ +// swapn{172} +// /* "":8237:8240 */ +// 0xd7 +// /* "":8224:8241 */ +// calldataload +// /* "":8262:8279 */ +// swapn{174} +// /* "":8275:8278 */ +// 0xd8 +// /* "":8262:8279 */ +// calldataload +// /* "":8300:8317 */ +// swapn{176} +// /* "":8313:8316 */ +// 0xd9 +// /* "":8300:8317 */ +// calldataload +// /* "":8338:8355 */ +// swapn{178} +// /* "":8351:8354 */ +// 0xda +// /* "":8338:8355 */ +// calldataload +// /* "":8376:8393 */ +// swapn{180} +// /* "":8389:8392 */ +// 0xdb +// /* "":8376:8393 */ +// calldataload +// /* "":8414:8431 */ +// swapn{182} +// /* "":8427:8430 */ +// 0xdc +// /* "":8414:8431 */ +// calldataload +// /* "":8452:8469 */ +// swapn{184} +// /* "":8465:8468 */ +// 0xdd +// /* "":8452:8469 */ +// calldataload +// /* "":8490:8507 */ +// swapn{186} +// /* "":8503:8506 */ +// 0xde +// /* "":8490:8507 */ +// calldataload +// /* "":8528:8545 */ +// swapn{188} +// /* "":8541:8544 */ +// 0xdf +// /* "":8528:8545 */ +// calldataload +// /* "":8566:8583 */ +// swapn{190} +// /* "":8579:8582 */ +// 0xe0 +// /* "":8566:8583 */ +// calldataload +// /* "":8604:8621 */ +// swapn{192} +// /* "":8617:8620 */ +// 0xe1 +// /* "":8604:8621 */ +// calldataload +// /* "":8642:8659 */ +// swapn{194} +// /* "":8655:8658 */ +// 0xe2 +// /* "":8642:8659 */ +// calldataload +// /* "":8680:8697 */ +// swapn{196} +// /* "":8693:8696 */ +// 0xe3 +// /* "":8680:8697 */ +// calldataload +// /* "":8718:8735 */ +// swapn{198} +// /* "":8731:8734 */ +// 0xe4 +// /* "":8718:8735 */ +// calldataload +// /* "":8756:8773 */ +// swapn{200} +// /* "":8769:8772 */ +// 0xe5 +// /* "":8756:8773 */ +// calldataload +// /* "":8794:8811 */ +// swapn{202} +// /* "":8807:8810 */ +// 0xe6 +// /* "":8794:8811 */ +// calldataload +// /* "":8832:8849 */ +// swapn{204} +// /* "":8845:8848 */ +// 0xe7 +// /* "":8832:8849 */ +// calldataload +// /* "":8870:8887 */ +// swapn{206} +// /* "":8883:8886 */ +// 0xe8 +// /* "":8870:8887 */ +// calldataload +// /* "":8908:8925 */ +// swapn{208} +// /* "":8921:8924 */ +// 0xe9 +// /* "":8908:8925 */ +// calldataload +// /* "":8946:8963 */ +// swapn{210} +// /* "":8959:8962 */ +// 0xea +// /* "":8946:8963 */ +// calldataload +// /* "":8984:9001 */ +// swapn{212} +// /* "":8997:9000 */ +// 0xeb +// /* "":8984:9001 */ +// calldataload +// /* "":9022:9039 */ +// swapn{214} +// /* "":9035:9038 */ +// 0xec +// /* "":9022:9039 */ +// calldataload +// /* "":9060:9077 */ +// swapn{216} +// /* "":9073:9076 */ +// 0xed +// /* "":9060:9077 */ +// calldataload +// /* "":9098:9115 */ +// swapn{218} +// /* "":9111:9114 */ +// 0xee +// /* "":9098:9115 */ +// calldataload +// /* "":9136:9153 */ +// swapn{220} +// /* "":9149:9152 */ +// 0xef +// /* "":9136:9153 */ +// calldataload +// /* "":9174:9191 */ +// swapn{222} +// /* "":9187:9190 */ +// 0xf0 +// /* "":9174:9191 */ +// calldataload +// /* "":9212:9229 */ +// swapn{224} +// /* "":9225:9228 */ +// 0xf1 +// /* "":9212:9229 */ +// calldataload +// /* "":9250:9267 */ +// swapn{226} +// /* "":9263:9266 */ +// 0xf2 +// /* "":9250:9267 */ +// calldataload +// /* "":9288:9305 */ +// swapn{228} +// /* "":9301:9304 */ +// 0xf3 +// /* "":9288:9305 */ +// calldataload +// /* "":9326:9343 */ +// swapn{230} +// /* "":9339:9342 */ +// 0xf4 +// /* "":9326:9343 */ +// calldataload +// /* "":9364:9381 */ +// swapn{232} +// /* "":9377:9380 */ +// 0xf5 +// /* "":9364:9381 */ +// calldataload +// /* "":9402:9419 */ +// swapn{234} +// /* "":9415:9418 */ +// 0xf6 +// /* "":9402:9419 */ +// calldataload +// /* "":9440:9457 */ +// swapn{236} +// /* "":9453:9456 */ +// 0xf7 +// /* "":9440:9457 */ +// calldataload +// /* "":9478:9495 */ +// swapn{238} +// /* "":9491:9494 */ +// 0xf8 +// /* "":9478:9495 */ +// calldataload +// /* "":9516:9533 */ +// swapn{240} +// /* "":9529:9532 */ +// 0xf9 +// /* "":9516:9533 */ +// calldataload +// /* "":9554:9571 */ +// swapn{242} +// /* "":9567:9570 */ +// 0xfa +// /* "":9554:9571 */ +// calldataload +// /* "":9592:9609 */ +// swapn{244} +// /* "":9605:9608 */ +// 0xfb +// /* "":9592:9609 */ +// calldataload +// /* "":9630:9647 */ +// swapn{246} +// /* "":9643:9646 */ +// 0xfc +// /* "":9630:9647 */ +// calldataload +// /* "":9668:9685 */ +// swapn{248} +// /* "":9681:9684 */ +// 0xfd +// /* "":9668:9685 */ +// calldataload +// /* "":9706:9723 */ +// swapn{250} +// /* "":9719:9722 */ +// 0xfe +// /* "":9706:9723 */ +// calldataload +// /* "":9744:9761 */ +// swapn{252} +// /* "":9757:9760 */ +// 0xff +// /* "":9744:9761 */ +// calldataload +// /* "":9782:9799 */ +// swapn{254} +// /* "":9795:9798 */ +// 0x0100 +// /* "":9782:9799 */ +// calldataload +// /* "":9808:9821 */ +// swapn{256} +// /* "":9815:9816 */ +// 0x00 +// /* "":9808:9821 */ +// sstore +// /* "":9837:9838 */ +// 0x01 +// /* "":9830:9843 */ +// sstore +// /* "":9859:9860 */ +// 0x02 +// /* "":9852:9865 */ +// sstore +// /* "":9881:9882 */ +// 0x03 +// /* "":9874:9887 */ +// sstore +// /* "":9903:9904 */ +// 0x04 +// /* "":9896:9909 */ +// sstore +// /* "":9925:9926 */ +// 0x05 +// /* "":9918:9931 */ +// sstore +// /* "":9947:9948 */ +// 0x06 +// /* "":9940:9953 */ +// sstore +// /* "":9969:9970 */ +// 0x07 +// /* "":9962:9975 */ +// sstore +// /* "":9991:9992 */ +// 0x08 +// /* "":9984:9997 */ +// sstore +// /* "":10013:10014 */ +// 0x09 +// /* "":10006:10019 */ +// sstore +// /* "":10035:10037 */ +// 0x0a +// /* "":10028:10043 */ +// sstore +// /* "":10059:10061 */ +// 0x0b +// /* "":10052:10067 */ +// sstore +// /* "":10083:10085 */ +// 0x0c +// /* "":10076:10091 */ +// sstore +// /* "":10107:10109 */ +// 0x0d +// /* "":10100:10115 */ +// sstore +// /* "":10131:10133 */ +// 0x0e +// /* "":10124:10139 */ +// sstore +// /* "":10155:10157 */ +// 0x0f +// /* "":10148:10163 */ +// sstore +// /* "":10179:10181 */ +// 0x10 +// /* "":10172:10187 */ +// sstore +// /* "":10203:10205 */ +// 0x11 +// /* "":10196:10211 */ +// sstore +// /* "":10227:10229 */ +// 0x12 +// /* "":10220:10235 */ +// sstore +// /* "":10251:10253 */ +// 0x13 +// /* "":10244:10259 */ +// sstore +// /* "":10275:10277 */ +// 0x14 +// /* "":10268:10283 */ +// sstore +// /* "":10299:10301 */ +// 0x15 +// /* "":10292:10307 */ +// sstore +// /* "":10323:10325 */ +// 0x16 +// /* "":10316:10331 */ +// sstore +// /* "":10347:10349 */ +// 0x17 +// /* "":10340:10355 */ +// sstore +// /* "":10371:10373 */ +// 0x18 +// /* "":10364:10379 */ +// sstore +// /* "":10395:10397 */ +// 0x19 +// /* "":10388:10403 */ +// sstore +// /* "":10419:10421 */ +// 0x1a +// /* "":10412:10427 */ +// sstore +// /* "":10443:10445 */ +// 0x1b +// /* "":10436:10451 */ +// sstore +// /* "":10467:10469 */ +// 0x1c +// /* "":10460:10475 */ +// sstore +// /* "":10491:10493 */ +// 0x1d +// /* "":10484:10499 */ +// sstore +// /* "":10515:10517 */ +// 0x1e +// /* "":10508:10523 */ +// sstore +// /* "":10539:10541 */ +// 0x1f +// /* "":10532:10547 */ +// sstore +// /* "":10563:10565 */ +// 0x20 +// /* "":10556:10571 */ +// sstore +// /* "":10587:10589 */ +// 0x21 +// /* "":10580:10595 */ +// sstore +// /* "":10611:10613 */ +// 0x22 +// /* "":10604:10619 */ +// sstore +// /* "":10635:10637 */ +// 0x23 +// /* "":10628:10643 */ +// sstore +// /* "":10659:10661 */ +// 0x24 +// /* "":10652:10667 */ +// sstore +// /* "":10683:10685 */ +// 0x25 +// /* "":10676:10691 */ +// sstore +// /* "":10707:10709 */ +// 0x26 +// /* "":10700:10715 */ +// sstore +// /* "":10731:10733 */ +// 0x27 +// /* "":10724:10739 */ +// sstore +// /* "":10755:10757 */ +// 0x28 +// /* "":10748:10763 */ +// sstore +// /* "":10779:10781 */ +// 0x29 +// /* "":10772:10787 */ +// sstore +// /* "":10803:10805 */ +// 0x2a +// /* "":10796:10811 */ +// sstore +// /* "":10827:10829 */ +// 0x2b +// /* "":10820:10835 */ +// sstore +// /* "":10851:10853 */ +// 0x2c +// /* "":10844:10859 */ +// sstore +// /* "":10875:10877 */ +// 0x2d +// /* "":10868:10883 */ +// sstore +// /* "":10899:10901 */ +// 0x2e +// /* "":10892:10907 */ +// sstore +// /* "":10923:10925 */ +// 0x2f +// /* "":10916:10931 */ +// sstore +// /* "":10947:10949 */ +// 0x30 +// /* "":10940:10955 */ +// sstore +// /* "":10971:10973 */ +// 0x31 +// /* "":10964:10979 */ +// sstore +// /* "":10995:10997 */ +// 0x32 +// /* "":10988:11003 */ +// sstore +// /* "":11019:11021 */ +// 0x33 +// /* "":11012:11027 */ +// sstore +// /* "":11043:11045 */ +// 0x34 +// /* "":11036:11051 */ +// sstore +// /* "":11067:11069 */ +// 0x35 +// /* "":11060:11075 */ +// sstore +// /* "":11091:11093 */ +// 0x36 +// /* "":11084:11099 */ +// sstore +// /* "":11115:11117 */ +// 0x37 +// /* "":11108:11123 */ +// sstore +// /* "":11139:11141 */ +// 0x38 +// /* "":11132:11147 */ +// sstore +// /* "":11163:11165 */ +// 0x39 +// /* "":11156:11171 */ +// sstore +// /* "":11187:11189 */ +// 0x3a +// /* "":11180:11195 */ +// sstore +// /* "":11211:11213 */ +// 0x3b +// /* "":11204:11219 */ +// sstore +// /* "":11235:11237 */ +// 0x3c +// /* "":11228:11243 */ +// sstore +// /* "":11259:11261 */ +// 0x3d +// /* "":11252:11267 */ +// sstore +// /* "":11283:11285 */ +// 0x3e +// /* "":11276:11291 */ +// sstore +// /* "":11307:11309 */ +// 0x3f +// /* "":11300:11315 */ +// sstore +// /* "":11331:11333 */ +// 0x40 +// /* "":11324:11339 */ +// sstore +// /* "":11355:11357 */ +// 0x41 +// /* "":11348:11363 */ +// sstore +// /* "":11379:11381 */ +// 0x42 +// /* "":11372:11387 */ +// sstore +// /* "":11403:11405 */ +// 0x43 +// /* "":11396:11411 */ +// sstore +// /* "":11427:11429 */ +// 0x44 +// /* "":11420:11435 */ +// sstore +// /* "":11451:11453 */ +// 0x45 +// /* "":11444:11459 */ +// sstore +// /* "":11475:11477 */ +// 0x46 +// /* "":11468:11483 */ +// sstore +// /* "":11499:11501 */ +// 0x47 +// /* "":11492:11507 */ +// sstore +// /* "":11523:11525 */ +// 0x48 +// /* "":11516:11531 */ +// sstore +// /* "":11547:11549 */ +// 0x49 +// /* "":11540:11555 */ +// sstore +// /* "":11571:11573 */ +// 0x4a +// /* "":11564:11579 */ +// sstore +// /* "":11595:11597 */ +// 0x4b +// /* "":11588:11603 */ +// sstore +// /* "":11619:11621 */ +// 0x4c +// /* "":11612:11627 */ +// sstore +// /* "":11643:11645 */ +// 0x4d +// /* "":11636:11651 */ +// sstore +// /* "":11667:11669 */ +// 0x4e +// /* "":11660:11675 */ +// sstore +// /* "":11691:11693 */ +// 0x4f +// /* "":11684:11699 */ +// sstore +// /* "":11715:11717 */ +// 0x50 +// /* "":11708:11723 */ +// sstore +// /* "":11739:11741 */ +// 0x51 +// /* "":11732:11747 */ +// sstore +// /* "":11763:11765 */ +// 0x52 +// /* "":11756:11771 */ +// sstore +// /* "":11787:11789 */ +// 0x53 +// /* "":11780:11795 */ +// sstore +// /* "":11811:11813 */ +// 0x54 +// /* "":11804:11819 */ +// sstore +// /* "":11835:11837 */ +// 0x55 +// /* "":11828:11843 */ +// sstore +// /* "":11859:11861 */ +// 0x56 +// /* "":11852:11867 */ +// sstore +// /* "":11883:11885 */ +// 0x57 +// /* "":11876:11891 */ +// sstore +// /* "":11907:11909 */ +// 0x58 +// /* "":11900:11915 */ +// sstore +// /* "":11931:11933 */ +// 0x59 +// /* "":11924:11939 */ +// sstore +// /* "":11955:11957 */ +// 0x5a +// /* "":11948:11963 */ +// sstore +// /* "":11979:11981 */ +// 0x5b +// /* "":11972:11987 */ +// sstore +// /* "":12003:12005 */ +// 0x5c +// /* "":11996:12011 */ +// sstore +// /* "":12027:12029 */ +// 0x5d +// /* "":12020:12035 */ +// sstore +// /* "":12051:12053 */ +// 0x5e +// /* "":12044:12059 */ +// sstore +// /* "":12075:12077 */ +// 0x5f +// /* "":12068:12083 */ +// sstore +// /* "":12099:12101 */ +// 0x60 +// /* "":12092:12107 */ +// sstore +// /* "":12123:12125 */ +// 0x61 +// /* "":12116:12131 */ +// sstore +// /* "":12147:12149 */ +// 0x62 +// /* "":12140:12155 */ +// sstore +// /* "":12171:12173 */ +// 0x63 +// /* "":12164:12179 */ +// sstore +// /* "":12195:12198 */ +// 0x64 +// /* "":12188:12205 */ +// sstore +// /* "":12221:12224 */ +// 0x65 +// /* "":12214:12231 */ +// sstore +// /* "":12247:12250 */ +// 0x66 +// /* "":12240:12257 */ +// sstore +// /* "":12273:12276 */ +// 0x67 +// /* "":12266:12283 */ +// sstore +// /* "":12299:12302 */ +// 0x68 +// /* "":12292:12309 */ +// sstore +// /* "":12325:12328 */ +// 0x69 +// /* "":12318:12335 */ +// sstore +// /* "":12351:12354 */ +// 0x6a +// /* "":12344:12361 */ +// sstore +// /* "":12377:12380 */ +// 0x6b +// /* "":12370:12387 */ +// sstore +// /* "":12403:12406 */ +// 0x6c +// /* "":12396:12413 */ +// sstore +// /* "":12429:12432 */ +// 0x6d +// /* "":12422:12439 */ +// sstore +// /* "":12455:12458 */ +// 0x6e +// /* "":12448:12465 */ +// sstore +// /* "":12481:12484 */ +// 0x6f +// /* "":12474:12491 */ +// sstore +// /* "":12507:12510 */ +// 0x70 +// /* "":12500:12517 */ +// sstore +// /* "":12533:12536 */ +// 0x71 +// /* "":12526:12543 */ +// sstore +// /* "":12559:12562 */ +// 0x72 +// /* "":12552:12569 */ +// sstore +// /* "":12585:12588 */ +// 0x73 +// /* "":12578:12595 */ +// sstore +// /* "":12611:12614 */ +// 0x74 +// /* "":12604:12621 */ +// sstore +// /* "":12637:12640 */ +// 0x75 +// /* "":12630:12647 */ +// sstore +// /* "":12663:12666 */ +// 0x76 +// /* "":12656:12673 */ +// sstore +// /* "":12689:12692 */ +// 0x77 +// /* "":12682:12699 */ +// sstore +// /* "":12715:12718 */ +// 0x78 +// /* "":12708:12725 */ +// sstore +// /* "":12741:12744 */ +// 0x79 +// /* "":12734:12751 */ +// sstore +// /* "":12767:12770 */ +// 0x7a +// /* "":12760:12777 */ +// sstore +// /* "":12793:12796 */ +// 0x7b +// /* "":12786:12803 */ +// sstore +// /* "":12819:12822 */ +// 0x7c +// /* "":12812:12829 */ +// sstore +// /* "":12845:12848 */ +// 0x7d +// /* "":12838:12855 */ +// sstore +// /* "":12871:12874 */ +// 0x7e +// /* "":12864:12881 */ +// sstore +// /* "":12897:12900 */ +// 0x7f +// /* "":12890:12907 */ +// sstore +// /* "":12923:12926 */ +// 0x80 +// /* "":12916:12933 */ +// sstore +// /* "":12949:12952 */ +// 0x81 +// /* "":12942:12959 */ +// sstore +// /* "":12975:12978 */ +// 0x82 +// /* "":12968:12985 */ +// sstore +// /* "":13001:13004 */ +// 0x83 +// /* "":12994:13011 */ +// sstore +// /* "":13027:13030 */ +// 0x84 +// /* "":13020:13037 */ +// sstore +// /* "":13053:13056 */ +// 0x85 +// /* "":13046:13063 */ +// sstore +// /* "":13079:13082 */ +// 0x86 +// /* "":13072:13089 */ +// sstore +// /* "":13105:13108 */ +// 0x87 +// /* "":13098:13115 */ +// sstore +// /* "":13131:13134 */ +// 0x88 +// /* "":13124:13141 */ +// sstore +// /* "":13157:13160 */ +// 0x89 +// /* "":13150:13167 */ +// sstore +// /* "":13183:13186 */ +// 0x8a +// /* "":13176:13193 */ +// sstore +// /* "":13209:13212 */ +// 0x8b +// /* "":13202:13219 */ +// sstore +// /* "":13235:13238 */ +// 0x8c +// /* "":13228:13245 */ +// sstore +// /* "":13261:13264 */ +// 0x8d +// /* "":13254:13271 */ +// sstore +// /* "":13287:13290 */ +// 0x8e +// /* "":13280:13297 */ +// sstore +// /* "":13313:13316 */ +// 0x8f +// /* "":13306:13323 */ +// sstore +// /* "":13339:13342 */ +// 0x90 +// /* "":13332:13349 */ +// sstore +// /* "":13365:13368 */ +// 0x91 +// /* "":13358:13375 */ +// sstore +// /* "":13391:13394 */ +// 0x92 +// /* "":13384:13401 */ +// sstore +// /* "":13417:13420 */ +// 0x93 +// /* "":13410:13427 */ +// sstore +// /* "":13443:13446 */ +// 0x94 +// /* "":13436:13453 */ +// sstore +// /* "":13469:13472 */ +// 0x95 +// /* "":13462:13479 */ +// sstore +// /* "":13495:13498 */ +// 0x96 +// /* "":13488:13505 */ +// sstore +// /* "":13521:13524 */ +// 0x97 +// /* "":13514:13531 */ +// sstore +// /* "":13547:13550 */ +// 0x98 +// /* "":13540:13557 */ +// sstore +// /* "":13573:13576 */ +// 0x99 +// /* "":13566:13583 */ +// sstore +// /* "":13599:13602 */ +// 0x9a +// /* "":13592:13609 */ +// sstore +// /* "":13625:13628 */ +// 0x9b +// /* "":13618:13635 */ +// sstore +// /* "":13651:13654 */ +// 0x9c +// /* "":13644:13661 */ +// sstore +// /* "":13677:13680 */ +// 0x9d +// /* "":13670:13687 */ +// sstore +// /* "":13703:13706 */ +// 0x9e +// /* "":13696:13713 */ +// sstore +// /* "":13729:13732 */ +// 0x9f +// /* "":13722:13739 */ +// sstore +// /* "":13755:13758 */ +// 0xa0 +// /* "":13748:13765 */ +// sstore +// /* "":13781:13784 */ +// 0xa1 +// /* "":13774:13791 */ +// sstore +// /* "":13807:13810 */ +// 0xa2 +// /* "":13800:13817 */ +// sstore +// /* "":13833:13836 */ +// 0xa3 +// /* "":13826:13843 */ +// sstore +// /* "":13859:13862 */ +// 0xa4 +// /* "":13852:13869 */ +// sstore +// /* "":13885:13888 */ +// 0xa5 +// /* "":13878:13895 */ +// sstore +// /* "":13911:13914 */ +// 0xa6 +// /* "":13904:13921 */ +// sstore +// /* "":13937:13940 */ +// 0xa7 +// /* "":13930:13947 */ +// sstore +// /* "":13963:13966 */ +// 0xa8 +// /* "":13956:13973 */ +// sstore +// /* "":13989:13992 */ +// 0xa9 +// /* "":13982:13999 */ +// sstore +// /* "":14015:14018 */ +// 0xaa +// /* "":14008:14025 */ +// sstore +// /* "":14041:14044 */ +// 0xab +// /* "":14034:14051 */ +// sstore +// /* "":14067:14070 */ +// 0xac +// /* "":14060:14077 */ +// sstore +// /* "":14093:14096 */ +// 0xad +// /* "":14086:14103 */ +// sstore +// /* "":14119:14122 */ +// 0xae +// /* "":14112:14129 */ +// sstore +// /* "":14145:14148 */ +// 0xaf +// /* "":14138:14155 */ +// sstore +// /* "":14171:14174 */ +// 0xb0 +// /* "":14164:14181 */ +// sstore +// /* "":14197:14200 */ +// 0xb1 +// /* "":14190:14207 */ +// sstore +// /* "":14223:14226 */ +// 0xb2 +// /* "":14216:14233 */ +// sstore +// /* "":14249:14252 */ +// 0xb3 +// /* "":14242:14259 */ +// sstore +// /* "":14275:14278 */ +// 0xb4 +// /* "":14268:14285 */ +// sstore +// /* "":14301:14304 */ +// 0xb5 +// /* "":14294:14311 */ +// sstore +// /* "":14327:14330 */ +// 0xb6 +// /* "":14320:14337 */ +// sstore +// /* "":14353:14356 */ +// 0xb7 +// /* "":14346:14363 */ +// sstore +// /* "":14379:14382 */ +// 0xb8 +// /* "":14372:14389 */ +// sstore +// /* "":14405:14408 */ +// 0xb9 +// /* "":14398:14415 */ +// sstore +// /* "":14431:14434 */ +// 0xba +// /* "":14424:14441 */ +// sstore +// /* "":14457:14460 */ +// 0xbb +// /* "":14450:14467 */ +// sstore +// /* "":14483:14486 */ +// 0xbc +// /* "":14476:14493 */ +// sstore +// /* "":14509:14512 */ +// 0xbd +// /* "":14502:14519 */ +// sstore +// /* "":14535:14538 */ +// 0xbe +// /* "":14528:14545 */ +// sstore +// /* "":14561:14564 */ +// 0xbf +// /* "":14554:14571 */ +// sstore +// /* "":14587:14590 */ +// 0xc0 +// /* "":14580:14597 */ +// sstore +// /* "":14613:14616 */ +// 0xc1 +// /* "":14606:14623 */ +// sstore +// /* "":14639:14642 */ +// 0xc2 +// /* "":14632:14649 */ +// sstore +// /* "":14665:14668 */ +// 0xc3 +// /* "":14658:14675 */ +// sstore +// /* "":14691:14694 */ +// 0xc4 +// /* "":14684:14701 */ +// sstore +// /* "":14717:14720 */ +// 0xc5 +// /* "":14710:14727 */ +// sstore +// /* "":14743:14746 */ +// 0xc6 +// /* "":14736:14753 */ +// sstore +// /* "":14769:14772 */ +// 0xc7 +// /* "":14762:14779 */ +// sstore +// /* "":14795:14798 */ +// 0xc8 +// /* "":14788:14805 */ +// sstore +// /* "":14821:14824 */ +// 0xc9 +// /* "":14814:14831 */ +// sstore +// /* "":14847:14850 */ +// 0xca +// /* "":14840:14857 */ +// sstore +// /* "":14873:14876 */ +// 0xcb +// /* "":14866:14883 */ +// sstore +// /* "":14899:14902 */ +// 0xcc +// /* "":14892:14909 */ +// sstore +// /* "":14925:14928 */ +// 0xcd +// /* "":14918:14935 */ +// sstore +// /* "":14951:14954 */ +// 0xce +// /* "":14944:14961 */ +// sstore +// /* "":14977:14980 */ +// 0xcf +// /* "":14970:14987 */ +// sstore +// /* "":15003:15006 */ +// 0xd0 +// /* "":14996:15013 */ +// sstore +// /* "":15029:15032 */ +// 0xd1 +// /* "":15022:15039 */ +// sstore +// /* "":15055:15058 */ +// 0xd2 +// /* "":15048:15065 */ +// sstore +// /* "":15081:15084 */ +// 0xd3 +// /* "":15074:15091 */ +// sstore +// /* "":15107:15110 */ +// 0xd4 +// /* "":15100:15117 */ +// sstore +// /* "":15133:15136 */ +// 0xd5 +// /* "":15126:15143 */ +// sstore +// /* "":15159:15162 */ +// 0xd6 +// /* "":15152:15169 */ +// sstore +// /* "":15185:15188 */ +// 0xd7 +// /* "":15178:15195 */ +// sstore +// /* "":15211:15214 */ +// 0xd8 +// /* "":15204:15221 */ +// sstore +// /* "":15237:15240 */ +// 0xd9 +// /* "":15230:15247 */ +// sstore +// /* "":15263:15266 */ +// 0xda +// /* "":15256:15273 */ +// sstore +// /* "":15289:15292 */ +// 0xdb +// /* "":15282:15299 */ +// sstore +// /* "":15315:15318 */ +// 0xdc +// /* "":15308:15325 */ +// sstore +// /* "":15341:15344 */ +// 0xdd +// /* "":15334:15351 */ +// sstore +// /* "":15367:15370 */ +// 0xde +// /* "":15360:15377 */ +// sstore +// /* "":15393:15396 */ +// 0xdf +// /* "":15386:15403 */ +// sstore +// /* "":15419:15422 */ +// 0xe0 +// /* "":15412:15429 */ +// sstore +// /* "":15445:15448 */ +// 0xe1 +// /* "":15438:15455 */ +// sstore +// /* "":15471:15474 */ +// 0xe2 +// /* "":15464:15481 */ +// sstore +// /* "":15497:15500 */ +// 0xe3 +// /* "":15490:15507 */ +// sstore +// /* "":15523:15526 */ +// 0xe4 +// /* "":15516:15533 */ +// sstore +// /* "":15549:15552 */ +// 0xe5 +// /* "":15542:15559 */ +// sstore +// /* "":15575:15578 */ +// 0xe6 +// /* "":15568:15585 */ +// sstore +// /* "":15601:15604 */ +// 0xe7 +// /* "":15594:15611 */ +// sstore +// /* "":15627:15630 */ +// 0xe8 +// /* "":15620:15637 */ +// sstore +// /* "":15653:15656 */ +// 0xe9 +// /* "":15646:15663 */ +// sstore +// /* "":15679:15682 */ +// 0xea +// /* "":15672:15689 */ +// sstore +// /* "":15705:15708 */ +// 0xeb +// /* "":15698:15715 */ +// sstore +// /* "":15731:15734 */ +// 0xec +// /* "":15724:15741 */ +// sstore +// /* "":15757:15760 */ +// 0xed +// /* "":15750:15767 */ +// sstore +// /* "":15783:15786 */ +// 0xee +// /* "":15776:15793 */ +// sstore +// /* "":15809:15812 */ +// 0xef +// /* "":15802:15819 */ +// sstore +// /* "":15835:15838 */ +// 0xf0 +// /* "":15828:15845 */ +// sstore +// /* "":15861:15864 */ +// 0xf1 +// /* "":15854:15871 */ +// sstore +// /* "":15887:15890 */ +// 0xf2 +// /* "":15880:15897 */ +// sstore +// /* "":15913:15916 */ +// 0xf3 +// /* "":15906:15923 */ +// sstore +// /* "":15939:15942 */ +// 0xf4 +// /* "":15932:15949 */ +// sstore +// /* "":15965:15968 */ +// 0xf5 +// /* "":15958:15975 */ +// sstore +// /* "":15991:15994 */ +// 0xf6 +// /* "":15984:16001 */ +// sstore +// /* "":16017:16020 */ +// 0xf7 +// /* "":16010:16027 */ +// sstore +// /* "":16043:16046 */ +// 0xf8 +// /* "":16036:16053 */ +// sstore +// /* "":16069:16072 */ +// 0xf9 +// /* "":16062:16079 */ +// sstore +// /* "":16095:16098 */ +// 0xfa +// /* "":16088:16105 */ +// sstore +// /* "":16121:16124 */ +// 0xfb +// /* "":16114:16131 */ +// sstore +// /* "":16147:16150 */ +// 0xfc +// /* "":16140:16157 */ +// sstore +// /* "":16173:16176 */ +// 0xfd +// /* "":16166:16183 */ +// sstore +// /* "":16199:16202 */ +// 0xfe +// /* "":16192:16209 */ +// sstore +// /* "":16225:16228 */ +// 0xff +// /* "":16218:16235 */ +// sstore +// /* "":16251:16254 */ +// 0x0100 +// /* "":16244:16261 */ +// sstore +// /* "":25:16267 */ +// stop diff --git a/test/libyul/yulStackShuffling/pop_early_to_avoid_swap17.stack b/test/libyul/yulStackShuffling/pop_early_to_avoid_swap17.stack new file mode 100644 index 000000000000..6ec0cbb0b4ea --- /dev/null +++ b/test/libyul/yulStackShuffling/pop_early_to_avoid_swap17.stack @@ -0,0 +1,12 @@ +// We avoid a SWAP17 here by first removing duplicates on stack. +[ junk v00 v01 v02 v03 v04 v05 v06 v07 v08 v09 v10 v11 v12 v13 v14 junk deep ] +[ deep v00 v01 v02 v03 v04 v05 v06 v07 v08 v09 v10 v11 v12 v13 v14 junk ] +// ---- +// [ junk v00 v01 v02 v03 v04 v05 v06 v07 v08 v09 v10 v11 v12 v13 v14 junk deep ] +// SWAP1 +// [ junk v00 v01 v02 v03 v04 v05 v06 v07 v08 v09 v10 v11 v12 v13 v14 deep junk ] +// POP +// [ junk v00 v01 v02 v03 v04 v05 v06 v07 v08 v09 v10 v11 v12 v13 v14 deep ] +// SWAP16 +// [ deep v00 v01 v02 v03 v04 v05 v06 v07 v08 v09 v10 v11 v12 v13 v14 junk ] +// 3 operations diff --git a/test/libyul/yulStackShuffling/swap17.stack b/test/libyul/yulStackShuffling/swap17.stack new file mode 100644 index 000000000000..6e62854a9492 --- /dev/null +++ b/test/libyul/yulStackShuffling/swap17.stack @@ -0,0 +1,13 @@ +// With a SWAP17 at our disposal, we do not need to first remove duplicates from stack +// as seen in pop_early_to_avoid_swap17.stack. +[ junk v00 v01 v02 v03 v04 v05 v06 v07 v08 v09 v10 v11 v12 v13 v14 junk deep ] +[ deep v00 v01 v02 v03 v04 v05 v06 v07 v08 v09 v10 v11 v12 v13 v14 junk ] +// ==== +// maximumStackDepth: 256 +// ---- +// [ junk v00 v01 v02 v03 v04 v05 v06 v07 v08 v09 v10 v11 v12 v13 v14 junk deep ] +// SWAP17 +// [ deep v00 v01 v02 v03 v04 v05 v06 v07 v08 v09 v10 v11 v12 v13 v14 junk junk ] +// POP +// [ deep v00 v01 v02 v03 v04 v05 v06 v07 v08 v09 v10 v11 v12 v13 v14 junk ] +// 2 operations diff --git a/test/libyul/yulStackShuffling/swap_cycle.stack b/test/libyul/yulStackShuffling/swap_cycle.stack index fbda89ebfd2a..fd99cea6ec15 100644 --- a/test/libyul/yulStackShuffling/swap_cycle.stack +++ b/test/libyul/yulStackShuffling/swap_cycle.stack @@ -20,3 +20,4 @@ // [ v1 v0 v2 v3 v4 v5 v6 v7 v9 v10 v11 v12 v13 v14 v15 v16 RET JUNK ] // PUSH JUNK // [ v1 v0 v2 v3 v4 v5 v6 v7 v9 v10 v11 v12 v13 v14 v15 v16 RET JUNK JUNK ] +// 9 operations From 4d38789c12fe4b70ea3ae66b7802421c573007ea Mon Sep 17 00:00:00 2001 From: Daniel Kirchner Date: Wed, 26 Feb 2025 16:05:09 +0100 Subject: [PATCH 0829/1022] Do not run StackCompressor and StackLimitEvader on EOF. --- libyul/optimiser/StackCompressor.cpp | 5 ++-- libyul/optimiser/StackLimitEvader.cpp | 17 +++++++++++ libyul/optimiser/Suite.cpp | 30 +++++++++++-------- .../fakeStackLimitEvader/connected.yul | 2 ++ .../fakeStackLimitEvader/function_arg.yul | 2 ++ ...lti_variable_declaration_without_value.yul | 2 ++ .../fakeStackLimitEvader/outer_block.yul | 2 ++ .../fakeStackLimitEvader/return_leave.yul | 2 ++ .../fakeStackLimitEvader/return_one.yul | 2 ++ .../return_one_with_args.yul | 2 ++ .../same_variable_in_lhs_and_rhs.yul | 2 ++ .../fakeStackLimitEvader/stub.yul | 2 ++ .../stackCompressor/noInline.yul | 2 ++ .../stackLimitEvader/cycle.yul | 2 ++ .../stackLimitEvader/cycle_after.yul | 2 ++ .../stackLimitEvader/cycle_after_2.yul | 2 ++ .../stackLimitEvader/cycle_before.yul | 2 ++ .../stackLimitEvader/cycle_before_2.yul | 2 ++ .../stackLimitEvader/cycle_before_after.yul | 2 ++ .../stackLimitEvader/function_arg.yul | 2 ++ .../stackLimitEvader/stub.yul | 2 ++ .../stackLimitEvader/too_many_args_14.yul | 2 ++ .../stackLimitEvader/too_many_args_15.yul | 2 ++ .../stackLimitEvader/too_many_args_16.yul | 2 ++ .../stackLimitEvader/too_many_returns_15.yul | 2 ++ .../stackLimitEvader/too_many_returns_16.yul | 2 ++ .../stackLimitEvader/tree.yul | 2 ++ .../verbatim_many_arguments.yul | 2 ++ .../verbatim_many_arguments_and_returns.yul | 2 ++ .../verbatim_many_returns.yul | 2 ++ 30 files changed, 90 insertions(+), 16 deletions(-) diff --git a/libyul/optimiser/StackCompressor.cpp b/libyul/optimiser/StackCompressor.cpp index 1dac1a66fe21..3c27cc20ff10 100644 --- a/libyul/optimiser/StackCompressor.cpp +++ b/libyul/optimiser/StackCompressor.cpp @@ -249,15 +249,14 @@ std::tuple StackCompressor::run( ); bool usesOptimizedCodeGenerator = false; bool simulateFunctionsWithJumps = true; - size_t reachableStackDepth = 16; if (auto evmDialect = dynamic_cast(_object.dialect())) { + yulAssert(!evmDialect->eofVersion().has_value(), "StackCompressor does not support EOF."); usesOptimizedCodeGenerator = _optimizeStackAllocation && evmDialect->evmVersion().canOverchargeGasForCall() && evmDialect->providesObjectAccess(); simulateFunctionsWithJumps = !evmDialect->eofVersion().has_value(); - reachableStackDepth = evmDialect->reachableStackDepth(); } bool allowMSizeOptimization = !MSizeFinder::containsMSize(*_object.dialect(), _object.code()->root()); Block astRoot = std::get(ASTCopier{}(_object.code()->root())); @@ -272,7 +271,7 @@ std::tuple StackCompressor::run( eliminateVariablesOptimizedCodegen( *_object.dialect(), astRoot, - StackLayoutGenerator::reportStackTooDeep(*cfg, simulateFunctionsWithJumps, reachableStackDepth), + StackLayoutGenerator::reportStackTooDeep(*cfg, simulateFunctionsWithJumps, 16u), allowMSizeOptimization ); } diff --git a/libyul/optimiser/StackLimitEvader.cpp b/libyul/optimiser/StackLimitEvader.cpp index d62b3e93542f..a2a557de98d4 100644 --- a/libyul/optimiser/StackLimitEvader.cpp +++ b/libyul/optimiser/StackLimitEvader.cpp @@ -132,6 +132,10 @@ Block StackLimitEvader::run( evmDialect && evmDialect->providesObjectAccess(), "StackLimitEvader can only be run on objects using the EVMDialect with object access." ); + yulAssert( + !evmDialect->eofVersion().has_value(), + "StackLimitEvader does not support EOF." + ); auto astRoot = std::get(ASTCopier{}(_object.code()->root())); if (evmDialect && evmDialect->evmVersion().canOverchargeGasForCall()) { @@ -159,6 +163,15 @@ void StackLimitEvader::run( std::map> const& _stackTooDeepErrors ) { + auto const* evmDialect = dynamic_cast(&_context.dialect); + yulAssert( + evmDialect && evmDialect->providesObjectAccess(), + "StackLimitEvader can only be run on objects using the EVMDialect with object access." + ); + yulAssert( + !evmDialect->eofVersion().has_value(), + "StackLimitEvader does not support EOF." + ); std::map> unreachableVariables; for (auto&& [function, stackTooDeepErrors]: _stackTooDeepErrors) { @@ -183,6 +196,10 @@ void StackLimitEvader::run( evmDialect && evmDialect->providesObjectAccess(), "StackLimitEvader can only be run on objects using the EVMDialect with object access." ); + yulAssert( + !evmDialect->eofVersion().has_value(), + "StackLimitEvader does not support EOF." + ); std::vector memoryGuardCalls = findFunctionCalls(_astRoot, "memoryguard", *evmDialect); // Do not optimise, if no ``memoryguard`` call is found. diff --git a/libyul/optimiser/Suite.cpp b/libyul/optimiser/Suite.cpp index 766f96821b18..17698d74e2a0 100644 --- a/libyul/optimiser/Suite.cpp +++ b/libyul/optimiser/Suite.cpp @@ -163,25 +163,29 @@ void OptimiserSuite::run( } if (usesOptimizedCodeGenerator) { + if (!evmDialect->eofVersion().has_value()) { - PROFILER_PROBE("StackCompressor", probe); - _object.setCode(std::make_shared(dialect, std::move(astRoot))); - astRoot = std::get<1>(StackCompressor::run( - _object, - _optimizeStackAllocation, - stackCompressorMaxIterations - )); - } - if (evmDialect->providesObjectAccess()) - { - PROFILER_PROBE("StackLimitEvader", probe); - _object.setCode(std::make_shared(dialect, std::move(astRoot))); - astRoot = StackLimitEvader::run(suite.m_context, _object); + { + PROFILER_PROBE("StackCompressor", probe); + _object.setCode(std::make_shared(dialect, std::move(astRoot))); + astRoot = std::get<1>(StackCompressor::run( + _object, + _optimizeStackAllocation, + stackCompressorMaxIterations + )); + } + if (evmDialect->providesObjectAccess()) + { + PROFILER_PROBE("StackLimitEvader", probe); + _object.setCode(std::make_shared(dialect, std::move(astRoot))); + astRoot = StackLimitEvader::run(suite.m_context, _object); + } } } else if (evmDialect->providesObjectAccess() && _optimizeStackAllocation) { PROFILER_PROBE("StackLimitEvader", probe); + yulAssert(!evmDialect->eofVersion().has_value(), ""); _object.setCode(std::make_shared(dialect, std::move(astRoot))); astRoot = StackLimitEvader::run(suite.m_context, _object); } diff --git a/test/libyul/yulOptimizerTests/fakeStackLimitEvader/connected.yul b/test/libyul/yulOptimizerTests/fakeStackLimitEvader/connected.yul index 99e92c183edc..cc2cae6f652e 100644 --- a/test/libyul/yulOptimizerTests/fakeStackLimitEvader/connected.yul +++ b/test/libyul/yulOptimizerTests/fakeStackLimitEvader/connected.yul @@ -20,6 +20,8 @@ sstore(0, f()) let x, y := g() } +// ==== +// bytecodeFormat: legacy // ---- // step: fakeStackLimitEvader // diff --git a/test/libyul/yulOptimizerTests/fakeStackLimitEvader/function_arg.yul b/test/libyul/yulOptimizerTests/fakeStackLimitEvader/function_arg.yul index 0e5aa9e130f5..1accb5cef647 100644 --- a/test/libyul/yulOptimizerTests/fakeStackLimitEvader/function_arg.yul +++ b/test/libyul/yulOptimizerTests/fakeStackLimitEvader/function_arg.yul @@ -7,6 +7,8 @@ } sstore(1, h(32)) } +// ==== +// bytecodeFormat: legacy // ---- // step: fakeStackLimitEvader // diff --git a/test/libyul/yulOptimizerTests/fakeStackLimitEvader/multi_variable_declaration_without_value.yul b/test/libyul/yulOptimizerTests/fakeStackLimitEvader/multi_variable_declaration_without_value.yul index 5650b580da5f..02a974784140 100644 --- a/test/libyul/yulOptimizerTests/fakeStackLimitEvader/multi_variable_declaration_without_value.yul +++ b/test/libyul/yulOptimizerTests/fakeStackLimitEvader/multi_variable_declaration_without_value.yul @@ -7,6 +7,8 @@ let z, $w } } +// ==== +// bytecodeFormat: legacy // ---- // step: fakeStackLimitEvader // diff --git a/test/libyul/yulOptimizerTests/fakeStackLimitEvader/outer_block.yul b/test/libyul/yulOptimizerTests/fakeStackLimitEvader/outer_block.yul index 023100cddee6..46c3cabb948a 100644 --- a/test/libyul/yulOptimizerTests/fakeStackLimitEvader/outer_block.yul +++ b/test/libyul/yulOptimizerTests/fakeStackLimitEvader/outer_block.yul @@ -3,6 +3,8 @@ let $x := 42 sstore(42, $x) } +// ==== +// bytecodeFormat: legacy // ---- // step: fakeStackLimitEvader // diff --git a/test/libyul/yulOptimizerTests/fakeStackLimitEvader/return_leave.yul b/test/libyul/yulOptimizerTests/fakeStackLimitEvader/return_leave.yul index 3b43bd534309..a510c65e96b1 100644 --- a/test/libyul/yulOptimizerTests/fakeStackLimitEvader/return_leave.yul +++ b/test/libyul/yulOptimizerTests/fakeStackLimitEvader/return_leave.yul @@ -14,6 +14,8 @@ } } +// ==== +// bytecodeFormat: legacy // ---- // step: fakeStackLimitEvader // diff --git a/test/libyul/yulOptimizerTests/fakeStackLimitEvader/return_one.yul b/test/libyul/yulOptimizerTests/fakeStackLimitEvader/return_one.yul index 50a9d64869f5..5566f97130af 100644 --- a/test/libyul/yulOptimizerTests/fakeStackLimitEvader/return_one.yul +++ b/test/libyul/yulOptimizerTests/fakeStackLimitEvader/return_one.yul @@ -12,6 +12,8 @@ } } +// ==== +// bytecodeFormat: legacy // ---- // step: fakeStackLimitEvader // diff --git a/test/libyul/yulOptimizerTests/fakeStackLimitEvader/return_one_with_args.yul b/test/libyul/yulOptimizerTests/fakeStackLimitEvader/return_one_with_args.yul index 706a46c6280c..42084c16efc4 100644 --- a/test/libyul/yulOptimizerTests/fakeStackLimitEvader/return_one_with_args.yul +++ b/test/libyul/yulOptimizerTests/fakeStackLimitEvader/return_one_with_args.yul @@ -12,6 +12,8 @@ } } +// ==== +// bytecodeFormat: legacy // ---- // step: fakeStackLimitEvader // diff --git a/test/libyul/yulOptimizerTests/fakeStackLimitEvader/same_variable_in_lhs_and_rhs.yul b/test/libyul/yulOptimizerTests/fakeStackLimitEvader/same_variable_in_lhs_and_rhs.yul index e6a9379dfde2..95ede59faa94 100644 --- a/test/libyul/yulOptimizerTests/fakeStackLimitEvader/same_variable_in_lhs_and_rhs.yul +++ b/test/libyul/yulOptimizerTests/fakeStackLimitEvader/same_variable_in_lhs_and_rhs.yul @@ -5,6 +5,8 @@ let $z := 42 $z := f($z) } +// ==== +// bytecodeFormat: legacy // ---- // step: fakeStackLimitEvader // diff --git a/test/libyul/yulOptimizerTests/fakeStackLimitEvader/stub.yul b/test/libyul/yulOptimizerTests/fakeStackLimitEvader/stub.yul index e86619e464b2..39db59956535 100644 --- a/test/libyul/yulOptimizerTests/fakeStackLimitEvader/stub.yul +++ b/test/libyul/yulOptimizerTests/fakeStackLimitEvader/stub.yul @@ -23,6 +23,8 @@ g(0) h(1, 2, 3, 4) } +// ==== +// bytecodeFormat: legacy // ---- // step: fakeStackLimitEvader // diff --git a/test/libyul/yulOptimizerTests/stackCompressor/noInline.yul b/test/libyul/yulOptimizerTests/stackCompressor/noInline.yul index 1a178abf0958..a7e9166577a9 100644 --- a/test/libyul/yulOptimizerTests/stackCompressor/noInline.yul +++ b/test/libyul/yulOptimizerTests/stackCompressor/noInline.yul @@ -2,6 +2,8 @@ let x := 8 function f() { let y := 9 } } +// ==== +// bytecodeFormat: legacy // ---- // step: stackCompressor // diff --git a/test/libyul/yulOptimizerTests/stackLimitEvader/cycle.yul b/test/libyul/yulOptimizerTests/stackLimitEvader/cycle.yul index 37da7f9b83d6..1f87ba5b8be2 100644 --- a/test/libyul/yulOptimizerTests/stackLimitEvader/cycle.yul +++ b/test/libyul/yulOptimizerTests/stackLimitEvader/cycle.yul @@ -44,6 +44,8 @@ sstore(23, g(sload(42))) } } +// ==== +// bytecodeFormat: legacy // ---- // step: stackLimitEvader // diff --git a/test/libyul/yulOptimizerTests/stackLimitEvader/cycle_after.yul b/test/libyul/yulOptimizerTests/stackLimitEvader/cycle_after.yul index 4480d012e69d..5b3aba01fcaa 100644 --- a/test/libyul/yulOptimizerTests/stackLimitEvader/cycle_after.yul +++ b/test/libyul/yulOptimizerTests/stackLimitEvader/cycle_after.yul @@ -44,6 +44,8 @@ v := h() } } +// ==== +// bytecodeFormat: legacy // ---- // step: stackLimitEvader // diff --git a/test/libyul/yulOptimizerTests/stackLimitEvader/cycle_after_2.yul b/test/libyul/yulOptimizerTests/stackLimitEvader/cycle_after_2.yul index 4468165f1e55..c33eea9b3535 100644 --- a/test/libyul/yulOptimizerTests/stackLimitEvader/cycle_after_2.yul +++ b/test/libyul/yulOptimizerTests/stackLimitEvader/cycle_after_2.yul @@ -47,6 +47,8 @@ v := h() } } +// ==== +// bytecodeFormat: legacy // ---- // step: stackLimitEvader // diff --git a/test/libyul/yulOptimizerTests/stackLimitEvader/cycle_before.yul b/test/libyul/yulOptimizerTests/stackLimitEvader/cycle_before.yul index e6819ea903e7..0715f494522e 100644 --- a/test/libyul/yulOptimizerTests/stackLimitEvader/cycle_before.yul +++ b/test/libyul/yulOptimizerTests/stackLimitEvader/cycle_before.yul @@ -49,6 +49,8 @@ sstore(mul(1,4), a1) } } +// ==== +// bytecodeFormat: legacy // ---- // step: stackLimitEvader // diff --git a/test/libyul/yulOptimizerTests/stackLimitEvader/cycle_before_2.yul b/test/libyul/yulOptimizerTests/stackLimitEvader/cycle_before_2.yul index a0259b1800ef..59872e4a75f2 100644 --- a/test/libyul/yulOptimizerTests/stackLimitEvader/cycle_before_2.yul +++ b/test/libyul/yulOptimizerTests/stackLimitEvader/cycle_before_2.yul @@ -52,6 +52,8 @@ sstore(mul(1,4), a1) } } +// ==== +// bytecodeFormat: legacy // ---- // step: stackLimitEvader // diff --git a/test/libyul/yulOptimizerTests/stackLimitEvader/cycle_before_after.yul b/test/libyul/yulOptimizerTests/stackLimitEvader/cycle_before_after.yul index f5c068d5e382..ad9366322b18 100644 --- a/test/libyul/yulOptimizerTests/stackLimitEvader/cycle_before_after.yul +++ b/test/libyul/yulOptimizerTests/stackLimitEvader/cycle_before_after.yul @@ -53,6 +53,8 @@ v := h() } } +// ==== +// bytecodeFormat: legacy // ---- // step: stackLimitEvader // diff --git a/test/libyul/yulOptimizerTests/stackLimitEvader/function_arg.yul b/test/libyul/yulOptimizerTests/stackLimitEvader/function_arg.yul index 27f0705157c4..8501a8d028b8 100644 --- a/test/libyul/yulOptimizerTests/stackLimitEvader/function_arg.yul +++ b/test/libyul/yulOptimizerTests/stackLimitEvader/function_arg.yul @@ -40,6 +40,8 @@ sstore(mul(1,4), a1) } } +// ==== +// bytecodeFormat: legacy // ---- // step: stackLimitEvader // diff --git a/test/libyul/yulOptimizerTests/stackLimitEvader/stub.yul b/test/libyul/yulOptimizerTests/stackLimitEvader/stub.yul index 9f5001c87686..338c8e983ec5 100644 --- a/test/libyul/yulOptimizerTests/stackLimitEvader/stub.yul +++ b/test/libyul/yulOptimizerTests/stackLimitEvader/stub.yul @@ -45,6 +45,8 @@ sstore(mul(1,4), a1) } } +// ==== +// bytecodeFormat: legacy // ---- // step: stackLimitEvader // diff --git a/test/libyul/yulOptimizerTests/stackLimitEvader/too_many_args_14.yul b/test/libyul/yulOptimizerTests/stackLimitEvader/too_many_args_14.yul index 02614c492db8..f6779917e321 100644 --- a/test/libyul/yulOptimizerTests/stackLimitEvader/too_many_args_14.yul +++ b/test/libyul/yulOptimizerTests/stackLimitEvader/too_many_args_14.yul @@ -15,6 +15,8 @@ } } +// ==== +// bytecodeFormat: legacy // ---- // step: stackLimitEvader // diff --git a/test/libyul/yulOptimizerTests/stackLimitEvader/too_many_args_15.yul b/test/libyul/yulOptimizerTests/stackLimitEvader/too_many_args_15.yul index 9ce9be70ab88..1ad539b3024f 100644 --- a/test/libyul/yulOptimizerTests/stackLimitEvader/too_many_args_15.yul +++ b/test/libyul/yulOptimizerTests/stackLimitEvader/too_many_args_15.yul @@ -17,6 +17,8 @@ } } +// ==== +// bytecodeFormat: legacy // ---- // step: stackLimitEvader // diff --git a/test/libyul/yulOptimizerTests/stackLimitEvader/too_many_args_16.yul b/test/libyul/yulOptimizerTests/stackLimitEvader/too_many_args_16.yul index 5a3b3454c591..c94c18ac486b 100644 --- a/test/libyul/yulOptimizerTests/stackLimitEvader/too_many_args_16.yul +++ b/test/libyul/yulOptimizerTests/stackLimitEvader/too_many_args_16.yul @@ -17,6 +17,8 @@ } } +// ==== +// bytecodeFormat: legacy // ---- // step: stackLimitEvader // diff --git a/test/libyul/yulOptimizerTests/stackLimitEvader/too_many_returns_15.yul b/test/libyul/yulOptimizerTests/stackLimitEvader/too_many_returns_15.yul index b9d1a5571a9a..a47d38fd037b 100644 --- a/test/libyul/yulOptimizerTests/stackLimitEvader/too_many_returns_15.yul +++ b/test/libyul/yulOptimizerTests/stackLimitEvader/too_many_returns_15.yul @@ -13,6 +13,8 @@ } } +// ==== +// bytecodeFormat: legacy // ---- // step: stackLimitEvader // diff --git a/test/libyul/yulOptimizerTests/stackLimitEvader/too_many_returns_16.yul b/test/libyul/yulOptimizerTests/stackLimitEvader/too_many_returns_16.yul index 40553083ffaa..aa144950f9c8 100644 --- a/test/libyul/yulOptimizerTests/stackLimitEvader/too_many_returns_16.yul +++ b/test/libyul/yulOptimizerTests/stackLimitEvader/too_many_returns_16.yul @@ -13,6 +13,8 @@ } } +// ==== +// bytecodeFormat: legacy // ---- // step: stackLimitEvader // diff --git a/test/libyul/yulOptimizerTests/stackLimitEvader/tree.yul b/test/libyul/yulOptimizerTests/stackLimitEvader/tree.yul index 8407df5d0497..e97e458da0e2 100644 --- a/test/libyul/yulOptimizerTests/stackLimitEvader/tree.yul +++ b/test/libyul/yulOptimizerTests/stackLimitEvader/tree.yul @@ -164,6 +164,8 @@ v := sload(mul(42,8)) } } +// ==== +// bytecodeFormat: legacy // ---- // step: stackLimitEvader // diff --git a/test/libyul/yulOptimizerTests/stackLimitEvader/verbatim_many_arguments.yul b/test/libyul/yulOptimizerTests/stackLimitEvader/verbatim_many_arguments.yul index bde030f68ec3..8a2c52a9ad98 100644 --- a/test/libyul/yulOptimizerTests/stackLimitEvader/verbatim_many_arguments.yul +++ b/test/libyul/yulOptimizerTests/stackLimitEvader/verbatim_many_arguments.yul @@ -24,6 +24,8 @@ verbatim_20i_0o("test", a_1, a_2, a_3, a_4, a_5, a_6, a_7, a_8, a_9, a_10, a_11, a_12, a_13, a_14, a_15, a_16, a_17, a_18, a_19, a_20) } } +// ==== +// bytecodeFormat: legacy // ---- // step: stackLimitEvader // diff --git a/test/libyul/yulOptimizerTests/stackLimitEvader/verbatim_many_arguments_and_returns.yul b/test/libyul/yulOptimizerTests/stackLimitEvader/verbatim_many_arguments_and_returns.yul index 46435dd210dc..e7170a10defd 100644 --- a/test/libyul/yulOptimizerTests/stackLimitEvader/verbatim_many_arguments_and_returns.yul +++ b/test/libyul/yulOptimizerTests/stackLimitEvader/verbatim_many_arguments_and_returns.yul @@ -45,6 +45,8 @@ } } +// ==== +// bytecodeFormat: legacy // ---- // step: stackLimitEvader // diff --git a/test/libyul/yulOptimizerTests/stackLimitEvader/verbatim_many_returns.yul b/test/libyul/yulOptimizerTests/stackLimitEvader/verbatim_many_returns.yul index 47db17e21198..e06dd8d8b0a9 100644 --- a/test/libyul/yulOptimizerTests/stackLimitEvader/verbatim_many_returns.yul +++ b/test/libyul/yulOptimizerTests/stackLimitEvader/verbatim_many_returns.yul @@ -7,6 +7,8 @@ sstore(a18, 20) } } +// ==== +// bytecodeFormat: legacy // ---- // step: stackLimitEvader // From 9fdf9b5359ca28b5464e3b18992d4d8898b2d22d Mon Sep 17 00:00:00 2001 From: Daniel Kirchner Date: Wed, 26 Feb 2025 20:33:53 +0100 Subject: [PATCH 0830/1022] Pass EVMDialect to StackLayoutGenerator directly. --- .../evm/OptimizedEVMCodeTransform.cpp | 2 +- libyul/backends/evm/StackLayoutGenerator.cpp | 60 +++++++++---------- libyul/backends/evm/StackLayoutGenerator.h | 26 ++++---- libyul/optimiser/StackCompressor.cpp | 8 +-- libyul/optimiser/StackLimitEvader.cpp | 2 +- test/libyul/StackLayoutGeneratorTest.cpp | 4 +- 6 files changed, 50 insertions(+), 52 deletions(-) diff --git a/libyul/backends/evm/OptimizedEVMCodeTransform.cpp b/libyul/backends/evm/OptimizedEVMCodeTransform.cpp index 07ab758d7502..69cd046debd0 100644 --- a/libyul/backends/evm/OptimizedEVMCodeTransform.cpp +++ b/libyul/backends/evm/OptimizedEVMCodeTransform.cpp @@ -49,7 +49,7 @@ std::vector OptimizedEVMCodeTransform::run( ) { std::unique_ptr dfg = ControlFlowGraphBuilder::build(_analysisInfo, _dialect, _block); - StackLayout stackLayout = StackLayoutGenerator::run(*dfg, !_dialect.eofVersion().has_value(), _dialect.reachableStackDepth()); + StackLayout stackLayout = StackLayoutGenerator::run(*dfg, _dialect); if (_dialect.eofVersion().has_value()) { diff --git a/libyul/backends/evm/StackLayoutGenerator.cpp b/libyul/backends/evm/StackLayoutGenerator.cpp index 6abb1bb9fa1b..69045998c859 100644 --- a/libyul/backends/evm/StackLayoutGenerator.cpp +++ b/libyul/backends/evm/StackLayoutGenerator.cpp @@ -45,22 +45,20 @@ using namespace solidity; using namespace solidity::yul; -StackLayout StackLayoutGenerator::run(CFG const& _cfg, bool _simulateFunctionsWithJumps, size_t _reachableStackDepth) +StackLayout StackLayoutGenerator::run(CFG const& _cfg, EVMDialect const& _evmDialect) { StackLayout stackLayout{{}, {}}; StackLayoutGenerator{ stackLayout, nullptr, - _simulateFunctionsWithJumps, - _reachableStackDepth + _evmDialect }.processEntryPoint(*_cfg.entry); for (auto& functionInfo: _cfg.functionInfo | ranges::views::values) StackLayoutGenerator{ stackLayout, &functionInfo, - _simulateFunctionsWithJumps, - _reachableStackDepth + _evmDialect }.processEntryPoint(*functionInfo.entry, &functionInfo); return stackLayout; @@ -68,14 +66,13 @@ StackLayout StackLayoutGenerator::run(CFG const& _cfg, bool _simulateFunctionsWi std::map> StackLayoutGenerator::reportStackTooDeep( CFG const& _cfg, - bool _simulateFunctionsWithJumps, - size_t _reachableStackDepth + EVMDialect const& _evmDialect ) { std::map> stackTooDeepErrors; - stackTooDeepErrors[YulName{}] = reportStackTooDeep(_cfg, YulName{}, _simulateFunctionsWithJumps, _reachableStackDepth); + stackTooDeepErrors[YulName{}] = reportStackTooDeep(_cfg, YulName{}, _evmDialect); for (auto const& function: _cfg.functions) - if (auto errors = reportStackTooDeep(_cfg, function->name, _simulateFunctionsWithJumps, _reachableStackDepth); !errors.empty()) + if (auto errors = reportStackTooDeep(_cfg, function->name, _evmDialect); !errors.empty()) stackTooDeepErrors[function->name] = std::move(errors); return stackTooDeepErrors; } @@ -83,8 +80,7 @@ std::map> StackLayoutGe std::vector StackLayoutGenerator::reportStackTooDeep( CFG const& _cfg, YulName _functionName, - bool _simulateFunctionsWithJumps, - size_t _reachableStackDepth + EVMDialect const& _evmDialect ) { StackLayout stackLayout{{}, {}}; @@ -99,7 +95,7 @@ std::vector StackLayoutGenerator::reportStac yulAssert(functionInfo, "Function not found."); } - StackLayoutGenerator generator{stackLayout, functionInfo, _simulateFunctionsWithJumps, _reachableStackDepth}; + StackLayoutGenerator generator{stackLayout, functionInfo, _evmDialect}; CFG::BasicBlock const* entry = functionInfo ? functionInfo->entry : _cfg.entry; generator.processEntryPoint(*entry); return generator.reportStackTooDeep(*entry); @@ -108,13 +104,11 @@ std::vector StackLayoutGenerator::reportStac StackLayoutGenerator::StackLayoutGenerator( StackLayout& _layout, CFG::FunctionInfo const* _functionInfo, - bool _simulateFunctionsWithJumps, - size_t _reachableStackDepth + EVMDialect const& _evmDialect ): m_layout(_layout), m_currentFunctionInfo(_functionInfo), - m_simulateFunctionsWithJumps(_simulateFunctionsWithJumps), - m_reachableStackDepth(_reachableStackDepth) + m_evmDialect(_evmDialect) { } @@ -312,7 +306,7 @@ Stack StackLayoutGenerator::propagateStackThroughOperation(Stack _exitStack, CFG // Determine the ideal permutation of the slots in _exitLayout that are not operation outputs (and not to be // generated on the fly), s.t. shuffling the `stack + _operation.output` to _exitLayout is cheap. - Stack stack = createIdealLayout(_operation.output, _exitStack, generateSlotOnTheFly, m_reachableStackDepth); + Stack stack = createIdealLayout(_operation.output, _exitStack, generateSlotOnTheFly, reachableStackDepth()); // Make sure the resulting previous slots do not overlap with any assignmed variables. if (auto const* assignment = std::get_if(&_operation.operation)) @@ -336,7 +330,7 @@ Stack StackLayoutGenerator::propagateStackThroughOperation(Stack _exitStack, CFG stack.pop_back(); else if (auto offset = util::findOffset(stack | ranges::views::reverse | ranges::views::drop(1), stack.back())) { - if (*offset + 2 < m_reachableStackDepth) + if (*offset + 2 < reachableStackDepth()) stack.pop_back(); else break; @@ -354,7 +348,7 @@ Stack StackLayoutGenerator::propagateStackThroughBlock(Stack _exitStack, CFG::Ba for (auto&& [idx, operation]: _block.operations | ranges::views::enumerate | ranges::views::reverse) { Stack newStack = propagateStackThroughOperation(stack, operation, _aggressiveStackCompression); - if (!_aggressiveStackCompression && !findStackTooDeep(newStack, stack, m_reachableStackDepth).empty()) + if (!_aggressiveStackCompression && !findStackTooDeep(newStack, stack, reachableStackDepth()).empty()) // If we had stack errors, run again with aggressive stack compression. return propagateStackThroughBlock(std::move(_exitStack), _block, true); stack = std::move(newStack); @@ -476,7 +470,7 @@ std::optional StackLayoutGenerator::getExitLayoutOrStageDependencies( Stack stack = combineStack( m_layout.blockInfos.at(_conditionalJump.zero).entryLayout, m_layout.blockInfos.at(_conditionalJump.nonZero).entryLayout, - m_reachableStackDepth + reachableStackDepth() ); // Additionally, the jump condition has to be at the stack top at exit. stack.emplace_back(_conditionalJump.condition); @@ -497,7 +491,7 @@ std::optional StackLayoutGenerator::getExitLayoutOrStageDependencies( return StackSlot{_varSlot}; }) | ranges::to; - if (m_simulateFunctionsWithJumps) + if (simulateFunctionsWithJumps()) stack.emplace_back(FunctionReturnLabelSlot{_functionReturn.info->function}); return stack; }, @@ -677,7 +671,7 @@ std::vector StackLayoutGenerator::reportStac { Stack& operationEntry = m_layout.operationEntryLayout.at(&operation); - stackTooDeepErrors += findStackTooDeep(currentStack, operationEntry, m_reachableStackDepth); + stackTooDeepErrors += findStackTooDeep(currentStack, operationEntry, reachableStackDepth()); currentStack = operationEntry; for (size_t i = 0; i < operation.input.size(); i++) currentStack.pop_back(); @@ -691,7 +685,7 @@ std::vector StackLayoutGenerator::reportStac [&](CFG::BasicBlock::Jump const& _jump) { Stack const& targetLayout = m_layout.blockInfos.at(_jump.target).entryLayout; - stackTooDeepErrors += findStackTooDeep(currentStack, targetLayout, m_reachableStackDepth); + stackTooDeepErrors += findStackTooDeep(currentStack, targetLayout, reachableStackDepth()); if (!_jump.backwards) _addChild(_jump.target); @@ -702,7 +696,7 @@ std::vector StackLayoutGenerator::reportStac m_layout.blockInfos.at(_conditionalJump.zero).entryLayout, m_layout.blockInfos.at(_conditionalJump.nonZero).entryLayout }) - stackTooDeepErrors += findStackTooDeep(currentStack, targetLayout, m_reachableStackDepth); + stackTooDeepErrors += findStackTooDeep(currentStack, targetLayout, reachableStackDepth()); _addChild(_conditionalJump.zero); _addChild(_conditionalJump.nonZero); @@ -769,7 +763,7 @@ void StackLayoutGenerator::fillInJunk(CFG::BasicBlock const& _block, CFG::Functi _addChild(_conditionalJump.zero); _addChild(_conditionalJump.nonZero); }, - [&](CFG::BasicBlock::FunctionReturn const&) { yulAssert(!m_simulateFunctionsWithJumps); }, + [&](CFG::BasicBlock::FunctionReturn const&) { yulAssert(!simulateFunctionsWithJumps()); }, [&](CFG::BasicBlock::Terminated const&) {}, }, _block->exit); }); @@ -779,21 +773,21 @@ void StackLayoutGenerator::fillInJunk(CFG::BasicBlock const& _block, CFG::Functi size_t opGas = 0; auto swap = [&](unsigned _swapDepth) { - if (_swapDepth > m_reachableStackDepth) + if (_swapDepth > reachableStackDepth()) opGas += 1000; else - opGas += evmasm::GasMeter::swapGas(_swapDepth, langutil::EVMVersion{}); + opGas += evmasm::GasMeter::swapGas(_swapDepth, m_evmDialect.evmVersion()); }; auto dupOrPush = [&](StackSlot const& _slot) { if (canBeFreelyGenerated(_slot)) - opGas += evmasm::GasMeter::runGas(evmasm::pushInstruction(32), langutil::EVMVersion()); + opGas += evmasm::GasMeter::runGas(evmasm::pushInstruction(32), m_evmDialect.evmVersion()); else { if (auto depth = util::findOffset(_source | ranges::views::reverse, _slot)) { - if (*depth < m_reachableStackDepth) - opGas += evmasm::GasMeter::dupGas(*depth + 1, langutil::EVMVersion{}); + if (*depth < reachableStackDepth()) + opGas += evmasm::GasMeter::dupGas(*depth + 1, m_evmDialect.evmVersion()); else opGas += 1000; } @@ -805,12 +799,12 @@ void StackLayoutGenerator::fillInJunk(CFG::BasicBlock const& _block, CFG::Functi yulAssert(util::contains(m_currentFunctionInfo->returnVariables, std::get(_slot))); // Strictly speaking the cost of the PUSH0 depends on the targeted EVM version, but the difference // will not matter here. - opGas += evmasm::GasMeter::pushGas(u256(0), langutil::EVMVersion()); + opGas += evmasm::GasMeter::pushGas(u256(0), m_evmDialect.evmVersion()); } } }; - auto pop = [&]() { opGas += evmasm::GasMeter::runGas(evmasm::Instruction::POP,langutil::EVMVersion()); }; - createStackLayout(_source, _target, swap, dupOrPush, pop, m_reachableStackDepth); + auto pop = [&]() { opGas += evmasm::GasMeter::runGas(evmasm::Instruction::POP, m_evmDialect.evmVersion()); }; + createStackLayout(_source, _target, swap, dupOrPush, pop, reachableStackDepth()); return opGas; }; /// @returns the number of junk slots to be prepended to @a _targetLayout for an optimal transition from diff --git a/libyul/backends/evm/StackLayoutGenerator.h b/libyul/backends/evm/StackLayoutGenerator.h index 9626c7ad1c77..bf1b1917ba33 100644 --- a/libyul/backends/evm/StackLayoutGenerator.h +++ b/libyul/backends/evm/StackLayoutGenerator.h @@ -22,6 +22,7 @@ #pragma once #include +#include #include @@ -55,14 +56,13 @@ class StackLayoutGenerator std::vector variableChoices; }; - static StackLayout run(CFG const& _cfg, bool _simulateFunctionsWithJumps, size_t _reachableStackDepth); + static StackLayout run(CFG const& _cfg, EVMDialect const& _evmDialect); /// @returns a map from function names to the stack too deep errors occurring in that function. /// Requires @a _cfg to be a control flow graph generated from disambiguated Yul. /// The empty string is mapped to the stack too deep errors of the main entry point. static std::map> reportStackTooDeep( CFG const& _cfg, - bool _simulateFunctionsWithJumps, - size_t _reachableStackDepth + EVMDialect const& _evmDialect ); /// @returns all stack too deep errors in the function named @a _functionName. /// Requires @a _cfg to be a control flow graph generated from disambiguated Yul. @@ -70,16 +70,14 @@ class StackLayoutGenerator static std::vector reportStackTooDeep( CFG const& _cfg, YulName _functionName, - bool _simulateFunctionsWithJumps, - size_t _reachableStackDepth + EVMDialect const& _evmDialect ); private: StackLayoutGenerator( StackLayout& _context, CFG::FunctionInfo const* _functionInfo, - bool _simulateFunctionsWithJumps, - size_t _reachableStackDepth + EVMDialect const& _evmDialect ); /// @returns the optimal entry stack layout, s.t. @a _operation can be applied to it and @@ -128,11 +126,19 @@ class StackLayoutGenerator //// Fills in junk when entering branches that do not need a clean stack in case the result is cheaper. void fillInJunk(CFG::BasicBlock const& _block, CFG::FunctionInfo const* _functionInfo = nullptr); + /// True if it simulates functions with jumps. False otherwise. True for legacy bytecode. + bool simulateFunctionsWithJumps() const + { + return !m_evmDialect.eofVersion().has_value(); + } + size_t reachableStackDepth() const + { + return m_evmDialect.reachableStackDepth(); + } + StackLayout& m_layout; CFG::FunctionInfo const* m_currentFunctionInfo = nullptr; - /// True if it simulates functions with jumps. False otherwise. True for legacy bytecode - bool m_simulateFunctionsWithJumps = true; - size_t const m_reachableStackDepth{}; + EVMDialect const& m_evmDialect; }; } diff --git a/libyul/optimiser/StackCompressor.cpp b/libyul/optimiser/StackCompressor.cpp index 3c27cc20ff10..97d2c054700d 100644 --- a/libyul/optimiser/StackCompressor.cpp +++ b/libyul/optimiser/StackCompressor.cpp @@ -248,15 +248,14 @@ std::tuple StackCompressor::run( "Need to run the function grouper before the stack compressor." ); bool usesOptimizedCodeGenerator = false; - bool simulateFunctionsWithJumps = true; - if (auto evmDialect = dynamic_cast(_object.dialect())) + auto evmDialect = dynamic_cast(_object.dialect()); + if (evmDialect) { yulAssert(!evmDialect->eofVersion().has_value(), "StackCompressor does not support EOF."); usesOptimizedCodeGenerator = _optimizeStackAllocation && evmDialect->evmVersion().canOverchargeGasForCall() && evmDialect->providesObjectAccess(); - simulateFunctionsWithJumps = !evmDialect->eofVersion().has_value(); } bool allowMSizeOptimization = !MSizeFinder::containsMSize(*_object.dialect(), _object.code()->root()); Block astRoot = std::get(ASTCopier{}(_object.code()->root())); @@ -268,10 +267,11 @@ std::tuple StackCompressor::run( _object.summarizeStructure() ); std::unique_ptr cfg = ControlFlowGraphBuilder::build(analysisInfo, *_object.dialect(), astRoot); + yulAssert(evmDialect); eliminateVariablesOptimizedCodegen( *_object.dialect(), astRoot, - StackLayoutGenerator::reportStackTooDeep(*cfg, simulateFunctionsWithJumps, 16u), + StackLayoutGenerator::reportStackTooDeep(*cfg, *evmDialect), allowMSizeOptimization ); } diff --git a/libyul/optimiser/StackLimitEvader.cpp b/libyul/optimiser/StackLimitEvader.cpp index a2a557de98d4..13a3bbd87afa 100644 --- a/libyul/optimiser/StackLimitEvader.cpp +++ b/libyul/optimiser/StackLimitEvader.cpp @@ -145,7 +145,7 @@ Block StackLimitEvader::run( _object.summarizeStructure() ); std::unique_ptr cfg = ControlFlowGraphBuilder::build(analysisInfo, *evmDialect, astRoot); - run(_context, astRoot, StackLayoutGenerator::reportStackTooDeep(*cfg, !evmDialect->eofVersion().has_value(), evmDialect->reachableStackDepth())); + run(_context, astRoot, StackLayoutGenerator::reportStackTooDeep(*cfg, *evmDialect)); } else { diff --git a/test/libyul/StackLayoutGeneratorTest.cpp b/test/libyul/StackLayoutGeneratorTest.cpp index 86fd6184e26b..eb34eabb1776 100644 --- a/test/libyul/StackLayoutGeneratorTest.cpp +++ b/test/libyul/StackLayoutGeneratorTest.cpp @@ -234,10 +234,8 @@ TestCase::TestResult StackLayoutGeneratorTest::run(std::ostream& _stream, std::s auto const* evmDialect = dynamic_cast(&yulStack.dialect()); solAssert(evmDialect, "StackLayoutGenerator can only be run on EVM dialects."); - bool simulateFunctionsWithJumps = !evmDialect->eofVersion().has_value(); - size_t reachableStackDepth = evmDialect->reachableStackDepth(); - StackLayout stackLayout = StackLayoutGenerator::run(*cfg, simulateFunctionsWithJumps, reachableStackDepth); + StackLayout stackLayout = StackLayoutGenerator::run(*cfg, *evmDialect); output << "digraph CFG {\nnodesep=0.7;\nnode[shape=box];\n\n"; StackLayoutPrinter printer{output, stackLayout, yulStack.dialect()}; From 872805b06b6e92615539abe41edea78b8321e0c8 Mon Sep 17 00:00:00 2001 From: Alexander Arlt Date: Wed, 26 Feb 2025 17:13:41 +0100 Subject: [PATCH 0831/1022] Allow --irOptimized output selection in ethdebug. --- libsolidity/interface/StandardCompiler.cpp | 7 +- solc/CommandLineParser.cpp | 19 +- .../debug_info_ethdebug_compatible/args | 1 + .../input.sol | 0 .../debug_info_ethdebug_compatible/output | 193 +++ .../debug_info_ethdebug_incompatible/args | 1 + .../debug_info_ethdebug_incompatible/err | 1 + .../exit | 0 .../input.sol | 0 .../args | 0 .../input.sol | 0 .../output | 8 +- .../args | 1 + .../input.sol | 0 .../output | 79 ++ .../ethdebug_enabled_optimization/err | 1 - .../ethdebug_enabled_optimization_ir/args | 1 + .../ethdebug_enabled_optimization_ir/err | 1 + .../ethdebug_enabled_optimization_ir/exit | 1 + .../input.sol | 7 + .../args | 0 .../err | 1 + .../exit | 1 + .../input.sol | 7 + .../{ethdebug => ethdebug_ir}/args | 0 test/cmdlineTests/ethdebug_ir/input.sol | 7 + .../{ethdebug => ethdebug_ir}/output | 8 +- test/cmdlineTests/ethdebug_iroptimized/args | 1 + .../ethdebug_iroptimized/input.sol | 7 + test/cmdlineTests/ethdebug_iroptimized/output | 77 ++ test/cmdlineTests/ethdebug_no_via_ir/args | 1 + test/cmdlineTests/ethdebug_no_via_ir/err | 1 + test/cmdlineTests/ethdebug_no_via_ir/exit | 1 + .../cmdlineTests/ethdebug_no_via_ir/input.sol | 7 + .../args | 0 .../ethdebug_runtime_ir/input.sol | 7 + .../output | 8 +- .../ethdebug_runtime_iroptimized/args | 1 + .../ethdebug_runtime_iroptimized/input.sol | 7 + .../ethdebug_runtime_iroptimized/output | 77 ++ .../input.json | 29 + .../output.json | 1198 +++++++++++++++++ .../input.json | 26 + .../output.json | 11 + .../input.json | 24 - .../input.json | 24 - .../input.json | 26 + .../output.json | 0 .../input.json | 26 + .../output.json | 522 +++++++ .../input.json | 24 - .../input.json | 26 + .../output.json | 2 +- .../input.json | 26 + .../output.json | 2 +- .../input.json | 25 + .../output.json | 0 .../input.json | 25 + .../output.json | 510 +++++++ .../input.json | 24 - .../input.json | 25 + .../output.json | 0 .../input.json | 25 + .../output.json | 510 +++++++ .../input.json | 22 + .../output.json | 730 ++++++++++ .../input.json | 21 - .../input.json | 22 + .../output.json | 510 +++++++ .../input.json | 22 + .../output.json | 11 + .../input.json | 24 - .../input.json | 25 + .../output.json | 2 +- .../input.json | 25 + .../output.json | 2 +- .../args | 0 .../in.yul | 16 + .../input.json | 16 + .../output.json | 48 + .../args | 0 .../in.yul | 16 + .../input.json | 16 + .../output.json | 11 + .../args | 0 .../in.yul | 0 .../input.json | 2 +- .../output.json | 0 .../args | 1 + .../in.yul | 0 .../input.json | 2 +- .../output.json | 35 + .../input.json | 2 +- .../standard_yul_ethdebug_ir/args | 1 + .../in.yul | 0 .../standard_yul_ethdebug_ir/input.json | 11 + .../standard_yul_ethdebug_ir/output.json | 33 + .../standard_yul_ethdebug_iroptimize/args | 1 + .../standard_yul_ethdebug_iroptimize/in.yul | 17 + .../input.json | 11 + .../output.json | 20 + .../output.json | 11 - .../standard_yul_ethdebug_optimize_ir/args | 1 + .../standard_yul_ethdebug_optimize_ir/in.yul | 17 + .../input.json | 2 +- .../output.json | 11 + .../args | 1 + .../in.yul | 17 + .../input.json | 14 + .../output.json | 11 + test/cmdlineTests/yul_ethdebug/args | 2 +- test/cmdlineTests/yul_ethdebug/output | 11 - test/cmdlineTests/yul_ethdebug_ir/args | 1 + test/cmdlineTests/yul_ethdebug_ir/err | 1 + test/cmdlineTests/yul_ethdebug_ir/exit | 1 + test/cmdlineTests/yul_ethdebug_ir/input.yul | 18 + .../yul_ethdebug_iroptimized/args | 1 + .../yul_ethdebug_iroptimized/input.yul | 18 + .../yul_ethdebug_iroptimized/output | 26 + test/cmdlineTests/yul_ethdebug_optimize/args | 1 + test/cmdlineTests/yul_ethdebug_optimize/err | 1 + test/cmdlineTests/yul_ethdebug_optimize/exit | 1 + .../yul_ethdebug_optimize/input.yul | 18 + .../yul_ethdebug_optimize_iroptimized/args | 1 + .../yul_ethdebug_optimize_iroptimized/err | 1 + .../yul_ethdebug_optimize_iroptimized/exit | 1 + .../input.yul | 18 + test/libsolidity/StandardCompiler.cpp | 100 +- test/solc/CommandLineInterface.cpp | 232 ++-- 129 files changed, 5433 insertions(+), 430 deletions(-) create mode 100644 test/cmdlineTests/debug_info_ethdebug_compatible/args rename test/cmdlineTests/{ethdebug => debug_info_ethdebug_compatible}/input.sol (100%) create mode 100644 test/cmdlineTests/debug_info_ethdebug_compatible/output create mode 100644 test/cmdlineTests/debug_info_ethdebug_incompatible/args create mode 100644 test/cmdlineTests/debug_info_ethdebug_incompatible/err rename test/cmdlineTests/{ethdebug_enabled_optimization => debug_info_ethdebug_incompatible}/exit (100%) rename test/cmdlineTests/{ethdebug_and_ethdebug_runtime => debug_info_ethdebug_incompatible}/input.sol (100%) rename test/cmdlineTests/{ethdebug_and_ethdebug_runtime => ethdebug_and_ethdebug_runtime_ir}/args (100%) rename test/cmdlineTests/{ethdebug_enabled_optimization => ethdebug_and_ethdebug_runtime_ir}/input.sol (100%) rename test/cmdlineTests/{ethdebug_and_ethdebug_runtime => ethdebug_and_ethdebug_runtime_ir}/output (93%) create mode 100644 test/cmdlineTests/ethdebug_and_ethdebug_runtime_iroptimized/args rename test/cmdlineTests/{ethdebug_runtime => ethdebug_and_ethdebug_runtime_iroptimized}/input.sol (100%) create mode 100644 test/cmdlineTests/ethdebug_and_ethdebug_runtime_iroptimized/output delete mode 100644 test/cmdlineTests/ethdebug_enabled_optimization/err create mode 100644 test/cmdlineTests/ethdebug_enabled_optimization_ir/args create mode 100644 test/cmdlineTests/ethdebug_enabled_optimization_ir/err create mode 100644 test/cmdlineTests/ethdebug_enabled_optimization_ir/exit create mode 100644 test/cmdlineTests/ethdebug_enabled_optimization_ir/input.sol rename test/cmdlineTests/{ethdebug_enabled_optimization => ethdebug_enabled_optimization_iroptimized}/args (100%) create mode 100644 test/cmdlineTests/ethdebug_enabled_optimization_iroptimized/err create mode 100644 test/cmdlineTests/ethdebug_enabled_optimization_iroptimized/exit create mode 100644 test/cmdlineTests/ethdebug_enabled_optimization_iroptimized/input.sol rename test/cmdlineTests/{ethdebug => ethdebug_ir}/args (100%) create mode 100644 test/cmdlineTests/ethdebug_ir/input.sol rename test/cmdlineTests/{ethdebug => ethdebug_ir}/output (95%) create mode 100644 test/cmdlineTests/ethdebug_iroptimized/args create mode 100644 test/cmdlineTests/ethdebug_iroptimized/input.sol create mode 100644 test/cmdlineTests/ethdebug_iroptimized/output create mode 100644 test/cmdlineTests/ethdebug_no_via_ir/args create mode 100644 test/cmdlineTests/ethdebug_no_via_ir/err create mode 100644 test/cmdlineTests/ethdebug_no_via_ir/exit create mode 100644 test/cmdlineTests/ethdebug_no_via_ir/input.sol rename test/cmdlineTests/{ethdebug_runtime => ethdebug_runtime_ir}/args (100%) create mode 100644 test/cmdlineTests/ethdebug_runtime_ir/input.sol rename test/cmdlineTests/{ethdebug_runtime => ethdebug_runtime_ir}/output (94%) create mode 100644 test/cmdlineTests/ethdebug_runtime_iroptimized/args create mode 100644 test/cmdlineTests/ethdebug_runtime_iroptimized/input.sol create mode 100644 test/cmdlineTests/ethdebug_runtime_iroptimized/output create mode 100644 test/cmdlineTests/standard_output_debuginfo_ethdebug_compatible/input.json create mode 100644 test/cmdlineTests/standard_output_debuginfo_ethdebug_compatible/output.json create mode 100644 test/cmdlineTests/standard_output_debuginfo_ethdebug_incompatible/input.json create mode 100644 test/cmdlineTests/standard_output_debuginfo_ethdebug_incompatible/output.json delete mode 100644 test/cmdlineTests/standard_output_selection_ethdebug_bytecode/input.json delete mode 100644 test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode/input.json create mode 100644 test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_ir/input.json rename test/cmdlineTests/{standard_output_selection_ethdebug_bytecode_and_deployedbytecode => standard_output_selection_ethdebug_bytecode_and_deployedbytecode_ir}/output.json (100%) create mode 100644 test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_iroptimized/input.json create mode 100644 test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_iroptimized/output.json delete mode 100644 test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_optimizer/input.json create mode 100644 test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_optimizer_ir/input.json rename test/cmdlineTests/{standard_output_selection_ethdebug_bytecode_and_deployedbytecode_optimizer => standard_output_selection_ethdebug_bytecode_and_deployedbytecode_optimizer_ir}/output.json (85%) create mode 100644 test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_optimizer_iroptimized/input.json rename test/cmdlineTests/{standard_yul_ethdebug_irOptimized => standard_output_selection_ethdebug_bytecode_and_deployedbytecode_optimizer_iroptimized}/output.json (85%) create mode 100644 test/cmdlineTests/standard_output_selection_ethdebug_bytecode_ir/input.json rename test/cmdlineTests/{standard_output_selection_ethdebug_bytecode => standard_output_selection_ethdebug_bytecode_ir}/output.json (100%) create mode 100644 test/cmdlineTests/standard_output_selection_ethdebug_bytecode_iroptimized/input.json create mode 100644 test/cmdlineTests/standard_output_selection_ethdebug_bytecode_iroptimized/output.json delete mode 100644 test/cmdlineTests/standard_output_selection_ethdebug_deployedbytecode/input.json create mode 100644 test/cmdlineTests/standard_output_selection_ethdebug_deployedbytecode_ir/input.json rename test/cmdlineTests/{standard_output_selection_ethdebug_deployedbytecode => standard_output_selection_ethdebug_deployedbytecode_ir}/output.json (100%) create mode 100644 test/cmdlineTests/standard_output_selection_ethdebug_deployedbytecode_iroptimized/input.json create mode 100644 test/cmdlineTests/standard_output_selection_ethdebug_deployedbytecode_iroptimized/output.json create mode 100644 test/cmdlineTests/standard_output_selection_ethdebug_ir/input.json create mode 100644 test/cmdlineTests/standard_output_selection_ethdebug_ir/output.json delete mode 100644 test/cmdlineTests/standard_output_selection_ethdebug_irOptimized/input.json create mode 100644 test/cmdlineTests/standard_output_selection_ethdebug_iroptimized/input.json create mode 100644 test/cmdlineTests/standard_output_selection_ethdebug_iroptimized/output.json create mode 100644 test/cmdlineTests/standard_output_selection_ethdebug_no_viair/input.json create mode 100644 test/cmdlineTests/standard_output_selection_ethdebug_no_viair/output.json delete mode 100644 test/cmdlineTests/standard_output_selection_ethdebug_optimize/input.json create mode 100644 test/cmdlineTests/standard_output_selection_ethdebug_optimize_ir/input.json rename test/cmdlineTests/{standard_output_selection_ethdebug_irOptimized => standard_output_selection_ethdebug_optimize_ir}/output.json (85%) create mode 100644 test/cmdlineTests/standard_output_selection_ethdebug_optimize_iroptimized/input.json rename test/cmdlineTests/{standard_output_selection_ethdebug_optimize => standard_output_selection_ethdebug_optimize_iroptimized}/output.json (85%) rename test/cmdlineTests/{standard_yul_ethdebug_bytecode => standard_yul_debug_info_ethdebug_compatible_output}/args (100%) create mode 100644 test/cmdlineTests/standard_yul_debug_info_ethdebug_compatible_output/in.yul create mode 100644 test/cmdlineTests/standard_yul_debug_info_ethdebug_compatible_output/input.json create mode 100644 test/cmdlineTests/standard_yul_debug_info_ethdebug_compatible_output/output.json rename test/cmdlineTests/{standard_yul_ethdebug_irOptimized => standard_yul_debug_info_ethdebug_incompatible_output}/args (100%) create mode 100644 test/cmdlineTests/standard_yul_debug_info_ethdebug_incompatible_output/in.yul create mode 100644 test/cmdlineTests/standard_yul_debug_info_ethdebug_incompatible_output/input.json create mode 100644 test/cmdlineTests/standard_yul_debug_info_ethdebug_incompatible_output/output.json rename test/cmdlineTests/{standard_yul_ethdebug_optimize => standard_yul_ethdebug_bytecode_ir}/args (100%) rename test/cmdlineTests/{standard_yul_ethdebug_bytecode => standard_yul_ethdebug_bytecode_ir}/in.yul (100%) rename test/cmdlineTests/{standard_yul_ethdebug_bytecode => standard_yul_ethdebug_bytecode_ir}/input.json (68%) rename test/cmdlineTests/{standard_yul_ethdebug_bytecode => standard_yul_ethdebug_bytecode_ir}/output.json (100%) create mode 100644 test/cmdlineTests/standard_yul_ethdebug_bytecode_iroptimized/args rename test/cmdlineTests/{standard_yul_ethdebug_irOptimized => standard_yul_ethdebug_bytecode_iroptimized}/in.yul (100%) rename test/cmdlineTests/{standard_yul_ethdebug_irOptimized => standard_yul_ethdebug_bytecode_iroptimized}/input.json (66%) create mode 100644 test/cmdlineTests/standard_yul_ethdebug_bytecode_iroptimized/output.json create mode 100644 test/cmdlineTests/standard_yul_ethdebug_ir/args rename test/cmdlineTests/{standard_yul_ethdebug_optimize => standard_yul_ethdebug_ir}/in.yul (100%) create mode 100644 test/cmdlineTests/standard_yul_ethdebug_ir/input.json create mode 100644 test/cmdlineTests/standard_yul_ethdebug_ir/output.json create mode 100644 test/cmdlineTests/standard_yul_ethdebug_iroptimize/args create mode 100644 test/cmdlineTests/standard_yul_ethdebug_iroptimize/in.yul create mode 100644 test/cmdlineTests/standard_yul_ethdebug_iroptimize/input.json create mode 100644 test/cmdlineTests/standard_yul_ethdebug_iroptimize/output.json delete mode 100644 test/cmdlineTests/standard_yul_ethdebug_optimize/output.json create mode 100644 test/cmdlineTests/standard_yul_ethdebug_optimize_ir/args create mode 100644 test/cmdlineTests/standard_yul_ethdebug_optimize_ir/in.yul rename test/cmdlineTests/{standard_yul_ethdebug_optimize => standard_yul_ethdebug_optimize_ir}/input.json (73%) create mode 100644 test/cmdlineTests/standard_yul_ethdebug_optimize_ir/output.json create mode 100644 test/cmdlineTests/standard_yul_ethdebug_optimize_iroptimized/args create mode 100644 test/cmdlineTests/standard_yul_ethdebug_optimize_iroptimized/in.yul create mode 100644 test/cmdlineTests/standard_yul_ethdebug_optimize_iroptimized/input.json create mode 100644 test/cmdlineTests/standard_yul_ethdebug_optimize_iroptimized/output.json create mode 100644 test/cmdlineTests/yul_ethdebug_ir/args create mode 100644 test/cmdlineTests/yul_ethdebug_ir/err create mode 100644 test/cmdlineTests/yul_ethdebug_ir/exit create mode 100644 test/cmdlineTests/yul_ethdebug_ir/input.yul create mode 100644 test/cmdlineTests/yul_ethdebug_iroptimized/args create mode 100644 test/cmdlineTests/yul_ethdebug_iroptimized/input.yul create mode 100644 test/cmdlineTests/yul_ethdebug_iroptimized/output create mode 100644 test/cmdlineTests/yul_ethdebug_optimize/args create mode 100644 test/cmdlineTests/yul_ethdebug_optimize/err create mode 100644 test/cmdlineTests/yul_ethdebug_optimize/exit create mode 100644 test/cmdlineTests/yul_ethdebug_optimize/input.yul create mode 100644 test/cmdlineTests/yul_ethdebug_optimize_iroptimized/args create mode 100644 test/cmdlineTests/yul_ethdebug_optimize_iroptimized/err create mode 100644 test/cmdlineTests/yul_ethdebug_optimize_iroptimized/exit create mode 100644 test/cmdlineTests/yul_ethdebug_optimize_iroptimized/input.yul diff --git a/libsolidity/interface/StandardCompiler.cpp b/libsolidity/interface/StandardCompiler.cpp index 230408756cd0..f52ad4e1ee88 100644 --- a/libsolidity/interface/StandardCompiler.cpp +++ b/libsolidity/interface/StandardCompiler.cpp @@ -1200,13 +1200,14 @@ std::variant StandardCompiler::parseI } if ( - ret.debugInfoSelection.has_value() && ret.debugInfoSelection->ethdebug && ret.language == "Solidity" && + ret.debugInfoSelection.has_value() && ret.debugInfoSelection->ethdebug && (ret.language == "Solidity" || ret.language == "Yul") && !pipelineConfig(ret.outputSelection)[""][""].irCodegen && !isEthdebugRequested(ret.outputSelection) ) return formatFatalError(Error::Type::FatalError, "'settings.debug.debugInfo' can only include 'ethdebug', if output 'ir', 'irOptimized', 'evm.bytecode.ethdebug', or 'evm.deployedBytecode.ethdebug' was selected."); - if (isEthdebugRequested(ret.outputSelection) && (ret.optimiserSettings.runYulOptimiser || isArtifactRequested(ret.outputSelection, "*", "*", "irOptimized", false))) - return formatFatalError(Error::Type::FatalError, "Optimization is not yet supported with ethdebug."); + if (isEthdebugRequested(ret.outputSelection)) + if (ret.optimiserSettings.runYulOptimiser) + solUnimplemented("Optimization is not yet supported with ethdebug."); return {std::move(ret)}; } diff --git a/solc/CommandLineParser.cpp b/solc/CommandLineParser.cpp index 1ef477677447..25f3048b54f2 100644 --- a/solc/CommandLineParser.cpp +++ b/solc/CommandLineParser.cpp @@ -1342,12 +1342,18 @@ void CommandLineParser::processArgs() ); if (m_options.compiler.outputs.ethdebug || m_options.compiler.outputs.ethdebugRuntime) + { + if (m_options.optimiserSettings().runYulOptimiser) + solUnimplemented( + "Optimization (using --" + g_strOptimize + ") is not yet supported with ethdebug." + ); + if (!m_options.output.debugInfoSelection.has_value()) { m_options.output.debugInfoSelection = DebugInfoSelection::Default(); m_options.output.debugInfoSelection->enable("ethdebug"); } - + } return; } else if (countEnabledOptions({g_strYulDialect, g_strMachine}) >= 1) @@ -1486,17 +1492,14 @@ void CommandLineParser::processArgs() bool incompatibleEthdebugOutputs = m_options.compiler.outputs.asmJson || m_options.compiler.outputs.irAstJson || m_options.compiler.outputs.irOptimizedAstJson || - m_options.compiler.outputs.irOptimized || m_options.optimizer.optimizeYul || m_options.optimizer.optimizeEvmasm; + m_options.optimizer.optimizeYul || m_options.optimizer.optimizeEvmasm; bool incompatibleEthdebugInputs = m_options.input.mode != InputMode::Compiler; static std::string enableEthdebugMessage = "--" + CompilerOutputs::componentName(&CompilerOutputs::ethdebug) + " / --" + CompilerOutputs::componentName(&CompilerOutputs::ethdebugRuntime); - static std::string incompatibleEthdebugOptimizerMessage = - "--" + g_strOptimize + " / --" + CompilerOutputs::componentName(&CompilerOutputs::irOptimized); - - static std::string enableIrMessage = "--" + CompilerOutputs::componentName(&CompilerOutputs::ir); + static std::string enableIrMessage = "--" + CompilerOutputs::componentName(&CompilerOutputs::ir) + " / --" + CompilerOutputs::componentName(&CompilerOutputs::irOptimized); if (m_options.compiler.outputs.ethdebug || m_options.compiler.outputs.ethdebugRuntime) { @@ -1509,7 +1512,7 @@ void CommandLineParser::processArgs() if (incompatibleEthdebugOutputs) solThrow( CommandLineValidationError, - enableEthdebugMessage + " output can only be used with " + enableIrMessage + ". Optimization is not yet supported with ethdebug, e.g. no support for " + incompatibleEthdebugOptimizerMessage + " yet." + enableEthdebugMessage + " output can only be used with " + enableIrMessage + ". Optimization (using --" + g_strOptimize + ") is not yet supported with ethdebug." ); if (!m_options.output.debugInfoSelection.has_value()) @@ -1533,7 +1536,7 @@ void CommandLineParser::processArgs() ) solThrow( CommandLineValidationError, - "--debug-info ethdebug can only be used with " + enableIrMessage + " and/or " + enableEthdebugMessage + ". Optimization is not yet supported with ethdebug, e.g. no support for " + incompatibleEthdebugOptimizerMessage + " yet." + "--debug-info ethdebug can only be used with " + enableIrMessage + " and/or " + enableEthdebugMessage + ". Optimization (using --" + g_strOptimize + ") is not yet supported with ethdebug." ); if (m_options.output.debugInfoSelection.has_value() && m_options.output.debugInfoSelection->ethdebug && incompatibleEthdebugInputs) diff --git a/test/cmdlineTests/debug_info_ethdebug_compatible/args b/test/cmdlineTests/debug_info_ethdebug_compatible/args new file mode 100644 index 000000000000..74342f38f1cc --- /dev/null +++ b/test/cmdlineTests/debug_info_ethdebug_compatible/args @@ -0,0 +1 @@ +--debug-info ethdebug --via-ir --ir --ir-optimized --ethdebug --ethdebug-runtime diff --git a/test/cmdlineTests/ethdebug/input.sol b/test/cmdlineTests/debug_info_ethdebug_compatible/input.sol similarity index 100% rename from test/cmdlineTests/ethdebug/input.sol rename to test/cmdlineTests/debug_info_ethdebug_compatible/input.sol diff --git a/test/cmdlineTests/debug_info_ethdebug_compatible/output b/test/cmdlineTests/debug_info_ethdebug_compatible/output new file mode 100644 index 000000000000..0f9581e7f7f2 --- /dev/null +++ b/test/cmdlineTests/debug_info_ethdebug_compatible/output @@ -0,0 +1,193 @@ +======= Debug Data (ethdebug/format/info/resources) ======= +{"sources":["debug_info_ethdebug_compatible/input.sol"]} + +======= debug_info_ethdebug_compatible/input.sol:C ======= +IR: +/// ethdebug: enabled +/// @use-src 0:"debug_info_ethdebug_compatible/input.sol" +object "C_6" { + code { + /// @src 0:60:101 + mstore(64, memoryguard(128)) + if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } + + constructor_C_6() + + let _1 := allocate_unbounded() + codecopy(_1, dataoffset("C_6_deployed"), datasize("C_6_deployed")) + + return(_1, datasize("C_6_deployed")) + + function allocate_unbounded() -> memPtr { + memPtr := mload(64) + } + + function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() { + revert(0, 0) + } + + /// @src 0:60:101 + function constructor_C_6() { + + /// @src 0:60:101 + + } + /// @src 0:60:101 + + } + /// @use-src 0:"debug_info_ethdebug_compatible/input.sol" + object "C_6_deployed" { + code { + /// @src 0:60:101 + mstore(64, memoryguard(128)) + + if iszero(lt(calldatasize(), 4)) + { + let selector := shift_right_224_unsigned(calldataload(0)) + switch selector + + case 0x26121ff0 + { + // f() + + external_fun_f_5() + } + + default {} + } + + revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() + + function shift_right_224_unsigned(value) -> newValue { + newValue := + + shr(224, value) + + } + + function allocate_unbounded() -> memPtr { + memPtr := mload(64) + } + + function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() { + revert(0, 0) + } + + function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() { + revert(0, 0) + } + + function abi_decode_tuple_(headStart, dataEnd) { + if slt(sub(dataEnd, headStart), 0) { revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() } + + } + + function abi_encode_tuple__to__fromStack(headStart ) -> tail { + tail := add(headStart, 0) + + } + + function external_fun_f_5() { + + if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } + abi_decode_tuple_(4, calldatasize()) + fun_f_5() + let memPos := allocate_unbounded() + let memEnd := abi_encode_tuple__to__fromStack(memPos ) + return(memPos, sub(memEnd, memPos)) + + } + + function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() { + revert(0, 0) + } + + /// @src 0:77:99 + function fun_f_5() { + + } + /// @src 0:60:101 + + } + + data ".metadata" hex"" + } + +} + + +Optimized IR: +/// ethdebug: enabled +/// @use-src 0:"debug_info_ethdebug_compatible/input.sol" +object "C_6" { + code { + { + /// @src 0:60:101 + mstore(64, memoryguard(0x80)) + if callvalue() + { + revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() + } + let _1 := allocate_unbounded() + codecopy(_1, dataoffset("C_6_deployed"), datasize("C_6_deployed")) + return(_1, datasize("C_6_deployed")) + } + function allocate_unbounded() -> memPtr + { memPtr := mload(64) } + function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() + { revert(0, 0) } + } + /// @use-src 0:"debug_info_ethdebug_compatible/input.sol" + object "C_6_deployed" { + code { + { + /// @src 0:60:101 + mstore(64, memoryguard(0x80)) + if iszero(lt(calldatasize(), 4)) + { + let selector := shift_right_unsigned(calldataload(0)) + switch selector + case 0x26121ff0 { external_fun_f() } + default { } + } + revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() + } + function shift_right_unsigned(value) -> newValue + { newValue := shr(224, value) } + function allocate_unbounded() -> memPtr + { memPtr := mload(64) } + function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() + { revert(0, 0) } + function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() + { revert(0, 0) } + function abi_decode(headStart, dataEnd) + { + if slt(sub(dataEnd, headStart), 0) + { + revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() + } + } + function abi_encode_tuple(headStart) -> tail + { tail := add(headStart, 0) } + function external_fun_f() + { + if callvalue() + { + revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() + } + abi_decode(4, calldatasize()) + let memPos := allocate_unbounded() + let memEnd := abi_encode_tuple(memPos) + return(memPos, sub(memEnd, memPos)) + } + function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() + { revert(0, 0) } + } + data ".metadata" hex"" + } +} + +Debug Data (ethdebug/format/program): +{} +Debug Data of the runtime part (ethdebug/format/program): +{} diff --git a/test/cmdlineTests/debug_info_ethdebug_incompatible/args b/test/cmdlineTests/debug_info_ethdebug_incompatible/args new file mode 100644 index 000000000000..8afe2c9b3a61 --- /dev/null +++ b/test/cmdlineTests/debug_info_ethdebug_incompatible/args @@ -0,0 +1 @@ +--debug-info ethdebug --via-ir --asm diff --git a/test/cmdlineTests/debug_info_ethdebug_incompatible/err b/test/cmdlineTests/debug_info_ethdebug_incompatible/err new file mode 100644 index 000000000000..32401186d0d7 --- /dev/null +++ b/test/cmdlineTests/debug_info_ethdebug_incompatible/err @@ -0,0 +1 @@ +Error: --debug-info ethdebug can only be used with --ir / --ir-optimized and/or --ethdebug / --ethdebug-runtime. Optimization (using --optimize) is not yet supported with ethdebug. diff --git a/test/cmdlineTests/ethdebug_enabled_optimization/exit b/test/cmdlineTests/debug_info_ethdebug_incompatible/exit similarity index 100% rename from test/cmdlineTests/ethdebug_enabled_optimization/exit rename to test/cmdlineTests/debug_info_ethdebug_incompatible/exit diff --git a/test/cmdlineTests/ethdebug_and_ethdebug_runtime/input.sol b/test/cmdlineTests/debug_info_ethdebug_incompatible/input.sol similarity index 100% rename from test/cmdlineTests/ethdebug_and_ethdebug_runtime/input.sol rename to test/cmdlineTests/debug_info_ethdebug_incompatible/input.sol diff --git a/test/cmdlineTests/ethdebug_and_ethdebug_runtime/args b/test/cmdlineTests/ethdebug_and_ethdebug_runtime_ir/args similarity index 100% rename from test/cmdlineTests/ethdebug_and_ethdebug_runtime/args rename to test/cmdlineTests/ethdebug_and_ethdebug_runtime_ir/args diff --git a/test/cmdlineTests/ethdebug_enabled_optimization/input.sol b/test/cmdlineTests/ethdebug_and_ethdebug_runtime_ir/input.sol similarity index 100% rename from test/cmdlineTests/ethdebug_enabled_optimization/input.sol rename to test/cmdlineTests/ethdebug_and_ethdebug_runtime_ir/input.sol diff --git a/test/cmdlineTests/ethdebug_and_ethdebug_runtime/output b/test/cmdlineTests/ethdebug_and_ethdebug_runtime_ir/output similarity index 93% rename from test/cmdlineTests/ethdebug_and_ethdebug_runtime/output rename to test/cmdlineTests/ethdebug_and_ethdebug_runtime_ir/output index 000f29c4df1a..38dab05afaba 100644 --- a/test/cmdlineTests/ethdebug_and_ethdebug_runtime/output +++ b/test/cmdlineTests/ethdebug_and_ethdebug_runtime_ir/output @@ -1,10 +1,10 @@ ======= Debug Data (ethdebug/format/info/resources) ======= -{"sources":["ethdebug_and_ethdebug_runtime/input.sol"]} +{"sources":["ethdebug_and_ethdebug_runtime_ir/input.sol"]} -======= ethdebug_and_ethdebug_runtime/input.sol:C ======= +======= ethdebug_and_ethdebug_runtime_ir/input.sol:C ======= IR: /// ethdebug: enabled -/// @use-src 0:"ethdebug_and_ethdebug_runtime/input.sol" +/// @use-src 0:"ethdebug_and_ethdebug_runtime_ir/input.sol" object "C_6" { code { /// @src 0:60:101 "contract C {..." @@ -35,7 +35,7 @@ object "C_6" { /// @src 0:60:101 "contract C {..." } - /// @use-src 0:"ethdebug_and_ethdebug_runtime/input.sol" + /// @use-src 0:"ethdebug_and_ethdebug_runtime_ir/input.sol" object "C_6_deployed" { code { /// @src 0:60:101 "contract C {..." diff --git a/test/cmdlineTests/ethdebug_and_ethdebug_runtime_iroptimized/args b/test/cmdlineTests/ethdebug_and_ethdebug_runtime_iroptimized/args new file mode 100644 index 000000000000..09535998b5be --- /dev/null +++ b/test/cmdlineTests/ethdebug_and_ethdebug_runtime_iroptimized/args @@ -0,0 +1 @@ +--ethdebug-runtime --ethdebug --via-ir --ir-optimized \ No newline at end of file diff --git a/test/cmdlineTests/ethdebug_runtime/input.sol b/test/cmdlineTests/ethdebug_and_ethdebug_runtime_iroptimized/input.sol similarity index 100% rename from test/cmdlineTests/ethdebug_runtime/input.sol rename to test/cmdlineTests/ethdebug_and_ethdebug_runtime_iroptimized/input.sol diff --git a/test/cmdlineTests/ethdebug_and_ethdebug_runtime_iroptimized/output b/test/cmdlineTests/ethdebug_and_ethdebug_runtime_iroptimized/output new file mode 100644 index 000000000000..19a3c9e86b90 --- /dev/null +++ b/test/cmdlineTests/ethdebug_and_ethdebug_runtime_iroptimized/output @@ -0,0 +1,79 @@ +======= Debug Data (ethdebug/format/info/resources) ======= +{"sources":["ethdebug_and_ethdebug_runtime_iroptimized/input.sol"]} + +======= ethdebug_and_ethdebug_runtime_iroptimized/input.sol:C ======= +Optimized IR: +/// ethdebug: enabled +/// @use-src 0:"ethdebug_and_ethdebug_runtime_iroptimized/input.sol" +object "C_6" { + code { + { + /// @src 0:60:101 "contract C {..." + mstore(64, memoryguard(0x80)) + if callvalue() + { + revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() + } + let _1 := allocate_unbounded() + codecopy(_1, dataoffset("C_6_deployed"), datasize("C_6_deployed")) + return(_1, datasize("C_6_deployed")) + } + function allocate_unbounded() -> memPtr + { memPtr := mload(64) } + function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() + { revert(0, 0) } + } + /// @use-src 0:"ethdebug_and_ethdebug_runtime_iroptimized/input.sol" + object "C_6_deployed" { + code { + { + /// @src 0:60:101 "contract C {..." + mstore(64, memoryguard(0x80)) + if iszero(lt(calldatasize(), 4)) + { + let selector := shift_right_unsigned(calldataload(0)) + switch selector + case 0x26121ff0 { external_fun_f() } + default { } + } + revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() + } + function shift_right_unsigned(value) -> newValue + { newValue := shr(224, value) } + function allocate_unbounded() -> memPtr + { memPtr := mload(64) } + function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() + { revert(0, 0) } + function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() + { revert(0, 0) } + function abi_decode(headStart, dataEnd) + { + if slt(sub(dataEnd, headStart), 0) + { + revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() + } + } + function abi_encode_tuple(headStart) -> tail + { tail := add(headStart, 0) } + function external_fun_f() + { + if callvalue() + { + revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() + } + abi_decode(4, calldatasize()) + let memPos := allocate_unbounded() + let memEnd := abi_encode_tuple(memPos) + return(memPos, sub(memEnd, memPos)) + } + function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() + { revert(0, 0) } + } + data ".metadata" hex"" + } +} + +Debug Data (ethdebug/format/program): +{} +Debug Data of the runtime part (ethdebug/format/program): +{} diff --git a/test/cmdlineTests/ethdebug_enabled_optimization/err b/test/cmdlineTests/ethdebug_enabled_optimization/err deleted file mode 100644 index 082f6feee994..000000000000 --- a/test/cmdlineTests/ethdebug_enabled_optimization/err +++ /dev/null @@ -1 +0,0 @@ -Error: --ethdebug / --ethdebug-runtime output can only be used with --ir. Optimization is not yet supported with ethdebug, e.g. no support for --optimize / --ir-optimized yet. diff --git a/test/cmdlineTests/ethdebug_enabled_optimization_ir/args b/test/cmdlineTests/ethdebug_enabled_optimization_ir/args new file mode 100644 index 000000000000..38ce714e1b86 --- /dev/null +++ b/test/cmdlineTests/ethdebug_enabled_optimization_ir/args @@ -0,0 +1 @@ +--ethdebug --via-ir --optimize --ir \ No newline at end of file diff --git a/test/cmdlineTests/ethdebug_enabled_optimization_ir/err b/test/cmdlineTests/ethdebug_enabled_optimization_ir/err new file mode 100644 index 000000000000..b2c26e5d8a50 --- /dev/null +++ b/test/cmdlineTests/ethdebug_enabled_optimization_ir/err @@ -0,0 +1 @@ +Error: --ethdebug / --ethdebug-runtime output can only be used with --ir / --ir-optimized. Optimization (using --optimize) is not yet supported with ethdebug. diff --git a/test/cmdlineTests/ethdebug_enabled_optimization_ir/exit b/test/cmdlineTests/ethdebug_enabled_optimization_ir/exit new file mode 100644 index 000000000000..d00491fd7e5b --- /dev/null +++ b/test/cmdlineTests/ethdebug_enabled_optimization_ir/exit @@ -0,0 +1 @@ +1 diff --git a/test/cmdlineTests/ethdebug_enabled_optimization_ir/input.sol b/test/cmdlineTests/ethdebug_enabled_optimization_ir/input.sol new file mode 100644 index 000000000000..25b9640ca565 --- /dev/null +++ b/test/cmdlineTests/ethdebug_enabled_optimization_ir/input.sol @@ -0,0 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0 +pragma solidity >=0.0; + +contract C { + function f() public {} +} + diff --git a/test/cmdlineTests/ethdebug_enabled_optimization/args b/test/cmdlineTests/ethdebug_enabled_optimization_iroptimized/args similarity index 100% rename from test/cmdlineTests/ethdebug_enabled_optimization/args rename to test/cmdlineTests/ethdebug_enabled_optimization_iroptimized/args diff --git a/test/cmdlineTests/ethdebug_enabled_optimization_iroptimized/err b/test/cmdlineTests/ethdebug_enabled_optimization_iroptimized/err new file mode 100644 index 000000000000..b2c26e5d8a50 --- /dev/null +++ b/test/cmdlineTests/ethdebug_enabled_optimization_iroptimized/err @@ -0,0 +1 @@ +Error: --ethdebug / --ethdebug-runtime output can only be used with --ir / --ir-optimized. Optimization (using --optimize) is not yet supported with ethdebug. diff --git a/test/cmdlineTests/ethdebug_enabled_optimization_iroptimized/exit b/test/cmdlineTests/ethdebug_enabled_optimization_iroptimized/exit new file mode 100644 index 000000000000..d00491fd7e5b --- /dev/null +++ b/test/cmdlineTests/ethdebug_enabled_optimization_iroptimized/exit @@ -0,0 +1 @@ +1 diff --git a/test/cmdlineTests/ethdebug_enabled_optimization_iroptimized/input.sol b/test/cmdlineTests/ethdebug_enabled_optimization_iroptimized/input.sol new file mode 100644 index 000000000000..25b9640ca565 --- /dev/null +++ b/test/cmdlineTests/ethdebug_enabled_optimization_iroptimized/input.sol @@ -0,0 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0 +pragma solidity >=0.0; + +contract C { + function f() public {} +} + diff --git a/test/cmdlineTests/ethdebug/args b/test/cmdlineTests/ethdebug_ir/args similarity index 100% rename from test/cmdlineTests/ethdebug/args rename to test/cmdlineTests/ethdebug_ir/args diff --git a/test/cmdlineTests/ethdebug_ir/input.sol b/test/cmdlineTests/ethdebug_ir/input.sol new file mode 100644 index 000000000000..25b9640ca565 --- /dev/null +++ b/test/cmdlineTests/ethdebug_ir/input.sol @@ -0,0 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0 +pragma solidity >=0.0; + +contract C { + function f() public {} +} + diff --git a/test/cmdlineTests/ethdebug/output b/test/cmdlineTests/ethdebug_ir/output similarity index 95% rename from test/cmdlineTests/ethdebug/output rename to test/cmdlineTests/ethdebug_ir/output index 375c5cf900af..6713431b680e 100644 --- a/test/cmdlineTests/ethdebug/output +++ b/test/cmdlineTests/ethdebug_ir/output @@ -1,10 +1,10 @@ ======= Debug Data (ethdebug/format/info/resources) ======= -{"sources":["ethdebug/input.sol"]} +{"sources":["ethdebug_ir/input.sol"]} -======= ethdebug/input.sol:C ======= +======= ethdebug_ir/input.sol:C ======= IR: /// ethdebug: enabled -/// @use-src 0:"ethdebug/input.sol" +/// @use-src 0:"ethdebug_ir/input.sol" object "C_6" { code { /// @src 0:60:101 "contract C {..." @@ -35,7 +35,7 @@ object "C_6" { /// @src 0:60:101 "contract C {..." } - /// @use-src 0:"ethdebug/input.sol" + /// @use-src 0:"ethdebug_ir/input.sol" object "C_6_deployed" { code { /// @src 0:60:101 "contract C {..." diff --git a/test/cmdlineTests/ethdebug_iroptimized/args b/test/cmdlineTests/ethdebug_iroptimized/args new file mode 100644 index 000000000000..e048da7bbb2f --- /dev/null +++ b/test/cmdlineTests/ethdebug_iroptimized/args @@ -0,0 +1 @@ +--ethdebug --via-ir --ir-optimized \ No newline at end of file diff --git a/test/cmdlineTests/ethdebug_iroptimized/input.sol b/test/cmdlineTests/ethdebug_iroptimized/input.sol new file mode 100644 index 000000000000..25b9640ca565 --- /dev/null +++ b/test/cmdlineTests/ethdebug_iroptimized/input.sol @@ -0,0 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0 +pragma solidity >=0.0; + +contract C { + function f() public {} +} + diff --git a/test/cmdlineTests/ethdebug_iroptimized/output b/test/cmdlineTests/ethdebug_iroptimized/output new file mode 100644 index 000000000000..59e2579eb65a --- /dev/null +++ b/test/cmdlineTests/ethdebug_iroptimized/output @@ -0,0 +1,77 @@ +======= Debug Data (ethdebug/format/info/resources) ======= +{"sources":["ethdebug_iroptimized/input.sol"]} + +======= ethdebug_iroptimized/input.sol:C ======= +Optimized IR: +/// ethdebug: enabled +/// @use-src 0:"ethdebug_iroptimized/input.sol" +object "C_6" { + code { + { + /// @src 0:60:101 "contract C {..." + mstore(64, memoryguard(0x80)) + if callvalue() + { + revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() + } + let _1 := allocate_unbounded() + codecopy(_1, dataoffset("C_6_deployed"), datasize("C_6_deployed")) + return(_1, datasize("C_6_deployed")) + } + function allocate_unbounded() -> memPtr + { memPtr := mload(64) } + function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() + { revert(0, 0) } + } + /// @use-src 0:"ethdebug_iroptimized/input.sol" + object "C_6_deployed" { + code { + { + /// @src 0:60:101 "contract C {..." + mstore(64, memoryguard(0x80)) + if iszero(lt(calldatasize(), 4)) + { + let selector := shift_right_unsigned(calldataload(0)) + switch selector + case 0x26121ff0 { external_fun_f() } + default { } + } + revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() + } + function shift_right_unsigned(value) -> newValue + { newValue := shr(224, value) } + function allocate_unbounded() -> memPtr + { memPtr := mload(64) } + function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() + { revert(0, 0) } + function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() + { revert(0, 0) } + function abi_decode(headStart, dataEnd) + { + if slt(sub(dataEnd, headStart), 0) + { + revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() + } + } + function abi_encode_tuple(headStart) -> tail + { tail := add(headStart, 0) } + function external_fun_f() + { + if callvalue() + { + revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() + } + abi_decode(4, calldatasize()) + let memPos := allocate_unbounded() + let memEnd := abi_encode_tuple(memPos) + return(memPos, sub(memEnd, memPos)) + } + function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() + { revert(0, 0) } + } + data ".metadata" hex"" + } +} + +Debug Data (ethdebug/format/program): +{} diff --git a/test/cmdlineTests/ethdebug_no_via_ir/args b/test/cmdlineTests/ethdebug_no_via_ir/args new file mode 100644 index 000000000000..6a019364e6b3 --- /dev/null +++ b/test/cmdlineTests/ethdebug_no_via_ir/args @@ -0,0 +1 @@ +--ethdebug --ir --ir-optimized \ No newline at end of file diff --git a/test/cmdlineTests/ethdebug_no_via_ir/err b/test/cmdlineTests/ethdebug_no_via_ir/err new file mode 100644 index 000000000000..2729b6d5d830 --- /dev/null +++ b/test/cmdlineTests/ethdebug_no_via_ir/err @@ -0,0 +1 @@ +Error: --ethdebug / --ethdebug-runtime output can only be selected, if --via-ir was specified. diff --git a/test/cmdlineTests/ethdebug_no_via_ir/exit b/test/cmdlineTests/ethdebug_no_via_ir/exit new file mode 100644 index 000000000000..d00491fd7e5b --- /dev/null +++ b/test/cmdlineTests/ethdebug_no_via_ir/exit @@ -0,0 +1 @@ +1 diff --git a/test/cmdlineTests/ethdebug_no_via_ir/input.sol b/test/cmdlineTests/ethdebug_no_via_ir/input.sol new file mode 100644 index 000000000000..25b9640ca565 --- /dev/null +++ b/test/cmdlineTests/ethdebug_no_via_ir/input.sol @@ -0,0 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0 +pragma solidity >=0.0; + +contract C { + function f() public {} +} + diff --git a/test/cmdlineTests/ethdebug_runtime/args b/test/cmdlineTests/ethdebug_runtime_ir/args similarity index 100% rename from test/cmdlineTests/ethdebug_runtime/args rename to test/cmdlineTests/ethdebug_runtime_ir/args diff --git a/test/cmdlineTests/ethdebug_runtime_ir/input.sol b/test/cmdlineTests/ethdebug_runtime_ir/input.sol new file mode 100644 index 000000000000..25b9640ca565 --- /dev/null +++ b/test/cmdlineTests/ethdebug_runtime_ir/input.sol @@ -0,0 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0 +pragma solidity >=0.0; + +contract C { + function f() public {} +} + diff --git a/test/cmdlineTests/ethdebug_runtime/output b/test/cmdlineTests/ethdebug_runtime_ir/output similarity index 94% rename from test/cmdlineTests/ethdebug_runtime/output rename to test/cmdlineTests/ethdebug_runtime_ir/output index 8670e379d4e3..93b7b91f13e4 100644 --- a/test/cmdlineTests/ethdebug_runtime/output +++ b/test/cmdlineTests/ethdebug_runtime_ir/output @@ -1,10 +1,10 @@ ======= Debug Data (ethdebug/format/info/resources) ======= -{"sources":["ethdebug_runtime/input.sol"]} +{"sources":["ethdebug_runtime_ir/input.sol"]} -======= ethdebug_runtime/input.sol:C ======= +======= ethdebug_runtime_ir/input.sol:C ======= IR: /// ethdebug: enabled -/// @use-src 0:"ethdebug_runtime/input.sol" +/// @use-src 0:"ethdebug_runtime_ir/input.sol" object "C_6" { code { /// @src 0:60:101 "contract C {..." @@ -35,7 +35,7 @@ object "C_6" { /// @src 0:60:101 "contract C {..." } - /// @use-src 0:"ethdebug_runtime/input.sol" + /// @use-src 0:"ethdebug_runtime_ir/input.sol" object "C_6_deployed" { code { /// @src 0:60:101 "contract C {..." diff --git a/test/cmdlineTests/ethdebug_runtime_iroptimized/args b/test/cmdlineTests/ethdebug_runtime_iroptimized/args new file mode 100644 index 000000000000..f647c52a7eed --- /dev/null +++ b/test/cmdlineTests/ethdebug_runtime_iroptimized/args @@ -0,0 +1 @@ +--ethdebug-runtime --via-ir --ir-optimized \ No newline at end of file diff --git a/test/cmdlineTests/ethdebug_runtime_iroptimized/input.sol b/test/cmdlineTests/ethdebug_runtime_iroptimized/input.sol new file mode 100644 index 000000000000..25b9640ca565 --- /dev/null +++ b/test/cmdlineTests/ethdebug_runtime_iroptimized/input.sol @@ -0,0 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0 +pragma solidity >=0.0; + +contract C { + function f() public {} +} + diff --git a/test/cmdlineTests/ethdebug_runtime_iroptimized/output b/test/cmdlineTests/ethdebug_runtime_iroptimized/output new file mode 100644 index 000000000000..733e47a8500b --- /dev/null +++ b/test/cmdlineTests/ethdebug_runtime_iroptimized/output @@ -0,0 +1,77 @@ +======= Debug Data (ethdebug/format/info/resources) ======= +{"sources":["ethdebug_runtime_iroptimized/input.sol"]} + +======= ethdebug_runtime_iroptimized/input.sol:C ======= +Optimized IR: +/// ethdebug: enabled +/// @use-src 0:"ethdebug_runtime_iroptimized/input.sol" +object "C_6" { + code { + { + /// @src 0:60:101 "contract C {..." + mstore(64, memoryguard(0x80)) + if callvalue() + { + revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() + } + let _1 := allocate_unbounded() + codecopy(_1, dataoffset("C_6_deployed"), datasize("C_6_deployed")) + return(_1, datasize("C_6_deployed")) + } + function allocate_unbounded() -> memPtr + { memPtr := mload(64) } + function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() + { revert(0, 0) } + } + /// @use-src 0:"ethdebug_runtime_iroptimized/input.sol" + object "C_6_deployed" { + code { + { + /// @src 0:60:101 "contract C {..." + mstore(64, memoryguard(0x80)) + if iszero(lt(calldatasize(), 4)) + { + let selector := shift_right_unsigned(calldataload(0)) + switch selector + case 0x26121ff0 { external_fun_f() } + default { } + } + revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() + } + function shift_right_unsigned(value) -> newValue + { newValue := shr(224, value) } + function allocate_unbounded() -> memPtr + { memPtr := mload(64) } + function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() + { revert(0, 0) } + function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() + { revert(0, 0) } + function abi_decode(headStart, dataEnd) + { + if slt(sub(dataEnd, headStart), 0) + { + revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() + } + } + function abi_encode_tuple(headStart) -> tail + { tail := add(headStart, 0) } + function external_fun_f() + { + if callvalue() + { + revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() + } + abi_decode(4, calldatasize()) + let memPos := allocate_unbounded() + let memEnd := abi_encode_tuple(memPos) + return(memPos, sub(memEnd, memPos)) + } + function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() + { revert(0, 0) } + } + data ".metadata" hex"" + } +} + +Debug Data of the runtime part (ethdebug/format/program): +{} diff --git a/test/cmdlineTests/standard_output_debuginfo_ethdebug_compatible/input.json b/test/cmdlineTests/standard_output_debuginfo_ethdebug_compatible/input.json new file mode 100644 index 000000000000..422a54f90d9f --- /dev/null +++ b/test/cmdlineTests/standard_output_debuginfo_ethdebug_compatible/input.json @@ -0,0 +1,29 @@ +{ + "language": "Solidity", + "sources": { + "a.sol": { + "content": "//SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract A1 { function a(uint x) public pure { assert(x > 0); } } contract A2 { function a(uint x) public pure { assert(x > 0); } }" + }, + "b.sol": { + "content": "//SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract A1 { function b(uint x) public pure { assert(x > 0); } } contract B2 { function b(uint x) public pure { assert(x > 0); } }" + } + }, + "settings": { + "viaIR": true, + "debug": { + "debugInfo": [ + "ethdebug" + ] + }, + "outputSelection": { + "*": { + "*": [ + "evm.bytecode.ethdebug", + "evm.deployedBytecode.ethdebug", + "ir", + "irOptimized" + ] + } + } + } +} diff --git a/test/cmdlineTests/standard_output_debuginfo_ethdebug_compatible/output.json b/test/cmdlineTests/standard_output_debuginfo_ethdebug_compatible/output.json new file mode 100644 index 000000000000..0b8a87baf622 --- /dev/null +++ b/test/cmdlineTests/standard_output_debuginfo_ethdebug_compatible/output.json @@ -0,0 +1,1198 @@ +{ + "contracts": { + "a.sol": { + "A1": { + "evm": { + "bytecode": { + "ethdebug": {} + }, + "deployedBytecode": { + "ethdebug": {} + } + }, + "ir": "/// ethdebug: enabled +/// @use-src 0:\"a.sol\" +object \"A1_14\" { + code { + /// @src 0:58:123 + mstore(64, memoryguard(128)) + if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } + + constructor_A1_14() + + let _1 := allocate_unbounded() + codecopy(_1, dataoffset(\"A1_14_deployed\"), datasize(\"A1_14_deployed\")) + + return(_1, datasize(\"A1_14_deployed\")) + + function allocate_unbounded() -> memPtr { + memPtr := mload(64) + } + + function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() { + revert(0, 0) + } + + /// @src 0:58:123 + function constructor_A1_14() { + + /// @src 0:58:123 + + } + /// @src 0:58:123 + + } + /// @use-src 0:\"a.sol\" + object \"A1_14_deployed\" { + code { + /// @src 0:58:123 + mstore(64, memoryguard(128)) + + if iszero(lt(calldatasize(), 4)) + { + let selector := shift_right_224_unsigned(calldataload(0)) + switch selector + + case 0xf0fdf834 + { + // a(uint256) + + external_fun_a_13() + } + + default {} + } + + revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() + + function shift_right_224_unsigned(value) -> newValue { + newValue := + + shr(224, value) + + } + + function allocate_unbounded() -> memPtr { + memPtr := mload(64) + } + + function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() { + revert(0, 0) + } + + function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() { + revert(0, 0) + } + + function revert_error_c1322bf8034eace5e0b5c7295db60986aa89aae5e0ea0873e4689e076861a5db() { + revert(0, 0) + } + + function cleanup_t_uint256(value) -> cleaned { + cleaned := value + } + + function validator_revert_t_uint256(value) { + if iszero(eq(value, cleanup_t_uint256(value))) { revert(0, 0) } + } + + function abi_decode_t_uint256(offset, end) -> value { + value := calldataload(offset) + validator_revert_t_uint256(value) + } + + function abi_decode_tuple_t_uint256(headStart, dataEnd) -> value0 { + if slt(sub(dataEnd, headStart), 32) { revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() } + + { + + let offset := 0 + + value0 := abi_decode_t_uint256(add(headStart, offset), dataEnd) + } + + } + + function abi_encode_tuple__to__fromStack(headStart ) -> tail { + tail := add(headStart, 0) + + } + + function external_fun_a_13() { + + if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } + let param_0 := abi_decode_tuple_t_uint256(4, calldatasize()) + fun_a_13(param_0) + let memPos := allocate_unbounded() + let memEnd := abi_encode_tuple__to__fromStack(memPos ) + return(memPos, sub(memEnd, memPos)) + + } + + function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() { + revert(0, 0) + } + + function cleanup_t_rational_0_by_1(value) -> cleaned { + cleaned := value + } + + function identity(value) -> ret { + ret := value + } + + function convert_t_rational_0_by_1_to_t_uint256(value) -> converted { + converted := cleanup_t_uint256(identity(cleanup_t_rational_0_by_1(value))) + } + + function panic_error_0x01() { + mstore(0, 35408467139433450592217433187231851964531694900788300625387963629091585785856) + mstore(4, 0x01) + revert(0, 0x24) + } + + function assert_helper(condition) { + if iszero(condition) { panic_error_0x01() } + } + + /// @src 0:72:121 + function fun_a_13(var_x_3) { + + /// @src 0:112:113 + let _1 := var_x_3 + let expr_7 := _1 + /// @src 0:116:117 + let expr_8 := 0x00 + /// @src 0:112:117 + let expr_9 := gt(cleanup_t_uint256(expr_7), convert_t_rational_0_by_1_to_t_uint256(expr_8)) + /// @src 0:105:118 + assert_helper(expr_9) + + } + /// @src 0:58:123 + + } + + data \".metadata\" hex\"\" + } + +} + +", + "irOptimized": "/// ethdebug: enabled +/// @use-src 0:\"a.sol\" +object \"A1_14\" { + code { + { + /// @src 0:58:123 + mstore(64, memoryguard(0x80)) + if callvalue() + { + revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() + } + let _1 := allocate_unbounded() + codecopy(_1, dataoffset(\"A1_14_deployed\"), datasize(\"A1_14_deployed\")) + return(_1, datasize(\"A1_14_deployed\")) + } + function allocate_unbounded() -> memPtr + { memPtr := mload(64) } + function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() + { revert(0, 0) } + } + /// @use-src 0:\"a.sol\" + object \"A1_14_deployed\" { + code { + { + /// @src 0:58:123 + mstore(64, memoryguard(0x80)) + if iszero(lt(calldatasize(), 4)) + { + let selector := shift_right_unsigned(calldataload(0)) + switch selector + case 0xf0fdf834 { external_fun_a() } + default { } + } + revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() + } + function shift_right_unsigned(value) -> newValue + { newValue := shr(224, value) } + function allocate_unbounded() -> memPtr + { memPtr := mload(64) } + function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() + { revert(0, 0) } + function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() + { revert(0, 0) } + function cleanup_uint256(value) -> cleaned + { cleaned := value } + function validator_revert_uint256(value) + { + if iszero(eq(value, cleanup_uint256(value))) { revert(0, 0) } + } + function abi_decode_uint256(offset, end) -> value + { + value := calldataload(offset) + validator_revert_uint256(value) + } + function abi_decode_tuple_uint256(headStart, dataEnd) -> value0 + { + if slt(sub(dataEnd, headStart), 32) + { + revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() + } + let offset := 0 + value0 := abi_decode_uint256(add(headStart, offset), dataEnd) + } + function abi_encode_tuple(headStart) -> tail + { tail := add(headStart, 0) } + function external_fun_a() + { + if callvalue() + { + revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() + } + let param := abi_decode_tuple_uint256(4, calldatasize()) + fun_a(param) + let memPos := allocate_unbounded() + let memEnd := abi_encode_tuple(memPos) + return(memPos, sub(memEnd, memPos)) + } + function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() + { revert(0, 0) } + function cleanup_rational_by(value) -> cleaned + { cleaned := value } + function identity(value) -> ret + { ret := value } + function convert_rational_by_to_uint256(value) -> converted + { + converted := cleanup_uint256(identity(cleanup_rational_by(value))) + } + function panic_error_0x01() + { + mstore(0, shl(224, 0x4e487b71)) + mstore(4, 0x01) + revert(0, 0x24) + } + function assert_helper(condition) + { + if iszero(condition) { panic_error_0x01() } + } + /// @src 0:72:121 + function fun_a(var_x) + { + /// @src 0:112:113 + let _1 := var_x + let expr := _1 + /// @src 0:116:117 + let expr_1 := 0x00 + /// @src 0:112:117 + let expr_2 := gt(cleanup_uint256(expr), convert_rational_by_to_uint256(expr_1)) + /// @src 0:105:118 + assert_helper(expr_2) + } + } + data \".metadata\" hex\"\" + } +} +" + }, + "A2": { + "evm": { + "bytecode": { + "ethdebug": {} + }, + "deployedBytecode": { + "ethdebug": {} + } + }, + "ir": "/// ethdebug: enabled +/// @use-src 0:\"a.sol\" +object \"A2_27\" { + code { + /// @src 0:124:189 + mstore(64, memoryguard(128)) + if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } + + constructor_A2_27() + + let _1 := allocate_unbounded() + codecopy(_1, dataoffset(\"A2_27_deployed\"), datasize(\"A2_27_deployed\")) + + return(_1, datasize(\"A2_27_deployed\")) + + function allocate_unbounded() -> memPtr { + memPtr := mload(64) + } + + function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() { + revert(0, 0) + } + + /// @src 0:124:189 + function constructor_A2_27() { + + /// @src 0:124:189 + + } + /// @src 0:124:189 + + } + /// @use-src 0:\"a.sol\" + object \"A2_27_deployed\" { + code { + /// @src 0:124:189 + mstore(64, memoryguard(128)) + + if iszero(lt(calldatasize(), 4)) + { + let selector := shift_right_224_unsigned(calldataload(0)) + switch selector + + case 0xf0fdf834 + { + // a(uint256) + + external_fun_a_26() + } + + default {} + } + + revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() + + function shift_right_224_unsigned(value) -> newValue { + newValue := + + shr(224, value) + + } + + function allocate_unbounded() -> memPtr { + memPtr := mload(64) + } + + function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() { + revert(0, 0) + } + + function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() { + revert(0, 0) + } + + function revert_error_c1322bf8034eace5e0b5c7295db60986aa89aae5e0ea0873e4689e076861a5db() { + revert(0, 0) + } + + function cleanup_t_uint256(value) -> cleaned { + cleaned := value + } + + function validator_revert_t_uint256(value) { + if iszero(eq(value, cleanup_t_uint256(value))) { revert(0, 0) } + } + + function abi_decode_t_uint256(offset, end) -> value { + value := calldataload(offset) + validator_revert_t_uint256(value) + } + + function abi_decode_tuple_t_uint256(headStart, dataEnd) -> value0 { + if slt(sub(dataEnd, headStart), 32) { revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() } + + { + + let offset := 0 + + value0 := abi_decode_t_uint256(add(headStart, offset), dataEnd) + } + + } + + function abi_encode_tuple__to__fromStack(headStart ) -> tail { + tail := add(headStart, 0) + + } + + function external_fun_a_26() { + + if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } + let param_0 := abi_decode_tuple_t_uint256(4, calldatasize()) + fun_a_26(param_0) + let memPos := allocate_unbounded() + let memEnd := abi_encode_tuple__to__fromStack(memPos ) + return(memPos, sub(memEnd, memPos)) + + } + + function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() { + revert(0, 0) + } + + function cleanup_t_rational_0_by_1(value) -> cleaned { + cleaned := value + } + + function identity(value) -> ret { + ret := value + } + + function convert_t_rational_0_by_1_to_t_uint256(value) -> converted { + converted := cleanup_t_uint256(identity(cleanup_t_rational_0_by_1(value))) + } + + function panic_error_0x01() { + mstore(0, 35408467139433450592217433187231851964531694900788300625387963629091585785856) + mstore(4, 0x01) + revert(0, 0x24) + } + + function assert_helper(condition) { + if iszero(condition) { panic_error_0x01() } + } + + /// @src 0:138:187 + function fun_a_26(var_x_16) { + + /// @src 0:178:179 + let _1 := var_x_16 + let expr_20 := _1 + /// @src 0:182:183 + let expr_21 := 0x00 + /// @src 0:178:183 + let expr_22 := gt(cleanup_t_uint256(expr_20), convert_t_rational_0_by_1_to_t_uint256(expr_21)) + /// @src 0:171:184 + assert_helper(expr_22) + + } + /// @src 0:124:189 + + } + + data \".metadata\" hex\"\" + } + +} + +", + "irOptimized": "/// ethdebug: enabled +/// @use-src 0:\"a.sol\" +object \"A2_27\" { + code { + { + /// @src 0:124:189 + mstore(64, memoryguard(0x80)) + if callvalue() + { + revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() + } + let _1 := allocate_unbounded() + codecopy(_1, dataoffset(\"A2_27_deployed\"), datasize(\"A2_27_deployed\")) + return(_1, datasize(\"A2_27_deployed\")) + } + function allocate_unbounded() -> memPtr + { memPtr := mload(64) } + function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() + { revert(0, 0) } + } + /// @use-src 0:\"a.sol\" + object \"A2_27_deployed\" { + code { + { + /// @src 0:124:189 + mstore(64, memoryguard(0x80)) + if iszero(lt(calldatasize(), 4)) + { + let selector := shift_right_unsigned(calldataload(0)) + switch selector + case 0xf0fdf834 { external_fun_a() } + default { } + } + revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() + } + function shift_right_unsigned(value) -> newValue + { newValue := shr(224, value) } + function allocate_unbounded() -> memPtr + { memPtr := mload(64) } + function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() + { revert(0, 0) } + function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() + { revert(0, 0) } + function cleanup_uint256(value) -> cleaned + { cleaned := value } + function validator_revert_uint256(value) + { + if iszero(eq(value, cleanup_uint256(value))) { revert(0, 0) } + } + function abi_decode_uint256(offset, end) -> value + { + value := calldataload(offset) + validator_revert_uint256(value) + } + function abi_decode_tuple_uint256(headStart, dataEnd) -> value0 + { + if slt(sub(dataEnd, headStart), 32) + { + revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() + } + let offset := 0 + value0 := abi_decode_uint256(add(headStart, offset), dataEnd) + } + function abi_encode_tuple(headStart) -> tail + { tail := add(headStart, 0) } + function external_fun_a() + { + if callvalue() + { + revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() + } + let param := abi_decode_tuple_uint256(4, calldatasize()) + fun_a(param) + let memPos := allocate_unbounded() + let memEnd := abi_encode_tuple(memPos) + return(memPos, sub(memEnd, memPos)) + } + function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() + { revert(0, 0) } + function cleanup_rational_by(value) -> cleaned + { cleaned := value } + function identity(value) -> ret + { ret := value } + function convert_rational_by_to_uint256(value) -> converted + { + converted := cleanup_uint256(identity(cleanup_rational_by(value))) + } + function panic_error_0x01() + { + mstore(0, shl(224, 0x4e487b71)) + mstore(4, 0x01) + revert(0, 0x24) + } + function assert_helper(condition) + { + if iszero(condition) { panic_error_0x01() } + } + /// @src 0:138:187 + function fun_a(var_x) + { + /// @src 0:178:179 + let _1 := var_x + let expr := _1 + /// @src 0:182:183 + let expr_1 := 0x00 + /// @src 0:178:183 + let expr_2 := gt(cleanup_uint256(expr), convert_rational_by_to_uint256(expr_1)) + /// @src 0:171:184 + assert_helper(expr_2) + } + } + data \".metadata\" hex\"\" + } +} +" + } + }, + "b.sol": { + "A1": { + "evm": { + "bytecode": { + "ethdebug": {} + }, + "deployedBytecode": { + "ethdebug": {} + } + }, + "ir": "/// ethdebug: enabled +/// @use-src 1:\"b.sol\" +object \"A1_42\" { + code { + /// @src 1:58:123 + mstore(64, memoryguard(128)) + if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } + + constructor_A1_42() + + let _1 := allocate_unbounded() + codecopy(_1, dataoffset(\"A1_42_deployed\"), datasize(\"A1_42_deployed\")) + + return(_1, datasize(\"A1_42_deployed\")) + + function allocate_unbounded() -> memPtr { + memPtr := mload(64) + } + + function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() { + revert(0, 0) + } + + /// @src 1:58:123 + function constructor_A1_42() { + + /// @src 1:58:123 + + } + /// @src 1:58:123 + + } + /// @use-src 1:\"b.sol\" + object \"A1_42_deployed\" { + code { + /// @src 1:58:123 + mstore(64, memoryguard(128)) + + if iszero(lt(calldatasize(), 4)) + { + let selector := shift_right_224_unsigned(calldataload(0)) + switch selector + + case 0xcd580ff3 + { + // b(uint256) + + external_fun_b_41() + } + + default {} + } + + revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() + + function shift_right_224_unsigned(value) -> newValue { + newValue := + + shr(224, value) + + } + + function allocate_unbounded() -> memPtr { + memPtr := mload(64) + } + + function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() { + revert(0, 0) + } + + function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() { + revert(0, 0) + } + + function revert_error_c1322bf8034eace5e0b5c7295db60986aa89aae5e0ea0873e4689e076861a5db() { + revert(0, 0) + } + + function cleanup_t_uint256(value) -> cleaned { + cleaned := value + } + + function validator_revert_t_uint256(value) { + if iszero(eq(value, cleanup_t_uint256(value))) { revert(0, 0) } + } + + function abi_decode_t_uint256(offset, end) -> value { + value := calldataload(offset) + validator_revert_t_uint256(value) + } + + function abi_decode_tuple_t_uint256(headStart, dataEnd) -> value0 { + if slt(sub(dataEnd, headStart), 32) { revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() } + + { + + let offset := 0 + + value0 := abi_decode_t_uint256(add(headStart, offset), dataEnd) + } + + } + + function abi_encode_tuple__to__fromStack(headStart ) -> tail { + tail := add(headStart, 0) + + } + + function external_fun_b_41() { + + if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } + let param_0 := abi_decode_tuple_t_uint256(4, calldatasize()) + fun_b_41(param_0) + let memPos := allocate_unbounded() + let memEnd := abi_encode_tuple__to__fromStack(memPos ) + return(memPos, sub(memEnd, memPos)) + + } + + function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() { + revert(0, 0) + } + + function cleanup_t_rational_0_by_1(value) -> cleaned { + cleaned := value + } + + function identity(value) -> ret { + ret := value + } + + function convert_t_rational_0_by_1_to_t_uint256(value) -> converted { + converted := cleanup_t_uint256(identity(cleanup_t_rational_0_by_1(value))) + } + + function panic_error_0x01() { + mstore(0, 35408467139433450592217433187231851964531694900788300625387963629091585785856) + mstore(4, 0x01) + revert(0, 0x24) + } + + function assert_helper(condition) { + if iszero(condition) { panic_error_0x01() } + } + + /// @src 1:72:121 + function fun_b_41(var_x_31) { + + /// @src 1:112:113 + let _1 := var_x_31 + let expr_35 := _1 + /// @src 1:116:117 + let expr_36 := 0x00 + /// @src 1:112:117 + let expr_37 := gt(cleanup_t_uint256(expr_35), convert_t_rational_0_by_1_to_t_uint256(expr_36)) + /// @src 1:105:118 + assert_helper(expr_37) + + } + /// @src 1:58:123 + + } + + data \".metadata\" hex\"\" + } + +} + +", + "irOptimized": "/// ethdebug: enabled +/// @use-src 1:\"b.sol\" +object \"A1_42\" { + code { + { + /// @src 1:58:123 + mstore(64, memoryguard(0x80)) + if callvalue() + { + revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() + } + let _1 := allocate_unbounded() + codecopy(_1, dataoffset(\"A1_42_deployed\"), datasize(\"A1_42_deployed\")) + return(_1, datasize(\"A1_42_deployed\")) + } + function allocate_unbounded() -> memPtr + { memPtr := mload(64) } + function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() + { revert(0, 0) } + } + /// @use-src 1:\"b.sol\" + object \"A1_42_deployed\" { + code { + { + /// @src 1:58:123 + mstore(64, memoryguard(0x80)) + if iszero(lt(calldatasize(), 4)) + { + let selector := shift_right_unsigned(calldataload(0)) + switch selector + case 0xcd580ff3 { external_fun_b() } + default { } + } + revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() + } + function shift_right_unsigned(value) -> newValue + { newValue := shr(224, value) } + function allocate_unbounded() -> memPtr + { memPtr := mload(64) } + function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() + { revert(0, 0) } + function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() + { revert(0, 0) } + function cleanup_uint256(value) -> cleaned + { cleaned := value } + function validator_revert_uint256(value) + { + if iszero(eq(value, cleanup_uint256(value))) { revert(0, 0) } + } + function abi_decode_uint256(offset, end) -> value + { + value := calldataload(offset) + validator_revert_uint256(value) + } + function abi_decode_tuple_uint256(headStart, dataEnd) -> value0 + { + if slt(sub(dataEnd, headStart), 32) + { + revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() + } + let offset := 0 + value0 := abi_decode_uint256(add(headStart, offset), dataEnd) + } + function abi_encode_tuple(headStart) -> tail + { tail := add(headStart, 0) } + function external_fun_b() + { + if callvalue() + { + revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() + } + let param := abi_decode_tuple_uint256(4, calldatasize()) + fun_b(param) + let memPos := allocate_unbounded() + let memEnd := abi_encode_tuple(memPos) + return(memPos, sub(memEnd, memPos)) + } + function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() + { revert(0, 0) } + function cleanup_rational_by(value) -> cleaned + { cleaned := value } + function identity(value) -> ret + { ret := value } + function convert_rational_by_to_uint256(value) -> converted + { + converted := cleanup_uint256(identity(cleanup_rational_by(value))) + } + function panic_error_0x01() + { + mstore(0, shl(224, 0x4e487b71)) + mstore(4, 0x01) + revert(0, 0x24) + } + function assert_helper(condition) + { + if iszero(condition) { panic_error_0x01() } + } + /// @src 1:72:121 + function fun_b(var_x) + { + /// @src 1:112:113 + let _1 := var_x + let expr := _1 + /// @src 1:116:117 + let expr_1 := 0x00 + /// @src 1:112:117 + let expr_2 := gt(cleanup_uint256(expr), convert_rational_by_to_uint256(expr_1)) + /// @src 1:105:118 + assert_helper(expr_2) + } + } + data \".metadata\" hex\"\" + } +} +" + }, + "B2": { + "evm": { + "bytecode": { + "ethdebug": {} + }, + "deployedBytecode": { + "ethdebug": {} + } + }, + "ir": "/// ethdebug: enabled +/// @use-src 1:\"b.sol\" +object \"B2_55\" { + code { + /// @src 1:124:189 + mstore(64, memoryguard(128)) + if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } + + constructor_B2_55() + + let _1 := allocate_unbounded() + codecopy(_1, dataoffset(\"B2_55_deployed\"), datasize(\"B2_55_deployed\")) + + return(_1, datasize(\"B2_55_deployed\")) + + function allocate_unbounded() -> memPtr { + memPtr := mload(64) + } + + function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() { + revert(0, 0) + } + + /// @src 1:124:189 + function constructor_B2_55() { + + /// @src 1:124:189 + + } + /// @src 1:124:189 + + } + /// @use-src 1:\"b.sol\" + object \"B2_55_deployed\" { + code { + /// @src 1:124:189 + mstore(64, memoryguard(128)) + + if iszero(lt(calldatasize(), 4)) + { + let selector := shift_right_224_unsigned(calldataload(0)) + switch selector + + case 0xcd580ff3 + { + // b(uint256) + + external_fun_b_54() + } + + default {} + } + + revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() + + function shift_right_224_unsigned(value) -> newValue { + newValue := + + shr(224, value) + + } + + function allocate_unbounded() -> memPtr { + memPtr := mload(64) + } + + function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() { + revert(0, 0) + } + + function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() { + revert(0, 0) + } + + function revert_error_c1322bf8034eace5e0b5c7295db60986aa89aae5e0ea0873e4689e076861a5db() { + revert(0, 0) + } + + function cleanup_t_uint256(value) -> cleaned { + cleaned := value + } + + function validator_revert_t_uint256(value) { + if iszero(eq(value, cleanup_t_uint256(value))) { revert(0, 0) } + } + + function abi_decode_t_uint256(offset, end) -> value { + value := calldataload(offset) + validator_revert_t_uint256(value) + } + + function abi_decode_tuple_t_uint256(headStart, dataEnd) -> value0 { + if slt(sub(dataEnd, headStart), 32) { revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() } + + { + + let offset := 0 + + value0 := abi_decode_t_uint256(add(headStart, offset), dataEnd) + } + + } + + function abi_encode_tuple__to__fromStack(headStart ) -> tail { + tail := add(headStart, 0) + + } + + function external_fun_b_54() { + + if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } + let param_0 := abi_decode_tuple_t_uint256(4, calldatasize()) + fun_b_54(param_0) + let memPos := allocate_unbounded() + let memEnd := abi_encode_tuple__to__fromStack(memPos ) + return(memPos, sub(memEnd, memPos)) + + } + + function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() { + revert(0, 0) + } + + function cleanup_t_rational_0_by_1(value) -> cleaned { + cleaned := value + } + + function identity(value) -> ret { + ret := value + } + + function convert_t_rational_0_by_1_to_t_uint256(value) -> converted { + converted := cleanup_t_uint256(identity(cleanup_t_rational_0_by_1(value))) + } + + function panic_error_0x01() { + mstore(0, 35408467139433450592217433187231851964531694900788300625387963629091585785856) + mstore(4, 0x01) + revert(0, 0x24) + } + + function assert_helper(condition) { + if iszero(condition) { panic_error_0x01() } + } + + /// @src 1:138:187 + function fun_b_54(var_x_44) { + + /// @src 1:178:179 + let _1 := var_x_44 + let expr_48 := _1 + /// @src 1:182:183 + let expr_49 := 0x00 + /// @src 1:178:183 + let expr_50 := gt(cleanup_t_uint256(expr_48), convert_t_rational_0_by_1_to_t_uint256(expr_49)) + /// @src 1:171:184 + assert_helper(expr_50) + + } + /// @src 1:124:189 + + } + + data \".metadata\" hex\"\" + } + +} + +", + "irOptimized": "/// ethdebug: enabled +/// @use-src 1:\"b.sol\" +object \"B2_55\" { + code { + { + /// @src 1:124:189 + mstore(64, memoryguard(0x80)) + if callvalue() + { + revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() + } + let _1 := allocate_unbounded() + codecopy(_1, dataoffset(\"B2_55_deployed\"), datasize(\"B2_55_deployed\")) + return(_1, datasize(\"B2_55_deployed\")) + } + function allocate_unbounded() -> memPtr + { memPtr := mload(64) } + function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() + { revert(0, 0) } + } + /// @use-src 1:\"b.sol\" + object \"B2_55_deployed\" { + code { + { + /// @src 1:124:189 + mstore(64, memoryguard(0x80)) + if iszero(lt(calldatasize(), 4)) + { + let selector := shift_right_unsigned(calldataload(0)) + switch selector + case 0xcd580ff3 { external_fun_b() } + default { } + } + revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() + } + function shift_right_unsigned(value) -> newValue + { newValue := shr(224, value) } + function allocate_unbounded() -> memPtr + { memPtr := mload(64) } + function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() + { revert(0, 0) } + function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() + { revert(0, 0) } + function cleanup_uint256(value) -> cleaned + { cleaned := value } + function validator_revert_uint256(value) + { + if iszero(eq(value, cleanup_uint256(value))) { revert(0, 0) } + } + function abi_decode_uint256(offset, end) -> value + { + value := calldataload(offset) + validator_revert_uint256(value) + } + function abi_decode_tuple_uint256(headStart, dataEnd) -> value0 + { + if slt(sub(dataEnd, headStart), 32) + { + revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() + } + let offset := 0 + value0 := abi_decode_uint256(add(headStart, offset), dataEnd) + } + function abi_encode_tuple(headStart) -> tail + { tail := add(headStart, 0) } + function external_fun_b() + { + if callvalue() + { + revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() + } + let param := abi_decode_tuple_uint256(4, calldatasize()) + fun_b(param) + let memPos := allocate_unbounded() + let memEnd := abi_encode_tuple(memPos) + return(memPos, sub(memEnd, memPos)) + } + function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() + { revert(0, 0) } + function cleanup_rational_by(value) -> cleaned + { cleaned := value } + function identity(value) -> ret + { ret := value } + function convert_rational_by_to_uint256(value) -> converted + { + converted := cleanup_uint256(identity(cleanup_rational_by(value))) + } + function panic_error_0x01() + { + mstore(0, shl(224, 0x4e487b71)) + mstore(4, 0x01) + revert(0, 0x24) + } + function assert_helper(condition) + { + if iszero(condition) { panic_error_0x01() } + } + /// @src 1:138:187 + function fun_b(var_x) + { + /// @src 1:178:179 + let _1 := var_x + let expr := _1 + /// @src 1:182:183 + let expr_1 := 0x00 + /// @src 1:178:183 + let expr_2 := gt(cleanup_uint256(expr), convert_rational_by_to_uint256(expr_1)) + /// @src 1:171:184 + assert_helper(expr_2) + } + } + data \".metadata\" hex\"\" + } +} +" + } + } + }, + "ethdebug": { + "sources": [ + "a.sol", + "b.sol" + ] + }, + "sources": { + "a.sol": { + "id": 0 + }, + "b.sol": { + "id": 1 + } + } +} diff --git a/test/cmdlineTests/standard_output_debuginfo_ethdebug_incompatible/input.json b/test/cmdlineTests/standard_output_debuginfo_ethdebug_incompatible/input.json new file mode 100644 index 000000000000..8f8edcd29203 --- /dev/null +++ b/test/cmdlineTests/standard_output_debuginfo_ethdebug_incompatible/input.json @@ -0,0 +1,26 @@ +{ + "language": "Solidity", + "sources": { + "a.sol": { + "content": "//SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract A1 { function a(uint x) public pure { assert(x > 0); } } contract A2 { function a(uint x) public pure { assert(x > 0); } }" + }, + "b.sol": { + "content": "//SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract A1 { function b(uint x) public pure { assert(x > 0); } } contract B2 { function b(uint x) public pure { assert(x > 0); } }" + } + }, + "settings": { + "viaIR": true, + "debug": { + "debugInfo": [ + "ethdebug" + ] + }, + "outputSelection": { + "*": { + "*": [ + "evm.assembly" + ] + } + } + } +} diff --git a/test/cmdlineTests/standard_output_debuginfo_ethdebug_incompatible/output.json b/test/cmdlineTests/standard_output_debuginfo_ethdebug_incompatible/output.json new file mode 100644 index 000000000000..963bcd8d7d68 --- /dev/null +++ b/test/cmdlineTests/standard_output_debuginfo_ethdebug_incompatible/output.json @@ -0,0 +1,11 @@ +{ + "errors": [ + { + "component": "general", + "formattedMessage": "'settings.debug.debugInfo' can only include 'ethdebug', if output 'ir', 'irOptimized', 'evm.bytecode.ethdebug', or 'evm.deployedBytecode.ethdebug' was selected.", + "message": "'settings.debug.debugInfo' can only include 'ethdebug', if output 'ir', 'irOptimized', 'evm.bytecode.ethdebug', or 'evm.deployedBytecode.ethdebug' was selected.", + "severity": "error", + "type": "FatalError" + } + ] +} diff --git a/test/cmdlineTests/standard_output_selection_ethdebug_bytecode/input.json b/test/cmdlineTests/standard_output_selection_ethdebug_bytecode/input.json deleted file mode 100644 index 6ac2691c2085..000000000000 --- a/test/cmdlineTests/standard_output_selection_ethdebug_bytecode/input.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "language": "Solidity", - "sources": { - "a.sol": { - "content": "//SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract A1 { function a(uint x) public pure { assert(x > 0); } } contract A2 { function a(uint x) public pure { assert(x > 0); } }" - }, - "b.sol": { - "content": "//SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract A1 { function b(uint x) public pure { assert(x > 0); } } contract B2 { function b(uint x) public pure { assert(x > 0); } }" - } - }, - "settings": { - "viaIR": true, - "optimizer": { - "enabled": false - }, - "outputSelection": { - "*": { - "*": [ - "evm.bytecode.ethdebug", "ir" - ] - } - } - } -} diff --git a/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode/input.json b/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode/input.json deleted file mode 100644 index bb93f57a8256..000000000000 --- a/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode/input.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "language": "Solidity", - "sources": { - "a.sol": { - "content": "//SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract A1 { function a(uint x) public pure { assert(x > 0); } } contract A2 { function a(uint x) public pure { assert(x > 0); } }" - }, - "b.sol": { - "content": "//SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract A1 { function b(uint x) public pure { assert(x > 0); } } contract B2 { function b(uint x) public pure { assert(x > 0); } }" - } - }, - "settings": { - "viaIR": true, - "optimizer": { - "enabled": false - }, - "outputSelection": { - "*": { - "*": [ - "evm.bytecode.ethdebug", "evm.deployedBytecode.ethdebug", "ir" - ] - } - } - } -} diff --git a/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_ir/input.json b/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_ir/input.json new file mode 100644 index 000000000000..8ed44ca05de2 --- /dev/null +++ b/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_ir/input.json @@ -0,0 +1,26 @@ +{ + "language": "Solidity", + "sources": { + "a.sol": { + "content": "//SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract A1 { function a(uint x) public pure { assert(x > 0); } } contract A2 { function a(uint x) public pure { assert(x > 0); } }" + }, + "b.sol": { + "content": "//SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract A1 { function b(uint x) public pure { assert(x > 0); } } contract B2 { function b(uint x) public pure { assert(x > 0); } }" + } + }, + "settings": { + "viaIR": true, + "optimizer": { + "enabled": false + }, + "outputSelection": { + "*": { + "*": [ + "evm.bytecode.ethdebug", + "evm.deployedBytecode.ethdebug", + "ir" + ] + } + } + } +} diff --git a/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode/output.json b/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_ir/output.json similarity index 100% rename from test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode/output.json rename to test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_ir/output.json diff --git a/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_iroptimized/input.json b/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_iroptimized/input.json new file mode 100644 index 000000000000..27c400f9e946 --- /dev/null +++ b/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_iroptimized/input.json @@ -0,0 +1,26 @@ +{ + "language": "Solidity", + "sources": { + "a.sol": { + "content": "//SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract A1 { function a(uint x) public pure { assert(x > 0); } } contract A2 { function a(uint x) public pure { assert(x > 0); } }" + }, + "b.sol": { + "content": "//SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract A1 { function b(uint x) public pure { assert(x > 0); } } contract B2 { function b(uint x) public pure { assert(x > 0); } }" + } + }, + "settings": { + "viaIR": true, + "optimizer": { + "enabled": false + }, + "outputSelection": { + "*": { + "*": [ + "evm.bytecode.ethdebug", + "evm.deployedBytecode.ethdebug", + "irOptimized" + ] + } + } + } +} diff --git a/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_iroptimized/output.json b/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_iroptimized/output.json new file mode 100644 index 000000000000..66b9082dcc12 --- /dev/null +++ b/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_iroptimized/output.json @@ -0,0 +1,522 @@ +{ + "contracts": { + "a.sol": { + "A1": { + "evm": { + "bytecode": { + "ethdebug": {} + }, + "deployedBytecode": { + "ethdebug": {} + } + }, + "irOptimized": "/// ethdebug: enabled +/// @use-src 0:\"a.sol\" +object \"A1_14\" { + code { + { + /// @src 0:58:123 \"contract A1 { function a(uint x) public pure { assert(x > 0); } }\" + mstore(64, memoryguard(0x80)) + if callvalue() + { + revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() + } + let _1 := allocate_unbounded() + codecopy(_1, dataoffset(\"A1_14_deployed\"), datasize(\"A1_14_deployed\")) + return(_1, datasize(\"A1_14_deployed\")) + } + function allocate_unbounded() -> memPtr + { memPtr := mload(64) } + function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() + { revert(0, 0) } + } + /// @use-src 0:\"a.sol\" + object \"A1_14_deployed\" { + code { + { + /// @src 0:58:123 \"contract A1 { function a(uint x) public pure { assert(x > 0); } }\" + mstore(64, memoryguard(0x80)) + if iszero(lt(calldatasize(), 4)) + { + let selector := shift_right_unsigned(calldataload(0)) + switch selector + case 0xf0fdf834 { external_fun_a() } + default { } + } + revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() + } + function shift_right_unsigned(value) -> newValue + { newValue := shr(224, value) } + function allocate_unbounded() -> memPtr + { memPtr := mload(64) } + function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() + { revert(0, 0) } + function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() + { revert(0, 0) } + function cleanup_uint256(value) -> cleaned + { cleaned := value } + function validator_revert_uint256(value) + { + if iszero(eq(value, cleanup_uint256(value))) { revert(0, 0) } + } + function abi_decode_uint256(offset, end) -> value + { + value := calldataload(offset) + validator_revert_uint256(value) + } + function abi_decode_tuple_uint256(headStart, dataEnd) -> value0 + { + if slt(sub(dataEnd, headStart), 32) + { + revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() + } + let offset := 0 + value0 := abi_decode_uint256(add(headStart, offset), dataEnd) + } + function abi_encode_tuple(headStart) -> tail + { tail := add(headStart, 0) } + function external_fun_a() + { + if callvalue() + { + revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() + } + let param := abi_decode_tuple_uint256(4, calldatasize()) + fun_a(param) + let memPos := allocate_unbounded() + let memEnd := abi_encode_tuple(memPos) + return(memPos, sub(memEnd, memPos)) + } + function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() + { revert(0, 0) } + function cleanup_rational_by(value) -> cleaned + { cleaned := value } + function identity(value) -> ret + { ret := value } + function convert_rational_by_to_uint256(value) -> converted + { + converted := cleanup_uint256(identity(cleanup_rational_by(value))) + } + function panic_error_0x01() + { + mstore(0, shl(224, 0x4e487b71)) + mstore(4, 0x01) + revert(0, 0x24) + } + function assert_helper(condition) + { + if iszero(condition) { panic_error_0x01() } + } + /// @ast-id 13 @src 0:72:121 \"function a(uint x) public pure { assert(x > 0); }\" + function fun_a(var_x) + { + /// @src 0:112:113 \"x\" + let _1 := var_x + let expr := _1 + /// @src 0:116:117 \"0\" + let expr_1 := 0x00 + /// @src 0:112:117 \"x > 0\" + let expr_2 := gt(cleanup_uint256(expr), convert_rational_by_to_uint256(expr_1)) + /// @src 0:105:118 \"assert(x > 0)\" + assert_helper(expr_2) + } + } + data \".metadata\" hex\"\" + } +} +" + }, + "A2": { + "evm": { + "bytecode": { + "ethdebug": {} + }, + "deployedBytecode": { + "ethdebug": {} + } + }, + "irOptimized": "/// ethdebug: enabled +/// @use-src 0:\"a.sol\" +object \"A2_27\" { + code { + { + /// @src 0:124:189 \"contract A2 { function a(uint x) public pure { assert(x > 0); } }\" + mstore(64, memoryguard(0x80)) + if callvalue() + { + revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() + } + let _1 := allocate_unbounded() + codecopy(_1, dataoffset(\"A2_27_deployed\"), datasize(\"A2_27_deployed\")) + return(_1, datasize(\"A2_27_deployed\")) + } + function allocate_unbounded() -> memPtr + { memPtr := mload(64) } + function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() + { revert(0, 0) } + } + /// @use-src 0:\"a.sol\" + object \"A2_27_deployed\" { + code { + { + /// @src 0:124:189 \"contract A2 { function a(uint x) public pure { assert(x > 0); } }\" + mstore(64, memoryguard(0x80)) + if iszero(lt(calldatasize(), 4)) + { + let selector := shift_right_unsigned(calldataload(0)) + switch selector + case 0xf0fdf834 { external_fun_a() } + default { } + } + revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() + } + function shift_right_unsigned(value) -> newValue + { newValue := shr(224, value) } + function allocate_unbounded() -> memPtr + { memPtr := mload(64) } + function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() + { revert(0, 0) } + function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() + { revert(0, 0) } + function cleanup_uint256(value) -> cleaned + { cleaned := value } + function validator_revert_uint256(value) + { + if iszero(eq(value, cleanup_uint256(value))) { revert(0, 0) } + } + function abi_decode_uint256(offset, end) -> value + { + value := calldataload(offset) + validator_revert_uint256(value) + } + function abi_decode_tuple_uint256(headStart, dataEnd) -> value0 + { + if slt(sub(dataEnd, headStart), 32) + { + revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() + } + let offset := 0 + value0 := abi_decode_uint256(add(headStart, offset), dataEnd) + } + function abi_encode_tuple(headStart) -> tail + { tail := add(headStart, 0) } + function external_fun_a() + { + if callvalue() + { + revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() + } + let param := abi_decode_tuple_uint256(4, calldatasize()) + fun_a(param) + let memPos := allocate_unbounded() + let memEnd := abi_encode_tuple(memPos) + return(memPos, sub(memEnd, memPos)) + } + function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() + { revert(0, 0) } + function cleanup_rational_by(value) -> cleaned + { cleaned := value } + function identity(value) -> ret + { ret := value } + function convert_rational_by_to_uint256(value) -> converted + { + converted := cleanup_uint256(identity(cleanup_rational_by(value))) + } + function panic_error_0x01() + { + mstore(0, shl(224, 0x4e487b71)) + mstore(4, 0x01) + revert(0, 0x24) + } + function assert_helper(condition) + { + if iszero(condition) { panic_error_0x01() } + } + /// @ast-id 26 @src 0:138:187 \"function a(uint x) public pure { assert(x > 0); }\" + function fun_a(var_x) + { + /// @src 0:178:179 \"x\" + let _1 := var_x + let expr := _1 + /// @src 0:182:183 \"0\" + let expr_1 := 0x00 + /// @src 0:178:183 \"x > 0\" + let expr_2 := gt(cleanup_uint256(expr), convert_rational_by_to_uint256(expr_1)) + /// @src 0:171:184 \"assert(x > 0)\" + assert_helper(expr_2) + } + } + data \".metadata\" hex\"\" + } +} +" + } + }, + "b.sol": { + "A1": { + "evm": { + "bytecode": { + "ethdebug": {} + }, + "deployedBytecode": { + "ethdebug": {} + } + }, + "irOptimized": "/// ethdebug: enabled +/// @use-src 1:\"b.sol\" +object \"A1_42\" { + code { + { + /// @src 1:58:123 \"contract A1 { function b(uint x) public pure { assert(x > 0); } }\" + mstore(64, memoryguard(0x80)) + if callvalue() + { + revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() + } + let _1 := allocate_unbounded() + codecopy(_1, dataoffset(\"A1_42_deployed\"), datasize(\"A1_42_deployed\")) + return(_1, datasize(\"A1_42_deployed\")) + } + function allocate_unbounded() -> memPtr + { memPtr := mload(64) } + function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() + { revert(0, 0) } + } + /// @use-src 1:\"b.sol\" + object \"A1_42_deployed\" { + code { + { + /// @src 1:58:123 \"contract A1 { function b(uint x) public pure { assert(x > 0); } }\" + mstore(64, memoryguard(0x80)) + if iszero(lt(calldatasize(), 4)) + { + let selector := shift_right_unsigned(calldataload(0)) + switch selector + case 0xcd580ff3 { external_fun_b() } + default { } + } + revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() + } + function shift_right_unsigned(value) -> newValue + { newValue := shr(224, value) } + function allocate_unbounded() -> memPtr + { memPtr := mload(64) } + function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() + { revert(0, 0) } + function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() + { revert(0, 0) } + function cleanup_uint256(value) -> cleaned + { cleaned := value } + function validator_revert_uint256(value) + { + if iszero(eq(value, cleanup_uint256(value))) { revert(0, 0) } + } + function abi_decode_uint256(offset, end) -> value + { + value := calldataload(offset) + validator_revert_uint256(value) + } + function abi_decode_tuple_uint256(headStart, dataEnd) -> value0 + { + if slt(sub(dataEnd, headStart), 32) + { + revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() + } + let offset := 0 + value0 := abi_decode_uint256(add(headStart, offset), dataEnd) + } + function abi_encode_tuple(headStart) -> tail + { tail := add(headStart, 0) } + function external_fun_b() + { + if callvalue() + { + revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() + } + let param := abi_decode_tuple_uint256(4, calldatasize()) + fun_b(param) + let memPos := allocate_unbounded() + let memEnd := abi_encode_tuple(memPos) + return(memPos, sub(memEnd, memPos)) + } + function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() + { revert(0, 0) } + function cleanup_rational_by(value) -> cleaned + { cleaned := value } + function identity(value) -> ret + { ret := value } + function convert_rational_by_to_uint256(value) -> converted + { + converted := cleanup_uint256(identity(cleanup_rational_by(value))) + } + function panic_error_0x01() + { + mstore(0, shl(224, 0x4e487b71)) + mstore(4, 0x01) + revert(0, 0x24) + } + function assert_helper(condition) + { + if iszero(condition) { panic_error_0x01() } + } + /// @ast-id 41 @src 1:72:121 \"function b(uint x) public pure { assert(x > 0); }\" + function fun_b(var_x) + { + /// @src 1:112:113 \"x\" + let _1 := var_x + let expr := _1 + /// @src 1:116:117 \"0\" + let expr_1 := 0x00 + /// @src 1:112:117 \"x > 0\" + let expr_2 := gt(cleanup_uint256(expr), convert_rational_by_to_uint256(expr_1)) + /// @src 1:105:118 \"assert(x > 0)\" + assert_helper(expr_2) + } + } + data \".metadata\" hex\"\" + } +} +" + }, + "B2": { + "evm": { + "bytecode": { + "ethdebug": {} + }, + "deployedBytecode": { + "ethdebug": {} + } + }, + "irOptimized": "/// ethdebug: enabled +/// @use-src 1:\"b.sol\" +object \"B2_55\" { + code { + { + /// @src 1:124:189 \"contract B2 { function b(uint x) public pure { assert(x > 0); } }\" + mstore(64, memoryguard(0x80)) + if callvalue() + { + revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() + } + let _1 := allocate_unbounded() + codecopy(_1, dataoffset(\"B2_55_deployed\"), datasize(\"B2_55_deployed\")) + return(_1, datasize(\"B2_55_deployed\")) + } + function allocate_unbounded() -> memPtr + { memPtr := mload(64) } + function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() + { revert(0, 0) } + } + /// @use-src 1:\"b.sol\" + object \"B2_55_deployed\" { + code { + { + /// @src 1:124:189 \"contract B2 { function b(uint x) public pure { assert(x > 0); } }\" + mstore(64, memoryguard(0x80)) + if iszero(lt(calldatasize(), 4)) + { + let selector := shift_right_unsigned(calldataload(0)) + switch selector + case 0xcd580ff3 { external_fun_b() } + default { } + } + revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() + } + function shift_right_unsigned(value) -> newValue + { newValue := shr(224, value) } + function allocate_unbounded() -> memPtr + { memPtr := mload(64) } + function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() + { revert(0, 0) } + function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() + { revert(0, 0) } + function cleanup_uint256(value) -> cleaned + { cleaned := value } + function validator_revert_uint256(value) + { + if iszero(eq(value, cleanup_uint256(value))) { revert(0, 0) } + } + function abi_decode_uint256(offset, end) -> value + { + value := calldataload(offset) + validator_revert_uint256(value) + } + function abi_decode_tuple_uint256(headStart, dataEnd) -> value0 + { + if slt(sub(dataEnd, headStart), 32) + { + revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() + } + let offset := 0 + value0 := abi_decode_uint256(add(headStart, offset), dataEnd) + } + function abi_encode_tuple(headStart) -> tail + { tail := add(headStart, 0) } + function external_fun_b() + { + if callvalue() + { + revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() + } + let param := abi_decode_tuple_uint256(4, calldatasize()) + fun_b(param) + let memPos := allocate_unbounded() + let memEnd := abi_encode_tuple(memPos) + return(memPos, sub(memEnd, memPos)) + } + function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() + { revert(0, 0) } + function cleanup_rational_by(value) -> cleaned + { cleaned := value } + function identity(value) -> ret + { ret := value } + function convert_rational_by_to_uint256(value) -> converted + { + converted := cleanup_uint256(identity(cleanup_rational_by(value))) + } + function panic_error_0x01() + { + mstore(0, shl(224, 0x4e487b71)) + mstore(4, 0x01) + revert(0, 0x24) + } + function assert_helper(condition) + { + if iszero(condition) { panic_error_0x01() } + } + /// @ast-id 54 @src 1:138:187 \"function b(uint x) public pure { assert(x > 0); }\" + function fun_b(var_x) + { + /// @src 1:178:179 \"x\" + let _1 := var_x + let expr := _1 + /// @src 1:182:183 \"0\" + let expr_1 := 0x00 + /// @src 1:178:183 \"x > 0\" + let expr_2 := gt(cleanup_uint256(expr), convert_rational_by_to_uint256(expr_1)) + /// @src 1:171:184 \"assert(x > 0)\" + assert_helper(expr_2) + } + } + data \".metadata\" hex\"\" + } +} +" + } + } + }, + "ethdebug": { + "sources": [ + "a.sol", + "b.sol" + ] + }, + "sources": { + "a.sol": { + "id": 0 + }, + "b.sol": { + "id": 1 + } + } +} diff --git a/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_optimizer/input.json b/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_optimizer/input.json deleted file mode 100644 index e45f27f3caa8..000000000000 --- a/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_optimizer/input.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "language": "Solidity", - "sources": { - "a.sol": { - "content": "//SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract A1 { function a(uint x) public pure { assert(x > 0); } } contract A2 { function a(uint x) public pure { assert(x > 0); } }" - }, - "b.sol": { - "content": "//SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract A1 { function b(uint x) public pure { assert(x > 0); } } contract B2 { function b(uint x) public pure { assert(x > 0); } }" - } - }, - "settings": { - "viaIR": true, - "optimizer": { - "enabled": true - }, - "outputSelection": { - "*": { - "*": [ - "evm.bytecode.ethdebug", "evm.deployedBytecode.ethdebug", "irOptimized" - ] - } - } - } -} diff --git a/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_optimizer_ir/input.json b/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_optimizer_ir/input.json new file mode 100644 index 000000000000..ad74649f5d1d --- /dev/null +++ b/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_optimizer_ir/input.json @@ -0,0 +1,26 @@ +{ + "language": "Solidity", + "sources": { + "a.sol": { + "content": "//SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract A1 { function a(uint x) public pure { assert(x > 0); } } contract A2 { function a(uint x) public pure { assert(x > 0); } }" + }, + "b.sol": { + "content": "//SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract A1 { function b(uint x) public pure { assert(x > 0); } } contract B2 { function b(uint x) public pure { assert(x > 0); } }" + } + }, + "settings": { + "viaIR": true, + "optimizer": { + "enabled": true + }, + "outputSelection": { + "*": { + "*": [ + "evm.bytecode.ethdebug", + "evm.deployedBytecode.ethdebug", + "irOptimized" + ] + } + } + } +} diff --git a/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_optimizer/output.json b/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_optimizer_ir/output.json similarity index 85% rename from test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_optimizer/output.json rename to test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_optimizer_ir/output.json index 3ed2f577c7aa..44867c7a75eb 100644 --- a/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_optimizer/output.json +++ b/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_optimizer_ir/output.json @@ -5,7 +5,7 @@ "formattedMessage": "Optimization is not yet supported with ethdebug.", "message": "Optimization is not yet supported with ethdebug.", "severity": "error", - "type": "FatalError" + "type": "UnimplementedFeatureError" } ] } diff --git a/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_optimizer_iroptimized/input.json b/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_optimizer_iroptimized/input.json new file mode 100644 index 000000000000..ad74649f5d1d --- /dev/null +++ b/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_optimizer_iroptimized/input.json @@ -0,0 +1,26 @@ +{ + "language": "Solidity", + "sources": { + "a.sol": { + "content": "//SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract A1 { function a(uint x) public pure { assert(x > 0); } } contract A2 { function a(uint x) public pure { assert(x > 0); } }" + }, + "b.sol": { + "content": "//SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract A1 { function b(uint x) public pure { assert(x > 0); } } contract B2 { function b(uint x) public pure { assert(x > 0); } }" + } + }, + "settings": { + "viaIR": true, + "optimizer": { + "enabled": true + }, + "outputSelection": { + "*": { + "*": [ + "evm.bytecode.ethdebug", + "evm.deployedBytecode.ethdebug", + "irOptimized" + ] + } + } + } +} diff --git a/test/cmdlineTests/standard_yul_ethdebug_irOptimized/output.json b/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_optimizer_iroptimized/output.json similarity index 85% rename from test/cmdlineTests/standard_yul_ethdebug_irOptimized/output.json rename to test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_optimizer_iroptimized/output.json index 3ed2f577c7aa..44867c7a75eb 100644 --- a/test/cmdlineTests/standard_yul_ethdebug_irOptimized/output.json +++ b/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_optimizer_iroptimized/output.json @@ -5,7 +5,7 @@ "formattedMessage": "Optimization is not yet supported with ethdebug.", "message": "Optimization is not yet supported with ethdebug.", "severity": "error", - "type": "FatalError" + "type": "UnimplementedFeatureError" } ] } diff --git a/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_ir/input.json b/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_ir/input.json new file mode 100644 index 000000000000..35c8f940e82d --- /dev/null +++ b/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_ir/input.json @@ -0,0 +1,25 @@ +{ + "language": "Solidity", + "sources": { + "a.sol": { + "content": "//SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract A1 { function a(uint x) public pure { assert(x > 0); } } contract A2 { function a(uint x) public pure { assert(x > 0); } }" + }, + "b.sol": { + "content": "//SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract A1 { function b(uint x) public pure { assert(x > 0); } } contract B2 { function b(uint x) public pure { assert(x > 0); } }" + } + }, + "settings": { + "viaIR": true, + "optimizer": { + "enabled": false + }, + "outputSelection": { + "*": { + "*": [ + "evm.bytecode.ethdebug", + "ir" + ] + } + } + } +} diff --git a/test/cmdlineTests/standard_output_selection_ethdebug_bytecode/output.json b/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_ir/output.json similarity index 100% rename from test/cmdlineTests/standard_output_selection_ethdebug_bytecode/output.json rename to test/cmdlineTests/standard_output_selection_ethdebug_bytecode_ir/output.json diff --git a/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_iroptimized/input.json b/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_iroptimized/input.json new file mode 100644 index 000000000000..e4681967f7db --- /dev/null +++ b/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_iroptimized/input.json @@ -0,0 +1,25 @@ +{ + "language": "Solidity", + "sources": { + "a.sol": { + "content": "//SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract A1 { function a(uint x) public pure { assert(x > 0); } } contract A2 { function a(uint x) public pure { assert(x > 0); } }" + }, + "b.sol": { + "content": "//SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract A1 { function b(uint x) public pure { assert(x > 0); } } contract B2 { function b(uint x) public pure { assert(x > 0); } }" + } + }, + "settings": { + "viaIR": true, + "optimizer": { + "enabled": false + }, + "outputSelection": { + "*": { + "*": [ + "evm.bytecode.ethdebug", + "irOptimized" + ] + } + } + } +} diff --git a/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_iroptimized/output.json b/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_iroptimized/output.json new file mode 100644 index 000000000000..d7284ab6405e --- /dev/null +++ b/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_iroptimized/output.json @@ -0,0 +1,510 @@ +{ + "contracts": { + "a.sol": { + "A1": { + "evm": { + "bytecode": { + "ethdebug": {} + } + }, + "irOptimized": "/// ethdebug: enabled +/// @use-src 0:\"a.sol\" +object \"A1_14\" { + code { + { + /// @src 0:58:123 \"contract A1 { function a(uint x) public pure { assert(x > 0); } }\" + mstore(64, memoryguard(0x80)) + if callvalue() + { + revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() + } + let _1 := allocate_unbounded() + codecopy(_1, dataoffset(\"A1_14_deployed\"), datasize(\"A1_14_deployed\")) + return(_1, datasize(\"A1_14_deployed\")) + } + function allocate_unbounded() -> memPtr + { memPtr := mload(64) } + function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() + { revert(0, 0) } + } + /// @use-src 0:\"a.sol\" + object \"A1_14_deployed\" { + code { + { + /// @src 0:58:123 \"contract A1 { function a(uint x) public pure { assert(x > 0); } }\" + mstore(64, memoryguard(0x80)) + if iszero(lt(calldatasize(), 4)) + { + let selector := shift_right_unsigned(calldataload(0)) + switch selector + case 0xf0fdf834 { external_fun_a() } + default { } + } + revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() + } + function shift_right_unsigned(value) -> newValue + { newValue := shr(224, value) } + function allocate_unbounded() -> memPtr + { memPtr := mload(64) } + function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() + { revert(0, 0) } + function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() + { revert(0, 0) } + function cleanup_uint256(value) -> cleaned + { cleaned := value } + function validator_revert_uint256(value) + { + if iszero(eq(value, cleanup_uint256(value))) { revert(0, 0) } + } + function abi_decode_uint256(offset, end) -> value + { + value := calldataload(offset) + validator_revert_uint256(value) + } + function abi_decode_tuple_uint256(headStart, dataEnd) -> value0 + { + if slt(sub(dataEnd, headStart), 32) + { + revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() + } + let offset := 0 + value0 := abi_decode_uint256(add(headStart, offset), dataEnd) + } + function abi_encode_tuple(headStart) -> tail + { tail := add(headStart, 0) } + function external_fun_a() + { + if callvalue() + { + revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() + } + let param := abi_decode_tuple_uint256(4, calldatasize()) + fun_a(param) + let memPos := allocate_unbounded() + let memEnd := abi_encode_tuple(memPos) + return(memPos, sub(memEnd, memPos)) + } + function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() + { revert(0, 0) } + function cleanup_rational_by(value) -> cleaned + { cleaned := value } + function identity(value) -> ret + { ret := value } + function convert_rational_by_to_uint256(value) -> converted + { + converted := cleanup_uint256(identity(cleanup_rational_by(value))) + } + function panic_error_0x01() + { + mstore(0, shl(224, 0x4e487b71)) + mstore(4, 0x01) + revert(0, 0x24) + } + function assert_helper(condition) + { + if iszero(condition) { panic_error_0x01() } + } + /// @ast-id 13 @src 0:72:121 \"function a(uint x) public pure { assert(x > 0); }\" + function fun_a(var_x) + { + /// @src 0:112:113 \"x\" + let _1 := var_x + let expr := _1 + /// @src 0:116:117 \"0\" + let expr_1 := 0x00 + /// @src 0:112:117 \"x > 0\" + let expr_2 := gt(cleanup_uint256(expr), convert_rational_by_to_uint256(expr_1)) + /// @src 0:105:118 \"assert(x > 0)\" + assert_helper(expr_2) + } + } + data \".metadata\" hex\"\" + } +} +" + }, + "A2": { + "evm": { + "bytecode": { + "ethdebug": {} + } + }, + "irOptimized": "/// ethdebug: enabled +/// @use-src 0:\"a.sol\" +object \"A2_27\" { + code { + { + /// @src 0:124:189 \"contract A2 { function a(uint x) public pure { assert(x > 0); } }\" + mstore(64, memoryguard(0x80)) + if callvalue() + { + revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() + } + let _1 := allocate_unbounded() + codecopy(_1, dataoffset(\"A2_27_deployed\"), datasize(\"A2_27_deployed\")) + return(_1, datasize(\"A2_27_deployed\")) + } + function allocate_unbounded() -> memPtr + { memPtr := mload(64) } + function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() + { revert(0, 0) } + } + /// @use-src 0:\"a.sol\" + object \"A2_27_deployed\" { + code { + { + /// @src 0:124:189 \"contract A2 { function a(uint x) public pure { assert(x > 0); } }\" + mstore(64, memoryguard(0x80)) + if iszero(lt(calldatasize(), 4)) + { + let selector := shift_right_unsigned(calldataload(0)) + switch selector + case 0xf0fdf834 { external_fun_a() } + default { } + } + revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() + } + function shift_right_unsigned(value) -> newValue + { newValue := shr(224, value) } + function allocate_unbounded() -> memPtr + { memPtr := mload(64) } + function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() + { revert(0, 0) } + function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() + { revert(0, 0) } + function cleanup_uint256(value) -> cleaned + { cleaned := value } + function validator_revert_uint256(value) + { + if iszero(eq(value, cleanup_uint256(value))) { revert(0, 0) } + } + function abi_decode_uint256(offset, end) -> value + { + value := calldataload(offset) + validator_revert_uint256(value) + } + function abi_decode_tuple_uint256(headStart, dataEnd) -> value0 + { + if slt(sub(dataEnd, headStart), 32) + { + revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() + } + let offset := 0 + value0 := abi_decode_uint256(add(headStart, offset), dataEnd) + } + function abi_encode_tuple(headStart) -> tail + { tail := add(headStart, 0) } + function external_fun_a() + { + if callvalue() + { + revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() + } + let param := abi_decode_tuple_uint256(4, calldatasize()) + fun_a(param) + let memPos := allocate_unbounded() + let memEnd := abi_encode_tuple(memPos) + return(memPos, sub(memEnd, memPos)) + } + function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() + { revert(0, 0) } + function cleanup_rational_by(value) -> cleaned + { cleaned := value } + function identity(value) -> ret + { ret := value } + function convert_rational_by_to_uint256(value) -> converted + { + converted := cleanup_uint256(identity(cleanup_rational_by(value))) + } + function panic_error_0x01() + { + mstore(0, shl(224, 0x4e487b71)) + mstore(4, 0x01) + revert(0, 0x24) + } + function assert_helper(condition) + { + if iszero(condition) { panic_error_0x01() } + } + /// @ast-id 26 @src 0:138:187 \"function a(uint x) public pure { assert(x > 0); }\" + function fun_a(var_x) + { + /// @src 0:178:179 \"x\" + let _1 := var_x + let expr := _1 + /// @src 0:182:183 \"0\" + let expr_1 := 0x00 + /// @src 0:178:183 \"x > 0\" + let expr_2 := gt(cleanup_uint256(expr), convert_rational_by_to_uint256(expr_1)) + /// @src 0:171:184 \"assert(x > 0)\" + assert_helper(expr_2) + } + } + data \".metadata\" hex\"\" + } +} +" + } + }, + "b.sol": { + "A1": { + "evm": { + "bytecode": { + "ethdebug": {} + } + }, + "irOptimized": "/// ethdebug: enabled +/// @use-src 1:\"b.sol\" +object \"A1_42\" { + code { + { + /// @src 1:58:123 \"contract A1 { function b(uint x) public pure { assert(x > 0); } }\" + mstore(64, memoryguard(0x80)) + if callvalue() + { + revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() + } + let _1 := allocate_unbounded() + codecopy(_1, dataoffset(\"A1_42_deployed\"), datasize(\"A1_42_deployed\")) + return(_1, datasize(\"A1_42_deployed\")) + } + function allocate_unbounded() -> memPtr + { memPtr := mload(64) } + function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() + { revert(0, 0) } + } + /// @use-src 1:\"b.sol\" + object \"A1_42_deployed\" { + code { + { + /// @src 1:58:123 \"contract A1 { function b(uint x) public pure { assert(x > 0); } }\" + mstore(64, memoryguard(0x80)) + if iszero(lt(calldatasize(), 4)) + { + let selector := shift_right_unsigned(calldataload(0)) + switch selector + case 0xcd580ff3 { external_fun_b() } + default { } + } + revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() + } + function shift_right_unsigned(value) -> newValue + { newValue := shr(224, value) } + function allocate_unbounded() -> memPtr + { memPtr := mload(64) } + function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() + { revert(0, 0) } + function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() + { revert(0, 0) } + function cleanup_uint256(value) -> cleaned + { cleaned := value } + function validator_revert_uint256(value) + { + if iszero(eq(value, cleanup_uint256(value))) { revert(0, 0) } + } + function abi_decode_uint256(offset, end) -> value + { + value := calldataload(offset) + validator_revert_uint256(value) + } + function abi_decode_tuple_uint256(headStart, dataEnd) -> value0 + { + if slt(sub(dataEnd, headStart), 32) + { + revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() + } + let offset := 0 + value0 := abi_decode_uint256(add(headStart, offset), dataEnd) + } + function abi_encode_tuple(headStart) -> tail + { tail := add(headStart, 0) } + function external_fun_b() + { + if callvalue() + { + revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() + } + let param := abi_decode_tuple_uint256(4, calldatasize()) + fun_b(param) + let memPos := allocate_unbounded() + let memEnd := abi_encode_tuple(memPos) + return(memPos, sub(memEnd, memPos)) + } + function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() + { revert(0, 0) } + function cleanup_rational_by(value) -> cleaned + { cleaned := value } + function identity(value) -> ret + { ret := value } + function convert_rational_by_to_uint256(value) -> converted + { + converted := cleanup_uint256(identity(cleanup_rational_by(value))) + } + function panic_error_0x01() + { + mstore(0, shl(224, 0x4e487b71)) + mstore(4, 0x01) + revert(0, 0x24) + } + function assert_helper(condition) + { + if iszero(condition) { panic_error_0x01() } + } + /// @ast-id 41 @src 1:72:121 \"function b(uint x) public pure { assert(x > 0); }\" + function fun_b(var_x) + { + /// @src 1:112:113 \"x\" + let _1 := var_x + let expr := _1 + /// @src 1:116:117 \"0\" + let expr_1 := 0x00 + /// @src 1:112:117 \"x > 0\" + let expr_2 := gt(cleanup_uint256(expr), convert_rational_by_to_uint256(expr_1)) + /// @src 1:105:118 \"assert(x > 0)\" + assert_helper(expr_2) + } + } + data \".metadata\" hex\"\" + } +} +" + }, + "B2": { + "evm": { + "bytecode": { + "ethdebug": {} + } + }, + "irOptimized": "/// ethdebug: enabled +/// @use-src 1:\"b.sol\" +object \"B2_55\" { + code { + { + /// @src 1:124:189 \"contract B2 { function b(uint x) public pure { assert(x > 0); } }\" + mstore(64, memoryguard(0x80)) + if callvalue() + { + revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() + } + let _1 := allocate_unbounded() + codecopy(_1, dataoffset(\"B2_55_deployed\"), datasize(\"B2_55_deployed\")) + return(_1, datasize(\"B2_55_deployed\")) + } + function allocate_unbounded() -> memPtr + { memPtr := mload(64) } + function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() + { revert(0, 0) } + } + /// @use-src 1:\"b.sol\" + object \"B2_55_deployed\" { + code { + { + /// @src 1:124:189 \"contract B2 { function b(uint x) public pure { assert(x > 0); } }\" + mstore(64, memoryguard(0x80)) + if iszero(lt(calldatasize(), 4)) + { + let selector := shift_right_unsigned(calldataload(0)) + switch selector + case 0xcd580ff3 { external_fun_b() } + default { } + } + revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() + } + function shift_right_unsigned(value) -> newValue + { newValue := shr(224, value) } + function allocate_unbounded() -> memPtr + { memPtr := mload(64) } + function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() + { revert(0, 0) } + function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() + { revert(0, 0) } + function cleanup_uint256(value) -> cleaned + { cleaned := value } + function validator_revert_uint256(value) + { + if iszero(eq(value, cleanup_uint256(value))) { revert(0, 0) } + } + function abi_decode_uint256(offset, end) -> value + { + value := calldataload(offset) + validator_revert_uint256(value) + } + function abi_decode_tuple_uint256(headStart, dataEnd) -> value0 + { + if slt(sub(dataEnd, headStart), 32) + { + revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() + } + let offset := 0 + value0 := abi_decode_uint256(add(headStart, offset), dataEnd) + } + function abi_encode_tuple(headStart) -> tail + { tail := add(headStart, 0) } + function external_fun_b() + { + if callvalue() + { + revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() + } + let param := abi_decode_tuple_uint256(4, calldatasize()) + fun_b(param) + let memPos := allocate_unbounded() + let memEnd := abi_encode_tuple(memPos) + return(memPos, sub(memEnd, memPos)) + } + function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() + { revert(0, 0) } + function cleanup_rational_by(value) -> cleaned + { cleaned := value } + function identity(value) -> ret + { ret := value } + function convert_rational_by_to_uint256(value) -> converted + { + converted := cleanup_uint256(identity(cleanup_rational_by(value))) + } + function panic_error_0x01() + { + mstore(0, shl(224, 0x4e487b71)) + mstore(4, 0x01) + revert(0, 0x24) + } + function assert_helper(condition) + { + if iszero(condition) { panic_error_0x01() } + } + /// @ast-id 54 @src 1:138:187 \"function b(uint x) public pure { assert(x > 0); }\" + function fun_b(var_x) + { + /// @src 1:178:179 \"x\" + let _1 := var_x + let expr := _1 + /// @src 1:182:183 \"0\" + let expr_1 := 0x00 + /// @src 1:178:183 \"x > 0\" + let expr_2 := gt(cleanup_uint256(expr), convert_rational_by_to_uint256(expr_1)) + /// @src 1:171:184 \"assert(x > 0)\" + assert_helper(expr_2) + } + } + data \".metadata\" hex\"\" + } +} +" + } + } + }, + "ethdebug": { + "sources": [ + "a.sol", + "b.sol" + ] + }, + "sources": { + "a.sol": { + "id": 0 + }, + "b.sol": { + "id": 1 + } + } +} diff --git a/test/cmdlineTests/standard_output_selection_ethdebug_deployedbytecode/input.json b/test/cmdlineTests/standard_output_selection_ethdebug_deployedbytecode/input.json deleted file mode 100644 index f8e3ee312e6b..000000000000 --- a/test/cmdlineTests/standard_output_selection_ethdebug_deployedbytecode/input.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "language": "Solidity", - "sources": { - "a.sol": { - "content": "//SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract A1 { function a(uint x) public pure { assert(x > 0); } } contract A2 { function a(uint x) public pure { assert(x > 0); } }" - }, - "b.sol": { - "content": "//SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract A1 { function b(uint x) public pure { assert(x > 0); } } contract B2 { function b(uint x) public pure { assert(x > 0); } }" - } - }, - "settings": { - "viaIR": true, - "optimizer": { - "enabled": false - }, - "outputSelection": { - "*": { - "*": [ - "evm.deployedBytecode.ethdebug", "ir" - ] - } - } - } -} diff --git a/test/cmdlineTests/standard_output_selection_ethdebug_deployedbytecode_ir/input.json b/test/cmdlineTests/standard_output_selection_ethdebug_deployedbytecode_ir/input.json new file mode 100644 index 000000000000..6239a7275e4d --- /dev/null +++ b/test/cmdlineTests/standard_output_selection_ethdebug_deployedbytecode_ir/input.json @@ -0,0 +1,25 @@ +{ + "language": "Solidity", + "sources": { + "a.sol": { + "content": "//SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract A1 { function a(uint x) public pure { assert(x > 0); } } contract A2 { function a(uint x) public pure { assert(x > 0); } }" + }, + "b.sol": { + "content": "//SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract A1 { function b(uint x) public pure { assert(x > 0); } } contract B2 { function b(uint x) public pure { assert(x > 0); } }" + } + }, + "settings": { + "viaIR": true, + "optimizer": { + "enabled": false + }, + "outputSelection": { + "*": { + "*": [ + "evm.deployedBytecode.ethdebug", + "ir" + ] + } + } + } +} diff --git a/test/cmdlineTests/standard_output_selection_ethdebug_deployedbytecode/output.json b/test/cmdlineTests/standard_output_selection_ethdebug_deployedbytecode_ir/output.json similarity index 100% rename from test/cmdlineTests/standard_output_selection_ethdebug_deployedbytecode/output.json rename to test/cmdlineTests/standard_output_selection_ethdebug_deployedbytecode_ir/output.json diff --git a/test/cmdlineTests/standard_output_selection_ethdebug_deployedbytecode_iroptimized/input.json b/test/cmdlineTests/standard_output_selection_ethdebug_deployedbytecode_iroptimized/input.json new file mode 100644 index 000000000000..fdb6c95b813e --- /dev/null +++ b/test/cmdlineTests/standard_output_selection_ethdebug_deployedbytecode_iroptimized/input.json @@ -0,0 +1,25 @@ +{ + "language": "Solidity", + "sources": { + "a.sol": { + "content": "//SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract A1 { function a(uint x) public pure { assert(x > 0); } } contract A2 { function a(uint x) public pure { assert(x > 0); } }" + }, + "b.sol": { + "content": "//SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract A1 { function b(uint x) public pure { assert(x > 0); } } contract B2 { function b(uint x) public pure { assert(x > 0); } }" + } + }, + "settings": { + "viaIR": true, + "optimizer": { + "enabled": false + }, + "outputSelection": { + "*": { + "*": [ + "evm.deployedBytecode.ethdebug", + "irOptimized" + ] + } + } + } +} diff --git a/test/cmdlineTests/standard_output_selection_ethdebug_deployedbytecode_iroptimized/output.json b/test/cmdlineTests/standard_output_selection_ethdebug_deployedbytecode_iroptimized/output.json new file mode 100644 index 000000000000..dce2a276e46f --- /dev/null +++ b/test/cmdlineTests/standard_output_selection_ethdebug_deployedbytecode_iroptimized/output.json @@ -0,0 +1,510 @@ +{ + "contracts": { + "a.sol": { + "A1": { + "evm": { + "deployedBytecode": { + "ethdebug": {} + } + }, + "irOptimized": "/// ethdebug: enabled +/// @use-src 0:\"a.sol\" +object \"A1_14\" { + code { + { + /// @src 0:58:123 \"contract A1 { function a(uint x) public pure { assert(x > 0); } }\" + mstore(64, memoryguard(0x80)) + if callvalue() + { + revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() + } + let _1 := allocate_unbounded() + codecopy(_1, dataoffset(\"A1_14_deployed\"), datasize(\"A1_14_deployed\")) + return(_1, datasize(\"A1_14_deployed\")) + } + function allocate_unbounded() -> memPtr + { memPtr := mload(64) } + function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() + { revert(0, 0) } + } + /// @use-src 0:\"a.sol\" + object \"A1_14_deployed\" { + code { + { + /// @src 0:58:123 \"contract A1 { function a(uint x) public pure { assert(x > 0); } }\" + mstore(64, memoryguard(0x80)) + if iszero(lt(calldatasize(), 4)) + { + let selector := shift_right_unsigned(calldataload(0)) + switch selector + case 0xf0fdf834 { external_fun_a() } + default { } + } + revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() + } + function shift_right_unsigned(value) -> newValue + { newValue := shr(224, value) } + function allocate_unbounded() -> memPtr + { memPtr := mload(64) } + function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() + { revert(0, 0) } + function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() + { revert(0, 0) } + function cleanup_uint256(value) -> cleaned + { cleaned := value } + function validator_revert_uint256(value) + { + if iszero(eq(value, cleanup_uint256(value))) { revert(0, 0) } + } + function abi_decode_uint256(offset, end) -> value + { + value := calldataload(offset) + validator_revert_uint256(value) + } + function abi_decode_tuple_uint256(headStart, dataEnd) -> value0 + { + if slt(sub(dataEnd, headStart), 32) + { + revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() + } + let offset := 0 + value0 := abi_decode_uint256(add(headStart, offset), dataEnd) + } + function abi_encode_tuple(headStart) -> tail + { tail := add(headStart, 0) } + function external_fun_a() + { + if callvalue() + { + revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() + } + let param := abi_decode_tuple_uint256(4, calldatasize()) + fun_a(param) + let memPos := allocate_unbounded() + let memEnd := abi_encode_tuple(memPos) + return(memPos, sub(memEnd, memPos)) + } + function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() + { revert(0, 0) } + function cleanup_rational_by(value) -> cleaned + { cleaned := value } + function identity(value) -> ret + { ret := value } + function convert_rational_by_to_uint256(value) -> converted + { + converted := cleanup_uint256(identity(cleanup_rational_by(value))) + } + function panic_error_0x01() + { + mstore(0, shl(224, 0x4e487b71)) + mstore(4, 0x01) + revert(0, 0x24) + } + function assert_helper(condition) + { + if iszero(condition) { panic_error_0x01() } + } + /// @ast-id 13 @src 0:72:121 \"function a(uint x) public pure { assert(x > 0); }\" + function fun_a(var_x) + { + /// @src 0:112:113 \"x\" + let _1 := var_x + let expr := _1 + /// @src 0:116:117 \"0\" + let expr_1 := 0x00 + /// @src 0:112:117 \"x > 0\" + let expr_2 := gt(cleanup_uint256(expr), convert_rational_by_to_uint256(expr_1)) + /// @src 0:105:118 \"assert(x > 0)\" + assert_helper(expr_2) + } + } + data \".metadata\" hex\"\" + } +} +" + }, + "A2": { + "evm": { + "deployedBytecode": { + "ethdebug": {} + } + }, + "irOptimized": "/// ethdebug: enabled +/// @use-src 0:\"a.sol\" +object \"A2_27\" { + code { + { + /// @src 0:124:189 \"contract A2 { function a(uint x) public pure { assert(x > 0); } }\" + mstore(64, memoryguard(0x80)) + if callvalue() + { + revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() + } + let _1 := allocate_unbounded() + codecopy(_1, dataoffset(\"A2_27_deployed\"), datasize(\"A2_27_deployed\")) + return(_1, datasize(\"A2_27_deployed\")) + } + function allocate_unbounded() -> memPtr + { memPtr := mload(64) } + function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() + { revert(0, 0) } + } + /// @use-src 0:\"a.sol\" + object \"A2_27_deployed\" { + code { + { + /// @src 0:124:189 \"contract A2 { function a(uint x) public pure { assert(x > 0); } }\" + mstore(64, memoryguard(0x80)) + if iszero(lt(calldatasize(), 4)) + { + let selector := shift_right_unsigned(calldataload(0)) + switch selector + case 0xf0fdf834 { external_fun_a() } + default { } + } + revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() + } + function shift_right_unsigned(value) -> newValue + { newValue := shr(224, value) } + function allocate_unbounded() -> memPtr + { memPtr := mload(64) } + function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() + { revert(0, 0) } + function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() + { revert(0, 0) } + function cleanup_uint256(value) -> cleaned + { cleaned := value } + function validator_revert_uint256(value) + { + if iszero(eq(value, cleanup_uint256(value))) { revert(0, 0) } + } + function abi_decode_uint256(offset, end) -> value + { + value := calldataload(offset) + validator_revert_uint256(value) + } + function abi_decode_tuple_uint256(headStart, dataEnd) -> value0 + { + if slt(sub(dataEnd, headStart), 32) + { + revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() + } + let offset := 0 + value0 := abi_decode_uint256(add(headStart, offset), dataEnd) + } + function abi_encode_tuple(headStart) -> tail + { tail := add(headStart, 0) } + function external_fun_a() + { + if callvalue() + { + revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() + } + let param := abi_decode_tuple_uint256(4, calldatasize()) + fun_a(param) + let memPos := allocate_unbounded() + let memEnd := abi_encode_tuple(memPos) + return(memPos, sub(memEnd, memPos)) + } + function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() + { revert(0, 0) } + function cleanup_rational_by(value) -> cleaned + { cleaned := value } + function identity(value) -> ret + { ret := value } + function convert_rational_by_to_uint256(value) -> converted + { + converted := cleanup_uint256(identity(cleanup_rational_by(value))) + } + function panic_error_0x01() + { + mstore(0, shl(224, 0x4e487b71)) + mstore(4, 0x01) + revert(0, 0x24) + } + function assert_helper(condition) + { + if iszero(condition) { panic_error_0x01() } + } + /// @ast-id 26 @src 0:138:187 \"function a(uint x) public pure { assert(x > 0); }\" + function fun_a(var_x) + { + /// @src 0:178:179 \"x\" + let _1 := var_x + let expr := _1 + /// @src 0:182:183 \"0\" + let expr_1 := 0x00 + /// @src 0:178:183 \"x > 0\" + let expr_2 := gt(cleanup_uint256(expr), convert_rational_by_to_uint256(expr_1)) + /// @src 0:171:184 \"assert(x > 0)\" + assert_helper(expr_2) + } + } + data \".metadata\" hex\"\" + } +} +" + } + }, + "b.sol": { + "A1": { + "evm": { + "deployedBytecode": { + "ethdebug": {} + } + }, + "irOptimized": "/// ethdebug: enabled +/// @use-src 1:\"b.sol\" +object \"A1_42\" { + code { + { + /// @src 1:58:123 \"contract A1 { function b(uint x) public pure { assert(x > 0); } }\" + mstore(64, memoryguard(0x80)) + if callvalue() + { + revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() + } + let _1 := allocate_unbounded() + codecopy(_1, dataoffset(\"A1_42_deployed\"), datasize(\"A1_42_deployed\")) + return(_1, datasize(\"A1_42_deployed\")) + } + function allocate_unbounded() -> memPtr + { memPtr := mload(64) } + function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() + { revert(0, 0) } + } + /// @use-src 1:\"b.sol\" + object \"A1_42_deployed\" { + code { + { + /// @src 1:58:123 \"contract A1 { function b(uint x) public pure { assert(x > 0); } }\" + mstore(64, memoryguard(0x80)) + if iszero(lt(calldatasize(), 4)) + { + let selector := shift_right_unsigned(calldataload(0)) + switch selector + case 0xcd580ff3 { external_fun_b() } + default { } + } + revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() + } + function shift_right_unsigned(value) -> newValue + { newValue := shr(224, value) } + function allocate_unbounded() -> memPtr + { memPtr := mload(64) } + function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() + { revert(0, 0) } + function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() + { revert(0, 0) } + function cleanup_uint256(value) -> cleaned + { cleaned := value } + function validator_revert_uint256(value) + { + if iszero(eq(value, cleanup_uint256(value))) { revert(0, 0) } + } + function abi_decode_uint256(offset, end) -> value + { + value := calldataload(offset) + validator_revert_uint256(value) + } + function abi_decode_tuple_uint256(headStart, dataEnd) -> value0 + { + if slt(sub(dataEnd, headStart), 32) + { + revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() + } + let offset := 0 + value0 := abi_decode_uint256(add(headStart, offset), dataEnd) + } + function abi_encode_tuple(headStart) -> tail + { tail := add(headStart, 0) } + function external_fun_b() + { + if callvalue() + { + revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() + } + let param := abi_decode_tuple_uint256(4, calldatasize()) + fun_b(param) + let memPos := allocate_unbounded() + let memEnd := abi_encode_tuple(memPos) + return(memPos, sub(memEnd, memPos)) + } + function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() + { revert(0, 0) } + function cleanup_rational_by(value) -> cleaned + { cleaned := value } + function identity(value) -> ret + { ret := value } + function convert_rational_by_to_uint256(value) -> converted + { + converted := cleanup_uint256(identity(cleanup_rational_by(value))) + } + function panic_error_0x01() + { + mstore(0, shl(224, 0x4e487b71)) + mstore(4, 0x01) + revert(0, 0x24) + } + function assert_helper(condition) + { + if iszero(condition) { panic_error_0x01() } + } + /// @ast-id 41 @src 1:72:121 \"function b(uint x) public pure { assert(x > 0); }\" + function fun_b(var_x) + { + /// @src 1:112:113 \"x\" + let _1 := var_x + let expr := _1 + /// @src 1:116:117 \"0\" + let expr_1 := 0x00 + /// @src 1:112:117 \"x > 0\" + let expr_2 := gt(cleanup_uint256(expr), convert_rational_by_to_uint256(expr_1)) + /// @src 1:105:118 \"assert(x > 0)\" + assert_helper(expr_2) + } + } + data \".metadata\" hex\"\" + } +} +" + }, + "B2": { + "evm": { + "deployedBytecode": { + "ethdebug": {} + } + }, + "irOptimized": "/// ethdebug: enabled +/// @use-src 1:\"b.sol\" +object \"B2_55\" { + code { + { + /// @src 1:124:189 \"contract B2 { function b(uint x) public pure { assert(x > 0); } }\" + mstore(64, memoryguard(0x80)) + if callvalue() + { + revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() + } + let _1 := allocate_unbounded() + codecopy(_1, dataoffset(\"B2_55_deployed\"), datasize(\"B2_55_deployed\")) + return(_1, datasize(\"B2_55_deployed\")) + } + function allocate_unbounded() -> memPtr + { memPtr := mload(64) } + function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() + { revert(0, 0) } + } + /// @use-src 1:\"b.sol\" + object \"B2_55_deployed\" { + code { + { + /// @src 1:124:189 \"contract B2 { function b(uint x) public pure { assert(x > 0); } }\" + mstore(64, memoryguard(0x80)) + if iszero(lt(calldatasize(), 4)) + { + let selector := shift_right_unsigned(calldataload(0)) + switch selector + case 0xcd580ff3 { external_fun_b() } + default { } + } + revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() + } + function shift_right_unsigned(value) -> newValue + { newValue := shr(224, value) } + function allocate_unbounded() -> memPtr + { memPtr := mload(64) } + function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() + { revert(0, 0) } + function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() + { revert(0, 0) } + function cleanup_uint256(value) -> cleaned + { cleaned := value } + function validator_revert_uint256(value) + { + if iszero(eq(value, cleanup_uint256(value))) { revert(0, 0) } + } + function abi_decode_uint256(offset, end) -> value + { + value := calldataload(offset) + validator_revert_uint256(value) + } + function abi_decode_tuple_uint256(headStart, dataEnd) -> value0 + { + if slt(sub(dataEnd, headStart), 32) + { + revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() + } + let offset := 0 + value0 := abi_decode_uint256(add(headStart, offset), dataEnd) + } + function abi_encode_tuple(headStart) -> tail + { tail := add(headStart, 0) } + function external_fun_b() + { + if callvalue() + { + revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() + } + let param := abi_decode_tuple_uint256(4, calldatasize()) + fun_b(param) + let memPos := allocate_unbounded() + let memEnd := abi_encode_tuple(memPos) + return(memPos, sub(memEnd, memPos)) + } + function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() + { revert(0, 0) } + function cleanup_rational_by(value) -> cleaned + { cleaned := value } + function identity(value) -> ret + { ret := value } + function convert_rational_by_to_uint256(value) -> converted + { + converted := cleanup_uint256(identity(cleanup_rational_by(value))) + } + function panic_error_0x01() + { + mstore(0, shl(224, 0x4e487b71)) + mstore(4, 0x01) + revert(0, 0x24) + } + function assert_helper(condition) + { + if iszero(condition) { panic_error_0x01() } + } + /// @ast-id 54 @src 1:138:187 \"function b(uint x) public pure { assert(x > 0); }\" + function fun_b(var_x) + { + /// @src 1:178:179 \"x\" + let _1 := var_x + let expr := _1 + /// @src 1:182:183 \"0\" + let expr_1 := 0x00 + /// @src 1:178:183 \"x > 0\" + let expr_2 := gt(cleanup_uint256(expr), convert_rational_by_to_uint256(expr_1)) + /// @src 1:171:184 \"assert(x > 0)\" + assert_helper(expr_2) + } + } + data \".metadata\" hex\"\" + } +} +" + } + } + }, + "ethdebug": { + "sources": [ + "a.sol", + "b.sol" + ] + }, + "sources": { + "a.sol": { + "id": 0 + }, + "b.sol": { + "id": 1 + } + } +} diff --git a/test/cmdlineTests/standard_output_selection_ethdebug_ir/input.json b/test/cmdlineTests/standard_output_selection_ethdebug_ir/input.json new file mode 100644 index 000000000000..5bc9d5467345 --- /dev/null +++ b/test/cmdlineTests/standard_output_selection_ethdebug_ir/input.json @@ -0,0 +1,22 @@ +{ + "language": "Solidity", + "sources": { + "a.sol": { + "content": "//SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract A1 { function a(uint x) public pure { assert(x > 0); } } contract A2 { function a(uint x) public pure { assert(x > 0); } }" + }, + "b.sol": { + "content": "//SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract A1 { function b(uint x) public pure { assert(x > 0); } } contract B2 { function b(uint x) public pure { assert(x > 0); } }" + } + }, + "settings": { + "viaIR": true, + "outputSelection": { + "*": { + "*": [ + "evm.bytecode.ethdebug", + "ir" + ] + } + } + } +} diff --git a/test/cmdlineTests/standard_output_selection_ethdebug_ir/output.json b/test/cmdlineTests/standard_output_selection_ethdebug_ir/output.json new file mode 100644 index 000000000000..fabb25ee6720 --- /dev/null +++ b/test/cmdlineTests/standard_output_selection_ethdebug_ir/output.json @@ -0,0 +1,730 @@ +{ + "contracts": { + "a.sol": { + "A1": { + "evm": { + "bytecode": { + "ethdebug": {} + } + }, + "ir": "/// ethdebug: enabled +/// @use-src 0:\"a.sol\" +object \"A1_14\" { + code { + /// @src 0:58:123 \"contract A1 { function a(uint x) public pure { assert(x > 0); } }\" + mstore(64, memoryguard(128)) + if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } + + constructor_A1_14() + + let _1 := allocate_unbounded() + codecopy(_1, dataoffset(\"A1_14_deployed\"), datasize(\"A1_14_deployed\")) + + return(_1, datasize(\"A1_14_deployed\")) + + function allocate_unbounded() -> memPtr { + memPtr := mload(64) + } + + function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() { + revert(0, 0) + } + + /// @src 0:58:123 \"contract A1 { function a(uint x) public pure { assert(x > 0); } }\" + function constructor_A1_14() { + + /// @src 0:58:123 \"contract A1 { function a(uint x) public pure { assert(x > 0); } }\" + + } + /// @src 0:58:123 \"contract A1 { function a(uint x) public pure { assert(x > 0); } }\" + + } + /// @use-src 0:\"a.sol\" + object \"A1_14_deployed\" { + code { + /// @src 0:58:123 \"contract A1 { function a(uint x) public pure { assert(x > 0); } }\" + mstore(64, memoryguard(128)) + + if iszero(lt(calldatasize(), 4)) + { + let selector := shift_right_224_unsigned(calldataload(0)) + switch selector + + case 0xf0fdf834 + { + // a(uint256) + + external_fun_a_13() + } + + default {} + } + + revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() + + function shift_right_224_unsigned(value) -> newValue { + newValue := + + shr(224, value) + + } + + function allocate_unbounded() -> memPtr { + memPtr := mload(64) + } + + function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() { + revert(0, 0) + } + + function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() { + revert(0, 0) + } + + function revert_error_c1322bf8034eace5e0b5c7295db60986aa89aae5e0ea0873e4689e076861a5db() { + revert(0, 0) + } + + function cleanup_t_uint256(value) -> cleaned { + cleaned := value + } + + function validator_revert_t_uint256(value) { + if iszero(eq(value, cleanup_t_uint256(value))) { revert(0, 0) } + } + + function abi_decode_t_uint256(offset, end) -> value { + value := calldataload(offset) + validator_revert_t_uint256(value) + } + + function abi_decode_tuple_t_uint256(headStart, dataEnd) -> value0 { + if slt(sub(dataEnd, headStart), 32) { revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() } + + { + + let offset := 0 + + value0 := abi_decode_t_uint256(add(headStart, offset), dataEnd) + } + + } + + function abi_encode_tuple__to__fromStack(headStart ) -> tail { + tail := add(headStart, 0) + + } + + function external_fun_a_13() { + + if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } + let param_0 := abi_decode_tuple_t_uint256(4, calldatasize()) + fun_a_13(param_0) + let memPos := allocate_unbounded() + let memEnd := abi_encode_tuple__to__fromStack(memPos ) + return(memPos, sub(memEnd, memPos)) + + } + + function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() { + revert(0, 0) + } + + function cleanup_t_rational_0_by_1(value) -> cleaned { + cleaned := value + } + + function identity(value) -> ret { + ret := value + } + + function convert_t_rational_0_by_1_to_t_uint256(value) -> converted { + converted := cleanup_t_uint256(identity(cleanup_t_rational_0_by_1(value))) + } + + function panic_error_0x01() { + mstore(0, 35408467139433450592217433187231851964531694900788300625387963629091585785856) + mstore(4, 0x01) + revert(0, 0x24) + } + + function assert_helper(condition) { + if iszero(condition) { panic_error_0x01() } + } + + /// @ast-id 13 + /// @src 0:72:121 \"function a(uint x) public pure { assert(x > 0); }\" + function fun_a_13(var_x_3) { + + /// @src 0:112:113 \"x\" + let _1 := var_x_3 + let expr_7 := _1 + /// @src 0:116:117 \"0\" + let expr_8 := 0x00 + /// @src 0:112:117 \"x > 0\" + let expr_9 := gt(cleanup_t_uint256(expr_7), convert_t_rational_0_by_1_to_t_uint256(expr_8)) + /// @src 0:105:118 \"assert(x > 0)\" + assert_helper(expr_9) + + } + /// @src 0:58:123 \"contract A1 { function a(uint x) public pure { assert(x > 0); } }\" + + } + + data \".metadata\" hex\"\" + } + +} + +" + }, + "A2": { + "evm": { + "bytecode": { + "ethdebug": {} + } + }, + "ir": "/// ethdebug: enabled +/// @use-src 0:\"a.sol\" +object \"A2_27\" { + code { + /// @src 0:124:189 \"contract A2 { function a(uint x) public pure { assert(x > 0); } }\" + mstore(64, memoryguard(128)) + if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } + + constructor_A2_27() + + let _1 := allocate_unbounded() + codecopy(_1, dataoffset(\"A2_27_deployed\"), datasize(\"A2_27_deployed\")) + + return(_1, datasize(\"A2_27_deployed\")) + + function allocate_unbounded() -> memPtr { + memPtr := mload(64) + } + + function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() { + revert(0, 0) + } + + /// @src 0:124:189 \"contract A2 { function a(uint x) public pure { assert(x > 0); } }\" + function constructor_A2_27() { + + /// @src 0:124:189 \"contract A2 { function a(uint x) public pure { assert(x > 0); } }\" + + } + /// @src 0:124:189 \"contract A2 { function a(uint x) public pure { assert(x > 0); } }\" + + } + /// @use-src 0:\"a.sol\" + object \"A2_27_deployed\" { + code { + /// @src 0:124:189 \"contract A2 { function a(uint x) public pure { assert(x > 0); } }\" + mstore(64, memoryguard(128)) + + if iszero(lt(calldatasize(), 4)) + { + let selector := shift_right_224_unsigned(calldataload(0)) + switch selector + + case 0xf0fdf834 + { + // a(uint256) + + external_fun_a_26() + } + + default {} + } + + revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() + + function shift_right_224_unsigned(value) -> newValue { + newValue := + + shr(224, value) + + } + + function allocate_unbounded() -> memPtr { + memPtr := mload(64) + } + + function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() { + revert(0, 0) + } + + function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() { + revert(0, 0) + } + + function revert_error_c1322bf8034eace5e0b5c7295db60986aa89aae5e0ea0873e4689e076861a5db() { + revert(0, 0) + } + + function cleanup_t_uint256(value) -> cleaned { + cleaned := value + } + + function validator_revert_t_uint256(value) { + if iszero(eq(value, cleanup_t_uint256(value))) { revert(0, 0) } + } + + function abi_decode_t_uint256(offset, end) -> value { + value := calldataload(offset) + validator_revert_t_uint256(value) + } + + function abi_decode_tuple_t_uint256(headStart, dataEnd) -> value0 { + if slt(sub(dataEnd, headStart), 32) { revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() } + + { + + let offset := 0 + + value0 := abi_decode_t_uint256(add(headStart, offset), dataEnd) + } + + } + + function abi_encode_tuple__to__fromStack(headStart ) -> tail { + tail := add(headStart, 0) + + } + + function external_fun_a_26() { + + if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } + let param_0 := abi_decode_tuple_t_uint256(4, calldatasize()) + fun_a_26(param_0) + let memPos := allocate_unbounded() + let memEnd := abi_encode_tuple__to__fromStack(memPos ) + return(memPos, sub(memEnd, memPos)) + + } + + function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() { + revert(0, 0) + } + + function cleanup_t_rational_0_by_1(value) -> cleaned { + cleaned := value + } + + function identity(value) -> ret { + ret := value + } + + function convert_t_rational_0_by_1_to_t_uint256(value) -> converted { + converted := cleanup_t_uint256(identity(cleanup_t_rational_0_by_1(value))) + } + + function panic_error_0x01() { + mstore(0, 35408467139433450592217433187231851964531694900788300625387963629091585785856) + mstore(4, 0x01) + revert(0, 0x24) + } + + function assert_helper(condition) { + if iszero(condition) { panic_error_0x01() } + } + + /// @ast-id 26 + /// @src 0:138:187 \"function a(uint x) public pure { assert(x > 0); }\" + function fun_a_26(var_x_16) { + + /// @src 0:178:179 \"x\" + let _1 := var_x_16 + let expr_20 := _1 + /// @src 0:182:183 \"0\" + let expr_21 := 0x00 + /// @src 0:178:183 \"x > 0\" + let expr_22 := gt(cleanup_t_uint256(expr_20), convert_t_rational_0_by_1_to_t_uint256(expr_21)) + /// @src 0:171:184 \"assert(x > 0)\" + assert_helper(expr_22) + + } + /// @src 0:124:189 \"contract A2 { function a(uint x) public pure { assert(x > 0); } }\" + + } + + data \".metadata\" hex\"\" + } + +} + +" + } + }, + "b.sol": { + "A1": { + "evm": { + "bytecode": { + "ethdebug": {} + } + }, + "ir": "/// ethdebug: enabled +/// @use-src 1:\"b.sol\" +object \"A1_42\" { + code { + /// @src 1:58:123 \"contract A1 { function b(uint x) public pure { assert(x > 0); } }\" + mstore(64, memoryguard(128)) + if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } + + constructor_A1_42() + + let _1 := allocate_unbounded() + codecopy(_1, dataoffset(\"A1_42_deployed\"), datasize(\"A1_42_deployed\")) + + return(_1, datasize(\"A1_42_deployed\")) + + function allocate_unbounded() -> memPtr { + memPtr := mload(64) + } + + function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() { + revert(0, 0) + } + + /// @src 1:58:123 \"contract A1 { function b(uint x) public pure { assert(x > 0); } }\" + function constructor_A1_42() { + + /// @src 1:58:123 \"contract A1 { function b(uint x) public pure { assert(x > 0); } }\" + + } + /// @src 1:58:123 \"contract A1 { function b(uint x) public pure { assert(x > 0); } }\" + + } + /// @use-src 1:\"b.sol\" + object \"A1_42_deployed\" { + code { + /// @src 1:58:123 \"contract A1 { function b(uint x) public pure { assert(x > 0); } }\" + mstore(64, memoryguard(128)) + + if iszero(lt(calldatasize(), 4)) + { + let selector := shift_right_224_unsigned(calldataload(0)) + switch selector + + case 0xcd580ff3 + { + // b(uint256) + + external_fun_b_41() + } + + default {} + } + + revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() + + function shift_right_224_unsigned(value) -> newValue { + newValue := + + shr(224, value) + + } + + function allocate_unbounded() -> memPtr { + memPtr := mload(64) + } + + function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() { + revert(0, 0) + } + + function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() { + revert(0, 0) + } + + function revert_error_c1322bf8034eace5e0b5c7295db60986aa89aae5e0ea0873e4689e076861a5db() { + revert(0, 0) + } + + function cleanup_t_uint256(value) -> cleaned { + cleaned := value + } + + function validator_revert_t_uint256(value) { + if iszero(eq(value, cleanup_t_uint256(value))) { revert(0, 0) } + } + + function abi_decode_t_uint256(offset, end) -> value { + value := calldataload(offset) + validator_revert_t_uint256(value) + } + + function abi_decode_tuple_t_uint256(headStart, dataEnd) -> value0 { + if slt(sub(dataEnd, headStart), 32) { revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() } + + { + + let offset := 0 + + value0 := abi_decode_t_uint256(add(headStart, offset), dataEnd) + } + + } + + function abi_encode_tuple__to__fromStack(headStart ) -> tail { + tail := add(headStart, 0) + + } + + function external_fun_b_41() { + + if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } + let param_0 := abi_decode_tuple_t_uint256(4, calldatasize()) + fun_b_41(param_0) + let memPos := allocate_unbounded() + let memEnd := abi_encode_tuple__to__fromStack(memPos ) + return(memPos, sub(memEnd, memPos)) + + } + + function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() { + revert(0, 0) + } + + function cleanup_t_rational_0_by_1(value) -> cleaned { + cleaned := value + } + + function identity(value) -> ret { + ret := value + } + + function convert_t_rational_0_by_1_to_t_uint256(value) -> converted { + converted := cleanup_t_uint256(identity(cleanup_t_rational_0_by_1(value))) + } + + function panic_error_0x01() { + mstore(0, 35408467139433450592217433187231851964531694900788300625387963629091585785856) + mstore(4, 0x01) + revert(0, 0x24) + } + + function assert_helper(condition) { + if iszero(condition) { panic_error_0x01() } + } + + /// @ast-id 41 + /// @src 1:72:121 \"function b(uint x) public pure { assert(x > 0); }\" + function fun_b_41(var_x_31) { + + /// @src 1:112:113 \"x\" + let _1 := var_x_31 + let expr_35 := _1 + /// @src 1:116:117 \"0\" + let expr_36 := 0x00 + /// @src 1:112:117 \"x > 0\" + let expr_37 := gt(cleanup_t_uint256(expr_35), convert_t_rational_0_by_1_to_t_uint256(expr_36)) + /// @src 1:105:118 \"assert(x > 0)\" + assert_helper(expr_37) + + } + /// @src 1:58:123 \"contract A1 { function b(uint x) public pure { assert(x > 0); } }\" + + } + + data \".metadata\" hex\"\" + } + +} + +" + }, + "B2": { + "evm": { + "bytecode": { + "ethdebug": {} + } + }, + "ir": "/// ethdebug: enabled +/// @use-src 1:\"b.sol\" +object \"B2_55\" { + code { + /// @src 1:124:189 \"contract B2 { function b(uint x) public pure { assert(x > 0); } }\" + mstore(64, memoryguard(128)) + if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } + + constructor_B2_55() + + let _1 := allocate_unbounded() + codecopy(_1, dataoffset(\"B2_55_deployed\"), datasize(\"B2_55_deployed\")) + + return(_1, datasize(\"B2_55_deployed\")) + + function allocate_unbounded() -> memPtr { + memPtr := mload(64) + } + + function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() { + revert(0, 0) + } + + /// @src 1:124:189 \"contract B2 { function b(uint x) public pure { assert(x > 0); } }\" + function constructor_B2_55() { + + /// @src 1:124:189 \"contract B2 { function b(uint x) public pure { assert(x > 0); } }\" + + } + /// @src 1:124:189 \"contract B2 { function b(uint x) public pure { assert(x > 0); } }\" + + } + /// @use-src 1:\"b.sol\" + object \"B2_55_deployed\" { + code { + /// @src 1:124:189 \"contract B2 { function b(uint x) public pure { assert(x > 0); } }\" + mstore(64, memoryguard(128)) + + if iszero(lt(calldatasize(), 4)) + { + let selector := shift_right_224_unsigned(calldataload(0)) + switch selector + + case 0xcd580ff3 + { + // b(uint256) + + external_fun_b_54() + } + + default {} + } + + revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() + + function shift_right_224_unsigned(value) -> newValue { + newValue := + + shr(224, value) + + } + + function allocate_unbounded() -> memPtr { + memPtr := mload(64) + } + + function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() { + revert(0, 0) + } + + function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() { + revert(0, 0) + } + + function revert_error_c1322bf8034eace5e0b5c7295db60986aa89aae5e0ea0873e4689e076861a5db() { + revert(0, 0) + } + + function cleanup_t_uint256(value) -> cleaned { + cleaned := value + } + + function validator_revert_t_uint256(value) { + if iszero(eq(value, cleanup_t_uint256(value))) { revert(0, 0) } + } + + function abi_decode_t_uint256(offset, end) -> value { + value := calldataload(offset) + validator_revert_t_uint256(value) + } + + function abi_decode_tuple_t_uint256(headStart, dataEnd) -> value0 { + if slt(sub(dataEnd, headStart), 32) { revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() } + + { + + let offset := 0 + + value0 := abi_decode_t_uint256(add(headStart, offset), dataEnd) + } + + } + + function abi_encode_tuple__to__fromStack(headStart ) -> tail { + tail := add(headStart, 0) + + } + + function external_fun_b_54() { + + if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } + let param_0 := abi_decode_tuple_t_uint256(4, calldatasize()) + fun_b_54(param_0) + let memPos := allocate_unbounded() + let memEnd := abi_encode_tuple__to__fromStack(memPos ) + return(memPos, sub(memEnd, memPos)) + + } + + function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() { + revert(0, 0) + } + + function cleanup_t_rational_0_by_1(value) -> cleaned { + cleaned := value + } + + function identity(value) -> ret { + ret := value + } + + function convert_t_rational_0_by_1_to_t_uint256(value) -> converted { + converted := cleanup_t_uint256(identity(cleanup_t_rational_0_by_1(value))) + } + + function panic_error_0x01() { + mstore(0, 35408467139433450592217433187231851964531694900788300625387963629091585785856) + mstore(4, 0x01) + revert(0, 0x24) + } + + function assert_helper(condition) { + if iszero(condition) { panic_error_0x01() } + } + + /// @ast-id 54 + /// @src 1:138:187 \"function b(uint x) public pure { assert(x > 0); }\" + function fun_b_54(var_x_44) { + + /// @src 1:178:179 \"x\" + let _1 := var_x_44 + let expr_48 := _1 + /// @src 1:182:183 \"0\" + let expr_49 := 0x00 + /// @src 1:178:183 \"x > 0\" + let expr_50 := gt(cleanup_t_uint256(expr_48), convert_t_rational_0_by_1_to_t_uint256(expr_49)) + /// @src 1:171:184 \"assert(x > 0)\" + assert_helper(expr_50) + + } + /// @src 1:124:189 \"contract B2 { function b(uint x) public pure { assert(x > 0); } }\" + + } + + data \".metadata\" hex\"\" + } + +} + +" + } + } + }, + "ethdebug": { + "sources": [ + "a.sol", + "b.sol" + ] + }, + "sources": { + "a.sol": { + "id": 0 + }, + "b.sol": { + "id": 1 + } + } +} diff --git a/test/cmdlineTests/standard_output_selection_ethdebug_irOptimized/input.json b/test/cmdlineTests/standard_output_selection_ethdebug_irOptimized/input.json deleted file mode 100644 index ab13b27ea6ea..000000000000 --- a/test/cmdlineTests/standard_output_selection_ethdebug_irOptimized/input.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "language": "Solidity", - "sources": { - "a.sol": { - "content": "//SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract A1 { function a(uint x) public pure { assert(x > 0); } } contract A2 { function a(uint x) public pure { assert(x > 0); } }" - }, - "b.sol": { - "content": "//SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract A1 { function b(uint x) public pure { assert(x > 0); } } contract B2 { function b(uint x) public pure { assert(x > 0); } }" - } - }, - "settings": { - "viaIR": true, - "outputSelection": { - "*": { - "*": [ - "evm.bytecode.ethdebug", "irOptimized" - ] - } - } - } -} diff --git a/test/cmdlineTests/standard_output_selection_ethdebug_iroptimized/input.json b/test/cmdlineTests/standard_output_selection_ethdebug_iroptimized/input.json new file mode 100644 index 000000000000..8952a241f6e7 --- /dev/null +++ b/test/cmdlineTests/standard_output_selection_ethdebug_iroptimized/input.json @@ -0,0 +1,22 @@ +{ + "language": "Solidity", + "sources": { + "a.sol": { + "content": "//SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract A1 { function a(uint x) public pure { assert(x > 0); } } contract A2 { function a(uint x) public pure { assert(x > 0); } }" + }, + "b.sol": { + "content": "//SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract A1 { function b(uint x) public pure { assert(x > 0); } } contract B2 { function b(uint x) public pure { assert(x > 0); } }" + } + }, + "settings": { + "viaIR": true, + "outputSelection": { + "*": { + "*": [ + "evm.bytecode.ethdebug", + "irOptimized" + ] + } + } + } +} diff --git a/test/cmdlineTests/standard_output_selection_ethdebug_iroptimized/output.json b/test/cmdlineTests/standard_output_selection_ethdebug_iroptimized/output.json new file mode 100644 index 000000000000..d7284ab6405e --- /dev/null +++ b/test/cmdlineTests/standard_output_selection_ethdebug_iroptimized/output.json @@ -0,0 +1,510 @@ +{ + "contracts": { + "a.sol": { + "A1": { + "evm": { + "bytecode": { + "ethdebug": {} + } + }, + "irOptimized": "/// ethdebug: enabled +/// @use-src 0:\"a.sol\" +object \"A1_14\" { + code { + { + /// @src 0:58:123 \"contract A1 { function a(uint x) public pure { assert(x > 0); } }\" + mstore(64, memoryguard(0x80)) + if callvalue() + { + revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() + } + let _1 := allocate_unbounded() + codecopy(_1, dataoffset(\"A1_14_deployed\"), datasize(\"A1_14_deployed\")) + return(_1, datasize(\"A1_14_deployed\")) + } + function allocate_unbounded() -> memPtr + { memPtr := mload(64) } + function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() + { revert(0, 0) } + } + /// @use-src 0:\"a.sol\" + object \"A1_14_deployed\" { + code { + { + /// @src 0:58:123 \"contract A1 { function a(uint x) public pure { assert(x > 0); } }\" + mstore(64, memoryguard(0x80)) + if iszero(lt(calldatasize(), 4)) + { + let selector := shift_right_unsigned(calldataload(0)) + switch selector + case 0xf0fdf834 { external_fun_a() } + default { } + } + revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() + } + function shift_right_unsigned(value) -> newValue + { newValue := shr(224, value) } + function allocate_unbounded() -> memPtr + { memPtr := mload(64) } + function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() + { revert(0, 0) } + function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() + { revert(0, 0) } + function cleanup_uint256(value) -> cleaned + { cleaned := value } + function validator_revert_uint256(value) + { + if iszero(eq(value, cleanup_uint256(value))) { revert(0, 0) } + } + function abi_decode_uint256(offset, end) -> value + { + value := calldataload(offset) + validator_revert_uint256(value) + } + function abi_decode_tuple_uint256(headStart, dataEnd) -> value0 + { + if slt(sub(dataEnd, headStart), 32) + { + revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() + } + let offset := 0 + value0 := abi_decode_uint256(add(headStart, offset), dataEnd) + } + function abi_encode_tuple(headStart) -> tail + { tail := add(headStart, 0) } + function external_fun_a() + { + if callvalue() + { + revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() + } + let param := abi_decode_tuple_uint256(4, calldatasize()) + fun_a(param) + let memPos := allocate_unbounded() + let memEnd := abi_encode_tuple(memPos) + return(memPos, sub(memEnd, memPos)) + } + function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() + { revert(0, 0) } + function cleanup_rational_by(value) -> cleaned + { cleaned := value } + function identity(value) -> ret + { ret := value } + function convert_rational_by_to_uint256(value) -> converted + { + converted := cleanup_uint256(identity(cleanup_rational_by(value))) + } + function panic_error_0x01() + { + mstore(0, shl(224, 0x4e487b71)) + mstore(4, 0x01) + revert(0, 0x24) + } + function assert_helper(condition) + { + if iszero(condition) { panic_error_0x01() } + } + /// @ast-id 13 @src 0:72:121 \"function a(uint x) public pure { assert(x > 0); }\" + function fun_a(var_x) + { + /// @src 0:112:113 \"x\" + let _1 := var_x + let expr := _1 + /// @src 0:116:117 \"0\" + let expr_1 := 0x00 + /// @src 0:112:117 \"x > 0\" + let expr_2 := gt(cleanup_uint256(expr), convert_rational_by_to_uint256(expr_1)) + /// @src 0:105:118 \"assert(x > 0)\" + assert_helper(expr_2) + } + } + data \".metadata\" hex\"\" + } +} +" + }, + "A2": { + "evm": { + "bytecode": { + "ethdebug": {} + } + }, + "irOptimized": "/// ethdebug: enabled +/// @use-src 0:\"a.sol\" +object \"A2_27\" { + code { + { + /// @src 0:124:189 \"contract A2 { function a(uint x) public pure { assert(x > 0); } }\" + mstore(64, memoryguard(0x80)) + if callvalue() + { + revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() + } + let _1 := allocate_unbounded() + codecopy(_1, dataoffset(\"A2_27_deployed\"), datasize(\"A2_27_deployed\")) + return(_1, datasize(\"A2_27_deployed\")) + } + function allocate_unbounded() -> memPtr + { memPtr := mload(64) } + function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() + { revert(0, 0) } + } + /// @use-src 0:\"a.sol\" + object \"A2_27_deployed\" { + code { + { + /// @src 0:124:189 \"contract A2 { function a(uint x) public pure { assert(x > 0); } }\" + mstore(64, memoryguard(0x80)) + if iszero(lt(calldatasize(), 4)) + { + let selector := shift_right_unsigned(calldataload(0)) + switch selector + case 0xf0fdf834 { external_fun_a() } + default { } + } + revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() + } + function shift_right_unsigned(value) -> newValue + { newValue := shr(224, value) } + function allocate_unbounded() -> memPtr + { memPtr := mload(64) } + function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() + { revert(0, 0) } + function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() + { revert(0, 0) } + function cleanup_uint256(value) -> cleaned + { cleaned := value } + function validator_revert_uint256(value) + { + if iszero(eq(value, cleanup_uint256(value))) { revert(0, 0) } + } + function abi_decode_uint256(offset, end) -> value + { + value := calldataload(offset) + validator_revert_uint256(value) + } + function abi_decode_tuple_uint256(headStart, dataEnd) -> value0 + { + if slt(sub(dataEnd, headStart), 32) + { + revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() + } + let offset := 0 + value0 := abi_decode_uint256(add(headStart, offset), dataEnd) + } + function abi_encode_tuple(headStart) -> tail + { tail := add(headStart, 0) } + function external_fun_a() + { + if callvalue() + { + revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() + } + let param := abi_decode_tuple_uint256(4, calldatasize()) + fun_a(param) + let memPos := allocate_unbounded() + let memEnd := abi_encode_tuple(memPos) + return(memPos, sub(memEnd, memPos)) + } + function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() + { revert(0, 0) } + function cleanup_rational_by(value) -> cleaned + { cleaned := value } + function identity(value) -> ret + { ret := value } + function convert_rational_by_to_uint256(value) -> converted + { + converted := cleanup_uint256(identity(cleanup_rational_by(value))) + } + function panic_error_0x01() + { + mstore(0, shl(224, 0x4e487b71)) + mstore(4, 0x01) + revert(0, 0x24) + } + function assert_helper(condition) + { + if iszero(condition) { panic_error_0x01() } + } + /// @ast-id 26 @src 0:138:187 \"function a(uint x) public pure { assert(x > 0); }\" + function fun_a(var_x) + { + /// @src 0:178:179 \"x\" + let _1 := var_x + let expr := _1 + /// @src 0:182:183 \"0\" + let expr_1 := 0x00 + /// @src 0:178:183 \"x > 0\" + let expr_2 := gt(cleanup_uint256(expr), convert_rational_by_to_uint256(expr_1)) + /// @src 0:171:184 \"assert(x > 0)\" + assert_helper(expr_2) + } + } + data \".metadata\" hex\"\" + } +} +" + } + }, + "b.sol": { + "A1": { + "evm": { + "bytecode": { + "ethdebug": {} + } + }, + "irOptimized": "/// ethdebug: enabled +/// @use-src 1:\"b.sol\" +object \"A1_42\" { + code { + { + /// @src 1:58:123 \"contract A1 { function b(uint x) public pure { assert(x > 0); } }\" + mstore(64, memoryguard(0x80)) + if callvalue() + { + revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() + } + let _1 := allocate_unbounded() + codecopy(_1, dataoffset(\"A1_42_deployed\"), datasize(\"A1_42_deployed\")) + return(_1, datasize(\"A1_42_deployed\")) + } + function allocate_unbounded() -> memPtr + { memPtr := mload(64) } + function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() + { revert(0, 0) } + } + /// @use-src 1:\"b.sol\" + object \"A1_42_deployed\" { + code { + { + /// @src 1:58:123 \"contract A1 { function b(uint x) public pure { assert(x > 0); } }\" + mstore(64, memoryguard(0x80)) + if iszero(lt(calldatasize(), 4)) + { + let selector := shift_right_unsigned(calldataload(0)) + switch selector + case 0xcd580ff3 { external_fun_b() } + default { } + } + revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() + } + function shift_right_unsigned(value) -> newValue + { newValue := shr(224, value) } + function allocate_unbounded() -> memPtr + { memPtr := mload(64) } + function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() + { revert(0, 0) } + function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() + { revert(0, 0) } + function cleanup_uint256(value) -> cleaned + { cleaned := value } + function validator_revert_uint256(value) + { + if iszero(eq(value, cleanup_uint256(value))) { revert(0, 0) } + } + function abi_decode_uint256(offset, end) -> value + { + value := calldataload(offset) + validator_revert_uint256(value) + } + function abi_decode_tuple_uint256(headStart, dataEnd) -> value0 + { + if slt(sub(dataEnd, headStart), 32) + { + revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() + } + let offset := 0 + value0 := abi_decode_uint256(add(headStart, offset), dataEnd) + } + function abi_encode_tuple(headStart) -> tail + { tail := add(headStart, 0) } + function external_fun_b() + { + if callvalue() + { + revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() + } + let param := abi_decode_tuple_uint256(4, calldatasize()) + fun_b(param) + let memPos := allocate_unbounded() + let memEnd := abi_encode_tuple(memPos) + return(memPos, sub(memEnd, memPos)) + } + function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() + { revert(0, 0) } + function cleanup_rational_by(value) -> cleaned + { cleaned := value } + function identity(value) -> ret + { ret := value } + function convert_rational_by_to_uint256(value) -> converted + { + converted := cleanup_uint256(identity(cleanup_rational_by(value))) + } + function panic_error_0x01() + { + mstore(0, shl(224, 0x4e487b71)) + mstore(4, 0x01) + revert(0, 0x24) + } + function assert_helper(condition) + { + if iszero(condition) { panic_error_0x01() } + } + /// @ast-id 41 @src 1:72:121 \"function b(uint x) public pure { assert(x > 0); }\" + function fun_b(var_x) + { + /// @src 1:112:113 \"x\" + let _1 := var_x + let expr := _1 + /// @src 1:116:117 \"0\" + let expr_1 := 0x00 + /// @src 1:112:117 \"x > 0\" + let expr_2 := gt(cleanup_uint256(expr), convert_rational_by_to_uint256(expr_1)) + /// @src 1:105:118 \"assert(x > 0)\" + assert_helper(expr_2) + } + } + data \".metadata\" hex\"\" + } +} +" + }, + "B2": { + "evm": { + "bytecode": { + "ethdebug": {} + } + }, + "irOptimized": "/// ethdebug: enabled +/// @use-src 1:\"b.sol\" +object \"B2_55\" { + code { + { + /// @src 1:124:189 \"contract B2 { function b(uint x) public pure { assert(x > 0); } }\" + mstore(64, memoryguard(0x80)) + if callvalue() + { + revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() + } + let _1 := allocate_unbounded() + codecopy(_1, dataoffset(\"B2_55_deployed\"), datasize(\"B2_55_deployed\")) + return(_1, datasize(\"B2_55_deployed\")) + } + function allocate_unbounded() -> memPtr + { memPtr := mload(64) } + function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() + { revert(0, 0) } + } + /// @use-src 1:\"b.sol\" + object \"B2_55_deployed\" { + code { + { + /// @src 1:124:189 \"contract B2 { function b(uint x) public pure { assert(x > 0); } }\" + mstore(64, memoryguard(0x80)) + if iszero(lt(calldatasize(), 4)) + { + let selector := shift_right_unsigned(calldataload(0)) + switch selector + case 0xcd580ff3 { external_fun_b() } + default { } + } + revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() + } + function shift_right_unsigned(value) -> newValue + { newValue := shr(224, value) } + function allocate_unbounded() -> memPtr + { memPtr := mload(64) } + function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() + { revert(0, 0) } + function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() + { revert(0, 0) } + function cleanup_uint256(value) -> cleaned + { cleaned := value } + function validator_revert_uint256(value) + { + if iszero(eq(value, cleanup_uint256(value))) { revert(0, 0) } + } + function abi_decode_uint256(offset, end) -> value + { + value := calldataload(offset) + validator_revert_uint256(value) + } + function abi_decode_tuple_uint256(headStart, dataEnd) -> value0 + { + if slt(sub(dataEnd, headStart), 32) + { + revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() + } + let offset := 0 + value0 := abi_decode_uint256(add(headStart, offset), dataEnd) + } + function abi_encode_tuple(headStart) -> tail + { tail := add(headStart, 0) } + function external_fun_b() + { + if callvalue() + { + revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() + } + let param := abi_decode_tuple_uint256(4, calldatasize()) + fun_b(param) + let memPos := allocate_unbounded() + let memEnd := abi_encode_tuple(memPos) + return(memPos, sub(memEnd, memPos)) + } + function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() + { revert(0, 0) } + function cleanup_rational_by(value) -> cleaned + { cleaned := value } + function identity(value) -> ret + { ret := value } + function convert_rational_by_to_uint256(value) -> converted + { + converted := cleanup_uint256(identity(cleanup_rational_by(value))) + } + function panic_error_0x01() + { + mstore(0, shl(224, 0x4e487b71)) + mstore(4, 0x01) + revert(0, 0x24) + } + function assert_helper(condition) + { + if iszero(condition) { panic_error_0x01() } + } + /// @ast-id 54 @src 1:138:187 \"function b(uint x) public pure { assert(x > 0); }\" + function fun_b(var_x) + { + /// @src 1:178:179 \"x\" + let _1 := var_x + let expr := _1 + /// @src 1:182:183 \"0\" + let expr_1 := 0x00 + /// @src 1:178:183 \"x > 0\" + let expr_2 := gt(cleanup_uint256(expr), convert_rational_by_to_uint256(expr_1)) + /// @src 1:171:184 \"assert(x > 0)\" + assert_helper(expr_2) + } + } + data \".metadata\" hex\"\" + } +} +" + } + } + }, + "ethdebug": { + "sources": [ + "a.sol", + "b.sol" + ] + }, + "sources": { + "a.sol": { + "id": 0 + }, + "b.sol": { + "id": 1 + } + } +} diff --git a/test/cmdlineTests/standard_output_selection_ethdebug_no_viair/input.json b/test/cmdlineTests/standard_output_selection_ethdebug_no_viair/input.json new file mode 100644 index 000000000000..574a8b1c43cd --- /dev/null +++ b/test/cmdlineTests/standard_output_selection_ethdebug_no_viair/input.json @@ -0,0 +1,22 @@ +{ + "language": "Solidity", + "sources": { + "a.sol": { + "content": "//SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract A1 { function a(uint x) public pure { assert(x > 0); } } contract A2 { function a(uint x) public pure { assert(x > 0); } }" + }, + "b.sol": { + "content": "//SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract A1 { function b(uint x) public pure { assert(x > 0); } } contract B2 { function b(uint x) public pure { assert(x > 0); } }" + } + }, + "settings": { + "outputSelection": { + "*": { + "*": [ + "evm.bytecode.ethdebug", + "evm.deployedBytecode.ethdebug", + "ir" + ] + } + } + } +} diff --git a/test/cmdlineTests/standard_output_selection_ethdebug_no_viair/output.json b/test/cmdlineTests/standard_output_selection_ethdebug_no_viair/output.json new file mode 100644 index 000000000000..1329babc3dd7 --- /dev/null +++ b/test/cmdlineTests/standard_output_selection_ethdebug_no_viair/output.json @@ -0,0 +1,11 @@ +{ + "errors": [ + { + "component": "general", + "formattedMessage": "'evm.bytecode.ethdebug' or 'evm.deployedBytecode.ethdebug' can only be selected as output, if 'viaIR' was set.", + "message": "'evm.bytecode.ethdebug' or 'evm.deployedBytecode.ethdebug' can only be selected as output, if 'viaIR' was set.", + "severity": "error", + "type": "FatalError" + } + ] +} diff --git a/test/cmdlineTests/standard_output_selection_ethdebug_optimize/input.json b/test/cmdlineTests/standard_output_selection_ethdebug_optimize/input.json deleted file mode 100644 index a8a5cff05d0b..000000000000 --- a/test/cmdlineTests/standard_output_selection_ethdebug_optimize/input.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "language": "Solidity", - "sources": { - "a.sol": { - "content": "//SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract A1 { function a(uint x) public pure { assert(x > 0); } } contract A2 { function a(uint x) public pure { assert(x > 0); } }" - }, - "b.sol": { - "content": "//SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract A1 { function b(uint x) public pure { assert(x > 0); } } contract B2 { function b(uint x) public pure { assert(x > 0); } }" - } - }, - "settings": { - "viaIR": true, - "optimizer": { - "enabled": true - }, - "outputSelection": { - "*": { - "*": [ - "evm.bytecode.ethdebug", "ir" - ] - } - } - } -} diff --git a/test/cmdlineTests/standard_output_selection_ethdebug_optimize_ir/input.json b/test/cmdlineTests/standard_output_selection_ethdebug_optimize_ir/input.json new file mode 100644 index 000000000000..a684e0dc073b --- /dev/null +++ b/test/cmdlineTests/standard_output_selection_ethdebug_optimize_ir/input.json @@ -0,0 +1,25 @@ +{ + "language": "Solidity", + "sources": { + "a.sol": { + "content": "//SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract A1 { function a(uint x) public pure { assert(x > 0); } } contract A2 { function a(uint x) public pure { assert(x > 0); } }" + }, + "b.sol": { + "content": "//SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract A1 { function b(uint x) public pure { assert(x > 0); } } contract B2 { function b(uint x) public pure { assert(x > 0); } }" + } + }, + "settings": { + "viaIR": true, + "optimizer": { + "enabled": true + }, + "outputSelection": { + "*": { + "*": [ + "evm.bytecode.ethdebug", + "ir" + ] + } + } + } +} diff --git a/test/cmdlineTests/standard_output_selection_ethdebug_irOptimized/output.json b/test/cmdlineTests/standard_output_selection_ethdebug_optimize_ir/output.json similarity index 85% rename from test/cmdlineTests/standard_output_selection_ethdebug_irOptimized/output.json rename to test/cmdlineTests/standard_output_selection_ethdebug_optimize_ir/output.json index 3ed2f577c7aa..44867c7a75eb 100644 --- a/test/cmdlineTests/standard_output_selection_ethdebug_irOptimized/output.json +++ b/test/cmdlineTests/standard_output_selection_ethdebug_optimize_ir/output.json @@ -5,7 +5,7 @@ "formattedMessage": "Optimization is not yet supported with ethdebug.", "message": "Optimization is not yet supported with ethdebug.", "severity": "error", - "type": "FatalError" + "type": "UnimplementedFeatureError" } ] } diff --git a/test/cmdlineTests/standard_output_selection_ethdebug_optimize_iroptimized/input.json b/test/cmdlineTests/standard_output_selection_ethdebug_optimize_iroptimized/input.json new file mode 100644 index 000000000000..1f09e3a70253 --- /dev/null +++ b/test/cmdlineTests/standard_output_selection_ethdebug_optimize_iroptimized/input.json @@ -0,0 +1,25 @@ +{ + "language": "Solidity", + "sources": { + "a.sol": { + "content": "//SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract A1 { function a(uint x) public pure { assert(x > 0); } } contract A2 { function a(uint x) public pure { assert(x > 0); } }" + }, + "b.sol": { + "content": "//SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract A1 { function b(uint x) public pure { assert(x > 0); } } contract B2 { function b(uint x) public pure { assert(x > 0); } }" + } + }, + "settings": { + "viaIR": true, + "optimizer": { + "enabled": true + }, + "outputSelection": { + "*": { + "*": [ + "evm.bytecode.ethdebug", + "irOptimized" + ] + } + } + } +} diff --git a/test/cmdlineTests/standard_output_selection_ethdebug_optimize/output.json b/test/cmdlineTests/standard_output_selection_ethdebug_optimize_iroptimized/output.json similarity index 85% rename from test/cmdlineTests/standard_output_selection_ethdebug_optimize/output.json rename to test/cmdlineTests/standard_output_selection_ethdebug_optimize_iroptimized/output.json index 3ed2f577c7aa..44867c7a75eb 100644 --- a/test/cmdlineTests/standard_output_selection_ethdebug_optimize/output.json +++ b/test/cmdlineTests/standard_output_selection_ethdebug_optimize_iroptimized/output.json @@ -5,7 +5,7 @@ "formattedMessage": "Optimization is not yet supported with ethdebug.", "message": "Optimization is not yet supported with ethdebug.", "severity": "error", - "type": "FatalError" + "type": "UnimplementedFeatureError" } ] } diff --git a/test/cmdlineTests/standard_yul_ethdebug_bytecode/args b/test/cmdlineTests/standard_yul_debug_info_ethdebug_compatible_output/args similarity index 100% rename from test/cmdlineTests/standard_yul_ethdebug_bytecode/args rename to test/cmdlineTests/standard_yul_debug_info_ethdebug_compatible_output/args diff --git a/test/cmdlineTests/standard_yul_debug_info_ethdebug_compatible_output/in.yul b/test/cmdlineTests/standard_yul_debug_info_ethdebug_compatible_output/in.yul new file mode 100644 index 000000000000..aa564d00ce86 --- /dev/null +++ b/test/cmdlineTests/standard_yul_debug_info_ethdebug_compatible_output/in.yul @@ -0,0 +1,16 @@ +/// @use-src 0:"input.sol" +object "C_6_deployed" { + code { + /// @src 0:60:101 "contract C {..." + mstore(64, 128) + + // f() + fun_f_5() + + /// @src 0:77:99 "function f() public {}" + function fun_f_5() { + sstore(0, 42) + } + /// @src 0:60:101 "contract C {..." + } +} diff --git a/test/cmdlineTests/standard_yul_debug_info_ethdebug_compatible_output/input.json b/test/cmdlineTests/standard_yul_debug_info_ethdebug_compatible_output/input.json new file mode 100644 index 000000000000..3e5b81c5ef69 --- /dev/null +++ b/test/cmdlineTests/standard_yul_debug_info_ethdebug_compatible_output/input.json @@ -0,0 +1,16 @@ +{ + "language": "Yul", + "sources": { + "C": { + "urls": [ + "standard_yul_debug_info_ethdebug_compatible_output/in.yul" + ] + } + }, + "settings": { + "debug": {"debugInfo": ["ethdebug"]}, + "outputSelection": { + "*": {"*": ["ir", "irOptimized", "evm.bytecode.ethdebug"]} + } + } +} diff --git a/test/cmdlineTests/standard_yul_debug_info_ethdebug_compatible_output/output.json b/test/cmdlineTests/standard_yul_debug_info_ethdebug_compatible_output/output.json new file mode 100644 index 000000000000..63d48b80b255 --- /dev/null +++ b/test/cmdlineTests/standard_yul_debug_info_ethdebug_compatible_output/output.json @@ -0,0 +1,48 @@ +{ + "contracts": { + "C": { + "C_6_deployed": { + "evm": { + "bytecode": { + "ethdebug": { + "not yet implemented @ MachineAssemblyObject::ethdebug": true + } + } + }, + "ir": "/// ethdebug: enabled +/// @use-src 0:\"input.sol\" +object \"C_6_deployed\" { + code { + /// @src 0:60:101 + mstore(64, 128) + fun_f_5() + /// @src 0:77:99 + function fun_f_5() + { sstore(0, 42) } + } +} +", + "irOptimized": "/// ethdebug: enabled +/// @use-src 0:\"input.sol\" +object \"C_6_deployed\" { + code { + { + /// @src 0:60:101 + mstore(64, 128) + fun_f() + } + /// @src 0:77:99 + function fun_f() + { sstore(0, 42) } + } +} +" + } + } + }, + "ethdebug": { + "sources": [ + "C" + ] + } +} diff --git a/test/cmdlineTests/standard_yul_ethdebug_irOptimized/args b/test/cmdlineTests/standard_yul_debug_info_ethdebug_incompatible_output/args similarity index 100% rename from test/cmdlineTests/standard_yul_ethdebug_irOptimized/args rename to test/cmdlineTests/standard_yul_debug_info_ethdebug_incompatible_output/args diff --git a/test/cmdlineTests/standard_yul_debug_info_ethdebug_incompatible_output/in.yul b/test/cmdlineTests/standard_yul_debug_info_ethdebug_incompatible_output/in.yul new file mode 100644 index 000000000000..aa564d00ce86 --- /dev/null +++ b/test/cmdlineTests/standard_yul_debug_info_ethdebug_incompatible_output/in.yul @@ -0,0 +1,16 @@ +/// @use-src 0:"input.sol" +object "C_6_deployed" { + code { + /// @src 0:60:101 "contract C {..." + mstore(64, 128) + + // f() + fun_f_5() + + /// @src 0:77:99 "function f() public {}" + function fun_f_5() { + sstore(0, 42) + } + /// @src 0:60:101 "contract C {..." + } +} diff --git a/test/cmdlineTests/standard_yul_debug_info_ethdebug_incompatible_output/input.json b/test/cmdlineTests/standard_yul_debug_info_ethdebug_incompatible_output/input.json new file mode 100644 index 000000000000..f05e6f361aca --- /dev/null +++ b/test/cmdlineTests/standard_yul_debug_info_ethdebug_incompatible_output/input.json @@ -0,0 +1,16 @@ +{ + "language": "Yul", + "sources": { + "C": { + "urls": [ + "standard_yul_debug_info_ethdebug_incompatible_output/in.yul" + ] + } + }, + "settings": { + "debug": {"debugInfo": ["ethdebug"]}, + "outputSelection": { + "*": {"*": ["evm.assembly"]} + } + } +} diff --git a/test/cmdlineTests/standard_yul_debug_info_ethdebug_incompatible_output/output.json b/test/cmdlineTests/standard_yul_debug_info_ethdebug_incompatible_output/output.json new file mode 100644 index 000000000000..963bcd8d7d68 --- /dev/null +++ b/test/cmdlineTests/standard_yul_debug_info_ethdebug_incompatible_output/output.json @@ -0,0 +1,11 @@ +{ + "errors": [ + { + "component": "general", + "formattedMessage": "'settings.debug.debugInfo' can only include 'ethdebug', if output 'ir', 'irOptimized', 'evm.bytecode.ethdebug', or 'evm.deployedBytecode.ethdebug' was selected.", + "message": "'settings.debug.debugInfo' can only include 'ethdebug', if output 'ir', 'irOptimized', 'evm.bytecode.ethdebug', or 'evm.deployedBytecode.ethdebug' was selected.", + "severity": "error", + "type": "FatalError" + } + ] +} diff --git a/test/cmdlineTests/standard_yul_ethdebug_optimize/args b/test/cmdlineTests/standard_yul_ethdebug_bytecode_ir/args similarity index 100% rename from test/cmdlineTests/standard_yul_ethdebug_optimize/args rename to test/cmdlineTests/standard_yul_ethdebug_bytecode_ir/args diff --git a/test/cmdlineTests/standard_yul_ethdebug_bytecode/in.yul b/test/cmdlineTests/standard_yul_ethdebug_bytecode_ir/in.yul similarity index 100% rename from test/cmdlineTests/standard_yul_ethdebug_bytecode/in.yul rename to test/cmdlineTests/standard_yul_ethdebug_bytecode_ir/in.yul diff --git a/test/cmdlineTests/standard_yul_ethdebug_bytecode/input.json b/test/cmdlineTests/standard_yul_ethdebug_bytecode_ir/input.json similarity index 68% rename from test/cmdlineTests/standard_yul_ethdebug_bytecode/input.json rename to test/cmdlineTests/standard_yul_ethdebug_bytecode_ir/input.json index f3346fdd10e3..abfb7ee863af 100644 --- a/test/cmdlineTests/standard_yul_ethdebug_bytecode/input.json +++ b/test/cmdlineTests/standard_yul_ethdebug_bytecode_ir/input.json @@ -1,7 +1,7 @@ { "language": "Yul", "sources": { - "C": {"urls": ["standard_yul_debug_info_print_all/in.yul"]} + "C": {"urls": ["standard_yul_ethdebug_bytecode_ir/in.yul"]} }, "settings": { "outputSelection": { diff --git a/test/cmdlineTests/standard_yul_ethdebug_bytecode/output.json b/test/cmdlineTests/standard_yul_ethdebug_bytecode_ir/output.json similarity index 100% rename from test/cmdlineTests/standard_yul_ethdebug_bytecode/output.json rename to test/cmdlineTests/standard_yul_ethdebug_bytecode_ir/output.json diff --git a/test/cmdlineTests/standard_yul_ethdebug_bytecode_iroptimized/args b/test/cmdlineTests/standard_yul_ethdebug_bytecode_iroptimized/args new file mode 100644 index 000000000000..18532c5a6d3f --- /dev/null +++ b/test/cmdlineTests/standard_yul_ethdebug_bytecode_iroptimized/args @@ -0,0 +1 @@ +--allow-paths . diff --git a/test/cmdlineTests/standard_yul_ethdebug_irOptimized/in.yul b/test/cmdlineTests/standard_yul_ethdebug_bytecode_iroptimized/in.yul similarity index 100% rename from test/cmdlineTests/standard_yul_ethdebug_irOptimized/in.yul rename to test/cmdlineTests/standard_yul_ethdebug_bytecode_iroptimized/in.yul diff --git a/test/cmdlineTests/standard_yul_ethdebug_irOptimized/input.json b/test/cmdlineTests/standard_yul_ethdebug_bytecode_iroptimized/input.json similarity index 66% rename from test/cmdlineTests/standard_yul_ethdebug_irOptimized/input.json rename to test/cmdlineTests/standard_yul_ethdebug_bytecode_iroptimized/input.json index 89994857f418..54094c67305f 100644 --- a/test/cmdlineTests/standard_yul_ethdebug_irOptimized/input.json +++ b/test/cmdlineTests/standard_yul_ethdebug_bytecode_iroptimized/input.json @@ -1,7 +1,7 @@ { "language": "Yul", "sources": { - "C": {"urls": ["standard_yul_debug_info_print_all/in.yul"]} + "C": {"urls": ["standard_yul_ethdebug_bytecode_iroptimized/in.yul"]} }, "settings": { "outputSelection": { diff --git a/test/cmdlineTests/standard_yul_ethdebug_bytecode_iroptimized/output.json b/test/cmdlineTests/standard_yul_ethdebug_bytecode_iroptimized/output.json new file mode 100644 index 000000000000..d7e3e6be3b40 --- /dev/null +++ b/test/cmdlineTests/standard_yul_ethdebug_bytecode_iroptimized/output.json @@ -0,0 +1,35 @@ +{ + "contracts": { + "C": { + "C_6_deployed": { + "evm": { + "bytecode": { + "ethdebug": { + "not yet implemented @ MachineAssemblyObject::ethdebug": true + } + } + }, + "irOptimized": "/// ethdebug: enabled +/// @use-src 0:\"input.sol\" +object \"C_6_deployed\" { + code { + { + /// @src 0:60:101 + mstore(64, 128) + fun_f() + } + /// @src 0:77:99 + function fun_f() + { sstore(0, 42) } + } +} +" + } + } + }, + "ethdebug": { + "sources": [ + "C" + ] + } +} diff --git a/test/cmdlineTests/standard_yul_ethdebug_deployed_bytecode/input.json b/test/cmdlineTests/standard_yul_ethdebug_deployed_bytecode/input.json index e132c654f042..e222dfeda8c2 100644 --- a/test/cmdlineTests/standard_yul_ethdebug_deployed_bytecode/input.json +++ b/test/cmdlineTests/standard_yul_ethdebug_deployed_bytecode/input.json @@ -1,7 +1,7 @@ { "language": "Yul", "sources": { - "C": {"urls": ["standard_yul_debug_info_print_all/in.yul"]} + "C": {"urls": ["standard_yul_ethdebug_deployed_bytecode/in.yul"]} }, "settings": { "outputSelection": { diff --git a/test/cmdlineTests/standard_yul_ethdebug_ir/args b/test/cmdlineTests/standard_yul_ethdebug_ir/args new file mode 100644 index 000000000000..18532c5a6d3f --- /dev/null +++ b/test/cmdlineTests/standard_yul_ethdebug_ir/args @@ -0,0 +1 @@ +--allow-paths . diff --git a/test/cmdlineTests/standard_yul_ethdebug_optimize/in.yul b/test/cmdlineTests/standard_yul_ethdebug_ir/in.yul similarity index 100% rename from test/cmdlineTests/standard_yul_ethdebug_optimize/in.yul rename to test/cmdlineTests/standard_yul_ethdebug_ir/in.yul diff --git a/test/cmdlineTests/standard_yul_ethdebug_ir/input.json b/test/cmdlineTests/standard_yul_ethdebug_ir/input.json new file mode 100644 index 000000000000..3153a378db84 --- /dev/null +++ b/test/cmdlineTests/standard_yul_ethdebug_ir/input.json @@ -0,0 +1,11 @@ +{ + "language": "Yul", + "sources": { + "C": {"urls": ["standard_yul_ethdebug_ir/in.yul"]} + }, + "settings": { + "outputSelection": { + "*": {"*": ["evm.bytecode.ethdebug", "ir"]} + } + } +} diff --git a/test/cmdlineTests/standard_yul_ethdebug_ir/output.json b/test/cmdlineTests/standard_yul_ethdebug_ir/output.json new file mode 100644 index 000000000000..c9ab1d8f5e73 --- /dev/null +++ b/test/cmdlineTests/standard_yul_ethdebug_ir/output.json @@ -0,0 +1,33 @@ +{ + "contracts": { + "C": { + "C_6_deployed": { + "evm": { + "bytecode": { + "ethdebug": { + "not yet implemented @ MachineAssemblyObject::ethdebug": true + } + } + }, + "ir": "/// ethdebug: enabled +/// @use-src 0:\"input.sol\" +object \"C_6_deployed\" { + code { + /// @src 0:60:101 + mstore(64, 128) + fun_f_5() + /// @src 0:77:99 + function fun_f_5() + { sstore(0, 42) } + } +} +" + } + } + }, + "ethdebug": { + "sources": [ + "C" + ] + } +} diff --git a/test/cmdlineTests/standard_yul_ethdebug_iroptimize/args b/test/cmdlineTests/standard_yul_ethdebug_iroptimize/args new file mode 100644 index 000000000000..18532c5a6d3f --- /dev/null +++ b/test/cmdlineTests/standard_yul_ethdebug_iroptimize/args @@ -0,0 +1 @@ +--allow-paths . diff --git a/test/cmdlineTests/standard_yul_ethdebug_iroptimize/in.yul b/test/cmdlineTests/standard_yul_ethdebug_iroptimize/in.yul new file mode 100644 index 000000000000..920aef8e9dc2 --- /dev/null +++ b/test/cmdlineTests/standard_yul_ethdebug_iroptimize/in.yul @@ -0,0 +1,17 @@ +/// @use-src 0:"input.sol" +object "C_6_deployed" { + code { + /// @src 0:60:101 "contract C {..." + mstore(64, 128) + + // f() + fun_f_5() + + /// @src 0:77:99 "function f() public {}" + function fun_f_5() { + sstore(0, 42) + } + /// @src 0:60:101 "contract C {..." + } +} + diff --git a/test/cmdlineTests/standard_yul_ethdebug_iroptimize/input.json b/test/cmdlineTests/standard_yul_ethdebug_iroptimize/input.json new file mode 100644 index 000000000000..180abcf31f8d --- /dev/null +++ b/test/cmdlineTests/standard_yul_ethdebug_iroptimize/input.json @@ -0,0 +1,11 @@ +{ + "language": "Yul", + "sources": { + "C": {"urls": ["standard_yul_ethdebug_iroptimize/in.yul"]} + }, + "settings": { + "outputSelection": { + "*": {"*": ["evm.bytecode.ethdebug", "irOptimize"]} + } + } +} diff --git a/test/cmdlineTests/standard_yul_ethdebug_iroptimize/output.json b/test/cmdlineTests/standard_yul_ethdebug_iroptimize/output.json new file mode 100644 index 000000000000..47d0008f1eb5 --- /dev/null +++ b/test/cmdlineTests/standard_yul_ethdebug_iroptimize/output.json @@ -0,0 +1,20 @@ +{ + "contracts": { + "C": { + "C_6_deployed": { + "evm": { + "bytecode": { + "ethdebug": { + "not yet implemented @ MachineAssemblyObject::ethdebug": true + } + } + } + } + } + }, + "ethdebug": { + "sources": [ + "C" + ] + } +} diff --git a/test/cmdlineTests/standard_yul_ethdebug_optimize/output.json b/test/cmdlineTests/standard_yul_ethdebug_optimize/output.json deleted file mode 100644 index 3ed2f577c7aa..000000000000 --- a/test/cmdlineTests/standard_yul_ethdebug_optimize/output.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "errors": [ - { - "component": "general", - "formattedMessage": "Optimization is not yet supported with ethdebug.", - "message": "Optimization is not yet supported with ethdebug.", - "severity": "error", - "type": "FatalError" - } - ] -} diff --git a/test/cmdlineTests/standard_yul_ethdebug_optimize_ir/args b/test/cmdlineTests/standard_yul_ethdebug_optimize_ir/args new file mode 100644 index 000000000000..18532c5a6d3f --- /dev/null +++ b/test/cmdlineTests/standard_yul_ethdebug_optimize_ir/args @@ -0,0 +1 @@ +--allow-paths . diff --git a/test/cmdlineTests/standard_yul_ethdebug_optimize_ir/in.yul b/test/cmdlineTests/standard_yul_ethdebug_optimize_ir/in.yul new file mode 100644 index 000000000000..920aef8e9dc2 --- /dev/null +++ b/test/cmdlineTests/standard_yul_ethdebug_optimize_ir/in.yul @@ -0,0 +1,17 @@ +/// @use-src 0:"input.sol" +object "C_6_deployed" { + code { + /// @src 0:60:101 "contract C {..." + mstore(64, 128) + + // f() + fun_f_5() + + /// @src 0:77:99 "function f() public {}" + function fun_f_5() { + sstore(0, 42) + } + /// @src 0:60:101 "contract C {..." + } +} + diff --git a/test/cmdlineTests/standard_yul_ethdebug_optimize/input.json b/test/cmdlineTests/standard_yul_ethdebug_optimize_ir/input.json similarity index 73% rename from test/cmdlineTests/standard_yul_ethdebug_optimize/input.json rename to test/cmdlineTests/standard_yul_ethdebug_optimize_ir/input.json index fb232f23a1fb..9f0c8b0d5cef 100644 --- a/test/cmdlineTests/standard_yul_ethdebug_optimize/input.json +++ b/test/cmdlineTests/standard_yul_ethdebug_optimize_ir/input.json @@ -1,7 +1,7 @@ { "language": "Yul", "sources": { - "C": {"urls": ["standard_yul_debug_info_print_all/in.yul"]} + "C": {"urls": ["standard_yul_ethdebug_optimize_ir/in.yul"]} }, "settings": { "optimizer": { diff --git a/test/cmdlineTests/standard_yul_ethdebug_optimize_ir/output.json b/test/cmdlineTests/standard_yul_ethdebug_optimize_ir/output.json new file mode 100644 index 000000000000..44867c7a75eb --- /dev/null +++ b/test/cmdlineTests/standard_yul_ethdebug_optimize_ir/output.json @@ -0,0 +1,11 @@ +{ + "errors": [ + { + "component": "general", + "formattedMessage": "Optimization is not yet supported with ethdebug.", + "message": "Optimization is not yet supported with ethdebug.", + "severity": "error", + "type": "UnimplementedFeatureError" + } + ] +} diff --git a/test/cmdlineTests/standard_yul_ethdebug_optimize_iroptimized/args b/test/cmdlineTests/standard_yul_ethdebug_optimize_iroptimized/args new file mode 100644 index 000000000000..18532c5a6d3f --- /dev/null +++ b/test/cmdlineTests/standard_yul_ethdebug_optimize_iroptimized/args @@ -0,0 +1 @@ +--allow-paths . diff --git a/test/cmdlineTests/standard_yul_ethdebug_optimize_iroptimized/in.yul b/test/cmdlineTests/standard_yul_ethdebug_optimize_iroptimized/in.yul new file mode 100644 index 000000000000..920aef8e9dc2 --- /dev/null +++ b/test/cmdlineTests/standard_yul_ethdebug_optimize_iroptimized/in.yul @@ -0,0 +1,17 @@ +/// @use-src 0:"input.sol" +object "C_6_deployed" { + code { + /// @src 0:60:101 "contract C {..." + mstore(64, 128) + + // f() + fun_f_5() + + /// @src 0:77:99 "function f() public {}" + function fun_f_5() { + sstore(0, 42) + } + /// @src 0:60:101 "contract C {..." + } +} + diff --git a/test/cmdlineTests/standard_yul_ethdebug_optimize_iroptimized/input.json b/test/cmdlineTests/standard_yul_ethdebug_optimize_iroptimized/input.json new file mode 100644 index 000000000000..81b637abd5b5 --- /dev/null +++ b/test/cmdlineTests/standard_yul_ethdebug_optimize_iroptimized/input.json @@ -0,0 +1,14 @@ +{ + "language": "Yul", + "sources": { + "C": {"urls": ["standard_yul_ethdebug_optimize_iroptimized/in.yul"]} + }, + "settings": { + "optimizer": { + "enabled": true + }, + "outputSelection": { + "*": {"*": ["evm.bytecode.ethdebug", "irOptimized"]} + } + } +} diff --git a/test/cmdlineTests/standard_yul_ethdebug_optimize_iroptimized/output.json b/test/cmdlineTests/standard_yul_ethdebug_optimize_iroptimized/output.json new file mode 100644 index 000000000000..44867c7a75eb --- /dev/null +++ b/test/cmdlineTests/standard_yul_ethdebug_optimize_iroptimized/output.json @@ -0,0 +1,11 @@ +{ + "errors": [ + { + "component": "general", + "formattedMessage": "Optimization is not yet supported with ethdebug.", + "message": "Optimization is not yet supported with ethdebug.", + "severity": "error", + "type": "UnimplementedFeatureError" + } + ] +} diff --git a/test/cmdlineTests/yul_ethdebug/args b/test/cmdlineTests/yul_ethdebug/args index 715f3fb4848b..a800f5c34e34 100644 --- a/test/cmdlineTests/yul_ethdebug/args +++ b/test/cmdlineTests/yul_ethdebug/args @@ -1 +1 @@ ---ethdebug --strict-assembly --optimize --ir-optimized \ No newline at end of file +--ethdebug --strict-assembly \ No newline at end of file diff --git a/test/cmdlineTests/yul_ethdebug/output b/test/cmdlineTests/yul_ethdebug/output index 702fe057d532..84ba9317b85b 100644 --- a/test/cmdlineTests/yul_ethdebug/output +++ b/test/cmdlineTests/yul_ethdebug/output @@ -3,16 +3,5 @@ ======= yul_ethdebug/input.yul (EVM) ======= -Pretty printed source: -/// ethdebug: enabled -object "object" { - code { - { - sstore(calldataload(0), calldataload(0x20)) - } - } -} - - Debug Data (ethdebug/format/program): {"not yet implemented @ MachineAssemblyObject::ethdebug":true} diff --git a/test/cmdlineTests/yul_ethdebug_ir/args b/test/cmdlineTests/yul_ethdebug_ir/args new file mode 100644 index 000000000000..6194b51b6942 --- /dev/null +++ b/test/cmdlineTests/yul_ethdebug_ir/args @@ -0,0 +1 @@ +--ethdebug --strict-assembly --ir \ No newline at end of file diff --git a/test/cmdlineTests/yul_ethdebug_ir/err b/test/cmdlineTests/yul_ethdebug_ir/err new file mode 100644 index 000000000000..645f7557ada8 --- /dev/null +++ b/test/cmdlineTests/yul_ethdebug_ir/err @@ -0,0 +1 @@ +Error: The following outputs are not supported in assembler mode: --ir. diff --git a/test/cmdlineTests/yul_ethdebug_ir/exit b/test/cmdlineTests/yul_ethdebug_ir/exit new file mode 100644 index 000000000000..d00491fd7e5b --- /dev/null +++ b/test/cmdlineTests/yul_ethdebug_ir/exit @@ -0,0 +1 @@ +1 diff --git a/test/cmdlineTests/yul_ethdebug_ir/input.yul b/test/cmdlineTests/yul_ethdebug_ir/input.yul new file mode 100644 index 000000000000..acd0b45f5335 --- /dev/null +++ b/test/cmdlineTests/yul_ethdebug_ir/input.yul @@ -0,0 +1,18 @@ +object "object" { + code { + let a + let b + { + function z() -> y + { y := calldataload(0) } + a := z() + } + { + function z() -> y + { y := calldataload(0x20) } + b := z() + } + sstore(a, b) + } +} + diff --git a/test/cmdlineTests/yul_ethdebug_iroptimized/args b/test/cmdlineTests/yul_ethdebug_iroptimized/args new file mode 100644 index 000000000000..2063d860c504 --- /dev/null +++ b/test/cmdlineTests/yul_ethdebug_iroptimized/args @@ -0,0 +1 @@ +--ethdebug --strict-assembly --ir-optimized \ No newline at end of file diff --git a/test/cmdlineTests/yul_ethdebug_iroptimized/input.yul b/test/cmdlineTests/yul_ethdebug_iroptimized/input.yul new file mode 100644 index 000000000000..acd0b45f5335 --- /dev/null +++ b/test/cmdlineTests/yul_ethdebug_iroptimized/input.yul @@ -0,0 +1,18 @@ +object "object" { + code { + let a + let b + { + function z() -> y + { y := calldataload(0) } + a := z() + } + { + function z() -> y + { y := calldataload(0x20) } + b := z() + } + sstore(a, b) + } +} + diff --git a/test/cmdlineTests/yul_ethdebug_iroptimized/output b/test/cmdlineTests/yul_ethdebug_iroptimized/output new file mode 100644 index 000000000000..e2f0ed7f97f2 --- /dev/null +++ b/test/cmdlineTests/yul_ethdebug_iroptimized/output @@ -0,0 +1,26 @@ +======= Debug Data (ethdebug/format/info/resources) ======= +{"sources":["yul_ethdebug_iroptimized/input.yul"]} + +======= yul_ethdebug_iroptimized/input.yul (EVM) ======= + +Pretty printed source: +/// ethdebug: enabled +object "object" { + code { + { + let a + let b + a := z() + b := z_1() + sstore(a, b) + } + function z() -> y + { y := calldataload(0) } + function z_1() -> y + { y := calldataload(0x20) } + } +} + + +Debug Data (ethdebug/format/program): +{"not yet implemented @ MachineAssemblyObject::ethdebug":true} diff --git a/test/cmdlineTests/yul_ethdebug_optimize/args b/test/cmdlineTests/yul_ethdebug_optimize/args new file mode 100644 index 000000000000..fd081fdaf6d3 --- /dev/null +++ b/test/cmdlineTests/yul_ethdebug_optimize/args @@ -0,0 +1 @@ +--ethdebug --strict-assembly --optimize \ No newline at end of file diff --git a/test/cmdlineTests/yul_ethdebug_optimize/err b/test/cmdlineTests/yul_ethdebug_optimize/err new file mode 100644 index 000000000000..7d66138755f9 --- /dev/null +++ b/test/cmdlineTests/yul_ethdebug_optimize/err @@ -0,0 +1 @@ +Error: Optimization (using --optimize) is not yet supported with ethdebug. diff --git a/test/cmdlineTests/yul_ethdebug_optimize/exit b/test/cmdlineTests/yul_ethdebug_optimize/exit new file mode 100644 index 000000000000..d00491fd7e5b --- /dev/null +++ b/test/cmdlineTests/yul_ethdebug_optimize/exit @@ -0,0 +1 @@ +1 diff --git a/test/cmdlineTests/yul_ethdebug_optimize/input.yul b/test/cmdlineTests/yul_ethdebug_optimize/input.yul new file mode 100644 index 000000000000..acd0b45f5335 --- /dev/null +++ b/test/cmdlineTests/yul_ethdebug_optimize/input.yul @@ -0,0 +1,18 @@ +object "object" { + code { + let a + let b + { + function z() -> y + { y := calldataload(0) } + a := z() + } + { + function z() -> y + { y := calldataload(0x20) } + b := z() + } + sstore(a, b) + } +} + diff --git a/test/cmdlineTests/yul_ethdebug_optimize_iroptimized/args b/test/cmdlineTests/yul_ethdebug_optimize_iroptimized/args new file mode 100644 index 000000000000..715f3fb4848b --- /dev/null +++ b/test/cmdlineTests/yul_ethdebug_optimize_iroptimized/args @@ -0,0 +1 @@ +--ethdebug --strict-assembly --optimize --ir-optimized \ No newline at end of file diff --git a/test/cmdlineTests/yul_ethdebug_optimize_iroptimized/err b/test/cmdlineTests/yul_ethdebug_optimize_iroptimized/err new file mode 100644 index 000000000000..7d66138755f9 --- /dev/null +++ b/test/cmdlineTests/yul_ethdebug_optimize_iroptimized/err @@ -0,0 +1 @@ +Error: Optimization (using --optimize) is not yet supported with ethdebug. diff --git a/test/cmdlineTests/yul_ethdebug_optimize_iroptimized/exit b/test/cmdlineTests/yul_ethdebug_optimize_iroptimized/exit new file mode 100644 index 000000000000..d00491fd7e5b --- /dev/null +++ b/test/cmdlineTests/yul_ethdebug_optimize_iroptimized/exit @@ -0,0 +1 @@ +1 diff --git a/test/cmdlineTests/yul_ethdebug_optimize_iroptimized/input.yul b/test/cmdlineTests/yul_ethdebug_optimize_iroptimized/input.yul new file mode 100644 index 000000000000..acd0b45f5335 --- /dev/null +++ b/test/cmdlineTests/yul_ethdebug_optimize_iroptimized/input.yul @@ -0,0 +1,18 @@ +object "object" { + code { + let a + let b + { + function z() -> y + { y := calldataload(0) } + a := z() + } + { + function z() -> y + { y := calldataload(0x20) } + b := z() + } + sstore(a, b) + } +} + diff --git a/test/libsolidity/StandardCompiler.cpp b/test/libsolidity/StandardCompiler.cpp index 3161eba2a868..ec3c7db1c847 100644 --- a/test/libsolidity/StandardCompiler.cpp +++ b/test/libsolidity/StandardCompiler.cpp @@ -1940,99 +1940,85 @@ BOOST_AUTO_TEST_CASE(ethdebug_excluded_from_wildcards) BOOST_AUTO_TEST_CASE(ethdebug_debug_info_ethdebug) { - static std::vector>>> tests{ + static std::vector>>> tests{ { generateStandardJson(false, Json::array({"ethdebug"}), Json::array({"*"})), - "'settings.debug.debugInfo' can only include 'ethdebug', if output 'ir', 'irOptimized', 'evm.bytecode.ethdebug', or 'evm.deployedBytecode.ethdebug' was selected.", std::nullopt, }, { generateStandardJson(true, Json::array({"ethdebug"}), Json::array({"*"})), - "'settings.debug.debugInfo' can only include 'ethdebug', if output 'ir', 'irOptimized', 'evm.bytecode.ethdebug', or 'evm.deployedBytecode.ethdebug' was selected.", std::nullopt, }, { generateStandardJson(false, Json::array({"ethdebug"}), Json::array({"evm.bytecode.ethdebug"})), - "'evm.bytecode.ethdebug' or 'evm.deployedBytecode.ethdebug' can only be selected as output, if 'viaIR' was set.", std::nullopt, }, { generateStandardJson(false, Json::array({"ethdebug"}), Json::array({"evm.deployedBytecode.ethdebug"})), - "'evm.bytecode.ethdebug' or 'evm.deployedBytecode.ethdebug' can only be selected as output, if 'viaIR' was set.", std::nullopt, }, { generateStandardJson(false, Json::array({"ethdebug"}), Json::array({"evm.bytecode.ethdebug", "evm.deployedBytecode.ethdebug"})), - "'evm.bytecode.ethdebug' or 'evm.deployedBytecode.ethdebug' can only be selected as output, if 'viaIR' was set.", std::nullopt, }, { - generateStandardJson(false, Json::array({"ethdebug"}), Json::array({"ir"})), - {}, + generateStandardJson(false, Json::array({"ethdebug"}), Json::array({"irOptimized"})), [](const Json& result) { return result.dump().find("/// ethdebug: enabled") != std::string::npos; } }, { - generateStandardJson(false, Json::array({"ethdebug"}), Json::array({"ir"})), - {}, + generateStandardJson(false, Json::array({"ethdebug"}), Json::array({"irOptimized"})), [](const Json& result) { return result.dump().find("/// ethdebug: enabled") != std::string::npos; } }, { - generateStandardJson(true, {}, Json::array({"ir", "evm.bytecode.ethdebug"})), - {}, + generateStandardJson(true, {}, Json::array({"irOptimized", "evm.bytecode.ethdebug"})), [](const Json& result) { return result.dump().find("/// ethdebug: enabled") != std::string::npos; } }, { - generateStandardJson(true, {}, Json::array({"ir", "evm.deployedBytecode.ethdebug"})), - {}, + generateStandardJson(true, {}, Json::array({"irOptimized", "evm.deployedBytecode.ethdebug"})), [](const Json& result) { return result.dump().find("/// ethdebug: enabled") != std::string::npos; } }, { - generateStandardJson(true, {}, Json::array({"ir", "evm.bytecode.ethdebug", "evm.deployedBytecode.ethdebug"})), - {}, + generateStandardJson(true, {}, Json::array({"irOptimized", "evm.bytecode.ethdebug", "evm.deployedBytecode.ethdebug"})), [](const Json& result) { return result.dump().find("/// ethdebug: enabled") != std::string::npos; } }, { - generateStandardJson(true, {}, Json::array({"ir", "evm.bytecode.ethdebug"})), - {}, + generateStandardJson(true, {}, Json::array({"irOptimized", "evm.bytecode.ethdebug"})), [](const Json& result) { return result.dump().find("/// ethdebug: enabled") != std::string::npos; } }, { - generateStandardJson(true, {}, Json::array({"ir", "evm.deployedBytecode.ethdebug"})), - {}, + generateStandardJson(true, {}, Json::array({"irOptimized", "evm.deployedBytecode.ethdebug"})), [](const Json& result) { return result.dump().find("/// ethdebug: enabled") != std::string::npos; } }, { - generateStandardJson(true, {}, Json::array({"ir", "evm.bytecode.ethdebug", "evm.deployedBytecode.ethdebug"})), - {}, + generateStandardJson(true, {}, Json::array({"irOptimized", "evm.bytecode.ethdebug", "evm.deployedBytecode.ethdebug"})), [](const Json& result) { return result.dump().find("/// ethdebug: enabled") != std::string::npos; } }, { - generateStandardJson(true, Json::array({"ethdebug"}), Json::array({"ir"}), YulCode()), - {}, + generateStandardJson(true, Json::array({"ethdebug"}), Json::array({"irOptimized"}), YulCode()), [](const Json& result) { return result.dump().find("/// ethdebug: enabled") != std::string::npos; @@ -2040,13 +2026,10 @@ BOOST_AUTO_TEST_CASE(ethdebug_debug_info_ethdebug) }, { generateStandardJson(true, Json::array({"ethdebug"}), Json::array({"irOptimized"}), YulCode()), - "Optimization is not yet supported with ethdebug.", {} }, { - generateStandardJson(true, Json::array({"ethdebugs"}), Json::array({"ir"}), YulCode()), - "Invalid value in settings.debug.debugInfo.", - {} + generateStandardJson(true, Json::array({"ethdebugs"}), Json::array({"irOptimized"}), YulCode()), {} }, { generateStandardJson( @@ -2059,17 +2042,14 @@ BOOST_AUTO_TEST_CASE(ethdebug_debug_info_ethdebug) {"fileB", "pragma solidity >=0.0; contract contractB { function f() public pure {} }"} }), true ), - "'settings.debug.debugInfo' can only include 'ethdebug', if output 'ir', 'irOptimized', 'evm.bytecode.ethdebug', or 'evm.deployedBytecode.ethdebug' was selected.", std::nullopt, }, { generateStandardJson(true, Json::array({"ethdebug"}), Json::array({"*"}), EvmAssemblyCode()), - "'settings.debug.debugInfo' 'ethdebug' is only supported for languages 'Solidity' and 'Yul'.", std::nullopt, }, { generateStandardJson(true, Json::array({"ethdebug"}), Json::array({"*"}), SolidityAstCode()), - "'settings.debug.debugInfo' 'ethdebug' is only supported for languages 'Solidity' and 'Yul'.", std::nullopt, }, }; @@ -2077,66 +2057,52 @@ BOOST_AUTO_TEST_CASE(ethdebug_debug_info_ethdebug) for (auto const& test: tests) { Json result = compiler.compile(std::get<0>(test)); - BOOST_REQUIRE(!std::get<1>(test).empty() ? result.contains("errors") : result.contains("contracts")); - if (!std::get<1>(test).empty()) - for (auto const& e: result["errors"]) - BOOST_REQUIRE(e["message"] == std::get<1>(test)); - if (std::get<2>(test).has_value()) - BOOST_REQUIRE((*std::get<2>(test))(result)); + if (std::get<1>(test).has_value()) + BOOST_REQUIRE((*std::get<1>(test))(result)); } } BOOST_AUTO_TEST_CASE(ethdebug_ethdebug_output) { - static std::vector>>> tests{ + static std::vector>>> tests{ { generateStandardJson(false, Json::array({"ethdebug"}), Json::array({"evm.bytecode.ethdebug"})), - "'evm.bytecode.ethdebug' or 'evm.deployedBytecode.ethdebug' can only be selected as output, if 'viaIR' was set.", std::nullopt }, { generateStandardJson(false, {}, Json::array({"evm.bytecode.ethdebug"})), - "'evm.bytecode.ethdebug' or 'evm.deployedBytecode.ethdebug' can only be selected as output, if 'viaIR' was set.", std::nullopt }, { generateStandardJson(false, Json::array({"ethdebug"}), Json::array({"evm.deployedBytecode.ethdebug"})), - "'evm.bytecode.ethdebug' or 'evm.deployedBytecode.ethdebug' can only be selected as output, if 'viaIR' was set.", std::nullopt }, { generateStandardJson(false, {}, Json::array({"evm.deployedBytecode.ethdebug"})), - "'evm.bytecode.ethdebug' or 'evm.deployedBytecode.ethdebug' can only be selected as output, if 'viaIR' was set.", std::nullopt }, { generateStandardJson(false, Json::array({"ethdebug"}), Json::array({"evm.bytecode.ethdebug", "evm.deployedBytecode.ethdebug"})), - "'evm.bytecode.ethdebug' or 'evm.deployedBytecode.ethdebug' can only be selected as output, if 'viaIR' was set.", std::nullopt }, { generateStandardJson(false, {}, Json::array({"evm.bytecode.ethdebug", "evm.deployedBytecode.ethdebug"})), - "'evm.bytecode.ethdebug' or 'evm.deployedBytecode.ethdebug' can only be selected as output, if 'viaIR' was set.", std::nullopt }, { generateStandardJson(true, Json::array({"location"}), Json::array({"evm.bytecode.ethdebug"})), - "'ethdebug' needs to be enabled in 'settings.debug.debugInfo', if 'evm.bytecode.ethdebug' or 'evm.deployedBytecode.ethdebug' was selected as output.", std::nullopt }, { generateStandardJson(true, Json::array({"location"}), Json::array({"evm.deployedBytecode.ethdebug"})), - "'ethdebug' needs to be enabled in 'settings.debug.debugInfo', if 'evm.bytecode.ethdebug' or 'evm.deployedBytecode.ethdebug' was selected as output.", std::nullopt }, { generateStandardJson(true, Json::array({"location"}), Json::array({"evm.bytecode.ethdebug", "evm.deployedBytecode.ethdebug"})), - "'ethdebug' needs to be enabled in 'settings.debug.debugInfo', if 'evm.bytecode.ethdebug' or 'evm.deployedBytecode.ethdebug' was selected as output.", std::nullopt }, { generateStandardJson(true, Json::array({"ethdebug"}), Json::array({"evm.bytecode.ethdebug"})), - {}, [](const Json& result) { return result.contains("ethdebug") && result["contracts"]["fileA"]["C"]["evm"]["bytecode"].contains("ethdebug"); @@ -2144,7 +2110,6 @@ BOOST_AUTO_TEST_CASE(ethdebug_ethdebug_output) }, { generateStandardJson(true, Json::array({"ethdebug"}), Json::array({"evm.deployedBytecode.ethdebug"})), - {}, [](const Json& result) { return result.contains("ethdebug") && result["contracts"]["fileA"]["C"]["evm"]["deployedBytecode"].contains("ethdebug"); @@ -2152,7 +2117,6 @@ BOOST_AUTO_TEST_CASE(ethdebug_ethdebug_output) }, { generateStandardJson(true, Json::array({"ethdebug"}), Json::array({"evm.bytecode.ethdebug", "evm.deployedBytecode.ethdebug"})), - {}, [](const Json& result) { return result.contains("ethdebug") && result["contracts"]["fileA"]["C"]["evm"]["deployedBytecode"].contains("ethdebug") && @@ -2161,7 +2125,6 @@ BOOST_AUTO_TEST_CASE(ethdebug_ethdebug_output) }, { generateStandardJson(true, {}, Json::array({"evm.bytecode.ethdebug"})), - {}, [](const Json& result) { return result.contains("ethdebug") && result["contracts"]["fileA"]["C"]["evm"]["bytecode"].contains("ethdebug"); @@ -2169,7 +2132,6 @@ BOOST_AUTO_TEST_CASE(ethdebug_ethdebug_output) }, { generateStandardJson(true, {}, Json::array({"evm.deployedBytecode.ethdebug"})), - {}, [](const Json& result) { return result.contains("ethdebug") && result["contracts"]["fileA"]["C"]["evm"]["deployedBytecode"].contains("ethdebug"); @@ -2177,7 +2139,6 @@ BOOST_AUTO_TEST_CASE(ethdebug_ethdebug_output) }, { generateStandardJson(true, {}, Json::array({"evm.bytecode.ethdebug", "evm.deployedBytecode.ethdebug"})), - {}, [](const Json& result) { return result.contains("ethdebug") && result["contracts"]["fileA"]["C"]["evm"]["deployedBytecode"].contains("ethdebug") && @@ -2186,7 +2147,6 @@ BOOST_AUTO_TEST_CASE(ethdebug_ethdebug_output) }, { generateStandardJson(true, {}, Json::array({"evm.bytecode.ethdebug", "ir"})), - {}, [](const Json& result) { return result.dump().find("/// ethdebug: enabled") != std::string::npos && result.contains("ethdebug") && result["contracts"]["fileA"]["C"]["evm"]["bytecode"].contains("ethdebug"); @@ -2194,7 +2154,6 @@ BOOST_AUTO_TEST_CASE(ethdebug_ethdebug_output) }, { generateStandardJson(true, {}, Json::array({"evm.deployedBytecode.ethdebug", "ir"})), - {}, [](const Json& result) { return result.dump().find("/// ethdebug: enabled") != std::string::npos && result.contains("ethdebug") && result["contracts"]["fileA"]["C"]["evm"]["deployedBytecode"].contains("ethdebug"); @@ -2202,23 +2161,14 @@ BOOST_AUTO_TEST_CASE(ethdebug_ethdebug_output) }, { generateStandardJson(true, {}, Json::array({"evm.bytecode.ethdebugs"})), - {}, - [](const Json& result) - { - return !result.contains("ethdebug"); - } + std::nullopt }, { generateStandardJson(true, {}, Json::array({"evm.deployedBytecode.ethdebugs"})), - {}, - [](const Json& result) - { - return !result.contains("ethdebug"); - } + std::nullopt }, { generateStandardJson(true, {}, Json::array({"evm.bytecode.ethdebug", "evm.deployedBytecode.ethdebug", "ir"})), - {}, [](const Json& result) { return result.dump().find("/// ethdebug: enabled") != std::string::npos && result.contains("ethdebug") && result["contracts"]["fileA"]["C"]["evm"]["deployedBytecode"].contains("ethdebug") && @@ -2227,7 +2177,6 @@ BOOST_AUTO_TEST_CASE(ethdebug_ethdebug_output) }, { generateStandardJson(true, {}, Json::array({"evm.bytecode.ethdebug", "ir"}), YulCode()), - {}, [](const Json& result) { return result.dump().find("/// ethdebug: enabled") != std::string::npos && result["contracts"]["fileA"]["object"]["evm"]["bytecode"].contains("ethdebug"); @@ -2235,17 +2184,14 @@ BOOST_AUTO_TEST_CASE(ethdebug_ethdebug_output) }, { generateStandardJson(true, {}, Json::array({"evm.deployedBytecode.ethdebug", "ir"}), YulCode()), - {"\"evm.deployedBytecode.ethdebug\" cannot be used for Yul."}, std::nullopt }, { generateStandardJson(true, {}, Json::array({"evm.bytecode.ethdebug", "evm.deployedBytecode.ethdebug", "ir"}), YulCode()), - {"\"evm.deployedBytecode.ethdebug\" cannot be used for Yul."}, std::nullopt }, { generateStandardJson(true, {}, Json::array({"evm.bytecode"})), - {}, [](const Json& result) { return result.dump().find("ethdebug") == std::string::npos; @@ -2253,7 +2199,6 @@ BOOST_AUTO_TEST_CASE(ethdebug_ethdebug_output) }, { generateStandardJson(true, {}, Json::array({"evm.deployedBytecode"})), - {}, [](const Json& result) { return result.dump().find("ethdebug") == std::string::npos; @@ -2270,7 +2215,6 @@ BOOST_AUTO_TEST_CASE(ethdebug_ethdebug_output) {"fileB", "pragma solidity >=0.0; contract contractB { function f() public pure {} }"} }), true ), - {}, [](const Json& result) { return result["contracts"]["fileA"]["contractA"]["evm"]["deployedBytecode"].contains("ethdebug") && @@ -2279,14 +2223,12 @@ BOOST_AUTO_TEST_CASE(ethdebug_ethdebug_output) } }; frontend::StandardCompiler compiler; - for (auto const& test: tests) + for (auto const& [standardJsonToCompile, optionalCheck]: tests) { - Json result = compiler.compile(std::get<0>(test)); - if (!std::get<1>(test).empty()) - for (auto const& e: result["errors"]) - BOOST_REQUIRE(e["message"] == std::get<1>(test)); - if (std::get<2>(test).has_value()) - BOOST_REQUIRE((*std::get<2>(test))(result)); + Json result = compiler.compile(standardJsonToCompile); + BOOST_REQUIRE(!optionalCheck.has_value() ? result.contains("errors") : result.contains("contracts")); + if (optionalCheck.has_value()) + BOOST_REQUIRE((*optionalCheck)(result)); } } diff --git a/test/solc/CommandLineInterface.cpp b/test/solc/CommandLineInterface.cpp index 17166268a656..adfd24b02b26 100644 --- a/test/solc/CommandLineInterface.cpp +++ b/test/solc/CommandLineInterface.cpp @@ -1424,97 +1424,72 @@ BOOST_AUTO_TEST_CASE(cli_ethdebug_incompatible_outputs) { TemporaryDirectory tempDir(TEST_CASE_NAME); createFilesWithParentDirs({tempDir.path() / "input.sol"}); - static std::vector, std::string>> tests{ + static std::vector> tests{ { {"solc", "--ethdebug", "--asm-json", tempDir.path().string() + "/input.sol"}, - "Error: --ethdebug / --ethdebug-runtime output can only be selected, if --via-ir was specified.\n" }, { {"solc", "--via-ir", "--ethdebug", "--asm-json", tempDir.path().string() + "/input.sol"}, - "Error: --ethdebug / --ethdebug-runtime output can only be used with --ir. Optimization is not yet supported with ethdebug, e.g. no support for --optimize / --ir-optimized yet.\n" }, { {"solc", "--via-ir", "--ethdebug", "--optimize", tempDir.path().string() + "/input.sol"}, - "Error: --ethdebug / --ethdebug-runtime output can only be used with --ir. Optimization is not yet supported with ethdebug, e.g. no support for --optimize / --ir-optimized yet.\n" - }, - { - {"solc", "--via-ir", "--ethdebug", "--ir-optimized", tempDir.path().string() + "/input.sol"}, - "Error: --ethdebug / --ethdebug-runtime output can only be used with --ir. Optimization is not yet supported with ethdebug, e.g. no support for --optimize / --ir-optimized yet.\n" }, { {"solc", "--via-ir", "--ethdebug", "--ir-ast-json", tempDir.path().string() + "/input.sol"}, - "Error: --ethdebug / --ethdebug-runtime output can only be used with --ir. Optimization is not yet supported with ethdebug, e.g. no support for --optimize / --ir-optimized yet.\n" }, { {"solc", "--via-ir", "--ethdebug", "--ir-optimized-ast-json", tempDir.path().string() + "/input.sol"}, - "Error: --ethdebug / --ethdebug-runtime output can only be used with --ir. Optimization is not yet supported with ethdebug, e.g. no support for --optimize / --ir-optimized yet.\n" }, { {"solc", "--ethdebug", "--import-asm-json", tempDir.path().string() + "/input.json"}, - "Error: Option --ethdebug is not supported with --import-asm-json.\n" }, { {"solc", "--via-ir", "--ethdebug", "--asm-json", tempDir.path().string() + "/input.sol"}, - "Error: --ethdebug / --ethdebug-runtime output can only be used with --ir. Optimization is not yet supported with ethdebug, e.g. no support for --optimize / --ir-optimized yet.\n" }, { {"solc", "--ethdebug-runtime", "--asm-json", tempDir.path().string() + "/input.sol"}, - "Error: --ethdebug / --ethdebug-runtime output can only be selected, if --via-ir was specified.\n" }, { {"solc", "--via-ir", "--ethdebug-runtime", "--asm-json", tempDir.path().string() + "/input.sol"}, - "Error: --ethdebug / --ethdebug-runtime output can only be used with --ir. Optimization is not yet supported with ethdebug, e.g. no support for --optimize / --ir-optimized yet.\n" }, { {"solc", "--via-ir", "--ethdebug-runtime", "--ir-ast-json", tempDir.path().string() + "/input.sol"}, - "Error: --ethdebug / --ethdebug-runtime output can only be used with --ir. Optimization is not yet supported with ethdebug, e.g. no support for --optimize / --ir-optimized yet.\n" }, { {"solc", "--via-ir", "--ethdebug-runtime", "--ir-optimized-ast-json", tempDir.path().string() + "/input.sol"}, - "Error: --ethdebug / --ethdebug-runtime output can only be used with --ir. Optimization is not yet supported with ethdebug, e.g. no support for --optimize / --ir-optimized yet.\n" }, { {"solc", "--ethdebug-runtime", "--import-asm-json", tempDir.path().string() + "/input.json"}, - "Error: Option --ethdebug-runtime is not supported with --import-asm-json.\n" }, { {"solc", "--via-ir", "--ethdebug-runtime", "--asm-json", tempDir.path().string() + "/input.sol"}, - "Error: --ethdebug / --ethdebug-runtime output can only be used with --ir. Optimization is not yet supported with ethdebug, e.g. no support for --optimize / --ir-optimized yet.\n" }, { {"solc", "--debug-info", "ethdebug", "--asm-json", tempDir.path().string() + "/input.sol"}, - "Error: --debug-info ethdebug can only be used with --ir and/or --ethdebug / --ethdebug-runtime. Optimization is not yet supported with ethdebug, e.g. no support for --optimize / --ir-optimized yet.\n" }, { {"solc", "--debug-info", "ethdebug", "--asm-json", tempDir.path().string() + "/input.sol"}, - "Error: --debug-info ethdebug can only be used with --ir and/or --ethdebug / --ethdebug-runtime. Optimization is not yet supported with ethdebug, e.g. no support for --optimize / --ir-optimized yet.\n" }, { {"solc", "--debug-info", "ethdebug", "--ir-ast-json", tempDir.path().string() + "/input.sol"}, - "Error: --debug-info ethdebug can only be used with --ir and/or --ethdebug / --ethdebug-runtime. Optimization is not yet supported with ethdebug, e.g. no support for --optimize / --ir-optimized yet.\n" }, { {"solc", "--debug-info", "ethdebug", "--ir-optimized-ast-json", tempDir.path().string() + "/input.sol"}, - "Error: --debug-info ethdebug can only be used with --ir and/or --ethdebug / --ethdebug-runtime. Optimization is not yet supported with ethdebug, e.g. no support for --optimize / --ir-optimized yet.\n" }, { {"solc", "--debug-info", "ethdebug", "--import-asm-json", tempDir.path().string() + "/input.json"}, - "Error: Option --debug-info is not supported with --import-asm-json.\n" }, { {"solc", "--debug-info", "ethdebug", "--import-asm-json", tempDir.path().string() + "/input.json"}, - "Error: Option --debug-info is not supported with --import-asm-json.\n" }, { {"solc", "--debug-info", "ethdebug", "--asm-json", tempDir.path().string() + "/input.json"}, - "Error: --debug-info ethdebug can only be used with --ir and/or --ethdebug / --ethdebug-runtime. Optimization is not yet supported with ethdebug, e.g. no support for --optimize / --ir-optimized yet.\n" } }; for (auto const& test: tests) { - OptionsReaderAndMessages result = runCLI(test.first, ""); + OptionsReaderAndMessages result = runCLI(test, ""); BOOST_REQUIRE(!result.success); - BOOST_CHECK_EQUAL(result.stderrContent, test.second); } } @@ -1522,41 +1497,33 @@ BOOST_AUTO_TEST_CASE(cli_ethdebug_incompatible_input_modes) { TemporaryDirectory tempDir(TEST_CASE_NAME); createFilesWithParentDirs({tempDir.path() / "input.json"}); - static std::vector, std::string>> tests{ + static std::vector> tests{ { {"solc", "--ethdebug", "--import-asm-json", tempDir.path().string() + "/input.json"}, - "Error: Option --ethdebug is not supported with --import-asm-json.\n" }, { {"solc", "--ethdebug", "--via-ir", "--import-asm-json", tempDir.path().string() + "/input.json"}, - "Error: The following options are not supported in the current input mode: --via-ir\n" }, { {"solc", "--ethdebug", "--import-asm-json", tempDir.path().string() + "/input.json"}, - "Error: Option --ethdebug is not supported with --import-asm-json.\n" }, { {"solc", "--debug-info", "ethdebug", "--import-asm-json", tempDir.path().string() + "/input.json"}, - "Error: Option --debug-info is not supported with --import-asm-json.\n" }, { {"solc", "--ethdebug", "--import-ast", tempDir.path().string() + "/input.json"}, - "Error: --ethdebug / --ethdebug-runtime output can only be selected, if --via-ir was specified.\n" }, { {"solc", "--ethdebug", "--via-ir", "--import-ast", tempDir.path().string() + "/input.json"}, - "Error: Invalid input mode for --debug-info ethdebug / --ethdebug / --ethdebug-runtime.\n" }, { {"solc", "--debug-info", "ethdebug", "--ir", "--import-ast", tempDir.path().string() + "/input.json"}, - "Error: Invalid input mode for --debug-info ethdebug / --ethdebug / --ethdebug-runtime.\n" } }; for (auto const& test: tests) { - OptionsReaderAndMessages result = runCLI(test.first, ""); + OptionsReaderAndMessages result = runCLI(test, ""); BOOST_REQUIRE(!result.success); - BOOST_CHECK_EQUAL(result.stderrContent, test.second); } } @@ -1565,121 +1532,98 @@ BOOST_AUTO_TEST_CASE(cli_ethdebug_debug_info_ethdebug) TemporaryDirectory tempDir(TEST_CASE_NAME); createFilesWithParentDirs({tempDir.path() / "input.sol"}, "pragma solidity >=0.0; contract C { function f() public pure {} }"); createFilesWithParentDirs({tempDir.path() / "input.yul"}, "{}"); - static std::vector, std::vector, std::vector>> tests{ + static std::vector> erroneousCLIFlagCombinations{ { {"solc", "--debug-info", "ethdebug", tempDir.path().string() + "/input.sol"}, - {"Error: --debug-info ethdebug can only be used with --ir and/or --ethdebug / --ethdebug-runtime. Optimization is not yet supported with ethdebug, e.g. no support for --optimize / --ir-optimized yet.\n"}, - {}, - }, - { - {"solc", "--debug-info", "ethdebug", "--ir", tempDir.path().string() + "/input.sol"}, - {}, - {"/// ethdebug: enabled"}, }, { {"solc", "--debug-info", "ethdebug", "--ir-optimized", tempDir.path().string() + "/input.sol"}, - {"Error: --debug-info ethdebug can only be used with --ir and/or --ethdebug / --ethdebug-runtime. Optimization is not yet supported with ethdebug, e.g. no support for --optimize / --ir-optimized yet.\n"}, - {}, }, { {"solc", "--debug-info", "ethdebug", "--optimize", tempDir.path().string() + "/input.sol"}, - {"Error: --debug-info ethdebug can only be used with --ir and/or --ethdebug / --ethdebug-runtime. Optimization is not yet supported with ethdebug, e.g. no support for --optimize / --ir-optimized yet.\n"}, - {}, }, { {"solc", "--debug-info", "ethdebug", "--ethdebug", tempDir.path().string() + "/input.sol"}, - {"Error: --ethdebug / --ethdebug-runtime output can only be selected, if --via-ir was specified.\n"}, - {}, - }, - { - {"solc", "--debug-info", "ethdebug", "--ethdebug", "--via-ir", tempDir.path().string() + "/input.sol"}, - {}, - {"======= Debug Data (ethdebug/format/info/resources) =======", "Debug Data (ethdebug/format/program):"}, - }, - { - {"solc", "--debug-info", "ethdebug", "--ethdebug-runtime", "--via-ir", tempDir.path().string() + "/input.sol"}, - {}, - {"======= Debug Data (ethdebug/format/info/resources) =======", "Debug Data of the runtime part (ethdebug/format/program):"}, - }, - { - {"solc", "--debug-info", "ethdebug", "--strict-assembly", tempDir.path().string() + "/input.yul"}, - {}, - {"/// ethdebug: enabled", "Pretty printed source", "Binary representation", "Text representation"}, - }, - { - {"solc", "--ethdebug", "--strict-assembly", tempDir.path().string() + "/input.yul"}, - {}, - {"======= Debug Data (ethdebug/format/info/resources) =======", "Debug Data (ethdebug/format/program):"}, }, { {"solc", "--ethdebug-runtime", "--strict-assembly", tempDir.path().string() + "/input.yul"}, - {"Error: The following outputs are not supported in assembler mode: --ethdebug-runtime.\n"}, - {}, }, { {"solc", "--ethdebug", "--ethdebug-runtime", "--strict-assembly", tempDir.path().string() + "/input.yul"}, - {"Error: The following outputs are not supported in assembler mode: --ethdebug-runtime.\n"}, - {}, }, { {"solc", "--debug-info", "ethdebug", "--ethdebug", tempDir.path().string() + "/input.sol"}, - {"Error: --ethdebug / --ethdebug-runtime output can only be selected, if --via-ir was specified.\n"}, - {}, }, { {"solc", "--debug-info", "ethdebug", "--ethdebug-runtime", tempDir.path().string() + "/input.sol"}, - {"Error: --ethdebug / --ethdebug-runtime output can only be selected, if --via-ir was specified.\n"}, - {}, }, { {"solc", "--debug-info", "ethdebug", "--ethdebug", "--ethdebug-runtime", tempDir.path().string() + "/input.sol"}, - {"Error: --ethdebug / --ethdebug-runtime output can only be selected, if --via-ir was specified.\n"}, - {}, - }, - { - {"solc", "--debug-info", "ethdebug", "--ethdebug", "--ethdebug-runtime", "--via-ir", tempDir.path().string() + "/input.sol"}, - {}, - {"======= Debug Data (ethdebug/format/info/resources) =======", "Debug Data (ethdebug/format/program):", "Debug Data of the runtime part (ethdebug/format/program):"}, }, { {"solc", "--debug-info", "location", "--ethdebug", "--via-ir", tempDir.path().string() + "/input.sol"}, - {"Error: --debug-info must contain ethdebug, when compiling with --ethdebug / --ethdebug-runtime.\n"}, - {}, }, { {"solc", "--debug-info", "location", "--ethdebug-runtime", "--via-ir", tempDir.path().string() + "/input.sol"}, - {"Error: --debug-info must contain ethdebug, when compiling with --ethdebug / --ethdebug-runtime.\n"}, - {}, }, { {"solc", "--debug-info", "location", "--ethdebug", "--ethdebug-runtime", "--via-ir", tempDir.path().string() + "/input.sol"}, - {"Error: --debug-info must contain ethdebug, when compiling with --ethdebug / --ethdebug-runtime.\n"}, - {}, }, { {"solc", "--debug-info", "all", "--ethdebug", "--via-ir", tempDir.path().string() + "/input.sol"}, - {"Error: --debug-info must contain ethdebug, when compiling with --ethdebug / --ethdebug-runtime.\n"}, - {}, }, { {"solc", "--debug-info", "all", "--ethdebug-runtime", "--via-ir", tempDir.path().string() + "/input.sol"}, - {"Error: --debug-info must contain ethdebug, when compiling with --ethdebug / --ethdebug-runtime.\n"}, - {}, }, { {"solc", "--debug-info", "all", "--ethdebug", "--ethdebug-runtime", "--via-ir", tempDir.path().string() + "/input.sol"}, - {"Error: --debug-info must contain ethdebug, when compiling with --ethdebug / --ethdebug-runtime.\n"}, - {}, }, }; - for (auto const& test: tests) + static std::vector> supportedCLIFlagCombinations{ + { + {"solc", "--debug-info", "ethdebug", "--ir", tempDir.path().string() + "/input.sol"}, + }, + { + {"solc", "--debug-info", "ethdebug", "--ethdebug", "--via-ir", tempDir.path().string() + "/input.sol"}, + }, + { + { + "solc", + "--debug-info", + "ethdebug", + "--ethdebug-runtime", + "--via-ir", + tempDir.path().string() + "/input.sol" + }, + }, + { + {"solc", "--debug-info", "ethdebug", "--strict-assembly", tempDir.path().string() + "/input.yul"}, + }, + { + {"solc", "--ethdebug", "--strict-assembly", tempDir.path().string() + "/input.yul"}, + }, + { + { + "solc", + "--debug-info", + "ethdebug", + "--ethdebug", + "--ethdebug-runtime", + "--via-ir", + tempDir.path().string() + "/input.sol" + }, + }, + }; + + for (auto const& test: erroneousCLIFlagCombinations) { - OptionsReaderAndMessages result{runCLI(std::get<0>(test), "")}; - BOOST_REQUIRE(!std::get<1>(test).empty() ? !result.success : result.success); - for (auto const& error : std::get<1>(test)) - BOOST_REQUIRE(result.stderrContent == error); - for (auto const& output : std::get<2>(test)) - BOOST_REQUIRE(result.stdoutContent.find(output) != std::string::npos); + OptionsReaderAndMessages result{runCLI(test, "")}; + BOOST_REQUIRE(!result.success); + } + for (auto const& test: supportedCLIFlagCombinations) + { + OptionsReaderAndMessages result{runCLI(test, "")}; + BOOST_REQUIRE(result.success); } } @@ -1687,91 +1631,69 @@ BOOST_AUTO_TEST_CASE(cli_ethdebug_ethdebug_output) { TemporaryDirectory tempDir(TEST_CASE_NAME); createFilesWithParentDirs({tempDir.path() / "input.sol"}, "pragma solidity >=0.0; contract C { function f() public pure {} }"); - static std::vector, std::vector, std::vector>> tests{ + static std::vector> erroneousCLIFlagCombinations{ + { + {"solc", "--ethdebug", "--ethdebug-runtime", "--via-ir", "--ir-optimized", "--optimize", tempDir.path().string() + "/input.sol"}, + }, + { + { + "solc", + "--ethdebug-runtime", + "--via-ir", + "--ir-optimized", + "--optimize", + tempDir.path().string() + "/input.sol" + }, + }, + { + {"solc", "--ethdebug", "--via-ir", "--ir-optimized", "--optimize", tempDir.path().string() + "/input.sol"}, + }, { {"solc", "--ethdebug", tempDir.path().string() + "/input.sol"}, - {"Error: --ethdebug / --ethdebug-runtime output can only be selected, if --via-ir was specified.\n"}, - {}, }, { {"solc", "--ethdebug", "--ethdebug-runtime", tempDir.path().string() + "/input.sol"}, - {"Error: --ethdebug / --ethdebug-runtime output can only be selected, if --via-ir was specified.\n"}, - {}, }, { {"solc", "--ethdebug-runtime", tempDir.path().string() + "/input.sol"}, - {"Error: --ethdebug / --ethdebug-runtime output can only be selected, if --via-ir was specified.\n"}, - {}, }, + }; + static std::vector> supportedCLIFlagCombinations{ { {"solc", "--ethdebug", "--via-ir", tempDir.path().string() + "/input.sol"}, - {}, - {"======= Debug Data (ethdebug/format/info/resources) =======", "Debug Data (ethdebug/format/program)"}, }, { {"solc", "--ethdebug-runtime", "--via-ir", tempDir.path().string() + "/input.sol"}, - {}, - {"======= Debug Data (ethdebug/format/info/resources) =======", "Debug Data of the runtime part (ethdebug/format/program)"}, }, { {"solc", "--ethdebug", "--ethdebug-runtime", "--via-ir", tempDir.path().string() + "/input.sol"}, - {}, - {"======= Debug Data (ethdebug/format/info/resources) =======", "Debug Data (ethdebug/format/program)", "Debug Data of the runtime part (ethdebug/format/program)"}, }, { {"solc", "--ethdebug", "--via-ir", "--ir", tempDir.path().string() + "/input.sol"}, - {}, - {"======= Debug Data (ethdebug/format/info/resources) =======", "Debug Data (ethdebug/format/program)", "/// ethdebug: enabled"}, }, { {"solc", "--ethdebug-runtime", "--via-ir", "--ir", tempDir.path().string() + "/input.sol"}, - {}, - {"======= Debug Data (ethdebug/format/info/resources) =======", "Debug Data of the runtime part (ethdebug/format/program)", "/// ethdebug: enabled"}, }, { {"solc", "--ethdebug", "--ethdebug-runtime", "--via-ir", "--ir", tempDir.path().string() + "/input.sol"}, - {}, - {"======= Debug Data (ethdebug/format/info/resources) =======", "Debug Data (ethdebug/format/program)", "Debug Data of the runtime part (ethdebug/format/program)", "/// ethdebug: enabled"}, }, { {"solc", "--ethdebug", "--via-ir", "--ir-optimized", tempDir.path().string() + "/input.sol"}, - {"Error: --ethdebug / --ethdebug-runtime output can only be used with --ir. Optimization is not yet supported with ethdebug, e.g. no support for --optimize / --ir-optimized yet.\n"}, - {}, }, { {"solc", "--ethdebug-runtime", "--via-ir", "--ir-optimized", tempDir.path().string() + "/input.sol"}, - {"Error: --ethdebug / --ethdebug-runtime output can only be used with --ir. Optimization is not yet supported with ethdebug, e.g. no support for --optimize / --ir-optimized yet.\n"}, - {}, - }, - { - {"solc", "--ethdebug", "--ethdebug-runtime", "--via-ir", "--ir-optimized", tempDir.path().string() + "/input.sol"}, - {"Error: --ethdebug / --ethdebug-runtime output can only be used with --ir. Optimization is not yet supported with ethdebug, e.g. no support for --optimize / --ir-optimized yet.\n"}, - {}, - }, - { - {"solc", "--ethdebug", "--via-ir", "--ir-optimized", "--optimize", tempDir.path().string() + "/input.sol"}, - {"Error: --ethdebug / --ethdebug-runtime output can only be used with --ir. Optimization is not yet supported with ethdebug, e.g. no support for --optimize / --ir-optimized yet.\n"}, - {}, - }, - { - {"solc", "--ethdebug-runtime", "--via-ir", "--ir-optimized", "--optimize", tempDir.path().string() + "/input.sol"}, - {"Error: --ethdebug / --ethdebug-runtime output can only be used with --ir. Optimization is not yet supported with ethdebug, e.g. no support for --optimize / --ir-optimized yet.\n"}, - {}, - }, - { - {"solc", "--ethdebug", "--ethdebug-runtime", "--via-ir", "--ir-optimized", "--optimize", tempDir.path().string() + "/input.sol"}, - {"Error: --ethdebug / --ethdebug-runtime output can only be used with --ir. Optimization is not yet supported with ethdebug, e.g. no support for --optimize / --ir-optimized yet.\n"}, - {}, }, }; - for (auto const& test: tests) + + for (auto const& test: erroneousCLIFlagCombinations) { - OptionsReaderAndMessages result{runCLI(std::get<0>(test), "")}; - BOOST_REQUIRE(!std::get<1>(test).empty() ? !result.success : result.success); - for (auto const& error : std::get<1>(test)) - BOOST_REQUIRE(result.stderrContent == error); - for (auto const& output : std::get<2>(test)) - BOOST_REQUIRE(result.stdoutContent.find(output) != std::string::npos); + OptionsReaderAndMessages result{runCLI(test, "")}; + BOOST_REQUIRE(!result.success); + } + for (auto const& test: supportedCLIFlagCombinations) + { + OptionsReaderAndMessages result{runCLI(test, "")}; + BOOST_REQUIRE(result.success); } } From 4d96648017c89145a8ff56f4860c7db2d1315440 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Tue, 4 Feb 2025 11:00:26 +0100 Subject: [PATCH 0832/1022] Yul: Introduces ASTNodeRegistry --- libyul/ASTLabelRegistry.cpp | 166 ++++++++++++++++++++++++++++++++++++ libyul/ASTLabelRegistry.h | 110 ++++++++++++++++++++++++ libyul/CMakeLists.txt | 2 + 3 files changed, 278 insertions(+) create mode 100644 libyul/ASTLabelRegistry.cpp create mode 100644 libyul/ASTLabelRegistry.h diff --git a/libyul/ASTLabelRegistry.cpp b/libyul/ASTLabelRegistry.cpp new file mode 100644 index 000000000000..8f26f2f5be8d --- /dev/null +++ b/libyul/ASTLabelRegistry.cpp @@ -0,0 +1,166 @@ +/* + This file is part of solidity. + + solidity is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + solidity is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with solidity. If not, see . +*/ +// SPDX-License-Identifier: GPL-3.0 + +#include + +#include + +#include + +using namespace solidity::yul; + +ASTLabelRegistry::ASTLabelRegistry(): m_labels{""}, m_idToLabelMapping{0} {} + +ASTLabelRegistry::ASTLabelRegistry(std::vector _labels, std::vector _idToLabelMapping): + m_labels(std::move(_labels)), + m_idToLabelMapping(std::move(_idToLabelMapping)) +{ + yulAssert(!m_labels.empty()); + yulAssert(m_labels[0].empty()); + yulAssert(!m_idToLabelMapping.empty()); + yulAssert(m_idToLabelMapping[0] == 0); + // using vector over vector, as the latter is optimized for space-efficiency + std::vector labelVisited (m_labels.size(), false); + size_t numLabels = 0; + for (auto const& labelIndex: m_idToLabelMapping) + { + if (labelIndex == ghostLabelIndex()) + continue; + yulAssert(labelIndex < m_labels.size()); + // it is possible to have multiple references to the empty label index + // only the id == 0 refers to an actually empty label, otherwise the LabelID is unused + yulAssert( + labelIndex == 0 || !labelVisited[labelIndex], + fmt::format("LabelID {} (label \"{}\") is not unique.", labelIndex, m_labels[labelIndex]) + ); + labelVisited[labelIndex] = true; + if (labelIndex >= 1) + ++numLabels; + } + yulAssert(numLabels + 1 == m_labels.size(), "Unreferenced labels present."); +} + +ASTLabelRegistry::LabelID ASTLabelRegistry::maxID() const +{ + yulAssert(!m_idToLabelMapping.empty()); + return m_idToLabelMapping.size() - 1; +} + +size_t ASTLabelRegistry::idToLabelIndex(LabelID const _id) const +{ + yulAssert(_id < m_idToLabelMapping.size()); + return m_idToLabelMapping[_id]; +} + +std::string_view ASTLabelRegistry::operator[](LabelID const _id) const +{ + auto const labelIndex = idToLabelIndex(_id); + yulAssert(labelIndex != ghostLabelIndex(), "Ghost ids are not explicitly labelled in the registry."); + // not using `unused` here, as we already have evaluated the label index + // an id is unused if it is not id == 0 (empty label) but points at label index 0 + yulAssert(empty(_id) || labelIndex != 0, "Can only query ids that are not unused"); + return m_labels[labelIndex]; +} + +bool ASTLabelRegistry::ghost(LabelID const _id) const +{ + return idToLabelIndex(_id) == ghostLabelIndex(); +} + +bool ASTLabelRegistry::unused(LabelID const _id) const +{ + return !empty(_id) && idToLabelIndex(_id) == 0; +} + +std::optional ASTLabelRegistry::findIDForLabel(std::string_view const _label) const +{ + for (LabelID id = 0; id <= maxID(); ++id) + if ((*this)[id] == _label) + return id; + return std::nullopt; +} + +std::tuple ASTLabelRegistryBuilder::DefinedLabels::tryInsert( + std::string_view const _label, + ASTLabelRegistry::LabelID const _id +) +{ + auto const [it, emplaced] = m_labelToIDMapping.try_emplace(std::string{_label}, _id); + return std::make_tuple(it->second, emplaced); +} + +ASTLabelRegistryBuilder::ASTLabelRegistryBuilder(): + m_nextID(1) +{} + +ASTLabelRegistryBuilder::ASTLabelRegistryBuilder(ASTLabelRegistry const& _existingRegistry) +{ + yulAssert(!_existingRegistry.labels().empty() && _existingRegistry[0].empty()); + for (size_t id = 1; id <= _existingRegistry.maxID(); ++id) + { + if (!ASTLabelRegistry::empty(id) && !_existingRegistry.unused(id)) + { + // ghost ids are not added to the map as they are not explicitly labeled + if (_existingRegistry.ghost(id)) + m_ghosts.push_back(id); + else + { + auto const [_, inserted] = m_definedLabels.tryInsert(_existingRegistry[id], id); + yulAssert(inserted, "Existing registry cannot contain duplicate labels."); + } + } + } + m_nextID = _existingRegistry.maxID() + 1; +} + +ASTLabelRegistry::LabelID ASTLabelRegistryBuilder::define(std::string_view const _label) +{ + auto const [id, inserted] = m_definedLabels.tryInsert(_label, m_nextID); + if (inserted) + m_nextID++; + return id; +} + +ASTLabelRegistry::LabelID ASTLabelRegistryBuilder::addGhost() +{ + m_ghosts.push_back(m_nextID); + return m_nextID++; +} + +ASTLabelRegistry ASTLabelRegistryBuilder::build() const +{ + auto const& labelToIDMapping = m_definedLabels.labelToIDMapping(); + yulAssert(labelToIDMapping.contains("")); + yulAssert(labelToIDMapping.at("") == 0); + + std::vector labels{""}; + labels.reserve(labelToIDMapping.size()); + std::vector idToLabelMapping( m_nextID + 1, 0); + yulAssert(!idToLabelMapping.empty(), "Mapping must at least contain empty label"); + for (auto const& [label, id]: labelToIDMapping) + { + if (ASTLabelRegistry::empty(id)) + continue; + + labels.emplace_back(label); + idToLabelMapping[id] = labels.size() - 1; + } + for (auto const ghostId: m_ghosts) + idToLabelMapping[ghostId] = ASTLabelRegistry::ghostLabelIndex(); + return ASTLabelRegistry{std::move(labels), std::move(idToLabelMapping)}; +} diff --git a/libyul/ASTLabelRegistry.h b/libyul/ASTLabelRegistry.h new file mode 100644 index 000000000000..cb7c405af9fa --- /dev/null +++ b/libyul/ASTLabelRegistry.h @@ -0,0 +1,110 @@ +/* + This file is part of solidity. + + solidity is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + solidity is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with solidity. If not, see . +*/ +// SPDX-License-Identifier: GPL-3.0 + +#pragma once + +#include +#include +#include +#include +#include +#include + +namespace solidity::yul +{ + +/// Instances of the `ASTLabelRegistry` are immutable containers describing a labelling of nodes inside the AST. +/// Each element of the AST that possesses a label has a `ASTLabelRegistry::LabelID`, with which the label can +/// be queried in O(1). +/// Preferred way of creating instances is via `ASTLabelRegistryBuilder` when parsing/importing and +/// via `LabelIDDispenser` during/after optimization. +/// Note: The id == 0 always corresponds to the empty label. Other ids can point at the label index 0, which means that +/// they are unused. To check, whether an id is unused, the `unused` function can be used. +/// Note: There is a special case of ghost ids, which are added during CFG construction. +/// They do not directly correspond to elements of an AST but live inside the CFG. They are assigned the +/// special `std::numeric_limits::max` label index. The labels themselves are - if required - generated from +/// the CFG. +class ASTLabelRegistry +{ +public: + /// unsafe to use from a different registry instance, it is up to the user to safeguard against this + using LabelID = size_t; + + ASTLabelRegistry(); + ASTLabelRegistry(std::vector _labels, std::vector _idToLabelMapping); + + std::string_view operator[](LabelID _id) const; + + static bool constexpr empty(LabelID const _id) { return _id == emptyID(); } + static LabelID constexpr emptyID() { return 0; } + static size_t constexpr ghostLabelIndex() { return std::numeric_limits::max(); } + + bool unused(LabelID _id) const; + bool ghost(LabelID _id) const; + std::vector const& labels() const { return m_labels; } + LabelID maxID() const; + + size_t idToLabelIndex(LabelID _id) const; + /// this is a potentially expensive operation + std::optional findIDForLabel(std::string_view _label) const; + +private: + /// All Yul AST labels present in the registry. + /// Always contains at least an empty label which also serves as a null-state for non-contiguous ID ranges. + /// All items must be unique. + std::vector const m_labels; + + /// Assignment of labels to `LabelID`s. Indices are `LabelID`s and values are indices into `m_labels`. + /// Every label except empty always has exactly one `LabelID` pointing at it. + /// The empty label has one canonical ID, but unused IDs point to it as well. + std::vector const m_idToLabelMapping; +}; + +/// Produces instances of `ASTLabelRegistry`. Preferably used during parsing/importing. +class ASTLabelRegistryBuilder +{ +public: + ASTLabelRegistryBuilder(); + /// Creates a new builder taking an already existing label registry into account. + /// Unused IDs are skipped, ghost IDs are recorded and inserted back into the newly built registry. + explicit ASTLabelRegistryBuilder(ASTLabelRegistry const& _existingRegistry); + + ASTLabelRegistry::LabelID define(std::string_view _label); + ASTLabelRegistry::LabelID addGhost(); + + /// Creates a new label registry based on what was defined and potentially an existing registry. If such registry + /// was provided, all labels (including unused and ghost label IDs) carry over. + ASTLabelRegistry build() const; + +private: + class DefinedLabels + { + public: + std::tuple tryInsert(std::string_view _label, ASTLabelRegistry::LabelID _id); + auto const& labelToIDMapping() const { return m_labelToIDMapping; } + + private: + std::map> m_labelToIDMapping = {{"", 0}}; + }; + + DefinedLabels m_definedLabels; + std::vector m_ghosts; + size_t m_nextID{}; +}; + +} diff --git a/libyul/CMakeLists.txt b/libyul/CMakeLists.txt index cc4c5051c4bd..fc3302a82332 100644 --- a/libyul/CMakeLists.txt +++ b/libyul/CMakeLists.txt @@ -7,6 +7,8 @@ add_library(yul AST.h AST.cpp ASTForward.h + ASTLabelRegistry.cpp + ASTLabelRegistry.h AsmJsonConverter.h AsmJsonConverter.cpp AsmJsonImporter.h From 9c0098b221556e4df56c892d7280bfb5b7e10c0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Wed, 4 Dec 2024 07:26:26 +0100 Subject: [PATCH 0833/1022] Always include a message when throwing a FatalError - It's not shown to the user but it's still useful because we can include it in the assert that gets triggered when a fatal error gets thrown but not reported. --- liblangutil/ErrorReporter.cpp | 9 ++++++--- libsolidity/analysis/TypeChecker.cpp | 4 ++-- libsolidity/parsing/Parser.cpp | 2 +- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/liblangutil/ErrorReporter.cpp b/liblangutil/ErrorReporter.cpp index 10d7f1d116a6..9f3e293f53da 100644 --- a/liblangutil/ErrorReporter.cpp +++ b/liblangutil/ErrorReporter.cpp @@ -23,6 +23,9 @@ #include #include + +#include + #include #include @@ -121,7 +124,7 @@ bool ErrorReporter::checkForExcessiveErrors(Error::Type _type) if (m_errorCount > c_maxErrorsAllowed) { m_errorList.push_back(std::make_shared(4013_error, Error::Type::Warning, "There are more than 256 errors. Aborting.")); - BOOST_THROW_EXCEPTION(FatalError()); + solThrow(FatalError, "There are more than 256 errors. Aborting."); } } @@ -131,13 +134,13 @@ bool ErrorReporter::checkForExcessiveErrors(Error::Type _type) void ErrorReporter::fatalError(ErrorId _error, Error::Type _type, SourceLocation const& _location, SecondarySourceLocation const& _secondaryLocation, std::string const& _description) { error(_error, _type, _location, _secondaryLocation, _description); - BOOST_THROW_EXCEPTION(FatalError()); + solThrow(FatalError, _description); } void ErrorReporter::fatalError(ErrorId _error, Error::Type _type, SourceLocation const& _location, std::string const& _description) { error(_error, _type, _location, _description); - BOOST_THROW_EXCEPTION(FatalError()); + solThrow(FatalError, _description); } ErrorList const& ErrorReporter::errors() const diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp index a0d21744de88..e56ee157d94d 100644 --- a/libsolidity/analysis/TypeChecker.cpp +++ b/libsolidity/analysis/TypeChecker.cpp @@ -1327,7 +1327,7 @@ bool TypeChecker::visit(VariableDeclarationStatement const& _statement) solAssert(m_errorReporter.hasErrors(), "Should have errors!"); for (auto const& var: variables) if (var && !var->annotation().type) - BOOST_THROW_EXCEPTION(FatalError()); + solThrow(FatalError, "Type checker failed to determine types of all variables within the declaration."); } return false; @@ -1380,7 +1380,7 @@ bool TypeChecker::visit(Conditional const& _conditional) commonType = falseType; if (!trueType && !falseType) - BOOST_THROW_EXCEPTION(FatalError()); + solThrow(FatalError, "Both sides of the ternary expression have invalid types."); else if (trueType && falseType) { commonType = Type::commonType(trueType, falseType); diff --git a/libsolidity/parsing/Parser.cpp b/libsolidity/parsing/Parser.cpp index dce729de408b..720ff2afe4ed 100644 --- a/libsolidity/parsing/Parser.cpp +++ b/libsolidity/parsing/Parser.cpp @@ -1539,7 +1539,7 @@ ASTPointer Parser::parseInlineAssembly(ASTPointer con yul::Parser asmParser(m_errorReporter, dialect); std::shared_ptr ast = asmParser.parseInline(m_scanner); if (ast == nullptr) - BOOST_THROW_EXCEPTION(FatalError()); + solThrow(FatalError, "Failed to parse inline assembly."); location.end = nativeLocationOf(ast->root()).end; return std::make_shared(nextID(), location, _docString, dialect, std::move(flags), ast); From 04605d752889125f6c3d064ecd781fe733abf830 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Fri, 31 Jan 2025 20:12:06 +0100 Subject: [PATCH 0834/1022] Report more info when an unreported fatal error is caught --- libsolidity/analysis/NameAndTypeResolver.cpp | 27 +++++++++++++++----- libsolidity/interface/CompilerStack.cpp | 18 ++++++++++--- libsolidity/parsing/Parser.cpp | 9 +++++-- libyul/AsmAnalysis.cpp | 9 +++++-- libyul/AsmParser.cpp | 9 +++++-- libyul/ObjectParser.cpp | 9 +++++-- 6 files changed, 63 insertions(+), 18 deletions(-) diff --git a/libsolidity/analysis/NameAndTypeResolver.cpp b/libsolidity/analysis/NameAndTypeResolver.cpp index 2fb6a6162405..2d55b46fc9f7 100644 --- a/libsolidity/analysis/NameAndTypeResolver.cpp +++ b/libsolidity/analysis/NameAndTypeResolver.cpp @@ -61,9 +61,14 @@ bool NameAndTypeResolver::registerDeclarations(SourceUnit& _sourceUnit, ASTNode { DeclarationRegistrationHelper registrar(m_scopes, _sourceUnit, m_errorReporter, m_globalContext, _currentScope); } - catch (langutil::FatalError const& error) + catch (FatalError const&) { - solAssert(m_errorReporter.hasErrors(), "Unreported fatal error: "s + error.what()); + if (!m_errorReporter.hasErrors()) + { + std::cerr << "Unreported fatal error:" << std::endl; + std::cerr << boost::current_exception_diagnostic_information() << std::endl; + solAssert(false, "Unreported fatal error."); + } return false; } return true; @@ -135,9 +140,14 @@ bool NameAndTypeResolver::resolveNamesAndTypes(SourceUnit& _source) return false; } } - catch (langutil::FatalError const& error) + catch (FatalError const&) { - solAssert(m_errorReporter.hasErrors(), "Unreported fatal error: "s + error.what()); + if (!m_errorReporter.hasErrors()) + { + std::cerr << "Unreported fatal error:" << std::endl; + std::cerr << boost::current_exception_diagnostic_information() << std::endl; + solAssert(false, "Unreported fatal error."); + } return false; } return true; @@ -150,9 +160,14 @@ bool NameAndTypeResolver::updateDeclaration(Declaration const& _declaration) m_scopes[nullptr]->registerDeclaration(_declaration, false, true); solAssert(_declaration.scope() == nullptr, "Updated declaration outside global scope."); } - catch (langutil::FatalError const& error) + catch (FatalError const&) { - solAssert(m_errorReporter.hasErrors(), "Unreported fatal error: "s + error.what()); + if (!m_errorReporter.hasErrors()) + { + std::cerr << "Unreported fatal error:" << std::endl; + std::cerr << boost::current_exception_diagnostic_information() << std::endl; + solAssert(false, "Unreported fatal error."); + } return false; } return true; diff --git a/libsolidity/interface/CompilerStack.cpp b/libsolidity/interface/CompilerStack.cpp index 4e9346ecfebd..2748c09cda94 100644 --- a/libsolidity/interface/CompilerStack.cpp +++ b/libsolidity/interface/CompilerStack.cpp @@ -507,9 +507,14 @@ bool CompilerStack::analyze() else if (!analyzeLegacy(noErrors)) noErrors = false; } - catch (FatalError const& error) + catch (FatalError const&) { - solAssert(m_errorReporter.hasErrors(), "Unreported fatal error: "s + error.what()); + if (!m_errorReporter.hasErrors()) + { + std::cerr << "Unreported fatal error:" << std::endl; + std::cerr << boost::current_exception_diagnostic_information() << std::endl; + solAssert(false, "Unreported fatal error."); + } noErrors = false; } catch (UnimplementedFeatureError const& _error) @@ -1317,9 +1322,14 @@ StringMap CompilerStack::loadMissingSources(SourceUnit const& _ast) } } } - catch (FatalError const& error) + catch (FatalError const&) { - solAssert(m_errorReporter.hasErrors(), "Unreported fatal error: "s + error.what()); + if (!m_errorReporter.hasErrors()) + { + std::cerr << "Unreported fatal error:" << std::endl; + std::cerr << boost::current_exception_diagnostic_information() << std::endl; + solAssert(false, "Unreported fatal error."); + } } return newSources; } diff --git a/libsolidity/parsing/Parser.cpp b/libsolidity/parsing/Parser.cpp index 720ff2afe4ed..08a319b5b597 100644 --- a/libsolidity/parsing/Parser.cpp +++ b/libsolidity/parsing/Parser.cpp @@ -176,9 +176,14 @@ ASTPointer Parser::parse(CharStream& _charStream) solAssert(m_recursionDepth == 0, ""); return nodeFactory.createNode(findLicenseString(nodes), nodes, m_experimentalSolidityEnabledInCurrentSourceUnit); } - catch (FatalError const& error) + catch (FatalError const&) { - solAssert(m_errorReporter.hasErrors(), "Unreported fatal error: "s + error.what()); + if (!m_errorReporter.hasErrors()) + { + std::cerr << "Unreported fatal error:" << std::endl; + std::cerr << boost::current_exception_diagnostic_information() << std::endl; + solAssert(false, "Unreported fatal error."); + } return nullptr; } } diff --git a/libyul/AsmAnalysis.cpp b/libyul/AsmAnalysis.cpp index 352f16f769b8..aa3e23e2626f 100644 --- a/libyul/AsmAnalysis.cpp +++ b/libyul/AsmAnalysis.cpp @@ -75,13 +75,18 @@ bool AsmAnalyzer::analyze(Block const& _block) (*this)(_block); } - catch (FatalError const& error) + catch (FatalError const&) { // NOTE: There's a cap on the number of reported errors, but watcher.ok() will work fine even if // we exceed it because the reporter keeps counting (it just stops adding errors to the list). // Note also that fact of exceeding the cap triggers a FatalError so one can get thrown even // if we don't make any of our errors fatal. - yulAssert(!watcher.ok(), "Unreported fatal error: "s + error.what()); + if (watcher.ok()) + { + std::cerr << "Unreported fatal error:" << std::endl; + std::cerr << boost::current_exception_diagnostic_information() << std::endl; + yulAssert(false, "Unreported fatal error."); + } } return watcher.ok(); } diff --git a/libyul/AsmParser.cpp b/libyul/AsmParser.cpp index c061a251acd6..a6949d7f8bdb 100644 --- a/libyul/AsmParser.cpp +++ b/libyul/AsmParser.cpp @@ -127,9 +127,14 @@ std::unique_ptr Parser::parseInline(std::shared_ptr const& _scanne fetchDebugDataFromComment(); return std::make_unique(m_dialect, parseBlock()); } - catch (FatalError const& error) + catch (FatalError const&) { - yulAssert(m_errorReporter.hasErrors(), "Unreported fatal error: "s + error.what()); + if (!m_errorReporter.hasErrors()) + { + std::cerr << "Unreported fatal error:" << std::endl; + std::cerr << boost::current_exception_diagnostic_information() << std::endl; + yulAssert(false, "Unreported fatal error."); + } } return nullptr; diff --git a/libyul/ObjectParser.cpp b/libyul/ObjectParser.cpp index 954ade311f84..dfa604941ab5 100644 --- a/libyul/ObjectParser.cpp +++ b/libyul/ObjectParser.cpp @@ -63,9 +63,14 @@ std::shared_ptr ObjectParser::parse(std::shared_ptr const& _sca expectToken(Token::EOS); return object; } - catch (FatalError const& error) + catch (FatalError const&) { - yulAssert(m_errorReporter.hasErrors(), "Unreported fatal error: "s + error.what()); + if (!m_errorReporter.hasErrors()) + { + std::cerr << "Unreported fatal error:" << std::endl; + std::cerr << boost::current_exception_diagnostic_information() << std::endl; + yulAssert(false, "Unreported fatal error."); + } } return nullptr; } From d7073bada9705a998b9d48874d9c01fbfd165f26 Mon Sep 17 00:00:00 2001 From: Matheus Aguiar Date: Thu, 27 Feb 2025 19:23:53 -0300 Subject: [PATCH 0835/1022] Update and add tests --- .../err | 19 ++++--------------- ...already_specified_in_ancestor_contract.sol | 3 +-- ..._specified_by_ancestor_contract_module.sol | 13 +++++++++++++ ...ancestor_contract_multiple_inheritance.sol | 16 ++++++++++++++++ ...t_specified_by_first_ancestor_contract.sol | 4 +--- ...ut_specified_by_last_ancestor_contract.sol | 2 +- 6 files changed, 36 insertions(+), 21 deletions(-) create mode 100644 test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_ancestor_contract_module.sol create mode 100644 test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_ancestor_contract_multiple_inheritance.sol diff --git a/test/cmdlineTests/storage_layout_already_defined_in_ancestor/err b/test/cmdlineTests/storage_layout_already_defined_in_ancestor/err index a5ad279544f2..6d5d1dc46c36 100644 --- a/test/cmdlineTests/storage_layout_already_defined_in_ancestor/err +++ b/test/cmdlineTests/storage_layout_already_defined_in_ancestor/err @@ -1,20 +1,9 @@ -Error: Storage layout can only be specified in the most derived contract. - --> :5:1: +Error: Cannot inherit from a contract with a custom storage layout. + --> :5:15: | 5 | contract B is A {} - | ^^^^^^^^^^^^^^^^^^ -Note: Storage layout was already specified here. - --> :4:12: - | -4 | contract A layout at 0x1234 {} - | ^^^^^^^^^^^^^^^^ - -Error: Storage layout can only be specified in the most derived contract. - --> :6:1: - | -6 | contract C layout at 0x1234 is B {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Note: Storage layout was already specified here. + | ^ +Note: Custom storage layout defined here: --> :4:12: | 4 | contract A layout at 0x1234 {} diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_already_specified_in_ancestor_contract.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_already_specified_in_ancestor_contract.sol index d525d92066a0..3d60cc38d51a 100644 --- a/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_already_specified_in_ancestor_contract.sol +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_already_specified_in_ancestor_contract.sol @@ -4,5 +4,4 @@ contract B is A {} contract C is B layout at 0xABCD {} // ---- -// TypeError 8894: (32-50): Storage layout can only be specified in the most derived contract. -// TypeError 8894: (52-87): Storage layout can only be specified in the most derived contract. +// TypeError 8894: (46-47): Cannot inherit from a contract with a custom storage layout. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_ancestor_contract_module.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_ancestor_contract_module.sol new file mode 100644 index 000000000000..3b1cf05ce321 --- /dev/null +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_ancestor_contract_module.sol @@ -0,0 +1,13 @@ +==== Source: C ==== +import "M" as M; +import "N" as N; + +contract C is M.A, N.A layout at 0xABCD {} +==== Source: M ==== +contract A layout at 0x1234 {} + +==== Source: N ==== +contract A {} + +// ---- +// TypeError 8894: (C:49-52): Cannot inherit from a contract with a custom storage layout. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_ancestor_contract_multiple_inheritance.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_ancestor_contract_multiple_inheritance.sol new file mode 100644 index 000000000000..8b41095fb51d --- /dev/null +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_ancestor_contract_multiple_inheritance.sol @@ -0,0 +1,16 @@ +contract A layout at 1 {} +contract B is A layout at 2 {} + +contract C1 is B {} +contract C2 is A, B {} +contract C3 is B {} + +contract D1 is C1 {} +contract D2 is C2 {} +contract D3 is C3 {} +// ---- +// TypeError 8894: (40-41): Cannot inherit from a contract with a custom storage layout. +// TypeError 8894: (73-74): Cannot inherit from a contract with a custom storage layout. +// TypeError 8894: (93-94): Cannot inherit from a contract with a custom storage layout. +// TypeError 8894: (96-97): Cannot inherit from a contract with a custom storage layout. +// TypeError 8894: (116-117): Cannot inherit from a contract with a custom storage layout. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_first_ancestor_contract.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_first_ancestor_contract.sol index 77b1ed617c08..69df5d7752c3 100644 --- a/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_first_ancestor_contract.sol +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_first_ancestor_contract.sol @@ -3,6 +3,4 @@ contract B is A {} contract C is B {} contract D is C {} // ---- -// TypeError 8894: (27-45): Storage layout can only be specified in the most derived contract. -// TypeError 8894: (46-64): Storage layout can only be specified in the most derived contract. -// TypeError 8894: (65-83): Storage layout can only be specified in the most derived contract. +// TypeError 8894: (41-42): Cannot inherit from a contract with a custom storage layout. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_last_ancestor_contract.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_last_ancestor_contract.sol index 0c42f3550a44..d2ac0e931d0d 100644 --- a/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_last_ancestor_contract.sol +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_last_ancestor_contract.sol @@ -3,4 +3,4 @@ contract B is A {} contract C is B layout at 42 {} contract D is C {} // ---- -// TypeError 8894: (65-83): Storage layout can only be specified in the most derived contract. +// TypeError 8894: (79-80): Cannot inherit from a contract with a custom storage layout. From 2995f0455c176fa8906067147bbd76c1a0f15b87 Mon Sep 17 00:00:00 2001 From: Matheus Aguiar Date: Thu, 27 Feb 2025 19:23:04 -0300 Subject: [PATCH 0836/1022] Improve storage layout specifier error message --- libsolidity/analysis/ContractLevelChecker.cpp | 20 +++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/libsolidity/analysis/ContractLevelChecker.cpp b/libsolidity/analysis/ContractLevelChecker.cpp index 7996fd71137b..a426b8af93dd 100644 --- a/libsolidity/analysis/ContractLevelChecker.cpp +++ b/libsolidity/analysis/ContractLevelChecker.cpp @@ -30,6 +30,7 @@ #include +#include #include using namespace solidity; @@ -116,19 +117,22 @@ void ContractLevelChecker::checkStorageLayoutSpecifier(ContractDefinition const& ); } - for (auto const* ancestorContract: _contract.annotation().linearizedBaseContracts | ranges::views::reverse) + for (auto const& baseContractSpecifier: _contract.baseContracts()) { - if (*ancestorContract == _contract) - continue; - if (ancestorContract->storageLayoutSpecifier()) + auto const* baseContract = dynamic_cast( + baseContractSpecifier->name().annotation().referencedDeclaration + ); + + solAssert(baseContract); + if (baseContract->storageLayoutSpecifier()) m_errorReporter.typeError( 8894_error, - _contract.location(), + baseContractSpecifier->location(), SecondarySourceLocation().append( - "Storage layout was already specified here.", - ancestorContract->storageLayoutSpecifier()->location() + "Custom storage layout defined here:", + baseContract->storageLayoutSpecifier()->location() ), - "Storage layout can only be specified in the most derived contract." + "Cannot inherit from a contract with a custom storage layout." ); } } From 5fd8593a154c6874a7987058cb1a2c7057325947 Mon Sep 17 00:00:00 2001 From: Matheus Aguiar Date: Fri, 28 Feb 2025 00:17:28 -0300 Subject: [PATCH 0837/1022] Fix wrong storage size computation --- Changelog.md | 1 + libsolidity/analysis/ContractLevelChecker.cpp | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/Changelog.md b/Changelog.md index 3eb3abf79f38..8144fdf51b56 100644 --- a/Changelog.md +++ b/Changelog.md @@ -27,6 +27,7 @@ Bugfixes: * SMTChecker: Fix SMT logic error when translating invariants involving array store and select operations. * SMTChecker: Fix wrong encoding of string literals as arguments of ``ecrecover`` precompile. * Standard JSON Interface: Fix ``generatedSources`` and ``sourceMap`` being generated internally even when not requested. + * TypeChecker: Fix supurious compilation errors due to incorrect computation of contract storage size which erroneously included transient storage variables. * Yul: Fix internal compiler error when a code generation error should be reported instead. diff --git a/libsolidity/analysis/ContractLevelChecker.cpp b/libsolidity/analysis/ContractLevelChecker.cpp index a426b8af93dd..c655480bf8f1 100644 --- a/libsolidity/analysis/ContractLevelChecker.cpp +++ b/libsolidity/analysis/ContractLevelChecker.cpp @@ -593,7 +593,10 @@ void ContractLevelChecker::checkStorageSize(ContractDefinition const& _contract) bigint size = 0; for (ContractDefinition const* contract: _contract.annotation().linearizedBaseContracts | ranges::views::reverse) for (VariableDeclaration const* variable: contract->stateVariables()) - if (!(variable->isConstant() || variable->immutable())) + if ( + !(variable->isConstant() || variable->immutable()) && + variable->referenceLocation() == VariableDeclaration::Location::Unspecified + ) { size += variable->annotation().type->storageSizeUpperBound(); if (size >= bigint(1) << 256) From aae841e4f6ea5e1449eedc72d5e3ed19e404e034 Mon Sep 17 00:00:00 2001 From: Matheus Aguiar Date: Fri, 28 Feb 2025 02:15:00 -0300 Subject: [PATCH 0838/1022] Add helper to calculate storage/transient size --- libsolidity/analysis/ContractLevelChecker.cpp | 28 +++++++++---------- libsolidity/analysis/ContractLevelChecker.h | 2 +- libsolidity/ast/ASTUtils.cpp | 16 +++++++++++ libsolidity/ast/ASTUtils.h | 4 +++ scripts/error_codes.py | 1 + 5 files changed, 35 insertions(+), 16 deletions(-) diff --git a/libsolidity/analysis/ContractLevelChecker.cpp b/libsolidity/analysis/ContractLevelChecker.cpp index c655480bf8f1..08d8fc9f779b 100644 --- a/libsolidity/analysis/ContractLevelChecker.cpp +++ b/libsolidity/analysis/ContractLevelChecker.cpp @@ -23,6 +23,7 @@ #include #include +#include #include #include #include @@ -590,19 +591,16 @@ void ContractLevelChecker::checkPayableFallbackWithoutReceive(ContractDefinition void ContractLevelChecker::checkStorageSize(ContractDefinition const& _contract) { - bigint size = 0; - for (ContractDefinition const* contract: _contract.annotation().linearizedBaseContracts | ranges::views::reverse) - for (VariableDeclaration const* variable: contract->stateVariables()) - if ( - !(variable->isConstant() || variable->immutable()) && - variable->referenceLocation() == VariableDeclaration::Location::Unspecified - ) - { - size += variable->annotation().type->storageSizeUpperBound(); - if (size >= bigint(1) << 256) - { - m_errorReporter.typeError(7676_error, _contract.location(), "Contract requires too much storage."); - break; - } - } + using enum VariableDeclaration::Location; + for (VariableDeclaration::Location location: {Unspecified, Transient}) + { + bigint size = contractStorageSizeUpperBound(_contract, location); + if (size >= bigint(1) << 256) + { + if (location == Unspecified) + m_errorReporter.typeError(7676_error, _contract.location(), "Contract requires too much storage."); + else + m_errorReporter.typeError(5026_error, _contract.location(), "Contract requires too much transient storage."); + } + } } diff --git a/libsolidity/analysis/ContractLevelChecker.h b/libsolidity/analysis/ContractLevelChecker.h index f0e521c60bad..e51e39dc3963 100644 --- a/libsolidity/analysis/ContractLevelChecker.h +++ b/libsolidity/analysis/ContractLevelChecker.h @@ -88,7 +88,7 @@ class ContractLevelChecker /// Warns if the contract has a payable fallback, but no receive ether function. void checkPayableFallbackWithoutReceive(ContractDefinition const& _contract); - /// Error if the contract requires too much storage + /// Error if the contract requires too much storage or transient storage void checkStorageSize(ContractDefinition const& _contract); /// Checks if the storage layout specifier is properly assigned in the inheritance tree and not applied to an abstract contract void checkStorageLayoutSpecifier(ContractDefinition const& _contract); diff --git a/libsolidity/ast/ASTUtils.cpp b/libsolidity/ast/ASTUtils.cpp index 7d434f896d12..7f5ea03a0ac0 100644 --- a/libsolidity/ast/ASTUtils.cpp +++ b/libsolidity/ast/ASTUtils.cpp @@ -107,4 +107,20 @@ Type const* type(VariableDeclaration const& _variable) return _variable.annotation().type; } +bigint contractStorageSizeUpperBound(ContractDefinition const& _contract, VariableDeclaration::Location _location) +{ + solAssert(_location == VariableDeclaration::Location::Unspecified || _location == VariableDeclaration::Location::Transient); + + bigint size = 0; + for (ContractDefinition const* contract: _contract.annotation().linearizedBaseContracts) + for (VariableDeclaration const* variable: contract->stateVariables()) + if ( + !(variable->isConstant() || variable->immutable()) && + variable->referenceLocation() == _location + ) + size += variable->annotation().type->storageSizeUpperBound(); + + return size; +} + } diff --git a/libsolidity/ast/ASTUtils.h b/libsolidity/ast/ASTUtils.h index b31bd20d5845..0f37af7195d9 100644 --- a/libsolidity/ast/ASTUtils.h +++ b/libsolidity/ast/ASTUtils.h @@ -48,4 +48,8 @@ Type const* type(Expression const& _expression); /// (this can happen for variables with non-explicit types before their types are resolved) Type const* type(VariableDeclaration const& _variable); +/// @returns The number of slots occupied by all state variables in contract's inheritance hierarchy, +/// located in @a _location (either storage or transient storage). +bigint contractStorageSizeUpperBound(ContractDefinition const& _contract, VariableDeclaration::Location _location); + } diff --git a/scripts/error_codes.py b/scripts/error_codes.py index d99d60c6e284..71206ac43f8f 100755 --- a/scripts/error_codes.py +++ b/scripts/error_codes.py @@ -208,6 +208,7 @@ def examine_id_coverage(top_dir, source_id_to_file_names, new_ids_only=False): "2788", # SMTChecker: BMC: verification condition(s) could not be proved "1733", # AsmAnalysis: expecting bool expression (everything is implicitly bool without types in Yul) "9547", # AsmAnalysis: assigning incompatible types in Yul (whitelisted as there are currently no types) + "5026", # ContractLevelChecker: too difficult to exceed transient storage max size due to only value types supported. } assert len(test_ids & white_ids) == 0, "The sets are not supposed to intersect" test_ids |= white_ids From e601d83b62759ca8935b3803791a8c3a8925bbba Mon Sep 17 00:00:00 2001 From: Matheus Aguiar Date: Fri, 28 Feb 2025 00:17:11 -0300 Subject: [PATCH 0839/1022] Add tests --- .../max_size_array_with_transient_state_variables.sol | 8 ++++++++ .../syntaxTests/largeTypes/oversized_array_1d.sol | 5 +++++ .../{oversized_array.sol => oversized_array_2d.sol} | 0 3 files changed, 13 insertions(+) create mode 100644 test/libsolidity/syntaxTests/largeTypes/max_size_array_with_transient_state_variables.sol create mode 100644 test/libsolidity/syntaxTests/largeTypes/oversized_array_1d.sol rename test/libsolidity/syntaxTests/largeTypes/{oversized_array.sol => oversized_array_2d.sol} (100%) diff --git a/test/libsolidity/syntaxTests/largeTypes/max_size_array_with_transient_state_variables.sol b/test/libsolidity/syntaxTests/largeTypes/max_size_array_with_transient_state_variables.sol new file mode 100644 index 000000000000..280fb81c8e18 --- /dev/null +++ b/test/libsolidity/syntaxTests/largeTypes/max_size_array_with_transient_state_variables.sol @@ -0,0 +1,8 @@ +contract C { + uint[2**256 - 1] x; + uint transient y; +} +// ==== +// EVMVersion: >=cancun +// ---- +// Warning 7325: (17-33): Type uint256[115792089237316195423570985008687907853269984665640564039457584007913129639935] covers a large part of storage and thus makes collisions likely. Either use mappings or dynamic arrays and allow their size to be increased only in small quantities per transaction. diff --git a/test/libsolidity/syntaxTests/largeTypes/oversized_array_1d.sol b/test/libsolidity/syntaxTests/largeTypes/oversized_array_1d.sol new file mode 100644 index 000000000000..d46bdd9c3872 --- /dev/null +++ b/test/libsolidity/syntaxTests/largeTypes/oversized_array_1d.sol @@ -0,0 +1,5 @@ +contract C { + uint[2**256] x; +} +// ---- +// TypeError 1847: (22-28): Array length too large, maximum is 2**256 - 1. diff --git a/test/libsolidity/syntaxTests/largeTypes/oversized_array.sol b/test/libsolidity/syntaxTests/largeTypes/oversized_array_2d.sol similarity index 100% rename from test/libsolidity/syntaxTests/largeTypes/oversized_array.sol rename to test/libsolidity/syntaxTests/largeTypes/oversized_array_2d.sol From 7ffb394e72c01ffce9fc7ad85998c7be07a97aae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Sat, 1 Mar 2025 18:59:49 +0100 Subject: [PATCH 0840/1022] Replace assertThrow in tests with asserts/validations/unimplemented checks --- test/Common.cpp | 10 +++++----- test/EVMHost.cpp | 14 ++++++++------ test/Metadata.cpp | 35 ++++++++++++++++++---------------- test/tools/IsolTestOptions.cpp | 2 +- 4 files changed, 33 insertions(+), 28 deletions(-) diff --git a/test/Common.cpp b/test/Common.cpp index bb25d203b71e..8b39d4a53585 100644 --- a/test/Common.cpp +++ b/test/Common.cpp @@ -129,22 +129,22 @@ void CommonOptions::addOptions() void CommonOptions::validate() const { - assertThrow( + solRequire( !testPath.empty(), ConfigException, "No test path specified. The --testpath argument must not be empty when given." ); - assertThrow( + solRequire( fs::exists(testPath), ConfigException, "Invalid test path specified." ); - assertThrow( + solRequire( batches > 0, ConfigException, "Batches needs to be at least 1." ); - assertThrow( + solRequire( selectedBatch < batches, ConfigException, "Selected batch has to be less than number of batches." @@ -162,7 +162,7 @@ void CommonOptions::validate() const std::cout << std::endl << "DO NOT COMMIT THE UPDATED EXPECTATIONS." << std::endl << std::endl; } - assertThrow(!eofVersion().has_value() || evmVersion().supportsEOF(), ConfigException, "EOF is unavailable before Osaka fork."); + solRequire(!eofVersion().has_value() || evmVersion().supportsEOF(), ConfigException, "EOF is unavailable before Osaka fork."); } bool CommonOptions::parse(int argc, char const* const* argv) diff --git a/test/EVMHost.cpp b/test/EVMHost.cpp index 7df39bf71ee8..fcab682a2139 100644 --- a/test/EVMHost.cpp +++ b/test/EVMHost.cpp @@ -29,6 +29,7 @@ #endif #include +#include #if defined(__GNUC__) && !defined(__clang__) // GCC-specific pragma #pragma GCC diagnostic pop @@ -105,7 +106,7 @@ EVMHost::EVMHost(langutil::EVMVersion _evmVersion, evmc::VM& _vm): if (!m_vm) { std::cerr << "Unable to find evmone library" << std::endl; - assertThrow(false, Exception, ""); + solRequire(false, Exception, ""); } if (_evmVersion == langutil::EVMVersion::homestead()) @@ -137,7 +138,7 @@ EVMHost::EVMHost(langutil::EVMVersion _evmVersion, evmc::VM& _vm): else if (_evmVersion == langutil::EVMVersion::osaka()) m_evmRevision = EVMC_OSAKA; else - assertThrow(false, Exception, "Unsupported EVM version"); + solRequire(false, Exception, "Unsupported EVM version"); if (m_evmRevision >= EVMC_PARIS) // This is the value from the merge block. @@ -228,7 +229,7 @@ void EVMHost::newTransactionFrame() void EVMHost::transfer(evmc::MockedAccount& _sender, evmc::MockedAccount& _recipient, u256 const& _value) noexcept { - assertThrow(u256(convertFromEVMC(_sender.balance)) >= _value, Exception, "Insufficient balance for transfer"); + solRequire(u256(convertFromEVMC(_sender.balance)) >= _value, Exception, "Insufficient balance for transfer"); _sender.balance = convertToEVMC(u256(convertFromEVMC(_sender.balance)) - _value); _recipient.balance = convertToEVMC(u256(convertFromEVMC(_recipient.balance)) + _value); } @@ -329,7 +330,7 @@ evmc::Result EVMHost::call(evmc_message const& _message) noexcept } else if (value <= 0xffff) { return bytes{128 + 55 + 2, static_cast(value >> 8), static_cast(value)}; } else { - assertThrow(false, Exception, "Can only encode RLP numbers <= 0xffff"); + solUnimplemented("Can only encode RLP numbers <= 0xffff"); } }; @@ -343,7 +344,7 @@ evmc::Result EVMHost::call(evmc_message const& _message) noexcept ), h160::AlignRight); message.recipient = convertToEVMC(createAddress); - assertThrow(accounts.count(message.recipient) == 0, Exception, "Account cannot exist"); + soltestAssert(accounts.count(message.recipient) == 0, "Account cannot exist"); code = evmc::bytes(message.input_data, message.input_data + message.input_size); } @@ -1320,7 +1321,7 @@ evmc::Result EVMHost::resultWithGas( StorageMap const& EVMHost::get_address_storage(evmc::address const& _addr) { - assertThrow(account_exists(_addr), Exception, "Account does not exist."); + soltestAssert(account_exists(_addr), "Account does not exist."); return accounts[_addr].storage; } @@ -1386,6 +1387,7 @@ void EVMHostPrinter::callRecords() default: assertThrow(false, Exception, "Invalid call kind."); } + unreachable(); }; for (auto const& record: m_host.recorded_calls) diff --git a/test/Metadata.cpp b/test/Metadata.cpp index cdfcdfb19c48..6b2d1f3d82b8 100644 --- a/test/Metadata.cpp +++ b/test/Metadata.cpp @@ -20,11 +20,17 @@ * Metadata processing helpers. */ -#include -#include +#include + +#include + +#include + #include #include -#include + +#include +#include namespace solidity::test { @@ -64,11 +70,11 @@ class TinyCBORParser public: explicit TinyCBORParser(bytes const& _metadata): m_pos(0), m_metadata(_metadata) { - assertThrow((m_pos + 1) < _metadata.size(), CBORException, "Input too short."); + solRequire((m_pos + 1) < _metadata.size(), CBORException, "Input too short."); } unsigned mapItemCount() { - assertThrow(nextType() == MajorType::Map, CBORException, "Fixed-length map expected."); + solRequire(nextType() == MajorType::Map, CBORException, "Fixed-length map expected."); return readLength(); } std::string readKey() @@ -89,17 +95,14 @@ class TinyCBORParser m_pos++; if (value == 20) return "false"; - else if (value == 21) + if (value == 21) return "true"; - else - { - assertThrow(false, CBORException, "Unsupported simple value (not a boolean)."); - return ""; // unreachable, but prevents compiler warning. - } + solUnimplemented("Unsupported simple value (not a boolean)."); } - default: - assertThrow(false, CBORException, "Unsupported value type."); + case MajorType::Map: + solUnimplemented("Nested maps not supported."); } + util::unreachable(); } private: enum class MajorType @@ -118,7 +121,7 @@ class TinyCBORParser case 3: return MajorType::TextString; case 5: return MajorType::Map; case 7: return MajorType::SimpleData; - default: assertThrow(false, CBORException, "Unsupported major type."); + default: solUnimplemented("Unsupported major type."); } } unsigned nextImmediate() const { return m_metadata.at(m_pos) & 0x1f; } @@ -130,7 +133,7 @@ class TinyCBORParser if (length == 24) return m_metadata.at(m_pos++); // Unsupported length kind. (Only by this parser.) - assertThrow(false, CBORException, std::string("Unsupported length ") + std::to_string(length)); + solUnimplemented(std::string("Unsupported length ") + std::to_string(length)); } bytes readBytes(unsigned length) { @@ -141,7 +144,7 @@ class TinyCBORParser std::string readString() { // Expect a text string. - assertThrow(nextType() == MajorType::TextString, CBORException, "String expected."); + soltestAssert(nextType() == MajorType::TextString, "String expected."); bytes tmp{readBytes(readLength())}; return std::string{tmp.begin(), tmp.end()}; } diff --git a/test/tools/IsolTestOptions.cpp b/test/tools/IsolTestOptions.cpp index 0994b63a83ef..e0980c7646e6 100644 --- a/test/tools/IsolTestOptions.cpp +++ b/test/tools/IsolTestOptions.cpp @@ -92,7 +92,7 @@ void IsolTestOptions::validate() const CommonOptions::validate(); static std::string filterString{"[a-zA-Z0-9_/*]*"}; static std::regex filterExpression{filterString}; - assertThrow( + solRequire( regex_match(testFilter, filterExpression), ConfigException, "Invalid test unit filter - can only contain '" + filterString + ": " + testFilter From 7841d882056d1a6b066509d1b2fe113ce40df86e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Sat, 1 Mar 2025 18:14:19 +0100 Subject: [PATCH 0841/1022] Add validations against selecting EOF on EVM versions that do not support it --- libsolidity/interface/StandardCompiler.cpp | 3 +++ solc/CommandLineParser.cpp | 3 +++ test/Common.cpp | 6 +++++- test/cmdlineTests/eof_unavailable_before_osaka/args | 1 + test/cmdlineTests/eof_unavailable_before_osaka/err | 1 + test/cmdlineTests/eof_unavailable_before_osaka/exit | 1 + .../eof_unavailable_before_osaka/input.sol | 4 ++++ .../import_asm_json_eof_unavailable_before_osaka/args | 1 + .../import_asm_json_eof_unavailable_before_osaka/err | 1 + .../import_asm_json_eof_unavailable_before_osaka/exit | 1 + .../stdin | 1 + .../standard_eof_unavailable_before_osaka/input.json | 10 ++++++++++ .../standard_eof_unavailable_before_osaka/output.json | 11 +++++++++++ .../input.json | 10 ++++++++++ .../output.json | 11 +++++++++++ .../input.json | 10 ++++++++++ .../output.json | 11 +++++++++++ .../strict_asm_eof_unavailable_before_osaka/args | 1 + .../strict_asm_eof_unavailable_before_osaka/err | 1 + .../strict_asm_eof_unavailable_before_osaka/exit | 1 + .../strict_asm_eof_unavailable_before_osaka/input.yul | 1 + 21 files changed, 89 insertions(+), 1 deletion(-) create mode 100644 test/cmdlineTests/eof_unavailable_before_osaka/args create mode 100644 test/cmdlineTests/eof_unavailable_before_osaka/err create mode 100644 test/cmdlineTests/eof_unavailable_before_osaka/exit create mode 100644 test/cmdlineTests/eof_unavailable_before_osaka/input.sol create mode 100644 test/cmdlineTests/import_asm_json_eof_unavailable_before_osaka/args create mode 100644 test/cmdlineTests/import_asm_json_eof_unavailable_before_osaka/err create mode 100644 test/cmdlineTests/import_asm_json_eof_unavailable_before_osaka/exit create mode 100644 test/cmdlineTests/import_asm_json_eof_unavailable_before_osaka/stdin create mode 100644 test/cmdlineTests/standard_eof_unavailable_before_osaka/input.json create mode 100644 test/cmdlineTests/standard_eof_unavailable_before_osaka/output.json create mode 100644 test/cmdlineTests/standard_import_asm_json_eof_unavailable_before_osaka/input.json create mode 100644 test/cmdlineTests/standard_import_asm_json_eof_unavailable_before_osaka/output.json create mode 100644 test/cmdlineTests/standard_yul_eof_unavailable_before_osaka/input.json create mode 100644 test/cmdlineTests/standard_yul_eof_unavailable_before_osaka/output.json create mode 100644 test/cmdlineTests/strict_asm_eof_unavailable_before_osaka/args create mode 100644 test/cmdlineTests/strict_asm_eof_unavailable_before_osaka/err create mode 100644 test/cmdlineTests/strict_asm_eof_unavailable_before_osaka/exit create mode 100644 test/cmdlineTests/strict_asm_eof_unavailable_before_osaka/input.yul diff --git a/libsolidity/interface/StandardCompiler.cpp b/libsolidity/interface/StandardCompiler.cpp index f52ad4e1ee88..71fbf17e288b 100644 --- a/libsolidity/interface/StandardCompiler.cpp +++ b/libsolidity/interface/StandardCompiler.cpp @@ -846,6 +846,9 @@ std::variant StandardCompiler::parseI ret.eofVersion = 1; } + if (ret.eofVersion.has_value() && !ret.evmVersion.supportsEOF()) + return formatFatalError(Error::Type::JSONError, "EOF is not supported by EVM versions earlier than " + EVMVersion::firstWithEOF().name() + "."); + if (settings.contains("debug")) { if (auto result = checkKeys(settings["debug"], {"revertStrings", "debugInfo"}, "settings.debug")) diff --git a/solc/CommandLineParser.cpp b/solc/CommandLineParser.cpp index 25f3048b54f2..a382c5217377 100644 --- a/solc/CommandLineParser.cpp +++ b/solc/CommandLineParser.cpp @@ -1252,6 +1252,9 @@ void CommandLineParser::processArgs() m_options.output.eofVersion = 1; } + if (m_options.output.eofVersion.has_value() && !m_options.output.evmVersion.supportsEOF()) + solThrow(CommandLineValidationError, "EOF is not supported by EVM versions earlier than " + EVMVersion::firstWithEOF().name() + "."); + if (m_args.count(g_strNoOptimizeYul) > 0 && m_args.count(g_strOptimizeYul) > 0) solThrow( CommandLineValidationError, diff --git a/test/Common.cpp b/test/Common.cpp index 8b39d4a53585..d39c6db1ea9e 100644 --- a/test/Common.cpp +++ b/test/Common.cpp @@ -162,7 +162,11 @@ void CommonOptions::validate() const std::cout << std::endl << "DO NOT COMMIT THE UPDATED EXPECTATIONS." << std::endl << std::endl; } - solRequire(!eofVersion().has_value() || evmVersion().supportsEOF(), ConfigException, "EOF is unavailable before Osaka fork."); + solRequire( + !eofVersion().has_value() || evmVersion().supportsEOF(), + ConfigException, + "EOF is not supported by EVM versions earlier than " + langutil::EVMVersion::firstWithEOF().name() + "." + ); } bool CommonOptions::parse(int argc, char const* const* argv) diff --git a/test/cmdlineTests/eof_unavailable_before_osaka/args b/test/cmdlineTests/eof_unavailable_before_osaka/args new file mode 100644 index 000000000000..90e7e00e2552 --- /dev/null +++ b/test/cmdlineTests/eof_unavailable_before_osaka/args @@ -0,0 +1 @@ +--optimize --experimental-eof-version 1 --evm-version cancun diff --git a/test/cmdlineTests/eof_unavailable_before_osaka/err b/test/cmdlineTests/eof_unavailable_before_osaka/err new file mode 100644 index 000000000000..cf9a17a7dfb9 --- /dev/null +++ b/test/cmdlineTests/eof_unavailable_before_osaka/err @@ -0,0 +1 @@ +Error: EOF is not supported by EVM versions earlier than osaka. diff --git a/test/cmdlineTests/eof_unavailable_before_osaka/exit b/test/cmdlineTests/eof_unavailable_before_osaka/exit new file mode 100644 index 000000000000..d00491fd7e5b --- /dev/null +++ b/test/cmdlineTests/eof_unavailable_before_osaka/exit @@ -0,0 +1 @@ +1 diff --git a/test/cmdlineTests/eof_unavailable_before_osaka/input.sol b/test/cmdlineTests/eof_unavailable_before_osaka/input.sol new file mode 100644 index 000000000000..f123f6c8bee3 --- /dev/null +++ b/test/cmdlineTests/eof_unavailable_before_osaka/input.sol @@ -0,0 +1,4 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity >=0.0; + +contract C {} diff --git a/test/cmdlineTests/import_asm_json_eof_unavailable_before_osaka/args b/test/cmdlineTests/import_asm_json_eof_unavailable_before_osaka/args new file mode 100644 index 000000000000..b5d6267fa5b0 --- /dev/null +++ b/test/cmdlineTests/import_asm_json_eof_unavailable_before_osaka/args @@ -0,0 +1 @@ +--import-asm-json --experimental-eof-version 1 --evm-version cancun diff --git a/test/cmdlineTests/import_asm_json_eof_unavailable_before_osaka/err b/test/cmdlineTests/import_asm_json_eof_unavailable_before_osaka/err new file mode 100644 index 000000000000..02ce7958c8d7 --- /dev/null +++ b/test/cmdlineTests/import_asm_json_eof_unavailable_before_osaka/err @@ -0,0 +1 @@ +Error: Option --evm-version is not supported with --import-asm-json. diff --git a/test/cmdlineTests/import_asm_json_eof_unavailable_before_osaka/exit b/test/cmdlineTests/import_asm_json_eof_unavailable_before_osaka/exit new file mode 100644 index 000000000000..d00491fd7e5b --- /dev/null +++ b/test/cmdlineTests/import_asm_json_eof_unavailable_before_osaka/exit @@ -0,0 +1 @@ +1 diff --git a/test/cmdlineTests/import_asm_json_eof_unavailable_before_osaka/stdin b/test/cmdlineTests/import_asm_json_eof_unavailable_before_osaka/stdin new file mode 100644 index 000000000000..0967ef424bce --- /dev/null +++ b/test/cmdlineTests/import_asm_json_eof_unavailable_before_osaka/stdin @@ -0,0 +1 @@ +{} diff --git a/test/cmdlineTests/standard_eof_unavailable_before_osaka/input.json b/test/cmdlineTests/standard_eof_unavailable_before_osaka/input.json new file mode 100644 index 000000000000..071e711e6742 --- /dev/null +++ b/test/cmdlineTests/standard_eof_unavailable_before_osaka/input.json @@ -0,0 +1,10 @@ +{ + "language": "Solidity", + "sources": { + "C.sol": {"content": "contract C {}"} + }, + "settings": { + "eofVersion": 1, + "evmVersion": "cancun" + } +} diff --git a/test/cmdlineTests/standard_eof_unavailable_before_osaka/output.json b/test/cmdlineTests/standard_eof_unavailable_before_osaka/output.json new file mode 100644 index 000000000000..8b50700db35a --- /dev/null +++ b/test/cmdlineTests/standard_eof_unavailable_before_osaka/output.json @@ -0,0 +1,11 @@ +{ + "errors": [ + { + "component": "general", + "formattedMessage": "EOF is not supported by EVM versions earlier than osaka.", + "message": "EOF is not supported by EVM versions earlier than osaka.", + "severity": "error", + "type": "JSONError" + } + ] +} diff --git a/test/cmdlineTests/standard_import_asm_json_eof_unavailable_before_osaka/input.json b/test/cmdlineTests/standard_import_asm_json_eof_unavailable_before_osaka/input.json new file mode 100644 index 000000000000..12cac3b2c8d9 --- /dev/null +++ b/test/cmdlineTests/standard_import_asm_json_eof_unavailable_before_osaka/input.json @@ -0,0 +1,10 @@ +{ + "language": "EVMAssembly", + "sources": { + "C.sol": {"assemblyJson": {}} + }, + "settings": { + "eofVersion": 1, + "evmVersion": "cancun" + } +} diff --git a/test/cmdlineTests/standard_import_asm_json_eof_unavailable_before_osaka/output.json b/test/cmdlineTests/standard_import_asm_json_eof_unavailable_before_osaka/output.json new file mode 100644 index 000000000000..8b50700db35a --- /dev/null +++ b/test/cmdlineTests/standard_import_asm_json_eof_unavailable_before_osaka/output.json @@ -0,0 +1,11 @@ +{ + "errors": [ + { + "component": "general", + "formattedMessage": "EOF is not supported by EVM versions earlier than osaka.", + "message": "EOF is not supported by EVM versions earlier than osaka.", + "severity": "error", + "type": "JSONError" + } + ] +} diff --git a/test/cmdlineTests/standard_yul_eof_unavailable_before_osaka/input.json b/test/cmdlineTests/standard_yul_eof_unavailable_before_osaka/input.json new file mode 100644 index 000000000000..125792d0910a --- /dev/null +++ b/test/cmdlineTests/standard_yul_eof_unavailable_before_osaka/input.json @@ -0,0 +1,10 @@ +{ + "language": "Yul", + "sources": { + "C.yul": {"content": "{}"} + }, + "settings": { + "eofVersion": 1, + "evmVersion": "cancun" + } +} diff --git a/test/cmdlineTests/standard_yul_eof_unavailable_before_osaka/output.json b/test/cmdlineTests/standard_yul_eof_unavailable_before_osaka/output.json new file mode 100644 index 000000000000..8b50700db35a --- /dev/null +++ b/test/cmdlineTests/standard_yul_eof_unavailable_before_osaka/output.json @@ -0,0 +1,11 @@ +{ + "errors": [ + { + "component": "general", + "formattedMessage": "EOF is not supported by EVM versions earlier than osaka.", + "message": "EOF is not supported by EVM versions earlier than osaka.", + "severity": "error", + "type": "JSONError" + } + ] +} diff --git a/test/cmdlineTests/strict_asm_eof_unavailable_before_osaka/args b/test/cmdlineTests/strict_asm_eof_unavailable_before_osaka/args new file mode 100644 index 000000000000..7ec243fdeb21 --- /dev/null +++ b/test/cmdlineTests/strict_asm_eof_unavailable_before_osaka/args @@ -0,0 +1 @@ +--strict-assembly --experimental-eof-version 1 --evm-version cancun diff --git a/test/cmdlineTests/strict_asm_eof_unavailable_before_osaka/err b/test/cmdlineTests/strict_asm_eof_unavailable_before_osaka/err new file mode 100644 index 000000000000..cf9a17a7dfb9 --- /dev/null +++ b/test/cmdlineTests/strict_asm_eof_unavailable_before_osaka/err @@ -0,0 +1 @@ +Error: EOF is not supported by EVM versions earlier than osaka. diff --git a/test/cmdlineTests/strict_asm_eof_unavailable_before_osaka/exit b/test/cmdlineTests/strict_asm_eof_unavailable_before_osaka/exit new file mode 100644 index 000000000000..d00491fd7e5b --- /dev/null +++ b/test/cmdlineTests/strict_asm_eof_unavailable_before_osaka/exit @@ -0,0 +1 @@ +1 diff --git a/test/cmdlineTests/strict_asm_eof_unavailable_before_osaka/input.yul b/test/cmdlineTests/strict_asm_eof_unavailable_before_osaka/input.yul new file mode 100644 index 000000000000..0967ef424bce --- /dev/null +++ b/test/cmdlineTests/strict_asm_eof_unavailable_before_osaka/input.yul @@ -0,0 +1 @@ +{} From 24b0ec2e760d4b4a1063d385aebd6bbdad34fddf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Sat, 1 Mar 2025 18:58:28 +0100 Subject: [PATCH 0842/1022] EVMHostPrinter: Fix EOFCREATE not being handled --- test/EVMHost.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/EVMHost.cpp b/test/EVMHost.cpp index fcab682a2139..983615312efd 100644 --- a/test/EVMHost.cpp +++ b/test/EVMHost.cpp @@ -1384,8 +1384,8 @@ void EVMHostPrinter::callRecords() return "CREATE"; case evmc_call_kind::EVMC_CREATE2: return "CREATE2"; - default: - assertThrow(false, Exception, "Invalid call kind."); + case evmc_call_kind::EVMC_EOFCREATE: + return "EOFCREATE"; } unreachable(); }; From 252a3a8632bf8a2d1b49c77944c2cfc2572132ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Sun, 2 Mar 2025 02:45:07 +0100 Subject: [PATCH 0843/1022] ObjectOptimizer::calculateCacheKey(): Fix flipped boolean conditions - This fixes the error caused by accessing an empty optional. - Switch to static_cast --- Changelog.md | 1 + libyul/ObjectOptimizer.cpp | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/Changelog.md b/Changelog.md index 8144fdf51b56..7b15ce945885 100644 --- a/Changelog.md +++ b/Changelog.md @@ -29,6 +29,7 @@ Bugfixes: * Standard JSON Interface: Fix ``generatedSources`` and ``sourceMap`` being generated internally even when not requested. * TypeChecker: Fix supurious compilation errors due to incorrect computation of contract storage size which erroneously included transient storage variables. * Yul: Fix internal compiler error when a code generation error should be reported instead. + * Yul Optimizer: Fix failing debug assertion due to dereferencing of an empty ``optional`` value. Build system: diff --git a/libyul/ObjectOptimizer.cpp b/libyul/ObjectOptimizer.cpp index 181cbaa8fe4e..07c25a0681c6 100644 --- a/libyul/ObjectOptimizer.cpp +++ b/libyul/ObjectOptimizer.cpp @@ -154,12 +154,12 @@ std::optional ObjectOptimizer::calculateCacheKey( rawKey += keccak256(asmPrinter(_ast)).asBytes(); rawKey += keccak256(_debugData.formatUseSrcComment()).asBytes(); rawKey += h256(u256(_settings.language)).asBytes(); - rawKey += FixedHash<1>(uint8_t(_settings.optimizeStackAllocation ? 0 : 1)).asBytes(); + rawKey += FixedHash<1>(static_cast(_settings.optimizeStackAllocation ? 1 : 0)).asBytes(); rawKey += h256(u256(_settings.expectedExecutionsPerDeployment)).asBytes(); - rawKey += FixedHash<1>(uint8_t(_isCreation ? 0 : 1)).asBytes(); + rawKey += FixedHash<1>(static_cast(_isCreation ? 1 : 0)).asBytes(); rawKey += keccak256(_settings.evmVersion.name()).asBytes(); yulAssert(!_settings.eofVersion.has_value() || *_settings.eofVersion > 0); - rawKey += FixedHash<1>(uint8_t(_settings.eofVersion ? 0 : *_settings.eofVersion)).asBytes(); + rawKey += FixedHash<1>(static_cast(_settings.eofVersion ? *_settings.eofVersion : 0)).asBytes(); rawKey += keccak256(_settings.yulOptimiserSteps).asBytes(); rawKey += keccak256(_settings.yulOptimiserCleanupSteps).asBytes(); From c9aa6f4d9d505f3ed6d1043e58aec9ed2674737a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Mon, 3 Mar 2025 18:16:51 +0100 Subject: [PATCH 0844/1022] ObjectOptimizer::calculateCacheKey(): Cast bool directly in uint_t --- libyul/ObjectOptimizer.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/libyul/ObjectOptimizer.cpp b/libyul/ObjectOptimizer.cpp index 07c25a0681c6..a09e88791577 100644 --- a/libyul/ObjectOptimizer.cpp +++ b/libyul/ObjectOptimizer.cpp @@ -154,9 +154,10 @@ std::optional ObjectOptimizer::calculateCacheKey( rawKey += keccak256(asmPrinter(_ast)).asBytes(); rawKey += keccak256(_debugData.formatUseSrcComment()).asBytes(); rawKey += h256(u256(_settings.language)).asBytes(); - rawKey += FixedHash<1>(static_cast(_settings.optimizeStackAllocation ? 1 : 0)).asBytes(); + static_assert(static_cast(static_cast(2)) == 1); + rawKey += FixedHash<1>(static_cast(_settings.optimizeStackAllocation)).asBytes(); rawKey += h256(u256(_settings.expectedExecutionsPerDeployment)).asBytes(); - rawKey += FixedHash<1>(static_cast(_isCreation ? 1 : 0)).asBytes(); + rawKey += FixedHash<1>(static_cast(_isCreation)).asBytes(); rawKey += keccak256(_settings.evmVersion.name()).asBytes(); yulAssert(!_settings.eofVersion.has_value() || *_settings.eofVersion > 0); rawKey += FixedHash<1>(static_cast(_settings.eofVersion ? *_settings.eofVersion : 0)).asBytes(); From 3286c9ea5c3511ad2fae0bd31c37174af9a92128 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Sat, 1 Mar 2025 21:55:13 +0100 Subject: [PATCH 0845/1022] CommonSyntaxTest::printErrorList(): Use the colored stream in a less misleading way --- test/CommonSyntaxTest.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/CommonSyntaxTest.cpp b/test/CommonSyntaxTest.cpp index 3cb908118ea2..ccf4added41e 100644 --- a/test/CommonSyntaxTest.cpp +++ b/test/CommonSyntaxTest.cpp @@ -197,15 +197,15 @@ void CommonSyntaxTest::printErrorList( for (auto const& error: _errorList) { { - util::AnsiColorized scope( + util::AnsiColorized formattedStream( _stream, _formatted, {BOLD, SourceReferenceFormatter::errorTextColor(Error::errorSeverity(error.type))} ); - _stream << _linePrefix << Error::formatErrorType(error.type); + formattedStream << _linePrefix << Error::formatErrorType(error.type); if (error.errorId.has_value()) - _stream << ' ' << error.errorId->error; - _stream << ": "; + formattedStream << ' ' << error.errorId->error; + formattedStream << ": "; } if (!error.sourceName.empty() || error.locationStart >= 0 || error.locationEnd >= 0) { From 78854ecf75cc5806a5f9872c29bd8a53fb7f62b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Sun, 2 Mar 2025 09:02:22 +0100 Subject: [PATCH 0846/1022] Standard JSON test case for Yul StackTooDeep --- .../in.sol | 10 +++++++ .../input.json | 12 ++++++++ .../output.json | 29 +++++++++++++++++++ 3 files changed, 51 insertions(+) create mode 100644 test/cmdlineTests/standard_stack_too_deep_from_code_transform/in.sol create mode 100644 test/cmdlineTests/standard_stack_too_deep_from_code_transform/input.json create mode 100644 test/cmdlineTests/standard_stack_too_deep_from_code_transform/output.json diff --git a/test/cmdlineTests/standard_stack_too_deep_from_code_transform/in.sol b/test/cmdlineTests/standard_stack_too_deep_from_code_transform/in.sol new file mode 100644 index 000000000000..aae75b841ce0 --- /dev/null +++ b/test/cmdlineTests/standard_stack_too_deep_from_code_transform/in.sol @@ -0,0 +1,10 @@ +contract C { + function f() public { + uint b; + abi.encodePacked( + b, b, b, b, b, b, b, b, + b, b, b, b, b, b, b, b, + b, b, b, b, b, b, b, b + ); + } +} diff --git a/test/cmdlineTests/standard_stack_too_deep_from_code_transform/input.json b/test/cmdlineTests/standard_stack_too_deep_from_code_transform/input.json new file mode 100644 index 000000000000..a01e842b384d --- /dev/null +++ b/test/cmdlineTests/standard_stack_too_deep_from_code_transform/input.json @@ -0,0 +1,12 @@ +{ + "language": "Solidity", + "sources": { + "in.sol": {"urls": ["standard_stack_too_deep_from_code_transform/in.sol"]} + }, + "settings": { + "viaIR": true, + "outputSelection": { + "*": {"*": ["evm.bytecode"]} + } + } +} diff --git a/test/cmdlineTests/standard_stack_too_deep_from_code_transform/output.json b/test/cmdlineTests/standard_stack_too_deep_from_code_transform/output.json new file mode 100644 index 000000000000..dbf1dfdcfcda --- /dev/null +++ b/test/cmdlineTests/standard_stack_too_deep_from_code_transform/output.json @@ -0,0 +1,29 @@ +{ + "errors": [ + { + "component": "general", + "formattedMessage": "YulException: Cannot swap Variable value23 with Slot 0x20: too deep in the stack by 9 slots in [ RET value23 value22 value21 value20 value19 value18 value17 value16 value15 value14 value13 value12 value11 value10 value9 value8 value7 value6 value5 value4 value3 value2 value1 value0 pos 0x20 ] +memoryguard was present. + --> in.sol:1:1: + | +1 | contract C { + | ^ (Relevant source part starts here and spans across multiple lines). + +", + "message": "Yul exception:Cannot swap Variable value23 with Slot 0x20: too deep in the stack by 9 slots in [ RET value23 value22 value21 value20 value19 value18 value17 value16 value15 value14 value13 value12 value11 value10 value9 value8 value7 value6 value5 value4 value3 value2 value1 value0 pos 0x20 ] +memoryguard was present.", + "severity": "error", + "sourceLocation": { + "end": 206, + "file": "in.sol", + "start": 0 + }, + "type": "YulException" + } + ], + "sources": { + "in.sol": { + "id": 0 + } + } +} From 887ec85bf4e7ac5d8e4dd5143a644346b5b940a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Sat, 1 Mar 2025 23:27:38 +0100 Subject: [PATCH 0847/1022] Disentangle handling of failed Yul assertions from Yul StackTooDeep errors --- Changelog.md | 1 + libsolidity/interface/StandardCompiler.cpp | 15 +++++++++++++-- libyul/Exceptions.h | 2 +- solc/CommandLineInterface.cpp | 10 ++++++++++ solc/main.cpp | 6 ++++++ .../stack_too_deep_from_code_transform/args | 1 + .../stack_too_deep_from_code_transform/err | 6 ++++++ .../stack_too_deep_from_code_transform/exit | 1 + .../stack_too_deep_from_code_transform/input.sol | 10 ++++++++++ .../output.json | 2 +- 10 files changed, 50 insertions(+), 4 deletions(-) create mode 100644 test/cmdlineTests/stack_too_deep_from_code_transform/args create mode 100644 test/cmdlineTests/stack_too_deep_from_code_transform/err create mode 100644 test/cmdlineTests/stack_too_deep_from_code_transform/exit create mode 100644 test/cmdlineTests/stack_too_deep_from_code_transform/input.sol diff --git a/Changelog.md b/Changelog.md index 7b15ce945885..bb7a20d093d2 100644 --- a/Changelog.md +++ b/Changelog.md @@ -16,6 +16,7 @@ Compiler Features: Bugfixes: + * Commandline Interface: Report StackTooDeep errors in compiler mode as proper errors instead of printing diagnostic information meant for internal compiler errors. * General: Fix internal compiler error when requesting IR AST outputs for interfaces and abstract contracts. * Metadata: Fix custom cleanup sequence missing from metadata when other optimizer settings have default values. * SMTChecker: Fix internal compiler error when analyzing overflowing expressions or bitwise negation of unsigned types involving constants. diff --git a/libsolidity/interface/StandardCompiler.cpp b/libsolidity/interface/StandardCompiler.cpp index 71fbf17e288b..eee29f921fc5 100644 --- a/libsolidity/interface/StandardCompiler.cpp +++ b/libsolidity/interface/StandardCompiler.cpp @@ -1412,6 +1412,7 @@ Json StandardCompiler::compileSolidity(StandardCompiler::InputsAndSettings _inpu )); } } + // NOTE: This includes langutil::StackTooDeepError. catch (CompilerError const& _exception) { errors.emplace_back(formatErrorWithException( @@ -1422,6 +1423,16 @@ Json StandardCompiler::compileSolidity(StandardCompiler::InputsAndSettings _inpu "Compiler error (" + _exception.lineInfo() + ")" )); } + catch (yul::StackTooDeepError const& _exception) + { + errors.emplace_back(formatErrorWithException( + compilerStack, + _exception, + Error::Type::YulException, + "general", + "" // No prefix needed. These messages already say it's a "stack too deep" error. + )); + } catch (InternalCompilerError const& _exception) { errors.emplace_back(formatErrorWithException( @@ -1437,14 +1448,14 @@ Json StandardCompiler::compileSolidity(StandardCompiler::InputsAndSettings _inpu // let StandardCompiler::compile handle this throw _exception; } - catch (yul::YulException const& _exception) + catch (YulAssertion const& _exception) { errors.emplace_back(formatErrorWithException( compilerStack, _exception, Error::Type::YulException, "general", - "Yul exception" + "Yul assertion failed (" + _exception.lineInfo() + ")" )); } catch (smtutil::SMTLogicError const& _exception) diff --git a/libyul/Exceptions.h b/libyul/Exceptions.h index f92268180971..4f08e192f788 100644 --- a/libyul/Exceptions.h +++ b/libyul/Exceptions.h @@ -36,7 +36,7 @@ namespace solidity::yul struct YulException: virtual util::Exception {}; struct OptimizerException: virtual YulException {}; struct CodegenException: virtual YulException {}; -struct YulAssertion: virtual YulException {}; +struct YulAssertion: virtual util::Exception {}; struct StackTooDeepError: virtual YulException { diff --git a/solc/CommandLineInterface.cpp b/solc/CommandLineInterface.cpp index 4fd730096e85..e57cd77a98a2 100644 --- a/solc/CommandLineInterface.cpp +++ b/solc/CommandLineInterface.cpp @@ -1009,6 +1009,7 @@ void CommandLineInterface::compile() if (!successful) solThrow(CommandLineExecutionError, ""); } + // NOTE: This includes langutil::StackTooDeepError. catch (CompilerError const& _exception) { m_hasOutput = true; @@ -1018,6 +1019,15 @@ void CommandLineInterface::compile() ); solThrow(CommandLineExecutionError, ""); } + catch (yul::StackTooDeepError const& _exception) + { + m_hasOutput = true; + formatter.printExceptionInformation( + _exception, + Error::errorSeverity(Error::Type::YulException) + ); + solThrow(CommandLineExecutionError, ""); + } } void CommandLineInterface::handleCombinedJSON() diff --git a/solc/main.cpp b/solc/main.cpp index c6c3df7a2eba..49994559423a 100644 --- a/solc/main.cpp +++ b/solc/main.cpp @@ -51,6 +51,12 @@ int main(int argc, char** argv) std::cerr << boost::diagnostic_information(_exception); return 2; } + catch (yul::YulAssertion const& _exception) + { + std::cerr << "Yul assertion failed:" << std::endl; + std::cerr << boost::diagnostic_information(_exception); + return 2; + } catch (...) { std::cerr << "Uncaught exception:" << std::endl; diff --git a/test/cmdlineTests/stack_too_deep_from_code_transform/args b/test/cmdlineTests/stack_too_deep_from_code_transform/args new file mode 100644 index 000000000000..b182392aac61 --- /dev/null +++ b/test/cmdlineTests/stack_too_deep_from_code_transform/args @@ -0,0 +1 @@ +--via-ir --bin diff --git a/test/cmdlineTests/stack_too_deep_from_code_transform/err b/test/cmdlineTests/stack_too_deep_from_code_transform/err new file mode 100644 index 000000000000..588f4d437945 --- /dev/null +++ b/test/cmdlineTests/stack_too_deep_from_code_transform/err @@ -0,0 +1,6 @@ +Error: Cannot swap Variable value23 with Slot 0x20: too deep in the stack by 9 slots in [ RET value23 value22 value21 value20 value19 value18 value17 value16 value15 value14 value13 value12 value11 value10 value9 value8 value7 value6 value5 value4 value3 value2 value1 value0 pos 0x20 ] +memoryguard was present. + --> stack_too_deep_from_code_transform/input.sol:1:1: + | +1 | contract C { + | ^ (Relevant source part starts here and spans across multiple lines). diff --git a/test/cmdlineTests/stack_too_deep_from_code_transform/exit b/test/cmdlineTests/stack_too_deep_from_code_transform/exit new file mode 100644 index 000000000000..d00491fd7e5b --- /dev/null +++ b/test/cmdlineTests/stack_too_deep_from_code_transform/exit @@ -0,0 +1 @@ +1 diff --git a/test/cmdlineTests/stack_too_deep_from_code_transform/input.sol b/test/cmdlineTests/stack_too_deep_from_code_transform/input.sol new file mode 100644 index 000000000000..aae75b841ce0 --- /dev/null +++ b/test/cmdlineTests/stack_too_deep_from_code_transform/input.sol @@ -0,0 +1,10 @@ +contract C { + function f() public { + uint b; + abi.encodePacked( + b, b, b, b, b, b, b, b, + b, b, b, b, b, b, b, b, + b, b, b, b, b, b, b, b + ); + } +} diff --git a/test/cmdlineTests/standard_stack_too_deep_from_code_transform/output.json b/test/cmdlineTests/standard_stack_too_deep_from_code_transform/output.json index dbf1dfdcfcda..b4b0139fee69 100644 --- a/test/cmdlineTests/standard_stack_too_deep_from_code_transform/output.json +++ b/test/cmdlineTests/standard_stack_too_deep_from_code_transform/output.json @@ -10,7 +10,7 @@ memoryguard was present. | ^ (Relevant source part starts here and spans across multiple lines). ", - "message": "Yul exception:Cannot swap Variable value23 with Slot 0x20: too deep in the stack by 9 slots in [ RET value23 value22 value21 value20 value19 value18 value17 value16 value15 value14 value13 value12 value11 value10 value9 value8 value7 value6 value5 value4 value3 value2 value1 value0 pos 0x20 ] + "message": "Cannot swap Variable value23 with Slot 0x20: too deep in the stack by 9 slots in [ RET value23 value22 value21 value20 value19 value18 value17 value16 value15 value14 value13 value12 value11 value10 value9 value8 value7 value6 value5 value4 value3 value2 value1 value0 pos 0x20 ] memoryguard was present.", "severity": "error", "sourceLocation": { From e899fb9da9fedeaa8f922217bde89068cc7918a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Sun, 2 Mar 2025 10:06:44 +0100 Subject: [PATCH 0848/1022] StandardCompiler: Provide full ICE output on failed assertions --- libsolidity/interface/StandardCompiler.cpp | 31 ++++++++++------------ 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/libsolidity/interface/StandardCompiler.cpp b/libsolidity/interface/StandardCompiler.cpp index eee29f921fc5..6bd5cd2317b3 100644 --- a/libsolidity/interface/StandardCompiler.cpp +++ b/libsolidity/interface/StandardCompiler.cpp @@ -131,7 +131,7 @@ Json formatErrorWithException( ); if (std::string const* description = _exception.comment()) - message = ((_message.length() > 0) ? (_message + ":") : "") + *description; + message = ((_message.length() > 0) ? (_message + ": ") : "") + *description; else message = _message; @@ -1433,14 +1433,12 @@ Json StandardCompiler::compileSolidity(StandardCompiler::InputsAndSettings _inpu "" // No prefix needed. These messages already say it's a "stack too deep" error. )); } - catch (InternalCompilerError const& _exception) + catch (InternalCompilerError const&) { - errors.emplace_back(formatErrorWithException( - compilerStack, - _exception, + errors.emplace_back(formatError( Error::Type::InternalCompilerError, "general", - "Internal compiler error (" + _exception.lineInfo() + ")" + "Internal compiler error:\n" + boost::current_exception_diagnostic_information() )); } catch (UnimplementedFeatureError const& _exception) @@ -1448,24 +1446,20 @@ Json StandardCompiler::compileSolidity(StandardCompiler::InputsAndSettings _inpu // let StandardCompiler::compile handle this throw _exception; } - catch (YulAssertion const& _exception) + catch (YulAssertion const&) { - errors.emplace_back(formatErrorWithException( - compilerStack, - _exception, + errors.emplace_back(formatError( Error::Type::YulException, "general", - "Yul assertion failed (" + _exception.lineInfo() + ")" + "Yul assertion failed:\n" + boost::current_exception_diagnostic_information() )); } - catch (smtutil::SMTLogicError const& _exception) + catch (smtutil::SMTLogicError const&) { - errors.emplace_back(formatErrorWithException( - compilerStack, - _exception, + errors.emplace_back(formatError( Error::Type::SMTLogicException, "general", - "SMT logic exception" + "SMT logic error:\n" + boost::current_exception_diagnostic_information() )); } catch (...) @@ -1838,7 +1832,10 @@ Json StandardCompiler::compile(Json const& _input) noexcept } catch (...) { - return formatFatalError(Error::Type::InternalCompilerError, "Internal exception in StandardCompiler::compile: " + boost::current_exception_diagnostic_information()); + return formatFatalError( + Error::Type::InternalCompilerError, + "Uncaught exception:\n" + boost::current_exception_diagnostic_information() + ); } } From 688bd0dea86cd8e2d4d7fb9741722028b96a152a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Sun, 2 Mar 2025 00:59:22 +0100 Subject: [PATCH 0849/1022] SourceReferenceFormatter: Don't hide source location of the name of the input file is an empty string --- Changelog.md | 1 + liblangutil/SourceReferenceFormatter.cpp | 6 +++--- test/cmdlineTests/standard_empty_file_name/output.json | 4 ++++ 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/Changelog.md b/Changelog.md index bb7a20d093d2..65c04b106791 100644 --- a/Changelog.md +++ b/Changelog.md @@ -17,6 +17,7 @@ Compiler Features: Bugfixes: * Commandline Interface: Report StackTooDeep errors in compiler mode as proper errors instead of printing diagnostic information meant for internal compiler errors. + * Error Reporting: Fix error locations not being shown for source files with empty names. * General: Fix internal compiler error when requesting IR AST outputs for interfaces and abstract contracts. * Metadata: Fix custom cleanup sequence missing from metadata when other optimizer settings have default values. * SMTChecker: Fix internal compiler error when analyzing overflowing expressions or bitwise negation of unsigned types involving constants. diff --git a/liblangutil/SourceReferenceFormatter.cpp b/liblangutil/SourceReferenceFormatter.cpp index c48cb328d5f9..12308bf0d40b 100644 --- a/liblangutil/SourceReferenceFormatter.cpp +++ b/liblangutil/SourceReferenceFormatter.cpp @@ -114,11 +114,11 @@ AnsiColorized SourceReferenceFormatter::diagColored() const void SourceReferenceFormatter::printSourceLocation(SourceReference const& _ref) { - if (_ref.sourceName.empty()) - return; // Nothing we can print here - if (_ref.position.line < 0) { + if (_ref.sourceName.empty()) + return; // Nothing we can print here + frameColored() << "-->"; m_stream << ' ' << _ref.sourceName << '\n'; return; // No line available, nothing else to print diff --git a/test/cmdlineTests/standard_empty_file_name/output.json b/test/cmdlineTests/standard_empty_file_name/output.json index 1fd016e54e81..b4e525c21516 100644 --- a/test/cmdlineTests/standard_empty_file_name/output.json +++ b/test/cmdlineTests/standard_empty_file_name/output.json @@ -4,6 +4,10 @@ "component": "general", "errorCode": "2904", "formattedMessage": "DeclarationError: Declaration \"A\" not found in \"\" (referenced as \".\"). + --> :2:24: + | +2 | pragma solidity >=0.0; import {A} from \".\"; + | ^^^^^^^^^^^^^^^^^^^^ ", "message": "Declaration \"A\" not found in \"\" (referenced as \".\").", From 36ec42d1ae48ada54ca3a3d5095bbea5a9d16373 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Sun, 2 Mar 2025 00:45:18 +0100 Subject: [PATCH 0850/1022] CompilerStack::loadGeneratedIR(): Include error codes in the assertion message --- libsolidity/interface/CompilerStack.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/libsolidity/interface/CompilerStack.cpp b/libsolidity/interface/CompilerStack.cpp index 2748c09cda94..9582939f5e25 100644 --- a/libsolidity/interface/CompilerStack.cpp +++ b/libsolidity/interface/CompilerStack.cpp @@ -827,7 +827,12 @@ YulStack CompilerStack::loadGeneratedIR(std::string const& _ir) const yulAnalysisSuccessful, _ir + "\n\n" "Invalid IR generated:\n" + - SourceReferenceFormatter::formatErrorInformation(stack.errors(), stack) + "\n" + SourceReferenceFormatter::formatErrorInformation( + stack.errors(), + stack, // _charStreamProvider + false, // _colored + true // _withErrorIds + ) + "\n" ); return stack; From c422fa56a02df0de70e94da81148245981f70e05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Sun, 2 Mar 2025 00:36:36 +0100 Subject: [PATCH 0851/1022] AsmAnalyzer::analyzeStrictAssertCorrect(): Print source and errors when analysis fails --- libyul/AsmAnalysis.cpp | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/libyul/AsmAnalysis.cpp b/libyul/AsmAnalysis.cpp index aa3e23e2626f..b6ff862b3850 100644 --- a/libyul/AsmAnalysis.cpp +++ b/libyul/AsmAnalysis.cpp @@ -113,7 +113,36 @@ AsmAnalysisInfo AsmAnalyzer::analyzeStrictAssertCorrect( {}, std::move(_objectStructure) ).analyze(_astRoot); - yulAssert(success && !errors.hasErrors(), "Invalid assembly/yul code."); + + if (!success) + { + auto formatErrors = [](ErrorList const& _errorList) { + std::vector formattedErrors; + for (std::shared_ptr const& error: _errorList) + { + yulAssert(error->comment()); + formattedErrors.push_back(fmt::format( + // Intentionally not showing source locations because we don't have the original + // source here and it's unlikely they match the pretty-printed version. + // They may not even match the original source if the AST was modified by the optimizer. + "- {} {}: {}", + Error::formatErrorType(error->type()), + error->errorId().error, + *error->comment() + )); + } + return joinHumanReadable(formattedErrors, "\n"); + }; + + yulAssert(errors.hasErrors(), "Yul analysis failed but did not report any errors."); + yulAssert(false, fmt::format( + "{}\n\nExpected valid Yul, but errors were reported during analysis:\n{}", + AsmPrinter{_dialect}(_astRoot), + formatErrors(errorList) + )); + } + + yulAssert(!errors.hasErrors()); return analysisInfo; } From 8df4c81bc6aa2ce69609f12cb232f52a7d116da2 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Mon, 10 Feb 2025 09:38:48 +0100 Subject: [PATCH 0852/1022] Yul FunctionCallFinder uses FunctionHandle instead of strings as search key --- libyul/backends/evm/EVMObjectCompiler.cpp | 7 ++++--- libyul/optimiser/FullInliner.cpp | 11 +++++++---- libyul/optimiser/FunctionCallFinder.cpp | 22 ++++++++++------------ libyul/optimiser/FunctionCallFinder.h | 9 +++------ libyul/optimiser/StackLimitEvader.cpp | 6 ++++-- test/libsolidity/MemoryGuardTest.cpp | 12 ++++++++---- 6 files changed, 36 insertions(+), 31 deletions(-) diff --git a/libyul/backends/evm/EVMObjectCompiler.cpp b/libyul/backends/evm/EVMObjectCompiler.cpp index 30f06bc97385..830c32752dba 100644 --- a/libyul/backends/evm/EVMObjectCompiler.cpp +++ b/libyul/backends/evm/EVMObjectCompiler.cpp @@ -92,11 +92,12 @@ void EVMObjectCompiler::run(Object const& _object, bool _optimize) ); if (!stackErrors.empty()) { - yulAssert(_object.dialect()); + yulAssert(evmDialect->providesObjectAccess()); + auto const memoryGuardHandle = evmDialect->findBuiltin("memoryguard"); + yulAssert(memoryGuardHandle, "Compiling with object access, memoryguard should be available as builtin."); std::vector memoryGuardCalls = findFunctionCalls( _object.code()->root(), - "memoryguard", - *_object.dialect() + *memoryGuardHandle ); auto stackError = stackErrors.front(); std::string msg = stackError.comment() ? *stackError.comment() : ""; diff --git a/libyul/optimiser/FullInliner.cpp b/libyul/optimiser/FullInliner.cpp index 4b390f4f271a..894ada60962e 100644 --- a/libyul/optimiser/FullInliner.cpp +++ b/libyul/optimiser/FullInliner.cpp @@ -83,10 +83,13 @@ FullInliner::FullInliner(Block& _ast, NameDispenser& _dispenser, Dialect const& } // Check for memory guard. - std::vector memoryGuardCalls = findFunctionCalls(_ast, "memoryguard", m_dialect); - // We will perform less aggressive inlining, if no ``memoryguard`` call is found. - if (!memoryGuardCalls.empty()) - m_hasMemoryGuard = true; + if (auto const memoryGuard = m_dialect.findBuiltin("memoryguard")) + { + std::vector memoryGuardCalls = findFunctionCalls(_ast, *memoryGuard); + // We will perform less aggressive inlining, if no ``memoryguard`` call is found. + if (!memoryGuardCalls.empty()) + m_hasMemoryGuard = true; + } } void FullInliner::run(Pass _pass) diff --git a/libyul/optimiser/FunctionCallFinder.cpp b/libyul/optimiser/FunctionCallFinder.cpp index 4c85d77f5246..9f5c75b43749 100644 --- a/libyul/optimiser/FunctionCallFinder.cpp +++ b/libyul/optimiser/FunctionCallFinder.cpp @@ -19,7 +19,6 @@ #include #include -#include #include using namespace solidity; @@ -32,35 +31,34 @@ class MaybeConstFunctionCallFinder: Base { public: using MaybeConstBlock = std::conditional_t, Block const, Block>; - static std::vector run(MaybeConstBlock& _block, std::string_view const _functionName, Dialect const& _dialect) + static std::vector run(MaybeConstBlock& _block, FunctionHandle const& _functionHandle) { - MaybeConstFunctionCallFinder functionCallFinder(_functionName, _dialect); + MaybeConstFunctionCallFinder functionCallFinder(_functionHandle); functionCallFinder(_block); return functionCallFinder.m_calls; } private: - explicit MaybeConstFunctionCallFinder(std::string_view const _functionName, Dialect const& _dialect): - m_dialect(_dialect), m_functionName(_functionName), m_calls() {} + explicit MaybeConstFunctionCallFinder(FunctionHandle const& _functionHandle): + m_functionHandle(_functionHandle), m_calls() {} using Base::operator(); void operator()(ResultType& _functionCall) override { Base::operator()(_functionCall); - if (resolveFunctionName(_functionCall.functionName, m_dialect) == m_functionName) + if (functionNameToHandle(_functionCall.functionName) == m_functionHandle) m_calls.emplace_back(&_functionCall); } - Dialect const& m_dialect; - std::string_view m_functionName; + FunctionHandle const& m_functionHandle; std::vector m_calls; }; } -std::vector solidity::yul::findFunctionCalls(Block& _block, std::string_view const _functionName, Dialect const& _dialect) +std::vector yul::findFunctionCalls(Block& _block, FunctionHandle const& _functionHandle) { - return MaybeConstFunctionCallFinder::run(_block, _functionName, _dialect); + return MaybeConstFunctionCallFinder::run(_block, _functionHandle); } -std::vector solidity::yul::findFunctionCalls(Block const& _block, std::string_view const _functionName, Dialect const& _dialect) +std::vector yul::findFunctionCalls(Block const& _block, FunctionHandle const& _functionHandle) { - return MaybeConstFunctionCallFinder::run(_block, _functionName, _dialect); + return MaybeConstFunctionCallFinder::run(_block, _functionHandle); } diff --git a/libyul/optimiser/FunctionCallFinder.h b/libyul/optimiser/FunctionCallFinder.h index 1c21a0115985..560ecfc38bfa 100644 --- a/libyul/optimiser/FunctionCallFinder.h +++ b/libyul/optimiser/FunctionCallFinder.h @@ -20,28 +20,25 @@ #pragma once -#include +#include -#include #include namespace solidity::yul { -class Dialect; - /** * Finds all calls to a function of a given name using an ASTModifier. * * Prerequisite: Disambiguator */ -std::vector findFunctionCalls(Block& _block, std::string_view _functionName, Dialect const& _dialect); +std::vector findFunctionCalls(Block& _block, FunctionHandle const& _functionHandle); /** * Finds all calls to a function of a given name using an ASTWalker. * * Prerequisite: Disambiguator */ -std::vector findFunctionCalls(Block const& _block, std::string_view _functionName, Dialect const& _dialect); +std::vector findFunctionCalls(Block const& _block, FunctionHandle const& _functionHandle); } diff --git a/libyul/optimiser/StackLimitEvader.cpp b/libyul/optimiser/StackLimitEvader.cpp index 13a3bbd87afa..f70bc0c1d2a7 100644 --- a/libyul/optimiser/StackLimitEvader.cpp +++ b/libyul/optimiser/StackLimitEvader.cpp @@ -201,7 +201,9 @@ void StackLimitEvader::run( "StackLimitEvader does not support EOF." ); - std::vector memoryGuardCalls = findFunctionCalls(_astRoot, "memoryguard", *evmDialect); + auto const memoryGuardHandle = evmDialect->findBuiltin("memoryguard"); + yulAssert(memoryGuardHandle, "Compiling with object access, memoryguard should be available as builtin."); + std::vector const memoryGuardCalls = findFunctionCalls(_astRoot, *memoryGuardHandle); // Do not optimise, if no ``memoryguard`` call is found. if (memoryGuardCalls.empty()) return; @@ -233,7 +235,7 @@ void StackLimitEvader::run( StackToMemoryMover::run(_context, reservedMemory, memoryOffsetAllocator.slotAllocations, requiredSlots, _astRoot); reservedMemory += 32 * requiredSlots; - for (FunctionCall* memoryGuardCall: findFunctionCalls(_astRoot, "memoryguard", *evmDialect)) + for (FunctionCall* memoryGuardCall: findFunctionCalls(_astRoot, *memoryGuardHandle)) { Literal* literal = std::get_if(&memoryGuardCall->arguments.front()); yulAssert(literal && literal->kind == LiteralKind::Number, ""); diff --git a/test/libsolidity/MemoryGuardTest.cpp b/test/libsolidity/MemoryGuardTest.cpp index 0f4230d5adec..f7d07aa4447c 100644 --- a/test/libsolidity/MemoryGuardTest.cpp +++ b/test/libsolidity/MemoryGuardTest.cpp @@ -76,11 +76,15 @@ TestCase::TestResult MemoryGuardTest::run(std::ostream& _stream, std::string con } auto handleObject = [&](std::string const& _kind, Object const& _object) { - m_obtainedResult += contractName + "(" + _kind + ") " + (findFunctionCalls( + auto const memoryGuardHandle = yulStack.dialect().findBuiltin("memoryguard"); + m_obtainedResult += contractName + "(" + _kind + ") "; + if (memoryGuardHandle && !findFunctionCalls( _object.code()->root(), - "memoryguard", - yulStack.dialect() - ).empty() ? "false" : "true") + "\n"; + *memoryGuardHandle + ).empty()) + m_obtainedResult += "true\n"; + else + m_obtainedResult += "false\n"; }; handleObject("creation", *yulStack.parserResult()); size_t deployedIndex = yulStack.parserResult()->subIndexByName.at( From b07843da11c632a295c4579537250b0666f1b8b1 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Wed, 19 Feb 2025 08:45:05 +0100 Subject: [PATCH 0853/1022] Adds tests using memoryguard identifiers in inline-assembly to assert mangling --- .../args | 1 + .../input.sol | 15 +++ .../output | 123 ++++++++++++++++++ ...guard_with_inline_assembly_identifiers.sol | 26 ++++ 4 files changed, 165 insertions(+) create mode 100644 test/cmdlineTests/memoryguard_shadowing_by_inline_assembly_identifiers/args create mode 100644 test/cmdlineTests/memoryguard_shadowing_by_inline_assembly_identifiers/input.sol create mode 100644 test/cmdlineTests/memoryguard_shadowing_by_inline_assembly_identifiers/output create mode 100644 test/libsolidity/memoryGuardTests/shadowing_memoryguard_with_inline_assembly_identifiers.sol diff --git a/test/cmdlineTests/memoryguard_shadowing_by_inline_assembly_identifiers/args b/test/cmdlineTests/memoryguard_shadowing_by_inline_assembly_identifiers/args new file mode 100644 index 000000000000..d0fe39023051 --- /dev/null +++ b/test/cmdlineTests/memoryguard_shadowing_by_inline_assembly_identifiers/args @@ -0,0 +1 @@ +--ir --debug-info none \ No newline at end of file diff --git a/test/cmdlineTests/memoryguard_shadowing_by_inline_assembly_identifiers/input.sol b/test/cmdlineTests/memoryguard_shadowing_by_inline_assembly_identifiers/input.sol new file mode 100644 index 000000000000..685bec80771a --- /dev/null +++ b/test/cmdlineTests/memoryguard_shadowing_by_inline_assembly_identifiers/input.sol @@ -0,0 +1,15 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity >=0.0; + +contract C { + function f() public pure { + // NOTE: memoryguard is a builtin but only in pure Yul, not inline assembly. + // NOTE: memoryguard is not a reserved identifier. + // The expectation of this test is to not see the shadowed memoryguard within the generated Yul code but rather + // a mangled version of it + assembly { function memoryguard() {} } + assembly { function f(memoryguard) {} } + assembly { function f() -> memoryguard {} } + assembly { let memoryguard } + } +} diff --git a/test/cmdlineTests/memoryguard_shadowing_by_inline_assembly_identifiers/output b/test/cmdlineTests/memoryguard_shadowing_by_inline_assembly_identifiers/output new file mode 100644 index 000000000000..842580597d12 --- /dev/null +++ b/test/cmdlineTests/memoryguard_shadowing_by_inline_assembly_identifiers/output @@ -0,0 +1,123 @@ +IR: + +/// @use-src 0:"memoryguard_shadowing_by_inline_assembly_identifiers/input.sol" +object "C_10" { + code { + + mstore(64, memoryguard(128)) + if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } + + constructor_C_10() + + let _1 := allocate_unbounded() + codecopy(_1, dataoffset("C_10_deployed"), datasize("C_10_deployed")) + + return(_1, datasize("C_10_deployed")) + + function allocate_unbounded() -> memPtr { + memPtr := mload(64) + } + + function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() { + revert(0, 0) + } + + function constructor_C_10() { + + } + + } + /// @use-src 0:"memoryguard_shadowing_by_inline_assembly_identifiers/input.sol" + object "C_10_deployed" { + code { + + mstore(64, memoryguard(128)) + + if iszero(lt(calldatasize(), 4)) + { + let selector := shift_right_224_unsigned(calldataload(0)) + switch selector + + case 0x26121ff0 + { + // f() + + external_fun_f_9() + } + + default {} + } + + revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() + + function shift_right_224_unsigned(value) -> newValue { + newValue := + + shr(224, value) + + } + + function allocate_unbounded() -> memPtr { + memPtr := mload(64) + } + + function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() { + revert(0, 0) + } + + function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() { + revert(0, 0) + } + + function abi_decode_tuple_(headStart, dataEnd) { + if slt(sub(dataEnd, headStart), 0) { revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() } + + } + + function abi_encode_tuple__to__fromStack(headStart ) -> tail { + tail := add(headStart, 0) + + } + + function external_fun_f_9() { + + if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } + abi_decode_tuple_(4, calldatasize()) + fun_f_9() + let memPos := allocate_unbounded() + let memEnd := abi_encode_tuple__to__fromStack(memPos ) + return(memPos, sub(memEnd, memPos)) + + } + + function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() { + revert(0, 0) + } + + function fun_f_9() { + + { + function usr$memoryguard() + { } + } + + { + function usr$f(usr$memoryguard) + { } + } + + { + function usr$f() -> usr$memoryguard + { } + } + + { let usr$memoryguard } + + } + + } + + data ".metadata" hex"" + } + +} diff --git a/test/libsolidity/memoryGuardTests/shadowing_memoryguard_with_inline_assembly_identifiers.sol b/test/libsolidity/memoryGuardTests/shadowing_memoryguard_with_inline_assembly_identifiers.sol new file mode 100644 index 000000000000..5152882bb2a0 --- /dev/null +++ b/test/libsolidity/memoryGuardTests/shadowing_memoryguard_with_inline_assembly_identifiers.sol @@ -0,0 +1,26 @@ +// NOTE: memoryguard is a builtin but only in pure Yul, not inline assembly. +// NOTE: memoryguard is not a reserved identifier. + +contract C { + constructor() { + // The expectation of this test is to see a 'true' outcome, indicating the memoryguard builtin being used + // due to explicitly marking the inline assembly as memory-safe + + assembly ("memory-safe") { mstore(42, 42) function memoryguard() {} } + assembly ("memory-safe") { mstore(42, 42) function f(memoryguard) {} } + assembly ("memory-safe") { mstore(42, 42) function f() -> memoryguard {} } + assembly ("memory-safe") { mstore(42, 42) let memoryguard } + } + + function f() public pure { + // The expectation of this test is to see a 'false' outcome, indicating the memoryguard builtin not being used + + assembly { mstore(42, 42) function memoryguard() {} } + assembly { mstore(42, 42) function f(memoryguard) {} } + assembly { mstore(42, 42) function f() -> memoryguard {} } + assembly { mstore(42, 42) let memoryguard } + } +} +// ---- +// :C(creation) true +// :C(runtime) false From 273a6a4569d928d2e19b842afa6fe60db2ff6fe7 Mon Sep 17 00:00:00 2001 From: r0qs Date: Mon, 3 Mar 2025 14:47:55 +0100 Subject: [PATCH 0854/1022] Bump minimum Node.js version for Solc-Js to v12 --- Changelog.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Changelog.md b/Changelog.md index 65c04b106791..13cc8db13346 100644 --- a/Changelog.md +++ b/Changelog.md @@ -38,6 +38,10 @@ Build system: * Linux release builds are fully static again and no longer depend on ``glibc``. * Switch from C++17 to C++20 as the target standard. + +Solc-Js: + * The wrapper now requires at least nodejs v12. + ### 0.8.28 (2024-10-09) Language Features: From e1956d9fdca088e1af94e940c2556681757f0bb8 Mon Sep 17 00:00:00 2001 From: comfsrt <155266597+comfsrt@users.noreply.github.com> Date: Wed, 5 Mar 2025 16:22:39 +0100 Subject: [PATCH 0855/1022] fix errors in comments (#15822) * Update libsolc.cpp * Update ControlFlowBuilder.h * Update ABI.h --- libsolc/libsolc.cpp | 2 +- libsolidity/analysis/ControlFlowBuilder.h | 2 +- libsolidity/interface/ABI.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/libsolc/libsolc.cpp b/libsolc/libsolc.cpp index b49905130ccc..47dddb3aea08 100644 --- a/libsolc/libsolc.cpp +++ b/libsolc/libsolc.cpp @@ -63,7 +63,7 @@ std::string takeOverAllocation(char const* _data) abort(); } -/// Resizes a std::std::string to the proper length based on the occurrence of a zero terminator. +/// Resizes a std::string to the proper length based on the occurrence of a zero terminator. void truncateCString(std::string& _data) { size_t pos = _data.find('\0'); diff --git a/libsolidity/analysis/ControlFlowBuilder.h b/libsolidity/analysis/ControlFlowBuilder.h index 93bc52bd6936..7af843fcaec9 100644 --- a/libsolidity/analysis/ControlFlowBuilder.h +++ b/libsolidity/analysis/ControlFlowBuilder.h @@ -137,7 +137,7 @@ class ControlFlowBuilder: private ASTConstVisitor, private yul::ASTWalker } /// Merges the control flow of @a _nodes to @a _endNode. - /// If @a _endNode is nullptr, a new node is creates and used as end node. + /// If @a _endNode is nullptr, a new node is created and used as end node. /// Sets the merge destination as current node. /// Note: @a _endNode may be one of the nodes in @a _nodes. template diff --git a/libsolidity/interface/ABI.h b/libsolidity/interface/ABI.h index 22e306c4322b..65f130247147 100644 --- a/libsolidity/interface/ABI.h +++ b/libsolidity/interface/ABI.h @@ -37,7 +37,7 @@ class ABI public: /// Get the ABI Interface of the contract /// @param _contractDef The contract definition - /// @return A JSONrepresentation of the contract's ABI Interface + /// @return A JSON representation of the contract's ABI Interface static Json generate(ContractDefinition const& _contractDef); private: /// @returns a json value suitable for a list of types in function input or output From e745feabeffaa6bb78cc9304f858bc0a9efca13d Mon Sep 17 00:00:00 2001 From: Matheus Aguiar Date: Fri, 20 Dec 2024 16:17:38 -0300 Subject: [PATCH 0856/1022] Add and update tests --- libsolidity/interface/CompilerStack.cpp | 3 - .../args | 1 - .../err | 5 - .../exit | 1 - .../stdin | 4 - .../args | 1 - .../err | 5 - .../exit | 1 - .../storage_layout_specifier_smoke/args | 1 + .../storage_layout_specifier_smoke/output | 85 ++++ .../storage_layout_specifier_smoke/stdin | 9 + .../args | 1 + .../output | 20 + .../stdin | 4 +- .../args | 1 + .../output | 435 ++++++++++++++++++ .../stdin | 31 ++ .../args | 1 - .../err | 1 - .../exit | 1 - .../output | 2 - .../stdin | 4 - .../base_slot_max_value.sol | 7 + .../storageLayoutSpecifier/constructor.sol | 29 ++ .../storageLayoutSpecifier/delete.sol | 30 ++ .../delete_transient_storage.sol | 20 + .../dynamic_array_storage_end.sol | 29 ++ .../function_from_base_contract.sol | 30 ++ .../storageLayoutSpecifier/getters.sol | 9 + .../inheritance_from_abstract_contract.sol | 17 + .../inheritance_from_interface.sol | 15 + ...ritance_from_same_base_state_var_slots.sol | 47 ++ .../inheritance_simple.sol | 16 + ...inheritance_state_variable_slot_offset.sol | 19 + .../inline_assembly_direct_load.sol | 12 + .../inline_assembly_direct_store.sol | 12 + .../last_allowed_storage_slot.sol | 10 + .../mapping_storage_end.sol | 22 + .../multiple_inheritance.sol | 40 ++ .../multiple_inheritance_state_var_slots.sol | 24 + .../state_variable_arithmetic_expression.sol | 20 + .../state_variable_constant_and_immutable.sol | 16 + .../state_variable_dynamic_array.sol | 50 ++ .../state_variable_enum.sol | 18 + .../state_variable_mapping.sol | 33 ++ ...e_variable_reference_types_slot_offset.sol | 33 ++ .../state_variable_slot_offset.sol | 13 + .../state_variable_struct.sol | 39 ++ .../state_variables_transient.sol | 23 + .../storage_reference_array.sol | 21 + .../storage_reference_inheritance.sol | 25 + .../storage_reference_library_function.sol | 31 ++ .../transient_state_variable_slot_offset.sol | 18 + .../variable_cleanup.sol | 15 + .../variable_cleanup_sstore.sol | 20 + .../virtual_functions.sol | 34 ++ ..._contract_inheriting_from_non_abstract.sol | 4 + .../contract_named_at.sol | 1 - .../contract_named_layout.sol | 1 - ...tract_with_members_named_layout_and_at.sol | 1 - .../inheriting_from_abstract_contract.sol | 1 - .../inheriting_from_interface.sol | 1 - .../intermediate_operation_out_of_range.sol | 1 - ...layout_specification_binary_expression.sol | 1 - .../layout_specification_max_value.sol | 1 - .../layout_with_inheritance.sol | 1 - .../literal_with_underscore.sol | 1 - .../multi_token_expression.sol | 1 - .../rational_number_zero_fractional_part.sol | 1 - .../same_ancestor_two_contracts.sol | 1 - .../storageLayoutSpecifier/simple_layout.sol | 1 - 71 files changed, 1387 insertions(+), 45 deletions(-) delete mode 100644 test/cmdlineTests/storage_layout_specifier_codegen_error/args delete mode 100644 test/cmdlineTests/storage_layout_specifier_codegen_error/err delete mode 100644 test/cmdlineTests/storage_layout_specifier_codegen_error/exit delete mode 100644 test/cmdlineTests/storage_layout_specifier_codegen_error/stdin delete mode 100644 test/cmdlineTests/storage_layout_specifier_ir_codegen_error/args delete mode 100644 test/cmdlineTests/storage_layout_specifier_ir_codegen_error/err delete mode 100644 test/cmdlineTests/storage_layout_specifier_ir_codegen_error/exit create mode 100644 test/cmdlineTests/storage_layout_specifier_smoke/args create mode 100644 test/cmdlineTests/storage_layout_specifier_smoke/output create mode 100644 test/cmdlineTests/storage_layout_specifier_smoke/stdin create mode 100644 test/cmdlineTests/storage_layout_specifier_smoke_ir_codegen/args create mode 100644 test/cmdlineTests/storage_layout_specifier_smoke_ir_codegen/output rename test/cmdlineTests/{storage_layout_specifier_ir_codegen_error => storage_layout_specifier_smoke_ir_codegen}/stdin (57%) create mode 100644 test/cmdlineTests/storage_layout_specifier_storage_layout_output/args create mode 100644 test/cmdlineTests/storage_layout_specifier_storage_layout_output/output create mode 100644 test/cmdlineTests/storage_layout_specifier_storage_layout_output/stdin delete mode 100644 test/cmdlineTests/storage_layout_specifier_storage_layout_output_error/args delete mode 100644 test/cmdlineTests/storage_layout_specifier_storage_layout_output_error/err delete mode 100644 test/cmdlineTests/storage_layout_specifier_storage_layout_output_error/exit delete mode 100644 test/cmdlineTests/storage_layout_specifier_storage_layout_output_error/output delete mode 100644 test/cmdlineTests/storage_layout_specifier_storage_layout_output_error/stdin create mode 100644 test/libsolidity/semanticTests/storageLayoutSpecifier/base_slot_max_value.sol create mode 100644 test/libsolidity/semanticTests/storageLayoutSpecifier/constructor.sol create mode 100644 test/libsolidity/semanticTests/storageLayoutSpecifier/delete.sol create mode 100644 test/libsolidity/semanticTests/storageLayoutSpecifier/delete_transient_storage.sol create mode 100644 test/libsolidity/semanticTests/storageLayoutSpecifier/dynamic_array_storage_end.sol create mode 100644 test/libsolidity/semanticTests/storageLayoutSpecifier/function_from_base_contract.sol create mode 100644 test/libsolidity/semanticTests/storageLayoutSpecifier/getters.sol create mode 100644 test/libsolidity/semanticTests/storageLayoutSpecifier/inheritance_from_abstract_contract.sol create mode 100644 test/libsolidity/semanticTests/storageLayoutSpecifier/inheritance_from_interface.sol create mode 100644 test/libsolidity/semanticTests/storageLayoutSpecifier/inheritance_from_same_base_state_var_slots.sol create mode 100644 test/libsolidity/semanticTests/storageLayoutSpecifier/inheritance_simple.sol create mode 100644 test/libsolidity/semanticTests/storageLayoutSpecifier/inheritance_state_variable_slot_offset.sol create mode 100644 test/libsolidity/semanticTests/storageLayoutSpecifier/inline_assembly_direct_load.sol create mode 100644 test/libsolidity/semanticTests/storageLayoutSpecifier/inline_assembly_direct_store.sol create mode 100644 test/libsolidity/semanticTests/storageLayoutSpecifier/last_allowed_storage_slot.sol create mode 100644 test/libsolidity/semanticTests/storageLayoutSpecifier/mapping_storage_end.sol create mode 100644 test/libsolidity/semanticTests/storageLayoutSpecifier/multiple_inheritance.sol create mode 100644 test/libsolidity/semanticTests/storageLayoutSpecifier/multiple_inheritance_state_var_slots.sol create mode 100644 test/libsolidity/semanticTests/storageLayoutSpecifier/state_variable_arithmetic_expression.sol create mode 100644 test/libsolidity/semanticTests/storageLayoutSpecifier/state_variable_constant_and_immutable.sol create mode 100644 test/libsolidity/semanticTests/storageLayoutSpecifier/state_variable_dynamic_array.sol create mode 100644 test/libsolidity/semanticTests/storageLayoutSpecifier/state_variable_enum.sol create mode 100644 test/libsolidity/semanticTests/storageLayoutSpecifier/state_variable_mapping.sol create mode 100644 test/libsolidity/semanticTests/storageLayoutSpecifier/state_variable_reference_types_slot_offset.sol create mode 100644 test/libsolidity/semanticTests/storageLayoutSpecifier/state_variable_slot_offset.sol create mode 100644 test/libsolidity/semanticTests/storageLayoutSpecifier/state_variable_struct.sol create mode 100644 test/libsolidity/semanticTests/storageLayoutSpecifier/state_variables_transient.sol create mode 100644 test/libsolidity/semanticTests/storageLayoutSpecifier/storage_reference_array.sol create mode 100644 test/libsolidity/semanticTests/storageLayoutSpecifier/storage_reference_inheritance.sol create mode 100644 test/libsolidity/semanticTests/storageLayoutSpecifier/storage_reference_library_function.sol create mode 100644 test/libsolidity/semanticTests/storageLayoutSpecifier/transient_state_variable_slot_offset.sol create mode 100644 test/libsolidity/semanticTests/storageLayoutSpecifier/variable_cleanup.sol create mode 100644 test/libsolidity/semanticTests/storageLayoutSpecifier/variable_cleanup_sstore.sol create mode 100644 test/libsolidity/semanticTests/storageLayoutSpecifier/virtual_functions.sol create mode 100644 test/libsolidity/syntaxTests/storageLayoutSpecifier/abstract_contract_inheriting_from_non_abstract.sol diff --git a/libsolidity/interface/CompilerStack.cpp b/libsolidity/interface/CompilerStack.cpp index 9582939f5e25..60ebd7642434 100644 --- a/libsolidity/interface/CompilerStack.cpp +++ b/libsolidity/interface/CompilerStack.cpp @@ -1114,7 +1114,6 @@ Json const& CompilerStack::storageLayout(Contract const& _contract) const solAssert(m_stackState >= AnalysisSuccessful, "Analysis was not successful."); solAssert(_contract.contract); solUnimplementedAssert(!isExperimentalSolidity()); - solUnimplementedAssert(!_contract.contract->storageLayoutSpecifier(), "Storage layout not supported for contract with specified layout base."); return _contract.storageLayout.init([&]{ return StorageLayout().generate(*_contract.contract, DataLocation::Storage); }); } @@ -1539,7 +1538,6 @@ void CompilerStack::compileContract( solAssert(!m_viaIR, ""); solUnimplementedAssert(!m_eofVersion.has_value(), "Experimental EOF support is only available for via-IR compilation."); solAssert(m_stackState >= AnalysisSuccessful, ""); - solUnimplementedAssert(!_contract.storageLayoutSpecifier(), "Code generation is not supported for contracts with specified storage layout base."); if (_otherCompilers.count(&_contract)) return; @@ -1575,7 +1573,6 @@ void CompilerStack::compileContract( void CompilerStack::generateIR(ContractDefinition const& _contract, bool _unoptimizedOnly) { solAssert(m_stackState >= AnalysisSuccessful, ""); - solUnimplementedAssert(!_contract.storageLayoutSpecifier(), "Code generation is not supported for contracts with specified storage layout base."); Contract& compiledContract = m_contracts.at(_contract.fullyQualifiedName()); if (compiledContract.yulIR) { diff --git a/test/cmdlineTests/storage_layout_specifier_codegen_error/args b/test/cmdlineTests/storage_layout_specifier_codegen_error/args deleted file mode 100644 index ccc12f642d1c..000000000000 --- a/test/cmdlineTests/storage_layout_specifier_codegen_error/args +++ /dev/null @@ -1 +0,0 @@ ---asm - \ No newline at end of file diff --git a/test/cmdlineTests/storage_layout_specifier_codegen_error/err b/test/cmdlineTests/storage_layout_specifier_codegen_error/err deleted file mode 100644 index d1012053f398..000000000000 --- a/test/cmdlineTests/storage_layout_specifier_codegen_error/err +++ /dev/null @@ -1,5 +0,0 @@ -Error: Code generation is not supported for contracts with specified storage layout base. - --> :4:1: - | -4 | contract C layout at 42 {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/test/cmdlineTests/storage_layout_specifier_codegen_error/exit b/test/cmdlineTests/storage_layout_specifier_codegen_error/exit deleted file mode 100644 index d00491fd7e5b..000000000000 --- a/test/cmdlineTests/storage_layout_specifier_codegen_error/exit +++ /dev/null @@ -1 +0,0 @@ -1 diff --git a/test/cmdlineTests/storage_layout_specifier_codegen_error/stdin b/test/cmdlineTests/storage_layout_specifier_codegen_error/stdin deleted file mode 100644 index 87066c4d4050..000000000000 --- a/test/cmdlineTests/storage_layout_specifier_codegen_error/stdin +++ /dev/null @@ -1,4 +0,0 @@ -//SPDX-License-Identifier: GPL-3.0 -pragma solidity >=0.0; - -contract C layout at 42 {} \ No newline at end of file diff --git a/test/cmdlineTests/storage_layout_specifier_ir_codegen_error/args b/test/cmdlineTests/storage_layout_specifier_ir_codegen_error/args deleted file mode 100644 index a84e2a2576ff..000000000000 --- a/test/cmdlineTests/storage_layout_specifier_ir_codegen_error/args +++ /dev/null @@ -1 +0,0 @@ ---ir --asm - \ No newline at end of file diff --git a/test/cmdlineTests/storage_layout_specifier_ir_codegen_error/err b/test/cmdlineTests/storage_layout_specifier_ir_codegen_error/err deleted file mode 100644 index d1012053f398..000000000000 --- a/test/cmdlineTests/storage_layout_specifier_ir_codegen_error/err +++ /dev/null @@ -1,5 +0,0 @@ -Error: Code generation is not supported for contracts with specified storage layout base. - --> :4:1: - | -4 | contract C layout at 42 {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/test/cmdlineTests/storage_layout_specifier_ir_codegen_error/exit b/test/cmdlineTests/storage_layout_specifier_ir_codegen_error/exit deleted file mode 100644 index d00491fd7e5b..000000000000 --- a/test/cmdlineTests/storage_layout_specifier_ir_codegen_error/exit +++ /dev/null @@ -1 +0,0 @@ -1 diff --git a/test/cmdlineTests/storage_layout_specifier_smoke/args b/test/cmdlineTests/storage_layout_specifier_smoke/args new file mode 100644 index 000000000000..b207f3babd3e --- /dev/null +++ b/test/cmdlineTests/storage_layout_specifier_smoke/args @@ -0,0 +1 @@ +--no-cbor-metadata --optimize --asm --debug-info none - \ No newline at end of file diff --git a/test/cmdlineTests/storage_layout_specifier_smoke/output b/test/cmdlineTests/storage_layout_specifier_smoke/output new file mode 100644 index 000000000000..d1c54c99b7d0 --- /dev/null +++ b/test/cmdlineTests/storage_layout_specifier_smoke/output @@ -0,0 +1,85 @@ + +======= :C ======= +EVM assembly: + mstore(0x40, 0x80) + callvalue + dup1 + iszero + tag_1 + jumpi + revert(0x00, 0x00) +tag_1: + pop + dataSize(sub_0) + dup1 + dataOffset(sub_0) + 0x00 + codecopy + 0x00 + return +stop + +sub_0: assembly { + mstore(0x40, 0x80) + callvalue + dup1 + iszero + tag_1 + jumpi + revert(0x00, 0x00) + tag_1: + pop + jumpi(tag_2, lt(calldatasize, 0x04)) + shr(0xe0, calldataload(0x00)) + dup1 + 0x26121ff0 + eq + tag_3 + jumpi + tag_2: + revert(0x00, 0x00) + tag_3: + tag_4 + tag_5 + jump // in + tag_4: + stop + tag_5: + sload(0x0abc) + tag_7 + swap1 + 0x01 + tag_8 + jump // in + tag_7: + 0x0abc + sstore + jump // out + tag_8: + dup1 + dup3 + add + dup1 + dup3 + gt + iszero + tag_11 + jumpi + 0x4e487b71 + 0xe0 + shl + 0x00 + mstore + 0x11 + 0x04 + mstore + 0x24 + 0x00 + revert + tag_11: + swap3 + swap2 + pop + pop + jump // out +} diff --git a/test/cmdlineTests/storage_layout_specifier_smoke/stdin b/test/cmdlineTests/storage_layout_specifier_smoke/stdin new file mode 100644 index 000000000000..7e6575feffb2 --- /dev/null +++ b/test/cmdlineTests/storage_layout_specifier_smoke/stdin @@ -0,0 +1,9 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity >=0.0.0; + +contract C layout at 0xABC { + uint x; + function f() public { + x = x + 1; + } +} diff --git a/test/cmdlineTests/storage_layout_specifier_smoke_ir_codegen/args b/test/cmdlineTests/storage_layout_specifier_smoke_ir_codegen/args new file mode 100644 index 000000000000..9ad276caf3e4 --- /dev/null +++ b/test/cmdlineTests/storage_layout_specifier_smoke_ir_codegen/args @@ -0,0 +1 @@ +--optimize --ir-optimized --debug-info none - \ No newline at end of file diff --git a/test/cmdlineTests/storage_layout_specifier_smoke_ir_codegen/output b/test/cmdlineTests/storage_layout_specifier_smoke_ir_codegen/output new file mode 100644 index 000000000000..de5fd53748d4 --- /dev/null +++ b/test/cmdlineTests/storage_layout_specifier_smoke_ir_codegen/output @@ -0,0 +1,20 @@ +Optimized IR: +/// @use-src 0:"" +object "C_7" { + code { + { + let _1 := memoryguard(0x80) + mstore(64, _1) + if callvalue() { revert(0, 0) } + sstore(0x2a, 0x0a) + let _2 := datasize("C_7_deployed") + codecopy(_1, dataoffset("C_7_deployed"), _2) + return(_1, _2) + } + } + /// @use-src 0:"" + object "C_7_deployed" { + code { { revert(0, 0) } } + data ".metadata" hex"" + } +} diff --git a/test/cmdlineTests/storage_layout_specifier_ir_codegen_error/stdin b/test/cmdlineTests/storage_layout_specifier_smoke_ir_codegen/stdin similarity index 57% rename from test/cmdlineTests/storage_layout_specifier_ir_codegen_error/stdin rename to test/cmdlineTests/storage_layout_specifier_smoke_ir_codegen/stdin index 87066c4d4050..c3dbe062ff30 100644 --- a/test/cmdlineTests/storage_layout_specifier_ir_codegen_error/stdin +++ b/test/cmdlineTests/storage_layout_specifier_smoke_ir_codegen/stdin @@ -1,4 +1,6 @@ //SPDX-License-Identifier: GPL-3.0 pragma solidity >=0.0; -contract C layout at 42 {} \ No newline at end of file +contract C layout at 42 { + uint x = 10; +} \ No newline at end of file diff --git a/test/cmdlineTests/storage_layout_specifier_storage_layout_output/args b/test/cmdlineTests/storage_layout_specifier_storage_layout_output/args new file mode 100644 index 000000000000..b8163df7a36d --- /dev/null +++ b/test/cmdlineTests/storage_layout_specifier_storage_layout_output/args @@ -0,0 +1 @@ +--storage-layout --transient-storage-layout --pretty-json --json-indent 4 - \ No newline at end of file diff --git a/test/cmdlineTests/storage_layout_specifier_storage_layout_output/output b/test/cmdlineTests/storage_layout_specifier_storage_layout_output/output new file mode 100644 index 000000000000..7e5e61de0edb --- /dev/null +++ b/test/cmdlineTests/storage_layout_specifier_storage_layout_output/output @@ -0,0 +1,435 @@ + +======= :A ======= +Contract Storage Layout: +{ + "storage": [ + { + "astId": 3, + "contract": ":A", + "label": "x", + "offset": 0, + "slot": "0", + "type": "t_uint256" + }, + { + "astId": 7, + "contract": ":A", + "label": "y", + "offset": 0, + "slot": "1", + "type": "t_uint256" + } + ], + "types": { + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + } + } +} +Contract Transient Storage Layout: +{ + "storage": [ + { + "astId": 5, + "contract": ":A", + "label": "t1", + "offset": 0, + "slot": "0", + "type": "t_uint256" + } + ], + "types": { + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + } + } +} + +======= :B ======= +Contract Storage Layout: +{ + "storage": [ + { + "astId": 12, + "contract": ":B", + "label": "w", + "offset": 0, + "slot": "0", + "type": "t_int8" + } + ], + "types": { + "t_int8": { + "encoding": "inplace", + "label": "int8", + "numberOfBytes": "1" + } + } +} +Contract Transient Storage Layout: +{ + "storage": [ + { + "astId": 10, + "contract": ":B", + "label": "t2", + "offset": 0, + "slot": "0", + "type": "t_uint256" + }, + { + "astId": 14, + "contract": ":B", + "label": "t3", + "offset": 0, + "slot": "1", + "type": "t_int8" + } + ], + "types": { + "t_int8": { + "encoding": "inplace", + "label": "int8", + "numberOfBytes": "1" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + } + } +} + +======= :C ======= +Contract Storage Layout: +{ + "storage": [ + { + "astId": 12, + "contract": ":C", + "label": "w", + "offset": 0, + "slot": "0", + "type": "t_int8" + }, + { + "astId": 19, + "contract": ":C", + "label": "z", + "offset": 1, + "slot": "0", + "type": "t_uint128" + }, + { + "astId": 21, + "contract": ":C", + "label": "b", + "offset": 17, + "slot": "0", + "type": "t_bool" + } + ], + "types": { + "t_bool": { + "encoding": "inplace", + "label": "bool", + "numberOfBytes": "1" + }, + "t_int8": { + "encoding": "inplace", + "label": "int8", + "numberOfBytes": "1" + }, + "t_uint128": { + "encoding": "inplace", + "label": "uint128", + "numberOfBytes": "16" + } + } +} +Contract Transient Storage Layout: +{ + "storage": [ + { + "astId": 10, + "contract": ":C", + "label": "t2", + "offset": 0, + "slot": "0", + "type": "t_uint256" + }, + { + "astId": 14, + "contract": ":C", + "label": "t3", + "offset": 0, + "slot": "1", + "type": "t_int8" + }, + { + "astId": 23, + "contract": ":C", + "label": "t4", + "offset": 1, + "slot": "1", + "type": "t_bool" + } + ], + "types": { + "t_bool": { + "encoding": "inplace", + "label": "bool", + "numberOfBytes": "1" + }, + "t_int8": { + "encoding": "inplace", + "label": "int8", + "numberOfBytes": "1" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + } + } +} + +======= :D ======= +Contract Storage Layout: +{ + "storage": [ + { + "astId": 3, + "contract": ":D", + "label": "x", + "offset": 0, + "slot": "100", + "type": "t_uint256" + }, + { + "astId": 7, + "contract": ":D", + "label": "y", + "offset": 0, + "slot": "101", + "type": "t_uint256" + }, + { + "astId": 12, + "contract": ":D", + "label": "w", + "offset": 0, + "slot": "102", + "type": "t_int8" + }, + { + "astId": 19, + "contract": ":D", + "label": "z", + "offset": 1, + "slot": "102", + "type": "t_uint128" + }, + { + "astId": 21, + "contract": ":D", + "label": "b", + "offset": 17, + "slot": "102", + "type": "t_bool" + }, + { + "astId": 32, + "contract": ":D", + "label": "addr", + "offset": 0, + "slot": "103", + "type": "t_address" + }, + { + "astId": 38, + "contract": ":D", + "label": "array", + "offset": 0, + "slot": "104", + "type": "t_array(t_uint256)2_storage" + }, + { + "astId": 42, + "contract": ":D", + "label": "m", + "offset": 0, + "slot": "106", + "type": "t_mapping(t_uint256,t_address)" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + }, + "t_array(t_uint256)2_storage": { + "base": "t_uint256", + "encoding": "inplace", + "label": "uint256[2]", + "numberOfBytes": "64" + }, + "t_bool": { + "encoding": "inplace", + "label": "bool", + "numberOfBytes": "1" + }, + "t_int8": { + "encoding": "inplace", + "label": "int8", + "numberOfBytes": "1" + }, + "t_mapping(t_uint256,t_address)": { + "encoding": "mapping", + "key": "t_uint256", + "label": "mapping(uint256 => address)", + "numberOfBytes": "32", + "value": "t_address" + }, + "t_uint128": { + "encoding": "inplace", + "label": "uint128", + "numberOfBytes": "16" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + } + } +} +Contract Transient Storage Layout: +{ + "storage": [ + { + "astId": 5, + "contract": ":D", + "label": "t1", + "offset": 0, + "slot": "0", + "type": "t_uint256" + }, + { + "astId": 10, + "contract": ":D", + "label": "t2", + "offset": 0, + "slot": "1", + "type": "t_uint256" + }, + { + "astId": 14, + "contract": ":D", + "label": "t3", + "offset": 0, + "slot": "2", + "type": "t_int8" + }, + { + "astId": 23, + "contract": ":D", + "label": "t4", + "offset": 1, + "slot": "2", + "type": "t_bool" + }, + { + "astId": 34, + "contract": ":D", + "label": "t5", + "offset": 2, + "slot": "2", + "type": "t_address" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + }, + "t_bool": { + "encoding": "inplace", + "label": "bool", + "numberOfBytes": "1" + }, + "t_int8": { + "encoding": "inplace", + "label": "int8", + "numberOfBytes": "1" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + } + } +} + +======= :P ======= +Contract Storage Layout: +{ + "storage": [ + { + "astId": 3, + "contract": ":P", + "label": "x", + "offset": 0, + "slot": "200", + "type": "t_uint256" + }, + { + "astId": 7, + "contract": ":P", + "label": "y", + "offset": 0, + "slot": "201", + "type": "t_uint256" + }, + { + "astId": 49, + "contract": ":P", + "label": "q", + "offset": 0, + "slot": "202", + "type": "t_uint256" + } + ], + "types": { + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + } + } +} +Contract Transient Storage Layout: +{ + "storage": [ + { + "astId": 5, + "contract": ":P", + "label": "t1", + "offset": 0, + "slot": "0", + "type": "t_uint256" + } + ], + "types": { + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + } + } +} diff --git a/test/cmdlineTests/storage_layout_specifier_storage_layout_output/stdin b/test/cmdlineTests/storage_layout_specifier_storage_layout_output/stdin new file mode 100644 index 000000000000..ac391d192eb5 --- /dev/null +++ b/test/cmdlineTests/storage_layout_specifier_storage_layout_output/stdin @@ -0,0 +1,31 @@ +//SPDX-License-Identifier: GPL-3.0 +pragma solidity *; + +abstract contract A { + uint x; + uint transient t1; + uint y; +} + +contract B { + uint transient t2; + int8 w; + int8 transient t3; +} + +contract C is B { + uint128 z; + bool b; + bool transient t4; +} + +contract D is A, C layout at 100 { + address addr; + address transient t5; + uint[2] array; + mapping(uint => address) m; +} + +contract P is A layout at 200 { + uint q; +} \ No newline at end of file diff --git a/test/cmdlineTests/storage_layout_specifier_storage_layout_output_error/args b/test/cmdlineTests/storage_layout_specifier_storage_layout_output_error/args deleted file mode 100644 index 93090d6aabb9..000000000000 --- a/test/cmdlineTests/storage_layout_specifier_storage_layout_output_error/args +++ /dev/null @@ -1 +0,0 @@ ---storage-layout - \ No newline at end of file diff --git a/test/cmdlineTests/storage_layout_specifier_storage_layout_output_error/err b/test/cmdlineTests/storage_layout_specifier_storage_layout_output_error/err deleted file mode 100644 index 58e52d14aa9a..000000000000 --- a/test/cmdlineTests/storage_layout_specifier_storage_layout_output_error/err +++ /dev/null @@ -1 +0,0 @@ -Error: Storage layout not supported for contract with specified layout base. diff --git a/test/cmdlineTests/storage_layout_specifier_storage_layout_output_error/exit b/test/cmdlineTests/storage_layout_specifier_storage_layout_output_error/exit deleted file mode 100644 index d00491fd7e5b..000000000000 --- a/test/cmdlineTests/storage_layout_specifier_storage_layout_output_error/exit +++ /dev/null @@ -1 +0,0 @@ -1 diff --git a/test/cmdlineTests/storage_layout_specifier_storage_layout_output_error/output b/test/cmdlineTests/storage_layout_specifier_storage_layout_output_error/output deleted file mode 100644 index c90881588636..000000000000 --- a/test/cmdlineTests/storage_layout_specifier_storage_layout_output_error/output +++ /dev/null @@ -1,2 +0,0 @@ - -======= :C ======= diff --git a/test/cmdlineTests/storage_layout_specifier_storage_layout_output_error/stdin b/test/cmdlineTests/storage_layout_specifier_storage_layout_output_error/stdin deleted file mode 100644 index 87066c4d4050..000000000000 --- a/test/cmdlineTests/storage_layout_specifier_storage_layout_output_error/stdin +++ /dev/null @@ -1,4 +0,0 @@ -//SPDX-License-Identifier: GPL-3.0 -pragma solidity >=0.0; - -contract C layout at 42 {} \ No newline at end of file diff --git a/test/libsolidity/semanticTests/storageLayoutSpecifier/base_slot_max_value.sol b/test/libsolidity/semanticTests/storageLayoutSpecifier/base_slot_max_value.sol new file mode 100644 index 000000000000..e465437626b3 --- /dev/null +++ b/test/libsolidity/semanticTests/storageLayoutSpecifier/base_slot_max_value.sol @@ -0,0 +1,7 @@ +contract C layout at 2**256 - 1 { + function f(uint a) public pure returns (uint) { + return a * 2; + } +} +// ---- +// f(uint256): 4 -> 8 diff --git a/test/libsolidity/semanticTests/storageLayoutSpecifier/constructor.sol b/test/libsolidity/semanticTests/storageLayoutSpecifier/constructor.sol new file mode 100644 index 000000000000..c30f9dab98a7 --- /dev/null +++ b/test/libsolidity/semanticTests/storageLayoutSpecifier/constructor.sol @@ -0,0 +1,29 @@ +contract A { + uint public x; +} + +contract B is A { + int8 public y; +} + +contract C is B layout at 7 { + uint32 public z; + + constructor(uint _x, int8 _y, uint32 _z) { + x = _x + 1; + y = _y + 2; + z = _z + 3; + } + +} +// ---- +// constructor(): 1, 2, 3 +// gas irOptimized: 104178 +// gas irOptimized code: 30000 +// gas legacy: 114749 +// gas legacy code: 71400 +// gas legacyOptimized: 106296 +// gas legacyOptimized code: 31400 +// x() -> 2 +// y() -> 4 +// z() -> 6 diff --git a/test/libsolidity/semanticTests/storageLayoutSpecifier/delete.sol b/test/libsolidity/semanticTests/storageLayoutSpecifier/delete.sol new file mode 100644 index 000000000000..a6cc84cce511 --- /dev/null +++ b/test/libsolidity/semanticTests/storageLayoutSpecifier/delete.sol @@ -0,0 +1,30 @@ +contract C layout at 42 { + uint[] public array; + + function fillArray() public returns (uint) { + array.push(1); + array.push(2); + array.push(3); + return array.length; + } + function deleteLast() public { + delete array[array.length - 1]; + } + function deleteArray() public { + delete array; + } + function arrayLength() public returns (uint) { + return array.length; + } +} +// ---- +// fillArray() -> 3 +// gas irOptimized: 111121 +// gas legacy: 110730 +// gas legacyOptimized: 110307 +// arrayLength() -> 3 +// array(uint256): 2 -> 3 +// deleteLast() -> +// array(uint256): 2 -> 0 +// deleteArray() -> +// arrayLength() -> 0 diff --git a/test/libsolidity/semanticTests/storageLayoutSpecifier/delete_transient_storage.sol b/test/libsolidity/semanticTests/storageLayoutSpecifier/delete_transient_storage.sol new file mode 100644 index 000000000000..b651e0e888b9 --- /dev/null +++ b/test/libsolidity/semanticTests/storageLayoutSpecifier/delete_transient_storage.sol @@ -0,0 +1,20 @@ +contract C layout at 42 { + uint transient x; + address transient a; + + function f() public { + g(); + delete x; + delete a; + assert(x == 0); + assert(a == address(0)); + } + function g() public { + x = 99; + a = address(0x1234); + } +} +// ==== +// EVMVersion: >=cancun +// ---- +// f() -> \ No newline at end of file diff --git a/test/libsolidity/semanticTests/storageLayoutSpecifier/dynamic_array_storage_end.sol b/test/libsolidity/semanticTests/storageLayoutSpecifier/dynamic_array_storage_end.sol new file mode 100644 index 000000000000..54eabe844702 --- /dev/null +++ b/test/libsolidity/semanticTests/storageLayoutSpecifier/dynamic_array_storage_end.sol @@ -0,0 +1,29 @@ +contract C layout at 2**256 - 2 { + uint[] array; + + function init() public { + for (uint i = 0; i < 1000; ++i) + array.push(i + 1); + } + function validate() public { + for (uint i = 0; i < 1000; ++i) + require(array[i] == i + 1); + } + function clear() public { + for (uint i = 0; i < 1000; ++i) + array.pop(); + } +} +// ---- +// init() -> +// gas irOptimized: 22738151 +// gas legacy: 22699167 +// gas legacyOptimized: 22541160 +// validate() -> +// gas irOptimized: 2444232 +// gas legacy: 2560245 +// gas legacyOptimized: 2442238 +// clear() -> +// gas irOptimized: 4449608 +// gas legacy: 4300019 +// gas legacyOptimized: 4302413 diff --git a/test/libsolidity/semanticTests/storageLayoutSpecifier/function_from_base_contract.sol b/test/libsolidity/semanticTests/storageLayoutSpecifier/function_from_base_contract.sol new file mode 100644 index 000000000000..004997c221bc --- /dev/null +++ b/test/libsolidity/semanticTests/storageLayoutSpecifier/function_from_base_contract.sol @@ -0,0 +1,30 @@ +contract A { + uint public x; + function f() public returns (uint) { + x = x + 1; + return x; + } +} + +contract B is A { + uint public y; + function g() public virtual returns (uint) { + y = y + 2; + return y; + } +} + +contract C is B layout at 42 { + uint public z; + function test() public returns (uint){ + z = super.g() + A.f(); + return z; + } +} +// ---- +// f() -> 1 +// g() -> 2 +// test() -> 6 +// x() -> 2 +// y() -> 4 +// z() -> 6 diff --git a/test/libsolidity/semanticTests/storageLayoutSpecifier/getters.sol b/test/libsolidity/semanticTests/storageLayoutSpecifier/getters.sol new file mode 100644 index 000000000000..62a75e7d5342 --- /dev/null +++ b/test/libsolidity/semanticTests/storageLayoutSpecifier/getters.sol @@ -0,0 +1,9 @@ +contract C layout at 7 { + uint public x = 1; + int8 public y = 2; + uint32 public z = 3; +} +// ---- +// x() -> 1 +// y() -> 2 +// z() -> 3 diff --git a/test/libsolidity/semanticTests/storageLayoutSpecifier/inheritance_from_abstract_contract.sol b/test/libsolidity/semanticTests/storageLayoutSpecifier/inheritance_from_abstract_contract.sol new file mode 100644 index 000000000000..fdf68994be7e --- /dev/null +++ b/test/libsolidity/semanticTests/storageLayoutSpecifier/inheritance_from_abstract_contract.sol @@ -0,0 +1,17 @@ +abstract contract A { + uint public x; +} + +contract C is A layout at 42 { + uint public y; + function f() public returns (uint) { + x = 12; + x = x - 4; + y = x + 2; + return y; + } +} +// ---- +// f() -> 10 +// x() -> 8 +// y() -> 10 diff --git a/test/libsolidity/semanticTests/storageLayoutSpecifier/inheritance_from_interface.sol b/test/libsolidity/semanticTests/storageLayoutSpecifier/inheritance_from_interface.sol new file mode 100644 index 000000000000..8874f28f2fd4 --- /dev/null +++ b/test/libsolidity/semanticTests/storageLayoutSpecifier/inheritance_from_interface.sol @@ -0,0 +1,15 @@ +interface I { + function f(uint x) external returns (uint); +} + +contract C is I layout at 42 { + uint public y; + function f(uint x) public returns (uint) { + x = x - 4; + y = x + 2; + return y; + } +} +// ---- +// f(uint256): 8 -> 6 +// y() -> 6 diff --git a/test/libsolidity/semanticTests/storageLayoutSpecifier/inheritance_from_same_base_state_var_slots.sol b/test/libsolidity/semanticTests/storageLayoutSpecifier/inheritance_from_same_base_state_var_slots.sol new file mode 100644 index 000000000000..554c3fcd7e2b --- /dev/null +++ b/test/libsolidity/semanticTests/storageLayoutSpecifier/inheritance_from_same_base_state_var_slots.sol @@ -0,0 +1,47 @@ +contract A { + uint public x; + function xSlot() public view returns (uint xs) { + assembly { + xs := x.slot + } + } +} + +contract B is A layout at 5 { + uint public y; + function xAndYSlots() public view returns (uint xs, uint ys) { + assembly { + xs := x.slot + ys := y.slot + } + } +} + +contract C is A layout at 9 { + uint public z; + function xAndZSlots() public view returns (uint xs, uint zs) { + assembly { + xs := x.slot + zs := z.slot + } + } +} + +contract Test { + A a = new A(); + B b = new B(); + C c = new C(); + function contractASlots() public view returns (uint) { + return a.xSlot(); + } + function contractBSlots() public view returns (uint, uint) { + return b.xAndYSlots(); + } + function contractCSlots() public view returns (uint, uint) { + return c.xAndZSlots(); + } +} +// ---- +// contractASlots() -> 0 +// contractBSlots() -> 5, 6 +// contractCSlots() -> 9, 10 diff --git a/test/libsolidity/semanticTests/storageLayoutSpecifier/inheritance_simple.sol b/test/libsolidity/semanticTests/storageLayoutSpecifier/inheritance_simple.sol new file mode 100644 index 000000000000..a4eeee5f28db --- /dev/null +++ b/test/libsolidity/semanticTests/storageLayoutSpecifier/inheritance_simple.sol @@ -0,0 +1,16 @@ +contract A { + uint public x = 10; +} + +contract C is A layout at 42 { + uint public y; + function f() public returns (uint) { + x = x - 4; + y = x + 2; + return y; + } +} +// ---- +// f() -> 8 +// x() -> 6 +// y() -> 8 diff --git a/test/libsolidity/semanticTests/storageLayoutSpecifier/inheritance_state_variable_slot_offset.sol b/test/libsolidity/semanticTests/storageLayoutSpecifier/inheritance_state_variable_slot_offset.sol new file mode 100644 index 000000000000..73304d622965 --- /dev/null +++ b/test/libsolidity/semanticTests/storageLayoutSpecifier/inheritance_state_variable_slot_offset.sol @@ -0,0 +1,19 @@ +contract A { + uint x; + uint128 y; +} + +contract C is A layout at 7 { + uint32 w; + uint z; + + function xSlotOffset() public returns(uint s, uint o) { assembly { s := x.slot o := x.offset } } + function ySlotOffset() public returns(uint s, uint o) { assembly { s := y.slot o := y.offset } } + function wSlotOffset() public returns(uint s, uint o) { assembly { s := w.slot o := w.offset } } + function zSlotOffset() public returns(uint s, uint o) { assembly { s := z.slot o := z.offset } } +} +// ---- +// xSlotOffset() -> 7, 0 +// ySlotOffset() -> 8, 0 +// wSlotOffset() -> 8, 16 +// zSlotOffset() -> 9, 0 diff --git a/test/libsolidity/semanticTests/storageLayoutSpecifier/inline_assembly_direct_load.sol b/test/libsolidity/semanticTests/storageLayoutSpecifier/inline_assembly_direct_load.sol new file mode 100644 index 000000000000..9f5a5491d202 --- /dev/null +++ b/test/libsolidity/semanticTests/storageLayoutSpecifier/inline_assembly_direct_load.sol @@ -0,0 +1,12 @@ +contract C layout at 42 { + uint public x; + function f() public returns (uint r) { + x = 16; + assembly { + r := sload(42) + } + } +} +// ---- +// f() -> 16 +// x() -> 16 diff --git a/test/libsolidity/semanticTests/storageLayoutSpecifier/inline_assembly_direct_store.sol b/test/libsolidity/semanticTests/storageLayoutSpecifier/inline_assembly_direct_store.sol new file mode 100644 index 000000000000..6ea695e6625d --- /dev/null +++ b/test/libsolidity/semanticTests/storageLayoutSpecifier/inline_assembly_direct_store.sol @@ -0,0 +1,12 @@ +contract C layout at 42 { + uint public x; + function f() public returns (uint) { + assembly { + sstore(42, 16) + } + return x; + } +} +// ---- +// f() -> 16 +// x() -> 16 diff --git a/test/libsolidity/semanticTests/storageLayoutSpecifier/last_allowed_storage_slot.sol b/test/libsolidity/semanticTests/storageLayoutSpecifier/last_allowed_storage_slot.sol new file mode 100644 index 000000000000..89900c0f6d0b --- /dev/null +++ b/test/libsolidity/semanticTests/storageLayoutSpecifier/last_allowed_storage_slot.sol @@ -0,0 +1,10 @@ +contract C layout at 2**256 - 2 { + uint public x; + function f(uint a) public returns (uint) { + x = a * 2; + return x; + } +} +// ---- +// f(uint256): 4 -> 8 +// x() -> 8 diff --git a/test/libsolidity/semanticTests/storageLayoutSpecifier/mapping_storage_end.sol b/test/libsolidity/semanticTests/storageLayoutSpecifier/mapping_storage_end.sol new file mode 100644 index 000000000000..9745850c0091 --- /dev/null +++ b/test/libsolidity/semanticTests/storageLayoutSpecifier/mapping_storage_end.sol @@ -0,0 +1,22 @@ +contract C layout at 2**256 - 2 { + mapping(uint => uint) m; + + function init() public { + for (uint i = 0; i < 1000; ++i) + m[i] = i + 1; + } + + function validate() public { + for (uint i = 0; i < 1000; ++i) + require(m[i] == i + 1); + } +} +// ---- +// init() -> +// gas irOptimized: 22266229 +// gas legacy: 22447245 +// gas legacyOptimized: 22310238 +// validate() -> +// gas irOptimized: 2279210 +// gas legacy: 2456223 +// gas legacyOptimized: 2327216 diff --git a/test/libsolidity/semanticTests/storageLayoutSpecifier/multiple_inheritance.sol b/test/libsolidity/semanticTests/storageLayoutSpecifier/multiple_inheritance.sol new file mode 100644 index 000000000000..1b24b4961dbf --- /dev/null +++ b/test/libsolidity/semanticTests/storageLayoutSpecifier/multiple_inheritance.sol @@ -0,0 +1,40 @@ +contract A { + uint public x; + function f(uint a) public { + x = a; + } +} + +contract B is A { + uint public y; + function g(uint a) public { + f(x + a); + y = x + 1; + } +} + +contract C is B { + uint public w; + function h(uint a) public { + g(a); + w = x + y; + } +} + +contract D is A, B, C layout at 42 { + uint public z; + function test() public returns (uint, uint, uint, uint) { + h(1); + z = w + 2; + return (x, y, w, z); + } +} +// ---- +// test() -> 1, 2, 3, 5 +// gas irOptimized: 110112 +// gas legacy: 111881 +// gas legacyOptimized: 110945 +// x() -> 1 +// y() -> 2 +// w() -> 3 +// z() -> 5 diff --git a/test/libsolidity/semanticTests/storageLayoutSpecifier/multiple_inheritance_state_var_slots.sol b/test/libsolidity/semanticTests/storageLayoutSpecifier/multiple_inheritance_state_var_slots.sol new file mode 100644 index 000000000000..dd75b1d25648 --- /dev/null +++ b/test/libsolidity/semanticTests/storageLayoutSpecifier/multiple_inheritance_state_var_slots.sol @@ -0,0 +1,24 @@ +contract A { + uint x; +} + +contract B is A { + uint32 y; +} + +contract C is B { + uint160 w; +} + +contract D is A, B, C layout at 2 { + uint z; + function xSlotOffset() public view returns (uint s, uint o) { assembly { s := x.slot o := x.offset } } + function ySlotOffset() public view returns (uint s, uint o) { assembly { s := y.slot o := y.offset } } + function wSlotOffset() public view returns (uint s, uint o) { assembly { s := w.slot o := w.offset } } + function zSlotOffset() public view returns (uint s, uint o) { assembly { s := z.slot o := z.offset } } +} +// ---- +// xSlotOffset() -> 2, 0 +// ySlotOffset() -> 3, 0 +// wSlotOffset() -> 3, 4 +// zSlotOffset() -> 4, 0 diff --git a/test/libsolidity/semanticTests/storageLayoutSpecifier/state_variable_arithmetic_expression.sol b/test/libsolidity/semanticTests/storageLayoutSpecifier/state_variable_arithmetic_expression.sol new file mode 100644 index 000000000000..5dacc81ba6e1 --- /dev/null +++ b/test/libsolidity/semanticTests/storageLayoutSpecifier/state_variable_arithmetic_expression.sol @@ -0,0 +1,20 @@ +contract C layout at 7 { + uint public x; + uint public y; + uint public z; + + function f(uint a) public returns (uint) { + x = x + a; + y = y + x; + z = y - 2; + + return z; + } +} +// ---- +// f(uint256): 2 -> 0 +// f(uint256): 3 -> 5 +// f(uint256): 5 -> 15 +// x() -> 10 +// y() -> 17 +// z() -> 15 diff --git a/test/libsolidity/semanticTests/storageLayoutSpecifier/state_variable_constant_and_immutable.sol b/test/libsolidity/semanticTests/storageLayoutSpecifier/state_variable_constant_and_immutable.sol new file mode 100644 index 000000000000..6489b1e6b2fb --- /dev/null +++ b/test/libsolidity/semanticTests/storageLayoutSpecifier/state_variable_constant_and_immutable.sol @@ -0,0 +1,16 @@ +contract C layout at 42 { + uint constant x = 10; + uint immutable y = 100; + + function f() public view returns (uint) { + require(x > 9); + return x + 1; + } + function g() public view returns (uint) { + require(y > 99); + return y * 2; + } +} +// ---- +// f() -> 11 +// g() -> 200 diff --git a/test/libsolidity/semanticTests/storageLayoutSpecifier/state_variable_dynamic_array.sol b/test/libsolidity/semanticTests/storageLayoutSpecifier/state_variable_dynamic_array.sol new file mode 100644 index 000000000000..1737c35bb87c --- /dev/null +++ b/test/libsolidity/semanticTests/storageLayoutSpecifier/state_variable_dynamic_array.sol @@ -0,0 +1,50 @@ +contract A { + uint[] public arrayA; +} + +contract C is A layout at 42 { + uint[] public arrayC; + + function initA() public returns (uint, uint, uint) { + arrayA.push(1); + arrayA.push(2); + arrayA.push(3); + + return (arrayA[0], arrayA[1], arrayA[2]); + } + function initCFromAInReverse() public returns (uint, uint, uint) { + arrayC = new uint[](3); + arrayC[0] = arrayA[2]; + arrayC[1] = arrayA[1]; + arrayC[2] = arrayA[0]; + + return (arrayC[0], arrayC[1], arrayC[2]); + } + function clearA () public { + arrayA.pop(); + arrayA.pop(); + arrayA.pop(); + } + function arrayALength() public returns (uint) { + return arrayA.length; + } + function arrayCLength() public returns (uint) { + return arrayC.length; + } +} +// ---- +// initA() -> 1, 2, 3 +// gas irOptimized: 111986 +// gas legacy: 111679 +// gas legacyOptimized: 111150 +// arrayA(uint256): 0 -> 1 +// arrayALength() -> 3 +// arrayCLength() -> 0 +// initCFromAInReverse() -> 3, 2, 1 +// gas irOptimized: 121276 +// gas legacy: 121213 +// gas legacyOptimized: 120843 +// clearA() -> +// arrayC(uint256): 0 -> 3 +// arrayALength() -> 0 +// arrayCLength() -> 3 diff --git a/test/libsolidity/semanticTests/storageLayoutSpecifier/state_variable_enum.sol b/test/libsolidity/semanticTests/storageLayoutSpecifier/state_variable_enum.sol new file mode 100644 index 000000000000..66328261617d --- /dev/null +++ b/test/libsolidity/semanticTests/storageLayoutSpecifier/state_variable_enum.sol @@ -0,0 +1,18 @@ +enum Color {Red, Blue, Green } +contract C layout at 42 { + Color c; + function cSlotOffset() public returns(uint s, uint o) { + assembly { s := c.slot o := c.offset } + } + function setBlue() public { + c = Color.Blue; + } + function checkBlue() public view returns (bool) { + return c == Color.Blue; + } +} +// ---- +// cSlotOffset() -> 42, 0 +// checkBlue() -> false +// setBlue() -> +// checkBlue() -> true diff --git a/test/libsolidity/semanticTests/storageLayoutSpecifier/state_variable_mapping.sol b/test/libsolidity/semanticTests/storageLayoutSpecifier/state_variable_mapping.sol new file mode 100644 index 000000000000..e33df29ea604 --- /dev/null +++ b/test/libsolidity/semanticTests/storageLayoutSpecifier/state_variable_mapping.sol @@ -0,0 +1,33 @@ +contract A { + mapping(uint => bool) locked; +} +contract C layout at 42 is A { + mapping(uint => string) rooms; + + function setup() public { + locked[0] = true; + locked[1] = false; + locked[2] = true; + locked[3] = false; + + rooms[0] = "Empty"; + rooms[1] = "Monster"; + rooms[2] = "Treasure"; + rooms[3] = "Empty"; + } + function open(uint x) public view returns (string memory) { + if (locked[x]) + return "Locked"; + + require(!locked[x]); + return rooms[x]; + } +} +// ---- +// setup() -> +// gas irOptimized: 159082 +// gas legacy: 161738 +// gas legacyOptimized: 160222 +// open(uint256): 3 -> 0x20, 5, "Empty" +// open(uint256): 2 -> 0x20, 6, "Locked" +// open(uint256): 1 -> 0x20, 7, "Monster" diff --git a/test/libsolidity/semanticTests/storageLayoutSpecifier/state_variable_reference_types_slot_offset.sol b/test/libsolidity/semanticTests/storageLayoutSpecifier/state_variable_reference_types_slot_offset.sol new file mode 100644 index 000000000000..30cbed7f3ca2 --- /dev/null +++ b/test/libsolidity/semanticTests/storageLayoutSpecifier/state_variable_reference_types_slot_offset.sol @@ -0,0 +1,33 @@ +struct S { + uint x; + address a; + bool b; +} + +contract A { + S public s1; + uint transient t1; +} + +contract C is A layout at 42 { + uint transient t2; + S[][5] dArray; + uint[10][2] sArray; + bytes bArray; + string str; + + + function s1SlotOffset() public returns (uint s, uint o) { assembly { s:= s1.slot o:= s1.offset } } + function dArraySlotOffset() public returns (uint s, uint o) { assembly { s:= dArray.slot o:= dArray.offset } } + function sArraySlotOffset() public returns (uint s, uint o) { assembly { s:= sArray.slot o:= sArray.offset } } + function bArraySlotOffset() public returns (uint s, uint o) { assembly { s:= bArray.slot o:= bArray.offset } } + function strSlotOffset() public returns (uint s, uint o) { assembly { s:= str.slot o:= str.offset } } +} +// ==== +// EVMVersion: >=cancun +// ---- +// s1SlotOffset() -> 42, 0 +// dArraySlotOffset() -> 44, 0 +// sArraySlotOffset() -> 49, 0 +// bArraySlotOffset() -> 69, 0 +// strSlotOffset() -> 70, 0 diff --git a/test/libsolidity/semanticTests/storageLayoutSpecifier/state_variable_slot_offset.sol b/test/libsolidity/semanticTests/storageLayoutSpecifier/state_variable_slot_offset.sol new file mode 100644 index 000000000000..1ce5207eb181 --- /dev/null +++ b/test/libsolidity/semanticTests/storageLayoutSpecifier/state_variable_slot_offset.sol @@ -0,0 +1,13 @@ +contract C layout at 7 { + int8 public x; + int32 public y; + uint256 public z; + + function xSlotOffset() public returns(uint s, uint o) { assembly { s := x.slot o := x.offset } } + function ySlotOffset() public returns(uint s, uint o) { assembly { s := y.slot o := y.offset } } + function zSlotOffset() public returns(uint s, uint o) { assembly { s := z.slot o := z.offset } } +} +// ---- +// xSlotOffset() -> 7, 0 +// ySlotOffset() -> 7, 1 +// zSlotOffset() -> 8, 0 diff --git a/test/libsolidity/semanticTests/storageLayoutSpecifier/state_variable_struct.sol b/test/libsolidity/semanticTests/storageLayoutSpecifier/state_variable_struct.sol new file mode 100644 index 000000000000..5b2b6d5582df --- /dev/null +++ b/test/libsolidity/semanticTests/storageLayoutSpecifier/state_variable_struct.sol @@ -0,0 +1,39 @@ +struct S { + uint x; + address a; + bool b; +} + +contract A { + S public s1; + uint transient t1; +} + +contract C is A layout at 42 { + uint y; + uint8 z; + uint transient t2; + S public s2; + + function initS1() public returns (uint, address, bool) { + s1.x = 7; + s1.a = address(0xABC); + s1.b = true; + + return (s1.x, s1.a, s1.b); + } + function initS2() public returns (uint, address, bool) { + s2.x = 8; + s2.a = address(0xDEF); + s2.b = false; + + return (s2.x, s2.a, s2.b); + } +} +// ==== +// EVMVersion: >=cancun +// ---- +// initS1() -> 7, 0x0abc, 1 +// initS2() -> 8, 0x0def, 0 +// s1() -> 7, 0x0abc, 1 +// s2() -> 8, 0x0def, 0 diff --git a/test/libsolidity/semanticTests/storageLayoutSpecifier/state_variables_transient.sol b/test/libsolidity/semanticTests/storageLayoutSpecifier/state_variables_transient.sol new file mode 100644 index 000000000000..0c1e0a78a554 --- /dev/null +++ b/test/libsolidity/semanticTests/storageLayoutSpecifier/state_variables_transient.sol @@ -0,0 +1,23 @@ +contract C layout at 42 { + int x; + bool transient lock; + + function test() public returns(int) { + x = -1; + lock = true; + f(); + return x; + } + function f() private { + lock = false; + setX(); + } + function setX() private { + require(!lock); + x = 2; + } +} +// ==== +// EVMVersion: >=cancun +// ---- +// test() -> 2 \ No newline at end of file diff --git a/test/libsolidity/semanticTests/storageLayoutSpecifier/storage_reference_array.sol b/test/libsolidity/semanticTests/storageLayoutSpecifier/storage_reference_array.sol new file mode 100644 index 000000000000..db14ef55874c --- /dev/null +++ b/test/libsolidity/semanticTests/storageLayoutSpecifier/storage_reference_array.sol @@ -0,0 +1,21 @@ +contract C layout at 42 { + uint[] public array; + function initUsingReference() public { + uint[] storage ptr = array; + for(uint i = 0; i < 10; ++i) + ptr.push(i + 1); + + validate(array); + } + function validate(uint[] memory ptr) public pure { + for(uint i = 0; i < 10; ++i) + require(ptr[i] == i + 1); + } +} +// ---- +// initUsingReference() -> +// gas irOptimized: 273556 +// gas legacy: 274795 +// gas legacyOptimized: 271954 +// array(uint256): 0 -> 1 +// array(uint256): 9 -> 10 diff --git a/test/libsolidity/semanticTests/storageLayoutSpecifier/storage_reference_inheritance.sol b/test/libsolidity/semanticTests/storageLayoutSpecifier/storage_reference_inheritance.sol new file mode 100644 index 000000000000..1a4ee2e6f9d7 --- /dev/null +++ b/test/libsolidity/semanticTests/storageLayoutSpecifier/storage_reference_inheritance.sol @@ -0,0 +1,25 @@ +pragma abicoder v2; +contract A { + struct S { + uint x; + bool b; + } + S public s; +} + +contract C is A layout at 42 { + function InitUsingReference() public { + S storage ptr = s; + ptr.x = 2; + ptr.b = true; + + validate(s); + } + function validate(S memory ptr) public pure { + require(ptr.x == 2); + require(ptr.b); + } +} +// ---- +// InitUsingReference() -> +// s() -> 2, true diff --git a/test/libsolidity/semanticTests/storageLayoutSpecifier/storage_reference_library_function.sol b/test/libsolidity/semanticTests/storageLayoutSpecifier/storage_reference_library_function.sol new file mode 100644 index 000000000000..2d17de248c34 --- /dev/null +++ b/test/libsolidity/semanticTests/storageLayoutSpecifier/storage_reference_library_function.sol @@ -0,0 +1,31 @@ +pragma abicoder v2; + +struct S { + uint x; + bool b; +} + +library L { + function validate(S memory ptr) public { + require(ptr.x == 2); + require(ptr.b); + } +} + +contract A { + S public s; +} + +contract C is A layout at 42 { + function initUsingReference() public { + S storage ptr = s; + ptr.x = 2; + ptr.b = true; + + L.validate(s); + } +} +// ---- +// library: L +// initUsingReference() -> +// s() -> 2, true diff --git a/test/libsolidity/semanticTests/storageLayoutSpecifier/transient_state_variable_slot_offset.sol b/test/libsolidity/semanticTests/storageLayoutSpecifier/transient_state_variable_slot_offset.sol new file mode 100644 index 000000000000..c1d8f911d7c3 --- /dev/null +++ b/test/libsolidity/semanticTests/storageLayoutSpecifier/transient_state_variable_slot_offset.sol @@ -0,0 +1,18 @@ +contract C layout at 7 { + int transient x; + int y; + uint transient w; + uint256 z; + + function xSlotOffset() public returns(uint s, uint o) { assembly { s := x.slot o := x.offset } } + function ySlotOffset() public returns(uint s, uint o) { assembly { s := y.slot o := y.offset } } + function wSlotOffset() public returns(uint s, uint o) { assembly { s := w.slot o := w.offset } } + function zSlotOffset() public returns(uint s, uint o) { assembly { s := z.slot o := z.offset } } +} +// ==== +// EVMVersion: >=cancun +// ---- +// xSlotOffset() -> 0, 0 +// ySlotOffset() -> 7, 0 +// wSlotOffset() -> 1, 0 +// zSlotOffset() -> 8, 0 diff --git a/test/libsolidity/semanticTests/storageLayoutSpecifier/variable_cleanup.sol b/test/libsolidity/semanticTests/storageLayoutSpecifier/variable_cleanup.sol new file mode 100644 index 000000000000..33ffc59939e9 --- /dev/null +++ b/test/libsolidity/semanticTests/storageLayoutSpecifier/variable_cleanup.sol @@ -0,0 +1,15 @@ +contract C layout at 42 { + uint8 x; + int8 y; + bytes2 b; + // Note the return types are larger than the state variable ones + function f(uint _x, int _y, bytes3 _b) public returns (uint16, int32, bytes32) { + x = uint8(_x); + y = int8(_y); + b = bytes2(_b); + require(b == "ab"); + return (x, y, b); + } +} +// ---- +// f(uint256,int256,bytes3): 0x0100, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f, "abc" -> 0x00, 0x7f, "ab" diff --git a/test/libsolidity/semanticTests/storageLayoutSpecifier/variable_cleanup_sstore.sol b/test/libsolidity/semanticTests/storageLayoutSpecifier/variable_cleanup_sstore.sol new file mode 100644 index 000000000000..bda660d056a4 --- /dev/null +++ b/test/libsolidity/semanticTests/storageLayoutSpecifier/variable_cleanup_sstore.sol @@ -0,0 +1,20 @@ +contract C layout at 42 { + uint8 x; + int8 y; + bytes2 b; + // Note the return types are larger than the state variable ones + function f() public returns (uint16, int32, bytes16) { + uint32 z = 0; + z = z | 0x10; + z = z | 0x7f00; + z = z | 0x61620000; + + assembly { + sstore(x.slot, z) + } + require(b == "ab"); + return (x, y, b); + } +} +// ---- +// f() -> 0x10, 127, "ab" diff --git a/test/libsolidity/semanticTests/storageLayoutSpecifier/virtual_functions.sol b/test/libsolidity/semanticTests/storageLayoutSpecifier/virtual_functions.sol new file mode 100644 index 000000000000..42c917d18279 --- /dev/null +++ b/test/libsolidity/semanticTests/storageLayoutSpecifier/virtual_functions.sol @@ -0,0 +1,34 @@ +abstract contract A { + uint public x; + function f() public virtual returns (uint); +} + +contract B is A { + uint public y; + function f() public override returns (uint) { + x = 1; + return x; + } + function g() public virtual returns (uint) { + return y; + } +} + +contract C is B layout at 42 { + uint public z; + function g() public override returns (uint) { + y = x + 2; + return y; + } + function h() public returns (uint) { + z = g() + 3; + return z; + } +} +// ---- +// f() -> 1 +// g() -> 3 +// h() -> 6 +// x() -> 1 +// y() -> 3 +// z() -> 6 diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/abstract_contract_inheriting_from_non_abstract.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/abstract_contract_inheriting_from_non_abstract.sol new file mode 100644 index 000000000000..73dfa42f3a1b --- /dev/null +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/abstract_contract_inheriting_from_non_abstract.sol @@ -0,0 +1,4 @@ +contract A layout at 0x1234 {} +abstract contract C is A { } +// ---- +// TypeError 8894: (54-55): Cannot inherit from a contract with a custom storage layout. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/contract_named_at.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/contract_named_at.sol index bbb928cb3715..c5127249ab68 100644 --- a/test/libsolidity/syntaxTests/storageLayoutSpecifier/contract_named_at.sol +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/contract_named_at.sol @@ -1,3 +1,2 @@ contract at layout at 0x1234ABC { } // ---- -// UnimplementedFeatureError 1834: (0-35): Code generation is not supported for contracts with specified storage layout base. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/contract_named_layout.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/contract_named_layout.sol index 5c755d610ccf..111a4fc365f8 100644 --- a/test/libsolidity/syntaxTests/storageLayoutSpecifier/contract_named_layout.sol +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/contract_named_layout.sol @@ -1,3 +1,2 @@ contract layout layout at 0x1234ABC { } // ---- -// UnimplementedFeatureError 1834: (0-39): Code generation is not supported for contracts with specified storage layout base. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/contract_with_members_named_layout_and_at.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/contract_with_members_named_layout_and_at.sol index 9e15ef564985..7e448bba7fd5 100644 --- a/test/libsolidity/syntaxTests/storageLayoutSpecifier/contract_with_members_named_layout_and_at.sol +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/contract_with_members_named_layout_and_at.sol @@ -3,4 +3,3 @@ contract C layout at 0x1234 { function at() public pure { } } // ---- -// UnimplementedFeatureError 1834: (0-82): Code generation is not supported for contracts with specified storage layout base. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/inheriting_from_abstract_contract.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/inheriting_from_abstract_contract.sol index 850798c937ed..32d6839abd06 100644 --- a/test/libsolidity/syntaxTests/storageLayoutSpecifier/inheriting_from_abstract_contract.sol +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/inheriting_from_abstract_contract.sol @@ -2,4 +2,3 @@ abstract contract A { } contract C layout at 42 is A { } // ---- -// UnimplementedFeatureError 1834: (25-57): Code generation is not supported for contracts with specified storage layout base. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/inheriting_from_interface.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/inheriting_from_interface.sol index 541dea056c2a..c0ac98f57a89 100644 --- a/test/libsolidity/syntaxTests/storageLayoutSpecifier/inheriting_from_interface.sol +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/inheriting_from_interface.sol @@ -2,4 +2,3 @@ interface I { } contract C layout at 42 is I { } // ---- -// UnimplementedFeatureError 1834: (17-49): Code generation is not supported for contracts with specified storage layout base. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/intermediate_operation_out_of_range.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/intermediate_operation_out_of_range.sol index b7bae489fb5f..f74c45ed76f1 100644 --- a/test/libsolidity/syntaxTests/storageLayoutSpecifier/intermediate_operation_out_of_range.sol +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/intermediate_operation_out_of_range.sol @@ -1,4 +1,3 @@ contract A layout at (2**256 + 1) * 2 - 2**256 - 3 {} contract B layout at (2**2 - 2**3) * (2**5 - 2**8) {} // ---- -// UnimplementedFeatureError 1834: (0-54): Code generation is not supported for contracts with specified storage layout base. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specification_binary_expression.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specification_binary_expression.sol index 609178fd0e02..fffea1458e87 100644 --- a/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specification_binary_expression.sol +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specification_binary_expression.sol @@ -1,3 +1,2 @@ contract C layout at 0xffff * (0x123 + 0xABC) { } // ---- -// UnimplementedFeatureError 1834: (0-49): Code generation is not supported for contracts with specified storage layout base. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specification_max_value.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specification_max_value.sol index 67954bdce1d8..793b5b2689cf 100644 --- a/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specification_max_value.sol +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specification_max_value.sol @@ -1,3 +1,2 @@ contract C layout at 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF {} // ---- -// UnimplementedFeatureError 1834: (0-90): Code generation is not supported for contracts with specified storage layout base. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_with_inheritance.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_with_inheritance.sol index 7c8d483e272b..13e094631c23 100644 --- a/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_with_inheritance.sol +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_with_inheritance.sol @@ -3,4 +3,3 @@ contract B { } contract C is A, B layout at 0x1234 { } contract D layout at 0xABCD is A, B { } // ---- -// UnimplementedFeatureError 1834: (30-69): Code generation is not supported for contracts with specified storage layout base. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/literal_with_underscore.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/literal_with_underscore.sol index 1c3c715f9da9..a5876ab6e632 100644 --- a/test/libsolidity/syntaxTests/storageLayoutSpecifier/literal_with_underscore.sol +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/literal_with_underscore.sol @@ -2,4 +2,3 @@ contract A layout at 42_0e10 {} contract B layout at 0x1234_ABCD {} contract C layout at 1234_000 {} // ---- -// UnimplementedFeatureError 1834: (0-31): Code generation is not supported for contracts with specified storage layout base. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/multi_token_expression.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/multi_token_expression.sol index 8e048b29e992..a9b5abef18b3 100644 --- a/test/libsolidity/syntaxTests/storageLayoutSpecifier/multi_token_expression.sol +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/multi_token_expression.sol @@ -1,4 +1,3 @@ contract C layout at 5 minutes { } contract D layout at 2 gwei { } // ---- -// UnimplementedFeatureError 1834: (0-34): Code generation is not supported for contracts with specified storage layout base. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/rational_number_zero_fractional_part.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/rational_number_zero_fractional_part.sol index 4d5b2da9cd51..e21521e39a97 100644 --- a/test/libsolidity/syntaxTests/storageLayoutSpecifier/rational_number_zero_fractional_part.sol +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/rational_number_zero_fractional_part.sol @@ -1,4 +1,3 @@ contract A layout at 42.0 {} contract B layout at 2.5e10 {} // ---- -// UnimplementedFeatureError 1834: (0-28): Code generation is not supported for contracts with specified storage layout base. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/same_ancestor_two_contracts.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/same_ancestor_two_contracts.sol index 310f503579a0..58fb725d7590 100644 --- a/test/libsolidity/syntaxTests/storageLayoutSpecifier/same_ancestor_two_contracts.sol +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/same_ancestor_two_contracts.sol @@ -2,4 +2,3 @@ contract A {} contract B is A layout at 64 {} contract C is A layout at 42 {} // ---- -// UnimplementedFeatureError 1834: (14-45): Code generation is not supported for contracts with specified storage layout base. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/simple_layout.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/simple_layout.sol index 116a6c5e4a3b..024f5a95f941 100644 --- a/test/libsolidity/syntaxTests/storageLayoutSpecifier/simple_layout.sol +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/simple_layout.sol @@ -2,4 +2,3 @@ contract A layout at 0x1234 {} contract B layout at 1024 {} contract C layout at 0 {} // ---- -// UnimplementedFeatureError 1834: (0-30): Code generation is not supported for contracts with specified storage layout base. From 73e7917a0dea5a39ac6e40035fe139793d54d0da Mon Sep 17 00:00:00 2001 From: Matheus Aguiar Date: Fri, 20 Dec 2024 09:37:07 -0300 Subject: [PATCH 0857/1022] Storage Layout and Codegen --- Changelog.md | 2 +- .../analysis/PostTypeContractLevelChecker.cpp | 6 ++--- libsolidity/ast/ASTUtils.cpp | 14 +++++++++++ libsolidity/ast/ASTUtils.h | 9 ++++++++ libsolidity/ast/Types.cpp | 23 ++++++++++++------- libsolidity/ast/Types.h | 5 +++- 6 files changed, 45 insertions(+), 14 deletions(-) diff --git a/Changelog.md b/Changelog.md index 13cc8db13346..331a68a3f383 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,7 +1,7 @@ ### 0.8.29 (unreleased) Language Features: - * Introduce syntax for specifying contract storage layout base. + * Allow relocating contract storage to an arbitrary location. Compiler Features: diff --git a/libsolidity/analysis/PostTypeContractLevelChecker.cpp b/libsolidity/analysis/PostTypeContractLevelChecker.cpp index b605401e9e27..3e5a05499ea7 100644 --- a/libsolidity/analysis/PostTypeContractLevelChecker.cpp +++ b/libsolidity/analysis/PostTypeContractLevelChecker.cpp @@ -117,10 +117,8 @@ void PostTypeContractLevelChecker::checkStorageLayoutSpecifier(StorageLayoutSpec } solAssert(rationalType->value().denominator() == 1); - if ( - rationalType->value().numerator() < 0 || - rationalType->value().numerator() > std::numeric_limits::max() - ) + bigint baseSlot = rationalType->value().numerator(); + if (!(0 <= baseSlot && baseSlot <= std::numeric_limits::max())) { m_errorReporter.typeError( 6753_error, diff --git a/libsolidity/ast/ASTUtils.cpp b/libsolidity/ast/ASTUtils.cpp index 7f5ea03a0ac0..5ae3366194c6 100644 --- a/libsolidity/ast/ASTUtils.cpp +++ b/libsolidity/ast/ASTUtils.cpp @@ -123,4 +123,18 @@ bigint contractStorageSizeUpperBound(ContractDefinition const& _contract, Variab return size; } +u256 layoutBaseForInheritanceHierarchy(ContractDefinition const& _topLevelContract, DataLocation _location) +{ + if (_location != DataLocation::Storage) + { + solAssert(_location == DataLocation::Transient); + return 0; + } + + if (auto const* storageLayoutSpecifier = _topLevelContract.storageLayoutSpecifier()) + return *storageLayoutSpecifier->annotation().baseSlot; + + return 0; +} + } diff --git a/libsolidity/ast/ASTUtils.h b/libsolidity/ast/ASTUtils.h index 0f37af7195d9..d29bda35ff8c 100644 --- a/libsolidity/ast/ASTUtils.h +++ b/libsolidity/ast/ASTUtils.h @@ -18,6 +18,8 @@ #pragma once +#include + namespace solidity::frontend { @@ -26,6 +28,7 @@ class Declaration; class Expression; class SourceUnit; class VariableDeclaration; +class ContractDefinition; /// Find the topmost referenced constant variable declaration when the given variable /// declaration value is an identifier. Works only for constant variable declarations. @@ -52,4 +55,10 @@ Type const* type(VariableDeclaration const& _variable); /// located in @a _location (either storage or transient storage). bigint contractStorageSizeUpperBound(ContractDefinition const& _contract, VariableDeclaration::Location _location); +/// @returns The base slot of the inheritance hierarchy rooted at the specified contract. +/// The value comes from the inheritance specifier of the contract and defaults to zero. +/// The value is zero also when the contract is an interface or a library (and cannot have storage). +/// Assumes analysis was successful. +u256 layoutBaseForInheritanceHierarchy(ContractDefinition const& _topLevelContract, DataLocation _location); + } diff --git a/libsolidity/ast/Types.cpp b/libsolidity/ast/Types.cpp index c77a6d0b6b50..1a1cf929148c 100644 --- a/libsolidity/ast/Types.cpp +++ b/libsolidity/ast/Types.cpp @@ -24,6 +24,7 @@ #include #include +#include #include #include @@ -138,23 +139,23 @@ void Type::clearCache() const m_stackSize.reset(); } -void StorageOffsets::computeOffsets(TypePointers const& _types) +void StorageOffsets::computeOffsets(TypePointers const& _types, u256 _baseSlot) { - bigint slotOffset = 0; + bigint slotOffset = bigint(_baseSlot); unsigned byteOffset = 0; std::map> offsets; for (size_t i = 0; i < _types.size(); ++i) { Type const* type = _types[i]; - if (!type->canBeStored()) - continue; + solAssert(type->canBeStored()); + solAssert(type->storageBytes() <= 32); if (byteOffset + type->storageBytes() > 32) { // would overflow, go to next slot ++slotOffset; byteOffset = 0; } - solAssert(slotOffset < bigint(1) << 256 ,"Object too large for storage."); + solAssert(slotOffset < bigint(1) << 256, "Object extends past the end of storage."); offsets[i] = std::make_pair(u256(slotOffset), byteOffset); solAssert(type->storageSize() >= 1, "Invalid storage size."); if (type->storageSize() == 1 && byteOffset + type->storageBytes() <= 32) @@ -167,8 +168,11 @@ void StorageOffsets::computeOffsets(TypePointers const& _types) } if (byteOffset > 0) ++slotOffset; - solAssert(slotOffset < bigint(1) << 256, "Object too large for storage."); - m_storageSize = u256(slotOffset); + + solAssert(slotOffset < bigint(1) << 256, "Object extends past the end of storage."); + storageSize = slotOffset - _baseSlot; + solAssert(storageSize < bigint(1) << 256, "Object too large for storage."); + m_storageSize = u256(storageSize); swap(m_offsets, offsets); } @@ -2168,11 +2172,14 @@ std::vector> ContractType for (VariableDeclaration const* variable: contract->stateVariables()) if (!(variable->isConstant() || variable->immutable()) && variable->referenceLocation() == location) variables.push_back(variable); + TypePointers types; for (auto variable: variables) types.push_back(variable->annotation().type); StorageOffsets offsets; - offsets.computeOffsets(types); + u256 layoutBase = 0; + layoutBase = layoutBaseForInheritanceHierarchy(m_contract, _location); + offsets.computeOffsets(types, layoutBase); std::vector> variablesAndOffsets; for (size_t index = 0; index < variables.size(); ++index) diff --git a/libsolidity/ast/Types.h b/libsolidity/ast/Types.h index aa14cf6b938e..2a5cdcfc99bb 100644 --- a/libsolidity/ast/Types.h +++ b/libsolidity/ast/Types.h @@ -81,7 +81,10 @@ class StorageOffsets public: /// Resets the StorageOffsets objects and determines the position in storage for each /// of the elements of @a _types. - void computeOffsets(TypePointers const& _types); + /// Calculated positions are absolute and start at @a _baseSlot. + /// Assumes that @a _types is small enough to fit in the area between @a _baseSlot and the end of storage + /// (the caller is responsible for validating that). + void computeOffsets(TypePointers const& _types, u256 _baseSlot = 0); /// @returns the offset of the given member, might be null if the member is not part of storage. std::pair const* offset(size_t _index) const; /// @returns the total number of slots occupied by all members. From b601fb4fadf9fcf126a06f63a188802382a32a7f Mon Sep 17 00:00:00 2001 From: Matheus Aguiar Date: Wed, 26 Feb 2025 23:56:46 -0300 Subject: [PATCH 0858/1022] Type checking fix: error on contract extending past storage end --- .../analysis/PostTypeContractLevelChecker.cpp | 23 ++++++++++++++----- .../analysis/PostTypeContractLevelChecker.h | 2 +- libsolidity/ast/Types.cpp | 8 ++----- .../contract_at_storage_end.sol | 3 +++ ...age_end_with_transient_state_variables.sol | 8 +++++++ .../contract_extends_past_storage_end.sol | 6 +++++ .../contract_too_large_for_storage.sol | 6 +++++ 7 files changed, 43 insertions(+), 13 deletions(-) create mode 100644 test/libsolidity/syntaxTests/storageLayoutSpecifier/contract_at_storage_end.sol create mode 100644 test/libsolidity/syntaxTests/storageLayoutSpecifier/contract_at_storage_end_with_transient_state_variables.sol create mode 100644 test/libsolidity/syntaxTests/storageLayoutSpecifier/contract_extends_past_storage_end.sol create mode 100644 test/libsolidity/syntaxTests/storageLayoutSpecifier/contract_too_large_for_storage.sol diff --git a/libsolidity/analysis/PostTypeContractLevelChecker.cpp b/libsolidity/analysis/PostTypeContractLevelChecker.cpp index 3e5a05499ea7..657f39284544 100644 --- a/libsolidity/analysis/PostTypeContractLevelChecker.cpp +++ b/libsolidity/analysis/PostTypeContractLevelChecker.cpp @@ -73,15 +73,17 @@ bool PostTypeContractLevelChecker::check(ContractDefinition const& _contract) errorHashes[hash][signature] = error->location(); } - if (auto const* layoutSpecifier = _contract.storageLayoutSpecifier()) - checkStorageLayoutSpecifier(*layoutSpecifier); + if (_contract.storageLayoutSpecifier()) + checkStorageLayoutSpecifier(_contract); return !Error::containsErrors(m_errorReporter.errors()); } -void PostTypeContractLevelChecker::checkStorageLayoutSpecifier(StorageLayoutSpecifier const& _storageLayoutSpecifier) +void PostTypeContractLevelChecker::checkStorageLayoutSpecifier(ContractDefinition const& _contract) { - Expression const& baseSlotExpression = _storageLayoutSpecifier.baseSlotExpression(); + StorageLayoutSpecifier const* storageLayoutSpecifier = _contract.storageLayoutSpecifier(); + solAssert(storageLayoutSpecifier); + Expression const& baseSlotExpression = storageLayoutSpecifier->baseSlotExpression(); if (!*baseSlotExpression.annotation().isPure) { @@ -125,12 +127,21 @@ void PostTypeContractLevelChecker::checkStorageLayoutSpecifier(StorageLayoutSpec baseSlotExpression.location(), fmt::format( "The base slot of the storage layout evaluates to {}, which is outside the range of type uint256.", - formatNumberReadable(rationalType->value().numerator()) + formatNumberReadable(baseSlot) ) ); return; } solAssert(baseSlotExpressionType->isImplicitlyConvertibleTo(*TypeProvider::uint256())); - _storageLayoutSpecifier.annotation().baseSlot = u256(rationalType->value().numerator()); + storageLayoutSpecifier->annotation().baseSlot = u256(baseSlot); + + bigint size = contractStorageSizeUpperBound(_contract, VariableDeclaration::Location::Unspecified); + solAssert(size < bigint(1) << 256); + if (baseSlot + size >= bigint(1) << 256) + m_errorReporter.typeError( + 5015_error, + baseSlotExpression.location(), + "Contract extends past the end of storage when this base slot value is specified." + ); } diff --git a/libsolidity/analysis/PostTypeContractLevelChecker.h b/libsolidity/analysis/PostTypeContractLevelChecker.h index 889c163562ff..2fa2cb11bfd3 100644 --- a/libsolidity/analysis/PostTypeContractLevelChecker.h +++ b/libsolidity/analysis/PostTypeContractLevelChecker.h @@ -50,7 +50,7 @@ class PostTypeContractLevelChecker /// @returns true iff all checks passed. Note even if all checks passed, errors() can still contain warnings bool check(ContractDefinition const& _contract); - void checkStorageLayoutSpecifier(StorageLayoutSpecifier const& _storageLayoutSpecifier); + void checkStorageLayoutSpecifier(ContractDefinition const& _contract); langutil::ErrorReporter& m_errorReporter; }; diff --git a/libsolidity/ast/Types.cpp b/libsolidity/ast/Types.cpp index 1a1cf929148c..5f543be0dfa8 100644 --- a/libsolidity/ast/Types.cpp +++ b/libsolidity/ast/Types.cpp @@ -170,9 +170,7 @@ void StorageOffsets::computeOffsets(TypePointers const& _types, u256 _baseSlot) ++slotOffset; solAssert(slotOffset < bigint(1) << 256, "Object extends past the end of storage."); - storageSize = slotOffset - _baseSlot; - solAssert(storageSize < bigint(1) << 256, "Object too large for storage."); - m_storageSize = u256(storageSize); + m_storageSize = u256(slotOffset - _baseSlot); swap(m_offsets, offsets); } @@ -2177,9 +2175,7 @@ std::vector> ContractType for (auto variable: variables) types.push_back(variable->annotation().type); StorageOffsets offsets; - u256 layoutBase = 0; - layoutBase = layoutBaseForInheritanceHierarchy(m_contract, _location); - offsets.computeOffsets(types, layoutBase); + offsets.computeOffsets(types, layoutBaseForInheritanceHierarchy(m_contract, _location)); std::vector> variablesAndOffsets; for (size_t index = 0; index < variables.size(); ++index) diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/contract_at_storage_end.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/contract_at_storage_end.sol new file mode 100644 index 000000000000..29733c9ca96a --- /dev/null +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/contract_at_storage_end.sol @@ -0,0 +1,3 @@ +contract C layout at 2**256 - 1 { +} +// ---- diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/contract_at_storage_end_with_transient_state_variables.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/contract_at_storage_end_with_transient_state_variables.sol new file mode 100644 index 000000000000..fb1008616162 --- /dev/null +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/contract_at_storage_end_with_transient_state_variables.sol @@ -0,0 +1,8 @@ +contract C layout at 2**256 - 1 { + uint transient x; + uint transient y; + uint transient z; +} +// ==== +// EVMVersion: >=cancun +// ---- diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/contract_extends_past_storage_end.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/contract_extends_past_storage_end.sol new file mode 100644 index 000000000000..a3efe6d3a0de --- /dev/null +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/contract_extends_past_storage_end.sol @@ -0,0 +1,6 @@ +contract C layout at 2**256 - 2 { + uint x; + bool b; +} +// ---- +// TypeError 5015: (21-31): Contract extends past the end of storage when this base slot value is specified. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/contract_too_large_for_storage.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/contract_too_large_for_storage.sol new file mode 100644 index 000000000000..cfbfd539de28 --- /dev/null +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/contract_too_large_for_storage.sol @@ -0,0 +1,6 @@ +contract C layout at 1 { + uint[2**256 - 1] x; + uint y; +} +// ---- +// TypeError 7676: (0-62): Contract requires too much storage. From 14232980e4b39dee72972f3e142db584f0848a16 Mon Sep 17 00:00:00 2001 From: Matheus Aguiar Date: Tue, 4 Mar 2025 14:47:40 -0300 Subject: [PATCH 0859/1022] Rename ContractType::stateVariables --- libsolidity/ast/Types.cpp | 2 +- libsolidity/ast/Types.h | 9 ++++++--- libsolidity/codegen/ContractCompiler.cpp | 2 +- libsolidity/codegen/ir/IRGenerator.cpp | 2 +- libsolidity/interface/StorageLayout.cpp | 2 +- 5 files changed, 10 insertions(+), 7 deletions(-) diff --git a/libsolidity/ast/Types.cpp b/libsolidity/ast/Types.cpp index 5f543be0dfa8..02df22dd5ce0 100644 --- a/libsolidity/ast/Types.cpp +++ b/libsolidity/ast/Types.cpp @@ -2150,7 +2150,7 @@ FunctionType const* ContractType::newExpressionType() const return m_constructorType; } -std::vector> ContractType::stateVariables(DataLocation _location) const +std::vector> ContractType::linearizedStateVariables(DataLocation _location) const { VariableDeclaration::Location location; switch (_location) diff --git a/libsolidity/ast/Types.h b/libsolidity/ast/Types.h index 2a5cdcfc99bb..8d2453d8d503 100644 --- a/libsolidity/ast/Types.h +++ b/libsolidity/ast/Types.h @@ -1005,9 +1005,12 @@ class ContractType: public Type /// Returns the function type of the constructor modified to return an object of the contract's type. FunctionType const* newExpressionType() const; - /// @returns a list of all state variables (including inherited) of the contract and their - /// offsets in storage/transient storage. - std::vector> stateVariables(DataLocation _location) const; + /// @returns a list of all state variables in the linearized inheritance hierarchy and + /// their respective slots and offsets in storage/transient storage. + /// It should only be called for the top level contract in order to get the absolute slots and + /// offsets values in storage/transient storage. Otherwise, the slots of the state variables + /// will be relative to the contract position in the hierarchy. + std::vector> linearizedStateVariables(DataLocation _location) const; /// @returns a list of all immutable variables (including inherited) of the contract. std::vector immutableVariables() const; protected: diff --git a/libsolidity/codegen/ContractCompiler.cpp b/libsolidity/codegen/ContractCompiler.cpp index 57a23fb803ce..3a4dca0439ca 100644 --- a/libsolidity/codegen/ContractCompiler.cpp +++ b/libsolidity/codegen/ContractCompiler.cpp @@ -571,7 +571,7 @@ void ContractCompiler::appendReturnValuePacker(TypePointers const& _typeParamete void ContractCompiler::registerStateVariables(ContractDefinition const& _contract) { for (auto const location: {DataLocation::Storage, DataLocation::Transient}) - for (auto const& var: ContractType(_contract).stateVariables(location)) + for (auto const& var: ContractType(_contract).linearizedStateVariables(location)) m_context.addStateVariable(*std::get<0>(var), std::get<1>(var), std::get<2>(var)); } diff --git a/libsolidity/codegen/ir/IRGenerator.cpp b/libsolidity/codegen/ir/IRGenerator.cpp index dd6503ca1fbf..27f7bedce225 100644 --- a/libsolidity/codegen/ir/IRGenerator.cpp +++ b/libsolidity/codegen/ir/IRGenerator.cpp @@ -1175,7 +1175,7 @@ void IRGenerator::resetContext(ContractDefinition const& _contract, ExecutionCon m_context.setMostDerivedContract(_contract); for (auto const location: {DataLocation::Storage, DataLocation::Transient}) - for (auto const& var: ContractType(_contract).stateVariables(location)) + for (auto const& var: ContractType(_contract).linearizedStateVariables(location)) m_context.addStateVariable(*std::get<0>(var), std::get<1>(var), std::get<2>(var)); } diff --git a/libsolidity/interface/StorageLayout.cpp b/libsolidity/interface/StorageLayout.cpp index 8565fec68f26..05d799d08ffd 100644 --- a/libsolidity/interface/StorageLayout.cpp +++ b/libsolidity/interface/StorageLayout.cpp @@ -36,7 +36,7 @@ Json StorageLayout::generate(ContractDefinition const& _contractDef, DataLocatio solAssert(contractType, ""); Json variables = Json::array(); - for (auto [var, slot, offset]: contractType->stateVariables(_location)) + for (auto [var, slot, offset]: contractType->linearizedStateVariables(_location)) variables.emplace_back(generate(*var, slot, offset)); Json layout; From 3532328324cc479d17b4492de645597a3b5282c1 Mon Sep 17 00:00:00 2001 From: Sebastian Miasojed Date: Wed, 19 Feb 2025 22:51:47 +0100 Subject: [PATCH 0860/1022] Fix stack overflow issue when using soljson compiler --- cmake/EthCompilerSettings.cmake | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/cmake/EthCompilerSettings.cmake b/cmake/EthCompilerSettings.cmake index cc8435ed3c30..ab90c3f2035a 100644 --- a/cmake/EthCompilerSettings.cmake +++ b/cmake/EthCompilerSettings.cmake @@ -170,6 +170,10 @@ if (("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU") OR ("${CMAKE_CXX_COMPILER_ID}" MA 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") + # Increase stack size from 5MB to 16MB to prevent stack overflow issues. + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s TOTAL_STACK=16mb") + # Increase memory size from 16MB to 32MB since the stack size is now 16MB. + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s INITIAL_MEMORY=32mb") endif() endif() From f3705de1740737f31715ad7758ac4d47b9f5c4f2 Mon Sep 17 00:00:00 2001 From: Alexander Arlt Date: Tue, 27 Aug 2024 12:59:56 +0200 Subject: [PATCH 0861/1022] Ethdebug instructions and source ranges. --- Changelog.md | 1 + libevmasm/Assembly.cpp | 147 +++++++++---- libevmasm/CMakeLists.txt | 2 + libevmasm/Ethdebug.cpp | 115 +++++++++++ libevmasm/Ethdebug.h | 35 ++++ libevmasm/LinkerObject.h | 31 +++ libsolidity/interface/CompilerStack.cpp | 18 +- libsolidity/interface/StandardCompiler.cpp | 16 +- libyul/YulStack.cpp | 17 +- libyul/YulStack.h | 3 - solc/CommandLineInterface.cpp | 26 +-- test/cmdlineTests.sh | 21 ++ .../debug_info_ethdebug_compatible/args | 1 - .../debug_info_ethdebug_compatible/input.sol | 7 - .../debug_info_ethdebug_compatible/output | 193 ------------------ .../debug_info_ethdebug_incompatible/args | 1 - .../debug_info_ethdebug_incompatible/err | 1 - .../ethdebug_and_ethdebug_runtime_ir/args | 1 - .../input.sol | 7 - .../ethdebug_and_ethdebug_runtime_ir/output | 123 ----------- .../args | 1 - .../input.sol | 7 - .../output | 79 ------- .../ethdebug_enabled_optimization_ir/args | 1 - .../ethdebug_enabled_optimization_ir/err | 1 - .../ethdebug_enabled_optimization_ir/exit | 1 - .../input.sol | 7 - .../args | 1 - .../err | 1 - .../exit | 1 - .../input.sol | 7 - .../ethdebug_eof_container_osaka/args | 1 + .../ethdebug_eof_container_osaka/err | 1 + .../exit | 0 .../input.sol | 1 - .../ethdebug_eof_container_osaka/output | 4 + test/cmdlineTests/ethdebug_ir/args | 1 - test/cmdlineTests/ethdebug_ir/input.sol | 7 - test/cmdlineTests/ethdebug_ir/output | 121 ----------- test/cmdlineTests/ethdebug_iroptimized/args | 1 - .../ethdebug_iroptimized/input.sol | 7 - test/cmdlineTests/ethdebug_iroptimized/output | 77 ------- test/cmdlineTests/ethdebug_no_via_ir/args | 1 - test/cmdlineTests/ethdebug_no_via_ir/err | 1 - test/cmdlineTests/ethdebug_no_via_ir/exit | 1 - .../cmdlineTests/ethdebug_no_via_ir/input.sol | 7 - test/cmdlineTests/ethdebug_runtime_ir/args | 1 - .../ethdebug_runtime_ir/input.sol | 7 - test/cmdlineTests/ethdebug_runtime_ir/output | 121 ----------- .../ethdebug_runtime_iroptimized/args | 1 - .../ethdebug_runtime_iroptimized/input.sol | 7 - .../ethdebug_runtime_iroptimized/output | 77 ------- .../output.json | 23 +-- .../strip-ethdebug | 0 .../output.json | 23 +-- .../strip-ethdebug | 0 .../output.json | 23 +-- .../strip-ethdebug | 0 .../output.json | 15 +- .../strip-ethdebug | 0 .../output.json | 15 +- .../strip-ethdebug | 0 .../output.json | 15 +- .../strip-ethdebug | 0 .../output.json | 15 +- .../strip-ethdebug | 0 .../output.json | 15 +- .../strip-ethdebug | 0 .../output.json | 15 +- .../strip-ethdebug | 0 .../output.json | 10 +- .../strip-ethdebug | 0 .../args | 1 + .../in.yul | 11 + .../input.json | 16 ++ .../output.json | 13 ++ .../args | 1 + .../in.yul | 7 + .../input.json | 11 + .../output.json | 127 ++++++++++++ .../output.json | 10 +- .../strip-ethdebug | 0 .../output.json | 10 +- .../strip-ethdebug | 0 .../in.yul | 22 +- .../output.json | 19 +- .../strip-ethdebug | 0 .../args | 1 + .../in.yul | 19 ++ .../input.json | 11 + .../output.json | 17 ++ .../strip-ethdebug | 0 .../standard_yul_ethdebug_ir/output.json | 10 +- .../standard_yul_ethdebug_ir/strip-ethdebug | 0 .../output.json | 10 +- .../strip-ethdebug | 0 test/cmdlineTests/yul_ethdebug/args | 1 - test/cmdlineTests/yul_ethdebug/input.yul | 18 -- test/cmdlineTests/yul_ethdebug/output | 7 - test/cmdlineTests/yul_ethdebug_ir/args | 1 - test/cmdlineTests/yul_ethdebug_ir/err | 1 - test/cmdlineTests/yul_ethdebug_ir/exit | 1 - test/cmdlineTests/yul_ethdebug_ir/input.yul | 18 -- .../yul_ethdebug_iroptimized/args | 1 - .../yul_ethdebug_iroptimized/input.yul | 18 -- .../yul_ethdebug_iroptimized/output | 26 --- test/cmdlineTests/yul_ethdebug_optimize/args | 1 - test/cmdlineTests/yul_ethdebug_optimize/err | 1 - test/cmdlineTests/yul_ethdebug_optimize/exit | 1 - .../yul_ethdebug_optimize/input.yul | 18 -- .../yul_ethdebug_optimize_iroptimized/args | 1 - .../yul_ethdebug_optimize_iroptimized/err | 1 - .../yul_ethdebug_optimize_iroptimized/exit | 1 - .../input.yul | 18 -- test/cmdlineTests/yul_ethdebug_runtime/args | 1 - test/cmdlineTests/yul_ethdebug_runtime/err | 1 - test/cmdlineTests/yul_ethdebug_runtime/exit | 1 - .../yul_ethdebug_runtime/input.yul | 18 -- test/libevmasm/Assembler.cpp | 41 ++++ test/libsolidity/StandardCompiler.cpp | 41 ++++ 120 files changed, 747 insertions(+), 1293 deletions(-) create mode 100644 libevmasm/Ethdebug.cpp create mode 100644 libevmasm/Ethdebug.h delete mode 100644 test/cmdlineTests/debug_info_ethdebug_compatible/args delete mode 100644 test/cmdlineTests/debug_info_ethdebug_compatible/input.sol delete mode 100644 test/cmdlineTests/debug_info_ethdebug_compatible/output delete mode 100644 test/cmdlineTests/debug_info_ethdebug_incompatible/args delete mode 100644 test/cmdlineTests/debug_info_ethdebug_incompatible/err delete mode 100644 test/cmdlineTests/ethdebug_and_ethdebug_runtime_ir/args delete mode 100644 test/cmdlineTests/ethdebug_and_ethdebug_runtime_ir/input.sol delete mode 100644 test/cmdlineTests/ethdebug_and_ethdebug_runtime_ir/output delete mode 100644 test/cmdlineTests/ethdebug_and_ethdebug_runtime_iroptimized/args delete mode 100644 test/cmdlineTests/ethdebug_and_ethdebug_runtime_iroptimized/input.sol delete mode 100644 test/cmdlineTests/ethdebug_and_ethdebug_runtime_iroptimized/output delete mode 100644 test/cmdlineTests/ethdebug_enabled_optimization_ir/args delete mode 100644 test/cmdlineTests/ethdebug_enabled_optimization_ir/err delete mode 100644 test/cmdlineTests/ethdebug_enabled_optimization_ir/exit delete mode 100644 test/cmdlineTests/ethdebug_enabled_optimization_ir/input.sol delete mode 100644 test/cmdlineTests/ethdebug_enabled_optimization_iroptimized/args delete mode 100644 test/cmdlineTests/ethdebug_enabled_optimization_iroptimized/err delete mode 100644 test/cmdlineTests/ethdebug_enabled_optimization_iroptimized/exit delete mode 100644 test/cmdlineTests/ethdebug_enabled_optimization_iroptimized/input.sol create mode 100644 test/cmdlineTests/ethdebug_eof_container_osaka/args create mode 100644 test/cmdlineTests/ethdebug_eof_container_osaka/err rename test/cmdlineTests/{debug_info_ethdebug_incompatible => ethdebug_eof_container_osaka}/exit (100%) rename test/cmdlineTests/{debug_info_ethdebug_incompatible => ethdebug_eof_container_osaka}/input.sol (99%) create mode 100644 test/cmdlineTests/ethdebug_eof_container_osaka/output delete mode 100644 test/cmdlineTests/ethdebug_ir/args delete mode 100644 test/cmdlineTests/ethdebug_ir/input.sol delete mode 100644 test/cmdlineTests/ethdebug_ir/output delete mode 100644 test/cmdlineTests/ethdebug_iroptimized/args delete mode 100644 test/cmdlineTests/ethdebug_iroptimized/input.sol delete mode 100644 test/cmdlineTests/ethdebug_iroptimized/output delete mode 100644 test/cmdlineTests/ethdebug_no_via_ir/args delete mode 100644 test/cmdlineTests/ethdebug_no_via_ir/err delete mode 100644 test/cmdlineTests/ethdebug_no_via_ir/exit delete mode 100644 test/cmdlineTests/ethdebug_no_via_ir/input.sol delete mode 100644 test/cmdlineTests/ethdebug_runtime_ir/args delete mode 100644 test/cmdlineTests/ethdebug_runtime_ir/input.sol delete mode 100644 test/cmdlineTests/ethdebug_runtime_ir/output delete mode 100644 test/cmdlineTests/ethdebug_runtime_iroptimized/args delete mode 100644 test/cmdlineTests/ethdebug_runtime_iroptimized/input.sol delete mode 100644 test/cmdlineTests/ethdebug_runtime_iroptimized/output create mode 100644 test/cmdlineTests/standard_output_debuginfo_ethdebug_compatible/strip-ethdebug create mode 100644 test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_ir/strip-ethdebug create mode 100644 test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_iroptimized/strip-ethdebug create mode 100644 test/cmdlineTests/standard_output_selection_ethdebug_bytecode_ir/strip-ethdebug create mode 100644 test/cmdlineTests/standard_output_selection_ethdebug_bytecode_iroptimized/strip-ethdebug create mode 100644 test/cmdlineTests/standard_output_selection_ethdebug_deployedbytecode_ir/strip-ethdebug create mode 100644 test/cmdlineTests/standard_output_selection_ethdebug_deployedbytecode_iroptimized/strip-ethdebug create mode 100644 test/cmdlineTests/standard_output_selection_ethdebug_ir/strip-ethdebug create mode 100644 test/cmdlineTests/standard_output_selection_ethdebug_iroptimized/strip-ethdebug create mode 100644 test/cmdlineTests/standard_yul_debug_info_ethdebug_compatible_output/strip-ethdebug create mode 100644 test/cmdlineTests/standard_yul_debug_info_ethdebug_verbatim_unimplemented/args create mode 100644 test/cmdlineTests/standard_yul_debug_info_ethdebug_verbatim_unimplemented/in.yul create mode 100644 test/cmdlineTests/standard_yul_debug_info_ethdebug_verbatim_unimplemented/input.json create mode 100644 test/cmdlineTests/standard_yul_debug_info_ethdebug_verbatim_unimplemented/output.json create mode 100644 test/cmdlineTests/standard_yul_ethdebug_assign_immutable/args create mode 100644 test/cmdlineTests/standard_yul_ethdebug_assign_immutable/in.yul create mode 100644 test/cmdlineTests/standard_yul_ethdebug_assign_immutable/input.json create mode 100644 test/cmdlineTests/standard_yul_ethdebug_assign_immutable/output.json create mode 100644 test/cmdlineTests/standard_yul_ethdebug_bytecode_ir/strip-ethdebug create mode 100644 test/cmdlineTests/standard_yul_ethdebug_bytecode_iroptimized/strip-ethdebug create mode 100644 test/cmdlineTests/standard_yul_ethdebug_deployed_bytecode/strip-ethdebug create mode 100644 test/cmdlineTests/standard_yul_ethdebug_deployed_bytecode_and_bytecode/args create mode 100644 test/cmdlineTests/standard_yul_ethdebug_deployed_bytecode_and_bytecode/in.yul create mode 100644 test/cmdlineTests/standard_yul_ethdebug_deployed_bytecode_and_bytecode/input.json create mode 100644 test/cmdlineTests/standard_yul_ethdebug_deployed_bytecode_and_bytecode/output.json create mode 100644 test/cmdlineTests/standard_yul_ethdebug_deployed_bytecode_and_bytecode/strip-ethdebug create mode 100644 test/cmdlineTests/standard_yul_ethdebug_ir/strip-ethdebug create mode 100644 test/cmdlineTests/standard_yul_ethdebug_iroptimize/strip-ethdebug delete mode 100644 test/cmdlineTests/yul_ethdebug/args delete mode 100644 test/cmdlineTests/yul_ethdebug/input.yul delete mode 100644 test/cmdlineTests/yul_ethdebug/output delete mode 100644 test/cmdlineTests/yul_ethdebug_ir/args delete mode 100644 test/cmdlineTests/yul_ethdebug_ir/err delete mode 100644 test/cmdlineTests/yul_ethdebug_ir/exit delete mode 100644 test/cmdlineTests/yul_ethdebug_ir/input.yul delete mode 100644 test/cmdlineTests/yul_ethdebug_iroptimized/args delete mode 100644 test/cmdlineTests/yul_ethdebug_iroptimized/input.yul delete mode 100644 test/cmdlineTests/yul_ethdebug_iroptimized/output delete mode 100644 test/cmdlineTests/yul_ethdebug_optimize/args delete mode 100644 test/cmdlineTests/yul_ethdebug_optimize/err delete mode 100644 test/cmdlineTests/yul_ethdebug_optimize/exit delete mode 100644 test/cmdlineTests/yul_ethdebug_optimize/input.yul delete mode 100644 test/cmdlineTests/yul_ethdebug_optimize_iroptimized/args delete mode 100644 test/cmdlineTests/yul_ethdebug_optimize_iroptimized/err delete mode 100644 test/cmdlineTests/yul_ethdebug_optimize_iroptimized/exit delete mode 100644 test/cmdlineTests/yul_ethdebug_optimize_iroptimized/input.yul delete mode 100644 test/cmdlineTests/yul_ethdebug_runtime/args delete mode 100644 test/cmdlineTests/yul_ethdebug_runtime/err delete mode 100644 test/cmdlineTests/yul_ethdebug_runtime/exit delete mode 100644 test/cmdlineTests/yul_ethdebug_runtime/input.yul diff --git a/Changelog.md b/Changelog.md index 13cc8db13346..5a8438c5c5e5 100644 --- a/Changelog.md +++ b/Changelog.md @@ -6,6 +6,7 @@ Language Features: Compiler Features: * Error Reporting: Errors reported during code generation now point at the location of the contract when more fine-grained location is not available. + * ethdebug: Experimental support for instructions and source locations. * EVM: Support for the EVM version "Osaka". * EVM Assembly Import: Allow enabling opcode-based optimizer. * General: The experimental EOF backend implements a subset of EOF sufficient to compile arbitrary high-level Solidity syntax via IR with optimization enabled. diff --git a/libevmasm/Assembly.cpp b/libevmasm/Assembly.cpp index 4dcc6a4b092b..a0711cd41756 100644 --- a/libevmasm/Assembly.cpp +++ b/libevmasm/Assembly.cpp @@ -1281,6 +1281,21 @@ LinkerObject const& Assembly::assembleLegacy() const uint8_t tagPush = static_cast(pushInstruction(bytesPerTag)); uint8_t dataRefPush = static_cast(pushInstruction(bytesPerDataRef)); + LinkerObject::CodeSectionLocation codeSectionLocation; + codeSectionLocation.start = 0; + size_t assemblyItemIndex = 0; + auto assembleInstruction = [&](auto&& _addInstruction) { + size_t start = ret.bytecode.size(); + _addInstruction(); + size_t end = ret.bytecode.size(); + codeSectionLocation.instructionLocations.emplace_back( + LinkerObject::InstructionLocation{ + .start = start, + .end = end, + .assemblyItemIndex = assemblyItemIndex + } + ); + }; for (AssemblyItem const& item: items) { // store position of the invalid jump destination @@ -1290,63 +1305,81 @@ LinkerObject const& Assembly::assembleLegacy() const switch (item.type()) { case Operation: - ret.bytecode += assembleOperation(item); + assembleInstruction([&](){ + ret.bytecode += assembleOperation(item); + }); break; case Push: - ret.bytecode += assemblePush(item); + assembleInstruction([&](){ + ret.bytecode += assemblePush(item); + }); break; case PushTag: { - ret.bytecode.push_back(tagPush); - tagRefs[ret.bytecode.size()] = item.splitForeignPushTag(); - ret.bytecode.resize(ret.bytecode.size() + bytesPerTag); + assembleInstruction([&](){ + ret.bytecode.push_back(tagPush); + tagRefs[ret.bytecode.size()] = item.splitForeignPushTag(); + ret.bytecode.resize(ret.bytecode.size() + bytesPerTag); + }); break; } case PushData: - ret.bytecode.push_back(dataRefPush); - dataRefs.insert(std::make_pair(h256(item.data()), ret.bytecode.size())); - ret.bytecode.resize(ret.bytecode.size() + bytesPerDataRef); + assembleInstruction([&]() { + ret.bytecode.push_back(dataRefPush); + dataRefs.insert(std::make_pair(h256(item.data()), ret.bytecode.size())); + ret.bytecode.resize(ret.bytecode.size() + bytesPerDataRef); + }); break; case PushSub: - assertThrow(item.data() <= std::numeric_limits::max(), AssemblyException, ""); - ret.bytecode.push_back(dataRefPush); - subRefs.insert(std::make_pair(static_cast(item.data()), ret.bytecode.size())); - ret.bytecode.resize(ret.bytecode.size() + bytesPerDataRef); + assembleInstruction([&]() { + assertThrow(item.data() <= std::numeric_limits::max(), AssemblyException, ""); + ret.bytecode.push_back(dataRefPush); + subRefs.insert(std::make_pair(static_cast(item.data()), ret.bytecode.size())); + ret.bytecode.resize(ret.bytecode.size() + bytesPerDataRef); + }); break; case PushSubSize: { - assertThrow(item.data() <= std::numeric_limits::max(), AssemblyException, ""); - auto s = subAssemblyById(static_cast(item.data()))->assemble().bytecode.size(); - item.setPushedValue(u256(s)); - unsigned b = std::max(1, numberEncodingSize(s)); - ret.bytecode.push_back(static_cast(pushInstruction(b))); - ret.bytecode.resize(ret.bytecode.size() + b); - bytesRef byr(&ret.bytecode.back() + 1 - b, b); - toBigEndian(s, byr); + assembleInstruction([&](){ + assertThrow(item.data() <= std::numeric_limits::max(), AssemblyException, ""); + auto s = subAssemblyById(static_cast(item.data()))->assemble().bytecode.size(); + item.setPushedValue(u256(s)); + unsigned b = std::max(1, numberEncodingSize(s)); + ret.bytecode.push_back(static_cast(pushInstruction(b))); + ret.bytecode.resize(ret.bytecode.size() + b); + bytesRef byr(&ret.bytecode.back() + 1 - b, b); + toBigEndian(s, byr); + }); break; } case PushProgramSize: { - ret.bytecode.push_back(dataRefPush); - sizeRefs.push_back(static_cast(ret.bytecode.size())); - ret.bytecode.resize(ret.bytecode.size() + bytesPerDataRef); + assembleInstruction([&](){ + ret.bytecode.push_back(dataRefPush); + sizeRefs.push_back(static_cast(ret.bytecode.size())); + ret.bytecode.resize(ret.bytecode.size() + bytesPerDataRef); + }); break; } case PushLibraryAddress: { - auto const [bytecode, linkRef] = assemblePushLibraryAddress(item, ret.bytecode.size()); - ret.bytecode += bytecode; - ret.linkReferences.insert(linkRef); + assembleInstruction([&]() { + auto const [bytecode, linkRef] = assemblePushLibraryAddress(item, ret.bytecode.size()); + ret.bytecode += bytecode; + ret.linkReferences.insert(linkRef); + }); break; } case PushImmutable: - ret.bytecode.push_back(static_cast(Instruction::PUSH32)); - // Maps keccak back to the "identifier" std::string of that immutable. - ret.immutableReferences[item.data()].first = m_immutables.at(item.data()); - // Record the bytecode offset of the PUSH32 argument. - ret.immutableReferences[item.data()].second.emplace_back(ret.bytecode.size()); - // Advance bytecode by 32 bytes (default initialized). - ret.bytecode.resize(ret.bytecode.size() + 32); + assembleInstruction([&]() { + ret.bytecode.push_back(static_cast(Instruction::PUSH32)); + // Maps keccak back to the "identifier" std::string of that immutable. + ret.immutableReferences[item.data()].first = m_immutables.at(item.data()); + // Record the bytecode offset of the PUSH32 argument. + ret.immutableReferences[item.data()].second.emplace_back(ret.bytecode.size()); + // Advance bytecode by 32 bytes (default initialized). + ret.bytecode.resize(ret.bytecode.size() + 32); + }); break; case VerbatimBytecode: ret.bytecode += assembleVerbatimBytecode(item); @@ -1359,35 +1392,59 @@ LinkerObject const& Assembly::assembleLegacy() const { if (i != offsets.size() - 1) { - ret.bytecode.push_back(uint8_t(Instruction::DUP2)); - ret.bytecode.push_back(uint8_t(Instruction::DUP2)); + assembleInstruction([&]() { + ret.bytecode.push_back(uint8_t(Instruction::DUP2)); + }); + assembleInstruction([&]() { + ret.bytecode.push_back(uint8_t(Instruction::DUP2)); + }); } - // TODO: should we make use of the constant optimizer methods for pushing the offsets? - bytes offsetBytes = toCompactBigEndian(u256(offsets[i])); - ret.bytecode.push_back(static_cast(pushInstruction(static_cast(offsetBytes.size())))); - ret.bytecode += offsetBytes; - ret.bytecode.push_back(uint8_t(Instruction::ADD)); - ret.bytecode.push_back(uint8_t(Instruction::MSTORE)); + assembleInstruction([&]() { + // TODO: should we make use of the constant optimizer methods for pushing the offsets? + bytes offsetBytes = toCompactBigEndian(u256(offsets[i])); + ret.bytecode.push_back(static_cast(pushInstruction(static_cast(offsetBytes.size())))); + ret.bytecode += offsetBytes; + }); + assembleInstruction([&]() { + ret.bytecode.push_back(uint8_t(Instruction::ADD)); + }); + assembleInstruction([&]() { + ret.bytecode.push_back(uint8_t(Instruction::MSTORE)); + }); } if (offsets.empty()) { - ret.bytecode.push_back(uint8_t(Instruction::POP)); - ret.bytecode.push_back(uint8_t(Instruction::POP)); + assembleInstruction([&]() { + ret.bytecode.push_back(uint8_t(Instruction::POP)); + }); + assembleInstruction([&]() { + ret.bytecode.push_back(uint8_t(Instruction::POP)); + }); } immutableReferencesBySub.erase(item.data()); break; } case PushDeployTimeAddress: - ret.bytecode += assemblePushDeployTimeAddress(); + assembleInstruction([&]() { + ret.bytecode += assemblePushDeployTimeAddress(); + }); break; case Tag: - ret.bytecode += assembleTag(item, ret.bytecode.size(), true); + assembleInstruction([&](){ + ret.bytecode += assembleTag(item, ret.bytecode.size(), true); + }); break; default: solAssert(false, "Unexpected opcode while assembling."); } + + ++assemblyItemIndex; } + codeSectionLocation.end = ret.bytecode.size(); + + ret.codeSectionLocations.emplace_back(std::move(codeSectionLocation)); + if (!immutableReferencesBySub.empty()) throw langutil::Error( diff --git a/libevmasm/CMakeLists.txt b/libevmasm/CMakeLists.txt index c1918540e625..a7441b85e264 100644 --- a/libevmasm/CMakeLists.txt +++ b/libevmasm/CMakeLists.txt @@ -4,6 +4,8 @@ set(sources Assembly.h AssemblyItem.cpp AssemblyItem.h + Ethdebug.cpp + Ethdebug.h EVMAssemblyStack.cpp EVMAssemblyStack.h BlockDeduplicator.cpp diff --git a/libevmasm/Ethdebug.cpp b/libevmasm/Ethdebug.cpp new file mode 100644 index 000000000000..7b5de2ba9b59 --- /dev/null +++ b/libevmasm/Ethdebug.cpp @@ -0,0 +1,115 @@ +/* + 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 + +using namespace solidity; +using namespace solidity::evmasm; +using namespace solidity::evmasm::ethdebug; + +namespace +{ + +Json programInstructions(Assembly const* _assembly, LinkerObject const& _linkerObject, unsigned _sourceId) +{ + // e.g. interfaces don't have a valid assembly object. + if (_assembly) + { + solUnimplementedAssert(_assembly->eofVersion() == std::nullopt, "ethdebug does not yet support EOF."); + solUnimplementedAssert(_assembly->codeSections().size() == 1, "ethdebug does not yet support multiple code-sections."); + for (auto const& instruction: _assembly->codeSections()[0].items) + solUnimplementedAssert(instruction.type() != VerbatimBytecode, "Verbatim bytecode is currently not supported by ethdebug."); + } + + solAssert(_linkerObject.codeSectionLocations.size() == 1); + solAssert(_linkerObject.codeSectionLocations[0].end <= _linkerObject.bytecode.size()); + Json instructions = Json::array(); + for (size_t i = 0; i < _linkerObject.codeSectionLocations[0].instructionLocations.size(); ++i) + { + solAssert(_assembly); + LinkerObject::InstructionLocation currentInstruction = _linkerObject.codeSectionLocations[0].instructionLocations[i]; + size_t start = currentInstruction.start; + size_t end = currentInstruction.end; + size_t assemblyItemIndex = currentInstruction.assemblyItemIndex; + solAssert(end <= _linkerObject.bytecode.size()); + solAssert(start < end); + solAssert(assemblyItemIndex < _assembly->codeSections().at(0).items.size()); + Json operation = Json::object(); + operation["mnemonic"] = instructionInfo(static_cast(_linkerObject.bytecode[start]), _assembly->evmVersion()).name; + static size_t constexpr instructionSize = 1; + if (start + instructionSize < end) + { + bytes const argumentData( + _linkerObject.bytecode.begin() + static_cast(start) + instructionSize, + _linkerObject.bytecode.begin() + static_cast(end) + ); + solAssert(!argumentData.empty()); + operation["arguments"] = Json::array({util::toHex(argumentData, util::HexPrefix::Add)}); + } + langutil::SourceLocation const& location = _assembly->codeSections().at(0).items.at(assemblyItemIndex).location(); + Json instruction = Json::object(); + instruction["offset"] = start; + instruction["operation"] = operation; + + instruction["context"] = Json::object(); + instruction["context"]["code"] = Json::object(); + instruction["context"]["code"]["source"] = Json::object(); + instruction["context"]["code"]["source"]["id"] = static_cast(_sourceId); + + instruction["context"]["code"]["range"] = Json::object(); + instruction["context"]["code"]["range"]["offset"] = location.start; + instruction["context"]["code"]["range"]["length"] = location.end - location.start; + instructions.emplace_back(instruction); + } + + return instructions; +} + +} // anonymous namespace + +Json ethdebug::program(std::string_view _name, unsigned _sourceId, Assembly const* _assembly, LinkerObject const& _linkerObject) +{ + Json result = Json::object(); + result["contract"] = Json::object(); + result["contract"]["name"] = _name; + result["contract"]["definition"] = Json::object(); + result["contract"]["definition"]["source"] = Json::object(); + result["contract"]["definition"]["source"]["id"] = _sourceId; + result["environment"] = (!_assembly || _assembly->isCreation()) ? "create" : "call"; + result["instructions"] = programInstructions(_assembly, _linkerObject, _sourceId); + return result; +} + +Json ethdebug::resources(std::vector const& _sources, std::string const& _version) +{ + Json sources = Json::array(); + for (size_t id = 0; id < _sources.size(); ++id) + { + Json source = Json::object(); + source["id"] = id; + source["path"] = _sources[id]; + sources.push_back(source); + } + Json result = Json::object(); + result["compilation"] = Json::object(); + result["compilation"]["compiler"] = Json::object(); + result["compilation"]["compiler"]["name"] = "solc"; + result["compilation"]["compiler"]["version"] = _version; + result["compilation"]["sources"] = sources; + return result; +} diff --git a/libevmasm/Ethdebug.h b/libevmasm/Ethdebug.h new file mode 100644 index 000000000000..72ac16037969 --- /dev/null +++ b/libevmasm/Ethdebug.h @@ -0,0 +1,35 @@ +/* + This file is part of solidity. + + solidity is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + solidity is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with solidity. If not, see . +*/ +// SPDX-License-Identifier: GPL-3.0 + +#pragma once + +#include + +#include +#include + +namespace solidity::evmasm::ethdebug +{ + +// returns ethdebug/format/program. +Json program(std::string_view _name, unsigned _sourceId, Assembly const* _assembly, LinkerObject const& _linkerObject); + +// returns ethdebug/format/info/resources +Json resources(std::vector const& _sources, std::string const& _version); + +} // namespace solidity::evmasm::ethdebug diff --git a/libevmasm/LinkerObject.h b/libevmasm/LinkerObject.h index c103a565a069..34e696d4e159 100644 --- a/libevmasm/LinkerObject.h +++ b/libevmasm/LinkerObject.h @@ -46,6 +46,37 @@ struct LinkerObject /// to a list of offsets into the bytecode that refer to their values. std::map immutableReferences; + struct InstructionLocation + { + /// Absolute position of instruction's opcode within the bytecode. + /// The opcode takes up exactly one byte and is assumed to be followed by its immediate arguments. + size_t start{}; + /// Absolute position of the first byte past the end of the instruction, including potential immediate arguments. + size_t end{}; + /// Index of the AssemblyItem that produced the instruction within the Assembly. + /// While items of most types generate a single instruction, in general it can be more than one. + size_t assemblyItemIndex{}; + }; + struct CodeSectionLocation + { + /// Absolute position of the first byte belonging to the code section. + /// Equal to instructionLocations[0].start if the code section is not empty. + size_t start{}; + /// Absolute position of the first byte past end of the code section. + /// Greater or equal to start. Must be equal if instructionLocations is empty. + size_t end{}; + /// Descriptions of all instructions contained within the code section. + /// The instructions are assumed to fill the whole section, without any gaps or duplicates. + /// The areas between opcodes are assumed to contain their immediate arguments, of size appropriate for the opcode type. + /// The arguments of the last instruction extend to the end of the section. + /// The instructions must be ordered according to their positions (ascending). + std::vector instructionLocations; + }; + /// Descriptions of all code sections in the ascending order of their positions. + /// There are no duplicates and the sections never overlap. + /// Only sections belonging to the top-level assembly are included, even if the bytecode contains subassemblies. + std::vector codeSectionLocations; + struct FunctionDebugData { std::optional bytecodeOffset; diff --git a/libsolidity/interface/CompilerStack.cpp b/libsolidity/interface/CompilerStack.cpp index 9582939f5e25..b927776cee59 100644 --- a/libsolidity/interface/CompilerStack.cpp +++ b/libsolidity/interface/CompilerStack.cpp @@ -78,13 +78,14 @@ #include #include - #include #include #include #include #include +#include + #include #include @@ -1196,9 +1197,7 @@ Json CompilerStack::ethdebug() const { solAssert(m_stackState >= AnalysisSuccessful, "Analysis was not successful."); solAssert(!m_contracts.empty()); - Json result = Json::object(); - result["sources"] = sourceNames(); - return result; + return evmasm::ethdebug::resources(sourceNames(), VersionString); } Json CompilerStack::ethdebug(std::string const& _contractName) const @@ -1216,13 +1215,10 @@ Json CompilerStack::ethdebug(Contract const& _contract, bool _runtime) const solAssert(m_stackState >= AnalysisSuccessful, "Analysis was not successful."); solAssert(_contract.contract); solUnimplementedAssert(!isExperimentalSolidity()); - if (_runtime) - { - Json result = Json::object(); - return result; - } - Json result = Json::object(); - return result; + evmasm::LinkerObject const& object = _runtime ? _contract.runtimeObject : _contract.object; + std::shared_ptr const& assembly = _runtime ? _contract.evmRuntimeAssembly : _contract.evmAssembly; + solAssert(sourceIndices().contains(_contract.contract->sourceUnitName())); + return evmasm::ethdebug::program(_contract.contract->name(), sourceIndices()[_contract.contract->sourceUnitName()], assembly.get(), object); } bytes CompilerStack::cborMetadata(std::string const& _contractName, bool _forIR) const diff --git a/libsolidity/interface/StandardCompiler.cpp b/libsolidity/interface/StandardCompiler.cpp index 6bd5cd2317b3..d5502228bda4 100644 --- a/libsolidity/interface/StandardCompiler.cpp +++ b/libsolidity/interface/StandardCompiler.cpp @@ -30,6 +30,7 @@ #include #include +#include #include #include @@ -1680,19 +1681,6 @@ Json StandardCompiler::compileYul(InputsAndSettings _inputsAndSettings) return output; } - for (auto const& fileRequests: _inputsAndSettings.outputSelection) - for (auto const& requests: fileRequests) - for (auto const& request: requests) - if (request == "evm.deployedBytecode.ethdebug") - { - output["errors"].emplace_back(formatError( - Error::Type::JSONError, - "general", - "\"evm.deployedBytecode.ethdebug\" cannot be used for Yul." - )); - return output; - } - YulStack stack( _inputsAndSettings.evmVersion, _inputsAndSettings.eofVersion, @@ -1799,7 +1787,7 @@ Json StandardCompiler::compileYul(InputsAndSettings _inputsAndSettings) output["contracts"][sourceName][contractName]["yulCFGJson"] = stack.cfgJson(); if (isEthdebugRequested(_inputsAndSettings.outputSelection)) - output["ethdebug"] = stack.ethdebug(); + output["ethdebug"] = evmasm::ethdebug::resources({sourceName}, VersionString); return output; } diff --git a/libyul/YulStack.cpp b/libyul/YulStack.cpp index 1ad24998ffb5..5adb8d6d5c9a 100644 --- a/libyul/YulStack.cpp +++ b/libyul/YulStack.cpp @@ -30,6 +30,7 @@ #include #include #include +#include #include #include @@ -273,12 +274,15 @@ YulStack::assembleWithDeployed(std::optional _deployName) {{m_charStream->name(), 0}} ); } - creationObject.ethdebug["not yet implemented @ MachineAssemblyObject::ethdebug"] = true; + if (debugInfoSelection().ethdebug) + creationObject.ethdebug = evmasm::ethdebug::program(creationObject.assembly->name(), 0, creationObject.assembly.get(), *creationObject.bytecode.get()); if (deployedAssembly) { deployedObject.bytecode = std::make_shared(deployedAssembly->assemble()); deployedObject.assembly = deployedAssembly; + if (debugInfoSelection().ethdebug) + deployedObject.ethdebug = evmasm::ethdebug::program(deployedObject.assembly->name(), 0, deployedObject.assembly.get(), *deployedObject.bytecode.get()); solAssert(deployedAssembly->codeSections().size() == 1); deployedObject.sourceMappings = std::make_unique( evmasm::AssemblyItem::computeSourceMapping( @@ -383,17 +387,6 @@ Json YulStack::astJson() const return m_parserResult->toJson(); } -Json YulStack::ethdebug() const -{ - yulAssert(m_parserResult, ""); - yulAssert(m_parserResult->hasCode(), ""); - yulAssert(m_parserResult->analysisInfo, ""); - - Json result = Json::object(); - result["sources"] = Json::array({m_charStream->name()}); - return result; -} - Json YulStack::cfgJson() const { yulAssert(m_parserResult, ""); diff --git a/libyul/YulStack.h b/libyul/YulStack.h index b745f1b80538..e9d75b6ae9d9 100644 --- a/libyul/YulStack.h +++ b/libyul/YulStack.h @@ -149,9 +149,6 @@ class YulStack: public langutil::CharStreamProvider // return the JSON representation of the YuL CFG (experimental) Json cfgJson() const; - /// @returns a JSON representing the top-level ethdebug data (types, etc.). - Json ethdebug() const; - /// Return the parsed and analyzed object. std::shared_ptr parserResult() const; diff --git a/solc/CommandLineInterface.cpp b/solc/CommandLineInterface.cpp index e57cd77a98a2..4a7f34561fbe 100644 --- a/solc/CommandLineInterface.cpp +++ b/solc/CommandLineInterface.cpp @@ -43,6 +43,7 @@ #include +#include #include #include @@ -1347,26 +1348,25 @@ void CommandLineInterface::assembleYul(yul::YulStack::Language _language, yul::Y solThrow(CommandLineExecutionError, ""); } - if (m_options.compiler.outputs.ethdebug) - { - Json ethdebugObject = Json::object(); - ethdebugObject["sources"] = m_fileReader.sourceUnits() | ranges::views::keys; - sout() << "======= Debug Data (ethdebug/format/info/resources) =======" << std::endl; - sout() << util::jsonPrint( - ethdebugObject, - m_options.formatting.json - ) << std::endl; - } - for (auto const& [sourceUnitName, yulSource]: m_fileReader.sourceUnits()) { solAssert(_targetMachine == yul::YulStack::Machine::EVM); - std::string machine = "EVM"; - sout() << std::endl << "======= " << sourceUnitName << " (" << machine << ") =======" << std::endl; yul::YulStack const& stack = yulStacks[sourceUnitName]; yul::MachineAssemblyObject const& object = objects[sourceUnitName]; + if (m_options.compiler.outputs.ethdebug) + { + sout() << "======= Debug Data (ethdebug/format/info/resources) =======" << std::endl; + sout() << util::jsonPrint( + evmasm::ethdebug::resources({{sourceUnitName}}, VersionString), + m_options.formatting.json + ) << std::endl; + } + + std::string machine = "EVM"; + sout() << std::endl << "======= " << sourceUnitName << " (" << machine << ") =======" << std::endl; + if (m_options.compiler.outputs.irOptimized) { // NOTE: This actually outputs unoptimized code when the optimizer is disabled but diff --git a/test/cmdlineTests.sh b/test/cmdlineTests.sh index 3c781ea78f07..f68ed53dc066 100755 --- a/test/cmdlineTests.sh +++ b/test/cmdlineTests.sh @@ -220,6 +220,27 @@ json = re.sub(r"\n\s*\n", "\n", json) json = re.sub(r"},(\n{0,1})\n*(\s*(]|}))", r"}\1\2", json) # Remove trailing comma open("$stdout_path", "w").write(json) EOF + # Only do this to files that actually contain ethdebug output, because jq will reformat + # the whole file and its formatting differs from `solc --pretty-json` + if jq 'has("ethdebug")' "$stdout_path" --exit-status > /dev/null; then + local temporary_file + temporary_file=$(mktemp -t cmdline-ethdebug-XXXXXX.tmp) + if [[ -e ${tdir}/strip-ethdebug ]]; then + jq --indent 4 ' + (. | .. | objects | select(has("ethdebug"))) |= (.ethdebug = "") + ' "$stdout_path" > "$temporary_file" + else + jq --indent 4 ' + if .ethdebug.compilation.compiler.version? != null then + .ethdebug.compilation.compiler.version = "" + else + . + end + ' "$stdout_path" > "$temporary_file" + fi + mv "$temporary_file" "$stdout_path" + fi + sed -i.bak -E -e 's/ Consider adding \\"pragma solidity \^[0-9.]*;\\"//g' "$stdout_path" sed -i.bak -E -e 's/\"opcodes\":[[:space:]]*\"[^"]+\"/\"opcodes\":\"\"/g' "$stdout_path" sed -i.bak -E -e 's/\"sourceMap\":[[:space:]]*\"[0-9:;-]+\"/\"sourceMap\":\"\"/g' "$stdout_path" diff --git a/test/cmdlineTests/debug_info_ethdebug_compatible/args b/test/cmdlineTests/debug_info_ethdebug_compatible/args deleted file mode 100644 index 74342f38f1cc..000000000000 --- a/test/cmdlineTests/debug_info_ethdebug_compatible/args +++ /dev/null @@ -1 +0,0 @@ ---debug-info ethdebug --via-ir --ir --ir-optimized --ethdebug --ethdebug-runtime diff --git a/test/cmdlineTests/debug_info_ethdebug_compatible/input.sol b/test/cmdlineTests/debug_info_ethdebug_compatible/input.sol deleted file mode 100644 index 25b9640ca565..000000000000 --- a/test/cmdlineTests/debug_info_ethdebug_compatible/input.sol +++ /dev/null @@ -1,7 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -pragma solidity >=0.0; - -contract C { - function f() public {} -} - diff --git a/test/cmdlineTests/debug_info_ethdebug_compatible/output b/test/cmdlineTests/debug_info_ethdebug_compatible/output deleted file mode 100644 index 0f9581e7f7f2..000000000000 --- a/test/cmdlineTests/debug_info_ethdebug_compatible/output +++ /dev/null @@ -1,193 +0,0 @@ -======= Debug Data (ethdebug/format/info/resources) ======= -{"sources":["debug_info_ethdebug_compatible/input.sol"]} - -======= debug_info_ethdebug_compatible/input.sol:C ======= -IR: -/// ethdebug: enabled -/// @use-src 0:"debug_info_ethdebug_compatible/input.sol" -object "C_6" { - code { - /// @src 0:60:101 - mstore(64, memoryguard(128)) - if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } - - constructor_C_6() - - let _1 := allocate_unbounded() - codecopy(_1, dataoffset("C_6_deployed"), datasize("C_6_deployed")) - - return(_1, datasize("C_6_deployed")) - - function allocate_unbounded() -> memPtr { - memPtr := mload(64) - } - - function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() { - revert(0, 0) - } - - /// @src 0:60:101 - function constructor_C_6() { - - /// @src 0:60:101 - - } - /// @src 0:60:101 - - } - /// @use-src 0:"debug_info_ethdebug_compatible/input.sol" - object "C_6_deployed" { - code { - /// @src 0:60:101 - mstore(64, memoryguard(128)) - - if iszero(lt(calldatasize(), 4)) - { - let selector := shift_right_224_unsigned(calldataload(0)) - switch selector - - case 0x26121ff0 - { - // f() - - external_fun_f_5() - } - - default {} - } - - revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() - - function shift_right_224_unsigned(value) -> newValue { - newValue := - - shr(224, value) - - } - - function allocate_unbounded() -> memPtr { - memPtr := mload(64) - } - - function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() { - revert(0, 0) - } - - function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() { - revert(0, 0) - } - - function abi_decode_tuple_(headStart, dataEnd) { - if slt(sub(dataEnd, headStart), 0) { revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() } - - } - - function abi_encode_tuple__to__fromStack(headStart ) -> tail { - tail := add(headStart, 0) - - } - - function external_fun_f_5() { - - if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } - abi_decode_tuple_(4, calldatasize()) - fun_f_5() - let memPos := allocate_unbounded() - let memEnd := abi_encode_tuple__to__fromStack(memPos ) - return(memPos, sub(memEnd, memPos)) - - } - - function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() { - revert(0, 0) - } - - /// @src 0:77:99 - function fun_f_5() { - - } - /// @src 0:60:101 - - } - - data ".metadata" hex"" - } - -} - - -Optimized IR: -/// ethdebug: enabled -/// @use-src 0:"debug_info_ethdebug_compatible/input.sol" -object "C_6" { - code { - { - /// @src 0:60:101 - mstore(64, memoryguard(0x80)) - if callvalue() - { - revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() - } - let _1 := allocate_unbounded() - codecopy(_1, dataoffset("C_6_deployed"), datasize("C_6_deployed")) - return(_1, datasize("C_6_deployed")) - } - function allocate_unbounded() -> memPtr - { memPtr := mload(64) } - function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() - { revert(0, 0) } - } - /// @use-src 0:"debug_info_ethdebug_compatible/input.sol" - object "C_6_deployed" { - code { - { - /// @src 0:60:101 - mstore(64, memoryguard(0x80)) - if iszero(lt(calldatasize(), 4)) - { - let selector := shift_right_unsigned(calldataload(0)) - switch selector - case 0x26121ff0 { external_fun_f() } - default { } - } - revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() - } - function shift_right_unsigned(value) -> newValue - { newValue := shr(224, value) } - function allocate_unbounded() -> memPtr - { memPtr := mload(64) } - function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() - { revert(0, 0) } - function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() - { revert(0, 0) } - function abi_decode(headStart, dataEnd) - { - if slt(sub(dataEnd, headStart), 0) - { - revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() - } - } - function abi_encode_tuple(headStart) -> tail - { tail := add(headStart, 0) } - function external_fun_f() - { - if callvalue() - { - revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() - } - abi_decode(4, calldatasize()) - let memPos := allocate_unbounded() - let memEnd := abi_encode_tuple(memPos) - return(memPos, sub(memEnd, memPos)) - } - function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() - { revert(0, 0) } - } - data ".metadata" hex"" - } -} - -Debug Data (ethdebug/format/program): -{} -Debug Data of the runtime part (ethdebug/format/program): -{} diff --git a/test/cmdlineTests/debug_info_ethdebug_incompatible/args b/test/cmdlineTests/debug_info_ethdebug_incompatible/args deleted file mode 100644 index 8afe2c9b3a61..000000000000 --- a/test/cmdlineTests/debug_info_ethdebug_incompatible/args +++ /dev/null @@ -1 +0,0 @@ ---debug-info ethdebug --via-ir --asm diff --git a/test/cmdlineTests/debug_info_ethdebug_incompatible/err b/test/cmdlineTests/debug_info_ethdebug_incompatible/err deleted file mode 100644 index 32401186d0d7..000000000000 --- a/test/cmdlineTests/debug_info_ethdebug_incompatible/err +++ /dev/null @@ -1 +0,0 @@ -Error: --debug-info ethdebug can only be used with --ir / --ir-optimized and/or --ethdebug / --ethdebug-runtime. Optimization (using --optimize) is not yet supported with ethdebug. diff --git a/test/cmdlineTests/ethdebug_and_ethdebug_runtime_ir/args b/test/cmdlineTests/ethdebug_and_ethdebug_runtime_ir/args deleted file mode 100644 index 18053bcdac95..000000000000 --- a/test/cmdlineTests/ethdebug_and_ethdebug_runtime_ir/args +++ /dev/null @@ -1 +0,0 @@ ---ethdebug-runtime --ethdebug --via-ir --ir \ No newline at end of file diff --git a/test/cmdlineTests/ethdebug_and_ethdebug_runtime_ir/input.sol b/test/cmdlineTests/ethdebug_and_ethdebug_runtime_ir/input.sol deleted file mode 100644 index 25b9640ca565..000000000000 --- a/test/cmdlineTests/ethdebug_and_ethdebug_runtime_ir/input.sol +++ /dev/null @@ -1,7 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -pragma solidity >=0.0; - -contract C { - function f() public {} -} - diff --git a/test/cmdlineTests/ethdebug_and_ethdebug_runtime_ir/output b/test/cmdlineTests/ethdebug_and_ethdebug_runtime_ir/output deleted file mode 100644 index 38dab05afaba..000000000000 --- a/test/cmdlineTests/ethdebug_and_ethdebug_runtime_ir/output +++ /dev/null @@ -1,123 +0,0 @@ -======= Debug Data (ethdebug/format/info/resources) ======= -{"sources":["ethdebug_and_ethdebug_runtime_ir/input.sol"]} - -======= ethdebug_and_ethdebug_runtime_ir/input.sol:C ======= -IR: -/// ethdebug: enabled -/// @use-src 0:"ethdebug_and_ethdebug_runtime_ir/input.sol" -object "C_6" { - code { - /// @src 0:60:101 "contract C {..." - mstore(64, memoryguard(128)) - if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } - - constructor_C_6() - - let _1 := allocate_unbounded() - codecopy(_1, dataoffset("C_6_deployed"), datasize("C_6_deployed")) - - return(_1, datasize("C_6_deployed")) - - function allocate_unbounded() -> memPtr { - memPtr := mload(64) - } - - function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() { - revert(0, 0) - } - - /// @src 0:60:101 "contract C {..." - function constructor_C_6() { - - /// @src 0:60:101 "contract C {..." - - } - /// @src 0:60:101 "contract C {..." - - } - /// @use-src 0:"ethdebug_and_ethdebug_runtime_ir/input.sol" - object "C_6_deployed" { - code { - /// @src 0:60:101 "contract C {..." - mstore(64, memoryguard(128)) - - if iszero(lt(calldatasize(), 4)) - { - let selector := shift_right_224_unsigned(calldataload(0)) - switch selector - - case 0x26121ff0 - { - // f() - - external_fun_f_5() - } - - default {} - } - - revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() - - function shift_right_224_unsigned(value) -> newValue { - newValue := - - shr(224, value) - - } - - function allocate_unbounded() -> memPtr { - memPtr := mload(64) - } - - function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() { - revert(0, 0) - } - - function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() { - revert(0, 0) - } - - function abi_decode_tuple_(headStart, dataEnd) { - if slt(sub(dataEnd, headStart), 0) { revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() } - - } - - function abi_encode_tuple__to__fromStack(headStart ) -> tail { - tail := add(headStart, 0) - - } - - function external_fun_f_5() { - - if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } - abi_decode_tuple_(4, calldatasize()) - fun_f_5() - let memPos := allocate_unbounded() - let memEnd := abi_encode_tuple__to__fromStack(memPos ) - return(memPos, sub(memEnd, memPos)) - - } - - function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() { - revert(0, 0) - } - - /// @ast-id 5 - /// @src 0:77:99 "function f() public {}" - function fun_f_5() { - - } - /// @src 0:60:101 "contract C {..." - - } - - data ".metadata" hex"" - } - -} - - -Debug Data (ethdebug/format/program): -{} -Debug Data of the runtime part (ethdebug/format/program): -{} diff --git a/test/cmdlineTests/ethdebug_and_ethdebug_runtime_iroptimized/args b/test/cmdlineTests/ethdebug_and_ethdebug_runtime_iroptimized/args deleted file mode 100644 index 09535998b5be..000000000000 --- a/test/cmdlineTests/ethdebug_and_ethdebug_runtime_iroptimized/args +++ /dev/null @@ -1 +0,0 @@ ---ethdebug-runtime --ethdebug --via-ir --ir-optimized \ No newline at end of file diff --git a/test/cmdlineTests/ethdebug_and_ethdebug_runtime_iroptimized/input.sol b/test/cmdlineTests/ethdebug_and_ethdebug_runtime_iroptimized/input.sol deleted file mode 100644 index 25b9640ca565..000000000000 --- a/test/cmdlineTests/ethdebug_and_ethdebug_runtime_iroptimized/input.sol +++ /dev/null @@ -1,7 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -pragma solidity >=0.0; - -contract C { - function f() public {} -} - diff --git a/test/cmdlineTests/ethdebug_and_ethdebug_runtime_iroptimized/output b/test/cmdlineTests/ethdebug_and_ethdebug_runtime_iroptimized/output deleted file mode 100644 index 19a3c9e86b90..000000000000 --- a/test/cmdlineTests/ethdebug_and_ethdebug_runtime_iroptimized/output +++ /dev/null @@ -1,79 +0,0 @@ -======= Debug Data (ethdebug/format/info/resources) ======= -{"sources":["ethdebug_and_ethdebug_runtime_iroptimized/input.sol"]} - -======= ethdebug_and_ethdebug_runtime_iroptimized/input.sol:C ======= -Optimized IR: -/// ethdebug: enabled -/// @use-src 0:"ethdebug_and_ethdebug_runtime_iroptimized/input.sol" -object "C_6" { - code { - { - /// @src 0:60:101 "contract C {..." - mstore(64, memoryguard(0x80)) - if callvalue() - { - revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() - } - let _1 := allocate_unbounded() - codecopy(_1, dataoffset("C_6_deployed"), datasize("C_6_deployed")) - return(_1, datasize("C_6_deployed")) - } - function allocate_unbounded() -> memPtr - { memPtr := mload(64) } - function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() - { revert(0, 0) } - } - /// @use-src 0:"ethdebug_and_ethdebug_runtime_iroptimized/input.sol" - object "C_6_deployed" { - code { - { - /// @src 0:60:101 "contract C {..." - mstore(64, memoryguard(0x80)) - if iszero(lt(calldatasize(), 4)) - { - let selector := shift_right_unsigned(calldataload(0)) - switch selector - case 0x26121ff0 { external_fun_f() } - default { } - } - revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() - } - function shift_right_unsigned(value) -> newValue - { newValue := shr(224, value) } - function allocate_unbounded() -> memPtr - { memPtr := mload(64) } - function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() - { revert(0, 0) } - function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() - { revert(0, 0) } - function abi_decode(headStart, dataEnd) - { - if slt(sub(dataEnd, headStart), 0) - { - revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() - } - } - function abi_encode_tuple(headStart) -> tail - { tail := add(headStart, 0) } - function external_fun_f() - { - if callvalue() - { - revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() - } - abi_decode(4, calldatasize()) - let memPos := allocate_unbounded() - let memEnd := abi_encode_tuple(memPos) - return(memPos, sub(memEnd, memPos)) - } - function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() - { revert(0, 0) } - } - data ".metadata" hex"" - } -} - -Debug Data (ethdebug/format/program): -{} -Debug Data of the runtime part (ethdebug/format/program): -{} diff --git a/test/cmdlineTests/ethdebug_enabled_optimization_ir/args b/test/cmdlineTests/ethdebug_enabled_optimization_ir/args deleted file mode 100644 index 38ce714e1b86..000000000000 --- a/test/cmdlineTests/ethdebug_enabled_optimization_ir/args +++ /dev/null @@ -1 +0,0 @@ ---ethdebug --via-ir --optimize --ir \ No newline at end of file diff --git a/test/cmdlineTests/ethdebug_enabled_optimization_ir/err b/test/cmdlineTests/ethdebug_enabled_optimization_ir/err deleted file mode 100644 index b2c26e5d8a50..000000000000 --- a/test/cmdlineTests/ethdebug_enabled_optimization_ir/err +++ /dev/null @@ -1 +0,0 @@ -Error: --ethdebug / --ethdebug-runtime output can only be used with --ir / --ir-optimized. Optimization (using --optimize) is not yet supported with ethdebug. diff --git a/test/cmdlineTests/ethdebug_enabled_optimization_ir/exit b/test/cmdlineTests/ethdebug_enabled_optimization_ir/exit deleted file mode 100644 index d00491fd7e5b..000000000000 --- a/test/cmdlineTests/ethdebug_enabled_optimization_ir/exit +++ /dev/null @@ -1 +0,0 @@ -1 diff --git a/test/cmdlineTests/ethdebug_enabled_optimization_ir/input.sol b/test/cmdlineTests/ethdebug_enabled_optimization_ir/input.sol deleted file mode 100644 index 25b9640ca565..000000000000 --- a/test/cmdlineTests/ethdebug_enabled_optimization_ir/input.sol +++ /dev/null @@ -1,7 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -pragma solidity >=0.0; - -contract C { - function f() public {} -} - diff --git a/test/cmdlineTests/ethdebug_enabled_optimization_iroptimized/args b/test/cmdlineTests/ethdebug_enabled_optimization_iroptimized/args deleted file mode 100644 index 6edc3b560136..000000000000 --- a/test/cmdlineTests/ethdebug_enabled_optimization_iroptimized/args +++ /dev/null @@ -1 +0,0 @@ ---ethdebug --via-ir --optimize --ir-optimized \ No newline at end of file diff --git a/test/cmdlineTests/ethdebug_enabled_optimization_iroptimized/err b/test/cmdlineTests/ethdebug_enabled_optimization_iroptimized/err deleted file mode 100644 index b2c26e5d8a50..000000000000 --- a/test/cmdlineTests/ethdebug_enabled_optimization_iroptimized/err +++ /dev/null @@ -1 +0,0 @@ -Error: --ethdebug / --ethdebug-runtime output can only be used with --ir / --ir-optimized. Optimization (using --optimize) is not yet supported with ethdebug. diff --git a/test/cmdlineTests/ethdebug_enabled_optimization_iroptimized/exit b/test/cmdlineTests/ethdebug_enabled_optimization_iroptimized/exit deleted file mode 100644 index d00491fd7e5b..000000000000 --- a/test/cmdlineTests/ethdebug_enabled_optimization_iroptimized/exit +++ /dev/null @@ -1 +0,0 @@ -1 diff --git a/test/cmdlineTests/ethdebug_enabled_optimization_iroptimized/input.sol b/test/cmdlineTests/ethdebug_enabled_optimization_iroptimized/input.sol deleted file mode 100644 index 25b9640ca565..000000000000 --- a/test/cmdlineTests/ethdebug_enabled_optimization_iroptimized/input.sol +++ /dev/null @@ -1,7 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -pragma solidity >=0.0; - -contract C { - function f() public {} -} - diff --git a/test/cmdlineTests/ethdebug_eof_container_osaka/args b/test/cmdlineTests/ethdebug_eof_container_osaka/args new file mode 100644 index 000000000000..65974c6287da --- /dev/null +++ b/test/cmdlineTests/ethdebug_eof_container_osaka/args @@ -0,0 +1 @@ + --experimental-eof-version 1 --evm-version osaka --ethdebug --via-ir diff --git a/test/cmdlineTests/ethdebug_eof_container_osaka/err b/test/cmdlineTests/ethdebug_eof_container_osaka/err new file mode 100644 index 000000000000..7714685971d2 --- /dev/null +++ b/test/cmdlineTests/ethdebug_eof_container_osaka/err @@ -0,0 +1 @@ +Error: ethdebug does not yet support EOF. diff --git a/test/cmdlineTests/debug_info_ethdebug_incompatible/exit b/test/cmdlineTests/ethdebug_eof_container_osaka/exit similarity index 100% rename from test/cmdlineTests/debug_info_ethdebug_incompatible/exit rename to test/cmdlineTests/ethdebug_eof_container_osaka/exit diff --git a/test/cmdlineTests/debug_info_ethdebug_incompatible/input.sol b/test/cmdlineTests/ethdebug_eof_container_osaka/input.sol similarity index 99% rename from test/cmdlineTests/debug_info_ethdebug_incompatible/input.sol rename to test/cmdlineTests/ethdebug_eof_container_osaka/input.sol index 25b9640ca565..415509ef9aef 100644 --- a/test/cmdlineTests/debug_info_ethdebug_incompatible/input.sol +++ b/test/cmdlineTests/ethdebug_eof_container_osaka/input.sol @@ -4,4 +4,3 @@ pragma solidity >=0.0; contract C { function f() public {} } - diff --git a/test/cmdlineTests/ethdebug_eof_container_osaka/output b/test/cmdlineTests/ethdebug_eof_container_osaka/output new file mode 100644 index 000000000000..9d002fadc317 --- /dev/null +++ b/test/cmdlineTests/ethdebug_eof_container_osaka/output @@ -0,0 +1,4 @@ +======= Debug Data (ethdebug/format/info/resources) ======= +{"compilation":{"compiler":{"name":"solc","version": ""},"sources":[{"id":0,"path":"ethdebug_eof_container_osaka/input.sol"}]}} + +======= ethdebug_eof_container_osaka/input.sol:C ======= diff --git a/test/cmdlineTests/ethdebug_ir/args b/test/cmdlineTests/ethdebug_ir/args deleted file mode 100644 index ac83894b301f..000000000000 --- a/test/cmdlineTests/ethdebug_ir/args +++ /dev/null @@ -1 +0,0 @@ ---ethdebug --via-ir --ir \ No newline at end of file diff --git a/test/cmdlineTests/ethdebug_ir/input.sol b/test/cmdlineTests/ethdebug_ir/input.sol deleted file mode 100644 index 25b9640ca565..000000000000 --- a/test/cmdlineTests/ethdebug_ir/input.sol +++ /dev/null @@ -1,7 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -pragma solidity >=0.0; - -contract C { - function f() public {} -} - diff --git a/test/cmdlineTests/ethdebug_ir/output b/test/cmdlineTests/ethdebug_ir/output deleted file mode 100644 index 6713431b680e..000000000000 --- a/test/cmdlineTests/ethdebug_ir/output +++ /dev/null @@ -1,121 +0,0 @@ -======= Debug Data (ethdebug/format/info/resources) ======= -{"sources":["ethdebug_ir/input.sol"]} - -======= ethdebug_ir/input.sol:C ======= -IR: -/// ethdebug: enabled -/// @use-src 0:"ethdebug_ir/input.sol" -object "C_6" { - code { - /// @src 0:60:101 "contract C {..." - mstore(64, memoryguard(128)) - if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } - - constructor_C_6() - - let _1 := allocate_unbounded() - codecopy(_1, dataoffset("C_6_deployed"), datasize("C_6_deployed")) - - return(_1, datasize("C_6_deployed")) - - function allocate_unbounded() -> memPtr { - memPtr := mload(64) - } - - function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() { - revert(0, 0) - } - - /// @src 0:60:101 "contract C {..." - function constructor_C_6() { - - /// @src 0:60:101 "contract C {..." - - } - /// @src 0:60:101 "contract C {..." - - } - /// @use-src 0:"ethdebug_ir/input.sol" - object "C_6_deployed" { - code { - /// @src 0:60:101 "contract C {..." - mstore(64, memoryguard(128)) - - if iszero(lt(calldatasize(), 4)) - { - let selector := shift_right_224_unsigned(calldataload(0)) - switch selector - - case 0x26121ff0 - { - // f() - - external_fun_f_5() - } - - default {} - } - - revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() - - function shift_right_224_unsigned(value) -> newValue { - newValue := - - shr(224, value) - - } - - function allocate_unbounded() -> memPtr { - memPtr := mload(64) - } - - function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() { - revert(0, 0) - } - - function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() { - revert(0, 0) - } - - function abi_decode_tuple_(headStart, dataEnd) { - if slt(sub(dataEnd, headStart), 0) { revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() } - - } - - function abi_encode_tuple__to__fromStack(headStart ) -> tail { - tail := add(headStart, 0) - - } - - function external_fun_f_5() { - - if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } - abi_decode_tuple_(4, calldatasize()) - fun_f_5() - let memPos := allocate_unbounded() - let memEnd := abi_encode_tuple__to__fromStack(memPos ) - return(memPos, sub(memEnd, memPos)) - - } - - function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() { - revert(0, 0) - } - - /// @ast-id 5 - /// @src 0:77:99 "function f() public {}" - function fun_f_5() { - - } - /// @src 0:60:101 "contract C {..." - - } - - data ".metadata" hex"" - } - -} - - -Debug Data (ethdebug/format/program): -{} diff --git a/test/cmdlineTests/ethdebug_iroptimized/args b/test/cmdlineTests/ethdebug_iroptimized/args deleted file mode 100644 index e048da7bbb2f..000000000000 --- a/test/cmdlineTests/ethdebug_iroptimized/args +++ /dev/null @@ -1 +0,0 @@ ---ethdebug --via-ir --ir-optimized \ No newline at end of file diff --git a/test/cmdlineTests/ethdebug_iroptimized/input.sol b/test/cmdlineTests/ethdebug_iroptimized/input.sol deleted file mode 100644 index 25b9640ca565..000000000000 --- a/test/cmdlineTests/ethdebug_iroptimized/input.sol +++ /dev/null @@ -1,7 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -pragma solidity >=0.0; - -contract C { - function f() public {} -} - diff --git a/test/cmdlineTests/ethdebug_iroptimized/output b/test/cmdlineTests/ethdebug_iroptimized/output deleted file mode 100644 index 59e2579eb65a..000000000000 --- a/test/cmdlineTests/ethdebug_iroptimized/output +++ /dev/null @@ -1,77 +0,0 @@ -======= Debug Data (ethdebug/format/info/resources) ======= -{"sources":["ethdebug_iroptimized/input.sol"]} - -======= ethdebug_iroptimized/input.sol:C ======= -Optimized IR: -/// ethdebug: enabled -/// @use-src 0:"ethdebug_iroptimized/input.sol" -object "C_6" { - code { - { - /// @src 0:60:101 "contract C {..." - mstore(64, memoryguard(0x80)) - if callvalue() - { - revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() - } - let _1 := allocate_unbounded() - codecopy(_1, dataoffset("C_6_deployed"), datasize("C_6_deployed")) - return(_1, datasize("C_6_deployed")) - } - function allocate_unbounded() -> memPtr - { memPtr := mload(64) } - function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() - { revert(0, 0) } - } - /// @use-src 0:"ethdebug_iroptimized/input.sol" - object "C_6_deployed" { - code { - { - /// @src 0:60:101 "contract C {..." - mstore(64, memoryguard(0x80)) - if iszero(lt(calldatasize(), 4)) - { - let selector := shift_right_unsigned(calldataload(0)) - switch selector - case 0x26121ff0 { external_fun_f() } - default { } - } - revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() - } - function shift_right_unsigned(value) -> newValue - { newValue := shr(224, value) } - function allocate_unbounded() -> memPtr - { memPtr := mload(64) } - function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() - { revert(0, 0) } - function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() - { revert(0, 0) } - function abi_decode(headStart, dataEnd) - { - if slt(sub(dataEnd, headStart), 0) - { - revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() - } - } - function abi_encode_tuple(headStart) -> tail - { tail := add(headStart, 0) } - function external_fun_f() - { - if callvalue() - { - revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() - } - abi_decode(4, calldatasize()) - let memPos := allocate_unbounded() - let memEnd := abi_encode_tuple(memPos) - return(memPos, sub(memEnd, memPos)) - } - function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() - { revert(0, 0) } - } - data ".metadata" hex"" - } -} - -Debug Data (ethdebug/format/program): -{} diff --git a/test/cmdlineTests/ethdebug_no_via_ir/args b/test/cmdlineTests/ethdebug_no_via_ir/args deleted file mode 100644 index 6a019364e6b3..000000000000 --- a/test/cmdlineTests/ethdebug_no_via_ir/args +++ /dev/null @@ -1 +0,0 @@ ---ethdebug --ir --ir-optimized \ No newline at end of file diff --git a/test/cmdlineTests/ethdebug_no_via_ir/err b/test/cmdlineTests/ethdebug_no_via_ir/err deleted file mode 100644 index 2729b6d5d830..000000000000 --- a/test/cmdlineTests/ethdebug_no_via_ir/err +++ /dev/null @@ -1 +0,0 @@ -Error: --ethdebug / --ethdebug-runtime output can only be selected, if --via-ir was specified. diff --git a/test/cmdlineTests/ethdebug_no_via_ir/exit b/test/cmdlineTests/ethdebug_no_via_ir/exit deleted file mode 100644 index d00491fd7e5b..000000000000 --- a/test/cmdlineTests/ethdebug_no_via_ir/exit +++ /dev/null @@ -1 +0,0 @@ -1 diff --git a/test/cmdlineTests/ethdebug_no_via_ir/input.sol b/test/cmdlineTests/ethdebug_no_via_ir/input.sol deleted file mode 100644 index 25b9640ca565..000000000000 --- a/test/cmdlineTests/ethdebug_no_via_ir/input.sol +++ /dev/null @@ -1,7 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -pragma solidity >=0.0; - -contract C { - function f() public {} -} - diff --git a/test/cmdlineTests/ethdebug_runtime_ir/args b/test/cmdlineTests/ethdebug_runtime_ir/args deleted file mode 100644 index a2193034c8db..000000000000 --- a/test/cmdlineTests/ethdebug_runtime_ir/args +++ /dev/null @@ -1 +0,0 @@ ---ethdebug-runtime --via-ir --ir \ No newline at end of file diff --git a/test/cmdlineTests/ethdebug_runtime_ir/input.sol b/test/cmdlineTests/ethdebug_runtime_ir/input.sol deleted file mode 100644 index 25b9640ca565..000000000000 --- a/test/cmdlineTests/ethdebug_runtime_ir/input.sol +++ /dev/null @@ -1,7 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -pragma solidity >=0.0; - -contract C { - function f() public {} -} - diff --git a/test/cmdlineTests/ethdebug_runtime_ir/output b/test/cmdlineTests/ethdebug_runtime_ir/output deleted file mode 100644 index 93b7b91f13e4..000000000000 --- a/test/cmdlineTests/ethdebug_runtime_ir/output +++ /dev/null @@ -1,121 +0,0 @@ -======= Debug Data (ethdebug/format/info/resources) ======= -{"sources":["ethdebug_runtime_ir/input.sol"]} - -======= ethdebug_runtime_ir/input.sol:C ======= -IR: -/// ethdebug: enabled -/// @use-src 0:"ethdebug_runtime_ir/input.sol" -object "C_6" { - code { - /// @src 0:60:101 "contract C {..." - mstore(64, memoryguard(128)) - if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } - - constructor_C_6() - - let _1 := allocate_unbounded() - codecopy(_1, dataoffset("C_6_deployed"), datasize("C_6_deployed")) - - return(_1, datasize("C_6_deployed")) - - function allocate_unbounded() -> memPtr { - memPtr := mload(64) - } - - function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() { - revert(0, 0) - } - - /// @src 0:60:101 "contract C {..." - function constructor_C_6() { - - /// @src 0:60:101 "contract C {..." - - } - /// @src 0:60:101 "contract C {..." - - } - /// @use-src 0:"ethdebug_runtime_ir/input.sol" - object "C_6_deployed" { - code { - /// @src 0:60:101 "contract C {..." - mstore(64, memoryguard(128)) - - if iszero(lt(calldatasize(), 4)) - { - let selector := shift_right_224_unsigned(calldataload(0)) - switch selector - - case 0x26121ff0 - { - // f() - - external_fun_f_5() - } - - default {} - } - - revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() - - function shift_right_224_unsigned(value) -> newValue { - newValue := - - shr(224, value) - - } - - function allocate_unbounded() -> memPtr { - memPtr := mload(64) - } - - function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() { - revert(0, 0) - } - - function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() { - revert(0, 0) - } - - function abi_decode_tuple_(headStart, dataEnd) { - if slt(sub(dataEnd, headStart), 0) { revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() } - - } - - function abi_encode_tuple__to__fromStack(headStart ) -> tail { - tail := add(headStart, 0) - - } - - function external_fun_f_5() { - - if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } - abi_decode_tuple_(4, calldatasize()) - fun_f_5() - let memPos := allocate_unbounded() - let memEnd := abi_encode_tuple__to__fromStack(memPos ) - return(memPos, sub(memEnd, memPos)) - - } - - function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() { - revert(0, 0) - } - - /// @ast-id 5 - /// @src 0:77:99 "function f() public {}" - function fun_f_5() { - - } - /// @src 0:60:101 "contract C {..." - - } - - data ".metadata" hex"" - } - -} - - -Debug Data of the runtime part (ethdebug/format/program): -{} diff --git a/test/cmdlineTests/ethdebug_runtime_iroptimized/args b/test/cmdlineTests/ethdebug_runtime_iroptimized/args deleted file mode 100644 index f647c52a7eed..000000000000 --- a/test/cmdlineTests/ethdebug_runtime_iroptimized/args +++ /dev/null @@ -1 +0,0 @@ ---ethdebug-runtime --via-ir --ir-optimized \ No newline at end of file diff --git a/test/cmdlineTests/ethdebug_runtime_iroptimized/input.sol b/test/cmdlineTests/ethdebug_runtime_iroptimized/input.sol deleted file mode 100644 index 25b9640ca565..000000000000 --- a/test/cmdlineTests/ethdebug_runtime_iroptimized/input.sol +++ /dev/null @@ -1,7 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -pragma solidity >=0.0; - -contract C { - function f() public {} -} - diff --git a/test/cmdlineTests/ethdebug_runtime_iroptimized/output b/test/cmdlineTests/ethdebug_runtime_iroptimized/output deleted file mode 100644 index 733e47a8500b..000000000000 --- a/test/cmdlineTests/ethdebug_runtime_iroptimized/output +++ /dev/null @@ -1,77 +0,0 @@ -======= Debug Data (ethdebug/format/info/resources) ======= -{"sources":["ethdebug_runtime_iroptimized/input.sol"]} - -======= ethdebug_runtime_iroptimized/input.sol:C ======= -Optimized IR: -/// ethdebug: enabled -/// @use-src 0:"ethdebug_runtime_iroptimized/input.sol" -object "C_6" { - code { - { - /// @src 0:60:101 "contract C {..." - mstore(64, memoryguard(0x80)) - if callvalue() - { - revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() - } - let _1 := allocate_unbounded() - codecopy(_1, dataoffset("C_6_deployed"), datasize("C_6_deployed")) - return(_1, datasize("C_6_deployed")) - } - function allocate_unbounded() -> memPtr - { memPtr := mload(64) } - function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() - { revert(0, 0) } - } - /// @use-src 0:"ethdebug_runtime_iroptimized/input.sol" - object "C_6_deployed" { - code { - { - /// @src 0:60:101 "contract C {..." - mstore(64, memoryguard(0x80)) - if iszero(lt(calldatasize(), 4)) - { - let selector := shift_right_unsigned(calldataload(0)) - switch selector - case 0x26121ff0 { external_fun_f() } - default { } - } - revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() - } - function shift_right_unsigned(value) -> newValue - { newValue := shr(224, value) } - function allocate_unbounded() -> memPtr - { memPtr := mload(64) } - function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() - { revert(0, 0) } - function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() - { revert(0, 0) } - function abi_decode(headStart, dataEnd) - { - if slt(sub(dataEnd, headStart), 0) - { - revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() - } - } - function abi_encode_tuple(headStart) -> tail - { tail := add(headStart, 0) } - function external_fun_f() - { - if callvalue() - { - revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() - } - abi_decode(4, calldatasize()) - let memPos := allocate_unbounded() - let memEnd := abi_encode_tuple(memPos) - return(memPos, sub(memEnd, memPos)) - } - function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() - { revert(0, 0) } - } - data ".metadata" hex"" - } -} - -Debug Data of the runtime part (ethdebug/format/program): -{} diff --git a/test/cmdlineTests/standard_output_debuginfo_ethdebug_compatible/output.json b/test/cmdlineTests/standard_output_debuginfo_ethdebug_compatible/output.json index 0b8a87baf622..8f198f1f3adb 100644 --- a/test/cmdlineTests/standard_output_debuginfo_ethdebug_compatible/output.json +++ b/test/cmdlineTests/standard_output_debuginfo_ethdebug_compatible/output.json @@ -4,10 +4,10 @@ "A1": { "evm": { "bytecode": { - "ethdebug": {} + "ethdebug": "" }, "deployedBytecode": { - "ethdebug": {} + "ethdebug": "" } }, "ir": "/// ethdebug: enabled @@ -298,10 +298,10 @@ object \"A1_14\" { "A2": { "evm": { "bytecode": { - "ethdebug": {} + "ethdebug": "" }, "deployedBytecode": { - "ethdebug": {} + "ethdebug": "" } }, "ir": "/// ethdebug: enabled @@ -594,10 +594,10 @@ object \"A2_27\" { "A1": { "evm": { "bytecode": { - "ethdebug": {} + "ethdebug": "" }, "deployedBytecode": { - "ethdebug": {} + "ethdebug": "" } }, "ir": "/// ethdebug: enabled @@ -888,10 +888,10 @@ object \"A1_42\" { "B2": { "evm": { "bytecode": { - "ethdebug": {} + "ethdebug": "" }, "deployedBytecode": { - "ethdebug": {} + "ethdebug": "" } }, "ir": "/// ethdebug: enabled @@ -1181,12 +1181,7 @@ object \"B2_55\" { } } }, - "ethdebug": { - "sources": [ - "a.sol", - "b.sol" - ] - }, + "ethdebug": "", "sources": { "a.sol": { "id": 0 diff --git a/test/cmdlineTests/standard_output_debuginfo_ethdebug_compatible/strip-ethdebug b/test/cmdlineTests/standard_output_debuginfo_ethdebug_compatible/strip-ethdebug new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_ir/output.json b/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_ir/output.json index f8fb2ce274d0..7694acea611c 100644 --- a/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_ir/output.json +++ b/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_ir/output.json @@ -4,10 +4,10 @@ "A1": { "evm": { "bytecode": { - "ethdebug": {} + "ethdebug": "" }, "deployedBytecode": { - "ethdebug": {} + "ethdebug": "" } }, "ir": "/// ethdebug: enabled @@ -184,10 +184,10 @@ object \"A1_14\" { "A2": { "evm": { "bytecode": { - "ethdebug": {} + "ethdebug": "" }, "deployedBytecode": { - "ethdebug": {} + "ethdebug": "" } }, "ir": "/// ethdebug: enabled @@ -366,10 +366,10 @@ object \"A2_27\" { "A1": { "evm": { "bytecode": { - "ethdebug": {} + "ethdebug": "" }, "deployedBytecode": { - "ethdebug": {} + "ethdebug": "" } }, "ir": "/// ethdebug: enabled @@ -546,10 +546,10 @@ object \"A1_42\" { "B2": { "evm": { "bytecode": { - "ethdebug": {} + "ethdebug": "" }, "deployedBytecode": { - "ethdebug": {} + "ethdebug": "" } }, "ir": "/// ethdebug: enabled @@ -725,12 +725,7 @@ object \"B2_55\" { } } }, - "ethdebug": { - "sources": [ - "a.sol", - "b.sol" - ] - }, + "ethdebug": "", "sources": { "a.sol": { "id": 0 diff --git a/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_ir/strip-ethdebug b/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_ir/strip-ethdebug new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_iroptimized/output.json b/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_iroptimized/output.json index 66b9082dcc12..b129a0c91b85 100644 --- a/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_iroptimized/output.json +++ b/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_iroptimized/output.json @@ -4,10 +4,10 @@ "A1": { "evm": { "bytecode": { - "ethdebug": {} + "ethdebug": "" }, "deployedBytecode": { - "ethdebug": {} + "ethdebug": "" } }, "irOptimized": "/// ethdebug: enabled @@ -129,10 +129,10 @@ object \"A1_14\" { "A2": { "evm": { "bytecode": { - "ethdebug": {} + "ethdebug": "" }, "deployedBytecode": { - "ethdebug": {} + "ethdebug": "" } }, "irOptimized": "/// ethdebug: enabled @@ -256,10 +256,10 @@ object \"A2_27\" { "A1": { "evm": { "bytecode": { - "ethdebug": {} + "ethdebug": "" }, "deployedBytecode": { - "ethdebug": {} + "ethdebug": "" } }, "irOptimized": "/// ethdebug: enabled @@ -381,10 +381,10 @@ object \"A1_42\" { "B2": { "evm": { "bytecode": { - "ethdebug": {} + "ethdebug": "" }, "deployedBytecode": { - "ethdebug": {} + "ethdebug": "" } }, "irOptimized": "/// ethdebug: enabled @@ -505,12 +505,7 @@ object \"B2_55\" { } } }, - "ethdebug": { - "sources": [ - "a.sol", - "b.sol" - ] - }, + "ethdebug": "", "sources": { "a.sol": { "id": 0 diff --git a/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_iroptimized/strip-ethdebug b/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_iroptimized/strip-ethdebug new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_ir/output.json b/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_ir/output.json index fabb25ee6720..c7463f124184 100644 --- a/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_ir/output.json +++ b/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_ir/output.json @@ -4,7 +4,7 @@ "A1": { "evm": { "bytecode": { - "ethdebug": {} + "ethdebug": "" } }, "ir": "/// ethdebug: enabled @@ -181,7 +181,7 @@ object \"A1_14\" { "A2": { "evm": { "bytecode": { - "ethdebug": {} + "ethdebug": "" } }, "ir": "/// ethdebug: enabled @@ -360,7 +360,7 @@ object \"A2_27\" { "A1": { "evm": { "bytecode": { - "ethdebug": {} + "ethdebug": "" } }, "ir": "/// ethdebug: enabled @@ -537,7 +537,7 @@ object \"A1_42\" { "B2": { "evm": { "bytecode": { - "ethdebug": {} + "ethdebug": "" } }, "ir": "/// ethdebug: enabled @@ -713,12 +713,7 @@ object \"B2_55\" { } } }, - "ethdebug": { - "sources": [ - "a.sol", - "b.sol" - ] - }, + "ethdebug": "", "sources": { "a.sol": { "id": 0 diff --git a/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_ir/strip-ethdebug b/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_ir/strip-ethdebug new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_iroptimized/output.json b/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_iroptimized/output.json index d7284ab6405e..eab40879c4c5 100644 --- a/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_iroptimized/output.json +++ b/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_iroptimized/output.json @@ -4,7 +4,7 @@ "A1": { "evm": { "bytecode": { - "ethdebug": {} + "ethdebug": "" } }, "irOptimized": "/// ethdebug: enabled @@ -126,7 +126,7 @@ object \"A1_14\" { "A2": { "evm": { "bytecode": { - "ethdebug": {} + "ethdebug": "" } }, "irOptimized": "/// ethdebug: enabled @@ -250,7 +250,7 @@ object \"A2_27\" { "A1": { "evm": { "bytecode": { - "ethdebug": {} + "ethdebug": "" } }, "irOptimized": "/// ethdebug: enabled @@ -372,7 +372,7 @@ object \"A1_42\" { "B2": { "evm": { "bytecode": { - "ethdebug": {} + "ethdebug": "" } }, "irOptimized": "/// ethdebug: enabled @@ -493,12 +493,7 @@ object \"B2_55\" { } } }, - "ethdebug": { - "sources": [ - "a.sol", - "b.sol" - ] - }, + "ethdebug": "", "sources": { "a.sol": { "id": 0 diff --git a/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_iroptimized/strip-ethdebug b/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_iroptimized/strip-ethdebug new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/test/cmdlineTests/standard_output_selection_ethdebug_deployedbytecode_ir/output.json b/test/cmdlineTests/standard_output_selection_ethdebug_deployedbytecode_ir/output.json index 4c7b4ed67197..8a8080833cf6 100644 --- a/test/cmdlineTests/standard_output_selection_ethdebug_deployedbytecode_ir/output.json +++ b/test/cmdlineTests/standard_output_selection_ethdebug_deployedbytecode_ir/output.json @@ -4,7 +4,7 @@ "A1": { "evm": { "deployedBytecode": { - "ethdebug": {} + "ethdebug": "" } }, "ir": "/// ethdebug: enabled @@ -181,7 +181,7 @@ object \"A1_14\" { "A2": { "evm": { "deployedBytecode": { - "ethdebug": {} + "ethdebug": "" } }, "ir": "/// ethdebug: enabled @@ -360,7 +360,7 @@ object \"A2_27\" { "A1": { "evm": { "deployedBytecode": { - "ethdebug": {} + "ethdebug": "" } }, "ir": "/// ethdebug: enabled @@ -537,7 +537,7 @@ object \"A1_42\" { "B2": { "evm": { "deployedBytecode": { - "ethdebug": {} + "ethdebug": "" } }, "ir": "/// ethdebug: enabled @@ -713,12 +713,7 @@ object \"B2_55\" { } } }, - "ethdebug": { - "sources": [ - "a.sol", - "b.sol" - ] - }, + "ethdebug": "", "sources": { "a.sol": { "id": 0 diff --git a/test/cmdlineTests/standard_output_selection_ethdebug_deployedbytecode_ir/strip-ethdebug b/test/cmdlineTests/standard_output_selection_ethdebug_deployedbytecode_ir/strip-ethdebug new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/test/cmdlineTests/standard_output_selection_ethdebug_deployedbytecode_iroptimized/output.json b/test/cmdlineTests/standard_output_selection_ethdebug_deployedbytecode_iroptimized/output.json index dce2a276e46f..4f3bd68eed09 100644 --- a/test/cmdlineTests/standard_output_selection_ethdebug_deployedbytecode_iroptimized/output.json +++ b/test/cmdlineTests/standard_output_selection_ethdebug_deployedbytecode_iroptimized/output.json @@ -4,7 +4,7 @@ "A1": { "evm": { "deployedBytecode": { - "ethdebug": {} + "ethdebug": "" } }, "irOptimized": "/// ethdebug: enabled @@ -126,7 +126,7 @@ object \"A1_14\" { "A2": { "evm": { "deployedBytecode": { - "ethdebug": {} + "ethdebug": "" } }, "irOptimized": "/// ethdebug: enabled @@ -250,7 +250,7 @@ object \"A2_27\" { "A1": { "evm": { "deployedBytecode": { - "ethdebug": {} + "ethdebug": "" } }, "irOptimized": "/// ethdebug: enabled @@ -372,7 +372,7 @@ object \"A1_42\" { "B2": { "evm": { "deployedBytecode": { - "ethdebug": {} + "ethdebug": "" } }, "irOptimized": "/// ethdebug: enabled @@ -493,12 +493,7 @@ object \"B2_55\" { } } }, - "ethdebug": { - "sources": [ - "a.sol", - "b.sol" - ] - }, + "ethdebug": "", "sources": { "a.sol": { "id": 0 diff --git a/test/cmdlineTests/standard_output_selection_ethdebug_deployedbytecode_iroptimized/strip-ethdebug b/test/cmdlineTests/standard_output_selection_ethdebug_deployedbytecode_iroptimized/strip-ethdebug new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/test/cmdlineTests/standard_output_selection_ethdebug_ir/output.json b/test/cmdlineTests/standard_output_selection_ethdebug_ir/output.json index fabb25ee6720..c7463f124184 100644 --- a/test/cmdlineTests/standard_output_selection_ethdebug_ir/output.json +++ b/test/cmdlineTests/standard_output_selection_ethdebug_ir/output.json @@ -4,7 +4,7 @@ "A1": { "evm": { "bytecode": { - "ethdebug": {} + "ethdebug": "" } }, "ir": "/// ethdebug: enabled @@ -181,7 +181,7 @@ object \"A1_14\" { "A2": { "evm": { "bytecode": { - "ethdebug": {} + "ethdebug": "" } }, "ir": "/// ethdebug: enabled @@ -360,7 +360,7 @@ object \"A2_27\" { "A1": { "evm": { "bytecode": { - "ethdebug": {} + "ethdebug": "" } }, "ir": "/// ethdebug: enabled @@ -537,7 +537,7 @@ object \"A1_42\" { "B2": { "evm": { "bytecode": { - "ethdebug": {} + "ethdebug": "" } }, "ir": "/// ethdebug: enabled @@ -713,12 +713,7 @@ object \"B2_55\" { } } }, - "ethdebug": { - "sources": [ - "a.sol", - "b.sol" - ] - }, + "ethdebug": "", "sources": { "a.sol": { "id": 0 diff --git a/test/cmdlineTests/standard_output_selection_ethdebug_ir/strip-ethdebug b/test/cmdlineTests/standard_output_selection_ethdebug_ir/strip-ethdebug new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/test/cmdlineTests/standard_output_selection_ethdebug_iroptimized/output.json b/test/cmdlineTests/standard_output_selection_ethdebug_iroptimized/output.json index d7284ab6405e..eab40879c4c5 100644 --- a/test/cmdlineTests/standard_output_selection_ethdebug_iroptimized/output.json +++ b/test/cmdlineTests/standard_output_selection_ethdebug_iroptimized/output.json @@ -4,7 +4,7 @@ "A1": { "evm": { "bytecode": { - "ethdebug": {} + "ethdebug": "" } }, "irOptimized": "/// ethdebug: enabled @@ -126,7 +126,7 @@ object \"A1_14\" { "A2": { "evm": { "bytecode": { - "ethdebug": {} + "ethdebug": "" } }, "irOptimized": "/// ethdebug: enabled @@ -250,7 +250,7 @@ object \"A2_27\" { "A1": { "evm": { "bytecode": { - "ethdebug": {} + "ethdebug": "" } }, "irOptimized": "/// ethdebug: enabled @@ -372,7 +372,7 @@ object \"A1_42\" { "B2": { "evm": { "bytecode": { - "ethdebug": {} + "ethdebug": "" } }, "irOptimized": "/// ethdebug: enabled @@ -493,12 +493,7 @@ object \"B2_55\" { } } }, - "ethdebug": { - "sources": [ - "a.sol", - "b.sol" - ] - }, + "ethdebug": "", "sources": { "a.sol": { "id": 0 diff --git a/test/cmdlineTests/standard_output_selection_ethdebug_iroptimized/strip-ethdebug b/test/cmdlineTests/standard_output_selection_ethdebug_iroptimized/strip-ethdebug new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/test/cmdlineTests/standard_yul_debug_info_ethdebug_compatible_output/output.json b/test/cmdlineTests/standard_yul_debug_info_ethdebug_compatible_output/output.json index 63d48b80b255..2b2f395fadd4 100644 --- a/test/cmdlineTests/standard_yul_debug_info_ethdebug_compatible_output/output.json +++ b/test/cmdlineTests/standard_yul_debug_info_ethdebug_compatible_output/output.json @@ -4,9 +4,7 @@ "C_6_deployed": { "evm": { "bytecode": { - "ethdebug": { - "not yet implemented @ MachineAssemblyObject::ethdebug": true - } + "ethdebug": "" } }, "ir": "/// ethdebug: enabled @@ -40,9 +38,5 @@ object \"C_6_deployed\" { } } }, - "ethdebug": { - "sources": [ - "C" - ] - } + "ethdebug": "" } diff --git a/test/cmdlineTests/standard_yul_debug_info_ethdebug_compatible_output/strip-ethdebug b/test/cmdlineTests/standard_yul_debug_info_ethdebug_compatible_output/strip-ethdebug new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/test/cmdlineTests/standard_yul_debug_info_ethdebug_verbatim_unimplemented/args b/test/cmdlineTests/standard_yul_debug_info_ethdebug_verbatim_unimplemented/args new file mode 100644 index 000000000000..18532c5a6d3f --- /dev/null +++ b/test/cmdlineTests/standard_yul_debug_info_ethdebug_verbatim_unimplemented/args @@ -0,0 +1 @@ +--allow-paths . diff --git a/test/cmdlineTests/standard_yul_debug_info_ethdebug_verbatim_unimplemented/in.yul b/test/cmdlineTests/standard_yul_debug_info_ethdebug_verbatim_unimplemented/in.yul new file mode 100644 index 000000000000..182cdc75ddc9 --- /dev/null +++ b/test/cmdlineTests/standard_yul_debug_info_ethdebug_verbatim_unimplemented/in.yul @@ -0,0 +1,11 @@ +{ + let x := 2 + let y := sub(x, 2) + let t := verbatim_2i_1o("abc", x, y) + sstore(t, x) + let r := verbatim_0i_1o("def") + verbatim_0i_0o("xyz") + // more than 32 bytes + verbatim_0i_0o(hex"01020304050607090001020304050607090001020304050607090001020102030405060709000102030405060709000102030405060709000102") + r := 9 +} diff --git a/test/cmdlineTests/standard_yul_debug_info_ethdebug_verbatim_unimplemented/input.json b/test/cmdlineTests/standard_yul_debug_info_ethdebug_verbatim_unimplemented/input.json new file mode 100644 index 000000000000..be4fbb64fce3 --- /dev/null +++ b/test/cmdlineTests/standard_yul_debug_info_ethdebug_verbatim_unimplemented/input.json @@ -0,0 +1,16 @@ +{ + "language": "Yul", + "sources": { + "C": { + "urls": [ + "standard_yul_debug_info_ethdebug_verbatim_unimplemented/in.yul" + ] + } + }, + "settings": { + "debug": {"debugInfo": ["ethdebug"]}, + "outputSelection": { + "*": {"*": ["evm.bytecode.ethdebug"]} + } + } +} diff --git a/test/cmdlineTests/standard_yul_debug_info_ethdebug_verbatim_unimplemented/output.json b/test/cmdlineTests/standard_yul_debug_info_ethdebug_verbatim_unimplemented/output.json new file mode 100644 index 000000000000..b645222de390 --- /dev/null +++ b/test/cmdlineTests/standard_yul_debug_info_ethdebug_verbatim_unimplemented/output.json @@ -0,0 +1,13 @@ +{ + "errors": [ + { + "component": "general", + "formattedMessage": "UnimplementedFeatureError: Verbatim bytecode is currently not supported by ethdebug. + +", + "message": "Verbatim bytecode is currently not supported by ethdebug.", + "severity": "error", + "type": "UnimplementedFeatureError" + } + ] +} diff --git a/test/cmdlineTests/standard_yul_ethdebug_assign_immutable/args b/test/cmdlineTests/standard_yul_ethdebug_assign_immutable/args new file mode 100644 index 000000000000..18532c5a6d3f --- /dev/null +++ b/test/cmdlineTests/standard_yul_ethdebug_assign_immutable/args @@ -0,0 +1 @@ +--allow-paths . diff --git a/test/cmdlineTests/standard_yul_ethdebug_assign_immutable/in.yul b/test/cmdlineTests/standard_yul_ethdebug_assign_immutable/in.yul new file mode 100644 index 000000000000..5c098cc80569 --- /dev/null +++ b/test/cmdlineTests/standard_yul_ethdebug_assign_immutable/in.yul @@ -0,0 +1,7 @@ +object "a" { + code { + { + setimmutable(0, "long___name___that___definitely___exceeds___the___thirty___two___byte___limit", 0x1234567890123456789012345678901234567890) + } + } +} \ No newline at end of file diff --git a/test/cmdlineTests/standard_yul_ethdebug_assign_immutable/input.json b/test/cmdlineTests/standard_yul_ethdebug_assign_immutable/input.json new file mode 100644 index 000000000000..83acd4c42085 --- /dev/null +++ b/test/cmdlineTests/standard_yul_ethdebug_assign_immutable/input.json @@ -0,0 +1,11 @@ +{ + "language": "Yul", + "sources": { + "C": {"urls": ["standard_yul_ethdebug_assign_immutable/in.yul"]} + }, + "settings": { + "outputSelection": { + "*": {"*": ["evm.bytecode.ethdebug"]} + } + } +} diff --git a/test/cmdlineTests/standard_yul_ethdebug_assign_immutable/output.json b/test/cmdlineTests/standard_yul_ethdebug_assign_immutable/output.json new file mode 100644 index 000000000000..3af82e21d392 --- /dev/null +++ b/test/cmdlineTests/standard_yul_ethdebug_assign_immutable/output.json @@ -0,0 +1,127 @@ +{ + "contracts": { + "C": { + "a": { + "evm": { + "bytecode": { + "ethdebug": { + "contract": { + "definition": { + "source": { + "id": 0 + } + }, + "name": "" + }, + "environment": "create", + "instructions": [ + { + "context": { + "code": { + "range": { + "length": 42, + "offset": 165 + }, + "source": { + "id": 0 + } + } + }, + "offset": 0, + "operation": { + "arguments": [ + "0x1234567890123456789012345678901234567890" + ], + "mnemonic": "PUSH20" + } + }, + { + "context": { + "code": { + "range": { + "length": 1, + "offset": 81 + }, + "source": { + "id": 0 + } + } + }, + "offset": 21, + "operation": { + "mnemonic": "PUSH0" + } + }, + { + "context": { + "code": { + "range": { + "length": 140, + "offset": 68 + }, + "source": { + "id": 0 + } + } + }, + "offset": 22, + "operation": { + "mnemonic": "POP" + } + }, + { + "context": { + "code": { + "range": { + "length": 140, + "offset": 68 + }, + "source": { + "id": 0 + } + } + }, + "offset": 23, + "operation": { + "mnemonic": "POP" + } + }, + { + "context": { + "code": { + "range": { + "length": 180, + "offset": 44 + }, + "source": { + "id": 0 + } + } + }, + "offset": 24, + "operation": { + "mnemonic": "STOP" + } + } + ] + } + } + } + } + } + }, + "ethdebug": { + "compilation": { + "compiler": { + "name": "solc", + "version": "" + }, + "sources": [ + { + "id": 0, + "path": "C" + } + ] + } + } +} diff --git a/test/cmdlineTests/standard_yul_ethdebug_bytecode_ir/output.json b/test/cmdlineTests/standard_yul_ethdebug_bytecode_ir/output.json index c9ab1d8f5e73..c1f6523d5388 100644 --- a/test/cmdlineTests/standard_yul_ethdebug_bytecode_ir/output.json +++ b/test/cmdlineTests/standard_yul_ethdebug_bytecode_ir/output.json @@ -4,9 +4,7 @@ "C_6_deployed": { "evm": { "bytecode": { - "ethdebug": { - "not yet implemented @ MachineAssemblyObject::ethdebug": true - } + "ethdebug": "" } }, "ir": "/// ethdebug: enabled @@ -25,9 +23,5 @@ object \"C_6_deployed\" { } } }, - "ethdebug": { - "sources": [ - "C" - ] - } + "ethdebug": "" } diff --git a/test/cmdlineTests/standard_yul_ethdebug_bytecode_ir/strip-ethdebug b/test/cmdlineTests/standard_yul_ethdebug_bytecode_ir/strip-ethdebug new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/test/cmdlineTests/standard_yul_ethdebug_bytecode_iroptimized/output.json b/test/cmdlineTests/standard_yul_ethdebug_bytecode_iroptimized/output.json index d7e3e6be3b40..2f1d22b4df0f 100644 --- a/test/cmdlineTests/standard_yul_ethdebug_bytecode_iroptimized/output.json +++ b/test/cmdlineTests/standard_yul_ethdebug_bytecode_iroptimized/output.json @@ -4,9 +4,7 @@ "C_6_deployed": { "evm": { "bytecode": { - "ethdebug": { - "not yet implemented @ MachineAssemblyObject::ethdebug": true - } + "ethdebug": "" } }, "irOptimized": "/// ethdebug: enabled @@ -27,9 +25,5 @@ object \"C_6_deployed\" { } } }, - "ethdebug": { - "sources": [ - "C" - ] - } + "ethdebug": "" } diff --git a/test/cmdlineTests/standard_yul_ethdebug_bytecode_iroptimized/strip-ethdebug b/test/cmdlineTests/standard_yul_ethdebug_bytecode_iroptimized/strip-ethdebug new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/test/cmdlineTests/standard_yul_ethdebug_deployed_bytecode/in.yul b/test/cmdlineTests/standard_yul_ethdebug_deployed_bytecode/in.yul index 920aef8e9dc2..d5adfd0c28f4 100644 --- a/test/cmdlineTests/standard_yul_ethdebug_deployed_bytecode/in.yul +++ b/test/cmdlineTests/standard_yul_ethdebug_deployed_bytecode/in.yul @@ -1,17 +1,19 @@ -/// @use-src 0:"input.sol" -object "C_6_deployed" { - code { - /// @src 0:60:101 "contract C {..." +object "object" { + code { mstore(64, 128) - - // f() fun_f_5() - - /// @src 0:77:99 "function f() public {}" function fun_f_5() { sstore(0, 42) } - /// @src 0:60:101 "contract C {..." } -} + object "object_deployed" { + code { + mstore(64, 128) + fun_f_5() + function fun_f_5() { + sstore(0, 42) + } + } + } +} diff --git a/test/cmdlineTests/standard_yul_ethdebug_deployed_bytecode/output.json b/test/cmdlineTests/standard_yul_ethdebug_deployed_bytecode/output.json index 1380c31d7c10..44183e45fdde 100644 --- a/test/cmdlineTests/standard_yul_ethdebug_deployed_bytecode/output.json +++ b/test/cmdlineTests/standard_yul_ethdebug_deployed_bytecode/output.json @@ -1,11 +1,14 @@ { - "errors": [ - { - "component": "general", - "formattedMessage": "\"evm.deployedBytecode.ethdebug\" cannot be used for Yul.", - "message": "\"evm.deployedBytecode.ethdebug\" cannot be used for Yul.", - "severity": "error", - "type": "JSONError" + "contracts": { + "C": { + "object": { + "evm": { + "deployedBytecode": { + "ethdebug": "" + } + } + } } - ] + }, + "ethdebug": "" } diff --git a/test/cmdlineTests/standard_yul_ethdebug_deployed_bytecode/strip-ethdebug b/test/cmdlineTests/standard_yul_ethdebug_deployed_bytecode/strip-ethdebug new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/test/cmdlineTests/standard_yul_ethdebug_deployed_bytecode_and_bytecode/args b/test/cmdlineTests/standard_yul_ethdebug_deployed_bytecode_and_bytecode/args new file mode 100644 index 000000000000..18532c5a6d3f --- /dev/null +++ b/test/cmdlineTests/standard_yul_ethdebug_deployed_bytecode_and_bytecode/args @@ -0,0 +1 @@ +--allow-paths . diff --git a/test/cmdlineTests/standard_yul_ethdebug_deployed_bytecode_and_bytecode/in.yul b/test/cmdlineTests/standard_yul_ethdebug_deployed_bytecode_and_bytecode/in.yul new file mode 100644 index 000000000000..d5adfd0c28f4 --- /dev/null +++ b/test/cmdlineTests/standard_yul_ethdebug_deployed_bytecode_and_bytecode/in.yul @@ -0,0 +1,19 @@ +object "object" { + code { + mstore(64, 128) + fun_f_5() + function fun_f_5() { + sstore(0, 42) + } + } + + object "object_deployed" { + code { + mstore(64, 128) + fun_f_5() + function fun_f_5() { + sstore(0, 42) + } + } + } +} diff --git a/test/cmdlineTests/standard_yul_ethdebug_deployed_bytecode_and_bytecode/input.json b/test/cmdlineTests/standard_yul_ethdebug_deployed_bytecode_and_bytecode/input.json new file mode 100644 index 000000000000..20779012030d --- /dev/null +++ b/test/cmdlineTests/standard_yul_ethdebug_deployed_bytecode_and_bytecode/input.json @@ -0,0 +1,11 @@ +{ + "language": "Yul", + "sources": { + "C": {"urls": ["standard_yul_ethdebug_deployed_bytecode/in.yul"]} + }, + "settings": { + "outputSelection": { + "*": {"*": ["evm.deployedBytecode.ethdebug", "evm.bytecode.ethdebug"]} + } + } +} diff --git a/test/cmdlineTests/standard_yul_ethdebug_deployed_bytecode_and_bytecode/output.json b/test/cmdlineTests/standard_yul_ethdebug_deployed_bytecode_and_bytecode/output.json new file mode 100644 index 000000000000..6d8064a94f36 --- /dev/null +++ b/test/cmdlineTests/standard_yul_ethdebug_deployed_bytecode_and_bytecode/output.json @@ -0,0 +1,17 @@ +{ + "contracts": { + "C": { + "object": { + "evm": { + "bytecode": { + "ethdebug": "" + }, + "deployedBytecode": { + "ethdebug": "" + } + } + } + } + }, + "ethdebug": "" +} diff --git a/test/cmdlineTests/standard_yul_ethdebug_deployed_bytecode_and_bytecode/strip-ethdebug b/test/cmdlineTests/standard_yul_ethdebug_deployed_bytecode_and_bytecode/strip-ethdebug new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/test/cmdlineTests/standard_yul_ethdebug_ir/output.json b/test/cmdlineTests/standard_yul_ethdebug_ir/output.json index c9ab1d8f5e73..c1f6523d5388 100644 --- a/test/cmdlineTests/standard_yul_ethdebug_ir/output.json +++ b/test/cmdlineTests/standard_yul_ethdebug_ir/output.json @@ -4,9 +4,7 @@ "C_6_deployed": { "evm": { "bytecode": { - "ethdebug": { - "not yet implemented @ MachineAssemblyObject::ethdebug": true - } + "ethdebug": "" } }, "ir": "/// ethdebug: enabled @@ -25,9 +23,5 @@ object \"C_6_deployed\" { } } }, - "ethdebug": { - "sources": [ - "C" - ] - } + "ethdebug": "" } diff --git a/test/cmdlineTests/standard_yul_ethdebug_ir/strip-ethdebug b/test/cmdlineTests/standard_yul_ethdebug_ir/strip-ethdebug new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/test/cmdlineTests/standard_yul_ethdebug_iroptimize/output.json b/test/cmdlineTests/standard_yul_ethdebug_iroptimize/output.json index 47d0008f1eb5..6323c1157973 100644 --- a/test/cmdlineTests/standard_yul_ethdebug_iroptimize/output.json +++ b/test/cmdlineTests/standard_yul_ethdebug_iroptimize/output.json @@ -4,17 +4,11 @@ "C_6_deployed": { "evm": { "bytecode": { - "ethdebug": { - "not yet implemented @ MachineAssemblyObject::ethdebug": true - } + "ethdebug": "" } } } } }, - "ethdebug": { - "sources": [ - "C" - ] - } + "ethdebug": "" } diff --git a/test/cmdlineTests/standard_yul_ethdebug_iroptimize/strip-ethdebug b/test/cmdlineTests/standard_yul_ethdebug_iroptimize/strip-ethdebug new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/test/cmdlineTests/yul_ethdebug/args b/test/cmdlineTests/yul_ethdebug/args deleted file mode 100644 index a800f5c34e34..000000000000 --- a/test/cmdlineTests/yul_ethdebug/args +++ /dev/null @@ -1 +0,0 @@ ---ethdebug --strict-assembly \ No newline at end of file diff --git a/test/cmdlineTests/yul_ethdebug/input.yul b/test/cmdlineTests/yul_ethdebug/input.yul deleted file mode 100644 index acd0b45f5335..000000000000 --- a/test/cmdlineTests/yul_ethdebug/input.yul +++ /dev/null @@ -1,18 +0,0 @@ -object "object" { - code { - let a - let b - { - function z() -> y - { y := calldataload(0) } - a := z() - } - { - function z() -> y - { y := calldataload(0x20) } - b := z() - } - sstore(a, b) - } -} - diff --git a/test/cmdlineTests/yul_ethdebug/output b/test/cmdlineTests/yul_ethdebug/output deleted file mode 100644 index 84ba9317b85b..000000000000 --- a/test/cmdlineTests/yul_ethdebug/output +++ /dev/null @@ -1,7 +0,0 @@ -======= Debug Data (ethdebug/format/info/resources) ======= -{"sources":["yul_ethdebug/input.yul"]} - -======= yul_ethdebug/input.yul (EVM) ======= - -Debug Data (ethdebug/format/program): -{"not yet implemented @ MachineAssemblyObject::ethdebug":true} diff --git a/test/cmdlineTests/yul_ethdebug_ir/args b/test/cmdlineTests/yul_ethdebug_ir/args deleted file mode 100644 index 6194b51b6942..000000000000 --- a/test/cmdlineTests/yul_ethdebug_ir/args +++ /dev/null @@ -1 +0,0 @@ ---ethdebug --strict-assembly --ir \ No newline at end of file diff --git a/test/cmdlineTests/yul_ethdebug_ir/err b/test/cmdlineTests/yul_ethdebug_ir/err deleted file mode 100644 index 645f7557ada8..000000000000 --- a/test/cmdlineTests/yul_ethdebug_ir/err +++ /dev/null @@ -1 +0,0 @@ -Error: The following outputs are not supported in assembler mode: --ir. diff --git a/test/cmdlineTests/yul_ethdebug_ir/exit b/test/cmdlineTests/yul_ethdebug_ir/exit deleted file mode 100644 index d00491fd7e5b..000000000000 --- a/test/cmdlineTests/yul_ethdebug_ir/exit +++ /dev/null @@ -1 +0,0 @@ -1 diff --git a/test/cmdlineTests/yul_ethdebug_ir/input.yul b/test/cmdlineTests/yul_ethdebug_ir/input.yul deleted file mode 100644 index acd0b45f5335..000000000000 --- a/test/cmdlineTests/yul_ethdebug_ir/input.yul +++ /dev/null @@ -1,18 +0,0 @@ -object "object" { - code { - let a - let b - { - function z() -> y - { y := calldataload(0) } - a := z() - } - { - function z() -> y - { y := calldataload(0x20) } - b := z() - } - sstore(a, b) - } -} - diff --git a/test/cmdlineTests/yul_ethdebug_iroptimized/args b/test/cmdlineTests/yul_ethdebug_iroptimized/args deleted file mode 100644 index 2063d860c504..000000000000 --- a/test/cmdlineTests/yul_ethdebug_iroptimized/args +++ /dev/null @@ -1 +0,0 @@ ---ethdebug --strict-assembly --ir-optimized \ No newline at end of file diff --git a/test/cmdlineTests/yul_ethdebug_iroptimized/input.yul b/test/cmdlineTests/yul_ethdebug_iroptimized/input.yul deleted file mode 100644 index acd0b45f5335..000000000000 --- a/test/cmdlineTests/yul_ethdebug_iroptimized/input.yul +++ /dev/null @@ -1,18 +0,0 @@ -object "object" { - code { - let a - let b - { - function z() -> y - { y := calldataload(0) } - a := z() - } - { - function z() -> y - { y := calldataload(0x20) } - b := z() - } - sstore(a, b) - } -} - diff --git a/test/cmdlineTests/yul_ethdebug_iroptimized/output b/test/cmdlineTests/yul_ethdebug_iroptimized/output deleted file mode 100644 index e2f0ed7f97f2..000000000000 --- a/test/cmdlineTests/yul_ethdebug_iroptimized/output +++ /dev/null @@ -1,26 +0,0 @@ -======= Debug Data (ethdebug/format/info/resources) ======= -{"sources":["yul_ethdebug_iroptimized/input.yul"]} - -======= yul_ethdebug_iroptimized/input.yul (EVM) ======= - -Pretty printed source: -/// ethdebug: enabled -object "object" { - code { - { - let a - let b - a := z() - b := z_1() - sstore(a, b) - } - function z() -> y - { y := calldataload(0) } - function z_1() -> y - { y := calldataload(0x20) } - } -} - - -Debug Data (ethdebug/format/program): -{"not yet implemented @ MachineAssemblyObject::ethdebug":true} diff --git a/test/cmdlineTests/yul_ethdebug_optimize/args b/test/cmdlineTests/yul_ethdebug_optimize/args deleted file mode 100644 index fd081fdaf6d3..000000000000 --- a/test/cmdlineTests/yul_ethdebug_optimize/args +++ /dev/null @@ -1 +0,0 @@ ---ethdebug --strict-assembly --optimize \ No newline at end of file diff --git a/test/cmdlineTests/yul_ethdebug_optimize/err b/test/cmdlineTests/yul_ethdebug_optimize/err deleted file mode 100644 index 7d66138755f9..000000000000 --- a/test/cmdlineTests/yul_ethdebug_optimize/err +++ /dev/null @@ -1 +0,0 @@ -Error: Optimization (using --optimize) is not yet supported with ethdebug. diff --git a/test/cmdlineTests/yul_ethdebug_optimize/exit b/test/cmdlineTests/yul_ethdebug_optimize/exit deleted file mode 100644 index d00491fd7e5b..000000000000 --- a/test/cmdlineTests/yul_ethdebug_optimize/exit +++ /dev/null @@ -1 +0,0 @@ -1 diff --git a/test/cmdlineTests/yul_ethdebug_optimize/input.yul b/test/cmdlineTests/yul_ethdebug_optimize/input.yul deleted file mode 100644 index acd0b45f5335..000000000000 --- a/test/cmdlineTests/yul_ethdebug_optimize/input.yul +++ /dev/null @@ -1,18 +0,0 @@ -object "object" { - code { - let a - let b - { - function z() -> y - { y := calldataload(0) } - a := z() - } - { - function z() -> y - { y := calldataload(0x20) } - b := z() - } - sstore(a, b) - } -} - diff --git a/test/cmdlineTests/yul_ethdebug_optimize_iroptimized/args b/test/cmdlineTests/yul_ethdebug_optimize_iroptimized/args deleted file mode 100644 index 715f3fb4848b..000000000000 --- a/test/cmdlineTests/yul_ethdebug_optimize_iroptimized/args +++ /dev/null @@ -1 +0,0 @@ ---ethdebug --strict-assembly --optimize --ir-optimized \ No newline at end of file diff --git a/test/cmdlineTests/yul_ethdebug_optimize_iroptimized/err b/test/cmdlineTests/yul_ethdebug_optimize_iroptimized/err deleted file mode 100644 index 7d66138755f9..000000000000 --- a/test/cmdlineTests/yul_ethdebug_optimize_iroptimized/err +++ /dev/null @@ -1 +0,0 @@ -Error: Optimization (using --optimize) is not yet supported with ethdebug. diff --git a/test/cmdlineTests/yul_ethdebug_optimize_iroptimized/exit b/test/cmdlineTests/yul_ethdebug_optimize_iroptimized/exit deleted file mode 100644 index d00491fd7e5b..000000000000 --- a/test/cmdlineTests/yul_ethdebug_optimize_iroptimized/exit +++ /dev/null @@ -1 +0,0 @@ -1 diff --git a/test/cmdlineTests/yul_ethdebug_optimize_iroptimized/input.yul b/test/cmdlineTests/yul_ethdebug_optimize_iroptimized/input.yul deleted file mode 100644 index acd0b45f5335..000000000000 --- a/test/cmdlineTests/yul_ethdebug_optimize_iroptimized/input.yul +++ /dev/null @@ -1,18 +0,0 @@ -object "object" { - code { - let a - let b - { - function z() -> y - { y := calldataload(0) } - a := z() - } - { - function z() -> y - { y := calldataload(0x20) } - b := z() - } - sstore(a, b) - } -} - diff --git a/test/cmdlineTests/yul_ethdebug_runtime/args b/test/cmdlineTests/yul_ethdebug_runtime/args deleted file mode 100644 index 3bedf2d9e437..000000000000 --- a/test/cmdlineTests/yul_ethdebug_runtime/args +++ /dev/null @@ -1 +0,0 @@ ---ethdebug-runtime --strict-assembly \ No newline at end of file diff --git a/test/cmdlineTests/yul_ethdebug_runtime/err b/test/cmdlineTests/yul_ethdebug_runtime/err deleted file mode 100644 index ed5894632c43..000000000000 --- a/test/cmdlineTests/yul_ethdebug_runtime/err +++ /dev/null @@ -1 +0,0 @@ -Error: The following outputs are not supported in assembler mode: --ethdebug-runtime. diff --git a/test/cmdlineTests/yul_ethdebug_runtime/exit b/test/cmdlineTests/yul_ethdebug_runtime/exit deleted file mode 100644 index d00491fd7e5b..000000000000 --- a/test/cmdlineTests/yul_ethdebug_runtime/exit +++ /dev/null @@ -1 +0,0 @@ -1 diff --git a/test/cmdlineTests/yul_ethdebug_runtime/input.yul b/test/cmdlineTests/yul_ethdebug_runtime/input.yul deleted file mode 100644 index acd0b45f5335..000000000000 --- a/test/cmdlineTests/yul_ethdebug_runtime/input.yul +++ /dev/null @@ -1,18 +0,0 @@ -object "object" { - code { - let a - let b - { - function z() -> y - { y := calldataload(0) } - a := z() - } - { - function z() -> y - { y := calldataload(0x20) } - b := z() - } - sstore(a, b) - } -} - diff --git a/test/libevmasm/Assembler.cpp b/test/libevmasm/Assembler.cpp index 3a6383002dc3..6a41f7a7394c 100644 --- a/test/libevmasm/Assembler.cpp +++ b/test/libevmasm/Assembler.cpp @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -425,6 +426,46 @@ BOOST_AUTO_TEST_CASE(subobject_encode_decode) BOOST_CHECK(assembly.decodeSubPath(assembly.encodeSubPath(subPath)) == subPath); } +BOOST_AUTO_TEST_CASE(ethdebug_program_last_instruction_with_immediate_arguments) +{ + EVMVersion evmVersion = solidity::test::CommonOptions::get().evmVersion(); + { + Assembly assembly{evmVersion, true, {}, {}}; + assembly.append(AssemblyItem{0x11223344}); + LinkerObject output = assembly.assemble(); + + Json const program = ethdebug::program("", 0, &assembly, output); + BOOST_REQUIRE(program["instructions"].size() == 1); + BOOST_REQUIRE(program["instructions"][0]["operation"]["mnemonic"] == "PUSH4"); + BOOST_REQUIRE(program["instructions"][0]["operation"]["arguments"][0] == "0x11223344"); + } + { + Assembly assembly{evmVersion, true, {}, {}}; + assembly.append(AssemblyItem{Instruction::PUSH0}); + assembly.append(AssemblyItem{0x1122334455}); + LinkerObject output = assembly.assemble(); + + Json const program = ethdebug::program("", 0, &assembly, output); + BOOST_REQUIRE(program["instructions"].size() == 2); + BOOST_REQUIRE(program["instructions"][0]["operation"]["mnemonic"] == "PUSH0"); + BOOST_REQUIRE(!program["instructions"][0]["operation"].contains("arguments")); + BOOST_REQUIRE(program["instructions"][1]["operation"]["mnemonic"] == "PUSH5"); + BOOST_REQUIRE(program["instructions"][1]["operation"]["arguments"][0] == "0x1122334455"); + } +} + +BOOST_AUTO_TEST_CASE(ethdebug_resources) +{ + Json const resources = ethdebug::resources({"sourceA", "sourceB"}, "version1"); + BOOST_REQUIRE(resources["compilation"]["compiler"]["name"] == "solc"); + BOOST_REQUIRE(resources["compilation"]["compiler"]["version"] == "version1"); + BOOST_REQUIRE(resources["compilation"]["sources"].size() == 2); + BOOST_REQUIRE(resources["compilation"]["sources"][0]["id"] == 0); + BOOST_REQUIRE(resources["compilation"]["sources"][0]["path"] == "sourceA"); + BOOST_REQUIRE(resources["compilation"]["sources"][1]["id"] == 1); + BOOST_REQUIRE(resources["compilation"]["sources"][1]["path"] == "sourceB"); +} + BOOST_AUTO_TEST_SUITE_END() } // end namespaces diff --git a/test/libsolidity/StandardCompiler.cpp b/test/libsolidity/StandardCompiler.cpp index ec3c7db1c847..b17f566613a1 100644 --- a/test/libsolidity/StandardCompiler.cpp +++ b/test/libsolidity/StandardCompiler.cpp @@ -22,6 +22,7 @@ #include #include +#include #include #include #include @@ -2232,6 +2233,46 @@ BOOST_AUTO_TEST_CASE(ethdebug_ethdebug_output) } } +BOOST_DATA_TEST_CASE(ethdebug_output_instructions_smoketest, boost::unit_test::data::make({"deployedBytecode", "bytecode"}), bytecodeType) +{ + frontend::StandardCompiler compiler; + Json result = compiler.compile(generateStandardJson(true, {}, Json::array({std::string("evm.") + bytecodeType + ".ethdebug"}))); + BOOST_REQUIRE(result["contracts"]["fileA"]["C"]["evm"][bytecodeType].contains("ethdebug")); + bool creation = std::string(bytecodeType) == "bytecode"; + Json ethdebugInstructionsToCheck = result["contracts"]["fileA"]["C"]["evm"][bytecodeType]["ethdebug"]; + BOOST_REQUIRE(ethdebugInstructionsToCheck["contract"]["definition"]["source"]["id"] == 0); + BOOST_REQUIRE(ethdebugInstructionsToCheck["contract"]["name"] == "C"); + BOOST_REQUIRE(ethdebugInstructionsToCheck["environment"] == (creation ? "create" : "call")); + BOOST_REQUIRE(ethdebugInstructionsToCheck["instructions"].is_array()); + for (auto const& instruction: ethdebugInstructionsToCheck["instructions"]) + { + BOOST_REQUIRE(instruction.contains("offset")); + BOOST_REQUIRE(instruction.contains("operation")); + BOOST_REQUIRE(instruction["operation"].contains("mnemonic")); + BOOST_REQUIRE(instruction["context"]["code"]["range"].contains("length")); + BOOST_REQUIRE(instruction["context"]["code"]["range"].contains("offset")); + BOOST_REQUIRE(instruction["context"]["code"]["source"].contains("id")); + std::string mnemonic = instruction["operation"]["mnemonic"]; + if (mnemonic.find("PUSH") != std::string::npos) + { + size_t bytesToPush = boost::lexical_cast(mnemonic.substr(4)); + if (bytesToPush > 0) + { + BOOST_REQUIRE(instruction["operation"].contains("arguments")); + BOOST_REQUIRE(instruction["operation"]["arguments"].is_array()); + BOOST_REQUIRE(instruction["operation"]["arguments"].size() == 1); + std::string argument = instruction["operation"]["arguments"][0]; + BOOST_REQUIRE(argument.length() % 2 == 0); + BOOST_REQUIRE(bytesToPush == (argument.length() - 2) / 2); // remove "0x" and calculate actual byte size from hex. + } + else + BOOST_REQUIRE(!instruction["operation"].contains("arguments")); + } + else + BOOST_REQUIRE(!instruction["operation"].contains("arguments")); + } +} + BOOST_AUTO_TEST_SUITE_END() } // end namespaces From 2abfe0baa9f4b64521adf271984951d6760b0453 Mon Sep 17 00:00:00 2001 From: Alexander Arlt Date: Tue, 11 Mar 2025 02:07:46 +0100 Subject: [PATCH 0862/1022] ethdebug: correct handling of abstract contracts. --- libevmasm/Ethdebug.cpp | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/libevmasm/Ethdebug.cpp b/libevmasm/Ethdebug.cpp index 7b5de2ba9b59..6e635ef57952 100644 --- a/libevmasm/Ethdebug.cpp +++ b/libevmasm/Ethdebug.cpp @@ -25,32 +25,27 @@ using namespace solidity::evmasm::ethdebug; namespace { -Json programInstructions(Assembly const* _assembly, LinkerObject const& _linkerObject, unsigned _sourceId) +Json programInstructions(Assembly const& _assembly, LinkerObject const& _linkerObject, unsigned _sourceId) { - // e.g. interfaces don't have a valid assembly object. - if (_assembly) - { - solUnimplementedAssert(_assembly->eofVersion() == std::nullopt, "ethdebug does not yet support EOF."); - solUnimplementedAssert(_assembly->codeSections().size() == 1, "ethdebug does not yet support multiple code-sections."); - for (auto const& instruction: _assembly->codeSections()[0].items) - solUnimplementedAssert(instruction.type() != VerbatimBytecode, "Verbatim bytecode is currently not supported by ethdebug."); - } + solUnimplementedAssert(_assembly.eofVersion() == std::nullopt, "ethdebug does not yet support EOF."); + solUnimplementedAssert(_assembly.codeSections().size() == 1, "ethdebug does not yet support multiple code-sections."); + for (auto const& instruction: _assembly.codeSections()[0].items) + solUnimplementedAssert(instruction.type() != VerbatimBytecode, "Verbatim bytecode is currently not supported by ethdebug."); solAssert(_linkerObject.codeSectionLocations.size() == 1); solAssert(_linkerObject.codeSectionLocations[0].end <= _linkerObject.bytecode.size()); Json instructions = Json::array(); for (size_t i = 0; i < _linkerObject.codeSectionLocations[0].instructionLocations.size(); ++i) { - solAssert(_assembly); LinkerObject::InstructionLocation currentInstruction = _linkerObject.codeSectionLocations[0].instructionLocations[i]; size_t start = currentInstruction.start; size_t end = currentInstruction.end; size_t assemblyItemIndex = currentInstruction.assemblyItemIndex; solAssert(end <= _linkerObject.bytecode.size()); solAssert(start < end); - solAssert(assemblyItemIndex < _assembly->codeSections().at(0).items.size()); + solAssert(assemblyItemIndex < _assembly.codeSections().at(0).items.size()); Json operation = Json::object(); - operation["mnemonic"] = instructionInfo(static_cast(_linkerObject.bytecode[start]), _assembly->evmVersion()).name; + operation["mnemonic"] = instructionInfo(static_cast(_linkerObject.bytecode[start]), _assembly.evmVersion()).name; static size_t constexpr instructionSize = 1; if (start + instructionSize < end) { @@ -61,7 +56,7 @@ Json programInstructions(Assembly const* _assembly, LinkerObject const& _linkerO solAssert(!argumentData.empty()); operation["arguments"] = Json::array({util::toHex(argumentData, util::HexPrefix::Add)}); } - langutil::SourceLocation const& location = _assembly->codeSections().at(0).items.at(assemblyItemIndex).location(); + langutil::SourceLocation const& location = _assembly.codeSections().at(0).items.at(assemblyItemIndex).location(); Json instruction = Json::object(); instruction["offset"] = start; instruction["operation"] = operation; @@ -90,8 +85,11 @@ Json ethdebug::program(std::string_view _name, unsigned _sourceId, Assembly cons result["contract"]["definition"] = Json::object(); result["contract"]["definition"]["source"] = Json::object(); result["contract"]["definition"]["source"]["id"] = _sourceId; - result["environment"] = (!_assembly || _assembly->isCreation()) ? "create" : "call"; - result["instructions"] = programInstructions(_assembly, _linkerObject, _sourceId); + if (_assembly) + { + result["environment"] = _assembly->isCreation() ? "create" : "call"; + result["instructions"] = programInstructions(*_assembly, _linkerObject, _sourceId); + } return result; } From 9c80b9b62b9ac0d60d6d76affcdcc86659c95072 Mon Sep 17 00:00:00 2001 From: Matheus Aguiar Date: Tue, 4 Mar 2025 00:18:42 -0300 Subject: [PATCH 0863/1022] Update and add tests --- .../storageLayoutSpecifier/warning_near_the_storage_end.sol | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 test/libsolidity/syntaxTests/storageLayoutSpecifier/warning_near_the_storage_end.sol diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/warning_near_the_storage_end.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/warning_near_the_storage_end.sol new file mode 100644 index 000000000000..b1647e463cb6 --- /dev/null +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/warning_near_the_storage_end.sol @@ -0,0 +1,6 @@ +contract A layout at 2**256 - 2**64 {} +contract C layout at 2**256 - 2**65 { + uint[2**63] x; + uint[2**63] y; +} +// ---- From 529795019c766e2aced54455ce613254b1865df9 Mon Sep 17 00:00:00 2001 From: Matheus Aguiar Date: Tue, 4 Mar 2025 00:19:40 -0300 Subject: [PATCH 0864/1022] Warn when layout base is near the end of storage --- .../analysis/PostTypeContractLevelChecker.cpp | 61 +++++++++++++++++++ .../analysis/PostTypeContractLevelChecker.h | 2 + ...e_array_with_transient_state_variables.sol | 1 + .../contract_at_storage_end.sol | 1 + ...age_end_with_transient_state_variables.sol | 1 + .../intermediate_operation_out_of_range.sol | 1 + .../layout_specification_max_value.sol | 1 + .../warning_near_the_storage_end.sol | 2 + 8 files changed, 70 insertions(+) diff --git a/libsolidity/analysis/PostTypeContractLevelChecker.cpp b/libsolidity/analysis/PostTypeContractLevelChecker.cpp index 657f39284544..c7b7b0961622 100644 --- a/libsolidity/analysis/PostTypeContractLevelChecker.cpp +++ b/libsolidity/analysis/PostTypeContractLevelChecker.cpp @@ -29,6 +29,8 @@ #include #include +#include + #include using namespace solidity; @@ -76,6 +78,8 @@ bool PostTypeContractLevelChecker::check(ContractDefinition const& _contract) if (_contract.storageLayoutSpecifier()) checkStorageLayoutSpecifier(_contract); + warnStorageLayoutBaseNearStorageEnd(_contract); + return !Error::containsErrors(m_errorReporter.errors()); } @@ -145,3 +149,60 @@ void PostTypeContractLevelChecker::checkStorageLayoutSpecifier(ContractDefinitio "Contract extends past the end of storage when this base slot value is specified." ); } + +namespace +{ + +VariableDeclaration const* findLastStorageVariable(ContractDefinition const& _contract) +{ + for (ContractDefinition const* baseContract: ranges::actions::reverse(_contract.annotation().linearizedBaseContracts)) + for (VariableDeclaration const* stateVariable: ranges::actions::reverse(baseContract->stateVariables())) + if (stateVariable->referenceLocation() == VariableDeclaration::Location::Unspecified) + return stateVariable; + + return nullptr; +} + +} + +void PostTypeContractLevelChecker::warnStorageLayoutBaseNearStorageEnd(ContractDefinition const& _contract) +{ + // In case of most errors the warning is pointless. E.g. if we're already past storage end. + // If the errors were in the layout specifier, we may not even be able to get values to validate. + if (Error::containsErrors(m_errorReporter.errors())) + return; + + bigint storageSize = contractStorageSizeUpperBound(_contract, VariableDeclaration::Location::Unspecified); + u256 baseSlot = layoutBaseForInheritanceHierarchy(_contract, DataLocation::Storage); + solAssert(baseSlot + storageSize <= std::numeric_limits::max()); + + if ( + u256 slotsLeft = std::numeric_limits::max() - baseSlot - u256(storageSize); + slotsLeft <= u256(1) << 64 + ) + { + auto const& location = _contract.storageLayoutSpecifier() ? + _contract.storageLayoutSpecifier()->location() : + _contract.location(); + + VariableDeclaration const* lastStorageVariable = findLastStorageVariable(_contract); + + auto errorID = 3495_error; + std::string errorMsg = "This contract is very close to the end of storage. This limits its future upgradability."; + if (lastStorageVariable) + m_errorReporter.warning( + errorID, + location, + errorMsg, + SecondarySourceLocation{}.append( + fmt::format( + "There are {} storage slots between this state variable and the end of storage.", + formatNumberReadable(slotsLeft) + ), + lastStorageVariable->location() + ) + ); + else + m_errorReporter.warning(errorID, location, errorMsg); + } +} diff --git a/libsolidity/analysis/PostTypeContractLevelChecker.h b/libsolidity/analysis/PostTypeContractLevelChecker.h index 2fa2cb11bfd3..ca7247c4671a 100644 --- a/libsolidity/analysis/PostTypeContractLevelChecker.h +++ b/libsolidity/analysis/PostTypeContractLevelChecker.h @@ -52,6 +52,8 @@ class PostTypeContractLevelChecker void checkStorageLayoutSpecifier(ContractDefinition const& _contract); + void warnStorageLayoutBaseNearStorageEnd(ContractDefinition const& _contract); + langutil::ErrorReporter& m_errorReporter; }; diff --git a/test/libsolidity/syntaxTests/largeTypes/max_size_array_with_transient_state_variables.sol b/test/libsolidity/syntaxTests/largeTypes/max_size_array_with_transient_state_variables.sol index 280fb81c8e18..43acb5b14f7e 100644 --- a/test/libsolidity/syntaxTests/largeTypes/max_size_array_with_transient_state_variables.sol +++ b/test/libsolidity/syntaxTests/largeTypes/max_size_array_with_transient_state_variables.sol @@ -5,4 +5,5 @@ contract C { // ==== // EVMVersion: >=cancun // ---- +// Warning 3495: (0-60): This contract is very close to the end of storage. This limits its future upgradability. // Warning 7325: (17-33): Type uint256[115792089237316195423570985008687907853269984665640564039457584007913129639935] covers a large part of storage and thus makes collisions likely. Either use mappings or dynamic arrays and allow their size to be increased only in small quantities per transaction. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/contract_at_storage_end.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/contract_at_storage_end.sol index 29733c9ca96a..e215c26cff3e 100644 --- a/test/libsolidity/syntaxTests/storageLayoutSpecifier/contract_at_storage_end.sol +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/contract_at_storage_end.sol @@ -1,3 +1,4 @@ contract C layout at 2**256 - 1 { } // ---- +// Warning 3495: (11-31): This contract is very close to the end of storage. This limits its future upgradability. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/contract_at_storage_end_with_transient_state_variables.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/contract_at_storage_end_with_transient_state_variables.sol index fb1008616162..89012b781d80 100644 --- a/test/libsolidity/syntaxTests/storageLayoutSpecifier/contract_at_storage_end_with_transient_state_variables.sol +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/contract_at_storage_end_with_transient_state_variables.sol @@ -6,3 +6,4 @@ contract C layout at 2**256 - 1 { // ==== // EVMVersion: >=cancun // ---- +// Warning 3495: (11-31): This contract is very close to the end of storage. This limits its future upgradability. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/intermediate_operation_out_of_range.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/intermediate_operation_out_of_range.sol index f74c45ed76f1..dd298820cd93 100644 --- a/test/libsolidity/syntaxTests/storageLayoutSpecifier/intermediate_operation_out_of_range.sol +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/intermediate_operation_out_of_range.sol @@ -1,3 +1,4 @@ contract A layout at (2**256 + 1) * 2 - 2**256 - 3 {} contract B layout at (2**2 - 2**3) * (2**5 - 2**8) {} // ---- +// Warning 3495: (11-51): This contract is very close to the end of storage. This limits its future upgradability. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specification_max_value.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specification_max_value.sol index 793b5b2689cf..cfdefa1ed144 100644 --- a/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specification_max_value.sol +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specification_max_value.sol @@ -1,2 +1,3 @@ contract C layout at 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF {} // ---- +// Warning 3495: (11-87): This contract is very close to the end of storage. This limits its future upgradability. diff --git a/test/libsolidity/syntaxTests/storageLayoutSpecifier/warning_near_the_storage_end.sol b/test/libsolidity/syntaxTests/storageLayoutSpecifier/warning_near_the_storage_end.sol index b1647e463cb6..5d1f777fd3c0 100644 --- a/test/libsolidity/syntaxTests/storageLayoutSpecifier/warning_near_the_storage_end.sol +++ b/test/libsolidity/syntaxTests/storageLayoutSpecifier/warning_near_the_storage_end.sol @@ -4,3 +4,5 @@ contract C layout at 2**256 - 2**65 { uint[2**63] y; } // ---- +// Warning 3495: (11-35): This contract is very close to the end of storage. This limits its future upgradability. +// Warning 3495: (50-74): This contract is very close to the end of storage. This limits its future upgradability. From 05b0efbd04eafec21a43f08925efb82e0c7a1023 Mon Sep 17 00:00:00 2001 From: Matheus Aguiar Date: Tue, 25 Feb 2025 17:04:22 -0300 Subject: [PATCH 0865/1022] Storage layout specifier docs --- docs/contracts.rst | 1 + docs/contracts/custom-storage-layout.rst | 50 +++++++++++++++++++++ docs/internals/layout_in_storage.rst | 55 ++++++++++++++++++++++++ 3 files changed, 106 insertions(+) create mode 100644 docs/contracts/custom-storage-layout.rst diff --git a/docs/contracts.rst b/docs/contracts.rst index 588b1da00d0b..b47b4aa4552a 100644 --- a/docs/contracts.rst +++ b/docs/contracts.rst @@ -23,6 +23,7 @@ There is no "cron" concept in Ethereum to call a function at a particular event .. include:: contracts/transient-storage.rst .. include:: contracts/constant-state-variables.rst +.. include:: contracts/custom-storage-layout.rst .. include:: contracts/functions.rst .. include:: contracts/events.rst diff --git a/docs/contracts/custom-storage-layout.rst b/docs/contracts/custom-storage-layout.rst new file mode 100644 index 000000000000..484ca6a8b8f1 --- /dev/null +++ b/docs/contracts/custom-storage-layout.rst @@ -0,0 +1,50 @@ +.. index:: ! custom storage layout, ! storage layout specifier, ! layout at, ! base slot + +.. _custom-storage-layout: + +********************* +Custom Storage Layout +********************* + +Contracts can define an arbitrary base slot for its own storage. +The contract's state variables, including those inherited from base contracts, +will be stored from the specified slot instead of the default slot zero. + +.. code-block:: solidity + + // SPDX-License-Identifier: GPL-3.0 + pragma solidity ^0.8.29; + + contract C layout at 0xABCD + 0x1234 { } + +As the previous example shows, this can be done by using ``layout at `` +in the header of a contract definition. + +The layout specifier can be placed either before or after the inheritance specifier, and at most once. +The ``base-slot-expression`` must be an :ref:`integer literal` expression +that can be evaluated at compile time and yield a value in the range of ``uint256``. + +In the case of a custom storage layout specification which places the contract near the storage end, +the number of slots available for static objects is determined by ``max storage size - base slot`` and +the compiler can detect whether the contract extends past the end. +For dynamic typed variables, they are allocated in random locations of the storage, including those before +the layout base slot. +It is also important to mention that, in cases where the contract is near the end of storage, there are +risks related to upgradeability and inline assembly access beyond allocated space. + +The location of a contract's state variable is determined by its position in the hierarchy tree. +Inherited variables will be stored before the state variables declared by the contract itself and +that changes the slots where they should be placed. +Similarly, when a contract specifies a custom storage layout, not only its own storage variables are shifted, +but also all other variables from contracts in the same inheritance tree. +Thus, the storage layout can only be specified at the top most contract of the inheritance tree, assuring +that all contracts of the tree have their layout base properly adjusted. + +The storage layout cannot be specified for abstract contracts, interfaces and libraries. +Also, it is important to note that it does **not** affect transient state variables. + +Further details are explained later when :ref:`layout of storage variables` are described. + +.. warning:: + The identifiers ``layout`` and ``at`` are not reserved keywords of the Solidity language, but + it is strongly recommended to avoid using them since that may change in the future. \ No newline at end of file diff --git a/docs/internals/layout_in_storage.rst b/docs/internals/layout_in_storage.rst index 557a0a0e2090..aade16fb3a2f 100644 --- a/docs/internals/layout_in_storage.rst +++ b/docs/internals/layout_in_storage.rst @@ -34,6 +34,61 @@ by the above rules, state variables from different contracts do share the same s The elements of structs and arrays are stored after each other, just as if they were given as individual values. +If a contract specifies a :ref:`custom storage layout`, the slots which +the state variables occupy are shifted according the value defined as the layout base. +The custom layout is specified in the most derived contract and, following the order explained +above, starting from the most base-ward contract's variables, all storage slots are adjusted. + +In the following example, contract ``C`` inherits from contracts ``A`` and ``B`` and also +specifies a custom storage base slot. +The result is that all variable storage slots of the inheritance tree will be adjusted according to +the value specified by ``C``. + +.. code-block:: solidity + + // SPDX-License-Identifier: GPL-3.0 + pragma solidity ^0.8.29; + + struct S { + int32 a; + bool b; + } + + contract A { + uint x; + uint transient y; + uint constant w = 10; + uint immutable z = 12; + } + + contract B { + uint16 i; + uint16 j; + S s; + int8 k; + } + + contract C is A, B layout at 42 { + uint8[10] register; + bool flag; + } + +In the example, the storage layout starts with the inherited +state variable ``x`` stored at the specified base slot ``42``. +Transient, constant and immutable variables are stored in separate +locations and, thus, ``y``, ``w`` and ``z``don't interfere with the layout. +The next variables ``i`` and ``j`` need 2 bytes each and can be packed in +the next slot ``43``, at offsets ``0`` and ``2`` respectively. +Since ``s`` is a struct, its two members are packed contiguously, demanding +both 5 bytes. +Even though they still could fit in slot ``43``, structs and static arrays +always start a new slot as well as any other item after them. +So, according to that ``s`` is placed at slot ``44`` and the next variable, +``k`` at slot ``45``. +Then, variable ``register`` which is an array of 10 positions, starts at slot ``46`` +and demands 80 bytes. Finally, variable, ``flag``, start at slot ``47``, because, +as explained before, variables after structs and arrays always start a new slot. + .. warning:: When using elements that are smaller than 32 bytes, your contract's gas usage may be higher. This is because the EVM operates on 32 bytes at a time. Therefore, if the element is smaller From b4f9bb090bd2223771d5470aeb48a587ab5c0a06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Tue, 11 Mar 2025 03:40:14 +0100 Subject: [PATCH 0866/1022] fixup! Storage layout specifier docs --- docs/contracts/custom-storage-layout.rst | 61 +++++++++++++----------- 1 file changed, 34 insertions(+), 27 deletions(-) diff --git a/docs/contracts/custom-storage-layout.rst b/docs/contracts/custom-storage-layout.rst index 484ca6a8b8f1..341975eaca09 100644 --- a/docs/contracts/custom-storage-layout.rst +++ b/docs/contracts/custom-storage-layout.rst @@ -6,45 +6,52 @@ Custom Storage Layout ********************* -Contracts can define an arbitrary base slot for its own storage. +A contract can define an arbitrary location for its storage using the ``layout`` specifier. The contract's state variables, including those inherited from base contracts, -will be stored from the specified slot instead of the default slot zero. +start from the specified base slot instead of the default slot zero. .. code-block:: solidity // SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.29; - contract C layout at 0xABCD + 0x1234 { } + contract C layout at 0xAAAA + 0x11 { + uint[3] x; // Occupies slots 0xAABB..0xAABD + } -As the previous example shows, this can be done by using ``layout at `` -in the header of a contract definition. +As the above example shows, the specifier uses the ``layout at `` syntax +and is located in the header of a contract definition. -The layout specifier can be placed either before or after the inheritance specifier, and at most once. +The layout specifier can be placed either before or after the inheritance specifier, and can appear at most once. The ``base-slot-expression`` must be an :ref:`integer literal` expression -that can be evaluated at compile time and yield a value in the range of ``uint256``. - -In the case of a custom storage layout specification which places the contract near the storage end, -the number of slots available for static objects is determined by ``max storage size - base slot`` and -the compiler can detect whether the contract extends past the end. -For dynamic typed variables, they are allocated in random locations of the storage, including those before -the layout base slot. -It is also important to mention that, in cases where the contract is near the end of storage, there are -risks related to upgradeability and inline assembly access beyond allocated space. - -The location of a contract's state variable is determined by its position in the hierarchy tree. -Inherited variables will be stored before the state variables declared by the contract itself and -that changes the slots where they should be placed. -Similarly, when a contract specifies a custom storage layout, not only its own storage variables are shifted, -but also all other variables from contracts in the same inheritance tree. -Thus, the storage layout can only be specified at the top most contract of the inheritance tree, assuring -that all contracts of the tree have their layout base properly adjusted. +that can be evaluated at compilation time and yields a value in the range of ``uint256``. + +A custom layout cannot make contract's storage "wrap around". +If the selected base slot would push the statically-sized variables past the end of storage, +the compiler will issue an error. +Note that the data areas of dynamically-sized variables are not affected by this check because +their layout is not linear. +Regardless of the base slot used, their locations are calculated in a way that always puts them +within the range of ``uint256`` and their sizes are not known at compilation time. + +While there are no other limits placed on the base slot, it is recommended to avoid locations that are +too close to the end of the address space. +Leaving too little space may complicate contract upgrades or cause problems for contracts that store +additional values past their allocated space using inline assembly. + +The storage layout can only be specified for the topmost contract of an inheritance tree, and +affects locations of all the storage variables in all the contracts in that tree. +Variables are laid out according to the order of their definitions and the +positions of their contracts in the :ref:`linearized inheritance hierarchy` +and a custom base slot preserves their relative positions, shifting them all by the same amount. The storage layout cannot be specified for abstract contracts, interfaces and libraries. -Also, it is important to note that it does **not** affect transient state variables. +Also, it is important to note that it does *not* affect transient state variables. -Further details are explained later when :ref:`layout of storage variables` are described. +For details about storage layout and the effect of the layout specifier on it see +:ref:`layout of storage variables`. .. warning:: - The identifiers ``layout`` and ``at`` are not reserved keywords of the Solidity language, but - it is strongly recommended to avoid using them since that may change in the future. \ No newline at end of file + The identifiers ``layout`` and ``at`` are not yet reserved as keywords in the language. + It is strongly recommended to avoid using them since they will become reserved in a future + breaking release. From a371a4f8fe33c5a8159ad712e35c9d0c2819da42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Tue, 11 Mar 2025 05:17:31 +0100 Subject: [PATCH 0867/1022] fixup! Storage layout specifier docs --- docs/internals/layout_in_storage.rst | 31 ++++++++++++++-------------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/docs/internals/layout_in_storage.rst b/docs/internals/layout_in_storage.rst index aade16fb3a2f..034bfe29e0c2 100644 --- a/docs/internals/layout_in_storage.rst +++ b/docs/internals/layout_in_storage.rst @@ -34,14 +34,16 @@ by the above rules, state variables from different contracts do share the same s The elements of structs and arrays are stored after each other, just as if they were given as individual values. -If a contract specifies a :ref:`custom storage layout`, the slots which -the state variables occupy are shifted according the value defined as the layout base. +If a contract specifies a :ref:`custom storage layout`, the slots assigned +to static storage variables are shifted according the value defined as the layout base. +Locations of dynamic arrays and mappings are also indirectly affected by this due to shifting +of the static slots they are based on. The custom layout is specified in the most derived contract and, following the order explained above, starting from the most base-ward contract's variables, all storage slots are adjusted. In the following example, contract ``C`` inherits from contracts ``A`` and ``B`` and also specifies a custom storage base slot. -The result is that all variable storage slots of the inheritance tree will be adjusted according to +The result is that all storage variable slots of the inheritance tree are adjusted according to the value specified by ``C``. .. code-block:: solidity @@ -74,19 +76,16 @@ the value specified by ``C``. } In the example, the storage layout starts with the inherited -state variable ``x`` stored at the specified base slot ``42``. +state variable ``x`` stored directly inside the base slot (slot ``42``). Transient, constant and immutable variables are stored in separate -locations and, thus, ``y``, ``w`` and ``z``don't interfere with the layout. -The next variables ``i`` and ``j`` need 2 bytes each and can be packed in -the next slot ``43``, at offsets ``0`` and ``2`` respectively. -Since ``s`` is a struct, its two members are packed contiguously, demanding -both 5 bytes. -Even though they still could fit in slot ``43``, structs and static arrays -always start a new slot as well as any other item after them. -So, according to that ``s`` is placed at slot ``44`` and the next variable, -``k`` at slot ``45``. -Then, variable ``register`` which is an array of 10 positions, starts at slot ``46`` -and demands 80 bytes. Finally, variable, ``flag``, start at slot ``47``, because, +locations and, thus, ``y``, ``w`` and ``z`` have no effect on the storage layout. +The next two variables, ``i`` and ``j``, need 2 bytes each and can be packed together into +slot ``43``, at offsets ``0`` and ``2`` respectively. +Since ``s`` is a struct, its two members are packed contiguously, each taking up 5 bytes. +Even though they both would still fit in slot ``43``, structs and arrays always start a new slot. +Therefore, ``s`` is placed in slot ``44`` and the next variable, ``k``, in slot ``45``. +Then, variable ``register`` which is an array of 10 items, gets into slot ``46`` and takes up 80 bytes. +Finally, variable ``flag`` ends up in slot ``47``, because, as explained before, variables after structs and arrays always start a new slot. .. warning:: @@ -518,4 +517,4 @@ Transient Storage Layout "numberOfBytes": "32" } } - } \ No newline at end of file + } From 3d0904796c6b1802ff28840f6944d8bfd2288f97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Tue, 11 Mar 2025 05:17:44 +0100 Subject: [PATCH 0868/1022] fixup! Storage layout specifier docs --- docs/internals/layout_in_storage.rst | 32 ++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/docs/internals/layout_in_storage.rst b/docs/internals/layout_in_storage.rst index 034bfe29e0c2..c9c5f6ee3721 100644 --- a/docs/internals/layout_in_storage.rst +++ b/docs/internals/layout_in_storage.rst @@ -88,6 +88,38 @@ Then, variable ``register`` which is an array of 10 items, gets into slot ``46`` Finally, variable ``flag`` ends up in slot ``47``, because, as explained before, variables after structs and arrays always start a new slot. +Overall the storage and transient storage layouts of contract ``C`` can be illustrated as follows: + +- Storage: + :: + + 42 [xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx] + 43 [ jjii] + 44 [ baaaa] + 45 [ k] + 46 [ rrrrrrrrrr] + 47 [ f] + +- Transient storage: + :: + + 00 [yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy] + +Note that the storage specifier affects ``A`` and ``B`` only as a part of ``C``'s inheritance hierarchy. +When deployed independently, their storage starts at ``0``: + +- Storage layout of ``A``: + :: + + 00 [xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx] + +- Storage layout of ``B``: + :: + + 00 [ jjii] + 01 [ baaaa] + 02 [ k] + .. warning:: When using elements that are smaller than 32 bytes, your contract's gas usage may be higher. This is because the EVM operates on 32 bytes at a time. Therefore, if the element is smaller From e633eb411d71eaa1b46d774ded876d586420836e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Tue, 11 Mar 2025 06:05:48 +0100 Subject: [PATCH 0869/1022] fixup! Storage layout specifier docs --- docs/internals/layout_in_storage.rst | 80 +++++++++++++++++----------- 1 file changed, 49 insertions(+), 31 deletions(-) diff --git a/docs/internals/layout_in_storage.rst b/docs/internals/layout_in_storage.rst index c9c5f6ee3721..319aa4d8b1da 100644 --- a/docs/internals/layout_in_storage.rst +++ b/docs/internals/layout_in_storage.rst @@ -52,58 +52,74 @@ the value specified by ``C``. pragma solidity ^0.8.29; struct S { - int32 a; - bool b; + int32 x; + bool y; } contract A { - uint x; - uint transient y; - uint constant w = 10; - uint immutable z = 12; + uint a; + uint128 transient b; + uint constant c = 10; + uint immutable d = 12; } contract B { - uint16 i; - uint16 j; + uint8[] e; + mapping(uint => S) f; + uint16 g; + uint16 h; + bytes16 transient i; S s; int8 k; } contract C is A, B layout at 42 { - uint8[10] register; - bool flag; + bytes21 l; + uint8[10] m; + bytes5[8] n; + bytes5 o; } In the example, the storage layout starts with the inherited -state variable ``x`` stored directly inside the base slot (slot ``42``). +state variable ``a`` stored directly inside the base slot (slot ``42``). Transient, constant and immutable variables are stored in separate -locations and, thus, ``y``, ``w`` and ``z`` have no effect on the storage layout. -The next two variables, ``i`` and ``j``, need 2 bytes each and can be packed together into -slot ``43``, at offsets ``0`` and ``2`` respectively. +locations, and thus, ``b``, ``i``, ``c`` and ``d`` have no effect on the storage layout. +Then we get to the dynamic array ``e`` and mapping ``f``. +They both reserve a whole slot whose address will be used to :ref:`calculate` +the location where their data is actually stored. +The slot cannot be shared with any other variable, because the resulting addresses must be unique. +The next two variables, ``g`` and ``h``, need 2 bytes each and can be packed together into +slot ``45``, at offsets ``0`` and ``2`` respectively. Since ``s`` is a struct, its two members are packed contiguously, each taking up 5 bytes. -Even though they both would still fit in slot ``43``, structs and arrays always start a new slot. -Therefore, ``s`` is placed in slot ``44`` and the next variable, ``k``, in slot ``45``. -Then, variable ``register`` which is an array of 10 items, gets into slot ``46`` and takes up 80 bytes. -Finally, variable ``flag`` ends up in slot ``47``, because, -as explained before, variables after structs and arrays always start a new slot. +Even though they both would still fit in slot ``45``, structs and arrays always start a new slot. +Therefore, ``s`` is placed in slot ``46`` and the next variable, ``k``, in slot ``47``. +Base contracts, on the other hand, can share slots with derived ones, so ``l`` does not require an new one. +Then variable ``m``, which is an array of 10 items, gets into slot ``48`` and takes up 10 bytes. +``n`` is an array as well, but due to the size of its items, cannot fill its first slot perfectly +and spills over to the next one. +Finally, variable ``o`` ends up in slot ``51``, even though it is of the same type as items of ``n``. +As explained before, variables after structs and arrays always start a new slot. -Overall the storage and transient storage layouts of contract ``C`` can be illustrated as follows: +Putting it all together, the storage and transient storage layouts of contract ``C`` can be illustrated as follows: - Storage: :: - 42 [xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx] - 43 [ jjii] - 44 [ baaaa] - 45 [ k] - 46 [ rrrrrrrrrr] - 47 [ f] + 42 [aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa] + 43 [eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee] + 44 [ffffffffffffffffffffffffffffffff] + 45 [ hhgg] + 46 [ yxxxx] + 47 [ lllllllllllllllllllllk] + 48 [ mmmmmmmmmm] + 49 [ nnnnnnnnnnnnnnnnnnnnnnnnnnnnnn] + 50 [ nnnnnnnnnn] + 51 [ ooooo] - Transient storage: :: - 00 [yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy] + 00 [iiiiiiiiiiiiiiiibbbbbbbbbbbbbbbb] Note that the storage specifier affects ``A`` and ``B`` only as a part of ``C``'s inheritance hierarchy. When deployed independently, their storage starts at ``0``: @@ -111,14 +127,16 @@ When deployed independently, their storage starts at ``0``: - Storage layout of ``A``: :: - 00 [xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx] + 00 [aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa] - Storage layout of ``B``: :: - 00 [ jjii] - 01 [ baaaa] - 02 [ k] + 00 [eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee] + 01 [ffffffffffffffffffffffffffffffff] + 02 [ hhgg] + 03 [ yxxxx] + 04 [ k] .. warning:: When using elements that are smaller than 32 bytes, your contract's gas usage may be higher. From de966a76f726fd341ee930eb16b92962a1908b59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Tue, 11 Mar 2025 06:14:31 +0100 Subject: [PATCH 0870/1022] fixup! Storage layout specifier docs --- docs/contracts/custom-storage-layout.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/contracts/custom-storage-layout.rst b/docs/contracts/custom-storage-layout.rst index 341975eaca09..224e77425084 100644 --- a/docs/contracts/custom-storage-layout.rst +++ b/docs/contracts/custom-storage-layout.rst @@ -27,9 +27,9 @@ The ``base-slot-expression`` must be an :ref:`integer literal that can be evaluated at compilation time and yields a value in the range of ``uint256``. A custom layout cannot make contract's storage "wrap around". -If the selected base slot would push the statically-sized variables past the end of storage, +If the selected base slot would push the static variables past the end of storage, the compiler will issue an error. -Note that the data areas of dynamically-sized variables are not affected by this check because +Note that the data areas of dynamic arrays and mappings are not affected by this check because their layout is not linear. Regardless of the base slot used, their locations are calculated in a way that always puts them within the range of ``uint256`` and their sizes are not known at compilation time. From 3199cca75f5ad1b29a96eab9177c6c67bb7ac72c Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Tue, 11 Mar 2025 13:25:31 +0100 Subject: [PATCH 0871/1022] Bump vendored dependencies post-release --- ReleaseChecklist.md | 1 + 1 file changed, 1 insertion(+) diff --git a/ReleaseChecklist.md b/ReleaseChecklist.md index 758ef79ddaa4..f55384230aa4 100644 --- a/ReleaseChecklist.md +++ b/ReleaseChecklist.md @@ -121,4 +121,5 @@ At least a day before the release: - [ ] Share the announcement on [`#solidity` channel on Matrix](https://matrix.to/#/#ethereum_solidity:gitter.im) - [ ] Share the announcement on [`#solc-tooling`](https://matrix.to/#/#solc-tooling:matrix.org) - [ ] If anything went wrong this time, mention it in [Learning from Past Releases](https://notes.ethereum.org/@solidity/release-mistakes). + - [ ] Bump vendored dependencies. - [ ] Lean back, wait for bug reports and repeat from step 1 :). From 44533c991db9058278686372b38cb9c82f5e5757 Mon Sep 17 00:00:00 2001 From: flylai Date: Thu, 27 Feb 2025 20:58:46 +0800 Subject: [PATCH 0872/1022] Correct Chinese translation URL --- docs/index.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/index.rst b/docs/index.rst index a60dc1b84d46..11765d3be559 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -89,7 +89,7 @@ The English version stands as a reference. You can switch between languages by clicking on the flyout menu in the bottom-left corner and selecting the preferred language. -* `Chinese `_ +* `Chinese `_ * `French `_ * `Indonesian `_ * `Japanese `_ From d85833e5f8ebb16729cfdfc46787fe59970b2786 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Tue, 11 Mar 2025 14:39:11 +0100 Subject: [PATCH 0873/1022] docs: fix broken link for apeworkx tool --- docs/resources.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/resources.rst b/docs/resources.rst index e8e8fed5880b..7c8d61afacf1 100644 --- a/docs/resources.rst +++ b/docs/resources.rst @@ -19,7 +19,7 @@ General Resources Integrated (Ethereum) Development Environments ============================================== -* `Ape `_ +* `Ape `_ A Python-based web3 development tool for compiling, testing, and interacting with smart contracts. * `Brownie `_ From 90719b22b40794ccccd1d5ba58ff4c1d48d0f18c Mon Sep 17 00:00:00 2001 From: Nikola Matic Date: Tue, 11 Mar 2025 15:44:22 +0100 Subject: [PATCH 0874/1022] Fix changelog for upcoming release --- Changelog.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Changelog.md b/Changelog.md index b14ebb2c157f..e213ab437e35 100644 --- a/Changelog.md +++ b/Changelog.md @@ -10,8 +10,8 @@ Compiler Features: * EVM: Support for the EVM version "Osaka". * EVM Assembly Import: Allow enabling opcode-based optimizer. * General: The experimental EOF backend implements a subset of EOF sufficient to compile arbitrary high-level Solidity syntax via IR with optimization enabled. - * SMTChecker: Support `block.blobbasefee` and `blobhash`. - * SMTChecker: The option `--model-checker-print-query` no longer requires `--model-checker-solvers smtlib2`. + * SMTChecker: Support ``block.blobbasefee`` and ``blobhash``. + * SMTChecker: The option ``--model-checker-print-query`` no longer requires ``--model-checker-solvers smtlib2``. * SMTChecker: Z3 is now a runtime dependency, not a build dependency (except for emscripten build). * Yul Parser: Make name clash with a builtin a non-fatal error. @@ -30,7 +30,7 @@ Bugfixes: * SMTChecker: Fix SMT logic error when translating invariants involving array store and select operations. * SMTChecker: Fix wrong encoding of string literals as arguments of ``ecrecover`` precompile. * Standard JSON Interface: Fix ``generatedSources`` and ``sourceMap`` being generated internally even when not requested. - * TypeChecker: Fix supurious compilation errors due to incorrect computation of contract storage size which erroneously included transient storage variables. + * TypeChecker: Fix spurious compilation errors due to incorrect computation of contract storage size which erroneously included transient storage variables. * Yul: Fix internal compiler error when a code generation error should be reported instead. * Yul Optimizer: Fix failing debug assertion due to dereferencing of an empty ``optional`` value. From 0c45a5e9129c587a0b07be9937286d50d44fa6c8 Mon Sep 17 00:00:00 2001 From: Matheus Aguiar Date: Tue, 11 Mar 2025 12:41:02 -0300 Subject: [PATCH 0875/1022] Update changelog and bugs by version --- Changelog.md | 2 +- docs/bugs_by_version.json | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/Changelog.md b/Changelog.md index e213ab437e35..b1ddcacf6c94 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,4 +1,4 @@ -### 0.8.29 (unreleased) +### 0.8.29 (2025-03-12) Language Features: * Allow relocating contract storage to an arbitrary location. diff --git a/docs/bugs_by_version.json b/docs/bugs_by_version.json index 2c3b6487ae50..60fcdd049a0f 100644 --- a/docs/bugs_by_version.json +++ b/docs/bugs_by_version.json @@ -1906,6 +1906,10 @@ "bugs": [], "released": "2024-10-09" }, + "0.8.29": { + "bugs": [], + "released": "2025-03-12" + }, "0.8.3": { "bugs": [ "FullInlinerNonExpressionSplitArgumentEvaluationOrder", From a61cbb4be63db227cd82ae89181cef33e547b53c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Tue, 11 Mar 2025 18:56:13 +0100 Subject: [PATCH 0876/1022] Document the eofVersion field in StandardJSON and metadata --- docs/metadata.rst | 2 ++ docs/using-the-compiler.rst | 3 +++ 2 files changed, 5 insertions(+) diff --git a/docs/metadata.rst b/docs/metadata.rst index a44d9875388a..063936a9dcde 100644 --- a/docs/metadata.rst +++ b/docs/metadata.rst @@ -134,6 +134,8 @@ explanatory purposes. }, // Required for Solidity. "evmVersion": "london", + // Optional: Only present if not null. + "eofVersion": 1, // Required for Solidity: Addresses for libraries used. "libraries": { "MyLib": "0x123123..." diff --git a/docs/using-the-compiler.rst b/docs/using-the-compiler.rst index 97db1d7ceb0a..f1b33c648220 100644 --- a/docs/using-the-compiler.rst +++ b/docs/using-the-compiler.rst @@ -358,6 +358,9 @@ Input Description // tangerineWhistle, spuriousDragon, byzantium, constantinople, // petersburg, istanbul, berlin, london, paris, shanghai, cancun (default), prague (experimental) or osaka (experimental). "evmVersion": "cancun", + // EVM Object Format version to compile for (optional, experimental). + // Currently the only valid value is 1. If not specified, legacy non-EOF bytecode will be generated. + "eofVersion": null, // Optional: Change compilation pipeline to go through the Yul intermediate representation. // This is false by default. "viaIR": true, From 643caa3625570f69722bb92cc3f04dcad5a9d462 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Tue, 11 Mar 2025 18:56:44 +0100 Subject: [PATCH 0877/1022] Mark the evmVersion field in StandardJSON as optional --- docs/using-the-compiler.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/using-the-compiler.rst b/docs/using-the-compiler.rst index f1b33c648220..4984d999df27 100644 --- a/docs/using-the-compiler.rst +++ b/docs/using-the-compiler.rst @@ -353,7 +353,7 @@ Input Description } } }, - // Version of the EVM to compile for. + // Version of the EVM to compile for (optional). // Affects type checking and code generation. Can be homestead, // tangerineWhistle, spuriousDragon, byzantium, constantinople, // petersburg, istanbul, berlin, london, paris, shanghai, cancun (default), prague (experimental) or osaka (experimental). From 6738ce6f3379bbf1c2d5b2fff768d21913aa4d97 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Wed, 12 Mar 2025 11:49:55 +0100 Subject: [PATCH 0878/1022] bump fmtlib to 11.1.4 --- deps/fmtlib | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps/fmtlib b/deps/fmtlib index 0c9fce2ffefe..123913715afe 160000 --- a/deps/fmtlib +++ b/deps/fmtlib @@ -1 +1 @@ -Subproject commit 0c9fce2ffefecfdce794e1859584e25877b7b592 +Subproject commit 123913715afeb8a437e6388b4473fcc4753e1c9a From 363f1ae1dedbf47528dd1d76065032e1ed367b2b Mon Sep 17 00:00:00 2001 From: Matheus Aguiar Date: Tue, 11 Mar 2025 13:09:38 -0300 Subject: [PATCH 0879/1022] Set next version 0.8.30 --- CMakeLists.txt | 2 +- Changelog.md | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d95b7213ebe6..5b39878f26d3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -21,7 +21,7 @@ include(EthPolicy) eth_policy() # project name and version should be set after cmake_policy CMP0048 -set(PROJECT_VERSION "0.8.29") +set(PROJECT_VERSION "0.8.30") # OSX target needed in order to support std::visit set(CMAKE_OSX_DEPLOYMENT_TARGET "10.14") project(solidity VERSION ${PROJECT_VERSION} LANGUAGES C CXX) diff --git a/Changelog.md b/Changelog.md index b1ddcacf6c94..47334fd3dacd 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,3 +1,14 @@ +### 0.8.30 (unreleased) + +Language Features: + + +Compiler Features: + + +Bugfixes: + + ### 0.8.29 (2025-03-12) Language Features: From c84cac865295b87caa273b3ed8aaa31b0b121d99 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Wed, 12 Mar 2025 11:44:14 +0100 Subject: [PATCH 0880/1022] release checklist: mention buildx as requirement for docker_deploy_manual --- ReleaseChecklist.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ReleaseChecklist.md b/ReleaseChecklist.md index f55384230aa4..301cf963e81f 100644 --- a/ReleaseChecklist.md +++ b/ReleaseChecklist.md @@ -6,6 +6,7 @@ - [ ] DockerHub account with push rights to the [``solc`` image](https://hub.docker.com/r/ethereum/solc). - [ ] Launchpad (Ubuntu One) account with a membership in the ["Ethereum" team](https://launchpad.net/~ethereum) and a gnupg key for your email in the ``ethereum.org`` domain (has to be version 1, gpg2 won't work). + - [ ] Ubuntu/Debian dependencies of the Docker script: ``docker-buildx``. - [ ] Ubuntu/Debian dependencies of the PPA scripts: ``devscripts``, ``debhelper``, ``dput``, ``git``, ``wget``, ``ca-certificates``. - [ ] [npm Registry](https://www.npmjs.com) account added as a collaborator for the [``solc`` package](https://www.npmjs.com/package/solc). - [ ] Access to the [solidity_lang Twitter account](https://twitter.com/solidity_lang). @@ -79,6 +80,7 @@ At least a day before the release: - [ ] Update the version and the hash (``sha256sum solidity_$VERSION.tar.gz``) in the [``solidity`` formula in Homebrew core repository](https://github.com/Homebrew/homebrew-core/blob/master/Formula/s/solidity.rb). ### Docker + - [ ] Make sure ``docker-buildx`` is installed. - [ ] Run ``./scripts/docker_deploy_manual.sh v$VERSION``. ### PPA From 40a4d5d420006168e6c73a1a27a9159cb0b515f0 Mon Sep 17 00:00:00 2001 From: Ocenka Date: Fri, 14 Mar 2025 12:28:24 +0000 Subject: [PATCH 0881/1022] Minor spelling fix in external test runners base.py --- scripts/externalTests/runners/base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/externalTests/runners/base.py b/scripts/externalTests/runners/base.py index cd94fab6b80b..4778206150e2 100644 --- a/scripts/externalTests/runners/base.py +++ b/scripts/externalTests/runners/base.py @@ -74,7 +74,7 @@ def __init__(self, argv, config: TestConfig): def setup_solc(self) -> str: if self.solc_binary_type == "solcjs": - # TODO: add support to solc-js + # TODO: add support for solc-js raise NotImplementedError() print("Setting up solc...") solc_version_output = subprocess.check_output( From d547bf2b67668bc1fd85cf4c6713c50cf5db5b80 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Fri, 14 Mar 2025 08:50:53 +0100 Subject: [PATCH 0882/1022] Release checklist: Updates style - double backticks -> single backticks - remove single space before bullet points --- ReleaseChecklist.md | 200 ++++++++++++++++++++++---------------------- 1 file changed, 100 insertions(+), 100 deletions(-) diff --git a/ReleaseChecklist.md b/ReleaseChecklist.md index 301cf963e81f..f5e4ec7cae21 100644 --- a/ReleaseChecklist.md +++ b/ReleaseChecklist.md @@ -1,127 +1,127 @@ ## Checklist for making a release: ### Requirements - - [ ] GitHub account with access to [solidity](https://github.com/ethereum/solidity), [solc-js](https://github.com/ethereum/solc-js), - [solc-bin](https://github.com/ethereum/solc-bin), [solidity-website](https://github.com/ethereum/solidity-website). - - [ ] DockerHub account with push rights to the [``solc`` image](https://hub.docker.com/r/ethereum/solc). - - [ ] Launchpad (Ubuntu One) account with a membership in the ["Ethereum" team](https://launchpad.net/~ethereum) and - a gnupg key for your email in the ``ethereum.org`` domain (has to be version 1, gpg2 won't work). - - [ ] Ubuntu/Debian dependencies of the Docker script: ``docker-buildx``. - - [ ] Ubuntu/Debian dependencies of the PPA scripts: ``devscripts``, ``debhelper``, ``dput``, ``git``, ``wget``, ``ca-certificates``. - - [ ] [npm Registry](https://www.npmjs.com) account added as a collaborator for the [``solc`` package](https://www.npmjs.com/package/solc). - - [ ] Access to the [solidity_lang Twitter account](https://twitter.com/solidity_lang). - - [ ] [Reddit](https://www.reddit.com) account that is at least 10 days old with a minimum of 20 comment karma (``/r/ethereum`` requirements). +- [ ] GitHub account with access to [solidity](https://github.com/ethereum/solidity), [solc-js](https://github.com/ethereum/solc-js), + [solc-bin](https://github.com/ethereum/solc-bin), [solidity-website](https://github.com/ethereum/solidity-website). +- [ ] DockerHub account with push rights to the [`solc` image](https://hub.docker.com/r/ethereum/solc). +- [ ] Launchpad (Ubuntu One) account with a membership in the ["Ethereum" team](https://launchpad.net/~ethereum) and + a gnupg key for your email in the `ethereum.org` domain (has to be version 1, gpg2 won't work). +- [ ] Ubuntu/Debian dependencies of the Docker script: `docker-buildx`. +- [ ] Ubuntu/Debian dependencies of the PPA scripts: `devscripts`, `debhelper`, `dput`, `git`, `wget`, `ca-certificates`. +- [ ] [npm Registry](https://www.npmjs.com) account added as a collaborator for the [`solc` package](https://www.npmjs.com/package/solc). +- [ ] Access to the [solidity_lang Twitter account](https://twitter.com/solidity_lang). +- [ ] [Reddit](https://www.reddit.com) account that is at least 10 days old with a minimum of 20 comment karma (`/r/ethereum` requirements). ### Pre-flight checks At least a day before the release: - - [ ] Run ``make linkcheck`` from within ``docs/`` and fix any broken links it finds. - Ignore false positives caused by ``href`` anchors and dummy links not meant to work. - **Note**: In order to run the link check, make sure you've built the docs first via ``docs.sh``. - - [ ] Double-check that [the most recent docs builds at readthedocs](https://readthedocs.org/projects/solidity/builds/) succeeded. - - [ ] Make sure that all merged PRs that should have changelog entries do have them. - - [ ] Rerun CI on the top commits of main branches in all repositories that do not have daily activity by creating a test branch or PR: - - [ ] ``solc-js`` - - [ ] ``solc-bin`` (make sure the bytecode comparison check did run) - - [ ] (Optional) Create a prerelease in our Ubuntu PPA by following the steps in the PPA section below on ``develop`` rather than on a tag. - This is recommended especially when dealing with PPA for the first time, when we add a new Ubuntu version or when the PPA scripts were modified in this release cycle. - - [ ] Verify that the release tarball of ``solc-js`` works. - Bump version locally, add ``soljson.js`` from CI, build it, compare the file structure with the previous version, install it locally and try to use it. - - [ ] Review [Learning from Past Releases](https://notes.ethereum.org/@solidity/release-mistakes) to make sure you don't repeat the same mistakes. +- [ ] Run `make linkcheck` from within `docs/` and fix any broken links it finds. + Ignore false positives caused by `href` anchors and dummy links not meant to work. + **Note**: In order to run the link check, make sure you've built the docs first via `docs.sh`. +- [ ] Double-check that [the most recent docs builds at readthedocs](https://readthedocs.org/projects/solidity/builds/) succeeded. +- [ ] Make sure that all merged PRs that should have changelog entries do have them. +- [ ] Rerun CI on the top commits of main branches in all repositories that do not have daily activity by creating a test branch or PR: + - [ ] `solc-js` + - [ ] `solc-bin` (make sure the bytecode comparison check did run) +- [ ] (Optional) Create a prerelease in our Ubuntu PPA by following the steps in the PPA section below on `develop` rather than on a tag. + This is recommended especially when dealing with PPA for the first time, when we add a new Ubuntu version or when the PPA scripts were modified in this release cycle. +- [ ] Verify that the release tarball of `solc-js` works. + Bump version locally, add `soljson.js` from CI, build it, compare the file structure with the previous version, install it locally and try to use it. +- [ ] Review [Learning from Past Releases](https://notes.ethereum.org/@solidity/release-mistakes) to make sure you don't repeat the same mistakes. ### Drafts At least a day before the release: - - [ ] Create a draft PR to sort the changelog. - - [ ] Create draft PRs to bump version in ``solidity`` and ``solc-js``. - **Note**: The ``solc-js`` PR won't pass CI checks yet because it depends on the soljson binary from ``solc-bin``. - - [ ] Create a draft of the release on github. - - [ ] Create a draft PR to update soliditylang.org. - - [ ] Create drafts of blog posts. - - [ ] Prepare drafts of Twitter, Reddit and Solidity Forum announcements. +- [ ] Create a draft PR to sort the changelog. +- [ ] Create draft PRs to bump version in `solidity` and `solc-js`. + **Note**: The `solc-js` PR won't pass CI checks yet because it depends on the soljson binary from `solc-bin`. +- [ ] Create a draft of the release on github. +- [ ] Create a draft PR to update soliditylang.org. +- [ ] Create drafts of blog posts. +- [ ] Prepare drafts of Twitter, Reddit and Solidity Forum announcements. ### Blog Post - - [ ] Create a post on [solidity-website](https://github.com/ethereum/solidity-website/tree/main/src/posts) in the ``Releases`` category and explain some of the new features or concepts. - - [ ] Create a post on [solidity-website](https://github.com/ethereum/solidity-website/tree/main/src/posts) in the ``Security Alerts`` category in case of important bug(s). - - [ ] Get the posts reviewed and approved **before the release starts**. +- [ ] Create a post on [solidity-website](https://github.com/ethereum/solidity-website/tree/main/src/posts) in the `Releases` category and explain some of the new features or concepts. +- [ ] Create a post on [solidity-website](https://github.com/ethereum/solidity-website/tree/main/src/posts) in the `Security Alerts` category in case of important bug(s). +- [ ] Get the posts reviewed and approved **before the release starts**. ### Changelog - - [ ] Sort the changelog entries alphabetically and correct any errors you notice. Commit it. - - [ ] Update the changelog to include a release date. - - [ ] Run ``scripts/update_bugs_by_version.py`` to regenerate ``bugs_by_version.json`` from the changelog and ``bugs.json``. - Make sure that the resulting ``bugs_by_version.json`` has a new, empty entry for the new version. - - [ ] Commit changes, create a pull request and wait for the tests. Then merge it. - - [ ] Copy the changelog into the release blog post. +- [ ] Sort the changelog entries alphabetically and correct any errors you notice. Commit it. +- [ ] Update the changelog to include a release date. +- [ ] Run `scripts/update_bugs_by_version.py` to regenerate `bugs_by_version.json` from the changelog and `bugs.json`. + Make sure that the resulting `bugs_by_version.json` has a new, empty entry for the new version. +- [ ] Commit changes, create a pull request and wait for the tests. Then merge it. +- [ ] Copy the changelog into the release blog post. ### Create the Release - - [ ] Create a [release on GitHub](https://github.com/ethereum/solidity/releases/new). - Set the target to the ``develop`` branch and the tag to the new version, e.g. ``v0.8.5``. - Include the following warning: ``**The release is still in progress. You may see broken links and binaries may not yet be available from all sources.**``. - Do not publish it yet - click the ``Save draft`` button instead. - - [ ] Thank voluntary contributors in the GitHub release notes. - Use ``scripts/list_contributors.sh v`` to get initial list of names. - Remove different variants of the same name manually before using the output. - - [ ] Check that all tests on the latest commit in ``develop`` are green. - - [ ] Click the ``Publish release`` button on the release page, creating the tag. - **Important: Must not be done before all the PRs, including changelog cleanup and date, are merged.** - - [ ] Wait for the CI runs on the tag itself. +- [ ] Create a [release on GitHub](https://github.com/ethereum/solidity/releases/new). + Set the target to the `develop` branch and the tag to the new version, e.g. `v0.8.5`. + Include the following warning: `**The release is still in progress. You may see broken links and binaries may not yet be available from all sources.**`. + Do not publish it yet - click the `Save draft` button instead. +- [ ] Thank voluntary contributors in the GitHub release notes. + Use `scripts/list_contributors.sh v` to get initial list of names. + Remove different variants of the same name manually before using the output. +- [ ] Check that all tests on the latest commit in `develop` are green. +- [ ] Click the `Publish release` button on the release page, creating the tag. + **Important: Must not be done before all the PRs, including changelog cleanup and date, are merged.** +- [ ] Wait for the CI runs on the tag itself. ### Upload Release Artifacts and Publish Binaries - - [ ] Switch to the tag that archives have to be created for. - - [ ] Create the ``prerelease.txt`` file: (``echo -n > prerelease.txt``). - - [ ] Run ``scripts/create_source_tarball.sh`` while being on the tag to create the source tarball. This will create the tarball in a directory called ``upload``. - - [ ] Take the tarball from the upload directory (its name should be ``solidity_x.x.x.tar.gz``, otherwise ``prerelease.txt`` was missing in the step before) and upload the source tarball to the release page. - - [ ] Take the ``github-binaries.tar`` tarball from ``c_release_binaries`` run of the tagged commit in circle-ci and add all binaries from it to the release page. - Make sure it contains four binaries: ``solc-windows.exe``, ``solc-macos``, ``solc-static-linux`` and ``soljson.js``. - - [ ] Take the ``solc-bin-binaries.tar`` tarball from ``c_release_binaries`` run of the tagged commit in circle-ci and add all binaries from it to solc-bin. - - [ ] Run ``npm install`` if you've got a clean checkout of the solc-bin repo. - - [ ] Run ``npm run update -- --reuse-hashes`` in ``solc-bin`` and verify that the script has updated ``list.js``, ``list.txt`` and ``list.json`` files correctly and that symlinks to the new release have been added in ``solc-bin/wasm/`` and ``solc-bin/emscripten-wasm32/``. - - [ ] Create a pull request in solc-bin and merge. +- [ ] Switch to the tag that archives have to be created for. +- [ ] Create the `prerelease.txt` file: (`echo -n > prerelease.txt`). +- [ ] Run `scripts/create_source_tarball.sh` while being on the tag to create the source tarball. This will create the tarball in a directory called `upload`. +- [ ] Take the tarball from the upload directory (its name should be `solidity_x.x.x.tar.gz`, otherwise `prerelease.txt` was missing in the step before) and upload the source tarball to the release page. +- [ ] Take the `github-binaries.tar` tarball from `c_release_binaries` run of the tagged commit in circle-ci and add all binaries from it to the release page. + Make sure it contains four binaries: `solc-windows.exe`, `solc-macos`, `solc-static-linux` and `soljson.js`. +- [ ] Take the `solc-bin-binaries.tar` tarball from `c_release_binaries` run of the tagged commit in circle-ci and add all binaries from it to solc-bin. +- [ ] Run `npm install` if you've got a clean checkout of the solc-bin repo. +- [ ] Run `npm run update -- --reuse-hashes` in `solc-bin` and verify that the script has updated `list.js`, `list.txt` and `list.json` files correctly and that symlinks to the new release have been added in `solc-bin/wasm/` and `solc-bin/emscripten-wasm32/`. +- [ ] Create a pull request in solc-bin and merge. ### Homebrew and MacOS - - [ ] Update the version and the hash (``sha256sum solidity_$VERSION.tar.gz``) in the [``solidity`` formula in Homebrew core repository](https://github.com/Homebrew/homebrew-core/blob/master/Formula/s/solidity.rb). +- [ ] Update the version and the hash (`sha256sum solidity_$VERSION.tar.gz`) in the [`solidity` formula in Homebrew core repository](https://github.com/Homebrew/homebrew-core/blob/master/Formula/s/solidity.rb). ### Docker - - [ ] Make sure ``docker-buildx`` is installed. - - [ ] Run ``./scripts/docker_deploy_manual.sh v$VERSION``. +- [ ] Make sure `docker-buildx` is installed. +- [ ] Run `./scripts/docker_deploy_manual.sh v$VERSION`. ### PPA - - [ ] Create ``.release_ppa_auth`` at the root of your local Solidity checkout and set ``LAUNCHPAD_EMAIL`` and ``LAUNCHPAD_KEYID`` to your key's email and key id. - - [ ] Double-check that the ``DISTRIBUTIONS`` list in ``scripts/release_ppa.sh`` and ``scripts/deps-ppa/static_z3.sh`` contains the most recent versions of Ubuntu. - - [ ] Make sure the [``~ethereum/cpp-build-deps`` PPA repository](https://launchpad.net/~ethereum/+archive/ubuntu/cpp-build-deps) contains ``libz3-static-dev`` builds for all current versions of Ubuntu. - Note that it may be included in the ``z3-static`` multipackage (follow the ``View package details`` link to check). - If not present, run ``scripts/deps-ppa/static_z3.sh`` and wait for the builds to succeed before continuing. - - [ ] Run ``scripts/release_ppa.sh v$VERSION`` to create the PPA release. - This will create a single package containing static binary for older Ubuntu versions in the [``~ethereum/ethereum-static`` PPA](https://launchpad.net/~ethereum/+archive/ubuntu/ethereum-static) - and separate packages with dynamically-linked binaries for recent versions (those listed in ``DISTRIBUTIONS``) in the [``~ethereum/ethereum`` PPA](https://launchpad.net/~ethereum/+archive/ubuntu/ethereum). - - [ ] Wait for the build to be finished and published for *all architectures* (currently we only build for ``amd64``, but we may add ``arm`` in the future). - **SERIOUSLY: DO NOT PROCEED EARLIER!!!** - - [ ] *After* the package with the static build is *published*, use it to create packages for older Ubuntu versions. - Copy the static package to the [``~ethereum/ethereum`` PPA](https://launchpad.net/~ethereum/+archive/ubuntu/ethereum) - for the destination series ``Trusty``, ``Xenial``, ``Bionic``, and ``Focal`` - while selecting ``Copy existing binaries``. +- [ ] Create `.release_ppa_auth` at the root of your local Solidity checkout and set `LAUNCHPAD_EMAIL` and `LAUNCHPAD_KEYID` to your key's email and key id. +- [ ] Double-check that the `DISTRIBUTIONS` list in `scripts/release_ppa.sh` and `scripts/deps-ppa/static_z3.sh` contains the most recent versions of Ubuntu. +- [ ] Make sure the [`~ethereum/cpp-build-deps` PPA repository](https://launchpad.net/~ethereum/+archive/ubuntu/cpp-build-deps) contains `libz3-static-dev` builds for all current versions of Ubuntu. + Note that it may be included in the `z3-static` multipackage (follow the `View package details` link to check). + If not present, run `scripts/deps-ppa/static_z3.sh` and wait for the builds to succeed before continuing. +- [ ] Run `scripts/release_ppa.sh v$VERSION` to create the PPA release. + This will create a single package containing static binary for older Ubuntu versions in the [`~ethereum/ethereum-static` PPA](https://launchpad.net/~ethereum/+archive/ubuntu/ethereum-static) + and separate packages with dynamically-linked binaries for recent versions (those listed in `DISTRIBUTIONS`) in the [`~ethereum/ethereum` PPA](https://launchpad.net/~ethereum/+archive/ubuntu/ethereum). +- [ ] Wait for the build to be finished and published for *all architectures* (currently we only build for `amd64`, but we may add `arm` in the future). + **SERIOUSLY: DO NOT PROCEED EARLIER!!!** +- [ ] *After* the package with the static build is *published*, use it to create packages for older Ubuntu versions. + Copy the static package to the [`~ethereum/ethereum` PPA](https://launchpad.net/~ethereum/+archive/ubuntu/ethereum) + for the destination series `Trusty`, `Xenial`, `Bionic`, and `Focal` + while selecting `Copy existing binaries`. ### Release solc-js - - [ ] Wait until solc-bin was properly deployed. You can test this via remix - a test run through remix is advisable anyway. - - [ ] Increment the version number, create a pull request for that, merge it after tests succeeded. - - [ ] Create a tag using ``git tag --annotate v$VERSION`` and push it with ``git push --tags``. - - [ ] Wait for the CI runs on the tag itself. - - [ ] Take the ``solc-x.y.z.tgz`` artifact from ``build-package`` run on the tagged commit in circle-ci. - Inspect the tarball to ensure that it contains an up-to-date compiler binary (``soljson.js``). - - [ ] Run ``npm publish solc-x.y.z.tgz`` to publish the newly created tarball. +- [ ] Wait until solc-bin was properly deployed. You can test this via remix - a test run through remix is advisable anyway. +- [ ] Increment the version number, create a pull request for that, merge it after tests succeeded. +- [ ] Create a tag using `git tag --annotate v$VERSION` and push it with `git push --tags`. +- [ ] Wait for the CI runs on the tag itself. +- [ ] Take the `solc-x.y.z.tgz` artifact from `build-package` run on the tagged commit in circle-ci. + Inspect the tarball to ensure that it contains an up-to-date compiler binary (`soljson.js`). +- [ ] Run `npm publish solc-x.y.z.tgz` to publish the newly created tarball. ### Post-release - - [ ] Make sure the documentation for the new release has been published successfully. - Go to the [documentation status page at ReadTheDocs](https://readthedocs.org/projects/solidity/) and verify that the new version is listed, works and is marked as default. - - [ ] Remove "still in progress" warning from the [release notes](https://github.com/ethereum/solidity/releases). - - [ ] Merge the [blog posts](https://github.com/ethereum/solidity-website/pulls) related to the release. - - [ ] Create a commit to increase the version number on ``develop`` in ``CMakeLists.txt`` and add a new skeleton changelog entry. - - [ ] Update the release information section [in the source of soliditylang.org](https://github.com/ethereum/solidity-website/blob/main/src/pages/index.tsx). - - [ ] Announce on [Twitter](https://twitter.com/solidity_lang), including links to the release and the blog post. - - [ ] Announce on [Fosstodon](https://fosstodon.org/@solidity/), including links to the release and the blog post. - - [ ] Share the announcement on Reddit in [``/r/ethdev``](https://reddit.com/r/ethdev/), cross-posted to [``/r/ethereum``](https://reddit.com/r/ethereum/). - - [ ] Share the announcement on the [Solidity forum](https://forum.soliditylang.org) in the ``Announcements`` category. - - [ ] Share the announcement on [Project Updates](https://discord.com/channels/420394352083337236/798974456704925696) - - [ ] Share the announcement on [`#solidity` channel on Matrix](https://matrix.to/#/#ethereum_solidity:gitter.im) - - [ ] Share the announcement on [`#solc-tooling`](https://matrix.to/#/#solc-tooling:matrix.org) - - [ ] If anything went wrong this time, mention it in [Learning from Past Releases](https://notes.ethereum.org/@solidity/release-mistakes). - - [ ] Bump vendored dependencies. - - [ ] Lean back, wait for bug reports and repeat from step 1 :). +- [ ] Make sure the documentation for the new release has been published successfully. + Go to the [documentation status page at ReadTheDocs](https://readthedocs.org/projects/solidity/) and verify that the new version is listed, works and is marked as default. +- [ ] Remove "still in progress" warning from the [release notes](https://github.com/ethereum/solidity/releases). +- [ ] Merge the [blog posts](https://github.com/ethereum/solidity-website/pulls) related to the release. +- [ ] Create a commit to increase the version number on `develop` in `CMakeLists.txt` and add a new skeleton changelog entry. +- [ ] Update the release information section [in the source of soliditylang.org](https://github.com/ethereum/solidity-website/blob/main/src/pages/index.tsx). +- [ ] Announce on [Twitter](https://twitter.com/solidity_lang), including links to the release and the blog post. +- [ ] Announce on [Fosstodon](https://fosstodon.org/@solidity/), including links to the release and the blog post. +- [ ] Share the announcement on Reddit in [`/r/ethdev`](https://reddit.com/r/ethdev/), cross-posted to [`/r/ethereum`](https://reddit.com/r/ethereum/). +- [ ] Share the announcement on the [Solidity forum](https://forum.soliditylang.org) in the `Announcements` category. +- [ ] Share the announcement on [Project Updates](https://discord.com/channels/420394352083337236/798974456704925696) +- [ ] Share the announcement on [`#solidity` channel on Matrix](https://matrix.to/#/#ethereum_solidity:gitter.im) +- [ ] Share the announcement on [`#solc-tooling`](https://matrix.to/#/#solc-tooling:matrix.org) +- [ ] If anything went wrong this time, mention it in [Learning from Past Releases](https://notes.ethereum.org/@solidity/release-mistakes). +- [ ] Bump vendored dependencies. +- [ ] Lean back, wait for bug reports and repeat from step 1 :). From 70d344a0e93b299b531cbde369713ae067567688 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Fri, 14 Mar 2025 23:55:49 +0100 Subject: [PATCH 0883/1022] Remove double backticks from CODING_STYLE.md --- CODING_STYLE.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CODING_STYLE.md b/CODING_STYLE.md index 2305ae1ec752..b70126d91643 100644 --- a/CODING_STYLE.md +++ b/CODING_STYLE.md @@ -110,9 +110,9 @@ Use `solAssert` and `solUnimplementedAssert` generously to check assumptions tha 4. Favour declarations close to use; do not habitually declare at top of scope ala C. 5. Pass non-trivial parameters as const reference, unless the data is to be copied into the function, then either pass by const reference or by value and use std::move. 6. If a function returns multiple values, use std::tuple (std::pair acceptable) or better introduce a struct type. Do not use */& arguments. -7. Use parameters of pointer type only if ``nullptr`` is a valid argument, use references otherwise. Often, ``std::optional`` is better suited than a raw pointer. +7. Use parameters of pointer type only if `nullptr` is a valid argument, use references otherwise. Often, `std::optional` is better suited than a raw pointer. 8. Never use a macro where adequate non-preprocessor C++ can be written. -9. Only use ``auto`` if the type is very long and rather irrelevant. +9. Only use `auto` if the type is very long and rather irrelevant. 10. Do not pass bools: prefer enumerations instead. 11. Prefer enum class to straight enum. 12. Always initialize POD variables, even if their value is overwritten later. From 145e281fac9369c920c9628fe4a967f7b71e9193 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Wed, 12 Mar 2025 14:13:23 +0100 Subject: [PATCH 0884/1022] Name dependent CSE bug: Compare ASM only --- test/cmdlineTests/~name_dependent_cse_bug/test.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/cmdlineTests/~name_dependent_cse_bug/test.sh b/test/cmdlineTests/~name_dependent_cse_bug/test.sh index 96c3ac23ed97..710e82b1e7a0 100755 --- a/test/cmdlineTests/~name_dependent_cse_bug/test.sh +++ b/test/cmdlineTests/~name_dependent_cse_bug/test.sh @@ -19,7 +19,7 @@ function assemble_with_variable_name { local variable_name="$2" sed -e "s|__placeholder__|${variable_name}|g" "$input_file" | msg_on_error --no-stderr \ - "$SOLC" --strict-assembly - --optimize --debug-info none | + "$SOLC" --strict-assembly - --optimize --debug-info none --asm | stripCLIDecorations } From 74cd757be52c658a8eef7a81c62d364ee1921652 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Mon, 17 Mar 2025 08:52:34 +0100 Subject: [PATCH 0885/1022] SSACFG Builder: Improve function call visitor --- .../evm/SSAControlFlowGraphBuilder.cpp | 21 ++++++++++--------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/libyul/backends/evm/SSAControlFlowGraphBuilder.cpp b/libyul/backends/evm/SSAControlFlowGraphBuilder.cpp index bf8cfd92a802..69e9e3052104 100644 --- a/libyul/backends/evm/SSAControlFlowGraphBuilder.cpp +++ b/libyul/backends/evm/SSAControlFlowGraphBuilder.cpp @@ -548,21 +548,22 @@ void SSAControlFlowGraphBuilder::assign(std::vector SSAControlFlowGraphBuilder::visitFunctionCall(FunctionCall const& _call) { bool canContinue = true; - SSACFG::Operation operation = [&](){ - if (BuiltinFunction const* builtin = resolveBuiltinFunction(_call.functionName, m_dialect)) + SSACFG::Operation operation = std::visit(util::GenericVisitor{ + [&](BuiltinName const& _builtinName) { - SSACFG::Operation result{{}, SSACFG::BuiltinCall{_call.debugData, *builtin, _call}, {}}; + auto const& builtin = m_dialect.builtin(_builtinName.handle); + SSACFG::Operation result{{}, SSACFG::BuiltinCall{_call.debugData, builtin, _call}, {}}; for (auto&& [idx, arg]: _call.arguments | ranges::views::enumerate | ranges::views::reverse) - if (!builtin->literalArgument(idx).has_value()) + if (!builtin.literalArgument(idx).has_value()) result.inputs.emplace_back(std::visit(*this, arg)); - for (size_t i = 0; i < builtin->numReturns; ++i) + for (size_t i = 0; i < builtin.numReturns; ++i) result.outputs.emplace_back(m_graph.newVariable(m_currentBlock)); - canContinue = builtin->controlFlowSideEffects.canContinue; + canContinue = builtin.controlFlowSideEffects.canContinue; return result; - } - else + }, + [&](Identifier const& _identifier) { - YulName const functionName{resolveFunctionName(_call.functionName, m_dialect)}; + YulName const& functionName = _identifier.name; Scope::Function const& function = lookupFunction(functionName); auto const* definition = findFunctionDefinition(&function); yulAssert(definition); @@ -574,7 +575,7 @@ std::vector SSAControlFlowGraphBuilder::visitFunctionCall(Funct result.outputs.emplace_back(m_graph.newVariable(m_currentBlock)); return result; } - }(); + }, _call.functionName); auto results = operation.outputs; currentBlock().operations.emplace_back(std::move(operation)); if (!canContinue) From 25463c564dc18cb98750e49d227901087a32940b Mon Sep 17 00:00:00 2001 From: Martin Blicha Date: Fri, 14 Feb 2025 12:40:18 +0100 Subject: [PATCH 0886/1022] SMTChecker: Fix analysis for selected contracts Previously, when a contract was selected for analysis, the analysis was incorrect. There were two issues. First, the contracts in the same file were considered as entry points even though they were not selected for analysis. Second, the contracts in a different file were mostly ignored, resulting in unsoundness when an external call was made to such a contract in trusted mode. The solution to the above problems is to always create representation of all contracts (in case they are called from the selected contract), but create verification targets only for the selected contracts. --- Changelog.md | 1 + libsolidity/formal/BMC.cpp | 2 +- libsolidity/formal/CHC.cpp | 26 ++++---- libsolidity/formal/ModelCheckerSettings.cpp | 2 +- libsolidity/formal/SMTEncoder.cpp | 13 ++-- libsolidity/formal/SMTEncoder.h | 11 ++-- .../err | 26 -------- .../model_checker_contracts_only_one/err | 2 +- .../output.json | 66 ------------------- .../output.json | 4 +- .../output.json | 4 +- test/libsolidity/SMTCheckerTest.cpp | 11 +++- ...ternal_call_from_constructor_1_trusted.sol | 5 +- ...ternal_call_from_constructor_3_trusted.sol | 5 +- ...lled_from_selection_with_trusted_calls.sol | 11 ++++ ...selected_and_not_called_from_selection.sol | 9 +++ ...selected_and_not_called_from_selection.sol | 13 ++++ ...selected_and_not_called_from_selection.sol | 11 ++++ 18 files changed, 94 insertions(+), 128 deletions(-) create mode 100644 test/libsolidity/smtCheckerTests/imports/target_in_imported_contract_analyzed_when_called_from_selection_with_trusted_calls.sol create mode 100644 test/libsolidity/smtCheckerTests/imports/target_in_imported_contract_not_analyzed_when_not_selected_and_not_called_from_selection.sol create mode 100644 test/libsolidity/smtCheckerTests/verification_target/target_in_constructor_of_same_source_contract_not_analyzed_when_not_selected_and_not_called_from_selection.sol create mode 100644 test/libsolidity/smtCheckerTests/verification_target/target_in_same_source_contract_not_analyzed_when_not_selected_and_not_called_from_selection.sol diff --git a/Changelog.md b/Changelog.md index 47334fd3dacd..3e423c838b67 100644 --- a/Changelog.md +++ b/Changelog.md @@ -7,6 +7,7 @@ Compiler Features: Bugfixes: +* SMTChecker: Fix incorrect analysis when only a subset of contracts is selected with `--model-checker-contracts`. ### 0.8.29 (2025-03-12) diff --git a/libsolidity/formal/BMC.cpp b/libsolidity/formal/BMC.cpp index e5521b816582..6dcd856ee2af 100644 --- a/libsolidity/formal/BMC.cpp +++ b/libsolidity/formal/BMC.cpp @@ -1068,7 +1068,7 @@ void BMC::addVerificationTarget( Expression const* _expression ) { - if (!m_settings.targets.has(_type) || (m_currentContract && !shouldAnalyze(*m_currentContract))) + if (!m_settings.targets.has(_type) || (m_currentContract && !shouldAnalyzeVerificationTargetsFor(*m_currentContract))) return; BMCVerificationTarget target{ diff --git a/libsolidity/formal/CHC.cpp b/libsolidity/formal/CHC.cpp index c313ae54e1ae..bab340051f82 100644 --- a/libsolidity/formal/CHC.cpp +++ b/libsolidity/formal/CHC.cpp @@ -89,7 +89,7 @@ void CHC::analyze(SourceUnit const& _source) " If you wish to use Eldarica, please enable Eldarica only." ); - if (!shouldAnalyze(_source)) + if (!shouldAnalyzeVerificationTargetsFor(_source)) return; resetSourceAnalysis(); @@ -131,7 +131,7 @@ std::vector CHC::unhandledQueries() const bool CHC::visit(ContractDefinition const& _contract) { - if (!shouldAnalyze(_contract)) + if (!shouldEncode(_contract)) return false; // Raises UnimplementedFeatureError in the presence of transient storage variables @@ -152,7 +152,7 @@ bool CHC::visit(ContractDefinition const& _contract) void CHC::endVisit(ContractDefinition const& _contract) { - if (!shouldAnalyze(_contract)) + if (!shouldEncode(_contract)) return; for (auto base: _contract.annotation().linearizedBaseContracts) @@ -239,15 +239,14 @@ void CHC::endVisit(ContractDefinition const& _contract) setCurrentBlock(*m_constructorSummaries.at(&_contract)); solAssert(&_contract == m_currentContract, ""); - if (shouldAnalyze(_contract)) - { - auto constructor = _contract.constructor(); - auto txConstraints = state().txTypeConstraints(); - if (!constructor || !constructor->isPayable()) - txConstraints = txConstraints && state().txNonPayableConstraint(); + smtAssert(shouldEncode(_contract)); + auto constructor = _contract.constructor(); + auto txConstraints = state().txTypeConstraints(); + if (!constructor || !constructor->isPayable()) + txConstraints = txConstraints && state().txNonPayableConstraint(); + connectBlocks(m_currentBlock, interface(), txConstraints && errorFlag().currentValue() == 0); + if (shouldAnalyzeVerificationTargetsFor(_contract)) m_queryPlaceholders[&_contract].push_back({txConstraints, errorFlag().currentValue(), m_currentBlock}); - connectBlocks(m_currentBlock, interface(), txConstraints && errorFlag().currentValue() == 0); - } solAssert(m_scopes.back() == &_contract, ""); m_scopes.pop_back(); @@ -338,7 +337,7 @@ void CHC::endVisit(FunctionDefinition const& _function) !_function.isConstructor() && _function.isPublic() && contractFunctions(*m_currentContract).count(&_function) && - shouldAnalyze(*m_currentContract) + shouldEncode(*m_currentContract) ) { defineExternalFunctionInterface(_function, *m_currentContract); @@ -349,8 +348,9 @@ void CHC::endVisit(FunctionDefinition const& _function) auto ifacePre = smt::interfacePre(*m_interfaces.at(m_currentContract), *m_currentContract, m_context); auto sum = externalSummary(_function); - m_queryPlaceholders[&_function].push_back({sum, errorFlag().currentValue(), ifacePre}); connectBlocks(ifacePre, interface(), sum && errorFlag().currentValue() == 0); + if (shouldAnalyzeVerificationTargetsFor(*m_currentContract)) + m_queryPlaceholders[&_function].push_back({sum, errorFlag().currentValue(), ifacePre}); } m_currentFunction = nullptr; diff --git a/libsolidity/formal/ModelCheckerSettings.cpp b/libsolidity/formal/ModelCheckerSettings.cpp index ed4d5ce204c0..ffeedfe3ace0 100644 --- a/libsolidity/formal/ModelCheckerSettings.cpp +++ b/libsolidity/formal/ModelCheckerSettings.cpp @@ -123,7 +123,7 @@ std::optional ModelCheckerContracts::fromString(std::stri { auto&& names = sourceContract | ranges::views::split(':') | ranges::to>(); if (names.size() != 2 || names.at(0).empty() || names.at(1).empty()) - return {}; + return std::nullopt; chosen[names.at(0)].insert(names.at(1)); } diff --git a/libsolidity/formal/SMTEncoder.cpp b/libsolidity/formal/SMTEncoder.cpp index a0b71f5941a9..740af9382b88 100644 --- a/libsolidity/formal/SMTEncoder.cpp +++ b/libsolidity/formal/SMTEncoder.cpp @@ -1092,19 +1092,24 @@ void SMTEncoder::visitPublicGetter(FunctionCall const& _funCall) } } -bool SMTEncoder::shouldAnalyze(SourceUnit const& _source) const +bool SMTEncoder::shouldEncode(ContractDefinition const& _contract) const +{ + return _contract.canBeDeployed(); +} + +bool SMTEncoder::shouldAnalyzeVerificationTargetsFor(SourceUnit const& _source) const { return m_settings.contracts.isDefault() || m_settings.contracts.has(*_source.annotation().path); } -bool SMTEncoder::shouldAnalyze(ContractDefinition const& _contract) const +bool SMTEncoder::shouldAnalyzeVerificationTargetsFor(ContractDefinition const& _contract) const { - if (!_contract.canBeDeployed()) + if (!shouldEncode(_contract)) return false; return m_settings.contracts.isDefault() || - m_settings.contracts.has(_contract.sourceUnitName()); + m_settings.contracts.has(_contract.sourceUnitName(), _contract.name()); } void SMTEncoder::visitTypeConversion(FunctionCall const& _funCall) diff --git a/libsolidity/formal/SMTEncoder.h b/libsolidity/formal/SMTEncoder.h index f926a0d0fc80..5bfb70d8126d 100644 --- a/libsolidity/formal/SMTEncoder.h +++ b/libsolidity/formal/SMTEncoder.h @@ -238,11 +238,12 @@ class SMTEncoder: public ASTConstVisitor void visitFunctionIdentifier(Identifier const& _identifier); virtual void visitPublicGetter(FunctionCall const& _funCall); - /// @returns true if @param _contract is set for analysis in the settings - /// and it is not abstract. - bool shouldAnalyze(ContractDefinition const& _contract) const; - /// @returns true if @param _source is set for analysis in the settings. - bool shouldAnalyze(SourceUnit const& _source) const; + /// @returns true if symbolic representation of @param _contract is required for verification + bool shouldEncode(ContractDefinition const& _contract) const; + /// @returns true if the verification targets of @param _contract are actually selected for verification + bool shouldAnalyzeVerificationTargetsFor(ContractDefinition const& _contract) const; + /// @returns true if we should descend into @param _source to look for contracts that should be verified + bool shouldAnalyzeVerificationTargetsFor(SourceUnit const& _source) const; /// @returns the state variable returned by a public getter if /// @a _expr is a call to a public getter, diff --git a/test/cmdlineTests/model_checker_contracts_inexistent_contract/err b/test/cmdlineTests/model_checker_contracts_inexistent_contract/err index 00b97763f340..6326537e928c 100644 --- a/test/cmdlineTests/model_checker_contracts_inexistent_contract/err +++ b/test/cmdlineTests/model_checker_contracts_inexistent_contract/err @@ -1,27 +1 @@ Warning: Requested contract "C" does not exist in source "model_checker_contracts_inexistent_contract/input.sol". - -Warning: CHC: Assertion violation happens here. -Counterexample: - -x = 0 - -Transaction trace: -B.constructor() -B.f(0) - --> model_checker_contracts_inexistent_contract/input.sol:5:3: - | -5 | assert(x > 0); - | ^^^^^^^^^^^^^ - -Warning: CHC: Assertion violation happens here. -Counterexample: - -y = 0 - -Transaction trace: -A.constructor() -A.g(0) - --> model_checker_contracts_inexistent_contract/input.sol:10:3: - | -10 | assert(y > 0); - | ^^^^^^^^^^^^^ diff --git a/test/cmdlineTests/model_checker_contracts_only_one/err b/test/cmdlineTests/model_checker_contracts_only_one/err index 2088e19c7a2f..9c8ade6931c3 100644 --- a/test/cmdlineTests/model_checker_contracts_only_one/err +++ b/test/cmdlineTests/model_checker_contracts_only_one/err @@ -4,7 +4,7 @@ Counterexample: x = 0 Transaction trace: -B.constructor() +A.constructor() B.f(0) --> model_checker_contracts_only_one/input.sol:5:3: | diff --git a/test/cmdlineTests/standard_model_checker_contracts_inexistent_contract/output.json b/test/cmdlineTests/standard_model_checker_contracts_inexistent_contract/output.json index 22d5f32de32b..c6bde90dfbaa 100644 --- a/test/cmdlineTests/standard_model_checker_contracts_inexistent_contract/output.json +++ b/test/cmdlineTests/standard_model_checker_contracts_inexistent_contract/output.json @@ -9,72 +9,6 @@ "message": "Requested contract \"C\" does not exist in source \"Source\".", "severity": "warning", "type": "Warning" - }, - { - "component": "general", - "errorCode": "6328", - "formattedMessage": "Warning: CHC: Assertion violation happens here. -Counterexample: - -y = 0 - -Transaction trace: -B.constructor() -B.g(0) - --> Source:5:7: - | -5 | \t\t\t\t\t\tassert(y > 0); - | \t\t\t\t\t\t^^^^^^^^^^^^^ - -", - "message": "CHC: Assertion violation happens here. -Counterexample: - -y = 0 - -Transaction trace: -B.constructor() -B.g(0)", - "severity": "warning", - "sourceLocation": { - "end": 137, - "file": "Source", - "start": 124 - }, - "type": "Warning" - }, - { - "component": "general", - "errorCode": "6328", - "formattedMessage": "Warning: CHC: Assertion violation happens here. -Counterexample: - -x = 0 - -Transaction trace: -A.constructor() -A.f(0) - --> Source:10:7: - | -10 | \t\t\t\t\t\tassert(x > 0); - | \t\t\t\t\t\t^^^^^^^^^^^^^ - -", - "message": "CHC: Assertion violation happens here. -Counterexample: - -x = 0 - -Transaction trace: -A.constructor() -A.f(0)", - "severity": "warning", - "sourceLocation": { - "end": 231, - "file": "Source", - "start": 218 - }, - "type": "Warning" } ], "sources": { diff --git a/test/cmdlineTests/standard_model_checker_contracts_multi_source/output.json b/test/cmdlineTests/standard_model_checker_contracts_multi_source/output.json index fe287f833637..f568de16044b 100644 --- a/test/cmdlineTests/standard_model_checker_contracts_multi_source/output.json +++ b/test/cmdlineTests/standard_model_checker_contracts_multi_source/output.json @@ -9,7 +9,7 @@ Counterexample: y = 0 Transaction trace: -B.constructor() +A.constructor() B.g(0) --> Source:5:7: | @@ -23,7 +23,7 @@ Counterexample: y = 0 Transaction trace: -B.constructor() +A.constructor() B.g(0)", "severity": "warning", "sourceLocation": { diff --git a/test/cmdlineTests/standard_model_checker_contracts_only_one/output.json b/test/cmdlineTests/standard_model_checker_contracts_only_one/output.json index e9fc1b4cf6b5..a7ca17b4f5b4 100644 --- a/test/cmdlineTests/standard_model_checker_contracts_only_one/output.json +++ b/test/cmdlineTests/standard_model_checker_contracts_only_one/output.json @@ -9,7 +9,7 @@ Counterexample: y = 0 Transaction trace: -B.constructor() +A.constructor() B.g(0) --> Source:5:7: | @@ -23,7 +23,7 @@ Counterexample: y = 0 Transaction trace: -B.constructor() +A.constructor() B.g(0)", "severity": "warning", "sourceLocation": { diff --git a/test/libsolidity/SMTCheckerTest.cpp b/test/libsolidity/SMTCheckerTest.cpp index d8843e0d3a1e..ce099091f69c 100644 --- a/test/libsolidity/SMTCheckerTest.cpp +++ b/test/libsolidity/SMTCheckerTest.cpp @@ -32,8 +32,17 @@ SMTCheckerTest::SMTCheckerTest(std::string const& _filename): universalCallback(nullptr, smtCommand) { auto contract = m_reader.stringSetting("SMTContract", ""); - if (!contract.empty()) + auto maybeContracts = ModelCheckerContracts::fromString(contract); + auto isValidContractName = [](std::string const& _name) + { + return !_name.empty() && _name.find_first_of(" \t\n\r:,") == std::string::npos; + }; + if (maybeContracts) + m_modelCheckerSettings.contracts = *maybeContracts; + else if (isValidContractName(contract)) m_modelCheckerSettings.contracts.contracts[""] = {contract}; + else + BOOST_THROW_EXCEPTION(std::runtime_error("Invalid contract specified in SMTContract setting.")); auto extCallsMode = ModelCheckerExtCalls::fromString(m_reader.stringSetting("SMTExtCalls", "untrusted")); if (extCallsMode) diff --git a/test/libsolidity/smtCheckerTests/external_calls/external_call_from_constructor_1_trusted.sol b/test/libsolidity/smtCheckerTests/external_calls/external_call_from_constructor_1_trusted.sol index 6f2b717b5e87..051215bb102d 100644 --- a/test/libsolidity/smtCheckerTests/external_calls/external_call_from_constructor_1_trusted.sol +++ b/test/libsolidity/smtCheckerTests/external_calls/external_call_from_constructor_1_trusted.sol @@ -1,6 +1,6 @@ contract State { function f(uint _x) public pure returns (uint) { - assert(_x < 100); // should fail + assert(_x < 100); // should hold when analyzing only contract C (can fail only when analyzing State as standalone contract) return _x; } } @@ -18,5 +18,4 @@ contract C { // SMTExtCalls: trusted // SMTIgnoreInv: yes // ---- -// Warning 6328: (69-85): CHC: Assertion violation happens here. -// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. +// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/external_calls/external_call_from_constructor_3_trusted.sol b/test/libsolidity/smtCheckerTests/external_calls/external_call_from_constructor_3_trusted.sol index 590664055d6b..0f22100d696d 100644 --- a/test/libsolidity/smtCheckerTests/external_calls/external_call_from_constructor_3_trusted.sol +++ b/test/libsolidity/smtCheckerTests/external_calls/external_call_from_constructor_3_trusted.sol @@ -1,6 +1,6 @@ contract State { function f(uint _x) public pure returns (uint) { - assert(_x < 100); // should fail + assert(_x < 100); // should hold when analyzing only contract C (can fail only when analyzing State as standalone contract) return _x; } } @@ -21,5 +21,4 @@ contract C { // SMTEngine: all // SMTExtCalls: trusted // ---- -// Warning 6328: (69-85): CHC: Assertion violation happens here. -// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. +// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. diff --git a/test/libsolidity/smtCheckerTests/imports/target_in_imported_contract_analyzed_when_called_from_selection_with_trusted_calls.sol b/test/libsolidity/smtCheckerTests/imports/target_in_imported_contract_analyzed_when_called_from_selection_with_trusted_calls.sol new file mode 100644 index 000000000000..9389f7d93866 --- /dev/null +++ b/test/libsolidity/smtCheckerTests/imports/target_in_imported_contract_analyzed_when_called_from_selection_with_trusted_calls.sol @@ -0,0 +1,11 @@ +==== Source: A.sol ==== +contract A { function a() pure public { assert(false); } } +==== Source: B.sol ==== +import "A.sol"; +contract B { function b(A a) pure public { a.a(); } } +// ==== +// SMTContract: B.sol:B +// SMTEngine: chc +// SMTExtCalls: trusted +// ---- +// Warning 6328: (A.sol:40-53): CHC: Assertion violation happens here.\nCounterexample:\n\na = 0\n\nTransaction trace:\nB.constructor()\nB.b(0)\n A.a() -- trusted external call diff --git a/test/libsolidity/smtCheckerTests/imports/target_in_imported_contract_not_analyzed_when_not_selected_and_not_called_from_selection.sol b/test/libsolidity/smtCheckerTests/imports/target_in_imported_contract_not_analyzed_when_not_selected_and_not_called_from_selection.sol new file mode 100644 index 000000000000..a7c472bbcd1a --- /dev/null +++ b/test/libsolidity/smtCheckerTests/imports/target_in_imported_contract_not_analyzed_when_not_selected_and_not_called_from_selection.sol @@ -0,0 +1,9 @@ +==== Source: A.sol ==== +contract A { function a() pure public { assert(false); } } +==== Source: B.sol ==== +import "A.sol"; +contract B { function b() pure public { } } +// ==== +// SMTContract: B.sol:B +// SMTEngine: chc +// ---- diff --git a/test/libsolidity/smtCheckerTests/verification_target/target_in_constructor_of_same_source_contract_not_analyzed_when_not_selected_and_not_called_from_selection.sol b/test/libsolidity/smtCheckerTests/verification_target/target_in_constructor_of_same_source_contract_not_analyzed_when_not_selected_and_not_called_from_selection.sol new file mode 100644 index 000000000000..29d8017cc075 --- /dev/null +++ b/test/libsolidity/smtCheckerTests/verification_target/target_in_constructor_of_same_source_contract_not_analyzed_when_not_selected_and_not_called_from_selection.sol @@ -0,0 +1,13 @@ +contract B { + constructor() { fail(); } + + function fail() pure internal { assert(false); } +} + +contract A { + function safe() pure public { } +} +// ==== +// SMTContract: A +// SMTEngine: chc +// ---- diff --git a/test/libsolidity/smtCheckerTests/verification_target/target_in_same_source_contract_not_analyzed_when_not_selected_and_not_called_from_selection.sol b/test/libsolidity/smtCheckerTests/verification_target/target_in_same_source_contract_not_analyzed_when_not_selected_and_not_called_from_selection.sol new file mode 100644 index 000000000000..f9fcdbb18e7c --- /dev/null +++ b/test/libsolidity/smtCheckerTests/verification_target/target_in_same_source_contract_not_analyzed_when_not_selected_and_not_called_from_selection.sol @@ -0,0 +1,11 @@ +contract B { + function fail() pure public { assert(false); } +} + +contract A { + function safe() pure public { } +} +// ==== +// SMTContract: A +// SMTEngine: chc +// ---- From f2c9eecb46107a6caa1a9604fec7613b027a3d4a Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Mon, 17 Mar 2025 08:59:15 +0100 Subject: [PATCH 0887/1022] Yul Disambiguator: Don't check for builtins when translating identifiers --- libyul/optimiser/Disambiguator.cpp | 6 +++--- libyul/optimiser/Disambiguator.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/libyul/optimiser/Disambiguator.cpp b/libyul/optimiser/Disambiguator.cpp index 55219f6eae37..343feb0be379 100644 --- a/libyul/optimiser/Disambiguator.cpp +++ b/libyul/optimiser/Disambiguator.cpp @@ -30,15 +30,15 @@ using namespace solidity; using namespace solidity::yul; using namespace solidity::util; -YulName Disambiguator::translateIdentifier(YulName _originalName) +YulName Disambiguator::translateIdentifier(YulName const _originalName) { - if (m_dialect.findBuiltin(_originalName.str()) || m_externallyUsedIdentifiers.count(_originalName)) + if (m_externallyUsedIdentifiers.contains(_originalName)) return _originalName; assertThrow(!m_scopes.empty() && m_scopes.back(), OptimizerException, ""); Scope::Identifier const* id = m_scopes.back()->lookup(_originalName); assertThrow(id, OptimizerException, ""); - if (!m_translations.count(id)) + if (!m_translations.contains(id)) m_translations[id] = m_nameDispenser.newName(_originalName); return m_translations.at(id); } diff --git a/libyul/optimiser/Disambiguator.h b/libyul/optimiser/Disambiguator.h index 36d178b086c1..7ff186f0a8c7 100644 --- a/libyul/optimiser/Disambiguator.h +++ b/libyul/optimiser/Disambiguator.h @@ -56,7 +56,7 @@ class Disambiguator: public ASTCopier void leaveScope(Block const& _block) override; void enterFunction(FunctionDefinition const& _function) override; void leaveFunction(FunctionDefinition const& _function) override; - YulName translateIdentifier(YulName _name) override; + YulName translateIdentifier(YulName _originalName) override; void enterScopeInternal(Scope& _scope); void leaveScopeInternal(Scope& _scope); From 8f38f2304a69ad73b3800c5d552c2bda9dd8afff Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Wed, 19 Mar 2025 15:45:17 +0100 Subject: [PATCH 0888/1022] Peephole optimiser: Replace apply methods recursion by folding expression --- libevmasm/PeepholeOptimiser.cpp | 67 +++++++++++++++------------------ 1 file changed, 31 insertions(+), 36 deletions(-) diff --git a/libevmasm/PeepholeOptimiser.cpp b/libevmasm/PeepholeOptimiser.cpp index 879f5b3272dc..cc22db9fa2fd 100644 --- a/libevmasm/PeepholeOptimiser.cpp +++ b/libevmasm/PeepholeOptimiser.cpp @@ -690,16 +690,12 @@ struct DeduplicateNextTagSize1 : SimplePeepholeOptimizerMethod +void applyMethods(OptimiserState& _state) { - assertThrow(false, OptimizerException, "Peephole optimizer failed to apply identity."); -} - -template -void applyMethods(OptimiserState& _state, Method, OtherMethods... _other) -{ - if (!Method::apply(_state)) - applyMethods(_state, _other...); + bool continueWithNextMethod = true; + ((continueWithNextMethod && (continueWithNextMethod &= !Method::apply(_state))), ...); + assertThrow(!continueWithNextMethod, OptimizerException, "Peephole optimizer failed to apply identity."); } size_t numberOfPops(AssemblyItems const& _items) @@ -721,33 +717,32 @@ bool PeepholeOptimiser::optimise() auto const approx = evmasm::Precision::Approximate; OptimiserState state {m_items, 0, back_inserter(m_optimisedItems), m_evmVersion}; while (state.i < m_items.size()) - applyMethods( - state, - PushPop(), - OpPop(), - OpStop(), - OpReturnRevert(), - DoublePush(), - DoubleSwap(), - CommutativeSwap(), - SwapComparison(), - DupSwap(), - IsZeroIsZeroJumpI(), - IsZeroIsZeroRJumpI(), // EOF specific - EqIsZeroJumpI(), - EqIsZeroRJumpI(), // EOF specific - DoubleJump(), - DoubleRJump(), // EOF specific - JumpToNext(), - RJumpToNext(), // EOF specific - UnreachableCode(), - DeduplicateNextTagSize3(), - DeduplicateNextTagSize2(), - DeduplicateNextTagSize1(), - TagConjunctions(), - TruthyAnd(), - Identity() - ); + applyMethods< + PushPop, + OpPop, + OpStop, + OpReturnRevert, + DoublePush, + DoubleSwap, + CommutativeSwap, + SwapComparison, + DupSwap, + IsZeroIsZeroJumpI, + IsZeroIsZeroRJumpI, // EOF specific + EqIsZeroJumpI, + EqIsZeroRJumpI, // EOF specific + DoubleJump, + DoubleRJump, // EOF specific + JumpToNext, + RJumpToNext, // EOF specific + UnreachableCode, + DeduplicateNextTagSize3, + DeduplicateNextTagSize2, + DeduplicateNextTagSize1, + TagConjunctions, + TruthyAnd, + Identity + >(state); if (m_optimisedItems.size() < m_items.size() || ( m_optimisedItems.size() == m_items.size() && ( evmasm::bytesRequired(m_optimisedItems, 3, m_evmVersion, approx) < evmasm::bytesRequired(m_items, 3, m_evmVersion, approx) || From 098b854ce59393a1ef48e06de6b031a793486508 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Mon, 17 Mar 2025 09:38:07 +0100 Subject: [PATCH 0889/1022] IRGeneratorForStatements does not check for builtin when mangling user identifiers --- .../codegen/ir/IRGeneratorForStatements.cpp | 21 +++++++------------ .../codegen/IRGeneratorForStatements.cpp | 11 +++------- 2 files changed, 11 insertions(+), 21 deletions(-) diff --git a/libsolidity/codegen/ir/IRGeneratorForStatements.cpp b/libsolidity/codegen/ir/IRGeneratorForStatements.cpp index c716c43a6070..5902cfef68b6 100644 --- a/libsolidity/codegen/ir/IRGeneratorForStatements.cpp +++ b/libsolidity/codegen/ir/IRGeneratorForStatements.cpp @@ -63,8 +63,8 @@ struct CopyTranslate: public yul::ASTCopier { using ExternalRefsMap = std::map; - CopyTranslate(yul::Dialect const& _dialect, IRGenerationContext& _context, ExternalRefsMap const& _references): - m_dialect(_dialect), m_context(_context), m_references(_references) {} + CopyTranslate(IRGenerationContext& _context, ExternalRefsMap const& _references): + m_context(_context), m_references(_references) {} using ASTCopier::operator(); @@ -80,14 +80,11 @@ struct CopyTranslate: public yul::ASTCopier yul::YulName translateIdentifier(yul::YulName _name) override { - // Strictly, the dialect used by inline assembly (m_dialect) could be different - // from the Yul dialect we are compiling to. So we are assuming here that the builtin - // functions are identical. This should not be a problem for now since everything - // is EVM anyway. - if (m_dialect.findBuiltin(_name.str())) - return _name; - else - return yul::YulName{"usr$" + _name.str()}; + // Strictly, the dialect used by inline assembly could be different + // from the Yul dialect we are compiling to. By only translating `YulName`s which correspond to Identifiers, + // we are implicitly excluding builtins together with the assumption, that numerical builtin handles + // stay identical. Special care has to be taken, that these numerical handles stay consistent. + return yul::YulName{"usr$" + _name.str()}; } yul::Identifier translate(yul::Identifier const& _identifier) override @@ -209,8 +206,6 @@ struct CopyTranslate: public yul::ASTCopier return yul::Identifier{_identifier.debugData, yul::YulName{value}}; } - - yul::Dialect const& m_dialect; IRGenerationContext& m_context; ExternalRefsMap const& m_references; }; @@ -2294,7 +2289,7 @@ bool IRGeneratorForStatements::visit(InlineAssembly const& _inlineAsm) setLocation(_inlineAsm); if (*_inlineAsm.annotation().hasMemoryEffects && !_inlineAsm.annotation().markedMemorySafe) m_context.setMemoryUnsafeInlineAssemblySeen(); - CopyTranslate bodyCopier{_inlineAsm.dialect(), m_context, _inlineAsm.annotation().externalReferences}; + CopyTranslate bodyCopier{m_context, _inlineAsm.annotation().externalReferences}; yul::Statement modified = bodyCopier(_inlineAsm.operations().root()); diff --git a/libsolidity/experimental/codegen/IRGeneratorForStatements.cpp b/libsolidity/experimental/codegen/IRGeneratorForStatements.cpp index 80c442b88146..14aef1107dd3 100644 --- a/libsolidity/experimental/codegen/IRGeneratorForStatements.cpp +++ b/libsolidity/experimental/codegen/IRGeneratorForStatements.cpp @@ -54,9 +54,8 @@ struct CopyTranslate: public yul::ASTCopier { CopyTranslate( IRGenerationContext const& _context, - yul::Dialect const& _dialect, std::map _references - ): m_context(_context), m_dialect(_dialect), m_references(std::move(_references)) {} + ): m_context(_context), m_references(std::move(_references)) {} using ASTCopier::operator(); @@ -72,10 +71,7 @@ struct CopyTranslate: public yul::ASTCopier yul::YulName translateIdentifier(yul::YulName _name) override { - if (m_dialect.findBuiltin(_name.str())) - return _name; - else - return yul::YulName{"usr$" + _name.str()}; + return yul::YulName{"usr$" + _name.str()}; } yul::Identifier translate(yul::Identifier const& _identifier) override @@ -106,7 +102,6 @@ struct CopyTranslate: public yul::ASTCopier } IRGenerationContext const& m_context; - yul::Dialect const& m_dialect; std::map m_references; }; @@ -129,7 +124,7 @@ bool IRGeneratorForStatements::visit(TupleExpression const& _tupleExpression) bool IRGeneratorForStatements::visit(InlineAssembly const& _assembly) { - CopyTranslate bodyCopier{m_context, _assembly.dialect(), _assembly.annotation().externalReferences}; + CopyTranslate bodyCopier{m_context, _assembly.annotation().externalReferences}; yul::Statement modified = bodyCopier(_assembly.operations().root()); solAssert(std::holds_alternative(modified)); m_code << yul::AsmPrinter(_assembly.dialect())(std::get(modified)) << "\n"; From 08c9f535288b0d5a337c9dd416a47333791b41b9 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Wed, 12 Mar 2025 16:41:03 +0100 Subject: [PATCH 0890/1022] AssemblyItem gets an optional instruction and the null-state is properly asserted --- libevmasm/AssemblyItem.h | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/libevmasm/AssemblyItem.h b/libevmasm/AssemblyItem.h index b053c5b27598..8b65d77c91e9 100644 --- a/libevmasm/AssemblyItem.h +++ b/libevmasm/AssemblyItem.h @@ -105,7 +105,6 @@ class AssemblyItem explicit AssemblyItem(bytes _verbatimData, size_t _arguments, size_t _returnVariables): m_type(VerbatimBytecode), - m_instruction{}, m_verbatimBytecode{{_arguments, _returnVariables, std::move(_verbatimData)}}, m_debugData{langutil::DebugData::create()} {} @@ -195,7 +194,7 @@ class AssemblyItem /// @returns true if the item has m_instruction properly set. bool hasInstruction() const { - return + bool const shouldHaveInstruction = m_type == Operation || m_type == EOFCreate || m_type == ReturnContract || @@ -206,12 +205,14 @@ class AssemblyItem m_type == RetF || m_type == SwapN || m_type == DupN; + solAssert(shouldHaveInstruction == m_instruction.has_value()); + return shouldHaveInstruction; } /// @returns the instruction of this item (only valid if hasInstruction returns true) Instruction instruction() const { solAssert(hasInstruction()); - return m_instruction; + return *m_instruction; } /// @returns true if the type and data of the items are equal. @@ -323,7 +324,7 @@ class AssemblyItem size_t opcodeCount() const noexcept; AssemblyItemType m_type; - Instruction m_instruction; ///< Only valid if m_type == Operation + std::optional m_instruction; ///< Only valid for item types that represent a specific opcode std::shared_ptr m_data; ///< Only valid if m_type != Operation std::optional m_functionSignature; ///< Only valid if m_type == CallF or JumpF /// If m_type == VerbatimBytecode, this holds number of arguments, number of From dd03613b791b3d13d43b95e253c414eeeb27c35b Mon Sep 17 00:00:00 2001 From: Martin Blicha Date: Thu, 20 Mar 2025 22:26:14 +0100 Subject: [PATCH 0891/1022] SMTChecker: Fix string literal to fixed bytes conversion with user-defined type --- Changelog.md | 1 + libsolidity/formal/SMTEncoder.cpp | 6 ++++-- ...tes_can_be_initialized_from_string_literal.sol | 15 +++++++++++++++ 3 files changed, 20 insertions(+), 2 deletions(-) create mode 100644 test/libsolidity/smtCheckerTests/userTypes/user_type_over_fixed_bytes_can_be_initialized_from_string_literal.sol diff --git a/Changelog.md b/Changelog.md index 3e423c838b67..7efefca02d6a 100644 --- a/Changelog.md +++ b/Changelog.md @@ -8,6 +8,7 @@ Compiler Features: Bugfixes: * SMTChecker: Fix incorrect analysis when only a subset of contracts is selected with `--model-checker-contracts`. +* SMTChecker: Fix internal compiler error when string literal is used to initialize user-defined type based on fixed bytes. ### 0.8.29 (2025-03-12) diff --git a/libsolidity/formal/SMTEncoder.cpp b/libsolidity/formal/SMTEncoder.cpp index 740af9382b88..044ff61d8225 100644 --- a/libsolidity/formal/SMTEncoder.cpp +++ b/libsolidity/formal/SMTEncoder.cpp @@ -929,8 +929,10 @@ void SMTEncoder::visitAddMulMod(FunctionCall const& _funCall) void SMTEncoder::visitWrapUnwrap(FunctionCall const& _funCall) { auto const& args = _funCall.arguments(); - solAssert(args.size() == 1, ""); - defineExpr(_funCall, expr(*args.front())); + smtAssert(args.size() == 1, "Expected exactly one argument to wrap/unwrap"); + auto const& funType = dynamic_cast(*_funCall.expression().annotation().type); + auto const* argType = funType.parameterTypes().front(); + defineExpr(_funCall, expr(*args.front(), argType)); } void SMTEncoder::visitObjectCreation(FunctionCall const& _funCall) diff --git a/test/libsolidity/smtCheckerTests/userTypes/user_type_over_fixed_bytes_can_be_initialized_from_string_literal.sol b/test/libsolidity/smtCheckerTests/userTypes/user_type_over_fixed_bytes_can_be_initialized_from_string_literal.sol new file mode 100644 index 000000000000..fe64541f116e --- /dev/null +++ b/test/libsolidity/smtCheckerTests/userTypes/user_type_over_fixed_bytes_can_be_initialized_from_string_literal.sol @@ -0,0 +1,15 @@ +type MyBytes is bytes2; + +contract C { + MyBytes b = MyBytes.wrap("ab"); + + function check() view public { + assert(MyBytes.unwrap(b) == 0); // should fail + assert(MyBytes.unwrap(b) == 0x6162); // should hold + } +} +// ==== +// SMTEngine: chc +// ---- +// Warning 6328: (118-148): CHC: Assertion violation happens here.\nCounterexample:\n\n\nTransaction trace:\nC.constructor()\nC.check() +// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. From d97d7115815314af238de314d710abd4a1aa6868 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kaan=20Uzdo=C4=9Fan?= Date: Wed, 26 Feb 2025 16:10:25 -0700 Subject: [PATCH 0892/1022] Update metadata docs for "libraries" and "compilationSettings" fields --- docs/metadata.rst | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/docs/metadata.rst b/docs/metadata.rst index 063936a9dcde..e5945ea5235c 100644 --- a/docs/metadata.rst +++ b/docs/metadata.rst @@ -124,11 +124,13 @@ explanatory purposes. "version": 1 // NatSpec version } }, - // Required: Compiler settings. Reflects the settings in the JSON input during compilation. - // Check the documentation of standard JSON input's "settings" field + // Required: Compiler settings. + // Reflects the settings in the JSON input during compilation, except the + // "compilationTarget" and the "libraries" fields. Check each field for details. + // See the standard JSON input's "settings" docs for the rest. "settings": { // Required for Solidity: File path and the name of the contract or library this - // metadata is created for. + // metadata is created for. Not a valid field in the standard JSON input settings. "compilationTarget": { "myDirectory/myFile.sol": "MyContract" }, @@ -137,8 +139,11 @@ explanatory purposes. // Optional: Only present if not null. "eofVersion": 1, // Required for Solidity: Addresses for libraries used. + // Note that metadata has a different format for "libraries" field than the standard JSON input. + // metadata format = { "MyLib.sol:MyLib": "0x123123..." } + // standard JSON input format = { "MyLib.sol": { "MyLib": "0x123123..." } } "libraries": { - "MyLib": "0x123123..." + "MyLib.sol:MyLib": "0x123123..." }, "metadata": { // Reflects the setting used in the input json, defaults to "true" From 2e33f2557c2c91b59c7d5593389992d7f09b26ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kaan=20Uzdo=C4=9Fan?= Date: Wed, 26 Feb 2025 16:21:22 -0700 Subject: [PATCH 0893/1022] Update the metdata settings field to refer the rest of the settings to std-json --- docs/metadata.rst | 54 ++++++++++------------------------------------- 1 file changed, 11 insertions(+), 43 deletions(-) diff --git a/docs/metadata.rst b/docs/metadata.rst index e5945ea5235c..90513ee326de 100644 --- a/docs/metadata.rst +++ b/docs/metadata.rst @@ -124,20 +124,18 @@ explanatory purposes. "version": 1 // NatSpec version } }, - // Required: Compiler settings. - // Reflects the settings in the JSON input during compilation, except the - // "compilationTarget" and the "libraries" fields. Check each field for details. - // See the standard JSON input's "settings" docs for the rest. + // Required: Compiler settings. + // Reflects the settings in the JSON input during compilation, except: + // - Different format: "libraries" field + // - Added field in metadata.settings: "compilationTarget" + // - Not in metadata.settings: "stopAfter", "debug.debugInfo", "outputSelection" + // See the standard JSON input's "settings" field docs for the rest. "settings": { // Required for Solidity: File path and the name of the contract or library this - // metadata is created for. Not a valid field in the standard JSON input settings. + // metadata is created for. This field is not present in the standard JSON input settings. "compilationTarget": { "myDirectory/myFile.sol": "MyContract" }, - // Required for Solidity. - "evmVersion": "london", - // Optional: Only present if not null. - "eofVersion": 1, // Required for Solidity: Addresses for libraries used. // Note that metadata has a different format for "libraries" field than the standard JSON input. // metadata format = { "MyLib.sol:MyLib": "0x123123..." } @@ -145,40 +143,10 @@ explanatory purposes. "libraries": { "MyLib.sol:MyLib": "0x123123..." }, - "metadata": { - // Reflects the setting used in the input json, defaults to "true" - "appendCBOR": true, - // Reflects the setting used in the input json, defaults to "ipfs" - "bytecodeHash": "ipfs", - // Reflects the setting used in the input json, defaults to "false" - "useLiteralContent": true - }, - // Optional: Optimizer settings. The fields "enabled" and "runs" are deprecated - // and are only given for backward-compatibility. - "optimizer": { - "details": { - "constantOptimizer": false, - "cse": false, - "deduplicate": false, - // inliner defaults to "false" - "inliner": false, - // jumpdestRemover defaults to "true" - "jumpdestRemover": true, - "orderLiterals": false, - // peephole defaults to "true" - "peephole": true, - "yul": true, - // Optional: Only present if "yul" is "true" - "yulDetails": { - "optimizerSteps": "dhfoDgvulfnTUtnIf...", - "stackAllocation": false - } - }, - "enabled": true, - "runs": 500 - }, - // Required for Solidity: Sorted list of import remappings. - "remappings": [ ":g=/dir" ] + // ... + // ... + // ... + // The rest of the fields and their defaults same as in std JSON input. }, // Required: Compilation source files/source units, keys are file paths "sources": { From 1f044c153365955b48d19ae90fa8a57db359c870 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kaan=20Uzdo=C4=9Fan?= Date: Thu, 20 Mar 2025 10:29:03 +0100 Subject: [PATCH 0894/1022] Remove "sorted" in std-json remappings docs --- docs/using-the-compiler.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/using-the-compiler.rst b/docs/using-the-compiler.rst index 4984d999df27..23e83baec4e6 100644 --- a/docs/using-the-compiler.rst +++ b/docs/using-the-compiler.rst @@ -279,7 +279,7 @@ Input Description { // Optional: Stop compilation after the given stage. Currently only "parsing" is valid here "stopAfter": "parsing", - // Optional: Sorted list of remappings + // Optional: List of remappings "remappings": [ ":g=/dir" ], // Optional: Optimizer settings "optimizer": { From 1ccea419e6770553f15ce80872be21165ba946c5 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Fri, 14 Mar 2025 09:24:30 +0100 Subject: [PATCH 0895/1022] AsmAnalysis: Stronger use of fmt, refactor function call analysis --- libyul/AsmAnalysis.cpp | 272 ++++++++++++++++++++++------------------- libyul/AsmAnalysis.h | 19 +-- 2 files changed, 161 insertions(+), 130 deletions(-) diff --git a/libyul/AsmAnalysis.cpp b/libyul/AsmAnalysis.cpp index b6ff862b3850..480373d13271 100644 --- a/libyul/AsmAnalysis.cpp +++ b/libyul/AsmAnalysis.cpp @@ -94,19 +94,28 @@ bool AsmAnalyzer::analyze(Block const& _block) AsmAnalysisInfo AsmAnalyzer::analyzeStrictAssertCorrect(Object const& _object) { yulAssert(_object.dialect()); - return analyzeStrictAssertCorrect(*_object.dialect(), _object.code()->root(), _object.summarizeStructure()); + return analyzeStrictAssertCorrect(*_object.dialect(), *_object.code(), _object.summarizeStructure()); +} + +AsmAnalysisInfo AsmAnalyzer::analyzeStrictAssertCorrect( + Dialect const& _dialect, + AST const& _ast, + Object::Structure _objectStructure +) +{ + return analyzeStrictAssertCorrect(_dialect, _ast.root(), std::move(_objectStructure)); } AsmAnalysisInfo AsmAnalyzer::analyzeStrictAssertCorrect( Dialect const& _dialect, Block const& _astRoot, - Object::Structure const _objectStructure + Object::Structure _objectStructure ) { ErrorList errorList; langutil::ErrorReporter errors(errorList); AsmAnalysisInfo analysisInfo; - bool success = yul::AsmAnalyzer( + bool success = AsmAnalyzer( analysisInfo, errors, _dialect, @@ -155,7 +164,7 @@ size_t AsmAnalyzer::operator()(Literal const& _literal) m_errorReporter.typeError( 3069_error, nativeLocationOf(_literal), - "String literal too long (" + std::to_string(formatLiteral(_literal, false /* _validated */ ).size()) + " > 32)" + fmt::format("String literal too long ({} > 32)", formatLiteral(_literal, false /* _validated */ ).size()) ); } else if (_literal.kind == LiteralKind::Number && _literal.value.hint() && bigint(*_literal.value.hint()) > u256(-1)) @@ -170,7 +179,7 @@ size_t AsmAnalyzer::operator()(Literal const& _literal) size_t AsmAnalyzer::operator()(Identifier const& _identifier) { - yulAssert(!_identifier.name.empty(), ""); + yulAssert(!_identifier.name.empty()); auto watcher = m_errorReporter.errorWatcher(); if (m_currentScope->lookup(_identifier.name, GenericVisitor{ @@ -180,7 +189,7 @@ size_t AsmAnalyzer::operator()(Identifier const& _identifier) m_errorReporter.declarationError( 4990_error, nativeLocationOf(_identifier), - "Variable " + _identifier.name.str() + " used before it was declared." + fmt::format("Variable {} used before it was declared.", _identifier.name.str()) ); }, [&](Scope::Function const&) @@ -188,14 +197,15 @@ size_t AsmAnalyzer::operator()(Identifier const& _identifier) m_errorReporter.typeError( 6041_error, nativeLocationOf(_identifier), - "Function " + _identifier.name.str() + " used without being called." + fmt::format("Function {} used without being called.", _identifier.name.str()) ); } })) { if (m_resolver) // We found a local reference, make sure there is no external reference. - m_resolver( + // Used for side effects, e.g., error reporting in TypeChecker, hence ignoring return value + std::ignore = m_resolver( _identifier, yul::IdentifierContext::NonExternal, m_currentScope->insideFunction() @@ -213,7 +223,7 @@ size_t AsmAnalyzer::operator()(Identifier const& _identifier) m_errorReporter.declarationError( 8198_error, nativeLocationOf(_identifier), - "Identifier \"" + _identifier.name.str() + "\" not found." + fmt::format("Identifier \"{}\" not found.", _identifier.name.str()) ); } @@ -229,11 +239,12 @@ void AsmAnalyzer::operator()(ExpressionStatement const& _statement) m_errorReporter.typeError( 3083_error, nativeLocationOf(_statement), - "Top-level expressions are not supposed to return values (this expression returns " + - std::to_string(numReturns) + - " value" + - (numReturns == 1 ? "" : "s") + - "). Use ``pop()`` or assign them." + fmt::format( + "Top-level expressions are not supposed to return values (this expression returns {} value{}). " + "Use ``pop()`` or assign them.", + numReturns, + numReturns == 1 ? "" : "s" + ) ); } @@ -249,9 +260,10 @@ void AsmAnalyzer::operator()(Assignment const& _assignment) m_errorReporter.declarationError( 9005_error, nativeLocationOf(_assignment), - "Variable " + - _variableName.name.str() + - " occurs multiple times on the left-hand side of the assignment." + fmt::format( + "Variable {} occurs multiple times on the left-hand side of the assignment.", + _variableName.name.str() + ) ); size_t numRhsValues = std::visit(*this, *_assignment.value); @@ -260,13 +272,12 @@ void AsmAnalyzer::operator()(Assignment const& _assignment) m_errorReporter.declarationError( 8678_error, nativeLocationOf(_assignment), - "Variable count for assignment to \"" + - joinHumanReadable(applyMap(_assignment.variableNames, [](auto const& _identifier){ return _identifier.name.str(); })) + - "\" does not match number of values (" + - std::to_string(numVariables) + - " vs. " + - std::to_string(numRhsValues) + - ")" + fmt::format( + "Variable count for assignment to \"{}\" does not match number of values ({} vs. {})", + joinHumanReadable(applyMap(_assignment.variableNames, [](auto const& _identifier){ return _identifier.name.str(); })), + numVariables, + numRhsValues + ) ); for (size_t i = 0; i < numVariables; ++i) @@ -296,13 +307,12 @@ void AsmAnalyzer::operator()(VariableDeclaration const& _varDecl) m_errorReporter.declarationError( 3812_error, nativeLocationOf(_varDecl), - "Variable count mismatch for declaration of \"" + - joinHumanReadable(applyMap(_varDecl.variables, [](auto const& _identifier){ return _identifier.name.str(); })) + - + "\": " + - std::to_string(numVariables) + - " variables and " + - std::to_string(numValues) + - " values." + fmt::format( + "Variable count mismatch for declaration of \"{}\": {} variables and {} values.", + joinHumanReadable(applyMap(_varDecl.variables, [](auto const& _identifier){ return _identifier.name.str(); })), + numVariables, + numValues + ) ); } @@ -314,7 +324,7 @@ void AsmAnalyzer::operator()(VariableDeclaration const& _varDecl) void AsmAnalyzer::operator()(FunctionDefinition const& _funDef) { - yulAssert(!_funDef.name.empty(), ""); + yulAssert(!_funDef.name.empty()); expectValidIdentifier(_funDef.name, nativeLocationOf(_funDef)); Block const* virtualBlock = m_info.virtualBlocks.at(&_funDef).get(); yulAssert(virtualBlock, ""); @@ -352,77 +362,89 @@ size_t AsmAnalyzer::operator()(FunctionCall const& _funCall) std::optional numReturns; std::vector> const* literalArguments = nullptr; - if (BuiltinFunction const* builtin = resolveBuiltinFunction(_funCall.functionName, m_dialect)) - { - if (builtin->name == "selfdestruct") - m_errorReporter.warning( - 1699_error, - nativeLocationOf(_funCall.functionName), - "\"selfdestruct\" has been deprecated. " - "Note that, starting from the Cancun hard fork, the underlying opcode no longer deletes the code and " - "data associated with an account and only transfers its Ether to the beneficiary, " - "unless executed in the same transaction in which the contract was created (see EIP-6780). " - "Any use in newly deployed contracts is strongly discouraged even if the new behavior is taken into account. " - "Future changes to the EVM might further reduce the functionality of the opcode." - ); - else if ( - m_evmVersion.supportsTransientStorage() && - builtin->name == "tstore" && - !m_errorReporter.hasError({2394}) - ) - m_errorReporter.warning( - 2394_error, - nativeLocationOf(_funCall.functionName), - "Transient storage as defined by EIP-1153 can break the composability of smart contracts: " - "Since transient storage is cleared only at the end of the transaction and not at the end of the outermost call frame to the contract within a transaction, " - "your contract may unintentionally misbehave when invoked multiple times in a complex transaction. " - "To avoid this, be sure to clear all transient storage at the end of any call to your contract. " - "The use of transient storage for reentrancy guards that are cleared at the end of the call is safe." - ); + std::visit( + GenericVisitor { + [&](BuiltinName const& _builtinName) + { + BuiltinFunction const& builtin = m_dialect.builtin(_builtinName.handle); + if (builtin.name == "selfdestruct") + m_errorReporter.warning( + 1699_error, + nativeLocationOf(_builtinName), + "\"selfdestruct\" has been deprecated. " + "Note that, starting from the Cancun hard fork, the underlying opcode no longer deletes the code and " + "data associated with an account and only transfers its Ether to the beneficiary, " + "unless executed in the same transaction in which the contract was created (see EIP-6780). " + "Any use in newly deployed contracts is strongly discouraged even if the new behavior is taken into account. " + "Future changes to the EVM might further reduce the functionality of the opcode." + ); + else if ( + builtin.name == "tstore" && + !m_errorReporter.hasError({2394}) + ) + { + yulAssert(m_evmVersion.supportsTransientStorage(), "tstore is only a builtin on EVMs that support transient storage"); + m_errorReporter.warning( + 2394_error, + nativeLocationOf(_builtinName), + "Transient storage as defined by EIP-1153 can break the composability of smart contracts: " + "Since transient storage is cleared only at the end of the transaction and not at the end of the outermost call frame to the contract within a transaction, " + "your contract may unintentionally misbehave when invoked multiple times in a complex transaction. " + "To avoid this, be sure to clear all transient storage at the end of any call to your contract. " + "The use of transient storage for reentrancy guards that are cleared at the end of the call is safe." + ); + } - numParameters = builtin->numParameters; - numReturns = builtin->numReturns; - if (!builtin->literalArguments.empty()) - literalArguments = &builtin->literalArguments; + numParameters = builtin.numParameters; + numReturns = builtin.numReturns; + if (!builtin.literalArguments.empty()) + literalArguments = &builtin.literalArguments; - validateInstructions(_funCall); - m_sideEffects += builtin->sideEffects; - } - else if (m_currentScope->lookup(YulName{resolveFunctionName(_funCall.functionName, m_dialect)}, GenericVisitor{ - [&](Scope::Variable const&) - { - m_errorReporter.typeError( - 4202_error, - nativeLocationOf(_funCall.functionName), - "Attempt to call variable instead of function." - ); + validateInstructions(_funCall); + m_sideEffects += builtin.sideEffects; + }, + [&](Identifier const& _identifier) + { + bool const identifierInCurrentScope = m_currentScope->lookup(_identifier.name, GenericVisitor{ + [&](Scope::Variable const&) + { + m_errorReporter.typeError( + 4202_error, + nativeLocationOf(_identifier), + "Attempt to call variable instead of function." + ); + }, + [&](Scope::Function const& _fun) + { + numParameters = _fun.numArguments; + numReturns = _fun.numReturns; + } + }); + if (identifierInCurrentScope) + { + if (m_resolver) + // We found a local reference, make sure there is no external reference. + // Used for side effects, e.g., error reporting in TypeChecker, hence ignoring return value + std::ignore = m_resolver( + _identifier, + yul::IdentifierContext::NonExternal, + m_currentScope->insideFunction() + ); + } + else + { + if (!validateInstructions(_funCall)) + m_errorReporter.declarationError( + 4619_error, + nativeLocationOf(_identifier), + fmt::format("Function \"{}\" not found.", _identifier.name.str()) + ); + yulAssert(!watcher.ok(), "Expected a reported error."); + } + } }, - [&](Scope::Function const& _fun) - { - numParameters = _fun.numArguments; - numReturns = _fun.numReturns; - } - })) - { - yulAssert(std::holds_alternative(_funCall.functionName)); - if (m_resolver) - // We found a local reference, make sure there is no external reference. - m_resolver( - std::get(_funCall.functionName), - yul::IdentifierContext::NonExternal, - m_currentScope->insideFunction() - ); - } - else - { - if (!validateInstructions(_funCall)) - m_errorReporter.declarationError( - 4619_error, - nativeLocationOf(_funCall.functionName), - fmt::format("Function \"{}\" not found.", resolveFunctionName(_funCall.functionName, m_dialect)) - ); - yulAssert(!watcher.ok(), "Expected a reported error."); - } + _funCall.functionName + ); if (numParameters && _funCall.arguments.size() != *numParameters) m_errorReporter.typeError( @@ -455,7 +477,7 @@ size_t AsmAnalyzer::operator()(FunctionCall const& _funCall) m_errorReporter.typeError( 5859_error, nativeLocationOf(arg), - "Function expects " + to_string(*literalArgumentKind) + " literal." + fmt::format("Function expects {} literal.", to_string(*literalArgumentKind)) ); else if (*literalArgumentKind == LiteralKind::String) { @@ -467,7 +489,7 @@ size_t AsmAnalyzer::operator()(FunctionCall const& _funCall) m_errorReporter.typeError( 3517_error, nativeLocationOf(arg), - "Unknown data object \"" + formatLiteral(argumentAsLiteral) + "\"." + fmt::format("Unknown data object \"{}\".", formatLiteral(argumentAsLiteral)) ); } else if (functionName.substr(0, "verbatim_"s.size()) == "verbatim_") @@ -499,14 +521,17 @@ size_t AsmAnalyzer::operator()(FunctionCall const& _funCall) m_errorReporter.typeError( 7575_error, nativeLocationOf(arg), - "Data name \"" + formattedLiteral + "\" cannot be used as an argument of eofcreate/returncontract. " + - "An object name is only acceptable." + fmt::format( + "Data name \"{}\" cannot be used as an argument of eofcreate/returncontract. " + "An object name is only acceptable.", + formattedLiteral + ) ); else m_errorReporter.typeError( 8970_error, nativeLocationOf(arg), - "Unknown object \"" + formattedLiteral + "\"." + fmt::format("Unknown object \"{}\".", formattedLiteral) ); } } @@ -579,9 +604,7 @@ void AsmAnalyzer::operator()(Switch const& _switch) m_errorReporter.declarationError( 6792_error, nativeLocationOf(_case), - "Duplicate case \"" + - formatLiteral(*_case.value) + - "\" defined." + fmt::format("Duplicate case \"{}\" defined.", formatLiteral(*_case.value)) ); } @@ -631,9 +654,10 @@ void AsmAnalyzer::expectExpression(Expression const& _expr) m_errorReporter.typeError( 3950_error, nativeLocationOf(_expr), - "Expected expression to evaluate to one value, but got " + - std::to_string(numValues) + - " values instead." + fmt::format( + "Expected expression to evaluate to one value, but got {} values instead.", + numValues + ) ); } @@ -645,7 +669,7 @@ void AsmAnalyzer::expectUnlimitedStringLiteral(Literal const& _literal) void AsmAnalyzer::checkAssignment(Identifier const& _variable) { - yulAssert(!_variable.name.empty(), ""); + yulAssert(!_variable.name.empty()); auto watcher = m_errorReporter.errorWatcher(); bool hasVariable = false; bool found = false; @@ -653,7 +677,8 @@ void AsmAnalyzer::checkAssignment(Identifier const& _variable) { if (m_resolver) // We found a local reference, make sure there is no external reference. - m_resolver( + // Used for side effects, e.g., error reporting in TypeChecker, hence ignoring return value + std::ignore = m_resolver( _variable, yul::IdentifierContext::NonExternal, m_currentScope->insideFunction() @@ -665,7 +690,7 @@ void AsmAnalyzer::checkAssignment(Identifier const& _variable) m_errorReporter.declarationError( 1133_error, nativeLocationOf(_variable), - "Variable " + _variable.name.str() + " used before it was declared." + fmt::format("Variable {} used before it was declared.", _variable.name.str()) ); else hasVariable = true; @@ -698,26 +723,27 @@ Scope& AsmAnalyzer::scope(Block const* _block) void AsmAnalyzer::expectValidIdentifier(YulName _identifier, SourceLocation const& _location) { + std::string_view const label = _identifier.str(); // NOTE: the leading dot case is handled by the parser not allowing it. - if (boost::ends_with(_identifier.str(), ".")) + if (label.ends_with('.')) m_errorReporter.syntaxError( 3384_error, _location, - "\"" + _identifier.str() + "\" is not a valid identifier (ends with a dot)." + fmt::format("\"{}\" is not a valid identifier (ends with a dot).", label) ); - if (_identifier.str().find("..") != std::string::npos) + if (label.find("..") != std::string::npos) m_errorReporter.syntaxError( 7771_error, _location, - "\"" + _identifier.str() + "\" is not a valid identifier (contains consecutive dots)." + fmt::format("\"{}\" is not a valid identifier (contains consecutive dots).", label) ); - if (m_dialect.reservedIdentifier(_identifier.str())) + if (m_dialect.reservedIdentifier(label)) m_errorReporter.declarationError( 5017_error, _location, - "The identifier \"" + _identifier.str() + "\" is reserved and can not be used." + fmt::format("The identifier \"{}\" is reserved and can not be used.", label) ); } @@ -744,7 +770,7 @@ bool AsmAnalyzer::validateInstructions(std::string_view _instructionIdentifier, 7223_error, _location, fmt::format( - "Builtin function \"{}\" is only available in EOF.", + "Builtin function \"{function}\" is only available in EOF.", fmt::arg("function", _instructionIdentifier) ) ); @@ -844,7 +870,7 @@ bool AsmAnalyzer::validateInstructions(evmasm::Instruction _instr, SourceLocatio 4328_error, _location, fmt::format( - "The \"{}\" instruction is only available in EOF.", + "The \"{instruction}\" instruction is only available in EOF.", fmt::arg("instruction", boost::to_lower_copy(instructionInfo(_instr, m_evmVersion).name)) ) ); @@ -899,7 +925,7 @@ bool AsmAnalyzer::validateInstructions(FunctionCall const& _functionCall) ); } -void AsmAnalyzer::validateObjectStructure(langutil::SourceLocation _astRootLocation) +void AsmAnalyzer::validateObjectStructure(langutil::SourceLocation const& _astRootLocation) { if (m_eofVersion.has_value()) { diff --git a/libyul/AsmAnalysis.h b/libyul/AsmAnalysis.h index e8c02fbec132..51b8cde2ba1f 100644 --- a/libyul/AsmAnalysis.h +++ b/libyul/AsmAnalysis.h @@ -62,7 +62,7 @@ class AsmAnalyzer langutil::ErrorReporter& _errorReporter, Dialect const& _dialect, ExternalIdentifierAccess::Resolver _resolver = ExternalIdentifierAccess::Resolver(), - Object::Structure const _objectStructure = {} + Object::Structure _objectStructure = {} ): m_resolver(std::move(_resolver)), m_info(_analysisInfo), @@ -85,7 +85,12 @@ class AsmAnalyzer static AsmAnalysisInfo analyzeStrictAssertCorrect( Dialect const& _dialect, Block const& _astRoot, - Object::Structure const _objectStructure + Object::Structure _objectStructure + ); + static AsmAnalysisInfo analyzeStrictAssertCorrect( + Dialect const& _dialect, + AST const& _ast, + Object::Structure _objectStructure ); size_t operator()(Literal const& _literal); @@ -98,9 +103,9 @@ class AsmAnalyzer void operator()(If const& _if); void operator()(Switch const& _switch); void operator()(ForLoop const& _forLoop); - void operator()(Break const&) { } - void operator()(Continue const&) { } - void operator()(Leave const&) { } + void operator()(Break const&) const { } + void operator()(Continue const&) const { } + void operator()(Leave const&) const { } void operator()(Block const& _block); /// @returns the worst side effects encountered during analysis (including within defined functions). @@ -109,7 +114,7 @@ class AsmAnalyzer /// Visits the expression, expects that it evaluates to exactly one value. /// Reports errors otherwise. void expectExpression(Expression const& _expr); - void expectUnlimitedStringLiteral(Literal const& _literal); + static void expectUnlimitedStringLiteral(Literal const& _literal); /// Verifies that a variable to be assigned to exists and can be assigned to. void checkAssignment(Identifier const& _variable); @@ -121,7 +126,7 @@ class AsmAnalyzer bool validateInstructions(std::string_view _instrIdentifier, langutil::SourceLocation const& _location); bool validateInstructions(FunctionCall const& _functionCall); - void validateObjectStructure(langutil::SourceLocation _astRootLocation); + void validateObjectStructure(langutil::SourceLocation const& _astRootLocation); yul::ExternalIdentifierAccess::Resolver m_resolver; Scope* m_currentScope = nullptr; From b9cbf1e7db82b74c1c07801a05f663321889ce26 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Fri, 21 Mar 2025 09:17:09 +0100 Subject: [PATCH 0896/1022] AsmAnalysis: Improve wording of invalid argument for eofcreate/returncontract error --- libyul/AsmAnalysis.cpp | 2 +- .../yulSyntaxTests/eof/eofcreate_invalid_object_name_data.yul | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libyul/AsmAnalysis.cpp b/libyul/AsmAnalysis.cpp index 480373d13271..b36eb48b415e 100644 --- a/libyul/AsmAnalysis.cpp +++ b/libyul/AsmAnalysis.cpp @@ -523,7 +523,7 @@ size_t AsmAnalyzer::operator()(FunctionCall const& _funCall) nativeLocationOf(arg), fmt::format( "Data name \"{}\" cannot be used as an argument of eofcreate/returncontract. " - "An object name is only acceptable.", + "Only an object name is acceptable.", formattedLiteral ) ); diff --git a/test/libyul/yulSyntaxTests/eof/eofcreate_invalid_object_name_data.yul b/test/libyul/yulSyntaxTests/eof/eofcreate_invalid_object_name_data.yul index 1e9fad7d0244..06bb487d62f8 100644 --- a/test/libyul/yulSyntaxTests/eof/eofcreate_invalid_object_name_data.yul +++ b/test/libyul/yulSyntaxTests/eof/eofcreate_invalid_object_name_data.yul @@ -10,4 +10,4 @@ object "a" { // EVMVersion: >=shanghai // bytecodeFormat: >=EOFv1 // ---- -// TypeError 7575: (52-59): Data name "data1" cannot be used as an argument of eofcreate/returncontract. An object name is only acceptable. +// TypeError 7575: (52-59): Data name "data1" cannot be used as an argument of eofcreate/returncontract. Only an object name is acceptable. From d1cbd8dc3f0bd390669a99c8e036b8d6fd215b89 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Mon, 17 Mar 2025 11:02:44 +0100 Subject: [PATCH 0897/1022] interpreter uses yul AST instead of separate block and dialect --- test/libyul/YulInterpreterTest.cpp | 3 +-- test/tools/yulInterpreter/Inspector.cpp | 15 +++++++-------- test/tools/yulInterpreter/Inspector.h | 3 +-- test/tools/yulInterpreter/Interpreter.cpp | 5 ++--- test/tools/yulInterpreter/Interpreter.h | 4 ++-- 5 files changed, 13 insertions(+), 17 deletions(-) diff --git a/test/libyul/YulInterpreterTest.cpp b/test/libyul/YulInterpreterTest.cpp index d97211b9761d..42e0e7c6f543 100644 --- a/test/libyul/YulInterpreterTest.cpp +++ b/test/libyul/YulInterpreterTest.cpp @@ -80,8 +80,7 @@ std::string YulInterpreterTest::interpret(std::shared_ptr const& _ { Interpreter::run( state, - *_object->dialect(), - _object->code()->root(), + *_object->code(), /*disableExternalCalls=*/ !m_simulateExternalCallsToSelf, /*disableMemoryTracing=*/ false ); diff --git a/test/tools/yulInterpreter/Inspector.cpp b/test/tools/yulInterpreter/Inspector.cpp index 7746483a367a..5fec7f1c58d4 100644 --- a/test/tools/yulInterpreter/Inspector.cpp +++ b/test/tools/yulInterpreter/Inspector.cpp @@ -31,9 +31,9 @@ using namespace solidity::yul::test; namespace { -void printVariable(YulString const& _name, u256 const& _value) +void printVariable(std::string_view const _name, u256 const& _value) { - std::cout << "\t" << _name.str() << " = " << _value.str(); + std::cout << "\t" << _name << " = " << _value.str(); if (_value != 0) std::cout << " (" << toCompactHexWithPrefix(_value) << ")"; @@ -46,17 +46,16 @@ void printVariable(YulString const& _name, u256 const& _value) void InspectedInterpreter::run( std::shared_ptr _inspector, InterpreterState& _state, - Dialect const& _dialect, - Block const& _ast, + AST const& _ast, bool _disableExternalCalls, bool _disableMemoryTrace ) { Scope scope; - InspectedInterpreter{_inspector, _state, _dialect, scope, _disableExternalCalls, _disableMemoryTrace}(_ast); + InspectedInterpreter{_inspector, _state, _ast.dialect(), scope, _disableExternalCalls, _disableMemoryTrace}(_ast.root()); } -Inspector::NodeAction Inspector::queryUser(langutil::DebugData const& _data, std::map const& _variables) +Inspector::NodeAction Inspector::queryUser(langutil::DebugData const& _data, std::map const& _variables) { if (m_stepMode == NodeAction::RunNode) { @@ -99,7 +98,7 @@ Inspector::NodeAction Inspector::queryUser(langutil::DebugData const& _data, std else if (input == "variables" || input == "v") { for (auto &&[yulStr, val]: _variables) - printVariable(yulStr, val); + printVariable(yulStr.str(), val); std::cout << std::endl; } else if ( @@ -120,7 +119,7 @@ Inspector::NodeAction Inspector::queryUser(langutil::DebugData const& _data, std for (auto &&[yulStr, val]: _variables) if (yulStr.str() == varname) { - printVariable(yulStr, val); + printVariable(varname, val); found = true; break; } diff --git a/test/tools/yulInterpreter/Inspector.h b/test/tools/yulInterpreter/Inspector.h index 903ebc1142ea..3ea669b438a9 100644 --- a/test/tools/yulInterpreter/Inspector.h +++ b/test/tools/yulInterpreter/Inspector.h @@ -103,8 +103,7 @@ class InspectedInterpreter: public Interpreter static void run( std::shared_ptr _inspector, InterpreterState& _state, - Dialect const& _dialect, - Block const& _ast, + AST const& _ast, bool _disableExternalCalls, bool _disableMemoryTracing ); diff --git a/test/tools/yulInterpreter/Interpreter.cpp b/test/tools/yulInterpreter/Interpreter.cpp index 2709d1b468aa..05db9f581fa5 100644 --- a/test/tools/yulInterpreter/Interpreter.cpp +++ b/test/tools/yulInterpreter/Interpreter.cpp @@ -109,14 +109,13 @@ void InterpreterState::dumpTraceAndState(std::ostream& _out, bool _disableMemory void Interpreter::run( InterpreterState& _state, - Dialect const& _dialect, - Block const& _ast, + AST const& _ast, bool _disableExternalCalls, bool _disableMemoryTrace ) { Scope scope; - Interpreter{_state, _dialect, scope, _disableExternalCalls, _disableMemoryTrace}(_ast); + Interpreter{_state, _ast.dialect(), scope, _disableExternalCalls, _disableMemoryTrace}(_ast.root()); } void Interpreter::operator()(ExpressionStatement const& _expressionStatement) diff --git a/test/tools/yulInterpreter/Interpreter.h b/test/tools/yulInterpreter/Interpreter.h index 427a30d9ea08..3dd6a4238d97 100644 --- a/test/tools/yulInterpreter/Interpreter.h +++ b/test/tools/yulInterpreter/Interpreter.h @@ -22,6 +22,7 @@ #pragma once #include +#include #include #include @@ -162,8 +163,7 @@ class Interpreter: public ASTWalker /// activated e.g., Redundant store eliminator, Equal store eliminator. static void run( InterpreterState& _state, - Dialect const& _dialect, - Block const& _ast, + AST const& _ast, bool _disableExternalCalls, bool _disableMemoryTracing ); From 8859625fdeb9a19f538d596d380e0fae28ea108e Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Mon, 17 Mar 2025 11:02:55 +0100 Subject: [PATCH 0898/1022] yulrun on AST --- test/tools/yulrun.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/test/tools/yulrun.cpp b/test/tools/yulrun.cpp index 36d48858620b..a5fa05d934ce 100644 --- a/test/tools/yulrun.cpp +++ b/test/tools/yulrun.cpp @@ -63,6 +63,9 @@ std::pair, std::shared_ptr> parse(st solidity::frontend::OptimiserSettings::none(), DebugInfoSelection::Default() ); + auto const* evmDialect = dynamic_cast(&stack.dialect()); + // TODO: Add EOF support + solUnimplementedAssert(evmDialect && !evmDialect->eofVersion(), "No EOF support for yulrun yet."); if (stack.parseAndAnalyze("--INPUT--", _source)) { yulAssert(!Error::hasErrorsWarningsOrInfos(stack.errors()), "Parsed successfully but had errors."); @@ -87,13 +90,10 @@ void interpret(std::string const& _source, bool _inspect, bool _disableExternalC state.maxTraceSize = 10000; try { - Dialect const& dialect(EVMDialect::strictAssemblyForEVMObjects(langutil::EVMVersion{}, std::nullopt)); - if (_inspect) - InspectedInterpreter::run(std::make_shared(_source, state), state, dialect, ast->root(), _disableExternalCalls, /*disableMemoryTracing=*/false); - + InspectedInterpreter::run(std::make_shared(_source, state), state, *ast, _disableExternalCalls, /*disableMemoryTracing=*/false); else - Interpreter::run(state, dialect, ast->root(), _disableExternalCalls, /*disableMemoryTracing=*/false); + Interpreter::run(state, *ast, _disableExternalCalls, /*disableMemoryTracing=*/false); } catch (InterpreterTerminatedGeneric const&) { From dafe00677e1ccf04fb4853d74885cfe7288b25e7 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Mon, 17 Mar 2025 10:56:53 +0100 Subject: [PATCH 0899/1022] ossfuzz uses yul AST instead of separate block and dialect --- test/tools/ossfuzz/strictasm_diff_ossfuzz.cpp | 6 ++---- test/tools/ossfuzz/yulFuzzerCommon.cpp | 5 ++--- test/tools/ossfuzz/yulFuzzerCommon.h | 3 +-- test/tools/ossfuzz/yulProto_diff_ossfuzz.cpp | 6 ++---- 4 files changed, 7 insertions(+), 13 deletions(-) diff --git a/test/tools/ossfuzz/strictasm_diff_ossfuzz.cpp b/test/tools/ossfuzz/strictasm_diff_ossfuzz.cpp index a4515b30957a..9abf269c869a 100644 --- a/test/tools/ossfuzz/strictasm_diff_ossfuzz.cpp +++ b/test/tools/ossfuzz/strictasm_diff_ossfuzz.cpp @@ -90,8 +90,7 @@ extern "C" int LLVMFuzzerTestOneInput(uint8_t const* _data, size_t _size) // TODO: Add EOF support yulFuzzerUtil::TerminationReason termReason = yulFuzzerUtil::interpret( os1, - stack.parserResult()->code()->root(), - EVMDialect::strictAssemblyForEVMObjects(langutil::EVMVersion(), std::nullopt), + *stack.parserResult()->code(), /*disableMemoryTracing=*/true ); if (yulFuzzerUtil::resourceLimitsExceeded(termReason)) @@ -100,8 +99,7 @@ extern "C" int LLVMFuzzerTestOneInput(uint8_t const* _data, size_t _size) stack.optimize(); termReason = yulFuzzerUtil::interpret( os2, - stack.parserResult()->code()->root(), - EVMDialect::strictAssemblyForEVMObjects(langutil::EVMVersion(), std::nullopt), + *stack.parserResult()->code(), /*disableMemoryTracing=*/true ); diff --git a/test/tools/ossfuzz/yulFuzzerCommon.cpp b/test/tools/ossfuzz/yulFuzzerCommon.cpp index b95df8f2138c..c34f4351c5d4 100644 --- a/test/tools/ossfuzz/yulFuzzerCommon.cpp +++ b/test/tools/ossfuzz/yulFuzzerCommon.cpp @@ -23,8 +23,7 @@ using namespace solidity::yul::test::yul_fuzzer; yulFuzzerUtil::TerminationReason yulFuzzerUtil::interpret( std::ostream& _os, - yul::Block const& _astRoot, - Dialect const& _dialect, + AST const& _ast, bool _disableMemoryTracing, bool _outputStorageOnly, size_t _maxSteps, @@ -52,7 +51,7 @@ yulFuzzerUtil::TerminationReason yulFuzzerUtil::interpret( TerminationReason reason = TerminationReason::None; try { - Interpreter::run(state, _dialect, _astRoot, true, _disableMemoryTracing); + Interpreter::run(state, _ast, true, _disableMemoryTracing); } catch (StepLimitReached const&) { diff --git a/test/tools/ossfuzz/yulFuzzerCommon.h b/test/tools/ossfuzz/yulFuzzerCommon.h index afcb0f2d3c9e..dcfd0f833775 100644 --- a/test/tools/ossfuzz/yulFuzzerCommon.h +++ b/test/tools/ossfuzz/yulFuzzerCommon.h @@ -40,8 +40,7 @@ struct yulFuzzerUtil /// eliminator. static TerminationReason interpret( std::ostream& _os, - yul::Block const& _astRoot, - Dialect const& _dialect, + AST const& _ast, bool _disableMemoryTracing = false, bool _outputStorageOnly = false, size_t _maxSteps = maxSteps, diff --git a/test/tools/ossfuzz/yulProto_diff_ossfuzz.cpp b/test/tools/ossfuzz/yulProto_diff_ossfuzz.cpp index d15043972693..4edfbf7ba4ee 100644 --- a/test/tools/ossfuzz/yulProto_diff_ossfuzz.cpp +++ b/test/tools/ossfuzz/yulProto_diff_ossfuzz.cpp @@ -90,8 +90,7 @@ DEFINE_PROTO_FUZZER(Program const& _input) // TODO: Add EOF support yulFuzzerUtil::TerminationReason termReason = yulFuzzerUtil::interpret( os1, - stack.parserResult()->code()->root(), - EVMDialect::strictAssemblyForEVMObjects(version, std::nullopt), + *stack.parserResult()->code(), /*disableMemoryTracing=*/true ); @@ -106,8 +105,7 @@ DEFINE_PROTO_FUZZER(Program const& _input) // TODO: Add EOF support termReason = yulFuzzerUtil::interpret( os2, - *astRoot, - EVMDialect::strictAssemblyForEVMObjects(version, std::nullopt), + *optimizerTest.optimizedObject()->code(), true ); if (yulFuzzerUtil::resourceLimitsExceeded(termReason)) From 77878e5d4a56ea175d131a2338052ab4ac1e9ceb Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Fri, 14 Mar 2025 13:14:01 +0100 Subject: [PATCH 0900/1022] add repeats to external.sh --- test/benchmarks/external.sh | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/test/benchmarks/external.sh b/test/benchmarks/external.sh index b003f0ba18d2..7ad3279ae360 100755 --- a/test/benchmarks/external.sh +++ b/test/benchmarks/external.sh @@ -42,9 +42,10 @@ source "${repo_root}/scripts/common.sh" # shellcheck source=scripts/common_cmdline.sh source "${repo_root}/scripts/common_cmdline.sh" -(( $# <= 1 )) || fail "Too many arguments. Usage: external.sh []" +(( $# <= 2 )) || fail "Too many arguments. Usage: external.sh [] []" solc="${1:-${SOLIDITY_BUILD_DIR}/solc/solc}" +num_repeats="${2:-1}" command_available "$solc" --version command_available "$(type -P time)" --version @@ -65,10 +66,10 @@ function benchmark_project { > /dev/null \ 2> "../stderr-${project}-${pipeline}.log" || true - printf '| %-21s | %8s | %6d s | %9d MiB | %9d |\n' \ + printf '| %-21s | %8s | %6.2f s | %9d MiB | %9d |\n' \ "$project" \ "$pipeline" \ - "$(jq '(.user + .sys) | round' "$time_file")" \ + "$(jq '(.user + .sys) * 100 | round / 100' "$time_file")" \ "$(jq '.mem / 1024 | round' "$time_file")" \ "$(jq '.exit' "$time_file")" cd .. @@ -96,8 +97,12 @@ echo "| File | Pipeline | Time | Memory (peak) | Exit code echo "|-----------------------|----------|---------:|--------------:|----------:|" for project in "${benchmarks[@]}"; do - benchmark_project legacy "$project" - benchmark_project ir "$project" + for ((i=0; i Date: Tue, 25 Mar 2025 20:58:29 +0200 Subject: [PATCH 0901/1022] fix: Remove unnecessary Expression temporary in CHCSmtLib2Interface fix: Remove unnecessary Expression temporary in CHCSmtLib2Interface Update CHCSmtLib2Interface.cpp Update CHCSmtLib2Interface.cpp add repeats to external.sh --- libsmtutil/CHCSmtLib2Interface.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/libsmtutil/CHCSmtLib2Interface.cpp b/libsmtutil/CHCSmtLib2Interface.cpp index 6b0534296f29..04cbad1ad489 100644 --- a/libsmtutil/CHCSmtLib2Interface.cpp +++ b/libsmtutil/CHCSmtLib2Interface.cpp @@ -465,9 +465,7 @@ std::optional CHCSmtLib2Interface::invariantsFromSolverResp smtSolverInteractionRequire(isAtom(nameSortPair[0]), "Invalid format of CHC model"); SortPointer varSort = scopedParser.toSort(nameSortPair[1]); scopedParser.addVariableDeclaration(asAtom(nameSortPair[0]), varSort); - // FIXME: Why Expression here? - Expression arg = scopedParser.toSMTUtilExpression(nameSortPair[0]); - predicateArgs.push_back(arg); + predicateArgs.push_back(scopedParser.toSMTUtilExpression(nameSortPair[0])); } auto parsedInterpretation = scopedParser.toSMTUtilExpression(interpretation); @@ -479,6 +477,7 @@ std::optional CHCSmtLib2Interface::invariantsFromSolverResp }); Expression predicate(asAtom(args[1]), predicateArgs, SortProvider::boolSort); + // FIXME: Why do we need to represent the predicate as Expression? definitions.push_back(predicate == parsedInterpretation); } return Expression::mkAnd(std::move(definitions)); From a4489211c9a872e81235d35433cdffe318755c77 Mon Sep 17 00:00:00 2001 From: Martin Blicha Date: Fri, 28 Mar 2025 09:30:49 +0100 Subject: [PATCH 0902/1022] SMTChecker: Move helper function towards its only usage We don't need a separate file for a single, relatively small, helper function. --- libsolidity/CMakeLists.txt | 2 - libsolidity/formal/CHC.cpp | 54 +++++++++++++++++++- libsolidity/formal/Invariants.cpp | 85 ------------------------------- libsolidity/formal/Invariants.h | 37 -------------- 4 files changed, 53 insertions(+), 125 deletions(-) delete mode 100644 libsolidity/formal/Invariants.cpp delete mode 100644 libsolidity/formal/Invariants.h diff --git a/libsolidity/CMakeLists.txt b/libsolidity/CMakeLists.txt index 5925a50ac480..f0289acac3a8 100644 --- a/libsolidity/CMakeLists.txt +++ b/libsolidity/CMakeLists.txt @@ -117,8 +117,6 @@ set(sources formal/EncodingContext.h formal/ExpressionFormatter.cpp formal/ExpressionFormatter.h - formal/Invariants.cpp - formal/Invariants.h formal/ModelChecker.cpp formal/ModelChecker.h formal/ModelCheckerSettings.cpp diff --git a/libsolidity/formal/CHC.cpp b/libsolidity/formal/CHC.cpp index bab340051f82..67878084f61b 100644 --- a/libsolidity/formal/CHC.cpp +++ b/libsolidity/formal/CHC.cpp @@ -19,8 +19,8 @@ #include #include +#include #include -#include #include #include #include @@ -2134,6 +2134,58 @@ void CHC::checkVerificationTargets() m_safeTargets[m_verificationTargets.at(id).errorNode].insert(m_verificationTargets.at(id)); } +namespace +{ +std::map> collectInvariants( + smtutil::Expression const& _proof, + std::set const& _predicates, + ModelCheckerInvariants const& _invariantsSetting +) +{ + std::set targets; + if (_invariantsSetting.has(InvariantType::Contract)) + targets.insert("interface_"); + if (_invariantsSetting.has(InvariantType::Reentrancy)) + targets.insert("nondet_interface_"); + + std::map> equalities; + // Collect equalities where one of the sides is a predicate we're interested in. + util::BreadthFirstSearch{{&_proof}}.run([&](auto&& _expr, auto&& _addChild) { + if (_expr->name == "=") + for (auto const& t: targets) + { + auto arg0 = _expr->arguments.at(0); + auto arg1 = _expr->arguments.at(1); + if (boost::algorithm::starts_with(arg0.name, t)) + equalities.insert({arg0.name, {arg0, std::move(arg1)}}); + else if (boost::algorithm::starts_with(arg1.name, t)) + equalities.insert({arg1.name, {arg1, std::move(arg0)}}); + } + for (auto const& arg: _expr->arguments) + _addChild(&arg); + }); + + std::map> invariants; + for (auto pred: _predicates) + { + auto predName = pred->functor().name; + if (!equalities.count(predName)) + continue; + + solAssert(pred->contextContract(), ""); + + auto const& [predExpr, invExpr] = equalities.at(predName); + + static std::set const ignore{"true", "false"}; + auto r = substitute(invExpr, pred->expressionSubstitution(predExpr)); + // No point in reporting true/false as invariants. + if (!ignore.count(r.name)) + invariants[pred].insert(toSolidityStr(r)); + } + return invariants; +} +} // namespace + void CHC::checkAndReportTarget( CHCVerificationTarget const& _target, std::vector const& _placeholders, diff --git a/libsolidity/formal/Invariants.cpp b/libsolidity/formal/Invariants.cpp deleted file mode 100644 index 017ab1e3aedb..000000000000 --- a/libsolidity/formal/Invariants.cpp +++ /dev/null @@ -1,85 +0,0 @@ -/* - This file is part of solidity. - - solidity is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - solidity is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with solidity. If not, see . -*/ -// SPDX-License-Identifier: GPL-3.0 - -#include - -#include -#include - -#include - -#include - -using boost::algorithm::starts_with; -using namespace solidity; -using namespace solidity::smtutil; -using namespace solidity::frontend::smt; - -namespace solidity::frontend::smt -{ - -std::map> collectInvariants( - smtutil::Expression const& _proof, - std::set const& _predicates, - ModelCheckerInvariants const& _invariantsSetting -) -{ - std::set targets; - if (_invariantsSetting.has(InvariantType::Contract)) - targets.insert("interface_"); - if (_invariantsSetting.has(InvariantType::Reentrancy)) - targets.insert("nondet_interface_"); - - std::map> equalities; - // Collect equalities where one of the sides is a predicate we're interested in. - util::BreadthFirstSearch{{&_proof}}.run([&](auto&& _expr, auto&& _addChild) { - if (_expr->name == "=") - for (auto const& t: targets) - { - auto arg0 = _expr->arguments.at(0); - auto arg1 = _expr->arguments.at(1); - if (starts_with(arg0.name, t)) - equalities.insert({arg0.name, {arg0, std::move(arg1)}}); - else if (starts_with(arg1.name, t)) - equalities.insert({arg1.name, {arg1, std::move(arg0)}}); - } - for (auto const& arg: _expr->arguments) - _addChild(&arg); - }); - - std::map> invariants; - for (auto pred: _predicates) - { - auto predName = pred->functor().name; - if (!equalities.count(predName)) - continue; - - solAssert(pred->contextContract(), ""); - - auto const& [predExpr, invExpr] = equalities.at(predName); - - static std::set const ignore{"true", "false"}; - auto r = substitute(invExpr, pred->expressionSubstitution(predExpr)); - // No point in reporting true/false as invariants. - if (!ignore.count(r.name)) - invariants[pred].insert(toSolidityStr(r)); - } - return invariants; -} - -} diff --git a/libsolidity/formal/Invariants.h b/libsolidity/formal/Invariants.h deleted file mode 100644 index b6459fccd415..000000000000 --- a/libsolidity/formal/Invariants.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - This file is part of solidity. - - solidity is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - solidity is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with solidity. If not, see . -*/ -// SPDX-License-Identifier: GPL-3.0 - -#pragma once - -#include -#include - -#include -#include -#include - -namespace solidity::frontend::smt -{ - -std::map> collectInvariants( - smtutil::Expression const& _proof, - std::set const& _predicates, - ModelCheckerInvariants const& _invariantsSettings -); - -} From 5ea8f2587447a09daa4089322dc06d1f323a16e7 Mon Sep 17 00:00:00 2001 From: Nikola Matic Date: Wed, 19 Mar 2025 13:40:09 +0100 Subject: [PATCH 0903/1022] Add support for enum values in NatSpec --- Changelog.md | 1 + libsolidity/ast/AST.h | 14 ++++- libsolidity/ast/ASTJsonExporter.cpp | 1 + libsolidity/ast/ASTJsonImporter.cpp | 3 +- libsolidity/parsing/Parser.cpp | 3 +- .../ASTJSON/enum_value_natspec.json | 56 +++++++++++++++++++ .../ASTJSON/enum_value_natspec.sol | 11 ++++ .../ASTJSON/enum_value_natspec_parseOnly.json | 50 +++++++++++++++++ .../{enum_no_docs.sol => enum.sol} | 0 .../{docstring_enum.sol => enum_value.sol} | 10 ++-- 10 files changed, 140 insertions(+), 9 deletions(-) create mode 100644 test/libsolidity/ASTJSON/enum_value_natspec.json create mode 100644 test/libsolidity/ASTJSON/enum_value_natspec.sol create mode 100644 test/libsolidity/ASTJSON/enum_value_natspec_parseOnly.json rename test/libsolidity/natspecJSON/{enum_no_docs.sol => enum.sol} (100%) rename test/libsolidity/natspecJSON/{docstring_enum.sol => enum_value.sol} (55%) diff --git a/Changelog.md b/Changelog.md index 7efefca02d6a..525ed2d9e58b 100644 --- a/Changelog.md +++ b/Changelog.md @@ -4,6 +4,7 @@ Language Features: Compiler Features: +* NatSpec: Capture Natspec documentation of `enum` values in the AST. Bugfixes: diff --git a/libsolidity/ast/AST.h b/libsolidity/ast/AST.h index 0121bef332df..9c7cbbded2cc 100644 --- a/libsolidity/ast/AST.h +++ b/libsolidity/ast/AST.h @@ -823,11 +823,19 @@ class EnumDefinition: public Declaration, public StructurallyDocumented, public /** * Declaration of an Enum Value */ -class EnumValue: public Declaration +class EnumValue: public Declaration, public StructurallyDocumented { public: - EnumValue(int64_t _id, SourceLocation const& _location, ASTPointer const& _name): - Declaration(_id, _location, _name, _location) {} + EnumValue( + int64_t _id, + SourceLocation const& _location, + ASTPointer const& _name, + ASTPointer _documentation + ): + Declaration(_id, _location, _name, _location), + StructurallyDocumented(std::move(_documentation)) + { + } void accept(ASTVisitor& _visitor) override; void accept(ASTConstVisitor& _visitor) const override; diff --git a/libsolidity/ast/ASTJsonExporter.cpp b/libsolidity/ast/ASTJsonExporter.cpp index 42627b5f7f7c..4eaa558713a7 100644 --- a/libsolidity/ast/ASTJsonExporter.cpp +++ b/libsolidity/ast/ASTJsonExporter.cpp @@ -430,6 +430,7 @@ bool ASTJsonExporter::visit(EnumValue const& _node) setJsonNode(_node, "EnumValue", { std::make_pair("name", _node.name()), std::make_pair("nameLocation", sourceLocationToString(_node.nameLocation())), + std::make_pair("documentation", toJson(_node.documentation().get())), }); return false; } diff --git a/libsolidity/ast/ASTJsonImporter.cpp b/libsolidity/ast/ASTJsonImporter.cpp index d6cd7f43896a..2d2b66fd8d08 100644 --- a/libsolidity/ast/ASTJsonImporter.cpp +++ b/libsolidity/ast/ASTJsonImporter.cpp @@ -489,7 +489,8 @@ ASTPointer ASTJsonImporter::createEnumValue(Json const& _node) { return createASTNode( _node, - memberAsASTString(_node, "name") + memberAsASTString(_node, "name"), + _node.contains("documentation") && !_node["documentation"].is_null() ? createDocumentation(member(_node, "documentation")) : nullptr ); } diff --git a/libsolidity/parsing/Parser.cpp b/libsolidity/parsing/Parser.cpp index 08a319b5b597..8889e65087fa 100644 --- a/libsolidity/parsing/Parser.cpp +++ b/libsolidity/parsing/Parser.cpp @@ -824,8 +824,9 @@ ASTPointer Parser::parseEnumValue() { RecursionGuard recursionGuard(*this); ASTNodeFactory nodeFactory(*this); + ASTPointer documentation = parseStructuredDocumentation(); nodeFactory.markEndPosition(); - return nodeFactory.createNode(expectIdentifierToken()); + return nodeFactory.createNode(expectIdentifierToken(), documentation); } ASTPointer Parser::parseEnumDefinition() diff --git a/test/libsolidity/ASTJSON/enum_value_natspec.json b/test/libsolidity/ASTJSON/enum_value_natspec.json new file mode 100644 index 000000000000..e468bb987064 --- /dev/null +++ b/test/libsolidity/ASTJSON/enum_value_natspec.json @@ -0,0 +1,56 @@ +{ + "absolutePath": "a", + "exportedSymbols": { + "Color": [ + 6 + ] + }, + "id": 7, + "nodeType": "SourceUnit", + "nodes": [ + { + "canonicalName": "Color", + "id": 6, + "members": [ + { + "id": 1, + "name": "Red", + "nameLocation": "17:3:1", + "nodeType": "EnumValue", + "src": "17:3:1" + }, + { + "documentation": { + "id": 2, + "nodeType": "StructuredDocumentation", + "src": "26:57:1", + "text": "@notice example of notice\n @dev example of dev" + }, + "id": 3, + "name": "Green", + "nameLocation": "88:5:1", + "nodeType": "EnumValue", + "src": "88:5:1" + }, + { + "documentation": { + "id": 4, + "nodeType": "StructuredDocumentation", + "src": "99:23:1", + "text": "@dev example of dev" + }, + "id": 5, + "name": "Blue", + "nameLocation": "127:4:1", + "nodeType": "EnumValue", + "src": "127:4:1" + } + ], + "name": "Color", + "nameLocation": "5:5:1", + "nodeType": "EnumDefinition", + "src": "0:164:1" + } + ], + "src": "0:165:1" +} diff --git a/test/libsolidity/ASTJSON/enum_value_natspec.sol b/test/libsolidity/ASTJSON/enum_value_natspec.sol new file mode 100644 index 000000000000..e5209d644831 --- /dev/null +++ b/test/libsolidity/ASTJSON/enum_value_natspec.sol @@ -0,0 +1,11 @@ +enum Color { + Red, + /// @notice example of notice + /// @dev example of dev + Green, + /// @dev example of dev + Blue + /// @dev beyond last value +} + +// ---- diff --git a/test/libsolidity/ASTJSON/enum_value_natspec_parseOnly.json b/test/libsolidity/ASTJSON/enum_value_natspec_parseOnly.json new file mode 100644 index 000000000000..ff3d7c756ed1 --- /dev/null +++ b/test/libsolidity/ASTJSON/enum_value_natspec_parseOnly.json @@ -0,0 +1,50 @@ +{ + "absolutePath": "a", + "id": 7, + "nodeType": "SourceUnit", + "nodes": [ + { + "id": 6, + "members": [ + { + "id": 1, + "name": "Red", + "nameLocation": "17:3:1", + "nodeType": "EnumValue", + "src": "17:3:1" + }, + { + "documentation": { + "id": 2, + "nodeType": "StructuredDocumentation", + "src": "26:57:1", + "text": "@notice example of notice\n @dev example of dev" + }, + "id": 3, + "name": "Green", + "nameLocation": "88:5:1", + "nodeType": "EnumValue", + "src": "88:5:1" + }, + { + "documentation": { + "id": 4, + "nodeType": "StructuredDocumentation", + "src": "99:23:1", + "text": "@dev example of dev" + }, + "id": 5, + "name": "Blue", + "nameLocation": "127:4:1", + "nodeType": "EnumValue", + "src": "127:4:1" + } + ], + "name": "Color", + "nameLocation": "5:5:1", + "nodeType": "EnumDefinition", + "src": "0:164:1" + } + ], + "src": "0:165:1" +} diff --git a/test/libsolidity/natspecJSON/enum_no_docs.sol b/test/libsolidity/natspecJSON/enum.sol similarity index 100% rename from test/libsolidity/natspecJSON/enum_no_docs.sol rename to test/libsolidity/natspecJSON/enum.sol diff --git a/test/libsolidity/natspecJSON/docstring_enum.sol b/test/libsolidity/natspecJSON/enum_value.sol similarity index 55% rename from test/libsolidity/natspecJSON/docstring_enum.sol rename to test/libsolidity/natspecJSON/enum_value.sol index d5ace6b14192..ccb3233a51b4 100644 --- a/test/libsolidity/natspecJSON/docstring_enum.sol +++ b/test/libsolidity/natspecJSON/enum_value.sol @@ -1,11 +1,13 @@ contract C { - /// @title example of title - /// @author example of author - /// @notice example of notice - /// @dev example of dev enum Color { + /// @custom red color Red, + /// @title example of title + /// @author example of author + /// @notice example of notice + /// @dev example of dev Green + /// @notice beyond last value } } // ---- From c4b454ac53ad6409cee612ddaf38d467b50a6299 Mon Sep 17 00:00:00 2001 From: Nikola Matic Date: Wed, 2 Apr 2025 13:16:18 +0200 Subject: [PATCH 0904/1022] Docs --- docs/natspec-format.rst | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/natspec-format.rst b/docs/natspec-format.rst index 2f0d1d6b40d9..40da3e5e3529 100644 --- a/docs/natspec-format.rst +++ b/docs/natspec-format.rst @@ -37,7 +37,7 @@ Documentation Example ===================== Documentation is inserted above each ``contract``, ``interface``, ``library``, -``function``, and ``event`` using the Doxygen notation format. +``function``, ``enum``, ``enum`` value and ``event`` using the Doxygen notation format. A ``public`` state variable is equivalent to a ``function`` for the purposes of NatSpec. @@ -116,13 +116,13 @@ in the same way as if it were tagged with ``@notice``. =============== ====================================================================================== ============================= Tag Context =============== ====================================================================================== ============================= -``@title`` A title that should describe the contract/interface contract, library, interface, struct, enum -``@author`` The name of the author contract, library, interface, struct, enum -``@notice`` Explain to an end user what this does contract, library, interface, function, public state variable, event, struct, enum, error -``@dev`` Explain to a developer any extra details contract, library, interface, function, state variable, event, struct, enum, error -``@param`` Documents a parameter just like in Doxygen (must be followed by parameter name) function, event, error -``@return`` Documents the return variables of a contract's function function, public state variable -``@inheritdoc`` Copies all missing tags from the base function (must be followed by the contract name) function, public state variable +``@title`` A title that should describe the contract/interface contract, library, interface, struct, enum, enum values +``@author`` The name of the author contract, library, interface, struct, enum, enum values +``@notice`` Explain to an end user what this does contract, library, interface, function, public state variable, event, struct, enum, enum values error +``@dev`` Explain to a developer any extra details contract, library, interface, function, state variable, event, struct, enum, enum values, error +``@param`` Documents a parameter just like in Doxygen (must be followed by parameter name) function, event, enum values, error +``@return`` Documents the return variables of a contract's function function, enum, enum values, public state variable +``@inheritdoc`` Copies all missing tags from the base function (must be followed by the contract name) function, enum, enum values, public state variable ``@custom:...`` Custom tag, semantics is application-defined everywhere =============== ====================================================================================== ============================= From c6084281e3e7ff0b969235acab44eb409f93f273 Mon Sep 17 00:00:00 2001 From: Martin Blicha Date: Fri, 28 Mar 2025 09:49:35 +0100 Subject: [PATCH 0905/1022] SMTChecker: Refactor processing invariants from the solver Instead of extracting invariants as a single expression containing all predicates and their definitions, we represent invariants as a map from predicate names to the corresponding definitions. Additionally, we need to remember formal arguments of the predicate so we can apply substitutions to the definitions properly. I believe the previous representation was an artifact of how Z3 returns CHC model through its API. The new representation is more fitting for models extracted from SMT-LIB. --- libsmtutil/CHCSmtLib2Interface.cpp | 27 +++++------ libsmtutil/CHCSmtLib2Interface.h | 4 +- libsmtutil/CHCSolverInterface.h | 12 ++++- libsolidity/formal/CHC.cpp | 50 +++++++------------- libsolidity/formal/Predicate.cpp | 30 ++++++------ libsolidity/formal/Predicate.h | 4 +- libsolidity/formal/Z3CHCSmtLib2Interface.cpp | 15 +++--- 7 files changed, 65 insertions(+), 77 deletions(-) diff --git a/libsmtutil/CHCSmtLib2Interface.cpp b/libsmtutil/CHCSmtLib2Interface.cpp index 04cbad1ad489..b81eeb4fe06b 100644 --- a/libsmtutil/CHCSmtLib2Interface.cpp +++ b/libsmtutil/CHCSmtLib2Interface.cpp @@ -102,21 +102,18 @@ CHCSolverInterface::QueryResult CHCSmtLib2Interface::query(Expression const& _bl // However, with CHC solvers, the meaning is flipped, UNSAT -> UNSAFE and SAT -> SAFE. // So we have to flip the answer. if (boost::starts_with(response, "sat")) - { - auto maybeInvariants = invariantsFromSolverResponse(response); - return {CheckResult::UNSATISFIABLE, maybeInvariants.value_or(Expression(true)), {}}; - } - else if (boost::starts_with(response, "unsat")) + return {CheckResult::UNSATISFIABLE, invariantsFromSolverResponse(response), {}}; + if (boost::starts_with(response, "unsat")) result = CheckResult::SATISFIABLE; else if (boost::starts_with(response, "unknown")) result = CheckResult::UNKNOWN; else result = CheckResult::ERROR; - return {result, Expression(true), {}}; + return {result, {}, {}}; } catch(smtutil::SMTSolverInteractionError const&) { - return {CheckResult::ERROR, Expression(true), {}}; + return {CheckResult::ERROR, {}, {}}; } } @@ -416,7 +413,7 @@ smtutil::Expression CHCSmtLib2Interface::ScopedParser::toSMTUtilExpression(SMTLi } -std::optional CHCSmtLib2Interface::invariantsFromSolverResponse(std::string const& _response) const +CHCSmtLib2Interface::Invariants CHCSmtLib2Interface::invariantsFromSolverResponse(std::string const& _response) const { std::stringstream ss(_response); std::string answer; @@ -438,7 +435,7 @@ std::optional CHCSmtLib2Interface::invariantsFromSolverResp smtSolverInteractionRequire(parser.isEOF(), "Error during parsing CHC model"); smtSolverInteractionRequire(!parsedOutput.empty(), "Error during parsing CHC model"); auto& commands = parsedOutput.size() == 1 ? asSubExpressions(parsedOutput[0]) : parsedOutput; - std::vector definitions; + Invariants definitions; for (auto& command: commands) { auto& args = asSubExpressions(command); @@ -456,7 +453,7 @@ std::optional CHCSmtLib2Interface::invariantsFromSolverResp inlineLetExpressions(interpretation); ScopedParser scopedParser(m_context); auto const& formalArguments = asSubExpressions(args[2]); - std::vector predicateArgs; + std::vector predicateArguments; for (auto const& formalArgument: formalArguments) { smtSolverInteractionRequire(!isAtom(formalArgument), "Invalid format of CHC model"); @@ -465,7 +462,7 @@ std::optional CHCSmtLib2Interface::invariantsFromSolverResp smtSolverInteractionRequire(isAtom(nameSortPair[0]), "Invalid format of CHC model"); SortPointer varSort = scopedParser.toSort(nameSortPair[1]); scopedParser.addVariableDeclaration(asAtom(nameSortPair[0]), varSort); - predicateArgs.push_back(scopedParser.toSMTUtilExpression(nameSortPair[0])); + predicateArguments.push_back(asAtom(nameSortPair[0])); } auto parsedInterpretation = scopedParser.toSMTUtilExpression(interpretation); @@ -476,11 +473,11 @@ std::optional CHCSmtLib2Interface::invariantsFromSolverResp return first.name < second.name; }); - Expression predicate(asAtom(args[1]), predicateArgs, SortProvider::boolSort); - // FIXME: Why do we need to represent the predicate as Expression? - definitions.push_back(predicate == parsedInterpretation); + std::string const& predicateName = asAtom(args[1]); + smtSolverInteractionRequire(!definitions.contains(predicateName), "Predicates must be unique"); + definitions.emplace(predicateName, InvariantInfo{parsedInterpretation, predicateArguments}); } - return Expression::mkAnd(std::move(definitions)); + return definitions; } namespace diff --git a/libsmtutil/CHCSmtLib2Interface.h b/libsmtutil/CHCSmtLib2Interface.h index 0f8fc061d3df..5b45f1638012 100644 --- a/libsmtutil/CHCSmtLib2Interface.h +++ b/libsmtutil/CHCSmtLib2Interface.h @@ -94,8 +94,8 @@ class CHCSmtLib2Interface: public CHCSolverInterface /// Communicates with the solver via the callback. Throws SMTSolverError on error. virtual std::string querySolver(std::string const& _input); - /// Translates CHC solver response with a model to our representation of invariants. Returns None on error. - std::optional invariantsFromSolverResponse(std::string const& _response) const; + /// Translates CHC solver response with a model to our representation of invariants. + Invariants invariantsFromSolverResponse(std::string const& _response) const; std::set collectVariableNames(Expression const& _expr) const; diff --git a/libsmtutil/CHCSolverInterface.h b/libsmtutil/CHCSolverInterface.h index 8feb18aa8245..641d54cfb440 100644 --- a/libsmtutil/CHCSolverInterface.h +++ b/libsmtutil/CHCSolverInterface.h @@ -25,6 +25,7 @@ #include #include +#include #include namespace solidity::smtutil @@ -49,10 +50,19 @@ class CHCSolverInterface : public SolverInterface std::map> edges; }; + struct InvariantInfo + { + /// Predicate definition as SMT expression + Expression expression; + /// Names of the formal arguments of the predicate definition + std::vector variableNames; + }; + /// Maps predicate to its definition as given by the solver and the formal arguments of the predicate + using Invariants = std::unordered_map; struct QueryResult { CheckResult answer; - Expression invariant; + Invariants invariants; CexGraph cex; }; /// Takes a function application _expr and checks for reachability. diff --git a/libsolidity/formal/CHC.cpp b/libsolidity/formal/CHC.cpp index 67878084f61b..fea13fde2360 100644 --- a/libsolidity/formal/CHC.cpp +++ b/libsolidity/formal/CHC.cpp @@ -34,9 +34,8 @@ #include #include -#include - #include +#include #include #include #include @@ -1895,7 +1894,7 @@ CHCSolverInterface::QueryResult CHC::query(smtutil::Expression const& _query, la 2339_error, "CHC: Requested query:\n" + smtLibCode ); - return {.answer = CheckResult::UNKNOWN, .invariant = smtutil::Expression(true), .cex = {}}; + return {.answer = CheckResult::UNKNOWN, .invariants = {}, .cex = {}}; } auto result = m_interface->query(_query); switch (result.answer) @@ -2137,7 +2136,7 @@ void CHC::checkVerificationTargets() namespace { std::map> collectInvariants( - smtutil::Expression const& _proof, + CHCSmtLib2Interface::Invariants const& _invariants, std::set const& _predicates, ModelCheckerInvariants const& _invariantsSetting ) @@ -2148,38 +2147,23 @@ std::map> collectInvariants( if (_invariantsSetting.has(InvariantType::Reentrancy)) targets.insert("nondet_interface_"); - std::map> equalities; - // Collect equalities where one of the sides is a predicate we're interested in. - util::BreadthFirstSearch{{&_proof}}.run([&](auto&& _expr, auto&& _addChild) { - if (_expr->name == "=") - for (auto const& t: targets) - { - auto arg0 = _expr->arguments.at(0); - auto arg1 = _expr->arguments.at(1); - if (boost::algorithm::starts_with(arg0.name, t)) - equalities.insert({arg0.name, {arg0, std::move(arg1)}}); - else if (boost::algorithm::starts_with(arg1.name, t)) - equalities.insert({arg1.name, {arg1, std::move(arg0)}}); - } - for (auto const& arg: _expr->arguments) - _addChild(&arg); - }); - std::map> invariants; - for (auto pred: _predicates) + for (auto const* pred: _predicates) { - auto predName = pred->functor().name; - if (!equalities.count(predName)) + smtAssert(pred); + auto const& predName = pred->functor().name; + if (!_invariants.contains(predName)) + continue; + if (ranges::none_of(targets, [&](auto const& _target) { return predName.starts_with(_target); })) continue; - solAssert(pred->contextContract(), ""); + smtAssert(pred->contextContract()); - auto const& [predExpr, invExpr] = equalities.at(predName); + auto const& [definition, formalArguments] = _invariants.at(predName); - static std::set const ignore{"true", "false"}; - auto r = substitute(invExpr, pred->expressionSubstitution(predExpr)); + auto r = substitute(definition, pred->expressionSubstitution(formalArguments)); // No point in reporting true/false as invariants. - if (!ignore.count(r.name)) + if (r.name != "true" && r.name != "false") invariants[pred].insert(toSolidityStr(r)); } return invariants; @@ -2205,7 +2189,7 @@ void CHC::checkAndReportTarget( placeholder.constraints && placeholder.errorExpression == _target.errorId ); auto const& location = _target.errorNode->location(); - auto [result, invariant, model] = query(error(), location); + auto [result, invariants, model] = query(error(), location); if (result == CheckResult::UNSATISFIABLE) { m_safeTargets[_target.errorNode].insert(_target); @@ -2214,9 +2198,9 @@ void CHC::checkAndReportTarget( predicates.insert(pred); for (auto const* pred: m_nondetInterfaces | ranges::views::values) predicates.insert(pred); - std::map> invariants = collectInvariants(invariant, predicates, m_settings.invariants); - for (auto pred: invariants | ranges::views::keys) - m_invariants[pred] += std::move(invariants.at(pred)); + std::map> invariantStrings = collectInvariants(invariants, predicates, m_settings.invariants); + for (auto pred: invariantStrings | ranges::views::keys) + m_invariants[pred] += std::move(invariantStrings.at(pred)); } else if (result == CheckResult::SATISFIABLE) { diff --git a/libsolidity/formal/Predicate.cpp b/libsolidity/formal/Predicate.cpp index 4b7ca8edb324..66d8c2405538 100644 --- a/libsolidity/formal/Predicate.cpp +++ b/libsolidity/formal/Predicate.cpp @@ -27,12 +27,10 @@ #include #include -#include #include #include -using boost::algorithm::starts_with; using namespace solidity; using namespace solidity::smtutil; using namespace solidity::frontend; @@ -434,15 +432,15 @@ std::pair>, std::vector Predicate::expressionSubstitution(smtutil::Expression const& _predExpr) const +std::map Predicate::expressionSubstitution(std::vector const& _predArgs) const { std::map subst; std::string predName = functor().name; - solAssert(contextContract(), ""); + smtAssert(contextContract()); auto const& stateVars = SMTEncoder::stateVariablesIncludingInheritedAndPrivate(*contextContract()); - auto nArgs = _predExpr.arguments.size(); + auto const nArgs = _predArgs.size(); // The signature of an interface predicate is // interface(this, abiFunctions, (optionally) bytesConcatFunctions, cryptoFunctions, blockchainState, stateVariables). @@ -450,12 +448,13 @@ std::map Predicate::expressionSubstitution(smtutil::Ex // invariant over its state, for example `x <= 0`. if (isInterface()) { + smtAssert(nArgs > 0); size_t shift = txValuesIndex(); - solAssert(starts_with(predName, "interface"), ""); - subst[_predExpr.arguments.at(0).name] = "address(this)"; - solAssert(nArgs == stateVars.size() + shift, ""); + smtAssert(predName.starts_with("interface")); + subst[_predArgs.at(0)] = "address(this)"; + smtAssert(nArgs == stateVars.size() + shift); for (size_t i = nArgs - stateVars.size(); i < nArgs; ++i) - subst[_predExpr.arguments.at(i).name] = stateVars.at(i - shift)->name(); + subst[_predArgs.at(i)] = stateVars.at(i - shift)->name(); } // The signature of a nondet interface predicate is // nondet_interface(error, this, abiFunctions, (optionally) bytesConcatFunctions, cryptoFunctions, blockchainState, stateVariables, blockchainState', stateVariables'). @@ -466,14 +465,15 @@ std::map Predicate::expressionSubstitution(smtutil::Ex // `(x <= 0) => (x' <= 100)`. else if (isNondetInterface()) { - solAssert(starts_with(predName, "nondet_interface"), ""); - subst[_predExpr.arguments.at(0).name] = ""; - subst[_predExpr.arguments.at(1).name] = "address(this)"; - solAssert(nArgs == stateVars.size() * 2 + firstArgIndex(), ""); + smtAssert(nArgs > 1); + smtAssert(predName.starts_with("nondet_interface")); + subst[_predArgs.at(0)] = ""; + subst[_predArgs.at(1)] = "address(this)"; + smtAssert(nArgs == stateVars.size() * 2 + firstArgIndex()); for (size_t i = nArgs - stateVars.size(), s = 0; i < nArgs; ++i, ++s) - subst[_predExpr.arguments.at(i).name] = stateVars.at(s)->name() + "'"; + subst[_predArgs.at(i)] = stateVars.at(s)->name() + "'"; for (size_t i = nArgs - (stateVars.size() * 2 + 1), s = 0; i < nArgs - (stateVars.size() + 1); ++i, ++s) - subst[_predExpr.arguments.at(i).name] = stateVars.at(s)->name(); + subst[_predArgs.at(i)] = stateVars.at(s)->name(); } return subst; diff --git a/libsolidity/formal/Predicate.h b/libsolidity/formal/Predicate.h index f389ab822111..7e4ba0f00fe8 100644 --- a/libsolidity/formal/Predicate.h +++ b/libsolidity/formal/Predicate.h @@ -179,9 +179,9 @@ class Predicate /// @returns the values of the local variables used by this predicate. std::pair>, std::vector> localVariableValues(std::vector const& _args) const; - /// @returns a substitution map from the arguments of _predExpr + /// @returns a substitution map from the predicate arguments @p _predArgs /// to a Solidity-like expression. - std::map expressionSubstitution(smtutil::Expression const& _predExprs) const; + std::map expressionSubstitution(std::vector const& _predArgs) const; private: /// Recursively fills _array from _expr. diff --git a/libsolidity/formal/Z3CHCSmtLib2Interface.cpp b/libsolidity/formal/Z3CHCSmtLib2Interface.cpp index 2ceecfcf9088..da6f14d963d3 100644 --- a/libsolidity/formal/Z3CHCSmtLib2Interface.cpp +++ b/libsolidity/formal/Z3CHCSmtLib2Interface.cpp @@ -90,26 +90,23 @@ CHCSolverInterface::QueryResult Z3CHCSmtLib2Interface::query(smtutil::Expression #endif setupSmtCallback(true); if (!boost::starts_with(response, "unsat")) - return {CheckResult::SATISFIABLE, Expression(true), {}}; - return {CheckResult::SATISFIABLE, Expression(true), graphFromZ3Answer(response)}; + return {CheckResult::SATISFIABLE, {}, {}}; + return {CheckResult::SATISFIABLE, {}, graphFromZ3Answer(response)}; } CheckResult result; if (boost::starts_with(response, "sat")) - { - auto maybeInvariants = invariantsFromSolverResponse(response); - return {CheckResult::UNSATISFIABLE, maybeInvariants.value_or(Expression(true)), {}}; - } - else if (boost::starts_with(response, "unknown")) + return {CheckResult::UNSATISFIABLE, invariantsFromSolverResponse(response), {}}; + if (boost::starts_with(response, "unknown")) result = CheckResult::UNKNOWN; else result = CheckResult::ERROR; - return {result, Expression(true), {}}; + return {result, {}, {}}; } catch(smtutil::SMTSolverInteractionError const&) { - return {CheckResult::ERROR, Expression(true), {}}; + return {CheckResult::ERROR, {}, {}}; } } From dbd5521a697eae275afeb5d8a0b256670238f5b9 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Fri, 4 Apr 2025 07:50:21 +0200 Subject: [PATCH 0906/1022] remove install of obsolete jsoncpp --- .circleci/osx_install_dependencies.sh | 3 --- scripts/install_obsolete_jsoncpp_1_7_4.sh | 24 ----------------------- 2 files changed, 27 deletions(-) delete mode 100755 scripts/install_obsolete_jsoncpp_1_7_4.sh diff --git a/.circleci/osx_install_dependencies.sh b/.circleci/osx_install_dependencies.sh index e7a0b9ddfda2..6e0c859f9ace 100755 --- a/.circleci/osx_install_dependencies.sh +++ b/.circleci/osx_install_dependencies.sh @@ -59,9 +59,6 @@ then brew install openjdk@11 brew install unzip - # writing to /usr/local/lib need administrative privileges. - sudo ./scripts/install_obsolete_jsoncpp_1_7_4.sh - # boost boost_version="1.84.0" boost_package="boost_${boost_version//./_}.tar.bz2" diff --git a/scripts/install_obsolete_jsoncpp_1_7_4.sh b/scripts/install_obsolete_jsoncpp_1_7_4.sh deleted file mode 100755 index f9de0245d70b..000000000000 --- a/scripts/install_obsolete_jsoncpp_1_7_4.sh +++ /dev/null @@ -1,24 +0,0 @@ -#!/usr/bin/env bash -set -eu - -TEMPDIR=$(mktemp -d) -( - cd "$TEMPDIR" - jsoncpp_version="1.7.4" - jsoncpp_package="jsoncpp-${jsoncpp_version}.tar.gz" - jsoncpp_sha256=10dcd0677e80727e572a1e462193e51a5fde3e023b99e144b2ee1a469835f769 - wget -O "$jsoncpp_package" https://github.com/open-source-parsers/jsoncpp/archive/${jsoncpp_version}.tar.gz - if ! [ "$(sha256sum "$jsoncpp_package")" = "${jsoncpp_sha256} ${jsoncpp_package}" ] - then - >&2 echo "ERROR: Downloaded jsoncpp source package has wrong checksum." - exit 1 - fi - tar xvzf "$jsoncpp_package" - cd "jsoncpp-${jsoncpp_version}" - mkdir -p build - cd build - cmake -DCMAKE_OSX_ARCHITECTURES:STRING="x86_64;arm64" -DARCHIVE_INSTALL_DIR=. -G "Unix Makefiles" .. - make - make install -) -rm -r "$TEMPDIR" From f323bd4de27b635dab1ba249832a1ec0b054cf4e Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Fri, 4 Apr 2025 09:07:12 +0200 Subject: [PATCH 0907/1022] cmake: use boost include dirs and version in status message --- cmake/EthDependencies.cmake | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/cmake/EthDependencies.cmake b/cmake/EthDependencies.cmake index 87a5e1b5e17e..56d90bb478e3 100644 --- a/cmake/EthDependencies.cmake +++ b/cmake/EthDependencies.cmake @@ -49,8 +49,7 @@ if (NOT TARGET Boost::boost) # header only target add_library(Boost::boost INTERFACE IMPORTED) set_property(TARGET Boost::boost APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${Boost_INCLUDE_DIRS}) endif() -get_property(LOCATION TARGET Boost::boost PROPERTY INTERFACE_INCLUDE_DIRECTORIES) -message(STATUS "Found Boost headers in ${LOCATION}") +message(STATUS "Found Boost ${Boost_VERSION} headers in ${Boost_INCLUDE_DIRS}") foreach (BOOST_COMPONENT IN LISTS BOOST_COMPONENTS) if (NOT TARGET Boost::${BOOST_COMPONENT}) From e6d56997aba55b2805a288b671d14651bd140270 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Fri, 4 Apr 2025 09:17:23 +0200 Subject: [PATCH 0908/1022] set CMP0167 to OLD behavior for boost versions < 1.70 --- cmake/EthDependencies.cmake | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/cmake/EthDependencies.cmake b/cmake/EthDependencies.cmake index 56d90bb478e3..f79140dd29d9 100644 --- a/cmake/EthDependencies.cmake +++ b/cmake/EthDependencies.cmake @@ -31,6 +31,10 @@ endif() set(BOOST_COMPONENTS "filesystem;unit_test_framework;program_options;system") +# CMake >= 3.30 should not use the vendored boost +if(POLICY CMP0167) + cmake_policy(SET CMP0167 NEW) +endif() if (WIN32) # Boost 1.77 fixes a bug that causes crashes on Windows for some relative paths in --allow-paths. # See https://github.com/boostorg/filesystem/issues/201 @@ -38,7 +42,16 @@ if (WIN32) else() # Boost 1.65 is the first to also provide boost::get for rvalue-references (#5787). # Boost 1.67 moved container_hash into is own module. - find_package(Boost 1.67.0 QUIET REQUIRED COMPONENTS ${BOOST_COMPONENTS}) + # Boost 1.70 comes with its own BoostConfig.cmake and is the new (non-deprecated) behavior + find_package(Boost 1.70.0 QUIET COMPONENTS ${BOOST_COMPONENTS}) + if (NOT ${Boost_FOUND}) + # If the boost version is < 1.70.0, there is no boost config delivered with it, revert to old behavior + # todo drop this once cmake minimum version >= 3.30 is reached + if(POLICY CMP0167) + cmake_policy(SET CMP0167 OLD) + endif() + find_package(Boost 1.67.0 QUIET REQUIRED COMPONENTS ${BOOST_COMPONENTS}) + endif() endif() # If cmake is older than boost and boost is older than 1.70, From 4c23d04b53cba7bfda8ddf19ead131e88529e003 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Mon, 7 Apr 2025 16:00:49 +0200 Subject: [PATCH 0909/1022] Disable pedantic compilation for CMake 4.0.0 and AppleClang 15.0 --- CMakeLists.txt | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5b39878f26d3..29bf2b0ca663 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -70,6 +70,14 @@ endif() find_package(Threads) +if ("${CMAKE_SYSTEM_NAME}" MATCHES "Darwin" AND "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") + if (CMAKE_VERSION VERSION_EQUAL "4.0.0" AND CMAKE_CXX_COMPILER_VERSION VERSION_EQUAL "15.0.0.15000040") + # for Apple clang 15 under cmake 4.0.0, disable pedantic warnings explicitly as it fails to treat boost properly as + # system library, warnings propagate + set(PEDANTIC OFF) + endif() +endif() + if(NOT PEDANTIC) message(WARNING "-- Pedantic build flags turned off. Warnings will not make compilation fail. This is NOT recommended in development builds.") endif() From 2cd97dc2b248edfac74241036cf7327d035bae57 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Tue, 8 Apr 2025 11:34:38 +0200 Subject: [PATCH 0910/1022] Use pre-release version of sphinx-a4doc for python 3.13 --- docs/requirements.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/requirements.txt b/docs/requirements.txt index b1b21a8691d3..e0c87915b40a 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -4,7 +4,9 @@ sphinx_rtd_theme>=0.5.2 pygments-lexer-solidity>=0.7.0 -sphinx-a4doc>=1.6.0 +sphinx-a4doc>=1.6.0; python_version < '3.13' +# todo remove this once there is a version > 1.6.0 +sphinx-a4doc @ git+https://github.com/taminomara/sphinx-a4doc@f63d3b2; python_version >= '3.13' # Sphinx 2.1.0 is the oldest version that accepts a lexer class in add_lexer() sphinx>=2.1.0, <6.0 From 0a6cce58a0e3814db15844c53e05e384e00088fd Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Tue, 8 Apr 2025 11:34:59 +0200 Subject: [PATCH 0911/1022] relax sphinx version range to [2.1, 9) --- docs/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/requirements.txt b/docs/requirements.txt index e0c87915b40a..8e058b6296b9 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -9,4 +9,4 @@ sphinx-a4doc>=1.6.0; python_version < '3.13' sphinx-a4doc @ git+https://github.com/taminomara/sphinx-a4doc@f63d3b2; python_version >= '3.13' # Sphinx 2.1.0 is the oldest version that accepts a lexer class in add_lexer() -sphinx>=2.1.0, <6.0 +sphinx>=2.1.0, <9.0 From 971ac4c9ae79c4b7d5d76d23df1e1c9cd75b61ab Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Tue, 8 Apr 2025 11:46:21 +0200 Subject: [PATCH 0912/1022] require rtd theme < 3.0.0 --- docs/requirements.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/requirements.txt b/docs/requirements.txt index 8e058b6296b9..f4c1aae61730 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1,7 +1,8 @@ # Older versions of sphinx-rtd-theme do not work with never docutils but have a bug in the dependency # which could result in it being installed anyway and the style (especially bullet points) being broken. # See https://github.com/readthedocs/sphinx_rtd_theme/issues/1115 -sphinx_rtd_theme>=0.5.2 +# theme >=3.0.0 removes the display_version option in favor of version_selector and language_selector +sphinx_rtd_theme>=0.5.2, <3.0.0 pygments-lexer-solidity>=0.7.0 sphinx-a4doc>=1.6.0; python_version < '3.13' From 502ebaa8f879e8c5b5440a984030cf30f48c6f8a Mon Sep 17 00:00:00 2001 From: Michael Cho Date: Mon, 31 Mar 2025 16:06:00 -0400 Subject: [PATCH 0913/1022] Add support for upcoming Boost 1.88.0 Boost.Process will make v2 the default in Boost 1.88.0[^1] which breaks compilation of prior code. For a simple fix, this commit updates to use the newer paths for v1 until the code is updated to use v2 API. [^1]: https://github.com/boostorg/process/commit/2ccd97cd48c5468b0609a488b59253efaa381711 --- libsolidity/formal/ModelChecker.cpp | 6 ++++++ libsolidity/interface/SMTSolverCommand.cpp | 9 +++++++++ test/libyul/ControlFlowGraphTest.cpp | 8 ++++++++ test/libyul/SSAControlFlowGraphTest.cpp | 8 ++++++++ test/libyul/StackLayoutGeneratorTest.cpp | 8 ++++++++ 5 files changed, 39 insertions(+) diff --git a/libsolidity/formal/ModelChecker.cpp b/libsolidity/formal/ModelChecker.cpp index 04d96f06746c..2d52414127a6 100644 --- a/libsolidity/formal/ModelChecker.cpp +++ b/libsolidity/formal/ModelChecker.cpp @@ -18,7 +18,13 @@ #include +#include +#if (BOOST_VERSION < 108800) #include +#else +#define BOOST_PROCESS_VERSION 1 +#include +#endif #include #include diff --git a/libsolidity/interface/SMTSolverCommand.cpp b/libsolidity/interface/SMTSolverCommand.cpp index 66adfd0c5e17..e6e0ded6252d 100644 --- a/libsolidity/interface/SMTSolverCommand.cpp +++ b/libsolidity/interface/SMTSolverCommand.cpp @@ -20,7 +20,16 @@ #include #include +#include +#if (BOOST_VERSION < 108800) #include +#else +#define BOOST_PROCESS_VERSION 1 +#include +#include +#include +#include +#endif namespace solidity::frontend { diff --git a/test/libyul/ControlFlowGraphTest.cpp b/test/libyul/ControlFlowGraphTest.cpp index c0ab37956e4c..594b2f6c96ee 100644 --- a/test/libyul/ControlFlowGraphTest.cpp +++ b/test/libyul/ControlFlowGraphTest.cpp @@ -29,7 +29,15 @@ #include #ifdef ISOLTEST +#include +#if (BOOST_VERSION < 108800) #include +#else +#define BOOST_PROCESS_VERSION 1 +#include +#include +#include +#endif #endif using namespace solidity; diff --git a/test/libyul/SSAControlFlowGraphTest.cpp b/test/libyul/SSAControlFlowGraphTest.cpp index c23a2ca5faf9..d2acee7bcb85 100644 --- a/test/libyul/SSAControlFlowGraphTest.cpp +++ b/test/libyul/SSAControlFlowGraphTest.cpp @@ -28,7 +28,15 @@ #include #ifdef ISOLTEST +#include +#if (BOOST_VERSION < 108800) #include +#else +#define BOOST_PROCESS_VERSION 1 +#include +#include +#include +#endif #endif using namespace solidity; diff --git a/test/libyul/StackLayoutGeneratorTest.cpp b/test/libyul/StackLayoutGeneratorTest.cpp index eb34eabb1776..0c85b1a7b968 100644 --- a/test/libyul/StackLayoutGeneratorTest.cpp +++ b/test/libyul/StackLayoutGeneratorTest.cpp @@ -33,7 +33,15 @@ #include #ifdef ISOLTEST +#include +#if (BOOST_VERSION < 108800) #include +#else +#define BOOST_PROCESS_VERSION 1 +#include +#include +#include +#endif #endif using namespace solidity; From 334b7685525367fe8bbe8781ec260fef0ee44f7b Mon Sep 17 00:00:00 2001 From: Daniel Kirchner Date: Wed, 12 Mar 2025 12:28:40 +0100 Subject: [PATCH 0914/1022] Remove Z3 from ppa scripts and add ubunutu plucky. --- scripts/deps-ppa/static_z3.sh | 267 ---------------------------------- scripts/release_ppa.sh | 11 +- 2 files changed, 4 insertions(+), 274 deletions(-) delete mode 100755 scripts/deps-ppa/static_z3.sh diff --git a/scripts/deps-ppa/static_z3.sh b/scripts/deps-ppa/static_z3.sh deleted file mode 100755 index 140c40c6abb3..000000000000 --- a/scripts/deps-ppa/static_z3.sh +++ /dev/null @@ -1,267 +0,0 @@ -#!/usr/bin/env bash -############################################################################## -## This is used to package .deb packages and upload them to the launchpad -## ppa servers for building. -## -## It will clone the Z3 git from github on the specified version tag, -## create a source archive and push it to the ubuntu ppa servers. -## -## This requires the following entries in /etc/dput.cf: -## -## [cpp-build-deps] -## fqdn = ppa.launchpad.net -## method = ftp -## incoming = ~ethereum/cpp-build-deps -## login = anonymous -## -## To interact with launchpad, you need to set the variables $LAUNCHPAD_EMAIL -## and $LAUNCHPAD_KEYID in the file .release_ppa_auth in the root directory of -## the project to your launchpad email and pgp keyid. -## This could for example look like this: -## -## LAUNCHPAD_EMAIL=your-launchpad-email@ethereum.org -## LAUNCHPAD_KEYID=123ABCFFFFFFFF -## -############################################################################## - -set -e - -packagename=z3-static -version="$1" - -REPO_ROOT="$(dirname "$0")/../.." - -# shellcheck source=/dev/null -source "${REPO_ROOT}/scripts/common.sh" - -[[ $version != "" ]] || fail "Usage: $0 " - -sourcePPAConfig - -# Sanity check -checkDputEntries "\[cpp-build-deps\]" - -DISTRIBUTIONS="jammy noble oracular" - -for distribution in $DISTRIBUTIONS -do -cd /tmp/ -rm -rf "$distribution" -mkdir "$distribution" -cd "$distribution" - -pparepo=cpp-build-deps -ppafilesurl=https://launchpad.net/~ethereum/+archive/ubuntu/${pparepo}/+files - -# Fetch source -git clone --branch "z3-${version}" https://github.com/Z3Prover/z3.git -cd z3 - -debversion="${version}" - -CMAKE_OPTIONS="-DZ3_BUILD_LIBZ3_SHARED=OFF -DCMAKE_BUILD_TYPE=Release" - -# gzip will create different tars all the time and we are not allowed -# to upload the same file twice with different contents, so we only -# create it once. -if [ ! -e "/tmp/${packagename}_${debversion}.orig.tar.gz" ] -then - tar --exclude .git -czf "/tmp/${packagename}_${debversion}.orig.tar.gz" . -fi -cp "/tmp/${packagename}_${debversion}.orig.tar.gz" ../ - -# Create debian package information - -mkdir debian -echo 9 > debian/compat -# TODO: the Z3 packages have different build dependencies -cat < debian/control -Source: z3-static -Section: science -Priority: extra -Maintainer: Daniel Kirchner -Build-Depends: debhelper (>= 9.0.0), - cmake, - g++ (>= 5.0), - git, - libgmp-dev, - dh-python, - python3 -Standards-Version: 3.9.6 -Homepage: https://github.com/Z3Prover/z3 -Vcs-Git: https://github.com/Z3Prover/z3.git -Vcs-Browser: https://github.com/Z3Prover/z3 - -Package: z3-static -Architecture: any -Breaks: z3 -Replaces: z3 -Depends: \${misc:Depends}, \${shlibs:Depends} -Description: theorem prover from Microsoft Research - Z3 is a state-of-the art theorem prover from Microsoft Research. It can be - used to check the satisfiability of logical formulas over one or more - theories. Z3 offers a compelling match for software analysis and verification - tools, since several common software constructs map directly into supported - theories. - . - The Z3 input format is an extension of the one defined by the SMT-LIB 2.0 - standard. - - -Package: libz3-static-dev -Section: libdevel -Architecture: any-amd64 -Breaks: libz3-dev -Replaces: libz3-dev -Multi-Arch: same -Depends: \${shlibs:Depends}, \${misc:Depends} -Description: theorem prover from Microsoft Research - development files (static library) - Z3 is a state-of-the art theorem prover from Microsoft Research. It can be - used to check the satisfiability of logical formulas over one or more - theories. Z3 offers a compelling match for software analysis and verification - tools, since several common software constructs map directly into supported - theories. - . - This package can be used to invoke Z3 via its C++ API. -EOF -cat < debian/rules -#!/usr/bin/make -f -# -*- makefile -*- -# Sample debian/rules that uses debhelper. -# -# This file was originally written by Joey Hess and Craig Small. -# As a special exception, when this file is copied by dh-make into a -# dh-make output file, you may use that output file without restriction. -# This special exception was added by Craig Small in version 0.37 of dh-make. -# -# Modified to make a template file for a multi-binary package with separated -# build-arch and build-indep targets by Bill Allombert 2001 - -# Uncomment this to turn on verbose mode. -export DH_VERBOSE=1 - -# This has to be exported to make some magic below work. -export DH_OPTIONS - - -%: - dh \$@ --buildsystem=cmake - -override_dh_auto_test: - -override_dh_shlibdeps: - dh_shlibdeps --dpkg-shlibdeps-params=--ignore-missing-info - -override_dh_auto_configure: - dh_auto_configure -- ${CMAKE_OPTIONS} - -override_dh_auto_install: - dh_auto_install --destdir debian/tmp -EOF -cat < debian/libz3-static-dev.install -usr/include/* -usr/lib/*/libz3.a -usr/lib/*/cmake/z3/* -EOF -cat < debian/z3-static.install -usr/bin/z3 -EOF -cat < debian/copyright -Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ -Upstream-Name: z3 -Source: https://github.com/Z3Prover/z3 - -Files: * -Copyright: Microsoft Corporation -License: Expat - Permission is hereby granted, free of charge, to any person obtaining a copy of - this software and associated documentation files (the "Software"), to deal in - the Software without restriction, including without limitation the rights to - use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies - of the Software, and to permit persons to whom the Software is furnished to do - so, subject to the following conditions: - . - The above copyright notice and this permission notice shall be included in all - copies or substantial portions of the Software. - . - THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. - -Files: debian/* -Copyright: 2019 Ethereum -License: GPL-3.0+ -This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - . - This package is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - . - You should have received a copy of the GNU General Public License - along with this program. If not, see . - . - On Debian systems, the complete text of the GNU General - Public License version 3 can be found in "/usr/share/common-licenses/GPL-3". -EOF -cat < debian/changelog -z3-static (0.0.1-1ubuntu0) saucy; urgency=low - - * Initial release. - - -- Daniel Mon, 03 Jun 2019 14:50:20 +0000 -EOF -mkdir debian/source -echo "3.0 (quilt)" > debian/source/format -chmod +x debian/rules - -versionsuffix=1ubuntu0~${distribution} -EMAIL="$LAUNCHPAD_EMAIL" dch -v "1:${debversion}-${versionsuffix}" "build of ${version}" - -# build source package -# If packages is rejected because original source is already present, add -# -sd to remove it from the .changes file -# -d disables the build dependencies check -debuild -S -d -sa -us -uc - -# prepare .changes file for Launchpad -sed -i -e "s/UNRELEASED/${distribution}/" -e s/urgency=medium/urgency=low/ ../*.changes - -# check if ubuntu already has the source tarball -( -cd .. -orig="${packagename}_${debversion}.orig.tar.gz" -# shellcheck disable=SC2012 -orig_size=$(ls -l "$orig" | cut -d ' ' -f 5) -orig_sha1=$(sha1sum "$orig" | cut -d ' ' -f 1) -orig_sha256=$(sha256sum "$orig" | cut -d ' ' -f 1) -orig_md5=$(md5sum "$orig" | cut -d ' ' -f 1) - -if wget --quiet -O "$orig-tmp" "$ppafilesurl/$orig" -then - echo "[WARN] Original tarball found in Ubuntu archive, using it instead" - mv "${orig}-tmp" "$orig" - # shellcheck disable=SC2012 - new_size=$(ls -l ./*.orig.tar.gz | cut -d ' ' -f 5) - new_sha1=$(sha1sum "$orig" | cut -d ' ' -f 1) - new_sha256=$(sha256sum "$orig" | cut -d ' ' -f 1) - new_md5=$(md5sum "$orig" | cut -d ' ' -f 1) - sed -i -e "s,$orig_sha1,$new_sha1,g" -e "s,$orig_sha256,$new_sha256,g" -e "s,$orig_size,$new_size,g" -e "s,$orig_md5,$new_md5,g" ./*.dsc - sed -i -e "s,$orig_sha1,$new_sha1,g" -e "s,$orig_sha256,$new_sha256,g" -e "s,$orig_size,$new_size,g" -e "s,$orig_md5,$new_md5,g" ./*.changes -fi -) - -# sign the package -debsign --re-sign -k "${LAUNCHPAD_KEYID}" "../${packagename}_${debversion}-${versionsuffix}_source.changes" - -# upload -dput "${pparepo}" "../${packagename}_${debversion}-${versionsuffix}_source.changes" - -done diff --git a/scripts/release_ppa.sh b/scripts/release_ppa.sh index cf8df3d6c47d..2d0cbd180f56 100755 --- a/scripts/release_ppa.sh +++ b/scripts/release_ppa.sh @@ -68,7 +68,7 @@ packagename=solc # This needs to be a still active release static_build_distribution=noble -DISTRIBUTIONS="jammy noble oracular" +DISTRIBUTIONS="jammy noble oracular plucky" if is_release then @@ -103,17 +103,14 @@ else fi if [ "$distribution" = focal ] then - SMTDEPENDENCY="libz3-static-dev, - libcvc4-dev, + SMTDEPENDENCY="libcvc4-dev, " elif [ "$distribution" = disco ] then - SMTDEPENDENCY="libz3-static-dev, - libcvc4-dev, + SMTDEPENDENCY="libcvc4-dev, " else - SMTDEPENDENCY="libz3-static-dev, - " + SMTDEPENDENCY="" fi CMAKE_OPTIONS="" fi From 38810a3dc2d91aa51b2788a2df9170da421d34c2 Mon Sep 17 00:00:00 2001 From: Daniel Kirchner Date: Tue, 8 Apr 2025 15:15:38 +0200 Subject: [PATCH 0915/1022] Adjust release checklist. --- ReleaseChecklist.md | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/ReleaseChecklist.md b/ReleaseChecklist.md index f5e4ec7cae21..c9fcaba79fb7 100644 --- a/ReleaseChecklist.md +++ b/ReleaseChecklist.md @@ -85,10 +85,7 @@ At least a day before the release: ### PPA - [ ] Create `.release_ppa_auth` at the root of your local Solidity checkout and set `LAUNCHPAD_EMAIL` and `LAUNCHPAD_KEYID` to your key's email and key id. -- [ ] Double-check that the `DISTRIBUTIONS` list in `scripts/release_ppa.sh` and `scripts/deps-ppa/static_z3.sh` contains the most recent versions of Ubuntu. -- [ ] Make sure the [`~ethereum/cpp-build-deps` PPA repository](https://launchpad.net/~ethereum/+archive/ubuntu/cpp-build-deps) contains `libz3-static-dev` builds for all current versions of Ubuntu. - Note that it may be included in the `z3-static` multipackage (follow the `View package details` link to check). - If not present, run `scripts/deps-ppa/static_z3.sh` and wait for the builds to succeed before continuing. +- [ ] Double-check that the `DISTRIBUTIONS` list in `scripts/release_ppa.sh` contains the most recent versions of Ubuntu. - [ ] Run `scripts/release_ppa.sh v$VERSION` to create the PPA release. This will create a single package containing static binary for older Ubuntu versions in the [`~ethereum/ethereum-static` PPA](https://launchpad.net/~ethereum/+archive/ubuntu/ethereum-static) and separate packages with dynamically-linked binaries for recent versions (those listed in `DISTRIBUTIONS`) in the [`~ethereum/ethereum` PPA](https://launchpad.net/~ethereum/+archive/ubuntu/ethereum). From fd2d543c6b7f6f134c6146dc8013814fd3e44c13 Mon Sep 17 00:00:00 2001 From: Daniel Kirchner Date: Tue, 8 Apr 2025 15:21:33 +0200 Subject: [PATCH 0916/1022] Also drop libcvc4-dev and smtdependencies generally. --- scripts/release_ppa.sh | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/scripts/release_ppa.sh b/scripts/release_ppa.sh index 2d0cbd180f56..a8d89040f2dc 100755 --- a/scripts/release_ppa.sh +++ b/scripts/release_ppa.sh @@ -92,7 +92,6 @@ cd "$distribution" if [ "$distribution" = STATIC ] then pparepo=ethereum-static - SMTDEPENDENCY="" CMAKE_OPTIONS="-DSOLC_LINK_STATIC=On -DCMAKE_EXE_LINKER_FLAGS=-static" else if is_release @@ -101,17 +100,6 @@ else else pparepo=ethereum-dev fi - if [ "$distribution" = focal ] - then - SMTDEPENDENCY="libcvc4-dev, - " - elif [ "$distribution" = disco ] - then - SMTDEPENDENCY="libcvc4-dev, - " - else - SMTDEPENDENCY="" - fi CMAKE_OPTIONS="" fi ppafilesurl=https://launchpad.net/~ethereum/+archive/ubuntu/${pparepo}/+files @@ -153,7 +141,7 @@ Source: solc Section: science Priority: extra Maintainer: Christian (Buildserver key) -Build-Depends: ${SMTDEPENDENCY}debhelper (>= 9.0.0), +Build-Depends: debhelper (>= 9.0.0), cmake, g++ (>= 5.0), git, From e13c612202823d158e845df4435e405fd1576dea Mon Sep 17 00:00:00 2001 From: Henry Chu Date: Fri, 4 Apr 2025 16:28:43 +0800 Subject: [PATCH 0917/1022] Language Server: Fix hover crashes on invalid parameters When `textDocument/hover` gets an out-of-range request --- libsolidity/lsp/DocumentHoverHandler.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/libsolidity/lsp/DocumentHoverHandler.cpp b/libsolidity/lsp/DocumentHoverHandler.cpp index e5991b765a66..a4f3de25c014 100644 --- a/libsolidity/lsp/DocumentHoverHandler.cpp +++ b/libsolidity/lsp/DocumentHoverHandler.cpp @@ -59,6 +59,11 @@ void DocumentHoverHandler::operator()(MessageID _id, Json const& _args) { auto const [sourceUnitName, lineColumn] = HandlerBase(*this).extractSourceUnitNameAndLineColumn(_args); auto const [sourceNode, sourceOffset] = m_server.astNodeAndOffsetAtSourceLocation(sourceUnitName, lineColumn); + if (!sourceNode) + { + client().reply(_id, Json()); + return; + } MarkdownBuilder markdown; auto rangeToHighlight = toRange(sourceNode->location()); From 1cd7045cd2cf77a813b8b3baecfcfc5eb5b6af25 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Mon, 14 Apr 2025 08:52:53 +0200 Subject: [PATCH 0918/1022] Remove disable pedantic mode switch for osx cmake 4.0.0 and clang 15.0.0 --- CMakeLists.txt | 8 -------- 1 file changed, 8 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 29bf2b0ca663..5b39878f26d3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -70,14 +70,6 @@ endif() find_package(Threads) -if ("${CMAKE_SYSTEM_NAME}" MATCHES "Darwin" AND "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") - if (CMAKE_VERSION VERSION_EQUAL "4.0.0" AND CMAKE_CXX_COMPILER_VERSION VERSION_EQUAL "15.0.0.15000040") - # for Apple clang 15 under cmake 4.0.0, disable pedantic warnings explicitly as it fails to treat boost properly as - # system library, warnings propagate - set(PEDANTIC OFF) - endif() -endif() - if(NOT PEDANTIC) message(WARNING "-- Pedantic build flags turned off. Warnings will not make compilation fail. This is NOT recommended in development builds.") endif() From 09715e6d13f3922b96d671cddf463aea6523ad3e Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Mon, 14 Apr 2025 09:18:54 +0200 Subject: [PATCH 0919/1022] osx ci: Install Boost to /opt/boost instead of /usr/local --- .circleci/config.yml | 10 ++++++++-- .circleci/osx_install_dependencies.sh | 3 ++- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index d26ef3bd41a6..09b1281c5630 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -385,7 +385,7 @@ commands: name: Installing dependencies / Restoring dependency cache command: | if [[ -f ~/osx-dependencies-cached ]]; then - echo "Dependency flag exists. Removing /usr/local/ and /opt/homebrew/. These directories will be restored from cache." + echo "Dependency flag exists. Removing /usr/local/, /opt/homebrew/, and /opt/boost. These directories will be restored from cache." # CircleCI is providing the circleci cli tools via some kind of symlink magic. # So we just save the original symlinks and restore them later. @@ -405,6 +405,10 @@ commands: sudo mkdir -p /usr/local/bin sudo chmod 777 /usr/{local,local/bin} + sudo rm -rf /opt/boost + sudo mkdir -p /opt/boost + sudo chmod 777 /opt/boost + mv /tmp/circleci "${circleci_binary_path}" mv /tmp/circleci-agent "${circleci_agent_binary_path}" fi @@ -425,6 +429,7 @@ commands: # Homebrew is installed in /usr/local on intel macs, but in /opt/homebrew on apple silicon. - /usr/local - /opt/homebrew + - /opt/boost - save_cache: key: osx-dependencies-cached-{{ arch }}-{{ checksum ".circleci/osx_install_dependencies.sh" }} paths: @@ -1159,7 +1164,8 @@ jobs: environment: <<: *base_osx_env CMAKE_BUILD_TYPE: Release - CMAKE_OPTIONS: -DCMAKE_OSX_ARCHITECTURES:STRING=x86_64;arm64 + # boost root configured to the prefix used in `osx_install_dependencies.sh` + CMAKE_OPTIONS: -DCMAKE_OSX_ARCHITECTURES:STRING=x86_64;arm64 -DBoost_ROOT=/opt/boost steps: - checkout - install_dependencies_osx diff --git a/.circleci/osx_install_dependencies.sh b/.circleci/osx_install_dependencies.sh index 6e0c859f9ace..367e8cbb40cb 100755 --- a/.circleci/osx_install_dependencies.sh +++ b/.circleci/osx_install_dependencies.sh @@ -69,7 +69,8 @@ then cd "$boost_dir" ./bootstrap.sh --with-toolset=clang --with-libraries=thread,system,filesystem,program_options,serialization,test # the default number of jobs that b2 is taking, is the number of detected available CPU threads. - sudo ./b2 -a address-model=64 architecture=arm+x86 install + # install boost to /opt/boost, to use it in CMake, specify Boost_ROOT + sudo ./b2 -a address-model=64 architecture=arm+x86 --prefix=/opt/boost install cd .. sudo rm -rf "$boost_dir" From f1c3a2d6eb2e071d5b09a0a472fd5871e342f83f Mon Sep 17 00:00:00 2001 From: closeobserve Date: Sun, 13 Apr 2025 19:13:59 +0800 Subject: [PATCH 0920/1022] chore: remove redundant word in comment Signed-off-by: closeobserve --- libsolidity/codegen/YulUtilFunctions.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libsolidity/codegen/YulUtilFunctions.h b/libsolidity/codegen/YulUtilFunctions.h index 5ea99d603083..c28ba855c816 100644 --- a/libsolidity/codegen/YulUtilFunctions.h +++ b/libsolidity/codegen/YulUtilFunctions.h @@ -560,7 +560,7 @@ class YulUtilFunctions /// Signature: (address) -> mpos std::string externalCodeFunction(); - /// @return the name of a function that that checks if two external functions pointers are equal or not + /// @return the name of a function that checks if two external functions pointers are equal or not std::string externalFunctionPointersEqualFunction(); private: From 1706158dbb4e2525695c8cef023b87b37052af4c Mon Sep 17 00:00:00 2001 From: futreall <86553580+futreall@users.noreply.github.com> Date: Tue, 25 Mar 2025 18:41:27 +0200 Subject: [PATCH 0921/1022] Update premium.sol --- test/compilationTests/corion/premium.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/compilationTests/corion/premium.sol b/test/compilationTests/corion/premium.sol index 646ab00e1594..2702aa5bb815 100644 --- a/test/compilationTests/corion/premium.sol +++ b/test/compilationTests/corion/premium.sol @@ -229,7 +229,7 @@ contract premium is module, safeMath { function transfer(address to, uint256 amount, bytes calldata extraData) isReady external returns (bool success) { /* Launch a transaction where we transfer from a given address to another one. - After thetransaction the approvedCorionPremiumToken function of the receiver’s address is going to be called with the given data. + After the transaction the approvedCorionPremiumToken function of the receiver’s address is going to be called with the given data. @to For who? @amount Amount From a1be4f313dd4120b5cb5994fe93f03c76e1de9ba Mon Sep 17 00:00:00 2001 From: futreall <86553580+futreall@users.noreply.github.com> Date: Tue, 25 Mar 2025 18:41:58 +0200 Subject: [PATCH 0922/1022] Update publisher.sol --- test/compilationTests/corion/publisher.sol | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/compilationTests/corion/publisher.sol b/test/compilationTests/corion/publisher.sol index 311e8d92e725..27d90a27e89b 100644 --- a/test/compilationTests/corion/publisher.sol +++ b/test/compilationTests/corion/publisher.sol @@ -205,8 +205,8 @@ contract publisher is announcementTypes, module, safeMath { If announcement is opposable, anyone owning a token can oppose it Opposition is automatically with the total amount of tokens If the quantity of his tokens changes, the purport of his opposition changes automatically - The prime time is the windup of the announcement, because this is the moment when the number of tokens in opposition are counted. - One address is entitled to be in oppositon only once. An opposition cannot be withdrawn. + The prime time is the windup of the announcement, because this is the moment when the number of tokens in opposition are counted. + One address is entitled to be in opposition only once. An opposition cannot be withdrawn. Running announcements can be opposed only. @id Announcement identification From 513535a75849bf18c44e24f31e56aad4d1b4b94f Mon Sep 17 00:00:00 2001 From: matta Date: Fri, 8 Mar 2024 17:17:06 -0300 Subject: [PATCH 0923/1022] Adding clarity on extcalls with precompiled contracts. --- docs/control-structures.rst | 33 +++++++++++++++++++++++---------- 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/docs/control-structures.rst b/docs/control-structures.rst index 1d21a6e2668e..8a815e10ef0f 100644 --- a/docs/control-structures.rst +++ b/docs/control-structures.rst @@ -111,22 +111,35 @@ otherwise, the ``value`` option would not be available. the ``value`` and ``gas`` settings are lost, only ``feed.info{value: 10, gas: 800}()`` performs the function call. -Due to the fact that the EVM considers a call to a non-existing contract to -always succeed, Solidity uses the ``extcodesize`` opcode to check that -the contract that is about to be called actually exists (it contains code) -and causes an exception if it does not. This check is skipped if the return -data will be decoded after the call and thus the ABI decoder will catch the -case of a non-existing contract. +.. warning:: + Due to the fact that the EVM considers a call to a non-existing contract to + always succeed, Solidity uses the ``extcodesize`` opcode to check that + the contract that is about to be called actually exists (it contains code) + and causes an exception if it does not. This check is skipped if the return + data will be decoded after the call and thus the ABI decoder will catch the + case of a non-existing contract. -Note that this check is not performed in case of :ref:`low-level calls ` which -operate on addresses rather than contract instances. + This check is not performed in case of :ref:`low-level calls ` which + operate on addresses rather than contract instances. -.. note:: +.. warning:: Be careful when using high-level calls to :ref:`precompiled contracts `, since the compiler considers them non-existing according to the above logic even though they execute code and can return data. +.. note:: + Since the version 0.8.10, the compiler does not check ``extcodesize`` on + high-level external calls if return data is expected, because an empty code + will be unable to return data, and the ABI decoder will revert. + As a consequence, this allows high-level external calls to precompiled + contracts, since they can return data despite having no code + associated with their addresses. + + Read about :ref:`precompiled contracts ` and + :ref:`low-level calls ` + for more information. + Function calls also cause exceptions if the called contract itself throws an exception or goes out of gas. @@ -901,4 +914,4 @@ in scope in the block that follows. out-of-gas situation and not a deliberate error condition: The caller always retains at least 1/64th of the gas in a call and thus even if the called contract goes out of gas, the caller still - has some gas left. + has some gas left. \ No newline at end of file From 8b85d14f7d1e3cbb476434dec2af60c456af7fe4 Mon Sep 17 00:00:00 2001 From: Bilog WEB3 <155262265+Bilogweb3@users.noreply.github.com> Date: Wed, 26 Feb 2025 09:50:31 +0100 Subject: [PATCH 0924/1022] Update custom.css --- docs/_static/css/custom.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/_static/css/custom.css b/docs/_static/css/custom.css index d2c9c86e7b2e..bdfb5ce0bce5 100644 --- a/docs/_static/css/custom.css +++ b/docs/_static/css/custom.css @@ -93,7 +93,7 @@ h1 { } section:first-of-type h1:first-of-type { - font-family: 'Overpass mono', monospace; + font-family: 'Overpass Mono', monospace; font-size: 48px; margin-top: 3rem; margin-bottom: 5rem; From eda68d51fdefd92186bb4390d8b2eaaae2bf7c93 Mon Sep 17 00:00:00 2001 From: PixelPilot <161360836+PixelPil0t1@users.noreply.github.com> Date: Tue, 11 Mar 2025 15:15:18 +0100 Subject: [PATCH 0925/1022] Update events.rst --- docs/contracts/events.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/contracts/events.rst b/docs/contracts/events.rst index 8c73c31603ae..c83970099a65 100644 --- a/docs/contracts/events.rst +++ b/docs/contracts/events.rst @@ -15,7 +15,7 @@ arguments to be stored in the transaction's log - a special data structure in the blockchain. These logs are associated with the address of the contract that emitted them, are incorporated into the blockchain, and stay there as long as a block is accessible (forever as of now, but this might -change in the future). The Log and its event data is not accessible from within +change in the future). The Log and its event data are not accessible from within contracts (not even from the contract that created them). It is possible to request a Merkle proof for logs, so if From feed69b5cac1e9519b881878b6595a2ee893835f Mon Sep 17 00:00:00 2001 From: argentpapa Date: Fri, 28 Feb 2025 01:17:33 +0800 Subject: [PATCH 0926/1022] Update calling_nonexisting_contract.sol --- .../functionCall/eof/calling_nonexisting_contract.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/libsolidity/semanticTests/functionCall/eof/calling_nonexisting_contract.sol b/test/libsolidity/semanticTests/functionCall/eof/calling_nonexisting_contract.sol index 10b39634d5de..a1a53e09d89a 100644 --- a/test/libsolidity/semanticTests/functionCall/eof/calling_nonexisting_contract.sol +++ b/test/libsolidity/semanticTests/functionCall/eof/calling_nonexisting_contract.sol @@ -8,7 +8,7 @@ contract C { function f() public returns (uint256) { // This call throws on legacy bytecode because of calling nonexisting contract. Legacy checks that there is - // a non-empty code under under an address. EOF doesn't do it because non-observability assumption + // a non-empty code under an address. EOF doesn't do it because non-observability assumption d.g(); return 7; } From ba3fd65cfbc2450d538229febf87ea3863230a67 Mon Sep 17 00:00:00 2001 From: Voronor <129545215+voronor@users.noreply.github.com> Date: Tue, 4 Feb 2025 14:23:39 +0100 Subject: [PATCH 0927/1022] docs: Fix grammar in workflow trigger condition --- scripts/docker/buildpack-deps/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/docker/buildpack-deps/README.md b/scripts/docker/buildpack-deps/README.md index 9cfcafd4bf27..6149165c8941 100644 --- a/scripts/docker/buildpack-deps/README.md +++ b/scripts/docker/buildpack-deps/README.md @@ -6,7 +6,7 @@ The `buildpack-deps` docker images are used to compile and test solidity within The creation of the images is triggered by a single workflow, defined in `.github/workflows/buildpack-deps.yml`. For each resulting `buildpack-deps` docker image a strategy is defined in the workflow file - the image variant. -The workflow gets triggered, if any Dockerfile defined in `scripts/docker/buildpack-deps/Dockerfile.*` were changed +The workflow gets triggered, if any Dockerfile defined in `scripts/docker/buildpack-deps/Dockerfile.*` was changed within the PR. ### Versioning From ab77b34e67ae6327f80bdd5098889243b3a86d66 Mon Sep 17 00:00:00 2001 From: emmmm <155267286+eeemmmmmm@users.noreply.github.com> Date: Wed, 26 Feb 2025 09:43:24 +0100 Subject: [PATCH 0928/1022] Update ControlFlowGraphBuilder.h --- libyul/backends/evm/ControlFlowGraphBuilder.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libyul/backends/evm/ControlFlowGraphBuilder.h b/libyul/backends/evm/ControlFlowGraphBuilder.h index 1d0227a56b71..4a2aae98c26f 100644 --- a/libyul/backends/evm/ControlFlowGraphBuilder.h +++ b/libyul/backends/evm/ControlFlowGraphBuilder.h @@ -33,7 +33,7 @@ class ControlFlowGraphBuilder ControlFlowGraphBuilder& operator=(ControlFlowGraphBuilder const&) = delete; static std::unique_ptr build(AsmAnalysisInfo const& _analysisInfo, Dialect const& _dialect, Block const& _block); - StackSlot operator()(Expression const& _literal); + StackSlot operator()(Expression const& _expression); StackSlot operator()(Literal const& _literal); StackSlot operator()(Identifier const& _identifier); StackSlot operator()(FunctionCall const&); From 10b21b89a6c2c8a00ea27706497607d28bb4cf19 Mon Sep 17 00:00:00 2001 From: "ferranmesas@gmx.es" Date: Fri, 28 Feb 2025 22:52:40 +0100 Subject: [PATCH 0929/1022] Replace temporary std::string with std::string_view in _yulname literal to avoid unnecessary allocations --- libyul/YulString.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libyul/YulString.h b/libyul/YulString.h index d6c13f0d3751..329825a4465b 100644 --- a/libyul/YulString.h +++ b/libyul/YulString.h @@ -165,7 +165,7 @@ class YulString inline YulString operator "" _yulname(char const* _string, std::size_t _size) { - return YulString(std::string(_string, _size)); + return YulString(std::string_view(_string, _size)); } } From 771d8052df8947f781d126fea349734344941a3c Mon Sep 17 00:00:00 2001 From: NeoByteX <160131789+NeoByteXx@users.noreply.github.com> Date: Sat, 22 Feb 2025 08:33:10 +0100 Subject: [PATCH 0930/1022] Fix typo in test script comments --- test/externalTests/brink.sh | 2 +- test/externalTests/elementfi.sh | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/test/externalTests/brink.sh b/test/externalTests/brink.sh index 02e5fe971c65..e541481b43ae 100755 --- a/test/externalTests/brink.sh +++ b/test/externalTests/brink.sh @@ -61,7 +61,7 @@ function brink_test setup_solc "$DIR" "$BINARY_TYPE" "$BINARY_PATH" download_project "$repo" "$ref" "$DIR" - # TODO: Remove this when Brink merges https://github.com/brinktrade/brink-core/pull/52 + # TODO: Remove this once Brink merges PR #52 (https://github.com/brinktrade/brink-core/pull/52). sed -i "s|\(function isValidSignature(bytes \)calldata\( _data, bytes \)calldata\( _signature)\)|\1memory\2memory\3|g" src/Test/MockEIP1271Validator.sol neutralize_package_lock diff --git a/test/externalTests/elementfi.sh b/test/externalTests/elementfi.sh index f34a169e9512..aa73ea768740 100755 --- a/test/externalTests/elementfi.sh +++ b/test/externalTests/elementfi.sh @@ -93,8 +93,8 @@ function elementfi_test sed -i 's|it(\("should prevent withdrawal of Principal Tokens and Interest Tokens before the tranche expires "\)|it.skip(\1|g' test/trancheTest.ts sed -i 's|it(\("should prevent withdrawal of more Principal Tokens and Interest Tokens than the user has"\)|it.skip(\1|g' test/trancheTest.ts - # This test file is very flaky. There's one particular cases that fails randomly (see - # https://github.com/element-fi/elf-contracts/issues/240) but some others also depends on an external + # This test file is very flaky. There's one particular case that fails randomly (see + # https://github.com/element-fi/elf-contracts/issues/240) but some others also depend on an external # service which makes tests time out when that service is down. # "ProviderError: Too Many Requests error received from eth-mainnet.alchemyapi.io" rm test/mockERC20YearnVaultTest.ts From d22a07012e03cd3a942235aa166f00f0c000dcdb Mon Sep 17 00:00:00 2001 From: Skylar Ray <137945430+sky-coderay@users.noreply.github.com> Date: Fri, 14 Mar 2025 10:08:33 +0200 Subject: [PATCH 0931/1022] fix minor issues Update DataFlowAnalyzer.cpp Update CommonSubexpressionEliminator.cpp /*( -deleted ( --- libyul/CompilabilityChecker.cpp | 2 +- libyul/optimiser/CommonSubexpressionEliminator.cpp | 2 +- libyul/optimiser/DataFlowAnalyzer.cpp | 2 +- libyul/optimiser/Metrics.cpp | 2 +- libyul/optimiser/Rematerialiser.cpp | 2 +- libyul/optimiser/StackCompressor.cpp | 2 +- libyul/optimiser/SyntacticalEquality.cpp | 2 +- libyul/optimiser/UnusedPruner.cpp | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/libyul/CompilabilityChecker.cpp b/libyul/CompilabilityChecker.cpp index cc46ecb77000..2df14f211939 100644 --- a/libyul/CompilabilityChecker.cpp +++ b/libyul/CompilabilityChecker.cpp @@ -1,4 +1,4 @@ -/*( +/* This file is part of solidity. solidity is free software: you can redistribute it and/or modify diff --git a/libyul/optimiser/CommonSubexpressionEliminator.cpp b/libyul/optimiser/CommonSubexpressionEliminator.cpp index 87a14d259070..1a6f3911a1bb 100644 --- a/libyul/optimiser/CommonSubexpressionEliminator.cpp +++ b/libyul/optimiser/CommonSubexpressionEliminator.cpp @@ -1,4 +1,4 @@ -/*( +/* This file is part of solidity. solidity is free software: you can redistribute it and/or modify diff --git a/libyul/optimiser/DataFlowAnalyzer.cpp b/libyul/optimiser/DataFlowAnalyzer.cpp index 2407781354d0..1aecd6bd4a91 100644 --- a/libyul/optimiser/DataFlowAnalyzer.cpp +++ b/libyul/optimiser/DataFlowAnalyzer.cpp @@ -1,4 +1,4 @@ -/*( +/* This file is part of solidity. solidity is free software: you can redistribute it and/or modify diff --git a/libyul/optimiser/Metrics.cpp b/libyul/optimiser/Metrics.cpp index 04bfe9a7a06d..5c3a624269d5 100644 --- a/libyul/optimiser/Metrics.cpp +++ b/libyul/optimiser/Metrics.cpp @@ -1,4 +1,4 @@ -/*( +/* This file is part of solidity. solidity is free software: you can redistribute it and/or modify diff --git a/libyul/optimiser/Rematerialiser.cpp b/libyul/optimiser/Rematerialiser.cpp index bfcd9d8f630f..1d3535fdae82 100644 --- a/libyul/optimiser/Rematerialiser.cpp +++ b/libyul/optimiser/Rematerialiser.cpp @@ -1,4 +1,4 @@ -/*( +/* This file is part of solidity. solidity is free software: you can redistribute it and/or modify diff --git a/libyul/optimiser/StackCompressor.cpp b/libyul/optimiser/StackCompressor.cpp index 97d2c054700d..b0be60d63442 100644 --- a/libyul/optimiser/StackCompressor.cpp +++ b/libyul/optimiser/StackCompressor.cpp @@ -1,4 +1,4 @@ -/*( +/* This file is part of solidity. solidity is free software: you can redistribute it and/or modify diff --git a/libyul/optimiser/SyntacticalEquality.cpp b/libyul/optimiser/SyntacticalEquality.cpp index e233b57e9e2d..a032e912be63 100644 --- a/libyul/optimiser/SyntacticalEquality.cpp +++ b/libyul/optimiser/SyntacticalEquality.cpp @@ -1,4 +1,4 @@ -/*( +/* This file is part of solidity. solidity is free software: you can redistribute it and/or modify diff --git a/libyul/optimiser/UnusedPruner.cpp b/libyul/optimiser/UnusedPruner.cpp index 5d50e4599bfd..2f982b164093 100644 --- a/libyul/optimiser/UnusedPruner.cpp +++ b/libyul/optimiser/UnusedPruner.cpp @@ -1,4 +1,4 @@ -/*( +/* This file is part of solidity. solidity is free software: you can redistribute it and/or modify From a7ac67cc8f19aed11c9fad10e861a2c318608438 Mon Sep 17 00:00:00 2001 From: Tomass <155266802+zeroprooff@users.noreply.github.com> Date: Thu, 17 Apr 2025 23:09:46 +0200 Subject: [PATCH 0932/1022] fix duplicate EVMHost.cpp --- test/EVMHost.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/EVMHost.cpp b/test/EVMHost.cpp index 983615312efd..6f64b703b0b5 100644 --- a/test/EVMHost.cpp +++ b/test/EVMHost.cpp @@ -399,7 +399,7 @@ evmc::Result EVMHost::call(evmc_message const& _message) noexcept transfer(sender, destination, value); } - // Populate the access access list (enabled since Berlin). + // Populate the access list (enabled since Berlin). // Note, this will also properly touch the created address. // TODO: support a user supplied access list too if (m_evmRevision >= EVMC_BERLIN) From 02d2c9af23c830667ccbce4e581357a163615dea Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Wed, 9 Apr 2025 13:54:18 +0200 Subject: [PATCH 0933/1022] change into test dir for cmdline tests --- test/cmdlineTests.sh | 45 ++++++++++++++++++++++++-------------------- 1 file changed, 25 insertions(+), 20 deletions(-) diff --git a/test/cmdlineTests.sh b/test/cmdlineTests.sh index f68ed53dc066..b3327ea988c8 100755 --- a/test/cmdlineTests.sh +++ b/test/cmdlineTests.sh @@ -225,7 +225,7 @@ EOF if jq 'has("ethdebug")' "$stdout_path" --exit-status > /dev/null; then local temporary_file temporary_file=$(mktemp -t cmdline-ethdebug-XXXXXX.tmp) - if [[ -e ${tdir}/strip-ethdebug ]]; then + if [[ -e strip-ethdebug ]]; then jq --indent 4 ' (. | .. | objects | select(has("ethdebug"))) |= (.ethdebug = "") ' "$stdout_path" > "$temporary_file" @@ -350,9 +350,11 @@ test_solc_behaviour "${0}" "ctx:=/some/remapping/target" "" "" 1 "" "Error: Inva printTask "Running general commandline tests..." ( - cd "$REPO_ROOT"/test/cmdlineTests/ for tdir in "${selected_tests[@]}" do + # go back to the test root dir + cd "$REPO_ROOT"/test/cmdlineTests/ + if ! [[ -d $tdir ]] then fail "Test directory not found: $tdir" @@ -377,10 +379,13 @@ printTask "Running general commandline tests..." fi fi - scriptFiles="$(ls -1 "${tdir}/test."* 2> /dev/null || true)" + # jump into test dir + cd "${tdir}" + + scriptFiles="$(ls -1 "test."* 2> /dev/null || true)" scriptCount="$(echo "${scriptFiles}" | wc -w)" - inputFiles="$(ls -1 "${tdir}/input."* 2> /dev/null || true)" + inputFiles="$(ls -1 "input."* 2> /dev/null || true)" inputCount="$(echo "${inputFiles}" | wc -w)" (( inputCount <= 1 )) || fail "Ambiguous input. Found input files in multiple formats:"$'\n'"${inputFiles}" (( scriptCount <= 1 )) || fail "Ambiguous input. Found script files in multiple formats:"$'\n'"${scriptFiles}" @@ -388,7 +393,7 @@ printTask "Running general commandline tests..." if (( scriptCount == 1 )) then - if ! "$scriptFiles" + if ! "./$scriptFiles" then fail "Test script ${scriptFiles} failed." fi @@ -399,38 +404,38 @@ printTask "Running general commandline tests..." # Use printf to get rid of the trailing newline inputFile=$(printf "%s" "${inputFiles}") - if [ "${inputFile}" = "${tdir}/input.json" ] + if [ "${inputFile}" = "input.json" ] then - ! [ -e "${tdir}/stdin" ] || fail "Found a file called 'stdin' but redirecting standard input in JSON mode is not allowed." + ! [ -e "stdin" ] || fail "Found a file called 'stdin' but redirecting standard input in JSON mode is not allowed." stdin="${inputFile}" inputFile="" - stdout="$(cat "${tdir}/output.json" 2>/dev/null || true)" - stdoutExpectationFile="${tdir}/output.json" + stdout="$(cat "output.json" 2>/dev/null || true)" + stdoutExpectationFile="output.json" prettyPrintFlags="" - if [[ ! -f "${tdir}/no-pretty-print" ]] + if [[ ! -f "no-pretty-print" ]] then prettyPrintFlags="--pretty-json --json-indent 4" fi - command_args="--standard-json ${prettyPrintFlags} "$(cat "${tdir}/args" 2>/dev/null || true) + command_args="--standard-json ${prettyPrintFlags} "$(cat "args" 2>/dev/null || true) else - if [ -e "${tdir}/stdin" ] + if [ -e "stdin" ] then - stdin="${tdir}/stdin" - [ -f "${tdir}/stdin" ] || fail "'stdin' is not a regular file." + stdin="stdin" + [ -f "stdin" ] || fail "'stdin' is not a regular file." else stdin="" fi - stdout="$(cat "${tdir}/output" 2>/dev/null || true)" - stdoutExpectationFile="${tdir}/output" - command_args=$(cat "${tdir}/args" 2>/dev/null || true) + stdout="$(cat "output" 2>/dev/null || true)" + stdoutExpectationFile="output" + command_args=$(cat "args" 2>/dev/null || true) fi - exitCodeExpectationFile="${tdir}/exit" + exitCodeExpectationFile="exit" exitCode=$(cat "$exitCodeExpectationFile" 2>/dev/null || true) - err="$(cat "${tdir}/err" 2>/dev/null || true)" - stderrExpectationFile="${tdir}/err" + err="$(cat "err" 2>/dev/null || true)" + stderrExpectationFile="err" test_solc_behaviour "$inputFile" \ "$command_args" \ "$stdin" \ From 2fa170efc1517f1ddc82c24d015c95d82f4c1534 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Thu, 10 Apr 2025 15:26:42 +0200 Subject: [PATCH 0934/1022] update test expectations with cwd being in test dir --- test/cmdlineTests/abi_via_ir/output | 4 +- .../abiencoderv2_no_warning/output | 2 +- test/cmdlineTests/asm_json/output | 4 +- .../asm_json_no_pretty_print/output | 4 +- .../ast_compact_json_no_pretty_json/output | 4 +- .../output | 4 +- .../ast_compact_json_with_base_path/output | 10 +- test/cmdlineTests/ast_ir/output | 276 +++++++++--------- test/cmdlineTests/combined_json_abi/output | 2 +- .../combined_json_generated_sources/output | 2 +- .../combined_json_no_pretty_print/output | 2 +- .../combined_json_stop_after_parsing/output | 8 +- .../combined_json_with_base_path/output | 16 +- .../combined_json_with_devdoc/output | 4 +- .../combined_json_with_userdoc/output | 4 +- .../constant_optimizer_yul/output | 4 +- .../output | 16 +- .../output | 16 +- .../output | 10 +- .../debug_info_in_yul_snippet_escaping/output | 24 +- test/cmdlineTests/dup_opt_peephole/output | 18 +- test/cmdlineTests/error_codes/err | 12 +- .../ethdebug_eof_container_osaka/output | 4 +- test/cmdlineTests/events_in_abi/output | 4 +- test/cmdlineTests/evm_version_byzantium/err | 2 +- .../evm_version_constantinople/err | 2 +- .../evmasm_difficulty_post_paris/err | 2 +- .../evmasm_difficulty_post_paris/output | 2 +- .../evmasm_difficulty_pre_paris/output | 2 +- .../evmasm_prevrandao_post_paris/output | 2 +- .../evmasm_prevrandao_pre_paris/err | 2 +- .../evmasm_prevrandao_pre_paris/output | 2 +- .../err | 2 +- .../output | 2 +- .../err | 2 +- .../output | 2 +- .../output | 2 +- .../output | 2 +- test/cmdlineTests/exp_base_literal/output | 4 +- test/cmdlineTests/function_debug_info/output | 2 +- .../function_debug_info_via_yul/output | 2 +- test/cmdlineTests/hashes/output | 4 +- .../inline_assembly_function_name_clash/err | 4 +- .../output | 2 +- .../output | 8 +- test/cmdlineTests/ir_compiler_subobjects/err | 2 +- .../ir_compiler_subobjects/output | 12 +- .../output | 4 +- .../ir_optimized_with_optimize/output | 4 +- test/cmdlineTests/ir_subobject_order/output | 20 +- .../ir_unoptimized_with_optimize/output | 4 +- .../output | 4 +- .../output | 4 +- .../output | 4 +- .../keccak_optimization_deploy_code/output | 4 +- .../keccak_optimization_low_runs/output | 4 +- .../linking_qualified_library_name/args | 2 +- .../contract1.sol | 2 +- .../linking_qualified_library_name/output | 4 +- test/cmdlineTests/linking_solidity/args | 2 +- test/cmdlineTests/linking_solidity/output | 4 +- .../args | 2 +- .../output | 18 +- .../linking_strict_assembly/output | 10 +- .../output | 2 +- .../output | 2 +- .../output | 18 +- .../output | 18 +- .../output | 2 +- .../output | 2 +- .../output | 18 +- .../linking_unqualified_library_name/args | 2 +- .../contract1.sol | 2 +- .../contract2.sol | 2 +- .../linking_unqualified_library_name/output | 16 +- .../mcopy_bytes_array_abi_decode/err | 2 +- .../mcopy_bytes_array_abi_decode/output | 4 +- .../output | 4 +- .../output | 4 +- .../output | 4 +- test/cmdlineTests/message_format/err | 18 +- test/cmdlineTests/message_format_utf8/err | 10 +- test/cmdlineTests/metadata/output | 4 +- .../model_checker_bmc_loop_iterations/err | 2 +- .../err | 2 +- .../model_checker_contracts_all/err | 4 +- .../model_checker_contracts_all_explicit/args | 2 +- .../model_checker_contracts_all_explicit/err | 4 +- .../args | 2 +- .../err | 2 +- .../args | 2 +- .../err | 2 +- .../args | 2 +- .../err | 2 +- .../model_checker_contracts_only_one/args | 2 +- .../model_checker_contracts_only_one/err | 4 +- .../cmdlineTests/model_checker_engine_all/err | 2 +- .../cmdlineTests/model_checker_engine_bmc/err | 2 +- .../cmdlineTests/model_checker_engine_chc/err | 2 +- .../model_checker_ext_calls_trusted_chc/err | 2 +- .../model_checker_ext_calls_untrusted_chc/err | 2 +- .../model_checker_invariants_all/err | 4 +- .../model_checker_invariants_contract/err | 2 +- .../model_checker_invariants_contract_eld/err | 2 +- .../err | 4 +- .../model_checker_invariants_reentrancy/err | 2 +- .../err | 2 +- .../err | 2 +- .../err | 2 +- .../err | 6 +- .../err | 6 +- .../err | 6 +- .../err | 2 +- .../model_checker_show_unproved_true_chc/err | 2 +- .../err | 2 +- .../err | 2 +- .../err | 2 +- .../model_checker_solvers_cvc5/err | 2 +- .../model_checker_solvers_cvc5_eld/err | 2 +- .../model_checker_solvers_eld/err | 2 +- .../cmdlineTests/model_checker_solvers_z3/err | 2 +- .../model_checker_solvers_z3_implicit/err | 2 +- .../model_checker_solvers_z3_smtlib2/err | 2 +- .../model_checker_targets_all_all_engines/err | 14 +- .../model_checker_targets_all_bmc/err | 12 +- .../model_checker_targets_all_chc/err | 12 +- .../model_checker_targets_assert_bmc/err | 2 +- .../model_checker_targets_assert_chc/err | 2 +- .../model_checker_targets_balance_bmc/err | 2 +- .../err | 2 +- .../err | 10 +- .../model_checker_targets_default_bmc/err | 8 +- .../model_checker_targets_default_chc/err | 8 +- .../model_checker_targets_div_by_zero_bmc/err | 2 +- .../model_checker_targets_div_by_zero_chc/err | 2 +- .../err | 2 +- .../model_checker_targets_overflow_bmc/err | 2 +- .../model_checker_targets_overflow_chc/err | 2 +- .../model_checker_targets_pop_empty_chc/err | 2 +- .../model_checker_targets_underflow_bmc/err | 2 +- .../model_checker_targets_underflow_chc/err | 2 +- .../err | 6 +- .../err | 6 +- .../err | 4 +- .../err | 4 +- test/cmdlineTests/name_simplifier/output | 4 +- test/cmdlineTests/no_cbor_metadata/output | 2 +- .../no_contract_combined_json/output | 6 +- test/cmdlineTests/no_import_callback/args | 2 +- test/cmdlineTests/no_import_callback/err | 2 +- test/cmdlineTests/object_compiler/output | 34 +-- .../optimize_full_storage_write/output | 16 +- .../optimizer_BlockDeDuplicator/err | 4 +- .../optimizer_BlockDeDuplicator/output | 20 +- .../cmdlineTests/optimizer_array_sload/output | 4 +- .../cmdlineTests/optimizer_inliner_add/output | 30 +- .../output | 24 +- .../output | 58 ++-- .../output | 66 ++--- .../cmdlineTests/optimizer_inliner_inc/output | 28 +- .../optimizer_inliner_multireturn/output | 30 +- test/cmdlineTests/optimizer_user_yul/output | 56 ++-- test/cmdlineTests/require_overload/err | 2 +- .../cmdlineTests/require_with_error_ir/output | 4 +- .../require_with_string_ir/output | 4 +- test/cmdlineTests/revert_strings/output | 4 +- .../stack_too_deep_from_code_transform/err | 2 +- .../input.json | 2 +- .../input.json | 2 +- .../input.json | 2 +- .../input.json | 2 +- .../input.json | 2 +- .../standard_ir_ast_requested/input.json | 2 +- .../cmdlineTests/standard_metadata/input.json | 2 +- .../input.json | 2 +- .../input.json | 2 +- .../standard_optimizer_no_yul/input.json | 2 +- .../standard_optimizer_yul/input.json | 2 +- .../standard_optimizer_yulDetails/input.json | 2 +- .../input.json | 2 +- .../input.json | 2 +- .../input.json | 2 +- .../input.json | 2 +- .../input.json | 2 +- .../input.json | 2 +- .../input.json | 2 +- .../input.json | 2 +- .../input.json | 2 +- .../input.json | 2 +- .../input.json | 2 +- .../input.json | 2 +- .../input.json | 2 +- .../input.json | 2 +- .../input.json | 2 +- .../input.json | 2 +- .../input.json | 2 +- .../input.json | 2 +- .../input.json | 2 +- .../input.json | 2 +- .../input.json | 2 +- .../input.json | 2 +- .../input.json | 2 +- .../input.json | 2 +- .../input.json | 2 +- .../input.json | 2 +- .../input.json | 2 +- .../input.json | 2 +- .../input.json | 6 +- .../output.json | 4 +- .../standard_urls_missing/input.json | 6 +- .../standard_urls_missing/output.json | 12 +- .../standard_yul_cfg_json_export/input.json | 2 +- .../input.json | 2 +- .../input.json | 2 +- .../input.json | 2 +- .../input.json | 2 +- .../input.json | 2 +- .../input.json | 2 +- .../input.json | 2 +- .../input.json | 2 +- .../input.json | 2 +- .../input.json | 2 +- .../input.json | 2 +- .../input.json | 2 +- .../input.json | 2 +- .../standard_yul_ethdebug_ir/input.json | 2 +- .../input.json | 2 +- .../input.json | 2 +- .../input.json | 2 +- .../stop_after_parsing_ast/output | 4 +- .../input.json | 2 +- .../storage_layout_user_defined/err | 2 +- .../storage_layout_user_defined/output | 18 +- .../output | 2 +- .../strict_asm_ast_compact_json/output | 2 +- .../strict_asm_debug_info_print_all/output | 2 +- .../output | 2 +- .../strict_asm_debug_info_print_none/output | 2 +- .../strict_asm_eof_container_osaka/output | 2 +- .../strict_asm_eof_dataloadn_osaka/output | 2 +- .../strict_asm_evm_version_byzantium/output | 4 +- .../output | 4 +- test/cmdlineTests/strict_asm_jump/err | 2 +- .../strict_asm_msize_with_optimizer/output | 2 +- .../strict_asm_msize_without_optimizer/output | 2 +- test/cmdlineTests/strict_asm_only_cr/err | 2 +- .../strict_asm_optimizer_steps/output | 50 ++-- .../output | 10 +- .../output | 2 +- .../output | 2 +- test/cmdlineTests/strict_asm_warning/err | 2 +- test/cmdlineTests/strict_asm_warning/output | 2 +- .../strict_asm_warning_and_error_optimize/err | 4 +- .../strict_asm_warning_optimize/err | 2 +- .../strict_asm_warning_optimize/output | 2 +- .../err | 2 +- .../output | 2 +- .../strict_asm_yul_cfg_json_export/output | 2 +- .../err | 4 +- test/cmdlineTests/too_long_line/err | 2 +- .../too_long_line_both_sides_short/err | 2 +- test/cmdlineTests/too_long_line_edge_in/err | 2 +- test/cmdlineTests/too_long_line_edge_out/err | 2 +- .../cmdlineTests/too_long_line_left_short/err | 2 +- test/cmdlineTests/too_long_line_multiline/err | 2 +- .../too_long_line_right_short/err | 2 +- .../transient_storage_layout/output | 12 +- .../input.json | 2 +- .../input.json | 2 +- .../input.json | 2 +- .../output | 4 +- test/cmdlineTests/viair_abicoder_v1/err | 2 +- test/cmdlineTests/viair_abicoder_v1/output | 4 +- .../viair_msize_without_optimizer/output | 6 +- .../viair_subobject_optimization/output | 56 ++-- test/cmdlineTests/viair_subobjects/err | 2 +- test/cmdlineTests/viair_subobjects/output | 16 +- test/cmdlineTests/yul_cfg_json_export/output | 6 +- .../yul_function_name_clashes/output | 2 +- .../output | 28 +- test/cmdlineTests/yul_optimize_runs/output | 22 +- .../output | 4 +- test/cmdlineTests/yul_optimizer_steps/output | 4 +- .../output | 4 +- .../yul_optimizer_steps_short_sequence/output | 4 +- .../output | 4 +- .../output | 4 +- .../err | 4 +- .../output | 8 +- test/cmdlineTests/yul_verbatim/output | 34 +-- test/cmdlineTests/yul_verbatim_msize/output | 18 +- 291 files changed, 959 insertions(+), 959 deletions(-) diff --git a/test/cmdlineTests/abi_via_ir/output b/test/cmdlineTests/abi_via_ir/output index 56ba01a4a248..3b3fec68d93b 100644 --- a/test/cmdlineTests/abi_via_ir/output +++ b/test/cmdlineTests/abi_via_ir/output @@ -1,5 +1,5 @@ -======= abi_via_ir/input.sol:C ======= +======= input.sol:C ======= Contract JSON ABI [ { @@ -101,7 +101,7 @@ Contract JSON ABI } ] -======= abi_via_ir/input.sol:L ======= +======= input.sol:L ======= Contract JSON ABI [ { diff --git a/test/cmdlineTests/abiencoderv2_no_warning/output b/test/cmdlineTests/abiencoderv2_no_warning/output index 33f8d2e1fa8f..5b99567cc0fb 100644 --- a/test/cmdlineTests/abiencoderv2_no_warning/output +++ b/test/cmdlineTests/abiencoderv2_no_warning/output @@ -1,4 +1,4 @@ -======= abiencoderv2_no_warning/input.sol:C ======= +======= input.sol:C ======= Function signatures: 3fc03eeb: f((uint256)) diff --git a/test/cmdlineTests/asm_json/output b/test/cmdlineTests/asm_json/output index 820eda6ec4a6..a148e42f0ca7 100644 --- a/test/cmdlineTests/asm_json/output +++ b/test/cmdlineTests/asm_json/output @@ -1,5 +1,5 @@ -======= asm_json/input.sol:C ======= +======= input.sol:C ======= EVM assembly: { ".code": [ @@ -1573,7 +1573,7 @@ EVM assembly: } }, "sourceList": [ - "asm_json/input.sol", + "input.sol", "#utility.yul" ] } diff --git a/test/cmdlineTests/asm_json_no_pretty_print/output b/test/cmdlineTests/asm_json_no_pretty_print/output index 8fce2f4827d9..b2382e1866b5 100644 --- a/test/cmdlineTests/asm_json_no_pretty_print/output +++ b/test/cmdlineTests/asm_json_no_pretty_print/output @@ -1,4 +1,4 @@ -======= asm_json_no_pretty_print/input.sol:C ======= +======= input.sol:C ======= EVM assembly: -{".code":[{"begin":60,"end":160,"name":"PUSH","source":0,"value":"80"},{"begin":60,"end":160,"name":"PUSH","source":0,"value":"40"},{"begin":60,"end":160,"name":"MSTORE","source":0},{"begin":60,"end":160,"name":"CALLVALUE","source":0},{"begin":60,"end":160,"name":"DUP1","source":0},{"begin":60,"end":160,"name":"ISZERO","source":0},{"begin":60,"end":160,"name":"PUSH [tag]","source":0,"value":"1"},{"begin":60,"end":160,"name":"JUMPI","source":0},{"begin":60,"end":160,"name":"PUSH","source":0,"value":"0"},{"begin":60,"end":160,"name":"PUSH","source":0,"value":"0"},{"begin":60,"end":160,"name":"REVERT","source":0},{"begin":60,"end":160,"name":"tag","source":0,"value":"1"},{"begin":60,"end":160,"name":"JUMPDEST","source":0},{"begin":60,"end":160,"name":"POP","source":0},{"begin":60,"end":160,"name":"PUSH #[$]","source":0,"value":"0000000000000000000000000000000000000000000000000000000000000000"},{"begin":60,"end":160,"name":"DUP1","source":0},{"begin":60,"end":160,"name":"PUSH [$]","source":0,"value":"0000000000000000000000000000000000000000000000000000000000000000"},{"begin":60,"end":160,"name":"PUSH","source":0,"value":"0"},{"begin":60,"end":160,"name":"CODECOPY","source":0},{"begin":60,"end":160,"name":"PUSH","source":0,"value":"0"},{"begin":60,"end":160,"name":"RETURN","source":0}],".data":{"0":{".auxdata":"",".code":[{"begin":60,"end":160,"name":"PUSH","source":0,"value":"80"},{"begin":60,"end":160,"name":"PUSH","source":0,"value":"40"},{"begin":60,"end":160,"name":"MSTORE","source":0},{"begin":60,"end":160,"name":"CALLVALUE","source":0},{"begin":60,"end":160,"name":"DUP1","source":0},{"begin":60,"end":160,"name":"ISZERO","source":0},{"begin":60,"end":160,"name":"PUSH [tag]","source":0,"value":"1"},{"begin":60,"end":160,"name":"JUMPI","source":0},{"begin":60,"end":160,"name":"PUSH","source":0,"value":"0"},{"begin":60,"end":160,"name":"PUSH","source":0,"value":"0"},{"begin":60,"end":160,"name":"REVERT","source":0},{"begin":60,"end":160,"name":"tag","source":0,"value":"1"},{"begin":60,"end":160,"name":"JUMPDEST","source":0},{"begin":60,"end":160,"name":"POP","source":0},{"begin":60,"end":160,"name":"PUSH","source":0,"value":"4"},{"begin":60,"end":160,"name":"CALLDATASIZE","source":0},{"begin":60,"end":160,"name":"LT","source":0},{"begin":60,"end":160,"name":"PUSH [tag]","source":0,"value":"2"},{"begin":60,"end":160,"name":"JUMPI","source":0},{"begin":60,"end":160,"name":"PUSH","source":0,"value":"0"},{"begin":60,"end":160,"name":"CALLDATALOAD","source":0},{"begin":60,"end":160,"name":"PUSH","source":0,"value":"E0"},{"begin":60,"end":160,"name":"SHR","source":0},{"begin":60,"end":160,"name":"DUP1","source":0},{"begin":60,"end":160,"name":"PUSH","source":0,"value":"B3DE648B"},{"begin":60,"end":160,"name":"EQ","source":0},{"begin":60,"end":160,"name":"PUSH [tag]","source":0,"value":"3"},{"begin":60,"end":160,"name":"JUMPI","source":0},{"begin":60,"end":160,"name":"tag","source":0,"value":"2"},{"begin":60,"end":160,"name":"JUMPDEST","source":0},{"begin":60,"end":160,"name":"PUSH","source":0,"value":"0"},{"begin":60,"end":160,"name":"PUSH","source":0,"value":"0"},{"begin":60,"end":160,"name":"REVERT","source":0},{"begin":77,"end":158,"name":"tag","source":0,"value":"3"},{"begin":77,"end":158,"name":"JUMPDEST","source":0},{"begin":77,"end":158,"name":"PUSH [tag]","source":0,"value":"4"},{"begin":77,"end":158,"name":"PUSH","source":0,"value":"4"},{"begin":77,"end":158,"name":"DUP1","source":0},{"begin":77,"end":158,"name":"CALLDATASIZE","source":0},{"begin":77,"end":158,"name":"SUB","source":0},{"begin":77,"end":158,"name":"DUP2","source":0},{"begin":77,"end":158,"name":"ADD","source":0},{"begin":77,"end":158,"name":"SWAP1","source":0},{"begin":77,"end":158,"name":"PUSH [tag]","source":0,"value":"5"},{"begin":77,"end":158,"name":"SWAP2","source":0},{"begin":77,"end":158,"name":"SWAP1","source":0},{"begin":77,"end":158,"name":"PUSH [tag]","source":0,"value":"6"},{"begin":77,"end":158,"jumpType":"[in]","name":"JUMP","source":0},{"begin":77,"end":158,"name":"tag","source":0,"value":"5"},{"begin":77,"end":158,"name":"JUMPDEST","source":0},{"begin":77,"end":158,"name":"PUSH [tag]","source":0,"value":"7"},{"begin":77,"end":158,"jumpType":"[in]","name":"JUMP","source":0},{"begin":77,"end":158,"name":"tag","source":0,"value":"4"},{"begin":77,"end":158,"name":"JUMPDEST","source":0},{"begin":77,"end":158,"name":"STOP","source":0},{"begin":77,"end":158,"name":"tag","source":0,"value":"7"},{"begin":77,"end":158,"name":"JUMPDEST","source":0},{"begin":123,"end":125,"name":"PUSH","source":0,"value":"2A"},{"begin":118,"end":125,"name":"DUP2","source":0},{"begin":118,"end":125,"name":"PUSH [tag]","source":0,"value":"9"},{"begin":118,"end":125,"name":"SWAP2","source":0},{"begin":118,"end":125,"name":"SWAP1","source":0},{"begin":118,"end":125,"name":"PUSH [tag]","source":0,"value":"10"},{"begin":118,"end":125,"jumpType":"[in]","name":"JUMP","source":0},{"begin":118,"end":125,"name":"tag","source":0,"value":"9"},{"begin":118,"end":125,"name":"JUMPDEST","source":0},{"begin":118,"end":125,"name":"SWAP1","source":0},{"begin":118,"end":125,"name":"POP","source":0},{"begin":147,"end":150,"name":"PUSH","source":0,"value":"64"},{"begin":143,"end":144,"name":"DUP2","source":0},{"begin":143,"end":150,"name":"GT","source":0},{"begin":135,"end":151,"name":"PUSH [tag]","source":0,"value":"11"},{"begin":135,"end":151,"name":"JUMPI","source":0},{"begin":135,"end":151,"name":"PUSH","source":0,"value":"0"},{"begin":135,"end":151,"name":"PUSH","source":0,"value":"0"},{"begin":135,"end":151,"name":"REVERT","source":0},{"begin":135,"end":151,"name":"tag","source":0,"value":"11"},{"begin":135,"end":151,"name":"JUMPDEST","source":0},{"begin":77,"end":158,"name":"POP","source":0},{"begin":77,"end":158,"jumpType":"[out]","name":"JUMP","source":0},{"begin":88,"end":205,"name":"tag","source":1,"value":"13"},{"begin":88,"end":205,"name":"JUMPDEST","source":1},{"begin":197,"end":198,"name":"PUSH","source":1,"value":"0"},{"begin":194,"end":195,"name":"PUSH","source":1,"value":"0"},{"begin":187,"end":199,"name":"REVERT","source":1},{"begin":334,"end":411,"name":"tag","source":1,"value":"15"},{"begin":334,"end":411,"name":"JUMPDEST","source":1},{"begin":371,"end":378,"name":"PUSH","source":1,"value":"0"},{"begin":400,"end":405,"name":"DUP2","source":1},{"begin":389,"end":405,"name":"SWAP1","source":1},{"begin":389,"end":405,"name":"POP","source":1},{"begin":334,"end":411,"name":"SWAP2","source":1},{"begin":334,"end":411,"name":"SWAP1","source":1},{"begin":334,"end":411,"name":"POP","source":1},{"begin":334,"end":411,"jumpType":"[out]","name":"JUMP","source":1},{"begin":417,"end":539,"name":"tag","source":1,"value":"16"},{"begin":417,"end":539,"name":"JUMPDEST","source":1},{"begin":490,"end":514,"name":"PUSH [tag]","source":1,"value":"25"},{"begin":508,"end":513,"name":"DUP2","source":1},{"begin":490,"end":514,"name":"PUSH [tag]","source":1,"value":"15"},{"begin":490,"end":514,"jumpType":"[in]","name":"JUMP","source":1},{"begin":490,"end":514,"name":"tag","source":1,"value":"25"},{"begin":490,"end":514,"name":"JUMPDEST","source":1},{"begin":483,"end":488,"name":"DUP2","source":1},{"begin":480,"end":515,"name":"EQ","source":1},{"begin":470,"end":533,"name":"PUSH [tag]","source":1,"value":"26"},{"begin":470,"end":533,"name":"JUMPI","source":1},{"begin":529,"end":530,"name":"PUSH","source":1,"value":"0"},{"begin":526,"end":527,"name":"PUSH","source":1,"value":"0"},{"begin":519,"end":531,"name":"REVERT","source":1},{"begin":470,"end":533,"name":"tag","source":1,"value":"26"},{"begin":470,"end":533,"name":"JUMPDEST","source":1},{"begin":417,"end":539,"name":"POP","source":1},{"begin":417,"end":539,"jumpType":"[out]","name":"JUMP","source":1},{"begin":545,"end":684,"name":"tag","source":1,"value":"17"},{"begin":545,"end":684,"name":"JUMPDEST","source":1},{"begin":591,"end":596,"name":"PUSH","source":1,"value":"0"},{"begin":629,"end":635,"name":"DUP2","source":1},{"begin":616,"end":636,"name":"CALLDATALOAD","source":1},{"begin":607,"end":636,"name":"SWAP1","source":1},{"begin":607,"end":636,"name":"POP","source":1},{"begin":645,"end":678,"name":"PUSH [tag]","source":1,"value":"28"},{"begin":672,"end":677,"name":"DUP2","source":1},{"begin":645,"end":678,"name":"PUSH [tag]","source":1,"value":"16"},{"begin":645,"end":678,"jumpType":"[in]","name":"JUMP","source":1},{"begin":645,"end":678,"name":"tag","source":1,"value":"28"},{"begin":645,"end":678,"name":"JUMPDEST","source":1},{"begin":545,"end":684,"name":"SWAP3","source":1},{"begin":545,"end":684,"name":"SWAP2","source":1},{"begin":545,"end":684,"name":"POP","source":1},{"begin":545,"end":684,"name":"POP","source":1},{"begin":545,"end":684,"jumpType":"[out]","name":"JUMP","source":1},{"begin":690,"end":1019,"name":"tag","source":1,"value":"6"},{"begin":690,"end":1019,"name":"JUMPDEST","source":1},{"begin":749,"end":755,"name":"PUSH","source":1,"value":"0"},{"begin":798,"end":800,"name":"PUSH","source":1,"value":"20"},{"begin":786,"end":795,"name":"DUP3","source":1},{"begin":777,"end":784,"name":"DUP5","source":1},{"begin":773,"end":796,"name":"SUB","source":1},{"begin":769,"end":801,"name":"SLT","source":1},{"begin":766,"end":885,"name":"ISZERO","source":1},{"begin":766,"end":885,"name":"PUSH [tag]","source":1,"value":"30"},{"begin":766,"end":885,"name":"JUMPI","source":1},{"begin":804,"end":883,"name":"PUSH [tag]","source":1,"value":"31"},{"begin":804,"end":883,"name":"PUSH [tag]","source":1,"value":"13"},{"begin":804,"end":883,"jumpType":"[in]","name":"JUMP","source":1},{"begin":804,"end":883,"name":"tag","source":1,"value":"31"},{"begin":804,"end":883,"name":"JUMPDEST","source":1},{"begin":766,"end":885,"name":"tag","source":1,"value":"30"},{"begin":766,"end":885,"name":"JUMPDEST","source":1},{"begin":924,"end":925,"name":"PUSH","source":1,"value":"0"},{"begin":949,"end":1002,"name":"PUSH [tag]","source":1,"value":"32"},{"begin":994,"end":1001,"name":"DUP5","source":1},{"begin":985,"end":991,"name":"DUP3","source":1},{"begin":974,"end":983,"name":"DUP6","source":1},{"begin":970,"end":992,"name":"ADD","source":1},{"begin":949,"end":1002,"name":"PUSH [tag]","source":1,"value":"17"},{"begin":949,"end":1002,"jumpType":"[in]","name":"JUMP","source":1},{"begin":949,"end":1002,"name":"tag","source":1,"value":"32"},{"begin":949,"end":1002,"name":"JUMPDEST","source":1},{"begin":939,"end":1002,"name":"SWAP2","source":1},{"begin":939,"end":1002,"name":"POP","source":1},{"begin":895,"end":1012,"name":"POP","source":1},{"begin":690,"end":1019,"name":"SWAP3","source":1},{"begin":690,"end":1019,"name":"SWAP2","source":1},{"begin":690,"end":1019,"name":"POP","source":1},{"begin":690,"end":1019,"name":"POP","source":1},{"begin":690,"end":1019,"jumpType":"[out]","name":"JUMP","source":1},{"begin":1025,"end":1205,"name":"tag","source":1,"value":"18"},{"begin":1025,"end":1205,"name":"JUMPDEST","source":1},{"begin":1073,"end":1150,"name":"PUSH","source":1,"value":"4E487B7100000000000000000000000000000000000000000000000000000000"},{"begin":1070,"end":1071,"name":"PUSH","source":1,"value":"0"},{"begin":1063,"end":1151,"name":"MSTORE","source":1},{"begin":1170,"end":1174,"name":"PUSH","source":1,"value":"11"},{"begin":1167,"end":1168,"name":"PUSH","source":1,"value":"4"},{"begin":1160,"end":1175,"name":"MSTORE","source":1},{"begin":1194,"end":1198,"name":"PUSH","source":1,"value":"24"},{"begin":1191,"end":1192,"name":"PUSH","source":1,"value":"0"},{"begin":1184,"end":1199,"name":"REVERT","source":1},{"begin":1211,"end":1402,"name":"tag","source":1,"value":"10"},{"begin":1211,"end":1402,"name":"JUMPDEST","source":1},{"begin":1251,"end":1254,"name":"PUSH","source":1,"value":"0"},{"begin":1270,"end":1290,"name":"PUSH [tag]","source":1,"value":"35"},{"begin":1288,"end":1289,"name":"DUP3","source":1},{"begin":1270,"end":1290,"name":"PUSH [tag]","source":1,"value":"15"},{"begin":1270,"end":1290,"jumpType":"[in]","name":"JUMP","source":1},{"begin":1270,"end":1290,"name":"tag","source":1,"value":"35"},{"begin":1270,"end":1290,"name":"JUMPDEST","source":1},{"begin":1265,"end":1290,"name":"SWAP2","source":1},{"begin":1265,"end":1290,"name":"POP","source":1},{"begin":1304,"end":1324,"name":"PUSH [tag]","source":1,"value":"36"},{"begin":1322,"end":1323,"name":"DUP4","source":1},{"begin":1304,"end":1324,"name":"PUSH [tag]","source":1,"value":"15"},{"begin":1304,"end":1324,"jumpType":"[in]","name":"JUMP","source":1},{"begin":1304,"end":1324,"name":"tag","source":1,"value":"36"},{"begin":1304,"end":1324,"name":"JUMPDEST","source":1},{"begin":1299,"end":1324,"name":"SWAP3","source":1},{"begin":1299,"end":1324,"name":"POP","source":1},{"begin":1347,"end":1348,"name":"DUP3","source":1},{"begin":1344,"end":1345,"name":"DUP3","source":1},{"begin":1340,"end":1349,"name":"ADD","source":1},{"begin":1333,"end":1349,"name":"SWAP1","source":1},{"begin":1333,"end":1349,"name":"POP","source":1},{"begin":1368,"end":1371,"name":"DUP1","source":1},{"begin":1365,"end":1366,"name":"DUP3","source":1},{"begin":1362,"end":1372,"name":"GT","source":1},{"begin":1359,"end":1395,"name":"ISZERO","source":1},{"begin":1359,"end":1395,"name":"PUSH [tag]","source":1,"value":"37"},{"begin":1359,"end":1395,"name":"JUMPI","source":1},{"begin":1375,"end":1393,"name":"PUSH [tag]","source":1,"value":"38"},{"begin":1375,"end":1393,"name":"PUSH [tag]","source":1,"value":"18"},{"begin":1375,"end":1393,"jumpType":"[in]","name":"JUMP","source":1},{"begin":1375,"end":1393,"name":"tag","source":1,"value":"38"},{"begin":1375,"end":1393,"name":"JUMPDEST","source":1},{"begin":1359,"end":1395,"name":"tag","source":1,"value":"37"},{"begin":1359,"end":1395,"name":"JUMPDEST","source":1},{"begin":1211,"end":1402,"name":"SWAP3","source":1},{"begin":1211,"end":1402,"name":"SWAP2","source":1},{"begin":1211,"end":1402,"name":"POP","source":1},{"begin":1211,"end":1402,"name":"POP","source":1},{"begin":1211,"end":1402,"jumpType":"[out]","name":"JUMP","source":1}]}},"sourceList":["asm_json_no_pretty_print/input.sol","#utility.yul"]} +{".code":[{"begin":60,"end":160,"name":"PUSH","source":0,"value":"80"},{"begin":60,"end":160,"name":"PUSH","source":0,"value":"40"},{"begin":60,"end":160,"name":"MSTORE","source":0},{"begin":60,"end":160,"name":"CALLVALUE","source":0},{"begin":60,"end":160,"name":"DUP1","source":0},{"begin":60,"end":160,"name":"ISZERO","source":0},{"begin":60,"end":160,"name":"PUSH [tag]","source":0,"value":"1"},{"begin":60,"end":160,"name":"JUMPI","source":0},{"begin":60,"end":160,"name":"PUSH","source":0,"value":"0"},{"begin":60,"end":160,"name":"PUSH","source":0,"value":"0"},{"begin":60,"end":160,"name":"REVERT","source":0},{"begin":60,"end":160,"name":"tag","source":0,"value":"1"},{"begin":60,"end":160,"name":"JUMPDEST","source":0},{"begin":60,"end":160,"name":"POP","source":0},{"begin":60,"end":160,"name":"PUSH #[$]","source":0,"value":"0000000000000000000000000000000000000000000000000000000000000000"},{"begin":60,"end":160,"name":"DUP1","source":0},{"begin":60,"end":160,"name":"PUSH [$]","source":0,"value":"0000000000000000000000000000000000000000000000000000000000000000"},{"begin":60,"end":160,"name":"PUSH","source":0,"value":"0"},{"begin":60,"end":160,"name":"CODECOPY","source":0},{"begin":60,"end":160,"name":"PUSH","source":0,"value":"0"},{"begin":60,"end":160,"name":"RETURN","source":0}],".data":{"0":{".auxdata":"",".code":[{"begin":60,"end":160,"name":"PUSH","source":0,"value":"80"},{"begin":60,"end":160,"name":"PUSH","source":0,"value":"40"},{"begin":60,"end":160,"name":"MSTORE","source":0},{"begin":60,"end":160,"name":"CALLVALUE","source":0},{"begin":60,"end":160,"name":"DUP1","source":0},{"begin":60,"end":160,"name":"ISZERO","source":0},{"begin":60,"end":160,"name":"PUSH [tag]","source":0,"value":"1"},{"begin":60,"end":160,"name":"JUMPI","source":0},{"begin":60,"end":160,"name":"PUSH","source":0,"value":"0"},{"begin":60,"end":160,"name":"PUSH","source":0,"value":"0"},{"begin":60,"end":160,"name":"REVERT","source":0},{"begin":60,"end":160,"name":"tag","source":0,"value":"1"},{"begin":60,"end":160,"name":"JUMPDEST","source":0},{"begin":60,"end":160,"name":"POP","source":0},{"begin":60,"end":160,"name":"PUSH","source":0,"value":"4"},{"begin":60,"end":160,"name":"CALLDATASIZE","source":0},{"begin":60,"end":160,"name":"LT","source":0},{"begin":60,"end":160,"name":"PUSH [tag]","source":0,"value":"2"},{"begin":60,"end":160,"name":"JUMPI","source":0},{"begin":60,"end":160,"name":"PUSH","source":0,"value":"0"},{"begin":60,"end":160,"name":"CALLDATALOAD","source":0},{"begin":60,"end":160,"name":"PUSH","source":0,"value":"E0"},{"begin":60,"end":160,"name":"SHR","source":0},{"begin":60,"end":160,"name":"DUP1","source":0},{"begin":60,"end":160,"name":"PUSH","source":0,"value":"B3DE648B"},{"begin":60,"end":160,"name":"EQ","source":0},{"begin":60,"end":160,"name":"PUSH [tag]","source":0,"value":"3"},{"begin":60,"end":160,"name":"JUMPI","source":0},{"begin":60,"end":160,"name":"tag","source":0,"value":"2"},{"begin":60,"end":160,"name":"JUMPDEST","source":0},{"begin":60,"end":160,"name":"PUSH","source":0,"value":"0"},{"begin":60,"end":160,"name":"PUSH","source":0,"value":"0"},{"begin":60,"end":160,"name":"REVERT","source":0},{"begin":77,"end":158,"name":"tag","source":0,"value":"3"},{"begin":77,"end":158,"name":"JUMPDEST","source":0},{"begin":77,"end":158,"name":"PUSH [tag]","source":0,"value":"4"},{"begin":77,"end":158,"name":"PUSH","source":0,"value":"4"},{"begin":77,"end":158,"name":"DUP1","source":0},{"begin":77,"end":158,"name":"CALLDATASIZE","source":0},{"begin":77,"end":158,"name":"SUB","source":0},{"begin":77,"end":158,"name":"DUP2","source":0},{"begin":77,"end":158,"name":"ADD","source":0},{"begin":77,"end":158,"name":"SWAP1","source":0},{"begin":77,"end":158,"name":"PUSH [tag]","source":0,"value":"5"},{"begin":77,"end":158,"name":"SWAP2","source":0},{"begin":77,"end":158,"name":"SWAP1","source":0},{"begin":77,"end":158,"name":"PUSH [tag]","source":0,"value":"6"},{"begin":77,"end":158,"jumpType":"[in]","name":"JUMP","source":0},{"begin":77,"end":158,"name":"tag","source":0,"value":"5"},{"begin":77,"end":158,"name":"JUMPDEST","source":0},{"begin":77,"end":158,"name":"PUSH [tag]","source":0,"value":"7"},{"begin":77,"end":158,"jumpType":"[in]","name":"JUMP","source":0},{"begin":77,"end":158,"name":"tag","source":0,"value":"4"},{"begin":77,"end":158,"name":"JUMPDEST","source":0},{"begin":77,"end":158,"name":"STOP","source":0},{"begin":77,"end":158,"name":"tag","source":0,"value":"7"},{"begin":77,"end":158,"name":"JUMPDEST","source":0},{"begin":123,"end":125,"name":"PUSH","source":0,"value":"2A"},{"begin":118,"end":125,"name":"DUP2","source":0},{"begin":118,"end":125,"name":"PUSH [tag]","source":0,"value":"9"},{"begin":118,"end":125,"name":"SWAP2","source":0},{"begin":118,"end":125,"name":"SWAP1","source":0},{"begin":118,"end":125,"name":"PUSH [tag]","source":0,"value":"10"},{"begin":118,"end":125,"jumpType":"[in]","name":"JUMP","source":0},{"begin":118,"end":125,"name":"tag","source":0,"value":"9"},{"begin":118,"end":125,"name":"JUMPDEST","source":0},{"begin":118,"end":125,"name":"SWAP1","source":0},{"begin":118,"end":125,"name":"POP","source":0},{"begin":147,"end":150,"name":"PUSH","source":0,"value":"64"},{"begin":143,"end":144,"name":"DUP2","source":0},{"begin":143,"end":150,"name":"GT","source":0},{"begin":135,"end":151,"name":"PUSH [tag]","source":0,"value":"11"},{"begin":135,"end":151,"name":"JUMPI","source":0},{"begin":135,"end":151,"name":"PUSH","source":0,"value":"0"},{"begin":135,"end":151,"name":"PUSH","source":0,"value":"0"},{"begin":135,"end":151,"name":"REVERT","source":0},{"begin":135,"end":151,"name":"tag","source":0,"value":"11"},{"begin":135,"end":151,"name":"JUMPDEST","source":0},{"begin":77,"end":158,"name":"POP","source":0},{"begin":77,"end":158,"jumpType":"[out]","name":"JUMP","source":0},{"begin":88,"end":205,"name":"tag","source":1,"value":"13"},{"begin":88,"end":205,"name":"JUMPDEST","source":1},{"begin":197,"end":198,"name":"PUSH","source":1,"value":"0"},{"begin":194,"end":195,"name":"PUSH","source":1,"value":"0"},{"begin":187,"end":199,"name":"REVERT","source":1},{"begin":334,"end":411,"name":"tag","source":1,"value":"15"},{"begin":334,"end":411,"name":"JUMPDEST","source":1},{"begin":371,"end":378,"name":"PUSH","source":1,"value":"0"},{"begin":400,"end":405,"name":"DUP2","source":1},{"begin":389,"end":405,"name":"SWAP1","source":1},{"begin":389,"end":405,"name":"POP","source":1},{"begin":334,"end":411,"name":"SWAP2","source":1},{"begin":334,"end":411,"name":"SWAP1","source":1},{"begin":334,"end":411,"name":"POP","source":1},{"begin":334,"end":411,"jumpType":"[out]","name":"JUMP","source":1},{"begin":417,"end":539,"name":"tag","source":1,"value":"16"},{"begin":417,"end":539,"name":"JUMPDEST","source":1},{"begin":490,"end":514,"name":"PUSH [tag]","source":1,"value":"25"},{"begin":508,"end":513,"name":"DUP2","source":1},{"begin":490,"end":514,"name":"PUSH [tag]","source":1,"value":"15"},{"begin":490,"end":514,"jumpType":"[in]","name":"JUMP","source":1},{"begin":490,"end":514,"name":"tag","source":1,"value":"25"},{"begin":490,"end":514,"name":"JUMPDEST","source":1},{"begin":483,"end":488,"name":"DUP2","source":1},{"begin":480,"end":515,"name":"EQ","source":1},{"begin":470,"end":533,"name":"PUSH [tag]","source":1,"value":"26"},{"begin":470,"end":533,"name":"JUMPI","source":1},{"begin":529,"end":530,"name":"PUSH","source":1,"value":"0"},{"begin":526,"end":527,"name":"PUSH","source":1,"value":"0"},{"begin":519,"end":531,"name":"REVERT","source":1},{"begin":470,"end":533,"name":"tag","source":1,"value":"26"},{"begin":470,"end":533,"name":"JUMPDEST","source":1},{"begin":417,"end":539,"name":"POP","source":1},{"begin":417,"end":539,"jumpType":"[out]","name":"JUMP","source":1},{"begin":545,"end":684,"name":"tag","source":1,"value":"17"},{"begin":545,"end":684,"name":"JUMPDEST","source":1},{"begin":591,"end":596,"name":"PUSH","source":1,"value":"0"},{"begin":629,"end":635,"name":"DUP2","source":1},{"begin":616,"end":636,"name":"CALLDATALOAD","source":1},{"begin":607,"end":636,"name":"SWAP1","source":1},{"begin":607,"end":636,"name":"POP","source":1},{"begin":645,"end":678,"name":"PUSH [tag]","source":1,"value":"28"},{"begin":672,"end":677,"name":"DUP2","source":1},{"begin":645,"end":678,"name":"PUSH [tag]","source":1,"value":"16"},{"begin":645,"end":678,"jumpType":"[in]","name":"JUMP","source":1},{"begin":645,"end":678,"name":"tag","source":1,"value":"28"},{"begin":645,"end":678,"name":"JUMPDEST","source":1},{"begin":545,"end":684,"name":"SWAP3","source":1},{"begin":545,"end":684,"name":"SWAP2","source":1},{"begin":545,"end":684,"name":"POP","source":1},{"begin":545,"end":684,"name":"POP","source":1},{"begin":545,"end":684,"jumpType":"[out]","name":"JUMP","source":1},{"begin":690,"end":1019,"name":"tag","source":1,"value":"6"},{"begin":690,"end":1019,"name":"JUMPDEST","source":1},{"begin":749,"end":755,"name":"PUSH","source":1,"value":"0"},{"begin":798,"end":800,"name":"PUSH","source":1,"value":"20"},{"begin":786,"end":795,"name":"DUP3","source":1},{"begin":777,"end":784,"name":"DUP5","source":1},{"begin":773,"end":796,"name":"SUB","source":1},{"begin":769,"end":801,"name":"SLT","source":1},{"begin":766,"end":885,"name":"ISZERO","source":1},{"begin":766,"end":885,"name":"PUSH [tag]","source":1,"value":"30"},{"begin":766,"end":885,"name":"JUMPI","source":1},{"begin":804,"end":883,"name":"PUSH [tag]","source":1,"value":"31"},{"begin":804,"end":883,"name":"PUSH [tag]","source":1,"value":"13"},{"begin":804,"end":883,"jumpType":"[in]","name":"JUMP","source":1},{"begin":804,"end":883,"name":"tag","source":1,"value":"31"},{"begin":804,"end":883,"name":"JUMPDEST","source":1},{"begin":766,"end":885,"name":"tag","source":1,"value":"30"},{"begin":766,"end":885,"name":"JUMPDEST","source":1},{"begin":924,"end":925,"name":"PUSH","source":1,"value":"0"},{"begin":949,"end":1002,"name":"PUSH [tag]","source":1,"value":"32"},{"begin":994,"end":1001,"name":"DUP5","source":1},{"begin":985,"end":991,"name":"DUP3","source":1},{"begin":974,"end":983,"name":"DUP6","source":1},{"begin":970,"end":992,"name":"ADD","source":1},{"begin":949,"end":1002,"name":"PUSH [tag]","source":1,"value":"17"},{"begin":949,"end":1002,"jumpType":"[in]","name":"JUMP","source":1},{"begin":949,"end":1002,"name":"tag","source":1,"value":"32"},{"begin":949,"end":1002,"name":"JUMPDEST","source":1},{"begin":939,"end":1002,"name":"SWAP2","source":1},{"begin":939,"end":1002,"name":"POP","source":1},{"begin":895,"end":1012,"name":"POP","source":1},{"begin":690,"end":1019,"name":"SWAP3","source":1},{"begin":690,"end":1019,"name":"SWAP2","source":1},{"begin":690,"end":1019,"name":"POP","source":1},{"begin":690,"end":1019,"name":"POP","source":1},{"begin":690,"end":1019,"jumpType":"[out]","name":"JUMP","source":1},{"begin":1025,"end":1205,"name":"tag","source":1,"value":"18"},{"begin":1025,"end":1205,"name":"JUMPDEST","source":1},{"begin":1073,"end":1150,"name":"PUSH","source":1,"value":"4E487B7100000000000000000000000000000000000000000000000000000000"},{"begin":1070,"end":1071,"name":"PUSH","source":1,"value":"0"},{"begin":1063,"end":1151,"name":"MSTORE","source":1},{"begin":1170,"end":1174,"name":"PUSH","source":1,"value":"11"},{"begin":1167,"end":1168,"name":"PUSH","source":1,"value":"4"},{"begin":1160,"end":1175,"name":"MSTORE","source":1},{"begin":1194,"end":1198,"name":"PUSH","source":1,"value":"24"},{"begin":1191,"end":1192,"name":"PUSH","source":1,"value":"0"},{"begin":1184,"end":1199,"name":"REVERT","source":1},{"begin":1211,"end":1402,"name":"tag","source":1,"value":"10"},{"begin":1211,"end":1402,"name":"JUMPDEST","source":1},{"begin":1251,"end":1254,"name":"PUSH","source":1,"value":"0"},{"begin":1270,"end":1290,"name":"PUSH [tag]","source":1,"value":"35"},{"begin":1288,"end":1289,"name":"DUP3","source":1},{"begin":1270,"end":1290,"name":"PUSH [tag]","source":1,"value":"15"},{"begin":1270,"end":1290,"jumpType":"[in]","name":"JUMP","source":1},{"begin":1270,"end":1290,"name":"tag","source":1,"value":"35"},{"begin":1270,"end":1290,"name":"JUMPDEST","source":1},{"begin":1265,"end":1290,"name":"SWAP2","source":1},{"begin":1265,"end":1290,"name":"POP","source":1},{"begin":1304,"end":1324,"name":"PUSH [tag]","source":1,"value":"36"},{"begin":1322,"end":1323,"name":"DUP4","source":1},{"begin":1304,"end":1324,"name":"PUSH [tag]","source":1,"value":"15"},{"begin":1304,"end":1324,"jumpType":"[in]","name":"JUMP","source":1},{"begin":1304,"end":1324,"name":"tag","source":1,"value":"36"},{"begin":1304,"end":1324,"name":"JUMPDEST","source":1},{"begin":1299,"end":1324,"name":"SWAP3","source":1},{"begin":1299,"end":1324,"name":"POP","source":1},{"begin":1347,"end":1348,"name":"DUP3","source":1},{"begin":1344,"end":1345,"name":"DUP3","source":1},{"begin":1340,"end":1349,"name":"ADD","source":1},{"begin":1333,"end":1349,"name":"SWAP1","source":1},{"begin":1333,"end":1349,"name":"POP","source":1},{"begin":1368,"end":1371,"name":"DUP1","source":1},{"begin":1365,"end":1366,"name":"DUP3","source":1},{"begin":1362,"end":1372,"name":"GT","source":1},{"begin":1359,"end":1395,"name":"ISZERO","source":1},{"begin":1359,"end":1395,"name":"PUSH [tag]","source":1,"value":"37"},{"begin":1359,"end":1395,"name":"JUMPI","source":1},{"begin":1375,"end":1393,"name":"PUSH [tag]","source":1,"value":"38"},{"begin":1375,"end":1393,"name":"PUSH [tag]","source":1,"value":"18"},{"begin":1375,"end":1393,"jumpType":"[in]","name":"JUMP","source":1},{"begin":1375,"end":1393,"name":"tag","source":1,"value":"38"},{"begin":1375,"end":1393,"name":"JUMPDEST","source":1},{"begin":1359,"end":1395,"name":"tag","source":1,"value":"37"},{"begin":1359,"end":1395,"name":"JUMPDEST","source":1},{"begin":1211,"end":1402,"name":"SWAP3","source":1},{"begin":1211,"end":1402,"name":"SWAP2","source":1},{"begin":1211,"end":1402,"name":"POP","source":1},{"begin":1211,"end":1402,"name":"POP","source":1},{"begin":1211,"end":1402,"jumpType":"[out]","name":"JUMP","source":1}]}},"sourceList":["input.sol","#utility.yul"]} diff --git a/test/cmdlineTests/ast_compact_json_no_pretty_json/output b/test/cmdlineTests/ast_compact_json_no_pretty_json/output index fb79fd524e24..43806c05506d 100644 --- a/test/cmdlineTests/ast_compact_json_no_pretty_json/output +++ b/test/cmdlineTests/ast_compact_json_no_pretty_json/output @@ -1,5 +1,5 @@ JSON AST (compact format): -======= ast_compact_json_no_pretty_json/input.sol ======= -{"absolutePath":"ast_compact_json_no_pretty_json/input.sol","exportedSymbols":{"C":[2]},"id":3,"license":"GPL-3.0","nodeType":"SourceUnit","nodes":[{"id":1,"literals":["solidity",">=","0.0"],"nodeType":"PragmaDirective","src":"36:22:0"},{"abstract":false,"baseContracts":[],"canonicalName":"C","contractDependencies":[],"contractKind":"contract","fullyImplemented":true,"id":2,"linearizedBaseContracts":[2],"name":"C","nameLocation":"69:1:0","nodeType":"ContractDefinition","nodes":[],"scope":3,"src":"60:13:0","usedErrors":[],"usedEvents":[]}],"src":"36:38:0"} +======= input.sol ======= +{"absolutePath":"input.sol","exportedSymbols":{"C":[2]},"id":3,"license":"GPL-3.0","nodeType":"SourceUnit","nodes":[{"id":1,"literals":["solidity",">=","0.0"],"nodeType":"PragmaDirective","src":"36:22:0"},{"abstract":false,"baseContracts":[],"canonicalName":"C","contractDependencies":[],"contractKind":"contract","fullyImplemented":true,"id":2,"linearizedBaseContracts":[2],"name":"C","nameLocation":"69:1:0","nodeType":"ContractDefinition","nodes":[],"scope":3,"src":"60:13:0","usedErrors":[],"usedEvents":[]}],"src":"36:38:0"} diff --git a/test/cmdlineTests/ast_compact_json_storage_layout_specifier/output b/test/cmdlineTests/ast_compact_json_storage_layout_specifier/output index 4fe5fe193be9..994286c3bbe4 100644 --- a/test/cmdlineTests/ast_compact_json_storage_layout_specifier/output +++ b/test/cmdlineTests/ast_compact_json_storage_layout_specifier/output @@ -1,9 +1,9 @@ JSON AST (compact format): -======= ast_compact_json_storage_layout_specifier/input.sol ======= +======= input.sol ======= { - "absolutePath": "ast_compact_json_storage_layout_specifier/input.sol", + "absolutePath": "input.sol", "exportedSymbols": { "C": [ 6 diff --git a/test/cmdlineTests/ast_compact_json_with_base_path/output b/test/cmdlineTests/ast_compact_json_with_base_path/output index c61502020765..93f7df2536b6 100644 --- a/test/cmdlineTests/ast_compact_json_with_base_path/output +++ b/test/cmdlineTests/ast_compact_json_with_base_path/output @@ -1,9 +1,9 @@ JSON AST (compact format): -======= ast_compact_json_with_base_path/c.sol ======= +======= c.sol ======= { - "absolutePath": "ast_compact_json_with_base_path/c.sol", + "absolutePath": "c.sol", "exportedSymbols": { "C": [ 5 @@ -46,9 +46,9 @@ JSON AST (compact format): ], "src": "36:38:0" } -======= ast_compact_json_with_base_path/input.sol ======= +======= input.sol ======= { - "absolutePath": "ast_compact_json_with_base_path/input.sol", + "absolutePath": "input.sol", "exportedSymbols": { "C": [ 5 @@ -69,7 +69,7 @@ JSON AST (compact format): "src": "36:22:1" }, { - "absolutePath": "ast_compact_json_with_base_path/c.sol", + "absolutePath": "c.sol", "file": "./c.sol", "id": 2, "nameLocation": "-1:-1:-1", diff --git a/test/cmdlineTests/ast_ir/output b/test/cmdlineTests/ast_ir/output index 76f111990870..88047ade02b3 100644 --- a/test/cmdlineTests/ast_ir/output +++ b/test/cmdlineTests/ast_ir/output @@ -2,7 +2,7 @@ IR AST: { "code": { "block": { - "nativeSrc": "59:790:0", + "nativeSrc": "52:790:0", "nodeType": "YulBlock", "src": "-1:-1:0", "statements": [ @@ -11,7 +11,7 @@ IR AST: "arguments": [ { "kind": "number", - "nativeSrc": "118:2:0", + "nativeSrc": "111:2:0", "nodeType": "YulLiteral", "src": "60:13:0", "type": "", @@ -21,7 +21,7 @@ IR AST: "arguments": [ { "kind": "number", - "nativeSrc": "134:3:0", + "nativeSrc": "127:3:0", "nodeType": "YulLiteral", "src": "60:13:0", "type": "", @@ -30,32 +30,32 @@ IR AST: ], "functionName": { "name": "memoryguard", - "nativeSrc": "122:11:0", + "nativeSrc": "115:11:0", "nodeType": "YulIdentifier", "src": "60:13:0" }, - "nativeSrc": "122:16:0", + "nativeSrc": "115:16:0", "nodeType": "YulFunctionCall", "src": "60:13:0" } ], "functionName": { "name": "mstore", - "nativeSrc": "111:6:0", + "nativeSrc": "104:6:0", "nodeType": "YulIdentifier", "src": "60:13:0" }, - "nativeSrc": "111:28:0", + "nativeSrc": "104:28:0", "nodeType": "YulFunctionCall", "src": "60:13:0" }, - "nativeSrc": "111:28:0", + "nativeSrc": "104:28:0", "nodeType": "YulExpressionStatement", "src": "60:13:0" }, { "body": { - "nativeSrc": "163:83:0", + "nativeSrc": "156:83:0", "nodeType": "YulBlock", "src": "60:13:0", "statements": [ @@ -64,15 +64,15 @@ IR AST: "arguments": [], "functionName": { "name": "revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb", - "nativeSrc": "165:77:0", + "nativeSrc": "158:77:0", "nodeType": "YulIdentifier", "src": "60:13:0" }, - "nativeSrc": "165:79:0", + "nativeSrc": "158:79:0", "nodeType": "YulFunctionCall", "src": "60:13:0" }, - "nativeSrc": "165:79:0", + "nativeSrc": "158:79:0", "nodeType": "YulExpressionStatement", "src": "60:13:0" } @@ -82,15 +82,15 @@ IR AST: "arguments": [], "functionName": { "name": "callvalue", - "nativeSrc": "151:9:0", + "nativeSrc": "144:9:0", "nodeType": "YulIdentifier", "src": "60:13:0" }, - "nativeSrc": "151:11:0", + "nativeSrc": "144:11:0", "nodeType": "YulFunctionCall", "src": "60:13:0" }, - "nativeSrc": "148:98:0", + "nativeSrc": "141:98:0", "nodeType": "YulIf", "src": "60:13:0" }, @@ -99,38 +99,38 @@ IR AST: "arguments": [], "functionName": { "name": "constructor_C_2", - "nativeSrc": "256:15:0", + "nativeSrc": "249:15:0", "nodeType": "YulIdentifier", "src": "60:13:0" }, - "nativeSrc": "256:17:0", + "nativeSrc": "249:17:0", "nodeType": "YulFunctionCall", "src": "60:13:0" }, - "nativeSrc": "256:17:0", + "nativeSrc": "249:17:0", "nodeType": "YulExpressionStatement", "src": "60:13:0" }, { - "nativeSrc": "283:30:0", + "nativeSrc": "276:30:0", "nodeType": "YulVariableDeclaration", "src": "60:13:0", "value": { "arguments": [], "functionName": { "name": "allocate_unbounded", - "nativeSrc": "293:18:0", + "nativeSrc": "286:18:0", "nodeType": "YulIdentifier", "src": "60:13:0" }, - "nativeSrc": "293:20:0", + "nativeSrc": "286:20:0", "nodeType": "YulFunctionCall", "src": "60:13:0" }, "variables": [ { "name": "_1", - "nativeSrc": "287:2:0", + "nativeSrc": "280:2:0", "nodeType": "YulTypedName", "src": "60:13:0", "type": "" @@ -142,7 +142,7 @@ IR AST: "arguments": [ { "name": "_1", - "nativeSrc": "331:2:0", + "nativeSrc": "324:2:0", "nodeType": "YulIdentifier", "src": "60:13:0" }, @@ -151,7 +151,7 @@ IR AST: { "hexValue": "435f325f6465706c6f796564", "kind": "string", - "nativeSrc": "346:14:0", + "nativeSrc": "339:14:0", "nodeType": "YulLiteral", "src": "60:13:0", "type": "", @@ -160,11 +160,11 @@ IR AST: ], "functionName": { "name": "dataoffset", - "nativeSrc": "335:10:0", + "nativeSrc": "328:10:0", "nodeType": "YulIdentifier", "src": "60:13:0" }, - "nativeSrc": "335:26:0", + "nativeSrc": "328:26:0", "nodeType": "YulFunctionCall", "src": "60:13:0" }, @@ -173,7 +173,7 @@ IR AST: { "hexValue": "435f325f6465706c6f796564", "kind": "string", - "nativeSrc": "372:14:0", + "nativeSrc": "365:14:0", "nodeType": "YulLiteral", "src": "60:13:0", "type": "", @@ -182,26 +182,26 @@ IR AST: ], "functionName": { "name": "datasize", - "nativeSrc": "363:8:0", + "nativeSrc": "356:8:0", "nodeType": "YulIdentifier", "src": "60:13:0" }, - "nativeSrc": "363:24:0", + "nativeSrc": "356:24:0", "nodeType": "YulFunctionCall", "src": "60:13:0" } ], "functionName": { "name": "codecopy", - "nativeSrc": "322:8:0", + "nativeSrc": "315:8:0", "nodeType": "YulIdentifier", "src": "60:13:0" }, - "nativeSrc": "322:66:0", + "nativeSrc": "315:66:0", "nodeType": "YulFunctionCall", "src": "60:13:0" }, - "nativeSrc": "322:66:0", + "nativeSrc": "315:66:0", "nodeType": "YulExpressionStatement", "src": "60:13:0" }, @@ -210,7 +210,7 @@ IR AST: "arguments": [ { "name": "_1", - "nativeSrc": "405:2:0", + "nativeSrc": "398:2:0", "nodeType": "YulIdentifier", "src": "60:13:0" }, @@ -219,7 +219,7 @@ IR AST: { "hexValue": "435f325f6465706c6f796564", "kind": "string", - "nativeSrc": "418:14:0", + "nativeSrc": "411:14:0", "nodeType": "YulLiteral", "src": "60:13:0", "type": "", @@ -228,44 +228,44 @@ IR AST: ], "functionName": { "name": "datasize", - "nativeSrc": "409:8:0", + "nativeSrc": "402:8:0", "nodeType": "YulIdentifier", "src": "60:13:0" }, - "nativeSrc": "409:24:0", + "nativeSrc": "402:24:0", "nodeType": "YulFunctionCall", "src": "60:13:0" } ], "functionName": { "name": "return", - "nativeSrc": "398:6:0", + "nativeSrc": "391:6:0", "nodeType": "YulIdentifier", "src": "60:13:0" }, - "nativeSrc": "398:36:0", + "nativeSrc": "391:36:0", "nodeType": "YulFunctionCall", "src": "60:13:0" }, - "nativeSrc": "398:36:0", + "nativeSrc": "391:36:0", "nodeType": "YulExpressionStatement", "src": "60:13:0" }, { "body": { - "nativeSrc": "484:43:0", + "nativeSrc": "477:43:0", "nodeType": "YulBlock", "src": "60:13:0", "statements": [ { - "nativeSrc": "498:19:0", + "nativeSrc": "491:19:0", "nodeType": "YulAssignment", "src": "60:13:0", "value": { "arguments": [ { "kind": "number", - "nativeSrc": "514:2:0", + "nativeSrc": "507:2:0", "nodeType": "YulLiteral", "src": "60:13:0", "type": "", @@ -274,18 +274,18 @@ IR AST: ], "functionName": { "name": "mload", - "nativeSrc": "508:5:0", + "nativeSrc": "501:5:0", "nodeType": "YulIdentifier", "src": "60:13:0" }, - "nativeSrc": "508:9:0", + "nativeSrc": "501:9:0", "nodeType": "YulFunctionCall", "src": "60:13:0" }, "variableNames": [ { "name": "memPtr", - "nativeSrc": "498:6:0", + "nativeSrc": "491:6:0", "nodeType": "YulIdentifier", "src": "60:13:0" } @@ -294,12 +294,12 @@ IR AST: ] }, "name": "allocate_unbounded", - "nativeSrc": "444:83:0", + "nativeSrc": "437:83:0", "nodeType": "YulFunctionDefinition", "returnVariables": [ { "name": "memPtr", - "nativeSrc": "477:6:0", + "nativeSrc": "470:6:0", "nodeType": "YulTypedName", "src": "60:13:0", "type": "" @@ -309,7 +309,7 @@ IR AST: }, { "body": { - "nativeSrc": "626:36:0", + "nativeSrc": "619:36:0", "nodeType": "YulBlock", "src": "60:13:0", "statements": [ @@ -318,7 +318,7 @@ IR AST: "arguments": [ { "kind": "number", - "nativeSrc": "647:1:0", + "nativeSrc": "640:1:0", "nodeType": "YulLiteral", "src": "60:13:0", "type": "", @@ -326,7 +326,7 @@ IR AST: }, { "kind": "number", - "nativeSrc": "650:1:0", + "nativeSrc": "643:1:0", "nodeType": "YulLiteral", "src": "60:13:0", "type": "", @@ -335,34 +335,34 @@ IR AST: ], "functionName": { "name": "revert", - "nativeSrc": "640:6:0", + "nativeSrc": "633:6:0", "nodeType": "YulIdentifier", "src": "60:13:0" }, - "nativeSrc": "640:12:0", + "nativeSrc": "633:12:0", "nodeType": "YulFunctionCall", "src": "60:13:0" }, - "nativeSrc": "640:12:0", + "nativeSrc": "633:12:0", "nodeType": "YulExpressionStatement", "src": "60:13:0" } ] }, "name": "revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb", - "nativeSrc": "537:125:0", + "nativeSrc": "530:125:0", "nodeType": "YulFunctionDefinition", "src": "60:13:0" }, { "body": { - "nativeSrc": "741:59:0", + "nativeSrc": "734:59:0", "nodeType": "YulBlock", "src": "60:13:0", "statements": [] }, "name": "constructor_C_2", - "nativeSrc": "714:86:0", + "nativeSrc": "707:86:0", "nodeType": "YulFunctionDefinition", "src": "60:13:0" } @@ -376,7 +376,7 @@ IR AST: { "code": { "block": { - "nativeSrc": "929:588:0", + "nativeSrc": "915:588:0", "nodeType": "YulBlock", "src": "-1:-1:0", "statements": [ @@ -385,7 +385,7 @@ IR AST: "arguments": [ { "kind": "number", - "nativeSrc": "996:2:0", + "nativeSrc": "982:2:0", "nodeType": "YulLiteral", "src": "60:13:0", "type": "", @@ -395,7 +395,7 @@ IR AST: "arguments": [ { "kind": "number", - "nativeSrc": "1012:3:0", + "nativeSrc": "998:3:0", "nodeType": "YulLiteral", "src": "60:13:0", "type": "", @@ -404,26 +404,26 @@ IR AST: ], "functionName": { "name": "memoryguard", - "nativeSrc": "1000:11:0", + "nativeSrc": "986:11:0", "nodeType": "YulIdentifier", "src": "60:13:0" }, - "nativeSrc": "1000:16:0", + "nativeSrc": "986:16:0", "nodeType": "YulFunctionCall", "src": "60:13:0" } ], "functionName": { "name": "mstore", - "nativeSrc": "989:6:0", + "nativeSrc": "975:6:0", "nodeType": "YulIdentifier", "src": "60:13:0" }, - "nativeSrc": "989:28:0", + "nativeSrc": "975:28:0", "nodeType": "YulFunctionCall", "src": "60:13:0" }, - "nativeSrc": "989:28:0", + "nativeSrc": "975:28:0", "nodeType": "YulExpressionStatement", "src": "60:13:0" }, @@ -432,33 +432,33 @@ IR AST: "arguments": [], "functionName": { "name": "revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74", - "nativeSrc": "1031:77:0", + "nativeSrc": "1017:77:0", "nodeType": "YulIdentifier", "src": "60:13:0" }, - "nativeSrc": "1031:79:0", + "nativeSrc": "1017:79:0", "nodeType": "YulFunctionCall", "src": "60:13:0" }, - "nativeSrc": "1031:79:0", + "nativeSrc": "1017:79:0", "nodeType": "YulExpressionStatement", "src": "60:13:0" }, { "body": { - "nativeSrc": "1177:77:0", + "nativeSrc": "1163:77:0", "nodeType": "YulBlock", "src": "60:13:0", "statements": [ { - "nativeSrc": "1195:44:0", + "nativeSrc": "1181:44:0", "nodeType": "YulAssignment", "src": "60:13:0", "value": { "arguments": [ { "kind": "number", - "nativeSrc": "1228:3:0", + "nativeSrc": "1214:3:0", "nodeType": "YulLiteral", "src": "60:13:0", "type": "", @@ -466,25 +466,25 @@ IR AST: }, { "name": "value", - "nativeSrc": "1233:5:0", + "nativeSrc": "1219:5:0", "nodeType": "YulIdentifier", "src": "60:13:0" } ], "functionName": { "name": "shr", - "nativeSrc": "1224:3:0", + "nativeSrc": "1210:3:0", "nodeType": "YulIdentifier", "src": "60:13:0" }, - "nativeSrc": "1224:15:0", + "nativeSrc": "1210:15:0", "nodeType": "YulFunctionCall", "src": "60:13:0" }, "variableNames": [ { "name": "newValue", - "nativeSrc": "1195:8:0", + "nativeSrc": "1181:8:0", "nodeType": "YulIdentifier", "src": "60:13:0" } @@ -493,12 +493,12 @@ IR AST: ] }, "name": "shift_right_224_unsigned", - "nativeSrc": "1124:130:0", + "nativeSrc": "1110:130:0", "nodeType": "YulFunctionDefinition", "parameters": [ { "name": "value", - "nativeSrc": "1158:5:0", + "nativeSrc": "1144:5:0", "nodeType": "YulTypedName", "src": "60:13:0", "type": "" @@ -507,7 +507,7 @@ IR AST: "returnVariables": [ { "name": "newValue", - "nativeSrc": "1168:8:0", + "nativeSrc": "1154:8:0", "nodeType": "YulTypedName", "src": "60:13:0", "type": "" @@ -517,19 +517,19 @@ IR AST: }, { "body": { - "nativeSrc": "1308:51:0", + "nativeSrc": "1294:51:0", "nodeType": "YulBlock", "src": "60:13:0", "statements": [ { - "nativeSrc": "1326:19:0", + "nativeSrc": "1312:19:0", "nodeType": "YulAssignment", "src": "60:13:0", "value": { "arguments": [ { "kind": "number", - "nativeSrc": "1342:2:0", + "nativeSrc": "1328:2:0", "nodeType": "YulLiteral", "src": "60:13:0", "type": "", @@ -538,18 +538,18 @@ IR AST: ], "functionName": { "name": "mload", - "nativeSrc": "1336:5:0", + "nativeSrc": "1322:5:0", "nodeType": "YulIdentifier", "src": "60:13:0" }, - "nativeSrc": "1336:9:0", + "nativeSrc": "1322:9:0", "nodeType": "YulFunctionCall", "src": "60:13:0" }, "variableNames": [ { "name": "memPtr", - "nativeSrc": "1326:6:0", + "nativeSrc": "1312:6:0", "nodeType": "YulIdentifier", "src": "60:13:0" } @@ -558,12 +558,12 @@ IR AST: ] }, "name": "allocate_unbounded", - "nativeSrc": "1268:91:0", + "nativeSrc": "1254:91:0", "nodeType": "YulFunctionDefinition", "returnVariables": [ { "name": "memPtr", - "nativeSrc": "1301:6:0", + "nativeSrc": "1287:6:0", "nodeType": "YulTypedName", "src": "60:13:0", "type": "" @@ -573,7 +573,7 @@ IR AST: }, { "body": { - "nativeSrc": "1462:44:0", + "nativeSrc": "1448:44:0", "nodeType": "YulBlock", "src": "60:13:0", "statements": [ @@ -582,7 +582,7 @@ IR AST: "arguments": [ { "kind": "number", - "nativeSrc": "1487:1:0", + "nativeSrc": "1473:1:0", "nodeType": "YulLiteral", "src": "60:13:0", "type": "", @@ -590,7 +590,7 @@ IR AST: }, { "kind": "number", - "nativeSrc": "1490:1:0", + "nativeSrc": "1476:1:0", "nodeType": "YulLiteral", "src": "60:13:0", "type": "", @@ -599,22 +599,22 @@ IR AST: ], "functionName": { "name": "revert", - "nativeSrc": "1480:6:0", + "nativeSrc": "1466:6:0", "nodeType": "YulIdentifier", "src": "60:13:0" }, - "nativeSrc": "1480:12:0", + "nativeSrc": "1466:12:0", "nodeType": "YulFunctionCall", "src": "60:13:0" }, - "nativeSrc": "1480:12:0", + "nativeSrc": "1466:12:0", "nodeType": "YulExpressionStatement", "src": "60:13:0" } ] }, "name": "revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74", - "nativeSrc": "1373:133:0", + "nativeSrc": "1359:133:0", "nodeType": "YulFunctionDefinition", "src": "60:13:0" } @@ -637,24 +637,24 @@ Optimized IR AST: { "code": { "block": { - "nativeSrc": "58:315:0", + "nativeSrc": "51:315:0", "nodeType": "YulBlock", "src": "-1:-1:0", "statements": [ { - "nativeSrc": "68:299:0", + "nativeSrc": "61:299:0", "nodeType": "YulBlock", "src": "-1:-1:0", "statements": [ { - "nativeSrc": "128:27:0", + "nativeSrc": "121:27:0", "nodeType": "YulVariableDeclaration", "src": "60:13:0", "value": { "arguments": [ { "kind": "number", - "nativeSrc": "150:4:0", + "nativeSrc": "143:4:0", "nodeType": "YulLiteral", "src": "60:13:0", "type": "", @@ -663,18 +663,18 @@ Optimized IR AST: ], "functionName": { "name": "memoryguard", - "nativeSrc": "138:11:0", + "nativeSrc": "131:11:0", "nodeType": "YulIdentifier", "src": "60:13:0" }, - "nativeSrc": "138:17:0", + "nativeSrc": "131:17:0", "nodeType": "YulFunctionCall", "src": "60:13:0" }, "variables": [ { "name": "_1", - "nativeSrc": "132:2:0", + "nativeSrc": "125:2:0", "nodeType": "YulTypedName", "src": "60:13:0", "type": "" @@ -686,7 +686,7 @@ Optimized IR AST: "arguments": [ { "kind": "number", - "nativeSrc": "175:2:0", + "nativeSrc": "168:2:0", "nodeType": "YulLiteral", "src": "60:13:0", "type": "", @@ -694,28 +694,28 @@ Optimized IR AST: }, { "name": "_1", - "nativeSrc": "179:2:0", + "nativeSrc": "172:2:0", "nodeType": "YulIdentifier", "src": "60:13:0" } ], "functionName": { "name": "mstore", - "nativeSrc": "168:6:0", + "nativeSrc": "161:6:0", "nodeType": "YulIdentifier", "src": "60:13:0" }, - "nativeSrc": "168:14:0", + "nativeSrc": "161:14:0", "nodeType": "YulFunctionCall", "src": "60:13:0" }, - "nativeSrc": "168:14:0", + "nativeSrc": "161:14:0", "nodeType": "YulExpressionStatement", "src": "60:13:0" }, { "body": { - "nativeSrc": "210:16:0", + "nativeSrc": "203:16:0", "nodeType": "YulBlock", "src": "60:13:0", "statements": [ @@ -724,7 +724,7 @@ Optimized IR AST: "arguments": [ { "kind": "number", - "nativeSrc": "219:1:0", + "nativeSrc": "212:1:0", "nodeType": "YulLiteral", "src": "60:13:0", "type": "", @@ -732,7 +732,7 @@ Optimized IR AST: }, { "kind": "number", - "nativeSrc": "222:1:0", + "nativeSrc": "215:1:0", "nodeType": "YulLiteral", "src": "60:13:0", "type": "", @@ -741,15 +741,15 @@ Optimized IR AST: ], "functionName": { "name": "revert", - "nativeSrc": "212:6:0", + "nativeSrc": "205:6:0", "nodeType": "YulIdentifier", "src": "60:13:0" }, - "nativeSrc": "212:12:0", + "nativeSrc": "205:12:0", "nodeType": "YulFunctionCall", "src": "60:13:0" }, - "nativeSrc": "212:12:0", + "nativeSrc": "205:12:0", "nodeType": "YulExpressionStatement", "src": "60:13:0" } @@ -759,20 +759,20 @@ Optimized IR AST: "arguments": [], "functionName": { "name": "callvalue", - "nativeSrc": "198:9:0", + "nativeSrc": "191:9:0", "nodeType": "YulIdentifier", "src": "60:13:0" }, - "nativeSrc": "198:11:0", + "nativeSrc": "191:11:0", "nodeType": "YulFunctionCall", "src": "60:13:0" }, - "nativeSrc": "195:31:0", + "nativeSrc": "188:31:0", "nodeType": "YulIf", "src": "60:13:0" }, { - "nativeSrc": "239:34:0", + "nativeSrc": "232:34:0", "nodeType": "YulVariableDeclaration", "src": "60:13:0", "value": { @@ -780,7 +780,7 @@ Optimized IR AST: { "hexValue": "435f325f6465706c6f796564", "kind": "string", - "nativeSrc": "258:14:0", + "nativeSrc": "251:14:0", "nodeType": "YulLiteral", "src": "60:13:0", "type": "", @@ -789,18 +789,18 @@ Optimized IR AST: ], "functionName": { "name": "datasize", - "nativeSrc": "249:8:0", + "nativeSrc": "242:8:0", "nodeType": "YulIdentifier", "src": "60:13:0" }, - "nativeSrc": "249:24:0", + "nativeSrc": "242:24:0", "nodeType": "YulFunctionCall", "src": "60:13:0" }, "variables": [ { "name": "_2", - "nativeSrc": "243:2:0", + "nativeSrc": "236:2:0", "nodeType": "YulTypedName", "src": "60:13:0", "type": "" @@ -812,7 +812,7 @@ Optimized IR AST: "arguments": [ { "name": "_1", - "nativeSrc": "295:2:0", + "nativeSrc": "288:2:0", "nodeType": "YulIdentifier", "src": "60:13:0" }, @@ -821,7 +821,7 @@ Optimized IR AST: { "hexValue": "435f325f6465706c6f796564", "kind": "string", - "nativeSrc": "310:14:0", + "nativeSrc": "303:14:0", "nodeType": "YulLiteral", "src": "60:13:0", "type": "", @@ -830,32 +830,32 @@ Optimized IR AST: ], "functionName": { "name": "dataoffset", - "nativeSrc": "299:10:0", + "nativeSrc": "292:10:0", "nodeType": "YulIdentifier", "src": "60:13:0" }, - "nativeSrc": "299:26:0", + "nativeSrc": "292:26:0", "nodeType": "YulFunctionCall", "src": "60:13:0" }, { "name": "_2", - "nativeSrc": "327:2:0", + "nativeSrc": "320:2:0", "nodeType": "YulIdentifier", "src": "60:13:0" } ], "functionName": { "name": "codecopy", - "nativeSrc": "286:8:0", + "nativeSrc": "279:8:0", "nodeType": "YulIdentifier", "src": "60:13:0" }, - "nativeSrc": "286:44:0", + "nativeSrc": "279:44:0", "nodeType": "YulFunctionCall", "src": "60:13:0" }, - "nativeSrc": "286:44:0", + "nativeSrc": "279:44:0", "nodeType": "YulExpressionStatement", "src": "60:13:0" }, @@ -864,28 +864,28 @@ Optimized IR AST: "arguments": [ { "name": "_1", - "nativeSrc": "350:2:0", + "nativeSrc": "343:2:0", "nodeType": "YulIdentifier", "src": "60:13:0" }, { "name": "_2", - "nativeSrc": "354:2:0", + "nativeSrc": "347:2:0", "nodeType": "YulIdentifier", "src": "60:13:0" } ], "functionName": { "name": "return", - "nativeSrc": "343:6:0", + "nativeSrc": "336:6:0", "nodeType": "YulIdentifier", "src": "60:13:0" }, - "nativeSrc": "343:14:0", + "nativeSrc": "336:14:0", "nodeType": "YulFunctionCall", "src": "60:13:0" }, - "nativeSrc": "343:14:0", + "nativeSrc": "336:14:0", "nodeType": "YulExpressionStatement", "src": "60:13:0" } @@ -901,12 +901,12 @@ Optimized IR AST: { "code": { "block": { - "nativeSrc": "453:118:0", + "nativeSrc": "439:118:0", "nodeType": "YulBlock", "src": "-1:-1:0", "statements": [ { - "nativeSrc": "467:94:0", + "nativeSrc": "453:94:0", "nodeType": "YulBlock", "src": "-1:-1:0", "statements": [ @@ -915,7 +915,7 @@ Optimized IR AST: "arguments": [ { "kind": "number", - "nativeSrc": "542:1:0", + "nativeSrc": "528:1:0", "nodeType": "YulLiteral", "src": "60:13:0", "type": "", @@ -923,7 +923,7 @@ Optimized IR AST: }, { "kind": "number", - "nativeSrc": "545:1:0", + "nativeSrc": "531:1:0", "nodeType": "YulLiteral", "src": "60:13:0", "type": "", @@ -932,15 +932,15 @@ Optimized IR AST: ], "functionName": { "name": "revert", - "nativeSrc": "535:6:0", + "nativeSrc": "521:6:0", "nodeType": "YulIdentifier", "src": "60:13:0" }, - "nativeSrc": "535:12:0", + "nativeSrc": "521:12:0", "nodeType": "YulFunctionCall", "src": "60:13:0" }, - "nativeSrc": "535:12:0", + "nativeSrc": "521:12:0", "nodeType": "YulExpressionStatement", "src": "60:13:0" } diff --git a/test/cmdlineTests/combined_json_abi/output b/test/cmdlineTests/combined_json_abi/output index 79b539db78d0..ee63ccb3ef6f 100644 --- a/test/cmdlineTests/combined_json_abi/output +++ b/test/cmdlineTests/combined_json_abi/output @@ -1,6 +1,6 @@ { "contracts": { - "combined_json_abi/input.sol:C": { + "input.sol:C": { "abi": [] } }, diff --git a/test/cmdlineTests/combined_json_generated_sources/output b/test/cmdlineTests/combined_json_generated_sources/output index db7c86ce13d7..d863bd73a726 100644 --- a/test/cmdlineTests/combined_json_generated_sources/output +++ b/test/cmdlineTests/combined_json_generated_sources/output @@ -1,6 +1,6 @@ { "contracts": { - "combined_json_generated_sources/input.sol:C": { + "input.sol:C": { "generated-sources": [], "generated-sources-runtime": [ { diff --git a/test/cmdlineTests/combined_json_no_pretty_print/output b/test/cmdlineTests/combined_json_no_pretty_print/output index 081dc4fa4eca..34c019b8f792 100644 --- a/test/cmdlineTests/combined_json_no_pretty_print/output +++ b/test/cmdlineTests/combined_json_no_pretty_print/output @@ -1 +1 @@ -{"contracts":{"combined_json_no_pretty_print/input.sol:C":{"abi":[]}},"version": ""} +{"contracts":{"input.sol:C":{"abi":[]}},"version": ""} diff --git a/test/cmdlineTests/combined_json_stop_after_parsing/output b/test/cmdlineTests/combined_json_stop_after_parsing/output index 64e66e3f1227..fa3707bf2488 100644 --- a/test/cmdlineTests/combined_json_stop_after_parsing/output +++ b/test/cmdlineTests/combined_json_stop_after_parsing/output @@ -1,14 +1,14 @@ { "contracts": { - "combined_json_stop_after_parsing/input.sol:C": {} + "input.sol:C": {} }, "sourceList": [ - "combined_json_stop_after_parsing/input.sol" + "input.sol" ], "sources": { - "combined_json_stop_after_parsing/input.sol": { + "input.sol": { "AST": { - "absolutePath": "combined_json_stop_after_parsing/input.sol", + "absolutePath": "input.sol", "id": 3, "license": "GPL-3.0", "nodeType": "SourceUnit", diff --git a/test/cmdlineTests/combined_json_with_base_path/output b/test/cmdlineTests/combined_json_with_base_path/output index 0a3add37e3b4..fe972a631a7a 100644 --- a/test/cmdlineTests/combined_json_with_base_path/output +++ b/test/cmdlineTests/combined_json_with_base_path/output @@ -1,15 +1,15 @@ { "contracts": { - "combined_json_with_base_path/c.sol:C": {} + "c.sol:C": {} }, "sourceList": [ - "combined_json_with_base_path/c.sol", - "combined_json_with_base_path/input.sol" + "c.sol", + "input.sol" ], "sources": { - "combined_json_with_base_path/c.sol": { + "c.sol": { "AST": { - "absolutePath": "combined_json_with_base_path/c.sol", + "absolutePath": "c.sol", "exportedSymbols": { "C": [ 5 @@ -54,9 +54,9 @@ }, "id": 0 }, - "combined_json_with_base_path/input.sol": { + "input.sol": { "AST": { - "absolutePath": "combined_json_with_base_path/input.sol", + "absolutePath": "input.sol", "exportedSymbols": { "C": [ 5 @@ -77,7 +77,7 @@ "src": "36:22:1" }, { - "absolutePath": "combined_json_with_base_path/c.sol", + "absolutePath": "c.sol", "file": "./c.sol", "id": 2, "nameLocation": "-1:-1:-1", diff --git a/test/cmdlineTests/combined_json_with_devdoc/output b/test/cmdlineTests/combined_json_with_devdoc/output index 817018ea6c58..482245fbc4b4 100644 --- a/test/cmdlineTests/combined_json_with_devdoc/output +++ b/test/cmdlineTests/combined_json_with_devdoc/output @@ -1,6 +1,6 @@ { "contracts": { - "combined_json_with_devdoc/input.sol:C": { + "input.sol:C": { "devdoc": { "details": "This is devdoc.", "kind": "dev", @@ -8,7 +8,7 @@ "version": 1 } }, - "combined_json_with_devdoc/input.sol:D": { + "input.sol:D": { "devdoc": { "kind": "dev", "methods": {}, diff --git a/test/cmdlineTests/combined_json_with_userdoc/output b/test/cmdlineTests/combined_json_with_userdoc/output index 4eb56fe24dd2..0e28af093c1c 100644 --- a/test/cmdlineTests/combined_json_with_userdoc/output +++ b/test/cmdlineTests/combined_json_with_userdoc/output @@ -1,6 +1,6 @@ { "contracts": { - "combined_json_with_userdoc/input.sol:C": { + "input.sol:C": { "userdoc": { "kind": "user", "methods": {}, @@ -8,7 +8,7 @@ "version": 1 } }, - "combined_json_with_userdoc/input.sol:D": { + "input.sol:D": { "userdoc": { "kind": "user", "methods": {}, diff --git a/test/cmdlineTests/constant_optimizer_yul/output b/test/cmdlineTests/constant_optimizer_yul/output index 9c7faa732272..c0d3ab934641 100644 --- a/test/cmdlineTests/constant_optimizer_yul/output +++ b/test/cmdlineTests/constant_optimizer_yul/output @@ -1,5 +1,5 @@ Optimized IR: -/// @use-src 0:"constant_optimizer_yul/input.sol" +/// @use-src 0:"input.sol" object "C_12" { code { { @@ -15,7 +15,7 @@ object "C_12" { return(_1, _2) } } - /// @use-src 0:"constant_optimizer_yul/input.sol" + /// @use-src 0:"input.sol" object "C_12_deployed" { code { { diff --git a/test/cmdlineTests/debug_info_in_yul_and_evm_asm_print_all/output b/test/cmdlineTests/debug_info_in_yul_and_evm_asm_print_all/output index 4833a9f620a7..7ad569ba1107 100644 --- a/test/cmdlineTests/debug_info_in_yul_and_evm_asm_print_all/output +++ b/test/cmdlineTests/debug_info_in_yul_and_evm_asm_print_all/output @@ -1,7 +1,7 @@ -======= debug_info_in_yul_and_evm_asm_print_all/input.sol:C ======= +======= input.sol:C ======= EVM assembly: - /* "debug_info_in_yul_and_evm_asm_print_all/input.sol":60:101 contract C {... */ + /* "input.sol":60:101 contract C {... */ mstore(0x40, 0x80) callvalue dup1 @@ -21,7 +21,7 @@ tag_1: stop sub_0: assembly { - /* "debug_info_in_yul_and_evm_asm_print_all/input.sol":60:101 contract C {... */ + /* "input.sol":60:101 contract C {... */ mstore(0x40, 0x80) callvalue dup1 @@ -40,7 +40,7 @@ sub_0: assembly { jumpi tag_2: revert(0x00, 0x00) - /* "debug_info_in_yul_and_evm_asm_print_all/input.sol":77:99 function f() public {} */ + /* "input.sol":77:99 function f() public {} */ tag_3: stop @@ -49,7 +49,7 @@ sub_0: assembly { IR: -/// @use-src 0:"debug_info_in_yul_and_evm_asm_print_all/input.sol" +/// @use-src 0:"input.sol" object "C_6" { code { /// @src 0:60:101 "contract C {..." @@ -80,7 +80,7 @@ object "C_6" { /// @src 0:60:101 "contract C {..." } - /// @use-src 0:"debug_info_in_yul_and_evm_asm_print_all/input.sol" + /// @use-src 0:"input.sol" object "C_6_deployed" { code { /// @src 0:60:101 "contract C {..." @@ -163,7 +163,7 @@ object "C_6" { Optimized IR: -/// @use-src 0:"debug_info_in_yul_and_evm_asm_print_all/input.sol" +/// @use-src 0:"input.sol" object "C_6" { code { { @@ -176,7 +176,7 @@ object "C_6" { return(_1, _2) } } - /// @use-src 0:"debug_info_in_yul_and_evm_asm_print_all/input.sol" + /// @use-src 0:"input.sol" object "C_6_deployed" { code { { diff --git a/test/cmdlineTests/debug_info_in_yul_and_evm_asm_print_location_only/output b/test/cmdlineTests/debug_info_in_yul_and_evm_asm_print_location_only/output index 00b04a01ad1f..36ef4d8294ab 100644 --- a/test/cmdlineTests/debug_info_in_yul_and_evm_asm_print_location_only/output +++ b/test/cmdlineTests/debug_info_in_yul_and_evm_asm_print_location_only/output @@ -1,7 +1,7 @@ -======= debug_info_in_yul_and_evm_asm_print_location_only/input.sol:C ======= +======= input.sol:C ======= EVM assembly: - /* "debug_info_in_yul_and_evm_asm_print_location_only/input.sol":60:101 */ + /* "input.sol":60:101 */ mstore(0x40, 0x80) callvalue dup1 @@ -21,7 +21,7 @@ tag_1: stop sub_0: assembly { - /* "debug_info_in_yul_and_evm_asm_print_location_only/input.sol":60:101 */ + /* "input.sol":60:101 */ mstore(0x40, 0x80) callvalue dup1 @@ -40,7 +40,7 @@ sub_0: assembly { jumpi tag_2: revert(0x00, 0x00) - /* "debug_info_in_yul_and_evm_asm_print_location_only/input.sol":77:99 */ + /* "input.sol":77:99 */ tag_3: stop @@ -49,7 +49,7 @@ sub_0: assembly { IR: -/// @use-src 0:"debug_info_in_yul_and_evm_asm_print_location_only/input.sol" +/// @use-src 0:"input.sol" object "C_6" { code { /// @src 0:60:101 @@ -80,7 +80,7 @@ object "C_6" { /// @src 0:60:101 } - /// @use-src 0:"debug_info_in_yul_and_evm_asm_print_location_only/input.sol" + /// @use-src 0:"input.sol" object "C_6_deployed" { code { /// @src 0:60:101 @@ -162,7 +162,7 @@ object "C_6" { Optimized IR: -/// @use-src 0:"debug_info_in_yul_and_evm_asm_print_location_only/input.sol" +/// @use-src 0:"input.sol" object "C_6" { code { { @@ -175,7 +175,7 @@ object "C_6" { return(_1, _2) } } - /// @use-src 0:"debug_info_in_yul_and_evm_asm_print_location_only/input.sol" + /// @use-src 0:"input.sol" object "C_6_deployed" { code { { diff --git a/test/cmdlineTests/debug_info_in_yul_and_evm_asm_print_none/output b/test/cmdlineTests/debug_info_in_yul_and_evm_asm_print_none/output index 9527edf769a4..ea3cb35a2849 100644 --- a/test/cmdlineTests/debug_info_in_yul_and_evm_asm_print_none/output +++ b/test/cmdlineTests/debug_info_in_yul_and_evm_asm_print_none/output @@ -1,5 +1,5 @@ -======= debug_info_in_yul_and_evm_asm_print_none/input.sol:C ======= +======= input.sol:C ======= EVM assembly: mstore(0x40, 0x80) callvalue @@ -46,7 +46,7 @@ sub_0: assembly { IR: -/// @use-src 0:"debug_info_in_yul_and_evm_asm_print_none/input.sol" +/// @use-src 0:"input.sol" object "C_6" { code { @@ -73,7 +73,7 @@ object "C_6" { } } - /// @use-src 0:"debug_info_in_yul_and_evm_asm_print_none/input.sol" + /// @use-src 0:"input.sol" object "C_6_deployed" { code { @@ -153,7 +153,7 @@ object "C_6" { Optimized IR: -/// @use-src 0:"debug_info_in_yul_and_evm_asm_print_none/input.sol" +/// @use-src 0:"input.sol" object "C_6" { code { { @@ -165,7 +165,7 @@ object "C_6" { return(_1, _2) } } - /// @use-src 0:"debug_info_in_yul_and_evm_asm_print_none/input.sol" + /// @use-src 0:"input.sol" object "C_6_deployed" { code { { diff --git a/test/cmdlineTests/debug_info_in_yul_snippet_escaping/output b/test/cmdlineTests/debug_info_in_yul_snippet_escaping/output index 975582f669ba..c29dfd89265d 100644 --- a/test/cmdlineTests/debug_info_in_yul_snippet_escaping/output +++ b/test/cmdlineTests/debug_info_in_yul_snippet_escaping/output @@ -1,6 +1,6 @@ IR: -/// @use-src 0:"debug_info_in_yul_snippet_escaping/input.sol" +/// @use-src 0:"input.sol" object "C_2" { code { /// @src 0:265:278 "contract C {}" @@ -31,7 +31,7 @@ object "C_2" { /// @src 0:265:278 "contract C {}" } - /// @use-src 0:"debug_info_in_yul_snippet_escaping/input.sol" + /// @use-src 0:"input.sol" object "C_2_deployed" { code { /// @src 0:265:278 "contract C {}" @@ -63,7 +63,7 @@ object "C_2" { Optimized IR: -/// @use-src 0:"debug_info_in_yul_snippet_escaping/input.sol" +/// @use-src 0:"input.sol" object "C_2" { code { { @@ -76,7 +76,7 @@ object "C_2" { return(_1, _2) } } - /// @use-src 0:"debug_info_in_yul_snippet_escaping/input.sol" + /// @use-src 0:"input.sol" object "C_2_deployed" { code { { @@ -90,7 +90,7 @@ object "C_2" { IR: -/// @use-src 0:"debug_info_in_yul_snippet_escaping/input.sol" +/// @use-src 0:"input.sol" object "D_27" { code { /// @src 0:279:599 "contract D /** @src 0:96:165 \"contract D {...\" *\/ {..." @@ -121,7 +121,7 @@ object "D_27" { /// @src 0:279:599 "contract D /** @src 0:96:165 \"contract D {...\" *\/ {..." } - /// @use-src 0:"debug_info_in_yul_snippet_escaping/input.sol" + /// @use-src 0:"input.sol" object "D_27_deployed" { code { /// @src 0:279:599 "contract D /** @src 0:96:165 \"contract D {...\" *\/ {..." @@ -342,7 +342,7 @@ object "D_27" { } - /// @use-src 0:"debug_info_in_yul_snippet_escaping/input.sol" + /// @use-src 0:"input.sol" object "C_2" { code { /// @src 0:265:278 "contract C {}" @@ -373,7 +373,7 @@ object "D_27" { /// @src 0:265:278 "contract C {}" } - /// @use-src 0:"debug_info_in_yul_snippet_escaping/input.sol" + /// @use-src 0:"input.sol" object "C_2_deployed" { code { /// @src 0:265:278 "contract C {}" @@ -410,7 +410,7 @@ object "D_27" { Optimized IR: -/// @use-src 0:"debug_info_in_yul_snippet_escaping/input.sol" +/// @use-src 0:"input.sol" object "D_27" { code { { @@ -423,7 +423,7 @@ object "D_27" { return(_1, _2) } } - /// @use-src 0:"debug_info_in_yul_snippet_escaping/input.sol" + /// @use-src 0:"input.sol" object "D_27_deployed" { code { { @@ -499,7 +499,7 @@ object "D_27" { revert(0, 0) } } - /// @use-src 0:"debug_info_in_yul_snippet_escaping/input.sol" + /// @use-src 0:"input.sol" object "C_2" { code { { @@ -512,7 +512,7 @@ object "D_27" { return(_1, _2) } } - /// @use-src 0:"debug_info_in_yul_snippet_escaping/input.sol" + /// @use-src 0:"input.sol" object "C_2_deployed" { code { { diff --git a/test/cmdlineTests/dup_opt_peephole/output b/test/cmdlineTests/dup_opt_peephole/output index a9e0203ed1ff..f53e9e2bdb17 100644 --- a/test/cmdlineTests/dup_opt_peephole/output +++ b/test/cmdlineTests/dup_opt_peephole/output @@ -1,7 +1,7 @@ -======= dup_opt_peephole/input.sol:C ======= +======= input.sol:C ======= EVM assembly: - /* "dup_opt_peephole/input.sol":60:171 contract C {... */ + /* "input.sol":60:171 contract C {... */ mstore(0x40, 0x80) callvalue dup1 @@ -21,7 +21,7 @@ tag_1: stop sub_0: assembly { - /* "dup_opt_peephole/input.sol":60:171 contract C {... */ + /* "input.sol":60:171 contract C {... */ mstore(0x40, 0x80) callvalue dup1 @@ -31,17 +31,17 @@ sub_0: assembly { revert(0x00, 0x00) tag_3: pop - /* "dup_opt_peephole/input.sol":134:135 0 */ + /* "input.sol":134:135 0 */ 0x00 - /* "dup_opt_peephole/input.sol":121:136 calldataload(0) */ + /* "input.sol":121:136 calldataload(0) */ calldataload - /* "dup_opt_peephole/input.sol":160:161 x */ + /* "input.sol":160:161 x */ dup1 - /* "dup_opt_peephole/input.sol":157:158 0 */ + /* "input.sol":157:158 0 */ 0x00 - /* "dup_opt_peephole/input.sol":150:162 sstore(0, x) */ + /* "input.sol":150:162 sstore(0, x) */ sstore - /* "dup_opt_peephole/input.sol":107:166 {... */ + /* "input.sol":107:166 {... */ stop auxdata: diff --git a/test/cmdlineTests/error_codes/err b/test/cmdlineTests/error_codes/err index a10362a863a8..f3f6fe33905c 100644 --- a/test/cmdlineTests/error_codes/err +++ b/test/cmdlineTests/error_codes/err @@ -1,29 +1,29 @@ Warning (1878): SPDX license identifier not provided in source file. Before publishing, consider adding a comment containing "SPDX-License-Identifier: " to each source file. Use "SPDX-License-Identifier: UNLICENSED" for non-open-source code. Please see https://spdx.org for more information. ---> error_codes/input.sol +--> input.sol Error (4937): No visibility specified. Did you intend to add "public"? - --> error_codes/input.sol:2:5: + --> input.sol:2:5: | 2 | function f() { | ^ (Relevant source part starts here and spans across multiple lines). Warning (3420): Source file does not specify required compiler version! ---> error_codes/input.sol +--> input.sol Error (4247): Expression has to be an lvalue. - --> error_codes/input.sol:3:9: + --> input.sol:3:9: | 3 | 2=0; | ^ Error (7407): Type int_const 0 is not implicitly convertible to expected type int_const 2. - --> error_codes/input.sol:3:11: + --> input.sol:3:11: | 3 | 2=0; | ^ Error (2614): Indexed expression has to be a type, mapping or array (is literal_string "") - --> error_codes/input.sol:4:9: + --> input.sol:4:9: | 4 | ""[2]; | ^^ diff --git a/test/cmdlineTests/ethdebug_eof_container_osaka/output b/test/cmdlineTests/ethdebug_eof_container_osaka/output index 9d002fadc317..b29297ee3749 100644 --- a/test/cmdlineTests/ethdebug_eof_container_osaka/output +++ b/test/cmdlineTests/ethdebug_eof_container_osaka/output @@ -1,4 +1,4 @@ ======= Debug Data (ethdebug/format/info/resources) ======= -{"compilation":{"compiler":{"name":"solc","version": ""},"sources":[{"id":0,"path":"ethdebug_eof_container_osaka/input.sol"}]}} +{"compilation":{"compiler":{"name":"solc","version": ""},"sources":[{"id":0,"path":"input.sol"}]}} -======= ethdebug_eof_container_osaka/input.sol:C ======= +======= input.sol:C ======= diff --git a/test/cmdlineTests/events_in_abi/output b/test/cmdlineTests/events_in_abi/output index ab246ef24a15..220e65ef4a9f 100644 --- a/test/cmdlineTests/events_in_abi/output +++ b/test/cmdlineTests/events_in_abi/output @@ -1,5 +1,5 @@ -======= events_in_abi/input.sol:C ======= +======= input.sol:C ======= Contract JSON ABI [ { @@ -37,7 +37,7 @@ Contract JSON ABI } ] -======= events_in_abi/input.sol:L ======= +======= input.sol:L ======= Contract JSON ABI [ { diff --git a/test/cmdlineTests/evm_version_byzantium/err b/test/cmdlineTests/evm_version_byzantium/err index accbb596cb25..6815a852460a 100644 --- a/test/cmdlineTests/evm_version_byzantium/err +++ b/test/cmdlineTests/evm_version_byzantium/err @@ -1,3 +1,3 @@ Warning: Support for EVM versions older than constantinople is deprecated and will be removed in the future. Warning: Source file does not specify required compiler version! ---> evm_version_byzantium/input.sol +--> input.sol diff --git a/test/cmdlineTests/evm_version_constantinople/err b/test/cmdlineTests/evm_version_constantinople/err index 69f328f54efd..e3815925acb9 100644 --- a/test/cmdlineTests/evm_version_constantinople/err +++ b/test/cmdlineTests/evm_version_constantinople/err @@ -1,2 +1,2 @@ Warning: Source file does not specify required compiler version! ---> evm_version_constantinople/input.sol +--> input.sol diff --git a/test/cmdlineTests/evmasm_difficulty_post_paris/err b/test/cmdlineTests/evmasm_difficulty_post_paris/err index d8210184e1b0..8498f4c460c7 100644 --- a/test/cmdlineTests/evmasm_difficulty_post_paris/err +++ b/test/cmdlineTests/evmasm_difficulty_post_paris/err @@ -1,5 +1,5 @@ Warning: Since the VM version paris, "difficulty" was replaced by "prevrandao", which now returns a random number based on the beacon chain. - --> evmasm_difficulty_post_paris/input.sol:6:21: + --> input.sol:6:21: | 6 | uint256 x = block.difficulty; | ^^^^^^^^^^^^^^^^ diff --git a/test/cmdlineTests/evmasm_difficulty_post_paris/output b/test/cmdlineTests/evmasm_difficulty_post_paris/output index f8c1611e0274..6ade453b9735 100644 --- a/test/cmdlineTests/evmasm_difficulty_post_paris/output +++ b/test/cmdlineTests/evmasm_difficulty_post_paris/output @@ -1,5 +1,5 @@ -======= evmasm_difficulty_post_paris/input.sol:C ======= +======= input.sol:C ======= EVM assembly: sstore(0x00, prevrandao) stop diff --git a/test/cmdlineTests/evmasm_difficulty_pre_paris/output b/test/cmdlineTests/evmasm_difficulty_pre_paris/output index ad75355f5bcb..26456f276fb7 100644 --- a/test/cmdlineTests/evmasm_difficulty_pre_paris/output +++ b/test/cmdlineTests/evmasm_difficulty_pre_paris/output @@ -1,5 +1,5 @@ -======= evmasm_difficulty_pre_paris/input.sol:C ======= +======= input.sol:C ======= EVM assembly: sstore(0x00, difficulty) stop diff --git a/test/cmdlineTests/evmasm_prevrandao_post_paris/output b/test/cmdlineTests/evmasm_prevrandao_post_paris/output index 47c85bb50fcd..6ade453b9735 100644 --- a/test/cmdlineTests/evmasm_prevrandao_post_paris/output +++ b/test/cmdlineTests/evmasm_prevrandao_post_paris/output @@ -1,5 +1,5 @@ -======= evmasm_prevrandao_post_paris/input.sol:C ======= +======= input.sol:C ======= EVM assembly: sstore(0x00, prevrandao) stop diff --git a/test/cmdlineTests/evmasm_prevrandao_pre_paris/err b/test/cmdlineTests/evmasm_prevrandao_pre_paris/err index 5970ec202066..429c06395086 100644 --- a/test/cmdlineTests/evmasm_prevrandao_pre_paris/err +++ b/test/cmdlineTests/evmasm_prevrandao_pre_paris/err @@ -1,5 +1,5 @@ Warning: "prevrandao" is not supported by the VM version and will be treated as "difficulty". - --> evmasm_prevrandao_pre_paris/input.sol:6:21: + --> input.sol:6:21: | 6 | uint256 x = block.prevrandao; | ^^^^^^^^^^^^^^^^ diff --git a/test/cmdlineTests/evmasm_prevrandao_pre_paris/output b/test/cmdlineTests/evmasm_prevrandao_pre_paris/output index e41148a8331a..26456f276fb7 100644 --- a/test/cmdlineTests/evmasm_prevrandao_pre_paris/output +++ b/test/cmdlineTests/evmasm_prevrandao_pre_paris/output @@ -1,5 +1,5 @@ -======= evmasm_prevrandao_pre_paris/input.sol:C ======= +======= input.sol:C ======= EVM assembly: sstore(0x00, difficulty) stop diff --git a/test/cmdlineTests/evmasm_transient_storage_inline_assembly/err b/test/cmdlineTests/evmasm_transient_storage_inline_assembly/err index 2e52d9ced0c6..6b7f432f2c92 100644 --- a/test/cmdlineTests/evmasm_transient_storage_inline_assembly/err +++ b/test/cmdlineTests/evmasm_transient_storage_inline_assembly/err @@ -1,5 +1,5 @@ Warning: Transient storage as defined by EIP-1153 can break the composability of smart contracts: Since transient storage is cleared only at the end of the transaction and not at the end of the outermost call frame to the contract within a transaction, your contract may unintentionally misbehave when invoked multiple times in a complex transaction. To avoid this, be sure to clear all transient storage at the end of any call to your contract. The use of transient storage for reentrancy guards that are cleared at the end of the call is safe. - --> evmasm_transient_storage_inline_assembly/input.sol:7:13: + --> input.sol:7:13: | 7 | tstore(0, 123) | ^^^^^^ diff --git a/test/cmdlineTests/evmasm_transient_storage_inline_assembly/output b/test/cmdlineTests/evmasm_transient_storage_inline_assembly/output index 0b4c516baef3..adeb0822c610 100644 --- a/test/cmdlineTests/evmasm_transient_storage_inline_assembly/output +++ b/test/cmdlineTests/evmasm_transient_storage_inline_assembly/output @@ -1,5 +1,5 @@ -======= evmasm_transient_storage_inline_assembly/input.sol:C ======= +======= input.sol:C ======= EVM assembly: mstore(0x40, 0x80) callvalue diff --git a/test/cmdlineTests/evmasm_transient_storage_inline_assembly_via_ir/err b/test/cmdlineTests/evmasm_transient_storage_inline_assembly_via_ir/err index 154da21b6577..6b7f432f2c92 100644 --- a/test/cmdlineTests/evmasm_transient_storage_inline_assembly_via_ir/err +++ b/test/cmdlineTests/evmasm_transient_storage_inline_assembly_via_ir/err @@ -1,5 +1,5 @@ Warning: Transient storage as defined by EIP-1153 can break the composability of smart contracts: Since transient storage is cleared only at the end of the transaction and not at the end of the outermost call frame to the contract within a transaction, your contract may unintentionally misbehave when invoked multiple times in a complex transaction. To avoid this, be sure to clear all transient storage at the end of any call to your contract. The use of transient storage for reentrancy guards that are cleared at the end of the call is safe. - --> evmasm_transient_storage_inline_assembly_via_ir/input.sol:7:13: + --> input.sol:7:13: | 7 | tstore(0, 123) | ^^^^^^ diff --git a/test/cmdlineTests/evmasm_transient_storage_inline_assembly_via_ir/output b/test/cmdlineTests/evmasm_transient_storage_inline_assembly_via_ir/output index 673bdd0a052d..754bc9d455a7 100644 --- a/test/cmdlineTests/evmasm_transient_storage_inline_assembly_via_ir/output +++ b/test/cmdlineTests/evmasm_transient_storage_inline_assembly_via_ir/output @@ -1,5 +1,5 @@ -======= evmasm_transient_storage_inline_assembly_via_ir/input.sol:C ======= +======= input.sol:C ======= EVM assembly: 0x80 dup1 diff --git a/test/cmdlineTests/evmasm_transient_storage_state_variable/output b/test/cmdlineTests/evmasm_transient_storage_state_variable/output index e80eb3c57fc7..0f2580c80564 100644 --- a/test/cmdlineTests/evmasm_transient_storage_state_variable/output +++ b/test/cmdlineTests/evmasm_transient_storage_state_variable/output @@ -1,5 +1,5 @@ -======= evmasm_transient_storage_state_variable/input.sol:C ======= +======= input.sol:C ======= EVM assembly: mstore(0x40, 0x80) callvalue diff --git a/test/cmdlineTests/evmasm_transient_storage_state_variable_via_ir/output b/test/cmdlineTests/evmasm_transient_storage_state_variable_via_ir/output index 5959fad952f1..b2f55e1d5724 100644 --- a/test/cmdlineTests/evmasm_transient_storage_state_variable_via_ir/output +++ b/test/cmdlineTests/evmasm_transient_storage_state_variable_via_ir/output @@ -1,5 +1,5 @@ -======= evmasm_transient_storage_state_variable_via_ir/input.sol:C ======= +======= input.sol:C ======= EVM assembly: 0x80 dup1 diff --git a/test/cmdlineTests/exp_base_literal/output b/test/cmdlineTests/exp_base_literal/output index 24e5d29be756..fb5b35ed0fba 100644 --- a/test/cmdlineTests/exp_base_literal/output +++ b/test/cmdlineTests/exp_base_literal/output @@ -1,6 +1,6 @@ IR: -/// @use-src 0:"exp_base_literal/input.sol" +/// @use-src 0:"input.sol" object "C_81" { code { /// @src 0:82:370 "contract C {..." @@ -31,7 +31,7 @@ object "C_81" { /// @src 0:82:370 "contract C {..." } - /// @use-src 0:"exp_base_literal/input.sol" + /// @use-src 0:"input.sol" object "C_81_deployed" { code { /// @src 0:82:370 "contract C {..." diff --git a/test/cmdlineTests/function_debug_info/output b/test/cmdlineTests/function_debug_info/output index c1346e33ab0c..aa4512352623 100644 --- a/test/cmdlineTests/function_debug_info/output +++ b/test/cmdlineTests/function_debug_info/output @@ -1,6 +1,6 @@ { "contracts": { - "function_debug_info/input.sol:C": { + "input.sol:C": { "function-debug": { "@_34": { "id": 34, diff --git a/test/cmdlineTests/function_debug_info_via_yul/output b/test/cmdlineTests/function_debug_info_via_yul/output index 05c2da48c607..c3a828ab30f0 100644 --- a/test/cmdlineTests/function_debug_info_via_yul/output +++ b/test/cmdlineTests/function_debug_info_via_yul/output @@ -1,6 +1,6 @@ { "contracts": { - "function_debug_info_via_yul/input.sol:C": { + "input.sol:C": { "function-debug": {}, "function-debug-runtime": {} } diff --git a/test/cmdlineTests/hashes/output b/test/cmdlineTests/hashes/output index b010456d3901..45eb1835900a 100644 --- a/test/cmdlineTests/hashes/output +++ b/test/cmdlineTests/hashes/output @@ -1,5 +1,5 @@ -======= hashes/input.sol:C ======= +======= input.sol:C ======= Function signatures: 3fc03eeb: f((uint256)) @@ -12,7 +12,7 @@ Event signatures: 2d4dd5fe18ada5a020a9f5591539a8dc3010a5c074ba6a70e1c956659f02786a: ev(uint256) 81f3fb02f88d32d3bb08c80c9a622ca3b3223292f131c6ad049811f9a8a606dc: libraryEvent(uint256) -======= hashes/input.sol:L ======= +======= input.sol:L ======= Function signatures: Error signatures: diff --git a/test/cmdlineTests/inline_assembly_function_name_clash/err b/test/cmdlineTests/inline_assembly_function_name_clash/err index 5284ffe5ca89..892a312d0f26 100644 --- a/test/cmdlineTests/inline_assembly_function_name_clash/err +++ b/test/cmdlineTests/inline_assembly_function_name_clash/err @@ -1,5 +1,5 @@ Warning: SPDX license identifier not provided in source file. Before publishing, consider adding a comment containing "SPDX-License-Identifier: " to each source file. Use "SPDX-License-Identifier: UNLICENSED" for non-open-source code. Please see https://spdx.org for more information. ---> inline_assembly_function_name_clash/input.sol +--> input.sol Warning: Source file does not specify required compiler version! ---> inline_assembly_function_name_clash/input.sol +--> input.sol diff --git a/test/cmdlineTests/inline_assembly_function_name_clash/output b/test/cmdlineTests/inline_assembly_function_name_clash/output index 2fd6ff1f5592..d21576ff0ba0 100644 --- a/test/cmdlineTests/inline_assembly_function_name_clash/output +++ b/test/cmdlineTests/inline_assembly_function_name_clash/output @@ -1,6 +1,6 @@ { "contracts": { - "inline_assembly_function_name_clash/input.sol:C": { + "input.sol:C": { "function-debug-runtime": { "abi_decode": { "entryPoint": 80, diff --git a/test/cmdlineTests/ir_compiler_inheritance_nosubobjects/output b/test/cmdlineTests/ir_compiler_inheritance_nosubobjects/output index 84fd9d0bc35f..2d715d0abaad 100644 --- a/test/cmdlineTests/ir_compiler_inheritance_nosubobjects/output +++ b/test/cmdlineTests/ir_compiler_inheritance_nosubobjects/output @@ -1,5 +1,5 @@ Optimized IR: -/// @use-src 0:"ir_compiler_inheritance_nosubobjects/input.sol" +/// @use-src 0:"input.sol" object "C_7" { code { { @@ -12,7 +12,7 @@ object "C_7" { return(_1, _2) } } - /// @use-src 0:"ir_compiler_inheritance_nosubobjects/input.sol" + /// @use-src 0:"input.sol" object "C_7_deployed" { code { { @@ -25,7 +25,7 @@ object "C_7" { } Optimized IR: -/// @use-src 0:"ir_compiler_inheritance_nosubobjects/input.sol" +/// @use-src 0:"input.sol" object "D_10" { code { { @@ -38,7 +38,7 @@ object "D_10" { return(_1, _2) } } - /// @use-src 0:"ir_compiler_inheritance_nosubobjects/input.sol" + /// @use-src 0:"input.sol" object "D_10_deployed" { code { { diff --git a/test/cmdlineTests/ir_compiler_subobjects/err b/test/cmdlineTests/ir_compiler_subobjects/err index b300ec124361..66ebf4229caf 100644 --- a/test/cmdlineTests/ir_compiler_subobjects/err +++ b/test/cmdlineTests/ir_compiler_subobjects/err @@ -1,5 +1,5 @@ Warning: Unused local variable. - --> ir_compiler_subobjects/input.sol:8:9: + --> input.sol:8:9: | 8 | C c = new C(); | ^^^ diff --git a/test/cmdlineTests/ir_compiler_subobjects/output b/test/cmdlineTests/ir_compiler_subobjects/output index 39ef53f5529b..08ee8bf5d0b5 100644 --- a/test/cmdlineTests/ir_compiler_subobjects/output +++ b/test/cmdlineTests/ir_compiler_subobjects/output @@ -1,5 +1,5 @@ Optimized IR: -/// @use-src 0:"ir_compiler_subobjects/input.sol" +/// @use-src 0:"input.sol" object "C_3" { code { { @@ -12,7 +12,7 @@ object "C_3" { return(_1, _2) } } - /// @use-src 0:"ir_compiler_subobjects/input.sol" + /// @use-src 0:"input.sol" object "C_3_deployed" { code { { @@ -25,7 +25,7 @@ object "C_3" { } Optimized IR: -/// @use-src 0:"ir_compiler_subobjects/input.sol" +/// @use-src 0:"input.sol" object "D_16" { code { { @@ -38,7 +38,7 @@ object "D_16" { return(_1, _2) } } - /// @use-src 0:"ir_compiler_subobjects/input.sol" + /// @use-src 0:"input.sol" object "D_16_deployed" { code { { @@ -76,7 +76,7 @@ object "D_16" { revert(0, 0) } } - /// @use-src 0:"ir_compiler_subobjects/input.sol" + /// @use-src 0:"input.sol" object "C_3" { code { { @@ -89,7 +89,7 @@ object "D_16" { return(_1, _2) } } - /// @use-src 0:"ir_compiler_subobjects/input.sol" + /// @use-src 0:"input.sol" object "C_3_deployed" { code { { diff --git a/test/cmdlineTests/ir_optimized_transient_storage_value_type/output b/test/cmdlineTests/ir_optimized_transient_storage_value_type/output index 61d289e3f9e0..2f6918cabb36 100644 --- a/test/cmdlineTests/ir_optimized_transient_storage_value_type/output +++ b/test/cmdlineTests/ir_optimized_transient_storage_value_type/output @@ -1,5 +1,5 @@ Optimized IR: -/// @use-src 0:"ir_optimized_transient_storage_value_type/input.sol" +/// @use-src 0:"input.sol" object "C_14" { code { { @@ -11,7 +11,7 @@ object "C_14" { return(_1, _2) } } - /// @use-src 0:"ir_optimized_transient_storage_value_type/input.sol" + /// @use-src 0:"input.sol" object "C_14_deployed" { code { { diff --git a/test/cmdlineTests/ir_optimized_with_optimize/output b/test/cmdlineTests/ir_optimized_with_optimize/output index 8790e45d353d..bae07ea4eb05 100644 --- a/test/cmdlineTests/ir_optimized_with_optimize/output +++ b/test/cmdlineTests/ir_optimized_with_optimize/output @@ -1,5 +1,5 @@ Optimized IR: -/// @use-src 0:"ir_optimized_with_optimize/input.sol" +/// @use-src 0:"input.sol" object "C_2" { code { { @@ -11,7 +11,7 @@ object "C_2" { return(_1, _2) } } - /// @use-src 0:"ir_optimized_with_optimize/input.sol" + /// @use-src 0:"input.sol" object "C_2_deployed" { code { { revert(0, 0) } } data ".metadata" hex"" diff --git a/test/cmdlineTests/ir_subobject_order/output b/test/cmdlineTests/ir_subobject_order/output index da4390fff055..d41b65bf9a62 100644 --- a/test/cmdlineTests/ir_subobject_order/output +++ b/test/cmdlineTests/ir_subobject_order/output @@ -1,8 +1,8 @@ Optimized IR: -/// @use-src 0:"ir_subobject_order/input.sol" +/// @use-src 0:"input.sol" object "A_13" { code { { revert(0, 0) } } - /// @use-src 0:"ir_subobject_order/input.sol" + /// @use-src 0:"input.sol" object "A_13_deployed" { code { { revert(0, 0) } } data ".metadata" hex"" @@ -10,10 +10,10 @@ object "A_13" { } Optimized IR: -/// @use-src 0:"ir_subobject_order/input.sol" +/// @use-src 0:"input.sol" object "B_7" { code { { revert(0, 0) } } - /// @use-src 0:"ir_subobject_order/input.sol" + /// @use-src 0:"input.sol" object "B_7_deployed" { code { { revert(0, 0) } } data ".metadata" hex"" @@ -21,7 +21,7 @@ object "B_7" { } Optimized IR: -/// @use-src 0:"ir_subobject_order/input.sol" +/// @use-src 0:"input.sol" object "C_33" { code { { @@ -69,24 +69,24 @@ object "C_33" { return(_7, _8) } } - /// @use-src 0:"ir_subobject_order/input.sol" + /// @use-src 0:"input.sol" object "C_33_deployed" { code { { revert(0, 0) } } data ".metadata" hex"" } - /// @use-src 0:"ir_subobject_order/input.sol" + /// @use-src 0:"input.sol" object "A_13" { code { { revert(0, 0) } } - /// @use-src 0:"ir_subobject_order/input.sol" + /// @use-src 0:"input.sol" object "A_13_deployed" { code { { revert(0, 0) } } data ".metadata" hex"" } } - /// @use-src 0:"ir_subobject_order/input.sol" + /// @use-src 0:"input.sol" object "B_7" { code { { revert(0, 0) } } - /// @use-src 0:"ir_subobject_order/input.sol" + /// @use-src 0:"input.sol" object "B_7_deployed" { code { { revert(0, 0) } } data ".metadata" hex"" diff --git a/test/cmdlineTests/ir_unoptimized_with_optimize/output b/test/cmdlineTests/ir_unoptimized_with_optimize/output index c5307123f0f5..b34558d2a49f 100644 --- a/test/cmdlineTests/ir_unoptimized_with_optimize/output +++ b/test/cmdlineTests/ir_unoptimized_with_optimize/output @@ -1,6 +1,6 @@ IR: -/// @use-src 0:"ir_unoptimized_with_optimize/input.sol" +/// @use-src 0:"input.sol" object "C_2" { code { @@ -27,7 +27,7 @@ object "C_2" { } } - /// @use-src 0:"ir_unoptimized_with_optimize/input.sol" + /// @use-src 0:"input.sol" object "C_2_deployed" { code { diff --git a/test/cmdlineTests/ir_unoptimized_with_optimize_via_ir/output b/test/cmdlineTests/ir_unoptimized_with_optimize_via_ir/output index f5ecdd8bf5f0..b34558d2a49f 100644 --- a/test/cmdlineTests/ir_unoptimized_with_optimize_via_ir/output +++ b/test/cmdlineTests/ir_unoptimized_with_optimize_via_ir/output @@ -1,6 +1,6 @@ IR: -/// @use-src 0:"ir_unoptimized_with_optimize_via_ir/input.sol" +/// @use-src 0:"input.sol" object "C_2" { code { @@ -27,7 +27,7 @@ object "C_2" { } } - /// @use-src 0:"ir_unoptimized_with_optimize_via_ir/input.sol" + /// @use-src 0:"input.sol" object "C_2_deployed" { code { diff --git a/test/cmdlineTests/ir_with_assembly_no_memoryguard_creation/output b/test/cmdlineTests/ir_with_assembly_no_memoryguard_creation/output index 5c822949a409..03f5564200bf 100644 --- a/test/cmdlineTests/ir_with_assembly_no_memoryguard_creation/output +++ b/test/cmdlineTests/ir_with_assembly_no_memoryguard_creation/output @@ -1,5 +1,5 @@ Optimized IR: -/// @use-src 0:"ir_with_assembly_no_memoryguard_creation/input.sol" +/// @use-src 0:"input.sol" object "D_12" { code { { @@ -10,7 +10,7 @@ object "D_12" { return(128, _1) } } - /// @use-src 0:"ir_with_assembly_no_memoryguard_creation/input.sol" + /// @use-src 0:"input.sol" object "D_12_deployed" { code { { diff --git a/test/cmdlineTests/ir_with_assembly_no_memoryguard_runtime/output b/test/cmdlineTests/ir_with_assembly_no_memoryguard_runtime/output index f6be1493ec79..9d07cd910e9f 100644 --- a/test/cmdlineTests/ir_with_assembly_no_memoryguard_runtime/output +++ b/test/cmdlineTests/ir_with_assembly_no_memoryguard_runtime/output @@ -1,5 +1,5 @@ Optimized IR: -/// @use-src 0:"ir_with_assembly_no_memoryguard_runtime/input.sol" +/// @use-src 0:"input.sol" object "D_8" { code { { @@ -12,7 +12,7 @@ object "D_8" { return(_1, _2) } } - /// @use-src 0:"ir_with_assembly_no_memoryguard_runtime/input.sol" + /// @use-src 0:"input.sol" object "D_8_deployed" { code { { diff --git a/test/cmdlineTests/keccak_optimization_deploy_code/output b/test/cmdlineTests/keccak_optimization_deploy_code/output index 8b89ea5b6329..839e675210e7 100644 --- a/test/cmdlineTests/keccak_optimization_deploy_code/output +++ b/test/cmdlineTests/keccak_optimization_deploy_code/output @@ -1,5 +1,5 @@ Optimized IR: -/// @use-src 0:"keccak_optimization_deploy_code/input.sol" +/// @use-src 0:"input.sol" object "C_12" { code { { @@ -14,7 +14,7 @@ object "C_12" { return(128, _1) } } - /// @use-src 0:"keccak_optimization_deploy_code/input.sol" + /// @use-src 0:"input.sol" object "C_12_deployed" { code { { diff --git a/test/cmdlineTests/keccak_optimization_low_runs/output b/test/cmdlineTests/keccak_optimization_low_runs/output index c308d737b2f5..328bdd59e621 100644 --- a/test/cmdlineTests/keccak_optimization_low_runs/output +++ b/test/cmdlineTests/keccak_optimization_low_runs/output @@ -1,5 +1,5 @@ Optimized IR: -/// @use-src 0:"keccak_optimization_low_runs/input.sol" +/// @use-src 0:"input.sol" object "C_7" { code { { @@ -12,7 +12,7 @@ object "C_7" { return(_1, _2) } } - /// @use-src 0:"keccak_optimization_low_runs/input.sol" + /// @use-src 0:"input.sol" object "C_7_deployed" { code { { diff --git a/test/cmdlineTests/linking_qualified_library_name/args b/test/cmdlineTests/linking_qualified_library_name/args index dc996f46e236..e8a29e815367 100644 --- a/test/cmdlineTests/linking_qualified_library_name/args +++ b/test/cmdlineTests/linking_qualified_library_name/args @@ -1 +1 @@ -linking_qualified_library_name/contract1.sol --bin --libraries linking_qualified_library_name/math.sol:Log:0x7777777777777777777777777777777777777777 +contract1.sol --bin --libraries math.sol:Log:0x7777777777777777777777777777777777777777 diff --git a/test/cmdlineTests/linking_qualified_library_name/contract1.sol b/test/cmdlineTests/linking_qualified_library_name/contract1.sol index aedea65faaa7..d59420962939 100644 --- a/test/cmdlineTests/linking_qualified_library_name/contract1.sol +++ b/test/cmdlineTests/linking_qualified_library_name/contract1.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-3.0 pragma solidity >=0.0; -import "linking_qualified_library_name/math.sol"; +import "math.sol"; contract C { function foo() public { diff --git a/test/cmdlineTests/linking_qualified_library_name/output b/test/cmdlineTests/linking_qualified_library_name/output index 834874bf8e87..63359661bcd4 100644 --- a/test/cmdlineTests/linking_qualified_library_name/output +++ b/test/cmdlineTests/linking_qualified_library_name/output @@ -1,8 +1,8 @@ -======= linking_qualified_library_name/contract1.sol:C ======= +======= contract1.sol:C ======= Binary: -======= linking_qualified_library_name/math.sol:Log ======= +======= math.sol:Log ======= Binary: diff --git a/test/cmdlineTests/linking_solidity/args b/test/cmdlineTests/linking_solidity/args index 9a958527fd71..7689b925ae10 100644 --- a/test/cmdlineTests/linking_solidity/args +++ b/test/cmdlineTests/linking_solidity/args @@ -1 +1 @@ ---bin --bin-runtime --libraries linking_solidity/input.sol:L=0x1234567890123456789012345678901234567890 +--bin --bin-runtime --libraries input.sol:L=0x1234567890123456789012345678901234567890 diff --git a/test/cmdlineTests/linking_solidity/output b/test/cmdlineTests/linking_solidity/output index 307b131b5af3..ed60e0ccfc9b 100644 --- a/test/cmdlineTests/linking_solidity/output +++ b/test/cmdlineTests/linking_solidity/output @@ -1,11 +1,11 @@ -======= linking_solidity/input.sol:C ======= +======= input.sol:C ======= Binary: Binary of the runtime part: -======= linking_solidity/input.sol:L ======= +======= input.sol:L ======= Binary: Binary of the runtime part: diff --git a/test/cmdlineTests/linking_solidity_unresolved_references/args b/test/cmdlineTests/linking_solidity_unresolved_references/args index 8909b2779174..fbbed9f870b7 100644 --- a/test/cmdlineTests/linking_solidity_unresolved_references/args +++ b/test/cmdlineTests/linking_solidity_unresolved_references/args @@ -1 +1 @@ ---bin --bin-runtime --libraries linking_solidity_unresolved_references/input.sol:L1=0x1234567890123456789012345678901234567890 +--bin --bin-runtime --libraries input.sol:L1=0x1234567890123456789012345678901234567890 diff --git a/test/cmdlineTests/linking_solidity_unresolved_references/output b/test/cmdlineTests/linking_solidity_unresolved_references/output index f42191f51e0b..5df6611de091 100644 --- a/test/cmdlineTests/linking_solidity_unresolved_references/output +++ b/test/cmdlineTests/linking_solidity_unresolved_references/output @@ -1,23 +1,23 @@ -======= linking_solidity_unresolved_references/input.sol:C ======= +======= input.sol:C ======= Binary: -__$8ef13d1c56d5343bf69cf9444272079aa5$____$8ef13d1c56d5343bf69cf9444272079aa5$__ +__$a7fb54ac3bf4ba657d4a55d066b3521d62$____$a7fb54ac3bf4ba657d4a55d066b3521d62$__ -// $8ef13d1c56d5343bf69cf9444272079aa5$ -> linking_solidity_unresolved_references/input.sol:L2 -// $8ef13d1c56d5343bf69cf9444272079aa5$ -> linking_solidity_unresolved_references/input.sol:L2 +// $a7fb54ac3bf4ba657d4a55d066b3521d62$ -> input.sol:L2 +// $a7fb54ac3bf4ba657d4a55d066b3521d62$ -> input.sol:L2 Binary of the runtime part: -__$8ef13d1c56d5343bf69cf9444272079aa5$____$8ef13d1c56d5343bf69cf9444272079aa5$__ +__$a7fb54ac3bf4ba657d4a55d066b3521d62$____$a7fb54ac3bf4ba657d4a55d066b3521d62$__ -// $8ef13d1c56d5343bf69cf9444272079aa5$ -> linking_solidity_unresolved_references/input.sol:L2 -// $8ef13d1c56d5343bf69cf9444272079aa5$ -> linking_solidity_unresolved_references/input.sol:L2 +// $a7fb54ac3bf4ba657d4a55d066b3521d62$ -> input.sol:L2 +// $a7fb54ac3bf4ba657d4a55d066b3521d62$ -> input.sol:L2 -======= linking_solidity_unresolved_references/input.sol:L1 ======= +======= input.sol:L1 ======= Binary: Binary of the runtime part: -======= linking_solidity_unresolved_references/input.sol:L2 ======= +======= input.sol:L2 ======= Binary: Binary of the runtime part: diff --git a/test/cmdlineTests/linking_strict_assembly/output b/test/cmdlineTests/linking_strict_assembly/output index 4fa6edc0c372..756cc2822d3d 100644 --- a/test/cmdlineTests/linking_strict_assembly/output +++ b/test/cmdlineTests/linking_strict_assembly/output @@ -1,5 +1,5 @@ -======= linking_strict_assembly/input.yul (EVM) ======= +======= input.yul (EVM) ======= Pretty printed source: object "a" { @@ -16,11 +16,11 @@ Binary representation: 7312345678901234567890123456789012345678905f5500 Text representation: - /* "linking_strict_assembly/input.yul":58:93 */ + /* "input.yul":58:93 */ linkerSymbol("f919ba91ac99f96129544b80b9516b27a80e376b9dc693819d0b18b7e0395612") - /* "linking_strict_assembly/input.yul":113:114 */ + /* "input.yul":113:114 */ 0x00 - /* "linking_strict_assembly/input.yul":106:121 */ + /* "input.yul":106:121 */ sstore - /* "linking_strict_assembly/input.yul":22:137 */ + /* "input.yul":22:137 */ stop diff --git a/test/cmdlineTests/linking_strict_assembly_qualified_library_qualified_reference/output b/test/cmdlineTests/linking_strict_assembly_qualified_library_qualified_reference/output index e4fa4fcbd9ab..f347631001b9 100644 --- a/test/cmdlineTests/linking_strict_assembly_qualified_library_qualified_reference/output +++ b/test/cmdlineTests/linking_strict_assembly_qualified_library_qualified_reference/output @@ -1,5 +1,5 @@ -======= linking_strict_assembly_qualified_library_qualified_reference/input.yul (EVM) ======= +======= input.yul (EVM) ======= Pretty printed source: object "a" { diff --git a/test/cmdlineTests/linking_strict_assembly_qualified_library_unqualified_reference/output b/test/cmdlineTests/linking_strict_assembly_qualified_library_unqualified_reference/output index ebf7f6542c52..d329296eb2c5 100644 --- a/test/cmdlineTests/linking_strict_assembly_qualified_library_unqualified_reference/output +++ b/test/cmdlineTests/linking_strict_assembly_qualified_library_unqualified_reference/output @@ -1,5 +1,5 @@ -======= linking_strict_assembly_qualified_library_unqualified_reference/input.yul (EVM) ======= +======= input.yul (EVM) ======= Pretty printed source: object "a" { diff --git a/test/cmdlineTests/linking_strict_assembly_same_library_name_different_files/output b/test/cmdlineTests/linking_strict_assembly_same_library_name_different_files/output index 69c0a21f63c1..f4262400c815 100644 --- a/test/cmdlineTests/linking_strict_assembly_same_library_name_different_files/output +++ b/test/cmdlineTests/linking_strict_assembly_same_library_name_different_files/output @@ -1,5 +1,5 @@ -======= linking_strict_assembly_same_library_name_different_files/input.yul (EVM) ======= +======= input.yul (EVM) ======= Pretty printed source: object "a" { @@ -18,19 +18,19 @@ Binary representation: 731111111111111111111111111111111111111111732222222222222222222222222222222222222222905f5560015500 Text representation: - /* "linking_strict_assembly_same_library_name_different_files/input.yul":59:89 */ + /* "input.yul":59:89 */ linkerSymbol("f3ffc10c396a7cc41ae954b050792839d20947bf73497d30c49a9fda1ea477ec") - /* "linking_strict_assembly_same_library_name_different_files/input.yul":115:145 */ + /* "input.yul":115:145 */ linkerSymbol("c3523432985587641d17c68161d2f700c57aaf4ed21cda4f25d76193c831f97f") - /* "linking_strict_assembly_same_library_name_different_files/input.yul":158:174 */ + /* "input.yul":158:174 */ swap1 - /* "linking_strict_assembly_same_library_name_different_files/input.yul":165:166 */ + /* "input.yul":165:166 */ 0x00 - /* "linking_strict_assembly_same_library_name_different_files/input.yul":158:174 */ + /* "input.yul":158:174 */ sstore - /* "linking_strict_assembly_same_library_name_different_files/input.yul":194:195 */ + /* "input.yul":194:195 */ 0x01 - /* "linking_strict_assembly_same_library_name_different_files/input.yul":187:203 */ + /* "input.yul":187:203 */ sstore - /* "linking_strict_assembly_same_library_name_different_files/input.yul":22:219 */ + /* "input.yul":22:219 */ stop diff --git a/test/cmdlineTests/linking_strict_assembly_same_library_name_different_files_in_link_references/output b/test/cmdlineTests/linking_strict_assembly_same_library_name_different_files_in_link_references/output index 14fafa4e4604..a6422d8fbce2 100644 --- a/test/cmdlineTests/linking_strict_assembly_same_library_name_different_files_in_link_references/output +++ b/test/cmdlineTests/linking_strict_assembly_same_library_name_different_files_in_link_references/output @@ -1,5 +1,5 @@ -======= linking_strict_assembly_same_library_name_different_files_in_link_references/input.yul (EVM) ======= +======= input.yul (EVM) ======= Pretty printed source: object "a" { @@ -18,19 +18,19 @@ Binary representation: 73123456789012345678901234567890123456789073__$c3523432985587641d17c68161d2f700c5$__905f5560015500 Text representation: - /* "linking_strict_assembly_same_library_name_different_files_in_link_references/input.yul":59:89 */ + /* "input.yul":59:89 */ linkerSymbol("f3ffc10c396a7cc41ae954b050792839d20947bf73497d30c49a9fda1ea477ec") - /* "linking_strict_assembly_same_library_name_different_files_in_link_references/input.yul":115:145 */ + /* "input.yul":115:145 */ linkerSymbol("c3523432985587641d17c68161d2f700c57aaf4ed21cda4f25d76193c831f97f") - /* "linking_strict_assembly_same_library_name_different_files_in_link_references/input.yul":158:174 */ + /* "input.yul":158:174 */ swap1 - /* "linking_strict_assembly_same_library_name_different_files_in_link_references/input.yul":165:166 */ + /* "input.yul":165:166 */ 0x00 - /* "linking_strict_assembly_same_library_name_different_files_in_link_references/input.yul":158:174 */ + /* "input.yul":158:174 */ sstore - /* "linking_strict_assembly_same_library_name_different_files_in_link_references/input.yul":194:195 */ + /* "input.yul":194:195 */ 0x01 - /* "linking_strict_assembly_same_library_name_different_files_in_link_references/input.yul":187:203 */ + /* "input.yul":187:203 */ sstore - /* "linking_strict_assembly_same_library_name_different_files_in_link_references/input.yul":22:219 */ + /* "input.yul":22:219 */ stop diff --git a/test/cmdlineTests/linking_strict_assembly_unqualified_library_qualified_reference/output b/test/cmdlineTests/linking_strict_assembly_unqualified_library_qualified_reference/output index aaf03d0733b4..099b0ce54db3 100644 --- a/test/cmdlineTests/linking_strict_assembly_unqualified_library_qualified_reference/output +++ b/test/cmdlineTests/linking_strict_assembly_unqualified_library_qualified_reference/output @@ -1,5 +1,5 @@ -======= linking_strict_assembly_unqualified_library_qualified_reference/input.yul (EVM) ======= +======= input.yul (EVM) ======= Pretty printed source: object "a" { diff --git a/test/cmdlineTests/linking_strict_assembly_unqualified_library_unqualified_reference/output b/test/cmdlineTests/linking_strict_assembly_unqualified_library_unqualified_reference/output index d91d89f5ca69..b4bb825435c3 100644 --- a/test/cmdlineTests/linking_strict_assembly_unqualified_library_unqualified_reference/output +++ b/test/cmdlineTests/linking_strict_assembly_unqualified_library_unqualified_reference/output @@ -1,5 +1,5 @@ -======= linking_strict_assembly_unqualified_library_unqualified_reference/input.yul (EVM) ======= +======= input.yul (EVM) ======= Pretty printed source: object "a" { diff --git a/test/cmdlineTests/linking_strict_assembly_unresolved_references/output b/test/cmdlineTests/linking_strict_assembly_unresolved_references/output index 3b2d84ab3c6b..7b45cae6eb61 100644 --- a/test/cmdlineTests/linking_strict_assembly_unresolved_references/output +++ b/test/cmdlineTests/linking_strict_assembly_unresolved_references/output @@ -1,5 +1,5 @@ -======= linking_strict_assembly_unresolved_references/input.yul (EVM) ======= +======= input.yul (EVM) ======= Pretty printed source: object "a" { @@ -18,19 +18,19 @@ Binary representation: 73123456789012345678901234567890123456789073__$fb58009a6b1ecea3b9d99bedd645df4ec3$__905f5560015500 Text representation: - /* "linking_strict_assembly_unresolved_references/input.yul":59:95 */ + /* "input.yul":59:95 */ linkerSymbol("05b0326038374a21e0895480a58bda0768cdcc04c8d18f154362d1ca5223d245") - /* "linking_strict_assembly_unresolved_references/input.yul":121:157 */ + /* "input.yul":121:157 */ linkerSymbol("fb58009a6b1ecea3b9d99bedd645df4ec308f17bc0087e5f39d078f77f809177") - /* "linking_strict_assembly_unresolved_references/input.yul":170:186 */ + /* "input.yul":170:186 */ swap1 - /* "linking_strict_assembly_unresolved_references/input.yul":177:178 */ + /* "input.yul":177:178 */ 0x00 - /* "linking_strict_assembly_unresolved_references/input.yul":170:186 */ + /* "input.yul":170:186 */ sstore - /* "linking_strict_assembly_unresolved_references/input.yul":206:207 */ + /* "input.yul":206:207 */ 0x01 - /* "linking_strict_assembly_unresolved_references/input.yul":199:215 */ + /* "input.yul":199:215 */ sstore - /* "linking_strict_assembly_unresolved_references/input.yul":22:231 */ + /* "input.yul":22:231 */ stop diff --git a/test/cmdlineTests/linking_unqualified_library_name/args b/test/cmdlineTests/linking_unqualified_library_name/args index 6118acf02caf..08f3b8cd1c06 100644 --- a/test/cmdlineTests/linking_unqualified_library_name/args +++ b/test/cmdlineTests/linking_unqualified_library_name/args @@ -1 +1 @@ -linking_unqualified_library_name/contract1.sol linking_unqualified_library_name/contract2.sol --bin --libraries Log:0x7777777777777777777777777777777777777777 +contract1.sol contract2.sol --bin --libraries Log:0x7777777777777777777777777777777777777777 diff --git a/test/cmdlineTests/linking_unqualified_library_name/contract1.sol b/test/cmdlineTests/linking_unqualified_library_name/contract1.sol index 38e43f9d493e..893c63af07be 100644 --- a/test/cmdlineTests/linking_unqualified_library_name/contract1.sol +++ b/test/cmdlineTests/linking_unqualified_library_name/contract1.sol @@ -2,7 +2,7 @@ pragma solidity >=0.0; -import "linking_unqualified_library_name/error.sol"; +import "error.sol"; contract C { function foo() public { diff --git a/test/cmdlineTests/linking_unqualified_library_name/contract2.sol b/test/cmdlineTests/linking_unqualified_library_name/contract2.sol index 6ddb8ad6e286..d59420962939 100644 --- a/test/cmdlineTests/linking_unqualified_library_name/contract2.sol +++ b/test/cmdlineTests/linking_unqualified_library_name/contract2.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-3.0 pragma solidity >=0.0; -import "linking_unqualified_library_name/math.sol"; +import "math.sol"; contract C { function foo() public { diff --git a/test/cmdlineTests/linking_unqualified_library_name/output b/test/cmdlineTests/linking_unqualified_library_name/output index be64a93c9bbc..68e254363fa1 100644 --- a/test/cmdlineTests/linking_unqualified_library_name/output +++ b/test/cmdlineTests/linking_unqualified_library_name/output @@ -1,20 +1,20 @@ -======= linking_unqualified_library_name/contract1.sol:C ======= +======= contract1.sol:C ======= Binary: -__$cdf6d5ab08a9335b02e7c2475aa27d04fa$__ +__$4a937a7d3d68a205b3b2520e23ccff31ea$__ -// $cdf6d5ab08a9335b02e7c2475aa27d04fa$ -> linking_unqualified_library_name/error.sol:Log +// $4a937a7d3d68a205b3b2520e23ccff31ea$ -> error.sol:Log -======= linking_unqualified_library_name/contract2.sol:C ======= +======= contract2.sol:C ======= Binary: -__$22584241c2fc4f2884d5222245463779a8$__ +__$b77e1024bb5d89efefbab5fb1f7cb8fde7$__ -// $22584241c2fc4f2884d5222245463779a8$ -> linking_unqualified_library_name/math.sol:Log +// $b77e1024bb5d89efefbab5fb1f7cb8fde7$ -> math.sol:Log -======= linking_unqualified_library_name/error.sol:Log ======= +======= error.sol:Log ======= Binary: -======= linking_unqualified_library_name/math.sol:Log ======= +======= math.sol:Log ======= Binary: diff --git a/test/cmdlineTests/mcopy_bytes_array_abi_decode/err b/test/cmdlineTests/mcopy_bytes_array_abi_decode/err index de32e66295be..ead85d933e3a 100644 --- a/test/cmdlineTests/mcopy_bytes_array_abi_decode/err +++ b/test/cmdlineTests/mcopy_bytes_array_abi_decode/err @@ -1,5 +1,5 @@ Warning: Statement has no effect. - --> mcopy_bytes_array_abi_decode/input.sol:7:9: + --> input.sol:7:9: | 7 | abi.decode("abcd", (bytes)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/test/cmdlineTests/mcopy_bytes_array_abi_decode/output b/test/cmdlineTests/mcopy_bytes_array_abi_decode/output index 2a24ec834fa1..806094f76a15 100644 --- a/test/cmdlineTests/mcopy_bytes_array_abi_decode/output +++ b/test/cmdlineTests/mcopy_bytes_array_abi_decode/output @@ -1,6 +1,6 @@ IR: -/// @use-src 0:"mcopy_bytes_array_abi_decode/input.sol" +/// @use-src 0:"input.sol" object "C_15" { code { @@ -27,7 +27,7 @@ object "C_15" { } } - /// @use-src 0:"mcopy_bytes_array_abi_decode/input.sol" + /// @use-src 0:"input.sol" object "C_15_deployed" { code { diff --git a/test/cmdlineTests/mcopy_bytes_array_returned_from_function/output b/test/cmdlineTests/mcopy_bytes_array_returned_from_function/output index 170cdf1a7a3a..f3cd766954c5 100644 --- a/test/cmdlineTests/mcopy_bytes_array_returned_from_function/output +++ b/test/cmdlineTests/mcopy_bytes_array_returned_from_function/output @@ -1,5 +1,5 @@ Optimized IR: -/// @use-src 0:"mcopy_bytes_array_returned_from_function/input.sol" +/// @use-src 0:"input.sol" object "C_14" { code { { @@ -11,7 +11,7 @@ object "C_14" { return(_1, _2) } } - /// @use-src 0:"mcopy_bytes_array_returned_from_function/input.sol" + /// @use-src 0:"input.sol" object "C_14_deployed" { code { { diff --git a/test/cmdlineTests/mcopy_string_literal_returned_from_function/output b/test/cmdlineTests/mcopy_string_literal_returned_from_function/output index 548c34de8628..3adeae0f58e6 100644 --- a/test/cmdlineTests/mcopy_string_literal_returned_from_function/output +++ b/test/cmdlineTests/mcopy_string_literal_returned_from_function/output @@ -1,5 +1,5 @@ Optimized IR: -/// @use-src 0:"mcopy_string_literal_returned_from_function/input.sol" +/// @use-src 0:"input.sol" object "C_10" { code { { @@ -11,7 +11,7 @@ object "C_10" { return(_1, _2) } } - /// @use-src 0:"mcopy_string_literal_returned_from_function/input.sol" + /// @use-src 0:"input.sol" object "C_10_deployed" { code { { diff --git a/test/cmdlineTests/memoryguard_shadowing_by_inline_assembly_identifiers/output b/test/cmdlineTests/memoryguard_shadowing_by_inline_assembly_identifiers/output index 842580597d12..1ea3bdf20209 100644 --- a/test/cmdlineTests/memoryguard_shadowing_by_inline_assembly_identifiers/output +++ b/test/cmdlineTests/memoryguard_shadowing_by_inline_assembly_identifiers/output @@ -1,6 +1,6 @@ IR: -/// @use-src 0:"memoryguard_shadowing_by_inline_assembly_identifiers/input.sol" +/// @use-src 0:"input.sol" object "C_10" { code { @@ -27,7 +27,7 @@ object "C_10" { } } - /// @use-src 0:"memoryguard_shadowing_by_inline_assembly_identifiers/input.sol" + /// @use-src 0:"input.sol" object "C_10_deployed" { code { diff --git a/test/cmdlineTests/message_format/err b/test/cmdlineTests/message_format/err index eee8267e25f3..1bb6a6469273 100644 --- a/test/cmdlineTests/message_format/err +++ b/test/cmdlineTests/message_format/err @@ -1,50 +1,50 @@ Warning: Source file does not specify required compiler version! ---> message_format/input.sol +--> input.sol Warning: Unused local variable. - --> message_format/input.sol:9:27: + --> input.sol:9:27: | 9 | function f() public { int x; } | ^^^^^ Warning: Unused local variable. - --> message_format/input.sol:10:27: + --> input.sol:10:27: | 10 | function g() public { int x; } | ^^^^^ Warning: Unused local variable. - --> message_format/input.sol:99:14: + --> input.sol:99:14: | 99 | /**/ int a; /**/ | ^^^^^ Warning: Unused local variable. - --> message_format/input.sol:100:14: + --> input.sol:100:14: | 100 | /**/ int b; /**/ | ^^^^^ Warning: Unused local variable. - --> message_format/input.sol:101:14: + --> input.sol:101:14: | 101 | /**/ int c; /**/ | ^^^^^ Warning: Function state mutability can be restricted to pure - --> message_format/input.sol:9:5: + --> input.sol:9:5: | 9 | function f() public { int x; } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Warning: Function state mutability can be restricted to pure - --> message_format/input.sol:10:5: + --> input.sol:10:5: | 10 | function g() public { int x; } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Warning: Function state mutability can be restricted to pure - --> message_format/input.sol:11:5: + --> input.sol:11:5: | 11 | function h() public { | ^ (Relevant source part starts here and spans across multiple lines). diff --git a/test/cmdlineTests/message_format_utf8/err b/test/cmdlineTests/message_format_utf8/err index 58d45127cb3d..e14a048fc54b 100644 --- a/test/cmdlineTests/message_format_utf8/err +++ b/test/cmdlineTests/message_format_utf8/err @@ -1,29 +1,29 @@ Warning: Statement has no effect. - --> message_format_utf8/input.sol:5:51: + --> input.sol:5:51: | 5 | /* ©©©©ᄅ©©©©© 2017 */ constructor () { unicode"©©©©ᄅ©©©©©" ; } | ^^^^^^^^^^^^^^^^^^^ Warning: Statement has no effect. - --> message_format_utf8/input.sol:9:25: + --> input.sol:9:25: | 9 | unicode"S = π × r²"; | ^^^^^^^^^^^^^^^^^^^ Warning: Statement has no effect. - --> message_format_utf8/input.sol:10:39: + --> input.sol:10:39: | 10 | /* ₀₁₂₃₄⁵⁶⁷⁸⁹ */ unicode"∑ 1/n! ≈ 2.7"; // tabs in-between | ^^^^^^^^^^^^^^^^^^^^^ Warning: Statement has no effect. - --> message_format_utf8/input.sol:11:30: + --> input.sol:11:30: | 11 | /* Ŀŏŗėɯ ïƥŝʉɱ */ unicode"μὴ χεῖρον βέλτιστον"; // tabs in-between and inside | ^^^^^^^^^^ ^^^^^^ ^^^^^^^^^^ Warning: Function state mutability can be restricted to pure - --> message_format_utf8/input.sol:15:2: + --> input.sol:15:2: | 15 | function selector() public returns(uint) { // starts with tab | ^ (Relevant source part starts here and spans across multiple lines). diff --git a/test/cmdlineTests/metadata/output b/test/cmdlineTests/metadata/output index b6a684b844f3..0910128894df 100644 --- a/test/cmdlineTests/metadata/output +++ b/test/cmdlineTests/metadata/output @@ -1,4 +1,4 @@ -======= metadata/input.sol:C ======= +======= input.sol:C ======= Metadata: -{"compiler":{"version": ""},"language":"Solidity","output":{"abi":[],"devdoc":{"kind":"dev","methods":{},"version":1},"userdoc":{"kind":"user","methods":{},"version":1}},"settings":{"compilationTarget":{"metadata/input.sol":"C"},"evmVersion":"cancun","libraries":{},"metadata":{"bytecodeHash":"ipfs"},"optimizer":{"enabled":false,"runs":200},"remappings":[]},"sources":{"metadata/input.sol":{"keccak256":"0x5cf617b1707a484e3c4bd59643013dec76ab7d75900b46855214729ae3e0ceb0","license":"GPL-3.0","urls":["bzz-raw://ac418a02dfadf87234150d3568f33269e3f49460345cb39300e017a6d755eff2","dweb:/ipfs/QmQq3owBu25x2WV46HB1WyKzJpxiAPecU7eMKqtXCF7eeS"]}},"version":1} +{"compiler":{"version": ""},"language":"Solidity","output":{"abi":[],"devdoc":{"kind":"dev","methods":{},"version":1},"userdoc":{"kind":"user","methods":{},"version":1}},"settings":{"compilationTarget":{"input.sol":"C"},"evmVersion":"cancun","libraries":{},"metadata":{"bytecodeHash":"ipfs"},"optimizer":{"enabled":false,"runs":200},"remappings":[]},"sources":{"input.sol":{"keccak256":"0x5cf617b1707a484e3c4bd59643013dec76ab7d75900b46855214729ae3e0ceb0","license":"GPL-3.0","urls":["bzz-raw://ac418a02dfadf87234150d3568f33269e3f49460345cb39300e017a6d755eff2","dweb:/ipfs/QmQq3owBu25x2WV46HB1WyKzJpxiAPecU7eMKqtXCF7eeS"]}},"version":1} diff --git a/test/cmdlineTests/model_checker_bmc_loop_iterations/err b/test/cmdlineTests/model_checker_bmc_loop_iterations/err index cbb2b0f9daca..0ec7a09b6d3c 100644 --- a/test/cmdlineTests/model_checker_bmc_loop_iterations/err +++ b/test/cmdlineTests/model_checker_bmc_loop_iterations/err @@ -1,5 +1,5 @@ Warning: BMC: Assertion violation happens here. - --> model_checker_bmc_loop_iterations/input.sol:10:3: + --> input.sol:10:3: | 10 | assert(x == 3); | ^^^^^^^^^^^^^^ diff --git a/test/cmdlineTests/model_checker_bmc_loop_iterations_no_argument/err b/test/cmdlineTests/model_checker_bmc_loop_iterations_no_argument/err index 1bd45b6c6f57..4b1a2ea3b1fd 100644 --- a/test/cmdlineTests/model_checker_bmc_loop_iterations_no_argument/err +++ b/test/cmdlineTests/model_checker_bmc_loop_iterations_no_argument/err @@ -1 +1 @@ -Error: the argument ('model_checker_bmc_loop_iterations_no_argument/input.sol') for option '--model-checker-bmc-loop-iterations' is invalid +Error: the argument ('input.sol') for option '--model-checker-bmc-loop-iterations' is invalid diff --git a/test/cmdlineTests/model_checker_contracts_all/err b/test/cmdlineTests/model_checker_contracts_all/err index 9135483d5f79..0d19af174c39 100644 --- a/test/cmdlineTests/model_checker_contracts_all/err +++ b/test/cmdlineTests/model_checker_contracts_all/err @@ -6,7 +6,7 @@ x = 0 Transaction trace: B.constructor() B.f(0) - --> model_checker_contracts_all/input.sol:5:9: + --> input.sol:5:9: | 5 | assert(x > 0); | ^^^^^^^^^^^^^ @@ -19,7 +19,7 @@ y = 0 Transaction trace: A.constructor() A.g(0) - --> model_checker_contracts_all/input.sol:10:9: + --> input.sol:10:9: | 10 | assert(y > 0); | ^^^^^^^^^^^^^ diff --git a/test/cmdlineTests/model_checker_contracts_all_explicit/args b/test/cmdlineTests/model_checker_contracts_all_explicit/args index 6e6bee97aed8..151a636fe265 100644 --- a/test/cmdlineTests/model_checker_contracts_all_explicit/args +++ b/test/cmdlineTests/model_checker_contracts_all_explicit/args @@ -1 +1 @@ ---model-checker-engine all --model-checker-contracts model_checker_contracts_all_explicit/input.sol:B,model_checker_contracts_all_explicit/input.sol:A +--model-checker-engine all --model-checker-contracts input.sol:B,input.sol:A diff --git a/test/cmdlineTests/model_checker_contracts_all_explicit/err b/test/cmdlineTests/model_checker_contracts_all_explicit/err index 003c0dffe018..25ce2e5e9947 100644 --- a/test/cmdlineTests/model_checker_contracts_all_explicit/err +++ b/test/cmdlineTests/model_checker_contracts_all_explicit/err @@ -6,7 +6,7 @@ x = 0 Transaction trace: B.constructor() B.f(0) - --> model_checker_contracts_all_explicit/input.sol:5:3: + --> input.sol:5:3: | 5 | assert(x > 0); | ^^^^^^^^^^^^^ @@ -19,7 +19,7 @@ y = 0 Transaction trace: A.constructor() A.g(0) - --> model_checker_contracts_all_explicit/input.sol:10:3: + --> input.sol:10:3: | 10 | assert(y > 0); | ^^^^^^^^^^^^^ diff --git a/test/cmdlineTests/model_checker_contracts_inexistent_contract/args b/test/cmdlineTests/model_checker_contracts_inexistent_contract/args index b3c44af85b87..1128064d8a59 100644 --- a/test/cmdlineTests/model_checker_contracts_inexistent_contract/args +++ b/test/cmdlineTests/model_checker_contracts_inexistent_contract/args @@ -1 +1 @@ ---model-checker-engine all --model-checker-contracts model_checker_contracts_inexistent_contract/input.sol:C +--model-checker-engine all --model-checker-contracts input.sol:C diff --git a/test/cmdlineTests/model_checker_contracts_inexistent_contract/err b/test/cmdlineTests/model_checker_contracts_inexistent_contract/err index 6326537e928c..72f613bf3ccd 100644 --- a/test/cmdlineTests/model_checker_contracts_inexistent_contract/err +++ b/test/cmdlineTests/model_checker_contracts_inexistent_contract/err @@ -1 +1 @@ -Warning: Requested contract "C" does not exist in source "model_checker_contracts_inexistent_contract/input.sol". +Warning: Requested contract "C" does not exist in source "input.sol". diff --git a/test/cmdlineTests/model_checker_contracts_inexistent_source/args b/test/cmdlineTests/model_checker_contracts_inexistent_source/args index 6d91ecc34355..b98256bf4e9b 100644 --- a/test/cmdlineTests/model_checker_contracts_inexistent_source/args +++ b/test/cmdlineTests/model_checker_contracts_inexistent_source/args @@ -1 +1 @@ ---model-checker-engine all --model-checker-contracts model_checker_contracts_inexistent_source/A.sol:A +--model-checker-engine all --model-checker-contracts A.sol:A diff --git a/test/cmdlineTests/model_checker_contracts_inexistent_source/err b/test/cmdlineTests/model_checker_contracts_inexistent_source/err index 218588ad83d2..3c93482595f5 100644 --- a/test/cmdlineTests/model_checker_contracts_inexistent_source/err +++ b/test/cmdlineTests/model_checker_contracts_inexistent_source/err @@ -1 +1 @@ -Warning: Requested source "model_checker_contracts_inexistent_source/A.sol" does not exist. +Warning: Requested source "A.sol" does not exist. diff --git a/test/cmdlineTests/model_checker_contracts_one_contract_missing/args b/test/cmdlineTests/model_checker_contracts_one_contract_missing/args index 7ea3d3f04610..8670db9b57a9 100644 --- a/test/cmdlineTests/model_checker_contracts_one_contract_missing/args +++ b/test/cmdlineTests/model_checker_contracts_one_contract_missing/args @@ -1 +1 @@ ---model-checker-engine all --model-checker-contracts model_checker_contracts_all_explicit/input.sol:,model_checker_contracts_all_explicit/input.sol:A +--model-checker-engine all --model-checker-contracts input.sol:,input.sol:A diff --git a/test/cmdlineTests/model_checker_contracts_one_contract_missing/err b/test/cmdlineTests/model_checker_contracts_one_contract_missing/err index d4e93bcd705e..88e675624e2f 100644 --- a/test/cmdlineTests/model_checker_contracts_one_contract_missing/err +++ b/test/cmdlineTests/model_checker_contracts_one_contract_missing/err @@ -1 +1 @@ -Error: Invalid option for --model-checker-contracts: model_checker_contracts_all_explicit/input.sol:,model_checker_contracts_all_explicit/input.sol:A +Error: Invalid option for --model-checker-contracts: input.sol:,input.sol:A diff --git a/test/cmdlineTests/model_checker_contracts_only_one/args b/test/cmdlineTests/model_checker_contracts_only_one/args index ae76a81d6735..ff3ad9e1d4fe 100644 --- a/test/cmdlineTests/model_checker_contracts_only_one/args +++ b/test/cmdlineTests/model_checker_contracts_only_one/args @@ -1 +1 @@ ---model-checker-engine all --model-checker-contracts model_checker_contracts_only_one/input.sol:A +--model-checker-engine all --model-checker-contracts input.sol:A diff --git a/test/cmdlineTests/model_checker_contracts_only_one/err b/test/cmdlineTests/model_checker_contracts_only_one/err index 9c8ade6931c3..4472abefaf32 100644 --- a/test/cmdlineTests/model_checker_contracts_only_one/err +++ b/test/cmdlineTests/model_checker_contracts_only_one/err @@ -6,7 +6,7 @@ x = 0 Transaction trace: A.constructor() B.f(0) - --> model_checker_contracts_only_one/input.sol:5:3: + --> input.sol:5:3: | 5 | assert(x > 0); | ^^^^^^^^^^^^^ @@ -19,7 +19,7 @@ y = 0 Transaction trace: A.constructor() A.g(0) - --> model_checker_contracts_only_one/input.sol:10:3: + --> input.sol:10:3: | 10 | assert(y > 0); | ^^^^^^^^^^^^^ diff --git a/test/cmdlineTests/model_checker_engine_all/err b/test/cmdlineTests/model_checker_engine_all/err index 12614fd55f82..18b8774650b9 100644 --- a/test/cmdlineTests/model_checker_engine_all/err +++ b/test/cmdlineTests/model_checker_engine_all/err @@ -6,7 +6,7 @@ x = 0 Transaction trace: test.constructor() test.f(0) - --> model_checker_engine_all/input.sol:5:3: + --> input.sol:5:3: | 5 | assert(x > 0); | ^^^^^^^^^^^^^ diff --git a/test/cmdlineTests/model_checker_engine_bmc/err b/test/cmdlineTests/model_checker_engine_bmc/err index ed46539d6510..dcedef48bf09 100644 --- a/test/cmdlineTests/model_checker_engine_bmc/err +++ b/test/cmdlineTests/model_checker_engine_bmc/err @@ -1,5 +1,5 @@ Warning: BMC: Assertion violation happens here. - --> model_checker_engine_bmc/input.sol:5:3: + --> input.sol:5:3: | 5 | assert(x > 0); | ^^^^^^^^^^^^^ diff --git a/test/cmdlineTests/model_checker_engine_chc/err b/test/cmdlineTests/model_checker_engine_chc/err index 95198fa2027a..18b8774650b9 100644 --- a/test/cmdlineTests/model_checker_engine_chc/err +++ b/test/cmdlineTests/model_checker_engine_chc/err @@ -6,7 +6,7 @@ x = 0 Transaction trace: test.constructor() test.f(0) - --> model_checker_engine_chc/input.sol:5:3: + --> input.sol:5:3: | 5 | assert(x > 0); | ^^^^^^^^^^^^^ diff --git a/test/cmdlineTests/model_checker_ext_calls_trusted_chc/err b/test/cmdlineTests/model_checker_ext_calls_trusted_chc/err index e9c2d70a9739..58be5002f2d1 100644 --- a/test/cmdlineTests/model_checker_ext_calls_trusted_chc/err +++ b/test/cmdlineTests/model_checker_ext_calls_trusted_chc/err @@ -1,5 +1,5 @@ Warning: Function state mutability can be restricted to pure - --> model_checker_ext_calls_trusted_chc/input.sol:5:2: + --> input.sol:5:2: | 5 | function f() public view returns (uint) { | ^ (Relevant source part starts here and spans across multiple lines). diff --git a/test/cmdlineTests/model_checker_ext_calls_untrusted_chc/err b/test/cmdlineTests/model_checker_ext_calls_untrusted_chc/err index b06333e43bd5..73b355510e2f 100644 --- a/test/cmdlineTests/model_checker_ext_calls_untrusted_chc/err +++ b/test/cmdlineTests/model_checker_ext_calls_untrusted_chc/err @@ -8,7 +8,7 @@ Transaction trace: test.constructor() test.g(0) e.f() -- untrusted external call - --> model_checker_ext_calls_untrusted_chc/input.sol:11:3: + --> input.sol:11:3: | 11 | assert(x == 0); | ^^^^^^^^^^^^^^ diff --git a/test/cmdlineTests/model_checker_invariants_all/err b/test/cmdlineTests/model_checker_invariants_all/err index dcef00b5fd0e..b47334040b61 100644 --- a/test/cmdlineTests/model_checker_invariants_all/err +++ b/test/cmdlineTests/model_checker_invariants_all/err @@ -1,8 +1,8 @@ Info: CHC: 1 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. -Info: Contract invariant(s) for model_checker_invariants_all/input.sol:test: +Info: Contract invariant(s) for input.sol:test: (true || !(x >= 1)) -Reentrancy property(ies) for model_checker_invariants_all/input.sol:test: +Reentrancy property(ies) for input.sol:test: ((( = 0) && (x!6 = x!4) && (x' = x)) || true || true || true || true) = 0 -> no errors = 1 -> Assertion failed at assert(x == 0) diff --git a/test/cmdlineTests/model_checker_invariants_contract/err b/test/cmdlineTests/model_checker_invariants_contract/err index 3ecad6b35d48..2ea993088670 100644 --- a/test/cmdlineTests/model_checker_invariants_contract/err +++ b/test/cmdlineTests/model_checker_invariants_contract/err @@ -1,4 +1,4 @@ Info: CHC: 1 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. -Info: Contract invariant(s) for model_checker_invariants_contract/input.sol:test: +Info: Contract invariant(s) for input.sol:test: (true || !(x >= 1)) diff --git a/test/cmdlineTests/model_checker_invariants_contract_eld/err b/test/cmdlineTests/model_checker_invariants_contract_eld/err index 29c5a5bc8eae..4dc823ec8880 100644 --- a/test/cmdlineTests/model_checker_invariants_contract_eld/err +++ b/test/cmdlineTests/model_checker_invariants_contract_eld/err @@ -1,4 +1,4 @@ Info: CHC: 1 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. -Info: Contract invariant(s) for model_checker_invariants_contract_eld/input.sol:test: +Info: Contract invariant(s) for input.sol:test: (x = 0) diff --git a/test/cmdlineTests/model_checker_invariants_contract_reentrancy/err b/test/cmdlineTests/model_checker_invariants_contract_reentrancy/err index 7764e89abc59..b47334040b61 100644 --- a/test/cmdlineTests/model_checker_invariants_contract_reentrancy/err +++ b/test/cmdlineTests/model_checker_invariants_contract_reentrancy/err @@ -1,8 +1,8 @@ Info: CHC: 1 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. -Info: Contract invariant(s) for model_checker_invariants_contract_reentrancy/input.sol:test: +Info: Contract invariant(s) for input.sol:test: (true || !(x >= 1)) -Reentrancy property(ies) for model_checker_invariants_contract_reentrancy/input.sol:test: +Reentrancy property(ies) for input.sol:test: ((( = 0) && (x!6 = x!4) && (x' = x)) || true || true || true || true) = 0 -> no errors = 1 -> Assertion failed at assert(x == 0) diff --git a/test/cmdlineTests/model_checker_invariants_reentrancy/err b/test/cmdlineTests/model_checker_invariants_reentrancy/err index 8891b0e18c59..42ac3ca73311 100644 --- a/test/cmdlineTests/model_checker_invariants_reentrancy/err +++ b/test/cmdlineTests/model_checker_invariants_reentrancy/err @@ -1,6 +1,6 @@ Info: CHC: 1 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. -Info: Reentrancy property(ies) for model_checker_invariants_reentrancy/input.sol:test: +Info: Reentrancy property(ies) for input.sol:test: ((( = 0) && (x!6 = x!4) && (x' = x)) || true || true || true || true) = 0 -> no errors = 1 -> Assertion failed at assert(x == 0) diff --git a/test/cmdlineTests/model_checker_show_proved_safe_default_all_engines/err b/test/cmdlineTests/model_checker_show_proved_safe_default_all_engines/err index b896b21bc7f9..730e43b9588e 100644 --- a/test/cmdlineTests/model_checker_show_proved_safe_default_all_engines/err +++ b/test/cmdlineTests/model_checker_show_proved_safe_default_all_engines/err @@ -1,5 +1,5 @@ Warning: Function state mutability can be restricted to pure - --> model_checker_show_proved_safe_default_all_engines/input.sol:4:5: + --> input.sol:4:5: | 4 | function f(uint8 x) public { | ^ (Relevant source part starts here and spans across multiple lines). diff --git a/test/cmdlineTests/model_checker_show_proved_safe_default_bmc/err b/test/cmdlineTests/model_checker_show_proved_safe_default_bmc/err index f4a2d33e053b..7146c519260c 100644 --- a/test/cmdlineTests/model_checker_show_proved_safe_default_bmc/err +++ b/test/cmdlineTests/model_checker_show_proved_safe_default_bmc/err @@ -1,5 +1,5 @@ Warning: Function state mutability can be restricted to pure - --> model_checker_show_proved_safe_default_bmc/input.sol:4:5: + --> input.sol:4:5: | 4 | function f(uint8 x) public { | ^ (Relevant source part starts here and spans across multiple lines). diff --git a/test/cmdlineTests/model_checker_show_proved_safe_default_chc/err b/test/cmdlineTests/model_checker_show_proved_safe_default_chc/err index ab73c6bf56cd..730e43b9588e 100644 --- a/test/cmdlineTests/model_checker_show_proved_safe_default_chc/err +++ b/test/cmdlineTests/model_checker_show_proved_safe_default_chc/err @@ -1,5 +1,5 @@ Warning: Function state mutability can be restricted to pure - --> model_checker_show_proved_safe_default_chc/input.sol:4:5: + --> input.sol:4:5: | 4 | function f(uint8 x) public { | ^ (Relevant source part starts here and spans across multiple lines). diff --git a/test/cmdlineTests/model_checker_show_proved_safe_true_all_engines/err b/test/cmdlineTests/model_checker_show_proved_safe_true_all_engines/err index 297eb497a34d..d45cd29d3f6d 100644 --- a/test/cmdlineTests/model_checker_show_proved_safe_true_all_engines/err +++ b/test/cmdlineTests/model_checker_show_proved_safe_true_all_engines/err @@ -1,17 +1,17 @@ Warning: Function state mutability can be restricted to pure - --> model_checker_show_proved_safe_true_all_engines/input.sol:4:5: + --> input.sol:4:5: | 4 | function f(uint8 x) public { | ^ (Relevant source part starts here and spans across multiple lines). Info: CHC: Assertion violation check is safe! - --> model_checker_show_proved_safe_true_all_engines/input.sol:5:9: + --> input.sol:5:9: | 5 | assert(x >= 0); | ^^^^^^^^^^^^^^ Info: CHC: Assertion violation check is safe! - --> model_checker_show_proved_safe_true_all_engines/input.sol:6:9: + --> input.sol:6:9: | 6 | assert(x < 1000); | ^^^^^^^^^^^^^^^^ diff --git a/test/cmdlineTests/model_checker_show_proved_safe_true_bmc/err b/test/cmdlineTests/model_checker_show_proved_safe_true_bmc/err index bcec557f61ae..6bcf720faef7 100644 --- a/test/cmdlineTests/model_checker_show_proved_safe_true_bmc/err +++ b/test/cmdlineTests/model_checker_show_proved_safe_true_bmc/err @@ -1,17 +1,17 @@ Warning: Function state mutability can be restricted to pure - --> model_checker_show_proved_safe_true_bmc/input.sol:4:5: + --> input.sol:4:5: | 4 | function f(uint8 x) public { | ^ (Relevant source part starts here and spans across multiple lines). Info: BMC: Assertion violation check is safe! - --> model_checker_show_proved_safe_true_bmc/input.sol:5:9: + --> input.sol:5:9: | 5 | assert(x >= 0); | ^^^^^^^^^^^^^^ Info: BMC: Assertion violation check is safe! - --> model_checker_show_proved_safe_true_bmc/input.sol:6:9: + --> input.sol:6:9: | 6 | assert(x < 1000); | ^^^^^^^^^^^^^^^^ diff --git a/test/cmdlineTests/model_checker_show_proved_safe_true_chc/err b/test/cmdlineTests/model_checker_show_proved_safe_true_chc/err index fc14f494676f..d45cd29d3f6d 100644 --- a/test/cmdlineTests/model_checker_show_proved_safe_true_chc/err +++ b/test/cmdlineTests/model_checker_show_proved_safe_true_chc/err @@ -1,17 +1,17 @@ Warning: Function state mutability can be restricted to pure - --> model_checker_show_proved_safe_true_chc/input.sol:4:5: + --> input.sol:4:5: | 4 | function f(uint8 x) public { | ^ (Relevant source part starts here and spans across multiple lines). Info: CHC: Assertion violation check is safe! - --> model_checker_show_proved_safe_true_chc/input.sol:5:9: + --> input.sol:5:9: | 5 | assert(x >= 0); | ^^^^^^^^^^^^^^ Info: CHC: Assertion violation check is safe! - --> model_checker_show_proved_safe_true_chc/input.sol:6:9: + --> input.sol:6:9: | 6 | assert(x < 1000); | ^^^^^^^^^^^^^^^^ diff --git a/test/cmdlineTests/model_checker_show_unproved_true_all_engines/err b/test/cmdlineTests/model_checker_show_unproved_true_all_engines/err index 7a338f614952..18f317ac8c85 100644 --- a/test/cmdlineTests/model_checker_show_unproved_true_all_engines/err +++ b/test/cmdlineTests/model_checker_show_unproved_true_all_engines/err @@ -1,5 +1,5 @@ Warning: CHC: Assertion violation might happen here. - --> model_checker_show_unproved_true_all_engines/input.sol:10:9: + --> input.sol:10:9: | 10 | assert(s.x > 0); | ^^^^^^^^^^^^^^^ diff --git a/test/cmdlineTests/model_checker_show_unproved_true_chc/err b/test/cmdlineTests/model_checker_show_unproved_true_chc/err index 8274f4b463f2..e68e08677316 100644 --- a/test/cmdlineTests/model_checker_show_unproved_true_chc/err +++ b/test/cmdlineTests/model_checker_show_unproved_true_chc/err @@ -1,5 +1,5 @@ Warning: CHC: Assertion violation might happen here. - --> model_checker_show_unproved_true_chc/input.sol:10:9: + --> input.sol:10:9: | 10 | assert(s.x > 0); | ^^^^^^^^^^^^^^^ diff --git a/test/cmdlineTests/model_checker_show_unsupported_true_all_engines/err b/test/cmdlineTests/model_checker_show_unsupported_true_all_engines/err index 53c664ffc764..681a5995649d 100644 --- a/test/cmdlineTests/model_checker_show_unsupported_true_all_engines/err +++ b/test/cmdlineTests/model_checker_show_unsupported_true_all_engines/err @@ -1,5 +1,5 @@ Warning: Inline assembly may cause SMTChecker to produce spurious warnings (false positives). - --> model_checker_show_unsupported_true_all_engines/input.sol:5:9: + --> input.sol:5:9: | 5 | assembly {} | ^^^^^^^^^^^ diff --git a/test/cmdlineTests/model_checker_show_unsupported_true_bmc/err b/test/cmdlineTests/model_checker_show_unsupported_true_bmc/err index 013a7b0f118c..681a5995649d 100644 --- a/test/cmdlineTests/model_checker_show_unsupported_true_bmc/err +++ b/test/cmdlineTests/model_checker_show_unsupported_true_bmc/err @@ -1,5 +1,5 @@ Warning: Inline assembly may cause SMTChecker to produce spurious warnings (false positives). - --> model_checker_show_unsupported_true_bmc/input.sol:5:9: + --> input.sol:5:9: | 5 | assembly {} | ^^^^^^^^^^^ diff --git a/test/cmdlineTests/model_checker_show_unsupported_true_chc/err b/test/cmdlineTests/model_checker_show_unsupported_true_chc/err index 8dad0cc65bce..681a5995649d 100644 --- a/test/cmdlineTests/model_checker_show_unsupported_true_chc/err +++ b/test/cmdlineTests/model_checker_show_unsupported_true_chc/err @@ -1,5 +1,5 @@ Warning: Inline assembly may cause SMTChecker to produce spurious warnings (false positives). - --> model_checker_show_unsupported_true_chc/input.sol:5:9: + --> input.sol:5:9: | 5 | assembly {} | ^^^^^^^^^^^ diff --git a/test/cmdlineTests/model_checker_solvers_cvc5/err b/test/cmdlineTests/model_checker_solvers_cvc5/err index 1c36b103a65d..dcedef48bf09 100644 --- a/test/cmdlineTests/model_checker_solvers_cvc5/err +++ b/test/cmdlineTests/model_checker_solvers_cvc5/err @@ -1,5 +1,5 @@ Warning: BMC: Assertion violation happens here. - --> model_checker_solvers_cvc5/input.sol:5:3: + --> input.sol:5:3: | 5 | assert(x > 0); | ^^^^^^^^^^^^^ diff --git a/test/cmdlineTests/model_checker_solvers_cvc5_eld/err b/test/cmdlineTests/model_checker_solvers_cvc5_eld/err index 81a9f3a56342..b2cb662706f2 100644 --- a/test/cmdlineTests/model_checker_solvers_cvc5_eld/err +++ b/test/cmdlineTests/model_checker_solvers_cvc5_eld/err @@ -1,7 +1,7 @@ Info: CHC: 1 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. Warning: BMC: Condition is always false. - --> model_checker_solvers_cvc5_eld/input.sol:6:7: + --> input.sol:6:7: | 6 | if (y == 0) | ^^^^^^ diff --git a/test/cmdlineTests/model_checker_solvers_eld/err b/test/cmdlineTests/model_checker_solvers_eld/err index ff7ad37b313e..460764a0e997 100644 --- a/test/cmdlineTests/model_checker_solvers_eld/err +++ b/test/cmdlineTests/model_checker_solvers_eld/err @@ -1,5 +1,5 @@ Warning: CHC: Assertion violation happens here. - --> model_checker_solvers_eld/input.sol:5:3: + --> input.sol:5:3: | 5 | assert(x > 0); | ^^^^^^^^^^^^^ diff --git a/test/cmdlineTests/model_checker_solvers_z3/err b/test/cmdlineTests/model_checker_solvers_z3/err index 67349d8e17fe..18b8774650b9 100644 --- a/test/cmdlineTests/model_checker_solvers_z3/err +++ b/test/cmdlineTests/model_checker_solvers_z3/err @@ -6,7 +6,7 @@ x = 0 Transaction trace: test.constructor() test.f(0) - --> model_checker_solvers_z3/input.sol:5:3: + --> input.sol:5:3: | 5 | assert(x > 0); | ^^^^^^^^^^^^^ diff --git a/test/cmdlineTests/model_checker_solvers_z3_implicit/err b/test/cmdlineTests/model_checker_solvers_z3_implicit/err index 98d61828d9c1..18b8774650b9 100644 --- a/test/cmdlineTests/model_checker_solvers_z3_implicit/err +++ b/test/cmdlineTests/model_checker_solvers_z3_implicit/err @@ -6,7 +6,7 @@ x = 0 Transaction trace: test.constructor() test.f(0) - --> model_checker_solvers_z3_implicit/input.sol:5:3: + --> input.sol:5:3: | 5 | assert(x > 0); | ^^^^^^^^^^^^^ diff --git a/test/cmdlineTests/model_checker_solvers_z3_smtlib2/err b/test/cmdlineTests/model_checker_solvers_z3_smtlib2/err index 5699afcdeb3a..18b8774650b9 100644 --- a/test/cmdlineTests/model_checker_solvers_z3_smtlib2/err +++ b/test/cmdlineTests/model_checker_solvers_z3_smtlib2/err @@ -6,7 +6,7 @@ x = 0 Transaction trace: test.constructor() test.f(0) - --> model_checker_solvers_z3_smtlib2/input.sol:5:3: + --> input.sol:5:3: | 5 | assert(x > 0); | ^^^^^^^^^^^^^ diff --git a/test/cmdlineTests/model_checker_targets_all_all_engines/err b/test/cmdlineTests/model_checker_targets_all_all_engines/err index c67d97b61216..e095ba263c5a 100644 --- a/test/cmdlineTests/model_checker_targets_all_all_engines/err +++ b/test/cmdlineTests/model_checker_targets_all_all_engines/err @@ -8,7 +8,7 @@ Transaction trace: test.constructor() State: arr = [] test.f(0x0, 0) - --> model_checker_targets_all_all_engines/input.sol:7:3: + --> input.sol:7:3: | 7 | --x; | ^^^ @@ -23,7 +23,7 @@ Transaction trace: test.constructor() State: arr = [] test.f(0x0, 2) - --> model_checker_targets_all_all_engines/input.sol:8:3: + --> input.sol:8:3: | 8 | x + type(uint).max; | ^^^^^^^^^^^^^^^^^^ @@ -38,7 +38,7 @@ Transaction trace: test.constructor() State: arr = [] test.f(0x0, 1) - --> model_checker_targets_all_all_engines/input.sol:9:3: + --> input.sol:9:3: | 9 | 2 / x; | ^^^^^ @@ -53,7 +53,7 @@ Transaction trace: test.constructor() State: arr = [] test.f(0x0, 1) - --> model_checker_targets_all_all_engines/input.sol:11:3: + --> input.sol:11:3: | 11 | assert(x > 0); | ^^^^^^^^^^^^^ @@ -68,7 +68,7 @@ Transaction trace: test.constructor() State: arr = [] test.f(0x0, 1) - --> model_checker_targets_all_all_engines/input.sol:12:3: + --> input.sol:12:3: | 12 | arr.pop(); | ^^^^^^^^^ @@ -83,7 +83,7 @@ Transaction trace: test.constructor() State: arr = [] test.f(0x0, 1) - --> model_checker_targets_all_all_engines/input.sol:13:3: + --> input.sol:13:3: | 13 | arr[x]; | ^^^^^^ @@ -91,7 +91,7 @@ test.f(0x0, 1) Info: CHC: 1 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. Warning: BMC: Condition is always true. - --> model_checker_targets_all_all_engines/input.sol:6:11: + --> input.sol:6:11: | 6 | require(x >= 0); | ^^^^^^ diff --git a/test/cmdlineTests/model_checker_targets_all_bmc/err b/test/cmdlineTests/model_checker_targets_all_bmc/err index 27a51a67bd63..3887cc6b2a7f 100644 --- a/test/cmdlineTests/model_checker_targets_all_bmc/err +++ b/test/cmdlineTests/model_checker_targets_all_bmc/err @@ -1,12 +1,12 @@ Warning: BMC: Condition is always true. - --> model_checker_targets_all_bmc/input.sol:6:11: + --> input.sol:6:11: | 6 | require(x >= 0); | ^^^^^^ Note: Callstack: Warning: BMC: Underflow (resulting value less than 0) happens here. - --> model_checker_targets_all_bmc/input.sol:7:3: + --> input.sol:7:3: | 7 | --x; | ^^^ @@ -19,7 +19,7 @@ Note: Callstack: Note: Warning: BMC: Overflow (resulting value larger than 2**256 - 1) happens here. - --> model_checker_targets_all_bmc/input.sol:8:3: + --> input.sol:8:3: | 8 | x + type(uint).max; | ^^^^^^^^^^^^^^^^^^ @@ -32,7 +32,7 @@ Note: Callstack: Note: Warning: BMC: Division by zero happens here. - --> model_checker_targets_all_bmc/input.sol:9:3: + --> input.sol:9:3: | 9 | 2 / x; | ^^^^^ @@ -45,7 +45,7 @@ Note: Callstack: Note: Warning: BMC: Insufficient funds happens here. - --> model_checker_targets_all_bmc/input.sol:10:3: + --> input.sol:10:3: | 10 | a.transfer(x); | ^^^^^^^^^^^^^ @@ -57,7 +57,7 @@ Note: Callstack: Note: Warning: BMC: Assertion violation happens here. - --> model_checker_targets_all_bmc/input.sol:11:3: + --> input.sol:11:3: | 11 | assert(x > 0); | ^^^^^^^^^^^^^ diff --git a/test/cmdlineTests/model_checker_targets_all_chc/err b/test/cmdlineTests/model_checker_targets_all_chc/err index 9c257cefe9eb..c3853983af72 100644 --- a/test/cmdlineTests/model_checker_targets_all_chc/err +++ b/test/cmdlineTests/model_checker_targets_all_chc/err @@ -8,7 +8,7 @@ Transaction trace: test.constructor() State: arr = [] test.f(0x0, 0) - --> model_checker_targets_all_chc/input.sol:7:3: + --> input.sol:7:3: | 7 | --x; | ^^^ @@ -23,7 +23,7 @@ Transaction trace: test.constructor() State: arr = [] test.f(0x0, 2) - --> model_checker_targets_all_chc/input.sol:8:3: + --> input.sol:8:3: | 8 | x + type(uint).max; | ^^^^^^^^^^^^^^^^^^ @@ -38,7 +38,7 @@ Transaction trace: test.constructor() State: arr = [] test.f(0x0, 1) - --> model_checker_targets_all_chc/input.sol:9:3: + --> input.sol:9:3: | 9 | 2 / x; | ^^^^^ @@ -53,7 +53,7 @@ Transaction trace: test.constructor() State: arr = [] test.f(0x0, 1) - --> model_checker_targets_all_chc/input.sol:11:3: + --> input.sol:11:3: | 11 | assert(x > 0); | ^^^^^^^^^^^^^ @@ -68,7 +68,7 @@ Transaction trace: test.constructor() State: arr = [] test.f(0x0, 1) - --> model_checker_targets_all_chc/input.sol:12:3: + --> input.sol:12:3: | 12 | arr.pop(); | ^^^^^^^^^ @@ -83,7 +83,7 @@ Transaction trace: test.constructor() State: arr = [] test.f(0x0, 1) - --> model_checker_targets_all_chc/input.sol:13:3: + --> input.sol:13:3: | 13 | arr[x]; | ^^^^^^ diff --git a/test/cmdlineTests/model_checker_targets_assert_bmc/err b/test/cmdlineTests/model_checker_targets_assert_bmc/err index 90486bf792d9..27395c9dc507 100644 --- a/test/cmdlineTests/model_checker_targets_assert_bmc/err +++ b/test/cmdlineTests/model_checker_targets_assert_bmc/err @@ -1,5 +1,5 @@ Warning: BMC: Assertion violation happens here. - --> model_checker_targets_assert_bmc/input.sol:11:3: + --> input.sol:11:3: | 11 | assert(x > 0); | ^^^^^^^^^^^^^ diff --git a/test/cmdlineTests/model_checker_targets_assert_chc/err b/test/cmdlineTests/model_checker_targets_assert_chc/err index 1bf48bfa9abb..ada7c3d3dc90 100644 --- a/test/cmdlineTests/model_checker_targets_assert_chc/err +++ b/test/cmdlineTests/model_checker_targets_assert_chc/err @@ -8,7 +8,7 @@ Transaction trace: test.constructor() State: arr = [] test.f(0x0, 1) - --> model_checker_targets_assert_chc/input.sol:11:3: + --> input.sol:11:3: | 11 | assert(x > 0); | ^^^^^^^^^^^^^ diff --git a/test/cmdlineTests/model_checker_targets_balance_bmc/err b/test/cmdlineTests/model_checker_targets_balance_bmc/err index 39a8aac56df7..178bd66620bd 100644 --- a/test/cmdlineTests/model_checker_targets_balance_bmc/err +++ b/test/cmdlineTests/model_checker_targets_balance_bmc/err @@ -1,5 +1,5 @@ Warning: BMC: Insufficient funds happens here. - --> model_checker_targets_balance_bmc/input.sol:10:3: + --> input.sol:10:3: | 10 | a.transfer(x); | ^^^^^^^^^^^^^ diff --git a/test/cmdlineTests/model_checker_targets_constant_condition_bmc/err b/test/cmdlineTests/model_checker_targets_constant_condition_bmc/err index 6a376dd7ea5b..a7228dd768e8 100644 --- a/test/cmdlineTests/model_checker_targets_constant_condition_bmc/err +++ b/test/cmdlineTests/model_checker_targets_constant_condition_bmc/err @@ -1,5 +1,5 @@ Warning: BMC: Condition is always true. - --> model_checker_targets_constant_condition_bmc/input.sol:6:11: + --> input.sol:6:11: | 6 | require(x >= 0); | ^^^^^^ diff --git a/test/cmdlineTests/model_checker_targets_default_all_engines/err b/test/cmdlineTests/model_checker_targets_default_all_engines/err index 62d3b203cb9c..58cbc01f1436 100644 --- a/test/cmdlineTests/model_checker_targets_default_all_engines/err +++ b/test/cmdlineTests/model_checker_targets_default_all_engines/err @@ -8,7 +8,7 @@ Transaction trace: test.constructor() State: arr = [] test.f(0x0, 1) - --> model_checker_targets_default_all_engines/input.sol:9:3: + --> input.sol:9:3: | 9 | 2 / x; | ^^^^^ @@ -23,7 +23,7 @@ Transaction trace: test.constructor() State: arr = [] test.f(0x0, 1) - --> model_checker_targets_default_all_engines/input.sol:11:3: + --> input.sol:11:3: | 11 | assert(x > 0); | ^^^^^^^^^^^^^ @@ -38,7 +38,7 @@ Transaction trace: test.constructor() State: arr = [] test.f(0x0, 1) - --> model_checker_targets_default_all_engines/input.sol:12:3: + --> input.sol:12:3: | 12 | arr.pop(); | ^^^^^^^^^ @@ -53,7 +53,7 @@ Transaction trace: test.constructor() State: arr = [] test.f(0x0, 1) - --> model_checker_targets_default_all_engines/input.sol:13:3: + --> input.sol:13:3: | 13 | arr[x]; | ^^^^^^ @@ -61,7 +61,7 @@ test.f(0x0, 1) Info: CHC: 1 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them. Warning: BMC: Condition is always true. - --> model_checker_targets_default_all_engines/input.sol:6:11: + --> input.sol:6:11: | 6 | require(x >= 0); | ^^^^^^ diff --git a/test/cmdlineTests/model_checker_targets_default_bmc/err b/test/cmdlineTests/model_checker_targets_default_bmc/err index 1122be36b061..bc85e3cb4acc 100644 --- a/test/cmdlineTests/model_checker_targets_default_bmc/err +++ b/test/cmdlineTests/model_checker_targets_default_bmc/err @@ -1,12 +1,12 @@ Warning: BMC: Condition is always true. - --> model_checker_targets_default_bmc/input.sol:6:11: + --> input.sol:6:11: | 6 | require(x >= 0); | ^^^^^^ Note: Callstack: Warning: BMC: Division by zero happens here. - --> model_checker_targets_default_bmc/input.sol:9:3: + --> input.sol:9:3: | 9 | 2 / x; | ^^^^^ @@ -19,7 +19,7 @@ Note: Callstack: Note: Warning: BMC: Insufficient funds happens here. - --> model_checker_targets_default_bmc/input.sol:10:3: + --> input.sol:10:3: | 10 | a.transfer(x); | ^^^^^^^^^^^^^ @@ -31,7 +31,7 @@ Note: Callstack: Note: Warning: BMC: Assertion violation happens here. - --> model_checker_targets_default_bmc/input.sol:11:3: + --> input.sol:11:3: | 11 | assert(x > 0); | ^^^^^^^^^^^^^ diff --git a/test/cmdlineTests/model_checker_targets_default_chc/err b/test/cmdlineTests/model_checker_targets_default_chc/err index 70f3c5bc6072..e8b7382168ac 100644 --- a/test/cmdlineTests/model_checker_targets_default_chc/err +++ b/test/cmdlineTests/model_checker_targets_default_chc/err @@ -8,7 +8,7 @@ Transaction trace: test.constructor() State: arr = [] test.f(0x0, 1) - --> model_checker_targets_default_chc/input.sol:9:3: + --> input.sol:9:3: | 9 | 2 / x; | ^^^^^ @@ -23,7 +23,7 @@ Transaction trace: test.constructor() State: arr = [] test.f(0x0, 1) - --> model_checker_targets_default_chc/input.sol:11:3: + --> input.sol:11:3: | 11 | assert(x > 0); | ^^^^^^^^^^^^^ @@ -38,7 +38,7 @@ Transaction trace: test.constructor() State: arr = [] test.f(0x0, 1) - --> model_checker_targets_default_chc/input.sol:12:3: + --> input.sol:12:3: | 12 | arr.pop(); | ^^^^^^^^^ @@ -53,7 +53,7 @@ Transaction trace: test.constructor() State: arr = [] test.f(0x0, 1) - --> model_checker_targets_default_chc/input.sol:13:3: + --> input.sol:13:3: | 13 | arr[x]; | ^^^^^^ diff --git a/test/cmdlineTests/model_checker_targets_div_by_zero_bmc/err b/test/cmdlineTests/model_checker_targets_div_by_zero_bmc/err index bcf2c0c83a18..2d554ebceb7d 100644 --- a/test/cmdlineTests/model_checker_targets_div_by_zero_bmc/err +++ b/test/cmdlineTests/model_checker_targets_div_by_zero_bmc/err @@ -1,5 +1,5 @@ Warning: BMC: Division by zero happens here. - --> model_checker_targets_div_by_zero_bmc/input.sol:9:3: + --> input.sol:9:3: | 9 | 2 / x; | ^^^^^ diff --git a/test/cmdlineTests/model_checker_targets_div_by_zero_chc/err b/test/cmdlineTests/model_checker_targets_div_by_zero_chc/err index 3156dd90bd3f..81616b3bedab 100644 --- a/test/cmdlineTests/model_checker_targets_div_by_zero_chc/err +++ b/test/cmdlineTests/model_checker_targets_div_by_zero_chc/err @@ -8,7 +8,7 @@ Transaction trace: test.constructor() State: arr = [] test.f(0x0, 1) - --> model_checker_targets_div_by_zero_chc/input.sol:9:3: + --> input.sol:9:3: | 9 | 2 / x; | ^^^^^ diff --git a/test/cmdlineTests/model_checker_targets_out_of_bounds_chc/err b/test/cmdlineTests/model_checker_targets_out_of_bounds_chc/err index b4426a80e351..907a19f1e11a 100644 --- a/test/cmdlineTests/model_checker_targets_out_of_bounds_chc/err +++ b/test/cmdlineTests/model_checker_targets_out_of_bounds_chc/err @@ -8,7 +8,7 @@ Transaction trace: test.constructor() State: arr = [] test.f(0x0, 1) - --> model_checker_targets_out_of_bounds_chc/input.sol:13:3: + --> input.sol:13:3: | 13 | arr[x]; | ^^^^^^ diff --git a/test/cmdlineTests/model_checker_targets_overflow_bmc/err b/test/cmdlineTests/model_checker_targets_overflow_bmc/err index f2f475c304e8..a0f9ff1e07a9 100644 --- a/test/cmdlineTests/model_checker_targets_overflow_bmc/err +++ b/test/cmdlineTests/model_checker_targets_overflow_bmc/err @@ -1,5 +1,5 @@ Warning: BMC: Overflow (resulting value larger than 2**256 - 1) happens here. - --> model_checker_targets_overflow_bmc/input.sol:8:3: + --> input.sol:8:3: | 8 | x + type(uint).max; | ^^^^^^^^^^^^^^^^^^ diff --git a/test/cmdlineTests/model_checker_targets_overflow_chc/err b/test/cmdlineTests/model_checker_targets_overflow_chc/err index e7f98ff4dc7a..60298f02285a 100644 --- a/test/cmdlineTests/model_checker_targets_overflow_chc/err +++ b/test/cmdlineTests/model_checker_targets_overflow_chc/err @@ -8,7 +8,7 @@ Transaction trace: test.constructor() State: arr = [] test.f(0x0, 2) - --> model_checker_targets_overflow_chc/input.sol:8:3: + --> input.sol:8:3: | 8 | x + type(uint).max; | ^^^^^^^^^^^^^^^^^^ diff --git a/test/cmdlineTests/model_checker_targets_pop_empty_chc/err b/test/cmdlineTests/model_checker_targets_pop_empty_chc/err index d3478a700420..a01248775704 100644 --- a/test/cmdlineTests/model_checker_targets_pop_empty_chc/err +++ b/test/cmdlineTests/model_checker_targets_pop_empty_chc/err @@ -8,7 +8,7 @@ Transaction trace: test.constructor() State: arr = [] test.f(0x0, 1) - --> model_checker_targets_pop_empty_chc/input.sol:12:3: + --> input.sol:12:3: | 12 | arr.pop(); | ^^^^^^^^^ diff --git a/test/cmdlineTests/model_checker_targets_underflow_bmc/err b/test/cmdlineTests/model_checker_targets_underflow_bmc/err index 2162bec3aac9..db14639238c6 100644 --- a/test/cmdlineTests/model_checker_targets_underflow_bmc/err +++ b/test/cmdlineTests/model_checker_targets_underflow_bmc/err @@ -1,5 +1,5 @@ Warning: BMC: Underflow (resulting value less than 0) happens here. - --> model_checker_targets_underflow_bmc/input.sol:7:3: + --> input.sol:7:3: | 7 | --x; | ^^^ diff --git a/test/cmdlineTests/model_checker_targets_underflow_chc/err b/test/cmdlineTests/model_checker_targets_underflow_chc/err index 448b0e25ca7c..57c6649a40f4 100644 --- a/test/cmdlineTests/model_checker_targets_underflow_chc/err +++ b/test/cmdlineTests/model_checker_targets_underflow_chc/err @@ -8,7 +8,7 @@ Transaction trace: test.constructor() State: arr = [] test.f(0x0, 0) - --> model_checker_targets_underflow_chc/input.sol:7:3: + --> input.sol:7:3: | 7 | --x; | ^^^ diff --git a/test/cmdlineTests/model_checker_targets_underflow_overflow_assert_bmc/err b/test/cmdlineTests/model_checker_targets_underflow_overflow_assert_bmc/err index 9712b8cb7614..670b064ce183 100644 --- a/test/cmdlineTests/model_checker_targets_underflow_overflow_assert_bmc/err +++ b/test/cmdlineTests/model_checker_targets_underflow_overflow_assert_bmc/err @@ -1,5 +1,5 @@ Warning: BMC: Underflow (resulting value less than 0) happens here. - --> model_checker_targets_underflow_overflow_assert_bmc/input.sol:7:3: + --> input.sol:7:3: | 7 | --x; | ^^^ @@ -12,7 +12,7 @@ Note: Callstack: Note: Warning: BMC: Overflow (resulting value larger than 2**256 - 1) happens here. - --> model_checker_targets_underflow_overflow_assert_bmc/input.sol:8:3: + --> input.sol:8:3: | 8 | x + type(uint).max; | ^^^^^^^^^^^^^^^^^^ @@ -25,7 +25,7 @@ Note: Callstack: Note: Warning: BMC: Assertion violation happens here. - --> model_checker_targets_underflow_overflow_assert_bmc/input.sol:11:3: + --> input.sol:11:3: | 11 | assert(x > 0); | ^^^^^^^^^^^^^ diff --git a/test/cmdlineTests/model_checker_targets_underflow_overflow_assert_chc/err b/test/cmdlineTests/model_checker_targets_underflow_overflow_assert_chc/err index a0fbbe61a543..4602e76006dc 100644 --- a/test/cmdlineTests/model_checker_targets_underflow_overflow_assert_chc/err +++ b/test/cmdlineTests/model_checker_targets_underflow_overflow_assert_chc/err @@ -8,7 +8,7 @@ Transaction trace: test.constructor() State: arr = [] test.f(0x0, 0) - --> model_checker_targets_underflow_overflow_assert_chc/input.sol:7:3: + --> input.sol:7:3: | 7 | --x; | ^^^ @@ -23,7 +23,7 @@ Transaction trace: test.constructor() State: arr = [] test.f(0x0, 2) - --> model_checker_targets_underflow_overflow_assert_chc/input.sol:8:3: + --> input.sol:8:3: | 8 | x + type(uint).max; | ^^^^^^^^^^^^^^^^^^ @@ -38,7 +38,7 @@ Transaction trace: test.constructor() State: arr = [] test.f(0x0, 1) - --> model_checker_targets_underflow_overflow_assert_chc/input.sol:11:3: + --> input.sol:11:3: | 11 | assert(x > 0); | ^^^^^^^^^^^^^ diff --git a/test/cmdlineTests/model_checker_targets_underflow_overflow_bmc/err b/test/cmdlineTests/model_checker_targets_underflow_overflow_bmc/err index f3675ac5acbe..ea6dfb99cb5d 100644 --- a/test/cmdlineTests/model_checker_targets_underflow_overflow_bmc/err +++ b/test/cmdlineTests/model_checker_targets_underflow_overflow_bmc/err @@ -1,5 +1,5 @@ Warning: BMC: Underflow (resulting value less than 0) happens here. - --> model_checker_targets_underflow_overflow_bmc/input.sol:7:3: + --> input.sol:7:3: | 7 | --x; | ^^^ @@ -12,7 +12,7 @@ Note: Callstack: Note: Warning: BMC: Overflow (resulting value larger than 2**256 - 1) happens here. - --> model_checker_targets_underflow_overflow_bmc/input.sol:8:3: + --> input.sol:8:3: | 8 | x + type(uint).max; | ^^^^^^^^^^^^^^^^^^ diff --git a/test/cmdlineTests/model_checker_targets_underflow_overflow_chc/err b/test/cmdlineTests/model_checker_targets_underflow_overflow_chc/err index 0dcfb1c254a3..8eed85ac3de3 100644 --- a/test/cmdlineTests/model_checker_targets_underflow_overflow_chc/err +++ b/test/cmdlineTests/model_checker_targets_underflow_overflow_chc/err @@ -8,7 +8,7 @@ Transaction trace: test.constructor() State: arr = [] test.f(0x0, 0) - --> model_checker_targets_underflow_overflow_chc/input.sol:7:3: + --> input.sol:7:3: | 7 | --x; | ^^^ @@ -23,7 +23,7 @@ Transaction trace: test.constructor() State: arr = [] test.f(0x0, 2) - --> model_checker_targets_underflow_overflow_chc/input.sol:8:3: + --> input.sol:8:3: | 8 | x + type(uint).max; | ^^^^^^^^^^^^^^^^^^ diff --git a/test/cmdlineTests/name_simplifier/output b/test/cmdlineTests/name_simplifier/output index 04abaf600103..8eeff65b91a6 100644 --- a/test/cmdlineTests/name_simplifier/output +++ b/test/cmdlineTests/name_simplifier/output @@ -1,5 +1,5 @@ Optimized IR: -/// @use-src 0:"name_simplifier/input.sol" +/// @use-src 0:"input.sol" object "C_59" { code { { @@ -12,7 +12,7 @@ object "C_59" { return(_1, _2) } } - /// @use-src 0:"name_simplifier/input.sol" + /// @use-src 0:"input.sol" object "C_59_deployed" { code { { diff --git a/test/cmdlineTests/no_cbor_metadata/output b/test/cmdlineTests/no_cbor_metadata/output index 0328ece3f27c..295bc228bf1e 100644 --- a/test/cmdlineTests/no_cbor_metadata/output +++ b/test/cmdlineTests/no_cbor_metadata/output @@ -1,4 +1,4 @@ -======= no_cbor_metadata/input.sol:C ======= +======= input.sol:C ======= Binary: 608080604052346013576003908160188239f35b5f80fdfe5f80fd diff --git a/test/cmdlineTests/no_contract_combined_json/output b/test/cmdlineTests/no_contract_combined_json/output index 8c454e341442..a408cbdbc957 100644 --- a/test/cmdlineTests/no_contract_combined_json/output +++ b/test/cmdlineTests/no_contract_combined_json/output @@ -1,11 +1,11 @@ { "sourceList": [ - "no_contract_combined_json/input.sol" + "input.sol" ], "sources": { - "no_contract_combined_json/input.sol": { + "input.sol": { "AST": { - "absolutePath": "no_contract_combined_json/input.sol", + "absolutePath": "input.sol", "exportedSymbols": {}, "id": 2, "license": "GPL-3.0", diff --git a/test/cmdlineTests/no_import_callback/args b/test/cmdlineTests/no_import_callback/args index e816120d0db6..7efc6a77b677 100644 --- a/test/cmdlineTests/no_import_callback/args +++ b/test/cmdlineTests/no_import_callback/args @@ -1 +1 @@ ---no-import-callback no_import_callback/contract_1.sol +--no-import-callback contract_1.sol diff --git a/test/cmdlineTests/no_import_callback/err b/test/cmdlineTests/no_import_callback/err index 45690e34c8f2..c4e6d5701e22 100644 --- a/test/cmdlineTests/no_import_callback/err +++ b/test/cmdlineTests/no_import_callback/err @@ -1,5 +1,5 @@ Error: Source "contract_2.sol" not found: No import callback. - --> no_import_callback/contract_1.sol:4:1: + --> contract_1.sol:4:1: | 4 | import "contract_2.sol"; | ^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/test/cmdlineTests/object_compiler/output b/test/cmdlineTests/object_compiler/output index a88851b96c71..b552b3f241d5 100644 --- a/test/cmdlineTests/object_compiler/output +++ b/test/cmdlineTests/object_compiler/output @@ -1,5 +1,5 @@ -======= object_compiler/input.yul (EVM) ======= +======= input.yul (EVM) ======= Pretty printed source: object "MyContract" { @@ -26,40 +26,40 @@ Binary representation: 335f55600880600d5f395ff3fe5f545f5260205ff3 Text representation: - /* "object_compiler/input.yul":65:73 */ + /* "input.yul":65:73 */ caller - /* "object_compiler/input.yul":62:63 */ + /* "input.yul":62:63 */ 0x00 - /* "object_compiler/input.yul":55:74 */ + /* "input.yul":55:74 */ sstore - /* "object_compiler/input.yul":97:116 */ + /* "input.yul":97:116 */ dataSize(sub_0) - /* "object_compiler/input.yul":141:162 */ + /* "input.yul":141:162 */ dup1 dataOffset(sub_0) - /* "object_compiler/input.yul":138:139 */ + /* "input.yul":138:139 */ 0x00 - /* "object_compiler/input.yul":129:167 */ + /* "input.yul":129:167 */ codecopy - /* "object_compiler/input.yul":187:188 */ + /* "input.yul":187:188 */ 0x00 - /* "object_compiler/input.yul":180:193 */ + /* "input.yul":180:193 */ return stop sub_0: assembly { - /* "object_compiler/input.yul":294:295 */ + /* "input.yul":294:295 */ 0x00 - /* "object_compiler/input.yul":288:296 */ + /* "input.yul":288:296 */ sload - /* "object_compiler/input.yul":285:286 */ + /* "input.yul":285:286 */ 0x00 - /* "object_compiler/input.yul":278:297 */ + /* "input.yul":278:297 */ mstore - /* "object_compiler/input.yul":324:328 */ + /* "input.yul":324:328 */ 0x20 - /* "object_compiler/input.yul":321:322 */ + /* "input.yul":321:322 */ 0x00 - /* "object_compiler/input.yul":314:329 */ + /* "input.yul":314:329 */ return } diff --git a/test/cmdlineTests/optimize_full_storage_write/output b/test/cmdlineTests/optimize_full_storage_write/output index 9ebec71f0320..53e00008b08a 100644 --- a/test/cmdlineTests/optimize_full_storage_write/output +++ b/test/cmdlineTests/optimize_full_storage_write/output @@ -1,7 +1,7 @@ -======= optimize_full_storage_write/input.sol:OptimizeFullSlotWrite ======= +======= input.sol:OptimizeFullSlotWrite ======= EVM assembly: - /* "optimize_full_storage_write/input.sol":60:213 contract OptimizeFullSlotWrite {... */ + /* "input.sol":60:213 contract OptimizeFullSlotWrite {... */ mstore(0x40, 0x80) callvalue dup1 @@ -21,7 +21,7 @@ tag_1: stop sub_0: assembly { - /* "optimize_full_storage_write/input.sol":60:213 contract OptimizeFullSlotWrite {... */ + /* "input.sol":60:213 contract OptimizeFullSlotWrite {... */ mstore(0x40, 0x80) callvalue dup1 @@ -40,16 +40,16 @@ sub_0: assembly { jumpi tag_2: revert(0x00, 0x00) - /* "optimize_full_storage_write/input.sol":111:211 function f() public {... */ + /* "input.sol":111:211 function f() public {... */ tag_3: tag_4 - /* "optimize_full_storage_write/input.sol":192:207 nums[3] = 44444 */ + /* "input.sol":192:207 nums[3] = 44444 */ 0xad9c000000000000823500000000000056ce0000000000002b67 - /* "optimize_full_storage_write/input.sol":135:139 nums */ + /* "input.sol":135:139 nums */ 0x00 - /* "optimize_full_storage_write/input.sol":192:207 nums[3] = 44444 */ + /* "input.sol":192:207 nums[3] = 44444 */ sstore - /* "optimize_full_storage_write/input.sol":111:211 function f() public {... */ + /* "input.sol":111:211 function f() public {... */ jump tag_4: stop diff --git a/test/cmdlineTests/optimizer_BlockDeDuplicator/err b/test/cmdlineTests/optimizer_BlockDeDuplicator/err index e29fc4fc3fd7..9d851c2acd29 100644 --- a/test/cmdlineTests/optimizer_BlockDeDuplicator/err +++ b/test/cmdlineTests/optimizer_BlockDeDuplicator/err @@ -1,11 +1,11 @@ Warning: Statement has no effect. - --> optimizer_BlockDeDuplicator/input.sol:7:27: + --> input.sol:7:27: | 7 | function f() public { true ? 1 : 3;} | ^^^^^^^^^^^^ Warning: Function state mutability can be restricted to pure - --> optimizer_BlockDeDuplicator/input.sol:7:5: + --> input.sol:7:5: | 7 | function f() public { true ? 1 : 3;} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/test/cmdlineTests/optimizer_BlockDeDuplicator/output b/test/cmdlineTests/optimizer_BlockDeDuplicator/output index fb72e4bc1ee8..b3a645be3569 100644 --- a/test/cmdlineTests/optimizer_BlockDeDuplicator/output +++ b/test/cmdlineTests/optimizer_BlockDeDuplicator/output @@ -1,23 +1,23 @@ -======= optimizer_BlockDeDuplicator/input.sol:C ======= +======= input.sol:C ======= EVM assembly: - /* "optimizer_BlockDeDuplicator/input.sol":60:213 contract C {... */ + /* "input.sol":60:213 contract C {... */ mstore(0x40, 0x80) - /* "optimizer_BlockDeDuplicator/input.sol":179:210 function() r = true ? fun_x : f */ + /* "input.sol":179:210 function() r = true ? fun_x : f */ 0x00 dup1 sload not(sub(shl(0x40, 0x01), 0x01)) and - /* "optimizer_BlockDeDuplicator/input.sol":201:206 fun_x */ + /* "input.sol":201:206 fun_x */ or(tag_0_7, shl(0x20, tag_2)) sub(shl(0x40, 0x01), 0x01) - /* "optimizer_BlockDeDuplicator/input.sol":179:210 function() r = true ? fun_x : f */ + /* "input.sol":179:210 function() r = true ? fun_x : f */ and or swap1 sstore - /* "optimizer_BlockDeDuplicator/input.sol":60:213 contract C {... */ + /* "input.sol":60:213 contract C {... */ callvalue dup1 iszero @@ -27,10 +27,10 @@ EVM assembly: tag_5: pop jump(tag_6) - /* "optimizer_BlockDeDuplicator/input.sol":138:174 function f() public { true ? 1 : 3;} */ + /* "input.sol":138:174 function f() public { true ? 1 : 3;} */ tag_2: jump // out - /* "optimizer_BlockDeDuplicator/input.sol":60:213 contract C {... */ + /* "input.sol":60:213 contract C {... */ tag_6: dataSize(sub_0) dup1 @@ -42,7 +42,7 @@ tag_6: stop sub_0: assembly { - /* "optimizer_BlockDeDuplicator/input.sol":60:213 contract C {... */ + /* "input.sol":60:213 contract C {... */ mstore(0x40, 0x80) callvalue dup1 @@ -71,7 +71,7 @@ sub_0: assembly { jumpi tag_2: revert(0x00, 0x00) - /* "optimizer_BlockDeDuplicator/input.sol":138:174 function f() public { true ? 1 : 3;} */ + /* "input.sol":138:174 function f() public { true ? 1 : 3;} */ tag_3: stop tag_7: diff --git a/test/cmdlineTests/optimizer_array_sload/output b/test/cmdlineTests/optimizer_array_sload/output index c1e0796f56fa..a16ac43a0fda 100644 --- a/test/cmdlineTests/optimizer_array_sload/output +++ b/test/cmdlineTests/optimizer_array_sload/output @@ -1,5 +1,5 @@ Optimized IR: -/// @use-src 0:"optimizer_array_sload/input.sol" +/// @use-src 0:"input.sol" object "Arraysum_34" { code { { @@ -12,7 +12,7 @@ object "Arraysum_34" { return(_1, _2) } } - /// @use-src 0:"optimizer_array_sload/input.sol" + /// @use-src 0:"input.sol" object "Arraysum_34_deployed" { code { { diff --git a/test/cmdlineTests/optimizer_inliner_add/output b/test/cmdlineTests/optimizer_inliner_add/output index 9ebc9977daab..e4076c2fbc62 100644 --- a/test/cmdlineTests/optimizer_inliner_add/output +++ b/test/cmdlineTests/optimizer_inliner_add/output @@ -1,7 +1,7 @@ -======= optimizer_inliner_add/input.sol:C ======= +======= input.sol:C ======= EVM assembly: - /* "optimizer_inliner_add/input.sol":165:305 contract C {... */ + /* "input.sol":165:305 contract C {... */ mstore(0x40, 0x80) callvalue dup1 @@ -21,7 +21,7 @@ tag_1: stop sub_0: assembly { - /* "optimizer_inliner_add/input.sol":165:305 contract C {... */ + /* "input.sol":165:305 contract C {... */ mstore(0x40, 0x80) callvalue dup1 @@ -40,7 +40,7 @@ sub_0: assembly { jumpi tag_2: revert(0x00, 0x00) - /* "optimizer_inliner_add/input.sol":182:303 function f() public pure {... */ + /* "input.sol":182:303 function f() public pure {... */ tag_3: tag_4 tag_5 @@ -48,32 +48,32 @@ sub_0: assembly { tag_4: stop tag_5: - /* "optimizer_inliner_add/input.sol":221:227 uint x */ + /* "input.sol":221:227 uint x */ 0x00 - /* "optimizer_inliner_add/input.sol":217:297 for(uint x = 0; x < 10; x = unsafe_add(x, unsafe_add(x, 1)))... */ + /* "input.sol":217:297 for(uint x = 0; x < 10; x = unsafe_add(x, unsafe_add(x, 1)))... */ tag_7: - /* "optimizer_inliner_add/input.sol":237:239 10 */ + /* "input.sol":237:239 10 */ 0x0a - /* "optimizer_inliner_add/input.sol":233:234 x */ + /* "input.sol":233:234 x */ dup2 - /* "optimizer_inliner_add/input.sol":233:239 x < 10 */ + /* "input.sol":233:239 x < 10 */ lt - /* "optimizer_inliner_add/input.sol":217:297 for(uint x = 0; x < 10; x = unsafe_add(x, unsafe_add(x, 1)))... */ + /* "input.sol":217:297 for(uint x = 0; x < 10; x = unsafe_add(x, unsafe_add(x, 1)))... */ iszero tag_8 jumpi - /* "optimizer_inliner_add/input.sol":149:154 x + y */ + /* "input.sol":149:154 x + y */ dup1 add - /* "optimizer_inliner_add/input.sol":273:274 1 */ + /* "input.sol":273:274 1 */ 0x01 - /* "optimizer_inliner_add/input.sol":149:154 x + y */ + /* "input.sol":149:154 x + y */ add - /* "optimizer_inliner_add/input.sol":217:297 for(uint x = 0; x < 10; x = unsafe_add(x, unsafe_add(x, 1)))... */ + /* "input.sol":217:297 for(uint x = 0; x < 10; x = unsafe_add(x, unsafe_add(x, 1)))... */ jump(tag_7) tag_8: pop - /* "optimizer_inliner_add/input.sol":182:303 function f() public pure {... */ + /* "input.sol":182:303 function f() public pure {... */ jump // out auxdata: diff --git a/test/cmdlineTests/optimizer_inliner_call_from_constructor/output b/test/cmdlineTests/optimizer_inliner_call_from_constructor/output index f42f9de094c6..8c7b544bbdd6 100644 --- a/test/cmdlineTests/optimizer_inliner_call_from_constructor/output +++ b/test/cmdlineTests/optimizer_inliner_call_from_constructor/output @@ -1,9 +1,9 @@ -======= optimizer_inliner_call_from_constructor/input.sol:C ======= +======= input.sol:C ======= EVM assembly: - /* "optimizer_inliner_call_from_constructor/input.sol":60:263 contract C {... */ + /* "input.sol":60:263 contract C {... */ mstore(0x40, 0x80) - /* "optimizer_inliner_call_from_constructor/input.sol":89:115 constructor() { x = a(); } */ + /* "input.sol":89:115 constructor() { x = a(); } */ callvalue dup1 iszero @@ -12,13 +12,13 @@ EVM assembly: revert(0x00, 0x00) tag_1: pop - /* "optimizer_inliner_call_from_constructor/input.sol":257:258 6 */ + /* "input.sol":257:258 6 */ 0x06 - /* "optimizer_inliner_call_from_constructor/input.sol":105:106 x */ + /* "input.sol":105:106 x */ 0x00 - /* "optimizer_inliner_call_from_constructor/input.sol":105:112 x = a() */ + /* "input.sol":105:112 x = a() */ sstore - /* "optimizer_inliner_call_from_constructor/input.sol":60:263 contract C {... */ + /* "input.sol":60:263 contract C {... */ dataSize(sub_0) dup1 dataOffset(sub_0) @@ -29,7 +29,7 @@ tag_1: stop sub_0: assembly { - /* "optimizer_inliner_call_from_constructor/input.sol":60:263 contract C {... */ + /* "input.sol":60:263 contract C {... */ mstore(0x40, 0x80) callvalue dup1 @@ -48,11 +48,11 @@ sub_0: assembly { jumpi tag_2: revert(0x00, 0x00) - /* "optimizer_inliner_call_from_constructor/input.sol":120:175 function a() public pure returns (uint) { return f(); } */ + /* "input.sol":120:175 function a() public pure returns (uint) { return f(); } */ tag_3: - /* "optimizer_inliner_call_from_constructor/input.sol":257:258 6 */ + /* "input.sol":257:258 6 */ 0x06 - /* "optimizer_inliner_call_from_constructor/input.sol":120:175 function a() public pure returns (uint) { return f(); } */ + /* "input.sol":120:175 function a() public pure returns (uint) { return f(); } */ mload(0x40) /* "#utility.yul":160:185 */ swap1 @@ -62,7 +62,7 @@ sub_0: assembly { 0x20 /* "#utility.yul":133:151 */ add - /* "optimizer_inliner_call_from_constructor/input.sol":120:175 function a() public pure returns (uint) { return f(); } */ + /* "input.sol":120:175 function a() public pure returns (uint) { return f(); } */ mload(0x40) dup1 swap2 diff --git a/test/cmdlineTests/optimizer_inliner_dynamic_reference/output b/test/cmdlineTests/optimizer_inliner_dynamic_reference/output index b1c5c74d9037..5313893fc735 100644 --- a/test/cmdlineTests/optimizer_inliner_dynamic_reference/output +++ b/test/cmdlineTests/optimizer_inliner_dynamic_reference/output @@ -1,7 +1,7 @@ -======= optimizer_inliner_dynamic_reference/input.sol:C ======= +======= input.sol:C ======= EVM assembly: - /* "optimizer_inliner_dynamic_reference/input.sol":60:367 contract C {... */ + /* "input.sol":60:367 contract C {... */ mstore(0x40, 0x80) callvalue dup1 @@ -21,7 +21,7 @@ tag_1: stop sub_0: assembly { - /* "optimizer_inliner_dynamic_reference/input.sol":60:367 contract C {... */ + /* "input.sol":60:367 contract C {... */ mstore(0x40, 0x80) callvalue dup1 @@ -50,11 +50,11 @@ sub_0: assembly { jumpi tag_2: revert(0x00, 0x00) - /* "optimizer_inliner_dynamic_reference/input.sol":160:215 function a() public pure returns (uint) { return f(); } */ + /* "input.sol":160:215 function a() public pure returns (uint) { return f(); } */ tag_3: - /* "optimizer_inliner_dynamic_reference/input.sol":361:362 6 */ + /* "input.sol":361:362 6 */ 0x06 - /* "optimizer_inliner_dynamic_reference/input.sol":160:215 function a() public pure returns (uint) { return f(); } */ + /* "input.sol":160:215 function a() public pure returns (uint) { return f(); } */ tag_6: mload(0x40) /* "#utility.yul":160:185 */ @@ -65,78 +65,78 @@ sub_0: assembly { 0x20 /* "#utility.yul":133:151 */ add - /* "optimizer_inliner_dynamic_reference/input.sol":160:215 function a() public pure returns (uint) { return f(); } */ + /* "input.sol":160:215 function a() public pure returns (uint) { return f(); } */ mload(0x40) dup1 swap2 sub swap1 return - /* "optimizer_inliner_dynamic_reference/input.sol":246:305 function h() public view returns (uint) { return x() + 1; } */ + /* "input.sol":246:305 function h() public view returns (uint) { return x() + 1; } */ tag_4: tag_6 tag_11 jump // in - /* "optimizer_inliner_dynamic_reference/input.sol":125:155 function g() public { x = f; } */ + /* "input.sol":125:155 function g() public { x = f; } */ tag_5: - /* "optimizer_inliner_dynamic_reference/input.sol":147:148 x */ + /* "input.sol":147:148 x */ 0x00 - /* "optimizer_inliner_dynamic_reference/input.sol":147:152 x = f */ + /* "input.sol":147:152 x = f */ dup1 sload not(0xffffffffffffffff) and - /* "optimizer_inliner_dynamic_reference/input.sol":151:152 f */ + /* "input.sol":151:152 f */ tag_17 - /* "optimizer_inliner_dynamic_reference/input.sol":147:152 x = f */ + /* "input.sol":147:152 x = f */ or swap1 sstore - /* "optimizer_inliner_dynamic_reference/input.sol":125:155 function g() public { x = f; } */ + /* "input.sol":125:155 function g() public { x = f; } */ stop - /* "optimizer_inliner_dynamic_reference/input.sol":209:212 f() */ + /* "input.sol":209:212 f() */ tag_16: - /* "optimizer_inliner_dynamic_reference/input.sol":202:212 return f() */ + /* "input.sol":202:212 return f() */ swap1 pop - /* "optimizer_inliner_dynamic_reference/input.sol":160:215 function a() public pure returns (uint) { return f(); } */ + /* "input.sol":160:215 function a() public pure returns (uint) { return f(); } */ swap1 jump // out - /* "optimizer_inliner_dynamic_reference/input.sol":246:305 function h() public view returns (uint) { return x() + 1; } */ + /* "input.sol":246:305 function h() public view returns (uint) { return x() + 1; } */ tag_11: - /* "optimizer_inliner_dynamic_reference/input.sol":280:284 uint */ + /* "input.sol":280:284 uint */ 0x00 - /* "optimizer_inliner_dynamic_reference/input.sol":295:296 x */ + /* "input.sol":295:296 x */ dup1 sload - /* "optimizer_inliner_dynamic_reference/input.sol":295:298 x() */ + /* "input.sol":295:298 x() */ tag_19 swap1 - /* "optimizer_inliner_dynamic_reference/input.sol":295:296 x */ + /* "input.sol":295:296 x */ dup1 iszero tag_20 mul or - /* "optimizer_inliner_dynamic_reference/input.sol":295:298 x() */ + /* "input.sol":295:298 x() */ 0xffffffff and jump // in tag_19: - /* "optimizer_inliner_dynamic_reference/input.sol":295:302 x() + 1 */ + /* "input.sol":295:302 x() + 1 */ tag_16 swap1 - /* "optimizer_inliner_dynamic_reference/input.sol":301:302 1 */ + /* "input.sol":301:302 1 */ 0x01 - /* "optimizer_inliner_dynamic_reference/input.sol":295:302 x() + 1 */ + /* "input.sol":295:302 x() + 1 */ tag_22 jump // in - /* "optimizer_inliner_dynamic_reference/input.sol":310:365 function f() internal pure returns (uint) { return 6; } */ + /* "input.sol":310:365 function f() internal pure returns (uint) { return 6; } */ tag_17: - /* "optimizer_inliner_dynamic_reference/input.sol":361:362 6 */ + /* "input.sol":361:362 6 */ 0x06 swap1 - /* "optimizer_inliner_dynamic_reference/input.sol":310:365 function f() internal pure returns (uint) { return 6; } */ + /* "input.sol":310:365 function f() internal pure returns (uint) { return 6; } */ jump // out tag_20: tag_25 diff --git a/test/cmdlineTests/optimizer_inliner_dynamic_reference_constructor/output b/test/cmdlineTests/optimizer_inliner_dynamic_reference_constructor/output index 24ecaede0787..5997bd1c7b60 100644 --- a/test/cmdlineTests/optimizer_inliner_dynamic_reference_constructor/output +++ b/test/cmdlineTests/optimizer_inliner_dynamic_reference_constructor/output @@ -1,9 +1,9 @@ -======= optimizer_inliner_dynamic_reference_constructor/input.sol:C ======= +======= input.sol:C ======= EVM assembly: - /* "optimizer_inliner_dynamic_reference_constructor/input.sol":60:361 contract C {... */ + /* "input.sol":60:361 contract C {... */ mstore(0x40, 0x80) - /* "optimizer_inliner_dynamic_reference_constructor/input.sol":77:101 constructor() { x = f; } */ + /* "input.sol":77:101 constructor() { x = f; } */ callvalue dup1 iszero @@ -12,31 +12,31 @@ EVM assembly: revert(0x00, 0x00) tag_1: pop - /* "optimizer_inliner_dynamic_reference_constructor/input.sol":93:94 x */ + /* "input.sol":93:94 x */ 0x00 - /* "optimizer_inliner_dynamic_reference_constructor/input.sol":93:98 x = f */ + /* "input.sol":93:98 x = f */ dup1 sload not(sub(shl(0x40, 0x01), 0x01)) and - /* "optimizer_inliner_dynamic_reference_constructor/input.sol":97:98 f */ + /* "input.sol":97:98 f */ or(tag_0_12, shl(0x20, tag_4)) sub(shl(0x40, 0x01), 0x01) - /* "optimizer_inliner_dynamic_reference_constructor/input.sol":93:98 x = f */ + /* "input.sol":93:98 x = f */ and or swap1 sstore - /* "optimizer_inliner_dynamic_reference_constructor/input.sol":60:361 contract C {... */ + /* "input.sol":60:361 contract C {... */ jump(tag_5) - /* "optimizer_inliner_dynamic_reference_constructor/input.sol":304:359 function f() internal pure returns (uint) { return 6; } */ + /* "input.sol":304:359 function f() internal pure returns (uint) { return 6; } */ tag_4: - /* "optimizer_inliner_dynamic_reference_constructor/input.sol":355:356 6 */ + /* "input.sol":355:356 6 */ 0x06 swap1 - /* "optimizer_inliner_dynamic_reference_constructor/input.sol":304:359 function f() internal pure returns (uint) { return 6; } */ + /* "input.sol":304:359 function f() internal pure returns (uint) { return 6; } */ jump // out - /* "optimizer_inliner_dynamic_reference_constructor/input.sol":60:361 contract C {... */ + /* "input.sol":60:361 contract C {... */ tag_5: dataSize(sub_0) dup1 @@ -48,7 +48,7 @@ tag_5: stop sub_0: assembly { - /* "optimizer_inliner_dynamic_reference_constructor/input.sol":60:361 contract C {... */ + /* "input.sol":60:361 contract C {... */ mstore(0x40, 0x80) callvalue dup1 @@ -72,11 +72,11 @@ sub_0: assembly { jumpi tag_2: revert(0x00, 0x00) - /* "optimizer_inliner_dynamic_reference_constructor/input.sol":154:209 function a() public pure returns (uint) { return f(); } */ + /* "input.sol":154:209 function a() public pure returns (uint) { return f(); } */ tag_3: - /* "optimizer_inliner_dynamic_reference_constructor/input.sol":355:356 6 */ + /* "input.sol":355:356 6 */ 0x06 - /* "optimizer_inliner_dynamic_reference_constructor/input.sol":154:209 function a() public pure returns (uint) { return f(); } */ + /* "input.sol":154:209 function a() public pure returns (uint) { return f(); } */ tag_5: mload(0x40) /* "#utility.yul":160:185 */ @@ -87,61 +87,61 @@ sub_0: assembly { 0x20 /* "#utility.yul":133:151 */ add - /* "optimizer_inliner_dynamic_reference_constructor/input.sol":154:209 function a() public pure returns (uint) { return f(); } */ + /* "input.sol":154:209 function a() public pure returns (uint) { return f(); } */ mload(0x40) dup1 swap2 sub swap1 return - /* "optimizer_inliner_dynamic_reference_constructor/input.sol":240:299 function h() public view returns (uint) { return x() + 1; } */ + /* "input.sol":240:299 function h() public view returns (uint) { return x() + 1; } */ tag_4: tag_5 tag_10 jump // in - /* "optimizer_inliner_dynamic_reference_constructor/input.sol":203:206 f() */ + /* "input.sol":203:206 f() */ tag_14: - /* "optimizer_inliner_dynamic_reference_constructor/input.sol":196:206 return f() */ + /* "input.sol":196:206 return f() */ swap1 pop - /* "optimizer_inliner_dynamic_reference_constructor/input.sol":154:209 function a() public pure returns (uint) { return f(); } */ + /* "input.sol":154:209 function a() public pure returns (uint) { return f(); } */ swap1 jump // out - /* "optimizer_inliner_dynamic_reference_constructor/input.sol":240:299 function h() public view returns (uint) { return x() + 1; } */ + /* "input.sol":240:299 function h() public view returns (uint) { return x() + 1; } */ tag_10: - /* "optimizer_inliner_dynamic_reference_constructor/input.sol":274:278 uint */ + /* "input.sol":274:278 uint */ 0x00 - /* "optimizer_inliner_dynamic_reference_constructor/input.sol":289:290 x */ + /* "input.sol":289:290 x */ dup1 sload - /* "optimizer_inliner_dynamic_reference_constructor/input.sol":289:292 x() */ + /* "input.sol":289:292 x() */ tag_16 swap1 - /* "optimizer_inliner_dynamic_reference_constructor/input.sol":289:290 x */ + /* "input.sol":289:290 x */ dup1 iszero tag_17 mul or - /* "optimizer_inliner_dynamic_reference_constructor/input.sol":289:292 x() */ + /* "input.sol":289:292 x() */ 0xffffffff and jump // in tag_16: - /* "optimizer_inliner_dynamic_reference_constructor/input.sol":289:296 x() + 1 */ + /* "input.sol":289:296 x() + 1 */ tag_14 swap1 - /* "optimizer_inliner_dynamic_reference_constructor/input.sol":295:296 1 */ + /* "input.sol":295:296 1 */ 0x01 - /* "optimizer_inliner_dynamic_reference_constructor/input.sol":289:296 x() + 1 */ + /* "input.sol":289:296 x() + 1 */ tag_19 jump // in - /* "optimizer_inliner_dynamic_reference_constructor/input.sol":304:359 function f() internal pure returns (uint) { return 6; } */ + /* "input.sol":304:359 function f() internal pure returns (uint) { return 6; } */ tag_12: - /* "optimizer_inliner_dynamic_reference_constructor/input.sol":355:356 6 */ + /* "input.sol":355:356 6 */ 0x06 swap1 - /* "optimizer_inliner_dynamic_reference_constructor/input.sol":304:359 function f() internal pure returns (uint) { return 6; } */ + /* "input.sol":304:359 function f() internal pure returns (uint) { return 6; } */ jump // out tag_17: tag_21 diff --git a/test/cmdlineTests/optimizer_inliner_inc/output b/test/cmdlineTests/optimizer_inliner_inc/output index 3a3639e190a5..d634bf2d431b 100644 --- a/test/cmdlineTests/optimizer_inliner_inc/output +++ b/test/cmdlineTests/optimizer_inliner_inc/output @@ -1,7 +1,7 @@ -======= optimizer_inliner_inc/input.sol:C ======= +======= input.sol:C ======= EVM assembly: - /* "optimizer_inliner_inc/input.sol":157:279 contract C {... */ + /* "input.sol":157:279 contract C {... */ mstore(0x40, 0x80) callvalue dup1 @@ -21,7 +21,7 @@ tag_1: stop sub_0: assembly { - /* "optimizer_inliner_inc/input.sol":157:279 contract C {... */ + /* "input.sol":157:279 contract C {... */ mstore(0x40, 0x80) callvalue dup1 @@ -40,7 +40,7 @@ sub_0: assembly { jumpi tag_2: revert(0x00, 0x00) - /* "optimizer_inliner_inc/input.sol":174:277 function f() public pure {... */ + /* "input.sol":174:277 function f() public pure {... */ tag_3: tag_4 tag_5 @@ -48,29 +48,29 @@ sub_0: assembly { tag_4: stop tag_5: - /* "optimizer_inliner_inc/input.sol":213:219 uint x */ + /* "input.sol":213:219 uint x */ 0x00 - /* "optimizer_inliner_inc/input.sol":209:271 for(uint x = 0; x < 10; x = unsafe_inc(x))... */ + /* "input.sol":209:271 for(uint x = 0; x < 10; x = unsafe_inc(x))... */ tag_7: - /* "optimizer_inliner_inc/input.sol":229:231 10 */ + /* "input.sol":229:231 10 */ 0x0a - /* "optimizer_inliner_inc/input.sol":225:226 x */ + /* "input.sol":225:226 x */ dup2 - /* "optimizer_inliner_inc/input.sol":225:231 x < 10 */ + /* "input.sol":225:231 x < 10 */ lt - /* "optimizer_inliner_inc/input.sol":209:271 for(uint x = 0; x < 10; x = unsafe_inc(x))... */ + /* "input.sol":209:271 for(uint x = 0; x < 10; x = unsafe_inc(x))... */ iszero tag_8 jumpi - /* "optimizer_inliner_inc/input.sol":145:146 1 */ + /* "input.sol":145:146 1 */ 0x01 - /* "optimizer_inliner_inc/input.sol":141:146 x + 1 */ + /* "input.sol":141:146 x + 1 */ add - /* "optimizer_inliner_inc/input.sol":209:271 for(uint x = 0; x < 10; x = unsafe_inc(x))... */ + /* "input.sol":209:271 for(uint x = 0; x < 10; x = unsafe_inc(x))... */ jump(tag_7) tag_8: pop - /* "optimizer_inliner_inc/input.sol":174:277 function f() public pure {... */ + /* "input.sol":174:277 function f() public pure {... */ jump // out auxdata: diff --git a/test/cmdlineTests/optimizer_inliner_multireturn/output b/test/cmdlineTests/optimizer_inliner_multireturn/output index 46d74055a208..20de1c219961 100644 --- a/test/cmdlineTests/optimizer_inliner_multireturn/output +++ b/test/cmdlineTests/optimizer_inliner_multireturn/output @@ -1,7 +1,7 @@ -======= optimizer_inliner_multireturn/input.sol:C ======= +======= input.sol:C ======= EVM assembly: - /* "optimizer_inliner_multireturn/input.sol":162:298 contract C {... */ + /* "input.sol":162:298 contract C {... */ mstore(0x40, 0x80) callvalue dup1 @@ -21,7 +21,7 @@ tag_1: stop sub_0: assembly { - /* "optimizer_inliner_multireturn/input.sol":162:298 contract C {... */ + /* "input.sol":162:298 contract C {... */ mstore(0x40, 0x80) callvalue dup1 @@ -40,7 +40,7 @@ sub_0: assembly { jumpi tag_2: revert(0x00, 0x00) - /* "optimizer_inliner_multireturn/input.sol":179:296 function f() public pure {... */ + /* "input.sol":179:296 function f() public pure {... */ tag_3: tag_4 tag_5 @@ -48,35 +48,35 @@ sub_0: assembly { tag_4: stop tag_5: - /* "optimizer_inliner_multireturn/input.sol":219:225 uint x */ + /* "input.sol":219:225 uint x */ 0x00 - /* "optimizer_inliner_multireturn/input.sol":241:242 1 */ + /* "input.sol":241:242 1 */ 0x01 - /* "optimizer_inliner_multireturn/input.sol":214:290 for((uint x, uint y) = (0, 1); x < 10; (x, y) = test(x))... */ + /* "input.sol":214:290 for((uint x, uint y) = (0, 1); x < 10; (x, y) = test(x))... */ tag_7: - /* "optimizer_inliner_multireturn/input.sol":249:251 10 */ + /* "input.sol":249:251 10 */ 0x0a - /* "optimizer_inliner_multireturn/input.sol":245:246 x */ + /* "input.sol":245:246 x */ dup3 - /* "optimizer_inliner_multireturn/input.sol":245:251 x < 10 */ + /* "input.sol":245:251 x < 10 */ lt - /* "optimizer_inliner_multireturn/input.sol":214:290 for((uint x, uint y) = (0, 1); x < 10; (x, y) = test(x))... */ + /* "input.sol":214:290 for((uint x, uint y) = (0, 1); x < 10; (x, y) = test(x))... */ iszero tag_8 jumpi pop - /* "optimizer_inliner_multireturn/input.sol":146:147 1 */ + /* "input.sol":146:147 1 */ 0x01 - /* "optimizer_inliner_multireturn/input.sol":142:147 x + 1 */ + /* "input.sol":142:147 x + 1 */ dup2 add swap1 - /* "optimizer_inliner_multireturn/input.sol":214:290 for((uint x, uint y) = (0, 1); x < 10; (x, y) = test(x))... */ + /* "input.sol":214:290 for((uint x, uint y) = (0, 1); x < 10; (x, y) = test(x))... */ jump(tag_7) tag_8: pop pop - /* "optimizer_inliner_multireturn/input.sol":179:296 function f() public pure {... */ + /* "input.sol":179:296 function f() public pure {... */ jump // out auxdata: diff --git a/test/cmdlineTests/optimizer_user_yul/output b/test/cmdlineTests/optimizer_user_yul/output index c106c011b37c..b18e155bf947 100644 --- a/test/cmdlineTests/optimizer_user_yul/output +++ b/test/cmdlineTests/optimizer_user_yul/output @@ -1,71 +1,71 @@ -======= optimizer_user_yul/input.sol:C ======= +======= input.sol:C ======= EVM assembly: - /* "optimizer_user_yul/input.sol":60:518 contract C... */ + /* "input.sol":60:518 contract C... */ mstore(0x40, 0x80) - /* "optimizer_user_yul/input.sol":101:106 int a */ + /* "input.sol":101:106 int a */ 0x00 - /* "optimizer_user_yul/input.sol":181:190 let x,y,z */ + /* "input.sol":181:190 let x,y,z */ 0x00 0x00 0x00 - /* "optimizer_user_yul/input.sol":205:206 1 */ + /* "input.sol":205:206 1 */ 0x01 - /* "optimizer_user_yul/input.sol":202:203 0 */ + /* "input.sol":202:203 0 */ 0x00 - /* "optimizer_user_yul/input.sol":195:207 sstore(0, 1) */ + /* "input.sol":195:207 sstore(0, 1) */ sstore - /* "optimizer_user_yul/input.sol":212:258 for { } sload(4) { } {... */ + /* "input.sol":212:258 for { } sload(4) { } {... */ tag_3: - /* "optimizer_user_yul/input.sol":226:227 4 */ + /* "input.sol":226:227 4 */ 0x04 - /* "optimizer_user_yul/input.sol":220:228 sload(4) */ + /* "input.sol":220:228 sload(4) */ sload - /* "optimizer_user_yul/input.sol":212:258 for { } sload(4) { } {... */ + /* "input.sol":212:258 for { } sload(4) { } {... */ iszero tag_5 jumpi pop - /* "optimizer_user_yul/input.sol":244:253 exp(x, y) */ + /* "input.sol":244:253 exp(x, y) */ dup1 dup3 exp - /* "optimizer_user_yul/input.sol":212:258 for { } sload(4) { } {... */ + /* "input.sol":212:258 for { } sload(4) { } {... */ jump(tag_3) tag_5: - /* "optimizer_user_yul/input.sol":216:219 { } */ + /* "input.sol":216:219 { } */ pop pop pop - /* "optimizer_user_yul/input.sol":268:269 2 */ + /* "input.sol":268:269 2 */ 0x02 - /* "optimizer_user_yul/input.sol":263:269 a := 2 */ + /* "input.sol":263:269 a := 2 */ swap1 pop - /* "optimizer_user_yul/input.sol":369:370 3 */ + /* "input.sol":369:370 3 */ 0x03 - /* "optimizer_user_yul/input.sol":366:367 2 */ + /* "input.sol":366:367 2 */ 0x02 - /* "optimizer_user_yul/input.sol":359:371 sstore(2, 3) */ + /* "input.sol":359:371 sstore(2, 3) */ sstore - /* "optimizer_user_yul/input.sol":390:391 5 */ + /* "input.sol":390:391 5 */ 0x05 - /* "optimizer_user_yul/input.sol":384:392 sload(5) */ + /* "input.sol":384:392 sload(5) */ sload iszero - /* "optimizer_user_yul/input.sol":376:509 for { } sload(5) { } {... */ + /* "input.sol":376:509 for { } sload(5) { } {... */ tag_6: - /* "optimizer_user_yul/input.sol":384:392 sload(5) */ + /* "input.sol":384:392 sload(5) */ dup1 - /* "optimizer_user_yul/input.sol":376:509 for { } sload(5) { } {... */ + /* "input.sol":376:509 for { } sload(5) { } {... */ iszero tag_6 jumpi - /* "optimizer_user_yul/input.sol":380:383 { } */ + /* "input.sol":380:383 { } */ pop - /* "optimizer_user_yul/input.sol":340:513 {... */ + /* "input.sol":340:513 {... */ pop - /* "optimizer_user_yul/input.sol":60:518 contract C... */ + /* "input.sol":60:518 contract C... */ dataSize(sub_0) dup1 dataOffset(sub_0) @@ -76,7 +76,7 @@ tag_6: stop sub_0: assembly { - /* "optimizer_user_yul/input.sol":60:518 contract C... */ + /* "input.sol":60:518 contract C... */ mstore(0x40, 0x80) revert(0x00, 0x00) diff --git a/test/cmdlineTests/require_overload/err b/test/cmdlineTests/require_overload/err index 184c8c22bdd0..c267269fe43b 100644 --- a/test/cmdlineTests/require_overload/err +++ b/test/cmdlineTests/require_overload/err @@ -1,5 +1,5 @@ Error: No matching declaration found after argument-dependent lookup. - --> require_overload/input.sol:5:9: + --> input.sol:5:9: | 5 | require(this); | ^^^^^^^ diff --git a/test/cmdlineTests/require_with_error_ir/output b/test/cmdlineTests/require_with_error_ir/output index 09515f3cd82e..236931eea4cf 100644 --- a/test/cmdlineTests/require_with_error_ir/output +++ b/test/cmdlineTests/require_with_error_ir/output @@ -1,6 +1,6 @@ IR: -/// @use-src 0:"require_with_error_ir/input.sol" +/// @use-src 0:"input.sol" object "C_36" { code { @@ -27,7 +27,7 @@ object "C_36" { } } - /// @use-src 0:"require_with_error_ir/input.sol" + /// @use-src 0:"input.sol" object "C_36_deployed" { code { diff --git a/test/cmdlineTests/require_with_string_ir/output b/test/cmdlineTests/require_with_string_ir/output index 3a19db372796..9b0bd869fe3b 100644 --- a/test/cmdlineTests/require_with_string_ir/output +++ b/test/cmdlineTests/require_with_string_ir/output @@ -1,6 +1,6 @@ IR: -/// @use-src 0:"require_with_string_ir/input.sol" +/// @use-src 0:"input.sol" object "C_28" { code { @@ -27,7 +27,7 @@ object "C_28" { } } - /// @use-src 0:"require_with_string_ir/input.sol" + /// @use-src 0:"input.sol" object "C_28_deployed" { code { diff --git a/test/cmdlineTests/revert_strings/output b/test/cmdlineTests/revert_strings/output index 0f16ff9d0f8f..1fdb4b884c2d 100644 --- a/test/cmdlineTests/revert_strings/output +++ b/test/cmdlineTests/revert_strings/output @@ -1,6 +1,6 @@ IR: -/// @use-src 0:"revert_strings/input.sol" +/// @use-src 0:"input.sol" object "C_15" { code { /// @src 0:59:147 "contract C {..." @@ -46,7 +46,7 @@ object "C_15" { /// @src 0:59:147 "contract C {..." } - /// @use-src 0:"revert_strings/input.sol" + /// @use-src 0:"input.sol" object "C_15_deployed" { code { /// @src 0:59:147 "contract C {..." diff --git a/test/cmdlineTests/stack_too_deep_from_code_transform/err b/test/cmdlineTests/stack_too_deep_from_code_transform/err index 588f4d437945..8820cce05aff 100644 --- a/test/cmdlineTests/stack_too_deep_from_code_transform/err +++ b/test/cmdlineTests/stack_too_deep_from_code_transform/err @@ -1,6 +1,6 @@ Error: Cannot swap Variable value23 with Slot 0x20: too deep in the stack by 9 slots in [ RET value23 value22 value21 value20 value19 value18 value17 value16 value15 value14 value13 value12 value11 value10 value9 value8 value7 value6 value5 value4 value3 value2 value1 value0 pos 0x20 ] memoryguard was present. - --> stack_too_deep_from_code_transform/input.sol:1:1: + --> input.sol:1:1: | 1 | contract C { | ^ (Relevant source part starts here and spans across multiple lines). diff --git a/test/cmdlineTests/standard_debug_info_in_yul_and_evm_asm_print_all/input.json b/test/cmdlineTests/standard_debug_info_in_yul_and_evm_asm_print_all/input.json index 3059e1ecd3e3..14dec3178f24 100644 --- a/test/cmdlineTests/standard_debug_info_in_yul_and_evm_asm_print_all/input.json +++ b/test/cmdlineTests/standard_debug_info_in_yul_and_evm_asm_print_all/input.json @@ -1,7 +1,7 @@ { "language": "Solidity", "sources": { - "C": {"urls": ["standard_debug_info_in_yul_and_evm_asm_print_all/in.sol"]} + "C": {"urls": ["in.sol"]} }, "settings": { "debug": {"debugInfo": ["*"]}, diff --git a/test/cmdlineTests/standard_debug_info_in_yul_and_evm_asm_print_location_only/input.json b/test/cmdlineTests/standard_debug_info_in_yul_and_evm_asm_print_location_only/input.json index 8e338322b0c7..f2311603a09f 100644 --- a/test/cmdlineTests/standard_debug_info_in_yul_and_evm_asm_print_location_only/input.json +++ b/test/cmdlineTests/standard_debug_info_in_yul_and_evm_asm_print_location_only/input.json @@ -1,7 +1,7 @@ { "language": "Solidity", "sources": { - "C": {"urls": ["standard_debug_info_in_yul_and_evm_asm_print_location_only/in.sol"]} + "C": {"urls": ["in.sol"]} }, "settings": { "debug": {"debugInfo": ["location"]}, diff --git a/test/cmdlineTests/standard_debug_info_in_yul_and_evm_asm_print_none/input.json b/test/cmdlineTests/standard_debug_info_in_yul_and_evm_asm_print_none/input.json index c9184d944bfd..09386f2bef3d 100644 --- a/test/cmdlineTests/standard_debug_info_in_yul_and_evm_asm_print_none/input.json +++ b/test/cmdlineTests/standard_debug_info_in_yul_and_evm_asm_print_none/input.json @@ -1,7 +1,7 @@ { "language": "Solidity", "sources": { - "C": {"urls": ["standard_debug_info_in_yul_and_evm_asm_print_none/in.sol"]} + "C": {"urls": ["in.sol"]} }, "settings": { "debug": {"debugInfo": []}, diff --git a/test/cmdlineTests/standard_debug_info_in_yul_and_evm_asm_print_snippet_only/input.json b/test/cmdlineTests/standard_debug_info_in_yul_and_evm_asm_print_snippet_only/input.json index 962688913096..cb6ac84463ee 100644 --- a/test/cmdlineTests/standard_debug_info_in_yul_and_evm_asm_print_snippet_only/input.json +++ b/test/cmdlineTests/standard_debug_info_in_yul_and_evm_asm_print_snippet_only/input.json @@ -1,7 +1,7 @@ { "language": "Solidity", "sources": { - "C": {"urls": ["standard_debug_info_in_yul_and_evm_asm_print_snippet_only/in.sol"]} + "C": {"urls": ["in.sol"]} }, "settings": { "debug": {"debugInfo": ["snippet"]}, diff --git a/test/cmdlineTests/standard_irOptimized_ast_requested/input.json b/test/cmdlineTests/standard_irOptimized_ast_requested/input.json index fd16983068aa..23f17f4ae40d 100644 --- a/test/cmdlineTests/standard_irOptimized_ast_requested/input.json +++ b/test/cmdlineTests/standard_irOptimized_ast_requested/input.json @@ -1,7 +1,7 @@ { "language": "Solidity", "sources": { - "C": {"urls": ["standard_irOptimized_ast_requested/in.sol"]} + "C": {"urls": ["in.sol"]} }, "settings": { "outputSelection": {"*": {"*": ["irOptimizedAst"]}} diff --git a/test/cmdlineTests/standard_ir_ast_requested/input.json b/test/cmdlineTests/standard_ir_ast_requested/input.json index 1cb1083a2ef6..07cfc13edee7 100644 --- a/test/cmdlineTests/standard_ir_ast_requested/input.json +++ b/test/cmdlineTests/standard_ir_ast_requested/input.json @@ -1,7 +1,7 @@ { "language": "Solidity", "sources": { - "C": {"urls": ["standard_ir_ast_requested/in.sol"]} + "C": {"urls": ["in.sol"]} }, "settings": { "outputSelection": {"*": {"*": ["irAst"]}} diff --git a/test/cmdlineTests/standard_metadata/input.json b/test/cmdlineTests/standard_metadata/input.json index ae4bfe8f5965..8ca8da20a260 100644 --- a/test/cmdlineTests/standard_metadata/input.json +++ b/test/cmdlineTests/standard_metadata/input.json @@ -1,7 +1,7 @@ { "language": "Solidity", "sources": { - "C": {"urls": ["standard_metadata/in.sol"]} + "C": {"urls": ["in.sol"]} }, "settings": { "outputSelection": { diff --git a/test/cmdlineTests/standard_optimizer_invalid_detail_type/input.json b/test/cmdlineTests/standard_optimizer_invalid_detail_type/input.json index 5d65bb2e2269..52c0b9c7ac82 100644 --- a/test/cmdlineTests/standard_optimizer_invalid_detail_type/input.json +++ b/test/cmdlineTests/standard_optimizer_invalid_detail_type/input.json @@ -1,7 +1,7 @@ { "language": "Solidity", "sources": { - "A": {"urls": ["standard_optimizer_invalid_detail_type/in.sol"]} + "A": {"urls": ["in.sol"]} }, "settings": { "optimizer": {"details": {"peephole": 7}} diff --git a/test/cmdlineTests/standard_optimizer_invalid_details/input.json b/test/cmdlineTests/standard_optimizer_invalid_details/input.json index dbab578d6175..b6c590b5e87a 100644 --- a/test/cmdlineTests/standard_optimizer_invalid_details/input.json +++ b/test/cmdlineTests/standard_optimizer_invalid_details/input.json @@ -1,7 +1,7 @@ { "language": "Solidity", "sources": { - "A": {"urls": ["standard_optimizer_invalid_details/in.sol"]} + "A": {"urls": ["in.sol"]} }, "settings": { "optimizer": {"details": {"notThere": true}} diff --git a/test/cmdlineTests/standard_optimizer_no_yul/input.json b/test/cmdlineTests/standard_optimizer_no_yul/input.json index 42ab767be632..ad1199dcf318 100644 --- a/test/cmdlineTests/standard_optimizer_no_yul/input.json +++ b/test/cmdlineTests/standard_optimizer_no_yul/input.json @@ -1,7 +1,7 @@ { "language": "Solidity", "sources": { - "A": {"urls": ["standard_optimizer_no_yul/in.sol"]} + "A": {"urls": ["in.sol"]} }, "settings": { "optimizer": { diff --git a/test/cmdlineTests/standard_optimizer_yul/input.json b/test/cmdlineTests/standard_optimizer_yul/input.json index cf40ef970bbb..7d27780e54c1 100644 --- a/test/cmdlineTests/standard_optimizer_yul/input.json +++ b/test/cmdlineTests/standard_optimizer_yul/input.json @@ -1,7 +1,7 @@ { "language": "Solidity", "sources": { - "A": {"urls": ["standard_optimizer_yul/in.sol"]} + "A": {"urls": ["in.sol"]} }, "settings": { "optimizer": { diff --git a/test/cmdlineTests/standard_optimizer_yulDetails/input.json b/test/cmdlineTests/standard_optimizer_yulDetails/input.json index 6cdf504fd854..53f1981d492a 100644 --- a/test/cmdlineTests/standard_optimizer_yulDetails/input.json +++ b/test/cmdlineTests/standard_optimizer_yulDetails/input.json @@ -1,7 +1,7 @@ { "language": "Solidity", "sources": { - "A": {"urls": ["standard_optimizer_yulDetails/in.sol"]} + "A": {"urls": ["in.sol"]} }, "settings": { "optimizer": { diff --git a/test/cmdlineTests/standard_optimizer_yulDetails_no_object/input.json b/test/cmdlineTests/standard_optimizer_yulDetails_no_object/input.json index 4aba68350fb6..d132a4797ed2 100644 --- a/test/cmdlineTests/standard_optimizer_yulDetails_no_object/input.json +++ b/test/cmdlineTests/standard_optimizer_yulDetails_no_object/input.json @@ -1,7 +1,7 @@ { "language": "Solidity", "sources": { - "A": {"urls": ["standard_optimizer_yulDetails_no_object/in.sol"]} + "A": {"urls": ["in.sol"]} }, "settings": { "optimizer": { diff --git a/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps/input.json b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps/input.json index 584b8bf83e42..dca784c63fd6 100644 --- a/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps/input.json +++ b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps/input.json @@ -1,7 +1,7 @@ { "language": "Solidity", "sources": { - "A": {"urls": ["standard_optimizer_yulDetails_optimiserSteps/in.sol"]} + "A": {"urls": ["in.sol"]} }, "settings": { "optimizer": { diff --git a/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_invalid_abbreviation/input.json b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_invalid_abbreviation/input.json index 48de0cce3f51..ebdf48e3a478 100644 --- a/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_invalid_abbreviation/input.json +++ b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_invalid_abbreviation/input.json @@ -1,7 +1,7 @@ { "language": "Solidity", "sources": { - "A": {"urls": ["standard_optimizer_yulDetails_optimiserSteps_invalid_abbreviation/in.sol"]} + "A": {"urls": ["in.sol"]} }, "settings": { "optimizer": { diff --git a/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_invalid_nested_delimiter/input.json b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_invalid_nested_delimiter/input.json index 5be769f7676a..a93f21739315 100644 --- a/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_invalid_nested_delimiter/input.json +++ b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_invalid_nested_delimiter/input.json @@ -1,7 +1,7 @@ { "language": "Solidity", "sources": { - "A": {"urls": ["standard_optimizer_yulDetails_optimiserSteps_invalid_nested_delimiter/in.sol"]} + "A": {"urls": ["in.sol"]} }, "settings": { "optimizer": { diff --git a/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_mutliple_delimiters/input.json b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_mutliple_delimiters/input.json index 0bddd9d9dc23..4caee0761778 100644 --- a/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_mutliple_delimiters/input.json +++ b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_mutliple_delimiters/input.json @@ -1,7 +1,7 @@ { "language": "Solidity", "sources": { - "A": {"urls": ["standard_optimizer_yulDetails_optimiserSteps_mutliple_delimiters/in.sol"]} + "A": {"urls": ["in.sol"]} }, "settings": { "optimizer": { diff --git a/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_nested_brackets/input.json b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_nested_brackets/input.json index 2baf7a7235fc..bddd8d531ff4 100644 --- a/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_nested_brackets/input.json +++ b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_nested_brackets/input.json @@ -1,7 +1,7 @@ { "language": "Solidity", "sources": { - "A": {"urls": ["standard_optimizer_yulDetails_optimiserSteps_nested_brackets/in.sol"]} + "A": {"urls": ["in.sol"]} }, "settings": { "optimizer": { diff --git a/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_nesting_too_deep/input.json b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_nesting_too_deep/input.json index 1c055d91545e..08aba5ccc7f0 100644 --- a/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_nesting_too_deep/input.json +++ b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_nesting_too_deep/input.json @@ -1,7 +1,7 @@ { "language": "Solidity", "sources": { - "A": {"urls": ["standard_optimizer_yulDetails_optimiserSteps_nesting_too_deep/in.sol"]} + "A": {"urls": ["in.sol"]} }, "settings": { "optimizer": { diff --git a/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_no_yul/input.json b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_no_yul/input.json index 511860250476..586560917fa0 100644 --- a/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_no_yul/input.json +++ b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_no_yul/input.json @@ -1,7 +1,7 @@ { "language": "Solidity", "sources": { - "A": {"urls": ["standard_optimizer_yulDetails_optimiserSteps_no_yul/in.sol"]} + "A": {"urls": ["in.sol"]} }, "settings": { "optimizer": { diff --git a/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_type/input.json b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_type/input.json index e6f2abaa2847..0166a4248ee3 100644 --- a/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_type/input.json +++ b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_type/input.json @@ -1,7 +1,7 @@ { "language": "Solidity", "sources": { - "A": {"urls": ["standard_optimizer_yulDetails_optimiserSteps_type/in.sol"]} + "A": {"urls": ["in.sol"]} }, "settings": { "optimizer": { diff --git a/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_unbalanced_closing_bracket/input.json b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_unbalanced_closing_bracket/input.json index e3cd50027b17..554bfe2e5797 100644 --- a/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_unbalanced_closing_bracket/input.json +++ b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_unbalanced_closing_bracket/input.json @@ -1,7 +1,7 @@ { "language": "Solidity", "sources": { - "A": {"urls": ["standard_optimizer_yulDetails_optimiserSteps_unbalanced_closing_bracket/in.sol"]} + "A": {"urls": ["in.sol"]} }, "settings": { "optimizer": { diff --git a/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_unbalanced_opening_bracket/input.json b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_unbalanced_opening_bracket/input.json index 6cf7a233479c..aa4b172bbd0d 100644 --- a/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_unbalanced_opening_bracket/input.json +++ b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_unbalanced_opening_bracket/input.json @@ -1,7 +1,7 @@ { "language": "Solidity", "sources": { - "A": {"urls": ["standard_optimizer_yulDetails_optimiserSteps_unbalanced_opening_bracket/in.sol"]} + "A": {"urls": ["in.sol"]} }, "settings": { "optimizer": { diff --git a/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_with_cleanup_sequence/input.json b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_with_cleanup_sequence/input.json index b557a9662d8e..c3dde4dd3bbe 100644 --- a/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_with_cleanup_sequence/input.json +++ b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_with_cleanup_sequence/input.json @@ -1,7 +1,7 @@ { "language": "Solidity", "sources": { - "A": {"urls": ["standard_optimizer_yulDetails_optimiserSteps_with_cleanup_sequence/in.sol"]} + "A": {"urls": ["in.sol"]} }, "settings": { "optimizer": { diff --git a/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_with_empty_cleanup_sequence/input.json b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_with_empty_cleanup_sequence/input.json index 7d2f529ccf7f..c293911639f2 100644 --- a/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_with_empty_cleanup_sequence/input.json +++ b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_with_empty_cleanup_sequence/input.json @@ -1,7 +1,7 @@ { "language": "Solidity", "sources": { - "A": {"urls": ["standard_optimizer_yulDetails_optimiserSteps_with_empty_cleanup_sequence/in.sol"]} + "A": {"urls": ["in.sol"]} }, "settings": { "optimizer": { diff --git a/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_with_empty_optimisation_sequence/input.json b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_with_empty_optimisation_sequence/input.json index 9c603d6f7f0b..8c4801da597a 100644 --- a/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_with_empty_optimisation_sequence/input.json +++ b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_with_empty_optimisation_sequence/input.json @@ -1,7 +1,7 @@ { "language": "Solidity", "sources": { - "A": {"urls": ["standard_optimizer_yulDetails_optimiserSteps_with_empty_optimisation_sequence/in.sol"]} + "A": {"urls": ["in.sol"]} }, "settings": { "optimizer": { diff --git a/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_with_empty_sequence/input.json b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_with_empty_sequence/input.json index 5780bea83aa8..9d126b88ee4f 100644 --- a/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_with_empty_sequence/input.json +++ b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_with_empty_sequence/input.json @@ -1,7 +1,7 @@ { "language": "Solidity", "sources": { - "A": {"urls": ["standard_optimizer_yulDetails_optimiserSteps_with_empty_sequence/in.sol"]} + "A": {"urls": ["in.sol"]} }, "settings": { "optimizer": { diff --git a/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_with_empty_sequence_no_yul/input.json b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_with_empty_sequence_no_yul/input.json index 8e6add377cac..aecf8d9d5c1e 100644 --- a/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_with_empty_sequence_no_yul/input.json +++ b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_with_empty_sequence_no_yul/input.json @@ -1,7 +1,7 @@ { "language": "Solidity", "sources": { - "A": {"urls": ["standard_optimizer_yulDetails_optimiserSteps_with_empty_sequence_no_yul/in.sol"]} + "A": {"urls": ["in.sol"]} }, "settings": { "optimizer": { diff --git a/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_with_whitespace_newline_sequence_no_yul/input.json b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_with_whitespace_newline_sequence_no_yul/input.json index 321ac8e99ab8..1396b4269ab5 100644 --- a/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_with_whitespace_newline_sequence_no_yul/input.json +++ b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_with_whitespace_newline_sequence_no_yul/input.json @@ -1,7 +1,7 @@ { "language": "Solidity", "sources": { - "A": {"urls": ["standard_optimizer_yulDetails_optimiserSteps_with_whitespace_newline_sequence_no_yul/in.sol"]} + "A": {"urls": ["in.sol"]} }, "settings": { "optimizer": { diff --git a/test/cmdlineTests/standard_optimizer_yulDetails_without_yul/input.json b/test/cmdlineTests/standard_optimizer_yulDetails_without_yul/input.json index abd8cc0c8bac..8ccf21992999 100644 --- a/test/cmdlineTests/standard_optimizer_yulDetails_without_yul/input.json +++ b/test/cmdlineTests/standard_optimizer_yulDetails_without_yul/input.json @@ -1,7 +1,7 @@ { "language": "Solidity", "sources": { - "A": {"urls": ["standard_optimizer_yulDetails_optimiserSteps_without_yul/in.sol"]} + "A": {"urls": ["in.sol"]} }, "settings": { "optimizer": {"details": {"yulDetails": 7} diff --git a/test/cmdlineTests/standard_outputs_on_analysis_error_fatal/input.json b/test/cmdlineTests/standard_outputs_on_analysis_error_fatal/input.json index b640f033dc46..c157a2724884 100644 --- a/test/cmdlineTests/standard_outputs_on_analysis_error_fatal/input.json +++ b/test/cmdlineTests/standard_outputs_on_analysis_error_fatal/input.json @@ -1,7 +1,7 @@ { "language": "Solidity", "sources": { - "C": {"urls": ["standard_outputs_on_analysis_error_fatal/in.sol"]} + "C": {"urls": ["in.sol"]} }, "settings": { "outputSelection": { diff --git a/test/cmdlineTests/standard_outputs_on_analysis_error_fatal_after_current_step/input.json b/test/cmdlineTests/standard_outputs_on_analysis_error_fatal_after_current_step/input.json index 0214e00e8406..c157a2724884 100644 --- a/test/cmdlineTests/standard_outputs_on_analysis_error_fatal_after_current_step/input.json +++ b/test/cmdlineTests/standard_outputs_on_analysis_error_fatal_after_current_step/input.json @@ -1,7 +1,7 @@ { "language": "Solidity", "sources": { - "C": {"urls": ["standard_outputs_on_analysis_error_fatal_after_current_step/in.sol"]} + "C": {"urls": ["in.sol"]} }, "settings": { "outputSelection": { diff --git a/test/cmdlineTests/standard_outputs_on_analysis_error_non_fatal/input.json b/test/cmdlineTests/standard_outputs_on_analysis_error_non_fatal/input.json index 904ebc5bf287..c157a2724884 100644 --- a/test/cmdlineTests/standard_outputs_on_analysis_error_non_fatal/input.json +++ b/test/cmdlineTests/standard_outputs_on_analysis_error_non_fatal/input.json @@ -1,7 +1,7 @@ { "language": "Solidity", "sources": { - "C": {"urls": ["standard_outputs_on_analysis_error_non_fatal/in.sol"]} + "C": {"urls": ["in.sol"]} }, "settings": { "outputSelection": { diff --git a/test/cmdlineTests/standard_outputs_on_compilation_error/input.json b/test/cmdlineTests/standard_outputs_on_compilation_error/input.json index 855f007689b8..0555ba5e93f9 100644 --- a/test/cmdlineTests/standard_outputs_on_compilation_error/input.json +++ b/test/cmdlineTests/standard_outputs_on_compilation_error/input.json @@ -1,7 +1,7 @@ { "language": "Solidity", "sources": { - "C": {"urls": ["standard_outputs_on_compilation_error/in.sol"]} + "C": {"urls": ["in.sol"]} }, "settings": { "optimizer": {"enabled": true}, diff --git a/test/cmdlineTests/standard_outputs_on_parsing_error/input.json b/test/cmdlineTests/standard_outputs_on_parsing_error/input.json index a0d00c4e9e39..c157a2724884 100644 --- a/test/cmdlineTests/standard_outputs_on_parsing_error/input.json +++ b/test/cmdlineTests/standard_outputs_on_parsing_error/input.json @@ -1,7 +1,7 @@ { "language": "Solidity", "sources": { - "C": {"urls": ["standard_outputs_on_parsing_error/in.sol"]} + "C": {"urls": ["in.sol"]} }, "settings": { "outputSelection": { diff --git a/test/cmdlineTests/standard_stack_too_deep_from_code_transform/input.json b/test/cmdlineTests/standard_stack_too_deep_from_code_transform/input.json index a01e842b384d..dc86ac68494e 100644 --- a/test/cmdlineTests/standard_stack_too_deep_from_code_transform/input.json +++ b/test/cmdlineTests/standard_stack_too_deep_from_code_transform/input.json @@ -1,7 +1,7 @@ { "language": "Solidity", "sources": { - "in.sol": {"urls": ["standard_stack_too_deep_from_code_transform/in.sol"]} + "in.sol": {"urls": ["in.sol"]} }, "settings": { "viaIR": true, diff --git a/test/cmdlineTests/standard_stop_after_parsing_ast_requested/input.json b/test/cmdlineTests/standard_stop_after_parsing_ast_requested/input.json index 34f157495034..c09db6a6ed84 100644 --- a/test/cmdlineTests/standard_stop_after_parsing_ast_requested/input.json +++ b/test/cmdlineTests/standard_stop_after_parsing_ast_requested/input.json @@ -1,7 +1,7 @@ { "language": "Solidity", "sources": { - "C": {"urls": ["standard_stop_after_parsing_ast_requested/in.sol"]} + "C": {"urls": ["in.sol"]} }, "settings": { "stopAfter": "parsing", diff --git a/test/cmdlineTests/standard_stop_after_parsing_bytecode_requested/input.json b/test/cmdlineTests/standard_stop_after_parsing_bytecode_requested/input.json index 7ef3d37fd305..274ca87c44e4 100644 --- a/test/cmdlineTests/standard_stop_after_parsing_bytecode_requested/input.json +++ b/test/cmdlineTests/standard_stop_after_parsing_bytecode_requested/input.json @@ -1,7 +1,7 @@ { "language": "Solidity", "sources": { - "C": {"urls": ["standard_stop_after_parsing_bytecode_requested/in.sol"]} + "C": {"urls": ["in.sol"]} }, "settings": { "stopAfter": "parsing", diff --git a/test/cmdlineTests/standard_stop_after_parsing_non_binary_output_requested/input.json b/test/cmdlineTests/standard_stop_after_parsing_non_binary_output_requested/input.json index ac4d623c7103..597468e20432 100644 --- a/test/cmdlineTests/standard_stop_after_parsing_non_binary_output_requested/input.json +++ b/test/cmdlineTests/standard_stop_after_parsing_non_binary_output_requested/input.json @@ -1,7 +1,7 @@ { "language": "Solidity", "sources": { - "C": {"urls": ["standard_stop_after_parsing_non_binary_output_requested/in.sol"]} + "C": {"urls": ["in.sol"]} }, "settings": { "stopAfter": "parsing", diff --git a/test/cmdlineTests/standard_undeployable_contract_all_outputs/input.json b/test/cmdlineTests/standard_undeployable_contract_all_outputs/input.json index 4d2aea1f147a..ecb97bef2c3a 100644 --- a/test/cmdlineTests/standard_undeployable_contract_all_outputs/input.json +++ b/test/cmdlineTests/standard_undeployable_contract_all_outputs/input.json @@ -1,7 +1,7 @@ { "language": "Solidity", "sources": { - "C": {"urls": ["standard_undeployable_contract_all_outputs/in.sol"]} + "C": {"urls": ["in.sol"]} }, "settings": { "outputSelection": { diff --git a/test/cmdlineTests/standard_urls_existing_and_missing/input.json b/test/cmdlineTests/standard_urls_existing_and_missing/input.json index 686e8128eca2..575145836b39 100644 --- a/test/cmdlineTests/standard_urls_existing_and_missing/input.json +++ b/test/cmdlineTests/standard_urls_existing_and_missing/input.json @@ -3,9 +3,9 @@ "sources": { "url_not_found.sol": { "urls": [ - "standard_urls_existing_and_missing/non-existent-contract-1.sol", - "standard_urls_existing_and_missing/contract.sol", - "standard_urls_existing_and_missing/non-existent-contract-2.sol" + "non-existent-contract-1.sol", + "contract.sol", + "non-existent-contract-2.sol" ] } }, diff --git a/test/cmdlineTests/standard_urls_existing_and_missing/output.json b/test/cmdlineTests/standard_urls_existing_and_missing/output.json index e9db1135d764..4204cdb45b99 100644 --- a/test/cmdlineTests/standard_urls_existing_and_missing/output.json +++ b/test/cmdlineTests/standard_urls_existing_and_missing/output.json @@ -2,8 +2,8 @@ "errors": [ { "component": "general", - "formattedMessage": "Cannot import url (\"standard_urls_existing_and_missing/non-existent-contract-1.sol\"): File not found. Searched the following locations: \"\".", - "message": "Cannot import url (\"standard_urls_existing_and_missing/non-existent-contract-1.sol\"): File not found. Searched the following locations: \"\".", + "formattedMessage": "Cannot import url (\"non-existent-contract-1.sol\"): File not found. Searched the following locations: \"\".", + "message": "Cannot import url (\"non-existent-contract-1.sol\"): File not found. Searched the following locations: \"\".", "severity": "warning", "type": "Warning" } diff --git a/test/cmdlineTests/standard_urls_missing/input.json b/test/cmdlineTests/standard_urls_missing/input.json index fecc50eb03a6..5ba6e71619c6 100644 --- a/test/cmdlineTests/standard_urls_missing/input.json +++ b/test/cmdlineTests/standard_urls_missing/input.json @@ -3,9 +3,9 @@ "sources": { "url_not_found.sol": { "urls": [ - "standard_urls_missing/non-existent-contract-1.sol", - "standard_urls_missing/non-existent-contract.sol", - "standard_urls_missing/non-existent-contract-2.sol" + "non-existent-contract-1.sol", + "non-existent-contract.sol", + "non-existent-contract-2.sol" ] } }, diff --git a/test/cmdlineTests/standard_urls_missing/output.json b/test/cmdlineTests/standard_urls_missing/output.json index 7e2bb3dd59c2..8f766b055718 100644 --- a/test/cmdlineTests/standard_urls_missing/output.json +++ b/test/cmdlineTests/standard_urls_missing/output.json @@ -2,22 +2,22 @@ "errors": [ { "component": "general", - "formattedMessage": "Cannot import url (\"standard_urls_missing/non-existent-contract-1.sol\"): File not found. Searched the following locations: \"\".", - "message": "Cannot import url (\"standard_urls_missing/non-existent-contract-1.sol\"): File not found. Searched the following locations: \"\".", + "formattedMessage": "Cannot import url (\"non-existent-contract-1.sol\"): File not found. Searched the following locations: \"\".", + "message": "Cannot import url (\"non-existent-contract-1.sol\"): File not found. Searched the following locations: \"\".", "severity": "error", "type": "IOError" }, { "component": "general", - "formattedMessage": "Cannot import url (\"standard_urls_missing/non-existent-contract.sol\"): File not found. Searched the following locations: \"\".", - "message": "Cannot import url (\"standard_urls_missing/non-existent-contract.sol\"): File not found. Searched the following locations: \"\".", + "formattedMessage": "Cannot import url (\"non-existent-contract.sol\"): File not found. Searched the following locations: \"\".", + "message": "Cannot import url (\"non-existent-contract.sol\"): File not found. Searched the following locations: \"\".", "severity": "error", "type": "IOError" }, { "component": "general", - "formattedMessage": "Cannot import url (\"standard_urls_missing/non-existent-contract-2.sol\"): File not found. Searched the following locations: \"\".", - "message": "Cannot import url (\"standard_urls_missing/non-existent-contract-2.sol\"): File not found. Searched the following locations: \"\".", + "formattedMessage": "Cannot import url (\"non-existent-contract-2.sol\"): File not found. Searched the following locations: \"\".", + "message": "Cannot import url (\"non-existent-contract-2.sol\"): File not found. Searched the following locations: \"\".", "severity": "error", "type": "IOError" } diff --git a/test/cmdlineTests/standard_yul_cfg_json_export/input.json b/test/cmdlineTests/standard_yul_cfg_json_export/input.json index aee56abf8600..b5353721ee09 100644 --- a/test/cmdlineTests/standard_yul_cfg_json_export/input.json +++ b/test/cmdlineTests/standard_yul_cfg_json_export/input.json @@ -1,7 +1,7 @@ { "language": "Solidity", "sources": { - "C": {"urls": ["standard_yul_cfg_json_export/in.sol"]} + "C": {"urls": ["in.sol"]} }, "settings": { "optimizer": { diff --git a/test/cmdlineTests/standard_yul_code_generation_error/input.json b/test/cmdlineTests/standard_yul_code_generation_error/input.json index 905eef6c758a..0f4da43fc66d 100644 --- a/test/cmdlineTests/standard_yul_code_generation_error/input.json +++ b/test/cmdlineTests/standard_yul_code_generation_error/input.json @@ -1,6 +1,6 @@ { "language": "Yul", "sources": { - "C": {"urls": ["standard_yul_code_generation_error/in.yul"]} + "C": {"urls": ["in.yul"]} } } diff --git a/test/cmdlineTests/standard_yul_debug_info_ethdebug_compatible_output/input.json b/test/cmdlineTests/standard_yul_debug_info_ethdebug_compatible_output/input.json index 3e5b81c5ef69..e52867fa329d 100644 --- a/test/cmdlineTests/standard_yul_debug_info_ethdebug_compatible_output/input.json +++ b/test/cmdlineTests/standard_yul_debug_info_ethdebug_compatible_output/input.json @@ -3,7 +3,7 @@ "sources": { "C": { "urls": [ - "standard_yul_debug_info_ethdebug_compatible_output/in.yul" + "in.yul" ] } }, diff --git a/test/cmdlineTests/standard_yul_debug_info_ethdebug_incompatible_output/input.json b/test/cmdlineTests/standard_yul_debug_info_ethdebug_incompatible_output/input.json index f05e6f361aca..c2c501c96616 100644 --- a/test/cmdlineTests/standard_yul_debug_info_ethdebug_incompatible_output/input.json +++ b/test/cmdlineTests/standard_yul_debug_info_ethdebug_incompatible_output/input.json @@ -3,7 +3,7 @@ "sources": { "C": { "urls": [ - "standard_yul_debug_info_ethdebug_incompatible_output/in.yul" + "in.yul" ] } }, diff --git a/test/cmdlineTests/standard_yul_debug_info_ethdebug_verbatim_unimplemented/input.json b/test/cmdlineTests/standard_yul_debug_info_ethdebug_verbatim_unimplemented/input.json index be4fbb64fce3..16ef6ef33f74 100644 --- a/test/cmdlineTests/standard_yul_debug_info_ethdebug_verbatim_unimplemented/input.json +++ b/test/cmdlineTests/standard_yul_debug_info_ethdebug_verbatim_unimplemented/input.json @@ -3,7 +3,7 @@ "sources": { "C": { "urls": [ - "standard_yul_debug_info_ethdebug_verbatim_unimplemented/in.yul" + "in.yul" ] } }, diff --git a/test/cmdlineTests/standard_yul_debug_info_print_all/input.json b/test/cmdlineTests/standard_yul_debug_info_print_all/input.json index 1e6ed81a43a5..705c9ba7cc41 100644 --- a/test/cmdlineTests/standard_yul_debug_info_print_all/input.json +++ b/test/cmdlineTests/standard_yul_debug_info_print_all/input.json @@ -1,7 +1,7 @@ { "language": "Yul", "sources": { - "C": {"urls": ["standard_yul_debug_info_print_all/in.yul"]} + "C": {"urls": ["in.yul"]} }, "settings": { "debug": {"debugInfo": ["*"]}, diff --git a/test/cmdlineTests/standard_yul_debug_info_print_location_only/input.json b/test/cmdlineTests/standard_yul_debug_info_print_location_only/input.json index 867bc6e705ff..84ad0edadf18 100644 --- a/test/cmdlineTests/standard_yul_debug_info_print_location_only/input.json +++ b/test/cmdlineTests/standard_yul_debug_info_print_location_only/input.json @@ -1,7 +1,7 @@ { "language": "Yul", "sources": { - "C": {"urls": ["standard_yul_debug_info_print_location_only/in.yul"]} + "C": {"urls": ["in.yul"]} }, "settings": { "debug": {"debugInfo": ["location"]}, diff --git a/test/cmdlineTests/standard_yul_debug_info_print_none/input.json b/test/cmdlineTests/standard_yul_debug_info_print_none/input.json index 705cf3879e4e..13681dd8b114 100644 --- a/test/cmdlineTests/standard_yul_debug_info_print_none/input.json +++ b/test/cmdlineTests/standard_yul_debug_info_print_none/input.json @@ -1,7 +1,7 @@ { "language": "Yul", "sources": { - "C": {"urls": ["standard_yul_debug_info_print_none/in.yul"]} + "C": {"urls": ["in.yul"]} }, "settings": { "debug": {"debugInfo": []}, diff --git a/test/cmdlineTests/standard_yul_debug_info_print_snippet_only/input.json b/test/cmdlineTests/standard_yul_debug_info_print_snippet_only/input.json index ee247218f33e..ed74c075288f 100644 --- a/test/cmdlineTests/standard_yul_debug_info_print_snippet_only/input.json +++ b/test/cmdlineTests/standard_yul_debug_info_print_snippet_only/input.json @@ -1,7 +1,7 @@ { "language": "Yul", "sources": { - "C": {"urls": ["standard_yul_debug_info_print_snippet_only/in.yul"]} + "C": {"urls": ["in.yul"]} }, "settings": { "debug": {"debugInfo": ["snippet"]}, diff --git a/test/cmdlineTests/standard_yul_ethdebug_assign_immutable/input.json b/test/cmdlineTests/standard_yul_ethdebug_assign_immutable/input.json index 83acd4c42085..652620bedd51 100644 --- a/test/cmdlineTests/standard_yul_ethdebug_assign_immutable/input.json +++ b/test/cmdlineTests/standard_yul_ethdebug_assign_immutable/input.json @@ -1,7 +1,7 @@ { "language": "Yul", "sources": { - "C": {"urls": ["standard_yul_ethdebug_assign_immutable/in.yul"]} + "C": {"urls": ["in.yul"]} }, "settings": { "outputSelection": { diff --git a/test/cmdlineTests/standard_yul_ethdebug_bytecode_ir/input.json b/test/cmdlineTests/standard_yul_ethdebug_bytecode_ir/input.json index abfb7ee863af..67c5fedc7fd0 100644 --- a/test/cmdlineTests/standard_yul_ethdebug_bytecode_ir/input.json +++ b/test/cmdlineTests/standard_yul_ethdebug_bytecode_ir/input.json @@ -1,7 +1,7 @@ { "language": "Yul", "sources": { - "C": {"urls": ["standard_yul_ethdebug_bytecode_ir/in.yul"]} + "C": {"urls": ["in.yul"]} }, "settings": { "outputSelection": { diff --git a/test/cmdlineTests/standard_yul_ethdebug_bytecode_iroptimized/input.json b/test/cmdlineTests/standard_yul_ethdebug_bytecode_iroptimized/input.json index 54094c67305f..17949761f0f2 100644 --- a/test/cmdlineTests/standard_yul_ethdebug_bytecode_iroptimized/input.json +++ b/test/cmdlineTests/standard_yul_ethdebug_bytecode_iroptimized/input.json @@ -1,7 +1,7 @@ { "language": "Yul", "sources": { - "C": {"urls": ["standard_yul_ethdebug_bytecode_iroptimized/in.yul"]} + "C": {"urls": ["in.yul"]} }, "settings": { "outputSelection": { diff --git a/test/cmdlineTests/standard_yul_ethdebug_deployed_bytecode/input.json b/test/cmdlineTests/standard_yul_ethdebug_deployed_bytecode/input.json index e222dfeda8c2..5c5e9c5f76e1 100644 --- a/test/cmdlineTests/standard_yul_ethdebug_deployed_bytecode/input.json +++ b/test/cmdlineTests/standard_yul_ethdebug_deployed_bytecode/input.json @@ -1,7 +1,7 @@ { "language": "Yul", "sources": { - "C": {"urls": ["standard_yul_ethdebug_deployed_bytecode/in.yul"]} + "C": {"urls": ["in.yul"]} }, "settings": { "outputSelection": { diff --git a/test/cmdlineTests/standard_yul_ethdebug_deployed_bytecode_and_bytecode/input.json b/test/cmdlineTests/standard_yul_ethdebug_deployed_bytecode_and_bytecode/input.json index 20779012030d..655def5c1abf 100644 --- a/test/cmdlineTests/standard_yul_ethdebug_deployed_bytecode_and_bytecode/input.json +++ b/test/cmdlineTests/standard_yul_ethdebug_deployed_bytecode_and_bytecode/input.json @@ -1,7 +1,7 @@ { "language": "Yul", "sources": { - "C": {"urls": ["standard_yul_ethdebug_deployed_bytecode/in.yul"]} + "C": {"urls": ["in.yul"]} }, "settings": { "outputSelection": { diff --git a/test/cmdlineTests/standard_yul_ethdebug_ir/input.json b/test/cmdlineTests/standard_yul_ethdebug_ir/input.json index 3153a378db84..67c5fedc7fd0 100644 --- a/test/cmdlineTests/standard_yul_ethdebug_ir/input.json +++ b/test/cmdlineTests/standard_yul_ethdebug_ir/input.json @@ -1,7 +1,7 @@ { "language": "Yul", "sources": { - "C": {"urls": ["standard_yul_ethdebug_ir/in.yul"]} + "C": {"urls": ["in.yul"]} }, "settings": { "outputSelection": { diff --git a/test/cmdlineTests/standard_yul_ethdebug_iroptimize/input.json b/test/cmdlineTests/standard_yul_ethdebug_iroptimize/input.json index 180abcf31f8d..b08c9dcd7286 100644 --- a/test/cmdlineTests/standard_yul_ethdebug_iroptimize/input.json +++ b/test/cmdlineTests/standard_yul_ethdebug_iroptimize/input.json @@ -1,7 +1,7 @@ { "language": "Yul", "sources": { - "C": {"urls": ["standard_yul_ethdebug_iroptimize/in.yul"]} + "C": {"urls": ["in.yul"]} }, "settings": { "outputSelection": { diff --git a/test/cmdlineTests/standard_yul_ethdebug_optimize_ir/input.json b/test/cmdlineTests/standard_yul_ethdebug_optimize_ir/input.json index 9f0c8b0d5cef..d7aec1f0889c 100644 --- a/test/cmdlineTests/standard_yul_ethdebug_optimize_ir/input.json +++ b/test/cmdlineTests/standard_yul_ethdebug_optimize_ir/input.json @@ -1,7 +1,7 @@ { "language": "Yul", "sources": { - "C": {"urls": ["standard_yul_ethdebug_optimize_ir/in.yul"]} + "C": {"urls": ["in.yul"]} }, "settings": { "optimizer": { diff --git a/test/cmdlineTests/standard_yul_ethdebug_optimize_iroptimized/input.json b/test/cmdlineTests/standard_yul_ethdebug_optimize_iroptimized/input.json index 81b637abd5b5..eeabdbcb9845 100644 --- a/test/cmdlineTests/standard_yul_ethdebug_optimize_iroptimized/input.json +++ b/test/cmdlineTests/standard_yul_ethdebug_optimize_iroptimized/input.json @@ -1,7 +1,7 @@ { "language": "Yul", "sources": { - "C": {"urls": ["standard_yul_ethdebug_optimize_iroptimized/in.yul"]} + "C": {"urls": ["in.yul"]} }, "settings": { "optimizer": { diff --git a/test/cmdlineTests/stop_after_parsing_ast/output b/test/cmdlineTests/stop_after_parsing_ast/output index 6cca9557da1b..e6d54c42615c 100644 --- a/test/cmdlineTests/stop_after_parsing_ast/output +++ b/test/cmdlineTests/stop_after_parsing_ast/output @@ -1,9 +1,9 @@ JSON AST (compact format): -======= stop_after_parsing_ast/input.sol ======= +======= input.sol ======= { - "absolutePath": "stop_after_parsing_ast/input.sol", + "absolutePath": "input.sol", "id": 4, "license": "GPL-3.0", "nodeType": "SourceUnit", diff --git a/test/cmdlineTests/storage_layout_transient_value_types/input.json b/test/cmdlineTests/storage_layout_transient_value_types/input.json index 8c90a7dde233..7a12ca85c985 100644 --- a/test/cmdlineTests/storage_layout_transient_value_types/input.json +++ b/test/cmdlineTests/storage_layout_transient_value_types/input.json @@ -1,7 +1,7 @@ { "language": "Solidity", "sources": { - "fileA": {"urls": ["storage_layout_transient_value_types/in.sol"]} + "fileA": {"urls": ["in.sol"]} }, "settings": { "outputSelection": { diff --git a/test/cmdlineTests/storage_layout_user_defined/err b/test/cmdlineTests/storage_layout_user_defined/err index a9b5f07b19a0..e3815925acb9 100644 --- a/test/cmdlineTests/storage_layout_user_defined/err +++ b/test/cmdlineTests/storage_layout_user_defined/err @@ -1,2 +1,2 @@ Warning: Source file does not specify required compiler version! ---> storage_layout_user_defined/input.sol +--> input.sol diff --git a/test/cmdlineTests/storage_layout_user_defined/output b/test/cmdlineTests/storage_layout_user_defined/output index bb7819c66f12..d5be033ffe45 100644 --- a/test/cmdlineTests/storage_layout_user_defined/output +++ b/test/cmdlineTests/storage_layout_user_defined/output @@ -1,11 +1,11 @@ -======= storage_layout_user_defined/input.sol:C ======= +======= input.sol:C ======= Contract Storage Layout: { "storage": [ { "astId": 7, - "contract": "storage_layout_user_defined/input.sol:C", + "contract": "input.sol:C", "label": "a", "offset": 0, "slot": "0", @@ -13,7 +13,7 @@ Contract Storage Layout: }, { "astId": 10, - "contract": "storage_layout_user_defined/input.sol:C", + "contract": "input.sol:C", "label": "b", "offset": 16, "slot": "0", @@ -21,7 +21,7 @@ Contract Storage Layout: }, { "astId": 13, - "contract": "storage_layout_user_defined/input.sol:C", + "contract": "input.sol:C", "label": "c", "offset": 0, "slot": "1", @@ -29,7 +29,7 @@ Contract Storage Layout: }, { "astId": 16, - "contract": "storage_layout_user_defined/input.sol:C", + "contract": "input.sol:C", "label": "d", "offset": 16, "slot": "1", @@ -37,7 +37,7 @@ Contract Storage Layout: }, { "astId": 19, - "contract": "storage_layout_user_defined/input.sol:C", + "contract": "input.sol:C", "label": "e", "offset": 17, "slot": "1", @@ -45,7 +45,7 @@ Contract Storage Layout: }, { "astId": 22, - "contract": "storage_layout_user_defined/input.sol:C", + "contract": "input.sol:C", "label": "f", "offset": 18, "slot": "1", @@ -53,7 +53,7 @@ Contract Storage Layout: }, { "astId": 25, - "contract": "storage_layout_user_defined/input.sol:C", + "contract": "input.sol:C", "label": "g", "offset": 19, "slot": "1", @@ -61,7 +61,7 @@ Contract Storage Layout: }, { "astId": 28, - "contract": "storage_layout_user_defined/input.sol:C", + "contract": "input.sol:C", "label": "h", "offset": 20, "slot": "1", diff --git a/test/cmdlineTests/storage_layout_user_defined_no_pretty_print/output b/test/cmdlineTests/storage_layout_user_defined_no_pretty_print/output index 1be4da0b6ee9..54276e472651 100644 --- a/test/cmdlineTests/storage_layout_user_defined_no_pretty_print/output +++ b/test/cmdlineTests/storage_layout_user_defined_no_pretty_print/output @@ -1,4 +1,4 @@ -======= storage_layout_user_defined_no_pretty_print/input.sol:C ======= +======= input.sol:C ======= Contract Storage Layout: {"storage":[]} diff --git a/test/cmdlineTests/strict_asm_ast_compact_json/output b/test/cmdlineTests/strict_asm_ast_compact_json/output index b2271c36cb05..1099f0c12a37 100644 --- a/test/cmdlineTests/strict_asm_ast_compact_json/output +++ b/test/cmdlineTests/strict_asm_ast_compact_json/output @@ -1,5 +1,5 @@ -======= strict_asm_ast_compact_json/input.yul (EVM) ======= +======= input.yul (EVM) ======= AST: { diff --git a/test/cmdlineTests/strict_asm_debug_info_print_all/output b/test/cmdlineTests/strict_asm_debug_info_print_all/output index 0e58baf578e6..ea8afb6a2f06 100644 --- a/test/cmdlineTests/strict_asm_debug_info_print_all/output +++ b/test/cmdlineTests/strict_asm_debug_info_print_all/output @@ -1,5 +1,5 @@ -======= strict_asm_debug_info_print_all/input.yul (EVM) ======= +======= input.yul (EVM) ======= Pretty printed source: /// @use-src 0:"input.sol" diff --git a/test/cmdlineTests/strict_asm_debug_info_print_location_only/output b/test/cmdlineTests/strict_asm_debug_info_print_location_only/output index 17d2f50e2e15..06448d25ab42 100644 --- a/test/cmdlineTests/strict_asm_debug_info_print_location_only/output +++ b/test/cmdlineTests/strict_asm_debug_info_print_location_only/output @@ -1,5 +1,5 @@ -======= strict_asm_debug_info_print_location_only/input.yul (EVM) ======= +======= input.yul (EVM) ======= Pretty printed source: /// @use-src 0:"input.sol" diff --git a/test/cmdlineTests/strict_asm_debug_info_print_none/output b/test/cmdlineTests/strict_asm_debug_info_print_none/output index 51f779490ab7..93fc5c73e53b 100644 --- a/test/cmdlineTests/strict_asm_debug_info_print_none/output +++ b/test/cmdlineTests/strict_asm_debug_info_print_none/output @@ -1,5 +1,5 @@ -======= strict_asm_debug_info_print_none/input.yul (EVM) ======= +======= input.yul (EVM) ======= Pretty printed source: /// @use-src 0:"input.sol" diff --git a/test/cmdlineTests/strict_asm_eof_container_osaka/output b/test/cmdlineTests/strict_asm_eof_container_osaka/output index 81f01798a766..3582e09d6cb6 100644 --- a/test/cmdlineTests/strict_asm_eof_container_osaka/output +++ b/test/cmdlineTests/strict_asm_eof_container_osaka/output @@ -1,5 +1,5 @@ -======= strict_asm_eof_container_osaka/input.yul (EVM) ======= +======= input.yul (EVM) ======= Pretty printed source: object "object" { diff --git a/test/cmdlineTests/strict_asm_eof_dataloadn_osaka/output b/test/cmdlineTests/strict_asm_eof_dataloadn_osaka/output index 677c49b88a1b..9d256a5dd493 100644 --- a/test/cmdlineTests/strict_asm_eof_dataloadn_osaka/output +++ b/test/cmdlineTests/strict_asm_eof_dataloadn_osaka/output @@ -1,5 +1,5 @@ -======= strict_asm_eof_dataloadn_osaka/input.yul (EVM) ======= +======= input.yul (EVM) ======= Pretty printed source: object "a" { diff --git a/test/cmdlineTests/strict_asm_evm_version_byzantium/output b/test/cmdlineTests/strict_asm_evm_version_byzantium/output index 2840e1d2b697..a43e6e47c34c 100644 --- a/test/cmdlineTests/strict_asm_evm_version_byzantium/output +++ b/test/cmdlineTests/strict_asm_evm_version_byzantium/output @@ -1,5 +1,5 @@ -======= strict_asm_evm_version_byzantium/input.yul (EVM) ======= +======= input.yul (EVM) ======= Pretty printed source: object "object" { @@ -11,5 +11,5 @@ Binary representation: 00 Text representation: - /* "strict_asm_evm_version_byzantium/input.yul":27:34 */ + /* "input.yul":27:34 */ stop diff --git a/test/cmdlineTests/strict_asm_evm_version_constantinople/output b/test/cmdlineTests/strict_asm_evm_version_constantinople/output index 9362866b43dc..a43e6e47c34c 100644 --- a/test/cmdlineTests/strict_asm_evm_version_constantinople/output +++ b/test/cmdlineTests/strict_asm_evm_version_constantinople/output @@ -1,5 +1,5 @@ -======= strict_asm_evm_version_constantinople/input.yul (EVM) ======= +======= input.yul (EVM) ======= Pretty printed source: object "object" { @@ -11,5 +11,5 @@ Binary representation: 00 Text representation: - /* "strict_asm_evm_version_constantinople/input.yul":27:34 */ + /* "input.yul":27:34 */ stop diff --git a/test/cmdlineTests/strict_asm_jump/err b/test/cmdlineTests/strict_asm_jump/err index c0001f382533..419701b46660 100644 --- a/test/cmdlineTests/strict_asm_jump/err +++ b/test/cmdlineTests/strict_asm_jump/err @@ -1,5 +1,5 @@ Error: Function "jump" not found. - --> strict_asm_jump/input.yul:1:3: + --> input.yul:1:3: | 1 | { jump(1) } | ^^^^ diff --git a/test/cmdlineTests/strict_asm_msize_with_optimizer/output b/test/cmdlineTests/strict_asm_msize_with_optimizer/output index fbc1e69fac24..7f170e22f699 100644 --- a/test/cmdlineTests/strict_asm_msize_with_optimizer/output +++ b/test/cmdlineTests/strict_asm_msize_with_optimizer/output @@ -1,5 +1,5 @@ -======= strict_asm_msize_with_optimizer/input.yul (EVM) ======= +======= input.yul (EVM) ======= Pretty printed source: object "object" { diff --git a/test/cmdlineTests/strict_asm_msize_without_optimizer/output b/test/cmdlineTests/strict_asm_msize_without_optimizer/output index ac19efbcbc78..2ba00372efca 100644 --- a/test/cmdlineTests/strict_asm_msize_without_optimizer/output +++ b/test/cmdlineTests/strict_asm_msize_without_optimizer/output @@ -1,5 +1,5 @@ -======= strict_asm_msize_without_optimizer/input.yul (EVM) ======= +======= input.yul (EVM) ======= Pretty printed source: object "object" { diff --git a/test/cmdlineTests/strict_asm_only_cr/err b/test/cmdlineTests/strict_asm_only_cr/err index 0879e4f212db..334ade78f75e 100644 --- a/test/cmdlineTests/strict_asm_only_cr/err +++ b/test/cmdlineTests/strict_asm_only_cr/err @@ -1,5 +1,5 @@ Error: Expected keyword "object". - --> strict_asm_only_cr/input.yul:1:2: + --> input.yul:1:2: | 1 | | ^ diff --git a/test/cmdlineTests/strict_asm_optimizer_steps/output b/test/cmdlineTests/strict_asm_optimizer_steps/output index 58c91976185c..4e20c6218f87 100644 --- a/test/cmdlineTests/strict_asm_optimizer_steps/output +++ b/test/cmdlineTests/strict_asm_optimizer_steps/output @@ -1,5 +1,5 @@ -======= strict_asm_optimizer_steps/input.yul (EVM) ======= +======= input.yul (EVM) ======= Pretty printed source: object "C_6" { @@ -27,58 +27,58 @@ Binary representation: 608060405234601357600c60185f39600c5ff35b5f80fdfe608060405236155f555f80fd Text representation: - /* "strict_asm_optimizer_steps/input.yul":59:62 */ + /* "input.yul":59:62 */ 0x80 - /* "strict_asm_optimizer_steps/input.yul":55:57 */ + /* "input.yul":55:57 */ 0x40 - /* "strict_asm_optimizer_steps/input.yul":48:63 */ + /* "input.yul":48:63 */ mstore - /* "strict_asm_optimizer_steps/input.yul":79:90 */ + /* "input.yul":79:90 */ callvalue - /* "strict_asm_optimizer_steps/input.yul":76:107 */ + /* "input.yul":76:107 */ tag_1 jumpi - /* "strict_asm_optimizer_steps/input.yul":160:184 */ + /* "input.yul":160:184 */ dataSize(sub_0) - /* "strict_asm_optimizer_steps/input.yul":132:158 */ + /* "input.yul":132:158 */ dataOffset(sub_0) - /* "strict_asm_optimizer_steps/input.yul":129:130 */ + /* "input.yul":129:130 */ 0x00 - /* "strict_asm_optimizer_steps/input.yul":120:185 */ + /* "input.yul":120:185 */ codecopy - /* "strict_asm_optimizer_steps/input.yul":208:232 */ + /* "input.yul":208:232 */ dataSize(sub_0) - /* "strict_asm_optimizer_steps/input.yul":205:206 */ + /* "input.yul":205:206 */ 0x00 - /* "strict_asm_optimizer_steps/input.yul":198:233 */ + /* "input.yul":198:233 */ return - /* "strict_asm_optimizer_steps/input.yul":91:107 */ + /* "input.yul":91:107 */ tag_1: - /* "strict_asm_optimizer_steps/input.yul":103:104 */ + /* "input.yul":103:104 */ 0x00 - /* "strict_asm_optimizer_steps/input.yul":93:105 */ + /* "input.yul":93:105 */ dup1 revert stop sub_0: assembly { - /* "strict_asm_optimizer_steps/input.yul":334:337 */ + /* "input.yul":334:337 */ 0x80 - /* "strict_asm_optimizer_steps/input.yul":330:332 */ + /* "input.yul":330:332 */ 0x40 - /* "strict_asm_optimizer_steps/input.yul":323:338 */ + /* "input.yul":323:338 */ mstore - /* "strict_asm_optimizer_steps/input.yul":372:386 */ + /* "input.yul":372:386 */ calldatasize - /* "strict_asm_optimizer_steps/input.yul":365:387 */ + /* "input.yul":365:387 */ iszero - /* "strict_asm_optimizer_steps/input.yul":362:363 */ + /* "input.yul":362:363 */ 0x00 - /* "strict_asm_optimizer_steps/input.yul":355:388 */ + /* "input.yul":355:388 */ sstore - /* "strict_asm_optimizer_steps/input.yul":415:416 */ + /* "input.yul":415:416 */ 0x00 - /* "strict_asm_optimizer_steps/input.yul":405:417 */ + /* "input.yul":405:417 */ dup1 revert } diff --git a/test/cmdlineTests/strict_asm_output_selection_asm_only/output b/test/cmdlineTests/strict_asm_output_selection_asm_only/output index 317c9a9ae2fd..08932887f114 100644 --- a/test/cmdlineTests/strict_asm_output_selection_asm_only/output +++ b/test/cmdlineTests/strict_asm_output_selection_asm_only/output @@ -1,12 +1,12 @@ -======= strict_asm_output_selection_asm_only/input.yul (EVM) ======= +======= input.yul (EVM) ======= Text representation: - /* "strict_asm_output_selection_asm_only/input.yul":41:43 */ + /* "input.yul":41:43 */ 0x2a - /* "strict_asm_output_selection_asm_only/input.yul":38:39 */ + /* "input.yul":38:39 */ 0x00 - /* "strict_asm_output_selection_asm_only/input.yul":31:44 */ + /* "input.yul":31:44 */ sstore - /* "strict_asm_output_selection_asm_only/input.yul":27:48 */ + /* "input.yul":27:48 */ stop diff --git a/test/cmdlineTests/strict_asm_output_selection_bin_only/output b/test/cmdlineTests/strict_asm_output_selection_bin_only/output index 86d249576805..4edd88b33146 100644 --- a/test/cmdlineTests/strict_asm_output_selection_bin_only/output +++ b/test/cmdlineTests/strict_asm_output_selection_bin_only/output @@ -1,5 +1,5 @@ -======= strict_asm_output_selection_bin_only/input.yul (EVM) ======= +======= input.yul (EVM) ======= Binary representation: 602a5f5500 diff --git a/test/cmdlineTests/strict_asm_output_selection_ir_optimized_only/output b/test/cmdlineTests/strict_asm_output_selection_ir_optimized_only/output index 1fa4b72c7e2b..15174c71c8d3 100644 --- a/test/cmdlineTests/strict_asm_output_selection_ir_optimized_only/output +++ b/test/cmdlineTests/strict_asm_output_selection_ir_optimized_only/output @@ -1,5 +1,5 @@ -======= strict_asm_output_selection_ir_optimized_only/input.yul (EVM) ======= +======= input.yul (EVM) ======= Pretty printed source: object "object" { diff --git a/test/cmdlineTests/strict_asm_warning/err b/test/cmdlineTests/strict_asm_warning/err index 0661ae1ffec2..be47fb6ad90d 100644 --- a/test/cmdlineTests/strict_asm_warning/err +++ b/test/cmdlineTests/strict_asm_warning/err @@ -1,5 +1,5 @@ Warning: "selfdestruct" has been deprecated. Note that, starting from the Cancun hard fork, the underlying opcode no longer deletes the code and data associated with an account and only transfers its Ether to the beneficiary, unless executed in the same transaction in which the contract was created (see EIP-6780). Any use in newly deployed contracts is strongly discouraged even if the new behavior is taken into account. Future changes to the EVM might further reduce the functionality of the opcode. - --> strict_asm_warning/input.yul:4:5: + --> input.yul:4:5: | 4 | selfdestruct(0) | ^^^^^^^^^^^^ diff --git a/test/cmdlineTests/strict_asm_warning/output b/test/cmdlineTests/strict_asm_warning/output index 71cb2ce69a09..b71411dae89d 100644 --- a/test/cmdlineTests/strict_asm_warning/output +++ b/test/cmdlineTests/strict_asm_warning/output @@ -1,5 +1,5 @@ -======= strict_asm_warning/input.yul (EVM) ======= +======= input.yul (EVM) ======= Pretty printed source: object "object" { diff --git a/test/cmdlineTests/strict_asm_warning_and_error_optimize/err b/test/cmdlineTests/strict_asm_warning_and_error_optimize/err index 22366e3e7bf3..b008c021a832 100644 --- a/test/cmdlineTests/strict_asm_warning_and_error_optimize/err +++ b/test/cmdlineTests/strict_asm_warning_and_error_optimize/err @@ -1,11 +1,11 @@ Warning: "selfdestruct" has been deprecated. Note that, starting from the Cancun hard fork, the underlying opcode no longer deletes the code and data associated with an account and only transfers its Ether to the beneficiary, unless executed in the same transaction in which the contract was created (see EIP-6780). Any use in newly deployed contracts is strongly discouraged even if the new behavior is taken into account. Future changes to the EVM might further reduce the functionality of the opcode. - --> strict_asm_warning_and_error_optimize/input.yul:4:5: + --> input.yul:4:5: | 4 | selfdestruct() | ^^^^^^^^^^^^ Error: Function "selfdestruct" expects 1 arguments but got 0. - --> strict_asm_warning_and_error_optimize/input.yul:4:5: + --> input.yul:4:5: | 4 | selfdestruct() | ^^^^^^^^^^^^ diff --git a/test/cmdlineTests/strict_asm_warning_optimize/err b/test/cmdlineTests/strict_asm_warning_optimize/err index 098aa00baf69..be47fb6ad90d 100644 --- a/test/cmdlineTests/strict_asm_warning_optimize/err +++ b/test/cmdlineTests/strict_asm_warning_optimize/err @@ -1,5 +1,5 @@ Warning: "selfdestruct" has been deprecated. Note that, starting from the Cancun hard fork, the underlying opcode no longer deletes the code and data associated with an account and only transfers its Ether to the beneficiary, unless executed in the same transaction in which the contract was created (see EIP-6780). Any use in newly deployed contracts is strongly discouraged even if the new behavior is taken into account. Future changes to the EVM might further reduce the functionality of the opcode. - --> strict_asm_warning_optimize/input.yul:4:5: + --> input.yul:4:5: | 4 | selfdestruct(0) | ^^^^^^^^^^^^ diff --git a/test/cmdlineTests/strict_asm_warning_optimize/output b/test/cmdlineTests/strict_asm_warning_optimize/output index d933dcb05525..b71411dae89d 100644 --- a/test/cmdlineTests/strict_asm_warning_optimize/output +++ b/test/cmdlineTests/strict_asm_warning_optimize/output @@ -1,5 +1,5 @@ -======= strict_asm_warning_optimize/input.yul (EVM) ======= +======= input.yul (EVM) ======= Pretty printed source: object "object" { diff --git a/test/cmdlineTests/strict_asm_warning_optimize_unreachable/err b/test/cmdlineTests/strict_asm_warning_optimize_unreachable/err index 4535680baa59..4465b2c242d9 100644 --- a/test/cmdlineTests/strict_asm_warning_optimize_unreachable/err +++ b/test/cmdlineTests/strict_asm_warning_optimize_unreachable/err @@ -1,5 +1,5 @@ Warning: "selfdestruct" has been deprecated. Note that, starting from the Cancun hard fork, the underlying opcode no longer deletes the code and data associated with an account and only transfers its Ether to the beneficiary, unless executed in the same transaction in which the contract was created (see EIP-6780). Any use in newly deployed contracts is strongly discouraged even if the new behavior is taken into account. Future changes to the EVM might further reduce the functionality of the opcode. - --> strict_asm_warning_optimize_unreachable/input.yul:7:5: + --> input.yul:7:5: | 7 | selfdestruct(0) | ^^^^^^^^^^^^ diff --git a/test/cmdlineTests/strict_asm_warning_optimize_unreachable/output b/test/cmdlineTests/strict_asm_warning_optimize_unreachable/output index 508e9d8ed4ef..a2c2516af78d 100644 --- a/test/cmdlineTests/strict_asm_warning_optimize_unreachable/output +++ b/test/cmdlineTests/strict_asm_warning_optimize_unreachable/output @@ -1,5 +1,5 @@ -======= strict_asm_warning_optimize_unreachable/input.yul (EVM) ======= +======= input.yul (EVM) ======= Pretty printed source: object "object" { diff --git a/test/cmdlineTests/strict_asm_yul_cfg_json_export/output b/test/cmdlineTests/strict_asm_yul_cfg_json_export/output index c79692c3c035..e0bb1af40952 100644 --- a/test/cmdlineTests/strict_asm_yul_cfg_json_export/output +++ b/test/cmdlineTests/strict_asm_yul_cfg_json_export/output @@ -1,5 +1,5 @@ -======= strict_asm_yul_cfg_json_export/input.yul (EVM) ======= +======= input.yul (EVM) ======= Yul Control Flow Graph: { diff --git a/test/cmdlineTests/structured_documentation_source_location/err b/test/cmdlineTests/structured_documentation_source_location/err index 1f69adf4f63d..51d3a652ee77 100644 --- a/test/cmdlineTests/structured_documentation_source_location/err +++ b/test/cmdlineTests/structured_documentation_source_location/err @@ -1,11 +1,11 @@ Error: Documentation tag "@return No value returned" does not contain the name of its return parameter. - --> structured_documentation_source_location/input.sol:4:5: + --> input.sol:4:5: | 4 | /// @param id Some identifier | ^ (Relevant source part starts here and spans across multiple lines). Error: Documentation tag "@return No value returned" does not contain the name of its return parameter. - --> structured_documentation_source_location/input.sol:8:5: + --> input.sol:8:5: | 8 | /// @return No value returned | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/test/cmdlineTests/too_long_line/err b/test/cmdlineTests/too_long_line/err index 25620bd4c5e2..626812e5f7bd 100644 --- a/test/cmdlineTests/too_long_line/err +++ b/test/cmdlineTests/too_long_line/err @@ -1,5 +1,5 @@ Error: Identifier not found or not unique. - --> too_long_line/input.sol:5:164: + --> input.sol:5:164: | 5 | ... ffffffffffffffffffffffffffffffffff(announcementType Type, string Announcement, string ... | ^^^^^^^^^^^^^^^^ diff --git a/test/cmdlineTests/too_long_line_both_sides_short/err b/test/cmdlineTests/too_long_line_both_sides_short/err index 5992d6ea9387..194047c580b4 100644 --- a/test/cmdlineTests/too_long_line_both_sides_short/err +++ b/test/cmdlineTests/too_long_line_both_sides_short/err @@ -1,5 +1,5 @@ Error: Identifier not found or not unique. - --> too_long_line_both_sides_short/input.sol:5:15: + --> input.sol:5:15: | 5 | function f(announcementTypeXXXXXXXXXXXXXXXXXXX ... XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX Type, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/test/cmdlineTests/too_long_line_edge_in/err b/test/cmdlineTests/too_long_line_edge_in/err index 1d96ea4cdc03..161e3a20bc93 100644 --- a/test/cmdlineTests/too_long_line_edge_in/err +++ b/test/cmdlineTests/too_long_line_edge_in/err @@ -1,5 +1,5 @@ Error: Identifier not found or not unique. - --> too_long_line_edge_in/input.sol:5:36: + --> input.sol:5:36: | 5 | function ffffffffffffffffffffff(announcementTypeTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT Ty, string A) onlyOwner external { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/test/cmdlineTests/too_long_line_edge_out/err b/test/cmdlineTests/too_long_line_edge_out/err index 3b3b4ee490b9..6aa17fc0335f 100644 --- a/test/cmdlineTests/too_long_line_edge_out/err +++ b/test/cmdlineTests/too_long_line_edge_out/err @@ -1,5 +1,5 @@ Error: Identifier not found or not unique. - --> too_long_line_edge_out/input.sol:5:37: + --> input.sol:5:37: | 5 | ... function fffffffffffffffffffffff(announcementTypeTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT Typ, string A) onlyOwner external ... | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/test/cmdlineTests/too_long_line_left_short/err b/test/cmdlineTests/too_long_line_left_short/err index 4f2359739076..25c35177d344 100644 --- a/test/cmdlineTests/too_long_line_left_short/err +++ b/test/cmdlineTests/too_long_line_left_short/err @@ -1,5 +1,5 @@ Error: Identifier not found or not unique. - --> too_long_line_left_short/input.sol:5:15: + --> input.sol:5:15: | 5 | function f(announcementType Type, string Announcement, string ... | ^^^^^^^^^^^^^^^^ diff --git a/test/cmdlineTests/too_long_line_multiline/err b/test/cmdlineTests/too_long_line_multiline/err index 4523938c6ee7..bfa99eed3c8b 100644 --- a/test/cmdlineTests/too_long_line_multiline/err +++ b/test/cmdlineTests/too_long_line_multiline/err @@ -1,5 +1,5 @@ Error: No visibility specified. Did you intend to add "public"? - --> too_long_line_multiline/input.sol:5:5: + --> input.sol:5:5: | 5 | function f() returns (bytes1 _b, by ... _b7, bytes22 _b22, bytes32 _b32) { | ^ (Relevant source part starts here and spans across multiple lines). diff --git a/test/cmdlineTests/too_long_line_right_short/err b/test/cmdlineTests/too_long_line_right_short/err index 7aa26ff074c5..f17f273b1c4e 100644 --- a/test/cmdlineTests/too_long_line_right_short/err +++ b/test/cmdlineTests/too_long_line_right_short/err @@ -1,5 +1,5 @@ Error: Identifier not found or not unique. - --> too_long_line_right_short/input.sol:5:164: + --> input.sol:5:164: | 5 | ... ffffffffffffffffffffffffffffffffff(announcementType Type, | ^^^^^^^^^^^^^^^^ diff --git a/test/cmdlineTests/transient_storage_layout/output b/test/cmdlineTests/transient_storage_layout/output index 0736271b44ad..846cb947d885 100644 --- a/test/cmdlineTests/transient_storage_layout/output +++ b/test/cmdlineTests/transient_storage_layout/output @@ -1,11 +1,11 @@ -======= transient_storage_layout/input.sol:C ======= +======= input.sol:C ======= Contract Transient Storage Layout: { "storage": [ { "astId": 4, - "contract": "transient_storage_layout/input.sol:C", + "contract": "input.sol:C", "label": "x", "offset": 0, "slot": "0", @@ -13,7 +13,7 @@ Contract Transient Storage Layout: }, { "astId": 8, - "contract": "transient_storage_layout/input.sol:C", + "contract": "input.sol:C", "label": "w", "offset": 0, "slot": "1", @@ -21,7 +21,7 @@ Contract Transient Storage Layout: }, { "astId": 12, - "contract": "transient_storage_layout/input.sol:C", + "contract": "input.sol:C", "label": "b", "offset": 20, "slot": "1", @@ -29,7 +29,7 @@ Contract Transient Storage Layout: }, { "astId": 15, - "contract": "transient_storage_layout/input.sol:C", + "contract": "input.sol:C", "label": "d", "offset": 0, "slot": "2", @@ -60,7 +60,7 @@ Contract Transient Storage Layout: } } -======= transient_storage_layout/input.sol:D ======= +======= input.sol:D ======= Contract Transient Storage Layout: { "storage": [] diff --git a/test/cmdlineTests/transient_storage_layout_value_types/input.json b/test/cmdlineTests/transient_storage_layout_value_types/input.json index 65d9a2231b90..2b903a2aea0d 100644 --- a/test/cmdlineTests/transient_storage_layout_value_types/input.json +++ b/test/cmdlineTests/transient_storage_layout_value_types/input.json @@ -1,7 +1,7 @@ { "language": "Solidity", "sources": { - "fileA": {"urls": ["transient_storage_layout_value_types/in.sol"]} + "fileA": {"urls": ["in.sol"]} }, "settings": { "outputSelection": { diff --git a/test/cmdlineTests/transient_storage_layout_value_types_interleaved_with_storage/input.json b/test/cmdlineTests/transient_storage_layout_value_types_interleaved_with_storage/input.json index e649fc838b82..7a12ca85c985 100644 --- a/test/cmdlineTests/transient_storage_layout_value_types_interleaved_with_storage/input.json +++ b/test/cmdlineTests/transient_storage_layout_value_types_interleaved_with_storage/input.json @@ -1,7 +1,7 @@ { "language": "Solidity", "sources": { - "fileA": {"urls": ["transient_storage_layout_value_types_interleaved_with_storage/in.sol"]} + "fileA": {"urls": ["in.sol"]} }, "settings": { "outputSelection": { diff --git a/test/cmdlineTests/transient_storage_layout_value_types_packed/input.json b/test/cmdlineTests/transient_storage_layout_value_types_packed/input.json index ee7fb0dec3b7..2b903a2aea0d 100644 --- a/test/cmdlineTests/transient_storage_layout_value_types_packed/input.json +++ b/test/cmdlineTests/transient_storage_layout_value_types_packed/input.json @@ -1,7 +1,7 @@ { "language": "Solidity", "sources": { - "fileA": {"urls": ["transient_storage_layout_value_types_packed/in.sol"]} + "fileA": {"urls": ["in.sol"]} }, "settings": { "outputSelection": { diff --git a/test/cmdlineTests/undeployable_contract_empty_outputs/output b/test/cmdlineTests/undeployable_contract_empty_outputs/output index 123edc75ddd6..71059f17f1d5 100644 --- a/test/cmdlineTests/undeployable_contract_empty_outputs/output +++ b/test/cmdlineTests/undeployable_contract_empty_outputs/output @@ -1,5 +1,5 @@ -======= undeployable_contract_empty_outputs/input.sol:C ======= +======= input.sol:C ======= EVM assembly: null Gas estimation: @@ -21,7 +21,7 @@ Function signatures: Contract JSON ABI [] -======= undeployable_contract_empty_outputs/input.sol:I ======= +======= input.sol:I ======= EVM assembly: null Gas estimation: diff --git a/test/cmdlineTests/viair_abicoder_v1/err b/test/cmdlineTests/viair_abicoder_v1/err index 55f8ba4b91b3..29fa2acd04a0 100644 --- a/test/cmdlineTests/viair_abicoder_v1/err +++ b/test/cmdlineTests/viair_abicoder_v1/err @@ -1,5 +1,5 @@ Warning (2066): Contract requests the ABI coder v1, which is incompatible with the IR. Using ABI coder v2 instead. - --> viair_abicoder_v1/input.sol:4:1: + --> input.sol:4:1: | 4 | contract test { | ^ (Relevant source part starts here and spans across multiple lines). diff --git a/test/cmdlineTests/viair_abicoder_v1/output b/test/cmdlineTests/viair_abicoder_v1/output index 1c4d6c90e260..3d6a582889df 100644 --- a/test/cmdlineTests/viair_abicoder_v1/output +++ b/test/cmdlineTests/viair_abicoder_v1/output @@ -1,6 +1,6 @@ IR: -/// @use-src 0:"viair_abicoder_v1/input.sol" +/// @use-src 0:"input.sol" object "test_11" { code { /// @src 0:79:169 "contract test {..." @@ -31,7 +31,7 @@ object "test_11" { /// @src 0:79:169 "contract test {..." } - /// @use-src 0:"viair_abicoder_v1/input.sol" + /// @use-src 0:"input.sol" object "test_11_deployed" { code { /// @src 0:79:169 "contract test {..." diff --git a/test/cmdlineTests/viair_msize_without_optimizer/output b/test/cmdlineTests/viair_msize_without_optimizer/output index f94c973bff3a..90c18ef947a1 100644 --- a/test/cmdlineTests/viair_msize_without_optimizer/output +++ b/test/cmdlineTests/viair_msize_without_optimizer/output @@ -1,5 +1,5 @@ -======= viair_msize_without_optimizer/input.sol:C ======= +======= input.sol:C ======= EVM assembly: mstore(0x40, 0x80) jumpi(tag_4, iszero(callvalue)) @@ -173,7 +173,7 @@ sub_0: assembly { } Optimized IR: -/// @use-src 0:"viair_msize_without_optimizer/input.sol" +/// @use-src 0:"input.sol" object "C_7" { code { mstore(64, memoryguard(128)) @@ -192,7 +192,7 @@ object "C_7" { function constructor_C_7() { } } - /// @use-src 0:"viair_msize_without_optimizer/input.sol" + /// @use-src 0:"input.sol" object "C_7_deployed" { code { mstore(64, memoryguard(128)) diff --git a/test/cmdlineTests/viair_subobject_optimization/output b/test/cmdlineTests/viair_subobject_optimization/output index dafba2771c5d..523cff79e0fa 100644 --- a/test/cmdlineTests/viair_subobject_optimization/output +++ b/test/cmdlineTests/viair_subobject_optimization/output @@ -1,7 +1,7 @@ -======= viair_subobject_optimization/input.sol:C ======= +======= input.sol:C ======= EVM assembly: - /* "viair_subobject_optimization/input.sol":61:668 contract C {... */ + /* "input.sol":61:668 contract C {... */ 0x80 jumpi(tag_7, callvalue) 0x1f @@ -44,12 +44,12 @@ EVM assembly: jumpi mload sub(shl(0x48, 0x01), 0xbe) - /* "viair_subobject_optimization/input.sol":620:645 x == 0xFFFFFFFFFFFFFFFF42 */ + /* "input.sol":620:645 x == 0xFFFFFFFFFFFFFFFF42 */ eq - /* "viair_subobject_optimization/input.sol":616:661 if (x == 0xFFFFFFFFFFFFFFFF42)... */ + /* "input.sol":616:661 if (x == 0xFFFFFFFFFFFFFFFF42)... */ tag_7 jumpi - /* "viair_subobject_optimization/input.sol":61:668 contract C {... */ + /* "input.sol":61:668 contract C {... */ mload(0x40) dataSize(sub_0) swap1 @@ -58,13 +58,13 @@ EVM assembly: dup3 codecopy return - /* "viair_subobject_optimization/input.sol":616:661 if (x == 0xFFFFFFFFFFFFFFFF42)... */ + /* "input.sol":616:661 if (x == 0xFFFFFFFFFFFFFFFF42)... */ tag_7: 0x00 - /* "viair_subobject_optimization/input.sol":653:661 revert() */ + /* "input.sol":653:661 revert() */ dup1 revert - /* "viair_subobject_optimization/input.sol":61:668 contract C {... */ + /* "input.sol":61:668 contract C {... */ tag_3: mstore(0x00, shl(0xe0, 0x4e487b71)) mstore(0x04, 0x41) @@ -72,7 +72,7 @@ tag_3: stop sub_0: assembly { - /* "viair_subobject_optimization/input.sol":61:668 contract C {... */ + /* "input.sol":61:668 contract C {... */ 0x00 dup1 revert @@ -81,9 +81,9 @@ sub_0: assembly { } -======= viair_subobject_optimization/input.sol:D ======= +======= input.sol:D ======= EVM assembly: - /* "viair_subobject_optimization/input.sol":669:772 contract D {... */ + /* "input.sol":669:772 contract D {... */ 0x80 dup1 0x40 @@ -103,7 +103,7 @@ tag_1: stop sub_0: assembly { - /* "viair_subobject_optimization/input.sol":669:772 contract D {... */ + /* "input.sol":669:772 contract D {... */ 0x80 jumpi(tag_1, iszero(lt(calldatasize, 0x04))) 0x00 @@ -117,10 +117,10 @@ sub_0: assembly { tag_3: jumpi(tag_7, callvalue) jumpi(tag_7, slt(add(not(0x03), calldatasize), 0x00)) - /* "viair_subobject_optimization/input.sol":745:765 type(C).creationCode */ + /* "input.sol":745:765 type(C).creationCode */ dataSize(sub_0) swap1 - /* "viair_subobject_optimization/input.sol":669:772 contract D {... */ + /* "input.sol":669:772 contract D {... */ 0x3f dup3 add @@ -142,7 +142,7 @@ sub_0: assembly { swap2 dup3 mstore - /* "viair_subobject_optimization/input.sol":745:765 type(C).creationCode */ + /* "input.sol":745:765 type(C).creationCode */ dup3 dup2 mstore @@ -153,24 +153,24 @@ sub_0: assembly { dataOffset(sub_0) dup5 codecopy - /* "viair_subobject_optimization/input.sol":669:772 contract D {... */ + /* "input.sol":669:772 contract D {... */ dup2 mload swap3 dup4 swap2 - /* "viair_subobject_optimization/input.sol":745:765 type(C).creationCode */ + /* "input.sol":745:765 type(C).creationCode */ 0x20 - /* "viair_subobject_optimization/input.sol":669:772 contract D {... */ + /* "input.sol":669:772 contract D {... */ dup4 mstore mload dup1 swap2 dup2 - /* "viair_subobject_optimization/input.sol":745:765 type(C).creationCode */ + /* "input.sol":745:765 type(C).creationCode */ 0x20 - /* "viair_subobject_optimization/input.sol":669:772 contract D {... */ + /* "input.sol":669:772 contract D {... */ dup6 add mstore @@ -206,7 +206,7 @@ sub_0: assembly { stop sub_0: assembly { - /* "viair_subobject_optimization/input.sol":61:668 contract C {... */ + /* "input.sol":61:668 contract C {... */ 0x80 jumpi(tag_7, callvalue) 0x1f @@ -249,12 +249,12 @@ sub_0: assembly { jumpi mload sub(shl(0x48, 0x01), 0xbe) - /* "viair_subobject_optimization/input.sol":620:645 x == 0xFFFFFFFFFFFFFFFF42 */ + /* "input.sol":620:645 x == 0xFFFFFFFFFFFFFFFF42 */ eq - /* "viair_subobject_optimization/input.sol":616:661 if (x == 0xFFFFFFFFFFFFFFFF42)... */ + /* "input.sol":616:661 if (x == 0xFFFFFFFFFFFFFFFF42)... */ tag_7 jumpi - /* "viair_subobject_optimization/input.sol":61:668 contract C {... */ + /* "input.sol":61:668 contract C {... */ mload(0x40) dataSize(sub_0) swap1 @@ -263,13 +263,13 @@ sub_0: assembly { dup3 codecopy return - /* "viair_subobject_optimization/input.sol":616:661 if (x == 0xFFFFFFFFFFFFFFFF42)... */ + /* "input.sol":616:661 if (x == 0xFFFFFFFFFFFFFFFF42)... */ tag_7: 0x00 - /* "viair_subobject_optimization/input.sol":653:661 revert() */ + /* "input.sol":653:661 revert() */ dup1 revert - /* "viair_subobject_optimization/input.sol":61:668 contract C {... */ + /* "input.sol":61:668 contract C {... */ tag_3: mstore(0x00, shl(0xe0, 0x4e487b71)) mstore(0x04, 0x41) @@ -277,7 +277,7 @@ sub_0: assembly { stop sub_0: assembly { - /* "viair_subobject_optimization/input.sol":61:668 contract C {... */ + /* "input.sol":61:668 contract C {... */ 0x00 dup1 revert diff --git a/test/cmdlineTests/viair_subobjects/err b/test/cmdlineTests/viair_subobjects/err index 5046525bef7a..66ebf4229caf 100644 --- a/test/cmdlineTests/viair_subobjects/err +++ b/test/cmdlineTests/viair_subobjects/err @@ -1,5 +1,5 @@ Warning: Unused local variable. - --> viair_subobjects/input.sol:8:9: + --> input.sol:8:9: | 8 | C c = new C(); | ^^^ diff --git a/test/cmdlineTests/viair_subobjects/output b/test/cmdlineTests/viair_subobjects/output index 7a6bc8e6570b..783756e67681 100644 --- a/test/cmdlineTests/viair_subobjects/output +++ b/test/cmdlineTests/viair_subobjects/output @@ -1,11 +1,11 @@ -======= viair_subobjects/input.sol:C ======= +======= input.sol:C ======= Binary: Binary of the runtime part: Optimized IR: -/// @use-src 0:"viair_subobjects/input.sol" +/// @use-src 0:"input.sol" object "C_3" { code { { @@ -18,7 +18,7 @@ object "C_3" { return(_1, _2) } } - /// @use-src 0:"viair_subobjects/input.sol" + /// @use-src 0:"input.sol" object "C_3_deployed" { code { { @@ -31,13 +31,13 @@ object "C_3" { } -======= viair_subobjects/input.sol:D ======= +======= input.sol:D ======= Binary: Binary of the runtime part: Optimized IR: -/// @use-src 0:"viair_subobjects/input.sol" +/// @use-src 0:"input.sol" object "D_16" { code { { @@ -50,7 +50,7 @@ object "D_16" { return(_1, _2) } } - /// @use-src 0:"viair_subobjects/input.sol" + /// @use-src 0:"input.sol" object "D_16_deployed" { code { { @@ -88,7 +88,7 @@ object "D_16" { revert(0, 0) } } - /// @use-src 0:"viair_subobjects/input.sol" + /// @use-src 0:"input.sol" object "C_3" { code { { @@ -101,7 +101,7 @@ object "D_16" { return(_1, _2) } } - /// @use-src 0:"viair_subobjects/input.sol" + /// @use-src 0:"input.sol" object "C_3_deployed" { code { { diff --git a/test/cmdlineTests/yul_cfg_json_export/output b/test/cmdlineTests/yul_cfg_json_export/output index 0508769d7cb0..9affc4206939 100644 --- a/test/cmdlineTests/yul_cfg_json_export/output +++ b/test/cmdlineTests/yul_cfg_json_export/output @@ -1,5 +1,5 @@ -======= yul_cfg_json_export/input.sol:C ======= +======= input.sol:C ======= Yul Control Flow Graph: { "C_19": { @@ -447,7 +447,7 @@ Yul Control Flow Graph: "type": "Object" } -======= yul_cfg_json_export/input.sol:D ======= +======= input.sol:D ======= Yul Control Flow Graph: { "D_38": { @@ -2127,6 +2127,6 @@ Yul Control Flow Graph: "type": "Object" } -======= yul_cfg_json_export/input.sol:I ======= +======= input.sol:I ======= Yul Control Flow Graph: null diff --git a/test/cmdlineTests/yul_function_name_clashes/output b/test/cmdlineTests/yul_function_name_clashes/output index 2c54b6f50893..1d319d284e5b 100644 --- a/test/cmdlineTests/yul_function_name_clashes/output +++ b/test/cmdlineTests/yul_function_name_clashes/output @@ -1,5 +1,5 @@ -======= yul_function_name_clashes/input.yul (EVM) ======= +======= input.yul (EVM) ======= Pretty printed source: object "object" { diff --git a/test/cmdlineTests/yul_function_name_clashes_different_params/output b/test/cmdlineTests/yul_function_name_clashes_different_params/output index 85884a6a0ede..fdffb0c31270 100644 --- a/test/cmdlineTests/yul_function_name_clashes_different_params/output +++ b/test/cmdlineTests/yul_function_name_clashes_different_params/output @@ -1,5 +1,5 @@ -======= yul_function_name_clashes_different_params/input.yul (EVM) ======= +======= input.yul (EVM) ======= Pretty printed source: object "object" { @@ -23,37 +23,37 @@ Binary representation: 60056011565b600d60706016565b9055005b5f3590565b359056 Text representation: - /* "yul_function_name_clashes_different_params/input.yul":92:95 */ + /* "input.yul":92:95 */ tag_3 tag_1 jump // in tag_3: - /* "yul_function_name_clashes_different_params/input.yul":113:122 */ + /* "input.yul":113:122 */ tag_4 - /* "yul_function_name_clashes_different_params/input.yul":117:121 */ + /* "input.yul":117:121 */ 0x70 - /* "yul_function_name_clashes_different_params/input.yul":113:122 */ + /* "input.yul":113:122 */ tag_2 jump // in tag_4: - /* "yul_function_name_clashes_different_params/input.yul":135:147 */ + /* "input.yul":135:147 */ swap1 sstore - /* "yul_function_name_clashes_different_params/input.yul":27:284 */ + /* "input.yul":27:284 */ stop - /* "yul_function_name_clashes_different_params/input.yul":166:216 */ + /* "input.yul":166:216 */ tag_1: - /* "yul_function_name_clashes_different_params/input.yul":212:213 */ + /* "input.yul":212:213 */ 0x00 - /* "yul_function_name_clashes_different_params/input.yul":199:214 */ + /* "input.yul":199:214 */ calldataload - /* "yul_function_name_clashes_different_params/input.yul":166:216 */ + /* "input.yul":166:216 */ swap1 jump // out - /* "yul_function_name_clashes_different_params/input.yul":225:278 */ + /* "input.yul":225:278 */ tag_2: - /* "yul_function_name_clashes_different_params/input.yul":261:276 */ + /* "input.yul":261:276 */ calldataload - /* "yul_function_name_clashes_different_params/input.yul":225:278 */ + /* "input.yul":225:278 */ swap1 jump // out diff --git a/test/cmdlineTests/yul_optimize_runs/output b/test/cmdlineTests/yul_optimize_runs/output index 589f8ce1a12c..ec3dab457213 100644 --- a/test/cmdlineTests/yul_optimize_runs/output +++ b/test/cmdlineTests/yul_optimize_runs/output @@ -1,5 +1,5 @@ -======= yul_optimize_runs/input.yul (EVM) ======= +======= input.yul (EVM) ======= Pretty printed source: object "RunsTest1" { @@ -24,28 +24,28 @@ Binary representation: 602480600a5f395ff3fe7fabc12345000000000000000000000000000000000000000000000000000000005f5500 Text representation: - /* "yul_optimize_runs/input.yul":64:92 */ + /* "input.yul":64:92 */ dataSize(sub_0) - /* "yul_optimize_runs/input.yul":117:147 */ + /* "input.yul":117:147 */ dup1 dataOffset(sub_0) - /* "yul_optimize_runs/input.yul":114:115 */ + /* "input.yul":114:115 */ 0x00 - /* "yul_optimize_runs/input.yul":105:152 */ + /* "input.yul":105:152 */ codecopy - /* "yul_optimize_runs/input.yul":172:173 */ + /* "input.yul":172:173 */ 0x00 - /* "yul_optimize_runs/input.yul":165:178 */ + /* "input.yul":165:178 */ return stop sub_0: assembly { - /* "yul_optimize_runs/input.yul":282:348 */ + /* "input.yul":282:348 */ 0xabc1234500000000000000000000000000000000000000000000000000000000 - /* "yul_optimize_runs/input.yul":279:280 */ + /* "input.yul":279:280 */ 0x00 - /* "yul_optimize_runs/input.yul":272:349 */ + /* "input.yul":272:349 */ sstore - /* "yul_optimize_runs/input.yul":240:373 */ + /* "input.yul":240:373 */ stop } diff --git a/test/cmdlineTests/yul_optimizer_disabled_sequence_empty/output b/test/cmdlineTests/yul_optimizer_disabled_sequence_empty/output index 7b948303ee43..744bc03a8c6e 100644 --- a/test/cmdlineTests/yul_optimizer_disabled_sequence_empty/output +++ b/test/cmdlineTests/yul_optimizer_disabled_sequence_empty/output @@ -1,4 +1,4 @@ -======= yul_optimizer_disabled_sequence_empty/input.sol:C ======= +======= input.sol:C ======= Metadata: -{"compiler":{"version": ""},"language":"Solidity","output":{"abi":[],"devdoc":{"kind":"dev","methods":{},"version":1},"userdoc":{"kind":"user","methods":{},"version":1}},"settings":{"compilationTarget":{"yul_optimizer_disabled_sequence_empty/input.sol":"C"},"evmVersion":"cancun","libraries":{},"metadata":{"bytecodeHash":"ipfs"},"optimizer":{"details":{"constantOptimizer":false,"cse":false,"deduplicate":false,"inliner":false,"jumpdestRemover":true,"orderLiterals":false,"peephole":true,"simpleCounterForLoopUncheckedIncrement":true,"yul":false,"yulDetails":{"optimizerSteps":":"}},"runs":200},"remappings":[]},"sources":{"yul_optimizer_disabled_sequence_empty/input.sol":{"keccak256":"0xc2db3500808896ce1e69de2fe20cecab7ae2ffbb47cdf6ba8321296d95f49fc5","license":"GPL-3.0","urls":["bzz-raw://fde21393c068cd9f2d2b10ba4782db54f6f1c9a725074b17fa742531076be8a4","dweb:/ipfs/QmeTD6mR7YrWNyRowKRS7xs6cJNeMF3T49GAHzGM1bquyM"]}},"version":1} +{"compiler":{"version": ""},"language":"Solidity","output":{"abi":[],"devdoc":{"kind":"dev","methods":{},"version":1},"userdoc":{"kind":"user","methods":{},"version":1}},"settings":{"compilationTarget":{"input.sol":"C"},"evmVersion":"cancun","libraries":{},"metadata":{"bytecodeHash":"ipfs"},"optimizer":{"details":{"constantOptimizer":false,"cse":false,"deduplicate":false,"inliner":false,"jumpdestRemover":true,"orderLiterals":false,"peephole":true,"simpleCounterForLoopUncheckedIncrement":true,"yul":false,"yulDetails":{"optimizerSteps":":"}},"runs":200},"remappings":[]},"sources":{"input.sol":{"keccak256":"0xc2db3500808896ce1e69de2fe20cecab7ae2ffbb47cdf6ba8321296d95f49fc5","license":"GPL-3.0","urls":["bzz-raw://fde21393c068cd9f2d2b10ba4782db54f6f1c9a725074b17fa742531076be8a4","dweb:/ipfs/QmeTD6mR7YrWNyRowKRS7xs6cJNeMF3T49GAHzGM1bquyM"]}},"version":1} diff --git a/test/cmdlineTests/yul_optimizer_steps/output b/test/cmdlineTests/yul_optimizer_steps/output index bb68a48fa809..f9484d2b4491 100644 --- a/test/cmdlineTests/yul_optimizer_steps/output +++ b/test/cmdlineTests/yul_optimizer_steps/output @@ -1,5 +1,5 @@ Optimized IR: -/// @use-src 0:"yul_optimizer_steps/input.sol" +/// @use-src 0:"input.sol" object "C_7" { code { { @@ -18,7 +18,7 @@ object "C_7" { function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() { revert(0, 0) } } - /// @use-src 0:"yul_optimizer_steps/input.sol" + /// @use-src 0:"input.sol" object "C_7_deployed" { code { { diff --git a/test/cmdlineTests/yul_optimizer_steps_nested_brackets/output b/test/cmdlineTests/yul_optimizer_steps_nested_brackets/output index 9687abf643b3..26be9469862a 100644 --- a/test/cmdlineTests/yul_optimizer_steps_nested_brackets/output +++ b/test/cmdlineTests/yul_optimizer_steps_nested_brackets/output @@ -1,5 +1,5 @@ Optimized IR: -/// @use-src 0:"yul_optimizer_steps_nested_brackets/input.sol" +/// @use-src 0:"input.sol" object "C_6" { code { { @@ -21,7 +21,7 @@ object "C_6" { function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() { revert(0, 0) } } - /// @use-src 0:"yul_optimizer_steps_nested_brackets/input.sol" + /// @use-src 0:"input.sol" object "C_6_deployed" { code { { diff --git a/test/cmdlineTests/yul_optimizer_steps_short_sequence/output b/test/cmdlineTests/yul_optimizer_steps_short_sequence/output index dc77ce3c53e7..e93958a5d619 100644 --- a/test/cmdlineTests/yul_optimizer_steps_short_sequence/output +++ b/test/cmdlineTests/yul_optimizer_steps_short_sequence/output @@ -1,5 +1,5 @@ Optimized IR: -/// @use-src 0:"yul_optimizer_steps_short_sequence/input.sol" +/// @use-src 0:"input.sol" object "C_8" { code { { @@ -9,7 +9,7 @@ object "C_8" { revert(0, 0) } } - /// @use-src 0:"yul_optimizer_steps_short_sequence/input.sol" + /// @use-src 0:"input.sol" object "C_8_deployed" { code { { diff --git a/test/cmdlineTests/yul_optimizer_steps_with_empty_cleanup_sequence/output b/test/cmdlineTests/yul_optimizer_steps_with_empty_cleanup_sequence/output index 01641c53bc30..bbfd22e9bdfe 100644 --- a/test/cmdlineTests/yul_optimizer_steps_with_empty_cleanup_sequence/output +++ b/test/cmdlineTests/yul_optimizer_steps_with_empty_cleanup_sequence/output @@ -1,5 +1,5 @@ Optimized IR: -/// @use-src 0:"yul_optimizer_steps_with_empty_cleanup_sequence/input.sol" +/// @use-src 0:"input.sol" object "C_8" { code { { @@ -10,7 +10,7 @@ object "C_8" { revert(0, usr$a) } } - /// @use-src 0:"yul_optimizer_steps_with_empty_cleanup_sequence/input.sol" + /// @use-src 0:"input.sol" object "C_8_deployed" { code { { diff --git a/test/cmdlineTests/yul_optimizer_steps_with_empty_optimization_sequence/output b/test/cmdlineTests/yul_optimizer_steps_with_empty_optimization_sequence/output index b13e6e2823ff..bbfd22e9bdfe 100644 --- a/test/cmdlineTests/yul_optimizer_steps_with_empty_optimization_sequence/output +++ b/test/cmdlineTests/yul_optimizer_steps_with_empty_optimization_sequence/output @@ -1,5 +1,5 @@ Optimized IR: -/// @use-src 0:"yul_optimizer_steps_with_empty_optimization_sequence/input.sol" +/// @use-src 0:"input.sol" object "C_8" { code { { @@ -10,7 +10,7 @@ object "C_8" { revert(0, usr$a) } } - /// @use-src 0:"yul_optimizer_steps_with_empty_optimization_sequence/input.sol" + /// @use-src 0:"input.sol" object "C_8_deployed" { code { { diff --git a/test/cmdlineTests/yul_optimizer_steps_without_optimize_empty_sequence/err b/test/cmdlineTests/yul_optimizer_steps_without_optimize_empty_sequence/err index 95e30df2e83d..d87be1839ccb 100644 --- a/test/cmdlineTests/yul_optimizer_steps_without_optimize_empty_sequence/err +++ b/test/cmdlineTests/yul_optimizer_steps_without_optimize_empty_sequence/err @@ -1,11 +1,11 @@ Warning: Unused local variable. - --> yul_optimizer_steps_without_optimize_empty_sequence/input.sol:13:9: + --> input.sol:13:9: | 13 | uint b = a; | ^^^^^^ Warning: Unused local variable. - --> yul_optimizer_steps_without_optimize_empty_sequence/input.sol:14:9: + --> input.sol:14:9: | 14 | uint c = a; | ^^^^^^ diff --git a/test/cmdlineTests/yul_optimizer_steps_without_optimize_empty_sequence/output b/test/cmdlineTests/yul_optimizer_steps_without_optimize_empty_sequence/output index 6873abe60e47..a7b037775f2c 100644 --- a/test/cmdlineTests/yul_optimizer_steps_without_optimize_empty_sequence/output +++ b/test/cmdlineTests/yul_optimizer_steps_without_optimize_empty_sequence/output @@ -1,7 +1,7 @@ -======= yul_optimizer_steps_without_optimize_empty_sequence/input.sol:C ======= +======= input.sol:C ======= Optimized IR: -/// @use-src 0:"yul_optimizer_steps_without_optimize_empty_sequence/input.sol" +/// @use-src 0:"input.sol" object "C_28" { code { { @@ -24,7 +24,7 @@ object "C_28" { function constructor_C() { } } - /// @use-src 0:"yul_optimizer_steps_without_optimize_empty_sequence/input.sol" + /// @use-src 0:"input.sol" object "C_28_deployed" { code { { @@ -130,4 +130,4 @@ object "C_28" { } Metadata: -{"compiler":{"version": ""},"language":"Solidity","output":{"abi":[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"foo","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"}],"devdoc":{"kind":"dev","methods":{},"version":1},"userdoc":{"kind":"user","methods":{},"version":1}},"settings":{"compilationTarget":{"yul_optimizer_steps_without_optimize_empty_sequence/input.sol":"C"},"evmVersion":"cancun","libraries":{},"metadata":{"bytecodeHash":"ipfs"},"optimizer":{"details":{"constantOptimizer":false,"cse":false,"deduplicate":false,"inliner":false,"jumpdestRemover":true,"orderLiterals":false,"peephole":true,"simpleCounterForLoopUncheckedIncrement":true,"yul":false,"yulDetails":{"optimizerSteps":":"}},"runs":200},"remappings":[]},"sources":{"yul_optimizer_steps_without_optimize_empty_sequence/input.sol":{"keccak256":"0x3fc910e345ce1ee62bfa6b0f66931ee632c08265b25b6139cfbbfe4d2f8d5dd8","license":"GPL-3.0","urls":["bzz-raw://e557e9ad2c2e420a669c06ae456b0b790d77d2d6d492cd8540e6b244388a5140","dweb:/ipfs/QmaNiZmC2Mo3YxGiehs1n3dVTjZwD7FguX7EUtpeshMVuR"]}},"version":1} +{"compiler":{"version": ""},"language":"Solidity","output":{"abi":[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"foo","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"}],"devdoc":{"kind":"dev","methods":{},"version":1},"userdoc":{"kind":"user","methods":{},"version":1}},"settings":{"compilationTarget":{"input.sol":"C"},"evmVersion":"cancun","libraries":{},"metadata":{"bytecodeHash":"ipfs"},"optimizer":{"details":{"constantOptimizer":false,"cse":false,"deduplicate":false,"inliner":false,"jumpdestRemover":true,"orderLiterals":false,"peephole":true,"simpleCounterForLoopUncheckedIncrement":true,"yul":false,"yulDetails":{"optimizerSteps":":"}},"runs":200},"remappings":[]},"sources":{"input.sol":{"keccak256":"0x3fc910e345ce1ee62bfa6b0f66931ee632c08265b25b6139cfbbfe4d2f8d5dd8","license":"GPL-3.0","urls":["bzz-raw://e557e9ad2c2e420a669c06ae456b0b790d77d2d6d492cd8540e6b244388a5140","dweb:/ipfs/QmaNiZmC2Mo3YxGiehs1n3dVTjZwD7FguX7EUtpeshMVuR"]}},"version":1} diff --git a/test/cmdlineTests/yul_verbatim/output b/test/cmdlineTests/yul_verbatim/output index 60fc7e6d1f46..33f86b2992be 100644 --- a/test/cmdlineTests/yul_verbatim/output +++ b/test/cmdlineTests/yul_verbatim/output @@ -1,5 +1,5 @@ -======= yul_verbatim/input.yul (EVM) ======= +======= input.yul (EVM) ======= Pretty printed source: object "object" { @@ -20,38 +20,38 @@ Binary representation: 6002808103808261626382815564656678797a010203040506070900010203040506070900010203040506070900010201020304050607090001020304050607090001020304050607090001026009905050505050 Text representation: - /* "yul_verbatim/input.yul":15:16 */ + /* "input.yul":15:16 */ 0x02 - /* "yul_verbatim/input.yul":37:38 */ + /* "input.yul":37:38 */ dup1 - /* "yul_verbatim/input.yul":34:35 */ + /* "input.yul":34:35 */ dup2 - /* "yul_verbatim/input.yul":30:39 */ + /* "input.yul":30:39 */ sub - /* "yul_verbatim/input.yul":78:79 */ + /* "input.yul":78:79 */ dup1 - /* "yul_verbatim/input.yul":75:76 */ + /* "input.yul":75:76 */ dup3 - /* "yul_verbatim/input.yul":53:80 */ + /* "input.yul":53:80 */ verbatimbytecode_616263 - /* "yul_verbatim/input.yul":95:96 */ + /* "input.yul":95:96 */ dup3 - /* "yul_verbatim/input.yul":92:93 */ + /* "input.yul":92:93 */ dup2 - /* "yul_verbatim/input.yul":85:97 */ + /* "input.yul":85:97 */ sstore - /* "yul_verbatim/input.yul":111:132 */ + /* "input.yul":111:132 */ verbatimbytecode_646566 - /* "yul_verbatim/input.yul":137:158 */ + /* "input.yul":137:158 */ verbatimbytecode_78797a - /* "yul_verbatim/input.yul":189:326 */ + /* "input.yul":189:326 */ verbatimbytecode_01020304050607090001020304050607090001020304050607090001020102030405060709000102030405060709000102030405060709000102 - /* "yul_verbatim/input.yul":336:337 */ + /* "input.yul":336:337 */ 0x09 - /* "yul_verbatim/input.yul":331:337 */ + /* "input.yul":331:337 */ swap1 pop - /* "yul_verbatim/input.yul":0:339 */ + /* "input.yul":0:339 */ pop pop pop diff --git a/test/cmdlineTests/yul_verbatim_msize/output b/test/cmdlineTests/yul_verbatim_msize/output index f684bac21752..b0acd819d8d1 100644 --- a/test/cmdlineTests/yul_verbatim_msize/output +++ b/test/cmdlineTests/yul_verbatim_msize/output @@ -1,5 +1,5 @@ -======= yul_verbatim_msize/input.yul (EVM) ======= +======= input.yul (EVM) ======= Pretty printed source: object "object" { @@ -17,19 +17,19 @@ Binary representation: 6120005150616160025f5500 Text representation: - /* "yul_verbatim_msize/input.yul":61:67 */ + /* "input.yul":61:67 */ 0x2000 - /* "yul_verbatim_msize/input.yul":55:68 */ + /* "input.yul":55:68 */ mload - /* "yul_verbatim_msize/input.yul":51:69 */ + /* "input.yul":51:69 */ pop - /* "yul_verbatim_msize/input.yul":82:102 */ + /* "input.yul":82:102 */ verbatimbytecode_6161 - /* "yul_verbatim_msize/input.yul":125:126 */ + /* "input.yul":125:126 */ 0x02 - /* "yul_verbatim_msize/input.yul":122:123 */ + /* "input.yul":122:123 */ 0x00 - /* "yul_verbatim_msize/input.yul":115:127 */ + /* "input.yul":115:127 */ sstore - /* "yul_verbatim_msize/input.yul":27:143 */ + /* "input.yul":27:143 */ stop From 880b61bd33f6df5c05d77671f6b534be2957e100 Mon Sep 17 00:00:00 2001 From: Martin Blicha Date: Thu, 13 Feb 2025 15:30:25 +0100 Subject: [PATCH 0935/1022] SMTChecker: Refactor handling of ConstantCondition verification target --- libsolidity/formal/BMC.cpp | 149 +++++++++++++++++-------------------- libsolidity/formal/BMC.h | 30 +++++--- 2 files changed, 90 insertions(+), 89 deletions(-) diff --git a/libsolidity/formal/BMC.cpp b/libsolidity/formal/BMC.cpp index 6dcd856ee2af..4b494d6236ac 100644 --- a/libsolidity/formal/BMC.cpp +++ b/libsolidity/formal/BMC.cpp @@ -247,14 +247,8 @@ bool BMC::visit(IfStatement const& _node) m_context.pushSolver(); _node.condition().accept(*this); - // We ignore called functions here because they have - // specific input values. - if (isRootFunction() && !isInsideLoop()) - addVerificationTarget( - VerificationTargetType::ConstantCondition, - expr(_node.condition()), - &_node.condition() - ); + checkIfConditionIsConstant(_node.condition()); + m_context.popSolver(); resetVariableIndices(std::move(indicesBeforePush)); @@ -283,13 +277,7 @@ bool BMC::visit(Conditional const& _op) auto indicesBeforePush = copyVariableIndices(); m_context.pushSolver(); _op.condition().accept(*this); - - if (isRootFunction() && !isInsideLoop()) - addVerificationTarget( - VerificationTargetType::ConstantCondition, - expr(_op.condition()), - &_op.condition() - ); + checkIfConditionIsConstant(_op.condition()); m_context.popSolver(); resetVariableIndices(std::move(indicesBeforePush)); @@ -690,12 +678,7 @@ void BMC::visitRequire(FunctionCall const& _funCall) auto const& args = _funCall.arguments(); solAssert(args.size() >= 1, ""); solAssert(args.front()->annotation().type->category() == Type::Category::Bool, ""); - if (isRootFunction() && !isInsideLoop()) - addVerificationTarget( - VerificationTargetType::ConstantCondition, - expr(*args.front()), - args.front().get() - ); + checkIfConditionIsConstant(*args.front()); } void BMC::visitAddMulMod(FunctionCall const& _funCall) @@ -933,9 +916,6 @@ void BMC::checkVerificationTarget(BMCVerificationTarget& _target) switch (_target.type) { - case VerificationTargetType::ConstantCondition: - checkConstantCondition(_target); - break; case VerificationTargetType::Underflow: checkUnderflow(_target); break; @@ -951,19 +931,70 @@ void BMC::checkVerificationTarget(BMCVerificationTarget& _target) case VerificationTargetType::Assert: checkAssert(_target); break; + case VerificationTargetType::ConstantCondition: + solAssert(false, "Checks for constant condition are handled separately"); default: solAssert(false, ""); } } -void BMC::checkConstantCondition(BMCVerificationTarget& _target) +void BMC::checkIfConditionIsConstant(Expression const& _condition) { - checkBooleanNotConstant( - *_target.expression, - _target.constraints, - _target.value, - _target.callStack - ); + if ( + !m_settings.targets.has(VerificationTargetType::ConstantCondition) || + (m_currentContract && !shouldEncode(*m_currentContract)) + ) + return; + + // We ignore called functions here because they have specific input values. + // Also, expressions inside loop can have different values in different iterations. + if (!isRootFunction() || isInsideLoop()) + return; + + // Do not check for const-ness if this is a literal. + if (dynamic_cast(&_condition)) + return; + + auto [canBeTrue, canBeFalse] = checkBooleanNotConstant(currentPathConditions() && m_context.assertions(), expr(_condition)); + + // Report based on the result of the checks + if (canBeTrue == CheckResult::ERROR || canBeFalse == CheckResult::ERROR) + m_errorReporter.warning(8592_error, _condition.location(), "BMC: Error trying to invoke SMT solver."); + else if (canBeTrue == CheckResult::CONFLICTING || canBeFalse == CheckResult::CONFLICTING) + m_errorReporter.warning(3356_error, _condition.location(), "BMC: At least two SMT solvers provided conflicting answers. Results might not be sound."); + else if (canBeTrue == CheckResult::UNKNOWN || canBeFalse == CheckResult::UNKNOWN) + { + // Not enough information to make definite claims. + } + else if (canBeTrue == CheckResult::SATISFIABLE && canBeFalse == CheckResult::SATISFIABLE) + { + // Condition can be both true and false for some program runs. + } + + else if (canBeTrue == CheckResult::UNSATISFIABLE && canBeFalse == CheckResult::UNSATISFIABLE) + m_errorReporter.warning(2512_error, _condition.location(), "BMC: Condition unreachable.", SMTEncoder::callStackMessage(m_callStack)); + else + { + std::string description; + if (canBeFalse == smtutil::CheckResult::UNSATISFIABLE) + { + smtAssert(canBeTrue == smtutil::CheckResult::SATISFIABLE); + description = "BMC: Condition is always true."; + } + else + { + smtAssert(canBeTrue == smtutil::CheckResult::UNSATISFIABLE); + smtAssert(canBeFalse == smtutil::CheckResult::SATISFIABLE); + description = "BMC: Condition is always false."; + } + m_errorReporter.warning( + 6838_error, + _condition.location(), + description, + SMTEncoder::callStackMessage(m_callStack) + ); + } + } void BMC::checkUnderflow(BMCVerificationTarget& _target) @@ -1068,6 +1099,7 @@ void BMC::addVerificationTarget( Expression const* _expression ) { + smtAssert(_type != VerificationTargetType::ConstantCondition, "Checks for constant condition are handled separately"); if (!m_settings.targets.has(_type) || (m_currentContract && !shouldAnalyzeVerificationTargetsFor(*m_currentContract))) return; @@ -1081,10 +1113,7 @@ void BMC::addVerificationTarget( m_callStack, modelExpressions() }; - if (_type == VerificationTargetType::ConstantCondition) - checkVerificationTarget(target); - else - m_verificationTargets.emplace_back(std::move(target)); + m_verificationTargets.emplace_back(std::move(target)); } /// Solving. @@ -1188,62 +1217,22 @@ void BMC::checkCondition( m_interface->pop(); } -void BMC::checkBooleanNotConstant( - Expression const& _condition, +BMC::ConstantExpressionCheckResult BMC::checkBooleanNotConstant( smtutil::Expression const& _constraints, - smtutil::Expression const& _value, - std::vector const& _callStack + smtutil::Expression const& _condition ) { - // Do not check for const-ness if this is a constant. - if (dynamic_cast(&_condition)) - return; - m_interface->push(); - m_interface->addAssertion(_constraints && _value); + m_interface->addAssertion(_constraints && _condition); auto positiveResult = checkSatisfiable(); m_interface->pop(); m_interface->push(); - m_interface->addAssertion(_constraints && !_value); + m_interface->addAssertion(_constraints && !_condition); auto negatedResult = checkSatisfiable(); m_interface->pop(); - if (positiveResult == smtutil::CheckResult::ERROR || negatedResult == smtutil::CheckResult::ERROR) - m_errorReporter.warning(8592_error, _condition.location(), "BMC: Error trying to invoke SMT solver."); - else if (positiveResult == smtutil::CheckResult::CONFLICTING || negatedResult == smtutil::CheckResult::CONFLICTING) - m_errorReporter.warning(3356_error, _condition.location(), "BMC: At least two SMT solvers provided conflicting answers. Results might not be sound."); - else if (positiveResult == smtutil::CheckResult::SATISFIABLE && negatedResult == smtutil::CheckResult::SATISFIABLE) - { - // everything fine. - } - else if (positiveResult == smtutil::CheckResult::UNKNOWN || negatedResult == smtutil::CheckResult::UNKNOWN) - { - // can't do anything. - } - else if (positiveResult == smtutil::CheckResult::UNSATISFIABLE && negatedResult == smtutil::CheckResult::UNSATISFIABLE) - m_errorReporter.warning(2512_error, _condition.location(), "BMC: Condition unreachable.", SMTEncoder::callStackMessage(_callStack)); - else - { - std::string description; - if (positiveResult == smtutil::CheckResult::SATISFIABLE) - { - solAssert(negatedResult == smtutil::CheckResult::UNSATISFIABLE, ""); - description = "BMC: Condition is always true."; - } - else - { - solAssert(positiveResult == smtutil::CheckResult::UNSATISFIABLE, ""); - solAssert(negatedResult == smtutil::CheckResult::SATISFIABLE, ""); - description = "BMC: Condition is always false."; - } - m_errorReporter.warning( - 6838_error, - _condition.location(), - description, - SMTEncoder::callStackMessage(_callStack) - ); - } + return {.canBeTrue = positiveResult, .canBeFalse = negatedResult}; } std::pair> diff --git a/libsolidity/formal/BMC.h b/libsolidity/formal/BMC.h index a0ee9a3749c2..67d930c79194 100644 --- a/libsolidity/formal/BMC.h +++ b/libsolidity/formal/BMC.h @@ -161,7 +161,6 @@ class BMC: public SMTEncoder void checkVerificationTargets(); void checkVerificationTarget(BMCVerificationTarget& _target); - void checkConstantCondition(BMCVerificationTarget& _target); void checkUnderflow(BMCVerificationTarget& _target); void checkOverflow(BMCVerificationTarget& _target); void checkDivByZero(BMCVerificationTarget& _target); @@ -172,8 +171,13 @@ class BMC: public SMTEncoder smtutil::Expression const& _value, Expression const* _expression ); + /// Special handling of ConstantCondition verification target. + /// The target is checked immediately, unlike the other targets that are queued for checking at the end of analysis. + void checkIfConditionIsConstant(Expression const& _condition); //@} + + /// Solver related. //@{ /// Check that a condition can be satisfied. @@ -188,13 +192,18 @@ class BMC: public SMTEncoder std::string const& _additionalValueName = "", smtutil::Expression const* _additionalValue = nullptr ); - /// Checks that a boolean condition is not constant. Do not warn if the expression - /// is a literal constant. - void checkBooleanNotConstant( - Expression const& _condition, + + struct ConstantExpressionCheckResult + { + smtutil::CheckResult canBeTrue; + smtutil::CheckResult canBeFalse; + }; + + /// Checks whether the given boolean condition is either true or always false under given constraints. + /// Returns the results from the solver for these two checks. + ConstantExpressionCheckResult checkBooleanNotConstant( smtutil::Expression const& _constraints, - smtutil::Expression const& _value, - std::vector const& _callStack + smtutil::Expression const& _condition ); std::pair> checkSatisfiableAndGenerateModel(std::vector const& _expressionsToEvaluate); @@ -222,20 +231,23 @@ class BMC: public SMTEncoder /// Number of verification conditions that could not be proved. size_t m_unprovedAmt = 0; + /// Loop analysis + //@{ enum class LoopControlKind { Continue, Break }; - // Current path conditions and SSA indices for break or continue statement + /// Current path conditions and SSA indices for break or continue statement struct LoopControl { LoopControlKind kind; smtutil::Expression pathConditions; VariableIndices variableIndices; }; - // Loop control statements for every loop + /// Loop control statements for every loop std::stack> m_loopCheckpoints; + //@} }; } From d9083dc11aa70eb3fa6089102c637b31fc9e0a31 Mon Sep 17 00:00:00 2001 From: Martin Blicha Date: Fri, 21 Mar 2025 18:04:51 +0100 Subject: [PATCH 0936/1022] SMTChecker: Loop conditions should be analyzed as in loop context in BMC Value of loop condition can change between iterations of the loop. Therefore, BMC should be in the "inside loop" state when analyzing loop conditions. --- Changelog.md | 1 + libsolidity/formal/BMC.cpp | 10 +++++++--- ..._first_iteration_and_constant_false_in_second.sol | 10 ++++++++++ ..._first_iteration_and_constant_false_in_second.sol | 12 ++++++++++++ 4 files changed, 30 insertions(+), 3 deletions(-) create mode 100644 test/libsolidity/smtCheckerTests/loops/for_loop_condition_constant_true_in_first_iteration_and_constant_false_in_second.sol create mode 100644 test/libsolidity/smtCheckerTests/loops/while_loop_condition_constant_true_in_first_iteration_and_constant_false_in_second.sol diff --git a/Changelog.md b/Changelog.md index 525ed2d9e58b..e8ccbb525302 100644 --- a/Changelog.md +++ b/Changelog.md @@ -8,6 +8,7 @@ Compiler Features: Bugfixes: +* SMTChecker: Do not consider loop conditions as constant-condition verification target as this could cause incorrect reports and internal compiler errors. * SMTChecker: Fix incorrect analysis when only a subset of contracts is selected with `--model-checker-contracts`. * SMTChecker: Fix internal compiler error when string literal is used to initialize user-defined type based on fixed bytes. diff --git a/libsolidity/formal/BMC.cpp b/libsolidity/formal/BMC.cpp index 4b494d6236ac..8401c8dbfc0b 100644 --- a/libsolidity/formal/BMC.cpp +++ b/libsolidity/formal/BMC.cpp @@ -363,7 +363,9 @@ bool BMC::visit(WhileStatement const& _node) { //after loop iterations are done, we check the loop condition last final time auto indices = copyVariableIndices(); + m_loopCheckpoints.emplace(); _node.condition().accept(*this); + m_loopCheckpoints.pop(); loopCondition = expr(_node.condition()); // assert that the loop is complete m_context.addAssertion(!loopCondition || broke || !loopConditionOnPreviousIterations); @@ -391,13 +393,13 @@ bool BMC::visit(ForStatement const& _node) for (unsigned int i = 0; i < bmcLoopIterations; ++i) { auto indicesBefore = copyVariableIndices(); + m_loopCheckpoints.emplace(); if (_node.condition()) { _node.condition()->accept(*this); // values in loop condition might change during loop iteration forCondition = expr(*_node.condition()); } - m_loopCheckpoints.emplace(); auto indicesAfterCondition = copyVariableIndices(); pushPathCondition(forCondition); @@ -443,8 +445,10 @@ bool BMC::visit(ForStatement const& _node) auto indices = copyVariableIndices(); if (_node.condition()) { + m_loopCheckpoints.emplace(); _node.condition()->accept(*this); forCondition = expr(*_node.condition()); + m_loopCheckpoints.pop(); } // assert that the loop is complete m_context.addAssertion(!forCondition || broke || !forConditionOnPreviousIterations); @@ -932,9 +936,9 @@ void BMC::checkVerificationTarget(BMCVerificationTarget& _target) checkAssert(_target); break; case VerificationTargetType::ConstantCondition: - solAssert(false, "Checks for constant condition are handled separately"); + smtAssert(false, "Checks for constant condition are handled separately"); default: - solAssert(false, ""); + smtAssert(false); } } diff --git a/test/libsolidity/smtCheckerTests/loops/for_loop_condition_constant_true_in_first_iteration_and_constant_false_in_second.sol b/test/libsolidity/smtCheckerTests/loops/for_loop_condition_constant_true_in_first_iteration_and_constant_false_in_second.sol new file mode 100644 index 000000000000..7e0a85b9b401 --- /dev/null +++ b/test/libsolidity/smtCheckerTests/loops/for_loop_condition_constant_true_in_first_iteration_and_constant_false_in_second.sol @@ -0,0 +1,10 @@ +contract Test { + function loop() public pure { + for (uint k = 0; (k == 0 ? true : false); k++) { + } + } +} +// ==== +// SMTEngine: bmc +// SMTTargets: constantCondition +// ---- diff --git a/test/libsolidity/smtCheckerTests/loops/while_loop_condition_constant_true_in_first_iteration_and_constant_false_in_second.sol b/test/libsolidity/smtCheckerTests/loops/while_loop_condition_constant_true_in_first_iteration_and_constant_false_in_second.sol new file mode 100644 index 000000000000..b367cb803647 --- /dev/null +++ b/test/libsolidity/smtCheckerTests/loops/while_loop_condition_constant_true_in_first_iteration_and_constant_false_in_second.sol @@ -0,0 +1,12 @@ +contract Test { + function loop() public pure { + uint k = 0; + while (k == 0 ? true : false) { + ++k; + } + } +} +// ==== +// SMTEngine: bmc +// SMTTargets: constantCondition +// ---- From b1a9031f5875e8bfd2e8ac670818c954096b8543 Mon Sep 17 00:00:00 2001 From: Martin Blicha Date: Sat, 29 Mar 2025 20:11:58 +0100 Subject: [PATCH 0937/1022] SMTChecker: Clean up includes --- libsmtutil/SMTLib2Interface.cpp | 3 ++- libsmtutil/SMTPortfolio.h | 3 --- libsmtutil/SolverInterface.h | 3 ++- libsolidity/formal/ArraySlicePredicate.cpp | 2 ++ libsolidity/formal/ArraySlicePredicate.h | 4 ++-- libsolidity/formal/EncodingContext.cpp | 7 +++++++ libsolidity/formal/EncodingContext.h | 5 +---- libsolidity/formal/ExpressionFormatter.cpp | 2 ++ libsolidity/formal/Predicate.cpp | 2 +- libsolidity/formal/Predicate.h | 3 ++- libsolidity/formal/SymbolicTypes.cpp | 1 + libsolidity/formal/SymbolicTypes.h | 1 - libsolidity/formal/SymbolicVariables.cpp | 2 ++ libsolidity/formal/VariableUsage.cpp | 5 +---- 14 files changed, 25 insertions(+), 18 deletions(-) diff --git a/libsmtutil/SMTLib2Interface.cpp b/libsmtutil/SMTLib2Interface.cpp index 0430f0d21ea0..403989ca1aad 100644 --- a/libsmtutil/SMTLib2Interface.cpp +++ b/libsmtutil/SMTLib2Interface.cpp @@ -25,7 +25,8 @@ #include #include -#include +#include +#include #include #include diff --git a/libsmtutil/SMTPortfolio.h b/libsmtutil/SMTPortfolio.h index b445f40a2b69..59e0752a3471 100644 --- a/libsmtutil/SMTPortfolio.h +++ b/libsmtutil/SMTPortfolio.h @@ -20,10 +20,7 @@ #include -#include -#include -#include #include namespace solidity::smtutil diff --git a/libsmtutil/SolverInterface.h b/libsmtutil/SolverInterface.h index 2639ae024034..c434322d5d0f 100644 --- a/libsmtutil/SolverInterface.h +++ b/libsmtutil/SolverInterface.h @@ -26,7 +26,8 @@ #include #include -#include +#include +#include #include #include diff --git a/libsolidity/formal/ArraySlicePredicate.cpp b/libsolidity/formal/ArraySlicePredicate.cpp index 21d5fb1add29..67e635deb39c 100644 --- a/libsolidity/formal/ArraySlicePredicate.cpp +++ b/libsolidity/formal/ArraySlicePredicate.cpp @@ -18,6 +18,8 @@ #include +#include + #include using namespace solidity; diff --git a/libsolidity/formal/ArraySlicePredicate.h b/libsolidity/formal/ArraySlicePredicate.h index 180a9d1898ed..565dba657b9c 100644 --- a/libsolidity/formal/ArraySlicePredicate.h +++ b/libsolidity/formal/ArraySlicePredicate.h @@ -16,9 +16,9 @@ */ // SPDX-License-Identifier: GPL-3.0 -#include +#pragma once + #include -#include #include diff --git a/libsolidity/formal/EncodingContext.cpp b/libsolidity/formal/EncodingContext.cpp index e0a09bcf7b8f..cc046cf0337d 100644 --- a/libsolidity/formal/EncodingContext.cpp +++ b/libsolidity/formal/EncodingContext.cpp @@ -18,12 +18,19 @@ #include +#include + #include using namespace solidity; using namespace solidity::util; using namespace solidity::frontend::smt; +bool EncodingContext::IdCompare::operator()(ASTNode const* lhs, ASTNode const* rhs) const +{ + return lhs->id() < rhs->id(); +} + EncodingContext::EncodingContext(): m_state(*this) { diff --git a/libsolidity/formal/EncodingContext.h b/libsolidity/formal/EncodingContext.h index 5387184ee0c9..e7d577bbf52c 100644 --- a/libsolidity/formal/EncodingContext.h +++ b/libsolidity/formal/EncodingContext.h @@ -68,10 +68,7 @@ class EncodingContext struct IdCompare { - bool operator()(ASTNode const* lhs, ASTNode const* rhs) const - { - return lhs->id() < rhs->id(); - } + bool operator()(ASTNode const* lhs, ASTNode const* rhs) const; }; /// Variables. diff --git a/libsolidity/formal/ExpressionFormatter.cpp b/libsolidity/formal/ExpressionFormatter.cpp index 865a568f62da..dff84c860aab 100644 --- a/libsolidity/formal/ExpressionFormatter.cpp +++ b/libsolidity/formal/ExpressionFormatter.cpp @@ -20,6 +20,8 @@ #include +#include + #include #include diff --git a/libsolidity/formal/Predicate.cpp b/libsolidity/formal/Predicate.cpp index 66d8c2405538..7f742ec18d0b 100644 --- a/libsolidity/formal/Predicate.cpp +++ b/libsolidity/formal/Predicate.cpp @@ -28,7 +28,7 @@ #include -#include +#include #include using namespace solidity; diff --git a/libsolidity/formal/Predicate.h b/libsolidity/formal/Predicate.h index 7e4ba0f00fe8..d523f955404c 100644 --- a/libsolidity/formal/Predicate.h +++ b/libsolidity/formal/Predicate.h @@ -19,7 +19,8 @@ #pragma once -#include +#include +#include #include #include diff --git a/libsolidity/formal/SymbolicTypes.cpp b/libsolidity/formal/SymbolicTypes.cpp index 738a48f706c3..11c92a83af40 100644 --- a/libsolidity/formal/SymbolicTypes.cpp +++ b/libsolidity/formal/SymbolicTypes.cpp @@ -20,6 +20,7 @@ #include +#include #include #include #include diff --git a/libsolidity/formal/SymbolicTypes.h b/libsolidity/formal/SymbolicTypes.h index d38dcc04514a..9259ff64a4c6 100644 --- a/libsolidity/formal/SymbolicTypes.h +++ b/libsolidity/formal/SymbolicTypes.h @@ -19,7 +19,6 @@ #pragma once #include -#include #include namespace solidity::frontend::smt diff --git a/libsolidity/formal/SymbolicVariables.cpp b/libsolidity/formal/SymbolicVariables.cpp index f0cebc46c291..29301d095ca4 100644 --- a/libsolidity/formal/SymbolicVariables.cpp +++ b/libsolidity/formal/SymbolicVariables.cpp @@ -18,6 +18,8 @@ #include +#include + #include #include diff --git a/libsolidity/formal/VariableUsage.cpp b/libsolidity/formal/VariableUsage.cpp index ab7c425ae46c..000dcbc8175a 100644 --- a/libsolidity/formal/VariableUsage.cpp +++ b/libsolidity/formal/VariableUsage.cpp @@ -18,12 +18,9 @@ #include -#include #include -#include - -#include +#include using namespace solidity; using namespace solidity::util; From 629bb285394593aa5271d1a8dbdf335e71d99ce4 Mon Sep 17 00:00:00 2001 From: Martin Blicha Date: Sat, 29 Mar 2025 21:29:24 +0100 Subject: [PATCH 0938/1022] SMTChecker: Remove unused functionality --- libsolidity/CMakeLists.txt | 2 - libsolidity/formal/BMC.cpp | 1 - libsolidity/formal/SMTEncoder.cpp | 9 --- libsolidity/formal/SMTEncoder.h | 2 - libsolidity/formal/VariableUsage.cpp | 115 --------------------------- libsolidity/formal/VariableUsage.h | 65 --------------- 6 files changed, 194 deletions(-) delete mode 100644 libsolidity/formal/VariableUsage.cpp delete mode 100644 libsolidity/formal/VariableUsage.h diff --git a/libsolidity/CMakeLists.txt b/libsolidity/CMakeLists.txt index f0289acac3a8..62f0576dc59f 100644 --- a/libsolidity/CMakeLists.txt +++ b/libsolidity/CMakeLists.txt @@ -137,8 +137,6 @@ set(sources formal/SymbolicTypes.h formal/SymbolicVariables.cpp formal/SymbolicVariables.h - formal/VariableUsage.cpp - formal/VariableUsage.h formal/Z3CHCSmtLib2Interface.cpp formal/Z3CHCSmtLib2Interface.h formal/Z3SMTLib2Interface.cpp diff --git a/libsolidity/formal/BMC.cpp b/libsolidity/formal/BMC.cpp index 8401c8dbfc0b..bcd88b6dac59 100644 --- a/libsolidity/formal/BMC.cpp +++ b/libsolidity/formal/BMC.cpp @@ -80,7 +80,6 @@ void BMC::analyze(SourceUnit const& _source, std::map SMTEncoder::touchedVariables(ASTNode const& _node) -{ - std::vector callStack; - for (auto const& call: m_callStack) - callStack.push_back(call.first); - return m_variableUsage.touchedVariables(_node, callStack); -} - Declaration const* SMTEncoder::expressionToDeclaration(Expression const& _expr) const { if (auto const* identifier = dynamic_cast(&_expr)) diff --git a/libsolidity/formal/SMTEncoder.h b/libsolidity/formal/SMTEncoder.h index 5bfb70d8126d..60cfb9cf90cd 100644 --- a/libsolidity/formal/SMTEncoder.h +++ b/libsolidity/formal/SMTEncoder.h @@ -27,7 +27,6 @@ #include #include #include -#include #include #include @@ -454,7 +453,6 @@ class SMTEncoder: public ASTConstVisitor smtutil::Expression constraints; }; - smt::VariableUsage m_variableUsage; bool m_arrayAssignmentHappened = false; /// Stores the instances of an Uninterpreted Function applied to arguments. diff --git a/libsolidity/formal/VariableUsage.cpp b/libsolidity/formal/VariableUsage.cpp deleted file mode 100644 index 000dcbc8175a..000000000000 --- a/libsolidity/formal/VariableUsage.cpp +++ /dev/null @@ -1,115 +0,0 @@ -/* - This file is part of solidity. - - solidity is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - solidity is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with solidity. If not, see . -*/ -// SPDX-License-Identifier: GPL-3.0 - -#include - -#include - -#include - -using namespace solidity; -using namespace solidity::util; -using namespace solidity::frontend; -using namespace solidity::frontend::smt; - -std::set VariableUsage::touchedVariables(ASTNode const& _node, std::vector const& _outerCallstack) -{ - m_touchedVariables.clear(); - m_callStack.clear(); - m_callStack += _outerCallstack; - if (!m_callStack.empty()) - m_lastCall = m_callStack.back(); - _node.accept(*this); - return m_touchedVariables; -} - -void VariableUsage::endVisit(Identifier const& _identifier) -{ - if (_identifier.annotation().willBeWrittenTo) - checkIdentifier(_identifier); -} - -void VariableUsage::endVisit(IndexAccess const& _indexAccess) -{ - if (_indexAccess.annotation().willBeWrittenTo) - { - /// identifier.annotation().willBeWrittenTo == false, that's why we - /// need to check that before. - auto identifier = dynamic_cast(SMTEncoder::leftmostBase(_indexAccess)); - if (identifier) - checkIdentifier(*identifier); - } -} - -void VariableUsage::endVisit(FunctionCall const& _funCall) -{ - auto scopeContract = currentScopeContract(); - if (m_inlineFunctionCalls(_funCall, scopeContract, m_currentContract)) - if (auto funDef = SMTEncoder::functionCallToDefinition(_funCall, scopeContract, m_currentContract)) - if (find(m_callStack.begin(), m_callStack.end(), funDef) == m_callStack.end()) - funDef->accept(*this); -} - -bool VariableUsage::visit(FunctionDefinition const& _function) -{ - m_callStack.push_back(&_function); - return true; -} - -void VariableUsage::endVisit(FunctionDefinition const&) -{ - solAssert(!m_callStack.empty(), ""); - m_callStack.pop_back(); -} - -void VariableUsage::endVisit(ModifierInvocation const& _modifierInv) -{ - auto const& modifierDef = dynamic_cast(_modifierInv.name().annotation().referencedDeclaration); - if (modifierDef) - modifierDef->accept(*this); -} - -void VariableUsage::endVisit(PlaceholderStatement const&) -{ - solAssert(!m_callStack.empty(), ""); - FunctionDefinition const* funDef = nullptr; - for (auto it = m_callStack.rbegin(); it != m_callStack.rend() && !funDef; ++it) - funDef = dynamic_cast(*it); - solAssert(funDef, ""); - if (funDef->isImplemented()) - funDef->body().accept(*this); -} - -void VariableUsage::checkIdentifier(Identifier const& _identifier) -{ - Declaration const* declaration = _identifier.annotation().referencedDeclaration; - solAssert(declaration, ""); - if (VariableDeclaration const* varDecl = dynamic_cast(declaration)) - { - if (!varDecl->isLocalVariable() || (m_lastCall && varDecl->functionOrModifierDefinition() == m_lastCall)) - m_touchedVariables.insert(varDecl); - } -} - -ContractDefinition const* VariableUsage::currentScopeContract() -{ - for (auto&& f: m_callStack | ranges::views::reverse) - if (auto fun = dynamic_cast(f)) - return fun->annotation().contract; - return nullptr; -} diff --git a/libsolidity/formal/VariableUsage.h b/libsolidity/formal/VariableUsage.h deleted file mode 100644 index 4dc90f8c07a7..000000000000 --- a/libsolidity/formal/VariableUsage.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - This file is part of solidity. - - solidity is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - solidity is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with solidity. If not, see . -*/ -// SPDX-License-Identifier: GPL-3.0 - -#pragma once - -#include - -#include -#include - -namespace solidity::frontend::smt -{ - -/** - * This class computes information about which variables are modified in a certain subtree. - */ -class VariableUsage: private ASTConstVisitor -{ -public: - /// @param _outerCallstack the current callstack in the callers context. - std::set touchedVariables(ASTNode const& _node, std::vector const& _outerCallstack); - - /// Sets whether to inline function calls. - void setFunctionInlining(std::function _inlineFunctionCalls) { m_inlineFunctionCalls = _inlineFunctionCalls; } - - void setCurrentContract(ContractDefinition const& _contract) { m_currentContract = &_contract; } - -private: - void endVisit(Identifier const& _node) override; - void endVisit(IndexAccess const& _node) override; - void endVisit(FunctionCall const& _node) override; - bool visit(FunctionDefinition const& _node) override; - void endVisit(FunctionDefinition const& _node) override; - void endVisit(ModifierInvocation const& _node) override; - void endVisit(PlaceholderStatement const& _node) override; - - /// Checks whether an identifier should be added to touchedVariables. - void checkIdentifier(Identifier const& _identifier); - - ContractDefinition const* currentScopeContract(); - - std::set m_touchedVariables; - std::vector m_callStack; - CallableDeclaration const* m_lastCall = nullptr; - ContractDefinition const* m_currentContract = nullptr; - - std::function m_inlineFunctionCalls = [](FunctionCall const&, ContractDefinition const*, ContractDefinition const*) { return false; }; -}; - -} From ae3da8c12ec9f1f22c3e2e1a9b29e5896a8313cf Mon Sep 17 00:00:00 2001 From: Maxim Ryabykh Date: Wed, 2 Oct 2024 11:56:08 +0300 Subject: [PATCH 0939/1022] docs: fixed a mismatch in the name of the function referenced in the micropayment example --- docs/examples/micropayment.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/examples/micropayment.rst b/docs/examples/micropayment.rst index 9a3ad845ce1a..a7b26bb51b8b 100644 --- a/docs/examples/micropayment.rst +++ b/docs/examples/micropayment.rst @@ -274,8 +274,8 @@ Opening the Payment Channel To open the payment channel, Alice deploys the smart contract, attaching the Ether to be escrowed and specifying the intended recipient and a -maximum duration for the channel to exist. This is the function -``SimplePaymentChannel`` in the contract, at the end of this section. +maximum duration for the channel to exist. This is the ``constructor`` +in the ``SimplePaymentChannel`` contract, at the end of this section. Making Payments --------------- From fe7411114cc0c62ad386975a8ea491650b5c709a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Wed, 16 Apr 2025 13:37:43 +0200 Subject: [PATCH 0940/1022] EVMAssemblyStack: Add extra accessors that do not require contract name --- libevmasm/EVMAssemblyStack.cpp | 24 +++++++++++++++++------- libevmasm/EVMAssemblyStack.h | 6 ++++++ 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/libevmasm/EVMAssemblyStack.cpp b/libevmasm/EVMAssemblyStack.cpp index 7cb05bf8bf00..bed4ff744ec4 100644 --- a/libevmasm/EVMAssemblyStack.cpp +++ b/libevmasm/EVMAssemblyStack.cpp @@ -74,13 +74,13 @@ void EVMAssemblyStack::assemble() LinkerObject const& EVMAssemblyStack::object(std::string const& _contractName) const { solAssert(_contractName == m_name); - return m_object; + return object(); } LinkerObject const& EVMAssemblyStack::runtimeObject(std::string const& _contractName) const { solAssert(_contractName == m_name); - return m_runtimeObject; + return runtimeObject(); } std::map EVMAssemblyStack::sourceIndices() const @@ -95,13 +95,13 @@ std::map EVMAssemblyStack::sourceIndices() const std::string const* EVMAssemblyStack::sourceMapping(std::string const& _contractName) const { solAssert(_contractName == m_name); - return &m_sourceMapping; + return &sourceMapping(); } std::string const* EVMAssemblyStack::runtimeSourceMapping(std::string const& _contractName) const { solAssert(_contractName == m_name); - return &m_runtimeSourceMapping; + return &runtimeSourceMapping(); } Json EVMAssemblyStack::ethdebug(std::string const& _contractName) const @@ -123,20 +123,30 @@ Json EVMAssemblyStack::ethdebug() const return {}; } -Json EVMAssemblyStack::assemblyJSON(std::string const& _contractName) const +Json EVMAssemblyStack::assemblyJSON() const { - solAssert(_contractName == m_name); solAssert(m_evmAssembly); return m_evmAssembly->assemblyJSON(sourceIndices()); } -std::string EVMAssemblyStack::assemblyString(std::string const& _contractName, StringMap const& _sourceCodes) const +Json EVMAssemblyStack::assemblyJSON(std::string const& _contractName) const { solAssert(_contractName == m_name); + return assemblyJSON(); +} + +std::string EVMAssemblyStack::assemblyString(StringMap const& _sourceCodes) const +{ solAssert(m_evmAssembly); return m_evmAssembly->assemblyString(m_debugInfoSelection, _sourceCodes); } +std::string EVMAssemblyStack::assemblyString(std::string const& _contractName, StringMap const& _sourceCodes) const +{ + solAssert(_contractName == m_name); + return assemblyString(_sourceCodes); +} + std::string const EVMAssemblyStack::filesystemFriendlyName(std::string const& _contractName) const { solAssert(_contractName == m_name); diff --git a/libevmasm/EVMAssemblyStack.h b/libevmasm/EVMAssemblyStack.h index 2fe63c11c2ec..444d444ba9e2 100644 --- a/libevmasm/EVMAssemblyStack.h +++ b/libevmasm/EVMAssemblyStack.h @@ -58,20 +58,26 @@ class EVMAssemblyStack: public AbstractAssemblyStack std::string const& name() const { return m_name; } + LinkerObject const& object() const { return m_object; } LinkerObject const& object(std::string const& _contractName) const override; + LinkerObject const& runtimeObject() const { return m_runtimeObject; } LinkerObject const& runtimeObject(std::string const& _contractName) const override; std::shared_ptr const& evmAssembly() const { return m_evmAssembly; } std::shared_ptr const& evmRuntimeAssembly() const { return m_evmRuntimeAssembly; } + std::string const& sourceMapping() const { return m_sourceMapping; } std::string const* sourceMapping(std::string const& _contractName) const override; + std::string const& runtimeSourceMapping() const { return m_runtimeSourceMapping; } std::string const* runtimeSourceMapping(std::string const& _contractName) const override; Json ethdebug(std::string const& _contractName) const override; Json ethdebugRuntime(std::string const& _contractName) const override; Json ethdebug() const override; + Json assemblyJSON() const; Json assemblyJSON(std::string const& _contractName) const override; + std::string assemblyString(StringMap const& _sourceCodes) const; std::string assemblyString(std::string const& _contractName, StringMap const& _sourceCodes) const override; std::string const filesystemFriendlyName(std::string const& _contractName) const override; From dd01ddda2379e6b9a2cf212e086e2d1ef6eb9340 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Fri, 14 Mar 2025 04:04:14 +0100 Subject: [PATCH 0941/1022] TestCaseReader: Expose fileName() --- test/TestCaseReader.h | 1 + 1 file changed, 1 insertion(+) diff --git a/test/TestCaseReader.h b/test/TestCaseReader.h index d1ef95be3c2c..5830e97f3666 100644 --- a/test/TestCaseReader.h +++ b/test/TestCaseReader.h @@ -59,6 +59,7 @@ class TestCaseReader std::size_t lineNumber() const { return m_lineNumber; } std::map const& settings() const { return m_settings; } std::ifstream& stream() { return m_fileStream; } + boost::filesystem::path const& fileName() const { return m_fileName; } std::string simpleExpectations(); From d3238c08ff61516a6d86a3035a0582aaeb5e5894 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Sat, 19 Apr 2025 04:36:11 +0200 Subject: [PATCH 0942/1022] Add a transparent comparator to c_instructions to allow string_view lookups --- libevmasm/Instruction.cpp | 2 +- libevmasm/Instruction.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libevmasm/Instruction.cpp b/libevmasm/Instruction.cpp index dad9804d09a8..b5568763573a 100644 --- a/libevmasm/Instruction.cpp +++ b/libevmasm/Instruction.cpp @@ -26,7 +26,7 @@ using namespace solidity; using namespace solidity::util; using namespace solidity::evmasm; -std::map const solidity::evmasm::c_instructions = +std::map> const solidity::evmasm::c_instructions = { { "STOP", Instruction::STOP }, { "ADD", Instruction::ADD }, diff --git a/libevmasm/Instruction.h b/libevmasm/Instruction.h index 137144715296..cfdb85d2fa4c 100644 --- a/libevmasm/Instruction.h +++ b/libevmasm/Instruction.h @@ -322,6 +322,6 @@ InstructionInfo instructionInfo(Instruction _inst, langutil::EVMVersion _evmVers bool isValidInstruction(Instruction _inst); /// Convert from string mnemonic to Instruction type. -extern const std::map c_instructions; +extern const std::map> c_instructions; } From 266c7d49a8b9a9524d841b088410957bb7335e4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Fri, 14 Mar 2025 04:51:35 +0100 Subject: [PATCH 0943/1022] EVM assembly test case with JSON input --- test/CMakeLists.txt | 2 + test/InteractiveTests.h | 3 + test/TestCase.cpp | 7 +- test/libevmasm/EVMAssemblyTest.cpp | 158 ++++++++++++++++++ test/libevmasm/EVMAssemblyTest.h | 70 ++++++++ .../code_generation_error.asmjson | 14 ++ .../isoltestTesting/invalid_json.asmjson | 3 + .../settings_eof_version.asmjson | 13 ++ .../settings_evm_version.asmjson | 13 ++ ...tings_optimizer_constant_optimizer.asmjson | 14 ++ .../settings_optimizer_cse.asmjson | 16 ++ .../settings_optimizer_deduplicate.asmjson | 26 +++ ...expected_executions_per_deployment.asmjson | 26 +++ .../settings_optimizer_inliner.asmjson | 33 ++++ ...ettings_optimizer_jumpdest_remover.asmjson | 14 ++ .../settings_optimizer_peephole.asmjson | 15 ++ .../settings_optimizer_preset.asmjson | 18 ++ .../isoltestTesting/settings_outputs.asmjson | 10 ++ .../isoltestTesting/smoke.asmjson | 11 ++ test/tools/CMakeLists.txt | 1 + test/tools/isoltest.cpp | 2 +- 21 files changed, 465 insertions(+), 4 deletions(-) create mode 100644 test/libevmasm/EVMAssemblyTest.cpp create mode 100644 test/libevmasm/EVMAssemblyTest.h create mode 100644 test/libevmasm/evmAssemblyTests/isoltestTesting/code_generation_error.asmjson create mode 100644 test/libevmasm/evmAssemblyTests/isoltestTesting/invalid_json.asmjson create mode 100644 test/libevmasm/evmAssemblyTests/isoltestTesting/settings_eof_version.asmjson create mode 100644 test/libevmasm/evmAssemblyTests/isoltestTesting/settings_evm_version.asmjson create mode 100644 test/libevmasm/evmAssemblyTests/isoltestTesting/settings_optimizer_constant_optimizer.asmjson create mode 100644 test/libevmasm/evmAssemblyTests/isoltestTesting/settings_optimizer_cse.asmjson create mode 100644 test/libevmasm/evmAssemblyTests/isoltestTesting/settings_optimizer_deduplicate.asmjson create mode 100644 test/libevmasm/evmAssemblyTests/isoltestTesting/settings_optimizer_expected_executions_per_deployment.asmjson create mode 100644 test/libevmasm/evmAssemblyTests/isoltestTesting/settings_optimizer_inliner.asmjson create mode 100644 test/libevmasm/evmAssemblyTests/isoltestTesting/settings_optimizer_jumpdest_remover.asmjson create mode 100644 test/libevmasm/evmAssemblyTests/isoltestTesting/settings_optimizer_peephole.asmjson create mode 100644 test/libevmasm/evmAssemblyTests/isoltestTesting/settings_optimizer_preset.asmjson create mode 100644 test/libevmasm/evmAssemblyTests/isoltestTesting/settings_outputs.asmjson create mode 100644 test/libevmasm/evmAssemblyTests/isoltestTesting/smoke.asmjson diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index da115f0d4a5b..6f48b8a8469e 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -51,6 +51,8 @@ detect_stray_source_files("${libsolutil_sources}" "libsolutil/") set(libevmasm_sources libevmasm/Assembler.cpp + libevmasm/EVMAssemblyTest.cpp + libevmasm/EVMAssemblyTest.h libevmasm/Optimiser.cpp ) detect_stray_source_files("${libevmasm_sources}" "libevmasm/") diff --git a/test/InteractiveTests.h b/test/InteractiveTests.h index e043fcdbe676..107a6aae0bef 100644 --- a/test/InteractiveTests.h +++ b/test/InteractiveTests.h @@ -42,6 +42,8 @@ #include #include +#include + #include namespace solidity::frontend::test @@ -64,6 +66,7 @@ struct Testsuite Testsuite const g_interactiveTestsuites[] = { /* Title Path Subpath SMT NeedsVM Creator function */ + {"EVM Assembly", "libevmasm", "evmAssemblyTests", false, false, &evmasm::test::EVMAssemblyTest::create}, {"Yul Optimizer", "libyul", "yulOptimizerTests", false, false, &yul::test::YulOptimizerTest::create}, {"Yul Interpreter", "libyul", "yulInterpreterTests", false, false, &yul::test::YulInterpreterTest::create}, {"Yul Object Compiler", "libyul", "objectCompiler", false, false, &yul::test::ObjectCompilerTest::create}, diff --git a/test/TestCase.cpp b/test/TestCase.cpp index da47c26fde90..8a8d2451d1f2 100644 --- a/test/TestCase.cpp +++ b/test/TestCase.cpp @@ -51,9 +51,10 @@ void TestCase::printUpdatedSettings(std::ostream& _stream, std::string const& _l bool TestCase::isTestFilename(boost::filesystem::path const& _filename) { std::string extension = _filename.extension().string(); - return (extension == ".sol" || extension == ".yul" || extension == ".stack") && - !boost::starts_with(_filename.string(), "~") && - !boost::starts_with(_filename.string(), "."); + // NOTE: .asmjson rather than .json because JSON files that do not represent test cases exist in some test dirs. + return (extension == ".sol" || extension == ".yul" || extension == ".asmjson" || extension == ".stack") && + !_filename.string().starts_with('~') && + !_filename.string().starts_with('.'); } bool TestCase::shouldRun() diff --git a/test/libevmasm/EVMAssemblyTest.cpp b/test/libevmasm/EVMAssemblyTest.cpp new file mode 100644 index 000000000000..b497c51476e6 --- /dev/null +++ b/test/libevmasm/EVMAssemblyTest.cpp @@ -0,0 +1,158 @@ +/* + This file is part of solidity. + + solidity is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + solidity is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with solidity. If not, see . +*/ + +#include + +#include + +#include +#include + +#include +#include +#include + +#include + +using namespace std::string_literals; +using namespace solidity; +using namespace solidity::test; +using namespace solidity::evmasm; +using namespace solidity::evmasm::test; +using namespace solidity::frontend; +using namespace solidity::frontend::test; +using namespace solidity::langutil; +using namespace solidity::util; + +std::vector const EVMAssemblyTest::c_outputLabels = { + "Assembly", + "Bytecode", + "Opcodes", + "SourceMappings", +}; + +std::unique_ptr EVMAssemblyTest::create(Config const& _config) +{ + return std::make_unique(_config.filename); +} + +EVMAssemblyTest::EVMAssemblyTest(std::string const& _filename): + EVMVersionRestrictedTestCase(_filename) +{ + m_source = m_reader.source(); + m_expectation = m_reader.simpleExpectations(); + + if (!_filename.ends_with(".asmjson")) + BOOST_THROW_EXCEPTION(std::runtime_error("Not an assembly test: \"" + _filename + "\". Allowed extensions: .asmjson.")); + + m_selectedOutputs = m_reader.stringSetting("outputs", "Assembly,Bytecode,Opcodes,SourceMappings"); + OptimisationPreset optimizationPreset = m_reader.enumSetting( + "optimizationPreset", + { + {"none", OptimisationPreset::None}, + {"minimal", OptimisationPreset::Minimal}, + {"standard", OptimisationPreset::Standard}, + {"full", OptimisationPreset::Full}, + }, + "none" + ); + m_optimizerSettings = Assembly::OptimiserSettings::translateSettings(OptimiserSettings::preset(optimizationPreset)); + m_optimizerSettings.expectedExecutionsPerDeployment = m_reader.sizetSetting( + "optimizer.expectedExecutionsPerDeployment", + m_optimizerSettings.expectedExecutionsPerDeployment + ); + + auto const optimizerComponentSetting = [&](std::string const& _component, bool& _setting) { + _setting = m_reader.boolSetting("optimizer." + _component, _setting); + }; + optimizerComponentSetting("inliner", m_optimizerSettings.runInliner); + optimizerComponentSetting("jumpdestRemover", m_optimizerSettings.runJumpdestRemover); + optimizerComponentSetting("peephole", m_optimizerSettings.runPeephole); + optimizerComponentSetting("deduplicate", m_optimizerSettings.runDeduplicate); + optimizerComponentSetting("cse", m_optimizerSettings.runCSE); + optimizerComponentSetting("constantOptimizer", m_optimizerSettings.runConstantOptimiser); + + // TODO: Enable when assembly import for EOF is implemented. + if (CommonOptions::get().eofVersion().has_value()) + m_shouldRun = false; +} + +TestCase::TestResult EVMAssemblyTest::run(std::ostream& _stream, std::string const& _linePrefix, bool const _formatted) +{ + EVMAssemblyStack evmAssemblyStack( + CommonOptions::get().evmVersion(), + CommonOptions::get().eofVersion(), + m_optimizerSettings + ); + + evmAssemblyStack.selectDebugInfo(DebugInfoSelection::AllExceptExperimental()); + + try + { + evmAssemblyStack.parseAndAnalyze(m_reader.fileName().filename().string(), m_source); + } + catch (AssemblyImportException const& _exception) + { + m_obtainedResult = "AssemblyImportException: "s + _exception.what() + "\n"; + return checkResult(_stream, _linePrefix, _formatted); + } + + try + { + evmAssemblyStack.assemble(); + } + catch (Error const& _error) + { + // TODO: EVMAssemblyStack should catch these on its own and provide an error reporter. + soltestAssert(_error.comment(), "Errors must include a message for the user."); + m_obtainedResult = Error::formatErrorType(_error.type()) + ": " + *_error.comment() + "\n"; + return checkResult(_stream, _linePrefix, _formatted); + } + soltestAssert(evmAssemblyStack.compilationSuccessful()); + + auto const produceOutput = [&](std::string const& _output) { + if (_output == "Assembly") + return evmAssemblyStack.assemblyString({{m_reader.fileName().filename().string(), m_source}}); + if (_output == "Bytecode") + return util::toHex(evmAssemblyStack.object().bytecode); + if (_output == "Opcodes") + return disassemble(evmAssemblyStack.object().bytecode, CommonOptions::get().evmVersion()); + if (_output == "SourceMappings") + return evmAssemblyStack.sourceMapping(); + soltestAssert(false); + unreachable(); + }; + + std::set selectedOutputSet; + boost::split(selectedOutputSet, m_selectedOutputs, boost::is_any_of(",")); + for (std::string const& output: c_outputLabels) + if (selectedOutputSet.contains(output)) + { + if (!m_obtainedResult.empty() && m_obtainedResult.back() != '\n') + m_obtainedResult += "\n"; + + // Don't trim on the left to avoid stripping indentation. + std::string content = produceOutput(output); + boost::trim_right(content); + std::string separator = (content.empty() ? "" : (output == "Assembly" ? "\n" : " ")); + m_obtainedResult += output + ":" + separator + content; + } + if (!m_obtainedResult.empty() && m_obtainedResult.back() != '\n') + m_obtainedResult += "\n"; + + return checkResult(_stream, _linePrefix, _formatted); +} diff --git a/test/libevmasm/EVMAssemblyTest.h b/test/libevmasm/EVMAssemblyTest.h new file mode 100644 index 000000000000..f8923c0dc1a1 --- /dev/null +++ b/test/libevmasm/EVMAssemblyTest.h @@ -0,0 +1,70 @@ +/* + This file is part of solidity. + + solidity is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + solidity is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with solidity. If not, see . +*/ +// SPDX-License-Identifier: GPL-3.0 + +#pragma once + +#include + +#include + +#include +#include +#include +#include + +namespace solidity::evmasm::test +{ + +/// Custom test case that runs the final part of the compiler pipeline (assembling into bytecode). +/// Supports assembly JSON format produced by --asm-json. +/// +/// Available settings: +/// - EVMVersion: The range of EVM versions to run the test for. Inherited from EVMVersionRestrictedTestCase. +/// - bytecodeFormat: The range of bytecode formats (EOF/legacy) to run the test for. Inherited from EVMVersionRestrictedTestCase. +/// - outputs: List of outputs to include in the test. The order of values does NOT determine the order +/// in which the outputs are printed. Supported outputs: Assembly, Bytecode, Opcodes, SourceMappings. +/// The default is to print all outputs. +/// - optimizationPreset: Preset to load as the base optimizer settings. +/// One of: none, minimal, standard, full. The default is none. +/// - optimizer.*: A set of detailed optimizer settings applied on top of the base preset. +/// Each one corresponds to a field in Assembly::OptimiserSettings and uses the value from the +/// preset as its default. Available settings: +/// - optimizer.expectedExecutionsPerDeployment (integer) +/// - optimizer.inliner (bool) +/// - optimizer.jumpdestRemover (bool) +/// - optimizer.peephole (bool) +/// - optimizer.deduplicate (bool) +/// - optimizer.cse (bool) +/// - optimizer.constantOptimizer (bool) +class EVMAssemblyTest: public frontend::test::EVMVersionRestrictedTestCase +{ +public: + static std::unique_ptr create(Config const& _config); + + EVMAssemblyTest(std::string const& _filename); + + TestResult run(std::ostream& _stream, std::string const& _linePrefix = "", bool const _formatted = false) override; + +private: + static std::vector const c_outputLabels; + + std::string m_selectedOutputs; + evmasm::Assembly::OptimiserSettings m_optimizerSettings; +}; + +} diff --git a/test/libevmasm/evmAssemblyTests/isoltestTesting/code_generation_error.asmjson b/test/libevmasm/evmAssemblyTests/isoltestTesting/code_generation_error.asmjson new file mode 100644 index 000000000000..4297c5f35b80 --- /dev/null +++ b/test/libevmasm/evmAssemblyTests/isoltestTesting/code_generation_error.asmjson @@ -0,0 +1,14 @@ +{ + ".code": [ + {"name": "PUSH [$]", "value": "0"} + ], + ".data": { + "0": { + ".code": [ + {"name": "PUSHIMMUTABLE", "value": "x"} + ] + } + } +} +// ---- +// CodeGenerationError: Some immutables were read from but never assigned, possibly because of optimization. diff --git a/test/libevmasm/evmAssemblyTests/isoltestTesting/invalid_json.asmjson b/test/libevmasm/evmAssemblyTests/isoltestTesting/invalid_json.asmjson new file mode 100644 index 000000000000..a834108d1ad7 --- /dev/null +++ b/test/libevmasm/evmAssemblyTests/isoltestTesting/invalid_json.asmjson @@ -0,0 +1,3 @@ +{ +// ---- +// AssemblyImportException: Could not parse JSON file. diff --git a/test/libevmasm/evmAssemblyTests/isoltestTesting/settings_eof_version.asmjson b/test/libevmasm/evmAssemblyTests/isoltestTesting/settings_eof_version.asmjson new file mode 100644 index 000000000000..5785b4b8931e --- /dev/null +++ b/test/libevmasm/evmAssemblyTests/isoltestTesting/settings_eof_version.asmjson @@ -0,0 +1,13 @@ +{ + ".code": [ + {"name": "CODESIZE"} + ] +} +// ==== +// bytecodeFormat: legacy +// ---- +// Assembly: +// codesize +// Bytecode: 38 +// Opcodes: CODESIZE +// SourceMappings: :::-:0 diff --git a/test/libevmasm/evmAssemblyTests/isoltestTesting/settings_evm_version.asmjson b/test/libevmasm/evmAssemblyTests/isoltestTesting/settings_evm_version.asmjson new file mode 100644 index 000000000000..a0f042b32e88 --- /dev/null +++ b/test/libevmasm/evmAssemblyTests/isoltestTesting/settings_evm_version.asmjson @@ -0,0 +1,13 @@ +{ + ".code": [ + {"name": "BLOBBASEFEE"} + ] +} +// ==== +// EVMVersion: >=cancun +// ---- +// Assembly: +// blobbasefee +// Bytecode: 4a +// Opcodes: BLOBBASEFEE +// SourceMappings: :::-:0 diff --git a/test/libevmasm/evmAssemblyTests/isoltestTesting/settings_optimizer_constant_optimizer.asmjson b/test/libevmasm/evmAssemblyTests/isoltestTesting/settings_optimizer_constant_optimizer.asmjson new file mode 100644 index 000000000000..a3610217fbaf --- /dev/null +++ b/test/libevmasm/evmAssemblyTests/isoltestTesting/settings_optimizer_constant_optimizer.asmjson @@ -0,0 +1,14 @@ +{ + ".code": [ + {"name": "PUSH", "value": "ffffffffffffffff"} + ] +} +// ==== +// optimizationPreset: none +// optimizer.constantOptimizer: true +// ---- +// Assembly: +// sub(shl(0x40, 0x01), 0x01) +// Bytecode: 6001600160401b03 +// Opcodes: PUSH1 0x1 PUSH1 0x1 PUSH1 0x40 SHL SUB +// SourceMappings: :::-:0;;;; diff --git a/test/libevmasm/evmAssemblyTests/isoltestTesting/settings_optimizer_cse.asmjson b/test/libevmasm/evmAssemblyTests/isoltestTesting/settings_optimizer_cse.asmjson new file mode 100644 index 000000000000..c8133b43f799 --- /dev/null +++ b/test/libevmasm/evmAssemblyTests/isoltestTesting/settings_optimizer_cse.asmjson @@ -0,0 +1,16 @@ +{ + ".code": [ + {"name": "PUSH", "value": "0"}, + {"name": "DUP2"}, + {"name": "SUB"} + ] +} +// ==== +// optimizationPreset: none +// optimizer.cse: true +// ---- +// Assembly: +// dup1 +// Bytecode: 80 +// Opcodes: DUP1 +// SourceMappings: :::-:0 diff --git a/test/libevmasm/evmAssemblyTests/isoltestTesting/settings_optimizer_deduplicate.asmjson b/test/libevmasm/evmAssemblyTests/isoltestTesting/settings_optimizer_deduplicate.asmjson new file mode 100644 index 000000000000..67b87e59e9ee --- /dev/null +++ b/test/libevmasm/evmAssemblyTests/isoltestTesting/settings_optimizer_deduplicate.asmjson @@ -0,0 +1,26 @@ +{ + ".code": [ + {"name": "PUSH [tag]", "value": "1"}, + {"name": "PUSH [tag]", "value": "2"}, + {"name": "tag", "value": "1"}, + {"name": "JUMPDEST"}, + {"name": "JUMP"}, + {"name": "tag", "value": "2"}, + {"name": "JUMPDEST"}, + {"name": "JUMP"} + ] +} +// ==== +// optimizationPreset: none +// optimizer.deduplicate: true +// ---- +// Assembly: +// tag_1 +// tag_1 +// tag_1: +// jump +// tag_2: +// jump +// Bytecode: 600460045b565b56 +// Opcodes: PUSH1 0x4 PUSH1 0x4 JUMPDEST JUMP JUMPDEST JUMP +// SourceMappings: :::-:0;;;;; diff --git a/test/libevmasm/evmAssemblyTests/isoltestTesting/settings_optimizer_expected_executions_per_deployment.asmjson b/test/libevmasm/evmAssemblyTests/isoltestTesting/settings_optimizer_expected_executions_per_deployment.asmjson new file mode 100644 index 000000000000..b9fd814d5c8e --- /dev/null +++ b/test/libevmasm/evmAssemblyTests/isoltestTesting/settings_optimizer_expected_executions_per_deployment.asmjson @@ -0,0 +1,26 @@ +{ + ".code": [ + {"name": "PUSH [$]", "value": "0"} + ], + ".data": { + "0": { + ".code": [ + {"name": "PUSH", "value": "ffffffffffffffff"} + ] + } + } +} +// ==== +// optimizationPreset: standard +// optimizer.expectedExecutionsPerDeployment: 0 +// ---- +// Assembly: +// dataOffset(sub_0) +// stop +// +// sub_0: assembly { +// sub(shl(0x40, 0x01), 0x01) +// } +// Bytecode: 6003fe6001600160401b03 +// Opcodes: PUSH1 0x3 INVALID PUSH1 0x1 PUSH1 0x1 PUSH1 0x40 SHL SUB +// SourceMappings: :::-:0 diff --git a/test/libevmasm/evmAssemblyTests/isoltestTesting/settings_optimizer_inliner.asmjson b/test/libevmasm/evmAssemblyTests/isoltestTesting/settings_optimizer_inliner.asmjson new file mode 100644 index 000000000000..81be6392c444 --- /dev/null +++ b/test/libevmasm/evmAssemblyTests/isoltestTesting/settings_optimizer_inliner.asmjson @@ -0,0 +1,33 @@ +{ + ".code": [ + {"name": "PUSH [tag]", "value": "1"}, + {"name": "PUSH [tag]", "value": "2"}, + {"name": "JUMP"}, + {"name": "tag", "value": "1"}, + {"name": "JUMPDEST"}, + {"name": "STOP"}, + {"name": "tag", "value": "2"}, + {"name": "JUMPDEST"}, + {"name": "CALLVALUE"}, + {"name": "SWAP1"}, + {"name": "JUMP"} + ] +} +// ==== +// optimizationPreset: none +// optimizer.inliner: true +// ---- +// Assembly: +// tag_1 +// callvalue +// swap1 +// jump +// tag_1: +// stop +// tag_2: +// callvalue +// swap1 +// jump +// Bytecode: 60053490565b005b349056 +// Opcodes: PUSH1 0x5 CALLVALUE SWAP1 JUMP JUMPDEST STOP JUMPDEST CALLVALUE SWAP1 JUMP +// SourceMappings: :::-:0;;;;;;;;; diff --git a/test/libevmasm/evmAssemblyTests/isoltestTesting/settings_optimizer_jumpdest_remover.asmjson b/test/libevmasm/evmAssemblyTests/isoltestTesting/settings_optimizer_jumpdest_remover.asmjson new file mode 100644 index 000000000000..baca77b992fc --- /dev/null +++ b/test/libevmasm/evmAssemblyTests/isoltestTesting/settings_optimizer_jumpdest_remover.asmjson @@ -0,0 +1,14 @@ +{ + ".code": [ + {"name": "tag", "value": "1"}, + {"name": "JUMPDEST"} + ] +} +// ==== +// optimizationPreset: none +// optimizer.jumpdestRemover: true +// ---- +// Assembly: +// Bytecode: +// Opcodes: +// SourceMappings: diff --git a/test/libevmasm/evmAssemblyTests/isoltestTesting/settings_optimizer_peephole.asmjson b/test/libevmasm/evmAssemblyTests/isoltestTesting/settings_optimizer_peephole.asmjson new file mode 100644 index 000000000000..f9e7c3b8d550 --- /dev/null +++ b/test/libevmasm/evmAssemblyTests/isoltestTesting/settings_optimizer_peephole.asmjson @@ -0,0 +1,15 @@ +{ + ".code": [ + {"name": "STOP"}, + {"name": "STOP"} + ] +} +// ==== +// optimizationPreset: none +// optimizer.peephole: true +// ---- +// Assembly: +// stop +// Bytecode: 00 +// Opcodes: STOP +// SourceMappings: :::-:0 diff --git a/test/libevmasm/evmAssemblyTests/isoltestTesting/settings_optimizer_preset.asmjson b/test/libevmasm/evmAssemblyTests/isoltestTesting/settings_optimizer_preset.asmjson new file mode 100644 index 000000000000..706a3ae8b61a --- /dev/null +++ b/test/libevmasm/evmAssemblyTests/isoltestTesting/settings_optimizer_preset.asmjson @@ -0,0 +1,18 @@ +{ + ".code": [ + {"name": "PUSH", "value": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"}, + {"name": "PUSH", "value": "42"}, + {"name": "PUSH", "value": "24"}, + {"name": "SWAP1"}, + {"name": "ADD"} + ] +} +// ==== +// optimizationPreset: full +// ---- +// Assembly: +// not(0x00) +// 0x66 +// Bytecode: 5f196066 +// Opcodes: PUSH0 NOT PUSH1 0x66 +// SourceMappings: :::-:0;; diff --git a/test/libevmasm/evmAssemblyTests/isoltestTesting/settings_outputs.asmjson b/test/libevmasm/evmAssemblyTests/isoltestTesting/settings_outputs.asmjson new file mode 100644 index 000000000000..2af7b57c3e75 --- /dev/null +++ b/test/libevmasm/evmAssemblyTests/isoltestTesting/settings_outputs.asmjson @@ -0,0 +1,10 @@ +{ + ".code": [ + {"name": "CALLVALUE"} + ] +} +// ==== +// outputs: SourceMappings,Opcodes +// ---- +// Opcodes: CALLVALUE +// SourceMappings: :::-:0 diff --git a/test/libevmasm/evmAssemblyTests/isoltestTesting/smoke.asmjson b/test/libevmasm/evmAssemblyTests/isoltestTesting/smoke.asmjson new file mode 100644 index 000000000000..99e527a72587 --- /dev/null +++ b/test/libevmasm/evmAssemblyTests/isoltestTesting/smoke.asmjson @@ -0,0 +1,11 @@ +{ + ".code": [ + {"name": "CALLVALUE"} + ] +} +// ---- +// Assembly: +// callvalue +// Bytecode: 34 +// Opcodes: CALLVALUE +// SourceMappings: :::-:0 diff --git a/test/tools/CMakeLists.txt b/test/tools/CMakeLists.txt index 5c1d41b7f595..13018bf18512 100644 --- a/test/tools/CMakeLists.txt +++ b/test/tools/CMakeLists.txt @@ -18,6 +18,7 @@ add_executable(isoltest ../EVMHost.cpp ../TestCase.cpp ../TestCaseReader.cpp + ../libevmasm/EVMAssemblyTest.cpp ../libsolidity/util/BytesUtils.cpp ../libsolidity/util/Common.cpp ../libsolidity/util/ContractABIUtils.cpp diff --git a/test/tools/isoltest.cpp b/test/tools/isoltest.cpp index 57ab4af16034..32309b005507 100644 --- a/test/tools/isoltest.cpp +++ b/test/tools/isoltest.cpp @@ -75,7 +75,7 @@ class TestFilter boost::replace_all(filter, "/", "\\/"); boost::replace_all(filter, "*", ".*"); - m_filterExpression = std::regex{"(" + filter + "(\\.sol|\\.yul|\\.stack))"}; + m_filterExpression = std::regex{"(" + filter + "(\\.sol|\\.yul|\\.asmjson|\\.stack))"}; } bool matches(fs::path const& _path, std::string const& _name) const From fe3955111883851f64939783b9f542ccf33f6998 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Fri, 18 Apr 2025 03:18:05 +0200 Subject: [PATCH 0944/1022] Support human-readable assembly in EVM assembly test case --- test/CMakeLists.txt | 2 + test/TestCase.cpp | 2 +- test/libevmasm/EVMAssemblyTest.cpp | 29 ++- test/libevmasm/EVMAssemblyTest.h | 16 +- test/libevmasm/PlainAssemblyParser.cpp | 180 ++++++++++++++++++ test/libevmasm/PlainAssemblyParser.h | 79 ++++++++ .../isoltestTesting/comments.asm | 34 ++++ .../isoltestTesting/jumps.asm | 56 ++++++ .../isoltestTesting/operations.asm | 53 ++++++ .../evmAssemblyTests/isoltestTesting/push.asm | 35 ++++ .../isoltestTesting/smoke_plain.asm | 16 ++ test/tools/CMakeLists.txt | 1 + test/tools/isoltest.cpp | 2 +- 13 files changed, 497 insertions(+), 8 deletions(-) create mode 100644 test/libevmasm/PlainAssemblyParser.cpp create mode 100644 test/libevmasm/PlainAssemblyParser.h create mode 100644 test/libevmasm/evmAssemblyTests/isoltestTesting/comments.asm create mode 100644 test/libevmasm/evmAssemblyTests/isoltestTesting/jumps.asm create mode 100644 test/libevmasm/evmAssemblyTests/isoltestTesting/operations.asm create mode 100644 test/libevmasm/evmAssemblyTests/isoltestTesting/push.asm create mode 100644 test/libevmasm/evmAssemblyTests/isoltestTesting/smoke_plain.asm diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 6f48b8a8469e..c66963c190d4 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -54,6 +54,8 @@ set(libevmasm_sources libevmasm/EVMAssemblyTest.cpp libevmasm/EVMAssemblyTest.h libevmasm/Optimiser.cpp + libevmasm/PlainAssemblyParser.cpp + libevmasm/PlainAssemblyParser.h ) detect_stray_source_files("${libevmasm_sources}" "libevmasm/") diff --git a/test/TestCase.cpp b/test/TestCase.cpp index 8a8d2451d1f2..efc455ff6ff1 100644 --- a/test/TestCase.cpp +++ b/test/TestCase.cpp @@ -52,7 +52,7 @@ bool TestCase::isTestFilename(boost::filesystem::path const& _filename) { std::string extension = _filename.extension().string(); // NOTE: .asmjson rather than .json because JSON files that do not represent test cases exist in some test dirs. - return (extension == ".sol" || extension == ".yul" || extension == ".asmjson" || extension == ".stack") && + return (extension == ".sol" || extension == ".yul" || extension == ".asm" || extension == ".asmjson" || extension == ".stack") && !_filename.string().starts_with('~') && !_filename.string().starts_with('.'); } diff --git a/test/libevmasm/EVMAssemblyTest.cpp b/test/libevmasm/EVMAssemblyTest.cpp index b497c51476e6..0c1dbb07ed7c 100644 --- a/test/libevmasm/EVMAssemblyTest.cpp +++ b/test/libevmasm/EVMAssemblyTest.cpp @@ -17,6 +17,8 @@ #include +#include + #include #include @@ -39,6 +41,7 @@ using namespace solidity::langutil; using namespace solidity::util; std::vector const EVMAssemblyTest::c_outputLabels = { + "InputAssemblyJSON", "Assembly", "Bytecode", "Opcodes", @@ -56,8 +59,12 @@ EVMAssemblyTest::EVMAssemblyTest(std::string const& _filename): m_source = m_reader.source(); m_expectation = m_reader.simpleExpectations(); - if (!_filename.ends_with(".asmjson")) - BOOST_THROW_EXCEPTION(std::runtime_error("Not an assembly test: \"" + _filename + "\". Allowed extensions: .asmjson.")); + if (_filename.ends_with(".asmjson")) + m_assemblyFormat = AssemblyFormat::JSON; + else if (_filename.ends_with(".asm")) + m_assemblyFormat = AssemblyFormat::Plain; + else + BOOST_THROW_EXCEPTION(std::runtime_error("Not an assembly test: \"" + _filename + "\". Allowed extensions: .asm, .asmjson.")); m_selectedOutputs = m_reader.stringSetting("outputs", "Assembly,Bytecode,Opcodes,SourceMappings"); OptimisationPreset optimizationPreset = m_reader.enumSetting( @@ -101,9 +108,23 @@ TestCase::TestResult EVMAssemblyTest::run(std::ostream& _stream, std::string con evmAssemblyStack.selectDebugInfo(DebugInfoSelection::AllExceptExperimental()); + std::string assemblyJSON; + switch (m_assemblyFormat) + { + case AssemblyFormat::JSON: + assemblyJSON = m_source; + break; + case AssemblyFormat::Plain: + assemblyJSON = jsonPrint( + PlainAssemblyParser{}.parse(m_reader.fileName().filename().string(), m_source), + {JsonFormat::Pretty, 4} + ); + break; + } + try { - evmAssemblyStack.parseAndAnalyze(m_reader.fileName().filename().string(), m_source); + evmAssemblyStack.parseAndAnalyze(m_reader.fileName().filename().string(), assemblyJSON); } catch (AssemblyImportException const& _exception) { @@ -125,6 +146,8 @@ TestCase::TestResult EVMAssemblyTest::run(std::ostream& _stream, std::string con soltestAssert(evmAssemblyStack.compilationSuccessful()); auto const produceOutput = [&](std::string const& _output) { + if (_output == "InputAssemblyJSON") + return assemblyJSON; if (_output == "Assembly") return evmAssemblyStack.assemblyString({{m_reader.fileName().filename().string(), m_source}}); if (_output == "Bytecode") diff --git a/test/libevmasm/EVMAssemblyTest.h b/test/libevmasm/EVMAssemblyTest.h index f8923c0dc1a1..9059fd716d81 100644 --- a/test/libevmasm/EVMAssemblyTest.h +++ b/test/libevmasm/EVMAssemblyTest.h @@ -31,14 +31,17 @@ namespace solidity::evmasm::test { /// Custom test case that runs the final part of the compiler pipeline (assembling into bytecode). -/// Supports assembly JSON format produced by --asm-json. +/// Supports two kinds of input (depending on file extension): +/// - .asmjson: assembly JSON format produced by --asm-json. +/// - .asm: plain assembly, a more limited but human-readable format that is internally converted +/// to assembly JSON. /// /// Available settings: /// - EVMVersion: The range of EVM versions to run the test for. Inherited from EVMVersionRestrictedTestCase. /// - bytecodeFormat: The range of bytecode formats (EOF/legacy) to run the test for. Inherited from EVMVersionRestrictedTestCase. /// - outputs: List of outputs to include in the test. The order of values does NOT determine the order -/// in which the outputs are printed. Supported outputs: Assembly, Bytecode, Opcodes, SourceMappings. -/// The default is to print all outputs. +/// in which the outputs are printed. Supported outputs: InputAssemblyJSON, Assembly, Bytecode, Opcodes, SourceMappings. +/// The default is to print all outputs except InputAssemblyJSON. /// - optimizationPreset: Preset to load as the base optimizer settings. /// One of: none, minimal, standard, full. The default is none. /// - optimizer.*: A set of detailed optimizer settings applied on top of the base preset. @@ -61,8 +64,15 @@ class EVMAssemblyTest: public frontend::test::EVMVersionRestrictedTestCase TestResult run(std::ostream& _stream, std::string const& _linePrefix = "", bool const _formatted = false) override; private: + enum class AssemblyFormat + { + JSON, + Plain, + }; + static std::vector const c_outputLabels; + AssemblyFormat m_assemblyFormat{}; std::string m_selectedOutputs; evmasm::Assembly::OptimiserSettings m_optimizerSettings; }; diff --git a/test/libevmasm/PlainAssemblyParser.cpp b/test/libevmasm/PlainAssemblyParser.cpp new file mode 100644 index 000000000000..0fb9d62c8c10 --- /dev/null +++ b/test/libevmasm/PlainAssemblyParser.cpp @@ -0,0 +1,180 @@ +/* + This file is part of solidity. + + solidity is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + solidity is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with solidity. If not, see . +*/ + +#include + +#include +#include + +#include + +#include + +#include + +#include + +#include + +using namespace std::string_literals; +using namespace solidity; +using namespace solidity::test; +using namespace solidity::evmasm; +using namespace solidity::evmasm::test; +using namespace solidity::langutil; + +Json PlainAssemblyParser::parse(std::string _sourceName, std::string const& _source) +{ + m_sourceName = std::move(_sourceName); + Json codeJSON = Json::array(); + std::istringstream sourceStream(_source); + while (getline(sourceStream, m_line)) + { + advanceLine(m_line); + if (m_lineTokens.empty()) + continue; + + if (c_instructions.contains(currentToken().value)) + { + expectNoMoreArguments(); + codeJSON.push_back({{"name", currentToken().value}}); + } + else if (currentToken().value == "PUSH") + { + if (hasMoreTokens() && nextToken().value == "[tag]") + { + advanceToken(); + std::string_view tagID = expectArgument(); + expectNoMoreArguments(); + codeJSON.push_back({{"name", "PUSH [tag]"}, {"value", tagID}}); + } + else + { + std::string_view immediateArgument = expectArgument(); + expectNoMoreArguments(); + + if (!immediateArgument.starts_with("0x")) + BOOST_THROW_EXCEPTION(std::runtime_error(formatError("The immediate argument to PUSH must be a hex number prefixed with '0x'."))); + + immediateArgument.remove_prefix("0x"s.size()); + codeJSON.push_back({{"name", "PUSH"}, {"value", immediateArgument}}); + } + } + else if (currentToken().value == "tag") + { + std::string_view tagID = expectArgument(); + expectNoMoreArguments(); + + codeJSON.push_back({{"name", "tag"}, {"value", tagID}}); + codeJSON.push_back({{"name", "JUMPDEST"}}); + } + else + BOOST_THROW_EXCEPTION(std::runtime_error(formatError("Unknown instruction."))); + } + return {{".code", codeJSON}}; +} + +PlainAssemblyParser::Token const& PlainAssemblyParser::currentToken() const +{ + soltestAssert(m_tokenIndex < m_lineTokens.size()); + return m_lineTokens[m_tokenIndex]; +} + +PlainAssemblyParser::Token const& PlainAssemblyParser::nextToken() const +{ + soltestAssert(m_tokenIndex + 1 < m_lineTokens.size()); + return m_lineTokens[m_tokenIndex + 1]; +} + +bool PlainAssemblyParser::advanceToken() +{ + if (!hasMoreTokens()) + return false; + + ++m_tokenIndex; + return true; +} + +std::string_view PlainAssemblyParser::expectArgument() +{ + bool hasArgument = advanceToken(); + if (!hasArgument) + BOOST_THROW_EXCEPTION(std::runtime_error(formatError("Missing argument(s)."))); + + return currentToken().value; +} + +void PlainAssemblyParser::expectNoMoreArguments() +{ + bool hasArgument = advanceToken(); + if (hasArgument) + BOOST_THROW_EXCEPTION(std::runtime_error(formatError("Too many arguments."))); +} + +void PlainAssemblyParser::advanceLine(std::string_view _line) +{ + ++m_lineNumber; + m_line = _line; + m_lineTokens = tokenizeLine(m_line); + m_tokenIndex = 0; +} + +std::vector PlainAssemblyParser::tokenizeLine(std::string_view _line) +{ + auto const notWhiteSpace = [](char _c) { return !isWhiteSpace(_c); }; + + std::vector tokens; + auto tokenLocation = boost::find_token(_line, notWhiteSpace, boost::token_compress_on); + while (!tokenLocation.empty()) + { + std::string_view value{tokenLocation.begin(), tokenLocation.end()}; + if (value.starts_with("//")) + break; + + tokens.push_back({ + .value = value, + .position = static_cast(std::distance(_line.begin(), tokenLocation.begin())), + }); + soltestAssert(!value.empty()); + soltestAssert(tokens.back().position < _line.size()); + soltestAssert(tokens.back().position + value.size() <= _line.size()); + + std::string_view tail{tokenLocation.end(), _line.end()}; + tokenLocation = boost::find_token(tail, notWhiteSpace, boost::token_compress_on); + } + + return tokens; +} + +std::string PlainAssemblyParser::formatError(std::string_view _message) const +{ + std::string lineNumberString = std::to_string(m_lineNumber); + std::string padding(lineNumberString.size(), ' '); + std::string underline = std::string(currentToken().position, ' ') + std::string(currentToken().value.size(), '^'); + return fmt::format( + "Error while parsing plain assembly: {}\n" + "{}--> {}\n" + "{} | \n" + "{} | {}\n" + "{} | {}\n", + _message, + padding, m_sourceName, + padding, + m_lineNumber, m_line, + padding, underline + ); +} diff --git a/test/libevmasm/PlainAssemblyParser.h b/test/libevmasm/PlainAssemblyParser.h new file mode 100644 index 000000000000..0154af5f7f19 --- /dev/null +++ b/test/libevmasm/PlainAssemblyParser.h @@ -0,0 +1,79 @@ +/* + This file is part of solidity. + + solidity is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + solidity is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with solidity. If not, see . +*/ +// SPDX-License-Identifier: GPL-3.0 + +#pragma once + +#include + +#include +#include +#include + +namespace solidity::evmasm::test +{ + +/// Parser for the plain assembly format. The format is meant to be good enough for humans to read +/// while being straightforward to map to the assembly JSON format that solc can import. +/// +/// Syntax: +/// - Every line consists of zero or more whitespace-separated tokens. +/// - A token that begins with `//` starts a comment, which extends to the end of the line. +/// - A non-empty line represents a single assembly item. +/// - The name of the item is the first thing on the line and may consist of one or more tokens. +/// - One or more arguments follow the name. +/// +/// Supported items: +/// - All instruction names. +/// - PUSH +/// - PUSH [tag] +/// - tag +class PlainAssemblyParser +{ +public: + /// Parses plain assembly format and returns the equivalent assembly JSON. + /// Errors are reported by throwing runtime_error. + Json parse(std::string _sourceName, std::string const& _source); + +protected: + struct Token + { + std::string_view value; ///< Substring of m_line that represents a complete token. + size_t position; ///< Position of the first character of the token within m_line. + }; + + Token const& currentToken() const; + Token const& nextToken() const; + bool hasMoreTokens() const { return m_tokenIndex + 1 < m_lineTokens.size(); } + + bool advanceToken(); + std::string_view expectArgument(); + void expectNoMoreArguments(); + void advanceLine(std::string_view _line); + + static std::vector tokenizeLine(std::string_view _line); + std::string formatError(std::string_view _message) const; + +private: + std::string m_sourceName; ///< Name of the file the source comes from. + size_t m_lineNumber = 0; ///< The number of the current line within the source, 1-based. + std::string m_line; ///< The current line, unparsed. + std::vector m_lineTokens; ///< Decomposition of the current line into tokens (does not include comments). + size_t m_tokenIndex = 0; ///< Points at a token within m_lineTokens. +}; + +} diff --git a/test/libevmasm/evmAssemblyTests/isoltestTesting/comments.asm b/test/libevmasm/evmAssemblyTests/isoltestTesting/comments.asm new file mode 100644 index 000000000000..13dca3ad1b2f --- /dev/null +++ b/test/libevmasm/evmAssemblyTests/isoltestTesting/comments.asm @@ -0,0 +1,34 @@ +// +//// comment + // comment +CALLVALUE // 0xff +CALLVALUE //0xff + +PUSH 0xff // comment // //0xff +// + +// +// ==== +// outputs: InputAssemblyJSON,Assembly,Bytecode,Opcodes,SourceMappings +// ---- +// InputAssemblyJSON: { +// ".code": [ +// { +// "name": "CALLVALUE" +// }, +// { +// "name": "CALLVALUE" +// }, +// { +// "name": "PUSH", +// "value": "ff" +// } +// ] +// } +// Assembly: +// callvalue +// callvalue +// 0xff +// Bytecode: 343460ff +// Opcodes: CALLVALUE CALLVALUE PUSH1 0xFF +// SourceMappings: :::-:0;; diff --git a/test/libevmasm/evmAssemblyTests/isoltestTesting/jumps.asm b/test/libevmasm/evmAssemblyTests/isoltestTesting/jumps.asm new file mode 100644 index 000000000000..be92671d8141 --- /dev/null +++ b/test/libevmasm/evmAssemblyTests/isoltestTesting/jumps.asm @@ -0,0 +1,56 @@ +PUSH [tag] 1 +JUMP +tag 1 +PUSH 0x01 +JUMPI +PUSH [tag] 0x012AB +tag 0x012AB +// ==== +// outputs: InputAssemblyJSON,Assembly,Bytecode,Opcodes,SourceMappings +// ---- +// InputAssemblyJSON: { +// ".code": [ +// { +// "name": "PUSH [tag]", +// "value": "1" +// }, +// { +// "name": "JUMP" +// }, +// { +// "name": "tag", +// "value": "1" +// }, +// { +// "name": "JUMPDEST" +// }, +// { +// "name": "PUSH", +// "value": "01" +// }, +// { +// "name": "JUMPI" +// }, +// { +// "name": "PUSH [tag]", +// "value": "0x012AB" +// }, +// { +// "name": "tag", +// "value": "0x012AB" +// }, +// { +// "name": "JUMPDEST" +// } +// ] +// } +// Assembly: +// jump(tag_1) +// tag_1: +// 0x01 +// jumpi +// tag_4779 +// tag_4779: +// Bytecode: 6003565b60015760095b +// Opcodes: PUSH1 0x3 JUMP JUMPDEST PUSH1 0x1 JUMPI PUSH1 0x9 JUMPDEST +// SourceMappings: :::-:0;;;;;; diff --git a/test/libevmasm/evmAssemblyTests/isoltestTesting/operations.asm b/test/libevmasm/evmAssemblyTests/isoltestTesting/operations.asm new file mode 100644 index 000000000000..923b0a6b1f37 --- /dev/null +++ b/test/libevmasm/evmAssemblyTests/isoltestTesting/operations.asm @@ -0,0 +1,53 @@ +NUMBER +SLOAD +ADDRESS +ORIGIN +ADD +DUP1 +SWAP1 +MSTORE8 +STOP +// ==== +// outputs: InputAssemblyJSON,Assembly,Bytecode,Opcodes,SourceMappings +// ---- +// InputAssemblyJSON: { +// ".code": [ +// { +// "name": "NUMBER" +// }, +// { +// "name": "SLOAD" +// }, +// { +// "name": "ADDRESS" +// }, +// { +// "name": "ORIGIN" +// }, +// { +// "name": "ADD" +// }, +// { +// "name": "DUP1" +// }, +// { +// "name": "SWAP1" +// }, +// { +// "name": "MSTORE8" +// }, +// { +// "name": "STOP" +// } +// ] +// } +// Assembly: +// sload(number) +// add(origin, address) +// dup1 +// swap1 +// mstore8 +// stop +// Bytecode: 435430320180905300 +// Opcodes: NUMBER SLOAD ADDRESS ORIGIN ADD DUP1 SWAP1 MSTORE8 STOP +// SourceMappings: :::-:0;;;;;;;; diff --git a/test/libevmasm/evmAssemblyTests/isoltestTesting/push.asm b/test/libevmasm/evmAssemblyTests/isoltestTesting/push.asm new file mode 100644 index 000000000000..51bc160507c7 --- /dev/null +++ b/test/libevmasm/evmAssemblyTests/isoltestTesting/push.asm @@ -0,0 +1,35 @@ +PUSH 0x0 +PUSH 0x1 +PUSH 0x0123456789ABCDEF +PUSH 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +// ==== +// outputs: InputAssemblyJSON,Assembly,Bytecode,Opcodes,SourceMappings +// ---- +// InputAssemblyJSON: { +// ".code": [ +// { +// "name": "PUSH", +// "value": "0" +// }, +// { +// "name": "PUSH", +// "value": "1" +// }, +// { +// "name": "PUSH", +// "value": "0123456789ABCDEF" +// }, +// { +// "name": "PUSH", +// "value": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" +// } +// ] +// } +// Assembly: +// 0x00 +// 0x01 +// 0x0123456789abcdef +// 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +// Bytecode: 5f6001670123456789abcdef7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +// Opcodes: PUSH0 PUSH1 0x1 PUSH8 0x123456789ABCDEF PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +// SourceMappings: :::-:0;;; diff --git a/test/libevmasm/evmAssemblyTests/isoltestTesting/smoke_plain.asm b/test/libevmasm/evmAssemblyTests/isoltestTesting/smoke_plain.asm new file mode 100644 index 000000000000..a1714241fb86 --- /dev/null +++ b/test/libevmasm/evmAssemblyTests/isoltestTesting/smoke_plain.asm @@ -0,0 +1,16 @@ +CALLVALUE +// ==== +// outputs: InputAssemblyJSON,Assembly,Bytecode,Opcodes,SourceMappings +// ---- +// InputAssemblyJSON: { +// ".code": [ +// { +// "name": "CALLVALUE" +// } +// ] +// } +// Assembly: +// callvalue +// Bytecode: 34 +// Opcodes: CALLVALUE +// SourceMappings: :::-:0 diff --git a/test/tools/CMakeLists.txt b/test/tools/CMakeLists.txt index 13018bf18512..289f2f2def35 100644 --- a/test/tools/CMakeLists.txt +++ b/test/tools/CMakeLists.txt @@ -19,6 +19,7 @@ add_executable(isoltest ../TestCase.cpp ../TestCaseReader.cpp ../libevmasm/EVMAssemblyTest.cpp + ../libevmasm/PlainAssemblyParser.cpp ../libsolidity/util/BytesUtils.cpp ../libsolidity/util/Common.cpp ../libsolidity/util/ContractABIUtils.cpp diff --git a/test/tools/isoltest.cpp b/test/tools/isoltest.cpp index 32309b005507..26efc089020b 100644 --- a/test/tools/isoltest.cpp +++ b/test/tools/isoltest.cpp @@ -75,7 +75,7 @@ class TestFilter boost::replace_all(filter, "/", "\\/"); boost::replace_all(filter, "*", ".*"); - m_filterExpression = std::regex{"(" + filter + "(\\.sol|\\.yul|\\.asmjson|\\.stack))"}; + m_filterExpression = std::regex{"(" + filter + "(\\.sol|\\.yul|\\.asm|\\.asmjson|\\.stack))"}; } bool matches(fs::path const& _path, std::string const& _name) const From 975ee1325833c6784adff85072c55c3ecf9439fc Mon Sep 17 00:00:00 2001 From: rodiazet Date: Wed, 9 Apr 2025 15:30:26 +0200 Subject: [PATCH 0945/1022] eof: Enable peephole optimizer for EOF. --- libevmasm/Assembly.cpp | 3 +- libevmasm/AssemblyItem.h | 2 +- libevmasm/PeepholeOptimiser.cpp | 12 ++++-- test/Common.cpp | 7 ++++ test/Common.h | 4 ++ test/libevmasm/Optimiser.cpp | 40 +++++++++++++++++++ .../objectCompiler/eof/256_subcontainers.yul | 8 ++-- 7 files changed, 65 insertions(+), 11 deletions(-) diff --git a/libevmasm/Assembly.cpp b/libevmasm/Assembly.cpp index a0711cd41756..9dd203a0f802 100644 --- a/libevmasm/Assembly.cpp +++ b/libevmasm/Assembly.cpp @@ -843,8 +843,7 @@ std::map const& Assembly::optimiseInternal( } } - // TODO: verify this for EOF. - if (_settings.runPeephole && !m_eofVersion.has_value()) + if (_settings.runPeephole) { for (auto& codeSection: m_codeSections) { diff --git a/libevmasm/AssemblyItem.h b/libevmasm/AssemblyItem.h index 8b65d77c91e9..0dfe0749768a 100644 --- a/libevmasm/AssemblyItem.h +++ b/libevmasm/AssemblyItem.h @@ -244,7 +244,7 @@ class AssemblyItem /// Shortcut that avoids constructing an AssemblyItem just to perform the comparison. bool operator==(Instruction _instr) const { - return type() == Operation && instruction() == _instr; + return hasInstruction() && instruction() == _instr; } bool operator!=(Instruction _instr) const { return !operator==(_instr); } diff --git a/libevmasm/PeepholeOptimiser.cpp b/libevmasm/PeepholeOptimiser.cpp index cc22db9fa2fd..267700e457cd 100644 --- a/libevmasm/PeepholeOptimiser.cpp +++ b/libevmasm/PeepholeOptimiser.cpp @@ -563,7 +563,9 @@ struct TruthyAnd: SimplePeepholeOptimizerMethod } }; -/// Removes everything after a JUMP (or similar) until the next JUMPDEST. +/// Removes everything after an non-continuing instruction until the next Tag. +/// Note: JUMPF can return but to the caller's parent call frame. +/// So it won't continue from the next to the JUMPF instruction struct UnreachableCode { static bool apply(OptimiserState& _state) @@ -572,14 +574,18 @@ struct UnreachableCode auto end = _state.items.end(); if (it == end) return false; + if ( it[0] != Instruction::JUMP && - it[0] != Instruction::RJUMP && it[0] != Instruction::RETURN && it[0] != Instruction::STOP && it[0] != Instruction::INVALID && it[0] != Instruction::SELFDESTRUCT && - it[0] != Instruction::REVERT + it[0] != Instruction::REVERT && + it[0] != Instruction::RJUMP && + it[0] != Instruction::JUMPF && + it[0] != Instruction::RETF && + it[0] != Instruction::RETURNCONTRACT ) return false; diff --git a/test/Common.cpp b/test/Common.cpp index d39c6db1ea9e..142afda22e9f 100644 --- a/test/Common.cpp +++ b/test/Common.cpp @@ -313,6 +313,13 @@ boost::unit_test::precondition::predicate_t nonEOF() }; } +boost::unit_test::precondition::predicate_t onEOF() +{ + return [](boost::unit_test::test_unit_id) { + return solidity::test::CommonOptions::get().eofVersion().has_value(); + }; +} + boost::unit_test::precondition::predicate_t minEVMVersionCheck(langutil::EVMVersion _minEVMVersion) { return [_minEVMVersion](boost::unit_test::test_unit_id) { diff --git a/test/Common.h b/test/Common.h index 27c2081346fc..e331c497a47f 100644 --- a/test/Common.h +++ b/test/Common.h @@ -116,6 +116,10 @@ boost::unit_test::precondition::predicate_t minEVMVersionCheck(langutil::EVMVers /// @return A predicate (function) that can be passed into @a boost::unit_test::precondition(). boost::unit_test::precondition::predicate_t nonEOF(); +/// Helper that can be used to skip tests when the legacy bytecode is not supported by the test case. +/// @return A predicate (function) that can be passed into @a boost::unit_test::precondition(). +boost::unit_test::precondition::predicate_t onEOF(); + bool loadVMs(CommonOptions const& _options); /** diff --git a/test/libevmasm/Optimiser.cpp b/test/libevmasm/Optimiser.cpp index f4b7034de544..4e344c174e00 100644 --- a/test/libevmasm/Optimiser.cpp +++ b/test/libevmasm/Optimiser.cpp @@ -1009,6 +1009,46 @@ BOOST_AUTO_TEST_CASE(clear_unreachable_code) ); } +BOOST_AUTO_TEST_CASE(clear_unreachable_code_eof, *boost::unit_test::precondition(onEOF())) +{ + for (auto const& blockTerminatingItem: + { + AssemblyItem::relativeJumpTo(AssemblyItem(Tag, 1)), + AssemblyItem::jumpToFunction(1, 0, 0), + AssemblyItem::functionReturn(), + AssemblyItem::returnContract(0), + } + ) + { + AssemblyItems items{ + blockTerminatingItem, + u256(0), + Instruction::SLOAD, + AssemblyItem(Tag, 2), + u256(5), + u256(6), + Instruction::SSTORE, + blockTerminatingItem, + u256(5), + u256(6) + }; + AssemblyItems expectation{ + blockTerminatingItem, + AssemblyItem(Tag, 2), + u256(5), + u256(6), + Instruction::SSTORE, + blockTerminatingItem, + }; + PeepholeOptimiser peepOpt(items, solidity::test::CommonOptions::get().evmVersion()); + BOOST_REQUIRE(peepOpt.optimise()); + BOOST_CHECK_EQUAL_COLLECTIONS( + items.begin(), items.end(), + expectation.begin(), expectation.end() + ); + } +} + BOOST_AUTO_TEST_CASE(deduplicateNextTagBlockSize3) { AssemblyItems items{ diff --git a/test/libyul/objectCompiler/eof/256_subcontainers.yul b/test/libyul/objectCompiler/eof/256_subcontainers.yul index fac0f7b5df29..9306dcbbdeb3 100644 --- a/test/libyul/objectCompiler/eof/256_subcontainers.yul +++ b/test/libyul/objectCompiler/eof/256_subcontainers.yul @@ -2823,8 +2823,6 @@ object "a" { // dup1 // eofcreate{255} // /* "source":12286:12321 */ -// pop -// /* "source":22:12337 */ // stop // stop // @@ -4107,6 +4105,6 @@ object "a" { // /* "source":24612:24619 */ // stop // } -// Bytecode: ef00010100040200010701030100001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001404000000008000045f808080ec00505f808080ec01505f808080ec02505f808080ec03505f808080ec04505f808080ec05505f808080ec06505f808080ec07505f808080ec08505f808080ec09505f808080ec0a505f808080ec0b505f808080ec0c505f808080ec0d505f808080ec0e505f808080ec0f505f808080ec10505f808080ec11505f808080ec12505f808080ec13505f808080ec14505f808080ec15505f808080ec16505f808080ec17505f808080ec18505f808080ec19505f808080ec1a505f808080ec1b505f808080ec1c505f808080ec1d505f808080ec1e505f808080ec1f505f808080ec20505f808080ec21505f808080ec22505f808080ec23505f808080ec24505f808080ec25505f808080ec26505f808080ec27505f808080ec28505f808080ec29505f808080ec2a505f808080ec2b505f808080ec2c505f808080ec2d505f808080ec2e505f808080ec2f505f808080ec30505f808080ec31505f808080ec32505f808080ec33505f808080ec34505f808080ec35505f808080ec36505f808080ec37505f808080ec38505f808080ec39505f808080ec3a505f808080ec3b505f808080ec3c505f808080ec3d505f808080ec3e505f808080ec3f505f808080ec40505f808080ec41505f808080ec42505f808080ec43505f808080ec44505f808080ec45505f808080ec46505f808080ec47505f808080ec48505f808080ec49505f808080ec4a505f808080ec4b505f808080ec4c505f808080ec4d505f808080ec4e505f808080ec4f505f808080ec50505f808080ec51505f808080ec52505f808080ec53505f808080ec54505f808080ec55505f808080ec56505f808080ec57505f808080ec58505f808080ec59505f808080ec5a505f808080ec5b505f808080ec5c505f808080ec5d505f808080ec5e505f808080ec5f505f808080ec60505f808080ec61505f808080ec62505f808080ec63505f808080ec64505f808080ec65505f808080ec66505f808080ec67505f808080ec68505f808080ec69505f808080ec6a505f808080ec6b505f808080ec6c505f808080ec6d505f808080ec6e505f808080ec6f505f808080ec70505f808080ec71505f808080ec72505f808080ec73505f808080ec74505f808080ec75505f808080ec76505f808080ec77505f808080ec78505f808080ec79505f808080ec7a505f808080ec7b505f808080ec7c505f808080ec7d505f808080ec7e505f808080ec7f505f808080ec80505f808080ec81505f808080ec82505f808080ec83505f808080ec84505f808080ec85505f808080ec86505f808080ec87505f808080ec88505f808080ec89505f808080ec8a505f808080ec8b505f808080ec8c505f808080ec8d505f808080ec8e505f808080ec8f505f808080ec90505f808080ec91505f808080ec92505f808080ec93505f808080ec94505f808080ec95505f808080ec96505f808080ec97505f808080ec98505f808080ec99505f808080ec9a505f808080ec9b505f808080ec9c505f808080ec9d505f808080ec9e505f808080ec9f505f808080eca0505f808080eca1505f808080eca2505f808080eca3505f808080eca4505f808080eca5505f808080eca6505f808080eca7505f808080eca8505f808080eca9505f808080ecaa505f808080ecab505f808080ecac505f808080ecad505f808080ecae505f808080ecaf505f808080ecb0505f808080ecb1505f808080ecb2505f808080ecb3505f808080ecb4505f808080ecb5505f808080ecb6505f808080ecb7505f808080ecb8505f808080ecb9505f808080ecba505f808080ecbb505f808080ecbc505f808080ecbd505f808080ecbe505f808080ecbf505f808080ecc0505f808080ecc1505f808080ecc2505f808080ecc3505f808080ecc4505f808080ecc5505f808080ecc6505f808080ecc7505f808080ecc8505f808080ecc9505f808080ecca505f808080eccb505f808080eccc505f808080eccd505f808080ecce505f808080eccf505f808080ecd0505f808080ecd1505f808080ecd2505f808080ecd3505f808080ecd4505f808080ecd5505f808080ecd6505f808080ecd7505f808080ecd8505f808080ecd9505f808080ecda505f808080ecdb505f808080ecdc505f808080ecdd505f808080ecde505f808080ecdf505f808080ece0505f808080ece1505f808080ece2505f808080ece3505f808080ece4505f808080ece5505f808080ece6505f808080ece7505f808080ece8505f808080ece9505f808080ecea505f808080eceb505f808080ecec505f808080eced505f808080ecee505f808080ecef505f808080ecf0505f808080ecf1505f808080ecf2505f808080ecf3505f808080ecf4505f808080ecf5505f808080ecf6505f808080ecf7505f808080ecf8505f808080ecf9505f808080ecfa505f808080ecfb505f808080ecfc505f808080ecfd505f808080ecfe505f808080ecff5000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000 -// Opcodes: 0xEF STOP ADD ADD STOP DIV MUL STOP ADD SMOD ADD SUB ADD STOP STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ DIV STOP STOP STOP STOP DUP1 STOP DIV PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x0 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x1 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x2 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x3 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x4 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x5 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x6 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x7 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x8 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x9 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xA POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xB POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xC POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xD POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xE POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xF POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x10 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x11 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x12 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x13 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x14 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x15 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x16 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x17 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x18 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x19 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x1A POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x1B POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x1C POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x1D POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x1E POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x1F POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x20 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x21 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x22 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x23 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x24 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x25 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x26 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x27 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x28 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x29 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x2A POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x2B POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x2C POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x2D POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x2E POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x2F POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x30 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x31 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x32 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x33 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x34 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x35 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x36 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x37 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x38 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x39 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x3A POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x3B POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x3C POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x3D POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x3E POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x3F POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x40 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x41 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x42 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x43 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x44 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x45 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x46 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x47 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x48 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x49 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x4A POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x4B POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x4C POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x4D POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x4E POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x4F POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x50 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x51 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x52 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x53 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x54 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x55 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x56 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x57 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x58 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x59 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x5A POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x5B POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x5C POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x5D POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x5E POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x5F POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x60 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x61 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x62 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x63 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x64 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x65 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x66 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x67 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x68 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x69 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x6A POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x6B POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x6C POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x6D POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x6E POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x6F POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x70 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x71 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x72 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x73 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x74 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x75 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x76 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x77 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x78 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x79 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x7A POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x7B POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x7C POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x7D POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x7E POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x7F POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x80 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x81 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x82 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x83 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x84 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x85 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x86 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x87 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x88 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x89 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x8A POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x8B POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x8C POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x8D POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x8E POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x8F POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x90 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x91 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x92 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x93 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x94 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x95 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x96 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x97 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x98 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x99 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x9A POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x9B POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x9C POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x9D POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x9E POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x9F POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xA0 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xA1 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xA2 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xA3 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xA4 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xA5 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xA6 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xA7 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xA8 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xA9 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xAA POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xAB POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xAC POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xAD POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xAE POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xAF POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xB0 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xB1 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xB2 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xB3 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xB4 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xB5 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xB6 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xB7 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xB8 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xB9 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xBA POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xBB POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xBC POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xBD POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xBE POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xBF POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xC0 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xC1 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xC2 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xC3 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xC4 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xC5 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xC6 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xC7 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xC8 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xC9 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xCA POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xCB POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xCC POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xCD POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xCE POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xCF POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xD0 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xD1 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xD2 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xD3 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xD4 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xD5 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xD6 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xD7 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xD8 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xD9 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xDA POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xDB POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xDC POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xDD POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xDE POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xDF POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xE0 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xE1 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xE2 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xE3 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xE4 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xE5 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xE6 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xE7 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xE8 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xE9 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xEA POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xEB POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xEC POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xED POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xEE POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xEF POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xF0 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xF1 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xF2 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xF3 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xF4 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xF5 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xF6 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xF7 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xF8 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xF9 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xFA POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xFB POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xFC POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xFD POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xFE POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xFF POP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP -// SourceMappings: 78:1:0:-:0;50:30;;;;46:35;126:1;98:30;;;;94:35;174:1;146:30;;;;142:35;222:1;194:30;;;;190:35;270:1;242:30;;;;238:35;318:1;290:30;;;;286:35;366:1;338:30;;;;334:35;414:1;386:30;;;;382:35;462:1;434:30;;;;430:35;510:1;482:30;;;;478:35;558:1;530:30;;;;526:35;606:1;578:30;;;;574:35;654:1;626:30;;;;622:35;702:1;674:30;;;;670:35;750:1;722:30;;;;718:35;798:1;770:30;;;;766:35;846:1;818:30;;;;814:35;894:1;866:30;;;;862:35;942:1;914:30;;;;910:35;990:1;962:30;;;;958:35;1038:1;1010:30;;;;1006:35;1086:1;1058:30;;;;1054:35;1134:1;1106:30;;;;1102:35;1182:1;1154:30;;;;1150:35;1230:1;1202:30;;;;1198:35;1278:1;1250:30;;;;1246:35;1326:1;1298:30;;;;1294:35;1374:1;1346:30;;;;1342:35;1422:1;1394:30;;;;1390:35;1470:1;1442:30;;;;1438:35;1518:1;1490:30;;;;1486:35;1566:1;1538:30;;;;1534:35;1614:1;1586:30;;;;1582:35;1662:1;1634:30;;;;1630:35;1710:1;1682:30;;;;1678:35;1758:1;1730:30;;;;1726:35;1806:1;1778:30;;;;1774:35;1854:1;1826:30;;;;1822:35;1902:1;1874:30;;;;1870:35;1950:1;1922:30;;;;1918:35;1998:1;1970:30;;;;1966:35;2046:1;2018:30;;;;2014:35;2094:1;2066:30;;;;2062:35;2142:1;2114:30;;;;2110:35;2190:1;2162:30;;;;2158:35;2238:1;2210:30;;;;2206:35;2286:1;2258:30;;;;2254:35;2334:1;2306:30;;;;2302:35;2382:1;2354:30;;;;2350:35;2430:1;2402:30;;;;2398:35;2478:1;2450:30;;;;2446:35;2526:1;2498:30;;;;2494:35;2574:1;2546:30;;;;2542:35;2622:1;2594:30;;;;2590:35;2670:1;2642:30;;;;2638:35;2718:1;2690:30;;;;2686:35;2766:1;2738:30;;;;2734:35;2814:1;2786:30;;;;2782:35;2862:1;2834:30;;;;2830:35;2910:1;2882:30;;;;2878:35;2958:1;2930:30;;;;2926:35;3006:1;2978:30;;;;2974:35;3054:1;3026:30;;;;3022:35;3102:1;3074:30;;;;3070:35;3150:1;3122:30;;;;3118:35;3198:1;3170:30;;;;3166:35;3246:1;3218:30;;;;3214:35;3294:1;3266:30;;;;3262:35;3342:1;3314:30;;;;3310:35;3390:1;3362:30;;;;3358:35;3438:1;3410:30;;;;3406:35;3486:1;3458:30;;;;3454:35;3534:1;3506:30;;;;3502:35;3582:1;3554:30;;;;3550:35;3630:1;3602:30;;;;3598:35;3678:1;3650:30;;;;3646:35;3726:1;3698:30;;;;3694:35;3774:1;3746:30;;;;3742:35;3822:1;3794:30;;;;3790:35;3870:1;3842:30;;;;3838:35;3918:1;3890:30;;;;3886:35;3966:1;3938:30;;;;3934:35;4014:1;3986:30;;;;3982:35;4062:1;4034:30;;;;4030:35;4110:1;4082:30;;;;4078:35;4158:1;4130:30;;;;4126:35;4206:1;4178:30;;;;4174:35;4254:1;4226:30;;;;4222:35;4302:1;4274:30;;;;4270:35;4350:1;4322:30;;;;4318:35;4398:1;4370:30;;;;4366:35;4446:1;4418:30;;;;4414:35;4494:1;4466:30;;;;4462:35;4542:1;4514:30;;;;4510:35;4590:1;4562:30;;;;4558:35;4638:1;4610:30;;;;4606:35;4686:1;4658:30;;;;4654:35;4734:1;4706:30;;;;4702:35;4782:1;4754:30;;;;4750:35;4830:1;4802:30;;;;4798:35;4878:1;4850:30;;;;4846:35;4926:1;4898:30;;;;4894:35;4974:1;4946:30;;;;4942:35;5022:1;4994:30;;;;4990:35;5070:1;5042:30;;;;5038:35;5118:1;5090:30;;;;5086:35;5166:1;5138:30;;;;5134:35;5214:1;5186:30;;;;5182:35;5262:1;5234:30;;;;5230:35;5310:1;5282:30;;;;5278:35;5358:1;5330:30;;;;5326:35;5406:1;5378:30;;;;5374:35;5454:1;5426:30;;;;5422:35;5502:1;5474:30;;;;5470:35;5550:1;5522:30;;;;5518:35;5598:1;5570:30;;;;5566:35;5646:1;5618:30;;;;5614:35;5694:1;5666:30;;;;5662:35;5742:1;5714:30;;;;5710:35;5790:1;5762:30;;;;5758:35;5838:1;5810:30;;;;5806:35;5886:1;5858:30;;;;5854:35;5934:1;5906:30;;;;5902:35;5982:1;5954:30;;;;5950:35;6030:1;6002:30;;;;5998:35;6078:1;6050:30;;;;6046:35;6126:1;6098:30;;;;6094:35;6174:1;6146:30;;;;6142:35;6222:1;6194:30;;;;6190:35;6270:1;6242:30;;;;6238:35;6318:1;6290:30;;;;6286:35;6366:1;6338:30;;;;6334:35;6414:1;6386:30;;;;6382:35;6462:1;6434:30;;;;6430:35;6510:1;6482:30;;;;6478:35;6558:1;6530:30;;;;6526:35;6606:1;6578:30;;;;6574:35;6654:1;6626:30;;;;6622:35;6702:1;6674:30;;;;6670:35;6750:1;6722:30;;;;6718:35;6798:1;6770:30;;;;6766:35;6846:1;6818:30;;;;6814:35;6894:1;6866:30;;;;6862:35;6942:1;6914:30;;;;6910:35;6990:1;6962:30;;;;6958:35;7038:1;7010:30;;;;7006:35;7086:1;7058:30;;;;7054:35;7134:1;7106:30;;;;7102:35;7182:1;7154:30;;;;7150:35;7230:1;7202:30;;;;7198:35;7278:1;7250:30;;;;7246:35;7326:1;7298:30;;;;7294:35;7374:1;7346:30;;;;7342:35;7422:1;7394:30;;;;7390:35;7470:1;7442:30;;;;7438:35;7518:1;7490:30;;;;7486:35;7566:1;7538:30;;;;7534:35;7614:1;7586:30;;;;7582:35;7662:1;7634:30;;;;7630:35;7710:1;7682:30;;;;7678:35;7758:1;7730:30;;;;7726:35;7806:1;7778:30;;;;7774:35;7854:1;7826:30;;;;7822:35;7902:1;7874:30;;;;7870:35;7950:1;7922:30;;;;7918:35;7998:1;7970:30;;;;7966:35;8046:1;8018:30;;;;8014:35;8094:1;8066:30;;;;8062:35;8142:1;8114:30;;;;8110:35;8190:1;8162:30;;;;8158:35;8238:1;8210:30;;;;8206:35;8286:1;8258:30;;;;8254:35;8334:1;8306:30;;;;8302:35;8382:1;8354:30;;;;8350:35;8430:1;8402:30;;;;8398:35;8478:1;8450:30;;;;8446:35;8526:1;8498:30;;;;8494:35;8574:1;8546:30;;;;8542:35;8622:1;8594:30;;;;8590:35;8670:1;8642:30;;;;8638:35;8718:1;8690:30;;;;8686:35;8766:1;8738:30;;;;8734:35;8814:1;8786:30;;;;8782:35;8862:1;8834:30;;;;8830:35;8910:1;8882:30;;;;8878:35;8958:1;8930:30;;;;8926:35;9006:1;8978:30;;;;8974:35;9054:1;9026:30;;;;9022:35;9102:1;9074:30;;;;9070:35;9150:1;9122:30;;;;9118:35;9198:1;9170:30;;;;9166:35;9246:1;9218:30;;;;9214:35;9294:1;9266:30;;;;9262:35;9342:1;9314:30;;;;9310:35;9390:1;9362:30;;;;9358:35;9438:1;9410:30;;;;9406:35;9486:1;9458:30;;;;9454:35;9534:1;9506:30;;;;9502:35;9582:1;9554:30;;;;9550:35;9630:1;9602:30;;;;9598:35;9678:1;9650:30;;;;9646:35;9726:1;9698:30;;;;9694:35;9774:1;9746:30;;;;9742:35;9822:1;9794:30;;;;9790:35;9870:1;9842:30;;;;9838:35;9918:1;9890:30;;;;9886:35;9966:1;9938:30;;;;9934:35;10014:1;9986:30;;;;9982:35;10062:1;10034:30;;;;10030:35;10110:1;10082:30;;;;10078:35;10158:1;10130:30;;;;10126:35;10206:1;10178:30;;;;10174:35;10254:1;10226:30;;;;10222:35;10302:1;10274:30;;;;10270:35;10350:1;10322:30;;;;10318:35;10398:1;10370:30;;;;10366:35;10446:1;10418:30;;;;10414:35;10494:1;10466:30;;;;10462:35;10542:1;10514:30;;;;10510:35;10590:1;10562:30;;;;10558:35;10638:1;10610:30;;;;10606:35;10686:1;10658:30;;;;10654:35;10734:1;10706:30;;;;10702:35;10782:1;10754:30;;;;10750:35;10830:1;10802:30;;;;10798:35;10878:1;10850:30;;;;10846:35;10926:1;10898:30;;;;10894:35;10974:1;10946:30;;;;10942:35;11022:1;10994:30;;;;10990:35;11070:1;11042:30;;;;11038:35;11118:1;11090:30;;;;11086:35;11166:1;11138:30;;;;11134:35;11214:1;11186:30;;;;11182:35;11262:1;11234:30;;;;11230:35;11310:1;11282:30;;;;11278:35;11358:1;11330:30;;;;11326:35;11406:1;11378:30;;;;11374:35;11454:1;11426:30;;;;11422:35;11502:1;11474:30;;;;11470:35;11550:1;11522:30;;;;11518:35;11598:1;11570:30;;;;11566:35;11646:1;11618:30;;;;11614:35;11694:1;11666:30;;;;11662:35;11742:1;11714:30;;;;11710:35;11790:1;11762:30;;;;11758:35;11838:1;11810:30;;;;11806:35;11886:1;11858:30;;;;11854:35;11934:1;11906:30;;;;11902:35;11982:1;11954:30;;;;11950:35;12030:1;12002:30;;;;11998:35;12078:1;12050:30;;;;12046:35;12126:1;12098:30;;;;12094:35;12174:1;12146:30;;;;12142:35;12222:1;12194:30;;;;12190:35;12270:1;12242:30;;;;12238:35;12318:1;12290:30;;;;12286:35;22:12315 +// Bytecode: ef00010100040200010700030100001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001404000000008000045f808080ec00505f808080ec01505f808080ec02505f808080ec03505f808080ec04505f808080ec05505f808080ec06505f808080ec07505f808080ec08505f808080ec09505f808080ec0a505f808080ec0b505f808080ec0c505f808080ec0d505f808080ec0e505f808080ec0f505f808080ec10505f808080ec11505f808080ec12505f808080ec13505f808080ec14505f808080ec15505f808080ec16505f808080ec17505f808080ec18505f808080ec19505f808080ec1a505f808080ec1b505f808080ec1c505f808080ec1d505f808080ec1e505f808080ec1f505f808080ec20505f808080ec21505f808080ec22505f808080ec23505f808080ec24505f808080ec25505f808080ec26505f808080ec27505f808080ec28505f808080ec29505f808080ec2a505f808080ec2b505f808080ec2c505f808080ec2d505f808080ec2e505f808080ec2f505f808080ec30505f808080ec31505f808080ec32505f808080ec33505f808080ec34505f808080ec35505f808080ec36505f808080ec37505f808080ec38505f808080ec39505f808080ec3a505f808080ec3b505f808080ec3c505f808080ec3d505f808080ec3e505f808080ec3f505f808080ec40505f808080ec41505f808080ec42505f808080ec43505f808080ec44505f808080ec45505f808080ec46505f808080ec47505f808080ec48505f808080ec49505f808080ec4a505f808080ec4b505f808080ec4c505f808080ec4d505f808080ec4e505f808080ec4f505f808080ec50505f808080ec51505f808080ec52505f808080ec53505f808080ec54505f808080ec55505f808080ec56505f808080ec57505f808080ec58505f808080ec59505f808080ec5a505f808080ec5b505f808080ec5c505f808080ec5d505f808080ec5e505f808080ec5f505f808080ec60505f808080ec61505f808080ec62505f808080ec63505f808080ec64505f808080ec65505f808080ec66505f808080ec67505f808080ec68505f808080ec69505f808080ec6a505f808080ec6b505f808080ec6c505f808080ec6d505f808080ec6e505f808080ec6f505f808080ec70505f808080ec71505f808080ec72505f808080ec73505f808080ec74505f808080ec75505f808080ec76505f808080ec77505f808080ec78505f808080ec79505f808080ec7a505f808080ec7b505f808080ec7c505f808080ec7d505f808080ec7e505f808080ec7f505f808080ec80505f808080ec81505f808080ec82505f808080ec83505f808080ec84505f808080ec85505f808080ec86505f808080ec87505f808080ec88505f808080ec89505f808080ec8a505f808080ec8b505f808080ec8c505f808080ec8d505f808080ec8e505f808080ec8f505f808080ec90505f808080ec91505f808080ec92505f808080ec93505f808080ec94505f808080ec95505f808080ec96505f808080ec97505f808080ec98505f808080ec99505f808080ec9a505f808080ec9b505f808080ec9c505f808080ec9d505f808080ec9e505f808080ec9f505f808080eca0505f808080eca1505f808080eca2505f808080eca3505f808080eca4505f808080eca5505f808080eca6505f808080eca7505f808080eca8505f808080eca9505f808080ecaa505f808080ecab505f808080ecac505f808080ecad505f808080ecae505f808080ecaf505f808080ecb0505f808080ecb1505f808080ecb2505f808080ecb3505f808080ecb4505f808080ecb5505f808080ecb6505f808080ecb7505f808080ecb8505f808080ecb9505f808080ecba505f808080ecbb505f808080ecbc505f808080ecbd505f808080ecbe505f808080ecbf505f808080ecc0505f808080ecc1505f808080ecc2505f808080ecc3505f808080ecc4505f808080ecc5505f808080ecc6505f808080ecc7505f808080ecc8505f808080ecc9505f808080ecca505f808080eccb505f808080eccc505f808080eccd505f808080ecce505f808080eccf505f808080ecd0505f808080ecd1505f808080ecd2505f808080ecd3505f808080ecd4505f808080ecd5505f808080ecd6505f808080ecd7505f808080ecd8505f808080ecd9505f808080ecda505f808080ecdb505f808080ecdc505f808080ecdd505f808080ecde505f808080ecdf505f808080ece0505f808080ece1505f808080ece2505f808080ece3505f808080ece4505f808080ece5505f808080ece6505f808080ece7505f808080ece8505f808080ece9505f808080ecea505f808080eceb505f808080ecec505f808080eced505f808080ecee505f808080ecef505f808080ecf0505f808080ecf1505f808080ecf2505f808080ecf3505f808080ecf4505f808080ecf5505f808080ecf6505f808080ecf7505f808080ecf8505f808080ecf9505f808080ecfa505f808080ecfb505f808080ecfc505f808080ecfd505f808080ecfe505f808080ecff00ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000ef00010100040200010001040000000080000000 +// Opcodes: 0xEF STOP ADD ADD STOP DIV MUL STOP ADD SMOD STOP SUB ADD STOP STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ STOP EQ DIV STOP STOP STOP STOP DUP1 STOP DIV PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x0 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x1 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x2 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x3 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x4 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x5 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x6 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x7 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x8 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x9 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xA POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xB POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xC POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xD POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xE POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xF POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x10 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x11 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x12 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x13 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x14 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x15 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x16 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x17 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x18 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x19 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x1A POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x1B POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x1C POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x1D POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x1E POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x1F POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x20 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x21 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x22 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x23 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x24 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x25 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x26 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x27 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x28 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x29 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x2A POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x2B POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x2C POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x2D POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x2E POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x2F POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x30 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x31 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x32 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x33 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x34 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x35 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x36 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x37 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x38 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x39 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x3A POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x3B POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x3C POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x3D POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x3E POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x3F POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x40 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x41 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x42 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x43 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x44 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x45 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x46 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x47 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x48 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x49 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x4A POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x4B POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x4C POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x4D POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x4E POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x4F POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x50 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x51 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x52 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x53 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x54 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x55 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x56 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x57 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x58 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x59 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x5A POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x5B POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x5C POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x5D POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x5E POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x5F POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x60 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x61 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x62 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x63 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x64 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x65 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x66 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x67 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x68 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x69 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x6A POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x6B POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x6C POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x6D POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x6E POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x6F POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x70 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x71 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x72 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x73 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x74 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x75 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x76 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x77 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x78 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x79 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x7A POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x7B POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x7C POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x7D POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x7E POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x7F POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x80 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x81 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x82 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x83 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x84 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x85 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x86 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x87 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x88 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x89 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x8A POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x8B POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x8C POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x8D POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x8E POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x8F POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x90 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x91 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x92 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x93 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x94 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x95 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x96 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x97 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x98 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x99 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x9A POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x9B POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x9C POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x9D POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x9E POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0x9F POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xA0 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xA1 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xA2 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xA3 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xA4 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xA5 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xA6 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xA7 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xA8 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xA9 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xAA POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xAB POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xAC POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xAD POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xAE POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xAF POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xB0 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xB1 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xB2 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xB3 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xB4 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xB5 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xB6 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xB7 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xB8 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xB9 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xBA POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xBB POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xBC POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xBD POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xBE POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xBF POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xC0 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xC1 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xC2 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xC3 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xC4 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xC5 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xC6 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xC7 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xC8 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xC9 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xCA POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xCB POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xCC POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xCD POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xCE POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xCF POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xD0 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xD1 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xD2 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xD3 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xD4 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xD5 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xD6 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xD7 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xD8 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xD9 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xDA POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xDB POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xDC POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xDD POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xDE POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xDF POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xE0 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xE1 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xE2 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xE3 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xE4 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xE5 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xE6 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xE7 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xE8 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xE9 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xEA POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xEB POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xEC POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xED POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xEE POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xEF POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xF0 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xF1 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xF2 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xF3 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xF4 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xF5 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xF6 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xF7 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xF8 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xF9 POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xFA POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xFB POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xFC POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xFD POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xFE POP PUSH0 DUP1 DUP1 DUP1 EOFCREATE 0xFF STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP ADD DIV STOP STOP STOP STOP DUP1 STOP STOP STOP +// SourceMappings: 78:1:0:-:0;50:30;;;;46:35;126:1;98:30;;;;94:35;174:1;146:30;;;;142:35;222:1;194:30;;;;190:35;270:1;242:30;;;;238:35;318:1;290:30;;;;286:35;366:1;338:30;;;;334:35;414:1;386:30;;;;382:35;462:1;434:30;;;;430:35;510:1;482:30;;;;478:35;558:1;530:30;;;;526:35;606:1;578:30;;;;574:35;654:1;626:30;;;;622:35;702:1;674:30;;;;670:35;750:1;722:30;;;;718:35;798:1;770:30;;;;766:35;846:1;818:30;;;;814:35;894:1;866:30;;;;862:35;942:1;914:30;;;;910:35;990:1;962:30;;;;958:35;1038:1;1010:30;;;;1006:35;1086:1;1058:30;;;;1054:35;1134:1;1106:30;;;;1102:35;1182:1;1154:30;;;;1150:35;1230:1;1202:30;;;;1198:35;1278:1;1250:30;;;;1246:35;1326:1;1298:30;;;;1294:35;1374:1;1346:30;;;;1342:35;1422:1;1394:30;;;;1390:35;1470:1;1442:30;;;;1438:35;1518:1;1490:30;;;;1486:35;1566:1;1538:30;;;;1534:35;1614:1;1586:30;;;;1582:35;1662:1;1634:30;;;;1630:35;1710:1;1682:30;;;;1678:35;1758:1;1730:30;;;;1726:35;1806:1;1778:30;;;;1774:35;1854:1;1826:30;;;;1822:35;1902:1;1874:30;;;;1870:35;1950:1;1922:30;;;;1918:35;1998:1;1970:30;;;;1966:35;2046:1;2018:30;;;;2014:35;2094:1;2066:30;;;;2062:35;2142:1;2114:30;;;;2110:35;2190:1;2162:30;;;;2158:35;2238:1;2210:30;;;;2206:35;2286:1;2258:30;;;;2254:35;2334:1;2306:30;;;;2302:35;2382:1;2354:30;;;;2350:35;2430:1;2402:30;;;;2398:35;2478:1;2450:30;;;;2446:35;2526:1;2498:30;;;;2494:35;2574:1;2546:30;;;;2542:35;2622:1;2594:30;;;;2590:35;2670:1;2642:30;;;;2638:35;2718:1;2690:30;;;;2686:35;2766:1;2738:30;;;;2734:35;2814:1;2786:30;;;;2782:35;2862:1;2834:30;;;;2830:35;2910:1;2882:30;;;;2878:35;2958:1;2930:30;;;;2926:35;3006:1;2978:30;;;;2974:35;3054:1;3026:30;;;;3022:35;3102:1;3074:30;;;;3070:35;3150:1;3122:30;;;;3118:35;3198:1;3170:30;;;;3166:35;3246:1;3218:30;;;;3214:35;3294:1;3266:30;;;;3262:35;3342:1;3314:30;;;;3310:35;3390:1;3362:30;;;;3358:35;3438:1;3410:30;;;;3406:35;3486:1;3458:30;;;;3454:35;3534:1;3506:30;;;;3502:35;3582:1;3554:30;;;;3550:35;3630:1;3602:30;;;;3598:35;3678:1;3650:30;;;;3646:35;3726:1;3698:30;;;;3694:35;3774:1;3746:30;;;;3742:35;3822:1;3794:30;;;;3790:35;3870:1;3842:30;;;;3838:35;3918:1;3890:30;;;;3886:35;3966:1;3938:30;;;;3934:35;4014:1;3986:30;;;;3982:35;4062:1;4034:30;;;;4030:35;4110:1;4082:30;;;;4078:35;4158:1;4130:30;;;;4126:35;4206:1;4178:30;;;;4174:35;4254:1;4226:30;;;;4222:35;4302:1;4274:30;;;;4270:35;4350:1;4322:30;;;;4318:35;4398:1;4370:30;;;;4366:35;4446:1;4418:30;;;;4414:35;4494:1;4466:30;;;;4462:35;4542:1;4514:30;;;;4510:35;4590:1;4562:30;;;;4558:35;4638:1;4610:30;;;;4606:35;4686:1;4658:30;;;;4654:35;4734:1;4706:30;;;;4702:35;4782:1;4754:30;;;;4750:35;4830:1;4802:30;;;;4798:35;4878:1;4850:30;;;;4846:35;4926:1;4898:30;;;;4894:35;4974:1;4946:30;;;;4942:35;5022:1;4994:30;;;;4990:35;5070:1;5042:30;;;;5038:35;5118:1;5090:30;;;;5086:35;5166:1;5138:30;;;;5134:35;5214:1;5186:30;;;;5182:35;5262:1;5234:30;;;;5230:35;5310:1;5282:30;;;;5278:35;5358:1;5330:30;;;;5326:35;5406:1;5378:30;;;;5374:35;5454:1;5426:30;;;;5422:35;5502:1;5474:30;;;;5470:35;5550:1;5522:30;;;;5518:35;5598:1;5570:30;;;;5566:35;5646:1;5618:30;;;;5614:35;5694:1;5666:30;;;;5662:35;5742:1;5714:30;;;;5710:35;5790:1;5762:30;;;;5758:35;5838:1;5810:30;;;;5806:35;5886:1;5858:30;;;;5854:35;5934:1;5906:30;;;;5902:35;5982:1;5954:30;;;;5950:35;6030:1;6002:30;;;;5998:35;6078:1;6050:30;;;;6046:35;6126:1;6098:30;;;;6094:35;6174:1;6146:30;;;;6142:35;6222:1;6194:30;;;;6190:35;6270:1;6242:30;;;;6238:35;6318:1;6290:30;;;;6286:35;6366:1;6338:30;;;;6334:35;6414:1;6386:30;;;;6382:35;6462:1;6434:30;;;;6430:35;6510:1;6482:30;;;;6478:35;6558:1;6530:30;;;;6526:35;6606:1;6578:30;;;;6574:35;6654:1;6626:30;;;;6622:35;6702:1;6674:30;;;;6670:35;6750:1;6722:30;;;;6718:35;6798:1;6770:30;;;;6766:35;6846:1;6818:30;;;;6814:35;6894:1;6866:30;;;;6862:35;6942:1;6914:30;;;;6910:35;6990:1;6962:30;;;;6958:35;7038:1;7010:30;;;;7006:35;7086:1;7058:30;;;;7054:35;7134:1;7106:30;;;;7102:35;7182:1;7154:30;;;;7150:35;7230:1;7202:30;;;;7198:35;7278:1;7250:30;;;;7246:35;7326:1;7298:30;;;;7294:35;7374:1;7346:30;;;;7342:35;7422:1;7394:30;;;;7390:35;7470:1;7442:30;;;;7438:35;7518:1;7490:30;;;;7486:35;7566:1;7538:30;;;;7534:35;7614:1;7586:30;;;;7582:35;7662:1;7634:30;;;;7630:35;7710:1;7682:30;;;;7678:35;7758:1;7730:30;;;;7726:35;7806:1;7778:30;;;;7774:35;7854:1;7826:30;;;;7822:35;7902:1;7874:30;;;;7870:35;7950:1;7922:30;;;;7918:35;7998:1;7970:30;;;;7966:35;8046:1;8018:30;;;;8014:35;8094:1;8066:30;;;;8062:35;8142:1;8114:30;;;;8110:35;8190:1;8162:30;;;;8158:35;8238:1;8210:30;;;;8206:35;8286:1;8258:30;;;;8254:35;8334:1;8306:30;;;;8302:35;8382:1;8354:30;;;;8350:35;8430:1;8402:30;;;;8398:35;8478:1;8450:30;;;;8446:35;8526:1;8498:30;;;;8494:35;8574:1;8546:30;;;;8542:35;8622:1;8594:30;;;;8590:35;8670:1;8642:30;;;;8638:35;8718:1;8690:30;;;;8686:35;8766:1;8738:30;;;;8734:35;8814:1;8786:30;;;;8782:35;8862:1;8834:30;;;;8830:35;8910:1;8882:30;;;;8878:35;8958:1;8930:30;;;;8926:35;9006:1;8978:30;;;;8974:35;9054:1;9026:30;;;;9022:35;9102:1;9074:30;;;;9070:35;9150:1;9122:30;;;;9118:35;9198:1;9170:30;;;;9166:35;9246:1;9218:30;;;;9214:35;9294:1;9266:30;;;;9262:35;9342:1;9314:30;;;;9310:35;9390:1;9362:30;;;;9358:35;9438:1;9410:30;;;;9406:35;9486:1;9458:30;;;;9454:35;9534:1;9506:30;;;;9502:35;9582:1;9554:30;;;;9550:35;9630:1;9602:30;;;;9598:35;9678:1;9650:30;;;;9646:35;9726:1;9698:30;;;;9694:35;9774:1;9746:30;;;;9742:35;9822:1;9794:30;;;;9790:35;9870:1;9842:30;;;;9838:35;9918:1;9890:30;;;;9886:35;9966:1;9938:30;;;;9934:35;10014:1;9986:30;;;;9982:35;10062:1;10034:30;;;;10030:35;10110:1;10082:30;;;;10078:35;10158:1;10130:30;;;;10126:35;10206:1;10178:30;;;;10174:35;10254:1;10226:30;;;;10222:35;10302:1;10274:30;;;;10270:35;10350:1;10322:30;;;;10318:35;10398:1;10370:30;;;;10366:35;10446:1;10418:30;;;;10414:35;10494:1;10466:30;;;;10462:35;10542:1;10514:30;;;;10510:35;10590:1;10562:30;;;;10558:35;10638:1;10610:30;;;;10606:35;10686:1;10658:30;;;;10654:35;10734:1;10706:30;;;;10702:35;10782:1;10754:30;;;;10750:35;10830:1;10802:30;;;;10798:35;10878:1;10850:30;;;;10846:35;10926:1;10898:30;;;;10894:35;10974:1;10946:30;;;;10942:35;11022:1;10994:30;;;;10990:35;11070:1;11042:30;;;;11038:35;11118:1;11090:30;;;;11086:35;11166:1;11138:30;;;;11134:35;11214:1;11186:30;;;;11182:35;11262:1;11234:30;;;;11230:35;11310:1;11282:30;;;;11278:35;11358:1;11330:30;;;;11326:35;11406:1;11378:30;;;;11374:35;11454:1;11426:30;;;;11422:35;11502:1;11474:30;;;;11470:35;11550:1;11522:30;;;;11518:35;11598:1;11570:30;;;;11566:35;11646:1;11618:30;;;;11614:35;11694:1;11666:30;;;;11662:35;11742:1;11714:30;;;;11710:35;11790:1;11762:30;;;;11758:35;11838:1;11810:30;;;;11806:35;11886:1;11858:30;;;;11854:35;11934:1;11906:30;;;;11902:35;11982:1;11954:30;;;;11950:35;12030:1;12002:30;;;;11998:35;12078:1;12050:30;;;;12046:35;12126:1;12098:30;;;;12094:35;12174:1;12146:30;;;;12142:35;12222:1;12194:30;;;;12190:35;12270:1;12242:30;;;;12238:35;12318:1;12290:30;;;;12286:35 From 03fde2ae36f3a306d14788c175c649d508d6ed42 Mon Sep 17 00:00:00 2001 From: rodiazet Date: Wed, 23 Apr 2025 12:27:48 +0200 Subject: [PATCH 0946/1022] eof: Add peephole optimiser tests for EOF specific optimisations --- test/libevmasm/Optimiser.cpp | 136 +++++++++++++++++++++++++++++++++++ 1 file changed, 136 insertions(+) diff --git a/test/libevmasm/Optimiser.cpp b/test/libevmasm/Optimiser.cpp index 4e344c174e00..b53205e959e5 100644 --- a/test/libevmasm/Optimiser.cpp +++ b/test/libevmasm/Optimiser.cpp @@ -1049,6 +1049,142 @@ BOOST_AUTO_TEST_CASE(clear_unreachable_code_eof, *boost::unit_test::precondition } } +BOOST_AUTO_TEST_CASE(is_zero_is_zero_rjumpi, *boost::unit_test::precondition(onEOF())) +{ + AssemblyItems items{ + u256(1), + Instruction::ISZERO, + Instruction::ISZERO, + AssemblyItem::conditionalRelativeJumpTo(AssemblyItem(Tag, 1)), + u256(0), + Instruction::SLOAD, + AssemblyItem(Tag, 1), + }; + + AssemblyItems expectation{ + u256(1), + AssemblyItem::conditionalRelativeJumpTo(AssemblyItem(Tag, 1)), + u256(0), + Instruction::SLOAD, + AssemblyItem(Tag, 1), + }; + + PeepholeOptimiser peepOpt(items, solidity::test::CommonOptions::get().evmVersion()); + BOOST_REQUIRE(peepOpt.optimise()); + BOOST_CHECK_EQUAL_COLLECTIONS( + items.begin(), items.end(), + expectation.begin(), expectation.end() + ); +} + +BOOST_AUTO_TEST_CASE(equal_is_zero_rjumpi, *boost::unit_test::precondition(onEOF())) +{ + AssemblyItems items{ + u256(1), + u256(2), + Instruction::EQ, + Instruction::ISZERO, + AssemblyItem::conditionalRelativeJumpTo(AssemblyItem(Tag, 1)), + u256(0), + Instruction::SLOAD, + AssemblyItem(Tag, 1), + }; + + AssemblyItems expectation{ + u256(1), + u256(2), + Instruction::SUB, + AssemblyItem::conditionalRelativeJumpTo(AssemblyItem(Tag, 1)), + u256(0), + Instruction::SLOAD, + AssemblyItem(Tag, 1), + }; + + PeepholeOptimiser peepOpt(items, solidity::test::CommonOptions::get().evmVersion()); + BOOST_REQUIRE(peepOpt.optimise()); + BOOST_CHECK_EQUAL_COLLECTIONS( + items.begin(), items.end(), + expectation.begin(), expectation.end() + ); +} + +BOOST_AUTO_TEST_CASE(double_rjump, *boost::unit_test::precondition(onEOF())) +{ + AssemblyItems items{ + u256(1), + AssemblyItem::conditionalRelativeJumpTo(AssemblyItem(Tag, 1)), + AssemblyItem::relativeJumpTo(AssemblyItem(Tag, 2)), + AssemblyItem(Tag, 1), + u256(0), + Instruction::SLOAD, + AssemblyItem(Tag, 2), + }; + + AssemblyItems expectation{ + u256(1), + Instruction::ISZERO, + AssemblyItem::conditionalRelativeJumpTo(AssemblyItem(Tag, 2)), + AssemblyItem(Tag, 1), + u256(0), + Instruction::SLOAD, + AssemblyItem(Tag, 2), + }; + + PeepholeOptimiser peepOpt(items, solidity::test::CommonOptions::get().evmVersion()); + BOOST_REQUIRE(peepOpt.optimise()); + BOOST_CHECK_EQUAL_COLLECTIONS( + items.begin(), items.end(), + expectation.begin(), expectation.end() + ); +} + +BOOST_AUTO_TEST_CASE(rjump_to_next, *boost::unit_test::precondition(onEOF())) +{ + AssemblyItems items{ + AssemblyItem::relativeJumpTo(AssemblyItem(Tag, 1)), + AssemblyItem(Tag, 1), + u256(0), + Instruction::SLOAD, + }; + + AssemblyItems expectation{ + AssemblyItem(Tag, 1), + u256(0), + Instruction::SLOAD, + }; + + PeepholeOptimiser peepOpt(items, solidity::test::CommonOptions::get().evmVersion()); + BOOST_REQUIRE(peepOpt.optimise()); + BOOST_CHECK_EQUAL_COLLECTIONS( + items.begin(), items.end(), + expectation.begin(), expectation.end() + ); +} + +BOOST_AUTO_TEST_CASE(rjumpi_to_next, *boost::unit_test::precondition(onEOF())) +{ + AssemblyItems items{ + AssemblyItem::conditionalRelativeJumpTo(AssemblyItem(Tag, 1)), + AssemblyItem(Tag, 1), + u256(0), + Instruction::SLOAD, + }; + + AssemblyItems expectation{ + Instruction::POP, + AssemblyItem(Tag, 1), + u256(0), + Instruction::SLOAD, + }; + + PeepholeOptimiser peepOpt(items, solidity::test::CommonOptions::get().evmVersion()); + BOOST_REQUIRE(peepOpt.optimise()); + BOOST_CHECK_EQUAL_COLLECTIONS( + items.begin(), items.end(), + expectation.begin(), expectation.end() + ); +} + BOOST_AUTO_TEST_CASE(deduplicateNextTagBlockSize3) { AssemblyItems items{ From 649c8ee32826476600f67e2f879859563c92dc00 Mon Sep 17 00:00:00 2001 From: Maximilian Hubert <64627729+gap-editor@users.noreply.github.com> Date: Sat, 26 Apr 2025 17:40:13 +0200 Subject: [PATCH 0947/1022] Update SMTPortfolio.cpp --- libsmtutil/SMTPortfolio.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libsmtutil/SMTPortfolio.cpp b/libsmtutil/SMTPortfolio.cpp index 94c92f390a53..e6f6e9913a59 100644 --- a/libsmtutil/SMTPortfolio.cpp +++ b/libsmtutil/SMTPortfolio.cpp @@ -78,7 +78,7 @@ void SMTPortfolio::addAssertion(Expression const& _expr) * Ideally all solvers answer the query and agree on what the answer is * (all say SAT or all say UNSAT). * - * The actual logic as as follows: + * The actual logic as follows: * 1) If at least one solver answers the query, all the non-answer results are ignored. * Here SAT/UNSAT is preferred over UNKNOWN since it's an actual answer, and over ERROR * because one buggy solver/integration shouldn't break the portfolio. From 76e80168f10e560f159309edf3448f48fb80dc0e Mon Sep 17 00:00:00 2001 From: Maximilian Hubert <64627729+gap-editor@users.noreply.github.com> Date: Mon, 28 Apr 2025 11:27:07 +0200 Subject: [PATCH 0948/1022] Update SMTPortfolio.cpp --- libsmtutil/SMTPortfolio.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libsmtutil/SMTPortfolio.cpp b/libsmtutil/SMTPortfolio.cpp index e6f6e9913a59..fb82f3c69361 100644 --- a/libsmtutil/SMTPortfolio.cpp +++ b/libsmtutil/SMTPortfolio.cpp @@ -78,7 +78,7 @@ void SMTPortfolio::addAssertion(Expression const& _expr) * Ideally all solvers answer the query and agree on what the answer is * (all say SAT or all say UNSAT). * - * The actual logic as follows: + * The actual logic is as follows: * 1) If at least one solver answers the query, all the non-answer results are ignored. * Here SAT/UNSAT is preferred over UNKNOWN since it's an actual answer, and over ERROR * because one buggy solver/integration shouldn't break the portfolio. From cc78330e3ad84767014f6fead28bf3a6b53e55f7 Mon Sep 17 00:00:00 2001 From: Afounso Souza Date: Sun, 4 May 2025 22:29:19 +0200 Subject: [PATCH 0949/1022] Update Types.cpp --- libsolidity/ast/Types.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libsolidity/ast/Types.cpp b/libsolidity/ast/Types.cpp index 02df22dd5ce0..f5c83b0cf991 100644 --- a/libsolidity/ast/Types.cpp +++ b/libsolidity/ast/Types.cpp @@ -1648,7 +1648,7 @@ BoolResult ArrayType::isImplicitlyConvertibleTo(Type const& _convertTo) const } else { - // Conversion to storage pointer or to memory, we de not copy element-for-element here, so + // Conversion to storage pointer or to memory, we do not copy element-for-element here, so // require that the base type is the same, not only convertible. // This disallows assignment of nested dynamic arrays from storage to memory for now. if ( From 09fc1d4a21504a9cfd0c645a7754015c18933eb2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Fri, 25 Apr 2025 06:10:31 +0200 Subject: [PATCH 0950/1022] PlainAssemblyParser: Store the stream globally in the class --- test/libevmasm/PlainAssemblyParser.cpp | 37 +++++++++++++++++++------- test/libevmasm/PlainAssemblyParser.h | 14 +++++----- 2 files changed, 35 insertions(+), 16 deletions(-) diff --git a/test/libevmasm/PlainAssemblyParser.cpp b/test/libevmasm/PlainAssemblyParser.cpp index 0fb9d62c8c10..4d09043b1623 100644 --- a/test/libevmasm/PlainAssemblyParser.cpp +++ b/test/libevmasm/PlainAssemblyParser.cpp @@ -28,8 +28,6 @@ #include -#include - using namespace std::string_literals; using namespace solidity; using namespace solidity::test; @@ -39,15 +37,21 @@ using namespace solidity::langutil; Json PlainAssemblyParser::parse(std::string _sourceName, std::string const& _source) { + m_sourceStream = std::istringstream(_source); m_sourceName = std::move(_sourceName); Json codeJSON = Json::array(); - std::istringstream sourceStream(_source); - while (getline(sourceStream, m_line)) + m_lineNumber = 0; + + if (!m_line.has_value()) + advanceLine(); + + while (m_line.has_value()) { - advanceLine(m_line); if (m_lineTokens.empty()) + { + advanceLine(); continue; - + } if (c_instructions.contains(currentToken().value)) { expectNoMoreArguments(); @@ -84,6 +88,8 @@ Json PlainAssemblyParser::parse(std::string _sourceName, std::string const& _sou } else BOOST_THROW_EXCEPTION(std::runtime_error(formatError("Unknown instruction."))); + + advanceLine(); } return {{".code", codeJSON}}; } @@ -125,12 +131,20 @@ void PlainAssemblyParser::expectNoMoreArguments() BOOST_THROW_EXCEPTION(std::runtime_error(formatError("Too many arguments."))); } -void PlainAssemblyParser::advanceLine(std::string_view _line) +bool PlainAssemblyParser::advanceLine() { + std::string line; + if (!getline(m_sourceStream, line)) + { + m_line = std::nullopt; + return false; + } + ++m_lineNumber; - m_line = _line; - m_lineTokens = tokenizeLine(m_line); + m_line = std::move(line); + m_lineTokens = tokenizeLine(*m_line); m_tokenIndex = 0; + return true; } std::vector PlainAssemblyParser::tokenizeLine(std::string_view _line) @@ -162,6 +176,9 @@ std::vector PlainAssemblyParser::tokenizeLine(std::s std::string PlainAssemblyParser::formatError(std::string_view _message) const { + soltestAssert(m_line.has_value()); + soltestAssert(!m_lineTokens.empty()); + std::string lineNumberString = std::to_string(m_lineNumber); std::string padding(lineNumberString.size(), ' '); std::string underline = std::string(currentToken().position, ' ') + std::string(currentToken().value.size(), '^'); @@ -174,7 +191,7 @@ std::string PlainAssemblyParser::formatError(std::string_view _message) const _message, padding, m_sourceName, padding, - m_lineNumber, m_line, + m_lineNumber, *m_line, padding, underline ); } diff --git a/test/libevmasm/PlainAssemblyParser.h b/test/libevmasm/PlainAssemblyParser.h index 0154af5f7f19..95cc3ee8f84e 100644 --- a/test/libevmasm/PlainAssemblyParser.h +++ b/test/libevmasm/PlainAssemblyParser.h @@ -20,6 +20,7 @@ #include +#include #include #include #include @@ -63,17 +64,18 @@ class PlainAssemblyParser bool advanceToken(); std::string_view expectArgument(); void expectNoMoreArguments(); - void advanceLine(std::string_view _line); + bool advanceLine(); static std::vector tokenizeLine(std::string_view _line); std::string formatError(std::string_view _message) const; private: - std::string m_sourceName; ///< Name of the file the source comes from. - size_t m_lineNumber = 0; ///< The number of the current line within the source, 1-based. - std::string m_line; ///< The current line, unparsed. - std::vector m_lineTokens; ///< Decomposition of the current line into tokens (does not include comments). - size_t m_tokenIndex = 0; ///< Points at a token within m_lineTokens. + std::istringstream m_sourceStream; ///< The source code being parsed. + std::string m_sourceName; ///< Name of the file the source comes from. + size_t m_lineNumber = 0; ///< The number of the current line within the source, 1-based. + std::optional m_line; ///< The current line, unparsed. + std::vector m_lineTokens; ///< Decomposition of the current line into tokens (does not include comments). + size_t m_tokenIndex = 0; ///< Points at a token within m_lineTokens. }; } From 73af6528bdd323d8c62fea2788525ad191a8ee3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Fri, 25 Apr 2025 06:17:46 +0200 Subject: [PATCH 0951/1022] PlainAssemblyParser: Syntax for subassemblies --- test/libevmasm/PlainAssemblyParser.cpp | 56 +++++- test/libevmasm/PlainAssemblyParser.h | 11 ++ .../isoltestTesting/empty.asm | 10 + .../isoltestTesting/subassemblies.asm | 69 +++++++ .../isoltestTesting/subassemblies_empty.asm | 34 ++++ .../isoltestTesting/subassemblies_nested.asm | 171 ++++++++++++++++++ 6 files changed, 347 insertions(+), 4 deletions(-) create mode 100644 test/libevmasm/evmAssemblyTests/isoltestTesting/empty.asm create mode 100644 test/libevmasm/evmAssemblyTests/isoltestTesting/subassemblies.asm create mode 100644 test/libevmasm/evmAssemblyTests/isoltestTesting/subassemblies_empty.asm create mode 100644 test/libevmasm/evmAssemblyTests/isoltestTesting/subassemblies_nested.asm diff --git a/test/libevmasm/PlainAssemblyParser.cpp b/test/libevmasm/PlainAssemblyParser.cpp index 4d09043b1623..c8fbfeaeb451 100644 --- a/test/libevmasm/PlainAssemblyParser.cpp +++ b/test/libevmasm/PlainAssemblyParser.cpp @@ -39,11 +39,16 @@ Json PlainAssemblyParser::parse(std::string _sourceName, std::string const& _sou { m_sourceStream = std::istringstream(_source); m_sourceName = std::move(_sourceName); - Json codeJSON = Json::array(); m_lineNumber = 0; - if (!m_line.has_value()) - advanceLine(); + advanceLine(); + return parseAssembly(0); +} + +Json PlainAssemblyParser::parseAssembly(size_t _nestingLevel) +{ + Json assemblyJSON = {{".code", Json::array()}}; + Json& codeJSON = assemblyJSON[".code"]; while (m_line.has_value()) { @@ -52,6 +57,25 @@ Json PlainAssemblyParser::parse(std::string _sourceName, std::string const& _sou advanceLine(); continue; } + + size_t newLevel = parseNestingLevel(); + if (newLevel > _nestingLevel) + BOOST_THROW_EXCEPTION(std::runtime_error(formatError("Indentation does not match the current subassembly nesting level."))); + + if (newLevel < _nestingLevel) + return assemblyJSON; + + if (currentToken().value == ".sub") + { + advanceLine(); + + std::string nextDataIndex = std::to_string(assemblyJSON[".data"].size()); + assemblyJSON[".data"][nextDataIndex] = parseAssembly(_nestingLevel + 1); + continue; + } + else if (assemblyJSON.contains(".data")) + BOOST_THROW_EXCEPTION(std::runtime_error(formatError("The code of an assembly must be specified before its subassemblies."))); + if (c_instructions.contains(currentToken().value)) { expectNoMoreArguments(); @@ -91,7 +115,21 @@ Json PlainAssemblyParser::parse(std::string _sourceName, std::string const& _sou advanceLine(); } - return {{".code", codeJSON}}; + + return assemblyJSON; +} + +size_t PlainAssemblyParser::parseNestingLevel() const +{ + std::string_view indentationString = indentation(); + + if (indentationString != std::string(indentationString.size(), ' ')) + BOOST_THROW_EXCEPTION(std::runtime_error(formatError("Non-space characters used for indentation."))); + + if (indentationString.size() % 4 != 0) + BOOST_THROW_EXCEPTION(std::runtime_error(formatError("Each indentation level must consist of 4 spaces."))); + + return indentationString.size() / 4; } PlainAssemblyParser::Token const& PlainAssemblyParser::currentToken() const @@ -106,6 +144,16 @@ PlainAssemblyParser::Token const& PlainAssemblyParser::nextToken() const return m_lineTokens[m_tokenIndex + 1]; } +std::string_view PlainAssemblyParser::indentation() const +{ + soltestAssert(m_line.has_value()); + + if (m_lineTokens.empty()) + return *m_line; + + return std::string_view(*m_line).substr(0, m_lineTokens.at(0).position); +} + bool PlainAssemblyParser::advanceToken() { if (!hasMoreTokens()) diff --git a/test/libevmasm/PlainAssemblyParser.h b/test/libevmasm/PlainAssemblyParser.h index 95cc3ee8f84e..5332b3202f7b 100644 --- a/test/libevmasm/PlainAssemblyParser.h +++ b/test/libevmasm/PlainAssemblyParser.h @@ -37,12 +37,18 @@ namespace solidity::evmasm::test /// - A non-empty line represents a single assembly item. /// - The name of the item is the first thing on the line and may consist of one or more tokens. /// - One or more arguments follow the name. +/// - Indentation determines assembly nesting level (4 spaces per level). +/// - A new subassembly starts with '.sub' and contains all subsequent lines at a higher nesting level. +/// The first line at the same or lower nesting level ends the subassembly. +/// - Subassemblies can be nested to arbitrary depth. +/// - The code of an assembly must be specified before its subassemblies. /// /// Supported items: /// - All instruction names. /// - PUSH /// - PUSH [tag] /// - tag +/// - .sub class PlainAssemblyParser { public: @@ -57,10 +63,15 @@ class PlainAssemblyParser size_t position; ///< Position of the first character of the token within m_line. }; + Json parseAssembly(size_t _nestingLevel); + size_t parseNestingLevel() const; + Token const& currentToken() const; Token const& nextToken() const; bool hasMoreTokens() const { return m_tokenIndex + 1 < m_lineTokens.size(); } + std::string_view indentation() const; + bool advanceToken(); std::string_view expectArgument(); void expectNoMoreArguments(); diff --git a/test/libevmasm/evmAssemblyTests/isoltestTesting/empty.asm b/test/libevmasm/evmAssemblyTests/isoltestTesting/empty.asm new file mode 100644 index 000000000000..a3c0ef5396a1 --- /dev/null +++ b/test/libevmasm/evmAssemblyTests/isoltestTesting/empty.asm @@ -0,0 +1,10 @@ +// ==== +// outputs: InputAssemblyJSON,Assembly,Bytecode,Opcodes,SourceMappings +// ---- +// InputAssemblyJSON: { +// ".code": [] +// } +// Assembly: +// Bytecode: +// Opcodes: +// SourceMappings: diff --git a/test/libevmasm/evmAssemblyTests/isoltestTesting/subassemblies.asm b/test/libevmasm/evmAssemblyTests/isoltestTesting/subassemblies.asm new file mode 100644 index 000000000000..7dc1a515067d --- /dev/null +++ b/test/libevmasm/evmAssemblyTests/isoltestTesting/subassemblies.asm @@ -0,0 +1,69 @@ +PUSH 0x2 +DUP1 +ADD + +.sub + PUSH 0x42 + DUP1 + MUL + +.sub + STOP +// ==== +// outputs: InputAssemblyJSON,Assembly,Bytecode,Opcodes,SourceMappings +// ---- +// InputAssemblyJSON: { +// ".code": [ +// { +// "name": "PUSH", +// "value": "2" +// }, +// { +// "name": "DUP1" +// }, +// { +// "name": "ADD" +// } +// ], +// ".data": { +// "0": { +// ".code": [ +// { +// "name": "PUSH", +// "value": "42" +// }, +// { +// "name": "DUP1" +// }, +// { +// "name": "MUL" +// } +// ] +// }, +// "1": { +// ".code": [ +// { +// "name": "STOP" +// } +// ] +// } +// } +// } +// Assembly: +// 0x02 +// dup1 +// add +// stop +// +// sub_0: assembly { +// 0x42 +// dup1 +// mul +// } +// +// sub_1: assembly { +// stop +// } +// Bytecode: 60028001fe +// Opcodes: PUSH1 0x2 DUP1 ADD INVALID +// SourceMappings: :::-:0;; diff --git a/test/libevmasm/evmAssemblyTests/isoltestTesting/subassemblies_empty.asm b/test/libevmasm/evmAssemblyTests/isoltestTesting/subassemblies_empty.asm new file mode 100644 index 000000000000..8914710dbf34 --- /dev/null +++ b/test/libevmasm/evmAssemblyTests/isoltestTesting/subassemblies_empty.asm @@ -0,0 +1,34 @@ +.sub +.sub +.sub +// ==== +// outputs: InputAssemblyJSON,Assembly,Bytecode,Opcodes,SourceMappings +// ---- +// InputAssemblyJSON: { +// ".code": [], +// ".data": { +// "0": { +// ".code": [] +// }, +// "1": { +// ".code": [] +// }, +// "2": { +// ".code": [] +// } +// } +// } +// Assembly: +// stop +// +// sub_0: assembly { +// } +// +// sub_1: assembly { +// } +// +// sub_2: assembly { +// } +// Bytecode: fe +// Opcodes: INVALID +// SourceMappings: diff --git a/test/libevmasm/evmAssemblyTests/isoltestTesting/subassemblies_nested.asm b/test/libevmasm/evmAssemblyTests/isoltestTesting/subassemblies_nested.asm new file mode 100644 index 000000000000..59beb9b69ece --- /dev/null +++ b/test/libevmasm/evmAssemblyTests/isoltestTesting/subassemblies_nested.asm @@ -0,0 +1,171 @@ +TIMESTAMP +TIMESTAMP + +.sub + TIMESTAMP + + .sub + TIMESTAMP + .sub + TIMESTAMP + .sub + TIMESTAMP + .sub + TIMESTAMP + .sub + TIMESTAMP +.sub + NUMBER + SLOAD + .sub + NUMBER + MLOAD + .sub + NUMBER + TLOAD + +// ==== +// outputs: InputAssemblyJSON,Assembly,Bytecode,Opcodes,SourceMappings +// ---- +// InputAssemblyJSON: { +// ".code": [ +// { +// "name": "TIMESTAMP" +// }, +// { +// "name": "TIMESTAMP" +// } +// ], +// ".data": { +// "0": { +// ".code": [ +// { +// "name": "TIMESTAMP" +// } +// ], +// ".data": { +// "0": { +// ".code": [ +// { +// "name": "TIMESTAMP" +// } +// ] +// }, +// "1": { +// ".code": [ +// { +// "name": "TIMESTAMP" +// } +// ], +// ".data": { +// "0": { +// ".code": [ +// { +// "name": "TIMESTAMP" +// } +// ], +// ".data": { +// "0": { +// ".code": [ +// { +// "name": "TIMESTAMP" +// } +// ] +// } +// } +// } +// } +// }, +// "2": { +// ".code": [ +// { +// "name": "TIMESTAMP" +// } +// ] +// } +// } +// }, +// "1": { +// ".code": [ +// { +// "name": "NUMBER" +// }, +// { +// "name": "SLOAD" +// } +// ], +// ".data": { +// "0": { +// ".code": [ +// { +// "name": "NUMBER" +// }, +// { +// "name": "MLOAD" +// } +// ], +// ".data": { +// "0": { +// ".code": [ +// { +// "name": "NUMBER" +// }, +// { +// "name": "TLOAD" +// } +// ] +// } +// } +// } +// } +// } +// } +// } +// Assembly: +// timestamp +// timestamp +// stop +// +// sub_0: assembly { +// timestamp +// stop +// +// sub_0: assembly { +// timestamp +// } +// +// sub_1: assembly { +// timestamp +// stop +// +// sub_0: assembly { +// timestamp +// stop +// +// sub_0: assembly { +// timestamp +// } +// } +// } +// +// sub_2: assembly { +// timestamp +// } +// } +// +// sub_1: assembly { +// sload(number) +// stop +// +// sub_0: assembly { +// mload(number) +// stop +// +// sub_0: assembly { +// tload(number) +// } +// } +// } +// Bytecode: 4242fe +// Opcodes: TIMESTAMP TIMESTAMP INVALID +// SourceMappings: :::-:0; From 202933bf14e3bd8349416f3cd185dfda488ef33f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Fri, 25 Apr 2025 07:58:58 +0200 Subject: [PATCH 0952/1022] PlainAssemblyParser: Support pushing assembly sizes and offsets --- test/libevmasm/PlainAssemblyParser.cpp | 15 +++- test/libevmasm/PlainAssemblyParser.h | 2 + .../isoltestTesting/pushsize.asm | 33 +++++++++ .../isoltestTesting/pushsubsize.asm | 72 +++++++++++++++++++ 4 files changed, 121 insertions(+), 1 deletion(-) create mode 100644 test/libevmasm/evmAssemblyTests/isoltestTesting/pushsize.asm create mode 100644 test/libevmasm/evmAssemblyTests/isoltestTesting/pushsubsize.asm diff --git a/test/libevmasm/PlainAssemblyParser.cpp b/test/libevmasm/PlainAssemblyParser.cpp index c8fbfeaeb451..07b680474cb9 100644 --- a/test/libevmasm/PlainAssemblyParser.cpp +++ b/test/libevmasm/PlainAssemblyParser.cpp @@ -76,7 +76,7 @@ Json PlainAssemblyParser::parseAssembly(size_t _nestingLevel) else if (assemblyJSON.contains(".data")) BOOST_THROW_EXCEPTION(std::runtime_error(formatError("The code of an assembly must be specified before its subassemblies."))); - if (c_instructions.contains(currentToken().value)) + if (c_instructions.contains(currentToken().value) || currentToken().value == "PUSHSIZE") { expectNoMoreArguments(); codeJSON.push_back({{"name", currentToken().value}}); @@ -90,6 +90,19 @@ Json PlainAssemblyParser::parseAssembly(size_t _nestingLevel) expectNoMoreArguments(); codeJSON.push_back({{"name", "PUSH [tag]"}, {"value", tagID}}); } + else if (hasMoreTokens() && (nextToken().value == "[$]" || nextToken().value == "#[$]")) + { + std::string pushType = std::string(nextToken().value); + advanceToken(); + std::string_view subassemblyID = expectArgument(); + expectNoMoreArguments(); + + if (!subassemblyID.starts_with("0x")) + BOOST_THROW_EXCEPTION(std::runtime_error(formatError("The subassembly ID must be a hex number prefixed with '0x'."))); + + subassemblyID.remove_prefix("0x"s.size()); + codeJSON.push_back({{"name", "PUSH " + pushType}, {"value", subassemblyID}}); + } else { std::string_view immediateArgument = expectArgument(); diff --git a/test/libevmasm/PlainAssemblyParser.h b/test/libevmasm/PlainAssemblyParser.h index 5332b3202f7b..9318d1662389 100644 --- a/test/libevmasm/PlainAssemblyParser.h +++ b/test/libevmasm/PlainAssemblyParser.h @@ -48,6 +48,8 @@ namespace solidity::evmasm::test /// - PUSH /// - PUSH [tag] /// - tag +/// - PUSH [$] +/// - PUSH #[$] /// - .sub class PlainAssemblyParser { diff --git a/test/libevmasm/evmAssemblyTests/isoltestTesting/pushsize.asm b/test/libevmasm/evmAssemblyTests/isoltestTesting/pushsize.asm new file mode 100644 index 000000000000..3c92687c425a --- /dev/null +++ b/test/libevmasm/evmAssemblyTests/isoltestTesting/pushsize.asm @@ -0,0 +1,33 @@ +PUSHSIZE + +.sub + PUSHSIZE +// ==== +// outputs: InputAssemblyJSON,Assembly,Bytecode,Opcodes,SourceMappings +// ---- +// InputAssemblyJSON: { +// ".code": [ +// { +// "name": "PUSHSIZE" +// } +// ], +// ".data": { +// "0": { +// ".code": [ +// { +// "name": "PUSHSIZE" +// } +// ] +// } +// } +// } +// Assembly: +// bytecodeSize +// stop +// +// sub_0: assembly { +// bytecodeSize +// } +// Bytecode: 6003fe +// Opcodes: PUSH1 0x3 INVALID +// SourceMappings: :::-:0 diff --git a/test/libevmasm/evmAssemblyTests/isoltestTesting/pushsubsize.asm b/test/libevmasm/evmAssemblyTests/isoltestTesting/pushsubsize.asm new file mode 100644 index 000000000000..1b51c22a84ef --- /dev/null +++ b/test/libevmasm/evmAssemblyTests/isoltestTesting/pushsubsize.asm @@ -0,0 +1,72 @@ +PUSH [$] 0x0000 +PUSH #[$] 0x0000 + +.sub + PUSH [$] 0x0 + PUSH #[$] 0x2 + + .sub + .sub + .sub +// ==== +// outputs: InputAssemblyJSON,Assembly,Bytecode,Opcodes,SourceMappings +// ---- +// InputAssemblyJSON: { +// ".code": [ +// { +// "name": "PUSH [$]", +// "value": "0000" +// }, +// { +// "name": "PUSH #[$]", +// "value": "0000" +// } +// ], +// ".data": { +// "0": { +// ".code": [ +// { +// "name": "PUSH [$]", +// "value": "0" +// }, +// { +// "name": "PUSH #[$]", +// "value": "2" +// } +// ], +// ".data": { +// "0": { +// ".code": [] +// }, +// "1": { +// ".code": [] +// }, +// "2": { +// ".code": [] +// } +// } +// } +// } +// } +// Assembly: +// dataOffset(sub_0) +// dataSize(sub_0) +// stop +// +// sub_0: assembly { +// dataOffset(sub_0) +// dataSize(sub_2) +// stop +// +// sub_0: assembly { +// } +// +// sub_1: assembly { +// } +// +// sub_2: assembly { +// } +// } +// Bytecode: 60056005fe60056000fe +// Opcodes: PUSH1 0x5 PUSH1 0x5 INVALID PUSH1 0x5 PUSH1 0x0 INVALID +// SourceMappings: :::-:0; From 78107e344ce526695a5a989250d01812a248d536 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Sun, 27 Apr 2025 11:01:00 +0200 Subject: [PATCH 0953/1022] Assembly item asserts that it's not implicity constructed by instruction for swapn/dupn --- libevmasm/AssemblyItem.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libevmasm/AssemblyItem.h b/libevmasm/AssemblyItem.h index 0dfe0749768a..8386bf2dd4bc 100644 --- a/libevmasm/AssemblyItem.h +++ b/libevmasm/AssemblyItem.h @@ -85,7 +85,10 @@ class AssemblyItem m_type(Operation), m_instruction(_i), m_debugData(std::move(_debugData)) - {} + { + solAssert(_i != Instruction::SWAPN, "Construct via AssemblyItem::swapN"); + solAssert(_i != Instruction::DUPN, "Construct via AssemblyItem::dupN"); + } AssemblyItem(AssemblyItemType _type, u256 _data = 0, langutil::DebugData::ConstPtr _debugData = langutil::DebugData::create()): m_type(_type), m_debugData(std::move(_debugData)) From 49c2e551c12f8fde4dccd59d07be0ad5637060dd Mon Sep 17 00:00:00 2001 From: Matheus Aguiar Date: Mon, 28 Apr 2025 17:57:02 -0300 Subject: [PATCH 0954/1022] Set prague as EVM default version --- .circleci/config.yml | 2 +- .circleci/soltest_all.sh | 2 +- Changelog.md | 1 + docs/using-the-compiler.rst | 8 ++--- liblangutil/EVMVersion.h | 2 +- scripts/externalTests/common.sh | 2 +- scripts/externalTests/runners/base.py | 2 +- scripts/tests.sh | 2 +- .../mcopy_bytes_array_abi_decode/args | 2 +- .../args | 2 +- .../args | 2 +- test/cmdlineTests/metadata/output | 2 +- .../standard_metadata/output.json | 2 +- .../output.json | 2 +- .../output.json | 2 +- .../output.json | 2 +- .../output.json | 4 +-- .../output | 2 +- .../output | 2 +- test/libsolidity/StandardCompiler.cpp | 32 ++++--------------- 20 files changed, 30 insertions(+), 47 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 09b1281c5630..80b3c5358825 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -34,7 +34,7 @@ parameters: default: "solbuildpackpusher/solidity-buildpack-deps@sha256:98f963ed799a0d206ef8e7b5475f847e0dea53b7fdea9618bbc6106a62730bd2" evm-version: type: string - default: cancun + default: prague orbs: win: circleci/windows@2.2.0 diff --git a/.circleci/soltest_all.sh b/.circleci/soltest_all.sh index 216b1ee3815a..56aa1c3be640 100755 --- a/.circleci/soltest_all.sh +++ b/.circleci/soltest_all.sh @@ -38,7 +38,7 @@ EVMS_WITH_EOF=(osaka) # set EVM_VALUES to the default values. IFS=" " read -ra EVM_VALUES <<< "${1:-${DEFAULT_EVM_VALUES[@]}}" -DEFAULT_EVM=cancun +DEFAULT_EVM=prague OPTIMIZE_VALUES=(0 1) EOF_VERSIONS=(0 1) diff --git a/Changelog.md b/Changelog.md index e8ccbb525302..cbaa4252151c 100644 --- a/Changelog.md +++ b/Changelog.md @@ -4,6 +4,7 @@ Language Features: Compiler Features: +* EVM: Set default EVM Version to `prague`. * NatSpec: Capture Natspec documentation of `enum` values in the AST. diff --git a/docs/using-the-compiler.rst b/docs/using-the-compiler.rst index 23e83baec4e6..a3943ea94da2 100644 --- a/docs/using-the-compiler.rst +++ b/docs/using-the-compiler.rst @@ -176,12 +176,12 @@ at each version. Backward compatibility is not guaranteed between each version. - Introduces ``prevrandao()`` and ``block.prevrandao``, and changes the semantics of the now deprecated ``block.difficulty``, disallowing ``difficulty()`` in inline assembly (see `EIP-4399 `_). - ``shanghai`` - Smaller code size and gas savings due to the introduction of ``push0`` (see `EIP-3855 `_). -- ``cancun`` (**default**) +- ``cancun`` - The block's blob base fee (`EIP-7516 `_ and `EIP-4844 `_) can be accessed via the global ``block.blobbasefee`` or ``blobbasefee()`` in inline assembly. - Introduces ``blobhash()`` in inline assembly and a corresponding global function to retrieve versioned hashes of blobs associated with the transaction (see `EIP-4844 `_). - Opcode ``mcopy`` is available in assembly (see `EIP-5656 `_). - Opcodes ``tstore`` and ``tload`` are available in assembly (see `EIP-1153 `_). -- ``prague`` (**experimental**) +- ``prague`` (**default**) - ``osaka`` (**experimental**) - Experimental compilation to EOF is available starting from this version. (`EIP-7692 `_) @@ -356,8 +356,8 @@ Input Description // Version of the EVM to compile for (optional). // Affects type checking and code generation. Can be homestead, // tangerineWhistle, spuriousDragon, byzantium, constantinople, - // petersburg, istanbul, berlin, london, paris, shanghai, cancun (default), prague (experimental) or osaka (experimental). - "evmVersion": "cancun", + // petersburg, istanbul, berlin, london, paris, shanghai, cancun, prague (default) or osaka (experimental). + "evmVersion": "prague", // EVM Object Format version to compile for (optional, experimental). // Currently the only valid value is 1. If not specified, legacy non-EOF bytecode will be generated. "eofVersion": null, diff --git a/liblangutil/EVMVersion.h b/liblangutil/EVMVersion.h index a159f2e4bb2f..38580621a45e 100644 --- a/liblangutil/EVMVersion.h +++ b/liblangutil/EVMVersion.h @@ -167,7 +167,7 @@ class EVMVersion: EVMVersion(Version _version): m_version(_version) {} - Version m_version = Version::Cancun; + Version m_version = Version::Prague; }; } diff --git a/scripts/externalTests/common.sh b/scripts/externalTests/common.sh index 2983b30c296a..26f27b07baca 100644 --- a/scripts/externalTests/common.sh +++ b/scripts/externalTests/common.sh @@ -22,7 +22,7 @@ set -e # Requires $REPO_ROOT to be defined and "${REPO_ROOT}/scripts/common.sh" to be included before. -CURRENT_EVM_VERSION=cancun +CURRENT_EVM_VERSION=prague AVAILABLE_PRESETS=( legacy-no-optimize diff --git a/scripts/externalTests/runners/base.py b/scripts/externalTests/runners/base.py index 4778206150e2..20ba67ddb4a4 100644 --- a/scripts/externalTests/runners/base.py +++ b/scripts/externalTests/runners/base.py @@ -41,7 +41,7 @@ from test_helpers import settings_from_preset from test_helpers import SettingsPreset -CURRENT_EVM_VERSION: str = "cancun" +CURRENT_EVM_VERSION: str = "prague" @dataclass class TestConfig: diff --git a/scripts/tests.sh b/scripts/tests.sh index 3d2849369eca..5ff962be6506 100755 --- a/scripts/tests.sh +++ b/scripts/tests.sh @@ -115,7 +115,7 @@ do for vm in $EVM_VERSIONS do FORCE_ABIV1_RUNS="no" - if [[ "$vm" == "cancun" ]] + if [[ "$vm" == "prague" ]] then FORCE_ABIV1_RUNS="no yes" # run both in paris fi diff --git a/test/cmdlineTests/mcopy_bytes_array_abi_decode/args b/test/cmdlineTests/mcopy_bytes_array_abi_decode/args index 4a03d8d932b9..a346a1eb7963 100644 --- a/test/cmdlineTests/mcopy_bytes_array_abi_decode/args +++ b/test/cmdlineTests/mcopy_bytes_array_abi_decode/args @@ -1 +1 @@ ---evm-version cancun --no-cbor-metadata --via-ir --ir --debug-info none +--no-cbor-metadata --via-ir --ir --debug-info none diff --git a/test/cmdlineTests/mcopy_bytes_array_returned_from_function/args b/test/cmdlineTests/mcopy_bytes_array_returned_from_function/args index c74711ba8aec..a582f88e9c3d 100644 --- a/test/cmdlineTests/mcopy_bytes_array_returned_from_function/args +++ b/test/cmdlineTests/mcopy_bytes_array_returned_from_function/args @@ -1 +1 @@ ---evm-version cancun --no-cbor-metadata --via-ir --optimize --ir-optimized --debug-info none +--no-cbor-metadata --via-ir --optimize --ir-optimized --debug-info none diff --git a/test/cmdlineTests/mcopy_string_literal_returned_from_function/args b/test/cmdlineTests/mcopy_string_literal_returned_from_function/args index c74711ba8aec..a582f88e9c3d 100644 --- a/test/cmdlineTests/mcopy_string_literal_returned_from_function/args +++ b/test/cmdlineTests/mcopy_string_literal_returned_from_function/args @@ -1 +1 @@ ---evm-version cancun --no-cbor-metadata --via-ir --optimize --ir-optimized --debug-info none +--no-cbor-metadata --via-ir --optimize --ir-optimized --debug-info none diff --git a/test/cmdlineTests/metadata/output b/test/cmdlineTests/metadata/output index 0910128894df..a62f2ed145f8 100644 --- a/test/cmdlineTests/metadata/output +++ b/test/cmdlineTests/metadata/output @@ -1,4 +1,4 @@ ======= input.sol:C ======= Metadata: -{"compiler":{"version": ""},"language":"Solidity","output":{"abi":[],"devdoc":{"kind":"dev","methods":{},"version":1},"userdoc":{"kind":"user","methods":{},"version":1}},"settings":{"compilationTarget":{"input.sol":"C"},"evmVersion":"cancun","libraries":{},"metadata":{"bytecodeHash":"ipfs"},"optimizer":{"enabled":false,"runs":200},"remappings":[]},"sources":{"input.sol":{"keccak256":"0x5cf617b1707a484e3c4bd59643013dec76ab7d75900b46855214729ae3e0ceb0","license":"GPL-3.0","urls":["bzz-raw://ac418a02dfadf87234150d3568f33269e3f49460345cb39300e017a6d755eff2","dweb:/ipfs/QmQq3owBu25x2WV46HB1WyKzJpxiAPecU7eMKqtXCF7eeS"]}},"version":1} +{"compiler":{"version": ""},"language":"Solidity","output":{"abi":[],"devdoc":{"kind":"dev","methods":{},"version":1},"userdoc":{"kind":"user","methods":{},"version":1}},"settings":{"compilationTarget":{"input.sol":"C"},"evmVersion":"prague","libraries":{},"metadata":{"bytecodeHash":"ipfs"},"optimizer":{"enabled":false,"runs":200},"remappings":[]},"sources":{"input.sol":{"keccak256":"0x5cf617b1707a484e3c4bd59643013dec76ab7d75900b46855214729ae3e0ceb0","license":"GPL-3.0","urls":["bzz-raw://ac418a02dfadf87234150d3568f33269e3f49460345cb39300e017a6d755eff2","dweb:/ipfs/QmQq3owBu25x2WV46HB1WyKzJpxiAPecU7eMKqtXCF7eeS"]}},"version":1} diff --git a/test/cmdlineTests/standard_metadata/output.json b/test/cmdlineTests/standard_metadata/output.json index 5b9c8504f386..155e15db1761 100644 --- a/test/cmdlineTests/standard_metadata/output.json +++ b/test/cmdlineTests/standard_metadata/output.json @@ -2,7 +2,7 @@ "contracts": { "C": { "C": { - "metadata": "{\"compiler\":{\"version\":\"\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"C\":\"C\"},\"evmVersion\":\"cancun\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"C\":{\"keccak256\":\"0x5cf617b1707a484e3c4bd59643013dec76ab7d75900b46855214729ae3e0ceb0\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://ac418a02dfadf87234150d3568f33269e3f49460345cb39300e017a6d755eff2\",\"dweb:/ipfs/QmQq3owBu25x2WV46HB1WyKzJpxiAPecU7eMKqtXCF7eeS\"]}},\"version\":1}" + "metadata": "{\"compiler\":{\"version\":\"\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"C\":\"C\"},\"evmVersion\":\"prague\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"C\":{\"keccak256\":\"0x5cf617b1707a484e3c4bd59643013dec76ab7d75900b46855214729ae3e0ceb0\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://ac418a02dfadf87234150d3568f33269e3f49460345cb39300e017a6d755eff2\",\"dweb:/ipfs/QmQq3owBu25x2WV46HB1WyKzJpxiAPecU7eMKqtXCF7eeS\"]}},\"version\":1}" } } }, diff --git a/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_empty_sequence_metadata/output.json b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_empty_sequence_metadata/output.json index c461a1485bda..07087b30fdb3 100644 --- a/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_empty_sequence_metadata/output.json +++ b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_empty_sequence_metadata/output.json @@ -2,7 +2,7 @@ "contracts": { "A": { "C": { - "metadata": "{\"compiler\":{\"version\":\"\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"A\":\"C\"},\"evmVersion\":\"cancun\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"details\":{\"constantOptimizer\":false,\"cse\":false,\"deduplicate\":false,\"inliner\":false,\"jumpdestRemover\":true,\"orderLiterals\":false,\"peephole\":true,\"simpleCounterForLoopUncheckedIncrement\":true,\"yul\":false,\"yulDetails\":{\"optimizerSteps\":\":\"}},\"runs\":200},\"remappings\":[]},\"sources\":{\"A\":{\"keccak256\":\"0xb284c39999cb85b80be315a6e9e322adf67a783c66e91ba4439168694580a66d\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://098cee915fad095b8a996813768bd7d5e8c9e40c405e8c43d0572bb7bbc17334\",\"dweb:/ipfs/QmZmUzvSryrrD7pJ9S32iQnEWn4QBL4J1NdbQqL2Xc3yTr\"]}},\"version\":1}" + "metadata": "{\"compiler\":{\"version\":\"\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"A\":\"C\"},\"evmVersion\":\"prague\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"details\":{\"constantOptimizer\":false,\"cse\":false,\"deduplicate\":false,\"inliner\":false,\"jumpdestRemover\":true,\"orderLiterals\":false,\"peephole\":true,\"simpleCounterForLoopUncheckedIncrement\":true,\"yul\":false,\"yulDetails\":{\"optimizerSteps\":\":\"}},\"runs\":200},\"remappings\":[]},\"sources\":{\"A\":{\"keccak256\":\"0xb284c39999cb85b80be315a6e9e322adf67a783c66e91ba4439168694580a66d\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://098cee915fad095b8a996813768bd7d5e8c9e40c405e8c43d0572bb7bbc17334\",\"dweb:/ipfs/QmZmUzvSryrrD7pJ9S32iQnEWn4QBL4J1NdbQqL2Xc3yTr\"]}},\"version\":1}" } } }, diff --git a/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_empty_sequence_whitespaces_metadata/output.json b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_empty_sequence_whitespaces_metadata/output.json index c461a1485bda..07087b30fdb3 100644 --- a/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_empty_sequence_whitespaces_metadata/output.json +++ b/test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_empty_sequence_whitespaces_metadata/output.json @@ -2,7 +2,7 @@ "contracts": { "A": { "C": { - "metadata": "{\"compiler\":{\"version\":\"\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"A\":\"C\"},\"evmVersion\":\"cancun\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"details\":{\"constantOptimizer\":false,\"cse\":false,\"deduplicate\":false,\"inliner\":false,\"jumpdestRemover\":true,\"orderLiterals\":false,\"peephole\":true,\"simpleCounterForLoopUncheckedIncrement\":true,\"yul\":false,\"yulDetails\":{\"optimizerSteps\":\":\"}},\"runs\":200},\"remappings\":[]},\"sources\":{\"A\":{\"keccak256\":\"0xb284c39999cb85b80be315a6e9e322adf67a783c66e91ba4439168694580a66d\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://098cee915fad095b8a996813768bd7d5e8c9e40c405e8c43d0572bb7bbc17334\",\"dweb:/ipfs/QmZmUzvSryrrD7pJ9S32iQnEWn4QBL4J1NdbQqL2Xc3yTr\"]}},\"version\":1}" + "metadata": "{\"compiler\":{\"version\":\"\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"A\":\"C\"},\"evmVersion\":\"prague\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"details\":{\"constantOptimizer\":false,\"cse\":false,\"deduplicate\":false,\"inliner\":false,\"jumpdestRemover\":true,\"orderLiterals\":false,\"peephole\":true,\"simpleCounterForLoopUncheckedIncrement\":true,\"yul\":false,\"yulDetails\":{\"optimizerSteps\":\":\"}},\"runs\":200},\"remappings\":[]},\"sources\":{\"A\":{\"keccak256\":\"0xb284c39999cb85b80be315a6e9e322adf67a783c66e91ba4439168694580a66d\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://098cee915fad095b8a996813768bd7d5e8c9e40c405e8c43d0572bb7bbc17334\",\"dweb:/ipfs/QmZmUzvSryrrD7pJ9S32iQnEWn4QBL4J1NdbQqL2Xc3yTr\"]}},\"version\":1}" } } }, diff --git a/test/cmdlineTests/standard_outputs_on_compilation_error/output.json b/test/cmdlineTests/standard_outputs_on_compilation_error/output.json index 0fa7fcff3cda..eae7a321f05b 100644 --- a/test/cmdlineTests/standard_outputs_on_compilation_error/output.json +++ b/test/cmdlineTests/standard_outputs_on_compilation_error/output.json @@ -32,7 +32,7 @@ "x()": "0c55699c" } }, - "metadata": "{\"compiler\":{\"version\":\"\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"x\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"C\":\"C\"},\"evmVersion\":\"cancun\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"C\":{\"keccak256\":\"0x67a13ebd685e4c6f792e71eb747dac57edb99e94d04d841ee6c979ae517934ce\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://665b000da768823654f680d02686c1e59d682a0b3882e43a77fed9f80ce64ae8\",\"dweb:/ipfs/QmVnKvuidH6KiCdNQpoAQUtDbB8hXkafVLXWMNitUcxnqC\"]}},\"version\":1}", + "metadata": "{\"compiler\":{\"version\":\"\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"x\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"C\":\"C\"},\"evmVersion\":\"prague\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"C\":{\"keccak256\":\"0x67a13ebd685e4c6f792e71eb747dac57edb99e94d04d841ee6c979ae517934ce\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://665b000da768823654f680d02686c1e59d682a0b3882e43a77fed9f80ce64ae8\",\"dweb:/ipfs/QmVnKvuidH6KiCdNQpoAQUtDbB8hXkafVLXWMNitUcxnqC\"]}},\"version\":1}", "storageLayout": { "storage": [], "types": null diff --git a/test/cmdlineTests/standard_undeployable_contract_all_outputs/output.json b/test/cmdlineTests/standard_undeployable_contract_all_outputs/output.json index 3869f7c652bd..be87a5176d06 100644 --- a/test/cmdlineTests/standard_undeployable_contract_all_outputs/output.json +++ b/test/cmdlineTests/standard_undeployable_contract_all_outputs/output.json @@ -35,7 +35,7 @@ "irAst": null, "irOptimized": "", "irOptimizedAst": null, - "metadata": "{\"compiler\":{\"version\":\"\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"C\":\"C\"},\"evmVersion\":\"cancun\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"C\":{\"keccak256\":\"0xa8b7bfe5eff9112e6573d2860721faef28e8920ee251acb458303a05c1ec7df2\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://a2333e25b5034de4f98729e0a737309ba8e0db4371016f312e8f991f6f01613f\",\"dweb:/ipfs/QmVLwS2grVYV6qiDvNmeEYWzb6WDne9Ze47NXERSLPM4fJ\"]}},\"version\":1}", + "metadata": "{\"compiler\":{\"version\":\"\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"C\":\"C\"},\"evmVersion\":\"prague\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"C\":{\"keccak256\":\"0xa8b7bfe5eff9112e6573d2860721faef28e8920ee251acb458303a05c1ec7df2\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://a2333e25b5034de4f98729e0a737309ba8e0db4371016f312e8f991f6f01613f\",\"dweb:/ipfs/QmVLwS2grVYV6qiDvNmeEYWzb6WDne9Ze47NXERSLPM4fJ\"]}},\"version\":1}", "storageLayout": { "storage": [], "types": null @@ -84,7 +84,7 @@ "irAst": null, "irOptimized": "", "irOptimizedAst": null, - "metadata": "{\"compiler\":{\"version\":\"\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"C\":\"I\"},\"evmVersion\":\"cancun\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"C\":{\"keccak256\":\"0xa8b7bfe5eff9112e6573d2860721faef28e8920ee251acb458303a05c1ec7df2\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://a2333e25b5034de4f98729e0a737309ba8e0db4371016f312e8f991f6f01613f\",\"dweb:/ipfs/QmVLwS2grVYV6qiDvNmeEYWzb6WDne9Ze47NXERSLPM4fJ\"]}},\"version\":1}", + "metadata": "{\"compiler\":{\"version\":\"\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"C\":\"I\"},\"evmVersion\":\"prague\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"C\":{\"keccak256\":\"0xa8b7bfe5eff9112e6573d2860721faef28e8920ee251acb458303a05c1ec7df2\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://a2333e25b5034de4f98729e0a737309ba8e0db4371016f312e8f991f6f01613f\",\"dweb:/ipfs/QmVLwS2grVYV6qiDvNmeEYWzb6WDne9Ze47NXERSLPM4fJ\"]}},\"version\":1}", "storageLayout": { "storage": [], "types": null diff --git a/test/cmdlineTests/yul_optimizer_disabled_sequence_empty/output b/test/cmdlineTests/yul_optimizer_disabled_sequence_empty/output index 744bc03a8c6e..de60e7d1dcd8 100644 --- a/test/cmdlineTests/yul_optimizer_disabled_sequence_empty/output +++ b/test/cmdlineTests/yul_optimizer_disabled_sequence_empty/output @@ -1,4 +1,4 @@ ======= input.sol:C ======= Metadata: -{"compiler":{"version": ""},"language":"Solidity","output":{"abi":[],"devdoc":{"kind":"dev","methods":{},"version":1},"userdoc":{"kind":"user","methods":{},"version":1}},"settings":{"compilationTarget":{"input.sol":"C"},"evmVersion":"cancun","libraries":{},"metadata":{"bytecodeHash":"ipfs"},"optimizer":{"details":{"constantOptimizer":false,"cse":false,"deduplicate":false,"inliner":false,"jumpdestRemover":true,"orderLiterals":false,"peephole":true,"simpleCounterForLoopUncheckedIncrement":true,"yul":false,"yulDetails":{"optimizerSteps":":"}},"runs":200},"remappings":[]},"sources":{"input.sol":{"keccak256":"0xc2db3500808896ce1e69de2fe20cecab7ae2ffbb47cdf6ba8321296d95f49fc5","license":"GPL-3.0","urls":["bzz-raw://fde21393c068cd9f2d2b10ba4782db54f6f1c9a725074b17fa742531076be8a4","dweb:/ipfs/QmeTD6mR7YrWNyRowKRS7xs6cJNeMF3T49GAHzGM1bquyM"]}},"version":1} +{"compiler":{"version": ""},"language":"Solidity","output":{"abi":[],"devdoc":{"kind":"dev","methods":{},"version":1},"userdoc":{"kind":"user","methods":{},"version":1}},"settings":{"compilationTarget":{"input.sol":"C"},"evmVersion":"prague","libraries":{},"metadata":{"bytecodeHash":"ipfs"},"optimizer":{"details":{"constantOptimizer":false,"cse":false,"deduplicate":false,"inliner":false,"jumpdestRemover":true,"orderLiterals":false,"peephole":true,"simpleCounterForLoopUncheckedIncrement":true,"yul":false,"yulDetails":{"optimizerSteps":":"}},"runs":200},"remappings":[]},"sources":{"input.sol":{"keccak256":"0xc2db3500808896ce1e69de2fe20cecab7ae2ffbb47cdf6ba8321296d95f49fc5","license":"GPL-3.0","urls":["bzz-raw://fde21393c068cd9f2d2b10ba4782db54f6f1c9a725074b17fa742531076be8a4","dweb:/ipfs/QmeTD6mR7YrWNyRowKRS7xs6cJNeMF3T49GAHzGM1bquyM"]}},"version":1} diff --git a/test/cmdlineTests/yul_optimizer_steps_without_optimize_empty_sequence/output b/test/cmdlineTests/yul_optimizer_steps_without_optimize_empty_sequence/output index a7b037775f2c..2b32c23ee319 100644 --- a/test/cmdlineTests/yul_optimizer_steps_without_optimize_empty_sequence/output +++ b/test/cmdlineTests/yul_optimizer_steps_without_optimize_empty_sequence/output @@ -130,4 +130,4 @@ object "C_28" { } Metadata: -{"compiler":{"version": ""},"language":"Solidity","output":{"abi":[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"foo","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"}],"devdoc":{"kind":"dev","methods":{},"version":1},"userdoc":{"kind":"user","methods":{},"version":1}},"settings":{"compilationTarget":{"input.sol":"C"},"evmVersion":"cancun","libraries":{},"metadata":{"bytecodeHash":"ipfs"},"optimizer":{"details":{"constantOptimizer":false,"cse":false,"deduplicate":false,"inliner":false,"jumpdestRemover":true,"orderLiterals":false,"peephole":true,"simpleCounterForLoopUncheckedIncrement":true,"yul":false,"yulDetails":{"optimizerSteps":":"}},"runs":200},"remappings":[]},"sources":{"input.sol":{"keccak256":"0x3fc910e345ce1ee62bfa6b0f66931ee632c08265b25b6139cfbbfe4d2f8d5dd8","license":"GPL-3.0","urls":["bzz-raw://e557e9ad2c2e420a669c06ae456b0b790d77d2d6d492cd8540e6b244388a5140","dweb:/ipfs/QmaNiZmC2Mo3YxGiehs1n3dVTjZwD7FguX7EUtpeshMVuR"]}},"version":1} +{"compiler":{"version": ""},"language":"Solidity","output":{"abi":[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"foo","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"}],"devdoc":{"kind":"dev","methods":{},"version":1},"userdoc":{"kind":"user","methods":{},"version":1}},"settings":{"compilationTarget":{"input.sol":"C"},"evmVersion":"prague","libraries":{},"metadata":{"bytecodeHash":"ipfs"},"optimizer":{"details":{"constantOptimizer":false,"cse":false,"deduplicate":false,"inliner":false,"jumpdestRemover":true,"orderLiterals":false,"peephole":true,"simpleCounterForLoopUncheckedIncrement":true,"yul":false,"yulDetails":{"optimizerSteps":":"}},"runs":200},"remappings":[]},"sources":{"input.sol":{"keccak256":"0x3fc910e345ce1ee62bfa6b0f66931ee632c08265b25b6139cfbbfe4d2f8d5dd8","license":"GPL-3.0","urls":["bzz-raw://e557e9ad2c2e420a669c06ae456b0b790d77d2d6d492cd8540e6b244388a5140","dweb:/ipfs/QmaNiZmC2Mo3YxGiehs1n3dVTjZwD7FguX7EUtpeshMVuR"]}},"version":1} diff --git a/test/libsolidity/StandardCompiler.cpp b/test/libsolidity/StandardCompiler.cpp index b17f566613a1..5360a2778677 100644 --- a/test/libsolidity/StandardCompiler.cpp +++ b/test/libsolidity/StandardCompiler.cpp @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -1170,33 +1171,14 @@ BOOST_AUTO_TEST_CASE(evm_version) )"; }; Json result; - result = compile(inputForVersion("\"evmVersion\": \"homestead\",")); - BOOST_CHECK(result["contracts"]["fileA"]["A"]["metadata"].get().find("\"evmVersion\":\"homestead\"") != std::string::npos); - result = compile(inputForVersion("\"evmVersion\": \"tangerineWhistle\",")); - BOOST_CHECK(result["contracts"]["fileA"]["A"]["metadata"].get().find("\"evmVersion\":\"tangerineWhistle\"") != std::string::npos); - result = compile(inputForVersion("\"evmVersion\": \"spuriousDragon\",")); - BOOST_CHECK(result["contracts"]["fileA"]["A"]["metadata"].get().find("\"evmVersion\":\"spuriousDragon\"") != std::string::npos); - result = compile(inputForVersion("\"evmVersion\": \"byzantium\",")); - BOOST_CHECK(result["contracts"]["fileA"]["A"]["metadata"].get().find("\"evmVersion\":\"byzantium\"") != std::string::npos); - result = compile(inputForVersion("\"evmVersion\": \"constantinople\",")); - BOOST_CHECK(result["contracts"]["fileA"]["A"]["metadata"].get().find("\"evmVersion\":\"constantinople\"") != std::string::npos); - result = compile(inputForVersion("\"evmVersion\": \"petersburg\",")); - BOOST_CHECK(result["contracts"]["fileA"]["A"]["metadata"].get().find("\"evmVersion\":\"petersburg\"") != std::string::npos); - result = compile(inputForVersion("\"evmVersion\": \"istanbul\",")); - BOOST_CHECK(result["contracts"]["fileA"]["A"]["metadata"].get().find("\"evmVersion\":\"istanbul\"") != std::string::npos); - result = compile(inputForVersion("\"evmVersion\": \"berlin\",")); - BOOST_CHECK(result["contracts"]["fileA"]["A"]["metadata"].get().find("\"evmVersion\":\"berlin\"") != std::string::npos); - result = compile(inputForVersion("\"evmVersion\": \"london\",")); - BOOST_CHECK(result["contracts"]["fileA"]["A"]["metadata"].get().find("\"evmVersion\":\"london\"") != std::string::npos); - result = compile(inputForVersion("\"evmVersion\": \"paris\",")); - BOOST_CHECK(result["contracts"]["fileA"]["A"]["metadata"].get().find("\"evmVersion\":\"paris\"") != std::string::npos); - result = compile(inputForVersion("\"evmVersion\": \"shanghai\",")); - BOOST_CHECK(result["contracts"]["fileA"]["A"]["metadata"].get().find("\"evmVersion\":\"shanghai\"") != std::string::npos); - result = compile(inputForVersion("\"evmVersion\": \"cancun\",")); - BOOST_CHECK(result["contracts"]["fileA"]["A"]["metadata"].get().find("\"evmVersion\":\"cancun\"") != std::string::npos); + for (auto const& version: langutil::EVMVersion::allVersions()) + { + result = compile(inputForVersion(fmt::format("\"evmVersion\": \"{}\",", version.name()))); + BOOST_CHECK(result["contracts"]["fileA"]["A"]["metadata"].get().find(fmt::format("\"evmVersion\":\"{}\"", version.name())) != std::string::npos); + } // test default result = compile(inputForVersion("")); - BOOST_CHECK(result["contracts"]["fileA"]["A"]["metadata"].get().find("\"evmVersion\":\"cancun\"") != std::string::npos); + BOOST_CHECK(result["contracts"]["fileA"]["A"]["metadata"].get().find("\"evmVersion\":\"prague\"") != std::string::npos); // test invalid result = compile(inputForVersion("\"evmVersion\": \"invalid\",")); BOOST_CHECK(result["errors"][0]["message"].get() == "Invalid EVM version requested."); From ca699f9b02a59270afd8f43c28d15c9a63d301ff Mon Sep 17 00:00:00 2001 From: Matheus Aguiar Date: Tue, 6 May 2025 11:47:39 -0300 Subject: [PATCH 0955/1022] bump hardhat version --- test/externalTests/gp2.sh | 5 +---- test/externalTests/pool-together.sh | 4 +--- test/externalTests/uniswap.sh | 5 +---- test/externalTests/zeppelin.sh | 5 +---- 4 files changed, 4 insertions(+), 15 deletions(-) diff --git a/test/externalTests/gp2.sh b/test/externalTests/gp2.sh index 20ea586f5f09..d648de592058 100755 --- a/test/externalTests/gp2.sh +++ b/test/externalTests/gp2.sh @@ -66,10 +66,7 @@ function gp2_test force_hardhat_compiler_settings "$config_file" "$(first_word "$SELECTED_PRESETS")" "$config_var" force_hardhat_unlimited_contract_size "$config_file" "$config_var" yarn - # We require to install hardhat 2.20.0 due to support for evm version cancun, otherwise we get the following error: - # Invalid value {"blockGasLimit":12500000,"hardfork":"cancun","allowUnlimitedContractSize":true} for HardhatConfig.networks.hardhat - Expected a value of type HardhatNetworkConfig. - # See: https://github.com/NomicFoundation/hardhat/issues/4176 - yarn add hardhat@2.20.0 + yarn add hardhat # Ignore bench directory which fails to compile with current hardhat and ethers versions. # bench/trace/gas.ts:123:19 - error TS2339: Property 'equals' does not exist on type 'Uint8Array'. diff --git a/test/externalTests/pool-together.sh b/test/externalTests/pool-together.sh index 0fc8aafbd69d..2eb47912c8b1 100755 --- a/test/externalTests/pool-together.sh +++ b/test/externalTests/pool-together.sh @@ -66,9 +66,7 @@ function pool_together_test force_hardhat_compiler_binary "$config_file" "$BINARY_TYPE" "$BINARY_PATH" force_hardhat_compiler_settings "$config_file" "$(first_word "$SELECTED_PRESETS")" "$config_var" yarn install - # Hardhat 2.20.0 is the last version that works. Newer versions throw this error: - # Unexpected config HardhatConfig.networks.hardhat.initialBaseFeePerGas found - This field is only valid for networks with EIP-1559. Try a newer hardfork or remove it. - yarn add hardhat@2.20.0 + yarn add hardhat # These come with already compiled artifacts. We want them recompiled with latest compiler. rm -r node_modules/@pooltogether/yield-source-interface/artifacts/ diff --git a/test/externalTests/uniswap.sh b/test/externalTests/uniswap.sh index f3d78e6e3397..575fcf309cd2 100755 --- a/test/externalTests/uniswap.sh +++ b/test/externalTests/uniswap.sh @@ -90,10 +90,7 @@ function uniswap_test # TODO: Remove when https://github.com/ethers-io/ethers.js/discussions/2849 is resolved. pnpm install ethers@5.6.1 - # We set hardhat version to 2.20.0 since version 2.21.0 has issues with solidity-coverage plugin - # that often causes out-of-memory errors. - # See hardhat note about the issue here: https://github.com/NomicFoundation/hardhat/releases/tag/hardhat@2.21.0 - pnpm install hardhat@2.20.0 + pnpm install hardhat replace_version_pragmas diff --git a/test/externalTests/zeppelin.sh b/test/externalTests/zeppelin.sh index b9e65562e08f..86d2495da30b 100755 --- a/test/externalTests/zeppelin.sh +++ b/test/externalTests/zeppelin.sh @@ -105,10 +105,7 @@ function zeppelin_test force_hardhat_compiler_binary "$config_file" "$BINARY_TYPE" "$BINARY_PATH" force_hardhat_compiler_settings "$config_file" "$(first_word "$SELECTED_PRESETS")" npm install - # We require to install hardhat 2.20.0 due to support for evm version cancun, otherwise we get the following error: - # Invalid value {"blockGasLimit":10000000,"allowUnlimitedContractSize":true,"hardfork":"cancun"} for HardhatConfig.networks.hardhat - Expected a value of type HardhatNetworkConfig. - # See: https://github.com/NomicFoundation/hardhat/issues/4176 - npm install hardhat@2.20.0 + npm install hardhat replace_version_pragmas for preset in $SELECTED_PRESETS; do From 24d534f67009c62feb336940e6711526d0905390 Mon Sep 17 00:00:00 2001 From: Matheus Aguiar Date: Tue, 6 May 2025 14:59:13 -0300 Subject: [PATCH 0956/1022] Increase resource for uniswap ext test --- .circleci/config.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index 80b3c5358825..6c88b9d19f7c 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -831,6 +831,7 @@ defaults: project: uniswap binary_type: native image: cimg/node:18.16 + resource_class: medium # Tests run out of memory on a smaller machine - job_native_test_ext_prb_math: &job_native_test_ext_prb_math <<: *requires_b_ubu_static From 13d734fd22990508a256c4c591310e78b8247112 Mon Sep 17 00:00:00 2001 From: Matheus Aguiar Date: Tue, 6 May 2025 17:24:18 -0300 Subject: [PATCH 0957/1022] Workaround for openzepellin ext test --- test/externalTests/zeppelin.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/externalTests/zeppelin.sh b/test/externalTests/zeppelin.sh index 86d2495da30b..9bc3e29132aa 100755 --- a/test/externalTests/zeppelin.sh +++ b/test/externalTests/zeppelin.sh @@ -101,6 +101,10 @@ function zeppelin_test # Here only the testToInt(248) and testToInt(256) cases fail so change the loop range to skip them sed -i "s|range(8, 256, 8)\(.forEach(bits => testToInt(bits));\)|range(8, 240, 8)\1|" test/utils/math/SafeCast.test.js + # TODO: Remove when next hardhat version releases, the fix is already merged: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/5663 + # Fails with ProviderError: Invalid transaction: GasFloorMoreThanGasLimit + sed -i "177s|+ 2_000n|+ 10_000n|" test/metatx/ERC2771Forwarder.test.js + neutralize_package_json_hooks force_hardhat_compiler_binary "$config_file" "$BINARY_TYPE" "$BINARY_PATH" force_hardhat_compiler_settings "$config_file" "$(first_word "$SELECTED_PRESETS")" From 1e6842c2c312a124c8ffb28fa0097ebd58f5e990 Mon Sep 17 00:00:00 2001 From: Nikola Matic Date: Wed, 7 May 2025 09:39:30 +0200 Subject: [PATCH 0958/1022] Fix broken docs links --- docs/contracts/inheritance.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/contracts/inheritance.rst b/docs/contracts/inheritance.rst index fccfee609587..8a2d12afd839 100644 --- a/docs/contracts/inheritance.rst +++ b/docs/contracts/inheritance.rst @@ -548,7 +548,7 @@ Multiple Inheritance and Linearization Languages that allow multiple inheritance have to deal with several problems. One is the `Diamond Problem `_. -Solidity is similar to Python in that it uses "`C3 Linearization `_" +Solidity is similar to Python in that it uses C3 Linearization to force a specific order in the directed acyclic graph (DAG) of base classes. This results in the desirable property of monotonicity but disallows some inheritance graphs. Especially, the order in From 1c8d4016f5394d9804864339515b995210eaff5a Mon Sep 17 00:00:00 2001 From: Nikola Matic Date: Wed, 7 May 2025 10:46:23 +0200 Subject: [PATCH 0959/1022] Set changelog release date --- Changelog.md | 5 +---- docs/bugs_by_version.json | 4 ++++ 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/Changelog.md b/Changelog.md index cbaa4252151c..9a1139e9ce84 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,7 +1,4 @@ -### 0.8.30 (unreleased) - -Language Features: - +### 0.8.30 (2025-05-07) Compiler Features: * EVM: Set default EVM Version to `prague`. diff --git a/docs/bugs_by_version.json b/docs/bugs_by_version.json index 60fcdd049a0f..1a210b885c2a 100644 --- a/docs/bugs_by_version.json +++ b/docs/bugs_by_version.json @@ -1923,6 +1923,10 @@ ], "released": "2021-03-23" }, + "0.8.30": { + "bugs": [], + "released": "2025-05-07" + }, "0.8.4": { "bugs": [ "FullInlinerNonExpressionSplitArgumentEvaluationOrder", From e313827e5441d306f6cb28c95c50b451cbf47b4a Mon Sep 17 00:00:00 2001 From: Nikola Matic Date: Wed, 7 May 2025 14:04:08 +0200 Subject: [PATCH 0960/1022] Set version to 0.8.31 --- CMakeLists.txt | 2 +- Changelog.md | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5b39878f26d3..1e477cf3a8dd 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.30") +set(PROJECT_VERSION "0.8.31") # 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 9a1139e9ce84..967e548814ef 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,3 +1,14 @@ +### 0.8.31 (unreleased) + +Language Features: + + +Compiler Features: + + +Bugfixes: + + ### 0.8.30 (2025-05-07) Compiler Features: From 895eb45c8afa147529af66b9431dc39f6d0ac9a9 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Fri, 9 May 2025 15:59:11 +0200 Subject: [PATCH 0961/1022] Add literal assignment to SSACFG --- libyul/YulControlFlowGraphExporter.cpp | 14 +++++++++++--- libyul/backends/evm/SSAControlFlowGraph.cpp | 21 ++++++++++++++++----- libyul/backends/evm/SSAControlFlowGraph.h | 8 ++++++-- 3 files changed, 33 insertions(+), 10 deletions(-) diff --git a/libyul/YulControlFlowGraphExporter.cpp b/libyul/YulControlFlowGraphExporter.cpp index 65c0805f984a..1ce7f58fc5bf 100644 --- a/libyul/YulControlFlowGraphExporter.cpp +++ b/libyul/YulControlFlowGraphExporter.cpp @@ -177,12 +177,20 @@ Json YulControlFlowGraphExporter::toJson(SSACFG const& _cfg, SSACFG::BlockId _bl Json YulControlFlowGraphExporter::toJson(Json& _ret, SSACFG const& _cfg, SSACFG::Operation const& _operation) { Json opJson = Json::object(); - std::visit(util::GenericVisitor{ - [&](SSACFG::Call const& _call) { + std::visit(GenericVisitor{ + [&](SSACFG::Call const& _call) + { _ret["type"] = "FunctionCall"; opJson["op"] = _call.function.get().name.str(); }, - [&](SSACFG::BuiltinCall const& _call) { + [&](SSACFG::LiteralAssignment const&) + { + yulAssert(_operation.inputs.size() == 1); + yulAssert(_cfg.isLiteralValue(_operation.inputs.back())); + _ret["type"] = "LiteralAssignment"; + }, + [&](SSACFG::BuiltinCall const& _call) + { _ret["type"] = "BuiltinCall"; Json builtinArgsJson = Json::array(); auto const& builtin = _call.builtin.get(); diff --git a/libyul/backends/evm/SSAControlFlowGraph.cpp b/libyul/backends/evm/SSAControlFlowGraph.cpp index 733f4967d806..215fe7358b2b 100644 --- a/libyul/backends/evm/SSAControlFlowGraph.cpp +++ b/libyul/backends/evm/SSAControlFlowGraph.cpp @@ -168,17 +168,28 @@ class SSACFGPrinter [&](SSACFG::BuiltinCall const& _call) { return _call.builtin.get().name; }, + [&](SSACFG::LiteralAssignment const&) + { + yulAssert(operation.inputs.size() == 1); + return varToString(m_cfg, operation.inputs.back()); + } }, operation.kind); if (!operation.outputs.empty()) m_result << fmt::format( "{} := ", fmt::join(operation.outputs | ranges::views::transform(valueToString), ", ") ); - m_result << fmt::format( - "{}({})\\l\\\n", - escape(label), - fmt::join(operation.inputs | ranges::views::transform(valueToString), ", ") - ); + if (std::holds_alternative(operation.kind)) + m_result << fmt::format( + "{}\\l\\\n", + escape(label) + ); + else + m_result << fmt::format( + "{}({})\\l\\\n", + escape(label), + fmt::join(operation.inputs | ranges::views::transform(valueToString), ", ") + ); } m_result << "\"];\n"; std::visit(GenericVisitor{ diff --git a/libyul/backends/evm/SSAControlFlowGraph.h b/libyul/backends/evm/SSAControlFlowGraph.h index 9397e0e207c1..ee1bdf3b4ecb 100644 --- a/libyul/backends/evm/SSAControlFlowGraph.h +++ b/libyul/backends/evm/SSAControlFlowGraph.h @@ -78,10 +78,14 @@ class SSACFG std::reference_wrapper call; bool canContinue; }; + struct LiteralAssignment + { + langutil::DebugData::ConstPtr debugData; + }; struct Operation { std::vector outputs{}; - std::variant kind; + std::variant kind; std::vector inputs{}; }; struct BasicBlock @@ -199,7 +203,7 @@ class SSACFG } ValueId newLiteral(langutil::DebugData::ConstPtr _debugData, u256 _value) { - auto [it, inserted] = m_literals.emplace(_value, SSACFG::ValueId{m_valueInfos.size()}); + auto [it, inserted] = m_literals.emplace(_value, ValueId{m_valueInfos.size()}); if (inserted) m_valueInfos.emplace_back(LiteralValue{std::move(_debugData), _value}); else From d790750c2abd66a86201c44d73e8074cd5076a84 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Fri, 9 May 2025 16:01:06 +0200 Subject: [PATCH 0962/1022] Add option to keep literal assignments in SSACFG builder --- libyul/YulStack.cpp | 8 +- .../evm/SSAControlFlowGraphBuilder.cpp | 65 +++++--- .../backends/evm/SSAControlFlowGraphBuilder.h | 7 +- .../standard_yul_cfg_json_export/output.json | 128 ++++++++------- test/cmdlineTests/yul_cfg_json_export/output | 128 ++++++++------- test/libyul/SSAControlFlowGraphTest.cpp | 3 +- .../libyul/yulSSAControlFlowGraph/complex.yul | 75 ++++----- .../yulSSAControlFlowGraph/complex2.yul | 80 +++++----- .../yulSSAControlFlowGraph/function.yul | 6 +- .../yulSSAControlFlowGraph/nested_for.yul | 147 +++++++++--------- .../nested_function.yul | 10 +- 11 files changed, 367 insertions(+), 290 deletions(-) diff --git a/libyul/YulStack.cpp b/libyul/YulStack.cpp index 5adb8d6d5c9a..85709b987c59 100644 --- a/libyul/YulStack.cpp +++ b/libyul/YulStack.cpp @@ -394,11 +394,15 @@ Json YulStack::cfgJson() const yulAssert(m_parserResult->analysisInfo, ""); // FIXME: we should not regenerate the cfg, but for now this is sufficient for testing purposes auto exportCFGFromObject = [&](Object const& _object) -> Json { + // with this set to `true`, assignments of the type `let x := 42` are preserved and added as assignment + // operations to the control flow graphs + bool constexpr keepLiteralAssignments = true; // NOTE: The block Ids are reset for each object std::unique_ptr controlFlow = SSAControlFlowGraphBuilder::build( - *_object.analysisInfo.get(), + *_object.analysisInfo, languageToDialect(m_language, m_evmVersion, m_eofVersion), - _object.code()->root() + _object.code()->root(), + keepLiteralAssignments ); std::unique_ptr liveness = std::make_unique(*controlFlow); YulControlFlowGraphExporter exporter(*controlFlow, liveness.get()); diff --git a/libyul/backends/evm/SSAControlFlowGraphBuilder.cpp b/libyul/backends/evm/SSAControlFlowGraphBuilder.cpp index 69e9e3052104..19308617cd5f 100644 --- a/libyul/backends/evm/SSAControlFlowGraphBuilder.cpp +++ b/libyul/backends/evm/SSAControlFlowGraphBuilder.cpp @@ -20,16 +20,18 @@ */ #include -#include -#include + #include +#include #include +#include #include #include #include #include +#include #include #include #include @@ -49,26 +51,29 @@ SSAControlFlowGraphBuilder::SSAControlFlowGraphBuilder( SSACFG& _graph, AsmAnalysisInfo const& _analysisInfo, ControlFlowSideEffectsCollector const& _sideEffects, - Dialect const& _dialect + Dialect const& _dialect, + bool _keepLiteralAssignments ): m_controlFlow(_controlFlow), m_graph(_graph), m_info(_analysisInfo), m_sideEffects(_sideEffects), - m_dialect(_dialect) + m_dialect(_dialect), + m_keepLiteralAssignments(_keepLiteralAssignments) { } std::unique_ptr SSAControlFlowGraphBuilder::build( AsmAnalysisInfo const& _analysisInfo, Dialect const& _dialect, - Block const& _block + Block const& _block, + bool _keepLiteralAssignments ) { ControlFlowSideEffectsCollector sideEffects(_dialect, _block); auto controlFlow = std::make_unique(); - SSAControlFlowGraphBuilder builder(*controlFlow, *controlFlow->mainGraph, _analysisInfo, sideEffects, _dialect); + SSAControlFlowGraphBuilder builder(*controlFlow, *controlFlow->mainGraph, _analysisInfo, sideEffects, _dialect, _keepLiteralAssignments); builder.m_currentBlock = controlFlow->mainGraph->makeBlock(debugDataOf(_block)); builder.sealBlock(builder.m_currentBlock); builder(_block); @@ -147,8 +152,8 @@ SSACFG::ValueId SSAControlFlowGraphBuilder::tryRemoveTrivialPhi(SSACFG::ValueId [](SSACFG::BasicBlock::Terminated&) {} }, block.exit); } - for (auto& [_, currentVariableDefs]: m_currentDef) - std::replace(currentVariableDefs.begin(), currentVariableDefs.end(), _phi, same); + for (auto& currentVariableDefs: m_currentDef | ranges::views::values) + ranges::replace(currentVariableDefs, _phi, same); for (auto phiUse: phiUses) tryRemoveTrivialPhi(phiUse); @@ -178,11 +183,6 @@ void SSAControlFlowGraphBuilder::cleanUnreachable() }, block.exit); }); - auto isUnreachableValue = [&](SSACFG::ValueId const& _value) -> bool { - auto* valueInfo = std::get_if(&m_graph.valueInfo(_value)); - return (valueInfo) ? true : false; - }; - // Remove all entries from unreachable nodes from the graph. for (SSACFG::BlockId blockId: reachabilityCheck.visited) { @@ -197,7 +197,7 @@ void SSAControlFlowGraphBuilder::cleanUnreachable() for (auto phi: block.phis) if (auto* phiInfo = std::get_if(&m_graph.valueInfo(phi))) std::erase_if(phiInfo->arguments, [&](SSACFG::ValueId _arg) { - if (isUnreachableValue(_arg)) + if (std::holds_alternative(m_graph.valueInfo(_arg))) { maybeTrivialPhi.insert(phi); return true; @@ -240,7 +240,7 @@ void SSAControlFlowGraphBuilder::buildFunctionGraph( cfg.arguments = arguments; cfg.returns = returns; - SSAControlFlowGraphBuilder builder(m_controlFlow, cfg, m_info, m_sideEffects, m_dialect); + SSAControlFlowGraphBuilder builder(m_controlFlow, cfg, m_info, m_sideEffects, m_dialect, m_keepLiteralAssignments); builder.m_currentBlock = cfg.entry; builder.m_functionDefinitions = m_functionDefinitions; for (auto&& [var, varId]: cfg.arguments) @@ -273,6 +273,11 @@ void SSAControlFlowGraphBuilder::operator()(Assignment const& _assignment) void SSAControlFlowGraphBuilder::operator()(VariableDeclaration const& _variableDeclaration) { + // if we have no value (like in `let a` without right-hand side), we can just skip this. the variable(s) will be + // added when first needed + if (!_variableDeclaration.value) + return; + assign( _variableDeclaration.variables | ranges::views::transform([&](auto& _var) { return std::ref(lookupVariable(_var.name)); }) | ranges::to, _variableDeclaration.value.get() @@ -533,15 +538,27 @@ void SSAControlFlowGraphBuilder::assign(std::vector std::vector { if (auto const* functionCall = std::get_if(_expression)) return visitFunctionCall(*functionCall); - else if (_expression) + if (_expression) return {std::visit(*this, *_expression)}; - else - return {_variables.size(), zero()}; + return {_variables.size(), zero()}; }(); yulAssert(rhs.size() == _variables.size()); for (auto const& [var, value]: ranges::zip_view(_variables, rhs)) - writeVariable(var, m_currentBlock, value); + { + if (m_keepLiteralAssignments && m_graph.isLiteralValue(value)) + { + SSACFG::Operation assignment{ + .outputs = {m_graph.newVariable(m_currentBlock)}, + .kind = SSACFG::LiteralAssignment{}, + .inputs = {value} + }; + currentBlock().operations.emplace_back(assignment); + writeVariable(var, m_currentBlock, assignment.outputs.back()); + } + else + writeVariable(var, m_currentBlock, value); + } } @@ -610,7 +627,7 @@ SSACFG::ValueId SSAControlFlowGraphBuilder::readVariableRecursive(Scope::Variabl // incomplete block val = m_graph.newPhi(_block); block.phis.insert(val); - info.incompletePhis.emplace_back(val, std::ref(_variable)); + info.incompletePhis.emplace_back(val, _variable); } else if (block.entries.size() == 1) // one predecessor: no phi needed @@ -633,7 +650,7 @@ SSACFG::ValueId SSAControlFlowGraphBuilder::addPhiOperands(Scope::Variable const { yulAssert(std::holds_alternative(m_graph.valueInfo(_phi))); auto& phi = std::get(m_graph.valueInfo(_phi)); - for (auto pred: m_graph.block(phi.block).entries) + for (auto const& pred: m_graph.block(phi.block).entries) phi.arguments.emplace_back(readVariable(_variable, pred)); // we call tryRemoveTrivialPhi explicitly to avoid removing trivial phis in unsealed blocks return _phi; @@ -660,14 +677,14 @@ Scope::Variable const& SSAControlFlowGraphBuilder::lookupVariable(YulName _name) yulAssert(m_scope, ""); Scope::Variable const* var = nullptr; if (m_scope->lookup(_name, util::GenericVisitor{ - [&](Scope::Variable& _var) { var = &_var; }, - [](Scope::Function&) + [&](Scope::Variable const& _var) { var = &_var; }, + [](Scope::Function const&) { yulAssert(false, "Function not removed during desugaring."); } })) { - yulAssert(var, ""); + yulAssert(var); return *var; }; yulAssert(false, "External identifier access unimplemented."); diff --git a/libyul/backends/evm/SSAControlFlowGraphBuilder.h b/libyul/backends/evm/SSAControlFlowGraphBuilder.h index a3a723f67c42..8cd214146260 100644 --- a/libyul/backends/evm/SSAControlFlowGraphBuilder.h +++ b/libyul/backends/evm/SSAControlFlowGraphBuilder.h @@ -44,7 +44,8 @@ class SSAControlFlowGraphBuilder SSACFG& _graph, AsmAnalysisInfo const& _analysisInfo, ControlFlowSideEffectsCollector const& _sideEffects, - Dialect const& _dialect + Dialect const& _dialect, + bool _keepLiteralAssignments ); public: SSAControlFlowGraphBuilder(SSAControlFlowGraphBuilder const&) = delete; @@ -52,7 +53,8 @@ class SSAControlFlowGraphBuilder static std::unique_ptr build( AsmAnalysisInfo const& _analysisInfo, Dialect const& _dialect, - Block const& _block + Block const& _block, + bool _keepLiteralAssignments ); void operator()(ExpressionStatement const& _statement); @@ -92,6 +94,7 @@ class SSAControlFlowGraphBuilder AsmAnalysisInfo const& m_info; ControlFlowSideEffectsCollector const& m_sideEffects; Dialect const& m_dialect; + bool const m_keepLiteralAssignments; std::vector> m_functionDefinitions; SSACFG::BlockId m_currentBlock; SSACFG::BasicBlock& currentBlock() { return m_graph.block(m_currentBlock); } diff --git a/test/cmdlineTests/standard_yul_cfg_json_export/output.json b/test/cmdlineTests/standard_yul_cfg_json_export/output.json index 303d51bbbbf4..a9c5ca7a6d4f 100644 --- a/test/cmdlineTests/standard_yul_cfg_json_export/output.json +++ b/test/cmdlineTests/standard_yul_cfg_json_export/output.json @@ -1221,16 +1221,27 @@ "type": "ConditionalJump" }, "id": "Block18", - "instructions": [], + "instructions": [ + { + "in": [ + "0x00" + ], + "out": [ + "v64" + ] + } + ], "liveness": { "in": [ "v46", "v59" ], "out": [ - "v46" + "v46", + "v64" ] - } + }, + "type": "LiteralAssignment" }, { "exit": { @@ -1297,12 +1308,12 @@ "instructions": [ { "in": [ - "0x00", - "v93" + "v64", + "v95" ], "op": "PhiFunction", "out": [ - "v95" + "v97" ] }, { @@ -1311,13 +1322,13 @@ ], "op": "mload", "out": [ - "v94" + "v96" ] }, { "in": [ - "v95", - "v94" + "v97", + "v96" ], "op": "mstore", "out": [] @@ -1325,7 +1336,7 @@ { "in": [ "0x20", - "v94" + "v96" ], "op": "return", "out": [] @@ -1333,7 +1344,7 @@ ], "liveness": { "in": [ - "v95" + "v97" ], "out": [] }, @@ -1341,7 +1352,7 @@ }, { "exit": { - "cond": "v67", + "cond": "v69", "targets": [ "Block23", "Block22" @@ -1350,21 +1361,29 @@ }, "id": "Block20", "instructions": [ + { + "in": [ + "0x20" + ], + "out": [ + "v67" + ] + }, { "in": [], "op": "returndatasize", "out": [ - "v66" + "v68" ] }, { "in": [ - "v66", + "v68", "0x20" ], "op": "gt", "out": [ - "v67" + "v69" ] } ], @@ -1373,7 +1392,8 @@ "v46" ], "out": [ - "v46" + "v46", + "v67" ] }, "type": "BuiltinCall" @@ -1384,7 +1404,7 @@ "Block22" ], "exit": { - "cond": "v80", + "cond": "v82", "targets": [ "Block25", "Block24" @@ -1395,12 +1415,12 @@ "instructions": [ { "in": [ - "0x20", - "v68" + "v67", + "v70" ], "op": "PhiFunction", "out": [ - "v71" + "v73" ] }, { @@ -1409,79 +1429,79 @@ ], "op": "not", "out": [ - "v70" + "v72" ] }, { "in": [ "0x1f", - "v71" + "v73" ], "op": "add", "out": [ - "v72" + "v74" ] }, { "in": [ - "v70", - "v72" + "v72", + "v74" ], "op": "and", "out": [ - "v73" + "v75" ] }, { "in": [ - "v73", + "v75", "v46" ], "op": "add", "out": [ - "v77" + "v79" ] }, { "in": [ "v46", - "v77" + "v79" ], "op": "lt", "out": [ - "v78" + "v80" ] }, { "in": [ "0xffffffffffffffff", - "v77" + "v79" ], "op": "gt", "out": [ - "v79" + "v81" ] }, { "in": [ - "v78", - "v79" + "v80", + "v81" ], "op": "or", "out": [ - "v80" + "v82" ] } ], "liveness": { "in": [ "v46", - "v71" + "v73" ], "out": [ "v46", - "v71", - "v77" + "v73", + "v79" ] }, "type": "BuiltinCall" @@ -1499,7 +1519,7 @@ "in": [], "op": "returndatasize", "out": [ - "v68" + "v70" ] } ], @@ -1509,14 +1529,14 @@ ], "out": [ "v46", - "v68" + "v70" ] }, "type": "BuiltinCall" }, { "exit": { - "cond": "v90", + "cond": "v92", "targets": [ "Block28", "Block27" @@ -1527,7 +1547,7 @@ "instructions": [ { "in": [ - "v77", + "v79", "0x40" ], "op": "mstore", @@ -1535,40 +1555,40 @@ }, { "in": [ - "v71", + "v73", "v46" ], "op": "add", "out": [ - "v88" + "v90" ] }, { "in": [ "v46", - "v88" + "v90" ], "op": "sub", "out": [ - "v89" + "v91" ] }, { "in": [ "0x20", - "v89" + "v91" ], "op": "slt", "out": [ - "v90" + "v92" ] } ], "liveness": { "in": [ "v46", - "v71", - "v77" + "v73", + "v79" ], "out": [ "v46" @@ -1589,12 +1609,12 @@ ], "op": "shl", "out": [ - "v81" + "v83" ] }, { "in": [ - "v81", + "v83", "0x00" ], "op": "mstore", @@ -1638,7 +1658,7 @@ ], "op": "mload", "out": [ - "v93" + "v95" ] } ], @@ -1647,7 +1667,7 @@ "v46" ], "out": [ - "v93" + "v95" ] }, "type": "BuiltinCall" diff --git a/test/cmdlineTests/yul_cfg_json_export/output b/test/cmdlineTests/yul_cfg_json_export/output index 9affc4206939..2620d53a96ab 100644 --- a/test/cmdlineTests/yul_cfg_json_export/output +++ b/test/cmdlineTests/yul_cfg_json_export/output @@ -1221,16 +1221,27 @@ Yul Control Flow Graph: "type": "ConditionalJump" }, "id": "Block18", - "instructions": [], + "instructions": [ + { + "in": [ + "0x00" + ], + "out": [ + "v64" + ] + } + ], "liveness": { "in": [ "v46", "v59" ], "out": [ - "v46" + "v46", + "v64" ] - } + }, + "type": "LiteralAssignment" }, { "exit": { @@ -1297,12 +1308,12 @@ Yul Control Flow Graph: "instructions": [ { "in": [ - "0x00", - "v93" + "v64", + "v95" ], "op": "PhiFunction", "out": [ - "v95" + "v97" ] }, { @@ -1311,13 +1322,13 @@ Yul Control Flow Graph: ], "op": "mload", "out": [ - "v94" + "v96" ] }, { "in": [ - "v95", - "v94" + "v97", + "v96" ], "op": "mstore", "out": [] @@ -1325,7 +1336,7 @@ Yul Control Flow Graph: { "in": [ "0x20", - "v94" + "v96" ], "op": "return", "out": [] @@ -1333,7 +1344,7 @@ Yul Control Flow Graph: ], "liveness": { "in": [ - "v95" + "v97" ], "out": [] }, @@ -1341,7 +1352,7 @@ Yul Control Flow Graph: }, { "exit": { - "cond": "v67", + "cond": "v69", "targets": [ "Block23", "Block22" @@ -1350,21 +1361,29 @@ Yul Control Flow Graph: }, "id": "Block20", "instructions": [ + { + "in": [ + "0x20" + ], + "out": [ + "v67" + ] + }, { "in": [], "op": "returndatasize", "out": [ - "v66" + "v68" ] }, { "in": [ - "v66", + "v68", "0x20" ], "op": "gt", "out": [ - "v67" + "v69" ] } ], @@ -1373,7 +1392,8 @@ Yul Control Flow Graph: "v46" ], "out": [ - "v46" + "v46", + "v67" ] }, "type": "BuiltinCall" @@ -1384,7 +1404,7 @@ Yul Control Flow Graph: "Block22" ], "exit": { - "cond": "v80", + "cond": "v82", "targets": [ "Block25", "Block24" @@ -1395,12 +1415,12 @@ Yul Control Flow Graph: "instructions": [ { "in": [ - "0x20", - "v68" + "v67", + "v70" ], "op": "PhiFunction", "out": [ - "v71" + "v73" ] }, { @@ -1409,79 +1429,79 @@ Yul Control Flow Graph: ], "op": "not", "out": [ - "v70" + "v72" ] }, { "in": [ "0x1f", - "v71" + "v73" ], "op": "add", "out": [ - "v72" + "v74" ] }, { "in": [ - "v70", - "v72" + "v72", + "v74" ], "op": "and", "out": [ - "v73" + "v75" ] }, { "in": [ - "v73", + "v75", "v46" ], "op": "add", "out": [ - "v77" + "v79" ] }, { "in": [ "v46", - "v77" + "v79" ], "op": "lt", "out": [ - "v78" + "v80" ] }, { "in": [ "0xffffffffffffffff", - "v77" + "v79" ], "op": "gt", "out": [ - "v79" + "v81" ] }, { "in": [ - "v78", - "v79" + "v80", + "v81" ], "op": "or", "out": [ - "v80" + "v82" ] } ], "liveness": { "in": [ "v46", - "v71" + "v73" ], "out": [ "v46", - "v71", - "v77" + "v73", + "v79" ] }, "type": "BuiltinCall" @@ -1499,7 +1519,7 @@ Yul Control Flow Graph: "in": [], "op": "returndatasize", "out": [ - "v68" + "v70" ] } ], @@ -1509,14 +1529,14 @@ Yul Control Flow Graph: ], "out": [ "v46", - "v68" + "v70" ] }, "type": "BuiltinCall" }, { "exit": { - "cond": "v90", + "cond": "v92", "targets": [ "Block28", "Block27" @@ -1527,7 +1547,7 @@ Yul Control Flow Graph: "instructions": [ { "in": [ - "v77", + "v79", "0x40" ], "op": "mstore", @@ -1535,40 +1555,40 @@ Yul Control Flow Graph: }, { "in": [ - "v71", + "v73", "v46" ], "op": "add", "out": [ - "v88" + "v90" ] }, { "in": [ "v46", - "v88" + "v90" ], "op": "sub", "out": [ - "v89" + "v91" ] }, { "in": [ "0x20", - "v89" + "v91" ], "op": "slt", "out": [ - "v90" + "v92" ] } ], "liveness": { "in": [ "v46", - "v71", - "v77" + "v73", + "v79" ], "out": [ "v46" @@ -1589,12 +1609,12 @@ Yul Control Flow Graph: ], "op": "shl", "out": [ - "v81" + "v83" ] }, { "in": [ - "v81", + "v83", "0x00" ], "op": "mstore", @@ -1638,7 +1658,7 @@ Yul Control Flow Graph: ], "op": "mload", "out": [ - "v93" + "v95" ] } ], @@ -1647,7 +1667,7 @@ Yul Control Flow Graph: "v46" ], "out": [ - "v93" + "v95" ] }, "type": "BuiltinCall" diff --git a/test/libyul/SSAControlFlowGraphTest.cpp b/test/libyul/SSAControlFlowGraphTest.cpp index d2acee7bcb85..087a79e974af 100644 --- a/test/libyul/SSAControlFlowGraphTest.cpp +++ b/test/libyul/SSAControlFlowGraphTest.cpp @@ -73,7 +73,8 @@ TestCase::TestResult SSAControlFlowGraphTest::run(std::ostream& _stream, std::st std::unique_ptr controlFlow = SSAControlFlowGraphBuilder::build( *yulStack.parserResult()->analysisInfo, yulStack.dialect(), - yulStack.parserResult()->code()->root() + yulStack.parserResult()->code()->root(), + true ); ControlFlowLiveness liveness(*controlFlow); m_obtainedResult = controlFlow->toDot(&liveness); diff --git a/test/libyul/yulSSAControlFlowGraph/complex.yul b/test/libyul/yulSSAControlFlowGraph/complex.yul index 6fb0453c186b..ecb1b7cfeacd 100644 --- a/test/libyul/yulSSAControlFlowGraph/complex.yul +++ b/test/libyul/yulSSAControlFlowGraph/complex.yul @@ -63,29 +63,30 @@ // FunctionEntry_f_0 -> Block1_0; // Block1_0 [label="\ // Block 0; (0, max 17)\nLiveIn: v0,v1\l\ -// LiveOut: v0,v1\l\n"]; +// LiveOut: v0,v1,v4\l\nv4 := 42\l\ +// "]; // Block1_0 -> Block1_0Exit [arrowhead=none]; // Block1_0Exit [label="Jump" shape=oval]; // Block1_0Exit -> Block1_1 [style="solid"]; // Block1_1 [label="\ -// Block 1; (1, max 17)\nLiveIn: v0,v1,v5\l\ -// LiveOut: v0,v1,v5\l\nv5 := φ(\l\ -// Block 0 => 42,\l\ -// Block 21 => v43\l\ +// Block 1; (1, max 17)\nLiveIn: v0,v1,v6\l\ +// LiveOut: v0,v1,v6\l\nv6 := φ(\l\ +// Block 0 => v4,\l\ +// Block 21 => v44\l\ // )\l\ -// v6 := lt(v0, v5)\l\ +// v7 := lt(v0, v6)\l\ // "]; // Block1_1 -> Block1_1Exit; -// Block1_1Exit [label="{ If v6 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; +// Block1_1Exit [label="{ If v7 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; // Block1_1Exit:0 -> Block1_4 [style="solid"]; // Block1_1Exit:1 -> Block1_2 [style="solid"]; // Block1_2 [label="\ -// Block 2; (2, max 17)\nLiveIn: v0,v1,v5\l\ -// LiveOut: v0,v1,v5,v7\l\nv7 := mload(v5)\l\ -// v8 := eq(0, v7)\l\ +// Block 2; (2, max 17)\nLiveIn: v0,v1,v6\l\ +// LiveOut: v0,v1,v6,v8\l\nv8 := mload(v6)\l\ +// v9 := eq(0, v8)\l\ // "]; // Block1_2 -> Block1_2Exit; -// Block1_2Exit [label="{ If v8 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; +// Block1_2Exit [label="{ If v9 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; // Block1_2Exit:0 -> Block1_7 [style="solid"]; // Block1_2Exit:1 -> Block1_6 [style="solid"]; // Block1_4 [label="\ @@ -102,11 +103,11 @@ // Block1_6Exit [label="Jump" shape=oval]; // Block1_6Exit -> Block1_4 [style="solid"]; // Block1_7 [label="\ -// Block 7; (5, max 17)\nLiveIn: v0,v1,v5,v7\l\ -// LiveOut: v0,v1,v5,v7\l\nv13 := eq(1, v7)\l\ +// Block 7; (5, max 17)\nLiveIn: v0,v1,v6,v8\l\ +// LiveOut: v0,v1,v6,v8\l\nv14 := eq(1, v8)\l\ // "]; // Block1_7 -> Block1_7Exit; -// Block1_7Exit [label="{ If v13 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; +// Block1_7Exit [label="{ If v14 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; // Block1_7Exit:0 -> Block1_10 [style="solid"]; // Block1_7Exit:1 -> Block1_9 [style="solid"]; // Block1_9 [label="\ @@ -116,11 +117,11 @@ // Block1_9Exit [label="FunctionReturn[0]"]; // Block1_9 -> Block1_9Exit; // Block1_10 [label="\ -// Block 10; (7, max 17)\nLiveIn: v0,v1,v5,v7\l\ -// LiveOut: v0,v1,v5,v7\l\nv20 := eq(2, v7)\l\ +// Block 10; (7, max 17)\nLiveIn: v0,v1,v6,v8\l\ +// LiveOut: v0,v1,v6,v8\l\nv21 := eq(2, v8)\l\ // "]; // Block1_10 -> Block1_10Exit; -// Block1_10Exit [label="{ If v20 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; +// Block1_10Exit [label="{ If v21 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; // Block1_10Exit:0 -> Block1_13 [style="solid"]; // Block1_10Exit:1 -> Block1_12 [style="solid"]; // Block1_12 [label="\ @@ -131,31 +132,31 @@ // Block1_12Exit [label="Terminated"]; // Block1_12 -> Block1_12Exit; // Block1_13 [label="\ -// Block 13; (9, max 17)\nLiveIn: v0,v1,v5,v7\l\ -// LiveOut: v0,v1,v5\l\nv25 := eq(3, v7)\l\ +// Block 13; (9, max 17)\nLiveIn: v0,v1,v6,v8\l\ +// LiveOut: v0,v1,v6\l\nv26 := eq(3, v8)\l\ // "]; // Block1_13 -> Block1_13Exit; -// Block1_13Exit [label="{ If v25 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; +// Block1_13Exit [label="{ If v26 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; // Block1_13Exit:0 -> Block1_16 [style="solid"]; // Block1_13Exit:1 -> Block1_15 [style="solid"]; // Block1_15 [label="\ -// Block 15; (10, max 14)\nLiveIn: v0,v1,v5\l\ -// LiveOut: v0,v1,v5\l\nsstore(2056, 8)\l\ +// Block 15; (10, max 14)\nLiveIn: v0,v1,v6\l\ +// LiveOut: v0,v1,v6\l\nsstore(2056, 8)\l\ // "]; // Block1_15 -> Block1_15Exit [arrowhead=none]; // Block1_15Exit [label="Jump" shape=oval]; // Block1_15Exit -> Block1_5 [style="solid"]; // Block1_16 [label="\ -// Block 16; (15, max 17)\nLiveIn: v0,v1,v5\l\ -// LiveOut: v0,v1,v5\l\nv29 := mload(v1)\l\ +// Block 16; (15, max 17)\nLiveIn: v0,v1,v6\l\ +// LiveOut: v0,v1,v6\l\nv30 := mload(v1)\l\ // "]; // Block1_16 -> Block1_16Exit; -// Block1_16Exit [label="{ If v29 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; +// Block1_16Exit [label="{ If v30 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; // Block1_16Exit:0 -> Block1_18 [style="solid"]; // Block1_16Exit:1 -> Block1_17 [style="solid"]; // Block1_5 [label="\ -// Block 5; (11, max 14)\nLiveIn: v0,v1,v5\l\ -// LiveOut: v0,v1,v5\l\nsstore(2827, 11)\l\ +// Block 5; (11, max 14)\nLiveIn: v0,v1,v6\l\ +// LiveOut: v0,v1,v6\l\nsstore(2827, 11)\l\ // "]; // Block1_5 -> Block1_5Exit [arrowhead=none]; // Block1_5Exit [label="Jump" shape=oval]; @@ -167,30 +168,30 @@ // Block1_17Exit [label="Terminated"]; // Block1_17 -> Block1_17Exit; // Block1_18 [label="\ -// Block 18; (17, max 17)\nLiveIn: v0,v1,v5\l\ -// LiveOut: v0,v1,v5\l\nsstore(2570, 10)\l\ +// Block 18; (17, max 17)\nLiveIn: v0,v1,v6\l\ +// LiveOut: v0,v1,v6\l\nsstore(2570, 10)\l\ // "]; // Block1_18 -> Block1_18Exit [arrowhead=none]; // Block1_18Exit [label="Jump" shape=oval]; // Block1_18Exit -> Block1_5 [style="solid"]; // Block1_3 [label="\ -// Block 3; (12, max 14)\nLiveIn: v0,v1,v5\l\ -// LiveOut: v0,v1,v43\l\nv43 := add(1, v5)\l\ -// v44 := calldataload(v43)\l\ +// Block 3; (12, max 14)\nLiveIn: v0,v1,v6\l\ +// LiveOut: v0,v1,v44\l\nv44 := add(1, v6)\l\ +// v45 := calldataload(v44)\l\ // "]; // Block1_3 -> Block1_3Exit; -// Block1_3Exit [label="{ If v44 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; +// Block1_3Exit [label="{ If v45 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; // Block1_3Exit:0 -> Block1_21 [style="solid"]; // Block1_3Exit:1 -> Block1_20 [style="solid"]; // Block1_20 [label="\ -// Block 20; (13, max 13)\nLiveIn: v43\l\ -// LiveOut: \l\nsstore(v43, 0)\l\ +// Block 20; (13, max 13)\nLiveIn: v44\l\ +// LiveOut: \l\nsstore(v44, 0)\l\ // "]; // Block1_20Exit [label="FunctionReturn[0]"]; // Block1_20 -> Block1_20Exit; // Block1_21 [label="\ -// Block 21; (14, max 14)\nLiveIn: v0,v1,v43\l\ -// LiveOut: v0,v1,v43\l\nsstore(65535, 255)\l\ +// Block 21; (14, max 14)\nLiveIn: v0,v1,v44\l\ +// LiveOut: v0,v1,v44\l\nsstore(65535, 255)\l\ // "]; // Block1_21 -> Block1_21Exit [arrowhead=none]; // Block1_21Exit [label="Jump" shape=oval]; diff --git a/test/libyul/yulSSAControlFlowGraph/complex2.yul b/test/libyul/yulSSAControlFlowGraph/complex2.yul index c3ea8b94f8aa..d4e8b432d608 100644 --- a/test/libyul/yulSSAControlFlowGraph/complex2.yul +++ b/test/libyul/yulSSAControlFlowGraph/complex2.yul @@ -79,36 +79,38 @@ // FunctionEntry_f_0 -> Block1_0; // Block1_0 [label="\ // Block 0; (0, max 17)\nLiveIn: v0,v1\l\ -// LiveOut: v0,v1\l\n"]; +// LiveOut: v0,v1,v4\l\nv4 := 42\l\ +// "]; // Block1_0 -> Block1_0Exit [arrowhead=none]; // Block1_0Exit [label="Jump" shape=oval]; // Block1_0Exit -> Block1_1 [style="solid"]; // Block1_1 [label="\ -// Block 1; (1, max 17)\nLiveIn: v0,v1,v5\l\ -// LiveOut: v0,v1,v5\l\nv5 := φ(\l\ -// Block 0 => 42,\l\ -// Block 21 => v43\l\ +// Block 1; (1, max 17)\nLiveIn: v0,v1,v6\l\ +// LiveOut: v0,v1,v6\l\nv6 := φ(\l\ +// Block 0 => v4,\l\ +// Block 21 => v44\l\ // )\l\ -// v6 := lt(v0, v5)\l\ +// v7 := lt(v0, v6)\l\ // "]; // Block1_1 -> Block1_1Exit; -// Block1_1Exit [label="{ If v6 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; +// Block1_1Exit [label="{ If v7 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; // Block1_1Exit:0 -> Block1_4 [style="solid"]; // Block1_1Exit:1 -> Block1_2 [style="solid"]; // Block1_2 [label="\ -// Block 2; (2, max 17)\nLiveIn: v0,v1,v5\l\ -// LiveOut: v0,v1,v5,v7\l\nv7 := mload(v5)\l\ -// v8 := eq(0, v7)\l\ +// Block 2; (2, max 17)\nLiveIn: v0,v1,v6\l\ +// LiveOut: v0,v1,v6,v8\l\nv8 := mload(v6)\l\ +// v9 := eq(0, v8)\l\ // "]; // Block1_2 -> Block1_2Exit; -// Block1_2Exit [label="{ If v8 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; +// Block1_2Exit [label="{ If v9 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; // Block1_2Exit:0 -> Block1_7 [style="solid"]; // Block1_2Exit:1 -> Block1_6 [style="solid"]; // Block1_4 [label="\ // Block 4; (4, max 4)\nLiveIn: \l\ -// LiveOut: \l\nsstore(3084, 12)\l\ +// LiveOut: v78\l\nsstore(3084, 12)\l\ +// v78 := 27\l\ // "]; -// Block1_4Exit [label="FunctionReturn[27]"]; +// Block1_4Exit [label="FunctionReturn[v78]"]; // Block1_4 -> Block1_4Exit; // Block1_6 [label="\ // Block 6; (3, max 4)\nLiveIn: \l\ @@ -118,11 +120,11 @@ // Block1_6Exit [label="Jump" shape=oval]; // Block1_6Exit -> Block1_4 [style="solid"]; // Block1_7 [label="\ -// Block 7; (5, max 17)\nLiveIn: v0,v1,v5,v7\l\ -// LiveOut: v0,v1,v5,v7\l\nv13 := eq(1, v7)\l\ +// Block 7; (5, max 17)\nLiveIn: v0,v1,v6,v8\l\ +// LiveOut: v0,v1,v6,v8\l\nv14 := eq(1, v8)\l\ // "]; // Block1_7 -> Block1_7Exit; -// Block1_7Exit [label="{ If v13 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; +// Block1_7Exit [label="{ If v14 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; // Block1_7Exit:0 -> Block1_10 [style="solid"]; // Block1_7Exit:1 -> Block1_9 [style="solid"]; // Block1_9 [label="\ @@ -132,11 +134,11 @@ // Block1_9Exit [label="FunctionReturn[0]"]; // Block1_9 -> Block1_9Exit; // Block1_10 [label="\ -// Block 10; (7, max 17)\nLiveIn: v0,v1,v5,v7\l\ -// LiveOut: v0,v1,v5,v7\l\nv20 := eq(2, v7)\l\ +// Block 10; (7, max 17)\nLiveIn: v0,v1,v6,v8\l\ +// LiveOut: v0,v1,v6,v8\l\nv21 := eq(2, v8)\l\ // "]; // Block1_10 -> Block1_10Exit; -// Block1_10Exit [label="{ If v20 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; +// Block1_10Exit [label="{ If v21 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; // Block1_10Exit:0 -> Block1_13 [style="solid"]; // Block1_10Exit:1 -> Block1_12 [style="solid"]; // Block1_12 [label="\ @@ -147,31 +149,31 @@ // Block1_12Exit [label="Terminated"]; // Block1_12 -> Block1_12Exit; // Block1_13 [label="\ -// Block 13; (9, max 17)\nLiveIn: v0,v1,v5,v7\l\ -// LiveOut: v0,v1,v5\l\nv25 := eq(3, v7)\l\ +// Block 13; (9, max 17)\nLiveIn: v0,v1,v6,v8\l\ +// LiveOut: v0,v1,v6\l\nv26 := eq(3, v8)\l\ // "]; // Block1_13 -> Block1_13Exit; -// Block1_13Exit [label="{ If v25 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; +// Block1_13Exit [label="{ If v26 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; // Block1_13Exit:0 -> Block1_16 [style="solid"]; // Block1_13Exit:1 -> Block1_15 [style="solid"]; // Block1_15 [label="\ -// Block 15; (10, max 14)\nLiveIn: v0,v1,v5\l\ -// LiveOut: v0,v1,v5\l\nsstore(2056, 8)\l\ +// Block 15; (10, max 14)\nLiveIn: v0,v1,v6\l\ +// LiveOut: v0,v1,v6\l\nsstore(2056, 8)\l\ // "]; // Block1_15 -> Block1_15Exit [arrowhead=none]; // Block1_15Exit [label="Jump" shape=oval]; // Block1_15Exit -> Block1_5 [style="solid"]; // Block1_16 [label="\ -// Block 16; (15, max 17)\nLiveIn: v0,v1,v5\l\ -// LiveOut: v0,v1,v5\l\nv29 := mload(v1)\l\ +// Block 16; (15, max 17)\nLiveIn: v0,v1,v6\l\ +// LiveOut: v0,v1,v6\l\nv30 := mload(v1)\l\ // "]; // Block1_16 -> Block1_16Exit; -// Block1_16Exit [label="{ If v29 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; +// Block1_16Exit [label="{ If v30 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; // Block1_16Exit:0 -> Block1_18 [style="solid"]; // Block1_16Exit:1 -> Block1_17 [style="solid"]; // Block1_5 [label="\ -// Block 5; (11, max 14)\nLiveIn: v0,v1,v5\l\ -// LiveOut: v0,v1,v5\l\nsstore(2827, 11)\l\ +// Block 5; (11, max 14)\nLiveIn: v0,v1,v6\l\ +// LiveOut: v0,v1,v6\l\nsstore(2827, 11)\l\ // "]; // Block1_5 -> Block1_5Exit [arrowhead=none]; // Block1_5Exit [label="Jump" shape=oval]; @@ -183,30 +185,30 @@ // Block1_17Exit [label="Terminated"]; // Block1_17 -> Block1_17Exit; // Block1_18 [label="\ -// Block 18; (17, max 17)\nLiveIn: v0,v1,v5\l\ -// LiveOut: v0,v1,v5\l\nsstore(2570, 10)\l\ +// Block 18; (17, max 17)\nLiveIn: v0,v1,v6\l\ +// LiveOut: v0,v1,v6\l\nsstore(2570, 10)\l\ // "]; // Block1_18 -> Block1_18Exit [arrowhead=none]; // Block1_18Exit [label="Jump" shape=oval]; // Block1_18Exit -> Block1_5 [style="solid"]; // Block1_3 [label="\ -// Block 3; (12, max 14)\nLiveIn: v0,v1,v5\l\ -// LiveOut: v0,v1,v43\l\nv43 := add(1, v5)\l\ -// v44 := calldataload(v43)\l\ +// Block 3; (12, max 14)\nLiveIn: v0,v1,v6\l\ +// LiveOut: v0,v1,v44\l\nv44 := add(1, v6)\l\ +// v45 := calldataload(v44)\l\ // "]; // Block1_3 -> Block1_3Exit; -// Block1_3Exit [label="{ If v44 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; +// Block1_3Exit [label="{ If v45 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; // Block1_3Exit:0 -> Block1_21 [style="solid"]; // Block1_3Exit:1 -> Block1_20 [style="solid"]; // Block1_20 [label="\ -// Block 20; (13, max 13)\nLiveIn: v43\l\ -// LiveOut: \l\nsstore(v43, 0)\l\ +// Block 20; (13, max 13)\nLiveIn: v44\l\ +// LiveOut: \l\nsstore(v44, 0)\l\ // "]; // Block1_20Exit [label="FunctionReturn[0]"]; // Block1_20 -> Block1_20Exit; // Block1_21 [label="\ -// Block 21; (14, max 14)\nLiveIn: v0,v1,v43\l\ -// LiveOut: v0,v1,v43\l\nsstore(65535, 255)\l\ +// Block 21; (14, max 14)\nLiveIn: v0,v1,v44\l\ +// LiveOut: v0,v1,v44\l\nsstore(65535, 255)\l\ // "]; // Block1_21 -> Block1_21Exit [arrowhead=none]; // Block1_21Exit [label="Jump" shape=oval]; diff --git a/test/libyul/yulSSAControlFlowGraph/function.yul b/test/libyul/yulSSAControlFlowGraph/function.yul index acf1a37aa43f..e2d8c1d52328 100644 --- a/test/libyul/yulSSAControlFlowGraph/function.yul +++ b/test/libyul/yulSSAControlFlowGraph/function.yul @@ -67,7 +67,9 @@ // FunctionEntry_i_0 -> Block4_0; // Block4_0 [label="\ // Block 0; (0, max 0)\nLiveIn: \l\ -// LiveOut: \l\n"]; -// Block4_0Exit [label="FunctionReturn[514, 771]"]; +// LiveOut: v2,v4\l\nv2 := 514\l\ +// v4 := 771\l\ +// "]; +// Block4_0Exit [label="FunctionReturn[v2, v4]"]; // Block4_0 -> Block4_0Exit; // } diff --git a/test/libyul/yulSSAControlFlowGraph/nested_for.yul b/test/libyul/yulSSAControlFlowGraph/nested_for.yul index b088e3b55ed8..f57a5ca29a5b 100644 --- a/test/libyul/yulSSAControlFlowGraph/nested_for.yul +++ b/test/libyul/yulSSAControlFlowGraph/nested_for.yul @@ -27,25 +27,27 @@ // Entry0 -> Block0_0; // Block0_0 [label="\ // Block 0; (0, max 24)\nLiveIn: \l\ -// LiveOut: \l\n"]; +// LiveOut: v1\l\nv1 := 0\l\ +// "]; // Block0_0 -> Block0_0Exit [arrowhead=none]; // Block0_0Exit [label="Jump" shape=oval]; // Block0_0Exit -> Block0_1 [style="solid"]; // Block0_1 [label="\ -// Block 1; (1, max 24)\nLiveIn: v2\l\ -// LiveOut: v2\l\nv2 := φ(\l\ -// Block 0 => 0,\l\ -// Block 3 => v36\l\ +// Block 1; (1, max 24)\nLiveIn: v3\l\ +// LiveOut: v3\l\nv3 := φ(\l\ +// Block 0 => v1,\l\ +// Block 3 => v41\l\ // )\l\ -// v3 := lt(3, v2)\l\ +// v4 := lt(3, v3)\l\ // "]; // Block0_1 -> Block0_1Exit; -// Block0_1Exit [label="{ If v3 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; +// Block0_1Exit [label="{ If v4 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; // Block0_1Exit:0 -> Block0_4 [style="solid"]; // Block0_1Exit:1 -> Block0_2 [style="solid"]; // Block0_2 [label="\ -// Block 2; (2, max 23)\nLiveIn: v2\l\ -// LiveOut: v2\l\n"]; +// Block 2; (2, max 23)\nLiveIn: v3\l\ +// LiveOut: v3,v5\l\nv5 := 0\l\ +// "]; // Block0_2 -> Block0_2Exit [arrowhead=none]; // Block0_2Exit [label="Jump" shape=oval]; // Block0_2Exit -> Block0_5 [style="solid"]; @@ -55,164 +57,167 @@ // Block0_4Exit [label="MainExit"]; // Block0_4 -> Block0_4Exit; // Block0_5 [label="\ -// Block 5; (3, max 23)\nLiveIn: v2,v4\l\ -// LiveOut: v2,v4\l\nv4 := φ(\l\ -// Block 2 => 0,\l\ -// Block 7 => v35\l\ +// Block 5; (3, max 23)\nLiveIn: v3,v6\l\ +// LiveOut: v3,v6\l\nv6 := φ(\l\ +// Block 2 => v5,\l\ +// Block 7 => v40\l\ // )\l\ -// v5 := lt(3, v4)\l\ +// v7 := lt(3, v6)\l\ // "]; // Block0_5 -> Block0_5Exit; -// Block0_5Exit [label="{ If v5 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; +// Block0_5Exit [label="{ If v7 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; // Block0_5Exit:0 -> Block0_8 [style="solid"]; // Block0_5Exit:1 -> Block0_6 [style="solid"]; // Block0_6 [label="\ -// Block 6; (4, max 21)\nLiveIn: v2,v4\l\ -// LiveOut: v2,v4\l\n"]; +// Block 6; (4, max 21)\nLiveIn: v3,v6\l\ +// LiveOut: v3,v6,v8\l\nv8 := 0\l\ +// "]; // Block0_6 -> Block0_6Exit [arrowhead=none]; // Block0_6Exit [label="Jump" shape=oval]; // Block0_6Exit -> Block0_9 [style="solid"]; // Block0_8 [label="\ -// Block 8; (22, max 23)\nLiveIn: v2\l\ -// LiveOut: v2\l\n"]; +// Block 8; (22, max 23)\nLiveIn: v3\l\ +// LiveOut: v3\l\n"]; // Block0_8 -> Block0_8Exit [arrowhead=none]; // Block0_8Exit [label="Jump" shape=oval]; // Block0_8Exit -> Block0_3 [style="solid"]; // Block0_9 [label="\ -// Block 9; (5, max 21)\nLiveIn: v2,v4,v6\l\ -// LiveOut: v2,v4,v6\l\nv6 := φ(\l\ -// Block 6 => 0,\l\ -// Block 11 => v31\l\ +// Block 9; (5, max 21)\nLiveIn: v3,v6,v9\l\ +// LiveOut: v3,v6,v9\l\nv9 := φ(\l\ +// Block 6 => v8,\l\ +// Block 11 => v36\l\ // )\l\ -// v7 := lt(3, v6)\l\ +// v10 := lt(3, v9)\l\ // "]; // Block0_9 -> Block0_9Exit; -// Block0_9Exit [label="{ If v7 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; +// Block0_9Exit [label="{ If v10 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; // Block0_9Exit:0 -> Block0_12 [style="solid"]; // Block0_9Exit:1 -> Block0_10 [style="solid"]; // Block0_3 [label="\ -// Block 3; (23, max 23)\nLiveIn: v2\l\ -// LiveOut: v36\l\nv36 := add(1, v2)\l\ +// Block 3; (23, max 23)\nLiveIn: v3\l\ +// LiveOut: v41\l\nv41 := add(1, v3)\l\ // "]; // Block0_3 -> Block0_3Exit [arrowhead=none]; // Block0_3Exit [label="Jump" shape=oval]; // Block0_3Exit -> Block0_1 [style="dashed"]; // Block0_10 [label="\ -// Block 10; (6, max 19)\nLiveIn: v2,v4,v6\l\ -// LiveOut: v2,v4,v6\l\n"]; +// Block 10; (6, max 19)\nLiveIn: v3,v6,v9\l\ +// LiveOut: v3,v6,v9\l\n"]; // Block0_10 -> Block0_10Exit; // Block0_10Exit [label="{ If 0 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; // Block0_10Exit:0 -> Block0_14 [style="solid"]; // Block0_10Exit:1 -> Block0_13 [style="solid"]; // Block0_12 [label="\ -// Block 12; (20, max 21)\nLiveIn: v2,v4\l\ -// LiveOut: v2,v4\l\n"]; +// Block 12; (20, max 21)\nLiveIn: v3,v6\l\ +// LiveOut: v3,v6\l\n"]; // Block0_12 -> Block0_12Exit [arrowhead=none]; // Block0_12Exit [label="Jump" shape=oval]; // Block0_12Exit -> Block0_7 [style="solid"]; // Block0_13 [label="\ -// Block 13; (7, max 19)\nLiveIn: v2,v4,v6\l\ -// LiveOut: v2,v4,v6\l\n"]; +// Block 13; (7, max 19)\nLiveIn: v3,v6,v9\l\ +// LiveOut: v3,v6,v9,v11\l\nv11 := 0\l\ +// "]; // Block0_13 -> Block0_13Exit [arrowhead=none]; // Block0_13Exit [label="Jump" shape=oval]; // Block0_13Exit -> Block0_15 [style="solid"]; // Block0_14 [label="\ -// Block 14; (12, max 19)\nLiveIn: v2,v4,v6\l\ -// LiveOut: v2,v4,v6\l\n"]; +// Block 14; (12, max 19)\nLiveIn: v3,v6,v9\l\ +// LiveOut: v3,v6,v9\l\n"]; // Block0_14 -> Block0_14Exit; // Block0_14Exit [label="{ If 1 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; // Block0_14Exit:0 -> Block0_20 [style="solid"]; // Block0_14Exit:1 -> Block0_19 [style="solid"]; // Block0_7 [label="\ -// Block 7; (21, max 21)\nLiveIn: v2,v4\l\ -// LiveOut: v2,v35\l\nv35 := add(1, v4)\l\ +// Block 7; (21, max 21)\nLiveIn: v3,v6\l\ +// LiveOut: v3,v40\l\nv40 := add(1, v6)\l\ // "]; // Block0_7 -> Block0_7Exit [arrowhead=none]; // Block0_7Exit [label="Jump" shape=oval]; // Block0_7Exit -> Block0_5 [style="dashed"]; // Block0_15 [label="\ -// Block 15; (8, max 19)\nLiveIn: v2,v4,v6,v8\l\ -// LiveOut: v2,v4,v6,v8\l\nv8 := φ(\l\ -// Block 13 => 0,\l\ -// Block 17 => v16\l\ +// Block 15; (8, max 19)\nLiveIn: v3,v6,v9,v12\l\ +// LiveOut: v3,v6,v9,v12\l\nv12 := φ(\l\ +// Block 13 => v11,\l\ +// Block 17 => v20\l\ // )\l\ -// v9 := lt(3, v8)\l\ +// v13 := lt(3, v12)\l\ // "]; // Block0_15 -> Block0_15Exit; -// Block0_15Exit [label="{ If v9 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; +// Block0_15Exit [label="{ If v13 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; // Block0_15Exit:0 -> Block0_18 [style="solid"]; // Block0_15Exit:1 -> Block0_16 [style="solid"]; // Block0_19 [label="\ -// Block 19; (13, max 19)\nLiveIn: v2,v4,v6\l\ -// LiveOut: v2,v4,v6\l\n"]; +// Block 19; (13, max 19)\nLiveIn: v3,v6,v9\l\ +// LiveOut: v3,v6,v9,v23\l\nv23 := 0\l\ +// "]; // Block0_19 -> Block0_19Exit [arrowhead=none]; // Block0_19Exit [label="Jump" shape=oval]; // Block0_19Exit -> Block0_21 [style="solid"]; // Block0_20 [label="\ -// Block 20; (18, max 19)\nLiveIn: v2,v4,v6\l\ -// LiveOut: v2,v4,v6\l\n"]; +// Block 20; (18, max 19)\nLiveIn: v3,v6,v9\l\ +// LiveOut: v3,v6,v9\l\n"]; // Block0_20 -> Block0_20Exit [arrowhead=none]; // Block0_20Exit [label="Jump" shape=oval]; // Block0_20Exit -> Block0_11 [style="solid"]; // Block0_16 [label="\ -// Block 16; (9, max 10)\nLiveIn: v2,v4,v6,v8\l\ -// LiveOut: v2,v4,v6,v8\l\nv13 := add(v4, v2)\l\ -// v14 := add(v6, v13)\l\ -// sstore(v14, v8)\l\ +// Block 16; (9, max 10)\nLiveIn: v3,v6,v9,v12\l\ +// LiveOut: v3,v6,v9,v12\l\nv17 := add(v6, v3)\l\ +// v18 := add(v9, v17)\l\ +// sstore(v18, v12)\l\ // "]; // Block0_16 -> Block0_16Exit [arrowhead=none]; // Block0_16Exit [label="Jump" shape=oval]; // Block0_16Exit -> Block0_17 [style="solid"]; // Block0_18 [label="\ -// Block 18; (11, max 19)\nLiveIn: v2,v4,v6\l\ -// LiveOut: v2,v4,v6\l\n"]; +// Block 18; (11, max 19)\nLiveIn: v3,v6,v9\l\ +// LiveOut: v3,v6,v9\l\n"]; // Block0_18 -> Block0_18Exit [arrowhead=none]; // Block0_18Exit [label="Jump" shape=oval]; // Block0_18Exit -> Block0_14 [style="solid"]; // Block0_21 [label="\ -// Block 21; (14, max 19)\nLiveIn: v2,v4,v6,v19\l\ -// LiveOut: v2,v4,v6,v19\l\nv19 := φ(\l\ -// Block 19 => 0,\l\ -// Block 23 => v26\l\ +// Block 21; (14, max 19)\nLiveIn: v3,v6,v9,v24\l\ +// LiveOut: v3,v6,v9,v24\l\nv24 := φ(\l\ +// Block 19 => v23,\l\ +// Block 23 => v31\l\ // )\l\ -// v20 := lt(3, v19)\l\ +// v25 := lt(3, v24)\l\ // "]; // Block0_21 -> Block0_21Exit; -// Block0_21Exit [label="{ If v20 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; +// Block0_21Exit [label="{ If v25 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; // Block0_21Exit:0 -> Block0_24 [style="solid"]; // Block0_21Exit:1 -> Block0_22 [style="solid"]; // Block0_11 [label="\ -// Block 11; (19, max 19)\nLiveIn: v2,v4,v6\l\ -// LiveOut: v2,v4,v31\l\nv31 := add(1, v6)\l\ +// Block 11; (19, max 19)\nLiveIn: v3,v6,v9\l\ +// LiveOut: v3,v6,v36\l\nv36 := add(1, v9)\l\ // "]; // Block0_11 -> Block0_11Exit [arrowhead=none]; // Block0_11Exit [label="Jump" shape=oval]; // Block0_11Exit -> Block0_9 [style="dashed"]; // Block0_17 [label="\ -// Block 17; (10, max 10)\nLiveIn: v2,v4,v6,v8\l\ -// LiveOut: v2,v4,v6,v16\l\nv16 := add(1, v8)\l\ +// Block 17; (10, max 10)\nLiveIn: v3,v6,v9,v12\l\ +// LiveOut: v3,v6,v9,v20\l\nv20 := add(1, v12)\l\ // "]; // Block0_17 -> Block0_17Exit [arrowhead=none]; // Block0_17Exit [label="Jump" shape=oval]; // Block0_17Exit -> Block0_15 [style="dashed"]; // Block0_22 [label="\ -// Block 22; (15, max 16)\nLiveIn: v2,v4,v6,v19\l\ -// LiveOut: v2,v4,v6,v19\l\nv24 := add(v4, v2)\l\ -// v25 := add(v6, v24)\l\ -// sstore(v25, v19)\l\ +// Block 22; (15, max 16)\nLiveIn: v3,v6,v9,v24\l\ +// LiveOut: v3,v6,v9,v24\l\nv29 := add(v6, v3)\l\ +// v30 := add(v9, v29)\l\ +// sstore(v30, v24)\l\ // "]; // Block0_22 -> Block0_22Exit [arrowhead=none]; // Block0_22Exit [label="Jump" shape=oval]; // Block0_22Exit -> Block0_23 [style="solid"]; // Block0_24 [label="\ -// Block 24; (17, max 19)\nLiveIn: v2,v4,v6\l\ -// LiveOut: v2,v4,v6\l\n"]; +// Block 24; (17, max 19)\nLiveIn: v3,v6,v9\l\ +// LiveOut: v3,v6,v9\l\n"]; // Block0_24 -> Block0_24Exit [arrowhead=none]; // Block0_24Exit [label="Jump" shape=oval]; // Block0_24Exit -> Block0_20 [style="solid"]; // Block0_23 [label="\ -// Block 23; (16, max 16)\nLiveIn: v2,v4,v6,v19\l\ -// LiveOut: v2,v4,v6,v26\l\nv26 := add(1, v19)\l\ +// Block 23; (16, max 16)\nLiveIn: v3,v6,v9,v24\l\ +// LiveOut: v3,v6,v9,v31\l\nv31 := add(1, v24)\l\ // "]; // Block0_23 -> Block0_23Exit [arrowhead=none]; // Block0_23Exit [label="Jump" shape=oval]; diff --git a/test/libyul/yulSSAControlFlowGraph/nested_function.yul b/test/libyul/yulSSAControlFlowGraph/nested_function.yul index acda15ce81a5..037e1f006c45 100644 --- a/test/libyul/yulSSAControlFlowGraph/nested_function.yul +++ b/test/libyul/yulSSAControlFlowGraph/nested_function.yul @@ -78,8 +78,9 @@ // FunctionEntry_w_0 -> Block4_0; // Block4_0 [label="\ // Block 0; (0, max 0)\nLiveIn: \l\ -// LiveOut: \l\n"]; -// Block4_0Exit [label="FunctionReturn[1]"]; +// LiveOut: v2\l\nv2 := 1\l\ +// "]; +// Block4_0Exit [label="FunctionReturn[v2]"]; // Block4_0 -> Block4_0Exit; // FunctionEntry_v_0 [label="function v: // r := v()"]; @@ -95,8 +96,9 @@ // FunctionEntry_w_0 -> Block6_0; // Block6_0 [label="\ // Block 0; (0, max 0)\nLiveIn: \l\ -// LiveOut: \l\n"]; -// Block6_0Exit [label="FunctionReturn[17]"]; +// LiveOut: v2\l\nv2 := 17\l\ +// "]; +// Block6_0Exit [label="FunctionReturn[v2]"]; // Block6_0 -> Block6_0Exit; // FunctionEntry_cycle1_0 [label="function cycle1: // r := cycle1()"]; From fe890f4d519677c1b49ac5e2cd62d19e7bc2a01c Mon Sep 17 00:00:00 2001 From: fhf <710790342@qq.com> Date: Mon, 28 Apr 2025 21:33:44 +0800 Subject: [PATCH 0963/1022] update docs: fix the position of flyout menu --- docs/index.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/index.rst b/docs/index.rst index 11765d3be559..73295404d475 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -86,7 +86,7 @@ Community contributors help translate this documentation into several languages. Note that they have varying degrees of completeness and up-to-dateness. The English version stands as a reference. -You can switch between languages by clicking on the flyout menu in the bottom-left corner +You can switch between languages by clicking on the flyout menu in the bottom-right corner and selecting the preferred language. * `Chinese `_ From e0daa3c05df3fa2b921362fa4161aaa40530b84d Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Tue, 13 May 2025 11:47:04 +0200 Subject: [PATCH 0964/1022] assign zero value to not explicitly initialized variables during ssa cfg construction --- .../evm/SSAControlFlowGraphBuilder.cpp | 5 --- .../default_initialized_variable.yul | 42 +++++++++++++++++++ 2 files changed, 42 insertions(+), 5 deletions(-) create mode 100644 test/libyul/yulSSAControlFlowGraph/default_initialized_variable.yul diff --git a/libyul/backends/evm/SSAControlFlowGraphBuilder.cpp b/libyul/backends/evm/SSAControlFlowGraphBuilder.cpp index 19308617cd5f..101fd2eb361f 100644 --- a/libyul/backends/evm/SSAControlFlowGraphBuilder.cpp +++ b/libyul/backends/evm/SSAControlFlowGraphBuilder.cpp @@ -273,11 +273,6 @@ void SSAControlFlowGraphBuilder::operator()(Assignment const& _assignment) void SSAControlFlowGraphBuilder::operator()(VariableDeclaration const& _variableDeclaration) { - // if we have no value (like in `let a` without right-hand side), we can just skip this. the variable(s) will be - // added when first needed - if (!_variableDeclaration.value) - return; - assign( _variableDeclaration.variables | ranges::views::transform([&](auto& _var) { return std::ref(lookupVariable(_var.name)); }) | ranges::to, _variableDeclaration.value.get() diff --git a/test/libyul/yulSSAControlFlowGraph/default_initialized_variable.yul b/test/libyul/yulSSAControlFlowGraph/default_initialized_variable.yul new file mode 100644 index 000000000000..92ea33382b10 --- /dev/null +++ b/test/libyul/yulSSAControlFlowGraph/default_initialized_variable.yul @@ -0,0 +1,42 @@ +{ + let x + if mload(42) { + x := 5 + } + sstore(x, x) +} +// ---- +// digraph SSACFG { +// nodesep=0.7; +// graph[fontname="DejaVu Sans"] +// node[shape=box,fontname="DejaVu Sans"]; +// +// Entry0 [label="Entry"]; +// Entry0 -> Block0_0; +// Block0_0 [label="\ +// Block 0; (0, max 2)\nLiveIn: \l\ +// LiveOut: v1\l\nv1 := 0\l\ +// v3 := mload(42)\l\ +// "]; +// Block0_0 -> Block0_0Exit; +// Block0_0Exit [label="{ If v3 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; +// Block0_0Exit:0 -> Block0_2 [style="solid"]; +// Block0_0Exit:1 -> Block0_1 [style="solid"]; +// Block0_1 [label="\ +// Block 1; (1, max 2)\nLiveIn: \l\ +// LiveOut: v5\l\nv5 := 5\l\ +// "]; +// Block0_1 -> Block0_1Exit [arrowhead=none]; +// Block0_1Exit [label="Jump" shape=oval]; +// Block0_1Exit -> Block0_2 [style="solid"]; +// Block0_2 [label="\ +// Block 2; (2, max 2)\nLiveIn: v6\l\ +// LiveOut: \l\nv6 := φ(\l\ +// Block 0 => v1,\l\ +// Block 1 => v5\l\ +// )\l\ +// sstore(v6, v6)\l\ +// "]; +// Block0_2Exit [label="MainExit"]; +// Block0_2 -> Block0_2Exit; +// } From 27c16d0734a09f67c001c1f8b746ae78b6a1f7cd Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Wed, 14 May 2025 10:33:41 +0200 Subject: [PATCH 0965/1022] update fmtlib to 11.2.0 --- deps/fmtlib | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps/fmtlib b/deps/fmtlib index 123913715afe..40626af88bd7 160000 --- a/deps/fmtlib +++ b/deps/fmtlib @@ -1 +1 @@ -Subproject commit 123913715afeb8a437e6388b4473fcc4753e1c9a +Subproject commit 40626af88bd7df9a5fb80be7b25ac85b122d6c21 From 287b66a15e37a35e859f93018b7d0a87dd45d1c7 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Wed, 9 Apr 2025 12:18:53 +0200 Subject: [PATCH 0966/1022] Add instruction location info to eof assembly --- libevmasm/Assembly.cpp | 64 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 63 insertions(+), 1 deletion(-) diff --git a/libevmasm/Assembly.cpp b/libevmasm/Assembly.cpp index 9dd203a0f802..670165a0bc5d 100644 --- a/libevmasm/Assembly.cpp +++ b/libevmasm/Assembly.cpp @@ -53,6 +53,54 @@ using namespace solidity::evmasm; using namespace solidity::langutil; using namespace solidity::util; +namespace +{ + +/// Produces instruction location info in RAII style. When an assembly instruction is added to the bytecode, +/// this class can be instantiated in that scope. It will record the current bytecode size (before addition) +/// and, at destruction time, record the new bytecode size. This information is then added to an external +/// instruction locations vector. +/// If the instruction decomposes into multiple individual evm instructions, `emit` can be +/// called for all but the last one (which will be emitted by the destructor). +class InstructionLocationEmitter +{ +public: + InstructionLocationEmitter( + std::vector& _instructionLocations, + bytes const& _bytecode, + size_t const _assemblyItemIndex + ): + m_instructionLocations(_instructionLocations), + m_bytecode(_bytecode), + m_assemblyItemIndex(_assemblyItemIndex), + m_instructionLocationStart(_bytecode.size()) + {} + + ~InstructionLocationEmitter() + { + emit(); + } + + void emit() + { + auto const end = m_bytecode.size(); + m_instructionLocations.push_back(LinkerObject::InstructionLocation{ + .start = m_instructionLocationStart, + .end = end, + .assemblyItemIndex = m_assemblyItemIndex + }); + m_instructionLocationStart = end; + } + +private: + std::vector& m_instructionLocations; + bytes const& m_bytecode; + size_t const m_assemblyItemIndex{}; + size_t m_instructionLocationStart{}; +}; + +} + std::map> Assembly::s_sharedSourceNames; AssemblyItem const& Assembly::append(AssemblyItem _i) @@ -1606,9 +1654,17 @@ LinkerObject const& Assembly::assembleEOF() const for (auto&& [codeSectionIndex, codeSection]: m_codeSections | ranges::views::enumerate) { auto const sectionStart = ret.bytecode.size(); + + std::vector instructionLocations; + instructionLocations.reserve(codeSection.items.size()); + solAssert(!codeSection.items.empty(), "Empty code section."); - for (AssemblyItem const& item: codeSection.items) + + for (auto const& [assemblyItemIndex, item]: codeSection.items | ranges::views::enumerate) { + // collect instruction locations via side effects + InstructionLocationEmitter instructionLocationEmitter {instructionLocations, ret.bytecode, assemblyItemIndex}; + // store position of the invalid jump destination if (item.type() != Tag && m_tagPositionsInBytecode[0] == std::numeric_limits::max()) m_tagPositionsInBytecode[0] = ret.bytecode.size(); @@ -1724,6 +1780,12 @@ LinkerObject const& Assembly::assembleEOF() const "Code section too large for EOF." ); setBigEndianUint16(ret.bytecode, codeSectionSizePositions[codeSectionIndex], ret.bytecode.size() - sectionStart); + + ret.codeSectionLocations.push_back(LinkerObject::CodeSectionLocation{ + .start = sectionStart, + .end = ret.bytecode.size(), + .instructionLocations = std::move(instructionLocations) + }); } for (auto const& [refPos, tagId]: tagRef) From a5e20d2dc05b42f27bb0fe1092502b1a799a014c Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Thu, 10 Apr 2025 10:54:11 +0200 Subject: [PATCH 0967/1022] Refactor legacy assemble to also use RAII instruction location construction --- libevmasm/Assembly.cpp | 158 +++++++++++++++-------------------------- 1 file changed, 57 insertions(+), 101 deletions(-) diff --git a/libevmasm/Assembly.cpp b/libevmasm/Assembly.cpp index 670165a0bc5d..019683c9d4fd 100644 --- a/libevmasm/Assembly.cpp +++ b/libevmasm/Assembly.cpp @@ -1329,22 +1329,12 @@ LinkerObject const& Assembly::assembleLegacy() const uint8_t dataRefPush = static_cast(pushInstruction(bytesPerDataRef)); LinkerObject::CodeSectionLocation codeSectionLocation; + codeSectionLocation.instructionLocations.reserve(items.size()); codeSectionLocation.start = 0; - size_t assemblyItemIndex = 0; - auto assembleInstruction = [&](auto&& _addInstruction) { - size_t start = ret.bytecode.size(); - _addInstruction(); - size_t end = ret.bytecode.size(); - codeSectionLocation.instructionLocations.emplace_back( - LinkerObject::InstructionLocation{ - .start = start, - .end = end, - .assemblyItemIndex = assemblyItemIndex - } - ); - }; - for (AssemblyItem const& item: items) + for (auto const& [assemblyItemIndex, item]: items | ranges::views::enumerate) { + // collect instruction locations via side effects + InstructionLocationEmitter instructionLocationEmitter(codeSectionLocation.instructionLocations, ret.bytecode, assemblyItemIndex); // store position of the invalid jump destination if (item.type() != Tag && m_tagPositionsInBytecode[0] == std::numeric_limits::max()) m_tagPositionsInBytecode[0] = ret.bytecode.size(); @@ -1352,81 +1342,59 @@ LinkerObject const& Assembly::assembleLegacy() const switch (item.type()) { case Operation: - assembleInstruction([&](){ - ret.bytecode += assembleOperation(item); - }); + ret.bytecode += assembleOperation(item); break; case Push: - assembleInstruction([&](){ - ret.bytecode += assemblePush(item); - }); + ret.bytecode += assemblePush(item); break; case PushTag: - { - assembleInstruction([&](){ - ret.bytecode.push_back(tagPush); - tagRefs[ret.bytecode.size()] = item.splitForeignPushTag(); - ret.bytecode.resize(ret.bytecode.size() + bytesPerTag); - }); + ret.bytecode.push_back(tagPush); + tagRefs[ret.bytecode.size()] = item.splitForeignPushTag(); + ret.bytecode.resize(ret.bytecode.size() + bytesPerTag); break; - } case PushData: - assembleInstruction([&]() { - ret.bytecode.push_back(dataRefPush); - dataRefs.insert(std::make_pair(h256(item.data()), ret.bytecode.size())); - ret.bytecode.resize(ret.bytecode.size() + bytesPerDataRef); - }); + ret.bytecode.push_back(dataRefPush); + dataRefs.insert(std::make_pair(h256(item.data()), ret.bytecode.size())); + ret.bytecode.resize(ret.bytecode.size() + bytesPerDataRef); break; case PushSub: - assembleInstruction([&]() { - assertThrow(item.data() <= std::numeric_limits::max(), AssemblyException, ""); - ret.bytecode.push_back(dataRefPush); - subRefs.insert(std::make_pair(static_cast(item.data()), ret.bytecode.size())); - ret.bytecode.resize(ret.bytecode.size() + bytesPerDataRef); - }); + assertThrow(item.data() <= std::numeric_limits::max(), AssemblyException, ""); + ret.bytecode.push_back(dataRefPush); + subRefs.insert(std::make_pair(static_cast(item.data()), ret.bytecode.size())); + ret.bytecode.resize(ret.bytecode.size() + bytesPerDataRef); break; case PushSubSize: { - assembleInstruction([&](){ - assertThrow(item.data() <= std::numeric_limits::max(), AssemblyException, ""); - auto s = subAssemblyById(static_cast(item.data()))->assemble().bytecode.size(); - item.setPushedValue(u256(s)); - unsigned b = std::max(1, numberEncodingSize(s)); - ret.bytecode.push_back(static_cast(pushInstruction(b))); - ret.bytecode.resize(ret.bytecode.size() + b); - bytesRef byr(&ret.bytecode.back() + 1 - b, b); - toBigEndian(s, byr); - }); + assertThrow(item.data() <= std::numeric_limits::max(), AssemblyException, ""); + auto s = subAssemblyById(static_cast(item.data()))->assemble().bytecode.size(); + item.setPushedValue(u256(s)); + unsigned b = std::max(1, numberEncodingSize(s)); + ret.bytecode.push_back(static_cast(pushInstruction(b))); + ret.bytecode.resize(ret.bytecode.size() + b); + bytesRef byr(&ret.bytecode.back() + 1 - b, b); + toBigEndian(s, byr); break; } case PushProgramSize: - { - assembleInstruction([&](){ - ret.bytecode.push_back(dataRefPush); - sizeRefs.push_back(static_cast(ret.bytecode.size())); - ret.bytecode.resize(ret.bytecode.size() + bytesPerDataRef); - }); + ret.bytecode.push_back(dataRefPush); + sizeRefs.push_back(static_cast(ret.bytecode.size())); + ret.bytecode.resize(ret.bytecode.size() + bytesPerDataRef); break; - } case PushLibraryAddress: { - assembleInstruction([&]() { - auto const [bytecode, linkRef] = assemblePushLibraryAddress(item, ret.bytecode.size()); - ret.bytecode += bytecode; - ret.linkReferences.insert(linkRef); - }); + auto const [bytecode, linkRef] = assemblePushLibraryAddress(item, ret.bytecode.size()); + ret.bytecode += bytecode; + ret.linkReferences.insert(linkRef); break; } case PushImmutable: - assembleInstruction([&]() { - ret.bytecode.push_back(static_cast(Instruction::PUSH32)); - // Maps keccak back to the "identifier" std::string of that immutable. - ret.immutableReferences[item.data()].first = m_immutables.at(item.data()); - // Record the bytecode offset of the PUSH32 argument. - ret.immutableReferences[item.data()].second.emplace_back(ret.bytecode.size()); - // Advance bytecode by 32 bytes (default initialized). - ret.bytecode.resize(ret.bytecode.size() + 32); - }); + ret.bytecode.push_back(static_cast(Instruction::PUSH32)); + // Maps keccak back to the "identifier" std::string of that immutable. + ret.immutableReferences[item.data()].first = m_immutables.at(item.data()); + // Record the bytecode offset of the PUSH32 argument. + ret.immutableReferences[item.data()].second.emplace_back(ret.bytecode.size()); + // Advance bytecode by 32 bytes (default initialized). + ret.bytecode.resize(ret.bytecode.size() + 32); break; case VerbatimBytecode: ret.bytecode += assembleVerbatimBytecode(item); @@ -1439,53 +1407,41 @@ LinkerObject const& Assembly::assembleLegacy() const { if (i != offsets.size() - 1) { - assembleInstruction([&]() { - ret.bytecode.push_back(uint8_t(Instruction::DUP2)); - }); - assembleInstruction([&]() { - ret.bytecode.push_back(uint8_t(Instruction::DUP2)); - }); + ret.bytecode.push_back(static_cast(Instruction::DUP2)); + // This item type decomposes into multiple evm instructions, so we manually call emit() + instructionLocationEmitter.emit(); + ret.bytecode.push_back(static_cast(Instruction::DUP2)); + instructionLocationEmitter.emit(); } - assembleInstruction([&]() { - // TODO: should we make use of the constant optimizer methods for pushing the offsets? - bytes offsetBytes = toCompactBigEndian(u256(offsets[i])); - ret.bytecode.push_back(static_cast(pushInstruction(static_cast(offsetBytes.size())))); - ret.bytecode += offsetBytes; - }); - assembleInstruction([&]() { - ret.bytecode.push_back(uint8_t(Instruction::ADD)); - }); - assembleInstruction([&]() { - ret.bytecode.push_back(uint8_t(Instruction::MSTORE)); - }); + // TODO: should we make use of the constant optimizer methods for pushing the offsets? + bytes offsetBytes = toCompactBigEndian(u256(offsets[i])); + ret.bytecode.push_back(static_cast(pushInstruction(static_cast(offsetBytes.size())))); + ret.bytecode += offsetBytes; + instructionLocationEmitter.emit(); + ret.bytecode.push_back(static_cast(Instruction::ADD)); + instructionLocationEmitter.emit(); + ret.bytecode.push_back(static_cast(Instruction::MSTORE)); + // No emit needed here, it's taken care of by the destructor of instructionLocationEmitter. } if (offsets.empty()) { - assembleInstruction([&]() { - ret.bytecode.push_back(uint8_t(Instruction::POP)); - }); - assembleInstruction([&]() { - ret.bytecode.push_back(uint8_t(Instruction::POP)); - }); + ret.bytecode.push_back(static_cast(Instruction::POP)); + instructionLocationEmitter.emit(); + ret.bytecode.push_back(static_cast(Instruction::POP)); + // no emit needed here, it's taken care of by the destructor of instructionLocationEmitter } immutableReferencesBySub.erase(item.data()); break; } case PushDeployTimeAddress: - assembleInstruction([&]() { - ret.bytecode += assemblePushDeployTimeAddress(); - }); + ret.bytecode += assemblePushDeployTimeAddress(); break; case Tag: - assembleInstruction([&](){ - ret.bytecode += assembleTag(item, ret.bytecode.size(), true); - }); + ret.bytecode += assembleTag(item, ret.bytecode.size(), true); break; default: solAssert(false, "Unexpected opcode while assembling."); } - - ++assemblyItemIndex; } codeSectionLocation.end = ret.bytecode.size(); From 6ae63c268c1b3ce94aa9230f40bf24f465cb6a8f Mon Sep 17 00:00:00 2001 From: Matheus Aguiar Date: Wed, 14 May 2025 15:26:37 -0300 Subject: [PATCH 0968/1022] Mention that dots are still allowed in variables/function names in yul-only mode --- docs/assembly.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/assembly.rst b/docs/assembly.rst index c1af2907aed8..3f00ab6a8a79 100644 --- a/docs/assembly.rst +++ b/docs/assembly.rst @@ -216,6 +216,7 @@ shadow any declaration visible in the scope of the inline assembly block Since Solidity 0.7.0, variables and functions declared inside the inline assembly block may not contain ``.``, but using ``.`` is valid to access Solidity variables from outside the inline assembly block. +However, it is still valid to use dots if you use Solidity in Yul-only mode. Things to Avoid --------------- From 54979c198c2519611d8491afd8fd41b8a588da05 Mon Sep 17 00:00:00 2001 From: Henry Chu Date: Tue, 20 May 2025 12:36:43 +0800 Subject: [PATCH 0969/1022] Add nullptr checking for rename logging --- libsolidity/lsp/RenameSymbol.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/libsolidity/lsp/RenameSymbol.cpp b/libsolidity/lsp/RenameSymbol.cpp index 497ee50fb451..b832029e45cc 100644 --- a/libsolidity/lsp/RenameSymbol.cpp +++ b/libsolidity/lsp/RenameSymbol.cpp @@ -65,7 +65,8 @@ void RenameSymbol::operator()(MessageID _id, Json const& _args) .translateLineColumnToPosition(lineColumn); solAssert(cursorBytePosition.has_value(), "Expected source pos"); - extractNameAndDeclaration(*sourceNode, *cursorBytePosition); + if (sourceNode != nullptr) + extractNameAndDeclaration(*sourceNode, *cursorBytePosition); // Find all source units using this symbol for (auto const& [name, content]: fileRepository().sourceUnits()) @@ -156,7 +157,8 @@ void RenameSymbol::extractNameAndDeclaration(ASTNode const& _node, int _cursorBy else solAssert(false, "Unexpected ASTNODE id: " + std::to_string(_node.id())); - lspDebug(fmt::format("Goal: rename '{}', loc: {}-{}", m_symbolName, m_declarationToRename->nameLocation().start, m_declarationToRename->nameLocation().end)); + if (m_declarationToRename != nullptr) + lspDebug(fmt::format("Goal: rename '{}', loc: {}-{}", m_symbolName, m_declarationToRename->nameLocation().start, m_declarationToRename->nameLocation().end)); } void RenameSymbol::extractNameAndDeclaration(ImportDirective const& _importDirective, int _cursorBytePosition) From 446610b6db27e16517fb51a18bd99d79e0463ae1 Mon Sep 17 00:00:00 2001 From: James Niken Date: Thu, 22 May 2025 21:19:48 +0200 Subject: [PATCH 0970/1022] Replace Reference StandardCompiler.cpp --- test/libsolidity/StandardCompiler.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/libsolidity/StandardCompiler.cpp b/test/libsolidity/StandardCompiler.cpp index 5360a2778677..62c72ad45c07 100644 --- a/test/libsolidity/StandardCompiler.cpp +++ b/test/libsolidity/StandardCompiler.cpp @@ -822,7 +822,7 @@ BOOST_AUTO_TEST_CASE(filename_with_colon) "language": "Solidity", "settings": { "outputSelection": { - "http://github.com/ethereum/solidity/std/StandardToken.sol": { + "https://github.com/ethereum/solidity/blob/develop/test/compilationTests/gnosis/Tokens/StandardToken.sol": { "A": [ "abi" ] @@ -830,7 +830,7 @@ BOOST_AUTO_TEST_CASE(filename_with_colon) } }, "sources": { - "http://github.com/ethereum/solidity/std/StandardToken.sol": { + "https://github.com/ethereum/solidity/blob/develop/test/compilationTests/gnosis/Tokens/StandardToken.sol": { "content": "contract A { }" } } @@ -838,7 +838,7 @@ BOOST_AUTO_TEST_CASE(filename_with_colon) )"; Json result = compile(input); BOOST_CHECK(containsAtMostWarnings(result)); - Json contract = getContractResult(result, "http://github.com/ethereum/solidity/std/StandardToken.sol", "A"); + Json contract = getContractResult(result, "https://github.com/ethereum/solidity/blob/develop/test/compilationTests/gnosis/Tokens/StandardToken.sol", "A"); BOOST_CHECK(contract.is_object()); BOOST_CHECK(contract["abi"].is_array()); BOOST_CHECK_EQUAL(util::jsonCompactPrint(contract["abi"]), "[]"); From e96a23725afa6bd7bfb09d0f4f134ab8ae705444 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Fri, 7 Feb 2025 12:00:36 +0100 Subject: [PATCH 0971/1022] Yul: add label id dispenser --- libyul/CMakeLists.txt | 2 + libyul/optimiser/LabelIDDispenser.cpp | 167 ++++++++++++++++++++++++++ libyul/optimiser/LabelIDDispenser.h | 73 +++++++++++ 3 files changed, 242 insertions(+) create mode 100644 libyul/optimiser/LabelIDDispenser.cpp create mode 100644 libyul/optimiser/LabelIDDispenser.h diff --git a/libyul/CMakeLists.txt b/libyul/CMakeLists.txt index fc3302a82332..68756fca92f0 100644 --- a/libyul/CMakeLists.txt +++ b/libyul/CMakeLists.txt @@ -145,6 +145,8 @@ add_library(yul optimiser/InlinableExpressionFunctionFinder.h optimiser/KnowledgeBase.cpp optimiser/KnowledgeBase.h + optimiser/LabelIDDispenser.cpp + optimiser/LabelIDDispenser.h optimiser/LoadResolver.cpp optimiser/LoadResolver.h optimiser/LoopInvariantCodeMotion.cpp diff --git a/libyul/optimiser/LabelIDDispenser.cpp b/libyul/optimiser/LabelIDDispenser.cpp new file mode 100644 index 000000000000..6d4e476cb67f --- /dev/null +++ b/libyul/optimiser/LabelIDDispenser.cpp @@ -0,0 +1,167 @@ +/* + This file is part of solidity. + + solidity is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + solidity is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with solidity. If not, see . +*/ +// SPDX-License-Identifier: GPL-3.0 + +#include + +#include + +#include + +#include +#include +#include + +using namespace solidity::yul; + +namespace +{ +bool isInvalidLabel( + std::string_view const _label, + std::set> const& _reservedLabels, + Dialect const& _dialect +) +{ + return isRestrictedIdentifier(_dialect, _label) || _reservedLabels.contains(_label); +} +} + +LabelIDDispenser::LabelIDDispenser(ASTLabelRegistry const& _labels, std::set const& _reservedLabels): + m_labels(_labels), + m_reservedLabels(_reservedLabels.begin(), _reservedLabels.end()) +{} + +LabelIDDispenser::LabelID LabelIDDispenser::newID(LabelID const _parent) +{ + auto const parentLabelID = resolveParentLabelID(_parent); + yulAssert(!m_labels.ghost(parentLabelID), "Use newGhost to add new ghosts."); + m_idToLabelMapping.push_back(parentLabelID); + return m_idToLabelMapping.size() + m_labels.maxID(); +} + +LabelIDDispenser::LabelID LabelIDDispenser::newGhost() +{ + m_idToLabelMapping.push_back(ASTLabelRegistry::ghostLabelIndex()); + return m_idToLabelMapping.size() + m_labels.maxID(); +} + +LabelIDDispenser::LabelID LabelIDDispenser::resolveParentLabelID(LabelID _id) const +{ + yulAssert(_id < m_idToLabelMapping.size() + m_labels.maxID() + 1, "ID exceeds bounds."); + // bigger than maxID means that the input label id was spawned by this dispenser + if (_id > m_labels.maxID()) + _id = m_idToLabelMapping[_id - m_labels.maxID() - 1]; + yulAssert( + _id <= m_labels.maxID() && !m_labels.unused(_id), + "We can have at most one level of indirection and the derived-from label cannot be unused." + ); + return _id; +} + +bool LabelIDDispenser::ghost(LabelID const _id) const +{ + yulAssert(_id < m_idToLabelMapping.size() + m_labels.maxID() + 1, "ID exceeds bounds."); + if (_id > m_labels.maxID()) + return m_idToLabelMapping[_id - m_labels.maxID() - 1] == ASTLabelRegistry::ghostLabelIndex(); + + return m_labels.ghost(_id); +} + +ASTLabelRegistry LabelIDDispenser::generateNewLabels(Dialect const& _dialect) const +{ + auto const usedIDs = + ranges::views::iota(static_cast(1), m_idToLabelMapping.size() + m_labels.maxID() + 1) | + ranges::to; + return generateNewLabels(usedIDs, _dialect); +} + +ASTLabelRegistry LabelIDDispenser::generateNewLabels(std::set const& _usedIDs, Dialect const& _dialect) const +{ + if (_usedIDs.empty()) + return {}; + + auto const& originalLabels = m_labels.labels(); + + std::vector reusedLabels (originalLabels.size()); + // this means that everything that is derived from empty needs to be generated + reusedLabels[0] = true; + + // start with the empty label + std::vector labels{""}; + labels.reserve(originalLabels.size()+1); + + // 0 maps to "" + yulAssert(!_usedIDs.empty()); + std::vector idToLabelMap (*std::prev(_usedIDs.end()) + 1); + + std::set> alreadyDefinedLabels = m_reservedLabels; + + // we record which labels have to be newly generated, some we can just take over from the existing registry + std::vector toGenerate; + for (auto const& id: _usedIDs) + { + if (ghost(id)) + { + idToLabelMap[id] = ASTLabelRegistry::ghostLabelIndex(); + continue; + } + + auto const parentLabelID = resolveParentLabelID(id); + + auto const originalLabelIndex = m_labels.idToLabelIndex(parentLabelID); + std::string const& originalLabel = originalLabels[originalLabelIndex]; + + // It is important that the used ids are in ascending order to ensure that ids which occur in the provided AST + // and have unchanged IDs will have their labels reused first, before anything derived from it gets assigned + // said label. + static_assert(std::is_same_v, std::set>); + + // if we haven't already reused the label, check that either the id didn't change, then we can just + // take over the old label, otherwise check that it is a valid label and then reuse + if (!reusedLabels[originalLabelIndex] && (parentLabelID == id || !isInvalidLabel(originalLabel, m_reservedLabels, _dialect))) + { + labels.push_back(originalLabel); + idToLabelMap[id] = labels.size() - 1; + alreadyDefinedLabels.insert(originalLabel); + reusedLabels[originalLabelIndex] = true; + } + else + toGenerate.push_back(id); + } + + std::vector labelSuffixes(m_labels.maxID() + 1, 1); + for (auto const& id: toGenerate) + { + yulAssert(!ghost(id)); + + auto const parentLabelID = resolveParentLabelID(id); + auto const parentLabelIndex = m_labels.idToLabelIndex(parentLabelID); + auto const& parentLabel = originalLabels[parentLabelIndex]; + + std::string generatedLabel = parentLabel; + do + { + generatedLabel = format(FMT_COMPILE("{}_{}"), parentLabel, labelSuffixes[parentLabelID]++); + } while (isInvalidLabel(generatedLabel, alreadyDefinedLabels, _dialect)); + + labels.push_back(generatedLabel); + idToLabelMap[id] = labels.size() - 1; + alreadyDefinedLabels.insert(generatedLabel); + } + + return ASTLabelRegistry{std::move(labels), std::move(idToLabelMap)}; +} diff --git a/libyul/optimiser/LabelIDDispenser.h b/libyul/optimiser/LabelIDDispenser.h new file mode 100644 index 000000000000..0168fadcfe28 --- /dev/null +++ b/libyul/optimiser/LabelIDDispenser.h @@ -0,0 +1,73 @@ +/* + This file is part of solidity. + + solidity is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + solidity is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with solidity. If not, see . +*/ +// SPDX-License-Identifier: GPL-3.0 + +#pragma once + +#include + +#include +#include + +namespace solidity::yul +{ + +class Dialect; + +/// Can spawn new `LabelID`s which depend on `LabelID`s from a parent label registry. Once generation is completed, +/// a new `ASTLabelRegistry` can be generated based on the used subset of spawned and original IDs. +class LabelIDDispenser +{ +public: + using LabelID = ASTLabelRegistry::LabelID; + /// A set of reserved labels may be provided, which is excluded when generating new labels. If a reserved label + /// already appears in the label registry and is used as-is in the AST, it will be reused despite it being + /// provided here. + /// Original labels will always be preserved even if they are not valid Yul identifiers. + explicit LabelIDDispenser( + ASTLabelRegistry const& _labels, + std::set const& _reserved = {} + ); + + ASTLabelRegistry const& labels() const { return m_labels; } + + /// Spawns a new LabelID which depends on a parent LabelID that will be used for its string representation. + /// Parent must not be unused. For spawning new ghost labels, `newGhost` must be used. + LabelID newID(LabelID _parent = 0); + /// Spawns a new ghost label. + LabelID newGhost(); + + /// Creates a new label registry based on the added labels. + /// Ghost IDs are always preserved, as these are not referenced in the AST. + /// Labels are guaranteed to be valid and not reserved if and only if they were valid and not reserved in the + /// original registry. No new invalid and/or reserved labels are introduced. + ASTLabelRegistry generateNewLabels(std::set const& _usedIDs, Dialect const& _dialect) const; + ASTLabelRegistry generateNewLabels(Dialect const& _dialect) const; +private: + /// For newly added label IDs, this yields the parent ID which is contained in the provided registry. + /// For label IDs which already are not new, this function is the identity. + LabelID resolveParentLabelID(LabelID _id) const; + bool ghost(LabelID _id) const; + + ASTLabelRegistry const& m_labels; + /// Reserved labels, equipped with the transparent less comparison operator to be able to handle string_view. + std::set> m_reservedLabels; + /// Contains references to parent label IDs. Indices are new IDs offset by `m_labels.maxID() + 1`. + std::vector m_idToLabelMapping; +}; + +} From 30caf713e20ac5fc90f347677d9dad779ab7ae45 Mon Sep 17 00:00:00 2001 From: r0qs <457348+r0qs@users.noreply.github.com> Date: Sun, 1 Jun 2025 10:47:18 +0200 Subject: [PATCH 0972/1022] Remove deprecated whitespace in literal operator declaration --- liblangutil/Exceptions.h | 2 +- libyul/YulString.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/liblangutil/Exceptions.h b/liblangutil/Exceptions.h index c441a6d2f962..2f2fdcb4c997 100644 --- a/liblangutil/Exceptions.h +++ b/liblangutil/Exceptions.h @@ -163,7 +163,7 @@ struct ErrorId bool operator!=(ErrorId const& _rhs) const { return !(*this == _rhs); } bool operator<(ErrorId const& _rhs) const { return error < _rhs.error; } }; -constexpr ErrorId operator"" _error(unsigned long long _error) { return ErrorId{ _error }; } +constexpr ErrorId operator""_error(unsigned long long _error) { return ErrorId{ _error }; } class Error: virtual public util::Exception { diff --git a/libyul/YulString.h b/libyul/YulString.h index 329825a4465b..80d58f3ed788 100644 --- a/libyul/YulString.h +++ b/libyul/YulString.h @@ -163,7 +163,7 @@ class YulString YulStringRepository::Handle m_handle{ 0, YulStringRepository::emptyHash() }; }; -inline YulString operator "" _yulname(char const* _string, std::size_t _size) +inline YulString operator""_yulname(char const* _string, std::size_t _size) { return YulString(std::string_view(_string, _size)); } From fe1a69005bd1e434420eb4628f95aad1ebb0b47d Mon Sep 17 00:00:00 2001 From: "fuder.eth" Date: Tue, 13 May 2025 15:55:17 +0300 Subject: [PATCH 0973/1022] Rename emitted emmited to emitted emited to emitted --- ...ed_in_base_contract.sol => event_emitted_in_base_contract.sol} | 0 ...emmited.sol => event_from_aggregated_contract_not_emitted.sol} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename test/libsolidity/ABIJson/{event_emited_in_base_contract.sol => event_emitted_in_base_contract.sol} (100%) rename test/libsolidity/ABIJson/{event_from_aggregated_contract_not_emmited.sol => event_from_aggregated_contract_not_emitted.sol} (100%) diff --git a/test/libsolidity/ABIJson/event_emited_in_base_contract.sol b/test/libsolidity/ABIJson/event_emitted_in_base_contract.sol similarity index 100% rename from test/libsolidity/ABIJson/event_emited_in_base_contract.sol rename to test/libsolidity/ABIJson/event_emitted_in_base_contract.sol diff --git a/test/libsolidity/ABIJson/event_from_aggregated_contract_not_emmited.sol b/test/libsolidity/ABIJson/event_from_aggregated_contract_not_emitted.sol similarity index 100% rename from test/libsolidity/ABIJson/event_from_aggregated_contract_not_emmited.sol rename to test/libsolidity/ABIJson/event_from_aggregated_contract_not_emitted.sol From c5fc3ddb6aa5e986beb0048077bc15eedf5fb876 Mon Sep 17 00:00:00 2001 From: FT <140458077+zeevick10@users.noreply.github.com> Date: Wed, 7 May 2025 10:22:15 +0200 Subject: [PATCH 0974/1022] Update TestFileParserTests.cpp --- test/libsolidity/util/TestFileParserTests.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/libsolidity/util/TestFileParserTests.cpp b/test/libsolidity/util/TestFileParserTests.cpp index 4bb4aed3aced..c0badfb21b0f 100644 --- a/test/libsolidity/util/TestFileParserTests.cpp +++ b/test/libsolidity/util/TestFileParserTests.cpp @@ -798,7 +798,7 @@ BOOST_AUTO_TEST_CASE(call_arguments_tuple_invalid_empty) BOOST_REQUIRE_THROW(parse(source), TestParserError); } -BOOST_AUTO_TEST_CASE(call_arguments_tuple_invalid_parantheses) +BOOST_AUTO_TEST_CASE(call_arguments_tuple_invalid_parentheses) { char const* source = R"( // f((uint8,() -> FAILURE From 2b1a9e5063639071c596436ef6dae7ec9c72a056 Mon Sep 17 00:00:00 2001 From: FT <140458077+zeevick10@users.noreply.github.com> Date: Wed, 7 May 2025 10:29:02 +0200 Subject: [PATCH 0975/1022] Update protoToAbiV2.cpp --- test/tools/ossfuzz/protoToAbiV2.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/tools/ossfuzz/protoToAbiV2.cpp b/test/tools/ossfuzz/protoToAbiV2.cpp index 1511390ebb35..693dbe79bc15 100644 --- a/test/tools/ossfuzz/protoToAbiV2.cpp +++ b/test/tools/ossfuzz/protoToAbiV2.cpp @@ -5,7 +5,7 @@ /// Convenience macros /// Returns a valid Solidity integer width w such that 8 <= w <= 256. -#define INTWIDTH(z, n, _ununsed) BOOST_PP_MUL(BOOST_PP_ADD(n, 1), 8) +#define INTWIDTH(z, n, _unused) BOOST_PP_MUL(BOOST_PP_ADD(n, 1), 8) /// Using declaration that aliases long boost multiprecision types with /// s(u) where is a valid Solidity integer width and "s" /// stands for "signed" and "u" for "unsigned". From 403b548d300a721ad47b11e9e216255548314341 Mon Sep 17 00:00:00 2001 From: Nikola Matic Date: Wed, 4 Jun 2025 15:10:28 +0200 Subject: [PATCH 0976/1022] Fix shellcheck script --- scripts/yul_coverage.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/scripts/yul_coverage.sh b/scripts/yul_coverage.sh index b2b16675c532..73c5084fd852 100755 --- a/scripts/yul_coverage.sh +++ b/scripts/yul_coverage.sh @@ -111,18 +111,18 @@ function test_file if OUTPUT=$("${SOLC}" --ir "${SOL_FILE}" 2>&1); then SUCCESS+=("${SOL_FILE}") - show_output_if ${SHOW_SUCCESSFUL} + show_output_if "${SHOW_SUCCESSFUL}" else FAILED+=("${SOL_FILE}") if [[ ${OUTPUT} == *"UnimplementedFeatureError"* ]]; then UNIMPLEMENTED_FEATURE_ERRORS+=("${SOL_FILE}") - show_output_if ${SHOW_UNIMPLEMENTED_FEATURE_ERRORS} + show_output_if "${SHOW_UNIMPLEMENTED_FEATURE_ERRORS}" elif [[ ${OUTPUT} == *"InternalCompilerError"* ]]; then INTERNAL_COMPILER_ERRORS+=("${SOL_FILE}") - show_output_if ${SHOW_INTERNAL_COMPILER_ERRORS} + show_output_if "${SHOW_INTERNAL_COMPILER_ERRORS}" else OTHER_ERRORS+=("${SOL_FILE}") - show_output_if ${SHOW_OTHER_ERRORS} + show_output_if "${SHOW_OTHER_ERRORS}" fi fi } From bcddfb4a346da9e9a5dcf5e8e0ac610d71d28ec7 Mon Sep 17 00:00:00 2001 From: otc group Date: Wed, 4 Jun 2025 19:08:21 +0200 Subject: [PATCH 0977/1022] fix typo in file's name --- ...call_parent.sol => overridden_function_static_call_parent.sol} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename test/libsolidity/smtCheckerTests/inheritance/{overriden_function_static_call_parent.sol => overridden_function_static_call_parent.sol} (100%) diff --git a/test/libsolidity/smtCheckerTests/inheritance/overriden_function_static_call_parent.sol b/test/libsolidity/smtCheckerTests/inheritance/overridden_function_static_call_parent.sol similarity index 100% rename from test/libsolidity/smtCheckerTests/inheritance/overriden_function_static_call_parent.sol rename to test/libsolidity/smtCheckerTests/inheritance/overridden_function_static_call_parent.sol From 725f8f7f477f27ff699840183c583ee93a0fd022 Mon Sep 17 00:00:00 2001 From: David Klank <155117116+davidjsonn@users.noreply.github.com> Date: Thu, 5 Jun 2025 17:31:44 +0300 Subject: [PATCH 0978/1022] replace 404 reference Natspec.cpp --- libsolidity/interface/Natspec.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libsolidity/interface/Natspec.cpp b/libsolidity/interface/Natspec.cpp index a0da7b54bb5e..a997ef09d9c6 100644 --- a/libsolidity/interface/Natspec.cpp +++ b/libsolidity/interface/Natspec.cpp @@ -19,7 +19,7 @@ * @author Lefteris * @date 2014 * Takes the parsed AST and produces the Natspec documentation: - * https://github.com/ethereum/wiki/wiki/Ethereum-Natural-Specification-Format + * https://docs.soliditylang.org/en/latest/natspec-format.html * * Can generally deal with JSON files */ From 7b011232925d4482072315e627d0ab4c2c3bec97 Mon Sep 17 00:00:00 2001 From: Kendra Karol Sevilla Date: Fri, 6 Jun 2025 23:47:38 +0200 Subject: [PATCH 0979/1022] fix typo in comment --- libsolidity/ast/AST.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libsolidity/ast/AST.h b/libsolidity/ast/AST.h index 9c7cbbded2cc..a4e19582b250 100644 --- a/libsolidity/ast/AST.h +++ b/libsolidity/ast/AST.h @@ -1151,7 +1151,7 @@ class VariableDeclaration: public Declaration, public StructurallyDocumented bool isCallableOrCatchParameter() const; /// @returns true if this variable is a return parameter of a function. bool isReturnParameter() const; - /// @returns true if this variable is a parameter of the success or failure clausse + /// @returns true if this variable is a parameter of the success or failure clause /// of a try/catch statement. bool isTryCatchParameter() const; /// @returns true if this variable is a local variable or return parameter. From d75bd3983ce39e1113886c3453c49cd34b73c640 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Sat, 12 Apr 2025 07:30:38 +0200 Subject: [PATCH 0980/1022] Ethdebug requires assembly instance --- libevmasm/Ethdebug.cpp | 2 +- libevmasm/Ethdebug.h | 2 +- libsolidity/interface/CompilerStack.cpp | 5 ++++- libyul/YulStack.cpp | 4 ++-- test/libevmasm/Assembler.cpp | 4 ++-- 5 files changed, 10 insertions(+), 7 deletions(-) diff --git a/libevmasm/Ethdebug.cpp b/libevmasm/Ethdebug.cpp index 6e635ef57952..0251600066ce 100644 --- a/libevmasm/Ethdebug.cpp +++ b/libevmasm/Ethdebug.cpp @@ -77,7 +77,7 @@ Json programInstructions(Assembly const& _assembly, LinkerObject const& _linkerO } // anonymous namespace -Json ethdebug::program(std::string_view _name, unsigned _sourceId, Assembly const* _assembly, LinkerObject const& _linkerObject) +Json ethdebug::program(std::string_view _name, unsigned _sourceId, Assembly const& _assembly, LinkerObject const& _linkerObject) { Json result = Json::object(); result["contract"] = Json::object(); diff --git a/libevmasm/Ethdebug.h b/libevmasm/Ethdebug.h index 72ac16037969..fdb693b190c4 100644 --- a/libevmasm/Ethdebug.h +++ b/libevmasm/Ethdebug.h @@ -27,7 +27,7 @@ namespace solidity::evmasm::ethdebug { // returns ethdebug/format/program. -Json program(std::string_view _name, unsigned _sourceId, Assembly const* _assembly, LinkerObject const& _linkerObject); +Json program(std::string_view _name, unsigned _sourceId, Assembly const& _assembly, LinkerObject const& _linkerObject); // returns ethdebug/format/info/resources Json resources(std::vector const& _sources, std::string const& _version); diff --git a/libsolidity/interface/CompilerStack.cpp b/libsolidity/interface/CompilerStack.cpp index 1b0a299f7291..975ed3c1982d 100644 --- a/libsolidity/interface/CompilerStack.cpp +++ b/libsolidity/interface/CompilerStack.cpp @@ -1216,8 +1216,11 @@ Json CompilerStack::ethdebug(Contract const& _contract, bool _runtime) const solUnimplementedAssert(!isExperimentalSolidity()); evmasm::LinkerObject const& object = _runtime ? _contract.runtimeObject : _contract.object; std::shared_ptr const& assembly = _runtime ? _contract.evmRuntimeAssembly : _contract.evmAssembly; + if (!assembly) + return {}; + solAssert(sourceIndices().contains(_contract.contract->sourceUnitName())); - return evmasm::ethdebug::program(_contract.contract->name(), sourceIndices()[_contract.contract->sourceUnitName()], assembly.get(), object); + return evmasm::ethdebug::program(_contract.contract->name(), sourceIndices()[_contract.contract->sourceUnitName()], *assembly, object); } bytes CompilerStack::cborMetadata(std::string const& _contractName, bool _forIR) const diff --git a/libyul/YulStack.cpp b/libyul/YulStack.cpp index 85709b987c59..b59b4781fe19 100644 --- a/libyul/YulStack.cpp +++ b/libyul/YulStack.cpp @@ -275,14 +275,14 @@ YulStack::assembleWithDeployed(std::optional _deployName) ); } if (debugInfoSelection().ethdebug) - creationObject.ethdebug = evmasm::ethdebug::program(creationObject.assembly->name(), 0, creationObject.assembly.get(), *creationObject.bytecode.get()); + creationObject.ethdebug = evmasm::ethdebug::program(creationObject.assembly->name(), 0, *creationObject.assembly, *creationObject.bytecode); if (deployedAssembly) { deployedObject.bytecode = std::make_shared(deployedAssembly->assemble()); deployedObject.assembly = deployedAssembly; if (debugInfoSelection().ethdebug) - deployedObject.ethdebug = evmasm::ethdebug::program(deployedObject.assembly->name(), 0, deployedObject.assembly.get(), *deployedObject.bytecode.get()); + deployedObject.ethdebug = evmasm::ethdebug::program(deployedObject.assembly->name(), 0, *deployedObject.assembly, *deployedObject.bytecode); solAssert(deployedAssembly->codeSections().size() == 1); deployedObject.sourceMappings = std::make_unique( evmasm::AssemblyItem::computeSourceMapping( diff --git a/test/libevmasm/Assembler.cpp b/test/libevmasm/Assembler.cpp index 6a41f7a7394c..32855cfbc211 100644 --- a/test/libevmasm/Assembler.cpp +++ b/test/libevmasm/Assembler.cpp @@ -434,7 +434,7 @@ BOOST_AUTO_TEST_CASE(ethdebug_program_last_instruction_with_immediate_arguments) assembly.append(AssemblyItem{0x11223344}); LinkerObject output = assembly.assemble(); - Json const program = ethdebug::program("", 0, &assembly, output); + Json const program = ethdebug::program("", 0, assembly, output); BOOST_REQUIRE(program["instructions"].size() == 1); BOOST_REQUIRE(program["instructions"][0]["operation"]["mnemonic"] == "PUSH4"); BOOST_REQUIRE(program["instructions"][0]["operation"]["arguments"][0] == "0x11223344"); @@ -445,7 +445,7 @@ BOOST_AUTO_TEST_CASE(ethdebug_program_last_instruction_with_immediate_arguments) assembly.append(AssemblyItem{0x1122334455}); LinkerObject output = assembly.assemble(); - Json const program = ethdebug::program("", 0, &assembly, output); + Json const program = ethdebug::program("", 0, assembly, output); BOOST_REQUIRE(program["instructions"].size() == 2); BOOST_REQUIRE(program["instructions"][0]["operation"]["mnemonic"] == "PUSH0"); BOOST_REQUIRE(!program["instructions"][0]["operation"].contains("arguments")); From 43b0f062d9b68ffbd5fc2d558e33a2bb2f76732d Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Tue, 8 Apr 2025 16:41:37 +0200 Subject: [PATCH 0981/1022] Ethdebug instructions output over multiple code sections --- Changelog.md | 2 +- libevmasm/Ethdebug.cpp | 85 ++++++++++++++++++++++++++++-------------- 2 files changed, 57 insertions(+), 30 deletions(-) diff --git a/Changelog.md b/Changelog.md index 967e548814ef..a2e814bda43c 100644 --- a/Changelog.md +++ b/Changelog.md @@ -4,7 +4,7 @@ Language Features: Compiler Features: - +* ethdebug: Experimental support for instructions and source locations under EOF. Bugfixes: diff --git a/libevmasm/Ethdebug.cpp b/libevmasm/Ethdebug.cpp index 0251600066ce..0a4c56ddd0a0 100644 --- a/libevmasm/Ethdebug.cpp +++ b/libevmasm/Ethdebug.cpp @@ -18,6 +18,8 @@ #include +#include + using namespace solidity; using namespace solidity::evmasm; using namespace solidity::evmasm::ethdebug; @@ -25,25 +27,35 @@ using namespace solidity::evmasm::ethdebug; namespace { -Json programInstructions(Assembly const& _assembly, LinkerObject const& _linkerObject, unsigned _sourceId) +std::vector codeSectionInstructions(Assembly const& _assembly, LinkerObject const& _linkerObject, unsigned _sourceId, size_t const _codeSectionIndex) { - solUnimplementedAssert(_assembly.eofVersion() == std::nullopt, "ethdebug does not yet support EOF."); - solUnimplementedAssert(_assembly.codeSections().size() == 1, "ethdebug does not yet support multiple code-sections."); - for (auto const& instruction: _assembly.codeSections()[0].items) - solUnimplementedAssert(instruction.type() != VerbatimBytecode, "Verbatim bytecode is currently not supported by ethdebug."); - - solAssert(_linkerObject.codeSectionLocations.size() == 1); - solAssert(_linkerObject.codeSectionLocations[0].end <= _linkerObject.bytecode.size()); - Json instructions = Json::array(); - for (size_t i = 0; i < _linkerObject.codeSectionLocations[0].instructionLocations.size(); ++i) + solAssert(_codeSectionIndex < _linkerObject.codeSectionLocations.size()); + solAssert(_codeSectionIndex < _assembly.codeSections().size()); + auto const& locations = _linkerObject.codeSectionLocations[_codeSectionIndex]; + auto const& codeSection = _assembly.codeSections().at(_codeSectionIndex); + + std::vector instructions; + instructions.reserve(codeSection.items.size()); + + bool const codeSectionContainsVerbatim = ranges::any_of( + codeSection.items, + [](auto const& _instruction) { return _instruction.type() == VerbatimBytecode; } + ); + solUnimplementedAssert(!codeSectionContainsVerbatim, "Verbatim bytecode is currently not supported by ethdebug."); + + for (auto const& currentInstruction: locations.instructionLocations) { - LinkerObject::InstructionLocation currentInstruction = _linkerObject.codeSectionLocations[0].instructionLocations[i]; - size_t start = currentInstruction.start; - size_t end = currentInstruction.end; - size_t assemblyItemIndex = currentInstruction.assemblyItemIndex; + size_t const start = currentInstruction.start; + size_t const end = currentInstruction.end; + + // some instructions do not contribute to the bytecode + if (start == end) + continue; + + size_t const assemblyItemIndex = currentInstruction.assemblyItemIndex; solAssert(end <= _linkerObject.bytecode.size()); solAssert(start < end); - solAssert(assemblyItemIndex < _assembly.codeSections().at(0).items.size()); + solAssert(assemblyItemIndex < codeSection.items.size()); Json operation = Json::object(); operation["mnemonic"] = instructionInfo(static_cast(_linkerObject.bytecode[start]), _assembly.evmVersion()).name; static size_t constexpr instructionSize = 1; @@ -56,25 +68,40 @@ Json programInstructions(Assembly const& _assembly, LinkerObject const& _linkerO solAssert(!argumentData.empty()); operation["arguments"] = Json::array({util::toHex(argumentData, util::HexPrefix::Add)}); } - langutil::SourceLocation const& location = _assembly.codeSections().at(0).items.at(assemblyItemIndex).location(); - Json instruction = Json::object(); - instruction["offset"] = start; - instruction["operation"] = operation; - - instruction["context"] = Json::object(); - instruction["context"]["code"] = Json::object(); - instruction["context"]["code"]["source"] = Json::object(); - instruction["context"]["code"]["source"]["id"] = static_cast(_sourceId); - - instruction["context"]["code"]["range"] = Json::object(); - instruction["context"]["code"]["range"]["offset"] = location.start; - instruction["context"]["code"]["range"]["length"] = location.end - location.start; - instructions.emplace_back(instruction); + langutil::SourceLocation const& location = codeSection.items.at(assemblyItemIndex).location(); + instructions.emplace_back(Json{ + { "offset", start }, + {"operation", operation }, + { + "context", { + "code", { + "source", { + { "id", static_cast(_sourceId) }, + }, + "range", { + { "offset", location.start }, + { "length", location.end - location.start } + } + } + } + } + }); } return instructions; } +Json programInstructions(Assembly const& _assembly, LinkerObject const& _linkerObject, unsigned _sourceId) +{ + auto const numCodeSections = _assembly.codeSections().size(); + solAssert(numCodeSections == _linkerObject.codeSectionLocations.size()); + + std::vector instructionInfo; + for (size_t codeSectionIndex = 0; codeSectionIndex < numCodeSections; ++codeSectionIndex) + instructionInfo += codeSectionInstructions(_assembly, _linkerObject, _sourceId, codeSectionIndex); + return instructionInfo; +} + } // anonymous namespace Json ethdebug::program(std::string_view _name, unsigned _sourceId, Assembly const& _assembly, LinkerObject const& _linkerObject) From 4ea1d47423ca28907bef2610a81c0031e43b1c34 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Fri, 11 Apr 2025 10:48:54 +0200 Subject: [PATCH 0982/1022] Add ethdebug schema --- libevmasm/CMakeLists.txt | 2 + libevmasm/EthdebugSchema.cpp | 143 +++++++++++++++++++++++++++++ libevmasm/EthdebugSchema.h | 172 +++++++++++++++++++++++++++++++++++ 3 files changed, 317 insertions(+) create mode 100644 libevmasm/EthdebugSchema.cpp create mode 100644 libevmasm/EthdebugSchema.h diff --git a/libevmasm/CMakeLists.txt b/libevmasm/CMakeLists.txt index a7441b85e264..74aaeb6c293b 100644 --- a/libevmasm/CMakeLists.txt +++ b/libevmasm/CMakeLists.txt @@ -6,6 +6,8 @@ set(sources AssemblyItem.h Ethdebug.cpp Ethdebug.h + EthdebugSchema.cpp + EthdebugSchema.h EVMAssemblyStack.cpp EVMAssemblyStack.h BlockDeduplicator.cpp diff --git a/libevmasm/EthdebugSchema.cpp b/libevmasm/EthdebugSchema.cpp new file mode 100644 index 000000000000..c54b7167f53e --- /dev/null +++ b/libevmasm/EthdebugSchema.cpp @@ -0,0 +1,143 @@ +/* + This file is part of solidity. + + solidity is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + solidity is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with solidity. If not, see . +*/ +// SPDX-License-Identifier: GPL-3.0 + +#include + +#include +#include + +using namespace solidity; +using namespace solidity::evmasm::ethdebug; + +void schema::data::to_json(Json& _json, HexValue const& _hexValue) +{ + _json = util::toHex(_hexValue.value, util::HexPrefix::Add); +} + +void schema::data::to_json(Json& _json, Unsigned const& _unsigned) +{ + std::visit(util::GenericVisitor{ + [&](HexValue const& _hexValue) { _json = _hexValue; }, + [&](std::uint64_t const _value) { _json = _value; } + }, _unsigned.value); +} + +void schema::materials::to_json(Json& _json, ID const& _id) +{ + std::visit(util::GenericVisitor{ + [&](std::string const& _hexValue) { _json = _hexValue; }, + [&](std::uint64_t const _value) { _json = _value; } + }, _id.value); +} + +void schema::materials::to_json(Json& _json, Reference const& _source) +{ + _json["id"] = _source.id; + if (_source.type) + _json["type"] = *_source.type == Reference::Type::Compilation ? "compilation" : "source"; +} + +void schema::materials::to_json(Json& _json, SourceRange::Range const& _range) +{ + _json["length"] = _range.length; + _json["offset"] = _range.offset; +} + + +void schema::materials::to_json(Json& _json, SourceRange const& _sourceRange) +{ + _json["source"] = _sourceRange.source; + if (_sourceRange.range) + _json["range"] = *_sourceRange.range; +} + +void schema::to_json(Json& _json, Program::Contract const& _contract) +{ + if (_contract.name) + _json["name"] = *_contract.name; + _json["definition"] = _contract.definition; +} + +void schema::program::to_json(Json& _json, Context::Variable const& _contextVariable) +{ + auto const numProperties = + _contextVariable.identifier.has_value() + + _contextVariable.declaration.has_value(); + solRequire(numProperties >= 1, EthdebugException, "Context variable has no properties."); + if (_contextVariable.identifier) + { + solRequire(!_contextVariable.identifier->empty(), EthdebugException, "Variable identifier must not be empty."); + _json["identifier"] = *_contextVariable.identifier; + } + if (_contextVariable.declaration) + _json["declaration"] = *_contextVariable.declaration; +} + +void schema::program::to_json(Json& _json, Context const& _context) +{ + solRequire(_context.code.has_value() + _context.remark.has_value() + _context.variables.has_value() >= 1, EthdebugException, "Context needs >=1 properties."); + if (_context.code) + _json["code"] = *_context.code; + if (_context.variables) + { + solRequire(!_context.variables->empty(), EthdebugException, "Context variables must not be empty if provided."); + _json["variables"] = *_context.variables; + } + if (_context.remark) + _json["remark"] = *_context.remark; +} + +void schema::program::to_json(Json& _json, Instruction::Operation const& _operation) +{ + _json = { {"mnemonic", _operation.mnemonic} }; + if (!_operation.arguments.empty()) + _json["arguments"] = _operation.arguments; +} + +void schema::program::to_json(Json& _json, Instruction const& _instruction) +{ + _json["offset"] = _instruction.offset; + if (_instruction.operation) + _json["operation"] = *_instruction.operation; + if (_instruction.context) + _json["context"] = *_instruction.context; +} + +void schema::to_json(Json& _json, Program const& _program) +{ + if (_program.compilation) + _json["compilation"] = *_program.compilation; + _json["contract"] = _program.contract; + _json["environment"] = _program.environment; + if (_program.context) + _json["context"] = *_program.context; + _json["instructions"] = _program.instructions; +} + +void schema::to_json(Json& _json, Program::Environment const& _environment) +{ + switch (_environment) + { + case Program::Environment::CALL: + _json = "call"; + break; + case Program::Environment::CREATE: + _json = "create"; + break; + } +} diff --git a/libevmasm/EthdebugSchema.h b/libevmasm/EthdebugSchema.h new file mode 100644 index 000000000000..5fc8f78fd62e --- /dev/null +++ b/libevmasm/EthdebugSchema.h @@ -0,0 +1,172 @@ +/* + This file is part of solidity. + + solidity is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + solidity is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with solidity. If not, see . +*/ +// SPDX-License-Identifier: GPL-3.0 + +#pragma once + +#include +#include + +#include +#include +#include +#include + +namespace solidity::evmasm::ethdebug::schema +{ + +struct EthdebugException: virtual util::Exception {}; + +namespace data +{ + +struct HexValue +{ + bytes value; +}; + +struct Unsigned +{ + template + Unsigned(T const _value) + { + solRequire(static_cast(_value) <= std::numeric_limits::max(), EthdebugException, "Too large value."); + value = static_cast(_value); + } + template + Unsigned(T const _value) + { + solRequire(_value >= 0, EthdebugException, "NonNegativeValue got negative value."); + solRequire(static_cast>(_value) <= std::numeric_limits::max(), EthdebugException, "Too large value."); + value = static_cast(_value); + } + Unsigned(HexValue&& _value): value(std::move(_value)) {} + + std::variant value; +}; + +} + +namespace materials +{ + +struct ID +{ + std::variant value; +}; + +struct Reference +{ + enum class Type { Compilation, Source }; + ID id; + std::optional type; +}; + +struct SourceRange +{ + struct Range + { + data::Unsigned length; + data::Unsigned offset; + }; + + Reference source; + std::optional range; +}; + +} + +namespace program +{ + +struct Context +{ + struct Variable + { + std::optional identifier; + std::optional declaration; + // TODO: type + // TODO: pointer according to ethdebug/format/spec/pointer + }; + + std::optional code; + std::optional> variables; + std::optional remark; +}; + +struct Instruction +{ + struct Operation + { + std::string mnemonic; + std::vector arguments; + }; + + data::Unsigned offset; + std::optional operation; + std::optional context; +}; + +} + +struct Program +{ + enum class Environment + { + CALL, CREATE + }; + + struct Contract + { + std::optional name; + materials::SourceRange definition; + }; + + std::optional compilation; + Contract contract; + Environment environment; + std::optional context; + std::vector instructions; +}; + +namespace data +{ +void to_json(Json& _json, HexValue const& _hexValue); +void to_json(Json& _json, Unsigned const& _unsigned); +} + +namespace materials +{ +void to_json(Json& _json, ID const& _id); +void to_json(Json& _json, Reference const& _source); +void to_json(Json& _json, SourceRange::Range const& _range); +void to_json(Json& _json, SourceRange const& _sourceRange); +} + +namespace program +{ +void to_json(Json& _json, Context::Variable const& _contextVariable); +void to_json(Json& _json, Context const& _context); +void to_json(Json& _json, Instruction::Operation const& _operation); +void to_json(Json& _json, Instruction const& _instruction); +} + +void to_json(Json& _json, Program::Contract const& _contract); +void to_json(Json& _json, Program::Environment const& _environment); +void to_json(Json& _json, Program const& _program); + +} From 3b924e6429e646feaa8f75ca0577435c63df3e0e Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Wed, 9 Apr 2025 15:22:54 +0200 Subject: [PATCH 0983/1022] Ethdebug uses schema for serialization --- libevmasm/Ethdebug.cpp | 131 ++++++++++++++++---------- libevmasm/Ethdebug.h | 2 +- test/libsolidity/StandardCompiler.cpp | 9 +- 3 files changed, 87 insertions(+), 55 deletions(-) diff --git a/libevmasm/Ethdebug.cpp b/libevmasm/Ethdebug.cpp index 0a4c56ddd0a0..8b87aadd072a 100644 --- a/libevmasm/Ethdebug.cpp +++ b/libevmasm/Ethdebug.cpp @@ -18,6 +18,8 @@ #include +#include + #include using namespace solidity; @@ -27,14 +29,66 @@ using namespace solidity::evmasm::ethdebug; namespace { -std::vector codeSectionInstructions(Assembly const& _assembly, LinkerObject const& _linkerObject, unsigned _sourceId, size_t const _codeSectionIndex) +schema::program::Instruction::Operation instructionOperation(Assembly const& _assembly, LinkerObject const& _linkerObject, size_t const _start, size_t const _end) +{ + solAssert(_end <= _linkerObject.bytecode.size()); + solAssert(_start < _end); + schema::program::Instruction::Operation operation; + operation.mnemonic = instructionInfo(static_cast(_linkerObject.bytecode[_start]), _assembly.evmVersion()).name; + static size_t constexpr instructionSize = 1; + if (_start + instructionSize < _end) + { + bytes const argumentData( + _linkerObject.bytecode.begin() + static_cast(_start) + instructionSize, + _linkerObject.bytecode.begin() + static_cast(_end) + ); + solAssert(!argumentData.empty()); + operation.arguments = {{schema::data::HexValue{argumentData}}}; + } + return operation; +} + +schema::materials::SourceRange::Range locationRange(langutil::SourceLocation const& _location) +{ + return { + .length = schema::data::Unsigned{_location.end - _location.start}, + .offset = schema::data::Unsigned{_location.start} + }; +} + +schema::materials::Reference sourceReference(unsigned _sourceID) +{ + return { + .id = schema::materials::ID{_sourceID}, + .type = std::nullopt + }; +} + +std::optional instructionContext(Assembly::CodeSection const& _codeSection, size_t _assemblyItemIndex, unsigned _sourceID) +{ + solAssert(_assemblyItemIndex < _codeSection.items.size()); + langutil::SourceLocation const& location = _codeSection.items.at(_assemblyItemIndex).location(); + if (!location.isValid()) + return std::nullopt; + + return schema::program::Context{ + schema::materials::SourceRange{ + .source = sourceReference(_sourceID), + .range = locationRange(location) + }, + std::nullopt, + std::nullopt + }; +} + +std::vector codeSectionInstructions(Assembly const& _assembly, LinkerObject const& _linkerObject, unsigned const _sourceID, size_t const _codeSectionIndex) { solAssert(_codeSectionIndex < _linkerObject.codeSectionLocations.size()); solAssert(_codeSectionIndex < _assembly.codeSections().size()); auto const& locations = _linkerObject.codeSectionLocations[_codeSectionIndex]; auto const& codeSection = _assembly.codeSections().at(_codeSectionIndex); - std::vector instructions; + std::vector instructions; instructions.reserve(codeSection.items.size()); bool const codeSectionContainsVerbatim = ranges::any_of( @@ -52,72 +106,47 @@ std::vector codeSectionInstructions(Assembly const& _assembly, LinkerObjec if (start == end) continue; - size_t const assemblyItemIndex = currentInstruction.assemblyItemIndex; - solAssert(end <= _linkerObject.bytecode.size()); - solAssert(start < end); - solAssert(assemblyItemIndex < codeSection.items.size()); - Json operation = Json::object(); - operation["mnemonic"] = instructionInfo(static_cast(_linkerObject.bytecode[start]), _assembly.evmVersion()).name; - static size_t constexpr instructionSize = 1; - if (start + instructionSize < end) - { - bytes const argumentData( - _linkerObject.bytecode.begin() + static_cast(start) + instructionSize, - _linkerObject.bytecode.begin() + static_cast(end) - ); - solAssert(!argumentData.empty()); - operation["arguments"] = Json::array({util::toHex(argumentData, util::HexPrefix::Add)}); - } - langutil::SourceLocation const& location = codeSection.items.at(assemblyItemIndex).location(); - instructions.emplace_back(Json{ - { "offset", start }, - {"operation", operation }, - { - "context", { - "code", { - "source", { - { "id", static_cast(_sourceId) }, - }, - "range", { - { "offset", location.start }, - { "length", location.end - location.start } - } - } - } - } + instructions.emplace_back(schema::program::Instruction{ + .offset = schema::data::Unsigned{start}, + .operation = instructionOperation(_assembly, _linkerObject, start, end), + .context = instructionContext(codeSection, currentInstruction.assemblyItemIndex, _sourceID) }); } return instructions; } -Json programInstructions(Assembly const& _assembly, LinkerObject const& _linkerObject, unsigned _sourceId) +std::vector programInstructions(Assembly const& _assembly, LinkerObject const& _linkerObject, unsigned const _sourceID) { auto const numCodeSections = _assembly.codeSections().size(); solAssert(numCodeSections == _linkerObject.codeSectionLocations.size()); - std::vector instructionInfo; + std::vector instructionInfo; for (size_t codeSectionIndex = 0; codeSectionIndex < numCodeSections; ++codeSectionIndex) - instructionInfo += codeSectionInstructions(_assembly, _linkerObject, _sourceId, codeSectionIndex); + instructionInfo += codeSectionInstructions(_assembly, _linkerObject, _sourceID, codeSectionIndex); return instructionInfo; } } // anonymous namespace -Json ethdebug::program(std::string_view _name, unsigned _sourceId, Assembly const& _assembly, LinkerObject const& _linkerObject) +Json ethdebug::program(std::string_view _name, unsigned _sourceID, Assembly const& _assembly, LinkerObject const& _linkerObject) { - Json result = Json::object(); - result["contract"] = Json::object(); - result["contract"]["name"] = _name; - result["contract"]["definition"] = Json::object(); - result["contract"]["definition"]["source"] = Json::object(); - result["contract"]["definition"]["source"]["id"] = _sourceId; - if (_assembly) - { - result["environment"] = _assembly->isCreation() ? "create" : "call"; - result["instructions"] = programInstructions(*_assembly, _linkerObject, _sourceId); - } - return result; + return schema::Program{ + .compilation = std::nullopt, + .contract = { + .name = std::string{_name}, + .definition = { + .source = { + .id = {_sourceID}, + .type = std::nullopt + }, + .range = std::nullopt + } + }, + .environment = _assembly.isCreation() ? schema::Program::Environment::CREATE : schema::Program::Environment::CALL, + .context = std::nullopt, + .instructions = programInstructions(_assembly, _linkerObject, _sourceID) + }; } Json ethdebug::resources(std::vector const& _sources, std::string const& _version) diff --git a/libevmasm/Ethdebug.h b/libevmasm/Ethdebug.h index fdb693b190c4..2e0df3484ba6 100644 --- a/libevmasm/Ethdebug.h +++ b/libevmasm/Ethdebug.h @@ -27,7 +27,7 @@ namespace solidity::evmasm::ethdebug { // returns ethdebug/format/program. -Json program(std::string_view _name, unsigned _sourceId, Assembly const& _assembly, LinkerObject const& _linkerObject); +Json program(std::string_view _name, unsigned _sourceID, Assembly const& _assembly, LinkerObject const& _linkerObject); // returns ethdebug/format/info/resources Json resources(std::vector const& _sources, std::string const& _version); diff --git a/test/libsolidity/StandardCompiler.cpp b/test/libsolidity/StandardCompiler.cpp index 62c72ad45c07..b9e31c5e3824 100644 --- a/test/libsolidity/StandardCompiler.cpp +++ b/test/libsolidity/StandardCompiler.cpp @@ -2231,9 +2231,12 @@ BOOST_DATA_TEST_CASE(ethdebug_output_instructions_smoketest, boost::unit_test::d BOOST_REQUIRE(instruction.contains("offset")); BOOST_REQUIRE(instruction.contains("operation")); BOOST_REQUIRE(instruction["operation"].contains("mnemonic")); - BOOST_REQUIRE(instruction["context"]["code"]["range"].contains("length")); - BOOST_REQUIRE(instruction["context"]["code"]["range"].contains("offset")); - BOOST_REQUIRE(instruction["context"]["code"]["source"].contains("id")); + if (instruction.contains("context")) + { + BOOST_REQUIRE(instruction["context"]["code"]["range"].contains("length")); + BOOST_REQUIRE(instruction["context"]["code"]["range"].contains("offset")); + BOOST_REQUIRE(instruction["context"]["code"]["source"].contains("id")); + } std::string mnemonic = instruction["operation"]["mnemonic"]; if (mnemonic.find("PUSH") != std::string::npos) { From 89a0f9142491cf08c8ce438723fe27f6c52fc083 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Wed, 9 Apr 2025 15:23:21 +0200 Subject: [PATCH 0984/1022] Update test expectations with eof-enabled ethdebug --- .../ethdebug_eof_container_osaka/args | 2 +- .../ethdebug_eof_container_osaka/err | 1 - .../ethdebug_eof_container_osaka/exit | 1 - .../ethdebug_eof_container_osaka/output | 251 +++++++++++++++++- 4 files changed, 251 insertions(+), 4 deletions(-) delete mode 100644 test/cmdlineTests/ethdebug_eof_container_osaka/err delete mode 100644 test/cmdlineTests/ethdebug_eof_container_osaka/exit diff --git a/test/cmdlineTests/ethdebug_eof_container_osaka/args b/test/cmdlineTests/ethdebug_eof_container_osaka/args index 65974c6287da..16466b842d0e 100644 --- a/test/cmdlineTests/ethdebug_eof_container_osaka/args +++ b/test/cmdlineTests/ethdebug_eof_container_osaka/args @@ -1 +1 @@ - --experimental-eof-version 1 --evm-version osaka --ethdebug --via-ir + --experimental-eof-version 1 --evm-version osaka --ethdebug --via-ir --pretty-json --json-indent 4 diff --git a/test/cmdlineTests/ethdebug_eof_container_osaka/err b/test/cmdlineTests/ethdebug_eof_container_osaka/err deleted file mode 100644 index 7714685971d2..000000000000 --- a/test/cmdlineTests/ethdebug_eof_container_osaka/err +++ /dev/null @@ -1 +0,0 @@ -Error: ethdebug does not yet support EOF. diff --git a/test/cmdlineTests/ethdebug_eof_container_osaka/exit b/test/cmdlineTests/ethdebug_eof_container_osaka/exit deleted file mode 100644 index d00491fd7e5b..000000000000 --- a/test/cmdlineTests/ethdebug_eof_container_osaka/exit +++ /dev/null @@ -1 +0,0 @@ -1 diff --git a/test/cmdlineTests/ethdebug_eof_container_osaka/output b/test/cmdlineTests/ethdebug_eof_container_osaka/output index b29297ee3749..e9b57d885711 100644 --- a/test/cmdlineTests/ethdebug_eof_container_osaka/output +++ b/test/cmdlineTests/ethdebug_eof_container_osaka/output @@ -1,4 +1,253 @@ ======= Debug Data (ethdebug/format/info/resources) ======= -{"compilation":{"compiler":{"name":"solc","version": ""},"sources":[{"id":0,"path":"input.sol"}]}} +{ + "compilation": { + "compiler": { + "name": "solc", + "version": "" + }, + "sources": [ + { + "id": 0, + "path": "input.sol" + } + ] + } +} ======= input.sol:C ======= +Debug Data (ethdebug/format/program): +{ + "contract": { + "definition": { + "source": { + "id": 0 + } + }, + "name": "C" + }, + "environment": "create", + "instructions": [ + { + "context": { + "code": { + "range": { + "length": 41, + "offset": 60 + }, + "source": { + "id": 0 + } + } + }, + "offset": 30, + "operation": { + "arguments": [ + "0x80" + ], + "mnemonic": "PUSH1" + } + }, + { + "context": { + "code": { + "range": { + "length": 41, + "offset": 60 + }, + "source": { + "id": 0 + } + } + }, + "offset": 32, + "operation": { + "arguments": [ + "0x40" + ], + "mnemonic": "PUSH1" + } + }, + { + "context": { + "code": { + "range": { + "length": 41, + "offset": 60 + }, + "source": { + "id": 0 + } + } + }, + "offset": 34, + "operation": { + "mnemonic": "MSTORE" + } + }, + { + "context": { + "code": { + "range": { + "length": 41, + "offset": 60 + }, + "source": { + "id": 0 + } + } + }, + "offset": 35, + "operation": { + "mnemonic": "CALLVALUE" + } + }, + { + "context": { + "code": { + "range": { + "length": 41, + "offset": 60 + }, + "source": { + "id": 0 + } + } + }, + "offset": 36, + "operation": { + "arguments": [ + "0x0005" + ], + "mnemonic": "RJUMPI" + } + }, + { + "context": { + "code": { + "range": { + "length": 41, + "offset": 60 + }, + "source": { + "id": 0 + } + } + }, + "offset": 39, + "operation": { + "mnemonic": "PUSH0" + } + }, + { + "context": { + "code": { + "range": { + "length": 41, + "offset": 60 + }, + "source": { + "id": 0 + } + } + }, + "offset": 40, + "operation": { + "arguments": [ + "0x80" + ], + "mnemonic": "PUSH1" + } + }, + { + "context": { + "code": { + "range": { + "length": 41, + "offset": 60 + }, + "source": { + "id": 0 + } + } + }, + "offset": 42, + "operation": { + "arguments": [ + "0x00" + ], + "mnemonic": "RETURNCONTRACT" + } + }, + { + "context": { + "code": { + "range": { + "length": 41, + "offset": 60 + }, + "source": { + "id": 0 + } + } + }, + "offset": 44, + "operation": { + "arguments": [ + "0x0001" + ], + "mnemonic": "JUMPF" + } + }, + { + "context": { + "code": { + "range": { + "length": 41, + "offset": 60 + }, + "source": { + "id": 0 + } + } + }, + "offset": 47, + "operation": { + "mnemonic": "PUSH0" + } + }, + { + "context": { + "code": { + "range": { + "length": 41, + "offset": 60 + }, + "source": { + "id": 0 + } + } + }, + "offset": 48, + "operation": { + "mnemonic": "DUP1" + } + }, + { + "context": { + "code": { + "range": { + "length": 41, + "offset": 60 + }, + "source": { + "id": 0 + } + } + }, + "offset": 49, + "operation": { + "mnemonic": "REVERT" + } + } + ] +} From 482f64b64ba6fbacf7db42148a8a8914b8a33e56 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Fri, 11 Apr 2025 11:37:46 +0200 Subject: [PATCH 0985/1022] Test ethdebug output when requested in standard json under EOF --- .../args | 1 + .../in.yul | 16 +++++++ .../input.json | 18 ++++++++ .../output.json | 42 +++++++++++++++++++ .../strip-ethdebug | 0 .../standard_yul_ethdebug_eof/args | 1 + .../standard_yul_ethdebug_eof/in.yul | 17 ++++++++ .../standard_yul_ethdebug_eof/input.json | 13 ++++++ .../standard_yul_ethdebug_eof/output.json | 42 +++++++++++++++++++ .../standard_yul_ethdebug_eof/strip-ethdebug | 0 10 files changed, 150 insertions(+) create mode 100644 test/cmdlineTests/standard_yul_debug_info_ethdebug_compatible_output_eof/args create mode 100644 test/cmdlineTests/standard_yul_debug_info_ethdebug_compatible_output_eof/in.yul create mode 100644 test/cmdlineTests/standard_yul_debug_info_ethdebug_compatible_output_eof/input.json create mode 100644 test/cmdlineTests/standard_yul_debug_info_ethdebug_compatible_output_eof/output.json create mode 100644 test/cmdlineTests/standard_yul_debug_info_ethdebug_compatible_output_eof/strip-ethdebug create mode 100644 test/cmdlineTests/standard_yul_ethdebug_eof/args create mode 100644 test/cmdlineTests/standard_yul_ethdebug_eof/in.yul create mode 100644 test/cmdlineTests/standard_yul_ethdebug_eof/input.json create mode 100644 test/cmdlineTests/standard_yul_ethdebug_eof/output.json create mode 100644 test/cmdlineTests/standard_yul_ethdebug_eof/strip-ethdebug diff --git a/test/cmdlineTests/standard_yul_debug_info_ethdebug_compatible_output_eof/args b/test/cmdlineTests/standard_yul_debug_info_ethdebug_compatible_output_eof/args new file mode 100644 index 000000000000..18532c5a6d3f --- /dev/null +++ b/test/cmdlineTests/standard_yul_debug_info_ethdebug_compatible_output_eof/args @@ -0,0 +1 @@ +--allow-paths . diff --git a/test/cmdlineTests/standard_yul_debug_info_ethdebug_compatible_output_eof/in.yul b/test/cmdlineTests/standard_yul_debug_info_ethdebug_compatible_output_eof/in.yul new file mode 100644 index 000000000000..aa564d00ce86 --- /dev/null +++ b/test/cmdlineTests/standard_yul_debug_info_ethdebug_compatible_output_eof/in.yul @@ -0,0 +1,16 @@ +/// @use-src 0:"input.sol" +object "C_6_deployed" { + code { + /// @src 0:60:101 "contract C {..." + mstore(64, 128) + + // f() + fun_f_5() + + /// @src 0:77:99 "function f() public {}" + function fun_f_5() { + sstore(0, 42) + } + /// @src 0:60:101 "contract C {..." + } +} diff --git a/test/cmdlineTests/standard_yul_debug_info_ethdebug_compatible_output_eof/input.json b/test/cmdlineTests/standard_yul_debug_info_ethdebug_compatible_output_eof/input.json new file mode 100644 index 000000000000..a8c3436c1a0f --- /dev/null +++ b/test/cmdlineTests/standard_yul_debug_info_ethdebug_compatible_output_eof/input.json @@ -0,0 +1,18 @@ +{ + "language": "Yul", + "sources": { + "C": { + "urls": [ + "in.yul" + ] + } + }, + "settings": { + "eofVersion": 1, + "evmVersion": "osaka", + "debug": {"debugInfo": ["ethdebug"]}, + "outputSelection": { + "*": {"*": ["ir", "irOptimized", "evm.bytecode.ethdebug"]} + } + } +} diff --git a/test/cmdlineTests/standard_yul_debug_info_ethdebug_compatible_output_eof/output.json b/test/cmdlineTests/standard_yul_debug_info_ethdebug_compatible_output_eof/output.json new file mode 100644 index 000000000000..2b2f395fadd4 --- /dev/null +++ b/test/cmdlineTests/standard_yul_debug_info_ethdebug_compatible_output_eof/output.json @@ -0,0 +1,42 @@ +{ + "contracts": { + "C": { + "C_6_deployed": { + "evm": { + "bytecode": { + "ethdebug": "" + } + }, + "ir": "/// ethdebug: enabled +/// @use-src 0:\"input.sol\" +object \"C_6_deployed\" { + code { + /// @src 0:60:101 + mstore(64, 128) + fun_f_5() + /// @src 0:77:99 + function fun_f_5() + { sstore(0, 42) } + } +} +", + "irOptimized": "/// ethdebug: enabled +/// @use-src 0:\"input.sol\" +object \"C_6_deployed\" { + code { + { + /// @src 0:60:101 + mstore(64, 128) + fun_f() + } + /// @src 0:77:99 + function fun_f() + { sstore(0, 42) } + } +} +" + } + } + }, + "ethdebug": "" +} diff --git a/test/cmdlineTests/standard_yul_debug_info_ethdebug_compatible_output_eof/strip-ethdebug b/test/cmdlineTests/standard_yul_debug_info_ethdebug_compatible_output_eof/strip-ethdebug new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/test/cmdlineTests/standard_yul_ethdebug_eof/args b/test/cmdlineTests/standard_yul_ethdebug_eof/args new file mode 100644 index 000000000000..18532c5a6d3f --- /dev/null +++ b/test/cmdlineTests/standard_yul_ethdebug_eof/args @@ -0,0 +1 @@ +--allow-paths . diff --git a/test/cmdlineTests/standard_yul_ethdebug_eof/in.yul b/test/cmdlineTests/standard_yul_ethdebug_eof/in.yul new file mode 100644 index 000000000000..920aef8e9dc2 --- /dev/null +++ b/test/cmdlineTests/standard_yul_ethdebug_eof/in.yul @@ -0,0 +1,17 @@ +/// @use-src 0:"input.sol" +object "C_6_deployed" { + code { + /// @src 0:60:101 "contract C {..." + mstore(64, 128) + + // f() + fun_f_5() + + /// @src 0:77:99 "function f() public {}" + function fun_f_5() { + sstore(0, 42) + } + /// @src 0:60:101 "contract C {..." + } +} + diff --git a/test/cmdlineTests/standard_yul_ethdebug_eof/input.json b/test/cmdlineTests/standard_yul_ethdebug_eof/input.json new file mode 100644 index 000000000000..4e33c42670a6 --- /dev/null +++ b/test/cmdlineTests/standard_yul_ethdebug_eof/input.json @@ -0,0 +1,13 @@ +{ + "language": "Yul", + "sources": { + "C": {"urls": ["in.yul"]} + }, + "settings": { + "eofVersion": 1, + "evmVersion": "osaka", + "outputSelection": { + "*": {"*": ["evm.bytecode.ethdebug", "evm.deployedBytecode.ethdebug", "ir", "irOptimized"]} + } + } +} diff --git a/test/cmdlineTests/standard_yul_ethdebug_eof/output.json b/test/cmdlineTests/standard_yul_ethdebug_eof/output.json new file mode 100644 index 000000000000..2b2f395fadd4 --- /dev/null +++ b/test/cmdlineTests/standard_yul_ethdebug_eof/output.json @@ -0,0 +1,42 @@ +{ + "contracts": { + "C": { + "C_6_deployed": { + "evm": { + "bytecode": { + "ethdebug": "" + } + }, + "ir": "/// ethdebug: enabled +/// @use-src 0:\"input.sol\" +object \"C_6_deployed\" { + code { + /// @src 0:60:101 + mstore(64, 128) + fun_f_5() + /// @src 0:77:99 + function fun_f_5() + { sstore(0, 42) } + } +} +", + "irOptimized": "/// ethdebug: enabled +/// @use-src 0:\"input.sol\" +object \"C_6_deployed\" { + code { + { + /// @src 0:60:101 + mstore(64, 128) + fun_f() + } + /// @src 0:77:99 + function fun_f() + { sstore(0, 42) } + } +} +" + } + } + }, + "ethdebug": "" +} diff --git a/test/cmdlineTests/standard_yul_ethdebug_eof/strip-ethdebug b/test/cmdlineTests/standard_yul_ethdebug_eof/strip-ethdebug new file mode 100644 index 000000000000..e69de29bb2d1 From 059bd8ee43fc8f767492f219060b5adfc68a8cda Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Tue, 6 May 2025 13:16:51 +0200 Subject: [PATCH 0986/1022] Add tests for ethdebug output on abstract contracts and interfaces --- test/cmdlineTests/ethdebug_on_abstract/args | 1 + .../ethdebug_on_abstract/input.sol | 6 +++ test/cmdlineTests/ethdebug_on_abstract/output | 19 +++++++ test/cmdlineTests/ethdebug_on_interface/args | 1 + .../ethdebug_on_interface/input.sol | 6 +++ .../cmdlineTests/ethdebug_on_interface/output | 19 +++++++ .../input.json | 27 ++++++++++ .../output.json | 54 +++++++++++++++++++ 8 files changed, 133 insertions(+) create mode 100644 test/cmdlineTests/ethdebug_on_abstract/args create mode 100644 test/cmdlineTests/ethdebug_on_abstract/input.sol create mode 100644 test/cmdlineTests/ethdebug_on_abstract/output create mode 100644 test/cmdlineTests/ethdebug_on_interface/args create mode 100644 test/cmdlineTests/ethdebug_on_interface/input.sol create mode 100644 test/cmdlineTests/ethdebug_on_interface/output create mode 100644 test/cmdlineTests/standard_output_debuginfo_ethdebug_with_interfaces_and_abstracts/input.json create mode 100644 test/cmdlineTests/standard_output_debuginfo_ethdebug_with_interfaces_and_abstracts/output.json diff --git a/test/cmdlineTests/ethdebug_on_abstract/args b/test/cmdlineTests/ethdebug_on_abstract/args new file mode 100644 index 000000000000..c6018b329a67 --- /dev/null +++ b/test/cmdlineTests/ethdebug_on_abstract/args @@ -0,0 +1 @@ +--ethdebug --via-ir --pretty-json --json-indent 4 diff --git a/test/cmdlineTests/ethdebug_on_abstract/input.sol b/test/cmdlineTests/ethdebug_on_abstract/input.sol new file mode 100644 index 000000000000..29ff21a20ce8 --- /dev/null +++ b/test/cmdlineTests/ethdebug_on_abstract/input.sol @@ -0,0 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0 +pragma solidity >=0.0; + +abstract contract C { + function f() public virtual returns (bytes32); +} diff --git a/test/cmdlineTests/ethdebug_on_abstract/output b/test/cmdlineTests/ethdebug_on_abstract/output new file mode 100644 index 000000000000..744ec0e77642 --- /dev/null +++ b/test/cmdlineTests/ethdebug_on_abstract/output @@ -0,0 +1,19 @@ +======= Debug Data (ethdebug/format/info/resources) ======= +{ + "compilation": { + "compiler": { + "name": "solc", + "version": "" + }, + "sources": [ + { + "id": 0, + "path": "input.sol" + } + ] + } +} + +======= input.sol:C ======= +Debug Data (ethdebug/format/program): +null diff --git a/test/cmdlineTests/ethdebug_on_interface/args b/test/cmdlineTests/ethdebug_on_interface/args new file mode 100644 index 000000000000..c6018b329a67 --- /dev/null +++ b/test/cmdlineTests/ethdebug_on_interface/args @@ -0,0 +1 @@ +--ethdebug --via-ir --pretty-json --json-indent 4 diff --git a/test/cmdlineTests/ethdebug_on_interface/input.sol b/test/cmdlineTests/ethdebug_on_interface/input.sol new file mode 100644 index 000000000000..cd008c45b465 --- /dev/null +++ b/test/cmdlineTests/ethdebug_on_interface/input.sol @@ -0,0 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0 +pragma solidity >=0.0; + +interface C { + function f() external; +} diff --git a/test/cmdlineTests/ethdebug_on_interface/output b/test/cmdlineTests/ethdebug_on_interface/output new file mode 100644 index 000000000000..744ec0e77642 --- /dev/null +++ b/test/cmdlineTests/ethdebug_on_interface/output @@ -0,0 +1,19 @@ +======= Debug Data (ethdebug/format/info/resources) ======= +{ + "compilation": { + "compiler": { + "name": "solc", + "version": "" + }, + "sources": [ + { + "id": 0, + "path": "input.sol" + } + ] + } +} + +======= input.sol:C ======= +Debug Data (ethdebug/format/program): +null diff --git a/test/cmdlineTests/standard_output_debuginfo_ethdebug_with_interfaces_and_abstracts/input.json b/test/cmdlineTests/standard_output_debuginfo_ethdebug_with_interfaces_and_abstracts/input.json new file mode 100644 index 000000000000..06b2d86e96f6 --- /dev/null +++ b/test/cmdlineTests/standard_output_debuginfo_ethdebug_with_interfaces_and_abstracts/input.json @@ -0,0 +1,27 @@ +{ + "language": "Solidity", + "sources": { + "a.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0\npragma solidity >=0.0;\n\nabstract contract C {\n function f() public virtual returns (bytes32);\n}\n" + }, + "b.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0\npragma solidity >=0.0;\n\ninterface C {\n function f() external;\n}\n" + } + }, + "settings": { + "viaIR": true, + "debug": { + "debugInfo": [ + "ethdebug" + ] + }, + "outputSelection": { + "*": { + "*": [ + "evm.bytecode.ethdebug", + "evm.deployedBytecode.ethdebug" + ] + } + } + } +} diff --git a/test/cmdlineTests/standard_output_debuginfo_ethdebug_with_interfaces_and_abstracts/output.json b/test/cmdlineTests/standard_output_debuginfo_ethdebug_with_interfaces_and_abstracts/output.json new file mode 100644 index 000000000000..57b26680146a --- /dev/null +++ b/test/cmdlineTests/standard_output_debuginfo_ethdebug_with_interfaces_and_abstracts/output.json @@ -0,0 +1,54 @@ +{ + "contracts": { + "a.sol": { + "C": { + "evm": { + "bytecode": { + "ethdebug": null + }, + "deployedBytecode": { + "ethdebug": null + } + } + } + }, + "b.sol": { + "C": { + "evm": { + "bytecode": { + "ethdebug": null + }, + "deployedBytecode": { + "ethdebug": null + } + } + } + } + }, + "ethdebug": { + "compilation": { + "compiler": { + "name": "solc", + "version": "" + }, + "sources": [ + { + "id": 0, + "path": "a.sol" + }, + { + "id": 1, + "path": "b.sol" + } + ] + } + }, + "sources": { + "a.sol": { + "id": 0 + }, + "b.sol": { + "id": 1 + } + } +} From dd25b24f12556921f99adf05268302a5e1b7f991 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Thu, 15 May 2025 16:05:23 +0200 Subject: [PATCH 0987/1022] Changelog uses single blank line between headlines --- Changelog.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/Changelog.md b/Changelog.md index a2e814bda43c..18e0deeaf612 100644 --- a/Changelog.md +++ b/Changelog.md @@ -2,13 +2,11 @@ Language Features: - Compiler Features: * ethdebug: Experimental support for instructions and source locations under EOF. Bugfixes: - ### 0.8.30 (2025-05-07) Compiler Features: From 1401089b42d13476b7380fe2569313fe16710230 Mon Sep 17 00:00:00 2001 From: r0qs <457348+r0qs@users.noreply.github.com> Date: Thu, 5 Jun 2025 17:13:17 +0200 Subject: [PATCH 0988/1022] Export literal assignments as operation --- libyul/YulControlFlowGraphExporter.cpp | 4 +- .../standard_yul_cfg_json_export/output.json | 61 ++++++++++--------- .../strict_asm_yul_cfg_json_export/output | 16 ++--- test/cmdlineTests/yul_cfg_json_export/output | 61 ++++++++++--------- 4 files changed, 72 insertions(+), 70 deletions(-) diff --git a/libyul/YulControlFlowGraphExporter.cpp b/libyul/YulControlFlowGraphExporter.cpp index 1ce7f58fc5bf..f0ad055f25ad 100644 --- a/libyul/YulControlFlowGraphExporter.cpp +++ b/libyul/YulControlFlowGraphExporter.cpp @@ -187,7 +187,7 @@ Json YulControlFlowGraphExporter::toJson(Json& _ret, SSACFG const& _cfg, SSACFG: { yulAssert(_operation.inputs.size() == 1); yulAssert(_cfg.isLiteralValue(_operation.inputs.back())); - _ret["type"] = "LiteralAssignment"; + opJson["op"] = "LiteralAssignment"; }, [&](SSACFG::BuiltinCall const& _call) { @@ -210,7 +210,7 @@ Json YulControlFlowGraphExporter::toJson(Json& _ret, SSACFG const& _cfg, SSACFG: } if (!builtinArgsJson.empty()) - opJson["builtinArgs"] = builtinArgsJson; + opJson["literalArgs"] = builtinArgsJson; opJson["op"] = _call.builtin.get().name; }, diff --git a/test/cmdlineTests/standard_yul_cfg_json_export/output.json b/test/cmdlineTests/standard_yul_cfg_json_export/output.json index a9c5ca7a6d4f..ac416d33174f 100644 --- a/test/cmdlineTests/standard_yul_cfg_json_export/output.json +++ b/test/cmdlineTests/standard_yul_cfg_json_export/output.json @@ -17,10 +17,10 @@ "id": "Block0", "instructions": [ { - "builtinArgs": [ + "in": [], + "literalArgs": [ "0x80" ], - "in": [], "op": "memoryguard", "out": [ "v0" @@ -57,20 +57,20 @@ "id": "Block2", "instructions": [ { - "builtinArgs": [ + "in": [], + "literalArgs": [ "C_19_deployed" ], - "in": [], "op": "datasize", "out": [ "v4" ] }, { - "builtinArgs": [ + "in": [], + "literalArgs": [ "C_19_deployed" ], - "in": [], "op": "dataoffset", "out": [ "v5" @@ -140,10 +140,10 @@ "id": "Block0", "instructions": [ { - "builtinArgs": [ + "in": [], + "literalArgs": [ "0x80" ], - "in": [], "op": "memoryguard", "out": [ "v0" @@ -464,10 +464,10 @@ "id": "Block0", "instructions": [ { - "builtinArgs": [ + "in": [], + "literalArgs": [ "0x80" ], - "in": [], "op": "memoryguard", "out": [ "v0" @@ -504,20 +504,20 @@ "id": "Block2", "instructions": [ { - "builtinArgs": [ + "in": [], + "literalArgs": [ "D_38_deployed" ], - "in": [], "op": "datasize", "out": [ "v4" ] }, { - "builtinArgs": [ + "in": [], + "literalArgs": [ "D_38_deployed" ], - "in": [], "op": "dataoffset", "out": [ "v5" @@ -587,10 +587,10 @@ "id": "Block0", "instructions": [ { - "builtinArgs": [ + "in": [], + "literalArgs": [ "0x80" ], - "in": [], "op": "memoryguard", "out": [ "v0" @@ -845,10 +845,10 @@ "id": "Block9", "instructions": [ { - "builtinArgs": [ + "in": [], + "literalArgs": [ "C_19" ], - "in": [], "op": "datasize", "out": [ "v18" @@ -940,10 +940,10 @@ "id": "Block12", "instructions": [ { - "builtinArgs": [ + "in": [], + "literalArgs": [ "C_19" ], - "in": [], "op": "dataoffset", "out": [ "v35" @@ -1226,6 +1226,7 @@ "in": [ "0x00" ], + "op": "LiteralAssignment", "out": [ "v64" ] @@ -1240,8 +1241,7 @@ "v46", "v64" ] - }, - "type": "LiteralAssignment" + } }, { "exit": { @@ -1365,6 +1365,7 @@ "in": [ "0x20" ], + "op": "LiteralAssignment", "out": [ "v67" ] @@ -1710,10 +1711,10 @@ "id": "Block0", "instructions": [ { - "builtinArgs": [ + "in": [], + "literalArgs": [ "0x80" ], - "in": [], "op": "memoryguard", "out": [ "v0" @@ -1750,20 +1751,20 @@ "id": "Block2", "instructions": [ { - "builtinArgs": [ + "in": [], + "literalArgs": [ "C_19_deployed" ], - "in": [], "op": "datasize", "out": [ "v4" ] }, { - "builtinArgs": [ + "in": [], + "literalArgs": [ "C_19_deployed" ], - "in": [], "op": "dataoffset", "out": [ "v5" @@ -1833,10 +1834,10 @@ "id": "Block0", "instructions": [ { - "builtinArgs": [ + "in": [], + "literalArgs": [ "0x80" ], - "in": [], "op": "memoryguard", "out": [ "v0" diff --git a/test/cmdlineTests/strict_asm_yul_cfg_json_export/output b/test/cmdlineTests/strict_asm_yul_cfg_json_export/output index e0bb1af40952..40f8186a1a27 100644 --- a/test/cmdlineTests/strict_asm_yul_cfg_json_export/output +++ b/test/cmdlineTests/strict_asm_yul_cfg_json_export/output @@ -17,10 +17,10 @@ Yul Control Flow Graph: "id": "Block0", "instructions": [ { - "builtinArgs": [ + "in": [], + "literalArgs": [ "0x80" ], - "in": [], "op": "memoryguard", "out": [ "v0" @@ -57,20 +57,20 @@ Yul Control Flow Graph: "id": "Block2", "instructions": [ { - "builtinArgs": [ + "in": [], + "literalArgs": [ "C_19_deployed" ], - "in": [], "op": "datasize", "out": [ "v4" ] }, { - "builtinArgs": [ + "in": [], + "literalArgs": [ "C_19_deployed" ], - "in": [], "op": "dataoffset", "out": [ "v5" @@ -140,10 +140,10 @@ Yul Control Flow Graph: "id": "Block0", "instructions": [ { - "builtinArgs": [ + "in": [], + "literalArgs": [ "0x80" ], - "in": [], "op": "memoryguard", "out": [ "v0" diff --git a/test/cmdlineTests/yul_cfg_json_export/output b/test/cmdlineTests/yul_cfg_json_export/output index 2620d53a96ab..1e22b84628ed 100644 --- a/test/cmdlineTests/yul_cfg_json_export/output +++ b/test/cmdlineTests/yul_cfg_json_export/output @@ -16,10 +16,10 @@ Yul Control Flow Graph: "id": "Block0", "instructions": [ { - "builtinArgs": [ + "in": [], + "literalArgs": [ "0x80" ], - "in": [], "op": "memoryguard", "out": [ "v0" @@ -56,20 +56,20 @@ Yul Control Flow Graph: "id": "Block2", "instructions": [ { - "builtinArgs": [ + "in": [], + "literalArgs": [ "C_19_deployed" ], - "in": [], "op": "datasize", "out": [ "v4" ] }, { - "builtinArgs": [ + "in": [], + "literalArgs": [ "C_19_deployed" ], - "in": [], "op": "dataoffset", "out": [ "v5" @@ -139,10 +139,10 @@ Yul Control Flow Graph: "id": "Block0", "instructions": [ { - "builtinArgs": [ + "in": [], + "literalArgs": [ "0x80" ], - "in": [], "op": "memoryguard", "out": [ "v0" @@ -464,10 +464,10 @@ Yul Control Flow Graph: "id": "Block0", "instructions": [ { - "builtinArgs": [ + "in": [], + "literalArgs": [ "0x80" ], - "in": [], "op": "memoryguard", "out": [ "v0" @@ -504,20 +504,20 @@ Yul Control Flow Graph: "id": "Block2", "instructions": [ { - "builtinArgs": [ + "in": [], + "literalArgs": [ "D_38_deployed" ], - "in": [], "op": "datasize", "out": [ "v4" ] }, { - "builtinArgs": [ + "in": [], + "literalArgs": [ "D_38_deployed" ], - "in": [], "op": "dataoffset", "out": [ "v5" @@ -587,10 +587,10 @@ Yul Control Flow Graph: "id": "Block0", "instructions": [ { - "builtinArgs": [ + "in": [], + "literalArgs": [ "0x80" ], - "in": [], "op": "memoryguard", "out": [ "v0" @@ -845,10 +845,10 @@ Yul Control Flow Graph: "id": "Block9", "instructions": [ { - "builtinArgs": [ + "in": [], + "literalArgs": [ "C_19" ], - "in": [], "op": "datasize", "out": [ "v18" @@ -940,10 +940,10 @@ Yul Control Flow Graph: "id": "Block12", "instructions": [ { - "builtinArgs": [ + "in": [], + "literalArgs": [ "C_19" ], - "in": [], "op": "dataoffset", "out": [ "v35" @@ -1226,6 +1226,7 @@ Yul Control Flow Graph: "in": [ "0x00" ], + "op": "LiteralAssignment", "out": [ "v64" ] @@ -1240,8 +1241,7 @@ Yul Control Flow Graph: "v46", "v64" ] - }, - "type": "LiteralAssignment" + } }, { "exit": { @@ -1365,6 +1365,7 @@ Yul Control Flow Graph: "in": [ "0x20" ], + "op": "LiteralAssignment", "out": [ "v67" ] @@ -1710,10 +1711,10 @@ Yul Control Flow Graph: "id": "Block0", "instructions": [ { - "builtinArgs": [ + "in": [], + "literalArgs": [ "0x80" ], - "in": [], "op": "memoryguard", "out": [ "v0" @@ -1750,20 +1751,20 @@ Yul Control Flow Graph: "id": "Block2", "instructions": [ { - "builtinArgs": [ + "in": [], + "literalArgs": [ "C_19_deployed" ], - "in": [], "op": "datasize", "out": [ "v4" ] }, { - "builtinArgs": [ + "in": [], + "literalArgs": [ "C_19_deployed" ], - "in": [], "op": "dataoffset", "out": [ "v5" @@ -1833,10 +1834,10 @@ Yul Control Flow Graph: "id": "Block0", "instructions": [ { - "builtinArgs": [ + "in": [], + "literalArgs": [ "0x80" ], - "in": [], "op": "memoryguard", "out": [ "v0" From 41eb541e5a2b5eacb36297a559d6aed3a976fa31 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Wed, 16 Apr 2025 14:18:26 +0200 Subject: [PATCH 0989/1022] Compare ethdebug output to program schema --- .circleci/config.yml | 18 +++++++ test/ethdebugSchemaTests/conftest.py | 49 ++++++++++++++++++ test/ethdebugSchemaTests/input_file.json | 27 ++++++++++ test/ethdebugSchemaTests/input_file_eof.json | 29 +++++++++++ .../test_ethdebug_schema_conformity.py | 51 +++++++++++++++++++ 5 files changed, 174 insertions(+) create mode 100644 test/ethdebugSchemaTests/conftest.py create mode 100644 test/ethdebugSchemaTests/input_file.json create mode 100644 test/ethdebugSchemaTests/input_file_eof.json create mode 100755 test/ethdebugSchemaTests/test_ethdebug_schema_conformity.py diff --git a/.circleci/config.yml b/.circleci/config.yml index 6c88b9d19f7c..def71c0bf96d 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -952,6 +952,8 @@ jobs: chk_pylint: <<: *base_ubuntu2404_small steps: + - install_python3: + packages: pyyaml jsonschema pytest - checkout - run: pylint --version - run: @@ -1535,6 +1537,19 @@ jobs: - reports/externalTests/ - matrix_notify_failure_unless_pr + t_ethdebug_output_validity: + <<: *base_node_small + steps: + - checkout + - attach_workspace: + at: /tmp/workspace + - install_python3: + packages: pyyaml jsonschema pytest + - run: + name: Ethdebug validity tests + command: | + pytest test/ethdebugSchemaTests --solc-binary-path=/tmp/workspace/solc/solc-static-linux -v + c_ext_benchmarks: <<: *base_node_small steps: @@ -1928,6 +1943,9 @@ workflows: #- t_ext: *job_native_compile_ext_chainlink #- t_ext: *job_native_compile_ext_bleeps + - t_ethdebug_output_validity: + <<: *requires_b_ubu_static + - c_ext_benchmarks: <<: *requires_nothing requires: diff --git a/test/ethdebugSchemaTests/conftest.py b/test/ethdebugSchemaTests/conftest.py new file mode 100644 index 000000000000..3f6a278f3f14 --- /dev/null +++ b/test/ethdebugSchemaTests/conftest.py @@ -0,0 +1,49 @@ +import shutil +import subprocess +from pathlib import Path + +import pytest +import referencing +import yaml +from referencing.jsonschema import DRAFT202012 + + +def pytest_addoption(parser): + parser.addoption("--solc-binary-path", type=Path, required=True, help="Path to the solidity compiler binary.") + + +@pytest.fixture +def solc_path(request): + solc_path = request.config.getoption("--solc-binary-path") + assert solc_path.is_file() + assert solc_path.exists() + return solc_path + + +@pytest.fixture(scope="module") +def ethdebug_clone_dir(tmpdir_factory): + temporary_dir = Path(tmpdir_factory.mktemp("data")) + yield temporary_dir + shutil.rmtree(temporary_dir) + + +@pytest.fixture(scope="module") +def ethdebug_schema_repository(ethdebug_clone_dir): + process = subprocess.run( + ["git", "clone", "https://github.com/ethdebug/format.git", ethdebug_clone_dir], + encoding="utf8", + capture_output=True, + check=True + ) + assert process.returncode == 0 + + registry = referencing.Registry() + for path in (ethdebug_clone_dir / "schemas").rglob("*.yaml"): + with open(path, "r", encoding="utf8") as f: + schema = yaml.safe_load(f) + if "$id" in schema: + resource = referencing.Resource.from_contents(schema, DRAFT202012) + registry = resource @ registry + else: + raise ValueError(f"Schema did not define an $id: {path}") + return registry diff --git a/test/ethdebugSchemaTests/input_file.json b/test/ethdebugSchemaTests/input_file.json new file mode 100644 index 000000000000..7daf7afd6852 --- /dev/null +++ b/test/ethdebugSchemaTests/input_file.json @@ -0,0 +1,27 @@ +{ + "language": "Solidity", + "sources": { + "a.sol": { + "content": "//SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract A1 { function a(uint x) public pure { assert(x > 0); } } contract A2 { function a(uint x) public pure { assert(x > 0); } }" + }, + "b.sol": { + "content": "//SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract A1 { function b(uint x) public pure { assert(x > 0); } } contract B2 { function b(uint x) public pure { assert(x > 0); } }" + } + }, + "settings": { + "viaIR": true, + "debug": { + "debugInfo": [ + "ethdebug" + ] + }, + "outputSelection": { + "*": { + "*": [ + "evm.bytecode.ethdebug", + "evm.deployedBytecode.ethdebug" + ] + } + } + } +} diff --git a/test/ethdebugSchemaTests/input_file_eof.json b/test/ethdebugSchemaTests/input_file_eof.json new file mode 100644 index 000000000000..0462065327f8 --- /dev/null +++ b/test/ethdebugSchemaTests/input_file_eof.json @@ -0,0 +1,29 @@ +{ + "language": "Solidity", + "sources": { + "a.sol": { + "content": "//SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract A1 { function a(uint x) public pure { assert(x > 0); } } contract A2 { function a(uint x) public pure { assert(x > 0); } }" + }, + "b.sol": { + "content": "//SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract A1 { function b(uint x) public pure { assert(x > 0); } } contract B2 { function b(uint x) public pure { assert(x > 0); } }" + } + }, + "settings": { + "eofVersion": 1, + "evmVersion": "osaka", + "viaIR": true, + "debug": { + "debugInfo": [ + "ethdebug" + ] + }, + "outputSelection": { + "*": { + "*": [ + "evm.bytecode.ethdebug", + "evm.deployedBytecode.ethdebug" + ] + } + } + } +} diff --git a/test/ethdebugSchemaTests/test_ethdebug_schema_conformity.py b/test/ethdebugSchemaTests/test_ethdebug_schema_conformity.py new file mode 100755 index 000000000000..6a349e7b17b8 --- /dev/null +++ b/test/ethdebugSchemaTests/test_ethdebug_schema_conformity.py @@ -0,0 +1,51 @@ +#!/usr/bin/env python3 + +import json +import subprocess +from pathlib import Path + +import jsonschema +import pytest + + +def get_nested_value(dictionary, *keys): + for key in keys: + dictionary = dictionary[key] + return dictionary + + +@pytest.fixture(params=["input_file.json", "input_file_eof.json"]) +def solc_output(request, solc_path): + testfile_dir = Path(__file__).parent + with open(testfile_dir / request.param, "r", encoding="utf8") as f: + source = json.load(f) + + process = subprocess.run( + [solc_path, "--standard-json"], + input=json.dumps(source), + encoding="utf8", + capture_output=True, + check=True, + ) + assert process.returncode == 0 + return json.loads(process.stdout) + + +@pytest.mark.parametrize("output_selection", ["evm.bytecode.ethdebug", "evm.deployedBytecode.ethdebug"], ids=str) +def test_program_schema( + output_selection, + ethdebug_schema_repository, + solc_output +): + validator = jsonschema.Draft202012Validator( + schema={"$ref": "schema:ethdebug/format/program"}, + registry=ethdebug_schema_repository + ) + assert "contracts" in solc_output + for contract in solc_output["contracts"].keys(): + contract_output = solc_output["contracts"][contract] + assert len(contract_output) > 0 + for source in contract_output.keys(): + source_output = contract_output[source] + ethdebug_data = get_nested_value(source_output, *(output_selection.split("."))) + validator.validate(ethdebug_data) From b04a46b13b9b50770214b74e19158158d5684d12 Mon Sep 17 00:00:00 2001 From: Coder <161350311+MamunC0der@users.noreply.github.com> Date: Wed, 11 Jun 2025 18:56:03 +0200 Subject: [PATCH 0990/1022] Fix broken HackMD link in release checklist (#16080) * Update ReleaseChecklist.md --- ReleaseChecklist.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ReleaseChecklist.md b/ReleaseChecklist.md index c9fcaba79fb7..acaabca63c8b 100644 --- a/ReleaseChecklist.md +++ b/ReleaseChecklist.md @@ -26,7 +26,7 @@ At least a day before the release: This is recommended especially when dealing with PPA for the first time, when we add a new Ubuntu version or when the PPA scripts were modified in this release cycle. - [ ] Verify that the release tarball of `solc-js` works. Bump version locally, add `soljson.js` from CI, build it, compare the file structure with the previous version, install it locally and try to use it. -- [ ] Review [Learning from Past Releases](https://notes.ethereum.org/@solidity/release-mistakes) to make sure you don't repeat the same mistakes. +- [ ] Review [Learning from Past Releases](https://notes.argot.org/@solidity-release-mistakes) to make sure you don't repeat the same mistakes. ### Drafts At least a day before the release: @@ -119,6 +119,6 @@ At least a day before the release: - [ ] Share the announcement on [Project Updates](https://discord.com/channels/420394352083337236/798974456704925696) - [ ] Share the announcement on [`#solidity` channel on Matrix](https://matrix.to/#/#ethereum_solidity:gitter.im) - [ ] Share the announcement on [`#solc-tooling`](https://matrix.to/#/#solc-tooling:matrix.org) -- [ ] If anything went wrong this time, mention it in [Learning from Past Releases](https://notes.ethereum.org/@solidity/release-mistakes). +- [ ] If anything went wrong this time, mention it in [Learning from Past Releases](https://notes.argot.org/@solidity-release-mistakes). - [ ] Bump vendored dependencies. - [ ] Lean back, wait for bug reports and repeat from step 1 :). From 637a8a11da2892d4c65cdb7d5f843d5b559fe822 Mon Sep 17 00:00:00 2001 From: Nikola Matic Date: Mon, 16 Jun 2025 14:48:04 +0200 Subject: [PATCH 0991/1022] Fix b_osx homebrew issue --- .circleci/osx_install_dependencies.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.circleci/osx_install_dependencies.sh b/.circleci/osx_install_dependencies.sh index 367e8cbb40cb..3ac380e36785 100755 --- a/.circleci/osx_install_dependencies.sh +++ b/.circleci/osx_install_dependencies.sh @@ -48,6 +48,8 @@ function validate_checksum { if [ ! -f /usr/local/lib/libz3.a ] # if this file does not exists (cache was not restored), rebuild dependencies then + brew uninstall temurin17 + brew untap homebrew/homebrew-cask-versions brew update brew upgrade brew install cmake From 48d1c9f4c02fc7f789c19ba74c9e5c86974450e3 Mon Sep 17 00:00:00 2001 From: kilavvy <140459108+kilavvy@users.noreply.github.com> Date: Tue, 17 Jun 2025 13:14:44 +0200 Subject: [PATCH 0992/1022] Rename dev_return_desc_multiple_unamed_mixed.sol to dev_return_desc_multiple_unnamed_mixed.sol --- ...named_mixed.sol => dev_return_desc_multiple_unnamed_mixed.sol} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename test/libsolidity/natspecJSON/{dev_return_desc_multiple_unamed_mixed.sol => dev_return_desc_multiple_unnamed_mixed.sol} (100%) diff --git a/test/libsolidity/natspecJSON/dev_return_desc_multiple_unamed_mixed.sol b/test/libsolidity/natspecJSON/dev_return_desc_multiple_unnamed_mixed.sol similarity index 100% rename from test/libsolidity/natspecJSON/dev_return_desc_multiple_unamed_mixed.sol rename to test/libsolidity/natspecJSON/dev_return_desc_multiple_unnamed_mixed.sol From e6d1fea4e183dae891c4be56b26d30530c7e3028 Mon Sep 17 00:00:00 2001 From: kilavvy <140459108+kilavvy@users.noreply.github.com> Date: Tue, 17 Jun 2025 13:16:16 +0200 Subject: [PATCH 0993/1022] Rename dev_return_desc_multiple_unamed_mixed_2.sol to dev_return_desc_multiple_unnamed_mixed_2.sol --- ...d_mixed_2.sol => dev_return_desc_multiple_unnamed_mixed_2.sol} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename test/libsolidity/natspecJSON/{dev_return_desc_multiple_unamed_mixed_2.sol => dev_return_desc_multiple_unnamed_mixed_2.sol} (100%) diff --git a/test/libsolidity/natspecJSON/dev_return_desc_multiple_unamed_mixed_2.sol b/test/libsolidity/natspecJSON/dev_return_desc_multiple_unnamed_mixed_2.sol similarity index 100% rename from test/libsolidity/natspecJSON/dev_return_desc_multiple_unamed_mixed_2.sol rename to test/libsolidity/natspecJSON/dev_return_desc_multiple_unnamed_mixed_2.sol From 9a4100a08c711837c5f350eb0dc2608d6dabc1cf Mon Sep 17 00:00:00 2001 From: kilavvy <140459108+kilavvy@users.noreply.github.com> Date: Tue, 17 Jun 2025 13:16:53 +0200 Subject: [PATCH 0994/1022] Rename dev_return_desc_multiple_unamed.sol to dev_return_desc_multiple_unnamed.sol --- ...c_multiple_unamed.sol => dev_return_desc_multiple_unnamed.sol} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename test/libsolidity/natspecJSON/{dev_return_desc_multiple_unamed.sol => dev_return_desc_multiple_unnamed.sol} (100%) diff --git a/test/libsolidity/natspecJSON/dev_return_desc_multiple_unamed.sol b/test/libsolidity/natspecJSON/dev_return_desc_multiple_unnamed.sol similarity index 100% rename from test/libsolidity/natspecJSON/dev_return_desc_multiple_unamed.sol rename to test/libsolidity/natspecJSON/dev_return_desc_multiple_unnamed.sol From 67288d658b1e0d0e6abdff6ca5787c24d6e3cf3f Mon Sep 17 00:00:00 2001 From: Emmanuel Ferdman Date: Wed, 21 May 2025 09:05:59 -0700 Subject: [PATCH 0995/1022] Correct the regex calls Signed-off-by: Emmanuel Ferdman --- scripts/wasm-rebuild/docker-scripts/isolate_tests.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/wasm-rebuild/docker-scripts/isolate_tests.py b/scripts/wasm-rebuild/docker-scripts/isolate_tests.py index 41487325edac..cc84f89bb254 100755 --- a/scripts/wasm-rebuild/docker-scripts/isolate_tests.py +++ b/scripts/wasm-rebuild/docker-scripts/isolate_tests.py @@ -46,7 +46,7 @@ def extract_and_write(f, path): def write_cases(f, tests): cleaned_filename = f.replace(".","_").replace("-","_").replace(" ","_").lower() for test in tests: - remainder = re.sub(r'^ {4}', '', test, 0, re.MULTILINE) + remainder = re.sub(r'^ {4}', '', test, count=0, flags=re.MULTILINE) source_code_hash = hashlib.sha256(test).hexdigest() with open(f'test_{source_code_hash}_{cleaned_filename}.sol', 'w', encoding='utf8') as _f: _f.write(remainder) From fbd9d1a7fb2bc7139a6c293e7ccc6eb3e594c8df Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Thu, 3 Jul 2025 09:11:02 +0200 Subject: [PATCH 0996/1022] ci: add "--break-system-packages" to pip install `pip install` or even `pip install --user` on its own does not work anymore on recent ubuntu versions to prevent breaking system packages (PEP 0668) --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index def71c0bf96d..8b69287b8a7e 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -127,7 +127,7 @@ commands: if [[ "<< parameters.packages >>" != "" ]] then echo "Installing additional packages..." - python3 -m pip install --user << parameters.packages >> + python3 -m pip install --user --break-system-packages << parameters.packages >> fi install_foundry: From aa1dae1f09500a785fb6770247d2d268ab8dae45 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Thu, 10 Jul 2025 14:13:40 +0200 Subject: [PATCH 0997/1022] external tests: pin gnosis to v1.4.1 it fails with a type error in OZ for v1.5.0 --- test/externalTests/gnosis.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/externalTests/gnosis.sh b/test/externalTests/gnosis.sh index 416d36153623..397786d65ff0 100755 --- a/test/externalTests/gnosis.sh +++ b/test/externalTests/gnosis.sh @@ -37,7 +37,7 @@ function test_fn { npm test; } function gnosis_safe_test { local repo="https://github.com/safe-global/safe-contracts.git" - local ref="" + local ref="v1.4.1" local config_file="hardhat.config.ts" local config_var=userConfig From 4efb2b33f998200bf74d03685e7fe9b523f3a343 Mon Sep 17 00:00:00 2001 From: emmmm <155267286+eeemmmmmm@users.noreply.github.com> Date: Wed, 2 Jul 2025 08:21:00 +0200 Subject: [PATCH 0998/1022] Replace string comparison with empty() method in DocStringParser --- libsolidity/parsing/DocStringParser.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libsolidity/parsing/DocStringParser.cpp b/libsolidity/parsing/DocStringParser.cpp index b9f358e020a0..13e43a9488ed 100644 --- a/libsolidity/parsing/DocStringParser.cpp +++ b/libsolidity/parsing/DocStringParser.cpp @@ -163,7 +163,7 @@ DocStringParser::iter DocStringParser::parseDocTag(iter _pos, iter _end, std::st { // TODO: need to check for @(start of a tag) between here and the end of line // for all cases. - if (!m_lastTag || _tag != "") + if (!m_lastTag || !_tag.empty()) { if (_tag == "param") return parseDocTagParam(_pos, _end); From a81065a01e9b0d3ab10849d3b2ca50f2bc9af6fd Mon Sep 17 00:00:00 2001 From: emmmm <155267286+eeemmmmmm@users.noreply.github.com> Date: Wed, 2 Jul 2025 08:21:32 +0200 Subject: [PATCH 0999/1022] Replace string comparison with empty() method in Parser --- libsolidity/parsing/Parser.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libsolidity/parsing/Parser.cpp b/libsolidity/parsing/Parser.cpp index 8889e65087fa..ddffdb600229 100644 --- a/libsolidity/parsing/Parser.cpp +++ b/libsolidity/parsing/Parser.cpp @@ -217,7 +217,7 @@ void Parser::parsePragmaVersion(SourceLocation const& _location, std::vector Parser::parseStructuredDocumentation() { - if (m_scanner->currentCommentLiteral() != "") + if (!m_scanner->currentCommentLiteral().empty()) { ASTNodeFactory nodeFactory{*this}; nodeFactory.setLocation(m_scanner->currentCommentLocation()); @@ -1445,7 +1445,7 @@ ASTPointer Parser::parseStatement(bool _allowUnchecked) RecursionGuard recursionGuard(*this); ASTPointer docString; ASTPointer statement; - if (m_scanner->currentCommentLiteral() != "") + if (!m_scanner->currentCommentLiteral().empty()) docString = std::make_shared(m_scanner->currentCommentLiteral()); switch (m_scanner->currentToken()) { From 66541b9f265994e3f1eeb4d1b50b22b87d66f9a2 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Fri, 11 Jul 2025 09:05:19 +0200 Subject: [PATCH 1000/1022] yulrun: Move dialect check of parse step after analyze The yul stack only has a dialect set when it is past the analysis stage --- test/tools/yulrun.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/tools/yulrun.cpp b/test/tools/yulrun.cpp index a5fa05d934ce..99d9df1a9cd2 100644 --- a/test/tools/yulrun.cpp +++ b/test/tools/yulrun.cpp @@ -63,11 +63,11 @@ std::pair, std::shared_ptr> parse(st solidity::frontend::OptimiserSettings::none(), DebugInfoSelection::Default() ); - auto const* evmDialect = dynamic_cast(&stack.dialect()); - // TODO: Add EOF support - solUnimplementedAssert(evmDialect && !evmDialect->eofVersion(), "No EOF support for yulrun yet."); if (stack.parseAndAnalyze("--INPUT--", _source)) { + auto const* evmDialect = dynamic_cast(&stack.dialect()); + // TODO: Add EOF support + solUnimplementedAssert(evmDialect && !evmDialect->eofVersion(), "No EOF support for yulrun yet."); yulAssert(!Error::hasErrorsWarningsOrInfos(stack.errors()), "Parsed successfully but had errors."); return make_pair(stack.parserResult()->code(), stack.parserResult()->analysisInfo); } From 53df4b721445ee7ad891a7795a03f6bfcf6e0912 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Fri, 25 Apr 2025 14:04:14 +0200 Subject: [PATCH 1001/1022] Add EVMVersion::current() helper --- liblangutil/EVMVersion.h | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/liblangutil/EVMVersion.h b/liblangutil/EVMVersion.h index 38580621a45e..f771d9f1cdf6 100644 --- a/liblangutil/EVMVersion.h +++ b/liblangutil/EVMVersion.h @@ -28,8 +28,6 @@ #include #include -#include - namespace solidity::evmasm { @@ -44,13 +42,13 @@ namespace solidity::langutil * A version specifier of the EVM we want to compile to. * Defaults to the latest version deployed on Ethereum Mainnet at the time of compiler release. */ -class EVMVersion: - boost::less_than_comparable, - boost::equality_comparable +class EVMVersion { public: EVMVersion() = default; + static EVMVersion current() { return {currentVersion}; } + static EVMVersion homestead() { return {Version::Homestead}; } static EVMVersion tangerineWhistle() { return {Version::TangerineWhistle}; } static EVMVersion spuriousDragon() { return {Version::SpuriousDragon}; } @@ -96,11 +94,10 @@ class EVMVersion: static EVMVersion firstWithEOF() { return {Version::Osaka}; } bool isExperimental() const { - return *this > EVMVersion{}; + return m_version > currentVersion; } - bool operator==(EVMVersion const& _other) const { return m_version == _other.m_version; } - bool operator<(EVMVersion const& _other) const { return m_version < _other.m_version; } + auto operator<=>(EVMVersion const&) const = default; std::string name() const { @@ -164,10 +161,11 @@ class EVMVersion: Prague, Osaka, }; + static auto constexpr currentVersion = Version::Prague; EVMVersion(Version _version): m_version(_version) {} - Version m_version = Version::Prague; + Version m_version = currentVersion; }; } From 70592afd73a9d8fe3bf6ae4598c6de6f495e66e5 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Thu, 20 Mar 2025 09:12:05 +0100 Subject: [PATCH 1002/1022] First define _all_ EVM functions, then declare them based on EVM version and configuration --- libyul/backends/evm/EVMDialect.cpp | 611 ++++++++++++++--------- libyul/backends/evm/EVMDialect.h | 2 +- libyul/backends/evm/NoOutputAssembly.cpp | 42 +- 3 files changed, 405 insertions(+), 250 deletions(-) diff --git a/libyul/backends/evm/EVMDialect.cpp b/libyul/backends/evm/EVMDialect.cpp index d68ef16348b1..87cd876ae254 100644 --- a/libyul/backends/evm/EVMDialect.cpp +++ b/libyul/backends/evm/EVMDialect.cpp @@ -21,17 +21,21 @@ #include +#include #include #include -#include + #include #include #include #include #include -#include +#include + #include +#include +#include #include #include @@ -56,55 +60,32 @@ std::tuple constexpr verbatimIndexToArgsAndRets(size_t _index) return std::make_tuple(_index - numRets * EVMDialect::verbatimMaxInputSlots, numRets); } -BuiltinFunctionForEVM createEVMFunction( - langutil::EVMVersion _evmVersion, - std::string const& _name, - evmasm::Instruction _instruction -) +bool isLowLevelStackManipulationInstruction(evmasm::Instruction const& _instruction) { - BuiltinFunctionForEVM f; - evmasm::InstructionInfo info = evmasm::instructionInfo(_instruction, _evmVersion); - f.name = _name; - f.numParameters = static_cast(info.args); - f.numReturns = static_cast(info.ret); - f.sideEffects = EVMDialect::sideEffectsOfInstruction(_instruction); - f.controlFlowSideEffects = ControlFlowSideEffects::fromInstruction(_instruction); - f.isMSize = _instruction == evmasm::Instruction::MSIZE; - f.literalArguments.clear(); - f.instruction = _instruction; - f.generateCode = [_instruction]( - FunctionCall const&, - AbstractAssembly& _assembly, - BuiltinContext& - ) { - _assembly.appendInstruction(_instruction); - }; - return f; + return + _instruction == evmasm::Instruction::SWAPN || + evmasm::SemanticInformation::isSwapInstruction(_instruction) || + _instruction == evmasm::Instruction::DUPN || + evmasm::SemanticInformation::isDupInstruction(_instruction) || + isPushInstruction(_instruction); } -BuiltinFunctionForEVM createFunction( - std::string const& _name, - size_t _params, - size_t _returns, - SideEffects _sideEffects, - ControlFlowSideEffects _controlFlowSideEffects, - std::vector> _literalArguments, - std::function _generateCode -) +bool isLowLevelControlFlowInstruction(evmasm::Instruction const& _instruction) { - yulAssert(_literalArguments.size() == _params || _literalArguments.empty(), ""); - - BuiltinFunctionForEVM f; - f.name = _name; - f.numParameters = _params; - f.numReturns = _returns; - f.sideEffects = _sideEffects; - f.controlFlowSideEffects = _controlFlowSideEffects; - f.literalArguments = std::move(_literalArguments); - f.isMSize = false; - f.instruction = {}; - f.generateCode = std::move(_generateCode); - return f; + switch (_instruction) + { + case evmasm::Instruction::JUMP: + case evmasm::Instruction::JUMPI: + case evmasm::Instruction::JUMPDEST: + case evmasm::Instruction::JUMPF: + case evmasm::Instruction::RJUMP: + case evmasm::Instruction::RJUMPI: + case evmasm::Instruction::RETF: + case evmasm::Instruction::CALLF: + return true; + default: + return false; + } } std::set> createReservedIdentifiers(langutil::EVMVersion _evmVersion, std::optional _eofVersion) @@ -195,47 +176,7 @@ std::set> createReservedIdentifiers(langutil::EVMVersio return reserved; } -std::vector> createBuiltins(langutil::EVMVersion _evmVersion, std::optional _eofVersion, bool _objectAccess) -{ - - // Exclude prevrandao as builtin for VMs before paris and difficulty for VMs after paris. - auto prevRandaoException = [&](std::string const& _instrName) -> bool - { - return (_instrName == "prevrandao" && _evmVersion < langutil::EVMVersion::paris()) || (_instrName == "difficulty" && _evmVersion >= langutil::EVMVersion::paris()); - }; - - std::vector> builtins; - for (auto const& instr: evmasm::c_instructions) - { - std::string name = toLower(instr.first); - auto const opcode = instr.second; - - if ( - !(opcode >= evmasm::Instruction::DUP1 && opcode <= evmasm::Instruction::DUP16) && - !(opcode >= evmasm::Instruction::SWAP1 && opcode <= evmasm::Instruction::SWAP16) && - !evmasm::isPushInstruction(opcode) && - opcode != evmasm::Instruction::JUMP && - opcode != evmasm::Instruction::JUMPI && - opcode != evmasm::Instruction::JUMPDEST && - opcode != evmasm::Instruction::DATALOADN && - opcode != evmasm::Instruction::EOFCREATE && - opcode != evmasm::Instruction::RETURNCONTRACT && - opcode != evmasm::Instruction::RJUMP && - opcode != evmasm::Instruction::RJUMPI && - opcode != evmasm::Instruction::CALLF && - opcode != evmasm::Instruction::JUMPF && - opcode != evmasm::Instruction::DUPN && - opcode != evmasm::Instruction::SWAPN && - opcode != evmasm::Instruction::RETF && - _evmVersion.hasOpcode(opcode, _eofVersion) && - !prevRandaoException(name) - ) - builtins.emplace_back(createEVMFunction(_evmVersion, name, opcode)); - else - builtins.emplace_back(std::nullopt); - } - - auto const createIfObjectAccess = [_objectAccess]( +BuiltinFunctionForEVM createFunction( std::string const& _name, size_t _params, size_t _returns, @@ -243,64 +184,200 @@ std::vector> createBuiltins(langutil::EVMVe ControlFlowSideEffects _controlFlowSideEffects, std::vector> _literalArguments, std::function _generateCode - ) -> std::optional + ) +{ + yulAssert(_literalArguments.size() == _params || _literalArguments.empty(), ""); + + BuiltinFunctionForEVM f; + f.name = _name; + f.numParameters = _params; + f.numReturns = _returns; + f.sideEffects = _sideEffects; + f.controlFlowSideEffects = _controlFlowSideEffects; + f.literalArguments = std::move(_literalArguments); + f.isMSize = false; + f.instruction = {}; + f.generateCode = std::move(_generateCode); + return f; +} + +class BuiltinFunctionCollection +{ + static size_t constexpr instructionBit = 0; + static size_t constexpr replacedInstructionBit = 1; + static size_t constexpr objectAccessBit = 2; + static size_t constexpr requiresEOFBit = 3; + static size_t constexpr requiresNonEOFBit = 4; +public: + struct BuiltinDescription { - if (!_objectAccess) - return std::nullopt; - return createFunction(_name, _params, _returns, _sideEffects, _controlFlowSideEffects, std::move(_literalArguments), std::move(_generateCode)); + /// whether the corresponding evm builtin function is an instruction builtin + bool instruction() const { return value.test(instructionBit); } + /// whether the corresponding evm builtin has been replaced by another builtin, ie, should be skipped + bool replaced() const { return value.test(replacedInstructionBit); } + /// if true, the evm builtin function is only valid when object access is given + bool requiresObjectAccess() const { return value.test(objectAccessBit); } + /// if true, the evm builtin function is only valid if EOF is enabled + bool requiresEOF() const { return value.test(requiresEOFBit); } + /// if true, the evm builtin function is only valid if EOF is not enabled + bool requiresNonEOF() const { return value.test(requiresNonEOFBit); } + + BuiltinDescription operator|(BuiltinDescription const& _other) const + { + return { value | _other.value }; + } + + std::bitset<5> value; }; - builtins.emplace_back(createIfObjectAccess("linkersymbol", 1, 1, SideEffects{}, ControlFlowSideEffects{}, {LiteralKind::String}, []( - FunctionCall const& _call, - AbstractAssembly& _assembly, - BuiltinContext& - ) { - yulAssert(_call.arguments.size() == 1, ""); - Expression const& arg = _call.arguments.front(); - _assembly.appendLinkerSymbol(formatLiteral(std::get(arg))); - })); - builtins.emplace_back(createIfObjectAccess( - "memoryguard", - 1, - 1, - SideEffects{}, - ControlFlowSideEffects{}, - {LiteralKind::Number}, - []( - FunctionCall const& _call, + static std::vector> const& builtins() + { + static BuiltinFunctionCollection const instance; + return instance.m_builtinFunctions; + } + +private: + static BuiltinDescription constexpr instruction{1 << instructionBit}; + static BuiltinDescription constexpr replaced{1 << replacedInstructionBit}; + static BuiltinDescription constexpr objectAccess{1 << objectAccessBit}; + static BuiltinDescription constexpr requiresEOF{1 << requiresEOFBit}; + static BuiltinDescription constexpr requiresNonEOF{1 << requiresNonEOFBit}; + + BuiltinFunctionCollection() + { + for (auto const& [name, opcode]: evmasm::c_instructions) + { + if (evmasm::SemanticInformation::isSwapInstruction(opcode) || evmasm::SemanticInformation::isDupInstruction(opcode)) + continue; + + if ( + opcode != evmasm::Instruction::DATALOADN && + opcode != evmasm::Instruction::EOFCREATE && + opcode != evmasm::Instruction::RETURNCONTRACT + ) + { + // difficulty was replaced by prevrandao after london + if (opcode == evmasm::Instruction::PREVRANDAO && name == "DIFFICULTY") + m_builtinFunctions.emplace_back(instruction, instructionBuiltin(opcode, langutil::EVMVersion::london())); + else + m_builtinFunctions.emplace_back(instruction, instructionBuiltin(opcode, langutil::EVMVersion::current())); + } + else + // these opcodes are replaced by explicit builtin functions + m_builtinFunctions.emplace_back(instruction | replaced, BuiltinFunctionForEVM{}); + } + + m_builtinFunctions.emplace_back(objectAccess, linkersymbolBuiltin()); + m_builtinFunctions.emplace_back(objectAccess, memoryguardBuiltin()); + + m_builtinFunctions.emplace_back(objectAccess | requiresNonEOF, datasizeBuiltin()); + m_builtinFunctions.emplace_back(objectAccess | requiresNonEOF, dataoffsetBuiltin()); + m_builtinFunctions.emplace_back(objectAccess | requiresNonEOF, datacopyBuiltin()); + m_builtinFunctions.emplace_back(objectAccess | requiresNonEOF, setimmutableBuiltin()); + m_builtinFunctions.emplace_back(objectAccess | requiresNonEOF, loadimmutableBuiltin()); + + m_builtinFunctions.emplace_back(objectAccess | requiresEOF, auxdataloadnBuiltin()); + m_builtinFunctions.emplace_back(objectAccess | requiresEOF, eofcreateBuiltin()); + m_builtinFunctions.emplace_back(objectAccess | requiresEOF, returncontractBuiltin()); + + yulAssert( + ranges::all_of(m_builtinFunctions, [](std::tuple const& _builtin) { + return std::get<1>(_builtin).name.substr(0, "verbatim_"s.size()) != "verbatim_"; + }), + "Builtin functions besides verbatim should not start with the verbatim_ prefix." + ); + } + + static BuiltinFunctionForEVM instructionBuiltin(evmasm::Instruction const& _instruction, langutil::EVMVersion const& _evmVersion) + { + evmasm::InstructionInfo const info = evmasm::instructionInfo(_instruction, _evmVersion); + BuiltinFunctionForEVM f; + f.name = toLower(info.name); + f.numParameters = static_cast(info.args); + f.numReturns = static_cast(info.ret); + f.sideEffects = EVMDialect::sideEffectsOfInstruction(_instruction); + f.controlFlowSideEffects = ControlFlowSideEffects::fromInstruction(_instruction); + f.isMSize = _instruction == evmasm::Instruction::MSIZE; + f.literalArguments.clear(); + f.instruction = _instruction; + f.generateCode = [_instruction]( + FunctionCall const&, AbstractAssembly& _assembly, BuiltinContext& - ) { - yulAssert(_call.arguments.size() == 1, ""); - Literal const* literal = std::get_if(&_call.arguments.front()); - yulAssert(literal, ""); - _assembly.appendConstant(literal->value.value()); - }) - ); - if (!_eofVersion.has_value()) + ) + { + _assembly.appendInstruction(_instruction); + }; + return f; + } + + static BuiltinFunctionForEVM linkersymbolBuiltin() { - builtins.emplace_back(createIfObjectAccess("datasize", 1, 1, SideEffects{}, ControlFlowSideEffects{}, {LiteralKind::String}, []( - FunctionCall const& _call, - AbstractAssembly& _assembly, - BuiltinContext& _context - ) { - yulAssert(_context.currentObject, "No object available."); - yulAssert(_call.arguments.size() == 1, ""); - Expression const& arg = _call.arguments.front(); - YulName const dataName (formatLiteral(std::get(arg))); - if (_context.currentObject->name == dataName.str()) - _assembly.appendAssemblySize(); - else - { - std::vector subIdPath = - _context.subIDs.count(dataName.str()) == 0 ? - _context.currentObject->pathToSubObject(dataName.str()) : - std::vector{_context.subIDs.at(dataName.str())}; - yulAssert(!subIdPath.empty(), "Could not find assembly object <" + dataName.str() + ">."); - _assembly.appendDataSize(subIdPath); + return createFunction( + "linkersymbol", + 1, + 1, + SideEffects{}, + ControlFlowSideEffects{}, + {LiteralKind::String}, + [](FunctionCall const& _call, AbstractAssembly& _assembly, BuiltinContext&) { + yulAssert(_call.arguments.size() == 1, ""); + Expression const& arg = _call.arguments.front(); + _assembly.appendLinkerSymbol(formatLiteral(std::get(arg))); } - })); - builtins.emplace_back(createIfObjectAccess("dataoffset", 1, 1, SideEffects{}, ControlFlowSideEffects{}, {LiteralKind::String}, []( + ); + } + + static BuiltinFunctionForEVM memoryguardBuiltin() + { + return createFunction( + "memoryguard", + 1, + 1, + SideEffects{}, + ControlFlowSideEffects{}, + {LiteralKind::Number}, + [](FunctionCall const& _call, AbstractAssembly& _assembly, BuiltinContext&) { + yulAssert(_call.arguments.size() == 1, ""); + Literal const* literal = std::get_if(&_call.arguments.front()); + yulAssert(literal, ""); + _assembly.appendConstant(literal->value.value()); + } + ); + } + + static BuiltinFunctionForEVM datasizeBuiltin() + { + return createFunction( + "datasize", + 1, + 1, + SideEffects{}, + ControlFlowSideEffects{}, + {LiteralKind::String}, + [](FunctionCall const& _call, AbstractAssembly& _assembly, BuiltinContext& _context) { + yulAssert(_context.currentObject, "No object available."); + yulAssert(_call.arguments.size() == 1, ""); + Expression const& arg = _call.arguments.front(); + YulName const dataName (formatLiteral(std::get(arg))); + if (_context.currentObject->name == dataName.str()) + _assembly.appendAssemblySize(); + else + { + std::vector subIdPath = + _context.subIDs.count(dataName.str()) == 0 ? + _context.currentObject->pathToSubObject(dataName.str()) : + std::vector{_context.subIDs.at(dataName.str())}; + yulAssert(!subIdPath.empty(), "Could not find assembly object <" + dataName.str() + ">."); + _assembly.appendDataSize(subIdPath); + } + } + ); + } + + static BuiltinFunctionForEVM dataoffsetBuiltin() + { + return createFunction("dataoffset", 1, 1, SideEffects{}, ControlFlowSideEffects{}, {LiteralKind::String}, []( FunctionCall const& _call, AbstractAssembly& _assembly, BuiltinContext& _context @@ -320,8 +397,12 @@ std::vector> createBuiltins(langutil::EVMVe yulAssert(!subIdPath.empty(), "Could not find assembly object <" + dataName.str() + ">."); _assembly.appendDataOffset(subIdPath); } - })); - builtins.emplace_back(createIfObjectAccess( + }); + } + + static BuiltinFunctionForEVM datacopyBuiltin() + { + return createFunction( "datacopy", 3, 0, @@ -335,8 +416,12 @@ std::vector> createBuiltins(langutil::EVMVe ) { _assembly.appendInstruction(evmasm::Instruction::CODECOPY); } - )); - builtins.emplace_back(createIfObjectAccess( + ); + } + + static BuiltinFunctionForEVM setimmutableBuiltin() + { + return createFunction( "setimmutable", 3, 0, @@ -362,8 +447,12 @@ std::vector> createBuiltins(langutil::EVMVe auto const identifier = (formatLiteral(std::get(_call.arguments[1]))); _assembly.appendImmutableAssignment(identifier); } - )); - builtins.emplace_back(createIfObjectAccess( + ); + } + + static BuiltinFunctionForEVM loadimmutableBuiltin() + { + return createFunction( "loadimmutable", 1, 1, @@ -378,86 +467,131 @@ std::vector> createBuiltins(langutil::EVMVe yulAssert(_call.arguments.size() == 1, ""); _assembly.appendImmutable(formatLiteral(std::get(_call.arguments.front()))); } - )); + ); + } + + static BuiltinFunctionForEVM auxdataloadnBuiltin() + { + return createFunction( + "auxdataloadn", + 1, + 1, + EVMDialect::sideEffectsOfInstruction(evmasm::Instruction::DATALOADN), + ControlFlowSideEffects::fromInstruction(evmasm::Instruction::DATALOADN), + {LiteralKind::Number}, + []( + FunctionCall const& _call, + AbstractAssembly& _assembly, + BuiltinContext& + ) { + yulAssert(_call.arguments.size() == 1); + Literal const* literal = std::get_if(&_call.arguments.front()); + yulAssert(literal, ""); + yulAssert(literal->value.value() <= std::numeric_limits::max()); + _assembly.appendAuxDataLoadN(static_cast(literal->value.value())); + } + ); + } + + static BuiltinFunctionForEVM eofcreateBuiltin() + { + return createFunction( + "eofcreate", + 5, + 1, + EVMDialect::sideEffectsOfInstruction(evmasm::Instruction::EOFCREATE), + ControlFlowSideEffects::fromInstruction(evmasm::Instruction::EOFCREATE), + {LiteralKind::String, std::nullopt, std::nullopt, std::nullopt, std::nullopt}, + []( + FunctionCall const& _call, + AbstractAssembly& _assembly, + BuiltinContext& context + ) { + yulAssert(_call.arguments.size() == 5); + Literal const* literal = std::get_if(&_call.arguments.front()); + auto const formattedLiteral = formatLiteral(*literal); + yulAssert(!util::contains(formattedLiteral, '.')); + auto const* containerID = valueOrNullptr(context.subIDs, formattedLiteral); + yulAssert(containerID != nullptr); + yulAssert(*containerID <= std::numeric_limits::max()); + _assembly.appendEOFCreate(static_cast(*containerID)); + } + ); } - else // EOF context + + static BuiltinFunctionForEVM returncontractBuiltin() { - if (_objectAccess) + return createFunction( + "returncontract", + 3, + 0, + EVMDialect::sideEffectsOfInstruction(evmasm::Instruction::RETURNCONTRACT), + ControlFlowSideEffects::fromInstruction(evmasm::Instruction::RETURNCONTRACT), + {LiteralKind::String, std::nullopt, std::nullopt}, + []( + FunctionCall const& _call, + AbstractAssembly& _assembly, + BuiltinContext& context + ) { + yulAssert(_call.arguments.size() == 3); + Literal const* literal = std::get_if(&_call.arguments.front()); + yulAssert(literal); + auto const formattedLiteral = formatLiteral(*literal); + yulAssert(!util::contains(formattedLiteral, '.')); + auto const* containerID = valueOrNullptr(context.subIDs, formattedLiteral); + yulAssert(containerID != nullptr); + yulAssert(*containerID <= std::numeric_limits::max()); + _assembly.appendReturnContract(static_cast(*containerID)); + } + ); + } + + std::vector> m_builtinFunctions; +}; + +/// Make sure to only add builtins in a way that is consistent over EVM versions. If the order depends on the +/// EVM version - which can easily happen using conditionals -, different dialects' builtin handles +/// become inherently incompatible. +std::vector createBuiltins(langutil::EVMVersion _evmVersion, std::optional _eofVersion, bool _objectAccess) +{ + std::vector builtins; + builtins.reserve(BuiltinFunctionCollection::builtins().size()); + + for (auto const& [description, builtin]: BuiltinFunctionCollection::builtins()) + { + bool builtinShouldBeAdded = true; + if (description.instruction()) { - builtins.emplace_back(createFunction( - "auxdataloadn", - 1, - 1, - EVMDialect::sideEffectsOfInstruction(evmasm::Instruction::DATALOADN), - ControlFlowSideEffects::fromInstruction(evmasm::Instruction::DATALOADN), - {LiteralKind::Number}, - []( - FunctionCall const& _call, - AbstractAssembly& _assembly, - BuiltinContext& - ) { - yulAssert(_call.arguments.size() == 1); - Literal const* literal = std::get_if(&_call.arguments.front()); - yulAssert(literal, ""); - yulAssert(literal->value.value() <= std::numeric_limits::max()); - _assembly.appendAuxDataLoadN(static_cast(literal->value.value())); - } - )); - - builtins.emplace_back(createFunction( - "eofcreate", - 5, - 1, - EVMDialect::sideEffectsOfInstruction(evmasm::Instruction::EOFCREATE), - ControlFlowSideEffects::fromInstruction(evmasm::Instruction::EOFCREATE), - {LiteralKind::String, std::nullopt, std::nullopt, std::nullopt, std::nullopt}, - []( - FunctionCall const& _call, - AbstractAssembly& _assembly, - BuiltinContext& context - ) { - yulAssert(_call.arguments.size() == 5); - Literal const* literal = std::get_if(&_call.arguments.front()); - auto const formattedLiteral = formatLiteral(*literal); - yulAssert(!util::contains(formattedLiteral, '.')); - auto const* containerID = valueOrNullptr(context.subIDs, formattedLiteral); - yulAssert(containerID != nullptr); - yulAssert(*containerID <= std::numeric_limits::max()); - _assembly.appendEOFCreate(static_cast(*containerID)); - } - )); - - builtins.emplace_back(createFunction( - "returncontract", - 3, - 0, - EVMDialect::sideEffectsOfInstruction(evmasm::Instruction::RETURNCONTRACT), - ControlFlowSideEffects::fromInstruction(evmasm::Instruction::RETURNCONTRACT), - {LiteralKind::String, std::nullopt, std::nullopt}, - []( - FunctionCall const& _call, - AbstractAssembly& _assembly, - BuiltinContext& context - ) { - yulAssert(_call.arguments.size() == 3); - Literal const* literal = std::get_if(&_call.arguments.front()); - yulAssert(literal); - auto const formattedLiteral = formatLiteral(*literal); - yulAssert(!util::contains(formattedLiteral, '.')); - auto const* containerID = valueOrNullptr(context.subIDs, formattedLiteral); - yulAssert(containerID != nullptr); - yulAssert(*containerID <= std::numeric_limits::max()); - _assembly.appendReturnContract(static_cast(*containerID)); - } - )); + if (description.replaced()) + builtinShouldBeAdded = false; + else + { + // Exclude prevrandao as builtin for VMs before paris and difficulty for VMs after paris. + auto prevRandaoException = [&](std::string_view const _instrName) -> bool + { + return (_instrName == "prevrandao" && _evmVersion < langutil::EVMVersion::paris()) || (_instrName == "difficulty" && _evmVersion >= langutil::EVMVersion::paris()); + }; + + yulAssert(builtin.instruction); + auto const& _opcode = *builtin.instruction; + builtinShouldBeAdded = + !isLowLevelControlFlowInstruction(_opcode) && + !isLowLevelStackManipulationInstruction(_opcode) && + _evmVersion.hasOpcode(_opcode, _eofVersion) && + !prevRandaoException(builtin.name); + } } + + builtinShouldBeAdded &= !description.requiresObjectAccess() || _objectAccess; + builtinShouldBeAdded &= !description.requiresEOF() || _eofVersion.has_value(); + builtinShouldBeAdded &= !description.requiresNonEOF() || !_eofVersion.has_value(); + + if (builtinShouldBeAdded) + builtins.emplace_back(&builtin); + else + builtins.emplace_back(nullptr); } - yulAssert( - ranges::all_of(builtins, [](std::optional const& _builtinFunction){ - return !_builtinFunction || _builtinFunction->name.substr(0, "verbatim_"s.size()) != "verbatim_"; - }), - "Builtin functions besides verbatim should not start with the verbatim_ prefix." - ); + return builtins; } @@ -482,14 +616,14 @@ EVMDialect::EVMDialect(langutil::EVMVersion _evmVersion, std::optional // ids are offset by the maximum number of verbatim functions m_builtinFunctionsByName[maybeBuiltin->name] = BuiltinHandle{index + verbatimIDOffset}; - m_discardFunction = findBuiltin("pop"); - m_equalityFunction = findBuiltin("eq"); - m_booleanNegationFunction = findBuiltin("iszero"); - m_memoryStoreFunction = findBuiltin("mstore"); - m_memoryLoadFunction = findBuiltin("mload"); - m_storageStoreFunction = findBuiltin("sstore"); - m_storageLoadFunction = findBuiltin("sload"); - m_hashFunction = findBuiltin("keccak256"); + m_discardFunction = EVMDialect::findBuiltin("pop"); + m_equalityFunction = EVMDialect::findBuiltin("eq"); + m_booleanNegationFunction = EVMDialect::findBuiltin("iszero"); + m_memoryStoreFunction = EVMDialect::findBuiltin("mstore"); + m_memoryLoadFunction = EVMDialect::findBuiltin("mload"); + m_storageStoreFunction = EVMDialect::findBuiltin("sstore"); + m_storageLoadFunction = EVMDialect::findBuiltin("sload"); + m_hashFunction = EVMDialect::findBuiltin("keccak256"); m_auxiliaryBuiltinHandles.add = EVMDialect::findBuiltin("add"); m_auxiliaryBuiltinHandles.exp = EVMDialect::findBuiltin("exp"); @@ -529,8 +663,8 @@ BuiltinFunctionForEVM const& EVMDialect::builtin(BuiltinHandle const& _handle) c } yulAssert(_handle.id - verbatimIDOffset < m_functions.size()); - auto const& maybeBuiltin = m_functions[_handle.id - verbatimIDOffset]; - yulAssert(maybeBuiltin.has_value()); + auto const* maybeBuiltin = m_functions[_handle.id - verbatimIDOffset]; + yulAssert(maybeBuiltin); return *maybeBuiltin; } @@ -563,22 +697,7 @@ EVMDialect const& EVMDialect::strictAssemblyForEVMObjects(langutil::EVMVersion _ SideEffects EVMDialect::sideEffectsOfInstruction(evmasm::Instruction _instruction) { - auto translate = [](evmasm::SemanticInformation::Effect _e) -> SideEffects::Effect - { - return static_cast(_e); - }; - - return SideEffects{ - evmasm::SemanticInformation::movable(_instruction), - evmasm::SemanticInformation::movableApartFromEffects(_instruction), - evmasm::SemanticInformation::canBeRemoved(_instruction), - evmasm::SemanticInformation::canBeRemovedIfNoMSize(_instruction), - true, // cannotLoop - translate(evmasm::SemanticInformation::otherState(_instruction)), - translate(evmasm::SemanticInformation::storage(_instruction)), - translate(evmasm::SemanticInformation::memory(_instruction)), - translate(evmasm::SemanticInformation::transientStorage(_instruction)), - }; + return ranges::views::keys(m_builtinFunctionsByName) | ranges::to; } BuiltinFunctionForEVM EVMDialect::createVerbatimFunctionFromHandle(BuiltinHandle const& _handle) diff --git a/libyul/backends/evm/EVMDialect.h b/libyul/backends/evm/EVMDialect.h index 0440daade1ce..73136ef6e30b 100644 --- a/libyul/backends/evm/EVMDialect.h +++ b/libyul/backends/evm/EVMDialect.h @@ -125,7 +125,7 @@ class EVMDialect: public Dialect langutil::EVMVersion const m_evmVersion; std::optional m_eofVersion; std::unordered_map m_builtinFunctionsByName; - std::vector> m_functions; + std::vector m_functions; std::array, verbatimIDOffset> mutable m_verbatimFunctions{}; std::set> m_reserved; diff --git a/libyul/backends/evm/NoOutputAssembly.cpp b/libyul/backends/evm/NoOutputAssembly.cpp index 78025265f342..55e034399e33 100644 --- a/libyul/backends/evm/NoOutputAssembly.cpp +++ b/libyul/backends/evm/NoOutputAssembly.cpp @@ -207,9 +207,45 @@ void NoOutputAssembly::appendReturnContract(ContainerID) NoOutputEVMDialect::NoOutputEVMDialect(EVMDialect const& _copyFrom): EVMDialect(_copyFrom.evmVersion(), _copyFrom.eofVersion(), _copyFrom.providesObjectAccess()) { - for (auto& fun: m_functions) - if (fun) - modifyBuiltinToNoOutput(*fun); + // save the modified functions here - note that this only has to be done once because we modify all of + // them in one go, later just reference pointers to this static vector + static std::vector const noOutputBuiltins = [] + { + std::vector modifiedBuiltins; + modifiedBuiltins.reserve(allBuiltins().functions().size()); + + for (auto const& [_, builtin]: allBuiltins().functions()) + { + auto noOutputFunction = builtin; + modifyBuiltinToNoOutput(noOutputFunction); + modifiedBuiltins.push_back(std::move(noOutputFunction)); + } + + return modifiedBuiltins; + }(); + + m_functions = [&] + { + std::vector result; + result.reserve(m_functions.size()); + for (auto const* builtinFunction: m_functions) + { + if (builtinFunction) + { + auto it = noOutputBuiltins.find(builtinFunction); + if (it == noOutputBuiltins.end()) + { + auto noOutputFunction = *builtinFunction; + modifyBuiltinToNoOutput(noOutputFunction); + it = noOutputBuiltins.emplace(builtinFunction, std::move(noOutputFunction)).first; + } + result.emplace_back(&it->second); + } + else + result.emplace_back(nullptr); + } + return result; + }(); } BuiltinFunctionForEVM const& NoOutputEVMDialect::builtin(BuiltinHandle const& _handle) const From 90078897b6dd0f4455908594feee85fef37df0e1 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Mon, 28 Apr 2025 10:48:06 +0200 Subject: [PATCH 1003/1022] Separate out builtin function collection into its own class This makes for a better separation between the declarations and the logic that defines builtins. # Conflicts: # libyul/backends/evm/EVMDialect.cpp --- libyul/CMakeLists.txt | 2 + libyul/backends/evm/EVMBuiltins.cpp | 419 +++++++++++++++++++++ libyul/backends/evm/EVMBuiltins.h | 120 ++++++ libyul/backends/evm/EVMDialect.cpp | 444 ++--------------------- libyul/backends/evm/EVMDialect.h | 36 +- libyul/backends/evm/NoOutputAssembly.cpp | 61 ++-- libyul/backends/evm/NoOutputAssembly.h | 3 + 7 files changed, 601 insertions(+), 484 deletions(-) create mode 100644 libyul/backends/evm/EVMBuiltins.cpp create mode 100644 libyul/backends/evm/EVMBuiltins.h diff --git a/libyul/CMakeLists.txt b/libyul/CMakeLists.txt index 68756fca92f0..58390d95653c 100644 --- a/libyul/CMakeLists.txt +++ b/libyul/CMakeLists.txt @@ -58,6 +58,8 @@ add_library(yul backends/evm/ControlFlowGraphBuilder.h backends/evm/EthAssemblyAdapter.cpp backends/evm/EthAssemblyAdapter.h + backends/evm/EVMBuiltins.cpp + backends/evm/EVMBuiltins.h backends/evm/EVMCodeTransform.cpp backends/evm/EVMCodeTransform.h backends/evm/EVMDialect.cpp diff --git a/libyul/backends/evm/EVMBuiltins.cpp b/libyul/backends/evm/EVMBuiltins.cpp new file mode 100644 index 000000000000..d8a3d5c8e34e --- /dev/null +++ b/libyul/backends/evm/EVMBuiltins.cpp @@ -0,0 +1,419 @@ +/* + This file is part of solidity. + + solidity is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + solidity is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with solidity. If not, see . +*/ +// SPDX-License-Identifier: GPL-3.0 + +#include + +#include +#include +#include + +#include + +#include + +#include + +using namespace solidity; +using namespace solidity::yul; + +namespace +{ + +BuiltinFunctionForEVM createFunction( + std::string const& _name, + size_t _params, + size_t _returns, + SideEffects _sideEffects, + ControlFlowSideEffects _controlFlowSideEffects, + std::vector> _literalArguments, + std::function _generateCode +) +{ + yulAssert(_literalArguments.size() == _params || _literalArguments.empty(), ""); + + BuiltinFunctionForEVM f; + f.name = _name; + f.numParameters = _params; + f.numReturns = _returns; + f.sideEffects = _sideEffects; + f.controlFlowSideEffects = _controlFlowSideEffects; + f.literalArguments = std::move(_literalArguments); + f.isMSize = false; + f.instruction = {}; + f.generateCode = std::move(_generateCode); + return f; +} + +BuiltinFunctionForEVM instructionBuiltin(evmasm::Instruction const& _instruction, langutil::EVMVersion const& _evmVersion) +{ + evmasm::InstructionInfo const info = evmasm::instructionInfo(_instruction, _evmVersion); + BuiltinFunctionForEVM f; + f.name = util::toLower(info.name); + f.numParameters = static_cast(info.args); + f.numReturns = static_cast(info.ret); + f.sideEffects = EVMBuiltins::sideEffectsOfInstruction(_instruction); + f.controlFlowSideEffects = ControlFlowSideEffects::fromInstruction(_instruction); + f.isMSize = _instruction == evmasm::Instruction::MSIZE; + f.literalArguments.clear(); + f.instruction = _instruction; + f.generateCode = [_instruction]( + FunctionCall const&, + AbstractAssembly& _assembly, + BuiltinContext& + ) + { + _assembly.appendInstruction(_instruction); + }; + return f; +} + +BuiltinFunctionForEVM linkersymbolBuiltin() +{ + return createFunction( + "linkersymbol", + 1, + 1, + SideEffects{}, + ControlFlowSideEffects{}, + {LiteralKind::String}, + [](FunctionCall const& _call, AbstractAssembly& _assembly, BuiltinContext&) { + yulAssert(_call.arguments.size() == 1, ""); + Expression const& arg = _call.arguments.front(); + _assembly.appendLinkerSymbol(formatLiteral(std::get(arg))); + } + ); +} + +BuiltinFunctionForEVM memoryguardBuiltin() +{ + return createFunction( + "memoryguard", + 1, + 1, + SideEffects{}, + ControlFlowSideEffects{}, + {LiteralKind::Number}, + [](FunctionCall const& _call, AbstractAssembly& _assembly, BuiltinContext&) { + yulAssert(_call.arguments.size() == 1, ""); + Literal const* literal = std::get_if(&_call.arguments.front()); + yulAssert(literal, ""); + _assembly.appendConstant(literal->value.value()); + } + ); +} + +BuiltinFunctionForEVM datasizeBuiltin() +{ + return createFunction( + "datasize", + 1, + 1, + SideEffects{}, + ControlFlowSideEffects{}, + {LiteralKind::String}, + [](FunctionCall const& _call, AbstractAssembly& _assembly, BuiltinContext& _context) { + yulAssert(_context.currentObject, "No object available."); + yulAssert(_call.arguments.size() == 1, ""); + Expression const& arg = _call.arguments.front(); + YulName const dataName (formatLiteral(std::get(arg))); + if (_context.currentObject->name == dataName.str()) + _assembly.appendAssemblySize(); + else + { + std::vector subIdPath = + _context.subIDs.count(dataName.str()) == 0 ? + _context.currentObject->pathToSubObject(dataName.str()) : + std::vector{_context.subIDs.at(dataName.str())}; + yulAssert(!subIdPath.empty(), "Could not find assembly object <" + dataName.str() + ">."); + _assembly.appendDataSize(subIdPath); + } + } + ); +} + +BuiltinFunctionForEVM dataoffsetBuiltin() +{ + return createFunction("dataoffset", 1, 1, SideEffects{}, ControlFlowSideEffects{}, {LiteralKind::String}, []( + FunctionCall const& _call, + AbstractAssembly& _assembly, + BuiltinContext& _context + ) { + yulAssert(_context.currentObject, "No object available."); + yulAssert(_call.arguments.size() == 1, ""); + Expression const& arg = _call.arguments.front(); + YulName const dataName (formatLiteral(std::get(arg))); + if (_context.currentObject->name == dataName.str()) + _assembly.appendConstant(0); + else + { + std::vector subIdPath = + _context.subIDs.count(dataName.str()) == 0 ? + _context.currentObject->pathToSubObject(dataName.str()) : + std::vector{_context.subIDs.at(dataName.str())}; + yulAssert(!subIdPath.empty(), "Could not find assembly object <" + dataName.str() + ">."); + _assembly.appendDataOffset(subIdPath); + } + }); +} + +BuiltinFunctionForEVM datacopyBuiltin() +{ + return createFunction( + "datacopy", + 3, + 0, + EVMBuiltins::sideEffectsOfInstruction(evmasm::Instruction::CODECOPY), + ControlFlowSideEffects::fromInstruction(evmasm::Instruction::CODECOPY), + {}, + []( + FunctionCall const&, + AbstractAssembly& _assembly, + BuiltinContext& + ) { + _assembly.appendInstruction(evmasm::Instruction::CODECOPY); + } + ); +} + +BuiltinFunctionForEVM setimmutableBuiltin() +{ + return createFunction( + "setimmutable", + 3, + 0, + SideEffects{ + false, // movable + false, // movableApartFromEffects + false, // canBeRemoved + false, // canBeRemovedIfNotMSize + true, // cannotLoop + SideEffects::None, // otherState + SideEffects::None, // storage + SideEffects::Write, // memory + SideEffects::None // transientStorage + }, + ControlFlowSideEffects{}, + {std::nullopt, LiteralKind::String, std::nullopt}, + []( + FunctionCall const& _call, + AbstractAssembly& _assembly, + BuiltinContext& + ) { + yulAssert(_call.arguments.size() == 3, ""); + auto const identifier = (formatLiteral(std::get(_call.arguments[1]))); + _assembly.appendImmutableAssignment(identifier); + } + ); +} + +BuiltinFunctionForEVM loadimmutableBuiltin() +{ + return createFunction( + "loadimmutable", + 1, + 1, + SideEffects{}, + ControlFlowSideEffects{}, + {LiteralKind::String}, + []( + FunctionCall const& _call, + AbstractAssembly& _assembly, + BuiltinContext& + ) { + yulAssert(_call.arguments.size() == 1, ""); + _assembly.appendImmutable(formatLiteral(std::get(_call.arguments.front()))); + } + ); +} + +BuiltinFunctionForEVM auxdataloadnBuiltin() +{ + return createFunction( + "auxdataloadn", + 1, + 1, + EVMBuiltins::sideEffectsOfInstruction(evmasm::Instruction::DATALOADN), + ControlFlowSideEffects::fromInstruction(evmasm::Instruction::DATALOADN), + {LiteralKind::Number}, + []( + FunctionCall const& _call, + AbstractAssembly& _assembly, + BuiltinContext& + ) { + yulAssert(_call.arguments.size() == 1); + Literal const* literal = std::get_if(&_call.arguments.front()); + yulAssert(literal, ""); + yulAssert(literal->value.value() <= std::numeric_limits::max()); + _assembly.appendAuxDataLoadN(static_cast(literal->value.value())); + } + ); +} + +BuiltinFunctionForEVM eofcreateBuiltin() +{ + return createFunction( + "eofcreate", + 5, + 1, + EVMBuiltins::sideEffectsOfInstruction(evmasm::Instruction::EOFCREATE), + ControlFlowSideEffects::fromInstruction(evmasm::Instruction::EOFCREATE), + {LiteralKind::String, std::nullopt, std::nullopt, std::nullopt, std::nullopt}, + []( + FunctionCall const& _call, + AbstractAssembly& _assembly, + BuiltinContext& context + ) { + yulAssert(_call.arguments.size() == 5); + Literal const* literal = std::get_if(&_call.arguments.front()); + auto const formattedLiteral = formatLiteral(*literal); + yulAssert(!util::contains(formattedLiteral, '.')); + auto const* containerID = util::valueOrNullptr(context.subIDs, formattedLiteral); + yulAssert(containerID != nullptr); + yulAssert(*containerID <= std::numeric_limits::max()); + _assembly.appendEOFCreate(static_cast(*containerID)); + } + ); +} + +BuiltinFunctionForEVM returncontractBuiltin() +{ + return createFunction( + "returncontract", + 3, + 0, + EVMBuiltins::sideEffectsOfInstruction(evmasm::Instruction::RETURNCONTRACT), + ControlFlowSideEffects::fromInstruction(evmasm::Instruction::RETURNCONTRACT), + {LiteralKind::String, std::nullopt, std::nullopt}, + []( + FunctionCall const& _call, + AbstractAssembly& _assembly, + BuiltinContext& context + ) { + yulAssert(_call.arguments.size() == 3); + Literal const* literal = std::get_if(&_call.arguments.front()); + yulAssert(literal); + auto const formattedLiteral = formatLiteral(*literal); + yulAssert(!util::contains(formattedLiteral, '.')); + auto const* containerID = util::valueOrNullptr(context.subIDs, formattedLiteral); + yulAssert(containerID != nullptr); + yulAssert(*containerID <= std::numeric_limits::max()); + _assembly.appendReturnContract(static_cast(*containerID)); + } + ); +} + +} + +EVMBuiltins::EVMBuiltins() +{ + for (auto const& [name, opcode]: evmasm::c_instructions) + { + if ( + opcode == evmasm::Instruction::SWAPN || + opcode == evmasm::Instruction::DUPN || + evmasm::SemanticInformation::isSwapInstruction(opcode) || + evmasm::SemanticInformation::isDupInstruction(opcode) + ) + continue; + + // difficulty was replaced by prevrandao after london + if (opcode == evmasm::Instruction::PREVRANDAO && name == "DIFFICULTY") + m_scopesAndFunctions.emplace_back(instruction, instructionBuiltin(opcode, langutil::EVMVersion::london())); + else + m_scopesAndFunctions.emplace_back(instruction, instructionBuiltin(opcode, langutil::EVMVersion::current())); + + // these are replaced by 'proper' builtin functions + if ( + opcode == evmasm::Instruction::DATALOADN || + opcode == evmasm::Instruction::EOFCREATE || + opcode == evmasm::Instruction::RETURNCONTRACT + ) + std::get<0>(m_scopesAndFunctions.back()) |= replaced; + } + + m_scopesAndFunctions.emplace_back(objectAccess, linkersymbolBuiltin()); + m_scopesAndFunctions.emplace_back(objectAccess, memoryguardBuiltin()); + + m_scopesAndFunctions.emplace_back(objectAccess | requiresNonEOF, datasizeBuiltin()); + m_scopesAndFunctions.emplace_back(objectAccess | requiresNonEOF, dataoffsetBuiltin()); + m_scopesAndFunctions.emplace_back(objectAccess | requiresNonEOF, datacopyBuiltin()); + m_scopesAndFunctions.emplace_back(objectAccess | requiresNonEOF, setimmutableBuiltin()); + m_scopesAndFunctions.emplace_back(objectAccess | requiresNonEOF, loadimmutableBuiltin()); + + m_scopesAndFunctions.emplace_back(objectAccess | requiresEOF, auxdataloadnBuiltin()); + m_scopesAndFunctions.emplace_back(objectAccess | requiresEOF, eofcreateBuiltin()); + m_scopesAndFunctions.emplace_back(objectAccess | requiresEOF, returncontractBuiltin()); + + static size_t constexpr verbatimPrefixLength = std::char_traits::length("verbatim_"); + for (auto const& [scope, builtin]: m_scopesAndFunctions) + { + yulAssert( + builtin.name.substr(0, verbatimPrefixLength) != "verbatim_", + "Builtin functions besides verbatim should not start with the verbatim_ prefix." + ); + yulAssert(!(scope.requiresEOF() && scope.requiresNonEOF()), "Mutually exclusive scopes"); + } +} + +BuiltinFunctionForEVM EVMBuiltins::createVerbatimFunction(size_t const _arguments, size_t const _returnVariables) +{ + BuiltinFunctionForEVM builtinFunction = createFunction( + "verbatim_" + std::to_string(_arguments) + "i_" + std::to_string(_returnVariables) + "o", + 1 + _arguments, + _returnVariables, + SideEffects::worst(), + ControlFlowSideEffects::worst(), // Worst control flow side effects because verbatim can do anything. + std::vector>{LiteralKind::String} + std::vector>(_arguments), + [=]( + FunctionCall const& _call, + AbstractAssembly& _assembly, + BuiltinContext& + ) { + yulAssert(_call.arguments.size() == (1 + _arguments), ""); + Expression const& bytecode = _call.arguments.front(); + + _assembly.appendVerbatim( + util::asBytes(formatLiteral(std::get(bytecode))), + _arguments, + _returnVariables + ); + } + ); + builtinFunction.isMSize = true; + return builtinFunction; +} + +SideEffects EVMBuiltins::sideEffectsOfInstruction(evmasm::Instruction _instruction) +{ + auto translate = [](evmasm::SemanticInformation::Effect _e) -> SideEffects::Effect + { + return static_cast(_e); + }; + + return SideEffects{ + evmasm::SemanticInformation::movable(_instruction), + evmasm::SemanticInformation::movableApartFromEffects(_instruction), + evmasm::SemanticInformation::canBeRemoved(_instruction), + evmasm::SemanticInformation::canBeRemovedIfNoMSize(_instruction), + true, // cannotLoop + translate(evmasm::SemanticInformation::otherState(_instruction)), + translate(evmasm::SemanticInformation::storage(_instruction)), + translate(evmasm::SemanticInformation::memory(_instruction)), + translate(evmasm::SemanticInformation::transientStorage(_instruction)), + }; +} diff --git a/libyul/backends/evm/EVMBuiltins.h b/libyul/backends/evm/EVMBuiltins.h new file mode 100644 index 000000000000..c4b383ddad78 --- /dev/null +++ b/libyul/backends/evm/EVMBuiltins.h @@ -0,0 +1,120 @@ +/* + This file is part of solidity. + + solidity is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + solidity is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with solidity. If not, see . +*/ +// SPDX-License-Identifier: GPL-3.0 + +#pragma once + +#include + +#include +#include + +#include +#include +#include +#include +#include +#include + +namespace solidity::yul +{ + +class Object; + +/// Context used during code generation. +struct BuiltinContext +{ + Object const* currentObject = nullptr; + /// Mapping from named objects to abstract assembly sub IDs. + std::map subIDs; + + std::map functionIDs; +}; + +struct BuiltinFunctionForEVM: public BuiltinFunction +{ + std::optional instruction; + /// Function to generate code for the given function call and append it to the abstract + /// assembly. Expects all non-literal arguments of the call to be on stack in reverse order + /// (i.e. right-most argument pushed first). + /// Expects the caller to set the source location. + std::function generateCode; +}; + +/// Collection of all possible EVM builtin functions. +/// Each builtin can have one (or multiple) scopes, which define whether, e.g., it requires object access. +/// Using this class as single source of truth for builtin functions makes sure that these are consistent over +/// EVM dialects. If the order were to depend on the EVM dialect - which can easily happen using conditionals -, +/// different dialects' builtin handles become inherently incompatible. +class EVMBuiltins +{ + static std::size_t constexpr instructionBit = 0; + static std::size_t constexpr replacedInstructionBit = 1; + static std::size_t constexpr objectAccessBit = 2; + static std::size_t constexpr requiresEOFBit = 3; + static std::size_t constexpr requiresNonEOFBit = 4; + +public: + struct Scopes + { + /// whether the corresponding evm builtin function is an instruction builtin + bool instruction() const { return value.test(instructionBit); } + /// whether the corresponding evm builtin has been replaced by another builtin, ie, should be skipped + bool replaced() const { return value.test(replacedInstructionBit); } + /// if true, the evm builtin function is only valid when object access is given + bool requiresObjectAccess() const { return value.test(objectAccessBit); } + /// if true, the evm builtin function is only valid if EOF is enabled + bool requiresEOF() const { return value.test(requiresEOFBit); } + /// if true, the evm builtin function is only valid if EOF is not enabled + bool requiresNonEOF() const { return value.test(requiresNonEOFBit); } + + Scopes operator|(Scopes const& _other) const + { + Scopes result = *this; + result |= _other; + return result; + } + + Scopes& operator|=(Scopes const& _other) + { + value |= _other.value; + return *this; + } + + std::bitset<5> value; + }; + + EVMBuiltins(); + + std::vector> const& functions() const { return m_scopesAndFunctions; } + + /// Creates a verbatim builtin function. These are not part of the usual builtin functions collection and + /// must be cached in the dialect creating them. + static BuiltinFunctionForEVM createVerbatimFunction(size_t _arguments, size_t _returnVariables); + static SideEffects sideEffectsOfInstruction(evmasm::Instruction _instruction); + +private: + static Scopes constexpr instruction{1 << instructionBit}; + static Scopes constexpr replaced{1 << replacedInstructionBit}; + static Scopes constexpr objectAccess{1 << objectAccessBit}; + static Scopes constexpr requiresEOF{1 << requiresEOFBit}; + static Scopes constexpr requiresNonEOF{1 << requiresNonEOFBit}; + + std::vector> m_scopesAndFunctions; +}; + +} diff --git a/libyul/backends/evm/EVMDialect.cpp b/libyul/backends/evm/EVMDialect.cpp index 87cd876ae254..c903b9c4dae0 100644 --- a/libyul/backends/evm/EVMDialect.cpp +++ b/libyul/backends/evm/EVMDialect.cpp @@ -29,7 +29,6 @@ #include #include #include -#include #include @@ -176,393 +175,22 @@ std::set> createReservedIdentifiers(langutil::EVMVersio return reserved; } -BuiltinFunctionForEVM createFunction( - std::string const& _name, - size_t _params, - size_t _returns, - SideEffects _sideEffects, - ControlFlowSideEffects _controlFlowSideEffects, - std::vector> _literalArguments, - std::function _generateCode - ) -{ - yulAssert(_literalArguments.size() == _params || _literalArguments.empty(), ""); - - BuiltinFunctionForEVM f; - f.name = _name; - f.numParameters = _params; - f.numReturns = _returns; - f.sideEffects = _sideEffects; - f.controlFlowSideEffects = _controlFlowSideEffects; - f.literalArguments = std::move(_literalArguments); - f.isMSize = false; - f.instruction = {}; - f.generateCode = std::move(_generateCode); - return f; -} - -class BuiltinFunctionCollection -{ - static size_t constexpr instructionBit = 0; - static size_t constexpr replacedInstructionBit = 1; - static size_t constexpr objectAccessBit = 2; - static size_t constexpr requiresEOFBit = 3; - static size_t constexpr requiresNonEOFBit = 4; -public: - struct BuiltinDescription - { - /// whether the corresponding evm builtin function is an instruction builtin - bool instruction() const { return value.test(instructionBit); } - /// whether the corresponding evm builtin has been replaced by another builtin, ie, should be skipped - bool replaced() const { return value.test(replacedInstructionBit); } - /// if true, the evm builtin function is only valid when object access is given - bool requiresObjectAccess() const { return value.test(objectAccessBit); } - /// if true, the evm builtin function is only valid if EOF is enabled - bool requiresEOF() const { return value.test(requiresEOFBit); } - /// if true, the evm builtin function is only valid if EOF is not enabled - bool requiresNonEOF() const { return value.test(requiresNonEOFBit); } - - BuiltinDescription operator|(BuiltinDescription const& _other) const - { - return { value | _other.value }; - } - - std::bitset<5> value; - }; - - static std::vector> const& builtins() - { - static BuiltinFunctionCollection const instance; - return instance.m_builtinFunctions; - } - -private: - static BuiltinDescription constexpr instruction{1 << instructionBit}; - static BuiltinDescription constexpr replaced{1 << replacedInstructionBit}; - static BuiltinDescription constexpr objectAccess{1 << objectAccessBit}; - static BuiltinDescription constexpr requiresEOF{1 << requiresEOFBit}; - static BuiltinDescription constexpr requiresNonEOF{1 << requiresNonEOFBit}; - - BuiltinFunctionCollection() - { - for (auto const& [name, opcode]: evmasm::c_instructions) - { - if (evmasm::SemanticInformation::isSwapInstruction(opcode) || evmasm::SemanticInformation::isDupInstruction(opcode)) - continue; - - if ( - opcode != evmasm::Instruction::DATALOADN && - opcode != evmasm::Instruction::EOFCREATE && - opcode != evmasm::Instruction::RETURNCONTRACT - ) - { - // difficulty was replaced by prevrandao after london - if (opcode == evmasm::Instruction::PREVRANDAO && name == "DIFFICULTY") - m_builtinFunctions.emplace_back(instruction, instructionBuiltin(opcode, langutil::EVMVersion::london())); - else - m_builtinFunctions.emplace_back(instruction, instructionBuiltin(opcode, langutil::EVMVersion::current())); - } - else - // these opcodes are replaced by explicit builtin functions - m_builtinFunctions.emplace_back(instruction | replaced, BuiltinFunctionForEVM{}); - } - - m_builtinFunctions.emplace_back(objectAccess, linkersymbolBuiltin()); - m_builtinFunctions.emplace_back(objectAccess, memoryguardBuiltin()); - - m_builtinFunctions.emplace_back(objectAccess | requiresNonEOF, datasizeBuiltin()); - m_builtinFunctions.emplace_back(objectAccess | requiresNonEOF, dataoffsetBuiltin()); - m_builtinFunctions.emplace_back(objectAccess | requiresNonEOF, datacopyBuiltin()); - m_builtinFunctions.emplace_back(objectAccess | requiresNonEOF, setimmutableBuiltin()); - m_builtinFunctions.emplace_back(objectAccess | requiresNonEOF, loadimmutableBuiltin()); - - m_builtinFunctions.emplace_back(objectAccess | requiresEOF, auxdataloadnBuiltin()); - m_builtinFunctions.emplace_back(objectAccess | requiresEOF, eofcreateBuiltin()); - m_builtinFunctions.emplace_back(objectAccess | requiresEOF, returncontractBuiltin()); - - yulAssert( - ranges::all_of(m_builtinFunctions, [](std::tuple const& _builtin) { - return std::get<1>(_builtin).name.substr(0, "verbatim_"s.size()) != "verbatim_"; - }), - "Builtin functions besides verbatim should not start with the verbatim_ prefix." - ); - } - - static BuiltinFunctionForEVM instructionBuiltin(evmasm::Instruction const& _instruction, langutil::EVMVersion const& _evmVersion) - { - evmasm::InstructionInfo const info = evmasm::instructionInfo(_instruction, _evmVersion); - BuiltinFunctionForEVM f; - f.name = toLower(info.name); - f.numParameters = static_cast(info.args); - f.numReturns = static_cast(info.ret); - f.sideEffects = EVMDialect::sideEffectsOfInstruction(_instruction); - f.controlFlowSideEffects = ControlFlowSideEffects::fromInstruction(_instruction); - f.isMSize = _instruction == evmasm::Instruction::MSIZE; - f.literalArguments.clear(); - f.instruction = _instruction; - f.generateCode = [_instruction]( - FunctionCall const&, - AbstractAssembly& _assembly, - BuiltinContext& - ) - { - _assembly.appendInstruction(_instruction); - }; - return f; - } - - static BuiltinFunctionForEVM linkersymbolBuiltin() - { - return createFunction( - "linkersymbol", - 1, - 1, - SideEffects{}, - ControlFlowSideEffects{}, - {LiteralKind::String}, - [](FunctionCall const& _call, AbstractAssembly& _assembly, BuiltinContext&) { - yulAssert(_call.arguments.size() == 1, ""); - Expression const& arg = _call.arguments.front(); - _assembly.appendLinkerSymbol(formatLiteral(std::get(arg))); - } - ); - } - - static BuiltinFunctionForEVM memoryguardBuiltin() - { - return createFunction( - "memoryguard", - 1, - 1, - SideEffects{}, - ControlFlowSideEffects{}, - {LiteralKind::Number}, - [](FunctionCall const& _call, AbstractAssembly& _assembly, BuiltinContext&) { - yulAssert(_call.arguments.size() == 1, ""); - Literal const* literal = std::get_if(&_call.arguments.front()); - yulAssert(literal, ""); - _assembly.appendConstant(literal->value.value()); - } - ); - } - - static BuiltinFunctionForEVM datasizeBuiltin() - { - return createFunction( - "datasize", - 1, - 1, - SideEffects{}, - ControlFlowSideEffects{}, - {LiteralKind::String}, - [](FunctionCall const& _call, AbstractAssembly& _assembly, BuiltinContext& _context) { - yulAssert(_context.currentObject, "No object available."); - yulAssert(_call.arguments.size() == 1, ""); - Expression const& arg = _call.arguments.front(); - YulName const dataName (formatLiteral(std::get(arg))); - if (_context.currentObject->name == dataName.str()) - _assembly.appendAssemblySize(); - else - { - std::vector subIdPath = - _context.subIDs.count(dataName.str()) == 0 ? - _context.currentObject->pathToSubObject(dataName.str()) : - std::vector{_context.subIDs.at(dataName.str())}; - yulAssert(!subIdPath.empty(), "Could not find assembly object <" + dataName.str() + ">."); - _assembly.appendDataSize(subIdPath); - } - } - ); - } - - static BuiltinFunctionForEVM dataoffsetBuiltin() - { - return createFunction("dataoffset", 1, 1, SideEffects{}, ControlFlowSideEffects{}, {LiteralKind::String}, []( - FunctionCall const& _call, - AbstractAssembly& _assembly, - BuiltinContext& _context - ) { - yulAssert(_context.currentObject, "No object available."); - yulAssert(_call.arguments.size() == 1, ""); - Expression const& arg = _call.arguments.front(); - YulName const dataName (formatLiteral(std::get(arg))); - if (_context.currentObject->name == dataName.str()) - _assembly.appendConstant(0); - else - { - std::vector subIdPath = - _context.subIDs.count(dataName.str()) == 0 ? - _context.currentObject->pathToSubObject(dataName.str()) : - std::vector{_context.subIDs.at(dataName.str())}; - yulAssert(!subIdPath.empty(), "Could not find assembly object <" + dataName.str() + ">."); - _assembly.appendDataOffset(subIdPath); - } - }); - } - - static BuiltinFunctionForEVM datacopyBuiltin() - { - return createFunction( - "datacopy", - 3, - 0, - EVMDialect::sideEffectsOfInstruction(evmasm::Instruction::CODECOPY), - ControlFlowSideEffects::fromInstruction(evmasm::Instruction::CODECOPY), - {}, - []( - FunctionCall const&, - AbstractAssembly& _assembly, - BuiltinContext& - ) { - _assembly.appendInstruction(evmasm::Instruction::CODECOPY); - } - ); - } - - static BuiltinFunctionForEVM setimmutableBuiltin() - { - return createFunction( - "setimmutable", - 3, - 0, - SideEffects{ - false, // movable - false, // movableApartFromEffects - false, // canBeRemoved - false, // canBeRemovedIfNotMSize - true, // cannotLoop - SideEffects::None, // otherState - SideEffects::None, // storage - SideEffects::Write, // memory - SideEffects::None // transientStorage - }, - ControlFlowSideEffects{}, - {std::nullopt, LiteralKind::String, std::nullopt}, - []( - FunctionCall const& _call, - AbstractAssembly& _assembly, - BuiltinContext& - ) { - yulAssert(_call.arguments.size() == 3, ""); - auto const identifier = (formatLiteral(std::get(_call.arguments[1]))); - _assembly.appendImmutableAssignment(identifier); - } - ); - } - - static BuiltinFunctionForEVM loadimmutableBuiltin() - { - return createFunction( - "loadimmutable", - 1, - 1, - SideEffects{}, - ControlFlowSideEffects{}, - {LiteralKind::String}, - []( - FunctionCall const& _call, - AbstractAssembly& _assembly, - BuiltinContext& - ) { - yulAssert(_call.arguments.size() == 1, ""); - _assembly.appendImmutable(formatLiteral(std::get(_call.arguments.front()))); - } - ); - } - - static BuiltinFunctionForEVM auxdataloadnBuiltin() - { - return createFunction( - "auxdataloadn", - 1, - 1, - EVMDialect::sideEffectsOfInstruction(evmasm::Instruction::DATALOADN), - ControlFlowSideEffects::fromInstruction(evmasm::Instruction::DATALOADN), - {LiteralKind::Number}, - []( - FunctionCall const& _call, - AbstractAssembly& _assembly, - BuiltinContext& - ) { - yulAssert(_call.arguments.size() == 1); - Literal const* literal = std::get_if(&_call.arguments.front()); - yulAssert(literal, ""); - yulAssert(literal->value.value() <= std::numeric_limits::max()); - _assembly.appendAuxDataLoadN(static_cast(literal->value.value())); - } - ); - } - - static BuiltinFunctionForEVM eofcreateBuiltin() - { - return createFunction( - "eofcreate", - 5, - 1, - EVMDialect::sideEffectsOfInstruction(evmasm::Instruction::EOFCREATE), - ControlFlowSideEffects::fromInstruction(evmasm::Instruction::EOFCREATE), - {LiteralKind::String, std::nullopt, std::nullopt, std::nullopt, std::nullopt}, - []( - FunctionCall const& _call, - AbstractAssembly& _assembly, - BuiltinContext& context - ) { - yulAssert(_call.arguments.size() == 5); - Literal const* literal = std::get_if(&_call.arguments.front()); - auto const formattedLiteral = formatLiteral(*literal); - yulAssert(!util::contains(formattedLiteral, '.')); - auto const* containerID = valueOrNullptr(context.subIDs, formattedLiteral); - yulAssert(containerID != nullptr); - yulAssert(*containerID <= std::numeric_limits::max()); - _assembly.appendEOFCreate(static_cast(*containerID)); - } - ); - } - - static BuiltinFunctionForEVM returncontractBuiltin() - { - return createFunction( - "returncontract", - 3, - 0, - EVMDialect::sideEffectsOfInstruction(evmasm::Instruction::RETURNCONTRACT), - ControlFlowSideEffects::fromInstruction(evmasm::Instruction::RETURNCONTRACT), - {LiteralKind::String, std::nullopt, std::nullopt}, - []( - FunctionCall const& _call, - AbstractAssembly& _assembly, - BuiltinContext& context - ) { - yulAssert(_call.arguments.size() == 3); - Literal const* literal = std::get_if(&_call.arguments.front()); - yulAssert(literal); - auto const formattedLiteral = formatLiteral(*literal); - yulAssert(!util::contains(formattedLiteral, '.')); - auto const* containerID = valueOrNullptr(context.subIDs, formattedLiteral); - yulAssert(containerID != nullptr); - yulAssert(*containerID <= std::numeric_limits::max()); - _assembly.appendReturnContract(static_cast(*containerID)); - } - ); - } - - std::vector> m_builtinFunctions; -}; - -/// Make sure to only add builtins in a way that is consistent over EVM versions. If the order depends on the -/// EVM version - which can easily happen using conditionals -, different dialects' builtin handles -/// become inherently incompatible. -std::vector createBuiltins(langutil::EVMVersion _evmVersion, std::optional _eofVersion, bool _objectAccess) +std::vector createDialectBuiltins( + std::vector> const& _allBuiltins, + langutil::EVMVersion const _evmVersion, + std::optional const _eofVersion, + bool const _objectAccess +) { std::vector builtins; - builtins.reserve(BuiltinFunctionCollection::builtins().size()); + builtins.reserve(_allBuiltins.size()); - for (auto const& [description, builtin]: BuiltinFunctionCollection::builtins()) + for (auto const& [scopes, builtin]: _allBuiltins) { bool builtinShouldBeAdded = true; - if (description.instruction()) + if (scopes.instruction()) { - if (description.replaced()) + if (scopes.replaced()) builtinShouldBeAdded = false; else { @@ -582,9 +210,9 @@ std::vector createBuiltins(langutil::EVMVersion _e } } - builtinShouldBeAdded &= !description.requiresObjectAccess() || _objectAccess; - builtinShouldBeAdded &= !description.requiresEOF() || _eofVersion.has_value(); - builtinShouldBeAdded &= !description.requiresNonEOF() || !_eofVersion.has_value(); + builtinShouldBeAdded &= !scopes.requiresObjectAccess() || _objectAccess; + builtinShouldBeAdded &= !scopes.requiresEOF() || _eofVersion.has_value(); + builtinShouldBeAdded &= !scopes.requiresNonEOF() || !_eofVersion.has_value(); if (builtinShouldBeAdded) builtins.emplace_back(&builtin); @@ -603,12 +231,11 @@ std::regex const& verbatimPattern() } - EVMDialect::EVMDialect(langutil::EVMVersion _evmVersion, std::optional _eofVersion, bool _objectAccess): m_objectAccess(_objectAccess), m_evmVersion(_evmVersion), m_eofVersion(_eofVersion), - m_functions(createBuiltins(_evmVersion, _eofVersion, _objectAccess)), + m_functions(createDialectBuiltins(allBuiltins().functions(), _evmVersion, _eofVersion, _objectAccess)), m_reserved(createReservedIdentifiers(_evmVersion, _eofVersion)) { for (auto const& [index, maybeBuiltin]: m_functions | ranges::views::enumerate) @@ -668,13 +295,12 @@ BuiltinFunctionForEVM const& EVMDialect::builtin(BuiltinHandle const& _handle) c return *maybeBuiltin; } - bool EVMDialect::reservedIdentifier(std::string_view _name) const { if (m_objectAccess) if (_name.substr(0, "verbatim"s.size()) == "verbatim") return true; - return m_reserved.count(_name) != 0; + return m_reserved.contains(_name); } EVMDialect const& EVMDialect::strictAssemblyForEVM(langutil::EVMVersion _evmVersion, std::optional _eofVersion) @@ -695,42 +321,14 @@ EVMDialect const& EVMDialect::strictAssemblyForEVMObjects(langutil::EVMVersion _ return *dialects[{_evmVersion, _eofVersion}]; } -SideEffects EVMDialect::sideEffectsOfInstruction(evmasm::Instruction _instruction) +std::set EVMDialect::builtinFunctionNames() const { return ranges::views::keys(m_builtinFunctionsByName) | ranges::to; } BuiltinFunctionForEVM EVMDialect::createVerbatimFunctionFromHandle(BuiltinHandle const& _handle) { - return std::apply(createVerbatimFunction, verbatimIndexToArgsAndRets(_handle.id)); -} - -BuiltinFunctionForEVM EVMDialect::createVerbatimFunction(size_t _arguments, size_t _returnVariables) -{ - BuiltinFunctionForEVM builtinFunction = createFunction( - "verbatim_" + std::to_string(_arguments) + "i_" + std::to_string(_returnVariables) + "o", - 1 + _arguments, - _returnVariables, - SideEffects::worst(), - ControlFlowSideEffects::worst(), // Worst control flow side effects because verbatim can do anything. - std::vector>{LiteralKind::String} + std::vector>(_arguments), - [=]( - FunctionCall const& _call, - AbstractAssembly& _assembly, - BuiltinContext& - ) { - yulAssert(_call.arguments.size() == (1 + _arguments), ""); - Expression const& bytecode = _call.arguments.front(); - - _assembly.appendVerbatim( - asBytes(formatLiteral(std::get(bytecode))), - _arguments, - _returnVariables - ); - } - ); - builtinFunction.isMSize = true; - return builtinFunction; + return std::apply(EVMBuiltins::createVerbatimFunction, verbatimIndexToArgsAndRets(_handle.id)); } BuiltinHandle EVMDialect::verbatimFunction(size_t _arguments, size_t _returnVariables) const @@ -745,7 +343,13 @@ BuiltinHandle EVMDialect::verbatimFunction(size_t _arguments, size_t _returnVari auto& verbatimFunctionPtr = m_verbatimFunctions[verbatimIndex]; !verbatimFunctionPtr ) - verbatimFunctionPtr = std::make_unique(createVerbatimFunction(_arguments, _returnVariables)); + verbatimFunctionPtr = std::make_unique(EVMBuiltins::createVerbatimFunction(_arguments, _returnVariables)); return {verbatimIndex}; } + +EVMBuiltins const& EVMDialect::allBuiltins() +{ + static EVMBuiltins const builtins; + return builtins; +} diff --git a/libyul/backends/evm/EVMDialect.h b/libyul/backends/evm/EVMDialect.h index 73136ef6e30b..96723e9191f7 100644 --- a/libyul/backends/evm/EVMDialect.h +++ b/libyul/backends/evm/EVMDialect.h @@ -25,11 +25,15 @@ #include #include -#include +#include + #include -#include +#include +#include #include +#include +#include namespace solidity::yul { @@ -37,29 +41,6 @@ namespace solidity::yul struct FunctionCall; class Object; -/** - * Context used during code generation. - */ -struct BuiltinContext -{ - Object const* currentObject = nullptr; - /// Mapping from named objects to abstract assembly sub IDs. - std::map subIDs; - - std::map functionIDs; -}; - -struct BuiltinFunctionForEVM: public BuiltinFunction -{ - std::optional instruction; - /// Function to generate code for the given function call and append it to the abstract - /// assembly. Expects all non-literal arguments of the call to be on stack in reverse order - /// (i.e. right-most argument pushed first). - /// Expects the caller to set the source location. - std::function generateCode; -}; - - /** * Yul dialect for EVM as a backend. * The main difference is that the builtin functions take an AbstractAssembly for the @@ -108,19 +89,18 @@ class EVMDialect: public Dialect bool providesObjectAccess() const { return m_objectAccess; } - static SideEffects sideEffectsOfInstruction(evmasm::Instruction _instruction); - static size_t constexpr verbatimMaxInputSlots = 100; static size_t constexpr verbatimMaxOutputSlots = 100; protected: static bool constexpr isVerbatimHandle(BuiltinHandle const& _handle) { return _handle.id < verbatimIDOffset; } static BuiltinFunctionForEVM createVerbatimFunctionFromHandle(BuiltinHandle const& _handle); - static BuiltinFunctionForEVM createVerbatimFunction(size_t _arguments, size_t _returnVariables); BuiltinHandle verbatimFunction(size_t _arguments, size_t _returnVariables) const; static size_t constexpr verbatimIDOffset = verbatimMaxInputSlots * verbatimMaxOutputSlots; + static EVMBuiltins const& allBuiltins(); + bool const m_objectAccess; langutil::EVMVersion const m_evmVersion; std::optional m_eofVersion; diff --git a/libyul/backends/evm/NoOutputAssembly.cpp b/libyul/backends/evm/NoOutputAssembly.cpp index 55e034399e33..90713b0e2065 100644 --- a/libyul/backends/evm/NoOutputAssembly.cpp +++ b/libyul/backends/evm/NoOutputAssembly.cpp @@ -26,6 +26,7 @@ #include +#include #include using namespace solidity; @@ -208,44 +209,17 @@ NoOutputEVMDialect::NoOutputEVMDialect(EVMDialect const& _copyFrom): EVMDialect(_copyFrom.evmVersion(), _copyFrom.eofVersion(), _copyFrom.providesObjectAccess()) { // save the modified functions here - note that this only has to be done once because we modify all of - // them in one go, later just reference pointers to this static vector - static std::vector const noOutputBuiltins = [] - { - std::vector modifiedBuiltins; - modifiedBuiltins.reserve(allBuiltins().functions().size()); - - for (auto const& [_, builtin]: allBuiltins().functions()) - { - auto noOutputFunction = builtin; - modifyBuiltinToNoOutput(noOutputFunction); - modifiedBuiltins.push_back(std::move(noOutputFunction)); - } + // them in one go, later reference pointers to this static vector + static std::vector noOutputBuiltins = defineNoOutputBuiltins(); - return modifiedBuiltins; - }(); - - m_functions = [&] + m_functions.reserve(m_functions.size()); + for (auto const& [index, builtinFunction]: m_functions | ranges::views::enumerate) { - std::vector result; - result.reserve(m_functions.size()); - for (auto const* builtinFunction: m_functions) - { - if (builtinFunction) - { - auto it = noOutputBuiltins.find(builtinFunction); - if (it == noOutputBuiltins.end()) - { - auto noOutputFunction = *builtinFunction; - modifyBuiltinToNoOutput(noOutputFunction); - it = noOutputBuiltins.emplace(builtinFunction, std::move(noOutputFunction)).first; - } - result.emplace_back(&it->second); - } - else - result.emplace_back(nullptr); - } - return result; - }(); + if (builtinFunction) + m_functions.emplace_back(&noOutputBuiltins[index]); + else + m_functions.emplace_back(nullptr); + } } BuiltinFunctionForEVM const& NoOutputEVMDialect::builtin(BuiltinHandle const& _handle) const @@ -262,3 +236,18 @@ BuiltinFunctionForEVM const& NoOutputEVMDialect::builtin(BuiltinHandle const& _h } return EVMDialect::builtin(_handle); } + +std::vector NoOutputEVMDialect::defineNoOutputBuiltins() +{ + std::vector modifiedBuiltins; + modifiedBuiltins.reserve(allBuiltins().functions().size()); + + for (auto const& [_, builtin]: allBuiltins().functions()) + { + auto noOutputFunction = builtin; + modifyBuiltinToNoOutput(noOutputFunction); + modifiedBuiltins.push_back(std::move(noOutputFunction)); + } + + return modifiedBuiltins; +} diff --git a/libyul/backends/evm/NoOutputAssembly.h b/libyul/backends/evm/NoOutputAssembly.h index 502f90d854f5..0a9ade3466a4 100644 --- a/libyul/backends/evm/NoOutputAssembly.h +++ b/libyul/backends/evm/NoOutputAssembly.h @@ -114,6 +114,9 @@ class NoOutputEVMDialect: public EVMDialect explicit NoOutputEVMDialect(EVMDialect const& _copyFrom); BuiltinFunctionForEVM const& builtin(BuiltinHandle const& _handle) const override; + +private: + static std::vector defineNoOutputBuiltins(); }; From e465a316b96f2e4dec795b0129c1def3a41c3270 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Mon, 28 Apr 2025 14:23:42 +0200 Subject: [PATCH 1004/1022] Add allEOFVersions to EVMVersion --- liblangutil/EVMVersion.h | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/liblangutil/EVMVersion.h b/liblangutil/EVMVersion.h index f771d9f1cdf6..f5e7b3d34bb9 100644 --- a/liblangutil/EVMVersion.h +++ b/liblangutil/EVMVersion.h @@ -23,6 +23,7 @@ #include +#include #include #include #include @@ -83,6 +84,14 @@ class EVMVersion }; } + static auto constexpr allEOFVersions() + { + return std::array{ + std::optional(), + std::make_optional(1) + }; + } + static std::optional fromString(std::string const& _version) { for (auto const& v: allVersions()) From e39aaeb1d951f49ece3c99e26b669d63e6150db5 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Mon, 28 Apr 2025 14:24:04 +0200 Subject: [PATCH 1005/1022] EVMVersion::allVersions is constexpr --- liblangutil/EVMVersion.h | 37 ++++++++++++++++++------------------ solc/CommandLineParser.cpp | 2 +- test/tools/fuzzer_common.cpp | 2 +- 3 files changed, 20 insertions(+), 21 deletions(-) diff --git a/liblangutil/EVMVersion.h b/liblangutil/EVMVersion.h index f5e7b3d34bb9..b5489de0bab6 100644 --- a/liblangutil/EVMVersion.h +++ b/liblangutil/EVMVersion.h @@ -27,7 +27,6 @@ #include #include #include -#include namespace solidity::evmasm @@ -50,23 +49,23 @@ class EVMVersion static EVMVersion current() { return {currentVersion}; } - static EVMVersion homestead() { return {Version::Homestead}; } - static EVMVersion tangerineWhistle() { return {Version::TangerineWhistle}; } - static EVMVersion spuriousDragon() { return {Version::SpuriousDragon}; } - static EVMVersion byzantium() { return {Version::Byzantium}; } - static EVMVersion constantinople() { return {Version::Constantinople}; } - static EVMVersion petersburg() { return {Version::Petersburg}; } - static EVMVersion istanbul() { return {Version::Istanbul}; } - static EVMVersion berlin() { return {Version::Berlin}; } - static EVMVersion london() { return {Version::London}; } - static EVMVersion paris() { return {Version::Paris}; } - static EVMVersion shanghai() { return {Version::Shanghai}; } - static EVMVersion cancun() { return {Version::Cancun}; } - static EVMVersion prague() { return {Version::Prague}; } - static EVMVersion osaka() { return {Version::Osaka}; } - - static std::vector allVersions() { - return { + static EVMVersion constexpr homestead() { return {Version::Homestead}; } + static EVMVersion constexpr tangerineWhistle() { return {Version::TangerineWhistle}; } + static EVMVersion constexpr spuriousDragon() { return {Version::SpuriousDragon}; } + static EVMVersion constexpr byzantium() { return {Version::Byzantium}; } + static EVMVersion constexpr constantinople() { return {Version::Constantinople}; } + static EVMVersion constexpr petersburg() { return {Version::Petersburg}; } + static EVMVersion constexpr istanbul() { return {Version::Istanbul}; } + static EVMVersion constexpr berlin() { return {Version::Berlin}; } + static EVMVersion constexpr london() { return {Version::London}; } + static EVMVersion constexpr paris() { return {Version::Paris}; } + static EVMVersion constexpr shanghai() { return {Version::Shanghai}; } + static EVMVersion constexpr cancun() { return {Version::Cancun}; } + static EVMVersion constexpr prague() { return {Version::Prague}; } + static EVMVersion constexpr osaka() { return {Version::Osaka}; } + + static auto constexpr allVersions() { + return std::array{ homestead(), tangerineWhistle(), spuriousDragon(), @@ -172,7 +171,7 @@ class EVMVersion }; static auto constexpr currentVersion = Version::Prague; - EVMVersion(Version _version): m_version(_version) {} + constexpr EVMVersion(Version _version): m_version(_version) {} Version m_version = currentVersion; }; diff --git a/solc/CommandLineParser.cpp b/solc/CommandLineParser.cpp index a382c5217377..50ce02bd14c8 100644 --- a/solc/CommandLineParser.cpp +++ b/solc/CommandLineParser.cpp @@ -596,7 +596,7 @@ General Information)").c_str(), auto const annotateEVMVersion = [](EVMVersion const& _version) { return _version.name() + (_version.isExperimental() ? " (experimental)" : ""); }; - std::vector allEVMVersions = EVMVersion::allVersions(); + static auto constexpr allEVMVersions = EVMVersion::allVersions(); std::string annotatedEVMVersions = util::joinHumanReadable( allEVMVersions | ranges::views::transform(annotateEVMVersion), ", ", diff --git a/test/tools/fuzzer_common.cpp b/test/tools/fuzzer_common.cpp index 6a70c1cc8f77..8cc30c199507 100644 --- a/test/tools/fuzzer_common.cpp +++ b/test/tools/fuzzer_common.cpp @@ -39,7 +39,7 @@ using namespace solidity::frontend; using namespace solidity::langutil; using namespace solidity::util; -static std::vector s_evmVersions = EVMVersion::allVersions(); +static auto constexpr s_evmVersions = EVMVersion::allVersions(); void FuzzerUtil::testCompilerJsonInterface(std::string const& _input, bool _optimize, bool _quiet) { From 55e29b69e9c8b108e834b98bebd46e11e4153989 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Thu, 20 Mar 2025 11:31:46 +0100 Subject: [PATCH 1006/1022] EVMDialect: add test that enforces builtin handle compatibility Between current default dialect as well as latest dialect and all other dialects. --- libyul/backends/evm/EVMDialect.h | 8 ++ test/CMakeLists.txt | 1 + test/libyul/EVMDialectCompatibility.cpp | 167 ++++++++++++++++++++++++ 3 files changed, 176 insertions(+) create mode 100644 test/libyul/EVMDialectCompatibility.cpp diff --git a/libyul/backends/evm/EVMDialect.h b/libyul/backends/evm/EVMDialect.h index 96723e9191f7..9f57600893b6 100644 --- a/libyul/backends/evm/EVMDialect.h +++ b/libyul/backends/evm/EVMDialect.h @@ -45,6 +45,10 @@ class Object; * Yul dialect for EVM as a backend. * The main difference is that the builtin functions take an AbstractAssembly for the * code generation. + * + * Builtins are defined so that their handles stay compatible over different dialect flavors - be it with/without + * object access, with/without EOF, different versions. It may be, of course, that these builtins are no longer defined. + * The ones that _are_ defined, though, remain under the same handle. */ class EVMDialect: public Dialect { @@ -81,6 +85,8 @@ class EVMDialect: public Dialect AuxiliaryBuiltinHandles const& auxiliaryBuiltinHandles() const { return m_auxiliaryBuiltinHandles; } static EVMDialect const& strictAssemblyForEVM(langutil::EVMVersion _evmVersion, std::optional _eofVersion); + /// Builtins with and without object access are compatible, i.e., builtin handles without object access are not + /// invalidated and still point to the same function. static EVMDialect const& strictAssemblyForEVMObjects(langutil::EVMVersion _evmVersion, std::optional _eofVersion); langutil::EVMVersion evmVersion() const { return m_evmVersion; } @@ -92,6 +98,8 @@ class EVMDialect: public Dialect static size_t constexpr verbatimMaxInputSlots = 100; static size_t constexpr verbatimMaxOutputSlots = 100; + std::set builtinFunctionNames() const; + protected: static bool constexpr isVerbatimHandle(BuiltinHandle const& _handle) { return _handle.id < verbatimIDOffset; } static BuiltinFunctionForEVM createVerbatimFunctionFromHandle(BuiltinHandle const& _handle); diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index c66963c190d4..b0cd991f7313 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -149,6 +149,7 @@ set(libyul_sources libyul/ControlFlowSideEffectsTest.h libyul/EVMCodeTransformTest.cpp libyul/EVMCodeTransformTest.h + libyul/EVMDialectCompatibility.cpp libyul/FunctionSideEffects.cpp libyul/FunctionSideEffects.h libyul/Inliner.cpp diff --git a/test/libyul/EVMDialectCompatibility.cpp b/test/libyul/EVMDialectCompatibility.cpp new file mode 100644 index 000000000000..6c8c5a60a1df --- /dev/null +++ b/test/libyul/EVMDialectCompatibility.cpp @@ -0,0 +1,167 @@ +/* + This file is part of solidity. + + solidity is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + solidity is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with solidity. If not, see . +*/ +// SPDX-License-Identifier: GPL-3.0 + +#include + +#include + +#include +#include +#include + +#include +#include + +#include + +#include +#include +#include + +namespace bdata = boost::unit_test::data; + +using namespace solidity; +using namespace solidity::yul; + +namespace +{ + +struct EVMDialectConfigurationToTest +{ + EVMDialect const& dialect() const + { + return objectAccess ? EVMDialect::strictAssemblyForEVMObjects(evmVersion, eofVersion) : EVMDialect::strictAssemblyForEVM(evmVersion, eofVersion); + } + + friend std::ostream& operator<<(std::ostream& _out, EVMDialectConfigurationToTest const& _config) + { + _out << fmt::format( + "EVMConfigurationToTest[{}, eof={}, objectAccess={}]", + _config.evmVersion.name(), + _config.eofVersion.has_value() ? std::to_string(*_config.eofVersion) : "null", + _config.objectAccess + ); + return _out; + } + + langutil::EVMVersion evmVersion; + std::optional eofVersion; + bool objectAccess; +}; + +template +std::vector generateConfigs(EVMVersionCollection const& _evmVersions, std::vector const& _objectAccess = {false, true}) +{ + std::vector configs; + for (bool const objectAccess: _objectAccess) + for (auto const& eofVersion: langutil::EVMVersion::allEOFVersions()) + for (auto const& evmVersion: _evmVersions) + if (!eofVersion || evmVersion.supportsEOF()) + configs.push_back(EVMDialectConfigurationToTest{evmVersion, eofVersion, objectAccess}); + + return configs; +} +} + +BOOST_AUTO_TEST_SUITE(EVMDialectCompatibility) + +/// Test for both current and latest (source) EVM dialect that for all other (target) dialects and all builtins in the +/// source dialect, if the builtin exists for both source and target, they have the same handle. +/// Note: The comparison is packed into a single BOOST_REQUIRE to avoid massive amounts of output on cout. +BOOST_DATA_TEST_CASE( + builtin_function_handle_compatibility, + bdata::monomorphic::grid( + bdata::make(generateConfigs(std::array{langutil::EVMVersion::current(), langutil::EVMVersion::allVersions().back()})), + bdata::make(generateConfigs(langutil::EVMVersion::allVersions())) + ), + sourceDialectConfiguration, + evmDialectConfigurationToTest +) +{ + auto const& sourceDialect = sourceDialectConfiguration.dialect(); + auto const& dialectToTestAgainst = evmDialectConfigurationToTest.dialect(); + + std::set const builtinNames = sourceDialect.builtinFunctionNames(); + std::vector sourceHandles; + sourceHandles.reserve(builtinNames.size()); + std::vector> testHandles; + testHandles.reserve(builtinNames.size()); + + for (auto const& builtinFunctionName: builtinNames) + { + std::optional sourceHandle = sourceDialect.findBuiltin(builtinFunctionName); + soltestAssert(sourceHandle.has_value()); + sourceHandles.push_back(*sourceHandle); + testHandles.push_back(dialectToTestAgainst.findBuiltin(builtinFunctionName)); + } + + BOOST_REQUIRE([&]() -> boost::test_tools::predicate_result + { + boost::test_tools::predicate_result result{true}; + for (auto const& [name, sourceBuiltin, testBuiltin]: ranges::views::zip(builtinNames, sourceHandles, testHandles)) + if (testBuiltin && sourceBuiltin != *testBuiltin) + { + result = false; + result.message() << fmt::format("Builtin \"{}\" had a mismatch of builtin handles: {} =/= {}.", name, sourceBuiltin.id, testBuiltin->id); + } + return result; + }()); +} + +/// Test that for all inline-dialects the corresponding object dialect contains all inline-dialect builtins and they +/// have the same handle. +BOOST_DATA_TEST_CASE( + builtin_inline_to_object_compatibility, + bdata::make(generateConfigs(langutil::EVMVersion::allVersions(), {false})), + configToTest +) +{ + auto const& dialect = EVMDialect::strictAssemblyForEVM(configToTest.evmVersion, configToTest.eofVersion); + auto const& dialectForObjects = EVMDialect::strictAssemblyForEVMObjects(configToTest.evmVersion, configToTest.eofVersion); + + std::set const inlineBuiltinNames = dialect.builtinFunctionNames(); + + std::vector inlineHandles; + inlineHandles.reserve(inlineBuiltinNames.size()); + std::vector> objectHandles; + objectHandles.reserve(inlineBuiltinNames.size()); + + for (auto const& builtinFunctionName: inlineBuiltinNames) + { + std::optional handle = dialect.findBuiltin(builtinFunctionName); + soltestAssert(handle.has_value()); + inlineHandles.push_back(*handle); + objectHandles.push_back(dialectForObjects.findBuiltin(builtinFunctionName)); + } + + BOOST_REQUIRE([&]() -> boost::test_tools::predicate_result + { + boost::test_tools::predicate_result result{true}; + for (auto const& [name, inlineHandle, objectHandle]: ranges::views::zip(inlineBuiltinNames, inlineHandles, objectHandles)) + if (!objectHandle || inlineHandle != *objectHandle) + { + result = false; + result.message() + << fmt::format("Builtin \"{}\" had a mismatch of builtin handles: {} != ", name, inlineHandle.id) + << (objectHandle.has_value() ? std::to_string(objectHandle->id) : "null"); + } + return result; + }()); +} + +BOOST_AUTO_TEST_SUITE_END() From 35282a89786c4a5ba8a43e20853a752d1c678f1b Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Mon, 21 Jul 2025 10:47:02 +0200 Subject: [PATCH 1007/1022] CI: Update cimg/node to 20.19 for gp2 and pool together Requirement of the micro-eth-signer dependency --- .circleci/config.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 8b69287b8a7e..0f4d2b6ebd41 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -823,7 +823,7 @@ defaults: # NOTE: test suite disabled due to dependence on a specific version of Hardhat # which does not support shanghai EVM. compile_only: 1 - image: cimg/node:18.16 + image: cimg/node:20.19 - job_native_test_ext_uniswap: &job_native_test_ext_uniswap <<: *requires_b_ubu_static @@ -876,7 +876,7 @@ defaults: binary_type: native # NOTE: test suite disabled due to constant failures. compile_only: 1 - image: cimg/node:18.16 + image: cimg/node:20.19 - job_b_ubu_asan_clang: &job_b_ubu_asan_clang <<: *on_all_tags_and_branches From fde1aaf38af395d3a4d6c9c3a54189f30b1182b5 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Mon, 21 Jul 2025 09:27:06 +0200 Subject: [PATCH 1008/1022] Yul: NoOutputAssembly assigns functions instead of appending There was an error in that the functions were already part of the dialect (via the parent constructor) and the no output versions were appended instead of overwritten. This causes the vector to be re-allocated and therefore could invalidate pointers to its elements. --- libyul/backends/evm/NoOutputAssembly.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libyul/backends/evm/NoOutputAssembly.cpp b/libyul/backends/evm/NoOutputAssembly.cpp index 90713b0e2065..1acc0d0aebeb 100644 --- a/libyul/backends/evm/NoOutputAssembly.cpp +++ b/libyul/backends/evm/NoOutputAssembly.cpp @@ -212,13 +212,13 @@ NoOutputEVMDialect::NoOutputEVMDialect(EVMDialect const& _copyFrom): // them in one go, later reference pointers to this static vector static std::vector noOutputBuiltins = defineNoOutputBuiltins(); - m_functions.reserve(m_functions.size()); + yulAssert(m_functions.size() == noOutputBuiltins.size(), "Function count mismatch."); for (auto const& [index, builtinFunction]: m_functions | ranges::views::enumerate) { if (builtinFunction) - m_functions.emplace_back(&noOutputBuiltins[index]); + m_functions[index] = &noOutputBuiltins[index]; else - m_functions.emplace_back(nullptr); + m_functions[index] = nullptr; } } From 2593de82e6c46324455d26f3c146281cfa5216c7 Mon Sep 17 00:00:00 2001 From: r0qs <457348+r0qs@users.noreply.github.com> Date: Tue, 22 Jul 2025 12:04:14 +0200 Subject: [PATCH 1009/1022] Fix solidity public calls url --- docs/contributing.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/contributing.rst b/docs/contributing.rst index 3cdadef95300..2d5faa550b45 100644 --- a/docs/contributing.rst +++ b/docs/contributing.rst @@ -32,7 +32,7 @@ the team and contributors are working on, you can join our public team call: - Wednesdays at 3PM CET/CEST. -The call takes place on `Jitsi `_. +The call takes place on `Jitsi `_. How to Report Issues ==================== From bf6548ba70f81e08ea030ccafa1dd7bfc8d01d99 Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Tue, 18 Mar 2025 10:24:04 +0100 Subject: [PATCH 1010/1022] Add tests with non-zero PUSH #[$] asm instructions --- .../args | 1 + .../input.yul | 19 ++++ .../output | 101 ++++++++++++++++++ .../nontrivial_subassembly_ids.asm | 61 +++++++++++ 4 files changed, 182 insertions(+) create mode 100644 test/cmdlineTests/asm_json_subassembly_id_representation/args create mode 100644 test/cmdlineTests/asm_json_subassembly_id_representation/input.yul create mode 100644 test/cmdlineTests/asm_json_subassembly_id_representation/output create mode 100644 test/libevmasm/evmAssemblyTests/isoltestTesting/nontrivial_subassembly_ids.asm diff --git a/test/cmdlineTests/asm_json_subassembly_id_representation/args b/test/cmdlineTests/asm_json_subassembly_id_representation/args new file mode 100644 index 000000000000..52d48e24a77c --- /dev/null +++ b/test/cmdlineTests/asm_json_subassembly_id_representation/args @@ -0,0 +1 @@ +--asm-json --pretty-json --strict-assembly --json-indent 4 \ No newline at end of file diff --git a/test/cmdlineTests/asm_json_subassembly_id_representation/input.yul b/test/cmdlineTests/asm_json_subassembly_id_representation/input.yul new file mode 100644 index 000000000000..b6db74e7e356 --- /dev/null +++ b/test/cmdlineTests/asm_json_subassembly_id_representation/input.yul @@ -0,0 +1,19 @@ +object "root" { + code { + // this produces non-zero PUSH #[$] assembly item values + mstore(42, datasize("sub1.sub1_2")) + mstore(42, datasize("sub2.sub2_2")) + } + object "sub1" { + code {} + object "sub1_2" { + code {} + } + } + object "sub2" { + code {} + object "sub2_2" { + code {} + } + } +} diff --git a/test/cmdlineTests/asm_json_subassembly_id_representation/output b/test/cmdlineTests/asm_json_subassembly_id_representation/output new file mode 100644 index 000000000000..709f9158b24f --- /dev/null +++ b/test/cmdlineTests/asm_json_subassembly_id_representation/output @@ -0,0 +1,101 @@ + +======= input.yul (EVM) ======= + +EVM assembly: +{ + ".code": [ + { + "begin": 60, + "end": 83, + "name": "PUSH #[$]", + "source": -1, + "value": "000000000000000000000000000000000000000000000000ffffffffffffffff" + }, + { + "begin": 56, + "end": 58, + "name": "PUSH", + "source": -1, + "value": "2A" + }, + { + "begin": 49, + "end": 84, + "name": "MSTORE", + "source": -1 + }, + { + "begin": 108, + "end": 131, + "name": "PUSH #[$]", + "source": -1, + "value": "000000000000000000000000000000000000000000000000fffffffffffffffe" + }, + { + "begin": 104, + "end": 106, + "name": "PUSH", + "source": -1, + "value": "2A" + }, + { + "begin": 97, + "end": 132, + "name": "MSTORE", + "source": -1 + }, + { + "begin": 25, + "end": 148, + "name": "STOP", + "source": -1 + } + ], + ".data": { + "0": { + ".code": [ + { + "begin": 182, + "end": 189, + "name": "STOP", + "source": -1 + } + ], + ".data": { + "0": { + ".code": [ + { + "begin": 233, + "end": 240, + "name": "STOP", + "source": -1 + } + ] + } + } + }, + "1": { + ".code": [ + { + "begin": 290, + "end": 297, + "name": "STOP", + "source": -1 + } + ], + ".data": { + "0": { + ".code": [ + { + "begin": 341, + "end": 348, + "name": "STOP", + "source": -1 + } + ] + } + } + } + }, + "sourceList": [] +} diff --git a/test/libevmasm/evmAssemblyTests/isoltestTesting/nontrivial_subassembly_ids.asm b/test/libevmasm/evmAssemblyTests/isoltestTesting/nontrivial_subassembly_ids.asm new file mode 100644 index 000000000000..bcf9b03a7145 --- /dev/null +++ b/test/libevmasm/evmAssemblyTests/isoltestTesting/nontrivial_subassembly_ids.asm @@ -0,0 +1,61 @@ +// sub_0 and children +PUSH #[$] 0x0000 +// negative indices for nested subobjects in DFS order +PUSH #[$] 0x000000000000000000000000000000000000000000000000ffffffffffffffff +PUSH #[$] 0x000000000000000000000000000000000000000000000000fffffffffffffffe +PUSH #[$] 0x000000000000000000000000000000000000000000000000fffffffffffffffd +PUSH #[$] 0x000000000000000000000000000000000000000000000000fffffffffffffffc +// sub_1 and children +PUSH #[$] 0x0001 +PUSH #[$] 0x000000000000000000000000000000000000000000000000fffffffffffffffb + +.sub + // referencing sub_0.sub_0 from inside sub_0 + PUSH #[$] 0x0000 + // referencing sub_0.sub_0.sub_0 from inside sub_0 + PUSH #[$] 0x000000000000000000000000000000000000000000000000ffffffffffffffff + .sub + .sub + .sub + .sub +.sub + .sub +// ---- +// Assembly: +// dataSize(sub_0) +// dataSize(sub_0.sub_0) +// dataSize(sub_0.sub_0.sub_0) +// dataSize(sub_0.sub_1) +// dataSize(sub_0.sub_2) +// dataSize(sub_1) +// dataSize(sub_1.sub_0) +// stop +// +// sub_0: assembly { +// dataSize(sub_0) +// dataSize(sub_0.sub_0) +// stop +// +// sub_0: assembly { +// stop +// +// sub_0: assembly { +// } +// } +// +// sub_1: assembly { +// } +// +// sub_2: assembly { +// } +// } +// +// sub_1: assembly { +// stop +// +// sub_0: assembly { +// } +// } +// Bytecode: 6005600160006000600060016000fe +// Opcodes: PUSH1 0x5 PUSH1 0x1 PUSH1 0x0 PUSH1 0x0 PUSH1 0x0 PUSH1 0x1 PUSH1 0x0 INVALID +// SourceMappings: :::-:0;;;;;; From 57f39fa81d2075cc46d00cd60bd7a528a56a031f Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Tue, 18 Mar 2025 17:58:03 +0100 Subject: [PATCH 1011/1022] Make subassembly IDs based on fixed-size 64 bit uint --- Changelog.md | 1 + libevmasm/Assembly.cpp | 68 +++++++++++----------- libevmasm/Assembly.h | 26 +++++---- libevmasm/AssemblyItem.cpp | 37 ++++++------ libevmasm/AssemblyItem.h | 7 ++- libevmasm/BlockDeduplicator.cpp | 4 +- libevmasm/BlockDeduplicator.h | 9 +-- libevmasm/CMakeLists.txt | 1 + libevmasm/EVMAssemblyStack.cpp | 2 +- libevmasm/Inliner.cpp | 2 +- libevmasm/JumpdestRemover.cpp | 6 +- libevmasm/JumpdestRemover.h | 4 +- libevmasm/SubAssemblyID.h | 62 ++++++++++++++++++++ libsolidity/codegen/Compiler.h | 2 +- libsolidity/codegen/CompilerContext.h | 10 ++-- libsolidity/codegen/ContractCompiler.cpp | 10 ++-- libsolidity/codegen/ContractCompiler.h | 6 +- libyul/CompilabilityChecker.cpp | 4 +- libyul/Object.cpp | 8 +-- libyul/Object.h | 8 ++- libyul/ObjectOptimizer.cpp | 2 +- libyul/YulStack.cpp | 8 +-- libyul/backends/evm/AbstractAssembly.h | 4 +- libyul/backends/evm/EVMBuiltins.cpp | 16 ++--- libyul/backends/evm/EthAssemblyAdapter.cpp | 4 +- libyul/backends/evm/EthAssemblyAdapter.h | 2 +- libyul/backends/evm/NoOutputAssembly.cpp | 2 +- test/libevmasm/Assembler.cpp | 14 ++--- test/libevmasm/Optimiser.cpp | 2 +- 29 files changed, 202 insertions(+), 129 deletions(-) create mode 100644 libevmasm/SubAssemblyID.h diff --git a/Changelog.md b/Changelog.md index 18e0deeaf612..8220e6d74bfe 100644 --- a/Changelog.md +++ b/Changelog.md @@ -6,6 +6,7 @@ Compiler Features: * ethdebug: Experimental support for instructions and source locations under EOF. Bugfixes: +* Assembler: Fix not using a fixed-width type for IDs being assigned to subassemblies nested more than one level away, resulting in inconsistent `--asm-json` output between target architectures. ### 0.8.30 (2025-05-07) diff --git a/libevmasm/Assembly.cpp b/libevmasm/Assembly.cpp index 019683c9d4fd..3fe31771fcc6 100644 --- a/libevmasm/Assembly.cpp +++ b/libevmasm/Assembly.cpp @@ -39,6 +39,7 @@ #include #include +#include #include #include #include @@ -715,17 +716,17 @@ std::pair, std::vector> Assembly::fromJSO return std::make_pair(result, _level == 0 ? parsedSourceList : std::vector{}); } -void Assembly::encodeAllPossibleSubPathsInAssemblyTree(std::vector _pathFromRoot, std::vector _assembliesOnPath) +void Assembly::encodeAllPossibleSubPathsInAssemblyTree(std::vector _pathFromRoot, std::vector _assembliesOnPath) { _assembliesOnPath.push_back(this); - for (_pathFromRoot.push_back(0); _pathFromRoot.back() < m_subs.size(); ++_pathFromRoot.back()) + for (_pathFromRoot.push_back(SubAssemblyID{0}); _pathFromRoot.back().value < m_subs.size(); ++_pathFromRoot.back().value) { for (size_t distanceFromRoot = 0; distanceFromRoot < _assembliesOnPath.size(); ++distanceFromRoot) _assembliesOnPath[distanceFromRoot]->encodeSubPath( _pathFromRoot | ranges::views::drop_exactly(distanceFromRoot) | ranges::to ); - m_subs[_pathFromRoot.back()]->encodeAllPossibleSubPathsInAssemblyTree(_pathFromRoot, _assembliesOnPath); + m_subs[_pathFromRoot.back().asIndex()]->encodeAllPossibleSubPathsInAssemblyTree(_pathFromRoot, _assembliesOnPath); } } @@ -846,20 +847,20 @@ std::map const& Assembly::optimiseInternal( // Run optimisation for sub-assemblies. // TODO: verify and double-check this for EOF. - for (size_t subId = 0; subId < m_subs.size(); ++subId) + for (SubAssemblyID subID{0}; subID.value < m_subs.size(); ++subID.value) { OptimiserSettings settings = _settings; - Assembly& sub = *m_subs[subId]; + Assembly& sub = *m_subs[subID.asIndex()]; std::set referencedTags; for (auto& codeSection: m_codeSections) - referencedTags += JumpdestRemover::referencedTags(codeSection.items, subId); + referencedTags += JumpdestRemover::referencedTags(codeSection.items, subID); std::map const& subTagReplacements = sub.optimiseInternal( settings, referencedTags ); // Apply the replacements (can be empty). for (auto& codeSection: m_codeSections) - BlockDeduplicator::applyTagReplacement(codeSection.items, subTagReplacements, subId); + BlockDeduplicator::applyTagReplacement(codeSection.items, subTagReplacements, subID); } std::map tagReplacements; @@ -1235,7 +1236,7 @@ LinkerObject const& Assembly::assemble() const [[nodiscard]] bytes Assembly::assembleTag(AssemblyItem const& _item, size_t _pos, bool _addJumpDest) const { solRequire(_item.data() != 0, AssemblyException, "Invalid tag position."); - solRequire(_item.splitForeignPushTag().first == std::numeric_limits::max(), AssemblyException, "Foreign tag."); + solRequire(_item.splitForeignPushTag().first.empty(), AssemblyException, "Foreign tag."); solRequire(_pos < 0xffffffffL, AssemblyException, "Tag too large."); size_t tagId = static_cast(_item.data()); solRequire(m_tagPositionsInBytecode[tagId] == std::numeric_limits::max(), AssemblyException, "Duplicate tag position."); @@ -1306,10 +1307,10 @@ LinkerObject const& Assembly::assembleLegacy() const if (item.type() == PushTag) { auto [subId, tagId] = item.splitForeignPushTag(); - if (subId == std::numeric_limits::max()) + if (subId.empty()) continue; - assertThrow(subId < m_subs.size(), AssemblyException, "Invalid sub id"); - auto subTagPosition = m_subs[subId]->m_tagPositionsInBytecode.at(tagId); + solAssert(subId.value < m_subs.size(), "Invalid sub id"); + auto subTagPosition = m_subs[subId.asIndex()]->m_tagPositionsInBytecode.at(tagId); assertThrow(subTagPosition != std::numeric_limits::max(), AssemblyException, "Reference to tag without position."); bytesPerTag = std::max(bytesPerTag, numberEncodingSize(subTagPosition)); } @@ -1358,15 +1359,15 @@ LinkerObject const& Assembly::assembleLegacy() const ret.bytecode.resize(ret.bytecode.size() + bytesPerDataRef); break; case PushSub: - assertThrow(item.data() <= std::numeric_limits::max(), AssemblyException, ""); + solAssert(item.data() <= std::numeric_limits::max()); ret.bytecode.push_back(dataRefPush); - subRefs.insert(std::make_pair(static_cast(item.data()), ret.bytecode.size())); + subRefs.emplace(SubAssemblyID{item.data()}, ret.bytecode.size()); ret.bytecode.resize(ret.bytecode.size() + bytesPerDataRef); break; case PushSubSize: { - assertThrow(item.data() <= std::numeric_limits::max(), AssemblyException, ""); - auto s = subAssemblyById(static_cast(item.data()))->assemble().bytecode.size(); + solAssert(item.data() <= std::numeric_limits::max()); + auto s = subAssemblyById(SubAssemblyID{item.data()})->assemble().bytecode.size(); item.setPushedValue(u256(s)); unsigned b = std::max(1, numberEncodingSize(s)); ret.bytecode.push_back(static_cast(pushInstruction(b))); @@ -1481,14 +1482,12 @@ LinkerObject const& Assembly::assembleLegacy() const } for (auto const& i: tagRefs) { - size_t subId; - size_t tagId; - std::tie(subId, tagId) = i.second; - assertThrow(subId == std::numeric_limits::max() || subId < m_subs.size(), AssemblyException, "Invalid sub id"); + auto [subId, tagId] = i.second; + solAssert(subId.empty() || subId.value < m_subs.size(), "Invalid sub id"); std::vector const& tagPositions = - subId == std::numeric_limits::max() ? + subId.empty() ? m_tagPositionsInBytecode : - m_subs[subId]->m_tagPositionsInBytecode; + m_subs[subId.asIndex()]->m_tagPositionsInBytecode; assertThrow(tagId < tagPositions.size(), AssemblyException, "Reference to non-existing tag."); size_t pos = tagPositions[tagId]; assertThrow(pos != std::numeric_limits::max(), AssemblyException, "Reference to tag without position."); @@ -1813,14 +1812,13 @@ LinkerObject const& Assembly::assembleEOF() const return ret; } -std::vector Assembly::decodeSubPath(size_t _subObjectId) const +std::vector Assembly::decodeSubPath(SubAssemblyID _subObjectId) const { - if (_subObjectId < m_subs.size()) + if (_subObjectId.value < m_subs.size()) return {_subObjectId}; - auto subIdPathIt = find_if( - m_subPaths.begin(), - m_subPaths.end(), + auto subIdPathIt = ranges::find_if( + m_subPaths, [_subObjectId](auto const& subId) { return subId.second == _subObjectId; } ); @@ -1828,32 +1826,32 @@ std::vector Assembly::decodeSubPath(size_t _subObjectId) const return subIdPathIt->first; } -size_t Assembly::encodeSubPath(std::vector const& _subPath) +SubAssemblyID Assembly::encodeSubPath(std::vector const& _subPath) { assertThrow(!_subPath.empty(), AssemblyException, ""); if (_subPath.size() == 1) { - assertThrow(_subPath[0] < m_subs.size(), AssemblyException, ""); + solAssert(_subPath[0].value < m_subs.size()); return _subPath[0]; } - if (m_subPaths.find(_subPath) == m_subPaths.end()) + if (!m_subPaths.contains(_subPath)) { - size_t objectId = std::numeric_limits::max() - m_subPaths.size(); - assertThrow(objectId >= m_subs.size(), AssemblyException, ""); + SubAssemblyID const objectId{std::numeric_limits::max() - m_subPaths.size()}; + solAssert(objectId.value >= m_subs.size()); m_subPaths[_subPath] = objectId; } return m_subPaths[_subPath]; } -Assembly const* Assembly::subAssemblyById(size_t _subId) const +Assembly const* Assembly::subAssemblyById(SubAssemblyID const _subId) const { - std::vector subIds = decodeSubPath(_subId); + std::vector subIDs = decodeSubPath(_subId); Assembly const* currentAssembly = this; - for (size_t currentSubId: subIds) + for (auto const& subID: subIDs) { - currentAssembly = currentAssembly->m_subs.at(currentSubId).get(); + currentAssembly = currentAssembly->m_subs.at(subID.asIndex()).get(); assertThrow(currentAssembly, AssemblyException, ""); } diff --git a/libevmasm/Assembly.h b/libevmasm/Assembly.h index 30b06dd367fb..f931c438e38a 100644 --- a/libevmasm/Assembly.h +++ b/libevmasm/Assembly.h @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -47,9 +48,9 @@ using AssemblyPointer = std::shared_ptr; class Assembly { - using TagRefs = std::map>; + using TagRefs = std::map>; using DataRefs = std::multimap; - using SubAssemblyRefs = std::multimap; + using SubAssemblyRefs = std::multimap; using ProgramSizeRefs = std::vector; using LinkRef = std::pair; @@ -81,8 +82,8 @@ class Assembly AssemblyItem newData(bytes const& _data) { util::h256 h(util::keccak256(util::asString(_data))); m_data[h] = _data; return AssemblyItem(PushData, h); } bytes const& data(util::h256 const& _i) const { return m_data.at(_i); } AssemblyItem newSub(AssemblyPointer const& _sub) { m_subs.push_back(_sub); return AssemblyItem(PushSub, m_subs.size() - 1); } - Assembly const& sub(size_t _sub) const { return *m_subs.at(_sub); } - Assembly& sub(size_t _sub) { return *m_subs.at(_sub); } + Assembly const& sub(SubAssemblyID const _sub) const { return *m_subs.at(_sub.asIndex()); } + Assembly& sub(SubAssemblyID const _sub) { return *m_subs.at(_sub.asIndex()); } size_t numSubs() const { return m_subs.size(); } AssemblyItem newPushSubSize(u256 const& _subId) { return AssemblyItem(PushSubSize, _subId); } AssemblyItem newPushLibraryAddress(std::string const& _identifier); @@ -142,9 +143,9 @@ class Assembly /// Adds a subroutine to the code (in the data section) and pushes its size (via a tag) /// on the stack. @returns the pushsub assembly item. AssemblyItem appendSubroutine(AssemblyPointer const& _assembly) { auto sub = newSub(_assembly); append(newPushSubSize(size_t(sub.data()))); return sub; } - void pushSubroutineSize(size_t _subRoutine) { append(newPushSubSize(_subRoutine)); } + void pushSubroutineSize(SubAssemblyID _subRoutine) { append(newPushSubSize(_subRoutine.value)); } /// Pushes the offset of the subroutine. - void pushSubroutineOffset(size_t _subRoutine) { append(AssemblyItem(PushSub, _subRoutine)); } + void pushSubroutineOffset(SubAssemblyID _subRoutine) { append(AssemblyItem(PushSub, _subRoutine.value)); } /// Appends @a _data literally to the very end of the bytecode. void appendToAuxiliaryData(bytes const& _data) { m_auxiliaryData += _data; } @@ -216,8 +217,8 @@ class Assembly /// Mark this assembly as invalid. Calling ``assemble`` on it will throw. void markAsInvalid() { m_invalid = true; } - std::vector decodeSubPath(size_t _subObjectId) const; - size_t encodeSubPath(std::vector const& _subPath); + std::vector decodeSubPath(SubAssemblyID _subObjectId) const; + SubAssemblyID encodeSubPath(std::vector const& _subPath); bool isCreation() const { return m_creation; } @@ -265,9 +266,9 @@ class Assembly private: bool m_invalid = false; - Assembly const* subAssemblyById(size_t _subId) const; + Assembly const* subAssemblyById(SubAssemblyID _subId) const; - void encodeAllPossibleSubPathsInAssemblyTree(std::vector _pathFromRoot = {}, std::vector _assembliesOnPath = {}); + void encodeAllPossibleSubPathsInAssemblyTree(std::vector _pathFromRoot = {}, std::vector _assembliesOnPath = {}); std::shared_ptr sharedSourceName(std::string const& _name) const; @@ -315,7 +316,10 @@ class Assembly /// Map from a vector representing a path to a particular sub assembly to sub assembly id. /// This map is used only for sub-assemblies which are not direct sub-assemblies (where path is having more than one value). - std::map, size_t> m_subPaths; + /// Nested/indirect SubAssemblyIDs are assigned negative unsigned 64 bit integers, i.e., the `i`th indirect + /// index corresponds to `std::numeric_limits::max() - i` in contrast to direct indices which occupy + /// the non-negative half of the index space. + std::map, SubAssemblyID> m_subPaths; /// Contains the tag replacements relevant for super-assemblies. /// If set, it means the optimizer has run and we will not run it again. diff --git a/libevmasm/AssemblyItem.cpp b/libevmasm/AssemblyItem.cpp index 8a917986f915..80df5ce74776 100644 --- a/libevmasm/AssemblyItem.cpp +++ b/libevmasm/AssemblyItem.cpp @@ -50,7 +50,7 @@ std::string toStringInHex(u256 _value) } -AssemblyItem AssemblyItem::toSubAssemblyTag(size_t _subId) const +AssemblyItem AssemblyItem::toSubAssemblyTag(SubAssemblyID _subId) const { assertThrow(data() < (u256(1) << 64), util::Exception, "Tag already has subassembly set."); assertThrow(m_type == PushTag || m_type == Tag, util::Exception, ""); @@ -61,20 +61,21 @@ AssemblyItem AssemblyItem::toSubAssemblyTag(size_t _subId) const return r; } -std::pair AssemblyItem::splitForeignPushTag() const +std::pair AssemblyItem::splitForeignPushTag() const { solAssert(m_type == PushTag || m_type == Tag || m_type == RelativeJump || m_type == ConditionalRelativeJump); u256 combined = u256(data()); - size_t subId = static_cast((combined >> 64) - 1); + // the combined u256 is 'dirty', so we can't use the conversion constructor of SubAssemblyID here + SubAssemblyID const subID{static_cast((combined >> 64) - 1)}; size_t tag = static_cast(combined & 0xffffffffffffffffULL); - return std::make_pair(subId, tag); + return std::make_pair(subID, tag); } size_t AssemblyItem::relativeJumpTagID() const { solAssert(m_type == RelativeJump || m_type == ConditionalRelativeJump); auto const [subId, tagId] = splitForeignPushTag(); - solAssert(subId == std::numeric_limits::max(), "Relative jump to sub"); + solAssert(subId.empty(), "Relative jump to sub"); return tagId; } @@ -130,13 +131,13 @@ std::pair AssemblyItem::nameAndData(langutil::EVMVersi util::unreachable(); } -void AssemblyItem::setPushTagSubIdAndTag(size_t _subId, size_t _tag) +void AssemblyItem::setPushTagSubIdAndTag(SubAssemblyID _subId, size_t _tag) { solAssert(m_type == PushTag || m_type == Tag || m_type == RelativeJump || m_type == ConditionalRelativeJump); - solAssert(!(m_type == RelativeJump || m_type == ConditionalRelativeJump) || _subId == std::numeric_limits::max()); + solAssert(!(m_type == RelativeJump || m_type == ConditionalRelativeJump) || _subId.empty()); u256 data = _tag; - if (_subId != std::numeric_limits::max()) - data |= (u256(_subId) + 1) << 64; + if (!_subId.empty()) + data |= (u256(_subId.value) + 1) << 64; setData(data); } @@ -352,13 +353,11 @@ std::string AssemblyItem::toAssemblyText(Assembly const& _assembly) const break; case PushTag: { - size_t sub{0}; - size_t tag{0}; - std::tie(sub, tag) = splitForeignPushTag(); - if (sub == std::numeric_limits::max()) + auto [sub, tag] = splitForeignPushTag(); + if (sub.empty()) text = std::string("tag_") + std::to_string(tag); else - text = std::string("tag_") + std::to_string(sub) + "_" + std::to_string(tag); + text = std::string("tag_") + std::to_string(sub.value) + "_" + std::to_string(tag); break; } case Tag: @@ -372,8 +371,8 @@ std::string AssemblyItem::toAssemblyText(Assembly const& _assembly) const case PushSubSize: { std::vector subPathComponents; - for (size_t subPathComponentId: _assembly.decodeSubPath(static_cast(data()))) - subPathComponents.emplace_back("sub_" + std::to_string(subPathComponentId)); + for (SubAssemblyID subPathComponentId: _assembly.decodeSubPath(SubAssemblyID{data()})) + subPathComponents.emplace_back("sub_" + std::to_string(subPathComponentId.value)); text = (type() == PushSub ? "dataOffset"s : "dataSize"s) + "(" + @@ -469,11 +468,11 @@ std::ostream& solidity::evmasm::operator<<(std::ostream& _out, AssemblyItem cons break; case PushTag: { - size_t subId = _item.splitForeignPushTag().first; - if (subId == std::numeric_limits::max()) + SubAssemblyID subId = _item.splitForeignPushTag().first; + if (subId.empty()) _out << " PushTag " << _item.splitForeignPushTag().second; else - _out << " PushTag " << subId << ":" << _item.splitForeignPushTag().second; + _out << " PushTag " << subId.value << ":" << _item.splitForeignPushTag().second; break; } case Tag: diff --git a/libevmasm/AssemblyItem.h b/libevmasm/AssemblyItem.h index 8386bf2dd4bc..dcb4bf3a7988 100644 --- a/libevmasm/AssemblyItem.h +++ b/libevmasm/AssemblyItem.h @@ -24,6 +24,7 @@ #include #include +#include #include #include #include @@ -171,14 +172,14 @@ class AssemblyItem AssemblyItem pushTag() const { solAssert(m_type == PushTag || m_type == Tag || m_type == RelativeJump || m_type == ConditionalRelativeJump); return AssemblyItem(PushTag, data()); } /// Converts the tag to a subassembly tag. This has to be called in order to move a tag across assemblies. /// @param _subId the identifier of the subassembly the tag is taken from. - AssemblyItem toSubAssemblyTag(size_t _subId) const; + AssemblyItem toSubAssemblyTag(SubAssemblyID _subId) const; /// @returns splits the data of the push tag into sub assembly id and actual tag id. /// The sub assembly id of non-foreign push tags is -1. - std::pair splitForeignPushTag() const; + std::pair splitForeignPushTag() const; /// @returns relative jump target tag ID. Asserts that it is not foreign tag. size_t relativeJumpTagID() const; /// Sets sub-assembly part and tag for a push tag. - void setPushTagSubIdAndTag(size_t _subId, size_t _tag); + void setPushTagSubIdAndTag(SubAssemblyID _subId, size_t _tag); AssemblyItemType type() const { return m_type; } u256 const& data() const { solAssert(m_type != Operation && m_data != nullptr); return *m_data; } diff --git a/libevmasm/BlockDeduplicator.cpp b/libevmasm/BlockDeduplicator.cpp index 3ba8cfcd3523..5c9c5a840f6e 100644 --- a/libevmasm/BlockDeduplicator.cpp +++ b/libevmasm/BlockDeduplicator.cpp @@ -101,14 +101,14 @@ bool BlockDeduplicator::deduplicate() bool BlockDeduplicator::applyTagReplacement( AssemblyItems& _items, std::map const& _replacements, - size_t _subId + SubAssemblyID _subId ) { bool changed = false; for (AssemblyItem& item: _items) if (item.type() == PushTag || item.type() == RelativeJump || item.type() == ConditionalRelativeJump) { - size_t subId; + SubAssemblyID subId; size_t tagId; std::tie(subId, tagId) = item.splitForeignPushTag(); if (subId != _subId) diff --git a/libevmasm/BlockDeduplicator.h b/libevmasm/BlockDeduplicator.h index fb83b317e0a1..26bcf59dcaa1 100644 --- a/libevmasm/BlockDeduplicator.h +++ b/libevmasm/BlockDeduplicator.h @@ -24,10 +24,11 @@ #pragma once +#include + #include #include - #include #include #include @@ -52,14 +53,14 @@ class BlockDeduplicator /// @returns the tags that were replaced. std::map const& replacedTags() const { return m_replacedTags; } - /// Replaces all PushTag operations insied @a _items that match a key in - /// @a _replacements by the respective value. If @a _subID is not -1, only + /// Replaces all PushTag operations inside @a _items that match a key in + /// @a _replacements by the respective value. If @a _subID is not empty, only /// apply the replacement for foreign tags from this sub id. /// @returns true iff a replacement was performed. static bool applyTagReplacement( AssemblyItems& _items, std::map const& _replacements, - size_t _subID = size_t(-1) + SubAssemblyID _subID = {} ); private: diff --git a/libevmasm/CMakeLists.txt b/libevmasm/CMakeLists.txt index 74aaeb6c293b..55ae30e7c182 100644 --- a/libevmasm/CMakeLists.txt +++ b/libevmasm/CMakeLists.txt @@ -44,6 +44,7 @@ set(sources SimplificationRule.h SimplificationRules.cpp SimplificationRules.h + SubAssemblyID.h ) add_library(evmasm ${sources}) diff --git a/libevmasm/EVMAssemblyStack.cpp b/libevmasm/EVMAssemblyStack.cpp index bed4ff744ec4..34a5c8a2a76c 100644 --- a/libevmasm/EVMAssemblyStack.cpp +++ b/libevmasm/EVMAssemblyStack.cpp @@ -62,7 +62,7 @@ void EVMAssemblyStack::assemble() m_sourceMapping = AssemblyItem::computeSourceMapping(m_evmAssembly->codeSections().front().items, sourceIndices()); if (m_evmAssembly->numSubs() > 0) { - m_evmRuntimeAssembly = std::make_shared(m_evmAssembly->sub(0)); + m_evmRuntimeAssembly = std::make_shared(m_evmAssembly->sub(SubAssemblyID{0})); solAssert(m_evmRuntimeAssembly && !m_evmRuntimeAssembly->isCreation()); // TODO: Check for EOF solAssert(m_evmRuntimeAssembly->codeSections().size() == 1); diff --git a/libevmasm/Inliner.cpp b/libevmasm/Inliner.cpp index f3358128c655..f32a03ab59f5 100644 --- a/libevmasm/Inliner.cpp +++ b/libevmasm/Inliner.cpp @@ -71,7 +71,7 @@ std::optional getLocalTag(AssemblyItem const& _item) if (_item.type() != PushTag && _item.type() != Tag) return std::nullopt; auto [subId, tag] = _item.splitForeignPushTag(); - if (subId != std::numeric_limits::max()) + if (!subId.empty()) return std::nullopt; return tag; } diff --git a/libevmasm/JumpdestRemover.cpp b/libevmasm/JumpdestRemover.cpp index 7ded5ae90889..84bec59d1693 100644 --- a/libevmasm/JumpdestRemover.cpp +++ b/libevmasm/JumpdestRemover.cpp @@ -32,7 +32,7 @@ using namespace solidity::evmasm; bool JumpdestRemover::optimise(std::set const& _tagsReferencedFromOutside) { - std::set references{referencedTags(m_items, std::numeric_limits::max())}; + std::set references{referencedTags(m_items, SubAssemblyID{})}; references.insert(_tagsReferencedFromOutside.begin(), _tagsReferencedFromOutside.end()); size_t initialSize = m_items.size(); @@ -45,7 +45,7 @@ bool JumpdestRemover::optimise(std::set const& _tagsReferencedFromOutsid if (_item.type() != Tag) return false; auto asmIdAndTag = _item.splitForeignPushTag(); - assertThrow(asmIdAndTag.first == std::numeric_limits::max(), OptimizerException, "Sub-assembly tag used as label."); + solAssert(asmIdAndTag.first.empty(), "Sub-assembly tag used as label."); size_t tag = asmIdAndTag.second; return !references.count(tag); } @@ -54,7 +54,7 @@ bool JumpdestRemover::optimise(std::set const& _tagsReferencedFromOutsid return m_items.size() != initialSize; } -std::set JumpdestRemover::referencedTags(AssemblyItems const& _items, size_t _subId) +std::set JumpdestRemover::referencedTags(AssemblyItems const& _items, SubAssemblyID _subId) { std::set ret; for (auto const& item: _items) diff --git a/libevmasm/JumpdestRemover.h b/libevmasm/JumpdestRemover.h index e07550e2dd40..f344e543c573 100644 --- a/libevmasm/JumpdestRemover.h +++ b/libevmasm/JumpdestRemover.h @@ -21,6 +21,8 @@ */ #pragma once +#include + #include #include #include @@ -39,7 +41,7 @@ class JumpdestRemover /// @returns a set of all tags from the given sub-assembly that are referenced /// from the given list of items. - static std::set referencedTags(AssemblyItems const& _items, size_t _subId); + static std::set referencedTags(AssemblyItems const& _items, SubAssemblyID _subId); private: AssemblyItems& m_items; diff --git a/libevmasm/SubAssemblyID.h b/libevmasm/SubAssemblyID.h new file mode 100644 index 000000000000..48fb49894a4a --- /dev/null +++ b/libevmasm/SubAssemblyID.h @@ -0,0 +1,62 @@ +/* + This file is part of solidity. + + solidity is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + solidity is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with solidity. If not, see . +*/ +// SPDX-License-Identifier: GPL-3.0 + +#pragma once + +#include + +#include + +#include +#include +#include +#include + +namespace solidity::evmasm +{ + +/// Sub assembly ID representing class. Based on fixed-size 64-bit unsigned int. +/// An empty / root state is reflected by a value that is set to max and can be queried via the `empty()` member +/// function. +struct SubAssemblyID +{ + using ValueType = uint64_t; + SubAssemblyID() = default; + SubAssemblyID(ValueType const _value): value(_value) {} + explicit SubAssemblyID(u256 const& _data) + { + solAssert(_data <= std::numeric_limits::max()); + value = static_cast(_data); + } + + size_t asIndex() const + { + if constexpr(sizeof(ValueType) > sizeof(size_t)) + { + solAssert(value < std::numeric_limits::max()); + return static_cast(value); + } + return value; + } + bool empty() const { return value == std::numeric_limits::max(); } + auto operator<=>(SubAssemblyID const&) const = default; + + ValueType value = std::numeric_limits::max(); +}; + +} diff --git a/libsolidity/codegen/Compiler.h b/libsolidity/codegen/Compiler.h index bc801ff5782b..1df3e3cb4219 100644 --- a/libsolidity/codegen/Compiler.h +++ b/libsolidity/codegen/Compiler.h @@ -70,7 +70,7 @@ class Compiler private: OptimiserSettings const m_optimiserSettings; CompilerContext m_runtimeContext; - size_t m_runtimeSub = size_t(-1); ///< Identifier of the runtime sub-assembly, if present. + evmasm::SubAssemblyID m_runtimeSub{}; ///< Identifier of the runtime sub-assembly, if present. CompilerContext m_context; }; diff --git a/libsolidity/codegen/CompilerContext.h b/libsolidity/codegen/CompilerContext.h index e8c4e9bc77f7..638ee6939ca8 100644 --- a/libsolidity/codegen/CompilerContext.h +++ b/libsolidity/codegen/CompilerContext.h @@ -75,7 +75,7 @@ class CompilerContext m_yulUtilFunctions(m_evmVersion, _eofVersion, m_revertStrings, m_yulFunctionCollector) { if (m_runtimeContext) - m_runtimeSub = size_t(m_asm->newSub(m_runtimeContext->m_asm).data()); + m_runtimeSub = evmasm::SubAssemblyID{m_asm->newSub(m_runtimeContext->m_asm).data()}; } langutil::EVMVersion const& evmVersion() const { return m_evmVersion; } @@ -227,9 +227,9 @@ class CompilerContext /// on the stack. @returns the pushsub assembly item. evmasm::AssemblyItem addSubroutine(evmasm::AssemblyPointer const& _assembly) { return m_asm->appendSubroutine(_assembly); } /// Pushes the size of the subroutine. - void pushSubroutineSize(size_t _subRoutine) { m_asm->pushSubroutineSize(_subRoutine); } + void pushSubroutineSize(evmasm::SubAssemblyID _subRoutine) { m_asm->pushSubroutineSize(_subRoutine); } /// Pushes the offset of the subroutine. - void pushSubroutineOffset(size_t _subRoutine) { m_asm->pushSubroutineOffset(_subRoutine); } + void pushSubroutineOffset(evmasm::SubAssemblyID _subRoutine) { m_asm->pushSubroutineOffset(_subRoutine); } /// Pushes the size of the final program void appendProgramSize() { m_asm->appendProgramSize(); } /// Adds data to the data section, pushes a reference to the stack @@ -289,7 +289,7 @@ class CompilerContext /// @returns the runtime context if in creation mode and runtime context is set, nullptr otherwise. CompilerContext* runtimeContext() const { return m_runtimeContext; } /// @returns the identifier of the runtime subroutine. - size_t runtimeSub() const { return m_runtimeSub; } + evmasm::SubAssemblyID runtimeSub() const { return m_runtimeSub; } /// @returns a const reference to the underlying assembly. evmasm::Assembly const& assembly() const { return *m_asm; } @@ -376,7 +376,7 @@ class CompilerContext /// The runtime context if in Creation mode, this is used for generating tags that would be stored into the storage and then used at runtime. CompilerContext *m_runtimeContext; /// The index of the runtime subroutine. - size_t m_runtimeSub = std::numeric_limits::max(); + evmasm::SubAssemblyID m_runtimeSub{}; /// An index of low-level function labels by name. std::map m_lowLevelFunctions; /// Collector for yul functions. diff --git a/libsolidity/codegen/ContractCompiler.cpp b/libsolidity/codegen/ContractCompiler.cpp index 3a4dca0439ca..fc5ec2917f33 100644 --- a/libsolidity/codegen/ContractCompiler.cpp +++ b/libsolidity/codegen/ContractCompiler.cpp @@ -108,7 +108,7 @@ void ContractCompiler::compileContract( appendFunctionSelector(_contract); } -size_t ContractCompiler::compileConstructor( +SubAssemblyID ContractCompiler::compileConstructor( ContractDefinition const& _contract, std::map> const& _otherCompilers ) @@ -167,7 +167,7 @@ void ContractCompiler::appendInitAndConstructorCode(ContractDefinition const& _c } } -size_t ContractCompiler::packIntoContractCreator(ContractDefinition const& _contract) +SubAssemblyID ContractCompiler::packIntoContractCreator(ContractDefinition const& _contract) { solAssert(!!m_runtimeCompiler, ""); solAssert(!_contract.isLibrary(), "Tried to use contract creator or library."); @@ -186,7 +186,7 @@ size_t ContractCompiler::packIntoContractCreator(ContractDefinition const& _cont CompilerContext::LocationSetter locationSetter(m_context, _contract); m_context << deployRoutine; - solAssert(m_context.runtimeSub() != std::numeric_limits::max(), "Runtime sub not registered"); + solAssert(!m_context.runtimeSub().empty(), "Runtime sub not registered"); ContractType contractType(_contract); auto const& immutables = contractType.immutableVariables(); @@ -220,7 +220,7 @@ size_t ContractCompiler::packIntoContractCreator(ContractDefinition const& _cont return m_context.runtimeSub(); } -size_t ContractCompiler::deployLibrary(ContractDefinition const& _contract) +SubAssemblyID ContractCompiler::deployLibrary(ContractDefinition const& _contract) { solAssert(!!m_runtimeCompiler, ""); solAssert(_contract.isLibrary(), "Tried to deploy contract as library."); @@ -230,7 +230,7 @@ size_t ContractCompiler::deployLibrary(ContractDefinition const& _contract) CompilerContext::LocationSetter locationSetter(m_context, _contract); - solAssert(m_context.runtimeSub() != std::numeric_limits::max(), "Runtime sub not registered"); + solAssert(!m_context.runtimeSub().empty(), "Runtime sub not registered"); m_context.pushSubroutineSize(m_context.runtimeSub()); m_context.pushSubroutineOffset(m_context.runtimeSub()); // This code replaces the address added by appendDeployTimeAddress(). diff --git a/libsolidity/codegen/ContractCompiler.h b/libsolidity/codegen/ContractCompiler.h index 592b6703997b..e342bbc5fb1b 100644 --- a/libsolidity/codegen/ContractCompiler.h +++ b/libsolidity/codegen/ContractCompiler.h @@ -58,7 +58,7 @@ class ContractCompiler: private ASTConstVisitor ); /// Compiles the constructor part of the contract. /// @returns the identifier of the runtime sub-assembly. - size_t compileConstructor( + evmasm::SubAssemblyID compileConstructor( ContractDefinition const& _contract, std::map> const& _otherCompilers ); @@ -73,11 +73,11 @@ class ContractCompiler: private ASTConstVisitor /// Adds the code that is run at creation time. Should be run after exchanging the run-time context /// with a new and initialized context. Adds the constructor code. /// @returns the identifier of the runtime sub assembly - size_t packIntoContractCreator(ContractDefinition const& _contract); + evmasm::SubAssemblyID packIntoContractCreator(ContractDefinition const& _contract); /// Appends code that deploys the given contract as a library. /// Will also add code that modifies the contract in memory by injecting the current address /// for the call protector. - size_t deployLibrary(ContractDefinition const& _contract); + evmasm::SubAssemblyID deployLibrary(ContractDefinition const& _contract); /// Appends state variable initialisation and constructor code. void appendInitAndConstructorCode(ContractDefinition const& _contract); void appendBaseConstructor(FunctionDefinition const& _constructor); diff --git a/libyul/CompilabilityChecker.cpp b/libyul/CompilabilityChecker.cpp index 2df14f211939..6cd59874658f 100644 --- a/libyul/CompilabilityChecker.cpp +++ b/libyul/CompilabilityChecker.cpp @@ -49,9 +49,9 @@ CompilabilityChecker::CompilabilityChecker( BuiltinContext builtinContext; builtinContext.currentObject = &_object; if (!_object.name.empty()) - builtinContext.subIDs[_object.name] = 1; + builtinContext.subIDs[_object.name] = {1}; for (auto const& subNode: _object.subObjects) - builtinContext.subIDs[subNode->name] = 1; + builtinContext.subIDs[subNode->name] = {1}; NoOutputAssembly assembly{evmDialect->evmVersion()}; CodeTransform transform( assembly, diff --git a/libyul/Object.cpp b/libyul/Object.cpp index 54ec6a3cfd7a..bb044128766a 100644 --- a/libyul/Object.cpp +++ b/libyul/Object.cpp @@ -169,7 +169,7 @@ Object::Structure Object::summarizeStructure() const return structure; } -std::vector Object::pathToSubObject(std::string_view _qualifiedName) const +std::vector Object::pathToSubObject(std::string_view _qualifiedName) const { yulAssert(_qualifiedName != name, ""); yulAssert(subIndexByName.count(name) == 0, ""); @@ -181,7 +181,7 @@ std::vector Object::pathToSubObject(std::string_view _qualifiedName) con std::vector subObjectPathComponents; boost::algorithm::split(subObjectPathComponents, _qualifiedName, boost::is_any_of(".")); - std::vector path; + std::vector path; Object const* object = this; for (std::string const& currentSubObjectName: subObjectPathComponents) { @@ -193,8 +193,8 @@ std::vector Object::pathToSubObject(std::string_view _qualifiedName) con ); object = dynamic_cast(object->subObjects[subIndexIt->second].get()); yulAssert(object, "Assembly object <" + std::string(_qualifiedName) + "> not found or does not contain code."); - yulAssert(object->subId != std::numeric_limits::max(), ""); - path.push_back({object->subId}); + yulAssert(!object->subId.empty()); + path.emplace_back(object->subId); } return path; diff --git a/libyul/Object.h b/libyul/Object.h index c865b906ed37..a816db11b820 100644 --- a/libyul/Object.h +++ b/libyul/Object.h @@ -24,6 +24,8 @@ #include #include +#include + #include #include @@ -135,14 +137,14 @@ class Object: public ObjectNode /// pathToSubObject("E2.F3.H4") == {1, 0, 2} /// pathToSubObject("A1.E2") == {1} /// The path must not lead to a @a Data object (will throw in that case). - std::vector pathToSubObject(std::string_view _qualifiedName) const; + std::vector pathToSubObject(std::string_view _qualifiedName) const; std::shared_ptr code() const; void setCode(std::shared_ptr const& _ast, std::shared_ptr = nullptr); bool hasCode() const; - /// sub id for object if it is subobject of another object, max value if it is not subobject - size_t subId = std::numeric_limits::max(); + /// sub id for object if it is subobject of another object, max value / empty if it is not subobject + evmasm::SubAssemblyID subId{}; std::vector> subObjects; std::map> subIndexByName; diff --git a/libyul/ObjectOptimizer.cpp b/libyul/ObjectOptimizer.cpp index a09e88791577..63f372bf6448 100644 --- a/libyul/ObjectOptimizer.cpp +++ b/libyul/ObjectOptimizer.cpp @@ -56,7 +56,7 @@ Dialect const& yul::languageToDialect(Language _language, EVMVersion _version, s void ObjectOptimizer::optimize(Object& _object, Settings const& _settings) { - yulAssert(_object.subId == std::numeric_limits::max(), "Not a top-level object."); + yulAssert(_object.subId.empty(), "Not a top-level object."); optimize(_object, _settings, true /* _isCreation */); } diff --git a/libyul/YulStack.cpp b/libyul/YulStack.cpp index b59b4781fe19..52c6241c6a34 100644 --- a/libyul/YulStack.cpp +++ b/libyul/YulStack.cpp @@ -330,15 +330,15 @@ YulStack::assembleEVMWithDeployed(std::optional _deployName) assembly.optimise(evmasm::Assembly::OptimiserSettings::translateSettings(m_optimiserSettings)); - std::optional subIndex; + std::optional subIndex; // Pick matching assembly if name was given if (_deployName.has_value()) { for (size_t i = 0; i < assembly.numSubs(); i++) - if (assembly.sub(i).name() == _deployName) + if (assembly.sub({i}).name() == _deployName) { - subIndex = i; + subIndex = {i}; break; } @@ -346,7 +346,7 @@ YulStack::assembleEVMWithDeployed(std::optional _deployName) } // Otherwise use heuristic: If there is a single sub-assembly, this is likely the object to be deployed. else if (assembly.numSubs() == 1) - subIndex = 0; + subIndex = {0}; if (subIndex.has_value()) { diff --git a/libyul/backends/evm/AbstractAssembly.h b/libyul/backends/evm/AbstractAssembly.h index 41f480f442a0..3108729b9fa9 100644 --- a/libyul/backends/evm/AbstractAssembly.h +++ b/libyul/backends/evm/AbstractAssembly.h @@ -25,6 +25,8 @@ #include +#include + #include #include #include @@ -55,7 +57,7 @@ class AbstractAssembly { public: using LabelID = size_t; - using SubID = size_t; + using SubID = evmasm::SubAssemblyID; using ContainerID = uint8_t; using FunctionID = uint16_t; enum class JumpType { Ordinary, IntoFunction, OutOfFunction }; diff --git a/libyul/backends/evm/EVMBuiltins.cpp b/libyul/backends/evm/EVMBuiltins.cpp index d8a3d5c8e34e..bc459063242b 100644 --- a/libyul/backends/evm/EVMBuiltins.cpp +++ b/libyul/backends/evm/EVMBuiltins.cpp @@ -135,10 +135,10 @@ BuiltinFunctionForEVM datasizeBuiltin() _assembly.appendAssemblySize(); else { - std::vector subIdPath = + std::vector subIdPath = _context.subIDs.count(dataName.str()) == 0 ? _context.currentObject->pathToSubObject(dataName.str()) : - std::vector{_context.subIDs.at(dataName.str())}; + std::vector{_context.subIDs.at(dataName.str())}; yulAssert(!subIdPath.empty(), "Could not find assembly object <" + dataName.str() + ">."); _assembly.appendDataSize(subIdPath); } @@ -161,10 +161,10 @@ BuiltinFunctionForEVM dataoffsetBuiltin() _assembly.appendConstant(0); else { - std::vector subIdPath = + std::vector subIdPath = _context.subIDs.count(dataName.str()) == 0 ? _context.currentObject->pathToSubObject(dataName.str()) : - std::vector{_context.subIDs.at(dataName.str())}; + std::vector{_context.subIDs.at(dataName.str())}; yulAssert(!subIdPath.empty(), "Could not find assembly object <" + dataName.str() + ">."); _assembly.appendDataOffset(subIdPath); } @@ -284,8 +284,8 @@ BuiltinFunctionForEVM eofcreateBuiltin() yulAssert(!util::contains(formattedLiteral, '.')); auto const* containerID = util::valueOrNullptr(context.subIDs, formattedLiteral); yulAssert(containerID != nullptr); - yulAssert(*containerID <= std::numeric_limits::max()); - _assembly.appendEOFCreate(static_cast(*containerID)); + yulAssert(containerID->value <= std::numeric_limits::max()); + _assembly.appendEOFCreate(static_cast(containerID->value)); } ); } @@ -311,8 +311,8 @@ BuiltinFunctionForEVM returncontractBuiltin() yulAssert(!util::contains(formattedLiteral, '.')); auto const* containerID = util::valueOrNullptr(context.subIDs, formattedLiteral); yulAssert(containerID != nullptr); - yulAssert(*containerID <= std::numeric_limits::max()); - _assembly.appendReturnContract(static_cast(*containerID)); + yulAssert(containerID->value <= std::numeric_limits::max()); + _assembly.appendReturnContract(static_cast(containerID->value)); } ); } diff --git a/libyul/backends/evm/EthAssemblyAdapter.cpp b/libyul/backends/evm/EthAssemblyAdapter.cpp index 960e663dfa7a..47bd3ffb6644 100644 --- a/libyul/backends/evm/EthAssemblyAdapter.cpp +++ b/libyul/backends/evm/EthAssemblyAdapter.cpp @@ -142,7 +142,7 @@ std::pair, AbstractAssembly::SubID> EthAssembl { std::shared_ptr assembly{std::make_shared(m_assembly.evmVersion(), _creation, m_assembly.eofVersion(), std::move(_name))}; auto sub = m_assembly.newSub(assembly); - return {std::make_shared(*assembly), static_cast(sub.data())}; + return {std::make_shared(*assembly), SubID{sub.data()}}; } AbstractAssembly::FunctionID EthAssemblyAdapter::registerFunction(uint8_t _args, uint8_t _rets, bool _nonReturning) @@ -207,7 +207,7 @@ void EthAssemblyAdapter::appendDataSize(std::vector con AbstractAssembly::SubID EthAssemblyAdapter::appendData(bytes const& _data) { evmasm::AssemblyItem pushData = m_assembly.newData(_data); - SubID subID = m_nextDataCounter++; + SubID const subID{m_nextDataCounter++}; m_dataHashBySubId[subID] = pushData.data(); return subID; } diff --git a/libyul/backends/evm/EthAssemblyAdapter.h b/libyul/backends/evm/EthAssemblyAdapter.h index dd708b8b33de..ffdd26f146c7 100644 --- a/libyul/backends/evm/EthAssemblyAdapter.h +++ b/libyul/backends/evm/EthAssemblyAdapter.h @@ -88,6 +88,6 @@ class EthAssemblyAdapter: public AbstractAssembly evmasm::Assembly& m_assembly; std::map m_dataHashBySubId; - size_t m_nextDataCounter = std::numeric_limits::max() / 2; + SubID::ValueType m_nextDataCounter = std::numeric_limits::max() / 2; }; } diff --git a/libyul/backends/evm/NoOutputAssembly.cpp b/libyul/backends/evm/NoOutputAssembly.cpp index 1acc0d0aebeb..bd98d18ff2c0 100644 --- a/libyul/backends/evm/NoOutputAssembly.cpp +++ b/libyul/backends/evm/NoOutputAssembly.cpp @@ -176,7 +176,7 @@ void NoOutputAssembly::appendDataSize(std::vector const AbstractAssembly::SubID NoOutputAssembly::appendData(bytes const&) { - return 1; + return {1}; } diff --git a/test/libevmasm/Assembler.cpp b/test/libevmasm/Assembler.cpp index 32855cfbc211..4432a4f2ea6b 100644 --- a/test/libevmasm/Assembler.cpp +++ b/test/libevmasm/Assembler.cpp @@ -109,11 +109,11 @@ BOOST_AUTO_TEST_CASE(all_assembly_items, *boost::unit_test::precondition(nonEOF( // PushSubSize auto sub = _assembly.appendSubroutine(_subAsmPtr); // PushSub - _assembly.pushSubroutineOffset(static_cast(sub.data())); + _assembly.pushSubroutineOffset(SubAssemblyID(sub.data())); // PushSubSize auto verbatim_sub = _assembly.appendSubroutine(_verbatimAsmPtr); // PushSub - _assembly.pushSubroutineOffset(static_cast(verbatim_sub.data())); + _assembly.pushSubroutineOffset(SubAssemblyID(verbatim_sub.data())); // PushDeployTimeAddress _assembly.append(PushDeployTimeAddress); // AssignImmutable. @@ -332,7 +332,7 @@ BOOST_AUTO_TEST_CASE(immutable, *boost::unit_test::precondition(nonEOF())) _assembly.appendImmutableAssignment("someOtherImmutable"); auto sub = _assembly.appendSubroutine(_subAsmPtr); - _assembly.pushSubroutineOffset(static_cast(sub.data())); + _assembly.pushSubroutineOffset(SubAssemblyID(sub.data())); checkCompilation(_assembly); @@ -418,11 +418,11 @@ BOOST_AUTO_TEST_CASE(subobject_encode_decode) assembly.appendSubroutine(subAsmPtr); subAsmPtr->appendSubroutine(subSubAsmPtr); - BOOST_CHECK(assembly.encodeSubPath({0}) == 0); - BOOST_REQUIRE_THROW(assembly.encodeSubPath({1}), solidity::evmasm::AssemblyException); - BOOST_REQUIRE_THROW(assembly.decodeSubPath(1), solidity::evmasm::AssemblyException); + BOOST_CHECK(assembly.encodeSubPath({SubAssemblyID{0}}).value == 0); + BOOST_REQUIRE_THROW(assembly.encodeSubPath({SubAssemblyID{1}}), solidity::langutil::InternalCompilerError); + BOOST_REQUIRE_THROW(assembly.decodeSubPath(SubAssemblyID{1}), solidity::evmasm::AssemblyException); - std::vector subPath{0, 0}; + std::vector subPath{{0}, {0}}; BOOST_CHECK(assembly.decodeSubPath(assembly.encodeSubPath(subPath)) == subPath); } diff --git a/test/libevmasm/Optimiser.cpp b/test/libevmasm/Optimiser.cpp index b53205e959e5..01e1f9ac6c83 100644 --- a/test/libevmasm/Optimiser.cpp +++ b/test/libevmasm/Optimiser.cpp @@ -1546,7 +1546,7 @@ BOOST_AUTO_TEST_CASE(jumpdest_removal_subassemblies, *boost::unit_test::precondi sub->append(t4.pushTag()); sub->append(Instruction::JUMP); - size_t subId = static_cast(main.appendSubroutine(sub).data()); + SubAssemblyID subId{main.appendSubroutine(sub).data()}; main.append(t1.toSubAssemblyTag(subId)); main.append(t1.toSubAssemblyTag(subId)); main.append(u256(8)); From f6b95db7d42660254fbf946e32e04c5eb562d03a Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Wed, 19 Mar 2025 10:45:10 +0100 Subject: [PATCH 1012/1022] Add test with non-zero PUSH #[$] to solc-js tests --- test/externalTests/solc-js/asm-json.js | 45 ++++++++++++++++++++++++++ test/externalTests/solc-js/solc-js.sh | 3 ++ 2 files changed, 48 insertions(+) create mode 100644 test/externalTests/solc-js/asm-json.js diff --git a/test/externalTests/solc-js/asm-json.js b/test/externalTests/solc-js/asm-json.js new file mode 100644 index 000000000000..b41c35947230 --- /dev/null +++ b/test/externalTests/solc-js/asm-json.js @@ -0,0 +1,45 @@ +const tape = require('tape'); +const fs = require('fs'); +const solc = require('../index.js'); + +tape('ASM Json output consistency', function (t) { + t.test('Nested structure', function(st) { + const testdir = 'test/'; + const output = JSON.parse(solc.compile(JSON.stringify({ + language: 'Solidity', + settings: { + viaIR: true, + outputSelection: { + '*': { + '*': ['evm.legacyAssembly'] + } + } + }, + sources: { + C: { + content: fs.readFileSync(testdir + 'code_access_runtime.sol', 'utf8') + } + } + }))); + st.ok(output); + + function containsAssemblyItem(assemblyJSON, assemblyItem) { + if (Array.isArray(assemblyJSON)) + return assemblyJSON.some(item => containsAssemblyItem(item, assemblyItem)); + else if (typeof assemblyJSON === 'object' && assemblyJSON !== null) { + if (assemblyJSON.name === assemblyItem.name && assemblyJSON.value === assemblyItem.value) + return true; + return Object.values(assemblyJSON).some(value => containsAssemblyItem(value, assemblyItem)); + } + return false; + } + + // regression test that there is indeed a negative subassembly index in there + // and it is based on a 64 bit uint + const targetObject = { + "name": "PUSH #[$]", + "value": "000000000000000000000000000000000000000000000000ffffffffffffffff" + }; + st.equal(containsAssemblyItem(output["contracts"]["C"]["C"]["evm"]["legacyAssembly"], targetObject), true) + }); +}); diff --git a/test/externalTests/solc-js/solc-js.sh b/test/externalTests/solc-js/solc-js.sh index af325326c2db..f4e62b6da8ea 100755 --- a/test/externalTests/solc-js/solc-js.sh +++ b/test/externalTests/solc-js/solc-js.sh @@ -48,6 +48,9 @@ function solcjs_test printLog "Copying contracts..." cp -Rf "$SOLCJS_INPUT_DIR/DAO" test/ + printLog "Copying test with non-zero subassembly access" + cp -f "$TEST_DIR"/test/libsolidity/semanticTests/various/code_access_runtime.sol test/ + printLog "Copying SMTChecker tests..." # We do not copy all tests because that takes too long. cp -Rf "$TEST_DIR"/test/libsolidity/smtCheckerTests/external_calls test/smtCheckerTests/ From 683ad061bc10ea445d0ee9924dda0168b3020fa7 Mon Sep 17 00:00:00 2001 From: MozirDmitriy Date: Mon, 28 Jul 2025 10:13:13 +0300 Subject: [PATCH 1013/1022] Fix typo in fitsPrecisionBase2 function comment --- libsolidity/analysis/ConstantEvaluator.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libsolidity/analysis/ConstantEvaluator.cpp b/libsolidity/analysis/ConstantEvaluator.cpp index 0d953be93ff4..691d273d5855 100644 --- a/libsolidity/analysis/ConstantEvaluator.cpp +++ b/libsolidity/analysis/ConstantEvaluator.cpp @@ -59,7 +59,7 @@ bool fitsPrecisionExp(bigint const& _base, bigint const& _exp) return bitsNeeded <= bitsMax; } -/// Checks whether _mantissa * (2 ** _expBase10) fits into 4096 bits. +/// Checks whether _mantissa * (2 ** _expBase2) fits into 4096 bits. bool fitsPrecisionBase2(bigint const& _mantissa, uint32_t _expBase2) { return fitsPrecisionBaseX(_mantissa, 1.0, _expBase2); From 84dd7077c49eb670c0145e16d15836df50014f0e Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Wed, 30 Jul 2025 09:30:37 +0200 Subject: [PATCH 1014/1022] ssa cfg builder: treat constant conditions in jumpi explicitly --- .../evm/SSAControlFlowGraphBuilder.cpp | 41 ++++++---- test/libyul/yulSSAControlFlowGraph/if.yul | 17 ++-- .../yulSSAControlFlowGraph/if_const.yul | 31 ++++++++ .../yulSSAControlFlowGraph/nested_for.yul | 78 ++++++++++--------- 4 files changed, 107 insertions(+), 60 deletions(-) create mode 100644 test/libyul/yulSSAControlFlowGraph/if_const.yul diff --git a/libyul/backends/evm/SSAControlFlowGraphBuilder.cpp b/libyul/backends/evm/SSAControlFlowGraphBuilder.cpp index 101fd2eb361f..5022bd04f95e 100644 --- a/libyul/backends/evm/SSAControlFlowGraphBuilder.cpp +++ b/libyul/backends/evm/SSAControlFlowGraphBuilder.cpp @@ -287,20 +287,33 @@ void SSAControlFlowGraphBuilder::operator()(FunctionDefinition const& _functionD void SSAControlFlowGraphBuilder::operator()(If const& _if) { - auto condition = std::visit(*this, *_if.condition); - auto ifBranch = m_graph.makeBlock(debugDataOf(_if.body)); - auto afterIf = m_graph.makeBlock(debugDataOf(currentBlock())); - conditionalJump( - debugDataOf(_if), - condition, - ifBranch, - afterIf - ); - sealBlock(ifBranch); - m_currentBlock = ifBranch; - (*this)(_if.body); - jump(debugDataOf(_if.body), afterIf); - sealBlock(afterIf); + std::optional constantCondition; + if (auto const* literalCondition = std::get_if(_if.condition.get())) + constantCondition = literalCondition->value.value() != 0; + // deal with literal (constant) conditions explicitly + if (constantCondition) + { + if (*constantCondition) + // Always true - skip conditional, just execute if branch + (*this)(_if.body); + } + else + { + auto condition = std::visit(*this, *_if.condition); + auto ifBranch = m_graph.makeBlock(debugDataOf(_if.body)); + auto afterIf = m_graph.makeBlock(debugDataOf(currentBlock())); + conditionalJump( + debugDataOf(_if), + condition, + ifBranch, + afterIf + ); + sealBlock(ifBranch); + m_currentBlock = ifBranch; + (*this)(_if.body); + jump(debugDataOf(_if.body), afterIf); + sealBlock(afterIf); + } } void SSAControlFlowGraphBuilder::operator()(Switch const& _switch) diff --git a/test/libyul/yulSSAControlFlowGraph/if.yul b/test/libyul/yulSSAControlFlowGraph/if.yul index e2a66ab74fba..f8639b2cc3cd 100644 --- a/test/libyul/yulSSAControlFlowGraph/if.yul +++ b/test/libyul/yulSSAControlFlowGraph/if.yul @@ -1,6 +1,6 @@ { let x := calldataload(3) - if 0 { + if mload(42) { x := calldataload(77) } let y := calldataload(x) @@ -17,26 +17,27 @@ // Block0_0 [label="\ // Block 0; (0, max 2)\nLiveIn: \l\ // LiveOut: v1\l\nv1 := calldataload(3)\l\ +// v3 := mload(42)\l\ // "]; // Block0_0 -> Block0_0Exit; -// Block0_0Exit [label="{ If 0 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; +// Block0_0Exit [label="{ If v3 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; // Block0_0Exit:0 -> Block0_2 [style="solid"]; // Block0_0Exit:1 -> Block0_1 [style="solid"]; // Block0_1 [label="\ // Block 1; (1, max 2)\nLiveIn: \l\ -// LiveOut: v4\l\nv4 := calldataload(77)\l\ +// LiveOut: v5\l\nv5 := calldataload(77)\l\ // "]; // Block0_1 -> Block0_1Exit [arrowhead=none]; // Block0_1Exit [label="Jump" shape=oval]; // Block0_1Exit -> Block0_2 [style="solid"]; // Block0_2 [label="\ -// Block 2; (2, max 2)\nLiveIn: v5\l\ -// LiveOut: \l\nv5 := φ(\l\ +// Block 2; (2, max 2)\nLiveIn: v6\l\ +// LiveOut: \l\nv6 := φ(\l\ // Block 0 => v1,\l\ -// Block 1 => v4\l\ +// Block 1 => v5\l\ // )\l\ -// v6 := calldataload(v5)\l\ -// sstore(0, v6)\l\ +// v7 := calldataload(v6)\l\ +// sstore(0, v7)\l\ // "]; // Block0_2Exit [label="MainExit"]; // Block0_2 -> Block0_2Exit; diff --git a/test/libyul/yulSSAControlFlowGraph/if_const.yul b/test/libyul/yulSSAControlFlowGraph/if_const.yul new file mode 100644 index 000000000000..26a3c094c5d7 --- /dev/null +++ b/test/libyul/yulSSAControlFlowGraph/if_const.yul @@ -0,0 +1,31 @@ +{ + let x := calldataload(3) + // this should not appear in the output at all + if 0 { + x := calldataload(77) + } + // this should avoid a conditional jump + if 33 { + x := calldataload(42) + } + let y := calldataload(x) + sstore(y, 0) +} +// ---- +// digraph SSACFG { +// nodesep=0.7; +// graph[fontname="DejaVu Sans"] +// node[shape=box,fontname="DejaVu Sans"]; +// +// Entry0 [label="Entry"]; +// Entry0 -> Block0_0; +// Block0_0 [label="\ +// Block 0; (0, max 0)\nLiveIn: \l\ +// LiveOut: \l\nv1 := calldataload(3)\l\ +// v3 := calldataload(42)\l\ +// v4 := calldataload(v3)\l\ +// sstore(0, v4)\l\ +// "]; +// Block0_0Exit [label="MainExit"]; +// Block0_0 -> Block0_0Exit; +// } diff --git a/test/libyul/yulSSAControlFlowGraph/nested_for.yul b/test/libyul/yulSSAControlFlowGraph/nested_for.yul index f57a5ca29a5b..6efb3552a182 100644 --- a/test/libyul/yulSSAControlFlowGraph/nested_for.yul +++ b/test/libyul/yulSSAControlFlowGraph/nested_for.yul @@ -2,12 +2,12 @@ for { let i := 0 } lt(i, 3) { i := add(i, 1) } { for { let j := 0 } lt(j, 3) { j := add(j, 1) } { for { let k := 0 } lt(k, 3) { k := add(k, 1) } { - if 0 { + if mload(0) { for { let l := 0 } lt(l, 3) { l := add(l, 1) } { sstore(l, add(add(i,j),k)) } } - if 1 { + if mload(1) { for { let l := 0 } lt(l, 3) { l := add(l, 1) } { sstore(l, add(add(i,j),k)) } @@ -36,7 +36,7 @@ // Block 1; (1, max 24)\nLiveIn: v3\l\ // LiveOut: v3\l\nv3 := φ(\l\ // Block 0 => v1,\l\ -// Block 3 => v41\l\ +// Block 3 => v43\l\ // )\l\ // v4 := lt(3, v3)\l\ // "]; @@ -60,7 +60,7 @@ // Block 5; (3, max 23)\nLiveIn: v3,v6\l\ // LiveOut: v3,v6\l\nv6 := φ(\l\ // Block 2 => v5,\l\ -// Block 7 => v40\l\ +// Block 7 => v42\l\ // )\l\ // v7 := lt(3, v6)\l\ // "]; @@ -85,7 +85,7 @@ // Block 9; (5, max 21)\nLiveIn: v3,v6,v9\l\ // LiveOut: v3,v6,v9\l\nv9 := φ(\l\ // Block 6 => v8,\l\ -// Block 11 => v36\l\ +// Block 11 => v38\l\ // )\l\ // v10 := lt(3, v9)\l\ // "]; @@ -95,16 +95,17 @@ // Block0_9Exit:1 -> Block0_10 [style="solid"]; // Block0_3 [label="\ // Block 3; (23, max 23)\nLiveIn: v3\l\ -// LiveOut: v41\l\nv41 := add(1, v3)\l\ +// LiveOut: v43\l\nv43 := add(1, v3)\l\ // "]; // Block0_3 -> Block0_3Exit [arrowhead=none]; // Block0_3Exit [label="Jump" shape=oval]; // Block0_3Exit -> Block0_1 [style="dashed"]; // Block0_10 [label="\ // Block 10; (6, max 19)\nLiveIn: v3,v6,v9\l\ -// LiveOut: v3,v6,v9\l\n"]; +// LiveOut: v3,v6,v9\l\nv11 := mload(0)\l\ +// "]; // Block0_10 -> Block0_10Exit; -// Block0_10Exit [label="{ If 0 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; +// Block0_10Exit [label="{ If v11 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; // Block0_10Exit:0 -> Block0_14 [style="solid"]; // Block0_10Exit:1 -> Block0_13 [style="solid"]; // Block0_12 [label="\ @@ -115,40 +116,41 @@ // Block0_12Exit -> Block0_7 [style="solid"]; // Block0_13 [label="\ // Block 13; (7, max 19)\nLiveIn: v3,v6,v9\l\ -// LiveOut: v3,v6,v9,v11\l\nv11 := 0\l\ +// LiveOut: v3,v6,v9,v12\l\nv12 := 0\l\ // "]; // Block0_13 -> Block0_13Exit [arrowhead=none]; // Block0_13Exit [label="Jump" shape=oval]; // Block0_13Exit -> Block0_15 [style="solid"]; // Block0_14 [label="\ // Block 14; (12, max 19)\nLiveIn: v3,v6,v9\l\ -// LiveOut: v3,v6,v9\l\n"]; +// LiveOut: v3,v6,v9\l\nv24 := mload(1)\l\ +// "]; // Block0_14 -> Block0_14Exit; -// Block0_14Exit [label="{ If 1 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; +// Block0_14Exit [label="{ If v24 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; // Block0_14Exit:0 -> Block0_20 [style="solid"]; // Block0_14Exit:1 -> Block0_19 [style="solid"]; // Block0_7 [label="\ // Block 7; (21, max 21)\nLiveIn: v3,v6\l\ -// LiveOut: v3,v40\l\nv40 := add(1, v6)\l\ +// LiveOut: v3,v42\l\nv42 := add(1, v6)\l\ // "]; // Block0_7 -> Block0_7Exit [arrowhead=none]; // Block0_7Exit [label="Jump" shape=oval]; // Block0_7Exit -> Block0_5 [style="dashed"]; // Block0_15 [label="\ -// Block 15; (8, max 19)\nLiveIn: v3,v6,v9,v12\l\ -// LiveOut: v3,v6,v9,v12\l\nv12 := φ(\l\ -// Block 13 => v11,\l\ -// Block 17 => v20\l\ +// Block 15; (8, max 19)\nLiveIn: v3,v6,v9,v13\l\ +// LiveOut: v3,v6,v9,v13\l\nv13 := φ(\l\ +// Block 13 => v12,\l\ +// Block 17 => v21\l\ // )\l\ -// v13 := lt(3, v12)\l\ +// v14 := lt(3, v13)\l\ // "]; // Block0_15 -> Block0_15Exit; -// Block0_15Exit [label="{ If v13 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; +// Block0_15Exit [label="{ If v14 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; // Block0_15Exit:0 -> Block0_18 [style="solid"]; // Block0_15Exit:1 -> Block0_16 [style="solid"]; // Block0_19 [label="\ // Block 19; (13, max 19)\nLiveIn: v3,v6,v9\l\ -// LiveOut: v3,v6,v9,v23\l\nv23 := 0\l\ +// LiveOut: v3,v6,v9,v25\l\nv25 := 0\l\ // "]; // Block0_19 -> Block0_19Exit [arrowhead=none]; // Block0_19Exit [label="Jump" shape=oval]; @@ -160,10 +162,10 @@ // Block0_20Exit [label="Jump" shape=oval]; // Block0_20Exit -> Block0_11 [style="solid"]; // Block0_16 [label="\ -// Block 16; (9, max 10)\nLiveIn: v3,v6,v9,v12\l\ -// LiveOut: v3,v6,v9,v12\l\nv17 := add(v6, v3)\l\ -// v18 := add(v9, v17)\l\ -// sstore(v18, v12)\l\ +// Block 16; (9, max 10)\nLiveIn: v3,v6,v9,v13\l\ +// LiveOut: v3,v6,v9,v13\l\nv18 := add(v6, v3)\l\ +// v19 := add(v9, v18)\l\ +// sstore(v19, v13)\l\ // "]; // Block0_16 -> Block0_16Exit [arrowhead=none]; // Block0_16Exit [label="Jump" shape=oval]; @@ -175,36 +177,36 @@ // Block0_18Exit [label="Jump" shape=oval]; // Block0_18Exit -> Block0_14 [style="solid"]; // Block0_21 [label="\ -// Block 21; (14, max 19)\nLiveIn: v3,v6,v9,v24\l\ -// LiveOut: v3,v6,v9,v24\l\nv24 := φ(\l\ -// Block 19 => v23,\l\ -// Block 23 => v31\l\ +// Block 21; (14, max 19)\nLiveIn: v3,v6,v9,v26\l\ +// LiveOut: v3,v6,v9,v26\l\nv26 := φ(\l\ +// Block 19 => v25,\l\ +// Block 23 => v33\l\ // )\l\ -// v25 := lt(3, v24)\l\ +// v27 := lt(3, v26)\l\ // "]; // Block0_21 -> Block0_21Exit; -// Block0_21Exit [label="{ If v25 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; +// Block0_21Exit [label="{ If v27 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; // Block0_21Exit:0 -> Block0_24 [style="solid"]; // Block0_21Exit:1 -> Block0_22 [style="solid"]; // Block0_11 [label="\ // Block 11; (19, max 19)\nLiveIn: v3,v6,v9\l\ -// LiveOut: v3,v6,v36\l\nv36 := add(1, v9)\l\ +// LiveOut: v3,v6,v38\l\nv38 := add(1, v9)\l\ // "]; // Block0_11 -> Block0_11Exit [arrowhead=none]; // Block0_11Exit [label="Jump" shape=oval]; // Block0_11Exit -> Block0_9 [style="dashed"]; // Block0_17 [label="\ -// Block 17; (10, max 10)\nLiveIn: v3,v6,v9,v12\l\ -// LiveOut: v3,v6,v9,v20\l\nv20 := add(1, v12)\l\ +// Block 17; (10, max 10)\nLiveIn: v3,v6,v9,v13\l\ +// LiveOut: v3,v6,v9,v21\l\nv21 := add(1, v13)\l\ // "]; // Block0_17 -> Block0_17Exit [arrowhead=none]; // Block0_17Exit [label="Jump" shape=oval]; // Block0_17Exit -> Block0_15 [style="dashed"]; // Block0_22 [label="\ -// Block 22; (15, max 16)\nLiveIn: v3,v6,v9,v24\l\ -// LiveOut: v3,v6,v9,v24\l\nv29 := add(v6, v3)\l\ -// v30 := add(v9, v29)\l\ -// sstore(v30, v24)\l\ +// Block 22; (15, max 16)\nLiveIn: v3,v6,v9,v26\l\ +// LiveOut: v3,v6,v9,v26\l\nv31 := add(v6, v3)\l\ +// v32 := add(v9, v31)\l\ +// sstore(v32, v26)\l\ // "]; // Block0_22 -> Block0_22Exit [arrowhead=none]; // Block0_22Exit [label="Jump" shape=oval]; @@ -216,8 +218,8 @@ // Block0_24Exit [label="Jump" shape=oval]; // Block0_24Exit -> Block0_20 [style="solid"]; // Block0_23 [label="\ -// Block 23; (16, max 16)\nLiveIn: v3,v6,v9,v24\l\ -// LiveOut: v3,v6,v9,v31\l\nv31 := add(1, v24)\l\ +// Block 23; (16, max 16)\nLiveIn: v3,v6,v9,v26\l\ +// LiveOut: v3,v6,v9,v33\l\nv33 := add(1, v26)\l\ // "]; // Block0_23 -> Block0_23Exit [arrowhead=none]; // Block0_23Exit [label="Jump" shape=oval]; From 140fdbd654687d11be889fa4039b68840d674d2f Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Wed, 30 Jul 2025 10:12:46 +0200 Subject: [PATCH 1015/1022] ssa cfg builder: treat constant switches explicitly --- .../evm/SSAControlFlowGraphBuilder.cpp | 22 ++++++++ .../yulSSAControlFlowGraph/switch_const.yul | 55 +++++++++++++++++++ 2 files changed, 77 insertions(+) create mode 100644 test/libyul/yulSSAControlFlowGraph/switch_const.yul diff --git a/libyul/backends/evm/SSAControlFlowGraphBuilder.cpp b/libyul/backends/evm/SSAControlFlowGraphBuilder.cpp index 5022bd04f95e..35e2e4935327 100644 --- a/libyul/backends/evm/SSAControlFlowGraphBuilder.cpp +++ b/libyul/backends/evm/SSAControlFlowGraphBuilder.cpp @@ -355,6 +355,28 @@ void SSAControlFlowGraphBuilder::operator()(Switch const& _switch) } else { + if (auto const* constantExpression = std::get_if(_switch.expression.get())) + { + Case const* matchedCase = nullptr; + // select case that matches (or default if available) + for (auto const& switchCase: _switch.cases) + { + if (!switchCase.value) + matchedCase = &switchCase; + if (switchCase.value && switchCase.value->value.value() == constantExpression->value.value()) + { + matchedCase = &switchCase; + break; + } + } + if (matchedCase) + { + // inject directly into the current block + (*this)(matchedCase->body); + } + return; + } + std::optional equalityBuiltinHandle = m_dialect.equalityFunctionHandle(); yulAssert(equalityBuiltinHandle); diff --git a/test/libyul/yulSSAControlFlowGraph/switch_const.yul b/test/libyul/yulSSAControlFlowGraph/switch_const.yul new file mode 100644 index 000000000000..3de0537dc5f0 --- /dev/null +++ b/test/libyul/yulSSAControlFlowGraph/switch_const.yul @@ -0,0 +1,55 @@ +{ + let x := calldataload(3) + + // this should yield calldataload(88) directly + switch 1 + case 0 { + x := calldataload(77) + } + case 1 { + x := calldataload(88) + } + default { + x := calldataload(99) + } + + // this should yield the default case + switch 55 + case 0 { + x := calldataload(77) + } + case 1 { + x := calldataload(88) + } + default { + x := calldataload(99) + } + + // this should be skipped entirely + switch 66 + case 0 { + x := calldataload(77) + } + case 1 { + x := calldataload(88) + } + sstore(x, 0) +} +// ---- +// digraph SSACFG { +// nodesep=0.7; +// graph[fontname="DejaVu Sans"] +// node[shape=box,fontname="DejaVu Sans"]; +// +// Entry0 [label="Entry"]; +// Entry0 -> Block0_0; +// Block0_0 [label="\ +// Block 0; (0, max 0)\nLiveIn: \l\ +// LiveOut: \l\nv1 := calldataload(3)\l\ +// v4 := calldataload(88)\l\ +// v7 := calldataload(99)\l\ +// sstore(0, v7)\l\ +// "]; +// Block0_0Exit [label="MainExit"]; +// Block0_0 -> Block0_0Exit; +// } From 3d4a3c8ddef9182596e89c76b8aa9f4f5d82f372 Mon Sep 17 00:00:00 2001 From: sudo rm -rf --no-preserve-root / Date: Thu, 24 Jul 2025 12:17:15 +0200 Subject: [PATCH 1016/1022] docs: fix unnecessary `uint160(bytes20(b))` casting Resolves: https://github.com/ethereum/solidity/issues/16129. --- 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 38d22aebdc2d..57fa7b3dabd3 100644 --- a/docs/types/value-types.rst +++ b/docs/types/value-types.rst @@ -229,7 +229,7 @@ Operators: To reduce conversion ambiguity, starting with version 0.4.24, the compiler will force you to make the truncation explicit in the conversion. Take for example the 32-byte value ``0x111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFFCCCC``. - You can use ``address(uint160(bytes20(b)))``, which results in ``0x111122223333444455556666777788889999aAaa``, + You can use ``address(bytes20(b))``, which results in ``0x111122223333444455556666777788889999aAaa``, or you can use ``address(uint160(uint256(b)))``, which results in ``0x777788889999AaAAbBbbCcccddDdeeeEfFFfCcCc``. .. note:: From ab68eaf116be0985baa598e35f94e8546202cda1 Mon Sep 17 00:00:00 2001 From: GarmashAlex Date: Tue, 13 May 2025 19:22:29 +0300 Subject: [PATCH 1017/1022] fix typos in comments --- libyul/backends/evm/StackLayoutGenerator.cpp | 2 +- test/compilationTests/corion/provider.sol | 2 +- test/compilationTests/corion/schelling.sol | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/libyul/backends/evm/StackLayoutGenerator.cpp b/libyul/backends/evm/StackLayoutGenerator.cpp index 69045998c859..f6d1108eeb78 100644 --- a/libyul/backends/evm/StackLayoutGenerator.cpp +++ b/libyul/backends/evm/StackLayoutGenerator.cpp @@ -308,7 +308,7 @@ Stack StackLayoutGenerator::propagateStackThroughOperation(Stack _exitStack, CFG // generated on the fly), s.t. shuffling the `stack + _operation.output` to _exitLayout is cheap. Stack stack = createIdealLayout(_operation.output, _exitStack, generateSlotOnTheFly, reachableStackDepth()); - // Make sure the resulting previous slots do not overlap with any assignmed variables. + // Make sure the resulting previous slots do not overlap with any assigned variables. if (auto const* assignment = std::get_if(&_operation.operation)) for (auto& stackSlot: stack) if (auto const* varSlot = std::get_if(&stackSlot)) diff --git a/test/compilationTests/corion/provider.sol b/test/compilationTests/corion/provider.sol index 524390b2ed3a..435ddcc30247 100644 --- a/test/compilationTests/corion/provider.sol +++ b/test/compilationTests/corion/provider.sol @@ -185,7 +185,7 @@ contract provider is module, safeMath, announcementTypes { } function setRightForInterest(uint256 oldValue, uint256 newValue, bool priv) internal { /* - It checks if the provider has enough connected captital to be able to get from the token emission. + It checks if the provider has enough connected capital to be able to get from the token emission. In case the provider is not able to get the share from the token emission then the connected capital will not count to the value of the globalFunds, to the current schelling round. @oldValue old diff --git a/test/compilationTests/corion/schelling.sol b/test/compilationTests/corion/schelling.sol index 96b530d26e83..9c57fe16f8e7 100644 --- a/test/compilationTests/corion/schelling.sol +++ b/test/compilationTests/corion/schelling.sol @@ -256,7 +256,7 @@ contract schelling is module, announcementTypes, schellingVars { @_moduleHandler Address of ModuleHandler. @_db Address of the database. @_forReplace This address will be replaced with the old one or not. - @_icoExpansionAddress This address can turn schelling runds during ICO. + @_icoExpansionAddress This address can turn schelling funds during ICO. */ db = schellingDB(_db); super.registerModuleHandler(_moduleHandler); From 5dba5c5c389a5b98de285a8f3e440396c961b4a3 Mon Sep 17 00:00:00 2001 From: Shane Date: Sat, 25 Jan 2025 12:52:10 +0800 Subject: [PATCH 1018/1022] Replace "External accounts" with "Externally-owned accounts" for accuracy --- docs/introduction-to-smart-contracts.rst | 6 +++--- docs/security-considerations.rst | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/introduction-to-smart-contracts.rst b/docs/introduction-to-smart-contracts.rst index 994cb85d479f..74b537cca93f 100644 --- a/docs/introduction-to-smart-contracts.rst +++ b/docs/introduction-to-smart-contracts.rst @@ -131,7 +131,7 @@ This contract introduces some new concepts, let us go through them one by one. The line ``address public minter;`` declares a state variable of type :ref:`address
`. The ``address`` type is a 160-bit value that does not allow any arithmetic operations. It is suitable for storing addresses of contracts, or a hash of the public half -of a keypair belonging to :ref:`external accounts`. +of a keypair belonging to :ref:`externally-owned accounts`. The keyword ``public`` automatically generates a function that allows you to access the current value of the state variable from outside of the contract. Without this keyword, other contracts have no way to access the variable. @@ -338,11 +338,11 @@ Accounts ======== There are two kinds of accounts in Ethereum which share the same -address space: **External accounts** that are controlled by +address space: **Externally-owned accounts** that are controlled by public-private key pairs (i.e. humans) and **contract accounts** which are controlled by the code stored together with the account. -The address of an external account is determined from +The address of an externally-owned account is determined from the public key while the address of a contract is determined at the time the contract is created (it is derived from the creator address and the number diff --git a/docs/security-considerations.rst b/docs/security-considerations.rst index 2b8f7f835133..eb42993e6764 100644 --- a/docs/security-considerations.rst +++ b/docs/security-considerations.rst @@ -144,7 +144,7 @@ Please be explicit about such cases in the documentation of your contracts. Sending and Receiving Ether =========================== -- Neither contracts nor "external accounts" are currently able to prevent someone from sending them Ether. +- Neither contracts nor "externally-owned accounts" are currently able to prevent someone from sending them Ether. Contracts can react on and reject a regular transfer, but there are ways to move Ether without creating a message call. One way is to simply "mine to" the contract address and the second way is using ``selfdestruct(x)``. From ce366e770a99b12e264e963b6f3c9fc829069d37 Mon Sep 17 00:00:00 2001 From: Nikola Matic Date: Tue, 5 Aug 2025 17:47:15 +0200 Subject: [PATCH 1019/1022] Fix external ENS test --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 0f4d2b6ebd41..ed4a29b6d948 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -779,7 +779,7 @@ defaults: name: t_native_test_ext_ens project: ens binary_type: native - image: cimg/node:18.16 + image: cimg/node:lts - job_native_compile_ext_trident: &job_native_compile_ext_trident <<: *requires_b_ubu_static From 37d4a729742a7f367bf454f85f17d9b25d011731 Mon Sep 17 00:00:00 2001 From: Tronica Date: Thu, 20 Mar 2025 10:01:53 +0100 Subject: [PATCH 1020/1022] chore(scripts): improve readability of regressions.py and splitSources.py Co-authored-by: clonker <1685266+clonker@users.noreply.github.com> --- scripts/regressions.py | 10 +++++----- scripts/splitSources.py | 6 +++--- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/scripts/regressions.py b/scripts/regressions.py index e30c0aeb9f8d..7de108ef30f3 100755 --- a/scripts/regressions.py +++ b/scripts/regressions.py @@ -22,15 +22,15 @@ def __init__(self, interval=300): thread.start() def run(self): - """ Runs until the main Python thread exits. """ - ## Print a newline at the very beginning. + """ Run indefinitely until the main Python thread exits. """ + ## Print an initial newline at the very beginning. print("") while True: # Print dot print(".") time.sleep(self.interval) -class regressor: +class Regressor: _re_sanitizer_log = re.compile(r"""ERROR: (libFuzzer|UndefinedBehaviorSanitizer)""") def __init__(self, description, args): @@ -87,7 +87,7 @@ def process_log(self, logfile): False -> Failure """ - ## Log may contain non ASCII characters, so we simply stringify them + ## Log may contain non-ASCII characters, so we simply stringify them ## since they don't matter for regular expression matching with open(logfile, 'rb', encoding=None) as f: rawtext = str(f.read()) @@ -122,5 +122,5 @@ def run(self): if __name__ == '__main__': dotprinter = PrintDotsThread() - tool = regressor(DESCRIPTION, sys.argv[1:]) + tool = Regressor(DESCRIPTION, sys.argv[1:]) sys.exit(not tool.run()) diff --git a/scripts/splitSources.py b/scripts/splitSources.py index 5e783b2d5aa9..878600b17947 100755 --- a/scripts/splitSources.py +++ b/scripts/splitSources.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 # # This script reads a syntaxTest file and writes all -# sources into their own files. If one source-name specifies subdirectories +# sources into separate files. If a source name specifies subdirectories, # those will be created too. # Usage: scripts/splitSources.py pathToTestfile @@ -18,7 +18,7 @@ def uncaught_exception_hook(exc_type, exc_value, exc_traceback): # The script `scripts/ASTImportTest.sh` will interpret return code 3 # as a critical error (because of the uncaught exception) and will # terminate further execution. - print("Unhandled exception: %s", "".join(traceback.format_exception(exc_type, exc_value, exc_traceback))) + print("Unhandled exception: " + "".join(traceback.format_exception(exc_type, exc_value, exc_traceback))) sys.exit(3) @@ -42,7 +42,7 @@ def writeSourceToFile(lines): with open(srcName, mode='a+', encoding='utf8', newline='') as f: for idx, line in enumerate(lines[1:]): # write to file - if line[:12] != "==== Source:": + if not line.startswith("==== Source:"): f.write(line + '\n') # recursive call if there is another source From d578b6bdb781c6e24a30b7b3ab535002e4d87378 Mon Sep 17 00:00:00 2001 From: radik878 Date: Tue, 5 Aug 2025 16:16:01 +0300 Subject: [PATCH 1021/1022] Fix comparison operator of CHCVerificationTarget --- libsolidity/formal/CHC.h | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/libsolidity/formal/CHC.h b/libsolidity/formal/CHC.h index 8ecef3960f6c..43033118a600 100644 --- a/libsolidity/formal/CHC.h +++ b/libsolidity/formal/CHC.h @@ -74,18 +74,10 @@ class CHC: public SMTEncoder friend bool operator<(CHCVerificationTarget const& _a, CHCVerificationTarget const& _b) { - return _a.errorId < _b.errorId; - } - }; - - struct SafeTargetsCompare - { - bool operator()(CHCVerificationTarget const & _lhs, CHCVerificationTarget const & _rhs) const - { - if (_lhs.errorNode->id() == _rhs.errorNode->id()) - return _lhs.type < _rhs.type; + if (_a.errorNode->id() == _b.errorNode->id()) + return _a.type < _b.type; else - return _lhs.errorNode->id() == _rhs.errorNode->id(); + return _a.errorNode->id() < _b.errorNode->id(); } }; @@ -96,7 +88,7 @@ class CHC: public SMTEncoder std::string message; }; - std::map, smt::EncodingContext::IdCompare> const& safeTargets() const { return m_safeTargets; } + std::map, smt::EncodingContext::IdCompare> const& safeTargets() const { return m_safeTargets; } std::map, smt::EncodingContext::IdCompare> const& unsafeTargets() const { return m_unsafeTargets; } /// This is used if the Horn solver is not directly linked into this binary. @@ -434,7 +426,7 @@ class CHC: public SMTEncoder std::map m_verificationTargets; /// Targets proved safe. - std::map, smt::EncodingContext::IdCompare> m_safeTargets; + std::map, smt::EncodingContext::IdCompare> m_safeTargets; /// Targets proved unsafe. std::map, smt::EncodingContext::IdCompare> m_unsafeTargets; /// Targets not proved. From c78de76b993a8d2944d3d552318d1601029cb27a Mon Sep 17 00:00:00 2001 From: Martin Blicha Date: Mon, 11 Aug 2025 14:42:46 +0200 Subject: [PATCH 1022/1022] SSA-CFG: Tiny code simplifications --- .../evm/SSAControlFlowGraphBuilder.cpp | 34 +++++++------------ 1 file changed, 12 insertions(+), 22 deletions(-) diff --git a/libyul/backends/evm/SSAControlFlowGraphBuilder.cpp b/libyul/backends/evm/SSAControlFlowGraphBuilder.cpp index 35e2e4935327..0af08e39dd7b 100644 --- a/libyul/backends/evm/SSAControlFlowGraphBuilder.cpp +++ b/libyul/backends/evm/SSAControlFlowGraphBuilder.cpp @@ -109,7 +109,7 @@ SSACFG::ValueId SSAControlFlowGraphBuilder::tryRemoveTrivialPhi(SSACFG::ValueId m_graph.block(phiInfo->block).phis.erase(_phi); - std::set phiUses; + std::vector phiUses; for (size_t blockIdValue = 0; blockIdValue < m_graph.numBlocks(); ++blockIdValue) { auto& block = m_graph.block(SSACFG::BlockId{blockIdValue}); @@ -126,18 +126,13 @@ SSACFG::ValueId SSAControlFlowGraphBuilder::tryRemoveTrivialPhi(SSACFG::ValueId usedInPhi = true; } if (usedInPhi) - phiUses.emplace(blockPhi); + phiUses.push_back(blockPhi); } for (auto& op: block.operations) - std::replace(op.inputs.begin(), op.inputs.end(), _phi, same); + ranges::replace(op.inputs, _phi, same); std::visit(util::GenericVisitor{ [_phi, same](SSACFG::BasicBlock::FunctionReturn& _functionReturn) { - std::replace( - _functionReturn.returnValues.begin(), - _functionReturn.returnValues.end(), - _phi, - same - ); + ranges::replace(_functionReturn.returnValues,_phi, same); }, [_phi, same](SSACFG::BasicBlock::ConditionalJump& _condJump) { if (_condJump.condition == _phi) @@ -188,22 +183,17 @@ void SSAControlFlowGraphBuilder::cleanUnreachable() { auto& block = m_graph.block(blockId); - std::set maybeTrivialPhi; - for (auto it = block.entries.begin(); it != block.entries.end();) - if (reachabilityCheck.visited.count(*it)) - it++; - else - it = block.entries.erase(it); + std::vector maybeTrivialPhi; + std::erase_if(block.entries, [&](auto const& entry) { return !reachabilityCheck.visited.contains(entry); }); for (auto phi: block.phis) if (auto* phiInfo = std::get_if(&m_graph.valueInfo(phi))) - std::erase_if(phiInfo->arguments, [&](SSACFG::ValueId _arg) { - if (std::holds_alternative(m_graph.valueInfo(_arg))) - { - maybeTrivialPhi.insert(phi); - return true; - } - return false; + { + auto erasedCount = std::erase_if(phiInfo->arguments, [&](SSACFG::ValueId _arg) { + return std::holds_alternative(m_graph.valueInfo(_arg)); }); + if (erasedCount > 0) + maybeTrivialPhi.push_back(phi); + } // After removing a phi argument, we might end up with a trivial phi that can be removed. for (auto phi: maybeTrivialPhi)